Fix memory overflow in ESQueue am: 91fed774ac am: 979ebeacb7 am: 6f24da9b73 am: 8381c1ef9b

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/av/+/12794733

Change-Id: I49d48409ddb70facbf2bd95b40345669dca6e208
diff --git a/Android.bp b/Android.bp
deleted file mode 100644
index e4f12c8..0000000
--- a/Android.bp
+++ /dev/null
@@ -1,7 +0,0 @@
-subdirs = [
-    "camera",
-    "drm/*",
-    "media/*",
-    "services/*",
-    "soundtrigger",
-]
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 793cbf4..e584ffb 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -81,6 +81,7 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libstagefright_xmlparser@1.0.so)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libstagefright_soft_*)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/vndk/libstagefright_soft_*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libaudiopolicyengineconfig*)
 
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/apex/Android.bp b/apex/Android.bp
new file mode 100644
index 0000000..42a620b
--- /dev/null
+++ b/apex/Android.bp
@@ -0,0 +1,121 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+apex_defaults {
+    name: "com.android.media-defaults",
+    java_libs: ["updatable-media"],
+    multilib: {
+        first: {
+            // Extractor process runs only with the primary ABI.
+            native_shared_libs: [
+                // Extractor plugins
+                "libaacextractor",
+                "libamrextractor",
+                "libflacextractor",
+                "libmidiextractor",
+                "libmkvextractor",
+                "libmp3extractor",
+                "libmp4extractor",
+                "libmpeg2extractor",
+                "liboggextractor",
+                "libwavextractor",
+            ],
+        },
+    },
+    prebuilts: [
+        "mediaextractor.policy",
+    ],
+    key: "com.android.media.key",
+    certificate: ":com.android.media.certificate",
+
+    // Use a custom AndroidManifest.xml used for API targeting.
+    androidManifest: ":com.android.media-androidManifest",
+}
+
+apex {
+    name: "com.android.media",
+    manifest: "manifest.json",
+    defaults: ["com.android.media-defaults"],
+}
+
+filegroup {
+    name: "com.android.media-androidManifest",
+    srcs: ["AndroidManifest-media.xml"],
+}
+
+filegroup {
+    name: "com.android.media.swcodec-androidManifest",
+    srcs: ["AndroidManifest-swcodec.xml"],
+}
+
+apex_defaults {
+    name: "com.android.media.swcodec-defaults",
+    binaries: [
+        "mediaswcodec",
+    ],
+    prebuilts: [
+        "com.android.media.swcodec-mediaswcodec.rc",
+        "com.android.media.swcodec-ld.config.txt",
+        "mediaswcodec.policy",
+        "mediaswcodec.xml",
+    ],
+    use_vendor: true,
+    key: "com.android.media.swcodec.key",
+    certificate: ":com.android.media.swcodec.certificate",
+
+    // Use a custom AndroidManifest.xml used for API targeting.
+    androidManifest: ":com.android.media.swcodec-androidManifest",
+}
+
+prebuilt_etc {
+    name: "com.android.media.swcodec-mediaswcodec.rc",
+    src: "mediaswcodec.rc",
+    filename: "init.rc",
+    installable: false,
+}
+
+prebuilt_etc {
+    name: "com.android.media.swcodec-ld.config.txt",
+    src: "ld.config.txt",
+    filename: "ld.config.txt",
+    installable: false,
+}
+
+apex {
+    name: "com.android.media.swcodec",
+    manifest: "manifest_codec.json",
+    defaults: ["com.android.media.swcodec-defaults"],
+}
+
+apex_key {
+    name: "com.android.media.key",
+    public_key: "com.android.media.avbpubkey",
+    private_key: "com.android.media.pem",
+}
+
+apex_key {
+    name: "com.android.media.swcodec.key",
+    public_key: "com.android.media.swcodec.avbpubkey",
+    private_key: "com.android.media.swcodec.pem",
+}
+
+android_app_certificate {
+    name: "com.android.media.certificate",
+    certificate: "com.android.media",
+}
+
+android_app_certificate {
+    name: "com.android.media.swcodec.certificate",
+    certificate: "com.android.media.swcodec",
+}
diff --git a/apex/AndroidManifest-media.xml b/apex/AndroidManifest-media.xml
new file mode 100644
index 0000000..1af4586
--- /dev/null
+++ b/apex/AndroidManifest-media.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+  package="com.android.media">
+  <!-- APEX does not have classes.dex -->
+  <application android:hasCode="false" />
+  <!-- Setting maxSdk to lock the module to Q. minSdk is auto-set by build system -->
+  <uses-sdk
+      android:maxSdkVersion="29"
+      android:targetSdkVersion="29"
+  />
+</manifest>
diff --git a/apex/AndroidManifest-swcodec.xml b/apex/AndroidManifest-swcodec.xml
new file mode 100644
index 0000000..de50864
--- /dev/null
+++ b/apex/AndroidManifest-swcodec.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+  package="com.android.media.swcodec">
+  <!-- APEX does not have classes.dex -->
+  <application android:hasCode="false" />
+  <!-- Setting maxSdk to lock the module to Q. minSdk is auto-set by build system -->
+  <uses-sdk
+      android:maxSdkVersion="29"
+      android:targetSdkVersion="29"
+  />
+</manifest>
diff --git a/apex/OWNERS b/apex/OWNERS
new file mode 100644
index 0000000..5587f5f
--- /dev/null
+++ b/apex/OWNERS
@@ -0,0 +1,6 @@
+chz@google.com
+dwkang@google.com
+jiyong@google.com
+lajos@google.com
+marcone@google.com
+wjia@google.com
diff --git a/apex/TEST_MAPPING b/apex/TEST_MAPPING
new file mode 100644
index 0000000..a2e98cc
--- /dev/null
+++ b/apex/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "imports": [
+    {
+      "path": "system/apex/tests"
+    }
+  ]
+}
diff --git a/apex/com.android.media.avbpubkey b/apex/com.android.media.avbpubkey
new file mode 100644
index 0000000..c0c8fd3
--- /dev/null
+++ b/apex/com.android.media.avbpubkey
Binary files differ
diff --git a/apex/com.android.media.pem b/apex/com.android.media.pem
new file mode 100644
index 0000000..8daa50e
--- /dev/null
+++ b/apex/com.android.media.pem
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKAIBAAKCAgEA06dKiF+xQp36Xcosmac+DzJTXC9nbHy0Yqfy+zEC5hlwXbHZ
+1gAZZu8zL9p7kbBkmtSCulU0M+cTHr74gkG9UDkM/S7Z+957FzHMqWXY03gupFP7
+lcCnKtpkzsyQrABavynoxyY6dfmKZNtEFQrikK1zs80CppRoMwZS2dLogX8qO5LU
+gLe7/0PZBdbQSVA5AARE+AO6pR5Px/8QAere9TCLcm1aK9BUVOJvaAZAf7bD2f8s
+3J/lANQ1tvXXZrFL1i26H6sNja11u5/M0odg3SfqKI0x/317nLkYx8QSSHVKEjBs
+nzsyoFry4INEh/q7zSEX5+S1VA6ORjyof3u7CrGavrYwI2k6x3t+Dkc2dfNDaNY9
+9vGYD1nMyRqUzSIqaOz8q78tc1A391Lua8SB1E0Tx/FnsPjxPee0wZ1taGddkZxD
+cvMdQJhLyE6EloimFiOhkVjnAnlPYiiPEQkwJomE9kCsP9aMmyhwBOpbbRISj1ua
+edESrpTC5DHpt1owjtAfHvD8TfmPWT1KSN1iCQAuh5hnEM5LLDljc/AYvJV4L5uR
+l/6t5dE8deg9ksY6lVRrUwHsXxUtBPhM82PWSrpAPNJCHLuBBVx+zDD//kOmt5oe
+OyYJ2RcDsnLmDfFLHbPcAwuyfmxQ+pbFBfiL4NaKoUWRy0viR4/3zulysCsCAwEA
+AQKCAgAphaNIl8VVtVpdtgED79xr7MqPxjj6/ogA5sPzZY0VCR6TMwXyRri1Ce43
+0Bv32+wQt+ohlf+UwxtsJ7jnDPCP4XFb5iobkG0DguCMxw8/hU9ZK6Sqn03sSUYH
+j/g91h/3ashg8W38oQT2flGf8y+5hF2zg1+mwGykvfPZCdhVN1ZYs5h+3AzEqlHU
+JG1eRJ+6EhxZr5mZNRYfvTkttx8gaPKiczOCbu9sa7PBa6CRrZBEnxv0+GVbwUX8
+a8RjQBsJnJTsC4mwJrx3H4V2M9rb6C224ORTJBHxEBr9bcjMcD4kzV0x69IlxVHq
+m7YBGz5morxm4OZ15BkjTFkeEW8C8bdpRrYoY8ocmybWUf6g5IxpE33M699lWzdn
++xwPloJOA5sqsDIXGXt4+KPb2hjHLpqS4V9Rw1JQErBgB9/0EHqK4u1kwI1/djea
+Ny26esGgjmupq+M+G3vQysKEX8m/KhYZKw8yqG4LrzUKp1uosEXEeE+FBnPW1fwU
+OapJTAKLDAeItz2YsZ+82oTMREKR6gNoAw3yF3dxo/E4sk3IDG4y3w7A8D5dlBBM
+hx2fDqnieS/OffGndbbbIIGH0Sb1MBURNlZlXwXz1hbACc8FMYmn4iyQUJfKlCfU
+Rp1jOR4silFxEGYhSi0Jw7+AJe1prZRyZYp2ZQQ+trGvqQNhwQKCAQEA7CsaDxvP
+L9GI8yFVznAG5SZvIut3/lLA7hd4F0LKJ277hW8YMENLjvmrtEQW1dyQqQXV+CpL
+QErvgRuVj9DyV6qOKDimmpqhT+YZlbxp98N9Ba8RJ4ckw07vPNvglTjAeIZyUbRP
+VX5Onr/OFw66GLzOIhsOnRlqviOKg2wm1kfBF3OBAwVczqh4PJ4gc3rbW9jPN3pn
+eaouV4CdGIooXckV6XtQCGjWFNNzxmuknn1GbLbHslGuDUX89rQsRsk9qZGpi1M1
+Cf2yaQY0d+AjDdPslXKZ92EbDAmo3KGtoxy2hWWytZHbUhtWgguEwxDMkJhJ0yCM
+ZSLQZ2TXlC/iCwKCAQEA5W0xuNTozb2UrwqEaDCkogxgdv5NdQvlvBM7+fD4RpOY
+ItDFcudhuapnpxdbPrdl3F5bgTXZJ4jKMIKePVveugI7wNCQX7aSET3U0Qj47RzA
+vVVHb0K3SZsicpK7K067Ejk1esxrPreaTnUj14jUle20Cq+3iysJnwMFs2DkmE1B
+UK6MiBJ1+MbFuBATw7TWxu8yPyfa3JzUAEsfP8NqqIlXrK26DdGefd8C0hysiq4X
+3matZ3SDck1mCk4LS9PCZZlDqdxLM6/UIoy4cj0qbSPdFMop8zjB8lF/1OABowkT
+e/9L0dpG08G35aEJJ6vKSGnFLbstgly165PlGapeYQKCAQEAwoShuw4BsXYZIYA0
+Z4sX8secRBvDwoKwi6pi7G3DiYU8v2OIfb//zOxRg3GNiWpY8A5xdSyIvJS7/hAV
+ONY1tQUyf2hhuPdhpCh2rED62up14CeYroD+Q6uRGwRTTzTmOp8qK6eirF0TLmf2
+vEESAGwKMEcu2zBjHeayIJsExftlzAYDndRd440ZM3xeaB8p69WAn0Y/UhNchg/V
+1K9+nfiRBrTdb3/BzHd5ZVWlyjCOv94wTuw9uosJ1r0Btu/rzO2/wpSvG+KMfzpw
+HshKtwn1VAaHUBz4JQsTvV2hYba1ktv3vNs81LzVnNkV6YC9rN7x92ZYnLh3BKIn
+edOSjwKCAQAP51zeAixNLsoixCjfjBetgAwj04cNCREY04CB1/lt8wdFypEVYQK+
+OxjKVW0m0NHHz+ap81ClU+8oI7XSbQ7oeAUqXYrUh7Ria5XYE7Ylwat+tG2qQcaw
+3IcryA4fd2qyXbLeW1NH2rRgofAlHcAW0I59eybPB+G32x7HC31tLVXMwPzO5fC1
+mRnVo4+rLlsBGU2zYRDj4B82Ef8NjX9URYkFWFmgYZqKAS6R4Bj52A2hhh6ZIFOI
+VeMv7a8Mx5YfMtuk57dy0spyxqx2htTtEeJecZEs4g9Xu9yPpiOW6KcoHk9kMaxd
+O32C9oHK9TalhGd9vw7tjX2y4eKsv8mhAoIBABEtJSjQ571YUbELvJgnVILWKExj
+nURnbQ8C2j2lLdb20fi8UGJDei9g2b2oCs3SfCaMcRqoOs4uy8ZJzofPelwWY1B7
+SZezn/2d1Q/cXpaXew++krhFvJFVxya6eLD7pvEVQAsGtkp9BTi2CFIhcGo5UQdc
+pym7XjFsW0LCI8mOAleuYe7DEpEU79RdsfxgQpeh1NgFJRpupHT6I2BkVijD/TI4
+kbwz11SuznkUTB4QePIwnEzV+gqDtlny4M1Qvsk8hqcU6JUOu+MOT1qnI6ZGSsdS
+D6RhPukordC9y/cbiV6qqKBVZ39O8ydWvpto/g7G7fSL5SddFuVRnwAV7Vg=
+-----END RSA PRIVATE KEY-----
diff --git a/apex/com.android.media.pk8 b/apex/com.android.media.pk8
new file mode 100644
index 0000000..6df741e
--- /dev/null
+++ b/apex/com.android.media.pk8
Binary files differ
diff --git a/apex/com.android.media.swcodec.avbpubkey b/apex/com.android.media.swcodec.avbpubkey
new file mode 100644
index 0000000..0459723
--- /dev/null
+++ b/apex/com.android.media.swcodec.avbpubkey
Binary files differ
diff --git a/apex/com.android.media.swcodec.pem b/apex/com.android.media.swcodec.pem
new file mode 100644
index 0000000..e379cd3
--- /dev/null
+++ b/apex/com.android.media.swcodec.pem
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKgIBAAKCAgEAvB6lOEEOR58KMcFlayEZjsXuPgcfHi/OPxcvfpiGLCpOcK3l
+OPChWUvDRcIHMB7BO+Csfxs0HgsHvvZfNyoNIm99WcjFbboiO7WrBBArIszPr14X
+cfY2NxzT9LBj+EqAnbdL+4OQW1/npLHNE0qtDcxL71ipbjSuKNb58E9qGL0KwvkS
+fwwueWj++bg/iz7dq0mz7iKpnxYscNm4RhJjqcG2Usmg4Ejhr8h5UmOUmTJbObC/
+vzClXQqeeuzS8NTtGVgQ/CI9gC2WN9upq2p/2T7P4U3o3CWvBytUoLKR0UyC83ey
+S8XJgOa42uWR3T/eJOI1ZS4H6Srg1o2XC8Yb8EprFI/NM6/+/5DX/FgDimsslAP6
+Qq4+pSte9v/FjWGqy7QBQaefFRGRuS63xHcSZhXC9J2CFdnxo8+65QT8r4yfQEei
+Ax/0Q94yB7VIL1pIJxHEonKjtd3iKdFEKQzADJ3edsmtHybERdJKCxcm9QIrDCsC
+4YVT9nX0OoC9RD5d5EVD7W5I6eEnRu6igrKIKgUVppeYFQNZD+o+eiNJa4yoggRl
+h8sT0/xLKjMRxAQ7fafi1j+LB2O7UgJmIDDAnidq8Aoz7h3pNi139rNWrjNfwhus
+nMcZvL9dTVv26JWeESHP/zAfAX7j1rfkDwR02ocRLquwEUs1+UHA27Wi1bMCAwEA
+AQKCAgAO3PT83tb7/arWh4s1zaWxTB4otHNW9Tv8bB6KiA6Bys3rxTGJMCnvXjcN
+eekLekKWMoguer3BaemwwtJ/D0l+YQSsZVqD8uLliNL8PTLLSxdVqb98d5GNBTAR
+8yXS5kAHNgZA1wI+1fL9ZjbnwUyu/Gc7f+vTE0J3Y5TX0c52KemBwiAd/Z5mZU9P
+96i9nbfx4p7ev8pbEWttdyZCEw3gybdYDyowzlFWjCZZxhhlij7+7eIYfwVxtncT
+C0cXVBtvly+wXBwz1mY5/5cGPiHfzkCqcndlfWy4ykmjcLhoqvzls51Ys0Xac2BD
+m0PNEVDB5UWGuv5RA9xD12gJvBtU3D7ggMw6C5RcXJT+jSYmSFtD2klWi+It8A/N
+Hv42soKskt6JqYAWE1cvJ3PEqH9ASEJNq2R0Z/PmuM000UJyzU9KId3SNwjXA1Xc
+Kn9hRga4uf9elHTjkTDt79/8+Xv7hjer9sF/S/np7g04rUjIWkuFkC/7NK2tQSh1
+mljV1sD9SF4DPfVK75LwJJaQUlI7TtGd5KJ7FzZwvb+w8ODrpW3hkt6FcI6KwE/a
+QT1T2Z9DknXJSYNdWGrj6vMHsYMiyz8IdAHSCrOB6eXCQxpitbn6W71Raw7f9UaZ
+VDK5AhTU493hkGj1no4cJwecXInMigg/c4ywk2Ibh6IV8O0nkQKCAQEA2+dQQ0IF
+vvVgmQ2WxHBD7M2mbOyf43YBY6Ka6oPBNGPVpZE8X8LoTavQLV+SgCkH8T6gY7XS
+5L4Ze0JFxfua0o1rm6+L2XrOx5F/A2Y40YcPclEik5h1woSwH/J1iHGiEhY8Nqeu
+9GCvjQojkgXx/Rn3Nz+lpvZ329O3H85RWWGF0l60RwLOkig0ZwUb619t8affmGIl
+sxdDv2nfy7OtJX8iGDua7Kf64dvVWQKKtACWkARrlkcWX3uoESxkpSDxue+z7ndH
+o7uHLfM8Tx+Rn+QvYWuRW5TPLbEDMbIYrX65ISt2r/T7v/04XdAC8YpCQRytlqPI
+fpDm15htyHBizQKCAQEA2v+5otRoY56JduISaVGlsJ/IbvKzDAIyWmM14EpRCR5E
+lu+MpTcRAiFQAbHGXr1tMlTFdVFD090WAzIKaKtADFVLXobIHeGspnRCq5OpVp9W
+RvLtVwLxflHAc2yN9/LNtnBqHUgt+S01LBPElybdGHQRTtqAKXhkp31sM21O34Go
+Pri/IxgupWxykMaW44Kig1Cr5DKvc8cwUsGuyDdJm8oBQeNPTMWqSnXtqoTWSaYg
+2kxiMTFokrkSXgufb8wng6OXt/QelywrhG3hAsldPO3GdKidDSxhWZSgpUXXFdAX
+y4GO0IcRJBF/WJtYTYtR+l84nQA2/1Ye4ujFlT0afwKCAQEAmXrXpSm2cvI2CnzW
+hqJIdkWOa6W3bn1VOOIrt5Rfy54GZnl4pumVU2igcpqq2HJKzdDFBvLHj8kyZbn6
+ktUp2NzFhzK9q/uvyNA+0vOMoojeeg4w0MzvG+WaO6Hw8FtHH9KPEiJ01LGKtSin
+bOpjXCC8T75HcsHBJBefTz6jvnt3eD2LG6jU3mPbNy/0rZG8XZaqU2PlJhsNuNI/
+VaBBL9OMy1cGqTgQvYS+YlKI1ls2uqurH4bcEaZvxhSy5iGZNQodDkoIITnofmSu
+6haBgBQ2EYuPN1kkRKKwNQY1fRneQk1gmCynbPdiWO+urkCuP12xtlr3u4aM51rG
+/Meb3QKCAQEA12SxZm9XhLOHLIBJ74A4YLGm50iZxXPbpn7xnHo7naZBe9p8EHtK
+pTeygxggrUnOPrSVyT92YMiQP/BVwIC+a+LwUDZsWMd/ke/DKxH+eY4Zw4pm2S+x
+6bXqfRwFvhr3LTr/g3FcljlalNGUh73Xs5dk9pN9fkxFY16+rw4Rh0709Uur4o6E
+QnuZar+H5Ji10kXj6nvXiR4ebybEC3QlV66k8fLqKe44AShf61jfkmxs34hFA3E/
+EyAn6ouv8rtvGdArBuh5teHho0yXBLCcnbKXgGHepfhCf2LpZeR9GZ0j6iqxFnPh
+7gGvqKyReyNOK9y/x9tQPG6tzit3OcNxbQKCAQEAuDheDOSkXPopXMvLAKOHBIdZ
+rbQ7oFTDHt59gbucM7U8/l2YtaxuKOQFBLnzQa/amIkkrtklYwOsz8E24d7Nm39w
+ykLHwX0XrmjAm6M4XKmDv66a+kSnSV6LEbKZdjvXP02DV+tGeZ5VsnNvJDquxMsD
+fvRTspB8j8CpU96szekxl/tCRhqbdw/4kVTSj5BF++OaRRcJrAyj1B2qf1ynAZE1
+gUvVPkEYa914zcrxg9XIXT4M7yqB7i8KJegOtOtcWjJ7uTiP+638AvygJLMJnSrV
++HjFZWG6P9btZmLHSEBRvwGOAilp0qejXo866l0fmnlGy7ehKz8u3PzvnlPYjQ==
+-----END RSA PRIVATE KEY-----
diff --git a/apex/com.android.media.swcodec.pk8 b/apex/com.android.media.swcodec.pk8
new file mode 100644
index 0000000..05a4216
--- /dev/null
+++ b/apex/com.android.media.swcodec.pk8
Binary files differ
diff --git a/apex/com.android.media.swcodec.x509.pem b/apex/com.android.media.swcodec.x509.pem
new file mode 100644
index 0000000..67b9b4f
--- /dev/null
+++ b/apex/com.android.media.swcodec.x509.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIIF3jCCA8agAwIBAgIJAIM72JpD4v6XMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD
+VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4g
+VmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEiMCAGA1UE
+AwwZY29tLmFuZHJvaWQubWVkaWEuc3djb2RlYzAgFw0xOTAyMTEwMjExMTFaGA80
+NzU3MDEwNzAyMTExMVowgYIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9y
+bmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAw
+DgYDVQQLDAdBbmRyb2lkMSIwIAYDVQQDDBljb20uYW5kcm9pZC5tZWRpYS5zd2Nv
+ZGVjMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsqXE0AIWpLW9Tgq2
+nQGph7KZ6L2Q9oxviqCVHxIaPqfhM2SwTbycADIQeqrrlRxhddVkjLuMUkJa7mev
+fERmgpiOfnPIlGK6PTs2gljCkskZhF3bgfeyuHt0tsYO+UaN8MVoZD7/QdiE46w2
+OMDClG1UqgiqOBhLTEN/cHXObnUiiVXUYqN8aYZf6L6Fs3yQi2ZZgfbxTVFewqdv
+aLLOqCYnVYXZH+ZxbXESA0M+WXKgRKsYTj2GYs3eko1rFi4Y6uHVLx45yaoT5u/i
+SxPEkocyMCKvGJWu4XlSOd3EjSOMaqCOYVyGLxdlnQWQU7PZDqBSJ0SysWgpFHpB
+I15c2jhRdXOCfQ9ZtDfPZkE0a2A8kJDAoF1mzTp6IvBAWUsl5nHPw5CWkFpNad/h
+tqqGCScWbiKZuvrQ4/RQNm3f1K+mxX9TrjFigpqNO6d4pGAo1fa6sHR3xWPw/myq
+h5ZJjVnXU5Yq64S4xWOssfjpOg7RfNuvzuk3ok3MYs1mbx3vhZOj5km1f3qrgX9c
+mXjYnyXD0jJBm4uAJWXLdK9PlZvlXbztMCzYj832Io4pFLCtSxkzX75t1em36Nv0
+mNp6NtSSy6SFSq8l7IsXV2FNyUiyHWxS/UQm8pYg5Q5dWHvEEF78P6lV0wRa6FQl
+BBSgpqTAI092KIjDDtB7GQCgV5ECAwEAAaNTMFEwHQYDVR0OBBYEFAFIdFTDEDft
+ewSSAS7Fa3OZ5TXzMB8GA1UdIwQYMBaAFAFIdFTDEDftewSSAS7Fa3OZ5TXzMA8G
+A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAC5e3zXythJCGmz1FmAV
+8Y/UI+Glg6G0x/k04WaRG0DPLLjlJ1F0LM1/IReBSgXcYAL0CAgPycf/rGPOgMFm
+tQxYyjBUxKdjpIqU5DJoV1feanGveIRpto1YRKNgHuzG9rZGR4AgPnt6X4Yxlq04
+lI7QpWadXe1myARJhj3niSNY9+2wEInkx4ZuCO1LtIGqnbdc8jQ8YoVqIE5N4kuM
+ccyPYgsdABtopbjN92rueu8sfF8R6ROy+tNgb6OjpAAevtnBfZ2LXqfObKirHCK+
+k6w4WSB1UUoZ3Xgz8sJtXgokvYeInkN8tHuTagHYU2VQTcA0rdBGMN/1OljJpWlN
+0UUq4fAYU6cN4lHxr2LM9If4WvAzdLAWvaIZrDqaU4i/zYT9l6rR4lC2KW3EHWov
+nPXfgEJJ8AP1iRGibvew3i3SB6XTWFQYTUIBeJfDz/KDXQabP+yzXWISdZCUMUpx
+f+Raqsb5MoKaJdVgnSL0mBunjCyJDzzg34J7oGx6/BnwoiOrwLN4Qaz5U8jbrPSx
+p9LfleCcO7ZdeE8GKqx0X1T4d7tradtmxOS8Iwr4niskkHGRkzozvVvuyGKmoN2k
+162Vfjq+ddj7qEpSh3BS6hHU+vlMbC9L0trGxPxFEAHDrwu0KwGNduTkiu/3jvfB
+JTgH8P9mD1loYxRdo+vet8eQ
+-----END CERTIFICATE-----
diff --git a/apex/com.android.media.x509.pem b/apex/com.android.media.x509.pem
new file mode 100644
index 0000000..e7908fa
--- /dev/null
+++ b/apex/com.android.media.x509.pem
@@ -0,0 +1,33 @@
+-----BEGIN CERTIFICATE-----
+MIIFzDCCA7SgAwIBAgIJAO05DBBusaaLMA0GCSqGSIb3DQEBCwUAMHoxCzAJBgNV
+BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBW
+aWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRyb2lkMRowGAYDVQQD
+DBFjb20uYW5kcm9pZC5tZWRpYTAgFw0xOTAxMjUxNzE3MTdaGA80NzU2MTIyMTE3
+MTcxN1owejELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNV
+BAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoMB0FuZHJvaWQxEDAOBgNVBAsMB0Fu
+ZHJvaWQxGjAYBgNVBAMMEWNvbS5hbmRyb2lkLm1lZGlhMIICIjANBgkqhkiG9w0B
+AQEFAAOCAg8AMIICCgKCAgEAmNkVxUbp/bLbeGbvKqYXzwBycSDpmOhh///lNGYQ
+/AMUD0q6EaZzU2bd4aL0rOGqfoYlhKd0kMVmMUmfdE9ODAfKxleEeEaRl2GJS8a9
+ABi770l3GHbB2xMI2sEWeOD9xsPFF6+ByPZmoUuNhMr4pUbXsDpE3h8ljrgXHtIg
+bh7ofbvddruwBV0lS1k9OZ9jPVGhEKkJnhgQa67cwgdjizAMbI0Dcz9gtMMawsDj
+Z2aQd1r+vxgh1/XkI/NMmXCnG2ERytXcJeC5S4gEtHfTTPoP0FuVgSB6y6dalMuZ
+F0NBZw8Mvgdy3QJip0uNa36J63CMZKTJWbTdlFpPL2hk0PgaYvje8C5Xtk5282wT
+dMocc8n2zIXbzbnSXGvjcNZib3Pfu55YUnX6eTqZ1BxlJ0FHZAsC4quFFWXxYBYD
+LCRoNNFEtIDQpuvuHF2DuHNDULpAQjy2y6+7eot0KEsVoDmZ4H8BpuAVVu2SxYNb
+gYflR9SmM0tmYeAcRT48q3xrocGyEHMqvgQRUpPfvct/8l8xVcDzOI/sJVDqmYzM
+u0Cj3fkSypGDJOMF/esFSmVvoI01tS7kaNS5vvtKYib//xqKRC9f0dCsGfFLnuUK
+o4KYbYWYwMyJqEd/5/ZvXyKIPAEeJL174L9+wTkc3cQpoBwJN4t+2E5MnhOEq6do
+5L0CAwEAAaNTMFEwHQYDVR0OBBYEFHjNK/GZko1RdZp+8iavWXL5xz9wMB8GA1Ud
+IwQYMBaAFHjNK/GZko1RdZp+8iavWXL5xz9wMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
+KoZIhvcNAQELBQADggIBACmPQMksuLrNV1vbI44S1f70I0FHdBxchFGB39zuLbcn
+SsYom/LPtYJiD0Dl4bB4eb+ZnxkQP2XeP6pycmUH2j1EWexFwvdUvlfe8Qz+wAec
+ap4AxiX4Z2Ke2ivYotIZFUHdZOLkX20js8Wex1mzY43MLQn5APl9gK1VZTxDggeR
+EObH1S+JVjGwQqYZj2e6gNZH34Q25NQ698RL85GDkYtSISAifJtaJsU/B3vKm82I
+k9xMiCooCH6bRdGHG1jze4SRpidjxEm8cxkiaQagfcuXeCLziXJr3qAMKYiEY6bp
+0+bAqCt3S8OrrN3RQZfQrnlwitsM1jJJ/+C+WoDg4eY5AFrXDLvNeKh1qO/f8xv+
+fCXkQPcVVphLfRH9oxNrSgOWBP5/qIDH4s1YUL9luGT6H+08dlue3RkbzDbBqsQu
+7fQ/BbrIG/GuVKgyEM+a7C9gv7zc86YlueVYJEyxKidnn7RxOqyDBqyyfXA3zvme
+Rro7xIrMHPL7Nu3AWjwjXzbp/w0z+tEFPsfVB+OOHKsWPcUG0HUTJGkyeO/uHRjN
+qPEkkf7BHHUO4V2gjOIdCsELxKwHf7vsZTOk40EV751fZ7FDHMr1eddQkgH4eqAb
+DB79uP+SLfUo+42n4q6eMmoqw8d76bBXRoUhIo/Ms4sebhV0sRtAS67OQioc9UUg
+-----END CERTIFICATE-----
diff --git a/apex/ld.config.txt b/apex/ld.config.txt
new file mode 100644
index 0000000..a5937fd
--- /dev/null
+++ b/apex/ld.config.txt
@@ -0,0 +1,131 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Bionic loader config file for the media swcodec APEX.
+#
+# There are no versioned APEX paths here - this APEX module does not support
+# having several versions mounted.
+
+dir.swcodec = /apex/com.android.media.swcodec/bin/
+
+[swcodec]
+additional.namespaces = platform,sphal
+
+###############################################################################
+# "default" namespace
+#
+# This namespace is for the binaries and libraries on the swcodec APEX.
+###############################################################################
+
+namespace.default.isolated = true
+namespace.default.visible = true
+
+namespace.default.search.paths      = /apex/com.android.media.swcodec/${LIB}
+namespace.default.asan.search.paths = /apex/com.android.media.swcodec/${LIB}
+
+namespace.default.links = platform
+
+# TODO: replace the following when apex has a way to auto-generate this list
+# namespace.default.link.platform.shared_libs  = %LLNDK_LIBRARIES%
+# namespace.default.link.platform.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
+namespace.default.link.platform.shared_libs = libEGL.so:libGLESv1_CM.so:libGLESv2.so:libGLESv3.so:libRS.so:libandroid_net.so:libc.so:libcgrouprc.so:libclang_rt.asan-aarch64-android.so:libclang_rt.asan-arm-android.so:libclang_rt.hwasan-aarch64-android.so:libclang_rt.asan-i686-android.so:libclang_rt.asan-x86_64-android.so:libdl.so:libft2.so:liblog.so:libm.so:libmediandk.so:libnativewindow.so:libneuralnetworks.so:libsync.so:libvndksupport.so:libdl_android.so:libvulkan.so
+
+###############################################################################
+# "platform" namespace
+#
+# This namespace is for linking to LLNDK and ASAN libraries on the system.
+###############################################################################
+
+namespace.platform.isolated = true
+
+namespace.platform.search.paths = /system/${LIB}
+namespace.platform.asan.search.paths  = /data/asan/system/${LIB}
+namespace.platform.asan.search.paths +=           /system/${LIB}
+
+# /system/lib/libc.so, etc are symlinks to /apex/com.android.lib/lib/bionic/libc.so, etc.
+# Add /apex/... pat to the permitted paths because linker uses realpath(3)
+# to check the accessibility of the lib. We could add this to search.paths
+# instead but that makes the resolution of bionic libs be dependent on
+# the order of /system/lib and /apex/... in search.paths. If /apex/...
+# is after /system/lib, then /apex/... is never tried because libc.so
+# is always found in /system/lib but fails to pass the accessibility test
+# because of its realpath.  It's better to not depend on the ordering if
+# possible.
+namespace.platform.permitted.paths = /apex/com.android.runtime/${LIB}/bionic
+namespace.platform.asan.permitted.paths = /apex/com.android.runtime/${LIB}/bionic
+
+###############################################################################
+# "sphal" namespace
+#
+###############################################################################
+namespace.sphal.isolated = true
+namespace.sphal.visible = true
+
+# Keep the below in sync with "sphal" namespace in system's /etc/ld.config.txt
+# Codec2 has dependencies on some SP-hals (eg. android.hardware.graphics.mapper@2.0)
+# These are dlopen'ed by libvndksupport.so.
+namespace.sphal.search.paths  = /odm/${LIB}
+namespace.sphal.search.paths += /vendor/${LIB}
+
+namespace.sphal.permitted.paths  = /odm/${LIB}
+namespace.sphal.permitted.paths += /vendor/${LIB}
+namespace.sphal.permitted.paths += /vendor/${LIB}/hw
+namespace.sphal.permitted.paths += /system/vendor/${LIB}
+
+namespace.sphal.asan.search.paths  = /data/asan/odm/${LIB}
+namespace.sphal.asan.search.paths +=           /odm/${LIB}
+namespace.sphal.asan.search.paths += /data/asan/vendor/${LIB}
+namespace.sphal.asan.search.paths +=           /vendor/${LIB}
+
+namespace.sphal.asan.permitted.paths  = /data/asan/odm/${LIB}
+namespace.sphal.asan.permitted.paths +=           /odm/${LIB}
+namespace.sphal.asan.permitted.paths += /data/asan/vendor/${LIB}
+namespace.sphal.asan.permitted.paths +=           /vendor/${LIB}
+
+# Keep the below in sync with "vndk" namespace in system's /etc/ld.config.txt
+# System's sphal namespace links to vndk namespace for %VNDK_SAMEPROCESS_LIBRARIES%,
+# since we don't have a good way to auto-expand %VNDK_SAMEPROCESS_LIBRARIES%,
+# we'll add the vndk paths below.
+
+namespace.sphal.search.paths += /odm/${LIB}/vndk-sp
+namespace.sphal.search.paths += /vendor/${LIB}/vndk-sp
+namespace.sphal.search.paths += /system/${LIB}/vndk-sp${VNDK_VER}
+
+namespace.sphal.permitted.paths += /odm/${LIB}/hw
+namespace.sphal.permitted.paths += /odm/${LIB}/egl
+namespace.sphal.permitted.paths += /vendor/${LIB}/hw
+namespace.sphal.permitted.paths += /vendor/${LIB}/egl
+namespace.sphal.permitted.paths += /system/vendor/${LIB}/hw
+namespace.sphal.permitted.paths += /system/vendor/${LIB}/egl
+# This is exceptionally required since android.hidl.memory@1.0-impl.so is here
+namespace.sphal.permitted.paths += /system/${LIB}/vndk-sp${VNDK_VER}/hw
+
+namespace.sphal.asan.search.paths += /data/asan/odm/${LIB}/vndk-sp
+namespace.sphal.asan.search.paths +=           /odm/${LIB}/vndk-sp
+namespace.sphal.asan.search.paths += /data/asan/vendor/${LIB}/vndk-sp
+namespace.sphal.asan.search.paths +=           /vendor/${LIB}/vndk-sp
+namespace.sphal.asan.search.paths += /data/asan/system/${LIB}/vndk-sp${VNDK_VER}
+namespace.sphal.asan.search.paths +=           /system/${LIB}/vndk-sp${VNDK_VER}
+
+namespace.sphal.asan.permitted.paths += /data/asan/odm/${LIB}/hw
+namespace.sphal.asan.permitted.paths +=           /odm/${LIB}/hw
+namespace.sphal.asan.permitted.paths += /data/asan/odm/${LIB}/egl
+namespace.sphal.asan.permitted.paths +=           /odm/${LIB}/egl
+namespace.sphal.asan.permitted.paths += /data/asan/vendor/${LIB}/hw
+namespace.sphal.asan.permitted.paths +=           /vendor/${LIB}/hw
+namespace.sphal.asan.permitted.paths += /data/asan/vendor/${LIB}/egl
+namespace.sphal.asan.permitted.paths +=           /vendor/${LIB}/egl
+
+namespace.sphal.asan.permitted.paths += /data/asan/system/${LIB}/vndk-sp${VNDK_VER}/hw
+namespace.sphal.asan.permitted.paths +=           /system/${LIB}/vndk-sp${VNDK_VER}/hw
+
+# Once in this namespace, access to libraries in /system/lib is restricted. Only
+# libs listed here can be used.
+namespace.sphal.links = platform
+
+# TODO: replace the following when apex has a way to auto-generate this list
+# namespace.sphal.link.platform.shared_libs  = %LLNDK_LIBRARIES%
+# namespace.sphal.link.platform.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
+namespace.sphal.link.platform.shared_libs = libEGL.so:libGLESv1_CM.so:libGLESv2.so:libGLESv3.so:libRS.so:libandroid_net.so:libc.so:libcgrouprc.so:libclang_rt.asan-aarch64-android.so:libclang_rt.asan-arm-android.so:libclang_rt.hwasan-aarch64-android.so:libclang_rt.asan-i686-android.so:libclang_rt.asan-x86_64-android.so:libdl.so:libft2.so:liblog.so:libm.so:libmediandk.so:libnativewindow.so:libneuralnetworks.so:libsync.so:libvndksupport.so:libvulkan.so
+
+# Add a link for libz.so which is llndk on devices where VNDK is not enforced.
+namespace.sphal.link.platform.shared_libs += libz.so
diff --git a/apex/manifest.json b/apex/manifest.json
new file mode 100644
index 0000000..3011ee8
--- /dev/null
+++ b/apex/manifest.json
@@ -0,0 +1,4 @@
+{
+  "name": "com.android.media",
+  "version": 290000000
+}
diff --git a/apex/manifest_codec.json b/apex/manifest_codec.json
new file mode 100644
index 0000000..83a5178
--- /dev/null
+++ b/apex/manifest_codec.json
@@ -0,0 +1,4 @@
+{
+  "name": "com.android.media.swcodec",
+  "version": 290000000
+}
diff --git a/apex/mediaswcodec.rc b/apex/mediaswcodec.rc
new file mode 100644
index 0000000..d17481b
--- /dev/null
+++ b/apex/mediaswcodec.rc
@@ -0,0 +1,7 @@
+service media.swcodec /apex/com.android.media.swcodec/bin/mediaswcodec
+    class main
+    user mediacodec
+    group camera drmrpc mediadrm
+    override
+    ioprio rt 4
+    writepid /dev/cpuset/foreground/tasks
diff --git a/apex/testing/Android.bp b/apex/testing/Android.bp
new file mode 100644
index 0000000..701ced7
--- /dev/null
+++ b/apex/testing/Android.bp
@@ -0,0 +1,29 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+apex {
+    name: "test_com.android.media",
+    manifest: "test_manifest.json",
+    file_contexts: "com.android.media",
+    defaults: ["com.android.media-defaults"],
+    installable: false,
+}
+
+apex {
+    name: "test_com.android.media.swcodec",
+    manifest: "test_manifest_codec.json",
+    file_contexts: "com.android.media.swcodec",
+    defaults: ["com.android.media.swcodec-defaults"],
+    installable: false,
+}
diff --git a/apex/testing/test_manifest.json b/apex/testing/test_manifest.json
new file mode 100644
index 0000000..ddd642e
--- /dev/null
+++ b/apex/testing/test_manifest.json
@@ -0,0 +1,4 @@
+{
+  "name": "com.android.media",
+  "version": 300000000
+}
diff --git a/apex/testing/test_manifest_codec.json b/apex/testing/test_manifest_codec.json
new file mode 100644
index 0000000..2320fd7
--- /dev/null
+++ b/apex/testing/test_manifest_codec.json
@@ -0,0 +1,4 @@
+{
+  "name": "com.android.media.swcodec",
+  "version": 300000000
+}
diff --git a/camera/Android.bp b/camera/Android.bp
index 24b3918..2800595 100644
--- a/camera/Android.bp
+++ b/camera/Android.bp
@@ -12,8 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-subdirs = ["ndk"]
-
 cc_library_shared {
     name: "libcamera_client",
 
@@ -43,6 +41,7 @@
         "ICameraRecordingProxyListener.cpp",
         "camera2/CaptureRequest.cpp",
         "camera2/OutputConfiguration.cpp",
+        "camera2/SessionConfiguration.cpp",
         "camera2/SubmitInfo.cpp",
         "CameraBase.cpp",
         "CameraUtils.cpp",
diff --git a/camera/CameraMetadata.cpp b/camera/CameraMetadata.cpp
index e143e05..92fe84b 100644
--- a/camera/CameraMetadata.cpp
+++ b/camera/CameraMetadata.cpp
@@ -22,7 +22,6 @@
 
 #include <binder/Parcel.h>
 #include <camera/CameraMetadata.h>
-#include <camera/VendorTagDescriptor.h>
 
 namespace android {
 
@@ -409,6 +408,79 @@
     return res;
 }
 
+status_t CameraMetadata::removePermissionEntries(metadata_vendor_id_t vendorId,
+        std::vector<int32_t> *tagsRemoved) {
+    uint32_t tagCount = 0;
+    std::vector<uint32_t> tagsToRemove;
+
+    if (tagsRemoved == nullptr) {
+        return BAD_VALUE;
+    }
+
+    sp<VendorTagDescriptor> vTags = VendorTagDescriptor::getGlobalVendorTagDescriptor();
+    if ((nullptr == vTags.get()) || (0 >= vTags->getTagCount())) {
+        sp<VendorTagDescriptorCache> cache =
+            VendorTagDescriptorCache::getGlobalVendorTagCache();
+        if (cache.get()) {
+            cache->getVendorTagDescriptor(vendorId, &vTags);
+        }
+    }
+
+    if ((nullptr != vTags.get()) && (vTags->getTagCount() > 0)) {
+        tagCount = vTags->getTagCount();
+        uint32_t *vendorTags = new uint32_t[tagCount];
+        if (nullptr == vendorTags) {
+            return NO_MEMORY;
+        }
+        vTags->getTagArray(vendorTags);
+
+        tagsToRemove.reserve(tagCount);
+        tagsToRemove.insert(tagsToRemove.begin(), vendorTags, vendorTags + tagCount);
+
+        delete [] vendorTags;
+        tagCount = 0;
+    }
+
+    auto tagsNeedingPermission = get_camera_metadata_permission_needed(&tagCount);
+    if (tagCount > 0) {
+        tagsToRemove.reserve(tagsToRemove.capacity() + tagCount);
+        tagsToRemove.insert(tagsToRemove.end(), tagsNeedingPermission,
+                tagsNeedingPermission + tagCount);
+    }
+
+    tagsRemoved->reserve(tagsToRemove.size());
+    for (const auto &it : tagsToRemove) {
+        if (exists(it)) {
+            auto rc = erase(it);
+            if (NO_ERROR != rc) {
+                ALOGE("%s: Failed to erase tag: %x", __func__, it);
+                return rc;
+            }
+            tagsRemoved->push_back(it);
+        }
+    }
+
+    // Update the available characterstics accordingly
+    if (exists(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS)) {
+        std::vector<uint32_t> currentKeys;
+
+        std::sort(tagsRemoved->begin(), tagsRemoved->end());
+        auto keys = find(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
+        currentKeys.reserve(keys.count);
+        currentKeys.insert(currentKeys.end(), keys.data.i32, keys.data.i32 + keys.count);
+        std::sort(currentKeys.begin(), currentKeys.end());
+
+        std::vector<int32_t> newKeys(keys.count);
+        auto end = std::set_difference(currentKeys.begin(), currentKeys.end(), tagsRemoved->begin(),
+                tagsRemoved->end(), newKeys.begin());
+        newKeys.resize(end - newKeys.begin());
+
+        update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, newKeys.data(), newKeys.size());
+    }
+
+    return NO_ERROR;
+}
+
 void CameraMetadata::dump(int fd, int verbosity, int indentation) const {
     dump_indented_camera_metadata(mBuffer, fd, verbosity, indentation);
 }
diff --git a/camera/CaptureResult.cpp b/camera/CaptureResult.cpp
index 928a6bc..1d8e8c4 100644
--- a/camera/CaptureResult.cpp
+++ b/camera/CaptureResult.cpp
@@ -39,6 +39,16 @@
     parcel->readInt64(&frameNumber);
     parcel->readInt32(&partialResultCount);
     parcel->readInt32(&errorStreamId);
+    auto physicalCameraIdPresent = parcel->readBool();
+    if (physicalCameraIdPresent) {
+        String16 cameraId;
+        status_t res = OK;
+        if ((res = parcel->readString16(&cameraId)) != OK) {
+            ALOGE("%s: Failed to read camera id: %d", __FUNCTION__, res);
+            return res;
+        }
+        errorPhysicalCameraId = cameraId;
+    }
 
     return OK;
 }
@@ -56,6 +66,16 @@
     parcel->writeInt64(frameNumber);
     parcel->writeInt32(partialResultCount);
     parcel->writeInt32(errorStreamId);
+    if (errorPhysicalCameraId.size() > 0) {
+        parcel->writeBool(true);
+        status_t res = OK;
+        if ((res = parcel->writeString16(errorPhysicalCameraId)) != OK) {
+            ALOGE("%s: Failed to write physical camera ID to parcel: %d", __FUNCTION__, res);
+            return res;
+        }
+    } else {
+        parcel->writeBool(false);
+    }
 
     return OK;
 }
diff --git a/camera/OWNERS b/camera/OWNERS
index 18acfee..d6b95da 100644
--- a/camera/OWNERS
+++ b/camera/OWNERS
@@ -1,6 +1,8 @@
-cychen@google.com
 epeev@google.com
 etalvala@google.com
+jchowdhary@google.com
 shuzhenwang@google.com
 yinchiayeh@google.com
+# backup owner
+cychen@google.com
 zhijunhe@google.com
diff --git a/camera/VendorTagDescriptor.cpp b/camera/VendorTagDescriptor.cpp
index 4c28789..d713d2d 100644
--- a/camera/VendorTagDescriptor.cpp
+++ b/camera/VendorTagDescriptor.cpp
@@ -315,6 +315,10 @@
     return OK;
 }
 
+ssize_t VendorTagDescriptor::getSectionIndex(uint32_t tag) const {
+    return mTagToSectionMap.valueFor(tag);
+}
+
 void VendorTagDescriptor::dump(int fd, int verbosity, int indentation) const {
 
     size_t size = mTagToNameMap.size();
@@ -407,6 +411,11 @@
     return res;
 }
 
+const std::unordered_map<metadata_vendor_id_t, sp<android::VendorTagDescriptor>> &
+            VendorTagDescriptorCache::getVendorIdsAndTagDescriptors() {
+    return mVendorMap;
+}
+
 int VendorTagDescriptorCache::getTagCount(metadata_vendor_id_t id) const {
     int ret = 0;
     auto desc = mVendorMap.find(id);
@@ -566,7 +575,7 @@
 
     for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
         uint32_t tag = tagArray[i];
-        String8 sectionString = tagToSectionMap.valueFor(tag);
+        const String8& sectionString = tagToSectionMap.valueFor(tag);
 
         // Set up tag to section index map
         ssize_t index = sections.indexOf(sectionString);
diff --git a/camera/aidl/android/hardware/ICameraService.aidl b/camera/aidl/android/hardware/ICameraService.aidl
index 9c0f28b..3e8992a 100644
--- a/camera/aidl/android/hardware/ICameraService.aidl
+++ b/camera/aidl/android/hardware/ICameraService.aidl
@@ -108,7 +108,7 @@
      *
      * Also returns the set of currently-known camera IDs and state of each device.
      * Adding a listener will trigger the torch status listener to fire for all
-     * devices that have a flash unit
+     * devices that have a flash unit.
      */
     CameraStatus[] addListener(ICameraServiceListener listener);
 
@@ -149,8 +149,10 @@
     const int API_VERSION_1 = 1;
     const int API_VERSION_2 = 2;
 
-    // Determines if a particular API version is supported directly
+    // Determines if a particular API version is supported directly for a cameraId.
     boolean supportsCameraApi(String cameraId, int apiVersion);
+    // Determines if a cameraId is a hidden physical camera of a logical multi-camera.
+    boolean isHiddenPhysicalCamera(String cameraId);
 
     void setTorchMode(String cameraId, boolean enabled, IBinder clientBinder);
 
@@ -160,6 +162,28 @@
      * Callers require the android.permission.CAMERA_SEND_SYSTEM_EVENTS permission.
      */
     const int EVENT_NONE = 0;
-    const int EVENT_USER_SWITCHED = 1;
+    const int EVENT_USER_SWITCHED = 1; // The argument is the set of new foreground user IDs.
     oneway void notifySystemEvent(int eventId, in int[] args);
+
+    /**
+     * Notify the camera service of a device physical status change. May only be called from
+     * a privileged process.
+     *
+     * newState is a bitfield consisting of DEVICE_STATE_* values combined together. Valid state
+     * combinations are device-specific. At device startup, the camera service will assume the device
+     * state is NORMAL until otherwise notified.
+     *
+     * Callers require the android.permission.CAMERA_SEND_SYSTEM_EVENTS permission.
+     */
+    oneway void notifyDeviceStateChange(long newState);
+
+    // Bitfield constants for notifyDeviceStateChange
+    // All bits >= 32 are for custom vendor states
+    // Written as ints since AIDL does not support long constants.
+    const int DEVICE_STATE_NORMAL = 0;
+    const int DEVICE_STATE_BACK_COVERED = 1;
+    const int DEVICE_STATE_FRONT_COVERED = 2;
+    const int DEVICE_STATE_FOLDED = 4;
+    const int DEVICE_STATE_LAST_FRAMEWORK_BIT = 0x80000000; // 1 << 31;
+
 }
diff --git a/camera/aidl/android/hardware/ICameraServiceListener.aidl b/camera/aidl/android/hardware/ICameraServiceListener.aidl
index f871ce4..e9dcbdb 100644
--- a/camera/aidl/android/hardware/ICameraServiceListener.aidl
+++ b/camera/aidl/android/hardware/ICameraServiceListener.aidl
@@ -76,4 +76,11 @@
     const int TORCH_STATUS_UNKNOWN = -1;
 
     oneway void onTorchStatusChanged(int status, String cameraId);
+
+    /**
+     * Notify registered clients about camera access priority changes.
+     * Clients which were previously unable to open a certain camera device
+     * can retry after receiving this callback.
+     */
+    oneway void onCameraAccessPrioritiesChanged();
 }
diff --git a/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl b/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
index 4ced08c..49dfde8 100644
--- a/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
+++ b/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
@@ -19,6 +19,7 @@
 import android.hardware.camera2.CaptureRequest;
 import android.hardware.camera2.impl.CameraMetadataNative;
 import android.hardware.camera2.params.OutputConfiguration;
+import android.hardware.camera2.params.SessionConfiguration;
 import android.hardware.camera2.utils.SubmitInfo;
 import android.view.Surface;
 
@@ -83,6 +84,16 @@
      */
     void endConfigure(int operatingMode, in CameraMetadataNative sessionParams);
 
+    /**
+      * Check whether a particular session configuration has camera device
+      * support.
+      *
+      * @param sessionConfiguration Specific session configuration to be verified.
+      * @return true  - in case the stream combination is supported.
+      *         false - in case there is no device support.
+      */
+    boolean isSessionConfigurationSupported(in SessionConfiguration sessionConfiguration);
+
     void deleteStream(int streamId);
 
     /**
diff --git a/camera/aidl/android/hardware/camera2/params/SessionConfiguration.aidl b/camera/aidl/android/hardware/camera2/params/SessionConfiguration.aidl
new file mode 100644
index 0000000..abf1556
--- /dev/null
+++ b/camera/aidl/android/hardware/camera2/params/SessionConfiguration.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.camera2.params;
+
+/** @hide */
+parcelable SessionConfiguration cpp_header "camera/camera2/SessionConfiguration.h";
diff --git a/camera/camera2/OutputConfiguration.cpp b/camera/camera2/OutputConfiguration.cpp
index feb04c2..4e9b27d 100644
--- a/camera/camera2/OutputConfiguration.cpp
+++ b/camera/camera2/OutputConfiguration.cpp
@@ -167,14 +167,24 @@
 }
 
 OutputConfiguration::OutputConfiguration(sp<IGraphicBufferProducer>& gbp, int rotation,
+        const String16& physicalId,
         int surfaceSetID, bool isShared) {
     mGbps.push_back(gbp);
     mRotation = rotation;
     mSurfaceSetID = surfaceSetID;
     mIsDeferred = false;
     mIsShared = isShared;
+    mPhysicalCameraId = physicalId;
 }
 
+OutputConfiguration::OutputConfiguration(
+        const std::vector<sp<IGraphicBufferProducer>>& gbps,
+    int rotation, const String16& physicalCameraId, int surfaceSetID,  int surfaceType,
+    int width, int height, bool isShared)
+  : mGbps(gbps), mRotation(rotation), mSurfaceSetID(surfaceSetID), mSurfaceType(surfaceType),
+    mWidth(width), mHeight(height), mIsDeferred(false), mIsShared(isShared),
+    mPhysicalCameraId(physicalCameraId) { }
+
 status_t OutputConfiguration::writeToParcel(android::Parcel* parcel) const {
 
     if (parcel == nullptr) return BAD_VALUE;
diff --git a/camera/camera2/SessionConfiguration.cpp b/camera/camera2/SessionConfiguration.cpp
new file mode 100644
index 0000000..a431a33
--- /dev/null
+++ b/camera/camera2/SessionConfiguration.cpp
@@ -0,0 +1,133 @@
+/*
+**
+** Copyright 2018, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#define LOG_TAG "SessionConfiguration"
+//#define LOG_NDEBUG 0
+
+#include <utils/Log.h>
+
+#include <camera/camera2/SessionConfiguration.h>
+#include <camera/camera2/OutputConfiguration.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+status_t SessionConfiguration::readFromParcel(const android::Parcel* parcel) {
+    status_t err = OK;
+    int operatingMode = 0;
+
+    if (parcel == nullptr) return BAD_VALUE;
+
+    if ((err = parcel->readInt32(&operatingMode)) != OK) {
+        ALOGE("%s: Failed to read operating mode from parcel", __FUNCTION__);
+        return err;
+    }
+
+    int inputWidth = 0;
+    if ((err = parcel->readInt32(&inputWidth)) != OK) {
+        ALOGE("%s: Failed to read input width from parcel", __FUNCTION__);
+        return err;
+    }
+
+    int inputHeight = 0;
+    if ((err = parcel->readInt32(&inputHeight)) != OK) {
+        ALOGE("%s: Failed to read input height from parcel", __FUNCTION__);
+        return err;
+    }
+
+    int inputFormat = -1;
+    if ((err = parcel->readInt32(&inputFormat)) != OK) {
+        ALOGE("%s: Failed to read input format from parcel", __FUNCTION__);
+        return err;
+    }
+
+    std::vector<OutputConfiguration> outputStreams;
+    if ((err = parcel->readParcelableVector(&outputStreams)) != OK) {
+        ALOGE("%s: Failed to read output configurations from parcel", __FUNCTION__);
+        return err;
+    }
+
+    mOperatingMode = operatingMode;
+    mInputWidth = inputWidth;
+    mInputHeight = inputHeight;
+    mInputFormat = inputFormat;
+    for (auto& stream : outputStreams) {
+        mOutputStreams.push_back(stream);
+    }
+
+
+    return err;
+}
+
+status_t SessionConfiguration::writeToParcel(android::Parcel* parcel) const {
+
+    if (parcel == nullptr) return BAD_VALUE;
+    status_t err = OK;
+
+    err = parcel->writeInt32(mOperatingMode);
+    if (err != OK) return err;
+
+    err = parcel->writeInt32(mInputWidth);
+    if (err != OK) return err;
+
+    err = parcel->writeInt32(mInputHeight);
+    if (err != OK) return err;
+
+    err = parcel->writeInt32(mInputFormat);
+    if (err != OK) return err;
+
+    err = parcel->writeParcelableVector(mOutputStreams);
+    if (err != OK) return err;
+
+    return OK;
+}
+
+bool SessionConfiguration::outputsEqual(const SessionConfiguration& other) const {
+    const std::vector<OutputConfiguration>& otherOutputStreams =
+            other.getOutputConfigurations();
+
+    if (mOutputStreams.size() !=  otherOutputStreams.size()) {
+        return false;
+    }
+
+    for (size_t i = 0; i < mOutputStreams.size(); i++) {
+        if (mOutputStreams[i] != otherOutputStreams[i]) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool SessionConfiguration::outputsLessThan(const SessionConfiguration& other) const {
+    const std::vector<OutputConfiguration>& otherOutputStreams =
+            other.getOutputConfigurations();
+
+    if (mOutputStreams.size() !=  otherOutputStreams.size()) {
+        return mOutputStreams.size() < otherOutputStreams.size();
+    }
+
+    for (size_t i = 0; i < mOutputStreams.size(); i++) {
+        if (mOutputStreams[i] != otherOutputStreams[i]) {
+            return mOutputStreams[i] < otherOutputStreams[i];
+        }
+    }
+
+    return false;
+}
+
+}; // namespace android
diff --git a/camera/cameraserver/Android.bp b/camera/cameraserver/Android.bp
new file mode 100644
index 0000000..ecaba3a
--- /dev/null
+++ b/camera/cameraserver/Android.bp
@@ -0,0 +1,49 @@
+// Copyright 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_binary {
+    name: "cameraserver",
+
+    srcs: ["main_cameraserver.cpp"],
+
+    shared_libs: [
+        "libcameraservice",
+        "liblog",
+        "libutils",
+        "libui",
+        "libgui",
+        "libbinder",
+        "libhidlbase",
+        "libhidltransport",
+        "android.hardware.camera.common@1.0",
+        "android.hardware.camera.provider@2.4",
+        "android.hardware.camera.provider@2.5",
+        "android.hardware.camera.device@1.0",
+        "android.hardware.camera.device@3.2",
+        "android.hardware.camera.device@3.4",
+    ],
+    compile_multilib: "32",
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-Wno-unused-parameter",
+    ],
+
+    init_rc: ["cameraserver.rc"],
+
+    vintf_fragments: [
+        "manifest_android.frameworks.cameraservice.service@2.0.xml",
+    ],
+}
diff --git a/camera/cameraserver/Android.mk b/camera/cameraserver/Android.mk
deleted file mode 100644
index b8c94e6..0000000
--- a/camera/cameraserver/Android.mk
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright 2015 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-	main_cameraserver.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-	libcameraservice \
-	liblog \
-	libutils \
-	libui \
-	libgui \
-	libbinder \
-	libhidltransport \
-	android.hardware.camera.common@1.0 \
-	android.hardware.camera.provider@2.4 \
-	android.hardware.camera.device@1.0 \
-	android.hardware.camera.device@3.2
-
-LOCAL_MODULE:= cameraserver
-LOCAL_32_BIT_ONLY := true
-
-LOCAL_CFLAGS += -Wall -Wextra -Werror -Wno-unused-parameter
-
-LOCAL_INIT_RC := cameraserver.rc
-
-include $(BUILD_EXECUTABLE)
diff --git a/camera/cameraserver/main_cameraserver.cpp b/camera/cameraserver/main_cameraserver.cpp
index 3972436..53b3d84 100644
--- a/camera/cameraserver/main_cameraserver.cpp
+++ b/camera/cameraserver/main_cameraserver.cpp
@@ -26,8 +26,9 @@
 {
     signal(SIGPIPE, SIG_IGN);
 
-    // Set 3 threads for HIDL calls
-    hardware::configureRpcThreadpool(3, /*willjoin*/ false);
+    // Set 5 threads for HIDL calls. Now cameraserver will serve HIDL calls in
+    // addition to consuming them from the Camera HAL as well.
+    hardware::configureRpcThreadpool(5, /*willjoin*/ false);
 
     sp<ProcessState> proc(ProcessState::self());
     sp<IServiceManager> sm = defaultServiceManager();
diff --git a/camera/cameraserver/manifest_android.frameworks.cameraservice.service@2.0.xml b/camera/cameraserver/manifest_android.frameworks.cameraservice.service@2.0.xml
new file mode 100644
index 0000000..601c717
--- /dev/null
+++ b/camera/cameraserver/manifest_android.frameworks.cameraservice.service@2.0.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="framework">
+    <hal>
+        <name>android.frameworks.cameraservice.service</name>
+        <transport>hwbinder</transport>
+        <version>2.0</version>
+        <interface>
+            <name>ICameraService</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/camera/include/camera/CameraMetadata.h b/camera/include/camera/CameraMetadata.h
index d284477..844bb80 100644
--- a/camera/include/camera/CameraMetadata.h
+++ b/camera/include/camera/CameraMetadata.h
@@ -22,6 +22,7 @@
 #include <utils/String8.h>
 #include <utils/Vector.h>
 #include <binder/Parcelable.h>
+#include <camera/VendorTagDescriptor.h>
 
 namespace android {
 
@@ -170,6 +171,12 @@
     status_t erase(uint32_t tag);
 
     /**
+     * Remove metadata entries that need additional permissions.
+     */
+    status_t removePermissionEntries(metadata_vendor_id_t vendorId,
+            std::vector<int32_t> *tagsRemoved /*out*/);
+
+    /**
      * Swap the underlying camera metadata between this and the other
      * metadata object.
      */
diff --git a/camera/include/camera/CaptureResult.h b/camera/include/camera/CaptureResult.h
index 56fa178..ef830b5 100644
--- a/camera/include/camera/CaptureResult.h
+++ b/camera/include/camera/CaptureResult.h
@@ -70,6 +70,13 @@
     int32_t errorStreamId;
 
     /**
+     * For capture result errors, the physical camera ID in case the respective request contains
+     * a reference to physical camera device.
+     * Empty otherwise.
+     */
+    String16  errorPhysicalCameraId;
+
+    /**
      * Constructor initializes object as invalid by setting requestId to be -1.
      */
     CaptureResultExtras()
@@ -79,7 +86,8 @@
           precaptureTriggerId(0),
           frameNumber(0),
           partialResultCount(0),
-          errorStreamId(-1) {
+          errorStreamId(-1),
+          errorPhysicalCameraId() {
     }
 
     /**
diff --git a/camera/include/camera/VendorTagDescriptor.h b/camera/include/camera/VendorTagDescriptor.h
index 904fba2..6f55890 100644
--- a/camera/include/camera/VendorTagDescriptor.h
+++ b/camera/include/camera/VendorTagDescriptor.h
@@ -99,6 +99,11 @@
         void dump(int fd, int verbosity, int indentation) const;
 
         /**
+         * Get Section for corresponding tag.
+         */
+        ssize_t getSectionIndex(uint32_t tag) const;
+
+        /**
          * Read values VendorTagDescriptor object from the given parcel.
          *
          * Returns OK on success, or a negative error code.
@@ -206,6 +211,9 @@
      */
     void dump(int fd, int verbosity, int indentation) const;
 
+    const std::unordered_map<metadata_vendor_id_t, sp<android::VendorTagDescriptor>> &
+            getVendorIdsAndTagDescriptors();
+
   protected:
     std::unordered_map<metadata_vendor_id_t, sp<android::VendorTagDescriptor>> mVendorMap;
     struct vendor_tag_cache_ops mVendorCacheOps;
diff --git a/camera/include/camera/camera2/OutputConfiguration.h b/camera/include/camera/camera2/OutputConfiguration.h
index a80f44b..95c4f39 100644
--- a/camera/include/camera/camera2/OutputConfiguration.h
+++ b/camera/include/camera/camera2/OutputConfiguration.h
@@ -65,8 +65,15 @@
     OutputConfiguration(const android::Parcel& parcel);
 
     OutputConfiguration(sp<IGraphicBufferProducer>& gbp, int rotation,
+            const String16& physicalCameraId,
             int surfaceSetID = INVALID_SET_ID, bool isShared = false);
 
+    OutputConfiguration(const std::vector<sp<IGraphicBufferProducer>>& gbps,
+                        int rotation, const String16& physicalCameraId,
+                        int surfaceSetID = INVALID_SET_ID,
+                        int surfaceType = OutputConfiguration::SURFACE_TYPE_UNKNOWN, int width = 0,
+                        int height = 0, bool isShared = false);
+
     bool operator == (const OutputConfiguration& other) const {
         return ( mRotation == other.mRotation &&
                 mSurfaceSetID == other.mSurfaceSetID &&
diff --git a/camera/include/camera/camera2/SessionConfiguration.h b/camera/include/camera/camera2/SessionConfiguration.h
new file mode 100644
index 0000000..64288ed
--- /dev/null
+++ b/camera/include/camera/camera2/SessionConfiguration.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_CAMERA2_SESSIONCONFIGURATION_H
+#define ANDROID_HARDWARE_CAMERA2_SESSIONCONFIGURATION_H
+
+#include <binder/Parcelable.h>
+
+namespace android {
+
+namespace hardware {
+namespace camera2 {
+namespace params {
+
+class OutputConfiguration;
+
+class SessionConfiguration : public android::Parcelable {
+public:
+
+    const std::vector<OutputConfiguration>& getOutputConfigurations() const {
+        return mOutputStreams;
+    }
+
+    int getInputWidth() const { return mInputWidth; }
+    int getInputHeight() const { return mInputHeight; }
+    int getInputFormat() const { return mInputFormat; }
+    int getOperatingMode() const { return mOperatingMode; }
+
+    virtual status_t writeToParcel(android::Parcel* parcel) const override;
+    virtual status_t readFromParcel(const android::Parcel* parcel) override;
+
+    SessionConfiguration() :
+            mInputWidth(0),
+            mInputHeight(0),
+            mInputFormat(-1),
+            mOperatingMode(-1) {}
+
+    SessionConfiguration(const android::Parcel& parcel) {
+        readFromParcel(&parcel);
+    }
+
+    SessionConfiguration(int inputWidth, int inputHeight, int inputFormat, int operatingMode) :
+        mInputWidth(inputWidth), mInputHeight(inputHeight), mInputFormat(inputFormat),
+        mOperatingMode(operatingMode) {}
+
+    bool operator == (const SessionConfiguration& other) const {
+        return (outputsEqual(other) &&
+                mInputWidth == other.mInputWidth &&
+                mInputHeight == other.mInputHeight &&
+                mInputFormat == other.mInputFormat &&
+                mOperatingMode == other.mOperatingMode);
+    }
+
+    bool operator != (const SessionConfiguration& other) const {
+        return !(*this == other);
+    }
+
+    bool operator < (const SessionConfiguration& other) const {
+        if (*this == other) return false;
+
+        if (mInputWidth != other.mInputWidth) {
+            return mInputWidth < other.mInputWidth;
+        }
+
+        if (mInputHeight != other.mInputHeight) {
+            return mInputHeight < other.mInputHeight;
+        }
+
+        if (mInputFormat != other.mInputFormat) {
+            return mInputFormat < other.mInputFormat;
+        }
+
+        if (mOperatingMode != other.mOperatingMode) {
+            return mOperatingMode < other.mOperatingMode;
+        }
+
+        return outputsLessThan(other);
+    }
+
+    bool operator > (const SessionConfiguration& other) const {
+        return (*this != other && !(*this < other));
+    }
+
+    bool outputsEqual(const SessionConfiguration& other) const;
+    bool outputsLessThan(const SessionConfiguration& other) const;
+    void addOutputConfiguration(const OutputConfiguration &config) {
+        mOutputStreams.push_back(config);
+    }
+
+private:
+
+    std::vector<OutputConfiguration> mOutputStreams;
+    int                              mInputWidth, mInputHeight, mInputFormat, mOperatingMode;
+};
+} // namespace params
+} // namespace camera2
+} // namespace hardware
+
+using hardware::camera2::params::SessionConfiguration;
+
+}; // namespace android
+
+#endif
diff --git a/camera/ndk/Android.bp b/camera/ndk/Android.bp
index 97cf6bf..a2ee65d 100644
--- a/camera/ndk/Android.bp
+++ b/camera/ndk/Android.bp
@@ -30,3 +30,133 @@
     srcs: ["include/camera/**/*.h"],
     license: "NOTICE",
 }
+
+cc_library_shared {
+    name: "libcamera2ndk",
+    srcs: [
+        "NdkCameraManager.cpp",
+        "NdkCameraMetadata.cpp",
+        "NdkCameraDevice.cpp",
+        "NdkCaptureRequest.cpp",
+        "NdkCameraCaptureSession.cpp",
+        "impl/ACameraManager.cpp",
+        "impl/ACameraMetadata.cpp",
+        "impl/ACameraDevice.cpp",
+        "impl/ACameraCaptureSession.cpp",
+    ],
+    shared_libs: [
+        "libbinder",
+        "liblog",
+        "libgui",
+        "libutils",
+        "libandroid_runtime",
+        "libcamera_client",
+        "libstagefright_foundation",
+        "libcutils",
+        "libcamera_metadata",
+        "libmediandk",
+        "libnativewindow",
+    ],
+    cflags: [
+        "-fvisibility=hidden",
+        "-DEXPORT=__attribute__ ((visibility (\"default\")))",
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+    ],
+    // TODO: jchowdhary@, use header_libs instead b/131165718
+    include_dirs: [
+        "system/media/private/camera/include",
+    ],
+    export_include_dirs: ["include"],
+    export_shared_lib_headers: [
+        "libnativewindow",
+    ],
+    version_script: "libcamera2ndk.map.txt",
+}
+
+cc_library_shared {
+    name: "libcamera2ndk_vendor",
+    vendor: true,
+    srcs: [
+        "ndk_vendor/impl/ACameraDevice.cpp",
+        "ndk_vendor/impl/ACameraManager.cpp",
+        "ndk_vendor/impl/utils.cpp",
+        "impl/ACameraMetadata.cpp",
+        "impl/ACameraCaptureSession.cpp",
+        "NdkCameraMetadata.cpp",
+        "NdkCameraCaptureSession.cpp",
+        "NdkCameraManager.cpp",
+        "NdkCameraDevice.cpp",
+        "NdkCaptureRequest.cpp",
+    ],
+
+    export_include_dirs: ["include"],
+    export_shared_lib_headers: [
+        "libcutils",
+    ],
+    local_include_dirs: [
+        ".",
+        "include",
+        "impl",
+    ],
+    cflags: [
+        "-fvisibility=hidden",
+        "-DEXPORT=__attribute__((visibility(\"default\")))",
+        "-D__ANDROID_VNDK__",
+    ],
+
+    shared_libs: [
+        "libhwbinder",
+        "libfmq",
+        "libhidlbase",
+        "libhardware",
+        "libnativewindow",
+        "liblog",
+        "libutils",
+        "libstagefright_foundation",
+        "libcutils",
+        "libcamera_metadata",
+        "libmediandk",
+        "android.frameworks.cameraservice.device@2.0",
+        "android.frameworks.cameraservice.common@2.0",
+        "android.frameworks.cameraservice.service@2.0",
+    ],
+
+    static_libs: [
+        "android.hardware.camera.common@1.0-helper",
+        "libarect",
+    ],
+    // TODO: jchowdhary@, use header_libs instead b/131165718
+    include_dirs: [
+        "system/media/private/camera/include",
+    ],
+    product_variables: {
+        pdk: {
+            enabled: false,
+        },
+    },
+}
+
+cc_test {
+    name: "AImageReaderVendorTest",
+    vendor: true,
+    srcs: ["ndk_vendor/tests/AImageReaderVendorTest.cpp"],
+    shared_libs: [
+        "libhwbinder",
+        "libcamera2ndk_vendor",
+        "libcamera_metadata",
+        "libmediandk",
+        "libnativewindow",
+        "libutils",
+        "libui",
+        "libcutils",
+        "liblog",
+    ],
+    static_libs: [
+        "android.hardware.camera.common@1.0-helper",
+    ],
+    cflags: [
+        "-D__ANDROID_VNDK__",
+    ],
+}
diff --git a/camera/ndk/Android.mk b/camera/ndk/Android.mk
deleted file mode 100644
index f5ff69d..0000000
--- a/camera/ndk/Android.mk
+++ /dev/null
@@ -1,56 +0,0 @@
-#
-# Copyright (C) 2015 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-LOCAL_PATH:= $(call my-dir)
-
-ifneq ($(TARGET_BUILD_PDK), true)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:=                  \
-    NdkCameraManager.cpp           \
-    NdkCameraMetadata.cpp          \
-    NdkCameraDevice.cpp            \
-    NdkCaptureRequest.cpp          \
-    NdkCameraCaptureSession.cpp    \
-    impl/ACameraManager.cpp        \
-    impl/ACameraMetadata.cpp       \
-    impl/ACameraDevice.cpp         \
-    impl/ACameraCaptureSession.cpp
-
-LOCAL_MODULE:= libcamera2ndk
-
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-
-LOCAL_CFLAGS += -fvisibility=hidden -D EXPORT='__attribute__ ((visibility ("default")))'
-LOCAL_CFLAGS += -Wall -Wextra -Werror
-
-LOCAL_SHARED_LIBRARIES := \
-    libbinder \
-    liblog \
-    libgui \
-    libutils \
-    libandroid_runtime \
-    libcamera_client \
-    libstagefright_foundation \
-    libcutils \
-    libcamera_metadata \
-    libmediandk
-
-include $(BUILD_SHARED_LIBRARY)
-
-endif
diff --git a/camera/ndk/NdkCameraCaptureSession.cpp b/camera/ndk/NdkCameraCaptureSession.cpp
index fd95296..1ac8482 100644
--- a/camera/ndk/NdkCameraCaptureSession.cpp
+++ b/camera/ndk/NdkCameraCaptureSession.cpp
@@ -28,6 +28,8 @@
 #include <camera/NdkCameraCaptureSession.h>
 #include "impl/ACameraCaptureSession.h"
 
+#include "impl/ACameraCaptureSession.inc"
+
 using namespace android;
 
 EXPORT
@@ -78,11 +80,39 @@
 
     if (session->isClosed()) {
         ALOGE("%s: session %p is already closed", __FUNCTION__, session);
-        *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
+        if (captureSequenceId != nullptr) {
+            *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
+        }
         return ACAMERA_ERROR_SESSION_CLOSED;
     }
 
-    return session->capture(cbs, numRequests, requests, captureSequenceId);
+    return session->capture(
+            cbs, numRequests, requests, captureSequenceId);
+}
+
+EXPORT
+camera_status_t ACameraCaptureSession_logicalCamera_capture(
+        ACameraCaptureSession* session,
+        /*optional*/ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs,
+        int numRequests, ACaptureRequest** requests,
+        /*optional*/int* captureSequenceId) {
+    ATRACE_CALL();
+    if (session == nullptr || requests == nullptr || numRequests < 1) {
+        ALOGE("%s: Error: invalid input: session %p, numRequest %d, requests %p",
+                __FUNCTION__, session, numRequests, requests);
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+
+    if (session->isClosed()) {
+        ALOGE("%s: session %p is already closed", __FUNCTION__, session);
+        if (captureSequenceId) {
+            *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
+        }
+        return ACAMERA_ERROR_SESSION_CLOSED;
+    }
+
+    return session->capture(
+            lcbs, numRequests, requests, captureSequenceId);
 }
 
 EXPORT
@@ -99,7 +129,9 @@
 
     if (session->isClosed()) {
         ALOGE("%s: session %p is already closed", __FUNCTION__, session);
-        *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
+        if (captureSequenceId) {
+            *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
+        }
         return ACAMERA_ERROR_SESSION_CLOSED;
     }
 
@@ -107,6 +139,30 @@
 }
 
 EXPORT
+camera_status_t ACameraCaptureSession_logicalCamera_setRepeatingRequest(
+        ACameraCaptureSession* session,
+        /*optional*/ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs,
+        int numRequests, ACaptureRequest** requests,
+        /*optional*/int* captureSequenceId) {
+    ATRACE_CALL();
+    if (session == nullptr || requests == nullptr || numRequests < 1) {
+        ALOGE("%s: Error: invalid input: session %p, numRequest %d, requests %p",
+                __FUNCTION__, session, numRequests, requests);
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+
+    if (session->isClosed()) {
+        ALOGE("%s: session %p is already closed", __FUNCTION__, session);
+        if (captureSequenceId) {
+            *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
+        }
+        return ACAMERA_ERROR_SESSION_CLOSED;
+    }
+
+    return session->setRepeatingRequest(lcbs, numRequests, requests, captureSequenceId);
+}
+
+EXPORT
 camera_status_t ACameraCaptureSession_stopRepeating(ACameraCaptureSession* session) {
     ATRACE_CALL();
     if (session == nullptr) {
diff --git a/camera/ndk/NdkCameraDevice.cpp b/camera/ndk/NdkCameraDevice.cpp
index 812a312..691996b 100644
--- a/camera/ndk/NdkCameraDevice.cpp
+++ b/camera/ndk/NdkCameraDevice.cpp
@@ -24,7 +24,15 @@
 #include <camera/NdkCameraDevice.h>
 #include "impl/ACameraCaptureSession.h"
 
-using namespace android;
+using namespace android::acam;
+
+bool areWindowTypesEqual(ACameraWindowType *a, ACameraWindowType *b) {
+#ifdef __ANDROID_VNDK__
+    return utils::isWindowNativeHandleEqual(a, b);
+#else
+    return a == b;
+#endif
+}
 
 EXPORT
 camera_status_t ACameraDevice_close(ACameraDevice* device) {
@@ -70,7 +78,34 @@
             ALOGE("%s: unknown template ID %d", __FUNCTION__, templateId);
             return ACAMERA_ERROR_INVALID_PARAMETER;
     }
-    return device->createCaptureRequest(templateId, request);
+    return device->createCaptureRequest(templateId, nullptr /*physicalIdList*/, request);
+}
+
+EXPORT
+camera_status_t ACameraDevice_createCaptureRequest_withPhysicalIds(
+        const ACameraDevice* device,
+        ACameraDevice_request_template templateId,
+        const ACameraIdList* physicalCameraIdList,
+        ACaptureRequest** request) {
+    ATRACE_CALL();
+    if (device == nullptr || request == nullptr || physicalCameraIdList == nullptr) {
+        ALOGE("%s: invalid argument! device %p request %p, physicalCameraIdList %p",
+                __FUNCTION__, device, request, physicalCameraIdList);
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+    switch (templateId) {
+        case TEMPLATE_PREVIEW:
+        case TEMPLATE_STILL_CAPTURE:
+        case TEMPLATE_RECORD:
+        case TEMPLATE_VIDEO_SNAPSHOT:
+        case TEMPLATE_ZERO_SHUTTER_LAG:
+        case TEMPLATE_MANUAL:
+            break;
+        default:
+            ALOGE("%s: unknown template ID %d", __FUNCTION__, templateId);
+            return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+    return device->createCaptureRequest(templateId, physicalCameraIdList, request);
 }
 
 EXPORT
@@ -96,7 +131,7 @@
 
 EXPORT
 camera_status_t ACaptureSessionOutput_create(
-        ANativeWindow* window, /*out*/ACaptureSessionOutput** out) {
+        ACameraWindowType* window, /*out*/ACaptureSessionOutput** out) {
     ATRACE_CALL();
     if (window == nullptr || out == nullptr) {
         ALOGE("%s: Error: bad argument. window %p, out %p",
@@ -109,7 +144,7 @@
 
 EXPORT
 camera_status_t ACaptureSessionSharedOutput_create(
-        ANativeWindow* window, /*out*/ACaptureSessionOutput** out) {
+        ACameraWindowType* window, /*out*/ACaptureSessionOutput** out) {
     ATRACE_CALL();
     if (window == nullptr || out == nullptr) {
         ALOGE("%s: Error: bad argument. window %p, out %p",
@@ -121,8 +156,22 @@
 }
 
 EXPORT
+camera_status_t ACaptureSessionPhysicalOutput_create(
+        ACameraWindowType* window, const char* physicalId,
+        /*out*/ACaptureSessionOutput** out) {
+    ATRACE_CALL();
+    if (window == nullptr || physicalId == nullptr || out == nullptr) {
+        ALOGE("%s: Error: bad argument. window %p, physicalId %p, out %p",
+                __FUNCTION__, window, physicalId, out);
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+    *out = new ACaptureSessionOutput(window, false, physicalId);
+    return ACAMERA_OK;
+}
+
+EXPORT
 camera_status_t ACaptureSessionSharedOutput_add(ACaptureSessionOutput *out,
-        ANativeWindow* window) {
+        ACameraWindowType* window) {
     ATRACE_CALL();
     if ((window == nullptr) || (out == nullptr)) {
         ALOGE("%s: Error: bad argument. window %p, out %p",
@@ -134,7 +183,7 @@
                 __FUNCTION__);
         return ACAMERA_ERROR_INVALID_OPERATION;
     }
-    if (out->mWindow == window) {
+    if (areWindowTypesEqual(out->mWindow, window)) {
         ALOGE("%s: Error trying to add the same window associated with the output configuration",
                 __FUNCTION__);
         return ACAMERA_ERROR_INVALID_PARAMETER;
@@ -147,7 +196,7 @@
 
 EXPORT
 camera_status_t ACaptureSessionSharedOutput_remove(ACaptureSessionOutput *out,
-        ANativeWindow* window) {
+        ACameraWindowType* window) {
     ATRACE_CALL();
     if ((window == nullptr) || (out == nullptr)) {
         ALOGE("%s: Error: bad argument. window %p, out %p",
@@ -159,7 +208,7 @@
                 __FUNCTION__);
         return ACAMERA_ERROR_INVALID_OPERATION;
     }
-    if (out->mWindow == window) {
+    if (areWindowTypesEqual(out->mWindow, window)) {
         ALOGE("%s: Error trying to remove the same window associated with the output configuration",
                 __FUNCTION__);
         return ACAMERA_ERROR_INVALID_PARAMETER;
@@ -238,3 +287,16 @@
     }
     return device->createCaptureSession(outputs, sessionParameters, callbacks, session);
 }
+
+EXPORT
+camera_status_t ACameraDevice_isSessionConfigurationSupported(
+        const ACameraDevice* device,
+        const ACaptureSessionOutputContainer* sessionOutputContainer) {
+    ATRACE_CALL();
+    if (device == nullptr || sessionOutputContainer == nullptr) {
+        ALOGE("%s: Error: invalid input: device %p, sessionOutputContainer %p",
+                __FUNCTION__, device, sessionOutputContainer);
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+    return device->isSessionConfigurationSupported(sessionOutputContainer);
+}
diff --git a/camera/ndk/NdkCameraManager.cpp b/camera/ndk/NdkCameraManager.cpp
index 60b4763..3d231a8 100644
--- a/camera/ndk/NdkCameraManager.cpp
+++ b/camera/ndk/NdkCameraManager.cpp
@@ -22,9 +22,15 @@
 #include <utils/Trace.h>
 
 #include <camera/NdkCameraManager.h>
-#include "impl/ACameraManager.h"
 
-using namespace android;
+#ifdef __ANDROID_VNDK__
+#include "ndk_vendor/impl/ACameraManager.h"
+#else
+#include "impl/ACameraManager.h"
+#endif
+#include "impl/ACameraMetadata.h"
+
+using namespace android::acam;
 
 EXPORT
 ACameraManager* ACameraManager_create() {
@@ -99,6 +105,60 @@
 }
 
 EXPORT
+camera_status_t ACameraManager_registerExtendedAvailabilityCallback(
+        ACameraManager* /*manager*/, const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
+    ATRACE_CALL();
+    if (callback == nullptr) {
+        ALOGE("%s: invalid argument! callback is null!", __FUNCTION__);
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+    if ((callback->availabilityCallbacks.onCameraAvailable == nullptr) ||
+            (callback->availabilityCallbacks.onCameraUnavailable == nullptr) ||
+            (callback->onCameraAccessPrioritiesChanged == nullptr)) {
+        ALOGE("%s: invalid argument! callback %p, "
+                "onCameraAvailable %p, onCameraUnavailable %p onCameraAccessPrioritiesChanged %p",
+               __FUNCTION__, callback,
+               callback->availabilityCallbacks.onCameraAvailable,
+               callback->availabilityCallbacks.onCameraUnavailable,
+               callback->onCameraAccessPrioritiesChanged);
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+    auto reservedEntriesCount = sizeof(callback->reserved) / sizeof(callback->reserved[0]);
+    for (size_t i = 0; i < reservedEntriesCount; i++) {
+        if (callback->reserved[i] != nullptr) {
+            ALOGE("%s: invalid argument! callback reserved entries must be set to NULL",
+                    __FUNCTION__);
+            return ACAMERA_ERROR_INVALID_PARAMETER;
+        }
+    }
+    CameraManagerGlobal::getInstance().registerExtendedAvailabilityCallback(callback);
+    return ACAMERA_OK;
+}
+
+EXPORT
+camera_status_t ACameraManager_unregisterExtendedAvailabilityCallback(
+        ACameraManager* /*manager*/, const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
+    ATRACE_CALL();
+    if (callback == nullptr) {
+        ALOGE("%s: invalid argument! callback is null!", __FUNCTION__);
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+    if ((callback->availabilityCallbacks.onCameraAvailable == nullptr) ||
+            (callback->availabilityCallbacks.onCameraUnavailable == nullptr) ||
+            (callback->onCameraAccessPrioritiesChanged == nullptr)) {
+        ALOGE("%s: invalid argument! callback %p, "
+                "onCameraAvailable %p, onCameraUnavailable %p onCameraAccessPrioritiesChanged %p",
+               __FUNCTION__, callback,
+               callback->availabilityCallbacks.onCameraAvailable,
+               callback->availabilityCallbacks.onCameraUnavailable,
+               callback->onCameraAccessPrioritiesChanged);
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+    CameraManagerGlobal::getInstance().unregisterExtendedAvailabilityCallback(callback);
+    return ACAMERA_OK;
+}
+
+EXPORT
 camera_status_t ACameraManager_getCameraCharacteristics(
         ACameraManager* mgr, const char* cameraId, ACameraMetadata** chars){
     ATRACE_CALL();
@@ -107,7 +167,14 @@
                 __FUNCTION__, mgr, cameraId, chars);
         return ACAMERA_ERROR_INVALID_PARAMETER;
     }
-    return mgr->getCameraCharacteristics(cameraId, chars);
+    sp<ACameraMetadata> spChars;
+    camera_status_t status = mgr->getCameraCharacteristics(cameraId, &spChars);
+    if (status != ACAMERA_OK) {
+        return status;
+    }
+    spChars->incStrong((void*) ACameraManager_getCameraCharacteristics);
+    *chars = spChars.get();
+    return ACAMERA_OK;
 }
 
 EXPORT
@@ -123,3 +190,17 @@
     }
     return mgr->openCamera(cameraId, callback, device);
 }
+
+#ifdef __ANDROID_VNDK__
+EXPORT
+camera_status_t ACameraManager_getTagFromName(ACameraManager *mgr, const char* cameraId,
+        const char *name, /*out*/uint32_t *tag) {
+    ATRACE_CALL();
+    if (mgr == nullptr || cameraId == nullptr || name == nullptr) {
+        ALOGE("%s: invalid argument! mgr %p cameraId %p name %p",
+                __FUNCTION__, mgr, cameraId, name);
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+    return mgr->getTagFromName(cameraId, name, tag);
+}
+#endif
diff --git a/camera/ndk/NdkCameraMetadata.cpp b/camera/ndk/NdkCameraMetadata.cpp
index 65de81f..9a39ed8 100644
--- a/camera/ndk/NdkCameraMetadata.cpp
+++ b/camera/ndk/NdkCameraMetadata.cpp
@@ -57,13 +57,32 @@
         ALOGE("%s: src is null!", __FUNCTION__);
         return nullptr;
     }
-    return new ACameraMetadata(*src);
+    ACameraMetadata* copy = new ACameraMetadata(*src);
+    copy->incStrong((void*) ACameraMetadata_copy);
+    return copy;
 }
 
 EXPORT
 void ACameraMetadata_free(ACameraMetadata* metadata) {
     ATRACE_CALL();
     if (metadata != nullptr) {
-        delete metadata;
+        metadata->decStrong((void*) ACameraMetadata_free);
     }
 }
+
+EXPORT
+bool ACameraMetadata_isLogicalMultiCamera(const ACameraMetadata* staticMetadata,
+        /*out*/size_t* numPhysicalCameras, /*out*/const char*const** physicalCameraIds) {
+    ATRACE_CALL();
+    if (numPhysicalCameras == nullptr || physicalCameraIds == nullptr) {
+        ALOGE("%s: Invalid input: numPhysicalCameras %p, physicalCameraIds %p",
+                 __FUNCTION__, numPhysicalCameras, physicalCameraIds);
+        return false;
+    }
+    if (staticMetadata == nullptr) {
+        ALOGE("%s: Invalid input: staticMetadata is null.", __FUNCTION__);
+        return false;
+    }
+
+    return staticMetadata->isLogicalMultiCamera(numPhysicalCameras, physicalCameraIds);
+}
diff --git a/camera/ndk/NdkCaptureRequest.cpp b/camera/ndk/NdkCaptureRequest.cpp
index ac1856b..87de4a9 100644
--- a/camera/ndk/NdkCaptureRequest.cpp
+++ b/camera/ndk/NdkCaptureRequest.cpp
@@ -27,7 +27,7 @@
 
 EXPORT
 camera_status_t ACameraOutputTarget_create(
-        ANativeWindow* window, ACameraOutputTarget** out) {
+        ACameraWindowType* window, ACameraOutputTarget** out) {
     ATRACE_CALL();
     if (window == nullptr) {
         ALOGE("%s: Error: input window is null", __FUNCTION__);
@@ -98,6 +98,27 @@
 }
 
 EXPORT
+camera_status_t ACaptureRequest_getConstEntry_physicalCamera(
+        const ACaptureRequest* req, const char* physicalId,
+        uint32_t tag, ACameraMetadata_const_entry* entry) {
+    ATRACE_CALL();
+    if (req == nullptr || entry == nullptr || physicalId == nullptr) {
+        ALOGE("%s: invalid argument! req %p, tag 0x%x, entry %p, physicalId %p",
+               __FUNCTION__, req, tag, entry, physicalId);
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+
+    const auto& physicalSettings = req->physicalSettings.find(physicalId);
+    if (physicalSettings == req->physicalSettings.end()) {
+        ALOGE("%s: Failed to find metadata for physical camera id  %s",
+                __FUNCTION__, physicalId);
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+
+    return physicalSettings->second->getConstEntry(tag, entry);
+}
+
+EXPORT
 camera_status_t ACaptureRequest_getAllTags(
         const ACaptureRequest* req, /*out*/int32_t* numTags, /*out*/const uint32_t** tags) {
     ATRACE_CALL();
@@ -131,13 +152,42 @@
 
 #undef SET_ENTRY
 
+#define SET_PHYSICAL_ENTRY(NAME,NDK_TYPE)                                               \
+EXPORT                                                                                  \
+camera_status_t ACaptureRequest_setEntry_physicalCamera_##NAME(                         \
+        ACaptureRequest* req, const char* physicalId, uint32_t tag,                     \
+        uint32_t count, const NDK_TYPE* data) {                                         \
+    ATRACE_CALL();                                                                      \
+    if (req == nullptr || (count > 0 && data == nullptr) || physicalId == nullptr) {    \
+        ALOGE("%s: invalid argument! req %p, tag 0x%x, count %d, data 0x%p, physicalId %p", \
+               __FUNCTION__, req, tag, count, data, physicalId);                        \
+        return ACAMERA_ERROR_INVALID_PARAMETER;                                         \
+    }                                                                                   \
+    if (req->physicalSettings.find(physicalId) == req->physicalSettings.end()) {        \
+        ALOGE("%s: Failed to find metadata for physical camera id %s",                  \
+            __FUNCTION__, physicalId);                                                  \
+      return ACAMERA_ERROR_INVALID_PARAMETER;                                           \
+    }                                                                                   \
+    return req->physicalSettings[physicalId]->update(tag, count, data);                 \
+}
+
+SET_PHYSICAL_ENTRY(u8,uint8_t)
+SET_PHYSICAL_ENTRY(i32,int32_t)
+SET_PHYSICAL_ENTRY(float,float)
+SET_PHYSICAL_ENTRY(double,double)
+SET_PHYSICAL_ENTRY(i64,int64_t)
+SET_PHYSICAL_ENTRY(rational,ACameraMetadata_rational)
+
+#undef SET_PHYSICAL_ENTRY
+
 EXPORT
 void ACaptureRequest_free(ACaptureRequest* request) {
     ATRACE_CALL();
     if (request == nullptr) {
         return;
     }
-    delete request->settings;
+    request->settings.clear();
+    request->physicalSettings.clear();
     delete request->targets;
     delete request;
     return;
@@ -174,6 +224,9 @@
 
     ACaptureRequest* pRequest = new ACaptureRequest();
     pRequest->settings = new ACameraMetadata(*(src->settings));
+    for (const auto& entry : src->physicalSettings) {
+        pRequest->physicalSettings[entry.first] = new ACameraMetadata(*(entry.second));
+    }
     pRequest->targets  = new ACameraOutputTargets();
     *(pRequest->targets)  = *(src->targets);
     pRequest->context = src->context;
diff --git a/camera/ndk/impl/ACameraCaptureSession.cpp b/camera/ndk/impl/ACameraCaptureSession.cpp
index f60e5fd..d6f1412 100644
--- a/camera/ndk/impl/ACameraCaptureSession.cpp
+++ b/camera/ndk/impl/ACameraCaptureSession.cpp
@@ -23,7 +23,7 @@
 
 ACameraCaptureSession::~ACameraCaptureSession() {
     ALOGV("~ACameraCaptureSession: %p notify device end of life", this);
-    sp<CameraDevice> dev = getDeviceSp();
+    sp<acam::CameraDevice> dev = getDeviceSp();
     if (dev != nullptr && !dev->isClosed()) {
         dev->lockDeviceForSessionOps();
         {
@@ -48,7 +48,7 @@
         mClosedByApp = true;
     }
 
-    sp<CameraDevice> dev = getDeviceSp();
+    sp<acam::CameraDevice> dev = getDeviceSp();
     if (dev != nullptr) {
         dev->lockDeviceForSessionOps();
     }
@@ -73,7 +73,7 @@
 
 camera_status_t
 ACameraCaptureSession::stopRepeating() {
-    sp<CameraDevice> dev = getDeviceSp();
+    sp<acam::CameraDevice> dev = getDeviceSp();
     if (dev == nullptr) {
         ALOGE("Error: Device associated with session %p has been closed!", this);
         return ACAMERA_ERROR_SESSION_CLOSED;
@@ -91,7 +91,7 @@
 
 camera_status_t
 ACameraCaptureSession::abortCaptures() {
-    sp<CameraDevice> dev = getDeviceSp();
+    sp<acam::CameraDevice> dev = getDeviceSp();
     if (dev == nullptr) {
         ALOGE("Error: Device associated with session %p has been closed!", this);
         return ACAMERA_ERROR_SESSION_CLOSED;
@@ -107,49 +107,8 @@
     return ret;
 }
 
-camera_status_t
-ACameraCaptureSession::setRepeatingRequest(
-        /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
-        int numRequests, ACaptureRequest** requests,
-        /*optional*/int* captureSequenceId) {
-    sp<CameraDevice> dev = getDeviceSp();
-    if (dev == nullptr) {
-        ALOGE("Error: Device associated with session %p has been closed!", this);
-        return ACAMERA_ERROR_SESSION_CLOSED;
-    }
-
-    camera_status_t ret;
-    dev->lockDeviceForSessionOps();
-    {
-        Mutex::Autolock _l(mSessionLock);
-        ret = dev->setRepeatingRequestsLocked(
-                this, cbs, numRequests, requests, captureSequenceId);
-    }
-    dev->unlockDevice();
-    return ret;
-}
-
-camera_status_t ACameraCaptureSession::capture(
-        /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
-        int numRequests, ACaptureRequest** requests,
-        /*optional*/int* captureSequenceId) {
-    sp<CameraDevice> dev = getDeviceSp();
-    if (dev == nullptr) {
-        ALOGE("Error: Device associated with session %p has been closed!", this);
-        return ACAMERA_ERROR_SESSION_CLOSED;
-    }
-    camera_status_t ret;
-    dev->lockDeviceForSessionOps();
-    {
-        Mutex::Autolock _l(mSessionLock);
-        ret = dev->captureLocked(this, cbs, numRequests, requests, captureSequenceId);
-    }
-    dev->unlockDevice();
-    return ret;
-}
-
 camera_status_t ACameraCaptureSession::updateOutputConfiguration(ACaptureSessionOutput *output) {
-    sp<CameraDevice> dev = getDeviceSp();
+    sp<acam::CameraDevice> dev = getDeviceSp();
     if (dev == nullptr) {
         ALOGE("Error: Device associated with session %p has been closed!", this);
         return ACAMERA_ERROR_SESSION_CLOSED;
@@ -168,7 +127,7 @@
 ACameraDevice*
 ACameraCaptureSession::getDevice() {
     Mutex::Autolock _l(mSessionLock);
-    sp<CameraDevice> dev = getDeviceSp();
+    sp<acam::CameraDevice> dev = getDeviceSp();
     if (dev == nullptr) {
         ALOGE("Error: Device associated with session %p has been closed!", this);
         return nullptr;
@@ -182,9 +141,9 @@
     mIsClosed = true;
 }
 
-sp<CameraDevice>
+sp<acam::CameraDevice>
 ACameraCaptureSession::getDeviceSp() {
-    sp<CameraDevice> device = mDevice.promote();
+    sp<acam::CameraDevice> device = mDevice.promote();
     if (device == nullptr || device->isClosed()) {
         ALOGW("Device is closed but session %d is not notified", mId);
         return nullptr;
diff --git a/camera/ndk/impl/ACameraCaptureSession.h b/camera/ndk/impl/ACameraCaptureSession.h
index a2068e7..08a9226 100644
--- a/camera/ndk/impl/ACameraCaptureSession.h
+++ b/camera/ndk/impl/ACameraCaptureSession.h
@@ -17,15 +17,22 @@
 #define _ACAMERA_CAPTURE_SESSION_H
 
 #include <set>
+#include <string>
 #include <hardware/camera3.h>
 #include <camera/NdkCameraDevice.h>
+
+#ifdef __ANDROID_VNDK__
+#include "ndk_vendor/impl/ACameraDevice.h"
+#include "ndk_vendor/impl/ACameraCaptureSessionVendor.h"
+#else
 #include "ACameraDevice.h"
 
 using namespace android;
 
 struct ACaptureSessionOutput {
-    explicit ACaptureSessionOutput(ANativeWindow* window, bool isShared = false) :
-            mWindow(window), mIsShared(isShared) {};
+    explicit ACaptureSessionOutput(ACameraWindowType* window, bool isShared = false,
+            const char* physicalCameraId = "") :
+            mWindow(window), mIsShared(isShared), mPhysicalCameraId(physicalCameraId) {};
 
     bool operator == (const ACaptureSessionOutput& other) const {
         return mWindow == other.mWindow;
@@ -40,11 +47,13 @@
         return mWindow > other.mWindow;
     }
 
-    ANativeWindow* mWindow;
-    std::set<ANativeWindow *> mSharedWindows;
+    ACameraWindowType* mWindow;
+    std::set<ACameraWindowType *> mSharedWindows;
     bool           mIsShared;
     int            mRotation = CAMERA3_STREAM_ROTATION_0;
+    std::string mPhysicalCameraId;
 };
+#endif
 
 struct ACaptureSessionOutputContainer {
     std::set<ACaptureSessionOutput> mOutputs;
@@ -60,7 +69,7 @@
             int id,
             const ACaptureSessionOutputContainer* outputs,
             const ACameraCaptureSession_stateCallbacks* cb,
-            CameraDevice* device) :
+            android::acam::CameraDevice* device) :
             mId(id), mOutput(*outputs), mUserSessionCallback(*cb),
             mDevice(device) {}
 
@@ -82,13 +91,15 @@
 
     camera_status_t abortCaptures();
 
+    template<class T>
     camera_status_t setRepeatingRequest(
-            /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
+            /*optional*/T* cbs,
             int numRequests, ACaptureRequest** requests,
             /*optional*/int* captureSequenceId);
 
+    template<class T>
     camera_status_t capture(
-            /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
+            /*optional*/T* cbs,
             int numRequests, ACaptureRequest** requests,
             /*optional*/int* captureSequenceId);
 
@@ -97,18 +108,18 @@
     ACameraDevice* getDevice();
 
   private:
-    friend class CameraDevice;
+    friend class android::acam::CameraDevice;
 
     // Close session because app close camera device, camera device got ERROR_DISCONNECTED,
     // or a new session is replacing this session.
     void closeByDevice();
 
-    sp<CameraDevice> getDeviceSp();
+    sp<android::acam::CameraDevice> getDeviceSp();
 
     const int mId;
     const ACaptureSessionOutputContainer mOutput;
     const ACameraCaptureSession_stateCallbacks mUserSessionCallback;
-    const wp<CameraDevice> mDevice;
+    const wp<android::acam::CameraDevice> mDevice;
     bool  mIsClosed = false;
     bool  mClosedByApp = false;
     Mutex mSessionLock;
diff --git a/camera/ndk/impl/ACameraCaptureSession.inc b/camera/ndk/impl/ACameraCaptureSession.inc
new file mode 100644
index 0000000..86bf8a5
--- /dev/null
+++ b/camera/ndk/impl/ACameraCaptureSession.inc
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ACameraCaptureSession.h"
+
+#ifdef __ANDROID_VNDK__
+#include "ndk_vendor/impl/ACameraDeviceVendor.inc"
+#else
+#include "ACameraDevice.inc"
+#endif
+
+using namespace android;
+
+template <class T>
+camera_status_t
+ACameraCaptureSession::setRepeatingRequest(
+        /*optional*/T* cbs,
+        int numRequests, ACaptureRequest** requests,
+        /*optional*/int* captureSequenceId) {
+    sp<acam::CameraDevice> dev = getDeviceSp();
+    if (dev == nullptr) {
+        ALOGE("Error: Device associated with session %p has been closed!", this);
+        return ACAMERA_ERROR_SESSION_CLOSED;
+    }
+
+    camera_status_t ret;
+    dev->lockDeviceForSessionOps();
+    {
+        Mutex::Autolock _l(mSessionLock);
+        ret = dev->setRepeatingRequestsLocked(
+                this, cbs, numRequests, requests, captureSequenceId);
+    }
+    dev->unlockDevice();
+    return ret;
+}
+
+template <class T>
+camera_status_t ACameraCaptureSession::capture(
+        /*optional*/T* cbs,
+        int numRequests, ACaptureRequest** requests,
+        /*optional*/int* captureSequenceId) {
+    sp<acam::CameraDevice> dev = getDeviceSp();
+    if (dev == nullptr) {
+        ALOGE("Error: Device associated with session %p has been closed!", this);
+        return ACAMERA_ERROR_SESSION_CLOSED;
+    }
+    camera_status_t ret;
+    dev->lockDeviceForSessionOps();
+    {
+        Mutex::Autolock _l(mSessionLock);
+        ret = dev->captureLocked(this, cbs, numRequests, requests, captureSequenceId);
+    }
+    dev->unlockDevice();
+    return ret;
+}
diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp
index 907debc..d24cb81 100644
--- a/camera/ndk/impl/ACameraDevice.cpp
+++ b/camera/ndk/impl/ACameraDevice.cpp
@@ -20,16 +20,21 @@
 #include <vector>
 #include <inttypes.h>
 #include <android/hardware/ICameraService.h>
-#include <camera2/SubmitInfo.h>
 #include <gui/Surface.h>
 #include "ACameraDevice.h"
 #include "ACameraMetadata.h"
 #include "ACaptureRequest.h"
 #include "ACameraCaptureSession.h"
 
-using namespace android;
+#include "ACameraCaptureSession.inc"
+
+ACameraDevice::~ACameraDevice() {
+    mDevice->stopLooper();
+}
 
 namespace android {
+namespace acam {
+
 // Static member definitions
 const char* CameraDevice::kContextKey        = "Context";
 const char* CameraDevice::kDeviceKey         = "Device";
@@ -39,10 +44,12 @@
 const char* CameraDevice::kCaptureRequestKey = "CaptureRequest";
 const char* CameraDevice::kTimeStampKey      = "TimeStamp";
 const char* CameraDevice::kCaptureResultKey  = "CaptureResult";
+const char* CameraDevice::kPhysicalCaptureResultKey = "PhysicalCaptureResult";
 const char* CameraDevice::kCaptureFailureKey = "CaptureFailure";
 const char* CameraDevice::kSequenceIdKey     = "SequenceId";
 const char* CameraDevice::kFrameNumberKey    = "FrameNumber";
 const char* CameraDevice::kAnwKey            = "Anw";
+const char* CameraDevice::kFailingPhysicalCameraId= "FailingPhysicalCameraId";
 
 /**
  * CameraDevice Implementation
@@ -50,11 +57,11 @@
 CameraDevice::CameraDevice(
         const char* id,
         ACameraDevice_StateCallbacks* cb,
-        std::unique_ptr<ACameraMetadata> chars,
+        sp<ACameraMetadata> chars,
         ACameraDevice* wrapper) :
         mCameraId(id),
         mAppCallbacks(*cb),
-        mChars(std::move(chars)),
+        mChars(chars),
         mServiceCallback(new ServiceCallback(this)),
         mWrapper(wrapper),
         mInError(false),
@@ -74,7 +81,7 @@
                 __FUNCTION__, strerror(-err), err);
         setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
     }
-    mHandler = new CallbackHandler();
+    mHandler = new CallbackHandler(id);
     mCbLooper->registerHandler(mHandler);
 
     const CameraMetadata& metadata = mChars->getInternalData();
@@ -95,6 +102,14 @@
         mShadingMapSize[0] = entry.data.i32[0];
         mShadingMapSize[1] = entry.data.i32[1];
     }
+
+    size_t physicalIdCnt = 0;
+    const char*const* physicalCameraIds;
+    if (mChars->isLogicalMultiCamera(&physicalIdCnt, &physicalCameraIds)) {
+        for (size_t i = 0; i < physicalIdCnt; i++) {
+            mPhysicalIds.push_back(physicalCameraIds[i]);
+        }
+    }
 }
 
 // Device close implementaiton
@@ -105,14 +120,10 @@
         if (!isClosed()) {
             disconnectLocked(session);
         }
+        LOG_ALWAYS_FATAL_IF(mCbLooper != nullptr,
+                "CameraDevice looper should've been stopped before ~CameraDevice");
         mCurrentSession = nullptr;
-        if (mCbLooper != nullptr) {
-            mCbLooper->unregisterHandler(mHandler->id());
-            mCbLooper->stop();
-        }
     }
-    mCbLooper.clear();
-    mHandler.clear();
 }
 
 void
@@ -127,8 +138,29 @@
 camera_status_t
 CameraDevice::createCaptureRequest(
         ACameraDevice_request_template templateId,
+        const ACameraIdList* physicalIdList,
         ACaptureRequest** request) const {
     Mutex::Autolock _l(mDeviceLock);
+
+    if (physicalIdList != nullptr) {
+        if (physicalIdList->numCameras > static_cast<int>(mPhysicalIds.size())) {
+            ALOGE("%s: physicalIdList size %d exceeds number of available physical cameras %zu",
+                    __FUNCTION__, physicalIdList->numCameras, mPhysicalIds.size());
+            return ACAMERA_ERROR_INVALID_PARAMETER;
+        }
+        for (auto i = 0; i < physicalIdList->numCameras; i++) {
+            if (physicalIdList->cameraIds[i] == nullptr) {
+                ALOGE("%s: physicalId is null!", __FUNCTION__);
+                return ACAMERA_ERROR_INVALID_PARAMETER;
+            }
+            if (mPhysicalIds.end() == std::find(
+                    mPhysicalIds.begin(), mPhysicalIds.end(), physicalIdList->cameraIds[i])) {
+                ALOGE("%s: Invalid physicalId %s!", __FUNCTION__, physicalIdList->cameraIds[i]);
+                return ACAMERA_ERROR_INVALID_PARAMETER;
+            }
+        }
+    }
+
     camera_status_t ret = checkCameraClosedOrErrorLocked();
     if (ret != ACAMERA_OK) {
         return ret;
@@ -149,6 +181,12 @@
     }
     ACaptureRequest* outReq = new ACaptureRequest();
     outReq->settings = new ACameraMetadata(rawRequest.release(), ACameraMetadata::ACM_REQUEST);
+    if (physicalIdList != nullptr) {
+        for (auto i = 0; i < physicalIdList->numCameras; i++) {
+            outReq->physicalSettings.emplace(physicalIdList->cameraIds[i],
+                    new ACameraMetadata(*(outReq->settings)));
+        }
+    }
     outReq->targets  = new ACameraOutputTargets();
     *request = outReq;
     return ACAMERA_OK;
@@ -190,104 +228,53 @@
     return ACAMERA_OK;
 }
 
-camera_status_t
-CameraDevice::captureLocked(
-        sp<ACameraCaptureSession> session,
-        /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
-        int numRequests, ACaptureRequest** requests,
-        /*optional*/int* captureSequenceId) {
-    return submitRequestsLocked(
-            session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/false);
-}
-
-camera_status_t
-CameraDevice::setRepeatingRequestsLocked(
-        sp<ACameraCaptureSession> session,
-        /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
-        int numRequests, ACaptureRequest** requests,
-        /*optional*/int* captureSequenceId) {
-    return submitRequestsLocked(
-            session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/true);
-}
-
-camera_status_t
-CameraDevice::submitRequestsLocked(
-        sp<ACameraCaptureSession> session,
-        /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
-        int numRequests, ACaptureRequest** requests,
-        /*optional*/int* captureSequenceId,
-        bool isRepeating) {
+camera_status_t CameraDevice::isSessionConfigurationSupported(
+        const ACaptureSessionOutputContainer* sessionOutputContainer) const {
+    Mutex::Autolock _l(mDeviceLock);
     camera_status_t ret = checkCameraClosedOrErrorLocked();
     if (ret != ACAMERA_OK) {
-        ALOGE("Camera %s submit capture request failed! ret %d", getId(), ret);
         return ret;
     }
 
-    // Form two vectors of capture request, one for internal tracking
-    std::vector<hardware::camera2::CaptureRequest> requestList;
-    Vector<sp<CaptureRequest> > requestsV;
-    requestsV.setCapacity(numRequests);
-    for (int i = 0; i < numRequests; i++) {
-        sp<CaptureRequest> req;
-        ret = allocateCaptureRequest(requests[i], req);
+    SessionConfiguration sessionConfiguration(0 /*inputWidth*/, 0 /*inputHeight*/,
+            -1 /*inputFormat*/, CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE);
+    for (const auto& output : sessionOutputContainer->mOutputs) {
+        sp<IGraphicBufferProducer> iGBP(nullptr);
+        ret = getIGBPfromAnw(output.mWindow, iGBP);
         if (ret != ACAMERA_OK) {
-            ALOGE("Convert capture request to internal format failure! ret %d", ret);
+            ALOGE("Camera device %s failed to extract graphic producer from native window",
+                    getId());
             return ret;
         }
-        if (req->mSurfaceList.empty()) {
-            ALOGE("Capture request without output target cannot be submitted!");
-            return ACAMERA_ERROR_INVALID_PARAMETER;
+
+        String16 physicalId16(output.mPhysicalCameraId.c_str());
+        OutputConfiguration outConfig(iGBP, output.mRotation, physicalId16,
+                OutputConfiguration::INVALID_SET_ID, true);
+
+        for (auto& anw : output.mSharedWindows) {
+            ret = getIGBPfromAnw(anw, iGBP);
+            if (ret != ACAMERA_OK) {
+                ALOGE("Camera device %s failed to extract graphic producer from native window",
+                        getId());
+                return ret;
+            }
+            outConfig.addGraphicProducer(iGBP);
         }
-        requestList.push_back(*(req.get()));
-        requestsV.push_back(req);
+
+        sessionConfiguration.addOutputConfiguration(outConfig);
     }
 
-    if (isRepeating) {
-        ret = stopRepeatingLocked();
-        if (ret != ACAMERA_OK) {
-            ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
-            return ret;
-        }
-    }
-
-    binder::Status remoteRet;
-    hardware::camera2::utils::SubmitInfo info;
-    remoteRet = mRemote->submitRequestList(requestList, isRepeating, &info);
-    int sequenceId = info.mRequestId;
-    int64_t lastFrameNumber = info.mLastFrameNumber;
-    if (sequenceId < 0) {
-        ALOGE("Camera %s submit request remote failure: ret %d", getId(), sequenceId);
+    bool supported = false;
+    binder::Status remoteRet = mRemote->isSessionConfigurationSupported(
+            sessionConfiguration, &supported);
+    if (remoteRet.serviceSpecificErrorCode() ==
+            hardware::ICameraService::ERROR_INVALID_OPERATION) {
+        return ACAMERA_ERROR_UNSUPPORTED_OPERATION;
+    } else if (!remoteRet.isOk()) {
         return ACAMERA_ERROR_UNKNOWN;
-    }
-
-    CallbackHolder cbHolder(session, requestsV, isRepeating, cbs);
-    mSequenceCallbackMap.insert(std::make_pair(sequenceId, cbHolder));
-
-    if (isRepeating) {
-        // stopRepeating above should have cleanup repeating sequence id
-        if (mRepeatingSequenceId != REQUEST_ID_NONE) {
-            setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
-            return ACAMERA_ERROR_CAMERA_DEVICE;
-        }
-        mRepeatingSequenceId = sequenceId;
     } else {
-        mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
+        return supported ? ACAMERA_OK : ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
     }
-
-    if (mIdle) {
-        sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
-        msg->setPointer(kContextKey, session->mUserSessionCallback.context);
-        msg->setObject(kSessionSpKey, session);
-        msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
-        postSessionMsgAndCleanup(msg);
-    }
-    mIdle = false;
-    mBusySession = session;
-
-    if (captureSequenceId) {
-        *captureSequenceId = sequenceId;
-    }
-    return ACAMERA_OK;
 }
 
 camera_status_t CameraDevice::updateOutputConfigurationLocked(ACaptureSessionOutput *output) {
@@ -325,8 +312,9 @@
         return ret;
     }
 
-    OutputConfiguration outConfig(iGBP, output->mRotation, OutputConfiguration::INVALID_SET_ID,
-            true);
+    String16 physicalId16(output->mPhysicalCameraId.c_str());
+    OutputConfiguration outConfig(iGBP, output->mRotation, physicalId16,
+            OutputConfiguration::INVALID_SET_ID, true);
 
     for (auto& anw : output->mSharedWindows) {
         ret = getIGBPfromAnw(anw, iGBP);
@@ -372,8 +360,12 @@
         const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
     camera_status_t ret;
     sp<CaptureRequest> req(new CaptureRequest());
-    req->mPhysicalCameraSettings.push_back({std::string(mCameraId.string()),
+    req->mPhysicalCameraSettings.push_back({getId(),
             request->settings->getInternalData()});
+    for (auto& entry : request->physicalSettings) {
+        req->mPhysicalCameraSettings.push_back({entry.first,
+                entry.second->getInternalData()});
+    }
     req->mIsReprocess = false; // NDK does not support reprocessing yet
     req->mContext = request->context;
     req->mSurfaceConverted = true; // set to true, and fill in stream/surface idx to speed up IPC
@@ -417,10 +409,17 @@
 }
 
 ACaptureRequest*
-CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req) {
+CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req, const std::string& deviceId) {
     ACaptureRequest* pRequest = new ACaptureRequest();
-    CameraMetadata clone = req->mPhysicalCameraSettings.begin()->settings;
-    pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
+    for (auto& entry : req->mPhysicalCameraSettings) {
+        CameraMetadata clone = entry.settings;
+        if (entry.id == deviceId) {
+            pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
+        } else {
+            pRequest->physicalSettings.emplace(entry.id,
+                    new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST));
+        }
+    }
     pRequest->targets  = new ACameraOutputTargets();
     for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
         ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
@@ -436,7 +435,8 @@
     if (req == nullptr) {
         return;
     }
-    delete req->settings;
+    req->settings.clear();
+    req->physicalSettings.clear();
     delete req->targets;
     delete req;
 }
@@ -633,15 +633,16 @@
     }
 
     std::set<std::pair<ANativeWindow*, OutputConfiguration>> outputSet;
-    for (auto outConfig : outputs->mOutputs) {
+    for (const auto& outConfig : outputs->mOutputs) {
         ANativeWindow* anw = outConfig.mWindow;
         sp<IGraphicBufferProducer> iGBP(nullptr);
         ret = getIGBPfromAnw(anw, iGBP);
         if (ret != ACAMERA_OK) {
             return ret;
         }
+        String16 physicalId16(outConfig.mPhysicalCameraId.c_str());
         outputSet.insert(std::make_pair(
-                anw, OutputConfiguration(iGBP, outConfig.mRotation,
+                anw, OutputConfiguration(iGBP, outConfig.mRotation, physicalId16,
                         OutputConfiguration::INVALID_SET_ID, outConfig.mIsShared)));
     }
     auto addSet = outputSet;
@@ -706,7 +707,7 @@
     }
 
     // add new streams
-    for (auto outputPair : addSet) {
+    for (const auto& outputPair : addSet) {
         int streamId;
         remoteRet = mRemote->createStream(outputPair.second, &streamId);
         if (!remoteRet.isOk()) {
@@ -829,7 +830,7 @@
     if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
         int32_t streamId = resultExtras.errorStreamId;
         ACameraCaptureSession_captureCallback_bufferLost onBufferLost =
-                cbh.mCallbacks.onCaptureBufferLost;
+                cbh.mOnCaptureBufferLost;
         auto outputPairIt = mConfiguredOutputs.find(streamId);
         if (outputPairIt == mConfiguredOutputs.end()) {
             ALOGE("%s: Error: stream id %d does not exist", __FUNCTION__, streamId);
@@ -839,14 +840,14 @@
 
         const auto& gbps = outputPairIt->second.second.getGraphicBufferProducers();
         for (const auto& outGbp : gbps) {
-            for (auto surface : request->mSurfaceList) {
+            for (const auto& surface : request->mSurfaceList) {
                 if (surface->getIGraphicBufferProducer() == outGbp) {
                     ANativeWindow* anw = static_cast<ANativeWindow*>(surface.get());
                     ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
                             getId(), anw, frameNumber);
 
                     sp<AMessage> msg = new AMessage(kWhatCaptureBufferLost, mHandler);
-                    msg->setPointer(kContextKey, cbh.mCallbacks.context);
+                    msg->setPointer(kContextKey, cbh.mContext);
                     msg->setObject(kSessionSpKey, session);
                     msg->setPointer(kCallbackFpKey, (void*) onBufferLost);
                     msg->setObject(kCaptureRequestKey, request);
@@ -858,7 +859,7 @@
         }
     } else { // Handle other capture failures
         // Fire capture failure callback if there is one registered
-        ACameraCaptureSession_captureCallback_failed onError = cbh.mCallbacks.onCaptureFailed;
+        ACameraCaptureSession_captureCallback_failed onError = cbh.mOnCaptureFailed;
         sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
         failure->frameNumber = frameNumber;
         // TODO: refine this when implementing flush
@@ -867,10 +868,19 @@
         failure->wasImageCaptured = (errorCode ==
                 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
 
-        sp<AMessage> msg = new AMessage(kWhatCaptureFail, mHandler);
-        msg->setPointer(kContextKey, cbh.mCallbacks.context);
+        sp<AMessage> msg = new AMessage(cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureFail :
+                kWhatCaptureFail, mHandler);
+        msg->setPointer(kContextKey, cbh.mContext);
         msg->setObject(kSessionSpKey, session);
-        msg->setPointer(kCallbackFpKey, (void*) onError);
+        if (cbh.mIsLogicalCameraCallback) {
+            if (resultExtras.errorPhysicalCameraId.size() > 0) {
+                String8 cameraId(resultExtras.errorPhysicalCameraId);
+                msg->setString(kFailingPhysicalCameraId, cameraId.string(), cameraId.size());
+            }
+            msg->setPointer(kCallbackFpKey, (void*) cbh.mOnLogicalCameraCaptureFailed);
+        } else {
+            msg->setPointer(kCallbackFpKey, (void*) onError);
+        }
         msg->setObject(kCaptureRequestKey, request);
         msg->setObject(kCaptureFailureKey, failure);
         postSessionMsgAndCleanup(msg);
@@ -882,6 +892,19 @@
     return;
 }
 
+void CameraDevice::stopLooper() {
+    Mutex::Autolock _l(mDeviceLock);
+    if (mCbLooper != nullptr) {
+      mCbLooper->unregisterHandler(mHandler->id());
+      mCbLooper->stop();
+    }
+    mCbLooper.clear();
+    mHandler.clear();
+}
+
+CameraDevice::CallbackHandler::CallbackHandler(const char* id) : mId(id) {
+}
+
 void CameraDevice::CallbackHandler::onMessageReceived(
         const sp<AMessage> &msg) {
     switch (msg->what()) {
@@ -890,7 +913,9 @@
         case kWhatSessionStateCb:
         case kWhatCaptureStart:
         case kWhatCaptureResult:
+        case kWhatLogicalCaptureResult:
         case kWhatCaptureFail:
+        case kWhatLogicalCaptureFail:
         case kWhatCaptureSeqEnd:
         case kWhatCaptureSeqAbort:
         case kWhatCaptureBufferLost:
@@ -960,7 +985,9 @@
         case kWhatSessionStateCb:
         case kWhatCaptureStart:
         case kWhatCaptureResult:
+        case kWhatLogicalCaptureResult:
         case kWhatCaptureFail:
+        case kWhatLogicalCaptureFail:
         case kWhatCaptureSeqEnd:
         case kWhatCaptureSeqAbort:
         case kWhatCaptureBufferLost:
@@ -977,7 +1004,9 @@
             switch (msg->what()) {
                 case kWhatCaptureStart:
                 case kWhatCaptureResult:
+                case kWhatLogicalCaptureResult:
                 case kWhatCaptureFail:
+                case kWhatLogicalCaptureFail:
                 case kWhatCaptureBufferLost:
                     found = msg->findObject(kCaptureRequestKey, &obj);
                     if (!found) {
@@ -1020,7 +1049,7 @@
                         ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
                         return;
                     }
-                    ACaptureRequest* request = allocateACaptureRequest(requestSp);
+                    ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
                     (*onStart)(context, session.get(), request, timestamp);
                     freeACaptureRequest(request);
                     break;
@@ -1043,11 +1072,69 @@
                         return;
                     }
                     sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
-                    ACaptureRequest* request = allocateACaptureRequest(requestSp);
+                    ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
                     (*onResult)(context, session.get(), request, result.get());
                     freeACaptureRequest(request);
                     break;
                 }
+                case kWhatLogicalCaptureResult:
+                {
+                    ACameraCaptureSession_logicalCamera_captureCallback_result onResult;
+                    found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
+                    if (!found) {
+                        ALOGE("%s: Cannot find logicalCamera capture result callback!",
+                                __FUNCTION__);
+                        return;
+                    }
+                    if (onResult == nullptr) {
+                        return;
+                    }
+
+                    found = msg->findObject(kCaptureResultKey, &obj);
+                    if (!found) {
+                        ALOGE("%s: Cannot find capture result!", __FUNCTION__);
+                        return;
+                    }
+                    sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
+
+                    found = msg->findObject(kPhysicalCaptureResultKey, &obj);
+                    if (!found) {
+                        ALOGE("%s: Cannot find physical capture result!", __FUNCTION__);
+                        return;
+                    }
+                    sp<ACameraPhysicalCaptureResultInfo> physicalResult(
+                            static_cast<ACameraPhysicalCaptureResultInfo*>(obj.get()));
+                    std::vector<PhysicalCaptureResultInfo>& physicalResultInfo =
+                            physicalResult->mPhysicalResultInfo;
+
+                    std::vector<std::string> physicalCameraIds;
+                    std::vector<sp<ACameraMetadata>> physicalMetadataCopy;
+                    for (size_t i = 0; i < physicalResultInfo.size(); i++) {
+                        String8 physicalId8(physicalResultInfo[i].mPhysicalCameraId);
+                        physicalCameraIds.push_back(physicalId8.c_str());
+
+                        CameraMetadata clone = physicalResultInfo[i].mPhysicalCameraMetadata;
+                        clone.update(ANDROID_SYNC_FRAME_NUMBER,
+                                &physicalResult->mFrameNumber, /*data_count*/1);
+                        sp<ACameraMetadata> metadata =
+                                new ACameraMetadata(clone.release(), ACameraMetadata::ACM_RESULT);
+                        physicalMetadataCopy.push_back(metadata);
+                    }
+
+                    std::vector<const char*> physicalCameraIdPtrs;
+                    std::vector<const ACameraMetadata*> physicalMetadataCopyPtrs;
+                    for (size_t i = 0; i < physicalResultInfo.size(); i++) {
+                        physicalCameraIdPtrs.push_back(physicalCameraIds[i].c_str());
+                        physicalMetadataCopyPtrs.push_back(physicalMetadataCopy[i].get());
+                    }
+
+                    ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
+                    (*onResult)(context, session.get(), request, result.get(),
+                            physicalResultInfo.size(), physicalCameraIdPtrs.data(),
+                            physicalMetadataCopyPtrs.data());
+                    freeACaptureRequest(request);
+                    break;
+                }
                 case kWhatCaptureFail:
                 {
                     ACameraCaptureSession_captureCallback_failed onFail;
@@ -1069,11 +1156,44 @@
                             static_cast<CameraCaptureFailure*>(obj.get()));
                     ACameraCaptureFailure* failure =
                             static_cast<ACameraCaptureFailure*>(failureSp.get());
-                    ACaptureRequest* request = allocateACaptureRequest(requestSp);
+                    ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
                     (*onFail)(context, session.get(), request, failure);
                     freeACaptureRequest(request);
                     break;
                 }
+                case kWhatLogicalCaptureFail:
+                {
+                    ACameraCaptureSession_logicalCamera_captureCallback_failed onFail;
+                    found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
+                    if (!found) {
+                        ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
+                        return;
+                    }
+                    if (onFail == nullptr) {
+                        return;
+                    }
+
+                    found = msg->findObject(kCaptureFailureKey, &obj);
+                    if (!found) {
+                        ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
+                        return;
+                    }
+                    sp<CameraCaptureFailure> failureSp(
+                            static_cast<CameraCaptureFailure*>(obj.get()));
+                    ALogicalCameraCaptureFailure failure;
+                    AString physicalCameraId;
+                    found = msg->findString(kFailingPhysicalCameraId, &physicalCameraId);
+                    if (found && !physicalCameraId.empty()) {
+                        failure.physicalCameraId = physicalCameraId.c_str();
+                    } else {
+                        failure.physicalCameraId = nullptr;
+                    }
+                    failure.captureFailure = *failureSp;
+                    ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
+                    (*onFail)(context, session.get(), request, &failure);
+                    freeACaptureRequest(request);
+                    break;
+                }
                 case kWhatCaptureSeqEnd:
                 {
                     ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
@@ -1146,7 +1266,7 @@
                         return;
                     }
 
-                    ACaptureRequest* request = allocateACaptureRequest(requestSp);
+                    ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
                     (*onBufferLost)(context, session.get(), request, anw, frameNumber);
                     freeACaptureRequest(request);
                     break;
@@ -1158,12 +1278,36 @@
 }
 
 CameraDevice::CallbackHolder::CallbackHolder(
-    sp<ACameraCaptureSession>          session,
-    const Vector<sp<CaptureRequest> >& requests,
-    bool                               isRepeating,
-    ACameraCaptureSession_captureCallbacks* cbs) :
-    mSession(session), mRequests(requests),
-    mIsRepeating(isRepeating), mCallbacks(fillCb(cbs)) {}
+        sp<ACameraCaptureSession>          session,
+        const Vector<sp<CaptureRequest> >& requests,
+        bool                               isRepeating,
+        ACameraCaptureSession_captureCallbacks* cbs) :
+        mSession(session), mRequests(requests),
+        mIsRepeating(isRepeating),
+        mIsLogicalCameraCallback(false) {
+    initCaptureCallbacks(cbs);
+
+    if (cbs != nullptr) {
+        mOnCaptureCompleted = cbs->onCaptureCompleted;
+        mOnCaptureFailed = cbs->onCaptureFailed;
+    }
+}
+
+CameraDevice::CallbackHolder::CallbackHolder(
+        sp<ACameraCaptureSession>          session,
+        const Vector<sp<CaptureRequest> >& requests,
+        bool                               isRepeating,
+        ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs) :
+        mSession(session), mRequests(requests),
+        mIsRepeating(isRepeating),
+        mIsLogicalCameraCallback(true) {
+    initCaptureCallbacks(lcbs);
+
+    if (lcbs != nullptr) {
+        mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
+        mOnLogicalCameraCaptureFailed = lcbs->onLogicalCameraCaptureFailed;
+    }
+}
 
 void
 CameraDevice::checkRepeatingSequenceCompleteLocked(
@@ -1180,9 +1324,9 @@
         mSequenceCallbackMap.erase(cbIt);
         // send seq aborted callback
         sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
-        msg->setPointer(kContextKey, cbh.mCallbacks.context);
+        msg->setPointer(kContextKey, cbh.mContext);
         msg->setObject(kSessionSpKey, cbh.mSession);
-        msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceAborted);
+        msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceAborted);
         msg->setInt32(kSequenceIdKey, sequenceId);
         postSessionMsgAndCleanup(msg);
     } else {
@@ -1230,9 +1374,9 @@
             mSequenceCallbackMap.erase(cbIt);
             // send seq complete callback
             sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
-            msg->setPointer(kContextKey, cbh.mCallbacks.context);
+            msg->setPointer(kContextKey, cbh.mContext);
             msg->setObject(kSessionSpKey, cbh.mSession);
-            msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceCompleted);
+            msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
             msg->setInt32(kSequenceIdKey, sequenceId);
             msg->setInt64(kFrameNumberKey, lastFrameNumber);
 
@@ -1290,16 +1434,21 @@
         }
         default:
             ALOGE("Unknown error from camera device: %d", errorCode);
-            // no break
+            [[fallthrough]];
         case ERROR_CAMERA_DEVICE:
         case ERROR_CAMERA_SERVICE:
         {
+            int32_t errorVal = ::ERROR_CAMERA_DEVICE;
+            // We keep this switch since this block might be encountered with
+            // more than just 2 states. The default fallthrough could have us
+            // handling more unmatched error cases.
             switch (errorCode) {
                 case ERROR_CAMERA_DEVICE:
                     dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
                     break;
                 case ERROR_CAMERA_SERVICE:
                     dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
+                    errorVal = ::ERROR_CAMERA_SERVICE;
                     break;
                 default:
                     dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
@@ -1309,7 +1458,7 @@
             msg->setPointer(kContextKey, dev->mAppCallbacks.context);
             msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
             msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
-            msg->setInt32(kErrorCodeKey, errorCode);
+            msg->setInt32(kErrorCodeKey, errorVal);
             msg->post();
             break;
         }
@@ -1384,7 +1533,7 @@
     auto it = dev->mSequenceCallbackMap.find(sequenceId);
     if (it != dev->mSequenceCallbackMap.end()) {
         CallbackHolder cbh = (*it).second;
-        ACameraCaptureSession_captureCallback_start onStart = cbh.mCallbacks.onCaptureStarted;
+        ACameraCaptureSession_captureCallback_start onStart = cbh.mOnCaptureStarted;
         sp<ACameraCaptureSession> session = cbh.mSession;
         if ((size_t) burstId >= cbh.mRequests.size()) {
             ALOGE("%s: Error: request index %d out of bound (size %zu)",
@@ -1393,7 +1542,7 @@
         }
         sp<CaptureRequest> request = cbh.mRequests[burstId];
         sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
-        msg->setPointer(kContextKey, cbh.mCallbacks.context);
+        msg->setPointer(kContextKey, cbh.mContext);
         msg->setObject(kSessionSpKey, session);
         msg->setPointer(kCallbackFpKey, (void*) onStart);
         msg->setObject(kCaptureRequestKey, request);
@@ -1408,7 +1557,6 @@
         const CameraMetadata& metadata,
         const CaptureResultExtras& resultExtras,
         const std::vector<PhysicalCaptureResultInfo>& physicalResultInfos) {
-    (void) physicalResultInfos;
     binder::Status ret = binder::Status::ok();
 
     sp<CameraDevice> dev = mDevice.promote();
@@ -1444,9 +1592,6 @@
     auto it = dev->mSequenceCallbackMap.find(sequenceId);
     if (it != dev->mSequenceCallbackMap.end()) {
         CallbackHolder cbh = (*it).second;
-        ACameraCaptureSession_captureCallback_result onResult = isPartialResult ?
-                cbh.mCallbacks.onCaptureProgressed :
-                cbh.mCallbacks.onCaptureCompleted;
         sp<ACameraCaptureSession> session = cbh.mSession;
         if ((size_t) burstId >= cbh.mRequests.size()) {
             ALOGE("%s: Error: request index %d out of bound (size %zu)",
@@ -1456,13 +1601,27 @@
         sp<CaptureRequest> request = cbh.mRequests[burstId];
         sp<ACameraMetadata> result(new ACameraMetadata(
                 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
+        sp<ACameraPhysicalCaptureResultInfo> physicalResult(
+                new ACameraPhysicalCaptureResultInfo(physicalResultInfos, frameNumber));
 
-        sp<AMessage> msg = new AMessage(kWhatCaptureResult, dev->mHandler);
-        msg->setPointer(kContextKey, cbh.mCallbacks.context);
+        sp<AMessage> msg = new AMessage(
+                cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureResult : kWhatCaptureResult,
+                dev->mHandler);
+        msg->setPointer(kContextKey, cbh.mContext);
         msg->setObject(kSessionSpKey, session);
-        msg->setPointer(kCallbackFpKey, (void*) onResult);
         msg->setObject(kCaptureRequestKey, request);
         msg->setObject(kCaptureResultKey, result);
+        if (isPartialResult) {
+            msg->setPointer(kCallbackFpKey,
+                    (void *)cbh.mOnCaptureProgressed);
+        } else if (cbh.mIsLogicalCameraCallback) {
+            msg->setPointer(kCallbackFpKey,
+                    (void *)cbh.mOnLogicalCameraCaptureCompleted);
+            msg->setObject(kPhysicalCaptureResultKey, physicalResult);
+        } else {
+            msg->setPointer(kCallbackFpKey,
+                    (void *)cbh.mOnCaptureCompleted);
+        }
         dev->postSessionMsgAndCleanup(msg);
     }
 
@@ -1508,5 +1667,5 @@
     return ret;
 }
 
-
+} // namespace acam
 } // namespace android
diff --git a/camera/ndk/impl/ACameraDevice.h b/camera/ndk/impl/ACameraDevice.h
index 1369148..7a35bf0 100644
--- a/camera/ndk/impl/ACameraDevice.h
+++ b/camera/ndk/impl/ACameraDevice.h
@@ -21,6 +21,7 @@
 #include <set>
 #include <atomic>
 #include <utility>
+#include <vector>
 #include <utils/StrongPointer.h>
 #include <utils/Mutex.h>
 #include <utils/String8.h>
@@ -34,6 +35,7 @@
 #include <media/stagefright/foundation/AMessage.h>
 #include <camera/CaptureResult.h>
 #include <camera/camera2/OutputConfiguration.h>
+#include <camera/camera2/SessionConfiguration.h>
 #include <camera/camera2/CaptureRequest.h>
 
 #include <camera/NdkCameraManager.h>
@@ -41,14 +43,25 @@
 #include "ACameraMetadata.h"
 
 namespace android {
+namespace acam {
 
 // Wrap ACameraCaptureFailure so it can be ref-counted
 struct CameraCaptureFailure : public RefBase, public ACameraCaptureFailure {};
 
+// Wrap PhysicalCaptureResultInfo so that it can be ref-counted
+struct ACameraPhysicalCaptureResultInfo: public RefBase {
+    ACameraPhysicalCaptureResultInfo(const std::vector<PhysicalCaptureResultInfo>& info,
+            int64_t frameNumber) :
+        mPhysicalResultInfo(info), mFrameNumber(frameNumber) {}
+
+    std::vector<PhysicalCaptureResultInfo> mPhysicalResultInfo;
+    int64_t mFrameNumber;
+};
+
 class CameraDevice final : public RefBase {
   public:
     CameraDevice(const char* id, ACameraDevice_StateCallbacks* cb,
-                  std::unique_ptr<ACameraMetadata> chars,
+                  sp<ACameraMetadata> chars,
                   ACameraDevice* wrapper);
     ~CameraDevice();
 
@@ -56,6 +69,7 @@
 
     camera_status_t createCaptureRequest(
             ACameraDevice_request_template templateId,
+            const ACameraIdList* physicalIdList,
             ACaptureRequest** request) const;
 
     camera_status_t createCaptureSession(
@@ -64,6 +78,9 @@
             const ACameraCaptureSession_stateCallbacks* callbacks,
             /*out*/ACameraCaptureSession** session);
 
+    camera_status_t isSessionConfigurationSupported(
+            const ACaptureSessionOutputContainer* sessionOutputContainer) const;
+
     // Callbacks from camera service
     class ServiceCallback : public hardware::camera2::BnCameraDeviceCallbacks {
       public:
@@ -92,6 +109,9 @@
 
     inline ACameraDevice* getWrapper() const { return mWrapper; };
 
+    // Stop the looper thread and unregister the handler
+    void stopLooper();
+
   private:
     friend ACameraCaptureSession;
     camera_status_t checkCameraClosedOrErrorLocked() const;
@@ -108,19 +128,22 @@
     camera_status_t waitUntilIdleLocked();
 
 
+    template<class T>
     camera_status_t captureLocked(sp<ACameraCaptureSession> session,
-            /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
+            /*optional*/T* cbs,
             int numRequests, ACaptureRequest** requests,
             /*optional*/int* captureSequenceId);
 
+    template<class T>
     camera_status_t setRepeatingRequestsLocked(sp<ACameraCaptureSession> session,
-            /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
+            /*optional*/T* cbs,
             int numRequests, ACaptureRequest** requests,
             /*optional*/int* captureSequenceId);
 
+    template<class T>
     camera_status_t submitRequestsLocked(
             sp<ACameraCaptureSession> session,
-            /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
+            /*optional*/T* cbs,
             int numRequests, ACaptureRequest** requests,
             /*out*/int* captureSequenceId,
             bool isRepeating);
@@ -130,7 +153,8 @@
     camera_status_t allocateCaptureRequest(
             const ACaptureRequest* request, sp<CaptureRequest>& outReq);
 
-    static ACaptureRequest* allocateACaptureRequest(sp<CaptureRequest>& req);
+    static ACaptureRequest* allocateACaptureRequest(sp<CaptureRequest>& req,
+            const std::string& deviceId);
     static void freeACaptureRequest(ACaptureRequest*);
 
     // only For session to hold device lock
@@ -156,7 +180,7 @@
     mutable Mutex mDeviceLock;
     const String8 mCameraId;                          // Camera ID
     const ACameraDevice_StateCallbacks mAppCallbacks; // Callback to app
-    const std::unique_ptr<ACameraMetadata> mChars;    // Camera characteristics
+    const sp<ACameraMetadata> mChars;                 // Camera characteristics
     const sp<ServiceCallback> mServiceCallback;
     ACameraDevice* mWrapper;
 
@@ -191,7 +215,9 @@
         // Capture callbacks
         kWhatCaptureStart,     // onCaptureStarted
         kWhatCaptureResult,    // onCaptureProgressed, onCaptureCompleted
+        kWhatLogicalCaptureResult, // onLogicalCameraCaptureCompleted
         kWhatCaptureFail,      // onCaptureFailed
+        kWhatLogicalCaptureFail, // onLogicalCameraCaptureFailed
         kWhatCaptureSeqEnd,    // onCaptureSequenceCompleted
         kWhatCaptureSeqAbort,  // onCaptureSequenceAborted
         kWhatCaptureBufferLost,// onCaptureBufferLost
@@ -206,16 +232,20 @@
     static const char* kCaptureRequestKey;
     static const char* kTimeStampKey;
     static const char* kCaptureResultKey;
+    static const char* kPhysicalCaptureResultKey;
     static const char* kCaptureFailureKey;
     static const char* kSequenceIdKey;
     static const char* kFrameNumberKey;
     static const char* kAnwKey;
+    static const char* kFailingPhysicalCameraId;
 
     class CallbackHandler : public AHandler {
       public:
+        explicit CallbackHandler(const char* id);
         void onMessageReceived(const sp<AMessage> &msg) override;
 
       private:
+        std::string mId;
         // This handler will cache all capture session sp until kWhatCleanUpSessions
         // is processed. This is used to guarantee the last session reference is always
         // being removed in callback thread without holding camera device lock
@@ -244,19 +274,47 @@
                        const Vector<sp<CaptureRequest> >& requests,
                        bool                               isRepeating,
                        ACameraCaptureSession_captureCallbacks* cbs);
+        CallbackHolder(sp<ACameraCaptureSession>          session,
+                       const Vector<sp<CaptureRequest> >& requests,
+                       bool                               isRepeating,
+                       ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs);
 
-        static ACameraCaptureSession_captureCallbacks fillCb(
-                ACameraCaptureSession_captureCallbacks* cbs) {
+        template <class T>
+        void initCaptureCallbacks(T* cbs) {
+            mContext = nullptr;
+            mOnCaptureStarted = nullptr;
+            mOnCaptureProgressed = nullptr;
+            mOnCaptureCompleted = nullptr;
+            mOnLogicalCameraCaptureCompleted = nullptr;
+            mOnLogicalCameraCaptureFailed = nullptr;
+            mOnCaptureFailed = nullptr;
+            mOnCaptureSequenceCompleted = nullptr;
+            mOnCaptureSequenceAborted = nullptr;
+            mOnCaptureBufferLost = nullptr;
             if (cbs != nullptr) {
-                return *cbs;
+                mContext = cbs->context;
+                mOnCaptureStarted = cbs->onCaptureStarted;
+                mOnCaptureProgressed = cbs->onCaptureProgressed;
+                mOnCaptureSequenceCompleted = cbs->onCaptureSequenceCompleted;
+                mOnCaptureSequenceAborted = cbs->onCaptureSequenceAborted;
+                mOnCaptureBufferLost = cbs->onCaptureBufferLost;
             }
-            return { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };
         }
-
         sp<ACameraCaptureSession>   mSession;
         Vector<sp<CaptureRequest> > mRequests;
         const bool                  mIsRepeating;
-        ACameraCaptureSession_captureCallbacks mCallbacks;
+        const bool                  mIsLogicalCameraCallback;
+
+        void*                       mContext;
+        ACameraCaptureSession_captureCallback_start mOnCaptureStarted;
+        ACameraCaptureSession_captureCallback_result mOnCaptureProgressed;
+        ACameraCaptureSession_captureCallback_result mOnCaptureCompleted;
+        ACameraCaptureSession_logicalCamera_captureCallback_result mOnLogicalCameraCaptureCompleted;
+        ACameraCaptureSession_logicalCamera_captureCallback_failed mOnLogicalCameraCaptureFailed;
+        ACameraCaptureSession_captureCallback_failed mOnCaptureFailed;
+        ACameraCaptureSession_captureCallback_sequenceEnd mOnCaptureSequenceCompleted;
+        ACameraCaptureSession_captureCallback_sequenceAbort mOnCaptureSequenceAborted;
+        ACameraCaptureSession_captureCallback_bufferLost mOnCaptureBufferLost;
     };
     // sequence id -> callbacks map
     std::map<int, CallbackHolder> mSequenceCallbackMap;
@@ -283,9 +341,11 @@
     // Misc variables
     int32_t mShadingMapSize[2];   // const after constructor
     int32_t mPartialResultCount;  // const after constructor
+    std::vector<std::string> mPhysicalIds; // const after constructor
 
 };
 
+} // namespace acam;
 } // namespace android;
 
 /**
@@ -294,10 +354,10 @@
  */
 struct ACameraDevice {
     ACameraDevice(const char* id, ACameraDevice_StateCallbacks* cb,
-                  std::unique_ptr<ACameraMetadata> chars) :
-            mDevice(new CameraDevice(id, cb, std::move(chars), this)) {}
+                  sp<ACameraMetadata> chars) :
+            mDevice(new android::acam::CameraDevice(id, cb, chars, this)) {}
 
-    ~ACameraDevice() {};
+    ~ACameraDevice();
 
     /*******************
      * NDK public APIs *
@@ -306,8 +366,9 @@
 
     camera_status_t createCaptureRequest(
             ACameraDevice_request_template templateId,
+            const ACameraIdList* physicalCameraIdList,
             ACaptureRequest** request) const {
-        return mDevice->createCaptureRequest(templateId, request);
+        return mDevice->createCaptureRequest(templateId, physicalCameraIdList, request);
     }
 
     camera_status_t createCaptureSession(
@@ -318,6 +379,11 @@
         return mDevice->createCaptureSession(outputs, sessionParameters, callbacks, session);
     }
 
+    camera_status_t isSessionConfigurationSupported(
+            const ACaptureSessionOutputContainer* sessionOutputContainer) const {
+        return mDevice->isSessionConfigurationSupported(sessionOutputContainer);
+    }
+
     /***********************
      * Device interal APIs *
      ***********************/
@@ -331,7 +397,7 @@
     }
 
   private:
-    android::sp<android::CameraDevice> mDevice;
+    android::sp<android::acam::CameraDevice> mDevice;
 };
 
 #endif // _ACAMERA_DEVICE_H
diff --git a/camera/ndk/impl/ACameraDevice.inc b/camera/ndk/impl/ACameraDevice.inc
new file mode 100644
index 0000000..1fc5352
--- /dev/null
+++ b/camera/ndk/impl/ACameraDevice.inc
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <vector>
+#include <inttypes.h>
+#include "ACameraDevice.h"
+#include "ACameraMetadata.h"
+#include "ACaptureRequest.h"
+#include "ACameraCaptureSession.h"
+
+namespace android {
+namespace acam {
+
+template<class T>
+camera_status_t
+CameraDevice::captureLocked(
+        sp<ACameraCaptureSession> session,
+        /*optional*/T* cbs,
+        int numRequests, ACaptureRequest** requests,
+        /*optional*/int* captureSequenceId) {
+    return submitRequestsLocked(
+            session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/false);
+}
+
+template<class T>
+camera_status_t
+CameraDevice::setRepeatingRequestsLocked(
+        sp<ACameraCaptureSession> session,
+        /*optional*/T* cbs,
+        int numRequests, ACaptureRequest** requests,
+        /*optional*/int* captureSequenceId) {
+    return submitRequestsLocked(
+            session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/true);
+}
+
+template<class T>
+camera_status_t CameraDevice::submitRequestsLocked(
+        sp<ACameraCaptureSession> session,
+        /*optional*/T* cbs,
+        int numRequests, ACaptureRequest** requests,
+        /*optional*/int* captureSequenceId,
+        bool isRepeating) {
+    camera_status_t ret = checkCameraClosedOrErrorLocked();
+    if (ret != ACAMERA_OK) {
+        ALOGE("Camera %s submit capture request failed! ret %d", getId(), ret);
+        return ret;
+    }
+
+    // Form two vectors of capture request, one for internal tracking
+    std::vector<hardware::camera2::CaptureRequest> requestList;
+    Vector<sp<CaptureRequest> > requestsV;
+    requestsV.setCapacity(numRequests);
+    for (int i = 0; i < numRequests; i++) {
+        sp<CaptureRequest> req;
+        ret = allocateCaptureRequest(requests[i], req);
+        if (ret != ACAMERA_OK) {
+            ALOGE("Convert capture request to internal format failure! ret %d", ret);
+            return ret;
+        }
+        if (req->mSurfaceList.empty()) {
+            ALOGE("Capture request without output target cannot be submitted!");
+            return ACAMERA_ERROR_INVALID_PARAMETER;
+        }
+        requestList.push_back(*(req.get()));
+        requestsV.push_back(req);
+    }
+
+    if (isRepeating) {
+        ret = stopRepeatingLocked();
+        if (ret != ACAMERA_OK) {
+            ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
+            return ret;
+        }
+    }
+
+    binder::Status remoteRet;
+    hardware::camera2::utils::SubmitInfo info;
+    remoteRet = mRemote->submitRequestList(requestList, isRepeating, &info);
+    int sequenceId = info.mRequestId;
+    int64_t lastFrameNumber = info.mLastFrameNumber;
+    if (sequenceId < 0) {
+        ALOGE("Camera %s submit request remote failure: ret %d", getId(), sequenceId);
+        return ACAMERA_ERROR_UNKNOWN;
+    }
+
+    CallbackHolder cbHolder(session, requestsV, isRepeating, cbs);
+    mSequenceCallbackMap.insert(std::make_pair(sequenceId, cbHolder));
+
+    if (isRepeating) {
+        // stopRepeating above should have cleanup repeating sequence id
+        if (mRepeatingSequenceId != REQUEST_ID_NONE) {
+            setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
+            return ACAMERA_ERROR_CAMERA_DEVICE;
+        }
+        mRepeatingSequenceId = sequenceId;
+    } else {
+        mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
+    }
+
+    if (mIdle) {
+        sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
+        msg->setPointer(kContextKey, session->mUserSessionCallback.context);
+        msg->setObject(kSessionSpKey, session);
+        msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
+        postSessionMsgAndCleanup(msg);
+    }
+    mIdle = false;
+    mBusySession = session;
+
+    if (captureSequenceId) {
+        *captureSequenceId = sequenceId;
+    }
+    return ACAMERA_OK;
+}
+
+} // namespace acam
+} // namespace android
diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp
index c59d0e7..9d40fd7 100644
--- a/camera/ndk/impl/ACameraManager.cpp
+++ b/camera/ndk/impl/ACameraManager.cpp
@@ -26,9 +26,10 @@
 #include <stdlib.h>
 #include <camera/VendorTagDescriptor.h>
 
-using namespace android;
+using namespace android::acam;
 
 namespace android {
+namespace acam {
 // Static member definitions
 const char* CameraManagerGlobal::kCameraIdKey   = "CameraId";
 const char* CameraManagerGlobal::kCallbackFpKey = "CallbackFp";
@@ -192,6 +193,20 @@
     }
 }
 
+void CameraManagerGlobal::registerExtendedAvailabilityCallback(
+        const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
+    Mutex::Autolock _l(mLock);
+    Callback cb(callback);
+    mCallbacks.insert(cb);
+}
+
+void CameraManagerGlobal::unregisterExtendedAvailabilityCallback(
+        const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
+    Mutex::Autolock _l(mLock);
+    Callback cb(callback);
+    mCallbacks.erase(cb);
+}
+
 void CameraManagerGlobal::registerAvailabilityCallback(
         const ACameraManager_AvailabilityCallbacks *callback) {
     Mutex::Autolock _l(mLock);
@@ -288,12 +303,40 @@
             (*cb)(context, cameraId.c_str());
             break;
         }
+        case kWhatSendSingleAccessCallback:
+        {
+            ACameraManager_AccessPrioritiesChangedCallback cb;
+            void* context;
+            AString cameraId;
+            bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
+            if (!found) {
+                ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
+                return;
+            }
+            found = msg->findPointer(kContextKey, &context);
+            if (!found) {
+                ALOGE("%s: Cannot find callback context!", __FUNCTION__);
+                return;
+            }
+            (*cb)(context);
+            break;
+        }
         default:
             ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what());
             break;
     }
 }
 
+binder::Status CameraManagerGlobal::CameraServiceListener::onCameraAccessPrioritiesChanged() {
+    sp<CameraManagerGlobal> cm = mCameraManager.promote();
+    if (cm != nullptr) {
+        cm->onCameraAccessPrioritiesChanged();
+    } else {
+        ALOGE("Cannot deliver camera access priority callback. Global camera manager died");
+    }
+    return binder::Status::ok();
+}
+
 binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged(
         int32_t status, const String16& cameraId) {
     sp<CameraManagerGlobal> cm = mCameraManager.promote();
@@ -305,6 +348,19 @@
     return binder::Status::ok();
 }
 
+void CameraManagerGlobal::onCameraAccessPrioritiesChanged() {
+    Mutex::Autolock _l(mLock);
+    for (auto cb : mCallbacks) {
+        sp<AMessage> msg = new AMessage(kWhatSendSingleAccessCallback, mHandler);
+        ACameraManager_AccessPrioritiesChangedCallback cbFp = cb.mAccessPriorityChanged;
+        if (cbFp != nullptr) {
+            msg->setPointer(kCallbackFpKey, (void *) cbFp);
+            msg->setPointer(kContextKey, cb.mContext);
+            msg->post();
+        }
+    }
+}
+
 void CameraManagerGlobal::onStatusChanged(
         int32_t status, const String8& cameraId) {
     Mutex::Autolock _l(mLock);
@@ -345,6 +401,7 @@
     }
 }
 
+} // namespace acam
 } // namespace android
 
 /**
@@ -402,7 +459,7 @@
 }
 
 camera_status_t ACameraManager::getCameraCharacteristics(
-        const char *cameraIdStr, ACameraMetadata **characteristics) {
+        const char* cameraIdStr, sp<ACameraMetadata>* characteristics) {
     Mutex::Autolock _l(mLock);
 
     sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
@@ -437,18 +494,16 @@
         const char* cameraId,
         ACameraDevice_StateCallbacks* callback,
         /*out*/ACameraDevice** outDevice) {
-    ACameraMetadata* rawChars;
-    camera_status_t ret = getCameraCharacteristics(cameraId, &rawChars);
+    sp<ACameraMetadata> chars;
+    camera_status_t ret = getCameraCharacteristics(cameraId, &chars);
     Mutex::Autolock _l(mLock);
     if (ret != ACAMERA_OK) {
         ALOGE("%s: cannot get camera characteristics for camera %s. err %d",
                 __FUNCTION__, cameraId, ret);
         return ACAMERA_ERROR_INVALID_PARAMETER;
     }
-    std::unique_ptr<ACameraMetadata> chars(rawChars);
-    rawChars = nullptr;
 
-    ACameraDevice* device = new ACameraDevice(cameraId, callback, std::move(chars));
+    ACameraDevice* device = new ACameraDevice(cameraId, callback, chars);
 
     sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
     if (cs == nullptr) {
diff --git a/camera/ndk/impl/ACameraManager.h b/camera/ndk/impl/ACameraManager.h
index cc42f77..8c1da36 100644
--- a/camera/ndk/impl/ACameraManager.h
+++ b/camera/ndk/impl/ACameraManager.h
@@ -35,6 +35,7 @@
 #include <map>
 
 namespace android {
+namespace acam {
 
 /**
  * Per-process singleton instance of CameraManger. Shared by all ACameraManager
@@ -53,6 +54,11 @@
     void unregisterAvailabilityCallback(
             const ACameraManager_AvailabilityCallbacks *callback);
 
+    void registerExtendedAvailabilityCallback(
+            const ACameraManager_ExtendedAvailabilityCallbacks* callback);
+    void unregisterExtendedAvailabilityCallback(
+            const ACameraManager_ExtendedAvailabilityCallbacks* callback);
+
     /**
      * Return camera IDs that support camera2
      */
@@ -85,6 +91,8 @@
             return binder::Status::ok();
         }
 
+        virtual binder::Status onCameraAccessPrioritiesChanged();
+
       private:
         const wp<CameraManagerGlobal> mCameraManager;
     };
@@ -95,11 +103,19 @@
         explicit Callback(const ACameraManager_AvailabilityCallbacks *callback) :
             mAvailable(callback->onCameraAvailable),
             mUnavailable(callback->onCameraUnavailable),
+            mAccessPriorityChanged(nullptr),
             mContext(callback->context) {}
 
+        explicit Callback(const ACameraManager_ExtendedAvailabilityCallbacks *callback) :
+            mAvailable(callback->availabilityCallbacks.onCameraAvailable),
+            mUnavailable(callback->availabilityCallbacks.onCameraUnavailable),
+            mAccessPriorityChanged(callback->onCameraAccessPrioritiesChanged),
+            mContext(callback->availabilityCallbacks.context) {}
+
         bool operator == (const Callback& other) const {
             return (mAvailable == other.mAvailable &&
                     mUnavailable == other.mUnavailable &&
+                    mAccessPriorityChanged == other.mAccessPriorityChanged &&
                     mContext == other.mContext);
         }
         bool operator != (const Callback& other) const {
@@ -108,6 +124,9 @@
         bool operator < (const Callback& other) const {
             if (*this == other) return false;
             if (mContext != other.mContext) return mContext < other.mContext;
+            if (mAccessPriorityChanged != other.mAccessPriorityChanged) {
+                return mAccessPriorityChanged < other.mAccessPriorityChanged;
+            }
             if (mAvailable != other.mAvailable) return mAvailable < other.mAvailable;
             return mUnavailable < other.mUnavailable;
         }
@@ -116,13 +135,15 @@
         }
         ACameraManager_AvailabilityCallback mAvailable;
         ACameraManager_AvailabilityCallback mUnavailable;
+        ACameraManager_AccessPrioritiesChangedCallback mAccessPriorityChanged;
         void*                               mContext;
     };
     std::set<Callback> mCallbacks;
 
     // definition of handler and message
     enum {
-        kWhatSendSingleCallback
+        kWhatSendSingleCallback,
+        kWhatSendSingleAccessCallback,
     };
     static const char* kCameraIdKey;
     static const char* kCallbackFpKey;
@@ -135,6 +156,7 @@
     sp<CallbackHandler> mHandler;
     sp<ALooper>         mCbLooper; // Looper thread where callbacks actually happen on
 
+    void onCameraAccessPrioritiesChanged();
     void onStatusChanged(int32_t status, const String8& cameraId);
     void onStatusChangedLocked(int32_t status, const String8& cameraId);
     // Utils for status
@@ -172,6 +194,7 @@
     ~CameraManagerGlobal();
 };
 
+} // namespace acam;
 } // namespace android;
 
 /**
@@ -180,13 +203,13 @@
  */
 struct ACameraManager {
     ACameraManager() :
-            mGlobalManager(&(android::CameraManagerGlobal::getInstance())) {}
+            mGlobalManager(&(android::acam::CameraManagerGlobal::getInstance())) {}
     ~ACameraManager();
     camera_status_t getCameraIdList(ACameraIdList** cameraIdList);
     static void     deleteCameraIdList(ACameraIdList* cameraIdList);
 
     camera_status_t getCameraCharacteristics(
-            const char *cameraId, ACameraMetadata **characteristics);
+            const char* cameraId, android::sp<ACameraMetadata>* characteristics);
     camera_status_t openCamera(const char* cameraId,
                                ACameraDevice_StateCallbacks* callback,
                                /*out*/ACameraDevice** device);
@@ -196,7 +219,7 @@
         kCameraIdListNotInit = -1
     };
     android::Mutex         mLock;
-    android::sp<android::CameraManagerGlobal> mGlobalManager;
+    android::sp<android::acam::CameraManagerGlobal> mGlobalManager;
 };
 
 #endif //_ACAMERA_MANAGER_H
diff --git a/camera/ndk/impl/ACameraMetadata.cpp b/camera/ndk/impl/ACameraMetadata.cpp
index fc00a2d..77dcd48 100644
--- a/camera/ndk/impl/ACameraMetadata.cpp
+++ b/camera/ndk/impl/ACameraMetadata.cpp
@@ -32,6 +32,14 @@
     if (mType == ACM_CHARACTERISTICS) {
         filterUnsupportedFeatures();
         filterStreamConfigurations();
+        filterDurations(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS);
+        filterDurations(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS);
+        filterDurations(ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS);
+        filterDurations(ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS);
+        filterDurations(ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS);
+        filterDurations(ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS);
+        filterDurations(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS);
+        filterDurations(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS);
     }
     // TODO: filter request/result keys
 }
@@ -39,23 +47,14 @@
 bool
 ACameraMetadata::isNdkSupportedCapability(int32_t capability) {
     switch (capability) {
-        case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE:
-        case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR:
-        case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING:
-        case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW:
-        case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS:
-        case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE:
-        case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT:
-            return true;
         case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING:
         case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING:
         case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO:
             return false;
         default:
-            // Newly defined capabilities will be unsupported by default (blacklist)
-            // TODO: Should we do whitelist or blacklist here?
-            ALOGE("%s: Unknonwn capability %d", __FUNCTION__, capability);
-            return false;
+            // Assuming every capability passed to this function is actually a
+            // valid capability.
+            return true;
     }
 }
 
@@ -75,11 +74,128 @@
         uint8_t capability = entry.data.u8[i];
         if (isNdkSupportedCapability(capability)) {
             capabilities.push(capability);
+
+            if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
+                derivePhysicalCameraIds();
+            }
         }
     }
     mData.update(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, capabilities);
 }
 
+void
+ACameraMetadata::derivePhysicalCameraIds() {
+    ACameraMetadata_const_entry entry;
+    auto ret = getConstEntry(ACAMERA_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS, &entry);
+    if (ret != ACAMERA_OK) {
+        ALOGE("%s: Get ACAMERA_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS key failed. ret %d",
+                __FUNCTION__, ret);
+        return;
+    }
+
+    const uint8_t* ids = entry.data.u8;
+    size_t start = 0;
+    for (size_t i = 0; i < entry.count; ++i) {
+        if (ids[i] == '\0') {
+            if (start != i) {
+                mStaticPhysicalCameraIdValues.push_back(String8((const char *)ids+start));
+                mStaticPhysicalCameraIds.push_back(mStaticPhysicalCameraIdValues.back().string());
+            }
+            start = i+1;
+        }
+    }
+
+    if (mStaticPhysicalCameraIds.size() < 2) {
+        ALOGW("%s: Logical multi-camera device only has %zu physical cameras",
+                __FUNCTION__, mStaticPhysicalCameraIds.size());
+    }
+}
+
+void
+ACameraMetadata::filterDurations(uint32_t tag) {
+    const int STREAM_CONFIGURATION_SIZE = 4;
+    const int STREAM_FORMAT_OFFSET = 0;
+    const int STREAM_WIDTH_OFFSET = 1;
+    const int STREAM_HEIGHT_OFFSET = 2;
+    const int STREAM_DURATION_OFFSET = 3;
+    camera_metadata_entry entry = mData.find(tag);
+    if (entry.count == 0 || entry.count % 4 || entry.type != TYPE_INT64) {
+        ALOGE("%s: malformed duration key %d! count %zu, type %d",
+                __FUNCTION__, tag, entry.count, entry.type);
+        return;
+    }
+    Vector<int64_t> filteredDurations;
+    filteredDurations.setCapacity(entry.count * 2);
+
+    for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
+        int64_t format = entry.data.i64[i + STREAM_FORMAT_OFFSET];
+        int64_t width = entry.data.i64[i + STREAM_WIDTH_OFFSET];
+        int64_t height = entry.data.i64[i + STREAM_HEIGHT_OFFSET];
+        int64_t duration = entry.data.i32[i + STREAM_DURATION_OFFSET];
+
+        // Leave the unfiltered format in so apps depending on previous wrong
+        // filter behavior continue to work
+        filteredDurations.push_back(format);
+        filteredDurations.push_back(width);
+        filteredDurations.push_back(height);
+        filteredDurations.push_back(duration);
+
+        // Translate HAL formats to NDK format
+        switch (tag) {
+            case ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS:
+            case ANDROID_SCALER_AVAILABLE_STALL_DURATIONS:
+                if (format == HAL_PIXEL_FORMAT_BLOB) {
+                    format = AIMAGE_FORMAT_JPEG;
+                    filteredDurations.push_back(format);
+                    filteredDurations.push_back(width);
+                    filteredDurations.push_back(height);
+                    filteredDurations.push_back(duration);
+                }
+                break;
+            case ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS:
+            case ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS:
+                if (format == HAL_PIXEL_FORMAT_BLOB) {
+                    format = AIMAGE_FORMAT_DEPTH_POINT_CLOUD;
+                    filteredDurations.push_back(format);
+                    filteredDurations.push_back(width);
+                    filteredDurations.push_back(height);
+                    filteredDurations.push_back(duration);
+                } else if (format == HAL_PIXEL_FORMAT_Y16) {
+                    format = AIMAGE_FORMAT_DEPTH16;
+                    filteredDurations.push_back(format);
+                    filteredDurations.push_back(width);
+                    filteredDurations.push_back(height);
+                    filteredDurations.push_back(duration);
+                }
+                break;
+            case ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS:
+            case ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS:
+                if (format == HAL_PIXEL_FORMAT_BLOB) {
+                    format = AIMAGE_FORMAT_HEIC;
+                    filteredDurations.push_back(format);
+                    filteredDurations.push_back(width);
+                    filteredDurations.push_back(height);
+                    filteredDurations.push_back(duration);
+                }
+                break;
+            case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS:
+            case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS:
+                if (format == HAL_PIXEL_FORMAT_BLOB) {
+                    format = AIMAGE_FORMAT_DEPTH_JPEG;
+                    filteredDurations.push_back(format);
+                    filteredDurations.push_back(width);
+                    filteredDurations.push_back(height);
+                    filteredDurations.push_back(duration);
+                }
+                break;
+            default:
+                // Should not reach here
+                ALOGE("%s: Unkown tag 0x%x", __FUNCTION__, tag);
+        }
+    }
+
+    mData.update(tag, filteredDurations);
+}
 
 void
 ACameraMetadata::filterStreamConfigurations() {
@@ -89,7 +205,7 @@
     const int STREAM_HEIGHT_OFFSET = 2;
     const int STREAM_IS_INPUT_OFFSET = 3;
     camera_metadata_entry entry = mData.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
-    if (entry.count == 0 || entry.count % 4 || entry.type != TYPE_INT32) {
+    if (entry.count > 0 && (entry.count % 4 || entry.type != TYPE_INT32)) {
         ALOGE("%s: malformed available stream configuration key! count %zu, type %d",
                 __FUNCTION__, entry.count, entry.type);
         return;
@@ -117,9 +233,17 @@
         filteredStreamConfigs.push_back(isInput);
     }
 
-    mData.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, filteredStreamConfigs);
+    if (filteredStreamConfigs.size() > 0) {
+        mData.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, filteredStreamConfigs);
+    }
 
     entry = mData.find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS);
+    if (entry.count > 0 && (entry.count % 4 || entry.type != TYPE_INT32)) {
+        ALOGE("%s: malformed available depth stream configuration key! count %zu, type %d",
+                __FUNCTION__, entry.count, entry.type);
+        return;
+    }
+
     Vector<int32_t> filteredDepthStreamConfigs;
     filteredDepthStreamConfigs.setCapacity(entry.count);
 
@@ -144,7 +268,62 @@
         filteredDepthStreamConfigs.push_back(height);
         filteredDepthStreamConfigs.push_back(isInput);
     }
-    mData.update(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, filteredDepthStreamConfigs);
+
+    if (filteredDepthStreamConfigs.size() > 0) {
+        mData.update(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
+                filteredDepthStreamConfigs);
+    }
+
+    entry = mData.find(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS);
+    Vector<int32_t> filteredHeicStreamConfigs;
+    filteredHeicStreamConfigs.setCapacity(entry.count);
+
+    for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
+        int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
+        int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
+        int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
+        int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
+        if (isInput == ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_INPUT) {
+            // Hide input streams
+            continue;
+        }
+        // Translate HAL formats to NDK format
+        if (format == HAL_PIXEL_FORMAT_BLOB) {
+            format = AIMAGE_FORMAT_HEIC;
+        }
+
+        filteredHeicStreamConfigs.push_back(format);
+        filteredHeicStreamConfigs.push_back(width);
+        filteredHeicStreamConfigs.push_back(height);
+        filteredHeicStreamConfigs.push_back(isInput);
+    }
+    mData.update(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS, filteredHeicStreamConfigs);
+
+    entry = mData.find(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS);
+    Vector<int32_t> filteredDynamicDepthStreamConfigs;
+    filteredDynamicDepthStreamConfigs.setCapacity(entry.count);
+
+    for (size_t i = 0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
+        int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
+        int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
+        int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
+        int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
+        if (isInput == ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_INPUT) {
+            // Hide input streams
+            continue;
+        }
+        // Translate HAL formats to NDK format
+        if (format == HAL_PIXEL_FORMAT_BLOB) {
+            format = AIMAGE_FORMAT_DEPTH_JPEG;
+        }
+
+        filteredDynamicDepthStreamConfigs.push_back(format);
+        filteredDynamicDepthStreamConfigs.push_back(width);
+        filteredDynamicDepthStreamConfigs.push_back(height);
+        filteredDynamicDepthStreamConfigs.push_back(isInput);
+    }
+    mData.update(ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS,
+            filteredDynamicDepthStreamConfigs);
 }
 
 bool
@@ -239,6 +418,27 @@
     return mData;
 }
 
+bool
+ACameraMetadata::isLogicalMultiCamera(size_t* count, const char*const** physicalCameraIds) const {
+    if (mType != ACM_CHARACTERISTICS) {
+        ALOGE("%s must be called for a static metadata!", __FUNCTION__);
+        return false;
+    }
+    if (count == nullptr || physicalCameraIds == nullptr) {
+        ALOGE("%s: Invalid input count: %p, physicalCameraIds: %p", __FUNCTION__,
+                count, physicalCameraIds);
+        return false;
+    }
+
+    if (mStaticPhysicalCameraIds.size() >= 2) {
+        *count = mStaticPhysicalCameraIds.size();
+        *physicalCameraIds = mStaticPhysicalCameraIds.data();
+        return true;
+    }
+
+    return false;
+}
+
 // TODO: some of key below should be hidden from user
 // ex: ACAMERA_REQUEST_ID and ACAMERA_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR
 /*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
@@ -360,7 +560,10 @@
     ANDROID_STATISTICS_INFO_MAX_HISTOGRAM_COUNT,
     ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE,
     ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE,
+    ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION,
     ANDROID_DEPTH_MAX_DEPTH_SAMPLES,
+    ANDROID_HEIC_INFO_SUPPORTED,
+    ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT,
 });
 
 /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
diff --git a/camera/ndk/impl/ACameraMetadata.h b/camera/ndk/impl/ACameraMetadata.h
index 0fd7efa..97f7f48 100644
--- a/camera/ndk/impl/ACameraMetadata.h
+++ b/camera/ndk/impl/ACameraMetadata.h
@@ -17,12 +17,19 @@
 #define _ACAMERA_METADATA_H
 
 #include <unordered_set>
+#include <vector>
 
 #include <sys/types.h>
 #include <utils/Mutex.h>
 #include <utils/RefBase.h>
 #include <utils/Vector.h>
+
+#ifdef __ANDROID_VNDK__
+#include <CameraMetadata.h>
+using CameraMetadata = android::hardware::camera::common::V1_0::helper::CameraMetadata;
+#else
 #include <camera/CameraMetadata.h>
+#endif
 
 #include <camera/NdkCameraMetadata.h>
 
@@ -58,13 +65,20 @@
     camera_status_t getTags(/*out*/int32_t* numTags,
                             /*out*/const uint32_t** tags) const;
 
+    const CameraMetadata& getInternalData() const;
+    bool isLogicalMultiCamera(size_t* count, const char* const** physicalCameraIds) const;
+
+  private:
+
+    // This function does not check whether the capability passed to it is valid.
+    // The caller must make sure that it is.
     bool isNdkSupportedCapability(const int32_t capability);
     static inline bool isVendorTag(const uint32_t tag);
     static bool isCaptureRequestTag(const uint32_t tag);
     void filterUnsupportedFeatures(); // Hide features not yet supported by NDK
     void filterStreamConfigurations(); // Hide input streams, translate hal format to NDK formats
-
-    const CameraMetadata& getInternalData() const;
+    void filterDurations(uint32_t tag); // translate hal format to NDK formats
+    void derivePhysicalCameraIds(); // Derive array of physical ids.
 
     template<typename INTERNAL_T, typename NDK_T>
     camera_status_t updateImpl(uint32_t tag, uint32_t count, const NDK_T* data) {
@@ -96,7 +110,6 @@
         }
     }
 
-  private:
     // guard access of public APIs: get/update/getTags
     mutable Mutex    mLock;
     CameraMetadata   mData;
@@ -104,6 +117,9 @@
     const ACAMERA_METADATA_TYPE mType;
 
     static std::unordered_set<uint32_t> sSystemTags;
+
+    std::vector<const char*> mStaticPhysicalCameraIds;
+    std::vector<String8> mStaticPhysicalCameraIdValues;
 };
 
 #endif // _ACAMERA_METADATA_H
diff --git a/camera/ndk/impl/ACaptureRequest.h b/camera/ndk/impl/ACaptureRequest.h
index 06b2cc3..2ffcafe 100644
--- a/camera/ndk/impl/ACaptureRequest.h
+++ b/camera/ndk/impl/ACaptureRequest.h
@@ -18,11 +18,15 @@
 
 #include <camera/NdkCaptureRequest.h>
 #include <set>
+#include <unordered_map>
 
 using namespace android;
 
+#ifdef __ANDROID_VNDK__
+#include "ndk_vendor/impl/ACaptureRequestVendor.h"
+#else
 struct ACameraOutputTarget {
-    explicit ACameraOutputTarget(ANativeWindow* window) : mWindow(window) {};
+    explicit ACameraOutputTarget(ACameraWindowType* window) : mWindow(window) {};
 
     bool operator == (const ACameraOutputTarget& other) const {
         return mWindow == other.mWindow;
@@ -37,8 +41,9 @@
         return mWindow > other.mWindow;
     }
 
-    ANativeWindow* mWindow;
+    ACameraWindowType* mWindow;
 };
+#endif
 
 struct ACameraOutputTargets {
     std::set<ACameraOutputTarget> mOutputs;
@@ -55,7 +60,8 @@
         return ACAMERA_OK;
     }
 
-    ACameraMetadata*      settings;
+    sp<ACameraMetadata> settings;
+    std::unordered_map<std::string, sp<ACameraMetadata>> physicalSettings;
     ACameraOutputTargets* targets;
     void*                 context;
 };
diff --git a/camera/ndk/include/camera/NdkCameraCaptureSession.h b/camera/ndk/include/camera/NdkCameraCaptureSession.h
index 51cef8c..07176cf 100644
--- a/camera/ndk/include/camera/NdkCameraCaptureSession.h
+++ b/camera/ndk/include/camera/NdkCameraCaptureSession.h
@@ -35,9 +35,10 @@
 #include <sys/cdefs.h>
 #include <stdbool.h>
 
-#include <android/native_window.h>
 #include "NdkCameraError.h"
 #include "NdkCameraMetadata.h"
+#include "NdkCaptureRequest.h"
+#include "NdkCameraWindowType.h"
 
 #ifndef _NDK_CAMERA_CAPTURE_SESSION_H
 #define _NDK_CAMERA_CAPTURE_SESSION_H
@@ -245,7 +246,7 @@
  */
 typedef void (*ACameraCaptureSession_captureCallback_bufferLost)(
         void* context, ACameraCaptureSession* session,
-        ACaptureRequest* request, ANativeWindow* window, int64_t frameNumber);
+        ACaptureRequest* request, ACameraWindowType* window, int64_t frameNumber);
 
 typedef struct ACameraCaptureSession_captureCallbacks {
     /// optional application context.
@@ -433,7 +434,7 @@
  *
  */
 camera_status_t ACameraCaptureSession_getDevice(
-        ACameraCaptureSession* session, /*out*/ACameraDevice** device);
+        ACameraCaptureSession* session, /*out*/ACameraDevice** device) __INTRODUCED_IN(24);
 
 /**
  * Submit an array of requests to be captured in sequence as a burst in the minimum of time possible.
@@ -471,7 +472,7 @@
         ACameraCaptureSession* session,
         /*optional*/ACameraCaptureSession_captureCallbacks* callbacks,
         int numRequests, ACaptureRequest** requests,
-        /*optional*/int* captureSequenceId);
+        /*optional*/int* captureSequenceId) __INTRODUCED_IN(24);
 
 /**
  * Request endlessly repeating capture of a sequence of images by this capture session.
@@ -525,7 +526,7 @@
         ACameraCaptureSession* session,
         /*optional*/ACameraCaptureSession_captureCallbacks* callbacks,
         int numRequests, ACaptureRequest** requests,
-        /*optional*/int* captureSequenceId);
+        /*optional*/int* captureSequenceId) __INTRODUCED_IN(24);
 
 /**
  * Cancel any ongoing repeating capture set by {@link ACameraCaptureSession_setRepeatingRequest}.
@@ -548,7 +549,8 @@
  *         <li>{@link ACAMERA_ERROR_CAMERA_SERVICE} if the camera service encounters fatal error</li>
  *         <li>{@link ACAMERA_ERROR_UNKNOWN} if the method fails for some other reasons</li></ul>
  */
-camera_status_t ACameraCaptureSession_stopRepeating(ACameraCaptureSession* session);
+camera_status_t ACameraCaptureSession_stopRepeating(ACameraCaptureSession* session)
+        __INTRODUCED_IN(24);
 
 /**
  * Discard all captures currently pending and in-progress as fast as possible.
@@ -588,7 +590,8 @@
  *         <li>{@link ACAMERA_ERROR_CAMERA_SERVICE} if the camera service encounters fatal error</li>
  *         <li>{@link ACAMERA_ERROR_UNKNOWN} if the method fails for some other reasons</li></ul>
  */
-camera_status_t ACameraCaptureSession_abortCaptures(ACameraCaptureSession* session);
+camera_status_t ACameraCaptureSession_abortCaptures(ACameraCaptureSession* session)
+        __INTRODUCED_IN(24);
 
 #endif /* __ANDROID_API__ >= 24 */
 
@@ -637,9 +640,156 @@
  *         <li>{@link ACAMERA_ERROR_UNKNOWN} if the method fails for some other reasons</li></ul>
  */
 camera_status_t ACameraCaptureSession_updateSharedOutput(ACameraCaptureSession* session,
-        ACaptureSessionOutput* output);
+        ACaptureSessionOutput* output) __INTRODUCED_IN(28);
 #endif /* __ANDROID_API__ >= 28 */
 
+#if __ANDROID_API__ >= 29
+/**
+ * The definition of final capture result callback with logical multi-camera support.
+ *
+ * This has the same functionality as final ACameraCaptureSession_captureCallback_result, with
+ * added ability to return physical camera result metadata within a logical multi-camera.
+ *
+ * For a logical multi-camera, this function will be called with the Id and result metadata
+ * of the underlying physical cameras, which the corresponding capture request contains targets for.
+ * If the capture request doesn't contain targets specific to any physical camera, or the current
+ * camera device isn't a logical multi-camera, physicalResultCount will be 0.
+ *
+ * @param context The optional application context provided by user in
+ *                {@link ACameraCaptureSession_captureCallbacks}.
+ * @param session The camera capture session of interest.
+ * @param request The capture request of interest. Note that this pointer points to a copy of
+ *                capture request sent by application, so the address is different to what
+ *                application sent but the content will match. This request will be freed by
+ *                framework immediately after this callback returns.
+ * @param result The capture result metadata reported by camera device. The memory is managed by
+ *                camera framework. Do not access this pointer after this callback returns.
+ * @param physicalResultCount The number of physical camera result metadata
+ * @param physicalCameraIds The array of physical camera IDs on which the
+ *                physical result metadata are reported.
+ * @param physicalResults The array of capture result metadata reported by the
+ *                physical camera devices.
+ */
+typedef void (*ACameraCaptureSession_logicalCamera_captureCallback_result)(
+        void* context, ACameraCaptureSession* session,
+        ACaptureRequest* request, const ACameraMetadata* result,
+        size_t physicalResultCount, const char** physicalCameraIds,
+        const ACameraMetadata** physicalResults);
+
+/// Struct to describe a logical camera capture failure
+typedef struct ALogicalCameraCaptureFailure {
+    /**
+     * The {@link ACameraCaptureFailure} contains information about regular logical device capture
+     * failure.
+     */
+    struct ACameraCaptureFailure captureFailure;
+
+    /**
+     * The physical camera device ID in case the capture failure comes from a capture request
+     * with configured physical camera streams for a logical camera. physicalCameraId will be set
+     * to NULL in case the capture request has no associated physical camera device.
+     *
+     */
+    const char*    physicalCameraId;
+} ALogicalCameraCaptureFailure;
+
+/**
+ * The definition of logical camera capture failure callback.
+ *
+ * @param context The optional application context provided by user in
+ *                {@link ACameraCaptureSession_captureCallbacks}.
+ * @param session The camera capture session of interest.
+ * @param request The capture request of interest. Note that this pointer points to a copy of
+ *                capture request sent by application, so the address is different to what
+ *                application sent but the content will match. This request will be freed by
+ *                framework immediately after this callback returns.
+ * @param failure The {@link ALogicalCameraCaptureFailure} desribes the capture failure. The memory
+ *                is managed by camera framework. Do not access this pointer after this callback
+ *                returns.
+ */
+typedef void (*ACameraCaptureSession_logicalCamera_captureCallback_failed)(
+        void* context, ACameraCaptureSession* session,
+        ACaptureRequest* request, ALogicalCameraCaptureFailure* failure);
+
+/**
+ * This has the same functionality as ACameraCaptureSession_captureCallbacks,
+ * with the exception that an onLogicalCameraCaptureCompleted callback is
+ * used, instead of onCaptureCompleted, to support logical multi-camera.
+ */
+typedef struct ACameraCaptureSession_logicalCamera_captureCallbacks {
+    /**
+     * Same as ACameraCaptureSession_captureCallbacks
+     */
+    void*                                               context;
+    ACameraCaptureSession_captureCallback_start         onCaptureStarted;
+    ACameraCaptureSession_captureCallback_result        onCaptureProgressed;
+
+    /**
+     * This callback is called when an image capture has fully completed and all the
+     * result metadata is available. For a logical multi-camera, this callback
+     * also returns the result metadata for all physical cameras being
+     * explicitly requested on.
+     *
+     * <p>This callback will always fire after the last {@link onCaptureProgressed};
+     * in other words, no more partial results will be delivered once the completed result
+     * is available.</p>
+     *
+     * <p>For performance-intensive use-cases where latency is a factor, consider
+     * using {@link onCaptureProgressed} instead.</p>
+     *
+     * <p>Note that the ACaptureRequest pointer in the callback will not match what application has
+     * submitted, but the contents the ACaptureRequest will match what application submitted.</p>
+     */
+    ACameraCaptureSession_logicalCamera_captureCallback_result onLogicalCameraCaptureCompleted;
+
+    /**
+     * This callback is called instead of {@link onLogicalCameraCaptureCompleted} when the
+     * camera device failed to produce a capture result for the
+     * request.
+     *
+     * <p>Other requests are unaffected, and some or all image buffers from
+     * the capture may have been pushed to their respective output
+     * streams.</p>
+     *
+     * <p>Note that the ACaptureRequest pointer in the callback will not match what application has
+     * submitted, but the contents the ACaptureRequest will match what application submitted.</p>
+     *
+     * @see ALogicalCameraCaptureFailure
+     */
+    ACameraCaptureSession_logicalCamera_captureCallback_failed onLogicalCameraCaptureFailed;
+
+    /**
+     * Same as ACameraCaptureSession_captureCallbacks
+     */
+    ACameraCaptureSession_captureCallback_sequenceEnd   onCaptureSequenceCompleted;
+    ACameraCaptureSession_captureCallback_sequenceAbort onCaptureSequenceAborted;
+    ACameraCaptureSession_captureCallback_bufferLost    onCaptureBufferLost;
+} ACameraCaptureSession_logicalCamera_captureCallbacks;
+
+/**
+ * This has the same functionality as ACameraCaptureSession_capture, with added
+ * support for logical multi-camera where the capture callbacks supports result metadata for
+ * physical cameras.
+ */
+camera_status_t ACameraCaptureSession_logicalCamera_capture(
+        ACameraCaptureSession* session,
+        /*optional*/ACameraCaptureSession_logicalCamera_captureCallbacks* callbacks,
+        int numRequests, ACaptureRequest** requests,
+        /*optional*/int* captureSequenceId) __INTRODUCED_IN(29);
+
+/**
+ * This has the same functionality as ACameraCaptureSession_setRepeatingRequest, with added
+ * support for logical multi-camera where the capture callbacks supports result metadata for
+ * physical cameras.
+ */
+camera_status_t ACameraCaptureSession_logicalCamera_setRepeatingRequest(
+        ACameraCaptureSession* session,
+        /*optional*/ACameraCaptureSession_logicalCamera_captureCallbacks* callbacks,
+        int numRequests, ACaptureRequest** requests,
+        /*optional*/int* captureSequenceId) __INTRODUCED_IN(29);
+
+#endif /* __ANDROID_API__ >= 29 */
+
 __END_DECLS
 
 #endif /* _NDK_CAMERA_CAPTURE_SESSION_H */
diff --git a/camera/ndk/include/camera/NdkCameraDevice.h b/camera/ndk/include/camera/NdkCameraDevice.h
index 92dad1c..1537bde 100644
--- a/camera/ndk/include/camera/NdkCameraDevice.h
+++ b/camera/ndk/include/camera/NdkCameraDevice.h
@@ -34,10 +34,10 @@
  */
 #include <sys/cdefs.h>
 
-#include <android/native_window.h>
 #include "NdkCameraError.h"
 #include "NdkCaptureRequest.h"
 #include "NdkCameraCaptureSession.h"
+#include "NdkCameraWindowType.h"
 
 #ifndef _NDK_CAMERA_DEVICE_H
 #define _NDK_CAMERA_DEVICE_H
@@ -53,6 +53,17 @@
  */
 typedef struct ACameraDevice ACameraDevice;
 
+/**
+ * Struct to hold list of camera device Ids. This can refer to either the Ids
+ * of connected camera devices returned from {@link ACameraManager_getCameraIdList},
+ * or the physical camera Ids passed into
+ * {@link ACameraDevice_createCaptureRequest_withPhysicalIds}.
+ */
+typedef struct ACameraIdList {
+    int numCameras;          ///< Number of camera device Ids
+    const char** cameraIds;  ///< list of camera device Ids
+} ACameraIdList;
+
 /// Enum for ACameraDevice_ErrorStateCallback error code
 enum {
     /**
@@ -176,7 +187,7 @@
  *         <li>{@link ACAMERA_OK} if the method call succeeds.</li>
  *         <li>{@link ACAMERA_ERROR_INVALID_PARAMETER} if device is NULL.</li></ul>
  */
-camera_status_t ACameraDevice_close(ACameraDevice* device);
+camera_status_t ACameraDevice_close(ACameraDevice* device) __INTRODUCED_IN(24);
 
 /**
  * Return the camera id associated with this camera device.
@@ -187,7 +198,7 @@
  * delete/free by the application. Also the returned string must not be used after the device
  * has been closed.
  */
-const char* ACameraDevice_getId(const ACameraDevice* device);
+const char* ACameraDevice_getId(const ACameraDevice* device) __INTRODUCED_IN(24);
 
 typedef enum {
     /**
@@ -290,7 +301,7 @@
  */
 camera_status_t ACameraDevice_createCaptureRequest(
         const ACameraDevice* device, ACameraDevice_request_template templateId,
-        /*out*/ACaptureRequest** request);
+        /*out*/ACaptureRequest** request) __INTRODUCED_IN(24);
 
 
 typedef struct ACaptureSessionOutputContainer ACaptureSessionOutputContainer;
@@ -313,7 +324,7 @@
  *         <li>{@link ACAMERA_ERROR_INVALID_PARAMETER} if container is NULL.</li></ul>
  */
 camera_status_t ACaptureSessionOutputContainer_create(
-        /*out*/ACaptureSessionOutputContainer** container);
+        /*out*/ACaptureSessionOutputContainer** container) __INTRODUCED_IN(24);
 
 /**
  * Free a capture session output container.
@@ -322,7 +333,8 @@
  *
  * @see ACaptureSessionOutputContainer_create
  */
-void            ACaptureSessionOutputContainer_free(ACaptureSessionOutputContainer* container);
+void            ACaptureSessionOutputContainer_free(ACaptureSessionOutputContainer* container)
+        __INTRODUCED_IN(24);
 
 /**
  * Create a ACaptureSessionOutput object.
@@ -344,7 +356,7 @@
  * @see ACaptureSessionOutputContainer_add
  */
 camera_status_t ACaptureSessionOutput_create(
-        ANativeWindow* anw, /*out*/ACaptureSessionOutput** output);
+        ACameraWindowType* anw, /*out*/ACaptureSessionOutput** output) __INTRODUCED_IN(24);
 
 /**
  * Free a ACaptureSessionOutput object.
@@ -353,7 +365,7 @@
  *
  * @see ACaptureSessionOutput_create
  */
-void            ACaptureSessionOutput_free(ACaptureSessionOutput* output);
+void            ACaptureSessionOutput_free(ACaptureSessionOutput* output) __INTRODUCED_IN(24);
 
 /**
  * Add an {@link ACaptureSessionOutput} object to {@link ACaptureSessionOutputContainer}.
@@ -366,7 +378,8 @@
  *         <li>{@link ACAMERA_ERROR_INVALID_PARAMETER} if container or output is NULL.</li></ul>
  */
 camera_status_t ACaptureSessionOutputContainer_add(
-        ACaptureSessionOutputContainer* container, const ACaptureSessionOutput* output);
+        ACaptureSessionOutputContainer* container, const ACaptureSessionOutput* output)
+        __INTRODUCED_IN(24);
 
 /**
  * Remove an {@link ACaptureSessionOutput} object from {@link ACaptureSessionOutputContainer}.
@@ -382,7 +395,8 @@
  *         <li>{@link ACAMERA_ERROR_INVALID_PARAMETER} if container or output is NULL.</li></ul>
  */
 camera_status_t ACaptureSessionOutputContainer_remove(
-        ACaptureSessionOutputContainer* container, const ACaptureSessionOutput* output);
+        ACaptureSessionOutputContainer* container, const ACaptureSessionOutput* output)
+        __INTRODUCED_IN(24);
 
 /**
  * Create a new camera capture session by providing the target output set of {@link ANativeWindow}
@@ -671,7 +685,7 @@
         ACameraDevice* device,
         const ACaptureSessionOutputContainer*       outputs,
         const ACameraCaptureSession_stateCallbacks* callbacks,
-        /*out*/ACameraCaptureSession** session);
+        /*out*/ACameraCaptureSession** session) __INTRODUCED_IN(24);
 
 #endif /* __ANDROID_API__ >= 24 */
 
@@ -699,7 +713,7 @@
  * @see ACaptureSessionOutputContainer_add
  */
 camera_status_t ACaptureSessionSharedOutput_create(
-        ANativeWindow* anw, /*out*/ACaptureSessionOutput** output);
+        ACameraWindowType* anw, /*out*/ACaptureSessionOutput** output) __INTRODUCED_IN(28);
 
 /**
  * Add a native window to shared ACaptureSessionOutput.
@@ -716,7 +730,8 @@
  *             window associated with ACaptureSessionOutput; or anw is already present inside
  *             ACaptureSessionOutput.</li></ul>
  */
-camera_status_t ACaptureSessionSharedOutput_add(ACaptureSessionOutput *output, ANativeWindow *anw);
+camera_status_t ACaptureSessionSharedOutput_add(ACaptureSessionOutput *output,
+        ACameraWindowType *anw) __INTRODUCED_IN(28);
 
 /**
  * Remove a native window from shared ACaptureSessionOutput.
@@ -732,7 +747,7 @@
  *             ACaptureSessionOutput.</li></ul>
  */
 camera_status_t ACaptureSessionSharedOutput_remove(ACaptureSessionOutput *output,
-        ANativeWindow* anw);
+        ACameraWindowType* anw) __INTRODUCED_IN(28);
 
 /**
  * Create a new camera capture session similar to {@link ACameraDevice_createCaptureSession}. This
@@ -765,10 +780,118 @@
         const ACaptureSessionOutputContainer* outputs,
         const ACaptureRequest* sessionParameters,
         const ACameraCaptureSession_stateCallbacks* callbacks,
-        /*out*/ACameraCaptureSession** session);
+        /*out*/ACameraCaptureSession** session) __INTRODUCED_IN(28);
 
 #endif /* __ANDROID_API__ >= 28 */
 
+#if __ANDROID_API__ >= 29
+
+/**
+ * Create a ACaptureSessionOutput object used for streaming from a physical
+ * camera as part of a logical camera device.
+ *
+ * <p>The ACaptureSessionOutput is used in {@link ACaptureSessionOutputContainer_add} method to add
+ * an output {@link ANativeWindow} to ACaptureSessionOutputContainer. Use
+ * {@link ACaptureSessionOutput_free} to free the object and its memory after application no longer
+ * needs the {@link ACaptureSessionOutput}.</p>
+ *
+ * @param anw the {@link ANativeWindow} to be associated with the {@link ACaptureSessionOutput}
+ * @param physicalId the Id of the physical camera this output is associated
+ *                  with.
+ * @param output the output {@link ACaptureSessionOutput} will be stored here if the
+ *                  method call succeeds.
+ *
+ * @return <ul>
+ *         <li>{@link ACAMERA_OK} if the method call succeeds. The created container will be
+ *                                filled in the output argument.</li>
+ *         <li>{@link ACAMERA_ERROR_INVALID_PARAMETER} if anw, physicalId or output is NULL.</li></ul>
+ *
+ * @see ACaptureSessionOutputContainer_add
+ */
+camera_status_t ACaptureSessionPhysicalOutput_create(
+        ACameraWindowType* anw, const char* physicalId,
+        /*out*/ACaptureSessionOutput** output) __INTRODUCED_IN(29);
+
+/**
+ * Create a logical multi-camera ACaptureRequest for capturing images, initialized with template
+ * for a target use case, with the ability to specify physical camera settings.
+ *
+ * <p>The settings are chosen to be the best options for this camera device,
+ * so it is not recommended to reuse the same request for a different camera device.</p>
+ *
+ * <p>Note that for all keys in physical camera settings, only the keys
+ * advertised in ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS are
+ * applicable. All other keys are ignored by the camera device.</p>
+ *
+ * @param device the camera device of interest
+ * @param templateId the type of capture request to be created.
+ *        See {@link ACameraDevice_request_template}.
+ * @param physicalIdList The list of physical camera Ids that can be used to
+ *        customize the request for a specific physical camera.
+ * @param request the output request will be stored here if the method call succeeds.
+ *
+ * @return <ul>
+ *         <li>{@link ACAMERA_OK} if the method call succeeds. The created capture request will be
+ *                                filled in request argument.</li>
+ *         <li>{@link ACAMERA_ERROR_INVALID_PARAMETER} if device, physicalIdList, or request is
+ *                                NULL, templateId is undefined or camera device does not support
+ *                                requested template, or if some Ids in physicalIdList isn't a
+ *                                valid physical camera backing the current camera device.</li>
+ *         <li>{@link ACAMERA_ERROR_CAMERA_DISCONNECTED} if the camera device is closed.</li>
+ *         <li>{@link ACAMERA_ERROR_CAMERA_DEVICE} if the camera device encounters fatal error.</li>
+ *         <li>{@link ACAMERA_ERROR_CAMERA_SERVICE} if the camera service encounters fatal error.</li>
+ *         <li>{@link ACAMERA_ERROR_UNKNOWN} if the method fails for some other reasons.</li></ul>
+ *
+ * @see TEMPLATE_PREVIEW
+ * @see TEMPLATE_RECORD
+ * @see TEMPLATE_STILL_CAPTURE
+ * @see TEMPLATE_VIDEO_SNAPSHOT
+ * @see TEMPLATE_MANUAL
+ */
+camera_status_t ACameraDevice_createCaptureRequest_withPhysicalIds(
+        const ACameraDevice* device, ACameraDevice_request_template templateId,
+        const ACameraIdList* physicalIdList,
+        /*out*/ACaptureRequest** request) __INTRODUCED_IN(29);
+
+/**
+ * Check whether a particular {@ACaptureSessionOutputContainer} is supported by
+ * the camera device.
+ *
+ * <p>This method performs a runtime check of a given {@link
+ * ACaptureSessionOutputContainer}. The result confirms whether or not the
+ * passed CaptureSession outputs can be successfully used to create a camera
+ * capture session using {@link ACameraDevice_createCaptureSession}.</p>
+ *
+ * <p>This method can be called at any point before, during and after active
+ * capture session. It must not impact normal camera behavior in any way and
+ * must complete significantly faster than creating a capture session.</p>
+ *
+ * <p>Although this method is faster than creating a new capture session, it is not intended
+ * to be used for exploring the entire space of supported stream combinations.</p>
+ *
+ * @param device the camera device of interest
+ * @param sessionOutputContainer the {@link ACaptureSessionOutputContainer} of
+ *                               interest.
+ *
+ * @return <ul>
+ *         <li>{@link ACAMERA_OK} if the given {@link ACaptureSessionOutputContainer}
+ *                                is supported by the camera device.</li>
+ *         <li>{@link ACAMERA_ERROR_INVALID_PARAMETER} if device, or sessionOutputContainer
+ *                                                     is NULL.</li>
+ *         <li>{@link ACAMERA_ERROR_STREAM_CONFIGURE_FAIL} if the given
+ *                                                         {@link ACaptureSessionOutputContainer}
+ *                                                         is not supported by
+ *                                                         the camera
+ *                                                         device.</li>
+ *        <li>{@link ACAMERA_ERROR_UNSUPPORTED_OPERATION} if the query operation is not
+ *                                                        supported by the camera device.</li>
+ */
+camera_status_t ACameraDevice_isSessionConfigurationSupported(
+        const ACameraDevice* device,
+        const ACaptureSessionOutputContainer* sessionOutputContainer) __INTRODUCED_IN(29);
+
+#endif /* __ANDROID_API__ >= 29 */
+
 __END_DECLS
 
 #endif /* _NDK_CAMERA_DEVICE_H */
diff --git a/camera/ndk/include/camera/NdkCameraError.h b/camera/ndk/include/camera/NdkCameraError.h
index 6b58155..fc618ee 100644
--- a/camera/ndk/include/camera/NdkCameraError.h
+++ b/camera/ndk/include/camera/NdkCameraError.h
@@ -106,7 +106,8 @@
 
     /**
      * Camera device does not support the stream configuration provided by application in
-     * {@link ACameraDevice_createCaptureSession}.
+     * {@link ACameraDevice_createCaptureSession} or {@link
+     * ACameraDevice_isSessionConfigurationSupported}.
      */
     ACAMERA_ERROR_STREAM_CONFIGURE_FAIL = ACAMERA_ERROR_BASE - 9,
 
@@ -130,6 +131,11 @@
      * The application does not have permission to open camera.
      */
     ACAMERA_ERROR_PERMISSION_DENIED     = ACAMERA_ERROR_BASE - 13,
+
+    /**
+     * The operation is not supported by the camera device.
+     */
+    ACAMERA_ERROR_UNSUPPORTED_OPERATION = ACAMERA_ERROR_BASE - 14,
 } camera_status_t;
 
 #endif /* __ANDROID_API__ >= 24 */
diff --git a/camera/ndk/include/camera/NdkCameraManager.h b/camera/ndk/include/camera/NdkCameraManager.h
index e5b3ad8..2cc8a97 100644
--- a/camera/ndk/include/camera/NdkCameraManager.h
+++ b/camera/ndk/include/camera/NdkCameraManager.h
@@ -65,20 +65,14 @@
  * @return a {@link ACameraManager} instance.
  *
  */
-ACameraManager* ACameraManager_create();
+ACameraManager* ACameraManager_create() __INTRODUCED_IN(24);
 
 /**
  * <p>Delete the {@link ACameraManager} instance and free its resources. </p>
  *
  * @param manager the {@link ACameraManager} instance to be deleted.
  */
-void ACameraManager_delete(ACameraManager* manager);
-
-/// Struct to hold list of camera devices
-typedef struct ACameraIdList {
-    int numCameras;          ///< Number of connected camera devices
-    const char** cameraIds;  ///< list of identifier of connected camera devices
-} ACameraIdList;
+void ACameraManager_delete(ACameraManager* manager) __INTRODUCED_IN(24);
 
 /**
  * Create a list of currently connected camera devices, including
@@ -91,6 +85,11 @@
  * <p>ACameraManager_getCameraIdList will allocate and return an {@link ACameraIdList}.
  * The caller must call {@link ACameraManager_deleteCameraIdList} to free the memory</p>
  *
+ * <p>Note: the returned camera list might be a subset to the output of <a href=
+ * "https://developer.android.com/reference/android/hardware/camera2/CameraManager.html#getCameraIdList()">
+ * SDK CameraManager#getCameraIdList API</a> as the NDK API does not support some legacy camera
+ * hardware.</p>
+ *
  * @param manager the {@link ACameraManager} of interest
  * @param cameraIdList the output {@link ACameraIdList} will be filled in here if the method call
  *        succeeds.
@@ -102,14 +101,14 @@
  *         <li>{@link ACAMERA_ERROR_NOT_ENOUGH_MEMORY} if allocating memory fails.</li></ul>
  */
 camera_status_t ACameraManager_getCameraIdList(ACameraManager* manager,
-                                              /*out*/ACameraIdList** cameraIdList);
+        /*out*/ACameraIdList** cameraIdList) __INTRODUCED_IN(24);
 
 /**
  * Delete a list of camera devices allocated via {@link ACameraManager_getCameraIdList}.
  *
  * @param cameraIdList the {@link ACameraIdList} to be deleted.
  */
-void ACameraManager_deleteCameraIdList(ACameraIdList* cameraIdList);
+void ACameraManager_deleteCameraIdList(ACameraIdList* cameraIdList) __INTRODUCED_IN(24);
 
 /**
  * Definition of camera availability callbacks.
@@ -120,7 +119,8 @@
  *                 argument is owned by camera framework and will become invalid immediately after
  *                 this callback returns.
  */
-typedef void (*ACameraManager_AvailabilityCallback)(void* context, const char* cameraId);
+typedef void (*ACameraManager_AvailabilityCallback)(void* context,
+        const char* cameraId);
 
 /**
  * A listener for camera devices becoming available or unavailable to open.
@@ -168,7 +168,8 @@
  *                  {ACameraManager_AvailabilityCallbacks#onCameraUnavailable} is NULL.</li></ul>
  */
 camera_status_t ACameraManager_registerAvailabilityCallback(
-        ACameraManager* manager, const ACameraManager_AvailabilityCallbacks* callback);
+        ACameraManager* manager,
+        const ACameraManager_AvailabilityCallbacks* callback) __INTRODUCED_IN(24);
 
 /**
  * Unregister camera availability callbacks.
@@ -185,7 +186,8 @@
  *                  {ACameraManager_AvailabilityCallbacks#onCameraUnavailable} is NULL.</li></ul>
  */
 camera_status_t ACameraManager_unregisterAvailabilityCallback(
-        ACameraManager* manager, const ACameraManager_AvailabilityCallbacks* callback);
+        ACameraManager* manager,
+        const ACameraManager_AvailabilityCallbacks* callback) __INTRODUCED_IN(24);
 
 /**
  * Query the capabilities of a camera device. These capabilities are
@@ -211,7 +213,7 @@
  */
 camera_status_t ACameraManager_getCameraCharacteristics(
         ACameraManager* manager, const char* cameraId,
-        /*out*/ACameraMetadata** characteristics);
+        /*out*/ACameraMetadata** characteristics) __INTRODUCED_IN(24);
 
 /**
  * Open a connection to a camera with the given ID. The opened camera device will be
@@ -271,10 +273,126 @@
 camera_status_t ACameraManager_openCamera(
         ACameraManager* manager, const char* cameraId,
         ACameraDevice_StateCallbacks* callback,
-        /*out*/ACameraDevice** device);
+        /*out*/ACameraDevice** device) __INTRODUCED_IN(24);
 
 #endif /* __ANDROID_API__ >= 24 */
 
+#if __ANDROID_API__ >= 29
+
+/**
+ * Definition of camera access permission change callback.
+ *
+ * <p>Notification that camera access priorities have changed and the camera may
+ * now be openable. An application that was previously denied camera access due to
+ * a higher-priority user already using the camera, or that was disconnected from an
+ * active camera session due to a higher-priority user trying to open the camera,
+ * should try to open the camera again if it still wants to use it.  Note that
+ * multiple applications may receive this callback at the same time, and only one of
+ * them will succeed in opening the camera in practice, depending on exact access
+ * priority levels and timing. This method is useful in cases where multiple
+ * applications may be in the resumed state at the same time, and the user switches
+ * focus between them, or if the current camera-using application moves between
+ * full-screen and Picture-in-Picture (PiP) states. In such cases, the camera
+ * available/unavailable callbacks will not be invoked, but another application may
+ * now have higher priority for camera access than the current camera-using
+ * application.</p>
+
+ * @param context The optional application context provided by user in
+ *                {@link ACameraManager_AvailabilityListener}.
+ */
+typedef void (*ACameraManager_AccessPrioritiesChangedCallback)(void* context);
+
+/**
+ * A listener for camera devices becoming available/unavailable to open or when
+ * the camera access permissions change.
+ *
+ * <p>Cameras become available when they are no longer in use, or when a new
+ * removable camera is connected. They become unavailable when some
+ * application or service starts using a camera, or when a removable camera
+ * is disconnected.</p>
+ *
+ * @see ACameraManager_registerExtendedAvailabilityCallback
+ */
+typedef struct ACameraManager_ExtendedAvailabilityListener {
+    ///
+    ACameraManager_AvailabilityCallbacks availabilityCallbacks;
+
+    /// Called when there is camera access permission change
+    ACameraManager_AccessPrioritiesChangedCallback onCameraAccessPrioritiesChanged;
+
+    /// Reserved for future use, please ensure that all entries are set to NULL
+    void *reserved[6];
+} ACameraManager_ExtendedAvailabilityCallbacks;
+
+/**
+ * Register camera extended availability callbacks.
+ *
+ * <p>onCameraUnavailable will be called whenever a camera device is opened by any camera API
+ * client. Other camera API clients may still be able to open such a camera device, evicting the
+ * existing client if they have higher priority than the existing client of a camera device.
+ * See {@link ACameraManager_openCamera} for more details.</p>
+ *
+ * <p>The callbacks will be called on a dedicated thread shared among all ACameraManager
+ * instances.</p>
+ *
+ * <p>Since this callback will be registered with the camera service, remember to unregister it
+ * once it is no longer needed; otherwise the callback will continue to receive events
+ * indefinitely and it may prevent other resources from being released. Specifically, the
+ * callbacks will be invoked independently of the general activity lifecycle and independently
+ * of the state of individual ACameraManager instances.</p>
+ *
+ * @param manager the {@link ACameraManager} of interest.
+ * @param callback the {@link ACameraManager_ExtendedAvailabilityCallbacks} to be registered.
+ *
+ * @return <ul>
+ *         <li>{@link ACAMERA_OK} if the method call succeeds.</li>
+ *         <li>{@link ACAMERA_ERROR_INVALID_PARAMETER} if manager or callback is NULL, or
+ *                  {ACameraManager_ExtendedAvailabilityCallbacks#onCameraAccessPrioritiesChanged}
+ *                  or {ACameraManager_AvailabilityCallbacks#onCameraAvailable} or
+ *                  {ACameraManager_AvailabilityCallbacks#onCameraUnavailable} is NULL.</li></ul>
+ */
+camera_status_t ACameraManager_registerExtendedAvailabilityCallback(
+        ACameraManager* manager,
+        const ACameraManager_ExtendedAvailabilityCallbacks* callback) __INTRODUCED_IN(29);
+
+/**
+ * Unregister camera extended availability callbacks.
+ *
+ * <p>Removing a callback that isn't registered has no effect.</p>
+ *
+ * @param manager the {@link ACameraManager} of interest.
+ * @param callback the {@link ACameraManager_ExtendedAvailabilityCallbacks} to be unregistered.
+ *
+ * @return <ul>
+ *         <li>{@link ACAMERA_OK} if the method call succeeds.</li>
+ *         <li>{@link ACAMERA_ERROR_INVALID_PARAMETER} if callback,
+ *                  {ACameraManager_ExtendedAvailabilityCallbacks#onCameraAccessPrioritiesChanged}
+ *                  or {ACameraManager_AvailabilityCallbacks#onCameraAvailable} or
+ *                  {ACameraManager_AvailabilityCallbacks#onCameraUnavailable} is NULL.</li></ul>
+ */
+camera_status_t ACameraManager_unregisterExtendedAvailabilityCallback(
+        ACameraManager* manager,
+        const ACameraManager_ExtendedAvailabilityCallbacks* callback) __INTRODUCED_IN(29);
+
+#ifdef __ANDROID_VNDK__
+/**
+ * Retrieve the tag value, given the tag name and camera id.
+ * This method is device specific since some metadata might be defined by device manufacturers
+ * and might only be accessible for specific cameras.
+ * @param manager The {@link ACameraManager} of interest.
+ * @param cameraId The cameraId, which is used to query camera characteristics.
+ * @param name The name of the tag being queried.
+ * @param tag The output tag assigned by this method.
+ *
+ * @return ACAMERA_OK only if the function call was successful.
+ */
+camera_status_t ACameraManager_getTagFromName(ACameraManager *manager, const char* cameraId,
+        const char *name, /*out*/uint32_t *tag)
+        __INTRODUCED_IN(29);
+#endif
+
+#endif /* __ANDROID_API__ >= 29 */
+
 __END_DECLS
 
 #endif /* _NDK_CAMERA_MANAGER_H */
diff --git a/camera/ndk/include/camera/NdkCameraMetadata.h b/camera/ndk/include/camera/NdkCameraMetadata.h
index f2aec98..9bbfb83 100644
--- a/camera/ndk/include/camera/NdkCameraMetadata.h
+++ b/camera/ndk/include/camera/NdkCameraMetadata.h
@@ -36,6 +36,7 @@
 #ifndef _NDK_CAMERA_METADATA_H
 #define _NDK_CAMERA_METADATA_H
 
+#include <stdint.h>
 #include <sys/cdefs.h>
 
 #include "NdkCameraError.h"
@@ -190,7 +191,8 @@
  *             of input tag value.</li></ul>
  */
 camera_status_t ACameraMetadata_getConstEntry(
-        const ACameraMetadata* metadata, uint32_t tag, /*out*/ACameraMetadata_const_entry* entry);
+        const ACameraMetadata* metadata,
+        uint32_t tag, /*out*/ACameraMetadata_const_entry* entry) __INTRODUCED_IN(24);
 
 /**
  * List all the entry tags in input {@link ACameraMetadata}.
@@ -207,7 +209,8 @@
  *         <li>{@link ACAMERA_ERROR_UNKNOWN} if the method fails for some other reasons.</li></ul>
  */
 camera_status_t ACameraMetadata_getAllTags(
-        const ACameraMetadata* metadata, /*out*/int32_t* numEntries, /*out*/const uint32_t** tags);
+        const ACameraMetadata* metadata,
+        /*out*/int32_t* numEntries, /*out*/const uint32_t** tags) __INTRODUCED_IN(24);
 
 /**
  * Create a copy of input {@link ACameraMetadata}.
@@ -219,17 +222,39 @@
  *
  * @return a valid ACameraMetadata pointer or NULL if the input metadata cannot be copied.
  */
-ACameraMetadata* ACameraMetadata_copy(const ACameraMetadata* src);
+ACameraMetadata* ACameraMetadata_copy(const ACameraMetadata* src) __INTRODUCED_IN(24);
 
 /**
  * Free a {@link ACameraMetadata} structure.
  *
  * @param metadata the {@link ACameraMetadata} to be freed.
  */
-void ACameraMetadata_free(ACameraMetadata* metadata);
+void ACameraMetadata_free(ACameraMetadata* metadata) __INTRODUCED_IN(24);
 
 #endif /* __ANDROID_API__ >= 24 */
 
+#if __ANDROID_API__ >= 29
+
+/**
+ * Helper function to check if a camera is logical multi-camera.
+ *
+ * <p> Check whether a camera device is a logical multi-camera based on its
+ * static metadata. If it is, also returns its physical sub camera Ids.</p>
+ *
+ * @param staticMetadata the static metadata of the camera being checked.
+ * @param numPhysicalCameras returns the number of physical cameras.
+ * @param physicalCameraIds returns the array of physical camera Ids backing this logical
+ *                          camera device. Note that this pointer is only valid
+ *                          during the lifetime of the staticMetadata object.
+ *
+ * @return true if this is a logical multi-camera, false otherwise.
+ */
+bool ACameraMetadata_isLogicalMultiCamera(const ACameraMetadata* staticMetadata,
+        /*out*/size_t* numPhysicalCameras, /*out*/const char* const** physicalCameraIds)
+        __INTRODUCED_IN(29);
+
+#endif /* __ANDROID_API__ >= 29 */
+
 __END_DECLS
 
 #endif /* _NDK_CAMERA_METADATA_H */
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index bee1a46..8dd6e00 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -71,6 +71,8 @@
     ACAMERA_DEPTH,
     ACAMERA_LOGICAL_MULTI_CAMERA,
     ACAMERA_DISTORTION_CORRECTION,
+    ACAMERA_HEIC,
+    ACAMERA_HEIC_INFO,
     ACAMERA_SECTION_COUNT,
 
     ACAMERA_VENDOR = 0x8000
@@ -112,6 +114,8 @@
     ACAMERA_DISTORTION_CORRECTION_START
                                    = ACAMERA_DISTORTION_CORRECTION
                                                                 << 16,
+    ACAMERA_HEIC_START             = ACAMERA_HEIC              << 16,
+    ACAMERA_HEIC_INFO_START        = ACAMERA_HEIC_INFO         << 16,
     ACAMERA_VENDOR_START           = ACAMERA_VENDOR            << 16
 } acamera_metadata_section_start_t;
 
@@ -1912,6 +1916,7 @@
      *   <li>ACaptureRequest</li>
      * </ul></p>
      *
+     * <p>This tag is also used for HEIC image capture.</p>
      */
     ACAMERA_JPEG_GPS_COORDINATES =                              // double[3]
             ACAMERA_JPEG_START,
@@ -1927,6 +1932,7 @@
      *   <li>ACaptureRequest</li>
      * </ul></p>
      *
+     * <p>This tag is also used for HEIC image capture.</p>
      */
     ACAMERA_JPEG_GPS_PROCESSING_METHOD =                        // byte
             ACAMERA_JPEG_START + 1,
@@ -1942,6 +1948,7 @@
      *   <li>ACaptureRequest</li>
      * </ul></p>
      *
+     * <p>This tag is also used for HEIC image capture.</p>
      */
     ACAMERA_JPEG_GPS_TIMESTAMP =                                // int64
             ACAMERA_JPEG_START + 2,
@@ -1986,6 +1993,10 @@
      * </code></pre>
      * <p>For EXTERNAL cameras the sensor orientation will always be set to 0 and the facing will
      * also be set to EXTERNAL. The above code is not relevant in such case.</p>
+     * <p>This tag is also used to describe the orientation of the HEIC image capture, in which
+     * case the rotation is reflected by
+     * <a href="https://developer.android.com/reference/android/media/ExifInterface.html#TAG_ORIENTATION">EXIF orientation flag</a>, and not by
+     * rotating the image data itself.</p>
      *
      * @see ACAMERA_SENSOR_ORIENTATION
      */
@@ -2003,7 +2014,8 @@
      *   <li>ACaptureRequest</li>
      * </ul></p>
      *
-     * <p>85-95 is typical usage range.</p>
+     * <p>85-95 is typical usage range. This tag is also used to describe the quality
+     * of the HEIC image capture.</p>
      */
     ACAMERA_JPEG_QUALITY =                                      // byte
             ACAMERA_JPEG_START + 4,
@@ -2019,6 +2031,7 @@
      *   <li>ACaptureRequest</li>
      * </ul></p>
      *
+     * <p>This tag is also used to describe the quality of the HEIC image capture.</p>
      */
     ACAMERA_JPEG_THUMBNAIL_QUALITY =                            // byte
             ACAMERA_JPEG_START + 5,
@@ -2055,6 +2068,10 @@
      *   orientation is requested. LEGACY device will always report unrotated thumbnail
      *   size.</li>
      * </ul>
+     * <p>The tag is also used as thumbnail size for HEIC image format capture, in which case the
+     * the thumbnail rotation is reflected by
+     * <a href="https://developer.android.com/reference/android/media/ExifInterface.html#TAG_ORIENTATION">EXIF orientation flag</a>, and not by
+     * rotating the thumbnail data itself.</p>
      *
      * @see ACAMERA_JPEG_ORIENTATION
      */
@@ -2088,6 +2105,7 @@
      * and vice versa.</li>
      * <li>All non-<code>(0, 0)</code> sizes will have non-zero widths and heights.</li>
      * </ul>
+     * <p>This list is also used as supported thumbnail sizes for HEIC image format capture.</p>
      *
      * @see ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
      */
@@ -2783,7 +2801,7 @@
      *   {@link AIMAGE_FORMAT_RAW12 RAW12}.</li>
      * <li>Processed (but not-stalling): any non-RAW format without a stall duration.  Typically
      *   {@link AIMAGE_FORMAT_YUV_420_888 YUV_420_888},
-     *   <a href="https://developer.android.com/reference/android/graphics/ImageFormat.html#NV21">NV21</a>, or <a href="https://developer.android.com/reference/android/graphics/ImageFormat.html#YV12">YV12</a>.</li>
+     *   <a href="https://developer.android.com/reference/android/graphics/ImageFormat.html#NV21">NV21</a>, <a href="https://developer.android.com/reference/android/graphics/ImageFormat.html#YV12">YV12</a>, or {@link AIMAGE_FORMAT_Y8 Y8} .</li>
      * </ul>
      *
      * @see ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
@@ -3028,6 +3046,28 @@
      */
     ACAMERA_REQUEST_AVAILABLE_SESSION_KEYS =                    // int32[n]
             ACAMERA_REQUEST_START + 16,
+    /**
+     * <p>A subset of the available request keys that can be overridden for
+     * physical devices backing a logical multi-camera.</p>
+     *
+     * <p>Type: int32[n]</p>
+     *
+     * <p>This tag may appear in:
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul></p>
+     *
+     * <p>This is a subset of ACAMERA_REQUEST_AVAILABLE_REQUEST_KEYS which contains a list
+     * of keys that can be overridden using <a href="https://developer.android.com/reference/CaptureRequest/Builder.html#setPhysicalCameraKey">Builder#setPhysicalCameraKey</a>.
+     * The respective value of such request key can be obtained by calling
+     * <a href="https://developer.android.com/reference/CaptureRequest/Builder.html#getPhysicalCameraKey">Builder#getPhysicalCameraKey</a>. Capture requests that contain
+     * individual physical device requests must be built via
+     * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraDevice.html#createCaptureRequest(int,">Set)</a>.</p>
+     *
+     * @see ACAMERA_REQUEST_AVAILABLE_REQUEST_KEYS
+     */
+    ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS =    // int32[n]
+            ACAMERA_REQUEST_START + 17,
     ACAMERA_REQUEST_END,
 
     /**
@@ -3257,6 +3297,7 @@
      * <li>{@link AIMAGE_FORMAT_YUV_420_888 }</li>
      * <li>{@link AIMAGE_FORMAT_RAW10 }</li>
      * <li>{@link AIMAGE_FORMAT_RAW12 }</li>
+     * <li>{@link AIMAGE_FORMAT_Y8 }</li>
      * </ul>
      * <p>All other formats may or may not have an allowed stall duration on
      * a per-capability basis; refer to ACAMERA_REQUEST_AVAILABLE_CAPABILITIES
@@ -3294,6 +3335,81 @@
      */
     ACAMERA_SCALER_CROPPING_TYPE =                              // byte (acamera_metadata_enum_android_scaler_cropping_type_t)
             ACAMERA_SCALER_START + 13,
+    /**
+     * <p>Recommended stream configurations for common client use cases.</p>
+     *
+     * <p>Type: int32[n*5] (acamera_metadata_enum_android_scaler_available_recommended_stream_configurations_t)</p>
+     *
+     * <p>This tag may appear in:
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul></p>
+     *
+     * <p>Optional subset of the ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS that contains
+     * similar tuples listed as
+     * (i.e. width, height, format, output/input stream, usecase bit field).
+     * Camera devices will be able to suggest particular stream configurations which are
+     * power and performance efficient for specific use cases. For more information about
+     * retrieving the suggestions see
+     * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#getRecommendedStreamConfigurationMap">CameraCharacteristics#getRecommendedStreamConfigurationMap</a>.</p>
+     * <p>The data representation is int[5], which maps to
+     * (width, height, format, output/input stream, usecase bit field). The array can be
+     * parsed using the following pseudo code:</p>
+     * <p>struct StreamConfiguration {
+     * int32_t format;
+     * int32_t width;
+     * int32_t height;
+     * int32_t isInput; };</p>
+     * <p>void getPreferredStreamConfigurations(
+     *     int32_t *array, size_t count, int32_t usecaseId,
+     *     Vector &lt; StreamConfiguration &gt; * scs) {
+     *     const size_t STREAM_CONFIGURATION_SIZE = 5;
+     *     const size_t STREAM_WIDTH_OFFSET = 0;
+     *     const size_t STREAM_HEIGHT_OFFSET = 1;
+     *     const size_t STREAM_FORMAT_OFFSET = 2;
+     *     const size_t STREAM_IS_INPUT_OFFSET = 3;
+     *     const size_t STREAM_USECASE_BITMAP_OFFSET = 4;</p>
+     * <pre><code>for (size_t i = 0; i &lt; count; i+= STREAM_CONFIGURATION_SIZE) {
+     *     int32_t width = array[i + STREAM_WIDTH_OFFSET];
+     *     int32_t height = array[i + STREAM_HEIGHT_OFFSET];
+     *     int32_t format = array[i + STREAM_FORMAT_OFFSET];
+     *     int32_t isInput = array[i + STREAM_IS_INPUT_OFFSET];
+     *     int32_t supportedUsecases = array[i + STREAM_USECASE_BITMAP_OFFSET];
+     *     if (supportedUsecases &amp; (1 &lt;&lt; usecaseId)) {
+     *         StreamConfiguration sc = {format, width, height, isInput};
+     *         scs-&gt;add(sc);
+     *     }
+     * }
+     * </code></pre>
+     * <p>}</p>
+     *
+     * @see ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
+     */
+    ACAMERA_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS = 
+                                                                // int32[n*5] (acamera_metadata_enum_android_scaler_available_recommended_stream_configurations_t)
+            ACAMERA_SCALER_START + 14,
+    /**
+     * <p>Recommended mappings of image formats that are supported by this
+     * camera device for input streams, to their corresponding output formats.</p>
+     *
+     * <p>Type: int32</p>
+     *
+     * <p>This tag may appear in:
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul></p>
+     *
+     * <p>This is a recommended subset of the complete list of mappings found in
+     * android.scaler.availableInputOutputFormatsMap. The same requirements apply here as well.
+     * The list however doesn't need to contain all available and supported mappings. Instead of
+     * this developers must list only recommended and efficient entries.
+     * If set, the information will be available in the ZERO_SHUTTER_LAG recommended stream
+     * configuration see
+     * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#getRecommendedStreamConfigurationMap">CameraCharacteristics#getRecommendedStreamConfigurationMap</a>.</p>
+     */
+    ACAMERA_SCALER_AVAILABLE_RECOMMENDED_INPUT_OUTPUT_FORMATS_MAP = 
+                                                                // int32
+            ACAMERA_SCALER_START + 15,
     ACAMERA_SCALER_END,
 
     /**
@@ -3454,6 +3570,8 @@
      * <p>Some devices may choose to provide a second set of calibration
      * information for improved quality, including
      * ACAMERA_SENSOR_REFERENCE_ILLUMINANT2 and its corresponding matrices.</p>
+     * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+     * the camera device has RAW capability.</p>
      *
      * @see ACAMERA_SENSOR_CALIBRATION_TRANSFORM1
      * @see ACAMERA_SENSOR_COLOR_TRANSFORM1
@@ -3483,6 +3601,8 @@
      * <p>If this key is present, then ACAMERA_SENSOR_COLOR_TRANSFORM2,
      * ACAMERA_SENSOR_CALIBRATION_TRANSFORM2, and
      * ACAMERA_SENSOR_FORWARD_MATRIX2 will also be present.</p>
+     * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+     * the camera device has RAW capability.</p>
      *
      * @see ACAMERA_SENSOR_CALIBRATION_TRANSFORM2
      * @see ACAMERA_SENSOR_COLOR_TRANSFORM2
@@ -3510,6 +3630,8 @@
      * colorspace) into this camera device's native sensor color
      * space under the first reference illuminant
      * (ACAMERA_SENSOR_REFERENCE_ILLUMINANT1).</p>
+     * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+     * the camera device has RAW capability.</p>
      *
      * @see ACAMERA_SENSOR_REFERENCE_ILLUMINANT1
      */
@@ -3537,6 +3659,8 @@
      * (ACAMERA_SENSOR_REFERENCE_ILLUMINANT2).</p>
      * <p>This matrix will only be present if the second reference
      * illuminant is present.</p>
+     * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+     * the camera device has RAW capability.</p>
      *
      * @see ACAMERA_SENSOR_REFERENCE_ILLUMINANT2
      */
@@ -3565,6 +3689,8 @@
      * and the CIE XYZ colorspace when calculating this transform will
      * match the standard white point for the first reference illuminant
      * (i.e. no chromatic adaptation will be applied by this transform).</p>
+     * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+     * the camera device has RAW capability.</p>
      *
      * @see ACAMERA_SENSOR_REFERENCE_ILLUMINANT1
      */
@@ -3595,6 +3721,8 @@
      * (i.e. no chromatic adaptation will be applied by this transform).</p>
      * <p>This matrix will only be present if the second reference
      * illuminant is present.</p>
+     * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+     * the camera device has RAW capability.</p>
      *
      * @see ACAMERA_SENSOR_REFERENCE_ILLUMINANT2
      */
@@ -3621,6 +3749,8 @@
      * this matrix is chosen so that the standard white point for this reference
      * illuminant in the reference sensor colorspace is mapped to D50 in the
      * CIE XYZ colorspace.</p>
+     * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+     * the camera device has RAW capability.</p>
      *
      * @see ACAMERA_SENSOR_REFERENCE_ILLUMINANT1
      */
@@ -3649,6 +3779,8 @@
      * CIE XYZ colorspace.</p>
      * <p>This matrix will only be present if the second reference
      * illuminant is present.</p>
+     * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+     * the camera device has RAW capability.</p>
      *
      * @see ACAMERA_SENSOR_REFERENCE_ILLUMINANT2
      */
@@ -3681,6 +3813,7 @@
      * level values. For raw capture in particular, it is recommended to use
      * pixels from ACAMERA_SENSOR_OPTICAL_BLACK_REGIONS to calculate black
      * level values for each frame.</p>
+     * <p>For a MONOCHROME camera device, all of the 2x2 channels must have the same values.</p>
      *
      * @see ACAMERA_SENSOR_DYNAMIC_BLACK_LEVEL
      * @see ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
@@ -3775,6 +3908,8 @@
      * used to interpolate between the provided color transforms when
      * processing raw sensor data.</p>
      * <p>The order of the values is R, G, B; where R is in the lowest index.</p>
+     * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+     * the camera device has RAW capability.</p>
      */
     ACAMERA_SENSOR_NEUTRAL_COLOR_POINT =                        // rational[3]
             ACAMERA_SENSOR_START + 18,
@@ -3805,6 +3940,8 @@
      * that channel.</p>
      * <p>A more detailed description of the noise model can be found in the
      * Adobe DNG specification for the NoiseProfile tag.</p>
+     * <p>For a MONOCHROME camera, there is only one color channel. So the noise model coefficients
+     * will only contain one S and one O.</p>
      *
      * @see ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
      */
@@ -3850,6 +3987,8 @@
      * <li>R &gt; 1.20 will require strong software correction to produce
      * a usuable image (&gt;20% divergence).</li>
      * </ul>
+     * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+     * the camera device has RAW capability.</p>
      */
     ACAMERA_SENSOR_GREEN_SPLIT =                                // float
             ACAMERA_SENSOR_START + 22,
@@ -4002,6 +4141,7 @@
      * layout key (see ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT), i.e. the
      * nth value given corresponds to the black level offset for the nth
      * color channel listed in the CFA.</p>
+     * <p>For a MONOCHROME camera, all of the 2x2 channels must have the same values.</p>
      * <p>This key will be available if ACAMERA_SENSOR_OPTICAL_BLACK_REGIONS is available or the
      * camera device advertises this key via {@link ACAMERA_REQUEST_AVAILABLE_RESULT_KEYS }.</p>
      *
@@ -4104,7 +4244,8 @@
     /**
      * <p>The arrangement of color filters on sensor;
      * represents the colors in the top-left 2x2 section of
-     * the sensor, in reading order.</p>
+     * the sensor, in reading order, for a Bayer camera, or the
+     * light spectrum it captures for MONOCHROME camera.</p>
      *
      * <p>Type: byte (acamera_metadata_enum_android_sensor_info_color_filter_arrangement_t)</p>
      *
@@ -4573,13 +4714,13 @@
      * (x,y) ϵ (0 ... N-1, 0 ... M-1) is the value of the shading map at
      * pixel ( ((W-1)/(N-1)) * x, ((H-1)/(M-1)) * y) for the four color channels.
      * The map is assumed to be bilinearly interpolated between the sample points.</p>
-     * <p>The channel order is [R, Geven, Godd, B], where Geven is the green
-     * channel for the even rows of a Bayer pattern, and Godd is the odd rows.
+     * <p>For a Bayer camera, the channel order is [R, Geven, Godd, B], where Geven is
+     * the green channel for the even rows of a Bayer pattern, and Godd is the odd rows.
      * The shading map is stored in a fully interleaved format, and its size
      * is provided in the camera static metadata by ACAMERA_LENS_INFO_SHADING_MAP_SIZE.</p>
      * <p>The shading map will generally have on the order of 30-40 rows and columns,
      * and will be smaller than 64x64.</p>
-     * <p>As an example, given a very small map defined as:</p>
+     * <p>As an example, given a very small map for a Bayer camera defined as:</p>
      * <pre><code>ACAMERA_LENS_INFO_SHADING_MAP_SIZE = [ 4, 3 ]
      * ACAMERA_STATISTICS_LENS_SHADING_MAP =
      * [ 1.3, 1.2, 1.15, 1.2,  1.2, 1.2, 1.15, 1.2,
@@ -4599,6 +4740,17 @@
      * image of a gray wall (using bicubic interpolation for visual quality)
      * as captured by the sensor gives:</p>
      * <p><img alt="Image of a uniform white wall (inverse shading map)" src="../images/camera2/metadata/android.statistics.lensShadingMap/inv_shading.png" /></p>
+     * <p>For a MONOCHROME camera, all of the 2x2 channels must have the same values. An example
+     * shading map for such a camera is defined as:</p>
+     * <pre><code>ACAMERA_LENS_INFO_SHADING_MAP_SIZE = [ 4, 3 ]
+     * ACAMERA_STATISTICS_LENS_SHADING_MAP =
+     * [ 1.3, 1.3, 1.3, 1.3,  1.2, 1.2, 1.2, 1.2,
+     *     1.1, 1.1, 1.1, 1.1,  1.3, 1.3, 1.3, 1.3,
+     *   1.2, 1.2, 1.2, 1.2,  1.1, 1.1, 1.1, 1.1,
+     *     1.0, 1.0, 1.0, 1.0,  1.2, 1.2, 1.2, 1.2,
+     *   1.3, 1.3, 1.3, 1.3,   1.2, 1.2, 1.2, 1.2,
+     *     1.2, 1.2, 1.2, 1.2,  1.3, 1.3, 1.3, 1.3 ]
+     * </code></pre>
      * <p>Note that the RAW image data might be subject to lens shading
      * correction not reported on this map. Query
      * ACAMERA_SENSOR_INFO_LENS_SHADING_APPLIED to see if RAW image data has subject
@@ -4942,8 +5094,8 @@
      * of points can be less than max (that is, the request doesn't have to
      * always provide a curve with number of points equivalent to
      * ACAMERA_TONEMAP_MAX_CURVE_POINTS).</p>
-     * <p>For devices with MONOCHROME capability, only red channel is used. Green and blue channels
-     * are ignored.</p>
+     * <p>For devices with MONOCHROME capability, all three channels must have the same set of
+     * control points.</p>
      * <p>A few examples, and their corresponding graphical mappings; these
      * only specify the red channel and the precision is limited to 4
      * digits, for conciseness.</p>
@@ -5417,9 +5569,121 @@
      */
     ACAMERA_DEPTH_DEPTH_IS_EXCLUSIVE =                          // byte (acamera_metadata_enum_android_depth_depth_is_exclusive_t)
             ACAMERA_DEPTH_START + 4,
+    /**
+     * <p>Recommended depth stream configurations for common client use cases.</p>
+     *
+     * <p>Type: int32[n*5]</p>
+     *
+     * <p>This tag may appear in:
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul></p>
+     *
+     * <p>Optional subset of the ACAMERA_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS that
+     * contains similar tuples listed as
+     * (i.e. width, height, format, output/input stream, usecase bit field).
+     * Camera devices will be able to suggest particular depth stream configurations which are
+     * power and performance efficient for specific use cases. For more information about
+     * retrieving the suggestions see
+     * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#getRecommendedStreamConfigurationMap">CameraCharacteristics#getRecommendedStreamConfigurationMap</a>.</p>
+     * <p>For data representation please refer to
+     * ACAMERA_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS</p>
+     *
+     * @see ACAMERA_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS
+     * @see ACAMERA_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS
+     */
+    ACAMERA_DEPTH_AVAILABLE_RECOMMENDED_DEPTH_STREAM_CONFIGURATIONS = 
+                                                                // int32[n*5]
+            ACAMERA_DEPTH_START + 5,
+    /**
+     * <p>The available dynamic depth dataspace stream
+     * configurations that this camera device supports
+     * (i.e. format, width, height, output/input stream).</p>
+     *
+     * <p>Type: int32[n*4] (acamera_metadata_enum_android_depth_available_dynamic_depth_stream_configurations_t)</p>
+     *
+     * <p>This tag may appear in:
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul></p>
+     *
+     * <p>These are output stream configurations for use with
+     * dataSpace DYNAMIC_DEPTH. The configurations are
+     * listed as <code>(format, width, height, input?)</code> tuples.</p>
+     * <p>Only devices that support depth output for at least
+     * the HAL_PIXEL_FORMAT_Y16 dense depth map along with
+     * HAL_PIXEL_FORMAT_BLOB with the same size or size with
+     * the same aspect ratio can have dynamic depth dataspace
+     * stream configuration. ACAMERA_DEPTH_DEPTH_IS_EXCLUSIVE also
+     * needs to be set to FALSE.</p>
+     *
+     * @see ACAMERA_DEPTH_DEPTH_IS_EXCLUSIVE
+     */
+    ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS = 
+                                                                // int32[n*4] (acamera_metadata_enum_android_depth_available_dynamic_depth_stream_configurations_t)
+            ACAMERA_DEPTH_START + 6,
+    /**
+     * <p>This lists the minimum frame duration for each
+     * format/size combination for dynamic depth output streams.</p>
+     *
+     * <p>Type: int64[4*n]</p>
+     *
+     * <p>This tag may appear in:
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul></p>
+     *
+     * <p>This should correspond to the frame duration when only that
+     * stream is active, with all processing (typically in android.*.mode)
+     * set to either OFF or FAST.</p>
+     * <p>When multiple streams are used in a request, the minimum frame
+     * duration will be max(individual stream min durations).</p>
+     * <p>The minimum frame duration of a stream (of a particular format, size)
+     * is the same regardless of whether the stream is input or output.</p>
+     */
+    ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS = // int64[4*n]
+            ACAMERA_DEPTH_START + 7,
+    /**
+     * <p>This lists the maximum stall duration for each
+     * output format/size combination for dynamic depth streams.</p>
+     *
+     * <p>Type: int64[4*n]</p>
+     *
+     * <p>This tag may appear in:
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul></p>
+     *
+     * <p>A stall duration is how much extra time would get added
+     * to the normal minimum frame duration for a repeating request
+     * that has streams with non-zero stall.</p>
+     * <p>All dynamic depth output streams may have a nonzero stall
+     * duration.</p>
+     */
+    ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS =     // int64[4*n]
+            ACAMERA_DEPTH_START + 8,
     ACAMERA_DEPTH_END,
 
     /**
+     * <p>String containing the ids of the underlying physical cameras.</p>
+     *
+     * <p>Type: byte[n]</p>
+     *
+     * <p>This tag may appear in:
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul></p>
+     *
+     * <p>For a logical camera, this is concatenation of all underlying physical camera IDs.
+     * The null terminator for physical camera ID must be preserved so that the whole string
+     * can be tokenized using '\0' to generate list of physical camera IDs.</p>
+     * <p>For example, if the physical camera IDs of the logical camera are "2" and "3", the
+     * value of this tag will be ['2', '\0', '3', '\0'].</p>
+     * <p>The number of physical camera IDs must be no less than 2.</p>
+     */
+    ACAMERA_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS =                 // byte[n]
+            ACAMERA_LOGICAL_MULTI_CAMERA_START,
+    /**
      * <p>The accuracy of frame timestamp synchronization between physical cameras</p>
      *
      * <p>Type: byte (acamera_metadata_enum_android_logical_multi_camera_sensor_sync_type_t)</p>
@@ -5437,9 +5701,37 @@
      * <p>In both cases, all images generated for a particular capture request still carry the same
      * timestamps, so that they can be used to look up the matching frame number and
      * onCaptureStarted callback.</p>
+     * <p>This tag is only applicable if the logical camera device supports concurrent physical
+     * streams from different physical cameras.</p>
      */
     ACAMERA_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE =             // byte (acamera_metadata_enum_android_logical_multi_camera_sensor_sync_type_t)
             ACAMERA_LOGICAL_MULTI_CAMERA_START + 1,
+    /**
+     * <p>String containing the ID of the underlying active physical camera.</p>
+     *
+     * <p>Type: byte</p>
+     *
+     * <p>This tag may appear in:
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul></p>
+     *
+     * <p>The ID of the active physical camera that's backing the logical camera. All camera
+     * streams and metadata that are not physical camera specific will be originating from this
+     * physical camera.</p>
+     * <p>For a logical camera made up of physical cameras where each camera's lenses have
+     * different characteristics, the camera device may choose to switch between the physical
+     * cameras when application changes FOCAL_LENGTH or SCALER_CROP_REGION.
+     * At the time of lens switch, this result metadata reflects the new active physical camera
+     * ID.</p>
+     * <p>This key will be available if the camera device advertises this key via {@link ACAMERA_REQUEST_AVAILABLE_RESULT_KEYS }.
+     * When available, this must be one of valid physical IDs backing this logical multi-camera.
+     * If this key is not available for a logical multi-camera, the camera device implementation
+     * may still switch between different active physical cameras based on use case, but the
+     * current active physical camera information won't be available to the application.</p>
+     */
+    ACAMERA_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID =           // byte
+            ACAMERA_LOGICAL_MULTI_CAMERA_START + 2,
     ACAMERA_LOGICAL_MULTI_CAMERA_END,
 
     /**
@@ -5463,8 +5755,8 @@
      * will not slow down capture rate when applying correction. FAST may be the same as OFF if
      * any correction at all would slow down capture rate.  Every output stream will have a
      * similar amount of enhancement applied.</p>
-     * <p>The correction only applies to processed outputs such as YUV, JPEG, or DEPTH16; it is not
-     * applied to any RAW output.</p>
+     * <p>The correction only applies to processed outputs such as YUV, Y8, JPEG, or DEPTH16; it is
+     * not applied to any RAW output.</p>
      * <p>This control will be on by default on devices that support this control. Applications
      * disabling distortion correction need to pay extra attention with the coordinate system of
      * metering regions, crop region, and face rectangles. When distortion correction is OFF,
@@ -5517,6 +5809,80 @@
             ACAMERA_DISTORTION_CORRECTION_START + 1,
     ACAMERA_DISTORTION_CORRECTION_END,
 
+    /**
+     * <p>The available HEIC (ISO/IEC 23008-12) stream
+     * configurations that this camera device supports
+     * (i.e. format, width, height, output/input stream).</p>
+     *
+     * <p>Type: int32[n*4] (acamera_metadata_enum_android_heic_available_heic_stream_configurations_t)</p>
+     *
+     * <p>This tag may appear in:
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul></p>
+     *
+     * <p>The configurations are listed as <code>(format, width, height, input?)</code> tuples.</p>
+     * <p>If the camera device supports HEIC image format, it will support identical set of stream
+     * combinations involving HEIC image format, compared to the combinations involving JPEG
+     * image format as required by the device's hardware level and capabilities.</p>
+     * <p>All the static, control, and dynamic metadata tags related to JPEG apply to HEIC formats.
+     * Configuring JPEG and HEIC streams at the same time is not supported.</p>
+     * <p>All the configuration tuples <code>(format, width, height, input?)</code> will contain
+     * AIMAGE_FORMAT_HEIC format as OUTPUT only.</p>
+     */
+    ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS =         // int32[n*4] (acamera_metadata_enum_android_heic_available_heic_stream_configurations_t)
+            ACAMERA_HEIC_START,
+    /**
+     * <p>This lists the minimum frame duration for each
+     * format/size combination for HEIC output formats.</p>
+     *
+     * <p>Type: int64[4*n]</p>
+     *
+     * <p>This tag may appear in:
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul></p>
+     *
+     * <p>This should correspond to the frame duration when only that
+     * stream is active, with all processing (typically in android.*.mode)
+     * set to either OFF or FAST.</p>
+     * <p>When multiple streams are used in a request, the minimum frame
+     * duration will be max(individual stream min durations).</p>
+     * <p>See ACAMERA_SENSOR_FRAME_DURATION and
+     * ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS for more details about
+     * calculating the max frame rate.</p>
+     *
+     * @see ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS
+     * @see ACAMERA_SENSOR_FRAME_DURATION
+     */
+    ACAMERA_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS =           // int64[4*n]
+            ACAMERA_HEIC_START + 1,
+    /**
+     * <p>This lists the maximum stall duration for each
+     * output format/size combination for HEIC streams.</p>
+     *
+     * <p>Type: int64[4*n]</p>
+     *
+     * <p>This tag may appear in:
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul></p>
+     *
+     * <p>A stall duration is how much extra time would get added
+     * to the normal minimum frame duration for a repeating request
+     * that has streams with non-zero stall.</p>
+     * <p>This functions similarly to
+     * ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS for HEIC
+     * streams.</p>
+     * <p>All HEIC output stream formats may have a nonzero stall
+     * duration.</p>
+     *
+     * @see ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS
+     */
+    ACAMERA_HEIC_AVAILABLE_HEIC_STALL_DURATIONS =               // int64[4*n]
+            ACAMERA_HEIC_START + 2,
+    ACAMERA_HEIC_END,
+
 } acamera_metadata_tag_t;
 
 /**
@@ -6333,7 +6699,7 @@
 
     /**
      * <p>Optimized for dim settings where the main light source
-     * is a flame.</p>
+     * is a candle.</p>
      */
     ACAMERA_CONTROL_SCENE_MODE_CANDLELIGHT                           = 15,
 
@@ -7011,6 +7377,10 @@
      * <p>If this is supported, android.scaler.streamConfigurationMap will
      * additionally return a min frame duration that is greater than
      * zero for each supported size-format combination.</p>
+     * <p>For camera devices with LOGICAL_MULTI_CAMERA capability, when the underlying active
+     * physical camera switches, exposureTime, sensitivity, and lens properties may change
+     * even if AE/AF is locked. However, the overall auto exposure and auto focus experience
+     * for users will be consistent. Refer to LOGICAL_MULTI_CAMERA capability for details.</p>
      *
      * @see ACAMERA_BLACK_LEVEL_LOCK
      * @see ACAMERA_CONTROL_AE_LOCK
@@ -7066,6 +7436,10 @@
      * will accurately report the values applied by AWB in the result.</p>
      * <p>A given camera device may also support additional post-processing
      * controls, but this capability only covers the above list of controls.</p>
+     * <p>For camera devices with LOGICAL_MULTI_CAMERA capability, when underlying active
+     * physical camera switches, tonemap, white balance, and shading map may change even if
+     * awb is locked. However, the overall post-processing experience for users will be
+     * consistent. Refer to LOGICAL_MULTI_CAMERA capability for details.</p>
      *
      * @see ACAMERA_COLOR_CORRECTION_ABERRATION_MODE
      * @see ACAMERA_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES
@@ -7137,19 +7511,20 @@
 
     /**
      * <p>The camera device supports capturing high-resolution images at &gt;= 20 frames per
-     * second, in at least the uncompressed YUV format, when post-processing settings are set
-     * to FAST. Additionally, maximum-resolution images can be captured at &gt;= 10 frames
-     * per second.  Here, 'high resolution' means at least 8 megapixels, or the maximum
-     * resolution of the device, whichever is smaller.</p>
+     * second, in at least the uncompressed YUV format, when post-processing settings are
+     * set to FAST. Additionally, all image resolutions less than 24 megapixels can be
+     * captured at &gt;= 10 frames per second. Here, 'high resolution' means at least 8
+     * megapixels, or the maximum resolution of the device, whichever is smaller.</p>
      * <p>More specifically, this means that at least one output {@link AIMAGE_FORMAT_YUV_420_888 } size listed in
      * {@link ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS }
      * is larger or equal to the 'high resolution' defined above, and can be captured at at
      * least 20 fps.  For the largest {@link AIMAGE_FORMAT_YUV_420_888 } size listed in
      * {@link ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS },
-     * camera device can capture this size for at least 10 frames per second.  Also the
-     * ACAMERA_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES entry lists at least one FPS range where
-     * the minimum FPS is &gt;= 1 / minimumFrameDuration for the largest YUV_420_888 size.</p>
-     * <p>If the device supports the {@link AIMAGE_FORMAT_RAW10 }, {@link AIMAGE_FORMAT_RAW12 }, then those can also be
+     * camera device can capture this size for at least 10 frames per second if the size is
+     * less than 24 megapixels. Also the ACAMERA_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES entry
+     * lists at least one FPS range where the minimum FPS is &gt;= 1 / minimumFrameDuration
+     * for the largest YUV_420_888 size.</p>
+     * <p>If the device supports the {@link AIMAGE_FORMAT_RAW10 }, {@link AIMAGE_FORMAT_RAW12 }, {@link AIMAGE_FORMAT_Y8 }, then those can also be
      * captured at the same rate as the maximum-size YUV_420_888 resolution is.</p>
      * <p>In addition, the ACAMERA_SYNC_MAX_LATENCY field is guaranted to have a value between 0
      * and 4, inclusive. ACAMERA_CONTROL_AE_LOCK_AVAILABLE and ACAMERA_CONTROL_AWB_LOCK_AVAILABLE
@@ -7183,8 +7558,8 @@
      * <li>The ACAMERA_DEPTH_DEPTH_IS_EXCLUSIVE entry is listed by this device.</li>
      * <li>As of Android P, the ACAMERA_LENS_POSE_REFERENCE entry is listed by this device.</li>
      * <li>A LIMITED camera with only the DEPTH_OUTPUT capability does not have to support
-     *   normal YUV_420_888, JPEG, and PRIV-format outputs. It only has to support the DEPTH16
-     *   format.</li>
+     *   normal YUV_420_888, Y8, JPEG, and PRIV-format outputs. It only has to support the
+     *   DEPTH16 format.</li>
      * </ul>
      * <p>Generally, depth output operates at a slower frame rate than standard color capture,
      * so the DEPTH16 and DEPTH_POINT_CLOUD formats will commonly have a stall duration that
@@ -7215,8 +7590,23 @@
     ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING           = 10,
 
     /**
-     * <p>The camera device is a logical camera backed by two or more physical cameras that are
-     * also exposed to the application.</p>
+     * <p>The camera device is a logical camera backed by two or more physical cameras.</p>
+     * <p>In API level 28, the physical cameras must also be exposed to the application via
+     * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraManager.html#getCameraIdList">CameraManager#getCameraIdList</a>.</p>
+     * <p>Starting from API level 29, some or all physical cameras may not be independently
+     * exposed to the application, in which case the physical camera IDs will not be
+     * available in <a href="https://developer.android.com/reference/android/hardware/camera2/CameraManager.html#getCameraIdList">CameraManager#getCameraIdList</a>. But the
+     * application can still query the physical cameras' characteristics by calling
+     * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraManager.html#getCameraCharacteristics">CameraManager#getCameraCharacteristics</a>. Additionally,
+     * if a physical camera is hidden from camera ID list, the mandatory stream combinations
+     * for that physical camera must be supported through the logical camera using physical
+     * streams.</p>
+     * <p>Combinations of logical and physical streams, or physical streams from different
+     * physical cameras are not guaranteed. However, if the camera device supports
+     * {@link ACameraDevice_isSessionConfigurationSupported },
+     * application must be able to query whether a stream combination involving physical
+     * streams is supported by calling
+     * {@link ACameraDevice_isSessionConfigurationSupported }.</p>
      * <p>Camera application shouldn't assume that there are at most 1 rear camera and 1 front
      * camera in the system. For an application that switches between front and back cameras,
      * the recommendation is to switch between the first rear camera and the first front
@@ -7239,42 +7629,128 @@
      * </li>
      * <li>The SENSOR_INFO_TIMESTAMP_SOURCE of the logical device and physical devices must be
      *   the same.</li>
-     * <li>The logical camera device must be LIMITED or higher device.</li>
+     * <li>The logical camera must be LIMITED or higher device.</li>
      * </ul>
-     * <p>Both the logical camera device and its underlying physical devices support the
-     * mandatory stream combinations required for their device levels.</p>
-     * <p>Additionally, for each guaranteed stream combination, the logical camera supports:</p>
+     * <p>A logical camera device's dynamic metadata may contain
+     * ACAMERA_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID to notify the application of the current
+     * active physical camera Id. An active physical camera is the physical camera from which
+     * the logical camera's main image data outputs (YUV or RAW) and metadata come from.
+     * In addition, this serves as an indication which physical camera is used to output to
+     * a RAW stream, or in case only physical cameras support RAW, which physical RAW stream
+     * the application should request.</p>
+     * <p>Logical camera's static metadata tags below describe the default active physical
+     * camera. An active physical camera is default if it's used when application directly
+     * uses requests built from a template. All templates will default to the same active
+     * physical camera.</p>
      * <ul>
-     * <li>For each guaranteed stream combination, the logical camera supports replacing one
-     *   logical {@link AIMAGE_FORMAT_YUV_420_888 YUV_420_888}
-     *   or raw stream with two physical streams of the same size and format, each from a
-     *   separate physical camera, given that the size and format are supported by both
-     *   physical cameras.</li>
-     * <li>If the logical camera doesn't advertise RAW capability, but the underlying physical
-     *   cameras do, the logical camera will support guaranteed stream combinations for RAW
-     *   capability, except that the RAW streams will be physical streams, each from a separate
-     *   physical camera. This is usually the case when the physical cameras have different
-     *   sensor sizes.</li>
+     * <li>ACAMERA_SENSOR_INFO_SENSITIVITY_RANGE</li>
+     * <li>ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT</li>
+     * <li>ACAMERA_SENSOR_INFO_EXPOSURE_TIME_RANGE</li>
+     * <li>ACAMERA_SENSOR_INFO_MAX_FRAME_DURATION</li>
+     * <li>ACAMERA_SENSOR_INFO_PHYSICAL_SIZE</li>
+     * <li>ACAMERA_SENSOR_INFO_WHITE_LEVEL</li>
+     * <li>ACAMERA_SENSOR_INFO_LENS_SHADING_APPLIED</li>
+     * <li>ACAMERA_SENSOR_REFERENCE_ILLUMINANT1</li>
+     * <li>ACAMERA_SENSOR_REFERENCE_ILLUMINANT2</li>
+     * <li>ACAMERA_SENSOR_CALIBRATION_TRANSFORM1</li>
+     * <li>ACAMERA_SENSOR_CALIBRATION_TRANSFORM2</li>
+     * <li>ACAMERA_SENSOR_COLOR_TRANSFORM1</li>
+     * <li>ACAMERA_SENSOR_COLOR_TRANSFORM2</li>
+     * <li>ACAMERA_SENSOR_FORWARD_MATRIX1</li>
+     * <li>ACAMERA_SENSOR_FORWARD_MATRIX2</li>
+     * <li>ACAMERA_SENSOR_BLACK_LEVEL_PATTERN</li>
+     * <li>ACAMERA_SENSOR_MAX_ANALOG_SENSITIVITY</li>
+     * <li>ACAMERA_SENSOR_OPTICAL_BLACK_REGIONS</li>
+     * <li>ACAMERA_SENSOR_AVAILABLE_TEST_PATTERN_MODES</li>
+     * <li>ACAMERA_LENS_INFO_HYPERFOCAL_DISTANCE</li>
+     * <li>ACAMERA_LENS_INFO_MINIMUM_FOCUS_DISTANCE</li>
+     * <li>ACAMERA_LENS_INFO_FOCUS_DISTANCE_CALIBRATION</li>
+     * <li>ACAMERA_LENS_POSE_ROTATION</li>
+     * <li>ACAMERA_LENS_POSE_TRANSLATION</li>
+     * <li>ACAMERA_LENS_INTRINSIC_CALIBRATION</li>
+     * <li>ACAMERA_LENS_POSE_REFERENCE</li>
+     * <li>ACAMERA_LENS_DISTORTION</li>
      * </ul>
-     * <p>Using physical streams in place of a logical stream of the same size and format will
-     * not slow down the frame rate of the capture, as long as the minimum frame duration
-     * of the physical and logical streams are the same.</p>
+     * <p>The field of view of all non-RAW physical streams must be the same or as close as
+     * possible to that of non-RAW logical streams. If the requested FOV is outside of the
+     * range supported by the physical camera, the physical stream for that physical camera
+     * will use either the maximum or minimum scaler crop region, depending on which one is
+     * closer to the requested FOV. For example, for a logical camera with wide-tele lens
+     * configuration where the wide lens is the default, if the logical camera's crop region
+     * is set to maximum, the physical stream for the tele lens will be configured to its
+     * maximum crop region. On the other hand, if the logical camera has a normal-wide lens
+     * configuration where the normal lens is the default, when the logical camera's crop
+     * region is set to maximum, the FOV of the logical streams will be that of the normal
+     * lens. The FOV of the physical streams for the wide lens will be the same as the
+     * logical stream, by making the crop region smaller than its active array size to
+     * compensate for the smaller focal length.</p>
+     * <p>Even if the underlying physical cameras have different RAW characteristics (such as
+     * size or CFA pattern), a logical camera can still advertise RAW capability. In this
+     * case, when the application configures a RAW stream, the camera device will make sure
+     * the active physical camera will remain active to ensure consistent RAW output
+     * behavior, and not switch to other physical cameras.</p>
+     * <p>The capture request and result metadata tags required for backward compatible camera
+     * functionalities will be solely based on the logical camera capabiltity. On the other
+     * hand, the use of manual capture controls (sensor or post-processing) with a
+     * logical camera may result in unexpected behavior when the HAL decides to switch
+     * between physical cameras with different characteristics under the hood. For example,
+     * when the application manually sets exposure time and sensitivity while zooming in,
+     * the brightness of the camera images may suddenly change because HAL switches from one
+     * physical camera to the other.</p>
      *
      * @see ACAMERA_LENS_DISTORTION
+     * @see ACAMERA_LENS_INFO_FOCUS_DISTANCE_CALIBRATION
+     * @see ACAMERA_LENS_INFO_HYPERFOCAL_DISTANCE
+     * @see ACAMERA_LENS_INFO_MINIMUM_FOCUS_DISTANCE
      * @see ACAMERA_LENS_INTRINSIC_CALIBRATION
      * @see ACAMERA_LENS_POSE_REFERENCE
      * @see ACAMERA_LENS_POSE_ROTATION
      * @see ACAMERA_LENS_POSE_TRANSLATION
+     * @see ACAMERA_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID
      * @see ACAMERA_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE
+     * @see ACAMERA_SENSOR_AVAILABLE_TEST_PATTERN_MODES
+     * @see ACAMERA_SENSOR_BLACK_LEVEL_PATTERN
+     * @see ACAMERA_SENSOR_CALIBRATION_TRANSFORM1
+     * @see ACAMERA_SENSOR_CALIBRATION_TRANSFORM2
+     * @see ACAMERA_SENSOR_COLOR_TRANSFORM1
+     * @see ACAMERA_SENSOR_COLOR_TRANSFORM2
+     * @see ACAMERA_SENSOR_FORWARD_MATRIX1
+     * @see ACAMERA_SENSOR_FORWARD_MATRIX2
+     * @see ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
+     * @see ACAMERA_SENSOR_INFO_EXPOSURE_TIME_RANGE
+     * @see ACAMERA_SENSOR_INFO_LENS_SHADING_APPLIED
+     * @see ACAMERA_SENSOR_INFO_MAX_FRAME_DURATION
+     * @see ACAMERA_SENSOR_INFO_PHYSICAL_SIZE
+     * @see ACAMERA_SENSOR_INFO_SENSITIVITY_RANGE
+     * @see ACAMERA_SENSOR_INFO_WHITE_LEVEL
+     * @see ACAMERA_SENSOR_MAX_ANALOG_SENSITIVITY
+     * @see ACAMERA_SENSOR_OPTICAL_BLACK_REGIONS
+     * @see ACAMERA_SENSOR_REFERENCE_ILLUMINANT1
+     * @see ACAMERA_SENSOR_REFERENCE_ILLUMINANT2
      */
     ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA      = 11,
 
     /**
      * <p>The camera device is a monochrome camera that doesn't contain a color filter array,
-     * and the pixel values on U and V planes are all 128.</p>
+     * and for YUV_420_888 stream, the pixel values on U and V planes are all 128.</p>
+     * <p>A MONOCHROME camera must support the guaranteed stream combinations required for
+     * its device level and capabilities. Additionally, if the monochrome camera device
+     * supports Y8 format, all mandatory stream combination requirements related to {@link AIMAGE_FORMAT_YUV_420_888 YUV_420_888} apply
+     * to {@link AIMAGE_FORMAT_Y8 Y8} as well. There are no
+     * mandatory stream combination requirements with regard to
+     * {@link AIMAGE_FORMAT_Y8 Y8} for Bayer camera devices.</p>
+     * <p>Starting from Android Q, the SENSOR_INFO_COLOR_FILTER_ARRANGEMENT of a MONOCHROME
+     * camera will be either MONO or NIR.</p>
      */
     ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME                = 12,
 
+    /**
+     * <p>The camera device is capable of writing image data into a region of memory
+     * inaccessible to Android userspace or the Android kernel, and only accessible to
+     * trusted execution environments (TEE).</p>
+     */
+    ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA         = 13,
+
 } acamera_metadata_enum_android_request_available_capabilities_t;
 
 
@@ -7300,6 +7776,81 @@
 
 } acamera_metadata_enum_android_scaler_cropping_type_t;
 
+// ACAMERA_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS
+typedef enum acamera_metadata_enum_acamera_scaler_available_recommended_stream_configurations {
+    /**
+     * <p>Preview must only include non-stalling processed stream configurations with
+     * output formats like
+     * {@link AIMAGE_FORMAT_YUV_420_888 },
+     * {@link AIMAGE_FORMAT_PRIVATE }, etc.</p>
+     */
+    ACAMERA_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PREVIEW
+                                                                      = 0x0,
+
+    /**
+     * <p>Video record must include stream configurations that match the advertised
+     * supported media profiles <a href="https://developer.android.com/reference/android/media/CamcorderProfile.html">CamcorderProfile</a> with
+     * IMPLEMENTATION_DEFINED format.</p>
+     */
+    ACAMERA_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_RECORD
+                                                                      = 0x1,
+
+    /**
+     * <p>Video snapshot must include stream configurations at least as big as
+     * the maximum RECORD resolutions and only with
+     * {@link AIMAGE_FORMAT_JPEG JPEG output format}.
+     * Additionally the configurations shouldn't cause preview glitches and also be able to
+     * run at 30 fps.</p>
+     */
+    ACAMERA_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VIDEO_SNAPSHOT
+                                                                      = 0x2,
+
+    /**
+     * <p>Recommended snapshot stream configurations must include at least one with
+     * size close to ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE and
+     * {@link AIMAGE_FORMAT_JPEG JPEG output format}.
+     * Taking into account restrictions on aspect ratio, alignment etc. the area of the
+     * maximum suggested size shouldn’t be less than 97% of the sensor array size area.</p>
+     *
+     * @see ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     */
+    ACAMERA_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_SNAPSHOT
+                                                                      = 0x3,
+
+    /**
+     * <p>If supported, recommended input stream configurations must only be advertised with
+     * ZSL along with other processed and/or stalling output formats.</p>
+     */
+    ACAMERA_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_ZSL   = 0x4,
+
+    /**
+     * <p>If supported, recommended raw stream configurations must only include RAW based
+     * output formats.</p>
+     */
+    ACAMERA_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_RAW   = 0x5,
+
+    /**
+     * <p>If supported, the recommended low latency stream configurations must have
+     * end-to-end latency that does not exceed 200 ms. under standard operating conditions
+     * (reasonable light levels, not loaded system) and using template
+     * TEMPLATE_STILL_CAPTURE. This is primarily for listing configurations for the
+     * {@link AIMAGE_FORMAT_JPEG JPEG output format}
+     * however other supported output formats can be added as well.</p>
+     */
+    ACAMERA_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_LOW_LATENCY_SNAPSHOT
+                                                                      = 0x6,
+
+    ACAMERA_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END
+                                                                      = 0x7,
+
+    /**
+     * <p>Vendor defined use cases. These depend on the vendor implementation.</p>
+     */
+    ACAMERA_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VENDOR_START
+                                                                      = 0x18,
+
+} acamera_metadata_enum_android_scaler_available_recommended_stream_configurations_t;
+
 
 // ACAMERA_SENSOR_REFERENCE_ILLUMINANT1
 typedef enum acamera_metadata_enum_acamera_sensor_reference_illuminant1 {
@@ -7476,6 +8027,21 @@
      */
     ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB                 = 4,
 
+    /**
+     * <p>Sensor doesn't have any Bayer color filter.
+     * Such sensor captures visible light in monochrome. The exact weighting and
+     * wavelengths captured is not specified, but generally only includes the visible
+     * frequencies. This value implies a MONOCHROME camera.</p>
+     */
+    ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO                = 5,
+
+    /**
+     * <p>Sensor has a near infrared filter capturing light with wavelength between
+     * roughly 750nm and 1400nm, and the same filter covers the whole sensor array. This
+     * value implies a MONOCHROME camera.</p>
+     */
+    ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR                 = 6,
+
 } acamera_metadata_enum_android_sensor_info_color_filter_arrangement_t;
 
 // ACAMERA_SENSOR_INFO_TIMESTAMP_SOURCE
@@ -7764,6 +8330,7 @@
      * fire the flash for flash power metering during precapture, and then fire the flash
      * for the final capture, if a flash is available on the device and the AE mode is set to
      * enable the flash.</p>
+     * <p>Devices that initially shipped with Android version <a href="https://developer.android.com/reference/android/os/Build/VERSION_CODES.html#Q">Q</a> or newer will not include any LEGACY-level devices.</p>
      *
      * @see ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER
      * @see ACAMERA_REQUEST_AVAILABLE_CAPABILITIES
@@ -7904,6 +8471,16 @@
 
 } acamera_metadata_enum_android_depth_depth_is_exclusive_t;
 
+// ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS
+typedef enum acamera_metadata_enum_acamera_depth_available_dynamic_depth_stream_configurations {
+    ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_OUTPUT
+                                                                      = 0,
+
+    ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_INPUT
+                                                                      = 1,
+
+} acamera_metadata_enum_android_depth_available_dynamic_depth_stream_configurations_t;
+
 
 // ACAMERA_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE
 typedef enum acamera_metadata_enum_acamera_logical_multi_camera_sensor_sync_type {
@@ -7947,6 +8524,16 @@
 } acamera_metadata_enum_android_distortion_correction_mode_t;
 
 
+// ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS
+typedef enum acamera_metadata_enum_acamera_heic_available_heic_stream_configurations {
+    ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_OUTPUT         = 0,
+
+    ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_INPUT          = 1,
+
+} acamera_metadata_enum_android_heic_available_heic_stream_configurations_t;
+
+
+
 #endif /* __ANDROID_API__ >= 24 */
 
 __END_DECLS
diff --git a/camera/ndk/include/camera/NdkCameraWindowType.h b/camera/ndk/include/camera/NdkCameraWindowType.h
new file mode 100644
index 0000000..99f67e9
--- /dev/null
+++ b/camera/ndk/include/camera/NdkCameraWindowType.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _NDK_CAMERA_WINDOW_TYPE_H
+#define _NDK_CAMERA_WINDOW_TYPE_H
+
+/**
+ * @addtogroup Camera
+ * @{
+ */
+
+/**
+ * @file NdkCameraWindowType.h
+ */
+
+/*
+ * This file defines an NDK API.
+ * Do not remove methods.
+ * Do not change method signatures.
+ * Do not change the value of constants.
+ * Do not change the size of any of the classes defined in here.
+ * Do not reference types that are not part of the NDK.
+ * Do not #include files that aren't part of the NDK.
+ */
+
+/**
+ * This file defines the window type used by NDK and the VNDK variants of the
+ * camera2 NDK. This enables us to share the api definition headers and avoid
+ * code duplication (since the VNDK variant doesn't use ANativeWindow unlike the
+ * NDK variant).
+ */
+#ifdef __ANDROID_VNDK__
+#include <cutils/native_handle.h>
+typedef native_handle_t ACameraWindowType;
+#else
+#include <android/native_window.h>
+typedef ANativeWindow ACameraWindowType;
+#endif
+
+#endif //_NDK_CAMERA_WINDOW_TYPE_H
diff --git a/camera/ndk/include/camera/NdkCaptureRequest.h b/camera/ndk/include/camera/NdkCaptureRequest.h
index 4961ce3..d3f8826 100644
--- a/camera/ndk/include/camera/NdkCaptureRequest.h
+++ b/camera/ndk/include/camera/NdkCaptureRequest.h
@@ -35,9 +35,9 @@
 
 #include <sys/cdefs.h>
 
-#include <android/native_window.h>
 #include "NdkCameraError.h"
 #include "NdkCameraMetadata.h"
+#include "NdkCameraWindowType.h"
 
 #ifndef _NDK_CAPTURE_REQUEST_H
 #define _NDK_CAPTURE_REQUEST_H
@@ -101,7 +101,8 @@
  *
  * @see ACaptureRequest_addTarget
  */
-camera_status_t ACameraOutputTarget_create(ANativeWindow* window, ACameraOutputTarget** output);
+camera_status_t ACameraOutputTarget_create(ACameraWindowType* window,
+        ACameraOutputTarget** output) __INTRODUCED_IN(24);
 
 /**
  * Free a ACameraOutputTarget object.
@@ -110,7 +111,7 @@
  *
  * @see ACameraOutputTarget_create
  */
-void ACameraOutputTarget_free(ACameraOutputTarget* output);
+void ACameraOutputTarget_free(ACameraOutputTarget* output) __INTRODUCED_IN(24);
 
 /**
  * Add an {@link ACameraOutputTarget} object to {@link ACaptureRequest}.
@@ -123,7 +124,7 @@
  *         <li>{@link ACAMERA_ERROR_INVALID_PARAMETER} if request or output is NULL.</li></ul>
  */
 camera_status_t ACaptureRequest_addTarget(ACaptureRequest* request,
-        const ACameraOutputTarget* output);
+        const ACameraOutputTarget* output) __INTRODUCED_IN(24);
 
 /**
  * Remove an {@link ACameraOutputTarget} object from {@link ACaptureRequest}.
@@ -138,7 +139,7 @@
  *         <li>{@link ACAMERA_ERROR_INVALID_PARAMETER} if request or output is NULL.</li></ul>
  */
 camera_status_t ACaptureRequest_removeTarget(ACaptureRequest* request,
-        const ACameraOutputTarget* output);
+        const ACameraOutputTarget* output) __INTRODUCED_IN(24);
 
 /**
  * Get a metadata entry from input {@link ACaptureRequest}.
@@ -158,7 +159,7 @@
  *             entry of input tag value.</li></ul>
  */
 camera_status_t ACaptureRequest_getConstEntry(
-        const ACaptureRequest* request, uint32_t tag, ACameraMetadata_const_entry* entry);
+        const ACaptureRequest* request, uint32_t tag, ACameraMetadata_const_entry* entry) __INTRODUCED_IN(24);
 
 /*
  * List all the entry tags in input {@link ACaptureRequest}.
@@ -179,7 +180,7 @@
  *         <li>{@link ACAMERA_ERROR_UNKNOWN} if the method fails for some other reasons.</li></ul>
  */
 camera_status_t ACaptureRequest_getAllTags(
-        const ACaptureRequest* request, /*out*/int32_t* numTags, /*out*/const uint32_t** tags);
+        const ACaptureRequest* request, /*out*/int32_t* numTags, /*out*/const uint32_t** tags) __INTRODUCED_IN(24);
 
 /**
  * Set/change a camera capture control entry with unsigned 8 bits data type.
@@ -198,7 +199,7 @@
  *             the tag is not controllable by application.</li></ul>
  */
 camera_status_t ACaptureRequest_setEntry_u8(
-        ACaptureRequest* request, uint32_t tag, uint32_t count, const uint8_t* data);
+        ACaptureRequest* request, uint32_t tag, uint32_t count, const uint8_t* data) __INTRODUCED_IN(24);
 
 /**
  * Set/change a camera capture control entry with signed 32 bits data type.
@@ -217,7 +218,7 @@
  *             the tag is not controllable by application.</li></ul>
  */
 camera_status_t ACaptureRequest_setEntry_i32(
-        ACaptureRequest* request, uint32_t tag, uint32_t count, const int32_t* data);
+        ACaptureRequest* request, uint32_t tag, uint32_t count, const int32_t* data) __INTRODUCED_IN(24);
 
 /**
  * Set/change a camera capture control entry with float data type.
@@ -236,7 +237,7 @@
  *             the tag is not controllable by application.</li></ul>
  */
 camera_status_t ACaptureRequest_setEntry_float(
-        ACaptureRequest* request, uint32_t tag, uint32_t count, const float* data);
+        ACaptureRequest* request, uint32_t tag, uint32_t count, const float* data) __INTRODUCED_IN(24);
 
 /**
  * Set/change a camera capture control entry with signed 64 bits data type.
@@ -255,7 +256,7 @@
  *             the tag is not controllable by application.</li></ul>
  */
 camera_status_t ACaptureRequest_setEntry_i64(
-        ACaptureRequest* request, uint32_t tag, uint32_t count, const int64_t* data);
+        ACaptureRequest* request, uint32_t tag, uint32_t count, const int64_t* data) __INTRODUCED_IN(24);
 
 /**
  * Set/change a camera capture control entry with double data type.
@@ -274,7 +275,7 @@
  *             the tag is not controllable by application.</li></ul>
  */
 camera_status_t ACaptureRequest_setEntry_double(
-        ACaptureRequest* request, uint32_t tag, uint32_t count, const double* data);
+        ACaptureRequest* request, uint32_t tag, uint32_t count, const double* data) __INTRODUCED_IN(24);
 
 /**
  * Set/change a camera capture control entry with rational data type.
@@ -294,14 +295,14 @@
  */
 camera_status_t ACaptureRequest_setEntry_rational(
         ACaptureRequest* request, uint32_t tag, uint32_t count,
-        const ACameraMetadata_rational* data);
+        const ACameraMetadata_rational* data) __INTRODUCED_IN(24);
 
 /**
  * Free a {@link ACaptureRequest} structure.
  *
  * @param request the {@link ACaptureRequest} to be freed.
  */
-void ACaptureRequest_free(ACaptureRequest* request);
+void ACaptureRequest_free(ACaptureRequest* request) __INTRODUCED_IN(24);
 
 #endif /* __ANDROID_API__ >= 24 */
 
@@ -325,7 +326,7 @@
  *         <li>{@link ACAMERA_ERROR_INVALID_PARAMETER} if request is NULL.</li></ul>
  */
 camera_status_t ACaptureRequest_setUserContext(
-        ACaptureRequest* request, void* context);
+        ACaptureRequest* request, void* context) __INTRODUCED_IN(28);
 
 /**
  * Get the user context pointer of the {@link ACaptureRequest}
@@ -341,7 +342,7 @@
  *         <li>{@link ACAMERA_ERROR_INVALID_PARAMETER} if request is NULL.</li></ul>
  */
 camera_status_t ACaptureRequest_getUserContext(
-        const ACaptureRequest* request, /*out*/void** context);
+        const ACaptureRequest* request, /*out*/void** context) __INTRODUCED_IN(28);
 
 /**
  * Create a copy of input {@link ACaptureRequest}.
@@ -353,10 +354,223 @@
  *
  * @return a valid ACaptureRequest pointer or NULL if the input request cannot be copied.
  */
-ACaptureRequest* ACaptureRequest_copy(const ACaptureRequest* src);
+ACaptureRequest* ACaptureRequest_copy(const ACaptureRequest* src) __INTRODUCED_IN(28);
 
 #endif /* __ANDROID_API__ >= 28 */
 
+#if __ANDROID_API__ >= 29
+
+/**
+ * Get a metadata entry from input {@link ACaptureRequest} for
+ * a physical camera backing a logical multi-camera device.
+ *
+ * <p>Same as ACaptureRequest_getConstEntry, except that if the key is contained
+ * in {@link ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS}, this function
+ * returns the entry set by ACaptureRequest_setEntry_physicalCamera_* class of
+ * functions on the particular physical camera.</p>
+ *
+ * @param request the {@link ACaptureRequest} of interest created by
+ *                {@link ACameraDevice_createCaptureRequest_withPhysicalIds}.
+ * @param physicalId one of the physical Ids used when request is created with
+ *                   {@link ACameraDevice_createCaptureRequest_withPhysicalIds}.
+ * @param tag the capture request metadata tag in
+ *            {@link ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS}
+ *            that is set by ACaptureRequest_setEntry_physicalCamera_* class of functions.
+ *
+ * @return <ul>
+ *         <li>{@link ACAMERA_OK} if the method call succeeds.</li>
+ *         <li>{@link ACAMERA_ERROR_INVALID_PARAMETER} if metadata, physicalId, or entry is NULL,
+ *         physicalId is not one of the Ids used in creating the request, or if the capture
+ *         request is a regular request with no physical Ids at all.</li>
+ *         <li>{@link ACAMERA_ERROR_METADATA_NOT_FOUND} if the capture request does not contain an
+ *             entry of input tag value.</li></ul>
+ */
+camera_status_t ACaptureRequest_getConstEntry_physicalCamera(
+        const ACaptureRequest* request, const char* physicalId, uint32_t tag,
+        ACameraMetadata_const_entry* entry) __INTRODUCED_IN(29);
+
+/**
+ * Set/change a camera capture control entry with unsigned 8 bits data type for
+ * a physical camera backing a logical multi-camera device.
+ *
+ * <p>Same as ACaptureRequest_setEntry_u8, except that if {@link tag} is contained
+ * in {@link ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS}, this function
+ * sets the entry for a particular physical sub-camera backing the logical multi-camera.
+ * If {@link tag} is not contained in
+ * {@link ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS}, the key will be ignored
+ * by the camera device.</p>
+ *
+ * @param request the {@link ACaptureRequest} of interest created by
+ *                {@link ACameraDevice_createCaptureRequest_withPhysicalIds}.
+ * @param physicalId one of the physical Ids used when request is created with
+ *                   {@link ACameraDevice_createCaptureRequest_withPhysicalIds}.
+ * @param tag one of the capture request metadata tags in
+ *            {@link ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS}.
+ *
+ * @return <ul>
+ *         <li>{@link ACAMERA_OK} if the method call succeeds.</li>
+ *         <li>{@link ACAMERA_ERROR_INVALID_PARAMETER} if request or physicalId is NULL, count is
+ *             larger than zero while data is NULL, the data type of the tag is not unsigned 8 bits,
+ *             the tag is not controllable by application, physicalId is not one of the Ids used
+ *             in creating the request, or if the capture request is a regular request with no
+ *             physical Ids at all.</li></ul>
+ */
+camera_status_t ACaptureRequest_setEntry_physicalCamera_u8(
+        ACaptureRequest* request, const char* physicalId, uint32_t tag,
+        uint32_t count, const uint8_t* data) __INTRODUCED_IN(29);
+
+/**
+ * Set/change a camera capture control entry with signed 32 bits data type for
+ * a physical camera of a logical multi-camera device.
+ *
+ * <p>Same as ACaptureRequest_setEntry_i32, except that if {@link tag} is contained
+ * in {@link ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS}, this function
+ * sets the entry for a particular physical sub-camera backing the logical multi-camera.
+ * If {@link tag} is not contained in
+ * {@link ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS}, the key will be ignored
+ * by the camera device.</p>
+ *
+ * @param request the {@link ACaptureRequest} of interest created by
+ *                {@link ACameraDevice_createCaptureRequest_withPhysicalIds}.
+ * @param physicalId one of the physical Ids used when request is created with
+ *                   {@link ACameraDevice_createCaptureRequest_withPhysicalIds}.
+ * @param tag one of the capture request metadata tags in
+ *            {@link ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS}.
+ *
+ * @return <ul>
+ *         <li>{@link ACAMERA_OK} if the method call succeeds.</li>
+ *         <li>{@link ACAMERA_ERROR_INVALID_PARAMETER} if request or physicalId is NULL, count is
+ *             larger than zero while data is NULL, the data type of the tag is not signed 32 bits,
+ *             the tag is not controllable by application, physicalId is not one of the Ids used
+ *             in creating the request, or if the capture request is a regular request with no
+ *             physical Ids at all.</li></ul>
+ */
+camera_status_t ACaptureRequest_setEntry_physicalCamera_i32(
+        ACaptureRequest* request, const char* physicalId, uint32_t tag,
+        uint32_t count, const int32_t* data) __INTRODUCED_IN(29);
+
+/**
+ * Set/change a camera capture control entry with float data type for
+ * a physical camera of a logical multi-camera device.
+ *
+ * <p>Same as ACaptureRequest_setEntry_float, except that if {@link tag} is contained
+ * in {@link ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS}, this function
+ * sets the entry for a particular physical sub-camera backing the logical multi-camera.
+ * If {@link tag} is not contained in
+ * {@link ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS}, the key will be ignored
+ * by the camera device.</p>
+ *
+ * @param request the {@link ACaptureRequest} of interest created by
+ *                {@link ACameraDevice_createCaptureRequest_withPhysicalIds}.
+ * @param physicalId one of the physical Ids used when request is created with
+ *                   {@link ACameraDevice_createCaptureRequest_withPhysicalIds}.
+ * @param tag one of the capture request metadata tags in
+ *            {@link ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS}.
+ *
+ * @return <ul>
+ *         <li>{@link ACAMERA_OK} if the method call succeeds.</li>
+ *         <li>{@link ACAMERA_ERROR_INVALID_PARAMETER} if request or physicalId is NULL, count is
+ *             larger than zero while data is NULL, the data type of the tag is not float,
+ *             the tag is not controllable by application, physicalId is not one of the Ids used
+ *             in creating the request, or if the capture request is a regular request with no
+ *             physical Ids at all.</li></ul>
+ */
+camera_status_t ACaptureRequest_setEntry_physicalCamera_float(
+        ACaptureRequest* request, const char* physicalId, uint32_t tag,
+        uint32_t count, const float* data) __INTRODUCED_IN(29);
+
+/**
+ * Set/change a camera capture control entry with signed 64 bits data type for
+ * a physical camera of a logical multi-camera device.
+ *
+ * <p>Same as ACaptureRequest_setEntry_i64, except that if {@link tag} is contained
+ * in {@link ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS}, this function
+ * sets the entry for a particular physical sub-camera backing the logical multi-camera.
+ * If {@link tag} is not contained in
+ * {@link ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS}, the key will be ignored
+ * by the camera device.</p>
+ *
+ * @param request the {@link ACaptureRequest} of interest created by
+ *                {@link ACameraDevice_createCaptureRequest_withPhysicalIds}.
+ * @param physicalId one of the physical Ids used when request is created with
+ *                   {@link ACameraDevice_createCaptureRequest_withPhysicalIds}.
+ * @param tag one of the capture request metadata tags in
+ *            {@link ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS}.
+ *
+ * @return <ul>
+ *         <li>{@link ACAMERA_OK} if the method call succeeds.</li>
+ *         <li>{@link ACAMERA_ERROR_INVALID_PARAMETER} if request or physicalId is NULL, count is
+ *             larger than zero while data is NULL, the data type of the tag is not signed 64 bits,
+ *             the tag is not controllable by application, physicalId is not one of the Ids used
+ *             in creating the request, or if the capture request is a regular request with no
+ *             physical Ids at all.</li></ul>
+ */
+camera_status_t ACaptureRequest_setEntry_physicalCamera_i64(
+        ACaptureRequest* request, const char* physicalId, uint32_t tag,
+        uint32_t count, const int64_t* data) __INTRODUCED_IN(29);
+
+/**
+ * Set/change a camera capture control entry with double data type for
+ * a physical camera of a logical multi-camera device.
+ *
+ * <p>Same as ACaptureRequest_setEntry_double, except that if {@link tag} is contained
+ * in {@link ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS}, this function
+ * sets the entry for a particular physical sub-camera backing the logical multi-camera.
+ * If {@link tag} is not contained in
+ * {@link ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS}, the key will be ignored
+ * by the camera device.</p>
+ *
+ * @param request the {@link ACaptureRequest} of interest created by
+ *                {@link ACameraDevice_createCaptureRequest_withPhysicalIds}.
+ * @param physicalId one of the physical Ids used when request is created with
+ *                   {@link ACameraDevice_createCaptureRequest_withPhysicalIds}.
+ * @param tag one of the capture request metadata tags in
+ *            {@link ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS}.
+ *
+ * @return <ul>
+ *         <li>{@link ACAMERA_OK} if the method call succeeds.</li>
+ *         <li>{@link ACAMERA_ERROR_INVALID_PARAMETER} if request or physicalId is NULL, count is
+ *             larger than zero while data is NULL, the data type of the tag is not double,
+ *             the tag is not controllable by application, physicalId is not one of the Ids used
+ *             in creating the request, or if the capture request is a regular request with no
+ *             physical Ids at all.</li></ul>
+ */
+camera_status_t ACaptureRequest_setEntry_physicalCamera_double(
+        ACaptureRequest* request, const char* physicalId, uint32_t tag,
+        uint32_t count, const double* data) __INTRODUCED_IN(29);
+
+/**
+ * Set/change a camera capture control entry with rational data type for
+ * a physical camera of a logical multi-camera device.
+ *
+ * <p>Same as ACaptureRequest_setEntry_rational, except that if {@link tag} is contained
+ * in {@link ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS}, this function
+ * sets the entry for a particular physical sub-camera backing the logical multi-camera.
+ * If {@link tag} is not contained in
+ * {@link ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS}, the key will be ignored
+ * by the camera device.</p>
+ *
+ * @param request the {@link ACaptureRequest} of interest created by
+ *                {@link ACameraDevice_createCaptureRequest_withPhysicalIds}.
+ * @param physicalId one of the physical Ids used when request is created with
+ *                   {@link ACameraDevice_createCaptureRequest_withPhysicalIds}.
+ * @param tag one of the capture request metadata tags in
+ *            {@link ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS}.
+ *
+ * @return <ul>
+ *         <li>{@link ACAMERA_OK} if the method call succeeds.</li>
+ *         <li>{@link ACAMERA_ERROR_INVALID_PARAMETER} if request or physicalId is NULL, count is
+ *             larger than zero while data is NULL, the data type of the tag is not rational,
+ *             the tag is not controllable by application, physicalId is not one of the Ids used
+ *             in creating the request, or if the capture request is a regular request with no
+ *             physical Ids at all.</li></ul>
+ */
+camera_status_t ACaptureRequest_setEntry_physicalCamera_rational(
+        ACaptureRequest* request, const char* physicalId, uint32_t tag,
+        uint32_t count, const ACameraMetadata_rational* data) __INTRODUCED_IN(29);
+
+#endif /* __ANDROID_API__ >= 29 */
+
 __END_DECLS
 
 #endif /* _NDK_CAPTURE_REQUEST_H */
diff --git a/camera/ndk/libcamera2ndk.map.txt b/camera/ndk/libcamera2ndk.map.txt
index d179aa0..b6f1553 100644
--- a/camera/ndk/libcamera2ndk.map.txt
+++ b/camera/ndk/libcamera2ndk.map.txt
@@ -2,15 +2,19 @@
   global:
     ACameraCaptureSession_abortCaptures;
     ACameraCaptureSession_capture;
+    ACameraCaptureSession_logicalCamera_capture; # introduced=29
     ACameraCaptureSession_close;
     ACameraCaptureSession_getDevice;
     ACameraCaptureSession_setRepeatingRequest;
+    ACameraCaptureSession_logicalCamera_setRepeatingRequest; # introduced=29
     ACameraCaptureSession_stopRepeating;
-    ACameraCaptureSession_updateSharedOutput;
+    ACameraCaptureSession_updateSharedOutput; # introduced=28
     ACameraDevice_close;
     ACameraDevice_createCaptureRequest;
+    ACameraDevice_createCaptureRequest_withPhysicalIds; # introduced=29
     ACameraDevice_createCaptureSession;
-    ACameraDevice_createCaptureSessionWithSessionParameters;
+    ACameraDevice_createCaptureSessionWithSessionParameters; # introduced=28
+    ACameraDevice_isSessionConfigurationSupported; # introduced=29
     ACameraDevice_getId;
     ACameraManager_create;
     ACameraManager_delete;
@@ -20,34 +24,45 @@
     ACameraManager_openCamera;
     ACameraManager_registerAvailabilityCallback;
     ACameraManager_unregisterAvailabilityCallback;
+    ACameraManager_registerExtendedAvailabilityCallback; # introduced=29
+    ACameraManager_unregisterExtendedAvailabilityCallback; # introduced=29
     ACameraMetadata_copy;
     ACameraMetadata_free;
     ACameraMetadata_getAllTags;
     ACameraMetadata_getConstEntry;
+    ACameraMetadata_isLogicalMultiCamera; # introduced=29
     ACameraOutputTarget_create;
     ACameraOutputTarget_free;
     ACaptureRequest_addTarget;
-    ACaptureRequest_copy;
+    ACaptureRequest_copy; # introduced=28
     ACaptureRequest_free;
     ACaptureRequest_getAllTags;
     ACaptureRequest_getConstEntry;
-    ACaptureRequest_getUserContext;
+    ACaptureRequest_getConstEntry_physicalCamera; # introduced=29
+    ACaptureRequest_getUserContext; # introduced=28
     ACaptureRequest_removeTarget;
     ACaptureRequest_setEntry_double;
+    ACaptureRequest_setEntry_physicalCamera_double; # introduced=29
     ACaptureRequest_setEntry_float;
+    ACaptureRequest_setEntry_physicalCamera_float; # introduced=29
     ACaptureRequest_setEntry_i32;
+    ACaptureRequest_setEntry_physicalCamera_i32; # introduced=29
     ACaptureRequest_setEntry_i64;
+    ACaptureRequest_setEntry_physicalCamera_i64; # introduced=29
     ACaptureRequest_setEntry_rational;
+    ACaptureRequest_setEntry_physicalCamera_rational; # introduced=29
     ACaptureRequest_setEntry_u8;
-    ACaptureRequest_setUserContext;
+    ACaptureRequest_setEntry_physicalCamera_u8; # introduced=29
+    ACaptureRequest_setUserContext; # introduced=28
     ACaptureSessionOutputContainer_add;
     ACaptureSessionOutputContainer_create;
     ACaptureSessionOutputContainer_free;
     ACaptureSessionOutputContainer_remove;
     ACaptureSessionOutput_create;
-    ACaptureSessionSharedOutput_create;
-    ACaptureSessionSharedOutput_add;
-    ACaptureSessionSharedOutput_remove;
+    ACaptureSessionSharedOutput_create; # introduced=28
+    ACaptureSessionSharedOutput_add; # introduced=28
+    ACaptureSessionSharedOutput_remove; # introduced=28
+    ACaptureSessionPhysicalOutput_create; # introduced=29
     ACaptureSessionOutput_free;
   local:
     *;
diff --git a/camera/ndk/ndk_vendor/impl/ACameraCaptureSessionVendor.h b/camera/ndk/ndk_vendor/impl/ACameraCaptureSessionVendor.h
new file mode 100644
index 0000000..e1af8c1
--- /dev/null
+++ b/camera/ndk/ndk_vendor/impl/ACameraCaptureSessionVendor.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+#include "utils.h"
+
+struct ACaptureSessionOutput {
+    explicit ACaptureSessionOutput(native_handle_t* window, bool isShared = false,
+            const char* physicalCameraId = "") :
+            mWindow(window), mIsShared(isShared), mPhysicalCameraId(physicalCameraId) {};
+
+    bool operator == (const ACaptureSessionOutput& other) const {
+        return (mWindow == other.mWindow);
+    }
+
+    bool operator != (const ACaptureSessionOutput& other) const {
+        return mWindow != other.mWindow;
+    }
+
+    bool operator < (const ACaptureSessionOutput& other) const {
+        return mWindow < other.mWindow;
+    }
+
+    bool operator > (const ACaptureSessionOutput& other) const {
+        return mWindow > other.mWindow;
+    }
+
+    android::acam::utils::native_handle_ptr_wrapper mWindow;
+    std::set<android::acam::utils::native_handle_ptr_wrapper> mSharedWindows;
+    bool           mIsShared;
+    int            mRotation = CAMERA3_STREAM_ROTATION_0;
+    std::string mPhysicalCameraId;
+};
+
+
diff --git a/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp b/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
new file mode 100644
index 0000000..35c8355
--- /dev/null
+++ b/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
@@ -0,0 +1,1719 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ACameraDeviceVendor"
+
+#include <vector>
+#include <inttypes.h>
+#include <android/frameworks/cameraservice/service/2.0/ICameraService.h>
+#include <android/frameworks/cameraservice/device/2.0/types.h>
+#include <CameraMetadata.h>
+
+#include "ndk_vendor/impl/ACameraDevice.h"
+#include "ACameraCaptureSession.h"
+#include "ACameraMetadata.h"
+#include "ACaptureRequest.h"
+#include "utils.h"
+
+#include "ACameraCaptureSession.inc"
+
+#define CHECK_TRANSACTION_AND_RET(remoteRet, status, callName) \
+    if (!remoteRet.isOk()) { \
+        ALOGE("%s: Transaction error during %s call %s", __FUNCTION__, callName, \
+                  remoteRet.description().c_str()); \
+        return ACAMERA_ERROR_UNKNOWN; \
+    } \
+    if (status != Status::NO_ERROR) { \
+        ALOGE("%s: %s call failed", __FUNCTION__, callName); \
+        return utils::convertFromHidl(status); \
+    }
+
+using namespace android;
+
+ACameraDevice::~ACameraDevice() {
+    mDevice->stopLooper();
+}
+
+namespace android {
+namespace acam {
+
+using HCameraMetadata = frameworks::cameraservice::device::V2_0::CameraMetadata;
+using OutputConfiguration = frameworks::cameraservice::device::V2_0::OutputConfiguration;
+using SessionConfiguration = frameworks::cameraservice::device::V2_0::SessionConfiguration;
+using hardware::Void;
+
+// Static member definitions
+const char* CameraDevice::kContextKey        = "Context";
+const char* CameraDevice::kDeviceKey         = "Device";
+const char* CameraDevice::kErrorCodeKey      = "ErrorCode";
+const char* CameraDevice::kCallbackFpKey     = "Callback";
+const char* CameraDevice::kSessionSpKey      = "SessionSp";
+const char* CameraDevice::kCaptureRequestKey = "CaptureRequest";
+const char* CameraDevice::kTimeStampKey      = "TimeStamp";
+const char* CameraDevice::kCaptureResultKey  = "CaptureResult";
+const char* CameraDevice::kPhysicalCaptureResultKey = "PhysicalCaptureResult";
+const char* CameraDevice::kCaptureFailureKey = "CaptureFailure";
+const char* CameraDevice::kSequenceIdKey     = "SequenceId";
+const char* CameraDevice::kFrameNumberKey    = "FrameNumber";
+const char* CameraDevice::kAnwKey            = "Anw";
+const char* CameraDevice::kFailingPhysicalCameraId= "FailingPhysicalCameraId";
+
+/**
+ * CameraDevice Implementation
+ */
+CameraDevice::CameraDevice(
+        const char* id,
+        ACameraDevice_StateCallbacks* cb,
+        sp<ACameraMetadata> chars,
+        ACameraDevice* wrapper) :
+        mCameraId(id),
+        mAppCallbacks(*cb),
+        mChars(std::move(chars)),
+        mServiceCallback(new ServiceCallback(this)),
+        mWrapper(wrapper),
+        mInError(false),
+        mError(ACAMERA_OK),
+        mIdle(true),
+        mCurrentSession(nullptr) {
+    mClosing = false;
+    // Setup looper thread to perfrom device callbacks to app
+    mCbLooper = new ALooper;
+    mCbLooper->setName("C2N-dev-looper");
+    status_t err = mCbLooper->start(
+            /*runOnCallingThread*/false,
+            /*canCallJava*/       true,
+            PRIORITY_DEFAULT);
+    if (err != OK) {
+        ALOGE("%s: Unable to start camera device callback looper: %s (%d)",
+                __FUNCTION__, strerror(-err), err);
+        setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
+    }
+    mHandler = new CallbackHandler(id);
+    mCbLooper->registerHandler(mHandler);
+
+    const CameraMetadata& metadata = mChars->getInternalData();
+    camera_metadata_ro_entry entry = metadata.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
+    if (entry.count != 1) {
+        ALOGW("%s: bad count %zu for partial result count", __FUNCTION__, entry.count);
+        mPartialResultCount = 1;
+    } else {
+        mPartialResultCount = entry.data.i32[0];
+    }
+
+    entry = metadata.find(ANDROID_LENS_INFO_SHADING_MAP_SIZE);
+    if (entry.count != 2) {
+        ALOGW("%s: bad count %zu for shading map size", __FUNCTION__, entry.count);
+        mShadingMapSize[0] = 0;
+        mShadingMapSize[1] = 0;
+    } else {
+        mShadingMapSize[0] = entry.data.i32[0];
+        mShadingMapSize[1] = entry.data.i32[1];
+    }
+}
+
+// Device close implementaiton
+CameraDevice::~CameraDevice() {
+    sp<ACameraCaptureSession> session = mCurrentSession.promote();
+    {
+        Mutex::Autolock _l(mDeviceLock);
+        if (!isClosed()) {
+            disconnectLocked(session);
+        }
+        mCurrentSession = nullptr;
+        LOG_ALWAYS_FATAL_IF(mCbLooper != nullptr,
+            "CameraDevice looper should've been stopped before ~CameraDevice");
+    }
+}
+
+void
+CameraDevice::postSessionMsgAndCleanup(sp<AMessage>& msg) {
+    msg->post();
+    msg.clear();
+    sp<AMessage> cleanupMsg = new AMessage(kWhatCleanUpSessions, mHandler);
+    cleanupMsg->post();
+}
+
+// TODO: cached created request?
+camera_status_t
+CameraDevice::createCaptureRequest(
+        ACameraDevice_request_template templateId,
+        const ACameraIdList* physicalCameraIdList,
+        ACaptureRequest** request) const {
+    Mutex::Autolock _l(mDeviceLock);
+    camera_status_t ret = checkCameraClosedOrErrorLocked();
+    if (ret != ACAMERA_OK) {
+        return ret;
+    }
+    if (mRemote == nullptr) {
+        return ACAMERA_ERROR_CAMERA_DISCONNECTED;
+    }
+    CameraMetadata rawRequest;
+    Status status = Status::UNKNOWN_ERROR;
+    auto remoteRet = mRemote->createDefaultRequest(
+        utils::convertToHidl(templateId),
+        [&status, &rawRequest](auto s, const hidl_vec<uint8_t> &metadata) {
+            status = s;
+            if (status == Status::NO_ERROR && utils::convertFromHidlCloned(metadata, &rawRequest)) {
+            } else {
+                ALOGE("%s: Couldn't create default request", __FUNCTION__);
+            }
+        });
+    CHECK_TRANSACTION_AND_RET(remoteRet, status, "createDefaultRequest()")
+    ACaptureRequest* outReq = new ACaptureRequest();
+    outReq->settings = new ACameraMetadata(rawRequest.release(), ACameraMetadata::ACM_REQUEST);
+    if (physicalCameraIdList != nullptr) {
+        for (auto i = 0; i < physicalCameraIdList->numCameras; i++) {
+            outReq->physicalSettings.emplace(physicalCameraIdList->cameraIds[i],
+                    new ACameraMetadata(*(outReq->settings)));
+        }
+    }
+    outReq->targets  = new ACameraOutputTargets();
+    *request = outReq;
+    return ACAMERA_OK;
+}
+
+camera_status_t
+CameraDevice::createCaptureSession(
+        const ACaptureSessionOutputContainer*       outputs,
+        const ACaptureRequest* sessionParameters,
+        const ACameraCaptureSession_stateCallbacks* callbacks,
+        /*out*/ACameraCaptureSession** session) {
+    sp<ACameraCaptureSession> currentSession = mCurrentSession.promote();
+    Mutex::Autolock _l(mDeviceLock);
+    camera_status_t ret = checkCameraClosedOrErrorLocked();
+    if (ret != ACAMERA_OK) {
+        return ret;
+    }
+
+    if (currentSession != nullptr) {
+        currentSession->closeByDevice();
+        stopRepeatingLocked();
+    }
+
+    // Create new session
+    ret = configureStreamsLocked(outputs, sessionParameters);
+    if (ret != ACAMERA_OK) {
+        ALOGE("Fail to create new session. cannot configure streams");
+        return ret;
+    }
+
+    ACameraCaptureSession* newSession = new ACameraCaptureSession(
+            mNextSessionId++, outputs, callbacks, this);
+
+    // set new session as current session
+    newSession->incStrong((void *) ACameraDevice_createCaptureSession);
+    mCurrentSession = newSession;
+    mFlushing = false;
+    *session = newSession;
+    return ACAMERA_OK;
+}
+
+camera_status_t CameraDevice::isSessionConfigurationSupported(
+        const ACaptureSessionOutputContainer* sessionOutputContainer) const {
+    Mutex::Autolock _l(mDeviceLock);
+    camera_status_t ret = checkCameraClosedOrErrorLocked();
+    if (ret != ACAMERA_OK) {
+        return ret;
+    }
+
+    SessionConfiguration sessionConfig;
+    sessionConfig.inputWidth = 0;
+    sessionConfig.inputHeight = 0;
+    sessionConfig.inputFormat = -1;
+    sessionConfig.operationMode = StreamConfigurationMode::NORMAL_MODE;
+    sessionConfig.outputStreams.resize(sessionOutputContainer->mOutputs.size());
+    size_t index = 0;
+    for (const auto& output : sessionOutputContainer->mOutputs) {
+        sessionConfig.outputStreams[index].rotation = utils::convertToHidl(output.mRotation);
+        sessionConfig.outputStreams[index].windowGroupId = -1;
+        sessionConfig.outputStreams[index].windowHandles.resize(output.mSharedWindows.size() + 1);
+        sessionConfig.outputStreams[index].windowHandles[0] = output.mWindow;
+        sessionConfig.outputStreams[index].physicalCameraId = output.mPhysicalCameraId;
+        index++;
+    }
+
+    bool configSupported = false;
+    Status status = Status::UNKNOWN_ERROR;
+    auto remoteRet = mRemote->isSessionConfigurationSupported(sessionConfig,
+        [&status, &configSupported](auto s, auto supported) {
+            status = s;
+            configSupported = supported;
+        });
+
+    CHECK_TRANSACTION_AND_RET(remoteRet, status, "isSessionConfigurationSupported()");
+    return configSupported ? ACAMERA_OK : ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
+}
+
+static void addMetadataToPhysicalCameraSettings(const CameraMetadata *metadata,
+        const std::string &cameraId, PhysicalCameraSettings *physicalCameraSettings) {
+    CameraMetadata metadataCopy = *metadata;
+    camera_metadata_t *camera_metadata = metadataCopy.release();
+    HCameraMetadata hCameraMetadata;
+    utils::convertToHidl(camera_metadata, &hCameraMetadata, /*shouldOwn*/ true);
+    physicalCameraSettings->settings.metadata(std::move(hCameraMetadata));
+    physicalCameraSettings->id = cameraId;
+}
+
+void CameraDevice::addRequestSettingsMetadata(ACaptureRequest *aCaptureRequest,
+        sp<CaptureRequest> &req) {
+    req->mPhysicalCameraSettings.resize(1 + aCaptureRequest->physicalSettings.size());
+    addMetadataToPhysicalCameraSettings(&(aCaptureRequest->settings->getInternalData()), getId(),
+                    &(req->mPhysicalCameraSettings[0]));
+    size_t i = 1;
+    for (auto &physicalSetting : aCaptureRequest->physicalSettings) {
+        addMetadataToPhysicalCameraSettings(&(physicalSetting.second->getInternalData()),
+                physicalSetting.first, &(req->mPhysicalCameraSettings[i]));
+        i++;
+    }
+}
+
+camera_status_t CameraDevice::updateOutputConfigurationLocked(ACaptureSessionOutput *output) {
+    camera_status_t ret = checkCameraClosedOrErrorLocked();
+    if (ret != ACAMERA_OK) {
+        return ret;
+    }
+
+    if (output == nullptr) {
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+
+    if (!output->mIsShared) {
+        ALOGE("Error output configuration is not shared");
+        return ACAMERA_ERROR_INVALID_OPERATION;
+    }
+
+    int32_t streamId = -1;
+    for (auto& kvPair : mConfiguredOutputs) {
+        if (utils::isWindowNativeHandleEqual(kvPair.second.first, output->mWindow)) {
+            streamId = kvPair.first;
+            break;
+        }
+    }
+    if (streamId < 0) {
+        ALOGE("Error: Invalid output configuration");
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+
+    OutputConfigurationWrapper outConfigW;
+    OutputConfiguration &outConfig = outConfigW.mOutputConfiguration;
+    outConfig.rotation = utils::convertToHidl(output->mRotation);
+    outConfig.windowHandles.resize(output->mSharedWindows.size() + 1);
+    outConfig.windowHandles[0] = output->mWindow;
+    outConfig.physicalCameraId = output->mPhysicalCameraId;
+    int i = 1;
+    for (auto& anw : output->mSharedWindows) {
+        outConfig.windowHandles[i++] = anw;
+    }
+
+    auto remoteRet = mRemote->updateOutputConfiguration(streamId, outConfig);
+    if (!remoteRet.isOk()) {
+        ALOGE("%s: Transaction error in updating OutputConfiguration: %s", __FUNCTION__,
+              remoteRet.description().c_str());
+        return ACAMERA_ERROR_UNKNOWN;
+    }
+
+    switch (remoteRet) {
+            case Status::NO_ERROR:
+                break;
+            case Status::INVALID_OPERATION:
+                ALOGE("Camera device %s invalid operation", getId());
+                return ACAMERA_ERROR_INVALID_OPERATION;
+            case Status::ALREADY_EXISTS:
+                ALOGE("Camera device %s output surface already exists", getId());
+                return ACAMERA_ERROR_INVALID_PARAMETER;
+            case Status::ILLEGAL_ARGUMENT:
+                ALOGE("Camera device %s invalid input argument", getId());
+                return ACAMERA_ERROR_INVALID_PARAMETER;
+            default:
+                ALOGE("Camera device %s failed to add shared output", getId());
+                return ACAMERA_ERROR_UNKNOWN;
+    }
+
+    mConfiguredOutputs[streamId] = std::make_pair(output->mWindow, outConfigW);
+
+    return ACAMERA_OK;
+}
+
+camera_status_t
+CameraDevice::allocateCaptureRequestLocked(
+        const ACaptureRequest* request, /*out*/sp<CaptureRequest> &outReq) {
+    sp<CaptureRequest> req(new CaptureRequest());
+    req->mCaptureRequest.physicalCameraSettings.resize(1 + request->physicalSettings.size());
+
+    size_t index = 0;
+    allocateOneCaptureRequestMetadata(
+            req->mCaptureRequest.physicalCameraSettings[index++], mCameraId, request->settings);
+
+    for (auto& physicalEntry : request->physicalSettings) {
+        allocateOneCaptureRequestMetadata(
+                req->mCaptureRequest.physicalCameraSettings[index++],
+                physicalEntry.first, physicalEntry.second);
+    }
+
+    std::vector<int32_t> requestStreamIdxList;
+    std::vector<int32_t> requestSurfaceIdxList;
+    for (auto outputTarget : request->targets->mOutputs) {
+        native_handle_t* anw = outputTarget.mWindow;
+        bool found = false;
+        req->mSurfaceList.push_back(anw);
+        // lookup stream/surface ID
+        for (const auto& kvPair : mConfiguredOutputs) {
+            int streamId = kvPair.first;
+            const OutputConfigurationWrapper& outConfig = kvPair.second.second;
+            const auto& windowHandles = outConfig.mOutputConfiguration.windowHandles;
+            for (int surfaceId = 0; surfaceId < (int) windowHandles.size(); surfaceId++) {
+                // If two native handles are equivalent, so are their surfaces.
+                if (utils::isWindowNativeHandleEqual(windowHandles[surfaceId].getNativeHandle(),
+                                                      anw)) {
+                    found = true;
+                    requestStreamIdxList.push_back(streamId);
+                    requestSurfaceIdxList.push_back(surfaceId);
+                    break;
+                }
+            }
+            if (found) {
+                break;
+            }
+        }
+        if (!found) {
+            ALOGE("Unconfigured output target %p in capture request!", anw);
+            return ACAMERA_ERROR_INVALID_PARAMETER;
+        }
+    }
+    req->mCaptureRequest.streamAndWindowIds.resize(requestStreamIdxList.size());
+    for (int i = 0; i < requestStreamIdxList.size(); i++) {
+        req->mCaptureRequest.streamAndWindowIds[i].streamId = requestStreamIdxList[i];
+        req->mCaptureRequest.streamAndWindowIds[i].windowId = requestSurfaceIdxList[i];
+    }
+    outReq = req;
+    return ACAMERA_OK;
+}
+
+void CameraDevice::allocateOneCaptureRequestMetadata(
+        PhysicalCameraSettings& cameraSettings,
+        const std::string& id, const sp<ACameraMetadata>& metadata) {
+    cameraSettings.id = id;
+    // TODO: Do we really need to copy the metadata here ?
+    CameraMetadata metadataCopy = metadata->getInternalData();
+    camera_metadata_t *cameraMetadata = metadataCopy.release();
+    HCameraMetadata hCameraMetadata;
+    utils::convertToHidl(cameraMetadata, &hCameraMetadata, true);
+    if (metadata != nullptr) {
+        if (hCameraMetadata.data() != nullptr &&
+            mCaptureRequestMetadataQueue != nullptr &&
+            mCaptureRequestMetadataQueue->write(
+                reinterpret_cast<const uint8_t *>(hCameraMetadata.data()),
+                hCameraMetadata.size())) {
+            // The metadata field of the union would've been destructued, so no need
+            // to re-size it.
+            cameraSettings.settings.fmqMetadataSize(hCameraMetadata.size());
+        } else {
+            ALOGE("Fmq write capture result failed, falling back to hwbinder");
+            cameraSettings.settings.metadata(std::move(hCameraMetadata));
+        }
+    }
+}
+
+
+ACaptureRequest*
+CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req, const char* deviceId) {
+    ACaptureRequest* pRequest = new ACaptureRequest();
+    for (size_t i = 0; i < req->mPhysicalCameraSettings.size(); i++) {
+        const std::string& id = req->mPhysicalCameraSettings[i].id;
+        CameraMetadata clone;
+        utils::convertFromHidlCloned(req->mPhysicalCameraSettings[i].settings.metadata(), &clone);
+        camera_metadata_t *clonep = clone.release();
+        if (id == deviceId) {
+            pRequest->settings = new ACameraMetadata(clonep, ACameraMetadata::ACM_REQUEST);
+        } else {
+            pRequest->physicalSettings[req->mPhysicalCameraSettings[i].id] =
+                    new ACameraMetadata(clonep, ACameraMetadata::ACM_REQUEST);
+        }
+    }
+    pRequest->targets = new ACameraOutputTargets();
+    for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
+        native_handle_t* anw = req->mSurfaceList[i];
+        ACameraOutputTarget outputTarget(anw);
+        pRequest->targets->mOutputs.insert(outputTarget);
+    }
+    return pRequest;
+}
+
+void
+CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
+    if (req == nullptr) {
+        return;
+    }
+    req->settings.clear();
+    delete req->targets;
+    delete req;
+}
+
+void
+CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) {
+    if (isClosed()) {
+        // Device is closing already. do nothing
+        return;
+    }
+
+    if (mCurrentSession != session) {
+        // Session has been replaced by other seesion or device is closed
+        return;
+    }
+    mCurrentSession = nullptr;
+
+    // Should not happen
+    if (!session->mIsClosed) {
+        ALOGE("Error: unclosed session %p reaches end of life!", session);
+        setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
+        return;
+    }
+
+    // No new session, unconfigure now
+    camera_status_t ret = configureStreamsLocked(nullptr, nullptr);
+    if (ret != ACAMERA_OK) {
+        ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
+    }
+}
+
+void
+CameraDevice::disconnectLocked(sp<ACameraCaptureSession>& session) {
+    if (mClosing.exchange(true)) {
+        // Already closing, just return
+        ALOGW("Camera device %s is already closing.", getId());
+        return;
+    }
+
+    if (mRemote != nullptr) {
+        auto ret = mRemote->disconnect();
+        if (!ret.isOk()) {
+            ALOGE("%s: Transaction error while disconnecting device %s", __FUNCTION__,
+                  ret.description().c_str());
+        }
+    }
+    mRemote = nullptr;
+
+    if (session != nullptr) {
+        session->closeByDevice();
+    }
+}
+
+camera_status_t
+CameraDevice::stopRepeatingLocked() {
+    camera_status_t ret = checkCameraClosedOrErrorLocked();
+    if (ret != ACAMERA_OK) {
+        ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
+        return ret;
+    }
+    if (mRepeatingSequenceId != REQUEST_ID_NONE) {
+        int repeatingSequenceId = mRepeatingSequenceId;
+        mRepeatingSequenceId = REQUEST_ID_NONE;
+
+        int64_t lastFrameNumber;
+        Status status = Status::UNKNOWN_ERROR;
+        auto remoteRet = mRemote->cancelRepeatingRequest(
+                [&status, &lastFrameNumber](Status s, auto frameNumber) {
+                    status = s;
+                    lastFrameNumber = frameNumber;
+                });
+        CHECK_TRANSACTION_AND_RET(remoteRet, status, "cancelRepeatingRequest()");
+        checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
+    }
+    return ACAMERA_OK;
+}
+
+camera_status_t
+CameraDevice::flushLocked(ACameraCaptureSession* session) {
+    camera_status_t ret = checkCameraClosedOrErrorLocked();
+    if (ret != ACAMERA_OK) {
+        ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
+        return ret;
+    }
+
+    // This should never happen because creating a new session will close
+    // previous one and thus reject any API call from previous session.
+    // But still good to check here in case something unexpected happen.
+    if (mCurrentSession != session) {
+        ALOGE("Camera %s session %p is not current active session!", getId(), session);
+        return ACAMERA_ERROR_INVALID_OPERATION;
+    }
+
+    if (mFlushing) {
+        ALOGW("Camera %s is already aborting captures", getId());
+        return ACAMERA_OK;
+    }
+
+    mFlushing = true;
+
+    // Send onActive callback to guarantee there is always active->ready transition
+    sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
+    msg->setPointer(kContextKey, session->mUserSessionCallback.context);
+    msg->setObject(kSessionSpKey, session);
+    msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
+    postSessionMsgAndCleanup(msg);
+
+    // If device is already idling, send callback and exit early
+    if (mIdle) {
+        sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
+        msg->setPointer(kContextKey, session->mUserSessionCallback.context);
+        msg->setObject(kSessionSpKey, session);
+        msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
+        postSessionMsgAndCleanup(msg);
+        mFlushing = false;
+        return ACAMERA_OK;
+    }
+
+    int64_t lastFrameNumber;
+    Status status = Status::UNKNOWN_ERROR;
+    auto remoteRet = mRemote->flush([&status, &lastFrameNumber](auto s, auto frameNumber) {
+                                        status = s;
+                                        lastFrameNumber = frameNumber;
+                                    });
+    CHECK_TRANSACTION_AND_RET(remoteRet, status, "flush()")
+    if (mRepeatingSequenceId != REQUEST_ID_NONE) {
+        checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
+    }
+    return ACAMERA_OK;
+}
+
+camera_status_t
+CameraDevice::waitUntilIdleLocked() {
+    camera_status_t ret = checkCameraClosedOrErrorLocked();
+    if (ret != ACAMERA_OK) {
+        ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
+        return ret;
+    }
+
+    if (mRepeatingSequenceId != REQUEST_ID_NONE) {
+        ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
+        return ACAMERA_ERROR_INVALID_OPERATION;
+    }
+
+    auto remoteRet = mRemote->waitUntilIdle();
+    CHECK_TRANSACTION_AND_RET(remoteRet, remoteRet, "waitUntilIdle()")
+    return ACAMERA_OK;
+}
+
+camera_status_t
+CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs,
+        const ACaptureRequest* sessionParameters) {
+    ACaptureSessionOutputContainer emptyOutput;
+    if (outputs == nullptr) {
+        outputs = &emptyOutput;
+    }
+
+    camera_status_t ret = checkCameraClosedOrErrorLocked();
+    if (ret != ACAMERA_OK) {
+        return ret;
+    }
+
+    std::set<std::pair<native_handle_ptr_wrapper, OutputConfigurationWrapper>> outputSet;
+    for (auto outConfig : outputs->mOutputs) {
+        native_handle_t* anw = outConfig.mWindow;
+        OutputConfigurationWrapper outConfigInsertW;
+        OutputConfiguration &outConfigInsert = outConfigInsertW.mOutputConfiguration;
+        outConfigInsert.rotation = utils::convertToHidl(outConfig.mRotation);
+        outConfigInsert.windowGroupId = -1;
+        outConfigInsert.windowHandles.resize(outConfig.mSharedWindows.size() + 1);
+        outConfigInsert.windowHandles[0] = anw;
+        outConfigInsert.physicalCameraId = outConfig.mPhysicalCameraId;
+        native_handle_ptr_wrapper wrap(anw);
+        outputSet.insert(std::make_pair(anw, outConfigInsertW));
+    }
+    std::set<std::pair<native_handle_ptr_wrapper, OutputConfigurationWrapper>> addSet = outputSet;
+    std::vector<int32_t> deleteList;
+
+    // Determine which streams need to be created, which to be deleted
+    for (auto& kvPair : mConfiguredOutputs) {
+        int32_t streamId = kvPair.first;
+        auto& outputPair = kvPair.second;
+        if (outputSet.count(outputPair)) {
+            deleteList.push_back(streamId); // Need to delete a no longer needed stream
+        } else {
+            addSet.erase(outputPair);        // No need to add already existing stream
+        }
+    }
+
+    ret = stopRepeatingLocked();
+    if (ret != ACAMERA_OK) {
+        ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
+        return ret;
+    }
+
+    ret = waitUntilIdleLocked();
+    if (ret != ACAMERA_OK) {
+        ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
+        return ret;
+    }
+
+    // Send onReady to previous session
+    // CurrentSession will be updated after configureStreamLocked, so here
+    // mCurrentSession is the session to be replaced by a new session
+    if (!mIdle && mCurrentSession != nullptr) {
+        if (mBusySession != mCurrentSession) {
+            ALOGE("Current session != busy session");
+            setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
+            return ACAMERA_ERROR_CAMERA_DEVICE;
+        }
+        sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
+        msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
+        msg->setObject(kSessionSpKey, mBusySession);
+        msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
+        mBusySession.clear();
+        postSessionMsgAndCleanup(msg);
+    }
+    mIdle = true;
+
+    auto remoteRet = mRemote->beginConfigure();
+    CHECK_TRANSACTION_AND_RET(remoteRet, remoteRet, "beginConfigure()")
+
+    // delete to-be-deleted streams
+    for (auto streamId : deleteList) {
+        remoteRet = mRemote->deleteStream(streamId);
+        CHECK_TRANSACTION_AND_RET(remoteRet, remoteRet, "deleteStream()")
+        mConfiguredOutputs.erase(streamId);
+    }
+
+    // add new streams
+    for (auto outputPair : addSet) {
+        int streamId;
+        Status status = Status::UNKNOWN_ERROR;
+        auto ret = mRemote->createStream(outputPair.second,
+                                         [&status, &streamId](Status s, auto stream_id) {
+                                             status = s;
+                                             streamId = stream_id;
+                                         });
+        CHECK_TRANSACTION_AND_RET(ret, status, "createStream()")
+        mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
+    }
+
+    CameraMetadata params;
+    HCameraMetadata hidlParams;
+    if ((sessionParameters != nullptr) && (sessionParameters->settings != nullptr)) {
+        params.append(sessionParameters->settings->getInternalData());
+        const camera_metadata_t *params_metadata = params.getAndLock();
+        utils::convertToHidl(params_metadata, &hidlParams);
+        params.unlock(params_metadata);
+    }
+    remoteRet = mRemote->endConfigure(StreamConfigurationMode::NORMAL_MODE, hidlParams);
+    CHECK_TRANSACTION_AND_RET(remoteRet, remoteRet, "endConfigure()")
+    return ACAMERA_OK;
+}
+
+void
+CameraDevice::setRemoteDevice(sp<ICameraDeviceUser> remote) {
+    Mutex::Autolock _l(mDeviceLock);
+    mRemote = remote;
+}
+
+bool
+CameraDevice::setDeviceMetadataQueues() {
+        if (mRemote == nullptr) {
+          ALOGE("mRemote must not be null while trying to fetch metadata queues");
+          return false;
+        }
+        std::shared_ptr<RequestMetadataQueue> &reqQueue = mCaptureRequestMetadataQueue;
+        auto ret =
+            mRemote->getCaptureRequestMetadataQueue(
+                [&reqQueue](const auto &mqDescriptor) {
+                    reqQueue = std::make_shared<RequestMetadataQueue>(mqDescriptor);
+                    if (!reqQueue->isValid() || reqQueue->availableToWrite() <=0) {
+                        ALOGE("Empty fmq from cameraserver");
+                        reqQueue = nullptr;
+                    }
+                });
+        if (!ret.isOk()) {
+            ALOGE("Transaction error trying to get capture request metadata queue");
+            return false;
+        }
+        std::shared_ptr<ResultMetadataQueue> &resQueue = mCaptureResultMetadataQueue;
+        ret =
+                mRemote->getCaptureResultMetadataQueue(
+                        [&resQueue](const auto &mqDescriptor) {
+                            resQueue = std::make_shared<ResultMetadataQueue>(mqDescriptor);
+                            if (!resQueue->isValid() || resQueue->availableToWrite() <=0) {
+                                ALOGE("Empty fmq from cameraserver");
+                            }
+                        });
+        if (!ret.isOk()) {
+            ALOGE("Transaction error trying to get capture result metadata queue");
+            return false;
+        }
+        return true;
+}
+
+camera_status_t
+CameraDevice::checkCameraClosedOrErrorLocked() const {
+    if (mRemote == nullptr) {
+        ALOGE("%s: camera device already closed", __FUNCTION__);
+        return ACAMERA_ERROR_CAMERA_DISCONNECTED;
+    }
+    if (mInError) {// triggered by onDeviceError
+        ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
+        return mError;
+    }
+    return ACAMERA_OK;
+}
+
+void
+CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
+    mInError = true;
+    mError = error;
+    return;
+}
+
+void
+CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
+    ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
+    if (isError) {
+        mFutureErrorSet.insert(frameNumber);
+    } else if (frameNumber <= mCompletedFrameNumber) {
+        ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
+                frameNumber, mCompletedFrameNumber);
+        return;
+    } else {
+        if (frameNumber != mCompletedFrameNumber + 1) {
+            ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
+                    mCompletedFrameNumber + 1, frameNumber);
+            // Do not assert as in java implementation
+        }
+        mCompletedFrameNumber = frameNumber;
+    }
+    update();
+}
+
+void
+CameraDevice::FrameNumberTracker::update() {
+    for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
+        int64_t errorFrameNumber = *it;
+        if (errorFrameNumber == mCompletedFrameNumber + 1) {
+            mCompletedFrameNumber++;
+            it = mFutureErrorSet.erase(it);
+        } else if (errorFrameNumber <= mCompletedFrameNumber) {
+            // This should not happen, but deal with it anyway
+            ALOGE("Completd frame number passed through current frame number!");
+            // erase the old error since it's no longer useful
+            it = mFutureErrorSet.erase(it);
+        } else {
+            // Normal requests hasn't catched up error frames, just break
+            break;
+        }
+    }
+    ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
+}
+
+void
+CameraDevice::onCaptureErrorLocked(
+        ErrorCode errorCode,
+        const CaptureResultExtras& resultExtras) {
+    int sequenceId = resultExtras.requestId;
+    int64_t frameNumber = resultExtras.frameNumber;
+    int32_t burstId = resultExtras.burstId;
+    auto it = mSequenceCallbackMap.find(sequenceId);
+    if (it == mSequenceCallbackMap.end()) {
+        ALOGE("%s: Error: capture sequence index %d not found!",
+                __FUNCTION__, sequenceId);
+        setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
+        return;
+    }
+
+    CallbackHolder cbh = (*it).second;
+    sp<ACameraCaptureSession> session = cbh.mSession;
+    if ((size_t) burstId >= cbh.mRequests.size()) {
+        ALOGE("%s: Error: request index %d out of bound (size %zu)",
+                __FUNCTION__, burstId, cbh.mRequests.size());
+        setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
+        return;
+    }
+    sp<CaptureRequest> request = cbh.mRequests[burstId];
+
+    // Handle buffer error
+    if (errorCode == ErrorCode::CAMERA_BUFFER) {
+        int32_t streamId = resultExtras.errorStreamId;
+        ACameraCaptureSession_captureCallback_bufferLost onBufferLost =
+                cbh.mOnCaptureBufferLost;
+        auto outputPairIt = mConfiguredOutputs.find(streamId);
+        if (outputPairIt == mConfiguredOutputs.end()) {
+            ALOGE("%s: Error: stream id %d does not exist", __FUNCTION__, streamId);
+            setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
+            return;
+        }
+
+        const auto& windowHandles = outputPairIt->second.second.mOutputConfiguration.windowHandles;
+        for (const auto& outHandle : windowHandles) {
+            for (auto streamAndWindowId : request->mCaptureRequest.streamAndWindowIds) {
+                int32_t windowId = streamAndWindowId.windowId;
+                if (utils::isWindowNativeHandleEqual(windowHandles[windowId],outHandle)) {
+                    native_handle_t* anw =
+                        const_cast<native_handle_t *>(windowHandles[windowId].getNativeHandle());
+                    ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
+                            getId(), anw, frameNumber);
+
+                    sp<AMessage> msg = new AMessage(kWhatCaptureBufferLost, mHandler);
+                    msg->setPointer(kContextKey, cbh.mContext);
+                    msg->setObject(kSessionSpKey, session);
+                    msg->setPointer(kCallbackFpKey, (void*) onBufferLost);
+                    msg->setObject(kCaptureRequestKey, request);
+                    msg->setPointer(kAnwKey, (void*) anw);
+                    msg->setInt64(kFrameNumberKey, frameNumber);
+                    postSessionMsgAndCleanup(msg);
+                }
+            }
+        }
+    } else { // Handle other capture failures
+        // Fire capture failure callback if there is one registered
+        ACameraCaptureSession_captureCallback_failed onError = cbh.mOnCaptureFailed;
+        sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
+        failure->frameNumber = frameNumber;
+        // TODO: refine this when implementing flush
+        failure->reason      = CAPTURE_FAILURE_REASON_ERROR;
+        failure->sequenceId  = sequenceId;
+        failure->wasImageCaptured = (errorCode == ErrorCode::CAMERA_RESULT);
+
+        sp<AMessage> msg = new AMessage(cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureFail :
+                kWhatCaptureFail, mHandler);
+        msg->setPointer(kContextKey, cbh.mContext);
+        msg->setObject(kSessionSpKey, session);
+        if (cbh.mIsLogicalCameraCallback) {
+            if (resultExtras.errorPhysicalCameraId.size() > 0) {
+                msg->setString(kFailingPhysicalCameraId, resultExtras.errorPhysicalCameraId.c_str(),
+                        resultExtras.errorPhysicalCameraId.size());
+            }
+            msg->setPointer(kCallbackFpKey, (void*) cbh.mOnLogicalCameraCaptureFailed);
+        } else {
+            msg->setPointer(kCallbackFpKey, (void*) onError);
+        }
+        msg->setObject(kCaptureRequestKey, request);
+        msg->setObject(kCaptureFailureKey, failure);
+        postSessionMsgAndCleanup(msg);
+
+        // Update tracker
+        mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
+        checkAndFireSequenceCompleteLocked();
+    }
+    return;
+}
+
+CameraDevice::CallbackHandler::CallbackHandler(const char *id) : mId(id) { }
+
+void CameraDevice::CallbackHandler::onMessageReceived(
+        const sp<AMessage> &msg) {
+    switch (msg->what()) {
+        case kWhatOnDisconnected:
+        case kWhatOnError:
+        case kWhatSessionStateCb:
+        case kWhatCaptureStart:
+        case kWhatCaptureResult:
+        case kWhatLogicalCaptureResult:
+        case kWhatCaptureFail:
+        case kWhatLogicalCaptureFail:
+        case kWhatCaptureSeqEnd:
+        case kWhatCaptureSeqAbort:
+        case kWhatCaptureBufferLost:
+            ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
+            break;
+        case kWhatCleanUpSessions:
+            mCachedSessions.clear();
+            return;
+        default:
+            ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
+            return;
+    }
+    // Check the common part of all message
+    void* context;
+    bool found = msg->findPointer(kContextKey, &context);
+    if (!found) {
+        ALOGE("%s: Cannot find callback context!", __FUNCTION__);
+        return;
+    }
+    switch (msg->what()) {
+        case kWhatOnDisconnected:
+        {
+            ACameraDevice* dev;
+            found = msg->findPointer(kDeviceKey, (void**) &dev);
+            if (!found || dev == nullptr) {
+                ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
+                return;
+            }
+            ACameraDevice_StateCallback onDisconnected;
+            found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
+            if (!found) {
+                ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
+                return;
+            }
+            if (onDisconnected == nullptr) {
+                return;
+            }
+            (*onDisconnected)(context, dev);
+            break;
+        }
+        case kWhatOnError:
+        {
+            ACameraDevice* dev;
+            found = msg->findPointer(kDeviceKey, (void**) &dev);
+            if (!found || dev == nullptr) {
+                ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
+                return;
+            }
+            ACameraDevice_ErrorStateCallback onError;
+            found = msg->findPointer(kCallbackFpKey, (void**) &onError);
+            if (!found) {
+                ALOGE("%s: Cannot find onError!", __FUNCTION__);
+                return;
+            }
+            int errorCode;
+            found = msg->findInt32(kErrorCodeKey, &errorCode);
+            if (!found) {
+                ALOGE("%s: Cannot find error code!", __FUNCTION__);
+                return;
+            }
+            if (onError == nullptr) {
+                return;
+            }
+            (*onError)(context, dev, errorCode);
+            break;
+        }
+        case kWhatSessionStateCb:
+        case kWhatCaptureStart:
+        case kWhatCaptureResult:
+        case kWhatLogicalCaptureResult:
+        case kWhatCaptureFail:
+        case kWhatLogicalCaptureFail:
+        case kWhatCaptureSeqEnd:
+        case kWhatCaptureSeqAbort:
+        case kWhatCaptureBufferLost:
+        {
+            sp<RefBase> obj;
+            found = msg->findObject(kSessionSpKey, &obj);
+            if (!found || obj == nullptr) {
+                ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
+                return;
+            }
+            sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
+            mCachedSessions.push(session);
+            sp<CaptureRequest> requestSp = nullptr;
+            const char *id_cstr = mId.c_str();
+            switch (msg->what()) {
+                case kWhatCaptureStart:
+                case kWhatCaptureResult:
+                case kWhatLogicalCaptureResult:
+                case kWhatCaptureFail:
+                case kWhatLogicalCaptureFail:
+                case kWhatCaptureBufferLost:
+                    found = msg->findObject(kCaptureRequestKey, &obj);
+                    if (!found) {
+                        ALOGE("%s: Cannot find capture request!", __FUNCTION__);
+                        return;
+                    }
+                    requestSp = static_cast<CaptureRequest*>(obj.get());
+                    break;
+            }
+
+            switch (msg->what()) {
+                case kWhatSessionStateCb:
+                {
+                    ACameraCaptureSession_stateCallback onState;
+                    found = msg->findPointer(kCallbackFpKey, (void**) &onState);
+                    if (!found) {
+                        ALOGE("%s: Cannot find state callback!", __FUNCTION__);
+                        return;
+                    }
+                    if (onState == nullptr) {
+                        return;
+                    }
+                    (*onState)(context, session.get());
+                    break;
+                }
+                case kWhatCaptureStart:
+                {
+                    ACameraCaptureSession_captureCallback_start onStart;
+                    found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
+                    if (!found) {
+                        ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
+                        return;
+                    }
+                    if (onStart == nullptr) {
+                        return;
+                    }
+                    int64_t timestamp;
+                    found = msg->findInt64(kTimeStampKey, &timestamp);
+                    if (!found) {
+                        ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
+                        return;
+                    }
+                    ACaptureRequest* request = allocateACaptureRequest(requestSp, id_cstr);
+                    (*onStart)(context, session.get(), request, timestamp);
+                    freeACaptureRequest(request);
+                    break;
+                }
+                case kWhatCaptureResult:
+                {
+                    ACameraCaptureSession_captureCallback_result onResult;
+                    found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
+                    if (!found) {
+                        ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
+                        return;
+                    }
+                    if (onResult == nullptr) {
+                        return;
+                    }
+
+                    found = msg->findObject(kCaptureResultKey, &obj);
+                    if (!found) {
+                        ALOGE("%s: Cannot find capture result!", __FUNCTION__);
+                        return;
+                    }
+                    sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
+                    ACaptureRequest* request = allocateACaptureRequest(requestSp, id_cstr);
+                    (*onResult)(context, session.get(), request, result.get());
+                    freeACaptureRequest(request);
+                    break;
+                }
+                case kWhatLogicalCaptureResult:
+                {
+                    ACameraCaptureSession_logicalCamera_captureCallback_result onResult;
+                    found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
+                    if (!found) {
+                        ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
+                        return;
+                    }
+                    if (onResult == nullptr) {
+                        return;
+                    }
+
+                    found = msg->findObject(kCaptureResultKey, &obj);
+                    if (!found) {
+                        ALOGE("%s: Cannot find capture result!", __FUNCTION__);
+                        return;
+                    }
+                    sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
+
+                    found = msg->findObject(kPhysicalCaptureResultKey, &obj);
+                    if (!found) {
+                        ALOGE("%s: Cannot find physical capture result!", __FUNCTION__);
+                        return;
+                    }
+                    sp<ACameraPhysicalCaptureResultInfo> physicalResult(
+                            static_cast<ACameraPhysicalCaptureResultInfo*>(obj.get()));
+                    std::vector<PhysicalCaptureResultInfoLocal>& physicalResultInfo =
+                            physicalResult->mPhysicalResultInfo;
+
+                    std::vector<std::string> physicalCameraIds;
+                    std::vector<sp<ACameraMetadata>> physicalMetadataCopy;
+                    for (size_t i = 0; i < physicalResultInfo.size(); i++) {
+                        physicalCameraIds.push_back(physicalResultInfo[i].physicalCameraId);
+
+                        CameraMetadata clone = physicalResultInfo[i].physicalMetadata;
+                        clone.update(ANDROID_SYNC_FRAME_NUMBER,
+                                &physicalResult->mFrameNumber, /*data_count*/1);
+                        sp<ACameraMetadata> metadata =
+                                new ACameraMetadata(clone.release(), ACameraMetadata::ACM_RESULT);
+                        physicalMetadataCopy.push_back(metadata);
+                    }
+                    std::vector<const char*> physicalCameraIdPtrs;
+                    std::vector<const ACameraMetadata*> physicalMetadataCopyPtrs;
+                    for (size_t i = 0; i < physicalResultInfo.size(); i++) {
+                        physicalCameraIdPtrs.push_back(physicalCameraIds[i].c_str());
+                        physicalMetadataCopyPtrs.push_back(physicalMetadataCopy[i].get());
+                    }
+
+                    ACaptureRequest* request = allocateACaptureRequest(requestSp, id_cstr);
+                    (*onResult)(context, session.get(), request, result.get(),
+                            physicalResultInfo.size(), physicalCameraIdPtrs.data(),
+                            physicalMetadataCopyPtrs.data());
+                    freeACaptureRequest(request);
+                    break;
+                }
+
+                case kWhatCaptureFail:
+                {
+                    ACameraCaptureSession_captureCallback_failed onFail;
+                    found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
+                    if (!found) {
+                        ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
+                        return;
+                    }
+                    if (onFail == nullptr) {
+                        return;
+                    }
+
+                    found = msg->findObject(kCaptureFailureKey, &obj);
+                    if (!found) {
+                        ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
+                        return;
+                    }
+                    sp<CameraCaptureFailure> failureSp(
+                            static_cast<CameraCaptureFailure*>(obj.get()));
+                    ACameraCaptureFailure* failure =
+                            static_cast<ACameraCaptureFailure*>(failureSp.get());
+                    ACaptureRequest* request = allocateACaptureRequest(requestSp, id_cstr);
+                    (*onFail)(context, session.get(), request, failure);
+                    freeACaptureRequest(request);
+                    break;
+                }
+                case kWhatLogicalCaptureFail:
+                {
+                    ACameraCaptureSession_logicalCamera_captureCallback_failed onFail;
+                    found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
+                    if (!found) {
+                        ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
+                        return;
+                    }
+                    if (onFail == nullptr) {
+                        return;
+                    }
+
+                    found = msg->findObject(kCaptureFailureKey, &obj);
+                    if (!found) {
+                        ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
+                        return;
+                    }
+                    sp<CameraCaptureFailure> failureSp(
+                            static_cast<CameraCaptureFailure*>(obj.get()));
+                    ALogicalCameraCaptureFailure failure;
+                    AString physicalCameraId;
+                    found = msg->findString(kFailingPhysicalCameraId, &physicalCameraId);
+                    if (found && !physicalCameraId.empty()) {
+                        failure.physicalCameraId = physicalCameraId.c_str();
+                    } else {
+                        failure.physicalCameraId = nullptr;
+                    }
+                    failure.captureFailure = *failureSp;
+                    ACaptureRequest* request = allocateACaptureRequest(requestSp, id_cstr);
+                    (*onFail)(context, session.get(), request, &failure);
+                    freeACaptureRequest(request);
+                    break;
+                }
+                case kWhatCaptureSeqEnd:
+                {
+                    ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
+                    found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
+                    if (!found) {
+                        ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
+                        return;
+                    }
+                    if (onSeqEnd == nullptr) {
+                        return;
+                    }
+                    int seqId;
+                    found = msg->findInt32(kSequenceIdKey, &seqId);
+                    if (!found) {
+                        ALOGE("%s: Cannot find frame number!", __FUNCTION__);
+                        return;
+                    }
+                    int64_t frameNumber;
+                    found = msg->findInt64(kFrameNumberKey, &frameNumber);
+                    if (!found) {
+                        ALOGE("%s: Cannot find frame number!", __FUNCTION__);
+                        return;
+                    }
+                    (*onSeqEnd)(context, session.get(), seqId, frameNumber);
+                    break;
+                }
+                case kWhatCaptureSeqAbort:
+                {
+                    ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
+                    found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
+                    if (!found) {
+                        ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
+                        return;
+                    }
+                    if (onSeqAbort == nullptr) {
+                        return;
+                    }
+                    int seqId;
+                    found = msg->findInt32(kSequenceIdKey, &seqId);
+                    if (!found) {
+                        ALOGE("%s: Cannot find frame number!", __FUNCTION__);
+                        return;
+                    }
+                    (*onSeqAbort)(context, session.get(), seqId);
+                    break;
+                }
+                case kWhatCaptureBufferLost:
+                {
+                    ACameraCaptureSession_captureCallback_bufferLost onBufferLost;
+                    found = msg->findPointer(kCallbackFpKey, (void**) &onBufferLost);
+                    if (!found) {
+                        ALOGE("%s: Cannot find buffer lost callback!", __FUNCTION__);
+                        return;
+                    }
+                    if (onBufferLost == nullptr) {
+                        return;
+                    }
+
+                    native_handle_t* anw;
+                    found = msg->findPointer(kAnwKey, (void**) &anw);
+                    if (!found) {
+                        ALOGE("%s: Cannot find native_handle_t!", __FUNCTION__);
+                        return;
+                    }
+
+                    int64_t frameNumber;
+                    found = msg->findInt64(kFrameNumberKey, &frameNumber);
+                    if (!found) {
+                        ALOGE("%s: Cannot find frame number!", __FUNCTION__);
+                        return;
+                    }
+
+                    ACaptureRequest* request = allocateACaptureRequest(requestSp, id_cstr);
+                    (*onBufferLost)(context, session.get(), request, anw, frameNumber);
+                    freeACaptureRequest(request);
+                    break;
+                }
+            }
+            break;
+        }
+    }
+}
+
+CameraDevice::CallbackHolder::CallbackHolder(
+        sp<ACameraCaptureSession>          session,
+        const Vector<sp<CaptureRequest> >& requests,
+        bool                               isRepeating,
+        ACameraCaptureSession_captureCallbacks* cbs) :
+        mSession(session), mRequests(requests),
+        mIsRepeating(isRepeating),
+        mIsLogicalCameraCallback(false) {
+    initCaptureCallbacks(cbs);
+
+    if (cbs != nullptr) {
+        mOnCaptureCompleted = cbs->onCaptureCompleted;
+        mOnCaptureFailed = cbs->onCaptureFailed;
+    }
+}
+
+CameraDevice::CallbackHolder::CallbackHolder(
+        sp<ACameraCaptureSession>          session,
+        const Vector<sp<CaptureRequest> >& requests,
+        bool                               isRepeating,
+        ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs) :
+        mSession(session), mRequests(requests),
+        mIsRepeating(isRepeating),
+        mIsLogicalCameraCallback(true) {
+    initCaptureCallbacks(lcbs);
+
+    if (lcbs != nullptr) {
+        mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
+        mOnLogicalCameraCaptureFailed = lcbs->onLogicalCameraCaptureFailed;
+    }
+}
+
+void
+CameraDevice::checkRepeatingSequenceCompleteLocked(
+    const int sequenceId, const int64_t lastFrameNumber) {
+    ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
+    if (lastFrameNumber == NO_FRAMES_CAPTURED) {
+        if (mSequenceCallbackMap.count(sequenceId) == 0) {
+            ALOGW("No callback found for sequenceId %d", sequenceId);
+            return;
+        }
+        // remove callback holder from callback map
+        auto cbIt = mSequenceCallbackMap.find(sequenceId);
+        CallbackHolder cbh = cbIt->second;
+        mSequenceCallbackMap.erase(cbIt);
+        // send seq aborted callback
+        sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
+        msg->setPointer(kContextKey, cbh.mContext);
+        msg->setObject(kSessionSpKey, cbh.mSession);
+        msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceAborted);
+        msg->setInt32(kSequenceIdKey, sequenceId);
+        postSessionMsgAndCleanup(msg);
+    } else {
+        // Use mSequenceLastFrameNumberMap to track
+        mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
+
+        // Last frame might have arrived. Check now
+        checkAndFireSequenceCompleteLocked();
+    }
+}
+
+void
+CameraDevice::checkAndFireSequenceCompleteLocked() {
+    int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
+    auto it = mSequenceLastFrameNumberMap.begin();
+    while (it != mSequenceLastFrameNumberMap.end()) {
+        int sequenceId = it->first;
+        int64_t lastFrameNumber = it->second;
+        bool seqCompleted = false;
+        bool hasCallback  = true;
+
+        if (mRemote == nullptr) {
+            ALOGW("Camera %s closed while checking sequence complete", getId());
+            return;
+        }
+
+        // Check if there is callback for this sequence
+        // This should not happen because we always register callback (with nullptr inside)
+        if (mSequenceCallbackMap.count(sequenceId) == 0) {
+            ALOGW("No callback found for sequenceId %d", sequenceId);
+            hasCallback = false;
+        }
+
+        if (lastFrameNumber <= completedFrameNumber) {
+            ALOGV("seq %d reached last frame %" PRId64 ", completed %" PRId64,
+                  sequenceId, lastFrameNumber, completedFrameNumber);
+            seqCompleted = true;
+        }
+
+        if (seqCompleted && hasCallback) {
+            // remove callback holder from callback map
+            auto cbIt = mSequenceCallbackMap.find(sequenceId);
+            CallbackHolder cbh = cbIt->second;
+            mSequenceCallbackMap.erase(cbIt);
+            // send seq complete callback
+            sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
+            msg->setPointer(kContextKey, cbh.mContext);
+            msg->setObject(kSessionSpKey, cbh.mSession);
+            msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
+            msg->setInt32(kSequenceIdKey, sequenceId);
+            msg->setInt64(kFrameNumberKey, lastFrameNumber);
+
+            // Clear the session sp before we send out the message
+            // This will guarantee the rare case where the message is processed
+            // before cbh goes out of scope and causing we call the session
+            // destructor while holding device lock
+            cbh.mSession.clear();
+            postSessionMsgAndCleanup(msg);
+        }
+
+        // No need to track sequence complete if there is no callback registered
+        if (seqCompleted || !hasCallback) {
+            it = mSequenceLastFrameNumberMap.erase(it);
+        } else {
+            ++it;
+        }
+    }
+}
+
+void CameraDevice::stopLooper() {
+    Mutex::Autolock _l(mDeviceLock);
+    if (mCbLooper != nullptr) {
+      mCbLooper->unregisterHandler(mHandler->id());
+      mCbLooper->stop();
+    }
+    mCbLooper.clear();
+    mHandler.clear();
+}
+
+/**
+  * Camera service callback implementation
+  */
+android::hardware::Return<void>
+CameraDevice::ServiceCallback::onDeviceError(
+        ErrorCode errorCode,
+        const CaptureResultExtras& resultExtras) {
+    ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d"
+            " physical camera ID %s", errorCode, resultExtras.frameNumber, resultExtras.requestId,
+            resultExtras.burstId, resultExtras.errorPhysicalCameraId.c_str());
+    auto ret = Void();
+    sp<CameraDevice> dev = mDevice.promote();
+    if (dev == nullptr) {
+        return ret; // device has been closed
+    }
+
+    sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
+    Mutex::Autolock _l(dev->mDeviceLock);
+    if (dev->mRemote == nullptr) {
+        return ret; // device has been closed
+    }
+    switch (errorCode) {
+        case ErrorCode::CAMERA_DISCONNECTED:
+        {
+            // Camera is disconnected, close the session and expect no more callbacks
+            if (session != nullptr) {
+                session->closeByDevice();
+            }
+            dev->mCurrentSession = nullptr;
+            sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
+            msg->setPointer(kContextKey, dev->mAppCallbacks.context);
+            msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
+            msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
+            msg->post();
+            break;
+        }
+        default:
+            ALOGE("Unknown error from camera device: %d", errorCode);
+            [[fallthrough]];
+        case ErrorCode::CAMERA_DEVICE:
+        case ErrorCode::CAMERA_SERVICE:
+        {
+            int32_t errorVal = ::ERROR_CAMERA_DEVICE;
+            // We keep this switch since this block might be encountered with
+            // more than just 2 states. The default fallthrough could have us
+            // handling more unmatched error cases.
+            switch (errorCode) {
+                case ErrorCode::CAMERA_DEVICE:
+                    dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
+                    break;
+                case ErrorCode::CAMERA_SERVICE:
+                    dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
+                    errorVal = ::ERROR_CAMERA_SERVICE;
+                    break;
+                default:
+                    dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
+                    break;
+            }
+            sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
+            msg->setPointer(kContextKey, dev->mAppCallbacks.context);
+            msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
+            msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
+            msg->setInt32(kErrorCodeKey, errorVal);
+            msg->post();
+            break;
+        }
+        case ErrorCode::CAMERA_REQUEST:
+        case ErrorCode::CAMERA_RESULT:
+        case ErrorCode::CAMERA_BUFFER:
+            dev->onCaptureErrorLocked(errorCode, resultExtras);
+            break;
+    }
+    return ret;
+}
+
+android::hardware::Return<void>
+CameraDevice::ServiceCallback::onDeviceIdle() {
+    ALOGV("Camera is now idle");
+    auto ret = Void();
+    sp<CameraDevice> dev = mDevice.promote();
+    if (dev == nullptr) {
+        return ret; // device has been closed
+    }
+
+    Mutex::Autolock _l(dev->mDeviceLock);
+    if (dev->isClosed() || dev->mRemote == nullptr) {
+        return ret;
+    }
+
+    if (dev->mIdle) {
+        // Already in idle state. Possibly other thread did waitUntilIdle
+        return ret;
+    }
+
+    if (dev->mCurrentSession != nullptr) {
+        ALOGE("onDeviceIdle sending state cb");
+        if (dev->mBusySession != dev->mCurrentSession) {
+            ALOGE("Current session != busy session");
+            dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
+            return ret;
+        }
+
+        sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
+        msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
+        msg->setObject(kSessionSpKey, dev->mBusySession);
+        msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
+        // Make sure we clear the sp first so the session destructor can
+        // only happen on handler thread (where we don't hold device/session lock)
+        dev->mBusySession.clear();
+        dev->postSessionMsgAndCleanup(msg);
+    }
+    dev->mIdle = true;
+    dev->mFlushing = false;
+    return ret;
+}
+
+android::hardware::Return<void>
+CameraDevice::ServiceCallback::onCaptureStarted(
+        const CaptureResultExtras& resultExtras,
+        uint64_t timestamp) {
+    auto ret = Void();
+
+    sp<CameraDevice> dev = mDevice.promote();
+    if (dev == nullptr) {
+        return ret; // device has been closed
+    }
+    Mutex::Autolock _l(dev->mDeviceLock);
+    if (dev->isClosed() || dev->mRemote == nullptr) {
+        return ret;
+    }
+
+    int32_t sequenceId = resultExtras.requestId;
+    int32_t burstId = resultExtras.burstId;
+
+    auto it = dev->mSequenceCallbackMap.find(sequenceId);
+    if (it != dev->mSequenceCallbackMap.end()) {
+        CallbackHolder cbh = (*it).second;
+        ACameraCaptureSession_captureCallback_start onStart = cbh.mOnCaptureStarted;
+        sp<ACameraCaptureSession> session = cbh.mSession;
+        if ((size_t) burstId >= cbh.mRequests.size()) {
+            ALOGE("%s: Error: request index %d out of bound (size %zu)",
+                    __FUNCTION__, burstId, cbh.mRequests.size());
+            dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
+        }
+        sp<CaptureRequest> request = cbh.mRequests[burstId];
+        sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
+        msg->setPointer(kContextKey, cbh.mContext);
+        msg->setObject(kSessionSpKey, session);
+        msg->setPointer(kCallbackFpKey, (void*) onStart);
+        msg->setObject(kCaptureRequestKey, request);
+        msg->setInt64(kTimeStampKey, timestamp);
+        dev->postSessionMsgAndCleanup(msg);
+    }
+    return ret;
+}
+
+android::hardware::Return<void>
+CameraDevice::ServiceCallback::onResultReceived(
+        const FmqSizeOrMetadata& resultMetadata,
+        const CaptureResultExtras& resultExtras,
+        const hidl_vec<PhysicalCaptureResultInfo>& physicalResultInfos) {
+    auto ret = Void();
+
+    sp<CameraDevice> dev = mDevice.promote();
+    if (dev == nullptr) {
+        return ret; // device has been closed
+    }
+    int32_t sequenceId = resultExtras.requestId;
+    int64_t frameNumber = resultExtras.frameNumber;
+    int32_t burstId = resultExtras.burstId;
+    bool    isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
+
+    if (!isPartialResult) {
+        ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
+    }
+
+    Mutex::Autolock _l(dev->mDeviceLock);
+    if (dev->mRemote == nullptr) {
+        return ret; // device has been disconnected
+    }
+
+    if (dev->isClosed()) {
+        if (!isPartialResult) {
+            dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
+        }
+        // early return to avoid callback sent to closed devices
+        return ret;
+    }
+
+    CameraMetadata metadataCopy;
+    camera_status_t status = readOneResultMetadata(resultMetadata,
+            dev->mCaptureResultMetadataQueue.get(), &metadataCopy);
+    if (status != ACAMERA_OK) {
+        ALOGE("%s: result metadata couldn't be converted", __FUNCTION__);
+        return ret;
+    }
+
+    metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
+    metadataCopy.update(ANDROID_SYNC_FRAME_NUMBER, &frameNumber, /*data_count*/1);
+
+    auto it = dev->mSequenceCallbackMap.find(sequenceId);
+    if (it != dev->mSequenceCallbackMap.end()) {
+        CallbackHolder cbh = (*it).second;
+        sp<ACameraCaptureSession> session = cbh.mSession;
+        if ((size_t) burstId >= cbh.mRequests.size()) {
+            ALOGE("%s: Error: request index %d out of bound (size %zu)",
+                    __FUNCTION__, burstId, cbh.mRequests.size());
+            dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
+        }
+        sp<CaptureRequest> request = cbh.mRequests[burstId];
+        sp<ACameraMetadata> result(new ACameraMetadata(
+                metadataCopy.release(), ACameraMetadata::ACM_RESULT));
+
+        std::vector<PhysicalCaptureResultInfoLocal> localPhysicalResult;
+        localPhysicalResult.resize(physicalResultInfos.size());
+        for (size_t i = 0; i < physicalResultInfos.size(); i++) {
+            localPhysicalResult[i].physicalCameraId = physicalResultInfos[i].physicalCameraId;
+            status = readOneResultMetadata(physicalResultInfos[i].physicalCameraMetadata,
+                    dev->mCaptureResultMetadataQueue.get(),
+                    &localPhysicalResult[i].physicalMetadata);
+            if (status != ACAMERA_OK) {
+                ALOGE("%s: physical camera result metadata couldn't be converted", __FUNCTION__);
+                return ret;
+            }
+        }
+        sp<ACameraPhysicalCaptureResultInfo> physicalResult(
+                new ACameraPhysicalCaptureResultInfo(localPhysicalResult, frameNumber));
+
+        sp<AMessage> msg = new AMessage(
+                cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureResult : kWhatCaptureResult,
+                dev->mHandler);
+        msg->setPointer(kContextKey, cbh.mContext);
+        msg->setObject(kSessionSpKey, session);
+        msg->setObject(kCaptureRequestKey, request);
+        msg->setObject(kCaptureResultKey, result);
+        if (isPartialResult) {
+            msg->setPointer(kCallbackFpKey,
+                    (void *)cbh.mOnCaptureProgressed);
+        } else if (cbh.mIsLogicalCameraCallback) {
+            msg->setPointer(kCallbackFpKey,
+                    (void *)cbh.mOnLogicalCameraCaptureCompleted);
+            msg->setObject(kPhysicalCaptureResultKey, physicalResult);
+        } else {
+            msg->setPointer(kCallbackFpKey,
+                    (void *)cbh.mOnCaptureCompleted);
+        }
+        dev->postSessionMsgAndCleanup(msg);
+    }
+
+    if (!isPartialResult) {
+        dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
+        dev->checkAndFireSequenceCompleteLocked();
+    }
+
+    return ret;
+}
+
+android::hardware::Return<void>
+CameraDevice::ServiceCallback::onRepeatingRequestError(
+        uint64_t lastFrameNumber, int32_t stoppedSequenceId) {
+    auto ret = Void();
+
+    sp<CameraDevice> dev = mDevice.promote();
+    if (dev == nullptr) {
+        return ret; // device has been closed
+    }
+
+    Mutex::Autolock _l(dev->mDeviceLock);
+
+    int repeatingSequenceId = dev->mRepeatingSequenceId;
+    if (stoppedSequenceId == repeatingSequenceId) {
+        dev->mRepeatingSequenceId = REQUEST_ID_NONE;
+    }
+
+    dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
+
+    return ret;
+}
+
+camera_status_t CameraDevice::ServiceCallback::readOneResultMetadata(
+        const FmqSizeOrMetadata& fmqSizeOrMetadata, ResultMetadataQueue* metadataQueue,
+        CameraMetadata* metadata) {
+    if (metadataQueue == nullptr || metadata == nullptr) {
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+    bool converted;
+    HCameraMetadata hCameraMetadata;
+    if (fmqSizeOrMetadata.getDiscriminator() ==
+            FmqSizeOrMetadata::hidl_discriminator::fmqMetadataSize) {
+        hCameraMetadata.resize(fmqSizeOrMetadata.fmqMetadataSize());
+        bool read = metadataQueue->read(
+                hCameraMetadata.data(), fmqSizeOrMetadata.fmqMetadataSize());
+        if (!read) {
+            ALOGE("%s capture request settings could't be read from fmq", __FUNCTION__);
+            return ACAMERA_ERROR_UNKNOWN;
+        }
+        // TODO: Do we actually need to clone here ?
+        converted = utils::convertFromHidlCloned(hCameraMetadata, metadata);
+    } else {
+        converted = utils::convertFromHidlCloned(fmqSizeOrMetadata.metadata(), metadata);
+    }
+
+    return converted ? ACAMERA_OK : ACAMERA_ERROR_UNKNOWN;
+}
+
+} // namespace acam
+} // namespace android
diff --git a/camera/ndk/ndk_vendor/impl/ACameraDevice.h b/camera/ndk/ndk_vendor/impl/ACameraDevice.h
new file mode 100644
index 0000000..3328a85
--- /dev/null
+++ b/camera/ndk/ndk_vendor/impl/ACameraDevice.h
@@ -0,0 +1,434 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef _ACAMERA_DEVICE_H
+#define _ACAMERA_DEVICE_H
+
+#include <memory>
+#include <map>
+#include <set>
+#include <atomic>
+#include <utility>
+#include <vector>
+#include <utils/StrongPointer.h>
+#include <utils/Mutex.h>
+#include <utils/List.h>
+#include <utils/Vector.h>
+#include <android/frameworks/cameraservice/device/2.0/ICameraDeviceUser.h>
+#include <android/frameworks/cameraservice/device/2.0/ICameraDeviceCallback.h>
+#include <android/frameworks/cameraservice/device/2.0/types.h>
+#include <fmq/MessageQueue.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/foundation/AHandler.h>
+#include <media/stagefright/foundation/AMessage.h>
+
+#include <camera/NdkCameraManager.h>
+#include <camera/NdkCameraCaptureSession.h>
+#include "ACameraMetadata.h"
+#include "utils.h"
+
+namespace android {
+namespace acam {
+
+using ICameraDeviceCallback = frameworks::cameraservice::device::V2_0::ICameraDeviceCallback;
+using ICameraDeviceUser = frameworks::cameraservice::device::V2_0::ICameraDeviceUser;
+using CaptureResultExtras = frameworks::cameraservice::device::V2_0::CaptureResultExtras;
+using PhysicalCaptureResultInfo = frameworks::cameraservice::device::V2_0::PhysicalCaptureResultInfo;
+using PhysicalCameraSettings = frameworks::cameraservice::device::V2_0::PhysicalCameraSettings;
+using SubmitInfo = frameworks::cameraservice::device::V2_0::SubmitInfo;
+using CaptureResultExtras = frameworks::cameraservice::device::V2_0::CaptureResultExtras;
+using ErrorCode = frameworks::cameraservice::device::V2_0::ErrorCode;
+using FmqSizeOrMetadata = frameworks::cameraservice::device::V2_0::FmqSizeOrMetadata;
+using StreamConfigurationMode = frameworks::cameraservice::device::V2_0::StreamConfigurationMode;
+using Status = frameworks::cameraservice::common::V2_0::Status;
+using ResultMetadataQueue = hardware::MessageQueue<uint8_t, hardware::kSynchronizedReadWrite>;
+using RequestMetadataQueue = hardware::MessageQueue<uint8_t, hardware::kSynchronizedReadWrite>;
+using CameraStatusAndId = frameworks::cameraservice::service::V2_0::CameraStatusAndId;
+
+using hardware::hidl_vec;
+using hardware::hidl_string;
+using utils::native_handle_ptr_wrapper;
+using utils::CaptureRequest;
+using utils::OutputConfigurationWrapper;
+
+// Wrap ACameraCaptureFailure so it can be ref-counted
+struct CameraCaptureFailure : public RefBase, public ACameraCaptureFailure { };
+
+// Wrap PhysicalCaptureResultInfo so that it can be ref-counted
+struct PhysicalCaptureResultInfoLocal {
+    std::string physicalCameraId;
+    CameraMetadata physicalMetadata;
+};
+
+struct ACameraPhysicalCaptureResultInfo: public RefBase {
+    ACameraPhysicalCaptureResultInfo(const std::vector<PhysicalCaptureResultInfoLocal>& info,
+            int64_t frameNumber) :
+        mPhysicalResultInfo(info), mFrameNumber(frameNumber) {}
+
+    std::vector<PhysicalCaptureResultInfoLocal> mPhysicalResultInfo;
+    int64_t mFrameNumber;
+};
+
+class CameraDevice final : public RefBase {
+  public:
+    CameraDevice(const char* id, ACameraDevice_StateCallbacks* cb,
+                  sp<ACameraMetadata> chars,
+                  ACameraDevice* wrapper);
+    ~CameraDevice();
+
+    inline const char* getId() const { return mCameraId.c_str(); }
+
+    camera_status_t createCaptureRequest(
+            ACameraDevice_request_template templateId,
+            const ACameraIdList* physicalCameraIdList,
+            ACaptureRequest** request) const;
+
+    camera_status_t createCaptureSession(
+            const ACaptureSessionOutputContainer*       outputs,
+            const ACaptureRequest* sessionParameters,
+            const ACameraCaptureSession_stateCallbacks* callbacks,
+            /*out*/ACameraCaptureSession** session);
+
+    camera_status_t isSessionConfigurationSupported(
+            const ACaptureSessionOutputContainer* sessionOutputContainer) const;
+
+    // Callbacks from camera service
+    class ServiceCallback : public ICameraDeviceCallback {
+      public:
+        explicit ServiceCallback(CameraDevice* device) : mDevice(device) {}
+        android::hardware::Return<void> onDeviceError(ErrorCode errorCode,
+                           const CaptureResultExtras& resultExtras) override;
+        android::hardware::Return<void> onDeviceIdle() override;
+        android::hardware::Return<void> onCaptureStarted(const CaptureResultExtras& resultExtras,
+                              uint64_t timestamp) override;
+        android::hardware::Return<void> onResultReceived(const FmqSizeOrMetadata& result,
+                              const CaptureResultExtras& resultExtras,
+                              const hidl_vec<PhysicalCaptureResultInfo>& physicalResultInfos) override;
+        android::hardware::Return<void> onRepeatingRequestError(uint64_t lastFrameNumber,
+                int32_t stoppedSequenceId) override;
+      private:
+        camera_status_t readOneResultMetadata(const FmqSizeOrMetadata& fmqSizeOrMetadata,
+                ResultMetadataQueue* metadataQueue, CameraMetadata* metadata);
+        const wp<CameraDevice> mDevice;
+    };
+    inline sp<ICameraDeviceCallback> getServiceCallback() {
+        return mServiceCallback;
+    };
+
+    // Camera device is only functional after remote being set
+    void setRemoteDevice(sp<ICameraDeviceUser> remote);
+
+    bool setDeviceMetadataQueues();
+    inline ACameraDevice* getWrapper() const { return mWrapper; };
+
+    // Stop the looper thread and unregister the handler
+    void stopLooper();
+
+  private:
+    friend ACameraCaptureSession;
+
+    camera_status_t checkCameraClosedOrErrorLocked() const;
+
+    // device goes into fatal error state after this
+    void setCameraDeviceErrorLocked(camera_status_t error);
+
+    void disconnectLocked(sp<ACameraCaptureSession>& session); // disconnect from camera service
+
+    camera_status_t stopRepeatingLocked();
+
+    camera_status_t flushLocked(ACameraCaptureSession*);
+
+    camera_status_t waitUntilIdleLocked();
+
+    template<class T>
+    camera_status_t captureLocked(sp<ACameraCaptureSession> session,
+            /*optional*/T* cbs,
+            int numRequests, ACaptureRequest** requests,
+            /*optional*/int* captureSequenceId);
+
+    template<class T>
+    camera_status_t setRepeatingRequestsLocked(sp<ACameraCaptureSession> session,
+            /*optional*/T* cbs,
+            int numRequests, ACaptureRequest** requests,
+            /*optional*/int* captureSequenceId);
+
+    template<class T>
+    camera_status_t submitRequestsLocked(
+            sp<ACameraCaptureSession> session,
+            /*optional*/T* cbs,
+            int numRequests, ACaptureRequest** requests,
+            /*out*/int* captureSequenceId,
+            bool isRepeating);
+
+    void addRequestSettingsMetadata(ACaptureRequest *aCaptureRequest, sp<CaptureRequest> &req);
+
+    camera_status_t updateOutputConfigurationLocked(ACaptureSessionOutput *output);
+
+    // Since this writes to ICameraDeviceUser's fmq, clients must take care that:
+    //   a) This function is called serially.
+    //   b) This function is called in accordance with ICameraDeviceUser.submitRequestList,
+    //      otherwise, the wrong capture request might have the wrong settings
+    //      metadata associated with it.
+    camera_status_t allocateCaptureRequestLocked(
+            const ACaptureRequest* request, sp<CaptureRequest>& outReq);
+    void allocateOneCaptureRequestMetadata(
+            PhysicalCameraSettings& cameraSettings,
+            const std::string& id, const sp<ACameraMetadata>& metadata);
+
+    static ACaptureRequest* allocateACaptureRequest(sp<CaptureRequest>& req, const char* deviceId);
+    static void freeACaptureRequest(ACaptureRequest*);
+
+    // only For session to hold device lock
+    // Always grab device lock before grabbing session lock
+    void lockDeviceForSessionOps() const { mDeviceLock.lock(); };
+    void unlockDevice() const { mDeviceLock.unlock(); };
+
+    // For capture session to notify its end of life
+    void notifySessionEndOfLifeLocked(ACameraCaptureSession* session);
+
+    camera_status_t configureStreamsLocked(const ACaptureSessionOutputContainer* outputs,
+           const ACaptureRequest* sessionParameters);
+
+    // Input message will be posted and cleared after this returns
+    void postSessionMsgAndCleanup(sp<AMessage>& msg);
+
+    mutable Mutex mDeviceLock;
+    const hidl_string mCameraId;                          // Camera ID
+    const ACameraDevice_StateCallbacks mAppCallbacks; // Callback to app
+    const sp<ACameraMetadata> mChars;    // Camera characteristics
+    const sp<ServiceCallback> mServiceCallback;
+    ACameraDevice* mWrapper;
+
+    // stream id -> pair of (ACameraWindowType* from application, OutputConfiguration used for
+    // camera service)
+    std::map<int, std::pair<native_handle_ptr_wrapper, OutputConfigurationWrapper>> mConfiguredOutputs;
+
+    // TODO: maybe a bool will suffice for synchronous implementation?
+    std::atomic_bool mClosing;
+    inline bool isClosed() { return mClosing; }
+
+    bool mInError = false;
+    camera_status_t mError = ACAMERA_OK;
+    void onCaptureErrorLocked(
+            ErrorCode errorCode,
+            const CaptureResultExtras& resultExtras);
+
+    bool mIdle = true;
+    // This will avoid a busy session being deleted before it's back to idle state
+    sp<ACameraCaptureSession> mBusySession;
+
+    sp<ICameraDeviceUser> mRemote;
+
+    // Looper thread to handle callback to app
+    sp<ALooper> mCbLooper;
+    // definition of handler and message
+    enum {
+        // Device state callbacks
+        kWhatOnDisconnected,   // onDisconnected
+        kWhatOnError,          // onError
+        // Session state callbacks
+        kWhatSessionStateCb,   // onReady, onActive
+        // Capture callbacks
+        kWhatCaptureStart,     // onCaptureStarted
+        kWhatCaptureResult,    // onCaptureProgressed, onCaptureCompleted
+        kWhatLogicalCaptureResult, // onLogicalCameraCaptureCompleted
+        kWhatCaptureFail,      // onCaptureFailed
+        kWhatLogicalCaptureFail, // onLogicalCameraCaptureFailed
+        kWhatCaptureSeqEnd,    // onCaptureSequenceCompleted
+        kWhatCaptureSeqAbort,  // onCaptureSequenceAborted
+        kWhatCaptureBufferLost,// onCaptureBufferLost
+        // Internal cleanup
+        kWhatCleanUpSessions   // Cleanup cached sp<ACameraCaptureSession>
+    };
+    static const char* kContextKey;
+    static const char* kDeviceKey;
+    static const char* kErrorCodeKey;
+    static const char* kCallbackFpKey;
+    static const char* kSessionSpKey;
+    static const char* kCaptureRequestKey;
+    static const char* kTimeStampKey;
+    static const char* kCaptureResultKey;
+    static const char* kPhysicalCaptureResultKey;
+    static const char* kCaptureFailureKey;
+    static const char* kSequenceIdKey;
+    static const char* kFrameNumberKey;
+    static const char* kAnwKey;
+    static const char* kFailingPhysicalCameraId;
+
+    class CallbackHandler : public AHandler {
+      public:
+        explicit CallbackHandler(const char *id);
+        void onMessageReceived(const sp<AMessage> &msg) override;
+
+      private:
+        std::string mId;
+        // This handler will cache all capture session sp until kWhatCleanUpSessions
+        // is processed. This is used to guarantee the last session reference is always
+        // being removed in callback thread without holding camera device lock
+        Vector<sp<ACameraCaptureSession>> mCachedSessions;
+    };
+    sp<CallbackHandler> mHandler;
+
+    /***********************************
+     * Capture session related members *
+     ***********************************/
+    // The current active session
+    wp<ACameraCaptureSession> mCurrentSession;
+    bool mFlushing = false;
+
+    int mNextSessionId = 0;
+    // TODO: might need another looper/handler to handle callbacks from service
+
+    static const int REQUEST_ID_NONE = -1;
+    int mRepeatingSequenceId = REQUEST_ID_NONE;
+
+    // sequence id -> last frame number map
+    std::map<int32_t, int64_t> mSequenceLastFrameNumberMap;
+
+    struct CallbackHolder {
+        CallbackHolder(sp<ACameraCaptureSession>          session,
+                       const Vector<sp<CaptureRequest>>&  requests,
+                       bool                               isRepeating,
+                       ACameraCaptureSession_captureCallbacks* cbs);
+        CallbackHolder(sp<ACameraCaptureSession>          session,
+                       const Vector<sp<CaptureRequest>>&  requests,
+                       bool                               isRepeating,
+                       ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs);
+
+        template <class T>
+        void initCaptureCallbacks(T* cbs) {
+            mContext = nullptr;
+            mOnCaptureStarted = nullptr;
+            mOnCaptureProgressed = nullptr;
+            mOnCaptureCompleted = nullptr;
+            mOnLogicalCameraCaptureCompleted = nullptr;
+            mOnLogicalCameraCaptureFailed = nullptr;
+            mOnCaptureFailed = nullptr;
+            mOnCaptureSequenceCompleted = nullptr;
+            mOnCaptureSequenceAborted = nullptr;
+            mOnCaptureBufferLost = nullptr;
+            if (cbs != nullptr) {
+                mContext = cbs->context;
+                mOnCaptureStarted = cbs->onCaptureStarted;
+                mOnCaptureProgressed = cbs->onCaptureProgressed;
+                mOnCaptureSequenceCompleted = cbs->onCaptureSequenceCompleted;
+                mOnCaptureSequenceAborted = cbs->onCaptureSequenceAborted;
+                mOnCaptureBufferLost = cbs->onCaptureBufferLost;
+            }
+        }
+
+        sp<ACameraCaptureSession>   mSession;
+        Vector<sp<CaptureRequest>>  mRequests;
+        const bool                  mIsRepeating;
+        const bool                  mIsLogicalCameraCallback;
+
+        void*                       mContext;
+        ACameraCaptureSession_captureCallback_start mOnCaptureStarted;
+        ACameraCaptureSession_captureCallback_result mOnCaptureProgressed;
+        ACameraCaptureSession_captureCallback_result mOnCaptureCompleted;
+        ACameraCaptureSession_logicalCamera_captureCallback_result mOnLogicalCameraCaptureCompleted;
+        ACameraCaptureSession_logicalCamera_captureCallback_failed mOnLogicalCameraCaptureFailed;
+        ACameraCaptureSession_captureCallback_failed mOnCaptureFailed;
+        ACameraCaptureSession_captureCallback_sequenceEnd mOnCaptureSequenceCompleted;
+        ACameraCaptureSession_captureCallback_sequenceAbort mOnCaptureSequenceAborted;
+        ACameraCaptureSession_captureCallback_bufferLost mOnCaptureBufferLost;
+    };
+    // sequence id -> callbacks map
+    std::map<int, CallbackHolder> mSequenceCallbackMap;
+
+    static const int64_t NO_FRAMES_CAPTURED = -1;
+    class FrameNumberTracker {
+      public:
+        // TODO: Called in onResultReceived and onCaptureErrorLocked
+        void updateTracker(int64_t frameNumber, bool isError);
+        inline int64_t getCompletedFrameNumber() { return mCompletedFrameNumber; }
+      private:
+        void update();
+        void updateCompletedFrameNumber(int64_t frameNumber);
+
+        int64_t mCompletedFrameNumber = NO_FRAMES_CAPTURED;
+        List<int64_t> mSkippedFrameNumbers;
+        std::set<int64_t> mFutureErrorSet;
+    };
+    FrameNumberTracker mFrameNumberTracker;
+
+    void checkRepeatingSequenceCompleteLocked(const int sequenceId, const int64_t lastFrameNumber);
+    void checkAndFireSequenceCompleteLocked();
+
+    // Misc variables
+    int32_t mShadingMapSize[2];   // const after constructor
+    int32_t mPartialResultCount;  // const after constructor
+    std::shared_ptr<ResultMetadataQueue> mCaptureRequestMetadataQueue = nullptr;
+    std::shared_ptr<ResultMetadataQueue> mCaptureResultMetadataQueue = nullptr;
+};
+
+} // namespace acam;
+} // namespace android;
+
+/**
+ * ACameraDevice opaque struct definition
+ * Leave outside of android namespace because it's NDK struct
+ */
+struct ACameraDevice {
+    ACameraDevice(const char* id, ACameraDevice_StateCallbacks* cb,
+                  sp<ACameraMetadata> chars) :
+            mDevice(new android::acam::CameraDevice(id, cb, std::move(chars), this)) {}
+
+    ~ACameraDevice();
+
+    /*******************
+     * NDK public APIs *
+     *******************/
+    inline const char* getId() const { return mDevice->getId(); }
+
+    camera_status_t createCaptureRequest(
+            ACameraDevice_request_template templateId,
+            const ACameraIdList* physicalCameraIdList,
+            ACaptureRequest** request) const {
+        return mDevice->createCaptureRequest(templateId, physicalCameraIdList, request);
+    }
+
+    camera_status_t createCaptureSession(
+            const ACaptureSessionOutputContainer*       outputs,
+            const ACaptureRequest* sessionParameters,
+            const ACameraCaptureSession_stateCallbacks* callbacks,
+            /*out*/ACameraCaptureSession** session) {
+        return mDevice->createCaptureSession(outputs, sessionParameters, callbacks, session);
+    }
+
+    camera_status_t isSessionConfigurationSupported(
+            const ACaptureSessionOutputContainer* sessionOutputContainer) const {
+        return mDevice->isSessionConfigurationSupported(sessionOutputContainer);
+    }
+
+    /***********************
+     * Device interal APIs *
+     ***********************/
+    inline android::sp<android::acam::ICameraDeviceCallback> getServiceCallback() {
+        return mDevice->getServiceCallback();
+    };
+
+    // Camera device is only functional after remote being set
+    inline void setRemoteDevice(android::sp<android::acam::ICameraDeviceUser> remote) {
+        mDevice->setRemoteDevice(remote);
+    }
+    inline bool setDeviceMetadataQueues() {
+        return mDevice->setDeviceMetadataQueues();
+    }
+  private:
+    android::sp<android::acam::CameraDevice> mDevice;
+};
+
+#endif // _ACAMERA_DEVICE_H
diff --git a/camera/ndk/ndk_vendor/impl/ACameraDeviceVendor.inc b/camera/ndk/ndk_vendor/impl/ACameraDeviceVendor.inc
new file mode 100644
index 0000000..8bd5a52
--- /dev/null
+++ b/camera/ndk/ndk_vendor/impl/ACameraDeviceVendor.inc
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <vector>
+#include <inttypes.h>
+#include <android/frameworks/cameraservice/service/2.0/ICameraService.h>
+#include <android/frameworks/cameraservice/device/2.0/types.h>
+#include <CameraMetadata.h>
+
+#include "ndk_vendor/impl/ACameraDevice.h"
+#include "ACameraCaptureSession.h"
+#include "ACameraMetadata.h"
+#include "ACaptureRequest.h"
+#include "utils.h"
+
+using namespace android;
+
+namespace android {
+namespace acam {
+
+template<class T>
+camera_status_t
+CameraDevice::captureLocked(
+        sp<ACameraCaptureSession> session,
+        /*optional*/T* cbs,
+        int numRequests, ACaptureRequest** requests,
+        /*optional*/int* captureSequenceId) {
+    return submitRequestsLocked(
+            session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/false);
+}
+
+template<class T>
+camera_status_t
+CameraDevice::setRepeatingRequestsLocked(
+        sp<ACameraCaptureSession> session,
+        /*optional*/T* cbs,
+        int numRequests, ACaptureRequest** requests,
+        /*optional*/int* captureSequenceId) {
+    return submitRequestsLocked(
+            session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/true);
+}
+
+template<class T>
+camera_status_t CameraDevice::submitRequestsLocked(
+        sp<ACameraCaptureSession> session,
+        /*optional*/T* cbs,
+        int numRequests, ACaptureRequest** requests,
+        /*out*/int* captureSequenceId,
+        bool isRepeating)
+{
+    camera_status_t ret = checkCameraClosedOrErrorLocked();
+    if (ret != ACAMERA_OK) {
+        ALOGE("Camera %s submit capture request failed! ret %d", getId(), ret);
+        return ret;
+    }
+
+    // Form two vectors of capture request, one for internal tracking
+    std::vector<frameworks::cameraservice::device::V2_0::CaptureRequest> requestList;
+    Vector<sp<CaptureRequest>> requestsV;
+    requestsV.setCapacity(numRequests);
+    for (int i = 0; i < numRequests; i++) {
+        sp<CaptureRequest> req;
+        ret = allocateCaptureRequestLocked(requests[i], req);
+        // We need to call this method since after submitRequestList is called,
+        // the request metadata queue might have removed the capture request
+        // metadata. Therefore we simply add the metadata to its wrapper class,
+        // so that it can be retrieved later.
+        addRequestSettingsMetadata(requests[i], req);
+        if (ret != ACAMERA_OK) {
+            ALOGE("Convert capture request to internal format failure! ret %d", ret);
+            return ret;
+        }
+        if (req->mCaptureRequest.streamAndWindowIds.size() == 0) {
+            ALOGE("Capture request without output target cannot be submitted!");
+            return ACAMERA_ERROR_INVALID_PARAMETER;
+        }
+        requestList.push_back(utils::convertToHidl(req.get()));
+        requestsV.push_back(req);
+    }
+    if (isRepeating) {
+        ret = stopRepeatingLocked();
+        if (ret != ACAMERA_OK) {
+            ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
+            return ret;
+        }
+    }
+
+    SubmitInfo info;
+    Status status;
+    auto remoteRet = mRemote->submitRequestList(requestList, isRepeating,
+                                                [&status, &info](auto s, auto &submitInfo) {
+                                                    status = s;
+                                                    info = submitInfo;
+                                                });
+    if (!remoteRet.isOk()) {
+        ALOGE("%s: Transaction error for submitRequestList call: %s", __FUNCTION__,
+              remoteRet.description().c_str());
+    }
+    if (status != Status::NO_ERROR) {
+        return utils::convertFromHidl(status);
+    }
+    int32_t sequenceId = info.requestId;
+    int64_t lastFrameNumber = info.lastFrameNumber;
+    if (sequenceId < 0) {
+        ALOGE("Camera %s submit request remote failure: ret %d", getId(), sequenceId);
+        return ACAMERA_ERROR_UNKNOWN;
+    }
+
+    CallbackHolder cbHolder(session, requestsV, isRepeating, cbs);
+    mSequenceCallbackMap.insert(std::make_pair(sequenceId, cbHolder));
+    if (isRepeating) {
+        // stopRepeating above should have cleanup repeating sequence id
+        if (mRepeatingSequenceId != REQUEST_ID_NONE) {
+            setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
+            return ACAMERA_ERROR_CAMERA_DEVICE;
+        }
+        mRepeatingSequenceId = sequenceId;
+    } else {
+        mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
+    }
+
+    if (mIdle) {
+        sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
+        msg->setPointer(kContextKey, session->mUserSessionCallback.context);
+        msg->setObject(kSessionSpKey, session);
+        msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
+        postSessionMsgAndCleanup(msg);
+    }
+    mIdle = false;
+    mBusySession = session;
+
+    if (captureSequenceId) {
+        *captureSequenceId = sequenceId;
+    }
+    return ACAMERA_OK;
+}
+
+} // namespace acam
+} // namespace android
diff --git a/camera/ndk/ndk_vendor/impl/ACameraManager.cpp b/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
new file mode 100644
index 0000000..70c887a
--- /dev/null
+++ b/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
@@ -0,0 +1,614 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ACameraManagerVendor"
+
+#include <memory>
+#include "ndk_vendor/impl/ACameraManager.h"
+#include "ACameraMetadata.h"
+#include "ndk_vendor/impl/ACameraDevice.h"
+#include "utils.h"
+#include <CameraMetadata.h>
+#include <camera_metadata_hidden.h>
+
+#include <utils/Vector.h>
+#include <cutils/properties.h>
+#include <stdlib.h>
+
+#include <VendorTagDescriptor.h>
+
+using namespace android::acam;
+
+namespace android {
+namespace acam {
+
+using frameworks::cameraservice::service::V2_0::CameraStatusAndId;
+using frameworks::cameraservice::common::V2_0::ProviderIdAndVendorTagSections;
+using android::hardware::camera::common::V1_0::helper::VendorTagDescriptor;
+using android::hardware::camera::common::V1_0::helper::VendorTagDescriptorCache;
+
+// Static member definitions
+const char* CameraManagerGlobal::kCameraIdKey   = "CameraId";
+const char* CameraManagerGlobal::kCallbackFpKey = "CallbackFp";
+const char* CameraManagerGlobal::kContextKey    = "CallbackContext";
+Mutex                CameraManagerGlobal::sLock;
+CameraManagerGlobal* CameraManagerGlobal::sInstance = nullptr;
+
+/**
+ * The vendor tag descriptor class that takes HIDL vendor tag information as
+ * input. Not part of vendor available VendorTagDescriptor class because that class is used by
+ * default HAL implementation code as well.
+ */
+class HidlVendorTagDescriptor : public VendorTagDescriptor {
+public:
+    /**
+     * Create a VendorTagDescriptor object from the HIDL VendorTagSection
+     * vector.
+     *
+     * Returns OK on success, or a negative error code.
+     */
+    static status_t createDescriptorFromHidl(const hidl_vec<VendorTagSection>& vts,
+                                             /*out*/ sp<VendorTagDescriptor> *descriptor);
+};
+
+status_t HidlVendorTagDescriptor::createDescriptorFromHidl(const hidl_vec<VendorTagSection> &vts,
+                                                           sp<VendorTagDescriptor> *descriptor) {
+    int tagCount = 0;
+
+    for (size_t s = 0; s < vts.size(); s++) {
+        tagCount += vts[s].tags.size();
+    }
+
+    if (tagCount < 0 || tagCount > INT32_MAX) {
+        ALOGE("%s: tag count %d from vendor tag sections is invalid.", __FUNCTION__, tagCount);
+        return BAD_VALUE;
+    }
+
+    Vector<uint32_t> tagArray;
+    LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
+            "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
+
+    sp<HidlVendorTagDescriptor> desc = new HidlVendorTagDescriptor();
+    desc->mTagCount = tagCount;
+
+    KeyedVector<uint32_t, String8> tagToSectionMap;
+
+    int idx = 0;
+    for (size_t s = 0; s < vts.size(); s++) {
+        const VendorTagSection& section = vts[s];
+        const char *sectionName = section.sectionName.c_str();
+        if (sectionName == NULL) {
+            ALOGE("%s: no section name defined for vendor tag section %zu.", __FUNCTION__, s);
+            return BAD_VALUE;
+        }
+        String8 sectionString(sectionName);
+        desc->mSections.add(sectionString);
+
+        for (size_t j = 0; j < section.tags.size(); j++) {
+            uint32_t tag = section.tags[j].tagId;
+            if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
+                ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
+                return BAD_VALUE;
+            }
+
+            tagArray.editItemAt(idx++) = section.tags[j].tagId;
+
+            const char *tagName = section.tags[j].tagName.c_str();
+            if (tagName == NULL) {
+                ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
+                return BAD_VALUE;
+            }
+            desc->mTagToNameMap.add(tag, String8(tagName));
+            tagToSectionMap.add(tag, sectionString);
+
+            int tagType = (int) section.tags[j].tagType;
+            if (tagType < 0 || tagType >= NUM_TYPES) {
+                ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
+                return BAD_VALUE;
+            }
+            desc->mTagToTypeMap.emplace(tag, tagType);
+        }
+    }
+
+    for (size_t i = 0; i < tagArray.size(); ++i) {
+        uint32_t tag = tagArray[i];
+        String8 sectionString = tagToSectionMap.valueFor(tag);
+
+        // Set up tag to section index map
+        ssize_t index = desc->mSections.indexOf(sectionString);
+        LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
+        desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
+
+        // Set up reverse mapping
+        ssize_t reverseIndex = -1;
+        if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
+            KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
+            reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
+        }
+        desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
+    }
+
+    *descriptor = std::move(desc);
+    return OK;
+}
+
+CameraManagerGlobal&
+CameraManagerGlobal::getInstance() {
+    Mutex::Autolock _l(sLock);
+    CameraManagerGlobal* instance = sInstance;
+    if (instance == nullptr) {
+        instance = new CameraManagerGlobal();
+        sInstance = instance;
+    }
+    return *instance;
+}
+
+CameraManagerGlobal::~CameraManagerGlobal() {
+    // clear sInstance so next getInstance call knows to create a new one
+    Mutex::Autolock _sl(sLock);
+    sInstance = nullptr;
+    Mutex::Autolock _l(mLock);
+    if (mCameraService != nullptr) {
+        mCameraService->unlinkToDeath(mDeathNotifier);
+        mCameraService->removeListener(mCameraServiceListener);
+    }
+    mDeathNotifier.clear();
+    if (mCbLooper != nullptr) {
+        mCbLooper->unregisterHandler(mHandler->id());
+        mCbLooper->stop();
+    }
+    mCbLooper.clear();
+    mHandler.clear();
+    mCameraServiceListener.clear();
+    mCameraService.clear();
+}
+
+static bool isCameraServiceDisabled() {
+    char value[PROPERTY_VALUE_MAX];
+    property_get("config.disable_cameraservice", value, "0");
+    return (strncmp(value, "0", 2) != 0 && strncasecmp(value, "false", 6) != 0);
+}
+
+bool CameraManagerGlobal::setupVendorTags() {
+    sp<VendorTagDescriptorCache> tagCache = new VendorTagDescriptorCache();
+    Status status = Status::NO_ERROR;
+    std::vector<ProviderIdAndVendorTagSections> providerIdsAndVts;
+    auto remoteRet = mCameraService->getCameraVendorTagSections([&status, &providerIdsAndVts]
+                                                                 (Status s,
+                                                                  auto &IdsAndVts) {
+                                                         status = s;
+                                                         providerIdsAndVts = IdsAndVts; });
+
+    if (!remoteRet.isOk() || status != Status::NO_ERROR) {
+        ALOGE("Failed to retrieve VendorTagSections %s", remoteRet.description().c_str());
+        return false;
+    }
+    // Convert each providers VendorTagSections into a VendorTagDescriptor and
+    // add it to the cache
+    for (auto &providerIdAndVts : providerIdsAndVts) {
+        sp<VendorTagDescriptor> vendorTagDescriptor;
+        if (HidlVendorTagDescriptor::createDescriptorFromHidl(providerIdAndVts.vendorTagSections,
+                                                              &vendorTagDescriptor) != OK) {
+            ALOGE("Failed to convert from Hidl: VendorTagDescriptor");
+            return false;
+        }
+        tagCache->addVendorDescriptor(providerIdAndVts.providerId, vendorTagDescriptor);
+    }
+    VendorTagDescriptorCache::setAsGlobalVendorTagCache(tagCache);
+    return true;
+}
+
+sp<ICameraService> CameraManagerGlobal::getCameraService() {
+    Mutex::Autolock _l(mLock);
+    if (mCameraService.get() == nullptr) {
+        if (isCameraServiceDisabled()) {
+            return mCameraService;
+        }
+
+        sp<ICameraService> cameraServiceBinder;
+        do {
+            cameraServiceBinder = ICameraService::getService();
+            if (cameraServiceBinder != nullptr) {
+                break;
+            }
+            ALOGW("CameraService not published, waiting...");
+            usleep(kCameraServicePollDelay);
+        } while(true);
+        if (mDeathNotifier == nullptr) {
+            mDeathNotifier = new DeathNotifier(this);
+        }
+        cameraServiceBinder->linkToDeath(mDeathNotifier, 0);
+        mCameraService = cameraServiceBinder;
+
+        // Setup looper thread to perfrom availiability callbacks
+        if (mCbLooper == nullptr) {
+            mCbLooper = new ALooper;
+            mCbLooper->setName("C2N-mgr-looper");
+            status_t err = mCbLooper->start(
+                    /*runOnCallingThread*/false,
+                    /*canCallJava*/       true,
+                    PRIORITY_DEFAULT);
+            if (err != OK) {
+                ALOGE("%s: Unable to start camera service listener looper: %s (%d)",
+                        __FUNCTION__, strerror(-err), err);
+                mCbLooper.clear();
+                return nullptr;
+            }
+            if (mHandler == nullptr) {
+                mHandler = new CallbackHandler();
+            }
+            mCbLooper->registerHandler(mHandler);
+        }
+
+        // register ICameraServiceListener
+        if (mCameraServiceListener == nullptr) {
+            mCameraServiceListener = new CameraServiceListener(this);
+        }
+        hidl_vec<CameraStatusAndId> cameraStatuses{};
+        Status status = Status::NO_ERROR;
+        auto remoteRet = mCameraService->addListener(mCameraServiceListener,
+                                                     [&status, &cameraStatuses](Status s,
+                                                                                auto &retStatuses) {
+                                                         status = s;
+                                                         cameraStatuses = retStatuses;
+                                                     });
+        if (!remoteRet.isOk() || status != Status::NO_ERROR) {
+            ALOGE("Failed to add listener to camera service %s", remoteRet.description().c_str());
+        }
+
+        // Setup vendor tags
+        if (!setupVendorTags()) {
+            ALOGE("Unable to set up vendor tags");
+            return nullptr;
+        }
+
+        for (auto& c : cameraStatuses) {
+            onStatusChangedLocked(c);
+        }
+    }
+    return mCameraService;
+}
+
+void CameraManagerGlobal::DeathNotifier::serviceDied(uint64_t cookie, const wp<IBase> &who) {
+    (void) cookie;
+    (void) who;
+    ALOGE("Camera service binderDied!");
+    sp<CameraManagerGlobal> cm = mCameraManager.promote();
+    if (cm != nullptr) {
+        AutoMutex lock(cm->mLock);
+        for (auto& pair : cm->mDeviceStatusMap) {
+            CameraStatusAndId cameraStatusAndId;
+            cameraStatusAndId.cameraId = pair.first;
+            cameraStatusAndId.deviceStatus = pair.second;
+            cm->onStatusChangedLocked(cameraStatusAndId);
+        }
+        cm->mCameraService.clear();
+        // TODO: consider adding re-connect call here?
+    }
+}
+
+void CameraManagerGlobal::registerAvailabilityCallback(
+        const ACameraManager_AvailabilityCallbacks *callback) {
+    Mutex::Autolock _l(mLock);
+    Callback cb(callback);
+    auto pair = mCallbacks.insert(cb);
+    // Send initial callbacks if callback is newly registered
+    if (pair.second) {
+        for (auto& pair : mDeviceStatusMap) {
+            const hidl_string& cameraId = pair.first;
+            CameraDeviceStatus status = pair.second;
+
+            sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
+            ACameraManager_AvailabilityCallback cb = isStatusAvailable(status) ?
+                    callback->onCameraAvailable : callback->onCameraUnavailable;
+            msg->setPointer(kCallbackFpKey, (void *) cb);
+            msg->setPointer(kContextKey, callback->context);
+            msg->setString(kCameraIdKey, AString(cameraId.c_str()));
+            msg->post();
+        }
+    }
+}
+
+void CameraManagerGlobal::unregisterAvailabilityCallback(
+        const ACameraManager_AvailabilityCallbacks *callback) {
+    Mutex::Autolock _l(mLock);
+    Callback cb(callback);
+    mCallbacks.erase(cb);
+}
+
+void CameraManagerGlobal::getCameraIdList(std::vector<hidl_string>* cameraIds) {
+    // Ensure that we have initialized/refreshed the list of available devices
+    auto cs = getCameraService();
+    Mutex::Autolock _l(mLock);
+
+    for(auto& deviceStatus : mDeviceStatusMap) {
+        if (deviceStatus.second == CameraDeviceStatus::STATUS_NOT_PRESENT ||
+                deviceStatus.second == CameraDeviceStatus::STATUS_ENUMERATING) {
+            continue;
+        }
+        cameraIds->push_back(deviceStatus.first);
+    }
+}
+
+bool CameraManagerGlobal::validStatus(CameraDeviceStatus status) {
+    switch (status) {
+        case CameraDeviceStatus::STATUS_NOT_PRESENT:
+        case CameraDeviceStatus::STATUS_PRESENT:
+        case CameraDeviceStatus::STATUS_ENUMERATING:
+        case CameraDeviceStatus::STATUS_NOT_AVAILABLE:
+            return true;
+        default:
+            return false;
+    }
+}
+
+bool CameraManagerGlobal::isStatusAvailable(CameraDeviceStatus status) {
+    switch (status) {
+        case CameraDeviceStatus::STATUS_PRESENT:
+            return true;
+        default:
+            return false;
+    }
+}
+
+void CameraManagerGlobal::CallbackHandler::onMessageReceived(
+        const sp<AMessage> &msg) {
+    switch (msg->what()) {
+        case kWhatSendSingleCallback:
+        {
+            ACameraManager_AvailabilityCallback cb;
+            void* context;
+            AString cameraId;
+            bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
+            if (!found) {
+                ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
+                return;
+            }
+            found = msg->findPointer(kContextKey, &context);
+            if (!found) {
+                ALOGE("%s: Cannot find callback context!", __FUNCTION__);
+                return;
+            }
+            found = msg->findString(kCameraIdKey, &cameraId);
+            if (!found) {
+                ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
+                return;
+            }
+            (*cb)(context, cameraId.c_str());
+            break;
+        }
+        default:
+            ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what());
+            break;
+    }
+}
+
+hardware::Return<void> CameraManagerGlobal::CameraServiceListener::onStatusChanged(
+        const CameraStatusAndId &statusAndId) {
+    sp<CameraManagerGlobal> cm = mCameraManager.promote();
+    if (cm != nullptr) {
+        cm->onStatusChanged(statusAndId);
+    } else {
+        ALOGE("Cannot deliver status change. Global camera manager died");
+    }
+    return Void();
+}
+
+void CameraManagerGlobal::onStatusChanged(
+        const CameraStatusAndId &statusAndId) {
+    Mutex::Autolock _l(mLock);
+    onStatusChangedLocked(statusAndId);
+}
+
+void CameraManagerGlobal::onStatusChangedLocked(
+        const CameraStatusAndId &statusAndId) {
+    hidl_string cameraId = statusAndId.cameraId;
+    CameraDeviceStatus status = statusAndId.deviceStatus;
+    if (!validStatus(status)) {
+        ALOGE("%s: Invalid status %d", __FUNCTION__, status);
+        return;
+    }
+
+    bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0);
+    CameraDeviceStatus oldStatus = firstStatus ?
+            status : // first status
+            mDeviceStatusMap[cameraId];
+
+    if (!firstStatus &&
+            isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
+        // No status update. No need to send callback
+        return;
+    }
+
+    // Iterate through all registered callbacks
+    mDeviceStatusMap[cameraId] = status;
+    for (auto cb : mCallbacks) {
+        sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
+        ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
+                cb.mAvailable : cb.mUnavailable;
+        msg->setPointer(kCallbackFpKey, (void *) cbFp);
+        msg->setPointer(kContextKey, cb.mContext);
+        msg->setString(kCameraIdKey, AString(cameraId.c_str()));
+        msg->post();
+    }
+    if (status == CameraDeviceStatus::STATUS_NOT_PRESENT) {
+        mDeviceStatusMap.erase(cameraId);
+    }
+}
+
+} // namespace acam
+} // namespace android
+
+/**
+ * ACameraManger Implementation
+ */
+camera_status_t
+ACameraManager::getCameraIdList(ACameraIdList** cameraIdList) {
+    Mutex::Autolock _l(mLock);
+
+    std::vector<hidl_string> idList;
+    CameraManagerGlobal::getInstance().getCameraIdList(&idList);
+
+    int numCameras = idList.size();
+    ACameraIdList *out = new ACameraIdList;
+    if (!out) {
+        ALOGE("Allocate memory for ACameraIdList failed!");
+        return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
+    }
+    out->numCameras = numCameras;
+    out->cameraIds = new const char*[numCameras];
+    if (!out->cameraIds) {
+        ALOGE("Allocate memory for ACameraIdList failed!");
+        deleteCameraIdList(out);
+        return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
+    }
+    for (int i = 0; i < numCameras; i++) {
+        const char* src = idList[i].c_str();
+        size_t dstSize = strlen(src) + 1;
+        char* dst = new char[dstSize];
+        if (!dst) {
+            ALOGE("Allocate memory for ACameraIdList failed!");
+            deleteCameraIdList(out);
+            return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
+        }
+        strlcpy(dst, src, dstSize);
+        out->cameraIds[i] = dst;
+    }
+    *cameraIdList = out;
+    return ACAMERA_OK;
+}
+
+void
+ACameraManager::deleteCameraIdList(ACameraIdList* cameraIdList) {
+    if (cameraIdList != nullptr) {
+        if (cameraIdList->cameraIds != nullptr) {
+            for (int i = 0; i < cameraIdList->numCameras; i ++) {
+                if (cameraIdList->cameraIds[i] != nullptr) {
+                    delete[] cameraIdList->cameraIds[i];
+                }
+            }
+            delete[] cameraIdList->cameraIds;
+        }
+        delete cameraIdList;
+    }
+}
+
+camera_status_t ACameraManager::getCameraCharacteristics(
+        const char *cameraIdStr, sp<ACameraMetadata> *characteristics) {
+    Mutex::Autolock _l(mLock);
+
+    sp<ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
+    if (cs == nullptr) {
+        ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
+        return ACAMERA_ERROR_CAMERA_DISCONNECTED;
+    }
+    CameraMetadata rawMetadata;
+    Status status = Status::NO_ERROR;
+    auto serviceRet =
+        cs->getCameraCharacteristics(cameraIdStr,
+                                     [&status, &rawMetadata] (auto s ,
+                                                              const hidl_vec<uint8_t> &metadata) {
+                                          status = s;
+                                          if (status == Status::NO_ERROR) {
+                                              utils::convertFromHidlCloned(metadata, &rawMetadata);
+                                          }
+                                     });
+    if (!serviceRet.isOk() || status != Status::NO_ERROR) {
+        ALOGE("Get camera characteristics from camera service failed");
+        return ACAMERA_ERROR_UNKNOWN; // should not reach here
+    }
+
+    *characteristics = new ACameraMetadata(
+            rawMetadata.release(), ACameraMetadata::ACM_CHARACTERISTICS);
+    return ACAMERA_OK;
+}
+
+camera_status_t
+ACameraManager::openCamera(
+        const char* cameraId,
+        ACameraDevice_StateCallbacks* callback,
+        /*out*/ACameraDevice** outDevice) {
+    sp<ACameraMetadata> rawChars;
+    camera_status_t ret = getCameraCharacteristics(cameraId, &rawChars);
+    Mutex::Autolock _l(mLock);
+    if (ret != ACAMERA_OK) {
+        ALOGE("%s: cannot get camera characteristics for camera %s. err %d",
+                __FUNCTION__, cameraId, ret);
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+
+    ACameraDevice* device = new ACameraDevice(cameraId, callback, std::move(rawChars));
+
+    sp<ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
+    if (cs == nullptr) {
+        ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
+        delete device;
+        return ACAMERA_ERROR_CAMERA_DISCONNECTED;
+    }
+
+    sp<ICameraDeviceCallback> callbacks = device->getServiceCallback();
+    sp<ICameraDeviceUser> deviceRemote;
+
+    // No way to get package name from native.
+    // Send a zero length package name and let camera service figure it out from UID
+    Status status = Status::NO_ERROR;
+    auto serviceRet = cs->connectDevice(
+            callbacks, cameraId, [&status, &deviceRemote](auto s, auto &device) {
+                                     status = s;
+                                     deviceRemote = device;
+                                 });
+
+    if (!serviceRet.isOk() || status != Status::NO_ERROR) {
+        ALOGE("%s: connect camera device failed", __FUNCTION__);
+        // TODO: Convert serviceRet to camera_status_t
+        delete device;
+        return ACAMERA_ERROR_UNKNOWN;
+    }
+    if (deviceRemote == nullptr) {
+        ALOGE("%s: connect camera device failed! remote device is null", __FUNCTION__);
+        delete device;
+        return ACAMERA_ERROR_CAMERA_DISCONNECTED;
+    }
+    device->setRemoteDevice(deviceRemote);
+    device->setDeviceMetadataQueues();
+    *outDevice = device;
+    return ACAMERA_OK;
+}
+
+camera_status_t
+ACameraManager::getTagFromName(const char *cameraId, const char *name, uint32_t *tag) {
+    sp<ACameraMetadata> rawChars;
+    camera_status_t ret = getCameraCharacteristics(cameraId, &rawChars);
+    if (ret != ACAMERA_OK) {
+        ALOGE("%s, Cannot retrieve camera characteristics for camera id %s", __FUNCTION__,
+                cameraId);
+        return ACAMERA_ERROR_METADATA_NOT_FOUND;
+    }
+    const CameraMetadata& metadata = rawChars->getInternalData();
+    const camera_metadata_t *rawMetadata = metadata.getAndLock();
+    metadata_vendor_id_t vendorTagId = get_camera_metadata_vendor_id(rawMetadata);
+    metadata.unlock(rawMetadata);
+    sp<VendorTagDescriptorCache> vtCache = VendorTagDescriptorCache::getGlobalVendorTagCache();
+    sp<VendorTagDescriptor> vTags = nullptr;
+    vtCache->getVendorTagDescriptor(vendorTagId, &vTags);
+    status_t status= metadata.getTagFromName(name, vTags.get(), tag);
+    return status == OK ? ACAMERA_OK : ACAMERA_ERROR_METADATA_NOT_FOUND;
+}
+
+ACameraManager::~ACameraManager() {
+
+}
diff --git a/camera/ndk/ndk_vendor/impl/ACameraManager.h b/camera/ndk/ndk_vendor/impl/ACameraManager.h
new file mode 100644
index 0000000..2c62d44
--- /dev/null
+++ b/camera/ndk/ndk_vendor/impl/ACameraManager.h
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ACAMERA_MANAGER_H
+#define _ACAMERA_MANAGER_H
+
+#include <camera/NdkCameraManager.h>
+
+#include <android-base/parseint.h>
+#include <android/frameworks/cameraservice/service/2.0/ICameraService.h>
+
+#include <CameraMetadata.h>
+#include <utils/StrongPointer.h>
+#include <utils/Mutex.h>
+
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/foundation/AHandler.h>
+#include <media/stagefright/foundation/AMessage.h>
+
+#include <set>
+#include <map>
+
+namespace android {
+namespace acam {
+
+using ICameraService = frameworks::cameraservice::service::V2_0::ICameraService;
+using CameraDeviceStatus = frameworks::cameraservice::service::V2_0::CameraDeviceStatus;
+using ICameraServiceListener = frameworks::cameraservice::service::V2_0::ICameraServiceListener;
+using CameraStatusAndId = frameworks::cameraservice::service::V2_0::CameraStatusAndId;
+using Status = frameworks::cameraservice::common::V2_0::Status;
+using VendorTagSection = frameworks::cameraservice::common::V2_0::VendorTagSection;
+using VendorTag = frameworks::cameraservice::common::V2_0::VendorTag;
+using IBase = android::hidl::base::V1_0::IBase;
+using android::hardware::hidl_string;
+using hardware::Void;
+
+/**
+ * Per-process singleton instance of CameraManger. Shared by all ACameraManager
+ * instances. Created when first ACameraManager is created and destroyed when
+ * all ACameraManager instances are deleted.
+ *
+ * TODO: maybe CameraManagerGlobal is better suited in libcameraclient?
+ */
+class CameraManagerGlobal final : public RefBase {
+  public:
+    static CameraManagerGlobal& getInstance();
+    sp<ICameraService> getCameraService();
+
+    void registerAvailabilityCallback(
+            const ACameraManager_AvailabilityCallbacks *callback);
+    void unregisterAvailabilityCallback(
+            const ACameraManager_AvailabilityCallbacks *callback);
+
+    void registerExtendedAvailabilityCallback(
+            const ACameraManager_ExtendedAvailabilityCallbacks* /*callback*/) {}
+    void unregisterExtendedAvailabilityCallback(
+            const ACameraManager_ExtendedAvailabilityCallbacks* /*callback*/) {}
+
+    /**
+     * Return camera IDs that support camera2
+     */
+    void getCameraIdList(std::vector<hidl_string> *cameraIds);
+
+  private:
+    sp<ICameraService> mCameraService;
+    const int          kCameraServicePollDelay = 500000; // 0.5s
+    Mutex              mLock;
+    class DeathNotifier : public android::hardware::hidl_death_recipient {
+      public:
+        explicit DeathNotifier(CameraManagerGlobal* cm) : mCameraManager(cm) {}
+      protected:
+        // IBinder::DeathRecipient implementation
+        virtual void serviceDied(uint64_t cookie, const wp<IBase> &who);
+      private:
+        const wp<CameraManagerGlobal> mCameraManager;
+    };
+    sp<DeathNotifier> mDeathNotifier;
+
+    class CameraServiceListener final : public ICameraServiceListener {
+      public:
+        explicit CameraServiceListener(CameraManagerGlobal* cm) : mCameraManager(cm) {}
+        android::hardware::Return<void> onStatusChanged(
+            const CameraStatusAndId &statusAndId) override;
+
+      private:
+        const wp<CameraManagerGlobal> mCameraManager;
+    };
+    sp<CameraServiceListener> mCameraServiceListener;
+
+    // Wrapper of ACameraManager_AvailabilityCallbacks so we can store it in std::set
+    struct Callback {
+        explicit Callback(const ACameraManager_AvailabilityCallbacks *callback) :
+            mAvailable(callback->onCameraAvailable),
+            mUnavailable(callback->onCameraUnavailable),
+            mContext(callback->context) {}
+
+        bool operator == (const Callback& other) const {
+            return (mAvailable == other.mAvailable &&
+                    mUnavailable == other.mUnavailable &&
+                    mContext == other.mContext);
+        }
+        bool operator != (const Callback& other) const {
+            return !(*this == other);
+        }
+        bool operator < (const Callback& other) const {
+            if (*this == other) return false;
+            if (mContext != other.mContext) return mContext < other.mContext;
+            if (mAvailable != other.mAvailable) return mAvailable < other.mAvailable;
+            return mUnavailable < other.mUnavailable;
+        }
+        bool operator > (const Callback& other) const {
+            return (*this != other && !(*this < other));
+        }
+        ACameraManager_AvailabilityCallback mAvailable;
+        ACameraManager_AvailabilityCallback mUnavailable;
+        void*                               mContext;
+    };
+    std::set<Callback> mCallbacks;
+
+    // definition of handler and message
+    enum {
+        kWhatSendSingleCallback
+    };
+    static const char* kCameraIdKey;
+    static const char* kCallbackFpKey;
+    static const char* kContextKey;
+    class CallbackHandler : public AHandler {
+      public:
+        CallbackHandler() {}
+        void onMessageReceived(const sp<AMessage> &msg) override;
+    };
+    sp<CallbackHandler> mHandler;
+    sp<ALooper>         mCbLooper; // Looper thread where callbacks actually happen on
+
+    void onStatusChanged(const CameraStatusAndId &statusAndId);
+    void onStatusChangedLocked(const CameraStatusAndId &statusAndId);
+    bool setupVendorTags();
+
+    // Utils for status
+    static bool validStatus(CameraDeviceStatus status);
+    static bool isStatusAvailable(CameraDeviceStatus status);
+
+    // The sort logic must match the logic in
+    // libcameraservice/common/CameraProviderManager.cpp::getAPI1CompatibleCameraDeviceIds
+    struct CameraIdComparator {
+        bool operator()(const hidl_string& a, const hidl_string& b) const {
+            uint32_t aUint = 0, bUint = 0;
+            bool aIsUint = base::ParseUint(a.c_str(), &aUint);
+            bool bIsUint = base::ParseUint(b.c_str(), &bUint);
+
+            // Uint device IDs first
+            if (aIsUint && bIsUint) {
+                return aUint < bUint;
+            } else if (aIsUint) {
+                return true;
+            } else if (bIsUint) {
+                return false;
+            }
+            // Simple string compare if both id are not uint
+            return a < b;
+        }
+    };
+
+    // Map camera_id -> status
+    std::map<hidl_string, CameraDeviceStatus, CameraIdComparator> mDeviceStatusMap;
+
+    // For the singleton instance
+    static Mutex sLock;
+    static CameraManagerGlobal* sInstance;
+    CameraManagerGlobal() {};
+    ~CameraManagerGlobal();
+};
+
+} // namespace acam;
+} // namespace android;
+
+/**
+ * ACameraManager opaque struct definition
+ * Leave outside of android namespace because it's NDK struct
+ */
+struct ACameraManager {
+    ACameraManager() :
+            mGlobalManager(&(android::acam::CameraManagerGlobal::getInstance())) {}
+    ~ACameraManager();
+    camera_status_t getCameraIdList(ACameraIdList** cameraIdList);
+    static void     deleteCameraIdList(ACameraIdList* cameraIdList);
+
+    camera_status_t getCameraCharacteristics(
+            const char* cameraId, android::sp<ACameraMetadata>* characteristics);
+
+    camera_status_t openCamera(const char* cameraId,
+                               ACameraDevice_StateCallbacks* callback,
+                               /*out*/ACameraDevice** device);
+    camera_status_t getTagFromName(const char *cameraId, const char *name, uint32_t *tag);
+
+  private:
+    enum {
+        kCameraIdListNotInit = -1
+    };
+    android::Mutex         mLock;
+    android::sp<android::acam::CameraManagerGlobal> mGlobalManager;
+};
+
+#endif //_ACAMERA_MANAGER_H
diff --git a/camera/ndk/ndk_vendor/impl/ACaptureRequestVendor.h b/camera/ndk/ndk_vendor/impl/ACaptureRequestVendor.h
new file mode 100644
index 0000000..ed67615
--- /dev/null
+++ b/camera/ndk/ndk_vendor/impl/ACaptureRequestVendor.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "utils.h"
+
+struct ACameraOutputTarget {
+    explicit ACameraOutputTarget(native_handle_t* window) : mWindow(window) {};
+
+    bool operator == (const ACameraOutputTarget& other) const {
+        return mWindow == other.mWindow;
+    }
+    bool operator != (const ACameraOutputTarget& other) const {
+        return mWindow != other.mWindow;
+    }
+    bool operator < (const ACameraOutputTarget& other) const {
+        return mWindow < other.mWindow;
+    }
+    bool operator > (const ACameraOutputTarget& other) const {
+        return mWindow > other.mWindow;
+    }
+
+    android::acam::utils::native_handle_ptr_wrapper mWindow;
+};
diff --git a/camera/ndk/ndk_vendor/impl/utils.cpp b/camera/ndk/ndk_vendor/impl/utils.cpp
new file mode 100644
index 0000000..e4fb204
--- /dev/null
+++ b/camera/ndk/ndk_vendor/impl/utils.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ACameraVendorUtils"
+
+#include <utils/Log.h>
+
+#include "utils.h"
+
+namespace android {
+namespace acam {
+namespace utils {
+
+// Convert CaptureRequest wrappable by sp<> to hidl CaptureRequest.
+frameworks::cameraservice::device::V2_0::CaptureRequest
+convertToHidl(const CaptureRequest *captureRequest) {
+    frameworks::cameraservice::device::V2_0::CaptureRequest hCaptureRequest;
+    hCaptureRequest.physicalCameraSettings = captureRequest->mCaptureRequest.physicalCameraSettings;
+    hCaptureRequest.streamAndWindowIds = captureRequest->mCaptureRequest.streamAndWindowIds;
+    return hCaptureRequest;
+}
+
+HRotation convertToHidl(int rotation) {
+    HRotation hRotation = HRotation::R0;
+    switch(rotation) {
+        case CAMERA3_STREAM_ROTATION_90:
+            hRotation = HRotation::R90;
+            break;
+        case CAMERA3_STREAM_ROTATION_180:
+            hRotation = HRotation::R180;
+            break;
+        case CAMERA3_STREAM_ROTATION_270:
+            hRotation = HRotation::R270;
+            break;
+        default:
+            break;
+    }
+    return hRotation;
+}
+
+bool convertFromHidlCloned(const HCameraMetadata &metadata, CameraMetadata *rawMetadata) {
+    const camera_metadata *buffer = (camera_metadata_t*)(metadata.data());
+    size_t expectedSize = metadata.size();
+    int ret = validate_camera_metadata_structure(buffer, &expectedSize);
+    if (ret == OK || ret == CAMERA_METADATA_VALIDATION_SHIFTED) {
+        *rawMetadata = buffer;
+    } else {
+        ALOGE("%s: Malformed camera metadata received from caller", __FUNCTION__);
+        return false;
+    }
+    return true;
+}
+
+// Note: existing data in dst will be gone. dst owns memory if shouldOwn is set
+//       to true.
+void convertToHidl(const camera_metadata_t *src, HCameraMetadata* dst, bool shouldOwn) {
+    if (src == nullptr) {
+        return;
+    }
+    size_t size = get_camera_metadata_size(src);
+    dst->setToExternal((uint8_t *) src, size, shouldOwn);
+    return;
+}
+
+TemplateId convertToHidl(ACameraDevice_request_template templateId) {
+    switch(templateId) {
+        case TEMPLATE_STILL_CAPTURE:
+            return TemplateId::STILL_CAPTURE;
+        case TEMPLATE_RECORD:
+            return TemplateId::RECORD;
+        case TEMPLATE_VIDEO_SNAPSHOT:
+            return TemplateId::VIDEO_SNAPSHOT;
+        case TEMPLATE_ZERO_SHUTTER_LAG:
+            return TemplateId::ZERO_SHUTTER_LAG;
+        case TEMPLATE_MANUAL:
+            return TemplateId::MANUAL;
+        default:
+            return TemplateId::PREVIEW;
+    }
+}
+
+camera_status_t convertFromHidl(Status status) {
+    camera_status_t ret = ACAMERA_OK;
+    switch(status) {
+        case Status::NO_ERROR:
+            break;
+        case Status::DISCONNECTED:
+            ret = ACAMERA_ERROR_CAMERA_DISCONNECTED;
+            break;
+        case Status::CAMERA_IN_USE:
+            ret = ACAMERA_ERROR_CAMERA_IN_USE;
+            break;
+        case Status::MAX_CAMERAS_IN_USE:
+            ret = ACAMERA_ERROR_MAX_CAMERA_IN_USE;
+            break;
+        case Status::ILLEGAL_ARGUMENT:
+            ret = ACAMERA_ERROR_INVALID_PARAMETER;
+            break;
+        case Status::DEPRECATED_HAL:
+            // Should not reach here since we filtered legacy HALs earlier
+            ret = ACAMERA_ERROR_INVALID_PARAMETER;
+            break;
+        case Status::DISABLED:
+            ret = ACAMERA_ERROR_CAMERA_DISABLED;
+            break;
+        case Status::PERMISSION_DENIED:
+            ret = ACAMERA_ERROR_PERMISSION_DENIED;
+            break;
+        case Status::INVALID_OPERATION:
+            ret = ACAMERA_ERROR_INVALID_OPERATION;
+            break;
+        default:
+            ret = ACAMERA_ERROR_UNKNOWN;
+            break;
+    }
+    return ret;
+}
+
+bool isWindowNativeHandleEqual(const native_handle_t *nh1, const native_handle_t *nh2) {
+    if (nh1->numFds !=0 || nh2->numFds !=0) {
+        ALOGE("Invalid window native handles being compared");
+        return false;
+    }
+    if (nh1->version != nh2->version || nh1->numFds != nh2->numFds ||
+        nh1->numInts != nh2->numInts) {
+        return false;
+    }
+    for (int i = 0; i < nh1->numInts; i++) {
+        if(nh1->data[i] != nh2->data[i]) {
+            return false;
+        }
+    }
+    return true;
+}
+
+bool isWindowNativeHandleLessThan(const native_handle_t *nh1, const native_handle_t *nh2) {
+    if (isWindowNativeHandleEqual(nh1, nh2)) {
+        return false;
+    }
+    if (nh1->numInts != nh2->numInts) {
+        return nh1->numInts < nh2->numInts;
+    }
+
+    for (int i = 0; i < nh1->numInts; i++) {
+        if (nh1->data[i] != nh2->data[i]) {
+            return nh1->data[i] < nh2->data[i];
+        }
+    }
+    return false;
+}
+
+bool isWindowNativeHandleGreaterThan(const native_handle_t *nh1, const native_handle_t *nh2) {
+    return !isWindowNativeHandleLessThan(nh1, nh2) && !isWindowNativeHandleEqual(nh1, nh2);
+}
+
+bool areWindowNativeHandlesEqual(hidl_vec<hidl_handle> handles1, hidl_vec<hidl_handle> handles2) {
+    if (handles1.size() != handles2.size()) {
+        return false;
+    }
+    for (int i = 0; i < handles1.size(); i++) {
+        if (!isWindowNativeHandleEqual(handles1[i], handles2[i])) {
+            return false;
+        }
+    }
+    return true;
+}
+
+bool areWindowNativeHandlesLessThan(hidl_vec<hidl_handle> handles1, hidl_vec<hidl_handle>handles2) {
+    if (handles1.size() != handles2.size()) {
+        return handles1.size() < handles2.size();
+    }
+    for (int i = 0; i < handles1.size(); i++) {
+        const native_handle_t *handle1 = handles1[i].getNativeHandle();
+        const native_handle_t *handle2 = handles2[i].getNativeHandle();
+        if (!isWindowNativeHandleEqual(handle1, handle2)) {
+            return isWindowNativeHandleLessThan(handle1, handle2);
+        }
+    }
+    return false;
+}
+
+} // namespace utils
+} // namespace acam
+} // namespace android
diff --git a/camera/ndk/ndk_vendor/impl/utils.h b/camera/ndk/ndk_vendor/impl/utils.h
new file mode 100644
index 0000000..f389f03
--- /dev/null
+++ b/camera/ndk/ndk_vendor/impl/utils.h
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/frameworks/cameraservice/service/2.0/ICameraService.h>
+#include <android/frameworks/cameraservice/device/2.0/ICameraDeviceUser.h>
+#include <android/frameworks/cameraservice/device/2.0/types.h>
+#include <camera/NdkCameraDevice.h>
+#include <CameraMetadata.h>
+#include <hardware/camera3.h>
+
+#ifndef CAMERA_NDK_VENDOR_H
+#define CAMERA_NDK_VENDOR_H
+
+using android::hardware::hidl_vec;
+using android::hardware::hidl_handle;
+
+namespace android {
+namespace acam {
+namespace utils {
+
+using CameraMetadata = hardware::camera::common::V1_0::helper::CameraMetadata;
+using HCameraMetadata  = frameworks::cameraservice::service::V2_0::CameraMetadata;
+using Status = frameworks::cameraservice::common::V2_0::Status;
+using TemplateId = frameworks::cameraservice::device::V2_0::TemplateId;
+using PhysicalCameraSettings = frameworks::cameraservice::device::V2_0::PhysicalCameraSettings;
+using HRotation = frameworks::cameraservice::device::V2_0::OutputConfiguration::Rotation;
+using OutputConfiguration = frameworks::cameraservice::device::V2_0::OutputConfiguration;
+
+// Utility class so that CaptureRequest can be stored by sp<>
+struct CaptureRequest : public RefBase {
+  frameworks::cameraservice::device::V2_0::CaptureRequest mCaptureRequest;
+  std::vector<native_handle_t *> mSurfaceList;
+  //Physical camera settings metadata is stored here, since the capture request
+  //might not contain it. That's since, fmq might have consumed it.
+  hidl_vec<PhysicalCameraSettings> mPhysicalCameraSettings;
+};
+
+bool areWindowNativeHandlesEqual(hidl_vec<hidl_handle> handles1, hidl_vec<hidl_handle>handles2);
+
+bool areWindowNativeHandlesLessThan(hidl_vec<hidl_handle> handles1, hidl_vec<hidl_handle>handles2);
+
+bool isWindowNativeHandleEqual(const native_handle_t *nh1, const native_handle_t *nh2);
+
+bool isWindowNativeHandleLessThan(const native_handle_t *nh1, const native_handle_t *nh2);
+
+// Convenience wrapper over isWindowNativeHandleLessThan and isWindowNativeHandleEqual
+bool isWindowNativeHandleGreaterThan(const native_handle_t *nh1, const native_handle_t *nh2);
+
+// Utility class so the native_handle_t can be compared with  its contents instead
+// of just raw pointer comparisons.
+struct native_handle_ptr_wrapper {
+    native_handle_t *mWindow = nullptr;
+
+    native_handle_ptr_wrapper(native_handle_t *nh) : mWindow(nh) { }
+
+    native_handle_ptr_wrapper() = default;
+
+    operator native_handle_t *() const { return mWindow; }
+
+    bool operator ==(const native_handle_ptr_wrapper other) const {
+        return isWindowNativeHandleEqual(mWindow, other.mWindow);
+    }
+
+    bool operator != (const native_handle_ptr_wrapper& other) const {
+        return !isWindowNativeHandleEqual(mWindow, other.mWindow);
+    }
+
+    bool operator < (const native_handle_ptr_wrapper& other) const {
+        return isWindowNativeHandleLessThan(mWindow, other.mWindow);
+    }
+
+    bool operator > (const native_handle_ptr_wrapper& other) const {
+        return !isWindowNativeHandleGreaterThan(mWindow, other.mWindow);
+    }
+
+};
+
+// Wrapper around OutputConfiguration. This is needed since HIDL
+// OutputConfiguration is auto-generated and marked final. Therefore, operator
+// overloads outside the class, will not get picked by clang while trying to
+// store OutputConfiguration in maps/sets.
+struct OutputConfigurationWrapper {
+    OutputConfiguration mOutputConfiguration;
+
+    operator const OutputConfiguration &() const {
+        return mOutputConfiguration;
+    }
+
+    OutputConfigurationWrapper() {
+        mOutputConfiguration.rotation = OutputConfiguration::Rotation::R0;
+        // The ndk currently doesn't support deferred surfaces
+        mOutputConfiguration.isDeferred = false;
+        mOutputConfiguration.width = 0;
+        mOutputConfiguration.height = 0;
+        // ndk doesn't support inter OutputConfiguration buffer sharing.
+        mOutputConfiguration.windowGroupId = -1;
+    };
+
+    OutputConfigurationWrapper(OutputConfiguration &outputConfiguration)
+            : mOutputConfiguration((outputConfiguration)) { }
+
+    bool operator ==(const OutputConfiguration &other) const {
+        const OutputConfiguration &self = mOutputConfiguration;
+        return self.rotation == other.rotation && self.windowGroupId == other.windowGroupId &&
+                self.physicalCameraId == other.physicalCameraId && self.width == other.width &&
+                self.height == other.height && self.isDeferred == other.isDeferred &&
+                areWindowNativeHandlesEqual(self.windowHandles, other.windowHandles);
+    }
+
+    bool operator < (const OutputConfiguration &other) const {
+        if (*this == other) {
+            return false;
+        }
+        const OutputConfiguration &self = mOutputConfiguration;
+        if (self.windowGroupId != other.windowGroupId) {
+            return self.windowGroupId < other.windowGroupId;
+        }
+
+        if (self.width != other.width) {
+            return self.width < other.width;
+        }
+
+        if (self.height != other.height) {
+            return self.height < other.height;
+        }
+
+        if (self.rotation != other.rotation) {
+            return static_cast<uint32_t>(self.rotation) < static_cast<uint32_t>(other.rotation);
+        }
+
+        if (self.isDeferred != other.isDeferred) {
+            return self.isDeferred < other.isDeferred;
+        }
+
+        if (self.physicalCameraId != other.physicalCameraId) {
+            return self.physicalCameraId < other.physicalCameraId;
+        }
+        return areWindowNativeHandlesLessThan(self.windowHandles, other.windowHandles);
+    }
+
+    bool operator != (const OutputConfiguration &other) const {
+        return !(*this == other);
+    }
+
+    bool operator > (const OutputConfiguration &other) const {
+        return (*this != other) && !(*this < other);
+    }
+};
+
+// Convert CaptureRequest wrappable by sp<> to hidl CaptureRequest.
+frameworks::cameraservice::device::V2_0::CaptureRequest convertToHidl(
+    const CaptureRequest *captureRequest);
+
+HRotation convertToHidl(int rotation);
+
+bool convertFromHidlCloned(const HCameraMetadata &metadata, CameraMetadata *rawMetadata);
+
+// Note: existing data in dst will be gone.
+void convertToHidl(const camera_metadata_t *src, HCameraMetadata* dst, bool shouldOwn = false);
+
+TemplateId convertToHidl(ACameraDevice_request_template templateId);
+
+camera_status_t convertFromHidl(Status status);
+
+} // namespace utils
+} // namespace acam
+} // namespace android
+
+#endif // CAMERA_NDK_VENDOR_H
diff --git a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
new file mode 100644
index 0000000..37de30a
--- /dev/null
+++ b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
@@ -0,0 +1,826 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AImageReaderVendorTest"
+//#define LOG_NDEBUG 0
+
+#include <stdint.h>
+#include <unistd.h>
+#include <gtest/gtest.h>
+
+#include <algorithm>
+#include <mutex>
+#include <string>
+#include <vector>
+#include <stdio.h>
+#include <stdio.h>
+#include <stdio.h>
+
+#include <android/log.h>
+#include <camera/NdkCameraError.h>
+#include <camera/NdkCameraManager.h>
+#include <camera/NdkCameraDevice.h>
+#include <camera/NdkCameraCaptureSession.h>
+#include <media/NdkImage.h>
+#include <media/NdkImageReader.h>
+#include <cutils/native_handle.h>
+#include <VendorTagDescriptor.h>
+
+namespace {
+
+static constexpr int kDummyFenceFd = -1;
+static constexpr int kCaptureWaitUs = 100 * 1000;
+static constexpr int kCaptureWaitRetry = 10;
+static constexpr int kTestImageWidth = 640;
+static constexpr int kTestImageHeight = 480;
+static constexpr int kTestImageFormat = AIMAGE_FORMAT_YUV_420_888;
+
+using android::hardware::camera::common::V1_0::helper::VendorTagDescriptorCache;
+
+class CameraHelper {
+   public:
+    CameraHelper(const char* id, ACameraManager *manager) :
+            mImgReaderAnw(nullptr), mCameraId(id), mCameraManager(manager) {}
+    ~CameraHelper() { closeCamera(); }
+
+    struct PhysicalImgReaderInfo {
+        const char* physicalCameraId;
+        native_handle_t* anw;
+    };
+    int initCamera(native_handle_t* imgReaderAnw,
+            const std::vector<PhysicalImgReaderInfo>& physicalImgReaders,
+            bool usePhysicalSettings) {
+        if (imgReaderAnw == nullptr) {
+            ALOGE("Cannot initialize camera before image reader get initialized.");
+            return -1;
+        }
+        if (mIsCameraReady) {
+            ALOGE("initCamera should only be called once.");
+            return -1;
+        }
+
+        int ret;
+        mImgReaderAnw = imgReaderAnw;
+
+        ret = ACameraManager_openCamera(mCameraManager, mCameraId, &mDeviceCb, &mDevice);
+        if (ret != AMEDIA_OK || mDevice == nullptr) {
+            ALOGE("Failed to open camera, ret=%d, mDevice=%p.", ret, mDevice);
+            return -1;
+        }
+
+        // Create capture session
+        ret = ACaptureSessionOutputContainer_create(&mOutputs);
+        if (ret != AMEDIA_OK) {
+            ALOGE("ACaptureSessionOutputContainer_create failed, ret=%d", ret);
+            return ret;
+        }
+        ret = ACaptureSessionOutput_create(mImgReaderAnw, &mImgReaderOutput);
+        if (ret != AMEDIA_OK) {
+            ALOGE("ACaptureSessionOutput_create failed, ret=%d", ret);
+            return ret;
+        }
+        ret = ACaptureSessionOutputContainer_add(mOutputs, mImgReaderOutput);
+        if (ret != AMEDIA_OK) {
+            ALOGE("ACaptureSessionOutputContainer_add failed, ret=%d", ret);
+            return ret;
+        }
+
+        std::vector<const char*> idPointerList;
+        for (auto& physicalStream : physicalImgReaders) {
+            ACaptureSessionOutput* sessionOutput = nullptr;
+            ret = ACaptureSessionPhysicalOutput_create(physicalStream.anw,
+                    physicalStream.physicalCameraId, &sessionOutput);
+            if (ret != ACAMERA_OK) {
+                ALOGE("ACaptureSessionPhysicalOutput_create failed, ret=%d", ret);
+                return ret;
+            }
+            ret = ACaptureSessionOutputContainer_add(mOutputs, sessionOutput);
+            if (ret != AMEDIA_OK) {
+                ALOGE("ACaptureSessionOutputContainer_add failed, ret=%d", ret);
+                return ret;
+            }
+            mExtraOutputs.push_back(sessionOutput);
+            // Assume that at most one physical stream per physical camera.
+            mPhysicalCameraIds.push_back(physicalStream.physicalCameraId);
+            idPointerList.push_back(physicalStream.physicalCameraId);
+        }
+        ACameraIdList cameraIdList;
+        cameraIdList.numCameras = idPointerList.size();
+        cameraIdList.cameraIds = idPointerList.data();
+
+        ret = ACameraDevice_isSessionConfigurationSupported(mDevice, mOutputs);
+        if (ret != ACAMERA_OK && ret != ACAMERA_ERROR_UNSUPPORTED_OPERATION) {
+            ALOGE("ACameraDevice_isSessionConfigurationSupported failed, ret=%d", ret);
+            return ret;
+        }
+
+        ret = ACameraDevice_createCaptureSession(mDevice, mOutputs, &mSessionCb, &mSession);
+        if (ret != AMEDIA_OK) {
+            ALOGE("ACameraDevice_createCaptureSession failed, ret=%d", ret);
+            return ret;
+        }
+
+        // Create capture request
+        if (usePhysicalSettings) {
+            ret = ACameraDevice_createCaptureRequest_withPhysicalIds(mDevice,
+                    TEMPLATE_STILL_CAPTURE, &cameraIdList, &mStillRequest);
+        } else {
+            ret = ACameraDevice_createCaptureRequest(mDevice,
+                    TEMPLATE_STILL_CAPTURE, &mStillRequest);
+        }
+        if (ret != AMEDIA_OK) {
+            ALOGE("ACameraDevice_createCaptureRequest failed, ret=%d", ret);
+            return ret;
+        }
+        ret = ACameraOutputTarget_create(mImgReaderAnw, &mReqImgReaderOutput);
+        if (ret != AMEDIA_OK) {
+            ALOGE("ACameraOutputTarget_create failed, ret=%d", ret);
+            return ret;
+        }
+        ret = ACaptureRequest_addTarget(mStillRequest, mReqImgReaderOutput);
+        if (ret != AMEDIA_OK) {
+            ALOGE("ACaptureRequest_addTarget failed, ret=%d", ret);
+            return ret;
+        }
+
+        for (auto& physicalStream : physicalImgReaders) {
+            ACameraOutputTarget* outputTarget = nullptr;
+            ret = ACameraOutputTarget_create(physicalStream.anw, &outputTarget);
+            if (ret != AMEDIA_OK) {
+                ALOGE("ACameraOutputTarget_create failed, ret=%d", ret);
+                return ret;
+            }
+            ret = ACaptureRequest_addTarget(mStillRequest, outputTarget);
+            if (ret != AMEDIA_OK) {
+                ALOGE("ACaptureRequest_addTarget failed, ret=%d", ret);
+                return ret;
+            }
+            mReqExtraOutputs.push_back(outputTarget);
+        }
+
+        mIsCameraReady = true;
+        return 0;
+    }
+
+
+    bool isCameraReady() { return mIsCameraReady; }
+
+    void closeCamera() {
+        // Destroy capture request
+        if (mReqImgReaderOutput) {
+            ACameraOutputTarget_free(mReqImgReaderOutput);
+            mReqImgReaderOutput = nullptr;
+        }
+        for (auto& outputTarget : mReqExtraOutputs) {
+            ACameraOutputTarget_free(outputTarget);
+        }
+        mReqExtraOutputs.clear();
+        if (mStillRequest) {
+            ACaptureRequest_free(mStillRequest);
+            mStillRequest = nullptr;
+        }
+        // Destroy capture session
+        if (mSession != nullptr) {
+            ACameraCaptureSession_close(mSession);
+            mSession = nullptr;
+        }
+        if (mImgReaderOutput) {
+            ACaptureSessionOutput_free(mImgReaderOutput);
+            mImgReaderOutput = nullptr;
+        }
+        for (auto& extraOutput : mExtraOutputs) {
+            ACaptureSessionOutput_free(extraOutput);
+        }
+        mExtraOutputs.clear();
+        if (mOutputs) {
+            ACaptureSessionOutputContainer_free(mOutputs);
+            mOutputs = nullptr;
+        }
+        // Destroy camera device
+        if (mDevice) {
+            ACameraDevice_close(mDevice);
+            mDevice = nullptr;
+        }
+        mIsCameraReady = false;
+    }
+
+    int takePicture() {
+        int seqId;
+        return ACameraCaptureSession_capture(mSession, &mCaptureCallbacks, 1, &mStillRequest,
+                                             &seqId);
+    }
+
+    int takeLogicalCameraPicture() {
+        int seqId;
+        return ACameraCaptureSession_logicalCamera_capture(mSession, &mLogicalCaptureCallbacks,
+                1, &mStillRequest, &seqId);
+    }
+
+    bool checkCallbacks(int pictureCount) {
+        std::lock_guard<std::mutex> lock(mMutex);
+        if (mCompletedCaptureCallbackCount != pictureCount) {
+            ALOGE("Completed capture callaback count not as expected. expected %d actual %d",
+                  pictureCount, mCompletedCaptureCallbackCount);
+            return false;
+        }
+        return true;
+    }
+
+    static void onDeviceDisconnected(void* /*obj*/, ACameraDevice* /*device*/) {}
+
+    static void onDeviceError(void* /*obj*/, ACameraDevice* /*device*/, int /*errorCode*/) {}
+
+    static void onSessionClosed(void* /*obj*/, ACameraCaptureSession* /*session*/) {}
+
+    static void onSessionReady(void* /*obj*/, ACameraCaptureSession* /*session*/) {}
+
+    static void onSessionActive(void* /*obj*/, ACameraCaptureSession* /*session*/) {}
+
+   private:
+    ACameraDevice_StateCallbacks mDeviceCb{this, onDeviceDisconnected,
+                                           onDeviceError};
+    ACameraCaptureSession_stateCallbacks mSessionCb{
+        this, onSessionClosed, onSessionReady, onSessionActive};
+
+    native_handle_t* mImgReaderAnw = nullptr;  // not owned by us.
+
+    // Camera device
+    ACameraDevice* mDevice = nullptr;
+    // Capture session
+    ACaptureSessionOutputContainer* mOutputs = nullptr;
+    ACaptureSessionOutput* mImgReaderOutput = nullptr;
+    std::vector<ACaptureSessionOutput*> mExtraOutputs;
+
+    ACameraCaptureSession* mSession = nullptr;
+    // Capture request
+    ACaptureRequest* mStillRequest = nullptr;
+    ACameraOutputTarget* mReqImgReaderOutput = nullptr;
+    std::vector<ACameraOutputTarget*> mReqExtraOutputs;
+
+    bool mIsCameraReady = false;
+    const char* mCameraId;
+    ACameraManager* mCameraManager;
+    int mCompletedCaptureCallbackCount = 0;
+    std::mutex mMutex;
+    ACameraCaptureSession_captureCallbacks mCaptureCallbacks = {
+        // TODO: Add tests for other callbacks
+        this, // context
+        nullptr, // onCaptureStarted
+        nullptr, // onCaptureProgressed
+        [](void* ctx , ACameraCaptureSession *, ACaptureRequest *,
+                                          const ACameraMetadata *) {
+            CameraHelper *ch = static_cast<CameraHelper *>(ctx);
+            std::lock_guard<std::mutex> lock(ch->mMutex);
+            ch->mCompletedCaptureCallbackCount++;
+        },
+        nullptr, // onCaptureFailed
+        nullptr, // onCaptureSequenceCompleted
+        nullptr, // onCaptureSequenceAborted
+        nullptr, // onCaptureBufferLost
+    };
+
+    std::vector<std::string> mPhysicalCameraIds;
+    ACameraCaptureSession_logicalCamera_captureCallbacks mLogicalCaptureCallbacks = {
+        // TODO: Add tests for other callbacks
+        this, // context
+        nullptr, // onCaptureStarted
+        nullptr, // onCaptureProgressed
+        [](void* ctx , ACameraCaptureSession *, ACaptureRequest *,
+                const ACameraMetadata *, size_t physicalResultCount,
+                const char** physicalCameraIds, const ACameraMetadata** physicalResults) {
+            CameraHelper *ch = static_cast<CameraHelper *>(ctx);
+            std::lock_guard<std::mutex> lock(ch->mMutex);
+            ASSERT_EQ(physicalResultCount, ch->mPhysicalCameraIds.size());
+            for (size_t i = 0; i < physicalResultCount; i++) {
+                ASSERT_TRUE(physicalCameraIds[i] != nullptr);
+                ASSERT_TRUE(physicalResults[i] != nullptr);
+                ASSERT_NE(std::find(ch->mPhysicalCameraIds.begin(),
+                        ch->mPhysicalCameraIds.end(), physicalCameraIds[i]),
+                        ch->mPhysicalCameraIds.end());
+
+                // Verify frameNumber and sensorTimestamp exist in physical
+                // result metadata
+                ACameraMetadata_const_entry entry;
+                ACameraMetadata_getConstEntry(
+                        physicalResults[i], ACAMERA_SYNC_FRAME_NUMBER, &entry);
+                ASSERT_EQ(entry.count, 1);
+                ACameraMetadata_getConstEntry(
+                        physicalResults[i], ACAMERA_SENSOR_TIMESTAMP, &entry);
+                ASSERT_EQ(entry.count, 1);
+            }
+            ch->mCompletedCaptureCallbackCount++;
+        },
+        [] (void * /*ctx*/, ACameraCaptureSession* /*session*/, ACaptureRequest* /*request*/,
+                ALogicalCameraCaptureFailure* failure) {
+            if (failure->physicalCameraId) {
+                ALOGD("%s: Physical camera id: %s result failure", __FUNCTION__,
+                        failure->physicalCameraId);
+            }
+        },
+        nullptr, // onCaptureSequenceCompleted
+        nullptr, // onCaptureSequenceAborted
+        nullptr, // onCaptureBufferLost
+    };
+};
+
+class ImageReaderTestCase {
+   public:
+    ImageReaderTestCase(int32_t width,
+                        int32_t height,
+                        int32_t format,
+                        uint64_t usage,
+                        int32_t maxImages,
+                        bool async)
+        : mWidth(width),
+          mHeight(height),
+          mFormat(format),
+          mUsage(usage),
+          mMaxImages(maxImages),
+          mAsync(async) {}
+
+    ~ImageReaderTestCase() {
+        if (mImgReaderAnw) {
+            AImageReader_delete(mImgReader);
+            // No need to call native_handle_t_release on imageReaderAnw
+        }
+    }
+
+    int initImageReader() {
+        if (mImgReader != nullptr || mImgReaderAnw != nullptr) {
+            ALOGE("Cannot re-initalize image reader, mImgReader=%p, mImgReaderAnw=%p", mImgReader,
+                  mImgReaderAnw);
+            return -1;
+        }
+
+        media_status_t ret = AImageReader_newWithUsage(
+                mWidth, mHeight, mFormat, mUsage, mMaxImages, &mImgReader);
+        if (ret != AMEDIA_OK || mImgReader == nullptr) {
+            ALOGE("Failed to create new AImageReader, ret=%d, mImgReader=%p", ret, mImgReader);
+            return -1;
+        }
+
+        ret = AImageReader_setImageListener(mImgReader, &mReaderAvailableCb);
+        if (ret != AMEDIA_OK) {
+            ALOGE("Failed to set image available listener, ret=%d.", ret);
+            return ret;
+        }
+
+        ret = AImageReader_setBufferRemovedListener(mImgReader, &mReaderDetachedCb);
+        if (ret != AMEDIA_OK) {
+            ALOGE("Failed to set buffer detaching listener, ret=%d.", ret);
+            return ret;
+        }
+
+        ret = AImageReader_getWindowNativeHandle(mImgReader, &mImgReaderAnw);
+        if (ret != AMEDIA_OK || mImgReaderAnw == nullptr) {
+            ALOGE("Failed to get native_handle_t from AImageReader, ret=%d, mImgReaderAnw=%p.", ret,
+                  mImgReaderAnw);
+            return -1;
+        }
+
+        return 0;
+    }
+
+    native_handle_t* getNativeWindow() { return mImgReaderAnw; }
+
+    int getAcquiredImageCount() {
+        std::lock_guard<std::mutex> lock(mMutex);
+        return mAcquiredImageCount;
+    }
+
+    void HandleImageAvailable(AImageReader* reader) {
+        std::lock_guard<std::mutex> lock(mMutex);
+
+        AImage* outImage = nullptr;
+        media_status_t ret;
+
+        // Make sure AImage will be deleted automatically when it goes out of
+        // scope.
+        auto imageDeleter = [this](AImage* img) {
+            if (mAsync) {
+                AImage_deleteAsync(img, kDummyFenceFd);
+            } else {
+                AImage_delete(img);
+            }
+        };
+        std::unique_ptr<AImage, decltype(imageDeleter)> img(nullptr, imageDeleter);
+
+        if (mAsync) {
+            int outFenceFd = 0;
+            // Verity that outFenceFd's value will be changed by
+            // AImageReader_acquireNextImageAsync.
+            ret = AImageReader_acquireNextImageAsync(reader, &outImage, &outFenceFd);
+            if (ret != AMEDIA_OK || outImage == nullptr || outFenceFd == 0) {
+                ALOGE("Failed to acquire image, ret=%d, outIamge=%p, outFenceFd=%d.", ret, outImage,
+                      outFenceFd);
+                return;
+            }
+            img.reset(outImage);
+        } else {
+            ret = AImageReader_acquireNextImage(reader, &outImage);
+            if (ret != AMEDIA_OK || outImage == nullptr) {
+                ALOGE("Failed to acquire image, ret=%d, outIamge=%p.", ret, outImage);
+                return;
+            }
+            img.reset(outImage);
+        }
+
+        AHardwareBuffer* outBuffer = nullptr;
+        ret = AImage_getHardwareBuffer(img.get(), &outBuffer);
+        if (ret != AMEDIA_OK || outBuffer == nullptr) {
+            ALOGE("Faild to get hardware buffer, ret=%d, outBuffer=%p.", ret, outBuffer);
+            return;
+        }
+
+        // No need to release AHardwareBuffer, since we don't acquire additional
+        // reference to it.
+        AHardwareBuffer_Desc outDesc;
+        AHardwareBuffer_describe(outBuffer, &outDesc);
+        int32_t imageWidth = 0;
+        int32_t imageHeight = 0;
+        int32_t bufferWidth = static_cast<int32_t>(outDesc.width);
+        int32_t bufferHeight = static_cast<int32_t>(outDesc.height);
+
+        AImage_getWidth(outImage, &imageWidth);
+        AImage_getHeight(outImage, &imageHeight);
+        if (imageWidth != mWidth || imageHeight != mHeight) {
+            ALOGE("Mismatched output image dimension: expected=%dx%d, actual=%dx%d", mWidth,
+                  mHeight, imageWidth, imageHeight);
+            return;
+        }
+
+        if (mFormat == AIMAGE_FORMAT_RGBA_8888 ||
+            mFormat == AIMAGE_FORMAT_RGBX_8888 ||
+            mFormat == AIMAGE_FORMAT_RGB_888 ||
+            mFormat == AIMAGE_FORMAT_RGB_565 ||
+            mFormat == AIMAGE_FORMAT_RGBA_FP16 ||
+            mFormat == AIMAGE_FORMAT_YUV_420_888 ||
+            mFormat == AIMAGE_FORMAT_Y8) {
+            // Check output buffer dimension for certain formats. Don't do this for blob based
+            // formats.
+            if (bufferWidth != mWidth || bufferHeight != mHeight) {
+                ALOGE("Mismatched output buffer dimension: expected=%dx%d, actual=%dx%d", mWidth,
+                      mHeight, bufferWidth, bufferHeight);
+                return;
+            }
+        }
+
+        if ((outDesc.usage & mUsage) != mUsage) {
+            ALOGE("Mismatched output buffer usage: actual (%" PRIu64 "), expected (%" PRIu64 ")",
+                  outDesc.usage, mUsage);
+            return;
+        }
+
+        uint8_t* data = nullptr;
+        int dataLength = 0;
+        ret = AImage_getPlaneData(img.get(), 0, &data, &dataLength);
+        if (mUsage & AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN) {
+            // When we have CPU_READ_OFTEN usage bits, we can lock the image.
+            if (ret != AMEDIA_OK || data == nullptr || dataLength < 0) {
+                ALOGE("Failed to access CPU data, ret=%d, data=%p, dataLength=%d", ret, data,
+                      dataLength);
+                return;
+            }
+        } else {
+            if (ret != AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE || data != nullptr || dataLength != 0) {
+                ALOGE("Shouldn't be able to access CPU data, ret=%d, data=%p, dataLength=%d", ret,
+                      data, dataLength);
+                return;
+            }
+        }
+        // Only increase mAcquiredImageCount if all checks pass.
+        mAcquiredImageCount++;
+    }
+
+    static void onImageAvailable(void* obj, AImageReader* reader) {
+        ImageReaderTestCase* thiz = reinterpret_cast<ImageReaderTestCase*>(obj);
+        thiz->HandleImageAvailable(reader);
+    }
+
+    static void
+    onBufferRemoved(void* /*obj*/, AImageReader* /*reader*/, AHardwareBuffer* /*buffer*/) {
+        // No-op, just to check the listener can be set properly.
+    }
+
+   private:
+    int32_t mWidth;
+    int32_t mHeight;
+    int32_t mFormat;
+    uint64_t mUsage;
+    int32_t mMaxImages;
+    bool mAsync;
+
+    std::mutex mMutex;
+    int mAcquiredImageCount{0};
+
+    AImageReader* mImgReader = nullptr;
+    native_handle_t* mImgReaderAnw = nullptr;
+
+    AImageReader_ImageListener mReaderAvailableCb{this, onImageAvailable};
+    AImageReader_BufferRemovedListener mReaderDetachedCb{this, onBufferRemoved};
+};
+
+
+class AImageReaderVendorTest : public ::testing::Test {
+  public:
+    void SetUp() override {
+        mCameraManager = ACameraManager_create();
+        if (mCameraManager == nullptr) {
+            ALOGE("Failed to create ACameraManager.");
+            return;
+        }
+
+        camera_status_t ret = ACameraManager_getCameraIdList(mCameraManager, &mCameraIdList);
+        if (ret != ACAMERA_OK) {
+            ALOGE("Failed to get cameraIdList: ret=%d", ret);
+            return;
+        }
+        // TODO: Add more rigorous tests for vendor tags
+        ASSERT_NE(VendorTagDescriptorCache::getGlobalVendorTagCache(), nullptr);
+        if (mCameraIdList->numCameras < 1) {
+            ALOGW("Device has no camera on board.");
+            return;
+        }
+    }
+    void TearDown() override {
+        // Destroy camera manager
+        if (mCameraIdList) {
+            ACameraManager_deleteCameraIdList(mCameraIdList);
+            mCameraIdList = nullptr;
+        }
+        if (mCameraManager) {
+            ACameraManager_delete(mCameraManager);
+            mCameraManager = nullptr;
+        }
+    }
+
+    bool takePictures(const char* id, uint64_t readerUsage, int readerMaxImages,
+            bool readerAsync, int pictureCount) {
+        int ret = 0;
+
+        ImageReaderTestCase testCase(
+                kTestImageWidth, kTestImageHeight, kTestImageFormat, readerUsage, readerMaxImages,
+                readerAsync);
+        ret = testCase.initImageReader();
+        if (ret < 0) {
+            ALOGE("Unable to initialize ImageReader");
+            return false;
+        }
+
+        CameraHelper cameraHelper(id, mCameraManager);
+        ret = cameraHelper.initCamera(testCase.getNativeWindow(),
+                {}/*physicalImageReaders*/, false/*usePhysicalSettings*/);
+        if (ret < 0) {
+            ALOGE("Unable to initialize camera helper");
+            return false;
+        }
+
+        if (!cameraHelper.isCameraReady()) {
+            ALOGW("Camera is not ready after successful initialization. It's either due to camera "
+                  "on board lacks BACKWARDS_COMPATIBLE capability or the device does not have "
+                  "camera on board.");
+            return true;
+        }
+
+        for (int i = 0; i < pictureCount; i++) {
+            ret = cameraHelper.takePicture();
+            if (ret < 0) {
+                ALOGE("Unable to take picture");
+                return false;
+            }
+        }
+
+        // Sleep until all capture finished
+        for (int i = 0; i < kCaptureWaitRetry * pictureCount; i++) {
+            usleep(kCaptureWaitUs);
+            if (testCase.getAcquiredImageCount() == pictureCount) {
+                ALOGI("Session take ~%d ms to capture %d images", i * kCaptureWaitUs / 1000,
+                      pictureCount);
+                break;
+            }
+        }
+        return testCase.getAcquiredImageCount() == pictureCount &&
+                cameraHelper.checkCallbacks(pictureCount);
+    }
+
+    bool testTakePicturesNative(const char* id) {
+        for (auto& readerUsage :
+             {AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN}) {
+            for (auto& readerMaxImages : {1, 4, 8}) {
+                for (auto& readerAsync : {true, false}) {
+                    for (auto& pictureCount : {1, 4, 8}) {
+                        if (!takePictures(id, readerUsage, readerMaxImages,
+                                readerAsync, pictureCount)) {
+                            ALOGE("Test takePictures failed for test case usage=%" PRIu64
+                                  ", maxImages=%d, async=%d, pictureCount=%d",
+                                  readerUsage, readerMaxImages, readerAsync, pictureCount);
+                            return false;
+                        }
+                    }
+                }
+            }
+        }
+        return true;
+    }
+
+    // Camera manager
+    ACameraManager* mCameraManager = nullptr;
+    ACameraIdList* mCameraIdList = nullptr;
+
+    bool isCapabilitySupported(ACameraMetadata* staticInfo,
+            acamera_metadata_enum_android_request_available_capabilities_t cap) {
+        ACameraMetadata_const_entry entry;
+        ACameraMetadata_getConstEntry(
+                staticInfo, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entry);
+        for (uint32_t i = 0; i < entry.count; i++) {
+            if (entry.data.u8[i] == cap) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    bool isSizeSupportedForFormat(ACameraMetadata* staticInfo,
+            int32_t format, int32_t width, int32_t height) {
+        ACameraMetadata_const_entry entry;
+        ACameraMetadata_getConstEntry(staticInfo,
+                ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &entry);
+        for (uint32_t i = 0; i < entry.count; i += 4) {
+            if (entry.data.i32[i] == format &&
+                    entry.data.i32[i+3] == ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT &&
+                    entry.data.i32[i+1] == width &&
+                    entry.data.i32[i+2] == height) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    void findCandidateLogicalCamera(const char **cameraId,
+            ACameraMetadata** staticMetadata,
+            std::vector<const char*>* candidatePhysicalIds) {
+        // Find first available logical camera
+        for (int i = 0; i < mCameraIdList->numCameras; i++) {
+            camera_status_t ret;
+            ret = ACameraManager_getCameraCharacteristics(
+                    mCameraManager, mCameraIdList->cameraIds[i], staticMetadata);
+            ASSERT_EQ(ret, ACAMERA_OK);
+            ASSERT_NE(*staticMetadata, nullptr);
+
+            if (!isCapabilitySupported(*staticMetadata,
+                    ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA)) {
+                ACameraMetadata_free(*staticMetadata);
+                *staticMetadata = nullptr;
+                continue;
+            }
+
+            // Check returned physical camera Ids are valid
+            size_t physicalCameraIdCnt = 0;
+            const char*const* physicalCameraIds = nullptr;
+            bool isLogicalCamera = ACameraMetadata_isLogicalMultiCamera(*staticMetadata,
+                    &physicalCameraIdCnt, &physicalCameraIds);
+            ASSERT_TRUE(isLogicalCamera);
+            ASSERT_GE(physicalCameraIdCnt, 2);
+            ACameraMetadata* physicalCameraMetadata = nullptr;
+            candidatePhysicalIds->clear();
+            for (size_t j = 0; j < physicalCameraIdCnt && candidatePhysicalIds->size() < 2; j++) {
+                ASSERT_GT(strlen(physicalCameraIds[j]), 0);
+                ret = ACameraManager_getCameraCharacteristics(
+                        mCameraManager, physicalCameraIds[j], &physicalCameraMetadata);
+                ASSERT_EQ(ret, ACAMERA_OK);
+                ASSERT_NE(physicalCameraMetadata, nullptr);
+
+                if (isSizeSupportedForFormat(physicalCameraMetadata, kTestImageFormat,
+                        kTestImageWidth, kTestImageHeight)) {
+                    candidatePhysicalIds->push_back(physicalCameraIds[j]);
+                }
+                ACameraMetadata_free(physicalCameraMetadata);
+            }
+            if (candidatePhysicalIds->size() == 2) {
+                *cameraId = mCameraIdList->cameraIds[i];
+                return;
+            } else {
+                ACameraMetadata_free(*staticMetadata);
+                *staticMetadata = nullptr;
+            }
+        }
+        *cameraId = nullptr;
+        return;
+    }
+
+    void testLogicalCameraPhysicalStream(bool usePhysicalSettings) {
+        const char* cameraId = nullptr;
+        ACameraMetadata* staticMetadata = nullptr;
+        std::vector<const char*> physicalCameraIds;
+
+        findCandidateLogicalCamera(&cameraId, &staticMetadata, &physicalCameraIds);
+        if (cameraId == nullptr) {
+            // Couldn't find logical camera to test
+            return;
+        }
+
+        // Test streaming the logical multi-camera
+        uint64_t readerUsage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN;
+        int32_t readerMaxImages = 8;
+        bool readerAsync = false;
+        const int pictureCount = 6;
+        std::vector<ImageReaderTestCase*> testCases;
+        for (size_t i = 0; i < 3; i++) {
+            ImageReaderTestCase* testCase = new ImageReaderTestCase(
+                    kTestImageWidth, kTestImageHeight, kTestImageFormat, readerUsage,
+                    readerMaxImages, readerAsync);
+            ASSERT_EQ(testCase->initImageReader(), 0);
+            testCases.push_back(testCase);
+        }
+
+        CameraHelper cameraHelper(cameraId, mCameraManager);
+        std::vector<CameraHelper::PhysicalImgReaderInfo> physicalImgReaderInfo;
+        physicalImgReaderInfo.push_back({physicalCameraIds[0], testCases[1]->getNativeWindow()});
+        physicalImgReaderInfo.push_back({physicalCameraIds[1], testCases[2]->getNativeWindow()});
+
+        int ret = cameraHelper.initCamera(testCases[0]->getNativeWindow(),
+                physicalImgReaderInfo, usePhysicalSettings);
+        ASSERT_EQ(ret, 0);
+
+        if (!cameraHelper.isCameraReady()) {
+            ALOGW("Camera is not ready after successful initialization. It's either due to camera "
+                  "on board lacks BACKWARDS_COMPATIBLE capability or the device does not have "
+                  "camera on board.");
+            return;
+        }
+
+        for (int i = 0; i < pictureCount; i++) {
+            ret = cameraHelper.takeLogicalCameraPicture();
+            ASSERT_EQ(ret, 0);
+        }
+
+        // Sleep until all capture finished
+        for (int i = 0; i < kCaptureWaitRetry * pictureCount; i++) {
+            usleep(kCaptureWaitUs);
+            if (testCases[0]->getAcquiredImageCount() == pictureCount) {
+                ALOGI("Session take ~%d ms to capture %d images", i * kCaptureWaitUs / 1000,
+                      pictureCount);
+                break;
+            }
+        }
+        ASSERT_EQ(testCases[0]->getAcquiredImageCount(), pictureCount);
+        ASSERT_EQ(testCases[1]->getAcquiredImageCount(), pictureCount);
+        ASSERT_EQ(testCases[2]->getAcquiredImageCount(), pictureCount);
+        ASSERT_TRUE(cameraHelper.checkCallbacks(pictureCount));
+
+        ACameraMetadata_free(staticMetadata);
+    }
+};
+
+TEST_F(AImageReaderVendorTest, CreateWindowNativeHandle) {
+    // We always use the first camera.
+    const char* cameraId = mCameraIdList->cameraIds[0];
+    ASSERT_TRUE(cameraId != nullptr);
+
+    ACameraMetadata* staticMetadata = nullptr;
+    camera_status_t ret = ACameraManager_getCameraCharacteristics(
+            mCameraManager, cameraId, &staticMetadata);
+    ASSERT_EQ(ret, ACAMERA_OK);
+    ASSERT_NE(staticMetadata, nullptr);
+
+    bool isBC = isCapabilitySupported(staticMetadata,
+            ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE);
+
+    uint32_t namedTag = 0;
+    // Test that ACameraMetadata_getTagFromName works as expected for public tag
+    // names
+    camera_status_t status = ACameraManager_getTagFromName(mCameraManager, cameraId,
+            "android.control.aeMode", &namedTag);
+
+    ASSERT_EQ(status, ACAMERA_OK);
+    ASSERT_EQ(namedTag, ACAMERA_CONTROL_AE_MODE);
+
+    ACameraMetadata_free(staticMetadata);
+
+    if (!isBC) {
+        ALOGW("Camera does not support BACKWARD_COMPATIBLE.");
+        return;
+    }
+
+    EXPECT_TRUE(testTakePicturesNative(cameraId));
+}
+
+TEST_F(AImageReaderVendorTest, LogicalCameraPhysicalStream) {
+    testLogicalCameraPhysicalStream(false/*usePhysicalSettings*/);
+    testLogicalCameraPhysicalStream(true/*usePhysicalSettings*/);
+}
+
+}  // namespace
diff --git a/camera/tests/Android.mk b/camera/tests/Android.mk
index 659484f..e5c1631 100644
--- a/camera/tests/Android.mk
+++ b/camera/tests/Android.mk
@@ -19,7 +19,8 @@
 LOCAL_SRC_FILES:= \
 	VendorTagDescriptorTests.cpp \
 	CameraBinderTests.cpp \
-	CameraZSLTests.cpp
+	CameraZSLTests.cpp \
+	CameraCharacteristicsPermission.cpp
 
 LOCAL_SHARED_LIBRARIES := \
 	liblog \
diff --git a/camera/tests/CameraBinderTests.cpp b/camera/tests/CameraBinderTests.cpp
index 1de7013..8fe029a 100644
--- a/camera/tests/CameraBinderTests.cpp
+++ b/camera/tests/CameraBinderTests.cpp
@@ -29,6 +29,7 @@
 #include <utils/Condition.h>
 #include <utils/Mutex.h>
 #include <system/graphics.h>
+#include <hardware/camera3.h>
 #include <hardware/gralloc.h>
 
 #include <camera/CameraMetadata.h>
@@ -40,6 +41,7 @@
 #include <android/hardware/camera2/BnCameraDeviceCallbacks.h>
 #include <camera/camera2/CaptureRequest.h>
 #include <camera/camera2/OutputConfiguration.h>
+#include <camera/camera2/SessionConfiguration.h>
 #include <camera/camera2/SubmitInfo.h>
 
 #include <gui/BufferItemConsumer.h>
@@ -55,6 +57,8 @@
 #include <algorithm>
 
 using namespace android;
+using ::android::hardware::ICameraServiceDefault;
+using ::android::hardware::camera2::ICameraDeviceUser;
 
 #define ASSERT_NOT_NULL(x) \
     ASSERT_TRUE((x) != nullptr)
@@ -86,6 +90,11 @@
         return binder::Status::ok();
     };
 
+    virtual binder::Status onCameraAccessPrioritiesChanged() {
+        // No op
+        return binder::Status::ok();
+    }
+
     bool waitForNumCameras(size_t num) const {
         Mutex::Autolock l(mLock);
 
@@ -476,7 +485,8 @@
 
         sp<Surface> surface(new Surface(gbProducer, /*controlledByApp*/false));
 
-        OutputConfiguration output(gbProducer, /*rotation*/0);
+        String16 noPhysicalId;
+        OutputConfiguration output(gbProducer, /*rotation*/0, noPhysicalId);
 
         // Can we configure?
         res = device->beginConfigure();
@@ -490,6 +500,19 @@
         EXPECT_TRUE(res.isOk()) << res;
         EXPECT_FALSE(callbacks->hadError());
 
+        // Session configuration must also be supported in this case
+        SessionConfiguration sessionConfiguration = { /*inputWidth*/ 0, /*inputHeight*/0,
+                /*inputFormat*/ -1, CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE};
+        sessionConfiguration.addOutputConfiguration(output);
+        bool queryStatus;
+        res = device->isSessionConfigurationSupported(sessionConfiguration, &queryStatus);
+        EXPECT_TRUE(res.isOk() ||
+                (res.serviceSpecificErrorCode() == ICameraServiceDefault::ERROR_INVALID_OPERATION))
+                << res;
+        if (res.isOk()) {
+            EXPECT_TRUE(queryStatus);
+        }
+
         // Can we make requests?
         CameraMetadata requestTemplate;
         res = device->createDefaultRequest(/*preview template*/1,
diff --git a/camera/tests/CameraCharacteristicsPermission.cpp b/camera/tests/CameraCharacteristicsPermission.cpp
new file mode 100644
index 0000000..135d2a3
--- /dev/null
+++ b/camera/tests/CameraCharacteristicsPermission.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "CameraCharacteristicsPermission"
+
+#include <gtest/gtest.h>
+
+#include <binder/ProcessState.h>
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <camera/CameraMetadata.h>
+#include <camera/Camera.h>
+#include <android/hardware/ICameraService.h>
+
+using namespace android;
+using namespace android::hardware;
+
+class CameraCharacteristicsPermission : public ::testing::Test {
+protected:
+
+    CameraCharacteristicsPermission() : numCameras(0){}
+    //Gtest interface
+    void SetUp() override;
+    void TearDown() override;
+
+    int32_t numCameras;
+    sp<ICameraService> mCameraService;
+};
+
+void CameraCharacteristicsPermission::SetUp() {
+    ::android::binder::Status rc;
+    ProcessState::self()->startThreadPool();
+    sp<IServiceManager> sm = defaultServiceManager();
+    sp<IBinder> binder = sm->getService(String16("media.camera"));
+    mCameraService = interface_cast<ICameraService>(binder);
+    rc = mCameraService->getNumberOfCameras(
+            hardware::ICameraService::CAMERA_TYPE_ALL, &numCameras);
+    EXPECT_TRUE(rc.isOk());
+}
+
+void CameraCharacteristicsPermission::TearDown() {
+    mCameraService.clear();
+}
+
+// Revoking and acquiring permissions automatically might not be possible.
+// Test the functionality for removal of camera characteristics needing
+// a camera permission.
+TEST_F(CameraCharacteristicsPermission, TestCameraPermission) {
+    for (int32_t cameraId = 0; cameraId < numCameras; cameraId++) {
+
+        String16 cameraIdStr = String16(String8::format("%d", cameraId));
+        bool isSupported = false;
+        auto rc = mCameraService->supportsCameraApi(cameraIdStr,
+                hardware::ICameraService::API_VERSION_2, &isSupported);
+        EXPECT_TRUE(rc.isOk());
+        if (!isSupported) {
+            continue;
+        }
+
+        CameraMetadata metadata;
+        std::vector<int32_t> tagsNeedingPermission;
+        rc = mCameraService->getCameraCharacteristics(cameraIdStr, &metadata);
+        ASSERT_TRUE(rc.isOk());
+        EXPECT_FALSE(metadata.isEmpty());
+        EXPECT_EQ(metadata.removePermissionEntries(CAMERA_METADATA_INVALID_VENDOR_ID,
+                    &tagsNeedingPermission), NO_ERROR);
+        camera_metadata_entry_t availableCharacteristics =
+                metadata.find(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
+        EXPECT_TRUE(0 < availableCharacteristics.count);
+
+        std::vector<uint32_t> availableKeys;
+        availableKeys.reserve(availableCharacteristics.count);
+        availableKeys.insert(availableKeys.begin(), availableCharacteristics.data.i32,
+                availableCharacteristics.data.i32 + availableCharacteristics.count);
+
+        for (const auto &key : tagsNeedingPermission) {
+            ASSERT_FALSE(metadata.exists(key));
+            auto it = std::find(availableKeys.begin(), availableKeys.end(), key);
+            ASSERT_TRUE(it == availableKeys.end());
+        }
+    }
+}
diff --git a/cmds/screenrecord/Android.bp b/cmds/screenrecord/Android.bp
new file mode 100644
index 0000000..86476cd
--- /dev/null
+++ b/cmds/screenrecord/Android.bp
@@ -0,0 +1,55 @@
+// Copyright 2013 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_binary {
+    name: "screenrecord",
+
+    srcs: [
+        "screenrecord.cpp",
+        "EglWindow.cpp",
+        "FrameOutput.cpp",
+        "TextRenderer.cpp",
+        "Overlay.cpp",
+        "Program.cpp",
+    ],
+
+    shared_libs: [
+        "libstagefright",
+        "libmedia",
+        "libmedia_omx",
+        "libutils",
+        "libbinder",
+        "libstagefright_foundation",
+        "libjpeg",
+        "libui",
+        "libgui",
+        "libcutils",
+        "liblog",
+        "libEGL",
+        "libGLESv2",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/libstagefright",
+        "frameworks/av/media/libstagefright/include",
+        "frameworks/native/include/media/openmax",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+        "-Wno-multichar",
+        //"-UNDEBUG",
+    ]
+}
diff --git a/cmds/screenrecord/Android.mk b/cmds/screenrecord/Android.mk
deleted file mode 100644
index 5e83ed6..0000000
--- a/cmds/screenrecord/Android.mk
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-	screenrecord.cpp \
-	EglWindow.cpp \
-	FrameOutput.cpp \
-	TextRenderer.cpp \
-	Overlay.cpp \
-	Program.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-	libstagefright libmedia libmedia_omx libutils libbinder libstagefright_foundation \
-	libjpeg libui libgui libcutils liblog libEGL libGLESv2
-
-LOCAL_C_INCLUDES := \
-	frameworks/av/media/libstagefright \
-	frameworks/av/media/libstagefright/include \
-	frameworks/native/include/media/openmax \
-	external/jpeg
-
-LOCAL_CFLAGS := -Werror -Wall
-LOCAL_CFLAGS += -Wno-multichar
-#LOCAL_CFLAGS += -UNDEBUG
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE:= screenrecord
-
-include $(BUILD_EXECUTABLE)
diff --git a/cmds/screenrecord/screenrecord.cpp b/cmds/screenrecord/screenrecord.cpp
index d1859d1..7aa655f 100644
--- a/cmds/screenrecord/screenrecord.cpp
+++ b/cmds/screenrecord/screenrecord.cpp
@@ -48,6 +48,7 @@
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/MediaCodec.h>
+#include <media/stagefright/MediaCodecConstants.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MediaMuxer.h>
 #include <media/stagefright/PersistentSurface.h>
@@ -58,7 +59,35 @@
 #include "Overlay.h"
 #include "FrameOutput.h"
 
-using namespace android;
+using android::ABuffer;
+using android::ALooper;
+using android::AMessage;
+using android::AString;
+using android::DisplayInfo;
+using android::FrameOutput;
+using android::IBinder;
+using android::IGraphicBufferProducer;
+using android::ISurfaceComposer;
+using android::MediaCodec;
+using android::MediaCodecBuffer;
+using android::MediaMuxer;
+using android::Overlay;
+using android::PersistentSurface;
+using android::ProcessState;
+using android::Rect;
+using android::String8;
+using android::SurfaceComposerClient;
+using android::Vector;
+using android::sp;
+using android::status_t;
+
+using android::DISPLAY_ORIENTATION_0;
+using android::DISPLAY_ORIENTATION_180;
+using android::DISPLAY_ORIENTATION_90;
+using android::INVALID_OPERATION;
+using android::NAME_NOT_FOUND;
+using android::NO_ERROR;
+using android::UNKNOWN_ERROR;
 
 static const uint32_t kMinBitRate = 100000;         // 0.1Mbps
 static const uint32_t kMaxBitRate = 200 * 1000000;  // 200Mbps
@@ -73,7 +102,7 @@
 static bool gMonotonicTime = false;     // use system monotonic time for timestamps
 static bool gPersistentSurface = false; // use persistent surface
 static enum {
-    FORMAT_MP4, FORMAT_H264, FORMAT_FRAMES, FORMAT_RAW_FRAMES
+    FORMAT_MP4, FORMAT_H264, FORMAT_WEBM, FORMAT_3GPP, FORMAT_FRAMES, FORMAT_RAW_FRAMES
 } gOutputFormat = FORMAT_MP4;           // data format for output
 static AString gCodecName = "";         // codec name override
 static bool gSizeSpecified = false;     // was size explicitly requested?
@@ -83,6 +112,7 @@
 static uint32_t gVideoHeight = 0;
 static uint32_t gBitRate = 20000000;     // 20Mbps
 static uint32_t gTimeLimitSec = kMaxTimeLimitSec;
+static uint32_t gBframes = 0;
 
 // Set by signal handler to stop recording.
 static volatile bool gStopRequested = false;
@@ -154,15 +184,20 @@
     }
 
     sp<AMessage> format = new AMessage;
-    format->setInt32("width", gVideoWidth);
-    format->setInt32("height", gVideoHeight);
-    format->setString("mime", kMimeTypeAvc);
-    format->setInt32("color-format", OMX_COLOR_FormatAndroidOpaque);
-    format->setInt32("bitrate", gBitRate);
-    format->setFloat("frame-rate", displayFps);
-    format->setInt32("i-frame-interval", 10);
+    format->setInt32(KEY_WIDTH, gVideoWidth);
+    format->setInt32(KEY_HEIGHT, gVideoHeight);
+    format->setString(KEY_MIME, kMimeTypeAvc);
+    format->setInt32(KEY_COLOR_FORMAT, OMX_COLOR_FormatAndroidOpaque);
+    format->setInt32(KEY_BIT_RATE, gBitRate);
+    format->setFloat(KEY_FRAME_RATE, displayFps);
+    format->setInt32(KEY_I_FRAME_INTERVAL, 10);
+    format->setInt32(KEY_MAX_B_FRAMES, gBframes);
+    if (gBframes > 0) {
+        format->setInt32(KEY_PROFILE, AVCProfileMain);
+        format->setInt32(KEY_LEVEL, AVCLevel41);
+    }
 
-    sp<ALooper> looper = new ALooper;
+    sp<android::ALooper> looper = new android::ALooper;
     looper->setName("screenrecord_looper");
     looper->start();
     ALOGV("Creating codec");
@@ -235,10 +270,10 @@
 
     // Set the region of the layer stack we're interested in, which in our
     // case is "all of it".
-    Rect layerStackRect(mainDpyInfo.w, mainDpyInfo.h);
+    Rect layerStackRect(mainDpyInfo.viewportW, mainDpyInfo.viewportH);
 
     // We need to preserve the aspect ratio of the display.
-    float displayAspect = (float) mainDpyInfo.h / (float) mainDpyInfo.w;
+    float displayAspect = (float) mainDpyInfo.viewportH / (float) mainDpyInfo.viewportW;
 
 
     // Set the way we map the output onto the display surface (which will
@@ -315,22 +350,6 @@
 }
 
 /*
- * Set the main display width and height to the actual width and height
- */
-static status_t getActualDisplaySize(const sp<IBinder>& mainDpy, DisplayInfo* mainDpyInfo) {
-    Rect viewport;
-    status_t err = SurfaceComposerClient::getDisplayViewport(mainDpy, &viewport);
-    if (err != NO_ERROR) {
-        fprintf(stderr, "ERROR: unable to get display viewport\n");
-        return err;
-    }
-    mainDpyInfo->w = viewport.width();
-    mainDpyInfo->h = viewport.height();
-
-    return NO_ERROR;
-}
-
-/*
  * Runs the MediaCodec encoder, sending the output to the MediaMuxer.  The
  * input frames are coming from the virtual display as fast as SurfaceFlinger
  * wants to send them.
@@ -400,22 +419,14 @@
                     // useful stuff is hard to get at without a Dalvik VM.
                     err = SurfaceComposerClient::getDisplayInfo(mainDpy,
                             &mainDpyInfo);
-                    if (err == NO_ERROR) {
-                        err = getActualDisplaySize(mainDpy, &mainDpyInfo);
-                        if (err != NO_ERROR) {
-                            fprintf(stderr, "ERROR: unable to set actual display size\n");
-                            return err;
-                        }
-
-                        if (orientation != mainDpyInfo.orientation) {
-                            ALOGD("orientation changed, now %d", mainDpyInfo.orientation);
-                            SurfaceComposerClient::Transaction t;
-                            setDisplayProjection(t, virtualDpy, mainDpyInfo);
-                            t.apply();
-                            orientation = mainDpyInfo.orientation;
-                        }
-                    } else {
+                    if (err != NO_ERROR) {
                         ALOGW("getDisplayInfo(main) failed: %d", err);
+                    } else if (orientation != mainDpyInfo.orientation) {
+                        ALOGD("orientation changed, now %d", mainDpyInfo.orientation);
+                        SurfaceComposerClient::Transaction t;
+                        setDisplayProjection(t, virtualDpy, mainDpyInfo);
+                        t.apply();
+                        orientation = mainDpyInfo.orientation;
                     }
                 }
 
@@ -472,7 +483,7 @@
         case -EAGAIN:                       // INFO_TRY_AGAIN_LATER
             ALOGV("Got -EAGAIN, looping");
             break;
-        case INFO_FORMAT_CHANGED:           // INFO_OUTPUT_FORMAT_CHANGED
+        case android::INFO_FORMAT_CHANGED:    // INFO_OUTPUT_FORMAT_CHANGED
             {
                 // Format includes CSD, which we must provide to muxer.
                 ALOGV("Encoder format changed");
@@ -489,7 +500,7 @@
                 }
             }
             break;
-        case INFO_OUTPUT_BUFFERS_CHANGED:   // INFO_OUTPUT_BUFFERS_CHANGED
+        case android::INFO_OUTPUT_BUFFERS_CHANGED:   // INFO_OUTPUT_BUFFERS_CHANGED
             // Not expected for an encoder; handle it anyway.
             ALOGV("Encoder buffers changed");
             err = encoder->getOutputBuffers(&buffers);
@@ -580,8 +591,12 @@
     self->startThreadPool();
 
     // Get main display parameters.
-    sp<IBinder> mainDpy = SurfaceComposerClient::getBuiltInDisplay(
-            ISurfaceComposer::eDisplayIdMain);
+    const sp<IBinder> mainDpy = SurfaceComposerClient::getInternalDisplayToken();
+    if (mainDpy == nullptr) {
+        fprintf(stderr, "ERROR: no display\n");
+        return NAME_NOT_FOUND;
+    }
+
     DisplayInfo mainDpyInfo;
     err = SurfaceComposerClient::getDisplayInfo(mainDpy, &mainDpyInfo);
     if (err != NO_ERROR) {
@@ -589,25 +604,19 @@
         return err;
     }
 
-    err = getActualDisplaySize(mainDpy, &mainDpyInfo);
-    if (err != NO_ERROR) {
-        fprintf(stderr, "ERROR: unable to set actual display size\n");
-        return err;
-    }
-
     if (gVerbose) {
         printf("Main display is %dx%d @%.2ffps (orientation=%u)\n",
-                mainDpyInfo.w, mainDpyInfo.h, mainDpyInfo.fps,
+                mainDpyInfo.viewportW, mainDpyInfo.viewportH, mainDpyInfo.fps,
                 mainDpyInfo.orientation);
         fflush(stdout);
     }
 
     // Encoder can't take odd number as config
     if (gVideoWidth == 0) {
-        gVideoWidth = floorToEven(mainDpyInfo.w);
+        gVideoWidth = floorToEven(mainDpyInfo.viewportW);
     }
     if (gVideoHeight == 0) {
-        gVideoHeight = floorToEven(mainDpyInfo.h);
+        gVideoHeight = floorToEven(mainDpyInfo.viewportH);
     }
 
     // Configure and start the encoder.
@@ -685,7 +694,9 @@
     sp<MediaMuxer> muxer = NULL;
     FILE* rawFp = NULL;
     switch (gOutputFormat) {
-        case FORMAT_MP4: {
+        case FORMAT_MP4:
+        case FORMAT_WEBM:
+        case FORMAT_3GPP: {
             // Configure muxer.  We have to wait for the CSD blob from the encoder
             // before we can start it.
             err = unlink(fileName);
@@ -698,7 +709,13 @@
                 fprintf(stderr, "ERROR: couldn't open file\n");
                 abort();
             }
-            muxer = new MediaMuxer(fd, MediaMuxer::OUTPUT_FORMAT_MPEG_4);
+            if (gOutputFormat == FORMAT_MP4) {
+                muxer = new MediaMuxer(fd, MediaMuxer::OUTPUT_FORMAT_MPEG_4);
+            } else if (gOutputFormat == FORMAT_WEBM) {
+                muxer = new MediaMuxer(fd, MediaMuxer::OUTPUT_FORMAT_WEBM);
+            } else {
+                muxer = new MediaMuxer(fd, MediaMuxer::OUTPUT_FORMAT_THREE_GPP);
+            }
             close(fd);
             if (gRotate) {
                 muxer->setOrientationHint(90);  // TODO: does this do anything?
@@ -948,6 +965,7 @@
         { "codec-name",         required_argument,  NULL, 'N' },
         { "monotonic-time",     no_argument,        NULL, 'm' },
         { "persistent-surface", no_argument,        NULL, 'p' },
+        { "bframes",            required_argument,  NULL, 'B' },
         { NULL,                 0,                  NULL, 0 }
     };
 
@@ -1018,6 +1036,10 @@
                 gOutputFormat = FORMAT_MP4;
             } else if (strcmp(optarg, "h264") == 0) {
                 gOutputFormat = FORMAT_H264;
+            } else if (strcmp(optarg, "webm") == 0) {
+                gOutputFormat = FORMAT_WEBM;
+            } else if (strcmp(optarg, "3gpp") == 0) {
+                gOutputFormat = FORMAT_3GPP;
             } else if (strcmp(optarg, "frames") == 0) {
                 gOutputFormat = FORMAT_FRAMES;
             } else if (strcmp(optarg, "raw-frames") == 0) {
@@ -1036,6 +1058,11 @@
         case 'p':
             gPersistentSurface = true;
             break;
+        case 'B':
+            if (parseValueWithUnit(optarg, &gBframes) != NO_ERROR) {
+                return 2;
+            }
+            break;
         default:
             if (ic != '?') {
                 fprintf(stderr, "getopt_long returned unexpected value 0x%x\n", ic);
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index c7619af..6eb2e9f 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -8,7 +8,7 @@
         SineSource.cpp
 
 LOCAL_SHARED_LIBRARIES := \
-        libstagefright libmedia libmedia_omx libmediaextractor libutils libbinder \
+        libstagefright libmedia libmedia_omx libutils libbinder \
         libstagefright_foundation libjpeg libui libgui libcutils liblog \
         libhidlbase \
         android.hardware.media.omx@1.0 \
@@ -36,7 +36,7 @@
         record.cpp
 
 LOCAL_SHARED_LIBRARIES := \
-        libstagefright libmedia libmediaextractor liblog libutils libbinder \
+        libstagefright libmedia liblog libutils libbinder \
         libstagefright_foundation
 
 LOCAL_C_INCLUDES:= \
@@ -61,7 +61,7 @@
         recordvideo.cpp
 
 LOCAL_SHARED_LIBRARIES := \
-        libstagefright libmedia libmediaextractor liblog libutils libbinder \
+        libstagefright libmedia liblog libutils libbinder \
         libstagefright_foundation
 
 LOCAL_C_INCLUDES:= \
@@ -87,7 +87,7 @@
         audioloop.cpp
 
 LOCAL_SHARED_LIBRARIES := \
-        libstagefright libmedia libmediaextractor liblog libutils libbinder \
+        libstagefright libmedia liblog libutils libbinder \
         libstagefright_foundation
 
 LOCAL_C_INCLUDES:= \
@@ -111,7 +111,7 @@
 
 LOCAL_SHARED_LIBRARIES := \
         libstagefright liblog libutils libbinder libui libgui \
-        libstagefright_foundation libmedia libcutils libmediaextractor
+        libstagefright_foundation libmedia libcutils
 
 LOCAL_C_INCLUDES:= \
         frameworks/av/media/libstagefright \
@@ -191,7 +191,6 @@
 LOCAL_MODULE:= mediafilter
 
 LOCAL_SANITIZE := cfi
-LOCAL_SANITIZE_DIAG := cfi
 
 include $(BUILD_EXECUTABLE)
 
@@ -204,7 +203,7 @@
 
 LOCAL_SHARED_LIBRARIES := \
         libstagefright liblog libutils libbinder libstagefright_foundation \
-        libcutils libc libmediaextractor
+        libcutils libc
 
 LOCAL_C_INCLUDES:= \
         frameworks/av/media/libstagefright \
diff --git a/cmds/stagefright/codec.cpp b/cmds/stagefright/codec.cpp
index 6a58467..e5a4337 100644
--- a/cmds/stagefright/codec.cpp
+++ b/cmds/stagefright/codec.cpp
@@ -138,7 +138,7 @@
 
     CHECK(!stateByTrack.isEmpty());
 
-    int64_t startTimeUs = ALooper::GetNowUs();
+    int64_t startTimeUs = android::ALooper::GetNowUs();
     int64_t startTimeRender = -1;
 
     for (size_t i = 0; i < stateByTrack.size(); ++i) {
@@ -307,7 +307,7 @@
         }
     }
 
-    int64_t elapsedTimeUs = ALooper::GetNowUs() - startTimeUs;
+    int64_t elapsedTimeUs = android::ALooper::GetNowUs() - startTimeUs;
 
     for (size_t i = 0; i < stateByTrack.size(); ++i) {
         CodecState *state = &stateByTrack.editValueAt(i);
@@ -366,13 +366,13 @@
             case 'T':
             {
                 useTimestamp = true;
+                FALLTHROUGH_INTENDED;
             }
-            // fall through
             case 'R':
             {
                 renderSurface = true;
+                FALLTHROUGH_INTENDED;
             }
-            // fall through
             case 'S':
             {
                 useSurface = true;
@@ -400,7 +400,7 @@
 
     ProcessState::self()->startThreadPool();
 
-    sp<ALooper> looper = new ALooper;
+    sp<android::ALooper> looper = new android::ALooper;
     looper->start();
 
     sp<SurfaceComposerClient> composerClient;
@@ -411,10 +411,12 @@
         composerClient = new SurfaceComposerClient;
         CHECK_EQ(composerClient->initCheck(), (status_t)OK);
 
-        sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(
-                ISurfaceComposer::eDisplayIdMain));
+        const sp<IBinder> display = SurfaceComposerClient::getInternalDisplayToken();
+        CHECK(display != nullptr);
+
         DisplayInfo info;
-        SurfaceComposerClient::getDisplayInfo(display, &info);
+        CHECK_EQ(SurfaceComposerClient::getDisplayInfo(display, &info), NO_ERROR);
+
         ssize_t displayWidth = info.w;
         ssize_t displayHeight = info.h;
 
diff --git a/cmds/stagefright/mediafilter.cpp b/cmds/stagefright/mediafilter.cpp
index f24d2dd..2cf6955 100644
--- a/cmds/stagefright/mediafilter.cpp
+++ b/cmds/stagefright/mediafilter.cpp
@@ -310,7 +310,7 @@
 }
 
 static int decode(
-        const sp<ALooper> &looper,
+        const sp<android::ALooper> &looper,
         const char *path,
         const sp<Surface> &surface,
         bool renderSurface,
@@ -465,7 +465,7 @@
     filterState->mSignalledInputEOS = false;
     filterState->mSawOutputEOS = false;
 
-    int64_t startTimeUs = ALooper::GetNowUs();
+    int64_t startTimeUs = android::ALooper::GetNowUs();
     int64_t startTimeRender = -1;
 
     for (size_t i = 0; i < stateByTrack.size(); ++i) {
@@ -643,7 +643,7 @@
                 useTimestamp, &startTimeRender);
     }
 
-    int64_t elapsedTimeUs = ALooper::GetNowUs() - startTimeUs;
+    int64_t elapsedTimeUs = android::ALooper::GetNowUs() - startTimeUs;
 
     for (size_t i = 0; i < stateByTrack.size(); ++i) {
         CodecState *state = &stateByTrack.editValueAt(i);
@@ -706,13 +706,13 @@
             case 'T':
             {
                 useTimestamp = true;
+                FALLTHROUGH_INTENDED;
             }
-            // fall through
             case 'R':
             {
                 renderSurface = true;
+                FALLTHROUGH_INTENDED;
             }
-            // fall through
             case 'S':
             {
                 useSurface = true;
@@ -737,7 +737,7 @@
 
     ProcessState::self()->startThreadPool();
 
-    android::sp<ALooper> looper = new ALooper;
+    android::sp<android::ALooper> looper = new android::ALooper;
     looper->start();
 
     android::sp<SurfaceComposerClient> composerClient;
@@ -748,10 +748,12 @@
         composerClient = new SurfaceComposerClient;
         CHECK_EQ((status_t)OK, composerClient->initCheck());
 
-        android::sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(
-                ISurfaceComposer::eDisplayIdMain));
+        const android::sp<IBinder> display = SurfaceComposerClient::getInternalDisplayToken();
+        CHECK(display != nullptr);
+
         DisplayInfo info;
-        SurfaceComposerClient::getDisplayInfo(display, &info);
+        CHECK_EQ(SurfaceComposerClient::getDisplayInfo(display, &info), NO_ERROR);
+
         ssize_t displayWidth = info.w;
         ssize_t displayHeight = info.h;
 
diff --git a/cmds/stagefright/record.cpp b/cmds/stagefright/record.cpp
index 44b0015..95a16f3 100644
--- a/cmds/stagefright/record.cpp
+++ b/cmds/stagefright/record.cpp
@@ -17,7 +17,6 @@
 #include "SineSource.h"
 
 #include <binder/ProcessState.h>
-#include <media/MediaExtractor.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ALooper.h>
 #include <media/stagefright/foundation/AMessage.h>
@@ -28,6 +27,7 @@
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaCodecSource.h>
 #include <media/stagefright/MetaData.h>
+#include <media/stagefright/MediaExtractor.h>
 #include <media/stagefright/MediaExtractorFactory.h>
 #include <media/stagefright/MPEG4Writer.h>
 #include <media/stagefright/SimpleDecodingSource.h>
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 61fc897..bf36be0 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -32,7 +32,6 @@
 #include <binder/IServiceManager.h>
 #include <binder/ProcessState.h>
 #include <media/DataSource.h>
-#include <media/MediaExtractor.h>
 #include <media/MediaSource.h>
 #include <media/ICrypto.h>
 #include <media/IMediaHTTPService.h>
@@ -47,9 +46,11 @@
 #include <media/stagefright/JPEGSource.h>
 #include <media/stagefright/InterfaceUtils.h>
 #include <media/stagefright/MediaCodec.h>
+#include <media/stagefright/MediaCodecConstants.h>
 #include <media/stagefright/MediaCodecList.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MediaExtractor.h>
 #include <media/stagefright/MediaExtractorFactory.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/SimpleDecodingSource.h>
@@ -78,6 +79,7 @@
 static bool gPlaybackAudio;
 static bool gWriteMP4;
 static bool gDisplayHistogram;
+static bool gVerbose = false;
 static bool showProgress = true;
 static String8 gWriteMP4Filename;
 static String8 gComponentNameOverride;
@@ -159,6 +161,11 @@
             break;
         }
 
+        if (gVerbose) {
+            MetaDataBase &meta = mbuf->meta_data();
+            fprintf(stdout, "sample format: %s\n", meta.toString().c_str());
+        }
+
         CHECK_EQ(
                 fwrite((const uint8_t *)mbuf->data() + mbuf->range_offset(),
                        1,
@@ -218,11 +225,15 @@
         player->setSource(rawSource);
         rawSource.clear();
 
-        player->start(true /* sourceAlreadyStarted */);
+        err = player->start(true /* sourceAlreadyStarted */);
 
-        status_t finalStatus;
-        while (!player->reachedEOS(&finalStatus)) {
-            usleep(100000ll);
+        if (err == OK) {
+            status_t finalStatus;
+            while (!player->reachedEOS(&finalStatus)) {
+                usleep(100000ll);
+            }
+        } else {
+            fprintf(stderr, "unable to start playback err=%d (0x%08x)\n", err, err);
         }
 
         delete player;
@@ -348,7 +359,10 @@
                     decodeTimesUs.push(delayDecodeUs);
                 }
 
-                if (showProgress && (n++ % 16) == 0) {
+                if (gVerbose) {
+                    MetaDataBase &meta = buffer->meta_data();
+                    fprintf(stdout, "%ld sample format: %s\n", numFrames, meta.toString().c_str());
+                } else if (showProgress && (n++ % 16) == 0) {
                     printf(".");
                     fflush(stdout);
                 }
@@ -579,12 +593,12 @@
                 break;
             }
 
+            CHECK(buffer != NULL);
+
             if (buffer->range_length() > 0) {
                 break;
             }
 
-            CHECK(buffer != NULL);
-
             buffer->release();
             buffer = NULL;
         }
@@ -615,7 +629,7 @@
     fprintf(stderr, "       -l(ist) components\n");
     fprintf(stderr, "       -m max-number-of-frames-to-decode in each pass\n");
     fprintf(stderr, "       -b bug to reproduce\n");
-    fprintf(stderr, "       -p(rofiles) dump decoder profiles supported\n");
+    fprintf(stderr, "       -i(nfo) dump codec info (profiles and color formats supported, details)\n");
     fprintf(stderr, "       -t(humbnail) extract video thumbnail or album art\n");
     fprintf(stderr, "       -s(oftware) prefer software codec\n");
     fprintf(stderr, "       -r(hardware) force to use hardware codec\n");
@@ -630,55 +644,134 @@
     fprintf(stderr, "       -T allocate buffers from a surface texture\n");
     fprintf(stderr, "       -d(ump) output_filename (raw stream data to a file)\n");
     fprintf(stderr, "       -D(ump) output_filename (decoded PCM data to a file)\n");
+    fprintf(stderr, "       -v be more verbose\n");
 }
 
-static void dumpCodecProfiles(bool queryDecoders) {
-    const char *kMimeTypes[] = {
-        MEDIA_MIMETYPE_VIDEO_AVC, MEDIA_MIMETYPE_VIDEO_MPEG4,
-        MEDIA_MIMETYPE_VIDEO_H263, MEDIA_MIMETYPE_AUDIO_AAC,
-        MEDIA_MIMETYPE_AUDIO_AMR_NB, MEDIA_MIMETYPE_AUDIO_AMR_WB,
-        MEDIA_MIMETYPE_AUDIO_MPEG, MEDIA_MIMETYPE_AUDIO_G711_MLAW,
-        MEDIA_MIMETYPE_AUDIO_G711_ALAW, MEDIA_MIMETYPE_AUDIO_VORBIS,
-        MEDIA_MIMETYPE_VIDEO_VP8, MEDIA_MIMETYPE_VIDEO_VP9,
-        MEDIA_MIMETYPE_VIDEO_DOLBY_VISION
-    };
-
-    const char *codecType = queryDecoders? "decoder" : "encoder";
-    printf("%s profiles:\n", codecType);
+static void dumpCodecDetails(bool queryDecoders) {
+    const char *codecType = queryDecoders? "Decoder" : "Encoder";
+    printf("\n%s infos by media types:\n"
+           "=============================\n", codecType);
 
     sp<IMediaCodecList> list = MediaCodecList::getInstance();
     size_t numCodecs = list->countCodecs();
 
-    for (size_t k = 0; k < sizeof(kMimeTypes) / sizeof(kMimeTypes[0]); ++k) {
-        printf("type '%s':\n", kMimeTypes[k]);
+    // gather all media types supported by codec class, and link to codecs that support them
+    KeyedVector<AString, Vector<sp<MediaCodecInfo>>> allMediaTypes;
+    for (size_t codec_ix = 0; codec_ix < numCodecs; ++codec_ix) {
+        sp<MediaCodecInfo> info = list->getCodecInfo(codec_ix);
+        if (info->isEncoder() == !queryDecoders) {
+            Vector<AString> supportedMediaTypes;
+            info->getSupportedMediaTypes(&supportedMediaTypes);
+            if (!supportedMediaTypes.size()) {
+                printf("warning: %s does not support any media types\n",
+                        info->getCodecName());
+            } else {
+                for (const AString &mediaType : supportedMediaTypes) {
+                    if (allMediaTypes.indexOfKey(mediaType) < 0) {
+                        allMediaTypes.add(mediaType, Vector<sp<MediaCodecInfo>>());
+                    }
+                    allMediaTypes.editValueFor(mediaType).add(info);
+                }
+            }
+        }
+    }
 
-        for (size_t index = 0; index < numCodecs; ++index) {
-            sp<MediaCodecInfo> info = list->getCodecInfo(index);
-            if (info == NULL || info->isEncoder() != !queryDecoders) {
-                continue;
-            }
-            sp<MediaCodecInfo::Capabilities> caps = info->getCapabilitiesFor(kMimeTypes[k]);
+    KeyedVector<AString, bool> visitedCodecs;
+    for (size_t type_ix = 0; type_ix < allMediaTypes.size(); ++type_ix) {
+        const AString &mediaType = allMediaTypes.keyAt(type_ix);
+        printf("\nMedia type '%s':\n", mediaType.c_str());
+
+        for (const sp<MediaCodecInfo> &info : allMediaTypes.valueAt(type_ix)) {
+            sp<MediaCodecInfo::Capabilities> caps = info->getCapabilitiesFor(mediaType.c_str());
             if (caps == NULL) {
+                printf("warning: %s does not have capabilities for type %s\n",
+                        info->getCodecName(), mediaType.c_str());
                 continue;
             }
-            printf("  %s '%s' supports ",
+            printf("  %s \"%s\" supports\n",
                        codecType, info->getCodecName());
 
-            Vector<MediaCodecInfo::ProfileLevel> profileLevels;
-            caps->getSupportedProfileLevels(&profileLevels);
-            if (profileLevels.size() == 0) {
-                printf("NOTHING.\n");
-                continue;
+            auto printList = [](const char *type, const Vector<AString> &values){
+                printf("    %s: [", type);
+                for (size_t j = 0; j < values.size(); ++j) {
+                    printf("\n      %s%s", values[j].c_str(),
+                            j == values.size() - 1 ? " " : ",");
+                }
+                printf("]\n");
+            };
+
+            if (visitedCodecs.indexOfKey(info->getCodecName()) < 0) {
+                visitedCodecs.add(info->getCodecName(), true);
+                {
+                    Vector<AString> aliases;
+                    info->getAliases(&aliases);
+                    // quote alias
+                    for (AString &alias : aliases) {
+                        alias.insert("\"", 1, 0);
+                        alias.append('"');
+                    }
+                    printList("aliases", aliases);
+                }
+                {
+                    uint32_t attrs = info->getAttributes();
+                    Vector<AString> list;
+                    list.add(AStringPrintf("encoder: %d", !!(attrs & MediaCodecInfo::kFlagIsEncoder)));
+                    list.add(AStringPrintf("vendor: %d", !!(attrs & MediaCodecInfo::kFlagIsVendor)));
+                    list.add(AStringPrintf("software-only: %d", !!(attrs & MediaCodecInfo::kFlagIsSoftwareOnly)));
+                    list.add(AStringPrintf("hw-accelerated: %d", !!(attrs & MediaCodecInfo::kFlagIsHardwareAccelerated)));
+                    printList(AStringPrintf("attributes: %#x", attrs).c_str(), list);
+                }
+
+                printf("    owner: \"%s\"\n", info->getOwnerName());
+                printf("    rank: %u\n", info->getRank());
+            } else {
+                printf("    aliases, attributes, owner, rank: see above\n");
             }
 
-            for (size_t j = 0; j < profileLevels.size(); ++j) {
-                const MediaCodecInfo::ProfileLevel &profileLevel = profileLevels[j];
+            {
+                Vector<AString> list;
+                Vector<MediaCodecInfo::ProfileLevel> profileLevels;
+                caps->getSupportedProfileLevels(&profileLevels);
+                for (const MediaCodecInfo::ProfileLevel &pl : profileLevels) {
+                    const char *niceProfile =
+                        mediaType.equalsIgnoreCase(MIMETYPE_AUDIO_AAC)   ? asString_AACObject(pl.mProfile) :
+                        mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_MPEG2) ? asString_MPEG2Profile(pl.mProfile) :
+                        mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_H263)  ? asString_H263Profile(pl.mProfile) :
+                        mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_MPEG4) ? asString_MPEG4Profile(pl.mProfile) :
+                        mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_AVC)   ? asString_AVCProfile(pl.mProfile) :
+                        mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_VP8)   ? asString_VP8Profile(pl.mProfile) :
+                        mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_HEVC)  ? asString_HEVCProfile(pl.mProfile) :
+                        mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_VP9)   ? asString_VP9Profile(pl.mProfile) :
+                        mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_AV1)   ? asString_AV1Profile(pl.mProfile) :"??";
+                    const char *niceLevel =
+                        mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_MPEG2) ? asString_MPEG2Level(pl.mLevel) :
+                        mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_H263)  ? asString_H263Level(pl.mLevel) :
+                        mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_MPEG4) ? asString_MPEG4Level(pl.mLevel) :
+                        mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_AVC)   ? asString_AVCLevel(pl.mLevel) :
+                        mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_VP8)   ? asString_VP8Level(pl.mLevel) :
+                        mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_HEVC)  ? asString_HEVCTierLevel(pl.mLevel) :
+                        mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_VP9)   ? asString_VP9Level(pl.mLevel) :
+                        mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_AV1)   ? asString_AV1Level(pl.mLevel) :
+                        "??";
 
-                printf("%s%u/%u", j > 0 ? ", " : "",
-                        profileLevel.mProfile, profileLevel.mLevel);
+                    list.add(AStringPrintf("% 5u/% 5u (%s/%s)",
+                            pl.mProfile, pl.mLevel, niceProfile, niceLevel));
+                }
+                printList("profile/levels", list);
             }
 
-            printf("\n");
+            {
+                Vector<AString> list;
+                Vector<uint32_t> colors;
+                caps->getSupportedColorFormats(&colors);
+                for (uint32_t color : colors) {
+                    list.add(AStringPrintf("%#x (%s)", color,
+                            asString_ColorFormat((int32_t)color)));
+                }
+                printList("colors", list);
+            }
+
+            printf("    details: %s\n", caps->getDetails()->debugString(6).c_str());
         }
     }
 }
@@ -688,7 +781,7 @@
 
     bool audioOnly = false;
     bool listComponents = false;
-    bool dumpProfiles = false;
+    bool dumpCodecInfo = false;
     bool extractThumbnail = false;
     bool seekTest = false;
     bool useSurfaceAlloc = false;
@@ -705,10 +798,10 @@
     gWriteMP4 = false;
     gDisplayHistogram = false;
 
-    sp<ALooper> looper;
+    sp<android::ALooper> looper;
 
     int res;
-    while ((res = getopt(argc, argv, "haqn:lm:b:ptsrow:kN:xSTd:D:")) >= 0) {
+    while ((res = getopt(argc, argv, "vhaqn:lm:b:itsrow:kN:xSTd:D:")) >= 0) {
         switch (res) {
             case 'a':
             {
@@ -778,9 +871,9 @@
                 break;
             }
 
-            case 'p':
+            case 'i':
             {
-                dumpProfiles = true;
+                dumpCodecInfo = true;
                 break;
             }
 
@@ -832,6 +925,12 @@
                 break;
             }
 
+            case 'v':
+            {
+                gVerbose = true;
+                break;
+            }
+
             case '?':
             case 'h':
             default:
@@ -915,9 +1014,9 @@
         return 0;
     }
 
-    if (dumpProfiles) {
-        dumpCodecProfiles(true /* queryDecoders */);
-        dumpCodecProfiles(false /* queryDecoders */);
+    if (dumpCodecInfo) {
+        dumpCodecDetails(true /* queryDecoders */);
+        dumpCodecDetails(false /* queryDecoders */);
     }
 
     if (listComponents) {
diff --git a/cmds/stagefright/stream.cpp b/cmds/stagefright/stream.cpp
index b0199d8..35bdbc0 100644
--- a/cmds/stagefright/stream.cpp
+++ b/cmds/stagefright/stream.cpp
@@ -24,7 +24,6 @@
 #include <media/DataSource.h>
 #include <media/IMediaHTTPService.h>
 #include <media/IStreamSource.h>
-#include <media/MediaExtractor.h>
 #include <media/mediaplayer.h>
 #include <media/MediaSource.h>
 #include <media/stagefright/foundation/ADebug.h>
@@ -32,6 +31,7 @@
 #include <media/stagefright/DataSourceFactory.h>
 #include <media/stagefright/InterfaceUtils.h>
 #include <media/stagefright/MPEG2TSWriter.h>
+#include <media/stagefright/MediaExtractor.h>
 #include <media/stagefright/MediaExtractorFactory.h>
 #include <media/stagefright/MetaData.h>
 
@@ -318,10 +318,12 @@
     sp<SurfaceComposerClient> composerClient = new SurfaceComposerClient;
     CHECK_EQ(composerClient->initCheck(), (status_t)OK);
 
-    sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(
-            ISurfaceComposer::eDisplayIdMain));
+    const sp<IBinder> display = SurfaceComposerClient::getInternalDisplayToken();
+    CHECK(display != nullptr);
+
     DisplayInfo info;
-    SurfaceComposerClient::getDisplayInfo(display, &info);
+    CHECK_EQ(SurfaceComposerClient::getDisplayInfo(display, &info), NO_ERROR);
+
     ssize_t displayWidth = info.w;
     ssize_t displayHeight = info.h;
 
diff --git a/drm/common/Android.bp b/drm/common/Android.bp
index 1552c3f..272684c 100644
--- a/drm/common/Android.bp
+++ b/drm/common/Android.bp
@@ -35,7 +35,7 @@
 
     cflags: ["-Wall", "-Werror"],
 
-    static_libs: ["libbinder"],
+    shared_libs: ["libbinder"],
 
     export_include_dirs: ["include"],
 }
diff --git a/drm/common/DrmEngineBase.cpp b/drm/common/DrmEngineBase.cpp
index f734905..aec5959 100644
--- a/drm/common/DrmEngineBase.cpp
+++ b/drm/common/DrmEngineBase.cpp
@@ -79,12 +79,12 @@
 }
 
 status_t DrmEngineBase::consumeRights(
-    int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
+    int uniqueId, sp<DecryptHandle>& decryptHandle, int action, bool reserve) {
     return onConsumeRights(uniqueId, decryptHandle, action, reserve);
 }
 
 status_t DrmEngineBase::setPlaybackStatus(
-    int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
+    int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus, int64_t position) {
     return onSetPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
 }
 
@@ -120,7 +120,7 @@
 }
 
 status_t DrmEngineBase::openDecryptSession(
-    int uniqueId, DecryptHandle* decryptHandle,
+    int uniqueId, sp<DecryptHandle>& decryptHandle,
     int fd, off64_t offset, off64_t length, const char* mime) {
 
     if (!mime || mime[0] == '\0') {
@@ -131,7 +131,7 @@
 }
 
 status_t DrmEngineBase::openDecryptSession(
-    int uniqueId, DecryptHandle* decryptHandle,
+    int uniqueId, sp<DecryptHandle>& decryptHandle,
     const char* uri, const char* mime) {
     if (!mime || mime[0] == '\0') {
         return onOpenDecryptSession(uniqueId, decryptHandle, uri);
@@ -139,33 +139,33 @@
     return onOpenDecryptSession(uniqueId, decryptHandle, uri, mime);
 }
 
-status_t DrmEngineBase::openDecryptSession(int uniqueId, DecryptHandle* decryptHandle,
+status_t DrmEngineBase::openDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle,
         const DrmBuffer& buf, const String8& mimeType) {
     return onOpenDecryptSession(uniqueId, decryptHandle, buf, mimeType);
 }
 
-status_t DrmEngineBase::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+status_t DrmEngineBase::closeDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle) {
     return onCloseDecryptSession(uniqueId, decryptHandle);
 }
 
 status_t DrmEngineBase::initializeDecryptUnit(
-    int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
+    int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
     return onInitializeDecryptUnit(uniqueId, decryptHandle, decryptUnitId, headerInfo);
 }
 
 status_t DrmEngineBase::decrypt(
-    int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+    int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
     const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
     return onDecrypt(uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
 }
 
 status_t DrmEngineBase::finalizeDecryptUnit(
-    int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
+    int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId) {
     return onFinalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
 }
 
 ssize_t DrmEngineBase::pread(
-    int uniqueId, DecryptHandle* decryptHandle, void* buffer, ssize_t numBytes, off64_t offset) {
+    int uniqueId, sp<DecryptHandle>& decryptHandle, void* buffer, ssize_t numBytes, off64_t offset) {
     return onPread(uniqueId, decryptHandle, buffer, numBytes, offset);
 }
 
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp
index 44f98dd..a6d33b0 100644
--- a/drm/common/IDrmManagerService.cpp
+++ b/drm/common/IDrmManagerService.cpp
@@ -39,7 +39,7 @@
 using namespace android;
 
 static void writeDecryptHandleToParcelData(
-        const DecryptHandle* handle, Parcel* data) {
+        const sp<DecryptHandle>& handle, Parcel* data) {
     data->writeInt32(handle->decryptId);
     data->writeString8(handle->mimeType);
     data->writeInt32(handle->decryptApiType);
@@ -67,7 +67,7 @@
 }
 
 static void readDecryptHandleFromParcelData(
-        DecryptHandle* handle, const Parcel& data) {
+        sp<DecryptHandle>& handle, const Parcel& data) {
     if (0 == data.dataAvail()) {
         return;
     }
@@ -99,7 +99,7 @@
     }
 }
 
-static void clearDecryptHandle(DecryptHandle* handle) {
+static void clearDecryptHandle(sp<DecryptHandle> &handle) {
     if (handle == NULL) {
         return;
     }
@@ -414,7 +414,7 @@
 }
 
 status_t BpDrmManagerService::consumeRights(
-            int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int action, bool reserve) {
     ALOGV("consumeRights");
     Parcel data, reply;
 
@@ -431,7 +431,7 @@
 }
 
 status_t BpDrmManagerService::setPlaybackStatus(
-            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus, int64_t position) {
     ALOGV("setPlaybackStatus");
     Parcel data, reply;
 
@@ -603,7 +603,7 @@
     return reply.readInt32();
 }
 
-DecryptHandle* BpDrmManagerService::openDecryptSession(
+sp<DecryptHandle> BpDrmManagerService::openDecryptSession(
             int uniqueId, int fd, off64_t offset, off64_t length, const char* mime) {
     ALOGV("Entering BpDrmManagerService::openDecryptSession");
     Parcel data, reply;
@@ -621,7 +621,7 @@
 
     remote()->transact(OPEN_DECRYPT_SESSION, data, &reply);
 
-    DecryptHandle* handle = NULL;
+    sp<DecryptHandle> handle;
     if (0 != reply.dataAvail()) {
         handle = new DecryptHandle();
         readDecryptHandleFromParcelData(handle, reply);
@@ -629,7 +629,7 @@
     return handle;
 }
 
-DecryptHandle* BpDrmManagerService::openDecryptSession(
+sp<DecryptHandle> BpDrmManagerService::openDecryptSession(
         int uniqueId, const char* uri, const char* mime) {
 
     ALOGV("Entering BpDrmManagerService::openDecryptSession: mime=%s", mime? mime: "NULL");
@@ -646,7 +646,7 @@
 
     remote()->transact(OPEN_DECRYPT_SESSION_FROM_URI, data, &reply);
 
-    DecryptHandle* handle = NULL;
+    sp<DecryptHandle> handle;
     if (0 != reply.dataAvail()) {
         handle = new DecryptHandle();
         readDecryptHandleFromParcelData(handle, reply);
@@ -656,7 +656,7 @@
     return handle;
 }
 
-DecryptHandle* BpDrmManagerService::openDecryptSession(
+sp<DecryptHandle> BpDrmManagerService::openDecryptSession(
             int uniqueId, const DrmBuffer& buf, const String8& mimeType) {
     ALOGV("Entering BpDrmManagerService::openDecryptSession");
     Parcel data, reply;
@@ -673,7 +673,7 @@
 
     remote()->transact(OPEN_DECRYPT_SESSION_FOR_STREAMING, data, &reply);
 
-    DecryptHandle* handle = NULL;
+    sp<DecryptHandle> handle;
     if (0 != reply.dataAvail()) {
         handle = new DecryptHandle();
         readDecryptHandleFromParcelData(handle, reply);
@@ -683,7 +683,7 @@
     return handle;
 }
 
-status_t BpDrmManagerService::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+status_t BpDrmManagerService::closeDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle) {
     ALOGV("closeDecryptSession");
     Parcel data, reply;
 
@@ -698,7 +698,7 @@
 }
 
 status_t BpDrmManagerService::initializeDecryptUnit(
-            int uniqueId, DecryptHandle* decryptHandle,
+            int uniqueId, sp<DecryptHandle>& decryptHandle,
             int decryptUnitId, const DrmBuffer* headerInfo) {
     ALOGV("initializeDecryptUnit");
     Parcel data, reply;
@@ -718,7 +718,7 @@
 }
 
 status_t BpDrmManagerService::decrypt(
-            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
             const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
     ALOGV("decrypt");
     Parcel data, reply;
@@ -754,7 +754,7 @@
 }
 
 status_t BpDrmManagerService::finalizeDecryptUnit(
-            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId) {
     ALOGV("finalizeDecryptUnit");
     Parcel data, reply;
 
@@ -770,7 +770,7 @@
 }
 
 ssize_t BpDrmManagerService::pread(
-            int uniqueId, DecryptHandle* decryptHandle, void* buffer,
+            int uniqueId, sp<DecryptHandle>& decryptHandle, void* buffer,
             ssize_t numBytes, off64_t offset) {
     ALOGV("read");
     Parcel data, reply;
@@ -1128,16 +1128,16 @@
 
         const int uniqueId = data.readInt32();
 
-        DecryptHandle handle;
-        readDecryptHandleFromParcelData(&handle, data);
+        sp<DecryptHandle> handle = new DecryptHandle();
+        readDecryptHandleFromParcelData(handle, data);
 
         const int action = data.readInt32();
         const bool reserve = static_cast<bool>(data.readInt32());
         const status_t status
-            = consumeRights(uniqueId, &handle, action, reserve);
+            = consumeRights(uniqueId, handle, action, reserve);
         reply->writeInt32(status);
 
-        clearDecryptHandle(&handle);
+        clearDecryptHandle(handle);
         return DRM_NO_ERROR;
     }
 
@@ -1148,16 +1148,16 @@
 
         const int uniqueId = data.readInt32();
 
-        DecryptHandle handle;
-        readDecryptHandleFromParcelData(&handle, data);
+        sp<DecryptHandle> handle = new DecryptHandle();
+        readDecryptHandleFromParcelData(handle, data);
 
         const int playbackStatus = data.readInt32();
         const int64_t position = data.readInt64();
         const status_t status
-            = setPlaybackStatus(uniqueId, &handle, playbackStatus, position);
+            = setPlaybackStatus(uniqueId, handle, playbackStatus, position);
         reply->writeInt32(status);
 
-        clearDecryptHandle(&handle);
+        clearDecryptHandle(handle);
         return DRM_NO_ERROR;
     }
 
@@ -1329,13 +1329,13 @@
         const off64_t length = data.readInt64();
         const String8 mime = data.readString8();
 
-        DecryptHandle* handle
+        sp<DecryptHandle> handle
             = openDecryptSession(uniqueId, fd, offset, length, mime.string());
 
-        if (NULL != handle) {
-            writeDecryptHandleToParcelData(handle, reply);
+        if (NULL != handle.get()) {
+            writeDecryptHandleToParcelData(handle.get(), reply);
             clearDecryptHandle(handle);
-            delete handle; handle = NULL;
+            handle.clear();
         }
         return DRM_NO_ERROR;
     }
@@ -1349,13 +1349,13 @@
         const String8 uri = data.readString8();
         const String8 mime = data.readString8();
 
-        DecryptHandle* handle = openDecryptSession(uniqueId, uri.string(), mime.string());
+        sp<DecryptHandle> handle = openDecryptSession(uniqueId, uri.string(), mime.string());
 
-        if (NULL != handle) {
-            writeDecryptHandleToParcelData(handle, reply);
+        if (NULL != handle.get()) {
+            writeDecryptHandleToParcelData(handle.get(), reply);
 
             clearDecryptHandle(handle);
-            delete handle; handle = NULL;
+            handle.clear();
         } else {
             ALOGV("NULL decryptHandle is returned");
         }
@@ -1373,13 +1373,12 @@
                 bufferSize);
         const String8 mimeType(data.readString8());
 
-        DecryptHandle* handle = openDecryptSession(uniqueId, buf, mimeType);
+        sp<DecryptHandle> handle = openDecryptSession(uniqueId, buf, mimeType);
 
         if (handle != NULL) {
             writeDecryptHandleToParcelData(handle, reply);
             clearDecryptHandle(handle);
-            delete handle;
-            handle = NULL;
+            handle.clear();
         } else {
             ALOGV("NULL decryptHandle is returned");
         }
@@ -1393,7 +1392,7 @@
 
         const int uniqueId = data.readInt32();
 
-        DecryptHandle* handle = new DecryptHandle();
+        sp<DecryptHandle> handle = new DecryptHandle();
         readDecryptHandleFromParcelData(handle, data);
 
         const status_t status = closeDecryptSession(uniqueId, handle);
@@ -1408,8 +1407,8 @@
 
         const int uniqueId = data.readInt32();
 
-        DecryptHandle handle;
-        readDecryptHandleFromParcelData(&handle, data);
+        sp<DecryptHandle> handle = new DecryptHandle();
+        readDecryptHandleFromParcelData(handle, data);
 
         const int decryptUnitId = data.readInt32();
 
@@ -1417,17 +1416,17 @@
         const uint32_t bufferSize = data.readInt32();
         if (bufferSize > data.dataAvail()) {
             reply->writeInt32(BAD_VALUE);
-            clearDecryptHandle(&handle);
+            clearDecryptHandle(handle);
             return DRM_NO_ERROR;
         }
         DrmBuffer* headerInfo = NULL;
         headerInfo = new DrmBuffer((char *)data.readInplace(bufferSize), bufferSize);
 
         const status_t status
-            = initializeDecryptUnit(uniqueId, &handle, decryptUnitId, headerInfo);
+            = initializeDecryptUnit(uniqueId, handle, decryptUnitId, headerInfo);
         reply->writeInt32(status);
 
-        clearDecryptHandle(&handle);
+        clearDecryptHandle(handle);
         delete headerInfo; headerInfo = NULL;
         return DRM_NO_ERROR;
     }
@@ -1439,8 +1438,8 @@
 
         const int uniqueId = data.readInt32();
 
-        DecryptHandle handle;
-        readDecryptHandleFromParcelData(&handle, data);
+        sp<DecryptHandle> handle = new DecryptHandle;
+        readDecryptHandleFromParcelData(handle, data);
 
         const int decryptUnitId = data.readInt32();
         const uint32_t decBufferSize = data.readInt32();
@@ -1450,7 +1449,7 @@
             decBufferSize > MAX_BINDER_TRANSACTION_SIZE) {
             reply->writeInt32(BAD_VALUE);
             reply->writeInt32(0);
-            clearDecryptHandle(&handle);
+            clearDecryptHandle(handle);
             return DRM_NO_ERROR;
         }
 
@@ -1470,7 +1469,7 @@
         }
 
         const status_t status
-            = decrypt(uniqueId, &handle, decryptUnitId, encBuffer, &decBuffer, IV);
+            = decrypt(uniqueId, handle, decryptUnitId, encBuffer, &decBuffer, IV);
 
         reply->writeInt32(status);
 
@@ -1480,7 +1479,7 @@
             reply->write(decBuffer->data, size);
         }
 
-        clearDecryptHandle(&handle);
+        clearDecryptHandle(handle);
         delete encBuffer; encBuffer = NULL;
         delete decBuffer; decBuffer = NULL;
         delete [] buffer; buffer = NULL;
@@ -1495,13 +1494,13 @@
 
         const int uniqueId = data.readInt32();
 
-        DecryptHandle handle;
-        readDecryptHandleFromParcelData(&handle, data);
+        sp<DecryptHandle> handle = new DecryptHandle();
+        readDecryptHandleFromParcelData(handle, data);
 
-        const status_t status = finalizeDecryptUnit(uniqueId, &handle, data.readInt32());
+        const status_t status = finalizeDecryptUnit(uniqueId, handle, data.readInt32());
         reply->writeInt32(status);
 
-        clearDecryptHandle(&handle);
+        clearDecryptHandle(handle);
         return DRM_NO_ERROR;
     }
 
@@ -1512,8 +1511,8 @@
 
         const int uniqueId = data.readInt32();
 
-        DecryptHandle handle;
-        readDecryptHandleFromParcelData(&handle, data);
+        sp<DecryptHandle> handle = new DecryptHandle();
+        readDecryptHandleFromParcelData(handle, data);
 
         const uint32_t numBytes = data.readInt32();
         if (numBytes > MAX_BINDER_TRANSACTION_SIZE) {
@@ -1524,13 +1523,13 @@
 
         const off64_t offset = data.readInt64();
 
-        ssize_t result = pread(uniqueId, &handle, buffer, numBytes, offset);
+        ssize_t result = pread(uniqueId, handle, buffer, numBytes, offset);
         reply->writeInt32(result);
         if (0 < result) {
             reply->write(buffer, result);
         }
 
-        clearDecryptHandle(&handle);
+        clearDecryptHandle(handle);
         delete [] buffer, buffer = NULL;
         return DRM_NO_ERROR;
     }
diff --git a/drm/common/include/DrmEngineBase.h b/drm/common/include/DrmEngineBase.h
index 417107f..73f11a4 100644
--- a/drm/common/include/DrmEngineBase.h
+++ b/drm/common/include/DrmEngineBase.h
@@ -59,10 +59,11 @@
 
     int checkRightsStatus(int uniqueId, const String8& path, int action);
 
-    status_t consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+    status_t consumeRights(int uniqueId, sp<DecryptHandle>& decryptHandle, int action,
+            bool reserve);
 
     status_t setPlaybackStatus(
-            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position);
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus, int64_t position);
 
     bool validateAction(
             int uniqueId, const String8& path, int action, const ActionDescription& description);
@@ -80,27 +81,28 @@
     DrmSupportInfo* getSupportInfo(int uniqueId);
 
     status_t openDecryptSession(
-            int uniqueId, DecryptHandle* decryptHandle,
+            int uniqueId, sp<DecryptHandle>& decryptHandle,
             int fd, off64_t offset, off64_t length, const char* mime);
 
     status_t openDecryptSession(
-            int uniqueId, DecryptHandle* decryptHandle,
+            int uniqueId, sp<DecryptHandle>& decryptHandle,
             const char* uri, const char* mime);
 
-    status_t openDecryptSession(int uniqueId, DecryptHandle* decryptHandle,
+    status_t openDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle,
             const DrmBuffer& buf, const String8& mimeType);
 
-    status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+    status_t closeDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle);
 
-    status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+    status_t initializeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
             int decryptUnitId, const DrmBuffer* headerInfo);
 
-    status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+    status_t decrypt(int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
             const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
 
-    status_t finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+    status_t finalizeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
+            int decryptUnitId);
 
-    ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+    ssize_t pread(int uniqueId, sp<DecryptHandle>& decryptHandle,
             void* buffer, ssize_t numBytes, off64_t offset);
 
 protected:
@@ -265,7 +267,7 @@
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    virtual status_t onConsumeRights(int uniqueId, DecryptHandle* decryptHandle,
+    virtual status_t onConsumeRights(int uniqueId, sp<DecryptHandle>& decryptHandle,
             int action, bool reserve) = 0;
 
     /**
@@ -280,7 +282,8 @@
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
     virtual status_t onSetPlaybackStatus(
-            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) = 0;
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus,
+            int64_t position) = 0;
 
     /**
      * Validates whether an action on the DRM content is allowed or not.
@@ -381,7 +384,7 @@
      *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
      */
     virtual status_t onOpenDecryptSession(
-            int uniqueId, DecryptHandle* decryptHandle,
+            int uniqueId, sp<DecryptHandle>& decryptHandle,
             int fd, off64_t offset, off64_t length) = 0;
 
     /**
@@ -398,7 +401,7 @@
      *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
      */
     virtual status_t onOpenDecryptSession(
-            int /* uniqueId */, DecryptHandle* /* decryptHandle */,
+            int /* uniqueId */, sp<DecryptHandle>& /* decryptHandle */,
             int /* fd */, off64_t /* offset */, off64_t /* length */,
             const char* /* mime */) {
 
@@ -415,7 +418,7 @@
      *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
      */
     virtual status_t onOpenDecryptSession(
-            int uniqueId, DecryptHandle* decryptHandle,
+            int uniqueId, sp<DecryptHandle>& decryptHandle,
             const char* uri) = 0;
 
     /**
@@ -430,7 +433,7 @@
      *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
      */
     virtual status_t onOpenDecryptSession(
-            int /* uniqueId */, DecryptHandle* /* decryptHandle */,
+            int /* uniqueId */, sp<DecryptHandle>& /* decryptHandle */,
             const char* /* uri */, const char* /* mime */) {
 
         return DRM_ERROR_CANNOT_HANDLE;
@@ -447,7 +450,7 @@
      *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
      */
     virtual status_t onOpenDecryptSession(int /* uniqueId */,
-            DecryptHandle* /* decryptHandle */,
+            sp<DecryptHandle>& /* decryptHandle */,
             const DrmBuffer& /* buf */,
             const String8& /* mimeType */) {
         return DRM_ERROR_CANNOT_HANDLE;
@@ -461,7 +464,7 @@
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    virtual status_t onCloseDecryptSession(int uniqueId, DecryptHandle* decryptHandle) = 0;
+    virtual status_t onCloseDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle) = 0;
 
     /**
      * Initialize decryption for the given unit of the protected content
@@ -473,7 +476,7 @@
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    virtual status_t onInitializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+    virtual status_t onInitializeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
             int decryptUnitId, const DrmBuffer* headerInfo) = 0;
 
     /**
@@ -493,7 +496,7 @@
      *     DRM_ERROR_SESSION_NOT_OPENED, DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED,
      *     DRM_ERROR_DECRYPT for failure.
      */
-    virtual status_t onDecrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+    virtual status_t onDecrypt(int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
             const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) = 0;
 
     /**
@@ -506,7 +509,7 @@
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
     virtual status_t onFinalizeDecryptUnit(
-            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) = 0;
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId) = 0;
 
     /**
      * Reads the specified number of bytes from an open DRM file.
@@ -519,7 +522,7 @@
      *
      * @return Number of bytes read. Returns -1 for Failure.
      */
-    virtual ssize_t onPread(int uniqueId, DecryptHandle* decryptHandle,
+    virtual ssize_t onPread(int uniqueId, sp<DecryptHandle>& decryptHandle,
             void* buffer, ssize_t numBytes, off64_t offset) = 0;
 };
 
diff --git a/drm/common/include/IDrmEngine.h b/drm/common/include/IDrmEngine.h
index acc8ed9..1837a11 100644
--- a/drm/common/include/IDrmEngine.h
+++ b/drm/common/include/IDrmEngine.h
@@ -210,7 +210,7 @@
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
     virtual status_t consumeRights(
-            int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) = 0;
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int action, bool reserve) = 0;
 
     /**
      * Informs the DRM Engine about the playback actions performed on the DRM files.
@@ -223,7 +223,7 @@
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    virtual status_t setPlaybackStatus(int uniqueId, DecryptHandle* decryptHandle,
+    virtual status_t setPlaybackStatus(int uniqueId, sp<DecryptHandle>& decryptHandle,
             int playbackStatus, int64_t position) = 0;
 
     /**
@@ -327,7 +327,7 @@
      *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
      */
     virtual status_t openDecryptSession(
-        int uniqueId, DecryptHandle* decryptHandle,
+        int uniqueId, sp<DecryptHandle>& decryptHandle,
         int fd, off64_t offset, off64_t length, const char* mime) = 0;
 
     /**
@@ -342,7 +342,7 @@
      *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
      */
     virtual status_t openDecryptSession(
-        int uniqueId, DecryptHandle* decryptHandle,
+        int uniqueId, sp<DecryptHandle>& decryptHandle,
         const char* uri, const char* mime) = 0;
 
     /**
@@ -355,7 +355,7 @@
      * @return
      *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
      */
-    virtual status_t openDecryptSession(int uniqueId, DecryptHandle* decryptHandle,
+    virtual status_t openDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle,
             const DrmBuffer& buf, const String8& mimeType) = 0;
 
     /**
@@ -366,7 +366,7 @@
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    virtual status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) = 0;
+    virtual status_t closeDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle) = 0;
 
     /**
      * Initialize decryption for the given unit of the protected content
@@ -378,7 +378,7 @@
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    virtual status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+    virtual status_t initializeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
             int decryptUnitId, const DrmBuffer* headerInfo) = 0;
 
     /**
@@ -398,7 +398,7 @@
      *     DRM_ERROR_SESSION_NOT_OPENED, DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED,
      *     DRM_ERROR_DECRYPT for failure.
      */
-    virtual status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+    virtual status_t decrypt(int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
             const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) = 0;
 
     /**
@@ -411,7 +411,7 @@
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
     virtual status_t finalizeDecryptUnit(
-            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) = 0;
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId) = 0;
 
     /**
      * Reads the specified number of bytes from an open DRM file.
@@ -424,7 +424,7 @@
      *
      * @return Number of bytes read. Returns -1 for Failure.
      */
-    virtual ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+    virtual ssize_t pread(int uniqueId, sp<DecryptHandle>& decryptHandle,
             void* buffer, ssize_t numBytes, off64_t offset) = 0;
 };
 
diff --git a/drm/common/include/IDrmManagerService.h b/drm/common/include/IDrmManagerService.h
index 0376b49..836ae0a 100644
--- a/drm/common/include/IDrmManagerService.h
+++ b/drm/common/include/IDrmManagerService.h
@@ -115,10 +115,11 @@
     virtual int checkRightsStatus(int uniqueId, const String8& path, int action) = 0;
 
     virtual status_t consumeRights(
-            int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) = 0;
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int action, bool reserve) = 0;
 
     virtual status_t setPlaybackStatus(
-            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) = 0;
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus,
+            int64_t position) = 0;
 
     virtual bool validateAction(
             int uniqueId, const String8& path,
@@ -138,28 +139,28 @@
     virtual status_t getAllSupportInfo(
             int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) = 0;
 
-    virtual DecryptHandle* openDecryptSession(
+    virtual sp<DecryptHandle> openDecryptSession(
                 int uniqueId, int fd, off64_t offset,
                 off64_t length, const char* mime) = 0;
 
-    virtual DecryptHandle* openDecryptSession(
+    virtual sp<DecryptHandle> openDecryptSession(
                 int uniqueId, const char* uri, const char* mime) = 0;
 
-    virtual DecryptHandle* openDecryptSession(
+    virtual sp<DecryptHandle> openDecryptSession(
             int uniqueId, const DrmBuffer& buf, const String8& mimeType) = 0;
 
-    virtual status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) = 0;
+    virtual status_t closeDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle) = 0;
 
-    virtual status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+    virtual status_t initializeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
             int decryptUnitId, const DrmBuffer* headerInfo) = 0;
 
-    virtual status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+    virtual status_t decrypt(int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
             const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) = 0;
 
     virtual status_t finalizeDecryptUnit(
-            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) = 0;
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId) = 0;
 
-    virtual ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+    virtual ssize_t pread(int uniqueId, sp<DecryptHandle>& decryptHandle,
             void* buffer, ssize_t numBytes,off64_t offset) = 0;
 };
 
@@ -203,10 +204,10 @@
     virtual int checkRightsStatus(int uniqueId, const String8& path, int action);
 
     virtual status_t consumeRights(
-            int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int action, bool reserve);
 
     virtual status_t setPlaybackStatus(
-            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position);
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus, int64_t position);
 
     virtual bool validateAction(
             int uniqueId, const String8& path, int action, const ActionDescription& description);
@@ -225,28 +226,28 @@
     virtual status_t getAllSupportInfo(
             int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray);
 
-    virtual DecryptHandle* openDecryptSession(
+    virtual sp<DecryptHandle> openDecryptSession(
                 int uniqueId, int fd, off64_t offset, off64_t length,
                 const char* mime);
 
-    virtual DecryptHandle* openDecryptSession(
+    virtual sp<DecryptHandle> openDecryptSession(
                 int uniqueId, const char* uri, const char* mime);
 
-    virtual DecryptHandle* openDecryptSession(
+    virtual sp<DecryptHandle> openDecryptSession(
             int uniqueId, const DrmBuffer& buf, const String8& mimeType);
 
-    virtual status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+    virtual status_t closeDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle);
 
-    virtual status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+    virtual status_t initializeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
             int decryptUnitId, const DrmBuffer* headerInfo);
 
-    virtual status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+    virtual status_t decrypt(int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
             const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
 
     virtual status_t finalizeDecryptUnit(
-            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId);
 
-    virtual ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+    virtual ssize_t pread(int uniqueId, sp<DecryptHandle>& decryptHandle,
             void* buffer, ssize_t numBytes, off64_t offset);
 };
 
diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp
index bf04a89..afbcb39 100644
--- a/drm/drmserver/DrmManager.cpp
+++ b/drm/drmserver/DrmManager.cpp
@@ -267,7 +267,7 @@
 }
 
 status_t DrmManager::consumeRights(
-    int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
+    int uniqueId, sp<DecryptHandle>& decryptHandle, int action, bool reserve) {
     status_t result = DRM_ERROR_UNKNOWN;
     Mutex::Autolock _l(mDecryptLock);
     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
@@ -278,7 +278,7 @@
 }
 
 status_t DrmManager::setPlaybackStatus(
-    int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
+    int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus, int64_t position) {
     status_t result = DRM_ERROR_UNKNOWN;
     Mutex::Autolock _l(mDecryptLock);
     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
@@ -396,15 +396,15 @@
     return DRM_NO_ERROR;
 }
 
-DecryptHandle* DrmManager::openDecryptSession(
+sp<DecryptHandle> DrmManager::openDecryptSession(
         int uniqueId, int fd, off64_t offset, off64_t length, const char* mime) {
 
     Mutex::Autolock _l(mDecryptLock);
     status_t result = DRM_ERROR_CANNOT_HANDLE;
     Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
 
-    DecryptHandle* handle = new DecryptHandle();
-    if (NULL != handle) {
+    sp<DecryptHandle> handle = new DecryptHandle();
+    if (NULL != handle.get()) {
         handle->decryptId = mDecryptSessionId + 1;
 
         for (size_t index = 0; index < plugInIdList.size(); index++) {
@@ -420,19 +420,19 @@
         }
     }
     if (DRM_NO_ERROR != result) {
-        delete handle; handle = NULL;
+        handle.clear();
     }
     return handle;
 }
 
-DecryptHandle* DrmManager::openDecryptSession(
+sp<DecryptHandle> DrmManager::openDecryptSession(
         int uniqueId, const char* uri, const char* mime) {
     Mutex::Autolock _l(mDecryptLock);
     status_t result = DRM_ERROR_CANNOT_HANDLE;
     Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
 
-    DecryptHandle* handle = new DecryptHandle();
-    if (NULL != handle) {
+    sp<DecryptHandle> handle = new DecryptHandle();
+    if (NULL != handle.get()) {
         handle->decryptId = mDecryptSessionId + 1;
 
         for (size_t index = 0; index < plugInIdList.size(); index++) {
@@ -448,20 +448,20 @@
         }
     }
     if (DRM_NO_ERROR != result) {
-        delete handle; handle = NULL;
+        handle.clear();
         ALOGV("DrmManager::openDecryptSession: no capable plug-in found");
     }
     return handle;
 }
 
-DecryptHandle* DrmManager::openDecryptSession(
+sp<DecryptHandle> DrmManager::openDecryptSession(
         int uniqueId, const DrmBuffer& buf, const String8& mimeType) {
     Mutex::Autolock _l(mDecryptLock);
     status_t result = DRM_ERROR_CANNOT_HANDLE;
     Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
 
-    DecryptHandle* handle = new DecryptHandle();
-    if (NULL != handle) {
+    sp<DecryptHandle> handle = new DecryptHandle();
+    if (NULL != handle.get()) {
         handle->decryptId = mDecryptSessionId + 1;
 
         for (size_t index = 0; index < plugInIdList.size(); index++) {
@@ -477,20 +477,19 @@
         }
     }
     if (DRM_NO_ERROR != result) {
-        delete handle;
-        handle = NULL;
+        handle.clear();
         ALOGV("DrmManager::openDecryptSession: no capable plug-in found");
     }
     return handle;
 }
 
-status_t DrmManager::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+status_t DrmManager::closeDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle) {
     Mutex::Autolock _l(mDecryptLock);
     status_t result = DRM_ERROR_UNKNOWN;
     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
         IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
         result = drmEngine->closeDecryptSession(uniqueId, decryptHandle);
-        if (DRM_NO_ERROR == result) {
+        if (DRM_NO_ERROR == result && NULL != decryptHandle.get()) {
             mDecryptSessionMap.removeItem(decryptHandle->decryptId);
         }
     }
@@ -498,7 +497,8 @@
 }
 
 status_t DrmManager::initializeDecryptUnit(
-    int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
+        int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
+        const DrmBuffer* headerInfo) {
     status_t result = DRM_ERROR_UNKNOWN;
     Mutex::Autolock _l(mDecryptLock);
     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
@@ -508,7 +508,7 @@
     return result;
 }
 
-status_t DrmManager::decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+status_t DrmManager::decrypt(int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
             const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
     status_t result = DRM_ERROR_UNKNOWN;
 
@@ -522,7 +522,7 @@
 }
 
 status_t DrmManager::finalizeDecryptUnit(
-            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId) {
     status_t result = DRM_ERROR_UNKNOWN;
     Mutex::Autolock _l(mDecryptLock);
     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
@@ -532,7 +532,7 @@
     return result;
 }
 
-ssize_t DrmManager::pread(int uniqueId, DecryptHandle* decryptHandle,
+ssize_t DrmManager::pread(int uniqueId, sp<DecryptHandle>& decryptHandle,
             void* buffer, ssize_t numBytes, off64_t offset) {
     ssize_t result = DECRYPT_FILE_ERROR;
 
diff --git a/drm/drmserver/DrmManager.h b/drm/drmserver/DrmManager.h
index e7cdd36..26222bc 100644
--- a/drm/drmserver/DrmManager.h
+++ b/drm/drmserver/DrmManager.h
@@ -89,10 +89,11 @@
 
     int checkRightsStatus(int uniqueId, const String8& path, int action);
 
-    status_t consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+    status_t consumeRights(int uniqueId, sp<DecryptHandle>& decryptHandle, int action,
+            bool reserve);
 
     status_t setPlaybackStatus(
-            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position);
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus, int64_t position);
 
     bool validateAction(
             int uniqueId, const String8& path, int action, const ActionDescription& description);
@@ -109,25 +110,26 @@
 
     status_t getAllSupportInfo(int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray);
 
-    DecryptHandle* openDecryptSession(
+    sp<DecryptHandle> openDecryptSession(
             int uniqueId, int fd, off64_t offset, off64_t length, const char* mime);
 
-    DecryptHandle* openDecryptSession(int uniqueId, const char* uri, const char* mime);
+    sp<DecryptHandle> openDecryptSession(int uniqueId, const char* uri, const char* mime);
 
-    DecryptHandle* openDecryptSession(int uniqueId, const DrmBuffer& buf,
+    sp<DecryptHandle> openDecryptSession(int uniqueId, const DrmBuffer& buf,
             const String8& mimeType);
 
-    status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+    status_t closeDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle);
 
-    status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+    status_t initializeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
             int decryptUnitId, const DrmBuffer* headerInfo);
 
-    status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+    status_t decrypt(int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
             const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
 
-    status_t finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+    status_t finalizeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
+            int decryptUnitId);
 
-    ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+    ssize_t pread(int uniqueId, sp<DecryptHandle>& decryptHandle,
             void* buffer, ssize_t numBytes, off64_t offset);
 
     void onInfo(const DrmInfoEvent& event);
diff --git a/drm/drmserver/DrmManagerService.cpp b/drm/drmserver/DrmManagerService.cpp
index dad599b..2600a2c 100644
--- a/drm/drmserver/DrmManagerService.cpp
+++ b/drm/drmserver/DrmManagerService.cpp
@@ -58,22 +58,26 @@
     return drm_perm_labels[index];
 }
 
-bool DrmManagerService::selinuxIsProtectedCallAllowed(pid_t spid, drm_perm_t perm) {
+bool DrmManagerService::selinuxIsProtectedCallAllowed(pid_t spid, const char* ssid, drm_perm_t perm) {
     if (selinux_enabled <= 0) {
         return true;
     }
 
-    char *sctx;
+    char *sctx = NULL;
     const char *selinux_class = "drmservice";
     const char *str_perm = get_perm_label(perm);
 
-    if (getpidcon(spid, &sctx) != 0) {
-        ALOGE("SELinux: getpidcon(pid=%d) failed.\n", spid);
-        return false;
+    if (ssid == NULL) {
+        android_errorWriteLog(0x534e4554, "121035042");
+
+        if (getpidcon(spid, &sctx) != 0) {
+            ALOGE("SELinux: getpidcon(pid=%d) failed.\n", spid);
+            return false;
+        }
     }
 
-    bool allowed = (selinux_check_access(sctx, drmserver_context, selinux_class,
-            str_perm, NULL) == 0);
+    bool allowed = (selinux_check_access(ssid ? ssid : sctx, drmserver_context,
+            selinux_class, str_perm, NULL) == 0);
     freecon(sctx);
 
     return allowed;
@@ -86,10 +90,11 @@
     IPCThreadState* ipcState = IPCThreadState::self();
     uid_t uid = ipcState->getCallingUid();
     pid_t spid = ipcState->getCallingPid();
+    const char* ssid = ipcState->getCallingSid();
 
     for (unsigned int i = 0; i < trustedUids.size(); ++i) {
         if (trustedUids[i] == uid) {
-            return selinuxIsProtectedCallAllowed(spid, perm);
+            return selinuxIsProtectedCallAllowed(spid, ssid, perm);
         }
     }
     return false;
@@ -97,7 +102,9 @@
 
 void DrmManagerService::instantiate() {
     ALOGV("instantiate");
-    defaultServiceManager()->addService(String16("drm.drmManager"), new DrmManagerService());
+    sp<DrmManagerService> service = new DrmManagerService();
+    service->setRequestingSid(true);
+    defaultServiceManager()->addService(String16("drm.drmManager"), service);
 
     if (0 >= trustedUids.size()) {
         // TODO
@@ -206,7 +213,7 @@
 }
 
 status_t DrmManagerService::consumeRights(
-            int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int action, bool reserve) {
     ALOGV("Entering consumeRights");
     if (!isProtectedCallAllowed(CONSUME_RIGHTS)) {
         return DRM_ERROR_NO_PERMISSION;
@@ -215,7 +222,7 @@
 }
 
 status_t DrmManagerService::setPlaybackStatus(
-            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus, int64_t position) {
     ALOGV("Entering setPlaybackStatus");
     if (!isProtectedCallAllowed(SET_PLAYBACK_STATUS)) {
         return DRM_ERROR_NO_PERMISSION;
@@ -262,7 +269,7 @@
     return mDrmManager->getAllSupportInfo(uniqueId, length, drmSupportInfoArray);
 }
 
-DecryptHandle* DrmManagerService::openDecryptSession(
+sp<DecryptHandle> DrmManagerService::openDecryptSession(
             int uniqueId, int fd, off64_t offset, off64_t length, const char* mime) {
     ALOGV("Entering DrmManagerService::openDecryptSession");
     if (isProtectedCallAllowed(OPEN_DECRYPT_SESSION)) {
@@ -272,7 +279,7 @@
     return NULL;
 }
 
-DecryptHandle* DrmManagerService::openDecryptSession(
+sp<DecryptHandle> DrmManagerService::openDecryptSession(
             int uniqueId, const char* uri, const char* mime) {
     ALOGV("Entering DrmManagerService::openDecryptSession with uri");
     if (isProtectedCallAllowed(OPEN_DECRYPT_SESSION)) {
@@ -282,7 +289,7 @@
     return NULL;
 }
 
-DecryptHandle* DrmManagerService::openDecryptSession(
+sp<DecryptHandle> DrmManagerService::openDecryptSession(
             int uniqueId, const DrmBuffer& buf, const String8& mimeType) {
     ALOGV("Entering DrmManagerService::openDecryptSession for streaming");
     if (isProtectedCallAllowed(OPEN_DECRYPT_SESSION)) {
@@ -292,7 +299,7 @@
     return NULL;
 }
 
-status_t DrmManagerService::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+status_t DrmManagerService::closeDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle) {
     ALOGV("Entering closeDecryptSession");
     if (!isProtectedCallAllowed(CLOSE_DECRYPT_SESSION)) {
         return DRM_ERROR_NO_PERMISSION;
@@ -300,7 +307,7 @@
     return mDrmManager->closeDecryptSession(uniqueId, decryptHandle);
 }
 
-status_t DrmManagerService::initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+status_t DrmManagerService::initializeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
             int decryptUnitId, const DrmBuffer* headerInfo) {
     ALOGV("Entering initializeDecryptUnit");
     if (!isProtectedCallAllowed(INITIALIZE_DECRYPT_UNIT)) {
@@ -310,7 +317,7 @@
 }
 
 status_t DrmManagerService::decrypt(
-            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
             const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
     ALOGV("Entering decrypt");
     if (!isProtectedCallAllowed(DECRYPT)) {
@@ -320,7 +327,7 @@
 }
 
 status_t DrmManagerService::finalizeDecryptUnit(
-            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId) {
     ALOGV("Entering finalizeDecryptUnit");
     if (!isProtectedCallAllowed(FINALIZE_DECRYPT_UNIT)) {
         return DRM_ERROR_NO_PERMISSION;
@@ -328,7 +335,7 @@
     return mDrmManager->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
 }
 
-ssize_t DrmManagerService::pread(int uniqueId, DecryptHandle* decryptHandle,
+ssize_t DrmManagerService::pread(int uniqueId, sp<DecryptHandle>& decryptHandle,
             void* buffer, ssize_t numBytes, off64_t offset) {
     ALOGV("Entering pread");
     if (!isProtectedCallAllowed(PREAD)) {
diff --git a/drm/drmserver/DrmManagerService.h b/drm/drmserver/DrmManagerService.h
index 45cee2e..2e27a3c 100644
--- a/drm/drmserver/DrmManagerService.h
+++ b/drm/drmserver/DrmManagerService.h
@@ -60,7 +60,7 @@
 
     static const char *get_perm_label(drm_perm_t perm);
 
-    static bool selinuxIsProtectedCallAllowed(pid_t spid, drm_perm_t perm);
+    static bool selinuxIsProtectedCallAllowed(pid_t spid, const char* ssid, drm_perm_t perm);
 
     static bool isProtectedCallAllowed(drm_perm_t perm);
 
@@ -95,10 +95,11 @@
 
     int checkRightsStatus(int uniqueId, const String8& path,int action);
 
-    status_t consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+    status_t consumeRights(int uniqueId, sp<DecryptHandle>& decryptHandle, int action,
+            bool reserve);
 
     status_t setPlaybackStatus(
-            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position);
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus, int64_t position);
 
     bool validateAction(int uniqueId, const String8& path,
             int action, const ActionDescription& description);
@@ -115,26 +116,27 @@
 
     status_t getAllSupportInfo(int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray);
 
-    DecryptHandle* openDecryptSession(
+    sp<DecryptHandle> openDecryptSession(
         int uniqueId, int fd, off64_t offset, off64_t length, const char *mime);
 
-    DecryptHandle* openDecryptSession(
+    sp<DecryptHandle> openDecryptSession(
         int uniqueId, const char* uri, const char* mime);
 
-    DecryptHandle* openDecryptSession(int uniqueId, const DrmBuffer& buf,
+    sp<DecryptHandle> openDecryptSession(int uniqueId, const DrmBuffer& buf,
             const String8& mimeType);
 
-    status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+    status_t closeDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle);
 
-    status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+    status_t initializeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
             int decryptUnitId, const DrmBuffer* headerInfo);
 
-    status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+    status_t decrypt(int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
             const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
 
-    status_t finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+    status_t finalizeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
+            int decryptUnitId);
 
-    ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+    ssize_t pread(int uniqueId, sp<DecryptHandle>& decryptHandle,
             void* buffer, ssize_t numBytes, off64_t offset);
 
     virtual status_t dump(int fd, const Vector<String16>& args);
diff --git a/drm/libdrmframework/Android.bp b/drm/libdrmframework/Android.bp
index 43ba72b..940c17d 100644
--- a/drm/libdrmframework/Android.bp
+++ b/drm/libdrmframework/Android.bp
@@ -39,4 +39,3 @@
     cflags: ["-Werror"],
 }
 
-subdirs = ["plugins/*"]
diff --git a/drm/libdrmframework/DrmManagerClientImpl.cpp b/drm/libdrmframework/DrmManagerClientImpl.cpp
index c047eb1..b0a441b 100644
--- a/drm/libdrmframework/DrmManagerClientImpl.cpp
+++ b/drm/libdrmframework/DrmManagerClientImpl.cpp
@@ -183,7 +183,7 @@
     status_t status = DRM_ERROR_UNKNOWN;
     if (NULL != decryptHandle.get()) {
         status = getDrmManagerService()->consumeRights(
-                uniqueId, decryptHandle.get(), action, reserve);
+                uniqueId, decryptHandle, action, reserve);
     }
     return status;
 }
@@ -194,7 +194,7 @@
     status_t status = DRM_ERROR_UNKNOWN;
     if (NULL != decryptHandle.get()) {
         status = getDrmManagerService()->setPlaybackStatus(
-                uniqueId, decryptHandle.get(), playbackStatus, position);
+                uniqueId, decryptHandle, playbackStatus, position);
     }
     return status;
 }
@@ -267,7 +267,7 @@
 sp<DecryptHandle> DrmManagerClientImpl::openDecryptSession(
         int uniqueId, const char* uri, const char* mime) {
 
-    DecryptHandle* handle = NULL;
+    sp<DecryptHandle> handle;
     if (NULL != uri) {
         handle = getDrmManagerService()->openDecryptSession(uniqueId, uri, mime);
     }
@@ -284,7 +284,7 @@
     status_t status = DRM_ERROR_UNKNOWN;
     if (NULL != decryptHandle.get()) {
         status = getDrmManagerService()->closeDecryptSession(
-                uniqueId, decryptHandle.get());
+                uniqueId, decryptHandle);
     }
     return status;
 }
@@ -295,7 +295,7 @@
     status_t status = DRM_ERROR_UNKNOWN;
     if ((NULL != decryptHandle.get()) && (NULL != headerInfo)) {
         status = getDrmManagerService()->initializeDecryptUnit(
-                uniqueId, decryptHandle.get(), decryptUnitId, headerInfo);
+                uniqueId, decryptHandle, decryptUnitId, headerInfo);
     }
     return status;
 }
@@ -308,7 +308,7 @@
     if ((NULL != decryptHandle.get()) && (NULL != encBuffer)
         && (NULL != decBuffer) && (NULL != *decBuffer)) {
         status = getDrmManagerService()->decrypt(
-                uniqueId, decryptHandle.get(), decryptUnitId,
+                uniqueId, decryptHandle, decryptUnitId,
                 encBuffer, decBuffer, IV);
     }
     return status;
@@ -319,7 +319,7 @@
     status_t status = DRM_ERROR_UNKNOWN;
     if (NULL != decryptHandle.get()) {
         status = getDrmManagerService()->finalizeDecryptUnit(
-                    uniqueId, decryptHandle.get(), decryptUnitId);
+                    uniqueId, decryptHandle, decryptUnitId);
     }
     return status;
 }
@@ -329,7 +329,7 @@
     ssize_t retCode = INVALID_VALUE;
     if ((NULL != decryptHandle.get()) && (NULL != buffer) && (0 < numBytes)) {
         retCode = getDrmManagerService()->pread(
-                uniqueId, decryptHandle.get(), buffer, numBytes, offset);
+                uniqueId, decryptHandle, buffer, numBytes, offset);
     }
     return retCode;
 }
diff --git a/drm/libdrmframework/plugins/common/Android.bp b/drm/libdrmframework/plugins/common/Android.bp
deleted file mode 100644
index 213e57f..0000000
--- a/drm/libdrmframework/plugins/common/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["util"]
diff --git a/drm/libdrmframework/plugins/forward-lock/Android.bp b/drm/libdrmframework/plugins/forward-lock/Android.bp
deleted file mode 100644
index f884c14..0000000
--- a/drm/libdrmframework/plugins/forward-lock/Android.bp
+++ /dev/null
@@ -1,4 +0,0 @@
-subdirs = [
-    "FwdLockEngine",
-    "internal-format",
-]
diff --git a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.bp b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.bp
index 28a78aa..bb9d7ec 100644
--- a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.bp
+++ b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.bp
@@ -29,8 +29,7 @@
     srcs: ["src/FwdLockEngine.cpp"],
 
     shared_libs: [
-        "libicui18n",
-        "libicuuc",
+        "libandroidicu",
         "libutils",
         "liblog",
         "libdl",
diff --git a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/include/FwdLockEngine.h b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/include/FwdLockEngine.h
index a571b3a..b62ddb9 100644
--- a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/include/FwdLockEngine.h
+++ b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/include/FwdLockEngine.h
@@ -198,7 +198,7 @@
  *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
  */
 status_t onConsumeRights(int uniqueId,
-                         DecryptHandle* decryptHandle,
+                         sp<DecryptHandle>& decryptHandle,
                          int action,
                          bool reserve);
 
@@ -215,12 +215,12 @@
  */
 #ifdef USE_64BIT_DRM_API
 status_t onSetPlaybackStatus(int uniqueId,
-                             DecryptHandle* decryptHandle,
+                             sp<DecryptHandle>& decryptHandle,
                              int playbackStatus,
                              int64_t position);
 #else
 status_t onSetPlaybackStatus(int uniqueId,
-                             DecryptHandle* decryptHandle,
+                             sp<DecryptHandle>& decryptHandle,
                              int playbackStatus,
                              int position);
 #endif
@@ -330,11 +330,11 @@
  */
 #ifdef USE_64BIT_DRM_API
 status_t onOpenDecryptSession(int uniqueId,
-                              DecryptHandle* decryptHandle,
+                              sp<DecryptHandle>& decryptHandle,
                               int fd, off64_t offset, off64_t length);
 #else
 status_t onOpenDecryptSession(int uniqueId,
-                              DecryptHandle* decryptHandle,
+                              sp<DecryptHandle>& decryptHandle,
                               int fd, int offset, int length);
 #endif
 
@@ -348,7 +348,7 @@
  *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
  */
 status_t onOpenDecryptSession(int uniqueId,
-                              DecryptHandle* decryptHandle,
+                              sp<DecryptHandle>& decryptHandle,
                               const char* uri);
 
 /**
@@ -360,7 +360,7 @@
  *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
  */
 status_t onCloseDecryptSession(int uniqueId,
-                               DecryptHandle* decryptHandle);
+                               sp<DecryptHandle>& decryptHandle);
 
 /**
  * Initialize decryption for the given unit of the protected content.
@@ -373,7 +373,7 @@
  *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
  */
 status_t onInitializeDecryptUnit(int uniqueId,
-                                 DecryptHandle* decryptHandle,
+                                 sp<DecryptHandle>& decryptHandle,
                                  int decryptUnitId,
                                  const DrmBuffer* headerInfo);
 
@@ -394,7 +394,7 @@
  *     DRM_ERROR_DECRYPT for failure.
  */
 status_t onDecrypt(int uniqueId,
-                   DecryptHandle* decryptHandle,
+                   sp<DecryptHandle>& decryptHandle,
                    int decryptUnitId,
                    const DrmBuffer* encBuffer,
                    DrmBuffer** decBuffer);
@@ -416,7 +416,7 @@
  *     DRM_ERROR_SESSION_NOT_OPENED, DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED,
  *     DRM_ERROR_DECRYPT for failure.
  */
-status_t onDecrypt(int uniqueId, DecryptHandle* decryptHandle,
+status_t onDecrypt(int uniqueId, sp<DecryptHandle>& decryptHandle,
                    int decryptUnitId, const DrmBuffer* encBuffer,
                    DrmBuffer** decBuffer, DrmBuffer* IV);
 
@@ -430,7 +430,7 @@
  *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
  */
 status_t onFinalizeDecryptUnit(int uniqueId,
-                               DecryptHandle* decryptHandle,
+                               sp<DecryptHandle>& decryptHandle,
                                int decryptUnitId);
 
 /**
@@ -445,7 +445,7 @@
  * @retval -1 Failure.
  */
 ssize_t onRead(int uniqueId,
-               DecryptHandle* decryptHandle,
+               sp<DecryptHandle>& decryptHandle,
                void* pBuffer,
                int numBytes);
 
@@ -463,12 +463,12 @@
  */
 #ifdef USE_64BIT_DRM_API
 off64_t onLseek(int uniqueId,
-                DecryptHandle* decryptHandle,
+                sp<DecryptHandle>& decryptHandle,
                 off64_t offset,
                 int whence);
 #else
 off_t onLseek(int uniqueId,
-              DecryptHandle* decryptHandle,
+              sp<DecryptHandle>& decryptHandle,
               off_t offset,
               int whence);
 #endif
@@ -486,13 +486,13 @@
  */
 #ifdef USE_64BIT_DRM_API
 ssize_t onPread(int uniqueId,
-                DecryptHandle* decryptHandle,
+                sp<DecryptHandle>& decryptHandle,
                 void* buffer,
                 ssize_t numBytes,
                 off64_t offset);
 #else
 ssize_t onPread(int uniqueId,
-                DecryptHandle* decryptHandle,
+                sp<DecryptHandle>& decryptHandle,
                 void* buffer,
                 ssize_t numBytes,
                 off_t offset);
diff --git a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
index 73eea89..769de0c 100644
--- a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
+++ b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
@@ -294,7 +294,7 @@
 }
 
 status_t FwdLockEngine::onConsumeRights(int /* uniqueId */,
-                                        DecryptHandle* /* decryptHandle */,
+                                        sp<DecryptHandle>& /* decryptHandle */,
                                         int /* action */,
                                         bool /* reserve */) {
     // No rights consumption
@@ -372,11 +372,13 @@
 }
 
 #ifdef USE_64BIT_DRM_API
-status_t FwdLockEngine::onSetPlaybackStatus(int /* uniqueId */, DecryptHandle* /* decryptHandle */,
-                                            int /* playbackStatus */, int64_t /* position */) {
+status_t FwdLockEngine::onSetPlaybackStatus(int /* uniqueId */,
+        sp<DecryptHandle>& /* decryptHandle */, int /* playbackStatus */,
+        int64_t /* position */) {
 #else
-status_t FwdLockEngine::onSetPlaybackStatus(int /* uniqueId */, DecryptHandle* /* decryptHandle */,
-                                            int /* playbackStatus */, int /* position */) {
+status_t FwdLockEngine::onSetPlaybackStatus(int /* uniqueId */,
+        sp<DecryptHandle>& /* decryptHandle */,
+        int /* playbackStatus */, int /* position */) {
 #endif
     // Not used
     LOG_VERBOSE("FwdLockEngine::onSetPlaybackStatus");
@@ -470,13 +472,13 @@
 
 #ifdef USE_64BIT_DRM_API
 status_t FwdLockEngine::onOpenDecryptSession(int /* uniqueId */,
-                                             DecryptHandle* decryptHandle,
+                                             sp<DecryptHandle>& decryptHandle,
                                              int fd,
                                              off64_t offset,
                                              off64_t /* length */) {
 #else
 status_t FwdLockEngine::onOpenDecryptSession(int /* uniqueId */,
-                                             DecryptHandle* decryptHandle,
+                                             sp<DecryptHandle>& decryptHandle,
                                              int fd,
                                              int offset,
                                              int /* length */) {
@@ -487,7 +489,7 @@
     LOG_VERBOSE("FwdLockEngine::onOpenDecryptSession");
 
     if ((-1 < fd) &&
-        (NULL != decryptHandle) &&
+        (NULL != decryptHandle.get()) &&
         (!decodeSessionMap.isCreated(decryptHandle->decryptId))) {
         fileDesc = dup(fd);
     } else {
@@ -533,12 +535,12 @@
 }
 
 status_t FwdLockEngine::onOpenDecryptSession(int uniqueId,
-                                             DecryptHandle* decryptHandle,
+                                             sp<DecryptHandle>& decryptHandle,
                                              const char* uri) {
     status_t result = DRM_ERROR_CANNOT_HANDLE;
     const char fileTag [] = "file://";
 
-    if (NULL != decryptHandle && NULL != uri && strlen(uri) > sizeof(fileTag)) {
+    if (NULL != decryptHandle.get() && NULL != uri && strlen(uri) > sizeof(fileTag)) {
         String8 uriTag = String8(uri);
         uriTag.toLower();
 
@@ -562,11 +564,11 @@
 }
 
 status_t FwdLockEngine::onCloseDecryptSession(int /* uniqueId */,
-                                              DecryptHandle* decryptHandle) {
+                                              sp<DecryptHandle>& decryptHandle) {
     status_t result = DRM_ERROR_UNKNOWN;
     LOG_VERBOSE("FwdLockEngine::onCloseDecryptSession");
 
-    if (NULL != decryptHandle && decodeSessionMap.isCreated(decryptHandle->decryptId)) {
+    if (NULL != decryptHandle.get() && decodeSessionMap.isCreated(decryptHandle->decryptId)) {
         DecodeSession* session = decodeSessionMap.getValue(decryptHandle->decryptId);
         if (NULL != session && session->fileDesc > -1) {
             FwdLockFile_detach(session->fileDesc);
@@ -576,7 +578,7 @@
         }
     }
 
-    if (NULL != decryptHandle) {
+    if (NULL != decryptHandle.get()) {
         if (NULL != decryptHandle->decryptInfo) {
             delete decryptHandle->decryptInfo;
             decryptHandle->decryptInfo = NULL;
@@ -584,9 +586,7 @@
 
         decryptHandle->copyControlVector.clear();
         decryptHandle->extendedData.clear();
-
-        delete decryptHandle;
-        decryptHandle = NULL;
+        decryptHandle.clear();
     }
 
     LOG_VERBOSE("FwdLockEngine::onCloseDecryptSession Exit");
@@ -594,7 +594,7 @@
 }
 
 status_t FwdLockEngine::onInitializeDecryptUnit(int /* uniqueId */,
-                                                DecryptHandle* /* decryptHandle */,
+                                                sp<DecryptHandle>& /* decryptHandle */,
                                                 int /* decryptUnitId */,
                                                 const DrmBuffer* /* headerInfo */) {
     ALOGE("FwdLockEngine::onInitializeDecryptUnit is not supported for this DRM scheme");
@@ -603,7 +603,7 @@
 
 status_t FwdLockEngine::onDecrypt(
             int /* uniqueId */,
-            DecryptHandle* /* decryptHandle */,
+            sp<DecryptHandle>& /* decryptHandle */,
             int /* decryptUnitId */,
             const DrmBuffer* /* encBuffer */,
             DrmBuffer** /* decBuffer */,
@@ -613,7 +613,7 @@
 }
 
 status_t FwdLockEngine::onDecrypt(int /* uniqueId */,
-                                  DecryptHandle* /* decryptHandle */,
+                                  sp<DecryptHandle>& /* decryptHandle */,
                                   int /* decryptUnitId */,
                                   const DrmBuffer* /* encBuffer */,
                                   DrmBuffer** /* decBuffer */) {
@@ -622,19 +622,19 @@
 }
 
 status_t FwdLockEngine::onFinalizeDecryptUnit(int /* uniqueId */,
-                                              DecryptHandle* /* decryptHandle */,
+                                              sp<DecryptHandle>& /* decryptHandle */,
                                               int /* decryptUnitId */) {
     ALOGE("FwdLockEngine::onFinalizeDecryptUnit is not supported for this DRM scheme");
     return DRM_ERROR_UNKNOWN;
 }
 
 ssize_t FwdLockEngine::onRead(int /* uniqueId */,
-                              DecryptHandle* decryptHandle,
+                              sp<DecryptHandle>& decryptHandle,
                               void* buffer,
                               int numBytes) {
     ssize_t size = -1;
 
-    if (NULL != decryptHandle &&
+    if (NULL != decryptHandle.get() &&
         decodeSessionMap.isCreated(decryptHandle->decryptId) &&
         NULL != buffer &&
         numBytes > -1) {
@@ -654,15 +654,15 @@
 }
 
 #ifdef USE_64BIT_DRM_API
-off64_t FwdLockEngine::onLseek(int /* uniqueId */, DecryptHandle* decryptHandle,
+off64_t FwdLockEngine::onLseek(int /* uniqueId */, sp<DecryptHandle>& decryptHandle,
                                off64_t offset, int whence) {
 #else
-off_t FwdLockEngine::onLseek(int /* uniqueId */, DecryptHandle* decryptHandle,
+off_t FwdLockEngine::onLseek(int /* uniqueId */, sp<DecryptHandle>& decryptHandle,
                              off_t offset, int whence) {
 #endif
     off_t offval = -1;
 
-    if (NULL != decryptHandle && decodeSessionMap.isCreated(decryptHandle->decryptId)) {
+    if (NULL != decryptHandle.get() && decodeSessionMap.isCreated(decryptHandle->decryptId)) {
         DecodeSession* session = decodeSessionMap.getValue(decryptHandle->decryptId);
         if (NULL != session && session->fileDesc > -1) {
             offval = FwdLockFile_lseek(session->fileDesc, offset, whence);
@@ -675,13 +675,13 @@
 
 #ifdef USE_64BIT_DRM_API
 ssize_t FwdLockEngine::onPread(int uniqueId,
-                               DecryptHandle* decryptHandle,
+                               sp<DecryptHandle>& decryptHandle,
                                void* buffer,
                                ssize_t numBytes,
                                off64_t offset) {
 #else
 ssize_t FwdLockEngine::onPread(int uniqueId,
-                               DecryptHandle* decryptHandle,
+                               sp<DecryptHandle>& decryptHandle,
                                void* buffer,
                                ssize_t numBytes,
                                off_t offset) {
@@ -690,7 +690,7 @@
 
     DecodeSession* decoderSession = NULL;
 
-    if ((NULL != decryptHandle) &&
+    if ((NULL != decryptHandle.get()) &&
         (NULL != (decoderSession = decodeSessionMap.getValue(decryptHandle->decryptId))) &&
         (NULL != buffer) &&
         (numBytes > -1) &&
diff --git a/drm/libdrmframework/plugins/forward-lock/internal-format/Android.bp b/drm/libdrmframework/plugins/forward-lock/internal-format/Android.bp
deleted file mode 100644
index 9f58e26..0000000
--- a/drm/libdrmframework/plugins/forward-lock/internal-format/Android.bp
+++ /dev/null
@@ -1,5 +0,0 @@
-subdirs = [
-    "common",
-    "converter",
-    "decoder",
-]
diff --git a/drm/libdrmframework/plugins/passthru/include/DrmPassthruPlugIn.h b/drm/libdrmframework/plugins/passthru/include/DrmPassthruPlugIn.h
index 7b66dc7..4ab5272 100644
--- a/drm/libdrmframework/plugins/passthru/include/DrmPassthruPlugIn.h
+++ b/drm/libdrmframework/plugins/passthru/include/DrmPassthruPlugIn.h
@@ -53,10 +53,11 @@
 
     int onCheckRightsStatus(int uniqueId, const String8& path, int action);
 
-    status_t onConsumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+    status_t onConsumeRights(int uniqueId, sp<DecryptHandle>& decryptHandle,
+            int action, bool reserve);
 
     status_t onSetPlaybackStatus(
-            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position);
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus, int64_t position);
 
     bool onValidateAction(
             int uniqueId, const String8& path, int action, const ActionDescription& description);
@@ -74,26 +75,25 @@
     DrmSupportInfo* onGetSupportInfo(int uniqueId);
 
     status_t onOpenDecryptSession(
-            int uniqueId, DecryptHandle* decryptHandle, int fd, off64_t offset, off64_t length);
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int fd, off64_t offset,
+            off64_t length);
 
     status_t onOpenDecryptSession(
-            int uniqueId, DecryptHandle* decryptHandle, const char* uri);
+            int uniqueId, sp<DecryptHandle>& decryptHandle, const char* uri);
 
-    status_t onCloseDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+    status_t onCloseDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle);
 
-    status_t onInitializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+    status_t onInitializeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
             int decryptUnitId, const DrmBuffer* headerInfo);
 
-    status_t onDecrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+    status_t onDecrypt(int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
             const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
 
-    status_t onFinalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+    status_t onFinalizeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
+            int decryptUnitId);
 
-    ssize_t onPread(int uniqueId, DecryptHandle* decryptHandle,
+    ssize_t onPread(int uniqueId, sp<DecryptHandle>& decryptHandle,
             void* buffer, ssize_t numBytes, off64_t offset);
-
-private:
-    DecryptHandle* openDecryptSessionImpl();
 };
 
 };
diff --git a/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp b/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp
index d7f2d28..0fa3478 100644
--- a/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp
+++ b/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp
@@ -183,13 +183,13 @@
 }
 
 status_t DrmPassthruPlugIn::onConsumeRights(int uniqueId,
-            DecryptHandle* /*decryptHandle*/, int /*action*/, bool /*reserve*/) {
+            sp<DecryptHandle>& /*decryptHandle*/, int /*action*/, bool /*reserve*/) {
     ALOGV("DrmPassthruPlugIn::onConsumeRights() : %d", uniqueId);
     return DRM_NO_ERROR;
 }
 
 status_t DrmPassthruPlugIn::onSetPlaybackStatus(int uniqueId,
-            DecryptHandle* /*decryptHandle*/, int /*playbackStatus*/, int64_t /*position*/) {
+            sp<DecryptHandle>& /*decryptHandle*/, int /*playbackStatus*/, int64_t /*position*/) {
     ALOGV("DrmPassthruPlugIn::onSetPlaybackStatus() : %d", uniqueId);
     return DRM_NO_ERROR;
 }
@@ -236,7 +236,8 @@
 }
 
 status_t DrmPassthruPlugIn::onOpenDecryptSession(
-            int uniqueId, DecryptHandle* decryptHandle, int /*fd*/, off64_t /*offset*/, off64_t /*length*/) {
+            int uniqueId, sp<DecryptHandle>& decryptHandle, int /*fd*/, off64_t /*offset*/,
+            off64_t /*length*/) {
     ALOGV("DrmPassthruPlugIn::onOpenDecryptSession() : %d", uniqueId);
 
 #ifdef ENABLE_PASSTHRU_DECRYPTION
@@ -246,36 +247,38 @@
     decryptHandle->decryptInfo = NULL;
     return DRM_NO_ERROR;
 #else
-    (void)(decryptHandle); // unused
+    (void)(decryptHandle.get()); // unused
 #endif
 
     return DRM_ERROR_CANNOT_HANDLE;
 }
 
 status_t DrmPassthruPlugIn::onOpenDecryptSession(
-            int /*uniqueId*/, DecryptHandle* /*decryptHandle*/, const char* /*uri*/) {
+            int /*uniqueId*/, sp<DecryptHandle>& /*decryptHandle*/, const char* /*uri*/) {
     return DRM_ERROR_CANNOT_HANDLE;
 }
 
-status_t DrmPassthruPlugIn::onCloseDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+status_t DrmPassthruPlugIn::onCloseDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle) {
     ALOGV("DrmPassthruPlugIn::onCloseDecryptSession() : %d", uniqueId);
-    if (NULL != decryptHandle) {
+    if (NULL != decryptHandle.get()) {
         if (NULL != decryptHandle->decryptInfo) {
             delete decryptHandle->decryptInfo; decryptHandle->decryptInfo = NULL;
         }
-        delete decryptHandle; decryptHandle = NULL;
+        decryptHandle.clear();
     }
     return DRM_NO_ERROR;
 }
 
-status_t DrmPassthruPlugIn::onInitializeDecryptUnit(int uniqueId, DecryptHandle* /*decryptHandle*/,
-            int /*decryptUnitId*/, const DrmBuffer* /*headerInfo*/) {
+status_t DrmPassthruPlugIn::onInitializeDecryptUnit(int uniqueId,
+        sp<DecryptHandle>& /*decryptHandle*/,
+        int /*decryptUnitId*/, const DrmBuffer* /*headerInfo*/) {
     ALOGV("DrmPassthruPlugIn::onInitializeDecryptUnit() : %d", uniqueId);
     return DRM_NO_ERROR;
 }
 
-status_t DrmPassthruPlugIn::onDecrypt(int uniqueId, DecryptHandle* /*decryptHandle*/,
-            int /*decryptUnitId*/, const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* /*IV*/) {
+status_t DrmPassthruPlugIn::onDecrypt(int uniqueId, sp<DecryptHandle>& /*decryptHandle*/,
+        int /*decryptUnitId*/, const DrmBuffer* encBuffer, DrmBuffer** decBuffer,
+        DrmBuffer* /*IV*/) {
     ALOGV("DrmPassthruPlugIn::onDecrypt() : %d", uniqueId);
     /**
      * As a workaround implementation passthru would copy the given
@@ -296,12 +299,12 @@
 }
 
 status_t DrmPassthruPlugIn::onFinalizeDecryptUnit(
-            int uniqueId, DecryptHandle* /*decryptHandle*/, int /*decryptUnitId*/) {
+            int uniqueId, sp<DecryptHandle>& /*decryptHandle*/, int /*decryptUnitId*/) {
     ALOGV("DrmPassthruPlugIn::onFinalizeDecryptUnit() : %d", uniqueId);
     return DRM_NO_ERROR;
 }
 
-ssize_t DrmPassthruPlugIn::onPread(int uniqueId, DecryptHandle* /*decryptHandle*/,
+ssize_t DrmPassthruPlugIn::onPread(int uniqueId, sp<DecryptHandle>& /*decryptHandle*/,
             void* /*buffer*/, ssize_t /*numBytes*/, off64_t /*offset*/) {
     ALOGV("DrmPassthruPlugIn::onPread() : %d", uniqueId);
     return 0;
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 4991e50..d6db1d4 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -27,11 +27,11 @@
         "libmediadrmmetrics_lite",
         "libmediametrics",
         "libmediautils",
-        "libprotobuf-cpp-lite",
         "libstagefright_foundation",
         "libutils",
         "android.hardware.drm@1.0",
         "android.hardware.drm@1.1",
+        "android.hardware.drm@1.2",
         "libhidlallocatorutils",
         "libhidlbase",
         "libhidltransport",
@@ -59,20 +59,18 @@
     shared_libs: [
         "android.hardware.drm@1.0",
         "android.hardware.drm@1.1",
-        "libbase",
+        "android.hardware.drm@1.2",
         "libbinder",
         "libhidlbase",
         "liblog",
         "libmediametrics",
         "libprotobuf-cpp-lite",
-        "libstagefright_foundation",
         "libutils",
     ],
     cflags: [
         // Suppress unused parameter and no error options. These cause problems
         // with the when using the map type in a proto definition.
         "-Wno-unused-parameter",
-        "-Wno-error",
     ],
 }
 
@@ -92,6 +90,7 @@
     shared_libs: [
         "android.hardware.drm@1.0",
         "android.hardware.drm@1.1",
+        "android.hardware.drm@1.2",
         "libbase",
         "libbinder",
         "libhidlbase",
@@ -105,7 +104,6 @@
         // Suppress unused parameter and no error options. These cause problems
         // when using the map type in a proto definition.
         "-Wno-unused-parameter",
-        "-Wno-error",
     ],
 }
 
diff --git a/drm/libmediadrm/CryptoHal.cpp b/drm/libmediadrm/CryptoHal.cpp
index 3035c5a..d62ccd6 100644
--- a/drm/libmediadrm/CryptoHal.cpp
+++ b/drm/libmediadrm/CryptoHal.cpp
@@ -30,16 +30,16 @@
 #include <media/stagefright/MediaErrors.h>
 #include <mediadrm/CryptoHal.h>
 
+using drm::V1_0::BufferType;
+using drm::V1_0::DestinationBuffer;
+using drm::V1_0::ICryptoFactory;
+using drm::V1_0::ICryptoPlugin;
+using drm::V1_0::Mode;
+using drm::V1_0::Pattern;
+using drm::V1_0::SharedBuffer;
+using drm::V1_0::Status;
+using drm::V1_0::SubSample;
 
-using ::android::hardware::drm::V1_0::BufferType;
-using ::android::hardware::drm::V1_0::DestinationBuffer;
-using ::android::hardware::drm::V1_0::ICryptoFactory;
-using ::android::hardware::drm::V1_0::ICryptoPlugin;
-using ::android::hardware::drm::V1_0::Mode;
-using ::android::hardware::drm::V1_0::Pattern;
-using ::android::hardware::drm::V1_0::SharedBuffer;
-using ::android::hardware::drm::V1_0::Status;
-using ::android::hardware::drm::V1_0::SubSample;
 using ::android::hardware::hidl_array;
 using ::android::hardware::hidl_handle;
 using ::android::hardware::hidl_memory;
@@ -50,6 +50,7 @@
 using ::android::hidl::manager::V1_0::IServiceManager;
 using ::android::sp;
 
+typedef drm::V1_2::Status Status_V1_2;
 
 namespace android {
 
@@ -76,6 +77,18 @@
     }
 }
 
+static status_t toStatusT_1_2(Status_V1_2 status) {
+    switch (status) {
+    case Status_V1_2::ERROR_DRM_SESSION_LOST_STATE:
+        return ERROR_DRM_SESSION_LOST_STATE;;
+    case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
+        return ERROR_DRM_FRAME_TOO_LARGE;
+    case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
+        return ERROR_DRM_INSUFFICIENT_SECURITY;
+    default:
+        return toStatusT(static_cast<Status>(status));
+    }
+}
 
 static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
     hidl_vec<uint8_t> vec;
@@ -196,6 +209,9 @@
     for (size_t i = 0; i < mFactories.size(); i++) {
         if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
             mPlugin = makeCryptoPlugin(mFactories[i], uuid, data, size);
+            if (mPlugin != NULL) {
+                mPluginV1_2 = drm::V1_2::ICryptoPlugin::castFrom(mPlugin);
+            }
         }
     }
 
@@ -216,6 +232,7 @@
     }
 
     mPlugin.clear();
+    mPluginV1_2.clear();
     return OK;
 }
 
@@ -284,7 +301,7 @@
     ssize_t offset;
     size_t size;
 
-    if (memory == NULL && buffer == NULL) {
+    if (memory == NULL || buffer == NULL) {
         return UNEXPECTED_NULL;
     }
 
@@ -389,21 +406,33 @@
     status_t err = UNKNOWN_ERROR;
     uint32_t bytesWritten = 0;
 
-    Return<void> hResult = mPlugin->decrypt(secure, toHidlArray16(keyId), toHidlArray16(iv), hMode,
-            hPattern, hSubSamples, hSource, offset, hDestination,
-            [&](Status status, uint32_t hBytesWritten, hidl_string hDetailedError) {
-                if (status == Status::OK) {
-                    bytesWritten = hBytesWritten;
-                    *errorDetailMsg = toString8(hDetailedError);
-                }
-                err = toStatusT(status);
-            }
-        );
+    Return<void> hResult;
 
-    if (!hResult.isOk()) {
-        err = DEAD_OBJECT;
+    if (mPluginV1_2 != NULL) {
+        hResult = mPluginV1_2->decrypt_1_2(secure, toHidlArray16(keyId), toHidlArray16(iv),
+                hMode, hPattern, hSubSamples, hSource, offset, hDestination,
+                [&](Status_V1_2 status, uint32_t hBytesWritten, hidl_string hDetailedError) {
+                    if (status == Status_V1_2::OK) {
+                        bytesWritten = hBytesWritten;
+                        *errorDetailMsg = toString8(hDetailedError);
+                    }
+                    err = toStatusT_1_2(status);
+                }
+            );
+    } else {
+        hResult = mPlugin->decrypt(secure, toHidlArray16(keyId), toHidlArray16(iv),
+                hMode, hPattern, hSubSamples, hSource, offset, hDestination,
+                [&](Status status, uint32_t hBytesWritten, hidl_string hDetailedError) {
+                    if (status == Status::OK) {
+                        bytesWritten = hBytesWritten;
+                        *errorDetailMsg = toString8(hDetailedError);
+                    }
+                    err = toStatusT(status);
+                }
+            );
     }
 
+    err = hResult.isOk() ? err : DEAD_OBJECT;
     if (err == OK) {
         return bytesWritten;
     }
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index cf08610..919f4ee 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -23,8 +23,8 @@
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 
-#include <android/hardware/drm/1.0/types.h>
-#include <android/hidl/manager/1.0/IServiceManager.h>
+#include <android/hardware/drm/1.2/types.h>
+#include <android/hidl/manager/1.2/IServiceManager.h>
 #include <hidl/ServiceManagement.h>
 
 #include <media/EventMetric.h>
@@ -40,15 +40,17 @@
 #include <mediadrm/DrmSessionManager.h>
 
 using drm::V1_0::KeyedVector;
-using drm::V1_0::KeyStatusType;
+using drm::V1_0::KeyRequestType;
 using drm::V1_0::KeyType;
 using drm::V1_0::KeyValue;
-using drm::V1_1::HdcpLevel;;
 using drm::V1_0::SecureStop;
-using drm::V1_1::SecureStopRelease;
 using drm::V1_0::SecureStopId;
-using drm::V1_1::SecurityLevel;
 using drm::V1_0::Status;
+using drm::V1_1::HdcpLevel;
+using drm::V1_1::SecureStopRelease;
+using drm::V1_1::SecurityLevel;
+using drm::V1_2::KeySetId;
+using drm::V1_2::KeyStatusType;
 using ::android::hardware::drm::V1_1::DrmMetricGroup;
 using ::android::hardware::hidl_array;
 using ::android::hardware::hidl_string;
@@ -59,6 +61,10 @@
 using ::android::os::PersistableBundle;
 using ::android::sp;
 
+typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
+typedef drm::V1_2::Status Status_V1_2;
+typedef drm::V1_2::HdcpLevel HdcpLevel_V1_2;
+
 namespace {
 
 // This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
@@ -139,26 +145,55 @@
     }
 }
 
-static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) {
+static SecurityLevel toHidlSecurityLevel(DrmPlugin::SecurityLevel level) {
     switch(level) {
-    case HdcpLevel::HDCP_NONE:
+    case DrmPlugin::kSecurityLevelSwSecureCrypto:
+        return SecurityLevel::SW_SECURE_CRYPTO;
+    case DrmPlugin::kSecurityLevelSwSecureDecode:
+        return SecurityLevel::SW_SECURE_DECODE;
+    case DrmPlugin::kSecurityLevelHwSecureCrypto:
+        return SecurityLevel::HW_SECURE_CRYPTO;
+    case DrmPlugin::kSecurityLevelHwSecureDecode:
+        return SecurityLevel::HW_SECURE_DECODE;
+    case DrmPlugin::kSecurityLevelHwSecureAll:
+        return SecurityLevel::HW_SECURE_ALL;
+    default:
+        return SecurityLevel::UNKNOWN;
+    }
+}
+
+static DrmPlugin::OfflineLicenseState toOfflineLicenseState(
+        OfflineLicenseState licenseState) {
+    switch(licenseState) {
+    case OfflineLicenseState::USABLE:
+        return DrmPlugin::kOfflineLicenseStateUsable;
+    case OfflineLicenseState::INACTIVE:
+        return DrmPlugin::kOfflineLicenseStateReleased;
+    default:
+        return DrmPlugin::kOfflineLicenseStateUnknown;
+    }
+}
+
+static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel_V1_2 level) {
+    switch(level) {
+    case HdcpLevel_V1_2::HDCP_NONE:
         return DrmPlugin::kHdcpNone;
-    case HdcpLevel::HDCP_V1:
+    case HdcpLevel_V1_2::HDCP_V1:
         return DrmPlugin::kHdcpV1;
-    case HdcpLevel::HDCP_V2:
+    case HdcpLevel_V1_2::HDCP_V2:
         return DrmPlugin::kHdcpV2;
-    case HdcpLevel::HDCP_V2_1:
+    case HdcpLevel_V1_2::HDCP_V2_1:
         return DrmPlugin::kHdcpV2_1;
-    case HdcpLevel::HDCP_V2_2:
+    case HdcpLevel_V1_2::HDCP_V2_2:
         return DrmPlugin::kHdcpV2_2;
-    case HdcpLevel::HDCP_NO_OUTPUT:
+    case HdcpLevel_V1_2::HDCP_V2_3:
+        return DrmPlugin::kHdcpV2_3;
+    case HdcpLevel_V1_2::HDCP_NO_OUTPUT:
         return DrmPlugin::kHdcpNoOutput;
     default:
         return DrmPlugin::kHdcpLevelUnknown;
     }
 }
-
-
 static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
         keyedVector) {
     std::vector<KeyValue> stdKeyedVector;
@@ -199,6 +234,15 @@
     return secureStopIds;
 }
 
+static List<Vector<uint8_t>> toKeySetIds(const hidl_vec<KeySetId>&
+        hKeySetIds) {
+    List<Vector<uint8_t>> keySetIds;
+    for (size_t i = 0; i < hKeySetIds.size(); i++) {
+        keySetIds.push_back(toVector(hKeySetIds[i]));
+    }
+    return keySetIds;
+}
+
 static status_t toStatusT(Status status) {
     switch (status) {
     case Status::OK:
@@ -217,7 +261,7 @@
         return ERROR_DRM_CANNOT_HANDLE;
         break;
     case Status::ERROR_DRM_INVALID_STATE:
-        return ERROR_DRM_TAMPER_DETECTED;
+        return ERROR_DRM_INVALID_STATE;
         break;
     case Status::BAD_VALUE:
         return BAD_VALUE;
@@ -238,6 +282,19 @@
     }
 }
 
+static status_t toStatusT_1_2(Status_V1_2 status) {
+    switch (status) {
+    case Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION:
+        return ERROR_DRM_RESOURCE_CONTENTION;
+    case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
+        return ERROR_DRM_FRAME_TOO_LARGE;
+    case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
+        return ERROR_DRM_INSUFFICIENT_SECURITY;
+    default:
+        return toStatusT(static_cast<Status>(status));
+    }
+}
+
 
 Mutex DrmHal::mLock;
 
@@ -297,39 +354,51 @@
 
     setListener(NULL);
     mInitCheck = NO_INIT;
-
-    if (mPlugin != NULL) {
+    if (mPluginV1_2 != NULL) {
+        if (!mPluginV1_2->setListener(NULL).isOk()) {
+            mInitCheck = DEAD_OBJECT;
+        }
+    } else if (mPlugin != NULL) {
         if (!mPlugin->setListener(NULL).isOk()) {
             mInitCheck = DEAD_OBJECT;
         }
     }
     mPlugin.clear();
     mPluginV1_1.clear();
+    mPluginV1_2.clear();
 }
 
 Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
     Vector<sp<IDrmFactory>> factories;
 
-    auto manager = hardware::defaultServiceManager();
+    auto manager = hardware::defaultServiceManager1_2();
 
     if (manager != NULL) {
-        manager->listByInterface(drm::V1_0::IDrmFactory::descriptor,
+        manager->listManifestByInterface(drm::V1_0::IDrmFactory::descriptor,
                 [&factories](const hidl_vec<hidl_string> &registered) {
                     for (const auto &instance : registered) {
                         auto factory = drm::V1_0::IDrmFactory::getService(instance);
                         if (factory != NULL) {
-                            ALOGD("found drm@1.0 IDrmFactory %s", instance.c_str());
                             factories.push_back(factory);
                         }
                     }
                 }
             );
-        manager->listByInterface(drm::V1_1::IDrmFactory::descriptor,
+        manager->listManifestByInterface(drm::V1_1::IDrmFactory::descriptor,
                 [&factories](const hidl_vec<hidl_string> &registered) {
                     for (const auto &instance : registered) {
                         auto factory = drm::V1_1::IDrmFactory::getService(instance);
                         if (factory != NULL) {
-                            ALOGD("found drm@1.1 IDrmFactory %s", instance.c_str());
+                            factories.push_back(factory);
+                        }
+                    }
+                }
+            );
+        manager->listByInterface(drm::V1_2::IDrmFactory::descriptor,
+                [&factories](const hidl_vec<hidl_string> &registered) {
+                    for (const auto &instance : registered) {
+                        auto factory = drm::V1_2::IDrmFactory::getService(instance);
+                        if (factory != NULL) {
                             factories.push_back(factory);
                         }
                     }
@@ -448,6 +517,17 @@
 }
 
 Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
+        const hidl_vec<KeyStatus_V1_0>& keyStatusList_V1_0, bool hasNewUsableKey) {
+    std::vector<KeyStatus> keyStatusVec;
+    for (const auto &keyStatus_V1_0 : keyStatusList_V1_0) {
+        keyStatusVec.push_back({keyStatus_V1_0.keyId,
+                static_cast<KeyStatusType>(keyStatus_V1_0.type)});
+    }
+    hidl_vec<KeyStatus> keyStatusList_V1_2(keyStatusVec);
+    return sendKeysChange_1_2(sessionId, keyStatusList_V1_2, hasNewUsableKey);
+}
+
+Return<void> DrmHal::sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId,
         const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
 
     mEventLock.lock();
@@ -477,6 +557,9 @@
             case KeyStatusType::STATUSPENDING:
                 type = DrmPlugin::kKeyStatusType_StatusPending;
                 break;
+            case KeyStatusType::USABLEINFUTURE:
+                type = DrmPlugin::kKeyStatusType_UsableInFuture;
+                break;
             case KeyStatusType::INTERNALERROR:
             default:
                 type = DrmPlugin::kKeyStatusType_InternalError;
@@ -501,32 +584,80 @@
     return Void();
 }
 
-bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
-    Mutex::Autolock autoLock(mLock);
+Return<void> DrmHal::sendSessionLostState(
+        const hidl_vec<uint8_t>& sessionId) {
 
-    for (size_t i = 0; i < mFactories.size(); i++) {
+    mEventLock.lock();
+    sp<IDrmClient> listener = mListener;
+    mEventLock.unlock();
+
+    if (listener != NULL) {
+        Parcel obj;
+        writeByteArray(obj, sessionId);
+        Mutex::Autolock lock(mNotifyLock);
+        listener->notify(DrmPlugin::kDrmPluginEventSessionLostState, 0, &obj);
+    }
+    return Void();
+}
+
+status_t DrmHal::matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> &factory,
+                                               const uint8_t uuid[16],
+                                               const String8 &mimeType,
+                                               DrmPlugin::SecurityLevel level,
+                                               bool *isSupported) {
+    *isSupported = false;
+
+    // handle default value cases
+    if (level == DrmPlugin::kSecurityLevelUnknown) {
+        if (mimeType == "") {
+            // isCryptoSchemeSupported(uuid)
+            *isSupported = true;
+        } else {
+            // isCryptoSchemeSupported(uuid, mimeType)
+            *isSupported = factory->isContentTypeSupported(mimeType.string());
+        }
+        return OK;
+    } else if (mimeType == "") {
+        return BAD_VALUE;
+    }
+
+    sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
+    if (factoryV1_2 == NULL) {
+        return ERROR_UNSUPPORTED;
+    } else {
+        *isSupported = factoryV1_2->isCryptoSchemeSupported_1_2(uuid,
+                mimeType.string(), toHidlSecurityLevel(level));
+        return OK;
+    }
+}
+
+status_t DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16],
+                                         const String8 &mimeType,
+                                         DrmPlugin::SecurityLevel level,
+                                         bool *isSupported) {
+    Mutex::Autolock autoLock(mLock);
+    *isSupported = false;
+    for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
         if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
-            if (mimeType != "") {
-                if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
-                    return true;
-                }
-            } else {
-                return true;
-            }
+            return matchMimeTypeAndSecurityLevel(mFactories[i],
+                    uuid, mimeType, level, isSupported);
         }
     }
-    return false;
+    return OK;
 }
 
 status_t DrmHal::createPlugin(const uint8_t uuid[16],
         const String8& appPackageName) {
     Mutex::Autolock autoLock(mLock);
 
-    for (size_t i = 0; i < mFactories.size(); i++) {
+    for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
         if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
-            mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
-            if (mPlugin != NULL) {
+            auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
+            if (plugin != NULL) {
+                mPlugin = plugin;
                 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
+                mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
+                break;
             }
         }
     }
@@ -534,13 +665,22 @@
     if (mPlugin == NULL) {
         mInitCheck = ERROR_UNSUPPORTED;
     } else {
-        if (!mPlugin->setListener(this).isOk()) {
+        mInitCheck = OK;
+        if (mPluginV1_2 != NULL) {
+            if (!mPluginV1_2->setListener(this).isOk()) {
+                mInitCheck = DEAD_OBJECT;
+            }
+        } else if (!mPlugin->setListener(this).isOk()) {
             mInitCheck = DEAD_OBJECT;
-        } else {
-            mInitCheck = OK;
+        }
+        if (mInitCheck != OK) {
+            mPlugin.clear();
+            mPluginV1_1.clear();
+            mPluginV1_2.clear();
         }
     }
 
+
     return mInitCheck;
 }
 
@@ -554,30 +694,15 @@
     Mutex::Autolock autoLock(mLock);
     INIT_CHECK();
 
-    SecurityLevel hSecurityLevel;
+    SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
     bool setSecurityLevel = true;
 
-    switch(level) {
-    case DrmPlugin::kSecurityLevelSwSecureCrypto:
-        hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO;
-        break;
-    case DrmPlugin::kSecurityLevelSwSecureDecode:
-        hSecurityLevel = SecurityLevel::SW_SECURE_DECODE;
-        break;
-    case DrmPlugin::kSecurityLevelHwSecureCrypto:
-        hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO;
-        break;
-    case DrmPlugin::kSecurityLevelHwSecureDecode:
-        hSecurityLevel = SecurityLevel::HW_SECURE_DECODE;
-        break;
-    case DrmPlugin::kSecurityLevelHwSecureAll:
-        hSecurityLevel = SecurityLevel::HW_SECURE_ALL;
-        break;
-    case DrmPlugin::kSecurityLevelMax:
+    if (level == DrmPlugin::kSecurityLevelMax) {
         setSecurityLevel = false;
-        break;
-    default:
-        return ERROR_DRM_CANNOT_HANDLE;
+    } else {
+        if (hSecurityLevel == SecurityLevel::UNKNOWN) {
+            return ERROR_DRM_CANNOT_HANDLE;
+        }
     }
 
     status_t  err = UNKNOWN_ERROR;
@@ -657,6 +782,39 @@
     return DEAD_OBJECT;
 }
 
+static DrmPlugin::KeyRequestType toKeyRequestType(
+        KeyRequestType keyRequestType) {
+    switch (keyRequestType) {
+        case KeyRequestType::INITIAL:
+            return DrmPlugin::kKeyRequestType_Initial;
+            break;
+        case KeyRequestType::RENEWAL:
+            return DrmPlugin::kKeyRequestType_Renewal;
+            break;
+        case KeyRequestType::RELEASE:
+            return DrmPlugin::kKeyRequestType_Release;
+            break;
+        default:
+            return DrmPlugin::kKeyRequestType_Unknown;
+            break;
+    }
+}
+
+static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
+        KeyRequestType_V1_1 keyRequestType) {
+    switch (keyRequestType) {
+        case KeyRequestType_V1_1::NONE:
+            return DrmPlugin::kKeyRequestType_None;
+            break;
+        case KeyRequestType_V1_1::UPDATE:
+            return DrmPlugin::kKeyRequestType_Update;
+            break;
+        default:
+            return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
+            break;
+    }
+}
+
 status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
         Vector<uint8_t> const &initData, String8 const &mimeType,
         DrmPlugin::KeyType keyType, KeyedVector<String8,
@@ -683,73 +841,51 @@
     ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
 
     status_t err = UNKNOWN_ERROR;
+    Return<void> hResult;
 
-    if (mPluginV1_1 != NULL) {
-        Return<void> hResult =
-            mPluginV1_1->getKeyRequest_1_1(
+    if (mPluginV1_2 != NULL) {
+        hResult = mPluginV1_2->getKeyRequest_1_2(
+                toHidlVec(sessionId), toHidlVec(initData),
+                toHidlString(mimeType), hKeyType, hOptionalParameters,
+                [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
+                        KeyRequestType_V1_1 hKeyRequestType,
+                        const hidl_string& hDefaultUrl) {
+                    if (status == Status_V1_2::OK) {
+                        request = toVector(hRequest);
+                        defaultUrl = toString8(hDefaultUrl);
+                        *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
+                    }
+                    err = toStatusT_1_2(status);
+                });
+    } else if (mPluginV1_1 != NULL) {
+        hResult = mPluginV1_1->getKeyRequest_1_1(
                 toHidlVec(sessionId), toHidlVec(initData),
                 toHidlString(mimeType), hKeyType, hOptionalParameters,
                 [&](Status status, const hidl_vec<uint8_t>& hRequest,
-                    drm::V1_1::KeyRequestType hKeyRequestType,
-                    const hidl_string& hDefaultUrl) {
-
-            if (status == Status::OK) {
-                request = toVector(hRequest);
-                defaultUrl = toString8(hDefaultUrl);
-
-                switch (hKeyRequestType) {
-                    case drm::V1_1::KeyRequestType::INITIAL:
-                        *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
-                        break;
-                    case drm::V1_1::KeyRequestType::RENEWAL:
-                        *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
-                        break;
-                    case drm::V1_1::KeyRequestType::RELEASE:
-                        *keyRequestType = DrmPlugin::kKeyRequestType_Release;
-                        break;
-                    case drm::V1_1::KeyRequestType::NONE:
-                        *keyRequestType = DrmPlugin::kKeyRequestType_None;
-                        break;
-                    case drm::V1_1::KeyRequestType::UPDATE:
-                        *keyRequestType = DrmPlugin::kKeyRequestType_Update;
-                        break;
-                    default:
-                        *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
-                        break;
-                }
-                err = toStatusT(status);
-            }
-        });
-        return hResult.isOk() ? err : DEAD_OBJECT;
-    }
-
-    Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
-            toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
-            [&](Status status, const hidl_vec<uint8_t>& hRequest,
-                    drm::V1_0::KeyRequestType hKeyRequestType,
-                    const hidl_string& hDefaultUrl) {
-
-                if (status == Status::OK) {
-                    request = toVector(hRequest);
-                    defaultUrl = toString8(hDefaultUrl);
-
-                    switch (hKeyRequestType) {
-                    case drm::V1_0::KeyRequestType::INITIAL:
-                        *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
-                        break;
-                    case drm::V1_0::KeyRequestType::RENEWAL:
-                        *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
-                        break;
-                    case drm::V1_0::KeyRequestType::RELEASE:
-                        *keyRequestType = DrmPlugin::kKeyRequestType_Release;
-                        break;
-                    default:
-                        *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
-                        break;
+                        KeyRequestType_V1_1 hKeyRequestType,
+                        const hidl_string& hDefaultUrl) {
+                    if (status == Status::OK) {
+                        request = toVector(hRequest);
+                        defaultUrl = toString8(hDefaultUrl);
+                        *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
                     }
                     err = toStatusT(status);
-                }
-            });
+                });
+    } else {
+        hResult = mPlugin->getKeyRequest(
+                toHidlVec(sessionId), toHidlVec(initData),
+                toHidlString(mimeType), hKeyType, hOptionalParameters,
+                [&](Status status, const hidl_vec<uint8_t>& hRequest,
+                        KeyRequestType hKeyRequestType,
+                        const hidl_string& hDefaultUrl) {
+                    if (status == Status::OK) {
+                        request = toVector(hRequest);
+                        defaultUrl = toString8(hDefaultUrl);
+                        *keyRequestType = toKeyRequestType(hKeyRequestType);
+                    }
+                    err = toStatusT(status);
+                });
+    }
 
     err = hResult.isOk() ? err : DEAD_OBJECT;
     keyRequestTimer.SetAttribute(err);
@@ -831,18 +967,33 @@
     INIT_CHECK();
 
     status_t err = UNKNOWN_ERROR;
+    Return<void> hResult;
 
-    Return<void> hResult = mPlugin->getProvisionRequest(
-            toHidlString(certType), toHidlString(certAuthority),
-            [&](Status status, const hidl_vec<uint8_t>& hRequest,
-                    const hidl_string& hDefaultUrl) {
-                if (status == Status::OK) {
-                    request = toVector(hRequest);
-                    defaultUrl = toString8(hDefaultUrl);
+    if (mPluginV1_2 != NULL) {
+        Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
+                toHidlString(certType), toHidlString(certAuthority),
+                [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
+                        const hidl_string& hDefaultUrl) {
+                    if (status == Status_V1_2::OK) {
+                        request = toVector(hRequest);
+                        defaultUrl = toString8(hDefaultUrl);
+                    }
+                    err = toStatusT_1_2(status);
                 }
-                err = toStatusT(status);
-            }
-        );
+            );
+    } else {
+        Return<void> hResult = mPlugin->getProvisionRequest(
+                toHidlString(certType), toHidlString(certAuthority),
+                [&](Status status, const hidl_vec<uint8_t>& hRequest,
+                        const hidl_string& hDefaultUrl) {
+                    if (status == Status::OK) {
+                        request = toVector(hRequest);
+                        defaultUrl = toString8(hDefaultUrl);
+                    }
+                    err = toStatusT(status);
+                }
+            );
+    }
 
     err = hResult.isOk() ? err : DEAD_OBJECT;
     mMetrics.mGetProvisionRequestCounter.Increment(err);
@@ -988,22 +1139,31 @@
     }
     status_t err = UNKNOWN_ERROR;
 
-    if (mPluginV1_1 == NULL) {
-        return ERROR_DRM_CANNOT_HANDLE;
-    }
-
     *connected = DrmPlugin::kHdcpLevelUnknown;
     *max = DrmPlugin::kHdcpLevelUnknown;
 
-    Return<void> hResult = mPluginV1_1->getHdcpLevels(
-            [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
-                if (status == Status::OK) {
-                    *connected = toHdcpLevel(hConnected);
-                    *max = toHdcpLevel(hMax);
-                }
-                err = toStatusT(status);
-            }
-    );
+    Return<void> hResult;
+    if (mPluginV1_2 != NULL) {
+        hResult = mPluginV1_2->getHdcpLevels_1_2(
+                [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) {
+                    if (status == Status_V1_2::OK) {
+                        *connected = toHdcpLevel(hConnected);
+                        *max = toHdcpLevel(hMax);
+                    }
+                    err = toStatusT_1_2(status);
+                });
+    } else if (mPluginV1_1 != NULL) {
+        hResult = mPluginV1_1->getHdcpLevels(
+                [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
+                    if (status == Status::OK) {
+                        *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
+                        *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
+                    }
+                    err = toStatusT(status);
+                });
+    } else {
+        return ERROR_DRM_CANNOT_HANDLE;
+    }
 
     return hResult.isOk() ? err : DEAD_OBJECT;
 }
@@ -1065,6 +1225,73 @@
     return hResult.isOk() ? err : DEAD_OBJECT;
 }
 
+status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
+    Mutex::Autolock autoLock(mLock);
+
+    if (mInitCheck != OK) {
+        return mInitCheck;
+    }
+
+    if (mPluginV1_2 == NULL) {
+        return ERROR_UNSUPPORTED;
+    }
+
+    status_t err = UNKNOWN_ERROR;
+
+    Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
+            [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
+                if (status == Status::OK) {
+                    keySetIds = toKeySetIds(hKeySetIds);
+                }
+                err = toStatusT(status);
+            }
+    );
+
+    return hResult.isOk() ? err : DEAD_OBJECT;
+}
+
+status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
+    Mutex::Autolock autoLock(mLock);
+
+    if (mInitCheck != OK) {
+        return mInitCheck;
+    }
+
+    if (mPluginV1_2 == NULL) {
+        return ERROR_UNSUPPORTED;
+    }
+
+    Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
+    return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
+}
+
+status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
+        DrmPlugin::OfflineLicenseState *licenseState) const {
+    Mutex::Autolock autoLock(mLock);
+
+    if (mInitCheck != OK) {
+        return mInitCheck;
+    }
+
+    if (mPluginV1_2 == NULL) {
+        return ERROR_UNSUPPORTED;
+    }
+    *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
+
+    status_t err = UNKNOWN_ERROR;
+
+    Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
+            [&](Status status, OfflineLicenseState hLicenseState) {
+                if (status == Status::OK) {
+                    *licenseState = toOfflineLicenseState(hLicenseState);
+                }
+                err = toStatusT(status);
+            }
+    );
+
+    return hResult.isOk() ? err : DEAD_OBJECT;
+}
+
 status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
     Mutex::Autolock autoLock(mLock);
     return getPropertyStringInternal(name, value);
@@ -1343,22 +1570,22 @@
 
 void DrmHal::reportFrameworkMetrics() const
 {
-    MediaAnalyticsItem item("mediadrm");
-    item.generateSessionID();
-    item.setPkgName(mMetrics.GetAppPackageName().c_str());
+    std::unique_ptr<MediaAnalyticsItem> item(MediaAnalyticsItem::create("mediadrm"));
+    item->generateSessionID();
+    item->setPkgName(mMetrics.GetAppPackageName().c_str());
     String8 vendor;
     String8 description;
     status_t result = getPropertyStringInternal(String8("vendor"), vendor);
     if (result != OK) {
         ALOGE("Failed to get vendor from drm plugin: %d", result);
     } else {
-        item.setCString("vendor", vendor.c_str());
+        item->setCString("vendor", vendor.c_str());
     }
     result = getPropertyStringInternal(String8("description"), description);
     if (result != OK) {
         ALOGE("Failed to get description from drm plugin: %d", result);
     } else {
-        item.setCString("description", description.c_str());
+        item->setCString("description", description.c_str());
     }
 
     std::string serializedMetrics;
@@ -1369,9 +1596,9 @@
     std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
                                                         serializedMetrics.size());
     if (!b64EncodedMetrics.empty()) {
-        item.setCString("serialized_metrics", b64EncodedMetrics.c_str());
+        item->setCString("serialized_metrics", b64EncodedMetrics.c_str());
     }
-    if (!item.selfrecord()) {
+    if (!item->selfrecord()) {
         ALOGE("Failed to self record framework metrics");
     }
 }
diff --git a/drm/libmediadrm/DrmMetrics.cpp b/drm/libmediadrm/DrmMetrics.cpp
index 4fed707..3080802 100644
--- a/drm/libmediadrm/DrmMetrics.cpp
+++ b/drm/libmediadrm/DrmMetrics.cpp
@@ -32,7 +32,7 @@
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
 using ::android::hardware::drm::V1_0::EventType;
-using ::android::hardware::drm::V1_0::KeyStatusType;
+using ::android::hardware::drm::V1_2::KeyStatusType;
 using ::android::hardware::drm::V1_1::DrmMetricGroup;
 using ::android::os::PersistableBundle;
 
diff --git a/drm/libmediadrm/IDrm.cpp b/drm/libmediadrm/IDrm.cpp
index 509961f..51274d1 100644
--- a/drm/libmediadrm/IDrm.cpp
+++ b/drm/libmediadrm/IDrm.cpp
@@ -61,7 +61,10 @@
     GET_NUMBER_OF_SESSIONS,
     GET_SECURITY_LEVEL,
     REMOVE_SECURE_STOP,
-    GET_SECURE_STOP_IDS
+    GET_SECURE_STOP_IDS,
+    GET_OFFLINE_LICENSE_KEYSET_IDS,
+    REMOVE_OFFLINE_LICENSE,
+    GET_OFFLINE_LICENSE_STATE
 };
 
 struct BpDrm : public BpInterface<IDrm> {
@@ -80,18 +83,22 @@
         return reply.readInt32();
     }
 
-    virtual bool isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
+    virtual status_t isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType,
+            DrmPlugin::SecurityLevel level, bool *isSupported) {
         Parcel data, reply;
         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
         data.write(uuid, 16);
         data.writeString8(mimeType);
+        data.writeInt32(level);
+
         status_t status = remote()->transact(IS_CRYPTO_SUPPORTED, data, &reply);
         if (status != OK) {
             ALOGE("isCryptoSchemeSupported: binder call failed: %d", status);
-            return false;
+            return status;
         }
+        *isSupported = static_cast<bool>(reply.readInt32());
 
-        return reply.readInt32() != 0;
+        return reply.readInt32();
     }
 
     virtual status_t createPlugin(const uint8_t uuid[16],
@@ -120,11 +127,11 @@
         return reply.readInt32();
     }
 
-    virtual status_t openSession(DrmPlugin::SecurityLevel securityLevel,
+    virtual status_t openSession(DrmPlugin::SecurityLevel level,
             Vector<uint8_t> &sessionId) {
         Parcel data, reply;
         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
-        data.writeInt32(securityLevel);
+        data.writeInt32(level);
 
         status_t status = remote()->transact(OPEN_SESSION, data, &reply);
         if (status != OK) {
@@ -376,6 +383,52 @@
         return reply.readInt32();
     }
 
+    virtual status_t getOfflineLicenseKeySetIds(List<Vector<uint8_t> > &keySetIds) const {
+        Parcel data, reply;
+        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+
+        status_t status = remote()->transact(GET_OFFLINE_LICENSE_KEYSET_IDS, data, &reply);
+        if (status != OK) {
+            return status;
+        }
+
+        keySetIds.clear();
+        uint32_t count = reply.readInt32();
+        for (size_t i = 0; i < count; i++) {
+            Vector<uint8_t> keySetId;
+            readVector(reply, keySetId);
+            keySetIds.push_back(keySetId);
+        }
+        return reply.readInt32();
+    }
+
+    virtual status_t removeOfflineLicense(Vector<uint8_t> const &keySetId) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+
+        writeVector(data, keySetId);
+        status_t status = remote()->transact(REMOVE_OFFLINE_LICENSE, data, &reply);
+        if (status != OK) {
+            return status;
+        }
+        return reply.readInt32();
+    }
+
+    virtual status_t getOfflineLicenseState(Vector<uint8_t> const &keySetId,
+            DrmPlugin::OfflineLicenseState *licenseState) const {
+        Parcel data, reply;
+        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+
+        writeVector(data, keySetId);
+        status_t status = remote()->transact(GET_OFFLINE_LICENSE_STATE, data, &reply);
+        if (status != OK) {
+            *licenseState = DrmPlugin::OfflineLicenseState::kOfflineLicenseStateUnknown;
+            return status;
+        }
+        *licenseState = static_cast<DrmPlugin::OfflineLicenseState>(reply.readInt32());
+        return reply.readInt32();
+    }
+
     virtual status_t getPropertyString(String8 const &name, String8 &value) const {
         Parcel data, reply;
         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
@@ -719,7 +772,12 @@
             uint8_t uuid[16];
             data.read(uuid, sizeof(uuid));
             String8 mimeType = data.readString8();
-            reply->writeInt32(isCryptoSchemeSupported(uuid, mimeType));
+            DrmPlugin::SecurityLevel level =
+                    static_cast<DrmPlugin::SecurityLevel>(data.readInt32());
+            bool isSupported = false;
+            status_t result = isCryptoSchemeSupported(uuid, mimeType, level, &isSupported);
+            reply->writeInt32(isSupported);
+            reply->writeInt32(result);
             return OK;
         }
 
@@ -980,6 +1038,45 @@
             return OK;
         }
 
+        case GET_OFFLINE_LICENSE_KEYSET_IDS:
+        {
+            CHECK_INTERFACE(IDrm, data, reply);
+            List<Vector<uint8_t> > keySetIds;
+            status_t result = getOfflineLicenseKeySetIds(keySetIds);
+            size_t count = keySetIds.size();
+            reply->writeInt32(count);
+            List<Vector<uint8_t> >::iterator iter = keySetIds.begin();
+            while(iter != keySetIds.end()) {
+                size_t size = iter->size();
+                reply->writeInt32(size);
+                reply->write(iter->array(), iter->size());
+                iter++;
+            }
+            reply->writeInt32(result);
+            return OK;
+        }
+
+        case REMOVE_OFFLINE_LICENSE:
+        {
+            CHECK_INTERFACE(IDrm, data, reply);
+            Vector<uint8_t> keySetId;
+            readVector(data, keySetId);
+            reply->writeInt32(removeOfflineLicense(keySetId));
+            return OK;
+        }
+
+        case GET_OFFLINE_LICENSE_STATE:
+        {
+            CHECK_INTERFACE(IDrm, data, reply);
+            Vector<uint8_t> keySetId;
+            readVector(data, keySetId);
+            DrmPlugin::OfflineLicenseState state;
+            status_t result = getOfflineLicenseState(keySetId, &state);
+            reply->writeInt32(static_cast<DrmPlugin::OfflineLicenseState>(state));
+            reply->writeInt32(result);
+            return OK;
+        }
+
         case GET_PROPERTY_STRING:
         {
             CHECK_INTERFACE(IDrm, data, reply);
diff --git a/drm/libmediadrm/PluginMetricsReporting.cpp b/drm/libmediadrm/PluginMetricsReporting.cpp
index 5cb48bf..8cd6f96 100644
--- a/drm/libmediadrm/PluginMetricsReporting.cpp
+++ b/drm/libmediadrm/PluginMetricsReporting.cpp
@@ -34,17 +34,17 @@
 status_t reportVendorMetrics(const std::string& metrics,
                              const String8& name,
                              const String8& appPackageName) {
-    MediaAnalyticsItem analyticsItem(name.c_str());
-    analyticsItem.generateSessionID();
+    std::unique_ptr<MediaAnalyticsItem> analyticsItem(MediaAnalyticsItem::create(name.c_str()));
+    analyticsItem->generateSessionID();
 
     std::string app_package_name(appPackageName.c_str(), appPackageName.size());
-    analyticsItem.setPkgName(app_package_name);
+    analyticsItem->setPkgName(app_package_name);
     if (metrics.size() > 0) {
-        analyticsItem.setCString(kSerializedMetricsField, metrics.c_str());
+        analyticsItem->setCString(kSerializedMetricsField, metrics.c_str());
     }
 
-    if (!analyticsItem.selfrecord()) {
-      ALOGE("selfrecord() returned false. sessioId %" PRId64, analyticsItem.getSessionID());
+    if (!analyticsItem->selfrecord()) {
+      ALOGE("selfrecord() returned false. sessioId %" PRId64, analyticsItem->getSessionID());
     }
 
     return OK;
diff --git a/drm/libmediadrm/tests/Android.bp b/drm/libmediadrm/tests/Android.bp
index 66c906f..9e0115e 100644
--- a/drm/libmediadrm/tests/Android.bp
+++ b/drm/libmediadrm/tests/Android.bp
@@ -17,6 +17,7 @@
     shared_libs: [
       "android.hardware.drm@1.0",
       "android.hardware.drm@1.1",
+      "android.hardware.drm@1.2",
       "libbinder",
       "libhidlbase",
       "liblog",
@@ -33,7 +34,6 @@
         // Suppress unused parameter and no error options. These cause problems
         // when using the map type in a proto definition.
         "-Wno-unused-parameter",
-        "-Wno-error",
     ]
 }
 
diff --git a/drm/libmediadrm/tests/DrmMetrics_test.cpp b/drm/libmediadrm/tests/DrmMetrics_test.cpp
index 64aa9d0..5c8a1b0 100644
--- a/drm/libmediadrm/tests/DrmMetrics_test.cpp
+++ b/drm/libmediadrm/tests/DrmMetrics_test.cpp
@@ -30,7 +30,7 @@
 using ::android::drm_metrics::DrmFrameworkMetrics;
 using ::android::hardware::hidl_vec;
 using ::android::hardware::drm::V1_0::EventType;
-using ::android::hardware::drm::V1_0::KeyStatusType;
+using ::android::hardware::drm::V1_2::KeyStatusType;
 using ::android::hardware::drm::V1_0::Status;
 using ::android::hardware::drm::V1_1::DrmMetricGroup;
 using ::android::os::PersistableBundle;
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
index 1558e8b..bf35224 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
+++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
@@ -65,7 +65,20 @@
     *plugin = new ClearKeyCasPlugin(appData, callback);
     return OK;
 }
-///////////////////////////////////////////////////////////////////////////////
+
+status_t ClearKeyCasFactory::createPlugin(
+        int32_t CA_system_id,
+        void *appData,
+        CasPluginCallbackExt callback,
+        CasPlugin **plugin) {
+    if (!isSystemIdSupported(CA_system_id)) {
+        return BAD_VALUE;
+    }
+
+    *plugin = new ClearKeyCasPlugin(appData, callback);
+    return OK;
+}
+////////////////////////////////////////////////////////////////////////////////
 bool ClearKeyDescramblerFactory::isSystemIdSupported(
         int32_t CA_system_id) const {
     return CA_system_id == sClearKeySystemId;
@@ -84,7 +97,13 @@
 ///////////////////////////////////////////////////////////////////////////////
 ClearKeyCasPlugin::ClearKeyCasPlugin(
         void *appData, CasPluginCallback callback)
-    : mCallback(callback), mAppData(appData) {
+    : mCallback(callback), mCallbackExt(NULL), mAppData(appData) {
+    ALOGV("CTOR");
+}
+
+ClearKeyCasPlugin::ClearKeyCasPlugin(
+        void *appData, CasPluginCallbackExt callback)
+    : mCallback(NULL), mCallbackExt(callback), mAppData(appData) {
     ALOGV("CTOR");
 }
 
@@ -167,11 +186,30 @@
     // Echo the received event to the callback.
     // Clear key plugin doesn't use any event, echo'ing for testing only.
     if (mCallback != NULL) {
-        mCallback((void*)mAppData, event, arg, (uint8_t*)eventData.data(), eventData.size());
+        mCallback((void*)mAppData, event, arg, (uint8_t*)eventData.data(),
+                    eventData.size());
+    } else if (mCallbackExt != NULL) {
+        mCallbackExt((void*)mAppData, event, arg, (uint8_t*)eventData.data(),
+                    eventData.size(), NULL);
     }
     return OK;
 }
 
+status_t ClearKeyCasPlugin::sendSessionEvent(
+        const CasSessionId &sessionId, int32_t event,
+        int arg, const CasData &eventData) {
+    ALOGV("sendSessionEvent: sessionId=%s, event=%d, arg=%d",
+          sessionIdToString(sessionId).string(), event, arg);
+    // Echo the received event to the callback.
+    // Clear key plugin doesn't use any event, echo'ing for testing only.
+    if (mCallbackExt != NULL) {
+        mCallbackExt((void*)mAppData, event, arg, (uint8_t*)eventData.data(),
+                    eventData.size(), &sessionId);
+    }
+
+    return OK;
+}
+
 status_t ClearKeyCasPlugin::provision(const String8 &str) {
     ALOGV("provision: provisionString=%s", str.string());
     Mutex::Autolock lock(mKeyFetcherLock);
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
index 389e172..f48d5b1 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
+++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
@@ -47,6 +47,11 @@
             void *appData,
             CasPluginCallback callback,
             CasPlugin **plugin) override;
+    virtual status_t createPlugin(
+            int32_t CA_system_id,
+            void *appData,
+            CasPluginCallbackExt callback,
+            CasPlugin **plugin) override;
 };
 
 class ClearKeyDescramblerFactory : public DescramblerFactory {
@@ -63,6 +68,7 @@
 class ClearKeyCasPlugin : public CasPlugin {
 public:
     ClearKeyCasPlugin(void *appData, CasPluginCallback callback);
+    ClearKeyCasPlugin(void *appData, CasPluginCallbackExt callback);
     virtual ~ClearKeyCasPlugin();
 
     virtual status_t setPrivateData(
@@ -85,6 +91,10 @@
     virtual status_t sendEvent(
             int32_t event, int32_t arg, const CasData &eventData) override;
 
+    virtual status_t sendSessionEvent(
+            const CasSessionId &sessionId,
+            int32_t event, int32_t arg, const CasData &eventData) override;
+
     virtual status_t provision(const String8 &str) override;
 
     virtual status_t refreshEntitlements(
@@ -94,6 +104,7 @@
     Mutex mKeyFetcherLock;
     std::unique_ptr<KeyFetcher> mKeyFetcher;
     CasPluginCallback mCallback;
+    CasPluginCallbackExt mCallbackExt;
     void* mAppData;
 };
 
diff --git a/drm/mediacas/plugins/mock/MockCasPlugin.cpp b/drm/mediacas/plugins/mock/MockCasPlugin.cpp
index 8404a83..2964791 100644
--- a/drm/mediacas/plugins/mock/MockCasPlugin.cpp
+++ b/drm/mediacas/plugins/mock/MockCasPlugin.cpp
@@ -60,6 +60,19 @@
     return OK;
 }
 
+status_t MockCasFactory::createPlugin(
+        int32_t CA_system_id,
+        void* /*appData*/,
+        CasPluginCallbackExt /*callback*/,
+        CasPlugin **plugin) {
+    if (!isSystemIdSupported(CA_system_id)) {
+        return BAD_VALUE;
+    }
+
+    *plugin = new MockCasPlugin();
+    return OK;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 bool MockDescramblerFactory::isSystemIdSupported(int32_t CA_system_id) const {
@@ -170,6 +183,16 @@
     return OK;
 }
 
+status_t MockCasPlugin::sendSessionEvent(
+        const CasSessionId &sessionId, int32_t event,
+        int /*arg*/, const CasData& /*eventData*/) {
+    ALOGV("sendSessionEvent: sessionId=%s, event=%d",
+          arrayToString(sessionId).string(), event);
+    Mutex::Autolock lock(mLock);
+
+    return OK;
+}
+
 status_t MockCasPlugin::provision(const String8 &str) {
     ALOGV("provision: provisionString=%s", str.string());
     Mutex::Autolock lock(mLock);
diff --git a/drm/mediacas/plugins/mock/MockCasPlugin.h b/drm/mediacas/plugins/mock/MockCasPlugin.h
index 8106990..74b540c 100644
--- a/drm/mediacas/plugins/mock/MockCasPlugin.h
+++ b/drm/mediacas/plugins/mock/MockCasPlugin.h
@@ -42,6 +42,11 @@
             void *appData,
             CasPluginCallback callback,
             CasPlugin **plugin) override;
+    virtual status_t createPlugin(
+            int32_t CA_system_id,
+            void *appData,
+            CasPluginCallbackExt callback,
+            CasPlugin **plugin) override;
 };
 
 class MockDescramblerFactory : public DescramblerFactory {
@@ -80,7 +85,11 @@
     virtual status_t sendEvent(
             int32_t event, int32_t arg, const CasData &eventData) override;
 
-    virtual status_t provision(const String8 &str) override;
+    virtual status_t sendSessionEvent(
+            const CasSessionId &sessionId,
+            int32_t event, int32_t arg, const CasData &eventData) override;
+
+     virtual status_t provision(const String8 &str) override;
 
     virtual status_t refreshEntitlements(
             int32_t refreshType, const CasData &refreshData) override;
diff --git a/drm/mediadrm/Android.bp b/drm/mediadrm/Android.bp
deleted file mode 100644
index b9f07f1..0000000
--- a/drm/mediadrm/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["plugins/*"]
diff --git a/drm/mediadrm/plugins/clearkey/common/Utils.cpp b/drm/mediadrm/plugins/clearkey/common/Utils.cpp
index 93c643b..d48b0a8 100644
--- a/drm/mediadrm/plugins/clearkey/common/Utils.cpp
+++ b/drm/mediadrm/plugins/clearkey/common/Utils.cpp
@@ -27,4 +27,18 @@
     return memcmp((void *)lhs.array(), (void *)rhs.array(), rhs.size()) < 0;
 }
 
+std::string ByteArrayToHexString(const uint8_t* in_buffer, size_t length) {
+    static const char kHexChars[] = "0123456789ABCDEF";
+
+    // Each input byte creates two output hex characters.
+    std::string out_buffer(length * 2, '\0');
+
+    for (size_t i = 0; i < length; ++i) {
+        char byte = in_buffer[i];
+        out_buffer[(i * 2)] = kHexChars[(byte >> 4) & 0xf];
+        out_buffer[(i * 2) + 1] = kHexChars[byte & 0xf];
+    }
+    return out_buffer;
+}
+
 } // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/common/include/Utils.h b/drm/mediadrm/plugins/clearkey/common/include/Utils.h
index 2543124..aa571c0 100644
--- a/drm/mediadrm/plugins/clearkey/common/include/Utils.h
+++ b/drm/mediadrm/plugins/clearkey/common/include/Utils.h
@@ -17,14 +17,16 @@
 #ifndef CLEARKEY_UTILS_H_
 #define CLEARKEY_UTILS_H_
 
+#include <string>
 #include <utils/Vector.h>
 
+namespace android {
 // Add a comparison operator for this Vector specialization so that it can be
 // used as a key in a KeyedVector.
-namespace android {
-
 bool operator<(const Vector<uint8_t> &lhs, const Vector<uint8_t> &rhs);
 
+std::string ByteArrayToHexString(const uint8_t* in_buffer, size_t length);
+
 } // namespace android
 
 #define UNUSED(x) (void)(x);
diff --git a/drm/mediadrm/plugins/clearkey/default/Android.bp b/drm/mediadrm/plugins/clearkey/default/Android.bp
index 7ba5708..9803d32 100644
--- a/drm/mediadrm/plugins/clearkey/default/Android.bp
+++ b/drm/mediadrm/plugins/clearkey/default/Android.bp
@@ -61,7 +61,3 @@
     },
 }
 
-//########################################################################
-// Build unit tests
-
-subdirs = ["tests"]
diff --git a/drm/mediadrm/plugins/clearkey/hidl/AesCtrDecryptor.cpp b/drm/mediadrm/plugins/clearkey/hidl/AesCtrDecryptor.cpp
index 2fce0790..0ac879c 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/AesCtrDecryptor.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/AesCtrDecryptor.cpp
@@ -26,7 +26,7 @@
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
 using ::android::hardware::drm::V1_0::SubSample;
@@ -79,7 +79,7 @@
 }
 
 } // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
 } // namespace drm
 } // namespace hardware
 } // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/Android.bp b/drm/mediadrm/plugins/clearkey/hidl/Android.bp
index 341d4f6..e91e918 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/Android.bp
+++ b/drm/mediadrm/plugins/clearkey/hidl/Android.bp
@@ -14,8 +14,8 @@
 // limitations under the License.
 //
 
-cc_binary {
-    name: "android.hardware.drm@1.1-service.clearkey",
+cc_defaults {
+    name: "clearkey_service_defaults",
     vendor: true,
 
     srcs: [
@@ -25,23 +25,24 @@
         "CreatePluginFactories.cpp",
         "CryptoFactory.cpp",
         "CryptoPlugin.cpp",
+        "DeviceFiles.cpp",
         "DrmFactory.cpp",
         "DrmPlugin.cpp",
         "InitDataParser.cpp",
         "JsonWebKey.cpp",
+        "MemoryFileSystem.cpp",
         "Session.cpp",
         "SessionLibrary.cpp",
-        "service.cpp",
     ],
 
     relative_install_path: "hw",
 
     cflags: ["-Wall", "-Werror"],
-    init_rc: ["android.hardware.drm@1.1-service.clearkey.rc"],
 
     shared_libs: [
         "android.hardware.drm@1.0",
         "android.hardware.drm@1.1",
+        "android.hardware.drm@1.2",
         "libbase",
         "libbinder",
         "libcrypto",
@@ -49,11 +50,13 @@
         "libhidlmemory",
         "libhidltransport",
         "liblog",
+        "libprotobuf-cpp-lite",
         "libutils",
     ],
 
     static_libs: [
         "libclearkeycommon",
+        "libclearkeydevicefiles-protos",
         "libjsmn",
     ],
 
@@ -65,4 +68,26 @@
         integer_overflow: true,
     },
 }
+cc_library_static {
+    name: "libclearkeydevicefiles-protos",
+    vendor: true,
 
+    proto: {
+        export_proto_headers: true,
+        type: "lite",
+    },
+    srcs: ["protos/DeviceFiles.proto"],
+}
+cc_binary {
+    name: "android.hardware.drm@1.2-service.clearkey",
+    defaults: ["clearkey_service_defaults"],
+    srcs: ["service.cpp"],
+    init_rc: ["android.hardware.drm@1.2-service.clearkey.rc"],
+}
+cc_binary {
+    name: "android.hardware.drm@1.2-service-lazy.clearkey",
+    overrides: ["android.hardware.drm@1.2-service.clearkey"],
+    defaults: ["clearkey_service_defaults"],
+    srcs: ["serviceLazy.cpp"],
+    init_rc: ["android.hardware.drm@1.2-service-lazy.clearkey.rc"],
+}
diff --git a/drm/mediadrm/plugins/clearkey/hidl/Base64.cpp b/drm/mediadrm/plugins/clearkey/hidl/Base64.cpp
index c2ed751..657a42f 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/Base64.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/Base64.cpp
@@ -21,7 +21,7 @@
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
 sp<Buffer> decodeBase64(const std::string &s) {
@@ -169,7 +169,7 @@
 }
 
 } // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
 } // namespace drm
 } // namespace hardware
 } // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/Buffer.cpp b/drm/mediadrm/plugins/clearkey/hidl/Buffer.cpp
index e58f58a..75f8395 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/Buffer.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/Buffer.cpp
@@ -21,7 +21,7 @@
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
 Buffer::Buffer(size_t capacity)
@@ -47,7 +47,7 @@
 }
 
 } // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
 } // namespace drm
 } // namespace hardware
 } // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/CreatePluginFactories.cpp b/drm/mediadrm/plugins/clearkey/hidl/CreatePluginFactories.cpp
index 1ba5c6a..1410d77 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/CreatePluginFactories.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/CreatePluginFactories.cpp
@@ -22,7 +22,7 @@
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
 extern "C" {
@@ -38,7 +38,7 @@
 } // extern "C"
 
 }  // namespace clearkey
-}  // namespace V1_1
+}  // namespace V1_2
 }  // namespace drm
 }  // namespace hardware
 }  // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/CryptoFactory.cpp b/drm/mediadrm/plugins/clearkey/hidl/CryptoFactory.cpp
index 0848cef..2a48db6 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/CryptoFactory.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/CryptoFactory.cpp
@@ -27,7 +27,7 @@
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
 Return<bool> CryptoFactory::isCryptoSchemeSupported(
@@ -60,7 +60,7 @@
 }
 
 } // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
 } // namespace drm
 } // namespace hardware
 } // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
index a3f5bf5..1495703 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
@@ -27,7 +27,7 @@
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
 using ::android::hardware::drm::V1_0::BufferType;
@@ -42,10 +42,40 @@
     return Void();
 }
 
+Return<void> CryptoPlugin::decrypt(
+    bool secure,
+    const hidl_array<uint8_t, 16>& keyId,
+    const hidl_array<uint8_t, 16>& iv,
+    Mode mode,
+    const Pattern& pattern,
+    const hidl_vec<SubSample>& subSamples,
+    const SharedBuffer& source,
+    uint64_t offset,
+    const DestinationBuffer& destination,
+    decrypt_cb _hidl_cb) {
+
+  Status status = Status::ERROR_DRM_UNKNOWN;
+  hidl_string detailedError;
+  uint32_t bytesWritten = 0;
+
+  Return<void> hResult = decrypt_1_2(
+      secure, keyId, iv, mode, pattern, subSamples, source, offset, destination,
+      [&](Status_V1_2 hStatus, uint32_t hBytesWritten, hidl_string hDetailedError) {
+        status = toStatus_1_0(hStatus);
+        bytesWritten = hBytesWritten;
+        detailedError = hDetailedError;
+      }
+    );
+
+  status = hResult.isOk() ? status : Status::ERROR_DRM_CANNOT_HANDLE;
+  _hidl_cb(status, bytesWritten, detailedError);
+  return Void();
+}
+
 // Returns negative values for error code and positive values for the size of
 // decrypted data.  In theory, the output size can be larger than the input
 // size, but in practice this will never happen for AES-CTR.
-Return<void> CryptoPlugin::decrypt(
+Return<void> CryptoPlugin::decrypt_1_2(
         bool secure,
         const hidl_array<uint8_t, KEY_ID_SIZE>& keyId,
         const hidl_array<uint8_t, KEY_IV_SIZE>& iv,
@@ -55,17 +85,17 @@
         const SharedBuffer& source,
         uint64_t offset,
         const DestinationBuffer& destination,
-        decrypt_cb _hidl_cb) {
+        decrypt_1_2_cb _hidl_cb) {
     UNUSED(pattern);
 
     if (secure) {
-        _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
+        _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
             "Secure decryption is not supported with ClearKey.");
         return Void();
     }
 
     if (mSharedBufferMap.find(source.bufferId) == mSharedBufferMap.end()) {
-      _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
+      _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
                "source decrypt buffer base not set");
       return Void();
     }
@@ -73,24 +103,24 @@
     if (destination.type == BufferType::SHARED_MEMORY) {
       const SharedBuffer& dest = destination.nonsecureMemory;
       if (mSharedBufferMap.find(dest.bufferId) == mSharedBufferMap.end()) {
-        _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
+        _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
                  "destination decrypt buffer base not set");
         return Void();
       }
     } else {
-        _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
+        _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
                  "destination type not supported");
         return Void();
     }
 
     sp<IMemory> sourceBase = mSharedBufferMap[source.bufferId];
     if (sourceBase == nullptr) {
-        _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "source is a nullptr");
+        _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0, "source is a nullptr");
         return Void();
     }
 
     if (source.offset + offset + source.size > sourceBase->getSize()) {
-        _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
+        _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
         return Void();
     }
 
@@ -102,18 +132,19 @@
     const SharedBuffer& destBuffer = destination.nonsecureMemory;
     sp<IMemory> destBase = mSharedBufferMap[destBuffer.bufferId];
     if (destBase == nullptr) {
-        _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "destination is a nullptr");
+        _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0, "destination is a nullptr");
         return Void();
     }
 
     base = static_cast<uint8_t *>(static_cast<void *>(destBase->getPointer()));
 
     if (destBuffer.offset + destBuffer.size > destBase->getSize()) {
-        _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
+        _hidl_cb(Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE, 0, "invalid buffer size");
         return Void();
     }
     destPtr = static_cast<void *>(base + destination.nonsecureMemory.offset);
 
+
     // Calculate the output buffer size and determine if any subsamples are
     // encrypted.
     size_t destSize = 0;
@@ -123,12 +154,12 @@
         const SubSample &subSample = subSamples[i];
         if (__builtin_add_overflow(destSize, subSample.numBytesOfClearData, &destSize) ||
             __builtin_add_overflow(srcSize, subSample.numBytesOfClearData, &srcSize)) {
-            _hidl_cb(Status::BAD_VALUE, 0, "subsample clear size overflow");
+            _hidl_cb(Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE, 0, "subsample clear size overflow");
             return Void();
         }
         if (__builtin_add_overflow(destSize, subSample.numBytesOfEncryptedData, &destSize) ||
             __builtin_add_overflow(srcSize, subSample.numBytesOfEncryptedData, &srcSize)) {
-            _hidl_cb(Status::BAD_VALUE, 0, "subsample encrypted size overflow");
+            _hidl_cb(Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE, 0, "subsample encrypted size overflow");
             return Void();
         }
         if (subSample.numBytesOfEncryptedData > 0) {
@@ -137,13 +168,13 @@
     }
 
     if (destSize > destBuffer.size || srcSize > source.size) {
-        _hidl_cb(Status::BAD_VALUE, 0, "subsample sum too large");
+        _hidl_cb(Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE, 0, "subsample sum too large");
         return Void();
     }
 
     if (mode == Mode::UNENCRYPTED) {
         if (haveEncryptedSubsamples) {
-            _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
+            _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
                     "Encrypted subsamples found in allegedly unencrypted data.");
             return Void();
         }
@@ -159,22 +190,21 @@
             }
         }
 
-        _hidl_cb(Status::OK, static_cast<ssize_t>(offset), "");
+        _hidl_cb(Status_V1_2::OK, static_cast<ssize_t>(offset), "");
         return Void();
     } else if (mode == Mode::AES_CTR) {
         size_t bytesDecrypted;
-        Status res = mSession->decrypt(keyId.data(), iv.data(), srcPtr,
+        Status_V1_2 res = mSession->decrypt(keyId.data(), iv.data(), srcPtr,
                 static_cast<uint8_t*>(destPtr), toVector(subSamples), &bytesDecrypted);
-        if (res == Status::OK) {
-            _hidl_cb(Status::OK, static_cast<ssize_t>(bytesDecrypted), "");
+        if (res == Status_V1_2::OK) {
+            _hidl_cb(Status_V1_2::OK, static_cast<ssize_t>(bytesDecrypted), "");
             return Void();
         } else {
-            _hidl_cb(Status::ERROR_DRM_DECRYPT, static_cast<ssize_t>(res),
-                    "Decryption Error");
+            _hidl_cb(res, 0, "Decryption Error");
             return Void();
         }
     } else {
-        _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
+        _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
                 "Selected encryption mode is not supported by the ClearKey DRM Plugin.");
         return Void();
     }
@@ -194,7 +224,7 @@
 }
 
 } // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
 } // namespace drm
 } // namespace hardware
 } // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/DeviceFiles.cpp b/drm/mediadrm/plugins/clearkey/hidl/DeviceFiles.cpp
new file mode 100644
index 0000000..2415b6f
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/DeviceFiles.cpp
@@ -0,0 +1,252 @@
+// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
+// source code may only be used and distributed under the Widevine Master
+// License Agreement.
+
+#include <utils/Log.h>
+
+#include <string>
+#include <sys/stat.h>
+
+#include "DeviceFiles.h"
+#include "Utils.h"
+
+#include <openssl/sha.h>
+
+// Protobuf generated classes.
+using android::hardware::drm::V1_2::clearkey::OfflineFile;
+using android::hardware::drm::V1_2::clearkey::HashedFile;
+using android::hardware::drm::V1_2::clearkey::License;
+using android::hardware::drm::V1_2::clearkey::License_LicenseState_ACTIVE;
+using android::hardware::drm::V1_2::clearkey::License_LicenseState_RELEASING;
+
+namespace {
+const char kLicenseFileNameExt[] = ".lic";
+
+bool Hash(const std::string& data, std::string* hash) {
+    if (!hash) return false;
+
+    hash->resize(SHA256_DIGEST_LENGTH);
+
+    const unsigned char* input = reinterpret_cast<const unsigned char*>(data.data());
+    unsigned char* output = reinterpret_cast<unsigned char*>(&(*hash)[0]);
+    SHA256(input, data.size(), output);
+    return true;
+}
+
+}  // namespace
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_2 {
+namespace clearkey {
+
+bool DeviceFiles::StoreLicense(
+        const std::string& keySetId, LicenseState state,
+        const std::string& licenseResponse) {
+
+    OfflineFile file;
+    file.set_type(OfflineFile::LICENSE);
+    file.set_version(OfflineFile::VERSION_1);
+
+    License* license = file.mutable_license();
+    switch (state) {
+        case kLicenseStateActive:
+            license->set_state(License_LicenseState_ACTIVE);
+            license->set_license(licenseResponse);
+            break;
+        case kLicenseStateReleasing:
+            license->set_state(License_LicenseState_RELEASING);
+            license->set_license(licenseResponse);
+            break;
+        default:
+            ALOGW("StoreLicense: Unknown license state: %u", state);
+            return false;
+    }
+
+    std::string serializedFile;
+    file.SerializeToString(&serializedFile);
+
+    return StoreFileWithHash(keySetId + kLicenseFileNameExt, serializedFile);
+}
+
+bool DeviceFiles::StoreFileWithHash(const std::string& fileName,
+        const std::string& serializedFile) {
+    std::string hash;
+    if (!Hash(serializedFile, &hash)) {
+        ALOGE("StoreFileWithHash: Failed to compute hash");
+        return false;
+    }
+
+    HashedFile hashFile;
+    hashFile.set_file(serializedFile);
+    hashFile.set_hash(hash);
+
+    std::string serializedHashFile;
+    hashFile.SerializeToString(&serializedHashFile);
+
+    return StoreFileRaw(fileName, serializedHashFile);
+}
+
+bool DeviceFiles::StoreFileRaw(const std::string& fileName, const std::string& serializedHashFile) {
+    MemoryFileSystem::MemoryFile memFile;
+    memFile.setFileName(fileName);
+    memFile.setContent(serializedHashFile);
+    memFile.setFileSize(serializedHashFile.size());
+    size_t len = mFileHandle.Write(fileName, memFile);
+
+    if (len != static_cast<size_t>(serializedHashFile.size())) {
+        ALOGE("StoreFileRaw: Failed to write %s", fileName.c_str());
+        ALOGD("StoreFileRaw: expected=%zd, actual=%zu", serializedHashFile.size(), len);
+        return false;
+    }
+
+    ALOGD("StoreFileRaw: wrote %zu bytes to %s", serializedHashFile.size(), fileName.c_str());
+    return true;
+}
+
+bool DeviceFiles::RetrieveLicense(
+    const std::string& keySetId, LicenseState* state, std::string* offlineLicense) {
+
+    OfflineFile file;
+    if (!RetrieveHashedFile(keySetId + kLicenseFileNameExt, &file)) {
+        return false;
+    }
+
+    if (file.type() != OfflineFile::LICENSE) {
+        ALOGE("RetrieveLicense: Invalid file type");
+        return false;
+    }
+
+    if (file.version() != OfflineFile::VERSION_1) {
+        ALOGE("RetrieveLicense: Invalid file version");
+        return false;
+    }
+
+    if (!file.has_license()) {
+        ALOGE("RetrieveLicense: License not present");
+        return false;
+    }
+
+    License license = file.license();
+    switch (license.state()) {
+        case License_LicenseState_ACTIVE:
+            *state = kLicenseStateActive;
+            break;
+        case License_LicenseState_RELEASING:
+            *state = kLicenseStateReleasing;
+            break;
+        default:
+            ALOGW("RetrieveLicense: Unrecognized license state: %u",
+                    kLicenseStateUnknown);
+            *state = kLicenseStateUnknown;
+            break;
+    }
+    *offlineLicense = license.license();
+    return true;
+}
+
+bool DeviceFiles::DeleteLicense(const std::string& keySetId) {
+    return mFileHandle.RemoveFile(keySetId + kLicenseFileNameExt);
+}
+
+bool DeviceFiles::DeleteAllLicenses() {
+    return mFileHandle.RemoveAllFiles();
+}
+
+bool DeviceFiles::LicenseExists(const std::string& keySetId) {
+    return mFileHandle.FileExists(keySetId + kLicenseFileNameExt);
+}
+
+std::vector<std::string> DeviceFiles::ListLicenses() const {
+    std::vector<std::string> licenses = mFileHandle.ListFiles();
+    for (size_t i = 0; i < licenses.size(); i++) {
+        std::string& license = licenses[i];
+        license = license.substr(0, license.size() - strlen(kLicenseFileNameExt));
+    }
+    return licenses;
+}
+
+bool DeviceFiles::RetrieveHashedFile(const std::string& fileName, OfflineFile* deSerializedFile) {
+    if (!deSerializedFile) {
+        ALOGE("RetrieveHashedFile: invalid file parameter");
+        return false;
+    }
+
+    if (!FileExists(fileName)) {
+        ALOGE("RetrieveHashedFile: %s does not exist", fileName.c_str());
+        return false;
+    }
+
+    ssize_t bytes = GetFileSize(fileName);
+    if (bytes <= 0) {
+        ALOGE("RetrieveHashedFile: invalid file size: %s", fileName.c_str());
+        // Remove the corrupted file so the caller will not get the same error
+        // when trying to access the file repeatedly, causing the system to stall.
+        RemoveFile(fileName);
+        return false;
+    }
+
+    std::string serializedHashFile;
+    serializedHashFile.resize(bytes);
+    bytes = mFileHandle.Read(fileName, &serializedHashFile);
+
+    if (bytes != static_cast<ssize_t>(serializedHashFile.size())) {
+        ALOGE("RetrieveHashedFile: Failed to read from %s", fileName.c_str());
+        ALOGV("RetrieveHashedFile: expected: %zd, actual: %zd", serializedHashFile.size(), bytes);
+        // Remove the corrupted file so the caller will not get the same error
+        // when trying to access the file repeatedly, causing the system to stall.
+        RemoveFile(fileName);
+        return false;
+    }
+
+    ALOGV("RetrieveHashedFile: read %zd from %s", bytes, fileName.c_str());
+
+    HashedFile hashFile;
+    if (!hashFile.ParseFromString(serializedHashFile)) {
+        ALOGE("RetrieveHashedFile: Unable to parse hash file");
+        // Remove corrupt file.
+        RemoveFile(fileName);
+        return false;
+    }
+
+    std::string hash;
+    if (!Hash(hashFile.file(), &hash)) {
+        ALOGE("RetrieveHashedFile: Hash computation failed");
+        return false;
+    }
+
+    if (hash != hashFile.hash()) {
+        ALOGE("RetrieveHashedFile: Hash mismatch");
+        // Remove corrupt file.
+        RemoveFile(fileName);
+        return false;
+    }
+
+    if (!deSerializedFile->ParseFromString(hashFile.file())) {
+        ALOGE("RetrieveHashedFile: Unable to parse file");
+        // Remove corrupt file.
+        RemoveFile(fileName);
+        return false;
+    }
+
+    return true;
+}
+
+bool DeviceFiles::FileExists(const std::string& fileName) const {
+    return mFileHandle.FileExists(fileName);
+}
+
+bool DeviceFiles::RemoveFile(const std::string& fileName) {
+    return mFileHandle.RemoveFile(fileName);
+}
+
+ssize_t DeviceFiles::GetFileSize(const std::string& fileName) const {
+    return mFileHandle.GetFileSize(fileName);
+}
+
+} // namespace clearkey
+} // namespace V1_2
+} // namespace drm
+} // namespace hardware
+} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/DrmFactory.cpp b/drm/mediadrm/plugins/clearkey/hidl/DrmFactory.cpp
index 77557f9..9fb5bbe 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/DrmFactory.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/DrmFactory.cpp
@@ -30,10 +30,11 @@
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
 using ::android::hardware::drm::V1_0::Status;
+using ::android::hardware::drm::V1_1::SecurityLevel;
 using ::android::hardware::Void;
 
 Return<bool> DrmFactory::isCryptoSchemeSupported(
@@ -41,6 +42,13 @@
     return clearkeydrm::isClearKeyUUID(uuid.data());
 }
 
+Return<bool> DrmFactory::isCryptoSchemeSupported_1_2(const hidl_array<uint8_t, 16>& uuid,
+                                                     const hidl_string &mimeType,
+                                                     SecurityLevel level) {
+    return isCryptoSchemeSupported(uuid) && isContentTypeSupported(mimeType) &&
+            level == SecurityLevel::SW_SECURE_CRYPTO;
+}
+
 Return<bool> DrmFactory::isContentTypeSupported(const hidl_string &mimeType) {
     // This should match the mimeTypes handed by InitDataParser.
     return mimeType == kIsoBmffVideoMimeType ||
@@ -71,7 +79,7 @@
 }
 
 } // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
 } // namespace drm
 } // namespace hardware
 } // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
index 30f7459..7cb5a38 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
@@ -25,11 +25,15 @@
 #include "ClearKeyDrmProperties.h"
 #include "Session.h"
 #include "TypeConvert.h"
+#include "Utils.h"
 
 namespace {
+const std::string kKeySetIdPrefix("ckid");
+const int kKeySetIdLength = 16;
 const int kSecureStopIdStart = 100;
+const std::string kOfflineLicense("\"type\":\"persistent-license\"");
 const std::string kStreaming("Streaming");
-const std::string kOffline("Offline");
+const std::string kTemporaryLicense("\"type\":\"temporary\"");
 const std::string kTrue("True");
 
 const std::string kQueryKeyLicenseType("LicenseType");
@@ -54,18 +58,31 @@
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
+KeyRequestType toKeyRequestType_V1_0(KeyRequestType_V1_1 keyRequestType) {
+  switch (keyRequestType) {
+    case KeyRequestType_V1_1::NONE:
+    case KeyRequestType_V1_1::UPDATE:
+      return KeyRequestType::UNKNOWN;
+    default:
+      return static_cast<KeyRequestType>(keyRequestType);
+  }
+}
+
 DrmPlugin::DrmPlugin(SessionLibrary* sessionLibrary)
         : mSessionLibrary(sessionLibrary),
           mOpenSessionOkCount(0),
           mCloseSessionOkCount(0),
           mCloseSessionNotOpenedCount(0),
-          mNextSecureStopId(kSecureStopIdStart) {
+          mNextSecureStopId(kSecureStopIdStart),
+          mMockError(Status_V1_2::OK) {
     mPlayPolicy.clear();
     initProperties();
     mSecureStops.clear();
+    mReleaseKeysMap.clear();
+    std::srand(std::time(nullptr));
 }
 
 void DrmPlugin::initProperties() {
@@ -75,6 +92,7 @@
     mStringProperties[kPluginDescriptionKey] = kPluginDescriptionValue;
     mStringProperties[kAlgorithmsKey] = kAlgorithmsValue;
     mStringProperties[kListenerTestSupportKey] = kListenerTestSupportValue;
+    mStringProperties[kDrmErrorTestKey] = kDrmErrorTestValue;
 
     std::vector<uint8_t> valueVector;
     valueVector.clear();
@@ -103,6 +121,7 @@
 
 Return<void> DrmPlugin::openSession(openSession_cb _hidl_cb) {
     sp<Session> session = mSessionLibrary->createSession();
+    processMockError(session);
     std::vector<uint8_t> sessionId = session->sessionId();
 
     Status status = setSecurityLevel(sessionId, SecurityLevel::SW_SECURE_CRYPTO);
@@ -114,6 +133,7 @@
 Return<void> DrmPlugin::openSession_1_1(SecurityLevel securityLevel,
         openSession_1_1_cb _hidl_cb) {
     sp<Session> session = mSessionLibrary->createSession();
+    processMockError(session);
     std::vector<uint8_t> sessionId = session->sessionId();
 
     Status status = setSecurityLevel(sessionId, securityLevel);
@@ -129,6 +149,10 @@
 
     sp<Session> session = mSessionLibrary->findSession(toVector(sessionId));
     if (session.get()) {
+        if (session->getMockError() != Status_V1_2::OK) {
+            sendSessionLostState(sessionId);
+            return Status::ERROR_DRM_INVALID_STATE;
+        }
         mCloseSessionOkCount++;
         mSessionLibrary->destroySession(session);
         return Status::OK;
@@ -137,35 +161,75 @@
     return Status::ERROR_DRM_SESSION_NOT_OPENED;
 }
 
-Status DrmPlugin::getKeyRequestCommon(const hidl_vec<uint8_t>& scope,
+Status_V1_2 DrmPlugin::getKeyRequestCommon(const hidl_vec<uint8_t>& scope,
         const hidl_vec<uint8_t>& initData,
         const hidl_string& mimeType,
         KeyType keyType,
         const hidl_vec<KeyValue>& optionalParameters,
         std::vector<uint8_t> *request,
-        KeyRequestType *keyRequestType,
+        KeyRequestType_V1_1 *keyRequestType,
         std::string *defaultUrl) {
         UNUSED(optionalParameters);
 
+    // GetKeyRequestOfflineKeyTypeNotSupported() in vts 1.0 and 1.1 expects
+    // KeyType::OFFLINE to return ERROR_DRM_CANNOT_HANDLE in clearkey plugin.
+    // Those tests pass in an empty initData, we use the empty initData to
+    // signal such specific use case.
+    if (keyType == KeyType::OFFLINE && 0 == initData.size()) {
+        return Status_V1_2::ERROR_DRM_CANNOT_HANDLE;
+    }
+
     *defaultUrl = "";
-    *keyRequestType = KeyRequestType::UNKNOWN;
+    *keyRequestType = KeyRequestType_V1_1::UNKNOWN;
     *request = std::vector<uint8_t>();
 
-    if (scope.size() == 0) {
-        return Status::BAD_VALUE;
+    if (scope.size() == 0 ||
+            (keyType != KeyType::STREAMING &&
+            keyType != KeyType::OFFLINE &&
+            keyType != KeyType::RELEASE)) {
+        return Status_V1_2::BAD_VALUE;
     }
 
-    if (keyType != KeyType::STREAMING) {
-        return Status::ERROR_DRM_CANNOT_HANDLE;
+    const std::vector<uint8_t> scopeId = toVector(scope);
+    sp<Session> session;
+    if (keyType == KeyType::STREAMING || keyType == KeyType::OFFLINE) {
+        std::vector<uint8_t> sessionId(scopeId.begin(), scopeId.end());
+        session = mSessionLibrary->findSession(sessionId);
+        if (!session.get()) {
+            return Status_V1_2::ERROR_DRM_SESSION_NOT_OPENED;
+        } else if (session->getMockError() != Status_V1_2::OK) {
+            return session->getMockError();
+        }
+
+        *keyRequestType = KeyRequestType_V1_1::INITIAL;
     }
 
-    sp<Session> session = mSessionLibrary->findSession(toVector(scope));
-    if (!session.get()) {
-        return Status::ERROR_DRM_SESSION_NOT_OPENED;
-    }
+    Status_V1_2 status = static_cast<Status_V1_2>(
+            session->getKeyRequest(initData, mimeType, keyType, request));
 
-    Status status = session->getKeyRequest(initData, mimeType, request);
-    *keyRequestType = KeyRequestType::INITIAL;
+    if (keyType == KeyType::RELEASE) {
+        std::vector<uint8_t> keySetId(scopeId.begin(), scopeId.end());
+        std::string requestString(request->begin(), request->end());
+        if (requestString.find(kOfflineLicense) != std::string::npos) {
+            std::string emptyResponse;
+            std::string keySetIdString(keySetId.begin(), keySetId.end());
+            if (!mFileHandle.StoreLicense(keySetIdString,
+                    DeviceFiles::kLicenseStateReleasing,
+                    emptyResponse)) {
+                ALOGE("Problem releasing offline license");
+                return Status_V1_2::ERROR_DRM_UNKNOWN;
+            }
+            if (mReleaseKeysMap.find(keySetIdString) == mReleaseKeysMap.end()) {
+                sp<Session> session = mSessionLibrary->createSession();
+                mReleaseKeysMap[keySetIdString] = session->sessionId();
+            } else {
+                ALOGI("key is in use, ignore release request");
+            }
+        } else {
+            ALOGE("Offline license not found, nothing to release");
+        }
+        *keyRequestType = KeyRequestType_V1_1::RELEASE;
+    }
     return status;
 }
 
@@ -178,15 +242,15 @@
         getKeyRequest_cb _hidl_cb) {
     UNUSED(optionalParameters);
 
-    KeyRequestType keyRequestType = KeyRequestType::UNKNOWN;
+    KeyRequestType_V1_1 keyRequestType = KeyRequestType_V1_1::UNKNOWN;
     std::string defaultUrl("");
     std::vector<uint8_t> request;
-    Status status = getKeyRequestCommon(
+    Status_V1_2 status = getKeyRequestCommon(
             scope, initData, mimeType, keyType, optionalParameters,
             &request, &keyRequestType, &defaultUrl);
 
-    _hidl_cb(status, toHidlVec(request),
-            static_cast<drm::V1_0::KeyRequestType>(keyRequestType),
+    _hidl_cb(toStatus_1_0(status), toHidlVec(request),
+            toKeyRequestType_V1_0(keyRequestType),
             hidl_string(defaultUrl));
     return Void();
 }
@@ -200,10 +264,31 @@
         getKeyRequest_1_1_cb _hidl_cb) {
     UNUSED(optionalParameters);
 
-    KeyRequestType keyRequestType = KeyRequestType::UNKNOWN;
+    KeyRequestType_V1_1 keyRequestType = KeyRequestType_V1_1::UNKNOWN;
     std::string defaultUrl("");
     std::vector<uint8_t> request;
-    Status status = getKeyRequestCommon(
+    Status_V1_2 status = getKeyRequestCommon(
+            scope, initData, mimeType, keyType, optionalParameters,
+            &request, &keyRequestType, &defaultUrl);
+
+    _hidl_cb(toStatus_1_0(status), toHidlVec(request),
+            keyRequestType, hidl_string(defaultUrl));
+    return Void();
+}
+
+Return<void> DrmPlugin::getKeyRequest_1_2(
+        const hidl_vec<uint8_t>& scope,
+        const hidl_vec<uint8_t>& initData,
+        const hidl_string& mimeType,
+        KeyType keyType,
+        const hidl_vec<KeyValue>& optionalParameters,
+        getKeyRequest_1_2_cb _hidl_cb) {
+    UNUSED(optionalParameters);
+
+    KeyRequestType_V1_1 keyRequestType = KeyRequestType_V1_1::UNKNOWN;
+    std::string defaultUrl("");
+    std::vector<uint8_t> request;
+    Status_V1_2 status = getKeyRequestCommon(
             scope, initData, mimeType, keyType, optionalParameters,
             &request, &keyRequestType, &defaultUrl);
 
@@ -227,6 +312,30 @@
     mPlayPolicy.push_back(policy);
 }
 
+bool DrmPlugin::makeKeySetId(std::string* keySetId) {
+    if (!keySetId) {
+        ALOGE("keySetId destination not provided");
+        return false;
+    }
+    std::vector<uint8_t> ksid(kKeySetIdPrefix.begin(), kKeySetIdPrefix.end());
+    ksid.resize(kKeySetIdLength);
+    std::vector<uint8_t> randomData((kKeySetIdLength - kKeySetIdPrefix.size()) / 2, 0);
+
+    while (keySetId->empty()) {
+        for (auto itr = randomData.begin(); itr != randomData.end(); ++itr) {
+            *itr = std::rand() % 0xff;
+        }
+        *keySetId = kKeySetIdPrefix + ByteArrayToHexString(
+                reinterpret_cast<const uint8_t*>(randomData.data()), randomData.size());
+        if (mFileHandle.LicenseExists(*keySetId)) {
+            // collision, regenerate
+            ALOGV("Retry generating KeySetId");
+            keySetId->clear();
+        }
+    }
+    return true;
+}
+
 Return<void> DrmPlugin::provideKeyResponse(
         const hidl_vec<uint8_t>& scope,
         const hidl_vec<uint8_t>& response,
@@ -237,28 +346,124 @@
         return Void();
     }
 
-    sp<Session> session = mSessionLibrary->findSession(toVector(scope));
+    std::string responseString(
+            reinterpret_cast<const char*>(response.data()), response.size());
+    const std::vector<uint8_t> scopeId = toVector(scope);
+    std::vector<uint8_t> sessionId;
+    std::string keySetId;
+
+    Status status = Status::OK;
+    bool isOfflineLicense = responseString.find(kOfflineLicense) != std::string::npos;
+    bool isRelease = (memcmp(scopeId.data(), kKeySetIdPrefix.data(), kKeySetIdPrefix.size()) == 0);
+    if (isRelease) {
+        keySetId.assign(scopeId.begin(), scopeId.end());
+
+        auto iter = mReleaseKeysMap.find(std::string(keySetId.begin(), keySetId.end()));
+        if (iter != mReleaseKeysMap.end()) {
+            sessionId.assign(iter->second.begin(), iter->second.end());
+        }
+    } else {
+        sessionId.assign(scopeId.begin(), scopeId.end());
+        // non offline license returns empty keySetId
+        keySetId.clear();
+    }
+
+    sp<Session> session = mSessionLibrary->findSession(sessionId);
     if (!session.get()) {
         _hidl_cb(Status::ERROR_DRM_SESSION_NOT_OPENED, hidl_vec<uint8_t>());
         return Void();
     }
-
     setPlayPolicy();
-    std::vector<uint8_t> keySetId;
-    Status status = session->provideKeyResponse(response);
+
+    status = session->provideKeyResponse(response);
     if (status == Status::OK) {
-        // This is for testing AMediaDrm_setOnEventListener only.
-        sendEvent(EventType::VENDOR_DEFINED, 0, scope);
-        keySetId.clear();
+        if (isOfflineLicense) {
+            if (isRelease) {
+                mFileHandle.DeleteLicense(keySetId);
+            } else {
+                if (!makeKeySetId(&keySetId)) {
+                    _hidl_cb(Status::ERROR_DRM_UNKNOWN, hidl_vec<uint8_t>());
+                    return Void();
+                }
+
+                bool ok = mFileHandle.StoreLicense(
+                        keySetId,
+                        DeviceFiles::kLicenseStateActive,
+                        std::string(response.begin(), response.end()));
+                if (!ok) {
+                    ALOGE("Failed to store offline license");
+                }
+            }
+        }
+
+        // Test calling AMediaDrm listeners.
+        sendEvent(EventType::VENDOR_DEFINED, sessionId, sessionId);
+
+        sendExpirationUpdate(sessionId, 100);
+
+        std::vector<KeyStatus_V1_2> keysStatus;
+        KeyStatus_V1_2 keyStatus;
+
+        std::vector<uint8_t> keyId1 = { 0xA, 0xB, 0xC };
+        keyStatus.keyId = keyId1;
+        keyStatus.type = V1_2::KeyStatusType::USABLE;
+        keysStatus.push_back(keyStatus);
+
+        std::vector<uint8_t> keyId2 = { 0xD, 0xE, 0xF };
+        keyStatus.keyId = keyId2;
+        keyStatus.type = V1_2::KeyStatusType::EXPIRED;
+        keysStatus.push_back(keyStatus);
+
+        std::vector<uint8_t> keyId3 = { 0x0, 0x1, 0x2 };
+        keyStatus.keyId = keyId3;
+        keyStatus.type = V1_2::KeyStatusType::USABLEINFUTURE;
+        keysStatus.push_back(keyStatus);
+
+        sendKeysChange_1_2(sessionId, keysStatus, true);
+
+        installSecureStop(sessionId);
+    } else {
+        ALOGE("provideKeyResponse returns error=%d", status);
     }
 
-    installSecureStop(scope);
-
-    // Returns status and empty keySetId
-    _hidl_cb(status, toHidlVec(keySetId));
+    std::vector<uint8_t> keySetIdVec(keySetId.begin(), keySetId.end());
+    _hidl_cb(status, toHidlVec(keySetIdVec));
     return Void();
 }
 
+Return<Status> DrmPlugin::restoreKeys(
+        const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& keySetId) {
+        if (sessionId.size() == 0 || keySetId.size() == 0) {
+            return Status::BAD_VALUE;
+        }
+
+        DeviceFiles::LicenseState licenseState;
+        std::string offlineLicense;
+        Status status = Status::OK;
+        if (!mFileHandle.RetrieveLicense(std::string(keySetId.begin(), keySetId.end()),
+                &licenseState, &offlineLicense)) {
+            ALOGE("Failed to restore offline license");
+            return Status::ERROR_DRM_NO_LICENSE;
+        }
+
+        if (DeviceFiles::kLicenseStateUnknown == licenseState ||
+                DeviceFiles::kLicenseStateReleasing == licenseState) {
+            ALOGE("Invalid license state=%d", licenseState);
+            return Status::ERROR_DRM_NO_LICENSE;
+        }
+
+        sp<Session> session = mSessionLibrary->findSession(toVector(sessionId));
+        if (!session.get()) {
+            return Status::ERROR_DRM_SESSION_NOT_OPENED;
+        }
+        status = session->provideKeyResponse(std::vector<uint8_t>(offlineLicense.begin(),
+                offlineLicense.end()));
+        if (status != Status::OK) {
+            ALOGE("Failed to restore keys");
+        }
+        return status;
+}
+
 Return<void> DrmPlugin::getPropertyString(
         const hidl_string& propertyName, getPropertyString_cb _hidl_cb) {
     std::string name(propertyName.c_str());
@@ -274,6 +479,8 @@
         value = mStringProperties[kAlgorithmsKey];
     } else if (name == kListenerTestSupportKey) {
         value = mStringProperties[kListenerTestSupportKey];
+    } else if (name == kDrmErrorTestKey) {
+        value = mStringProperties[kDrmErrorTestKey];
     } else {
         ALOGE("App requested unknown string property %s", name.c_str());
         _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, "");
@@ -318,6 +525,20 @@
         return Status::BAD_VALUE;
     }
 
+    if (name == kDrmErrorTestKey) {
+        if (value == kResourceContentionValue) {
+            mMockError = Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION;
+        } else if (value == kLostStateValue) {
+            mMockError = Status_V1_2::ERROR_DRM_SESSION_LOST_STATE;
+        } else if (value == kFrameTooLargeValue) {
+            mMockError = Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE;
+        } else if (value == kInvalidStateValue)  {
+            mMockError = Status_V1_2::ERROR_DRM_INVALID_STATE;
+        } else {
+            mMockError = Status_V1_2::ERROR_DRM_UNKNOWN;
+        }
+    }
+
     mStringProperties[key] = std::string(value.c_str());
     return Status::OK;
 }
@@ -328,6 +549,9 @@
    if (name == kDeviceIdKey) {
       ALOGD("Cannot set immutable property: %s", name.c_str());
       return Status::BAD_VALUE;
+   } else if (name == kClientIdKey) {
+       mByteArrayProperties[kClientIdKey] = toVector(value);
+       return Status::OK;
    }
 
    // Setting of undefined properties is not supported
@@ -465,6 +689,60 @@
     return Void();
 }
 
+Return<void> DrmPlugin::getOfflineLicenseKeySetIds(getOfflineLicenseKeySetIds_cb _hidl_cb) {
+    std::vector<std::string> licenseNames = mFileHandle.ListLicenses();
+    std::vector<KeySetId> keySetIds;
+    if (mMockError != Status_V1_2::OK) {
+        _hidl_cb(toStatus_1_0(mMockError), keySetIds);
+        return Void();
+    }
+    for (const auto& name : licenseNames) {
+        std::vector<uint8_t> keySetId(name.begin(), name.end());
+        keySetIds.push_back(keySetId);
+    }
+    _hidl_cb(Status::OK, keySetIds);
+    return Void();
+}
+
+
+Return<Status> DrmPlugin::removeOfflineLicense(const KeySetId& keySetId) {
+    if (mMockError != Status_V1_2::OK) {
+        return toStatus_1_0(mMockError);
+    }
+    std::string licenseName(keySetId.begin(), keySetId.end());
+    if (mFileHandle.DeleteLicense(licenseName)) {
+        return Status::OK;
+    }
+    return Status::BAD_VALUE;
+}
+
+Return<void> DrmPlugin::getOfflineLicenseState(const KeySetId& keySetId,
+        getOfflineLicenseState_cb _hidl_cb) {
+    std::string licenseName(keySetId.begin(), keySetId.end());
+    DeviceFiles::LicenseState state;
+    std::string license;
+    OfflineLicenseState hLicenseState;
+    if (mMockError != Status_V1_2::OK) {
+        _hidl_cb(toStatus_1_0(mMockError), OfflineLicenseState::UNKNOWN);
+    } else if (mFileHandle.RetrieveLicense(licenseName, &state, &license)) {
+        switch (state) {
+        case DeviceFiles::kLicenseStateActive:
+            hLicenseState = OfflineLicenseState::USABLE;
+            break;
+        case DeviceFiles::kLicenseStateReleasing:
+            hLicenseState = OfflineLicenseState::INACTIVE;
+            break;
+        case DeviceFiles::kLicenseStateUnknown:
+            hLicenseState = OfflineLicenseState::UNKNOWN;
+            break;
+        }
+        _hidl_cb(Status::OK, hLicenseState);
+    } else {
+        _hidl_cb(Status::BAD_VALUE, OfflineLicenseState::UNKNOWN);
+    }
+    return Void();
+}
+
 Return<void> DrmPlugin::getSecureStops(getSecureStops_cb _hidl_cb) {
     std::vector<SecureStop> stops;
     for (auto itr = mSecureStops.begin(); itr != mSecureStops.end(); ++itr) {
@@ -572,7 +850,7 @@
 }
 
 }  // namespace clearkey
-}  // namespace V1_1
+}  // namespace V1_2
 }  // namespace drm
 }  // namespace hardware
 }  // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/InitDataParser.cpp b/drm/mediadrm/plugins/clearkey/hidl/InitDataParser.cpp
index e2bb651..b988ce0 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/InitDataParser.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/InitDataParser.cpp
@@ -31,7 +31,7 @@
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
 namespace {
@@ -45,21 +45,22 @@
 }
 
 Status InitDataParser::parse(const std::vector<uint8_t>& initData,
-        const std::string& type,
+        const std::string& mimeType,
+        V1_0::KeyType keyType,
         std::vector<uint8_t>* licenseRequest) {
     // Build a list of the key IDs
     std::vector<const uint8_t*> keyIds;
 
-    if (type == kIsoBmffVideoMimeType ||
-        type == kIsoBmffAudioMimeType ||
-        type == kCencInitDataFormat) {
+    if (mimeType == kIsoBmffVideoMimeType.c_str() ||
+        mimeType == kIsoBmffAudioMimeType.c_str() ||
+        mimeType == kCencInitDataFormat.c_str()) {
         Status res = parsePssh(initData, &keyIds);
         if (res != Status::OK) {
             return res;
         }
-    } else if (type == kWebmVideoMimeType ||
-        type == kWebmAudioMimeType ||
-        type == kWebmInitDataFormat) {
+    } else if (mimeType == kWebmVideoMimeType.c_str() ||
+        mimeType == kWebmAudioMimeType.c_str() ||
+        mimeType == kWebmInitDataFormat.c_str()) {
         // WebM "init data" is just a single key ID
         if (initData.size() != kKeyIdSize) {
             return Status::ERROR_DRM_CANNOT_HANDLE;
@@ -69,8 +70,12 @@
         return Status::ERROR_DRM_CANNOT_HANDLE;
     }
 
+    if (keyType == V1_0::KeyType::RELEASE) {
+        // restore key
+    }
+
     // Build the request
-    std::string requestJson = generateRequest(keyIds);
+    std::string requestJson = generateRequest(keyType, keyIds);
     std::vector<uint8_t> requestJsonVec = StrToVector(requestJson);
 
     licenseRequest->clear();
@@ -131,9 +136,11 @@
     return Status::OK;
 }
 
-std::string InitDataParser::generateRequest(const std::vector<const uint8_t*>& keyIds) {
+std::string InitDataParser::generateRequest(V1_0::KeyType keyType,
+        const std::vector<const uint8_t*>& keyIds) {
     const std::string kRequestPrefix("{\"kids\":[");
-    const std::string kRequestSuffix("],\"type\":\"temporary\"}");
+    const std::string kTemporarySession("],\"type\":\"temporary\"}");
+    const std::string kPersistentSession("],\"type\":\"persistent-license\"}");
 
     std::string request(kRequestPrefix);
     std::string encodedId;
@@ -147,7 +154,12 @@
         request.append(encodedId);
         request.push_back('\"');
     }
-    request.append(kRequestSuffix);
+    if (keyType == V1_0::KeyType::STREAMING) {
+        request.append(kTemporarySession);
+    } else if (keyType == V1_0::KeyType::OFFLINE ||
+                   keyType == V1_0::KeyType::RELEASE) {
+            request.append(kPersistentSession);
+    }
 
     // Android's Base64 encoder produces padding. EME forbids padding.
     const char kBase64Padding = '=';
@@ -157,7 +169,7 @@
 }
 
 } // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
 } // namespace drm
 } // namespace hardware
 } // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/JsonWebKey.cpp b/drm/mediadrm/plugins/clearkey/hidl/JsonWebKey.cpp
index cccb41e..d93777d 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/JsonWebKey.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/JsonWebKey.cpp
@@ -22,18 +22,21 @@
 #include "Base64.h"
 
 namespace {
+const std::string kBase64Padding("=");
 const std::string kKeysTag("keys");
 const std::string kKeyTypeTag("kty");
-const std::string kSymmetricKeyValue("oct");
 const std::string kKeyTag("k");
 const std::string kKeyIdTag("kid");
-const std::string kBase64Padding("=");
+const std::string kMediaSessionType("type");
+const std::string kPersistentLicenseSession("persistent-license");
+const std::string kSymmetricKeyValue("oct");
+const std::string kTemporaryLicenseSession("temporary");
 }
 
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
 JsonWebKey::JsonWebKey() {
@@ -268,7 +271,7 @@
 }
 
 } // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
 } // namespace drm
 } // namespace hardware
 } // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/MemoryFileSystem.cpp b/drm/mediadrm/plugins/clearkey/hidl/MemoryFileSystem.cpp
new file mode 100644
index 0000000..2dcd00f
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/MemoryFileSystem.cpp
@@ -0,0 +1,92 @@
+// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
+// source code may only be used and distributed under the Widevine Master
+// License Agreement.
+
+#include <utils/Log.h>
+#include <string>
+
+#include "MemoryFileSystem.h"
+#include "Utils.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_2 {
+namespace clearkey {
+
+std::string MemoryFileSystem::GetFileName(const std::string& path) {
+    size_t index = path.find_last_of("/");
+    if (index != std::string::npos) {
+        return path.substr(index+1);
+    } else {
+        return path;
+    }
+}
+
+bool MemoryFileSystem::FileExists(const std::string& fileName) const {
+    auto result = mMemoryFileSystem.find(fileName);
+    return result != mMemoryFileSystem.end();
+}
+
+ssize_t MemoryFileSystem::GetFileSize(const std::string& fileName) const {
+    auto result = mMemoryFileSystem.find(fileName);
+    if (result != mMemoryFileSystem.end()) {
+        return static_cast<ssize_t>(result->second.getFileSize());
+    } else {
+        ALOGE("Failed to get size for %s", fileName.c_str());
+        return -1;
+    }
+}
+
+std::vector<std::string> MemoryFileSystem::ListFiles() const {
+    std::vector<std::string> list;
+    for (const auto& filename : mMemoryFileSystem) {
+        list.push_back(filename.first);
+    }
+    return list;
+}
+
+size_t MemoryFileSystem::Read(const std::string& path, std::string* buffer) {
+    std::string key = GetFileName(path);
+    auto result = mMemoryFileSystem.find(key);
+    if (result != mMemoryFileSystem.end()) {
+        std::string serializedHashFile = result->second.getContent();
+        buffer->assign(serializedHashFile);
+        return buffer->size();
+    } else {
+        ALOGE("Failed to read from %s", path.c_str());
+        return -1;
+    }
+}
+
+size_t MemoryFileSystem::Write(const std::string& path, const MemoryFile& memoryFile) {
+    std::string key = GetFileName(path);
+    auto result = mMemoryFileSystem.find(key);
+    if (result != mMemoryFileSystem.end()) {
+        mMemoryFileSystem.erase(key);
+    }
+    mMemoryFileSystem.insert(std::pair<std::string, MemoryFile>(key, memoryFile));
+    return memoryFile.getFileSize();
+}
+
+bool MemoryFileSystem::RemoveFile(const std::string& fileName) {
+    auto result = mMemoryFileSystem.find(fileName);
+    if (result != mMemoryFileSystem.end()) {
+        mMemoryFileSystem.erase(result);
+        return true;
+    } else {
+        ALOGE("Cannot find license to remove: %s", fileName.c_str());
+        return false;
+    }
+}
+
+bool MemoryFileSystem::RemoveAllFiles() {
+    mMemoryFileSystem.clear();
+    return mMemoryFileSystem.empty();
+}
+
+} // namespace clearkey
+} // namespace V1_2
+} // namespace drm
+} // namespace hardware
+} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/Session.cpp b/drm/mediadrm/plugins/clearkey/hidl/Session.cpp
index 07c9269..a9d7016 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/Session.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/Session.cpp
@@ -28,7 +28,7 @@
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
 using ::android::hardware::drm::V1_0::KeyValue;
@@ -42,9 +42,10 @@
 Status Session::getKeyRequest(
         const std::vector<uint8_t>& initData,
         const std::string& mimeType,
+        V1_0::KeyType keyType,
         std::vector<uint8_t>* keyRequest) const {
     InitDataParser parser;
-    return parser.parse(initData, mimeType, keyRequest);
+    return parser.parse(initData, mimeType, keyType, keyRequest);
 }
 
 Status Session::provideKeyResponse(const std::vector<uint8_t>& response) {
@@ -67,29 +68,34 @@
     }
 }
 
-Status Session::decrypt(
+Status_V1_2 Session::decrypt(
         const KeyId keyId, const Iv iv, const uint8_t* srcPtr,
         uint8_t* destPtr, const std::vector<SubSample> subSamples,
         size_t* bytesDecryptedOut) {
     Mutex::Autolock lock(mMapLock);
 
+    if (getMockError() != Status_V1_2::OK) {
+        return getMockError();
+    }
+
     std::vector<uint8_t> keyIdVector;
     keyIdVector.clear();
     keyIdVector.insert(keyIdVector.end(), keyId, keyId + kBlockSize);
     std::map<std::vector<uint8_t>, std::vector<uint8_t> >::iterator itr;
     itr = mKeyMap.find(keyIdVector);
     if (itr == mKeyMap.end()) {
-        return Status::ERROR_DRM_NO_LICENSE;
+        return Status_V1_2::ERROR_DRM_NO_LICENSE;
     }
 
     AesCtrDecryptor decryptor;
-    return decryptor.decrypt(
+    Status status = decryptor.decrypt(
             itr->second /*key*/, iv, srcPtr, destPtr, subSamples,
             subSamples.size(), bytesDecryptedOut);
+    return static_cast<Status_V1_2>(status);
 }
 
 } // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
 } // namespace drm
 } // namespace hardware
 } // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/SessionLibrary.cpp b/drm/mediadrm/plugins/clearkey/hidl/SessionLibrary.cpp
index b4319e6..99fb30f 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/SessionLibrary.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/SessionLibrary.cpp
@@ -24,7 +24,7 @@
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
 using ::android::hardware::hidl_string;
@@ -59,7 +59,8 @@
 
     mSessions.insert(std::pair<std::vector<uint8_t>,
             sp<Session> >(sessionId, new Session(sessionId)));
-    std::map<std::vector<uint8_t>, sp<Session> >::iterator itr = mSessions.find(sessionId);
+    std::map<std::vector<uint8_t>, sp<Session> >::iterator itr =
+            mSessions.find(sessionId);
     if (itr != mSessions.end()) {
         return itr->second;
     } else {
@@ -70,7 +71,8 @@
 sp<Session> SessionLibrary::findSession(
         const std::vector<uint8_t>& sessionId) {
     Mutex::Autolock lock(mSessionsLock);
-    std::map<std::vector<uint8_t>, sp<Session> >::iterator itr = mSessions.find(sessionId);
+    std::map<std::vector<uint8_t>, sp<Session> >::iterator itr =
+            mSessions.find(sessionId);
     if (itr != mSessions.end()) {
         return itr->second;
     } else {
@@ -84,7 +86,7 @@
 }
 
 } // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
 } // namespace drm
 } // namespace hardware
 } // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.1-service.clearkey.rc b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.1-service.clearkey.rc
deleted file mode 100644
index ffe856a..0000000
--- a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.1-service.clearkey.rc
+++ /dev/null
@@ -1,6 +0,0 @@
-service vendor.drm-clearkey-hal-1-1 /vendor/bin/hw/android.hardware.drm@1.1-service.clearkey
-    class hal
-    user media
-    group media mediadrm
-    ioprio rt 4
-    writepid /dev/cpuset/foreground/tasks
diff --git a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service-lazy.clearkey.rc b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service-lazy.clearkey.rc
new file mode 100644
index 0000000..9afd3d7
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service-lazy.clearkey.rc
@@ -0,0 +1,14 @@
+service vendor.drm-clearkey-hal-1-2 /vendor/bin/hw/android.hardware.drm@1.2-service-lazy.clearkey
+    interface android.hardware.drm@1.0::ICryptoFactory clearkey
+    interface android.hardware.drm@1.0::IDrmFactory clearkey
+    interface android.hardware.drm@1.1::ICryptoFactory clearkey
+    interface android.hardware.drm@1.1::IDrmFactory clearkey
+    interface android.hardware.drm@1.2::ICryptoFactory clearkey
+    interface android.hardware.drm@1.2::IDrmFactory clearkey
+    disabled
+    oneshot
+    class hal
+    user media
+    group media mediadrm
+    ioprio rt 4
+    writepid /dev/cpuset/foreground/tasks
diff --git a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service.clearkey.rc b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service.clearkey.rc
new file mode 100644
index 0000000..5ba669d
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service.clearkey.rc
@@ -0,0 +1,12 @@
+service vendor.drm-clearkey-hal-1-2 /vendor/bin/hw/android.hardware.drm@1.2-service.clearkey
+    interface android.hardware.drm@1.0::ICryptoFactory clearkey
+    interface android.hardware.drm@1.0::IDrmFactory clearkey
+    interface android.hardware.drm@1.1::ICryptoFactory clearkey
+    interface android.hardware.drm@1.1::IDrmFactory clearkey
+    interface android.hardware.drm@1.2::ICryptoFactory clearkey
+    interface android.hardware.drm@1.2::IDrmFactory clearkey
+    class hal
+    user media
+    group media mediadrm
+    ioprio rt 4
+    writepid /dev/cpuset/foreground/tasks
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/AesCtrDecryptor.h b/drm/mediadrm/plugins/clearkey/hidl/include/AesCtrDecryptor.h
index 0c7ef20..721f4c0 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/AesCtrDecryptor.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/AesCtrDecryptor.h
@@ -22,7 +22,7 @@
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
 using ::android::hardware::drm::V1_0::Status;
@@ -42,7 +42,7 @@
 };
 
 } // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
 } // namespace drm
 } // namespace hardware
 } // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/Base64.h b/drm/mediadrm/plugins/clearkey/hidl/include/Base64.h
index 4a385bd..ec30cc1 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/Base64.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/Base64.h
@@ -25,7 +25,7 @@
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
 using ::android::sp;
@@ -38,7 +38,7 @@
 void encodeBase64Url(const void *data, size_t size, std::string *out);
 
 } // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
 } // namespace drm
 } // namespace hardware
 } // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/Buffer.h b/drm/mediadrm/plugins/clearkey/hidl/include/Buffer.h
index 5bbb28a..c497e37 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/Buffer.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/Buffer.h
@@ -25,7 +25,7 @@
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
 using ::android::sp;
@@ -54,7 +54,7 @@
 };
 
 } // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
 } // namespace drm
 } // namespace hardware
 } // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyDrmProperties.h b/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyDrmProperties.h
index d65b25c..b83ce69 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyDrmProperties.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyDrmProperties.h
@@ -22,30 +22,40 @@
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
 static const std::string kVendorKey("vendor");
 static const std::string kVendorValue("Google");
 static const std::string kVersionKey("version");
-static const std::string kVersionValue("1.1");
+static const std::string kVersionValue("1.2");
 static const std::string kPluginDescriptionKey("description");
 static const std::string kPluginDescriptionValue("ClearKey CDM");
 static const std::string kAlgorithmsKey("algorithms");
 static const std::string kAlgorithmsValue("");
 static const std::string kListenerTestSupportKey("listenerTestSupport");
 static const std::string kListenerTestSupportValue("true");
+static const std::string kDrmErrorTestKey("drmErrorTest");
+static const std::string kDrmErrorTestValue("");
+static const std::string kResourceContentionValue("resourceContention");
+static const std::string kLostStateValue("lostState");
+static const std::string kFrameTooLargeValue("frameTooLarge");
+static const std::string kInvalidStateValue("invalidState");
 
 static const std::string kDeviceIdKey("deviceId");
 static const uint8_t kTestDeviceIdData[] =
         {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
          0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
+
+// settable byte array property
+static const std::string kClientIdKey("clientId");
+
 // TODO stub out metrics for nw
 static const std::string kMetricsKey("metrics");
 static const uint8_t kMetricsData[] = { 0 };
 
 } // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
 } // namespace drm
 } // namespace hardware
 } // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyTypes.h b/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyTypes.h
index 46cb5e4..03c434e 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyTypes.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyTypes.h
@@ -17,17 +17,18 @@
 #ifndef CLEARKEY_MACROS_H_
 #define CLEARKEY_MACROS_H_
 
-#include <android/hardware/drm/1.0/types.h>
+#include <android/hardware/drm/1.2/types.h>
 
 #include <map>
 
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
 using ::android::hardware::drm::V1_0::KeyValue;
+using ::android::hardware::drm::V1_1::SecurityLevel;
 using ::android::hardware::hidl_vec;
 
 const uint8_t kBlockSize = 16; //AES_BLOCK_SIZE;
@@ -47,7 +48,7 @@
   void operator=(const TypeName&) = delete;
 
 } // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
 } // namespace drm
 } // namespace hardware
 } // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/CreatePluginFactories.h b/drm/mediadrm/plugins/clearkey/hidl/include/CreatePluginFactories.h
index 9952027..6368f3d 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/CreatePluginFactories.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/CreatePluginFactories.h
@@ -17,17 +17,17 @@
 #ifndef CLEARKEY_CREATE_PLUGIN_FACTORIES_H_
 #define CLEARKEY_CREATE_PLUGIN_FACTORIES_H_
 
-#include <android/hardware/drm/1.1/ICryptoFactory.h>
-#include <android/hardware/drm/1.1/IDrmFactory.h>
+#include <android/hardware/drm/1.2/ICryptoFactory.h>
+#include <android/hardware/drm/1.2/IDrmFactory.h>
 
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
-using ::android::hardware::drm::V1_1::ICryptoFactory;
-using ::android::hardware::drm::V1_1::IDrmFactory;
+using ::android::hardware::drm::V1_2::ICryptoFactory;
+using ::android::hardware::drm::V1_2::IDrmFactory;
 
 extern "C" {
     IDrmFactory* createDrmFactory();
@@ -35,7 +35,7 @@
 }
 
 }  // namespace clearkey
-}  // namespace V1_1
+}  // namespace V1_2
 }  // namespace drm
 }  // namespace hardware
 }  // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/CryptoFactory.h b/drm/mediadrm/plugins/clearkey/hidl/include/CryptoFactory.h
index 175ab76..203bb2d 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/CryptoFactory.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/CryptoFactory.h
@@ -18,17 +18,17 @@
 #define CLEARKEY_CRYPTO_FACTORY_H_
 
 #include <android/hardware/drm/1.0/ICryptoPlugin.h>
-#include <android/hardware/drm/1.1/ICryptoFactory.h>
+#include <android/hardware/drm/1.2/ICryptoFactory.h>
 
 #include "ClearKeyTypes.h"
 
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
-using ::android::hardware::drm::V1_1::ICryptoFactory;
+using ::android::hardware::drm::V1_2::ICryptoFactory;
 using ::android::hardware::drm::V1_0::ICryptoPlugin;
 using ::android::hardware::hidl_array;
 using ::android::hardware::hidl_string;
@@ -52,7 +52,7 @@
 };
 
 } // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
 } // namespace drm
 } // namespace hardware
 } // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h b/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h
index 6a73806..8680f0c 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h
@@ -17,7 +17,7 @@
 #ifndef CLEARKEY_CRYPTO_PLUGIN_H_
 #define CLEARKEY_CRYPTO_PLUGIN_H_
 
-#include <android/hardware/drm/1.0/ICryptoPlugin.h>
+#include <android/hardware/drm/1.2/ICryptoPlugin.h>
 #include <android/hidl/memory/1.0/IMemory.h>
 
 #include "ClearKeyTypes.h"
@@ -32,16 +32,17 @@
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
-using ::android::hardware::drm::V1_0::DestinationBuffer;
-using ::android::hardware::drm::V1_0::ICryptoPlugin;
-using ::android::hardware::drm::V1_0::Mode;
-using ::android::hardware::drm::V1_0::Pattern;
-using ::android::hardware::drm::V1_0::SharedBuffer;
-using ::android::hardware::drm::V1_0::Status;
-using ::android::hardware::drm::V1_0::SubSample;
+namespace drm = ::android::hardware::drm;
+using drm::V1_0::DestinationBuffer;
+using drm::V1_0::Mode;
+using drm::V1_0::Pattern;
+using drm::V1_0::SharedBuffer;
+using drm::V1_0::Status;
+using drm::V1_0::SubSample;
+
 using ::android::hardware::hidl_array;
 using ::android::hardware::hidl_memory;
 using ::android::hardware::hidl_string;
@@ -51,7 +52,9 @@
 using ::android::hidl::memory::V1_0::IMemory;
 using ::android::sp;
 
-struct CryptoPlugin : public ICryptoPlugin {
+typedef drm::V1_2::Status Status_V1_2;
+
+struct CryptoPlugin : public drm::V1_2::ICryptoPlugin {
     explicit CryptoPlugin(const hidl_vec<uint8_t>& sessionId) {
         mInitStatus = setMediaDrmSession(sessionId);
     }
@@ -80,6 +83,18 @@
             const DestinationBuffer& destination,
             decrypt_cb _hidl_cb);
 
+    Return<void> decrypt_1_2(
+            bool secure,
+            const hidl_array<uint8_t, KEY_ID_SIZE>& keyId,
+            const hidl_array<uint8_t, KEY_IV_SIZE>& iv,
+            Mode mode,
+            const Pattern& pattern,
+            const hidl_vec<SubSample>& subSamples,
+            const SharedBuffer& source,
+            uint64_t offset,
+            const DestinationBuffer& destination,
+            decrypt_1_2_cb _hidl_cb);
+
     Return<void> setSharedBufferBase(const hidl_memory& base,
             uint32_t bufferId);
 
@@ -96,7 +111,7 @@
 };
 
 } // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
 } // namespace drm
 } // namespace hardware
 } // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/DeviceFiles.h b/drm/mediadrm/plugins/clearkey/hidl/include/DeviceFiles.h
new file mode 100644
index 0000000..554ae59
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/DeviceFiles.h
@@ -0,0 +1,71 @@
+// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
+// source code may only be used and distributed under the Widevine Master
+// License Agreement.
+//
+#ifndef CLEARKEY_DEVICE_FILES_H_
+#define CLEARKEY_DEVICE_FILES_H_
+
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include "protos/DeviceFiles.pb.h"
+#include "ClearKeyTypes.h"
+#include "MemoryFileSystem.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_2 {
+namespace clearkey {
+
+class DeviceFiles {
+ public:
+    typedef enum {
+        kLicenseStateUnknown,
+        kLicenseStateActive,
+        kLicenseStateReleasing,
+    } LicenseState;
+
+    DeviceFiles() {};
+    virtual ~DeviceFiles() {};
+
+    virtual bool StoreLicense(const std::string& keySetId, LicenseState state,
+            const std::string& keyResponse);
+
+    virtual bool RetrieveLicense(
+            const std::string& key_set_id, LicenseState* state, std::string* offlineLicense);
+
+    virtual bool LicenseExists(const std::string& keySetId);
+
+    virtual std::vector<std::string> ListLicenses() const;
+
+    virtual bool DeleteLicense(const std::string& keySetId);
+
+    virtual bool DeleteAllLicenses();
+
+ private:
+    bool FileExists(const std::string& path) const;
+    ssize_t GetFileSize(const std::string& fileName) const;
+    bool RemoveFile(const std::string& fileName);
+
+    bool RetrieveHashedFile(const std::string& fileName, OfflineFile* deSerializedFile);
+    bool StoreFileRaw(const std::string& fileName, const std::string& serializedFile);
+    bool StoreFileWithHash(const std::string& fileName, const std::string& serializedFile);
+
+    MemoryFileSystem mFileHandle;
+
+    CLEARKEY_DISALLOW_COPY_AND_ASSIGN(DeviceFiles);
+};
+
+} // namespace clearkey
+} // namespace V1_2
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif  // CLEARKEY_DEVICE_FILES_H_
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/DrmFactory.h b/drm/mediadrm/plugins/clearkey/hidl/include/DrmFactory.h
index 6f58195..4ca856d 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/DrmFactory.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/DrmFactory.h
@@ -17,15 +17,15 @@
 #ifndef CLEARKEY_DRM_FACTORY_H_
 #define CLEARKEY_DRM_FACTORY_H_
 
-#include <android/hardware/drm/1.1/IDrmPlugin.h>
-#include <android/hardware/drm/1.1/IDrmFactory.h>
+#include <android/hardware/drm/1.2/IDrmPlugin.h>
+#include <android/hardware/drm/1.2/IDrmFactory.h>
 
 #include "ClearKeyTypes.h"
 
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
 using ::android::hardware::hidl_array;
@@ -39,6 +39,10 @@
     Return<bool> isCryptoSchemeSupported(const hidl_array<uint8_t, 16>& uuid)
             override;
 
+    Return<bool> isCryptoSchemeSupported_1_2(const hidl_array<uint8_t, 16>& uuid,
+                                             const hidl_string& mimeType,
+                                             SecurityLevel level) override;
+
     Return<bool> isContentTypeSupported(const hidl_string &mimeType)
             override;
 
@@ -52,7 +56,7 @@
 };
 
 } // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
 } // namespace drm
 } // namespace hardware
 } // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h b/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
index fb0695a..f294d4d 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
@@ -17,32 +17,42 @@
 #ifndef CLEARKEY_DRM_PLUGIN_H_
 #define CLEARKEY_DRM_PLUGIN_H_
 
-#include <android/hardware/drm/1.1/IDrmPlugin.h>
+#include <android/hardware/drm/1.2/IDrmPlugin.h>
+#include <android/hardware/drm/1.2/IDrmPluginListener.h>
 
-#include <stdio.h>
 #include <map>
+#include <stdio.h>
 
+#include <utils/List.h>
+
+#include "DeviceFiles.h"
 #include "SessionLibrary.h"
 #include "Utils.h"
 
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
-using ::android::hardware::drm::V1_0::EventType;
-using ::android::hardware::drm::V1_0::IDrmPluginListener;
-using ::android::hardware::drm::V1_0::KeyStatus;
-using ::android::hardware::drm::V1_0::KeyType;
-using ::android::hardware::drm::V1_0::KeyValue;
-using ::android::hardware::drm::V1_0::SecureStop;
-using ::android::hardware::drm::V1_0::SecureStopId;
-using ::android::hardware::drm::V1_0::SessionId;
-using ::android::hardware::drm::V1_0::Status;
-using ::android::hardware::drm::V1_1::DrmMetricGroup;
-using ::android::hardware::drm::V1_1::IDrmPlugin;
-using ::android::hardware::drm::V1_1::KeyRequestType;
+namespace drm = ::android::hardware::drm;
+using drm::V1_0::EventType;
+using drm::V1_0::IDrmPluginListener;
+using drm::V1_0::KeyRequestType;
+using drm::V1_0::KeyStatus;
+using drm::V1_0::KeyType;
+using drm::V1_0::KeyValue;
+using drm::V1_0::SecureStop;
+using drm::V1_0::SecureStopId;
+using drm::V1_0::SessionId;
+using drm::V1_0::Status;
+using drm::V1_1::DrmMetricGroup;
+using drm::V1_1::HdcpLevel;
+using drm::V1_1::SecureStopRelease;
+using drm::V1_1::SecurityLevel;
+using drm::V1_2::IDrmPlugin;
+using drm::V1_2::KeySetId;
+using drm::V1_2::OfflineLicenseState;
 
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
@@ -50,10 +60,16 @@
 using ::android::hardware::Void;
 using ::android::sp;
 
+typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
+typedef drm::V1_2::IDrmPluginListener IDrmPluginListener_V1_2;
+typedef drm::V1_2::KeyStatus KeyStatus_V1_2;
+typedef drm::V1_2::Status Status_V1_2;
+typedef drm::V1_2::HdcpLevel HdcpLevel_V1_2;
+
 struct DrmPlugin : public IDrmPlugin {
     explicit DrmPlugin(SessionLibrary* sessionLibrary);
 
-    virtual ~DrmPlugin() {}
+    virtual ~DrmPlugin() { mFileHandle.DeleteAllLicenses(); }
 
     Return<void> openSession(openSession_cb _hidl_cb) override;
     Return<void> openSession_1_1(SecurityLevel securityLevel,
@@ -77,6 +93,14 @@
         const hidl_vec<KeyValue>& optionalParameters,
         getKeyRequest_1_1_cb _hidl_cb) override;
 
+    Return<void> getKeyRequest_1_2(
+        const hidl_vec<uint8_t>& scope,
+        const hidl_vec<uint8_t>& initData,
+        const hidl_string& mimeType,
+        KeyType keyType,
+        const hidl_vec<KeyValue>& optionalParameters,
+        getKeyRequest_1_2_cb _hidl_cb) override;
+
     Return<void> provideKeyResponse(
         const hidl_vec<uint8_t>& scope,
         const hidl_vec<uint8_t>& response,
@@ -91,13 +115,7 @@
 
     Return<Status> restoreKeys(
         const hidl_vec<uint8_t>& sessionId,
-        const hidl_vec<uint8_t>& keySetId) {
-
-        if (sessionId.size() == 0 || keySetId.size() == 0) {
-            return Status::BAD_VALUE;
-        }
-        return Status::ERROR_DRM_CANNOT_HANDLE;
-    }
+        const hidl_vec<uint8_t>& keySetId) override;
 
     Return<void> queryKeyStatus(
         const hidl_vec<uint8_t>& sessionId,
@@ -115,6 +133,18 @@
         return Void();
     }
 
+    Return<void> getProvisionRequest_1_2(
+        const hidl_string& certificateType,
+        const hidl_string& certificateAuthority,
+        getProvisionRequest_1_2_cb _hidl_cb) {
+        UNUSED(certificateType);
+        UNUSED(certificateAuthority);
+
+        hidl_string defaultUrl;
+        _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, hidl_vec<uint8_t>(), defaultUrl);
+        return Void();
+    }
+
     Return<void> provideProvisionResponse(
         const hidl_vec<uint8_t>& response,
         provideProvisionResponse_cb _hidl_cb) {
@@ -134,6 +164,13 @@
         return Void();
     }
 
+    Return<void> getHdcpLevels_1_2(getHdcpLevels_1_2_cb _hidl_cb) {
+        HdcpLevel_V1_2 connectedLevel = HdcpLevel_V1_2::HDCP_NONE;
+        HdcpLevel_V1_2 maxLevel = HdcpLevel_V1_2::HDCP_NO_OUTPUT;
+        _hidl_cb(Status_V1_2::OK, connectedLevel, maxLevel);
+        return Void();
+    }
+
     Return<void> getNumberOfSessions(getNumberOfSessions_cb _hidl_cb) override;
 
     Return<void> getSecurityLevel(const hidl_vec<uint8_t>& sessionId,
@@ -141,6 +178,13 @@
 
     Return<void> getMetrics(getMetrics_cb _hidl_cb) override;
 
+    Return<void> getOfflineLicenseKeySetIds(getOfflineLicenseKeySetIds_cb _hidl_cb) override;
+
+    Return<Status> removeOfflineLicense(const KeySetId &keySetId) override;
+
+    Return<void> getOfflineLicenseState(const KeySetId &keySetId,
+            getOfflineLicenseState_cb _hidl_cb) override;
+
     Return<void> getPropertyString(
         const hidl_string& name,
         getPropertyString_cb _hidl_cb) override;
@@ -248,12 +292,17 @@
 
     Return<void> setListener(const sp<IDrmPluginListener>& listener) {
         mListener = listener;
+        mListenerV1_2 = IDrmPluginListener_V1_2::castFrom(listener);
         return Void();
     };
 
-    Return<void> sendEvent(EventType eventType, const hidl_vec<uint8_t>& sessionId,
+    Return<void> sendEvent(
+            EventType eventType,
+            const hidl_vec<uint8_t>& sessionId,
             const hidl_vec<uint8_t>& data) {
-        if (mListener != NULL) {
+        if (mListenerV1_2 != NULL) {
+            mListenerV1_2->sendEvent(eventType, sessionId, data);
+        } else if (mListener != NULL) {
             mListener->sendEvent(eventType, sessionId, data);
         } else {
             ALOGE("Null event listener, event not sent");
@@ -261,8 +310,12 @@
         return Void();
     }
 
-    Return<void> sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId, int64_t expiryTimeInMS) {
-        if (mListener != NULL) {
+    Return<void> sendExpirationUpdate(
+            const hidl_vec<uint8_t>& sessionId,
+            int64_t expiryTimeInMS) {
+        if (mListenerV1_2 != NULL) {
+            mListenerV1_2->sendExpirationUpdate(sessionId, expiryTimeInMS);
+        } else if (mListener != NULL) {
             mListener->sendExpirationUpdate(sessionId, expiryTimeInMS);
         } else {
             ALOGE("Null event listener, event not sent");
@@ -270,9 +323,12 @@
         return Void();
     }
 
-    Return<void> sendKeysChange(const hidl_vec<uint8_t>& sessionId,
+    Return<void> sendKeysChange(
+            const hidl_vec<uint8_t>& sessionId,
             const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
-        if (mListener != NULL) {
+        if (mListenerV1_2 != NULL) {
+            mListenerV1_2->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
+        } else if (mListener != NULL) {
             mListener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
         } else {
             ALOGE("Null event listener, event not sent");
@@ -280,6 +336,23 @@
         return Void();
     }
 
+    Return<void> sendKeysChange_1_2(
+            const hidl_vec<uint8_t>& sessionId,
+            const hidl_vec<KeyStatus_V1_2>& keyStatusList, bool hasNewUsableKey) {
+        if (mListenerV1_2 != NULL) {
+            mListenerV1_2->sendKeysChange_1_2(sessionId, keyStatusList, hasNewUsableKey);
+        }
+        return Void();
+    }
+
+    Return<void> sendSessionLostState(
+            const hidl_vec<uint8_t>& sessionId) {
+        if (mListenerV1_2 != NULL) {
+            mListenerV1_2->sendSessionLostState(sessionId);
+        }
+        return Void();
+    }
+
     Return<void> getSecureStops(getSecureStops_cb _hidl_cb);
 
     Return<void> getSecureStop(const hidl_vec<uint8_t>& secureStopId,
@@ -300,18 +373,19 @@
 private:
     void initProperties();
     void installSecureStop(const hidl_vec<uint8_t>& sessionId);
+    bool makeKeySetId(std::string* keySetId);
     void setPlayPolicy();
 
     Return<Status> setSecurityLevel(const hidl_vec<uint8_t>& sessionId,
             SecurityLevel level);
 
-    Status getKeyRequestCommon(const hidl_vec<uint8_t>& scope,
+    Status_V1_2 getKeyRequestCommon(const hidl_vec<uint8_t>& scope,
             const hidl_vec<uint8_t>& initData,
             const hidl_string& mimeType,
             KeyType keyType,
             const hidl_vec<KeyValue>& optionalParameters,
             std::vector<uint8_t> *request,
-            KeyRequestType *getKeyRequestType,
+            KeyRequestType_V1_1 *getKeyRequestType,
             std::string *defaultUrl);
 
     struct ClearkeySecureStop {
@@ -323,19 +397,31 @@
     std::vector<KeyValue> mPlayPolicy;
     std::map<std::string, std::string> mStringProperties;
     std::map<std::string, std::vector<uint8_t> > mByteArrayProperties;
+    std::map<std::string, std::vector<uint8_t> > mReleaseKeysMap;
     std::map<std::vector<uint8_t>, SecurityLevel> mSecurityLevel;
     sp<IDrmPluginListener> mListener;
+    sp<IDrmPluginListener_V1_2> mListenerV1_2;
     SessionLibrary *mSessionLibrary;
     int64_t mOpenSessionOkCount;
     int64_t mCloseSessionOkCount;
     int64_t mCloseSessionNotOpenedCount;
     uint32_t mNextSecureStopId;
 
+    // set by property to mock error scenarios
+    Status_V1_2 mMockError;
+
+    void processMockError(const sp<Session> &session) {
+        session->setMockError(mMockError);
+        mMockError = Status_V1_2::OK;
+    }
+
+    DeviceFiles mFileHandle;
+
     CLEARKEY_DISALLOW_COPY_AND_ASSIGN_AND_NEW(DrmPlugin);
 };
 
 } // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
 } // namespace drm
 } // namespace hardware
 } // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/InitDataParser.h b/drm/mediadrm/plugins/clearkey/hidl/include/InitDataParser.h
index 3189c4a..889f511 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/InitDataParser.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/InitDataParser.h
@@ -24,7 +24,7 @@
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
 using ::android::hardware::drm::V1_0::Status;
@@ -34,7 +34,8 @@
     InitDataParser() {}
 
     Status parse(const std::vector<uint8_t>& initData,
-            const std::string& type,
+            const std::string& mimeType,
+            V1_0::KeyType keyType,
             std::vector<uint8_t>* licenseRequest);
 
 private:
@@ -43,12 +44,12 @@
     Status parsePssh(const std::vector<uint8_t>& initData,
             std::vector<const uint8_t*>* keyIds);
 
-    std::string generateRequest(
+    std::string generateRequest(V1_0::KeyType keyType,
             const std::vector<const uint8_t*>& keyIds);
 };
 
 } // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
 } // namespace drm
 } // namespace hardware
 } // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/JsonWebKey.h b/drm/mediadrm/plugins/clearkey/hidl/include/JsonWebKey.h
index 4ab034c..e57470c 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/JsonWebKey.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/JsonWebKey.h
@@ -23,7 +23,7 @@
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
 class JsonWebKey {
@@ -54,7 +54,7 @@
 };
 
 } // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
 } // namespace drm
 } // namespace hardware
 } // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/MemoryFileSystem.h b/drm/mediadrm/plugins/clearkey/hidl/include/MemoryFileSystem.h
new file mode 100644
index 0000000..bcd9fd6
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/MemoryFileSystem.h
@@ -0,0 +1,68 @@
+// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
+// source code may only be used and distributed under the Widevine Master
+// License Agreement.
+//
+#ifndef CLEARKEY_MEMORY_FILE_SYSTEM_H_
+#define CLEARKEY_MEMORY_FILE_SYSTEM_H_
+
+#include <map>
+#include <string>
+
+#include "ClearKeyTypes.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_2 {
+namespace clearkey {
+
+// Using android file system requires clearkey plugin to update
+// its sepolicy. However, we are unable to update sepolicy for
+// older vendor partitions. To provide backward compatibility,
+// clearkey plugin implements a very simple file system in memory.
+// This memory file system does not support directory structure.
+class MemoryFileSystem {
+ public:
+    struct MemoryFile {
+        std::string fileName;  // excludes path
+        std::string content;
+        size_t fileSize;
+
+        std::string getContent() const { return content; }
+        size_t getFileSize() const { return fileSize; }
+        void setContent(const std::string& file) { content = file; }
+        void setFileName(const std::string& name) { fileName = name; }
+        void setFileSize(size_t size) {
+            content.resize(size); fileSize = size;
+        }
+    };
+
+    MemoryFileSystem() {};
+    virtual ~MemoryFileSystem() {};
+
+    bool FileExists(const std::string& fileName) const;
+    ssize_t GetFileSize(const std::string& fileName) const;
+    std::vector<std::string> ListFiles() const;
+    size_t Read(const std::string& pathName, std::string* buffer);
+    bool RemoveAllFiles();
+    bool RemoveFile(const std::string& fileName);
+    size_t Write(const std::string& pathName, const MemoryFile& memoryFile);
+
+ private:
+    // License file name is made up of a unique keySetId, therefore,
+    // the filename can be used as the key to locate licenses in the
+    // memory file system.
+    std::map<std::string, MemoryFile> mMemoryFileSystem;
+
+    std::string GetFileName(const std::string& path);
+
+    CLEARKEY_DISALLOW_COPY_AND_ASSIGN(MemoryFileSystem);
+};
+
+} // namespace clearkey
+} // namespace V1_2
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif  // CLEARKEY_MEMORY_FILE_SYSTEM_H_
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/Session.h b/drm/mediadrm/plugins/clearkey/hidl/include/Session.h
index cddfca5..a159e5a 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/Session.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/Session.h
@@ -27,43 +27,53 @@
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
-using ::android::hardware::drm::V1_0::Status;
-using ::android::hardware::drm::V1_0::SubSample;
+namespace drm = ::android::hardware::drm;
+using drm::V1_0::Status;
+using drm::V1_0::SubSample;
+
+typedef drm::V1_2::Status Status_V1_2;
 
 class Session : public RefBase {
 public:
     explicit Session(const std::vector<uint8_t>& sessionId)
-            : mSessionId(sessionId) {}
+        : mSessionId(sessionId), mMockError(Status_V1_2::OK) {}
     virtual ~Session() {}
 
     const std::vector<uint8_t>& sessionId() const { return mSessionId; }
 
     Status getKeyRequest(
-            const std::vector<uint8_t>& mimeType,
-            const std::string& initDataType,
+            const std::vector<uint8_t>& initDataType,
+            const std::string& mimeType,
+            V1_0::KeyType keyType,
             std::vector<uint8_t>* keyRequest) const;
 
     Status provideKeyResponse(
             const std::vector<uint8_t>& response);
 
-    Status decrypt(
+    Status_V1_2 decrypt(
             const KeyId keyId, const Iv iv, const uint8_t* srcPtr,
             uint8_t* dstPtr, const std::vector<SubSample> subSamples,
             size_t* bytesDecryptedOut);
 
+    void setMockError(Status_V1_2 error) {mMockError = error;}
+    Status_V1_2 getMockError() const {return mMockError;}
+
 private:
     CLEARKEY_DISALLOW_COPY_AND_ASSIGN(Session);
 
     const std::vector<uint8_t> mSessionId;
     KeyMap mKeyMap;
     Mutex mMapLock;
+
+    // For mocking error return scenarios
+    Status_V1_2 mMockError;
 };
 
 } // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
 } // namespace drm
 } // namespace hardware
 } // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/SessionLibrary.h b/drm/mediadrm/plugins/clearkey/hidl/include/SessionLibrary.h
index 326a0c1..1e567b8 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/SessionLibrary.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/SessionLibrary.h
@@ -26,7 +26,7 @@
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
 using ::android::sp;
@@ -58,7 +58,7 @@
 };
 
 } // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
 } // namespace drm
 } // namespace hardware
 } // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/TypeConvert.h b/drm/mediadrm/plugins/clearkey/hidl/include/TypeConvert.h
index cc06329..b0f8607 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/TypeConvert.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/TypeConvert.h
@@ -24,7 +24,7 @@
 namespace android {
 namespace hardware {
 namespace drm {
-namespace V1_1 {
+namespace V1_2 {
 namespace clearkey {
 
 using ::android::hardware::hidl_array;
@@ -68,8 +68,19 @@
     return vec;
 }
 
+inline Status toStatus_1_0(Status_V1_2 status) {
+  switch (status) {
+    case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
+    case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
+    case Status_V1_2::ERROR_DRM_SESSION_LOST_STATE:
+      return Status::ERROR_DRM_UNKNOWN;
+    default:
+      return static_cast<Status>(status);
+  }
+}
+
 }  // namespace clearkey
-}  // namespace V1_1
+}  // namespace V1_2
 }  // namespace drm
 }  // namespace hardware
 }  // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/protos/DeviceFiles.proto b/drm/mediadrm/plugins/clearkey/hidl/protos/DeviceFiles.proto
new file mode 100644
index 0000000..3e11f0b
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/protos/DeviceFiles.proto
@@ -0,0 +1,47 @@
+// ----------------------------------------------------------------------------
+// device_files.proto
+// ----------------------------------------------------------------------------
+// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
+// source code may only be used and distributed under the Widevine Master
+// License Agreement.
+//
+// Description:
+//   Format of various files stored at the device.
+//
+syntax = "proto2";
+
+package android.hardware.drm.V1_2.clearkey;
+
+// need this if we are using libprotobuf-cpp-2.3.0-lite
+option optimize_for = LITE_RUNTIME;
+
+message License {
+  enum LicenseState {
+    ACTIVE = 1;
+    RELEASING = 2;
+  }
+
+  optional LicenseState state = 1;
+  optional bytes license = 2;
+}
+
+message OfflineFile {
+  enum FileType {
+    LICENSE = 1;
+  }
+
+  enum FileVersion {
+    VERSION_1 = 1;
+  }
+
+  optional FileType type = 1;
+  optional FileVersion version = 2 [default = VERSION_1];
+  optional License license = 3;
+
+}
+
+message HashedFile {
+  optional bytes file = 1;
+  // A raw (not hex-encoded) SHA256, taken over the bytes of 'file'.
+  optional bytes hash = 2;
+}
diff --git a/drm/mediadrm/plugins/clearkey/hidl/service.cpp b/drm/mediadrm/plugins/clearkey/hidl/service.cpp
index 6a97b72..b39ea01 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/service.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/service.cpp
@@ -13,32 +13,24 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#define LOG_TAG "android.hardware.drm@1.1-service.clearkey"
-
 #include <CryptoFactory.h>
 #include <DrmFactory.h>
 
 #include <android-base/logging.h>
 #include <binder/ProcessState.h>
+#include <hidl/HidlLazyUtils.h>
 #include <hidl/HidlTransportSupport.h>
 
 using ::android::hardware::configureRpcThreadpool;
 using ::android::hardware::joinRpcThreadpool;
 using ::android::sp;
 
-using android::hardware::drm::V1_1::ICryptoFactory;
-using android::hardware::drm::V1_1::IDrmFactory;
-using android::hardware::drm::V1_1::clearkey::CryptoFactory;
-using android::hardware::drm::V1_1::clearkey::DrmFactory;
-
+using android::hardware::drm::V1_2::ICryptoFactory;
+using android::hardware::drm::V1_2::IDrmFactory;
+using android::hardware::drm::V1_2::clearkey::CryptoFactory;
+using android::hardware::drm::V1_2::clearkey::DrmFactory;
 
 int main(int /* argc */, char** /* argv */) {
-    ALOGD("android.hardware.drm@1.1-service.clearkey starting...");
-
-    // The DRM HAL may communicate to other vendor components via
-    // /dev/vndbinder
-    android::ProcessState::initWithDriver("/dev/vndbinder");
-
     sp<IDrmFactory> drmFactory = new DrmFactory;
     sp<ICryptoFactory> cryptoFactory = new CryptoFactory;
 
diff --git a/drm/mediadrm/plugins/clearkey/hidl/serviceLazy.cpp b/drm/mediadrm/plugins/clearkey/hidl/serviceLazy.cpp
new file mode 100644
index 0000000..99fd883
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/serviceLazy.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <CryptoFactory.h>
+#include <DrmFactory.h>
+
+#include <android-base/logging.h>
+#include <binder/ProcessState.h>
+#include <hidl/HidlLazyUtils.h>
+#include <hidl/HidlTransportSupport.h>
+
+using ::android::hardware::configureRpcThreadpool;
+using ::android::hardware::joinRpcThreadpool;
+using ::android::sp;
+
+using android::hardware::drm::V1_2::ICryptoFactory;
+using android::hardware::drm::V1_2::IDrmFactory;
+using android::hardware::drm::V1_2::clearkey::CryptoFactory;
+using android::hardware::drm::V1_2::clearkey::DrmFactory;
+using android::hardware::LazyServiceRegistrar;
+
+int main(int /* argc */, char** /* argv */) {
+    sp<IDrmFactory> drmFactory = new DrmFactory;
+    sp<ICryptoFactory> cryptoFactory = new CryptoFactory;
+
+    configureRpcThreadpool(8, true /* callerWillJoin */);
+
+    // Setup hwbinder service
+    LazyServiceRegistrar serviceRegistrar;
+
+    // Setup hwbinder service
+    CHECK_EQ(serviceRegistrar.registerService(drmFactory, "clearkey"), android::NO_ERROR)
+        << "Failed to register Clearkey Factory HAL";
+    CHECK_EQ(serviceRegistrar.registerService(cryptoFactory, "clearkey"), android::NO_ERROR)
+        << "Failed to register Clearkey Crypto  HAL";
+
+    joinRpcThreadpool();
+}
diff --git a/include/common_time/ICommonClock.h b/include/common_time/ICommonClock.h
deleted file mode 100644
index d7073f1..0000000
--- a/include/common_time/ICommonClock.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_ICOMMONCLOCK_H
-#define ANDROID_ICOMMONCLOCK_H
-
-#include <stdint.h>
-#include <linux/socket.h>
-
-#include <binder/IInterface.h>
-#include <binder/IServiceManager.h>
-
-namespace android {
-
-class ICommonClockListener : public IInterface {
-  public:
-    DECLARE_META_INTERFACE(CommonClockListener);
-
-    virtual void onTimelineChanged(uint64_t timelineID) = 0;
-};
-
-class BnCommonClockListener : public BnInterface<ICommonClockListener> {
-  public:
-    virtual status_t onTransact(uint32_t code, const Parcel& data,
-                                Parcel* reply, uint32_t flags = 0);
-};
-
-class ICommonClock : public IInterface {
-  public:
-    DECLARE_META_INTERFACE(CommonClock);
-
-    // Name of the ICommonClock service registered with the service manager.
-    static const String16 kServiceName;
-
-    // a reserved invalid timeline ID
-    static const uint64_t kInvalidTimelineID;
-
-    // a reserved invalid error estimate
-    static const int32_t kErrorEstimateUnknown;
-
-    enum State {
-        // the device just came up and is trying to discover the master
-        STATE_INITIAL,
-
-        // the device is a client of a master
-        STATE_CLIENT,
-
-        // the device is acting as master
-        STATE_MASTER,
-
-        // the device has lost contact with its master and needs to participate
-        // in the election of a new master
-        STATE_RONIN,
-
-        // the device is waiting for announcement of the newly elected master
-        STATE_WAIT_FOR_ELECTION,
-    };
-
-    virtual status_t isCommonTimeValid(bool* valid, uint32_t* timelineID) = 0;
-    virtual status_t commonTimeToLocalTime(int64_t commonTime,
-                                           int64_t* localTime) = 0;
-    virtual status_t localTimeToCommonTime(int64_t localTime,
-                                           int64_t* commonTime) = 0;
-    virtual status_t getCommonTime(int64_t* commonTime) = 0;
-    virtual status_t getCommonFreq(uint64_t* freq) = 0;
-    virtual status_t getLocalTime(int64_t* localTime) = 0;
-    virtual status_t getLocalFreq(uint64_t* freq) = 0;
-    virtual status_t getEstimatedError(int32_t* estimate) = 0;
-    virtual status_t getTimelineID(uint64_t* id) = 0;
-    virtual status_t getState(State* state) = 0;
-    virtual status_t getMasterAddr(struct sockaddr_storage* addr) = 0;
-
-    virtual status_t registerListener(
-            const sp<ICommonClockListener>& listener) = 0;
-    virtual status_t unregisterListener(
-            const sp<ICommonClockListener>& listener) = 0;
-
-    // Simple helper to make it easier to connect to the CommonClock service.
-    static inline sp<ICommonClock> getInstance() {
-        sp<IBinder> binder = defaultServiceManager()->checkService(
-                ICommonClock::kServiceName);
-        sp<ICommonClock> clk = interface_cast<ICommonClock>(binder);
-        return clk;
-    }
-};
-
-class BnCommonClock : public BnInterface<ICommonClock> {
-  public:
-    virtual status_t onTransact(uint32_t code, const Parcel& data,
-                                Parcel* reply, uint32_t flags = 0);
-};
-
-};  // namespace android
-
-#endif  // ANDROID_ICOMMONCLOCK_H
diff --git a/include/common_time/ICommonTimeConfig.h b/include/common_time/ICommonTimeConfig.h
deleted file mode 100644
index 497b666..0000000
--- a/include/common_time/ICommonTimeConfig.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_ICOMMONTIMECONFIG_H
-#define ANDROID_ICOMMONTIMECONFIG_H
-
-#include <stdint.h>
-#include <linux/socket.h>
-
-#include <binder/IInterface.h>
-#include <binder/IServiceManager.h>
-
-namespace android {
-
-class String16;
-
-class ICommonTimeConfig : public IInterface {
-  public:
-    DECLARE_META_INTERFACE(CommonTimeConfig);
-
-    // Name of the ICommonTimeConfig service registered with the service
-    // manager.
-    static const String16 kServiceName;
-
-    virtual status_t getMasterElectionPriority(uint8_t *priority) = 0;
-    virtual status_t setMasterElectionPriority(uint8_t priority) = 0;
-    virtual status_t getMasterElectionEndpoint(struct sockaddr_storage *addr) = 0;
-    virtual status_t setMasterElectionEndpoint(const struct sockaddr_storage *addr) = 0;
-    virtual status_t getMasterElectionGroupId(uint64_t *id) = 0;
-    virtual status_t setMasterElectionGroupId(uint64_t id) = 0;
-    virtual status_t getInterfaceBinding(String16& ifaceName) = 0;
-    virtual status_t setInterfaceBinding(const String16& ifaceName) = 0;
-    virtual status_t getMasterAnnounceInterval(int *interval) = 0;
-    virtual status_t setMasterAnnounceInterval(int interval) = 0;
-    virtual status_t getClientSyncInterval(int *interval) = 0;
-    virtual status_t setClientSyncInterval(int interval) = 0;
-    virtual status_t getPanicThreshold(int *threshold) = 0;
-    virtual status_t setPanicThreshold(int threshold) = 0;
-    virtual status_t getAutoDisable(bool *autoDisable) = 0;
-    virtual status_t setAutoDisable(bool autoDisable) = 0;
-    virtual status_t forceNetworklessMasterMode() = 0;
-
-    // Simple helper to make it easier to connect to the CommonTimeConfig service.
-    static inline sp<ICommonTimeConfig> getInstance() {
-        sp<IBinder> binder = defaultServiceManager()->checkService(
-                ICommonTimeConfig::kServiceName);
-        sp<ICommonTimeConfig> clk = interface_cast<ICommonTimeConfig>(binder);
-        return clk;
-    }
-};
-
-class BnCommonTimeConfig : public BnInterface<ICommonTimeConfig> {
-  public:
-    virtual status_t onTransact(uint32_t code, const Parcel& data,
-                                Parcel* reply, uint32_t flags = 0);
-};
-
-};  // namespace android
-
-#endif  // ANDROID_ICOMMONTIMECONFIG_H
diff --git a/include/common_time/cc_helper.h b/include/common_time/cc_helper.h
deleted file mode 100644
index 8c4d5c0..0000000
--- a/include/common_time/cc_helper.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __CC_HELPER_H__
-#define __CC_HELPER_H__
-
-#include <stdint.h>
-#include <common_time/ICommonClock.h>
-#include <utils/threads.h>
-
-namespace android {
-
-// CCHelper is a simple wrapper class to help with centralizing access to the
-// Common Clock service and implementing lifetime managment, as well as to
-// implement a simple policy of making a basic attempt to reconnect to the
-// common clock service when things go wrong.
-//
-// On platforms which run the native common_time service in auto-disable mode,
-// the service will go into networkless mode whenever it has no active clients.
-// It tracks active clients using registered CommonClockListeners (the callback
-// interface for onTimelineChanged) since this provides a convienent death
-// handler notification for when the service's clients die unexpectedly.  This
-// means that users of the common time service should really always have a
-// CommonClockListener, unless they know that the time service is not running in
-// auto disabled mode, or that there is at least one other registered listener
-// active in the system.  The CCHelper makes this a little easier by sharing a
-// ref counted ICommonClock interface across all clients and automatically
-// registering and unregistering a listener whenever there are CCHelper
-// instances active in the process.
-class CCHelper {
-  public:
-    CCHelper();
-    ~CCHelper();
-
-    status_t isCommonTimeValid(bool* valid, uint32_t* timelineID);
-    status_t commonTimeToLocalTime(int64_t commonTime, int64_t* localTime);
-    status_t localTimeToCommonTime(int64_t localTime, int64_t* commonTime);
-    status_t getCommonTime(int64_t* commonTime);
-    status_t getCommonFreq(uint64_t* freq);
-    status_t getLocalTime(int64_t* localTime);
-    status_t getLocalFreq(uint64_t* freq);
-
-  private:
-    class CommonClockListener : public BnCommonClockListener {
-      public:
-        void onTimelineChanged(uint64_t timelineID);
-    };
-
-    static bool verifyClock_l();
-
-    static Mutex lock_;
-    static sp<ICommonClock> common_clock_;
-    static sp<ICommonClockListener> common_clock_listener_;
-    static uint32_t ref_count_;
-};
-
-
-}  // namespace android
-#endif  // __CC_HELPER_H__
diff --git a/include/common_time/local_clock.h b/include/common_time/local_clock.h
deleted file mode 100644
index 384c3de..0000000
--- a/include/common_time/local_clock.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef __LOCAL_CLOCK_H__
-#define __LOCAL_CLOCK_H__
-
-#include <stdint.h>
-
-#include <hardware/local_time_hal.h>
-#include <utils/Errors.h>
-#include <utils/threads.h>
-
-namespace android {
-
-class LocalClock {
-  public:
-    LocalClock();
-
-    bool initCheck();
-
-    int64_t  getLocalTime();
-    uint64_t getLocalFreq();
-    status_t setLocalSlew(int16_t rate);
-    int32_t  getDebugLog(struct local_time_debug_event* records,
-                         int max_records);
-
-  private:
-    static Mutex dev_lock_;
-    static local_time_hw_device_t* dev_;
-};
-
-}  // namespace android
-#endif  // __LOCAL_CLOCK_H__
diff --git a/include/media/AudioAttributes.h b/include/media/AudioAttributes.h
new file mode 120000
index 0000000..27ba471
--- /dev/null
+++ b/include/media/AudioAttributes.h
@@ -0,0 +1 @@
+../../media/libaudioclient/include/media/AudioAttributes.h
\ No newline at end of file
diff --git a/include/media/AudioCommonTypes.h b/include/media/AudioCommonTypes.h
new file mode 120000
index 0000000..ae7c99a
--- /dev/null
+++ b/include/media/AudioCommonTypes.h
@@ -0,0 +1 @@
+../../media/libaudioclient/include/media/AudioCommonTypes.h
\ No newline at end of file
diff --git a/include/media/AudioPolicyHelper.h b/include/media/AudioPolicyHelper.h
deleted file mode 120000
index 558657e..0000000
--- a/include/media/AudioPolicyHelper.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/AudioPolicyHelper.h
\ No newline at end of file
diff --git a/include/media/AudioPresentationInfo.h b/include/media/AudioPresentationInfo.h
deleted file mode 100644
index e91a992..0000000
--- a/include/media/AudioPresentationInfo.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef AUDIO_PRESENTATION_INFO_H_
-#define AUDIO_PRESENTATION_INFO_H_
-
-#include <sstream>
-#include <stdint.h>
-
-#include <utils/KeyedVector.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-#include <utils/Vector.h>
-
-namespace android {
-
-enum mastering_indication {
-    MASTERING_NOT_INDICATED,
-    MASTERED_FOR_STEREO,
-    MASTERED_FOR_SURROUND,
-    MASTERED_FOR_3D,
-    MASTERED_FOR_HEADPHONE,
-};
-
-struct AudioPresentation : public RefBase {
-    int32_t mPresentationId;
-    int32_t mProgramId;
-    KeyedVector<String8, String8> mLabels;
-    String8 mLanguage;
-    int32_t mMasteringIndication;
-    bool mAudioDescriptionAvailable;
-    bool mSpokenSubtitlesAvailable;
-    bool mDialogueEnhancementAvailable;
-
-    AudioPresentation() {
-        mPresentationId = -1;
-        mProgramId = -1;
-        mLanguage = "";
-        mMasteringIndication = MASTERING_NOT_INDICATED;
-        mAudioDescriptionAvailable = false;
-        mSpokenSubtitlesAvailable = false;
-        mDialogueEnhancementAvailable = false;
-    }
-};
-
-typedef Vector<sp<AudioPresentation>> AudioPresentations;
-
-class AudioPresentationInfo : public RefBase {
- public:
-    AudioPresentationInfo();
-
-    ~AudioPresentationInfo();
-
-    void addPresentation(sp<AudioPresentation> presentation);
-
-    size_t countPresentations() const;
-
-    const sp<AudioPresentation> getPresentation(size_t index) const;
-
- private:
-    AudioPresentations mPresentations;
-};
-
-}  // namespace android
-
-#endif  // AUDIO_PRESENTATION_INFO_H_
diff --git a/include/media/AudioProductStrategy.h b/include/media/AudioProductStrategy.h
new file mode 120000
index 0000000..6bfaf11
--- /dev/null
+++ b/include/media/AudioProductStrategy.h
@@ -0,0 +1 @@
+../../media/libaudioclient/include/media/AudioProductStrategy.h
\ No newline at end of file
diff --git a/include/media/AudioVolumeGroup.h b/include/media/AudioVolumeGroup.h
new file mode 120000
index 0000000..d6f1c99
--- /dev/null
+++ b/include/media/AudioVolumeGroup.h
@@ -0,0 +1 @@
+../../media/libaudioclient/include/media/AudioVolumeGroup.h
\ No newline at end of file
diff --git a/include/media/DataSource.h b/include/media/DataSource.h
index 905bec1..198b27e 120000
--- a/include/media/DataSource.h
+++ b/include/media/DataSource.h
@@ -1 +1 @@
-../../media/libmediaextractor/include/media/DataSource.h
\ No newline at end of file
+stagefright/DataSource.h
\ No newline at end of file
diff --git a/include/media/DataSourceBase.h b/include/media/DataSourceBase.h
index 54c8047..d2ab2f1 120000
--- a/include/media/DataSourceBase.h
+++ b/include/media/DataSourceBase.h
@@ -1 +1 @@
-../../media/libmediaextractor/include/media/DataSourceBase.h
\ No newline at end of file
+stagefright/DataSourceBase.h
\ No newline at end of file
diff --git a/include/media/EventLog.h b/include/media/EventLog.h
new file mode 120000
index 0000000..9b2c4bf
--- /dev/null
+++ b/include/media/EventLog.h
@@ -0,0 +1 @@
+../../media/utils/include/mediautils/EventLog.h
\ No newline at end of file
diff --git a/include/media/ExtractorUtils.h b/include/media/ExtractorUtils.h
deleted file mode 120000
index e2dd082..0000000
--- a/include/media/ExtractorUtils.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmediaextractor/include/media/ExtractorUtils.h
\ No newline at end of file
diff --git a/media/libmediaextractor/include/media/ExtractorUtils.h b/include/media/ExtractorUtils.h
similarity index 100%
rename from media/libmediaextractor/include/media/ExtractorUtils.h
rename to include/media/ExtractorUtils.h
diff --git a/include/media/MediaExtractor.h b/include/media/MediaExtractor.h
deleted file mode 120000
index 4b35fe1..0000000
--- a/include/media/MediaExtractor.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmediaextractor/include/media/MediaExtractor.h
\ No newline at end of file
diff --git a/include/media/MediaExtractorPluginApi.h b/include/media/MediaExtractorPluginApi.h
new file mode 100644
index 0000000..916472c
--- /dev/null
+++ b/include/media/MediaExtractorPluginApi.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MEDIA_EXTRACTOR_PLUGIN_API_H_
+#define MEDIA_EXTRACTOR_PLUGIN_API_H_
+
+#include <utils/Errors.h> // for status_t
+#include <media/NdkMediaError.h>
+struct AMediaFormat;
+
+namespace android {
+
+struct MediaTrack;
+class MetaDataBase;
+class MediaBufferBase;
+
+extern "C" {
+
+struct CDataSource {
+    ssize_t (*readAt)(void *handle, off64_t offset, void *data, size_t size);
+    status_t (*getSize)(void *handle, off64_t *size);
+    uint32_t (*flags)(void *handle );
+    bool (*getUri)(void *handle, char *uriString, size_t bufferSize);
+    void *handle;
+};
+
+enum CMediaTrackReadOptions : uint32_t {
+    SEEK_PREVIOUS_SYNC = 0,
+    SEEK_NEXT_SYNC = 1,
+    SEEK_CLOSEST_SYNC = 2,
+    SEEK_CLOSEST = 3,
+    SEEK_FRAME_INDEX = 4,
+    SEEK = 8,
+    NONBLOCKING = 16
+};
+
+/**
+ * only use CMediaBuffer allocated from the CMediaBufferGroup that is
+ * provided to CMediaTrack::start()
+ */
+struct CMediaBuffer {
+    void *handle;
+    void (*release)(void *handle);
+    void* (*data)(void *handle);
+    size_t (*size)(void *handle);
+    size_t (*range_offset)(void *handle);
+    size_t (*range_length)(void *handle);
+    void (*set_range)(void *handle, size_t offset, size_t length);
+    AMediaFormat* (*meta_data)(void *handle);
+};
+
+struct CMediaBufferGroup {
+    void *handle;
+    bool (*init)(void *handle, size_t buffers, size_t buffer_size, size_t growthLimit);
+    void (*add_buffer)(void *handle, size_t size);
+    media_status_t (*acquire_buffer)(void *handle,
+            CMediaBuffer **buffer, bool nonBlocking, size_t requestedSize);
+    bool (*has_buffers)(void *handle);
+};
+
+struct CMediaTrack {
+    void *data;
+    void (*free)(void *data);
+
+    media_status_t (*start)(void *data, CMediaBufferGroup *bufferGroup);
+    media_status_t (*stop)(void *data);
+    media_status_t (*getFormat)(void *data, AMediaFormat *format);
+    media_status_t (*read)(void *data, CMediaBuffer **buffer, uint32_t options, int64_t seekPosUs);
+    bool     (*supportsNonBlockingRead)(void *data);
+};
+
+struct CMediaExtractor {
+    void *data;
+
+    void (*free)(void *data);
+    size_t (*countTracks)(void *data);
+    CMediaTrack* (*getTrack)(void *data, size_t index);
+    media_status_t (*getTrackMetaData)(
+            void *data,
+            AMediaFormat *meta,
+            size_t index, uint32_t flags);
+
+    media_status_t (*getMetaData)(void *data, AMediaFormat *meta);
+    uint32_t (*flags)(void *data);
+    media_status_t (*setMediaCas)(void *data, const uint8_t* casToken, size_t size);
+    const char * (*name)(void *data);
+};
+
+typedef CMediaExtractor* (*CreatorFunc)(CDataSource *source, void *meta);
+typedef void (*FreeMetaFunc)(void *meta);
+
+// The sniffer can optionally fill in an opaque object, "meta", that helps
+// the corresponding extractor initialize its state without duplicating
+// effort already exerted by the sniffer. If "freeMeta" is given, it will be
+// called against the opaque object when it is no longer used.
+typedef CreatorFunc (*SnifferFunc)(
+        CDataSource *source, float *confidence,
+        void **meta, FreeMetaFunc *freeMeta);
+
+typedef CMediaExtractor CMediaExtractor;
+typedef CreatorFunc CreatorFunc;
+
+
+typedef struct {
+    const uint8_t b[16];
+} media_uuid_t;
+
+struct ExtractorDef {
+    // version number of this structure
+    const uint32_t def_version;
+
+    // A unique identifier for this extractor.
+    // See below for a convenience macro to create this from a string.
+    media_uuid_t extractor_uuid;
+
+    // Version number of this extractor. When two extractors with the same
+    // uuid are encountered, the one with the largest version number will
+    // be used.
+    const uint32_t extractor_version;
+
+    // a human readable name
+    const char *extractor_name;
+
+    union {
+        struct {
+            SnifferFunc sniff;
+        } v2;
+        struct {
+            SnifferFunc sniff;
+            // a NULL terminated list of container mime types and/or file extensions
+            // that this extractor supports
+            const char **supported_types;
+        } v3;
+    } u;
+};
+
+// the C++ based API which first shipped in P and is no longer supported
+const uint32_t EXTRACTORDEF_VERSION_LEGACY = 1;
+
+// the first C/NDK based API
+const uint32_t EXTRACTORDEF_VERSION_NDK_V1 = 2;
+
+// the second C/NDK based API
+const uint32_t EXTRACTORDEF_VERSION_NDK_V2 = 3;
+
+const uint32_t EXTRACTORDEF_VERSION = EXTRACTORDEF_VERSION_NDK_V2;
+
+// each plugin library exports one function of this type
+typedef ExtractorDef (*GetExtractorDef)();
+
+} // extern "C"
+
+}  // namespace android
+
+#endif  // MEDIA_EXTRACTOR_PLUGIN_API_H_
diff --git a/include/media/MediaExtractorPluginHelper.h b/include/media/MediaExtractorPluginHelper.h
new file mode 100644
index 0000000..b86f177
--- /dev/null
+++ b/include/media/MediaExtractorPluginHelper.h
@@ -0,0 +1,494 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MEDIA_EXTRACTOR_PLUGIN_HELPER_H_
+
+#define MEDIA_EXTRACTOR_PLUGIN_HELPER_H_
+
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <map>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <utils/RefBase.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/NdkMediaFormat.h>
+
+namespace android {
+
+class DataSourceBase;
+class MetaDataBase;
+struct MediaTrack;
+
+
+class MediaTrackHelper;
+
+class MediaBufferHelper {
+private:
+    friend CMediaTrack *wrap(MediaTrackHelper *);
+    CMediaBuffer *mBuffer;
+public:
+    MediaBufferHelper(CMediaBuffer *buf) {
+        mBuffer = buf;
+    }
+
+    virtual ~MediaBufferHelper() {}
+
+    virtual void release() {
+        mBuffer->release(mBuffer->handle);
+    }
+
+    virtual void* data() {
+        return mBuffer->data(mBuffer->handle);
+    }
+
+    virtual size_t size() {
+        return mBuffer->size(mBuffer->handle);
+    }
+
+    virtual size_t range_offset() {
+        return mBuffer->range_offset(mBuffer->handle);
+    }
+
+    virtual size_t range_length() {
+        return mBuffer->range_length(mBuffer->handle);
+    }
+
+    virtual void set_range(size_t offset, size_t length) {
+        mBuffer->set_range(mBuffer->handle, offset, length);
+    }
+    virtual AMediaFormat *meta_data() {
+        return mBuffer->meta_data(mBuffer->handle);
+    }
+};
+
+class MediaBufferGroupHelper {
+private:
+    CMediaBufferGroup *mGroup;
+    std::map<CMediaBuffer*, MediaBufferHelper*> mBufferHelpers;
+public:
+    MediaBufferGroupHelper(CMediaBufferGroup *group) {
+        mGroup = group;
+    }
+    ~MediaBufferGroupHelper() {
+        // delete all entries in map
+        ALOGV("buffergroup %p map has %zu entries", this, mBufferHelpers.size());
+        for (auto it = mBufferHelpers.begin(); it != mBufferHelpers.end(); ++it) {
+            delete it->second;
+        }
+    }
+    bool init(size_t buffers, size_t buffer_size, size_t growthLimit = 0) {
+        return mGroup->init(mGroup->handle, buffers, buffer_size, growthLimit);
+    }
+    void add_buffer(size_t size) {
+        mGroup->add_buffer(mGroup->handle, size);
+    }
+    media_status_t acquire_buffer(
+            MediaBufferHelper **buffer, bool nonBlocking = false, size_t requestedSize = 0) {
+        CMediaBuffer *buf = nullptr;
+        media_status_t ret =
+                mGroup->acquire_buffer(mGroup->handle, &buf, nonBlocking, requestedSize);
+        if (ret == AMEDIA_OK && buf != nullptr) {
+            auto helper = mBufferHelpers.find(buf);
+            if (helper == mBufferHelpers.end()) {
+                MediaBufferHelper* newHelper = new MediaBufferHelper(buf);
+                mBufferHelpers.insert(std::make_pair(buf, newHelper));
+                *buffer = newHelper;
+            } else {
+                *buffer = helper->second;
+            }
+        } else {
+            *buffer = nullptr;
+        }
+        return ret;
+    }
+    bool has_buffers() {
+        return mGroup->has_buffers(mGroup->handle);
+    }
+};
+
+class MediaTrackHelper {
+public:
+    MediaTrackHelper() : mBufferGroup(nullptr) {
+    }
+    virtual ~MediaTrackHelper() {
+        delete mBufferGroup;
+    }
+    virtual media_status_t start() = 0;
+    virtual media_status_t stop() = 0;
+    virtual media_status_t getFormat(AMediaFormat *format) = 0;
+
+    class ReadOptions {
+    public:
+        enum SeekMode : int32_t {
+            SEEK_PREVIOUS_SYNC,
+            SEEK_NEXT_SYNC,
+            SEEK_CLOSEST_SYNC,
+            SEEK_CLOSEST,
+            SEEK_FRAME_INDEX,
+        };
+
+        ReadOptions(uint32_t options, int64_t seekPosUs) {
+            mOptions = options;
+            mSeekPosUs = seekPosUs;
+        }
+        bool getSeekTo(int64_t *time_us, SeekMode *mode) const {
+            if ((mOptions & CMediaTrackReadOptions::SEEK) == 0) {
+                return false;
+            }
+            *time_us = mSeekPosUs;
+            *mode = (SeekMode) (mOptions & 7);
+            return true;
+        }
+        bool getNonBlocking() const {
+            return mOptions & CMediaTrackReadOptions::NONBLOCKING;
+        }
+    private:
+        uint32_t mOptions;
+        int64_t mSeekPosUs;
+    };
+
+    virtual media_status_t read(
+            MediaBufferHelper **buffer, const ReadOptions *options = NULL) = 0;
+    virtual bool supportsNonBlockingRead() { return false; }
+protected:
+    friend CMediaTrack *wrap(MediaTrackHelper *track);
+    MediaBufferGroupHelper *mBufferGroup;
+};
+
+inline CMediaTrack *wrap(MediaTrackHelper *track) {
+    if (track == nullptr) {
+        return nullptr;
+    }
+    CMediaTrack *wrapper = (CMediaTrack*) malloc(sizeof(CMediaTrack));
+    wrapper->data = track;
+    wrapper->free = [](void *data) -> void {
+        delete (MediaTrackHelper*)(data);
+    };
+    wrapper->start = [](void *data, CMediaBufferGroup *bufferGroup) -> media_status_t {
+        if (((MediaTrackHelper*)data)->mBufferGroup) {
+            // this shouldn't happen, but handle it anyway
+            delete ((MediaTrackHelper*)data)->mBufferGroup;
+        }
+        ((MediaTrackHelper*)data)->mBufferGroup = new MediaBufferGroupHelper(bufferGroup);
+        return ((MediaTrackHelper*)data)->start();
+    };
+    wrapper->stop = [](void *data) -> media_status_t {
+        return ((MediaTrackHelper*)data)->stop();
+    };
+    wrapper->getFormat = [](void *data, AMediaFormat *meta) -> media_status_t {
+        return ((MediaTrackHelper*)data)->getFormat(meta);
+    };
+    wrapper->read = [](void *data, CMediaBuffer **buffer,  uint32_t options, int64_t seekPosUs)
+            -> media_status_t {
+        MediaTrackHelper::ReadOptions opts(options, seekPosUs);
+        MediaBufferHelper *buf = NULL;
+        media_status_t ret = ((MediaTrackHelper*)data)->read(&buf, &opts);
+        if (ret == AMEDIA_OK && buf != nullptr) {
+            *buffer = buf->mBuffer;
+        }
+        return ret;
+    };
+    wrapper->supportsNonBlockingRead = [](void *data) -> bool {
+                return ((MediaTrackHelper*)data)->supportsNonBlockingRead();
+    };
+    return wrapper;
+}
+
+
+// extractor plugins can derive from this class which looks remarkably
+// like MediaExtractor and can be easily wrapped in the required C API
+class MediaExtractorPluginHelper
+{
+public:
+    virtual ~MediaExtractorPluginHelper() {}
+    virtual size_t countTracks() = 0;
+    virtual MediaTrackHelper *getTrack(size_t index) = 0;
+
+    enum GetTrackMetaDataFlags {
+        kIncludeExtensiveMetaData = 1
+    };
+    virtual media_status_t getTrackMetaData(
+            AMediaFormat *meta,
+            size_t index, uint32_t flags = 0) = 0;
+
+    // Return container specific meta-data. The default implementation
+    // returns an empty metadata object.
+    virtual media_status_t getMetaData(AMediaFormat *meta) = 0;
+
+    enum Flags {
+        CAN_SEEK_BACKWARD  = 1,  // the "seek 10secs back button"
+        CAN_SEEK_FORWARD   = 2,  // the "seek 10secs forward button"
+        CAN_PAUSE          = 4,
+        CAN_SEEK           = 8,  // the "seek bar"
+    };
+
+    // If subclasses do _not_ override this, the default is
+    // CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK | CAN_PAUSE
+    virtual uint32_t flags() const {
+        return CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK | CAN_PAUSE;
+    };
+
+    virtual media_status_t setMediaCas(const uint8_t* /*casToken*/, size_t /*size*/) {
+        return AMEDIA_ERROR_INVALID_OPERATION;
+    }
+
+    virtual const char * name() { return "<unspecified>"; }
+
+protected:
+    MediaExtractorPluginHelper() {}
+
+private:
+    MediaExtractorPluginHelper(const MediaExtractorPluginHelper &);
+    MediaExtractorPluginHelper &operator=(const MediaExtractorPluginHelper &);
+};
+
+inline CMediaExtractor *wrap(MediaExtractorPluginHelper *extractor) {
+    CMediaExtractor *wrapper = (CMediaExtractor*) malloc(sizeof(CMediaExtractor));
+    wrapper->data = extractor;
+    wrapper->free = [](void *data) -> void {
+        delete (MediaExtractorPluginHelper*)(data);
+    };
+    wrapper->countTracks = [](void *data) -> size_t {
+        return ((MediaExtractorPluginHelper*)data)->countTracks();
+    };
+    wrapper->getTrack = [](void *data, size_t index) -> CMediaTrack* {
+        return wrap(((MediaExtractorPluginHelper*)data)->getTrack(index));
+    };
+    wrapper->getTrackMetaData = [](
+            void *data,
+            AMediaFormat *meta,
+            size_t index, uint32_t flags) -> media_status_t {
+        return ((MediaExtractorPluginHelper*)data)->getTrackMetaData(meta, index, flags);
+    };
+    wrapper->getMetaData = [](
+            void *data,
+            AMediaFormat *meta) -> media_status_t {
+        return ((MediaExtractorPluginHelper*)data)->getMetaData(meta);
+    };
+    wrapper->flags = [](
+            void *data) -> uint32_t {
+        return ((MediaExtractorPluginHelper*)data)->flags();
+    };
+    wrapper->setMediaCas = [](
+            void *data, const uint8_t *casToken, size_t size) -> media_status_t {
+        return ((MediaExtractorPluginHelper*)data)->setMediaCas(casToken, size);
+    };
+    wrapper->name = [](
+            void *data) -> const char * {
+        return ((MediaExtractorPluginHelper*)data)->name();
+    };
+    return wrapper;
+}
+
+/* adds some convience methods */
+class DataSourceHelper {
+public:
+    explicit DataSourceHelper(CDataSource *csource) {
+        mSource = csource;
+    }
+
+    explicit DataSourceHelper(DataSourceHelper *source) {
+        mSource = source->mSource;
+    }
+
+    virtual ~DataSourceHelper() {}
+
+    virtual ssize_t readAt(off64_t offset, void *data, size_t size) {
+        return mSource->readAt(mSource->handle, offset, data, size);
+    }
+
+    virtual status_t getSize(off64_t *size) {
+        return mSource->getSize(mSource->handle, size);
+    }
+
+    bool getUri(char *uriString, size_t bufferSize) {
+        return mSource->getUri(mSource->handle, uriString, bufferSize);
+    }
+
+    virtual uint32_t flags() {
+        return mSource->flags(mSource->handle);
+    }
+
+    // Convenience methods:
+    bool getUInt16(off64_t offset, uint16_t *x) {
+        *x = 0;
+
+        uint8_t byte[2];
+        if (readAt(offset, byte, 2) != 2) {
+            return false;
+        }
+
+        *x = (byte[0] << 8) | byte[1];
+
+        return true;
+    }
+
+    // 3 byte int, returned as a 32-bit int
+    bool getUInt24(off64_t offset, uint32_t *x) {
+        *x = 0;
+
+        uint8_t byte[3];
+        if (readAt(offset, byte, 3) != 3) {
+            return false;
+        }
+
+        *x = (byte[0] << 16) | (byte[1] << 8) | byte[2];
+
+        return true;
+    }
+
+    bool getUInt32(off64_t offset, uint32_t *x) {
+        *x = 0;
+
+        uint32_t tmp;
+        if (readAt(offset, &tmp, 4) != 4) {
+            return false;
+        }
+
+        *x = ntohl(tmp);
+
+        return true;
+    }
+
+    bool getUInt64(off64_t offset, uint64_t *x) {
+        *x = 0;
+
+        uint64_t tmp;
+        if (readAt(offset, &tmp, 8) != 8) {
+            return false;
+        }
+
+        *x = ((uint64_t)ntohl(tmp & 0xffffffff) << 32) | ntohl(tmp >> 32);
+
+        return true;
+    }
+
+    // read either int<N> or int<2N> into a uint<2N>_t, size is the int size in bytes.
+    bool getUInt16Var(off64_t offset, uint16_t *x, size_t size) {
+        if (size == 2) {
+            return getUInt16(offset, x);
+        }
+        if (size == 1) {
+            uint8_t tmp;
+            if (readAt(offset, &tmp, 1) == 1) {
+                *x = tmp;
+                return true;
+            }
+        }
+        return false;
+    }
+
+    bool getUInt32Var(off64_t offset, uint32_t *x, size_t size) {
+        if (size == 4) {
+            return getUInt32(offset, x);
+        }
+        if (size == 2) {
+            uint16_t tmp;
+            if (getUInt16(offset, &tmp)) {
+                *x = tmp;
+                return true;
+            }
+        }
+        return false;
+    }
+
+    bool getUInt64Var(off64_t offset, uint64_t *x, size_t size) {
+        if (size == 8) {
+            return getUInt64(offset, x);
+        }
+        if (size == 4) {
+            uint32_t tmp;
+            if (getUInt32(offset, &tmp)) {
+                *x = tmp;
+                return true;
+            }
+        }
+        return false;
+    }
+
+protected:
+    CDataSource *mSource;
+};
+
+
+
+// helpers to create a media_uuid_t from a string literal
+
+// purposely not defined anywhere so that this will fail to link if
+// expressions below are not evaluated at compile time
+int invalid_uuid_string(const char *);
+
+template <typename T, size_t N>
+constexpr uint8_t _digitAt_(const T (&s)[N], const size_t n) {
+    return s[n] >= '0' && s[n] <= '9' ? s[n] - '0'
+            : s[n] >= 'a' && s[n] <= 'f' ? s[n] - 'a' + 10
+                    : s[n] >= 'A' && s[n] <= 'F' ? s[n] - 'A' + 10
+                            : invalid_uuid_string("uuid: bad digits");
+}
+
+template <typename T, size_t N>
+constexpr uint8_t _hexByteAt_(const T (&s)[N], size_t n) {
+    return (_digitAt_(s, n) << 4) + _digitAt_(s, n + 1);
+}
+
+constexpr bool _assertIsDash_(char c) {
+    return c == '-' ? true : invalid_uuid_string("Wrong format");
+}
+
+template <size_t N>
+constexpr media_uuid_t constUUID(const char (&s) [N]) {
+    static_assert(N == 37, "uuid: wrong length");
+    return
+            _assertIsDash_(s[8]),
+            _assertIsDash_(s[13]),
+            _assertIsDash_(s[18]),
+            _assertIsDash_(s[23]),
+            media_uuid_t {{
+                _hexByteAt_(s, 0),
+                _hexByteAt_(s, 2),
+                _hexByteAt_(s, 4),
+                _hexByteAt_(s, 6),
+                _hexByteAt_(s, 9),
+                _hexByteAt_(s, 11),
+                _hexByteAt_(s, 14),
+                _hexByteAt_(s, 16),
+                _hexByteAt_(s, 19),
+                _hexByteAt_(s, 21),
+                _hexByteAt_(s, 24),
+                _hexByteAt_(s, 26),
+                _hexByteAt_(s, 28),
+                _hexByteAt_(s, 30),
+                _hexByteAt_(s, 32),
+                _hexByteAt_(s, 34),
+            }};
+}
+// Convenience macro to create a media_uuid_t from a string literal, which should
+// be formatted as "12345678-1234-1234-1234-123456789abc", as generated by
+// e.g. https://www.uuidgenerator.net/ or the 'uuidgen' linux command.
+// Hex digits may be upper or lower case.
+//
+// The macro call is otherwise equivalent to specifying the structure directly
+// (e.g. UUID("7d613858-5837-4a38-84c5-332d1cddee27") is the same as
+//       {{0x7d, 0x61, 0x38, 0x58, 0x58, 0x37, 0x4a, 0x38,
+//         0x84, 0xc5, 0x33, 0x2d, 0x1c, 0xdd, 0xee, 0x27}})
+
+#define UUID(str) []{ constexpr media_uuid_t uuid = constUUID(str); return uuid; }()
+
+}  // namespace android
+
+#endif  // MEDIA_EXTRACTOR_PLUGIN_HELPER_H_
diff --git a/include/media/MediaMetrics.h b/include/media/MediaMetrics.h
new file mode 120000
index 0000000..5f757e4
--- /dev/null
+++ b/include/media/MediaMetrics.h
@@ -0,0 +1 @@
+../../media/libmediametrics/include/MediaMetrics.h
\ No newline at end of file
diff --git a/include/media/MediaSource.h b/include/media/MediaSource.h
index 2e147c4..34bf65d 120000
--- a/include/media/MediaSource.h
+++ b/include/media/MediaSource.h
@@ -1 +1 @@
-../../media/libmediaextractor/include/media/MediaSource.h
\ No newline at end of file
+../../media/libstagefright/include/media/stagefright/MediaSource.h
\ No newline at end of file
diff --git a/include/media/MediaTrack.h b/include/media/MediaTrack.h
deleted file mode 120000
index 5a63287a..0000000
--- a/include/media/MediaTrack.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmediaextractor/include/media/MediaTrack.h
\ No newline at end of file
diff --git a/include/media/MediaTrack.h b/include/media/MediaTrack.h
new file mode 100644
index 0000000..493eba3
--- /dev/null
+++ b/include/media/MediaTrack.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MEDIA_SOURCE_BASE_H_
+
+#define MEDIA_SOURCE_BASE_H_
+
+#include <sys/types.h>
+
+#include <binder/IMemory.h>
+#include <binder/MemoryDealer.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/stagefright/MediaBufferGroup.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MetaData.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <utils/Log.h>
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+class MediaBufferBase;
+struct CMediaTrack;
+
+class SourceBaseAllocTracker {
+public:
+    SourceBaseAllocTracker() {
+        ALOGD("sourcebase allocated: %p", this);
+    }
+    virtual ~SourceBaseAllocTracker() {
+        ALOGD("sourcebase freed: %p", this);
+    }
+};
+
+struct MediaTrack
+//    : public SourceBaseAllocTracker
+{
+    MediaTrack();
+
+    // To be called before any other methods on this object, except
+    // getFormat().
+    virtual status_t start() = 0;
+
+    // Any blocking read call returns immediately with a result of NO_INIT.
+    // It is an error to call any methods other than start after this call
+    // returns. Any buffers the object may be holding onto at the time of
+    // the stop() call are released.
+    // Also, it is imperative that any buffers output by this object and
+    // held onto by callers be released before a call to stop() !!!
+    virtual status_t stop() = 0;
+
+    // Returns the format of the data output by this media track.
+    virtual status_t getFormat(MetaDataBase& format) = 0;
+
+    // Options that modify read() behaviour. The default is to
+    // a) not request a seek
+    // b) not be late, i.e. lateness_us = 0
+    struct ReadOptions {
+        enum SeekMode : int32_t {
+            SEEK_PREVIOUS_SYNC = CMediaTrackReadOptions::SEEK_PREVIOUS_SYNC,
+            SEEK_NEXT_SYNC = CMediaTrackReadOptions::SEEK_NEXT_SYNC,
+            SEEK_CLOSEST_SYNC = CMediaTrackReadOptions::SEEK_CLOSEST_SYNC,
+            SEEK_CLOSEST = CMediaTrackReadOptions::SEEK_CLOSEST,
+            SEEK_FRAME_INDEX = CMediaTrackReadOptions::SEEK_FRAME_INDEX,
+        };
+
+        ReadOptions() {
+            reset();
+        }
+
+        // Reset everything back to defaults.
+        void reset() {
+            mOptions = 0;
+            mSeekTimeUs = 0;
+            mNonBlocking = false;
+        }
+
+        void setSeekTo(int64_t time_us, SeekMode mode = SEEK_CLOSEST_SYNC);
+        void clearSeekTo() {
+            mOptions &= ~kSeekTo_Option;
+            mSeekTimeUs = 0;
+            mSeekMode = SEEK_CLOSEST_SYNC;
+        }
+        bool getSeekTo(int64_t *time_us, SeekMode *mode) const;
+
+        void setNonBlocking();
+        void clearNonBlocking();
+        bool getNonBlocking() const;
+
+        // Used to clear all non-persistent options for multiple buffer reads.
+        void clearNonPersistent() {
+            clearSeekTo();
+        }
+
+    private:
+        enum Options {
+            kSeekTo_Option      = 1,
+        };
+
+        uint32_t mOptions;
+        int64_t mSeekTimeUs;
+        SeekMode mSeekMode;
+        bool mNonBlocking;
+    } __attribute__((packed)); // sent through Binder
+
+    // Returns a new buffer of data. Call blocks until a
+    // buffer is available, an error is encountered of the end of the stream
+    // is reached.
+    // End of stream is signalled by a result of ERROR_END_OF_STREAM.
+    // A result of INFO_FORMAT_CHANGED indicates that the format of this
+    // MediaSource has changed mid-stream, the client can continue reading
+    // but should be prepared for buffers of the new configuration.
+    virtual status_t read(
+            MediaBufferBase **buffer, const ReadOptions *options = NULL) = 0;
+
+    // Returns true if |read| supports nonblocking option, otherwise false.
+    // |readMultiple| if supported, always allows the nonblocking option.
+    virtual bool supportNonblockingRead() {
+        return false;
+    }
+
+    virtual ~MediaTrack();
+
+private:
+    MediaTrack(const MediaTrack &);
+    MediaTrack &operator=(const MediaTrack &);
+};
+
+class MediaTrackCUnwrapper : public MediaTrack {
+public:
+    static MediaTrackCUnwrapper *create(CMediaTrack *wrapper);
+
+    virtual status_t start();
+    virtual status_t stop();
+    virtual status_t getFormat(MetaDataBase& format);
+    virtual status_t read(MediaBufferBase **buffer, const ReadOptions *options = NULL);
+
+    virtual bool supportNonblockingRead();
+
+protected:
+    virtual ~MediaTrackCUnwrapper();
+
+private:
+    explicit MediaTrackCUnwrapper(CMediaTrack *wrapper);
+    CMediaTrack *wrapper;
+    MediaBufferGroup *bufferGroup;
+};
+
+}  // namespace android
+
+#endif  // MEDIA_SOURCE_BASE_H_
diff --git a/include/media/NdkMediaErrorPriv.h b/include/media/NdkMediaErrorPriv.h
new file mode 100644
index 0000000..3bbba79
--- /dev/null
+++ b/include/media/NdkMediaErrorPriv.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _NDK_MEDIA_ERROR_PRIV_H
+#define _NDK_MEDIA_ERROR_PRIV_H
+
+#include <media/NdkMediaError.h>
+#include <utils/Errors.h>
+
+media_status_t translate_error(android::status_t);
+
+android::status_t reverse_translate_error(media_status_t);
+
+#endif // _NDK_MEDIA_ERROR_PRIV_H
diff --git a/include/media/NdkMediaFormatPriv.h b/include/media/NdkMediaFormatPriv.h
new file mode 100644
index 0000000..1fda4a8
--- /dev/null
+++ b/include/media/NdkMediaFormatPriv.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * This file defines an NDK API.
+ * Do not remove methods.
+ * Do not change method signatures.
+ * Do not change the value of constants.
+ * Do not change the size of any of the classes defined in here.
+ * Do not reference types that are not part of the NDK.
+ * Do not #include files that aren't part of the NDK.
+ */
+
+#ifndef _NDK_MEDIA_FORMAT_PRIV_H
+#define _NDK_MEDIA_FORMAT_PRIV_H
+
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+#include <utils/StrongPointer.h>
+#include <media/stagefright/foundation/AMessage.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct AMediaFormat {
+    android::sp<android::AMessage> mFormat;
+    android::String8 mDebug;
+    android::KeyedVector<android::String8, android::String8> mStringCache;
+};
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+namespace android {
+
+AMediaFormat* AMediaFormat_fromMsg(sp<AMessage> *);
+void AMediaFormat_getFormat(const AMediaFormat* mData, sp<AMessage> *dest);
+
+} // namespace android
+
+#endif // _NDK_MEDIA_FORMAT_PRIV_H
+
diff --git a/include/media/TimeCheck.h b/include/media/TimeCheck.h
index e3ef134..85e17f9 120000
--- a/include/media/TimeCheck.h
+++ b/include/media/TimeCheck.h
@@ -1 +1 @@
-../../media/libmedia/include/media/TimeCheck.h
\ No newline at end of file
+../../media/utils/include/mediautils/TimeCheck.h
\ No newline at end of file
diff --git a/include/media/VolumeShaper.h b/include/media/VolumeShaper.h
index a3aaece..79afd6c 100644
--- a/include/media/VolumeShaper.h
+++ b/include/media/VolumeShaper.h
@@ -551,7 +551,7 @@
 
     static int64_t convertTimespecToUs(const struct timespec &tv)
     {
-        return tv.tv_sec * 1000000ll + tv.tv_nsec / 1000;
+        return tv.tv_sec * 1000000LL + tv.tv_nsec / 1000;
     }
 
     // current monotonic time in microseconds.
diff --git a/include/media/VorbisComment.h b/include/media/VorbisComment.h
deleted file mode 120000
index adaa489..0000000
--- a/include/media/VorbisComment.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmediaextractor/include/media/VorbisComment.h
\ No newline at end of file
diff --git a/include/mediadrm/Crypto.h b/include/mediadrm/Crypto.h
deleted file mode 120000
index 9af6495..0000000
--- a/include/mediadrm/Crypto.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/Crypto.h
\ No newline at end of file
diff --git a/include/mediadrm/Drm.h b/include/mediadrm/Drm.h
deleted file mode 120000
index ac60003..0000000
--- a/include/mediadrm/Drm.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/Drm.h
\ No newline at end of file
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index ca119d5..5f19f74 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -538,6 +538,10 @@
         mTimestampMutator.push(timestamp);
     }
 
+    virtual ExtendedTimestamp getTimestamp() const {
+        return mTimestampMutator.last();
+    }
+
     // Flushes the shared ring buffer if the client had requested it using mStreaming.mFlush.
     // If flush occurs then:
     //   cblk->u.mStreaming.mFront, ServerProxy::mFlush and ServerProxy::mFlushed will be modified
@@ -551,6 +555,9 @@
     // Total count of the number of flushed frames since creation (never reset).
     virtual int64_t     framesFlushed() const { return mFlushed; }
 
+    // Safe frames ready query with no side effects.
+    virtual size_t      framesReadySafe() const = 0;
+
     // Get dynamic buffer size from the shared control block.
     uint32_t            getBufferSizeInFrames() const {
         return android_atomic_acquire_load((int32_t *)&mCblk->mBufferSizeInFrames);
@@ -588,8 +595,7 @@
     // which may include non-contiguous frames
     virtual size_t      framesReady();
 
-    // Safe frames ready query used by dump() - this has no side effects.
-    virtual size_t      framesReadySafe() const;
+    size_t              framesReadySafe() const override; // frames available to read by server.
 
     // Currently AudioFlinger will call framesReady() for a fast track from two threads:
     // FastMixer thread, and normal mixer thread.  This is dangerous, as the proxy is intended
@@ -693,6 +699,8 @@
         return mCblk->u.mStreaming.mRear; // For completeness only; mRear written by server.
     }
 
+    size_t framesReadySafe() const override; // frames available to read by client.
+
 protected:
     virtual ~AudioRecordServerProxy() { }
 };
diff --git a/include/soundtrigger/ISoundTrigger.h b/include/soundtrigger/ISoundTrigger.h
index 5fd8eb2..c357caa 100644
--- a/include/soundtrigger/ISoundTrigger.h
+++ b/include/soundtrigger/ISoundTrigger.h
@@ -40,6 +40,7 @@
     virtual status_t startRecognition(sound_model_handle_t handle,
                                       const sp<IMemory>& dataMemory) = 0;
     virtual status_t stopRecognition(sound_model_handle_t handle) = 0;
+    virtual status_t getModelState(sound_model_handle_t handle) = 0;
 
 };
 
diff --git a/include/soundtrigger/ISoundTriggerHwService.h b/include/soundtrigger/ISoundTriggerHwService.h
index ae0cb01..1faeb0f 100644
--- a/include/soundtrigger/ISoundTriggerHwService.h
+++ b/include/soundtrigger/ISoundTriggerHwService.h
@@ -33,12 +33,14 @@
 
     DECLARE_META_INTERFACE(SoundTriggerHwService);
 
-    virtual status_t listModules(struct sound_trigger_module_descriptor *modules,
+    virtual status_t listModules(const String16& opPackageName,
+                                 struct sound_trigger_module_descriptor *modules,
                                  uint32_t *numModules) = 0;
 
-    virtual status_t attach(const sound_trigger_module_handle_t handle,
-                                      const sp<ISoundTriggerClient>& client,
-                                      sp<ISoundTrigger>& module) = 0;
+    virtual status_t attach(const String16& opPackageName,
+                            const sound_trigger_module_handle_t handle,
+                            const sp<ISoundTriggerClient>& client,
+                            sp<ISoundTrigger>& module) = 0;
 
     virtual status_t setCaptureState(bool active) = 0;
 };
diff --git a/include/soundtrigger/SoundTrigger.h b/include/soundtrigger/SoundTrigger.h
index 7a29e31..ccc61dc 100644
--- a/include/soundtrigger/SoundTrigger.h
+++ b/include/soundtrigger/SoundTrigger.h
@@ -36,10 +36,12 @@
 
     virtual ~SoundTrigger();
 
-    static  status_t listModules(struct sound_trigger_module_descriptor *modules,
+    static  status_t listModules(const String16& opPackageName,
+                                 struct sound_trigger_module_descriptor *modules,
                                  uint32_t *numModules);
-    static  sp<SoundTrigger> attach(const sound_trigger_module_handle_t module,
-                                       const sp<SoundTriggerCallback>& callback);
+    static  sp<SoundTrigger> attach(const String16& opPackageName,
+                                    const sound_trigger_module_handle_t module,
+                                    const sp<SoundTriggerCallback>& callback);
 
     static  status_t setCaptureState(bool active);
 
@@ -52,6 +54,7 @@
 
             status_t startRecognition(sound_model_handle_t handle, const sp<IMemory>& dataMemory);
             status_t stopRecognition(sound_model_handle_t handle);
+            status_t getModelState(sound_model_handle_t handle);
 
             // BpSoundTriggerClient
             virtual void onRecognitionEvent(const sp<IMemory>& eventMemory);
diff --git a/media/OWNERS b/media/OWNERS
index d49eb8d..1afc253 100644
--- a/media/OWNERS
+++ b/media/OWNERS
@@ -1,9 +1,12 @@
+andrewlewis@google.com
 chz@google.com
 dwkang@google.com
 elaurent@google.com
 essick@google.com
+gkasten@google.com
 hkuang@google.com
 hunga@google.com
+jiabin@google.com
 jmtrivi@google.com
 krocard@google.com
 lajos@google.com
@@ -15,5 +18,6 @@
 rachad@google.com
 rago@google.com
 robertshih@google.com
+taklee@google.com
 wjia@google.com
 wonsik@google.com
diff --git a/media/audioserver/Android.mk b/media/audioserver/Android.mk
index 70c281a..33b36b8 100644
--- a/media/audioserver/Android.mk
+++ b/media/audioserver/Android.mk
@@ -4,7 +4,6 @@
 
 LOCAL_SRC_FILES := \
 	main_audioserver.cpp \
-	../libaudioclient/aidl/android/media/IAudioRecord.aidl
 
 LOCAL_SHARED_LIBRARIES := \
 	libaaudioservice \
@@ -13,13 +12,17 @@
 	libbinder \
 	libcutils \
 	liblog \
+	libhidlbase \
 	libhidltransport \
 	libhwbinder \
 	libmedia \
 	libmedialogservice \
+	libmediautils \
 	libnbaio \
+	libnblog \
 	libsoundtriggerservice \
-	libutils
+	libutils \
+	libvibrator
 
 # TODO oboeservice is the old folder name for aaudioservice. It will be changed.
 LOCAL_C_INCLUDES := \
@@ -40,9 +43,6 @@
 	$(call include-path-for, audio-utils) \
 	external/sonic \
 
-LOCAL_AIDL_INCLUDES := \
-        frameworks/av/media/libaudioclient/aidl
-
 # If AUDIOSERVER_MULTILIB in device.mk is non-empty then it is used to control
 # the LOCAL_MULTILIB for all audioserver exclusive libraries.
 # This is relevant for 64 bit architectures where either or both
@@ -54,13 +54,9 @@
 #   both    to build both 32 bit and 64 bit libraries,
 #           and use primary target architecture (32 or 64) for audioserver.
 #   first   to build libraries and audioserver for the primary target architecture only.
-#   <empty> to build both 32 and 64 bit libraries and 32 bit audioserver.
+#   <empty> to build both 32 and 64 bit libraries and primary target audioserver.
 
-ifeq ($(strip $(AUDIOSERVER_MULTILIB)),)
-LOCAL_MULTILIB := 32
-else
 LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-endif
 
 LOCAL_MODULE := audioserver
 
diff --git a/media/audioserver/audioserver.rc b/media/audioserver/audioserver.rc
index 75675a9..dfb1a3f 100644
--- a/media/audioserver/audioserver.rc
+++ b/media/audioserver/audioserver.rc
@@ -2,10 +2,12 @@
     class core
     user audioserver
     # media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
-    group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct
+    group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct wakelock
+    capabilities BLOCK_SUSPEND
     ioprio rt 4
     writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
     onrestart restart vendor.audio-hal-2-0
+    onrestart restart vendor.audio-hal-4-0-msd
     # Keep the original service name for backward compatibility when upgrading
     # O-MR1 devices with framework-only.
     onrestart restart audio-hal-2-0
@@ -14,3 +16,6 @@
     stop audioserver
 on property:vts.native_server.on=0
     start audioserver
+
+on init
+    mkdir /dev/socket/audioserver 0775 audioserver audioserver
diff --git a/media/bufferpool/1.0/Accessor.cpp b/media/bufferpool/1.0/Accessor.cpp
new file mode 100644
index 0000000..b1dfc08
--- /dev/null
+++ b/media/bufferpool/1.0/Accessor.cpp
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "BufferPoolConnection"
+
+#include "Accessor.h"
+#include "AccessorImpl.h"
+#include "Connection.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V1_0 {
+namespace implementation {
+
+void ConnectionDeathRecipient::add(
+        int64_t connectionId,
+        const sp<Accessor> &accessor) {
+    std::lock_guard<std::mutex> lock(mLock);
+    if (mAccessors.find(connectionId) == mAccessors.end()) {
+        mAccessors.insert(std::make_pair(connectionId, accessor));
+    }
+}
+
+void ConnectionDeathRecipient::remove(int64_t connectionId) {
+    std::lock_guard<std::mutex> lock(mLock);
+    mAccessors.erase(connectionId);
+    auto it = mConnectionToCookie.find(connectionId);
+    if (it != mConnectionToCookie.end()) {
+        uint64_t cookie = it->second;
+        mConnectionToCookie.erase(it);
+        auto cit = mCookieToConnections.find(cookie);
+        if (cit != mCookieToConnections.end()) {
+            cit->second.erase(connectionId);
+            if (cit->second.size() == 0) {
+                mCookieToConnections.erase(cit);
+            }
+        }
+    }
+}
+
+void ConnectionDeathRecipient::addCookieToConnection(
+        uint64_t cookie,
+        int64_t connectionId) {
+    std::lock_guard<std::mutex> lock(mLock);
+    if (mAccessors.find(connectionId) == mAccessors.end()) {
+        return;
+    }
+    mConnectionToCookie.insert(std::make_pair(connectionId, cookie));
+    auto it = mCookieToConnections.find(cookie);
+    if (it != mCookieToConnections.end()) {
+        it->second.insert(connectionId);
+    } else {
+        mCookieToConnections.insert(std::make_pair(
+                cookie, std::set<int64_t>{connectionId}));
+    }
+}
+
+void ConnectionDeathRecipient::serviceDied(
+        uint64_t cookie,
+        const wp<::android::hidl::base::V1_0::IBase>& /* who */
+        ) {
+    std::map<int64_t, const wp<Accessor>> connectionsToClose;
+    {
+        std::lock_guard<std::mutex> lock(mLock);
+
+        auto it = mCookieToConnections.find(cookie);
+        if (it != mCookieToConnections.end()) {
+            for (auto conIt = it->second.begin(); conIt != it->second.end(); ++conIt) {
+                auto accessorIt = mAccessors.find(*conIt);
+                if (accessorIt != mAccessors.end()) {
+                    connectionsToClose.insert(std::make_pair(*conIt, accessorIt->second));
+                    mAccessors.erase(accessorIt);
+                }
+                mConnectionToCookie.erase(*conIt);
+            }
+            mCookieToConnections.erase(it);
+        }
+    }
+
+    if (connectionsToClose.size() > 0) {
+        sp<Accessor> accessor;
+        for (auto it = connectionsToClose.begin(); it != connectionsToClose.end(); ++it) {
+            accessor = it->second.promote();
+
+            if (accessor) {
+                accessor->close(it->first);
+                ALOGD("connection %lld closed on death", (long long)it->first);
+            }
+        }
+    }
+}
+
+namespace {
+static sp<ConnectionDeathRecipient> sConnectionDeathRecipient =
+        new ConnectionDeathRecipient();
+}
+
+sp<ConnectionDeathRecipient> Accessor::getConnectionDeathRecipient() {
+    return sConnectionDeathRecipient;
+}
+
+// Methods from ::android::hardware::media::bufferpool::V1_0::IAccessor follow.
+Return<void> Accessor::connect(connect_cb _hidl_cb) {
+    sp<Connection> connection;
+    ConnectionId connectionId;
+    const QueueDescriptor* fmqDesc;
+
+    ResultStatus status = connect(&connection, &connectionId, &fmqDesc, false);
+    if (status == ResultStatus::OK) {
+        _hidl_cb(status, connection, connectionId, *fmqDesc);
+    } else {
+        _hidl_cb(status, nullptr, -1LL,
+                 android::hardware::MQDescriptorSync<BufferStatusMessage>(
+                         std::vector<android::hardware::GrantorDescriptor>(),
+                         nullptr /* nhandle */, 0 /* size */));
+    }
+    return Void();
+}
+
+Accessor::Accessor(const std::shared_ptr<BufferPoolAllocator> &allocator)
+    : mImpl(new Impl(allocator)) {}
+
+Accessor::~Accessor() {
+}
+
+bool Accessor::isValid() {
+    return (bool)mImpl;
+}
+
+ResultStatus Accessor::allocate(
+        ConnectionId connectionId,
+        const std::vector<uint8_t> &params,
+        BufferId *bufferId, const native_handle_t** handle) {
+    if (mImpl) {
+        return mImpl->allocate(connectionId, params, bufferId, handle);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus Accessor::fetch(
+        ConnectionId connectionId, TransactionId transactionId,
+        BufferId bufferId, const native_handle_t** handle) {
+    if (mImpl) {
+        return mImpl->fetch(connectionId, transactionId, bufferId, handle);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus Accessor::connect(
+        sp<Connection> *connection, ConnectionId *pConnectionId,
+        const QueueDescriptor** fmqDescPtr, bool local) {
+    if (mImpl) {
+        ResultStatus status = mImpl->connect(this, connection, pConnectionId, fmqDescPtr);
+        if (!local && status == ResultStatus::OK) {
+            sp<Accessor> accessor(this);
+            sConnectionDeathRecipient->add(*pConnectionId, accessor);
+        }
+        return status;
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus Accessor::close(ConnectionId connectionId) {
+    if (mImpl) {
+        ResultStatus status = mImpl->close(connectionId);
+        sConnectionDeathRecipient->remove(connectionId);
+        return status;
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+void Accessor::cleanUp(bool clearCache) {
+    if (mImpl) {
+        mImpl->cleanUp(clearCache);
+    }
+}
+
+//IAccessor* HIDL_FETCH_IAccessor(const char* /* name */) {
+//    return new Accessor();
+//}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
diff --git a/media/bufferpool/1.0/Accessor.h b/media/bufferpool/1.0/Accessor.h
new file mode 100644
index 0000000..2f86f7b
--- /dev/null
+++ b/media/bufferpool/1.0/Accessor.h
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_ACCESSOR_H
+#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_ACCESSOR_H
+
+#include <android/hardware/media/bufferpool/1.0/IAccessor.h>
+#include <bufferpool/BufferPoolTypes.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include "BufferStatus.h"
+
+#include <set>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct Accessor;
+struct Connection;
+
+/**
+ * Receives death notifications from remote connections.
+ * On death notifications, the connections are closed and used resources
+ * are released.
+ */
+struct ConnectionDeathRecipient : public hardware::hidl_death_recipient {
+    /**
+     * Registers a newly connected connection from remote processes.
+     */
+    void add(int64_t connectionId, const sp<Accessor> &accessor);
+
+    /**
+     * Removes a connection.
+     */
+    void remove(int64_t connectionId);
+
+    void addCookieToConnection(uint64_t cookie, int64_t connectionId);
+
+    virtual void serviceDied(
+            uint64_t /* cookie */,
+            const wp<::android::hidl::base::V1_0::IBase>& /* who */
+            ) override;
+
+private:
+    std::mutex mLock;
+    std::map<uint64_t, std::set<int64_t>>  mCookieToConnections;
+    std::map<int64_t, uint64_t> mConnectionToCookie;
+    std::map<int64_t, const wp<Accessor>> mAccessors;
+};
+
+/**
+ * A buffer pool accessor which enables a buffer pool to communicate with buffer
+ * pool clients. 1:1 correspondense holds between a buffer pool and an accessor.
+ */
+struct Accessor : public IAccessor {
+    // Methods from ::android::hardware::media::bufferpool::V1_0::IAccessor follow.
+    Return<void> connect(connect_cb _hidl_cb) override;
+
+    /**
+     * Creates a buffer pool accessor which uses the specified allocator.
+     *
+     * @param allocator buffer allocator.
+     */
+    explicit Accessor(const std::shared_ptr<BufferPoolAllocator> &allocator);
+
+    /** Destructs a buffer pool accessor. */
+    ~Accessor();
+
+    /** Returns whether the accessor is valid. */
+    bool isValid();
+
+    /** Allocates a buffer from a buffer pool.
+     *
+     * @param connectionId  the connection id of the client.
+     * @param params        the allocation parameters.
+     * @param bufferId      the id of the allocated buffer.
+     * @param handle        the native handle of the allocated buffer.
+     *
+     * @return OK when a buffer is successfully allocated.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus allocate(
+            ConnectionId connectionId,
+            const std::vector<uint8_t>& params,
+            BufferId *bufferId,
+            const native_handle_t** handle);
+
+    /**
+     * Fetches a buffer for the specified transaction.
+     *
+     * @param connectionId  the id of receiving connection(client).
+     * @param transactionId the id of the transfer transaction.
+     * @param bufferId      the id of the buffer to be fetched.
+     * @param handle        the native handle of the fetched buffer.
+     *
+     * @return OK when a buffer is successfully fetched.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus fetch(
+            ConnectionId connectionId,
+            TransactionId transactionId,
+            BufferId bufferId,
+            const native_handle_t** handle);
+
+    /**
+     * Makes a connection to the buffer pool. The buffer pool client uses the
+     * created connection in order to communicate with the buffer pool. An
+     * FMQ for buffer status message is also created for the client.
+     *
+     * @param connection    created connection
+     * @param pConnectionId the id of the created connection
+     * @param fmqDescPtr    FMQ descriptor for shared buffer status message
+     *                      queue between a buffer pool and the client.
+     * @param local         true when a connection request comes from local process,
+     *                      false otherwise.
+     *
+     * @return OK when a connection is successfully made.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus connect(
+            sp<Connection> *connection, ConnectionId *pConnectionId,
+            const QueueDescriptor** fmqDescPtr, bool local);
+
+    /**
+     * Closes the specified connection to the client.
+     *
+     * @param connectionId  the id of the connection.
+     *
+     * @return OK when the connection is closed.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus close(ConnectionId connectionId);
+
+    /**
+     * Processes pending buffer status messages and perfoms periodic cache
+     * cleaning.
+     *
+     * @param clearCache    if clearCache is true, it frees all buffers waiting
+     *                      to be recycled.
+     */
+    void cleanUp(bool clearCache);
+
+    /**
+     * Gets a hidl_death_recipient for remote connection death.
+     */
+    static sp<ConnectionDeathRecipient> getConnectionDeathRecipient();
+
+private:
+    class Impl;
+    std::unique_ptr<Impl> mImpl;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_ACCESSOR_H
diff --git a/media/bufferpool/1.0/AccessorImpl.cpp b/media/bufferpool/1.0/AccessorImpl.cpp
new file mode 100644
index 0000000..fa17f15
--- /dev/null
+++ b/media/bufferpool/1.0/AccessorImpl.cpp
@@ -0,0 +1,543 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BufferPoolAccessor"
+//#define LOG_NDEBUG 0
+
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+#include <utils/Log.h>
+#include "AccessorImpl.h"
+#include "Connection.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V1_0 {
+namespace implementation {
+
+namespace {
+    static constexpr int64_t kCleanUpDurationUs = 500000; // TODO tune 0.5 sec
+    static constexpr int64_t kLogDurationUs = 5000000; // 5 secs
+
+    static constexpr size_t kMinAllocBytesForEviction = 1024*1024*15;
+    static constexpr size_t kMinBufferCountForEviction = 40;
+}
+
+// Buffer structure in bufferpool process
+struct InternalBuffer {
+    BufferId mId;
+    size_t mOwnerCount;
+    size_t mTransactionCount;
+    const std::shared_ptr<BufferPoolAllocation> mAllocation;
+    const size_t mAllocSize;
+    const std::vector<uint8_t> mConfig;
+
+    InternalBuffer(
+            BufferId id,
+            const std::shared_ptr<BufferPoolAllocation> &alloc,
+            const size_t allocSize,
+            const std::vector<uint8_t> &allocConfig)
+            : mId(id), mOwnerCount(0), mTransactionCount(0),
+            mAllocation(alloc), mAllocSize(allocSize), mConfig(allocConfig) {}
+
+    const native_handle_t *handle() {
+        return mAllocation->handle();
+    }
+};
+
+struct TransactionStatus {
+    TransactionId mId;
+    BufferId mBufferId;
+    ConnectionId mSender;
+    ConnectionId mReceiver;
+    BufferStatus mStatus;
+    int64_t mTimestampUs;
+    bool mSenderValidated;
+
+    TransactionStatus(const BufferStatusMessage &message, int64_t timestampUs) {
+        mId = message.transactionId;
+        mBufferId = message.bufferId;
+        mStatus = message.newStatus;
+        mTimestampUs = timestampUs;
+        if (mStatus == BufferStatus::TRANSFER_TO) {
+            mSender = message.connectionId;
+            mReceiver = message.targetConnectionId;
+            mSenderValidated = true;
+        } else {
+            mSender = -1LL;
+            mReceiver = message.connectionId;
+            mSenderValidated = false;
+        }
+    }
+};
+
+// Helper template methods for handling map of set.
+template<class T, class U>
+bool insert(std::map<T, std::set<U>> *mapOfSet, T key, U value) {
+    auto iter = mapOfSet->find(key);
+    if (iter == mapOfSet->end()) {
+        std::set<U> valueSet{value};
+        mapOfSet->insert(std::make_pair(key, valueSet));
+        return true;
+    } else if (iter->second.find(value)  == iter->second.end()) {
+        iter->second.insert(value);
+        return true;
+    }
+    return false;
+}
+
+template<class T, class U>
+bool erase(std::map<T, std::set<U>> *mapOfSet, T key, U value) {
+    bool ret = false;
+    auto iter = mapOfSet->find(key);
+    if (iter != mapOfSet->end()) {
+        if (iter->second.erase(value) > 0) {
+            ret = true;
+        }
+        if (iter->second.size() == 0) {
+            mapOfSet->erase(iter);
+        }
+    }
+    return ret;
+}
+
+template<class T, class U>
+bool contains(std::map<T, std::set<U>> *mapOfSet, T key, U value) {
+    auto iter = mapOfSet->find(key);
+    if (iter != mapOfSet->end()) {
+        auto setIter = iter->second.find(value);
+        return setIter != iter->second.end();
+    }
+    return false;
+}
+
+int32_t Accessor::Impl::sPid = getpid();
+uint32_t Accessor::Impl::sSeqId = time(nullptr);
+
+Accessor::Impl::Impl(
+        const std::shared_ptr<BufferPoolAllocator> &allocator)
+        : mAllocator(allocator) {}
+
+Accessor::Impl::~Impl() {
+}
+
+ResultStatus Accessor::Impl::connect(
+        const sp<Accessor> &accessor, sp<Connection> *connection,
+        ConnectionId *pConnectionId, const QueueDescriptor** fmqDescPtr) {
+    sp<Connection> newConnection = new Connection();
+    ResultStatus status = ResultStatus::CRITICAL_ERROR;
+    {
+        std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+        if (newConnection) {
+            ConnectionId id = (int64_t)sPid << 32 | sSeqId;
+            status = mBufferPool.mObserver.open(id, fmqDescPtr);
+            if (status == ResultStatus::OK) {
+                newConnection->initialize(accessor, id);
+                *connection = newConnection;
+                *pConnectionId = id;
+                ++sSeqId;
+            }
+        }
+        mBufferPool.processStatusMessages();
+        mBufferPool.cleanUp();
+    }
+    return status;
+}
+
+ResultStatus Accessor::Impl::close(ConnectionId connectionId) {
+    std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+    mBufferPool.processStatusMessages();
+    mBufferPool.handleClose(connectionId);
+    mBufferPool.mObserver.close(connectionId);
+    // Since close# will be called after all works are finished, it is OK to
+    // evict unused buffers.
+    mBufferPool.cleanUp(true);
+    return ResultStatus::OK;
+}
+
+ResultStatus Accessor::Impl::allocate(
+        ConnectionId connectionId, const std::vector<uint8_t>& params,
+        BufferId *bufferId, const native_handle_t** handle) {
+    std::unique_lock<std::mutex> lock(mBufferPool.mMutex);
+    mBufferPool.processStatusMessages();
+    ResultStatus status = ResultStatus::OK;
+    if (!mBufferPool.getFreeBuffer(mAllocator, params, bufferId, handle)) {
+        lock.unlock();
+        std::shared_ptr<BufferPoolAllocation> alloc;
+        size_t allocSize;
+        status = mAllocator->allocate(params, &alloc, &allocSize);
+        lock.lock();
+        if (status == ResultStatus::OK) {
+            status = mBufferPool.addNewBuffer(alloc, allocSize, params, bufferId, handle);
+        }
+        ALOGV("create a buffer %d : %u %p",
+              status == ResultStatus::OK, *bufferId, *handle);
+    }
+    if (status == ResultStatus::OK) {
+        // TODO: handle ownBuffer failure
+        mBufferPool.handleOwnBuffer(connectionId, *bufferId);
+    }
+    mBufferPool.cleanUp();
+    return status;
+}
+
+ResultStatus Accessor::Impl::fetch(
+        ConnectionId connectionId, TransactionId transactionId,
+        BufferId bufferId, const native_handle_t** handle) {
+    std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+    mBufferPool.processStatusMessages();
+    auto found = mBufferPool.mTransactions.find(transactionId);
+    if (found != mBufferPool.mTransactions.end() &&
+            contains(&mBufferPool.mPendingTransactions,
+                     connectionId, transactionId)) {
+        if (found->second->mSenderValidated &&
+                found->second->mStatus == BufferStatus::TRANSFER_FROM &&
+                found->second->mBufferId == bufferId) {
+            found->second->mStatus = BufferStatus::TRANSFER_FETCH;
+            auto bufferIt = mBufferPool.mBuffers.find(bufferId);
+            if (bufferIt != mBufferPool.mBuffers.end()) {
+                mBufferPool.mStats.onBufferFetched();
+                *handle = bufferIt->second->handle();
+                return ResultStatus::OK;
+            }
+        }
+    }
+    mBufferPool.cleanUp();
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+void Accessor::Impl::cleanUp(bool clearCache) {
+    // transaction timeout, buffer cacheing TTL handling
+    std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+    mBufferPool.processStatusMessages();
+    mBufferPool.cleanUp(clearCache);
+}
+
+Accessor::Impl::Impl::BufferPool::BufferPool()
+    : mTimestampUs(getTimestampNow()),
+      mLastCleanUpUs(mTimestampUs),
+      mLastLogUs(mTimestampUs),
+      mSeq(0) {}
+
+
+// Statistics helper
+template<typename T, typename S>
+int percentage(T base, S total) {
+    return int(total ? 0.5 + 100. * static_cast<S>(base) / total : 0);
+}
+
+Accessor::Impl::Impl::BufferPool::~BufferPool() {
+    std::lock_guard<std::mutex> lock(mMutex);
+    ALOGD("Destruction - bufferpool %p "
+          "cached: %zu/%zuM, %zu/%d%% in use; "
+          "allocs: %zu, %d%% recycled; "
+          "transfers: %zu, %d%% unfetced",
+          this, mStats.mBuffersCached, mStats.mSizeCached >> 20,
+          mStats.mBuffersInUse, percentage(mStats.mBuffersInUse, mStats.mBuffersCached),
+          mStats.mTotalAllocations, percentage(mStats.mTotalRecycles, mStats.mTotalAllocations),
+          mStats.mTotalTransfers,
+          percentage(mStats.mTotalTransfers - mStats.mTotalFetches, mStats.mTotalTransfers));
+}
+
+bool Accessor::Impl::BufferPool::handleOwnBuffer(
+        ConnectionId connectionId, BufferId bufferId) {
+
+    bool added = insert(&mUsingBuffers, connectionId, bufferId);
+    if (added) {
+        auto iter = mBuffers.find(bufferId);
+        iter->second->mOwnerCount++;
+    }
+    insert(&mUsingConnections, bufferId, connectionId);
+    return added;
+}
+
+bool Accessor::Impl::BufferPool::handleReleaseBuffer(
+        ConnectionId connectionId, BufferId bufferId) {
+    bool deleted = erase(&mUsingBuffers, connectionId, bufferId);
+    if (deleted) {
+        auto iter = mBuffers.find(bufferId);
+        iter->second->mOwnerCount--;
+        if (iter->second->mOwnerCount == 0 &&
+                iter->second->mTransactionCount == 0) {
+            mStats.onBufferUnused(iter->second->mAllocSize);
+            mFreeBuffers.insert(bufferId);
+        }
+    }
+    erase(&mUsingConnections, bufferId, connectionId);
+    ALOGV("release buffer %u : %d", bufferId, deleted);
+    return deleted;
+}
+
+bool Accessor::Impl::BufferPool::handleTransferTo(const BufferStatusMessage &message) {
+    auto completed = mCompletedTransactions.find(
+            message.transactionId);
+    if (completed != mCompletedTransactions.end()) {
+        // already completed
+        mCompletedTransactions.erase(completed);
+        return true;
+    }
+    // the buffer should exist and be owned.
+    auto bufferIter = mBuffers.find(message.bufferId);
+    if (bufferIter == mBuffers.end() ||
+            !contains(&mUsingBuffers, message.connectionId, message.bufferId)) {
+        return false;
+    }
+    auto found = mTransactions.find(message.transactionId);
+    if (found != mTransactions.end()) {
+        // transfer_from was received earlier.
+        found->second->mSender = message.connectionId;
+        found->second->mSenderValidated = true;
+        return true;
+    }
+    // TODO: verify there is target connection Id
+    mStats.onBufferSent();
+    mTransactions.insert(std::make_pair(
+            message.transactionId,
+            std::make_unique<TransactionStatus>(message, mTimestampUs)));
+    insert(&mPendingTransactions, message.targetConnectionId,
+           message.transactionId);
+    bufferIter->second->mTransactionCount++;
+    return true;
+}
+
+bool Accessor::Impl::BufferPool::handleTransferFrom(const BufferStatusMessage &message) {
+    auto found = mTransactions.find(message.transactionId);
+    if (found == mTransactions.end()) {
+        // TODO: is it feasible to check ownership here?
+        mStats.onBufferSent();
+        mTransactions.insert(std::make_pair(
+                message.transactionId,
+                std::make_unique<TransactionStatus>(message, mTimestampUs)));
+        insert(&mPendingTransactions, message.connectionId,
+               message.transactionId);
+        auto bufferIter = mBuffers.find(message.bufferId);
+        bufferIter->second->mTransactionCount++;
+    } else {
+        if (message.connectionId == found->second->mReceiver) {
+            found->second->mStatus = BufferStatus::TRANSFER_FROM;
+        }
+    }
+    return true;
+}
+
+bool Accessor::Impl::BufferPool::handleTransferResult(const BufferStatusMessage &message) {
+    auto found = mTransactions.find(message.transactionId);
+    if (found != mTransactions.end()) {
+        bool deleted = erase(&mPendingTransactions, message.connectionId,
+                             message.transactionId);
+        if (deleted) {
+            if (!found->second->mSenderValidated) {
+                mCompletedTransactions.insert(message.transactionId);
+            }
+            auto bufferIter = mBuffers.find(message.bufferId);
+            if (message.newStatus == BufferStatus::TRANSFER_OK) {
+                handleOwnBuffer(message.connectionId, message.bufferId);
+            }
+            bufferIter->second->mTransactionCount--;
+            if (bufferIter->second->mOwnerCount == 0
+                && bufferIter->second->mTransactionCount == 0) {
+                mStats.onBufferUnused(bufferIter->second->mAllocSize);
+                mFreeBuffers.insert(message.bufferId);
+            }
+            mTransactions.erase(found);
+        }
+        ALOGV("transfer finished %llu %u - %d", (unsigned long long)message.transactionId,
+              message.bufferId, deleted);
+        return deleted;
+    }
+    ALOGV("transfer not found %llu %u", (unsigned long long)message.transactionId,
+          message.bufferId);
+    return false;
+}
+
+void Accessor::Impl::BufferPool::processStatusMessages() {
+    std::vector<BufferStatusMessage> messages;
+    mObserver.getBufferStatusChanges(messages);
+    mTimestampUs = getTimestampNow();
+    for (BufferStatusMessage& message: messages) {
+        bool ret = false;
+        switch (message.newStatus) {
+            case BufferStatus::NOT_USED:
+                ret = handleReleaseBuffer(
+                        message.connectionId, message.bufferId);
+                break;
+            case BufferStatus::USED:
+                // not happening
+                break;
+            case BufferStatus::TRANSFER_TO:
+                ret = handleTransferTo(message);
+                break;
+            case BufferStatus::TRANSFER_FROM:
+                ret = handleTransferFrom(message);
+                break;
+            case BufferStatus::TRANSFER_TIMEOUT:
+                // TODO
+                break;
+            case BufferStatus::TRANSFER_LOST:
+                // TODO
+                break;
+            case BufferStatus::TRANSFER_FETCH:
+                // not happening
+                break;
+            case BufferStatus::TRANSFER_OK:
+            case BufferStatus::TRANSFER_ERROR:
+                ret = handleTransferResult(message);
+                break;
+        }
+        if (ret == false) {
+            ALOGW("buffer status message processing failure - message : %d connection : %lld",
+                  message.newStatus, (long long)message.connectionId);
+        }
+    }
+    messages.clear();
+}
+
+bool Accessor::Impl::BufferPool::handleClose(ConnectionId connectionId) {
+    // Cleaning buffers
+    auto buffers = mUsingBuffers.find(connectionId);
+    if (buffers != mUsingBuffers.end()) {
+        for (const BufferId& bufferId : buffers->second) {
+            bool deleted = erase(&mUsingConnections, bufferId, connectionId);
+            if (deleted) {
+                auto bufferIter = mBuffers.find(bufferId);
+                bufferIter->second->mOwnerCount--;
+                if (bufferIter->second->mOwnerCount == 0 &&
+                        bufferIter->second->mTransactionCount == 0) {
+                    // TODO: handle freebuffer insert fail
+                    mStats.onBufferUnused(bufferIter->second->mAllocSize);
+                    mFreeBuffers.insert(bufferId);
+                }
+            }
+        }
+        mUsingBuffers.erase(buffers);
+    }
+
+    // Cleaning transactions
+    auto pending = mPendingTransactions.find(connectionId);
+    if (pending != mPendingTransactions.end()) {
+        for (const TransactionId& transactionId : pending->second) {
+            auto iter = mTransactions.find(transactionId);
+            if (iter != mTransactions.end()) {
+                if (!iter->second->mSenderValidated) {
+                    mCompletedTransactions.insert(transactionId);
+                }
+                BufferId bufferId = iter->second->mBufferId;
+                auto bufferIter = mBuffers.find(bufferId);
+                bufferIter->second->mTransactionCount--;
+                if (bufferIter->second->mOwnerCount == 0 &&
+                    bufferIter->second->mTransactionCount == 0) {
+                    // TODO: handle freebuffer insert fail
+                    mStats.onBufferUnused(bufferIter->second->mAllocSize);
+                    mFreeBuffers.insert(bufferId);
+                }
+                mTransactions.erase(iter);
+            }
+        }
+    }
+    return true;
+}
+
+bool Accessor::Impl::BufferPool::getFreeBuffer(
+        const std::shared_ptr<BufferPoolAllocator> &allocator,
+        const std::vector<uint8_t> &params, BufferId *pId,
+        const native_handle_t** handle) {
+    auto bufferIt = mFreeBuffers.begin();
+    for (;bufferIt != mFreeBuffers.end(); ++bufferIt) {
+        BufferId bufferId = *bufferIt;
+        if (allocator->compatible(params, mBuffers[bufferId]->mConfig)) {
+            break;
+        }
+    }
+    if (bufferIt != mFreeBuffers.end()) {
+        BufferId id = *bufferIt;
+        mFreeBuffers.erase(bufferIt);
+        mStats.onBufferRecycled(mBuffers[id]->mAllocSize);
+        *handle = mBuffers[id]->handle();
+        *pId = id;
+        ALOGV("recycle a buffer %u %p", id, *handle);
+        return true;
+    }
+    return false;
+}
+
+ResultStatus Accessor::Impl::BufferPool::addNewBuffer(
+        const std::shared_ptr<BufferPoolAllocation> &alloc,
+        const size_t allocSize,
+        const std::vector<uint8_t> &params,
+        BufferId *pId,
+        const native_handle_t** handle) {
+
+    BufferId bufferId = mSeq++;
+    if (mSeq == Connection::SYNC_BUFFERID) {
+        mSeq = 0;
+    }
+    std::unique_ptr<InternalBuffer> buffer =
+            std::make_unique<InternalBuffer>(
+                    bufferId, alloc, allocSize, params);
+    if (buffer) {
+        auto res = mBuffers.insert(std::make_pair(
+                bufferId, std::move(buffer)));
+        if (res.second) {
+            mStats.onBufferAllocated(allocSize);
+            *handle = alloc->handle();
+            *pId = bufferId;
+            return ResultStatus::OK;
+        }
+    }
+    return ResultStatus::NO_MEMORY;
+}
+
+void Accessor::Impl::BufferPool::cleanUp(bool clearCache) {
+    if (clearCache || mTimestampUs > mLastCleanUpUs + kCleanUpDurationUs) {
+        mLastCleanUpUs = mTimestampUs;
+        if (mTimestampUs > mLastLogUs + kLogDurationUs) {
+            mLastLogUs = mTimestampUs;
+            ALOGD("bufferpool %p : %zu(%zu size) total buffers - "
+                  "%zu(%zu size) used buffers - %zu/%zu (recycle/alloc) - "
+                  "%zu/%zu (fetch/transfer)",
+                  this, mStats.mBuffersCached, mStats.mSizeCached,
+                  mStats.mBuffersInUse, mStats.mSizeInUse,
+                  mStats.mTotalRecycles, mStats.mTotalAllocations,
+                  mStats.mTotalFetches, mStats.mTotalTransfers);
+        }
+        for (auto freeIt = mFreeBuffers.begin(); freeIt != mFreeBuffers.end();) {
+            if (!clearCache && mStats.mSizeCached < kMinAllocBytesForEviction
+                    && mBuffers.size() < kMinBufferCountForEviction) {
+                break;
+            }
+            auto it = mBuffers.find(*freeIt);
+            if (it != mBuffers.end() &&
+                    it->second->mOwnerCount == 0 && it->second->mTransactionCount == 0) {
+                mStats.onBufferEvicted(it->second->mAllocSize);
+                mBuffers.erase(it);
+                freeIt = mFreeBuffers.erase(freeIt);
+            } else {
+                ++freeIt;
+                ALOGW("bufferpool inconsistent!");
+            }
+        }
+    }
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
diff --git a/media/bufferpool/1.0/AccessorImpl.h b/media/bufferpool/1.0/AccessorImpl.h
new file mode 100644
index 0000000..c04dbf3
--- /dev/null
+++ b/media/bufferpool/1.0/AccessorImpl.h
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_ACCESSORIMPL_H
+#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_ACCESSORIMPL_H
+
+#include <map>
+#include <set>
+#include "Accessor.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V1_0 {
+namespace implementation {
+
+struct InternalBuffer;
+struct TransactionStatus;
+
+/**
+ * An implementation of a buffer pool accessor(or a buffer pool implementation.) */
+class Accessor::Impl {
+public:
+    Impl(const std::shared_ptr<BufferPoolAllocator> &allocator);
+
+    ~Impl();
+
+    ResultStatus connect(
+            const sp<Accessor> &accessor, sp<Connection> *connection,
+            ConnectionId *pConnectionId, const QueueDescriptor** fmqDescPtr);
+
+    ResultStatus close(ConnectionId connectionId);
+
+    ResultStatus allocate(ConnectionId connectionId,
+                          const std::vector<uint8_t>& params,
+                          BufferId *bufferId,
+                          const native_handle_t** handle);
+
+    ResultStatus fetch(ConnectionId connectionId,
+                       TransactionId transactionId,
+                       BufferId bufferId,
+                       const native_handle_t** handle);
+
+    void cleanUp(bool clearCache);
+
+private:
+    // ConnectionId = pid : (timestamp_created + seqId)
+    // in order to guarantee uniqueness for each connection
+    static uint32_t sSeqId;
+    static int32_t sPid;
+
+    const std::shared_ptr<BufferPoolAllocator> mAllocator;
+
+    /**
+     * Buffer pool implementation.
+     *
+     * Handles buffer status messages. Handles buffer allocation/recycling.
+     * Handles buffer transfer between buffer pool clients.
+     */
+    struct BufferPool {
+    private:
+        std::mutex mMutex;
+        int64_t mTimestampUs;
+        int64_t mLastCleanUpUs;
+        int64_t mLastLogUs;
+        BufferId mSeq;
+        BufferStatusObserver mObserver;
+
+        std::map<ConnectionId, std::set<BufferId>> mUsingBuffers;
+        std::map<BufferId, std::set<ConnectionId>> mUsingConnections;
+
+        std::map<ConnectionId, std::set<TransactionId>> mPendingTransactions;
+        // Transactions completed before TRANSFER_TO message arrival.
+        // Fetch does not occur for the transactions.
+        // Only transaction id is kept for the transactions in short duration.
+        std::set<TransactionId> mCompletedTransactions;
+        // Currently active(pending) transations' status & information.
+        std::map<TransactionId, std::unique_ptr<TransactionStatus>>
+                mTransactions;
+
+        std::map<BufferId, std::unique_ptr<InternalBuffer>> mBuffers;
+        std::set<BufferId> mFreeBuffers;
+
+        /// Buffer pool statistics which tracks allocation and transfer statistics.
+        struct Stats {
+            /// Total size of allocations which are used or available to use.
+            /// (bytes or pixels)
+            size_t mSizeCached;
+            /// # of cached buffers which are used or available to use.
+            size_t mBuffersCached;
+            /// Total size of allocations which are currently used. (bytes or pixels)
+            size_t mSizeInUse;
+            /// # of currently used buffers
+            size_t mBuffersInUse;
+
+            /// # of allocations called on bufferpool. (# of fetched from BlockPool)
+            size_t mTotalAllocations;
+            /// # of allocations that were served from the cache.
+            /// (# of allocator alloc prevented)
+            size_t mTotalRecycles;
+            /// # of buffer transfers initiated.
+            size_t mTotalTransfers;
+            /// # of transfers that had to be fetched.
+            size_t mTotalFetches;
+
+            Stats()
+                : mSizeCached(0), mBuffersCached(0), mSizeInUse(0), mBuffersInUse(0),
+                  mTotalAllocations(0), mTotalRecycles(0), mTotalTransfers(0), mTotalFetches(0) {}
+
+            /// A new buffer is allocated on an allocation request.
+            void onBufferAllocated(size_t allocSize) {
+                mSizeCached += allocSize;
+                mBuffersCached++;
+
+                mSizeInUse += allocSize;
+                mBuffersInUse++;
+
+                mTotalAllocations++;
+            }
+
+            /// A buffer is evicted and destroyed.
+            void onBufferEvicted(size_t allocSize) {
+                mSizeCached -= allocSize;
+                mBuffersCached--;
+            }
+
+            /// A buffer is recycled on an allocation request.
+            void onBufferRecycled(size_t allocSize) {
+                mSizeInUse += allocSize;
+                mBuffersInUse++;
+
+                mTotalAllocations++;
+                mTotalRecycles++;
+            }
+
+            /// A buffer is available to be recycled.
+            void onBufferUnused(size_t allocSize) {
+                mSizeInUse -= allocSize;
+                mBuffersInUse--;
+            }
+
+            /// A buffer transfer is initiated.
+            void onBufferSent() {
+                mTotalTransfers++;
+            }
+
+            /// A buffer fetch is invoked by a buffer transfer.
+            void onBufferFetched() {
+                mTotalFetches++;
+            }
+        } mStats;
+
+    public:
+        /** Creates a buffer pool. */
+        BufferPool();
+
+        /** Destroys a buffer pool. */
+        ~BufferPool();
+
+        /**
+         * Processes all pending buffer status messages, and returns the result.
+         * Each status message is handled by methods with 'handle' prefix.
+         */
+        void processStatusMessages();
+
+        /**
+         * Handles a buffer being owned by a connection.
+         *
+         * @param connectionId  the id of the buffer owning connection.
+         * @param bufferId      the id of the buffer.
+         *
+         * @return {@code true} when the buffer is owned,
+         *         {@code false} otherwise.
+         */
+        bool handleOwnBuffer(ConnectionId connectionId, BufferId bufferId);
+
+        /**
+         * Handles a buffer being released by a connection.
+         *
+         * @param connectionId  the id of the buffer owning connection.
+         * @param bufferId      the id of the buffer.
+         *
+         * @return {@code true} when the buffer ownership is released,
+         *         {@code false} otherwise.
+         */
+        bool handleReleaseBuffer(ConnectionId connectionId, BufferId bufferId);
+
+        /**
+         * Handles a transfer transaction start message from the sender.
+         *
+         * @param message   a buffer status message for the transaction.
+         *
+         * @result {@code true} when transfer_to message is acknowledged,
+         *         {@code false} otherwise.
+         */
+        bool handleTransferTo(const BufferStatusMessage &message);
+
+        /**
+         * Handles a transfer transaction being acked by the receiver.
+         *
+         * @param message   a buffer status message for the transaction.
+         *
+         * @result {@code true} when transfer_from message is acknowledged,
+         *         {@code false} otherwise.
+         */
+        bool handleTransferFrom(const BufferStatusMessage &message);
+
+        /**
+         * Handles a transfer transaction result message from the receiver.
+         *
+         * @param message   a buffer status message for the transaction.
+         *
+         * @result {@code true} when the exisitng transaction is finished,
+         *         {@code false} otherwise.
+         */
+        bool handleTransferResult(const BufferStatusMessage &message);
+
+        /**
+         * Handles a connection being closed, and returns the result. All the
+         * buffers and transactions owned by the connection will be cleaned up.
+         * The related FMQ will be cleaned up too.
+         *
+         * @param connectionId  the id of the connection.
+         *
+         * @result {@code true} when the connection existed,
+         *         {@code false} otherwise.
+         */
+        bool handleClose(ConnectionId connectionId);
+
+        /**
+         * Recycles a existing free buffer if it is possible.
+         *
+         * @param allocator the buffer allocator
+         * @param params    the allocation parameters.
+         * @param pId       the id of the recycled buffer.
+         * @param handle    the native handle of the recycled buffer.
+         *
+         * @return {@code true} when a buffer is recycled, {@code false}
+         *         otherwise.
+         */
+        bool getFreeBuffer(
+                const std::shared_ptr<BufferPoolAllocator> &allocator,
+                const std::vector<uint8_t> &params,
+                BufferId *pId, const native_handle_t **handle);
+
+        /**
+         * Adds a newly allocated buffer to bufferpool.
+         *
+         * @param alloc     the newly allocated buffer.
+         * @param allocSize the size of the newly allocated buffer.
+         * @param params    the allocation parameters.
+         * @param pId       the buffer id for the newly allocated buffer.
+         * @param handle    the native handle for the newly allocated buffer.
+         *
+         * @return OK when an allocation is successfully allocated.
+         *         NO_MEMORY when there is no memory.
+         *         CRITICAL_ERROR otherwise.
+         */
+        ResultStatus addNewBuffer(
+                const std::shared_ptr<BufferPoolAllocation> &alloc,
+                const size_t allocSize,
+                const std::vector<uint8_t> &params,
+                BufferId *pId,
+                const native_handle_t **handle);
+
+        /**
+         * Processes pending buffer status messages and performs periodic cache
+         * cleaning.
+         *
+         * @param clearCache    if clearCache is true, it frees all buffers
+         *                      waiting to be recycled.
+         */
+        void cleanUp(bool clearCache = false);
+
+        friend class Accessor::Impl;
+    } mBufferPool;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace ufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_ACCESSORIMPL_H
diff --git a/media/bufferpool/1.0/Android.bp b/media/bufferpool/1.0/Android.bp
new file mode 100644
index 0000000..c7ea70f
--- /dev/null
+++ b/media/bufferpool/1.0/Android.bp
@@ -0,0 +1,29 @@
+cc_library {
+    name: "libstagefright_bufferpool@1.0",
+    vendor_available: true,
+    srcs: [
+        "Accessor.cpp",
+        "AccessorImpl.cpp",
+        "BufferPoolClient.cpp",
+        "BufferStatus.cpp",
+        "ClientManager.cpp",
+        "Connection.cpp",
+    ],
+    export_include_dirs: [
+        "include",
+    ],
+    shared_libs: [
+        "libcutils",
+        "libfmq",
+        "libhidlbase",
+        "libhwbinder",
+        "libhidltransport",
+        "liblog",
+        "libutils",
+        "android.hardware.media.bufferpool@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libfmq",
+        "android.hardware.media.bufferpool@1.0",
+    ],
+}
diff --git a/media/bufferpool/1.0/BufferPoolClient.cpp b/media/bufferpool/1.0/BufferPoolClient.cpp
new file mode 100644
index 0000000..d712398
--- /dev/null
+++ b/media/bufferpool/1.0/BufferPoolClient.cpp
@@ -0,0 +1,712 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BufferPoolClient"
+//#define LOG_NDEBUG 0
+
+#include <thread>
+#include <utils/Log.h>
+#include "BufferPoolClient.h"
+#include "Connection.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V1_0 {
+namespace implementation {
+
+static constexpr int64_t kReceiveTimeoutUs = 1000000; // 100ms
+static constexpr int kPostMaxRetry = 3;
+static constexpr int kCacheTtlUs = 1000000; // TODO: tune
+
+class BufferPoolClient::Impl
+        : public std::enable_shared_from_this<BufferPoolClient::Impl> {
+public:
+    explicit Impl(const sp<Accessor> &accessor);
+
+    explicit Impl(const sp<IAccessor> &accessor);
+
+    bool isValid() {
+        return mValid;
+    }
+
+    bool isLocal() {
+        return mValid && mLocal;
+    }
+
+    ConnectionId getConnectionId() {
+        return mConnectionId;
+    }
+
+    sp<IAccessor> &getAccessor() {
+        return mAccessor;
+    }
+
+    bool isActive(int64_t *lastTransactionUs, bool clearCache);
+
+    ResultStatus allocate(const std::vector<uint8_t> &params,
+                          native_handle_t **handle,
+                          std::shared_ptr<BufferPoolData> *buffer);
+
+    ResultStatus receive(
+            TransactionId transactionId, BufferId bufferId,
+            int64_t timestampUs,
+            native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer);
+
+    void postBufferRelease(BufferId bufferId);
+
+    bool postSend(
+            BufferId bufferId, ConnectionId receiver,
+            TransactionId *transactionId, int64_t *timestampUs);
+private:
+
+    bool postReceive(
+            BufferId bufferId, TransactionId transactionId,
+            int64_t timestampUs);
+
+    bool postReceiveResult(
+            BufferId bufferId, TransactionId transactionId, bool result, bool *needsSync);
+
+    void trySyncFromRemote();
+
+    bool syncReleased();
+
+    void evictCaches(bool clearCache = false);
+
+    ResultStatus allocateBufferHandle(
+            const std::vector<uint8_t>& params, BufferId *bufferId,
+            native_handle_t **handle);
+
+    ResultStatus fetchBufferHandle(
+            TransactionId transactionId, BufferId bufferId,
+            native_handle_t **handle);
+
+    struct BlockPoolDataDtor;
+    struct ClientBuffer;
+
+    bool mLocal;
+    bool mValid;
+    sp<IAccessor> mAccessor;
+    sp<Connection> mLocalConnection;
+    sp<IConnection> mRemoteConnection;
+    uint32_t mSeqId;
+    ConnectionId mConnectionId;
+    int64_t mLastEvictCacheUs;
+
+    // CachedBuffers
+    struct BufferCache {
+        std::mutex mLock;
+        bool mCreating;
+        std::condition_variable mCreateCv;
+        std::map<BufferId, std::unique_ptr<ClientBuffer>> mBuffers;
+        int mActive;
+        int64_t mLastChangeUs;
+
+        BufferCache() : mCreating(false), mActive(0), mLastChangeUs(getTimestampNow()) {}
+
+        void incActive_l() {
+            ++mActive;
+            mLastChangeUs = getTimestampNow();
+        }
+
+        void decActive_l() {
+            --mActive;
+            mLastChangeUs = getTimestampNow();
+        }
+    } mCache;
+
+    // FMQ - release notifier
+    struct {
+        std::mutex mLock;
+        // TODO: use only one list?(using one list may dealy sending messages?)
+        std::list<BufferId> mReleasingIds;
+        std::list<BufferId> mReleasedIds;
+        std::unique_ptr<BufferStatusChannel> mStatusChannel;
+    } mReleasing;
+
+    // This lock is held during synchronization from remote side.
+    // In order to minimize remote calls and locking durtaion, this lock is held
+    // by best effort approach using try_lock().
+    std::mutex mRemoteSyncLock;
+};
+
+struct BufferPoolClient::Impl::BlockPoolDataDtor {
+    BlockPoolDataDtor(const std::shared_ptr<BufferPoolClient::Impl> &impl)
+            : mImpl(impl) {}
+
+    void operator()(BufferPoolData *buffer) {
+        BufferId id = buffer->mId;
+        delete buffer;
+
+        auto impl = mImpl.lock();
+        if (impl && impl->isValid()) {
+            impl->postBufferRelease(id);
+        }
+    }
+    const std::weak_ptr<BufferPoolClient::Impl> mImpl;
+};
+
+struct BufferPoolClient::Impl::ClientBuffer {
+private:
+    bool mInvalidated; // TODO: implement
+    int64_t mExpireUs;
+    bool mHasCache;
+    ConnectionId mConnectionId;
+    BufferId mId;
+    native_handle_t *mHandle;
+    std::weak_ptr<BufferPoolData> mCache;
+
+    void updateExpire() {
+        mExpireUs = getTimestampNow() + kCacheTtlUs;
+    }
+
+public:
+    ClientBuffer(
+            ConnectionId connectionId, BufferId id, native_handle_t *handle)
+            : mInvalidated(false), mHasCache(false),
+              mConnectionId(connectionId), mId(id), mHandle(handle) {
+        (void)mInvalidated;
+        mExpireUs = getTimestampNow() + kCacheTtlUs;
+    }
+
+    ~ClientBuffer() {
+        if (mHandle) {
+            native_handle_close(mHandle);
+            native_handle_delete(mHandle);
+        }
+    }
+
+    bool expire() const {
+        int64_t now = getTimestampNow();
+        return now >= mExpireUs;
+    }
+
+    bool hasCache() const {
+        return mHasCache;
+    }
+
+    std::shared_ptr<BufferPoolData> fetchCache(native_handle_t **pHandle) {
+        if (mHasCache) {
+            std::shared_ptr<BufferPoolData> cache = mCache.lock();
+            if (cache) {
+                *pHandle = mHandle;
+            }
+            return cache;
+        }
+        return nullptr;
+    }
+
+    std::shared_ptr<BufferPoolData> createCache(
+            const std::shared_ptr<BufferPoolClient::Impl> &impl,
+            native_handle_t **pHandle) {
+        if (!mHasCache) {
+            // Allocates a raw ptr in order to avoid sending #postBufferRelease
+            // from deleter, in case of native_handle_clone failure.
+            BufferPoolData *ptr = new BufferPoolData(mConnectionId, mId);
+            if (ptr) {
+                std::shared_ptr<BufferPoolData> cache(ptr, BlockPoolDataDtor(impl));
+                if (cache) {
+                    mCache = cache;
+                    mHasCache = true;
+                    *pHandle = mHandle;
+                    return cache;
+                }
+            }
+            if (ptr) {
+                delete ptr;
+            }
+        }
+        return nullptr;
+    }
+
+    bool onCacheRelease() {
+        if (mHasCache) {
+            // TODO: verify mCache is not valid;
+            updateExpire();
+            mHasCache = false;
+            return true;
+        }
+        return false;
+    }
+};
+
+BufferPoolClient::Impl::Impl(const sp<Accessor> &accessor)
+    : mLocal(true), mValid(false), mAccessor(accessor), mSeqId(0),
+      mLastEvictCacheUs(getTimestampNow()) {
+    const QueueDescriptor *fmqDesc;
+    ResultStatus status = accessor->connect(
+            &mLocalConnection, &mConnectionId, &fmqDesc, true);
+    if (status == ResultStatus::OK) {
+        mReleasing.mStatusChannel =
+                std::make_unique<BufferStatusChannel>(*fmqDesc);
+        mValid = mReleasing.mStatusChannel &&
+                mReleasing.mStatusChannel->isValid();
+    }
+}
+
+BufferPoolClient::Impl::Impl(const sp<IAccessor> &accessor)
+    : mLocal(false), mValid(false), mAccessor(accessor), mSeqId(0),
+      mLastEvictCacheUs(getTimestampNow()) {
+    bool valid = false;
+    sp<IConnection>& outConnection = mRemoteConnection;
+    ConnectionId& id = mConnectionId;
+    std::unique_ptr<BufferStatusChannel>& outChannel =
+            mReleasing.mStatusChannel;
+    Return<void> transResult = accessor->connect(
+            [&valid, &outConnection, &id, &outChannel]
+            (ResultStatus status, sp<IConnection> connection,
+             ConnectionId connectionId, const QueueDescriptor& desc) {
+                if (status == ResultStatus::OK) {
+                    outConnection = connection;
+                    id = connectionId;
+                    outChannel = std::make_unique<BufferStatusChannel>(desc);
+                    if (outChannel && outChannel->isValid()) {
+                        valid = true;
+                    }
+                }
+            });
+    mValid = transResult.isOk() && valid;
+}
+
+bool BufferPoolClient::Impl::isActive(int64_t *lastTransactionUs, bool clearCache) {
+    bool active = false;
+    {
+        std::lock_guard<std::mutex> lock(mCache.mLock);
+        syncReleased();
+        evictCaches(clearCache);
+        *lastTransactionUs = mCache.mLastChangeUs;
+        active = mCache.mActive > 0;
+    }
+    if (mValid && mLocal && mLocalConnection) {
+        mLocalConnection->cleanUp(clearCache);
+        return true;
+    }
+    return active;
+}
+
+ResultStatus BufferPoolClient::Impl::allocate(
+        const std::vector<uint8_t> &params,
+        native_handle_t **pHandle,
+        std::shared_ptr<BufferPoolData> *buffer) {
+    if (!mLocal || !mLocalConnection || !mValid) {
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    BufferId bufferId;
+    native_handle_t *handle = nullptr;
+    buffer->reset();
+    ResultStatus status = allocateBufferHandle(params, &bufferId, &handle);
+    if (status == ResultStatus::OK) {
+        if (handle) {
+            std::unique_lock<std::mutex> lock(mCache.mLock);
+            syncReleased();
+            evictCaches();
+            auto cacheIt = mCache.mBuffers.find(bufferId);
+            if (cacheIt != mCache.mBuffers.end()) {
+                // TODO: verify it is recycled. (not having active ref)
+                mCache.mBuffers.erase(cacheIt);
+            }
+            auto clientBuffer = std::make_unique<ClientBuffer>(
+                    mConnectionId, bufferId, handle);
+            if (clientBuffer) {
+                auto result = mCache.mBuffers.insert(std::make_pair(
+                        bufferId, std::move(clientBuffer)));
+                if (result.second) {
+                    *buffer = result.first->second->createCache(
+                            shared_from_this(), pHandle);
+                    if (*buffer) {
+                        mCache.incActive_l();
+                    }
+                }
+            }
+        }
+        if (!*buffer) {
+            ALOGV("client cache creation failure %d: %lld",
+                  handle != nullptr, (long long)mConnectionId);
+            status = ResultStatus::NO_MEMORY;
+            postBufferRelease(bufferId);
+        }
+    }
+    return status;
+}
+
+ResultStatus BufferPoolClient::Impl::receive(
+        TransactionId transactionId, BufferId bufferId, int64_t timestampUs,
+        native_handle_t **pHandle,
+        std::shared_ptr<BufferPoolData> *buffer) {
+    if (!mValid) {
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    if (timestampUs != 0) {
+        timestampUs += kReceiveTimeoutUs;
+    }
+    if (!postReceive(bufferId, transactionId, timestampUs)) {
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    ResultStatus status = ResultStatus::CRITICAL_ERROR;
+    buffer->reset();
+    while(1) {
+        std::unique_lock<std::mutex> lock(mCache.mLock);
+        syncReleased();
+        evictCaches();
+        auto cacheIt = mCache.mBuffers.find(bufferId);
+        if (cacheIt != mCache.mBuffers.end()) {
+            if (cacheIt->second->hasCache()) {
+                *buffer = cacheIt->second->fetchCache(pHandle);
+                if (!*buffer) {
+                    // check transfer time_out
+                    lock.unlock();
+                    std::this_thread::yield();
+                    continue;
+                }
+                ALOGV("client receive from reference %lld", (long long)mConnectionId);
+                break;
+            } else {
+                *buffer = cacheIt->second->createCache(shared_from_this(), pHandle);
+                if (*buffer) {
+                    mCache.incActive_l();
+                }
+                ALOGV("client receive from cache %lld", (long long)mConnectionId);
+                break;
+            }
+        } else {
+            if (!mCache.mCreating) {
+                mCache.mCreating = true;
+                lock.unlock();
+                native_handle_t* handle = nullptr;
+                status = fetchBufferHandle(transactionId, bufferId, &handle);
+                lock.lock();
+                if (status == ResultStatus::OK) {
+                    if (handle) {
+                        auto clientBuffer = std::make_unique<ClientBuffer>(
+                                mConnectionId, bufferId, handle);
+                        if (clientBuffer) {
+                            auto result = mCache.mBuffers.insert(
+                                    std::make_pair(bufferId, std::move(
+                                            clientBuffer)));
+                            if (result.second) {
+                                *buffer = result.first->second->createCache(
+                                        shared_from_this(), pHandle);
+                                if (*buffer) {
+                                    mCache.incActive_l();
+                                }
+                            }
+                        }
+                    }
+                    if (!*buffer) {
+                        status = ResultStatus::NO_MEMORY;
+                    }
+                }
+                mCache.mCreating = false;
+                lock.unlock();
+                mCache.mCreateCv.notify_all();
+                break;
+            }
+            mCache.mCreateCv.wait(lock);
+        }
+    }
+    bool needsSync = false;
+    bool posted = postReceiveResult(bufferId, transactionId,
+                                      *buffer ? true : false, &needsSync);
+    ALOGV("client receive %lld - %u : %s (%d)", (long long)mConnectionId, bufferId,
+          *buffer ? "ok" : "fail", posted);
+    if (mValid && mLocal && mLocalConnection) {
+        mLocalConnection->cleanUp(false);
+    }
+    if (needsSync && mRemoteConnection) {
+        trySyncFromRemote();
+    }
+    if (*buffer) {
+        if (!posted) {
+            buffer->reset();
+            return ResultStatus::CRITICAL_ERROR;
+        }
+        return ResultStatus::OK;
+    }
+    return status;
+}
+
+
+void BufferPoolClient::Impl::postBufferRelease(BufferId bufferId) {
+    std::lock_guard<std::mutex> lock(mReleasing.mLock);
+    mReleasing.mReleasingIds.push_back(bufferId);
+    mReleasing.mStatusChannel->postBufferRelease(
+            mConnectionId, mReleasing.mReleasingIds, mReleasing.mReleasedIds);
+}
+
+// TODO: revise ad-hoc posting data structure
+bool BufferPoolClient::Impl::postSend(
+        BufferId bufferId, ConnectionId receiver,
+        TransactionId *transactionId, int64_t *timestampUs) {
+    bool ret = false;
+    bool needsSync = false;
+    {
+        std::lock_guard<std::mutex> lock(mReleasing.mLock);
+        *timestampUs = getTimestampNow();
+        *transactionId = (mConnectionId << 32) | mSeqId++;
+        // TODO: retry, add timeout, target?
+        ret =  mReleasing.mStatusChannel->postBufferStatusMessage(
+                *transactionId, bufferId, BufferStatus::TRANSFER_TO, mConnectionId,
+                receiver, mReleasing.mReleasingIds, mReleasing.mReleasedIds);
+        needsSync = !mLocal && mReleasing.mStatusChannel->needsSync();
+    }
+    if (mValid && mLocal && mLocalConnection) {
+        mLocalConnection->cleanUp(false);
+    }
+    if (needsSync && mRemoteConnection) {
+        trySyncFromRemote();
+    }
+    return ret;
+}
+
+bool BufferPoolClient::Impl::postReceive(
+        BufferId bufferId, TransactionId transactionId, int64_t timestampUs) {
+    for (int i = 0; i < kPostMaxRetry; ++i) {
+        std::unique_lock<std::mutex> lock(mReleasing.mLock);
+        int64_t now = getTimestampNow();
+        if (timestampUs == 0 || now < timestampUs) {
+            bool result = mReleasing.mStatusChannel->postBufferStatusMessage(
+                    transactionId, bufferId, BufferStatus::TRANSFER_FROM,
+                    mConnectionId, -1, mReleasing.mReleasingIds,
+                    mReleasing.mReleasedIds);
+            if (result) {
+                return true;
+            }
+            lock.unlock();
+            std::this_thread::yield();
+        } else {
+            mReleasing.mStatusChannel->postBufferStatusMessage(
+                    transactionId, bufferId, BufferStatus::TRANSFER_TIMEOUT,
+                    mConnectionId, -1, mReleasing.mReleasingIds,
+                    mReleasing.mReleasedIds);
+            return false;
+        }
+    }
+    return false;
+}
+
+bool BufferPoolClient::Impl::postReceiveResult(
+        BufferId bufferId, TransactionId transactionId, bool result, bool *needsSync) {
+    std::lock_guard<std::mutex> lock(mReleasing.mLock);
+    // TODO: retry, add timeout
+    bool ret = mReleasing.mStatusChannel->postBufferStatusMessage(
+            transactionId, bufferId,
+            result ? BufferStatus::TRANSFER_OK : BufferStatus::TRANSFER_ERROR,
+            mConnectionId, -1, mReleasing.mReleasingIds,
+            mReleasing.mReleasedIds);
+    *needsSync = !mLocal && mReleasing.mStatusChannel->needsSync();
+    return ret;
+}
+
+void BufferPoolClient::Impl::trySyncFromRemote() {
+    if (mRemoteSyncLock.try_lock()) {
+        bool needsSync = false;
+        {
+            std::lock_guard<std::mutex> lock(mReleasing.mLock);
+            needsSync = mReleasing.mStatusChannel->needsSync();
+        }
+        if (needsSync) {
+            TransactionId transactionId = (mConnectionId << 32);
+            BufferId bufferId = Connection::SYNC_BUFFERID;
+            Return<void> transResult = mRemoteConnection->fetch(
+                    transactionId, bufferId,
+                    []
+                    (ResultStatus outStatus, Buffer outBuffer) {
+                        (void) outStatus;
+                        (void) outBuffer;
+                    });
+            if(!transResult.isOk()) {
+                ALOGD("sync from client %lld failed: bufferpool process died.",
+                      (long long)mConnectionId);
+            }
+        }
+        mRemoteSyncLock.unlock();
+    }
+}
+
+// should have mCache.mLock
+bool BufferPoolClient::Impl::syncReleased() {
+    std::lock_guard<std::mutex> lock(mReleasing.mLock);
+    if (mReleasing.mReleasingIds.size() > 0) {
+        mReleasing.mStatusChannel->postBufferRelease(
+                mConnectionId, mReleasing.mReleasingIds,
+                mReleasing.mReleasedIds);
+    }
+    if (mReleasing.mReleasedIds.size() > 0) {
+        for (BufferId& id: mReleasing.mReleasedIds) {
+            ALOGV("client release buffer %lld - %u", (long long)mConnectionId, id);
+            auto found = mCache.mBuffers.find(id);
+            if (found != mCache.mBuffers.end()) {
+                if (found->second->onCacheRelease()) {
+                    mCache.decActive_l();
+                } else {
+                    // should not happen!
+                    ALOGW("client %lld cache release status inconsitent!",
+                          (long long)mConnectionId);
+                }
+            } else {
+                // should not happen!
+                ALOGW("client %lld cache status inconsitent!", (long long)mConnectionId);
+            }
+        }
+        mReleasing.mReleasedIds.clear();
+        return true;
+    }
+    return false;
+}
+
+// should have mCache.mLock
+void BufferPoolClient::Impl::evictCaches(bool clearCache) {
+    int64_t now = getTimestampNow();
+    if (now >= mLastEvictCacheUs + kCacheTtlUs || clearCache) {
+        size_t evicted = 0;
+        for (auto it = mCache.mBuffers.begin(); it != mCache.mBuffers.end();) {
+            if (!it->second->hasCache() && (it->second->expire() || clearCache)) {
+                it = mCache.mBuffers.erase(it);
+                ++evicted;
+            } else {
+                ++it;
+            }
+        }
+        ALOGV("cache count %lld : total %zu, active %d, evicted %zu",
+              (long long)mConnectionId, mCache.mBuffers.size(), mCache.mActive, evicted);
+        mLastEvictCacheUs = now;
+    }
+}
+
+ResultStatus BufferPoolClient::Impl::allocateBufferHandle(
+        const std::vector<uint8_t>& params, BufferId *bufferId,
+        native_handle_t** handle) {
+    if (mLocalConnection) {
+        const native_handle_t* allocHandle = nullptr;
+        ResultStatus status = mLocalConnection->allocate(
+                params, bufferId, &allocHandle);
+        if (status == ResultStatus::OK) {
+            *handle = native_handle_clone(allocHandle);
+        }
+        ALOGV("client allocate result %lld %d : %u clone %p",
+              (long long)mConnectionId, status == ResultStatus::OK,
+              *handle ? *bufferId : 0 , *handle);
+        return status;
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus BufferPoolClient::Impl::fetchBufferHandle(
+        TransactionId transactionId, BufferId bufferId,
+        native_handle_t **handle) {
+    sp<IConnection> connection;
+    if (mLocal) {
+        connection = mLocalConnection;
+    } else {
+        connection = mRemoteConnection;
+    }
+    ResultStatus status;
+    Return<void> transResult = connection->fetch(
+            transactionId, bufferId,
+            [&status, &handle]
+            (ResultStatus outStatus, Buffer outBuffer) {
+                status = outStatus;
+                if (status == ResultStatus::OK) {
+                    *handle = native_handle_clone(
+                            outBuffer.buffer.getNativeHandle());
+                }
+            });
+    return transResult.isOk() ? status : ResultStatus::CRITICAL_ERROR;
+}
+
+
+BufferPoolClient::BufferPoolClient(const sp<Accessor> &accessor) {
+    mImpl = std::make_shared<Impl>(accessor);
+}
+
+BufferPoolClient::BufferPoolClient(const sp<IAccessor> &accessor) {
+    mImpl = std::make_shared<Impl>(accessor);
+}
+
+BufferPoolClient::~BufferPoolClient() {
+    // TODO: how to handle orphaned buffers?
+}
+
+bool BufferPoolClient::isValid() {
+    return mImpl && mImpl->isValid();
+}
+
+bool BufferPoolClient::isLocal() {
+    return mImpl && mImpl->isLocal();
+}
+
+bool BufferPoolClient::isActive(int64_t *lastTransactionUs, bool clearCache) {
+    if (!isValid()) {
+        *lastTransactionUs = 0;
+        return false;
+    }
+    return mImpl->isActive(lastTransactionUs, clearCache);
+}
+
+ConnectionId BufferPoolClient::getConnectionId() {
+    if (isValid()) {
+        return mImpl->getConnectionId();
+    }
+    return -1;
+}
+
+ResultStatus BufferPoolClient::getAccessor(sp<IAccessor> *accessor) {
+    if (isValid()) {
+        *accessor = mImpl->getAccessor();
+        return ResultStatus::OK;
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus BufferPoolClient::allocate(
+        const std::vector<uint8_t> &params,
+        native_handle_t **handle,
+        std::shared_ptr<BufferPoolData> *buffer) {
+    if (isValid()) {
+        return mImpl->allocate(params, handle, buffer);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus BufferPoolClient::receive(
+        TransactionId transactionId, BufferId bufferId, int64_t timestampUs,
+        native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
+    if (isValid()) {
+        return mImpl->receive(transactionId, bufferId, timestampUs, handle, buffer);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus BufferPoolClient::postSend(
+        ConnectionId receiverId,
+        const std::shared_ptr<BufferPoolData> &buffer,
+        TransactionId *transactionId,
+        int64_t *timestampUs) {
+    if (isValid()) {
+        bool result = mImpl->postSend(
+                buffer->mId, receiverId, transactionId, timestampUs);
+        return result ? ResultStatus::OK : ResultStatus::CRITICAL_ERROR;
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
diff --git a/media/bufferpool/1.0/BufferPoolClient.h b/media/bufferpool/1.0/BufferPoolClient.h
new file mode 100644
index 0000000..577efed
--- /dev/null
+++ b/media/bufferpool/1.0/BufferPoolClient.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_BUFFERPOOLCLIENT_H
+#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_BUFFERPOOLCLIENT_H
+
+#include <memory>
+#include <android/hardware/media/bufferpool/1.0/IAccessor.h>
+#include <android/hardware/media/bufferpool/1.0/IConnection.h>
+#include <bufferpool/BufferPoolTypes.h>
+#include <cutils/native_handle.h>
+#include "Accessor.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::media::bufferpool::V1_0::IAccessor;
+using ::android::hardware::media::bufferpool::V1_0::IConnection;
+using ::android::hardware::media::bufferpool::V1_0::ResultStatus;
+using ::android::sp;
+
+/**
+ * A buffer pool client for a buffer pool. For a specific buffer pool, at most
+ * one buffer pool client exists per process. This class will not be exposed
+ * outside. A buffer pool client will be used via ClientManager.
+ */
+class BufferPoolClient {
+public:
+    /**
+     * Creates a buffer pool client from a local buffer pool
+     * (via ClientManager#create).
+     */
+    explicit BufferPoolClient(const sp<Accessor> &accessor);
+
+    /**
+     * Creates a buffer pool client from a remote buffer pool
+     * (via ClientManager#registerSender).
+     * Note: A buffer pool client created with remote buffer pool cannot
+     * allocate a buffer.
+     */
+    explicit BufferPoolClient(const sp<IAccessor> &accessor);
+
+    /** Destructs a buffer pool client. */
+    ~BufferPoolClient();
+
+private:
+    bool isValid();
+
+    bool isLocal();
+
+    bool isActive(int64_t *lastTransactionUs, bool clearCache);
+
+    ConnectionId getConnectionId();
+
+    ResultStatus getAccessor(sp<IAccessor> *accessor);
+
+    ResultStatus allocate(const std::vector<uint8_t> &params,
+                          native_handle_t **handle,
+                          std::shared_ptr<BufferPoolData> *buffer);
+
+    ResultStatus receive(TransactionId transactionId,
+                         BufferId bufferId,
+                         int64_t timestampUs,
+                         native_handle_t **handle,
+                         std::shared_ptr<BufferPoolData> *buffer);
+
+    ResultStatus postSend(ConnectionId receiver,
+                          const std::shared_ptr<BufferPoolData> &buffer,
+                          TransactionId *transactionId,
+                          int64_t *timestampUs);
+
+    class Impl;
+    std::shared_ptr<Impl> mImpl;
+
+    friend struct ClientManager;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_BUFFERPOOLCLIENT_H
diff --git a/media/bufferpool/1.0/BufferStatus.cpp b/media/bufferpool/1.0/BufferStatus.cpp
new file mode 100644
index 0000000..169abce
--- /dev/null
+++ b/media/bufferpool/1.0/BufferStatus.cpp
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BufferPoolStatus"
+//#define LOG_NDEBUG 0
+
+#include <time.h>
+#include "BufferStatus.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V1_0 {
+namespace implementation {
+
+int64_t getTimestampNow() {
+    int64_t stamp;
+    struct timespec ts;
+    // TODO: CLOCK_MONOTONIC_COARSE?
+    clock_gettime(CLOCK_MONOTONIC, &ts);
+    stamp = ts.tv_nsec / 1000;
+    stamp += (ts.tv_sec * 1000000LL);
+    return stamp;
+}
+
+static constexpr int kNumElementsInQueue = 1024*16;
+static constexpr int kMinElementsToSyncInQueue = 128;
+
+ResultStatus BufferStatusObserver::open(
+        ConnectionId id, const QueueDescriptor** fmqDescPtr) {
+    if (mBufferStatusQueues.find(id) != mBufferStatusQueues.end()) {
+        // TODO: id collision log?
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    std::unique_ptr<BufferStatusQueue> queue =
+            std::make_unique<BufferStatusQueue>(kNumElementsInQueue);
+    if (!queue || queue->isValid() == false) {
+        *fmqDescPtr = nullptr;
+        return ResultStatus::NO_MEMORY;
+    } else {
+        *fmqDescPtr = queue->getDesc();
+    }
+    auto result = mBufferStatusQueues.insert(
+            std::make_pair(id, std::move(queue)));
+    if (!result.second) {
+        *fmqDescPtr = nullptr;
+        return ResultStatus::NO_MEMORY;
+    }
+    return ResultStatus::OK;
+}
+
+ResultStatus BufferStatusObserver::close(ConnectionId id) {
+    if (mBufferStatusQueues.find(id) == mBufferStatusQueues.end()) {
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    mBufferStatusQueues.erase(id);
+    return ResultStatus::OK;
+}
+
+void BufferStatusObserver::getBufferStatusChanges(std::vector<BufferStatusMessage> &messages) {
+    for (auto it = mBufferStatusQueues.begin(); it != mBufferStatusQueues.end(); ++it) {
+        BufferStatusMessage message;
+        size_t avail = it->second->availableToRead();
+        while (avail > 0) {
+            if (!it->second->read(&message, 1)) {
+                // Since avaliable # of reads are already confirmed,
+                // this should not happen.
+                // TODO: error handling (spurious client?)
+                ALOGW("FMQ message cannot be read from %lld", (long long)it->first);
+                return;
+            }
+            message.connectionId = it->first;
+            messages.push_back(message);
+            --avail;
+        }
+    }
+}
+
+BufferStatusChannel::BufferStatusChannel(
+        const QueueDescriptor &fmqDesc) {
+    std::unique_ptr<BufferStatusQueue> queue =
+            std::make_unique<BufferStatusQueue>(fmqDesc);
+    if (!queue || queue->isValid() == false) {
+        mValid = false;
+        return;
+    }
+    mValid  = true;
+    mBufferStatusQueue = std::move(queue);
+}
+
+bool BufferStatusChannel::isValid() {
+    return mValid;
+}
+
+bool BufferStatusChannel::needsSync() {
+    if (mValid) {
+        size_t avail = mBufferStatusQueue->availableToWrite();
+        return avail + kMinElementsToSyncInQueue < kNumElementsInQueue;
+    }
+    return false;
+}
+
+void BufferStatusChannel::postBufferRelease(
+        ConnectionId connectionId,
+        std::list<BufferId> &pending, std::list<BufferId> &posted) {
+    if (mValid && pending.size() > 0) {
+        size_t avail = mBufferStatusQueue->availableToWrite();
+        avail = std::min(avail, pending.size());
+        BufferStatusMessage message;
+        for (size_t i = 0 ; i < avail; ++i) {
+            BufferId id = pending.front();
+            message.newStatus = BufferStatus::NOT_USED;
+            message.bufferId = id;
+            message.connectionId = connectionId;
+            if (!mBufferStatusQueue->write(&message, 1)) {
+                // Since avaliable # of writes are already confirmed,
+                // this should not happen.
+                // TODO: error handing?
+                ALOGW("FMQ message cannot be sent from %lld", (long long)connectionId);
+                return;
+            }
+            pending.pop_front();
+            posted.push_back(id);
+        }
+    }
+}
+
+bool BufferStatusChannel::postBufferStatusMessage(
+        TransactionId transactionId, BufferId bufferId,
+        BufferStatus status, ConnectionId connectionId, ConnectionId targetId,
+        std::list<BufferId> &pending, std::list<BufferId> &posted) {
+    if (mValid) {
+        size_t avail = mBufferStatusQueue->availableToWrite();
+        size_t numPending = pending.size();
+        if (avail >= numPending + 1) {
+            BufferStatusMessage release, message;
+            for (size_t i = 0; i < numPending; ++i) {
+                BufferId id = pending.front();
+                release.newStatus = BufferStatus::NOT_USED;
+                release.bufferId = id;
+                release.connectionId = connectionId;
+                if (!mBufferStatusQueue->write(&release, 1)) {
+                    // Since avaliable # of writes are already confirmed,
+                    // this should not happen.
+                    // TODO: error handling?
+                    ALOGW("FMQ message cannot be sent from %lld", (long long)connectionId);
+                    return false;
+                }
+                pending.pop_front();
+                posted.push_back(id);
+            }
+            message.transactionId = transactionId;
+            message.bufferId = bufferId;
+            message.newStatus = status;
+            message.connectionId = connectionId;
+            message.targetConnectionId = targetId;
+            // TODO : timesatamp
+            message.timestampUs = 0;
+            if (!mBufferStatusQueue->write(&message, 1)) {
+                // Since avaliable # of writes are already confirmed,
+                // this should not happen.
+                ALOGW("FMQ message cannot be sent from %lld", (long long)connectionId);
+                return false;
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
diff --git a/media/bufferpool/1.0/BufferStatus.h b/media/bufferpool/1.0/BufferStatus.h
new file mode 100644
index 0000000..a18a921
--- /dev/null
+++ b/media/bufferpool/1.0/BufferStatus.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_BUFFERSTATUS_H
+#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_BUFFERSTATUS_H
+
+#include <android/hardware/media/bufferpool/1.0/types.h>
+#include <bufferpool/BufferPoolTypes.h>
+#include <fmq/MessageQueue.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <memory>
+#include <mutex>
+#include <vector>
+#include <list>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V1_0 {
+namespace implementation {
+
+/** Returns monotonic timestamp in Us since fixed point in time. */
+int64_t getTimestampNow();
+
+/**
+ * A collection of FMQ for a buffer pool. buffer ownership/status change
+ * messages are sent via the FMQs from the clients.
+ */
+class BufferStatusObserver {
+private:
+    std::map<ConnectionId, std::unique_ptr<BufferStatusQueue>>
+            mBufferStatusQueues;
+
+public:
+    /** Creates an FMQ for the specified connection(client).
+     *
+     * @param connectionId  connection Id of the specified client.
+     * @param fmqDescPtr    double ptr of created FMQ's descriptor.
+     *
+     * @return OK if FMQ is created successfully.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus open(ConnectionId id, const QueueDescriptor** fmqDescPtr);
+
+    /** Closes an FMQ for the specified connection(client).
+     *
+     * @param connectionId  connection Id of the specified client.
+     *
+     * @return OK if the specified connection is closed successfully.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus close(ConnectionId id);
+
+    /** Retrieves all pending FMQ buffer status messages from clients.
+     *
+     * @param messages  retrieved pending messages.
+     */
+    void getBufferStatusChanges(std::vector<BufferStatusMessage> &messages);
+};
+
+/**
+ * An FMQ for a buffer pool client. Buffer ownership/status change messages
+ * are sent via the fmq to the buffer pool.
+ */
+class BufferStatusChannel {
+private:
+    bool mValid;
+    std::unique_ptr<BufferStatusQueue> mBufferStatusQueue;
+
+public:
+    /**
+     * Connects to an FMQ from a descriptor of the created FMQ.
+     *
+     * @param fmqDesc   Descriptor of the created FMQ.
+     */
+    BufferStatusChannel(const QueueDescriptor &fmqDesc);
+
+    /** Returns whether the FMQ is connected successfully. */
+    bool isValid();
+
+    /** Returns whether the FMQ needs to be synced from the buffer pool */
+    bool needsSync();
+
+    /**
+     * Posts a buffer release message to the buffer pool.
+     *
+     * @param connectionId  connection Id of the client.
+     * @param pending       currently pending buffer release messages.
+     * @param posted        posted buffer release messages.
+     */
+    void postBufferRelease(
+            ConnectionId connectionId,
+            std::list<BufferId> &pending, std::list<BufferId> &posted);
+
+    /**
+     * Posts a buffer status message regarding the specified buffer
+     * transfer transaction.
+     *
+     * @param transactionId Id of the specified transaction.
+     * @param bufferId      buffer Id of the specified transaction.
+     * @param status        new status of the buffer.
+     * @param connectionId  connection Id of the client.
+     * @param targetId      connection Id of the receiver(only when the sender
+     *                      posts a status message).
+     * @param pending       currently pending buffer release messages.
+     * @param posted        posted buffer release messages.
+     *
+     * @return {@code true} when the specified message is posted,
+     *         {@code false} otherwise.
+     */
+    bool postBufferStatusMessage(
+            TransactionId transactionId,
+            BufferId bufferId,
+            BufferStatus status,
+            ConnectionId connectionId,
+            ConnectionId targetId,
+            std::list<BufferId> &pending, std::list<BufferId> &posted);
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_BUFFERSTATUS_H
diff --git a/media/bufferpool/1.0/ClientManager.cpp b/media/bufferpool/1.0/ClientManager.cpp
new file mode 100644
index 0000000..ecea0a4
--- /dev/null
+++ b/media/bufferpool/1.0/ClientManager.cpp
@@ -0,0 +1,504 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "BufferPoolManager"
+//#define LOG_NDEBUG 0
+
+#include <bufferpool/ClientManager.h>
+#include <hidl/HidlTransportSupport.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+#include <utils/Log.h>
+#include "BufferPoolClient.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V1_0 {
+namespace implementation {
+
+static constexpr int64_t kRegisterTimeoutUs = 500000; // 0.5 sec
+static constexpr int64_t kCleanUpDurationUs = 1000000; // TODO: 1 sec tune
+static constexpr int64_t kClientTimeoutUs = 5000000; // TODO: 5 secs tune
+
+/**
+ * The holder of the cookie of remote IClientManager.
+ * The cookie is process locally unique for each IClientManager.
+ * (The cookie is used to notify death of clients to bufferpool process.)
+ */
+class ClientManagerCookieHolder {
+public:
+    /**
+     * Creates a cookie holder for remote IClientManager(s).
+     */
+    ClientManagerCookieHolder();
+
+    /**
+     * Gets a cookie for a remote IClientManager.
+     *
+     * @param manager   the specified remote IClientManager.
+     * @param added     true when the specified remote IClientManager is added
+     *                  newly, false otherwise.
+     *
+     * @return the process locally unique cookie for the specified IClientManager.
+     */
+    uint64_t getCookie(const sp<IClientManager> &manager, bool *added);
+
+private:
+    uint64_t mSeqId;
+    std::mutex mLock;
+    std::list<std::pair<const wp<IClientManager>, uint64_t>> mManagers;
+};
+
+ClientManagerCookieHolder::ClientManagerCookieHolder() : mSeqId(0){}
+
+uint64_t ClientManagerCookieHolder::getCookie(
+        const sp<IClientManager> &manager,
+        bool *added) {
+    std::lock_guard<std::mutex> lock(mLock);
+    for (auto it = mManagers.begin(); it != mManagers.end();) {
+        const sp<IClientManager> key = it->first.promote();
+        if (key) {
+            if (interfacesEqual(key, manager)) {
+                *added = false;
+                return it->second;
+            }
+            ++it;
+        } else {
+            it = mManagers.erase(it);
+        }
+    }
+    uint64_t id = mSeqId++;
+    *added = true;
+    mManagers.push_back(std::make_pair(manager, id));
+    return id;
+}
+
+class ClientManager::Impl {
+public:
+    Impl();
+
+    // BnRegisterSender
+    ResultStatus registerSender(const sp<IAccessor> &accessor,
+                                ConnectionId *pConnectionId);
+
+    // BpRegisterSender
+    ResultStatus registerSender(const sp<IClientManager> &receiver,
+                                ConnectionId senderId,
+                                ConnectionId *receiverId);
+
+    ResultStatus create(const std::shared_ptr<BufferPoolAllocator> &allocator,
+                        ConnectionId *pConnectionId);
+
+    ResultStatus close(ConnectionId connectionId);
+
+    ResultStatus allocate(ConnectionId connectionId,
+                          const std::vector<uint8_t> &params,
+                          native_handle_t **handle,
+                          std::shared_ptr<BufferPoolData> *buffer);
+
+    ResultStatus receive(ConnectionId connectionId,
+                         TransactionId transactionId,
+                         BufferId bufferId,
+                         int64_t timestampUs,
+                         native_handle_t **handle,
+                         std::shared_ptr<BufferPoolData> *buffer);
+
+    ResultStatus postSend(ConnectionId receiverId,
+                          const std::shared_ptr<BufferPoolData> &buffer,
+                          TransactionId *transactionId,
+                          int64_t *timestampUs);
+
+    ResultStatus getAccessor(ConnectionId connectionId,
+                             sp<IAccessor> *accessor);
+
+    void cleanUp(bool clearCache = false);
+
+private:
+    // In order to prevent deadlock between multiple locks,
+    // always lock ClientCache.lock before locking ActiveClients.lock.
+    struct ClientCache {
+        // This lock is held for brief duration.
+        // Blocking operation is not performed while holding the lock.
+        std::mutex mMutex;
+        std::list<std::pair<const wp<IAccessor>, const std::weak_ptr<BufferPoolClient>>>
+                mClients;
+        std::condition_variable mConnectCv;
+        bool mConnecting;
+        int64_t mLastCleanUpUs;
+
+        ClientCache() : mConnecting(false), mLastCleanUpUs(getTimestampNow()) {}
+    } mCache;
+
+    // Active clients which can be retrieved via ConnectionId
+    struct ActiveClients {
+        // This lock is held for brief duration.
+        // Blocking operation is not performed holding the lock.
+        std::mutex mMutex;
+        std::map<ConnectionId, const std::shared_ptr<BufferPoolClient>>
+                mClients;
+    } mActive;
+
+    ClientManagerCookieHolder mRemoteClientCookies;
+};
+
+ClientManager::Impl::Impl() {}
+
+ResultStatus ClientManager::Impl::registerSender(
+        const sp<IAccessor> &accessor, ConnectionId *pConnectionId) {
+    cleanUp();
+    int64_t timeoutUs = getTimestampNow() + kRegisterTimeoutUs;
+    do {
+        std::unique_lock<std::mutex> lock(mCache.mMutex);
+        for (auto it = mCache.mClients.begin(); it != mCache.mClients.end(); ++it) {
+            sp<IAccessor> sAccessor = it->first.promote();
+            if (sAccessor && interfacesEqual(sAccessor, accessor)) {
+                const std::shared_ptr<BufferPoolClient> client = it->second.lock();
+                if (client) {
+                    std::lock_guard<std::mutex> lock(mActive.mMutex);
+                    *pConnectionId = client->getConnectionId();
+                    if (mActive.mClients.find(*pConnectionId) != mActive.mClients.end()) {
+                        ALOGV("register existing connection %lld", (long long)*pConnectionId);
+                        return ResultStatus::ALREADY_EXISTS;
+                    }
+                }
+                mCache.mClients.erase(it);
+                break;
+            }
+        }
+        if (!mCache.mConnecting) {
+            mCache.mConnecting = true;
+            lock.unlock();
+            ResultStatus result = ResultStatus::OK;
+            const std::shared_ptr<BufferPoolClient> client =
+                    std::make_shared<BufferPoolClient>(accessor);
+            lock.lock();
+            if (!client) {
+                result = ResultStatus::NO_MEMORY;
+            } else if (!client->isValid()) {
+                result = ResultStatus::CRITICAL_ERROR;
+            }
+            if (result == ResultStatus::OK) {
+                // TODO: handle insert fail. (malloc fail)
+                const std::weak_ptr<BufferPoolClient> wclient = client;
+                mCache.mClients.push_back(std::make_pair(accessor, wclient));
+                ConnectionId conId = client->getConnectionId();
+                {
+                    std::lock_guard<std::mutex> lock(mActive.mMutex);
+                    mActive.mClients.insert(std::make_pair(conId, client));
+                }
+                *pConnectionId = conId;
+                ALOGV("register new connection %lld", (long long)*pConnectionId);
+            }
+            mCache.mConnecting = false;
+            lock.unlock();
+            mCache.mConnectCv.notify_all();
+            return result;
+        }
+        mCache.mConnectCv.wait_for(
+                lock, std::chrono::microseconds(kRegisterTimeoutUs));
+    } while (getTimestampNow() < timeoutUs);
+    // TODO: return timeout error
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus ClientManager::Impl::registerSender(
+        const sp<IClientManager> &receiver,
+        ConnectionId senderId,
+        ConnectionId *receiverId) {
+    sp<IAccessor> accessor;
+    bool local = false;
+    {
+        std::lock_guard<std::mutex> lock(mActive.mMutex);
+        auto it = mActive.mClients.find(senderId);
+        if (it == mActive.mClients.end()) {
+            return ResultStatus::NOT_FOUND;
+        }
+        it->second->getAccessor(&accessor);
+        local = it->second->isLocal();
+    }
+    ResultStatus rs = ResultStatus::CRITICAL_ERROR;
+    if (accessor) {
+       Return<void> transResult = receiver->registerSender(
+                accessor,
+                [&rs, receiverId](
+                        ResultStatus status,
+                        int64_t connectionId) {
+                    rs = status;
+                    *receiverId = connectionId;
+                });
+        if (!transResult.isOk()) {
+            return ResultStatus::CRITICAL_ERROR;
+        } else if (local && rs == ResultStatus::OK) {
+            sp<ConnectionDeathRecipient> recipient = Accessor::getConnectionDeathRecipient();
+            if (recipient)  {
+                ALOGV("client death recipient registered %lld", (long long)*receiverId);
+                bool added;
+                uint64_t cookie = mRemoteClientCookies.getCookie(receiver, &added);
+                recipient->addCookieToConnection(cookie, *receiverId);
+                if (added) {
+                    Return<bool> transResult = receiver->linkToDeath(recipient, cookie);
+                }
+            }
+        }
+    }
+    return rs;
+}
+
+ResultStatus ClientManager::Impl::create(
+        const std::shared_ptr<BufferPoolAllocator> &allocator,
+        ConnectionId *pConnectionId) {
+    const sp<Accessor> accessor = new Accessor(allocator);
+    if (!accessor || !accessor->isValid()) {
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    std::shared_ptr<BufferPoolClient> client =
+            std::make_shared<BufferPoolClient>(accessor);
+    if (!client || !client->isValid()) {
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    // Since a new bufferpool is created, evict memories which are used by
+    // existing bufferpools and clients.
+    cleanUp(true);
+    {
+        // TODO: handle insert fail. (malloc fail)
+        std::lock_guard<std::mutex> lock(mCache.mMutex);
+        const std::weak_ptr<BufferPoolClient> wclient = client;
+        mCache.mClients.push_back(std::make_pair(accessor, wclient));
+        ConnectionId conId = client->getConnectionId();
+        {
+            std::lock_guard<std::mutex> lock(mActive.mMutex);
+            mActive.mClients.insert(std::make_pair(conId, client));
+        }
+        *pConnectionId = conId;
+        ALOGV("create new connection %lld", (long long)*pConnectionId);
+    }
+    return ResultStatus::OK;
+}
+
+ResultStatus ClientManager::Impl::close(ConnectionId connectionId) {
+    std::lock_guard<std::mutex> lock1(mCache.mMutex);
+    std::lock_guard<std::mutex> lock2(mActive.mMutex);
+    auto it = mActive.mClients.find(connectionId);
+    if (it != mActive.mClients.end()) {
+        sp<IAccessor> accessor;
+        it->second->getAccessor(&accessor);
+        mActive.mClients.erase(connectionId);
+        for (auto cit = mCache.mClients.begin(); cit != mCache.mClients.end();) {
+            // clean up dead client caches
+            sp<IAccessor> cAccessor = cit->first.promote();
+            if (!cAccessor || (accessor && interfacesEqual(cAccessor, accessor))) {
+                cit = mCache.mClients.erase(cit);
+            } else {
+                cit++;
+            }
+        }
+        return ResultStatus::OK;
+    }
+    return ResultStatus::NOT_FOUND;
+}
+
+ResultStatus ClientManager::Impl::allocate(
+        ConnectionId connectionId, const std::vector<uint8_t> &params,
+        native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
+    std::shared_ptr<BufferPoolClient> client;
+    {
+        std::lock_guard<std::mutex> lock(mActive.mMutex);
+        auto it = mActive.mClients.find(connectionId);
+        if (it == mActive.mClients.end()) {
+            return ResultStatus::NOT_FOUND;
+        }
+        client = it->second;
+    }
+    return client->allocate(params, handle, buffer);
+}
+
+ResultStatus ClientManager::Impl::receive(
+        ConnectionId connectionId, TransactionId transactionId,
+        BufferId bufferId, int64_t timestampUs,
+        native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
+    std::shared_ptr<BufferPoolClient> client;
+    {
+        std::lock_guard<std::mutex> lock(mActive.mMutex);
+        auto it = mActive.mClients.find(connectionId);
+        if (it == mActive.mClients.end()) {
+            return ResultStatus::NOT_FOUND;
+        }
+        client = it->second;
+    }
+    return client->receive(transactionId, bufferId, timestampUs, handle, buffer);
+}
+
+ResultStatus ClientManager::Impl::postSend(
+        ConnectionId receiverId, const std::shared_ptr<BufferPoolData> &buffer,
+        TransactionId *transactionId, int64_t *timestampUs) {
+    ConnectionId connectionId = buffer->mConnectionId;
+    std::shared_ptr<BufferPoolClient> client;
+    {
+        std::lock_guard<std::mutex> lock(mActive.mMutex);
+        auto it = mActive.mClients.find(connectionId);
+        if (it == mActive.mClients.end()) {
+            return ResultStatus::NOT_FOUND;
+        }
+        client = it->second;
+    }
+    return client->postSend(receiverId, buffer, transactionId, timestampUs);
+}
+
+ResultStatus ClientManager::Impl::getAccessor(
+        ConnectionId connectionId, sp<IAccessor> *accessor) {
+    std::shared_ptr<BufferPoolClient> client;
+    {
+        std::lock_guard<std::mutex> lock(mActive.mMutex);
+        auto it = mActive.mClients.find(connectionId);
+        if (it == mActive.mClients.end()) {
+            return ResultStatus::NOT_FOUND;
+        }
+        client = it->second;
+    }
+    return client->getAccessor(accessor);
+}
+
+void ClientManager::Impl::cleanUp(bool clearCache) {
+    int64_t now = getTimestampNow();
+    int64_t lastTransactionUs;
+    std::lock_guard<std::mutex> lock1(mCache.mMutex);
+    if (clearCache || mCache.mLastCleanUpUs + kCleanUpDurationUs < now) {
+        std::lock_guard<std::mutex> lock2(mActive.mMutex);
+        int cleaned = 0;
+        for (auto it = mActive.mClients.begin(); it != mActive.mClients.end();) {
+            if (!it->second->isActive(&lastTransactionUs, clearCache)) {
+                if (lastTransactionUs + kClientTimeoutUs < now) {
+                    sp<IAccessor> accessor;
+                    it->second->getAccessor(&accessor);
+                    it = mActive.mClients.erase(it);
+                    ++cleaned;
+                    continue;
+                }
+            }
+            ++it;
+        }
+        for (auto cit = mCache.mClients.begin(); cit != mCache.mClients.end();) {
+            // clean up dead client caches
+            sp<IAccessor> cAccessor = cit->first.promote();
+            if (!cAccessor) {
+                cit = mCache.mClients.erase(cit);
+            } else {
+                ++cit;
+            }
+        }
+        ALOGV("# of cleaned connections: %d", cleaned);
+        mCache.mLastCleanUpUs = now;
+    }
+}
+
+// Methods from ::android::hardware::media::bufferpool::V1_0::IClientManager follow.
+Return<void> ClientManager::registerSender(const sp<::android::hardware::media::bufferpool::V1_0::IAccessor>& bufferPool, registerSender_cb _hidl_cb) {
+    if (mImpl) {
+        ConnectionId connectionId = -1;
+        ResultStatus status = mImpl->registerSender(bufferPool, &connectionId);
+        _hidl_cb(status, connectionId);
+    } else {
+        _hidl_cb(ResultStatus::CRITICAL_ERROR, -1);
+    }
+    return Void();
+}
+
+// Methods for local use.
+sp<ClientManager> ClientManager::sInstance;
+std::mutex ClientManager::sInstanceLock;
+
+sp<ClientManager> ClientManager::getInstance() {
+    std::lock_guard<std::mutex> lock(sInstanceLock);
+    if (!sInstance) {
+        sInstance = new ClientManager();
+    }
+    return sInstance;
+}
+
+ClientManager::ClientManager() : mImpl(new Impl()) {}
+
+ClientManager::~ClientManager() {
+}
+
+ResultStatus ClientManager::create(
+        const std::shared_ptr<BufferPoolAllocator> &allocator,
+        ConnectionId *pConnectionId) {
+    if (mImpl) {
+        return mImpl->create(allocator, pConnectionId);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus ClientManager::registerSender(
+        const sp<IClientManager> &receiver,
+        ConnectionId senderId,
+        ConnectionId *receiverId) {
+    if (mImpl) {
+        return mImpl->registerSender(receiver, senderId, receiverId);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus ClientManager::close(ConnectionId connectionId) {
+    if (mImpl) {
+        return mImpl->close(connectionId);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus ClientManager::allocate(
+        ConnectionId connectionId, const std::vector<uint8_t> &params,
+        native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
+    if (mImpl) {
+        return mImpl->allocate(connectionId, params, handle, buffer);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus ClientManager::receive(
+        ConnectionId connectionId, TransactionId transactionId,
+        BufferId bufferId, int64_t timestampUs,
+        native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
+    if (mImpl) {
+        return mImpl->receive(connectionId, transactionId, bufferId,
+                              timestampUs, handle, buffer);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus ClientManager::postSend(
+        ConnectionId receiverId, const std::shared_ptr<BufferPoolData> &buffer,
+        TransactionId *transactionId, int64_t* timestampUs) {
+    if (mImpl && buffer) {
+        return mImpl->postSend(receiverId, buffer, transactionId, timestampUs);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+void ClientManager::cleanUp() {
+    if (mImpl) {
+        mImpl->cleanUp(true);
+    }
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
diff --git a/media/bufferpool/1.0/Connection.cpp b/media/bufferpool/1.0/Connection.cpp
new file mode 100644
index 0000000..be89701
--- /dev/null
+++ b/media/bufferpool/1.0/Connection.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Connection.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V1_0 {
+namespace implementation {
+
+// Methods from ::android::hardware::media::bufferpool::V1_0::IConnection follow.
+Return<void> Connection::fetch(uint64_t transactionId, uint32_t bufferId, fetch_cb _hidl_cb) {
+    ResultStatus status = ResultStatus::CRITICAL_ERROR;
+    if (mInitialized && mAccessor) {
+        if (bufferId != SYNC_BUFFERID) {
+            const native_handle_t *handle = nullptr;
+            status = mAccessor->fetch(
+                    mConnectionId, transactionId, bufferId, &handle);
+            if (status == ResultStatus::OK) {
+                Buffer buffer = {};
+                buffer.id = bufferId;
+                buffer.buffer = handle;
+                _hidl_cb(status, buffer);
+                return Void();
+            }
+        } else {
+            mAccessor->cleanUp(false);
+        }
+    }
+
+    Buffer buffer = {};
+    buffer.id = 0;
+    buffer.buffer = nullptr;
+
+    _hidl_cb(status, buffer);
+    return Void();
+}
+
+Connection::Connection() : mInitialized(false), mConnectionId(-1LL) {}
+
+Connection::~Connection() {
+    if (mInitialized && mAccessor) {
+        mAccessor->close(mConnectionId);
+    }
+}
+
+void Connection::initialize(
+        const sp<Accessor>& accessor, ConnectionId connectionId) {
+    if (!mInitialized) {
+        mAccessor = accessor;
+        mConnectionId = connectionId;
+        mInitialized = true;
+    }
+}
+
+ResultStatus Connection::allocate(
+        const std::vector<uint8_t> &params, BufferId *bufferId,
+        const native_handle_t **handle) {
+    if (mInitialized && mAccessor) {
+        return mAccessor->allocate(mConnectionId, params, bufferId, handle);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+void Connection::cleanUp(bool clearCache) {
+    if (mInitialized && mAccessor) {
+        mAccessor->cleanUp(clearCache);
+    }
+}
+
+// Methods from ::android::hidl::base::V1_0::IBase follow.
+
+//IConnection* HIDL_FETCH_IConnection(const char* /* name */) {
+//    return new Connection();
+//}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
diff --git a/media/bufferpool/1.0/Connection.h b/media/bufferpool/1.0/Connection.h
new file mode 100644
index 0000000..e19cb67
--- /dev/null
+++ b/media/bufferpool/1.0/Connection.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_CONNECTION_H
+#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_CONNECTION_H
+
+#include <android/hardware/media/bufferpool/1.0/IConnection.h>
+#include <bufferpool/BufferPoolTypes.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include "Accessor.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::media::bufferpool::V1_0::implementation::Accessor;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct Connection : public IConnection {
+    // Methods from ::android::hardware::media::bufferpool::V1_0::IConnection follow.
+    Return<void> fetch(uint64_t transactionId, uint32_t bufferId, fetch_cb _hidl_cb) override;
+
+    /**
+     * Allocates a buffer using the specified parameters. Recycles a buffer if
+     * it is possible. The returned buffer can be transferred to other remote
+     * clients(Connection).
+     *
+     * @param params    allocation parameters.
+     * @param bufferId  Id of the allocated buffer.
+     * @param handle    native handle of the allocated buffer.
+     *
+     * @return OK if a buffer is successfully allocated.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus allocate(const std::vector<uint8_t> &params,
+                          BufferId *bufferId, const native_handle_t **handle);
+
+    /**
+     * Processes pending buffer status messages and performs periodic cache cleaning
+     * from bufferpool.
+     *
+     * @param clearCache    if clearCache is true, bufferpool frees all buffers
+     *                      waiting to be recycled.
+     */
+    void cleanUp(bool clearCache);
+
+    /** Destructs a connection. */
+    ~Connection();
+
+    /** Creates a connection. */
+    Connection();
+
+    /**
+     * Initializes with the specified buffer pool and the connection id.
+     * The connection id should be unique in the whole system.
+     *
+     * @param accessor      the specified buffer pool.
+     * @param connectionId  Id.
+     */
+    void initialize(const sp<Accessor> &accessor, ConnectionId connectionId);
+
+    enum : uint32_t {
+        SYNC_BUFFERID = UINT32_MAX,
+    };
+
+private:
+    bool mInitialized;
+    sp<Accessor> mAccessor;
+    ConnectionId mConnectionId;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_CONNECTION_H
diff --git a/media/bufferpool/1.0/include/bufferpool/BufferPoolTypes.h b/media/bufferpool/1.0/include/bufferpool/BufferPoolTypes.h
new file mode 100644
index 0000000..710f015
--- /dev/null
+++ b/media/bufferpool/1.0/include/bufferpool/BufferPoolTypes.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_BUFFERPOOLTYPES_H
+#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_BUFFERPOOLTYPES_H
+
+#include <android/hardware/media/bufferpool/1.0/types.h>
+#include <cutils/native_handle.h>
+#include <fmq/MessageQueue.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+
+struct BufferPoolData {
+    // For local use, to specify a bufferpool (client connection) for buffers.
+    // Return value from connect#IAccessor(android.hardware.media.bufferpool@1.0).
+    int64_t mConnectionId;
+    // BufferId
+    uint32_t mId;
+
+    BufferPoolData() : mConnectionId(0), mId(0) {}
+
+    BufferPoolData(
+            int64_t connectionId, uint32_t id)
+            : mConnectionId(connectionId), mId(id) {}
+
+    ~BufferPoolData() {}
+};
+
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::kSynchronizedReadWrite;
+
+typedef uint32_t BufferId;
+typedef uint64_t TransactionId;
+typedef int64_t ConnectionId;
+
+enum : ConnectionId {
+    INVALID_CONNECTIONID = 0,
+};
+
+typedef android::hardware::MessageQueue<BufferStatusMessage, kSynchronizedReadWrite> BufferStatusQueue;
+typedef BufferStatusQueue::Descriptor QueueDescriptor;
+
+/**
+ * Allocation wrapper class for buffer pool.
+ */
+struct BufferPoolAllocation {
+    const native_handle_t *mHandle;
+
+    const native_handle_t *handle() {
+        return mHandle;
+    }
+
+    BufferPoolAllocation(const native_handle_t *handle) : mHandle(handle) {}
+
+    ~BufferPoolAllocation() {};
+};
+
+/**
+ * Allocator wrapper class for buffer pool.
+ */
+class BufferPoolAllocator {
+public:
+
+    /**
+     * Allocate an allocation(buffer) for buffer pool.
+     *
+     * @param params    allocation parameters
+     * @param alloc     created allocation
+     * @param allocSize size of created allocation
+     *
+     * @return OK when an allocation is created successfully.
+     */
+    virtual ResultStatus allocate(
+            const std::vector<uint8_t> &params,
+            std::shared_ptr<BufferPoolAllocation> *alloc,
+            size_t *allocSize) = 0;
+
+    /**
+     * Returns whether allocation parameters of an old allocation are
+     * compatible with new allocation parameters.
+     */
+    virtual bool compatible(const std::vector<uint8_t> &newParams,
+                            const std::vector<uint8_t> &oldParams) = 0;
+
+protected:
+    BufferPoolAllocator() = default;
+
+    virtual ~BufferPoolAllocator() = default;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_BUFFERPOOLTYPES_H
diff --git a/media/bufferpool/1.0/include/bufferpool/ClientManager.h b/media/bufferpool/1.0/include/bufferpool/ClientManager.h
new file mode 100644
index 0000000..be5779f
--- /dev/null
+++ b/media/bufferpool/1.0/include/bufferpool/ClientManager.h
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_CLIENTMANAGER_H
+#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_CLIENTMANAGER_H
+
+#include <android/hardware/media/bufferpool/1.0/IClientManager.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <memory>
+#include "BufferPoolTypes.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::media::bufferpool::V1_0::IAccessor;
+using ::android::hardware::media::bufferpool::V1_0::ResultStatus;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct ClientManager : public IClientManager {
+    // Methods from ::android::hardware::media::bufferpool::V1_0::IClientManager follow.
+    Return<void> registerSender(const sp<::android::hardware::media::bufferpool::V1_0::IAccessor>& bufferPool, registerSender_cb _hidl_cb) override;
+
+    /** Gets an instance. */
+    static sp<ClientManager> getInstance();
+
+    /**
+     * Creates a local connection with a newly created buffer pool.
+     *
+     * @param allocator     for new buffer allocation.
+     * @param pConnectionId Id of the created connection. This is
+     *                      system-wide unique.
+     *
+     * @return OK when a buffer pool and a local connection is successfully
+     *         created.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus create(const std::shared_ptr<BufferPoolAllocator> &allocator,
+                        ConnectionId *pConnectionId);
+
+    /**
+     * Register a created connection as sender for remote process.
+     *
+     * @param receiver      The remote receiving process.
+     * @param senderId      A local connection which will send buffers to.
+     * @param receiverId    Id of the created receiving connection on the receiver
+     *                      process.
+     *
+     * @return OK when the receiving connection is successfully created on the
+     *         receiver process.
+     *         NOT_FOUND when the sender connection was not found.
+     *         ALREADY_EXISTS the receiving connection is already made.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus registerSender(const sp<IClientManager> &receiver,
+                                ConnectionId senderId,
+                                ConnectionId *receiverId);
+
+    /**
+     * Closes the specified connection.
+     *
+     * @param connectionId  The id of the connection.
+     *
+     * @return OK when the connection is closed.
+     *         NOT_FOUND when the specified connection was not found.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus close(ConnectionId connectionId);
+
+    /**
+     * Allocates a buffer from the specified connection.
+     *
+     * @param connectionId  The id of the connection.
+     * @param params        The allocation parameters.
+     * @param handle        The native handle to the allocated buffer. handle
+     *                      should be cloned before use.
+     * @param buffer        The allocated buffer.
+     *
+     * @return OK when a buffer was allocated successfully.
+     *         NOT_FOUND when the specified connection was not found.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus allocate(ConnectionId connectionId,
+                          const std::vector<uint8_t> &params,
+                          native_handle_t **handle,
+                          std::shared_ptr<BufferPoolData> *buffer);
+
+    /**
+     * Receives a buffer for the transaction.
+     *
+     * @param connectionId  The id of the receiving connection.
+     * @param transactionId The id for the transaction.
+     * @param bufferId      The id for the buffer.
+     * @param timestampUs   The timestamp of the buffer is being sent.
+     * @param handle        The native handle to the allocated buffer. handle
+     *                      should be cloned before use.
+     * @param buffer        The received buffer.
+     *
+     * @return OK when a buffer was received successfully.
+     *         NOT_FOUND when the specified connection was not found.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus receive(ConnectionId connectionId,
+                         TransactionId transactionId,
+                         BufferId bufferId,
+                         int64_t timestampUs,
+                          native_handle_t **handle,
+                         std::shared_ptr<BufferPoolData> *buffer);
+
+    /**
+     * Posts a buffer transfer transaction to the buffer pool. Sends a buffer
+     * to other remote clients(connection) after this call has been succeeded.
+     *
+     * @param receiverId    The id of the receiving connection.
+     * @param buffer        to transfer
+     * @param transactionId Id of the transfer transaction.
+     * @param timestampUs   The timestamp of the buffer transaction is being
+     *                      posted.
+     *
+     * @return OK when a buffer transaction was posted successfully.
+     *         NOT_FOUND when the sending connection was not found.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus postSend(ConnectionId receiverId,
+                          const std::shared_ptr<BufferPoolData> &buffer,
+                          TransactionId *transactionId,
+                          int64_t *timestampUs);
+
+    /**
+     *  Time out inactive lingering connections and close.
+     */
+    void cleanUp();
+
+    /** Destructs the manager of buffer pool clients.  */
+    ~ClientManager();
+private:
+    static sp<ClientManager> sInstance;
+    static std::mutex sInstanceLock;
+
+    class Impl;
+    const std::unique_ptr<Impl> mImpl;
+
+    ClientManager();
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_CLIENTMANAGER_H
diff --git a/media/bufferpool/1.0/vts/Android.bp b/media/bufferpool/1.0/vts/Android.bp
new file mode 100644
index 0000000..ee5a757
--- /dev/null
+++ b/media/bufferpool/1.0/vts/Android.bp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+cc_test {
+    name: "VtsVndkHidlBufferpoolV1_0TargetSingleTest",
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: [
+        "allocator.cpp",
+        "single.cpp",
+    ],
+    static_libs: [
+        "android.hardware.media.bufferpool@1.0",
+        "libion",
+        "libstagefright_bufferpool@1.0",
+    ],
+    shared_libs: [
+        "libfmq",
+    ],
+    compile_multilib: "both",
+}
+
+cc_test {
+    name: "VtsVndkHidlBufferpoolV1_0TargetMultiTest",
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: [
+        "allocator.cpp",
+        "multi.cpp",
+    ],
+    static_libs: [
+        "android.hardware.media.bufferpool@1.0",
+        "libion",
+        "libstagefright_bufferpool@1.0",
+    ],
+    shared_libs: [
+        "libfmq",
+    ],
+    compile_multilib: "both",
+}
diff --git a/media/bufferpool/1.0/vts/OWNERS b/media/bufferpool/1.0/vts/OWNERS
new file mode 100644
index 0000000..6733e0c
--- /dev/null
+++ b/media/bufferpool/1.0/vts/OWNERS
@@ -0,0 +1,9 @@
+# Media team
+lajos@google.com
+pawin@google.com
+taklee@google.com
+wonsik@google.com
+
+# VTS team
+yim@google.com
+zhuoyao@google.com
diff --git a/media/bufferpool/1.0/vts/allocator.cpp b/media/bufferpool/1.0/vts/allocator.cpp
new file mode 100644
index 0000000..843f7ea
--- /dev/null
+++ b/media/bufferpool/1.0/vts/allocator.cpp
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cutils/ashmem.h>
+#include <sys/mman.h>
+#include "allocator.h"
+
+union Params {
+  struct {
+    uint32_t capacity;
+  } data;
+  uint8_t array[0];
+  Params() : data{0} {}
+  Params(uint32_t size)
+      : data{size} {}
+};
+
+
+namespace {
+
+struct HandleAshmem : public native_handle_t {
+  HandleAshmem(int ashmemFd, size_t size)
+    : native_handle_t(cHeader),
+    mFds{ ashmemFd },
+    mInts{ int (size & 0xFFFFFFFF), int((uint64_t(size) >> 32) & 0xFFFFFFFF), kMagic } {}
+
+  int ashmemFd() const { return mFds.mAshmem; }
+  size_t size() const {
+    return size_t(unsigned(mInts.mSizeLo))
+        | size_t(uint64_t(unsigned(mInts.mSizeHi)) << 32);
+  }
+
+  static bool isValid(const native_handle_t * const o);
+
+protected:
+  struct {
+    int mAshmem;
+  } mFds;
+  struct {
+    int mSizeLo;
+    int mSizeHi;
+    int mMagic;
+  } mInts;
+
+private:
+  enum {
+    kMagic = 'ahm\x00',
+    numFds = sizeof(mFds) / sizeof(int),
+    numInts = sizeof(mInts) / sizeof(int),
+    version = sizeof(native_handle_t)
+  };
+  const static native_handle_t cHeader;
+};
+
+const native_handle_t HandleAshmem::cHeader = {
+  HandleAshmem::version,
+  HandleAshmem::numFds,
+  HandleAshmem::numInts,
+  {}
+};
+
+bool HandleAshmem::isValid(const native_handle_t * const o) {
+  if (!o || memcmp(o, &cHeader, sizeof(cHeader))) {
+    return false;
+  }
+  const HandleAshmem *other = static_cast<const HandleAshmem*>(o);
+  return other->mInts.mMagic == kMagic;
+}
+
+class AllocationAshmem {
+private:
+  AllocationAshmem(int ashmemFd, size_t capacity, bool res)
+    : mHandle(ashmemFd, capacity),
+      mInit(res) {}
+
+public:
+  static AllocationAshmem *Alloc(size_t size) {
+    constexpr static const char *kAllocationTag = "bufferpool_test";
+    int ashmemFd = ashmem_create_region(kAllocationTag, size);
+    return new AllocationAshmem(ashmemFd, size, ashmemFd >= 0);
+  }
+
+  ~AllocationAshmem() {
+    if (mInit) {
+      native_handle_close(&mHandle);
+    }
+  }
+
+  const HandleAshmem *handle() {
+    return &mHandle;
+  }
+
+private:
+  HandleAshmem mHandle;
+  bool mInit;
+  // TODO: mapping and map fd
+};
+
+struct AllocationDtor {
+  AllocationDtor(const std::shared_ptr<AllocationAshmem> &alloc)
+      : mAlloc(alloc) {}
+
+  void operator()(BufferPoolAllocation *poolAlloc) { delete poolAlloc; }
+
+  const std::shared_ptr<AllocationAshmem> mAlloc;
+};
+
+}
+
+
+ResultStatus TestBufferPoolAllocator::allocate(
+    const std::vector<uint8_t> &params,
+    std::shared_ptr<BufferPoolAllocation> *alloc,
+    size_t *allocSize) {
+  Params ashmemParams;
+  memcpy(&ashmemParams, params.data(), std::min(sizeof(Params), params.size()));
+
+  std::shared_ptr<AllocationAshmem> ashmemAlloc =
+      std::shared_ptr<AllocationAshmem>(
+          AllocationAshmem::Alloc(ashmemParams.data.capacity));
+  if (ashmemAlloc) {
+    BufferPoolAllocation *ptr = new BufferPoolAllocation(ashmemAlloc->handle());
+    if (ptr) {
+      *alloc = std::shared_ptr<BufferPoolAllocation>(ptr, AllocationDtor(ashmemAlloc));
+      if (*alloc) {
+          *allocSize = ashmemParams.data.capacity;
+          return ResultStatus::OK;
+      }
+      delete ptr;
+      return ResultStatus::NO_MEMORY;
+    }
+  }
+  return ResultStatus::CRITICAL_ERROR;
+}
+
+bool TestBufferPoolAllocator::compatible(const std::vector<uint8_t> &newParams,
+                                        const std::vector<uint8_t> &oldParams) {
+  size_t newSize = newParams.size();
+  size_t oldSize = oldParams.size();
+  if (newSize == oldSize) {
+    for (size_t i = 0; i < newSize; ++i) {
+      if (newParams[i] != oldParams[i]) {
+        return false;
+      }
+    }
+    return true;
+  }
+  return false;
+}
+
+bool TestBufferPoolAllocator::Fill(const native_handle_t *handle, const unsigned char val) {
+  if (!HandleAshmem::isValid(handle)) {
+    return false;
+  }
+  const HandleAshmem *o = static_cast<const HandleAshmem*>(handle);
+  unsigned char *ptr = (unsigned char *)mmap(
+      NULL, o->size(), PROT_READ|PROT_WRITE, MAP_SHARED, o->ashmemFd(), 0);
+
+  if (ptr != MAP_FAILED) {
+    for (size_t i = 0; i < o->size(); ++i) {
+      ptr[i] = val;
+    }
+    munmap(ptr, o->size());
+    return true;
+  }
+  return false;
+}
+
+bool TestBufferPoolAllocator::Verify(const native_handle_t *handle, const unsigned char val) {
+  if (!HandleAshmem::isValid(handle)) {
+    return false;
+  }
+  const HandleAshmem *o = static_cast<const HandleAshmem*>(handle);
+  unsigned char *ptr = (unsigned char *)mmap(
+      NULL, o->size(), PROT_READ, MAP_SHARED, o->ashmemFd(), 0);
+
+  if (ptr != MAP_FAILED) {
+    bool res = true;
+    for (size_t i = 0; i < o->size(); ++i) {
+      if (ptr[i] != val) {
+        res = false;
+        break;
+      }
+    }
+    munmap(ptr, o->size());
+    return res;
+  }
+  return false;
+}
+
+void getTestAllocatorParams(std::vector<uint8_t> *params) {
+  constexpr static int kAllocationSize = 1024 * 10;
+  Params ashmemParams(kAllocationSize);
+
+  params->assign(ashmemParams.array, ashmemParams.array + sizeof(ashmemParams));
+}
diff --git a/media/bufferpool/1.0/vts/allocator.h b/media/bufferpool/1.0/vts/allocator.h
new file mode 100644
index 0000000..886e5f2
--- /dev/null
+++ b/media/bufferpool/1.0/vts/allocator.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef VNDK_HIDL_BUFFERPOOL_V1_0_ALLOCATOR_H
+#define VNDK_HIDL_BUFFERPOOL_V1_0_ALLOCATOR_H
+
+#include <bufferpool/BufferPoolTypes.h>
+
+using android::hardware::media::bufferpool::V1_0::ResultStatus;
+using android::hardware::media::bufferpool::V1_0::implementation::
+    BufferPoolAllocation;
+using android::hardware::media::bufferpool::V1_0::implementation::
+    BufferPoolAllocator;
+
+// buffer allocator for the tests
+class TestBufferPoolAllocator : public BufferPoolAllocator {
+ public:
+  TestBufferPoolAllocator() {}
+
+  ~TestBufferPoolAllocator() override {}
+
+  ResultStatus allocate(const std::vector<uint8_t> &params,
+                        std::shared_ptr<BufferPoolAllocation> *alloc,
+                        size_t *allocSize) override;
+
+  bool compatible(const std::vector<uint8_t> &newParams,
+                  const std::vector<uint8_t> &oldParams) override;
+
+  static bool Fill(const native_handle_t *handle, const unsigned char val);
+
+  static bool Verify(const native_handle_t *handle, const unsigned char val);
+
+};
+
+// retrieve buffer allocator paramters
+void getTestAllocatorParams(std::vector<uint8_t> *params);
+
+#endif  // VNDK_HIDL_BUFFERPOOL_V1_0_ALLOCATOR_H
diff --git a/media/bufferpool/1.0/vts/multi.cpp b/media/bufferpool/1.0/vts/multi.cpp
new file mode 100644
index 0000000..1796819
--- /dev/null
+++ b/media/bufferpool/1.0/vts/multi.cpp
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "buffferpool_unit_test"
+
+#include <gtest/gtest.h>
+
+#include <android-base/logging.h>
+#include <binder/ProcessState.h>
+#include <bufferpool/ClientManager.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/LegacySupport.h>
+#include <hidl/Status.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <iostream>
+#include <memory>
+#include <vector>
+#include "allocator.h"
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::hidl_handle;
+using android::hardware::media::bufferpool::V1_0::IClientManager;
+using android::hardware::media::bufferpool::V1_0::ResultStatus;
+using android::hardware::media::bufferpool::V1_0::implementation::BufferId;
+using android::hardware::media::bufferpool::V1_0::implementation::ClientManager;
+using android::hardware::media::bufferpool::V1_0::implementation::ConnectionId;
+using android::hardware::media::bufferpool::V1_0::implementation::TransactionId;
+using android::hardware::media::bufferpool::BufferPoolData;
+
+namespace {
+
+// communication message types between processes.
+enum PipeCommand : int32_t {
+    INIT_OK = 0,
+    INIT_ERROR,
+    SEND,
+    RECEIVE_OK,
+    RECEIVE_ERROR,
+};
+
+// communication message between processes.
+union PipeMessage {
+    struct  {
+        int32_t command;
+        BufferId bufferId;
+        ConnectionId connectionId;
+        TransactionId transactionId;
+        int64_t  timestampUs;
+    } data;
+    char array[0];
+};
+
+// media.bufferpool test setup
+class BufferpoolMultiTest : public ::testing::Test {
+ public:
+  virtual void SetUp() override {
+    ResultStatus status;
+    mReceiverPid = -1;
+    mConnectionValid = false;
+
+    ASSERT_TRUE(pipe(mCommandPipeFds) == 0);
+    ASSERT_TRUE(pipe(mResultPipeFds) == 0);
+
+    mReceiverPid = fork();
+    ASSERT_TRUE(mReceiverPid >= 0);
+
+    if (mReceiverPid == 0) {
+      doReceiver();
+      // In order to ignore gtest behaviour, wait for being killed from
+      // tearDown
+      pause();
+    }
+
+    mManager = ClientManager::getInstance();
+    ASSERT_NE(mManager, nullptr);
+
+    mAllocator = std::make_shared<TestBufferPoolAllocator>();
+    ASSERT_TRUE((bool)mAllocator);
+
+    status = mManager->create(mAllocator, &mConnectionId);
+    ASSERT_TRUE(status == ResultStatus::OK);
+    mConnectionValid = true;
+  }
+
+  virtual void TearDown() override {
+    if (mReceiverPid > 0) {
+      kill(mReceiverPid, SIGKILL);
+      int wstatus;
+      wait(&wstatus);
+    }
+
+    if (mConnectionValid) {
+      mManager->close(mConnectionId);
+    }
+  }
+
+ protected:
+  static void description(const std::string& description) {
+    RecordProperty("description", description);
+  }
+
+  android::sp<ClientManager> mManager;
+  std::shared_ptr<BufferPoolAllocator> mAllocator;
+  bool mConnectionValid;
+  ConnectionId mConnectionId;
+  pid_t mReceiverPid;
+  int mCommandPipeFds[2];
+  int mResultPipeFds[2];
+
+  bool sendMessage(int *pipes, const PipeMessage &message) {
+    int ret = write(pipes[1], message.array, sizeof(PipeMessage));
+    return ret == sizeof(PipeMessage);
+  }
+
+  bool receiveMessage(int *pipes, PipeMessage *message) {
+    int ret = read(pipes[0], message->array, sizeof(PipeMessage));
+    return ret == sizeof(PipeMessage);
+  }
+
+  void doReceiver() {
+    configureRpcThreadpool(1, false);
+    PipeMessage message;
+    mManager = ClientManager::getInstance();
+    if (!mManager) {
+      message.data.command = PipeCommand::INIT_ERROR;
+      sendMessage(mResultPipeFds, message);
+      return;
+    }
+    android::status_t status = mManager->registerAsService();
+    if (status != android::OK) {
+      message.data.command = PipeCommand::INIT_ERROR;
+      sendMessage(mResultPipeFds, message);
+      return;
+    }
+    message.data.command = PipeCommand::INIT_OK;
+    sendMessage(mResultPipeFds, message);
+
+    receiveMessage(mCommandPipeFds, &message);
+    {
+      native_handle_t *rhandle = nullptr;
+      std::shared_ptr<BufferPoolData> rbuffer;
+      ResultStatus status = mManager->receive(
+          message.data.connectionId, message.data.transactionId,
+          message.data.bufferId, message.data.timestampUs, &rhandle, &rbuffer);
+      mManager->close(message.data.connectionId);
+      if (status != ResultStatus::OK) {
+        if (!TestBufferPoolAllocator::Verify(rhandle, 0x77)) {
+          message.data.command = PipeCommand::RECEIVE_ERROR;
+          sendMessage(mResultPipeFds, message);
+          return;
+        }
+      }
+    }
+    message.data.command = PipeCommand::RECEIVE_OK;
+    sendMessage(mResultPipeFds, message);
+  }
+};
+
+// Buffer transfer test between processes.
+TEST_F(BufferpoolMultiTest, TransferBuffer) {
+  ResultStatus status;
+  PipeMessage message;
+
+  ASSERT_TRUE(receiveMessage(mResultPipeFds, &message));
+
+  android::sp<IClientManager> receiver = IClientManager::getService();
+  ConnectionId receiverId;
+  ASSERT_TRUE((bool)receiver);
+
+  status = mManager->registerSender(receiver, mConnectionId, &receiverId);
+  ASSERT_TRUE(status == ResultStatus::OK);
+  {
+    native_handle_t *shandle = nullptr;
+    std::shared_ptr<BufferPoolData> sbuffer;
+    TransactionId transactionId;
+    int64_t postUs;
+    std::vector<uint8_t> vecParams;
+
+    getTestAllocatorParams(&vecParams);
+    status = mManager->allocate(mConnectionId, vecParams, &shandle, &sbuffer);
+    ASSERT_TRUE(status == ResultStatus::OK);
+
+    ASSERT_TRUE(TestBufferPoolAllocator::Fill(shandle, 0x77));
+
+    status = mManager->postSend(receiverId, sbuffer, &transactionId, &postUs);
+    ASSERT_TRUE(status == ResultStatus::OK);
+
+    message.data.command = PipeCommand::SEND;
+    message.data.bufferId = sbuffer->mId;
+    message.data.connectionId = receiverId;
+    message.data.transactionId = transactionId;
+    message.data.timestampUs = postUs;
+    sendMessage(mCommandPipeFds, message);
+  }
+  EXPECT_TRUE(receiveMessage(mResultPipeFds, &message));
+}
+
+}  // anonymous namespace
+
+int main(int argc, char** argv) {
+  setenv("TREBLE_TESTING_OVERRIDE", "true", true);
+  ::testing::InitGoogleTest(&argc, argv);
+  int status = RUN_ALL_TESTS();
+  LOG(INFO) << "Test result = " << status;
+  return status;
+}
diff --git a/media/bufferpool/1.0/vts/single.cpp b/media/bufferpool/1.0/vts/single.cpp
new file mode 100644
index 0000000..f73eb62
--- /dev/null
+++ b/media/bufferpool/1.0/vts/single.cpp
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "buffferpool_unit_test"
+
+#include <gtest/gtest.h>
+
+#include <android-base/logging.h>
+#include <binder/ProcessState.h>
+#include <bufferpool/ClientManager.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/LegacySupport.h>
+#include <hidl/Status.h>
+#include <unistd.h>
+#include <iostream>
+#include <memory>
+#include <vector>
+#include "allocator.h"
+
+using android::hardware::hidl_handle;
+using android::hardware::media::bufferpool::V1_0::ResultStatus;
+using android::hardware::media::bufferpool::V1_0::implementation::BufferId;
+using android::hardware::media::bufferpool::V1_0::implementation::ClientManager;
+using android::hardware::media::bufferpool::V1_0::implementation::ConnectionId;
+using android::hardware::media::bufferpool::V1_0::implementation::TransactionId;
+using android::hardware::media::bufferpool::BufferPoolData;
+
+namespace {
+
+// Number of iteration for buffer allocation test.
+constexpr static int kNumAllocationTest = 3;
+
+// Number of iteration for buffer recycling test.
+constexpr static int kNumRecycleTest = 3;
+
+// media.bufferpool test setup
+class BufferpoolSingleTest : public ::testing::Test {
+ public:
+  virtual void SetUp() override {
+    ResultStatus status;
+    mConnectionValid = false;
+
+    mManager = ClientManager::getInstance();
+    ASSERT_NE(mManager, nullptr);
+
+    mAllocator = std::make_shared<TestBufferPoolAllocator>();
+    ASSERT_TRUE((bool)mAllocator);
+
+    status = mManager->create(mAllocator, &mConnectionId);
+    ASSERT_TRUE(status == ResultStatus::OK);
+
+    mConnectionValid = true;
+
+    status = mManager->registerSender(mManager, mConnectionId, &mReceiverId);
+    ASSERT_TRUE(status == ResultStatus::ALREADY_EXISTS &&
+                mReceiverId == mConnectionId);
+  }
+
+  virtual void TearDown() override {
+    if (mConnectionValid) {
+      mManager->close(mConnectionId);
+    }
+  }
+
+ protected:
+  static void description(const std::string& description) {
+    RecordProperty("description", description);
+  }
+
+  android::sp<ClientManager> mManager;
+  std::shared_ptr<BufferPoolAllocator> mAllocator;
+  bool mConnectionValid;
+  ConnectionId mConnectionId;
+  ConnectionId mReceiverId;
+
+};
+
+// Buffer allocation test.
+// Check whether each buffer allocation is done successfully with
+// unique buffer id.
+TEST_F(BufferpoolSingleTest, AllocateBuffer) {
+  ResultStatus status;
+  std::vector<uint8_t> vecParams;
+  getTestAllocatorParams(&vecParams);
+
+  std::shared_ptr<BufferPoolData> buffer[kNumAllocationTest];
+  native_handle_t *allocHandle = nullptr;
+  for (int i = 0; i < kNumAllocationTest; ++i) {
+    status = mManager->allocate(mConnectionId, vecParams, &allocHandle, &buffer[i]);
+    ASSERT_TRUE(status == ResultStatus::OK);
+  }
+  for (int i = 0; i < kNumAllocationTest; ++i) {
+    for (int j = i + 1; j < kNumAllocationTest; ++j) {
+      ASSERT_TRUE(buffer[i]->mId != buffer[j]->mId);
+    }
+  }
+  EXPECT_TRUE(kNumAllocationTest > 1);
+}
+
+// Buffer recycle test.
+// Check whether de-allocated buffers are recycled.
+TEST_F(BufferpoolSingleTest, RecycleBuffer) {
+  ResultStatus status;
+  std::vector<uint8_t> vecParams;
+  getTestAllocatorParams(&vecParams);
+
+  BufferId bid[kNumRecycleTest];
+  for (int i = 0; i < kNumRecycleTest; ++i) {
+    std::shared_ptr<BufferPoolData> buffer;
+    native_handle_t *allocHandle = nullptr;
+    status = mManager->allocate(mConnectionId, vecParams, &allocHandle, &buffer);
+    ASSERT_TRUE(status == ResultStatus::OK);
+    bid[i] = buffer->mId;
+  }
+  for (int i = 1; i < kNumRecycleTest; ++i) {
+    ASSERT_TRUE(bid[i - 1] == bid[i]);
+  }
+  EXPECT_TRUE(kNumRecycleTest > 1);
+}
+
+// Buffer transfer test.
+// Check whether buffer is transferred to another client successfully.
+TEST_F(BufferpoolSingleTest, TransferBuffer) {
+  ResultStatus status;
+  std::vector<uint8_t> vecParams;
+  getTestAllocatorParams(&vecParams);
+  std::shared_ptr<BufferPoolData> sbuffer, rbuffer;
+  native_handle_t *allocHandle = nullptr;
+  native_handle_t *recvHandle = nullptr;
+
+  TransactionId transactionId;
+  int64_t postUs;
+
+  status = mManager->allocate(mConnectionId, vecParams, &allocHandle, &sbuffer);
+  ASSERT_TRUE(status == ResultStatus::OK);
+  ASSERT_TRUE(TestBufferPoolAllocator::Fill(allocHandle, 0x77));
+  status = mManager->postSend(mReceiverId, sbuffer, &transactionId, &postUs);
+  ASSERT_TRUE(status == ResultStatus::OK);
+  status = mManager->receive(mReceiverId, transactionId, sbuffer->mId, postUs,
+                             &recvHandle, &rbuffer);
+  EXPECT_TRUE(status == ResultStatus::OK);
+  ASSERT_TRUE(TestBufferPoolAllocator::Verify(recvHandle, 0x77));
+}
+
+}  // anonymous namespace
+
+int main(int argc, char** argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  int status = RUN_ALL_TESTS();
+  LOG(INFO) << "Test result = " << status;
+  return status;
+}
diff --git a/media/bufferpool/2.0/Accessor.cpp b/media/bufferpool/2.0/Accessor.cpp
new file mode 100644
index 0000000..57b4609
--- /dev/null
+++ b/media/bufferpool/2.0/Accessor.cpp
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "BufferPoolConnection"
+
+#include "Accessor.h"
+#include "AccessorImpl.h"
+#include "Connection.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V2_0 {
+namespace implementation {
+
+void ConnectionDeathRecipient::add(
+        int64_t connectionId,
+        const sp<Accessor> &accessor) {
+    std::lock_guard<std::mutex> lock(mLock);
+    if (mAccessors.find(connectionId) == mAccessors.end()) {
+        mAccessors.insert(std::make_pair(connectionId, accessor));
+    }
+}
+
+void ConnectionDeathRecipient::remove(int64_t connectionId) {
+    std::lock_guard<std::mutex> lock(mLock);
+    mAccessors.erase(connectionId);
+    auto it = mConnectionToCookie.find(connectionId);
+    if (it != mConnectionToCookie.end()) {
+        uint64_t cookie = it->second;
+        mConnectionToCookie.erase(it);
+        auto cit = mCookieToConnections.find(cookie);
+        if (cit != mCookieToConnections.end()) {
+            cit->second.erase(connectionId);
+            if (cit->second.size() == 0) {
+                mCookieToConnections.erase(cit);
+            }
+        }
+    }
+}
+
+void ConnectionDeathRecipient::addCookieToConnection(
+        uint64_t cookie,
+        int64_t connectionId) {
+    std::lock_guard<std::mutex> lock(mLock);
+    if (mAccessors.find(connectionId) == mAccessors.end()) {
+        return;
+    }
+    mConnectionToCookie.insert(std::make_pair(connectionId, cookie));
+    auto it = mCookieToConnections.find(cookie);
+    if (it != mCookieToConnections.end()) {
+        it->second.insert(connectionId);
+    } else {
+        mCookieToConnections.insert(std::make_pair(
+                cookie, std::set<int64_t>{connectionId}));
+    }
+}
+
+void ConnectionDeathRecipient::serviceDied(
+        uint64_t cookie,
+        const wp<::android::hidl::base::V1_0::IBase>& /* who */
+        ) {
+    std::map<int64_t, const wp<Accessor>> connectionsToClose;
+    {
+        std::lock_guard<std::mutex> lock(mLock);
+
+        auto it = mCookieToConnections.find(cookie);
+        if (it != mCookieToConnections.end()) {
+            for (auto conIt = it->second.begin(); conIt != it->second.end(); ++conIt) {
+                auto accessorIt = mAccessors.find(*conIt);
+                if (accessorIt != mAccessors.end()) {
+                    connectionsToClose.insert(std::make_pair(*conIt, accessorIt->second));
+                    mAccessors.erase(accessorIt);
+                }
+                mConnectionToCookie.erase(*conIt);
+            }
+            mCookieToConnections.erase(it);
+        }
+    }
+
+    if (connectionsToClose.size() > 0) {
+        sp<Accessor> accessor;
+        for (auto it = connectionsToClose.begin(); it != connectionsToClose.end(); ++it) {
+            accessor = it->second.promote();
+
+            if (accessor) {
+                accessor->close(it->first);
+                ALOGD("connection %lld closed on death", (long long)it->first);
+            }
+        }
+    }
+}
+
+namespace {
+static sp<ConnectionDeathRecipient> sConnectionDeathRecipient =
+        new ConnectionDeathRecipient();
+}
+
+sp<ConnectionDeathRecipient> Accessor::getConnectionDeathRecipient() {
+    return sConnectionDeathRecipient;
+}
+
+void Accessor::createInvalidator() {
+    Accessor::Impl::createInvalidator();
+}
+
+// Methods from ::android::hardware::media::bufferpool::V2_0::IAccessor follow.
+Return<void> Accessor::connect(
+        const sp<::android::hardware::media::bufferpool::V2_0::IObserver>& observer,
+        connect_cb _hidl_cb) {
+    sp<Connection> connection;
+    ConnectionId connectionId;
+    uint32_t msgId;
+    const StatusDescriptor* fmqDesc;
+    const InvalidationDescriptor* invDesc;
+
+    ResultStatus status = connect(
+            observer, false, &connection, &connectionId, &msgId, &fmqDesc, &invDesc);
+    if (status == ResultStatus::OK) {
+        _hidl_cb(status, connection, connectionId, msgId, *fmqDesc, *invDesc);
+    } else {
+        _hidl_cb(status, nullptr, -1LL, 0,
+                 android::hardware::MQDescriptorSync<BufferStatusMessage>(
+                         std::vector<android::hardware::GrantorDescriptor>(),
+                         nullptr /* nhandle */, 0 /* size */),
+                 android::hardware::MQDescriptorUnsync<BufferInvalidationMessage>(
+                         std::vector<android::hardware::GrantorDescriptor>(),
+                         nullptr /* nhandle */, 0 /* size */));
+    }
+    return Void();
+}
+
+Accessor::Accessor(const std::shared_ptr<BufferPoolAllocator> &allocator)
+    : mImpl(new Impl(allocator)) {}
+
+Accessor::~Accessor() {
+}
+
+bool Accessor::isValid() {
+    return (bool)mImpl && mImpl->isValid();
+}
+
+ResultStatus Accessor::flush() {
+    if (mImpl) {
+        mImpl->flush();
+        return ResultStatus::OK;
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus Accessor::allocate(
+        ConnectionId connectionId,
+        const std::vector<uint8_t> &params,
+        BufferId *bufferId, const native_handle_t** handle) {
+    if (mImpl) {
+        return mImpl->allocate(connectionId, params, bufferId, handle);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus Accessor::fetch(
+        ConnectionId connectionId, TransactionId transactionId,
+        BufferId bufferId, const native_handle_t** handle) {
+    if (mImpl) {
+        return mImpl->fetch(connectionId, transactionId, bufferId, handle);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus Accessor::connect(
+        const sp<IObserver> &observer, bool local,
+        sp<Connection> *connection, ConnectionId *pConnectionId,
+        uint32_t *pMsgId,
+        const StatusDescriptor** statusDescPtr,
+        const InvalidationDescriptor** invDescPtr) {
+    if (mImpl) {
+        ResultStatus status = mImpl->connect(
+                this, observer, connection, pConnectionId, pMsgId,
+                statusDescPtr, invDescPtr);
+        if (!local && status == ResultStatus::OK) {
+            sp<Accessor> accessor(this);
+            sConnectionDeathRecipient->add(*pConnectionId, accessor);
+        }
+        return status;
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus Accessor::close(ConnectionId connectionId) {
+    if (mImpl) {
+        ResultStatus status = mImpl->close(connectionId);
+        sConnectionDeathRecipient->remove(connectionId);
+        return status;
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+void Accessor::cleanUp(bool clearCache) {
+    if (mImpl) {
+        mImpl->cleanUp(clearCache);
+    }
+}
+
+//IAccessor* HIDL_FETCH_IAccessor(const char* /* name */) {
+//    return new Accessor();
+//}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
diff --git a/media/bufferpool/2.0/Accessor.h b/media/bufferpool/2.0/Accessor.h
new file mode 100644
index 0000000..8d02519
--- /dev/null
+++ b/media/bufferpool/2.0/Accessor.h
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_ACCESSOR_H
+#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_ACCESSOR_H
+
+#include <android/hardware/media/bufferpool/2.0/IAccessor.h>
+#include <android/hardware/media/bufferpool/2.0/IObserver.h>
+#include <bufferpool/BufferPoolTypes.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include "BufferStatus.h"
+
+#include <set>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct Accessor;
+struct Connection;
+
+/**
+ * Receives death notifications from remote connections.
+ * On death notifications, the connections are closed and used resources
+ * are released.
+ */
+struct ConnectionDeathRecipient : public hardware::hidl_death_recipient {
+    /**
+     * Registers a newly connected connection from remote processes.
+     */
+    void add(int64_t connectionId, const sp<Accessor> &accessor);
+
+    /**
+     * Removes a connection.
+     */
+    void remove(int64_t connectionId);
+
+    void addCookieToConnection(uint64_t cookie, int64_t connectionId);
+
+    virtual void serviceDied(
+            uint64_t /* cookie */,
+            const wp<::android::hidl::base::V1_0::IBase>& /* who */
+            ) override;
+
+private:
+    std::mutex mLock;
+    std::map<uint64_t, std::set<int64_t>>  mCookieToConnections;
+    std::map<int64_t, uint64_t> mConnectionToCookie;
+    std::map<int64_t, const wp<Accessor>> mAccessors;
+};
+
+/**
+ * A buffer pool accessor which enables a buffer pool to communicate with buffer
+ * pool clients. 1:1 correspondense holds between a buffer pool and an accessor.
+ */
+struct Accessor : public IAccessor {
+    // Methods from ::android::hardware::media::bufferpool::V2_0::IAccessor follow.
+    Return<void> connect(const sp<::android::hardware::media::bufferpool::V2_0::IObserver>& observer, connect_cb _hidl_cb) override;
+
+    /**
+     * Creates a buffer pool accessor which uses the specified allocator.
+     *
+     * @param allocator buffer allocator.
+     */
+    explicit Accessor(const std::shared_ptr<BufferPoolAllocator> &allocator);
+
+    /** Destructs a buffer pool accessor. */
+    ~Accessor();
+
+    /** Returns whether the accessor is valid. */
+    bool isValid();
+
+    /** Invalidates all buffers which are owned by bufferpool */
+    ResultStatus flush();
+
+    /** Allocates a buffer from a buffer pool.
+     *
+     * @param connectionId  the connection id of the client.
+     * @param params        the allocation parameters.
+     * @param bufferId      the id of the allocated buffer.
+     * @param handle        the native handle of the allocated buffer.
+     *
+     * @return OK when a buffer is successfully allocated.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus allocate(
+            ConnectionId connectionId,
+            const std::vector<uint8_t>& params,
+            BufferId *bufferId,
+            const native_handle_t** handle);
+
+    /**
+     * Fetches a buffer for the specified transaction.
+     *
+     * @param connectionId  the id of receiving connection(client).
+     * @param transactionId the id of the transfer transaction.
+     * @param bufferId      the id of the buffer to be fetched.
+     * @param handle        the native handle of the fetched buffer.
+     *
+     * @return OK when a buffer is successfully fetched.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus fetch(
+            ConnectionId connectionId,
+            TransactionId transactionId,
+            BufferId bufferId,
+            const native_handle_t** handle);
+
+    /**
+     * Makes a connection to the buffer pool. The buffer pool client uses the
+     * created connection in order to communicate with the buffer pool. An
+     * FMQ for buffer status message is also created for the client.
+     *
+     * @param observer      client observer for buffer invalidation
+     * @param local         true when a connection request comes from local process,
+     *                      false otherwise.
+     * @param connection    created connection
+     * @param pConnectionId the id of the created connection
+     * @param pMsgId        the id of the recent buffer pool message
+     * @param statusDescPtr FMQ descriptor for shared buffer status message
+     *                      queue between a buffer pool and the client.
+     * @param invDescPtr    FMQ descriptor for buffer invalidation message
+     *                      queue from a buffer pool to the client.
+     *
+     * @return OK when a connection is successfully made.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus connect(
+            const sp<IObserver>& observer,
+            bool local,
+            sp<Connection> *connection, ConnectionId *pConnectionId,
+            uint32_t *pMsgId,
+            const StatusDescriptor** statusDescPtr,
+            const InvalidationDescriptor** invDescPtr);
+
+    /**
+     * Closes the specified connection to the client.
+     *
+     * @param connectionId  the id of the connection.
+     *
+     * @return OK when the connection is closed.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus close(ConnectionId connectionId);
+
+    /**
+     * Processes pending buffer status messages and perfoms periodic cache
+     * cleaning.
+     *
+     * @param clearCache    if clearCache is true, it frees all buffers waiting
+     *                      to be recycled.
+     */
+    void cleanUp(bool clearCache);
+
+    /**
+     * Gets a hidl_death_recipient for remote connection death.
+     */
+    static sp<ConnectionDeathRecipient> getConnectionDeathRecipient();
+
+    static void createInvalidator();
+
+private:
+    class Impl;
+    std::shared_ptr<Impl> mImpl;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_ACCESSOR_H
diff --git a/media/bufferpool/2.0/AccessorImpl.cpp b/media/bufferpool/2.0/AccessorImpl.cpp
new file mode 100644
index 0000000..94cf006
--- /dev/null
+++ b/media/bufferpool/2.0/AccessorImpl.cpp
@@ -0,0 +1,861 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BufferPoolAccessor"
+//#define LOG_NDEBUG 0
+
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+#include <utils/Log.h>
+#include <thread>
+#include "AccessorImpl.h"
+#include "Connection.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V2_0 {
+namespace implementation {
+
+namespace {
+    static constexpr int64_t kCleanUpDurationUs = 500000; // TODO tune 0.5 sec
+    static constexpr int64_t kLogDurationUs = 5000000; // 5 secs
+
+    static constexpr size_t kMinAllocBytesForEviction = 1024*1024*15;
+    static constexpr size_t kMinBufferCountForEviction = 40;
+}
+
+// Buffer structure in bufferpool process
+struct InternalBuffer {
+    BufferId mId;
+    size_t mOwnerCount;
+    size_t mTransactionCount;
+    const std::shared_ptr<BufferPoolAllocation> mAllocation;
+    const size_t mAllocSize;
+    const std::vector<uint8_t> mConfig;
+    bool mInvalidated;
+
+    InternalBuffer(
+            BufferId id,
+            const std::shared_ptr<BufferPoolAllocation> &alloc,
+            const size_t allocSize,
+            const std::vector<uint8_t> &allocConfig)
+            : mId(id), mOwnerCount(0), mTransactionCount(0),
+            mAllocation(alloc), mAllocSize(allocSize), mConfig(allocConfig),
+            mInvalidated(false) {}
+
+    const native_handle_t *handle() {
+        return mAllocation->handle();
+    }
+
+    void invalidate() {
+        mInvalidated = true;
+    }
+};
+
+struct TransactionStatus {
+    TransactionId mId;
+    BufferId mBufferId;
+    ConnectionId mSender;
+    ConnectionId mReceiver;
+    BufferStatus mStatus;
+    int64_t mTimestampUs;
+    bool mSenderValidated;
+
+    TransactionStatus(const BufferStatusMessage &message, int64_t timestampUs) {
+        mId = message.transactionId;
+        mBufferId = message.bufferId;
+        mStatus = message.newStatus;
+        mTimestampUs = timestampUs;
+        if (mStatus == BufferStatus::TRANSFER_TO) {
+            mSender = message.connectionId;
+            mReceiver = message.targetConnectionId;
+            mSenderValidated = true;
+        } else {
+            mSender = -1LL;
+            mReceiver = message.connectionId;
+            mSenderValidated = false;
+        }
+    }
+};
+
+// Helper template methods for handling map of set.
+template<class T, class U>
+bool insert(std::map<T, std::set<U>> *mapOfSet, T key, U value) {
+    auto iter = mapOfSet->find(key);
+    if (iter == mapOfSet->end()) {
+        std::set<U> valueSet{value};
+        mapOfSet->insert(std::make_pair(key, valueSet));
+        return true;
+    } else if (iter->second.find(value)  == iter->second.end()) {
+        iter->second.insert(value);
+        return true;
+    }
+    return false;
+}
+
+template<class T, class U>
+bool erase(std::map<T, std::set<U>> *mapOfSet, T key, U value) {
+    bool ret = false;
+    auto iter = mapOfSet->find(key);
+    if (iter != mapOfSet->end()) {
+        if (iter->second.erase(value) > 0) {
+            ret = true;
+        }
+        if (iter->second.size() == 0) {
+            mapOfSet->erase(iter);
+        }
+    }
+    return ret;
+}
+
+template<class T, class U>
+bool contains(std::map<T, std::set<U>> *mapOfSet, T key, U value) {
+    auto iter = mapOfSet->find(key);
+    if (iter != mapOfSet->end()) {
+        auto setIter = iter->second.find(value);
+        return setIter != iter->second.end();
+    }
+    return false;
+}
+
+int32_t Accessor::Impl::sPid = getpid();
+uint32_t Accessor::Impl::sSeqId = time(nullptr);
+
+Accessor::Impl::Impl(
+        const std::shared_ptr<BufferPoolAllocator> &allocator)
+        : mAllocator(allocator) {}
+
+Accessor::Impl::~Impl() {
+}
+
+ResultStatus Accessor::Impl::connect(
+        const sp<Accessor> &accessor, const sp<IObserver> &observer,
+        sp<Connection> *connection,
+        ConnectionId *pConnectionId,
+        uint32_t *pMsgId,
+        const StatusDescriptor** statusDescPtr,
+        const InvalidationDescriptor** invDescPtr) {
+    sp<Connection> newConnection = new Connection();
+    ResultStatus status = ResultStatus::CRITICAL_ERROR;
+    {
+        std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+        if (newConnection) {
+            ConnectionId id = (int64_t)sPid << 32 | sSeqId;
+            status = mBufferPool.mObserver.open(id, statusDescPtr);
+            if (status == ResultStatus::OK) {
+                newConnection->initialize(accessor, id);
+                *connection = newConnection;
+                *pConnectionId = id;
+                *pMsgId = mBufferPool.mInvalidation.mInvalidationId;
+                mBufferPool.mInvalidationChannel.getDesc(invDescPtr);
+                mBufferPool.mInvalidation.onConnect(id, observer);
+                ++sSeqId;
+            }
+
+        }
+        mBufferPool.processStatusMessages();
+        mBufferPool.cleanUp();
+    }
+    return status;
+}
+
+ResultStatus Accessor::Impl::close(ConnectionId connectionId) {
+    std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+    ALOGV("connection close %lld: %u", (long long)connectionId, mBufferPool.mInvalidation.mId);
+    mBufferPool.processStatusMessages();
+    mBufferPool.handleClose(connectionId);
+    mBufferPool.mObserver.close(connectionId);
+    mBufferPool.mInvalidation.onClose(connectionId);
+    // Since close# will be called after all works are finished, it is OK to
+    // evict unused buffers.
+    mBufferPool.cleanUp(true);
+    return ResultStatus::OK;
+}
+
+ResultStatus Accessor::Impl::allocate(
+        ConnectionId connectionId, const std::vector<uint8_t>& params,
+        BufferId *bufferId, const native_handle_t** handle) {
+    std::unique_lock<std::mutex> lock(mBufferPool.mMutex);
+    mBufferPool.processStatusMessages();
+    ResultStatus status = ResultStatus::OK;
+    if (!mBufferPool.getFreeBuffer(mAllocator, params, bufferId, handle)) {
+        lock.unlock();
+        std::shared_ptr<BufferPoolAllocation> alloc;
+        size_t allocSize;
+        status = mAllocator->allocate(params, &alloc, &allocSize);
+        lock.lock();
+        if (status == ResultStatus::OK) {
+            status = mBufferPool.addNewBuffer(alloc, allocSize, params, bufferId, handle);
+        }
+        ALOGV("create a buffer %d : %u %p",
+              status == ResultStatus::OK, *bufferId, *handle);
+    }
+    if (status == ResultStatus::OK) {
+        // TODO: handle ownBuffer failure
+        mBufferPool.handleOwnBuffer(connectionId, *bufferId);
+    }
+    mBufferPool.cleanUp();
+    return status;
+}
+
+ResultStatus Accessor::Impl::fetch(
+        ConnectionId connectionId, TransactionId transactionId,
+        BufferId bufferId, const native_handle_t** handle) {
+    std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+    mBufferPool.processStatusMessages();
+    auto found = mBufferPool.mTransactions.find(transactionId);
+    if (found != mBufferPool.mTransactions.end() &&
+            contains(&mBufferPool.mPendingTransactions,
+                     connectionId, transactionId)) {
+        if (found->second->mSenderValidated &&
+                found->second->mStatus == BufferStatus::TRANSFER_FROM &&
+                found->second->mBufferId == bufferId) {
+            found->second->mStatus = BufferStatus::TRANSFER_FETCH;
+            auto bufferIt = mBufferPool.mBuffers.find(bufferId);
+            if (bufferIt != mBufferPool.mBuffers.end()) {
+                mBufferPool.mStats.onBufferFetched();
+                *handle = bufferIt->second->handle();
+                return ResultStatus::OK;
+            }
+        }
+    }
+    mBufferPool.cleanUp();
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+void Accessor::Impl::cleanUp(bool clearCache) {
+    // transaction timeout, buffer cacheing TTL handling
+    std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+    mBufferPool.processStatusMessages();
+    mBufferPool.cleanUp(clearCache);
+}
+
+void Accessor::Impl::flush() {
+    std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+    mBufferPool.processStatusMessages();
+    mBufferPool.flush(shared_from_this());
+}
+
+void Accessor::Impl::handleInvalidateAck() {
+    std::map<ConnectionId, const sp<IObserver>> observers;
+    uint32_t invalidationId;
+    {
+        std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+        mBufferPool.processStatusMessages();
+        mBufferPool.mInvalidation.onHandleAck(&observers, &invalidationId);
+    }
+    // Do not hold lock for send invalidations
+    size_t deadClients = 0;
+    for (auto it = observers.begin(); it != observers.end(); ++it) {
+        const sp<IObserver> observer = it->second;
+        if (observer) {
+            Return<void> transResult = observer->onMessage(it->first, invalidationId);
+            if (!transResult.isOk()) {
+                ++deadClients;
+            }
+        }
+    }
+    if (deadClients > 0) {
+        ALOGD("During invalidation found %zu dead clients", deadClients);
+    }
+}
+
+bool Accessor::Impl::isValid() {
+    return mBufferPool.isValid();
+}
+
+Accessor::Impl::Impl::BufferPool::BufferPool()
+    : mTimestampUs(getTimestampNow()),
+      mLastCleanUpUs(mTimestampUs),
+      mLastLogUs(mTimestampUs),
+      mSeq(0),
+      mStartSeq(0) {
+    mValid = mInvalidationChannel.isValid();
+}
+
+
+// Statistics helper
+template<typename T, typename S>
+int percentage(T base, S total) {
+    return int(total ? 0.5 + 100. * static_cast<S>(base) / total : 0);
+}
+
+std::atomic<std::uint32_t> Accessor::Impl::BufferPool::Invalidation::sInvSeqId(0);
+
+Accessor::Impl::Impl::BufferPool::~BufferPool() {
+    std::lock_guard<std::mutex> lock(mMutex);
+    ALOGD("Destruction - bufferpool2 %p "
+          "cached: %zu/%zuM, %zu/%d%% in use; "
+          "allocs: %zu, %d%% recycled; "
+          "transfers: %zu, %d%% unfetced",
+          this, mStats.mBuffersCached, mStats.mSizeCached >> 20,
+          mStats.mBuffersInUse, percentage(mStats.mBuffersInUse, mStats.mBuffersCached),
+          mStats.mTotalAllocations, percentage(mStats.mTotalRecycles, mStats.mTotalAllocations),
+          mStats.mTotalTransfers,
+          percentage(mStats.mTotalTransfers - mStats.mTotalFetches, mStats.mTotalTransfers));
+}
+
+void Accessor::Impl::BufferPool::Invalidation::onConnect(
+        ConnectionId conId, const sp<IObserver>& observer) {
+    mAcks[conId] = mInvalidationId; // starts from current invalidationId
+    mObservers.insert(std::make_pair(conId, observer));
+}
+
+void Accessor::Impl::BufferPool::Invalidation::onClose(ConnectionId conId) {
+    mAcks.erase(conId);
+    mObservers.erase(conId);
+}
+
+void Accessor::Impl::BufferPool::Invalidation::onAck(
+        ConnectionId conId,
+        uint32_t msgId) {
+    auto it = mAcks.find(conId);
+    if (it == mAcks.end()) {
+        ALOGW("ACK from inconsistent connection! %lld", (long long)conId);
+        return;
+    }
+    if (isMessageLater(msgId, it->second)) {
+        mAcks[conId] = msgId;
+    }
+}
+
+void Accessor::Impl::BufferPool::Invalidation::onBufferInvalidated(
+        BufferId bufferId,
+        BufferInvalidationChannel &channel) {
+    for (auto it = mPendings.begin(); it != mPendings.end();) {
+        if (it->isInvalidated(bufferId)) {
+            uint32_t msgId = 0;
+            if (it->mNeedsAck) {
+                msgId = ++mInvalidationId;
+                if (msgId == 0) {
+                    // wrap happens
+                    msgId = ++mInvalidationId;
+                }
+            }
+            channel.postInvalidation(msgId, it->mFrom, it->mTo);
+            it = mPendings.erase(it);
+            continue;
+        }
+        ++it;
+    }
+}
+
+void Accessor::Impl::BufferPool::Invalidation::onInvalidationRequest(
+        bool needsAck,
+        uint32_t from,
+        uint32_t to,
+        size_t left,
+        BufferInvalidationChannel &channel,
+        const std::shared_ptr<Accessor::Impl> &impl) {
+        uint32_t msgId = 0;
+    if (needsAck) {
+        msgId = ++mInvalidationId;
+        if (msgId == 0) {
+            // wrap happens
+            msgId = ++mInvalidationId;
+        }
+    }
+    ALOGV("bufferpool2 invalidation requested and queued");
+    if (left == 0) {
+        channel.postInvalidation(msgId, from, to);
+    } else {
+        // TODO: sending hint message?
+        ALOGV("bufferpoo2 invalidation requested and pending");
+        Pending pending(needsAck, from, to, left, impl);
+        mPendings.push_back(pending);
+    }
+    sInvalidator->addAccessor(mId, impl);
+}
+
+void Accessor::Impl::BufferPool::Invalidation::onHandleAck(
+        std::map<ConnectionId, const sp<IObserver>> *observers,
+        uint32_t *invalidationId) {
+    if (mInvalidationId != 0) {
+        *invalidationId = mInvalidationId;
+        std::set<int> deads;
+        for (auto it = mAcks.begin(); it != mAcks.end(); ++it) {
+            if (it->second != mInvalidationId) {
+                const sp<IObserver> observer = mObservers[it->first];
+                if (observer) {
+                    observers->emplace(it->first, observer);
+                    ALOGV("connection %lld will call observer (%u: %u)",
+                          (long long)it->first, it->second, mInvalidationId);
+                    // N.B: onMessage will be called later. ignore possibility of
+                    // onMessage# oneway call being lost.
+                    it->second = mInvalidationId;
+                } else {
+                    ALOGV("bufferpool2 observer died %lld", (long long)it->first);
+                    deads.insert(it->first);
+                }
+            }
+        }
+        if (deads.size() > 0) {
+            for (auto it = deads.begin(); it != deads.end(); ++it) {
+                onClose(*it);
+            }
+        }
+    }
+    if (mPendings.size() == 0) {
+        // All invalidation Ids are synced and no more pending invalidations.
+        sInvalidator->delAccessor(mId);
+    }
+}
+
+bool Accessor::Impl::BufferPool::handleOwnBuffer(
+        ConnectionId connectionId, BufferId bufferId) {
+
+    bool added = insert(&mUsingBuffers, connectionId, bufferId);
+    if (added) {
+        auto iter = mBuffers.find(bufferId);
+        iter->second->mOwnerCount++;
+    }
+    insert(&mUsingConnections, bufferId, connectionId);
+    return added;
+}
+
+bool Accessor::Impl::BufferPool::handleReleaseBuffer(
+        ConnectionId connectionId, BufferId bufferId) {
+    bool deleted = erase(&mUsingBuffers, connectionId, bufferId);
+    if (deleted) {
+        auto iter = mBuffers.find(bufferId);
+        iter->second->mOwnerCount--;
+        if (iter->second->mOwnerCount == 0 &&
+                iter->second->mTransactionCount == 0) {
+            if (!iter->second->mInvalidated) {
+                mStats.onBufferUnused(iter->second->mAllocSize);
+                mFreeBuffers.insert(bufferId);
+            } else {
+                mStats.onBufferUnused(iter->second->mAllocSize);
+                mStats.onBufferEvicted(iter->second->mAllocSize);
+                mBuffers.erase(iter);
+                mInvalidation.onBufferInvalidated(bufferId, mInvalidationChannel);
+            }
+        }
+    }
+    erase(&mUsingConnections, bufferId, connectionId);
+    ALOGV("release buffer %u : %d", bufferId, deleted);
+    return deleted;
+}
+
+bool Accessor::Impl::BufferPool::handleTransferTo(const BufferStatusMessage &message) {
+    auto completed = mCompletedTransactions.find(
+            message.transactionId);
+    if (completed != mCompletedTransactions.end()) {
+        // already completed
+        mCompletedTransactions.erase(completed);
+        return true;
+    }
+    // the buffer should exist and be owned.
+    auto bufferIter = mBuffers.find(message.bufferId);
+    if (bufferIter == mBuffers.end() ||
+            !contains(&mUsingBuffers, message.connectionId, message.bufferId)) {
+        return false;
+    }
+    auto found = mTransactions.find(message.transactionId);
+    if (found != mTransactions.end()) {
+        // transfer_from was received earlier.
+        found->second->mSender = message.connectionId;
+        found->second->mSenderValidated = true;
+        return true;
+    }
+    // TODO: verify there is target connection Id
+    mStats.onBufferSent();
+    mTransactions.insert(std::make_pair(
+            message.transactionId,
+            std::make_unique<TransactionStatus>(message, mTimestampUs)));
+    insert(&mPendingTransactions, message.targetConnectionId,
+           message.transactionId);
+    bufferIter->second->mTransactionCount++;
+    return true;
+}
+
+bool Accessor::Impl::BufferPool::handleTransferFrom(const BufferStatusMessage &message) {
+    auto found = mTransactions.find(message.transactionId);
+    if (found == mTransactions.end()) {
+        // TODO: is it feasible to check ownership here?
+        mStats.onBufferSent();
+        mTransactions.insert(std::make_pair(
+                message.transactionId,
+                std::make_unique<TransactionStatus>(message, mTimestampUs)));
+        insert(&mPendingTransactions, message.connectionId,
+               message.transactionId);
+        auto bufferIter = mBuffers.find(message.bufferId);
+        bufferIter->second->mTransactionCount++;
+    } else {
+        if (message.connectionId == found->second->mReceiver) {
+            found->second->mStatus = BufferStatus::TRANSFER_FROM;
+        }
+    }
+    return true;
+}
+
+bool Accessor::Impl::BufferPool::handleTransferResult(const BufferStatusMessage &message) {
+    auto found = mTransactions.find(message.transactionId);
+    if (found != mTransactions.end()) {
+        bool deleted = erase(&mPendingTransactions, message.connectionId,
+                             message.transactionId);
+        if (deleted) {
+            if (!found->second->mSenderValidated) {
+                mCompletedTransactions.insert(message.transactionId);
+            }
+            auto bufferIter = mBuffers.find(message.bufferId);
+            if (message.newStatus == BufferStatus::TRANSFER_OK) {
+                handleOwnBuffer(message.connectionId, message.bufferId);
+            }
+            bufferIter->second->mTransactionCount--;
+            if (bufferIter->second->mOwnerCount == 0
+                && bufferIter->second->mTransactionCount == 0) {
+                if (!bufferIter->second->mInvalidated) {
+                    mStats.onBufferUnused(bufferIter->second->mAllocSize);
+                    mFreeBuffers.insert(message.bufferId);
+                } else {
+                    mStats.onBufferUnused(bufferIter->second->mAllocSize);
+                    mStats.onBufferEvicted(bufferIter->second->mAllocSize);
+                    mBuffers.erase(bufferIter);
+                    mInvalidation.onBufferInvalidated(message.bufferId, mInvalidationChannel);
+                }
+            }
+            mTransactions.erase(found);
+        }
+        ALOGV("transfer finished %llu %u - %d", (unsigned long long)message.transactionId,
+              message.bufferId, deleted);
+        return deleted;
+    }
+    ALOGV("transfer not found %llu %u", (unsigned long long)message.transactionId,
+          message.bufferId);
+    return false;
+}
+
+void Accessor::Impl::BufferPool::processStatusMessages() {
+    std::vector<BufferStatusMessage> messages;
+    mObserver.getBufferStatusChanges(messages);
+    mTimestampUs = getTimestampNow();
+    for (BufferStatusMessage& message: messages) {
+        bool ret = false;
+        switch (message.newStatus) {
+            case BufferStatus::NOT_USED:
+                ret = handleReleaseBuffer(
+                        message.connectionId, message.bufferId);
+                break;
+            case BufferStatus::USED:
+                // not happening
+                break;
+            case BufferStatus::TRANSFER_TO:
+                ret = handleTransferTo(message);
+                break;
+            case BufferStatus::TRANSFER_FROM:
+                ret = handleTransferFrom(message);
+                break;
+            case BufferStatus::TRANSFER_TIMEOUT:
+                // TODO
+                break;
+            case BufferStatus::TRANSFER_LOST:
+                // TODO
+                break;
+            case BufferStatus::TRANSFER_FETCH:
+                // not happening
+                break;
+            case BufferStatus::TRANSFER_OK:
+            case BufferStatus::TRANSFER_ERROR:
+                ret = handleTransferResult(message);
+                break;
+            case BufferStatus::INVALIDATION_ACK:
+                mInvalidation.onAck(message.connectionId, message.bufferId);
+                ret = true;
+                break;
+        }
+        if (ret == false) {
+            ALOGW("buffer status message processing failure - message : %d connection : %lld",
+                  message.newStatus, (long long)message.connectionId);
+        }
+    }
+    messages.clear();
+}
+
+bool Accessor::Impl::BufferPool::handleClose(ConnectionId connectionId) {
+    // Cleaning buffers
+    auto buffers = mUsingBuffers.find(connectionId);
+    if (buffers != mUsingBuffers.end()) {
+        for (const BufferId& bufferId : buffers->second) {
+            bool deleted = erase(&mUsingConnections, bufferId, connectionId);
+            if (deleted) {
+                auto bufferIter = mBuffers.find(bufferId);
+                bufferIter->second->mOwnerCount--;
+                if (bufferIter->second->mOwnerCount == 0 &&
+                        bufferIter->second->mTransactionCount == 0) {
+                    // TODO: handle freebuffer insert fail
+                    if (!bufferIter->second->mInvalidated) {
+                        mStats.onBufferUnused(bufferIter->second->mAllocSize);
+                        mFreeBuffers.insert(bufferId);
+                    } else {
+                        mStats.onBufferUnused(bufferIter->second->mAllocSize);
+                        mStats.onBufferEvicted(bufferIter->second->mAllocSize);
+                        mBuffers.erase(bufferIter);
+                        mInvalidation.onBufferInvalidated(bufferId, mInvalidationChannel);
+                    }
+                }
+            }
+        }
+        mUsingBuffers.erase(buffers);
+    }
+
+    // Cleaning transactions
+    auto pending = mPendingTransactions.find(connectionId);
+    if (pending != mPendingTransactions.end()) {
+        for (const TransactionId& transactionId : pending->second) {
+            auto iter = mTransactions.find(transactionId);
+            if (iter != mTransactions.end()) {
+                if (!iter->second->mSenderValidated) {
+                    mCompletedTransactions.insert(transactionId);
+                }
+                BufferId bufferId = iter->second->mBufferId;
+                auto bufferIter = mBuffers.find(bufferId);
+                bufferIter->second->mTransactionCount--;
+                if (bufferIter->second->mOwnerCount == 0 &&
+                    bufferIter->second->mTransactionCount == 0) {
+                    // TODO: handle freebuffer insert fail
+                    if (!bufferIter->second->mInvalidated) {
+                        mStats.onBufferUnused(bufferIter->second->mAllocSize);
+                        mFreeBuffers.insert(bufferId);
+                    } else {
+                        mStats.onBufferUnused(bufferIter->second->mAllocSize);
+                        mStats.onBufferEvicted(bufferIter->second->mAllocSize);
+                        mBuffers.erase(bufferIter);
+                        mInvalidation.onBufferInvalidated(bufferId, mInvalidationChannel);
+                    }
+                }
+                mTransactions.erase(iter);
+            }
+        }
+    }
+    return true;
+}
+
+bool Accessor::Impl::BufferPool::getFreeBuffer(
+        const std::shared_ptr<BufferPoolAllocator> &allocator,
+        const std::vector<uint8_t> &params, BufferId *pId,
+        const native_handle_t** handle) {
+    auto bufferIt = mFreeBuffers.begin();
+    for (;bufferIt != mFreeBuffers.end(); ++bufferIt) {
+        BufferId bufferId = *bufferIt;
+        if (allocator->compatible(params, mBuffers[bufferId]->mConfig)) {
+            break;
+        }
+    }
+    if (bufferIt != mFreeBuffers.end()) {
+        BufferId id = *bufferIt;
+        mFreeBuffers.erase(bufferIt);
+        mStats.onBufferRecycled(mBuffers[id]->mAllocSize);
+        *handle = mBuffers[id]->handle();
+        *pId = id;
+        ALOGV("recycle a buffer %u %p", id, *handle);
+        return true;
+    }
+    return false;
+}
+
+ResultStatus Accessor::Impl::BufferPool::addNewBuffer(
+        const std::shared_ptr<BufferPoolAllocation> &alloc,
+        const size_t allocSize,
+        const std::vector<uint8_t> &params,
+        BufferId *pId,
+        const native_handle_t** handle) {
+
+    BufferId bufferId = mSeq++;
+    if (mSeq == Connection::SYNC_BUFFERID) {
+        mSeq = 0;
+    }
+    std::unique_ptr<InternalBuffer> buffer =
+            std::make_unique<InternalBuffer>(
+                    bufferId, alloc, allocSize, params);
+    if (buffer) {
+        auto res = mBuffers.insert(std::make_pair(
+                bufferId, std::move(buffer)));
+        if (res.second) {
+            mStats.onBufferAllocated(allocSize);
+            *handle = alloc->handle();
+            *pId = bufferId;
+            return ResultStatus::OK;
+        }
+    }
+    return ResultStatus::NO_MEMORY;
+}
+
+void Accessor::Impl::BufferPool::cleanUp(bool clearCache) {
+    if (clearCache || mTimestampUs > mLastCleanUpUs + kCleanUpDurationUs) {
+        mLastCleanUpUs = mTimestampUs;
+        if (mTimestampUs > mLastLogUs + kLogDurationUs) {
+            mLastLogUs = mTimestampUs;
+            ALOGD("bufferpool2 %p : %zu(%zu size) total buffers - "
+                  "%zu(%zu size) used buffers - %zu/%zu (recycle/alloc) - "
+                  "%zu/%zu (fetch/transfer)",
+                  this, mStats.mBuffersCached, mStats.mSizeCached,
+                  mStats.mBuffersInUse, mStats.mSizeInUse,
+                  mStats.mTotalRecycles, mStats.mTotalAllocations,
+                  mStats.mTotalFetches, mStats.mTotalTransfers);
+        }
+        for (auto freeIt = mFreeBuffers.begin(); freeIt != mFreeBuffers.end();) {
+            if (!clearCache && mStats.mSizeCached < kMinAllocBytesForEviction
+                    && mBuffers.size() < kMinBufferCountForEviction) {
+                break;
+            }
+            auto it = mBuffers.find(*freeIt);
+            if (it != mBuffers.end() &&
+                    it->second->mOwnerCount == 0 && it->second->mTransactionCount == 0) {
+                mStats.onBufferEvicted(it->second->mAllocSize);
+                mBuffers.erase(it);
+                freeIt = mFreeBuffers.erase(freeIt);
+            } else {
+                ++freeIt;
+                ALOGW("bufferpool2 inconsistent!");
+            }
+        }
+    }
+}
+
+void Accessor::Impl::BufferPool::invalidate(
+        bool needsAck, BufferId from, BufferId to,
+        const std::shared_ptr<Accessor::Impl> &impl) {
+    for (auto freeIt = mFreeBuffers.begin(); freeIt != mFreeBuffers.end();) {
+        if (isBufferInRange(from, to, *freeIt)) {
+            auto it = mBuffers.find(*freeIt);
+            if (it != mBuffers.end() &&
+                it->second->mOwnerCount == 0 && it->second->mTransactionCount == 0) {
+                mStats.onBufferEvicted(it->second->mAllocSize);
+                mBuffers.erase(it);
+                freeIt = mFreeBuffers.erase(freeIt);
+                continue;
+            } else {
+                ALOGW("bufferpool2 inconsistent!");
+            }
+        }
+        ++freeIt;
+    }
+
+    size_t left = 0;
+    for (auto it = mBuffers.begin(); it != mBuffers.end(); ++it) {
+        if (isBufferInRange(from, to, it->first)) {
+            it->second->invalidate();
+            ++left;
+        }
+    }
+    mInvalidation.onInvalidationRequest(needsAck, from, to, left, mInvalidationChannel, impl);
+}
+
+void Accessor::Impl::BufferPool::flush(const std::shared_ptr<Accessor::Impl> &impl) {
+    BufferId from = mStartSeq;
+    BufferId to = mSeq;
+    mStartSeq = mSeq;
+    // TODO: needsAck params 
+    ALOGV("buffer invalidation request bp:%u %u %u", mInvalidation.mId, from, to);
+    if (from != to) {
+        invalidate(true, from, to, impl);
+    }
+}
+
+void Accessor::Impl::invalidatorThread(
+            std::map<uint32_t, const std::weak_ptr<Accessor::Impl>> &accessors,
+            std::mutex &mutex,
+            std::condition_variable &cv,
+            bool &ready) {
+    while(true) {
+        std::map<uint32_t, const std::weak_ptr<Accessor::Impl>> copied;
+        {
+            std::unique_lock<std::mutex> lock(mutex);
+            if (!ready) {
+                cv.wait(lock);
+            }
+            copied.insert(accessors.begin(), accessors.end());
+        }
+        std::list<ConnectionId> erased;
+        for (auto it = copied.begin(); it != copied.end(); ++it) {
+            const std::shared_ptr<Accessor::Impl> impl = it->second.lock();
+            if (!impl) {
+                erased.push_back(it->first);
+            } else {
+                impl->handleInvalidateAck();
+            }
+        }
+        {
+            std::unique_lock<std::mutex> lock(mutex);
+            for (auto it = erased.begin(); it != erased.end(); ++it) {
+                accessors.erase(*it);
+            }
+            if (accessors.size() == 0) {
+                ready = false;
+            } else {
+                // prevent draining cpu.
+                lock.unlock();
+                std::this_thread::yield();
+            }
+        }
+    }
+}
+
+Accessor::Impl::AccessorInvalidator::AccessorInvalidator() : mReady(false) {
+    std::thread invalidator(
+            invalidatorThread,
+            std::ref(mAccessors),
+            std::ref(mMutex),
+            std::ref(mCv),
+            std::ref(mReady));
+    invalidator.detach();
+}
+
+void Accessor::Impl::AccessorInvalidator::addAccessor(
+        uint32_t accessorId, const std::weak_ptr<Accessor::Impl> &impl) {
+    bool notify = false;
+    std::unique_lock<std::mutex> lock(mMutex);
+    if (mAccessors.find(accessorId) == mAccessors.end()) {
+        if (!mReady) {
+            mReady = true;
+            notify = true;
+        }
+        mAccessors.insert(std::make_pair(accessorId, impl));
+        ALOGV("buffer invalidation added bp:%u %d", accessorId, notify);
+    }
+    lock.unlock();
+    if (notify) {
+        mCv.notify_one();
+    }
+}
+
+void Accessor::Impl::AccessorInvalidator::delAccessor(uint32_t accessorId) {
+    std::lock_guard<std::mutex> lock(mMutex);
+    mAccessors.erase(accessorId);
+    ALOGV("buffer invalidation deleted bp:%u", accessorId);
+    if (mAccessors.size() == 0) {
+        mReady = false;
+    }
+}
+
+std::unique_ptr<Accessor::Impl::AccessorInvalidator> Accessor::Impl::sInvalidator;
+
+void Accessor::Impl::createInvalidator() {
+    if (!sInvalidator) {
+        sInvalidator = std::make_unique<Accessor::Impl::AccessorInvalidator>();
+    }
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
diff --git a/media/bufferpool/2.0/AccessorImpl.h b/media/bufferpool/2.0/AccessorImpl.h
new file mode 100644
index 0000000..eea72b9
--- /dev/null
+++ b/media/bufferpool/2.0/AccessorImpl.h
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_ACCESSORIMPL_H
+#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_ACCESSORIMPL_H
+
+#include <map>
+#include <set>
+#include <condition_variable>
+#include "Accessor.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V2_0 {
+namespace implementation {
+
+struct InternalBuffer;
+struct TransactionStatus;
+
+/**
+ * An implementation of a buffer pool accessor(or a buffer pool implementation.) */
+class Accessor::Impl
+    : public std::enable_shared_from_this<Accessor::Impl> {
+public:
+    Impl(const std::shared_ptr<BufferPoolAllocator> &allocator);
+
+    ~Impl();
+
+    ResultStatus connect(
+            const sp<Accessor> &accessor, const sp<IObserver> &observer,
+            sp<Connection> *connection,
+            ConnectionId *pConnectionId,
+            uint32_t *pMsgId,
+            const StatusDescriptor** statusDescPtr,
+            const InvalidationDescriptor** invDescPtr);
+
+    ResultStatus close(ConnectionId connectionId);
+
+    ResultStatus allocate(ConnectionId connectionId,
+                          const std::vector<uint8_t>& params,
+                          BufferId *bufferId,
+                          const native_handle_t** handle);
+
+    ResultStatus fetch(ConnectionId connectionId,
+                       TransactionId transactionId,
+                       BufferId bufferId,
+                       const native_handle_t** handle);
+
+    void flush();
+
+    void cleanUp(bool clearCache);
+
+    bool isValid();
+
+    void handleInvalidateAck();
+
+    static void createInvalidator();
+
+private:
+    // ConnectionId = pid : (timestamp_created + seqId)
+    // in order to guarantee uniqueness for each connection
+    static uint32_t sSeqId;
+    static int32_t sPid;
+
+    const std::shared_ptr<BufferPoolAllocator> mAllocator;
+
+    /**
+     * Buffer pool implementation.
+     *
+     * Handles buffer status messages. Handles buffer allocation/recycling.
+     * Handles buffer transfer between buffer pool clients.
+     */
+    struct BufferPool {
+    private:
+        std::mutex mMutex;
+        int64_t mTimestampUs;
+        int64_t mLastCleanUpUs;
+        int64_t mLastLogUs;
+        BufferId mSeq;
+        BufferId mStartSeq;
+        bool mValid;
+        BufferStatusObserver mObserver;
+        BufferInvalidationChannel mInvalidationChannel;
+
+        std::map<ConnectionId, std::set<BufferId>> mUsingBuffers;
+        std::map<BufferId, std::set<ConnectionId>> mUsingConnections;
+
+        std::map<ConnectionId, std::set<TransactionId>> mPendingTransactions;
+        // Transactions completed before TRANSFER_TO message arrival.
+        // Fetch does not occur for the transactions.
+        // Only transaction id is kept for the transactions in short duration.
+        std::set<TransactionId> mCompletedTransactions;
+        // Currently active(pending) transations' status & information.
+        std::map<TransactionId, std::unique_ptr<TransactionStatus>>
+                mTransactions;
+
+        std::map<BufferId, std::unique_ptr<InternalBuffer>> mBuffers;
+        std::set<BufferId> mFreeBuffers;
+
+        struct Invalidation {
+            static std::atomic<std::uint32_t> sInvSeqId;
+
+            struct Pending {
+                bool mNeedsAck;
+                uint32_t mFrom;
+                uint32_t mTo;
+                size_t mLeft;
+                const std::weak_ptr<Accessor::Impl> mImpl;
+                Pending(bool needsAck, uint32_t from, uint32_t to, size_t left,
+                        const std::shared_ptr<Accessor::Impl> &impl)
+                        : mNeedsAck(needsAck),
+                          mFrom(from),
+                          mTo(to),
+                          mLeft(left),
+                          mImpl(impl)
+                {}
+
+                bool isInvalidated(uint32_t bufferId) {
+                    return isBufferInRange(mFrom, mTo, bufferId) && --mLeft == 0;
+                }
+            };
+
+            std::list<Pending> mPendings;
+            std::map<ConnectionId, uint32_t> mAcks;
+            std::map<ConnectionId, const sp<IObserver>> mObservers;
+            uint32_t mInvalidationId;
+            uint32_t mId;
+
+            Invalidation() : mInvalidationId(0), mId(sInvSeqId.fetch_add(1)) {}
+
+            void onConnect(ConnectionId conId, const sp<IObserver> &observer);
+
+            void onClose(ConnectionId conId);
+
+            void onAck(ConnectionId conId, uint32_t msgId);
+
+            void onBufferInvalidated(
+                    BufferId bufferId,
+                    BufferInvalidationChannel &channel);
+
+            void onInvalidationRequest(
+                    bool needsAck, uint32_t from, uint32_t to, size_t left,
+                    BufferInvalidationChannel &channel,
+                    const std::shared_ptr<Accessor::Impl> &impl);
+
+            void onHandleAck(
+                    std::map<ConnectionId, const sp<IObserver>> *observers,
+                    uint32_t *invalidationId);
+        } mInvalidation;
+        /// Buffer pool statistics which tracks allocation and transfer statistics.
+        struct Stats {
+            /// Total size of allocations which are used or available to use.
+            /// (bytes or pixels)
+            size_t mSizeCached;
+            /// # of cached buffers which are used or available to use.
+            size_t mBuffersCached;
+            /// Total size of allocations which are currently used. (bytes or pixels)
+            size_t mSizeInUse;
+            /// # of currently used buffers
+            size_t mBuffersInUse;
+
+            /// # of allocations called on bufferpool. (# of fetched from BlockPool)
+            size_t mTotalAllocations;
+            /// # of allocations that were served from the cache.
+            /// (# of allocator alloc prevented)
+            size_t mTotalRecycles;
+            /// # of buffer transfers initiated.
+            size_t mTotalTransfers;
+            /// # of transfers that had to be fetched.
+            size_t mTotalFetches;
+
+            Stats()
+                : mSizeCached(0), mBuffersCached(0), mSizeInUse(0), mBuffersInUse(0),
+                  mTotalAllocations(0), mTotalRecycles(0), mTotalTransfers(0), mTotalFetches(0) {}
+
+            /// A new buffer is allocated on an allocation request.
+            void onBufferAllocated(size_t allocSize) {
+                mSizeCached += allocSize;
+                mBuffersCached++;
+
+                mSizeInUse += allocSize;
+                mBuffersInUse++;
+
+                mTotalAllocations++;
+            }
+
+            /// A buffer is evicted and destroyed.
+            void onBufferEvicted(size_t allocSize) {
+                mSizeCached -= allocSize;
+                mBuffersCached--;
+            }
+
+            /// A buffer is recycled on an allocation request.
+            void onBufferRecycled(size_t allocSize) {
+                mSizeInUse += allocSize;
+                mBuffersInUse++;
+
+                mTotalAllocations++;
+                mTotalRecycles++;
+            }
+
+            /// A buffer is available to be recycled.
+            void onBufferUnused(size_t allocSize) {
+                mSizeInUse -= allocSize;
+                mBuffersInUse--;
+            }
+
+            /// A buffer transfer is initiated.
+            void onBufferSent() {
+                mTotalTransfers++;
+            }
+
+            /// A buffer fetch is invoked by a buffer transfer.
+            void onBufferFetched() {
+                mTotalFetches++;
+            }
+        } mStats;
+
+        bool isValid() {
+            return mValid;
+        }
+
+        void invalidate(bool needsAck, BufferId from, BufferId to,
+                        const std::shared_ptr<Accessor::Impl> &impl);
+
+        static void createInvalidator();
+
+    public:
+        /** Creates a buffer pool. */
+        BufferPool();
+
+        /** Destroys a buffer pool. */
+        ~BufferPool();
+
+        /**
+         * Processes all pending buffer status messages, and returns the result.
+         * Each status message is handled by methods with 'handle' prefix.
+         */
+        void processStatusMessages();
+
+        /**
+         * Handles a buffer being owned by a connection.
+         *
+         * @param connectionId  the id of the buffer owning connection.
+         * @param bufferId      the id of the buffer.
+         *
+         * @return {@code true} when the buffer is owned,
+         *         {@code false} otherwise.
+         */
+        bool handleOwnBuffer(ConnectionId connectionId, BufferId bufferId);
+
+        /**
+         * Handles a buffer being released by a connection.
+         *
+         * @param connectionId  the id of the buffer owning connection.
+         * @param bufferId      the id of the buffer.
+         *
+         * @return {@code true} when the buffer ownership is released,
+         *         {@code false} otherwise.
+         */
+        bool handleReleaseBuffer(ConnectionId connectionId, BufferId bufferId);
+
+        /**
+         * Handles a transfer transaction start message from the sender.
+         *
+         * @param message   a buffer status message for the transaction.
+         *
+         * @result {@code true} when transfer_to message is acknowledged,
+         *         {@code false} otherwise.
+         */
+        bool handleTransferTo(const BufferStatusMessage &message);
+
+        /**
+         * Handles a transfer transaction being acked by the receiver.
+         *
+         * @param message   a buffer status message for the transaction.
+         *
+         * @result {@code true} when transfer_from message is acknowledged,
+         *         {@code false} otherwise.
+         */
+        bool handleTransferFrom(const BufferStatusMessage &message);
+
+        /**
+         * Handles a transfer transaction result message from the receiver.
+         *
+         * @param message   a buffer status message for the transaction.
+         *
+         * @result {@code true} when the exisitng transaction is finished,
+         *         {@code false} otherwise.
+         */
+        bool handleTransferResult(const BufferStatusMessage &message);
+
+        /**
+         * Handles a connection being closed, and returns the result. All the
+         * buffers and transactions owned by the connection will be cleaned up.
+         * The related FMQ will be cleaned up too.
+         *
+         * @param connectionId  the id of the connection.
+         *
+         * @result {@code true} when the connection existed,
+         *         {@code false} otherwise.
+         */
+        bool handleClose(ConnectionId connectionId);
+
+        /**
+         * Recycles a existing free buffer if it is possible.
+         *
+         * @param allocator the buffer allocator
+         * @param params    the allocation parameters.
+         * @param pId       the id of the recycled buffer.
+         * @param handle    the native handle of the recycled buffer.
+         *
+         * @return {@code true} when a buffer is recycled, {@code false}
+         *         otherwise.
+         */
+        bool getFreeBuffer(
+                const std::shared_ptr<BufferPoolAllocator> &allocator,
+                const std::vector<uint8_t> &params,
+                BufferId *pId, const native_handle_t **handle);
+
+        /**
+         * Adds a newly allocated buffer to bufferpool.
+         *
+         * @param alloc     the newly allocated buffer.
+         * @param allocSize the size of the newly allocated buffer.
+         * @param params    the allocation parameters.
+         * @param pId       the buffer id for the newly allocated buffer.
+         * @param handle    the native handle for the newly allocated buffer.
+         *
+         * @return OK when an allocation is successfully allocated.
+         *         NO_MEMORY when there is no memory.
+         *         CRITICAL_ERROR otherwise.
+         */
+        ResultStatus addNewBuffer(
+                const std::shared_ptr<BufferPoolAllocation> &alloc,
+                const size_t allocSize,
+                const std::vector<uint8_t> &params,
+                BufferId *pId,
+                const native_handle_t **handle);
+
+        /**
+         * Processes pending buffer status messages and performs periodic cache
+         * cleaning.
+         *
+         * @param clearCache    if clearCache is true, it frees all buffers
+         *                      waiting to be recycled.
+         */
+        void cleanUp(bool clearCache = false);
+
+        /**
+         * Processes pending buffer status messages and invalidate all current
+         * free buffers. Active buffers are invalidated after being inactive.
+         */
+        void flush(const std::shared_ptr<Accessor::Impl> &impl);
+
+        friend class Accessor::Impl;
+    } mBufferPool;
+
+    struct  AccessorInvalidator {
+        std::map<uint32_t, const std::weak_ptr<Accessor::Impl>> mAccessors;
+        std::mutex mMutex;
+        std::condition_variable mCv;
+        bool mReady;
+
+        AccessorInvalidator();
+        void addAccessor(uint32_t accessorId, const std::weak_ptr<Accessor::Impl> &impl);
+        void delAccessor(uint32_t accessorId);
+    };
+
+    static std::unique_ptr<AccessorInvalidator> sInvalidator;
+
+    static void invalidatorThread(
+        std::map<uint32_t, const std::weak_ptr<Accessor::Impl>> &accessors,
+        std::mutex &mutex,
+        std::condition_variable &cv,
+        bool &ready);
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace ufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_ACCESSORIMPL_H
diff --git a/media/bufferpool/2.0/Android.bp b/media/bufferpool/2.0/Android.bp
new file mode 100644
index 0000000..c71ac17
--- /dev/null
+++ b/media/bufferpool/2.0/Android.bp
@@ -0,0 +1,33 @@
+cc_library {
+    name: "libstagefright_bufferpool@2.0",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
+    srcs: [
+        "Accessor.cpp",
+        "AccessorImpl.cpp",
+        "BufferPoolClient.cpp",
+        "BufferStatus.cpp",
+        "ClientManager.cpp",
+        "Connection.cpp",
+        "Observer.cpp",
+    ],
+    export_include_dirs: [
+        "include",
+    ],
+    shared_libs: [
+        "libcutils",
+        "libfmq",
+        "libhidlbase",
+        "libhwbinder",
+        "libhidltransport",
+        "liblog",
+        "libutils",
+        "android.hardware.media.bufferpool@2.0",
+    ],
+    export_shared_lib_headers: [
+        "libfmq",
+        "android.hardware.media.bufferpool@2.0",
+    ],
+}
diff --git a/media/bufferpool/2.0/BufferPoolClient.cpp b/media/bufferpool/2.0/BufferPoolClient.cpp
new file mode 100644
index 0000000..342fef6
--- /dev/null
+++ b/media/bufferpool/2.0/BufferPoolClient.cpp
@@ -0,0 +1,868 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BufferPoolClient"
+//#define LOG_NDEBUG 0
+
+#include <thread>
+#include <utils/Log.h>
+#include "BufferPoolClient.h"
+#include "Connection.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V2_0 {
+namespace implementation {
+
+static constexpr int64_t kReceiveTimeoutUs = 1000000; // 100ms
+static constexpr int kPostMaxRetry = 3;
+static constexpr int kCacheTtlUs = 1000000; // TODO: tune
+
+class BufferPoolClient::Impl
+        : public std::enable_shared_from_this<BufferPoolClient::Impl> {
+public:
+    explicit Impl(const sp<Accessor> &accessor, const sp<IObserver> &observer);
+
+    explicit Impl(const sp<IAccessor> &accessor, const sp<IObserver> &observer);
+
+    bool isValid() {
+        return mValid;
+    }
+
+    bool isLocal() {
+        return mValid && mLocal;
+    }
+
+    ConnectionId getConnectionId() {
+        return mConnectionId;
+    }
+
+    sp<IAccessor> &getAccessor() {
+        return mAccessor;
+    }
+
+    bool isActive(int64_t *lastTransactionUs, bool clearCache);
+
+    void receiveInvalidation(uint32_t msgID);
+
+    ResultStatus flush();
+
+    ResultStatus allocate(const std::vector<uint8_t> &params,
+                          native_handle_t **handle,
+                          std::shared_ptr<BufferPoolData> *buffer);
+
+    ResultStatus receive(
+            TransactionId transactionId, BufferId bufferId,
+            int64_t timestampUs,
+            native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer);
+
+    void postBufferRelease(BufferId bufferId);
+
+    bool postSend(
+            BufferId bufferId, ConnectionId receiver,
+            TransactionId *transactionId, int64_t *timestampUs);
+private:
+
+    bool postReceive(
+            BufferId bufferId, TransactionId transactionId,
+            int64_t timestampUs);
+
+    bool postReceiveResult(
+            BufferId bufferId, TransactionId transactionId, bool result, bool *needsSync);
+
+    void trySyncFromRemote();
+
+    bool syncReleased(uint32_t msgId = 0);
+
+    void evictCaches(bool clearCache = false);
+
+    void invalidateBuffer(BufferId id);
+
+    void invalidateRange(BufferId from, BufferId to);
+
+    ResultStatus allocateBufferHandle(
+            const std::vector<uint8_t>& params, BufferId *bufferId,
+            native_handle_t **handle);
+
+    ResultStatus fetchBufferHandle(
+            TransactionId transactionId, BufferId bufferId,
+            native_handle_t **handle);
+
+    struct BlockPoolDataDtor;
+    struct ClientBuffer;
+
+    bool mLocal;
+    bool mValid;
+    sp<IAccessor> mAccessor;
+    sp<Connection> mLocalConnection;
+    sp<IConnection> mRemoteConnection;
+    uint32_t mSeqId;
+    ConnectionId mConnectionId;
+    int64_t mLastEvictCacheUs;
+    std::unique_ptr<BufferInvalidationListener> mInvalidationListener;
+
+    // CachedBuffers
+    struct BufferCache {
+        std::mutex mLock;
+        bool mCreating;
+        std::condition_variable mCreateCv;
+        std::map<BufferId, std::unique_ptr<ClientBuffer>> mBuffers;
+        int mActive;
+        int64_t mLastChangeUs;
+
+        BufferCache() : mCreating(false), mActive(0), mLastChangeUs(getTimestampNow()) {}
+
+        void incActive_l() {
+            ++mActive;
+            mLastChangeUs = getTimestampNow();
+        }
+
+        void decActive_l() {
+            --mActive;
+            mLastChangeUs = getTimestampNow();
+        }
+    } mCache;
+
+    // FMQ - release notifier
+    struct ReleaseCache {
+        std::mutex mLock;
+        // TODO: use only one list?(using one list may dealy sending messages?)
+        std::list<BufferId> mReleasingIds;
+        std::list<BufferId> mReleasedIds;
+        uint32_t mInvalidateId; // TODO: invalidation ACK to bufferpool
+        bool mInvalidateAck;
+        std::unique_ptr<BufferStatusChannel> mStatusChannel;
+
+        ReleaseCache() : mInvalidateId(0), mInvalidateAck(true) {}
+    } mReleasing;
+
+    // This lock is held during synchronization from remote side.
+    // In order to minimize remote calls and locking durtaion, this lock is held
+    // by best effort approach using try_lock().
+    std::mutex mRemoteSyncLock;
+};
+
+struct BufferPoolClient::Impl::BlockPoolDataDtor {
+    BlockPoolDataDtor(const std::shared_ptr<BufferPoolClient::Impl> &impl)
+            : mImpl(impl) {}
+
+    void operator()(BufferPoolData *buffer) {
+        BufferId id = buffer->mId;
+        delete buffer;
+
+        auto impl = mImpl.lock();
+        if (impl && impl->isValid()) {
+            impl->postBufferRelease(id);
+        }
+    }
+    const std::weak_ptr<BufferPoolClient::Impl> mImpl;
+};
+
+struct BufferPoolClient::Impl::ClientBuffer {
+private:
+    int64_t mExpireUs;
+    bool mHasCache;
+    ConnectionId mConnectionId;
+    BufferId mId;
+    native_handle_t *mHandle;
+    std::weak_ptr<BufferPoolData> mCache;
+
+    void updateExpire() {
+        mExpireUs = getTimestampNow() + kCacheTtlUs;
+    }
+
+public:
+    ClientBuffer(
+            ConnectionId connectionId, BufferId id, native_handle_t *handle)
+            : mHasCache(false), mConnectionId(connectionId),
+              mId(id), mHandle(handle) {
+        mExpireUs = getTimestampNow() + kCacheTtlUs;
+    }
+
+    ~ClientBuffer() {
+        if (mHandle) {
+            native_handle_close(mHandle);
+            native_handle_delete(mHandle);
+        }
+    }
+
+    BufferId id() const {
+        return mId;
+    }
+
+    bool expire() const {
+        int64_t now = getTimestampNow();
+        return now >= mExpireUs;
+    }
+
+    bool hasCache() const {
+        return mHasCache;
+    }
+
+    std::shared_ptr<BufferPoolData> fetchCache(native_handle_t **pHandle) {
+        if (mHasCache) {
+            std::shared_ptr<BufferPoolData> cache = mCache.lock();
+            if (cache) {
+                *pHandle = mHandle;
+            }
+            return cache;
+        }
+        return nullptr;
+    }
+
+    std::shared_ptr<BufferPoolData> createCache(
+            const std::shared_ptr<BufferPoolClient::Impl> &impl,
+            native_handle_t **pHandle) {
+        if (!mHasCache) {
+            // Allocates a raw ptr in order to avoid sending #postBufferRelease
+            // from deleter, in case of native_handle_clone failure.
+            BufferPoolData *ptr = new BufferPoolData(mConnectionId, mId);
+            if (ptr) {
+                std::shared_ptr<BufferPoolData> cache(ptr, BlockPoolDataDtor(impl));
+                if (cache) {
+                    mCache = cache;
+                    mHasCache = true;
+                    *pHandle = mHandle;
+                    return cache;
+                }
+            }
+            if (ptr) {
+                delete ptr;
+            }
+        }
+        return nullptr;
+    }
+
+    bool onCacheRelease() {
+        if (mHasCache) {
+            // TODO: verify mCache is not valid;
+            updateExpire();
+            mHasCache = false;
+            return true;
+        }
+        return false;
+    }
+};
+
+BufferPoolClient::Impl::Impl(const sp<Accessor> &accessor, const sp<IObserver> &observer)
+    : mLocal(true), mValid(false), mAccessor(accessor), mSeqId(0),
+      mLastEvictCacheUs(getTimestampNow()) {
+    const StatusDescriptor *statusDesc;
+    const InvalidationDescriptor *invDesc;
+    ResultStatus status = accessor->connect(
+            observer, true,
+            &mLocalConnection, &mConnectionId, &mReleasing.mInvalidateId,
+            &statusDesc, &invDesc);
+    if (status == ResultStatus::OK) {
+        mReleasing.mStatusChannel =
+                std::make_unique<BufferStatusChannel>(*statusDesc);
+        mInvalidationListener =
+                std::make_unique<BufferInvalidationListener>(*invDesc);
+        mValid = mReleasing.mStatusChannel &&
+                mReleasing.mStatusChannel->isValid() &&
+                mInvalidationListener &&
+                mInvalidationListener->isValid();
+    }
+}
+
+BufferPoolClient::Impl::Impl(const sp<IAccessor> &accessor, const sp<IObserver> &observer)
+    : mLocal(false), mValid(false), mAccessor(accessor), mSeqId(0),
+      mLastEvictCacheUs(getTimestampNow()) {
+    bool valid = false;
+    sp<IConnection>& outConnection = mRemoteConnection;
+    ConnectionId& id = mConnectionId;
+    uint32_t& outMsgId = mReleasing.mInvalidateId;
+    std::unique_ptr<BufferStatusChannel>& outChannel =
+            mReleasing.mStatusChannel;
+    std::unique_ptr<BufferInvalidationListener>& outObserver =
+            mInvalidationListener;
+    Return<void> transResult = accessor->connect(
+            observer,
+            [&valid, &outConnection, &id, &outMsgId, &outChannel, &outObserver]
+            (ResultStatus status, sp<IConnection> connection,
+             ConnectionId connectionId, uint32_t msgId,
+             const StatusDescriptor& statusDesc,
+             const InvalidationDescriptor& invDesc) {
+                if (status == ResultStatus::OK) {
+                    outConnection = connection;
+                    id = connectionId;
+                    outMsgId = msgId;
+                    outChannel = std::make_unique<BufferStatusChannel>(statusDesc);
+                    outObserver = std::make_unique<BufferInvalidationListener>(invDesc);
+                    if (outChannel && outChannel->isValid() &&
+                        outObserver && outObserver->isValid()) {
+                        valid = true;
+                    }
+                }
+            });
+    mValid = transResult.isOk() && valid;
+}
+
+bool BufferPoolClient::Impl::isActive(int64_t *lastTransactionUs, bool clearCache) {
+    bool active = false;
+    {
+        std::lock_guard<std::mutex> lock(mCache.mLock);
+        syncReleased();
+        evictCaches(clearCache);
+        *lastTransactionUs = mCache.mLastChangeUs;
+        active = mCache.mActive > 0;
+    }
+    if (mValid && mLocal && mLocalConnection) {
+        mLocalConnection->cleanUp(clearCache);
+        return true;
+    }
+    return active;
+}
+
+void BufferPoolClient::Impl::receiveInvalidation(uint32_t messageId) {
+    std::lock_guard<std::mutex> lock(mCache.mLock);
+    syncReleased(messageId);
+    // TODO: evict cache required?
+}
+
+ResultStatus BufferPoolClient::Impl::flush() {
+    if (!mLocal || !mLocalConnection || !mValid) {
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    {
+        std::unique_lock<std::mutex> lock(mCache.mLock);
+        syncReleased();
+        evictCaches();
+        return mLocalConnection->flush();
+    }
+}
+
+ResultStatus BufferPoolClient::Impl::allocate(
+        const std::vector<uint8_t> &params,
+        native_handle_t **pHandle,
+        std::shared_ptr<BufferPoolData> *buffer) {
+    if (!mLocal || !mLocalConnection || !mValid) {
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    BufferId bufferId;
+    native_handle_t *handle = nullptr;
+    buffer->reset();
+    ResultStatus status = allocateBufferHandle(params, &bufferId, &handle);
+    if (status == ResultStatus::OK) {
+        if (handle) {
+            std::unique_lock<std::mutex> lock(mCache.mLock);
+            syncReleased();
+            evictCaches();
+            auto cacheIt = mCache.mBuffers.find(bufferId);
+            if (cacheIt != mCache.mBuffers.end()) {
+                // TODO: verify it is recycled. (not having active ref)
+                mCache.mBuffers.erase(cacheIt);
+            }
+            auto clientBuffer = std::make_unique<ClientBuffer>(
+                    mConnectionId, bufferId, handle);
+            if (clientBuffer) {
+                auto result = mCache.mBuffers.insert(std::make_pair(
+                        bufferId, std::move(clientBuffer)));
+                if (result.second) {
+                    *buffer = result.first->second->createCache(
+                            shared_from_this(), pHandle);
+                    if (*buffer) {
+                        mCache.incActive_l();
+                    }
+                }
+            }
+        }
+        if (!*buffer) {
+            ALOGV("client cache creation failure %d: %lld",
+                  handle != nullptr, (long long)mConnectionId);
+            status = ResultStatus::NO_MEMORY;
+            postBufferRelease(bufferId);
+        }
+    }
+    return status;
+}
+
+ResultStatus BufferPoolClient::Impl::receive(
+        TransactionId transactionId, BufferId bufferId, int64_t timestampUs,
+        native_handle_t **pHandle,
+        std::shared_ptr<BufferPoolData> *buffer) {
+    if (!mValid) {
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    if (timestampUs != 0) {
+        timestampUs += kReceiveTimeoutUs;
+    }
+    if (!postReceive(bufferId, transactionId, timestampUs)) {
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    ResultStatus status = ResultStatus::CRITICAL_ERROR;
+    buffer->reset();
+    while(1) {
+        std::unique_lock<std::mutex> lock(mCache.mLock);
+        syncReleased();
+        evictCaches();
+        auto cacheIt = mCache.mBuffers.find(bufferId);
+        if (cacheIt != mCache.mBuffers.end()) {
+            if (cacheIt->second->hasCache()) {
+                *buffer = cacheIt->second->fetchCache(pHandle);
+                if (!*buffer) {
+                    // check transfer time_out
+                    lock.unlock();
+                    std::this_thread::yield();
+                    continue;
+                }
+                ALOGV("client receive from reference %lld", (long long)mConnectionId);
+                break;
+            } else {
+                *buffer = cacheIt->second->createCache(shared_from_this(), pHandle);
+                if (*buffer) {
+                    mCache.incActive_l();
+                }
+                ALOGV("client receive from cache %lld", (long long)mConnectionId);
+                break;
+            }
+        } else {
+            if (!mCache.mCreating) {
+                mCache.mCreating = true;
+                lock.unlock();
+                native_handle_t* handle = nullptr;
+                status = fetchBufferHandle(transactionId, bufferId, &handle);
+                lock.lock();
+                if (status == ResultStatus::OK) {
+                    if (handle) {
+                        auto clientBuffer = std::make_unique<ClientBuffer>(
+                                mConnectionId, bufferId, handle);
+                        if (clientBuffer) {
+                            auto result = mCache.mBuffers.insert(
+                                    std::make_pair(bufferId, std::move(
+                                            clientBuffer)));
+                            if (result.second) {
+                                *buffer = result.first->second->createCache(
+                                        shared_from_this(), pHandle);
+                                if (*buffer) {
+                                    mCache.incActive_l();
+                                }
+                            }
+                        }
+                    }
+                    if (!*buffer) {
+                        status = ResultStatus::NO_MEMORY;
+                    }
+                }
+                mCache.mCreating = false;
+                lock.unlock();
+                mCache.mCreateCv.notify_all();
+                break;
+            }
+            mCache.mCreateCv.wait(lock);
+        }
+    }
+    bool needsSync = false;
+    bool posted = postReceiveResult(bufferId, transactionId,
+                                      *buffer ? true : false, &needsSync);
+    ALOGV("client receive %lld - %u : %s (%d)", (long long)mConnectionId, bufferId,
+          *buffer ? "ok" : "fail", posted);
+    if (mValid && mLocal && mLocalConnection) {
+        mLocalConnection->cleanUp(false);
+    }
+    if (needsSync && mRemoteConnection) {
+        trySyncFromRemote();
+    }
+    if (*buffer) {
+        if (!posted) {
+            buffer->reset();
+            return ResultStatus::CRITICAL_ERROR;
+        }
+        return ResultStatus::OK;
+    }
+    return status;
+}
+
+
+void BufferPoolClient::Impl::postBufferRelease(BufferId bufferId) {
+    std::lock_guard<std::mutex> lock(mReleasing.mLock);
+    mReleasing.mReleasingIds.push_back(bufferId);
+    mReleasing.mStatusChannel->postBufferRelease(
+            mConnectionId, mReleasing.mReleasingIds, mReleasing.mReleasedIds);
+}
+
+// TODO: revise ad-hoc posting data structure
+bool BufferPoolClient::Impl::postSend(
+        BufferId bufferId, ConnectionId receiver,
+        TransactionId *transactionId, int64_t *timestampUs) {
+    {
+        // TODO: don't need to call syncReleased every time
+        std::lock_guard<std::mutex> lock(mCache.mLock);
+        syncReleased();
+    }
+    bool ret = false;
+    bool needsSync = false;
+    {
+        std::lock_guard<std::mutex> lock(mReleasing.mLock);
+        *timestampUs = getTimestampNow();
+        *transactionId = (mConnectionId << 32) | mSeqId++;
+        // TODO: retry, add timeout, target?
+        ret =  mReleasing.mStatusChannel->postBufferStatusMessage(
+                *transactionId, bufferId, BufferStatus::TRANSFER_TO, mConnectionId,
+                receiver, mReleasing.mReleasingIds, mReleasing.mReleasedIds);
+        needsSync = !mLocal && mReleasing.mStatusChannel->needsSync();
+    }
+    if (mValid && mLocal && mLocalConnection) {
+        mLocalConnection->cleanUp(false);
+    }
+    if (needsSync && mRemoteConnection) {
+        trySyncFromRemote();
+    }
+    return ret;
+}
+
+bool BufferPoolClient::Impl::postReceive(
+        BufferId bufferId, TransactionId transactionId, int64_t timestampUs) {
+    for (int i = 0; i < kPostMaxRetry; ++i) {
+        std::unique_lock<std::mutex> lock(mReleasing.mLock);
+        int64_t now = getTimestampNow();
+        if (timestampUs == 0 || now < timestampUs) {
+            bool result = mReleasing.mStatusChannel->postBufferStatusMessage(
+                    transactionId, bufferId, BufferStatus::TRANSFER_FROM,
+                    mConnectionId, -1, mReleasing.mReleasingIds,
+                    mReleasing.mReleasedIds);
+            if (result) {
+                return true;
+            }
+            lock.unlock();
+            std::this_thread::yield();
+        } else {
+            mReleasing.mStatusChannel->postBufferStatusMessage(
+                    transactionId, bufferId, BufferStatus::TRANSFER_TIMEOUT,
+                    mConnectionId, -1, mReleasing.mReleasingIds,
+                    mReleasing.mReleasedIds);
+            return false;
+        }
+    }
+    return false;
+}
+
+bool BufferPoolClient::Impl::postReceiveResult(
+        BufferId bufferId, TransactionId transactionId, bool result, bool *needsSync) {
+    std::lock_guard<std::mutex> lock(mReleasing.mLock);
+    // TODO: retry, add timeout
+    bool ret = mReleasing.mStatusChannel->postBufferStatusMessage(
+            transactionId, bufferId,
+            result ? BufferStatus::TRANSFER_OK : BufferStatus::TRANSFER_ERROR,
+            mConnectionId, -1, mReleasing.mReleasingIds,
+            mReleasing.mReleasedIds);
+    *needsSync = !mLocal && mReleasing.mStatusChannel->needsSync();
+    return ret;
+}
+
+void BufferPoolClient::Impl::trySyncFromRemote() {
+    if (mRemoteSyncLock.try_lock()) {
+        bool needsSync = false;
+        {
+            std::lock_guard<std::mutex> lock(mReleasing.mLock);
+            needsSync = mReleasing.mStatusChannel->needsSync();
+        }
+        if (needsSync) {
+            TransactionId transactionId = (mConnectionId << 32);
+            BufferId bufferId = Connection::SYNC_BUFFERID;
+            Return<void> transResult = mRemoteConnection->fetch(
+                    transactionId, bufferId,
+                    []
+                    (ResultStatus outStatus, Buffer outBuffer) {
+                        (void) outStatus;
+                        (void) outBuffer;
+                    });
+            if (!transResult.isOk()) {
+                ALOGD("sync from client %lld failed: bufferpool process died.",
+                      (long long)mConnectionId);
+            }
+        }
+        mRemoteSyncLock.unlock();
+    }
+}
+
+// should have mCache.mLock
+bool BufferPoolClient::Impl::syncReleased(uint32_t messageId) {
+    bool cleared = false;
+    {
+        std::lock_guard<std::mutex> lock(mReleasing.mLock);
+        if (mReleasing.mReleasingIds.size() > 0) {
+            mReleasing.mStatusChannel->postBufferRelease(
+                    mConnectionId, mReleasing.mReleasingIds,
+                    mReleasing.mReleasedIds);
+        }
+        if (mReleasing.mReleasedIds.size() > 0) {
+            for (BufferId& id: mReleasing.mReleasedIds) {
+                ALOGV("client release buffer %lld - %u", (long long)mConnectionId, id);
+                auto found = mCache.mBuffers.find(id);
+                if (found != mCache.mBuffers.end()) {
+                    if (found->second->onCacheRelease()) {
+                        mCache.decActive_l();
+                    } else {
+                        // should not happen!
+                        ALOGW("client %lld cache release status inconsitent!",
+                            (long long)mConnectionId);
+                    }
+                } else {
+                    // should not happen!
+                    ALOGW("client %lld cache status inconsitent!", (long long)mConnectionId);
+                }
+            }
+            mReleasing.mReleasedIds.clear();
+            cleared = true;
+        }
+    }
+    std::vector<BufferInvalidationMessage> invalidations;
+    mInvalidationListener->getInvalidations(invalidations);
+    uint32_t lastMsgId = 0;
+    if (invalidations.size() > 0) {
+        for (auto it = invalidations.begin(); it != invalidations.end(); ++it) {
+            if (it->messageId != 0) {
+                lastMsgId = it->messageId;
+            }
+            if (it->fromBufferId == it->toBufferId) {
+                // TODO: handle fromBufferId = UINT32_MAX
+                invalidateBuffer(it->fromBufferId);
+            } else {
+                invalidateRange(it->fromBufferId, it->toBufferId);
+            }
+        }
+    }
+    {
+        std::lock_guard<std::mutex> lock(mReleasing.mLock);
+        if (lastMsgId != 0) {
+            if (isMessageLater(lastMsgId, mReleasing.mInvalidateId)) {
+                mReleasing.mInvalidateId = lastMsgId;
+                mReleasing.mInvalidateAck = false;
+            }
+        } else if (messageId != 0) {
+            // messages are drained.
+            if (isMessageLater(messageId, mReleasing.mInvalidateId)) {
+                mReleasing.mInvalidateId = messageId;
+                mReleasing.mInvalidateAck = true;
+            }
+        }
+        if (!mReleasing.mInvalidateAck) {
+            // post ACK
+            mReleasing.mStatusChannel->postBufferInvalidateAck(
+                    mConnectionId,
+                    mReleasing.mInvalidateId, &mReleasing.mInvalidateAck);
+            ALOGV("client %lld invalidateion ack (%d) %u",
+                (long long)mConnectionId,
+                mReleasing.mInvalidateAck, mReleasing.mInvalidateId);
+        }
+    }
+    return cleared;
+}
+
+// should have mCache.mLock
+void BufferPoolClient::Impl::evictCaches(bool clearCache) {
+    int64_t now = getTimestampNow();
+    if (now >= mLastEvictCacheUs + kCacheTtlUs || clearCache) {
+        size_t evicted = 0;
+        for (auto it = mCache.mBuffers.begin(); it != mCache.mBuffers.end();) {
+            if (!it->second->hasCache() && (it->second->expire() || clearCache)) {
+                it = mCache.mBuffers.erase(it);
+                ++evicted;
+            } else {
+                ++it;
+            }
+        }
+        ALOGV("cache count %lld : total %zu, active %d, evicted %zu",
+              (long long)mConnectionId, mCache.mBuffers.size(), mCache.mActive, evicted);
+        mLastEvictCacheUs = now;
+    }
+}
+
+// should have mCache.mLock
+void BufferPoolClient::Impl::invalidateBuffer(BufferId id) {
+    for (auto it = mCache.mBuffers.begin(); it != mCache.mBuffers.end(); ++it) {
+        if (id == it->second->id()) {
+            if (!it->second->hasCache()) {
+                mCache.mBuffers.erase(it);
+                ALOGV("cache invalidated %lld : buffer %u",
+                      (long long)mConnectionId, id);
+            } else {
+                ALOGW("Inconsitent invalidation %lld : activer buffer!! %u",
+                      (long long)mConnectionId, (unsigned int)id);
+            }
+            break;
+        }
+    }
+}
+
+// should have mCache.mLock
+void BufferPoolClient::Impl::invalidateRange(BufferId from, BufferId to) {
+    size_t invalidated = 0;
+    for (auto it = mCache.mBuffers.begin(); it != mCache.mBuffers.end();) {
+        if (!it->second->hasCache()) {
+            BufferId bid = it->second->id();
+            if (from < to) {
+                if (from <= bid && bid < to) {
+                    ++invalidated;
+                    it = mCache.mBuffers.erase(it);
+                    continue;
+                }
+            } else {
+                if (from <= bid || bid < to) {
+                    ++invalidated;
+                    it = mCache.mBuffers.erase(it);
+                    continue;
+                }
+            }
+        }
+        ++it;
+    }
+    ALOGV("cache invalidated %lld : # of invalidated %zu",
+          (long long)mConnectionId, invalidated);
+}
+
+ResultStatus BufferPoolClient::Impl::allocateBufferHandle(
+        const std::vector<uint8_t>& params, BufferId *bufferId,
+        native_handle_t** handle) {
+    if (mLocalConnection) {
+        const native_handle_t* allocHandle = nullptr;
+        ResultStatus status = mLocalConnection->allocate(
+                params, bufferId, &allocHandle);
+        if (status == ResultStatus::OK) {
+            *handle = native_handle_clone(allocHandle);
+        }
+        ALOGV("client allocate result %lld %d : %u clone %p",
+              (long long)mConnectionId, status == ResultStatus::OK,
+              *handle ? *bufferId : 0 , *handle);
+        return status;
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus BufferPoolClient::Impl::fetchBufferHandle(
+        TransactionId transactionId, BufferId bufferId,
+        native_handle_t **handle) {
+    sp<IConnection> connection;
+    if (mLocal) {
+        connection = mLocalConnection;
+    } else {
+        connection = mRemoteConnection;
+    }
+    ResultStatus status;
+    Return<void> transResult = connection->fetch(
+            transactionId, bufferId,
+            [&status, &handle]
+            (ResultStatus outStatus, Buffer outBuffer) {
+                status = outStatus;
+                if (status == ResultStatus::OK) {
+                    *handle = native_handle_clone(
+                            outBuffer.buffer.getNativeHandle());
+                }
+            });
+    return transResult.isOk() ? status : ResultStatus::CRITICAL_ERROR;
+}
+
+
+BufferPoolClient::BufferPoolClient(const sp<Accessor> &accessor,
+                                   const sp<IObserver> &observer) {
+    mImpl = std::make_shared<Impl>(accessor, observer);
+}
+
+BufferPoolClient::BufferPoolClient(const sp<IAccessor> &accessor,
+                                   const sp<IObserver> &observer) {
+    mImpl = std::make_shared<Impl>(accessor, observer);
+}
+
+BufferPoolClient::~BufferPoolClient() {
+    // TODO: how to handle orphaned buffers?
+}
+
+bool BufferPoolClient::isValid() {
+    return mImpl && mImpl->isValid();
+}
+
+bool BufferPoolClient::isLocal() {
+    return mImpl && mImpl->isLocal();
+}
+
+bool BufferPoolClient::isActive(int64_t *lastTransactionUs, bool clearCache) {
+    if (!isValid()) {
+        *lastTransactionUs = 0;
+        return false;
+    }
+    return mImpl->isActive(lastTransactionUs, clearCache);
+}
+
+ConnectionId BufferPoolClient::getConnectionId() {
+    if (isValid()) {
+        return mImpl->getConnectionId();
+    }
+    return -1;
+}
+
+ResultStatus BufferPoolClient::getAccessor(sp<IAccessor> *accessor) {
+    if (isValid()) {
+        *accessor = mImpl->getAccessor();
+        return ResultStatus::OK;
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+void BufferPoolClient::receiveInvalidation(uint32_t msgId) {
+    ALOGV("bufferpool2 client recv inv %u", msgId);
+    if (isValid()) {
+        mImpl->receiveInvalidation(msgId);
+    }
+}
+
+ResultStatus BufferPoolClient::flush() {
+    if (isValid()) {
+        return mImpl->flush();
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus BufferPoolClient::allocate(
+        const std::vector<uint8_t> &params,
+        native_handle_t **handle,
+        std::shared_ptr<BufferPoolData> *buffer) {
+    if (isValid()) {
+        return mImpl->allocate(params, handle, buffer);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus BufferPoolClient::receive(
+        TransactionId transactionId, BufferId bufferId, int64_t timestampUs,
+        native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
+    if (isValid()) {
+        return mImpl->receive(transactionId, bufferId, timestampUs, handle, buffer);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus BufferPoolClient::postSend(
+        ConnectionId receiverId,
+        const std::shared_ptr<BufferPoolData> &buffer,
+        TransactionId *transactionId,
+        int64_t *timestampUs) {
+    if (isValid()) {
+        bool result = mImpl->postSend(
+                buffer->mId, receiverId, transactionId, timestampUs);
+        return result ? ResultStatus::OK : ResultStatus::CRITICAL_ERROR;
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
diff --git a/media/bufferpool/2.0/BufferPoolClient.h b/media/bufferpool/2.0/BufferPoolClient.h
new file mode 100644
index 0000000..e8d9ae6
--- /dev/null
+++ b/media/bufferpool/2.0/BufferPoolClient.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_BUFFERPOOLCLIENT_H
+#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_BUFFERPOOLCLIENT_H
+
+#include <memory>
+#include <android/hardware/media/bufferpool/2.0/IAccessor.h>
+#include <android/hardware/media/bufferpool/2.0/IConnection.h>
+#include <android/hardware/media/bufferpool/2.0/IObserver.h>
+#include <bufferpool/BufferPoolTypes.h>
+#include <cutils/native_handle.h>
+#include "Accessor.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::media::bufferpool::V2_0::IAccessor;
+using ::android::hardware::media::bufferpool::V2_0::IConnection;
+using ::android::hardware::media::bufferpool::V2_0::IObserver;
+using ::android::hardware::media::bufferpool::V2_0::ResultStatus;
+using ::android::sp;
+
+/**
+ * A buffer pool client for a buffer pool. For a specific buffer pool, at most
+ * one buffer pool client exists per process. This class will not be exposed
+ * outside. A buffer pool client will be used via ClientManager.
+ */
+class BufferPoolClient {
+public:
+    /**
+     * Creates a buffer pool client from a local buffer pool
+     * (via ClientManager#create).
+     */
+    explicit BufferPoolClient(const sp<Accessor> &accessor,
+                              const sp<IObserver> &observer);
+
+    /**
+     * Creates a buffer pool client from a remote buffer pool
+     * (via ClientManager#registerSender).
+     * Note: A buffer pool client created with remote buffer pool cannot
+     * allocate a buffer.
+     */
+    explicit BufferPoolClient(const sp<IAccessor> &accessor,
+                              const sp<IObserver> &observer);
+
+    /** Destructs a buffer pool client. */
+    ~BufferPoolClient();
+
+private:
+    bool isValid();
+
+    bool isLocal();
+
+    bool isActive(int64_t *lastTransactionUs, bool clearCache);
+
+    ConnectionId getConnectionId();
+
+    ResultStatus getAccessor(sp<IAccessor> *accessor);
+
+    void receiveInvalidation(uint32_t msgId);
+
+    ResultStatus flush();
+
+    ResultStatus allocate(const std::vector<uint8_t> &params,
+                          native_handle_t **handle,
+                          std::shared_ptr<BufferPoolData> *buffer);
+
+    ResultStatus receive(TransactionId transactionId,
+                         BufferId bufferId,
+                         int64_t timestampUs,
+                         native_handle_t **handle,
+                         std::shared_ptr<BufferPoolData> *buffer);
+
+    ResultStatus postSend(ConnectionId receiver,
+                          const std::shared_ptr<BufferPoolData> &buffer,
+                          TransactionId *transactionId,
+                          int64_t *timestampUs);
+
+    class Impl;
+    std::shared_ptr<Impl> mImpl;
+
+    friend struct ClientManager;
+    friend struct Observer;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_BUFFERPOOLCLIENT_H
diff --git a/media/bufferpool/2.0/BufferStatus.cpp b/media/bufferpool/2.0/BufferStatus.cpp
new file mode 100644
index 0000000..6937260
--- /dev/null
+++ b/media/bufferpool/2.0/BufferStatus.cpp
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BufferPoolStatus"
+//#define LOG_NDEBUG 0
+
+#include <thread>
+#include <time.h>
+#include "BufferStatus.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V2_0 {
+namespace implementation {
+
+int64_t getTimestampNow() {
+    int64_t stamp;
+    struct timespec ts;
+    // TODO: CLOCK_MONOTONIC_COARSE?
+    clock_gettime(CLOCK_MONOTONIC, &ts);
+    stamp = ts.tv_nsec / 1000;
+    stamp += (ts.tv_sec * 1000000LL);
+    return stamp;
+}
+
+bool isMessageLater(uint32_t curMsgId, uint32_t prevMsgId) {
+    return curMsgId != prevMsgId && curMsgId - prevMsgId < prevMsgId - curMsgId;
+}
+
+bool isBufferInRange(BufferId from, BufferId to, BufferId bufferId) {
+    if (from < to) {
+        return from <= bufferId && bufferId < to;
+    } else { // wrap happens
+        return from <= bufferId || bufferId < to;
+    }
+}
+
+static constexpr int kNumElementsInQueue = 1024*16;
+static constexpr int kMinElementsToSyncInQueue = 128;
+
+ResultStatus BufferStatusObserver::open(
+        ConnectionId id, const StatusDescriptor** fmqDescPtr) {
+    if (mBufferStatusQueues.find(id) != mBufferStatusQueues.end()) {
+        // TODO: id collision log?
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    std::unique_ptr<BufferStatusQueue> queue =
+            std::make_unique<BufferStatusQueue>(kNumElementsInQueue);
+    if (!queue || queue->isValid() == false) {
+        *fmqDescPtr = nullptr;
+        return ResultStatus::NO_MEMORY;
+    } else {
+        *fmqDescPtr = queue->getDesc();
+    }
+    auto result = mBufferStatusQueues.insert(
+            std::make_pair(id, std::move(queue)));
+    if (!result.second) {
+        *fmqDescPtr = nullptr;
+        return ResultStatus::NO_MEMORY;
+    }
+    return ResultStatus::OK;
+}
+
+ResultStatus BufferStatusObserver::close(ConnectionId id) {
+    if (mBufferStatusQueues.find(id) == mBufferStatusQueues.end()) {
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    mBufferStatusQueues.erase(id);
+    return ResultStatus::OK;
+}
+
+void BufferStatusObserver::getBufferStatusChanges(std::vector<BufferStatusMessage> &messages) {
+    for (auto it = mBufferStatusQueues.begin(); it != mBufferStatusQueues.end(); ++it) {
+        BufferStatusMessage message;
+        size_t avail = it->second->availableToRead();
+        while (avail > 0) {
+            if (!it->second->read(&message, 1)) {
+                // Since avaliable # of reads are already confirmed,
+                // this should not happen.
+                // TODO: error handling (spurious client?)
+                ALOGW("FMQ message cannot be read from %lld", (long long)it->first);
+                return;
+            }
+            message.connectionId = it->first;
+            messages.push_back(message);
+            --avail;
+        }
+    }
+}
+
+BufferStatusChannel::BufferStatusChannel(
+        const StatusDescriptor &fmqDesc) {
+    std::unique_ptr<BufferStatusQueue> queue =
+            std::make_unique<BufferStatusQueue>(fmqDesc);
+    if (!queue || queue->isValid() == false) {
+        mValid = false;
+        return;
+    }
+    mValid  = true;
+    mBufferStatusQueue = std::move(queue);
+}
+
+bool BufferStatusChannel::isValid() {
+    return mValid;
+}
+
+bool BufferStatusChannel::needsSync() {
+    if (mValid) {
+        size_t avail = mBufferStatusQueue->availableToWrite();
+        return avail + kMinElementsToSyncInQueue < kNumElementsInQueue;
+    }
+    return false;
+}
+
+void BufferStatusChannel::postBufferRelease(
+        ConnectionId connectionId,
+        std::list<BufferId> &pending, std::list<BufferId> &posted) {
+    if (mValid && pending.size() > 0) {
+        size_t avail = mBufferStatusQueue->availableToWrite();
+        avail = std::min(avail, pending.size());
+        BufferStatusMessage message;
+        for (size_t i = 0 ; i < avail; ++i) {
+            BufferId id = pending.front();
+            message.newStatus = BufferStatus::NOT_USED;
+            message.bufferId = id;
+            message.connectionId = connectionId;
+            if (!mBufferStatusQueue->write(&message, 1)) {
+                // Since avaliable # of writes are already confirmed,
+                // this should not happen.
+                // TODO: error handing?
+                ALOGW("FMQ message cannot be sent from %lld", (long long)connectionId);
+                return;
+            }
+            pending.pop_front();
+            posted.push_back(id);
+        }
+    }
+}
+
+void BufferStatusChannel::postBufferInvalidateAck(
+        ConnectionId connectionId,
+        uint32_t invalidateId,
+        bool *invalidated) {
+    if (mValid && !*invalidated) {
+        size_t avail = mBufferStatusQueue->availableToWrite();
+        if (avail > 0) {
+            BufferStatusMessage message;
+            message.newStatus = BufferStatus::INVALIDATION_ACK;
+            message.bufferId = invalidateId;
+            message.connectionId = connectionId;
+            if (!mBufferStatusQueue->write(&message, 1)) {
+                // Since avaliable # of writes are already confirmed,
+                // this should not happen.
+                // TODO: error handing?
+                ALOGW("FMQ message cannot be sent from %lld", (long long)connectionId);
+                return;
+            }
+            *invalidated = true;
+        }
+    }
+}
+
+bool BufferStatusChannel::postBufferStatusMessage(
+        TransactionId transactionId, BufferId bufferId,
+        BufferStatus status, ConnectionId connectionId, ConnectionId targetId,
+        std::list<BufferId> &pending, std::list<BufferId> &posted) {
+    if (mValid) {
+        size_t avail = mBufferStatusQueue->availableToWrite();
+        size_t numPending = pending.size();
+        if (avail >= numPending + 1) {
+            BufferStatusMessage release, message;
+            for (size_t i = 0; i < numPending; ++i) {
+                BufferId id = pending.front();
+                release.newStatus = BufferStatus::NOT_USED;
+                release.bufferId = id;
+                release.connectionId = connectionId;
+                if (!mBufferStatusQueue->write(&release, 1)) {
+                    // Since avaliable # of writes are already confirmed,
+                    // this should not happen.
+                    // TODO: error handling?
+                    ALOGW("FMQ message cannot be sent from %lld", (long long)connectionId);
+                    return false;
+                }
+                pending.pop_front();
+                posted.push_back(id);
+            }
+            message.transactionId = transactionId;
+            message.bufferId = bufferId;
+            message.newStatus = status;
+            message.connectionId = connectionId;
+            message.targetConnectionId = targetId;
+            // TODO : timesatamp
+            message.timestampUs = 0;
+            if (!mBufferStatusQueue->write(&message, 1)) {
+                // Since avaliable # of writes are already confirmed,
+                // this should not happen.
+                ALOGW("FMQ message cannot be sent from %lld", (long long)connectionId);
+                return false;
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
+BufferInvalidationListener::BufferInvalidationListener(
+        const InvalidationDescriptor &fmqDesc) {
+    std::unique_ptr<BufferInvalidationQueue> queue =
+            std::make_unique<BufferInvalidationQueue>(fmqDesc);
+    if (!queue || queue->isValid() == false) {
+        mValid = false;
+        return;
+    }
+    mValid  = true;
+    mBufferInvalidationQueue = std::move(queue);
+    // drain previous messages
+    size_t avail = std::min(
+            mBufferInvalidationQueue->availableToRead(), (size_t) kNumElementsInQueue);
+    std::vector<BufferInvalidationMessage> temp(avail);
+    if (avail > 0) {
+        mBufferInvalidationQueue->read(temp.data(), avail);
+    }
+}
+
+void BufferInvalidationListener::getInvalidations(
+        std::vector<BufferInvalidationMessage> &messages) {
+    // Try twice in case of overflow.
+    // TODO: handling overflow though it may not happen.
+    for (int i = 0; i < 2; ++i) {
+        size_t avail = std::min(
+                mBufferInvalidationQueue->availableToRead(), (size_t) kNumElementsInQueue);
+        if (avail > 0) {
+            std::vector<BufferInvalidationMessage> temp(avail);
+            if (mBufferInvalidationQueue->read(temp.data(), avail)) {
+                messages.reserve(messages.size() + avail);
+                for (auto it = temp.begin(); it != temp.end(); ++it) {
+                    messages.push_back(*it);
+                }
+                break;
+            }
+        } else {
+            return;
+        }
+    }
+}
+
+bool BufferInvalidationListener::isValid() {
+    return mValid;
+}
+
+BufferInvalidationChannel::BufferInvalidationChannel()
+    : mValid(true),
+      mBufferInvalidationQueue(
+              std::make_unique<BufferInvalidationQueue>(kNumElementsInQueue, true)) {
+    if (!mBufferInvalidationQueue || mBufferInvalidationQueue->isValid() == false) {
+        mValid = false;
+    }
+}
+
+bool BufferInvalidationChannel::isValid() {
+    return mValid;
+}
+
+void BufferInvalidationChannel::getDesc(const InvalidationDescriptor **fmqDescPtr) {
+    if (mValid) {
+        *fmqDescPtr = mBufferInvalidationQueue->getDesc();
+    } else {
+        *fmqDescPtr = nullptr;
+    }
+}
+
+void BufferInvalidationChannel::postInvalidation(
+        uint32_t msgId, BufferId fromId, BufferId toId) {
+    BufferInvalidationMessage message;
+
+    message.messageId = msgId;
+    message.fromBufferId = fromId;
+    message.toBufferId = toId;
+    // TODO: handle failure (it does not happen normally.)
+    mBufferInvalidationQueue->write(&message);
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
diff --git a/media/bufferpool/2.0/BufferStatus.h b/media/bufferpool/2.0/BufferStatus.h
new file mode 100644
index 0000000..fa65838
--- /dev/null
+++ b/media/bufferpool/2.0/BufferStatus.h
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_BUFFERSTATUS_H
+#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_BUFFERSTATUS_H
+
+#include <android/hardware/media/bufferpool/2.0/types.h>
+#include <bufferpool/BufferPoolTypes.h>
+#include <fmq/MessageQueue.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <memory>
+#include <mutex>
+#include <vector>
+#include <list>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V2_0 {
+namespace implementation {
+
+/** Returns monotonic timestamp in Us since fixed point in time. */
+int64_t getTimestampNow();
+
+bool isMessageLater(uint32_t curMsgId, uint32_t prevMsgId);
+
+bool isBufferInRange(BufferId from, BufferId to, BufferId bufferId);
+
+/**
+ * A collection of buffer status message FMQ for a buffer pool. buffer
+ * ownership/status change messages are sent via the FMQs from the clients.
+ */
+class BufferStatusObserver {
+private:
+    std::map<ConnectionId, std::unique_ptr<BufferStatusQueue>>
+            mBufferStatusQueues;
+
+public:
+    /** Creates a buffer status message FMQ for the specified
+     * connection(client).
+     *
+     * @param connectionId  connection Id of the specified client.
+     * @param fmqDescPtr    double ptr of created FMQ's descriptor.
+     *
+     * @return OK if FMQ is created successfully.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus open(ConnectionId id, const StatusDescriptor** fmqDescPtr);
+
+    /** Closes a buffer status message FMQ for the specified
+     * connection(client).
+     *
+     * @param connectionId  connection Id of the specified client.
+     *
+     * @return OK if the specified connection is closed successfully.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus close(ConnectionId id);
+
+    /** Retrieves all pending FMQ buffer status messages from clients.
+     *
+     * @param messages  retrieved pending messages.
+     */
+    void getBufferStatusChanges(std::vector<BufferStatusMessage> &messages);
+};
+
+/**
+ * A buffer status message FMQ for a buffer pool client. Buffer ownership/status
+ * change messages are sent via the fmq to the buffer pool.
+ */
+class BufferStatusChannel {
+private:
+    bool mValid;
+    std::unique_ptr<BufferStatusQueue> mBufferStatusQueue;
+
+public:
+    /**
+     * Connects to a buffer status message FMQ from a descriptor of
+     * the created FMQ.
+     *
+     * @param fmqDesc   Descriptor of the created FMQ.
+     */
+    BufferStatusChannel(const StatusDescriptor &fmqDesc);
+
+    /** Returns whether the FMQ is connected successfully. */
+    bool isValid();
+
+    /** Returns whether the FMQ needs to be synced from the buffer pool */
+    bool needsSync();
+
+    /**
+     * Posts a buffer release message to the buffer pool.
+     *
+     * @param connectionId  connection Id of the client.
+     * @param pending       currently pending buffer release messages.
+     * @param posted        posted buffer release messages.
+     */
+    void postBufferRelease(
+            ConnectionId connectionId,
+            std::list<BufferId> &pending, std::list<BufferId> &posted);
+
+    /**
+     * Posts a buffer status message regarding the specified buffer
+     * transfer transaction.
+     *
+     * @param transactionId Id of the specified transaction.
+     * @param bufferId      buffer Id of the specified transaction.
+     * @param status        new status of the buffer.
+     * @param connectionId  connection Id of the client.
+     * @param targetId      connection Id of the receiver(only when the sender
+     *                      posts a status message).
+     * @param pending       currently pending buffer release messages.
+     * @param posted        posted buffer release messages.
+     *
+     * @return {@code true} when the specified message is posted,
+     *         {@code false} otherwise.
+     */
+    bool postBufferStatusMessage(
+            TransactionId transactionId,
+            BufferId bufferId,
+            BufferStatus status,
+            ConnectionId connectionId,
+            ConnectionId targetId,
+            std::list<BufferId> &pending, std::list<BufferId> &posted);
+
+    /**
+     * Posts a buffer invaliadation messge to the buffer pool.
+     *
+     * @param connectionId  connection Id of the client.
+     * @param invalidateId  invalidation ack to the buffer pool.
+     *                      if invalidation id is zero, the ack will not be
+     *                      posted.
+     * @param invalidated   sets {@code true} only when the invalidation ack is
+     *                      posted.
+     */
+    void postBufferInvalidateAck(
+            ConnectionId connectionId,
+            uint32_t invalidateId,
+            bool *invalidated);
+};
+
+/**
+ * A buffer invalidation FMQ for a buffer pool client. Buffer invalidation
+ * messages are received via the fmq from the buffer pool. Buffer invalidation
+ * messages are handled as soon as possible.
+ */
+class BufferInvalidationListener {
+private:
+    bool mValid;
+    std::unique_ptr<BufferInvalidationQueue> mBufferInvalidationQueue;
+
+public:
+    /**
+     * Connects to a buffer invalidation FMQ from a descriptor of the created FMQ.
+     *
+     * @param fmqDesc   Descriptor of the created FMQ.
+     */
+    BufferInvalidationListener(const InvalidationDescriptor &fmqDesc);
+
+    /** Retrieves all pending buffer invalidation messages from the buffer pool.
+     *
+     * @param messages  retrieved pending messages.
+     */
+    void getInvalidations(std::vector<BufferInvalidationMessage> &messages);
+
+    /** Returns whether the FMQ is connected succesfully. */
+    bool isValid();
+};
+
+/**
+ * A buffer invalidation FMQ for a buffer pool. A buffer pool will send buffer
+ * invalidation messages to the clients via the FMQ. The FMQ is shared among
+ * buffer pool clients.
+ */
+class BufferInvalidationChannel {
+private:
+    bool mValid;
+    std::unique_ptr<BufferInvalidationQueue> mBufferInvalidationQueue;
+
+public:
+    /**
+     * Creates a buffer invalidation FMQ for a buffer pool.
+     */
+    BufferInvalidationChannel();
+
+    /** Returns whether the FMQ is connected succesfully. */
+    bool isValid();
+
+    /**
+     * Retrieves the descriptor of a buffer invalidation FMQ. the descriptor may
+     * be passed to the client for buffer invalidation handling.
+     *
+     * @param fmqDescPtr    double ptr of created FMQ's descriptor.
+     */
+    void getDesc(const InvalidationDescriptor **fmqDescPtr);
+
+    /** Posts a buffer invalidation for invalidated buffers.
+     *
+     * @param msgId     Invalidation message id which is used when clients send
+     *                  acks back via BufferStatusMessage
+     * @param fromId    The start bufferid of the invalidated buffers(inclusive)
+     * @param toId      The end bufferId of the invalidated buffers(inclusive)
+     */
+    void postInvalidation(uint32_t msgId, BufferId fromId, BufferId toId);
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_BUFFERSTATUS_H
diff --git a/media/bufferpool/2.0/ClientManager.cpp b/media/bufferpool/2.0/ClientManager.cpp
new file mode 100644
index 0000000..c31d313
--- /dev/null
+++ b/media/bufferpool/2.0/ClientManager.cpp
@@ -0,0 +1,539 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "BufferPoolManager"
+//#define LOG_NDEBUG 0
+
+#include <bufferpool/ClientManager.h>
+#include <hidl/HidlTransportSupport.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+#include <utils/Log.h>
+#include "BufferPoolClient.h"
+#include "Observer.h"
+#include "Accessor.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V2_0 {
+namespace implementation {
+
+static constexpr int64_t kRegisterTimeoutUs = 500000; // 0.5 sec
+static constexpr int64_t kCleanUpDurationUs = 1000000; // TODO: 1 sec tune
+static constexpr int64_t kClientTimeoutUs = 5000000; // TODO: 5 secs tune
+
+/**
+ * The holder of the cookie of remote IClientManager.
+ * The cookie is process locally unique for each IClientManager.
+ * (The cookie is used to notify death of clients to bufferpool process.)
+ */
+class ClientManagerCookieHolder {
+public:
+    /**
+     * Creates a cookie holder for remote IClientManager(s).
+     */
+    ClientManagerCookieHolder();
+
+    /**
+     * Gets a cookie for a remote IClientManager.
+     *
+     * @param manager   the specified remote IClientManager.
+     * @param added     true when the specified remote IClientManager is added
+     *                  newly, false otherwise.
+     *
+     * @return the process locally unique cookie for the specified IClientManager.
+     */
+    uint64_t getCookie(const sp<IClientManager> &manager, bool *added);
+
+private:
+    uint64_t mSeqId;
+    std::mutex mLock;
+    std::list<std::pair<const wp<IClientManager>, uint64_t>> mManagers;
+};
+
+ClientManagerCookieHolder::ClientManagerCookieHolder() : mSeqId(0){}
+
+uint64_t ClientManagerCookieHolder::getCookie(
+        const sp<IClientManager> &manager,
+        bool *added) {
+    std::lock_guard<std::mutex> lock(mLock);
+    for (auto it = mManagers.begin(); it != mManagers.end();) {
+        const sp<IClientManager> key = it->first.promote();
+        if (key) {
+            if (interfacesEqual(key, manager)) {
+                *added = false;
+                return it->second;
+            }
+            ++it;
+        } else {
+            it = mManagers.erase(it);
+        }
+    }
+    uint64_t id = mSeqId++;
+    *added = true;
+    mManagers.push_back(std::make_pair(manager, id));
+    return id;
+}
+
+class ClientManager::Impl {
+public:
+    Impl();
+
+    // BnRegisterSender
+    ResultStatus registerSender(const sp<IAccessor> &accessor,
+                                ConnectionId *pConnectionId);
+
+    // BpRegisterSender
+    ResultStatus registerSender(const sp<IClientManager> &receiver,
+                                ConnectionId senderId,
+                                ConnectionId *receiverId);
+
+    ResultStatus create(const std::shared_ptr<BufferPoolAllocator> &allocator,
+                        ConnectionId *pConnectionId);
+
+    ResultStatus close(ConnectionId connectionId);
+
+    ResultStatus flush(ConnectionId connectionId);
+
+    ResultStatus allocate(ConnectionId connectionId,
+                          const std::vector<uint8_t> &params,
+                          native_handle_t **handle,
+                          std::shared_ptr<BufferPoolData> *buffer);
+
+    ResultStatus receive(ConnectionId connectionId,
+                         TransactionId transactionId,
+                         BufferId bufferId,
+                         int64_t timestampUs,
+                         native_handle_t **handle,
+                         std::shared_ptr<BufferPoolData> *buffer);
+
+    ResultStatus postSend(ConnectionId receiverId,
+                          const std::shared_ptr<BufferPoolData> &buffer,
+                          TransactionId *transactionId,
+                          int64_t *timestampUs);
+
+    ResultStatus getAccessor(ConnectionId connectionId,
+                             sp<IAccessor> *accessor);
+
+    void cleanUp(bool clearCache = false);
+
+private:
+    // In order to prevent deadlock between multiple locks,
+    // always lock ClientCache.lock before locking ActiveClients.lock.
+    struct ClientCache {
+        // This lock is held for brief duration.
+        // Blocking operation is not performed while holding the lock.
+        std::mutex mMutex;
+        std::list<std::pair<const wp<IAccessor>, const std::weak_ptr<BufferPoolClient>>>
+                mClients;
+        std::condition_variable mConnectCv;
+        bool mConnecting;
+        int64_t mLastCleanUpUs;
+
+        ClientCache() : mConnecting(false), mLastCleanUpUs(getTimestampNow()) {}
+    } mCache;
+
+    // Active clients which can be retrieved via ConnectionId
+    struct ActiveClients {
+        // This lock is held for brief duration.
+        // Blocking operation is not performed holding the lock.
+        std::mutex mMutex;
+        std::map<ConnectionId, const std::shared_ptr<BufferPoolClient>>
+                mClients;
+    } mActive;
+
+    sp<Observer> mObserver;
+
+    ClientManagerCookieHolder mRemoteClientCookies;
+};
+
+ClientManager::Impl::Impl()
+    : mObserver(new Observer()) {}
+
+ResultStatus ClientManager::Impl::registerSender(
+        const sp<IAccessor> &accessor, ConnectionId *pConnectionId) {
+    cleanUp();
+    int64_t timeoutUs = getTimestampNow() + kRegisterTimeoutUs;
+    do {
+        std::unique_lock<std::mutex> lock(mCache.mMutex);
+        for (auto it = mCache.mClients.begin(); it != mCache.mClients.end(); ++it) {
+            sp<IAccessor> sAccessor = it->first.promote();
+            if (sAccessor && interfacesEqual(sAccessor, accessor)) {
+                const std::shared_ptr<BufferPoolClient> client = it->second.lock();
+                if (client) {
+                    std::lock_guard<std::mutex> lock(mActive.mMutex);
+                    *pConnectionId = client->getConnectionId();
+                    if (mActive.mClients.find(*pConnectionId) != mActive.mClients.end()) {
+                        ALOGV("register existing connection %lld", (long long)*pConnectionId);
+                        return ResultStatus::ALREADY_EXISTS;
+                    }
+                }
+                mCache.mClients.erase(it);
+                break;
+            }
+        }
+        if (!mCache.mConnecting) {
+            mCache.mConnecting = true;
+            lock.unlock();
+            ResultStatus result = ResultStatus::OK;
+            const std::shared_ptr<BufferPoolClient> client =
+                    std::make_shared<BufferPoolClient>(accessor, mObserver);
+            lock.lock();
+            if (!client) {
+                result = ResultStatus::NO_MEMORY;
+            } else if (!client->isValid()) {
+                result = ResultStatus::CRITICAL_ERROR;
+            }
+            if (result == ResultStatus::OK) {
+                // TODO: handle insert fail. (malloc fail)
+                const std::weak_ptr<BufferPoolClient> wclient = client;
+                mCache.mClients.push_back(std::make_pair(accessor, wclient));
+                ConnectionId conId = client->getConnectionId();
+                mObserver->addClient(conId, wclient);
+                {
+                    std::lock_guard<std::mutex> lock(mActive.mMutex);
+                    mActive.mClients.insert(std::make_pair(conId, client));
+                }
+                *pConnectionId = conId;
+                ALOGV("register new connection %lld", (long long)*pConnectionId);
+            }
+            mCache.mConnecting = false;
+            lock.unlock();
+            mCache.mConnectCv.notify_all();
+            return result;
+        }
+        mCache.mConnectCv.wait_for(
+                lock, std::chrono::microseconds(kRegisterTimeoutUs));
+    } while (getTimestampNow() < timeoutUs);
+    // TODO: return timeout error
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus ClientManager::Impl::registerSender(
+        const sp<IClientManager> &receiver,
+        ConnectionId senderId,
+        ConnectionId *receiverId) {
+    sp<IAccessor> accessor;
+    bool local = false;
+    {
+        std::lock_guard<std::mutex> lock(mActive.mMutex);
+        auto it = mActive.mClients.find(senderId);
+        if (it == mActive.mClients.end()) {
+            return ResultStatus::NOT_FOUND;
+        }
+        it->second->getAccessor(&accessor);
+        local = it->second->isLocal();
+    }
+    ResultStatus rs = ResultStatus::CRITICAL_ERROR;
+    if (accessor) {
+       Return<void> transResult = receiver->registerSender(
+                accessor,
+                [&rs, receiverId](
+                        ResultStatus status,
+                        int64_t connectionId) {
+                    rs = status;
+                    *receiverId = connectionId;
+                });
+        if (!transResult.isOk()) {
+            return ResultStatus::CRITICAL_ERROR;
+        } else if (local && rs == ResultStatus::OK) {
+            sp<ConnectionDeathRecipient> recipient = Accessor::getConnectionDeathRecipient();
+            if (recipient)  {
+                ALOGV("client death recipient registered %lld", (long long)*receiverId);
+                bool added;
+                uint64_t cookie = mRemoteClientCookies.getCookie(receiver, &added);
+                recipient->addCookieToConnection(cookie, *receiverId);
+                if (added) {
+                    Return<bool> transResult = receiver->linkToDeath(recipient, cookie);
+                }
+            }
+        }
+    }
+    return rs;
+}
+
+ResultStatus ClientManager::Impl::create(
+        const std::shared_ptr<BufferPoolAllocator> &allocator,
+        ConnectionId *pConnectionId) {
+    const sp<Accessor> accessor = new Accessor(allocator);
+    if (!accessor || !accessor->isValid()) {
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    // TODO: observer is local. use direct call instead of hidl call.
+    std::shared_ptr<BufferPoolClient> client =
+            std::make_shared<BufferPoolClient>(accessor, mObserver);
+    if (!client || !client->isValid()) {
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    // Since a new bufferpool is created, evict memories which are used by
+    // existing bufferpools and clients.
+    cleanUp(true);
+    {
+        // TODO: handle insert fail. (malloc fail)
+        std::lock_guard<std::mutex> lock(mCache.mMutex);
+        const std::weak_ptr<BufferPoolClient> wclient = client;
+        mCache.mClients.push_back(std::make_pair(accessor, wclient));
+        ConnectionId conId = client->getConnectionId();
+        mObserver->addClient(conId, wclient);
+        {
+            std::lock_guard<std::mutex> lock(mActive.mMutex);
+            mActive.mClients.insert(std::make_pair(conId, client));
+        }
+        *pConnectionId = conId;
+        ALOGV("create new connection %lld", (long long)*pConnectionId);
+    }
+    return ResultStatus::OK;
+}
+
+ResultStatus ClientManager::Impl::close(ConnectionId connectionId) {
+    std::unique_lock<std::mutex> lock1(mCache.mMutex);
+    std::unique_lock<std::mutex> lock2(mActive.mMutex);
+    auto it = mActive.mClients.find(connectionId);
+    if (it != mActive.mClients.end()) {
+        sp<IAccessor> accessor;
+        it->second->getAccessor(&accessor);
+        std::shared_ptr<BufferPoolClient> closing = it->second;
+        mActive.mClients.erase(connectionId);
+        for (auto cit = mCache.mClients.begin(); cit != mCache.mClients.end();) {
+            // clean up dead client caches
+            sp<IAccessor> cAccessor = cit->first.promote();
+            if (!cAccessor || (accessor && interfacesEqual(cAccessor, accessor))) {
+                cit = mCache.mClients.erase(cit);
+            } else {
+                cit++;
+            }
+        }
+        lock2.unlock();
+        lock1.unlock();
+        closing->flush();
+        return ResultStatus::OK;
+    }
+    return ResultStatus::NOT_FOUND;
+}
+
+ResultStatus ClientManager::Impl::flush(ConnectionId connectionId) {
+    std::shared_ptr<BufferPoolClient> client;
+    {
+        std::lock_guard<std::mutex> lock(mActive.mMutex);
+        auto it = mActive.mClients.find(connectionId);
+        if (it == mActive.mClients.end()) {
+            return ResultStatus::NOT_FOUND;
+        }
+        client = it->second;
+    }
+    return client->flush();
+}
+
+ResultStatus ClientManager::Impl::allocate(
+        ConnectionId connectionId, const std::vector<uint8_t> &params,
+        native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
+    std::shared_ptr<BufferPoolClient> client;
+    {
+        std::lock_guard<std::mutex> lock(mActive.mMutex);
+        auto it = mActive.mClients.find(connectionId);
+        if (it == mActive.mClients.end()) {
+            return ResultStatus::NOT_FOUND;
+        }
+        client = it->second;
+    }
+    return client->allocate(params, handle, buffer);
+}
+
+ResultStatus ClientManager::Impl::receive(
+        ConnectionId connectionId, TransactionId transactionId,
+        BufferId bufferId, int64_t timestampUs,
+        native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
+    std::shared_ptr<BufferPoolClient> client;
+    {
+        std::lock_guard<std::mutex> lock(mActive.mMutex);
+        auto it = mActive.mClients.find(connectionId);
+        if (it == mActive.mClients.end()) {
+            return ResultStatus::NOT_FOUND;
+        }
+        client = it->second;
+    }
+    return client->receive(transactionId, bufferId, timestampUs, handle, buffer);
+}
+
+ResultStatus ClientManager::Impl::postSend(
+        ConnectionId receiverId, const std::shared_ptr<BufferPoolData> &buffer,
+        TransactionId *transactionId, int64_t *timestampUs) {
+    ConnectionId connectionId = buffer->mConnectionId;
+    std::shared_ptr<BufferPoolClient> client;
+    {
+        std::lock_guard<std::mutex> lock(mActive.mMutex);
+        auto it = mActive.mClients.find(connectionId);
+        if (it == mActive.mClients.end()) {
+            return ResultStatus::NOT_FOUND;
+        }
+        client = it->second;
+    }
+    return client->postSend(receiverId, buffer, transactionId, timestampUs);
+}
+
+ResultStatus ClientManager::Impl::getAccessor(
+        ConnectionId connectionId, sp<IAccessor> *accessor) {
+    std::shared_ptr<BufferPoolClient> client;
+    {
+        std::lock_guard<std::mutex> lock(mActive.mMutex);
+        auto it = mActive.mClients.find(connectionId);
+        if (it == mActive.mClients.end()) {
+            return ResultStatus::NOT_FOUND;
+        }
+        client = it->second;
+    }
+    return client->getAccessor(accessor);
+}
+
+void ClientManager::Impl::cleanUp(bool clearCache) {
+    int64_t now = getTimestampNow();
+    int64_t lastTransactionUs;
+    std::lock_guard<std::mutex> lock1(mCache.mMutex);
+    if (clearCache || mCache.mLastCleanUpUs + kCleanUpDurationUs < now) {
+        std::lock_guard<std::mutex> lock2(mActive.mMutex);
+        int cleaned = 0;
+        for (auto it = mActive.mClients.begin(); it != mActive.mClients.end();) {
+            if (!it->second->isActive(&lastTransactionUs, clearCache)) {
+                if (lastTransactionUs + kClientTimeoutUs < now) {
+                    sp<IAccessor> accessor;
+                    it->second->getAccessor(&accessor);
+                    it = mActive.mClients.erase(it);
+                    ++cleaned;
+                    continue;
+                }
+            }
+            ++it;
+        }
+        for (auto cit = mCache.mClients.begin(); cit != mCache.mClients.end();) {
+            // clean up dead client caches
+            sp<IAccessor> cAccessor = cit->first.promote();
+            if (!cAccessor) {
+                cit = mCache.mClients.erase(cit);
+            } else {
+                ++cit;
+            }
+        }
+        ALOGV("# of cleaned connections: %d", cleaned);
+        mCache.mLastCleanUpUs = now;
+    }
+}
+
+// Methods from ::android::hardware::media::bufferpool::V2_0::IClientManager follow.
+Return<void> ClientManager::registerSender(const sp<::android::hardware::media::bufferpool::V2_0::IAccessor>& bufferPool, registerSender_cb _hidl_cb) {
+    if (mImpl) {
+        ConnectionId connectionId = -1;
+        ResultStatus status = mImpl->registerSender(bufferPool, &connectionId);
+        _hidl_cb(status, connectionId);
+    } else {
+        _hidl_cb(ResultStatus::CRITICAL_ERROR, -1);
+    }
+    return Void();
+}
+
+// Methods for local use.
+sp<ClientManager> ClientManager::sInstance;
+std::mutex ClientManager::sInstanceLock;
+
+sp<ClientManager> ClientManager::getInstance() {
+    std::lock_guard<std::mutex> lock(sInstanceLock);
+    if (!sInstance) {
+        sInstance = new ClientManager();
+    }
+    Accessor::createInvalidator();
+    return sInstance;
+}
+
+ClientManager::ClientManager() : mImpl(new Impl()) {}
+
+ClientManager::~ClientManager() {
+}
+
+ResultStatus ClientManager::create(
+        const std::shared_ptr<BufferPoolAllocator> &allocator,
+        ConnectionId *pConnectionId) {
+    if (mImpl) {
+        return mImpl->create(allocator, pConnectionId);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus ClientManager::registerSender(
+        const sp<IClientManager> &receiver,
+        ConnectionId senderId,
+        ConnectionId *receiverId) {
+    if (mImpl) {
+        return mImpl->registerSender(receiver, senderId, receiverId);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus ClientManager::close(ConnectionId connectionId) {
+    if (mImpl) {
+        return mImpl->close(connectionId);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus ClientManager::flush(ConnectionId connectionId) {
+    if (mImpl) {
+        return mImpl->flush(connectionId);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus ClientManager::allocate(
+        ConnectionId connectionId, const std::vector<uint8_t> &params,
+        native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
+    if (mImpl) {
+        return mImpl->allocate(connectionId, params, handle, buffer);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus ClientManager::receive(
+        ConnectionId connectionId, TransactionId transactionId,
+        BufferId bufferId, int64_t timestampUs,
+        native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
+    if (mImpl) {
+        return mImpl->receive(connectionId, transactionId, bufferId,
+                              timestampUs, handle, buffer);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus ClientManager::postSend(
+        ConnectionId receiverId, const std::shared_ptr<BufferPoolData> &buffer,
+        TransactionId *transactionId, int64_t* timestampUs) {
+    if (mImpl && buffer) {
+        return mImpl->postSend(receiverId, buffer, transactionId, timestampUs);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+void ClientManager::cleanUp() {
+    if (mImpl) {
+        mImpl->cleanUp(true);
+    }
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
diff --git a/media/bufferpool/2.0/Connection.cpp b/media/bufferpool/2.0/Connection.cpp
new file mode 100644
index 0000000..57d0c7e
--- /dev/null
+++ b/media/bufferpool/2.0/Connection.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Connection.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V2_0 {
+namespace implementation {
+
+// Methods from ::android::hardware::media::bufferpool::V2_0::IConnection follow.
+Return<void> Connection::fetch(uint64_t transactionId, uint32_t bufferId, fetch_cb _hidl_cb) {
+    ResultStatus status = ResultStatus::CRITICAL_ERROR;
+    if (mInitialized && mAccessor) {
+        if (bufferId != SYNC_BUFFERID) {
+            const native_handle_t *handle = nullptr;
+            status = mAccessor->fetch(
+                    mConnectionId, transactionId, bufferId, &handle);
+            if (status == ResultStatus::OK) {
+                Buffer buffer = {};
+                buffer.id = bufferId;
+                buffer.buffer = handle;
+                _hidl_cb(status, buffer);
+                return Void();
+            }
+        } else {
+            mAccessor->cleanUp(false);
+        }
+    }
+
+    Buffer buffer = {};
+    buffer.id = 0;
+    buffer.buffer = nullptr;
+
+    _hidl_cb(status, buffer);
+    return Void();
+}
+
+Connection::Connection() : mInitialized(false), mConnectionId(-1LL) {}
+
+Connection::~Connection() {
+    if (mInitialized && mAccessor) {
+        mAccessor->close(mConnectionId);
+    }
+}
+
+void Connection::initialize(
+        const sp<Accessor>& accessor, ConnectionId connectionId) {
+    if (!mInitialized) {
+        mAccessor = accessor;
+        mConnectionId = connectionId;
+        mInitialized = true;
+    }
+}
+
+ResultStatus Connection::flush() {
+    if (mInitialized && mAccessor) {
+        return mAccessor->flush();
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+ResultStatus Connection::allocate(
+        const std::vector<uint8_t> &params, BufferId *bufferId,
+        const native_handle_t **handle) {
+    if (mInitialized && mAccessor) {
+        return mAccessor->allocate(mConnectionId, params, bufferId, handle);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+void Connection::cleanUp(bool clearCache) {
+    if (mInitialized && mAccessor) {
+        mAccessor->cleanUp(clearCache);
+    }
+}
+
+// Methods from ::android::hidl::base::V1_0::IBase follow.
+
+//IConnection* HIDL_FETCH_IConnection(const char* /* name */) {
+//    return new Connection();
+//}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
diff --git a/media/bufferpool/2.0/Connection.h b/media/bufferpool/2.0/Connection.h
new file mode 100644
index 0000000..8507749
--- /dev/null
+++ b/media/bufferpool/2.0/Connection.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_CONNECTION_H
+#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_CONNECTION_H
+
+#include <android/hardware/media/bufferpool/2.0/IConnection.h>
+#include <bufferpool/BufferPoolTypes.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include "Accessor.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::media::bufferpool::V2_0::implementation::Accessor;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct Connection : public IConnection {
+    // Methods from ::android::hardware::media::bufferpool::V2_0::IConnection follow.
+    Return<void> fetch(uint64_t transactionId, uint32_t bufferId, fetch_cb _hidl_cb) override;
+
+    /**
+     * Invalidates all buffers which are active and/or are ready to be recycled.
+     */
+    ResultStatus flush();
+
+    /**
+     * Allocates a buffer using the specified parameters. Recycles a buffer if
+     * it is possible. The returned buffer can be transferred to other remote
+     * clients(Connection).
+     *
+     * @param params    allocation parameters.
+     * @param bufferId  Id of the allocated buffer.
+     * @param handle    native handle of the allocated buffer.
+     *
+     * @return OK if a buffer is successfully allocated.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus allocate(const std::vector<uint8_t> &params,
+                          BufferId *bufferId, const native_handle_t **handle);
+
+    /**
+     * Processes pending buffer status messages and performs periodic cache cleaning
+     * from bufferpool.
+     *
+     * @param clearCache    if clearCache is true, bufferpool frees all buffers
+     *                      waiting to be recycled.
+     */
+    void cleanUp(bool clearCache);
+
+    /** Destructs a connection. */
+    ~Connection();
+
+    /** Creates a connection. */
+    Connection();
+
+    /**
+     * Initializes with the specified buffer pool and the connection id.
+     * The connection id should be unique in the whole system.
+     *
+     * @param accessor      the specified buffer pool.
+     * @param connectionId  Id.
+     */
+    void initialize(const sp<Accessor> &accessor, ConnectionId connectionId);
+
+    enum : uint32_t {
+        SYNC_BUFFERID = UINT32_MAX,
+    };
+
+private:
+    bool mInitialized;
+    sp<Accessor> mAccessor;
+    ConnectionId mConnectionId;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_CONNECTION_H
diff --git a/media/bufferpool/2.0/Observer.cpp b/media/bufferpool/2.0/Observer.cpp
new file mode 100644
index 0000000..5b23160
--- /dev/null
+++ b/media/bufferpool/2.0/Observer.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Observer.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V2_0 {
+namespace implementation {
+
+Observer::Observer() {
+}
+
+Observer::~Observer() {
+}
+
+// Methods from ::android::hardware::media::bufferpool::V2_0::IObserver follow.
+Return<void> Observer::onMessage(int64_t connectionId, uint32_t msgId) {
+    std::unique_lock<std::mutex> lock(mLock);
+    auto it = mClients.find(connectionId);
+    if (it != mClients.end()) {
+        const std::shared_ptr<BufferPoolClient> client = it->second.lock();
+        if (!client) {
+            mClients.erase(it);
+        } else {
+            lock.unlock();
+            client->receiveInvalidation(msgId);
+        }
+    }
+    return Void();
+}
+
+void Observer::addClient(ConnectionId connectionId,
+                         const std::weak_ptr<BufferPoolClient> &wclient) {
+    std::lock_guard<std::mutex> lock(mLock);
+    for (auto it = mClients.begin(); it != mClients.end();) {
+        if (!it->second.lock() || it->first == connectionId) {
+            it = mClients.erase(it);
+        } else {
+            ++it;
+        }
+    }
+    mClients.insert(std::make_pair(connectionId, wclient));
+
+}
+
+void Observer::delClient(ConnectionId connectionId) {
+    std::lock_guard<std::mutex> lock(mLock);
+    mClients.erase(connectionId);
+}
+
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
diff --git a/media/bufferpool/2.0/Observer.h b/media/bufferpool/2.0/Observer.h
new file mode 100644
index 0000000..42bd7c1
--- /dev/null
+++ b/media/bufferpool/2.0/Observer.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_OBSERVER_H
+#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_OBSERVER_H
+
+#include <android/hardware/media/bufferpool/2.0/IObserver.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include "BufferPoolClient.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct Observer : public IObserver {
+    // Methods from ::android::hardware::media::bufferpool::V2_0::IObserver follow.
+    Return<void> onMessage(int64_t connectionId, uint32_t msgId) override;
+
+    ~Observer();
+
+    void addClient(ConnectionId connectionId,
+                   const std::weak_ptr<BufferPoolClient> &wclient);
+
+    void delClient(ConnectionId connectionId);
+
+private:
+    Observer();
+
+    friend struct ClientManager;
+
+    std::mutex mLock;
+    std::map<ConnectionId, const std::weak_ptr<BufferPoolClient>> mClients;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_OBSERVER_H
diff --git a/media/bufferpool/2.0/include/bufferpool/BufferPoolTypes.h b/media/bufferpool/2.0/include/bufferpool/BufferPoolTypes.h
new file mode 100644
index 0000000..7c906cb
--- /dev/null
+++ b/media/bufferpool/2.0/include/bufferpool/BufferPoolTypes.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_BUFFERPOOLTYPES_H
+#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_BUFFERPOOLTYPES_H
+
+#include <android/hardware/media/bufferpool/2.0/types.h>
+#include <cutils/native_handle.h>
+#include <fmq/MessageQueue.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+
+struct BufferPoolData {
+    // For local use, to specify a bufferpool (client connection) for buffers.
+    // Return value from connect#IAccessor(android.hardware.media.bufferpool@2.0).
+    int64_t mConnectionId;
+    // BufferId
+    uint32_t mId;
+
+    BufferPoolData() : mConnectionId(0), mId(0) {}
+
+    BufferPoolData(
+            int64_t connectionId, uint32_t id)
+            : mConnectionId(connectionId), mId(id) {}
+
+    ~BufferPoolData() {}
+};
+
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::kSynchronizedReadWrite;
+using ::android::hardware::kUnsynchronizedWrite;
+
+typedef uint32_t BufferId;
+typedef uint64_t TransactionId;
+typedef int64_t ConnectionId;
+
+enum : ConnectionId {
+    INVALID_CONNECTIONID = 0,
+};
+
+typedef android::hardware::MessageQueue<BufferStatusMessage, kSynchronizedReadWrite> BufferStatusQueue;
+typedef BufferStatusQueue::Descriptor StatusDescriptor;
+
+typedef android::hardware::MessageQueue<BufferInvalidationMessage, kUnsynchronizedWrite>
+        BufferInvalidationQueue;
+typedef BufferInvalidationQueue::Descriptor InvalidationDescriptor;
+
+/**
+ * Allocation wrapper class for buffer pool.
+ */
+struct BufferPoolAllocation {
+    const native_handle_t *mHandle;
+
+    const native_handle_t *handle() {
+        return mHandle;
+    }
+
+    BufferPoolAllocation(const native_handle_t *handle) : mHandle(handle) {}
+
+    ~BufferPoolAllocation() {};
+};
+
+/**
+ * Allocator wrapper class for buffer pool.
+ */
+class BufferPoolAllocator {
+public:
+
+    /**
+     * Allocate an allocation(buffer) for buffer pool.
+     *
+     * @param params    allocation parameters
+     * @param alloc     created allocation
+     * @param allocSize size of created allocation
+     *
+     * @return OK when an allocation is created successfully.
+     */
+    virtual ResultStatus allocate(
+            const std::vector<uint8_t> &params,
+            std::shared_ptr<BufferPoolAllocation> *alloc,
+            size_t *allocSize) = 0;
+
+    /**
+     * Returns whether allocation parameters of an old allocation are
+     * compatible with new allocation parameters.
+     */
+    virtual bool compatible(const std::vector<uint8_t> &newParams,
+                            const std::vector<uint8_t> &oldParams) = 0;
+
+protected:
+    BufferPoolAllocator() = default;
+
+    virtual ~BufferPoolAllocator() = default;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_BUFFERPOOLTYPES_H
diff --git a/media/bufferpool/2.0/include/bufferpool/ClientManager.h b/media/bufferpool/2.0/include/bufferpool/ClientManager.h
new file mode 100644
index 0000000..953c304
--- /dev/null
+++ b/media/bufferpool/2.0/include/bufferpool/ClientManager.h
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_CLIENTMANAGER_H
+#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_CLIENTMANAGER_H
+
+#include <android/hardware/media/bufferpool/2.0/IClientManager.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <memory>
+#include "BufferPoolTypes.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::media::bufferpool::V2_0::IAccessor;
+using ::android::hardware::media::bufferpool::V2_0::ResultStatus;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct ClientManager : public IClientManager {
+    // Methods from ::android::hardware::media::bufferpool::V2_0::IClientManager follow.
+    Return<void> registerSender(const sp<::android::hardware::media::bufferpool::V2_0::IAccessor>& bufferPool, registerSender_cb _hidl_cb) override;
+
+    /** Gets an instance. */
+    static sp<ClientManager> getInstance();
+
+    /**
+     * Creates a local connection with a newly created buffer pool.
+     *
+     * @param allocator     for new buffer allocation.
+     * @param pConnectionId Id of the created connection. This is
+     *                      system-wide unique.
+     *
+     * @return OK when a buffer pool and a local connection is successfully
+     *         created.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus create(const std::shared_ptr<BufferPoolAllocator> &allocator,
+                        ConnectionId *pConnectionId);
+
+    /**
+     * Register a created connection as sender for remote process.
+     *
+     * @param receiver      The remote receiving process.
+     * @param senderId      A local connection which will send buffers to.
+     * @param receiverId    Id of the created receiving connection on the receiver
+     *                      process.
+     *
+     * @return OK when the receiving connection is successfully created on the
+     *         receiver process.
+     *         NOT_FOUND when the sender connection was not found.
+     *         ALREADY_EXISTS the receiving connection is already made.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus registerSender(const sp<IClientManager> &receiver,
+                                ConnectionId senderId,
+                                ConnectionId *receiverId);
+
+    /**
+     * Closes the specified connection.
+     *
+     * @param connectionId  The id of the connection.
+     *
+     * @return OK when the connection is closed.
+     *         NOT_FOUND when the specified connection was not found.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus close(ConnectionId connectionId);
+
+    /**
+     * Evicts cached allocations. If it's local connection, release the
+     * previous allocations and do not recycle current active allocations.
+     *
+     * @param connectionId The id of the connection.
+     *
+     * @return OK when the connection is resetted.
+     *         NOT_FOUND when the specified connection was not found.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus flush(ConnectionId connectionId);
+
+    /**
+     * Allocates a buffer from the specified connection.
+     *
+     * @param connectionId  The id of the connection.
+     * @param params        The allocation parameters.
+     * @param handle        The native handle to the allocated buffer. handle
+     *                      should be cloned before use.
+     * @param buffer        The allocated buffer.
+     *
+     * @return OK when a buffer was allocated successfully.
+     *         NOT_FOUND when the specified connection was not found.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus allocate(ConnectionId connectionId,
+                          const std::vector<uint8_t> &params,
+                          native_handle_t **handle,
+                          std::shared_ptr<BufferPoolData> *buffer);
+
+    /**
+     * Receives a buffer for the transaction.
+     *
+     * @param connectionId  The id of the receiving connection.
+     * @param transactionId The id for the transaction.
+     * @param bufferId      The id for the buffer.
+     * @param timestampUs   The timestamp of the buffer is being sent.
+     * @param handle        The native handle to the allocated buffer. handle
+     *                      should be cloned before use.
+     * @param buffer        The received buffer.
+     *
+     * @return OK when a buffer was received successfully.
+     *         NOT_FOUND when the specified connection was not found.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus receive(ConnectionId connectionId,
+                         TransactionId transactionId,
+                         BufferId bufferId,
+                         int64_t timestampUs,
+                          native_handle_t **handle,
+                         std::shared_ptr<BufferPoolData> *buffer);
+
+    /**
+     * Posts a buffer transfer transaction to the buffer pool. Sends a buffer
+     * to other remote clients(connection) after this call has been succeeded.
+     *
+     * @param receiverId    The id of the receiving connection.
+     * @param buffer        to transfer
+     * @param transactionId Id of the transfer transaction.
+     * @param timestampUs   The timestamp of the buffer transaction is being
+     *                      posted.
+     *
+     * @return OK when a buffer transaction was posted successfully.
+     *         NOT_FOUND when the sending connection was not found.
+     *         CRITICAL_ERROR otherwise.
+     */
+    ResultStatus postSend(ConnectionId receiverId,
+                          const std::shared_ptr<BufferPoolData> &buffer,
+                          TransactionId *transactionId,
+                          int64_t *timestampUs);
+
+    /**
+     *  Time out inactive lingering connections and close.
+     */
+    void cleanUp();
+
+    /** Destructs the manager of buffer pool clients.  */
+    ~ClientManager();
+private:
+    static sp<ClientManager> sInstance;
+    static std::mutex sInstanceLock;
+
+    class Impl;
+    const std::unique_ptr<Impl> mImpl;
+
+    ClientManager();
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace bufferpool
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_CLIENTMANAGER_H
diff --git a/media/bufferpool/2.0/tests/Android.bp b/media/bufferpool/2.0/tests/Android.bp
new file mode 100644
index 0000000..8b44f61
--- /dev/null
+++ b/media/bufferpool/2.0/tests/Android.bp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+cc_test {
+    name: "VtsVndkHidlBufferpoolV2_0TargetSingleTest",
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: [
+        "allocator.cpp",
+        "single.cpp",
+    ],
+    static_libs: [
+        "android.hardware.media.bufferpool@2.0",
+        "libcutils",
+        "libstagefright_bufferpool@2.0",
+    ],
+    shared_libs: [
+        "libfmq",
+    ],
+    compile_multilib: "both",
+}
+
+cc_test {
+    name: "VtsVndkHidlBufferpoolV2_0TargetMultiTest",
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: [
+        "allocator.cpp",
+        "multi.cpp",
+    ],
+    static_libs: [
+        "android.hardware.media.bufferpool@2.0",
+        "libcutils",
+        "libstagefright_bufferpool@2.0",
+    ],
+    shared_libs: [
+        "libfmq",
+    ],
+    compile_multilib: "both",
+}
diff --git a/media/bufferpool/2.0/tests/OWNERS b/media/bufferpool/2.0/tests/OWNERS
new file mode 100644
index 0000000..6733e0c
--- /dev/null
+++ b/media/bufferpool/2.0/tests/OWNERS
@@ -0,0 +1,9 @@
+# Media team
+lajos@google.com
+pawin@google.com
+taklee@google.com
+wonsik@google.com
+
+# VTS team
+yim@google.com
+zhuoyao@google.com
diff --git a/media/bufferpool/2.0/tests/allocator.cpp b/media/bufferpool/2.0/tests/allocator.cpp
new file mode 100644
index 0000000..843f7ea
--- /dev/null
+++ b/media/bufferpool/2.0/tests/allocator.cpp
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cutils/ashmem.h>
+#include <sys/mman.h>
+#include "allocator.h"
+
+union Params {
+  struct {
+    uint32_t capacity;
+  } data;
+  uint8_t array[0];
+  Params() : data{0} {}
+  Params(uint32_t size)
+      : data{size} {}
+};
+
+
+namespace {
+
+struct HandleAshmem : public native_handle_t {
+  HandleAshmem(int ashmemFd, size_t size)
+    : native_handle_t(cHeader),
+    mFds{ ashmemFd },
+    mInts{ int (size & 0xFFFFFFFF), int((uint64_t(size) >> 32) & 0xFFFFFFFF), kMagic } {}
+
+  int ashmemFd() const { return mFds.mAshmem; }
+  size_t size() const {
+    return size_t(unsigned(mInts.mSizeLo))
+        | size_t(uint64_t(unsigned(mInts.mSizeHi)) << 32);
+  }
+
+  static bool isValid(const native_handle_t * const o);
+
+protected:
+  struct {
+    int mAshmem;
+  } mFds;
+  struct {
+    int mSizeLo;
+    int mSizeHi;
+    int mMagic;
+  } mInts;
+
+private:
+  enum {
+    kMagic = 'ahm\x00',
+    numFds = sizeof(mFds) / sizeof(int),
+    numInts = sizeof(mInts) / sizeof(int),
+    version = sizeof(native_handle_t)
+  };
+  const static native_handle_t cHeader;
+};
+
+const native_handle_t HandleAshmem::cHeader = {
+  HandleAshmem::version,
+  HandleAshmem::numFds,
+  HandleAshmem::numInts,
+  {}
+};
+
+bool HandleAshmem::isValid(const native_handle_t * const o) {
+  if (!o || memcmp(o, &cHeader, sizeof(cHeader))) {
+    return false;
+  }
+  const HandleAshmem *other = static_cast<const HandleAshmem*>(o);
+  return other->mInts.mMagic == kMagic;
+}
+
+class AllocationAshmem {
+private:
+  AllocationAshmem(int ashmemFd, size_t capacity, bool res)
+    : mHandle(ashmemFd, capacity),
+      mInit(res) {}
+
+public:
+  static AllocationAshmem *Alloc(size_t size) {
+    constexpr static const char *kAllocationTag = "bufferpool_test";
+    int ashmemFd = ashmem_create_region(kAllocationTag, size);
+    return new AllocationAshmem(ashmemFd, size, ashmemFd >= 0);
+  }
+
+  ~AllocationAshmem() {
+    if (mInit) {
+      native_handle_close(&mHandle);
+    }
+  }
+
+  const HandleAshmem *handle() {
+    return &mHandle;
+  }
+
+private:
+  HandleAshmem mHandle;
+  bool mInit;
+  // TODO: mapping and map fd
+};
+
+struct AllocationDtor {
+  AllocationDtor(const std::shared_ptr<AllocationAshmem> &alloc)
+      : mAlloc(alloc) {}
+
+  void operator()(BufferPoolAllocation *poolAlloc) { delete poolAlloc; }
+
+  const std::shared_ptr<AllocationAshmem> mAlloc;
+};
+
+}
+
+
+ResultStatus TestBufferPoolAllocator::allocate(
+    const std::vector<uint8_t> &params,
+    std::shared_ptr<BufferPoolAllocation> *alloc,
+    size_t *allocSize) {
+  Params ashmemParams;
+  memcpy(&ashmemParams, params.data(), std::min(sizeof(Params), params.size()));
+
+  std::shared_ptr<AllocationAshmem> ashmemAlloc =
+      std::shared_ptr<AllocationAshmem>(
+          AllocationAshmem::Alloc(ashmemParams.data.capacity));
+  if (ashmemAlloc) {
+    BufferPoolAllocation *ptr = new BufferPoolAllocation(ashmemAlloc->handle());
+    if (ptr) {
+      *alloc = std::shared_ptr<BufferPoolAllocation>(ptr, AllocationDtor(ashmemAlloc));
+      if (*alloc) {
+          *allocSize = ashmemParams.data.capacity;
+          return ResultStatus::OK;
+      }
+      delete ptr;
+      return ResultStatus::NO_MEMORY;
+    }
+  }
+  return ResultStatus::CRITICAL_ERROR;
+}
+
+bool TestBufferPoolAllocator::compatible(const std::vector<uint8_t> &newParams,
+                                        const std::vector<uint8_t> &oldParams) {
+  size_t newSize = newParams.size();
+  size_t oldSize = oldParams.size();
+  if (newSize == oldSize) {
+    for (size_t i = 0; i < newSize; ++i) {
+      if (newParams[i] != oldParams[i]) {
+        return false;
+      }
+    }
+    return true;
+  }
+  return false;
+}
+
+bool TestBufferPoolAllocator::Fill(const native_handle_t *handle, const unsigned char val) {
+  if (!HandleAshmem::isValid(handle)) {
+    return false;
+  }
+  const HandleAshmem *o = static_cast<const HandleAshmem*>(handle);
+  unsigned char *ptr = (unsigned char *)mmap(
+      NULL, o->size(), PROT_READ|PROT_WRITE, MAP_SHARED, o->ashmemFd(), 0);
+
+  if (ptr != MAP_FAILED) {
+    for (size_t i = 0; i < o->size(); ++i) {
+      ptr[i] = val;
+    }
+    munmap(ptr, o->size());
+    return true;
+  }
+  return false;
+}
+
+bool TestBufferPoolAllocator::Verify(const native_handle_t *handle, const unsigned char val) {
+  if (!HandleAshmem::isValid(handle)) {
+    return false;
+  }
+  const HandleAshmem *o = static_cast<const HandleAshmem*>(handle);
+  unsigned char *ptr = (unsigned char *)mmap(
+      NULL, o->size(), PROT_READ, MAP_SHARED, o->ashmemFd(), 0);
+
+  if (ptr != MAP_FAILED) {
+    bool res = true;
+    for (size_t i = 0; i < o->size(); ++i) {
+      if (ptr[i] != val) {
+        res = false;
+        break;
+      }
+    }
+    munmap(ptr, o->size());
+    return res;
+  }
+  return false;
+}
+
+void getTestAllocatorParams(std::vector<uint8_t> *params) {
+  constexpr static int kAllocationSize = 1024 * 10;
+  Params ashmemParams(kAllocationSize);
+
+  params->assign(ashmemParams.array, ashmemParams.array + sizeof(ashmemParams));
+}
diff --git a/media/bufferpool/2.0/tests/allocator.h b/media/bufferpool/2.0/tests/allocator.h
new file mode 100644
index 0000000..5281dc3
--- /dev/null
+++ b/media/bufferpool/2.0/tests/allocator.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef VNDK_HIDL_BUFFERPOOL_V2_0_ALLOCATOR_H
+#define VNDK_HIDL_BUFFERPOOL_V2_0_ALLOCATOR_H
+
+#include <bufferpool/BufferPoolTypes.h>
+
+using android::hardware::media::bufferpool::V2_0::ResultStatus;
+using android::hardware::media::bufferpool::V2_0::implementation::
+    BufferPoolAllocation;
+using android::hardware::media::bufferpool::V2_0::implementation::
+    BufferPoolAllocator;
+
+// buffer allocator for the tests
+class TestBufferPoolAllocator : public BufferPoolAllocator {
+ public:
+  TestBufferPoolAllocator() {}
+
+  ~TestBufferPoolAllocator() override {}
+
+  ResultStatus allocate(const std::vector<uint8_t> &params,
+                        std::shared_ptr<BufferPoolAllocation> *alloc,
+                        size_t *allocSize) override;
+
+  bool compatible(const std::vector<uint8_t> &newParams,
+                  const std::vector<uint8_t> &oldParams) override;
+
+  static bool Fill(const native_handle_t *handle, const unsigned char val);
+
+  static bool Verify(const native_handle_t *handle, const unsigned char val);
+
+};
+
+// retrieve buffer allocator paramters
+void getTestAllocatorParams(std::vector<uint8_t> *params);
+
+#endif  // VNDK_HIDL_BUFFERPOOL_V2_0_ALLOCATOR_H
diff --git a/media/bufferpool/2.0/tests/multi.cpp b/media/bufferpool/2.0/tests/multi.cpp
new file mode 100644
index 0000000..68b6992
--- /dev/null
+++ b/media/bufferpool/2.0/tests/multi.cpp
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "buffferpool_unit_test"
+
+#include <gtest/gtest.h>
+
+#include <android-base/logging.h>
+#include <binder/ProcessState.h>
+#include <bufferpool/ClientManager.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/LegacySupport.h>
+#include <hidl/Status.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <iostream>
+#include <memory>
+#include <vector>
+#include "allocator.h"
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::hidl_handle;
+using android::hardware::media::bufferpool::V2_0::IClientManager;
+using android::hardware::media::bufferpool::V2_0::ResultStatus;
+using android::hardware::media::bufferpool::V2_0::implementation::BufferId;
+using android::hardware::media::bufferpool::V2_0::implementation::ClientManager;
+using android::hardware::media::bufferpool::V2_0::implementation::ConnectionId;
+using android::hardware::media::bufferpool::V2_0::implementation::TransactionId;
+using android::hardware::media::bufferpool::BufferPoolData;
+
+namespace {
+
+// communication message types between processes.
+enum PipeCommand : int32_t {
+    INIT_OK = 0,
+    INIT_ERROR,
+    SEND,
+    RECEIVE_OK,
+    RECEIVE_ERROR,
+};
+
+// communication message between processes.
+union PipeMessage {
+    struct  {
+        int32_t command;
+        BufferId bufferId;
+        ConnectionId connectionId;
+        TransactionId transactionId;
+        int64_t  timestampUs;
+    } data;
+    char array[0];
+};
+
+// media.bufferpool test setup
+class BufferpoolMultiTest : public ::testing::Test {
+ public:
+  virtual void SetUp() override {
+    ResultStatus status;
+    mReceiverPid = -1;
+    mConnectionValid = false;
+
+    ASSERT_TRUE(pipe(mCommandPipeFds) == 0);
+    ASSERT_TRUE(pipe(mResultPipeFds) == 0);
+
+    mReceiverPid = fork();
+    ASSERT_TRUE(mReceiverPid >= 0);
+
+    if (mReceiverPid == 0) {
+      doReceiver();
+      // In order to ignore gtest behaviour, wait for being killed from
+      // tearDown
+      pause();
+    }
+
+    mManager = ClientManager::getInstance();
+    ASSERT_NE(mManager, nullptr);
+
+    mAllocator = std::make_shared<TestBufferPoolAllocator>();
+    ASSERT_TRUE((bool)mAllocator);
+
+    status = mManager->create(mAllocator, &mConnectionId);
+    ASSERT_TRUE(status == ResultStatus::OK);
+    mConnectionValid = true;
+  }
+
+  virtual void TearDown() override {
+    if (mReceiverPid > 0) {
+      kill(mReceiverPid, SIGKILL);
+      int wstatus;
+      wait(&wstatus);
+    }
+
+    if (mConnectionValid) {
+      mManager->close(mConnectionId);
+    }
+  }
+
+ protected:
+  static void description(const std::string& description) {
+    RecordProperty("description", description);
+  }
+
+  android::sp<ClientManager> mManager;
+  std::shared_ptr<BufferPoolAllocator> mAllocator;
+  bool mConnectionValid;
+  ConnectionId mConnectionId;
+  pid_t mReceiverPid;
+  int mCommandPipeFds[2];
+  int mResultPipeFds[2];
+
+  bool sendMessage(int *pipes, const PipeMessage &message) {
+    int ret = write(pipes[1], message.array, sizeof(PipeMessage));
+    return ret == sizeof(PipeMessage);
+  }
+
+  bool receiveMessage(int *pipes, PipeMessage *message) {
+    int ret = read(pipes[0], message->array, sizeof(PipeMessage));
+    return ret == sizeof(PipeMessage);
+  }
+
+  void doReceiver() {
+    configureRpcThreadpool(1, false);
+    PipeMessage message;
+    mManager = ClientManager::getInstance();
+    if (!mManager) {
+      message.data.command = PipeCommand::INIT_ERROR;
+      sendMessage(mResultPipeFds, message);
+      return;
+    }
+    android::status_t status = mManager->registerAsService();
+    if (status != android::OK) {
+      message.data.command = PipeCommand::INIT_ERROR;
+      sendMessage(mResultPipeFds, message);
+      return;
+    }
+    message.data.command = PipeCommand::INIT_OK;
+    sendMessage(mResultPipeFds, message);
+
+    receiveMessage(mCommandPipeFds, &message);
+    {
+      native_handle_t *rhandle = nullptr;
+      std::shared_ptr<BufferPoolData> rbuffer;
+      ResultStatus status = mManager->receive(
+          message.data.connectionId, message.data.transactionId,
+          message.data.bufferId, message.data.timestampUs, &rhandle, &rbuffer);
+      mManager->close(message.data.connectionId);
+      if (status != ResultStatus::OK) {
+        if (!TestBufferPoolAllocator::Verify(rhandle, 0x77)) {
+          message.data.command = PipeCommand::RECEIVE_ERROR;
+          sendMessage(mResultPipeFds, message);
+          return;
+        }
+      }
+    }
+    message.data.command = PipeCommand::RECEIVE_OK;
+    sendMessage(mResultPipeFds, message);
+  }
+};
+
+// Buffer transfer test between processes.
+TEST_F(BufferpoolMultiTest, TransferBuffer) {
+  ResultStatus status;
+  PipeMessage message;
+
+  ASSERT_TRUE(receiveMessage(mResultPipeFds, &message));
+
+  android::sp<IClientManager> receiver = IClientManager::getService();
+  ConnectionId receiverId;
+  ASSERT_TRUE((bool)receiver);
+
+  status = mManager->registerSender(receiver, mConnectionId, &receiverId);
+  ASSERT_TRUE(status == ResultStatus::OK);
+  {
+    native_handle_t *shandle = nullptr;
+    std::shared_ptr<BufferPoolData> sbuffer;
+    TransactionId transactionId;
+    int64_t postUs;
+    std::vector<uint8_t> vecParams;
+
+    getTestAllocatorParams(&vecParams);
+    status = mManager->allocate(mConnectionId, vecParams, &shandle, &sbuffer);
+    ASSERT_TRUE(status == ResultStatus::OK);
+
+    ASSERT_TRUE(TestBufferPoolAllocator::Fill(shandle, 0x77));
+
+    status = mManager->postSend(receiverId, sbuffer, &transactionId, &postUs);
+    ASSERT_TRUE(status == ResultStatus::OK);
+
+    message.data.command = PipeCommand::SEND;
+    message.data.bufferId = sbuffer->mId;
+    message.data.connectionId = receiverId;
+    message.data.transactionId = transactionId;
+    message.data.timestampUs = postUs;
+    sendMessage(mCommandPipeFds, message);
+  }
+  EXPECT_TRUE(receiveMessage(mResultPipeFds, &message));
+}
+
+}  // anonymous namespace
+
+int main(int argc, char** argv) {
+  setenv("TREBLE_TESTING_OVERRIDE", "true", true);
+  ::testing::InitGoogleTest(&argc, argv);
+  int status = RUN_ALL_TESTS();
+  LOG(INFO) << "Test result = " << status;
+  return status;
+}
diff --git a/media/bufferpool/2.0/tests/single.cpp b/media/bufferpool/2.0/tests/single.cpp
new file mode 100644
index 0000000..777edcf
--- /dev/null
+++ b/media/bufferpool/2.0/tests/single.cpp
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "buffferpool_unit_test"
+
+#include <gtest/gtest.h>
+
+#include <android-base/logging.h>
+#include <binder/ProcessState.h>
+#include <bufferpool/ClientManager.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/LegacySupport.h>
+#include <hidl/Status.h>
+#include <unistd.h>
+#include <iostream>
+#include <memory>
+#include <vector>
+#include "allocator.h"
+
+using android::hardware::hidl_handle;
+using android::hardware::media::bufferpool::V2_0::ResultStatus;
+using android::hardware::media::bufferpool::V2_0::implementation::BufferId;
+using android::hardware::media::bufferpool::V2_0::implementation::ClientManager;
+using android::hardware::media::bufferpool::V2_0::implementation::ConnectionId;
+using android::hardware::media::bufferpool::V2_0::implementation::TransactionId;
+using android::hardware::media::bufferpool::BufferPoolData;
+
+namespace {
+
+// Number of iteration for buffer allocation test.
+constexpr static int kNumAllocationTest = 3;
+
+// Number of iteration for buffer recycling test.
+constexpr static int kNumRecycleTest = 3;
+
+// media.bufferpool test setup
+class BufferpoolSingleTest : public ::testing::Test {
+ public:
+  virtual void SetUp() override {
+    ResultStatus status;
+    mConnectionValid = false;
+
+    mManager = ClientManager::getInstance();
+    ASSERT_NE(mManager, nullptr);
+
+    mAllocator = std::make_shared<TestBufferPoolAllocator>();
+    ASSERT_TRUE((bool)mAllocator);
+
+    status = mManager->create(mAllocator, &mConnectionId);
+    ASSERT_TRUE(status == ResultStatus::OK);
+
+    mConnectionValid = true;
+
+    status = mManager->registerSender(mManager, mConnectionId, &mReceiverId);
+    ASSERT_TRUE(status == ResultStatus::ALREADY_EXISTS &&
+                mReceiverId == mConnectionId);
+  }
+
+  virtual void TearDown() override {
+    if (mConnectionValid) {
+      mManager->close(mConnectionId);
+    }
+  }
+
+ protected:
+  static void description(const std::string& description) {
+    RecordProperty("description", description);
+  }
+
+  android::sp<ClientManager> mManager;
+  std::shared_ptr<BufferPoolAllocator> mAllocator;
+  bool mConnectionValid;
+  ConnectionId mConnectionId;
+  ConnectionId mReceiverId;
+
+};
+
+// Buffer allocation test.
+// Check whether each buffer allocation is done successfully with
+// unique buffer id.
+TEST_F(BufferpoolSingleTest, AllocateBuffer) {
+  ResultStatus status;
+  std::vector<uint8_t> vecParams;
+  getTestAllocatorParams(&vecParams);
+
+  std::shared_ptr<BufferPoolData> buffer[kNumAllocationTest];
+  native_handle_t *allocHandle = nullptr;
+  for (int i = 0; i < kNumAllocationTest; ++i) {
+    status = mManager->allocate(mConnectionId, vecParams, &allocHandle, &buffer[i]);
+    ASSERT_TRUE(status == ResultStatus::OK);
+  }
+  for (int i = 0; i < kNumAllocationTest; ++i) {
+    for (int j = i + 1; j < kNumAllocationTest; ++j) {
+      ASSERT_TRUE(buffer[i]->mId != buffer[j]->mId);
+    }
+  }
+  EXPECT_TRUE(kNumAllocationTest > 1);
+}
+
+// Buffer recycle test.
+// Check whether de-allocated buffers are recycled.
+TEST_F(BufferpoolSingleTest, RecycleBuffer) {
+  ResultStatus status;
+  std::vector<uint8_t> vecParams;
+  getTestAllocatorParams(&vecParams);
+
+  BufferId bid[kNumRecycleTest];
+  for (int i = 0; i < kNumRecycleTest; ++i) {
+    std::shared_ptr<BufferPoolData> buffer;
+    native_handle_t *allocHandle = nullptr;
+    status = mManager->allocate(mConnectionId, vecParams, &allocHandle, &buffer);
+    ASSERT_TRUE(status == ResultStatus::OK);
+    bid[i] = buffer->mId;
+  }
+  for (int i = 1; i < kNumRecycleTest; ++i) {
+    ASSERT_TRUE(bid[i - 1] == bid[i]);
+  }
+  EXPECT_TRUE(kNumRecycleTest > 1);
+}
+
+// Buffer transfer test.
+// Check whether buffer is transferred to another client successfully.
+TEST_F(BufferpoolSingleTest, TransferBuffer) {
+  ResultStatus status;
+  std::vector<uint8_t> vecParams;
+  getTestAllocatorParams(&vecParams);
+  std::shared_ptr<BufferPoolData> sbuffer, rbuffer;
+  native_handle_t *allocHandle = nullptr;
+  native_handle_t *recvHandle = nullptr;
+
+  TransactionId transactionId;
+  int64_t postUs;
+
+  status = mManager->allocate(mConnectionId, vecParams, &allocHandle, &sbuffer);
+  ASSERT_TRUE(status == ResultStatus::OK);
+  ASSERT_TRUE(TestBufferPoolAllocator::Fill(allocHandle, 0x77));
+  status = mManager->postSend(mReceiverId, sbuffer, &transactionId, &postUs);
+  ASSERT_TRUE(status == ResultStatus::OK);
+  status = mManager->receive(mReceiverId, transactionId, sbuffer->mId, postUs,
+                             &recvHandle, &rbuffer);
+  EXPECT_TRUE(status == ResultStatus::OK);
+  ASSERT_TRUE(TestBufferPoolAllocator::Verify(recvHandle, 0x77));
+}
+
+}  // anonymous namespace
+
+int main(int argc, char** argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  int status = RUN_ALL_TESTS();
+  LOG(INFO) << "Test result = " << status;
+  return status;
+}
diff --git a/media/codec2/Android.mk b/media/codec2/Android.mk
new file mode 100644
index 0000000..82d739f
--- /dev/null
+++ b/media/codec2/Android.mk
@@ -0,0 +1,48 @@
+# =============================================================================
+# DOCUMENTATION GENERATION
+# =============================================================================
+C2_ROOT := $(call my-dir)
+
+C2_DOCS_ROOT := $(OUT_DIR)/target/common/docs/codec2
+
+C2_OUT_TEMP := $(PRODUCT_OUT)/gen/ETC/Codec2-docs_intermediates
+
+C2_DOXY := $(or $(shell command -v doxygen),\
+		$(shell command -v /Applications/Doxygen.app/Contents/Resources/doxygen))
+
+.PHONY: check-doxygen
+check-doxygen:
+ifndef C2_DOXY
+	$(error 'doxygen is not available')
+endif
+
+$(C2_OUT_TEMP)/doxy-api.config: $(C2_ROOT)/docs/doxygen.config
+	# only document include directory, no internal sections
+	sed 's/\(^INPUT *=.*\)/\1include\//; \
+	s/\(^INTERNAL_DOCS *= *\).*/\1NO/; \
+	s/\(^ENABLED_SECTIONS *=.*\)INTERNAL\(.*\).*/\1\2/; \
+	s:\(^OUTPUT_DIRECTORY *= \)out:\1'$(OUT_DIR)':;' \
+		$(C2_ROOT)/docs/doxygen.config > $@
+
+$(C2_OUT_TEMP)/doxy-internal.config: $(C2_ROOT)/docs/doxygen.config
+	sed 's:\(^OUTPUT_DIRECTORY *= \)out\(.*\)api:\1'$(OUT_DIR)'\2internal:;' \
+		$(C2_ROOT)/docs/doxygen.config > $@
+
+.PHONY: docs-api
+docs-api: $(C2_OUT_TEMP)/doxy-api.config check-doxygen
+	echo API docs are building in $(C2_DOCS_ROOT)/api
+	rm -rf $(C2_DOCS_ROOT)/api
+	mkdir -p $(C2_DOCS_ROOT)/api
+	$(C2_DOXY) $(C2_OUT_TEMP)/doxy-api.config
+
+.PHONY: docs-internal
+docs-internal: $(C2_OUT_TEMP)/doxy-internal.config check-doxygen
+	echo Internal docs are building in $(C2_DOCS_ROOT)/internal
+	rm -rf $(C2_DOCS_ROOT)/internal
+	mkdir -p $(C2_DOCS_ROOT)/internal
+	$(C2_DOXY) $(C2_OUT_TEMP)/doxy-internal.config
+
+.PHONY: docs-all
+docs-all: docs-api docs-internal
+
+include $(call all-makefiles-under,$(call my-dir))
diff --git a/media/codec2/components/aac/Android.bp b/media/codec2/components/aac/Android.bp
new file mode 100644
index 0000000..9eca585
--- /dev/null
+++ b/media/codec2/components/aac/Android.bp
@@ -0,0 +1,30 @@
+cc_library_shared {
+    name: "libcodec2_soft_aacdec",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_all-defaults",
+    ],
+
+    srcs: [
+        "C2SoftAacDec.cpp",
+        "DrcPresModeWrap.cpp",
+    ],
+
+    static_libs: [
+        "libFraunhoferAAC",
+    ],
+}
+
+cc_library_shared {
+    name: "libcodec2_soft_aacenc",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["C2SoftAacEnc.cpp"],
+
+    static_libs: [
+        "libFraunhoferAAC",
+    ],
+}
diff --git a/media/codec2/components/aac/C2SoftAacDec.cpp b/media/codec2/components/aac/C2SoftAacDec.cpp
new file mode 100644
index 0000000..2d4e126
--- /dev/null
+++ b/media/codec2/components/aac/C2SoftAacDec.cpp
@@ -0,0 +1,928 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftAacDec"
+#include <log/log.h>
+
+#include <inttypes.h>
+#include <math.h>
+#include <numeric>
+
+#include <cutils/properties.h>
+#include <media/stagefright/foundation/MediaDefs.h>
+#include <media/stagefright/foundation/hexdump.h>
+#include <media/stagefright/MediaErrors.h>
+#include <utils/misc.h>
+
+#include <C2PlatformSupport.h>
+#include <SimpleC2Interface.h>
+
+#include "C2SoftAacDec.h"
+
+#define FILEREAD_MAX_LAYERS 2
+
+#define DRC_DEFAULT_MOBILE_REF_LEVEL -16.0  /* 64*-0.25dB = -16 dB below full scale for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_CUT   1.0 /* maximum compression of dynamic range for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_BOOST 1.0 /* maximum compression of dynamic range for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_HEAVY C2Config::DRC_COMPRESSION_HEAVY   /* switch for heavy compression for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_EFFECT 3  /* MPEG-D DRC effect type; 3 => Limited playback range */
+#define DRC_DEFAULT_MOBILE_ENC_LEVEL (0.25) /* encoder target level; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
+#define MAX_CHANNEL_COUNT            8  /* maximum number of audio channels that can be decoded */
+// names of properties that can be used to override the default DRC settings
+#define PROP_DRC_OVERRIDE_REF_LEVEL  "aac_drc_reference_level"
+#define PROP_DRC_OVERRIDE_CUT        "aac_drc_cut"
+#define PROP_DRC_OVERRIDE_BOOST      "aac_drc_boost"
+#define PROP_DRC_OVERRIDE_HEAVY      "aac_drc_heavy"
+#define PROP_DRC_OVERRIDE_ENC_LEVEL "aac_drc_enc_target_level"
+#define PROP_DRC_OVERRIDE_EFFECT     "ro.aac_drc_effect_type"
+
+namespace android {
+
+constexpr char COMPONENT_NAME[] = "c2.android.aac.decoder";
+
+class C2SoftAacDec::IntfImpl : public SimpleInterface<void>::BaseParams {
+public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+        : SimpleInterface<void>::BaseParams(
+                helper,
+                COMPONENT_NAME,
+                C2Component::KIND_DECODER,
+                C2Component::DOMAIN_AUDIO,
+                MEDIA_MIMETYPE_AUDIO_AAC) {
+        noPrivateBuffers();
+        noInputReferences();
+        noOutputReferences();
+        noInputLatency();
+        noTimeStretch();
+
+        addParameter(
+                DefineParam(mActualOutputDelay, C2_PARAMKEY_OUTPUT_DELAY)
+                .withConstValue(new C2PortActualDelayTuning::output(2u))
+                .build());
+
+        addParameter(
+                DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE)
+                .withDefault(new C2StreamSampleRateInfo::output(0u, 44100))
+                .withFields({C2F(mSampleRate, value).oneOf({
+                    7350, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
+                })})
+                .withSetter(Setter<decltype(*mSampleRate)>::NonStrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mChannelCount, C2_PARAMKEY_CHANNEL_COUNT)
+                .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
+                .withFields({C2F(mChannelCount, value).inRange(1, 8)})
+                .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
+                .withDefault(new C2StreamBitrateInfo::input(0u, 64000))
+                .withFields({C2F(mBitrate, value).inRange(8000, 960000)})
+                .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
+                .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 8192))
+                .build());
+
+        addParameter(
+                DefineParam(mAacFormat, C2_PARAMKEY_AAC_PACKAGING)
+                .withDefault(new C2StreamAacFormatInfo::input(0u, C2Config::AAC_PACKAGING_RAW))
+                .withFields({C2F(mAacFormat, value).oneOf({
+                    C2Config::AAC_PACKAGING_RAW, C2Config::AAC_PACKAGING_ADTS
+                })})
+                .withSetter(Setter<decltype(*mAacFormat)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
+                .withDefault(new C2StreamProfileLevelInfo::input(0u,
+                        C2Config::PROFILE_AAC_LC, C2Config::LEVEL_UNUSED))
+                .withFields({
+                    C2F(mProfileLevel, profile).oneOf({
+                            C2Config::PROFILE_AAC_LC,
+                            C2Config::PROFILE_AAC_HE,
+                            C2Config::PROFILE_AAC_HE_PS,
+                            C2Config::PROFILE_AAC_LD,
+                            C2Config::PROFILE_AAC_ELD,
+                            C2Config::PROFILE_AAC_ER_SCALABLE,
+                            C2Config::PROFILE_AAC_XHE}),
+                    C2F(mProfileLevel, level).oneOf({
+                            C2Config::LEVEL_UNUSED
+                    })
+                })
+                .withSetter(ProfileLevelSetter)
+                .build());
+
+        addParameter(
+                DefineParam(mDrcCompressMode, C2_PARAMKEY_DRC_COMPRESSION_MODE)
+                .withDefault(new C2StreamDrcCompressionModeTuning::input(0u, C2Config::DRC_COMPRESSION_HEAVY))
+                .withFields({
+                    C2F(mDrcCompressMode, value).oneOf({
+                            C2Config::DRC_COMPRESSION_ODM_DEFAULT,
+                            C2Config::DRC_COMPRESSION_NONE,
+                            C2Config::DRC_COMPRESSION_LIGHT,
+                            C2Config::DRC_COMPRESSION_HEAVY})
+                })
+                .withSetter(Setter<decltype(*mDrcCompressMode)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mDrcTargetRefLevel, C2_PARAMKEY_DRC_TARGET_REFERENCE_LEVEL)
+                .withDefault(new C2StreamDrcTargetReferenceLevelTuning::input(0u, DRC_DEFAULT_MOBILE_REF_LEVEL))
+                .withFields({C2F(mDrcTargetRefLevel, value).inRange(-31.75, 0.25)})
+                .withSetter(Setter<decltype(*mDrcTargetRefLevel)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mDrcEncTargetLevel, C2_PARAMKEY_DRC_ENCODED_TARGET_LEVEL)
+                .withDefault(new C2StreamDrcEncodedTargetLevelTuning::input(0u, DRC_DEFAULT_MOBILE_ENC_LEVEL))
+                .withFields({C2F(mDrcEncTargetLevel, value).inRange(-31.75, 0.25)})
+                .withSetter(Setter<decltype(*mDrcEncTargetLevel)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mDrcBoostFactor, C2_PARAMKEY_DRC_BOOST_FACTOR)
+                .withDefault(new C2StreamDrcBoostFactorTuning::input(0u, DRC_DEFAULT_MOBILE_DRC_BOOST))
+                .withFields({C2F(mDrcBoostFactor, value).inRange(0, 1.)})
+                .withSetter(Setter<decltype(*mDrcBoostFactor)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mDrcAttenuationFactor, C2_PARAMKEY_DRC_ATTENUATION_FACTOR)
+                .withDefault(new C2StreamDrcAttenuationFactorTuning::input(0u, DRC_DEFAULT_MOBILE_DRC_CUT))
+                .withFields({C2F(mDrcAttenuationFactor, value).inRange(0, 1.)})
+                .withSetter(Setter<decltype(*mDrcAttenuationFactor)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mDrcEffectType, C2_PARAMKEY_DRC_EFFECT_TYPE)
+                .withDefault(new C2StreamDrcEffectTypeTuning::input(0u, C2Config::DRC_EFFECT_LIMITED_PLAYBACK_RANGE))
+                .withFields({
+                    C2F(mDrcEffectType, value).oneOf({
+                            C2Config::DRC_EFFECT_ODM_DEFAULT,
+                            C2Config::DRC_EFFECT_OFF,
+                            C2Config::DRC_EFFECT_NONE,
+                            C2Config::DRC_EFFECT_LATE_NIGHT,
+                            C2Config::DRC_EFFECT_NOISY_ENVIRONMENT,
+                            C2Config::DRC_EFFECT_LIMITED_PLAYBACK_RANGE,
+                            C2Config::DRC_EFFECT_LOW_PLAYBACK_LEVEL,
+                            C2Config::DRC_EFFECT_DIALOG_ENHANCEMENT,
+                            C2Config::DRC_EFFECT_GENERAL_COMPRESSION})
+                })
+                .withSetter(Setter<decltype(*mDrcEffectType)>::StrictValueWithNoDeps)
+                .build());
+    }
+
+    bool isAdts() const { return mAacFormat->value == C2Config::AAC_PACKAGING_ADTS; }
+    static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me) {
+        (void)mayBlock;
+        (void)me;  // TODO: validate
+        return C2R::Ok();
+    }
+    int32_t getDrcCompressMode() const { return mDrcCompressMode->value == C2Config::DRC_COMPRESSION_HEAVY ? 1 : 0; }
+    int32_t getDrcTargetRefLevel() const { return (mDrcTargetRefLevel->value <= 0 ? -mDrcTargetRefLevel->value * 4. + 0.5 : -1); }
+    int32_t getDrcEncTargetLevel() const { return (mDrcEncTargetLevel->value <= 0 ? -mDrcEncTargetLevel->value * 4. + 0.5 : -1); }
+    int32_t getDrcBoostFactor() const { return mDrcBoostFactor->value * 127. + 0.5; }
+    int32_t getDrcAttenuationFactor() const { return mDrcAttenuationFactor->value * 127. + 0.5; }
+    int32_t getDrcEffectType() const { return mDrcEffectType->value; }
+
+private:
+    std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
+    std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
+    std::shared_ptr<C2StreamBitrateInfo::input> mBitrate;
+    std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
+    std::shared_ptr<C2StreamAacFormatInfo::input> mAacFormat;
+    std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
+    std::shared_ptr<C2StreamDrcCompressionModeTuning::input> mDrcCompressMode;
+    std::shared_ptr<C2StreamDrcTargetReferenceLevelTuning::input> mDrcTargetRefLevel;
+    std::shared_ptr<C2StreamDrcEncodedTargetLevelTuning::input> mDrcEncTargetLevel;
+    std::shared_ptr<C2StreamDrcBoostFactorTuning::input> mDrcBoostFactor;
+    std::shared_ptr<C2StreamDrcAttenuationFactorTuning::input> mDrcAttenuationFactor;
+    std::shared_ptr<C2StreamDrcEffectTypeTuning::input> mDrcEffectType;
+    // TODO Add : C2StreamAacSbrModeTuning
+};
+
+C2SoftAacDec::C2SoftAacDec(
+        const char *name,
+        c2_node_id_t id,
+        const std::shared_ptr<IntfImpl> &intfImpl)
+    : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+      mIntf(intfImpl),
+      mAACDecoder(nullptr),
+      mStreamInfo(nullptr),
+      mSignalledError(false),
+      mOutputDelayRingBuffer(nullptr) {
+}
+
+C2SoftAacDec::~C2SoftAacDec() {
+    onRelease();
+}
+
+c2_status_t C2SoftAacDec::onInit() {
+    status_t err = initDecoder();
+    return err == OK ? C2_OK : C2_CORRUPTED;
+}
+
+c2_status_t C2SoftAacDec::onStop() {
+    drainDecoder();
+    // reset the "configured" state
+    mOutputDelayCompensated = 0;
+    mOutputDelayRingBufferWritePos = 0;
+    mOutputDelayRingBufferReadPos = 0;
+    mOutputDelayRingBufferFilled = 0;
+    mBuffersInfo.clear();
+
+    // To make the codec behave the same before and after a reset, we need to invalidate the
+    // streaminfo struct. This does that:
+    mStreamInfo->sampleRate = 0; // TODO: mStreamInfo is read only
+
+    mSignalledError = false;
+
+    return C2_OK;
+}
+
+void C2SoftAacDec::onReset() {
+    (void)onStop();
+}
+
+void C2SoftAacDec::onRelease() {
+    if (mAACDecoder) {
+        aacDecoder_Close(mAACDecoder);
+        mAACDecoder = nullptr;
+    }
+    if (mOutputDelayRingBuffer) {
+        delete[] mOutputDelayRingBuffer;
+        mOutputDelayRingBuffer = nullptr;
+    }
+}
+
+status_t C2SoftAacDec::initDecoder() {
+    ALOGV("initDecoder()");
+    status_t status = UNKNOWN_ERROR;
+    mAACDecoder = aacDecoder_Open(TT_MP4_ADIF, /* num layers */ 1);
+    if (mAACDecoder != nullptr) {
+        mStreamInfo = aacDecoder_GetStreamInfo(mAACDecoder);
+        if (mStreamInfo != nullptr) {
+            status = OK;
+        }
+    }
+
+    mOutputDelayCompensated = 0;
+    mOutputDelayRingBufferSize = 2048 * MAX_CHANNEL_COUNT * kNumDelayBlocksMax;
+    mOutputDelayRingBuffer = new short[mOutputDelayRingBufferSize];
+    mOutputDelayRingBufferWritePos = 0;
+    mOutputDelayRingBufferReadPos = 0;
+    mOutputDelayRingBufferFilled = 0;
+
+    if (mAACDecoder == nullptr) {
+        ALOGE("AAC decoder is null. TODO: Can not call aacDecoder_SetParam in the following code");
+    }
+
+    //aacDecoder_SetParam(mAACDecoder, AAC_PCM_LIMITER_ENABLE, 0);
+
+    //init DRC wrapper
+    mDrcWrap.setDecoderHandle(mAACDecoder);
+    mDrcWrap.submitStreamData(mStreamInfo);
+
+    // for streams that contain metadata, use the mobile profile DRC settings unless overridden by platform properties
+    // TODO: change the DRC settings depending on audio output device type (HDMI, loadspeaker, headphone)
+
+    //  DRC_PRES_MODE_WRAP_DESIRED_TARGET
+    int32_t targetRefLevel = mIntf->getDrcTargetRefLevel();
+    ALOGV("AAC decoder using desired DRC target reference level of %d", targetRefLevel);
+    mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, (unsigned)targetRefLevel);
+
+    //  DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR
+
+    int32_t attenuationFactor = mIntf->getDrcAttenuationFactor();
+    ALOGV("AAC decoder using desired DRC attenuation factor of %d", attenuationFactor);
+    mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, (unsigned)attenuationFactor);
+
+    //  DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR
+    int32_t boostFactor = mIntf->getDrcBoostFactor();
+    ALOGV("AAC decoder using desired DRC boost factor of %d", boostFactor);
+    mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, (unsigned)boostFactor);
+
+    //  DRC_PRES_MODE_WRAP_DESIRED_HEAVY
+    int32_t compressMode = mIntf->getDrcCompressMode();
+    ALOGV("AAC decoder using desried DRC heavy compression switch of %d", compressMode);
+    mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, (unsigned)compressMode);
+
+    // DRC_PRES_MODE_WRAP_ENCODER_TARGET
+    int32_t encTargetLevel = mIntf->getDrcEncTargetLevel();
+    ALOGV("AAC decoder using encoder-side DRC reference level of %d", encTargetLevel);
+    mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, (unsigned)encTargetLevel);
+
+    // AAC_UNIDRC_SET_EFFECT
+    int32_t effectType = mIntf->getDrcEffectType();
+    ALOGV("AAC decoder using MPEG-D DRC effect type %d", effectType);
+    aacDecoder_SetParam(mAACDecoder, AAC_UNIDRC_SET_EFFECT, effectType);
+
+    // By default, the decoder creates a 5.1 channel downmix signal.
+    // For seven and eight channel input streams, enable 6.1 and 7.1 channel output
+    aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, -1);
+
+    return status;
+}
+
+bool C2SoftAacDec::outputDelayRingBufferPutSamples(INT_PCM *samples, int32_t numSamples) {
+    if (numSamples == 0) {
+        return true;
+    }
+    if (outputDelayRingBufferSpaceLeft() < numSamples) {
+        ALOGE("RING BUFFER WOULD OVERFLOW");
+        return false;
+    }
+    if (mOutputDelayRingBufferWritePos + numSamples <= mOutputDelayRingBufferSize
+            && (mOutputDelayRingBufferReadPos <= mOutputDelayRingBufferWritePos
+                    || mOutputDelayRingBufferReadPos > mOutputDelayRingBufferWritePos + numSamples)) {
+        // faster memcopy loop without checks, if the preconditions allow this
+        for (int32_t i = 0; i < numSamples; i++) {
+            mOutputDelayRingBuffer[mOutputDelayRingBufferWritePos++] = samples[i];
+        }
+
+        if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) {
+            mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize;
+        }
+    } else {
+        ALOGV("slow C2SoftAacDec::outputDelayRingBufferPutSamples()");
+
+        for (int32_t i = 0; i < numSamples; i++) {
+            mOutputDelayRingBuffer[mOutputDelayRingBufferWritePos] = samples[i];
+            mOutputDelayRingBufferWritePos++;
+            if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) {
+                mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize;
+            }
+        }
+    }
+    mOutputDelayRingBufferFilled += numSamples;
+    return true;
+}
+
+int32_t C2SoftAacDec::outputDelayRingBufferGetSamples(INT_PCM *samples, int32_t numSamples) {
+
+    if (numSamples > mOutputDelayRingBufferFilled) {
+        ALOGE("RING BUFFER WOULD UNDERRUN");
+        return -1;
+    }
+
+    if (mOutputDelayRingBufferReadPos + numSamples <= mOutputDelayRingBufferSize
+            && (mOutputDelayRingBufferWritePos < mOutputDelayRingBufferReadPos
+                    || mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferReadPos + numSamples)) {
+        // faster memcopy loop without checks, if the preconditions allow this
+        if (samples != nullptr) {
+            for (int32_t i = 0; i < numSamples; i++) {
+                samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos++];
+            }
+        } else {
+            mOutputDelayRingBufferReadPos += numSamples;
+        }
+        if (mOutputDelayRingBufferReadPos >= mOutputDelayRingBufferSize) {
+            mOutputDelayRingBufferReadPos -= mOutputDelayRingBufferSize;
+        }
+    } else {
+        ALOGV("slow C2SoftAacDec::outputDelayRingBufferGetSamples()");
+
+        for (int32_t i = 0; i < numSamples; i++) {
+            if (samples != nullptr) {
+                samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos];
+            }
+            mOutputDelayRingBufferReadPos++;
+            if (mOutputDelayRingBufferReadPos >= mOutputDelayRingBufferSize) {
+                mOutputDelayRingBufferReadPos -= mOutputDelayRingBufferSize;
+            }
+        }
+    }
+    mOutputDelayRingBufferFilled -= numSamples;
+    return numSamples;
+}
+
+int32_t C2SoftAacDec::outputDelayRingBufferSamplesAvailable() {
+    return mOutputDelayRingBufferFilled;
+}
+
+int32_t C2SoftAacDec::outputDelayRingBufferSpaceLeft() {
+    return mOutputDelayRingBufferSize - outputDelayRingBufferSamplesAvailable();
+}
+
+void C2SoftAacDec::drainRingBuffer(
+        const std::unique_ptr<C2Work> &work,
+        const std::shared_ptr<C2BlockPool> &pool,
+        bool eos) {
+    while (!mBuffersInfo.empty() && outputDelayRingBufferSamplesAvailable()
+            >= mStreamInfo->frameSize * mStreamInfo->numChannels) {
+        Info &outInfo = mBuffersInfo.front();
+        ALOGV("outInfo.frameIndex = %" PRIu64, outInfo.frameIndex);
+        int samplesize __unused = mStreamInfo->numChannels * sizeof(int16_t);
+
+        int available = outputDelayRingBufferSamplesAvailable();
+        int numFrames = outInfo.decodedSizes.size();
+        int numSamples = numFrames * (mStreamInfo->frameSize * mStreamInfo->numChannels);
+        if (available < numSamples) {
+            if (eos) {
+                numSamples = available;
+            } else {
+                break;
+            }
+        }
+        ALOGV("%d samples available (%d), or %d frames",
+                numSamples, available, numFrames);
+        ALOGV("getting %d from ringbuffer", numSamples);
+
+        std::shared_ptr<C2LinearBlock> block;
+        std::function<void(const std::unique_ptr<C2Work>&)> fillWork =
+            [&block, numSamples, pool, this]()
+                    -> std::function<void(const std::unique_ptr<C2Work>&)> {
+                auto fillEmptyWork = [](
+                        const std::unique_ptr<C2Work> &work, c2_status_t err) {
+                    work->result = err;
+                    C2FrameData &output = work->worklets.front()->output;
+                    output.flags = work->input.flags;
+                    output.buffers.clear();
+                    output.ordinal = work->input.ordinal;
+
+                    work->workletsProcessed = 1u;
+                };
+
+                using namespace std::placeholders;
+                if (numSamples == 0) {
+                    return std::bind(fillEmptyWork, _1, C2_OK);
+                }
+
+                // TODO: error handling, proper usage, etc.
+                C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+                c2_status_t err = pool->fetchLinearBlock(
+                        numSamples * sizeof(int16_t), usage, &block);
+                if (err != C2_OK) {
+                    ALOGD("failed to fetch a linear block (%d)", err);
+                    return std::bind(fillEmptyWork, _1, C2_NO_MEMORY);
+                }
+                C2WriteView wView = block->map().get();
+                // TODO
+                INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(wView.data());
+                int32_t ns = outputDelayRingBufferGetSamples(outBuffer, numSamples);
+                if (ns != numSamples) {
+                    ALOGE("not a complete frame of samples available");
+                    mSignalledError = true;
+                    return std::bind(fillEmptyWork, _1, C2_CORRUPTED);
+                }
+                return [buffer = createLinearBuffer(block)](
+                        const std::unique_ptr<C2Work> &work) {
+                    work->result = C2_OK;
+                    C2FrameData &output = work->worklets.front()->output;
+                    output.flags = work->input.flags;
+                    output.buffers.clear();
+                    output.buffers.push_back(buffer);
+                    output.ordinal = work->input.ordinal;
+                    work->workletsProcessed = 1u;
+                };
+            }();
+
+        if (work && work->input.ordinal.frameIndex == c2_cntr64_t(outInfo.frameIndex)) {
+            fillWork(work);
+        } else {
+            finish(outInfo.frameIndex, fillWork);
+        }
+
+        ALOGV("out timestamp %" PRIu64 " / %u", outInfo.timestamp, block ? block->capacity() : 0);
+        mBuffersInfo.pop_front();
+    }
+}
+
+void C2SoftAacDec::process(
+        const std::unique_ptr<C2Work> &work,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    // Initialize output work
+    work->result = C2_OK;
+    work->workletsProcessed = 1u;
+    work->worklets.front()->output.configUpdate.clear();
+    work->worklets.front()->output.flags = work->input.flags;
+
+    if (mSignalledError) {
+        return;
+    }
+
+    UCHAR* inBuffer[FILEREAD_MAX_LAYERS];
+    UINT inBufferLength[FILEREAD_MAX_LAYERS] = {0};
+    UINT bytesValid[FILEREAD_MAX_LAYERS] = {0};
+
+    INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
+    C2ReadView view = mDummyReadView;
+    size_t offset = 0u;
+    size_t size = 0u;
+    if (!work->input.buffers.empty()) {
+        view = work->input.buffers[0]->data().linearBlocks().front().map().get();
+        size = view.capacity();
+    }
+
+    bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
+    bool codecConfig = (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0;
+
+    //TODO
+#if 0
+    if (mInputBufferCount == 0 && !codecConfig) {
+        ALOGW("first buffer should have FLAG_CODEC_CONFIG set");
+        codecConfig = true;
+    }
+#endif
+    if (codecConfig && size > 0u) {
+        // const_cast because of libAACdec method signature.
+        inBuffer[0] = const_cast<UCHAR *>(view.data() + offset);
+        inBufferLength[0] = size;
+
+        AAC_DECODER_ERROR decoderErr =
+            aacDecoder_ConfigRaw(mAACDecoder,
+                                 inBuffer,
+                                 inBufferLength);
+
+        if (decoderErr != AAC_DEC_OK) {
+            ALOGE("aacDecoder_ConfigRaw decoderErr = 0x%4.4x", decoderErr);
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+        work->worklets.front()->output.flags = work->input.flags;
+        work->worklets.front()->output.ordinal = work->input.ordinal;
+        work->worklets.front()->output.buffers.clear();
+        return;
+    }
+
+    Info inInfo;
+    inInfo.frameIndex = work->input.ordinal.frameIndex.peeku();
+    inInfo.timestamp = work->input.ordinal.timestamp.peeku();
+    inInfo.bufferSize = size;
+    inInfo.decodedSizes.clear();
+    while (size > 0u) {
+        ALOGV("size = %zu", size);
+        if (mIntf->isAdts()) {
+            size_t adtsHeaderSize = 0;
+            // skip 30 bits, aac_frame_length follows.
+            // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
+
+            const uint8_t *adtsHeader = view.data() + offset;
+
+            bool signalError = false;
+            if (size < 7) {
+                ALOGE("Audio data too short to contain even the ADTS header. "
+                        "Got %zu bytes.", size);
+                hexdump(adtsHeader, size);
+                signalError = true;
+            } else {
+                bool protectionAbsent = (adtsHeader[1] & 1);
+
+                unsigned aac_frame_length =
+                    ((adtsHeader[3] & 3) << 11)
+                    | (adtsHeader[4] << 3)
+                    | (adtsHeader[5] >> 5);
+
+                if (size < aac_frame_length) {
+                    ALOGE("Not enough audio data for the complete frame. "
+                            "Got %zu bytes, frame size according to the ADTS "
+                            "header is %u bytes.",
+                            size, aac_frame_length);
+                    hexdump(adtsHeader, size);
+                    signalError = true;
+                } else {
+                    adtsHeaderSize = (protectionAbsent ? 7 : 9);
+                    if (aac_frame_length < adtsHeaderSize) {
+                        signalError = true;
+                    } else {
+                        // const_cast because of libAACdec method signature.
+                        inBuffer[0] = const_cast<UCHAR *>(adtsHeader + adtsHeaderSize);
+                        inBufferLength[0] = aac_frame_length - adtsHeaderSize;
+
+                        offset += adtsHeaderSize;
+                        size -= adtsHeaderSize;
+                    }
+                }
+            }
+
+            if (signalError) {
+                mSignalledError = true;
+                work->result = C2_CORRUPTED;
+                return;
+            }
+        } else {
+            // const_cast because of libAACdec method signature.
+            inBuffer[0] = const_cast<UCHAR *>(view.data() + offset);
+            inBufferLength[0] = size;
+        }
+
+        // Fill and decode
+        bytesValid[0] = inBufferLength[0];
+
+        INT prevSampleRate = mStreamInfo->sampleRate;
+        INT prevNumChannels = mStreamInfo->numChannels;
+
+        aacDecoder_Fill(mAACDecoder,
+                        inBuffer,
+                        inBufferLength,
+                        bytesValid);
+
+        // run DRC check
+        mDrcWrap.submitStreamData(mStreamInfo);
+        mDrcWrap.update();
+
+        UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
+        size -= inBufferUsedLength;
+        offset += inBufferUsedLength;
+
+        AAC_DECODER_ERROR decoderErr;
+        do {
+            if (outputDelayRingBufferSpaceLeft() <
+                    (mStreamInfo->frameSize * mStreamInfo->numChannels)) {
+                ALOGV("skipping decode: not enough space left in ringbuffer");
+                // discard buffer
+                size = 0;
+                break;
+            }
+
+            int numConsumed = mStreamInfo->numTotalBytes;
+            decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
+                                       tmpOutBuffer,
+                                       2048 * MAX_CHANNEL_COUNT,
+                                       0 /* flags */);
+
+            numConsumed = mStreamInfo->numTotalBytes - numConsumed;
+
+            if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
+                break;
+            }
+            inInfo.decodedSizes.push_back(numConsumed);
+
+            if (decoderErr != AAC_DEC_OK) {
+                ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
+            }
+
+            if (bytesValid[0] != 0) {
+                ALOGE("bytesValid[0] != 0 should never happen");
+                mSignalledError = true;
+                work->result = C2_CORRUPTED;
+                return;
+            }
+
+            size_t numOutBytes =
+                mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels;
+
+            if (decoderErr == AAC_DEC_OK) {
+                if (!outputDelayRingBufferPutSamples(tmpOutBuffer,
+                        mStreamInfo->frameSize * mStreamInfo->numChannels)) {
+                    mSignalledError = true;
+                    work->result = C2_CORRUPTED;
+                    return;
+                }
+            } else {
+                ALOGW("AAC decoder returned error 0x%4.4x, substituting silence", decoderErr);
+
+                memset(tmpOutBuffer, 0, numOutBytes); // TODO: check for overflow
+
+                if (!outputDelayRingBufferPutSamples(tmpOutBuffer,
+                        mStreamInfo->frameSize * mStreamInfo->numChannels)) {
+                    mSignalledError = true;
+                    work->result = C2_CORRUPTED;
+                    return;
+                }
+
+                // Discard input buffer.
+                size = 0;
+
+                aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
+
+                // After an error, replace bufferSize with the sum of the
+                // decodedSizes to resynchronize the in/out lists.
+                inInfo.decodedSizes.pop_back();
+                inInfo.bufferSize = std::accumulate(
+                        inInfo.decodedSizes.begin(), inInfo.decodedSizes.end(), 0);
+
+                // fall through
+            }
+
+            /*
+             * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
+             * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
+             * rate system and the sampling rate in the final output is actually
+             * doubled compared with the core AAC decoder sampling rate.
+             *
+             * Explicit signalling is done by explicitly defining SBR audio object
+             * type in the bitstream. Implicit signalling is done by embedding
+             * SBR content in AAC extension payload specific to SBR, and hence
+             * requires an AAC decoder to perform pre-checks on actual audio frames.
+             *
+             * Thus, we could not say for sure whether a stream is
+             * AAC+/eAAC+ until the first data frame is decoded.
+             */
+            if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) {
+                // if ((mInputBufferCount > 2) && (mOutputBufferCount <= 1)) {
+                    ALOGD("Invalid AAC stream");
+                    // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
+                    // mSignalledError = true;
+                // }
+            } else if ((mStreamInfo->sampleRate != prevSampleRate) ||
+                       (mStreamInfo->numChannels != prevNumChannels)) {
+                ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
+                      prevSampleRate, mStreamInfo->sampleRate,
+                      prevNumChannels, mStreamInfo->numChannels);
+
+                C2StreamSampleRateInfo::output sampleRateInfo(0u, mStreamInfo->sampleRate);
+                C2StreamChannelCountInfo::output channelCountInfo(0u, mStreamInfo->numChannels);
+                std::vector<std::unique_ptr<C2SettingResult>> failures;
+                c2_status_t err = mIntf->config(
+                        { &sampleRateInfo, &channelCountInfo },
+                        C2_MAY_BLOCK,
+                        &failures);
+                if (err == OK) {
+                    // TODO: this does not handle the case where the values are
+                    //       altered during config.
+                    C2FrameData &output = work->worklets.front()->output;
+                    output.configUpdate.push_back(C2Param::Copy(sampleRateInfo));
+                    output.configUpdate.push_back(C2Param::Copy(channelCountInfo));
+                } else {
+                    ALOGE("Config Update failed");
+                    mSignalledError = true;
+                    work->result = C2_CORRUPTED;
+                    return;
+                }
+            }
+            ALOGV("size = %zu", size);
+        } while (decoderErr == AAC_DEC_OK);
+    }
+
+    int32_t outputDelay = mStreamInfo->outputDelay * mStreamInfo->numChannels;
+
+    mBuffersInfo.push_back(std::move(inInfo));
+    work->workletsProcessed = 0u;
+    if (!eos && mOutputDelayCompensated < outputDelay) {
+        // discard outputDelay at the beginning
+        int32_t toCompensate = outputDelay - mOutputDelayCompensated;
+        int32_t discard = outputDelayRingBufferSamplesAvailable();
+        if (discard > toCompensate) {
+            discard = toCompensate;
+        }
+        int32_t discarded = outputDelayRingBufferGetSamples(nullptr, discard);
+        mOutputDelayCompensated += discarded;
+        return;
+    }
+
+    if (eos) {
+        drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
+    } else {
+        drainRingBuffer(work, pool, false /* not EOS */);
+    }
+}
+
+c2_status_t C2SoftAacDec::drainInternal(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool,
+        const std::unique_ptr<C2Work> &work) {
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+
+    bool eos = (drainMode == DRAIN_COMPONENT_WITH_EOS);
+
+    drainDecoder();
+    drainRingBuffer(work, pool, eos);
+
+    if (eos) {
+        auto fillEmptyWork = [](const std::unique_ptr<C2Work> &work) {
+            work->worklets.front()->output.flags = work->input.flags;
+            work->worklets.front()->output.buffers.clear();
+            work->worklets.front()->output.ordinal = work->input.ordinal;
+            work->workletsProcessed = 1u;
+        };
+        while (mBuffersInfo.size() > 1u) {
+            finish(mBuffersInfo.front().frameIndex, fillEmptyWork);
+            mBuffersInfo.pop_front();
+        }
+        if (work && work->workletsProcessed == 0u) {
+            fillEmptyWork(work);
+        }
+        mBuffersInfo.clear();
+    }
+
+    return C2_OK;
+}
+
+c2_status_t C2SoftAacDec::drain(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    return drainInternal(drainMode, pool, nullptr);
+}
+
+c2_status_t C2SoftAacDec::onFlush_sm() {
+    drainDecoder();
+    mBuffersInfo.clear();
+
+    int avail;
+    while ((avail = outputDelayRingBufferSamplesAvailable()) > 0) {
+        if (avail > mStreamInfo->frameSize * mStreamInfo->numChannels) {
+            avail = mStreamInfo->frameSize * mStreamInfo->numChannels;
+        }
+        int32_t ns = outputDelayRingBufferGetSamples(nullptr, avail);
+        if (ns != avail) {
+            ALOGW("not a complete frame of samples available");
+            break;
+        }
+    }
+    mOutputDelayRingBufferReadPos = mOutputDelayRingBufferWritePos;
+
+    return C2_OK;
+}
+
+void C2SoftAacDec::drainDecoder() {
+    // flush decoder until outputDelay is compensated
+    while (mOutputDelayCompensated > 0) {
+        // a buffer big enough for MAX_CHANNEL_COUNT channels of decoded HE-AAC
+        INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
+
+        // run DRC check
+        mDrcWrap.submitStreamData(mStreamInfo);
+        mDrcWrap.update();
+
+        AAC_DECODER_ERROR decoderErr =
+            aacDecoder_DecodeFrame(mAACDecoder,
+                                   tmpOutBuffer,
+                                   2048 * MAX_CHANNEL_COUNT,
+                                   AACDEC_FLUSH);
+        if (decoderErr != AAC_DEC_OK) {
+            ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
+        }
+
+        int32_t tmpOutBufferSamples = mStreamInfo->frameSize * mStreamInfo->numChannels;
+        if (tmpOutBufferSamples > mOutputDelayCompensated) {
+            tmpOutBufferSamples = mOutputDelayCompensated;
+        }
+        outputDelayRingBufferPutSamples(tmpOutBuffer, tmpOutBufferSamples);
+
+        mOutputDelayCompensated -= tmpOutBufferSamples;
+    }
+}
+
+class C2SoftAacDecFactory : public C2ComponentFactory {
+public:
+    C2SoftAacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+            GetCodec2PlatformComponentStore()->getParamReflector())) {
+    }
+
+    virtual c2_status_t createComponent(
+            c2_node_id_t id,
+            std::shared_ptr<C2Component>* const component,
+            std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+                new C2SoftAacDec(COMPONENT_NAME,
+                              id,
+                              std::make_shared<C2SoftAacDec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+            c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
+            std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+                new SimpleInterface<C2SoftAacDec::IntfImpl>(
+                        COMPONENT_NAME, id, std::make_shared<C2SoftAacDec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftAacDecFactory() override = default;
+
+private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftAacDecFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/aac/C2SoftAacDec.h b/media/codec2/components/aac/C2SoftAacDec.h
new file mode 100644
index 0000000..965c29e
--- /dev/null
+++ b/media/codec2/components/aac/C2SoftAacDec.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_AAC_DEC_H_
+#define ANDROID_C2_SOFT_AAC_DEC_H_
+
+#include <SimpleC2Component.h>
+
+
+#include "aacdecoder_lib.h"
+#include "DrcPresModeWrap.h"
+
+namespace android {
+
+struct C2SoftAacDec : public SimpleC2Component {
+    class IntfImpl;
+
+    C2SoftAacDec(const char *name, c2_node_id_t id, const std::shared_ptr<IntfImpl> &intfImpl);
+    virtual ~C2SoftAacDec();
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+    c2_status_t drain(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+
+private:
+    enum {
+        kNumDelayBlocksMax      = 8,
+    };
+
+    std::shared_ptr<IntfImpl> mIntf;
+
+    HANDLE_AACDECODER mAACDecoder;
+    CStreamInfo *mStreamInfo;
+    bool mIsFirst;
+    size_t mInputBufferCount;
+    size_t mOutputBufferCount;
+    bool mSignalledError;
+    struct Info {
+        uint64_t frameIndex;
+        size_t bufferSize;
+        uint64_t timestamp;
+        std::vector<int32_t> decodedSizes;
+    };
+    std::list<Info> mBuffersInfo;
+
+    CDrcPresModeWrapper mDrcWrap;
+
+    enum {
+        NONE,
+        AWAITING_DISABLED,
+        AWAITING_ENABLED
+    } mOutputPortSettingsChange;
+
+    void initPorts();
+    status_t initDecoder();
+    bool isConfigured() const;
+    void drainDecoder();
+
+    void drainRingBuffer(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool,
+            bool eos);
+    c2_status_t drainInternal(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool,
+            const std::unique_ptr<C2Work> &work);
+
+//      delay compensation
+    bool mEndOfInput;
+    bool mEndOfOutput;
+    int32_t mOutputDelayCompensated;
+    int32_t mOutputDelayRingBufferSize;
+    short *mOutputDelayRingBuffer;
+    int32_t mOutputDelayRingBufferWritePos;
+    int32_t mOutputDelayRingBufferReadPos;
+    int32_t mOutputDelayRingBufferFilled;
+    bool outputDelayRingBufferPutSamples(INT_PCM *samples, int numSamples);
+    int32_t outputDelayRingBufferGetSamples(INT_PCM *samples, int numSamples);
+    int32_t outputDelayRingBufferSamplesAvailable();
+    int32_t outputDelayRingBufferSpaceLeft();
+
+    C2_DO_NOT_COPY(C2SoftAacDec);
+};
+
+}  // namespace android
+
+#endif  // ANDROID_C2_SOFT_AAC_DEC_H_
diff --git a/media/codec2/components/aac/C2SoftAacEnc.cpp b/media/codec2/components/aac/C2SoftAacEnc.cpp
new file mode 100644
index 0000000..8e3852c
--- /dev/null
+++ b/media/codec2/components/aac/C2SoftAacEnc.cpp
@@ -0,0 +1,622 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftAacEnc"
+#include <utils/Log.h>
+
+#include <inttypes.h>
+
+#include <C2PlatformSupport.h>
+#include <SimpleC2Interface.h>
+#include <media/stagefright/foundation/MediaDefs.h>
+#include <media/stagefright/foundation/hexdump.h>
+
+#include "C2SoftAacEnc.h"
+
+namespace android {
+
+namespace {
+
+constexpr char COMPONENT_NAME[] = "c2.android.aac.encoder";
+
+}  // namespace
+
+class C2SoftAacEnc::IntfImpl : public SimpleInterface<void>::BaseParams {
+public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+        : SimpleInterface<void>::BaseParams(
+                helper,
+                COMPONENT_NAME,
+                C2Component::KIND_ENCODER,
+                C2Component::DOMAIN_AUDIO,
+                MEDIA_MIMETYPE_AUDIO_AAC) {
+        noPrivateBuffers();
+        noInputReferences();
+        noOutputReferences();
+        noInputLatency();
+        noTimeStretch();
+        setDerivedInstance(this);
+
+        addParameter(
+                DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                .withConstValue(new C2ComponentAttributesSetting(
+                    C2Component::ATTRIB_IS_TEMPORAL))
+                .build());
+
+        addParameter(
+                DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE)
+                .withDefault(new C2StreamSampleRateInfo::input(0u, 44100))
+                .withFields({C2F(mSampleRate, value).oneOf({
+                    8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
+                })})
+                .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
+                .build());
+
+        addParameter(
+                DefineParam(mChannelCount, C2_PARAMKEY_CHANNEL_COUNT)
+                .withDefault(new C2StreamChannelCountInfo::input(0u, 1))
+                .withFields({C2F(mChannelCount, value).inRange(1, 6)})
+                .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
+                .withDefault(new C2StreamBitrateInfo::output(0u, 64000))
+                .withFields({C2F(mBitrate, value).inRange(8000, 960000)})
+                .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
+                .withDefault(new C2StreamMaxBufferSizeInfo::input(0u, 8192))
+                .calculatedAs(MaxBufSizeCalculator, mChannelCount)
+                .build());
+
+        addParameter(
+                DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
+                .withDefault(new C2StreamProfileLevelInfo::output(0u,
+                        C2Config::PROFILE_AAC_LC, C2Config::LEVEL_UNUSED))
+                .withFields({
+                    C2F(mProfileLevel, profile).oneOf({
+                            C2Config::PROFILE_AAC_LC,
+                            C2Config::PROFILE_AAC_HE,
+                            C2Config::PROFILE_AAC_HE_PS,
+                            C2Config::PROFILE_AAC_LD,
+                            C2Config::PROFILE_AAC_ELD}),
+                    C2F(mProfileLevel, level).oneOf({
+                            C2Config::LEVEL_UNUSED
+                    })
+                })
+                .withSetter(ProfileLevelSetter)
+                .build());
+
+       addParameter(
+                DefineParam(mSBRMode, C2_PARAMKEY_AAC_SBR_MODE)
+                .withDefault(new C2StreamAacSbrModeTuning::input(0u, AAC_SBR_AUTO))
+                .withFields({C2F(mSBRMode, value).oneOf({
+                            C2Config::AAC_SBR_OFF,
+                            C2Config::AAC_SBR_SINGLE_RATE,
+                            C2Config::AAC_SBR_DUAL_RATE,
+                            C2Config::AAC_SBR_AUTO })})
+                .withSetter(Setter<decltype(*mSBRMode)>::NonStrictValueWithNoDeps)
+                .build());
+    }
+
+    uint32_t getSampleRate() const { return mSampleRate->value; }
+    uint32_t getChannelCount() const { return mChannelCount->value; }
+    uint32_t getBitrate() const { return mBitrate->value; }
+    uint32_t getSBRMode() const { return mSBRMode->value; }
+    uint32_t getProfile() const { return mProfileLevel->profile; }
+    static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::output> &me) {
+        (void)mayBlock;
+        (void)me;  // TODO: validate
+        return C2R::Ok();
+    }
+
+    static C2R MaxBufSizeCalculator(
+            bool mayBlock,
+            C2P<C2StreamMaxBufferSizeInfo::input> &me,
+            const C2P<C2StreamChannelCountInfo::input> &channelCount) {
+        (void)mayBlock;
+        me.set().value = 1024 * sizeof(short) * channelCount.v.value;
+        return C2R::Ok();
+    }
+
+private:
+    std::shared_ptr<C2StreamSampleRateInfo::input> mSampleRate;
+    std::shared_ptr<C2StreamChannelCountInfo::input> mChannelCount;
+    std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
+    std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
+    std::shared_ptr<C2StreamProfileLevelInfo::output> mProfileLevel;
+    std::shared_ptr<C2StreamAacSbrModeTuning::input> mSBRMode;
+};
+
+C2SoftAacEnc::C2SoftAacEnc(
+        const char *name,
+        c2_node_id_t id,
+        const std::shared_ptr<IntfImpl> &intfImpl)
+    : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+      mIntf(intfImpl),
+      mAACEncoder(nullptr),
+      mNumBytesPerInputFrame(0u),
+      mOutBufferSize(0u),
+      mSentCodecSpecificData(false),
+      mInputTimeSet(false),
+      mInputSize(0),
+      mInputTimeUs(0),
+      mSignalledError(false),
+      mOutIndex(0u) {
+}
+
+C2SoftAacEnc::~C2SoftAacEnc() {
+    onReset();
+}
+
+c2_status_t C2SoftAacEnc::onInit() {
+    status_t err = initEncoder();
+    return err == OK ? C2_OK : C2_CORRUPTED;
+}
+
+status_t C2SoftAacEnc::initEncoder() {
+    if (AACENC_OK != aacEncOpen(&mAACEncoder, 0, 0)) {
+        ALOGE("Failed to init AAC encoder");
+        return UNKNOWN_ERROR;
+    }
+    return setAudioParams();
+}
+
+c2_status_t C2SoftAacEnc::onStop() {
+    mSentCodecSpecificData = false;
+    mInputTimeSet = false;
+    mInputSize = 0u;
+    mInputTimeUs = 0;
+    mSignalledError = false;
+    return C2_OK;
+}
+
+void C2SoftAacEnc::onReset() {
+    (void)onStop();
+    aacEncClose(&mAACEncoder);
+}
+
+void C2SoftAacEnc::onRelease() {
+    // no-op
+}
+
+c2_status_t C2SoftAacEnc::onFlush_sm() {
+    mSentCodecSpecificData = false;
+    mInputTimeSet = false;
+    mInputSize = 0u;
+    mInputTimeUs = 0;
+    return C2_OK;
+}
+
+static CHANNEL_MODE getChannelMode(uint32_t nChannels) {
+    CHANNEL_MODE chMode = MODE_INVALID;
+    switch (nChannels) {
+        case 1: chMode = MODE_1; break;
+        case 2: chMode = MODE_2; break;
+        case 3: chMode = MODE_1_2; break;
+        case 4: chMode = MODE_1_2_1; break;
+        case 5: chMode = MODE_1_2_2; break;
+        case 6: chMode = MODE_1_2_2_1; break;
+        default: chMode = MODE_INVALID;
+    }
+    return chMode;
+}
+
+static AUDIO_OBJECT_TYPE getAOTFromProfile(uint32_t profile) {
+   if (profile == C2Config::PROFILE_AAC_LC) {
+       return AOT_AAC_LC;
+   } else if (profile == C2Config::PROFILE_AAC_HE) {
+       return AOT_SBR;
+   } else if (profile == C2Config::PROFILE_AAC_HE_PS) {
+       return AOT_PS;
+   } else if (profile == C2Config::PROFILE_AAC_LD) {
+       return AOT_ER_AAC_LD;
+   } else if (profile == C2Config::PROFILE_AAC_ELD) {
+       return AOT_ER_AAC_ELD;
+   } else {
+       ALOGW("Unsupported AAC profile - defaulting to AAC-LC");
+       return AOT_AAC_LC;
+   }
+}
+
+status_t C2SoftAacEnc::setAudioParams() {
+    // We call this whenever sample rate, number of channels, bitrate or SBR mode change
+    // in reponse to setParameter calls.
+    int32_t sbrRatio = 0;
+    uint32_t sbrMode = mIntf->getSBRMode();
+    if (sbrMode == AAC_SBR_SINGLE_RATE) sbrRatio = 1;
+    else if (sbrMode == AAC_SBR_DUAL_RATE) sbrRatio = 2;
+
+    ALOGV("setAudioParams: %u Hz, %u channels, %u bps, %i sbr mode, %i sbr ratio",
+         mIntf->getSampleRate(), mIntf->getChannelCount(), mIntf->getBitrate(),
+         sbrMode, sbrRatio);
+
+    uint32_t aacProfile = mIntf->getProfile();
+    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_AOT, getAOTFromProfile(aacProfile))) {
+        ALOGE("Failed to set AAC encoder parameters");
+        return UNKNOWN_ERROR;
+    }
+
+    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_SAMPLERATE, mIntf->getSampleRate())) {
+        ALOGE("Failed to set AAC encoder parameters");
+        return UNKNOWN_ERROR;
+    }
+    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_BITRATE, mIntf->getBitrate())) {
+        ALOGE("Failed to set AAC encoder parameters");
+        return UNKNOWN_ERROR;
+    }
+    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_CHANNELMODE,
+            getChannelMode(mIntf->getChannelCount()))) {
+        ALOGE("Failed to set AAC encoder parameters");
+        return UNKNOWN_ERROR;
+    }
+    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_TRANSMUX, TT_MP4_RAW)) {
+        ALOGE("Failed to set AAC encoder parameters");
+        return UNKNOWN_ERROR;
+    }
+
+    if (sbrMode != -1 && aacProfile == C2Config::PROFILE_AAC_ELD) {
+        if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_SBR_MODE, sbrMode)) {
+            ALOGE("Failed to set AAC encoder parameters");
+            return UNKNOWN_ERROR;
+        }
+    }
+
+    /* SBR ratio parameter configurations:
+       0: Default configuration wherein SBR ratio is configured depending on audio object type by
+          the FDK.
+       1: Downsampled SBR (default for ELD)
+       2: Dualrate SBR (default for HE-AAC)
+     */
+    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_SBR_RATIO, sbrRatio)) {
+        ALOGE("Failed to set AAC encoder parameters");
+        return UNKNOWN_ERROR;
+    }
+
+    return OK;
+}
+
+void C2SoftAacEnc::process(
+        const std::unique_ptr<C2Work> &work,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    // Initialize output work
+    work->result = C2_OK;
+    work->workletsProcessed = 1u;
+    work->worklets.front()->output.flags = work->input.flags;
+
+    if (mSignalledError) {
+        return;
+    }
+    bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
+
+    uint32_t sampleRate = mIntf->getSampleRate();
+    uint32_t channelCount = mIntf->getChannelCount();
+
+    if (!mSentCodecSpecificData) {
+        // The very first thing we want to output is the codec specific
+        // data.
+
+        if (AACENC_OK != aacEncEncode(mAACEncoder, nullptr, nullptr, nullptr, nullptr)) {
+            ALOGE("Unable to initialize encoder for profile / sample-rate / bit-rate / channels");
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+
+        uint32_t bitrate = mIntf->getBitrate();
+        uint32_t actualBitRate = aacEncoder_GetParam(mAACEncoder, AACENC_BITRATE);
+        if (bitrate != actualBitRate) {
+            ALOGW("Requested bitrate %u unsupported, using %u", bitrate, actualBitRate);
+        }
+
+        AACENC_InfoStruct encInfo;
+        if (AACENC_OK != aacEncInfo(mAACEncoder, &encInfo)) {
+            ALOGE("Failed to get AAC encoder info");
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+
+        std::unique_ptr<C2StreamInitDataInfo::output> csd =
+            C2StreamInitDataInfo::output::AllocUnique(encInfo.confSize, 0u);
+        if (!csd) {
+            ALOGE("CSD allocation failed");
+            mSignalledError = true;
+            work->result = C2_NO_MEMORY;
+            return;
+        }
+        memcpy(csd->m.value, encInfo.confBuf, encInfo.confSize);
+        ALOGV("put csd");
+#if defined(LOG_NDEBUG) && !LOG_NDEBUG
+        hexdump(csd->m.value, csd->flexCount());
+#endif
+        work->worklets.front()->output.configUpdate.push_back(std::move(csd));
+
+        mOutBufferSize = encInfo.maxOutBufBytes;
+        mNumBytesPerInputFrame = encInfo.frameLength * channelCount * sizeof(int16_t);
+
+        mSentCodecSpecificData = true;
+    }
+
+    uint8_t temp[1];
+    C2ReadView view = mDummyReadView;
+    const uint8_t *data = temp;
+    size_t capacity = 0u;
+    if (!work->input.buffers.empty()) {
+        view = work->input.buffers[0]->data().linearBlocks().front().map().get();
+        data = view.data();
+        capacity = view.capacity();
+    }
+    if (!mInputTimeSet && capacity > 0) {
+        mInputTimeUs = work->input.ordinal.timestamp;
+        mInputTimeSet = true;
+    }
+
+    size_t numFrames = (capacity + mInputSize + (eos ? mNumBytesPerInputFrame - 1 : 0))
+            / mNumBytesPerInputFrame;
+    ALOGV("capacity = %zu; mInputSize = %zu; numFrames = %zu mNumBytesPerInputFrame = %u",
+          capacity, mInputSize, numFrames, mNumBytesPerInputFrame);
+
+    std::shared_ptr<C2LinearBlock> block;
+    std::shared_ptr<C2Buffer> buffer;
+    std::unique_ptr<C2WriteView> wView;
+    uint8_t *outPtr = temp;
+    size_t outAvailable = 0u;
+    uint64_t inputIndex = work->input.ordinal.frameIndex.peeku();
+
+    AACENC_InArgs inargs;
+    AACENC_OutArgs outargs;
+    memset(&inargs, 0, sizeof(inargs));
+    memset(&outargs, 0, sizeof(outargs));
+    inargs.numInSamples = capacity / sizeof(int16_t);
+
+    void* inBuffer[]        = { (unsigned char *)data };
+    INT   inBufferIds[]     = { IN_AUDIO_DATA };
+    INT   inBufferSize[]    = { (INT)capacity };
+    INT   inBufferElSize[]  = { sizeof(int16_t) };
+
+    AACENC_BufDesc inBufDesc;
+    inBufDesc.numBufs           = sizeof(inBuffer) / sizeof(void*);
+    inBufDesc.bufs              = (void**)&inBuffer;
+    inBufDesc.bufferIdentifiers = inBufferIds;
+    inBufDesc.bufSizes          = inBufferSize;
+    inBufDesc.bufElSizes        = inBufferElSize;
+
+    void* outBuffer[]       = { outPtr };
+    INT   outBufferIds[]    = { OUT_BITSTREAM_DATA };
+    INT   outBufferSize[]   = { 0 };
+    INT   outBufferElSize[] = { sizeof(UCHAR) };
+
+    AACENC_BufDesc outBufDesc;
+    outBufDesc.numBufs           = sizeof(outBuffer) / sizeof(void*);
+    outBufDesc.bufs              = (void**)&outBuffer;
+    outBufDesc.bufferIdentifiers = outBufferIds;
+    outBufDesc.bufSizes          = outBufferSize;
+    outBufDesc.bufElSizes        = outBufferElSize;
+
+    AACENC_ERROR encoderErr = AACENC_OK;
+
+    class FillWork {
+    public:
+        FillWork(uint32_t flags, C2WorkOrdinalStruct ordinal,
+                 const std::shared_ptr<C2Buffer> &buffer)
+            : mFlags(flags), mOrdinal(ordinal), mBuffer(buffer) {
+        }
+        ~FillWork() = default;
+
+        void operator()(const std::unique_ptr<C2Work> &work) {
+            work->worklets.front()->output.flags = (C2FrameData::flags_t)mFlags;
+            work->worklets.front()->output.buffers.clear();
+            work->worklets.front()->output.ordinal = mOrdinal;
+            work->workletsProcessed = 1u;
+            work->result = C2_OK;
+            if (mBuffer) {
+                work->worklets.front()->output.buffers.push_back(mBuffer);
+            }
+            ALOGV("timestamp = %lld, index = %lld, w/%s buffer",
+                  mOrdinal.timestamp.peekll(),
+                  mOrdinal.frameIndex.peekll(),
+                  mBuffer ? "" : "o");
+        }
+
+    private:
+        const uint32_t mFlags;
+        const C2WorkOrdinalStruct mOrdinal;
+        const std::shared_ptr<C2Buffer> mBuffer;
+    };
+
+    C2WorkOrdinalStruct outOrdinal = work->input.ordinal;
+
+    while (encoderErr == AACENC_OK && inargs.numInSamples > 0) {
+        if (numFrames && !block) {
+            C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+            // TODO: error handling, proper usage, etc.
+            c2_status_t err = pool->fetchLinearBlock(mOutBufferSize, usage, &block);
+            if (err != C2_OK) {
+                ALOGE("fetchLinearBlock failed : err = %d", err);
+                work->result = C2_NO_MEMORY;
+                return;
+            }
+
+            wView.reset(new C2WriteView(block->map().get()));
+            outPtr = wView->data();
+            outAvailable = wView->size();
+            --numFrames;
+        }
+
+        memset(&outargs, 0, sizeof(outargs));
+
+        outBuffer[0] = outPtr;
+        outBufferSize[0] = outAvailable;
+
+        encoderErr = aacEncEncode(mAACEncoder,
+                                  &inBufDesc,
+                                  &outBufDesc,
+                                  &inargs,
+                                  &outargs);
+
+        if (encoderErr == AACENC_OK) {
+            if (buffer) {
+                outOrdinal.frameIndex = mOutIndex++;
+                outOrdinal.timestamp = mInputTimeUs;
+                cloneAndSend(
+                        inputIndex,
+                        work,
+                        FillWork(C2FrameData::FLAG_INCOMPLETE, outOrdinal, buffer));
+                buffer.reset();
+            }
+
+            if (outargs.numOutBytes > 0) {
+                mInputSize = 0;
+                int consumed = (capacity / sizeof(int16_t)) - inargs.numInSamples
+                        + outargs.numInSamples;
+                mInputTimeUs = work->input.ordinal.timestamp
+                        + (consumed * 1000000ll / channelCount / sampleRate);
+                buffer = createLinearBuffer(block, 0, outargs.numOutBytes);
+#if defined(LOG_NDEBUG) && !LOG_NDEBUG
+                hexdump(outPtr, std::min(outargs.numOutBytes, 256));
+#endif
+                outPtr = temp;
+                outAvailable = 0;
+                block.reset();
+            } else {
+                mInputSize += outargs.numInSamples * sizeof(int16_t);
+            }
+
+            if (outargs.numInSamples > 0) {
+                inBuffer[0] = (int16_t *)inBuffer[0] + outargs.numInSamples;
+                inBufferSize[0] -= outargs.numInSamples * sizeof(int16_t);
+                inargs.numInSamples -= outargs.numInSamples;
+            }
+        }
+        ALOGV("encoderErr = %d mInputSize = %zu inargs.numInSamples = %d, mInputTimeUs = %lld",
+              encoderErr, mInputSize, inargs.numInSamples, mInputTimeUs.peekll());
+    }
+
+    if (eos && inBufferSize[0] > 0) {
+        if (numFrames && !block) {
+            C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+            // TODO: error handling, proper usage, etc.
+            c2_status_t err = pool->fetchLinearBlock(mOutBufferSize, usage, &block);
+            if (err != C2_OK) {
+                ALOGE("fetchLinearBlock failed : err = %d", err);
+                work->result = C2_NO_MEMORY;
+                return;
+            }
+
+            wView.reset(new C2WriteView(block->map().get()));
+            outPtr = wView->data();
+            outAvailable = wView->size();
+            --numFrames;
+        }
+
+        memset(&outargs, 0, sizeof(outargs));
+
+        outBuffer[0] = outPtr;
+        outBufferSize[0] = outAvailable;
+
+        // Flush
+        inargs.numInSamples = -1;
+
+        (void)aacEncEncode(mAACEncoder,
+                           &inBufDesc,
+                           &outBufDesc,
+                           &inargs,
+                           &outargs);
+    }
+
+    outOrdinal.frameIndex = mOutIndex++;
+    outOrdinal.timestamp = mInputTimeUs;
+    FillWork((C2FrameData::flags_t)(eos ? C2FrameData::FLAG_END_OF_STREAM : 0),
+             outOrdinal, buffer)(work);
+}
+
+c2_status_t C2SoftAacEnc::drain(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    switch (drainMode) {
+        case DRAIN_COMPONENT_NO_EOS:
+            [[fallthrough]];
+        case NO_DRAIN:
+            // no-op
+            return C2_OK;
+        case DRAIN_CHAIN:
+            return C2_OMITTED;
+        case DRAIN_COMPONENT_WITH_EOS:
+            break;
+        default:
+            return C2_BAD_VALUE;
+    }
+
+    (void)pool;
+    mSentCodecSpecificData = false;
+    mInputTimeSet = false;
+    mInputSize = 0u;
+    mInputTimeUs = 0;
+
+    // TODO: we don't have any pending work at this time to drain.
+    return C2_OK;
+}
+
+class C2SoftAacEncFactory : public C2ComponentFactory {
+public:
+    C2SoftAacEncFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+            GetCodec2PlatformComponentStore()->getParamReflector())) {
+    }
+
+    virtual c2_status_t createComponent(
+            c2_node_id_t id,
+            std::shared_ptr<C2Component>* const component,
+            std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+                new C2SoftAacEnc(COMPONENT_NAME,
+                                 id,
+                                 std::make_shared<C2SoftAacEnc::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+            c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
+            std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+                new SimpleInterface<C2SoftAacEnc::IntfImpl>(
+                        COMPONENT_NAME, id, std::make_shared<C2SoftAacEnc::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftAacEncFactory() override = default;
+
+private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftAacEncFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/aac/C2SoftAacEnc.h b/media/codec2/components/aac/C2SoftAacEnc.h
new file mode 100644
index 0000000..a38be19
--- /dev/null
+++ b/media/codec2/components/aac/C2SoftAacEnc.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_AAC_ENC_H_
+#define ANDROID_C2_SOFT_AAC_ENC_H_
+
+#include <atomic>
+
+#include <SimpleC2Component.h>
+
+#include "aacenc_lib.h"
+
+namespace android {
+
+class C2SoftAacEnc : public SimpleC2Component {
+public:
+    class IntfImpl;
+
+    C2SoftAacEnc(const char *name, c2_node_id_t id, const std::shared_ptr<IntfImpl> &intfImpl);
+    virtual ~C2SoftAacEnc();
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+    c2_status_t drain(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+
+private:
+    std::shared_ptr<IntfImpl> mIntf;
+
+    HANDLE_AACENCODER mAACEncoder;
+
+    UINT mNumBytesPerInputFrame;
+    UINT mOutBufferSize;
+
+    bool mSentCodecSpecificData;
+    bool mInputTimeSet;
+    size_t mInputSize;
+    c2_cntr64_t mInputTimeUs;
+
+    bool mSignalledError;
+    std::atomic_uint64_t mOutIndex;
+
+    status_t initEncoder();
+
+    status_t setAudioParams();
+
+    C2_DO_NOT_COPY(C2SoftAacEnc);
+};
+
+}  // namespace android
+
+#endif  // ANDROID_C2_SOFT_AAC_ENC_H_
diff --git a/media/codec2/components/aac/DrcPresModeWrap.cpp b/media/codec2/components/aac/DrcPresModeWrap.cpp
new file mode 100644
index 0000000..5b9aebc
--- /dev/null
+++ b/media/codec2/components/aac/DrcPresModeWrap.cpp
@@ -0,0 +1,372 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "DrcPresModeWrap.h"
+
+#include <assert.h>
+
+#define LOG_TAG "C2SoftAacDrcWrapper"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+//#define DRC_PRES_MODE_WRAP_DEBUG
+
+#define GPM_ENCODER_TARGET_LEVEL 64
+#define MAX_TARGET_LEVEL 40
+
+CDrcPresModeWrapper::CDrcPresModeWrapper()
+{
+    mDataUpdate = true;
+
+    /* Data from streamInfo. */
+    /* Initialized to the same values as in the aac decoder */
+    mStreamPRL = -1;
+    mStreamDRCPresMode = -1;
+    mStreamNrAACChan = 0;
+    mStreamNrOutChan = 0;
+
+    /* Desired values (set by user). */
+    /* Initialized to the same values as in the aac decoder */
+    mDesTarget = -1;
+    mDesAttFactor = 0;
+    mDesBoostFactor = 0;
+    mDesHeavy = 0;
+
+    mEncoderTarget = -1;
+
+    /* Values from last time. */
+    /* Initialized to the same values as the desired values */
+    mLastTarget = -1;
+    mLastAttFactor = 0;
+    mLastBoostFactor = 0;
+    mLastHeavy = 0;
+}
+
+CDrcPresModeWrapper::~CDrcPresModeWrapper()
+{
+}
+
+void
+CDrcPresModeWrapper::setDecoderHandle(const HANDLE_AACDECODER handle)
+{
+    mHandleDecoder = handle;
+}
+
+void
+CDrcPresModeWrapper::submitStreamData(CStreamInfo* pStreamInfo)
+{
+    assert(pStreamInfo);
+
+    if (mStreamPRL != pStreamInfo->drcProgRefLev) {
+        mStreamPRL = pStreamInfo->drcProgRefLev;
+        mDataUpdate = true;
+#ifdef DRC_PRES_MODE_WRAP_DEBUG
+        ALOGV("DRC presentation mode wrapper: drcProgRefLev is %d\n", mStreamPRL);
+#endif
+    }
+
+    if (mStreamDRCPresMode != pStreamInfo->drcPresMode) {
+        mStreamDRCPresMode = pStreamInfo->drcPresMode;
+        mDataUpdate = true;
+#ifdef DRC_PRES_MODE_WRAP_DEBUG
+        ALOGV("DRC presentation mode wrapper: drcPresMode is %d\n", mStreamDRCPresMode);
+#endif
+    }
+
+    if (mStreamNrAACChan != pStreamInfo->aacNumChannels) {
+        mStreamNrAACChan = pStreamInfo->aacNumChannels;
+        mDataUpdate = true;
+#ifdef DRC_PRES_MODE_WRAP_DEBUG
+        ALOGV("DRC presentation mode wrapper: aacNumChannels is %d\n", mStreamNrAACChan);
+#endif
+    }
+
+    if (mStreamNrOutChan != pStreamInfo->numChannels) {
+        mStreamNrOutChan = pStreamInfo->numChannels;
+        mDataUpdate = true;
+#ifdef DRC_PRES_MODE_WRAP_DEBUG
+        ALOGV("DRC presentation mode wrapper: numChannels is %d\n", mStreamNrOutChan);
+#endif
+    }
+
+
+
+    if (mStreamNrOutChan<mStreamNrAACChan) {
+        mIsDownmix = true;
+    } else {
+        mIsDownmix = false;
+    }
+
+    if (mIsDownmix && (mStreamNrOutChan == 1)) {
+        mIsMonoDownmix = true;
+    } else {
+        mIsMonoDownmix = false;
+    }
+
+    if (mIsDownmix && mStreamNrOutChan == 2){
+        mIsStereoDownmix = true;
+    } else {
+        mIsStereoDownmix = false;
+    }
+
+}
+
+void
+CDrcPresModeWrapper::setParam(const DRC_PRES_MODE_WRAP_PARAM param, const int value)
+{
+    switch (param) {
+    case DRC_PRES_MODE_WRAP_DESIRED_TARGET:
+        mDesTarget = value;
+        break;
+    case DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR:
+        mDesAttFactor = value;
+        break;
+    case DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR:
+        mDesBoostFactor = value;
+        break;
+    case DRC_PRES_MODE_WRAP_DESIRED_HEAVY:
+        mDesHeavy = value;
+        break;
+    case DRC_PRES_MODE_WRAP_ENCODER_TARGET:
+        mEncoderTarget = value;
+        break;
+    default:
+        break;
+    }
+    mDataUpdate = true;
+}
+
+void
+CDrcPresModeWrapper::update()
+{
+    // Get Data from Decoder
+    int progRefLevel = mStreamPRL;
+    int drcPresMode = mStreamDRCPresMode;
+
+    // by default, do as desired
+    int newTarget         = mDesTarget;
+    int newAttFactor      = mDesAttFactor;
+    int newBoostFactor    = mDesBoostFactor;
+    int newHeavy          = mDesHeavy;
+
+    if (mDataUpdate) {
+        // sanity check
+        if (mDesTarget < MAX_TARGET_LEVEL){
+            mDesTarget = MAX_TARGET_LEVEL;  // limit target level to -10 dB or below
+            newTarget = MAX_TARGET_LEVEL;
+        }
+
+        if (mEncoderTarget != -1) {
+            if (mDesTarget<124) { // if target level > -31 dB
+                if ((mIsStereoDownmix == false) && (mIsMonoDownmix == false)) {
+                    // no stereo or mono downmixing, calculated scaling of light DRC
+                    /* use as little compression as possible */
+                    newAttFactor = 0;
+                    newBoostFactor = 0;
+                    if (mDesTarget<progRefLevel) { // if target level > PRL
+                        if (mEncoderTarget < mDesTarget) { // if mEncoderTarget > target level
+                            // mEncoderTarget > target level > PRL
+                            int calcFactor;
+                            float calcFactor_norm;
+                            // 0.0f < calcFactor_norm < 1.0f
+                            calcFactor_norm = (float)(mDesTarget - progRefLevel) /
+                                    (float)(mEncoderTarget - progRefLevel);
+                            calcFactor = (int)(calcFactor_norm*127.0f); // 0 <= calcFactor < 127
+                            // calcFactor is the lower limit
+                            newAttFactor = (calcFactor>newAttFactor) ? calcFactor : newAttFactor;
+                            // new AttFactor will be always = calcFactor, as it is set to 0 before.
+                            newBoostFactor = newAttFactor;
+                        } else {
+                            /* target level > mEncoderTarget > PRL */
+                            // newTDLimiterEnable = 1;
+                            // the time domain limiter must always be active in this case.
+                            //     It is assumed that the framework activates it by default
+                            newAttFactor = 127;
+                            newBoostFactor = 127;
+                        }
+                    } else { // target level <= PRL
+                        // no restrictions required
+                        // newAttFactor = newAttFactor;
+                    }
+                } else { // downmixing
+                    // if target level > -23 dB or mono downmix
+                    if ( (mDesTarget<92) || mIsMonoDownmix ) {
+                        newHeavy = 1;
+                    } else {
+                        // we perform a downmix, so, we need at least full light DRC
+                        newAttFactor = 127;
+                    }
+                }
+            } else { // target level <= -31 dB
+                // playback -31 dB: light DRC only needed if we perform downmixing
+                if (mIsDownmix) {   // we do downmixing
+                    newAttFactor = 127;
+                }
+            }
+        }
+        else { // handle other used encoder target levels
+
+            // Sanity check: DRC presentation mode is only specified for max. 5.1 channels
+            if (mStreamNrAACChan > 6) {
+                drcPresMode = 0;
+            }
+
+            switch (drcPresMode) {
+            case 0:
+            default: // presentation mode not indicated
+            {
+
+                if (mDesTarget<124) { // if target level > -31 dB
+                    // no stereo or mono downmixing
+                    if ((mIsStereoDownmix == false) && (mIsMonoDownmix == false)) {
+                        if (mDesTarget<progRefLevel) { // if target level > PRL
+                            // newTDLimiterEnable = 1;
+                            // the time domain limiter must always be active in this case.
+                            //    It is assumed that the framework activates it by default
+                            newAttFactor = 127; // at least, use light compression
+                        } else { // target level <= PRL
+                            // no restrictions required
+                            // newAttFactor = newAttFactor;
+                        }
+                    } else { // downmixing
+                        // newTDLimiterEnable = 1;
+                        // the time domain limiter must always be active in this case.
+                        //    It is assumed that the framework activates it by default
+
+                        // if target level > -23 dB or mono downmix
+                        if ( (mDesTarget < 92) || mIsMonoDownmix ) {
+                            newHeavy = 1;
+                        } else{
+                            // we perform a downmix, so, we need at least full light DRC
+                            newAttFactor = 127;
+                        }
+                    }
+                } else { // target level <= -31 dB
+                    if (mIsDownmix) {   // we do downmixing.
+                        // newTDLimiterEnable = 1;
+                        // the time domain limiter must always be active in this case.
+                        //    It is assumed that the framework activates it by default
+                        newAttFactor = 127;
+                    }
+                }
+            }
+            break;
+
+            // Presentation mode 1 and 2 according to ETSI TS 101 154:
+            // Digital Video Broadcasting (DVB); Specification for the use of Video and Audio Coding
+            // in Broadcasting Applications based on the MPEG-2 Transport Stream,
+            // section C.5.4., "Decoding", and Table C.33
+            // ISO DRC            -> newHeavy = 0  (Use light compression, MPEG-style)
+            // Compression_value  -> newHeavy = 1  (Use heavy compression, DVB-style)
+            // scaling restricted -> newAttFactor = 127
+
+            case 1: // presentation mode 1, Light:-31/Heavy:-23
+            {
+                if (mDesTarget < 124) { // if target level > -31 dB
+                    // playback up to -23 dB
+                    newHeavy = 1;
+                } else { // target level <= -31 dB
+                    // playback -31 dB
+                    if (mIsDownmix) {   // we do downmixing.
+                        newAttFactor = 127;
+                    }
+                }
+            }
+            break;
+
+            case 2: // presentation mode 2, Light:-23/Heavy:-23
+            {
+                if (mDesTarget < 124) { // if target level > -31 dB
+                    // playback up to -23 dB
+                    if (mIsMonoDownmix) { // if mono downmix
+                        newHeavy = 1;
+                    } else {
+                        newHeavy = 0;
+                        newAttFactor = 127;
+                    }
+                } else { // target level <= -31 dB
+                    // playback -31 dB
+                    newHeavy = 0;
+                    if (mIsDownmix) {   // we do downmixing.
+                        newAttFactor = 127;
+                    }
+                }
+            }
+            break;
+
+            } // switch()
+        } // if (mEncoderTarget  == GPM_ENCODER_TARGET_LEVEL)
+
+        // sanity again
+        if (newHeavy == 1) {
+            newBoostFactor=127; // not really needed as the same would be done by the decoder anyway
+            newAttFactor = 127;
+        }
+
+        // update the decoder
+        if (newTarget != mLastTarget) {
+            aacDecoder_SetParam(mHandleDecoder, AAC_DRC_REFERENCE_LEVEL, newTarget);
+            mLastTarget = newTarget;
+#ifdef DRC_PRES_MODE_WRAP_DEBUG
+            if (newTarget != mDesTarget)
+                ALOGV("DRC presentation mode wrapper: forced target level to %d (from %d)\n", newTarget, mDesTarget);
+            else
+                ALOGV("DRC presentation mode wrapper: set target level to %d\n", newTarget);
+#endif
+        }
+
+        if (newAttFactor != mLastAttFactor) {
+            aacDecoder_SetParam(mHandleDecoder, AAC_DRC_ATTENUATION_FACTOR, newAttFactor);
+            mLastAttFactor = newAttFactor;
+#ifdef DRC_PRES_MODE_WRAP_DEBUG
+            if (newAttFactor != mDesAttFactor)
+                ALOGV("DRC presentation mode wrapper: forced attenuation factor to %d (from %d)\n", newAttFactor, mDesAttFactor);
+            else
+                ALOGV("DRC presentation mode wrapper: set attenuation factor to %d\n", newAttFactor);
+#endif
+        }
+
+        if (newBoostFactor != mLastBoostFactor) {
+            aacDecoder_SetParam(mHandleDecoder, AAC_DRC_BOOST_FACTOR, newBoostFactor);
+            mLastBoostFactor = newBoostFactor;
+#ifdef DRC_PRES_MODE_WRAP_DEBUG
+            if (newBoostFactor != mDesBoostFactor)
+                ALOGV("DRC presentation mode wrapper: forced boost factor to %d (from %d)\n",
+                        newBoostFactor, mDesBoostFactor);
+            else
+                ALOGV("DRC presentation mode wrapper: set boost factor to %d\n", newBoostFactor);
+#endif
+        }
+
+        if (newHeavy != mLastHeavy) {
+            aacDecoder_SetParam(mHandleDecoder, AAC_DRC_HEAVY_COMPRESSION, newHeavy);
+            mLastHeavy = newHeavy;
+#ifdef DRC_PRES_MODE_WRAP_DEBUG
+            if (newHeavy != mDesHeavy)
+                ALOGV("DRC presentation mode wrapper: forced heavy compression to %d (from %d)\n",
+                        newHeavy, mDesHeavy);
+            else
+                ALOGV("DRC presentation mode wrapper: set heavy compression to %d\n", newHeavy);
+#endif
+        }
+
+#ifdef DRC_PRES_MODE_WRAP_DEBUG
+        ALOGV("DRC config: tgt_lev: %3d, cut: %3d, boost: %3d, heavy: %d\n", newTarget,
+                newAttFactor, newBoostFactor, newHeavy);
+#endif
+        mDataUpdate = false;
+
+    } // if (mDataUpdate)
+}
diff --git a/media/codec2/components/aac/DrcPresModeWrap.h b/media/codec2/components/aac/DrcPresModeWrap.h
new file mode 100644
index 0000000..f0b6cf2
--- /dev/null
+++ b/media/codec2/components/aac/DrcPresModeWrap.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+#include "aacdecoder_lib.h"
+
+typedef enum
+{
+    DRC_PRES_MODE_WRAP_DESIRED_TARGET         = 0x0000,
+    DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR     = 0x0001,
+    DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR   = 0x0002,
+    DRC_PRES_MODE_WRAP_DESIRED_HEAVY          = 0x0003,
+    DRC_PRES_MODE_WRAP_ENCODER_TARGET         = 0x0004
+} DRC_PRES_MODE_WRAP_PARAM;
+
+
+class CDrcPresModeWrapper {
+public:
+    CDrcPresModeWrapper();
+    ~CDrcPresModeWrapper();
+    void setDecoderHandle(const HANDLE_AACDECODER handle);
+    void setParam(const DRC_PRES_MODE_WRAP_PARAM param, const int value);
+    void submitStreamData(CStreamInfo*);
+    void update();
+
+protected:
+    HANDLE_AACDECODER mHandleDecoder;
+    int mDesTarget;
+    int mDesAttFactor;
+    int mDesBoostFactor;
+    int mDesHeavy;
+
+    int mEncoderTarget;
+
+    int mLastTarget;
+    int mLastAttFactor;
+    int mLastBoostFactor;
+    int mLastHeavy;
+
+    SCHAR mStreamPRL;
+    SCHAR mStreamDRCPresMode;
+    INT mStreamNrAACChan;
+    INT mStreamNrOutChan;
+
+    bool mIsDownmix;
+    bool mIsMonoDownmix;
+    bool mIsStereoDownmix;
+
+    bool mDataUpdate;
+};
diff --git a/media/common_time/MODULE_LICENSE_APACHE2 b/media/codec2/components/aac/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/common_time/MODULE_LICENSE_APACHE2
rename to media/codec2/components/aac/MODULE_LICENSE_APACHE2
diff --git a/media/common_time/NOTICE b/media/codec2/components/aac/NOTICE
similarity index 100%
rename from media/common_time/NOTICE
rename to media/codec2/components/aac/NOTICE
diff --git a/media/codec2/components/aac/patent_disclaimer.txt b/media/codec2/components/aac/patent_disclaimer.txt
new file mode 100644
index 0000000..b4bf11d
--- /dev/null
+++ b/media/codec2/components/aac/patent_disclaimer.txt
@@ -0,0 +1,9 @@
+
+THIS IS NOT A GRANT OF PATENT RIGHTS.
+
+Google makes no representation or warranty that the codecs for which
+source code is made available hereunder are unencumbered by
+third-party patents.  Those intending to use this source code in
+hardware or software products are advised that implementations of
+these codecs, including in open source software or shareware, may
+require patent licenses from the relevant patent holders.
diff --git a/media/codec2/components/amr_nb_wb/Android.bp b/media/codec2/components/amr_nb_wb/Android.bp
new file mode 100644
index 0000000..ce25bc9
--- /dev/null
+++ b/media/codec2/components/amr_nb_wb/Android.bp
@@ -0,0 +1,77 @@
+cc_library_shared {
+    name: "libcodec2_soft_amrnbdec",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["C2SoftAmrDec.cpp"],
+
+    cflags: [
+        "-DAMRNB",
+    ],
+
+    static_libs: [
+        "libstagefright_amrnbdec",
+        "libstagefright_amrwbdec",
+    ],
+
+    shared_libs: [
+        "libstagefright_amrnb_common",
+    ],
+}
+
+cc_library_shared {
+    name: "libcodec2_soft_amrwbdec",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["C2SoftAmrDec.cpp"],
+
+    static_libs: [
+        "libstagefright_amrnbdec",
+        "libstagefright_amrwbdec",
+    ],
+
+    shared_libs: [
+        "libstagefright_amrnb_common",
+    ],
+}
+
+cc_library_shared {
+    name: "libcodec2_soft_amrnbenc",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["C2SoftAmrNbEnc.cpp"],
+
+    static_libs: [
+        "libstagefright_amrnbenc",
+    ],
+
+    shared_libs: [
+        "libstagefright_amrnb_common",
+    ],
+}
+
+cc_library_shared {
+    name: "libcodec2_soft_amrwbenc",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["C2SoftAmrWbEnc.cpp"],
+
+    static_libs: [
+        "libstagefright_amrwbenc",
+    ],
+
+    shared_libs: [
+        "libstagefright_enc_common",
+    ],
+}
diff --git a/media/codec2/components/amr_nb_wb/C2SoftAmrDec.cpp b/media/codec2/components/amr_nb_wb/C2SoftAmrDec.cpp
new file mode 100644
index 0000000..6578ad2
--- /dev/null
+++ b/media/codec2/components/amr_nb_wb/C2SoftAmrDec.cpp
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#ifdef AMRNB
+#define LOG_TAG "C2SoftAmrNbDec"
+#else
+#define LOG_TAG "C2SoftAmrWbDec"
+#endif
+#include <log/log.h>
+
+#include <media/stagefright/foundation/MediaDefs.h>
+
+#include <C2PlatformSupport.h>
+#include <SimpleC2Interface.h>
+
+#include "C2SoftAmrDec.h"
+#include "gsmamr_dec.h"
+#include "pvamrwbdecoder.h"
+
+namespace android {
+
+namespace {
+
+#ifdef AMRNB
+  constexpr char COMPONENT_NAME[] = "c2.android.amrnb.decoder";
+#else
+  constexpr char COMPONENT_NAME[] = "c2.android.amrwb.decoder";
+#endif
+
+}  // namespace
+
+class C2SoftAmrDec::IntfImpl : public SimpleInterface<void>::BaseParams {
+public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+        : SimpleInterface<void>::BaseParams(
+                helper,
+                COMPONENT_NAME,
+                C2Component::KIND_DECODER,
+                C2Component::DOMAIN_AUDIO,
+#ifdef AMRNB
+                MEDIA_MIMETYPE_AUDIO_AMR_NB
+#else
+                MEDIA_MIMETYPE_AUDIO_AMR_WB
+#endif
+                ) {
+        noPrivateBuffers();
+        noInputReferences();
+        noOutputReferences();
+        noInputLatency();
+        noTimeStretch();
+        setDerivedInstance(this);
+
+        addParameter(
+                DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                .withConstValue(new C2ComponentAttributesSetting(
+                    C2Component::ATTRIB_IS_TEMPORAL))
+                .build());
+
+        addParameter(
+                DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE)
+#ifdef AMRNB
+                .withDefault(new C2StreamSampleRateInfo::output(0u, 8000))
+                .withFields({C2F(mSampleRate, value).equalTo(8000)})
+#else
+                .withDefault(new C2StreamSampleRateInfo::output(0u, 16000))
+                .withFields({C2F(mSampleRate, value).equalTo(16000)})
+#endif
+                .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
+                .build());
+
+        addParameter(
+                DefineParam(mChannelCount, C2_PARAMKEY_CHANNEL_COUNT)
+                .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
+                .withFields({C2F(mChannelCount, value).equalTo(1)})
+                .withSetter((Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps))
+                .build());
+
+        addParameter(
+                DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
+#ifdef AMRNB
+                .withDefault(new C2StreamBitrateInfo::input(0u, 4750))
+                .withFields({C2F(mBitrate, value).inRange(4750, 12200)})
+#else
+                .withDefault(new C2StreamBitrateInfo::input(0u, 6600))
+                .withFields({C2F(mBitrate, value).inRange(6600, 23850)})
+#endif
+                .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
+                .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 8192))
+                .build());
+    }
+
+private:
+    std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
+    std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
+    std::shared_ptr<C2StreamBitrateInfo::input> mBitrate;
+    std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
+};
+
+C2SoftAmrDec::C2SoftAmrDec(
+        const char *name,
+        c2_node_id_t id,
+        const std::shared_ptr<IntfImpl> &intfImpl)
+    : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+      mIntf(intfImpl),
+      mAmrHandle(nullptr),
+      mDecoderBuf(nullptr),
+      mDecoderCookie(nullptr) {
+#ifdef AMRNB
+    mIsWide = false;
+#else
+    mIsWide = true;
+#endif
+}
+
+C2SoftAmrDec::~C2SoftAmrDec() {
+    (void)onRelease();
+}
+
+c2_status_t C2SoftAmrDec::onInit() {
+    status_t err = initDecoder();
+    return err == OK ? C2_OK : C2_NO_MEMORY;
+}
+
+c2_status_t C2SoftAmrDec::onStop() {
+    if (!mIsWide) {
+        Speech_Decode_Frame_reset(mAmrHandle);
+    } else {
+        pvDecoder_AmrWb_Reset(mAmrHandle, 0 /* reset_all */);
+    }
+    mSignalledError = false;
+    mSignalledOutputEos = false;
+
+    return C2_OK;
+}
+
+void C2SoftAmrDec::onReset() {
+    (void)onStop();
+}
+
+void C2SoftAmrDec::onRelease() {
+    if (!mIsWide) {
+        if (mAmrHandle) {
+            GSMDecodeFrameExit(&mAmrHandle);
+        }
+        mAmrHandle = nullptr;
+    } else {
+        if (mDecoderBuf) {
+            free(mDecoderBuf);
+        }
+        mDecoderBuf = nullptr;
+        mAmrHandle = nullptr;
+        mDecoderCookie = nullptr;
+    }
+}
+
+c2_status_t C2SoftAmrDec::onFlush_sm() {
+    return onStop();
+}
+
+status_t C2SoftAmrDec::initDecoder() {
+    if (!mIsWide) {
+        if (GSMInitDecode(&mAmrHandle, (int8_t *)"AMRNBDecoder"))
+            return UNKNOWN_ERROR;
+    } else {
+        uint32_t memReq = pvDecoder_AmrWbMemRequirements();
+        mDecoderBuf = malloc(memReq);
+        if (mDecoderBuf) {
+            pvDecoder_AmrWb_Init(&mAmrHandle, mDecoderBuf, &mDecoderCookie);
+        }
+        else {
+            return NO_MEMORY;
+        }
+    }
+    mSignalledError = false;
+    mSignalledOutputEos = false;
+
+    return OK;
+}
+
+static size_t getFrameSize(bool isWide, unsigned FM) {
+    static const size_t kFrameSizeNB[16] = {
+        12, 13, 15, 17, 19, 20, 26, 31,
+        5, 6, 5, 5, // SID
+        0, 0, 0, // future use
+        0 // no data
+    };
+    static const size_t kFrameSizeWB[16] = {
+        17, 23, 32, 36, 40, 46, 50, 58, 60,
+        5, // SID
+        0, 0, 0, 0, // future use
+        0, // speech lost
+        0 // no data
+    };
+
+    if (FM > 15 || (isWide && FM > 9 && FM < 14) || (!isWide && FM > 11 && FM < 15)) {
+        ALOGE("illegal AMR frame mode %d", FM);
+        return 0;
+    }
+    // add 1 for header byte
+    return (isWide ? kFrameSizeWB[FM] : kFrameSizeNB[FM]) + 1;
+}
+
+static status_t calculateNumFrames(const uint8 *input, size_t inSize,
+                                   std::vector<size_t> *frameSizeList, bool isWide) {
+    for (size_t k = 0; k < inSize;) {
+        int16_t FM = ((input[0] >> 3) & 0x0f);
+        size_t frameSize = getFrameSize(isWide, FM);
+        if (frameSize == 0) {
+            return UNKNOWN_ERROR;
+        }
+        if ((inSize - k) >= frameSize) {
+            input += frameSize;
+            k += frameSize;
+        }
+        else break;
+        frameSizeList->push_back(frameSize);
+    }
+    return OK;
+}
+
+void C2SoftAmrDec::process(
+        const std::unique_ptr<C2Work> &work,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    // Initialize output work
+    work->result = C2_OK;
+    work->workletsProcessed = 1u;
+    work->worklets.front()->output.flags = work->input.flags;
+
+    if (mSignalledError || mSignalledOutputEos) {
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+
+    C2ReadView rView = mDummyReadView;
+    size_t inOffset = 0u;
+    size_t inSize = 0u;
+    if (!work->input.buffers.empty()) {
+        rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
+        inSize = rView.capacity();
+        if (inSize && rView.error()) {
+            ALOGE("read view map failed %d", rView.error());
+            work->result = rView.error();
+            return;
+        }
+    }
+
+    bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
+    if (inSize == 0) {
+        work->worklets.front()->output.flags = work->input.flags;
+        work->worklets.front()->output.buffers.clear();
+        work->worklets.front()->output.ordinal = work->input.ordinal;
+        if (eos) {
+            mSignalledOutputEos = true;
+            ALOGV("signalled EOS");
+        }
+        return;
+    }
+
+    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
+          (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
+
+    std::vector<size_t> frameSizeList;
+    if (OK != calculateNumFrames(rView.data() + inOffset, inSize, &frameSizeList,
+                                 mIsWide)) {
+        work->result = C2_CORRUPTED;
+        mSignalledError = true;
+        return;
+    }
+    if (frameSizeList.empty()) {
+        ALOGE("input size smaller than expected");
+        work->result = C2_CORRUPTED;
+        mSignalledError = true;
+        return;
+    }
+
+    int16_t outSamples = mIsWide ? kNumSamplesPerFrameWB : kNumSamplesPerFrameNB;
+    size_t calOutSize = outSamples * frameSizeList.size() * sizeof(int16_t);
+    std::shared_ptr<C2LinearBlock> block;
+    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+    c2_status_t err = pool->fetchLinearBlock(calOutSize, usage, &block);
+    if (err != C2_OK) {
+        ALOGE("fetchLinearBlock for Output failed with status %d", err);
+        work->result = C2_NO_MEMORY;
+        return;
+    }
+    C2WriteView wView = block->map().get();
+    if (wView.error()) {
+        ALOGE("write view map failed %d", wView.error());
+        work->result = wView.error();
+        return;
+    }
+
+    int16_t *output = reinterpret_cast<int16_t *>(wView.data());
+    auto it = frameSizeList.begin();
+    const uint8_t *inPtr = rView.data() + inOffset;
+    size_t inPos = 0;
+    while (inPos < inSize) {
+        if (it == frameSizeList.end()) {
+            ALOGD("unexpected trailing bytes, ignoring them");
+            break;
+        }
+        uint8_t *input = const_cast<uint8_t *>(inPtr + inPos);
+        int16_t FM = ((*input >> 3) & 0x0f);
+        if (!mIsWide) {
+            int32_t numBytesRead = AMRDecode(mAmrHandle,
+                                             (Frame_Type_3GPP) FM,
+                                             input + 1, output, MIME_IETF);
+            if (static_cast<size_t>(numBytesRead + 1) != *it) {
+                ALOGE("panic, parsed size does not match decoded size");
+                work->result = C2_CORRUPTED;
+                mSignalledError = true;
+                return;
+            }
+        } else {
+            if (FM >= 9) {
+                // Produce silence instead of comfort noise and for
+                // speech lost/no data.
+                memset(output, 0, outSamples * sizeof(int16_t));
+            } else {
+                int16_t FT;
+                RX_State_wb rx_state;
+                int16_t numRecSamples;
+
+                mime_unsorting(const_cast<uint8_t *>(&input[1]),
+                               mInputSampleBuffer, &FT, &FM, 1, &rx_state);
+                pvDecoder_AmrWb(FM, mInputSampleBuffer, output, &numRecSamples,
+                                mDecoderBuf, FT, mDecoderCookie);
+                if (numRecSamples != outSamples) {
+                    ALOGE("Sample output per frame incorrect");
+                    work->result = C2_CORRUPTED;
+                    mSignalledError = true;
+                    return;
+                }
+                /* Delete the 2 LSBs (14-bit output) */
+                for (int i = 0; i < numRecSamples; ++i) {
+                    output[i] &= 0xfffC;
+                }
+            }
+        }
+        inPos += *it;
+        output += outSamples;
+        ++it;
+    }
+
+    work->worklets.front()->output.flags = work->input.flags;
+    work->worklets.front()->output.buffers.clear();
+    work->worklets.front()->output.buffers.push_back(createLinearBuffer(block));
+    work->worklets.front()->output.ordinal = work->input.ordinal;
+    if (eos) {
+        mSignalledOutputEos = true;
+        ALOGV("signalled EOS");
+    }
+}
+
+c2_status_t C2SoftAmrDec::drain(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    (void)pool;
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+    return C2_OK;
+}
+
+class C2SoftAMRDecFactory : public C2ComponentFactory {
+public:
+    C2SoftAMRDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+            GetCodec2PlatformComponentStore()->getParamReflector())) {
+    }
+
+    virtual c2_status_t createComponent(
+            c2_node_id_t id,
+            std::shared_ptr<C2Component>* const component,
+            std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+                new C2SoftAmrDec(COMPONENT_NAME, id,
+                              std::make_shared<C2SoftAmrDec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+            c2_node_id_t id,
+            std::shared_ptr<C2ComponentInterface>* const interface,
+            std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+                new SimpleInterface<C2SoftAmrDec::IntfImpl>(
+                        COMPONENT_NAME, id, std::make_shared<C2SoftAmrDec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftAMRDecFactory() override = default;
+
+private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftAMRDecFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/amr_nb_wb/C2SoftAmrDec.h b/media/codec2/components/amr_nb_wb/C2SoftAmrDec.h
new file mode 100644
index 0000000..6384450
--- /dev/null
+++ b/media/codec2/components/amr_nb_wb/C2SoftAmrDec.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_AMR_DEC_H_
+#define ANDROID_C2_SOFT_AMR_DEC_H_
+
+#include <SimpleC2Component.h>
+
+
+namespace android {
+
+struct C2SoftAmrDec : public SimpleC2Component {
+    class IntfImpl;
+
+    C2SoftAmrDec(const char *name, c2_node_id_t id,
+              const std::shared_ptr<IntfImpl> &intfImpl);
+    virtual ~C2SoftAmrDec();
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+    c2_status_t drain(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+private:
+    enum {
+        kNumSamplesPerFrameNB   = 160,
+        kNumSamplesPerFrameWB   = 320,
+    };
+
+    std::shared_ptr<IntfImpl> mIntf;
+    void *mAmrHandle;
+    void *mDecoderBuf;
+    int16_t *mDecoderCookie;
+
+    int16_t mInputSampleBuffer[477];
+
+    bool mIsWide;
+    bool mSignalledError;
+    bool mSignalledOutputEos;
+
+    status_t initDecoder();
+
+    C2_DO_NOT_COPY(C2SoftAmrDec);
+};
+
+}  // namespace android
+
+#endif  // ANDROID_C2_SOFT_AMR_DEC_H_
diff --git a/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.cpp b/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.cpp
new file mode 100644
index 0000000..e2d8cb6
--- /dev/null
+++ b/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.cpp
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftAmrNbEnc"
+#include <log/log.h>
+
+#include <media/stagefright/foundation/MediaDefs.h>
+
+#include <C2PlatformSupport.h>
+#include <SimpleC2Interface.h>
+
+#include "C2SoftAmrNbEnc.h"
+
+namespace android {
+
+namespace {
+
+constexpr char COMPONENT_NAME[] = "c2.android.amrnb.encoder";
+
+}  // namespace
+
+
+class C2SoftAmrNbEnc::IntfImpl : public SimpleInterface<void>::BaseParams {
+public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+        : SimpleInterface<void>::BaseParams(
+                helper,
+                COMPONENT_NAME,
+                C2Component::KIND_ENCODER,
+                C2Component::DOMAIN_AUDIO,
+                MEDIA_MIMETYPE_AUDIO_AMR_NB) {
+        noPrivateBuffers();
+        noInputReferences();
+        noOutputReferences();
+        noInputLatency();
+        noTimeStretch();
+        setDerivedInstance(this);
+
+        addParameter(
+                DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                .withConstValue(new C2ComponentAttributesSetting(
+                    C2Component::ATTRIB_IS_TEMPORAL))
+                .build());
+
+        addParameter(
+                DefineParam(mChannelCount, C2_PARAMKEY_CHANNEL_COUNT)
+                .withDefault(new C2StreamChannelCountInfo::input(0u, 1))
+                .withFields({C2F(mChannelCount, value).equalTo(1)})
+                .withSetter((Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps))
+                .build());
+
+        addParameter(
+            DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE)
+                .withDefault(new C2StreamSampleRateInfo::input(0u, 8000))
+                .withFields({C2F(mSampleRate, value).equalTo(8000)})
+                .withSetter(
+                    (Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
+                .build());
+
+        addParameter(
+                DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
+                .withDefault(new C2StreamBitrateInfo::output(0u, 4750))
+                .withFields({C2F(mBitrate, value).inRange(4750, 12200)})
+                .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
+                .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 8192))
+                .build());
+    }
+
+    uint32_t getSampleRate() const { return mSampleRate->value; }
+    uint32_t getChannelCount() const { return mChannelCount->value; }
+    uint32_t getBitrate() const { return mBitrate->value; }
+
+private:
+    std::shared_ptr<C2StreamSampleRateInfo::input> mSampleRate;
+    std::shared_ptr<C2StreamChannelCountInfo::input> mChannelCount;
+    std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
+    std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
+};
+
+C2SoftAmrNbEnc::C2SoftAmrNbEnc(const char* name, c2_node_id_t id,
+                               const std::shared_ptr<IntfImpl>& intfImpl)
+    : SimpleC2Component(
+          std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+      mIntf(intfImpl),
+      mEncState(nullptr),
+      mSidState(nullptr) {
+}
+
+C2SoftAmrNbEnc::~C2SoftAmrNbEnc() {
+    onRelease();
+}
+
+c2_status_t C2SoftAmrNbEnc::onInit() {
+    bool dtx_enable = false;
+
+    if (AMREncodeInit(&mEncState, &mSidState, dtx_enable) != 0)
+        return C2_CORRUPTED;
+    // TODO: get mode directly from config
+    switch(mIntf->getBitrate()) {
+        case 4750: mMode = MR475;
+            break;
+        case 5150: mMode = MR515;
+            break;
+        case 5900: mMode = MR59;
+            break;
+        case 6700: mMode = MR67;
+            break;
+        case 7400: mMode = MR74;
+            break;
+        case 7950: mMode = MR795;
+            break;
+        case 10200: mMode = MR102;
+            break;
+        case 12200: mMode = MR122;
+            break;
+        default: mMode = MR795;
+    }
+    mIsFirst = true;
+    mSignalledError = false;
+    mSignalledOutputEos = false;
+    mAnchorTimeStamp = 0;
+    mProcessedSamples = 0;
+    mFilledLen = 0;
+
+    return C2_OK;
+}
+
+void C2SoftAmrNbEnc::onRelease() {
+    if (mEncState) {
+        AMREncodeExit(&mEncState, &mSidState);
+        mEncState = mSidState = nullptr;
+    }
+}
+
+c2_status_t C2SoftAmrNbEnc::onStop() {
+    if (AMREncodeReset(mEncState, mSidState) != 0)
+        return C2_CORRUPTED;
+    mIsFirst = true;
+    mSignalledError = false;
+    mSignalledOutputEos = false;
+    mAnchorTimeStamp = 0;
+    mProcessedSamples = 0;
+    mFilledLen = 0;
+
+    return C2_OK;
+}
+
+void C2SoftAmrNbEnc::onReset() {
+    (void) onStop();
+}
+
+c2_status_t C2SoftAmrNbEnc::onFlush_sm() {
+    return onStop();
+}
+
+static void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
+    work->worklets.front()->output.flags = work->input.flags;
+    work->worklets.front()->output.buffers.clear();
+    work->worklets.front()->output.ordinal = work->input.ordinal;
+    work->workletsProcessed = 1u;
+}
+
+void C2SoftAmrNbEnc::process(
+        const std::unique_ptr<C2Work> &work,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    // Initialize output work
+    work->result = C2_OK;
+    work->workletsProcessed = 1u;
+    work->worklets.front()->output.flags = work->input.flags;
+
+    if (mSignalledError || mSignalledOutputEos) {
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+
+    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
+    size_t inOffset = 0u;
+    size_t inSize = 0u;
+    C2ReadView rView = mDummyReadView;
+    if (!work->input.buffers.empty()) {
+        rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
+        inSize = rView.capacity();
+        if (inSize && rView.error()) {
+            ALOGE("read view map failed %d", rView.error());
+            work->result = C2_CORRUPTED;
+            return;
+        }
+    }
+
+    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
+          inSize, (int)work->input.ordinal.timestamp.peeku(),
+          (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
+
+    size_t outCapacity = kNumBytesPerInputFrame;
+    outCapacity += mFilledLen + inSize;
+    std::shared_ptr<C2LinearBlock> outputBlock;
+    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+    c2_status_t err = pool->fetchLinearBlock(outCapacity, usage, &outputBlock);
+    if (err != C2_OK) {
+        ALOGE("fetchLinearBlock for Output failed with status %d", err);
+        work->result = C2_NO_MEMORY;
+        return;
+    }
+    C2WriteView wView = outputBlock->map().get();
+    if (wView.error()) {
+        ALOGE("write view map failed %d", wView.error());
+        work->result = C2_CORRUPTED;
+        return;
+    }
+    uint64_t outTimeStamp =
+        mProcessedSamples * 1000000ll / mIntf->getSampleRate();
+    size_t inPos = 0;
+    size_t outPos = 0;
+    while (inPos < inSize) {
+        const uint8_t *inPtr = rView.data() + inOffset;
+        int validSamples = mFilledLen / sizeof(int16_t);
+        if ((inPos + (kNumBytesPerInputFrame - mFilledLen)) <= inSize) {
+            memcpy(mInputFrame + validSamples, inPtr + inPos,
+                   (kNumBytesPerInputFrame - mFilledLen));
+            inPos += (kNumBytesPerInputFrame - mFilledLen);
+        } else {
+            memcpy(mInputFrame + validSamples, inPtr + inPos, (inSize - inPos));
+            mFilledLen += (inSize - inPos);
+            inPos += (inSize - inPos);
+            if (eos) {
+                validSamples = mFilledLen / sizeof(int16_t);
+                memset(mInputFrame + validSamples, 0, (kNumBytesPerInputFrame - mFilledLen));
+            } else break;
+
+        }
+        Frame_Type_3GPP frameType;
+        int numEncBytes = AMREncode(mEncState, mSidState, mMode, mInputFrame,
+                                    wView.data() + outPos, &frameType,
+                                    AMR_TX_WMF);
+        if (numEncBytes < 0 || numEncBytes > ((int)outCapacity - (int)outPos)) {
+            ALOGE("encodeFrame call failed, state [%d %zu %zu]", numEncBytes, outPos, outCapacity);
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+        // Convert header byte from WMF to IETF format.
+        if (numEncBytes > 0)
+            wView.data()[outPos] = ((wView.data()[outPos] << 3) | 4) & 0x7c;
+        outPos += numEncBytes;
+        mProcessedSamples += kNumSamplesPerFrame;
+        mFilledLen = 0;
+    }
+    ALOGV("causal sample size %d", mFilledLen);
+    if (mIsFirst && outPos != 0) {
+        mIsFirst = false;
+        mAnchorTimeStamp = work->input.ordinal.timestamp.peekull();
+    }
+    fillEmptyWork(work);
+    if (outPos != 0) {
+        work->worklets.front()->output.buffers.push_back(
+                createLinearBuffer(std::move(outputBlock), 0, outPos));
+        work->worklets.front()->output.ordinal.timestamp = mAnchorTimeStamp + outTimeStamp;
+
+    }
+    if (eos) {
+        mSignalledOutputEos = true;
+        ALOGV("signalled EOS");
+        if (mFilledLen) ALOGV("Discarding trailing %d bytes", mFilledLen);
+    }
+}
+
+c2_status_t C2SoftAmrNbEnc::drain(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    (void) pool;
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+
+    onFlush_sm();
+    return C2_OK;
+}
+
+class C2SoftAmrNbEncFactory : public C2ComponentFactory {
+public:
+    C2SoftAmrNbEncFactory()
+        : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+              GetCodec2PlatformComponentStore()->getParamReflector())) {}
+
+    virtual c2_status_t createComponent(
+            c2_node_id_t id,
+            std::shared_ptr<C2Component>* const component,
+            std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+            new C2SoftAmrNbEnc(
+                COMPONENT_NAME, id,
+                std::make_shared<C2SoftAmrNbEnc::IntfImpl>(mHelper)),
+            deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+            c2_node_id_t id,
+            std::shared_ptr<C2ComponentInterface>* const interface,
+            std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+            new SimpleInterface<C2SoftAmrNbEnc::IntfImpl>(
+                COMPONENT_NAME, id,
+                std::make_shared<C2SoftAmrNbEnc::IntfImpl>(mHelper)),
+            deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftAmrNbEncFactory() override = default;
+
+private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftAmrNbEncFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.h b/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.h
new file mode 100644
index 0000000..6ab14db
--- /dev/null
+++ b/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_AMR_NB_ENC_H_
+#define ANDROID_C2_SOFT_AMR_NB_ENC_H_
+
+#include <SimpleC2Component.h>
+
+#include "gsmamr_enc.h"
+
+namespace android {
+
+class C2SoftAmrNbEnc : public SimpleC2Component {
+   public:
+    class IntfImpl;
+    C2SoftAmrNbEnc(const char* name, c2_node_id_t id,
+                   const std::shared_ptr<IntfImpl>& intfImpl);
+    virtual ~C2SoftAmrNbEnc();
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+    c2_status_t drain(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+
+private:
+    std::shared_ptr<IntfImpl> mIntf;
+    static const int32_t kNumSamplesPerFrame = L_FRAME;
+    static const int32_t kNumBytesPerInputFrame = kNumSamplesPerFrame * sizeof(int16_t);
+
+    void *mEncState;
+    void *mSidState;
+    Mode mMode;
+    bool mIsFirst;
+    bool mSignalledError;
+    bool mSignalledOutputEos;
+    uint64_t mAnchorTimeStamp;
+    uint64_t mProcessedSamples;
+    int32_t mFilledLen;
+    int16_t mInputFrame[kNumSamplesPerFrame];
+
+    C2_DO_NOT_COPY(C2SoftAmrNbEnc);
+};
+
+}  // namespace android
+
+#endif  // ANDROID_C2_SOFT_AMR_NB_ENC_H_
diff --git a/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.cpp b/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.cpp
new file mode 100644
index 0000000..84ae4b7
--- /dev/null
+++ b/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.cpp
@@ -0,0 +1,422 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftAmrWbEnc"
+#include <log/log.h>
+
+#include <media/stagefright/foundation/MediaDefs.h>
+
+#include <C2Debug.h>
+#include <C2PlatformSupport.h>
+#include <SimpleC2Interface.h>
+
+#include "C2SoftAmrWbEnc.h"
+#include "cmnMemory.h"
+
+namespace android {
+
+namespace {
+
+constexpr char COMPONENT_NAME[] = "c2.android.amrwb.encoder";
+
+}  // namespace
+
+class C2SoftAmrWbEnc::IntfImpl : public SimpleInterface<void>::BaseParams {
+public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+        : SimpleInterface<void>::BaseParams(
+                helper,
+                COMPONENT_NAME,
+                C2Component::KIND_ENCODER,
+                C2Component::DOMAIN_AUDIO,
+                MEDIA_MIMETYPE_AUDIO_AMR_WB) {
+        noPrivateBuffers();
+        noInputReferences();
+        noOutputReferences();
+        noInputLatency();
+        noTimeStretch();
+        setDerivedInstance(this);
+
+        addParameter(
+                DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                .withConstValue(new C2ComponentAttributesSetting(
+                    C2Component::ATTRIB_IS_TEMPORAL))
+                .build());
+
+        addParameter(
+                DefineParam(mChannelCount, C2_PARAMKEY_CHANNEL_COUNT)
+                .withDefault(new C2StreamChannelCountInfo::input(0u, 1))
+                .withFields({C2F(mChannelCount, value).equalTo(1)})
+                .withSetter((Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps))
+                .build());
+
+        addParameter(
+            DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE)
+                .withDefault(new C2StreamSampleRateInfo::input(0u, 16000))
+                .withFields({C2F(mSampleRate, value).equalTo(16000)})
+                .withSetter(
+                    (Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
+                .build());
+
+        addParameter(
+                DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
+                .withDefault(new C2StreamBitrateInfo::output(0u, 6600))
+                .withFields({C2F(mBitrate, value).inRange(6600, 23850)})
+                .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
+                .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 8192))
+                .build());
+    }
+
+    uint32_t getSampleRate() const { return mSampleRate->value; }
+    uint32_t getChannelCount() const { return mChannelCount->value; }
+    uint32_t getBitrate() const { return mBitrate->value; }
+
+private:
+    std::shared_ptr<C2StreamSampleRateInfo::input> mSampleRate;
+    std::shared_ptr<C2StreamChannelCountInfo::input> mChannelCount;
+    std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
+    std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
+};
+
+C2SoftAmrWbEnc::C2SoftAmrWbEnc(const char* name, c2_node_id_t id,
+                               const std::shared_ptr<IntfImpl>& intfImpl)
+    : SimpleC2Component(
+          std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+      mIntf(intfImpl),
+      mEncoderHandle(nullptr),
+      mApiHandle(nullptr),
+      mMemOperator(nullptr) {
+}
+
+C2SoftAmrWbEnc::~C2SoftAmrWbEnc() {
+    onRelease();
+}
+
+c2_status_t C2SoftAmrWbEnc::onInit() {
+    // TODO: get mode directly from config
+    switch(mIntf->getBitrate()) {
+        case 6600: mMode = VOAMRWB_MD66;
+            break;
+        case 8850: mMode = VOAMRWB_MD885;
+            break;
+        case 12650: mMode = VOAMRWB_MD1265;
+            break;
+        case 14250: mMode = VOAMRWB_MD1425;
+            break;
+        case 15850: mMode = VOAMRWB_MD1585;
+            break;
+        case 18250: mMode = VOAMRWB_MD1825;
+            break;
+        case 19850: mMode = VOAMRWB_MD1985;
+            break;
+        case 23050: mMode = VOAMRWB_MD2305;
+            break;
+        case 23850: mMode = VOAMRWB_MD2385;
+            break;
+        default: mMode = VOAMRWB_MD2305;
+    }
+    status_t err = initEncoder();
+    mIsFirst = true;
+    mSignalledError = false;
+    mSignalledOutputEos = false;
+    mAnchorTimeStamp = 0;
+    mProcessedSamples = 0;
+    mFilledLen = 0;
+
+    return err == OK ? C2_OK : C2_NO_MEMORY;
+}
+
+void C2SoftAmrWbEnc::onRelease() {
+    if (mEncoderHandle) {
+        CHECK_EQ((VO_U32)VO_ERR_NONE, mApiHandle->Uninit(mEncoderHandle));
+        mEncoderHandle = nullptr;
+    }
+    if (mApiHandle) {
+        delete mApiHandle;
+        mApiHandle = nullptr;
+    }
+    if (mMemOperator) {
+        delete mMemOperator;
+        mMemOperator = nullptr;
+    }
+}
+
+c2_status_t C2SoftAmrWbEnc::onStop() {
+    for (int i = 0; i < kNumSamplesPerFrame; i++) {
+        mInputFrame[i] = 0x0008; /* EHF_MASK */
+    }
+    uint8_t outBuffer[kNumBytesPerInputFrame];
+    (void) encodeInput(outBuffer, kNumBytesPerInputFrame);
+    mIsFirst = true;
+    mSignalledError = false;
+    mSignalledOutputEos = false;
+    mAnchorTimeStamp = 0;
+    mProcessedSamples = 0;
+    mFilledLen = 0;
+
+    return C2_OK;
+}
+
+void C2SoftAmrWbEnc::onReset() {
+    (void) onStop();
+}
+
+c2_status_t C2SoftAmrWbEnc::onFlush_sm() {
+    return onStop();
+}
+
+status_t C2SoftAmrWbEnc::initEncoder() {
+    mApiHandle = new VO_AUDIO_CODECAPI;
+    if (!mApiHandle) return NO_MEMORY;
+
+    if (VO_ERR_NONE != voGetAMRWBEncAPI(mApiHandle)) {
+        ALOGE("Failed to get api handle");
+        return UNKNOWN_ERROR;
+    }
+
+    mMemOperator = new VO_MEM_OPERATOR;
+    if (!mMemOperator) return NO_MEMORY;
+
+    mMemOperator->Alloc = cmnMemAlloc;
+    mMemOperator->Copy = cmnMemCopy;
+    mMemOperator->Free = cmnMemFree;
+    mMemOperator->Set = cmnMemSet;
+    mMemOperator->Check = cmnMemCheck;
+
+    VO_CODEC_INIT_USERDATA userData;
+    memset(&userData, 0, sizeof(userData));
+    userData.memflag = VO_IMF_USERMEMOPERATOR;
+    userData.memData = (VO_PTR) mMemOperator;
+
+    if (VO_ERR_NONE != mApiHandle->Init(
+                &mEncoderHandle, VO_AUDIO_CodingAMRWB, &userData)) {
+        ALOGE("Failed to init AMRWB encoder");
+        return UNKNOWN_ERROR;
+    }
+
+    VOAMRWBFRAMETYPE type = VOAMRWB_RFC3267;
+    if (VO_ERR_NONE != mApiHandle->SetParam(
+                mEncoderHandle, VO_PID_AMRWB_FRAMETYPE, &type)) {
+        ALOGE("Failed to set AMRWB encoder frame type to %d", type);
+        return UNKNOWN_ERROR;
+    }
+
+    if (VO_ERR_NONE !=
+            mApiHandle->SetParam(
+                    mEncoderHandle, VO_PID_AMRWB_MODE,  &mMode)) {
+        ALOGE("Failed to set AMRWB encoder mode to %d", mMode);
+        return UNKNOWN_ERROR;
+    }
+
+    return OK;
+}
+
+int C2SoftAmrWbEnc::encodeInput(uint8_t *buffer, uint32_t length) {
+    VO_CODECBUFFER inputData;
+    memset(&inputData, 0, sizeof(inputData));
+    inputData.Buffer = (unsigned char *) mInputFrame;
+    inputData.Length = kNumBytesPerInputFrame;
+
+    CHECK_EQ((VO_U32)VO_ERR_NONE,
+             mApiHandle->SetInputData(mEncoderHandle, &inputData));
+
+    VO_AUDIO_OUTPUTINFO outputInfo;
+    memset(&outputInfo, 0, sizeof(outputInfo));
+    VO_CODECBUFFER outputData;
+    memset(&outputData, 0, sizeof(outputData));
+    outputData.Buffer = buffer;
+    outputData.Length = length;
+    VO_U32 ret = mApiHandle->GetOutputData(
+            mEncoderHandle, &outputData, &outputInfo);
+    if (ret != VO_ERR_NONE && ret != VO_ERR_INPUT_BUFFER_SMALL) {
+        ALOGD("encountered error during encode call");
+        return -1;
+    }
+    return outputData.Length;
+}
+
+static void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
+    work->worklets.front()->output.flags = work->input.flags;
+    work->worklets.front()->output.buffers.clear();
+    work->worklets.front()->output.ordinal = work->input.ordinal;
+    work->workletsProcessed = 1u;
+}
+
+void C2SoftAmrWbEnc::process(
+        const std::unique_ptr<C2Work> &work,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    // Initialize output work
+    work->result = C2_OK;
+    work->workletsProcessed = 1u;
+    work->worklets.front()->output.flags = work->input.flags;
+
+    if (mSignalledError || mSignalledOutputEos) {
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+
+    size_t inOffset = 0u;
+    size_t inSize = 0u;
+    C2ReadView rView = mDummyReadView;
+    if (!work->input.buffers.empty()) {
+        rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
+        inSize = rView.capacity();
+        if (inSize && rView.error()) {
+            ALOGE("read view map failed %d", rView.error());
+            work->result = rView.error();
+            return;
+        }
+    }
+    bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
+
+    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
+          inSize, (int)work->input.ordinal.timestamp.peeku(),
+          (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
+
+    size_t outCapacity = kNumBytesPerInputFrame;
+    outCapacity += mFilledLen + inSize;
+    std::shared_ptr<C2LinearBlock> outputBlock;
+    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+    c2_status_t err = pool->fetchLinearBlock(outCapacity, usage, &outputBlock);
+    if (err != C2_OK) {
+        ALOGE("fetchLinearBlock for Output failed with status %d", err);
+        work->result = C2_NO_MEMORY;
+        return;
+    }
+    C2WriteView wView = outputBlock->map().get();
+    if (wView.error()) {
+        ALOGE("write view map failed %d", wView.error());
+        work->result = wView.error();
+        return;
+    }
+    uint64_t outTimeStamp =
+        mProcessedSamples * 1000000ll / mIntf->getSampleRate();
+    size_t inPos = 0;
+    size_t outPos = 0;
+    while (inPos < inSize) {
+        const uint8_t *inPtr = rView.data() + inOffset;
+        int validSamples = mFilledLen / sizeof(int16_t);
+        if ((inPos + (kNumBytesPerInputFrame - mFilledLen)) <= inSize) {
+            memcpy(mInputFrame + validSamples, inPtr + inPos,
+                   (kNumBytesPerInputFrame - mFilledLen));
+            inPos += (kNumBytesPerInputFrame - mFilledLen);
+        } else {
+            memcpy(mInputFrame + validSamples, inPtr + inPos, (inSize - inPos));
+            mFilledLen += (inSize - inPos);
+            inPos += (inSize - inPos);
+            if (eos) {
+                validSamples = mFilledLen / sizeof(int16_t);
+                memset(mInputFrame + validSamples, 0, (kNumBytesPerInputFrame - mFilledLen));
+            } else break;
+        }
+        int numEncBytes = encodeInput((wView.data() + outPos), outCapacity - outPos);
+        if (numEncBytes < 0) {
+            ALOGE("encodeFrame call failed, state [%d %zu %zu]", numEncBytes, outPos, outCapacity);
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+        outPos += numEncBytes;
+        mProcessedSamples += kNumSamplesPerFrame;
+        mFilledLen = 0;
+    }
+    ALOGV("causal sample size %d", mFilledLen);
+    if (mIsFirst && outPos != 0) {
+        mIsFirst = false;
+        mAnchorTimeStamp = work->input.ordinal.timestamp.peekull();
+    }
+    fillEmptyWork(work);
+    if (outPos != 0) {
+        work->worklets.front()->output.buffers.push_back(
+                createLinearBuffer(std::move(outputBlock), 0, outPos));
+        work->worklets.front()->output.ordinal.timestamp = mAnchorTimeStamp + outTimeStamp;
+    }
+    if (eos) {
+        mSignalledOutputEos = true;
+        ALOGV("signalled EOS");
+        if (mFilledLen) ALOGV("Discarding trailing %d bytes", mFilledLen);
+    }
+}
+
+c2_status_t C2SoftAmrWbEnc::drain(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    (void) pool;
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+
+    onFlush_sm();
+    return C2_OK;
+}
+
+class C2SoftAmrWbEncFactory : public C2ComponentFactory {
+public:
+    C2SoftAmrWbEncFactory()
+        : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+              GetCodec2PlatformComponentStore()->getParamReflector())) {}
+
+    virtual c2_status_t createComponent(
+            c2_node_id_t id,
+            std::shared_ptr<C2Component>* const component,
+            std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+            new C2SoftAmrWbEnc(
+                COMPONENT_NAME, id,
+                std::make_shared<C2SoftAmrWbEnc::IntfImpl>(mHelper)),
+            deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+            c2_node_id_t id,
+            std::shared_ptr<C2ComponentInterface>* const interface,
+            std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+            new SimpleInterface<C2SoftAmrWbEnc::IntfImpl>(
+                COMPONENT_NAME, id,
+                std::make_shared<C2SoftAmrWbEnc::IntfImpl>(mHelper)),
+            deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftAmrWbEncFactory() override = default;
+
+private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftAmrWbEncFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.h b/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.h
new file mode 100644
index 0000000..0cc9e9f
--- /dev/null
+++ b/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_AMR_WB_ENC_H_
+#define ANDROID_C2_SOFT_AMR_WB_ENC_H_
+
+#include <SimpleC2Component.h>
+
+#include "voAMRWB.h"
+
+namespace android {
+
+class C2SoftAmrWbEnc : public SimpleC2Component {
+public:
+    class IntfImpl;
+    C2SoftAmrWbEnc(const char* name, c2_node_id_t id,
+                   const std::shared_ptr<IntfImpl>& intfImpl);
+    virtual ~C2SoftAmrWbEnc();
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+    c2_status_t drain(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+
+private:
+    std::shared_ptr<IntfImpl> mIntf;
+    static const int32_t kNumSamplesPerFrame = 320;
+    static const int32_t kNumBytesPerInputFrame = kNumSamplesPerFrame * sizeof(int16_t);
+
+    void *mEncoderHandle;
+    VO_AUDIO_CODECAPI *mApiHandle;
+    VO_MEM_OPERATOR *mMemOperator;
+    VOAMRWBMODE mMode;
+    bool mIsFirst;
+    bool mSignalledError;
+    bool mSignalledOutputEos;
+    uint64_t mAnchorTimeStamp;
+    uint64_t mProcessedSamples;
+    int32_t mFilledLen;
+    int16_t mInputFrame[kNumSamplesPerFrame];
+
+    status_t initEncoder();
+    int encodeInput(uint8_t *buffer, uint32_t length);
+
+    C2_DO_NOT_COPY(C2SoftAmrWbEnc);
+};
+
+}  // namespace android
+
+#endif  // ANDROID_C2_SOFT_AMR_WB_ENC_H_
diff --git a/media/common_time/MODULE_LICENSE_APACHE2 b/media/codec2/components/amr_nb_wb/MODULE_LICENSE_APACHE2
similarity index 100%
copy from media/common_time/MODULE_LICENSE_APACHE2
copy to media/codec2/components/amr_nb_wb/MODULE_LICENSE_APACHE2
diff --git a/media/common_time/NOTICE b/media/codec2/components/amr_nb_wb/NOTICE
similarity index 100%
copy from media/common_time/NOTICE
copy to media/codec2/components/amr_nb_wb/NOTICE
diff --git a/media/codec2/components/amr_nb_wb/patent_disclaimer.txt b/media/codec2/components/amr_nb_wb/patent_disclaimer.txt
new file mode 100644
index 0000000..b4bf11d
--- /dev/null
+++ b/media/codec2/components/amr_nb_wb/patent_disclaimer.txt
@@ -0,0 +1,9 @@
+
+THIS IS NOT A GRANT OF PATENT RIGHTS.
+
+Google makes no representation or warranty that the codecs for which
+source code is made available hereunder are unencumbered by
+third-party patents.  Those intending to use this source code in
+hardware or software products are advised that implementations of
+these codecs, including in open source software or shareware, may
+require patent licenses from the relevant patent holders.
diff --git a/media/codec2/components/aom/Android.bp b/media/codec2/components/aom/Android.bp
new file mode 100644
index 0000000..0fabf5c
--- /dev/null
+++ b/media/codec2/components/aom/Android.bp
@@ -0,0 +1,14 @@
+cc_library_shared {
+    name: "libcodec2_soft_av1dec",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["C2SoftAomDec.cpp"],
+    static_libs: ["libaom"],
+
+    include_dirs: [
+        "external/libaom/",
+    ],
+}
diff --git a/media/codec2/components/aom/C2SoftAomDec.cpp b/media/codec2/components/aom/C2SoftAomDec.cpp
new file mode 100644
index 0000000..769895c
--- /dev/null
+++ b/media/codec2/components/aom/C2SoftAomDec.cpp
@@ -0,0 +1,810 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftAomDec"
+#include <log/log.h>
+
+#include <media/stagefright/foundation/AUtils.h>
+#include <media/stagefright/foundation/MediaDefs.h>
+
+#include <C2Debug.h>
+#include <C2PlatformSupport.h>
+#include <SimpleC2Interface.h>
+
+#include "C2SoftAomDec.h"
+
+namespace android {
+
+constexpr char COMPONENT_NAME[] = "c2.android.av1.decoder";
+
+class C2SoftAomDec::IntfImpl : public SimpleInterface<void>::BaseParams {
+  public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper>& helper)
+        : SimpleInterface<void>::BaseParams(
+              helper, COMPONENT_NAME, C2Component::KIND_DECODER,
+              C2Component::DOMAIN_VIDEO, MEDIA_MIMETYPE_VIDEO_AV1) {
+        noPrivateBuffers();  // TODO: account for our buffers here
+        noInputReferences();
+        noOutputReferences();
+        noInputLatency();
+        noTimeStretch();
+
+        addParameter(DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                         .withConstValue(new C2ComponentAttributesSetting(
+                             C2Component::ATTRIB_IS_TEMPORAL))
+                         .build());
+
+        addParameter(
+            DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
+                .withDefault(new C2StreamPictureSizeInfo::output(0u, 320, 240))
+                .withFields({
+                    C2F(mSize, width).inRange(2, 2048, 2),
+                    C2F(mSize, height).inRange(2, 2048, 2),
+                })
+                .withSetter(SizeSetter)
+                .build());
+
+        addParameter(
+                DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
+                .withDefault(new C2StreamProfileLevelInfo::input(0u,
+                        C2Config::PROFILE_AV1_0, C2Config::LEVEL_AV1_2_1))
+                .withFields({
+                    C2F(mProfileLevel, profile).oneOf({
+                            C2Config::PROFILE_AV1_0,
+                            C2Config::PROFILE_AV1_1}),
+                    C2F(mProfileLevel, level).oneOf({
+                            C2Config::LEVEL_AV1_2,
+                            C2Config::LEVEL_AV1_2_1,
+                            C2Config::LEVEL_AV1_2_2,
+                            C2Config::LEVEL_AV1_3,
+                            C2Config::LEVEL_AV1_3_1,
+                            C2Config::LEVEL_AV1_3_2,
+                    })
+                })
+                .withSetter(ProfileLevelSetter, mSize)
+                .build());
+
+        mHdr10PlusInfoInput = C2StreamHdr10PlusInfo::input::AllocShared(0);
+        addParameter(
+                DefineParam(mHdr10PlusInfoInput, C2_PARAMKEY_INPUT_HDR10_PLUS_INFO)
+                .withDefault(mHdr10PlusInfoInput)
+                .withFields({
+                    C2F(mHdr10PlusInfoInput, m.value).any(),
+                })
+                .withSetter(Hdr10PlusInfoInputSetter)
+                .build());
+
+        mHdr10PlusInfoOutput = C2StreamHdr10PlusInfo::output::AllocShared(0);
+        addParameter(
+                DefineParam(mHdr10PlusInfoOutput, C2_PARAMKEY_OUTPUT_HDR10_PLUS_INFO)
+                .withDefault(mHdr10PlusInfoOutput)
+                .withFields({
+                    C2F(mHdr10PlusInfoOutput, m.value).any(),
+                })
+                .withSetter(Hdr10PlusInfoOutputSetter)
+                .build());
+
+        addParameter(DefineParam(mMaxSize, C2_PARAMKEY_MAX_PICTURE_SIZE)
+                         .withDefault(new C2StreamMaxPictureSizeTuning::output(
+                             0u, 320, 240))
+                         .withFields({
+                             C2F(mSize, width).inRange(2, 2048, 2),
+                             C2F(mSize, height).inRange(2, 2048, 2),
+                         })
+                         .withSetter(MaxPictureSizeSetter, mSize)
+                         .build());
+
+        addParameter(
+            DefineParam(mMaxInputSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
+                .withDefault(
+                    new C2StreamMaxBufferSizeInfo::input(0u, 320 * 240 * 3 / 4))
+                .withFields({
+                    C2F(mMaxInputSize, value).any(),
+                })
+                .calculatedAs(MaxInputSizeSetter, mMaxSize)
+                .build());
+
+        C2ChromaOffsetStruct locations[1] = {
+            C2ChromaOffsetStruct::ITU_YUV_420_0()};
+        std::shared_ptr<C2StreamColorInfo::output> defaultColorInfo =
+            C2StreamColorInfo::output::AllocShared(1u, 0u, 8u /* bitDepth */,
+                                                   C2Color::YUV_420);
+        memcpy(defaultColorInfo->m.locations, locations, sizeof(locations));
+
+        defaultColorInfo = C2StreamColorInfo::output::AllocShared(
+            {C2ChromaOffsetStruct::ITU_YUV_420_0()}, 0u, 8u /* bitDepth */,
+            C2Color::YUV_420);
+        helper->addStructDescriptors<C2ChromaOffsetStruct>();
+
+        addParameter(DefineParam(mColorInfo, C2_PARAMKEY_CODED_COLOR_INFO)
+                         .withConstValue(defaultColorInfo)
+                         .build());
+
+        addParameter(
+                DefineParam(mDefaultColorAspects, C2_PARAMKEY_DEFAULT_COLOR_ASPECTS)
+                .withDefault(new C2StreamColorAspectsTuning::output(
+                        0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
+                        C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+                .withFields({
+                    C2F(mDefaultColorAspects, range).inRange(
+                                C2Color::RANGE_UNSPECIFIED,     C2Color::RANGE_OTHER),
+                    C2F(mDefaultColorAspects, primaries).inRange(
+                                C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
+                    C2F(mDefaultColorAspects, transfer).inRange(
+                                C2Color::TRANSFER_UNSPECIFIED,  C2Color::TRANSFER_OTHER),
+                    C2F(mDefaultColorAspects, matrix).inRange(
+                                C2Color::MATRIX_UNSPECIFIED,    C2Color::MATRIX_OTHER)
+                })
+                .withSetter(DefaultColorAspectsSetter)
+                .build());
+
+        // TODO: support more formats?
+        addParameter(DefineParam(mPixelFormat, C2_PARAMKEY_PIXEL_FORMAT)
+                         .withConstValue(new C2StreamPixelFormatInfo::output(
+                             0u, HAL_PIXEL_FORMAT_YCBCR_420_888))
+                         .build());
+    }
+
+    static C2R SizeSetter(bool mayBlock,
+                          const C2P<C2StreamPictureSizeInfo::output>& oldMe,
+                          C2P<C2StreamPictureSizeInfo::output>& me) {
+        (void)mayBlock;
+        C2R res = C2R::Ok();
+        if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
+            res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
+            me.set().width = oldMe.v.width;
+        }
+        if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
+            res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
+            me.set().height = oldMe.v.height;
+        }
+        return res;
+    }
+
+    static C2R MaxPictureSizeSetter(
+        bool mayBlock, C2P<C2StreamMaxPictureSizeTuning::output>& me,
+        const C2P<C2StreamPictureSizeInfo::output>& size) {
+        (void)mayBlock;
+        // TODO: get max width/height from the size's field helpers vs.
+        // hardcoding
+        me.set().width = c2_min(c2_max(me.v.width, size.v.width), 4096u);
+        me.set().height = c2_min(c2_max(me.v.height, size.v.height), 4096u);
+        return C2R::Ok();
+    }
+
+    static C2R MaxInputSizeSetter(
+        bool mayBlock, C2P<C2StreamMaxBufferSizeInfo::input>& me,
+        const C2P<C2StreamMaxPictureSizeTuning::output>& maxSize) {
+        (void)mayBlock;
+        // assume compression ratio of 2
+        me.set().value = (((maxSize.v.width + 63) / 64) *
+                          ((maxSize.v.height + 63) / 64) * 3072);
+        return C2R::Ok();
+    }
+    static C2R DefaultColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsTuning::output> &me) {
+        (void)mayBlock;
+        if (me.v.range > C2Color::RANGE_OTHER) {
+            me.set().range = C2Color::RANGE_OTHER;
+        }
+        if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
+            me.set().primaries = C2Color::PRIMARIES_OTHER;
+        }
+        if (me.v.transfer > C2Color::TRANSFER_OTHER) {
+            me.set().transfer = C2Color::TRANSFER_OTHER;
+        }
+        if (me.v.matrix > C2Color::MATRIX_OTHER) {
+            me.set().matrix = C2Color::MATRIX_OTHER;
+        }
+        return C2R::Ok();
+    }
+
+    static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me,
+                                  const C2P<C2StreamPictureSizeInfo::output> &size) {
+        (void)mayBlock;
+        (void)size;
+        (void)me;  // TODO: validate
+        return C2R::Ok();
+    }
+    std::shared_ptr<C2StreamColorAspectsTuning::output> getDefaultColorAspects_l() {
+        return mDefaultColorAspects;
+    }
+
+    static C2R Hdr10PlusInfoInputSetter(bool mayBlock, C2P<C2StreamHdr10PlusInfo::input> &me) {
+        (void)mayBlock;
+        (void)me;  // TODO: validate
+        return C2R::Ok();
+    }
+
+    static C2R Hdr10PlusInfoOutputSetter(bool mayBlock, C2P<C2StreamHdr10PlusInfo::output> &me) {
+        (void)mayBlock;
+        (void)me;  // TODO: validate
+        return C2R::Ok();
+    }
+
+  private:
+    std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
+    std::shared_ptr<C2StreamPictureSizeInfo::output> mSize;
+    std::shared_ptr<C2StreamMaxPictureSizeTuning::output> mMaxSize;
+    std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mMaxInputSize;
+    std::shared_ptr<C2StreamColorInfo::output> mColorInfo;
+    std::shared_ptr<C2StreamPixelFormatInfo::output> mPixelFormat;
+    std::shared_ptr<C2StreamColorAspectsTuning::output> mDefaultColorAspects;
+    std::shared_ptr<C2StreamHdr10PlusInfo::input> mHdr10PlusInfoInput;
+    std::shared_ptr<C2StreamHdr10PlusInfo::output> mHdr10PlusInfoOutput;
+};
+
+C2SoftAomDec::C2SoftAomDec(const char* name, c2_node_id_t id,
+                           const std::shared_ptr<IntfImpl>& intfImpl)
+    : SimpleC2Component(
+          std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+      mIntf(intfImpl),
+      mCodecCtx(nullptr){
+
+    GENERATE_FILE_NAMES();
+    CREATE_DUMP_FILE(mInFile);
+    CREATE_DUMP_FILE(mOutFile);
+
+    gettimeofday(&mTimeStart, nullptr);
+    gettimeofday(&mTimeEnd, nullptr);
+}
+
+C2SoftAomDec::~C2SoftAomDec() {
+    onRelease();
+}
+
+c2_status_t C2SoftAomDec::onInit() {
+    status_t err = initDecoder();
+    return err == OK ? C2_OK : C2_CORRUPTED;
+}
+
+c2_status_t C2SoftAomDec::onStop() {
+    mSignalledError = false;
+    mSignalledOutputEos = false;
+    return C2_OK;
+}
+
+void C2SoftAomDec::onReset() {
+    (void)onStop();
+    c2_status_t err = onFlush_sm();
+    if (err != C2_OK) {
+        ALOGW("Failed to flush decoder. Try to hard reset decoder.");
+        destroyDecoder();
+        (void)initDecoder();
+    }
+}
+
+void C2SoftAomDec::onRelease() {
+    destroyDecoder();
+}
+
+c2_status_t C2SoftAomDec::onFlush_sm() {
+    if (aom_codec_decode(mCodecCtx, nullptr, 0, nullptr)) {
+        ALOGE("Failed to flush av1 decoder.");
+        return C2_CORRUPTED;
+    }
+
+    aom_codec_iter_t iter = nullptr;
+    while (aom_codec_get_frame(mCodecCtx, &iter)) {
+    }
+
+    mSignalledError = false;
+    mSignalledOutputEos = false;
+
+    return C2_OK;
+}
+
+static int GetCPUCoreCount() {
+    int cpuCoreCount = 1;
+#if defined(_SC_NPROCESSORS_ONLN)
+    cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
+#else
+    // _SC_NPROC_ONLN must be defined...
+    cpuCoreCount = sysconf(_SC_NPROC_ONLN);
+#endif
+    CHECK(cpuCoreCount >= 1);
+    ALOGV("Number of CPU cores: %d", cpuCoreCount);
+    return cpuCoreCount;
+}
+
+status_t C2SoftAomDec::initDecoder() {
+    mSignalledError = false;
+    mSignalledOutputEos = false;
+    if (!mCodecCtx) {
+        mCodecCtx = new aom_codec_ctx_t;
+    }
+
+    if (!mCodecCtx) {
+        ALOGE("mCodecCtx is null");
+        return NO_MEMORY;
+    }
+
+    aom_codec_dec_cfg_t cfg;
+    memset(&cfg, 0, sizeof(aom_codec_dec_cfg_t));
+    cfg.threads = GetCPUCoreCount();
+    cfg.allow_lowbitdepth = 1;
+
+    aom_codec_flags_t flags;
+    memset(&flags, 0, sizeof(aom_codec_flags_t));
+
+    aom_codec_err_t err;
+    if ((err = aom_codec_dec_init(mCodecCtx, aom_codec_av1_dx(), &cfg, 0))) {
+        ALOGE("av1 decoder failed to initialize. (%d)", err);
+        return UNKNOWN_ERROR;
+    }
+
+    return OK;
+}
+
+status_t C2SoftAomDec::destroyDecoder() {
+    if (mCodecCtx) {
+        aom_codec_destroy(mCodecCtx);
+        delete mCodecCtx;
+        mCodecCtx = nullptr;
+    }
+    return OK;
+}
+
+void fillEmptyWork(const std::unique_ptr<C2Work>& work) {
+    uint32_t flags = 0;
+    if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
+        flags |= C2FrameData::FLAG_END_OF_STREAM;
+        ALOGV("signalling eos");
+    }
+    work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
+    work->worklets.front()->output.buffers.clear();
+    work->worklets.front()->output.ordinal = work->input.ordinal;
+    work->workletsProcessed = 1u;
+}
+
+void C2SoftAomDec::finishWork(uint64_t index,
+                              const std::unique_ptr<C2Work>& work,
+                              const std::shared_ptr<C2GraphicBlock>& block) {
+    std::shared_ptr<C2Buffer> buffer =
+        createGraphicBuffer(block, C2Rect(mWidth, mHeight));
+    auto fillWork = [buffer, index, intf = this->mIntf](
+            const std::unique_ptr<C2Work>& work) {
+        uint32_t flags = 0;
+        if ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) &&
+            (c2_cntr64_t(index) == work->input.ordinal.frameIndex)) {
+            flags |= C2FrameData::FLAG_END_OF_STREAM;
+            ALOGV("signalling eos");
+        }
+        work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
+        work->worklets.front()->output.buffers.clear();
+        work->worklets.front()->output.buffers.push_back(buffer);
+        work->worklets.front()->output.ordinal = work->input.ordinal;
+        work->workletsProcessed = 1u;
+
+        for (const std::unique_ptr<C2Param> &param: work->input.configUpdate) {
+            if (param) {
+                C2StreamHdr10PlusInfo::input *hdr10PlusInfo =
+                        C2StreamHdr10PlusInfo::input::From(param.get());
+
+                if (hdr10PlusInfo != nullptr) {
+                    std::vector<std::unique_ptr<C2SettingResult>> failures;
+                    std::unique_ptr<C2Param> outParam = C2Param::CopyAsStream(
+                            *param.get(), true /*output*/, param->stream());
+                    c2_status_t err = intf->config(
+                            { outParam.get() }, C2_MAY_BLOCK, &failures);
+                    if (err == C2_OK) {
+                        work->worklets.front()->output.configUpdate.push_back(
+                                C2Param::Copy(*outParam.get()));
+                    } else {
+                        ALOGE("finishWork: Config update size failed");
+                    }
+                    break;
+                }
+            }
+        }
+    };
+    if (work && c2_cntr64_t(index) == work->input.ordinal.frameIndex) {
+        fillWork(work);
+    } else {
+        finish(index, fillWork);
+    }
+}
+
+void C2SoftAomDec::process(const std::unique_ptr<C2Work>& work,
+                           const std::shared_ptr<C2BlockPool>& pool) {
+    work->result = C2_OK;
+    work->workletsProcessed = 0u;
+    work->worklets.front()->output.configUpdate.clear();
+    work->worklets.front()->output.flags = work->input.flags;
+    if (mSignalledError || mSignalledOutputEos) {
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+
+    size_t inOffset = 0u;
+    size_t inSize = 0u;
+    C2ReadView rView = mDummyReadView;
+    if (!work->input.buffers.empty()) {
+        rView =
+            work->input.buffers[0]->data().linearBlocks().front().map().get();
+        inSize = rView.capacity();
+        if (inSize && rView.error()) {
+            ALOGE("read view map failed %d", rView.error());
+            work->result = C2_CORRUPTED;
+            return;
+        }
+    }
+
+    bool codecConfig =
+        ((work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0);
+    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
+
+    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
+          inSize, (int)work->input.ordinal.timestamp.peeku(),
+          (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
+
+    if (codecConfig) {
+        fillEmptyWork(work);
+        return;
+    }
+
+    int64_t frameIndex = work->input.ordinal.frameIndex.peekll();
+    if (inSize) {
+        uint8_t* bitstream = const_cast<uint8_t*>(rView.data() + inOffset);
+        int32_t decodeTime = 0;
+        int32_t delay = 0;
+
+        DUMP_TO_FILE(mOutFile, bitstream, inSize);
+        GETTIME(&mTimeStart, nullptr);
+        TIME_DIFF(mTimeEnd, mTimeStart, delay);
+
+        aom_codec_err_t err =
+            aom_codec_decode(mCodecCtx, bitstream, inSize, &frameIndex);
+
+        GETTIME(&mTimeEnd, nullptr);
+        TIME_DIFF(mTimeStart, mTimeEnd, decodeTime);
+        ALOGV("decodeTime=%4d delay=%4d\n", decodeTime, delay);
+
+        if (err != AOM_CODEC_OK) {
+            ALOGE("av1 decoder failed to decode frame err: %d", err);
+            work->result = C2_CORRUPTED;
+            work->workletsProcessed = 1u;
+            mSignalledError = true;
+            return;
+        }
+
+    } else {
+        if (aom_codec_decode(mCodecCtx, nullptr, 0, nullptr)) {
+            ALOGE("Failed to flush av1 decoder.");
+            work->result = C2_CORRUPTED;
+            work->workletsProcessed = 1u;
+            mSignalledError = true;
+            return;
+        }
+    }
+
+    (void)outputBuffer(pool, work);
+
+    if (eos) {
+        drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
+        mSignalledOutputEos = true;
+    } else if (!inSize) {
+        fillEmptyWork(work);
+    }
+}
+
+static void copyOutputBufferToYuvPlanarFrame(
+        uint8_t *dst, const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV,
+        size_t srcYStride, size_t srcUStride, size_t srcVStride,
+        size_t dstYStride, size_t dstUVStride,
+        uint32_t width, uint32_t height) {
+    uint8_t* dstStart = dst;
+
+    for (size_t i = 0; i < height; ++i) {
+        memcpy(dst, srcY, width);
+        srcY += srcYStride;
+        dst += dstYStride;
+    }
+
+    dst = dstStart + dstYStride * height;
+    for (size_t i = 0; i < height / 2; ++i) {
+         memcpy(dst, srcV, width / 2);
+        srcV += srcVStride;
+        dst += dstUVStride;
+    }
+
+    dst = dstStart + (dstYStride * height) + (dstUVStride * height / 2);
+    for (size_t i = 0; i < height / 2; ++i) {
+         memcpy(dst, srcU, width / 2);
+        srcU += srcUStride;
+        dst += dstUVStride;
+    }
+}
+
+static void convertYUV420Planar16ToY410(uint32_t *dst,
+        const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV,
+        size_t srcYStride, size_t srcUStride, size_t srcVStride,
+        size_t dstStride, size_t width, size_t height) {
+
+    // Converting two lines at a time, slightly faster
+    for (size_t y = 0; y < height; y += 2) {
+        uint32_t *dstTop = (uint32_t *) dst;
+        uint32_t *dstBot = (uint32_t *) (dst + dstStride);
+        uint16_t *ySrcTop = (uint16_t*) srcY;
+        uint16_t *ySrcBot = (uint16_t*) (srcY + srcYStride);
+        uint16_t *uSrc = (uint16_t*) srcU;
+        uint16_t *vSrc = (uint16_t*) srcV;
+
+        uint32_t u01, v01, y01, y23, y45, y67, uv0, uv1;
+        size_t x = 0;
+        for (; x < width - 3; x += 4) {
+
+            u01 = *((uint32_t*)uSrc); uSrc += 2;
+            v01 = *((uint32_t*)vSrc); vSrc += 2;
+
+            y01 = *((uint32_t*)ySrcTop); ySrcTop += 2;
+            y23 = *((uint32_t*)ySrcTop); ySrcTop += 2;
+            y45 = *((uint32_t*)ySrcBot); ySrcBot += 2;
+            y67 = *((uint32_t*)ySrcBot); ySrcBot += 2;
+
+            uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20);
+            uv1 = (u01 >> 16) | ((v01 >> 16) << 20);
+
+            *dstTop++ = 3 << 30 | ((y01 & 0x3FF) << 10) | uv0;
+            *dstTop++ = 3 << 30 | ((y01 >> 16) << 10) | uv0;
+            *dstTop++ = 3 << 30 | ((y23 & 0x3FF) << 10) | uv1;
+            *dstTop++ = 3 << 30 | ((y23 >> 16) << 10) | uv1;
+
+            *dstBot++ = 3 << 30 | ((y45 & 0x3FF) << 10) | uv0;
+            *dstBot++ = 3 << 30 | ((y45 >> 16) << 10) | uv0;
+            *dstBot++ = 3 << 30 | ((y67 & 0x3FF) << 10) | uv1;
+            *dstBot++ = 3 << 30 | ((y67 >> 16) << 10) | uv1;
+        }
+
+        // There should be at most 2 more pixels to process. Note that we don't
+        // need to consider odd case as the buffer is always aligned to even.
+        if (x < width) {
+            u01 = *uSrc;
+            v01 = *vSrc;
+            y01 = *((uint32_t*)ySrcTop);
+            y45 = *((uint32_t*)ySrcBot);
+            uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20);
+            *dstTop++ = ((y01 & 0x3FF) << 10) | uv0;
+            *dstTop++ = ((y01 >> 16) << 10) | uv0;
+            *dstBot++ = ((y45 & 0x3FF) << 10) | uv0;
+            *dstBot++ = ((y45 >> 16) << 10) | uv0;
+        }
+
+        srcY += srcYStride * 2;
+        srcU += srcUStride;
+        srcV += srcVStride;
+        dst += dstStride * 2;
+    }
+
+    return;
+}
+
+static void convertYUV420Planar16ToYUV420Planar(uint8_t *dst,
+        const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV,
+        size_t srcYStride, size_t srcUStride, size_t srcVStride,
+        size_t dstYStride, size_t dstUVStride, size_t width, size_t height) {
+
+    uint8_t *dstY = (uint8_t *)dst;
+    size_t dstYSize = dstYStride * height;
+    size_t dstUVSize = dstUVStride * height / 2;
+    uint8_t *dstV = dstY + dstYSize;
+    uint8_t *dstU = dstV + dstUVSize;
+
+    for (size_t y = 0; y < height; ++y) {
+        for (size_t x = 0; x < width; ++x) {
+            dstY[x] = (uint8_t)(srcY[x] >> 2);
+        }
+
+        srcY += srcYStride;
+        dstY += dstYStride;
+    }
+
+    for (size_t y = 0; y < (height + 1) / 2; ++y) {
+        for (size_t x = 0; x < (width + 1) / 2; ++x) {
+            dstU[x] = (uint8_t)(srcU[x] >> 2);
+            dstV[x] = (uint8_t)(srcV[x] >> 2);
+        }
+
+        srcU += srcUStride;
+        srcV += srcVStride;
+        dstU += dstUVStride;
+        dstV += dstUVStride;
+    }
+    return;
+}
+bool C2SoftAomDec::outputBuffer(
+        const std::shared_ptr<C2BlockPool> &pool,
+        const std::unique_ptr<C2Work> &work)
+{
+    if (!(work && pool)) return false;
+
+    aom_codec_iter_t iter = nullptr;
+    aom_image_t* img = aom_codec_get_frame(mCodecCtx, &iter);
+
+    if (!img) return false;
+
+    if (img->d_w != mWidth || img->d_h != mHeight) {
+        mWidth = img->d_w;
+        mHeight = img->d_h;
+
+        C2StreamPictureSizeInfo::output size(0u, mWidth, mHeight);
+        std::vector<std::unique_ptr<C2SettingResult>> failures;
+        c2_status_t err = mIntf->config({&size}, C2_MAY_BLOCK, &failures);
+        if (err == C2_OK) {
+            work->worklets.front()->output.configUpdate.push_back(
+                C2Param::Copy(size));
+        } else {
+            ALOGE("Config update size failed");
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            work->workletsProcessed = 1u;
+            return false;
+        }
+    }
+
+    CHECK(img->fmt == AOM_IMG_FMT_I420 || img->fmt == AOM_IMG_FMT_I42016);
+
+    std::shared_ptr<C2GraphicBlock> block;
+    uint32_t format = HAL_PIXEL_FORMAT_YV12;
+    if (img->fmt == AOM_IMG_FMT_I42016) {
+        IntfImpl::Lock lock = mIntf->lock();
+        std::shared_ptr<C2StreamColorAspectsTuning::output> defaultColorAspects = mIntf->getDefaultColorAspects_l();
+
+        if (defaultColorAspects->primaries == C2Color::PRIMARIES_BT2020 &&
+            defaultColorAspects->matrix == C2Color::MATRIX_BT2020 &&
+            defaultColorAspects->transfer == C2Color::TRANSFER_ST2084) {
+            format = HAL_PIXEL_FORMAT_RGBA_1010102;
+        }
+    }
+    C2MemoryUsage usage = {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE};
+
+    c2_status_t err = pool->fetchGraphicBlock(align(mWidth, 16), mHeight,
+                                              format, usage, &block);
+
+    if (err != C2_OK) {
+        ALOGE("fetchGraphicBlock for Output failed with status %d", err);
+        work->result = err;
+        return false;
+    }
+
+    C2GraphicView wView = block->map().get();
+
+    if (wView.error()) {
+        ALOGE("graphic view map failed %d", wView.error());
+        work->result = C2_CORRUPTED;
+        return false;
+    }
+
+    ALOGV("provided (%dx%d) required (%dx%d), out frameindex %d",
+          block->width(), block->height(), mWidth, mHeight,
+          (int)*(int64_t*)img->user_priv);
+
+    uint8_t* dst = const_cast<uint8_t*>(wView.data()[C2PlanarLayout::PLANE_Y]);
+    size_t srcYStride = img->stride[AOM_PLANE_Y];
+    size_t srcUStride = img->stride[AOM_PLANE_U];
+    size_t srcVStride = img->stride[AOM_PLANE_V];
+    C2PlanarLayout layout = wView.layout();
+    size_t dstYStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
+    size_t dstUVStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
+
+    if (img->fmt == AOM_IMG_FMT_I42016) {
+        const uint16_t *srcY = (const uint16_t *)img->planes[AOM_PLANE_Y];
+        const uint16_t *srcU = (const uint16_t *)img->planes[AOM_PLANE_U];
+        const uint16_t *srcV = (const uint16_t *)img->planes[AOM_PLANE_V];
+
+        if (format == HAL_PIXEL_FORMAT_RGBA_1010102) {
+            convertYUV420Planar16ToY410((uint32_t *)dst, srcY, srcU, srcV, srcYStride / 2,
+                                    srcUStride / 2, srcVStride / 2,
+                                    dstYStride / sizeof(uint32_t),
+                                    mWidth, mHeight);
+        } else {
+            convertYUV420Planar16ToYUV420Planar(dst, srcY, srcU, srcV, srcYStride / 2,
+                                    srcUStride / 2, srcVStride / 2,
+                                    dstYStride, dstUVStride,
+                                    mWidth, mHeight);
+        }
+    } else {
+        const uint8_t *srcY = (const uint8_t *)img->planes[AOM_PLANE_Y];
+        const uint8_t *srcU = (const uint8_t *)img->planes[AOM_PLANE_U];
+        const uint8_t *srcV = (const uint8_t *)img->planes[AOM_PLANE_V];
+        copyOutputBufferToYuvPlanarFrame(
+                dst, srcY, srcU, srcV,
+                srcYStride, srcUStride, srcVStride,
+                dstYStride, dstUVStride,
+                mWidth, mHeight);
+    }
+    finishWork(*(int64_t*)img->user_priv, work, std::move(block));
+    block = nullptr;
+    return true;
+}
+
+c2_status_t C2SoftAomDec::drainInternal(
+    uint32_t drainMode, const std::shared_ptr<C2BlockPool>& pool,
+    const std::unique_ptr<C2Work>& work) {
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+
+    if (aom_codec_decode(mCodecCtx, nullptr, 0, nullptr)) {
+        ALOGE("Failed to flush av1 decoder.");
+        return C2_CORRUPTED;
+    }
+
+    while ((outputBuffer(pool, work))) {
+    }
+
+    if (drainMode == DRAIN_COMPONENT_WITH_EOS && work &&
+        work->workletsProcessed == 0u) {
+        fillEmptyWork(work);
+    }
+
+    return C2_OK;
+}
+
+c2_status_t C2SoftAomDec::drain(uint32_t drainMode,
+                                const std::shared_ptr<C2BlockPool>& pool) {
+    return drainInternal(drainMode, pool, nullptr);
+}
+
+class C2SoftAomFactory : public C2ComponentFactory {
+   public:
+    C2SoftAomFactory()
+        : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+              GetCodec2PlatformComponentStore()->getParamReflector())) {}
+
+    virtual c2_status_t createComponent(
+        c2_node_id_t id, std::shared_ptr<C2Component>* const component,
+        std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+            new C2SoftAomDec(COMPONENT_NAME, id,
+                             std::make_shared<C2SoftAomDec::IntfImpl>(mHelper)),
+            deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+        c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
+        std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+            new SimpleInterface<C2SoftAomDec::IntfImpl>(
+                COMPONENT_NAME, id,
+                std::make_shared<C2SoftAomDec::IntfImpl>(mHelper)),
+            deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftAomFactory() override = default;
+
+   private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftAomFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/aom/C2SoftAomDec.h b/media/codec2/components/aom/C2SoftAomDec.h
new file mode 100644
index 0000000..4c82647
--- /dev/null
+++ b/media/codec2/components/aom/C2SoftAomDec.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_AV1_DEC_H_
+#define ANDROID_C2_SOFT_AV1_DEC_H_
+
+#include <SimpleC2Component.h>
+#include "aom/aom_decoder.h"
+#include "aom/aomdx.h"
+
+#define GETTIME(a, b) gettimeofday(a, b);
+#define TIME_DIFF(start, end, diff)     \
+    diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \
+            ((end).tv_usec - (start).tv_usec);
+
+namespace android {
+
+struct C2SoftAomDec : public SimpleC2Component {
+    class IntfImpl;
+
+    C2SoftAomDec(const char* name, c2_node_id_t id,
+                 const std::shared_ptr<IntfImpl>& intfImpl);
+    virtual ~C2SoftAomDec();
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(const std::unique_ptr<C2Work>& work,
+                 const std::shared_ptr<C2BlockPool>& pool) override;
+    c2_status_t drain(uint32_t drainMode,
+                      const std::shared_ptr<C2BlockPool>& pool) override;
+
+   private:
+    std::shared_ptr<IntfImpl> mIntf;
+    aom_codec_ctx_t* mCodecCtx;
+
+    uint32_t mWidth;
+    uint32_t mHeight;
+    bool mSignalledOutputEos;
+    bool mSignalledError;
+
+    #ifdef FILE_DUMP_ENABLE
+    char mInFile[200];
+    char mOutFile[200];
+    #endif /* FILE_DUMP_ENABLE */
+
+    struct timeval mTimeStart;   // Time at the start of decode()
+    struct timeval mTimeEnd;     // Time at the end of decode()
+
+    status_t initDecoder();
+    status_t destroyDecoder();
+    void finishWork(uint64_t index, const std::unique_ptr<C2Work>& work,
+                    const std::shared_ptr<C2GraphicBlock>& block);
+    bool outputBuffer(const std::shared_ptr<C2BlockPool>& pool,
+                      const std::unique_ptr<C2Work>& work);
+
+    c2_status_t drainInternal(uint32_t drainMode,
+                              const std::shared_ptr<C2BlockPool>& pool,
+                              const std::unique_ptr<C2Work>& work);
+
+    C2_DO_NOT_COPY(C2SoftAomDec);
+};
+
+#ifdef FILE_DUMP_ENABLE
+
+#define INPUT_DUMP_PATH "/data/local/tmp/temp/av1"
+#define INPUT_DUMP_EXT "webm"
+#define OUTPUT_DUMP_PATH "/data/local/tmp/temp/av1"
+#define OUTPUT_DUMP_EXT "av1"
+#define GENERATE_FILE_NAMES()                                                 \
+    {                                                                         \
+        GETTIME(&mTimeStart, NULL);                                           \
+        strcpy(mInFile, "");                                                  \
+        ALOGD("GENERATE_FILE_NAMES");                                         \
+        sprintf(mInFile, "%s_%ld.%ld.%s", INPUT_DUMP_PATH, mTimeStart.tv_sec, \
+                mTimeStart.tv_usec, INPUT_DUMP_EXT);                          \
+        strcpy(mOutFile, "");                                                 \
+        sprintf(mOutFile, "%s_%ld.%ld.%s", OUTPUT_DUMP_PATH,                  \
+                mTimeStart.tv_sec, mTimeStart.tv_usec, OUTPUT_DUMP_EXT);      \
+    }
+
+#define CREATE_DUMP_FILE(m_filename)                     \
+    {                                                    \
+        FILE* fp = fopen(m_filename, "wb");              \
+        if (fp != NULL) {                                \
+            ALOGD("Opened file %s", m_filename);         \
+            fclose(fp);                                  \
+        } else {                                         \
+            ALOGD("Could not open file %s", m_filename); \
+        }                                                \
+    }
+#define DUMP_TO_FILE(m_filename, m_buf, m_size)              \
+    {                                                        \
+        FILE* fp = fopen(m_filename, "ab");                  \
+        if (fp != NULL && m_buf != NULL) {                   \
+            int i;                                           \
+            ALOGD("Dump to file!");                          \
+            i = fwrite(m_buf, 1, m_size, fp);                \
+            if (i != (int)m_size) {                          \
+                ALOGD("Error in fwrite, returned %d", i);    \
+                perror("Error in write to file");            \
+            }                                                \
+            fclose(fp);                                      \
+        } else {                                             \
+            ALOGD("Could not write to file %s", m_filename); \
+            if (fp != NULL) fclose(fp);                      \
+        }                                                    \
+    }
+#else /* FILE_DUMP_ENABLE */
+#define INPUT_DUMP_PATH
+#define INPUT_DUMP_EXT
+#define OUTPUT_DUMP_PATH
+#define OUTPUT_DUMP_EXT
+#define GENERATE_FILE_NAMES()
+#define CREATE_DUMP_FILE(m_filename)
+#define DUMP_TO_FILE(m_filename, m_buf, m_size)
+#endif /* FILE_DUMP_ENABLE */
+
+}  // namespace android
+
+#endif  // ANDROID_C2_SOFT_AV1_DEC_H_
diff --git a/media/codec2/components/avc/Android.bp b/media/codec2/components/avc/Android.bp
new file mode 100644
index 0000000..4021444
--- /dev/null
+++ b/media/codec2/components/avc/Android.bp
@@ -0,0 +1,37 @@
+cc_library_shared {
+    name: "libcodec2_soft_avcdec",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_signed-defaults",
+   ],
+
+    static_libs: ["libavcdec"],
+
+    srcs: ["C2SoftAvcDec.cpp"],
+
+    include_dirs: [
+        "external/libavc/decoder",
+        "external/libavc/common",
+    ],
+}
+
+cc_library_shared {
+    name: "libcodec2_soft_avcenc",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_signed-defaults",
+   ],
+
+    static_libs: ["libavcenc"],
+
+    srcs: ["C2SoftAvcEnc.cpp"],
+
+    include_dirs: [
+        "external/libavc/encoder",
+        "external/libavc/common",
+    ],
+
+    cflags: [
+        "-Wno-unused-variable",
+    ],
+}
diff --git a/media/codec2/components/avc/C2SoftAvcDec.cpp b/media/codec2/components/avc/C2SoftAvcDec.cpp
new file mode 100644
index 0000000..3f015b4
--- /dev/null
+++ b/media/codec2/components/avc/C2SoftAvcDec.cpp
@@ -0,0 +1,1033 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftAvcDec"
+#include <log/log.h>
+
+#include <media/stagefright/foundation/MediaDefs.h>
+
+#include <C2Debug.h>
+#include <C2PlatformSupport.h>
+#include <Codec2Mapper.h>
+#include <SimpleC2Interface.h>
+
+#include "C2SoftAvcDec.h"
+#include "ih264d.h"
+
+namespace android {
+
+namespace {
+
+constexpr char COMPONENT_NAME[] = "c2.android.avc.decoder";
+
+}  // namespace
+
+class C2SoftAvcDec::IntfImpl : public SimpleInterface<void>::BaseParams {
+public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+        : SimpleInterface<void>::BaseParams(
+                helper,
+                COMPONENT_NAME,
+                C2Component::KIND_DECODER,
+                C2Component::DOMAIN_VIDEO,
+                MEDIA_MIMETYPE_VIDEO_AVC) {
+        noPrivateBuffers(); // TODO: account for our buffers here
+        noInputReferences();
+        noOutputReferences();
+        noInputLatency();
+        noTimeStretch();
+
+        // TODO: Proper support for reorder depth.
+        addParameter(
+                DefineParam(mActualOutputDelay, C2_PARAMKEY_OUTPUT_DELAY)
+                .withConstValue(new C2PortActualDelayTuning::output(8u))
+                .build());
+
+        // TODO: output latency and reordering
+
+        addParameter(
+                DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                .withConstValue(new C2ComponentAttributesSetting(C2Component::ATTRIB_IS_TEMPORAL))
+                .build());
+
+        // coded and output picture size is the same for this codec
+        addParameter(
+                DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
+                .withDefault(new C2StreamPictureSizeInfo::output(0u, 320, 240))
+                .withFields({
+                    C2F(mSize, width).inRange(2, 4080, 2),
+                    C2F(mSize, height).inRange(2, 4080, 2),
+                })
+                .withSetter(SizeSetter)
+                .build());
+
+        addParameter(
+                DefineParam(mMaxSize, C2_PARAMKEY_MAX_PICTURE_SIZE)
+                .withDefault(new C2StreamMaxPictureSizeTuning::output(0u, 320, 240))
+                .withFields({
+                    C2F(mSize, width).inRange(2, 4080, 2),
+                    C2F(mSize, height).inRange(2, 4080, 2),
+                })
+                .withSetter(MaxPictureSizeSetter, mSize)
+                .build());
+
+        addParameter(
+                DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
+                .withDefault(new C2StreamProfileLevelInfo::input(0u,
+                        C2Config::PROFILE_AVC_CONSTRAINED_BASELINE, C2Config::LEVEL_AVC_5_2))
+                .withFields({
+                    C2F(mProfileLevel, profile).oneOf({
+                            C2Config::PROFILE_AVC_CONSTRAINED_BASELINE,
+                            C2Config::PROFILE_AVC_BASELINE,
+                            C2Config::PROFILE_AVC_MAIN,
+                            C2Config::PROFILE_AVC_CONSTRAINED_HIGH,
+                            C2Config::PROFILE_AVC_PROGRESSIVE_HIGH,
+                            C2Config::PROFILE_AVC_HIGH}),
+                    C2F(mProfileLevel, level).oneOf({
+                            C2Config::LEVEL_AVC_1, C2Config::LEVEL_AVC_1B, C2Config::LEVEL_AVC_1_1,
+                            C2Config::LEVEL_AVC_1_2, C2Config::LEVEL_AVC_1_3,
+                            C2Config::LEVEL_AVC_2, C2Config::LEVEL_AVC_2_1, C2Config::LEVEL_AVC_2_2,
+                            C2Config::LEVEL_AVC_3, C2Config::LEVEL_AVC_3_1, C2Config::LEVEL_AVC_3_2,
+                            C2Config::LEVEL_AVC_4, C2Config::LEVEL_AVC_4_1, C2Config::LEVEL_AVC_4_2,
+                            C2Config::LEVEL_AVC_5, C2Config::LEVEL_AVC_5_1, C2Config::LEVEL_AVC_5_2
+                    })
+                })
+                .withSetter(ProfileLevelSetter, mSize)
+                .build());
+
+        addParameter(
+                DefineParam(mMaxInputSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
+                .withDefault(new C2StreamMaxBufferSizeInfo::input(0u, 320 * 240 * 3 / 4))
+                .withFields({
+                    C2F(mMaxInputSize, value).any(),
+                })
+                .calculatedAs(MaxInputSizeSetter, mMaxSize)
+                .build());
+
+        C2ChromaOffsetStruct locations[1] = { C2ChromaOffsetStruct::ITU_YUV_420_0() };
+        std::shared_ptr<C2StreamColorInfo::output> defaultColorInfo =
+            C2StreamColorInfo::output::AllocShared(
+                    1u, 0u, 8u /* bitDepth */, C2Color::YUV_420);
+        memcpy(defaultColorInfo->m.locations, locations, sizeof(locations));
+
+        defaultColorInfo =
+            C2StreamColorInfo::output::AllocShared(
+                    { C2ChromaOffsetStruct::ITU_YUV_420_0() },
+                    0u, 8u /* bitDepth */, C2Color::YUV_420);
+        helper->addStructDescriptors<C2ChromaOffsetStruct>();
+
+        addParameter(
+                DefineParam(mColorInfo, C2_PARAMKEY_CODED_COLOR_INFO)
+                .withConstValue(defaultColorInfo)
+                .build());
+
+        addParameter(
+                DefineParam(mDefaultColorAspects, C2_PARAMKEY_DEFAULT_COLOR_ASPECTS)
+                .withDefault(new C2StreamColorAspectsTuning::output(
+                        0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
+                        C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+                .withFields({
+                    C2F(mDefaultColorAspects, range).inRange(
+                                C2Color::RANGE_UNSPECIFIED,     C2Color::RANGE_OTHER),
+                    C2F(mDefaultColorAspects, primaries).inRange(
+                                C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
+                    C2F(mDefaultColorAspects, transfer).inRange(
+                                C2Color::TRANSFER_UNSPECIFIED,  C2Color::TRANSFER_OTHER),
+                    C2F(mDefaultColorAspects, matrix).inRange(
+                                C2Color::MATRIX_UNSPECIFIED,    C2Color::MATRIX_OTHER)
+                })
+                .withSetter(DefaultColorAspectsSetter)
+                .build());
+
+        addParameter(
+                DefineParam(mCodedColorAspects, C2_PARAMKEY_VUI_COLOR_ASPECTS)
+                .withDefault(new C2StreamColorAspectsInfo::input(
+                        0u, C2Color::RANGE_LIMITED, C2Color::PRIMARIES_UNSPECIFIED,
+                        C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+                .withFields({
+                    C2F(mCodedColorAspects, range).inRange(
+                                C2Color::RANGE_UNSPECIFIED,     C2Color::RANGE_OTHER),
+                    C2F(mCodedColorAspects, primaries).inRange(
+                                C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
+                    C2F(mCodedColorAspects, transfer).inRange(
+                                C2Color::TRANSFER_UNSPECIFIED,  C2Color::TRANSFER_OTHER),
+                    C2F(mCodedColorAspects, matrix).inRange(
+                                C2Color::MATRIX_UNSPECIFIED,    C2Color::MATRIX_OTHER)
+                })
+                .withSetter(CodedColorAspectsSetter)
+                .build());
+
+        addParameter(
+                DefineParam(mColorAspects, C2_PARAMKEY_COLOR_ASPECTS)
+                .withDefault(new C2StreamColorAspectsInfo::output(
+                        0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
+                        C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+                .withFields({
+                    C2F(mColorAspects, range).inRange(
+                                C2Color::RANGE_UNSPECIFIED,     C2Color::RANGE_OTHER),
+                    C2F(mColorAspects, primaries).inRange(
+                                C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
+                    C2F(mColorAspects, transfer).inRange(
+                                C2Color::TRANSFER_UNSPECIFIED,  C2Color::TRANSFER_OTHER),
+                    C2F(mColorAspects, matrix).inRange(
+                                C2Color::MATRIX_UNSPECIFIED,    C2Color::MATRIX_OTHER)
+                })
+                .withSetter(ColorAspectsSetter, mDefaultColorAspects, mCodedColorAspects)
+                .build());
+
+        // TODO: support more formats?
+        addParameter(
+                DefineParam(mPixelFormat, C2_PARAMKEY_PIXEL_FORMAT)
+                .withConstValue(new C2StreamPixelFormatInfo::output(
+                                     0u, HAL_PIXEL_FORMAT_YCBCR_420_888))
+                .build());
+    }
+
+    static C2R SizeSetter(bool mayBlock, const C2P<C2StreamPictureSizeInfo::output> &oldMe,
+                          C2P<C2StreamPictureSizeInfo::output> &me) {
+        (void)mayBlock;
+        C2R res = C2R::Ok();
+        if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
+            res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
+            me.set().width = oldMe.v.width;
+        }
+        if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
+            res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
+            me.set().height = oldMe.v.height;
+        }
+        return res;
+    }
+
+    static C2R MaxPictureSizeSetter(bool mayBlock, C2P<C2StreamMaxPictureSizeTuning::output> &me,
+                                    const C2P<C2StreamPictureSizeInfo::output> &size) {
+        (void)mayBlock;
+        // TODO: get max width/height from the size's field helpers vs. hardcoding
+        me.set().width = c2_min(c2_max(me.v.width, size.v.width), 4080u);
+        me.set().height = c2_min(c2_max(me.v.height, size.v.height), 4080u);
+        return C2R::Ok();
+    }
+
+    static C2R MaxInputSizeSetter(bool mayBlock, C2P<C2StreamMaxBufferSizeInfo::input> &me,
+                                  const C2P<C2StreamMaxPictureSizeTuning::output> &maxSize) {
+        (void)mayBlock;
+        // assume compression ratio of 2
+        me.set().value = (((maxSize.v.width + 15) / 16) * ((maxSize.v.height + 15) / 16) * 192);
+        return C2R::Ok();
+    }
+
+    static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me,
+                                  const C2P<C2StreamPictureSizeInfo::output> &size) {
+        (void)mayBlock;
+        (void)size;
+        (void)me;  // TODO: validate
+        return C2R::Ok();
+    }
+
+    static C2R DefaultColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsTuning::output> &me) {
+        (void)mayBlock;
+        if (me.v.range > C2Color::RANGE_OTHER) {
+                me.set().range = C2Color::RANGE_OTHER;
+        }
+        if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
+                me.set().primaries = C2Color::PRIMARIES_OTHER;
+        }
+        if (me.v.transfer > C2Color::TRANSFER_OTHER) {
+                me.set().transfer = C2Color::TRANSFER_OTHER;
+        }
+        if (me.v.matrix > C2Color::MATRIX_OTHER) {
+                me.set().matrix = C2Color::MATRIX_OTHER;
+        }
+        return C2R::Ok();
+    }
+
+    static C2R CodedColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::input> &me) {
+        (void)mayBlock;
+        if (me.v.range > C2Color::RANGE_OTHER) {
+                me.set().range = C2Color::RANGE_OTHER;
+        }
+        if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
+                me.set().primaries = C2Color::PRIMARIES_OTHER;
+        }
+        if (me.v.transfer > C2Color::TRANSFER_OTHER) {
+                me.set().transfer = C2Color::TRANSFER_OTHER;
+        }
+        if (me.v.matrix > C2Color::MATRIX_OTHER) {
+                me.set().matrix = C2Color::MATRIX_OTHER;
+        }
+        return C2R::Ok();
+    }
+
+    static C2R ColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::output> &me,
+                                  const C2P<C2StreamColorAspectsTuning::output> &def,
+                                  const C2P<C2StreamColorAspectsInfo::input> &coded) {
+        (void)mayBlock;
+        // take default values for all unspecified fields, and coded values for specified ones
+        me.set().range = coded.v.range == RANGE_UNSPECIFIED ? def.v.range : coded.v.range;
+        me.set().primaries = coded.v.primaries == PRIMARIES_UNSPECIFIED
+                ? def.v.primaries : coded.v.primaries;
+        me.set().transfer = coded.v.transfer == TRANSFER_UNSPECIFIED
+                ? def.v.transfer : coded.v.transfer;
+        me.set().matrix = coded.v.matrix == MATRIX_UNSPECIFIED ? def.v.matrix : coded.v.matrix;
+        return C2R::Ok();
+    }
+
+    std::shared_ptr<C2StreamColorAspectsInfo::output> getColorAspects_l() {
+        return mColorAspects;
+    }
+
+private:
+    std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
+    std::shared_ptr<C2StreamPictureSizeInfo::output> mSize;
+    std::shared_ptr<C2StreamMaxPictureSizeTuning::output> mMaxSize;
+    std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mMaxInputSize;
+    std::shared_ptr<C2StreamColorInfo::output> mColorInfo;
+    std::shared_ptr<C2StreamColorAspectsInfo::input> mCodedColorAspects;
+    std::shared_ptr<C2StreamColorAspectsTuning::output> mDefaultColorAspects;
+    std::shared_ptr<C2StreamColorAspectsInfo::output> mColorAspects;
+    std::shared_ptr<C2StreamPixelFormatInfo::output> mPixelFormat;
+};
+
+static size_t getCpuCoreCount() {
+    long cpuCoreCount = 1;
+#if defined(_SC_NPROCESSORS_ONLN)
+    cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
+#else
+    // _SC_NPROC_ONLN must be defined...
+    cpuCoreCount = sysconf(_SC_NPROC_ONLN);
+#endif
+    CHECK(cpuCoreCount >= 1);
+    ALOGV("Number of CPU cores: %ld", cpuCoreCount);
+    return (size_t)cpuCoreCount;
+}
+
+static void *ivd_aligned_malloc(void *ctxt, WORD32 alignment, WORD32 size) {
+    (void) ctxt;
+    return memalign(alignment, size);
+}
+
+static void ivd_aligned_free(void *ctxt, void *mem) {
+    (void) ctxt;
+    free(mem);
+}
+
+C2SoftAvcDec::C2SoftAvcDec(
+        const char *name,
+        c2_node_id_t id,
+        const std::shared_ptr<IntfImpl> &intfImpl)
+    : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+      mIntf(intfImpl),
+      mDecHandle(nullptr),
+      mOutBufferFlush(nullptr),
+      mIvColorFormat(IV_YUV_420P),
+      mWidth(320),
+      mHeight(240),
+      mHeaderDecoded(false),
+      mOutIndex(0u) {
+    GENERATE_FILE_NAMES();
+    CREATE_DUMP_FILE(mInFile);
+}
+
+C2SoftAvcDec::~C2SoftAvcDec() {
+    onRelease();
+}
+
+c2_status_t C2SoftAvcDec::onInit() {
+    status_t err = initDecoder();
+    return err == OK ? C2_OK : C2_CORRUPTED;
+}
+
+c2_status_t C2SoftAvcDec::onStop() {
+    if (OK != resetDecoder()) return C2_CORRUPTED;
+    resetPlugin();
+    return C2_OK;
+}
+
+void C2SoftAvcDec::onReset() {
+    (void) onStop();
+}
+
+void C2SoftAvcDec::onRelease() {
+    (void) deleteDecoder();
+    if (mOutBufferFlush) {
+        ivd_aligned_free(nullptr, mOutBufferFlush);
+        mOutBufferFlush = nullptr;
+    }
+    if (mOutBlock) {
+        mOutBlock.reset();
+    }
+}
+
+c2_status_t C2SoftAvcDec::onFlush_sm() {
+    if (OK != setFlushMode()) return C2_CORRUPTED;
+
+    uint32_t bufferSize = mStride * mHeight * 3 / 2;
+    mOutBufferFlush = (uint8_t *)ivd_aligned_malloc(nullptr, 128, bufferSize);
+    if (!mOutBufferFlush) {
+        ALOGE("could not allocate tmp output buffer (for flush) of size %u ", bufferSize);
+        return C2_NO_MEMORY;
+    }
+
+    while (true) {
+        ivd_video_decode_ip_t s_decode_ip;
+        ivd_video_decode_op_t s_decode_op;
+
+        setDecodeArgs(&s_decode_ip, &s_decode_op, nullptr, nullptr, 0, 0, 0);
+        (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
+        if (0 == s_decode_op.u4_output_present) {
+            resetPlugin();
+            break;
+        }
+    }
+
+    if (mOutBufferFlush) {
+        ivd_aligned_free(nullptr, mOutBufferFlush);
+        mOutBufferFlush = nullptr;
+    }
+
+    return C2_OK;
+}
+
+status_t C2SoftAvcDec::createDecoder() {
+    ivdext_create_ip_t s_create_ip;
+    ivdext_create_op_t s_create_op;
+
+    s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(ivdext_create_ip_t);
+    s_create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
+    s_create_ip.s_ivd_create_ip_t.u4_share_disp_buf = 0;
+    s_create_ip.s_ivd_create_ip_t.e_output_format = mIvColorFormat;
+    s_create_ip.s_ivd_create_ip_t.pf_aligned_alloc = ivd_aligned_malloc;
+    s_create_ip.s_ivd_create_ip_t.pf_aligned_free = ivd_aligned_free;
+    s_create_ip.s_ivd_create_ip_t.pv_mem_ctxt = nullptr;
+    s_create_op.s_ivd_create_op_t.u4_size = sizeof(ivdext_create_op_t);
+    IV_API_CALL_STATUS_T status = ivdec_api_function(nullptr,
+                                                     &s_create_ip,
+                                                     &s_create_op);
+    if (status != IV_SUCCESS) {
+        ALOGE("error in %s: 0x%x", __func__,
+              s_create_op.s_ivd_create_op_t.u4_error_code);
+        return UNKNOWN_ERROR;
+    }
+    mDecHandle = (iv_obj_t*)s_create_op.s_ivd_create_op_t.pv_handle;
+    mDecHandle->pv_fxns = (void *)ivdec_api_function;
+    mDecHandle->u4_size = sizeof(iv_obj_t);
+
+    return OK;
+}
+
+status_t C2SoftAvcDec::setNumCores() {
+    ivdext_ctl_set_num_cores_ip_t s_set_num_cores_ip;
+    ivdext_ctl_set_num_cores_op_t s_set_num_cores_op;
+
+    s_set_num_cores_ip.u4_size = sizeof(ivdext_ctl_set_num_cores_ip_t);
+    s_set_num_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+    s_set_num_cores_ip.e_sub_cmd = IVDEXT_CMD_CTL_SET_NUM_CORES;
+    s_set_num_cores_ip.u4_num_cores = mNumCores;
+    s_set_num_cores_op.u4_size = sizeof(ivdext_ctl_set_num_cores_op_t);
+    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+                                                     &s_set_num_cores_ip,
+                                                     &s_set_num_cores_op);
+    if (IV_SUCCESS != status) {
+        ALOGD("error in %s: 0x%x", __func__, s_set_num_cores_op.u4_error_code);
+        return UNKNOWN_ERROR;
+    }
+
+    return OK;
+}
+
+status_t C2SoftAvcDec::setParams(size_t stride, IVD_VIDEO_DECODE_MODE_T dec_mode) {
+    ivd_ctl_set_config_ip_t s_set_dyn_params_ip;
+    ivd_ctl_set_config_op_t s_set_dyn_params_op;
+
+    s_set_dyn_params_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
+    s_set_dyn_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+    s_set_dyn_params_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+    s_set_dyn_params_ip.u4_disp_wd = (UWORD32) stride;
+    s_set_dyn_params_ip.e_frm_skip_mode = IVD_SKIP_NONE;
+    s_set_dyn_params_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+    s_set_dyn_params_ip.e_vid_dec_mode = dec_mode;
+    s_set_dyn_params_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
+    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+                                                     &s_set_dyn_params_ip,
+                                                     &s_set_dyn_params_op);
+    if (status != IV_SUCCESS) {
+        ALOGE("error in %s: 0x%x", __func__, s_set_dyn_params_op.u4_error_code);
+        return UNKNOWN_ERROR;
+    }
+
+    return OK;
+}
+
+void C2SoftAvcDec::getVersion() {
+    ivd_ctl_getversioninfo_ip_t s_get_versioninfo_ip;
+    ivd_ctl_getversioninfo_op_t s_get_versioninfo_op;
+    UWORD8 au1_buf[512];
+
+    s_get_versioninfo_ip.u4_size = sizeof(ivd_ctl_getversioninfo_ip_t);
+    s_get_versioninfo_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+    s_get_versioninfo_ip.e_sub_cmd = IVD_CMD_CTL_GETVERSION;
+    s_get_versioninfo_ip.pv_version_buffer = au1_buf;
+    s_get_versioninfo_ip.u4_version_buffer_size = sizeof(au1_buf);
+    s_get_versioninfo_op.u4_size = sizeof(ivd_ctl_getversioninfo_op_t);
+    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+                                                     &s_get_versioninfo_ip,
+                                                     &s_get_versioninfo_op);
+    if (status != IV_SUCCESS) {
+        ALOGD("error in %s: 0x%x", __func__,
+              s_get_versioninfo_op.u4_error_code);
+    } else {
+        ALOGV("ittiam decoder version number: %s",
+              (char *) s_get_versioninfo_ip.pv_version_buffer);
+    }
+}
+
+status_t C2SoftAvcDec::initDecoder() {
+    if (OK != createDecoder()) return UNKNOWN_ERROR;
+    mNumCores = MIN(getCpuCoreCount(), MAX_NUM_CORES);
+    mStride = ALIGN64(mWidth);
+    mSignalledError = false;
+    resetPlugin();
+    (void) setNumCores();
+    if (OK != setParams(mStride, IVD_DECODE_FRAME)) return UNKNOWN_ERROR;
+    (void) getVersion();
+
+    return OK;
+}
+
+bool C2SoftAvcDec::setDecodeArgs(ivd_video_decode_ip_t *ps_decode_ip,
+                                 ivd_video_decode_op_t *ps_decode_op,
+                                 C2ReadView *inBuffer,
+                                 C2GraphicView *outBuffer,
+                                 size_t inOffset,
+                                 size_t inSize,
+                                 uint32_t tsMarker) {
+    uint32_t displayStride = mStride;
+    uint32_t displayHeight = mHeight;
+    size_t lumaSize = displayStride * displayHeight;
+    size_t chromaSize = lumaSize >> 2;
+
+    ps_decode_ip->u4_size = sizeof(ivd_video_decode_ip_t);
+    ps_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
+    if (inBuffer) {
+        ps_decode_ip->u4_ts = tsMarker;
+        ps_decode_ip->pv_stream_buffer = const_cast<uint8_t *>(inBuffer->data() + inOffset);
+        ps_decode_ip->u4_num_Bytes = inSize;
+    } else {
+        ps_decode_ip->u4_ts = 0;
+        ps_decode_ip->pv_stream_buffer = nullptr;
+        ps_decode_ip->u4_num_Bytes = 0;
+    }
+    ps_decode_ip->s_out_buffer.u4_min_out_buf_size[0] = lumaSize;
+    ps_decode_ip->s_out_buffer.u4_min_out_buf_size[1] = chromaSize;
+    ps_decode_ip->s_out_buffer.u4_min_out_buf_size[2] = chromaSize;
+    if (outBuffer) {
+        if (outBuffer->width() < displayStride || outBuffer->height() < displayHeight) {
+            ALOGE("Output buffer too small: provided (%dx%d) required (%ux%u)",
+                  outBuffer->width(), outBuffer->height(), displayStride, displayHeight);
+            return false;
+        }
+        ps_decode_ip->s_out_buffer.pu1_bufs[0] = outBuffer->data()[C2PlanarLayout::PLANE_Y];
+        ps_decode_ip->s_out_buffer.pu1_bufs[1] = outBuffer->data()[C2PlanarLayout::PLANE_U];
+        ps_decode_ip->s_out_buffer.pu1_bufs[2] = outBuffer->data()[C2PlanarLayout::PLANE_V];
+    } else {
+        ps_decode_ip->s_out_buffer.pu1_bufs[0] = mOutBufferFlush;
+        ps_decode_ip->s_out_buffer.pu1_bufs[1] = mOutBufferFlush + lumaSize;
+        ps_decode_ip->s_out_buffer.pu1_bufs[2] = mOutBufferFlush + lumaSize + chromaSize;
+    }
+    ps_decode_ip->s_out_buffer.u4_num_bufs = 3;
+    ps_decode_op->u4_size = sizeof(ivd_video_decode_op_t);
+
+    return true;
+}
+
+bool C2SoftAvcDec::getVuiParams() {
+    ivdext_ctl_get_vui_params_ip_t s_get_vui_params_ip;
+    ivdext_ctl_get_vui_params_op_t s_get_vui_params_op;
+
+    s_get_vui_params_ip.u4_size = sizeof(ivdext_ctl_get_vui_params_ip_t);
+    s_get_vui_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+    s_get_vui_params_ip.e_sub_cmd =
+            (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_VUI_PARAMS;
+    s_get_vui_params_op.u4_size = sizeof(ivdext_ctl_get_vui_params_op_t);
+    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+                                                     &s_get_vui_params_ip,
+                                                     &s_get_vui_params_op);
+    if (status != IV_SUCCESS) {
+        ALOGD("error in %s: 0x%x", __func__, s_get_vui_params_op.u4_error_code);
+        return false;
+    }
+
+    VuiColorAspects vuiColorAspects;
+    vuiColorAspects.primaries = s_get_vui_params_op.u1_colour_primaries;
+    vuiColorAspects.transfer = s_get_vui_params_op.u1_tfr_chars;
+    vuiColorAspects.coeffs = s_get_vui_params_op.u1_matrix_coeffs;
+    vuiColorAspects.fullRange = s_get_vui_params_op.u1_video_full_range_flag;
+
+    // convert vui aspects to C2 values if changed
+    if (!(vuiColorAspects == mBitstreamColorAspects)) {
+        mBitstreamColorAspects = vuiColorAspects;
+        ColorAspects sfAspects;
+        C2StreamColorAspectsInfo::input codedAspects = { 0u };
+        ColorUtils::convertIsoColorAspectsToCodecAspects(
+                vuiColorAspects.primaries, vuiColorAspects.transfer, vuiColorAspects.coeffs,
+                vuiColorAspects.fullRange, sfAspects);
+        if (!C2Mapper::map(sfAspects.mPrimaries, &codedAspects.primaries)) {
+            codedAspects.primaries = C2Color::PRIMARIES_UNSPECIFIED;
+        }
+        if (!C2Mapper::map(sfAspects.mRange, &codedAspects.range)) {
+            codedAspects.range = C2Color::RANGE_UNSPECIFIED;
+        }
+        if (!C2Mapper::map(sfAspects.mMatrixCoeffs, &codedAspects.matrix)) {
+            codedAspects.matrix = C2Color::MATRIX_UNSPECIFIED;
+        }
+        if (!C2Mapper::map(sfAspects.mTransfer, &codedAspects.transfer)) {
+            codedAspects.transfer = C2Color::TRANSFER_UNSPECIFIED;
+        }
+        std::vector<std::unique_ptr<C2SettingResult>> failures;
+        (void)mIntf->config({&codedAspects}, C2_MAY_BLOCK, &failures);
+    }
+    return true;
+}
+
+status_t C2SoftAvcDec::setFlushMode() {
+    ivd_ctl_flush_ip_t s_set_flush_ip;
+    ivd_ctl_flush_op_t s_set_flush_op;
+
+    s_set_flush_ip.u4_size = sizeof(ivd_ctl_flush_ip_t);
+    s_set_flush_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+    s_set_flush_ip.e_sub_cmd = IVD_CMD_CTL_FLUSH;
+    s_set_flush_op.u4_size = sizeof(ivd_ctl_flush_op_t);
+    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+                                                     &s_set_flush_ip,
+                                                     &s_set_flush_op);
+    if (status != IV_SUCCESS) {
+        ALOGE("error in %s: 0x%x", __func__, s_set_flush_op.u4_error_code);
+        return UNKNOWN_ERROR;
+    }
+
+    return OK;
+}
+
+status_t C2SoftAvcDec::resetDecoder() {
+    ivd_ctl_reset_ip_t s_reset_ip;
+    ivd_ctl_reset_op_t s_reset_op;
+
+    s_reset_ip.u4_size = sizeof(ivd_ctl_reset_ip_t);
+    s_reset_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+    s_reset_ip.e_sub_cmd = IVD_CMD_CTL_RESET;
+    s_reset_op.u4_size = sizeof(ivd_ctl_reset_op_t);
+    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+                                                     &s_reset_ip,
+                                                     &s_reset_op);
+    if (IV_SUCCESS != status) {
+        ALOGE("error in %s: 0x%x", __func__, s_reset_op.u4_error_code);
+        return UNKNOWN_ERROR;
+    }
+    mStride = 0;
+    (void) setNumCores();
+    mSignalledError = false;
+    mHeaderDecoded = false;
+
+    return OK;
+}
+
+void C2SoftAvcDec::resetPlugin() {
+    mSignalledOutputEos = false;
+    gettimeofday(&mTimeStart, nullptr);
+    gettimeofday(&mTimeEnd, nullptr);
+}
+
+status_t C2SoftAvcDec::deleteDecoder() {
+    if (mDecHandle) {
+        ivdext_delete_ip_t s_delete_ip;
+        ivdext_delete_op_t s_delete_op;
+
+        s_delete_ip.s_ivd_delete_ip_t.u4_size = sizeof(ivdext_delete_ip_t);
+        s_delete_ip.s_ivd_delete_ip_t.e_cmd = IVD_CMD_DELETE;
+        s_delete_op.s_ivd_delete_op_t.u4_size = sizeof(ivdext_delete_op_t);
+        IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+                                                         &s_delete_ip,
+                                                         &s_delete_op);
+        if (status != IV_SUCCESS) {
+            ALOGE("error in %s: 0x%x", __func__,
+                  s_delete_op.s_ivd_delete_op_t.u4_error_code);
+            return UNKNOWN_ERROR;
+        }
+        mDecHandle = nullptr;
+    }
+
+    return OK;
+}
+
+static void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
+    uint32_t flags = 0;
+    if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
+        flags |= C2FrameData::FLAG_END_OF_STREAM;
+        ALOGV("signalling eos");
+    }
+    work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
+    work->worklets.front()->output.buffers.clear();
+    work->worklets.front()->output.ordinal = work->input.ordinal;
+    work->workletsProcessed = 1u;
+}
+
+void C2SoftAvcDec::finishWork(uint64_t index, const std::unique_ptr<C2Work> &work) {
+    std::shared_ptr<C2Buffer> buffer = createGraphicBuffer(std::move(mOutBlock),
+                                                           C2Rect(mWidth, mHeight));
+    mOutBlock = nullptr;
+    {
+        IntfImpl::Lock lock = mIntf->lock();
+        buffer->setInfo(mIntf->getColorAspects_l());
+    }
+
+    class FillWork {
+       public:
+        FillWork(uint32_t flags, C2WorkOrdinalStruct ordinal,
+                 const std::shared_ptr<C2Buffer>& buffer)
+            : mFlags(flags), mOrdinal(ordinal), mBuffer(buffer) {}
+        ~FillWork() = default;
+
+        void operator()(const std::unique_ptr<C2Work>& work) {
+            work->worklets.front()->output.flags = (C2FrameData::flags_t)mFlags;
+            work->worklets.front()->output.buffers.clear();
+            work->worklets.front()->output.ordinal = mOrdinal;
+            work->workletsProcessed = 1u;
+            work->result = C2_OK;
+            if (mBuffer) {
+                work->worklets.front()->output.buffers.push_back(mBuffer);
+            }
+            ALOGV("timestamp = %lld, index = %lld, w/%s buffer",
+                  mOrdinal.timestamp.peekll(), mOrdinal.frameIndex.peekll(),
+                  mBuffer ? "" : "o");
+        }
+
+       private:
+        const uint32_t mFlags;
+        const C2WorkOrdinalStruct mOrdinal;
+        const std::shared_ptr<C2Buffer> mBuffer;
+    };
+
+    auto fillWork = [buffer](const std::unique_ptr<C2Work> &work) {
+        work->worklets.front()->output.flags = (C2FrameData::flags_t)0;
+        work->worklets.front()->output.buffers.clear();
+        work->worklets.front()->output.buffers.push_back(buffer);
+        work->worklets.front()->output.ordinal = work->input.ordinal;
+        work->workletsProcessed = 1u;
+    };
+    if (work && c2_cntr64_t(index) == work->input.ordinal.frameIndex) {
+        bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
+        // TODO: Check if cloneAndSend can be avoided by tracking number of frames remaining
+        if (eos) {
+            if (buffer) {
+                mOutIndex = index;
+                C2WorkOrdinalStruct outOrdinal = work->input.ordinal;
+                cloneAndSend(
+                    mOutIndex, work,
+                    FillWork(C2FrameData::FLAG_INCOMPLETE, outOrdinal, buffer));
+                buffer.reset();
+            }
+        } else {
+            fillWork(work);
+        }
+    } else {
+        finish(index, fillWork);
+    }
+}
+
+c2_status_t C2SoftAvcDec::ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool) {
+    if (!mDecHandle) {
+        ALOGE("not supposed to be here, invalid decoder context");
+        return C2_CORRUPTED;
+    }
+    if (mStride != ALIGN64(mWidth)) {
+        mStride = ALIGN64(mWidth);
+        if (OK != setParams(mStride, IVD_DECODE_FRAME)) return C2_CORRUPTED;
+    }
+    if (mOutBlock &&
+            (mOutBlock->width() != mStride || mOutBlock->height() != mHeight)) {
+        mOutBlock.reset();
+    }
+    if (!mOutBlock) {
+        uint32_t format = HAL_PIXEL_FORMAT_YV12;
+        C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+        c2_status_t err = pool->fetchGraphicBlock(mStride, mHeight, format, usage, &mOutBlock);
+        if (err != C2_OK) {
+            ALOGE("fetchGraphicBlock for Output failed with status %d", err);
+            return err;
+        }
+        ALOGV("provided (%dx%d) required (%dx%d)",
+              mOutBlock->width(), mOutBlock->height(), mStride, mHeight);
+    }
+
+    return C2_OK;
+}
+
+// TODO: can overall error checking be improved?
+// TODO: allow configuration of color format and usage for graphic buffers instead
+//       of hard coding them to HAL_PIXEL_FORMAT_YV12
+// TODO: pass coloraspects information to surface
+// TODO: test support for dynamic change in resolution
+// TODO: verify if the decoder sent back all frames
+void C2SoftAvcDec::process(
+        const std::unique_ptr<C2Work> &work,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    // Initialize output work
+    work->result = C2_OK;
+    work->workletsProcessed = 0u;
+    work->worklets.front()->output.flags = work->input.flags;
+    if (mSignalledError || mSignalledOutputEos) {
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+
+    size_t inOffset = 0u;
+    size_t inSize = 0u;
+    uint32_t workIndex = work->input.ordinal.frameIndex.peeku() & 0xFFFFFFFF;
+    C2ReadView rView = mDummyReadView;
+    if (!work->input.buffers.empty()) {
+        rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
+        inSize = rView.capacity();
+        if (inSize && rView.error()) {
+            ALOGE("read view map failed %d", rView.error());
+            work->result = rView.error();
+            return;
+        }
+    }
+    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
+    bool hasPicture = false;
+
+    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
+          inSize, (int)work->input.ordinal.timestamp.peeku(),
+          (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
+    size_t inPos = 0;
+    while (inPos < inSize) {
+        if (C2_OK != ensureDecoderState(pool)) {
+            mSignalledError = true;
+            work->workletsProcessed = 1u;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+
+        ivd_video_decode_ip_t s_decode_ip;
+        ivd_video_decode_op_t s_decode_op;
+        {
+            C2GraphicView wView = mOutBlock->map().get();
+            if (wView.error()) {
+                ALOGE("graphic view map failed %d", wView.error());
+                work->result = wView.error();
+                return;
+            }
+            if (!setDecodeArgs(&s_decode_ip, &s_decode_op, &rView, &wView,
+                               inOffset + inPos, inSize - inPos, workIndex)) {
+                mSignalledError = true;
+                work->workletsProcessed = 1u;
+                work->result = C2_CORRUPTED;
+                return;
+            }
+
+            if (false == mHeaderDecoded) {
+                /* Decode header and get dimensions */
+                setParams(mStride, IVD_DECODE_HEADER);
+            }
+
+            WORD32 delay;
+            GETTIME(&mTimeStart, nullptr);
+            TIME_DIFF(mTimeEnd, mTimeStart, delay);
+            (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
+            WORD32 decodeTime;
+            GETTIME(&mTimeEnd, nullptr);
+            TIME_DIFF(mTimeStart, mTimeEnd, decodeTime);
+            ALOGV("decodeTime=%6d delay=%6d numBytes=%6d", decodeTime, delay,
+                  s_decode_op.u4_num_bytes_consumed);
+        }
+        if (IVD_MEM_ALLOC_FAILED == (s_decode_op.u4_error_code & IVD_ERROR_MASK)) {
+            ALOGE("allocation failure in decoder");
+            mSignalledError = true;
+            work->workletsProcessed = 1u;
+            work->result = C2_CORRUPTED;
+            return;
+        } else if (IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED == (s_decode_op.u4_error_code & IVD_ERROR_MASK)) {
+            ALOGE("unsupported resolution : %dx%d", mWidth, mHeight);
+            mSignalledError = true;
+            work->workletsProcessed = 1u;
+            work->result = C2_CORRUPTED;
+            return;
+        } else if (IVD_RES_CHANGED == (s_decode_op.u4_error_code & IVD_ERROR_MASK)) {
+            ALOGV("resolution changed");
+            drainInternal(DRAIN_COMPONENT_NO_EOS, pool, work);
+            resetDecoder();
+            resetPlugin();
+            work->workletsProcessed = 0u;
+
+            /* Decode header and get new dimensions */
+            setParams(mStride, IVD_DECODE_HEADER);
+            (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
+        } else if (IS_IVD_FATAL_ERROR(s_decode_op.u4_error_code)) {
+            ALOGE("Fatal error in decoder 0x%x", s_decode_op.u4_error_code);
+            mSignalledError = true;
+            work->workletsProcessed = 1u;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+        if (0 < s_decode_op.u4_pic_wd && 0 < s_decode_op.u4_pic_ht) {
+            if (mHeaderDecoded == false) {
+                mHeaderDecoded = true;
+                setParams(ALIGN64(s_decode_op.u4_pic_wd), IVD_DECODE_FRAME);
+            }
+            if (s_decode_op.u4_pic_wd != mWidth || s_decode_op.u4_pic_ht != mHeight) {
+                mWidth = s_decode_op.u4_pic_wd;
+                mHeight = s_decode_op.u4_pic_ht;
+                CHECK_EQ(0u, s_decode_op.u4_output_present);
+
+                C2StreamPictureSizeInfo::output size(0u, mWidth, mHeight);
+                std::vector<std::unique_ptr<C2SettingResult>> failures;
+                c2_status_t err = mIntf->config({&size}, C2_MAY_BLOCK, &failures);
+                if (err == OK) {
+                    work->worklets.front()->output.configUpdate.push_back(
+                        C2Param::Copy(size));
+                } else {
+                    ALOGE("Cannot set width and height");
+                    mSignalledError = true;
+                    work->workletsProcessed = 1u;
+                    work->result = C2_CORRUPTED;
+                    return;
+                }
+                continue;
+            }
+        }
+        (void)getVuiParams();
+        hasPicture |= (1 == s_decode_op.u4_frame_decoded_flag);
+        if (s_decode_op.u4_output_present) {
+            finishWork(s_decode_op.u4_ts, work);
+        }
+        if (0 == s_decode_op.u4_num_bytes_consumed) {
+            ALOGD("Bytes consumed is zero. Ignoring remaining bytes");
+            break;
+        }
+        inPos += s_decode_op.u4_num_bytes_consumed;
+        if (hasPicture && (inSize - inPos)) {
+            ALOGD("decoded frame in current access nal, ignoring further trailing bytes %d",
+                  (int)inSize - (int)inPos);
+            break;
+        }
+    }
+    if (eos) {
+        drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
+        mSignalledOutputEos = true;
+    } else if (!hasPicture) {
+        fillEmptyWork(work);
+    }
+
+    work->input.buffers.clear();
+}
+
+c2_status_t C2SoftAvcDec::drainInternal(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool,
+        const std::unique_ptr<C2Work> &work) {
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+
+    if (OK != setFlushMode()) return C2_CORRUPTED;
+    while (true) {
+        if (C2_OK != ensureDecoderState(pool)) {
+            mSignalledError = true;
+            work->workletsProcessed = 1u;
+            work->result = C2_CORRUPTED;
+            return C2_CORRUPTED;
+        }
+        C2GraphicView wView = mOutBlock->map().get();
+        if (wView.error()) {
+            ALOGE("graphic view map failed %d", wView.error());
+            return C2_CORRUPTED;
+        }
+        ivd_video_decode_ip_t s_decode_ip;
+        ivd_video_decode_op_t s_decode_op;
+        if (!setDecodeArgs(&s_decode_ip, &s_decode_op, nullptr, &wView, 0, 0, 0)) {
+            mSignalledError = true;
+            work->workletsProcessed = 1u;
+            return C2_CORRUPTED;
+        }
+        (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
+        if (s_decode_op.u4_output_present) {
+            finishWork(s_decode_op.u4_ts, work);
+        } else {
+            fillEmptyWork(work);
+            break;
+        }
+    }
+
+    return C2_OK;
+}
+
+c2_status_t C2SoftAvcDec::drain(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    return drainInternal(drainMode, pool, nullptr);
+}
+
+class C2SoftAvcDecFactory : public C2ComponentFactory {
+public:
+    C2SoftAvcDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+        GetCodec2PlatformComponentStore()->getParamReflector())) {
+    }
+
+    virtual c2_status_t createComponent(
+            c2_node_id_t id,
+            std::shared_ptr<C2Component>* const component,
+            std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+                new C2SoftAvcDec(COMPONENT_NAME,
+                                 id,
+                                 std::make_shared<C2SoftAvcDec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+            c2_node_id_t id,
+            std::shared_ptr<C2ComponentInterface>* const interface,
+            std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+                new SimpleInterface<C2SoftAvcDec::IntfImpl>(
+                        COMPONENT_NAME, id, std::make_shared<C2SoftAvcDec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftAvcDecFactory() override = default;
+
+private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftAvcDecFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/avc/C2SoftAvcDec.h b/media/codec2/components/avc/C2SoftAvcDec.h
new file mode 100644
index 0000000..72ee583
--- /dev/null
+++ b/media/codec2/components/avc/C2SoftAvcDec.h
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_AVC_DEC_H_
+#define ANDROID_C2_SOFT_AVC_DEC_H_
+
+#include <sys/time.h>
+
+#include <media/stagefright/foundation/ColorUtils.h>
+
+#include <atomic>
+#include <SimpleC2Component.h>
+
+#include "ih264_typedefs.h"
+#include "iv.h"
+#include "ivd.h"
+
+namespace android {
+
+#define ivdec_api_function              ih264d_api_function
+#define ivdext_create_ip_t              ih264d_create_ip_t
+#define ivdext_create_op_t              ih264d_create_op_t
+#define ivdext_delete_ip_t              ih264d_delete_ip_t
+#define ivdext_delete_op_t              ih264d_delete_op_t
+#define ivdext_ctl_set_num_cores_ip_t   ih264d_ctl_set_num_cores_ip_t
+#define ivdext_ctl_set_num_cores_op_t   ih264d_ctl_set_num_cores_op_t
+#define ivdext_ctl_get_vui_params_ip_t  ih264d_ctl_get_vui_params_ip_t
+#define ivdext_ctl_get_vui_params_op_t  ih264d_ctl_get_vui_params_op_t
+#define ALIGN64(x)                      ((((x) + 63) >> 6) << 6)
+#define MAX_NUM_CORES                   4
+#define IVDEXT_CMD_CTL_SET_NUM_CORES    \
+        (IVD_CONTROL_API_COMMAND_TYPE_T)IH264D_CMD_CTL_SET_NUM_CORES
+#define MIN(a, b)                       (((a) < (b)) ? (a) : (b))
+#define GETTIME(a, b)                   gettimeofday(a, b);
+#define TIME_DIFF(start, end, diff)     \
+    diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \
+            ((end).tv_usec - (start).tv_usec);
+
+#ifdef FILE_DUMP_ENABLE
+    #define INPUT_DUMP_PATH     "/sdcard/clips/avcd_input"
+    #define INPUT_DUMP_EXT      "h264"
+    #define GENERATE_FILE_NAMES() {                         \
+        GETTIME(&mTimeStart, NULL);                         \
+        strcpy(mInFile, "");                                \
+        sprintf(mInFile, "%s_%ld.%ld.%s", INPUT_DUMP_PATH,  \
+                mTimeStart.tv_sec, mTimeStart.tv_usec,      \
+                INPUT_DUMP_EXT);                            \
+    }
+    #define CREATE_DUMP_FILE(m_filename) {                  \
+        FILE *fp = fopen(m_filename, "wb");                 \
+        if (fp != NULL) {                                   \
+            fclose(fp);                                     \
+        } else {                                            \
+            ALOGD("Could not open file %s", m_filename);    \
+        }                                                   \
+    }
+    #define DUMP_TO_FILE(m_filename, m_buf, m_size, m_offset)\
+    {                                                       \
+        FILE *fp = fopen(m_filename, "ab");                 \
+        if (fp != NULL && m_buf != NULL && m_offset == 0) { \
+            int i;                                          \
+            i = fwrite(m_buf, 1, m_size, fp);               \
+            ALOGD("fwrite ret %d to write %d", i, m_size);  \
+            if (i != (int) m_size) {                        \
+                ALOGD("Error in fwrite, returned %d", i);   \
+                perror("Error in write to file");           \
+            }                                               \
+        } else if (fp == NULL) {                            \
+            ALOGD("Could not write to file %s", m_filename);\
+        }                                                   \
+        if (fp) {                                           \
+            fclose(fp);                                     \
+        }                                                   \
+    }
+#else /* FILE_DUMP_ENABLE */
+    #define INPUT_DUMP_PATH
+    #define INPUT_DUMP_EXT
+    #define OUTPUT_DUMP_PATH
+    #define OUTPUT_DUMP_EXT
+    #define GENERATE_FILE_NAMES()
+    #define CREATE_DUMP_FILE(m_filename)
+    #define DUMP_TO_FILE(m_filename, m_buf, m_size, m_offset)
+#endif /* FILE_DUMP_ENABLE */
+
+
+class C2SoftAvcDec : public SimpleC2Component {
+public:
+    class IntfImpl;
+    C2SoftAvcDec(const char *name, c2_node_id_t id, const std::shared_ptr<IntfImpl> &intfImpl);
+    virtual ~C2SoftAvcDec();
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+    c2_status_t drain(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+
+private:
+    status_t createDecoder();
+    status_t setNumCores();
+    status_t setParams(size_t stride, IVD_VIDEO_DECODE_MODE_T dec_mode);
+    void getVersion();
+    status_t initDecoder();
+    bool setDecodeArgs(ivd_video_decode_ip_t *ps_decode_ip,
+                       ivd_video_decode_op_t *ps_decode_op,
+                       C2ReadView *inBuffer,
+                       C2GraphicView *outBuffer,
+                       size_t inOffset,
+                       size_t inSize,
+                       uint32_t tsMarker);
+    bool getVuiParams();
+    c2_status_t ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool);
+    void finishWork(uint64_t index, const std::unique_ptr<C2Work> &work);
+    status_t setFlushMode();
+    c2_status_t drainInternal(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool,
+            const std::unique_ptr<C2Work> &work);
+    status_t resetDecoder();
+    void resetPlugin();
+    status_t deleteDecoder();
+
+    std::shared_ptr<IntfImpl> mIntf;
+
+    // TODO:This is not the right place for this enum. These should
+    // be part of c2-vndk so that they can be accessed by all video plugins
+    // until then, make them feel at home
+    enum {
+        kNotSupported,
+        kPreferBitstream,
+        kPreferContainer,
+    };
+
+    iv_obj_t *mDecHandle;
+    std::shared_ptr<C2GraphicBlock> mOutBlock;
+    uint8_t *mOutBufferFlush;
+
+    size_t mNumCores;
+    IV_COLOR_FORMAT_T mIvColorFormat;
+
+    uint32_t mWidth;
+    uint32_t mHeight;
+    uint32_t mStride;
+    bool mSignalledOutputEos;
+    bool mSignalledError;
+    bool mHeaderDecoded;
+    std::atomic_uint64_t mOutIndex;
+    // Color aspects. These are ISO values and are meant to detect changes in aspects to avoid
+    // converting them to C2 values for each frame
+    struct VuiColorAspects {
+        uint8_t primaries;
+        uint8_t transfer;
+        uint8_t coeffs;
+        uint8_t fullRange;
+
+        // default color aspects
+        VuiColorAspects()
+            : primaries(2), transfer(2), coeffs(2), fullRange(0) { }
+
+        bool operator==(const VuiColorAspects &o) {
+            return primaries == o.primaries && transfer == o.transfer && coeffs == o.coeffs
+                    && fullRange == o.fullRange;
+        }
+    } mBitstreamColorAspects;
+
+    // profile
+    struct timeval mTimeStart;
+    struct timeval mTimeEnd;
+#ifdef FILE_DUMP_ENABLE
+    char mInFile[200];
+#endif /* FILE_DUMP_ENABLE */
+
+    C2_DO_NOT_COPY(C2SoftAvcDec);
+};
+
+}  // namespace android
+
+#endif  // ANDROID_C2_SOFT_AVC_DEC_H_
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.cpp b/media/codec2/components/avc/C2SoftAvcEnc.cpp
new file mode 100644
index 0000000..b41c271
--- /dev/null
+++ b/media/codec2/components/avc/C2SoftAvcEnc.cpp
@@ -0,0 +1,1765 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftAvcEnc"
+#include <log/log.h>
+#include <utils/misc.h>
+
+#include <media/hardware/VideoAPI.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/foundation/AUtils.h>
+
+#include <C2Debug.h>
+#include <C2PlatformSupport.h>
+#include <Codec2BufferUtils.h>
+#include <SimpleC2Interface.h>
+#include <util/C2InterfaceHelper.h>
+
+#include "C2SoftAvcEnc.h"
+#include "ih264e.h"
+#include "ih264e_error.h"
+
+namespace android {
+
+namespace {
+
+constexpr char COMPONENT_NAME[] = "c2.android.avc.encoder";
+
+void ParseGop(
+        const C2StreamGopTuning::output &gop,
+        uint32_t *syncInterval, uint32_t *iInterval, uint32_t *maxBframes) {
+    uint32_t syncInt = 1;
+    uint32_t iInt = 1;
+    for (size_t i = 0; i < gop.flexCount(); ++i) {
+        const C2GopLayerStruct &layer = gop.m.values[i];
+        if (layer.count == UINT32_MAX) {
+            syncInt = 0;
+        } else if (syncInt <= UINT32_MAX / (layer.count + 1)) {
+            syncInt *= (layer.count + 1);
+        }
+        if ((layer.type_ & I_FRAME) == 0) {
+            if (layer.count == UINT32_MAX) {
+                iInt = 0;
+            } else if (iInt <= UINT32_MAX / (layer.count + 1)) {
+                iInt *= (layer.count + 1);
+            }
+        }
+        if (layer.type_ == C2Config::picture_type_t(P_FRAME | B_FRAME) && maxBframes) {
+            *maxBframes = layer.count;
+        }
+    }
+    if (syncInterval) {
+        *syncInterval = syncInt;
+    }
+    if (iInterval) {
+        *iInterval = iInt;
+    }
+}
+
+}  // namespace
+
+class C2SoftAvcEnc::IntfImpl : public SimpleInterface<void>::BaseParams {
+public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+        : SimpleInterface<void>::BaseParams(
+                helper,
+                COMPONENT_NAME,
+                C2Component::KIND_ENCODER,
+                C2Component::DOMAIN_VIDEO,
+                MEDIA_MIMETYPE_VIDEO_AVC) {
+        noPrivateBuffers(); // TODO: account for our buffers here
+        noInputReferences();
+        noOutputReferences();
+        noTimeStretch();
+        setDerivedInstance(this);
+
+        addParameter(
+                DefineParam(mUsage, C2_PARAMKEY_INPUT_STREAM_USAGE)
+                .withConstValue(new C2StreamUsageTuning::input(
+                        0u, (uint64_t)C2MemoryUsage::CPU_READ))
+                .build());
+
+        addParameter(
+                DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                .withConstValue(new C2ComponentAttributesSetting(
+                    C2Component::ATTRIB_IS_TEMPORAL))
+                .build());
+
+        addParameter(
+                DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
+                .withDefault(new C2StreamPictureSizeInfo::input(0u, 320, 240))
+                .withFields({
+                    C2F(mSize, width).inRange(2, 2560, 2),
+                    C2F(mSize, height).inRange(2, 2560, 2),
+                })
+                .withSetter(SizeSetter)
+                .build());
+
+        addParameter(
+                DefineParam(mGop, C2_PARAMKEY_GOP)
+                .withDefault(C2StreamGopTuning::output::AllocShared(
+                        0 /* flexCount */, 0u /* stream */))
+                .withFields({C2F(mGop, m.values[0].type_).any(),
+                             C2F(mGop, m.values[0].count).any()})
+                .withSetter(GopSetter)
+                .build());
+
+        addParameter(
+                DefineParam(mActualInputDelay, C2_PARAMKEY_INPUT_DELAY)
+                .withDefault(new C2PortActualDelayTuning::input(DEFAULT_B_FRAMES))
+                .withFields({C2F(mActualInputDelay, value).inRange(0, MAX_B_FRAMES)})
+                .calculatedAs(InputDelaySetter, mGop)
+                .build());
+
+        addParameter(
+                DefineParam(mFrameRate, C2_PARAMKEY_FRAME_RATE)
+                .withDefault(new C2StreamFrameRateInfo::output(0u, 30.))
+                // TODO: More restriction?
+                .withFields({C2F(mFrameRate, value).greaterThan(0.)})
+                .withSetter(Setter<decltype(*mFrameRate)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
+                .withDefault(new C2StreamBitrateInfo::output(0u, 64000))
+                .withFields({C2F(mBitrate, value).inRange(4096, 12000000)})
+                .withSetter(BitrateSetter)
+                .build());
+
+        addParameter(
+                DefineParam(mIntraRefresh, C2_PARAMKEY_INTRA_REFRESH)
+                .withDefault(new C2StreamIntraRefreshTuning::output(
+                        0u, C2Config::INTRA_REFRESH_DISABLED, 0.))
+                .withFields({
+                    C2F(mIntraRefresh, mode).oneOf({
+                        C2Config::INTRA_REFRESH_DISABLED, C2Config::INTRA_REFRESH_ARBITRARY }),
+                    C2F(mIntraRefresh, period).any()
+                })
+                .withSetter(IntraRefreshSetter)
+                .build());
+
+        addParameter(
+                DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
+                .withDefault(new C2StreamProfileLevelInfo::output(
+                        0u, PROFILE_AVC_CONSTRAINED_BASELINE, LEVEL_AVC_4_1))
+                .withFields({
+                    C2F(mProfileLevel, profile).oneOf({
+                        PROFILE_AVC_BASELINE,
+                        PROFILE_AVC_CONSTRAINED_BASELINE,
+                        PROFILE_AVC_MAIN,
+                    }),
+                    C2F(mProfileLevel, level).oneOf({
+                        LEVEL_AVC_1,
+                        LEVEL_AVC_1B,
+                        LEVEL_AVC_1_1,
+                        LEVEL_AVC_1_2,
+                        LEVEL_AVC_1_3,
+                        LEVEL_AVC_2,
+                        LEVEL_AVC_2_1,
+                        LEVEL_AVC_2_2,
+                        LEVEL_AVC_3,
+                        LEVEL_AVC_3_1,
+                        LEVEL_AVC_3_2,
+                        LEVEL_AVC_4,
+                        LEVEL_AVC_4_1,
+                        LEVEL_AVC_4_2,
+                        LEVEL_AVC_5,
+                    }),
+                })
+                .withSetter(ProfileLevelSetter, mSize, mFrameRate, mBitrate)
+                .build());
+
+        addParameter(
+                DefineParam(mRequestSync, C2_PARAMKEY_REQUEST_SYNC_FRAME)
+                .withDefault(new C2StreamRequestSyncFrameTuning::output(0u, C2_FALSE))
+                .withFields({C2F(mRequestSync, value).oneOf({ C2_FALSE, C2_TRUE }) })
+                .withSetter(Setter<decltype(*mRequestSync)>::NonStrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mSyncFramePeriod, C2_PARAMKEY_SYNC_FRAME_INTERVAL)
+                .withDefault(new C2StreamSyncFrameIntervalTuning::output(0u, 1000000))
+                .withFields({C2F(mSyncFramePeriod, value).any()})
+                .withSetter(Setter<decltype(*mSyncFramePeriod)>::StrictValueWithNoDeps)
+                .build());
+    }
+
+    static C2R InputDelaySetter(
+            bool mayBlock,
+            C2P<C2PortActualDelayTuning::input> &me,
+            const C2P<C2StreamGopTuning::output> &gop) {
+        (void)mayBlock;
+        uint32_t maxBframes = 0;
+        ParseGop(gop.v, nullptr, nullptr, &maxBframes);
+        me.set().value = maxBframes;
+        return C2R::Ok();
+    }
+
+    static C2R BitrateSetter(bool mayBlock, C2P<C2StreamBitrateInfo::output> &me) {
+        (void)mayBlock;
+        C2R res = C2R::Ok();
+        if (me.v.value <= 4096) {
+            me.set().value = 4096;
+        }
+        return res;
+    }
+
+    static C2R SizeSetter(bool mayBlock, const C2P<C2StreamPictureSizeInfo::input> &oldMe,
+                          C2P<C2StreamPictureSizeInfo::input> &me) {
+        (void)mayBlock;
+        C2R res = C2R::Ok();
+        if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
+            res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
+            me.set().width = oldMe.v.width;
+        }
+        if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
+            res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
+            me.set().height = oldMe.v.height;
+        }
+        return res;
+    }
+
+    static C2R ProfileLevelSetter(
+            bool mayBlock,
+            C2P<C2StreamProfileLevelInfo::output> &me,
+            const C2P<C2StreamPictureSizeInfo::input> &size,
+            const C2P<C2StreamFrameRateInfo::output> &frameRate,
+            const C2P<C2StreamBitrateInfo::output> &bitrate) {
+        (void)mayBlock;
+        if (!me.F(me.v.profile).supportsAtAll(me.v.profile)) {
+            me.set().profile = PROFILE_AVC_CONSTRAINED_BASELINE;
+        }
+
+        struct LevelLimits {
+            C2Config::level_t level;
+            float mbsPerSec;
+            uint64_t mbs;
+            uint32_t bitrate;
+        };
+        constexpr LevelLimits kLimits[] = {
+            { LEVEL_AVC_1,     1485,    99,     64000 },
+            // Decoder does not properly handle level 1b.
+            // { LEVEL_AVC_1B,    1485,   99,   128000 },
+            { LEVEL_AVC_1_1,   3000,   396,    192000 },
+            { LEVEL_AVC_1_2,   6000,   396,    384000 },
+            { LEVEL_AVC_1_3,  11880,   396,    768000 },
+            { LEVEL_AVC_2,    11880,   396,   2000000 },
+            { LEVEL_AVC_2_1,  19800,   792,   4000000 },
+            { LEVEL_AVC_2_2,  20250,  1620,   4000000 },
+            { LEVEL_AVC_3,    40500,  1620,  10000000 },
+            { LEVEL_AVC_3_1, 108000,  3600,  14000000 },
+            { LEVEL_AVC_3_2, 216000,  5120,  20000000 },
+            { LEVEL_AVC_4,   245760,  8192,  20000000 },
+            { LEVEL_AVC_4_1, 245760,  8192,  50000000 },
+            { LEVEL_AVC_4_2, 522240,  8704,  50000000 },
+            { LEVEL_AVC_5,   589824, 22080, 135000000 },
+        };
+
+        uint64_t mbs = uint64_t((size.v.width + 15) / 16) * ((size.v.height + 15) / 16);
+        float mbsPerSec = float(mbs) * frameRate.v.value;
+
+        // Check if the supplied level meets the MB / bitrate requirements. If
+        // not, update the level with the lowest level meeting the requirements.
+
+        bool found = false;
+        // By default needsUpdate = false in case the supplied level does meet
+        // the requirements. For Level 1b, we want to update the level anyway,
+        // so we set it to true in that case.
+        bool needsUpdate = (me.v.level == LEVEL_AVC_1B);
+        for (const LevelLimits &limit : kLimits) {
+            if (mbs <= limit.mbs && mbsPerSec <= limit.mbsPerSec &&
+                    bitrate.v.value <= limit.bitrate) {
+                // This is the lowest level that meets the requirements, and if
+                // we haven't seen the supplied level yet, that means we don't
+                // need the update.
+                if (needsUpdate) {
+                    ALOGD("Given level %x does not cover current configuration: "
+                          "adjusting to %x", me.v.level, limit.level);
+                    me.set().level = limit.level;
+                }
+                found = true;
+                break;
+            }
+            if (me.v.level == limit.level) {
+                // We break out of the loop when the lowest feasible level is
+                // found. The fact that we're here means that our level doesn't
+                // meet the requirement and needs to be updated.
+                needsUpdate = true;
+            }
+        }
+        if (!found) {
+            // We set to the highest supported level.
+            me.set().level = LEVEL_AVC_5;
+        }
+
+        return C2R::Ok();
+    }
+
+    static C2R IntraRefreshSetter(bool mayBlock, C2P<C2StreamIntraRefreshTuning::output> &me) {
+        (void)mayBlock;
+        C2R res = C2R::Ok();
+        if (me.v.period < 1) {
+            me.set().mode = C2Config::INTRA_REFRESH_DISABLED;
+            me.set().period = 0;
+        } else {
+            // only support arbitrary mode (cyclic in our case)
+            me.set().mode = C2Config::INTRA_REFRESH_ARBITRARY;
+        }
+        return res;
+    }
+
+    static C2R GopSetter(bool mayBlock, C2P<C2StreamGopTuning::output> &me) {
+        (void)mayBlock;
+        for (size_t i = 0; i < me.v.flexCount(); ++i) {
+            const C2GopLayerStruct &layer = me.v.m.values[0];
+            if (layer.type_ == C2Config::picture_type_t(P_FRAME | B_FRAME)
+                    && layer.count > MAX_B_FRAMES) {
+                me.set().m.values[i].count = MAX_B_FRAMES;
+            }
+        }
+        return C2R::Ok();
+    }
+
+    IV_PROFILE_T getProfile_l() const {
+        switch (mProfileLevel->profile) {
+        case PROFILE_AVC_CONSTRAINED_BASELINE:  [[fallthrough]];
+        case PROFILE_AVC_BASELINE: return IV_PROFILE_BASE;
+        case PROFILE_AVC_MAIN:     return IV_PROFILE_MAIN;
+        default:
+            ALOGD("Unrecognized profile: %x", mProfileLevel->profile);
+            return IV_PROFILE_DEFAULT;
+        }
+    }
+
+    UWORD32 getLevel_l() const {
+        struct Level {
+            C2Config::level_t c2Level;
+            UWORD32 avcLevel;
+        };
+        constexpr Level levels[] = {
+            { LEVEL_AVC_1,   10 },
+            { LEVEL_AVC_1B,   9 },
+            { LEVEL_AVC_1_1, 11 },
+            { LEVEL_AVC_1_2, 12 },
+            { LEVEL_AVC_1_3, 13 },
+            { LEVEL_AVC_2,   20 },
+            { LEVEL_AVC_2_1, 21 },
+            { LEVEL_AVC_2_2, 22 },
+            { LEVEL_AVC_3,   30 },
+            { LEVEL_AVC_3_1, 31 },
+            { LEVEL_AVC_3_2, 32 },
+            { LEVEL_AVC_4,   40 },
+            { LEVEL_AVC_4_1, 41 },
+            { LEVEL_AVC_4_2, 42 },
+            { LEVEL_AVC_5,   50 },
+        };
+        for (const Level &level : levels) {
+            if (mProfileLevel->level == level.c2Level) {
+                return level.avcLevel;
+            }
+        }
+        ALOGD("Unrecognized level: %x", mProfileLevel->level);
+        return 41;
+    }
+
+    uint32_t getSyncFramePeriod_l() const {
+        if (mSyncFramePeriod->value < 0 || mSyncFramePeriod->value == INT64_MAX) {
+            return 0;
+        }
+        double period = mSyncFramePeriod->value / 1e6 * mFrameRate->value;
+        return (uint32_t)c2_max(c2_min(period + 0.5, double(UINT32_MAX)), 1.);
+    }
+
+    // unsafe getters
+    std::shared_ptr<C2StreamPictureSizeInfo::input> getSize_l() const { return mSize; }
+    std::shared_ptr<C2StreamIntraRefreshTuning::output> getIntraRefresh_l() const { return mIntraRefresh; }
+    std::shared_ptr<C2StreamFrameRateInfo::output> getFrameRate_l() const { return mFrameRate; }
+    std::shared_ptr<C2StreamBitrateInfo::output> getBitrate_l() const { return mBitrate; }
+    std::shared_ptr<C2StreamRequestSyncFrameTuning::output> getRequestSync_l() const { return mRequestSync; }
+    std::shared_ptr<C2StreamGopTuning::output> getGop_l() const { return mGop; }
+
+private:
+    std::shared_ptr<C2StreamUsageTuning::input> mUsage;
+    std::shared_ptr<C2StreamPictureSizeInfo::input> mSize;
+    std::shared_ptr<C2StreamFrameRateInfo::output> mFrameRate;
+    std::shared_ptr<C2StreamRequestSyncFrameTuning::output> mRequestSync;
+    std::shared_ptr<C2StreamIntraRefreshTuning::output> mIntraRefresh;
+    std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
+    std::shared_ptr<C2StreamProfileLevelInfo::output> mProfileLevel;
+    std::shared_ptr<C2StreamSyncFrameIntervalTuning::output> mSyncFramePeriod;
+    std::shared_ptr<C2StreamGopTuning::output> mGop;
+};
+
+#define ive_api_function  ih264e_api_function
+
+namespace {
+
+// From external/libavc/encoder/ih264e_bitstream.h
+constexpr uint32_t MIN_STREAM_SIZE = 0x800;
+
+static size_t GetCPUCoreCount() {
+    long cpuCoreCount = 1;
+#if defined(_SC_NPROCESSORS_ONLN)
+    cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
+#else
+    // _SC_NPROC_ONLN must be defined...
+    cpuCoreCount = sysconf(_SC_NPROC_ONLN);
+#endif
+    CHECK(cpuCoreCount >= 1);
+    ALOGV("Number of CPU cores: %ld", cpuCoreCount);
+    return (size_t)cpuCoreCount;
+}
+
+}  // namespace
+
+C2SoftAvcEnc::C2SoftAvcEnc(
+        const char *name, c2_node_id_t id, const std::shared_ptr<IntfImpl> &intfImpl)
+    : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+      mIntf(intfImpl),
+      mIvVideoColorFormat(IV_YUV_420P),
+      mAVCEncProfile(IV_PROFILE_BASE),
+      mAVCEncLevel(41),
+      mStarted(false),
+      mSawInputEOS(false),
+      mSignalledError(false),
+      mCodecCtx(nullptr),
+      mOutBlock(nullptr),
+      // TODO: output buffer size
+      mOutBufferSize(524288) {
+
+    // If dump is enabled, then open create an empty file
+    GENERATE_FILE_NAMES();
+    CREATE_DUMP_FILE(mInFile);
+    CREATE_DUMP_FILE(mOutFile);
+
+    initEncParams();
+}
+
+C2SoftAvcEnc::~C2SoftAvcEnc() {
+    onRelease();
+}
+
+c2_status_t C2SoftAvcEnc::onInit() {
+    return C2_OK;
+}
+
+c2_status_t C2SoftAvcEnc::onStop() {
+    return C2_OK;
+}
+
+void C2SoftAvcEnc::onReset() {
+    // TODO: use IVE_CMD_CTL_RESET?
+    releaseEncoder();
+    if (mOutBlock) {
+        mOutBlock.reset();
+    }
+    initEncParams();
+}
+
+void C2SoftAvcEnc::onRelease() {
+    releaseEncoder();
+    if (mOutBlock) {
+        mOutBlock.reset();
+    }
+}
+
+c2_status_t C2SoftAvcEnc::onFlush_sm() {
+    // TODO: use IVE_CMD_CTL_FLUSH?
+    return C2_OK;
+}
+
+void  C2SoftAvcEnc::initEncParams() {
+    mCodecCtx = nullptr;
+    mMemRecords = nullptr;
+    mNumMemRecords = DEFAULT_MEM_REC_CNT;
+    mHeaderGenerated = 0;
+    mNumCores = GetCPUCoreCount();
+    mArch = DEFAULT_ARCH;
+    mSliceMode = DEFAULT_SLICE_MODE;
+    mSliceParam = DEFAULT_SLICE_PARAM;
+    mHalfPelEnable = DEFAULT_HPEL;
+    mIInterval = DEFAULT_I_INTERVAL;
+    mIDRInterval = DEFAULT_IDR_INTERVAL;
+    mDisableDeblkLevel = DEFAULT_DISABLE_DEBLK_LEVEL;
+    mEnableFastSad = DEFAULT_ENABLE_FAST_SAD;
+    mEnableAltRef = DEFAULT_ENABLE_ALT_REF;
+    mEncSpeed = DEFAULT_ENC_SPEED;
+    mIntra4x4 = DEFAULT_INTRA4x4;
+    mConstrainedIntraFlag = DEFAULT_CONSTRAINED_INTRA;
+    mPSNREnable = DEFAULT_PSNR_ENABLE;
+    mReconEnable = DEFAULT_RECON_ENABLE;
+    mEntropyMode = DEFAULT_ENTROPY_MODE;
+    mBframes = DEFAULT_B_FRAMES;
+
+    gettimeofday(&mTimeStart, nullptr);
+    gettimeofday(&mTimeEnd, nullptr);
+}
+
+c2_status_t C2SoftAvcEnc::setDimensions() {
+    ive_ctl_set_dimensions_ip_t s_dimensions_ip;
+    ive_ctl_set_dimensions_op_t s_dimensions_op;
+    IV_STATUS_T status;
+
+    s_dimensions_ip.e_cmd = IVE_CMD_VIDEO_CTL;
+    s_dimensions_ip.e_sub_cmd = IVE_CMD_CTL_SET_DIMENSIONS;
+    s_dimensions_ip.u4_ht = mSize->height;
+    s_dimensions_ip.u4_wd = mSize->width;
+
+    s_dimensions_ip.u4_timestamp_high = -1;
+    s_dimensions_ip.u4_timestamp_low = -1;
+
+    s_dimensions_ip.u4_size = sizeof(ive_ctl_set_dimensions_ip_t);
+    s_dimensions_op.u4_size = sizeof(ive_ctl_set_dimensions_op_t);
+
+    status = ive_api_function(mCodecCtx, &s_dimensions_ip, &s_dimensions_op);
+    if (status != IV_SUCCESS) {
+        ALOGE("Unable to set frame dimensions = 0x%x\n",
+                s_dimensions_op.u4_error_code);
+        return C2_CORRUPTED;
+    }
+    return C2_OK;
+}
+
+c2_status_t C2SoftAvcEnc::setNumCores() {
+    IV_STATUS_T status;
+    ive_ctl_set_num_cores_ip_t s_num_cores_ip;
+    ive_ctl_set_num_cores_op_t s_num_cores_op;
+    s_num_cores_ip.e_cmd = IVE_CMD_VIDEO_CTL;
+    s_num_cores_ip.e_sub_cmd = IVE_CMD_CTL_SET_NUM_CORES;
+    s_num_cores_ip.u4_num_cores = MIN(mNumCores, CODEC_MAX_CORES);
+    s_num_cores_ip.u4_timestamp_high = -1;
+    s_num_cores_ip.u4_timestamp_low = -1;
+    s_num_cores_ip.u4_size = sizeof(ive_ctl_set_num_cores_ip_t);
+
+    s_num_cores_op.u4_size = sizeof(ive_ctl_set_num_cores_op_t);
+
+    status = ive_api_function(
+            mCodecCtx, (void *) &s_num_cores_ip, (void *) &s_num_cores_op);
+    if (status != IV_SUCCESS) {
+        ALOGE("Unable to set processor params = 0x%x\n",
+                s_num_cores_op.u4_error_code);
+        return C2_CORRUPTED;
+    }
+    return C2_OK;
+}
+
+c2_status_t C2SoftAvcEnc::setFrameRate() {
+    ive_ctl_set_frame_rate_ip_t s_frame_rate_ip;
+    ive_ctl_set_frame_rate_op_t s_frame_rate_op;
+    IV_STATUS_T status;
+
+    s_frame_rate_ip.e_cmd = IVE_CMD_VIDEO_CTL;
+    s_frame_rate_ip.e_sub_cmd = IVE_CMD_CTL_SET_FRAMERATE;
+
+    s_frame_rate_ip.u4_src_frame_rate = mFrameRate->value + 0.5;
+    s_frame_rate_ip.u4_tgt_frame_rate = mFrameRate->value + 0.5;
+
+    s_frame_rate_ip.u4_timestamp_high = -1;
+    s_frame_rate_ip.u4_timestamp_low = -1;
+
+    s_frame_rate_ip.u4_size = sizeof(ive_ctl_set_frame_rate_ip_t);
+    s_frame_rate_op.u4_size = sizeof(ive_ctl_set_frame_rate_op_t);
+
+    status = ive_api_function(mCodecCtx, &s_frame_rate_ip, &s_frame_rate_op);
+    if (status != IV_SUCCESS) {
+        ALOGE("Unable to set frame rate = 0x%x\n",
+                s_frame_rate_op.u4_error_code);
+        return C2_CORRUPTED;
+    }
+    return C2_OK;
+}
+
+c2_status_t C2SoftAvcEnc::setIpeParams() {
+    ive_ctl_set_ipe_params_ip_t s_ipe_params_ip;
+    ive_ctl_set_ipe_params_op_t s_ipe_params_op;
+    IV_STATUS_T status;
+
+    s_ipe_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
+    s_ipe_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_IPE_PARAMS;
+
+    s_ipe_params_ip.u4_enable_intra_4x4 = mIntra4x4;
+    s_ipe_params_ip.u4_enc_speed_preset = mEncSpeed;
+    s_ipe_params_ip.u4_constrained_intra_pred = mConstrainedIntraFlag;
+
+    s_ipe_params_ip.u4_timestamp_high = -1;
+    s_ipe_params_ip.u4_timestamp_low = -1;
+
+    s_ipe_params_ip.u4_size = sizeof(ive_ctl_set_ipe_params_ip_t);
+    s_ipe_params_op.u4_size = sizeof(ive_ctl_set_ipe_params_op_t);
+
+    status = ive_api_function(mCodecCtx, &s_ipe_params_ip, &s_ipe_params_op);
+    if (status != IV_SUCCESS) {
+        ALOGE("Unable to set ipe params = 0x%x\n",
+                s_ipe_params_op.u4_error_code);
+        return C2_CORRUPTED;
+    }
+    return C2_OK;
+}
+
+c2_status_t C2SoftAvcEnc::setBitRate() {
+    ive_ctl_set_bitrate_ip_t s_bitrate_ip;
+    ive_ctl_set_bitrate_op_t s_bitrate_op;
+    IV_STATUS_T status;
+
+    s_bitrate_ip.e_cmd = IVE_CMD_VIDEO_CTL;
+    s_bitrate_ip.e_sub_cmd = IVE_CMD_CTL_SET_BITRATE;
+
+    s_bitrate_ip.u4_target_bitrate = mBitrate->value;
+
+    s_bitrate_ip.u4_timestamp_high = -1;
+    s_bitrate_ip.u4_timestamp_low = -1;
+
+    s_bitrate_ip.u4_size = sizeof(ive_ctl_set_bitrate_ip_t);
+    s_bitrate_op.u4_size = sizeof(ive_ctl_set_bitrate_op_t);
+
+    status = ive_api_function(mCodecCtx, &s_bitrate_ip, &s_bitrate_op);
+    if (status != IV_SUCCESS) {
+        ALOGE("Unable to set bit rate = 0x%x\n", s_bitrate_op.u4_error_code);
+        return C2_CORRUPTED;
+    }
+    return C2_OK;
+}
+
+c2_status_t C2SoftAvcEnc::setFrameType(IV_PICTURE_CODING_TYPE_T e_frame_type) {
+    ive_ctl_set_frame_type_ip_t s_frame_type_ip;
+    ive_ctl_set_frame_type_op_t s_frame_type_op;
+    IV_STATUS_T status;
+    s_frame_type_ip.e_cmd = IVE_CMD_VIDEO_CTL;
+    s_frame_type_ip.e_sub_cmd = IVE_CMD_CTL_SET_FRAMETYPE;
+
+    s_frame_type_ip.e_frame_type = e_frame_type;
+
+    s_frame_type_ip.u4_timestamp_high = -1;
+    s_frame_type_ip.u4_timestamp_low = -1;
+
+    s_frame_type_ip.u4_size = sizeof(ive_ctl_set_frame_type_ip_t);
+    s_frame_type_op.u4_size = sizeof(ive_ctl_set_frame_type_op_t);
+
+    status = ive_api_function(mCodecCtx, &s_frame_type_ip, &s_frame_type_op);
+    if (status != IV_SUCCESS) {
+        ALOGE("Unable to set frame type = 0x%x\n",
+                s_frame_type_op.u4_error_code);
+        return C2_CORRUPTED;
+    }
+    return C2_OK;
+}
+
+c2_status_t C2SoftAvcEnc::setQp() {
+    ive_ctl_set_qp_ip_t s_qp_ip;
+    ive_ctl_set_qp_op_t s_qp_op;
+    IV_STATUS_T status;
+
+    s_qp_ip.e_cmd = IVE_CMD_VIDEO_CTL;
+    s_qp_ip.e_sub_cmd = IVE_CMD_CTL_SET_QP;
+
+    s_qp_ip.u4_i_qp = DEFAULT_I_QP;
+    s_qp_ip.u4_i_qp_max = DEFAULT_QP_MAX;
+    s_qp_ip.u4_i_qp_min = DEFAULT_QP_MIN;
+
+    s_qp_ip.u4_p_qp = DEFAULT_P_QP;
+    s_qp_ip.u4_p_qp_max = DEFAULT_QP_MAX;
+    s_qp_ip.u4_p_qp_min = DEFAULT_QP_MIN;
+
+    s_qp_ip.u4_b_qp = DEFAULT_P_QP;
+    s_qp_ip.u4_b_qp_max = DEFAULT_QP_MAX;
+    s_qp_ip.u4_b_qp_min = DEFAULT_QP_MIN;
+
+    s_qp_ip.u4_timestamp_high = -1;
+    s_qp_ip.u4_timestamp_low = -1;
+
+    s_qp_ip.u4_size = sizeof(ive_ctl_set_qp_ip_t);
+    s_qp_op.u4_size = sizeof(ive_ctl_set_qp_op_t);
+
+    status = ive_api_function(mCodecCtx, &s_qp_ip, &s_qp_op);
+    if (status != IV_SUCCESS) {
+        ALOGE("Unable to set qp 0x%x\n", s_qp_op.u4_error_code);
+        return C2_CORRUPTED;
+    }
+    return C2_OK;
+}
+
+c2_status_t C2SoftAvcEnc::setEncMode(IVE_ENC_MODE_T e_enc_mode) {
+    IV_STATUS_T status;
+    ive_ctl_set_enc_mode_ip_t s_enc_mode_ip;
+    ive_ctl_set_enc_mode_op_t s_enc_mode_op;
+
+    s_enc_mode_ip.e_cmd = IVE_CMD_VIDEO_CTL;
+    s_enc_mode_ip.e_sub_cmd = IVE_CMD_CTL_SET_ENC_MODE;
+
+    s_enc_mode_ip.e_enc_mode = e_enc_mode;
+
+    s_enc_mode_ip.u4_timestamp_high = -1;
+    s_enc_mode_ip.u4_timestamp_low = -1;
+
+    s_enc_mode_ip.u4_size = sizeof(ive_ctl_set_enc_mode_ip_t);
+    s_enc_mode_op.u4_size = sizeof(ive_ctl_set_enc_mode_op_t);
+
+    status = ive_api_function(mCodecCtx, &s_enc_mode_ip, &s_enc_mode_op);
+    if (status != IV_SUCCESS) {
+        ALOGE("Unable to set in header encode mode = 0x%x\n",
+                s_enc_mode_op.u4_error_code);
+        return C2_CORRUPTED;
+    }
+    return C2_OK;
+}
+
+c2_status_t C2SoftAvcEnc::setVbvParams() {
+    ive_ctl_set_vbv_params_ip_t s_vbv_ip;
+    ive_ctl_set_vbv_params_op_t s_vbv_op;
+    IV_STATUS_T status;
+
+    s_vbv_ip.e_cmd = IVE_CMD_VIDEO_CTL;
+    s_vbv_ip.e_sub_cmd = IVE_CMD_CTL_SET_VBV_PARAMS;
+
+    s_vbv_ip.u4_vbv_buf_size = 0;
+    s_vbv_ip.u4_vbv_buffer_delay = 1000;
+
+    s_vbv_ip.u4_timestamp_high = -1;
+    s_vbv_ip.u4_timestamp_low = -1;
+
+    s_vbv_ip.u4_size = sizeof(ive_ctl_set_vbv_params_ip_t);
+    s_vbv_op.u4_size = sizeof(ive_ctl_set_vbv_params_op_t);
+
+    status = ive_api_function(mCodecCtx, &s_vbv_ip, &s_vbv_op);
+    if (status != IV_SUCCESS) {
+        ALOGE("Unable to set VBV params = 0x%x\n", s_vbv_op.u4_error_code);
+        return C2_CORRUPTED;
+    }
+    return C2_OK;
+}
+
+c2_status_t C2SoftAvcEnc::setAirParams() {
+    ive_ctl_set_air_params_ip_t s_air_ip;
+    ive_ctl_set_air_params_op_t s_air_op;
+    IV_STATUS_T status;
+
+    s_air_ip.e_cmd = IVE_CMD_VIDEO_CTL;
+    s_air_ip.e_sub_cmd = IVE_CMD_CTL_SET_AIR_PARAMS;
+
+    s_air_ip.e_air_mode =
+        (mIntraRefresh->mode == C2Config::INTRA_REFRESH_DISABLED || mIntraRefresh->period < 1)
+            ? IVE_AIR_MODE_NONE : IVE_AIR_MODE_CYCLIC;
+    s_air_ip.u4_air_refresh_period = mIntraRefresh->period;
+
+    s_air_ip.u4_timestamp_high = -1;
+    s_air_ip.u4_timestamp_low = -1;
+
+    s_air_ip.u4_size = sizeof(ive_ctl_set_air_params_ip_t);
+    s_air_op.u4_size = sizeof(ive_ctl_set_air_params_op_t);
+
+    status = ive_api_function(mCodecCtx, &s_air_ip, &s_air_op);
+    if (status != IV_SUCCESS) {
+        ALOGE("Unable to set air params = 0x%x\n", s_air_op.u4_error_code);
+        return C2_CORRUPTED;
+    }
+    return C2_OK;
+}
+
+c2_status_t C2SoftAvcEnc::setMeParams() {
+    IV_STATUS_T status;
+    ive_ctl_set_me_params_ip_t s_me_params_ip;
+    ive_ctl_set_me_params_op_t s_me_params_op;
+
+    s_me_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
+    s_me_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_ME_PARAMS;
+
+    s_me_params_ip.u4_enable_fast_sad = mEnableFastSad;
+    s_me_params_ip.u4_enable_alt_ref = mEnableAltRef;
+
+    s_me_params_ip.u4_enable_hpel = mHalfPelEnable;
+    s_me_params_ip.u4_enable_qpel = DEFAULT_QPEL;
+    s_me_params_ip.u4_me_speed_preset = DEFAULT_ME_SPEED;
+    s_me_params_ip.u4_srch_rng_x = DEFAULT_SRCH_RNG_X;
+    s_me_params_ip.u4_srch_rng_y = DEFAULT_SRCH_RNG_Y;
+
+    s_me_params_ip.u4_timestamp_high = -1;
+    s_me_params_ip.u4_timestamp_low = -1;
+
+    s_me_params_ip.u4_size = sizeof(ive_ctl_set_me_params_ip_t);
+    s_me_params_op.u4_size = sizeof(ive_ctl_set_me_params_op_t);
+
+    status = ive_api_function(mCodecCtx, &s_me_params_ip, &s_me_params_op);
+    if (status != IV_SUCCESS) {
+        ALOGE("Unable to set me params = 0x%x\n", s_me_params_op.u4_error_code);
+        return C2_CORRUPTED;
+    }
+    return C2_OK;
+}
+
+c2_status_t C2SoftAvcEnc::setGopParams() {
+    IV_STATUS_T status;
+    ive_ctl_set_gop_params_ip_t s_gop_params_ip;
+    ive_ctl_set_gop_params_op_t s_gop_params_op;
+
+    s_gop_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
+    s_gop_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_GOP_PARAMS;
+
+    s_gop_params_ip.u4_i_frm_interval = mIInterval;
+    s_gop_params_ip.u4_idr_frm_interval = mIDRInterval;
+
+    s_gop_params_ip.u4_timestamp_high = -1;
+    s_gop_params_ip.u4_timestamp_low = -1;
+
+    s_gop_params_ip.u4_size = sizeof(ive_ctl_set_gop_params_ip_t);
+    s_gop_params_op.u4_size = sizeof(ive_ctl_set_gop_params_op_t);
+
+    status = ive_api_function(mCodecCtx, &s_gop_params_ip, &s_gop_params_op);
+    if (status != IV_SUCCESS) {
+        ALOGE("Unable to set GOP params = 0x%x\n",
+                s_gop_params_op.u4_error_code);
+        return C2_CORRUPTED;
+    }
+    return C2_OK;
+}
+
+c2_status_t C2SoftAvcEnc::setProfileParams() {
+    IntfImpl::Lock lock = mIntf->lock();
+
+    IV_STATUS_T status;
+    ive_ctl_set_profile_params_ip_t s_profile_params_ip;
+    ive_ctl_set_profile_params_op_t s_profile_params_op;
+
+    s_profile_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
+    s_profile_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_PROFILE_PARAMS;
+
+    s_profile_params_ip.e_profile = mIntf->getProfile_l();
+    if (s_profile_params_ip.e_profile == IV_PROFILE_BASE) {
+        s_profile_params_ip.u4_entropy_coding_mode = 0;
+    } else {
+        s_profile_params_ip.u4_entropy_coding_mode = 1;
+    }
+    s_profile_params_ip.u4_timestamp_high = -1;
+    s_profile_params_ip.u4_timestamp_low = -1;
+
+    s_profile_params_ip.u4_size = sizeof(ive_ctl_set_profile_params_ip_t);
+    s_profile_params_op.u4_size = sizeof(ive_ctl_set_profile_params_op_t);
+    lock.unlock();
+
+    status = ive_api_function(mCodecCtx, &s_profile_params_ip, &s_profile_params_op);
+    if (status != IV_SUCCESS) {
+        ALOGE("Unable to set profile params = 0x%x\n",
+                s_profile_params_op.u4_error_code);
+        return C2_CORRUPTED;
+    }
+    return C2_OK;
+}
+
+c2_status_t C2SoftAvcEnc::setDeblockParams() {
+    IV_STATUS_T status;
+    ive_ctl_set_deblock_params_ip_t s_deblock_params_ip;
+    ive_ctl_set_deblock_params_op_t s_deblock_params_op;
+
+    s_deblock_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
+    s_deblock_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_DEBLOCK_PARAMS;
+
+    s_deblock_params_ip.u4_disable_deblock_level = mDisableDeblkLevel;
+
+    s_deblock_params_ip.u4_timestamp_high = -1;
+    s_deblock_params_ip.u4_timestamp_low = -1;
+
+    s_deblock_params_ip.u4_size = sizeof(ive_ctl_set_deblock_params_ip_t);
+    s_deblock_params_op.u4_size = sizeof(ive_ctl_set_deblock_params_op_t);
+
+    status = ive_api_function(mCodecCtx, &s_deblock_params_ip, &s_deblock_params_op);
+    if (status != IV_SUCCESS) {
+        ALOGE("Unable to enable/disable deblock params = 0x%x\n",
+                s_deblock_params_op.u4_error_code);
+        return C2_CORRUPTED;
+    }
+    return C2_OK;
+}
+
+void C2SoftAvcEnc::logVersion() {
+    ive_ctl_getversioninfo_ip_t s_ctl_ip;
+    ive_ctl_getversioninfo_op_t s_ctl_op;
+    UWORD8 au1_buf[512];
+    IV_STATUS_T status;
+
+    s_ctl_ip.e_cmd = IVE_CMD_VIDEO_CTL;
+    s_ctl_ip.e_sub_cmd = IVE_CMD_CTL_GETVERSION;
+    s_ctl_ip.u4_size = sizeof(ive_ctl_getversioninfo_ip_t);
+    s_ctl_op.u4_size = sizeof(ive_ctl_getversioninfo_op_t);
+    s_ctl_ip.pu1_version = au1_buf;
+    s_ctl_ip.u4_version_bufsize = sizeof(au1_buf);
+
+    status = ive_api_function(mCodecCtx, (void *) &s_ctl_ip, (void *) &s_ctl_op);
+
+    if (status != IV_SUCCESS) {
+        ALOGE("Error in getting version: 0x%x", s_ctl_op.u4_error_code);
+    } else {
+        ALOGV("Ittiam encoder version: %s", (char *)s_ctl_ip.pu1_version);
+    }
+    return;
+}
+
+c2_status_t C2SoftAvcEnc::initEncoder() {
+    IV_STATUS_T status;
+    WORD32 level;
+
+    CHECK(!mStarted);
+
+    c2_status_t errType = C2_OK;
+
+    std::shared_ptr<C2StreamGopTuning::output> gop;
+    {
+        IntfImpl::Lock lock = mIntf->lock();
+        mSize = mIntf->getSize_l();
+        mBitrate = mIntf->getBitrate_l();
+        mFrameRate = mIntf->getFrameRate_l();
+        mIntraRefresh = mIntf->getIntraRefresh_l();
+        mAVCEncLevel = mIntf->getLevel_l();
+        mIInterval = mIntf->getSyncFramePeriod_l();
+        mIDRInterval = mIntf->getSyncFramePeriod_l();
+        gop = mIntf->getGop_l();
+    }
+    if (gop && gop->flexCount() > 0) {
+        uint32_t syncInterval = 1;
+        uint32_t iInterval = 1;
+        uint32_t maxBframes = 0;
+        ParseGop(*gop, &syncInterval, &iInterval, &maxBframes);
+        if (syncInterval > 0) {
+            ALOGD("Updating IDR interval from GOP: old %u new %u", mIDRInterval, syncInterval);
+            mIDRInterval = syncInterval;
+        }
+        if (iInterval > 0) {
+            ALOGD("Updating I interval from GOP: old %u new %u", mIInterval, iInterval);
+            mIInterval = iInterval;
+        }
+        if (mBframes != maxBframes) {
+            ALOGD("Updating max B frames from GOP: old %u new %u", mBframes, maxBframes);
+            mBframes = maxBframes;
+        }
+    }
+    uint32_t width = mSize->width;
+    uint32_t height = mSize->height;
+
+    mStride = width;
+
+    // TODO
+    mIvVideoColorFormat = IV_YUV_420P;
+
+    ALOGD("Params width %d height %d level %d colorFormat %d bframes %d", width,
+            height, mAVCEncLevel, mIvVideoColorFormat, mBframes);
+
+    /* Getting Number of MemRecords */
+    {
+        iv_num_mem_rec_ip_t s_num_mem_rec_ip;
+        iv_num_mem_rec_op_t s_num_mem_rec_op;
+
+        s_num_mem_rec_ip.u4_size = sizeof(iv_num_mem_rec_ip_t);
+        s_num_mem_rec_op.u4_size = sizeof(iv_num_mem_rec_op_t);
+
+        s_num_mem_rec_ip.e_cmd = IV_CMD_GET_NUM_MEM_REC;
+
+        status = ive_api_function(nullptr, &s_num_mem_rec_ip, &s_num_mem_rec_op);
+
+        if (status != IV_SUCCESS) {
+            ALOGE("Get number of memory records failed = 0x%x\n",
+                    s_num_mem_rec_op.u4_error_code);
+            return C2_CORRUPTED;
+        }
+
+        mNumMemRecords = s_num_mem_rec_op.u4_num_mem_rec;
+    }
+
+    /* Allocate array to hold memory records */
+    if (mNumMemRecords > SIZE_MAX / sizeof(iv_mem_rec_t)) {
+        ALOGE("requested memory size is too big.");
+        return C2_CORRUPTED;
+    }
+    mMemRecords = (iv_mem_rec_t *)malloc(mNumMemRecords * sizeof(iv_mem_rec_t));
+    if (nullptr == mMemRecords) {
+        ALOGE("Unable to allocate memory for hold memory records: Size %zu",
+                mNumMemRecords * sizeof(iv_mem_rec_t));
+        mSignalledError = true;
+        return C2_CORRUPTED;
+    }
+
+    {
+        iv_mem_rec_t *ps_mem_rec;
+        ps_mem_rec = mMemRecords;
+        for (size_t i = 0; i < mNumMemRecords; i++) {
+            ps_mem_rec->u4_size = sizeof(iv_mem_rec_t);
+            ps_mem_rec->pv_base = nullptr;
+            ps_mem_rec->u4_mem_size = 0;
+            ps_mem_rec->u4_mem_alignment = 0;
+            ps_mem_rec->e_mem_type = IV_NA_MEM_TYPE;
+
+            ps_mem_rec++;
+        }
+    }
+
+    /* Getting MemRecords Attributes */
+    {
+        iv_fill_mem_rec_ip_t s_fill_mem_rec_ip;
+        iv_fill_mem_rec_op_t s_fill_mem_rec_op;
+
+        s_fill_mem_rec_ip.u4_size = sizeof(iv_fill_mem_rec_ip_t);
+        s_fill_mem_rec_op.u4_size = sizeof(iv_fill_mem_rec_op_t);
+
+        s_fill_mem_rec_ip.e_cmd = IV_CMD_FILL_NUM_MEM_REC;
+        s_fill_mem_rec_ip.ps_mem_rec = mMemRecords;
+        s_fill_mem_rec_ip.u4_num_mem_rec = mNumMemRecords;
+        s_fill_mem_rec_ip.u4_max_wd = width;
+        s_fill_mem_rec_ip.u4_max_ht = height;
+        s_fill_mem_rec_ip.u4_max_level = mAVCEncLevel;
+        s_fill_mem_rec_ip.e_color_format = DEFAULT_INP_COLOR_FORMAT;
+        s_fill_mem_rec_ip.u4_max_ref_cnt = DEFAULT_MAX_REF_FRM;
+        s_fill_mem_rec_ip.u4_max_reorder_cnt = DEFAULT_MAX_REORDER_FRM;
+        s_fill_mem_rec_ip.u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X;
+        s_fill_mem_rec_ip.u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y;
+
+        status = ive_api_function(nullptr, &s_fill_mem_rec_ip, &s_fill_mem_rec_op);
+
+        if (status != IV_SUCCESS) {
+            ALOGE("Fill memory records failed = 0x%x\n",
+                    s_fill_mem_rec_op.u4_error_code);
+            return C2_CORRUPTED;
+        }
+    }
+
+    /* Allocating Memory for Mem Records */
+    {
+        WORD32 total_size;
+        iv_mem_rec_t *ps_mem_rec;
+        total_size = 0;
+        ps_mem_rec = mMemRecords;
+
+        for (size_t i = 0; i < mNumMemRecords; i++) {
+            ps_mem_rec->pv_base = ive_aligned_malloc(
+                    ps_mem_rec->u4_mem_alignment, ps_mem_rec->u4_mem_size);
+            if (ps_mem_rec->pv_base == nullptr) {
+                ALOGE("Allocation failure for mem record id %zu size %u\n", i,
+                        ps_mem_rec->u4_mem_size);
+                return C2_CORRUPTED;
+
+            }
+            total_size += ps_mem_rec->u4_mem_size;
+
+            ps_mem_rec++;
+        }
+    }
+
+    /* Codec Instance Creation */
+    {
+        ive_init_ip_t s_init_ip;
+        ive_init_op_t s_init_op;
+
+        mCodecCtx = (iv_obj_t *)mMemRecords[0].pv_base;
+        mCodecCtx->u4_size = sizeof(iv_obj_t);
+        mCodecCtx->pv_fxns = (void *)ive_api_function;
+
+        s_init_ip.u4_size = sizeof(ive_init_ip_t);
+        s_init_op.u4_size = sizeof(ive_init_op_t);
+
+        s_init_ip.e_cmd = IV_CMD_INIT;
+        s_init_ip.u4_num_mem_rec = mNumMemRecords;
+        s_init_ip.ps_mem_rec = mMemRecords;
+        s_init_ip.u4_max_wd = width;
+        s_init_ip.u4_max_ht = height;
+        s_init_ip.u4_max_ref_cnt = DEFAULT_MAX_REF_FRM;
+        s_init_ip.u4_max_reorder_cnt = DEFAULT_MAX_REORDER_FRM;
+        s_init_ip.u4_max_level = mAVCEncLevel;
+        s_init_ip.e_inp_color_fmt = mIvVideoColorFormat;
+
+        if (mReconEnable || mPSNREnable) {
+            s_init_ip.u4_enable_recon = 1;
+        } else {
+            s_init_ip.u4_enable_recon = 0;
+        }
+        s_init_ip.e_recon_color_fmt = DEFAULT_RECON_COLOR_FORMAT;
+        s_init_ip.e_rc_mode = DEFAULT_RC_MODE;
+        s_init_ip.u4_max_framerate = DEFAULT_MAX_FRAMERATE;
+        s_init_ip.u4_max_bitrate = DEFAULT_MAX_BITRATE;
+        s_init_ip.u4_num_bframes = mBframes;
+        s_init_ip.e_content_type = IV_PROGRESSIVE;
+        s_init_ip.u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X;
+        s_init_ip.u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y;
+        s_init_ip.e_slice_mode = mSliceMode;
+        s_init_ip.u4_slice_param = mSliceParam;
+        s_init_ip.e_arch = mArch;
+        s_init_ip.e_soc = DEFAULT_SOC;
+
+        status = ive_api_function(mCodecCtx, &s_init_ip, &s_init_op);
+
+        if (status != IV_SUCCESS) {
+            ALOGE("Init encoder failed = 0x%x\n", s_init_op.u4_error_code);
+            return C2_CORRUPTED;
+        }
+    }
+
+    /* Get Codec Version */
+    logVersion();
+
+    /* set processor details */
+    setNumCores();
+
+    /* Video control Set Frame dimensions */
+    setDimensions();
+
+    /* Video control Set Frame rates */
+    setFrameRate();
+
+    /* Video control Set IPE Params */
+    setIpeParams();
+
+    /* Video control Set Bitrate */
+    setBitRate();
+
+    /* Video control Set QP */
+    setQp();
+
+    /* Video control Set AIR params */
+    setAirParams();
+
+    /* Video control Set VBV params */
+    setVbvParams();
+
+    /* Video control Set Motion estimation params */
+    setMeParams();
+
+    /* Video control Set GOP params */
+    setGopParams();
+
+    /* Video control Set Deblock params */
+    setDeblockParams();
+
+    /* Video control Set Profile params */
+    setProfileParams();
+
+    /* Video control Set in Encode header mode */
+    setEncMode(IVE_ENC_MODE_HEADER);
+
+    ALOGV("init_codec successfull");
+
+    mSpsPpsHeaderReceived = false;
+    mStarted = true;
+
+    return C2_OK;
+}
+
+c2_status_t C2SoftAvcEnc::releaseEncoder() {
+    IV_STATUS_T status = IV_SUCCESS;
+    iv_retrieve_mem_rec_ip_t s_retrieve_mem_ip;
+    iv_retrieve_mem_rec_op_t s_retrieve_mem_op;
+    iv_mem_rec_t *ps_mem_rec;
+
+    if (!mStarted) {
+        return C2_OK;
+    }
+
+    s_retrieve_mem_ip.u4_size = sizeof(iv_retrieve_mem_rec_ip_t);
+    s_retrieve_mem_op.u4_size = sizeof(iv_retrieve_mem_rec_op_t);
+    s_retrieve_mem_ip.e_cmd = IV_CMD_RETRIEVE_MEMREC;
+    s_retrieve_mem_ip.ps_mem_rec = mMemRecords;
+
+    status = ive_api_function(mCodecCtx, &s_retrieve_mem_ip, &s_retrieve_mem_op);
+
+    if (status != IV_SUCCESS) {
+        ALOGE("Unable to retrieve memory records = 0x%x\n",
+                s_retrieve_mem_op.u4_error_code);
+        return C2_CORRUPTED;
+    }
+
+    /* Free memory records */
+    ps_mem_rec = mMemRecords;
+    for (size_t i = 0; i < s_retrieve_mem_op.u4_num_mem_rec_filled; i++) {
+        if (ps_mem_rec) ive_aligned_free(ps_mem_rec->pv_base);
+        else {
+            ALOGE("memory record is null.");
+            return C2_CORRUPTED;
+        }
+        ps_mem_rec++;
+    }
+
+    if (mMemRecords) free(mMemRecords);
+
+    // clear other pointers into the space being free()d
+    mCodecCtx = nullptr;
+
+    mStarted = false;
+
+    return C2_OK;
+}
+
+c2_status_t C2SoftAvcEnc::setEncodeArgs(
+        ive_video_encode_ip_t *ps_encode_ip,
+        ive_video_encode_op_t *ps_encode_op,
+        const C2GraphicView *const input,
+        uint8_t *base,
+        uint32_t capacity,
+        uint64_t workIndex) {
+    iv_raw_buf_t *ps_inp_raw_buf;
+    memset(ps_encode_ip, 0, sizeof(*ps_encode_ip));
+    memset(ps_encode_op, 0, sizeof(*ps_encode_op));
+
+    ps_inp_raw_buf = &ps_encode_ip->s_inp_buf;
+    ps_encode_ip->s_out_buf.pv_buf = base;
+    ps_encode_ip->s_out_buf.u4_bytes = 0;
+    ps_encode_ip->s_out_buf.u4_bufsize = capacity;
+    ps_encode_ip->u4_size = sizeof(ive_video_encode_ip_t);
+    ps_encode_op->u4_size = sizeof(ive_video_encode_op_t);
+
+    ps_encode_ip->e_cmd = IVE_CMD_VIDEO_ENCODE;
+    ps_encode_ip->pv_bufs = nullptr;
+    ps_encode_ip->pv_mb_info = nullptr;
+    ps_encode_ip->pv_pic_info = nullptr;
+    ps_encode_ip->u4_mb_info_type = 0;
+    ps_encode_ip->u4_pic_info_type = 0;
+    ps_encode_ip->u4_is_last = 0;
+    ps_encode_ip->u4_timestamp_high = workIndex >> 32;
+    ps_encode_ip->u4_timestamp_low = workIndex & 0xFFFFFFFF;
+    ps_encode_op->s_out_buf.pv_buf = nullptr;
+
+    /* Initialize color formats */
+    memset(ps_inp_raw_buf, 0, sizeof(iv_raw_buf_t));
+    ps_inp_raw_buf->u4_size = sizeof(iv_raw_buf_t);
+    ps_inp_raw_buf->e_color_fmt = mIvVideoColorFormat;
+    if (input == nullptr) {
+        if (mSawInputEOS) {
+            ps_encode_ip->u4_is_last = 1;
+        }
+        return C2_OK;
+    }
+
+    if (input->width() < mSize->width ||
+        input->height() < mSize->height) {
+        /* Expect width height to be configured */
+        ALOGW("unexpected Capacity Aspect %d(%d) x %d(%d)", input->width(),
+              mSize->width, input->height(), mSize->height);
+        return C2_BAD_VALUE;
+    }
+    ALOGV("width = %d, height = %d", input->width(), input->height());
+    const C2PlanarLayout &layout = input->layout();
+    uint8_t *yPlane = const_cast<uint8_t *>(input->data()[C2PlanarLayout::PLANE_Y]);
+    uint8_t *uPlane = const_cast<uint8_t *>(input->data()[C2PlanarLayout::PLANE_U]);
+    uint8_t *vPlane = const_cast<uint8_t *>(input->data()[C2PlanarLayout::PLANE_V]);
+    int32_t yStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
+    int32_t uStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
+    int32_t vStride = layout.planes[C2PlanarLayout::PLANE_V].rowInc;
+
+    uint32_t width = mSize->width;
+    uint32_t height = mSize->height;
+    // width and height are always even (as block size is 16x16)
+    CHECK_EQ((width & 1u), 0u);
+    CHECK_EQ((height & 1u), 0u);
+    size_t yPlaneSize = width * height;
+
+    switch (layout.type) {
+        case C2PlanarLayout::TYPE_RGB:
+            [[fallthrough]];
+        case C2PlanarLayout::TYPE_RGBA: {
+            ALOGV("yPlaneSize = %zu", yPlaneSize);
+            MemoryBlock conversionBuffer = mConversionBuffers.fetch(yPlaneSize * 3 / 2);
+            mConversionBuffersInUse.emplace(conversionBuffer.data(), conversionBuffer);
+            yPlane = conversionBuffer.data();
+            uPlane = yPlane + yPlaneSize;
+            vPlane = uPlane + yPlaneSize / 4;
+            yStride = width;
+            uStride = vStride = yStride / 2;
+            ConvertRGBToPlanarYUV(yPlane, yStride, height, conversionBuffer.size(), *input);
+            break;
+        }
+        case C2PlanarLayout::TYPE_YUV: {
+            if (!IsYUV420(*input)) {
+                ALOGE("input is not YUV420");
+                return C2_BAD_VALUE;
+            }
+
+            if (layout.planes[layout.PLANE_Y].colInc == 1
+                    && layout.planes[layout.PLANE_U].colInc == 1
+                    && layout.planes[layout.PLANE_V].colInc == 1
+                    && uStride == vStride
+                    && yStride == 2 * vStride) {
+                // I420 compatible - already set up above
+                break;
+            }
+
+            // copy to I420
+            yStride = width;
+            uStride = vStride = yStride / 2;
+            MemoryBlock conversionBuffer = mConversionBuffers.fetch(yPlaneSize * 3 / 2);
+            mConversionBuffersInUse.emplace(conversionBuffer.data(), conversionBuffer);
+            MediaImage2 img = CreateYUV420PlanarMediaImage2(width, height, yStride, height);
+            status_t err = ImageCopy(conversionBuffer.data(), &img, *input);
+            if (err != OK) {
+                ALOGE("Buffer conversion failed: %d", err);
+                return C2_BAD_VALUE;
+            }
+            yPlane = conversionBuffer.data();
+            uPlane = yPlane + yPlaneSize;
+            vPlane = uPlane + yPlaneSize / 4;
+            break;
+
+        }
+
+        case C2PlanarLayout::TYPE_YUVA:
+            ALOGE("YUVA plane type is not supported");
+            return C2_BAD_VALUE;
+
+        default:
+            ALOGE("Unrecognized plane type: %d", layout.type);
+            return C2_BAD_VALUE;
+    }
+
+    switch (mIvVideoColorFormat) {
+        case IV_YUV_420P:
+        {
+            // input buffer is supposed to be const but Ittiam API wants bare pointer.
+            ps_inp_raw_buf->apv_bufs[0] = yPlane;
+            ps_inp_raw_buf->apv_bufs[1] = uPlane;
+            ps_inp_raw_buf->apv_bufs[2] = vPlane;
+
+            ps_inp_raw_buf->au4_wd[0] = input->width();
+            ps_inp_raw_buf->au4_wd[1] = input->width() / 2;
+            ps_inp_raw_buf->au4_wd[2] = input->width() / 2;
+
+            ps_inp_raw_buf->au4_ht[0] = input->height();
+            ps_inp_raw_buf->au4_ht[1] = input->height() / 2;
+            ps_inp_raw_buf->au4_ht[2] = input->height() / 2;
+
+            ps_inp_raw_buf->au4_strd[0] = yStride;
+            ps_inp_raw_buf->au4_strd[1] = uStride;
+            ps_inp_raw_buf->au4_strd[2] = vStride;
+            break;
+        }
+
+        case IV_YUV_422ILE:
+        {
+            // TODO
+            // ps_inp_raw_buf->apv_bufs[0] = pu1_buf;
+            // ps_inp_raw_buf->au4_wd[0] = mWidth * 2;
+            // ps_inp_raw_buf->au4_ht[0] = mHeight;
+            // ps_inp_raw_buf->au4_strd[0] = mStride * 2;
+            break;
+        }
+
+        case IV_YUV_420SP_UV:
+        case IV_YUV_420SP_VU:
+        default:
+        {
+            ps_inp_raw_buf->apv_bufs[0] = yPlane;
+            ps_inp_raw_buf->apv_bufs[1] = uPlane;
+
+            ps_inp_raw_buf->au4_wd[0] = input->width();
+            ps_inp_raw_buf->au4_wd[1] = input->width();
+
+            ps_inp_raw_buf->au4_ht[0] = input->height();
+            ps_inp_raw_buf->au4_ht[1] = input->height() / 2;
+
+            ps_inp_raw_buf->au4_strd[0] = yStride;
+            ps_inp_raw_buf->au4_strd[1] = uStride;
+            break;
+        }
+    }
+    return C2_OK;
+}
+
+void C2SoftAvcEnc::finishWork(uint64_t workIndex, const std::unique_ptr<C2Work> &work,
+                              ive_video_encode_op_t *ps_encode_op) {
+    std::shared_ptr<C2Buffer> buffer =
+            createLinearBuffer(mOutBlock, 0, ps_encode_op->s_out_buf.u4_bytes);
+    if (IV_IDR_FRAME == ps_encode_op->u4_encoded_frame_type) {
+        ALOGV("IDR frame produced");
+        buffer->setInfo(std::make_shared<C2StreamPictureTypeMaskInfo::output>(
+                0u /* stream id */, C2Config::SYNC_FRAME));
+    }
+    mOutBlock = nullptr;
+
+    auto fillWork = [buffer](const std::unique_ptr<C2Work> &work) {
+        work->worklets.front()->output.flags = (C2FrameData::flags_t)0;
+        work->worklets.front()->output.buffers.clear();
+        work->worklets.front()->output.buffers.push_back(buffer);
+        work->worklets.front()->output.ordinal = work->input.ordinal;
+        work->workletsProcessed = 1u;
+    };
+    if (work && c2_cntr64_t(workIndex) == work->input.ordinal.frameIndex) {
+        fillWork(work);
+        if (mSawInputEOS) {
+            work->worklets.front()->output.flags = C2FrameData::FLAG_END_OF_STREAM;
+        }
+    } else {
+        finish(workIndex, fillWork);
+    }
+}
+
+void C2SoftAvcEnc::process(
+        const std::unique_ptr<C2Work> &work,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    // Initialize output work
+    work->result = C2_OK;
+    work->workletsProcessed = 0u;
+    work->worklets.front()->output.flags = work->input.flags;
+
+    IV_STATUS_T status;
+    WORD32 timeDelay = 0;
+    WORD32 timeTaken = 0;
+    uint64_t workIndex = work->input.ordinal.frameIndex.peekull();
+
+    // Initialize encoder if not already initialized
+    if (mCodecCtx == nullptr) {
+        if (C2_OK != initEncoder()) {
+            ALOGE("Failed to initialize encoder");
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            work->workletsProcessed = 1u;
+            return;
+        }
+    }
+    if (mSignalledError) {
+        return;
+    }
+    // while (!mSawOutputEOS && !outQueue.empty()) {
+    c2_status_t error;
+    ive_video_encode_ip_t s_encode_ip;
+    ive_video_encode_op_t s_encode_op;
+    memset(&s_encode_op, 0, sizeof(s_encode_op));
+
+    if (!mSpsPpsHeaderReceived) {
+        constexpr uint32_t kHeaderLength = MIN_STREAM_SIZE;
+        uint8_t header[kHeaderLength];
+        error = setEncodeArgs(
+                &s_encode_ip, &s_encode_op, nullptr, header, kHeaderLength, workIndex);
+        if (error != C2_OK) {
+            ALOGE("setEncodeArgs failed: %d", error);
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            work->workletsProcessed = 1u;
+            return;
+        }
+        status = ive_api_function(mCodecCtx, &s_encode_ip, &s_encode_op);
+
+        if (IV_SUCCESS != status) {
+            ALOGE("Encode header failed = 0x%x\n",
+                    s_encode_op.u4_error_code);
+            work->workletsProcessed = 1u;
+            return;
+        } else {
+            ALOGV("Bytes Generated in header %d\n",
+                    s_encode_op.s_out_buf.u4_bytes);
+        }
+
+        mSpsPpsHeaderReceived = true;
+
+        std::unique_ptr<C2StreamInitDataInfo::output> csd =
+            C2StreamInitDataInfo::output::AllocUnique(s_encode_op.s_out_buf.u4_bytes, 0u);
+        if (!csd) {
+            ALOGE("CSD allocation failed");
+            mSignalledError = true;
+            work->result = C2_NO_MEMORY;
+            work->workletsProcessed = 1u;
+            return;
+        }
+        memcpy(csd->m.value, header, s_encode_op.s_out_buf.u4_bytes);
+        work->worklets.front()->output.configUpdate.push_back(std::move(csd));
+
+        DUMP_TO_FILE(
+                mOutFile, csd->m.value, csd->flexCount());
+        if (work->input.buffers.empty()) {
+            work->workletsProcessed = 1u;
+            return;
+        }
+    }
+
+    // handle dynamic config parameters
+    {
+        IntfImpl::Lock lock = mIntf->lock();
+        std::shared_ptr<C2StreamIntraRefreshTuning::output> intraRefresh = mIntf->getIntraRefresh_l();
+        std::shared_ptr<C2StreamBitrateInfo::output> bitrate = mIntf->getBitrate_l();
+        std::shared_ptr<C2StreamRequestSyncFrameTuning::output> requestSync = mIntf->getRequestSync_l();
+        lock.unlock();
+
+        if (bitrate != mBitrate) {
+            mBitrate = bitrate;
+            setBitRate();
+        }
+
+        if (intraRefresh != mIntraRefresh) {
+            mIntraRefresh = intraRefresh;
+            setAirParams();
+        }
+
+        if (requestSync != mRequestSync) {
+            // we can handle IDR immediately
+            if (requestSync->value) {
+                // unset request
+                C2StreamRequestSyncFrameTuning::output clearSync(0u, C2_FALSE);
+                std::vector<std::unique_ptr<C2SettingResult>> failures;
+                mIntf->config({ &clearSync }, C2_MAY_BLOCK, &failures);
+                ALOGV("Got sync request");
+                setFrameType(IV_IDR_FRAME);
+            }
+            mRequestSync = requestSync;
+        }
+    }
+
+    if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
+        mSawInputEOS = true;
+    }
+
+    /* In normal mode, store inputBufferInfo and this will be returned
+       when encoder consumes this input */
+    // if (!mInputDataIsMeta && (inputBufferInfo != NULL)) {
+    //     for (size_t i = 0; i < MAX_INPUT_BUFFER_HEADERS; i++) {
+    //         if (NULL == mInputBufferInfo[i]) {
+    //             mInputBufferInfo[i] = inputBufferInfo;
+    //             break;
+    //         }
+    //     }
+    // }
+    std::shared_ptr<const C2GraphicView> view;
+    std::shared_ptr<C2Buffer> inputBuffer;
+    if (!work->input.buffers.empty()) {
+        inputBuffer = work->input.buffers[0];
+        view = std::make_shared<const C2GraphicView>(
+                inputBuffer->data().graphicBlocks().front().map().get());
+        if (view->error() != C2_OK) {
+            ALOGE("graphic view map err = %d", view->error());
+            work->workletsProcessed = 1u;
+            return;
+        }
+    }
+
+    do {
+        if (mSawInputEOS && work->input.buffers.empty()) break;
+        if (!mOutBlock) {
+            C2MemoryUsage usage = {C2MemoryUsage::CPU_READ,
+                                   C2MemoryUsage::CPU_WRITE};
+            // TODO: error handling, proper usage, etc.
+            c2_status_t err =
+                pool->fetchLinearBlock(mOutBufferSize, usage, &mOutBlock);
+            if (err != C2_OK) {
+                ALOGE("fetch linear block err = %d", err);
+                work->result = err;
+                work->workletsProcessed = 1u;
+                return;
+            }
+        }
+        C2WriteView wView = mOutBlock->map().get();
+        if (wView.error() != C2_OK) {
+            ALOGE("write view map err = %d", wView.error());
+            work->result = wView.error();
+            work->workletsProcessed = 1u;
+            return;
+        }
+
+        error = setEncodeArgs(
+                &s_encode_ip, &s_encode_op, view.get(), wView.base(), wView.capacity(), workIndex);
+        if (error != C2_OK) {
+            ALOGE("setEncodeArgs failed : %d", error);
+            mSignalledError = true;
+            work->result = error;
+            work->workletsProcessed = 1u;
+            return;
+        }
+
+        // DUMP_TO_FILE(
+        //         mInFile, s_encode_ip.s_inp_buf.apv_bufs[0],
+        //         (mHeight * mStride * 3 / 2));
+
+        GETTIME(&mTimeStart, nullptr);
+        /* Compute time elapsed between end of previous decode()
+         * to start of current decode() */
+        TIME_DIFF(mTimeEnd, mTimeStart, timeDelay);
+        status = ive_api_function(mCodecCtx, &s_encode_ip, &s_encode_op);
+
+        if (IV_SUCCESS != status) {
+            if ((s_encode_op.u4_error_code & 0xFF) == IH264E_BITSTREAM_BUFFER_OVERFLOW) {
+                // TODO: use IVE_CMD_CTL_GETBUFINFO for proper max input size?
+                mOutBufferSize *= 2;
+                mOutBlock.reset();
+                continue;
+            }
+            ALOGE("Encode Frame failed = 0x%x\n",
+                    s_encode_op.u4_error_code);
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            work->workletsProcessed = 1u;
+            return;
+        }
+    } while (IV_SUCCESS != status);
+
+    // Hold input buffer reference
+    if (inputBuffer) {
+        mBuffers[s_encode_ip.s_inp_buf.apv_bufs[0]] = inputBuffer;
+    }
+
+    GETTIME(&mTimeEnd, nullptr);
+    /* Compute time taken for decode() */
+    TIME_DIFF(mTimeStart, mTimeEnd, timeTaken);
+
+    ALOGV("timeTaken=%6d delay=%6d numBytes=%6d", timeTaken, timeDelay,
+            s_encode_op.s_out_buf.u4_bytes);
+
+    void *freed = s_encode_op.s_inp_buf.apv_bufs[0];
+    /* If encoder frees up an input buffer, mark it as free */
+    if (freed != nullptr) {
+        if (mBuffers.count(freed) == 0u) {
+            ALOGD("buffer not tracked");
+        } else {
+            // Release input buffer reference
+            mBuffers.erase(freed);
+            mConversionBuffersInUse.erase(freed);
+        }
+    }
+
+    if (s_encode_op.output_present) {
+        if (!s_encode_op.s_out_buf.u4_bytes) {
+            ALOGE("Error: Output present but bytes generated is zero");
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            work->workletsProcessed = 1u;
+            return;
+        }
+        uint64_t workId = ((uint64_t)s_encode_op.u4_timestamp_high << 32) |
+                      s_encode_op.u4_timestamp_low;
+        finishWork(workId, work, &s_encode_op);
+    }
+    if (mSawInputEOS) {
+        drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
+    }
+}
+
+c2_status_t C2SoftAvcEnc::drainInternal(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool,
+        const std::unique_ptr<C2Work> &work) {
+
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+
+    while (true) {
+        if (!mOutBlock) {
+            C2MemoryUsage usage = {C2MemoryUsage::CPU_READ,
+                                   C2MemoryUsage::CPU_WRITE};
+            // TODO: error handling, proper usage, etc.
+            c2_status_t err =
+                pool->fetchLinearBlock(mOutBufferSize, usage, &mOutBlock);
+            if (err != C2_OK) {
+                ALOGE("fetch linear block err = %d", err);
+                work->result = err;
+                work->workletsProcessed = 1u;
+                return err;
+            }
+        }
+        C2WriteView wView = mOutBlock->map().get();
+        if (wView.error()) {
+            ALOGE("graphic view map failed %d", wView.error());
+            return C2_CORRUPTED;
+        }
+        ive_video_encode_ip_t s_encode_ip;
+        ive_video_encode_op_t s_encode_op;
+        if (C2_OK != setEncodeArgs(&s_encode_ip, &s_encode_op, nullptr,
+                                   wView.base(), wView.capacity(), 0)) {
+            ALOGE("setEncodeArgs failed for drainInternal");
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            work->workletsProcessed = 1u;
+            return C2_CORRUPTED;
+        }
+        (void)ive_api_function(mCodecCtx, &s_encode_ip, &s_encode_op);
+
+        void *freed = s_encode_op.s_inp_buf.apv_bufs[0];
+        /* If encoder frees up an input buffer, mark it as free */
+        if (freed != nullptr) {
+            if (mBuffers.count(freed) == 0u) {
+                ALOGD("buffer not tracked");
+            } else {
+                // Release input buffer reference
+                mBuffers.erase(freed);
+                mConversionBuffersInUse.erase(freed);
+            }
+        }
+
+        if (s_encode_op.output_present) {
+            uint64_t workId = ((uint64_t)s_encode_op.u4_timestamp_high << 32) |
+                          s_encode_op.u4_timestamp_low;
+            finishWork(workId, work, &s_encode_op);
+        } else {
+            if (work->workletsProcessed != 1u) {
+                work->worklets.front()->output.flags = work->input.flags;
+                work->worklets.front()->output.ordinal = work->input.ordinal;
+                work->worklets.front()->output.buffers.clear();
+                work->workletsProcessed = 1u;
+            }
+            break;
+        }
+    }
+
+    return C2_OK;
+}
+
+c2_status_t C2SoftAvcEnc::drain(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    return drainInternal(drainMode, pool, nullptr);
+}
+
+class C2SoftAvcEncFactory : public C2ComponentFactory {
+public:
+    C2SoftAvcEncFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+        GetCodec2PlatformComponentStore()->getParamReflector())) {
+    }
+
+    virtual c2_status_t createComponent(
+            c2_node_id_t id,
+            std::shared_ptr<C2Component>* const component,
+            std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+                new C2SoftAvcEnc(COMPONENT_NAME,
+                                 id,
+                                 std::make_shared<C2SoftAvcEnc::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+            c2_node_id_t id,
+            std::shared_ptr<C2ComponentInterface>* const interface,
+            std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+                new SimpleInterface<C2SoftAvcEnc::IntfImpl>(
+                        COMPONENT_NAME, id, std::make_shared<C2SoftAvcEnc::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftAvcEncFactory() override = default;
+
+private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftAvcEncFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.h b/media/codec2/components/avc/C2SoftAvcEnc.h
new file mode 100644
index 0000000..555055b
--- /dev/null
+++ b/media/codec2/components/avc/C2SoftAvcEnc.h
@@ -0,0 +1,304 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_AVC_ENC_H__
+#define ANDROID_C2_SOFT_AVC_ENC_H__
+
+#include <map>
+
+#include <utils/Vector.h>
+
+#include <SimpleC2Component.h>
+
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "ive2.h"
+
+namespace android {
+
+#define CODEC_MAX_CORES          4
+#define LEN_STATUS_BUFFER        (10  * 1024)
+#define MAX_VBV_BUFF_SIZE        (120 * 16384)
+#define MAX_NUM_IO_BUFS           3
+#define MAX_B_FRAMES              1
+
+#define DEFAULT_MAX_REF_FRM         2
+#define DEFAULT_MAX_REORDER_FRM     0
+#define DEFAULT_QP_MIN              10
+#define DEFAULT_QP_MAX              40
+#define DEFAULT_MAX_BITRATE         240000000
+#define DEFAULT_MAX_SRCH_RANGE_X    256
+#define DEFAULT_MAX_SRCH_RANGE_Y    256
+#define DEFAULT_MAX_FRAMERATE       120000
+#define DEFAULT_NUM_CORES           1
+#define DEFAULT_NUM_CORES_PRE_ENC   0
+#define DEFAULT_FPS                 30
+#define DEFAULT_ENC_SPEED           IVE_NORMAL
+
+#define DEFAULT_MEM_REC_CNT         0
+#define DEFAULT_RECON_ENABLE        0
+#define DEFAULT_CHKSUM_ENABLE       0
+#define DEFAULT_START_FRM           0
+#define DEFAULT_NUM_FRMS            0xFFFFFFFF
+#define DEFAULT_INP_COLOR_FORMAT       IV_YUV_420SP_VU
+#define DEFAULT_RECON_COLOR_FORMAT     IV_YUV_420P
+#define DEFAULT_LOOPBACK            0
+#define DEFAULT_SRC_FRAME_RATE      30
+#define DEFAULT_TGT_FRAME_RATE      30
+#define DEFAULT_MAX_WD              1920
+#define DEFAULT_MAX_HT              1920
+#define DEFAULT_MAX_LEVEL           41
+#define DEFAULT_STRIDE              0
+#define DEFAULT_WD                  1280
+#define DEFAULT_HT                  720
+#define DEFAULT_PSNR_ENABLE         0
+#define DEFAULT_ME_SPEED            100
+#define DEFAULT_ENABLE_FAST_SAD     0
+#define DEFAULT_ENABLE_ALT_REF      0
+#define DEFAULT_RC_MODE             IVE_RC_STORAGE
+#define DEFAULT_BITRATE             6000000
+#define DEFAULT_I_QP                22
+#define DEFAULT_I_QP_MAX            DEFAULT_QP_MAX
+#define DEFAULT_I_QP_MIN            DEFAULT_QP_MIN
+#define DEFAULT_P_QP                28
+#define DEFAULT_P_QP_MAX            DEFAULT_QP_MAX
+#define DEFAULT_P_QP_MIN            DEFAULT_QP_MIN
+#define DEFAULT_B_QP                22
+#define DEFAULT_B_QP_MAX            DEFAULT_QP_MAX
+#define DEFAULT_B_QP_MIN            DEFAULT_QP_MIN
+#define DEFAULT_AIR                 IVE_AIR_MODE_NONE
+#define DEFAULT_AIR_REFRESH_PERIOD  30
+#define DEFAULT_SRCH_RNG_X          64
+#define DEFAULT_SRCH_RNG_Y          48
+#define DEFAULT_I_INTERVAL          30
+#define DEFAULT_IDR_INTERVAL        1000
+#define DEFAULT_B_FRAMES            0
+#define DEFAULT_DISABLE_DEBLK_LEVEL 0
+#define DEFAULT_HPEL                1
+#define DEFAULT_QPEL                1
+#define DEFAULT_I4                  1
+#define DEFAULT_EPROFILE            IV_PROFILE_BASE
+#define DEFAULT_ENTROPY_MODE        0
+#define DEFAULT_SLICE_MODE          IVE_SLICE_MODE_NONE
+#define DEFAULT_SLICE_PARAM         256
+#define DEFAULT_ARCH                ARCH_ARM_A9Q
+#define DEFAULT_SOC                 SOC_GENERIC
+#define DEFAULT_INTRA4x4            0
+#define STRLENGTH                   500
+#define DEFAULT_CONSTRAINED_INTRA   0
+
+#define MIN(a, b) ((a) < (b))? (a) : (b)
+#define MAX(a, b) ((a) > (b))? (a) : (b)
+#define ALIGN16(x) ((((x) + 15) >> 4) << 4)
+#define ALIGN128(x) ((((x) + 127) >> 7) << 7)
+#define ALIGN4096(x) ((((x) + 4095) >> 12) << 12)
+
+/** Used to remove warnings about unused parameters */
+#define UNUSED(x) ((void)(x))
+
+/** Get time */
+#define GETTIME(a, b) gettimeofday(a, b);
+
+/** Compute difference between start and end */
+#define TIME_DIFF(start, end, diff) \
+    diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \
+            ((end).tv_usec - (start).tv_usec);
+
+#define ive_aligned_malloc(alignment, size) memalign(alignment, size)
+#define ive_aligned_free(buf) free(buf)
+
+struct C2SoftAvcEnc : public SimpleC2Component {
+    class IntfImpl;
+
+    C2SoftAvcEnc(const char *name, c2_node_id_t id, const std::shared_ptr<IntfImpl> &intfImpl);
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+    c2_status_t drain(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+
+protected:
+    virtual ~C2SoftAvcEnc();
+
+private:
+    // OMX input buffer's timestamp and flags
+    typedef struct {
+        int64_t mTimeUs;
+        int32_t mFlags;
+    } InputBufferInfo;
+
+    std::shared_ptr<IntfImpl> mIntf;
+
+    int32_t mStride;
+
+    struct timeval mTimeStart;   // Time at the start of decode()
+    struct timeval mTimeEnd;     // Time at the end of decode()
+
+#ifdef FILE_DUMP_ENABLE
+    char mInFile[200];
+    char mOutFile[200];
+#endif /* FILE_DUMP_ENABLE */
+
+    IV_COLOR_FORMAT_T mIvVideoColorFormat;
+
+    IV_PROFILE_T mAVCEncProfile __unused;
+    WORD32   mAVCEncLevel;
+    bool     mStarted;
+    bool     mSpsPpsHeaderReceived;
+
+    bool     mSawInputEOS;
+    bool     mSignalledError;
+    bool     mIntra4x4;
+    bool     mEnableFastSad;
+    bool     mEnableAltRef;
+    bool     mReconEnable;
+    bool     mPSNREnable;
+    bool     mEntropyMode;
+    bool     mConstrainedIntraFlag;
+    IVE_SPEED_CONFIG     mEncSpeed;
+
+    iv_obj_t *mCodecCtx;         // Codec context
+    iv_mem_rec_t *mMemRecords;   // Memory records requested by the codec
+    size_t mNumMemRecords;       // Number of memory records requested by codec
+    size_t mNumCores;            // Number of cores used by the codec
+
+    std::shared_ptr<C2LinearBlock> mOutBlock;
+
+    // configurations used by component in process
+    // (TODO: keep this in intf but make them internal only)
+    std::shared_ptr<C2StreamPictureSizeInfo::input> mSize;
+    std::shared_ptr<C2StreamIntraRefreshTuning::output> mIntraRefresh;
+    std::shared_ptr<C2StreamFrameRateInfo::output> mFrameRate;
+    std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
+    std::shared_ptr<C2StreamRequestSyncFrameTuning::output> mRequestSync;
+
+    uint32_t mOutBufferSize;
+    UWORD32 mHeaderGenerated;
+    UWORD32 mBframes;
+    IV_ARCH_T mArch;
+    IVE_SLICE_MODE_T mSliceMode;
+    UWORD32 mSliceParam;
+    bool mHalfPelEnable;
+    UWORD32 mIInterval;
+    UWORD32 mIDRInterval;
+    UWORD32 mDisableDeblkLevel;
+    std::map<const void *, std::shared_ptr<C2Buffer>> mBuffers;
+    MemoryBlockPool mConversionBuffers;
+    std::map<const void *, MemoryBlock> mConversionBuffersInUse;
+
+    void initEncParams();
+    c2_status_t initEncoder();
+    c2_status_t releaseEncoder();
+
+    c2_status_t setFrameType(IV_PICTURE_CODING_TYPE_T  e_frame_type);
+    c2_status_t setQp();
+    c2_status_t setEncMode(IVE_ENC_MODE_T e_enc_mode);
+    c2_status_t setDimensions();
+    c2_status_t setNumCores();
+    c2_status_t setFrameRate();
+    c2_status_t setIpeParams();
+    c2_status_t setBitRate();
+    c2_status_t setAirParams();
+    c2_status_t setMeParams();
+    c2_status_t setGopParams();
+    c2_status_t setProfileParams();
+    c2_status_t setDeblockParams();
+    c2_status_t setVbvParams();
+    void logVersion();
+    c2_status_t setEncodeArgs(
+            ive_video_encode_ip_t *ps_encode_ip,
+            ive_video_encode_op_t *ps_encode_op,
+            const C2GraphicView *const input,
+            uint8_t *base,
+            uint32_t capacity,
+            uint64_t workIndex);
+    void finishWork(uint64_t workIndex,
+            const std::unique_ptr<C2Work> &work,
+            ive_video_encode_op_t *ps_encode_op);
+    c2_status_t drainInternal(uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool,
+            const std::unique_ptr<C2Work> &work);
+
+    C2_DO_NOT_COPY(C2SoftAvcEnc);
+};
+
+#ifdef FILE_DUMP_ENABLE
+
+#define INPUT_DUMP_PATH     "/sdcard/media/avce_input"
+#define INPUT_DUMP_EXT      "yuv"
+#define OUTPUT_DUMP_PATH    "/sdcard/media/avce_output"
+#define OUTPUT_DUMP_EXT     "h264"
+
+#define GENERATE_FILE_NAMES() {                         \
+    GETTIME(&mTimeStart, NULL);                         \
+    strcpy(mInFile, "");                                \
+    sprintf(mInFile, "%s_%ld.%ld.%s", INPUT_DUMP_PATH,  \
+            mTimeStart.tv_sec, mTimeStart.tv_usec,      \
+            INPUT_DUMP_EXT);                            \
+    strcpy(mOutFile, "");                               \
+    sprintf(mOutFile, "%s_%ld.%ld.%s", OUTPUT_DUMP_PATH,\
+            mTimeStart.tv_sec, mTimeStart.tv_usec,      \
+            OUTPUT_DUMP_EXT);                           \
+}
+
+#define CREATE_DUMP_FILE(m_filename) {                  \
+    FILE *fp = fopen(m_filename, "wb");                 \
+    if (fp != NULL) {                                   \
+        ALOGD("Opened file %s", m_filename);            \
+        fclose(fp);                                     \
+    } else {                                            \
+        ALOGD("Could not open file %s", m_filename);    \
+    }                                                   \
+}
+#define DUMP_TO_FILE(m_filename, m_buf, m_size)         \
+{                                                       \
+    FILE *fp = fopen(m_filename, "ab");                 \
+    if (fp != NULL && m_buf != NULL) {                  \
+        int i;                                          \
+        i = fwrite(m_buf, 1, m_size, fp);               \
+        ALOGD("fwrite ret %d to write %d", i, m_size);  \
+        if (i != (int)m_size) {                         \
+            ALOGD("Error in fwrite, returned %d", i);   \
+            perror("Error in write to file");           \
+        }                                               \
+        fclose(fp);                                     \
+    } else {                                            \
+        ALOGD("Could not write to file %s", m_filename);\
+        if (fp != NULL)                                 \
+            fclose(fp);                                 \
+    }                                                   \
+}
+#else /* FILE_DUMP_ENABLE */
+#define INPUT_DUMP_PATH
+#define INPUT_DUMP_EXT
+#define OUTPUT_DUMP_PATH
+#define OUTPUT_DUMP_EXT
+#define GENERATE_FILE_NAMES()
+#define CREATE_DUMP_FILE(m_filename)
+#define DUMP_TO_FILE(m_filename, m_buf, m_size)
+#endif /* FILE_DUMP_ENABLE */
+
+}  // namespace android
+
+#endif  // ANDROID_C2_SOFT_AVC_ENC_H__
diff --git a/media/codec2/components/base/Android.bp b/media/codec2/components/base/Android.bp
new file mode 100644
index 0000000..f10835f
--- /dev/null
+++ b/media/codec2/components/base/Android.bp
@@ -0,0 +1,134 @@
+// DO NOT DEPEND ON THIS DIRECTLY
+// use libcodec2_soft-defaults instead
+cc_library_shared {
+    name: "libcodec2_soft_common",
+    defaults: ["libcodec2-impl-defaults"],
+    vendor_available: true,
+
+    srcs: [
+        "SimpleC2Component.cpp",
+        "SimpleC2Interface.cpp",
+    ],
+
+    export_include_dirs: [
+        "include",
+    ],
+
+    export_shared_lib_headers: [
+        "libsfplugin_ccodec_utils",
+    ],
+
+    shared_libs: [
+        "libcutils", // for properties
+        "liblog",    // for ALOG
+        "libsfplugin_ccodec_utils", // for ImageCopy
+        "libstagefright_foundation", // for Mutexed
+    ],
+
+    sanitize: {
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+        cfi: true,
+    },
+
+    ldflags: ["-Wl,-Bsymbolic"],
+}
+
+filegroup {
+    name: "codec2_soft_exports",
+    srcs: [ "exports.lds" ],
+}
+
+// public dependency for software codec implementation
+// to be used by code under media/codecs/* only as its stability is not guaranteed
+cc_defaults {
+    name: "libcodec2_soft-defaults",
+    defaults: ["libcodec2-impl-defaults"],
+    vendor_available: true,
+    version_script: ":codec2_soft_exports",
+    export_shared_lib_headers: [
+        "libsfplugin_ccodec_utils",
+    ],
+
+    shared_libs: [
+        "libcodec2_soft_common",
+        "libcutils", // for properties
+        "liblog", // for ALOG
+        "libsfplugin_ccodec_utils", // for ImageCopy
+        "libstagefright_foundation", // for ColorUtils and MIME
+    ],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+
+    ldflags: ["-Wl,-Bsymbolic"],
+}
+
+// public dependency for software codec implementation
+// to be used by code under media/codecs/* only
+cc_defaults {
+    name: "libcodec2_soft_sanitize_all-defaults",
+
+    sanitize: {
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+        cfi: true,
+    },
+}
+
+// public dependency for software codec implementation
+// to be used by code under media/codecs/* only
+cc_defaults {
+    name: "libcodec2_soft_sanitize_signed-defaults",
+
+    sanitize: {
+        misc_undefined: [
+            "signed-integer-overflow",
+        ],
+        cfi: true,
+    },
+}
+
+// TEMP: used by cheets2 project - remove when no longer used
+cc_library_shared {
+    name: "libcodec2_simple_component",
+    vendor_available: true,
+
+    srcs: [
+        "SimpleC2Interface.cpp",
+    ],
+
+    local_include_dirs: [
+        "include",
+    ],
+
+    export_include_dirs: [
+        "include",
+    ],
+
+    shared_libs: [
+        "libcodec2",
+        "libcodec2_vndk",
+        "libcutils",
+        "liblog",
+        "libstagefright_foundation",
+        "libutils",
+    ],
+
+    sanitize: {
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+        cfi: true,
+    },
+
+    ldflags: ["-Wl,-Bsymbolic"],
+}
+
diff --git a/media/codec2/components/base/SimpleC2Component.cpp b/media/codec2/components/base/SimpleC2Component.cpp
new file mode 100644
index 0000000..fb3fbd0
--- /dev/null
+++ b/media/codec2/components/base/SimpleC2Component.cpp
@@ -0,0 +1,611 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "SimpleC2Component"
+#include <log/log.h>
+
+#include <cutils/properties.h>
+#include <media/stagefright/foundation/AMessage.h>
+
+#include <inttypes.h>
+
+#include <C2Config.h>
+#include <C2Debug.h>
+#include <C2PlatformSupport.h>
+#include <SimpleC2Component.h>
+
+namespace android {
+
+std::unique_ptr<C2Work> SimpleC2Component::WorkQueue::pop_front() {
+    std::unique_ptr<C2Work> work = std::move(mQueue.front().work);
+    mQueue.pop_front();
+    return work;
+}
+
+void SimpleC2Component::WorkQueue::push_back(std::unique_ptr<C2Work> work) {
+    mQueue.push_back({ std::move(work), NO_DRAIN });
+}
+
+bool SimpleC2Component::WorkQueue::empty() const {
+    return mQueue.empty();
+}
+
+void SimpleC2Component::WorkQueue::clear() {
+    mQueue.clear();
+}
+
+uint32_t SimpleC2Component::WorkQueue::drainMode() const {
+    return mQueue.front().drainMode;
+}
+
+void SimpleC2Component::WorkQueue::markDrain(uint32_t drainMode) {
+    mQueue.push_back({ nullptr, drainMode });
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+SimpleC2Component::WorkHandler::WorkHandler() : mRunning(false) {}
+
+void SimpleC2Component::WorkHandler::setComponent(
+        const std::shared_ptr<SimpleC2Component> &thiz) {
+    mThiz = thiz;
+}
+
+static void Reply(const sp<AMessage> &msg, int32_t *err = nullptr) {
+    sp<AReplyToken> replyId;
+    CHECK(msg->senderAwaitsResponse(&replyId));
+    sp<AMessage> reply = new AMessage;
+    if (err) {
+        reply->setInt32("err", *err);
+    }
+    reply->postReply(replyId);
+}
+
+void SimpleC2Component::WorkHandler::onMessageReceived(const sp<AMessage> &msg) {
+    std::shared_ptr<SimpleC2Component> thiz = mThiz.lock();
+    if (!thiz) {
+        ALOGD("component not yet set; msg = %s", msg->debugString().c_str());
+        sp<AReplyToken> replyId;
+        if (msg->senderAwaitsResponse(&replyId)) {
+            sp<AMessage> reply = new AMessage;
+            reply->setInt32("err", C2_CORRUPTED);
+            reply->postReply(replyId);
+        }
+        return;
+    }
+
+    switch (msg->what()) {
+        case kWhatProcess: {
+            if (mRunning) {
+                if (thiz->processQueue()) {
+                    (new AMessage(kWhatProcess, this))->post();
+                }
+            } else {
+                ALOGV("Ignore process message as we're not running");
+            }
+            break;
+        }
+        case kWhatInit: {
+            int32_t err = thiz->onInit();
+            Reply(msg, &err);
+            [[fallthrough]];
+        }
+        case kWhatStart: {
+            mRunning = true;
+            break;
+        }
+        case kWhatStop: {
+            int32_t err = thiz->onStop();
+            Reply(msg, &err);
+            break;
+        }
+        case kWhatReset: {
+            thiz->onReset();
+            mRunning = false;
+            Reply(msg);
+            break;
+        }
+        case kWhatRelease: {
+            thiz->onRelease();
+            mRunning = false;
+            Reply(msg);
+            break;
+        }
+        default: {
+            ALOGD("Unrecognized msg: %d", msg->what());
+            break;
+        }
+    }
+}
+
+class SimpleC2Component::BlockingBlockPool : public C2BlockPool {
+public:
+    BlockingBlockPool(const std::shared_ptr<C2BlockPool>& base): mBase{base} {}
+
+    virtual local_id_t getLocalId() const override {
+        return mBase->getLocalId();
+    }
+
+    virtual C2Allocator::id_t getAllocatorId() const override {
+        return mBase->getAllocatorId();
+    }
+
+    virtual c2_status_t fetchLinearBlock(
+            uint32_t capacity,
+            C2MemoryUsage usage,
+            std::shared_ptr<C2LinearBlock>* block) {
+        c2_status_t status;
+        do {
+            status = mBase->fetchLinearBlock(capacity, usage, block);
+        } while (status == C2_BLOCKING);
+        return status;
+    }
+
+    virtual c2_status_t fetchCircularBlock(
+            uint32_t capacity,
+            C2MemoryUsage usage,
+            std::shared_ptr<C2CircularBlock>* block) {
+        c2_status_t status;
+        do {
+            status = mBase->fetchCircularBlock(capacity, usage, block);
+        } while (status == C2_BLOCKING);
+        return status;
+    }
+
+    virtual c2_status_t fetchGraphicBlock(
+            uint32_t width, uint32_t height, uint32_t format,
+            C2MemoryUsage usage,
+            std::shared_ptr<C2GraphicBlock>* block) {
+        c2_status_t status;
+        do {
+            status = mBase->fetchGraphicBlock(width, height, format, usage,
+                                              block);
+        } while (status == C2_BLOCKING);
+        return status;
+    }
+
+private:
+    std::shared_ptr<C2BlockPool> mBase;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+namespace {
+
+struct DummyReadView : public C2ReadView {
+    DummyReadView() : C2ReadView(C2_NO_INIT) {}
+};
+
+}  // namespace
+
+SimpleC2Component::SimpleC2Component(
+        const std::shared_ptr<C2ComponentInterface> &intf)
+    : mDummyReadView(DummyReadView()),
+      mIntf(intf),
+      mLooper(new ALooper),
+      mHandler(new WorkHandler) {
+    mLooper->setName(intf->getName().c_str());
+    (void)mLooper->registerHandler(mHandler);
+    mLooper->start(false, false, ANDROID_PRIORITY_VIDEO);
+}
+
+SimpleC2Component::~SimpleC2Component() {
+    mLooper->unregisterHandler(mHandler->id());
+    (void)mLooper->stop();
+}
+
+c2_status_t SimpleC2Component::setListener_vb(
+        const std::shared_ptr<C2Component::Listener> &listener, c2_blocking_t mayBlock) {
+    mHandler->setComponent(shared_from_this());
+
+    Mutexed<ExecState>::Locked state(mExecState);
+    if (state->mState == RUNNING) {
+        if (listener) {
+            return C2_BAD_STATE;
+        } else if (!mayBlock) {
+            return C2_BLOCKING;
+        }
+    }
+    state->mListener = listener;
+    // TODO: wait for listener change to have taken place before returning
+    // (e.g. if there is an ongoing listener callback)
+    return C2_OK;
+}
+
+c2_status_t SimpleC2Component::queue_nb(std::list<std::unique_ptr<C2Work>> * const items) {
+    {
+        Mutexed<ExecState>::Locked state(mExecState);
+        if (state->mState != RUNNING) {
+            return C2_BAD_STATE;
+        }
+    }
+    bool queueWasEmpty = false;
+    {
+        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
+        queueWasEmpty = queue->empty();
+        while (!items->empty()) {
+            queue->push_back(std::move(items->front()));
+            items->pop_front();
+        }
+    }
+    if (queueWasEmpty) {
+        (new AMessage(WorkHandler::kWhatProcess, mHandler))->post();
+    }
+    return C2_OK;
+}
+
+c2_status_t SimpleC2Component::announce_nb(const std::vector<C2WorkOutline> &items) {
+    (void)items;
+    return C2_OMITTED;
+}
+
+c2_status_t SimpleC2Component::flush_sm(
+        flush_mode_t flushMode, std::list<std::unique_ptr<C2Work>>* const flushedWork) {
+    (void)flushMode;
+    {
+        Mutexed<ExecState>::Locked state(mExecState);
+        if (state->mState != RUNNING) {
+            return C2_BAD_STATE;
+        }
+    }
+    {
+        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
+        queue->incGeneration();
+        // TODO: queue->splicedBy(flushedWork, flushedWork->end());
+        while (!queue->empty()) {
+            std::unique_ptr<C2Work> work = queue->pop_front();
+            if (work) {
+                flushedWork->push_back(std::move(work));
+            }
+        }
+        while (!queue->pending().empty()) {
+            flushedWork->push_back(std::move(queue->pending().begin()->second));
+            queue->pending().erase(queue->pending().begin());
+        }
+    }
+
+    return C2_OK;
+}
+
+c2_status_t SimpleC2Component::drain_nb(drain_mode_t drainMode) {
+    if (drainMode == DRAIN_CHAIN) {
+        return C2_OMITTED;
+    }
+    {
+        Mutexed<ExecState>::Locked state(mExecState);
+        if (state->mState != RUNNING) {
+            return C2_BAD_STATE;
+        }
+    }
+    bool queueWasEmpty = false;
+    {
+        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
+        queueWasEmpty = queue->empty();
+        queue->markDrain(drainMode);
+    }
+    if (queueWasEmpty) {
+        (new AMessage(WorkHandler::kWhatProcess, mHandler))->post();
+    }
+
+    return C2_OK;
+}
+
+c2_status_t SimpleC2Component::start() {
+    Mutexed<ExecState>::Locked state(mExecState);
+    if (state->mState == RUNNING) {
+        return C2_BAD_STATE;
+    }
+    bool needsInit = (state->mState == UNINITIALIZED);
+    state.unlock();
+    if (needsInit) {
+        sp<AMessage> reply;
+        (new AMessage(WorkHandler::kWhatInit, mHandler))->postAndAwaitResponse(&reply);
+        int32_t err;
+        CHECK(reply->findInt32("err", &err));
+        if (err != C2_OK) {
+            return (c2_status_t)err;
+        }
+    } else {
+        (new AMessage(WorkHandler::kWhatStart, mHandler))->post();
+    }
+    state.lock();
+    state->mState = RUNNING;
+    return C2_OK;
+}
+
+c2_status_t SimpleC2Component::stop() {
+    ALOGV("stop");
+    {
+        Mutexed<ExecState>::Locked state(mExecState);
+        if (state->mState != RUNNING) {
+            return C2_BAD_STATE;
+        }
+        state->mState = STOPPED;
+    }
+    {
+        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
+        queue->clear();
+        queue->pending().clear();
+    }
+    sp<AMessage> reply;
+    (new AMessage(WorkHandler::kWhatStop, mHandler))->postAndAwaitResponse(&reply);
+    int32_t err;
+    CHECK(reply->findInt32("err", &err));
+    if (err != C2_OK) {
+        return (c2_status_t)err;
+    }
+    return C2_OK;
+}
+
+c2_status_t SimpleC2Component::reset() {
+    ALOGV("reset");
+    {
+        Mutexed<ExecState>::Locked state(mExecState);
+        state->mState = UNINITIALIZED;
+    }
+    {
+        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
+        queue->clear();
+        queue->pending().clear();
+    }
+    sp<AMessage> reply;
+    (new AMessage(WorkHandler::kWhatReset, mHandler))->postAndAwaitResponse(&reply);
+    return C2_OK;
+}
+
+c2_status_t SimpleC2Component::release() {
+    ALOGV("release");
+    sp<AMessage> reply;
+    (new AMessage(WorkHandler::kWhatRelease, mHandler))->postAndAwaitResponse(&reply);
+    return C2_OK;
+}
+
+std::shared_ptr<C2ComponentInterface> SimpleC2Component::intf() {
+    return mIntf;
+}
+
+namespace {
+
+std::list<std::unique_ptr<C2Work>> vec(std::unique_ptr<C2Work> &work) {
+    std::list<std::unique_ptr<C2Work>> ret;
+    ret.push_back(std::move(work));
+    return ret;
+}
+
+}  // namespace
+
+void SimpleC2Component::finish(
+        uint64_t frameIndex, std::function<void(const std::unique_ptr<C2Work> &)> fillWork) {
+    std::unique_ptr<C2Work> work;
+    {
+        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
+        if (queue->pending().count(frameIndex) == 0) {
+            ALOGW("unknown frame index: %" PRIu64, frameIndex);
+            return;
+        }
+        work = std::move(queue->pending().at(frameIndex));
+        queue->pending().erase(frameIndex);
+    }
+    if (work) {
+        fillWork(work);
+        std::shared_ptr<C2Component::Listener> listener = mExecState.lock()->mListener;
+        listener->onWorkDone_nb(shared_from_this(), vec(work));
+        ALOGV("returning pending work");
+    }
+}
+
+void SimpleC2Component::cloneAndSend(
+        uint64_t frameIndex,
+        const std::unique_ptr<C2Work> &currentWork,
+        std::function<void(const std::unique_ptr<C2Work> &)> fillWork) {
+    std::unique_ptr<C2Work> work(new C2Work);
+    if (currentWork->input.ordinal.frameIndex == frameIndex) {
+        work->input.flags = currentWork->input.flags;
+        work->input.ordinal = currentWork->input.ordinal;
+    } else {
+        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
+        if (queue->pending().count(frameIndex) == 0) {
+            ALOGW("unknown frame index: %" PRIu64, frameIndex);
+            return;
+        }
+        work->input.flags = queue->pending().at(frameIndex)->input.flags;
+        work->input.ordinal = queue->pending().at(frameIndex)->input.ordinal;
+    }
+    work->worklets.emplace_back(new C2Worklet);
+    if (work) {
+        fillWork(work);
+        std::shared_ptr<C2Component::Listener> listener = mExecState.lock()->mListener;
+        listener->onWorkDone_nb(shared_from_this(), vec(work));
+        ALOGV("cloned and sending work");
+    }
+}
+
+bool SimpleC2Component::processQueue() {
+    std::unique_ptr<C2Work> work;
+    uint64_t generation;
+    int32_t drainMode;
+    bool isFlushPending = false;
+    bool hasQueuedWork = false;
+    {
+        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
+        if (queue->empty()) {
+            return false;
+        }
+
+        generation = queue->generation();
+        drainMode = queue->drainMode();
+        isFlushPending = queue->popPendingFlush();
+        work = queue->pop_front();
+        hasQueuedWork = !queue->empty();
+    }
+    if (isFlushPending) {
+        ALOGV("processing pending flush");
+        c2_status_t err = onFlush_sm();
+        if (err != C2_OK) {
+            ALOGD("flush err: %d", err);
+            // TODO: error
+        }
+    }
+
+    if (!mOutputBlockPool) {
+        c2_status_t err = [this] {
+            // TODO: don't use query_vb
+            C2StreamBufferTypeSetting::output outputFormat(0u);
+            std::vector<std::unique_ptr<C2Param>> params;
+            c2_status_t err = intf()->query_vb(
+                    { &outputFormat },
+                    { C2PortBlockPoolsTuning::output::PARAM_TYPE },
+                    C2_DONT_BLOCK,
+                    &params);
+            if (err != C2_OK && err != C2_BAD_INDEX) {
+                ALOGD("query err = %d", err);
+                return err;
+            }
+            C2BlockPool::local_id_t poolId =
+                outputFormat.value == C2BufferData::GRAPHIC
+                        ? C2BlockPool::BASIC_GRAPHIC
+                        : C2BlockPool::BASIC_LINEAR;
+            if (params.size()) {
+                C2PortBlockPoolsTuning::output *outputPools =
+                    C2PortBlockPoolsTuning::output::From(params[0].get());
+                if (outputPools && outputPools->flexCount() >= 1) {
+                    poolId = outputPools->m.values[0];
+                }
+            }
+
+            std::shared_ptr<C2BlockPool> blockPool;
+            err = GetCodec2BlockPool(poolId, shared_from_this(), &blockPool);
+            ALOGD("Using output block pool with poolID %llu => got %llu - %d",
+                    (unsigned long long)poolId,
+                    (unsigned long long)(
+                            blockPool ? blockPool->getLocalId() : 111000111),
+                    err);
+            if (err == C2_OK) {
+                mOutputBlockPool = std::make_shared<BlockingBlockPool>(blockPool);
+            }
+            return err;
+        }();
+        if (err != C2_OK) {
+            Mutexed<ExecState>::Locked state(mExecState);
+            std::shared_ptr<C2Component::Listener> listener = state->mListener;
+            state.unlock();
+            listener->onError_nb(shared_from_this(), err);
+            return hasQueuedWork;
+        }
+    }
+
+    if (!work) {
+        c2_status_t err = drain(drainMode, mOutputBlockPool);
+        if (err != C2_OK) {
+            Mutexed<ExecState>::Locked state(mExecState);
+            std::shared_ptr<C2Component::Listener> listener = state->mListener;
+            state.unlock();
+            listener->onError_nb(shared_from_this(), err);
+        }
+        return hasQueuedWork;
+    }
+
+    {
+        std::vector<C2Param *> updates;
+        for (const std::unique_ptr<C2Param> &param: work->input.configUpdate) {
+            if (param) {
+                updates.emplace_back(param.get());
+            }
+        }
+        if (!updates.empty()) {
+            std::vector<std::unique_ptr<C2SettingResult>> failures;
+            c2_status_t err = intf()->config_vb(updates, C2_MAY_BLOCK, &failures);
+            ALOGD("applied %zu configUpdates => %s (%d)", updates.size(), asString(err), err);
+        }
+    }
+
+    ALOGV("start processing frame #%" PRIu64, work->input.ordinal.frameIndex.peeku());
+    // If input buffer list is not empty, it means we have some input to process on.
+    // However, input could be a null buffer. In such case, clear the buffer list
+    // before making call to process().
+    if (!work->input.buffers.empty() && !work->input.buffers[0]) {
+        ALOGD("Encountered null input buffer. Clearing the input buffer");
+        work->input.buffers.clear();
+    }
+    process(work, mOutputBlockPool);
+    ALOGV("processed frame #%" PRIu64, work->input.ordinal.frameIndex.peeku());
+    Mutexed<WorkQueue>::Locked queue(mWorkQueue);
+    if (queue->generation() != generation) {
+        ALOGD("work form old generation: was %" PRIu64 " now %" PRIu64,
+                queue->generation(), generation);
+        work->result = C2_NOT_FOUND;
+        queue.unlock();
+
+        Mutexed<ExecState>::Locked state(mExecState);
+        std::shared_ptr<C2Component::Listener> listener = state->mListener;
+        state.unlock();
+        listener->onWorkDone_nb(shared_from_this(), vec(work));
+        return hasQueuedWork;
+    }
+    if (work->workletsProcessed != 0u) {
+        queue.unlock();
+        Mutexed<ExecState>::Locked state(mExecState);
+        ALOGV("returning this work");
+        std::shared_ptr<C2Component::Listener> listener = state->mListener;
+        state.unlock();
+        listener->onWorkDone_nb(shared_from_this(), vec(work));
+    } else {
+        ALOGV("queue pending work");
+        work->input.buffers.clear();
+        std::unique_ptr<C2Work> unexpected;
+
+        uint64_t frameIndex = work->input.ordinal.frameIndex.peeku();
+        if (queue->pending().count(frameIndex) != 0) {
+            unexpected = std::move(queue->pending().at(frameIndex));
+            queue->pending().erase(frameIndex);
+        }
+        (void)queue->pending().insert({ frameIndex, std::move(work) });
+
+        queue.unlock();
+        if (unexpected) {
+            ALOGD("unexpected pending work");
+            unexpected->result = C2_CORRUPTED;
+            Mutexed<ExecState>::Locked state(mExecState);
+            std::shared_ptr<C2Component::Listener> listener = state->mListener;
+            state.unlock();
+            listener->onWorkDone_nb(shared_from_this(), vec(unexpected));
+        }
+    }
+    return hasQueuedWork;
+}
+
+std::shared_ptr<C2Buffer> SimpleC2Component::createLinearBuffer(
+        const std::shared_ptr<C2LinearBlock> &block) {
+    return createLinearBuffer(block, block->offset(), block->size());
+}
+
+std::shared_ptr<C2Buffer> SimpleC2Component::createLinearBuffer(
+        const std::shared_ptr<C2LinearBlock> &block, size_t offset, size_t size) {
+    return C2Buffer::CreateLinearBuffer(block->share(offset, size, ::C2Fence()));
+}
+
+std::shared_ptr<C2Buffer> SimpleC2Component::createGraphicBuffer(
+        const std::shared_ptr<C2GraphicBlock> &block) {
+    return createGraphicBuffer(block, C2Rect(block->width(), block->height()));
+}
+
+std::shared_ptr<C2Buffer> SimpleC2Component::createGraphicBuffer(
+        const std::shared_ptr<C2GraphicBlock> &block, const C2Rect &crop) {
+    return C2Buffer::CreateGraphicBuffer(block->share(crop, ::C2Fence()));
+}
+
+} // namespace android
diff --git a/media/codec2/components/base/SimpleC2Interface.cpp b/media/codec2/components/base/SimpleC2Interface.cpp
new file mode 100644
index 0000000..c849a4e
--- /dev/null
+++ b/media/codec2/components/base/SimpleC2Interface.cpp
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "SimpleC2Interface"
+#include <utils/Log.h>
+
+// use MediaDefs here vs. MediaCodecConstants as this is not MediaCodec specific/dependent
+#include <media/stagefright/foundation/MediaDefs.h>
+
+#include <SimpleC2Interface.h>
+
+namespace android {
+
+/* SimpleInterface */
+
+SimpleInterface<void>::BaseParams::BaseParams(
+        const std::shared_ptr<C2ReflectorHelper> &reflector,
+        C2String name,
+        C2Component::kind_t kind,
+        C2Component::domain_t domain,
+        C2String mediaType,
+        std::vector<C2String> aliases)
+    : C2InterfaceHelper(reflector) {
+    setDerivedInstance(this);
+
+    addParameter(
+            DefineParam(mName, C2_PARAMKEY_COMPONENT_NAME)
+            .withConstValue(AllocSharedString<C2ComponentNameSetting>(name.c_str()))
+            .build());
+
+    if (aliases.size()) {
+        C2String joined;
+        for (const C2String &alias : aliases) {
+            if (joined.length()) {
+                joined += ",";
+            }
+            joined += alias;
+        }
+        addParameter(
+                DefineParam(mAliases, C2_PARAMKEY_COMPONENT_ALIASES)
+                .withConstValue(AllocSharedString<C2ComponentAliasesSetting>(joined.c_str()))
+                .build());
+    }
+
+    addParameter(
+            DefineParam(mKind, C2_PARAMKEY_COMPONENT_KIND)
+            .withConstValue(new C2ComponentKindSetting(kind))
+            .build());
+
+    addParameter(
+            DefineParam(mDomain, C2_PARAMKEY_COMPONENT_DOMAIN)
+            .withConstValue(new C2ComponentDomainSetting(domain))
+            .build());
+
+    // simple interfaces have single streams
+    addParameter(
+            DefineParam(mInputStreamCount, C2_PARAMKEY_INPUT_STREAM_COUNT)
+            .withConstValue(new C2PortStreamCountTuning::input(1))
+            .build());
+
+    addParameter(
+            DefineParam(mOutputStreamCount, C2_PARAMKEY_OUTPUT_STREAM_COUNT)
+            .withConstValue(new C2PortStreamCountTuning::output(1))
+            .build());
+
+    // set up buffer formats and allocators
+
+    // default to linear buffers and no media type
+    C2BufferData::type_t rawBufferType = C2BufferData::LINEAR;
+    C2String rawMediaType;
+    C2Allocator::id_t rawAllocator = C2AllocatorStore::DEFAULT_LINEAR;
+    C2BlockPool::local_id_t rawPoolId = C2BlockPool::BASIC_LINEAR;
+    C2BufferData::type_t codedBufferType = C2BufferData::LINEAR;
+    C2Allocator::id_t codedAllocator = C2AllocatorStore::DEFAULT_LINEAR;
+    C2BlockPool::local_id_t codedPoolId = C2BlockPool::BASIC_LINEAR;
+
+    switch (domain) {
+        case C2Component::DOMAIN_IMAGE:
+        case C2Component::DOMAIN_VIDEO:
+            // TODO: should we define raw image? The only difference is timestamp handling
+            rawBufferType = C2BufferData::GRAPHIC;
+            rawMediaType = MEDIA_MIMETYPE_VIDEO_RAW;
+            rawAllocator = C2AllocatorStore::DEFAULT_GRAPHIC;
+            rawPoolId = C2BlockPool::BASIC_GRAPHIC;
+            break;
+        case C2Component::DOMAIN_AUDIO:
+            rawBufferType = C2BufferData::LINEAR;
+            rawMediaType = MEDIA_MIMETYPE_AUDIO_RAW;
+            rawAllocator = C2AllocatorStore::DEFAULT_LINEAR;
+            rawPoolId = C2BlockPool::BASIC_LINEAR;
+            break;
+        default:
+            break;
+    }
+    bool isEncoder = kind == C2Component::KIND_ENCODER;
+
+    // handle raw decoders
+    if (mediaType == rawMediaType) {
+        codedBufferType = rawBufferType;
+        codedAllocator = rawAllocator;
+        codedPoolId = rawPoolId;
+    }
+
+    addParameter(
+            DefineParam(mInputFormat, C2_PARAMKEY_INPUT_STREAM_BUFFER_TYPE)
+            .withConstValue(new C2StreamBufferTypeSetting::input(
+                    0u, isEncoder ? rawBufferType : codedBufferType))
+            .build());
+
+    addParameter(
+            DefineParam(mInputMediaType, C2_PARAMKEY_INPUT_MEDIA_TYPE)
+            .withConstValue(AllocSharedString<C2PortMediaTypeSetting::input>(
+                    isEncoder ? rawMediaType : mediaType))
+            .build());
+
+    addParameter(
+            DefineParam(mOutputFormat, C2_PARAMKEY_OUTPUT_STREAM_BUFFER_TYPE)
+            .withConstValue(new C2StreamBufferTypeSetting::output(
+                    0u, isEncoder ? codedBufferType : rawBufferType))
+            .build());
+
+    addParameter(
+            DefineParam(mOutputMediaType, C2_PARAMKEY_OUTPUT_MEDIA_TYPE)
+            .withConstValue(AllocSharedString<C2PortMediaTypeSetting::output>(
+                    isEncoder ? mediaType : rawMediaType))
+            .build());
+
+    C2Allocator::id_t inputAllocators[1] = { isEncoder ? rawAllocator : codedAllocator };
+    C2Allocator::id_t outputAllocators[1] = { isEncoder ? codedAllocator : rawAllocator };
+    C2BlockPool::local_id_t outputPoolIds[1] = { isEncoder ? codedPoolId : rawPoolId };
+
+    addParameter(
+            DefineParam(mInputAllocators, C2_PARAMKEY_INPUT_ALLOCATORS)
+            .withDefault(C2PortAllocatorsTuning::input::AllocShared(inputAllocators))
+            .withFields({ C2F(mInputAllocators, m.values[0]).any(),
+                          C2F(mInputAllocators, m.values).inRange(0, 1) })
+            .withSetter(Setter<C2PortAllocatorsTuning::input>::NonStrictValuesWithNoDeps)
+            .build());
+
+    addParameter(
+            DefineParam(mOutputAllocators, C2_PARAMKEY_OUTPUT_ALLOCATORS)
+            .withDefault(C2PortAllocatorsTuning::output::AllocShared(outputAllocators))
+            .withFields({ C2F(mOutputAllocators, m.values[0]).any(),
+                          C2F(mOutputAllocators, m.values).inRange(0, 1) })
+            .withSetter(Setter<C2PortAllocatorsTuning::output>::NonStrictValuesWithNoDeps)
+            .build());
+
+    addParameter(
+            DefineParam(mOutputPoolIds, C2_PARAMKEY_OUTPUT_BLOCK_POOLS)
+            .withDefault(C2PortBlockPoolsTuning::output::AllocShared(outputPoolIds))
+            .withFields({ C2F(mOutputPoolIds, m.values[0]).any(),
+                          C2F(mOutputPoolIds, m.values).inRange(0, 1) })
+            .withSetter(Setter<C2PortBlockPoolsTuning::output>::NonStrictValuesWithNoDeps)
+            .build());
+
+    // add stateless params
+    addParameter(
+            DefineParam(mSubscribedParamIndices, C2_PARAMKEY_SUBSCRIBED_PARAM_INDICES)
+            .withDefault(C2SubscribedParamIndicesTuning::AllocShared(0u))
+            .withFields({ C2F(mSubscribedParamIndices, m.values[0]).any(),
+                          C2F(mSubscribedParamIndices, m.values).any() })
+            .withSetter(Setter<C2SubscribedParamIndicesTuning>::NonStrictValuesWithNoDeps)
+            .build());
+
+    /* TODO
+
+    addParameter(
+            DefineParam(mCurrentWorkOrdinal, C2_PARAMKEY_CURRENT_WORK)
+            .withDefault(new C2CurrentWorkTuning())
+            .withFields({ C2F(mCurrentWorkOrdinal, m.timeStamp).any(),
+                          C2F(mCurrentWorkOrdinal, m.frameIndex).any(),
+                          C2F(mCurrentWorkOrdinal, m.customOrdinal).any() })
+            .withSetter(Setter<C2CurrentWorkTuning>::NonStrictValuesWithNoDeps)
+            .build());
+
+    addParameter(
+            DefineParam(mLastInputQueuedWorkOrdinal, C2_PARAMKEY_LAST_INPUT_QUEUED)
+            .withDefault(new C2LastWorkQueuedTuning::input())
+            .withFields({ C2F(mLastInputQueuedWorkOrdinal, m.timeStamp).any(),
+                          C2F(mLastInputQueuedWorkOrdinal, m.frameIndex).any(),
+                          C2F(mLastInputQueuedWorkOrdinal, m.customOrdinal).any() })
+            .withSetter(Setter<C2LastWorkQueuedTuning::input>::NonStrictValuesWithNoDeps)
+            .build());
+
+    addParameter(
+            DefineParam(mLastOutputQueuedWorkOrdinal, C2_PARAMKEY_LAST_OUTPUT_QUEUED)
+            .withDefault(new C2LastWorkQueuedTuning::output())
+            .withFields({ C2F(mLastOutputQueuedWorkOrdinal, m.timeStamp).any(),
+                          C2F(mLastOutputQueuedWorkOrdinal, m.frameIndex).any(),
+                          C2F(mLastOutputQueuedWorkOrdinal, m.customOrdinal).any() })
+            .withSetter(Setter<C2LastWorkQueuedTuning::output>::NonStrictValuesWithNoDeps)
+            .build());
+
+    std::shared_ptr<C2OutOfMemoryTuning> mOutOfMemory;
+
+    std::shared_ptr<C2PortConfigCounterTuning::input> mInputConfigCounter;
+    std::shared_ptr<C2PortConfigCounterTuning::output> mOutputConfigCounter;
+    std::shared_ptr<C2ConfigCounterTuning> mDirectConfigCounter;
+
+    */
+}
+
+void SimpleInterface<void>::BaseParams::noInputLatency() {
+    addParameter(
+            DefineParam(mRequestedInputDelay, C2_PARAMKEY_INPUT_DELAY_REQUEST)
+            .withConstValue(new C2PortRequestedDelayTuning::input(0u))
+            .build());
+
+    addParameter(
+            DefineParam(mActualInputDelay, C2_PARAMKEY_INPUT_DELAY)
+            .withConstValue(new C2PortActualDelayTuning::input(0u))
+            .build());
+}
+
+void SimpleInterface<void>::BaseParams::noOutputLatency() {
+    addParameter(
+            DefineParam(mRequestedOutputDelay, C2_PARAMKEY_OUTPUT_DELAY_REQUEST)
+            .withConstValue(new C2PortRequestedDelayTuning::output(0u))
+            .build());
+
+    addParameter(
+            DefineParam(mActualOutputDelay, C2_PARAMKEY_OUTPUT_DELAY)
+            .withConstValue(new C2PortActualDelayTuning::output(0u))
+            .build());
+}
+
+void SimpleInterface<void>::BaseParams::noPipelineLatency() {
+    addParameter(
+            DefineParam(mRequestedPipelineDelay, C2_PARAMKEY_PIPELINE_DELAY_REQUEST)
+            .withConstValue(new C2RequestedPipelineDelayTuning(0u))
+            .build());
+
+    addParameter(
+            DefineParam(mActualPipelineDelay, C2_PARAMKEY_PIPELINE_DELAY)
+            .withConstValue(new C2ActualPipelineDelayTuning(0u))
+            .build());
+}
+
+void SimpleInterface<void>::BaseParams::noPrivateBuffers() {
+    addParameter(
+            DefineParam(mPrivateAllocators, C2_PARAMKEY_PRIVATE_ALLOCATORS)
+            .withConstValue(C2PrivateAllocatorsTuning::AllocShared(0u))
+            .build());
+
+    addParameter(
+            DefineParam(mMaxPrivateBufferCount, C2_PARAMKEY_MAX_PRIVATE_BUFFER_COUNT)
+            .withConstValue(C2MaxPrivateBufferCountTuning::AllocShared(0u))
+            .build());
+
+    addParameter(
+            DefineParam(mPrivatePoolIds, C2_PARAMKEY_PRIVATE_BLOCK_POOLS)
+            .withConstValue(C2PrivateBlockPoolsTuning::AllocShared(0u))
+            .build());
+}
+
+void SimpleInterface<void>::BaseParams::noInputReferences() {
+    addParameter(
+            DefineParam(mMaxInputReferenceAge, C2_PARAMKEY_INPUT_MAX_REFERENCE_AGE)
+            .withConstValue(new C2StreamMaxReferenceAgeTuning::input(0u))
+            .build());
+
+    addParameter(
+            DefineParam(mMaxInputReferenceCount, C2_PARAMKEY_INPUT_MAX_REFERENCE_COUNT)
+            .withConstValue(new C2StreamMaxReferenceCountTuning::input(0u))
+            .build());
+}
+
+void SimpleInterface<void>::BaseParams::noOutputReferences() {
+    addParameter(
+            DefineParam(mMaxOutputReferenceAge, C2_PARAMKEY_OUTPUT_MAX_REFERENCE_AGE)
+            .withConstValue(new C2StreamMaxReferenceAgeTuning::output(0u))
+            .build());
+
+    addParameter(
+            DefineParam(mMaxOutputReferenceCount, C2_PARAMKEY_OUTPUT_MAX_REFERENCE_COUNT)
+            .withConstValue(new C2StreamMaxReferenceCountTuning::output(0u))
+            .build());
+}
+
+void SimpleInterface<void>::BaseParams::noTimeStretch() {
+    addParameter(
+            DefineParam(mTimeStretch, C2_PARAMKEY_TIME_STRETCH)
+            .withConstValue(new C2ComponentTimeStretchTuning(1.f))
+            .build());
+}
+
+/*
+    Clients need to handle the following base params due to custom dependency.
+
+    std::shared_ptr<C2ApiLevelSetting> mApiLevel;
+    std::shared_ptr<C2ApiFeaturesSetting> mApiFeatures;
+    std::shared_ptr<C2ComponentAttributesSetting> mAttrib;
+
+    std::shared_ptr<C2PortSuggestedBufferCountTuning::input> mSuggestedInputBufferCount;
+    std::shared_ptr<C2PortSuggestedBufferCountTuning::output> mSuggestedOutputBufferCount;
+
+    std::shared_ptr<C2TrippedTuning> mTripped;
+
+*/
+
+} // namespace android
diff --git a/media/codec2/components/base/exports.lds b/media/codec2/components/base/exports.lds
new file mode 100644
index 0000000..641bae8
--- /dev/null
+++ b/media/codec2/components/base/exports.lds
@@ -0,0 +1,7 @@
+{
+    global:
+        CreateCodec2Factory;
+        DestroyCodec2Factory;
+    local: *;
+};
+
diff --git a/media/codec2/components/base/include/SimpleC2Component.h b/media/codec2/components/base/include/SimpleC2Component.h
new file mode 100644
index 0000000..22d5714
--- /dev/null
+++ b/media/codec2/components/base/include/SimpleC2Component.h
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SIMPLE_C2_COMPONENT_H_
+#define SIMPLE_C2_COMPONENT_H_
+
+#include <list>
+#include <unordered_map>
+
+#include <C2Component.h>
+
+#include <media/stagefright/foundation/AHandler.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/foundation/Mutexed.h>
+
+namespace android {
+
+class SimpleC2Component
+        : public C2Component, public std::enable_shared_from_this<SimpleC2Component> {
+public:
+    explicit SimpleC2Component(
+            const std::shared_ptr<C2ComponentInterface> &intf);
+    virtual ~SimpleC2Component();
+
+    // C2Component
+    // From C2Component
+    virtual c2_status_t setListener_vb(
+            const std::shared_ptr<Listener> &listener, c2_blocking_t mayBlock) override;
+    virtual c2_status_t queue_nb(std::list<std::unique_ptr<C2Work>>* const items) override;
+    virtual c2_status_t announce_nb(const std::vector<C2WorkOutline> &items) override;
+    virtual c2_status_t flush_sm(
+            flush_mode_t mode, std::list<std::unique_ptr<C2Work>>* const flushedWork) override;
+    virtual c2_status_t drain_nb(drain_mode_t mode) override;
+    virtual c2_status_t start() override;
+    virtual c2_status_t stop() override;
+    virtual c2_status_t reset() override;
+    virtual c2_status_t release() override;
+    virtual std::shared_ptr<C2ComponentInterface> intf() override;
+
+    // for handler
+    bool processQueue();
+
+protected:
+    /**
+     * Initialize internal states of the component according to the config set
+     * in the interface.
+     *
+     * This method is called during start(), but only at the first invocation or
+     * after reset().
+     */
+    virtual c2_status_t onInit() = 0;
+
+    /**
+     * Stop the component.
+     */
+    virtual c2_status_t onStop() = 0;
+
+    /**
+     * Reset the component.
+     */
+    virtual void onReset() = 0;
+
+    /**
+     * Release the component.
+     */
+    virtual void onRelease() = 0;
+
+    /**
+     * Flush the component.
+     */
+    virtual c2_status_t onFlush_sm() = 0;
+
+    /**
+     * Process the given work and finish pending work using finish().
+     *
+     * \param[in,out]   work    the work to process
+     * \param[in]       pool    the pool to use for allocating output blocks.
+     */
+    virtual void process(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool) = 0;
+
+    /**
+     * Drain the component and finish pending work using finish().
+     *
+     * \param[in]   drainMode   mode of drain.
+     * \param[in]   pool        the pool to use for allocating output blocks.
+     *
+     * \retval C2_OK            The component has drained all pending output
+     *                          work.
+     * \retval C2_OMITTED       Unsupported mode (e.g. DRAIN_CHAIN)
+     */
+    virtual c2_status_t drain(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool) = 0;
+
+    // for derived classes
+    /**
+     * Finish pending work.
+     *
+     * This method will retrieve the pending work according to |frameIndex| and
+     * feed the work into |fillWork| function. |fillWork| must be
+     * "non-blocking". Once |fillWork| returns the filled work will be returned
+     * to the client.
+     *
+     * \param[in]   frameIndex    the index of the pending work
+     * \param[in]   fillWork      the function to fill the retrieved work.
+     */
+    void finish(uint64_t frameIndex, std::function<void(const std::unique_ptr<C2Work> &)> fillWork);
+
+    /**
+     * Clone pending or current work and send the work back to client.
+     *
+     * This method will retrieve and clone the pending or current work according
+     * to |frameIndex| and feed the work into |fillWork| function. |fillWork|
+     * must be "non-blocking". Once |fillWork| returns the filled work will be
+     * returned to the client.
+     *
+     * \param[in]   frameIndex    the index of the work
+     * \param[in]   currentWork   the current work under processing
+     * \param[in]   fillWork      the function to fill the retrieved work.
+     */
+    void cloneAndSend(
+            uint64_t frameIndex,
+            const std::unique_ptr<C2Work> &currentWork,
+            std::function<void(const std::unique_ptr<C2Work> &)> fillWork);
+
+
+    std::shared_ptr<C2Buffer> createLinearBuffer(
+            const std::shared_ptr<C2LinearBlock> &block);
+
+    std::shared_ptr<C2Buffer> createLinearBuffer(
+            const std::shared_ptr<C2LinearBlock> &block, size_t offset, size_t size);
+
+    std::shared_ptr<C2Buffer> createGraphicBuffer(
+            const std::shared_ptr<C2GraphicBlock> &block);
+
+    std::shared_ptr<C2Buffer> createGraphicBuffer(
+            const std::shared_ptr<C2GraphicBlock> &block,
+            const C2Rect &crop);
+
+    static constexpr uint32_t NO_DRAIN = ~0u;
+
+    C2ReadView mDummyReadView;
+
+private:
+    const std::shared_ptr<C2ComponentInterface> mIntf;
+
+    class WorkHandler : public AHandler {
+    public:
+        enum {
+            kWhatProcess,
+            kWhatInit,
+            kWhatStart,
+            kWhatStop,
+            kWhatReset,
+            kWhatRelease,
+        };
+
+        WorkHandler();
+        ~WorkHandler() override = default;
+
+        void setComponent(const std::shared_ptr<SimpleC2Component> &thiz);
+
+    protected:
+        void onMessageReceived(const sp<AMessage> &msg) override;
+
+    private:
+        std::weak_ptr<SimpleC2Component> mThiz;
+        bool mRunning;
+    };
+
+    enum {
+        UNINITIALIZED,
+        STOPPED,
+        RUNNING,
+    };
+
+    struct ExecState {
+        ExecState() : mState(UNINITIALIZED) {}
+
+        int mState;
+        std::shared_ptr<C2Component::Listener> mListener;
+    };
+    Mutexed<ExecState> mExecState;
+
+    sp<ALooper> mLooper;
+    sp<WorkHandler> mHandler;
+
+    class WorkQueue {
+    public:
+        typedef std::unordered_map<uint64_t, std::unique_ptr<C2Work>> PendingWork;
+
+        inline WorkQueue() : mFlush(false), mGeneration(0ul) {}
+
+        inline uint64_t generation() const { return mGeneration; }
+        inline void incGeneration() { ++mGeneration; mFlush = true; }
+
+        std::unique_ptr<C2Work> pop_front();
+        void push_back(std::unique_ptr<C2Work> work);
+        bool empty() const;
+        uint32_t drainMode() const;
+        void markDrain(uint32_t drainMode);
+        inline bool popPendingFlush() {
+            bool flush = mFlush;
+            mFlush = false;
+            return flush;
+        }
+        void clear();
+        PendingWork &pending() { return mPendingWork; }
+
+    private:
+        struct Entry {
+            std::unique_ptr<C2Work> work;
+            uint32_t drainMode;
+        };
+
+        bool mFlush;
+        uint64_t mGeneration;
+        std::list<Entry> mQueue;
+        PendingWork mPendingWork;
+    };
+    Mutexed<WorkQueue> mWorkQueue;
+
+    class BlockingBlockPool;
+    std::shared_ptr<BlockingBlockPool> mOutputBlockPool;
+
+    SimpleC2Component() = delete;
+};
+
+}  // namespace android
+
+#endif  // SIMPLE_C2_COMPONENT_H_
diff --git a/media/codec2/components/base/include/SimpleC2Interface.h b/media/codec2/components/base/include/SimpleC2Interface.h
new file mode 100644
index 0000000..2051d3d
--- /dev/null
+++ b/media/codec2/components/base/include/SimpleC2Interface.h
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SIMPLE_C2_INTERFACE_H_
+#define ANDROID_SIMPLE_C2_INTERFACE_H_
+
+#include <C2Component.h>
+#include <C2Config.h>
+#include <util/C2InterfaceHelper.h>
+
+namespace android {
+
+/**
+ * Wrap a common interface object (such as Codec2Client::Interface, or C2InterfaceHelper into
+ * a C2ComponentInterface.
+ *
+ * \param T common interface type
+ */
+template <typename T>
+class SimpleC2Interface : public C2ComponentInterface {
+public:
+    SimpleC2Interface(const char *name, c2_node_id_t id, const std::shared_ptr<T> &impl)
+        : mName(name),
+          mId(id),
+          mImpl(impl) {
+    }
+
+    ~SimpleC2Interface() override = default;
+
+    // From C2ComponentInterface
+    C2String getName() const override { return mName; }
+    c2_node_id_t getId() const override { return mId; }
+    c2_status_t query_vb(
+            const std::vector<C2Param*> &stackParams,
+            const std::vector<C2Param::Index> &heapParamIndices,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2Param>>* const heapParams) const override {
+        return mImpl->query(stackParams, heapParamIndices, mayBlock, heapParams);
+    }
+    c2_status_t config_vb(
+            const std::vector<C2Param*> &params,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2SettingResult>>* const failures) override {
+        return mImpl->config(params, mayBlock, failures);
+    }
+    c2_status_t createTunnel_sm(c2_node_id_t) override { return C2_OMITTED; }
+    c2_status_t releaseTunnel_sm(c2_node_id_t) override { return C2_OMITTED; }
+    c2_status_t querySupportedParams_nb(
+            std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const override {
+        return mImpl->querySupportedParams(params);
+    }
+    c2_status_t querySupportedValues_vb(
+            std::vector<C2FieldSupportedValuesQuery> &fields,
+            c2_blocking_t mayBlock) const override {
+        return mImpl->querySupportedValues(fields, mayBlock);
+    }
+
+private:
+    C2String mName;
+    const c2_node_id_t mId;
+    const std::shared_ptr<T> mImpl;
+};
+
+/**
+ * Utility classes for common interfaces.
+ */
+template<>
+class SimpleC2Interface<void> {
+public:
+    /**
+     * Base Codec 2.0 parameters required for all components.
+     */
+    struct BaseParams : C2InterfaceHelper {
+        explicit BaseParams(
+                const std::shared_ptr<C2ReflectorHelper> &helper,
+                C2String name,
+                C2Component::kind_t kind,
+                C2Component::domain_t domain,
+                C2String mediaType,
+                std::vector<C2String> aliases = std::vector<C2String>());
+
+        /// Marks that this component has no input latency. Otherwise, component must
+        /// add support for C2PortRequestedDelayTuning::input and C2PortActualDelayTuning::input.
+        void noInputLatency();
+
+        /// Marks that this component has no output latency. Otherwise, component must
+        /// add support for C2PortRequestedDelayTuning::output and C2PortActualDelayTuning::output.
+        void noOutputLatency();
+
+        /// Marks that this component has no pipeline latency. Otherwise, component must
+        /// add support for C2RequestedPipelineDelayTuning and C2ActualPipelineDelayTuning.
+        void noPipelineLatency();
+
+        /// Marks that this component has no need for private buffers. Otherwise, component must
+        /// add support for C2MaxPrivateBufferCountTuning, C2PrivateAllocatorsTuning and
+        /// C2PrivateBlockPoolsTuning.
+        void noPrivateBuffers();
+
+        /// Marks that this component holds no references to input buffers. Otherwise, component
+        /// must add support for C2StreamMaxReferenceAgeTuning::input and
+        /// C2StreamMaxReferenceCountTuning::input.
+        void noInputReferences();
+
+        /// Marks that this component holds no references to output buffers. Otherwise, component
+        /// must add support for C2StreamMaxReferenceAgeTuning::output and
+        /// C2StreamMaxReferenceCountTuning::output.
+        void noOutputReferences();
+
+        /// Marks that this component does not stretch time. Otherwise, component
+        /// must add support for C2ComponentTimeStretchTuning.
+        void noTimeStretch();
+
+        std::shared_ptr<C2ApiLevelSetting> mApiLevel;
+        std::shared_ptr<C2ApiFeaturesSetting> mApiFeatures;
+
+        std::shared_ptr<C2PlatformLevelSetting> mPlatformLevel;
+        std::shared_ptr<C2PlatformFeaturesSetting> mPlatformFeatures;
+
+        std::shared_ptr<C2ComponentNameSetting> mName;
+        std::shared_ptr<C2ComponentAliasesSetting> mAliases;
+        std::shared_ptr<C2ComponentKindSetting> mKind;
+        std::shared_ptr<C2ComponentDomainSetting> mDomain;
+        std::shared_ptr<C2ComponentAttributesSetting> mAttrib;
+        std::shared_ptr<C2ComponentTimeStretchTuning> mTimeStretch;
+
+        std::shared_ptr<C2PortMediaTypeSetting::input> mInputMediaType;
+        std::shared_ptr<C2PortMediaTypeSetting::output> mOutputMediaType;
+        std::shared_ptr<C2StreamBufferTypeSetting::input> mInputFormat;
+        std::shared_ptr<C2StreamBufferTypeSetting::output> mOutputFormat;
+
+        std::shared_ptr<C2PortRequestedDelayTuning::input> mRequestedInputDelay;
+        std::shared_ptr<C2PortRequestedDelayTuning::output> mRequestedOutputDelay;
+        std::shared_ptr<C2RequestedPipelineDelayTuning> mRequestedPipelineDelay;
+
+        std::shared_ptr<C2PortActualDelayTuning::input> mActualInputDelay;
+        std::shared_ptr<C2PortActualDelayTuning::output> mActualOutputDelay;
+        std::shared_ptr<C2ActualPipelineDelayTuning> mActualPipelineDelay;
+
+        std::shared_ptr<C2StreamMaxReferenceAgeTuning::input> mMaxInputReferenceAge;
+        std::shared_ptr<C2StreamMaxReferenceCountTuning::input> mMaxInputReferenceCount;
+        std::shared_ptr<C2StreamMaxReferenceAgeTuning::output> mMaxOutputReferenceAge;
+        std::shared_ptr<C2StreamMaxReferenceCountTuning::output> mMaxOutputReferenceCount;
+        std::shared_ptr<C2MaxPrivateBufferCountTuning> mMaxPrivateBufferCount;
+
+        std::shared_ptr<C2PortStreamCountTuning::input> mInputStreamCount;
+        std::shared_ptr<C2PortStreamCountTuning::output> mOutputStreamCount;
+
+        std::shared_ptr<C2SubscribedParamIndicesTuning> mSubscribedParamIndices;
+        std::shared_ptr<C2PortSuggestedBufferCountTuning::input> mSuggestedInputBufferCount;
+        std::shared_ptr<C2PortSuggestedBufferCountTuning::output> mSuggestedOutputBufferCount;
+
+        std::shared_ptr<C2CurrentWorkTuning> mCurrentWorkOrdinal;
+        std::shared_ptr<C2LastWorkQueuedTuning::input> mLastInputQueuedWorkOrdinal;
+        std::shared_ptr<C2LastWorkQueuedTuning::output> mLastOutputQueuedWorkOrdinal;
+
+        std::shared_ptr<C2PortAllocatorsTuning::input> mInputAllocators;
+        std::shared_ptr<C2PortAllocatorsTuning::output> mOutputAllocators;
+        std::shared_ptr<C2PrivateAllocatorsTuning> mPrivateAllocators;
+        std::shared_ptr<C2PortBlockPoolsTuning::output> mOutputPoolIds;
+        std::shared_ptr<C2PrivateBlockPoolsTuning> mPrivatePoolIds;
+
+        std::shared_ptr<C2TrippedTuning> mTripped;
+        std::shared_ptr<C2OutOfMemoryTuning> mOutOfMemory;
+
+        std::shared_ptr<C2PortConfigCounterTuning::input> mInputConfigCounter;
+        std::shared_ptr<C2PortConfigCounterTuning::output> mOutputConfigCounter;
+        std::shared_ptr<C2ConfigCounterTuning> mDirectConfigCounter;
+    };
+};
+
+template<typename T>
+using SimpleInterface = SimpleC2Interface<T>;
+
+template<typename T, typename ...Args>
+std::shared_ptr<T> AllocSharedString(const Args(&... args), const char *str) {
+    size_t len = strlen(str) + 1;
+    std::shared_ptr<T> ret = T::AllocShared(len, args...);
+    strcpy(ret->m.value, str);
+    return ret;
+}
+
+template<typename T, typename ...Args>
+std::shared_ptr<T> AllocSharedString(const Args(&... args), const std::string &str) {
+    std::shared_ptr<T> ret = T::AllocShared(str.length() + 1, args...);
+    strcpy(ret->m.value, str.c_str());
+    return ret;
+}
+
+template <typename T>
+struct Setter {
+    typedef typename std::remove_reference<T>::type type;
+
+    static C2R NonStrictValueWithNoDeps(
+            bool mayBlock, C2InterfaceHelper::C2P<type> &me) {
+        (void)mayBlock;
+        return me.F(me.v.value).validatePossible(me.v.value);
+    }
+
+    static C2R NonStrictValuesWithNoDeps(
+            bool mayBlock, C2InterfaceHelper::C2P<type> &me) {
+        (void)mayBlock;
+        C2R res = C2R::Ok();
+        for (size_t ix = 0; ix < me.v.flexCount(); ++ix) {
+            res.plus(me.F(me.v.m.values[ix]).validatePossible(me.v.m.values[ix]));
+        }
+        return res;
+    }
+
+    static C2R StrictValueWithNoDeps(
+            bool mayBlock,
+            const C2InterfaceHelper::C2P<type> &old,
+            C2InterfaceHelper::C2P<type> &me) {
+        (void)mayBlock;
+        if (!me.F(me.v.value).supportsNow(me.v.value)) {
+            me.set().value = old.v.value;
+        }
+        return me.F(me.v.value).validatePossible(me.v.value);
+    }
+};
+
+}  // namespace android
+
+#endif  // ANDROID_SIMPLE_C2_INTERFACE_H_
diff --git a/media/codec2/components/cmds/Android.bp b/media/codec2/components/cmds/Android.bp
new file mode 100644
index 0000000..35f689e
--- /dev/null
+++ b/media/codec2/components/cmds/Android.bp
@@ -0,0 +1,36 @@
+cc_binary {
+    name: "codec2play",
+    defaults: ["libcodec2-impl-defaults"],
+
+    srcs: [
+        "codec2.cpp",
+    ],
+
+    include_dirs: [
+    ],
+
+    shared_libs: [
+        "libbase",
+        "libbinder",
+        "libcutils",
+        "libgui",
+        "liblog",
+        "libstagefright",
+        "libstagefright_foundation",
+        "libui",
+        "libutils",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+
+    sanitize: {
+        cfi: true,
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+    },
+}
diff --git a/media/codec2/components/cmds/codec2.cpp b/media/codec2/components/cmds/codec2.cpp
new file mode 100644
index 0000000..f2cf545
--- /dev/null
+++ b/media/codec2/components/cmds/codec2.cpp
@@ -0,0 +1,483 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <inttypes.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <thread>
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "codec2"
+#include <log/log.h>
+
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <media/DataSource.h>
+#include <media/ICrypto.h>
+#include <media/IMediaHTTPService.h>
+#include <media/MediaSource.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/AUtils.h>
+#include <media/stagefright/DataSourceFactory.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MediaExtractorFactory.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/Utils.h>
+
+#include <gui/GLConsumer.h>
+#include <gui/IProducerListener.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
+
+#include <C2AllocatorGralloc.h>
+#include <C2Buffer.h>
+#include <C2BufferPriv.h>
+#include <C2Component.h>
+#include <C2Config.h>
+#include <C2Debug.h>
+#include <C2PlatformSupport.h>
+#include <C2Work.h>
+
+using namespace android;
+using namespace std::chrono_literals;
+
+namespace {
+
+class LinearBuffer : public C2Buffer {
+public:
+    explicit LinearBuffer(const std::shared_ptr<C2LinearBlock> &block)
+        : C2Buffer({ block->share(block->offset(), block->size(), ::C2Fence()) }) {}
+};
+
+class Listener;
+
+class SimplePlayer {
+public:
+    SimplePlayer();
+    ~SimplePlayer();
+
+    void onWorkDone(std::weak_ptr<C2Component> component,
+                    std::list<std::unique_ptr<C2Work>> workItems);
+    void onTripped(std::weak_ptr<C2Component> component,
+                   std::vector<std::shared_ptr<C2SettingResult>> settingResult);
+    void onError(std::weak_ptr<C2Component> component, uint32_t errorCode);
+
+    void play(const sp<IMediaSource> &source);
+
+private:
+    typedef std::unique_lock<std::mutex> ULock;
+
+    std::shared_ptr<Listener> mListener;
+    std::shared_ptr<C2Component> mComponent;
+
+    sp<IProducerListener> mProducerListener;
+
+    std::atomic_int mLinearPoolId;
+
+    std::shared_ptr<C2Allocator> mAllocIon;
+    std::shared_ptr<C2BlockPool> mLinearPool;
+
+    std::mutex mQueueLock;
+    std::condition_variable mQueueCondition;
+    std::list<std::unique_ptr<C2Work>> mWorkQueue;
+
+    std::mutex mProcessedLock;
+    std::condition_variable mProcessedCondition;
+    std::list<std::unique_ptr<C2Work>> mProcessedWork;
+
+    sp<Surface> mSurface;
+    sp<SurfaceComposerClient> mComposerClient;
+    sp<SurfaceControl> mControl;
+};
+
+class Listener : public C2Component::Listener {
+public:
+    explicit Listener(SimplePlayer *thiz) : mThis(thiz) {}
+    virtual ~Listener() = default;
+
+    virtual void onWorkDone_nb(std::weak_ptr<C2Component> component,
+                            std::list<std::unique_ptr<C2Work>> workItems) override {
+        mThis->onWorkDone(component, std::move(workItems));
+    }
+
+    virtual void onTripped_nb(std::weak_ptr<C2Component> component,
+                           std::vector<std::shared_ptr<C2SettingResult>> settingResult) override {
+        mThis->onTripped(component, settingResult);
+    }
+
+    virtual void onError_nb(std::weak_ptr<C2Component> component,
+                         uint32_t errorCode) override {
+        mThis->onError(component, errorCode);
+    }
+
+private:
+    SimplePlayer * const mThis;
+};
+
+
+SimplePlayer::SimplePlayer()
+    : mListener(new Listener(this)),
+      mProducerListener(new DummyProducerListener),
+      mLinearPoolId(C2BlockPool::PLATFORM_START),
+      mComposerClient(new SurfaceComposerClient) {
+    CHECK_EQ(mComposerClient->initCheck(), (status_t)OK);
+
+    std::shared_ptr<C2AllocatorStore> store = GetCodec2PlatformAllocatorStore();
+    CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &mAllocIon), C2_OK);
+    mLinearPool = std::make_shared<C2PooledBlockPool>(mAllocIon, mLinearPoolId++);
+
+    mControl = mComposerClient->createSurface(
+            String8("A Surface"),
+            1280,
+            800,
+            HAL_PIXEL_FORMAT_YV12);
+            //PIXEL_FORMAT_RGB_565);
+
+    CHECK(mControl != nullptr);
+    CHECK(mControl->isValid());
+
+    SurfaceComposerClient::Transaction{}
+            .setLayer(mControl, INT_MAX)
+            .show(mControl)
+            .apply();
+
+    mSurface = mControl->getSurface();
+    CHECK(mSurface != nullptr);
+    mSurface->connect(NATIVE_WINDOW_API_CPU, mProducerListener);
+}
+
+SimplePlayer::~SimplePlayer() {
+    mComposerClient->dispose();
+}
+
+void SimplePlayer::onWorkDone(
+        std::weak_ptr<C2Component> component, std::list<std::unique_ptr<C2Work>> workItems) {
+    ALOGV("SimplePlayer::onWorkDone");
+    (void) component;
+    ULock l(mProcessedLock);
+    for (auto & item : workItems) {
+        mProcessedWork.push_back(std::move(item));
+    }
+    mProcessedCondition.notify_all();
+}
+
+void SimplePlayer::onTripped(
+        std::weak_ptr<C2Component> component,
+        std::vector<std::shared_ptr<C2SettingResult>> settingResult) {
+    (void) component;
+    (void) settingResult;
+    // TODO
+}
+
+void SimplePlayer::onError(std::weak_ptr<C2Component> component, uint32_t errorCode) {
+    (void) component;
+    (void) errorCode;
+    // TODO
+}
+
+void SimplePlayer::play(const sp<IMediaSource> &source) {
+    ALOGV("SimplePlayer::play");
+    sp<AMessage> format;
+    (void) convertMetaDataToMessage(source->getFormat(), &format);
+
+    sp<ABuffer> csd0, csd1;
+    format->findBuffer("csd-0", &csd0);
+    format->findBuffer("csd-1", &csd1);
+
+    status_t err = source->start();
+
+    if (err != OK) {
+        fprintf(stderr, "source returned error %d (0x%08x)\n", err, err);
+        return;
+    }
+
+    std::shared_ptr<C2ComponentStore> store = GetCodec2PlatformComponentStore();
+    std::shared_ptr<C2Component> component;
+    (void)store->createComponent("c2.android.avc.decoder", &component);
+
+    (void)component->setListener_vb(mListener, C2_DONT_BLOCK);
+    std::unique_ptr<C2PortBlockPoolsTuning::output> pools =
+        C2PortBlockPoolsTuning::output::AllocUnique({ (uint64_t)C2BlockPool::BASIC_GRAPHIC });
+    std::vector<std::unique_ptr<C2SettingResult>> result;
+    (void)component->intf()->config_vb({pools.get()}, C2_DONT_BLOCK, &result);
+    component->start();
+
+    for (int i = 0; i < 8; ++i) {
+        mWorkQueue.emplace_back(new C2Work);
+    }
+
+    std::atomic_bool running(true);
+    std::thread surfaceThread([this, &running]() {
+        const sp<IGraphicBufferProducer> &igbp = mSurface->getIGraphicBufferProducer();
+        while (running) {
+            std::unique_ptr<C2Work> work;
+            {
+                ULock l(mProcessedLock);
+                if (mProcessedWork.empty()) {
+                    mProcessedCondition.wait_for(l, 100ms);
+                    if (mProcessedWork.empty()) {
+                        continue;
+                    }
+                }
+                work.swap(mProcessedWork.front());
+                mProcessedWork.pop_front();
+            }
+            int slot;
+            sp<Fence> fence;
+            ALOGV("Render: Frame #%lld", work->worklets.front()->output.ordinal.frameIndex.peekll());
+            const std::shared_ptr<C2Buffer> &output = work->worklets.front()->output.buffers[0];
+            if (output) {
+                const C2ConstGraphicBlock block = output->data().graphicBlocks().front();
+                native_handle_t *grallocHandle = UnwrapNativeCodec2GrallocHandle(block.handle());
+                sp<GraphicBuffer> buffer(new GraphicBuffer(
+                        grallocHandle,
+                        GraphicBuffer::CLONE_HANDLE,
+                        block.width(),
+                        block.height(),
+                        HAL_PIXEL_FORMAT_YV12,
+                        1,
+                        (uint64_t)GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+                        block.width()));
+                native_handle_delete(grallocHandle);
+
+                status_t err = igbp->attachBuffer(&slot, buffer);
+
+                IGraphicBufferProducer::QueueBufferInput qbi(
+                        (work->worklets.front()->output.ordinal.timestamp * 1000ll).peekll(),
+                        false,
+                        HAL_DATASPACE_UNKNOWN,
+                        Rect(block.width(), block.height()),
+                        NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
+                        0,
+                        Fence::NO_FENCE,
+                        0);
+                IGraphicBufferProducer::QueueBufferOutput qbo;
+                err = igbp->queueBuffer(slot, qbi, &qbo);
+            }
+
+            work->input.buffers.clear();
+            work->worklets.clear();
+
+            ULock l(mQueueLock);
+            mWorkQueue.push_back(std::move(work));
+            mQueueCondition.notify_all();
+        }
+        ALOGV("render loop finished");
+    });
+
+    long numFrames = 0;
+    mLinearPool.reset(new C2PooledBlockPool(mAllocIon, mLinearPoolId++));
+
+    for (;;) {
+        size_t size = 0u;
+        void *data = nullptr;
+        int64_t timestamp = 0u;
+        MediaBufferBase *buffer = nullptr;
+        sp<ABuffer> csd;
+        if (csd0 != nullptr) {
+            csd = csd0;
+            csd0 = nullptr;
+        } else if (csd1 != nullptr) {
+            csd = csd1;
+            csd1 = nullptr;
+        } else {
+            status_t err = source->read(&buffer);
+            if (err != OK) {
+                CHECK(buffer == nullptr);
+
+                if (err == INFO_FORMAT_CHANGED) {
+                    continue;
+                }
+
+                break;
+            }
+            MetaDataBase &meta = buffer->meta_data();
+            CHECK(meta.findInt64(kKeyTime, &timestamp));
+
+            size = buffer->size();
+            data = buffer->data();
+        }
+
+        if (csd != nullptr) {
+            size = csd->size();
+            data = csd->data();
+        }
+
+        // Prepare C2Work
+
+        std::unique_ptr<C2Work> work;
+        while (!work) {
+            ULock l(mQueueLock);
+            if (!mWorkQueue.empty()) {
+                work.swap(mWorkQueue.front());
+                mWorkQueue.pop_front();
+            } else {
+                mQueueCondition.wait_for(l, 100ms);
+            }
+        }
+        work->input.flags = (C2FrameData::flags_t)0;
+        work->input.ordinal.timestamp = timestamp;
+        work->input.ordinal.frameIndex = numFrames;
+
+        std::shared_ptr<C2LinearBlock> block;
+        mLinearPool->fetchLinearBlock(
+                size,
+                { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
+                &block);
+        C2WriteView view = block->map().get();
+        if (view.error() != C2_OK) {
+            fprintf(stderr, "C2LinearBlock::map() failed : %d", view.error());
+            break;
+        }
+        memcpy(view.base(), data, size);
+
+        work->input.buffers.clear();
+        work->input.buffers.emplace_back(new LinearBuffer(block));
+        work->worklets.clear();
+        work->worklets.emplace_back(new C2Worklet);
+
+        std::list<std::unique_ptr<C2Work>> items;
+        items.push_back(std::move(work));
+
+        ALOGV("Frame #%ld size = %zu", numFrames, size);
+        // DO THE DECODING
+        component->queue_nb(&items);
+
+        if (buffer) {
+            buffer->release();
+            buffer = nullptr;
+        }
+
+        ++numFrames;
+    }
+    ALOGV("main loop finished");
+    source->stop();
+    running.store(false);
+    surfaceThread.join();
+
+    component->release();
+    printf("\n");
+}
+
+}  // namespace
+
+static void usage(const char *me) {
+    fprintf(stderr, "usage: %s [options] [input_filename]\n", me);
+    fprintf(stderr, "       -h(elp)\n");
+}
+
+int main(int argc, char **argv) {
+    android::ProcessState::self()->startThreadPool();
+
+    int res;
+    while ((res = getopt(argc, argv, "h")) >= 0) {
+        switch (res) {
+            case 'h':
+            default:
+            {
+                usage(argv[0]);
+                exit(1);
+                break;
+            }
+        }
+    }
+
+    argc -= optind;
+    argv += optind;
+
+    if (argc < 1) {
+        fprintf(stderr, "No input file specified\n");
+        return 1;
+    }
+
+    status_t err = OK;
+    SimplePlayer player;
+
+    for (int k = 0; k < argc && err == OK; ++k) {
+        const char *filename = argv[k];
+
+        sp<DataSource> dataSource =
+            DataSourceFactory::CreateFromURI(nullptr /* httpService */, filename);
+
+        if (strncasecmp(filename, "sine:", 5) && dataSource == nullptr) {
+            fprintf(stderr, "Unable to create data source.\n");
+            return 1;
+        }
+
+        Vector<sp<IMediaSource> > mediaSources;
+        sp<IMediaSource> mediaSource;
+
+        sp<IMediaExtractor> extractor = MediaExtractorFactory::Create(dataSource);
+
+        if (extractor == nullptr) {
+            fprintf(stderr, "could not create extractor.\n");
+            return -1;
+        }
+
+        sp<MetaData> meta = extractor->getMetaData();
+
+        if (meta != nullptr) {
+            const char *mime;
+            if (!meta->findCString(kKeyMIMEType, &mime)) {
+                fprintf(stderr, "extractor did not provide MIME type.\n");
+                return -1;
+            }
+        }
+
+        size_t numTracks = extractor->countTracks();
+
+        size_t i;
+        for (i = 0; i < numTracks; ++i) {
+            meta = extractor->getTrackMetaData(i, 0);
+
+            if (meta == nullptr) {
+                break;
+            }
+            const char *mime;
+            meta->findCString(kKeyMIMEType, &mime);
+
+            // TODO: allowing AVC only for the time being
+            if (!strncasecmp(mime, "video/avc", 9)) {
+                break;
+            }
+
+            meta = nullptr;
+        }
+
+        if (meta == nullptr) {
+            fprintf(stderr, "No AVC track found.\n");
+            return -1;
+        }
+
+        mediaSource = extractor->getTrack(i);
+        if (mediaSource == nullptr) {
+            fprintf(stderr, "skip NULL track %zu, total tracks %zu.\n", i, numTracks);
+            return -1;
+        }
+
+        player.play(mediaSource);
+    }
+
+    return 0;
+}
diff --git a/media/codec2/components/flac/Android.bp b/media/codec2/components/flac/Android.bp
new file mode 100644
index 0000000..e5eb51d
--- /dev/null
+++ b/media/codec2/components/flac/Android.bp
@@ -0,0 +1,30 @@
+cc_library_shared {
+    name: "libcodec2_soft_flacdec",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_all-defaults",
+    ],
+
+    header_libs: ["libFLAC-headers"],
+
+    srcs: ["C2SoftFlacDec.cpp"],
+
+    shared_libs: [
+        "libstagefright_flacdec",
+    ],
+}
+
+cc_library_shared {
+    name: "libcodec2_soft_flacenc",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["C2SoftFlacEnc.cpp"],
+
+    static_libs: [
+        "libaudioutils",
+        "libFLAC",
+    ],
+}
diff --git a/media/codec2/components/flac/C2SoftFlacDec.cpp b/media/codec2/components/flac/C2SoftFlacDec.cpp
new file mode 100644
index 0000000..4039b9b
--- /dev/null
+++ b/media/codec2/components/flac/C2SoftFlacDec.cpp
@@ -0,0 +1,378 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftFlacDec"
+#include <log/log.h>
+
+#include <media/stagefright/foundation/MediaDefs.h>
+
+#include <C2PlatformSupport.h>
+#include <SimpleC2Interface.h>
+
+#include "C2SoftFlacDec.h"
+
+namespace android {
+
+namespace {
+
+constexpr char COMPONENT_NAME[] = "c2.android.flac.decoder";
+
+}  // namespace
+
+class C2SoftFlacDec::IntfImpl : public SimpleInterface<void>::BaseParams {
+public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+        : SimpleInterface<void>::BaseParams(
+                helper,
+                COMPONENT_NAME,
+                C2Component::KIND_DECODER,
+                C2Component::DOMAIN_AUDIO,
+                MEDIA_MIMETYPE_AUDIO_FLAC) {
+        noPrivateBuffers();
+        noInputReferences();
+        noOutputReferences();
+        noInputLatency();
+        noTimeStretch();
+        setDerivedInstance(this);
+
+        addParameter(
+                DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                .withConstValue(new C2ComponentAttributesSetting(
+                    C2Component::ATTRIB_IS_TEMPORAL))
+                .build());
+
+        addParameter(
+                DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE)
+                .withDefault(new C2StreamSampleRateInfo::output(0u, 44100))
+                .withFields({C2F(mSampleRate, value).inRange(1, 655350)})
+                .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
+                .build());
+
+        addParameter(
+                DefineParam(mChannelCount, C2_PARAMKEY_CHANNEL_COUNT)
+                .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
+                .withFields({C2F(mChannelCount, value).inRange(1, 8)})
+                .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
+                .withDefault(new C2StreamBitrateInfo::input(0u, 768000))
+                .withFields({C2F(mBitrate, value).inRange(1, 21000000)})
+                .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
+                .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 32768))
+                .build());
+
+        addParameter(
+                DefineParam(mPcmEncodingInfo, C2_PARAMKEY_PCM_ENCODING)
+                .withDefault(new C2StreamPcmEncodingInfo::output(0u, C2Config::PCM_16))
+                .withFields({C2F(mPcmEncodingInfo, value).oneOf({
+                     C2Config::PCM_16,
+                     // C2Config::PCM_8,
+                     C2Config::PCM_FLOAT})
+                })
+                .withSetter((Setter<decltype(*mPcmEncodingInfo)>::StrictValueWithNoDeps))
+                .build());
+    }
+
+    int32_t getPcmEncodingInfo() const { return mPcmEncodingInfo->value; }
+
+private:
+    std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
+    std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
+    std::shared_ptr<C2StreamBitrateInfo::input> mBitrate;
+    std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
+    std::shared_ptr<C2StreamPcmEncodingInfo::output> mPcmEncodingInfo;
+};
+
+C2SoftFlacDec::C2SoftFlacDec(
+        const char *name,
+        c2_node_id_t id,
+        const std::shared_ptr<IntfImpl> &intfImpl)
+    : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+      mIntf(intfImpl),
+      mFLACDecoder(nullptr) {
+}
+
+C2SoftFlacDec::~C2SoftFlacDec() {
+    onRelease();
+}
+
+c2_status_t C2SoftFlacDec::onInit() {
+    status_t err = initDecoder();
+    return err == OK ? C2_OK : C2_NO_MEMORY;
+}
+
+c2_status_t C2SoftFlacDec::onStop() {
+    if (mFLACDecoder) mFLACDecoder->flush();
+    memset(&mStreamInfo, 0, sizeof(mStreamInfo));
+    mHasStreamInfo = false;
+    mSignalledError = false;
+    mSignalledOutputEos = false;
+    return C2_OK;
+}
+
+void C2SoftFlacDec::onReset() {
+    mInputBufferCount = 0;
+    (void)onStop();
+}
+
+void C2SoftFlacDec::onRelease() {
+    mInputBufferCount = 0;
+    if (mFLACDecoder) delete mFLACDecoder;
+    mFLACDecoder = nullptr;
+}
+
+c2_status_t C2SoftFlacDec::onFlush_sm() {
+    return onStop();
+}
+
+status_t C2SoftFlacDec::initDecoder() {
+    if (mFLACDecoder) {
+        delete mFLACDecoder;
+    }
+    mFLACDecoder = FLACDecoder::Create();
+    if (!mFLACDecoder) {
+        ALOGE("initDecoder: failed to create FLACDecoder");
+        mSignalledError = true;
+        return NO_MEMORY;
+    }
+
+    memset(&mStreamInfo, 0, sizeof(mStreamInfo));
+    mHasStreamInfo = false;
+    mSignalledError = false;
+    mSignalledOutputEos = false;
+    mInputBufferCount = 0;
+
+    return OK;
+}
+
+static void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
+    work->worklets.front()->output.flags = work->input.flags;
+    work->worklets.front()->output.buffers.clear();
+    work->worklets.front()->output.ordinal = work->input.ordinal;
+    work->workletsProcessed = 1u;
+}
+
+// (TODO) add multiframe support, in plugin and FLACDecoder.cpp
+void C2SoftFlacDec::process(
+        const std::unique_ptr<C2Work> &work,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    // Initialize output work
+    work->result = C2_OK;
+    work->workletsProcessed = 1u;
+    work->worklets.front()->output.configUpdate.clear();
+    work->worklets.front()->output.flags = work->input.flags;
+
+    if (mSignalledError || mSignalledOutputEos) {
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+
+    C2ReadView rView = mDummyReadView;
+    size_t inOffset = 0u;
+    size_t inSize = 0u;
+    if (!work->input.buffers.empty()) {
+        rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
+        inSize = rView.capacity();
+        if (inSize && rView.error()) {
+            ALOGE("read view map failed %d", rView.error());
+            work->result = C2_CORRUPTED;
+            return;
+        }
+    }
+    bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
+    bool codecConfig = (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0;
+
+    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
+          (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
+
+    if (inSize == 0) {
+        fillEmptyWork(work);
+        if (eos) {
+            mSignalledOutputEos = true;
+            ALOGV("signalled EOS");
+        }
+        return;
+    }
+
+    if (mInputBufferCount == 0 && !codecConfig) {
+        ALOGV("First frame has to include configuration, forcing config");
+        codecConfig = true;
+    }
+
+    uint8_t *input = const_cast<uint8_t *>(rView.data() + inOffset);
+    if (codecConfig) {
+        status_t decoderErr = mFLACDecoder->parseMetadata(input, inSize);
+        if (decoderErr != OK && decoderErr != WOULD_BLOCK) {
+            ALOGE("process: FLACDecoder parseMetaData returns error %d", decoderErr);
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+
+        mInputBufferCount++;
+        fillEmptyWork(work);
+        if (eos) {
+            mSignalledOutputEos = true;
+            ALOGV("signalled EOS");
+        }
+
+        if (decoderErr == WOULD_BLOCK) {
+            ALOGV("process: parseMetadata is Blocking, Continue %d", decoderErr);
+        } else {
+            mStreamInfo = mFLACDecoder->getStreamInfo();
+            if (mStreamInfo.sample_rate && mStreamInfo.max_blocksize &&
+                mStreamInfo.channels) {
+                mHasStreamInfo = true;
+                C2StreamSampleRateInfo::output sampleRateInfo(
+                    0u, mStreamInfo.sample_rate);
+                C2StreamChannelCountInfo::output channelCountInfo(
+                    0u, mStreamInfo.channels);
+                std::vector<std::unique_ptr<C2SettingResult>> failures;
+                c2_status_t err =
+                    mIntf->config({&sampleRateInfo, &channelCountInfo},
+                                  C2_MAY_BLOCK, &failures);
+                if (err == OK) {
+                    work->worklets.front()->output.configUpdate.push_back(
+                        C2Param::Copy(sampleRateInfo));
+                    work->worklets.front()->output.configUpdate.push_back(
+                        C2Param::Copy(channelCountInfo));
+                } else {
+                    ALOGE("Config Update failed");
+                    mSignalledError = true;
+                    work->result = C2_CORRUPTED;
+                    return;
+                }
+            }
+            ALOGD("process: decoder configuration : %d Hz, %d channels, %d samples,"
+                  " %d block size", mStreamInfo.sample_rate, mStreamInfo.channels,
+                  (int)mStreamInfo.total_samples, mStreamInfo.max_blocksize);
+        }
+        return;
+    }
+
+    const bool outputFloat = mIntf->getPcmEncodingInfo() == C2Config::PCM_FLOAT;
+    const size_t sampleSize = outputFloat ? sizeof(float) : sizeof(short);
+    size_t outSize = mHasStreamInfo ?
+            mStreamInfo.max_blocksize * mStreamInfo.channels * sampleSize
+          : kMaxBlockSize * FLACDecoder::kMaxChannels * sampleSize;
+
+    std::shared_ptr<C2LinearBlock> block;
+    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+    c2_status_t err = pool->fetchLinearBlock(outSize, usage, &block);
+    if (err != C2_OK) {
+        ALOGE("fetchLinearBlock for Output failed with status %d", err);
+        work->result = C2_NO_MEMORY;
+        return;
+    }
+    C2WriteView wView = block->map().get();
+    if (wView.error()) {
+        ALOGE("write view map failed %d", wView.error());
+        work->result = C2_CORRUPTED;
+        return;
+    }
+
+    status_t decoderErr = mFLACDecoder->decodeOneFrame(
+                            input, inSize, wView.data(), &outSize, outputFloat);
+    if (decoderErr != OK) {
+        ALOGE("process: FLACDecoder decodeOneFrame returns error %d", decoderErr);
+        mSignalledError = true;
+        work->result = C2_CORRUPTED;
+        return;
+    }
+
+    mInputBufferCount++;
+    ALOGV("out buffer attr. size %zu", outSize);
+    work->worklets.front()->output.flags = work->input.flags;
+    work->worklets.front()->output.buffers.clear();
+    work->worklets.front()->output.buffers.push_back(createLinearBuffer(block, 0, outSize));
+    work->worklets.front()->output.ordinal = work->input.ordinal;
+    if (eos) {
+        mSignalledOutputEos = true;
+        ALOGV("signalled EOS");
+    }
+}
+
+c2_status_t C2SoftFlacDec::drain(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    (void) pool;
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+
+    if (mFLACDecoder) mFLACDecoder->flush();
+
+    return C2_OK;
+}
+
+class C2SoftFlacDecFactory : public C2ComponentFactory {
+public:
+    C2SoftFlacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+            GetCodec2PlatformComponentStore()->getParamReflector())) {
+    }
+
+    virtual c2_status_t createComponent(
+            c2_node_id_t id,
+            std::shared_ptr<C2Component>* const component,
+            std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+                new C2SoftFlacDec(COMPONENT_NAME,
+                                      id,
+                                      std::make_shared<C2SoftFlacDec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+            c2_node_id_t id,
+            std::shared_ptr<C2ComponentInterface>* const interface,
+            std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+                new SimpleInterface<C2SoftFlacDec::IntfImpl>(
+                        COMPONENT_NAME, id, std::make_shared<C2SoftFlacDec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftFlacDecFactory() override = default;
+
+private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftFlacDecFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/flac/C2SoftFlacDec.h b/media/codec2/components/flac/C2SoftFlacDec.h
new file mode 100644
index 0000000..b491bfd
--- /dev/null
+++ b/media/codec2/components/flac/C2SoftFlacDec.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_FLAC_DEC_H_
+#define ANDROID_C2_SOFT_FLAC_DEC_H_
+
+#include <SimpleC2Component.h>
+
+#include "FLACDecoder.h"
+
+namespace android {
+
+struct C2SoftFlacDec : public SimpleC2Component {
+    class IntfImpl;
+
+    C2SoftFlacDec(const char *name, c2_node_id_t id,
+                      const std::shared_ptr<IntfImpl> &intfImpl);
+    virtual ~C2SoftFlacDec();
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+    c2_status_t drain(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+
+private:
+    enum {
+        kMaxBlockSize   = 4096
+    };
+
+    std::shared_ptr<IntfImpl> mIntf;
+    FLACDecoder *mFLACDecoder;
+    FLAC__StreamMetadata_StreamInfo mStreamInfo;
+    bool mSignalledError;
+    bool mSignalledOutputEos;
+    bool mHasStreamInfo;
+    size_t mInputBufferCount;
+
+    status_t initDecoder();
+
+    C2_DO_NOT_COPY(C2SoftFlacDec);
+};
+
+}  // namespace android
+
+#endif  // ANDROID_C2_SOFT_FLAC_DEC_H_
diff --git a/media/codec2/components/flac/C2SoftFlacEnc.cpp b/media/codec2/components/flac/C2SoftFlacEnc.cpp
new file mode 100644
index 0000000..408db7e
--- /dev/null
+++ b/media/codec2/components/flac/C2SoftFlacEnc.cpp
@@ -0,0 +1,492 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftFlacEnc"
+#include <log/log.h>
+
+#include <audio_utils/primitives.h>
+#include <media/stagefright/foundation/MediaDefs.h>
+
+#include <C2PlatformSupport.h>
+#include <SimpleC2Interface.h>
+
+#include "C2SoftFlacEnc.h"
+
+namespace android {
+
+namespace {
+
+constexpr char COMPONENT_NAME[] = "c2.android.flac.encoder";
+
+}  // namespace
+
+class C2SoftFlacEnc::IntfImpl : public SimpleInterface<void>::BaseParams {
+public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+        : SimpleInterface<void>::BaseParams(
+                helper,
+                COMPONENT_NAME,
+                C2Component::KIND_ENCODER,
+                C2Component::DOMAIN_AUDIO,
+                MEDIA_MIMETYPE_AUDIO_FLAC) {
+        noPrivateBuffers();
+        noInputReferences();
+        noOutputReferences();
+        noInputLatency();
+        noTimeStretch();
+        setDerivedInstance(this);
+
+        addParameter(
+                DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                .withConstValue(new C2ComponentAttributesSetting(
+                    C2Component::ATTRIB_IS_TEMPORAL))
+                .build());
+        addParameter(
+                DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE)
+                .withDefault(new C2StreamSampleRateInfo::input(0u, 44100))
+                .withFields({C2F(mSampleRate, value).inRange(1, 655350)})
+                .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
+                .build());
+        addParameter(
+                DefineParam(mChannelCount, C2_PARAMKEY_CHANNEL_COUNT)
+                .withDefault(new C2StreamChannelCountInfo::input(0u, 1))
+                .withFields({C2F(mChannelCount, value).inRange(1, 2)})
+                .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
+                .build());
+        addParameter(
+                DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
+                .withDefault(new C2StreamBitrateInfo::output(0u, 768000))
+                .withFields({C2F(mBitrate, value).inRange(1, 21000000)})
+                .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
+                .build());
+        addParameter(
+                DefineParam(mComplexity, C2_PARAMKEY_COMPLEXITY)
+                .withDefault(new C2StreamComplexityTuning::output(0u,
+                    FLAC_COMPRESSION_LEVEL_DEFAULT))
+                .withFields({C2F(mComplexity, value).inRange(
+                    FLAC_COMPRESSION_LEVEL_MIN, FLAC_COMPRESSION_LEVEL_MAX)})
+                .withSetter(Setter<decltype(*mComplexity)>::NonStrictValueWithNoDeps)
+                .build());
+        addParameter(
+                DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
+                .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 4608))
+                .build());
+
+        addParameter(
+                DefineParam(mPcmEncodingInfo, C2_PARAMKEY_PCM_ENCODING)
+                .withDefault(new C2StreamPcmEncodingInfo::input(0u, C2Config::PCM_16))
+                .withFields({C2F(mPcmEncodingInfo, value).oneOf({
+                     C2Config::PCM_16,
+                     // C2Config::PCM_8,
+                     C2Config::PCM_FLOAT})
+                })
+                .withSetter((Setter<decltype(*mPcmEncodingInfo)>::StrictValueWithNoDeps))
+                .build());
+    }
+
+    uint32_t getSampleRate() const { return mSampleRate->value; }
+    uint32_t getChannelCount() const { return mChannelCount->value; }
+    uint32_t getBitrate() const { return mBitrate->value; }
+    uint32_t getComplexity() const { return mComplexity->value; }
+    int32_t getPcmEncodingInfo() const { return mPcmEncodingInfo->value; }
+
+private:
+    std::shared_ptr<C2StreamSampleRateInfo::input> mSampleRate;
+    std::shared_ptr<C2StreamChannelCountInfo::input> mChannelCount;
+    std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
+    std::shared_ptr<C2StreamComplexityTuning::output> mComplexity;
+    std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
+    std::shared_ptr<C2StreamPcmEncodingInfo::input> mPcmEncodingInfo;
+};
+
+C2SoftFlacEnc::C2SoftFlacEnc(
+        const char *name,
+        c2_node_id_t id,
+        const std::shared_ptr<IntfImpl> &intfImpl)
+    : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+      mIntf(intfImpl),
+      mFlacStreamEncoder(nullptr),
+      mInputBufferPcm32(nullptr) {
+}
+
+C2SoftFlacEnc::~C2SoftFlacEnc() {
+    onRelease();
+}
+
+c2_status_t C2SoftFlacEnc::onInit() {
+    mFlacStreamEncoder = FLAC__stream_encoder_new();
+    if (!mFlacStreamEncoder) return C2_CORRUPTED;
+
+    mInputBufferPcm32 = (FLAC__int32*) malloc(
+            kInBlockSize * kMaxNumChannels * sizeof(FLAC__int32));
+    if (!mInputBufferPcm32) return C2_NO_MEMORY;
+
+    mSignalledError = false;
+    mSignalledOutputEos = false;
+    mIsFirstFrame = true;
+    mAnchorTimeStamp = 0ull;
+    mProcessedSamples = 0u;
+    mEncoderWriteData = false;
+    mEncoderReturnedNbBytes = 0;
+    mHeaderOffset = 0;
+    mWroteHeader = false;
+
+    status_t err = configureEncoder();
+    return err == OK ? C2_OK : C2_CORRUPTED;
+}
+
+void C2SoftFlacEnc::onRelease() {
+    if (mFlacStreamEncoder) {
+        FLAC__stream_encoder_delete(mFlacStreamEncoder);
+        mFlacStreamEncoder = nullptr;
+    }
+
+    if (mInputBufferPcm32) {
+        free(mInputBufferPcm32);
+        mInputBufferPcm32 = nullptr;
+    }
+}
+
+void C2SoftFlacEnc::onReset() {
+    (void) onStop();
+}
+
+c2_status_t C2SoftFlacEnc::onStop() {
+    mSignalledError = false;
+    mSignalledOutputEos = false;
+    mIsFirstFrame = true;
+    mAnchorTimeStamp = 0ull;
+    mProcessedSamples = 0u;
+    mEncoderWriteData = false;
+    mEncoderReturnedNbBytes = 0;
+    mHeaderOffset = 0;
+    mWroteHeader = false;
+
+    c2_status_t status = drain(DRAIN_COMPONENT_NO_EOS, nullptr);
+    if (C2_OK != status) return status;
+
+    status_t err = configureEncoder();
+    if (err != OK) mSignalledError = true;
+    return C2_OK;
+}
+
+c2_status_t C2SoftFlacEnc::onFlush_sm() {
+    return onStop();
+}
+
+static void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
+    work->worklets.front()->output.flags = work->input.flags;
+    work->worklets.front()->output.buffers.clear();
+    work->worklets.front()->output.ordinal = work->input.ordinal;
+}
+
+void C2SoftFlacEnc::process(
+        const std::unique_ptr<C2Work> &work,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    // Initialize output work
+    work->result = C2_OK;
+    work->workletsProcessed = 1u;
+    work->worklets.front()->output.flags = work->input.flags;
+
+    if (mSignalledError || mSignalledOutputEos) {
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+
+    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
+    C2ReadView rView = mDummyReadView;
+    size_t inOffset = 0u;
+    size_t inSize = 0u;
+    if (!work->input.buffers.empty()) {
+        rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
+        inSize = rView.capacity();
+        if (inSize && rView.error()) {
+            ALOGE("read view map failed %d", rView.error());
+            work->result = C2_CORRUPTED;
+            return;
+        }
+    }
+
+    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
+              inSize, (int)work->input.ordinal.timestamp.peeku(),
+              (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
+    if (mIsFirstFrame && inSize) {
+        mAnchorTimeStamp = work->input.ordinal.timestamp.peekull();
+        mIsFirstFrame = false;
+    }
+
+    if (!mWroteHeader) {
+        std::unique_ptr<C2StreamInitDataInfo::output> csd =
+            C2StreamInitDataInfo::output::AllocUnique(mHeaderOffset, 0u);
+        if (!csd) {
+            ALOGE("CSD allocation failed");
+            mSignalledError = true;
+            work->result = C2_NO_MEMORY;
+            return;
+        }
+        memcpy(csd->m.value, mHeader, mHeaderOffset);
+        ALOGV("put csd, %d bytes", mHeaderOffset);
+
+        work->worklets.front()->output.configUpdate.push_back(std::move(csd));
+        mWroteHeader = true;
+    }
+
+    const uint32_t sampleRate = mIntf->getSampleRate();
+    const uint32_t channelCount = mIntf->getChannelCount();
+    const bool inputFloat = mIntf->getPcmEncodingInfo() == C2Config::PCM_FLOAT;
+    const unsigned sampleSize = inputFloat ? sizeof(float) : sizeof(int16_t);
+    const unsigned frameSize = channelCount * sampleSize;
+    const uint64_t outTimeStamp = mProcessedSamples * 1000000ll / sampleRate;
+
+    size_t outCapacity = inSize;
+    outCapacity += mBlockSize * frameSize;
+
+    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+    c2_status_t err = pool->fetchLinearBlock(outCapacity, usage, &mOutputBlock);
+    if (err != C2_OK) {
+        ALOGE("fetchLinearBlock for Output failed with status %d", err);
+        work->result = C2_NO_MEMORY;
+        return;
+    }
+    C2WriteView wView = mOutputBlock->map().get();
+    if (wView.error()) {
+        ALOGE("write view map failed %d", wView.error());
+        work->result = C2_CORRUPTED;
+        return;
+    }
+
+    mEncoderWriteData = true;
+    mEncoderReturnedNbBytes = 0;
+    size_t inPos = 0;
+    while (inPos < inSize) {
+        const uint8_t *inPtr = rView.data() + inOffset;
+        const size_t processSize = MIN(kInBlockSize * frameSize, (inSize - inPos));
+        const unsigned nbInputFrames = processSize / frameSize;
+        const unsigned nbInputSamples = processSize / sampleSize;
+
+        ALOGV("about to encode %zu bytes", processSize);
+        if (inputFloat) {
+            const float * const pcmFloat = reinterpret_cast<const float *>(inPtr + inPos);
+            memcpy_to_q8_23_from_float_with_clamp(mInputBufferPcm32, pcmFloat, nbInputSamples);
+        } else {
+            const int16_t * const pcm16 = reinterpret_cast<const int16_t *>(inPtr + inPos);
+            for (unsigned i = 0; i < nbInputSamples; i++) {
+                mInputBufferPcm32[i] = (FLAC__int32) pcm16[i];
+            }
+        }
+
+        FLAC__bool ok = FLAC__stream_encoder_process_interleaved(
+                mFlacStreamEncoder, mInputBufferPcm32, nbInputFrames);
+        if (!ok) {
+            ALOGE("error encountered during encoding");
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            mOutputBlock.reset();
+            return;
+        }
+        inPos += processSize;
+    }
+    if (eos && (C2_OK != drain(DRAIN_COMPONENT_WITH_EOS, pool))) {
+        ALOGE("error encountered during encoding");
+        mSignalledError = true;
+        work->result = C2_CORRUPTED;
+        mOutputBlock.reset();
+        return;
+    }
+    fillEmptyWork(work);
+    if (mEncoderReturnedNbBytes != 0) {
+        std::shared_ptr<C2Buffer> buffer = createLinearBuffer(std::move(mOutputBlock), 0, mEncoderReturnedNbBytes);
+        work->worklets.front()->output.buffers.push_back(buffer);
+        work->worklets.front()->output.ordinal.timestamp = mAnchorTimeStamp + outTimeStamp;
+    } else {
+        ALOGV("encoder process_interleaved returned without data to write");
+    }
+    mOutputBlock = nullptr;
+    if (eos) {
+        mSignalledOutputEos = true;
+        ALOGV("signalled EOS");
+    }
+    mEncoderWriteData = false;
+    mEncoderReturnedNbBytes = 0;
+}
+
+FLAC__StreamEncoderWriteStatus C2SoftFlacEnc::onEncodedFlacAvailable(
+        const FLAC__byte buffer[], size_t bytes, unsigned samples,
+        unsigned current_frame) {
+    (void) current_frame;
+    ALOGV("%s (bytes=%zu, samples=%u, curr_frame=%u)", __func__, bytes, samples,
+          current_frame);
+
+    if (samples == 0) {
+        ALOGI("saving %zu bytes of header", bytes);
+        memcpy(mHeader + mHeaderOffset, buffer, bytes);
+        mHeaderOffset += bytes;// will contain header size when finished receiving header
+        return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
+    }
+
+    if ((samples == 0) || !mEncoderWriteData) {
+        // called by the encoder because there's header data to save, but it's not the role
+        // of this component (unless WRITE_FLAC_HEADER_IN_FIRST_BUFFER is defined)
+        ALOGV("ignoring %zu bytes of header data (samples=%d)", bytes, samples);
+        return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
+    }
+
+    // write encoded data
+    C2WriteView wView = mOutputBlock->map().get();
+    uint8_t* outData = wView.data();
+    ALOGV("writing %zu bytes of encoded data on output", bytes);
+    // increment mProcessedSamples to maintain audio synchronization during
+    // play back
+    mProcessedSamples += samples;
+    if (bytes + mEncoderReturnedNbBytes > mOutputBlock->capacity()) {
+        ALOGE("not enough space left to write encoded data, dropping %zu bytes", bytes);
+        // a fatal error would stop the encoding
+        return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
+    }
+    memcpy(outData + mEncoderReturnedNbBytes, buffer, bytes);
+    mEncoderReturnedNbBytes += bytes;
+    return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
+}
+
+
+status_t C2SoftFlacEnc::configureEncoder() {
+    ALOGV("%s numChannel=%d, sampleRate=%d", __func__, mIntf->getChannelCount(), mIntf->getSampleRate());
+
+    if (mSignalledError || !mFlacStreamEncoder) {
+        ALOGE("can't configure encoder: no encoder or invalid state");
+        return UNKNOWN_ERROR;
+    }
+
+    const bool inputFloat = mIntf->getPcmEncodingInfo() == C2Config::PCM_FLOAT;
+    const int bitsPerSample = inputFloat ? 24 : 16;
+    FLAC__bool ok = true;
+    ok = ok && FLAC__stream_encoder_set_channels(mFlacStreamEncoder, mIntf->getChannelCount());
+    ok = ok && FLAC__stream_encoder_set_sample_rate(mFlacStreamEncoder, mIntf->getSampleRate());
+    ok = ok && FLAC__stream_encoder_set_bits_per_sample(mFlacStreamEncoder, bitsPerSample);
+    ok = ok && FLAC__stream_encoder_set_compression_level(mFlacStreamEncoder,
+                    mIntf->getComplexity());
+    ok = ok && FLAC__stream_encoder_set_verify(mFlacStreamEncoder, false);
+    if (!ok) {
+        ALOGE("unknown error when configuring encoder");
+        return UNKNOWN_ERROR;
+    }
+
+    ok &= FLAC__STREAM_ENCODER_INIT_STATUS_OK ==
+            FLAC__stream_encoder_init_stream(mFlacStreamEncoder,
+                    flacEncoderWriteCallback    /*write_callback*/,
+                    nullptr /*seek_callback*/,
+                    nullptr /*tell_callback*/,
+                    nullptr /*metadata_callback*/,
+                    (void *) this /*client_data*/);
+
+    if (!ok) {
+        ALOGE("unknown error when configuring encoder");
+        return UNKNOWN_ERROR;
+    }
+
+    mBlockSize = FLAC__stream_encoder_get_blocksize(mFlacStreamEncoder);
+
+    ALOGV("encoder successfully configured");
+    return OK;
+}
+
+FLAC__StreamEncoderWriteStatus C2SoftFlacEnc::flacEncoderWriteCallback(
+            const FLAC__StreamEncoder *,
+            const FLAC__byte buffer[],
+            size_t bytes,
+            unsigned samples,
+            unsigned current_frame,
+            void *client_data) {
+    return ((C2SoftFlacEnc*) client_data)->onEncodedFlacAvailable(
+            buffer, bytes, samples, current_frame);
+}
+
+c2_status_t C2SoftFlacEnc::drain(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    (void) pool;
+    switch (drainMode) {
+        case NO_DRAIN:
+            ALOGW("drain with NO_DRAIN: no-op");
+            return C2_OK;
+        case DRAIN_CHAIN:
+            ALOGW("DRAIN_CHAIN not supported");
+            return C2_OMITTED;
+        case DRAIN_COMPONENT_WITH_EOS:
+            // TODO: This flag is not being sent back to the client
+            // because there are no items in PendingWork queue as all the
+            // inputs are being sent back with emptywork or valid encoded data
+            // mSignalledOutputEos = true;
+        case DRAIN_COMPONENT_NO_EOS:
+            break;
+        default:
+            return C2_BAD_VALUE;
+    }
+    FLAC__bool ok = FLAC__stream_encoder_finish(mFlacStreamEncoder);
+    if (!ok) return C2_CORRUPTED;
+    mIsFirstFrame = true;
+    mAnchorTimeStamp = 0ull;
+    mProcessedSamples = 0u;
+
+    return C2_OK;
+}
+
+class C2SoftFlacEncFactory : public C2ComponentFactory {
+public:
+    C2SoftFlacEncFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+            GetCodec2PlatformComponentStore()->getParamReflector())) {
+    }
+
+    virtual c2_status_t createComponent(
+            c2_node_id_t id,
+            std::shared_ptr<C2Component>* const component,
+            std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+                new C2SoftFlacEnc(COMPONENT_NAME,
+                                  id,
+                                  std::make_shared<C2SoftFlacEnc::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+            c2_node_id_t id,
+            std::shared_ptr<C2ComponentInterface>* const interface,
+            std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+                new SimpleInterface<C2SoftFlacEnc::IntfImpl>(
+                        COMPONENT_NAME, id, std::make_shared<C2SoftFlacEnc::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftFlacEncFactory() override = default;
+private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftFlacEncFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/flac/C2SoftFlacEnc.h b/media/codec2/components/flac/C2SoftFlacEnc.h
new file mode 100644
index 0000000..b3f01d5
--- /dev/null
+++ b/media/codec2/components/flac/C2SoftFlacEnc.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_FLAC_ENC_H_
+#define ANDROID_C2_SOFT_FLAC_ENC_H_
+
+#include <SimpleC2Component.h>
+
+#include "FLAC/stream_encoder.h"
+
+#define FLAC_COMPRESSION_LEVEL_MIN     0
+#define FLAC_COMPRESSION_LEVEL_DEFAULT 5
+#define FLAC_COMPRESSION_LEVEL_MAX     8
+
+#define FLAC_HEADER_SIZE               128
+
+#define MIN(a, b)                      (((a) < (b)) ? (a) : (b))
+
+namespace android {
+
+class C2SoftFlacEnc : public SimpleC2Component {
+public:
+    class IntfImpl;
+
+    C2SoftFlacEnc(const char *name, c2_node_id_t id, const std::shared_ptr<IntfImpl> &intfImpl);
+    virtual ~C2SoftFlacEnc();
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+    c2_status_t drain(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+
+private:
+    status_t configureEncoder();
+    static FLAC__StreamEncoderWriteStatus flacEncoderWriteCallback(
+            const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[],
+            size_t bytes, unsigned samples, unsigned current_frame,
+            void *client_data);
+    FLAC__StreamEncoderWriteStatus onEncodedFlacAvailable(
+            const FLAC__byte buffer[], size_t bytes, unsigned samples,
+            unsigned current_frame);
+
+    std::shared_ptr<IntfImpl> mIntf;
+    const unsigned int kInBlockSize = 1152;
+    const unsigned int kMaxNumChannels = 2;
+    FLAC__StreamEncoder* mFlacStreamEncoder;
+    FLAC__int32* mInputBufferPcm32;
+    std::shared_ptr<C2LinearBlock> mOutputBlock;
+    bool mSignalledError;
+    bool mSignalledOutputEos;
+    uint32_t mBlockSize;
+    bool mIsFirstFrame;
+    uint64_t mAnchorTimeStamp;
+    uint64_t mProcessedSamples;
+    // should the data received by the callback be written to the output port
+    bool mEncoderWriteData;
+    size_t mEncoderReturnedNbBytes;
+    unsigned mHeaderOffset;
+    bool mWroteHeader;
+    char mHeader[FLAC_HEADER_SIZE];
+
+    C2_DO_NOT_COPY(C2SoftFlacEnc);
+};
+
+}  // namespace android
+
+#endif  // ANDROID_C2_SOFT_FLAC_ENC_H_
diff --git a/media/common_time/MODULE_LICENSE_APACHE2 b/media/codec2/components/flac/MODULE_LICENSE_APACHE2
similarity index 100%
copy from media/common_time/MODULE_LICENSE_APACHE2
copy to media/codec2/components/flac/MODULE_LICENSE_APACHE2
diff --git a/media/common_time/NOTICE b/media/codec2/components/flac/NOTICE
similarity index 100%
copy from media/common_time/NOTICE
copy to media/codec2/components/flac/NOTICE
diff --git a/media/codec2/components/g711/Android.bp b/media/codec2/components/g711/Android.bp
new file mode 100644
index 0000000..3ede68c
--- /dev/null
+++ b/media/codec2/components/g711/Android.bp
@@ -0,0 +1,23 @@
+cc_library_shared {
+    name: "libcodec2_soft_g711alawdec",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["C2SoftG711Dec.cpp"],
+
+    cflags: [
+        "-DALAW",
+    ],
+}
+
+cc_library_shared {
+    name: "libcodec2_soft_g711mlawdec",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["C2SoftG711Dec.cpp"],
+}
diff --git a/media/codec2/components/g711/C2SoftG711Dec.cpp b/media/codec2/components/g711/C2SoftG711Dec.cpp
new file mode 100644
index 0000000..43b843a
--- /dev/null
+++ b/media/codec2/components/g711/C2SoftG711Dec.cpp
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftG711Dec"
+#include <log/log.h>
+
+#include <media/stagefright/foundation/MediaDefs.h>
+
+#include <C2PlatformSupport.h>
+#include <SimpleC2Interface.h>
+
+#include "C2SoftG711Dec.h"
+
+namespace android {
+
+namespace {
+
+#ifdef ALAW
+constexpr char COMPONENT_NAME[] = "c2.android.g711.alaw.decoder";
+#else
+constexpr char COMPONENT_NAME[] = "c2.android.g711.mlaw.decoder";
+#endif
+
+}  // namespace
+
+class C2SoftG711Dec::IntfImpl : public SimpleInterface<void>::BaseParams {
+public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+        : SimpleInterface<void>::BaseParams(
+                helper,
+                COMPONENT_NAME,
+                C2Component::KIND_DECODER,
+                C2Component::DOMAIN_AUDIO,
+#ifdef ALAW
+                MEDIA_MIMETYPE_AUDIO_G711_ALAW
+#else
+                MEDIA_MIMETYPE_AUDIO_G711_MLAW
+#endif
+                ) {
+        noPrivateBuffers();
+        noInputReferences();
+        noOutputReferences();
+        noInputLatency();
+        noTimeStretch();
+        setDerivedInstance(this);
+
+        addParameter(
+                DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                .withConstValue(new C2ComponentAttributesSetting(
+                    C2Component::ATTRIB_IS_TEMPORAL))
+                .build());
+
+        addParameter(
+                DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE)
+                .withDefault(new C2StreamSampleRateInfo::output(0u, 8000))
+                .withFields({C2F(mSampleRate, value).inRange(8000, 48000)})
+                .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
+                .build());
+
+        addParameter(
+                DefineParam(mChannelCount, C2_PARAMKEY_CHANNEL_COUNT)
+                .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
+                .withFields({C2F(mChannelCount, value).equalTo(1)})
+                .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
+                .withDefault(new C2StreamBitrateInfo::input(0u, 64000))
+                .withFields({C2F(mBitrate, value).equalTo(64000)})
+                .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
+                .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 8192))
+                .build());
+    }
+
+private:
+    std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
+    std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
+    std::shared_ptr<C2StreamBitrateInfo::input> mBitrate;
+    std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
+};
+
+C2SoftG711Dec::C2SoftG711Dec(
+        const char *name,
+        c2_node_id_t id,
+        const std::shared_ptr<IntfImpl> &intfImpl)
+    : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+      mIntf(intfImpl) {
+}
+
+C2SoftG711Dec::~C2SoftG711Dec() {
+    onRelease();
+}
+
+c2_status_t C2SoftG711Dec::onInit() {
+    mSignalledOutputEos = false;
+    return C2_OK;
+}
+
+c2_status_t C2SoftG711Dec::onStop() {
+    mSignalledOutputEos = false;
+    return C2_OK;
+}
+
+void C2SoftG711Dec::onReset() {
+    (void)onStop();
+}
+
+void C2SoftG711Dec::onRelease() {
+}
+
+c2_status_t C2SoftG711Dec::onFlush_sm() {
+    return onStop();
+}
+
+void C2SoftG711Dec::process(
+        const std::unique_ptr<C2Work> &work,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    // Initialize output work
+    work->result = C2_OK;
+    work->workletsProcessed = 1u;
+    work->worklets.front()->output.flags = work->input.flags;
+
+    if (mSignalledOutputEos) {
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+
+    C2ReadView rView = mDummyReadView;
+    size_t inOffset = 0u;
+    size_t inSize = 0u;
+    if (!work->input.buffers.empty()) {
+        rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
+        inSize = rView.capacity();
+        if (inSize && rView.error()) {
+            ALOGE("read view map failed %d", rView.error());
+            work->result = C2_CORRUPTED;
+            return;
+        }
+    }
+    bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
+    int outSize = inSize * sizeof(int16_t);
+
+    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
+          (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
+
+    if (inSize == 0) {
+        work->worklets.front()->output.flags = work->input.flags;
+        work->worklets.front()->output.buffers.clear();
+        work->worklets.front()->output.ordinal = work->input.ordinal;
+        if (eos) {
+            mSignalledOutputEos = true;
+            ALOGV("signalled EOS");
+        }
+        return;
+    }
+
+    uint8_t *inputptr = const_cast<uint8_t *>(rView.data() + inOffset);
+
+    std::shared_ptr<C2LinearBlock> block;
+    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+    c2_status_t err = pool->fetchLinearBlock(outSize, usage, &block);
+    if (err != C2_OK) {
+        ALOGE("fetchLinearBlock for Output failed with status %d", err);
+        work->result = C2_NO_MEMORY;
+        return;
+    }
+    C2WriteView wView = block->map().get();
+    if (wView.error()) {
+        ALOGE("write view map failed %d", wView.error());
+        work->result = C2_CORRUPTED;
+        return;
+    }
+    int16_t *outputptr = reinterpret_cast<int16_t *>(wView.data());
+
+#ifdef ALAW
+    DecodeALaw(outputptr, inputptr, inSize);
+#else
+    DecodeMLaw(outputptr, inputptr, inSize);
+#endif
+
+    work->worklets.front()->output.flags = work->input.flags;
+    work->worklets.front()->output.buffers.clear();
+    work->worklets.front()->output.buffers.push_back(createLinearBuffer(block));
+    work->worklets.front()->output.ordinal = work->input.ordinal;
+
+    if (eos) {
+        mSignalledOutputEos = true;
+        ALOGV("signalled EOS");
+    }
+}
+
+c2_status_t C2SoftG711Dec::drain(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    (void) pool;
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+
+    return C2_OK;
+}
+
+#ifdef ALAW
+void C2SoftG711Dec::DecodeALaw(
+        int16_t *out, const uint8_t *in, size_t inSize) {
+    while (inSize > 0) {
+        inSize--;
+        int32_t x = *in++;
+
+        int32_t ix = x ^ 0x55;
+        ix &= 0x7f;
+
+        int32_t iexp = ix >> 4;
+        int32_t mant = ix & 0x0f;
+
+        if (iexp > 0) {
+            mant += 16;
+        }
+
+        mant = (mant << 4) + 8;
+
+        if (iexp > 1) {
+            mant = mant << (iexp - 1);
+        }
+
+        *out++ = (x > 127) ? mant : -mant;
+    }
+}
+#else
+void C2SoftG711Dec::DecodeMLaw(
+        int16_t *out, const uint8_t *in, size_t inSize) {
+    while (inSize > 0) {
+        inSize--;
+        int32_t x = *in++;
+
+        int32_t mantissa = ~x;
+        int32_t exponent = (mantissa >> 4) & 7;
+        int32_t segment = exponent + 1;
+        mantissa &= 0x0f;
+
+        int32_t step = 4 << segment;
+
+        int32_t abs = (0x80l << exponent) + step * mantissa + step / 2 - 4 * 33;
+
+        *out++ = (x < 0x80) ? -abs : abs;
+    }
+}
+#endif
+
+class C2SoftG711DecFactory : public C2ComponentFactory {
+public:
+    C2SoftG711DecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+            GetCodec2PlatformComponentStore()->getParamReflector())) {
+    }
+
+    virtual c2_status_t createComponent(
+            c2_node_id_t id,
+            std::shared_ptr<C2Component>* const component,
+            std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+                new C2SoftG711Dec(COMPONENT_NAME, id,
+                               std::make_shared<C2SoftG711Dec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+            c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
+            std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+                new SimpleInterface<C2SoftG711Dec::IntfImpl>(
+                        COMPONENT_NAME, id, std::make_shared<C2SoftG711Dec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftG711DecFactory() override = default;
+
+private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftG711DecFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/g711/C2SoftG711Dec.h b/media/codec2/components/g711/C2SoftG711Dec.h
new file mode 100644
index 0000000..23e8ffc
--- /dev/null
+++ b/media/codec2/components/g711/C2SoftG711Dec.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_G711_DEC_H_
+#define ANDROID_C2_SOFT_G711_DEC_H_
+
+#include <SimpleC2Component.h>
+
+
+namespace android {
+
+struct C2SoftG711Dec : public SimpleC2Component {
+    class IntfImpl;
+
+    C2SoftG711Dec(const char *name, c2_node_id_t id,
+               const std::shared_ptr<IntfImpl> &intfImpl);
+    virtual ~C2SoftG711Dec();
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+    c2_status_t drain(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+private:
+    std::shared_ptr<IntfImpl> mIntf;
+    bool mSignalledOutputEos;
+
+#ifdef ALAW
+    void DecodeALaw(int16_t *out, const uint8_t *in, size_t inSize);
+#else
+    void DecodeMLaw(int16_t *out, const uint8_t *in, size_t inSize);
+#endif
+
+    C2_DO_NOT_COPY(C2SoftG711Dec);
+};
+
+}  // namespace android
+
+#endif  // ANDROID_C2_SOFT_G711_DEC_H_
diff --git a/media/common_time/MODULE_LICENSE_APACHE2 b/media/codec2/components/g711/MODULE_LICENSE_APACHE2
similarity index 100%
copy from media/common_time/MODULE_LICENSE_APACHE2
copy to media/codec2/components/g711/MODULE_LICENSE_APACHE2
diff --git a/media/common_time/NOTICE b/media/codec2/components/g711/NOTICE
similarity index 100%
copy from media/common_time/NOTICE
copy to media/codec2/components/g711/NOTICE
diff --git a/media/codec2/components/gsm/Android.bp b/media/codec2/components/gsm/Android.bp
new file mode 100644
index 0000000..9330c01
--- /dev/null
+++ b/media/codec2/components/gsm/Android.bp
@@ -0,0 +1,11 @@
+cc_library_shared {
+    name: "libcodec2_soft_gsmdec",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["C2SoftGsmDec.cpp"],
+
+    static_libs: ["libgsm"],
+}
diff --git a/media/codec2/components/gsm/C2SoftGsmDec.cpp b/media/codec2/components/gsm/C2SoftGsmDec.cpp
new file mode 100644
index 0000000..287cfc6
--- /dev/null
+++ b/media/codec2/components/gsm/C2SoftGsmDec.cpp
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftGsmDec"
+#include <log/log.h>
+
+#include <media/stagefright/foundation/MediaDefs.h>
+
+#include <C2PlatformSupport.h>
+#include <SimpleC2Interface.h>
+
+#include "C2SoftGsmDec.h"
+
+namespace android {
+
+namespace {
+
+constexpr char COMPONENT_NAME[] = "c2.android.gsm.decoder";
+
+}  // namespace
+
+class C2SoftGsmDec::IntfImpl : public SimpleInterface<void>::BaseParams {
+public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+        : SimpleInterface<void>::BaseParams(
+                helper,
+                COMPONENT_NAME,
+                C2Component::KIND_DECODER,
+                C2Component::DOMAIN_AUDIO,
+                MEDIA_MIMETYPE_AUDIO_MSGSM) {
+        noPrivateBuffers();
+        noInputReferences();
+        noOutputReferences();
+        noInputLatency();
+        noTimeStretch();
+        setDerivedInstance(this);
+
+        addParameter(
+                DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                .withConstValue(new C2ComponentAttributesSetting(
+                    C2Component::ATTRIB_IS_TEMPORAL))
+                .build());
+
+        addParameter(
+                DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE)
+                .withDefault(new C2StreamSampleRateInfo::output(0u, 8000))
+                .withFields({C2F(mSampleRate, value).equalTo(8000)})
+                .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
+                .build());
+
+        addParameter(
+                DefineParam(mChannelCount, C2_PARAMKEY_CHANNEL_COUNT)
+                .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
+                .withFields({C2F(mChannelCount, value).equalTo(1)})
+                .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
+                .withDefault(new C2StreamBitrateInfo::input(0u, 13200))
+                .withFields({C2F(mBitrate, value).equalTo(13200)})
+                .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
+                .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 1024 / MSGSM_IN_FRM_SZ * MSGSM_IN_FRM_SZ))
+                .build());
+    }
+
+   private:
+    std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
+    std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
+    std::shared_ptr<C2StreamBitrateInfo::input> mBitrate;
+    std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
+};
+
+C2SoftGsmDec::C2SoftGsmDec(const char *name, c2_node_id_t id,
+                     const std::shared_ptr<IntfImpl>& intfImpl)
+    : SimpleC2Component(
+        std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+      mIntf(intfImpl),
+      mGsm(nullptr) {
+}
+
+C2SoftGsmDec::~C2SoftGsmDec() {
+    onRelease();
+}
+
+c2_status_t C2SoftGsmDec::onInit() {
+    if (!mGsm) mGsm = gsm_create();
+    if (!mGsm) return C2_NO_MEMORY;
+    int msopt = 1;
+    (void)gsm_option(mGsm, GSM_OPT_WAV49, &msopt);
+    mSignalledError = false;
+    mSignalledEos = false;
+    return C2_OK;
+}
+
+c2_status_t C2SoftGsmDec::onStop() {
+    if (mGsm) {
+        gsm_destroy(mGsm);
+        mGsm = nullptr;
+    }
+    if (!mGsm) mGsm = gsm_create();
+    if (!mGsm) return C2_NO_MEMORY;
+    int msopt = 1;
+    (void)gsm_option(mGsm, GSM_OPT_WAV49, &msopt);
+    mSignalledError = false;
+    mSignalledEos = false;
+    return C2_OK;
+}
+
+void C2SoftGsmDec::onReset() {
+    (void)onStop();
+}
+
+void C2SoftGsmDec::onRelease() {
+    if (mGsm) {
+        gsm_destroy(mGsm);
+        mGsm = nullptr;
+    }
+}
+
+c2_status_t C2SoftGsmDec::onFlush_sm() {
+    return onStop();
+}
+
+static size_t decodeGSM(gsm handle, int16_t *out, size_t outCapacity,
+                        uint8_t *in, size_t inSize) {
+    size_t outSize = 0;
+
+    if (inSize % MSGSM_IN_FRM_SZ == 0
+            && (inSize / MSGSM_IN_FRM_SZ * MSGSM_OUT_FRM_SZ * sizeof(*out)
+                    <= outCapacity)) {
+        while (inSize > 0) {
+            gsm_decode(handle, in, out);
+            in += FRGSM_IN_FRM_SZ;
+            inSize -= FRGSM_IN_FRM_SZ;
+            out += FRGSM_OUT_FRM_SZ;
+            outSize += FRGSM_OUT_FRM_SZ;
+
+            gsm_decode(handle, in, out);
+            in += FRGSM_IN_FRM_SZ_MINUS_1;
+            inSize -= FRGSM_IN_FRM_SZ_MINUS_1;
+            out += FRGSM_OUT_FRM_SZ;
+            outSize += FRGSM_OUT_FRM_SZ;
+        }
+    }
+
+    return outSize * sizeof(int16_t);
+}
+
+void C2SoftGsmDec::process(
+        const std::unique_ptr<C2Work> &work,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    // Initialize output work
+    work->result = C2_OK;
+    work->workletsProcessed = 1u;
+    work->worklets.front()->output.flags = work->input.flags;
+
+    if (mSignalledError || mSignalledEos) {
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+
+    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
+    C2ReadView rView = mDummyReadView;
+    size_t inOffset = 0u;
+    size_t inSize = 0u;
+    if (!work->input.buffers.empty()) {
+        rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
+        inSize = rView.capacity();
+        if (inSize && rView.error()) {
+            ALOGE("read view map failed %d", rView.error());
+            work->result = rView.error();
+            return;
+        }
+    }
+
+    if (inSize == 0) {
+        work->worklets.front()->output.flags = work->input.flags;
+        work->worklets.front()->output.buffers.clear();
+        work->worklets.front()->output.ordinal = work->input.ordinal;
+        if (eos) {
+            mSignalledEos = true;
+            ALOGV("signalled EOS");
+        }
+        return;
+    }
+    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
+          (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
+
+    size_t outCapacity = (inSize / MSGSM_IN_FRM_SZ ) * MSGSM_OUT_FRM_SZ * sizeof(int16_t);
+    std::shared_ptr<C2LinearBlock> block;
+    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+    c2_status_t err = pool->fetchLinearBlock(outCapacity, usage, &block);
+    if (err != C2_OK) {
+        ALOGE("fetchLinearBlock for Output failed with status %d", err);
+        work->result = C2_NO_MEMORY;
+        return;
+    }
+    C2WriteView wView = block->map().get();
+    if (wView.error()) {
+        ALOGE("write view map failed %d", wView.error());
+        work->result = wView.error();
+        return;
+    }
+
+    int16_t *output = reinterpret_cast<int16_t *>(wView.data());
+    uint8_t *input = const_cast<uint8_t *>(rView.data() + inOffset);
+    size_t outSize = decodeGSM(mGsm, output, outCapacity, input, inSize);
+    if (!outSize) {
+        ALOGE("encountered improper insize or outsize");
+        mSignalledError = true;
+        work->result = C2_CORRUPTED;
+        return;
+    }
+    ALOGV("out buffer attr. size %zu", outSize);
+    work->worklets.front()->output.flags = work->input.flags;
+    work->worklets.front()->output.buffers.clear();
+    work->worklets.front()->output.buffers.push_back(createLinearBuffer(block, 0, outSize));
+    work->worklets.front()->output.ordinal = work->input.ordinal;
+    if (eos) {
+        mSignalledEos = true;
+        ALOGV("signalled EOS");
+    }
+}
+
+c2_status_t C2SoftGsmDec::drain(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    (void) pool;
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+
+    return C2_OK;
+}
+
+class C2SoftGSMDecFactory : public C2ComponentFactory {
+public:
+    C2SoftGSMDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+            GetCodec2PlatformComponentStore()->getParamReflector())) {
+    }
+
+    virtual c2_status_t createComponent(
+            c2_node_id_t id,
+            std::shared_ptr<C2Component>* const component,
+            std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+                new C2SoftGsmDec(COMPONENT_NAME,
+                              id,
+                              std::make_shared<C2SoftGsmDec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+            c2_node_id_t id,
+            std::shared_ptr<C2ComponentInterface>* const interface,
+            std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+                new SimpleInterface<C2SoftGsmDec::IntfImpl>(
+                        COMPONENT_NAME, id, std::make_shared<C2SoftGsmDec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftGSMDecFactory() override = default;
+
+private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftGSMDecFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/gsm/C2SoftGsmDec.h b/media/codec2/components/gsm/C2SoftGsmDec.h
new file mode 100644
index 0000000..2b209fe
--- /dev/null
+++ b/media/codec2/components/gsm/C2SoftGsmDec.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_GSM_DEC_H_
+#define ANDROID_C2_SOFT_GSM_DEC_H_
+
+#include <SimpleC2Component.h>
+
+
+extern "C" {
+    #include "gsm.h"
+}
+
+namespace android {
+
+#define FRGSM_IN_FRM_SZ             33
+#define FRGSM_IN_FRM_SZ_MINUS_1     32
+#define FRGSM_OUT_FRM_SZ            160
+#define MSGSM_IN_FRM_SZ             (FRGSM_IN_FRM_SZ + FRGSM_IN_FRM_SZ_MINUS_1)
+#define MSGSM_OUT_FRM_SZ            (FRGSM_OUT_FRM_SZ * 2)
+
+struct C2SoftGsmDec : public SimpleC2Component {
+    class IntfImpl;
+
+    C2SoftGsmDec(const char *name, c2_node_id_t id,
+              const std::shared_ptr<IntfImpl> &intfImpl);
+    virtual ~C2SoftGsmDec();
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+    c2_status_t drain(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+ private:
+    std::shared_ptr<IntfImpl> mIntf;
+    gsm mGsm;
+    bool mSignalledError;
+    bool mSignalledEos;
+
+    C2_DO_NOT_COPY(C2SoftGsmDec);
+};
+
+}  // namespace android
+
+#endif  // ANDROID_C2_SOFT_GSM_DEC_H_
diff --git a/media/common_time/MODULE_LICENSE_APACHE2 b/media/codec2/components/gsm/MODULE_LICENSE_APACHE2
similarity index 100%
copy from media/common_time/MODULE_LICENSE_APACHE2
copy to media/codec2/components/gsm/MODULE_LICENSE_APACHE2
diff --git a/media/common_time/NOTICE b/media/codec2/components/gsm/NOTICE
similarity index 100%
copy from media/common_time/NOTICE
copy to media/codec2/components/gsm/NOTICE
diff --git a/media/codec2/components/hevc/Android.bp b/media/codec2/components/hevc/Android.bp
new file mode 100644
index 0000000..369bd78
--- /dev/null
+++ b/media/codec2/components/hevc/Android.bp
@@ -0,0 +1,25 @@
+cc_library_shared {
+    name: "libcodec2_soft_hevcdec",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_signed-defaults",
+    ],
+
+    srcs: ["C2SoftHevcDec.cpp"],
+
+    static_libs: ["libhevcdec"],
+
+}
+
+cc_library_shared {
+    name: "libcodec2_soft_hevcenc",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_signed-defaults",
+    ],
+
+    srcs: ["C2SoftHevcEnc.cpp"],
+
+    static_libs: ["libhevcenc"],
+
+}
diff --git a/media/codec2/components/hevc/C2SoftHevcDec.cpp b/media/codec2/components/hevc/C2SoftHevcDec.cpp
new file mode 100644
index 0000000..7232572
--- /dev/null
+++ b/media/codec2/components/hevc/C2SoftHevcDec.cpp
@@ -0,0 +1,1028 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftHevcDec"
+#include <log/log.h>
+
+#include <media/stagefright/foundation/MediaDefs.h>
+
+#include <C2Debug.h>
+#include <C2PlatformSupport.h>
+#include <Codec2Mapper.h>
+#include <SimpleC2Interface.h>
+
+#include "C2SoftHevcDec.h"
+#include "ihevcd_cxa.h"
+
+namespace android {
+
+namespace {
+
+constexpr char COMPONENT_NAME[] = "c2.android.hevc.decoder";
+
+}  // namespace
+
+class C2SoftHevcDec::IntfImpl : public SimpleInterface<void>::BaseParams {
+public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+        : SimpleInterface<void>::BaseParams(
+                helper,
+                COMPONENT_NAME,
+                C2Component::KIND_DECODER,
+                C2Component::DOMAIN_VIDEO,
+                MEDIA_MIMETYPE_VIDEO_HEVC) {
+        noPrivateBuffers(); // TODO: account for our buffers here
+        noInputReferences();
+        noOutputReferences();
+        noInputLatency();
+        noTimeStretch();
+
+        // TODO: Proper support for reorder depth.
+        addParameter(
+                DefineParam(mActualOutputDelay, C2_PARAMKEY_OUTPUT_DELAY)
+                .withConstValue(new C2PortActualDelayTuning::output(8u))
+                .build());
+
+        addParameter(
+                DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                .withConstValue(new C2ComponentAttributesSetting(C2Component::ATTRIB_IS_TEMPORAL))
+                .build());
+
+        addParameter(
+                DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
+                .withDefault(new C2StreamPictureSizeInfo::output(0u, 320, 240))
+                .withFields({
+                    C2F(mSize, width).inRange(2, 4096, 2),
+                    C2F(mSize, height).inRange(2, 4096, 2),
+                })
+                .withSetter(SizeSetter)
+                .build());
+
+        addParameter(
+                DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
+                .withDefault(new C2StreamProfileLevelInfo::input(0u,
+                        C2Config::PROFILE_HEVC_MAIN, C2Config::LEVEL_HEVC_MAIN_5_1))
+                .withFields({
+                    C2F(mProfileLevel, profile).oneOf({
+                            C2Config::PROFILE_HEVC_MAIN,
+                            C2Config::PROFILE_HEVC_MAIN_STILL}),
+                    C2F(mProfileLevel, level).oneOf({
+                            C2Config::LEVEL_HEVC_MAIN_1,
+                            C2Config::LEVEL_HEVC_MAIN_2, C2Config::LEVEL_HEVC_MAIN_2_1,
+                            C2Config::LEVEL_HEVC_MAIN_3, C2Config::LEVEL_HEVC_MAIN_3_1,
+                            C2Config::LEVEL_HEVC_MAIN_4, C2Config::LEVEL_HEVC_MAIN_4_1,
+                            C2Config::LEVEL_HEVC_MAIN_5, C2Config::LEVEL_HEVC_MAIN_5_1,
+                            C2Config::LEVEL_HEVC_MAIN_5_2, C2Config::LEVEL_HEVC_HIGH_4,
+                            C2Config::LEVEL_HEVC_HIGH_4_1, C2Config::LEVEL_HEVC_HIGH_5,
+                            C2Config::LEVEL_HEVC_HIGH_5_1, C2Config::LEVEL_HEVC_HIGH_5_2
+                    })
+                })
+                .withSetter(ProfileLevelSetter, mSize)
+                .build());
+
+        addParameter(
+                DefineParam(mMaxSize, C2_PARAMKEY_MAX_PICTURE_SIZE)
+                .withDefault(new C2StreamMaxPictureSizeTuning::output(0u, 320, 240))
+                .withFields({
+                    C2F(mSize, width).inRange(2, 4096, 2),
+                    C2F(mSize, height).inRange(2, 4096, 2),
+                })
+                .withSetter(MaxPictureSizeSetter, mSize)
+                .build());
+
+        addParameter(
+                DefineParam(mMaxInputSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
+                .withDefault(new C2StreamMaxBufferSizeInfo::input(0u, 320 * 240 * 3 / 4))
+                .withFields({
+                    C2F(mMaxInputSize, value).any(),
+                })
+                .calculatedAs(MaxInputSizeSetter, mMaxSize)
+                .build());
+
+        C2ChromaOffsetStruct locations[1] = { C2ChromaOffsetStruct::ITU_YUV_420_0() };
+        std::shared_ptr<C2StreamColorInfo::output> defaultColorInfo =
+            C2StreamColorInfo::output::AllocShared(
+                    1u, 0u, 8u /* bitDepth */, C2Color::YUV_420);
+        memcpy(defaultColorInfo->m.locations, locations, sizeof(locations));
+
+        defaultColorInfo = C2StreamColorInfo::output::AllocShared(
+            {C2ChromaOffsetStruct::ITU_YUV_420_0()}, 0u, 8u /* bitDepth */,
+            C2Color::YUV_420);
+        helper->addStructDescriptors<C2ChromaOffsetStruct>();
+
+        addParameter(
+                DefineParam(mColorInfo, C2_PARAMKEY_CODED_COLOR_INFO)
+                .withConstValue(defaultColorInfo)
+                .build());
+
+        addParameter(
+                DefineParam(mDefaultColorAspects, C2_PARAMKEY_DEFAULT_COLOR_ASPECTS)
+                .withDefault(new C2StreamColorAspectsTuning::output(
+                        0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
+                        C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+                .withFields({
+                    C2F(mDefaultColorAspects, range).inRange(
+                                C2Color::RANGE_UNSPECIFIED,     C2Color::RANGE_OTHER),
+                    C2F(mDefaultColorAspects, primaries).inRange(
+                                C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
+                    C2F(mDefaultColorAspects, transfer).inRange(
+                                C2Color::TRANSFER_UNSPECIFIED,  C2Color::TRANSFER_OTHER),
+                    C2F(mDefaultColorAspects, matrix).inRange(
+                                C2Color::MATRIX_UNSPECIFIED,    C2Color::MATRIX_OTHER)
+                })
+                .withSetter(DefaultColorAspectsSetter)
+                .build());
+
+        addParameter(
+                DefineParam(mCodedColorAspects, C2_PARAMKEY_VUI_COLOR_ASPECTS)
+                .withDefault(new C2StreamColorAspectsInfo::input(
+                        0u, C2Color::RANGE_LIMITED, C2Color::PRIMARIES_UNSPECIFIED,
+                        C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+                .withFields({
+                    C2F(mCodedColorAspects, range).inRange(
+                                C2Color::RANGE_UNSPECIFIED,     C2Color::RANGE_OTHER),
+                    C2F(mCodedColorAspects, primaries).inRange(
+                                C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
+                    C2F(mCodedColorAspects, transfer).inRange(
+                                C2Color::TRANSFER_UNSPECIFIED,  C2Color::TRANSFER_OTHER),
+                    C2F(mCodedColorAspects, matrix).inRange(
+                                C2Color::MATRIX_UNSPECIFIED,    C2Color::MATRIX_OTHER)
+                })
+                .withSetter(CodedColorAspectsSetter)
+                .build());
+
+        addParameter(
+                DefineParam(mColorAspects, C2_PARAMKEY_COLOR_ASPECTS)
+                .withDefault(new C2StreamColorAspectsInfo::output(
+                        0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
+                        C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+                .withFields({
+                    C2F(mColorAspects, range).inRange(
+                                C2Color::RANGE_UNSPECIFIED,     C2Color::RANGE_OTHER),
+                    C2F(mColorAspects, primaries).inRange(
+                                C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
+                    C2F(mColorAspects, transfer).inRange(
+                                C2Color::TRANSFER_UNSPECIFIED,  C2Color::TRANSFER_OTHER),
+                    C2F(mColorAspects, matrix).inRange(
+                                C2Color::MATRIX_UNSPECIFIED,    C2Color::MATRIX_OTHER)
+                })
+                .withSetter(ColorAspectsSetter, mDefaultColorAspects, mCodedColorAspects)
+                .build());
+
+        // TODO: support more formats?
+        addParameter(
+                DefineParam(mPixelFormat, C2_PARAMKEY_PIXEL_FORMAT)
+                .withConstValue(new C2StreamPixelFormatInfo::output(
+                                     0u, HAL_PIXEL_FORMAT_YCBCR_420_888))
+                .build());
+    }
+
+    static C2R SizeSetter(bool mayBlock, const C2P<C2StreamPictureSizeInfo::output> &oldMe,
+                          C2P<C2StreamPictureSizeInfo::output> &me) {
+        (void)mayBlock;
+        C2R res = C2R::Ok();
+        if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
+            res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
+            me.set().width = oldMe.v.width;
+        }
+        if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
+            res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
+            me.set().height = oldMe.v.height;
+        }
+        return res;
+    }
+
+    static C2R MaxPictureSizeSetter(bool mayBlock, C2P<C2StreamMaxPictureSizeTuning::output> &me,
+                                    const C2P<C2StreamPictureSizeInfo::output> &size) {
+        (void)mayBlock;
+        // TODO: get max width/height from the size's field helpers vs. hardcoding
+        me.set().width = c2_min(c2_max(me.v.width, size.v.width), 4096u);
+        me.set().height = c2_min(c2_max(me.v.height, size.v.height), 4096u);
+        return C2R::Ok();
+    }
+
+    static C2R MaxInputSizeSetter(bool mayBlock, C2P<C2StreamMaxBufferSizeInfo::input> &me,
+                                  const C2P<C2StreamMaxPictureSizeTuning::output> &maxSize) {
+        (void)mayBlock;
+        // assume compression ratio of 2
+        me.set().value = (((maxSize.v.width + 63) / 64) * ((maxSize.v.height + 63) / 64) * 3072);
+        return C2R::Ok();
+    }
+
+    static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me,
+                                  const C2P<C2StreamPictureSizeInfo::output> &size) {
+        (void)mayBlock;
+        (void)size;
+        (void)me;  // TODO: validate
+        return C2R::Ok();
+    }
+
+    static C2R DefaultColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsTuning::output> &me) {
+        (void)mayBlock;
+        if (me.v.range > C2Color::RANGE_OTHER) {
+                me.set().range = C2Color::RANGE_OTHER;
+        }
+        if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
+                me.set().primaries = C2Color::PRIMARIES_OTHER;
+        }
+        if (me.v.transfer > C2Color::TRANSFER_OTHER) {
+                me.set().transfer = C2Color::TRANSFER_OTHER;
+        }
+        if (me.v.matrix > C2Color::MATRIX_OTHER) {
+                me.set().matrix = C2Color::MATRIX_OTHER;
+        }
+        return C2R::Ok();
+    }
+
+    static C2R CodedColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::input> &me) {
+        (void)mayBlock;
+        if (me.v.range > C2Color::RANGE_OTHER) {
+                me.set().range = C2Color::RANGE_OTHER;
+        }
+        if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
+                me.set().primaries = C2Color::PRIMARIES_OTHER;
+        }
+        if (me.v.transfer > C2Color::TRANSFER_OTHER) {
+                me.set().transfer = C2Color::TRANSFER_OTHER;
+        }
+        if (me.v.matrix > C2Color::MATRIX_OTHER) {
+                me.set().matrix = C2Color::MATRIX_OTHER;
+        }
+        return C2R::Ok();
+    }
+
+    static C2R ColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::output> &me,
+                                  const C2P<C2StreamColorAspectsTuning::output> &def,
+                                  const C2P<C2StreamColorAspectsInfo::input> &coded) {
+        (void)mayBlock;
+        // take default values for all unspecified fields, and coded values for specified ones
+        me.set().range = coded.v.range == RANGE_UNSPECIFIED ? def.v.range : coded.v.range;
+        me.set().primaries = coded.v.primaries == PRIMARIES_UNSPECIFIED
+                ? def.v.primaries : coded.v.primaries;
+        me.set().transfer = coded.v.transfer == TRANSFER_UNSPECIFIED
+                ? def.v.transfer : coded.v.transfer;
+        me.set().matrix = coded.v.matrix == MATRIX_UNSPECIFIED ? def.v.matrix : coded.v.matrix;
+        return C2R::Ok();
+    }
+
+    std::shared_ptr<C2StreamColorAspectsInfo::output> getColorAspects_l() {
+        return mColorAspects;
+    }
+
+private:
+    std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
+    std::shared_ptr<C2StreamPictureSizeInfo::output> mSize;
+    std::shared_ptr<C2StreamMaxPictureSizeTuning::output> mMaxSize;
+    std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mMaxInputSize;
+    std::shared_ptr<C2StreamColorInfo::output> mColorInfo;
+    std::shared_ptr<C2StreamColorAspectsInfo::input> mCodedColorAspects;
+    std::shared_ptr<C2StreamColorAspectsTuning::output> mDefaultColorAspects;
+    std::shared_ptr<C2StreamColorAspectsInfo::output> mColorAspects;
+    std::shared_ptr<C2StreamPixelFormatInfo::output> mPixelFormat;
+};
+
+static size_t getCpuCoreCount() {
+    long cpuCoreCount = 1;
+#if defined(_SC_NPROCESSORS_ONLN)
+    cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
+#else
+    // _SC_NPROC_ONLN must be defined...
+    cpuCoreCount = sysconf(_SC_NPROC_ONLN);
+#endif
+    CHECK(cpuCoreCount >= 1);
+    ALOGV("Number of CPU cores: %ld", cpuCoreCount);
+    return (size_t)cpuCoreCount;
+}
+
+static void *ivd_aligned_malloc(void *ctxt, WORD32 alignment, WORD32 size) {
+    (void) ctxt;
+    return memalign(alignment, size);
+}
+
+static void ivd_aligned_free(void *ctxt, void *mem) {
+    (void) ctxt;
+    free(mem);
+}
+
+C2SoftHevcDec::C2SoftHevcDec(
+        const char *name,
+        c2_node_id_t id,
+        const std::shared_ptr<IntfImpl> &intfImpl)
+    : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+        mIntf(intfImpl),
+        mDecHandle(nullptr),
+        mOutBufferFlush(nullptr),
+        mIvColorformat(IV_YUV_420P),
+        mWidth(320),
+        mHeight(240),
+        mHeaderDecoded(false),
+        mOutIndex(0u) {
+}
+
+C2SoftHevcDec::~C2SoftHevcDec() {
+    onRelease();
+}
+
+c2_status_t C2SoftHevcDec::onInit() {
+    status_t err = initDecoder();
+    return err == OK ? C2_OK : C2_CORRUPTED;
+}
+
+c2_status_t C2SoftHevcDec::onStop() {
+    if (OK != resetDecoder()) return C2_CORRUPTED;
+    resetPlugin();
+    return C2_OK;
+}
+
+void C2SoftHevcDec::onReset() {
+    (void) onStop();
+}
+
+void C2SoftHevcDec::onRelease() {
+    (void) deleteDecoder();
+    if (mOutBufferFlush) {
+        ivd_aligned_free(nullptr, mOutBufferFlush);
+        mOutBufferFlush = nullptr;
+    }
+    if (mOutBlock) {
+        mOutBlock.reset();
+    }
+}
+
+c2_status_t C2SoftHevcDec::onFlush_sm() {
+    if (OK != setFlushMode()) return C2_CORRUPTED;
+
+    uint32_t displayStride = mStride;
+    uint32_t displayHeight = mHeight;
+    uint32_t bufferSize = displayStride * displayHeight * 3 / 2;
+    mOutBufferFlush = (uint8_t *)ivd_aligned_malloc(nullptr, 128, bufferSize);
+    if (!mOutBufferFlush) {
+        ALOGE("could not allocate tmp output buffer (for flush) of size %u ", bufferSize);
+        return C2_NO_MEMORY;
+    }
+
+    while (true) {
+        ivd_video_decode_ip_t s_decode_ip;
+        ivd_video_decode_op_t s_decode_op;
+
+        setDecodeArgs(&s_decode_ip, &s_decode_op, nullptr, nullptr, 0, 0, 0);
+        (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
+        if (0 == s_decode_op.u4_output_present) {
+            resetPlugin();
+            break;
+        }
+    }
+
+    if (mOutBufferFlush) {
+        ivd_aligned_free(nullptr, mOutBufferFlush);
+        mOutBufferFlush = nullptr;
+    }
+
+    return C2_OK;
+}
+
+status_t C2SoftHevcDec::createDecoder() {
+    ivdext_create_ip_t s_create_ip;
+    ivdext_create_op_t s_create_op;
+
+    s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(ivdext_create_ip_t);
+    s_create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
+    s_create_ip.s_ivd_create_ip_t.u4_share_disp_buf = 0;
+    s_create_ip.s_ivd_create_ip_t.e_output_format = mIvColorformat;
+    s_create_ip.s_ivd_create_ip_t.pf_aligned_alloc = ivd_aligned_malloc;
+    s_create_ip.s_ivd_create_ip_t.pf_aligned_free = ivd_aligned_free;
+    s_create_ip.s_ivd_create_ip_t.pv_mem_ctxt = nullptr;
+    s_create_op.s_ivd_create_op_t.u4_size = sizeof(ivdext_create_op_t);
+    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+                                                     &s_create_ip,
+                                                     &s_create_op);
+    if (status != IV_SUCCESS) {
+        ALOGE("error in %s: 0x%x", __func__,
+              s_create_op.s_ivd_create_op_t.u4_error_code);
+        return UNKNOWN_ERROR;
+    }
+    mDecHandle = (iv_obj_t*)s_create_op.s_ivd_create_op_t.pv_handle;
+    mDecHandle->pv_fxns = (void *)ivdec_api_function;
+    mDecHandle->u4_size = sizeof(iv_obj_t);
+
+    return OK;
+}
+
+status_t C2SoftHevcDec::setNumCores() {
+    ivdext_ctl_set_num_cores_ip_t s_set_num_cores_ip;
+    ivdext_ctl_set_num_cores_op_t s_set_num_cores_op;
+
+    s_set_num_cores_ip.u4_size = sizeof(ivdext_ctl_set_num_cores_ip_t);
+    s_set_num_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+    s_set_num_cores_ip.e_sub_cmd = IVDEXT_CMD_CTL_SET_NUM_CORES;
+    s_set_num_cores_ip.u4_num_cores = mNumCores;
+    s_set_num_cores_op.u4_size = sizeof(ivdext_ctl_set_num_cores_op_t);
+    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+                                                     &s_set_num_cores_ip,
+                                                     &s_set_num_cores_op);
+    if (IV_SUCCESS != status) {
+        ALOGD("error in %s: 0x%x", __func__, s_set_num_cores_op.u4_error_code);
+        return UNKNOWN_ERROR;
+    }
+
+    return OK;
+}
+
+status_t C2SoftHevcDec::setParams(size_t stride, IVD_VIDEO_DECODE_MODE_T dec_mode) {
+    ivd_ctl_set_config_ip_t s_set_dyn_params_ip;
+    ivd_ctl_set_config_op_t s_set_dyn_params_op;
+
+    s_set_dyn_params_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
+    s_set_dyn_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+    s_set_dyn_params_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+    s_set_dyn_params_ip.u4_disp_wd = (UWORD32) stride;
+    s_set_dyn_params_ip.e_frm_skip_mode = IVD_SKIP_NONE;
+    s_set_dyn_params_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+    s_set_dyn_params_ip.e_vid_dec_mode = dec_mode;
+    s_set_dyn_params_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
+    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+                                                     &s_set_dyn_params_ip,
+                                                     &s_set_dyn_params_op);
+    if (status != IV_SUCCESS) {
+        ALOGE("error in %s: 0x%x", __func__, s_set_dyn_params_op.u4_error_code);
+        return UNKNOWN_ERROR;
+    }
+
+    return OK;
+}
+
+status_t C2SoftHevcDec::getVersion() {
+    ivd_ctl_getversioninfo_ip_t s_get_versioninfo_ip;
+    ivd_ctl_getversioninfo_op_t s_get_versioninfo_op;
+    UWORD8 au1_buf[512];
+
+    s_get_versioninfo_ip.u4_size = sizeof(ivd_ctl_getversioninfo_ip_t);
+    s_get_versioninfo_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+    s_get_versioninfo_ip.e_sub_cmd = IVD_CMD_CTL_GETVERSION;
+    s_get_versioninfo_ip.pv_version_buffer = au1_buf;
+    s_get_versioninfo_ip.u4_version_buffer_size = sizeof(au1_buf);
+    s_get_versioninfo_op.u4_size = sizeof(ivd_ctl_getversioninfo_op_t);
+    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+                                                     &s_get_versioninfo_ip,
+                                                     &s_get_versioninfo_op);
+    if (status != IV_SUCCESS) {
+        ALOGD("error in %s: 0x%x", __func__,
+              s_get_versioninfo_op.u4_error_code);
+    } else {
+        ALOGV("ittiam decoder version number: %s",
+              (char *) s_get_versioninfo_ip.pv_version_buffer);
+    }
+
+    return OK;
+}
+
+status_t C2SoftHevcDec::initDecoder() {
+    if (OK != createDecoder()) return UNKNOWN_ERROR;
+    mNumCores = MIN(getCpuCoreCount(), MAX_NUM_CORES);
+    mStride = ALIGN64(mWidth);
+    mSignalledError = false;
+    resetPlugin();
+    (void) setNumCores();
+    if (OK != setParams(mStride, IVD_DECODE_FRAME)) return UNKNOWN_ERROR;
+    (void) getVersion();
+
+    return OK;
+}
+
+bool C2SoftHevcDec::setDecodeArgs(ivd_video_decode_ip_t *ps_decode_ip,
+                                  ivd_video_decode_op_t *ps_decode_op,
+                                  C2ReadView *inBuffer,
+                                  C2GraphicView *outBuffer,
+                                  size_t inOffset,
+                                  size_t inSize,
+                                  uint32_t tsMarker) {
+    uint32_t displayStride = mStride;
+    uint32_t displayHeight = mHeight;
+    size_t lumaSize = displayStride * displayHeight;
+    size_t chromaSize = lumaSize >> 2;
+
+    ps_decode_ip->u4_size = sizeof(ivd_video_decode_ip_t);
+    ps_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
+    if (inBuffer) {
+        ps_decode_ip->u4_ts = tsMarker;
+        ps_decode_ip->pv_stream_buffer = const_cast<uint8_t *>(inBuffer->data() + inOffset);
+        ps_decode_ip->u4_num_Bytes = inSize;
+    } else {
+        ps_decode_ip->u4_ts = 0;
+        ps_decode_ip->pv_stream_buffer = nullptr;
+        ps_decode_ip->u4_num_Bytes = 0;
+    }
+    ps_decode_ip->s_out_buffer.u4_min_out_buf_size[0] = lumaSize;
+    ps_decode_ip->s_out_buffer.u4_min_out_buf_size[1] = chromaSize;
+    ps_decode_ip->s_out_buffer.u4_min_out_buf_size[2] = chromaSize;
+    if (outBuffer) {
+        if (outBuffer->width() < displayStride || outBuffer->height() < displayHeight) {
+            ALOGE("Output buffer too small: provided (%dx%d) required (%ux%u)",
+                  outBuffer->width(), outBuffer->height(), displayStride, displayHeight);
+            return false;
+        }
+        ps_decode_ip->s_out_buffer.pu1_bufs[0] = outBuffer->data()[C2PlanarLayout::PLANE_Y];
+        ps_decode_ip->s_out_buffer.pu1_bufs[1] = outBuffer->data()[C2PlanarLayout::PLANE_U];
+        ps_decode_ip->s_out_buffer.pu1_bufs[2] = outBuffer->data()[C2PlanarLayout::PLANE_V];
+    } else {
+        ps_decode_ip->s_out_buffer.pu1_bufs[0] = mOutBufferFlush;
+        ps_decode_ip->s_out_buffer.pu1_bufs[1] = mOutBufferFlush + lumaSize;
+        ps_decode_ip->s_out_buffer.pu1_bufs[2] = mOutBufferFlush + lumaSize + chromaSize;
+    }
+    ps_decode_ip->s_out_buffer.u4_num_bufs = 3;
+    ps_decode_op->u4_size = sizeof(ivd_video_decode_op_t);
+    ps_decode_op->u4_output_present = 0;
+
+    return true;
+}
+
+bool C2SoftHevcDec::getVuiParams() {
+    ivdext_ctl_get_vui_params_ip_t s_get_vui_params_ip;
+    ivdext_ctl_get_vui_params_op_t s_get_vui_params_op;
+
+    s_get_vui_params_ip.u4_size = sizeof(ivdext_ctl_get_vui_params_ip_t);
+    s_get_vui_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+    s_get_vui_params_ip.e_sub_cmd =
+            (IVD_CONTROL_API_COMMAND_TYPE_T) IHEVCD_CXA_CMD_CTL_GET_VUI_PARAMS;
+    s_get_vui_params_op.u4_size = sizeof(ivdext_ctl_get_vui_params_op_t);
+    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+                                                     &s_get_vui_params_ip,
+                                                     &s_get_vui_params_op);
+    if (status != IV_SUCCESS) {
+        ALOGD("error in %s: 0x%x", __func__, s_get_vui_params_op.u4_error_code);
+        return false;
+    }
+
+    VuiColorAspects vuiColorAspects;
+    vuiColorAspects.primaries = s_get_vui_params_op.u1_colour_primaries;
+    vuiColorAspects.transfer = s_get_vui_params_op.u1_transfer_characteristics;
+    vuiColorAspects.coeffs = s_get_vui_params_op.u1_matrix_coefficients;
+    vuiColorAspects.fullRange = s_get_vui_params_op.u1_video_full_range_flag;
+
+    // convert vui aspects to C2 values if changed
+    if (!(vuiColorAspects == mBitstreamColorAspects)) {
+        mBitstreamColorAspects = vuiColorAspects;
+        ColorAspects sfAspects;
+        C2StreamColorAspectsInfo::input codedAspects = { 0u };
+        ColorUtils::convertIsoColorAspectsToCodecAspects(
+                vuiColorAspects.primaries, vuiColorAspects.transfer, vuiColorAspects.coeffs,
+                vuiColorAspects.fullRange, sfAspects);
+        if (!C2Mapper::map(sfAspects.mPrimaries, &codedAspects.primaries)) {
+            codedAspects.primaries = C2Color::PRIMARIES_UNSPECIFIED;
+        }
+        if (!C2Mapper::map(sfAspects.mRange, &codedAspects.range)) {
+            codedAspects.range = C2Color::RANGE_UNSPECIFIED;
+        }
+        if (!C2Mapper::map(sfAspects.mMatrixCoeffs, &codedAspects.matrix)) {
+            codedAspects.matrix = C2Color::MATRIX_UNSPECIFIED;
+        }
+        if (!C2Mapper::map(sfAspects.mTransfer, &codedAspects.transfer)) {
+            codedAspects.transfer = C2Color::TRANSFER_UNSPECIFIED;
+        }
+        std::vector<std::unique_ptr<C2SettingResult>> failures;
+        (void)mIntf->config({&codedAspects}, C2_MAY_BLOCK, &failures);
+    }
+    return true;
+}
+
+status_t C2SoftHevcDec::setFlushMode() {
+    ivd_ctl_flush_ip_t s_set_flush_ip;
+    ivd_ctl_flush_op_t s_set_flush_op;
+
+    s_set_flush_ip.u4_size = sizeof(ivd_ctl_flush_ip_t);
+    s_set_flush_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+    s_set_flush_ip.e_sub_cmd = IVD_CMD_CTL_FLUSH;
+    s_set_flush_op.u4_size = sizeof(ivd_ctl_flush_op_t);
+    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+                                                     &s_set_flush_ip,
+                                                     &s_set_flush_op);
+    if (status != IV_SUCCESS) {
+        ALOGE("error in %s: 0x%x", __func__, s_set_flush_op.u4_error_code);
+        return UNKNOWN_ERROR;
+    }
+
+    return OK;
+}
+
+status_t C2SoftHevcDec::resetDecoder() {
+    ivd_ctl_reset_ip_t s_reset_ip;
+    ivd_ctl_reset_op_t s_reset_op;
+
+    s_reset_ip.u4_size = sizeof(ivd_ctl_reset_ip_t);
+    s_reset_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+    s_reset_ip.e_sub_cmd = IVD_CMD_CTL_RESET;
+    s_reset_op.u4_size = sizeof(ivd_ctl_reset_op_t);
+    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+                                                     &s_reset_ip,
+                                                     &s_reset_op);
+    if (IV_SUCCESS != status) {
+        ALOGE("error in %s: 0x%x", __func__, s_reset_op.u4_error_code);
+        return UNKNOWN_ERROR;
+    }
+    mStride = 0;
+    (void) setNumCores();
+    mSignalledError = false;
+    mHeaderDecoded = false;
+    return OK;
+}
+
+void C2SoftHevcDec::resetPlugin() {
+    mSignalledOutputEos = false;
+    gettimeofday(&mTimeStart, nullptr);
+    gettimeofday(&mTimeEnd, nullptr);
+}
+
+status_t C2SoftHevcDec::deleteDecoder() {
+    if (mDecHandle) {
+        ivdext_delete_ip_t s_delete_ip;
+        ivdext_delete_op_t s_delete_op;
+
+        s_delete_ip.s_ivd_delete_ip_t.u4_size = sizeof(ivdext_delete_ip_t);
+        s_delete_ip.s_ivd_delete_ip_t.e_cmd = IVD_CMD_DELETE;
+        s_delete_op.s_ivd_delete_op_t.u4_size = sizeof(ivdext_delete_op_t);
+        IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+                                                         &s_delete_ip,
+                                                         &s_delete_op);
+        if (status != IV_SUCCESS) {
+            ALOGE("error in %s: 0x%x", __func__,
+                  s_delete_op.s_ivd_delete_op_t.u4_error_code);
+            return UNKNOWN_ERROR;
+        }
+        mDecHandle = nullptr;
+    }
+
+    return OK;
+}
+
+void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
+    uint32_t flags = 0;
+    if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
+        flags |= C2FrameData::FLAG_END_OF_STREAM;
+        ALOGV("signalling eos");
+    }
+    work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
+    work->worklets.front()->output.buffers.clear();
+    work->worklets.front()->output.ordinal = work->input.ordinal;
+    work->workletsProcessed = 1u;
+}
+
+void C2SoftHevcDec::finishWork(uint64_t index, const std::unique_ptr<C2Work> &work) {
+    std::shared_ptr<C2Buffer> buffer = createGraphicBuffer(std::move(mOutBlock),
+                                                           C2Rect(mWidth, mHeight));
+    mOutBlock = nullptr;
+    {
+        IntfImpl::Lock lock = mIntf->lock();
+        buffer->setInfo(mIntf->getColorAspects_l());
+    }
+
+    class FillWork {
+       public:
+        FillWork(uint32_t flags, C2WorkOrdinalStruct ordinal,
+                 const std::shared_ptr<C2Buffer>& buffer)
+            : mFlags(flags), mOrdinal(ordinal), mBuffer(buffer) {}
+        ~FillWork() = default;
+
+        void operator()(const std::unique_ptr<C2Work>& work) {
+            work->worklets.front()->output.flags = (C2FrameData::flags_t)mFlags;
+            work->worklets.front()->output.buffers.clear();
+            work->worklets.front()->output.ordinal = mOrdinal;
+            work->workletsProcessed = 1u;
+            work->result = C2_OK;
+            if (mBuffer) {
+                work->worklets.front()->output.buffers.push_back(mBuffer);
+            }
+            ALOGV("timestamp = %lld, index = %lld, w/%s buffer",
+                  mOrdinal.timestamp.peekll(), mOrdinal.frameIndex.peekll(),
+                  mBuffer ? "" : "o");
+        }
+
+       private:
+        const uint32_t mFlags;
+        const C2WorkOrdinalStruct mOrdinal;
+        const std::shared_ptr<C2Buffer> mBuffer;
+    };
+
+    auto fillWork = [buffer](const std::unique_ptr<C2Work> &work) {
+        work->worklets.front()->output.flags = (C2FrameData::flags_t)0;
+        work->worklets.front()->output.buffers.clear();
+        work->worklets.front()->output.buffers.push_back(buffer);
+        work->worklets.front()->output.ordinal = work->input.ordinal;
+        work->workletsProcessed = 1u;
+    };
+    if (work && c2_cntr64_t(index) == work->input.ordinal.frameIndex) {
+        bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
+        // TODO: Check if cloneAndSend can be avoided by tracking number of frames remaining
+        if (eos) {
+            if (buffer) {
+                mOutIndex = index;
+                C2WorkOrdinalStruct outOrdinal = work->input.ordinal;
+                cloneAndSend(
+                    mOutIndex, work,
+                    FillWork(C2FrameData::FLAG_INCOMPLETE, outOrdinal, buffer));
+                buffer.reset();
+            }
+        } else {
+            fillWork(work);
+        }
+    } else {
+        finish(index, fillWork);
+    }
+}
+
+c2_status_t C2SoftHevcDec::ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool) {
+    if (!mDecHandle) {
+        ALOGE("not supposed to be here, invalid decoder context");
+        return C2_CORRUPTED;
+    }
+    if (mStride != ALIGN64(mWidth)) {
+        mStride = ALIGN64(mWidth);
+        if (OK != setParams(mStride, IVD_DECODE_FRAME)) return C2_CORRUPTED;
+    }
+    if (mOutBlock &&
+            (mOutBlock->width() != mStride || mOutBlock->height() != mHeight)) {
+        mOutBlock.reset();
+    }
+    if (!mOutBlock) {
+        uint32_t format = HAL_PIXEL_FORMAT_YV12;
+        C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+        c2_status_t err = pool->fetchGraphicBlock(mStride, mHeight, format, usage, &mOutBlock);
+        if (err != C2_OK) {
+            ALOGE("fetchGraphicBlock for Output failed with status %d", err);
+            return err;
+        }
+        ALOGV("provided (%dx%d) required (%dx%d)",
+              mOutBlock->width(), mOutBlock->height(), mStride, mHeight);
+    }
+
+    return C2_OK;
+}
+
+// TODO: can overall error checking be improved?
+// TODO: allow configuration of color format and usage for graphic buffers instead
+//       of hard coding them to HAL_PIXEL_FORMAT_YV12
+// TODO: pass coloraspects information to surface
+// TODO: test support for dynamic change in resolution
+// TODO: verify if the decoder sent back all frames
+void C2SoftHevcDec::process(
+        const std::unique_ptr<C2Work> &work,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    // Initialize output work
+    work->result = C2_OK;
+    work->workletsProcessed = 0u;
+    work->worklets.front()->output.configUpdate.clear();
+    work->worklets.front()->output.flags = work->input.flags;
+
+    if (mSignalledError || mSignalledOutputEos) {
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+
+    size_t inOffset = 0u;
+    size_t inSize = 0u;
+    uint32_t workIndex = work->input.ordinal.frameIndex.peeku() & 0xFFFFFFFF;
+    C2ReadView rView = mDummyReadView;
+    if (!work->input.buffers.empty()) {
+        rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
+        inSize = rView.capacity();
+        if (inSize && rView.error()) {
+            ALOGE("read view map failed %d", rView.error());
+            work->result = rView.error();
+            return;
+        }
+    }
+    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
+    bool hasPicture = false;
+
+    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
+          inSize, (int)work->input.ordinal.timestamp.peeku(),
+          (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
+    size_t inPos = 0;
+    while (inPos < inSize) {
+        if (C2_OK != ensureDecoderState(pool)) {
+            mSignalledError = true;
+            work->workletsProcessed = 1u;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+        C2GraphicView wView = mOutBlock->map().get();
+        if (wView.error()) {
+            ALOGE("graphic view map failed %d", wView.error());
+            work->result = wView.error();
+            return;
+        }
+        ivd_video_decode_ip_t s_decode_ip;
+        ivd_video_decode_op_t s_decode_op;
+        if (!setDecodeArgs(&s_decode_ip, &s_decode_op, &rView, &wView,
+                           inOffset + inPos, inSize - inPos, workIndex)) {
+            mSignalledError = true;
+            work->workletsProcessed = 1u;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+
+        if (false == mHeaderDecoded) {
+            /* Decode header and get dimensions */
+            setParams(mStride, IVD_DECODE_HEADER);
+        }
+        WORD32 delay;
+        GETTIME(&mTimeStart, nullptr);
+        TIME_DIFF(mTimeEnd, mTimeStart, delay);
+        (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
+        WORD32 decodeTime;
+        GETTIME(&mTimeEnd, nullptr);
+        TIME_DIFF(mTimeStart, mTimeEnd, decodeTime);
+        ALOGV("decodeTime=%6d delay=%6d numBytes=%6d", decodeTime, delay,
+              s_decode_op.u4_num_bytes_consumed);
+        if (IVD_MEM_ALLOC_FAILED == (s_decode_op.u4_error_code & IVD_ERROR_MASK)) {
+            ALOGE("allocation failure in decoder");
+            mSignalledError = true;
+            work->workletsProcessed = 1u;
+            work->result = C2_CORRUPTED;
+            return;
+        } else if (IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED ==
+                   (s_decode_op.u4_error_code & IVD_ERROR_MASK)) {
+            ALOGE("unsupported resolution : %dx%d", mWidth, mHeight);
+            mSignalledError = true;
+            work->workletsProcessed = 1u;
+            work->result = C2_CORRUPTED;
+            return;
+        } else if (IVD_RES_CHANGED == (s_decode_op.u4_error_code & IVD_ERROR_MASK)) {
+            ALOGV("resolution changed");
+            drainInternal(DRAIN_COMPONENT_NO_EOS, pool, work);
+            resetDecoder();
+            resetPlugin();
+            work->workletsProcessed = 0u;
+
+            /* Decode header and get new dimensions */
+            setParams(mStride, IVD_DECODE_HEADER);
+            (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
+        } else if (IS_IVD_FATAL_ERROR(s_decode_op.u4_error_code)) {
+            ALOGE("Fatal error in decoder 0x%x", s_decode_op.u4_error_code);
+            mSignalledError = true;
+            work->workletsProcessed = 1u;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+        if (0 < s_decode_op.u4_pic_wd && 0 < s_decode_op.u4_pic_ht) {
+            if (mHeaderDecoded == false) {
+                mHeaderDecoded = true;
+                setParams(ALIGN64(s_decode_op.u4_pic_wd), IVD_DECODE_FRAME);
+            }
+            if (s_decode_op.u4_pic_wd != mWidth ||  s_decode_op.u4_pic_ht != mHeight) {
+                mWidth = s_decode_op.u4_pic_wd;
+                mHeight = s_decode_op.u4_pic_ht;
+                CHECK_EQ(0u, s_decode_op.u4_output_present);
+
+                C2StreamPictureSizeInfo::output size(0u, mWidth, mHeight);
+                std::vector<std::unique_ptr<C2SettingResult>> failures;
+                c2_status_t err =
+                    mIntf->config({&size}, C2_MAY_BLOCK, &failures);
+                if (err == OK) {
+                    work->worklets.front()->output.configUpdate.push_back(
+                        C2Param::Copy(size));
+                } else {
+                    ALOGE("Cannot set width and height");
+                    mSignalledError = true;
+                    work->workletsProcessed = 1u;
+                    work->result = C2_CORRUPTED;
+                    return;
+                }
+                continue;
+            }
+        }
+        (void) getVuiParams();
+        hasPicture |= (1 == s_decode_op.u4_frame_decoded_flag);
+        if (s_decode_op.u4_output_present) {
+            finishWork(s_decode_op.u4_ts, work);
+        }
+        if (0 == s_decode_op.u4_num_bytes_consumed) {
+            ALOGD("Bytes consumed is zero. Ignoring remaining bytes");
+            break;
+        }
+        inPos += s_decode_op.u4_num_bytes_consumed;
+        if (hasPicture && (inSize - inPos)) {
+            ALOGD("decoded frame in current access nal, ignoring further trailing bytes %d",
+                  (int)inSize - (int)inPos);
+            break;
+        }
+    }
+
+    if (eos) {
+        drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
+        mSignalledOutputEos = true;
+    } else if (!hasPicture) {
+        fillEmptyWork(work);
+    }
+}
+
+c2_status_t C2SoftHevcDec::drainInternal(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool,
+        const std::unique_ptr<C2Work> &work) {
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+
+    if (OK != setFlushMode()) return C2_CORRUPTED;
+    while (true) {
+        if (C2_OK != ensureDecoderState(pool)) {
+            mSignalledError = true;
+            work->workletsProcessed = 1u;
+            work->result = C2_CORRUPTED;
+            return C2_CORRUPTED;
+        }
+        C2GraphicView wView = mOutBlock->map().get();
+        if (wView.error()) {
+            ALOGE("graphic view map failed %d", wView.error());
+            return C2_CORRUPTED;
+        }
+        ivd_video_decode_ip_t s_decode_ip;
+        ivd_video_decode_op_t s_decode_op;
+        if (!setDecodeArgs(&s_decode_ip, &s_decode_op, nullptr, &wView, 0, 0, 0)) {
+            mSignalledError = true;
+            work->workletsProcessed = 1u;
+            return C2_CORRUPTED;
+        }
+        (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
+        if (s_decode_op.u4_output_present) {
+            finishWork(s_decode_op.u4_ts, work);
+        } else {
+            fillEmptyWork(work);
+            break;
+        }
+    }
+
+    return C2_OK;
+}
+
+c2_status_t C2SoftHevcDec::drain(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    return drainInternal(drainMode, pool, nullptr);
+}
+
+class C2SoftHevcDecFactory : public C2ComponentFactory {
+public:
+    C2SoftHevcDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+        GetCodec2PlatformComponentStore()->getParamReflector())) {
+    }
+
+    virtual c2_status_t createComponent(
+            c2_node_id_t id,
+            std::shared_ptr<C2Component>* const component,
+            std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+                new C2SoftHevcDec(COMPONENT_NAME,
+                                 id,
+                                 std::make_shared<C2SoftHevcDec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+            c2_node_id_t id,
+            std::shared_ptr<C2ComponentInterface>* const interface,
+            std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+                new SimpleInterface<C2SoftHevcDec::IntfImpl>(
+                        COMPONENT_NAME, id, std::make_shared<C2SoftHevcDec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftHevcDecFactory() override = default;
+
+private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftHevcDecFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/hevc/C2SoftHevcDec.h b/media/codec2/components/hevc/C2SoftHevcDec.h
new file mode 100644
index 0000000..b7664e6
--- /dev/null
+++ b/media/codec2/components/hevc/C2SoftHevcDec.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_HEVC_DEC_H_
+#define ANDROID_C2_SOFT_HEVC_DEC_H_
+
+#include <media/stagefright/foundation/ColorUtils.h>
+
+#include <atomic>
+#include <SimpleC2Component.h>
+
+#include "ihevc_typedefs.h"
+#include "iv.h"
+#include "ivd.h"
+
+namespace android {
+
+#define ivdec_api_function              ihevcd_cxa_api_function
+#define ivdext_create_ip_t              ihevcd_cxa_create_ip_t
+#define ivdext_create_op_t              ihevcd_cxa_create_op_t
+#define ivdext_delete_ip_t              ihevcd_cxa_delete_ip_t
+#define ivdext_delete_op_t              ihevcd_cxa_delete_op_t
+#define ivdext_ctl_set_num_cores_ip_t   ihevcd_cxa_ctl_set_num_cores_ip_t
+#define ivdext_ctl_set_num_cores_op_t   ihevcd_cxa_ctl_set_num_cores_op_t
+#define ivdext_ctl_get_vui_params_ip_t  ihevcd_cxa_ctl_get_vui_params_ip_t
+#define ivdext_ctl_get_vui_params_op_t  ihevcd_cxa_ctl_get_vui_params_op_t
+#define ALIGN64(x)                      ((((x) + 63) >> 6) << 6)
+#define MAX_NUM_CORES                   4
+#define IVDEXT_CMD_CTL_SET_NUM_CORES    \
+        (IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_SET_NUM_CORES
+#define MIN(a, b)                       (((a) < (b)) ? (a) : (b))
+#define GETTIME(a, b)                   gettimeofday(a, b);
+#define TIME_DIFF(start, end, diff)     \
+    diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \
+            ((end).tv_usec - (start).tv_usec);
+
+
+struct C2SoftHevcDec : public SimpleC2Component {
+    class IntfImpl;
+
+    C2SoftHevcDec(const char* name, c2_node_id_t id,
+                  const std::shared_ptr<IntfImpl>& intfImpl);
+    virtual ~C2SoftHevcDec();
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+    c2_status_t drain(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+ private:
+    status_t createDecoder();
+    status_t setNumCores();
+    status_t setParams(size_t stride, IVD_VIDEO_DECODE_MODE_T dec_mode);
+    status_t getVersion();
+    status_t initDecoder();
+    bool setDecodeArgs(ivd_video_decode_ip_t *ps_decode_ip,
+                       ivd_video_decode_op_t *ps_decode_op,
+                       C2ReadView *inBuffer,
+                       C2GraphicView *outBuffer,
+                       size_t inOffset,
+                       size_t inSize,
+                       uint32_t tsMarker);
+    bool getVuiParams();
+    // TODO:This is not the right place for colorAspects functions. These should
+    // be part of c2-vndk so that they can be accessed by all video plugins
+    // until then, make them feel at home
+    bool colorAspectsDiffer(const ColorAspects &a, const ColorAspects &b);
+    void updateFinalColorAspects(
+            const ColorAspects &otherAspects, const ColorAspects &preferredAspects);
+    status_t handleColorAspectsChange();
+    c2_status_t ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool);
+    void finishWork(uint64_t index, const std::unique_ptr<C2Work> &work);
+    status_t setFlushMode();
+    c2_status_t drainInternal(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool,
+            const std::unique_ptr<C2Work> &work);
+    status_t resetDecoder();
+    void resetPlugin();
+    status_t deleteDecoder();
+
+    // TODO:This is not the right place for this enum. These should
+    // be part of c2-vndk so that they can be accessed by all video plugins
+    // until then, make them feel at home
+    enum {
+        kNotSupported,
+        kPreferBitstream,
+        kPreferContainer,
+    };
+
+    std::shared_ptr<IntfImpl> mIntf;
+    iv_obj_t *mDecHandle;
+    std::shared_ptr<C2GraphicBlock> mOutBlock;
+    uint8_t *mOutBufferFlush;
+
+    size_t mNumCores;
+    IV_COLOR_FORMAT_T mIvColorformat;
+
+    uint32_t mWidth;
+    uint32_t mHeight;
+    uint32_t mStride;
+    bool mSignalledOutputEos;
+    bool mSignalledError;
+    bool mHeaderDecoded;
+    std::atomic_uint64_t mOutIndex;
+
+    // Color aspects. These are ISO values and are meant to detect changes in aspects to avoid
+    // converting them to C2 values for each frame
+    struct VuiColorAspects {
+        uint8_t primaries;
+        uint8_t transfer;
+        uint8_t coeffs;
+        uint8_t fullRange;
+
+        // default color aspects
+        VuiColorAspects()
+            : primaries(2), transfer(2), coeffs(2), fullRange(0) { }
+
+        bool operator==(const VuiColorAspects &o) {
+            return primaries == o.primaries && transfer == o.transfer && coeffs == o.coeffs
+                    && fullRange == o.fullRange;
+        }
+    } mBitstreamColorAspects;
+
+    // profile
+    struct timeval mTimeStart;
+    struct timeval mTimeEnd;
+
+    C2_DO_NOT_COPY(C2SoftHevcDec);
+};
+
+}  // namespace android
+
+#endif  // ANDROID_C2_SOFT_HEVC_DEC_H_
diff --git a/media/codec2/components/hevc/C2SoftHevcEnc.cpp b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
new file mode 100644
index 0000000..b129b1b
--- /dev/null
+++ b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
@@ -0,0 +1,974 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftHevcEnc"
+#include <log/log.h>
+
+#include <media/hardware/VideoAPI.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/foundation/AUtils.h>
+
+#include <C2Debug.h>
+#include <C2PlatformSupport.h>
+#include <Codec2BufferUtils.h>
+#include <SimpleC2Interface.h>
+#include <util/C2InterfaceHelper.h>
+
+#include "ihevc_typedefs.h"
+#include "itt_video_api.h"
+#include "ihevce_api.h"
+#include "ihevce_plugin.h"
+#include "C2SoftHevcEnc.h"
+
+namespace android {
+
+namespace {
+
+constexpr char COMPONENT_NAME[] = "c2.android.hevc.encoder";
+
+} // namepsace
+
+class C2SoftHevcEnc::IntfImpl : public SimpleInterface<void>::BaseParams {
+  public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+        : SimpleInterface<void>::BaseParams(
+                helper,
+                COMPONENT_NAME,
+                C2Component::KIND_ENCODER,
+                C2Component::DOMAIN_VIDEO,
+                MEDIA_MIMETYPE_VIDEO_HEVC) {
+        noPrivateBuffers(); // TODO: account for our buffers here
+        noInputReferences();
+        noOutputReferences();
+        noTimeStretch();
+        setDerivedInstance(this);
+
+        addParameter(
+                DefineParam(mActualInputDelay, C2_PARAMKEY_INPUT_DELAY)
+                .withDefault(new C2PortActualDelayTuning::input(
+                    DEFAULT_B_FRAMES + DEFAULT_RC_LOOKAHEAD))
+                .withFields({C2F(mActualInputDelay, value).inRange(
+                    0, MAX_B_FRAMES + MAX_RC_LOOKAHEAD)})
+                .withSetter(
+                    Setter<decltype(*mActualInputDelay)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                .withConstValue(new C2ComponentAttributesSetting(
+                    C2Component::ATTRIB_IS_TEMPORAL))
+                .build());
+
+        addParameter(
+                DefineParam(mUsage, C2_PARAMKEY_INPUT_STREAM_USAGE)
+                .withConstValue(new C2StreamUsageTuning::input(
+                        0u, (uint64_t)C2MemoryUsage::CPU_READ))
+                .build());
+
+        // matches size limits in codec library
+        addParameter(
+            DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
+                .withDefault(new C2StreamPictureSizeInfo::input(0u, 320, 240))
+                .withFields({
+                    C2F(mSize, width).inRange(2, 1920, 2),
+                    C2F(mSize, height).inRange(2, 1088, 2),
+                })
+                .withSetter(SizeSetter)
+                .build());
+
+        addParameter(
+            DefineParam(mFrameRate, C2_PARAMKEY_FRAME_RATE)
+                .withDefault(new C2StreamFrameRateInfo::output(0u, 30.))
+                .withFields({C2F(mFrameRate, value).greaterThan(0.)})
+                .withSetter(
+                    Setter<decltype(*mFrameRate)>::StrictValueWithNoDeps)
+                .build());
+
+        // matches limits in codec library
+        addParameter(
+            DefineParam(mBitrateMode, C2_PARAMKEY_BITRATE_MODE)
+                .withDefault(new C2StreamBitrateModeTuning::output(
+                        0u, C2Config::BITRATE_VARIABLE))
+                .withFields({
+                    C2F(mBitrateMode, value).oneOf({
+                        C2Config::BITRATE_CONST,
+                        C2Config::BITRATE_VARIABLE,
+                        C2Config::BITRATE_IGNORE})
+                })
+                .withSetter(
+                    Setter<decltype(*mBitrateMode)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+            DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
+                .withDefault(new C2StreamBitrateInfo::output(0u, 64000))
+                .withFields({C2F(mBitrate, value).inRange(4096, 12000000)})
+                .withSetter(BitrateSetter)
+                .build());
+
+        // matches levels allowed within codec library
+        addParameter(
+                DefineParam(mComplexity, C2_PARAMKEY_COMPLEXITY)
+                .withDefault(new C2StreamComplexityTuning::output(0u, 0))
+                .withFields({C2F(mComplexity, value).inRange(0, 10)})
+                .withSetter(Setter<decltype(*mComplexity)>::NonStrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mQuality, C2_PARAMKEY_QUALITY)
+                .withDefault(new C2StreamQualityTuning::output(0u, 80))
+                .withFields({C2F(mQuality, value).inRange(0, 100)})
+                .withSetter(Setter<decltype(*mQuality)>::NonStrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+            DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
+                .withDefault(new C2StreamProfileLevelInfo::output(
+                    0u, PROFILE_HEVC_MAIN, LEVEL_HEVC_MAIN_1))
+                .withFields({
+                    C2F(mProfileLevel, profile)
+                        .oneOf({C2Config::PROFILE_HEVC_MAIN,
+                                C2Config::PROFILE_HEVC_MAIN_STILL}),
+                    C2F(mProfileLevel, level)
+                        .oneOf({LEVEL_HEVC_MAIN_1, LEVEL_HEVC_MAIN_2,
+                                LEVEL_HEVC_MAIN_2_1, LEVEL_HEVC_MAIN_3,
+                                LEVEL_HEVC_MAIN_3_1, LEVEL_HEVC_MAIN_4,
+                                LEVEL_HEVC_MAIN_4_1, LEVEL_HEVC_MAIN_5,
+                                LEVEL_HEVC_MAIN_5_1, LEVEL_HEVC_MAIN_5_2}),
+                })
+                .withSetter(ProfileLevelSetter, mSize, mFrameRate, mBitrate)
+                .build());
+
+        addParameter(
+                DefineParam(mRequestSync, C2_PARAMKEY_REQUEST_SYNC_FRAME)
+                .withDefault(new C2StreamRequestSyncFrameTuning::output(0u, C2_FALSE))
+                .withFields({C2F(mRequestSync, value).oneOf({ C2_FALSE, C2_TRUE }) })
+                .withSetter(Setter<decltype(*mRequestSync)>::NonStrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+            DefineParam(mSyncFramePeriod, C2_PARAMKEY_SYNC_FRAME_INTERVAL)
+                .withDefault(
+                    new C2StreamSyncFrameIntervalTuning::output(0u, 1000000))
+                .withFields({C2F(mSyncFramePeriod, value).any()})
+                .withSetter(
+                    Setter<decltype(*mSyncFramePeriod)>::StrictValueWithNoDeps)
+                .build());
+    }
+
+    static C2R BitrateSetter(bool mayBlock,
+                             C2P<C2StreamBitrateInfo::output>& me) {
+        (void)mayBlock;
+        C2R res = C2R::Ok();
+        if (me.v.value < 4096) {
+            me.set().value = 4096;
+        }
+        return res;
+    }
+
+    static C2R SizeSetter(bool mayBlock,
+                          const C2P<C2StreamPictureSizeInfo::input>& oldMe,
+                          C2P<C2StreamPictureSizeInfo::input>& me) {
+        (void)mayBlock;
+        C2R res = C2R::Ok();
+        if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
+            res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
+            me.set().width = oldMe.v.width;
+        }
+        if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
+            res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
+            me.set().height = oldMe.v.height;
+        }
+        return res;
+    }
+
+    static C2R ProfileLevelSetter(
+            bool mayBlock,
+            C2P<C2StreamProfileLevelInfo::output> &me,
+            const C2P<C2StreamPictureSizeInfo::input> &size,
+            const C2P<C2StreamFrameRateInfo::output> &frameRate,
+            const C2P<C2StreamBitrateInfo::output> &bitrate) {
+        (void)mayBlock;
+        if (!me.F(me.v.profile).supportsAtAll(me.v.profile)) {
+            me.set().profile = PROFILE_HEVC_MAIN;
+        }
+
+        struct LevelLimits {
+            C2Config::level_t level;
+            uint64_t samplesPerSec;
+            uint64_t samples;
+            uint32_t bitrate;
+        };
+
+        constexpr LevelLimits kLimits[] = {
+            { LEVEL_HEVC_MAIN_1,       552960,    36864,    128000 },
+            { LEVEL_HEVC_MAIN_2,      3686400,   122880,   1500000 },
+            { LEVEL_HEVC_MAIN_2_1,    7372800,   245760,   3000000 },
+            { LEVEL_HEVC_MAIN_3,     16588800,   552960,   6000000 },
+            { LEVEL_HEVC_MAIN_3_1,   33177600,   983040,  10000000 },
+            { LEVEL_HEVC_MAIN_4,     66846720,  2228224,  12000000 },
+            { LEVEL_HEVC_MAIN_4_1,  133693440,  2228224,  20000000 },
+            { LEVEL_HEVC_MAIN_5,    267386880,  8912896,  25000000 },
+            { LEVEL_HEVC_MAIN_5_1,  534773760,  8912896,  40000000 },
+            { LEVEL_HEVC_MAIN_5_2, 1069547520,  8912896,  60000000 },
+            { LEVEL_HEVC_MAIN_6,   1069547520, 35651584,  60000000 },
+            { LEVEL_HEVC_MAIN_6_1, 2139095040, 35651584, 120000000 },
+            { LEVEL_HEVC_MAIN_6_2, 4278190080, 35651584, 240000000 },
+        };
+
+        uint64_t samples = size.v.width * size.v.height;
+        uint64_t samplesPerSec = samples * frameRate.v.value;
+
+        // Check if the supplied level meets the MB / bitrate requirements. If
+        // not, update the level with the lowest level meeting the requirements.
+
+        bool found = false;
+        // By default needsUpdate = false in case the supplied level does meet
+        // the requirements.
+        bool needsUpdate = false;
+        for (const LevelLimits &limit : kLimits) {
+            if (samples <= limit.samples && samplesPerSec <= limit.samplesPerSec &&
+                    bitrate.v.value <= limit.bitrate) {
+                // This is the lowest level that meets the requirements, and if
+                // we haven't seen the supplied level yet, that means we don't
+                // need the update.
+                if (needsUpdate) {
+                    ALOGD("Given level %x does not cover current configuration: "
+                          "adjusting to %x", me.v.level, limit.level);
+                    me.set().level = limit.level;
+                }
+                found = true;
+                break;
+            }
+            if (me.v.level == limit.level) {
+                // We break out of the loop when the lowest feasible level is
+                // found. The fact that we're here means that our level doesn't
+                // meet the requirement and needs to be updated.
+                needsUpdate = true;
+            }
+        }
+        if (!found) {
+            // We set to the highest supported level.
+            me.set().level = LEVEL_HEVC_MAIN_5_2;
+        }
+        return C2R::Ok();
+    }
+
+    UWORD32 getProfile_l() const {
+        switch (mProfileLevel->profile) {
+        case PROFILE_HEVC_MAIN:  [[fallthrough]];
+        case PROFILE_HEVC_MAIN_STILL: return 1;
+        default:
+            ALOGD("Unrecognized profile: %x", mProfileLevel->profile);
+            return 1;
+        }
+    }
+
+    UWORD32 getLevel_l() const {
+        struct Level {
+            C2Config::level_t c2Level;
+            UWORD32 hevcLevel;
+        };
+        constexpr Level levels[] = {
+            { LEVEL_HEVC_MAIN_1,    30 },
+            { LEVEL_HEVC_MAIN_2,    60 },
+            { LEVEL_HEVC_MAIN_2_1,  63 },
+            { LEVEL_HEVC_MAIN_3,    90 },
+            { LEVEL_HEVC_MAIN_3_1,  93 },
+            { LEVEL_HEVC_MAIN_4,   120 },
+            { LEVEL_HEVC_MAIN_4_1, 123 },
+            { LEVEL_HEVC_MAIN_5,   150 },
+            { LEVEL_HEVC_MAIN_5_1, 153 },
+            { LEVEL_HEVC_MAIN_5_2, 156 },
+            { LEVEL_HEVC_MAIN_6,   180 },
+            { LEVEL_HEVC_MAIN_6_1, 183 },
+            { LEVEL_HEVC_MAIN_6_2, 186 },
+        };
+        for (const Level &level : levels) {
+            if (mProfileLevel->level == level.c2Level) {
+                return level.hevcLevel;
+            }
+        }
+        ALOGD("Unrecognized level: %x", mProfileLevel->level);
+        return 156;
+    }
+    uint32_t getSyncFramePeriod_l() const {
+        if (mSyncFramePeriod->value < 0 ||
+            mSyncFramePeriod->value == INT64_MAX) {
+            return 0;
+        }
+        double period = mSyncFramePeriod->value / 1e6 * mFrameRate->value;
+        return (uint32_t)c2_max(c2_min(period + 0.5, double(UINT32_MAX)), 1.);
+    }
+
+    std::shared_ptr<C2StreamPictureSizeInfo::input> getSize_l() const {
+        return mSize;
+    }
+    std::shared_ptr<C2StreamFrameRateInfo::output> getFrameRate_l() const {
+        return mFrameRate;
+    }
+    std::shared_ptr<C2StreamBitrateModeTuning::output> getBitrateMode_l() const {
+        return mBitrateMode;
+    }
+    std::shared_ptr<C2StreamBitrateInfo::output> getBitrate_l() const {
+        return mBitrate;
+    }
+    std::shared_ptr<C2StreamRequestSyncFrameTuning::output> getRequestSync_l() const {
+        return mRequestSync;
+    }
+    std::shared_ptr<C2StreamComplexityTuning::output> getComplexity_l() const {
+        return mComplexity;
+    }
+    std::shared_ptr<C2StreamQualityTuning::output> getQuality_l() const {
+        return mQuality;
+    }
+
+   private:
+    std::shared_ptr<C2StreamUsageTuning::input> mUsage;
+    std::shared_ptr<C2StreamPictureSizeInfo::input> mSize;
+    std::shared_ptr<C2StreamFrameRateInfo::output> mFrameRate;
+    std::shared_ptr<C2StreamRequestSyncFrameTuning::output> mRequestSync;
+    std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
+    std::shared_ptr<C2StreamBitrateModeTuning::output> mBitrateMode;
+    std::shared_ptr<C2StreamComplexityTuning::output> mComplexity;
+    std::shared_ptr<C2StreamQualityTuning::output> mQuality;
+    std::shared_ptr<C2StreamProfileLevelInfo::output> mProfileLevel;
+    std::shared_ptr<C2StreamSyncFrameIntervalTuning::output> mSyncFramePeriod;
+};
+
+static size_t GetCPUCoreCount() {
+    long cpuCoreCount = 0;
+
+#if defined(_SC_NPROCESSORS_ONLN)
+    cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
+#else
+    // _SC_NPROC_ONLN must be defined...
+    cpuCoreCount = sysconf(_SC_NPROC_ONLN);
+#endif
+
+    if (cpuCoreCount < 1)
+        cpuCoreCount = 1;
+    return (size_t)cpuCoreCount;
+}
+
+C2SoftHevcEnc::C2SoftHevcEnc(const char* name, c2_node_id_t id,
+                             const std::shared_ptr<IntfImpl>& intfImpl)
+    : SimpleC2Component(
+          std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+      mIntf(intfImpl),
+      mIvVideoColorFormat(IV_YUV_420P),
+      mHevcEncProfile(1),
+      mHevcEncLevel(30),
+      mStarted(false),
+      mSpsPpsHeaderReceived(false),
+      mSignalledEos(false),
+      mSignalledError(false),
+      mCodecCtx(nullptr) {
+    // If dump is enabled, then create an empty file
+    GENERATE_FILE_NAMES();
+    CREATE_DUMP_FILE(mInFile);
+    CREATE_DUMP_FILE(mOutFile);
+
+    gettimeofday(&mTimeStart, nullptr);
+    gettimeofday(&mTimeEnd, nullptr);
+}
+
+C2SoftHevcEnc::~C2SoftHevcEnc() {
+    onRelease();
+}
+
+c2_status_t C2SoftHevcEnc::onInit() {
+    return C2_OK;
+}
+
+c2_status_t C2SoftHevcEnc::onStop() {
+    return C2_OK;
+}
+
+void C2SoftHevcEnc::onReset() {
+    releaseEncoder();
+}
+
+void C2SoftHevcEnc::onRelease() {
+    releaseEncoder();
+}
+
+c2_status_t C2SoftHevcEnc::onFlush_sm() {
+    return C2_OK;
+}
+
+static void fillEmptyWork(const std::unique_ptr<C2Work>& work) {
+    uint32_t flags = 0;
+    if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
+        flags |= C2FrameData::FLAG_END_OF_STREAM;
+        ALOGV("Signalling EOS");
+    }
+    work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
+    work->worklets.front()->output.buffers.clear();
+    work->worklets.front()->output.ordinal = work->input.ordinal;
+    work->workletsProcessed = 1u;
+}
+
+static int getQpFromQuality(int quality) {
+    int qp;
+#define MIN_QP 4
+#define MAX_QP 50
+    /* Quality: 100 -> Qp : MIN_QP
+     * Quality: 0 -> Qp : MAX_QP
+     * Qp = ((MIN_QP - MAX_QP) * quality / 100) + MAX_QP;
+     */
+    qp = ((MIN_QP - MAX_QP) * quality / 100) + MAX_QP;
+    qp = std::min(qp, MAX_QP);
+    qp = std::max(qp, MIN_QP);
+    return qp;
+}
+c2_status_t C2SoftHevcEnc::initEncParams() {
+    mCodecCtx = nullptr;
+    mNumCores = std::min(GetCPUCoreCount(), (size_t) CODEC_MAX_CORES);
+    memset(&mEncParams, 0, sizeof(ihevce_static_cfg_params_t));
+
+    // default configuration
+    IHEVCE_PLUGIN_STATUS_T err = ihevce_set_def_params(&mEncParams);
+    if (IHEVCE_EOK != err) {
+        ALOGE("HEVC default init failed : 0x%x", err);
+        return C2_CORRUPTED;
+    }
+
+    // update configuration
+    mEncParams.s_src_prms.i4_width = mSize->width;
+    mEncParams.s_src_prms.i4_height = mSize->height;
+    mEncParams.s_src_prms.i4_frm_rate_denom = 1000;
+    mEncParams.s_src_prms.i4_frm_rate_num =
+        mFrameRate->value * mEncParams.s_src_prms.i4_frm_rate_denom;
+    mEncParams.s_tgt_lyr_prms.as_tgt_params[0].i4_quality_preset = IHEVCE_QUALITY_P5;
+    mEncParams.s_tgt_lyr_prms.as_tgt_params[0].ai4_tgt_bitrate[0] =
+        mBitrate->value;
+    mEncParams.s_tgt_lyr_prms.as_tgt_params[0].ai4_peak_bitrate[0] =
+        mBitrate->value << 1;
+    mEncParams.s_tgt_lyr_prms.as_tgt_params[0].i4_codec_level = mHevcEncLevel;
+    mEncParams.s_coding_tools_prms.i4_max_i_open_gop_period = mIDRInterval;
+    mEncParams.s_coding_tools_prms.i4_max_cra_open_gop_period = mIDRInterval;
+    mIvVideoColorFormat = IV_YUV_420P;
+    mEncParams.s_multi_thrd_prms.i4_max_num_cores = mNumCores;
+    mEncParams.s_out_strm_prms.i4_codec_profile = mHevcEncProfile;
+    mEncParams.s_lap_prms.i4_rc_look_ahead_pics = DEFAULT_RC_LOOKAHEAD;
+    mEncParams.s_coding_tools_prms.i4_max_temporal_layers = DEFAULT_B_FRAMES;
+
+    switch (mBitrateMode->value) {
+        case C2Config::BITRATE_IGNORE:
+            mEncParams.s_config_prms.i4_rate_control_mode = 3;
+            mEncParams.s_tgt_lyr_prms.as_tgt_params[0].ai4_frame_qp[0] =
+                getQpFromQuality(mQuality->value);
+            break;
+        case C2Config::BITRATE_CONST:
+            mEncParams.s_config_prms.i4_rate_control_mode = 5;
+            break;
+        case C2Config::BITRATE_VARIABLE:
+            [[fallthrough]];
+        default:
+            mEncParams.s_config_prms.i4_rate_control_mode = 2;
+            break;
+        break;
+    }
+
+    if (mComplexity->value == 10) {
+        mEncParams.s_tgt_lyr_prms.as_tgt_params[0].i4_quality_preset = IHEVCE_QUALITY_P0;
+    } else if (mComplexity->value >= 8) {
+        mEncParams.s_tgt_lyr_prms.as_tgt_params[0].i4_quality_preset = IHEVCE_QUALITY_P2;
+    } else if (mComplexity->value >= 7) {
+        mEncParams.s_tgt_lyr_prms.as_tgt_params[0].i4_quality_preset = IHEVCE_QUALITY_P3;
+    } else if (mComplexity->value >= 5) {
+        mEncParams.s_tgt_lyr_prms.as_tgt_params[0].i4_quality_preset = IHEVCE_QUALITY_P4;
+    } else {
+        mEncParams.s_tgt_lyr_prms.as_tgt_params[0].i4_quality_preset = IHEVCE_QUALITY_P5;
+    }
+
+    return C2_OK;
+}
+
+c2_status_t C2SoftHevcEnc::releaseEncoder() {
+    mSpsPpsHeaderReceived = false;
+    mSignalledEos = false;
+    mSignalledError = false;
+    mStarted = false;
+
+    if (mCodecCtx) {
+        IHEVCE_PLUGIN_STATUS_T err = ihevce_close(mCodecCtx);
+        if (IHEVCE_EOK != err) return C2_CORRUPTED;
+        mCodecCtx = nullptr;
+    }
+    return C2_OK;
+}
+
+c2_status_t C2SoftHevcEnc::drain(uint32_t drainMode,
+                                 const std::shared_ptr<C2BlockPool>& pool) {
+    return drainInternal(drainMode, pool, nullptr);
+}
+
+c2_status_t C2SoftHevcEnc::initEncoder() {
+    CHECK(!mCodecCtx);
+    {
+        IntfImpl::Lock lock = mIntf->lock();
+        mSize = mIntf->getSize_l();
+        mBitrateMode = mIntf->getBitrateMode_l();
+        mBitrate = mIntf->getBitrate_l();
+        mFrameRate = mIntf->getFrameRate_l();
+        mHevcEncProfile = mIntf->getProfile_l();
+        mHevcEncLevel = mIntf->getLevel_l();
+        mIDRInterval = mIntf->getSyncFramePeriod_l();
+        mComplexity = mIntf->getComplexity_l();
+        mQuality = mIntf->getQuality_l();
+    }
+
+    c2_status_t status = initEncParams();
+
+    if (C2_OK != status) {
+        ALOGE("Failed to initialize encoder params : 0x%x", status);
+        mSignalledError = true;
+        return status;
+    }
+
+    IHEVCE_PLUGIN_STATUS_T err = IHEVCE_EOK;
+    err = ihevce_init(&mEncParams, &mCodecCtx);
+    if (IHEVCE_EOK != err) {
+        ALOGE("HEVC encoder init failed : 0x%x", err);
+        return C2_CORRUPTED;
+    }
+
+    mStarted = true;
+    return C2_OK;
+}
+
+c2_status_t C2SoftHevcEnc::setEncodeArgs(ihevce_inp_buf_t* ps_encode_ip,
+                                         const C2GraphicView* const input,
+                                         uint64_t workIndex) {
+    ihevce_static_cfg_params_t* params = &mEncParams;
+    memset(ps_encode_ip, 0, sizeof(*ps_encode_ip));
+
+    if (!input) {
+        return C2_OK;
+    }
+
+    if (input->width() < mSize->width ||
+        input->height() < mSize->height) {
+        /* Expect width height to be configured */
+        ALOGW("unexpected Capacity Aspect %d(%d) x %d(%d)", input->width(),
+              mSize->width, input->height(), mSize->height);
+        return C2_BAD_VALUE;
+    }
+
+    const C2PlanarLayout& layout = input->layout();
+    uint8_t* yPlane =
+        const_cast<uint8_t *>(input->data()[C2PlanarLayout::PLANE_Y]);
+    uint8_t* uPlane =
+        const_cast<uint8_t *>(input->data()[C2PlanarLayout::PLANE_U]);
+    uint8_t* vPlane =
+        const_cast<uint8_t *>(input->data()[C2PlanarLayout::PLANE_V]);
+    int32_t yStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
+    int32_t uStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
+    int32_t vStride = layout.planes[C2PlanarLayout::PLANE_V].rowInc;
+
+    const uint32_t width = mSize->width;
+    const uint32_t height = mSize->height;
+
+    // width and height must be even
+    if (width & 1u || height & 1u) {
+        ALOGW("height(%u) and width(%u) must both be even", height, width);
+        return C2_BAD_VALUE;
+    }
+
+    size_t yPlaneSize = width * height;
+
+    switch (layout.type) {
+        case C2PlanarLayout::TYPE_RGB:
+            [[fallthrough]];
+        case C2PlanarLayout::TYPE_RGBA: {
+            MemoryBlock conversionBuffer =
+                mConversionBuffers.fetch(yPlaneSize * 3 / 2);
+            mConversionBuffersInUse.emplace(conversionBuffer.data(),
+                                            conversionBuffer);
+            yPlane = conversionBuffer.data();
+            uPlane = yPlane + yPlaneSize;
+            vPlane = uPlane + yPlaneSize / 4;
+            yStride = width;
+            uStride = vStride = yStride / 2;
+            ConvertRGBToPlanarYUV(yPlane, yStride, height,
+                                  conversionBuffer.size(), *input);
+            break;
+        }
+        case C2PlanarLayout::TYPE_YUV: {
+            if (!IsYUV420(*input)) {
+                ALOGE("input is not YUV420");
+                return C2_BAD_VALUE;
+            }
+
+            if (layout.planes[layout.PLANE_Y].colInc == 1 &&
+                layout.planes[layout.PLANE_U].colInc == 1 &&
+                layout.planes[layout.PLANE_V].colInc == 1 &&
+                uStride == vStride && yStride == 2 * vStride) {
+                // I420 compatible - already set up above
+                break;
+            }
+
+            // copy to I420
+            yStride = width;
+            uStride = vStride = yStride / 2;
+            MemoryBlock conversionBuffer =
+                mConversionBuffers.fetch(yPlaneSize * 3 / 2);
+            mConversionBuffersInUse.emplace(conversionBuffer.data(),
+                                            conversionBuffer);
+            MediaImage2 img =
+                CreateYUV420PlanarMediaImage2(width, height, yStride, height);
+            status_t err = ImageCopy(conversionBuffer.data(), &img, *input);
+            if (err != OK) {
+                ALOGE("Buffer conversion failed: %d", err);
+                return C2_BAD_VALUE;
+            }
+            yPlane = conversionBuffer.data();
+            uPlane = yPlane + yPlaneSize;
+            vPlane = uPlane + yPlaneSize / 4;
+            break;
+        }
+
+        case C2PlanarLayout::TYPE_YUVA:
+            ALOGE("YUVA plane type is not supported");
+            return C2_BAD_VALUE;
+
+        default:
+            ALOGE("Unrecognized plane type: %d", layout.type);
+            return C2_BAD_VALUE;
+    }
+
+    switch (mIvVideoColorFormat) {
+        case IV_YUV_420P: {
+            // input buffer is supposed to be const but Ittiam API wants bare
+            // pointer.
+            ps_encode_ip->apv_inp_planes[0] = yPlane;
+            ps_encode_ip->apv_inp_planes[1] = uPlane;
+            ps_encode_ip->apv_inp_planes[2] = vPlane;
+
+            ps_encode_ip->ai4_inp_strd[0] = yStride;
+            ps_encode_ip->ai4_inp_strd[1] = uStride;
+            ps_encode_ip->ai4_inp_strd[2] = vStride;
+
+            ps_encode_ip->ai4_inp_size[0] = yStride * height;
+            ps_encode_ip->ai4_inp_size[1] = uStride * height >> 1;
+            ps_encode_ip->ai4_inp_size[2] = vStride * height >> 1;
+            break;
+        }
+
+        case IV_YUV_422ILE: {
+            // TODO
+            break;
+        }
+
+        case IV_YUV_420SP_UV:
+        case IV_YUV_420SP_VU:
+        default: {
+            ps_encode_ip->apv_inp_planes[0] = yPlane;
+            ps_encode_ip->apv_inp_planes[1] = uPlane;
+            ps_encode_ip->apv_inp_planes[2] = nullptr;
+
+            ps_encode_ip->ai4_inp_strd[0] = yStride;
+            ps_encode_ip->ai4_inp_strd[1] = uStride;
+            ps_encode_ip->ai4_inp_strd[2] = 0;
+
+            ps_encode_ip->ai4_inp_size[0] = yStride * height;
+            ps_encode_ip->ai4_inp_size[1] = uStride * height >> 1;
+            ps_encode_ip->ai4_inp_size[2] = 0;
+            break;
+        }
+    }
+
+    ps_encode_ip->i4_curr_bitrate =
+        params->s_tgt_lyr_prms.as_tgt_params[0].ai4_tgt_bitrate[0];
+    ps_encode_ip->i4_curr_peak_bitrate =
+        params->s_tgt_lyr_prms.as_tgt_params[0].ai4_peak_bitrate[0];
+    ps_encode_ip->i4_curr_rate_factor = params->s_config_prms.i4_rate_factor;
+    ps_encode_ip->u8_pts = workIndex;
+    return C2_OK;
+}
+
+void C2SoftHevcEnc::finishWork(uint64_t index,
+                               const std::unique_ptr<C2Work>& work,
+                               const std::shared_ptr<C2BlockPool>& pool,
+                               ihevce_out_buf_t* ps_encode_op) {
+    std::shared_ptr<C2LinearBlock> block;
+    C2MemoryUsage usage = {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE};
+    c2_status_t status =
+        pool->fetchLinearBlock(ps_encode_op->i4_bytes_generated, usage, &block);
+    if (C2_OK != status) {
+        ALOGE("fetchLinearBlock for Output failed with status 0x%x", status);
+        mSignalledError = true;
+        work->result = status;
+        work->workletsProcessed = 1u;
+        return;
+    }
+    C2WriteView wView = block->map().get();
+    if (C2_OK != wView.error()) {
+        ALOGE("write view map failed with status 0x%x", wView.error());
+        mSignalledError = true;
+        work->result = wView.error();
+        work->workletsProcessed = 1u;
+        return;
+    }
+    memcpy(wView.data(), ps_encode_op->pu1_output_buf,
+           ps_encode_op->i4_bytes_generated);
+
+    std::shared_ptr<C2Buffer> buffer =
+        createLinearBuffer(block, 0, ps_encode_op->i4_bytes_generated);
+
+    DUMP_TO_FILE(mOutFile, ps_encode_op->pu1_output_buf,
+                 ps_encode_op->i4_bytes_generated);
+
+    if (ps_encode_op->i4_is_key_frame) {
+        ALOGV("IDR frame produced");
+        buffer->setInfo(std::make_shared<C2StreamPictureTypeMaskInfo::output>(
+            0u /* stream id */, C2Config::SYNC_FRAME));
+    }
+
+    auto fillWork = [buffer](const std::unique_ptr<C2Work>& work) {
+        work->worklets.front()->output.flags = (C2FrameData::flags_t)0;
+        work->worklets.front()->output.buffers.clear();
+        work->worklets.front()->output.buffers.push_back(buffer);
+        work->worklets.front()->output.ordinal = work->input.ordinal;
+        work->workletsProcessed = 1u;
+    };
+    if (work && c2_cntr64_t(index) == work->input.ordinal.frameIndex) {
+        fillWork(work);
+        if (mSignalledEos) {
+            work->worklets.front()->output.flags =
+                C2FrameData::FLAG_END_OF_STREAM;
+        }
+    } else {
+        finish(index, fillWork);
+    }
+}
+
+c2_status_t C2SoftHevcEnc::drainInternal(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool,
+        const std::unique_ptr<C2Work> &work) {
+
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+
+    while (true) {
+        ihevce_out_buf_t s_encode_op{};
+        memset(&s_encode_op, 0, sizeof(s_encode_op));
+
+        ihevce_encode(mCodecCtx, nullptr, &s_encode_op);
+        if (s_encode_op.i4_bytes_generated) {
+            finishWork(s_encode_op.u8_pts, work, pool, &s_encode_op);
+        } else {
+            if (work->workletsProcessed != 1u) fillEmptyWork(work);
+            break;
+        }
+    }
+    return C2_OK;
+}
+
+void C2SoftHevcEnc::process(const std::unique_ptr<C2Work>& work,
+                            const std::shared_ptr<C2BlockPool>& pool) {
+    // Initialize output work
+    work->result = C2_OK;
+    work->workletsProcessed = 0u;
+    work->worklets.front()->output.flags = work->input.flags;
+
+    if (mSignalledError || mSignalledEos) {
+        work->result = C2_BAD_VALUE;
+        ALOGD("Signalled Error / Signalled Eos");
+        return;
+    }
+    c2_status_t status = C2_OK;
+
+    // Initialize encoder if not already initialized
+    if (!mStarted) {
+        status = initEncoder();
+        if (C2_OK != status) {
+            ALOGE("Failed to initialize encoder : 0x%x", status);
+            mSignalledError = true;
+            work->result = status;
+            work->workletsProcessed = 1u;
+            return;
+        }
+    }
+
+    std::shared_ptr<const C2GraphicView> view;
+    std::shared_ptr<C2Buffer> inputBuffer = nullptr;
+    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
+    if (eos) mSignalledEos = true;
+
+    if (!work->input.buffers.empty()) {
+        inputBuffer = work->input.buffers[0];
+        view = std::make_shared<const C2GraphicView>(
+            inputBuffer->data().graphicBlocks().front().map().get());
+        if (view->error() != C2_OK) {
+            ALOGE("graphic view map err = %d", view->error());
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            work->workletsProcessed = 1u;
+            return;
+        }
+    }
+    IHEVCE_PLUGIN_STATUS_T err = IHEVCE_EOK;
+
+    if (!mSpsPpsHeaderReceived) {
+        ihevce_out_buf_t s_header_op{};
+        err = ihevce_encode_header(mCodecCtx, &s_header_op);
+        if (err == IHEVCE_EOK && s_header_op.i4_bytes_generated) {
+            std::unique_ptr<C2StreamInitDataInfo::output> csd =
+                C2StreamInitDataInfo::output::AllocUnique(
+                    s_header_op.i4_bytes_generated, 0u);
+            if (!csd) {
+                ALOGE("CSD allocation failed");
+                mSignalledError = true;
+                work->result = C2_NO_MEMORY;
+                work->workletsProcessed = 1u;
+                return;
+            }
+            memcpy(csd->m.value, s_header_op.pu1_output_buf,
+                   s_header_op.i4_bytes_generated);
+            DUMP_TO_FILE(mOutFile, csd->m.value, csd->flexCount());
+            work->worklets.front()->output.configUpdate.push_back(
+                std::move(csd));
+            mSpsPpsHeaderReceived = true;
+        }
+        if (!inputBuffer) {
+            work->workletsProcessed = 1u;
+            return;
+        }
+    }
+
+    // handle dynamic config parameters
+    {
+        IntfImpl::Lock lock = mIntf->lock();
+        std::shared_ptr<C2StreamBitrateInfo::output> bitrate = mIntf->getBitrate_l();
+        lock.unlock();
+
+        if (bitrate != mBitrate) {
+            mBitrate = bitrate;
+            mEncParams.s_tgt_lyr_prms.as_tgt_params[0].ai4_tgt_bitrate[0] =
+                mBitrate->value;
+            mEncParams.s_tgt_lyr_prms.as_tgt_params[0].ai4_peak_bitrate[0] =
+                mBitrate->value << 1;
+        }
+    }
+
+    ihevce_inp_buf_t s_encode_ip{};
+    ihevce_out_buf_t s_encode_op{};
+    uint64_t workIndex = work->input.ordinal.frameIndex.peekull();
+
+    status = setEncodeArgs(&s_encode_ip, view.get(), workIndex);
+    if (C2_OK != status) {
+        ALOGE("setEncodeArgs failed : 0x%x", status);
+        mSignalledError = true;
+        work->result = status;
+        work->workletsProcessed = 1u;
+        return;
+    }
+
+    uint64_t timeDelay = 0;
+    uint64_t timeTaken = 0;
+    memset(&s_encode_op, 0, sizeof(s_encode_op));
+    GETTIME(&mTimeStart, nullptr);
+    TIME_DIFF(mTimeEnd, mTimeStart, timeDelay);
+
+    if (inputBuffer) {
+        err = ihevce_encode(mCodecCtx, &s_encode_ip, &s_encode_op);
+        if (IHEVCE_EOK != err) {
+            ALOGE("Encode Frame failed : 0x%x", err);
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            work->workletsProcessed = 1u;
+            return;
+        }
+    } else if (!eos) {
+        fillEmptyWork(work);
+    }
+
+    GETTIME(&mTimeEnd, nullptr);
+    /* Compute time taken for decode() */
+    TIME_DIFF(mTimeStart, mTimeEnd, timeTaken);
+
+    ALOGV("timeTaken=%6d delay=%6d numBytes=%6d", (int)timeTaken,
+          (int)timeDelay, s_encode_op.i4_bytes_generated);
+
+    if (s_encode_op.i4_bytes_generated) {
+        finishWork(s_encode_op.u8_pts, work, pool, &s_encode_op);
+    }
+
+    if (eos) {
+        drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
+    }
+}
+
+class C2SoftHevcEncFactory : public C2ComponentFactory {
+   public:
+    C2SoftHevcEncFactory()
+        : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+              GetCodec2PlatformComponentStore()->getParamReflector())) {}
+
+    c2_status_t createComponent(
+        c2_node_id_t id,
+        std::shared_ptr<C2Component>* const component,
+        std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+            new C2SoftHevcEnc(
+                COMPONENT_NAME, id,
+                std::make_shared<C2SoftHevcEnc::IntfImpl>(mHelper)),
+            deleter);
+        return C2_OK;
+    }
+
+    c2_status_t createInterface(
+        c2_node_id_t id,
+        std::shared_ptr<C2ComponentInterface>* const interface,
+        std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+            new SimpleInterface<C2SoftHevcEnc::IntfImpl>(
+                COMPONENT_NAME, id,
+                std::make_shared<C2SoftHevcEnc::IntfImpl>(mHelper)),
+            deleter);
+        return C2_OK;
+    }
+
+    ~C2SoftHevcEncFactory() override = default;
+
+   private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftHevcEncFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/hevc/C2SoftHevcEnc.h b/media/codec2/components/hevc/C2SoftHevcEnc.h
new file mode 100644
index 0000000..f2c7642
--- /dev/null
+++ b/media/codec2/components/hevc/C2SoftHevcEnc.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_HEVC_ENC_H_
+#define ANDROID_C2_SOFT_HEVC_ENC_H_
+
+#include <SimpleC2Component.h>
+#include <algorithm>
+#include <map>
+#include <media/stagefright/foundation/ColorUtils.h>
+#include <utils/Vector.h>
+
+#include "ihevc_typedefs.h"
+
+namespace android {
+
+/** Get time */
+#define GETTIME(a, b) gettimeofday(a, b)
+
+/** Compute difference between start and end */
+#define TIME_DIFF(start, end, diff)                      \
+    diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \
+           ((end).tv_usec - (start).tv_usec);
+
+#define CODEC_MAX_CORES  4
+#define MAX_B_FRAMES     1
+#define MAX_RC_LOOKAHEAD 1
+
+#define DEFAULT_B_FRAMES     0
+#define DEFAULT_RC_LOOKAHEAD 0
+
+struct C2SoftHevcEnc : public SimpleC2Component {
+    class IntfImpl;
+
+    C2SoftHevcEnc(const char* name, c2_node_id_t id,
+                  const std::shared_ptr<IntfImpl>& intfImpl);
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(const std::unique_ptr<C2Work>& work,
+                 const std::shared_ptr<C2BlockPool>& pool) override;
+    c2_status_t drain(uint32_t drainMode,
+                      const std::shared_ptr<C2BlockPool>& pool) override;
+
+   protected:
+    ~C2SoftHevcEnc() override;
+
+   private:
+    std::shared_ptr<IntfImpl> mIntf;
+    ihevce_static_cfg_params_t mEncParams;
+    size_t mNumCores;
+    UWORD32 mIDRInterval;
+    IV_COLOR_FORMAT_T mIvVideoColorFormat;
+    UWORD32 mHevcEncProfile;
+    UWORD32 mHevcEncLevel;
+    bool mStarted;
+    bool mSpsPpsHeaderReceived;
+    bool mSignalledEos;
+    bool mSignalledError;
+    void* mCodecCtx;
+    MemoryBlockPool mConversionBuffers;
+    std::map<void*, MemoryBlock> mConversionBuffersInUse;
+    // configurations used by component in process
+    // (TODO: keep this in intf but make them internal only)
+    std::shared_ptr<C2StreamPictureSizeInfo::input> mSize;
+    std::shared_ptr<C2StreamFrameRateInfo::output> mFrameRate;
+    std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
+    std::shared_ptr<C2StreamBitrateModeTuning::output> mBitrateMode;
+    std::shared_ptr<C2StreamComplexityTuning::output> mComplexity;
+    std::shared_ptr<C2StreamQualityTuning::output> mQuality;
+
+#ifdef FILE_DUMP_ENABLE
+    char mInFile[200];
+    char mOutFile[200];
+#endif /* FILE_DUMP_ENABLE */
+
+    // profile
+    struct timeval mTimeStart;
+    struct timeval mTimeEnd;
+
+    c2_status_t initEncParams();
+    c2_status_t initEncoder();
+    c2_status_t releaseEncoder();
+    c2_status_t setEncodeArgs(ihevce_inp_buf_t* ps_encode_ip,
+                              const C2GraphicView* const input,
+                              uint64_t workIndex);
+    void finishWork(uint64_t index, const std::unique_ptr<C2Work>& work,
+                    const std::shared_ptr<C2BlockPool>& pool,
+                    ihevce_out_buf_t* ps_encode_op);
+    c2_status_t drainInternal(uint32_t drainMode,
+                              const std::shared_ptr<C2BlockPool>& pool,
+                              const std::unique_ptr<C2Work>& work);
+    C2_DO_NOT_COPY(C2SoftHevcEnc);
+};
+#ifdef FILE_DUMP_ENABLE
+
+#define INPUT_DUMP_PATH "/data/local/tmp/hevc"
+#define INPUT_DUMP_EXT "yuv"
+#define OUTPUT_DUMP_PATH "/data/local/tmp/hevc"
+#define OUTPUT_DUMP_EXT "h265"
+#define GENERATE_FILE_NAMES()                                             \
+{                                                                         \
+    GETTIME(&mTimeStart, NULL);                                           \
+    strcpy(mInFile, "");                                                  \
+    ALOGD("GENERATE_FILE_NAMES");                                         \
+    sprintf(mInFile, "%s_%ld.%ld.%s", INPUT_DUMP_PATH, mTimeStart.tv_sec, \
+            mTimeStart.tv_usec, INPUT_DUMP_EXT);                          \
+    strcpy(mOutFile, "");                                                 \
+    sprintf(mOutFile, "%s_%ld.%ld.%s", OUTPUT_DUMP_PATH,                  \
+            mTimeStart.tv_sec, mTimeStart.tv_usec, OUTPUT_DUMP_EXT);      \
+}
+
+#define CREATE_DUMP_FILE(m_filename)                 \
+{                                                    \
+    FILE* fp = fopen(m_filename, "wb");              \
+    if (fp != NULL) {                                \
+        ALOGD("Opened file %s", m_filename);         \
+        fclose(fp);                                  \
+    } else {                                         \
+        ALOGD("Could not open file %s", m_filename); \
+    }                                                \
+}
+#define DUMP_TO_FILE(m_filename, m_buf, m_size)          \
+{                                                        \
+    FILE* fp = fopen(m_filename, "ab");                  \
+    if (fp != NULL && m_buf != NULL) {                   \
+        int i;                                           \
+        ALOGD("Dump to file!");                          \
+        i = fwrite(m_buf, 1, m_size, fp);                \
+        if (i != (int)m_size) {                          \
+            ALOGD("Error in fwrite, returned %d", i);    \
+            perror("Error in write to file");            \
+        }                                                \
+        fclose(fp);                                      \
+    } else {                                             \
+        ALOGD("Could not write to file %s", m_filename); \
+        if (fp != NULL) fclose(fp);                      \
+    }                                                    \
+}
+#else /* FILE_DUMP_ENABLE */
+#define INPUT_DUMP_PATH
+#define INPUT_DUMP_EXT
+#define OUTPUT_DUMP_PATH
+#define OUTPUT_DUMP_EXT
+#define GENERATE_FILE_NAMES()
+#define CREATE_DUMP_FILE(m_filename)
+#define DUMP_TO_FILE(m_filename, m_buf, m_size)
+#endif /* FILE_DUMP_ENABLE */
+
+}  // namespace android
+
+#endif  // C2_SOFT_HEVC_ENC_H__
diff --git a/media/codec2/components/mp3/Android.bp b/media/codec2/components/mp3/Android.bp
new file mode 100644
index 0000000..66665ed
--- /dev/null
+++ b/media/codec2/components/mp3/Android.bp
@@ -0,0 +1,11 @@
+cc_library_shared {
+    name: "libcodec2_soft_mp3dec",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["C2SoftMp3Dec.cpp"],
+
+    static_libs: ["libstagefright_mp3dec"],
+}
diff --git a/media/codec2/components/mp3/C2SoftMp3Dec.cpp b/media/codec2/components/mp3/C2SoftMp3Dec.cpp
new file mode 100644
index 0000000..5ba7e3d
--- /dev/null
+++ b/media/codec2/components/mp3/C2SoftMp3Dec.cpp
@@ -0,0 +1,550 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftMp3Dec"
+#include <log/log.h>
+
+#include <numeric>
+
+#include <media/stagefright/foundation/MediaDefs.h>
+
+#include <C2PlatformSupport.h>
+#include <SimpleC2Interface.h>
+
+#include "C2SoftMp3Dec.h"
+#include "pvmp3decoder_api.h"
+
+namespace android {
+
+namespace {
+
+constexpr char COMPONENT_NAME[] = "c2.android.mp3.decoder";
+
+}  // namespace
+
+class C2SoftMP3::IntfImpl : public SimpleInterface<void>::BaseParams {
+public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+        : SimpleInterface<void>::BaseParams(
+                helper,
+                COMPONENT_NAME,
+                C2Component::KIND_DECODER,
+                C2Component::DOMAIN_AUDIO,
+                MEDIA_MIMETYPE_AUDIO_MPEG) {
+        noPrivateBuffers();
+        noInputReferences();
+        noOutputReferences();
+        noInputLatency();
+        noTimeStretch();
+        setDerivedInstance(this);
+
+        addParameter(
+                DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                .withConstValue(new C2ComponentAttributesSetting(
+                    C2Component::ATTRIB_IS_TEMPORAL))
+                .build());
+
+        addParameter(
+                DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE)
+                .withDefault(new C2StreamSampleRateInfo::output(0u, 44100))
+                .withFields({C2F(mSampleRate, value).oneOf({8000, 11025, 12000, 16000,
+                    22050, 24000, 32000, 44100, 48000})})
+                .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
+                .build());
+
+        addParameter(
+                DefineParam(mChannelCount, C2_PARAMKEY_CHANNEL_COUNT)
+                .withDefault(new C2StreamChannelCountInfo::output(0u, 2))
+                .withFields({C2F(mChannelCount, value).inRange(1, 2)})
+                .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
+                .withDefault(new C2StreamBitrateInfo::input(0u, 64000))
+                .withFields({C2F(mBitrate, value).inRange(8000, 320000)})
+                .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
+                .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 8192))
+                .build());
+    }
+
+private:
+    std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
+    std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
+    std::shared_ptr<C2StreamBitrateInfo::input> mBitrate;
+    std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
+};
+
+C2SoftMP3::C2SoftMP3(const char *name, c2_node_id_t id,
+                     const std::shared_ptr<IntfImpl> &intfImpl)
+    : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+      mIntf(intfImpl),
+      mConfig(nullptr),
+      mDecoderBuf(nullptr) {
+}
+
+C2SoftMP3::~C2SoftMP3() {
+    onRelease();
+}
+
+c2_status_t C2SoftMP3::onInit() {
+    status_t err = initDecoder();
+    return err == OK ? C2_OK : C2_NO_MEMORY;
+}
+
+c2_status_t C2SoftMP3::onStop() {
+    // Make sure that the next buffer output does not still
+    // depend on fragments from the last one decoded.
+    pvmp3_InitDecoder(mConfig, mDecoderBuf);
+    mSignalledError = false;
+    mIsFirst = true;
+    mSignalledOutputEos = false;
+    mAnchorTimeStamp = 0;
+    mProcessedSamples = 0;
+
+    return C2_OK;
+}
+
+void C2SoftMP3::onReset() {
+    (void)onStop();
+}
+
+void C2SoftMP3::onRelease() {
+    mGaplessBytes = false;
+    if (mDecoderBuf) {
+        free(mDecoderBuf);
+        mDecoderBuf = nullptr;
+    }
+
+    if (mConfig) {
+        delete mConfig;
+        mConfig = nullptr;
+    }
+}
+
+status_t C2SoftMP3::initDecoder() {
+    mConfig = new tPVMP3DecoderExternal{};
+    if (!mConfig) return NO_MEMORY;
+    mConfig->equalizerType = flat;
+    mConfig->crcEnabled = false;
+
+    size_t memRequirements = pvmp3_decoderMemRequirements();
+    mDecoderBuf = malloc(memRequirements);
+    if (!mDecoderBuf) return NO_MEMORY;
+
+    pvmp3_InitDecoder(mConfig, mDecoderBuf);
+
+    mIsFirst = true;
+    mGaplessBytes = false;
+    mSignalledError = false;
+    mSignalledOutputEos = false;
+    mAnchorTimeStamp = 0;
+    mProcessedSamples = 0;
+
+    return OK;
+}
+
+/* The below code is borrowed from ./test/mp3reader.cpp */
+static bool parseMp3Header(uint32_t header, size_t *frame_size,
+                           uint32_t *out_sampling_rate = nullptr,
+                           uint32_t *out_channels = nullptr,
+                           uint32_t *out_bitrate = nullptr,
+                           uint32_t *out_num_samples = nullptr) {
+    *frame_size = 0;
+    if (out_sampling_rate) *out_sampling_rate = 0;
+    if (out_channels) *out_channels = 0;
+    if (out_bitrate) *out_bitrate = 0;
+    if (out_num_samples) *out_num_samples = 1152;
+
+    if ((header & 0xffe00000) != 0xffe00000) return false;
+
+    unsigned version = (header >> 19) & 3;
+    if (version == 0x01) return false;
+
+    unsigned layer = (header >> 17) & 3;
+    if (layer == 0x00) return false;
+
+    unsigned bitrate_index = (header >> 12) & 0x0f;
+    if (bitrate_index == 0 || bitrate_index == 0x0f) return false;
+
+    unsigned sampling_rate_index = (header >> 10) & 3;
+    if (sampling_rate_index == 3) return false;
+
+    static const int kSamplingRateV1[] = { 44100, 48000, 32000 };
+    int sampling_rate = kSamplingRateV1[sampling_rate_index];
+    if (version == 2 /* V2 */) {
+        sampling_rate /= 2;
+    } else if (version == 0 /* V2.5 */) {
+        sampling_rate /= 4;
+    }
+
+    unsigned padding = (header >> 9) & 1;
+
+    if (layer == 3) { // layer I
+        static const int kBitrateV1[] =
+        {
+            32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448
+        };
+        static const int kBitrateV2[] =
+        {
+            32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256
+        };
+
+        int bitrate = (version == 3 /* V1 */) ? kBitrateV1[bitrate_index - 1] :
+                kBitrateV2[bitrate_index - 1];
+
+        if (out_bitrate) {
+            *out_bitrate = bitrate;
+        }
+        *frame_size = (12000 * bitrate / sampling_rate + padding) * 4;
+        if (out_num_samples) {
+            *out_num_samples = 384;
+        }
+    } else { // layer II or III
+        static const int kBitrateV1L2[] =
+        {
+            32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384
+        };
+
+        static const int kBitrateV1L3[] =
+        {
+            32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320
+        };
+
+        static const int kBitrateV2[] =
+        {
+            8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160
+        };
+
+        int bitrate;
+        if (version == 3 /* V1 */) {
+            bitrate = (layer == 2 /* L2 */) ? kBitrateV1L2[bitrate_index - 1] :
+                    kBitrateV1L3[bitrate_index - 1];
+
+            if (out_num_samples) {
+                *out_num_samples = 1152;
+            }
+        } else { // V2 (or 2.5)
+            bitrate = kBitrateV2[bitrate_index - 1];
+            if (out_num_samples) {
+                *out_num_samples = (layer == 1 /* L3 */) ? 576 : 1152;
+            }
+        }
+
+        if (out_bitrate) {
+            *out_bitrate = bitrate;
+        }
+
+        if (version == 3 /* V1 */) {
+            *frame_size = 144000 * bitrate / sampling_rate + padding;
+        } else { // V2 or V2.5
+            size_t tmp = (layer == 1 /* L3 */) ? 72000 : 144000;
+            *frame_size = tmp * bitrate / sampling_rate + padding;
+        }
+    }
+
+    if (out_sampling_rate) {
+        *out_sampling_rate = sampling_rate;
+    }
+
+    if (out_channels) {
+        int channel_mode = (header >> 6) & 3;
+
+        *out_channels = (channel_mode == 3) ? 1 : 2;
+    }
+
+    return true;
+}
+
+static uint32_t U32_AT(const uint8_t *ptr) {
+    return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
+}
+
+static status_t calculateOutSize(uint8 *header, size_t inSize,
+                                 std::vector<size_t> *decodedSizes) {
+    uint32_t channels;
+    uint32_t numSamples;
+    size_t frameSize;
+    size_t totalInSize = 0;
+
+    while (totalInSize + 4 < inSize) {
+        if (!parseMp3Header(U32_AT(header + totalInSize), &frameSize,
+                            nullptr, &channels, nullptr, &numSamples)) {
+            ALOGE("Error in parse mp3 header during outSize estimation");
+            return UNKNOWN_ERROR;
+        }
+        totalInSize += frameSize;
+        decodedSizes->push_back(numSamples * channels * sizeof(int16_t));
+    }
+
+    if (decodedSizes->empty()) return UNKNOWN_ERROR;
+
+    return OK;
+}
+
+c2_status_t C2SoftMP3::onFlush_sm() {
+    return onStop();
+}
+
+c2_status_t C2SoftMP3::drain(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    (void) pool;
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+
+    return C2_OK;
+}
+
+// TODO: Can overall error checking be improved? As in the check for validity of
+//       work, pool ptr, work->input.buffers.size() == 1, ...
+// TODO: Blind removal of 529 samples from the output may not work. Because
+//       mpeg layer 1 frame size is 384 samples per frame. This should introduce
+//       negative values and can cause SEG faults. Soft omx mp3 plugin can have
+//       this problem (CHECK!)
+void C2SoftMP3::process(
+        const std::unique_ptr<C2Work> &work,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    // Initialize output work
+    work->result = C2_OK;
+    work->workletsProcessed = 1u;
+    work->worklets.front()->output.configUpdate.clear();
+    work->worklets.front()->output.flags = work->input.flags;
+
+    if (mSignalledError || mSignalledOutputEos) {
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+
+    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
+    size_t inSize = 0u;
+    C2ReadView rView = mDummyReadView;
+    if (!work->input.buffers.empty()) {
+        rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
+        inSize = rView.capacity();
+        if (inSize && rView.error()) {
+            ALOGE("read view map failed %d", rView.error());
+            work->result = rView.error();
+            return;
+        }
+    }
+
+    if (inSize == 0 && (!mGaplessBytes || !eos)) {
+        work->worklets.front()->output.flags = work->input.flags;
+        work->worklets.front()->output.buffers.clear();
+        work->worklets.front()->output.ordinal = work->input.ordinal;
+        return;
+    }
+    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
+          (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
+
+    int32_t numChannels = mConfig->num_channels;
+    size_t calOutSize;
+    std::vector<size_t> decodedSizes;
+    if (inSize && OK != calculateOutSize(const_cast<uint8 *>(rView.data()),
+                                         inSize, &decodedSizes)) {
+        work->result = C2_CORRUPTED;
+        return;
+    }
+    calOutSize = std::accumulate(decodedSizes.begin(), decodedSizes.end(), 0);
+    if (eos) {
+        calOutSize += kPVMP3DecoderDelay * numChannels * sizeof(int16_t);
+    }
+
+    std::shared_ptr<C2LinearBlock> block;
+    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+    c2_status_t err = pool->fetchLinearBlock(calOutSize, usage, &block);
+    if (err != C2_OK) {
+        ALOGE("fetchLinearBlock for Output failed with status %d", err);
+        work->result = C2_NO_MEMORY;
+        return;
+    }
+    C2WriteView wView = block->map().get();
+    if (wView.error()) {
+        ALOGE("write view map failed %d", wView.error());
+        work->result = wView.error();
+        return;
+    }
+
+    int outSize = 0;
+    int outOffset = 0;
+    auto it = decodedSizes.begin();
+    size_t inPos = 0;
+    int32_t samplingRate = mConfig->samplingRate;
+    while (inPos < inSize) {
+        if (it == decodedSizes.end()) {
+            ALOGE("unexpected trailing bytes, ignoring them");
+            break;
+        }
+
+        mConfig->pInputBuffer = const_cast<uint8 *>(rView.data() + inPos);
+        mConfig->inputBufferCurrentLength = (inSize - inPos);
+        mConfig->inputBufferMaxLength = 0;
+        mConfig->inputBufferUsedLength = 0;
+        mConfig->outputFrameSize = (calOutSize - outSize);
+        mConfig->pOutputBuffer = reinterpret_cast<int16_t *> (wView.data() + outSize);
+
+        ERROR_CODE decoderErr;
+        if ((decoderErr = pvmp3_framedecoder(mConfig, mDecoderBuf))
+                != NO_DECODING_ERROR) {
+            ALOGE("mp3 decoder returned error %d", decoderErr);
+            if (decoderErr != NO_ENOUGH_MAIN_DATA_ERROR
+                    && decoderErr != SIDE_INFO_ERROR) {
+                mSignalledError = true;
+                work->result = C2_CORRUPTED;
+                return;
+            }
+
+            // This is recoverable, just ignore the current frame and
+            // play silence instead.
+            ALOGV("ignoring error and sending silence");
+            if (mConfig->outputFrameSize == 0) {
+                mConfig->outputFrameSize = *it / sizeof(int16_t);
+            }
+            memset(mConfig->pOutputBuffer, 0, mConfig->outputFrameSize * sizeof(int16_t));
+        } else if (mConfig->samplingRate != samplingRate
+                || mConfig->num_channels != numChannels) {
+            ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
+                   samplingRate, mConfig->samplingRate,
+                   numChannels, mConfig->num_channels);
+            samplingRate = mConfig->samplingRate;
+            numChannels = mConfig->num_channels;
+
+            C2StreamSampleRateInfo::output sampleRateInfo(0u, samplingRate);
+            C2StreamChannelCountInfo::output channelCountInfo(0u, numChannels);
+            std::vector<std::unique_ptr<C2SettingResult>> failures;
+            c2_status_t err = mIntf->config(
+                    { &sampleRateInfo, &channelCountInfo },
+                    C2_MAY_BLOCK,
+                    &failures);
+            if (err == OK) {
+                work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(sampleRateInfo));
+                work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(channelCountInfo));
+            } else {
+                ALOGE("Config Update failed");
+                mSignalledError = true;
+                work->result = C2_CORRUPTED;
+                return;
+            }
+        }
+        if (*it != mConfig->outputFrameSize * sizeof(int16_t)) {
+            ALOGE("panic, parsed size does not match decoded size");
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+        outSize += mConfig->outputFrameSize * sizeof(int16_t);
+        inPos += mConfig->inputBufferUsedLength;
+        it++;
+    }
+    if (mIsFirst) {
+        mIsFirst = false;
+        mGaplessBytes = true;
+        // The decoder delay is 529 samples, so trim that many samples off
+        // the start of the first output buffer. This essentially makes this
+        // decoder have zero delay, which the rest of the pipeline assumes.
+        outOffset = kPVMP3DecoderDelay * numChannels * sizeof(int16_t);
+        mAnchorTimeStamp = work->input.ordinal.timestamp.peekull();
+    }
+    if (eos) {
+        if (calOutSize >=
+            outSize + kPVMP3DecoderDelay * numChannels * sizeof(int16_t)) {
+            if (!memset(reinterpret_cast<int16_t*>(wView.data() + outSize), 0,
+                        kPVMP3DecoderDelay * numChannels * sizeof(int16_t))) {
+                mSignalledError = true;
+                work->result = C2_CORRUPTED;
+                return;
+             }
+            ALOGV("Adding 529 samples at end");
+            mGaplessBytes = false;
+            outSize += kPVMP3DecoderDelay * numChannels * sizeof(int16_t);
+        }
+    }
+
+    uint64_t outTimeStamp = mProcessedSamples * 1000000ll / samplingRate;
+    mProcessedSamples += ((outSize - outOffset) / (numChannels * sizeof(int16_t)));
+    ALOGV("out buffer attr. offset %d size %d timestamp %u", outOffset, outSize - outOffset,
+          (uint32_t)(mAnchorTimeStamp + outTimeStamp));
+    decodedSizes.clear();
+    work->worklets.front()->output.flags = work->input.flags;
+    work->worklets.front()->output.buffers.clear();
+    work->worklets.front()->output.buffers.push_back(
+            createLinearBuffer(block, outOffset, outSize - outOffset));
+    work->worklets.front()->output.ordinal = work->input.ordinal;
+    work->worklets.front()->output.ordinal.timestamp = mAnchorTimeStamp + outTimeStamp;
+    if (eos) {
+        mSignalledOutputEos = true;
+        ALOGV("signalled EOS");
+    }
+}
+
+class C2SoftMp3DecFactory : public C2ComponentFactory {
+public:
+    C2SoftMp3DecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+            GetCodec2PlatformComponentStore()->getParamReflector())) {
+    }
+
+    virtual c2_status_t createComponent(
+            c2_node_id_t id,
+            std::shared_ptr<C2Component>* const component,
+            std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+              new C2SoftMP3(COMPONENT_NAME,
+                            id,
+                            std::make_shared<C2SoftMP3::IntfImpl>(mHelper)),
+              deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+            c2_node_id_t id,
+            std::shared_ptr<C2ComponentInterface>* const interface,
+            std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+              new SimpleInterface<C2SoftMP3::IntfImpl>(
+                      COMPONENT_NAME, id, std::make_shared<C2SoftMP3::IntfImpl>(mHelper)),
+              deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftMp3DecFactory() override = default;
+
+private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftMp3DecFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/mp3/C2SoftMp3Dec.h b/media/codec2/components/mp3/C2SoftMp3Dec.h
new file mode 100644
index 0000000..402bdc4
--- /dev/null
+++ b/media/codec2/components/mp3/C2SoftMp3Dec.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_MP3_DEC_H_
+#define ANDROID_C2_SOFT_MP3_DEC_H_
+
+#include <SimpleC2Component.h>
+
+
+struct tPVMP3DecoderExternal;
+
+bool parseMp3Header(uint32_t header, size_t *frame_size,
+                    uint32_t *out_sampling_rate = nullptr,
+                    uint32_t *out_channels = nullptr,
+                    uint32_t *out_bitrate = nullptr,
+                    uint32_t *out_num_samples = nullptr);
+
+namespace android {
+
+struct C2SoftMP3 : public SimpleC2Component {
+    class IntfImpl;
+
+    C2SoftMP3(const char *name, c2_node_id_t id,
+              const std::shared_ptr<IntfImpl> &intfImpl);
+    virtual ~C2SoftMP3();
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+    c2_status_t drain(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+
+private:
+    enum {
+        kPVMP3DecoderDelay = 529 // samples
+    };
+
+    std::shared_ptr<IntfImpl> mIntf;
+    tPVMP3DecoderExternal *mConfig;
+    void *mDecoderBuf;
+
+    bool mIsFirst;
+    bool mSignalledError;
+    bool mSignalledOutputEos;
+    bool mGaplessBytes;
+    uint64_t mAnchorTimeStamp;
+    uint64_t mProcessedSamples;
+
+    status_t initDecoder();
+
+    C2_DO_NOT_COPY(C2SoftMP3);
+};
+
+}  // namespace android
+
+#endif  // ANDROID_C2_SOFT_MP3_DEC_H_
diff --git a/media/common_time/MODULE_LICENSE_APACHE2 b/media/codec2/components/mp3/MODULE_LICENSE_APACHE2
similarity index 100%
copy from media/common_time/MODULE_LICENSE_APACHE2
copy to media/codec2/components/mp3/MODULE_LICENSE_APACHE2
diff --git a/media/common_time/NOTICE b/media/codec2/components/mp3/NOTICE
similarity index 100%
copy from media/common_time/NOTICE
copy to media/codec2/components/mp3/NOTICE
diff --git a/media/codec2/components/mp3/patent_disclaimer.txt b/media/codec2/components/mp3/patent_disclaimer.txt
new file mode 100644
index 0000000..b4bf11d
--- /dev/null
+++ b/media/codec2/components/mp3/patent_disclaimer.txt
@@ -0,0 +1,9 @@
+
+THIS IS NOT A GRANT OF PATENT RIGHTS.
+
+Google makes no representation or warranty that the codecs for which
+source code is made available hereunder are unencumbered by
+third-party patents.  Those intending to use this source code in
+hardware or software products are advised that implementations of
+these codecs, including in open source software or shareware, may
+require patent licenses from the relevant patent holders.
diff --git a/media/codec2/components/mpeg2/Android.bp b/media/codec2/components/mpeg2/Android.bp
new file mode 100644
index 0000000..841f0a9
--- /dev/null
+++ b/media/codec2/components/mpeg2/Android.bp
@@ -0,0 +1,16 @@
+cc_library_shared {
+    name: "libcodec2_soft_mpeg2dec",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_signed-defaults",
+    ],
+
+    srcs: ["C2SoftMpeg2Dec.cpp"],
+
+    static_libs: ["libmpeg2dec"],
+
+    include_dirs: [
+        "external/libmpeg2/decoder",
+        "external/libmpeg2/common",
+    ],
+}
diff --git a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
new file mode 100644
index 0000000..df7b403
--- /dev/null
+++ b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
@@ -0,0 +1,1110 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftMpeg2Dec"
+#include <log/log.h>
+
+#include <media/stagefright/foundation/MediaDefs.h>
+
+#include <C2Debug.h>
+#include <C2PlatformSupport.h>
+#include <Codec2Mapper.h>
+#include <SimpleC2Interface.h>
+
+#include "C2SoftMpeg2Dec.h"
+#include "impeg2d.h"
+
+namespace android {
+
+constexpr char COMPONENT_NAME[] = "c2.android.mpeg2.decoder";
+
+class C2SoftMpeg2Dec::IntfImpl : public SimpleInterface<void>::BaseParams {
+public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+        : SimpleInterface<void>::BaseParams(
+                helper,
+                COMPONENT_NAME,
+                C2Component::KIND_DECODER,
+                C2Component::DOMAIN_VIDEO,
+                MEDIA_MIMETYPE_VIDEO_MPEG2) {
+        noPrivateBuffers(); // TODO: account for our buffers here
+        noInputReferences();
+        noOutputReferences();
+        noInputLatency();
+        noTimeStretch();
+
+        // TODO: output latency and reordering
+
+        addParameter(
+                DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                .withConstValue(new C2ComponentAttributesSetting(C2Component::ATTRIB_IS_TEMPORAL))
+                .build());
+
+        addParameter(
+                DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
+                .withDefault(new C2StreamPictureSizeInfo::output(0u, 320, 240))
+                .withFields({
+                    C2F(mSize, width).inRange(16, 1920, 4),
+                    C2F(mSize, height).inRange(16, 1088, 4),
+                })
+                .withSetter(SizeSetter)
+                .build());
+
+        addParameter(
+                DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
+                .withDefault(new C2StreamProfileLevelInfo::input(0u,
+                        C2Config::PROFILE_MP2V_SIMPLE, C2Config::LEVEL_MP2V_HIGH))
+                .withFields({
+                    C2F(mProfileLevel, profile).oneOf({
+                            C2Config::PROFILE_MP2V_SIMPLE,
+                            C2Config::PROFILE_MP2V_MAIN}),
+                    C2F(mProfileLevel, level).oneOf({
+                            C2Config::LEVEL_MP2V_LOW,
+                            C2Config::LEVEL_MP2V_MAIN,
+                            C2Config::LEVEL_MP2V_HIGH_1440,
+                            C2Config::LEVEL_MP2V_HIGH})
+                })
+                .withSetter(ProfileLevelSetter, mSize)
+                .build());
+
+        addParameter(
+                DefineParam(mMaxSize, C2_PARAMKEY_MAX_PICTURE_SIZE)
+                .withDefault(new C2StreamMaxPictureSizeTuning::output(0u, 320, 240))
+                .withFields({
+                    C2F(mSize, width).inRange(2, 1920, 2),
+                    C2F(mSize, height).inRange(2, 1088, 2),
+                })
+                .withSetter(MaxPictureSizeSetter, mSize)
+                .build());
+
+        addParameter(
+                DefineParam(mMaxInputSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
+                .withDefault(new C2StreamMaxBufferSizeInfo::input(0u, 320 * 240 * 3 / 2))
+                .withFields({
+                    C2F(mMaxInputSize, value).any(),
+                })
+                .calculatedAs(MaxInputSizeSetter, mMaxSize)
+                .build());
+
+        C2ChromaOffsetStruct locations[1] = { C2ChromaOffsetStruct::ITU_YUV_420_0() };
+        std::shared_ptr<C2StreamColorInfo::output> defaultColorInfo =
+            C2StreamColorInfo::output::AllocShared(
+                    1u, 0u, 8u /* bitDepth */, C2Color::YUV_420);
+        memcpy(defaultColorInfo->m.locations, locations, sizeof(locations));
+
+        defaultColorInfo =
+            C2StreamColorInfo::output::AllocShared(
+                    { C2ChromaOffsetStruct::ITU_YUV_420_0() },
+                    0u, 8u /* bitDepth */, C2Color::YUV_420);
+        helper->addStructDescriptors<C2ChromaOffsetStruct>();
+
+        addParameter(
+                DefineParam(mColorInfo, C2_PARAMKEY_CODED_COLOR_INFO)
+                .withConstValue(defaultColorInfo)
+                .build());
+
+        addParameter(
+                DefineParam(mDefaultColorAspects, C2_PARAMKEY_DEFAULT_COLOR_ASPECTS)
+                .withDefault(new C2StreamColorAspectsTuning::output(
+                        0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
+                        C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+                .withFields({
+                    C2F(mDefaultColorAspects, range).inRange(
+                                C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
+                    C2F(mDefaultColorAspects, primaries).inRange(
+                                C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
+                    C2F(mDefaultColorAspects, transfer).inRange(
+                                C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER),
+                    C2F(mDefaultColorAspects, matrix).inRange(
+                                C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)
+                })
+                .withSetter(DefaultColorAspectsSetter)
+                .build());
+
+        addParameter(
+                DefineParam(mCodedColorAspects, C2_PARAMKEY_VUI_COLOR_ASPECTS)
+                .withDefault(new C2StreamColorAspectsInfo::input(
+                        0u, C2Color::RANGE_LIMITED, C2Color::PRIMARIES_UNSPECIFIED,
+                        C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+                .withFields({
+                    C2F(mCodedColorAspects, range).inRange(
+                                C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
+                    C2F(mCodedColorAspects, primaries).inRange(
+                                C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
+                    C2F(mCodedColorAspects, transfer).inRange(
+                                C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER),
+                    C2F(mCodedColorAspects, matrix).inRange(
+                                C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)
+                })
+                .withSetter(CodedColorAspectsSetter)
+                .build());
+
+        addParameter(
+                DefineParam(mColorAspects, C2_PARAMKEY_COLOR_ASPECTS)
+                .withDefault(new C2StreamColorAspectsInfo::output(
+                        0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
+                        C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+                .withFields({
+                    C2F(mColorAspects, range).inRange(
+                                C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
+                    C2F(mColorAspects, primaries).inRange(
+                                C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
+                    C2F(mColorAspects, transfer).inRange(
+                                C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER),
+                    C2F(mColorAspects, matrix).inRange(
+                                C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)
+                })
+                .withSetter(ColorAspectsSetter, mDefaultColorAspects, mCodedColorAspects)
+                .build());
+
+        // TODO: support more formats?
+        addParameter(
+                DefineParam(mPixelFormat, C2_PARAMKEY_PIXEL_FORMAT)
+                .withConstValue(new C2StreamPixelFormatInfo::output(
+                                     0u, HAL_PIXEL_FORMAT_YCBCR_420_888))
+                .build());
+    }
+
+    static C2R SizeSetter(bool mayBlock, const C2P<C2StreamPictureSizeInfo::output> &oldMe,
+                          C2P<C2StreamPictureSizeInfo::output> &me) {
+        (void)mayBlock;
+        C2R res = C2R::Ok();
+        if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
+            res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
+            me.set().width = oldMe.v.width;
+        }
+        if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
+            res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
+            me.set().height = oldMe.v.height;
+        }
+        return res;
+    }
+
+    static C2R MaxPictureSizeSetter(bool mayBlock, C2P<C2StreamMaxPictureSizeTuning::output> &me,
+                                    const C2P<C2StreamPictureSizeInfo::output> &size) {
+        (void)mayBlock;
+        // TODO: get max width/height from the size's field helpers vs. hardcoding
+        me.set().width = c2_min(c2_max(me.v.width, size.v.width), 1920u);
+        me.set().height = c2_min(c2_max(me.v.height, size.v.height), 1088u);
+        return C2R::Ok();
+    }
+
+    static C2R MaxInputSizeSetter(bool mayBlock, C2P<C2StreamMaxBufferSizeInfo::input> &me,
+                                  const C2P<C2StreamMaxPictureSizeTuning::output> &maxSize) {
+        (void)mayBlock;
+        // assume compression ratio of 1
+        me.set().value = (((maxSize.v.width + 15) / 16) * ((maxSize.v.height + 15) / 16) * 384);
+        return C2R::Ok();
+    }
+
+    static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me,
+                                  const C2P<C2StreamPictureSizeInfo::output> &size) {
+        (void)mayBlock;
+        (void)size;
+        (void)me;  // TODO: validate
+        return C2R::Ok();
+    }
+
+    static C2R DefaultColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsTuning::output> &me) {
+        (void)mayBlock;
+        if (me.v.range > C2Color::RANGE_OTHER) {
+                me.set().range = C2Color::RANGE_OTHER;
+        }
+        if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
+                me.set().primaries = C2Color::PRIMARIES_OTHER;
+        }
+        if (me.v.transfer > C2Color::TRANSFER_OTHER) {
+                me.set().transfer = C2Color::TRANSFER_OTHER;
+        }
+        if (me.v.matrix > C2Color::MATRIX_OTHER) {
+                me.set().matrix = C2Color::MATRIX_OTHER;
+        }
+        return C2R::Ok();
+    }
+
+    static C2R CodedColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::input> &me) {
+        (void)mayBlock;
+        if (me.v.range > C2Color::RANGE_OTHER) {
+                me.set().range = C2Color::RANGE_OTHER;
+        }
+        if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
+                me.set().primaries = C2Color::PRIMARIES_OTHER;
+        }
+        if (me.v.transfer > C2Color::TRANSFER_OTHER) {
+                me.set().transfer = C2Color::TRANSFER_OTHER;
+        }
+        if (me.v.matrix > C2Color::MATRIX_OTHER) {
+                me.set().matrix = C2Color::MATRIX_OTHER;
+        }
+        return C2R::Ok();
+    }
+
+    static C2R ColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::output> &me,
+                                  const C2P<C2StreamColorAspectsTuning::output> &def,
+                                  const C2P<C2StreamColorAspectsInfo::input> &coded) {
+        (void)mayBlock;
+        // take default values for all unspecified fields, and coded values for specified ones
+        me.set().range = coded.v.range == RANGE_UNSPECIFIED ? def.v.range : coded.v.range;
+        me.set().primaries = coded.v.primaries == PRIMARIES_UNSPECIFIED
+                ? def.v.primaries : coded.v.primaries;
+        me.set().transfer = coded.v.transfer == TRANSFER_UNSPECIFIED
+                ? def.v.transfer : coded.v.transfer;
+        me.set().matrix = coded.v.matrix == MATRIX_UNSPECIFIED ? def.v.matrix : coded.v.matrix;
+        return C2R::Ok();
+    }
+
+    std::shared_ptr<C2StreamColorAspectsInfo::output> getColorAspects_l() {
+        return mColorAspects;
+    }
+
+private:
+    std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
+    std::shared_ptr<C2StreamPictureSizeInfo::output> mSize;
+    std::shared_ptr<C2StreamMaxPictureSizeTuning::output> mMaxSize;
+    std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mMaxInputSize;
+    std::shared_ptr<C2StreamColorInfo::output> mColorInfo;
+    std::shared_ptr<C2StreamColorAspectsInfo::input> mCodedColorAspects;
+    std::shared_ptr<C2StreamColorAspectsTuning::output> mDefaultColorAspects;
+    std::shared_ptr<C2StreamColorAspectsInfo::output> mColorAspects;
+    std::shared_ptr<C2StreamPixelFormatInfo::output> mPixelFormat;
+};
+
+static size_t getCpuCoreCount() {
+    long cpuCoreCount = 1;
+#if defined(_SC_NPROCESSORS_ONLN)
+    cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
+#else
+    // _SC_NPROC_ONLN must be defined...
+    cpuCoreCount = sysconf(_SC_NPROC_ONLN);
+#endif
+    CHECK(cpuCoreCount >= 1);
+    ALOGV("Number of CPU cores: %ld", cpuCoreCount);
+    return (size_t)cpuCoreCount;
+}
+
+static void *ivd_aligned_malloc(WORD32 alignment, WORD32 size) {
+    return memalign(alignment, size);
+}
+
+static void ivd_aligned_free(void *mem) {
+    free(mem);
+}
+
+C2SoftMpeg2Dec::C2SoftMpeg2Dec(
+        const char *name,
+        c2_node_id_t id,
+        const std::shared_ptr<IntfImpl> &intfImpl)
+    : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+        mIntf(intfImpl),
+        mDecHandle(nullptr),
+        mMemRecords(nullptr),
+        mOutBufferDrain(nullptr),
+        mIvColorformat(IV_YUV_420P),
+        mWidth(320),
+        mHeight(240),
+        mOutIndex(0u) {
+    // If input dump is enabled, then open create an empty file
+    GENERATE_FILE_NAMES();
+    CREATE_DUMP_FILE(mInFile);
+}
+
+C2SoftMpeg2Dec::~C2SoftMpeg2Dec() {
+    onRelease();
+}
+
+c2_status_t C2SoftMpeg2Dec::onInit() {
+    status_t err = initDecoder();
+    return err == OK ? C2_OK : C2_CORRUPTED;
+}
+
+c2_status_t C2SoftMpeg2Dec::onStop() {
+    if (OK != resetDecoder()) return C2_CORRUPTED;
+    resetPlugin();
+    return C2_OK;
+}
+
+void C2SoftMpeg2Dec::onReset() {
+    (void) onStop();
+}
+
+void C2SoftMpeg2Dec::onRelease() {
+    (void) deleteDecoder();
+    if (mOutBufferDrain) {
+        ivd_aligned_free(mOutBufferDrain);
+        mOutBufferDrain = nullptr;
+    }
+    if (mOutBlock) {
+        mOutBlock.reset();
+    }
+    if (mMemRecords) {
+        ivd_aligned_free(mMemRecords);
+        mMemRecords = nullptr;
+    }
+}
+
+c2_status_t C2SoftMpeg2Dec::onFlush_sm() {
+    if (OK != setFlushMode()) return C2_CORRUPTED;
+
+    uint32_t displayStride = mStride;
+    uint32_t displayHeight = mHeight;
+    uint32_t bufferSize = displayStride * displayHeight * 3 / 2;
+    mOutBufferDrain = (uint8_t *)ivd_aligned_malloc(128, bufferSize);
+    if (!mOutBufferDrain) {
+        ALOGE("could not allocate tmp output buffer (for flush) of size %u ", bufferSize);
+        return C2_NO_MEMORY;
+    }
+
+    while (true) {
+        ivd_video_decode_ip_t s_decode_ip;
+        ivd_video_decode_op_t s_decode_op;
+
+        setDecodeArgs(&s_decode_ip, &s_decode_op, nullptr, nullptr, 0, 0, 0);
+        (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
+        if (0 == s_decode_op.u4_output_present) {
+            resetPlugin();
+            break;
+        }
+    }
+
+    if (mOutBufferDrain) {
+        ivd_aligned_free(mOutBufferDrain);
+        mOutBufferDrain = nullptr;
+    }
+
+    return C2_OK;
+}
+
+status_t C2SoftMpeg2Dec::getNumMemRecords() {
+    iv_num_mem_rec_ip_t s_num_mem_rec_ip;
+    iv_num_mem_rec_op_t s_num_mem_rec_op;
+
+    s_num_mem_rec_ip.u4_size = sizeof(s_num_mem_rec_ip);
+    s_num_mem_rec_ip.e_cmd = IV_CMD_GET_NUM_MEM_REC;
+    s_num_mem_rec_op.u4_size = sizeof(s_num_mem_rec_op);
+
+    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+                                                     &s_num_mem_rec_ip,
+                                                     &s_num_mem_rec_op);
+    if (IV_SUCCESS != status) {
+        ALOGE("Error in getting mem records: 0x%x", s_num_mem_rec_op.u4_error_code);
+        return UNKNOWN_ERROR;
+    }
+    mNumMemRecords = s_num_mem_rec_op.u4_num_mem_rec;
+
+    return OK;
+}
+
+status_t C2SoftMpeg2Dec::fillMemRecords() {
+    iv_mem_rec_t *ps_mem_rec = (iv_mem_rec_t *) ivd_aligned_malloc(
+            128, mNumMemRecords * sizeof(iv_mem_rec_t));
+    if (!ps_mem_rec) {
+        ALOGE("Allocation failure");
+        return NO_MEMORY;
+    }
+    memset(ps_mem_rec, 0, mNumMemRecords * sizeof(iv_mem_rec_t));
+    for (size_t i = 0; i < mNumMemRecords; i++)
+        ps_mem_rec[i].u4_size = sizeof(iv_mem_rec_t);
+    mMemRecords = ps_mem_rec;
+
+    ivdext_fill_mem_rec_ip_t s_fill_mem_ip;
+    ivdext_fill_mem_rec_op_t s_fill_mem_op;
+
+    s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.u4_size = sizeof(ivdext_fill_mem_rec_ip_t);
+    s_fill_mem_ip.u4_share_disp_buf = 0;
+    s_fill_mem_ip.e_output_format = mIvColorformat;
+    s_fill_mem_ip.u4_deinterlace = 1;
+    s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_FILL_NUM_MEM_REC;
+    s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location = mMemRecords;
+    s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd = mWidth;
+    s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht = mHeight;
+    s_fill_mem_op.s_ivd_fill_mem_rec_op_t.u4_size = sizeof(ivdext_fill_mem_rec_op_t);
+    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+                                                     &s_fill_mem_ip,
+                                                     &s_fill_mem_op);
+    if (IV_SUCCESS != status) {
+        ALOGE("Error in filling mem records: 0x%x",
+              s_fill_mem_op.s_ivd_fill_mem_rec_op_t.u4_error_code);
+        return UNKNOWN_ERROR;
+    }
+
+    CHECK_EQ(mNumMemRecords, s_fill_mem_op.s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled);
+    for (size_t i = 0; i < mNumMemRecords; i++, ps_mem_rec++) {
+        ps_mem_rec->pv_base = ivd_aligned_malloc(
+                ps_mem_rec->u4_mem_alignment, ps_mem_rec->u4_mem_size);
+        if (!ps_mem_rec->pv_base) {
+            ALOGE("Allocation failure for memory record #%zu of size %u",
+                  i, ps_mem_rec->u4_mem_size);
+            return NO_MEMORY;
+        }
+    }
+
+    return OK;
+}
+
+status_t C2SoftMpeg2Dec::createDecoder() {
+    ivdext_init_ip_t s_init_ip;
+    ivdext_init_op_t s_init_op;
+
+    s_init_ip.s_ivd_init_ip_t.u4_size = sizeof(ivdext_init_ip_t);
+    s_init_ip.s_ivd_init_ip_t.e_cmd = (IVD_API_COMMAND_TYPE_T)IV_CMD_INIT;
+    s_init_ip.s_ivd_init_ip_t.pv_mem_rec_location = mMemRecords;
+    s_init_ip.s_ivd_init_ip_t.u4_frm_max_wd = mWidth;
+    s_init_ip.s_ivd_init_ip_t.u4_frm_max_ht = mHeight;
+    s_init_ip.u4_share_disp_buf = 0;
+    s_init_ip.u4_deinterlace = 1;
+    s_init_ip.s_ivd_init_ip_t.u4_num_mem_rec = mNumMemRecords;
+    s_init_ip.s_ivd_init_ip_t.e_output_format = mIvColorformat;
+    s_init_op.s_ivd_init_op_t.u4_size = sizeof(ivdext_init_op_t);
+
+    mDecHandle = (iv_obj_t *)mMemRecords[0].pv_base;
+    mDecHandle->pv_fxns = (void *)ivdec_api_function;
+    mDecHandle->u4_size = sizeof(iv_obj_t);
+
+    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+                                                     &s_init_ip,
+                                                     &s_init_op);
+    if (status != IV_SUCCESS) {
+        ALOGE("error in %s: 0x%x", __func__,
+              s_init_op.s_ivd_init_op_t.u4_error_code);
+        return UNKNOWN_ERROR;
+    }
+
+    return OK;
+}
+
+status_t C2SoftMpeg2Dec::setNumCores() {
+    ivdext_ctl_set_num_cores_ip_t s_set_num_cores_ip;
+    ivdext_ctl_set_num_cores_op_t s_set_num_cores_op;
+
+    s_set_num_cores_ip.u4_size = sizeof(ivdext_ctl_set_num_cores_ip_t);
+    s_set_num_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+    s_set_num_cores_ip.e_sub_cmd = IVDEXT_CMD_CTL_SET_NUM_CORES;
+    s_set_num_cores_ip.u4_num_cores = mNumCores;
+    s_set_num_cores_op.u4_size = sizeof(ivdext_ctl_set_num_cores_op_t);
+    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+                                                     &s_set_num_cores_ip,
+                                                     &s_set_num_cores_op);
+    if (status != IV_SUCCESS) {
+        ALOGD("error in %s: 0x%x", __func__, s_set_num_cores_op.u4_error_code);
+        return UNKNOWN_ERROR;
+    }
+
+    return OK;
+}
+
+status_t C2SoftMpeg2Dec::setParams(size_t stride) {
+    ivd_ctl_set_config_ip_t s_set_dyn_params_ip;
+    ivd_ctl_set_config_op_t s_set_dyn_params_op;
+
+    s_set_dyn_params_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
+    s_set_dyn_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+    s_set_dyn_params_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+    s_set_dyn_params_ip.u4_disp_wd = (UWORD32) stride;
+    s_set_dyn_params_ip.e_frm_skip_mode = IVD_SKIP_NONE;
+    s_set_dyn_params_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+    s_set_dyn_params_ip.e_vid_dec_mode = IVD_DECODE_FRAME;
+    s_set_dyn_params_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
+    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+                                                     &s_set_dyn_params_ip,
+                                                     &s_set_dyn_params_op);
+    if (status != IV_SUCCESS) {
+        ALOGE("error in %s: 0x%x", __func__, s_set_dyn_params_op.u4_error_code);
+        return UNKNOWN_ERROR;
+    }
+
+    return OK;
+}
+
+status_t C2SoftMpeg2Dec::getVersion() {
+    ivd_ctl_getversioninfo_ip_t s_get_versioninfo_ip;
+    ivd_ctl_getversioninfo_op_t s_get_versioninfo_op;
+    UWORD8 au1_buf[512];
+
+    s_get_versioninfo_ip.u4_size = sizeof(ivd_ctl_getversioninfo_ip_t);
+    s_get_versioninfo_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+    s_get_versioninfo_ip.e_sub_cmd = IVD_CMD_CTL_GETVERSION;
+    s_get_versioninfo_ip.pv_version_buffer = au1_buf;
+    s_get_versioninfo_ip.u4_version_buffer_size = sizeof(au1_buf);
+    s_get_versioninfo_op.u4_size = sizeof(ivd_ctl_getversioninfo_op_t);
+    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+                                                     &s_get_versioninfo_ip,
+                                                     &s_get_versioninfo_op);
+    if (status != IV_SUCCESS) {
+        ALOGD("error in %s: 0x%x", __func__,
+              s_get_versioninfo_op.u4_error_code);
+    } else {
+        ALOGV("ittiam decoder version number: %s",
+              (char *) s_get_versioninfo_ip.pv_version_buffer);
+    }
+
+    return OK;
+}
+
+status_t C2SoftMpeg2Dec::initDecoder() {
+    status_t ret = getNumMemRecords();
+    if (OK != ret) return ret;
+
+    ret = fillMemRecords();
+    if (OK != ret) return ret;
+
+    if (OK != createDecoder()) return UNKNOWN_ERROR;
+
+    mNumCores = MIN(getCpuCoreCount(), MAX_NUM_CORES);
+    mStride = ALIGN64(mWidth);
+    mSignalledError = false;
+    resetPlugin();
+    (void) setNumCores();
+    if (OK != setParams(mStride)) return UNKNOWN_ERROR;
+    (void) getVersion();
+
+    return OK;
+}
+
+bool C2SoftMpeg2Dec::setDecodeArgs(ivd_video_decode_ip_t *ps_decode_ip,
+                                   ivd_video_decode_op_t *ps_decode_op,
+                                   C2ReadView *inBuffer,
+                                   C2GraphicView *outBuffer,
+                                   size_t inOffset,
+                                   size_t inSize,
+                                   uint32_t tsMarker) {
+    uint32_t displayStride = mStride;
+    uint32_t displayHeight = mHeight;
+    size_t lumaSize = displayStride * displayHeight;
+    size_t chromaSize = lumaSize >> 2;
+
+    ps_decode_ip->u4_size = sizeof(ivd_video_decode_ip_t);
+    ps_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
+    if (inBuffer) {
+        ps_decode_ip->u4_ts = tsMarker;
+        ps_decode_ip->pv_stream_buffer = const_cast<uint8_t *>(inBuffer->data() + inOffset);
+        ps_decode_ip->u4_num_Bytes = inSize;
+    } else {
+        ps_decode_ip->u4_ts = 0;
+        ps_decode_ip->pv_stream_buffer = nullptr;
+        ps_decode_ip->u4_num_Bytes = 0;
+    }
+    ps_decode_ip->s_out_buffer.u4_min_out_buf_size[0] = lumaSize;
+    ps_decode_ip->s_out_buffer.u4_min_out_buf_size[1] = chromaSize;
+    ps_decode_ip->s_out_buffer.u4_min_out_buf_size[2] = chromaSize;
+    if (outBuffer) {
+        if (outBuffer->width() < displayStride || outBuffer->height() < displayHeight) {
+            ALOGE("Output buffer too small: provided (%dx%d) required (%ux%u)",
+                  outBuffer->width(), outBuffer->height(), displayStride, displayHeight);
+            return false;
+        }
+        ps_decode_ip->s_out_buffer.pu1_bufs[0] = outBuffer->data()[C2PlanarLayout::PLANE_Y];
+        ps_decode_ip->s_out_buffer.pu1_bufs[1] = outBuffer->data()[C2PlanarLayout::PLANE_U];
+        ps_decode_ip->s_out_buffer.pu1_bufs[2] = outBuffer->data()[C2PlanarLayout::PLANE_V];
+    } else {
+        ps_decode_ip->s_out_buffer.pu1_bufs[0] = mOutBufferDrain;
+        ps_decode_ip->s_out_buffer.pu1_bufs[1] = mOutBufferDrain + lumaSize;
+        ps_decode_ip->s_out_buffer.pu1_bufs[2] = mOutBufferDrain + lumaSize + chromaSize;
+    }
+    ps_decode_ip->s_out_buffer.u4_num_bufs = 3;
+    ps_decode_op->u4_size = sizeof(ivd_video_decode_op_t);
+
+    return true;
+}
+
+
+bool C2SoftMpeg2Dec::getSeqInfo() {
+    ivdext_ctl_get_seq_info_ip_t s_ctl_get_seq_info_ip;
+    ivdext_ctl_get_seq_info_op_t s_ctl_get_seq_info_op;
+
+    s_ctl_get_seq_info_ip.u4_size = sizeof(ivdext_ctl_get_seq_info_ip_t);
+    s_ctl_get_seq_info_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+    s_ctl_get_seq_info_ip.e_sub_cmd =
+        (IVD_CONTROL_API_COMMAND_TYPE_T)IMPEG2D_CMD_CTL_GET_SEQ_INFO;
+    s_ctl_get_seq_info_op.u4_size = sizeof(ivdext_ctl_get_seq_info_op_t);
+    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+                                                     &s_ctl_get_seq_info_ip,
+                                                     &s_ctl_get_seq_info_op);
+    if (status != IV_SUCCESS) {
+        ALOGW("Error in getting Sequence info: 0x%x", s_ctl_get_seq_info_op.u4_error_code);
+        return false;
+    }
+
+    VuiColorAspects vuiColorAspects;
+    vuiColorAspects.primaries = s_ctl_get_seq_info_op.u1_colour_primaries;
+    vuiColorAspects.transfer = s_ctl_get_seq_info_op.u1_transfer_characteristics;
+    vuiColorAspects.coeffs = s_ctl_get_seq_info_op.u1_matrix_coefficients;
+    vuiColorAspects.fullRange =  false;  // mpeg2 video has limited range.
+
+    // convert vui aspects to C2 values if changed
+    if (!(vuiColorAspects == mBitstreamColorAspects)) {
+        mBitstreamColorAspects = vuiColorAspects;
+        ColorAspects sfAspects;
+        C2StreamColorAspectsInfo::input codedAspects = { 0u };
+        ColorUtils::convertIsoColorAspectsToCodecAspects(
+                vuiColorAspects.primaries, vuiColorAspects.transfer, vuiColorAspects.coeffs,
+                vuiColorAspects.fullRange, sfAspects);
+        if (!C2Mapper::map(sfAspects.mPrimaries, &codedAspects.primaries)) {
+            codedAspects.primaries = C2Color::PRIMARIES_UNSPECIFIED;
+        }
+        if (!C2Mapper::map(sfAspects.mRange, &codedAspects.range)) {
+            codedAspects.range = C2Color::RANGE_UNSPECIFIED;
+        }
+        if (!C2Mapper::map(sfAspects.mMatrixCoeffs, &codedAspects.matrix)) {
+            codedAspects.matrix = C2Color::MATRIX_UNSPECIFIED;
+        }
+        if (!C2Mapper::map(sfAspects.mTransfer, &codedAspects.transfer)) {
+            codedAspects.transfer = C2Color::TRANSFER_UNSPECIFIED;
+        }
+        std::vector<std::unique_ptr<C2SettingResult>> failures;
+        (void)mIntf->config({&codedAspects}, C2_MAY_BLOCK, &failures);
+    }
+    return true;
+}
+
+status_t C2SoftMpeg2Dec::setFlushMode() {
+    ivd_ctl_flush_ip_t s_set_flush_ip;
+    ivd_ctl_flush_op_t s_set_flush_op;
+
+    s_set_flush_ip.u4_size = sizeof(ivd_ctl_flush_ip_t);
+    s_set_flush_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+    s_set_flush_ip.e_sub_cmd = IVD_CMD_CTL_FLUSH;
+    s_set_flush_op.u4_size = sizeof(ivd_ctl_flush_op_t);
+    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+                                                     &s_set_flush_ip,
+                                                     &s_set_flush_op);
+    if (status != IV_SUCCESS) {
+        ALOGE("error in %s: 0x%x", __func__, s_set_flush_op.u4_error_code);
+        return UNKNOWN_ERROR;
+    }
+
+    return OK;
+}
+
+status_t C2SoftMpeg2Dec::resetDecoder() {
+    ivd_ctl_reset_ip_t s_reset_ip;
+    ivd_ctl_reset_op_t s_reset_op;
+
+    s_reset_ip.u4_size = sizeof(ivd_ctl_reset_ip_t);
+    s_reset_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+    s_reset_ip.e_sub_cmd = IVD_CMD_CTL_RESET;
+    s_reset_op.u4_size = sizeof(ivd_ctl_reset_op_t);
+    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+                                                     &s_reset_ip,
+                                                     &s_reset_op);
+    if (IV_SUCCESS != status) {
+        ALOGE("error in %s: 0x%x", __func__, s_reset_op.u4_error_code);
+        return UNKNOWN_ERROR;
+    }
+    (void) setNumCores();
+    mStride = 0;
+    mSignalledError = false;
+
+    return OK;
+}
+
+void C2SoftMpeg2Dec::resetPlugin() {
+    mSignalledOutputEos = false;
+    gettimeofday(&mTimeStart, nullptr);
+    gettimeofday(&mTimeEnd, nullptr);
+}
+
+status_t C2SoftMpeg2Dec::deleteDecoder() {
+    if (mMemRecords) {
+        iv_mem_rec_t *ps_mem_rec = mMemRecords;
+
+        for (size_t i = 0; i < mNumMemRecords; i++, ps_mem_rec++) {
+            if (ps_mem_rec->pv_base) {
+                ivd_aligned_free(ps_mem_rec->pv_base);
+            }
+        }
+        ivd_aligned_free(mMemRecords);
+        mMemRecords = nullptr;
+    }
+    mDecHandle = nullptr;
+
+    return OK;
+}
+
+status_t C2SoftMpeg2Dec::reInitDecoder() {
+    deleteDecoder();
+
+    status_t ret = initDecoder();
+    if (OK != ret) {
+        ALOGE("Failed to initialize decoder");
+        deleteDecoder();
+        return ret;
+    }
+    return OK;
+}
+
+void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
+    uint32_t flags = 0;
+    if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
+        flags |= C2FrameData::FLAG_END_OF_STREAM;
+        ALOGV("signalling eos");
+    }
+    work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
+    work->worklets.front()->output.buffers.clear();
+    work->worklets.front()->output.ordinal = work->input.ordinal;
+    work->workletsProcessed = 1u;
+}
+
+void C2SoftMpeg2Dec::finishWork(uint64_t index, const std::unique_ptr<C2Work> &work) {
+    std::shared_ptr<C2Buffer> buffer = createGraphicBuffer(std::move(mOutBlock),
+                                                           C2Rect(mWidth, mHeight));
+    mOutBlock = nullptr;
+    {
+        IntfImpl::Lock lock = mIntf->lock();
+        buffer->setInfo(mIntf->getColorAspects_l());
+    }
+
+    class FillWork {
+       public:
+        FillWork(uint32_t flags, C2WorkOrdinalStruct ordinal,
+                 const std::shared_ptr<C2Buffer>& buffer)
+            : mFlags(flags), mOrdinal(ordinal), mBuffer(buffer) {}
+        ~FillWork() = default;
+
+        void operator()(const std::unique_ptr<C2Work>& work) {
+            work->worklets.front()->output.flags = (C2FrameData::flags_t)mFlags;
+            work->worklets.front()->output.buffers.clear();
+            work->worklets.front()->output.ordinal = mOrdinal;
+            work->workletsProcessed = 1u;
+            work->result = C2_OK;
+            if (mBuffer) {
+                work->worklets.front()->output.buffers.push_back(mBuffer);
+            }
+            ALOGV("timestamp = %lld, index = %lld, w/%s buffer",
+                  mOrdinal.timestamp.peekll(), mOrdinal.frameIndex.peekll(),
+                  mBuffer ? "" : "o");
+        }
+
+       private:
+        const uint32_t mFlags;
+        const C2WorkOrdinalStruct mOrdinal;
+        const std::shared_ptr<C2Buffer> mBuffer;
+    };
+
+    auto fillWork = [buffer](const std::unique_ptr<C2Work> &work) {
+        work->worklets.front()->output.flags = (C2FrameData::flags_t)0;
+        work->worklets.front()->output.buffers.clear();
+        work->worklets.front()->output.buffers.push_back(buffer);
+        work->worklets.front()->output.ordinal = work->input.ordinal;
+        work->workletsProcessed = 1u;
+    };
+    if (work && c2_cntr64_t(index) == work->input.ordinal.frameIndex) {
+        bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
+        // TODO: Check if cloneAndSend can be avoided by tracking number of frames remaining
+        if (eos) {
+            if (buffer) {
+                mOutIndex = index;
+                C2WorkOrdinalStruct outOrdinal = work->input.ordinal;
+                cloneAndSend(
+                    mOutIndex, work,
+                    FillWork(C2FrameData::FLAG_INCOMPLETE, outOrdinal, buffer));
+                buffer.reset();
+            }
+        } else {
+            fillWork(work);
+        }
+    } else {
+        finish(index, fillWork);
+    }
+}
+
+c2_status_t C2SoftMpeg2Dec::ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool) {
+    if (!mDecHandle) {
+        ALOGE("not supposed to be here, invalid decoder context");
+        return C2_CORRUPTED;
+    }
+    if (mStride != ALIGN64(mWidth)) {
+        mStride = ALIGN64(mWidth);
+        if (OK != setParams(mStride)) return C2_CORRUPTED;
+    }
+    if (mOutBlock &&
+            (mOutBlock->width() != mStride || mOutBlock->height() != mHeight)) {
+        mOutBlock.reset();
+    }
+    if (!mOutBlock) {
+        uint32_t format = HAL_PIXEL_FORMAT_YV12;
+        C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+        c2_status_t err = pool->fetchGraphicBlock(mStride, mHeight, format, usage, &mOutBlock);
+        if (err != C2_OK) {
+            ALOGE("fetchGraphicBlock for Output failed with status %d", err);
+            return err;
+        }
+        ALOGV("provided (%dx%d) required (%dx%d)",
+              mOutBlock->width(), mOutBlock->height(), mStride, mHeight);
+    }
+
+    return C2_OK;
+}
+
+// TODO: can overall error checking be improved?
+// TODO: allow configuration of color format and usage for graphic buffers instead
+//       of hard coding them to HAL_PIXEL_FORMAT_YV12
+// TODO: pass coloraspects information to surface
+// TODO: test support for dynamic change in resolution
+// TODO: verify if the decoder sent back all frames
+void C2SoftMpeg2Dec::process(
+        const std::unique_ptr<C2Work> &work,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    // Initialize output work
+    work->result = C2_OK;
+    work->workletsProcessed = 0u;
+    work->worklets.front()->output.configUpdate.clear();
+    work->worklets.front()->output.flags = work->input.flags;
+
+    if (mSignalledError || mSignalledOutputEos) {
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+
+    size_t inOffset = 0u;
+    size_t inSize = 0u;
+    uint32_t workIndex = work->input.ordinal.frameIndex.peeku() & 0xFFFFFFFF;
+    C2ReadView rView = mDummyReadView;
+    if (!work->input.buffers.empty()) {
+        rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
+        inSize = rView.capacity();
+        if (inSize && rView.error()) {
+            ALOGE("read view map failed %d", rView.error());
+            work->result = C2_CORRUPTED;
+            return;
+        }
+    }
+    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
+    bool hasPicture = false;
+
+    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
+          inSize, (int)work->input.ordinal.timestamp.peeku(),
+          (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
+    size_t inPos = 0;
+    while (inPos < inSize) {
+        if (C2_OK != ensureDecoderState(pool)) {
+            mSignalledError = true;
+            work->workletsProcessed = 1u;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+        C2GraphicView wView = mOutBlock->map().get();
+        if (wView.error()) {
+            ALOGE("graphic view map failed %d", wView.error());
+            work->result = C2_CORRUPTED;
+            return;
+        }
+
+        ivd_video_decode_ip_t s_decode_ip;
+        ivd_video_decode_op_t s_decode_op;
+        if (!setDecodeArgs(&s_decode_ip, &s_decode_op, &rView, &wView,
+                           inOffset + inPos, inSize - inPos, workIndex)) {
+            mSignalledError = true;
+            work->workletsProcessed = 1u;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+        // If input dump is enabled, then write to file
+        DUMP_TO_FILE(mInFile, s_decode_ip.pv_stream_buffer, s_decode_ip.u4_num_Bytes);
+        WORD32 delay;
+        GETTIME(&mTimeStart, nullptr);
+        TIME_DIFF(mTimeEnd, mTimeStart, delay);
+        (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
+        WORD32 decodeTime;
+        GETTIME(&mTimeEnd, nullptr);
+        TIME_DIFF(mTimeStart, mTimeEnd, decodeTime);
+        ALOGV("decodeTime=%6d delay=%6d numBytes=%6d ", decodeTime, delay,
+              s_decode_op.u4_num_bytes_consumed);
+        if (IMPEG2D_UNSUPPORTED_DIMENSIONS == s_decode_op.u4_error_code) {
+            ALOGV("unsupported resolution : %dx%d", s_decode_op.u4_pic_wd, s_decode_op.u4_pic_ht);
+            drainInternal(DRAIN_COMPONENT_NO_EOS, pool, work);
+            resetPlugin();
+            work->workletsProcessed = 0u;
+            mWidth = s_decode_op.u4_pic_wd;
+            mHeight = s_decode_op.u4_pic_ht;
+
+            ALOGI("Configuring decoder: mWidth %d , mHeight %d ",
+                   mWidth, mHeight);
+            C2StreamPictureSizeInfo::output size(0u, mWidth, mHeight);
+            std::vector<std::unique_ptr<C2SettingResult>> failures;
+            c2_status_t err =
+                mIntf->config({&size}, C2_MAY_BLOCK, &failures);
+            if (err == OK) {
+                work->worklets.front()->output.configUpdate.push_back(
+                    C2Param::Copy(size));
+            } else {
+                ALOGE("Cannot set width and height");
+                mSignalledError = true;
+                work->workletsProcessed = 1u;
+                work->result = C2_CORRUPTED;
+                return;
+            }
+
+            if (OK != reInitDecoder()) {
+                ALOGE("Failed to reinitialize decoder");
+                mSignalledError = true;
+                work->workletsProcessed = 1u;
+                work->result = C2_CORRUPTED;
+                return;
+            }
+            continue;
+        } else if (IVD_RES_CHANGED == (s_decode_op.u4_error_code & 0xFF)) {
+            ALOGV("resolution changed");
+            drainInternal(DRAIN_COMPONENT_NO_EOS, pool, work);
+            resetDecoder();
+            resetPlugin();
+            work->workletsProcessed = 0u;
+            continue;
+        }
+        if (0 < s_decode_op.u4_pic_wd && 0 < s_decode_op.u4_pic_ht) {
+            if (s_decode_op.u4_pic_wd != mWidth ||  s_decode_op.u4_pic_ht != mHeight) {
+                mWidth = s_decode_op.u4_pic_wd;
+                mHeight = s_decode_op.u4_pic_ht;
+                CHECK_EQ(0u, s_decode_op.u4_output_present);
+
+                ALOGI("Configuring decoder out: mWidth %d , mHeight %d ",
+                       mWidth, mHeight);
+                C2StreamPictureSizeInfo::output size(0u, mWidth, mHeight);
+                std::vector<std::unique_ptr<C2SettingResult>> failures;
+                c2_status_t err =
+                    mIntf->config({&size}, C2_MAY_BLOCK, &failures);
+                if (err == OK) {
+                    work->worklets.front()->output.configUpdate.push_back(
+                        C2Param::Copy(size));
+                } else {
+                    ALOGE("Cannot set width and height");
+                    mSignalledError = true;
+                    work->workletsProcessed = 1u;
+                    work->result = C2_CORRUPTED;
+                    return;
+                }
+            }
+        }
+
+        (void) getSeqInfo();
+        hasPicture |= (1 == s_decode_op.u4_frame_decoded_flag);
+        if (s_decode_op.u4_output_present) {
+            finishWork(s_decode_op.u4_ts, work);
+        }
+
+        inPos += s_decode_op.u4_num_bytes_consumed;
+        if (hasPicture && (inSize - inPos) != 0) {
+            ALOGD("decoded frame in current access nal, ignoring further trailing bytes %d",
+                  (int)inSize - (int)inPos);
+            break;
+        }
+    }
+
+    if (eos) {
+        drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
+        mSignalledOutputEos = true;
+    } else if (!hasPicture) {
+        fillEmptyWork(work);
+    }
+}
+
+c2_status_t C2SoftMpeg2Dec::drainInternal(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool,
+        const std::unique_ptr<C2Work> &work) {
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+
+    if (OK != setFlushMode()) return C2_CORRUPTED;
+    while (true) {
+        if (C2_OK != ensureDecoderState(pool)) {
+            mSignalledError = true;
+            work->workletsProcessed = 1u;
+            work->result = C2_CORRUPTED;
+            return C2_CORRUPTED;
+        }
+        C2GraphicView wView = mOutBlock->map().get();
+        if (wView.error()) {
+            ALOGE("graphic view map failed %d", wView.error());
+            return C2_CORRUPTED;
+        }
+        ivd_video_decode_ip_t s_decode_ip;
+        ivd_video_decode_op_t s_decode_op;
+        if (!setDecodeArgs(&s_decode_ip, &s_decode_op, nullptr, &wView, 0, 0, 0)) {
+            mSignalledError = true;
+            work->workletsProcessed = 1u;
+            return C2_CORRUPTED;
+        }
+        (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
+        if (s_decode_op.u4_output_present) {
+            finishWork(s_decode_op.u4_ts, work);
+        } else {
+            fillEmptyWork(work);
+            break;
+        }
+    }
+
+    return C2_OK;
+}
+
+c2_status_t C2SoftMpeg2Dec::drain(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    return drainInternal(drainMode, pool, nullptr);
+}
+
+class C2SoftMpeg2DecFactory : public C2ComponentFactory {
+public:
+    C2SoftMpeg2DecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+            GetCodec2PlatformComponentStore()->getParamReflector())) {
+    }
+
+    virtual c2_status_t createComponent(
+            c2_node_id_t id,
+            std::shared_ptr<C2Component>* const component,
+            std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+                new C2SoftMpeg2Dec(COMPONENT_NAME,
+                                   id,
+                                   std::make_shared<C2SoftMpeg2Dec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+            c2_node_id_t id,
+            std::shared_ptr<C2ComponentInterface>* const interface,
+            std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+                new SimpleInterface<C2SoftMpeg2Dec::IntfImpl>(
+                        COMPONENT_NAME, id, std::make_shared<C2SoftMpeg2Dec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftMpeg2DecFactory() override = default;
+
+private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftMpeg2DecFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h
new file mode 100644
index 0000000..65d3b87
--- /dev/null
+++ b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_MPEG2_DEC_H_
+#define ANDROID_C2_SOFT_MPEG2_DEC_H_
+
+#include <atomic>
+#include <SimpleC2Component.h>
+
+#include <media/stagefright/foundation/ColorUtils.h>
+
+#include "iv_datatypedef.h"
+#include "iv.h"
+#include "ivd.h"
+
+namespace android {
+
+#define ivdec_api_function              impeg2d_api_function
+#define ivdext_init_ip_t                impeg2d_init_ip_t
+#define ivdext_init_op_t                impeg2d_init_op_t
+#define ivdext_fill_mem_rec_ip_t        impeg2d_fill_mem_rec_ip_t
+#define ivdext_fill_mem_rec_op_t        impeg2d_fill_mem_rec_op_t
+#define ivdext_ctl_set_num_cores_ip_t   impeg2d_ctl_set_num_cores_ip_t
+#define ivdext_ctl_set_num_cores_op_t   impeg2d_ctl_set_num_cores_op_t
+#define ivdext_ctl_get_seq_info_ip_t    impeg2d_ctl_get_seq_info_ip_t
+#define ivdext_ctl_get_seq_info_op_t    impeg2d_ctl_get_seq_info_op_t
+#define ALIGN64(x)                      ((((x) + 63) >> 6) << 6)
+#define MAX_NUM_CORES                   4
+#define IVDEXT_CMD_CTL_SET_NUM_CORES    \
+        (IVD_CONTROL_API_COMMAND_TYPE_T)IMPEG2D_CMD_CTL_SET_NUM_CORES
+#define MIN(a, b)                       (((a) < (b)) ? (a) : (b))
+#define GETTIME(a, b)                   gettimeofday(a, b);
+#define TIME_DIFF(start, end, diff)     \
+    diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \
+            ((end).tv_usec - (start).tv_usec);
+
+#ifdef FILE_DUMP_ENABLE
+    #define INPUT_DUMP_PATH     "/sdcard/clips/mpeg2d_input"
+    #define INPUT_DUMP_EXT      "m2v"
+    #define GENERATE_FILE_NAMES() {                         \
+        GETTIME(&mTimeStart, NULL);                         \
+        strcpy(mInFile, "");                                \
+        sprintf(mInFile, "%s_%ld.%ld.%s", INPUT_DUMP_PATH,  \
+                mTimeStart.tv_sec, mTimeStart.tv_usec,      \
+                INPUT_DUMP_EXT);                            \
+    }
+    #define CREATE_DUMP_FILE(m_filename) {                  \
+        FILE *fp = fopen(m_filename, "wb");                 \
+        if (fp != NULL) {                                   \
+            fclose(fp);                                     \
+        } else {                                            \
+            ALOGD("Could not open file %s", m_filename);    \
+        }                                                   \
+    }
+    #define DUMP_TO_FILE(m_filename, m_buf, m_size)         \
+    {                                                       \
+        FILE *fp = fopen(m_filename, "ab");                 \
+        if (fp != NULL && m_buf != NULL) {                  \
+            uint32_t i;                                     \
+            i = fwrite(m_buf, 1, m_size, fp);               \
+            ALOGD("fwrite ret %d to write %d", i, m_size);  \
+            if (i != (uint32_t)m_size) {                    \
+                ALOGD("Error in fwrite, returned %d", i);   \
+                perror("Error in write to file");           \
+            }                                               \
+            fclose(fp);                                     \
+        } else {                                            \
+            ALOGD("Could not write to file %s", m_filename);\
+        }                                                   \
+    }
+#else /* FILE_DUMP_ENABLE */
+    #define INPUT_DUMP_PATH
+    #define INPUT_DUMP_EXT
+    #define OUTPUT_DUMP_PATH
+    #define OUTPUT_DUMP_EXT
+    #define GENERATE_FILE_NAMES()
+    #define CREATE_DUMP_FILE(m_filename)
+    #define DUMP_TO_FILE(m_filename, m_buf, m_size)
+#endif /* FILE_DUMP_ENABLE */
+
+struct C2SoftMpeg2Dec : public SimpleC2Component {
+    class IntfImpl;
+
+    C2SoftMpeg2Dec(const char* name, c2_node_id_t id,
+                   const std::shared_ptr<IntfImpl>& intfImpl);
+    virtual ~C2SoftMpeg2Dec();
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+    c2_status_t drain(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+ private:
+    status_t getNumMemRecords();
+    status_t fillMemRecords();
+    status_t createDecoder();
+    status_t setNumCores();
+    status_t setParams(size_t stride);
+    status_t getVersion();
+    status_t initDecoder();
+    bool setDecodeArgs(ivd_video_decode_ip_t *ps_decode_ip,
+                       ivd_video_decode_op_t *ps_decode_op,
+                       C2ReadView *inBuffer,
+                       C2GraphicView *outBuffer,
+                       size_t inOffset,
+                       size_t inSize,
+                       uint32_t tsMarker);
+    bool getSeqInfo();
+    c2_status_t ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool);
+    void finishWork(uint64_t index, const std::unique_ptr<C2Work> &work);
+    status_t setFlushMode();
+    c2_status_t drainInternal(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool,
+            const std::unique_ptr<C2Work> &work);
+    status_t resetDecoder();
+    void resetPlugin();
+    status_t deleteDecoder();
+    status_t reInitDecoder();
+
+    // TODO:This is not the right place for this enum. These should
+    // be part of c2-vndk so that they can be accessed by all video plugins
+    // until then, make them feel at home
+    enum {
+        kNotSupported,
+        kPreferBitstream,
+        kPreferContainer,
+    };
+
+    std::shared_ptr<IntfImpl> mIntf;
+    iv_obj_t *mDecHandle;
+    iv_mem_rec_t *mMemRecords;
+    size_t mNumMemRecords;
+    std::shared_ptr<C2GraphicBlock> mOutBlock;
+    uint8_t *mOutBufferDrain;
+
+    size_t mNumCores;
+    IV_COLOR_FORMAT_T mIvColorformat;
+
+    uint32_t mWidth;
+    uint32_t mHeight;
+    uint32_t mStride;
+    bool mSignalledOutputEos;
+    bool mSignalledError;
+    std::atomic_uint64_t mOutIndex;
+
+    // Color aspects. These are ISO values and are meant to detect changes in aspects to avoid
+    // converting them to C2 values for each frame
+    struct VuiColorAspects {
+        uint8_t primaries;
+        uint8_t transfer;
+        uint8_t coeffs;
+        uint8_t fullRange;
+
+        // default color aspects
+        VuiColorAspects()
+            : primaries(2), transfer(2), coeffs(2), fullRange(0) { }
+
+        bool operator==(const VuiColorAspects &o) {
+            return primaries == o.primaries && transfer == o.transfer && coeffs == o.coeffs
+                    && fullRange == o.fullRange;
+        }
+    } mBitstreamColorAspects;
+
+    // profile
+    struct timeval mTimeStart;
+    struct timeval mTimeEnd;
+#ifdef FILE_DUMP_ENABLE
+    char mInFile[200];
+#endif /* FILE_DUMP_ENABLE */
+
+    C2_DO_NOT_COPY(C2SoftMpeg2Dec);
+};
+
+}  // namespace android
+
+#endif  // ANDROID_C2_SOFT_MPEG2_DEC_H_
diff --git a/media/codec2/components/mpeg4_h263/Android.bp b/media/codec2/components/mpeg4_h263/Android.bp
new file mode 100644
index 0000000..41e4f44
--- /dev/null
+++ b/media/codec2/components/mpeg4_h263/Android.bp
@@ -0,0 +1,66 @@
+cc_library_shared {
+    name: "libcodec2_soft_mpeg4dec",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_signed-defaults",
+    ],
+
+    srcs: ["C2SoftMpeg4Dec.cpp"],
+
+    static_libs: ["libstagefright_m4vh263dec"],
+
+    cflags: [
+        "-DOSCL_IMPORT_REF=",
+        "-DMPEG4",
+    ],
+}
+
+cc_library_shared {
+    name: "libcodec2_soft_h263dec",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_signed-defaults",
+    ],
+
+    srcs: ["C2SoftMpeg4Dec.cpp"],
+
+    static_libs: ["libstagefright_m4vh263dec"],
+
+    cflags: [
+        "-DOSCL_IMPORT_REF=",
+    ],
+}
+
+cc_library_shared {
+    name: "libcodec2_soft_mpeg4enc",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_signed-defaults",
+    ],
+
+
+    srcs: ["C2SoftMpeg4Enc.cpp"],
+
+    static_libs: ["libstagefright_m4vh263enc"],
+
+    cflags: [
+        "-DMPEG4",
+        "-DOSCL_IMPORT_REF=",
+    ],
+}
+
+cc_library_shared {
+    name: "libcodec2_soft_h263enc",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_signed-defaults",
+    ],
+
+    srcs: ["C2SoftMpeg4Enc.cpp"],
+
+    static_libs: [ "libstagefright_m4vh263enc" ],
+
+    cflags: [
+        "-DOSCL_IMPORT_REF=",
+    ],
+}
diff --git a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp
new file mode 100644
index 0000000..7e6685e
--- /dev/null
+++ b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp
@@ -0,0 +1,758 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#ifdef MPEG4
+  #define LOG_TAG "C2SoftMpeg4Dec"
+#else
+  #define LOG_TAG "C2SoftH263Dec"
+#endif
+#include <log/log.h>
+
+#include <media/stagefright/foundation/AUtils.h>
+#include <media/stagefright/foundation/MediaDefs.h>
+
+#include <C2Debug.h>
+#include <C2PlatformSupport.h>
+#include <SimpleC2Interface.h>
+
+#include "C2SoftMpeg4Dec.h"
+#include "mp4dec_api.h"
+
+namespace android {
+
+#ifdef MPEG4
+constexpr char COMPONENT_NAME[] = "c2.android.mpeg4.decoder";
+#else
+constexpr char COMPONENT_NAME[] = "c2.android.h263.decoder";
+#endif
+
+class C2SoftMpeg4Dec::IntfImpl : public SimpleInterface<void>::BaseParams {
+public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+        : SimpleInterface<void>::BaseParams(
+                helper,
+                COMPONENT_NAME,
+                C2Component::KIND_DECODER,
+                C2Component::DOMAIN_VIDEO,
+#ifdef MPEG4
+                MEDIA_MIMETYPE_VIDEO_MPEG4
+#else
+                MEDIA_MIMETYPE_VIDEO_H263
+#endif
+                ) {
+        noPrivateBuffers(); // TODO: account for our buffers here
+        noInputReferences();
+        noOutputReferences();
+        noInputLatency();
+        noTimeStretch();
+
+        // TODO: Proper support for reorder depth.
+        addParameter(
+                DefineParam(mActualOutputDelay, C2_PARAMKEY_OUTPUT_DELAY)
+                .withConstValue(new C2PortActualDelayTuning::output(1u))
+                .build());
+
+        addParameter(
+                DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                .withConstValue(new C2ComponentAttributesSetting(C2Component::ATTRIB_IS_TEMPORAL))
+                .build());
+
+        addParameter(
+                DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
+                .withDefault(new C2StreamPictureSizeInfo::output(0u, 176, 144))
+                .withFields({
+#ifdef MPEG4
+                    C2F(mSize, width).inRange(2, 1920, 2),
+                    C2F(mSize, height).inRange(2, 1088, 2),
+#else
+                    C2F(mSize, width).inRange(2, 352, 2),
+                    C2F(mSize, height).inRange(2, 288, 2),
+#endif
+                })
+                .withSetter(SizeSetter)
+                .build());
+
+#ifdef MPEG4
+        addParameter(
+                DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
+                .withDefault(new C2StreamProfileLevelInfo::input(0u,
+                        C2Config::PROFILE_MP4V_SIMPLE, C2Config::LEVEL_MP4V_3))
+                .withFields({
+                    C2F(mProfileLevel, profile).equalTo(
+                            C2Config::PROFILE_MP4V_SIMPLE),
+                    C2F(mProfileLevel, level).oneOf({
+                            C2Config::LEVEL_MP4V_0,
+                            C2Config::LEVEL_MP4V_0B,
+                            C2Config::LEVEL_MP4V_1,
+                            C2Config::LEVEL_MP4V_2,
+                            C2Config::LEVEL_MP4V_3,
+                            C2Config::LEVEL_MP4V_3B,
+                            C2Config::LEVEL_MP4V_4,
+                            C2Config::LEVEL_MP4V_4A,
+                            C2Config::LEVEL_MP4V_5,
+                            C2Config::LEVEL_MP4V_6})
+                })
+                .withSetter(ProfileLevelSetter, mSize)
+                .build());
+#else
+        addParameter(
+                DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
+                .withDefault(new C2StreamProfileLevelInfo::input(0u,
+                        C2Config::PROFILE_H263_BASELINE, C2Config::LEVEL_H263_30))
+                .withFields({
+                    C2F(mProfileLevel, profile).oneOf({
+                            C2Config::PROFILE_H263_BASELINE,
+                            C2Config::PROFILE_H263_ISWV2}),
+                    C2F(mProfileLevel, level).oneOf({
+                            C2Config::LEVEL_H263_10,
+                            C2Config::LEVEL_H263_20,
+                            C2Config::LEVEL_H263_30,
+                            C2Config::LEVEL_H263_40,
+                            C2Config::LEVEL_H263_45})
+                })
+                .withSetter(ProfileLevelSetter, mSize)
+                .build());
+#endif
+
+        addParameter(
+                DefineParam(mMaxSize, C2_PARAMKEY_MAX_PICTURE_SIZE)
+#ifdef MPEG4
+                .withDefault(new C2StreamMaxPictureSizeTuning::output(0u, 1920, 1088))
+#else
+                .withDefault(new C2StreamMaxPictureSizeTuning::output(0u, 352, 288))
+#endif
+                .withFields({
+#ifdef MPEG4
+                    C2F(mSize, width).inRange(2, 1920, 2),
+                    C2F(mSize, height).inRange(2, 1088, 2),
+#else
+                    C2F(mSize, width).inRange(2, 352, 2),
+                    C2F(mSize, height).inRange(2, 288, 2),
+#endif
+                })
+                .withSetter(MaxPictureSizeSetter, mSize)
+                .build());
+
+        addParameter(
+                DefineParam(mMaxInputSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
+#ifdef MPEG4
+                .withDefault(new C2StreamMaxBufferSizeInfo::input(0u, 1920 * 1088 * 3 / 2))
+#else
+                .withDefault(new C2StreamMaxBufferSizeInfo::input(0u, 352 * 288 * 3 / 2))
+#endif
+                .withFields({
+                    C2F(mMaxInputSize, value).any(),
+                })
+                .calculatedAs(MaxInputSizeSetter, mMaxSize)
+                .build());
+
+        C2ChromaOffsetStruct locations[1] = { C2ChromaOffsetStruct::ITU_YUV_420_0() };
+        std::shared_ptr<C2StreamColorInfo::output> defaultColorInfo =
+            C2StreamColorInfo::output::AllocShared(
+                    1u, 0u, 8u /* bitDepth */, C2Color::YUV_420);
+        memcpy(defaultColorInfo->m.locations, locations, sizeof(locations));
+
+        defaultColorInfo =
+            C2StreamColorInfo::output::AllocShared(
+                    { C2ChromaOffsetStruct::ITU_YUV_420_0() },
+                    0u, 8u /* bitDepth */, C2Color::YUV_420);
+        helper->addStructDescriptors<C2ChromaOffsetStruct>();
+
+        addParameter(
+                DefineParam(mColorInfo, C2_PARAMKEY_CODED_COLOR_INFO)
+                .withConstValue(defaultColorInfo)
+                .build());
+
+        // TODO: support more formats?
+        addParameter(
+                DefineParam(mPixelFormat, C2_PARAMKEY_PIXEL_FORMAT)
+                .withConstValue(new C2StreamPixelFormatInfo::output(
+                                     0u, HAL_PIXEL_FORMAT_YCBCR_420_888))
+                .build());
+    }
+
+    static C2R SizeSetter(bool mayBlock, const C2P<C2StreamPictureSizeInfo::output> &oldMe,
+                          C2P<C2StreamPictureSizeInfo::output> &me) {
+        (void)mayBlock;
+        C2R res = C2R::Ok();
+        if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
+            res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
+            me.set().width = oldMe.v.width;
+        }
+        if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
+            res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
+            me.set().height = oldMe.v.height;
+        }
+        return res;
+    }
+
+    static C2R MaxPictureSizeSetter(bool mayBlock, C2P<C2StreamMaxPictureSizeTuning::output> &me,
+                                    const C2P<C2StreamPictureSizeInfo::output> &size) {
+        (void)mayBlock;
+        // TODO: get max width/height from the size's field helpers vs. hardcoding
+#ifdef MPEG4
+        me.set().width = c2_min(c2_max(me.v.width, size.v.width), 1920u);
+        me.set().height = c2_min(c2_max(me.v.height, size.v.height), 1088u);
+#else
+        me.set().width = c2_min(c2_max(me.v.width, size.v.width), 352u);
+        me.set().height = c2_min(c2_max(me.v.height, size.v.height), 288u);
+#endif
+        return C2R::Ok();
+    }
+
+    static C2R MaxInputSizeSetter(bool mayBlock, C2P<C2StreamMaxBufferSizeInfo::input> &me,
+                                  const C2P<C2StreamMaxPictureSizeTuning::output> &maxSize) {
+        (void)mayBlock;
+        // assume compression ratio of 1
+        me.set().value = (((maxSize.v.width + 15) / 16) * ((maxSize.v.height + 15) / 16) * 384);
+        return C2R::Ok();
+    }
+
+    static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me,
+                                  const C2P<C2StreamPictureSizeInfo::output> &size) {
+        (void)mayBlock;
+        (void)size;
+        (void)me;  // TODO: validate
+        return C2R::Ok();
+    }
+
+    uint32_t getMaxWidth() const { return mMaxSize->width; }
+    uint32_t getMaxHeight() const { return mMaxSize->height; }
+
+private:
+    std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
+    std::shared_ptr<C2StreamPictureSizeInfo::output> mSize;
+    std::shared_ptr<C2StreamMaxPictureSizeTuning::output> mMaxSize;
+    std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mMaxInputSize;
+    std::shared_ptr<C2StreamColorInfo::output> mColorInfo;
+    std::shared_ptr<C2StreamPixelFormatInfo::output> mPixelFormat;
+};
+
+C2SoftMpeg4Dec::C2SoftMpeg4Dec(
+        const char *name,
+        c2_node_id_t id,
+        const std::shared_ptr<IntfImpl> &intfImpl)
+    : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+      mIntf(intfImpl),
+      mDecHandle(nullptr),
+      mOutputBuffer{},
+      mInitialized(false) {
+}
+
+C2SoftMpeg4Dec::~C2SoftMpeg4Dec() {
+    onRelease();
+}
+
+c2_status_t C2SoftMpeg4Dec::onInit() {
+    status_t err = initDecoder();
+    return err == OK ? C2_OK : C2_CORRUPTED;
+}
+
+c2_status_t C2SoftMpeg4Dec::onStop() {
+    if (mInitialized) {
+        if (mDecHandle) {
+            PVCleanUpVideoDecoder(mDecHandle);
+        }
+        mInitialized = false;
+    }
+    for (int32_t i = 0; i < kNumOutputBuffers; ++i) {
+        if (mOutputBuffer[i]) {
+            free(mOutputBuffer[i]);
+            mOutputBuffer[i] = nullptr;
+        }
+    }
+    mNumSamplesOutput = 0;
+    mFramesConfigured = false;
+    mSignalledOutputEos = false;
+    mSignalledError = false;
+
+    return C2_OK;
+}
+
+void C2SoftMpeg4Dec::onReset() {
+    (void)onStop();
+    (void)onInit();
+}
+
+void C2SoftMpeg4Dec::onRelease() {
+    if (mInitialized) {
+        if (mDecHandle) {
+            PVCleanUpVideoDecoder(mDecHandle);
+            delete mDecHandle;
+            mDecHandle = nullptr;
+        }
+        mInitialized = false;
+    }
+    if (mOutBlock) {
+        mOutBlock.reset();
+    }
+    for (int32_t i = 0; i < kNumOutputBuffers; ++i) {
+        if (mOutputBuffer[i]) {
+            free(mOutputBuffer[i]);
+            mOutputBuffer[i] = nullptr;
+        }
+    }
+}
+
+c2_status_t C2SoftMpeg4Dec::onFlush_sm() {
+    if (mInitialized) {
+        if (PV_TRUE != PVResetVideoDecoder(mDecHandle)) {
+            return C2_CORRUPTED;
+        }
+    }
+    mSignalledOutputEos = false;
+    mSignalledError = false;
+    return C2_OK;
+}
+
+status_t C2SoftMpeg4Dec::initDecoder() {
+#ifdef MPEG4
+    mIsMpeg4 = true;
+#else
+    mIsMpeg4 = false;
+#endif
+    if (!mDecHandle) {
+        mDecHandle = new tagvideoDecControls;
+    }
+    if (!mDecHandle) {
+        ALOGE("mDecHandle is null");
+        return NO_MEMORY;
+    }
+    memset(mDecHandle, 0, sizeof(tagvideoDecControls));
+
+    /* TODO: bring these values to 352 and 288. It cannot be done as of now
+     * because, h263 doesn't seem to allow port reconfiguration. In OMX, the
+     * problem of larger width and height than default width and height is
+     * overcome by adaptivePlayBack() api call. This call gets width and height
+     * information from extractor. Such a thing is not possible here.
+     * So we are configuring to larger values.*/
+    mWidth = 1408;
+    mHeight = 1152;
+    mNumSamplesOutput = 0;
+    mInitialized = false;
+    mFramesConfigured = false;
+    mSignalledOutputEos = false;
+    mSignalledError = false;
+
+    return OK;
+}
+
+void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
+    uint32_t flags = 0;
+    if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
+        flags |= C2FrameData::FLAG_END_OF_STREAM;
+        ALOGV("signalling eos");
+    }
+    work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
+    work->worklets.front()->output.buffers.clear();
+    work->worklets.front()->output.ordinal = work->input.ordinal;
+    work->workletsProcessed = 1u;
+}
+
+void C2SoftMpeg4Dec::finishWork(uint64_t index, const std::unique_ptr<C2Work> &work) {
+    std::shared_ptr<C2Buffer> buffer = createGraphicBuffer(std::move(mOutBlock),
+                                                           C2Rect(mWidth, mHeight));
+    mOutBlock = nullptr;
+    auto fillWork = [buffer, index](const std::unique_ptr<C2Work> &work) {
+        uint32_t flags = 0;
+        if ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) &&
+                (c2_cntr64_t(index) == work->input.ordinal.frameIndex)) {
+            flags |= C2FrameData::FLAG_END_OF_STREAM;
+            ALOGV("signalling eos");
+        }
+        work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
+        work->worklets.front()->output.buffers.clear();
+        work->worklets.front()->output.buffers.push_back(buffer);
+        work->worklets.front()->output.ordinal = work->input.ordinal;
+        work->workletsProcessed = 1u;
+    };
+    if (work && c2_cntr64_t(index) == work->input.ordinal.frameIndex) {
+        fillWork(work);
+    } else {
+        finish(index, fillWork);
+    }
+}
+
+c2_status_t C2SoftMpeg4Dec::ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool) {
+    if (!mDecHandle) {
+        ALOGE("not supposed to be here, invalid decoder context");
+        return C2_CORRUPTED;
+    }
+
+    mOutputBufferSize = align(mIntf->getMaxWidth(), 16) * align(mIntf->getMaxHeight(), 16) * 3 / 2;
+    for (int32_t i = 0; i < kNumOutputBuffers; ++i) {
+        if (!mOutputBuffer[i]) {
+            mOutputBuffer[i] = (uint8_t *)malloc(mOutputBufferSize);
+            if (!mOutputBuffer[i]) {
+                return C2_NO_MEMORY;
+            }
+        }
+    }
+    if (mOutBlock &&
+            (mOutBlock->width() != align(mWidth, 16) || mOutBlock->height() != mHeight)) {
+        mOutBlock.reset();
+    }
+    if (!mOutBlock) {
+        uint32_t format = HAL_PIXEL_FORMAT_YV12;
+        C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+        c2_status_t err = pool->fetchGraphicBlock(align(mWidth, 16), mHeight, format, usage, &mOutBlock);
+        if (err != C2_OK) {
+            ALOGE("fetchGraphicBlock for Output failed with status %d", err);
+            return err;
+        }
+        ALOGV("provided (%dx%d) required (%dx%d)",
+              mOutBlock->width(), mOutBlock->height(), mWidth, mHeight);
+    }
+    return C2_OK;
+}
+
+bool C2SoftMpeg4Dec::handleResChange(const std::unique_ptr<C2Work> &work) {
+    uint32_t disp_width, disp_height;
+    PVGetVideoDimensions(mDecHandle, (int32 *)&disp_width, (int32 *)&disp_height);
+
+    uint32_t buf_width, buf_height;
+    PVGetBufferDimensions(mDecHandle, (int32 *)&buf_width, (int32 *)&buf_height);
+
+    CHECK_LE(disp_width, buf_width);
+    CHECK_LE(disp_height, buf_height);
+
+    ALOGV("display size (%dx%d), buffer size (%dx%d)",
+           disp_width, disp_height, buf_width, buf_height);
+
+    bool resChanged = false;
+    if (disp_width != mWidth || disp_height != mHeight) {
+        mWidth = disp_width;
+        mHeight = disp_height;
+        resChanged = true;
+        for (int32_t i = 0; i < kNumOutputBuffers; ++i) {
+            if (mOutputBuffer[i]) {
+                free(mOutputBuffer[i]);
+                mOutputBuffer[i] = nullptr;
+            }
+        }
+
+        if (!mIsMpeg4) {
+            PVCleanUpVideoDecoder(mDecHandle);
+
+            uint8_t *vol_data[1]{};
+            int32_t vol_size = 0;
+
+            if (!PVInitVideoDecoder(
+                    mDecHandle, vol_data, &vol_size, 1, mIntf->getMaxWidth(), mIntf->getMaxHeight(), H263_MODE)) {
+                ALOGE("Error in PVInitVideoDecoder H263_MODE while resChanged was set to true");
+                mSignalledError = true;
+                work->result = C2_CORRUPTED;
+                return true;
+            }
+        }
+        mFramesConfigured = false;
+    }
+    return resChanged;
+}
+
+/* TODO: can remove temporary copy after library supports writing to display
+ * buffer Y, U and V plane pointers using stride info. */
+static void copyOutputBufferToYuvPlanarFrame(
+        uint8_t *dst, uint8_t *src,
+        size_t dstYStride, size_t dstUVStride,
+        size_t srcYStride, uint32_t width,
+        uint32_t height) {
+    size_t srcUVStride = srcYStride / 2;
+    uint8_t *srcStart = src;
+    uint8_t *dstStart = dst;
+    size_t vStride = align(height, 16);
+    for (size_t i = 0; i < height; ++i) {
+         memcpy(dst, src, width);
+         src += srcYStride;
+         dst += dstYStride;
+    }
+    /* U buffer */
+    src = srcStart + vStride * srcYStride;
+    dst = dstStart + (dstYStride * height) + (dstUVStride * height / 2);
+    for (size_t i = 0; i < height / 2; ++i) {
+         memcpy(dst, src, width / 2);
+         src += srcUVStride;
+         dst += dstUVStride;
+    }
+    /* V buffer */
+    src = srcStart + vStride * srcYStride * 5 / 4;
+    dst = dstStart + (dstYStride * height);
+    for (size_t i = 0; i < height / 2; ++i) {
+         memcpy(dst, src, width / 2);
+         src += srcUVStride;
+         dst += dstUVStride;
+    }
+}
+
+void C2SoftMpeg4Dec::process(
+        const std::unique_ptr<C2Work> &work,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    // Initialize output work
+    work->result = C2_OK;
+    work->workletsProcessed = 1u;
+    work->worklets.front()->output.configUpdate.clear();
+    work->worklets.front()->output.flags = work->input.flags;
+
+    if (mSignalledError || mSignalledOutputEos) {
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+
+    size_t inOffset = 0u;
+    size_t inSize = 0u;
+    uint32_t workIndex = work->input.ordinal.frameIndex.peeku() & 0xFFFFFFFF;
+    C2ReadView rView = mDummyReadView;
+    if (!work->input.buffers.empty()) {
+        rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
+        inSize = rView.capacity();
+        if (inSize && rView.error()) {
+            ALOGE("read view map failed %d", rView.error());
+            work->result = C2_CORRUPTED;
+            return;
+        }
+    }
+    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
+          inSize, (int)work->input.ordinal.timestamp.peeku(),
+          (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
+
+    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
+    if (inSize == 0) {
+        fillEmptyWork(work);
+        if (eos) {
+            mSignalledOutputEos = true;
+        }
+        return;
+    }
+
+    uint8_t *bitstream = const_cast<uint8_t *>(rView.data() + inOffset);
+    uint32_t *start_code = (uint32_t *)bitstream;
+    bool volHeader = *start_code == 0xB0010000;
+    if (volHeader) {
+        PVCleanUpVideoDecoder(mDecHandle);
+        mInitialized = false;
+    }
+
+    if (!mInitialized) {
+        uint8_t *vol_data[1]{};
+        int32_t vol_size = 0;
+
+        bool codecConfig = (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0;
+        if (codecConfig || volHeader) {
+            vol_data[0] = bitstream;
+            vol_size = inSize;
+        }
+        MP4DecodingMode mode = (mIsMpeg4) ? MPEG4_MODE : H263_MODE;
+        if (!PVInitVideoDecoder(
+                mDecHandle, vol_data, &vol_size, 1,
+                mIntf->getMaxWidth(), mIntf->getMaxHeight(), mode)) {
+            ALOGE("PVInitVideoDecoder failed. Unsupported content?");
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+        mInitialized = true;
+        MP4DecodingMode actualMode = PVGetDecBitstreamMode(mDecHandle);
+        if (mode != actualMode) {
+            ALOGE("Decoded mode not same as actual mode of the decoder");
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+
+        PVSetPostProcType(mDecHandle, 0);
+        if (handleResChange(work)) {
+            ALOGI("Setting width and height");
+            C2StreamPictureSizeInfo::output size(0u, mWidth, mHeight);
+            std::vector<std::unique_ptr<C2SettingResult>> failures;
+            c2_status_t err = mIntf->config({&size}, C2_MAY_BLOCK, &failures);
+            if (err == OK) {
+                work->worklets.front()->output.configUpdate.push_back(
+                    C2Param::Copy(size));
+            } else {
+                ALOGE("Config update size failed");
+                mSignalledError = true;
+                work->result = C2_CORRUPTED;
+                return;
+            }
+        }
+        if (codecConfig) {
+            fillEmptyWork(work);
+            return;
+        }
+    }
+
+    size_t inPos = 0;
+    while (inPos < inSize) {
+        c2_status_t err = ensureDecoderState(pool);
+        if (C2_OK != err) {
+            mSignalledError = true;
+            work->result = err;
+            return;
+        }
+        C2GraphicView wView = mOutBlock->map().get();
+        if (wView.error()) {
+            ALOGE("graphic view map failed %d", wView.error());
+            work->result = C2_CORRUPTED;
+            return;
+        }
+
+        uint32_t yFrameSize = sizeof(uint8) * mDecHandle->size;
+        if (mOutputBufferSize < yFrameSize * 3 / 2){
+            ALOGE("Too small output buffer: %zu bytes", mOutputBufferSize);
+            mSignalledError = true;
+            work->result = C2_NO_MEMORY;
+            return;
+        }
+
+        if (!mFramesConfigured) {
+            PVSetReferenceYUV(mDecHandle,mOutputBuffer[1]);
+            mFramesConfigured = true;
+        }
+
+        // Need to check if header contains new info, e.g., width/height, etc.
+        VopHeaderInfo header_info;
+        uint32_t useExtTimestamp = (inPos == 0);
+        int32_t tmpInSize = (int32_t)inSize;
+        uint8_t *bitstreamTmp = bitstream;
+        uint32_t timestamp = workIndex;
+        if (PVDecodeVopHeader(
+                    mDecHandle, &bitstreamTmp, &timestamp, &tmpInSize,
+                    &header_info, &useExtTimestamp,
+                    mOutputBuffer[mNumSamplesOutput & 1]) != PV_TRUE) {
+            ALOGE("failed to decode vop header.");
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+
+        // H263 doesn't have VOL header, the frame size information is in short header, i.e. the
+        // decoder may detect size change after PVDecodeVopHeader.
+        bool resChange = handleResChange(work);
+        if (mIsMpeg4 && resChange) {
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            return;
+        } else if (resChange) {
+            ALOGI("Setting width and height");
+            C2StreamPictureSizeInfo::output size(0u, mWidth, mHeight);
+            std::vector<std::unique_ptr<C2SettingResult>> failures;
+            c2_status_t err = mIntf->config({&size}, C2_MAY_BLOCK, &failures);
+            if (err == OK) {
+                work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(size));
+            } else {
+                ALOGE("Config update size failed");
+                mSignalledError = true;
+                work->result = C2_CORRUPTED;
+                return;
+            }
+            continue;
+        }
+
+        if (PVDecodeVopBody(mDecHandle, &tmpInSize) != PV_TRUE) {
+            ALOGE("failed to decode video frame.");
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+        if (handleResChange(work)) {
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+
+        uint8_t *outputBufferY = wView.data()[C2PlanarLayout::PLANE_Y];
+        C2PlanarLayout layout = wView.layout();
+        size_t dstYStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
+        size_t dstUVStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
+        (void)copyOutputBufferToYuvPlanarFrame(
+                outputBufferY,
+                mOutputBuffer[mNumSamplesOutput & 1],
+                dstYStride, dstUVStride,
+                align(mWidth, 16), mWidth, mHeight);
+
+        inPos += inSize - (size_t)tmpInSize;
+        finishWork(workIndex, work);
+        ++mNumSamplesOutput;
+        if (inSize - inPos != 0) {
+            ALOGD("decoded frame, ignoring further trailing bytes %d",
+                  (int)inSize - (int)inPos);
+            break;
+        }
+    }
+}
+
+c2_status_t C2SoftMpeg4Dec::drain(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    (void)pool;
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+    return C2_OK;
+}
+
+class C2SoftMpeg4DecFactory : public C2ComponentFactory {
+public:
+    C2SoftMpeg4DecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+        GetCodec2PlatformComponentStore()->getParamReflector())) {
+    }
+
+    virtual c2_status_t createComponent(
+            c2_node_id_t id,
+            std::shared_ptr<C2Component>* const component,
+            std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+                new C2SoftMpeg4Dec(COMPONENT_NAME,
+                                   id,
+                                   std::make_shared<C2SoftMpeg4Dec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+            c2_node_id_t id,
+            std::shared_ptr<C2ComponentInterface>* const interface,
+            std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+                new SimpleInterface<C2SoftMpeg4Dec::IntfImpl>(
+                        COMPONENT_NAME, id, std::make_shared<C2SoftMpeg4Dec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftMpeg4DecFactory() override = default;
+
+private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftMpeg4DecFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.h b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.h
new file mode 100644
index 0000000..716a095
--- /dev/null
+++ b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef C2_SOFT_MPEG4_DEC_H_
+#define C2_SOFT_MPEG4_DEC_H_
+
+#include <SimpleC2Component.h>
+
+
+struct tagvideoDecControls;
+
+namespace android {
+
+struct C2SoftMpeg4Dec : public SimpleC2Component {
+    class IntfImpl;
+
+    C2SoftMpeg4Dec(const char* name, c2_node_id_t id,
+                   const std::shared_ptr<IntfImpl>& intfImpl);
+    virtual ~C2SoftMpeg4Dec();
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+    c2_status_t drain(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+ private:
+    enum {
+        kNumOutputBuffers = 2,
+    };
+
+    status_t initDecoder();
+    c2_status_t ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool);
+    void finishWork(uint64_t index, const std::unique_ptr<C2Work> &work);
+    bool handleResChange(const std::unique_ptr<C2Work> &work);
+
+    std::shared_ptr<IntfImpl> mIntf;
+    tagvideoDecControls *mDecHandle;
+    std::shared_ptr<C2GraphicBlock> mOutBlock;
+    uint8_t *mOutputBuffer[kNumOutputBuffers];
+    size_t  mOutputBufferSize;
+
+    uint32_t mWidth;
+    uint32_t mHeight;
+    uint32_t mNumSamplesOutput;
+
+    bool mIsMpeg4;
+    bool mInitialized;
+    bool mFramesConfigured;
+    bool mSignalledOutputEos;
+    bool mSignalledError;
+
+    C2_DO_NOT_COPY(C2SoftMpeg4Dec);
+};
+
+}  // namespace android
+
+#endif  // C2_SOFT_MPEG4_DEC_H_
diff --git a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
new file mode 100644
index 0000000..36053f6
--- /dev/null
+++ b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
@@ -0,0 +1,661 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#ifdef MPEG4
+  #define LOG_TAG "C2SoftMpeg4Enc"
+#else
+  #define LOG_TAG "C2SoftH263Enc"
+#endif
+#include <log/log.h>
+
+#include <inttypes.h>
+
+#include <media/hardware/VideoAPI.h>
+#include <media/stagefright/foundation/AUtils.h>
+#include <media/stagefright/MediaDefs.h>
+#include <utils/misc.h>
+
+#include <C2Debug.h>
+#include <C2PlatformSupport.h>
+#include <SimpleC2Interface.h>
+#include <util/C2InterfaceHelper.h>
+
+#include "C2SoftMpeg4Enc.h"
+#include "mp4enc_api.h"
+
+namespace android {
+
+namespace {
+
+#ifdef MPEG4
+constexpr char COMPONENT_NAME[] = "c2.android.mpeg4.encoder";
+const char *MEDIA_MIMETYPE_VIDEO = MEDIA_MIMETYPE_VIDEO_MPEG4;
+#else
+constexpr char COMPONENT_NAME[] = "c2.android.h263.encoder";
+const char *MEDIA_MIMETYPE_VIDEO = MEDIA_MIMETYPE_VIDEO_H263;
+#endif
+
+} // namepsace
+
+class C2SoftMpeg4Enc::IntfImpl : public SimpleInterface<void>::BaseParams {
+   public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+        : SimpleInterface<void>::BaseParams(
+                helper,
+                COMPONENT_NAME,
+                C2Component::KIND_ENCODER,
+                C2Component::DOMAIN_VIDEO,
+                MEDIA_MIMETYPE_VIDEO) {
+        noPrivateBuffers(); // TODO: account for our buffers here
+        noInputReferences();
+        noOutputReferences();
+        noInputLatency();
+        noTimeStretch();
+        setDerivedInstance(this);
+
+        addParameter(
+                DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                .withConstValue(new C2ComponentAttributesSetting(
+                    C2Component::ATTRIB_IS_TEMPORAL))
+                .build());
+
+        addParameter(
+                DefineParam(mUsage, C2_PARAMKEY_INPUT_STREAM_USAGE)
+                .withConstValue(new C2StreamUsageTuning::input(
+                        0u, (uint64_t)C2MemoryUsage::CPU_READ))
+                .build());
+
+        addParameter(
+            DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
+                .withDefault(new C2StreamPictureSizeInfo::input(0u, 176, 144))
+                .withFields({
+#ifdef MPEG4
+                    C2F(mSize, width).inRange(16, 176, 16),
+                    C2F(mSize, height).inRange(16, 144, 16),
+#else
+                    C2F(mSize, width).oneOf({176, 352}),
+                    C2F(mSize, height).oneOf({144, 288}),
+#endif
+                })
+                .withSetter(SizeSetter)
+                .build());
+
+        addParameter(
+            DefineParam(mFrameRate, C2_PARAMKEY_FRAME_RATE)
+                .withDefault(new C2StreamFrameRateInfo::output(0u, 17.))
+                // TODO: More restriction?
+                .withFields({C2F(mFrameRate, value).greaterThan(0.)})
+                .withSetter(
+                    Setter<decltype(*mFrameRate)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+            DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
+                .withDefault(new C2StreamBitrateInfo::output(0u, 64000))
+                .withFields({C2F(mBitrate, value).inRange(4096, 12000000)})
+                .withSetter(BitrateSetter)
+                .build());
+
+        addParameter(
+                DefineParam(mSyncFramePeriod, C2_PARAMKEY_SYNC_FRAME_INTERVAL)
+                .withDefault(new C2StreamSyncFrameIntervalTuning::output(0u, 1000000))
+                .withFields({C2F(mSyncFramePeriod, value).any()})
+                .withSetter(Setter<decltype(*mSyncFramePeriod)>::StrictValueWithNoDeps)
+                .build());
+
+#ifdef MPEG4
+        addParameter(
+                DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
+                .withDefault(new C2StreamProfileLevelInfo::output(
+                        0u, PROFILE_MP4V_SIMPLE, LEVEL_MP4V_2))
+                .withFields({
+                    C2F(mProfileLevel, profile).equalTo(
+                            PROFILE_MP4V_SIMPLE),
+                    C2F(mProfileLevel, level).oneOf({
+                            C2Config::LEVEL_MP4V_0,
+                            C2Config::LEVEL_MP4V_0B,
+                            C2Config::LEVEL_MP4V_1,
+                            C2Config::LEVEL_MP4V_2})
+                })
+                .withSetter(ProfileLevelSetter)
+                .build());
+#else
+        addParameter(
+                DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
+                .withDefault(new C2StreamProfileLevelInfo::output(
+                        0u, PROFILE_H263_BASELINE, LEVEL_H263_45))
+                .withFields({
+                    C2F(mProfileLevel, profile).equalTo(
+                            PROFILE_H263_BASELINE),
+                    C2F(mProfileLevel, level).oneOf({
+                            C2Config::LEVEL_H263_10,
+                            C2Config::LEVEL_H263_20,
+                            C2Config::LEVEL_H263_30,
+                            C2Config::LEVEL_H263_40,
+                            C2Config::LEVEL_H263_45})
+                })
+                .withSetter(ProfileLevelSetter)
+                .build());
+#endif
+    }
+
+    static C2R BitrateSetter(bool mayBlock, C2P<C2StreamBitrateInfo::output> &me) {
+        (void)mayBlock;
+        C2R res = C2R::Ok();
+        if (me.v.value <= 4096) {
+            me.set().value = 4096;
+        }
+        return res;
+    }
+
+    static C2R SizeSetter(bool mayBlock, const C2P<C2StreamPictureSizeInfo::input> &oldMe,
+                          C2P<C2StreamPictureSizeInfo::input> &me) {
+        (void)mayBlock;
+        C2R res = C2R::Ok();
+        if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
+            res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
+            me.set().width = oldMe.v.width;
+        }
+        if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
+            res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
+            me.set().height = oldMe.v.height;
+        }
+        return res;
+    }
+
+    static C2R ProfileLevelSetter(
+            bool mayBlock,
+            C2P<C2StreamProfileLevelInfo::output> &me) {
+        (void)mayBlock;
+        if (!me.F(me.v.profile).supportsAtAll(me.v.profile)) {
+#ifdef MPEG4
+            me.set().profile = PROFILE_MP4V_SIMPLE;
+#else
+            me.set().profile = PROFILE_H263_BASELINE;
+#endif
+        }
+        if (!me.F(me.v.level).supportsAtAll(me.v.level)) {
+#ifdef MPEG4
+            me.set().level = LEVEL_MP4V_2;
+#else
+            me.set().level = LEVEL_H263_45;
+#endif
+        }
+        return C2R::Ok();
+    }
+
+    // unsafe getters
+    std::shared_ptr<C2StreamPictureSizeInfo::input> getSize_l() const { return mSize; }
+    std::shared_ptr<C2StreamFrameRateInfo::output> getFrameRate_l() const { return mFrameRate; }
+    std::shared_ptr<C2StreamBitrateInfo::output> getBitrate_l() const { return mBitrate; }
+    uint32_t getSyncFramePeriod() const {
+        if (mSyncFramePeriod->value < 0 || mSyncFramePeriod->value == INT64_MAX) {
+            return 0;
+        }
+        double period = mSyncFramePeriod->value / 1e6 * mFrameRate->value;
+        return (uint32_t)c2_max(c2_min(period + 0.5, double(UINT32_MAX)), 1.);
+    }
+
+   private:
+    std::shared_ptr<C2StreamUsageTuning::input> mUsage;
+    std::shared_ptr<C2StreamPictureSizeInfo::input> mSize;
+    std::shared_ptr<C2StreamFrameRateInfo::output> mFrameRate;
+    std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
+    std::shared_ptr<C2StreamProfileLevelInfo::output> mProfileLevel;
+    std::shared_ptr<C2StreamSyncFrameIntervalTuning::output> mSyncFramePeriod;
+};
+
+C2SoftMpeg4Enc::C2SoftMpeg4Enc(const char* name, c2_node_id_t id,
+                               const std::shared_ptr<IntfImpl>& intfImpl)
+    : SimpleC2Component(
+          std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+      mIntf(intfImpl),
+      mHandle(nullptr),
+      mEncParams(nullptr),
+      mStarted(false),
+      mOutBufferSize(524288) {
+}
+
+C2SoftMpeg4Enc::~C2SoftMpeg4Enc() {
+    onRelease();
+}
+
+c2_status_t C2SoftMpeg4Enc::onInit() {
+#ifdef MPEG4
+    mEncodeMode = COMBINE_MODE_WITH_ERR_RES;
+#else
+    mEncodeMode = H263_MODE;
+#endif
+    if (!mHandle) {
+        mHandle = new tagvideoEncControls;
+    }
+
+    if (!mEncParams) {
+        mEncParams = new tagvideoEncOptions;
+    }
+
+    if (!(mEncParams && mHandle)) return C2_NO_MEMORY;
+
+    mSignalledOutputEos = false;
+    mSignalledError = false;
+
+    return initEncoder();
+}
+
+c2_status_t C2SoftMpeg4Enc::onStop() {
+    if (!mStarted) {
+        return C2_OK;
+    }
+    if (mHandle) {
+        (void)PVCleanUpVideoEncoder(mHandle);
+    }
+    mStarted = false;
+    mSignalledOutputEos = false;
+    mSignalledError = false;
+    return C2_OK;
+}
+
+void C2SoftMpeg4Enc::onReset() {
+    onStop();
+    initEncoder();
+}
+
+void C2SoftMpeg4Enc::onRelease() {
+    onStop();
+    if (mEncParams) {
+        delete mEncParams;
+        mEncParams = nullptr;
+    }
+    if (mHandle) {
+        delete mHandle;
+        mHandle = nullptr;
+    }
+}
+
+c2_status_t C2SoftMpeg4Enc::onFlush_sm() {
+    return C2_OK;
+}
+
+static void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
+    uint32_t flags = 0;
+    if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
+        flags |= C2FrameData::FLAG_END_OF_STREAM;
+        ALOGV("signalling eos");
+    }
+    work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
+    work->worklets.front()->output.buffers.clear();
+    work->worklets.front()->output.ordinal = work->input.ordinal;
+    work->workletsProcessed = 1u;
+}
+
+c2_status_t C2SoftMpeg4Enc::initEncParams() {
+    if (mHandle) {
+        memset(mHandle, 0, sizeof(tagvideoEncControls));
+    } else return C2_CORRUPTED;
+    if (mEncParams) {
+        memset(mEncParams, 0, sizeof(tagvideoEncOptions));
+    } else return C2_CORRUPTED;
+
+    if (!PVGetDefaultEncOption(mEncParams, 0)) {
+        ALOGE("Failed to get default encoding parameters");
+        return C2_CORRUPTED;
+    }
+
+    if (mFrameRate->value == 0) {
+        ALOGE("Framerate should not be 0");
+        return C2_BAD_VALUE;
+    }
+
+    mEncParams->encMode = mEncodeMode;
+    mEncParams->encWidth[0] = mSize->width;
+    mEncParams->encHeight[0] = mSize->height;
+    mEncParams->encFrameRate[0] = mFrameRate->value + 0.5;
+    mEncParams->rcType = VBR_1;
+    mEncParams->vbvDelay = 5.0f;
+    mEncParams->profile_level = CORE_PROFILE_LEVEL2;
+    mEncParams->packetSize = 32;
+    mEncParams->rvlcEnable = PV_OFF;
+    mEncParams->numLayers = 1;
+    mEncParams->timeIncRes = 1000;
+    mEncParams->tickPerSrc = mEncParams->timeIncRes / (mFrameRate->value + 0.5);
+    mEncParams->bitRate[0] = mBitrate->value;
+    mEncParams->iQuant[0] = 15;
+    mEncParams->pQuant[0] = 12;
+    mEncParams->quantType[0] = 0;
+    mEncParams->noFrameSkipped = PV_OFF;
+
+    // PV's MPEG4 encoder requires the video dimension of multiple
+    if (mSize->width % 16 != 0 || mSize->height % 16 != 0) {
+        ALOGE("Video frame size %dx%d must be a multiple of 16",
+              mSize->width, mSize->height);
+        return C2_BAD_VALUE;
+    }
+
+    // Set IDR frame refresh interval
+    mEncParams->intraPeriod = mIntf->getSyncFramePeriod();
+    mEncParams->numIntraMB = 0;
+    mEncParams->sceneDetect = PV_ON;
+    mEncParams->searchRange = 16;
+    mEncParams->mv8x8Enable = PV_OFF;
+    mEncParams->gobHeaderInterval = 0;
+    mEncParams->useACPred = PV_ON;
+    mEncParams->intraDCVlcTh = 0;
+
+    return C2_OK;
+}
+
+c2_status_t C2SoftMpeg4Enc::initEncoder() {
+    if (mStarted) {
+        return C2_OK;
+    }
+    {
+        IntfImpl::Lock lock = mIntf->lock();
+        mSize = mIntf->getSize_l();
+        mBitrate = mIntf->getBitrate_l();
+        mFrameRate = mIntf->getFrameRate_l();
+    }
+    c2_status_t err = initEncParams();
+    if (C2_OK != err) {
+        ALOGE("Failed to initialized encoder params");
+        mSignalledError = true;
+        return err;
+    }
+    if (!PVInitVideoEncoder(mHandle, mEncParams)) {
+        ALOGE("Failed to initialize the encoder");
+        mSignalledError = true;
+        return C2_CORRUPTED;
+    }
+
+    // 1st buffer for codec specific data
+    mNumInputFrames = -1;
+    mStarted = true;
+    return C2_OK;
+}
+
+void C2SoftMpeg4Enc::process(
+        const std::unique_ptr<C2Work> &work,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    // Initialize output work
+    work->result = C2_OK;
+    work->workletsProcessed = 1u;
+    work->worklets.front()->output.flags = work->input.flags;
+    if (mSignalledError || mSignalledOutputEos) {
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+
+    // Initialize encoder if not already initialized
+    if (!mStarted && C2_OK != initEncoder()) {
+        ALOGE("Failed to initialize encoder");
+        mSignalledError = true;
+        work->result = C2_CORRUPTED;
+        return;
+    }
+
+    std::shared_ptr<C2LinearBlock> block;
+    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+    c2_status_t err = pool->fetchLinearBlock(mOutBufferSize, usage, &block);
+    if (err != C2_OK) {
+        ALOGE("fetchLinearBlock for Output failed with status %d", err);
+        work->result = C2_NO_MEMORY;
+        return;
+    }
+
+    C2WriteView wView = block->map().get();
+    if (wView.error()) {
+        ALOGE("write view map failed %d", wView.error());
+        work->result = wView.error();
+        return;
+    }
+
+    uint8_t *outPtr = (uint8_t *)wView.data();
+    if (mNumInputFrames < 0) {
+        // The very first thing we want to output is the codec specific data.
+        int32_t outputSize = mOutBufferSize;
+        if (!PVGetVolHeader(mHandle, outPtr, &outputSize, 0)) {
+            ALOGE("Failed to get VOL header");
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            return;
+        } else {
+            ALOGV("Bytes Generated in header %d\n", outputSize);
+        }
+
+        ++mNumInputFrames;
+        std::unique_ptr<C2StreamInitDataInfo::output> csd =
+            C2StreamInitDataInfo::output::AllocUnique(outputSize, 0u);
+        if (!csd) {
+            ALOGE("CSD allocation failed");
+            mSignalledError = true;
+            work->result = C2_NO_MEMORY;
+            return;
+        }
+        memcpy(csd->m.value, outPtr, outputSize);
+        work->worklets.front()->output.configUpdate.push_back(std::move(csd));
+    }
+
+    std::shared_ptr<const C2GraphicView> rView;
+    std::shared_ptr<C2Buffer> inputBuffer;
+    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
+    if (!work->input.buffers.empty()) {
+        inputBuffer = work->input.buffers[0];
+        rView = std::make_shared<const C2GraphicView>(
+                inputBuffer->data().graphicBlocks().front().map().get());
+        if (rView->error() != C2_OK) {
+            ALOGE("graphic view map err = %d", rView->error());
+            work->result = rView->error();
+            return;
+        }
+    } else {
+        fillEmptyWork(work);
+        if (eos) {
+            mSignalledOutputEos = true;
+            ALOGV("signalled EOS");
+        }
+        return;
+    }
+
+    uint64_t inputTimeStamp = work->input.ordinal.timestamp.peekull();
+    const C2ConstGraphicBlock inBuffer = inputBuffer->data().graphicBlocks().front();
+    if (inBuffer.width() < mSize->width ||
+        inBuffer.height() < mSize->height) {
+        /* Expect width height to be configured */
+        ALOGW("unexpected Capacity Aspect %d(%d) x %d(%d)", inBuffer.width(),
+              mSize->width, inBuffer.height(), mSize->height);
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+
+    const C2PlanarLayout &layout = rView->layout();
+    uint8_t *yPlane = const_cast<uint8_t *>(rView->data()[C2PlanarLayout::PLANE_Y]);
+    uint8_t *uPlane = const_cast<uint8_t *>(rView->data()[C2PlanarLayout::PLANE_U]);
+    uint8_t *vPlane = const_cast<uint8_t *>(rView->data()[C2PlanarLayout::PLANE_V]);
+    int32_t yStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
+    int32_t uStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
+    int32_t vStride = layout.planes[C2PlanarLayout::PLANE_V].rowInc;
+    uint32_t width = mSize->width;
+    uint32_t height = mSize->height;
+    // width and height are always even (as block size is 16x16)
+    CHECK_EQ((width & 1u), 0u);
+    CHECK_EQ((height & 1u), 0u);
+    size_t yPlaneSize = width * height;
+    switch (layout.type) {
+        case C2PlanarLayout::TYPE_RGB:
+            [[fallthrough]];
+        case C2PlanarLayout::TYPE_RGBA: {
+            MemoryBlock conversionBuffer = mConversionBuffers.fetch(yPlaneSize * 3 / 2);
+            mConversionBuffersInUse.emplace(conversionBuffer.data(), conversionBuffer);
+            yPlane = conversionBuffer.data();
+            uPlane = yPlane + yPlaneSize;
+            vPlane = uPlane + yPlaneSize / 4;
+            yStride = width;
+            uStride = vStride = width / 2;
+            ConvertRGBToPlanarYUV(yPlane, yStride, height, conversionBuffer.size(), *rView.get());
+            break;
+        }
+        case C2PlanarLayout::TYPE_YUV: {
+            if (!IsYUV420(*rView)) {
+                ALOGE("input is not YUV420");
+                work->result = C2_BAD_VALUE;
+                break;
+            }
+
+            if (layout.planes[layout.PLANE_Y].colInc == 1
+                    && layout.planes[layout.PLANE_U].colInc == 1
+                    && layout.planes[layout.PLANE_V].colInc == 1
+                    && uStride == vStride
+                    && yStride == 2 * vStride) {
+                // I420 compatible - planes are already set up above
+                break;
+            }
+
+            // copy to I420
+            MemoryBlock conversionBuffer = mConversionBuffers.fetch(yPlaneSize * 3 / 2);
+            mConversionBuffersInUse.emplace(conversionBuffer.data(), conversionBuffer);
+            MediaImage2 img = CreateYUV420PlanarMediaImage2(width, height, width, height);
+            status_t err = ImageCopy(conversionBuffer.data(), &img, *rView);
+            if (err != OK) {
+                ALOGE("Buffer conversion failed: %d", err);
+                work->result = C2_BAD_VALUE;
+                return;
+            }
+            yPlane = conversionBuffer.data();
+            uPlane = yPlane + yPlaneSize;
+            vPlane = uPlane + yPlaneSize / 4;
+            yStride = width;
+            uStride = vStride = width / 2;
+            break;
+        }
+
+        case C2PlanarLayout::TYPE_YUVA:
+            ALOGE("YUVA plane type is not supported");
+            work->result = C2_BAD_VALUE;
+            return;
+
+        default:
+            ALOGE("Unrecognized plane type: %d", layout.type);
+            work->result = C2_BAD_VALUE;
+            return;
+    }
+
+    CHECK(NULL != yPlane);
+    /* Encode frames */
+    VideoEncFrameIO vin, vout;
+    memset(&vin, 0, sizeof(vin));
+    memset(&vout, 0, sizeof(vout));
+    vin.yChan = yPlane;
+    vin.uChan = uPlane;
+    vin.vChan = vPlane;
+    vin.timestamp = (inputTimeStamp + 500) / 1000;  // in ms
+    vin.height = align(height, 16);
+    vin.pitch = align(width, 16);
+
+    uint32_t modTimeMs = 0;
+    int32_t nLayer = 0;
+    MP4HintTrack hintTrack;
+    int32_t outputSize = mOutBufferSize;
+    if (!PVEncodeVideoFrame(mHandle, &vin, &vout, &modTimeMs, outPtr, &outputSize, &nLayer) ||
+        !PVGetHintTrack(mHandle, &hintTrack)) {
+        ALOGE("Failed to encode frame or get hint track at frame %" PRId64, mNumInputFrames);
+        mSignalledError = true;
+        work->result = C2_CORRUPTED;
+        return;
+    }
+    ALOGV("outputSize filled : %d", outputSize);
+    ++mNumInputFrames;
+    CHECK(NULL == PVGetOverrunBuffer(mHandle));
+
+    fillEmptyWork(work);
+    if (outputSize) {
+        std::shared_ptr<C2Buffer> buffer = createLinearBuffer(block, 0, outputSize);
+        work->worklets.front()->output.ordinal.timestamp = inputTimeStamp;
+        if (hintTrack.CodeType == 0) {
+            buffer->setInfo(std::make_shared<C2StreamPictureTypeMaskInfo::output>(
+                    0u /* stream id */, C2Config::SYNC_FRAME));
+        }
+        work->worklets.front()->output.buffers.push_back(buffer);
+    }
+    if (eos) {
+        mSignalledOutputEos = true;
+    }
+
+    mConversionBuffersInUse.erase(yPlane);
+}
+
+c2_status_t C2SoftMpeg4Enc::drain(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    (void)pool;
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+
+    return C2_OK;
+}
+
+class C2SoftMpeg4EncFactory : public C2ComponentFactory {
+public:
+    C2SoftMpeg4EncFactory()
+        : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+              GetCodec2PlatformComponentStore()->getParamReflector())) {}
+
+    virtual c2_status_t createComponent(
+            c2_node_id_t id,
+            std::shared_ptr<C2Component>* const component,
+            std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+            new C2SoftMpeg4Enc(
+                COMPONENT_NAME, id,
+                std::make_shared<C2SoftMpeg4Enc::IntfImpl>(mHelper)),
+            deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+            c2_node_id_t id,
+            std::shared_ptr<C2ComponentInterface>* const interface,
+            std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+            new SimpleInterface<C2SoftMpeg4Enc::IntfImpl>(
+                COMPONENT_NAME, id,
+                std::make_shared<C2SoftMpeg4Enc::IntfImpl>(mHelper)),
+            deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftMpeg4EncFactory() override = default;
+
+private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftMpeg4EncFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.h b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.h
new file mode 100644
index 0000000..43461fc
--- /dev/null
+++ b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef C2_SOFT_MPEG4_ENC_H__
+#define C2_SOFT_MPEG4_ENC_H__
+
+#include <map>
+
+#include <Codec2BufferUtils.h>
+#include <SimpleC2Component.h>
+
+#include "mp4enc_api.h"
+
+namespace android {
+
+struct C2SoftMpeg4Enc : public SimpleC2Component {
+    class IntfImpl;
+
+    C2SoftMpeg4Enc(const char* name, c2_node_id_t id,
+                   const std::shared_ptr<IntfImpl>& intfImpl);
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+    c2_status_t drain(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+
+protected:
+
+    virtual ~C2SoftMpeg4Enc();
+
+private:
+    std::shared_ptr<IntfImpl> mIntf;
+
+    tagvideoEncControls *mHandle;
+    tagvideoEncOptions  *mEncParams;
+
+    bool     mStarted;
+    bool     mSignalledOutputEos;
+    bool     mSignalledError;
+
+    uint32_t mOutBufferSize;
+    // configurations used by component in process
+    // (TODO: keep this in intf but make them internal only)
+    std::shared_ptr<C2StreamPictureSizeInfo::input> mSize;
+    std::shared_ptr<C2StreamFrameRateInfo::output> mFrameRate;
+    std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
+
+    int64_t  mNumInputFrames;
+    MP4EncodingMode mEncodeMode;
+
+    MemoryBlockPool mConversionBuffers;
+    std::map<void *, MemoryBlock> mConversionBuffersInUse;
+
+    c2_status_t initEncParams();
+    c2_status_t initEncoder();
+
+    C2_DO_NOT_COPY(C2SoftMpeg4Enc);
+};
+
+}  // namespace android
+
+#endif  // C2_SOFT_MPEG4_ENC_H__
diff --git a/media/common_time/MODULE_LICENSE_APACHE2 b/media/codec2/components/mpeg4_h263/MODULE_LICENSE_APACHE2
similarity index 100%
copy from media/common_time/MODULE_LICENSE_APACHE2
copy to media/codec2/components/mpeg4_h263/MODULE_LICENSE_APACHE2
diff --git a/media/common_time/NOTICE b/media/codec2/components/mpeg4_h263/NOTICE
similarity index 100%
copy from media/common_time/NOTICE
copy to media/codec2/components/mpeg4_h263/NOTICE
diff --git a/media/codec2/components/mpeg4_h263/patent_disclaimer.txt b/media/codec2/components/mpeg4_h263/patent_disclaimer.txt
new file mode 100644
index 0000000..b4bf11d
--- /dev/null
+++ b/media/codec2/components/mpeg4_h263/patent_disclaimer.txt
@@ -0,0 +1,9 @@
+
+THIS IS NOT A GRANT OF PATENT RIGHTS.
+
+Google makes no representation or warranty that the codecs for which
+source code is made available hereunder are unencumbered by
+third-party patents.  Those intending to use this source code in
+hardware or software products are advised that implementations of
+these codecs, including in open source software or shareware, may
+require patent licenses from the relevant patent holders.
diff --git a/media/codec2/components/opus/Android.bp b/media/codec2/components/opus/Android.bp
new file mode 100644
index 0000000..0ed141b
--- /dev/null
+++ b/media/codec2/components/opus/Android.bp
@@ -0,0 +1,22 @@
+cc_library_shared {
+    name: "libcodec2_soft_opusdec",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["C2SoftOpusDec.cpp"],
+
+    shared_libs: ["libopus"],
+}
+cc_library_shared {
+    name: "libcodec2_soft_opusenc",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["C2SoftOpusEnc.cpp"],
+
+    shared_libs: ["libopus"],
+}
diff --git a/media/codec2/components/opus/C2SoftOpusDec.cpp b/media/codec2/components/opus/C2SoftOpusDec.cpp
new file mode 100644
index 0000000..6b6974f
--- /dev/null
+++ b/media/codec2/components/opus/C2SoftOpusDec.cpp
@@ -0,0 +1,484 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftOpusDec"
+#include <log/log.h>
+
+#include <media/stagefright/foundation/MediaDefs.h>
+#include <media/stagefright/foundation/OpusHeader.h>
+#include <C2PlatformSupport.h>
+#include <SimpleC2Interface.h>
+#include "C2SoftOpusDec.h"
+
+extern "C" {
+    #include <opus.h>
+    #include <opus_multistream.h>
+}
+
+namespace android {
+
+namespace {
+
+constexpr char COMPONENT_NAME[] = "c2.android.opus.decoder";
+
+}  // namespace
+
+class C2SoftOpusDec::IntfImpl : public SimpleInterface<void>::BaseParams {
+public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+        : SimpleInterface<void>::BaseParams(
+                helper,
+                COMPONENT_NAME,
+                C2Component::KIND_DECODER,
+                C2Component::DOMAIN_AUDIO,
+                MEDIA_MIMETYPE_AUDIO_OPUS) {
+        noPrivateBuffers();
+        noInputReferences();
+        noOutputReferences();
+        noInputLatency();
+        noTimeStretch();
+        setDerivedInstance(this);
+
+        addParameter(
+                DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                .withConstValue(new C2ComponentAttributesSetting(
+                    C2Component::ATTRIB_IS_TEMPORAL))
+                .build());
+
+        addParameter(
+                DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE)
+                .withDefault(new C2StreamSampleRateInfo::output(0u, 48000))
+                .withFields({C2F(mSampleRate, value).equalTo(48000)})
+                .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
+                .build());
+
+        addParameter(
+                DefineParam(mChannelCount, C2_PARAMKEY_CHANNEL_COUNT)
+                .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
+                .withFields({C2F(mChannelCount, value).inRange(1, 8)})
+                .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
+                .withDefault(new C2StreamBitrateInfo::input(0u, 6000))
+                .withFields({C2F(mBitrate, value).inRange(6000, 510000)})
+                .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
+                .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 960 * 6))
+                .build());
+    }
+
+private:
+    std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
+    std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
+    std::shared_ptr<C2StreamBitrateInfo::input> mBitrate;
+    std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
+};
+
+C2SoftOpusDec::C2SoftOpusDec(const char *name, c2_node_id_t id,
+                       const std::shared_ptr<IntfImpl>& intfImpl)
+    : SimpleC2Component(
+        std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+      mIntf(intfImpl),
+      mDecoder(nullptr) {
+}
+
+C2SoftOpusDec::~C2SoftOpusDec() {
+    onRelease();
+}
+
+c2_status_t C2SoftOpusDec::onInit() {
+    status_t err = initDecoder();
+    return err == OK ? C2_OK : C2_NO_MEMORY;
+}
+
+c2_status_t C2SoftOpusDec::onStop() {
+    if (mDecoder) {
+        opus_multistream_decoder_destroy(mDecoder);
+        mDecoder = nullptr;
+    }
+    memset(&mHeader, 0, sizeof(mHeader));
+    mCodecDelay = 0;
+    mSeekPreRoll = 0;
+    mSamplesToDiscard = 0;
+    mInputBufferCount = 0;
+    mSignalledError = false;
+    mSignalledOutputEos = false;
+
+    return C2_OK;
+}
+
+void C2SoftOpusDec::onReset() {
+    (void)onStop();
+}
+
+void C2SoftOpusDec::onRelease() {
+    if (mDecoder) {
+        opus_multistream_decoder_destroy(mDecoder);
+        mDecoder = nullptr;
+    }
+}
+
+status_t C2SoftOpusDec::initDecoder() {
+    memset(&mHeader, 0, sizeof(mHeader));
+    mCodecDelay = 0;
+    mSeekPreRoll = 0;
+    mSamplesToDiscard = 0;
+    mInputBufferCount = 0;
+    mSignalledError = false;
+    mSignalledOutputEos = false;
+
+    return OK;
+}
+
+c2_status_t C2SoftOpusDec::onFlush_sm() {
+    if (mDecoder) {
+        opus_multistream_decoder_ctl(mDecoder, OPUS_RESET_STATE);
+        mSamplesToDiscard = mSeekPreRoll;
+        mSignalledOutputEos = false;
+    }
+    return C2_OK;
+}
+
+c2_status_t C2SoftOpusDec::drain(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    (void) pool;
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+
+    return C2_OK;
+}
+
+static void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
+    work->worklets.front()->output.flags = work->input.flags;
+    work->worklets.front()->output.buffers.clear();
+    work->worklets.front()->output.ordinal = work->input.ordinal;
+    work->workletsProcessed = 1u;
+}
+
+static const int kRate = 48000;
+
+// Opus uses Vorbis channel mapping, and Vorbis channel mapping specifies
+// mappings for up to 8 channels. This information is part of the Vorbis I
+// Specification:
+// http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html
+static const int kMaxChannels = 8;
+
+// Maximum packet size used in Xiph's opusdec.
+static const int kMaxOpusOutputPacketSizeSamples = 960 * 6;
+
+// Default audio output channel layout. Used to initialize |stream_map| in
+// OpusHeader, and passed to opus_multistream_decoder_create() when the header
+// does not contain mapping information. The values are valid only for mono and
+// stereo output: Opus streams with more than 2 channels require a stream map.
+static const int kMaxChannelsWithDefaultLayout = 2;
+static const uint8_t kDefaultOpusChannelLayout[kMaxChannelsWithDefaultLayout] = { 0, 1 };
+
+
+// Convert nanoseconds to number of samples.
+static uint64_t ns_to_samples(uint64_t ns, int rate) {
+    return static_cast<double>(ns) * rate / 1000000000;
+}
+
+void C2SoftOpusDec::process(
+        const std::unique_ptr<C2Work> &work,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    // Initialize output work
+    work->result = C2_OK;
+    work->workletsProcessed = 1u;
+    work->worklets.front()->output.configUpdate.clear();
+    work->worklets.front()->output.flags = work->input.flags;
+
+    if (mSignalledError || mSignalledOutputEos) {
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+
+    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
+    size_t inOffset = 0u;
+    size_t inSize = 0u;
+    C2ReadView rView = mDummyReadView;
+    if (!work->input.buffers.empty()) {
+        rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
+        inSize = rView.capacity();
+        if (inSize && rView.error()) {
+            ALOGE("read view map failed %d", rView.error());
+            work->result = C2_CORRUPTED;
+            return;
+        }
+    }
+    if (inSize == 0) {
+        fillEmptyWork(work);
+        if (eos) {
+            mSignalledOutputEos = true;
+            ALOGV("signalled EOS");
+        }
+        return;
+    }
+
+    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
+          (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
+    const uint8_t *data = rView.data() + inOffset;
+    if (mInputBufferCount < 3) {
+        if (mInputBufferCount == 0) {
+            size_t opusHeadSize = 0;
+            size_t codecDelayBufSize = 0;
+            size_t seekPreRollBufSize = 0;
+            void *opusHeadBuf = NULL;
+            void *codecDelayBuf = NULL;
+            void *seekPreRollBuf = NULL;
+
+            if (!GetOpusHeaderBuffers(data, inSize, &opusHeadBuf,
+                                     &opusHeadSize, &codecDelayBuf,
+                                     &codecDelayBufSize, &seekPreRollBuf,
+                                     &seekPreRollBufSize)) {
+                ALOGE("%s encountered error in GetOpusHeaderBuffers", __func__);
+                mSignalledError = true;
+                work->result = C2_CORRUPTED;
+                return;
+            }
+
+            if (!ParseOpusHeader((uint8_t *)opusHeadBuf, opusHeadSize, &mHeader)) {
+                ALOGE("%s Encountered error while Parsing Opus Header.", __func__);
+                mSignalledError = true;
+                work->result = C2_CORRUPTED;
+                return;
+            }
+            uint8_t channel_mapping[kMaxChannels] = {0};
+            if (mHeader.channels <= kMaxChannelsWithDefaultLayout) {
+                memcpy(&channel_mapping,
+                       kDefaultOpusChannelLayout,
+                       kMaxChannelsWithDefaultLayout);
+            } else {
+                memcpy(&channel_mapping,
+                       mHeader.stream_map,
+                       mHeader.channels);
+            }
+            int status = OPUS_INVALID_STATE;
+            mDecoder = opus_multistream_decoder_create(kRate,
+                                                       mHeader.channels,
+                                                       mHeader.num_streams,
+                                                       mHeader.num_coupled,
+                                                       channel_mapping,
+                                                       &status);
+            if (!mDecoder || status != OPUS_OK) {
+                ALOGE("opus_multistream_decoder_create failed status = %s",
+                      opus_strerror(status));
+                mSignalledError = true;
+                work->result = C2_CORRUPTED;
+                return;
+            }
+            status = opus_multistream_decoder_ctl(mDecoder,
+                                                  OPUS_SET_GAIN(mHeader.gain_db));
+            if (status != OPUS_OK) {
+                ALOGE("Failed to set OPUS header gain; status = %s",
+                      opus_strerror(status));
+                mSignalledError = true;
+                work->result = C2_CORRUPTED;
+                return;
+            }
+
+            if (codecDelayBuf && codecDelayBufSize == sizeof(uint64_t)) {
+                uint64_t value;
+                memcpy(&value, codecDelayBuf, sizeof(uint64_t));
+                mCodecDelay = ns_to_samples(value, kRate);
+                mSamplesToDiscard = mCodecDelay;
+                ++mInputBufferCount;
+            }
+            if (seekPreRollBuf && seekPreRollBufSize == sizeof(uint64_t)) {
+                uint64_t value;
+                memcpy(&value, seekPreRollBuf, sizeof(uint64_t));
+                mSeekPreRoll = ns_to_samples(value, kRate);
+                ++mInputBufferCount;
+            }
+        } else {
+            if (inSize < 8) {
+                ALOGE("Input sample size is too small.");
+                mSignalledError = true;
+                work->result = C2_CORRUPTED;
+                return;
+            }
+            int64_t samples = ns_to_samples( *(reinterpret_cast<int64_t*>
+                              (const_cast<uint8_t *> (data))), kRate);
+            if (mInputBufferCount == 1) {
+                mCodecDelay = samples;
+                mSamplesToDiscard = mCodecDelay;
+            }
+            else {
+                mSeekPreRoll = samples;
+            }
+        }
+
+        ++mInputBufferCount;
+        if (mInputBufferCount == 3) {
+            ALOGI("Configuring decoder: %d Hz, %d channels",
+                   kRate, mHeader.channels);
+            C2StreamSampleRateInfo::output sampleRateInfo(0u, kRate);
+            C2StreamChannelCountInfo::output channelCountInfo(0u, mHeader.channels);
+            std::vector<std::unique_ptr<C2SettingResult>> failures;
+            c2_status_t err = mIntf->config(
+                    { &sampleRateInfo, &channelCountInfo },
+                    C2_MAY_BLOCK,
+                    &failures);
+            if (err == OK) {
+                work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(sampleRateInfo));
+                work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(channelCountInfo));
+            } else {
+                ALOGE("Config Update failed");
+                mSignalledError = true;
+                work->result = C2_CORRUPTED;
+                return;
+            }
+        }
+        fillEmptyWork(work);
+        if (eos) {
+            mSignalledOutputEos = true;
+            ALOGV("signalled EOS");
+        }
+        return;
+    }
+
+    // Ignore CSD re-submissions.
+    if ((work->input.flags & C2FrameData::FLAG_CODEC_CONFIG)) {
+        fillEmptyWork(work);
+        return;
+    }
+
+    // When seeking to zero, |mCodecDelay| samples has to be discarded
+    // instead of |mSeekPreRoll| samples (as we would when seeking to any
+    // other timestamp).
+    if (work->input.ordinal.timestamp.peeku() == 0) mSamplesToDiscard = mCodecDelay;
+
+    std::shared_ptr<C2LinearBlock> block;
+    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+    c2_status_t err = pool->fetchLinearBlock(
+                          kMaxNumSamplesPerBuffer * kMaxChannels * sizeof(int16_t),
+                          usage, &block);
+    if (err != C2_OK) {
+        ALOGE("fetchLinearBlock for Output failed with status %d", err);
+        work->result = C2_NO_MEMORY;
+        return;
+    }
+    C2WriteView wView = block->map().get();
+    if (wView.error()) {
+        ALOGE("write view map failed %d", wView.error());
+        work->result = C2_CORRUPTED;
+        return;
+    }
+
+    int numSamples = opus_multistream_decode(mDecoder,
+                                             data,
+                                             inSize,
+                                             reinterpret_cast<int16_t *> (wView.data()),
+                                             kMaxOpusOutputPacketSizeSamples,
+                                             0);
+    if (numSamples < 0) {
+        ALOGE("opus_multistream_decode returned numSamples %d", numSamples);
+        numSamples = 0;
+        mSignalledError = true;
+        work->result = C2_CORRUPTED;
+        return;
+    }
+
+    int outOffset = 0;
+    if (mSamplesToDiscard > 0) {
+        if (mSamplesToDiscard > numSamples) {
+            mSamplesToDiscard -= numSamples;
+            numSamples = 0;
+        } else {
+            numSamples -= mSamplesToDiscard;
+            outOffset = mSamplesToDiscard * sizeof(int16_t) * mHeader.channels;
+            mSamplesToDiscard = 0;
+        }
+    }
+
+    if (numSamples) {
+        int outSize = numSamples * sizeof(int16_t) * mHeader.channels;
+        ALOGV("out buffer attr. offset %d size %d ", outOffset, outSize);
+
+        work->worklets.front()->output.flags = work->input.flags;
+        work->worklets.front()->output.buffers.clear();
+        work->worklets.front()->output.buffers.push_back(createLinearBuffer(block, outOffset, outSize));
+        work->worklets.front()->output.ordinal = work->input.ordinal;
+        work->workletsProcessed = 1u;
+    } else {
+        fillEmptyWork(work);
+        block.reset();
+    }
+    if (eos) {
+        mSignalledOutputEos = true;
+        ALOGV("signalled EOS");
+    }
+}
+
+class C2SoftOpusDecFactory : public C2ComponentFactory {
+public:
+    C2SoftOpusDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+            GetCodec2PlatformComponentStore()->getParamReflector())) {
+    }
+
+    virtual c2_status_t createComponent(
+            c2_node_id_t id,
+            std::shared_ptr<C2Component>* const component,
+            std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+                new C2SoftOpusDec(COMPONENT_NAME,
+                               id,
+                               std::make_shared<C2SoftOpusDec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+            c2_node_id_t id,
+            std::shared_ptr<C2ComponentInterface>* const interface,
+            std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+                new SimpleInterface<C2SoftOpusDec::IntfImpl>(
+                        COMPONENT_NAME, id, std::make_shared<C2SoftOpusDec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftOpusDecFactory() override = default;
+
+private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftOpusDecFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/opus/C2SoftOpusDec.h b/media/codec2/components/opus/C2SoftOpusDec.h
new file mode 100644
index 0000000..b0715ac
--- /dev/null
+++ b/media/codec2/components/opus/C2SoftOpusDec.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_OPUS_DEC_H_
+#define ANDROID_C2_SOFT_OPUS_DEC_H_
+
+#include <SimpleC2Component.h>
+
+
+struct OpusMSDecoder;
+
+namespace android {
+
+struct C2SoftOpusDec : public SimpleC2Component {
+    class IntfImpl;
+
+    C2SoftOpusDec(const char *name, c2_node_id_t id,
+               const std::shared_ptr<IntfImpl> &intfImpl);
+    virtual ~C2SoftOpusDec();
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+    c2_status_t drain(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+private:
+    enum {
+        kMaxNumSamplesPerBuffer = 960 * 6
+    };
+
+    std::shared_ptr<IntfImpl> mIntf;
+    OpusMSDecoder *mDecoder;
+    OpusHeader mHeader;
+
+    int64_t mCodecDelay;
+    int64_t mSeekPreRoll;
+    int64_t mSamplesToDiscard;
+    size_t mInputBufferCount;
+    bool mSignalledError;
+    bool mSignalledOutputEos;
+
+    status_t initDecoder();
+
+    C2_DO_NOT_COPY(C2SoftOpusDec);
+};
+
+}  // namespace android
+
+#endif  // ANDROID_C2_SOFT_OPUS_DEC_H_
diff --git a/media/codec2/components/opus/C2SoftOpusEnc.cpp b/media/codec2/components/opus/C2SoftOpusEnc.cpp
new file mode 100644
index 0000000..70d1965
--- /dev/null
+++ b/media/codec2/components/opus/C2SoftOpusEnc.cpp
@@ -0,0 +1,637 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftOpusEnc"
+#include <utils/Log.h>
+
+#include <C2PlatformSupport.h>
+#include <SimpleC2Interface.h>
+#include <media/stagefright/foundation/MediaDefs.h>
+#include <media/stagefright/foundation/OpusHeader.h>
+#include "C2SoftOpusEnc.h"
+
+extern "C" {
+    #include <opus.h>
+    #include <opus_multistream.h>
+}
+
+#define DEFAULT_FRAME_DURATION_MS 20
+namespace android {
+
+namespace {
+
+constexpr char COMPONENT_NAME[] = "c2.android.opus.encoder";
+
+}  // namespace
+
+static const int kMaxNumChannelsSupported = 2;
+
+class C2SoftOpusEnc::IntfImpl : public SimpleInterface<void>::BaseParams {
+public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+        : SimpleInterface<void>::BaseParams(
+                helper,
+                COMPONENT_NAME,
+                C2Component::KIND_ENCODER,
+                C2Component::DOMAIN_AUDIO,
+                MEDIA_MIMETYPE_AUDIO_OPUS) {
+        noPrivateBuffers();
+        noInputReferences();
+        noOutputReferences();
+        noInputLatency();
+        noTimeStretch();
+        setDerivedInstance(this);
+
+        addParameter(
+                DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                .withConstValue(new C2ComponentAttributesSetting(
+                    C2Component::ATTRIB_IS_TEMPORAL))
+                .build());
+
+        addParameter(
+                DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE)
+                .withDefault(new C2StreamSampleRateInfo::input(0u, 48000))
+                .withFields({C2F(mSampleRate, value).oneOf({
+                    8000, 12000, 16000, 24000, 48000})})
+                .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
+                .build());
+
+        addParameter(
+                DefineParam(mChannelCount, C2_PARAMKEY_CHANNEL_COUNT)
+                .withDefault(new C2StreamChannelCountInfo::input(0u, 1))
+                .withFields({C2F(mChannelCount, value).inRange(1, kMaxNumChannelsSupported)})
+                .withSetter((Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps))
+                .build());
+
+        addParameter(
+                DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
+                .withDefault(new C2StreamBitrateInfo::output(0u, 128000))
+                .withFields({C2F(mBitrate, value).inRange(500, 512000)})
+                .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mComplexity, C2_PARAMKEY_COMPLEXITY)
+                .withDefault(new C2StreamComplexityTuning::output(0u, 10))
+                .withFields({C2F(mComplexity, value).inRange(1, 10)})
+                .withSetter(Setter<decltype(*mComplexity)>::NonStrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
+                .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 3840))
+                .build());
+    }
+
+    uint32_t getSampleRate() const { return mSampleRate->value; }
+    uint32_t getChannelCount() const { return mChannelCount->value; }
+    uint32_t getBitrate() const { return mBitrate->value; }
+    uint32_t getComplexity() const { return mComplexity->value; }
+
+private:
+    std::shared_ptr<C2StreamSampleRateInfo::input> mSampleRate;
+    std::shared_ptr<C2StreamChannelCountInfo::input> mChannelCount;
+    std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
+    std::shared_ptr<C2StreamComplexityTuning::output> mComplexity;
+    std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
+};
+
+C2SoftOpusEnc::C2SoftOpusEnc(const char* name, c2_node_id_t id,
+                               const std::shared_ptr<IntfImpl>& intfImpl)
+    : SimpleC2Component(
+          std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+      mIntf(intfImpl),
+      mOutputBlock(nullptr),
+      mEncoder(nullptr),
+      mInputBufferPcm16(nullptr),
+      mOutIndex(0u) {
+}
+
+C2SoftOpusEnc::~C2SoftOpusEnc() {
+    onRelease();
+}
+
+c2_status_t C2SoftOpusEnc::onInit() {
+    return initEncoder();
+}
+
+c2_status_t C2SoftOpusEnc::configureEncoder() {
+    static const unsigned char mono_mapping[256] = {0};
+    static const unsigned char stereo_mapping[256] = {0, 1};
+    mSampleRate = mIntf->getSampleRate();
+    mChannelCount = mIntf->getChannelCount();
+    uint32_t bitrate = mIntf->getBitrate();
+    int complexity = mIntf->getComplexity();
+    mNumSamplesPerFrame = mSampleRate / (1000 / mFrameDurationMs);
+    mNumPcmBytesPerInputFrame =
+        mChannelCount * mNumSamplesPerFrame * sizeof(int16_t);
+    int err = C2_OK;
+
+    const unsigned char* mapping;
+    if (mChannelCount == 1) {
+        mapping = mono_mapping;
+    } else if (mChannelCount == 2) {
+        mapping = stereo_mapping;
+    } else {
+        ALOGE("Number of channels (%d) is not supported", mChannelCount);
+        return C2_BAD_VALUE;
+    }
+
+    if (mEncoder != nullptr) {
+        opus_multistream_encoder_destroy(mEncoder);
+    }
+
+    mEncoder = opus_multistream_encoder_create(mSampleRate, mChannelCount,
+        1, mChannelCount - 1, mapping, OPUS_APPLICATION_AUDIO, &err);
+    if (err) {
+        ALOGE("Could not create libopus encoder. Error code: %i", err);
+        return C2_CORRUPTED;
+    }
+
+    // Complexity
+    if (opus_multistream_encoder_ctl(
+            mEncoder, OPUS_SET_COMPLEXITY(complexity)) != OPUS_OK) {
+        ALOGE("failed to set complexity");
+        return C2_BAD_VALUE;
+    }
+
+    // DTX
+    if (opus_multistream_encoder_ctl(mEncoder, OPUS_SET_DTX(0) != OPUS_OK)) {
+        ALOGE("failed to set dtx");
+        return C2_BAD_VALUE;
+    }
+
+    // Application
+    if (opus_multistream_encoder_ctl(mEncoder,
+            OPUS_SET_APPLICATION(OPUS_APPLICATION_AUDIO)) != OPUS_OK) {
+        ALOGE("failed to set application");
+        return C2_BAD_VALUE;
+    }
+
+    // Signal type
+    if (opus_multistream_encoder_ctl(mEncoder, OPUS_SET_SIGNAL(OPUS_AUTO)) !=
+        OPUS_OK) {
+        ALOGE("failed to set signal");
+        return C2_BAD_VALUE;
+    }
+
+    // Constrained VBR
+    if (opus_multistream_encoder_ctl(mEncoder, OPUS_SET_VBR(1) != OPUS_OK)) {
+        ALOGE("failed to set vbr type");
+        return C2_BAD_VALUE;
+    }
+    if (opus_multistream_encoder_ctl(mEncoder, OPUS_SET_VBR_CONSTRAINT(1) !=
+            OPUS_OK)) {
+        ALOGE("failed to set vbr constraint");
+        return C2_BAD_VALUE;
+    }
+
+    // Bitrate
+    if (opus_multistream_encoder_ctl(mEncoder, OPUS_SET_BITRATE(bitrate)) !=
+            OPUS_OK) {
+        ALOGE("failed to set bitrate");
+        return C2_BAD_VALUE;
+    }
+
+    // Set seek preroll to 80 ms
+    mSeekPreRoll = 80000000;
+    return C2_OK;
+}
+
+c2_status_t C2SoftOpusEnc::initEncoder() {
+    mSignalledEos = false;
+    mSignalledError = false;
+    mHeaderGenerated = false;
+    mIsFirstFrame = true;
+    mEncoderFlushed = false;
+    mBufferAvailable = false;
+    mAnchorTimeStamp = 0ull;
+    mProcessedSamples = 0;
+    mFilledLen = 0;
+    mFrameDurationMs = DEFAULT_FRAME_DURATION_MS;
+    if (!mInputBufferPcm16) {
+        mInputBufferPcm16 =
+            (int16_t*)malloc(kFrameSize * kMaxNumChannels * sizeof(int16_t));
+    }
+    if (!mInputBufferPcm16) return C2_NO_MEMORY;
+
+    /* Default Configurations */
+    c2_status_t status = configureEncoder();
+    return status;
+}
+
+c2_status_t C2SoftOpusEnc::onStop() {
+    mSignalledEos = false;
+    mSignalledError = false;
+    mIsFirstFrame = true;
+    mEncoderFlushed = false;
+    mBufferAvailable = false;
+    mAnchorTimeStamp = 0ull;
+    mProcessedSamples = 0u;
+    mFilledLen = 0;
+    if (mEncoder) {
+        int status = opus_multistream_encoder_ctl(mEncoder, OPUS_RESET_STATE);
+        if (status != OPUS_OK) {
+            ALOGE("OPUS_RESET_STATE failed status = %s", opus_strerror(status));
+            mSignalledError = true;
+            return C2_CORRUPTED;
+        }
+    }
+    if (mOutputBlock) mOutputBlock.reset();
+    mOutputBlock = nullptr;
+
+    return C2_OK;
+}
+
+void C2SoftOpusEnc::onReset() {
+    (void)onStop();
+}
+
+void C2SoftOpusEnc::onRelease() {
+    (void)onStop();
+    if (mInputBufferPcm16) {
+        free(mInputBufferPcm16);
+        mInputBufferPcm16 = nullptr;
+    }
+    if (mEncoder) {
+        opus_multistream_encoder_destroy(mEncoder);
+        mEncoder = nullptr;
+    }
+}
+
+c2_status_t C2SoftOpusEnc::onFlush_sm() {
+    return onStop();
+}
+
+// Drain the encoder to get last frames (if any)
+int C2SoftOpusEnc::drainEncoder(uint8_t* outPtr) {
+    memset((uint8_t *)mInputBufferPcm16 + mFilledLen, 0,
+        (mNumPcmBytesPerInputFrame - mFilledLen));
+    int encodedBytes = opus_multistream_encode(
+        mEncoder, mInputBufferPcm16, mNumSamplesPerFrame, outPtr, kMaxPayload);
+    if (encodedBytes > mOutputBlock->capacity()) {
+        ALOGE("not enough space left to write encoded data, dropping %d bytes",
+              mBytesEncoded);
+        // a fatal error would stop the encoding
+        return -1;
+    }
+    ALOGV("encoded %i Opus bytes from %zu PCM bytes", encodedBytes,
+          mNumPcmBytesPerInputFrame);
+    mEncoderFlushed = true;
+    mFilledLen = 0;
+    return encodedBytes;
+}
+
+void C2SoftOpusEnc::process(const std::unique_ptr<C2Work>& work,
+                            const std::shared_ptr<C2BlockPool>& pool) {
+    // Initialize output work
+    work->result = C2_OK;
+    work->workletsProcessed = 1u;
+    work->worklets.front()->output.flags = work->input.flags;
+
+    if (mSignalledError || mSignalledEos) {
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+
+    bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
+    C2ReadView rView = mDummyReadView;
+    size_t inOffset = 0u;
+    size_t inSize = 0u;
+    c2_status_t err = C2_OK;
+    if (!work->input.buffers.empty()) {
+        rView =
+            work->input.buffers[0]->data().linearBlocks().front().map().get();
+        inSize = rView.capacity();
+        if (inSize && rView.error()) {
+            ALOGE("read view map failed %d", rView.error());
+            work->result = C2_CORRUPTED;
+            return;
+        }
+    }
+
+    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
+          inSize, (int)work->input.ordinal.timestamp.peeku(),
+          (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
+
+    if (!mEncoder) {
+        if (initEncoder() != C2_OK) {
+            ALOGE("initEncoder failed with status %d", err);
+            work->result = err;
+            mSignalledError = true;
+            return;
+        }
+    }
+    if (mIsFirstFrame && inSize > 0) {
+        mAnchorTimeStamp = work->input.ordinal.timestamp.peekull();
+        mIsFirstFrame = false;
+    }
+
+    C2MemoryUsage usage = {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE};
+    err = pool->fetchLinearBlock(kMaxPayload, usage, &mOutputBlock);
+    if (err != C2_OK) {
+        ALOGE("fetchLinearBlock for Output failed with status %d", err);
+        work->result = C2_NO_MEMORY;
+        return;
+    }
+
+    C2WriteView wView = mOutputBlock->map().get();
+    if (wView.error()) {
+        ALOGE("write view map failed %d", wView.error());
+        work->result = C2_CORRUPTED;
+        mOutputBlock.reset();
+        return;
+    }
+
+    size_t inPos = 0;
+    size_t processSize = 0;
+    mBytesEncoded = 0;
+    uint64_t outTimeStamp = 0u;
+    std::shared_ptr<C2Buffer> buffer;
+    uint64_t inputIndex = work->input.ordinal.frameIndex.peeku();
+    const uint8_t* inPtr = rView.data() + inOffset;
+
+    class FillWork {
+    public:
+        FillWork(uint32_t flags, C2WorkOrdinalStruct ordinal,
+                 const std::shared_ptr<C2Buffer> &buffer)
+            : mFlags(flags), mOrdinal(ordinal), mBuffer(buffer) {
+        }
+        ~FillWork() = default;
+
+        void operator()(const std::unique_ptr<C2Work>& work) {
+            work->worklets.front()->output.flags = (C2FrameData::flags_t)mFlags;
+            work->worklets.front()->output.buffers.clear();
+            work->worklets.front()->output.ordinal = mOrdinal;
+            work->workletsProcessed = 1u;
+            work->result = C2_OK;
+            if (mBuffer) {
+                work->worklets.front()->output.buffers.push_back(mBuffer);
+            }
+            ALOGV("timestamp = %lld, index = %lld, w/%s buffer",
+                  mOrdinal.timestamp.peekll(),
+                  mOrdinal.frameIndex.peekll(),
+                  mBuffer ? "" : "o");
+        }
+
+    private:
+        const uint32_t mFlags;
+        const C2WorkOrdinalStruct mOrdinal;
+        const std::shared_ptr<C2Buffer> mBuffer;
+    };
+
+    C2WorkOrdinalStruct outOrdinal = work->input.ordinal;
+
+    if (!mHeaderGenerated) {
+        uint8_t header[AOPUS_UNIFIED_CSD_MAXSIZE];
+        memset(header, 0, sizeof(header));
+
+        // Get codecDelay
+        int32_t lookahead;
+        if (opus_multistream_encoder_ctl(mEncoder, OPUS_GET_LOOKAHEAD(&lookahead)) !=
+                OPUS_OK) {
+            ALOGE("failed to get lookahead");
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+        mCodecDelay = lookahead * 1000000000ll / mSampleRate;
+
+        OpusHeader opusHeader;
+        memset(&opusHeader, 0, sizeof(opusHeader));
+        opusHeader.channels = mChannelCount;
+        opusHeader.num_streams = mChannelCount;
+        opusHeader.num_coupled = 0;
+        opusHeader.channel_mapping = ((mChannelCount > 8) ? 255 : (mChannelCount > 2));
+        opusHeader.gain_db = 0;
+        opusHeader.skip_samples = lookahead;
+        int headerLen = WriteOpusHeaders(opusHeader, mSampleRate, header,
+            sizeof(header), mCodecDelay, mSeekPreRoll);
+
+        std::unique_ptr<C2StreamInitDataInfo::output> csd =
+            C2StreamInitDataInfo::output::AllocUnique(headerLen, 0u);
+        if (!csd) {
+            ALOGE("CSD allocation failed");
+            mSignalledError = true;
+            work->result = C2_NO_MEMORY;
+            return;
+        }
+        ALOGV("put csd, %d bytes", headerLen);
+        memcpy(csd->m.value, header, headerLen);
+        work->worklets.front()->output.configUpdate.push_back(std::move(csd));
+        mHeaderGenerated = true;
+    }
+
+    /*
+     * For buffer size which is not a multiple of mNumPcmBytesPerInputFrame, we will
+     * accumulate the input and keep it. Once the input is filled with expected number
+     * of bytes, we will send it to encoder. mFilledLen manages the bytes of input yet
+     * to be processed. The next call will fill mNumPcmBytesPerInputFrame - mFilledLen
+     * bytes to input and send it to the encoder.
+     */
+    while (inPos < inSize) {
+        const uint8_t* pcmBytes = inPtr + inPos;
+        int filledSamples = mFilledLen / sizeof(int16_t);
+        if ((inPos + (mNumPcmBytesPerInputFrame - mFilledLen)) <= inSize) {
+            processSize = mNumPcmBytesPerInputFrame - mFilledLen;
+            mBufferAvailable = true;
+        } else {
+            processSize = inSize - inPos;
+            mBufferAvailable = false;
+            if (eos) {
+                memset(mInputBufferPcm16 + filledSamples, 0,
+                       (mNumPcmBytesPerInputFrame - mFilledLen));
+                mBufferAvailable = true;
+            }
+        }
+        const unsigned nInputSamples = processSize / sizeof(int16_t);
+
+        for (unsigned i = 0; i < nInputSamples; i++) {
+            int32_t data = pcmBytes[2 * i + 1] << 8 | pcmBytes[2 * i];
+            data = ((data & 0xFFFF) ^ 0x8000) - 0x8000;
+            mInputBufferPcm16[i + filledSamples] = data;
+        }
+        inPos += processSize;
+        mFilledLen += processSize;
+        if (!mBufferAvailable) break;
+        uint8_t* outPtr = wView.data() + mBytesEncoded;
+        int encodedBytes =
+            opus_multistream_encode(mEncoder, mInputBufferPcm16,
+                                    mNumSamplesPerFrame, outPtr, kMaxPayload - mBytesEncoded);
+        ALOGV("encoded %i Opus bytes from %zu PCM bytes", encodedBytes,
+              processSize);
+
+        if (encodedBytes < 0 || encodedBytes > (kMaxPayload - mBytesEncoded)) {
+            ALOGE("opus_encode failed, encodedBytes : %d", encodedBytes);
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+        if (buffer) {
+            outOrdinal.frameIndex = mOutIndex++;
+            outOrdinal.timestamp = mAnchorTimeStamp + outTimeStamp;
+            cloneAndSend(
+                inputIndex, work,
+                FillWork(C2FrameData::FLAG_INCOMPLETE, outOrdinal, buffer));
+            buffer.reset();
+        }
+        if (encodedBytes > 0) {
+            buffer =
+                createLinearBuffer(mOutputBlock, mBytesEncoded, encodedBytes);
+        }
+        mBytesEncoded += encodedBytes;
+        mProcessedSamples += (filledSamples + nInputSamples);
+        outTimeStamp =
+            mProcessedSamples * 1000000ll / mChannelCount / mSampleRate;
+        if ((processSize + mFilledLen) < mNumPcmBytesPerInputFrame)
+            mEncoderFlushed = true;
+        mFilledLen = 0;
+    }
+
+    uint32_t flags = 0;
+    if (eos) {
+        ALOGV("signalled eos");
+        mSignalledEos = true;
+        if (!mEncoderFlushed) {
+            if (buffer) {
+                outOrdinal.frameIndex = mOutIndex++;
+                outOrdinal.timestamp = mAnchorTimeStamp + outTimeStamp;
+                cloneAndSend(
+                    inputIndex, work,
+                    FillWork(C2FrameData::FLAG_INCOMPLETE, outOrdinal, buffer));
+                buffer.reset();
+            }
+            // drain the encoder for last buffer
+            drainInternal(pool, work);
+        }
+        flags = C2FrameData::FLAG_END_OF_STREAM;
+    }
+    if (buffer) {
+        outOrdinal.frameIndex = mOutIndex++;
+        outOrdinal.timestamp = mAnchorTimeStamp + outTimeStamp;
+        FillWork((C2FrameData::flags_t)(flags), outOrdinal, buffer)(work);
+        buffer.reset();
+    }
+    mOutputBlock = nullptr;
+}
+
+c2_status_t C2SoftOpusEnc::drainInternal(
+        const std::shared_ptr<C2BlockPool>& pool,
+        const std::unique_ptr<C2Work>& work) {
+    mBytesEncoded = 0;
+    std::shared_ptr<C2Buffer> buffer = nullptr;
+    C2WorkOrdinalStruct outOrdinal = work->input.ordinal;
+    bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
+
+    C2MemoryUsage usage = {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE};
+    c2_status_t err = pool->fetchLinearBlock(kMaxPayload, usage, &mOutputBlock);
+    if (err != C2_OK) {
+        ALOGE("fetchLinearBlock for Output failed with status %d", err);
+        return C2_NO_MEMORY;
+    }
+
+    C2WriteView wView = mOutputBlock->map().get();
+    if (wView.error()) {
+        ALOGE("write view map failed %d", wView.error());
+        mOutputBlock.reset();
+        return C2_CORRUPTED;
+    }
+
+    int encBytes = drainEncoder(wView.data());
+    if (encBytes > 0) mBytesEncoded += encBytes;
+    if (mBytesEncoded > 0) {
+        buffer = createLinearBuffer(mOutputBlock, 0, mBytesEncoded);
+        mOutputBlock.reset();
+    }
+    mProcessedSamples += (mNumPcmBytesPerInputFrame / sizeof(int16_t));
+    uint64_t outTimeStamp =
+        mProcessedSamples * 1000000ll / mChannelCount / mSampleRate;
+    outOrdinal.frameIndex = mOutIndex++;
+    outOrdinal.timestamp = mAnchorTimeStamp + outTimeStamp;
+    work->worklets.front()->output.flags =
+        (C2FrameData::flags_t)(eos ? C2FrameData::FLAG_END_OF_STREAM : 0);
+    work->worklets.front()->output.buffers.clear();
+    work->worklets.front()->output.ordinal = outOrdinal;
+    work->workletsProcessed = 1u;
+    work->result = C2_OK;
+    if (buffer) {
+        work->worklets.front()->output.buffers.push_back(buffer);
+    }
+    mOutputBlock = nullptr;
+    return C2_OK;
+}
+
+c2_status_t C2SoftOpusEnc::drain(uint32_t drainMode,
+                                 const std::shared_ptr<C2BlockPool>& pool) {
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+    mIsFirstFrame = true;
+    mAnchorTimeStamp = 0ull;
+    mProcessedSamples = 0u;
+    return drainInternal(pool, nullptr);
+}
+
+class C2SoftOpusEncFactory : public C2ComponentFactory {
+public:
+    C2SoftOpusEncFactory()
+        : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+              GetCodec2PlatformComponentStore()->getParamReflector())) {}
+
+    virtual c2_status_t createComponent(
+        c2_node_id_t id, std::shared_ptr<C2Component>* const component,
+        std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+            new C2SoftOpusEnc(
+                COMPONENT_NAME, id,
+                std::make_shared<C2SoftOpusEnc::IntfImpl>(mHelper)),
+            deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+        c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
+        std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+            new SimpleInterface<C2SoftOpusEnc::IntfImpl>(
+                COMPONENT_NAME, id,
+                std::make_shared<C2SoftOpusEnc::IntfImpl>(mHelper)),
+            deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftOpusEncFactory() override = default;
+private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftOpusEncFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/opus/C2SoftOpusEnc.h b/media/codec2/components/opus/C2SoftOpusEnc.h
new file mode 100644
index 0000000..2b4d8f2
--- /dev/null
+++ b/media/codec2/components/opus/C2SoftOpusEnc.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_OPUS_ENC_H_
+#define ANDROID_C2_SOFT_OPUS_ENC_H_
+
+#include <atomic>
+#include <SimpleC2Component.h>
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+struct OpusMSEncoder;
+
+namespace android {
+
+struct C2SoftOpusEnc : public SimpleC2Component {
+    class IntfImpl;
+
+    C2SoftOpusEnc(const char *name, c2_node_id_t id,
+               const std::shared_ptr<IntfImpl> &intfImpl);
+    virtual ~C2SoftOpusEnc();
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+    c2_status_t drain(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+private:
+    /* OPUS_FRAMESIZE_20_MS */
+    const int kFrameSize = 960;
+    const int kMaxSampleRate = 48000;
+    const int kMinSampleRate = 8000;
+    const int kMaxPayload = (4000 * kMaxSampleRate) / kMinSampleRate;
+    const int kMaxNumChannels = 8;
+
+    std::shared_ptr<IntfImpl> mIntf;
+    std::shared_ptr<C2LinearBlock> mOutputBlock;
+
+    OpusMSEncoder* mEncoder;
+    int16_t* mInputBufferPcm16;
+
+    bool mHeaderGenerated;
+    bool mIsFirstFrame;
+    bool mEncoderFlushed;
+    bool mBufferAvailable;
+    bool mSignalledEos;
+    bool mSignalledError;
+    uint32_t mSampleRate;
+    uint32_t mChannelCount;
+    uint32_t mFrameDurationMs;
+    uint64_t mAnchorTimeStamp;
+    uint64_t mProcessedSamples;
+    // Codec delay in ns
+    uint64_t mCodecDelay;
+    // Seek pre-roll in ns
+    uint64_t mSeekPreRoll;
+    int mNumSamplesPerFrame;
+    int mBytesEncoded;
+    int32_t mFilledLen;
+    size_t mNumPcmBytesPerInputFrame;
+    std::atomic_uint64_t mOutIndex;
+    c2_status_t initEncoder();
+    c2_status_t configureEncoder();
+    int drainEncoder(uint8_t* outPtr);
+    c2_status_t drainInternal(const std::shared_ptr<C2BlockPool>& pool,
+                              const std::unique_ptr<C2Work>& work);
+
+    C2_DO_NOT_COPY(C2SoftOpusEnc);
+};
+
+}  // namespace android
+
+#endif  // ANDROID_C2_SOFT_OPUS_ENC_H_
diff --git a/media/codec2/components/raw/Android.bp b/media/codec2/components/raw/Android.bp
new file mode 100644
index 0000000..dc944da
--- /dev/null
+++ b/media/codec2/components/raw/Android.bp
@@ -0,0 +1,9 @@
+cc_library_shared {
+    name: "libcodec2_soft_rawdec",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["C2SoftRawDec.cpp"],
+}
diff --git a/media/codec2/components/raw/C2SoftRawDec.cpp b/media/codec2/components/raw/C2SoftRawDec.cpp
new file mode 100644
index 0000000..95eb909
--- /dev/null
+++ b/media/codec2/components/raw/C2SoftRawDec.cpp
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftRawDec"
+#include <log/log.h>
+
+#include <media/stagefright/foundation/MediaDefs.h>
+
+#include <C2PlatformSupport.h>
+#include <SimpleC2Interface.h>
+
+#include "C2SoftRawDec.h"
+
+namespace android {
+
+namespace {
+
+constexpr char COMPONENT_NAME[] = "c2.android.raw.decoder";
+
+}  // namespace
+
+class C2SoftRawDec::IntfImpl : public SimpleInterface<void>::BaseParams {
+public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+        : SimpleInterface<void>::BaseParams(
+                helper,
+                COMPONENT_NAME,
+                C2Component::KIND_DECODER,
+                C2Component::DOMAIN_AUDIO,
+                MEDIA_MIMETYPE_AUDIO_RAW) {
+        noPrivateBuffers();
+        noInputReferences();
+        noOutputReferences();
+        noInputLatency();
+        noTimeStretch();
+        setDerivedInstance(this);
+
+        addParameter(
+                DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                .withConstValue(new C2ComponentAttributesSetting(
+                    C2Component::ATTRIB_IS_TEMPORAL))
+                .build());
+
+        addParameter(
+                DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE)
+                .withDefault(new C2StreamSampleRateInfo::output(0u, 44100))
+                .withFields({C2F(mSampleRate, value).inRange(8000, 384000)})
+                .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
+                .build());
+
+        addParameter(
+                DefineParam(mChannelCount, C2_PARAMKEY_CHANNEL_COUNT)
+                .withDefault(new C2StreamChannelCountInfo::output(0u, 2))
+                .withFields({C2F(mChannelCount, value).inRange(1, 8)})
+                .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
+                .withDefault(new C2StreamBitrateInfo::input(0u, 64000))
+                .withFields({C2F(mBitrate, value).inRange(1, 98304000)})
+                .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
+                .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 64 * 1024))
+                .build());
+
+        addParameter(
+                DefineParam(mPcmEncodingInfo, C2_PARAMKEY_PCM_ENCODING)
+                .withDefault(new C2StreamPcmEncodingInfo::output(0u, C2Config::PCM_16))
+                .withFields({C2F(mPcmEncodingInfo, value).oneOf({
+                     C2Config::PCM_16,
+                     C2Config::PCM_8,
+                     C2Config::PCM_FLOAT})
+                })
+                .withSetter((Setter<decltype(*mPcmEncodingInfo)>::StrictValueWithNoDeps))
+                .build());
+
+    }
+
+private:
+    std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
+    std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
+    std::shared_ptr<C2StreamBitrateInfo::input> mBitrate;
+    std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
+    std::shared_ptr<C2StreamPcmEncodingInfo::output> mPcmEncodingInfo;
+};
+
+C2SoftRawDec::C2SoftRawDec(
+        const char *name,
+        c2_node_id_t id,
+        const std::shared_ptr<IntfImpl> &intfImpl)
+    : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+      mIntf(intfImpl) {
+}
+
+C2SoftRawDec::~C2SoftRawDec() {
+    onRelease();
+}
+
+c2_status_t C2SoftRawDec::onInit() {
+    mSignalledEos = false;
+    return C2_OK;
+}
+
+c2_status_t C2SoftRawDec::onStop() {
+    mSignalledEos = false;
+    return C2_OK;
+}
+
+void C2SoftRawDec::onReset() {
+    (void)onStop();
+}
+
+void C2SoftRawDec::onRelease() {
+}
+
+c2_status_t C2SoftRawDec::onFlush_sm() {
+    return onStop();
+}
+
+void C2SoftRawDec::process(
+        const std::unique_ptr<C2Work> &work,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    (void)pool;
+    work->result = C2_OK;
+    work->workletsProcessed = 1u;
+
+    if (mSignalledEos) {
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+
+    ALOGV("in buffer attr. timestamp %d frameindex %d",
+          (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
+
+    work->worklets.front()->output.flags = work->input.flags;
+    work->worklets.front()->output.buffers.clear();
+    work->worklets.front()->output.ordinal = work->input.ordinal;
+    if (!work->input.buffers.empty()) {
+        work->worklets.front()->output.buffers.push_back(work->input.buffers[0]);
+    }
+    if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
+        mSignalledEos = true;
+        ALOGV("signalled EOS");
+    }
+}
+
+c2_status_t C2SoftRawDec::drain(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    (void) pool;
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+
+    return C2_OK;
+}
+
+class C2SoftRawDecFactory : public C2ComponentFactory {
+public:
+    C2SoftRawDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+            GetCodec2PlatformComponentStore()->getParamReflector())) {
+    }
+
+    virtual c2_status_t createComponent(
+            c2_node_id_t id,
+            std::shared_ptr<C2Component>* const component,
+            std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+                new C2SoftRawDec(COMPONENT_NAME,
+                              id,
+                              std::make_shared<C2SoftRawDec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+            c2_node_id_t id,
+            std::shared_ptr<C2ComponentInterface>* const interface,
+            std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+                new SimpleInterface<C2SoftRawDec::IntfImpl>(
+                        COMPONENT_NAME, id, std::make_shared<C2SoftRawDec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftRawDecFactory() override = default;
+
+private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftRawDecFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/raw/C2SoftRawDec.h b/media/codec2/components/raw/C2SoftRawDec.h
new file mode 100644
index 0000000..7dfdec5
--- /dev/null
+++ b/media/codec2/components/raw/C2SoftRawDec.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_RAW_DEC_H_
+#define ANDROID_C2_SOFT_RAW_DEC_H_
+
+#include <SimpleC2Component.h>
+
+
+namespace android {
+
+struct C2SoftRawDec : public SimpleC2Component {
+    class IntfImpl;
+
+    C2SoftRawDec(const char* name, c2_node_id_t id,
+              const std::shared_ptr<IntfImpl>& intfImpl);
+    virtual ~C2SoftRawDec();
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+    c2_status_t drain(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+private:
+    std::shared_ptr<IntfImpl> mIntf;
+    bool mSignalledEos;
+
+    C2_DO_NOT_COPY(C2SoftRawDec);
+};
+
+}  // namespace android
+
+#endif  // ANDROID_C2_SOFT_RAW_DEC_H_
diff --git a/media/common_time/MODULE_LICENSE_APACHE2 b/media/codec2/components/raw/MODULE_LICENSE_APACHE2
similarity index 100%
copy from media/common_time/MODULE_LICENSE_APACHE2
copy to media/codec2/components/raw/MODULE_LICENSE_APACHE2
diff --git a/media/common_time/NOTICE b/media/codec2/components/raw/NOTICE
similarity index 100%
copy from media/common_time/NOTICE
copy to media/codec2/components/raw/NOTICE
diff --git a/media/codec2/components/vorbis/Android.bp b/media/codec2/components/vorbis/Android.bp
new file mode 100644
index 0000000..a5f485d
--- /dev/null
+++ b/media/codec2/components/vorbis/Android.bp
@@ -0,0 +1,11 @@
+cc_library_shared {
+    name: "libcodec2_soft_vorbisdec",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["C2SoftVorbisDec.cpp"],
+
+    shared_libs: ["libvorbisidec"],
+}
diff --git a/media/codec2/components/vorbis/C2SoftVorbisDec.cpp b/media/codec2/components/vorbis/C2SoftVorbisDec.cpp
new file mode 100644
index 0000000..18e6db2
--- /dev/null
+++ b/media/codec2/components/vorbis/C2SoftVorbisDec.cpp
@@ -0,0 +1,484 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftVorbisDec"
+#include <log/log.h>
+
+#include <media/stagefright/foundation/MediaDefs.h>
+
+#include <C2PlatformSupport.h>
+#include <SimpleC2Interface.h>
+
+#include "C2SoftVorbisDec.h"
+
+extern "C" {
+    #include <Tremolo/codec_internal.h>
+
+    int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb);
+    int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb);
+    int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb);
+}
+
+namespace android {
+
+namespace {
+
+constexpr char COMPONENT_NAME[] = "c2.android.vorbis.decoder";
+
+}  // namespace
+
+class C2SoftVorbisDec::IntfImpl : public SimpleInterface<void>::BaseParams {
+public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+        : SimpleInterface<void>::BaseParams(
+                helper,
+                COMPONENT_NAME,
+                C2Component::KIND_DECODER,
+                C2Component::DOMAIN_AUDIO,
+                MEDIA_MIMETYPE_AUDIO_VORBIS) {
+        noPrivateBuffers();
+        noInputReferences();
+        noOutputReferences();
+        noInputLatency();
+        noTimeStretch();
+        setDerivedInstance(this);
+
+        addParameter(
+                DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                .withConstValue(new C2ComponentAttributesSetting(
+                    C2Component::ATTRIB_IS_TEMPORAL))
+                .build());
+
+        addParameter(
+                DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE)
+                .withDefault(new C2StreamSampleRateInfo::output(0u, 48000))
+                .withFields({C2F(mSampleRate, value).inRange(8000, 96000)})
+                .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
+                .build());
+
+        addParameter(
+                DefineParam(mChannelCount, C2_PARAMKEY_CHANNEL_COUNT)
+                .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
+                .withFields({C2F(mChannelCount, value).inRange(1, 8)})
+                .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
+                .withDefault(new C2StreamBitrateInfo::input(0u, 64000))
+                .withFields({C2F(mBitrate, value).inRange(32000, 500000)})
+                .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
+                .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 8192 * 2 * sizeof(int16_t)))
+                .build());
+    }
+
+private:
+    std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
+    std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
+    std::shared_ptr<C2StreamBitrateInfo::input> mBitrate;
+    std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
+};
+
+C2SoftVorbisDec::C2SoftVorbisDec(
+        const char *name,
+        c2_node_id_t id,
+        const std::shared_ptr<IntfImpl> &intfImpl)
+    : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+      mIntf(intfImpl),
+      mState(nullptr),
+      mVi(nullptr) {
+}
+
+C2SoftVorbisDec::~C2SoftVorbisDec() {
+    onRelease();
+}
+
+c2_status_t C2SoftVorbisDec::onInit() {
+    status_t err = initDecoder();
+    return err == OK ? C2_OK : C2_NO_MEMORY;
+}
+
+c2_status_t C2SoftVorbisDec::onStop() {
+    if (mState) {
+        vorbis_dsp_clear(mState);
+        delete mState;
+        mState = nullptr;
+    }
+
+    if (mVi) {
+        vorbis_info_clear(mVi);
+        delete mVi;
+        mVi = nullptr;
+    }
+    mNumFramesLeftOnPage = -1;
+    mSignalledOutputEos = false;
+    mSignalledError = false;
+
+    return (initDecoder() == OK ? C2_OK : C2_CORRUPTED);
+}
+
+void C2SoftVorbisDec::onReset() {
+    (void)onStop();
+}
+
+void C2SoftVorbisDec::onRelease() {
+    if (mState) {
+        vorbis_dsp_clear(mState);
+        delete mState;
+        mState = nullptr;
+    }
+
+    if (mVi) {
+        vorbis_info_clear(mVi);
+        delete mVi;
+        mVi = nullptr;
+    }
+}
+
+status_t C2SoftVorbisDec::initDecoder() {
+    mVi = new vorbis_info{};
+    if (!mVi) return NO_MEMORY;
+    vorbis_info_clear(mVi);
+
+    mState = new vorbis_dsp_state{};
+    if (!mState) return NO_MEMORY;
+    vorbis_dsp_clear(mState);
+
+    mNumFramesLeftOnPage = -1;
+    mSignalledError = false;
+    mSignalledOutputEos = false;
+    mInfoUnpacked = false;
+    mBooksUnpacked = false;
+    return OK;
+}
+
+c2_status_t C2SoftVorbisDec::onFlush_sm() {
+    mNumFramesLeftOnPage = -1;
+    mSignalledOutputEos = false;
+    if (mState) vorbis_dsp_restart(mState);
+
+    return C2_OK;
+}
+
+c2_status_t C2SoftVorbisDec::drain(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    (void) pool;
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+
+    return C2_OK;
+}
+
+static void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
+    work->worklets.front()->output.flags = work->input.flags;
+    work->worklets.front()->output.buffers.clear();
+    work->worklets.front()->output.ordinal = work->input.ordinal;
+    work->workletsProcessed = 1u;
+}
+
+static void makeBitReader(
+        const void *data, size_t size,
+        ogg_buffer *buf, ogg_reference *ref, oggpack_buffer *bits) {
+    buf->data = (uint8_t *)data;
+    buf->size = size;
+    buf->refcount = 1;
+    buf->ptr.owner = nullptr;
+
+    ref->buffer = buf;
+    ref->begin = 0;
+    ref->length = size;
+    ref->next = nullptr;
+
+    oggpack_readinit(bits, ref);
+}
+
+// (CHECK!) multiframe is tricky. decode call doesnt return the number of bytes
+// consumed by the component. Also it is unclear why numPageFrames is being
+// tagged at the end of input buffers for new pages. Refer lines 297-300 in
+// SimpleDecodingSource.cpp
+void C2SoftVorbisDec::process(
+        const std::unique_ptr<C2Work> &work,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    // Initialize output work
+    work->result = C2_OK;
+    work->workletsProcessed = 1u;
+    work->worklets.front()->output.configUpdate.clear();
+    work->worklets.front()->output.flags = work->input.flags;
+
+    if (mSignalledError || mSignalledOutputEos) {
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+
+    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
+    size_t inOffset = 0u;
+    size_t inSize = 0u;
+    C2ReadView rView = mDummyReadView;
+    if (!work->input.buffers.empty()) {
+        rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
+        inSize = rView.capacity();
+        if (inSize && rView.error()) {
+            ALOGE("read view map failed %d", rView.error());
+            work->result = rView.error();
+            return;
+        }
+    }
+
+    if (inSize == 0) {
+        fillEmptyWork(work);
+        if (eos) {
+            mSignalledOutputEos = true;
+            ALOGV("signalled EOS");
+        }
+        return;
+    }
+
+    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
+          (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
+    const uint8_t *data = rView.data() + inOffset;
+    int32_t numChannels  = mVi->channels;
+    int32_t samplingRate = mVi->rate;
+    /* Decode vorbis headers only once */
+    if (inSize > 7 && !memcmp(&data[1], "vorbis", 6) && (!mInfoUnpacked || !mBooksUnpacked)) {
+        if ((data[0] != 1) && (data[0] != 5)) {
+            ALOGE("unexpected type received %d", data[0]);
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+
+        ogg_buffer buf;
+        ogg_reference ref;
+        oggpack_buffer bits;
+
+        // skip 7 <type + "vorbis"> bytes
+        makeBitReader((const uint8_t *)data + 7, inSize - 7, &buf, &ref, &bits);
+        if (data[0] == 1) {
+            vorbis_info_init(mVi);
+            if (0 != _vorbis_unpack_info(mVi, &bits)) {
+                ALOGE("Encountered error while unpacking info");
+                mSignalledError = true;
+                work->result = C2_CORRUPTED;
+                return;
+            }
+            if (mVi->rate != samplingRate ||
+                    mVi->channels != numChannels) {
+                ALOGV("vorbis: rate/channels changed: %ld/%d", mVi->rate, mVi->channels);
+                samplingRate = mVi->rate;
+                numChannels = mVi->channels;
+
+                C2StreamSampleRateInfo::output sampleRateInfo(0u, samplingRate);
+                C2StreamChannelCountInfo::output channelCountInfo(0u, numChannels);
+                std::vector<std::unique_ptr<C2SettingResult>> failures;
+                c2_status_t err = mIntf->config(
+                        { &sampleRateInfo, &channelCountInfo },
+                        C2_MAY_BLOCK,
+                        &failures);
+                if (err == OK) {
+                    work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(sampleRateInfo));
+                    work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(channelCountInfo));
+                } else {
+                    ALOGE("Config Update failed");
+                    mSignalledError = true;
+                    work->result = C2_CORRUPTED;
+                    return;
+                }
+            }
+            mInfoUnpacked = true;
+        } else {
+            if (!mInfoUnpacked) {
+                ALOGE("Data with type:5 sent before sending type:1");
+                mSignalledError = true;
+                work->result = C2_CORRUPTED;
+                return;
+            }
+            if (0 != _vorbis_unpack_books(mVi, &bits)) {
+                ALOGE("Encountered error while unpacking books");
+                mSignalledError = true;
+                work->result = C2_CORRUPTED;
+                return;
+            }
+            if (0 != vorbis_dsp_init(mState, mVi)) {
+                ALOGE("Encountered error while dsp init");
+                mSignalledError = true;
+                work->result = C2_CORRUPTED;
+                return;
+            }
+            mBooksUnpacked = true;
+        }
+        fillEmptyWork(work);
+        if (eos) {
+            mSignalledOutputEos = true;
+            ALOGV("signalled EOS");
+        }
+        return;
+    }
+
+    if (!mInfoUnpacked || !mBooksUnpacked) {
+        ALOGE("Missing CODEC_CONFIG data mInfoUnpacked: %d mBooksUnpack %d", mInfoUnpacked, mBooksUnpacked);
+        mSignalledError = true;
+        work->result = C2_CORRUPTED;
+        return;
+    }
+
+    int32_t numPageFrames = 0;
+    if (inSize < sizeof(numPageFrames)) {
+        ALOGE("input header has size %zu, expected %zu", inSize, sizeof(numPageFrames));
+        mSignalledError = true;
+        work->result = C2_CORRUPTED;
+        return;
+    }
+    memcpy(&numPageFrames, data + inSize - sizeof(numPageFrames), sizeof(numPageFrames));
+    inSize -= sizeof(numPageFrames);
+    if (numPageFrames >= 0) {
+        mNumFramesLeftOnPage = numPageFrames;
+    }
+
+    ogg_buffer buf;
+    buf.data = const_cast<unsigned char*>(data);
+    buf.size = inSize;
+    buf.refcount = 1;
+    buf.ptr.owner = nullptr;
+
+    ogg_reference ref;
+    ref.buffer = &buf;
+    ref.begin = 0;
+    ref.length = buf.size;
+    ref.next = nullptr;
+
+    ogg_packet pack;
+    pack.packet = &ref;
+    pack.bytes = ref.length;
+    pack.b_o_s = 0;
+    pack.e_o_s = 0;
+    pack.granulepos = 0;
+    pack.packetno = 0;
+
+    size_t maxSamplesInBuffer = kMaxNumSamplesPerChannel * mVi->channels;
+    size_t outCapacity =  maxSamplesInBuffer * sizeof(int16_t);
+    std::shared_ptr<C2LinearBlock> block;
+    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+    c2_status_t err = pool->fetchLinearBlock(outCapacity, usage, &block);
+    if (err != C2_OK) {
+        ALOGE("fetchLinearBlock for Output failed with status %d", err);
+        work->result = C2_NO_MEMORY;
+        return;
+    }
+    C2WriteView wView = block->map().get();
+    if (wView.error()) {
+        ALOGE("write view map failed %d", wView.error());
+        work->result = wView.error();
+        return;
+    }
+
+    int numFrames = 0;
+    int ret = vorbis_dsp_synthesis(mState, &pack, 1);
+    if (0 != ret) {
+        ALOGD("vorbis_dsp_synthesis returned %d; ignored", ret);
+    } else {
+        numFrames = vorbis_dsp_pcmout(
+                mState,  reinterpret_cast<int16_t *> (wView.data()),
+                kMaxNumSamplesPerChannel);
+        if (numFrames < 0) {
+            ALOGD("vorbis_dsp_pcmout returned %d", numFrames);
+            numFrames = 0;
+        }
+    }
+
+    if (mNumFramesLeftOnPage >= 0) {
+        if (numFrames > mNumFramesLeftOnPage) {
+            ALOGV("discarding %d frames at end of page", numFrames - mNumFramesLeftOnPage);
+            numFrames = mNumFramesLeftOnPage;
+        }
+        mNumFramesLeftOnPage -= numFrames;
+    }
+
+    if (numFrames) {
+        int outSize = numFrames * sizeof(int16_t) * mVi->channels;
+
+        work->worklets.front()->output.flags = work->input.flags;
+        work->worklets.front()->output.buffers.clear();
+        work->worklets.front()->output.buffers.push_back(createLinearBuffer(block, 0, outSize));
+        work->worklets.front()->output.ordinal = work->input.ordinal;
+        work->workletsProcessed = 1u;
+    } else {
+        fillEmptyWork(work);
+        block.reset();
+    }
+    if (eos) {
+        mSignalledOutputEos = true;
+        ALOGV("signalled EOS");
+    }
+}
+
+class C2SoftVorbisDecFactory : public C2ComponentFactory {
+public:
+    C2SoftVorbisDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+            GetCodec2PlatformComponentStore()->getParamReflector())) {
+    }
+
+    virtual c2_status_t createComponent(
+            c2_node_id_t id,
+            std::shared_ptr<C2Component>* const component,
+            std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+                new C2SoftVorbisDec(COMPONENT_NAME,
+                              id,
+                              std::make_shared<C2SoftVorbisDec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+            c2_node_id_t id,
+            std::shared_ptr<C2ComponentInterface>* const interface,
+            std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+                new SimpleInterface<C2SoftVorbisDec::IntfImpl>(
+                        COMPONENT_NAME, id, std::make_shared<C2SoftVorbisDec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftVorbisDecFactory() override = default;
+
+private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftVorbisDecFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/vorbis/C2SoftVorbisDec.h b/media/codec2/components/vorbis/C2SoftVorbisDec.h
new file mode 100644
index 0000000..3bf7326
--- /dev/null
+++ b/media/codec2/components/vorbis/C2SoftVorbisDec.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_VORBIS_DEC_H_
+#define ANDROID_C2_SOFT_VORBIS_DEC_H_
+
+#include <SimpleC2Component.h>
+
+
+struct vorbis_dsp_state;
+struct vorbis_info;
+
+namespace android {
+
+struct C2SoftVorbisDec : public SimpleC2Component {
+    class IntfImpl;
+
+    C2SoftVorbisDec(const char *name, c2_node_id_t id,
+                 const std::shared_ptr<IntfImpl> &intfImpl);
+    virtual ~C2SoftVorbisDec();
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+    c2_status_t drain(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+
+ private:
+    enum {
+        kMaxNumSamplesPerChannel = 8192,
+    };
+
+    std::shared_ptr<IntfImpl> mIntf;
+    vorbis_dsp_state *mState;
+    vorbis_info *mVi;
+
+    int32_t mNumFramesLeftOnPage;
+    bool mSignalledError;
+    bool mSignalledOutputEos;
+    bool mInfoUnpacked;
+    bool mBooksUnpacked;
+    status_t initDecoder();
+
+    C2_DO_NOT_COPY(C2SoftVorbisDec);
+};
+
+}  // namespace android
+
+#endif  // ANDROID_C2_SOFT_VORBIS_DEC_H_
+
diff --git a/media/common_time/MODULE_LICENSE_APACHE2 b/media/codec2/components/vorbis/MODULE_LICENSE_APACHE2
similarity index 100%
copy from media/common_time/MODULE_LICENSE_APACHE2
copy to media/codec2/components/vorbis/MODULE_LICENSE_APACHE2
diff --git a/media/common_time/NOTICE b/media/codec2/components/vorbis/NOTICE
similarity index 100%
copy from media/common_time/NOTICE
copy to media/codec2/components/vorbis/NOTICE
diff --git a/media/codec2/components/vpx/Android.bp b/media/codec2/components/vpx/Android.bp
new file mode 100644
index 0000000..34f5753
--- /dev/null
+++ b/media/codec2/components/vpx/Android.bp
@@ -0,0 +1,60 @@
+cc_library_shared {
+    name: "libcodec2_soft_vp9dec",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["C2SoftVpxDec.cpp"],
+
+    shared_libs: ["libvpx"],
+
+    cflags: [
+        "-DVP9",
+    ],
+}
+
+cc_library_shared {
+    name: "libcodec2_soft_vp8dec",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["C2SoftVpxDec.cpp"],
+
+    shared_libs: ["libvpx"],
+}
+
+cc_library_shared {
+    name: "libcodec2_soft_vp9enc",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_all-defaults",
+    ],
+
+    srcs: [
+        "C2SoftVp9Enc.cpp",
+        "C2SoftVpxEnc.cpp",
+    ],
+
+    shared_libs: ["libvpx"],
+
+    cflags: ["-DVP9"],
+}
+
+cc_library_shared {
+    name: "libcodec2_soft_vp8enc",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_all-defaults",
+    ],
+
+    srcs: [
+        "C2SoftVp8Enc.cpp",
+        "C2SoftVpxEnc.cpp",
+    ],
+
+    shared_libs: ["libvpx"],
+}
+
diff --git a/media/codec2/components/vpx/C2SoftVp8Enc.cpp b/media/codec2/components/vpx/C2SoftVp8Enc.cpp
new file mode 100644
index 0000000..f18f5d0
--- /dev/null
+++ b/media/codec2/components/vpx/C2SoftVp8Enc.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftVp8Enc"
+#include <utils/Log.h>
+#include <utils/misc.h>
+
+#include "C2SoftVp8Enc.h"
+
+namespace android {
+
+C2SoftVp8Enc::C2SoftVp8Enc(const char* name, c2_node_id_t id,
+                           const std::shared_ptr<IntfImpl>& intfImpl)
+    : C2SoftVpxEnc(name, id, intfImpl), mDCTPartitions(0), mProfile(1) {}
+
+void C2SoftVp8Enc::setCodecSpecificInterface() {
+    mCodecInterface = vpx_codec_vp8_cx();
+}
+
+void C2SoftVp8Enc::setCodecSpecificConfiguration() {
+    switch (mProfile) {
+        case 1:
+            mCodecConfiguration->g_profile = 0;
+            break;
+
+        case 2:
+            mCodecConfiguration->g_profile = 1;
+            break;
+
+        case 4:
+            mCodecConfiguration->g_profile = 2;
+            break;
+
+        case 8:
+            mCodecConfiguration->g_profile = 3;
+            break;
+
+        default:
+            mCodecConfiguration->g_profile = 0;
+    }
+}
+
+vpx_codec_err_t C2SoftVp8Enc::setCodecSpecificControls() {
+    vpx_codec_err_t codec_return = vpx_codec_control(mCodecContext,
+                                                     VP8E_SET_TOKEN_PARTITIONS,
+                                                     mDCTPartitions);
+    if (codec_return != VPX_CODEC_OK) {
+        ALOGE("Error setting dct partitions for vpx encoder.");
+    }
+    return codec_return;
+}
+
+class C2SoftVp8EncFactory : public C2ComponentFactory {
+public:
+    C2SoftVp8EncFactory()
+        : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+              GetCodec2PlatformComponentStore()->getParamReflector())) {}
+
+    virtual c2_status_t createComponent(
+            c2_node_id_t id,
+            std::shared_ptr<C2Component>* const component,
+            std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+            new C2SoftVp8Enc(COMPONENT_NAME, id,
+                             std::make_shared<C2SoftVpxEnc::IntfImpl>(mHelper)),
+            deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+            c2_node_id_t id,
+            std::shared_ptr<C2ComponentInterface>* const interface,
+            std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+            new SimpleInterface<C2SoftVpxEnc::IntfImpl>(
+                COMPONENT_NAME, id,
+                std::make_shared<C2SoftVpxEnc::IntfImpl>(mHelper)),
+            deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftVp8EncFactory() override = default;
+
+private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftVp8EncFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/vpx/C2SoftVp8Enc.h b/media/codec2/components/vpx/C2SoftVp8Enc.h
new file mode 100644
index 0000000..ed6f356
--- /dev/null
+++ b/media/codec2/components/vpx/C2SoftVp8Enc.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_VP8_ENC_H__
+#define ANDROID_C2_SOFT_VP8_ENC_H__
+
+#include "C2SoftVpxEnc.h"
+
+namespace android {
+
+// Exposes vp8 encoder as a c2 Component
+//
+// In addition to the base class settings, Only following encoder settings are
+// available:
+//    - token partitioning
+struct C2SoftVp8Enc : public C2SoftVpxEnc {
+    C2SoftVp8Enc(const char* name, c2_node_id_t id,
+                 const std::shared_ptr<IntfImpl>& intfImpl);
+
+ protected:
+    // Populates |mCodecInterface| with codec specific settings.
+    virtual void setCodecSpecificInterface();
+
+    // Sets codec specific configuration.
+    virtual void setCodecSpecificConfiguration();
+
+    // Initializes codec specific encoder settings.
+    virtual vpx_codec_err_t setCodecSpecificControls();
+
+ private:
+    // Max value supported for DCT partitions
+    static const uint32_t kMaxDCTPartitions = 3;
+
+    // vp8 specific configuration parameter
+    // that enables token partitioning of
+    // the stream into substreams
+    int32_t mDCTPartitions;
+
+    // C2 Profile parameter
+    int32_t mProfile;
+
+    C2_DO_NOT_COPY(C2SoftVp8Enc);
+};
+
+}  // namespace android
+
+#endif  // ANDROID_C2_SOFT_VP8_ENC_H__
diff --git a/media/codec2/components/vpx/C2SoftVp9Enc.cpp b/media/codec2/components/vpx/C2SoftVp9Enc.cpp
new file mode 100644
index 0000000..740dbda
--- /dev/null
+++ b/media/codec2/components/vpx/C2SoftVp9Enc.cpp
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftVp9Enc"
+#include <utils/Log.h>
+#include <utils/misc.h>
+
+#include "C2SoftVp9Enc.h"
+
+namespace android {
+
+C2SoftVp9Enc::C2SoftVp9Enc(const char* name, c2_node_id_t id,
+                           const std::shared_ptr<IntfImpl>& intfImpl)
+    : C2SoftVpxEnc(name, id, intfImpl),
+      mProfile(1),
+      mLevel(0),
+      mTileColumns(0),
+      mFrameParallelDecoding(false) {
+}
+
+void C2SoftVp9Enc::setCodecSpecificInterface() {
+    mCodecInterface = vpx_codec_vp9_cx();
+}
+
+void C2SoftVp9Enc::setCodecSpecificConfiguration() {
+    switch (mProfile) {
+        case 1:
+            mCodecConfiguration->g_profile = 0;
+            break;
+
+        case 2:
+            mCodecConfiguration->g_profile = 1;
+            break;
+
+        case 4:
+            mCodecConfiguration->g_profile = 2;
+            break;
+
+        case 8:
+            mCodecConfiguration->g_profile = 3;
+            break;
+
+        default:
+            mCodecConfiguration->g_profile = 0;
+    }
+}
+
+vpx_codec_err_t C2SoftVp9Enc::setCodecSpecificControls() {
+    vpx_codec_err_t codecReturn = vpx_codec_control(
+            mCodecContext, VP9E_SET_TILE_COLUMNS, mTileColumns);
+    if (codecReturn != VPX_CODEC_OK) {
+        ALOGE("Error setting VP9E_SET_TILE_COLUMNS to %d. vpx_codec_control() "
+              "returned %d", mTileColumns, codecReturn);
+        return codecReturn;
+    }
+    codecReturn = vpx_codec_control(
+            mCodecContext, VP9E_SET_FRAME_PARALLEL_DECODING,
+            mFrameParallelDecoding);
+    if (codecReturn != VPX_CODEC_OK) {
+        ALOGE("Error setting VP9E_SET_FRAME_PARALLEL_DECODING to %d."
+              "vpx_codec_control() returned %d", mFrameParallelDecoding,
+              codecReturn);
+        return codecReturn;
+    }
+    codecReturn = vpx_codec_control(mCodecContext, VP9E_SET_ROW_MT, 1);
+    if (codecReturn != VPX_CODEC_OK) {
+        ALOGE("Error setting VP9E_SET_ROW_MT to 1. vpx_codec_control() "
+              "returned %d", codecReturn);
+        return codecReturn;
+    }
+
+    // For VP9, we always set CPU_USED to 8 (because the realtime default is 0
+    // which is too slow).
+    codecReturn = vpx_codec_control(mCodecContext, VP8E_SET_CPUUSED, 8);
+    if (codecReturn != VPX_CODEC_OK) {
+        ALOGE("Error setting VP8E_SET_CPUUSED to 8. vpx_codec_control() "
+              "returned %d", codecReturn);
+        return codecReturn;
+    }
+    return codecReturn;
+}
+
+class C2SoftVp9EncFactory : public C2ComponentFactory {
+public:
+    C2SoftVp9EncFactory()
+        : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+              GetCodec2PlatformComponentStore()->getParamReflector())) {}
+
+    virtual c2_status_t createComponent(
+            c2_node_id_t id,
+            std::shared_ptr<C2Component>* const component,
+            std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+            new C2SoftVp9Enc(COMPONENT_NAME, id,
+                             std::make_shared<C2SoftVpxEnc::IntfImpl>(mHelper)),
+            deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+            c2_node_id_t id,
+            std::shared_ptr<C2ComponentInterface>* const interface,
+            std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+            new SimpleInterface<C2SoftVpxEnc::IntfImpl>(
+                COMPONENT_NAME, id,
+                std::make_shared<C2SoftVpxEnc::IntfImpl>(mHelper)),
+            deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftVp9EncFactory() override = default;
+
+private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftVp9EncFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/vpx/C2SoftVp9Enc.h b/media/codec2/components/vpx/C2SoftVp9Enc.h
new file mode 100644
index 0000000..77ef8fd
--- /dev/null
+++ b/media/codec2/components/vpx/C2SoftVp9Enc.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_VP9_ENC_H__
+#define ANDROID_C2_SOFT_VP9_ENC_H__
+
+#include "C2SoftVpxEnc.h"
+
+namespace android {
+
+// Exposes vp9 encoder as a c2 Component
+//
+// In addition to the base class settings, Only following encoder settings are
+// available:
+//    - tile rows
+//    - tile columns
+//    - frame parallel mode
+struct C2SoftVp9Enc : public C2SoftVpxEnc {
+    C2SoftVp9Enc(const char* name, c2_node_id_t id,
+                 const std::shared_ptr<IntfImpl>& intfImpl);
+
+ protected:
+    // Populates |mCodecInterface| with codec specific settings.
+    virtual void setCodecSpecificInterface();
+
+    // Sets codec specific configuration.
+    virtual void setCodecSpecificConfiguration();
+
+    // Initializes codec specific encoder settings.
+    virtual vpx_codec_err_t setCodecSpecificControls();
+
+ private:
+    // C2 Profile & Level parameter
+    int32_t mProfile;
+    int32_t mLevel __unused;
+
+    int32_t mTileColumns;
+
+    bool mFrameParallelDecoding;
+
+    C2_DO_NOT_COPY(C2SoftVp9Enc);
+};
+
+}  // namespace android
+
+#endif  // ANDROID_C2_SOFT_VP9_ENC_H__
diff --git a/media/codec2/components/vpx/C2SoftVpxDec.cpp b/media/codec2/components/vpx/C2SoftVpxDec.cpp
new file mode 100644
index 0000000..a52ca15
--- /dev/null
+++ b/media/codec2/components/vpx/C2SoftVpxDec.cpp
@@ -0,0 +1,939 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftVpxDec"
+#include <log/log.h>
+
+#include <algorithm>
+
+#include <media/stagefright/foundation/AUtils.h>
+#include <media/stagefright/foundation/MediaDefs.h>
+
+#include <C2Debug.h>
+#include <C2PlatformSupport.h>
+#include <SimpleC2Interface.h>
+
+#include "C2SoftVpxDec.h"
+
+namespace android {
+
+#ifdef VP9
+constexpr char COMPONENT_NAME[] = "c2.android.vp9.decoder";
+#else
+constexpr char COMPONENT_NAME[] = "c2.android.vp8.decoder";
+#endif
+
+class C2SoftVpxDec::IntfImpl : public SimpleInterface<void>::BaseParams {
+public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+        : SimpleInterface<void>::BaseParams(
+                helper,
+                COMPONENT_NAME,
+                C2Component::KIND_DECODER,
+                C2Component::DOMAIN_VIDEO,
+#ifdef VP9
+                MEDIA_MIMETYPE_VIDEO_VP9
+#else
+                MEDIA_MIMETYPE_VIDEO_VP8
+#endif
+                ) {
+        noPrivateBuffers(); // TODO: account for our buffers here
+        noInputReferences();
+        noOutputReferences();
+        noInputLatency();
+        noTimeStretch();
+
+        // TODO: output latency and reordering
+
+        addParameter(
+                DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                .withConstValue(new C2ComponentAttributesSetting(C2Component::ATTRIB_IS_TEMPORAL))
+                .build());
+
+        addParameter(
+                DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
+                .withDefault(new C2StreamPictureSizeInfo::output(0u, 320, 240))
+                .withFields({
+                    C2F(mSize, width).inRange(2, 2048, 2),
+                    C2F(mSize, height).inRange(2, 2048, 2),
+                })
+                .withSetter(SizeSetter)
+                .build());
+
+#ifdef VP9
+        // TODO: Add C2Config::PROFILE_VP9_2HDR ??
+        addParameter(
+                DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
+                .withDefault(new C2StreamProfileLevelInfo::input(0u,
+                        C2Config::PROFILE_VP9_0, C2Config::LEVEL_VP9_5))
+                .withFields({
+                    C2F(mProfileLevel, profile).oneOf({
+                            C2Config::PROFILE_VP9_0,
+                            C2Config::PROFILE_VP9_2}),
+                    C2F(mProfileLevel, level).oneOf({
+                            C2Config::LEVEL_VP9_1,
+                            C2Config::LEVEL_VP9_1_1,
+                            C2Config::LEVEL_VP9_2,
+                            C2Config::LEVEL_VP9_2_1,
+                            C2Config::LEVEL_VP9_3,
+                            C2Config::LEVEL_VP9_3_1,
+                            C2Config::LEVEL_VP9_4,
+                            C2Config::LEVEL_VP9_4_1,
+                            C2Config::LEVEL_VP9_5,
+                    })
+                })
+                .withSetter(ProfileLevelSetter, mSize)
+                .build());
+
+        mHdr10PlusInfoInput = C2StreamHdr10PlusInfo::input::AllocShared(0);
+        addParameter(
+                DefineParam(mHdr10PlusInfoInput, C2_PARAMKEY_INPUT_HDR10_PLUS_INFO)
+                .withDefault(mHdr10PlusInfoInput)
+                .withFields({
+                    C2F(mHdr10PlusInfoInput, m.value).any(),
+                })
+                .withSetter(Hdr10PlusInfoInputSetter)
+                .build());
+
+        mHdr10PlusInfoOutput = C2StreamHdr10PlusInfo::output::AllocShared(0);
+        addParameter(
+                DefineParam(mHdr10PlusInfoOutput, C2_PARAMKEY_OUTPUT_HDR10_PLUS_INFO)
+                .withDefault(mHdr10PlusInfoOutput)
+                .withFields({
+                    C2F(mHdr10PlusInfoOutput, m.value).any(),
+                })
+                .withSetter(Hdr10PlusInfoOutputSetter)
+                .build());
+
+#if 0
+        // sample BT.2020 static info
+        mHdrStaticInfo = std::make_shared<C2StreamHdrStaticInfo::output>();
+        mHdrStaticInfo->mastering = {
+            .red   = { .x = 0.708,  .y = 0.292 },
+            .green = { .x = 0.170,  .y = 0.797 },
+            .blue  = { .x = 0.131,  .y = 0.046 },
+            .white = { .x = 0.3127, .y = 0.3290 },
+            .maxLuminance = 1000,
+            .minLuminance = 0.1,
+        };
+        mHdrStaticInfo->maxCll = 1000;
+        mHdrStaticInfo->maxFall = 120;
+
+        mHdrStaticInfo->maxLuminance = 0; // disable static info
+
+        helper->addStructDescriptors<C2MasteringDisplayColorVolumeStruct, C2ColorXyStruct>();
+        addParameter(
+                DefineParam(mHdrStaticInfo, C2_PARAMKEY_HDR_STATIC_INFO)
+                .withDefault(mHdrStaticInfo)
+                .withFields({
+                    C2F(mHdrStaticInfo, mastering.red.x).inRange(0, 1),
+                    // TODO
+                })
+                .withSetter(HdrStaticInfoSetter)
+                .build());
+#endif
+#else
+        addParameter(
+                DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
+                .withConstValue(new C2StreamProfileLevelInfo::input(0u,
+                        C2Config::PROFILE_UNUSED, C2Config::LEVEL_UNUSED))
+                .build());
+#endif
+
+        addParameter(
+                DefineParam(mMaxSize, C2_PARAMKEY_MAX_PICTURE_SIZE)
+                .withDefault(new C2StreamMaxPictureSizeTuning::output(0u, 320, 240))
+                .withFields({
+                    C2F(mSize, width).inRange(2, 2048, 2),
+                    C2F(mSize, height).inRange(2, 2048, 2),
+                })
+                .withSetter(MaxPictureSizeSetter, mSize)
+                .build());
+
+        addParameter(
+                DefineParam(mMaxInputSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
+                .withDefault(new C2StreamMaxBufferSizeInfo::input(0u, 320 * 240 * 3 / 4))
+                .withFields({
+                    C2F(mMaxInputSize, value).any(),
+                })
+                .calculatedAs(MaxInputSizeSetter, mMaxSize)
+                .build());
+
+        C2ChromaOffsetStruct locations[1] = { C2ChromaOffsetStruct::ITU_YUV_420_0() };
+        std::shared_ptr<C2StreamColorInfo::output> defaultColorInfo =
+            C2StreamColorInfo::output::AllocShared(
+                    1u, 0u, 8u /* bitDepth */, C2Color::YUV_420);
+        memcpy(defaultColorInfo->m.locations, locations, sizeof(locations));
+
+        defaultColorInfo =
+            C2StreamColorInfo::output::AllocShared(
+                    { C2ChromaOffsetStruct::ITU_YUV_420_0() },
+                    0u, 8u /* bitDepth */, C2Color::YUV_420);
+        helper->addStructDescriptors<C2ChromaOffsetStruct>();
+
+        addParameter(
+                DefineParam(mColorInfo, C2_PARAMKEY_CODED_COLOR_INFO)
+                .withConstValue(defaultColorInfo)
+                .build());
+
+        addParameter(
+                DefineParam(mDefaultColorAspects, C2_PARAMKEY_DEFAULT_COLOR_ASPECTS)
+                .withDefault(new C2StreamColorAspectsTuning::output(
+                        0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
+                        C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+                .withFields({
+                    C2F(mDefaultColorAspects, range).inRange(
+                                C2Color::RANGE_UNSPECIFIED,     C2Color::RANGE_OTHER),
+                    C2F(mDefaultColorAspects, primaries).inRange(
+                                C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
+                    C2F(mDefaultColorAspects, transfer).inRange(
+                                C2Color::TRANSFER_UNSPECIFIED,  C2Color::TRANSFER_OTHER),
+                    C2F(mDefaultColorAspects, matrix).inRange(
+                                C2Color::MATRIX_UNSPECIFIED,    C2Color::MATRIX_OTHER)
+                })
+                .withSetter(DefaultColorAspectsSetter)
+                .build());
+
+        // TODO: support more formats?
+        addParameter(
+                DefineParam(mPixelFormat, C2_PARAMKEY_PIXEL_FORMAT)
+                .withConstValue(new C2StreamPixelFormatInfo::output(
+                                     0u, HAL_PIXEL_FORMAT_YCBCR_420_888))
+                .build());
+    }
+
+    static C2R SizeSetter(bool mayBlock, const C2P<C2StreamPictureSizeInfo::output> &oldMe,
+                          C2P<C2StreamPictureSizeInfo::output> &me) {
+        (void)mayBlock;
+        C2R res = C2R::Ok();
+        if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
+            res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
+            me.set().width = oldMe.v.width;
+        }
+        if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
+            res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
+            me.set().height = oldMe.v.height;
+        }
+        return res;
+    }
+
+    static C2R MaxPictureSizeSetter(bool mayBlock, C2P<C2StreamMaxPictureSizeTuning::output> &me,
+                                    const C2P<C2StreamPictureSizeInfo::output> &size) {
+        (void)mayBlock;
+        // TODO: get max width/height from the size's field helpers vs. hardcoding
+        me.set().width = c2_min(c2_max(me.v.width, size.v.width), 2048u);
+        me.set().height = c2_min(c2_max(me.v.height, size.v.height), 2048u);
+        return C2R::Ok();
+    }
+
+    static C2R MaxInputSizeSetter(bool mayBlock, C2P<C2StreamMaxBufferSizeInfo::input> &me,
+                                  const C2P<C2StreamMaxPictureSizeTuning::output> &maxSize) {
+        (void)mayBlock;
+        // assume compression ratio of 2
+        me.set().value = (((maxSize.v.width + 63) / 64) * ((maxSize.v.height + 63) / 64) * 3072);
+        return C2R::Ok();
+    }
+
+    static C2R DefaultColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsTuning::output> &me) {
+        (void)mayBlock;
+        if (me.v.range > C2Color::RANGE_OTHER) {
+            me.set().range = C2Color::RANGE_OTHER;
+        }
+        if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
+            me.set().primaries = C2Color::PRIMARIES_OTHER;
+        }
+        if (me.v.transfer > C2Color::TRANSFER_OTHER) {
+            me.set().transfer = C2Color::TRANSFER_OTHER;
+        }
+        if (me.v.matrix > C2Color::MATRIX_OTHER) {
+            me.set().matrix = C2Color::MATRIX_OTHER;
+        }
+        return C2R::Ok();
+    }
+
+    static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me,
+                                  const C2P<C2StreamPictureSizeInfo::output> &size) {
+        (void)mayBlock;
+        (void)size;
+        (void)me;  // TODO: validate
+        return C2R::Ok();
+    }
+    std::shared_ptr<C2StreamColorAspectsTuning::output> getDefaultColorAspects_l() {
+        return mDefaultColorAspects;
+    }
+
+    static C2R Hdr10PlusInfoInputSetter(bool mayBlock, C2P<C2StreamHdr10PlusInfo::input> &me) {
+        (void)mayBlock;
+        (void)me;  // TODO: validate
+        return C2R::Ok();
+    }
+
+    static C2R Hdr10PlusInfoOutputSetter(bool mayBlock, C2P<C2StreamHdr10PlusInfo::output> &me) {
+        (void)mayBlock;
+        (void)me;  // TODO: validate
+        return C2R::Ok();
+    }
+
+private:
+    std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
+    std::shared_ptr<C2StreamPictureSizeInfo::output> mSize;
+    std::shared_ptr<C2StreamMaxPictureSizeTuning::output> mMaxSize;
+    std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mMaxInputSize;
+    std::shared_ptr<C2StreamColorInfo::output> mColorInfo;
+    std::shared_ptr<C2StreamPixelFormatInfo::output> mPixelFormat;
+    std::shared_ptr<C2StreamColorAspectsTuning::output> mDefaultColorAspects;
+#ifdef VP9
+#if 0
+    std::shared_ptr<C2StreamHdrStaticInfo::output> mHdrStaticInfo;
+#endif
+    std::shared_ptr<C2StreamHdr10PlusInfo::input> mHdr10PlusInfoInput;
+    std::shared_ptr<C2StreamHdr10PlusInfo::output> mHdr10PlusInfoOutput;
+#endif
+};
+
+C2SoftVpxDec::ConverterThread::ConverterThread(
+        const std::shared_ptr<Mutexed<ConversionQueue>> &queue)
+    : Thread(false), mQueue(queue) {}
+
+bool C2SoftVpxDec::ConverterThread::threadLoop() {
+    Mutexed<ConversionQueue>::Locked queue(*mQueue);
+    if (queue->entries.empty()) {
+        queue.waitForCondition(queue->cond);
+        if (queue->entries.empty()) {
+            return true;
+        }
+    }
+    std::function<void()> convert = queue->entries.front();
+    queue->entries.pop_front();
+    if (!queue->entries.empty()) {
+        queue->cond.signal();
+    }
+    queue.unlock();
+
+    convert();
+
+    queue.lock();
+    if (--queue->numPending == 0u) {
+        queue->cond.broadcast();
+    }
+    return true;
+}
+
+C2SoftVpxDec::C2SoftVpxDec(
+        const char *name,
+        c2_node_id_t id,
+        const std::shared_ptr<IntfImpl> &intfImpl)
+    : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+      mIntf(intfImpl),
+      mCodecCtx(nullptr),
+      mCoreCount(1),
+      mQueue(new Mutexed<ConversionQueue>) {
+}
+
+C2SoftVpxDec::~C2SoftVpxDec() {
+    onRelease();
+}
+
+c2_status_t C2SoftVpxDec::onInit() {
+    status_t err = initDecoder();
+    return err == OK ? C2_OK : C2_CORRUPTED;
+}
+
+c2_status_t C2SoftVpxDec::onStop() {
+    mSignalledError = false;
+    mSignalledOutputEos = false;
+
+    return C2_OK;
+}
+
+void C2SoftVpxDec::onReset() {
+    (void)onStop();
+    c2_status_t err = onFlush_sm();
+    if (err != C2_OK)
+    {
+        ALOGW("Failed to flush decoder. Try to hard reset decoder");
+        destroyDecoder();
+        (void)initDecoder();
+    }
+}
+
+void C2SoftVpxDec::onRelease() {
+    destroyDecoder();
+}
+
+c2_status_t C2SoftVpxDec::onFlush_sm() {
+    if (mFrameParallelMode) {
+        // Flush decoder by passing nullptr data ptr and 0 size.
+        // Ideally, this should never fail.
+        if (vpx_codec_decode(mCodecCtx, nullptr, 0, nullptr, 0)) {
+            ALOGE("Failed to flush on2 decoder.");
+            return C2_CORRUPTED;
+        }
+    }
+
+    // Drop all the decoded frames in decoder.
+    vpx_codec_iter_t iter = nullptr;
+    while (vpx_codec_get_frame(mCodecCtx, &iter)) {
+    }
+
+    mSignalledError = false;
+    mSignalledOutputEos = false;
+    return C2_OK;
+}
+
+static int GetCPUCoreCount() {
+    int cpuCoreCount = 1;
+#if defined(_SC_NPROCESSORS_ONLN)
+    cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
+#else
+    // _SC_NPROC_ONLN must be defined...
+    cpuCoreCount = sysconf(_SC_NPROC_ONLN);
+#endif
+    CHECK(cpuCoreCount >= 1);
+    ALOGV("Number of CPU cores: %d", cpuCoreCount);
+    return cpuCoreCount;
+}
+
+status_t C2SoftVpxDec::initDecoder() {
+#ifdef VP9
+    mMode = MODE_VP9;
+#else
+    mMode = MODE_VP8;
+#endif
+
+    mWidth = 320;
+    mHeight = 240;
+    mFrameParallelMode = false;
+    mSignalledOutputEos = false;
+    mSignalledError = false;
+
+    if (!mCodecCtx) {
+        mCodecCtx = new vpx_codec_ctx_t;
+    }
+    if (!mCodecCtx) {
+        ALOGE("mCodecCtx is null");
+        return NO_MEMORY;
+    }
+
+    vpx_codec_dec_cfg_t cfg;
+    memset(&cfg, 0, sizeof(vpx_codec_dec_cfg_t));
+    cfg.threads = mCoreCount = GetCPUCoreCount();
+
+    vpx_codec_flags_t flags;
+    memset(&flags, 0, sizeof(vpx_codec_flags_t));
+    if (mFrameParallelMode) flags |= VPX_CODEC_USE_FRAME_THREADING;
+
+    vpx_codec_err_t vpx_err;
+    if ((vpx_err = vpx_codec_dec_init(
+                 mCodecCtx, mMode == MODE_VP8 ? &vpx_codec_vp8_dx_algo : &vpx_codec_vp9_dx_algo,
+                 &cfg, flags))) {
+        ALOGE("on2 decoder failed to initialize. (%d)", vpx_err);
+        return UNKNOWN_ERROR;
+    }
+
+    if (mMode == MODE_VP9) {
+        using namespace std::string_literals;
+        for (int i = 0; i < mCoreCount; ++i) {
+            sp<ConverterThread> thread(new ConverterThread(mQueue));
+            mConverterThreads.push_back(thread);
+            if (thread->run(("vp9conv #"s + std::to_string(i)).c_str(),
+                            ANDROID_PRIORITY_AUDIO) != OK) {
+                return UNKNOWN_ERROR;
+            }
+        }
+    }
+
+    return OK;
+}
+
+status_t C2SoftVpxDec::destroyDecoder() {
+    if  (mCodecCtx) {
+        vpx_codec_destroy(mCodecCtx);
+        delete mCodecCtx;
+        mCodecCtx = nullptr;
+    }
+    bool running = true;
+    for (const sp<ConverterThread> &thread : mConverterThreads) {
+        thread->requestExit();
+    }
+    while (running) {
+        mQueue->lock()->cond.broadcast();
+        running = false;
+        for (const sp<ConverterThread> &thread : mConverterThreads) {
+            if (thread->isRunning()) {
+                running = true;
+                break;
+            }
+        }
+    }
+    mConverterThreads.clear();
+
+    return OK;
+}
+
+void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
+    uint32_t flags = 0;
+    if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
+        flags |= C2FrameData::FLAG_END_OF_STREAM;
+        ALOGV("signalling eos");
+    }
+    work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
+    work->worklets.front()->output.buffers.clear();
+    work->worklets.front()->output.ordinal = work->input.ordinal;
+    work->workletsProcessed = 1u;
+}
+
+void C2SoftVpxDec::finishWork(uint64_t index, const std::unique_ptr<C2Work> &work,
+                           const std::shared_ptr<C2GraphicBlock> &block) {
+    std::shared_ptr<C2Buffer> buffer = createGraphicBuffer(block,
+                                                           C2Rect(mWidth, mHeight));
+    auto fillWork = [buffer, index, intf = this->mIntf](
+            const std::unique_ptr<C2Work> &work) {
+        uint32_t flags = 0;
+        if ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) &&
+                (c2_cntr64_t(index) == work->input.ordinal.frameIndex)) {
+            flags |= C2FrameData::FLAG_END_OF_STREAM;
+            ALOGV("signalling eos");
+        }
+        work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
+        work->worklets.front()->output.buffers.clear();
+        work->worklets.front()->output.buffers.push_back(buffer);
+        work->worklets.front()->output.ordinal = work->input.ordinal;
+        work->workletsProcessed = 1u;
+
+        for (const std::unique_ptr<C2Param> &param: work->input.configUpdate) {
+            if (param) {
+                C2StreamHdr10PlusInfo::input *hdr10PlusInfo =
+                        C2StreamHdr10PlusInfo::input::From(param.get());
+
+                if (hdr10PlusInfo != nullptr) {
+                    std::vector<std::unique_ptr<C2SettingResult>> failures;
+                    std::unique_ptr<C2Param> outParam = C2Param::CopyAsStream(
+                            *param.get(), true /*output*/, param->stream());
+                    c2_status_t err = intf->config(
+                            { outParam.get() }, C2_MAY_BLOCK, &failures);
+                    if (err == C2_OK) {
+                        work->worklets.front()->output.configUpdate.push_back(
+                                C2Param::Copy(*outParam.get()));
+                    } else {
+                        ALOGE("finishWork: Config update size failed");
+                    }
+                    break;
+                }
+            }
+        }
+    };
+    if (work && c2_cntr64_t(index) == work->input.ordinal.frameIndex) {
+        fillWork(work);
+    } else {
+        finish(index, fillWork);
+    }
+}
+
+void C2SoftVpxDec::process(
+        const std::unique_ptr<C2Work> &work,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    // Initialize output work
+    work->result = C2_OK;
+    work->workletsProcessed = 0u;
+    work->worklets.front()->output.configUpdate.clear();
+    work->worklets.front()->output.flags = work->input.flags;
+
+    if (mSignalledError || mSignalledOutputEos) {
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+
+    size_t inOffset = 0u;
+    size_t inSize = 0u;
+    C2ReadView rView = mDummyReadView;
+    if (!work->input.buffers.empty()) {
+        rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
+        inSize = rView.capacity();
+        if (inSize && rView.error()) {
+            ALOGE("read view map failed %d", rView.error());
+            work->result = C2_CORRUPTED;
+            return;
+        }
+    }
+
+    bool codecConfig = ((work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) !=0);
+    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
+
+    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
+          inSize, (int)work->input.ordinal.timestamp.peeku(),
+          (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
+
+    // Software VP9 Decoder does not need the Codec Specific Data (CSD)
+    // (specified in http://www.webmproject.org/vp9/profiles/). Ignore it if
+    // it was passed.
+    if (codecConfig) {
+        // Ignore CSD buffer for VP9.
+        if (mMode == MODE_VP9) {
+            fillEmptyWork(work);
+            return;
+        } else {
+            // Tolerate the CSD buffer for VP8. This is a workaround
+            // for b/28689536. continue
+            ALOGW("WARNING: Got CSD buffer for VP8. Continue");
+        }
+    }
+
+    int64_t frameIndex = work->input.ordinal.frameIndex.peekll();
+
+    if (inSize) {
+        uint8_t *bitstream = const_cast<uint8_t *>(rView.data() + inOffset);
+        vpx_codec_err_t err = vpx_codec_decode(
+                mCodecCtx, bitstream, inSize, &frameIndex, 0);
+        if (err != VPX_CODEC_OK) {
+            ALOGE("on2 decoder failed to decode frame. err: %d", err);
+            mSignalledError = true;
+            work->workletsProcessed = 1u;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+    }
+
+    (void)outputBuffer(pool, work);
+
+    if (eos) {
+        drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
+        mSignalledOutputEos = true;
+    } else if (!inSize) {
+        fillEmptyWork(work);
+    }
+}
+
+static void copyOutputBufferToYuvPlanarFrame(
+        uint8_t *dst, const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV,
+        size_t srcYStride, size_t srcUStride, size_t srcVStride,
+        size_t dstYStride, size_t dstUVStride,
+        uint32_t width, uint32_t height) {
+    uint8_t *dstStart = dst;
+
+    for (size_t i = 0; i < height; ++i) {
+         memcpy(dst, srcY, width);
+         srcY += srcYStride;
+         dst += dstYStride;
+    }
+
+    dst = dstStart + dstYStride * height;
+    for (size_t i = 0; i < height / 2; ++i) {
+         memcpy(dst, srcV, width / 2);
+         srcV += srcVStride;
+         dst += dstUVStride;
+    }
+
+    dst = dstStart + (dstYStride * height) + (dstUVStride * height / 2);
+    for (size_t i = 0; i < height / 2; ++i) {
+         memcpy(dst, srcU, width / 2);
+         srcU += srcUStride;
+         dst += dstUVStride;
+    }
+}
+
+static void convertYUV420Planar16ToY410(uint32_t *dst,
+        const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV,
+        size_t srcYStride, size_t srcUStride, size_t srcVStride,
+        size_t dstStride, size_t width, size_t height) {
+
+    // Converting two lines at a time, slightly faster
+    for (size_t y = 0; y < height; y += 2) {
+        uint32_t *dstTop = (uint32_t *) dst;
+        uint32_t *dstBot = (uint32_t *) (dst + dstStride);
+        uint16_t *ySrcTop = (uint16_t*) srcY;
+        uint16_t *ySrcBot = (uint16_t*) (srcY + srcYStride);
+        uint16_t *uSrc = (uint16_t*) srcU;
+        uint16_t *vSrc = (uint16_t*) srcV;
+
+        uint32_t u01, v01, y01, y23, y45, y67, uv0, uv1;
+        size_t x = 0;
+        for (; x < width - 3; x += 4) {
+
+            u01 = *((uint32_t*)uSrc); uSrc += 2;
+            v01 = *((uint32_t*)vSrc); vSrc += 2;
+
+            y01 = *((uint32_t*)ySrcTop); ySrcTop += 2;
+            y23 = *((uint32_t*)ySrcTop); ySrcTop += 2;
+            y45 = *((uint32_t*)ySrcBot); ySrcBot += 2;
+            y67 = *((uint32_t*)ySrcBot); ySrcBot += 2;
+
+            uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20);
+            uv1 = (u01 >> 16) | ((v01 >> 16) << 20);
+
+            *dstTop++ = 3 << 30 | ((y01 & 0x3FF) << 10) | uv0;
+            *dstTop++ = 3 << 30 | ((y01 >> 16) << 10) | uv0;
+            *dstTop++ = 3 << 30 | ((y23 & 0x3FF) << 10) | uv1;
+            *dstTop++ = 3 << 30 | ((y23 >> 16) << 10) | uv1;
+
+            *dstBot++ = 3 << 30 | ((y45 & 0x3FF) << 10) | uv0;
+            *dstBot++ = 3 << 30 | ((y45 >> 16) << 10) | uv0;
+            *dstBot++ = 3 << 30 | ((y67 & 0x3FF) << 10) | uv1;
+            *dstBot++ = 3 << 30 | ((y67 >> 16) << 10) | uv1;
+        }
+
+        // There should be at most 2 more pixels to process. Note that we don't
+        // need to consider odd case as the buffer is always aligned to even.
+        if (x < width) {
+            u01 = *uSrc;
+            v01 = *vSrc;
+            y01 = *((uint32_t*)ySrcTop);
+            y45 = *((uint32_t*)ySrcBot);
+            uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20);
+            *dstTop++ = ((y01 & 0x3FF) << 10) | uv0;
+            *dstTop++ = ((y01 >> 16) << 10) | uv0;
+            *dstBot++ = ((y45 & 0x3FF) << 10) | uv0;
+            *dstBot++ = ((y45 >> 16) << 10) | uv0;
+        }
+
+        srcY += srcYStride * 2;
+        srcU += srcUStride;
+        srcV += srcVStride;
+        dst += dstStride * 2;
+    }
+
+    return;
+}
+
+static void convertYUV420Planar16ToYUV420Planar(uint8_t *dst,
+        const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV,
+        size_t srcYStride, size_t srcUStride, size_t srcVStride,
+        size_t dstYStride, size_t dstUVStride, size_t width, size_t height) {
+
+    uint8_t *dstY = (uint8_t *)dst;
+    size_t dstYSize = dstYStride * height;
+    size_t dstUVSize = dstUVStride * height / 2;
+    uint8_t *dstV = dstY + dstYSize;
+    uint8_t *dstU = dstV + dstUVSize;
+
+    for (size_t y = 0; y < height; ++y) {
+        for (size_t x = 0; x < width; ++x) {
+            dstY[x] = (uint8_t)(srcY[x] >> 2);
+        }
+
+        srcY += srcYStride;
+        dstY += dstYStride;
+    }
+
+    for (size_t y = 0; y < (height + 1) / 2; ++y) {
+        for (size_t x = 0; x < (width + 1) / 2; ++x) {
+            dstU[x] = (uint8_t)(srcU[x] >> 2);
+            dstV[x] = (uint8_t)(srcV[x] >> 2);
+        }
+
+        srcU += srcUStride;
+        srcV += srcVStride;
+        dstU += dstUVStride;
+        dstV += dstUVStride;
+    }
+    return;
+}
+bool C2SoftVpxDec::outputBuffer(
+        const std::shared_ptr<C2BlockPool> &pool,
+        const std::unique_ptr<C2Work> &work)
+{
+    if (!(work && pool)) return false;
+
+    vpx_codec_iter_t iter = nullptr;
+    vpx_image_t *img = vpx_codec_get_frame(mCodecCtx, &iter);
+
+    if (!img) return false;
+
+    if (img->d_w != mWidth || img->d_h != mHeight) {
+        mWidth = img->d_w;
+        mHeight = img->d_h;
+
+        C2StreamPictureSizeInfo::output size(0u, mWidth, mHeight);
+        std::vector<std::unique_ptr<C2SettingResult>> failures;
+        c2_status_t err = mIntf->config({&size}, C2_MAY_BLOCK, &failures);
+        if (err == C2_OK) {
+            work->worklets.front()->output.configUpdate.push_back(
+                C2Param::Copy(size));
+        } else {
+            ALOGE("Config update size failed");
+            mSignalledError = true;
+            work->workletsProcessed = 1u;
+            work->result = C2_CORRUPTED;
+            return false;
+        }
+
+    }
+    CHECK(img->fmt == VPX_IMG_FMT_I420 || img->fmt == VPX_IMG_FMT_I42016);
+
+    std::shared_ptr<C2GraphicBlock> block;
+    uint32_t format = HAL_PIXEL_FORMAT_YV12;
+    if (img->fmt == VPX_IMG_FMT_I42016) {
+        IntfImpl::Lock lock = mIntf->lock();
+        std::shared_ptr<C2StreamColorAspectsTuning::output> defaultColorAspects = mIntf->getDefaultColorAspects_l();
+
+        if (defaultColorAspects->primaries == C2Color::PRIMARIES_BT2020 &&
+            defaultColorAspects->matrix == C2Color::MATRIX_BT2020 &&
+            defaultColorAspects->transfer == C2Color::TRANSFER_ST2084) {
+            format = HAL_PIXEL_FORMAT_RGBA_1010102;
+        }
+    }
+    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+    c2_status_t err = pool->fetchGraphicBlock(align(mWidth, 16), mHeight, format, usage, &block);
+    if (err != C2_OK) {
+        ALOGE("fetchGraphicBlock for Output failed with status %d", err);
+        work->result = err;
+        return false;
+    }
+
+    C2GraphicView wView = block->map().get();
+    if (wView.error()) {
+        ALOGE("graphic view map failed %d", wView.error());
+        work->result = C2_CORRUPTED;
+        return false;
+    }
+
+    ALOGV("provided (%dx%d) required (%dx%d), out frameindex %d",
+           block->width(), block->height(), mWidth, mHeight, (int)*(int64_t *)img->user_priv);
+
+    uint8_t *dst = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_Y]);
+    size_t srcYStride = img->stride[VPX_PLANE_Y];
+    size_t srcUStride = img->stride[VPX_PLANE_U];
+    size_t srcVStride = img->stride[VPX_PLANE_V];
+    C2PlanarLayout layout = wView.layout();
+    size_t dstYStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
+    size_t dstUVStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
+
+    if (img->fmt == VPX_IMG_FMT_I42016) {
+        const uint16_t *srcY = (const uint16_t *)img->planes[VPX_PLANE_Y];
+        const uint16_t *srcU = (const uint16_t *)img->planes[VPX_PLANE_U];
+        const uint16_t *srcV = (const uint16_t *)img->planes[VPX_PLANE_V];
+
+        if (format == HAL_PIXEL_FORMAT_RGBA_1010102) {
+            Mutexed<ConversionQueue>::Locked queue(*mQueue);
+            size_t i = 0;
+            constexpr size_t kHeight = 64;
+            for (; i < mHeight; i += kHeight) {
+                queue->entries.push_back(
+                        [dst, srcY, srcU, srcV,
+                         srcYStride, srcUStride, srcVStride, dstYStride,
+                         width = mWidth, height = std::min(mHeight - i, kHeight)] {
+                            convertYUV420Planar16ToY410(
+                                    (uint32_t *)dst, srcY, srcU, srcV, srcYStride / 2,
+                                    srcUStride / 2, srcVStride / 2, dstYStride / sizeof(uint32_t),
+                                    width, height);
+                        });
+                srcY += srcYStride / 2 * kHeight;
+                srcU += srcUStride / 2 * (kHeight / 2);
+                srcV += srcVStride / 2 * (kHeight / 2);
+                dst += dstYStride * kHeight;
+            }
+            CHECK_EQ(0u, queue->numPending);
+            queue->numPending = queue->entries.size();
+            while (queue->numPending > 0) {
+                queue->cond.signal();
+                queue.waitForCondition(queue->cond);
+            }
+        } else {
+            convertYUV420Planar16ToYUV420Planar(dst, srcY, srcU, srcV, srcYStride / 2,
+                                                srcUStride / 2, srcVStride / 2,
+                                                dstYStride, dstUVStride,
+                                                mWidth, mHeight);
+        }
+    } else {
+        const uint8_t *srcY = (const uint8_t *)img->planes[VPX_PLANE_Y];
+        const uint8_t *srcU = (const uint8_t *)img->planes[VPX_PLANE_U];
+        const uint8_t *srcV = (const uint8_t *)img->planes[VPX_PLANE_V];
+        copyOutputBufferToYuvPlanarFrame(
+                dst, srcY, srcU, srcV,
+                srcYStride, srcUStride, srcVStride,
+                dstYStride, dstUVStride,
+                mWidth, mHeight);
+    }
+    finishWork(*(int64_t *)img->user_priv, work, std::move(block));
+    return true;
+}
+
+c2_status_t C2SoftVpxDec::drainInternal(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool,
+        const std::unique_ptr<C2Work> &work) {
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+
+    while ((outputBuffer(pool, work))) {
+    }
+
+    if (drainMode == DRAIN_COMPONENT_WITH_EOS &&
+            work && work->workletsProcessed == 0u) {
+        fillEmptyWork(work);
+    }
+
+    return C2_OK;
+}
+c2_status_t C2SoftVpxDec::drain(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    return drainInternal(drainMode, pool, nullptr);
+}
+
+class C2SoftVpxFactory : public C2ComponentFactory {
+public:
+    C2SoftVpxFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+        GetCodec2PlatformComponentStore()->getParamReflector())) {
+    }
+
+    virtual c2_status_t createComponent(
+            c2_node_id_t id,
+            std::shared_ptr<C2Component>* const component,
+            std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+            new C2SoftVpxDec(COMPONENT_NAME, id,
+                          std::make_shared<C2SoftVpxDec::IntfImpl>(mHelper)),
+            deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+            c2_node_id_t id,
+            std::shared_ptr<C2ComponentInterface>* const interface,
+            std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+            new SimpleInterface<C2SoftVpxDec::IntfImpl>(
+                COMPONENT_NAME, id,
+                std::make_shared<C2SoftVpxDec::IntfImpl>(mHelper)),
+            deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftVpxFactory() override = default;
+
+private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftVpxFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/vpx/C2SoftVpxDec.h b/media/codec2/components/vpx/C2SoftVpxDec.h
new file mode 100644
index 0000000..e51bcee
--- /dev/null
+++ b/media/codec2/components/vpx/C2SoftVpxDec.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_VPX_DEC_H_
+#define ANDROID_C2_SOFT_VPX_DEC_H_
+
+#include <SimpleC2Component.h>
+
+
+#include "vpx/vpx_decoder.h"
+#include "vpx/vp8dx.h"
+
+namespace android {
+
+struct C2SoftVpxDec : public SimpleC2Component {
+    class IntfImpl;
+
+    C2SoftVpxDec(const char* name, c2_node_id_t id,
+              const std::shared_ptr<IntfImpl>& intfImpl);
+    virtual ~C2SoftVpxDec();
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+    c2_status_t drain(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+ private:
+    enum {
+        MODE_VP8,
+        MODE_VP9,
+    } mMode;
+
+    struct ConversionQueue;
+
+    class ConverterThread : public Thread {
+    public:
+        explicit ConverterThread(
+                const std::shared_ptr<Mutexed<ConversionQueue>> &queue);
+        ~ConverterThread() override = default;
+        bool threadLoop() override;
+
+    private:
+        std::shared_ptr<Mutexed<ConversionQueue>> mQueue;
+    };
+
+    std::shared_ptr<IntfImpl> mIntf;
+    vpx_codec_ctx_t *mCodecCtx;
+    bool mFrameParallelMode;  // Frame parallel is only supported by VP9 decoder.
+
+    uint32_t mWidth;
+    uint32_t mHeight;
+    bool mSignalledOutputEos;
+    bool mSignalledError;
+
+    int mCoreCount;
+    struct ConversionQueue {
+        std::list<std::function<void()>> entries;
+        Condition cond;
+        size_t numPending{0u};
+    };
+    std::shared_ptr<Mutexed<ConversionQueue>> mQueue;
+    std::vector<sp<ConverterThread>> mConverterThreads;
+
+    status_t initDecoder();
+    status_t destroyDecoder();
+    void finishWork(uint64_t index, const std::unique_ptr<C2Work> &work,
+                    const std::shared_ptr<C2GraphicBlock> &block);
+    bool outputBuffer(
+            const std::shared_ptr<C2BlockPool> &pool,
+            const std::unique_ptr<C2Work> &work);
+    c2_status_t drainInternal(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool,
+            const std::unique_ptr<C2Work> &work);
+
+    C2_DO_NOT_COPY(C2SoftVpxDec);
+};
+
+}  // namespace android
+
+#endif  // ANDROID_C2_SOFT_VPX_DEC_H_
diff --git a/media/codec2/components/vpx/C2SoftVpxEnc.cpp b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
new file mode 100644
index 0000000..6dab70b
--- /dev/null
+++ b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
@@ -0,0 +1,670 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftVpxEnc"
+#include <log/log.h>
+#include <utils/misc.h>
+
+#include <media/hardware/VideoAPI.h>
+
+#include <Codec2BufferUtils.h>
+#include <C2Debug.h>
+#include "C2SoftVpxEnc.h"
+
+#ifndef INT32_MAX
+#define INT32_MAX   2147483647
+#endif
+
+namespace android {
+
+#if 0
+static size_t getCpuCoreCount() {
+    long cpuCoreCount = 1;
+#if defined(_SC_NPROCESSORS_ONLN)
+    cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
+#else
+    // _SC_NPROC_ONLN must be defined...
+    cpuCoreCount = sysconf(_SC_NPROC_ONLN);
+#endif
+    CHECK(cpuCoreCount >= 1);
+    ALOGV("Number of CPU cores: %ld", cpuCoreCount);
+    return (size_t)cpuCoreCount;
+}
+#endif
+
+C2SoftVpxEnc::C2SoftVpxEnc(const char* name, c2_node_id_t id,
+                           const std::shared_ptr<IntfImpl>& intfImpl)
+    : SimpleC2Component(
+          std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+      mIntf(intfImpl),
+      mCodecContext(nullptr),
+      mCodecConfiguration(nullptr),
+      mCodecInterface(nullptr),
+      mStrideAlign(2),
+      mColorFormat(VPX_IMG_FMT_I420),
+      mBitrateControlMode(VPX_VBR),
+      mErrorResilience(false),
+      mMinQuantizer(0),
+      mMaxQuantizer(0),
+      mTemporalLayers(0),
+      mTemporalPatternType(VPXTemporalLayerPatternNone),
+      mTemporalPatternLength(0),
+      mTemporalPatternIdx(0),
+      mLastTimestamp(0x7FFFFFFFFFFFFFFFull),
+      mSignalledOutputEos(false),
+      mSignalledError(false) {
+    memset(mTemporalLayerBitrateRatio, 0, sizeof(mTemporalLayerBitrateRatio));
+    mTemporalLayerBitrateRatio[0] = 100;
+}
+
+C2SoftVpxEnc::~C2SoftVpxEnc() {
+    onRelease();
+}
+
+c2_status_t C2SoftVpxEnc::onInit() {
+    status_t err = initEncoder();
+    return err == OK ? C2_OK : C2_CORRUPTED;
+}
+
+void C2SoftVpxEnc::onRelease() {
+    if (mCodecContext) {
+        vpx_codec_destroy(mCodecContext);
+        delete mCodecContext;
+        mCodecContext = nullptr;
+    }
+
+    if (mCodecConfiguration) {
+        delete mCodecConfiguration;
+        mCodecConfiguration = nullptr;
+    }
+
+    // this one is not allocated by us
+    mCodecInterface = nullptr;
+}
+
+c2_status_t C2SoftVpxEnc::onStop() {
+    onRelease();
+    mLastTimestamp = 0x7FFFFFFFFFFFFFFFLL;
+    mSignalledOutputEos = false;
+    mSignalledError = false;
+    return C2_OK;
+}
+
+void C2SoftVpxEnc::onReset() {
+    (void)onStop();
+}
+
+c2_status_t C2SoftVpxEnc::onFlush_sm() {
+    return onStop();
+}
+
+status_t C2SoftVpxEnc::initEncoder() {
+    vpx_codec_err_t codec_return;
+    status_t result = UNKNOWN_ERROR;
+    {
+        IntfImpl::Lock lock = mIntf->lock();
+        mSize = mIntf->getSize_l();
+        mBitrate = mIntf->getBitrate_l();
+        mBitrateMode = mIntf->getBitrateMode_l();
+        mFrameRate = mIntf->getFrameRate_l();
+        mIntraRefresh = mIntf->getIntraRefresh_l();
+        mRequestSync = mIntf->getRequestSync_l();
+        mTemporalLayers = mIntf->getTemporalLayers_l()->m.layerCount;
+    }
+
+    switch (mBitrateMode->value) {
+        case C2Config::BITRATE_CONST:
+            mBitrateControlMode = VPX_CBR;
+            break;
+        case C2Config::BITRATE_VARIABLE:
+        [[fallthrough]];
+        default:
+            mBitrateControlMode = VPX_VBR;
+            break;
+    }
+
+    setCodecSpecificInterface();
+    if (!mCodecInterface) goto CleanUp;
+
+    ALOGD("VPx: initEncoder. BRMode: %u. TSLayers: %zu. KF: %u. QP: %u - %u",
+          (uint32_t)mBitrateControlMode, mTemporalLayers, mIntf->getSyncFramePeriod(),
+          mMinQuantizer, mMaxQuantizer);
+
+    mCodecConfiguration = new vpx_codec_enc_cfg_t;
+    if (!mCodecConfiguration) goto CleanUp;
+    codec_return = vpx_codec_enc_config_default(mCodecInterface,
+                                                mCodecConfiguration,
+                                                0);
+    if (codec_return != VPX_CODEC_OK) {
+        ALOGE("Error populating default configuration for vpx encoder.");
+        goto CleanUp;
+    }
+
+    mCodecConfiguration->g_w = mSize->width;
+    mCodecConfiguration->g_h = mSize->height;
+    //mCodecConfiguration->g_threads = getCpuCoreCount();
+    mCodecConfiguration->g_threads = 0;
+    mCodecConfiguration->g_error_resilient = mErrorResilience;
+
+    // timebase unit is microsecond
+    // g_timebase is in seconds (i.e. 1/1000000 seconds)
+    mCodecConfiguration->g_timebase.num = 1;
+    mCodecConfiguration->g_timebase.den = 1000000;
+    // rc_target_bitrate is in kbps, mBitrate in bps
+    mCodecConfiguration->rc_target_bitrate = (mBitrate->value + 500) / 1000;
+    mCodecConfiguration->rc_end_usage = mBitrateControlMode;
+    // Disable frame drop - not allowed in MediaCodec now.
+    mCodecConfiguration->rc_dropframe_thresh = 0;
+    // Disable lagged encoding.
+    mCodecConfiguration->g_lag_in_frames = 0;
+    if (mBitrateControlMode == VPX_CBR) {
+        // Disable spatial resizing.
+        mCodecConfiguration->rc_resize_allowed = 0;
+        // Single-pass mode.
+        mCodecConfiguration->g_pass = VPX_RC_ONE_PASS;
+        // Maximum amount of bits that can be subtracted from the target
+        // bitrate - expressed as percentage of the target bitrate.
+        mCodecConfiguration->rc_undershoot_pct = 100;
+        // Maximum amount of bits that can be added to the target
+        // bitrate - expressed as percentage of the target bitrate.
+        mCodecConfiguration->rc_overshoot_pct = 15;
+        // Initial value of the buffer level in ms.
+        mCodecConfiguration->rc_buf_initial_sz = 500;
+        // Amount of data that the encoder should try to maintain in ms.
+        mCodecConfiguration->rc_buf_optimal_sz = 600;
+        // The amount of data that may be buffered by the decoding
+        // application in ms.
+        mCodecConfiguration->rc_buf_sz = 1000;
+        // Enable error resilience - needed for packet loss.
+        mCodecConfiguration->g_error_resilient = 1;
+        // Maximum key frame interval - for CBR boost to 3000
+        mCodecConfiguration->kf_max_dist = 3000;
+        // Encoder determines optimal key frame placement automatically.
+        mCodecConfiguration->kf_mode = VPX_KF_AUTO;
+    }
+
+    // Frames temporal pattern - for now WebRTC like pattern is only supported.
+    switch (mTemporalLayers) {
+        case 0:
+            mTemporalPatternLength = 0;
+            break;
+        case 1:
+            mCodecConfiguration->ts_number_layers = 1;
+            mCodecConfiguration->ts_rate_decimator[0] = 1;
+            mCodecConfiguration->ts_periodicity = 1;
+            mCodecConfiguration->ts_layer_id[0] = 0;
+            mTemporalPattern[0] = kTemporalUpdateLastRefAll;
+            mTemporalPatternLength = 1;
+            break;
+        case 2:
+            mCodecConfiguration->ts_number_layers = 2;
+            mCodecConfiguration->ts_rate_decimator[0] = 2;
+            mCodecConfiguration->ts_rate_decimator[1] = 1;
+            mCodecConfiguration->ts_periodicity = 2;
+            mCodecConfiguration->ts_layer_id[0] = 0;
+            mCodecConfiguration->ts_layer_id[1] = 1;
+            mTemporalPattern[0] = kTemporalUpdateLastAndGoldenRefAltRef;
+            mTemporalPattern[1] = kTemporalUpdateGoldenWithoutDependencyRefAltRef;
+            mTemporalPattern[2] = kTemporalUpdateLastRefAltRef;
+            mTemporalPattern[3] = kTemporalUpdateGoldenRefAltRef;
+            mTemporalPattern[4] = kTemporalUpdateLastRefAltRef;
+            mTemporalPattern[5] = kTemporalUpdateGoldenRefAltRef;
+            mTemporalPattern[6] = kTemporalUpdateLastRefAltRef;
+            mTemporalPattern[7] = kTemporalUpdateNone;
+            mTemporalPatternLength = 8;
+            break;
+        case 3:
+            mCodecConfiguration->ts_number_layers = 3;
+            mCodecConfiguration->ts_rate_decimator[0] = 4;
+            mCodecConfiguration->ts_rate_decimator[1] = 2;
+            mCodecConfiguration->ts_rate_decimator[2] = 1;
+            mCodecConfiguration->ts_periodicity = 4;
+            mCodecConfiguration->ts_layer_id[0] = 0;
+            mCodecConfiguration->ts_layer_id[1] = 2;
+            mCodecConfiguration->ts_layer_id[2] = 1;
+            mCodecConfiguration->ts_layer_id[3] = 2;
+            mTemporalPattern[0] = kTemporalUpdateLastAndGoldenRefAltRef;
+            mTemporalPattern[1] = kTemporalUpdateNoneNoRefGoldenRefAltRef;
+            mTemporalPattern[2] = kTemporalUpdateGoldenWithoutDependencyRefAltRef;
+            mTemporalPattern[3] = kTemporalUpdateNone;
+            mTemporalPattern[4] = kTemporalUpdateLastRefAltRef;
+            mTemporalPattern[5] = kTemporalUpdateNone;
+            mTemporalPattern[6] = kTemporalUpdateGoldenRefAltRef;
+            mTemporalPattern[7] = kTemporalUpdateNone;
+            mTemporalPatternLength = 8;
+            break;
+        default:
+            ALOGE("Wrong number of temporal layers %zu", mTemporalLayers);
+            goto CleanUp;
+    }
+    // Set bitrate values for each layer
+    for (size_t i = 0; i < mCodecConfiguration->ts_number_layers; i++) {
+        mCodecConfiguration->ts_target_bitrate[i] =
+            mCodecConfiguration->rc_target_bitrate *
+            mTemporalLayerBitrateRatio[i] / 100;
+    }
+    if (mIntf->getSyncFramePeriod() >= 0) {
+        mCodecConfiguration->kf_max_dist = mIntf->getSyncFramePeriod();
+        mCodecConfiguration->kf_min_dist = mIntf->getSyncFramePeriod();
+        mCodecConfiguration->kf_mode = VPX_KF_AUTO;
+    }
+    if (mMinQuantizer > 0) {
+        mCodecConfiguration->rc_min_quantizer = mMinQuantizer;
+    }
+    if (mMaxQuantizer > 0) {
+        mCodecConfiguration->rc_max_quantizer = mMaxQuantizer;
+    }
+    setCodecSpecificConfiguration();
+    mCodecContext = new vpx_codec_ctx_t;
+    if (!mCodecContext) goto CleanUp;
+    codec_return = vpx_codec_enc_init(mCodecContext,
+                                      mCodecInterface,
+                                      mCodecConfiguration,
+                                      0);  // flags
+    if (codec_return != VPX_CODEC_OK) {
+        ALOGE("Error initializing vpx encoder");
+        goto CleanUp;
+    }
+
+    // Extra CBR settings
+    if (mBitrateControlMode == VPX_CBR) {
+        codec_return = vpx_codec_control(mCodecContext,
+                                         VP8E_SET_STATIC_THRESHOLD,
+                                         1);
+        if (codec_return == VPX_CODEC_OK) {
+            uint32_t rc_max_intra_target =
+                (uint32_t)(mCodecConfiguration->rc_buf_optimal_sz * mFrameRate->value / 20 + 0.5);
+            // Don't go below 3 times per frame bandwidth.
+            if (rc_max_intra_target < 300) {
+                rc_max_intra_target = 300;
+            }
+            codec_return = vpx_codec_control(mCodecContext,
+                                             VP8E_SET_MAX_INTRA_BITRATE_PCT,
+                                             rc_max_intra_target);
+        }
+        if (codec_return == VPX_CODEC_OK) {
+            codec_return = vpx_codec_control(mCodecContext,
+                                             VP8E_SET_CPUUSED,
+                                             -8);
+        }
+        if (codec_return != VPX_CODEC_OK) {
+            ALOGE("Error setting cbr parameters for vpx encoder.");
+            goto CleanUp;
+        }
+    }
+
+    codec_return = setCodecSpecificControls();
+    if (codec_return != VPX_CODEC_OK) goto CleanUp;
+
+    {
+        uint32_t width = mSize->width;
+        uint32_t height = mSize->height;
+        if (((uint64_t)width * height) >
+            ((uint64_t)INT32_MAX / 3)) {
+            ALOGE("b/25812794, Buffer size is too big, width=%u, height=%u.", width, height);
+        } else {
+            uint32_t stride = (width + mStrideAlign - 1) & ~(mStrideAlign - 1);
+            uint32_t vstride = (height + mStrideAlign - 1) & ~(mStrideAlign - 1);
+            mConversionBuffer = MemoryBlock::Allocate(stride * vstride * 3 / 2);
+            if (!mConversionBuffer.size()) {
+                ALOGE("Allocating conversion buffer failed.");
+            } else {
+                mNumInputFrames = -1;
+                return OK;
+            }
+        }
+    }
+
+CleanUp:
+    onRelease();
+    return result;
+}
+
+vpx_enc_frame_flags_t C2SoftVpxEnc::getEncodeFlags() {
+    vpx_enc_frame_flags_t flags = 0;
+    if (mTemporalPatternLength > 0) {
+      int patternIdx = mTemporalPatternIdx % mTemporalPatternLength;
+      mTemporalPatternIdx++;
+      switch (mTemporalPattern[patternIdx]) {
+          case kTemporalUpdateLast:
+              flags |= VP8_EFLAG_NO_UPD_GF;
+              flags |= VP8_EFLAG_NO_UPD_ARF;
+              flags |= VP8_EFLAG_NO_REF_GF;
+              flags |= VP8_EFLAG_NO_REF_ARF;
+              break;
+          case kTemporalUpdateGoldenWithoutDependency:
+              flags |= VP8_EFLAG_NO_REF_GF;
+              [[fallthrough]];
+          case kTemporalUpdateGolden:
+              flags |= VP8_EFLAG_NO_REF_ARF;
+              flags |= VP8_EFLAG_NO_UPD_ARF;
+              flags |= VP8_EFLAG_NO_UPD_LAST;
+              break;
+          case kTemporalUpdateAltrefWithoutDependency:
+              flags |= VP8_EFLAG_NO_REF_ARF;
+              flags |= VP8_EFLAG_NO_REF_GF;
+              [[fallthrough]];
+          case kTemporalUpdateAltref:
+              flags |= VP8_EFLAG_NO_UPD_GF;
+              flags |= VP8_EFLAG_NO_UPD_LAST;
+              break;
+          case kTemporalUpdateNoneNoRefAltref:
+              flags |= VP8_EFLAG_NO_REF_ARF;
+              [[fallthrough]];
+          case kTemporalUpdateNone:
+              flags |= VP8_EFLAG_NO_UPD_GF;
+              flags |= VP8_EFLAG_NO_UPD_ARF;
+              flags |= VP8_EFLAG_NO_UPD_LAST;
+              flags |= VP8_EFLAG_NO_UPD_ENTROPY;
+              break;
+          case kTemporalUpdateNoneNoRefGoldenRefAltRef:
+              flags |= VP8_EFLAG_NO_REF_GF;
+              flags |= VP8_EFLAG_NO_UPD_GF;
+              flags |= VP8_EFLAG_NO_UPD_ARF;
+              flags |= VP8_EFLAG_NO_UPD_LAST;
+              flags |= VP8_EFLAG_NO_UPD_ENTROPY;
+              break;
+          case kTemporalUpdateGoldenWithoutDependencyRefAltRef:
+              flags |= VP8_EFLAG_NO_REF_GF;
+              flags |= VP8_EFLAG_NO_UPD_ARF;
+              flags |= VP8_EFLAG_NO_UPD_LAST;
+              break;
+          case kTemporalUpdateLastRefAltRef:
+              flags |= VP8_EFLAG_NO_UPD_GF;
+              flags |= VP8_EFLAG_NO_UPD_ARF;
+              flags |= VP8_EFLAG_NO_REF_GF;
+              break;
+          case kTemporalUpdateGoldenRefAltRef:
+              flags |= VP8_EFLAG_NO_UPD_ARF;
+              flags |= VP8_EFLAG_NO_UPD_LAST;
+              break;
+          case kTemporalUpdateLastAndGoldenRefAltRef:
+              flags |= VP8_EFLAG_NO_UPD_ARF;
+              flags |= VP8_EFLAG_NO_REF_GF;
+              break;
+          case kTemporalUpdateLastRefAll:
+              flags |= VP8_EFLAG_NO_UPD_ARF;
+              flags |= VP8_EFLAG_NO_UPD_GF;
+              break;
+      }
+    }
+    return flags;
+}
+
+// TODO: add support for YUV input color formats
+// TODO: add support for SVC, ARF. SVC and ARF returns multiple frames
+// (hierarchical / noshow) in one call. These frames should be combined in to
+// a single buffer and sent back to the client
+void C2SoftVpxEnc::process(
+        const std::unique_ptr<C2Work> &work,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    // Initialize output work
+    work->result = C2_OK;
+    work->workletsProcessed = 1u;
+    work->worklets.front()->output.flags = work->input.flags;
+
+    if (mSignalledError || mSignalledOutputEos) {
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+    // Initialize encoder if not already
+    if (!mCodecContext && OK != initEncoder()) {
+        ALOGE("Failed to initialize encoder");
+        mSignalledError = true;
+        work->result = C2_CORRUPTED;
+        return;
+    }
+
+    std::shared_ptr<const C2GraphicView> rView;
+    std::shared_ptr<C2Buffer> inputBuffer;
+    if (!work->input.buffers.empty()) {
+        inputBuffer = work->input.buffers[0];
+        rView = std::make_shared<const C2GraphicView>(
+                    inputBuffer->data().graphicBlocks().front().map().get());
+        if (rView->error() != C2_OK) {
+            ALOGE("graphic view map err = %d", rView->error());
+            work->result = C2_CORRUPTED;
+            return;
+        }
+    } else {
+        ALOGV("Empty input Buffer");
+        uint32_t flags = 0;
+        if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
+            flags |= C2FrameData::FLAG_END_OF_STREAM;
+        }
+        work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
+        work->worklets.front()->output.buffers.clear();
+        work->worklets.front()->output.ordinal = work->input.ordinal;
+        work->workletsProcessed = 1u;
+        return;
+    }
+
+    const C2ConstGraphicBlock inBuffer =
+        inputBuffer->data().graphicBlocks().front();
+    if (inBuffer.width() != mSize->width ||
+        inBuffer.height() != mSize->height) {
+        ALOGE("unexpected Input buffer attributes %d(%d) x %d(%d)",
+              inBuffer.width(), mSize->width, inBuffer.height(),
+              mSize->height);
+        mSignalledError = true;
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
+    vpx_image_t raw_frame;
+    const C2PlanarLayout &layout = rView->layout();
+    uint32_t width = rView->width();
+    uint32_t height = rView->height();
+    if (width > 0x8000 || height > 0x8000) {
+        ALOGE("Image too big: %u x %u", width, height);
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+    uint32_t stride = (width + mStrideAlign - 1) & ~(mStrideAlign - 1);
+    uint32_t vstride = (height + mStrideAlign - 1) & ~(mStrideAlign - 1);
+    switch (layout.type) {
+        case C2PlanarLayout::TYPE_RGB:
+        case C2PlanarLayout::TYPE_RGBA: {
+            ConvertRGBToPlanarYUV(mConversionBuffer.data(), stride, vstride,
+                                  mConversionBuffer.size(), *rView.get());
+            vpx_img_wrap(&raw_frame, VPX_IMG_FMT_I420, width, height,
+                         mStrideAlign, mConversionBuffer.data());
+            break;
+        }
+        case C2PlanarLayout::TYPE_YUV: {
+            if (!IsYUV420(*rView)) {
+                ALOGE("input is not YUV420");
+                work->result = C2_BAD_VALUE;
+                return;
+            }
+
+            if (layout.planes[layout.PLANE_Y].colInc == 1
+                    && layout.planes[layout.PLANE_U].colInc == 1
+                    && layout.planes[layout.PLANE_V].colInc == 1) {
+                // I420 compatible - though with custom offset and stride
+                vpx_img_wrap(&raw_frame, VPX_IMG_FMT_I420, width, height,
+                             mStrideAlign, (uint8_t*)rView->data()[0]);
+                raw_frame.planes[1] = (uint8_t*)rView->data()[1];
+                raw_frame.planes[2] = (uint8_t*)rView->data()[2];
+                raw_frame.stride[0] = layout.planes[layout.PLANE_Y].rowInc;
+                raw_frame.stride[1] = layout.planes[layout.PLANE_U].rowInc;
+                raw_frame.stride[2] = layout.planes[layout.PLANE_V].rowInc;
+            } else {
+                // copy to I420
+                MediaImage2 img = CreateYUV420PlanarMediaImage2(width, height, stride, vstride);
+                if (mConversionBuffer.size() >= stride * vstride * 3 / 2) {
+                    status_t err = ImageCopy(mConversionBuffer.data(), &img, *rView);
+                    if (err != OK) {
+                        ALOGE("Buffer conversion failed: %d", err);
+                        work->result = C2_BAD_VALUE;
+                        return;
+                    }
+                    vpx_img_wrap(&raw_frame, VPX_IMG_FMT_I420, stride, vstride,
+                                 mStrideAlign, (uint8_t*)rView->data()[0]);
+                    vpx_img_set_rect(&raw_frame, 0, 0, width, height);
+                } else {
+                    ALOGE("Conversion buffer is too small: %u x %u for %zu",
+                            stride, vstride, mConversionBuffer.size());
+                    work->result = C2_BAD_VALUE;
+                    return;
+                }
+            }
+            break;
+        }
+        default:
+            ALOGE("Unrecognized plane type: %d", layout.type);
+            work->result = C2_BAD_VALUE;
+            return;
+    }
+
+    vpx_enc_frame_flags_t flags = getEncodeFlags();
+    // handle dynamic config parameters
+    {
+        IntfImpl::Lock lock = mIntf->lock();
+        std::shared_ptr<C2StreamIntraRefreshTuning::output> intraRefresh = mIntf->getIntraRefresh_l();
+        std::shared_ptr<C2StreamBitrateInfo::output> bitrate = mIntf->getBitrate_l();
+        std::shared_ptr<C2StreamRequestSyncFrameTuning::output> requestSync = mIntf->getRequestSync_l();
+        lock.unlock();
+
+        if (intraRefresh != mIntraRefresh) {
+            mIntraRefresh = intraRefresh;
+            ALOGV("Got mIntraRefresh request");
+        }
+
+        if (requestSync != mRequestSync) {
+            // we can handle IDR immediately
+            if (requestSync->value) {
+                // unset request
+                C2StreamRequestSyncFrameTuning::output clearSync(0u, C2_FALSE);
+                std::vector<std::unique_ptr<C2SettingResult>> failures;
+                mIntf->config({ &clearSync }, C2_MAY_BLOCK, &failures);
+                ALOGV("Got sync request");
+                flags |= VPX_EFLAG_FORCE_KF;
+            }
+            mRequestSync = requestSync;
+        }
+
+        if (bitrate != mBitrate) {
+            mBitrate = bitrate;
+            mCodecConfiguration->rc_target_bitrate =
+                (mBitrate->value + 500) / 1000;
+            vpx_codec_err_t res = vpx_codec_enc_config_set(mCodecContext,
+                                                           mCodecConfiguration);
+            if (res != VPX_CODEC_OK) {
+                ALOGE("vpx encoder failed to update bitrate: %s",
+                      vpx_codec_err_to_string(res));
+                mSignalledError = true;
+                work->result = C2_CORRUPTED;
+                return;
+            }
+        }
+    }
+
+    uint64_t inputTimeStamp = work->input.ordinal.timestamp.peekull();
+    uint32_t frameDuration;
+    if (inputTimeStamp > mLastTimestamp) {
+        frameDuration = (uint32_t)(inputTimeStamp - mLastTimestamp);
+    } else {
+        // Use default of 30 fps in case of 0 frame rate.
+        float frameRate = mFrameRate->value;
+        if (frameRate < 0.001) {
+            frameRate = 30;
+        }
+        frameDuration = (uint32_t)(1000000 / frameRate + 0.5);
+    }
+    mLastTimestamp = inputTimeStamp;
+
+    vpx_codec_err_t codec_return = vpx_codec_encode(mCodecContext, &raw_frame,
+                                                    inputTimeStamp,
+                                                    frameDuration, flags,
+                                                    VPX_DL_REALTIME);
+    if (codec_return != VPX_CODEC_OK) {
+        ALOGE("vpx encoder failed to encode frame");
+        mSignalledError = true;
+        work->result = C2_CORRUPTED;
+        return;
+    }
+
+    bool populated = false;
+    vpx_codec_iter_t encoded_packet_iterator = nullptr;
+    const vpx_codec_cx_pkt_t* encoded_packet;
+    while ((encoded_packet = vpx_codec_get_cx_data(
+                    mCodecContext, &encoded_packet_iterator))) {
+        if (encoded_packet->kind == VPX_CODEC_CX_FRAME_PKT) {
+            std::shared_ptr<C2LinearBlock> block;
+            C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+            c2_status_t err = pool->fetchLinearBlock(encoded_packet->data.frame.sz, usage, &block);
+            if (err != C2_OK) {
+                ALOGE("fetchLinearBlock for Output failed with status %d", err);
+                work->result = C2_NO_MEMORY;
+                return;
+            }
+            C2WriteView wView = block->map().get();
+            if (wView.error()) {
+                ALOGE("write view map failed %d", wView.error());
+                work->result = C2_CORRUPTED;
+                return;
+            }
+
+            memcpy(wView.data(), encoded_packet->data.frame.buf, encoded_packet->data.frame.sz);
+            ++mNumInputFrames;
+
+            ALOGD("bytes generated %zu", encoded_packet->data.frame.sz);
+            uint32_t flags = 0;
+            if (eos) {
+                flags |= C2FrameData::FLAG_END_OF_STREAM;
+            }
+            work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
+            work->worklets.front()->output.buffers.clear();
+            std::shared_ptr<C2Buffer> buffer = createLinearBuffer(block);
+            if (encoded_packet->data.frame.flags & VPX_FRAME_IS_KEY) {
+                buffer->setInfo(std::make_shared<C2StreamPictureTypeMaskInfo::output>(
+                        0u /* stream id */, C2Config::SYNC_FRAME));
+            }
+            work->worklets.front()->output.buffers.push_back(buffer);
+            work->worklets.front()->output.ordinal = work->input.ordinal;
+            work->worklets.front()->output.ordinal.timestamp = encoded_packet->data.frame.pts;
+            work->workletsProcessed = 1u;
+            populated = true;
+            if (eos) {
+                mSignalledOutputEos = true;
+                ALOGV("signalled EOS");
+            }
+        }
+    }
+    if (!populated) {
+        work->workletsProcessed = 0u;
+    }
+}
+
+c2_status_t C2SoftVpxEnc::drain(
+        uint32_t drainMode,
+        const std::shared_ptr<C2BlockPool> &pool) {
+    (void)pool;
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+
+    return C2_OK;
+}
+
+}  // namespace android
diff --git a/media/codec2/components/vpx/C2SoftVpxEnc.h b/media/codec2/components/vpx/C2SoftVpxEnc.h
new file mode 100644
index 0000000..62ccd1b
--- /dev/null
+++ b/media/codec2/components/vpx/C2SoftVpxEnc.h
@@ -0,0 +1,433 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_VPX_ENC_H__
+#define ANDROID_C2_SOFT_VPX_ENC_H__
+
+#include <media/stagefright/foundation/MediaDefs.h>
+
+#include <C2PlatformSupport.h>
+#include <Codec2BufferUtils.h>
+#include <SimpleC2Component.h>
+#include <SimpleC2Interface.h>
+#include <util/C2InterfaceHelper.h>
+
+#include "vpx/vpx_encoder.h"
+#include "vpx/vpx_codec.h"
+#include "vpx/vpx_image.h"
+#include "vpx/vp8cx.h"
+
+namespace android {
+
+// TODO: These defs taken from deprecated OMX_VideoExt.h. Move these definitions
+// to a new header file and include it.
+
+/** Maximum number of temporal layers */
+#define MAXTEMPORALLAYERS 3
+
+/** temporal layer patterns */
+typedef enum TemporalPatternType {
+    VPXTemporalLayerPatternNone = 0,
+    VPXTemporalLayerPatternWebRTC = 1,
+    VPXTemporalLayerPatternMax = 0x7FFFFFFF
+} TemporalPatternType;
+
+// Base class for a VPX Encoder Component
+//
+// Only following encoder settings are available (codec specific settings might
+// be available in the sub-classes):
+//    - video resolution
+//    - target bitrate
+//    - rate control (constant / variable)
+//    - frame rate
+//    - error resilience
+//    - reconstruction & loop filters (g_profile)
+//
+// Only following color formats are recognized
+//    - C2PlanarLayout::TYPE_RGB
+//    - C2PlanarLayout::TYPE_RGBA
+//
+// Following settings are not configurable by the client
+//    - encoding deadline is realtime
+//    - multithreaded encoding utilizes a number of threads equal
+// to online cpu's available
+//    - the algorithm interface for encoder is decided by the sub-class in use
+//    - fractional bits of frame rate is discarded
+//    - timestamps are in microseconds, therefore encoder timebase is fixed
+// to 1/1000000
+
+struct C2SoftVpxEnc : public SimpleC2Component {
+    class IntfImpl;
+
+    C2SoftVpxEnc(const char* name, c2_node_id_t id,
+                 const std::shared_ptr<IntfImpl>& intfImpl);
+
+    // From SimpleC2Component
+    c2_status_t onInit() override final;
+    c2_status_t onStop() override final;
+    void onReset() override final;
+    void onRelease() override final;
+    c2_status_t onFlush_sm() override final;
+
+    void process(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool) override final;
+    c2_status_t drain(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool) override final;
+
+ protected:
+     std::shared_ptr<IntfImpl> mIntf;
+     virtual ~C2SoftVpxEnc();
+
+     // Initializes vpx encoder with available settings.
+     status_t initEncoder();
+
+     // Populates mCodecInterface with codec specific settings.
+     virtual void setCodecSpecificInterface() = 0;
+
+     // Sets codec specific configuration.
+     virtual void setCodecSpecificConfiguration() = 0;
+
+     // Sets codec specific encoder controls.
+     virtual vpx_codec_err_t setCodecSpecificControls() = 0;
+
+     // Get current encode flags.
+     virtual vpx_enc_frame_flags_t getEncodeFlags();
+
+     enum TemporalReferences {
+         // For 1 layer case: reference all (last, golden, and alt ref), but only
+         // update last.
+         kTemporalUpdateLastRefAll = 12,
+         // First base layer frame for 3 temporal layers, which updates last and
+         // golden with alt ref dependency.
+         kTemporalUpdateLastAndGoldenRefAltRef = 11,
+         // First enhancement layer with alt ref dependency.
+         kTemporalUpdateGoldenRefAltRef = 10,
+         // First enhancement layer with alt ref dependency.
+         kTemporalUpdateGoldenWithoutDependencyRefAltRef = 9,
+         // Base layer with alt ref dependency.
+         kTemporalUpdateLastRefAltRef = 8,
+         // Highest enhacement layer without dependency on golden with alt ref
+         // dependency.
+         kTemporalUpdateNoneNoRefGoldenRefAltRef = 7,
+         // Second layer and last frame in cycle, for 2 layers.
+         kTemporalUpdateNoneNoRefAltref = 6,
+         // Highest enhancement layer.
+         kTemporalUpdateNone = 5,
+         // Second enhancement layer.
+         kTemporalUpdateAltref = 4,
+         // Second enhancement layer without dependency on previous frames in
+         // the second enhancement layer.
+         kTemporalUpdateAltrefWithoutDependency = 3,
+         // First enhancement layer.
+         kTemporalUpdateGolden = 2,
+         // First enhancement layer without dependency on previous frames in
+         // the first enhancement layer.
+         kTemporalUpdateGoldenWithoutDependency = 1,
+         // Base layer.
+         kTemporalUpdateLast = 0,
+     };
+     enum {
+         kMaxTemporalPattern = 8
+     };
+
+     // vpx specific opaque data structure that
+     // stores encoder state
+     vpx_codec_ctx_t* mCodecContext;
+
+     // vpx specific data structure that
+     // stores encoder configuration
+     vpx_codec_enc_cfg_t* mCodecConfiguration;
+
+     // vpx specific read-only data structure
+     // that specifies algorithm interface (e.g. vp8)
+     vpx_codec_iface_t* mCodecInterface;
+
+     // align stride to the power of 2
+     int32_t mStrideAlign;
+
+     // Color format for the input port
+     vpx_img_fmt_t mColorFormat;
+
+     // Bitrate control mode, either constant or variable
+     vpx_rc_mode mBitrateControlMode;
+
+     // Parameter that denotes whether error resilience
+     // is enabled in encoder
+     bool mErrorResilience;
+
+     // Minimum (best quality) quantizer
+     uint32_t mMinQuantizer;
+
+     // Maximum (worst quality) quantizer
+     uint32_t mMaxQuantizer;
+
+     // Number of coding temporal layers to be used.
+     size_t mTemporalLayers;
+
+     // Temporal layer bitrare ratio in percentage
+     uint32_t mTemporalLayerBitrateRatio[MAXTEMPORALLAYERS];
+
+     // Temporal pattern type
+     TemporalPatternType mTemporalPatternType;
+
+     // Temporal pattern length
+     size_t mTemporalPatternLength;
+
+     // Temporal pattern current index
+     size_t mTemporalPatternIdx;
+
+     // Frame type temporal pattern
+     TemporalReferences mTemporalPattern[kMaxTemporalPattern];
+
+     // Last input buffer timestamp
+     uint64_t mLastTimestamp;
+
+     // Number of input frames
+     int64_t mNumInputFrames;
+
+     // Conversion buffer is needed to input to
+     // yuv420 planar format.
+     MemoryBlock mConversionBuffer;
+
+     // Signalled EOS
+     bool mSignalledOutputEos;
+
+     // Signalled Error
+     bool mSignalledError;
+
+    // configurations used by component in process
+    // (TODO: keep this in intf but make them internal only)
+    std::shared_ptr<C2StreamPictureSizeInfo::input> mSize;
+    std::shared_ptr<C2StreamIntraRefreshTuning::output> mIntraRefresh;
+    std::shared_ptr<C2StreamFrameRateInfo::output> mFrameRate;
+    std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
+    std::shared_ptr<C2StreamBitrateModeTuning::output> mBitrateMode;
+    std::shared_ptr<C2StreamRequestSyncFrameTuning::output> mRequestSync;
+
+     C2_DO_NOT_COPY(C2SoftVpxEnc);
+};
+
+namespace {
+
+#ifdef VP9
+constexpr char COMPONENT_NAME[] = "c2.android.vp9.encoder";
+const char *MEDIA_MIMETYPE_VIDEO = MEDIA_MIMETYPE_VIDEO_VP9;
+#else
+constexpr char COMPONENT_NAME[] = "c2.android.vp8.encoder";
+const char *MEDIA_MIMETYPE_VIDEO = MEDIA_MIMETYPE_VIDEO_VP8;
+#endif
+
+} // namepsace
+
+class C2SoftVpxEnc::IntfImpl : public SimpleInterface<void>::BaseParams {
+   public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+        : SimpleInterface<void>::BaseParams(
+                helper,
+                COMPONENT_NAME,
+                C2Component::KIND_ENCODER,
+                C2Component::DOMAIN_VIDEO,
+                MEDIA_MIMETYPE_VIDEO) {
+        noPrivateBuffers(); // TODO: account for our buffers here
+        noInputReferences();
+        noOutputReferences();
+        noInputLatency();
+        noTimeStretch();
+        setDerivedInstance(this);
+
+        addParameter(
+                DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                .withConstValue(new C2ComponentAttributesSetting(
+                    C2Component::ATTRIB_IS_TEMPORAL))
+                .build());
+
+        addParameter(
+                DefineParam(mUsage, C2_PARAMKEY_INPUT_STREAM_USAGE)
+                .withConstValue(new C2StreamUsageTuning::input(
+                        0u, (uint64_t)C2MemoryUsage::CPU_READ))
+                .build());
+
+        addParameter(
+            DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
+                .withDefault(new C2StreamPictureSizeInfo::input(0u, 320, 240))
+                .withFields({
+                    C2F(mSize, width).inRange(2, 2048, 2),
+                    C2F(mSize, height).inRange(2, 2048, 2),
+                })
+                .withSetter(SizeSetter)
+                .build());
+
+        addParameter(
+            DefineParam(mBitrateMode, C2_PARAMKEY_BITRATE_MODE)
+                .withDefault(new C2StreamBitrateModeTuning::output(
+                        0u, C2Config::BITRATE_VARIABLE))
+                .withFields({
+                    C2F(mBitrateMode, value).oneOf({
+                        C2Config::BITRATE_CONST, C2Config::BITRATE_VARIABLE })
+                })
+                .withSetter(
+                    Setter<decltype(*mBitrateMode)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+            DefineParam(mFrameRate, C2_PARAMKEY_FRAME_RATE)
+                .withDefault(new C2StreamFrameRateInfo::output(0u, 30.))
+                // TODO: More restriction?
+                .withFields({C2F(mFrameRate, value).greaterThan(0.)})
+                .withSetter(
+                    Setter<decltype(*mFrameRate)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+            DefineParam(mLayering, C2_PARAMKEY_TEMPORAL_LAYERING)
+                .withDefault(C2StreamTemporalLayeringTuning::output::AllocShared(0u, 0, 0, 0))
+                .withFields({
+                    C2F(mLayering, m.layerCount).inRange(0, 4),
+                    C2F(mLayering, m.bLayerCount).inRange(0, 0),
+                    C2F(mLayering, m.bitrateRatios).inRange(0., 1.)
+                })
+                .withSetter(LayeringSetter)
+                .build());
+
+        addParameter(
+                DefineParam(mSyncFramePeriod, C2_PARAMKEY_SYNC_FRAME_INTERVAL)
+                .withDefault(new C2StreamSyncFrameIntervalTuning::output(0u, 1000000))
+                .withFields({C2F(mSyncFramePeriod, value).any()})
+                .withSetter(Setter<decltype(*mSyncFramePeriod)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+            DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
+                .withDefault(new C2StreamBitrateInfo::output(0u, 64000))
+                .withFields({C2F(mBitrate, value).inRange(4096, 40000000)})
+                .withSetter(BitrateSetter)
+                .build());
+
+        addParameter(
+                DefineParam(mIntraRefresh, C2_PARAMKEY_INTRA_REFRESH)
+                .withConstValue(new C2StreamIntraRefreshTuning::output(
+                             0u, C2Config::INTRA_REFRESH_DISABLED, 0.))
+                .build());
+
+        addParameter(
+        DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
+        .withDefault(new C2StreamProfileLevelInfo::output(
+                0u, PROFILE_VP9_0, LEVEL_VP9_4_1))
+        .withFields({
+            C2F(mProfileLevel, profile).equalTo(
+                PROFILE_VP9_0
+            ),
+            C2F(mProfileLevel, level).equalTo(
+                LEVEL_VP9_4_1),
+        })
+        .withSetter(ProfileLevelSetter)
+        .build());
+
+        addParameter(
+                DefineParam(mRequestSync, C2_PARAMKEY_REQUEST_SYNC_FRAME)
+                .withDefault(new C2StreamRequestSyncFrameTuning::output(0u, C2_FALSE))
+                .withFields({C2F(mRequestSync, value).oneOf({ C2_FALSE, C2_TRUE }) })
+                .withSetter(Setter<decltype(*mRequestSync)>::NonStrictValueWithNoDeps)
+                .build());
+    }
+
+    static C2R BitrateSetter(bool mayBlock, C2P<C2StreamBitrateInfo::output> &me) {
+        (void)mayBlock;
+        C2R res = C2R::Ok();
+        if (me.v.value <= 4096) {
+            me.set().value = 4096;
+        }
+        return res;
+    }
+
+    static C2R SizeSetter(bool mayBlock, const C2P<C2StreamPictureSizeInfo::input> &oldMe,
+                          C2P<C2StreamPictureSizeInfo::input> &me) {
+        (void)mayBlock;
+        C2R res = C2R::Ok();
+        if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
+            res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
+            me.set().width = oldMe.v.width;
+        }
+        if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
+            res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
+            me.set().height = oldMe.v.height;
+        }
+        return res;
+    }
+
+    static C2R ProfileLevelSetter(
+            bool mayBlock,
+            C2P<C2StreamProfileLevelInfo::output> &me) {
+        (void)mayBlock;
+        if (!me.F(me.v.profile).supportsAtAll(me.v.profile)) {
+            me.set().profile = PROFILE_VP9_0;
+        }
+        if (!me.F(me.v.level).supportsAtAll(me.v.level)) {
+            me.set().level = LEVEL_VP9_4_1;
+        }
+        return C2R::Ok();
+    }
+
+    static C2R LayeringSetter(bool mayBlock, C2P<C2StreamTemporalLayeringTuning::output>& me) {
+        (void)mayBlock;
+        C2R res = C2R::Ok();
+        if (me.v.m.layerCount > 4) {
+            me.set().m.layerCount = 4;
+        }
+        me.set().m.bLayerCount = 0;
+        // ensure ratios are monotonic and clamped between 0 and 1
+        for (size_t ix = 0; ix < me.v.flexCount(); ++ix) {
+            me.set().m.bitrateRatios[ix] = c2_clamp(
+                ix > 0 ? me.v.m.bitrateRatios[ix - 1] : 0, me.v.m.bitrateRatios[ix], 1.);
+        }
+        ALOGI("setting temporal layering %u + %u", me.v.m.layerCount, me.v.m.bLayerCount);
+        return res;
+    }
+
+    // unsafe getters
+    std::shared_ptr<C2StreamPictureSizeInfo::input> getSize_l() const { return mSize; }
+    std::shared_ptr<C2StreamIntraRefreshTuning::output> getIntraRefresh_l() const { return mIntraRefresh; }
+    std::shared_ptr<C2StreamFrameRateInfo::output> getFrameRate_l() const { return mFrameRate; }
+    std::shared_ptr<C2StreamBitrateInfo::output> getBitrate_l() const { return mBitrate; }
+    std::shared_ptr<C2StreamBitrateModeTuning::output> getBitrateMode_l() const { return mBitrateMode; }
+    std::shared_ptr<C2StreamRequestSyncFrameTuning::output> getRequestSync_l() const { return mRequestSync; }
+    std::shared_ptr<C2StreamTemporalLayeringTuning::output> getTemporalLayers_l() const { return mLayering; }
+    uint32_t getSyncFramePeriod() const {
+        if (mSyncFramePeriod->value < 0 || mSyncFramePeriod->value == INT64_MAX) {
+            return 0;
+        }
+        double period = mSyncFramePeriod->value / 1e6 * mFrameRate->value;
+        return (uint32_t)c2_max(c2_min(period + 0.5, double(UINT32_MAX)), 1.);
+    }
+
+   private:
+    std::shared_ptr<C2StreamUsageTuning::input> mUsage;
+    std::shared_ptr<C2StreamPictureSizeInfo::input> mSize;
+    std::shared_ptr<C2StreamFrameRateInfo::output> mFrameRate;
+    std::shared_ptr<C2StreamTemporalLayeringTuning::output> mLayering;
+    std::shared_ptr<C2StreamIntraRefreshTuning::output> mIntraRefresh;
+    std::shared_ptr<C2StreamRequestSyncFrameTuning::output> mRequestSync;
+    std::shared_ptr<C2StreamSyncFrameIntervalTuning::output> mSyncFramePeriod;
+    std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
+    std::shared_ptr<C2StreamBitrateModeTuning::output> mBitrateMode;
+    std::shared_ptr<C2StreamProfileLevelInfo::output> mProfileLevel;
+};
+
+}  // namespace android
+
+#endif  // ANDROID_C2_SOFT_VPX_ENC_H__
diff --git a/media/common_time/MODULE_LICENSE_APACHE2 b/media/codec2/components/vpx/MODULE_LICENSE_APACHE2
similarity index 100%
copy from media/common_time/MODULE_LICENSE_APACHE2
copy to media/codec2/components/vpx/MODULE_LICENSE_APACHE2
diff --git a/media/codec2/components/vpx/NOTICE b/media/codec2/components/vpx/NOTICE
new file mode 100644
index 0000000..faed58a
--- /dev/null
+++ b/media/codec2/components/vpx/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-2013, The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/media/codec2/components/xaac/Android.bp b/media/codec2/components/xaac/Android.bp
new file mode 100644
index 0000000..7795cc1
--- /dev/null
+++ b/media/codec2/components/xaac/Android.bp
@@ -0,0 +1,11 @@
+cc_library_shared {
+    name: "libcodec2_soft_xaacdec",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["C2SoftXaacDec.cpp"],
+
+    static_libs: ["libxaacdec"],
+}
diff --git a/media/codec2/components/xaac/C2SoftXaacDec.cpp b/media/codec2/components/xaac/C2SoftXaacDec.cpp
new file mode 100644
index 0000000..a3ebadb
--- /dev/null
+++ b/media/codec2/components/xaac/C2SoftXaacDec.cpp
@@ -0,0 +1,1595 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftXaacDec"
+#include <log/log.h>
+
+#include <inttypes.h>
+
+#include <cutils/properties.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/MediaDefs.h>
+#include <media/stagefright/foundation/hexdump.h>
+
+#include <C2PlatformSupport.h>
+#include <SimpleC2Interface.h>
+
+#include "C2SoftXaacDec.h"
+
+#define DRC_DEFAULT_MOBILE_REF_LEVEL -16.0   /* 64*-0.25dB = -16 dB below full scale for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_CUT   1.0  /* maximum compression of dynamic range for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_BOOST 1.0 /* maximum compression of dynamic range for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_HEAVY C2Config::DRC_COMPRESSION_HEAVY   /* switch for heavy compression for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_EFFECT 3  /* MPEG-D DRC effect type; 3 => Limited playback range */
+#define DRC_DEFAULT_MOBILE_ENC_LEVEL (0.25) /* encoder target level; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
+#define MAX_CHANNEL_COUNT            8  /* maximum number of audio channels that can be decoded */
+// names of properties that can be used to override the default DRC settings
+#define PROP_DRC_OVERRIDE_REF_LEVEL  "aac_drc_reference_level"
+#define PROP_DRC_OVERRIDE_CUT        "aac_drc_cut"
+#define PROP_DRC_OVERRIDE_BOOST      "aac_drc_boost"
+#define PROP_DRC_OVERRIDE_HEAVY      "aac_drc_heavy"
+#define PROP_DRC_OVERRIDE_ENC_LEVEL  "aac_drc_enc_target_level"
+#define PROP_DRC_OVERRIDE_EFFECT_TYPE "ro.aac_drc_effect_type"
+
+#define RETURN_IF_FATAL(retval, str)                       \
+    if (retval & IA_FATAL_ERROR) {                         \
+        ALOGE("Error in %s: Returned: %d", str, retval);   \
+        return retval;                                     \
+    } else if (retval != IA_NO_ERROR) {                    \
+        ALOGW("Warning in %s: Returned: %d", str, retval); \
+    }
+
+
+namespace android {
+
+namespace {
+
+constexpr char COMPONENT_NAME[] = "c2.android.xaac.decoder";
+
+}  // namespace
+
+class C2SoftXaacDec::IntfImpl : public SimpleInterface<void>::BaseParams {
+public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+        : SimpleInterface<void>::BaseParams(
+                helper,
+                COMPONENT_NAME,
+                C2Component::KIND_DECODER,
+                C2Component::DOMAIN_AUDIO,
+                MEDIA_MIMETYPE_AUDIO_AAC) {
+        noPrivateBuffers();
+        noInputReferences();
+        noOutputReferences();
+        noInputLatency();
+        noTimeStretch();
+
+        addParameter(
+                DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                .withConstValue(new C2ComponentAttributesSetting(
+                    C2Component::ATTRIB_IS_TEMPORAL))
+                .build());
+
+        addParameter(
+                DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE)
+                .withDefault(new C2StreamSampleRateInfo::output(0u, 44100))
+                .withFields({C2F(mSampleRate, value).oneOf({
+                    7350, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
+                })})
+                .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
+                .build());
+
+        addParameter(
+                DefineParam(mChannelCount, C2_PARAMKEY_CHANNEL_COUNT)
+                .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
+                .withFields({C2F(mChannelCount, value).inRange(1, 8)})
+                .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
+                .withDefault(new C2StreamBitrateInfo::input(0u, 64000))
+                .withFields({C2F(mBitrate, value).inRange(8000, 960000)})
+                .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
+                .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 8192))
+                .build());
+
+        addParameter(
+                DefineParam(mAacFormat, C2_PARAMKEY_AAC_PACKAGING)
+                .withDefault(new C2StreamAacFormatInfo::input(0u, C2Config::AAC_PACKAGING_RAW))
+                .withFields({C2F(mAacFormat, value).oneOf({
+                    C2Config::AAC_PACKAGING_RAW, C2Config::AAC_PACKAGING_ADTS
+                })})
+                .withSetter(Setter<decltype(*mAacFormat)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
+                .withDefault(new C2StreamProfileLevelInfo::input(0u,
+                        C2Config::PROFILE_AAC_LC, C2Config::LEVEL_UNUSED))
+                .withFields({
+                    C2F(mProfileLevel, profile).oneOf({
+                            C2Config::PROFILE_AAC_LC,
+                            C2Config::PROFILE_AAC_HE,
+                            C2Config::PROFILE_AAC_HE_PS,
+                            C2Config::PROFILE_AAC_LD,
+                            C2Config::PROFILE_AAC_ELD,
+                            C2Config::PROFILE_AAC_XHE}),
+                    C2F(mProfileLevel, level).oneOf({
+                            C2Config::LEVEL_UNUSED
+                    })
+                })
+                .withSetter(ProfileLevelSetter)
+                .build());
+
+        addParameter(
+                DefineParam(mDrcCompressMode, C2_PARAMKEY_DRC_COMPRESSION_MODE)
+                .withDefault(new C2StreamDrcCompressionModeTuning::input(0u, C2Config::DRC_COMPRESSION_HEAVY))
+                .withFields({
+                    C2F(mDrcCompressMode, value).oneOf({
+                            C2Config::DRC_COMPRESSION_ODM_DEFAULT,
+                            C2Config::DRC_COMPRESSION_NONE,
+                            C2Config::DRC_COMPRESSION_LIGHT,
+                            C2Config::DRC_COMPRESSION_HEAVY})
+                })
+                .withSetter(Setter<decltype(*mDrcCompressMode)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mDrcTargetRefLevel, C2_PARAMKEY_DRC_TARGET_REFERENCE_LEVEL)
+                .withDefault(new C2StreamDrcTargetReferenceLevelTuning::input(0u, DRC_DEFAULT_MOBILE_REF_LEVEL))
+                .withFields({C2F(mDrcTargetRefLevel, value).inRange(-31.75, 0.25)})
+                .withSetter(Setter<decltype(*mDrcTargetRefLevel)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mDrcEncTargetLevel, C2_PARAMKEY_DRC_ENCODED_TARGET_LEVEL)
+                .withDefault(new C2StreamDrcEncodedTargetLevelTuning::input(0u, DRC_DEFAULT_MOBILE_ENC_LEVEL))
+                .withFields({C2F(mDrcEncTargetLevel, value).inRange(-31.75, 0.25)})
+                .withSetter(Setter<decltype(*mDrcEncTargetLevel)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mDrcBoostFactor, C2_PARAMKEY_DRC_BOOST_FACTOR)
+                .withDefault(new C2StreamDrcBoostFactorTuning::input(0u, DRC_DEFAULT_MOBILE_DRC_BOOST))
+                .withFields({C2F(mDrcBoostFactor, value).inRange(0, 1.)})
+                .withSetter(Setter<decltype(*mDrcBoostFactor)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mDrcAttenuationFactor, C2_PARAMKEY_DRC_ATTENUATION_FACTOR)
+                .withDefault(new C2StreamDrcAttenuationFactorTuning::input(0u, DRC_DEFAULT_MOBILE_DRC_CUT))
+                .withFields({C2F(mDrcAttenuationFactor, value).inRange(0, 1.)})
+                .withSetter(Setter<decltype(*mDrcAttenuationFactor)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
+                DefineParam(mDrcEffectType, C2_PARAMKEY_DRC_EFFECT_TYPE)
+                .withDefault(new C2StreamDrcEffectTypeTuning::input(0u, C2Config::DRC_EFFECT_LIMITED_PLAYBACK_RANGE))
+                .withFields({
+                    C2F(mDrcEffectType, value).oneOf({
+                            C2Config::DRC_EFFECT_ODM_DEFAULT,
+                            C2Config::DRC_EFFECT_OFF,
+                            C2Config::DRC_EFFECT_NONE,
+                            C2Config::DRC_EFFECT_LATE_NIGHT,
+                            C2Config::DRC_EFFECT_NOISY_ENVIRONMENT,
+                            C2Config::DRC_EFFECT_LIMITED_PLAYBACK_RANGE,
+                            C2Config::DRC_EFFECT_LOW_PLAYBACK_LEVEL,
+                            C2Config::DRC_EFFECT_DIALOG_ENHANCEMENT,
+                            C2Config::DRC_EFFECT_GENERAL_COMPRESSION})
+                })
+                .withSetter(Setter<decltype(*mDrcEffectType)>::StrictValueWithNoDeps)
+                .build());
+    }
+
+    bool isAdts() const { return mAacFormat->value == C2Config::AAC_PACKAGING_ADTS; }
+    uint32_t getBitrate() const { return mBitrate->value; }
+    static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me) {
+        (void)mayBlock;
+        (void)me;  // TODO: validate
+        return C2R::Ok();
+    }
+    int32_t getDrcCompressMode() const { return mDrcCompressMode->value == C2Config::DRC_COMPRESSION_HEAVY ? 1 : 0; }
+    int32_t getDrcTargetRefLevel() const { return (mDrcTargetRefLevel->value <= 0 ? -mDrcTargetRefLevel->value * 4. + 0.5 : -1); }
+    int32_t getDrcEncTargetLevel() const { return (mDrcEncTargetLevel->value <= 0 ? -mDrcEncTargetLevel->value * 4. + 0.5 : -1); }
+    int32_t getDrcBoostFactor() const { return mDrcBoostFactor->value * 127. + 0.5; }
+    int32_t getDrcAttenuationFactor() const { return mDrcAttenuationFactor->value * 127. + 0.5; }
+    int32_t getDrcEffectType() const { return mDrcEffectType->value; }
+
+private:
+    std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
+    std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
+    std::shared_ptr<C2StreamBitrateInfo::input> mBitrate;
+    std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
+    std::shared_ptr<C2StreamAacFormatInfo::input> mAacFormat;
+    std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
+    std::shared_ptr<C2StreamDrcCompressionModeTuning::input> mDrcCompressMode;
+    std::shared_ptr<C2StreamDrcTargetReferenceLevelTuning::input> mDrcTargetRefLevel;
+    std::shared_ptr<C2StreamDrcEncodedTargetLevelTuning::input> mDrcEncTargetLevel;
+    std::shared_ptr<C2StreamDrcBoostFactorTuning::input> mDrcBoostFactor;
+    std::shared_ptr<C2StreamDrcAttenuationFactorTuning::input> mDrcAttenuationFactor;
+    std::shared_ptr<C2StreamDrcEffectTypeTuning::input> mDrcEffectType;
+    // TODO Add : C2StreamAacSbrModeTuning
+};
+
+C2SoftXaacDec::C2SoftXaacDec(
+        const char* name,
+        c2_node_id_t id,
+        const std::shared_ptr<IntfImpl> &intfImpl)
+    : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+        mIntf(intfImpl),
+        mXheaacCodecHandle(nullptr),
+        mMpegDDrcHandle(nullptr),
+        mOutputDrainBuffer(nullptr) {
+}
+
+C2SoftXaacDec::~C2SoftXaacDec() {
+    onRelease();
+}
+
+c2_status_t C2SoftXaacDec::onInit() {
+    mOutputFrameLength = 1024;
+    mInputBuffer = nullptr;
+    mOutputBuffer = nullptr;
+    mSampFreq = 0;
+    mNumChannels = 0;
+    mPcmWdSz = 0;
+    mChannelMask = 0;
+    mNumOutBytes = 0;
+    mCurFrameIndex = 0;
+    mCurTimestamp = 0;
+    mIsCodecInitialized = false;
+    mIsCodecConfigFlushRequired = false;
+    mSignalledOutputEos = false;
+    mSignalledError = false;
+    mOutputDrainBufferWritePos = 0;
+    mDRCFlag = 0;
+    mMpegDDRCPresent = 0;
+    mMemoryVec.clear();
+    mDrcMemoryVec.clear();
+
+    IA_ERRORCODE err = initDecoder();
+    return err == IA_NO_ERROR ? C2_OK : C2_CORRUPTED;
+
+}
+
+c2_status_t C2SoftXaacDec::onStop() {
+    mOutputFrameLength = 1024;
+    drainDecoder();
+    // reset the "configured" state
+    mSampFreq = 0;
+    mNumChannels = 0;
+    mPcmWdSz = 0;
+    mChannelMask = 0;
+    mNumOutBytes = 0;
+    mCurFrameIndex = 0;
+    mCurTimestamp = 0;
+    mSignalledOutputEos = false;
+    mSignalledError = false;
+    mOutputDrainBufferWritePos = 0;
+    mDRCFlag = 0;
+    mMpegDDRCPresent = 0;
+
+    return C2_OK;
+}
+
+void C2SoftXaacDec::onReset() {
+    (void)onStop();
+}
+
+void C2SoftXaacDec::onRelease() {
+    IA_ERRORCODE errCode = deInitXAACDecoder();
+    if (IA_NO_ERROR != errCode) ALOGE("deInitXAACDecoder() failed %d", errCode);
+
+    errCode = deInitMPEGDDDrc();
+    if (IA_NO_ERROR != errCode) ALOGE("deInitMPEGDDDrc() failed %d", errCode);
+
+    if (mOutputDrainBuffer) {
+        delete[] mOutputDrainBuffer;
+        mOutputDrainBuffer = nullptr;
+    }
+}
+
+IA_ERRORCODE C2SoftXaacDec::initDecoder() {
+    ALOGV("initDecoder()");
+    IA_ERRORCODE err_code = IA_NO_ERROR;
+
+    err_code = initXAACDecoder();
+    if (err_code != IA_NO_ERROR) {
+        ALOGE("initXAACDecoder Failed");
+        /* Call deInit to free any allocated memory */
+        deInitXAACDecoder();
+        return IA_FATAL_ERROR;
+    }
+
+    if (!mOutputDrainBuffer) {
+        mOutputDrainBuffer = new (std::nothrow) char[kOutputDrainBufferSize];
+        if (!mOutputDrainBuffer) return IA_FATAL_ERROR;
+    }
+
+    err_code = initXAACDrc();
+    RETURN_IF_FATAL(err_code,  "initXAACDrc");
+
+
+    return IA_NO_ERROR;
+}
+
+static void fillEmptyWork(const std::unique_ptr<C2Work>& work) {
+    uint32_t flags = 0;
+    if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
+        flags |= C2FrameData::FLAG_END_OF_STREAM;
+        ALOGV("signalling eos");
+    }
+    work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
+    work->worklets.front()->output.buffers.clear();
+    work->worklets.front()->output.ordinal = work->input.ordinal;
+    work->workletsProcessed = 1u;
+}
+
+void C2SoftXaacDec::finishWork(const std::unique_ptr<C2Work>& work,
+                            const std::shared_ptr<C2BlockPool>& pool) {
+    ALOGV("mCurFrameIndex = %" PRIu64, mCurFrameIndex);
+
+    std::shared_ptr<C2LinearBlock> block;
+    C2MemoryUsage usage = {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE};
+    // TODO: error handling, proper usage, etc.
+    c2_status_t err =
+        pool->fetchLinearBlock(mOutputDrainBufferWritePos, usage, &block);
+    if (err != C2_OK) {
+        ALOGE("fetchLinearBlock failed : err = %d", err);
+        work->result = C2_NO_MEMORY;
+        return;
+    }
+    C2WriteView wView = block->map().get();
+    int16_t* outBuffer = reinterpret_cast<int16_t*>(wView.data());
+    memcpy(outBuffer, mOutputDrainBuffer, mOutputDrainBufferWritePos);
+    mOutputDrainBufferWritePos = 0;
+
+    auto fillWork = [buffer = createLinearBuffer(block)](
+        const std::unique_ptr<C2Work>& work) {
+        uint32_t flags = 0;
+        if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
+            flags |= C2FrameData::FLAG_END_OF_STREAM;
+            ALOGV("signalling eos");
+        }
+        work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
+        work->worklets.front()->output.buffers.clear();
+        work->worklets.front()->output.buffers.push_back(buffer);
+        work->worklets.front()->output.ordinal = work->input.ordinal;
+        work->workletsProcessed = 1u;
+    };
+    if (work && work->input.ordinal.frameIndex == c2_cntr64_t(mCurFrameIndex)) {
+        fillWork(work);
+    } else {
+        finish(mCurFrameIndex, fillWork);
+    }
+
+    ALOGV("out timestamp %" PRIu64 " / %u", mCurTimestamp, block->capacity());
+}
+
+void C2SoftXaacDec::process(const std::unique_ptr<C2Work>& work,
+                         const std::shared_ptr<C2BlockPool>& pool) {
+    // Initialize output work
+    work->result = C2_OK;
+    work->workletsProcessed = 1u;
+    work->worklets.front()->output.configUpdate.clear();
+    work->worklets.front()->output.flags = work->input.flags;
+
+    if (mSignalledError || mSignalledOutputEos) {
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+    uint8_t* inBuffer = nullptr;
+    uint32_t inBufferLength = 0;
+    C2ReadView view = mDummyReadView;
+    size_t offset = 0u;
+    size_t size = 0u;
+    if (!work->input.buffers.empty()) {
+        view = work->input.buffers[0]->data().linearBlocks().front().map().get();
+        size = view.capacity();
+    }
+    if (size && view.error()) {
+        ALOGE("read view map failed %d", view.error());
+        work->result = view.error();
+        return;
+    }
+
+    bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
+    bool codecConfig =
+        (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0;
+    if (codecConfig) {
+        if (size == 0u) {
+            ALOGE("empty codec config");
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+        // const_cast because of libAACdec method signature.
+        inBuffer = const_cast<uint8_t*>(view.data() + offset);
+        inBufferLength = size;
+
+        /* GA header configuration sent to Decoder! */
+        IA_ERRORCODE err_code = configXAACDecoder(inBuffer, inBufferLength);
+        if (IA_NO_ERROR != err_code) {
+            ALOGE("configXAACDecoder err_code = %d", err_code);
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+        work->worklets.front()->output.flags = work->input.flags;
+        work->worklets.front()->output.ordinal = work->input.ordinal;
+        work->worklets.front()->output.buffers.clear();
+        return;
+    }
+
+    mCurFrameIndex = work->input.ordinal.frameIndex.peeku();
+    mCurTimestamp = work->input.ordinal.timestamp.peeku();
+    mOutputDrainBufferWritePos = 0;
+    char* tempOutputDrainBuffer = mOutputDrainBuffer;
+    while (size > 0u) {
+        if ((kOutputDrainBufferSize * sizeof(int16_t) -
+             mOutputDrainBufferWritePos) <
+            (mOutputFrameLength * sizeof(int16_t) * mNumChannels)) {
+            ALOGV("skipping decode: not enough space left in DrainBuffer");
+            break;
+        }
+
+        ALOGV("inAttribute size = %zu", size);
+        if (mIntf->isAdts()) {
+            ALOGV("ADTS");
+            size_t adtsHeaderSize = 0;
+            // skip 30 bits, aac_frame_length follows.
+            // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
+
+            const uint8_t* adtsHeader = view.data() + offset;
+            bool signalError = false;
+            if (size < 7) {
+                ALOGE("Audio data too short to contain even the ADTS header. "
+                      "Got %zu bytes.", size);
+                hexdump(adtsHeader, size);
+                signalError = true;
+            } else {
+                bool protectionAbsent = (adtsHeader[1] & 1);
+                unsigned aac_frame_length = ((adtsHeader[3] & 3) << 11) |
+                                            (adtsHeader[4] << 3) |
+                                            (adtsHeader[5] >> 5);
+
+                if (size < aac_frame_length) {
+                    ALOGE("Not enough audio data for the complete frame. "
+                          "Got %zu bytes, frame size according to the ADTS "
+                          "header is %u bytes.", size, aac_frame_length);
+                    hexdump(adtsHeader, size);
+                    signalError = true;
+                } else {
+                    adtsHeaderSize = (protectionAbsent ? 7 : 9);
+                    if (aac_frame_length < adtsHeaderSize) {
+                        signalError = true;
+                    } else {
+                        // const_cast because of libAACdec method signature.
+                        inBuffer =
+                            const_cast<uint8_t*>(adtsHeader + adtsHeaderSize);
+                        inBufferLength = aac_frame_length - adtsHeaderSize;
+
+                        offset += adtsHeaderSize;
+                        size -= adtsHeaderSize;
+                    }
+                }
+            }
+
+            if (signalError) {
+                mSignalledError = true;
+                work->result = C2_CORRUPTED;
+                return;
+            }
+        } else {
+            ALOGV("Non ADTS");
+            // const_cast because of libAACdec method signature.
+            inBuffer = const_cast<uint8_t*>(view.data() + offset);
+            inBufferLength = size;
+        }
+
+        signed int prevSampleRate = mSampFreq;
+        signed int prevNumChannels = mNumChannels;
+
+        /* XAAC decoder expects first frame to be fed via configXAACDecoder API
+         * which should initialize the codec. Once this state is reached, call the
+         * decodeXAACStream API with same frame to decode! */
+        if (!mIsCodecInitialized) {
+            IA_ERRORCODE err_code = configXAACDecoder(inBuffer, inBufferLength);
+            if (IA_NO_ERROR != err_code) {
+                ALOGE("configXAACDecoder Failed 2 err_code = %d", err_code);
+                mSignalledError = true;
+                work->result = C2_CORRUPTED;
+                return;
+            }
+
+            if ((mSampFreq != prevSampleRate) ||
+                (mNumChannels != prevNumChannels)) {
+                ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
+                      prevSampleRate, mSampFreq, prevNumChannels, mNumChannels);
+
+                C2StreamSampleRateInfo::output sampleRateInfo(0u, mSampFreq);
+                C2StreamChannelCountInfo::output channelCountInfo(0u, mNumChannels);
+                std::vector<std::unique_ptr<C2SettingResult>> failures;
+                c2_status_t err = mIntf->config(
+                        { &sampleRateInfo, &channelCountInfo },
+                        C2_MAY_BLOCK,
+                        &failures);
+                if (err == OK) {
+                    work->worklets.front()->output.configUpdate.push_back(
+                        C2Param::Copy(sampleRateInfo));
+                    work->worklets.front()->output.configUpdate.push_back(
+                        C2Param::Copy(channelCountInfo));
+                } else {
+                    ALOGE("Config Update failed");
+                    mSignalledError = true;
+                    work->result = C2_CORRUPTED;
+                    return;
+                }
+            }
+        }
+
+        signed int bytesConsumed = 0;
+        IA_ERRORCODE errorCode = IA_NO_ERROR;
+        if (mIsCodecInitialized) {
+            mIsCodecConfigFlushRequired = true;
+            errorCode = decodeXAACStream(inBuffer, inBufferLength,
+                                         &bytesConsumed, &mNumOutBytes);
+        } else if (!mIsCodecConfigFlushRequired) {
+            ALOGW("Assumption that first frame after header initializes decoder Failed!");
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+        size -= bytesConsumed;
+        offset += bytesConsumed;
+
+        if (inBufferLength != (uint32_t)bytesConsumed)
+            ALOGW("All data not consumed");
+
+        /* In case of error, decoder would have given out empty buffer */
+        if ((IA_NO_ERROR != errorCode) && (0 == mNumOutBytes) && mIsCodecInitialized)
+            mNumOutBytes = mOutputFrameLength * (mPcmWdSz / 8) * mNumChannels;
+
+        if (!bytesConsumed) {
+            ALOGW("bytesConsumed = 0 should never happen");
+        }
+
+        if ((uint32_t)mNumOutBytes >
+            mOutputFrameLength * sizeof(int16_t) * mNumChannels) {
+            ALOGE("mNumOutBytes > mOutputFrameLength * sizeof(int16_t) * mNumChannels, should never happen");
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            return;
+        }
+
+        if (IA_NO_ERROR != errorCode) {
+            // TODO: check for overflow, ASAN
+            memset(mOutputBuffer, 0, mNumOutBytes);
+
+            // Discard input buffer.
+            size = 0;
+
+            // fall through
+        }
+        memcpy(tempOutputDrainBuffer, mOutputBuffer, mNumOutBytes);
+        tempOutputDrainBuffer += mNumOutBytes;
+        mOutputDrainBufferWritePos += mNumOutBytes;
+    }
+
+    if (mOutputDrainBufferWritePos) {
+        finishWork(work, pool);
+    } else {
+        fillEmptyWork(work);
+    }
+    if (eos) mSignalledOutputEos = true;
+}
+
+c2_status_t C2SoftXaacDec::drain(uint32_t drainMode,
+                              const std::shared_ptr<C2BlockPool>& pool) {
+    (void)pool;
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+
+    return C2_OK;
+}
+
+IA_ERRORCODE C2SoftXaacDec::configflushDecode() {
+    IA_ERRORCODE err_code;
+    uint32_t ui_init_done;
+    uint32_t inBufferLength = 8203;
+
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_INIT,
+                                IA_CMD_TYPE_FLUSH_MEM,
+                                nullptr);
+    RETURN_IF_FATAL(err_code,  "IA_CMD_TYPE_FLUSH_MEM");
+
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_SET_INPUT_BYTES,
+                                0,
+                                &inBufferLength);
+    RETURN_IF_FATAL(err_code,  "IA_API_CMD_SET_INPUT_BYTES");
+
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_INIT,
+                                IA_CMD_TYPE_FLUSH_MEM,
+                                nullptr);
+    RETURN_IF_FATAL(err_code,  "IA_CMD_TYPE_FLUSH_MEM");
+
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_INIT,
+                                IA_CMD_TYPE_INIT_DONE_QUERY,
+                                &ui_init_done);
+    RETURN_IF_FATAL(err_code,  "IA_CMD_TYPE_INIT_DONE_QUERY");
+
+    if (ui_init_done) {
+        err_code = getXAACStreamInfo();
+        RETURN_IF_FATAL(err_code, "getXAACStreamInfo");
+        ALOGV("Found Codec with below config---\nsampFreq %d\nnumChannels %d\npcmWdSz %d\nchannelMask %d\noutputFrameLength %d",
+               mSampFreq, mNumChannels, mPcmWdSz, mChannelMask, mOutputFrameLength);
+        mIsCodecInitialized = true;
+    }
+    return IA_NO_ERROR;
+}
+
+c2_status_t C2SoftXaacDec::onFlush_sm() {
+    if (mIsCodecInitialized) {
+        IA_ERRORCODE err_code = configflushDecode();
+        if (err_code != IA_NO_ERROR) {
+            ALOGE("Error in configflushDecode: Error %d", err_code);
+        }
+    }
+    drainDecoder();
+    mSignalledOutputEos = false;
+    mSignalledError = false;
+
+    return C2_OK;
+}
+
+IA_ERRORCODE C2SoftXaacDec::drainDecoder() {
+    /* Output delay compensation logic should sit here. */
+    /* Nothing to be done as XAAC decoder does not introduce output buffer delay */
+
+    return 0;
+}
+
+IA_ERRORCODE C2SoftXaacDec::initXAACDecoder() {
+    /* First part                                        */
+    /* Error Handler Init                                */
+    /* Get Library Name, Library Version and API Version */
+    /* Initialize API structure + Default config set     */
+    /* Set config params from user                       */
+    /* Initialize memory tables                          */
+    /* Get memory information and allocate memory        */
+
+    mInputBufferSize = 0;
+    mInputBuffer = nullptr;
+    mOutputBuffer = nullptr;
+    /* Process struct initing end */
+
+    /* ******************************************************************/
+    /* Initialize API structure and set config params to default        */
+    /* ******************************************************************/
+    /* API size */
+    uint32_t pui_api_size;
+    /* Get the API size */
+    IA_ERRORCODE err_code = ixheaacd_dec_api(nullptr,
+                                             IA_API_CMD_GET_API_SIZE,
+                                             0,
+                                             &pui_api_size);
+    RETURN_IF_FATAL(err_code,  "IA_API_CMD_GET_API_SIZE");
+
+    /* Allocate memory for API */
+    mXheaacCodecHandle = memalign(4, pui_api_size);
+    if (!mXheaacCodecHandle) {
+        ALOGE("malloc for pui_api_size + 4 >> %d Failed", pui_api_size + 4);
+        return IA_FATAL_ERROR;
+    }
+    mMemoryVec.push(mXheaacCodecHandle);
+
+    /* Set the config params to default values */
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_INIT,
+                                IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS,
+                                nullptr);
+    RETURN_IF_FATAL(err_code,  "IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS");
+
+    /* Get the API size */
+    err_code = ia_drc_dec_api(nullptr, IA_API_CMD_GET_API_SIZE, 0, &pui_api_size);
+
+    RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_API_SIZE");
+
+    /* Allocate memory for API */
+    mMpegDDrcHandle = memalign(4, pui_api_size);
+    if (!mMpegDDrcHandle) {
+        ALOGE("malloc for pui_api_size + 4 >> %d Failed", pui_api_size + 4);
+        return IA_FATAL_ERROR;
+    }
+    mMemoryVec.push(mMpegDDrcHandle);
+
+    /* Set the config params to default values */
+    err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
+                              IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS, nullptr);
+
+    RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS");
+
+    /* ******************************************************************/
+    /* Set config parameters                                            */
+    /* ******************************************************************/
+    uint32_t ui_mp4_flag = 1;
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_SET_CONFIG_PARAM,
+                                IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISMP4,
+                                &ui_mp4_flag);
+    RETURN_IF_FATAL(err_code,  "IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISMP4");
+
+    /* ******************************************************************/
+    /* Initialize Memory info tables                                    */
+    /* ******************************************************************/
+    uint32_t ui_proc_mem_tabs_size;
+    pVOID pv_alloc_ptr;
+    /* Get memory info tables size */
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_GET_MEMTABS_SIZE,
+                                0,
+                                &ui_proc_mem_tabs_size);
+    RETURN_IF_FATAL(err_code,  "IA_API_CMD_GET_MEMTABS_SIZE");
+
+    pv_alloc_ptr = memalign(4, ui_proc_mem_tabs_size);
+    if (!pv_alloc_ptr) {
+        ALOGE("Malloc for size (ui_proc_mem_tabs_size + 4) = %d failed!", ui_proc_mem_tabs_size + 4);
+        return IA_FATAL_ERROR;
+    }
+    mMemoryVec.push(pv_alloc_ptr);
+
+    /* Set pointer for process memory tables    */
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_SET_MEMTABS_PTR,
+                                0,
+                                pv_alloc_ptr);
+    RETURN_IF_FATAL(err_code,  "IA_API_CMD_SET_MEMTABS_PTR");
+
+    /* initialize the API, post config, fill memory tables  */
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_INIT,
+                                IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS,
+                                nullptr);
+    RETURN_IF_FATAL(err_code,  "IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS");
+
+    /* ******************************************************************/
+    /* Allocate Memory with info from library                           */
+    /* ******************************************************************/
+    /* There are four different types of memories, that needs to be allocated */
+    /* persistent,scratch,input and output */
+    for (int i = 0; i < 4; i++) {
+        int ui_size = 0, ui_alignment = 0, ui_type = 0;
+
+        /* Get memory size */
+        err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                    IA_API_CMD_GET_MEM_INFO_SIZE,
+                                    i,
+                                    &ui_size);
+        RETURN_IF_FATAL(err_code,  "IA_API_CMD_GET_MEM_INFO_SIZE");
+
+        /* Get memory alignment */
+        err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                    IA_API_CMD_GET_MEM_INFO_ALIGNMENT,
+                                    i,
+                                    &ui_alignment);
+        RETURN_IF_FATAL(err_code,  "IA_API_CMD_GET_MEM_INFO_ALIGNMENT");
+
+        /* Get memory type */
+        err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                    IA_API_CMD_GET_MEM_INFO_TYPE,
+                                    i,
+                                    &ui_type);
+        RETURN_IF_FATAL(err_code,  "IA_API_CMD_GET_MEM_INFO_TYPE");
+
+        pv_alloc_ptr = memalign(ui_alignment, ui_size);
+        if (!pv_alloc_ptr) {
+            ALOGE("Malloc for size (ui_size + ui_alignment) = %d failed!",
+                   ui_size + ui_alignment);
+            return IA_FATAL_ERROR;
+        }
+        mMemoryVec.push(pv_alloc_ptr);
+
+        /* Set the buffer pointer */
+        err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                    IA_API_CMD_SET_MEM_PTR,
+                                    i,
+                                    pv_alloc_ptr);
+        RETURN_IF_FATAL(err_code,  "IA_API_CMD_SET_MEM_PTR");
+        if (ui_type == IA_MEMTYPE_INPUT) {
+            mInputBuffer = (pWORD8)pv_alloc_ptr;
+            mInputBufferSize = ui_size;
+        }
+        if (ui_type == IA_MEMTYPE_OUTPUT)
+            mOutputBuffer = (pWORD8)pv_alloc_ptr;
+    }
+    /* End first part */
+
+    return IA_NO_ERROR;
+}
+
+status_t C2SoftXaacDec::initXAACDrc() {
+    IA_ERRORCODE err_code = IA_NO_ERROR;
+    unsigned int ui_drc_val;
+    //  DRC_PRES_MODE_WRAP_DESIRED_TARGET
+    int32_t targetRefLevel = mIntf->getDrcTargetRefLevel();
+    ALOGV("AAC decoder using desired DRC target reference level of %d", targetRefLevel);
+    ui_drc_val = (unsigned int)targetRefLevel;
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_SET_CONFIG_PARAM,
+                                IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL,
+                                &ui_drc_val);
+    RETURN_IF_FATAL(err_code,  "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL");
+
+    /* Use ui_drc_val from PROP_DRC_OVERRIDE_REF_LEVEL or DRC_DEFAULT_MOBILE_REF_LEVEL
+     * for IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS too */
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
+                                IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS, &ui_drc_val);
+
+    RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS");
+
+    int32_t attenuationFactor = mIntf->getDrcAttenuationFactor();
+    ALOGV("AAC decoder using desired DRC attenuation factor of %d", attenuationFactor);
+    ui_drc_val = (unsigned int)attenuationFactor;
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_SET_CONFIG_PARAM,
+                                IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT,
+                                &ui_drc_val);
+    RETURN_IF_FATAL(err_code,  "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT");
+
+    //  DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR
+    int32_t boostFactor = mIntf->getDrcBoostFactor();
+    ALOGV("AAC decoder using desired DRC boost factor of %d", boostFactor);
+    ui_drc_val = (unsigned int)boostFactor;
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_SET_CONFIG_PARAM,
+                                IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST,
+                                &ui_drc_val);
+    RETURN_IF_FATAL(err_code,  "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST");
+
+    //  DRC_PRES_MODE_WRAP_DESIRED_HEAVY
+    int32_t compressMode = mIntf->getDrcCompressMode();
+    ALOGV("AAC decoder using desried DRC heavy compression switch of %d", compressMode);
+    ui_drc_val = (unsigned int)compressMode;
+
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_SET_CONFIG_PARAM,
+                                IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP,
+                                &ui_drc_val);
+    RETURN_IF_FATAL(err_code,  "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP");
+
+    // AAC_UNIDRC_SET_EFFECT
+    int32_t effectType = mIntf->getDrcEffectType();
+    ALOGV("AAC decoder using MPEG-D DRC effect type %d", effectType);
+    ui_drc_val = (unsigned int)effectType;
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
+                                IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE, &ui_drc_val);
+
+    RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE");
+
+    return IA_NO_ERROR;
+}
+
+IA_ERRORCODE C2SoftXaacDec::deInitXAACDecoder() {
+    ALOGV("deInitXAACDecoder");
+
+    /* Error code */
+    IA_ERRORCODE err_code = IA_NO_ERROR;
+
+    if (mXheaacCodecHandle) {
+        /* Tell that the input is over in this buffer */
+        err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                    IA_API_CMD_INPUT_OVER,
+                                    0,
+                                    nullptr);
+    }
+
+    /* Irrespective of error returned in IA_API_CMD_INPUT_OVER, free allocated memory */
+    for (void* buf : mMemoryVec) {
+        if (buf) free(buf);
+    }
+    mMemoryVec.clear();
+    mXheaacCodecHandle = nullptr;
+
+    return err_code;
+}
+
+IA_ERRORCODE C2SoftXaacDec::deInitMPEGDDDrc() {
+    ALOGV("deInitMPEGDDDrc");
+
+    for (void* buf : mDrcMemoryVec) {
+        if (buf) free(buf);
+    }
+    mDrcMemoryVec.clear();
+    return IA_NO_ERROR;
+}
+
+IA_ERRORCODE C2SoftXaacDec::configXAACDecoder(uint8_t* inBuffer, uint32_t inBufferLength) {
+    if (mInputBufferSize < inBufferLength) {
+        ALOGE("Cannot config AAC, input buffer size %d < inBufferLength %d", mInputBufferSize, inBufferLength);
+        return false;
+    }
+    /* Copy the buffer passed by Android plugin to codec input buffer */
+    memcpy(mInputBuffer, inBuffer, inBufferLength);
+
+    /* Set number of bytes to be processed */
+    IA_ERRORCODE err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                             IA_API_CMD_SET_INPUT_BYTES,
+                                             0,
+                                             &inBufferLength);
+    RETURN_IF_FATAL(err_code,  "IA_API_CMD_SET_INPUT_BYTES");
+
+    if (mIsCodecConfigFlushRequired) {
+        /* If codec is already initialized, then GA header is passed again */
+        /* Need to call the Flush API instead of INIT_PROCESS */
+        mIsCodecInitialized = false; /* Codec needs to be Reinitialized after flush */
+        err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                    IA_API_CMD_INIT,
+                                    IA_CMD_TYPE_GA_HDR,
+                                    nullptr);
+        RETURN_IF_FATAL(err_code,  "IA_CMD_TYPE_GA_HDR");
+    } else {
+        /* Initialize the process */
+        err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                    IA_API_CMD_INIT,
+                                    IA_CMD_TYPE_INIT_PROCESS,
+                                    nullptr);
+        RETURN_IF_FATAL(err_code,  "IA_CMD_TYPE_INIT_PROCESS");
+    }
+
+    uint32_t ui_init_done;
+    /* Checking for end of initialization */
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_INIT,
+                                IA_CMD_TYPE_INIT_DONE_QUERY,
+                                &ui_init_done);
+    RETURN_IF_FATAL(err_code,  "IA_CMD_TYPE_INIT_DONE_QUERY");
+
+    /* How much buffer is used in input buffers */
+    int32_t i_bytes_consumed;
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_GET_CURIDX_INPUT_BUF,
+                                0,
+                                &i_bytes_consumed);
+    RETURN_IF_FATAL(err_code,  "IA_API_CMD_GET_CURIDX_INPUT_BUF");
+
+    if (ui_init_done) {
+        err_code = getXAACStreamInfo();
+        RETURN_IF_FATAL(err_code, "getXAACStreamInfo");
+        ALOGI("Found Codec with below config---\nsampFreq %d\nnumChannels %d\npcmWdSz %d\nchannelMask %d\noutputFrameLength %d",
+               mSampFreq, mNumChannels, mPcmWdSz, mChannelMask, mOutputFrameLength);
+        mIsCodecInitialized = true;
+
+        err_code = configMPEGDDrc();
+        RETURN_IF_FATAL(err_code, "configMPEGDDrc");
+    }
+
+    return IA_NO_ERROR;
+}
+IA_ERRORCODE C2SoftXaacDec::initMPEGDDDrc() {
+    IA_ERRORCODE err_code = IA_NO_ERROR;
+
+    for (int i = 0; i < (WORD32)2; i++) {
+        WORD32 ui_size, ui_alignment, ui_type;
+        pVOID pv_alloc_ptr;
+
+        /* Get memory size */
+        err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_SIZE, i, &ui_size);
+
+        RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_SIZE");
+
+        /* Get memory alignment */
+        err_code =
+            ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_ALIGNMENT, i, &ui_alignment);
+
+        RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_ALIGNMENT");
+
+        /* Get memory type */
+        err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_TYPE, i, &ui_type);
+        RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_TYPE");
+
+        pv_alloc_ptr = memalign(4, ui_size);
+        if (pv_alloc_ptr == nullptr) {
+            ALOGE(" Cannot create requested memory  %d", ui_size);
+            return IA_FATAL_ERROR;
+        }
+        mDrcMemoryVec.push(pv_alloc_ptr);
+
+        /* Set the buffer pointer */
+        err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, i, pv_alloc_ptr);
+
+        RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
+    }
+
+    WORD32 ui_size;
+    ui_size = 8192 * 2;
+
+    mDrcInBuf = (int8_t*)memalign(4, ui_size);
+    if (mDrcInBuf == nullptr) {
+        ALOGE(" Cannot create requested memory  %d", ui_size);
+        return IA_FATAL_ERROR;
+    }
+    mDrcMemoryVec.push(mDrcInBuf);
+
+    err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, 2, mDrcInBuf);
+    RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
+
+    mDrcOutBuf = (int8_t*)memalign(4, ui_size);
+    if (mDrcOutBuf == nullptr) {
+        ALOGE(" Cannot create requested memory  %d", ui_size);
+        return IA_FATAL_ERROR;
+    }
+    mDrcMemoryVec.push(mDrcOutBuf);
+
+    err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, 3, mDrcOutBuf);
+    RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
+
+    return IA_NO_ERROR;
+}
+int C2SoftXaacDec::configMPEGDDrc() {
+    IA_ERRORCODE err_code = IA_NO_ERROR;
+    int i_effect_type;
+    int i_loud_norm;
+    int i_target_loudness;
+    unsigned int i_sbr_mode;
+    uint32_t ui_proc_mem_tabs_size = 0;
+    pVOID pv_alloc_ptr = NULL;
+
+    /* Sampling Frequency */
+    err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
+                              IA_DRC_DEC_CONFIG_PARAM_SAMP_FREQ, &mSampFreq);
+    RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_SAMP_FREQ");
+    /* Total Number of Channels */
+    err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
+                              IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS, &mNumChannels);
+    RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS");
+
+    /* PCM word size  */
+    err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
+                              IA_DRC_DEC_CONFIG_PARAM_PCM_WDSZ, &mPcmWdSz);
+    RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_PCM_WDSZ");
+
+    /*Set Effect Type*/
+
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
+                                IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE, &i_effect_type);
+    RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE");
+
+    err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
+                              IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE, &i_effect_type);
+    RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE");
+
+    /*Set target loudness */
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
+                                IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS,
+                                &i_target_loudness);
+    RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS");
+
+    err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
+                              IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS, &i_target_loudness);
+    RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS");
+
+    /*Set loud_norm_flag*/
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
+                                IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM, &i_loud_norm);
+    RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM");
+
+    err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
+                              IA_DRC_DEC_CONFIG_DRC_LOUD_NORM, &i_loud_norm);
+    RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_LOUD_NORM");
+
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
+                                IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE, &i_sbr_mode);
+    RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE");
+
+    /* Get memory info tables size */
+    err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEMTABS_SIZE, 0,
+                              &ui_proc_mem_tabs_size);
+    RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEMTABS_SIZE");
+
+    pv_alloc_ptr = memalign(4, ui_proc_mem_tabs_size);
+    if (pv_alloc_ptr == NULL) {
+        ALOGE(" Cannot create requested memory  %d", ui_proc_mem_tabs_size);
+        return IA_FATAL_ERROR;
+    }
+    memset(pv_alloc_ptr, 0, ui_proc_mem_tabs_size);
+    mMemoryVec.push(pv_alloc_ptr);
+
+    /* Set pointer for process memory tables */
+    err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEMTABS_PTR, 0,
+                              pv_alloc_ptr);
+    RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEMTABS_PTR");
+
+    err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
+                              IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS, nullptr);
+
+    RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS");
+
+    /* Free any memory that is allocated for MPEG D Drc so far */
+    deInitMPEGDDDrc();
+
+    err_code = initMPEGDDDrc();
+    if (err_code != IA_NO_ERROR) {
+        ALOGE("initMPEGDDDrc failed with error %d", err_code);
+        deInitMPEGDDDrc();
+        return err_code;
+    }
+
+    /* DRC buffers
+        buf[0] - contains extension element pay load loudness related
+        buf[1] - contains extension element pay load*/
+    {
+        VOID* p_array[2][16];
+        WORD32 ii;
+        WORD32 buf_sizes[2][16];
+        WORD32 num_elements;
+        WORD32 num_config_ext;
+        WORD32 bit_str_fmt = 1;
+
+        WORD32 uo_num_chan;
+
+        memset(buf_sizes, 0, 32 * sizeof(WORD32));
+
+        err_code =
+            ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
+                             IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_BUF_SIZES, &buf_sizes[0][0]);
+        RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_BUF_SIZES");
+
+        err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
+                                    IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_PTR, &p_array);
+        RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_PTR");
+
+        err_code =
+            ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT, IA_CMD_TYPE_INIT_SET_BUFF_PTR, nullptr);
+        RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_SET_BUFF_PTR");
+
+        err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
+                                    IA_ENHAACPLUS_DEC_CONFIG_NUM_ELE, &num_elements);
+        RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_NUM_ELE");
+
+        err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
+                                    IA_ENHAACPLUS_DEC_CONFIG_NUM_CONFIG_EXT, &num_config_ext);
+        RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_NUM_CONFIG_EXT");
+
+        for (ii = 0; ii < num_config_ext; ii++) {
+            /*copy loudness bitstream*/
+            if (buf_sizes[0][ii] > 0) {
+                memcpy(mDrcInBuf, p_array[0][ii], buf_sizes[0][ii]);
+
+                /*Set bitstream_split_format */
+                err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
+                                          IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt);
+                RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
+
+                /* Set number of bytes to be processed */
+                err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_IL_BS, 0,
+                                          &buf_sizes[0][ii]);
+                RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES_IL_BS");
+
+                /* Execute process */
+                err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
+                                          IA_CMD_TYPE_INIT_CPY_IL_BSF_BUFF, nullptr);
+                RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_CPY_IL_BSF_BUFF");
+
+                mDRCFlag = 1;
+            }
+        }
+
+        for (ii = 0; ii < num_elements; ii++) {
+            /*copy config bitstream*/
+            if (buf_sizes[1][ii] > 0) {
+                memcpy(mDrcInBuf, p_array[1][ii], buf_sizes[1][ii]);
+                /* Set number of bytes to be processed */
+
+                /*Set bitstream_split_format */
+                err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
+                                          IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt);
+                RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
+
+                err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_IC_BS, 0,
+                                          &buf_sizes[1][ii]);
+                RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES_IC_BS");
+
+                /* Execute process */
+                err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
+                                          IA_CMD_TYPE_INIT_CPY_IC_BSF_BUFF, nullptr);
+
+                RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_CPY_IC_BSF_BUFF");
+
+                mDRCFlag = 1;
+            }
+        }
+
+        if (mDRCFlag == 1) {
+            mMpegDDRCPresent = 1;
+        } else {
+            mMpegDDRCPresent = 0;
+        }
+
+        /*Read interface buffer config file bitstream*/
+        if (mMpegDDRCPresent == 1) {
+            WORD32 interface_is_present = 1;
+
+            if (i_sbr_mode != 0) {
+                if (i_sbr_mode == 1) {
+                    mOutputFrameLength = 2048;
+                } else if (i_sbr_mode == 3) {
+                    mOutputFrameLength = 4096;
+                } else {
+                    mOutputFrameLength = 1024;
+                }
+            } else {
+                mOutputFrameLength = 4096;
+            }
+
+            err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
+                                      IA_DRC_DEC_CONFIG_PARAM_FRAME_SIZE, (WORD32 *)&mOutputFrameLength);
+            RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_FRAME_SIZE");
+
+            err_code =
+                ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
+                               IA_DRC_DEC_CONFIG_PARAM_INT_PRESENT, &interface_is_present);
+            RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_INT_PRESENT");
+
+            /* Execute process */
+            err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
+                                      IA_CMD_TYPE_INIT_CPY_IN_BSF_BUFF, nullptr);
+            RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_CPY_IN_BSF_BUFF");
+
+            err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
+                                      IA_CMD_TYPE_INIT_PROCESS, nullptr);
+            RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_PROCESS");
+
+            err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_CONFIG_PARAM,
+                                      IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS, &uo_num_chan);
+            RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS");
+        }
+    }
+
+    return err_code;
+}
+
+IA_ERRORCODE C2SoftXaacDec::decodeXAACStream(uint8_t* inBuffer,
+                                 uint32_t inBufferLength,
+                                 int32_t* bytesConsumed,
+                                 int32_t* outBytes) {
+    if (mInputBufferSize < inBufferLength) {
+        ALOGE("Cannot config AAC, input buffer size %d < inBufferLength %d", mInputBufferSize, inBufferLength);
+        return -1;
+    }
+    /* Copy the buffer passed by Android plugin to codec input buffer */
+    memcpy(mInputBuffer, inBuffer, inBufferLength);
+
+    /* Set number of bytes to be processed */
+    IA_ERRORCODE err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                             IA_API_CMD_SET_INPUT_BYTES,
+                                             0,
+                                             &inBufferLength);
+    RETURN_IF_FATAL(err_code,  "IA_API_CMD_SET_INPUT_BYTES");
+
+    /* Execute process */
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_EXECUTE,
+                                IA_CMD_TYPE_DO_EXECUTE,
+                                nullptr);
+    RETURN_IF_FATAL(err_code,  "IA_CMD_TYPE_DO_EXECUTE");
+
+    /* Checking for end of processing */
+    uint32_t ui_exec_done;
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_EXECUTE,
+                                IA_CMD_TYPE_DONE_QUERY,
+                                &ui_exec_done);
+    RETURN_IF_FATAL(err_code,  "IA_CMD_TYPE_DONE_QUERY");
+
+    if (ui_exec_done != 1) {
+        VOID* p_array;        // ITTIAM:buffer to handle gain payload
+        WORD32 buf_size = 0;  // ITTIAM:gain payload length
+        WORD32 bit_str_fmt = 1;
+        WORD32 gain_stream_flag = 1;
+
+        err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
+                                    IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_LEN, &buf_size);
+        RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_LEN");
+
+        err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
+                                    IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_BUF, &p_array);
+        RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_BUF");
+
+        if (buf_size > 0) {
+            /*Set bitstream_split_format */
+            err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
+                                      IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt);
+            RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
+
+            memcpy(mDrcInBuf, p_array, buf_size);
+            /* Set number of bytes to be processed */
+            err_code =
+                ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_BS, 0, &buf_size);
+            RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
+
+            err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
+                                      IA_DRC_DEC_CONFIG_GAIN_STREAM_FLAG, &gain_stream_flag);
+            RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
+
+            /* Execute process */
+            err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
+                                      IA_CMD_TYPE_INIT_CPY_BSF_BUFF, nullptr);
+            RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
+
+            mMpegDDRCPresent = 1;
+        }
+    }
+
+    /* How much buffer is used in input buffers */
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_GET_CURIDX_INPUT_BUF,
+                                0,
+                                bytesConsumed);
+    RETURN_IF_FATAL(err_code,  "IA_API_CMD_GET_CURIDX_INPUT_BUF");
+
+    /* Get the output bytes */
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_GET_OUTPUT_BYTES,
+                                0,
+                                outBytes);
+    RETURN_IF_FATAL(err_code,  "IA_API_CMD_GET_OUTPUT_BYTES");
+
+    if (mMpegDDRCPresent == 1) {
+        memcpy(mDrcInBuf, mOutputBuffer, *outBytes);
+        err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES, 0, outBytes);
+        RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES");
+
+        err_code =
+            ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_EXECUTE, IA_CMD_TYPE_DO_EXECUTE, nullptr);
+        RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_DO_EXECUTE");
+
+        memcpy(mOutputBuffer, mDrcOutBuf, *outBytes);
+    }
+    return IA_NO_ERROR;
+}
+
+IA_ERRORCODE C2SoftXaacDec::getXAACStreamInfo() {
+    IA_ERRORCODE err_code = IA_NO_ERROR;
+
+    /* Sampling frequency */
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_GET_CONFIG_PARAM,
+                                IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ,
+                                &mSampFreq);
+    RETURN_IF_FATAL(err_code,  "IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ");
+
+    /* Total Number of Channels */
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_GET_CONFIG_PARAM,
+                                IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS,
+                                &mNumChannels);
+    RETURN_IF_FATAL(err_code,  "IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS");
+    if (mNumChannels > MAX_CHANNEL_COUNT) {
+        ALOGE(" No of channels are more than max channels\n");
+        return IA_FATAL_ERROR;
+    }
+
+    /* PCM word size */
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_GET_CONFIG_PARAM,
+                                IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ,
+                                &mPcmWdSz);
+    RETURN_IF_FATAL(err_code,  "IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ");
+    if ((mPcmWdSz / 8) != 2) {
+        ALOGE(" No of channels are more than max channels\n");
+        return IA_FATAL_ERROR;
+    }
+
+    /* channel mask to tell the arrangement of channels in bit stream */
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_GET_CONFIG_PARAM,
+                                IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MASK,
+                                &mChannelMask);
+    RETURN_IF_FATAL(err_code,  "IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MASK");
+
+    /* Channel mode to tell MONO/STEREO/DUAL-MONO/NONE_OF_THESE */
+    uint32_t ui_channel_mode;
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_GET_CONFIG_PARAM,
+                                IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MODE,
+                                &ui_channel_mode);
+    RETURN_IF_FATAL(err_code,  "IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MODE");
+    if (ui_channel_mode == 0)
+        ALOGV("Channel Mode: MONO_OR_PS\n");
+    else if (ui_channel_mode == 1)
+        ALOGV("Channel Mode: STEREO\n");
+    else if (ui_channel_mode == 2)
+        ALOGV("Channel Mode: DUAL-MONO\n");
+    else
+        ALOGV("Channel Mode: NONE_OF_THESE or MULTICHANNEL\n");
+
+    /* Channel mode to tell SBR PRESENT/NOT_PRESENT */
+    uint32_t ui_sbr_mode;
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+                                IA_API_CMD_GET_CONFIG_PARAM,
+                                IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE,
+                                &ui_sbr_mode);
+    RETURN_IF_FATAL(err_code,  "IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE");
+    if (ui_sbr_mode == 0)
+        ALOGV("SBR Mode: NOT_PRESENT\n");
+    else if (ui_sbr_mode == 1)
+        ALOGV("SBR Mode: PRESENT\n");
+    else
+        ALOGV("SBR Mode: ILLEGAL\n");
+
+    /* mOutputFrameLength = 1024 * (1 + SBR_MODE) for AAC */
+    /* For USAC it could be 1024 * 3 , support to query  */
+    /* not yet added in codec                            */
+    mOutputFrameLength = 1024 * (1 + ui_sbr_mode);
+    ALOGI("mOutputFrameLength %d ui_sbr_mode %d", mOutputFrameLength, ui_sbr_mode);
+
+    return IA_NO_ERROR;
+}
+
+IA_ERRORCODE C2SoftXaacDec::setXAACDRCInfo(int32_t drcCut, int32_t drcBoost,
+                                           int32_t drcRefLevel,
+                                           int32_t drcHeavyCompression,
+                                           int32_t drEffectType) {
+    IA_ERRORCODE err_code = IA_NO_ERROR;
+
+    int32_t ui_drc_enable = 1;
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
+                                IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_ENABLE,
+                                &ui_drc_enable);
+    RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_ENABLE");
+    if (drcCut != -1) {
+        err_code =
+            ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
+                             IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT, &drcCut);
+        RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT");
+    }
+
+    if (drcBoost != -1) {
+        err_code = ixheaacd_dec_api(
+            mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
+            IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST, &drcBoost);
+        RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST");
+    }
+
+    if (drcRefLevel != -1) {
+        err_code = ixheaacd_dec_api(
+            mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
+            IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL, &drcRefLevel);
+        RETURN_IF_FATAL(err_code,
+                        "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL");
+    }
+
+    if (drcRefLevel != -1) {
+        err_code = ixheaacd_dec_api(
+            mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
+            IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS, &drcRefLevel);
+        RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS");
+    }
+
+    if (drcHeavyCompression != -1) {
+        err_code =
+            ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
+                             IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP,
+                             &drcHeavyCompression);
+        RETURN_IF_FATAL(err_code,
+                        "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP");
+    }
+
+    err_code =
+        ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
+                         IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE, &drEffectType);
+    RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE");
+
+    int32_t i_effect_type, i_target_loudness, i_loud_norm;
+    /*Set Effect Type*/
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
+                                IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE,
+                                &i_effect_type);
+    RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE");
+
+    err_code =
+        ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
+                       IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE, &i_effect_type);
+
+    RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE");
+
+    /*Set target loudness */
+    err_code = ixheaacd_dec_api(
+        mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
+        IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS, &i_target_loudness);
+    RETURN_IF_FATAL(err_code,
+                    "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS");
+
+    err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
+                              IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS,
+                              &i_target_loudness);
+    RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS");
+
+    /*Set loud_norm_flag*/
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
+                                IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM,
+                                &i_loud_norm);
+    RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM");
+
+    err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
+                              IA_DRC_DEC_CONFIG_DRC_LOUD_NORM, &i_loud_norm);
+
+    RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_LOUD_NORM");
+
+    return IA_NO_ERROR;
+}
+
+class C2SoftXaacDecFactory : public C2ComponentFactory {
+public:
+    C2SoftXaacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+            GetCodec2PlatformComponentStore()->getParamReflector())) {
+    }
+
+    virtual c2_status_t createComponent(
+            c2_node_id_t id,
+            std::shared_ptr<C2Component>* const component,
+            std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+                new C2SoftXaacDec(COMPONENT_NAME,
+                               id,
+                               std::make_shared<C2SoftXaacDec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+            c2_node_id_t id,
+            std::shared_ptr<C2ComponentInterface>* const interface,
+            std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+                new SimpleInterface<C2SoftXaacDec::IntfImpl>(
+                        COMPONENT_NAME, id, std::make_shared<C2SoftXaacDec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftXaacDecFactory() override = default;
+
+private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftXaacDecFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/xaac/C2SoftXaacDec.h b/media/codec2/components/xaac/C2SoftXaacDec.h
new file mode 100644
index 0000000..5c8567f
--- /dev/null
+++ b/media/codec2/components/xaac/C2SoftXaacDec.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_XAAC_DEC_H_
+#define ANDROID_C2_SOFT_XAAC_DEC_H_
+#include <utils/Vector.h>
+#include <SimpleC2Component.h>
+
+#include "ixheaacd_type_def.h"
+#include "ixheaacd_error_standards.h"
+#include "ixheaacd_error_handler.h"
+#include "ixheaacd_apicmd_standards.h"
+#include "ixheaacd_memory_standards.h"
+#include "ixheaacd_aac_config.h"
+
+#include "impd_apicmd_standards.h"
+#include "impd_drc_config_params.h"
+
+#define MAX_CHANNEL_COUNT           8  /* maximum number of audio channels that can be decoded */
+#define MAX_NUM_BLOCKS              8  /* maximum number of audio blocks that can be decoded */
+
+extern "C" IA_ERRORCODE ixheaacd_dec_api(pVOID p_ia_module_obj,
+                        WORD32 i_cmd, WORD32 i_idx, pVOID pv_value);
+extern "C" IA_ERRORCODE ia_drc_dec_api(pVOID p_ia_module_obj,
+                        WORD32 i_cmd, WORD32 i_idx, pVOID pv_value);
+extern "C"  IA_ERRORCODE ixheaacd_get_config_param(pVOID p_ia_process_api_obj,
+                                       pWORD32 pi_samp_freq,
+                                       pWORD32 pi_num_chan,
+                                       pWORD32 pi_pcm_wd_sz,
+                                       pWORD32 pi_channel_mask);
+
+namespace android {
+
+struct C2SoftXaacDec : public SimpleC2Component {
+    class IntfImpl;
+
+    C2SoftXaacDec(const char* name, c2_node_id_t id,
+               const std::shared_ptr<IntfImpl>& intfImpl);
+    virtual ~C2SoftXaacDec();
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(
+            const std::unique_ptr<C2Work> &work,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+    c2_status_t drain(
+            uint32_t drainMode,
+            const std::shared_ptr<C2BlockPool> &pool) override;
+
+private:
+    enum {
+        kOutputDrainBufferSize      = 2048 * MAX_CHANNEL_COUNT * MAX_NUM_BLOCKS,
+    };
+
+    std::shared_ptr<IntfImpl> mIntf;
+    void* mXheaacCodecHandle;
+    void* mMpegDDrcHandle;
+    uint32_t mInputBufferSize;
+    uint32_t mOutputFrameLength;
+    int8_t* mInputBuffer;
+    int8_t* mOutputBuffer;
+    int32_t mSampFreq;
+    int32_t mNumChannels;
+    int32_t mPcmWdSz;
+    int32_t mChannelMask;
+    int32_t mNumOutBytes;
+    uint64_t mCurFrameIndex;
+    uint64_t mCurTimestamp;
+    bool mIsCodecInitialized;
+    bool mIsCodecConfigFlushRequired;
+    int8_t* mDrcInBuf;
+    int8_t* mDrcOutBuf;
+    int32_t mMpegDDRCPresent;
+    int32_t mDRCFlag;
+
+    Vector<void*> mMemoryVec;
+    Vector<void*> mDrcMemoryVec;
+
+    size_t mInputBufferCount __unused;
+    size_t mOutputBufferCount __unused;
+    bool mSignalledOutputEos;
+    bool mSignalledError;
+    char* mOutputDrainBuffer;
+    uint32_t mOutputDrainBufferWritePos;
+
+    IA_ERRORCODE initDecoder();
+    IA_ERRORCODE setDrcParameter();
+    IA_ERRORCODE configflushDecode();
+    IA_ERRORCODE drainDecoder();
+    void finishWork(const std::unique_ptr<C2Work>& work,
+                    const std::shared_ptr<C2BlockPool>& pool);
+
+    IA_ERRORCODE initXAACDrc();
+    IA_ERRORCODE initXAACDecoder();
+    IA_ERRORCODE deInitXAACDecoder();
+    IA_ERRORCODE initMPEGDDDrc();
+    IA_ERRORCODE deInitMPEGDDDrc();
+    IA_ERRORCODE configXAACDecoder(uint8_t* inBuffer, uint32_t inBufferLength);
+    int configMPEGDDrc();
+    IA_ERRORCODE decodeXAACStream(uint8_t* inBuffer,
+                         uint32_t inBufferLength,
+                         int32_t* bytesConsumed,
+                         int32_t* outBytes);
+    IA_ERRORCODE getXAACStreamInfo();
+    IA_ERRORCODE setXAACDRCInfo(int32_t drcCut, int32_t drcBoost,
+                                int32_t drcRefLevel, int32_t drcHeavyCompression,
+                                int32_t drEffectType);
+
+    C2_DO_NOT_COPY(C2SoftXaacDec);
+};
+
+}  // namespace android
+
+#endif  // C2_SOFT_XAAC_H_
diff --git a/media/codec2/core/Android.bp b/media/codec2/core/Android.bp
new file mode 100644
index 0000000..a7e8997
--- /dev/null
+++ b/media/codec2/core/Android.bp
@@ -0,0 +1,48 @@
+cc_library_headers {
+    name: "libcodec2_headers",
+    vendor_available: true,
+    export_include_dirs: ["include"],
+}
+
+cc_library_shared {
+    name: "libcodec2",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
+
+    srcs: ["C2.cpp"],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+
+    header_libs: [
+        "libcodec2_headers",
+        "libhardware_headers",
+        "libutils_headers",
+        "media_plugin_headers",
+    ],
+
+    export_header_lib_headers: [
+        "libcodec2_headers",
+        "libhardware_headers",
+        "libutils_headers",
+        "media_plugin_headers",
+    ],
+
+    sanitize: {
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+        cfi: false, // true,
+        diag: {
+            cfi: false, // true,
+        },
+    },
+
+    ldflags: ["-Wl,-Bsymbolic"],
+}
+
diff --git a/media/codec2/core/C2.cpp b/media/codec2/core/C2.cpp
new file mode 100644
index 0000000..359d4e5
--- /dev/null
+++ b/media/codec2/core/C2.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <C2.h>
+#include <C2Buffer.h>
+#include <C2Component.h>
+#include <C2Config.h>
+#include <C2Param.h>
+#include <C2ParamDef.h>
+#include <C2Work.h>
+
+/**
+ * There is nothing here yet. This library is built to see what symbols and methods get
+ * defined as part of the API include files.
+ *
+ * Going forward, the Codec2 library will contain utility methods that are useful for
+ * Codec2 clients.
+ */
+
+
diff --git a/media/codec2/core/include/C2.h b/media/codec2/core/include/C2.h
new file mode 100644
index 0000000..ef3466d
--- /dev/null
+++ b/media/codec2/core/include/C2.h
@@ -0,0 +1,552 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef C2_H_
+#define C2_H_
+
+#include <errno.h>
+
+#include <string>
+
+/** nanoseconds with arbitrary origin. */
+typedef int64_t c2_nsecs_t;
+
+/** \mainpage Codec2
+ *
+ * Codec2 is a generic frame-based data processing API.
+ *
+ * The media subsystem accesses components via the \ref API.
+ */
+
+/** \ingroup API
+ *
+ * The Codec2 API defines the operation of data processing components and their interaction with
+ * the rest of the system.
+ *
+ * Coding Conventions
+ *
+ * Mitigating Binary Compatibility.
+ *
+ * While full binary compatibility is not a goal of the API (due to our use of STL), we try to
+ * mitigate binary breaks by adhering to the following conventions:
+ *
+ * - at most one vtable with placeholder virtual methods
+ * - all optional/placeholder virtual methods returning a c2_status_t, with C2_OMITTED not requiring
+ *   any update to input/output arguments.
+ * - limiting symbol export of inline methods
+ * - use of pimpl (or shared-pimpl)
+ *
+ * Naming
+ *
+ * - all classes and types prefix with C2
+ * - classes for internal use prefix with _C2
+ * - enum values in global namespace prefix with C2_ all caps
+ * - enum values inside classes have no C2_ prefix as class already has it
+ * - supporting two kinds of enum naming: all-caps and kCamelCase
+ * \todo revisit kCamelCase for param-type
+ *
+ * Aspects
+ *
+ * Aspects define certain common behavior across a group of objects.
+ * - classes whose name matches _C2.*Aspect
+ * - only protected constructors
+ * - no desctructor and copiable
+ * - all methods are inline or static (this is opposite of the interface paradigm where all methods
+ *   are virtual, which would not work due to the at most one vtable rule.)
+ * - only private variables (this prevents subclasses interfering with the aspects.)
+ */
+
+/// \defgroup types Common Types
+/// @{
+
+/**
+ * C2String: basic string implementation
+ */
+typedef std::string C2String;
+
+/**
+ * C2StringLiteral: basic string literal implementation.
+ * \note these are never owned by any object, and can only refer to C string literals.
+ */
+typedef const char *C2StringLiteral;
+
+/**
+ * c2_status_t: status codes used.
+ */
+enum c2_status_t : int32_t {
+/*
+ * Use POSIX errno constants.
+ */
+    C2_OK        = 0,            ///< operation completed successfully
+
+    // bad input
+    C2_BAD_VALUE = EINVAL,       ///< argument has invalid value (user error)
+    C2_BAD_INDEX = ENXIO,        ///< argument uses invalid index (user error)
+    C2_CANNOT_DO = ENOTSUP,      ///< argument/index is valid but not possible
+
+    // bad sequencing of events
+    C2_DUPLICATE = EEXIST,       ///< object already exists
+    C2_NOT_FOUND = ENOENT,       ///< object not found
+    C2_BAD_STATE = EPERM,        ///< operation is not permitted in the current state
+    C2_BLOCKING  = EWOULDBLOCK,  ///< operation would block but blocking is not permitted
+    C2_CANCELED  = EINTR,        ///< operation interrupted/canceled
+
+    // bad environment
+    C2_NO_MEMORY = ENOMEM,       ///< not enough memory to complete operation
+    C2_REFUSED   = EACCES,       ///< missing permission to complete operation
+
+    C2_TIMED_OUT = ETIMEDOUT,    ///< operation did not complete within timeout
+
+    // bad versioning
+    C2_OMITTED   = ENOSYS,       ///< operation is not implemented/supported (optional only)
+
+    // unknown fatal
+    C2_CORRUPTED = EFAULT,       ///< some unexpected error prevented the operation
+    C2_NO_INIT   = ENODEV,       ///< status has not been initialized
+};
+
+/**
+ * Type that describes the desired blocking behavior for variable blocking calls. Blocking in this
+ * API is used in a somewhat modified meaning such that operations that merely update variables
+ * protected by mutexes are still considered "non-blocking" (always used in quotes).
+ */
+enum c2_blocking_t : int32_t {
+    /**
+     * The operation SHALL be "non-blocking". This means that it shall not perform any file
+     * operations, or call/wait on other processes. It may use a protected region as long as the
+     * mutex is never used to protect code that is otherwise "may block".
+     */
+    C2_DONT_BLOCK = false,
+    /**
+     * The operation MAY be temporarily blocking.
+     */
+    C2_MAY_BLOCK = true,
+};
+
+/// @}
+
+/// \defgroup utils Utilities
+/// @{
+
+#define C2_DO_NOT_COPY(type) \
+    type& operator=(const type &) = delete; \
+    type(const type &) = delete; \
+
+#define C2_DEFAULT_MOVE(type) \
+    type& operator=(type &&) = default; \
+    type(type &&) = default; \
+
+#define C2_ALLOW_OVERFLOW __attribute__((no_sanitize("integer")))
+#define C2_CONST    __attribute__((const))
+#define C2_HIDE     __attribute__((visibility("hidden")))
+#define C2_INLINE   inline C2_HIDE
+#define C2_INTERNAL __attribute__((internal_linkage))
+#define C2_PACK     __attribute__((aligned(4)))
+#define C2_PURE     __attribute__((pure))
+
+#define DEFINE_OTHER_COMPARISON_OPERATORS(type) \
+    inline bool operator!=(const type &other) const { return !(*this == other); } \
+    inline bool operator<=(const type &other) const { return (*this == other) || (*this < other); } \
+    inline bool operator>=(const type &other) const { return !(*this < other); } \
+    inline bool operator>(const type &other) const { return !(*this < other) && !(*this == other); }
+
+#define DEFINE_FIELD_BASED_COMPARISON_OPERATORS(type, field) \
+    inline bool operator<(const type &other) const { return field < other.field; } \
+    inline bool operator==(const type &other) const { return field == other.field; } \
+    DEFINE_OTHER_COMPARISON_OPERATORS(type)
+
+#define DEFINE_FIELD_AND_MASK_BASED_COMPARISON_OPERATORS(type, field, mask) \
+    inline bool operator<(const type &other) const { \
+        return (field & mask) < (other.field & (mask)); \
+    } \
+    inline bool operator==(const type &other) const { \
+        return (field & mask) == (other.field & (mask)); \
+    } \
+    DEFINE_OTHER_COMPARISON_OPERATORS(type)
+
+#define DEFINE_ENUM_OPERATORS(etype) \
+    inline constexpr etype operator|(etype a, etype b) { return (etype)(std::underlying_type<etype>::type(a) | std::underlying_type<etype>::type(b)); } \
+    inline constexpr etype &operator|=(etype &a, etype b) { a = (etype)(std::underlying_type<etype>::type(a) | std::underlying_type<etype>::type(b)); return a; } \
+    inline constexpr etype operator&(etype a, etype b) { return (etype)(std::underlying_type<etype>::type(a) & std::underlying_type<etype>::type(b)); } \
+    inline constexpr etype &operator&=(etype &a, etype b) { a = (etype)(std::underlying_type<etype>::type(a) & std::underlying_type<etype>::type(b)); return a; } \
+    inline constexpr etype operator^(etype a, etype b) { return (etype)(std::underlying_type<etype>::type(a) ^ std::underlying_type<etype>::type(b)); } \
+    inline constexpr etype &operator^=(etype &a, etype b) { a = (etype)(std::underlying_type<etype>::type(a) ^ std::underlying_type<etype>::type(b)); return a; } \
+    inline constexpr etype operator~(etype a) { return (etype)(~std::underlying_type<etype>::type(a)); }
+
+template<typename T, typename B>
+class C2_HIDE c2_cntr_t;
+
+/// \cond INTERNAL
+
+/// \defgroup utils_internal
+/// @{
+
+template<typename T>
+struct C2_HIDE _c2_cntr_compat_helper {
+    template<typename U, typename E=typename std::enable_if<std::is_integral<U>::value>::type>
+    C2_ALLOW_OVERFLOW
+    inline static constexpr T get(const U &value) {
+        return T(value);
+    }
+
+    template<typename U, typename E=typename std::enable_if<(sizeof(U) >= sizeof(T))>::type>
+    C2_ALLOW_OVERFLOW
+    inline static constexpr T get(const c2_cntr_t<U, void> &value) {
+        return T(value.mValue);
+    }
+};
+
+/// @}
+
+/// \endcond
+
+/**
+ * Integral counter type.
+ *
+ * This is basically an unsigned integral type that is NEVER checked for overflow/underflow - and
+ * comparison operators are redefined.
+ *
+ * \note Comparison of counter types is not fully transitive, e.g.
+ * it could be that a > b > c but a !> c.
+ * std::less<>, greater<>, less_equal<> and greater_equal<> specializations yield total ordering,
+ * but may not match semantic ordering of the values.
+ *
+ * Technically: counter types represent integer values: A * 2^N + value, where A can be arbitrary.
+ * This makes addition, subtraction, multiplication (as well as bitwise operations) well defined.
+ * However, division is in general not well defined, as the result may depend on A. This is also
+ * true for logical operators and boolean conversion.
+ *
+ * Even though well defined, bitwise operators are not implemented for counter types as they are not
+ * meaningful.
+ */
+template<typename T, typename B=typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value>::type>
+class C2_HIDE c2_cntr_t {
+    using compat = _c2_cntr_compat_helper<T>;
+
+    T mValue;
+    constexpr static T HALF_RANGE = T(~0) ^ (T(~0) >> 1);
+
+    template<typename U>
+    friend struct _c2_cntr_compat_helper;
+public:
+
+    /**
+     * Default constructor. Initialized counter to 0.
+     */
+    inline constexpr c2_cntr_t() : mValue(T(0)) {}
+
+    /**
+     * Construct from a compatible type.
+     */
+    template<typename U>
+    inline constexpr c2_cntr_t(const U &value) : mValue(compat::get(value)) {}
+
+    /**
+     * Peek as underlying signed type.
+     */
+    C2_ALLOW_OVERFLOW
+    inline constexpr typename std::make_signed<T>::type peek() const {
+        return static_cast<typename std::make_signed<T>::type>(mValue);
+    }
+
+    /**
+     * Peek as underlying unsigned type.
+     */
+    inline constexpr T peeku() const {
+        return mValue;
+    }
+
+    /**
+     * Peek as long long - e.g. for printing.
+     */
+    C2_ALLOW_OVERFLOW
+    inline constexpr long long peekll() const {
+        return (long long)mValue;
+    }
+
+    /**
+     * Peek as unsigned long long - e.g. for printing.
+     */
+    C2_ALLOW_OVERFLOW
+    inline constexpr unsigned long long peekull() const {
+        return (unsigned long long)mValue;
+    }
+
+    /**
+     * Convert to a smaller counter type. This is always safe.
+     */
+    template<typename U, typename E=typename std::enable_if<(sizeof(U) < sizeof(T))>::type>
+    inline constexpr operator c2_cntr_t<U>() {
+        return c2_cntr_t<U>(mValue);
+    }
+
+    /**
+     * Arithmetic operators
+     */
+
+#define DEFINE_C2_CNTR_BINARY_OP(attrib, op, op_assign) \
+    template<typename U> \
+    attrib inline c2_cntr_t<T>& operator op_assign(const U &value) { \
+        mValue op_assign compat::get(value); \
+        return *this; \
+    } \
+    \
+    template<typename U, typename E=decltype(compat::get(U(0)))> \
+    attrib inline constexpr c2_cntr_t<T> operator op(const U &value) const { \
+        return c2_cntr_t<T>(mValue op compat::get(value)); \
+    } \
+    \
+    template<typename U, typename E=typename std::enable_if<(sizeof(U) < sizeof(T))>::type> \
+    attrib inline constexpr c2_cntr_t<U> operator op(const c2_cntr_t<U> &value) const { \
+        return c2_cntr_t<U>(U(mValue) op value.peeku()); \
+    }
+
+#define DEFINE_C2_CNTR_UNARY_OP(attrib, op) \
+    attrib inline constexpr c2_cntr_t<T> operator op() const { \
+        return c2_cntr_t<T>(op mValue); \
+    }
+
+#define DEFINE_C2_CNTR_CREMENT_OP(attrib, op) \
+    attrib inline c2_cntr_t<T> &operator op() { \
+        op mValue; \
+        return *this; \
+    } \
+    attrib inline c2_cntr_t<T> operator op(int) { \
+        return c2_cntr_t<T, void>(mValue op); \
+    }
+
+    DEFINE_C2_CNTR_BINARY_OP(C2_ALLOW_OVERFLOW, +, +=)
+    DEFINE_C2_CNTR_BINARY_OP(C2_ALLOW_OVERFLOW, -, -=)
+    DEFINE_C2_CNTR_BINARY_OP(C2_ALLOW_OVERFLOW, *, *=)
+
+    DEFINE_C2_CNTR_UNARY_OP(C2_ALLOW_OVERFLOW, -)
+    DEFINE_C2_CNTR_UNARY_OP(C2_ALLOW_OVERFLOW, +)
+
+    DEFINE_C2_CNTR_CREMENT_OP(C2_ALLOW_OVERFLOW, ++)
+    DEFINE_C2_CNTR_CREMENT_OP(C2_ALLOW_OVERFLOW, --)
+
+    template<typename U, typename E=typename std::enable_if<std::is_unsigned<U>::value>::type>
+    C2_ALLOW_OVERFLOW
+    inline constexpr c2_cntr_t<T> operator<<(const U &value) const {
+        return c2_cntr_t<T>(mValue << value);
+    }
+
+    template<typename U, typename E=typename std::enable_if<std::is_unsigned<U>::value>::type>
+    C2_ALLOW_OVERFLOW
+    inline c2_cntr_t<T> &operator<<=(const U &value) {
+        mValue <<= value;
+        return *this;
+    }
+
+    /**
+     * Comparison operators
+     */
+    C2_ALLOW_OVERFLOW
+    inline constexpr bool operator<=(const c2_cntr_t<T> &other) const {
+        return T(other.mValue - mValue) < HALF_RANGE;
+    }
+
+    C2_ALLOW_OVERFLOW
+    inline constexpr bool operator>=(const c2_cntr_t<T> &other) const {
+        return T(mValue - other.mValue) < HALF_RANGE;
+    }
+
+    inline constexpr bool operator==(const c2_cntr_t<T> &other) const {
+        return mValue == other.mValue;
+    }
+
+    inline constexpr bool operator!=(const c2_cntr_t<T> &other) const {
+        return !(*this == other);
+    }
+
+    inline constexpr bool operator<(const c2_cntr_t<T> &other) const {
+        return *this <= other && *this != other;
+    }
+
+    inline constexpr bool operator>(const c2_cntr_t<T> &other) const {
+        return *this >= other && *this != other;
+    }
+};
+
+template<typename U, typename T, typename E=typename std::enable_if<std::is_integral<U>::value>::type>
+inline constexpr c2_cntr_t<T> operator+(const U &a, const c2_cntr_t<T> &b) {
+    return b + a;
+}
+
+template<typename U, typename T, typename E=typename std::enable_if<std::is_integral<U>::value>::type>
+inline constexpr c2_cntr_t<T> operator-(const U &a, const c2_cntr_t<T> &b) {
+    return c2_cntr_t<T>(a) - b;
+}
+
+template<typename U, typename T, typename E=typename std::enable_if<std::is_integral<U>::value>::type>
+inline constexpr c2_cntr_t<T> operator*(const U &a, const c2_cntr_t<T> &b) {
+    return b * a;
+}
+
+typedef c2_cntr_t<uint32_t> c2_cntr32_t; /** 32-bit counter type */
+typedef c2_cntr_t<uint64_t> c2_cntr64_t; /** 64-bit counter type */
+
+/// \cond INTERNAL
+
+/// \defgroup utils_internal
+/// @{
+
+template<typename... T> struct c2_types;
+
+/** specialization for a single type */
+template<typename T>
+struct c2_types<T> {
+    typedef typename std::decay<T>::type wide_type;
+    typedef wide_type narrow_type;
+    typedef wide_type min_type; // type for min(T...)
+};
+
+/** specialization for two types */
+template<typename T, typename U>
+struct c2_types<T, U> {
+    static_assert(std::is_floating_point<T>::value == std::is_floating_point<U>::value,
+                  "mixing floating point and non-floating point types is disallowed");
+    static_assert(std::is_signed<T>::value == std::is_signed<U>::value,
+                  "mixing signed and unsigned types is disallowed");
+
+    typedef typename std::decay<
+            decltype(true ? std::declval<T>() : std::declval<U>())>::type wide_type;
+    typedef typename std::decay<
+            typename std::conditional<sizeof(T) < sizeof(U), T, U>::type>::type narrow_type;
+    typedef typename std::conditional<
+            std::is_signed<T>::value, wide_type, narrow_type>::type min_type;
+};
+
+/// @}
+
+/// \endcond
+
+/**
+ * Type support utility class. Only supports similar classes, such as:
+ * - all floating point
+ * - all unsigned/all signed
+ * - all pointer
+ */
+template<typename T, typename U, typename... V>
+struct c2_types<T, U, V...> {
+    /** Common type that accommodates all template parameter types. */
+    typedef typename c2_types<typename c2_types<T, U>::wide_type, V...>::wide_type wide_type;
+    /** Narrowest type of the template parameter types. */
+    typedef typename c2_types<typename c2_types<T, U>::narrow_type, V...>::narrow_type narrow_type;
+    /** Type that accommodates the minimum value for any input for the template parameter types. */
+    typedef typename c2_types<typename c2_types<T, U>::min_type, V...>::min_type min_type;
+};
+
+/**
+ *  \ingroup utils_internal
+ * specialization for two values */
+template<typename T, typename U>
+inline constexpr typename c2_types<T, U>::wide_type c2_max(const T a, const U b) {
+    typedef typename c2_types<T, U>::wide_type wide_type;
+    return ({ wide_type a_(a), b_(b); a_ > b_ ? a_ : b_; });
+}
+
+/**
+ * Finds the maximum value of a list of "similarly typed" values.
+ *
+ * This is an extension to std::max where the types do not have to be identical, and the smallest
+ * resulting type is used that accommodates the argument types.
+ *
+ * \note Value types must be similar, e.g. all floating point, all pointers, all signed, or all
+ * unsigned.
+ *
+ * @return the largest of the input arguments.
+ */
+template<typename T, typename U, typename... V>
+constexpr typename c2_types<T, U, V...>::wide_type c2_max(const T a, const U b, const V ... c) {
+    typedef typename c2_types<T, U, V...>::wide_type wide_type;
+    return ({ wide_type a_(a), b_(c2_max(b, c...)); a_ > b_ ? a_ : b_; });
+}
+
+/**
+ *  \ingroup utils_internal
+ * specialization for two values */
+template<typename T, typename U>
+inline constexpr typename c2_types<T, U>::min_type c2_min(const T a, const U b) {
+    typedef typename c2_types<T, U>::wide_type wide_type;
+    return ({
+        wide_type a_(a), b_(b);
+        static_cast<typename c2_types<T, U>::min_type>(a_ < b_ ? a_ : b_);
+    });
+}
+
+/**
+ * Finds the minimum value of a list of "similarly typed" values.
+ *
+ * This is an extension to std::min where the types do not have to be identical, and the smallest
+ * resulting type is used that accommodates the argument types.
+ *
+ * \note Value types must be similar, e.g. all floating point, all pointers, all signed, or all
+ * unsigned.
+ *
+ * @return the smallest of the input arguments.
+ */
+template<typename T, typename U, typename... V>
+constexpr typename c2_types<T, U, V...>::min_type c2_min(const T a, const U b, const V ... c) {
+    typedef typename c2_types<U, V...>::min_type rest_type;
+    typedef typename c2_types<T, rest_type>::wide_type wide_type;
+    return ({
+        wide_type a_(a), b_(c2_min(b, c...));
+        static_cast<typename c2_types<T, rest_type>::min_type>(a_ < b_ ? a_ : b_);
+    });
+}
+
+/**
+ *  \ingroup utils_internal
+ */
+template<typename T, typename U, typename V>
+inline constexpr typename c2_types<T, V>::wide_type c2_clamp(const T a, const U b, const V c) {
+    typedef typename c2_types<T, U, V>::wide_type wide_type;
+    return ({
+        wide_type a_(a), b_(b), c_(c);
+        static_cast<typename c2_types<T, V>::wide_type>(b_ < a_ ? a_ : b_ > c_ ? c_ : b_);
+    });
+}
+
+/// @}
+
+#include <functional>
+template<typename T>
+struct std::less<::c2_cntr_t<T>> {
+    constexpr bool operator()(const ::c2_cntr_t<T> &lh, const ::c2_cntr_t<T> &rh) const {
+        return lh.peeku() < rh.peeku();
+    }
+};
+template<typename T>
+struct std::less_equal<::c2_cntr_t<T>> {
+    constexpr bool operator()(const ::c2_cntr_t<T> &lh, const ::c2_cntr_t<T> &rh) const {
+        return lh.peeku() <= rh.peeku();
+    }
+};
+template<typename T>
+struct std::greater<::c2_cntr_t<T>> {
+    constexpr bool operator()(const ::c2_cntr_t<T> &lh, const ::c2_cntr_t<T> &rh) const {
+        return lh.peeku() > rh.peeku();
+    }
+};
+template<typename T>
+struct std::greater_equal<::c2_cntr_t<T>> {
+    constexpr bool operator()(const ::c2_cntr_t<T> &lh, const ::c2_cntr_t<T> &rh) const {
+        return lh.peeku() >= rh.peeku();
+    }
+};
+
+#endif  // C2_H_
diff --git a/media/codec2/core/include/C2Buffer.h b/media/codec2/core/include/C2Buffer.h
new file mode 100644
index 0000000..3d3587c
--- /dev/null
+++ b/media/codec2/core/include/C2Buffer.h
@@ -0,0 +1,2184 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef C2BUFFER_H_
+#define C2BUFFER_H_
+
+#include <C2.h>
+#include <C2BufferBase.h>
+#include <C2Param.h> // for C2Info
+
+#include <memory>
+#include <vector>
+
+#ifdef __ANDROID__
+#include <android-C2Buffer.h>
+#else
+
+typedef void* C2Handle;
+
+#endif
+
+/// \defgroup buffer Buffers
+/// @{
+
+/// \defgroup buffer_sync Synchronization
+/// @{
+
+/**
+ * Synchronization is accomplished using event and fence objects.
+ *
+ * These are cross-process extensions of promise/future infrastructure.
+ * Events are analogous to std::promise<void>, whereas fences are to std::shared_future<void>.
+ *
+ * Fences and events are shareable/copyable.
+ *
+ * Fences are used in two scenarios, and all copied instances refer to the same event.
+ * \todo do events need to be copyable or should they be unique?
+ *
+ * acquire sync fence object: signaled when it is safe for the component or client to access
+ * (the contents of) an object.
+ *
+ * release sync fence object: \todo
+ *
+ * Fences can be backed by hardware. Hardware fences are guaranteed to signal NO MATTER WHAT within
+ * a short (platform specific) amount of time; this guarantee is usually less than 15 msecs.
+ */
+
+/**
+ * Fence object used by components and the framework.
+ *
+ * Implements the waiting for an event, analogous to a 'future'.
+ *
+ * To be implemented by vendors if using HW fences.
+ */
+class C2Fence {
+public:
+    /**
+     * Waits for a fence to be signaled with a timeout.
+     *
+     * \todo a mechanism to cancel a wait - for now the only way to do this is to abandon the
+     * event, but fences are shared so canceling a wait will cancel all waits.
+     *
+     * \param timeoutNs           the maximum time to wait in nsecs
+     *
+     * \retval C2_OK            the fence has been signaled
+     * \retval C2_TIMED_OUT     the fence has not been signaled within the timeout
+     * \retval C2_BAD_STATE     the fence has been abandoned without being signaled (it will never
+     *                          be signaled)
+     * \retval C2_REFUSED       no permission to wait for the fence (unexpected - system)
+     * \retval C2_CORRUPTED     some unknown error prevented waiting for the fence (unexpected)
+     */
+    c2_status_t wait(c2_nsecs_t timeoutNs);
+
+    /**
+     * Used to check if this fence is valid (if there is a chance for it to be signaled.)
+     * A fence becomes invalid if the controling event is destroyed without it signaling the fence.
+     *
+     * \return whether this fence is valid
+     */
+    bool valid() const;
+
+    /**
+     * Used to check if this fence has been signaled (is ready).
+     *
+     * \return whether this fence has been signaled
+     */
+    bool ready() const;
+
+    /**
+     * Returns a file descriptor that can be used to wait for this fence in a select system call.
+     * \note The returned file descriptor, if valid, must be closed by the caller.
+     *
+     * This can be used in e.g. poll() system calls. This file becomes readable (POLLIN) when the
+     * fence is signaled, and bad (POLLERR) if the fence is abandoned.
+     *
+     * \return a file descriptor representing this fence (with ownership), or -1 if the fence
+     * has already been signaled (\todo or abandoned).
+     *
+     * \todo this must be compatible with fences used by gralloc
+     */
+    int fd() const;
+
+    /**
+     * Returns whether this fence is a hardware-backed fence.
+     * \return whether this is a hardware fence
+     */
+    bool isHW() const;
+
+    /**
+     * Null-fence. A fence that has fired.
+     */
+    constexpr C2Fence() : mImpl(nullptr) { }
+
+private:
+    class Impl;
+    std::shared_ptr<Impl> mImpl;
+    C2Fence(std::shared_ptr<Impl> impl);
+    friend struct _C2FenceFactory;
+};
+
+/**
+ * Event object used by components and the framework.
+ *
+ * Implements the signaling of an event, analogous to a 'promise'.
+ *
+ * Hardware backed events do not go through this object, and must be exposed directly as fences
+ * by vendors.
+ */
+class C2Event {
+public:
+    /**
+     * Returns a fence for this event.
+     */
+    C2Fence fence() const;
+
+    /**
+     * Signals (all) associated fence(s).
+     * This has no effect no effect if the event was already signaled or abandoned.
+     *
+     * \retval C2_OK            the fence(s) were successfully signaled
+     * \retval C2_BAD_STATE     the fence(s) have already been abandoned or merged (caller error)
+     * \retval C2_DUPLICATE     the fence(s) have already been signaled (caller error)
+     * \retval C2_REFUSED       no permission to signal the fence (unexpected - system)
+     * \retval C2_CORRUPTED     some unknown error prevented signaling the fence(s) (unexpected)
+     */
+    c2_status_t fire();
+
+    /**
+     * Trigger this event from the merging of the supplied fences. This means that it will be
+     * abandoned if any of these fences have been abandoned, and it will be fired if all of these
+     * fences have been signaled.
+     *
+     * \retval C2_OK            the merging was successfully done
+     * \retval C2_NO_MEMORY     not enough memory to perform the merging
+     * \retval C2_DUPLICATE     the fence have already been merged (caller error)
+     * \retval C2_BAD_STATE     the fence have already been signaled or abandoned (caller error)
+     * \retval C2_REFUSED       no permission to merge the fence (unexpected - system)
+     * \retval C2_CORRUPTED     some unknown error prevented merging the fence(s) (unexpected)
+     */
+    c2_status_t merge(std::vector<C2Fence> fences);
+
+    /**
+     * Abandons the event and any associated fence(s).
+     * \note Call this to explicitly abandon an event before it is destructed to avoid a warning.
+     *
+     * This has no effect no effect if the event was already signaled or abandoned.
+     *
+     * \retval C2_OK            the fence(s) were successfully signaled
+     * \retval C2_BAD_STATE     the fence(s) have already been signaled or merged (caller error)
+     * \retval C2_DUPLICATE     the fence(s) have already been abandoned (caller error)
+     * \retval C2_REFUSED       no permission to abandon the fence (unexpected - system)
+     * \retval C2_CORRUPTED     some unknown error prevented signaling the fence(s) (unexpected)
+     */
+    c2_status_t abandon();
+
+private:
+    class Impl;
+    std::shared_ptr<Impl> mImpl;
+};
+
+/// \addtogroup buf_internal Internal
+/// @{
+
+/**
+ * Interface for objects that encapsulate an updatable status value.
+ */
+struct _C2InnateStatus {
+    inline c2_status_t status() const { return mStatus; }
+
+protected:
+    _C2InnateStatus(c2_status_t status) : mStatus(status) { }
+
+    c2_status_t mStatus; // this status is updatable by the object
+};
+
+/// @}
+
+/**
+ * This is a utility template for objects protected by an acquire fence, so that errors during
+ * acquiring the object are propagated to the object itself.
+ */
+template<typename T>
+class C2Acquirable : public C2Fence {
+public:
+    /**
+     * Acquires the object protected by an acquire fence. Any errors during the mapping will be
+     * passed to the object.
+     *
+     * \return acquired object potentially invalidated if waiting for the fence failed.
+     */
+    T get() {
+        // TODO:
+        // wait();
+        return mT;
+    }
+
+protected:
+    C2Acquirable(c2_status_t error, C2Fence fence, T t) : C2Fence(fence), mInitialError(error), mT(t) { }
+
+private:
+    c2_status_t mInitialError;
+    T mT; // TODO: move instead of copy
+};
+
+/// @}
+
+/// \defgroup linear Linear Data Blocks
+/// @{
+
+/**************************************************************************************************
+  LINEAR ASPECTS, BLOCKS AND VIEWS
+**************************************************************************************************/
+
+/**
+ * Basic segment math support.
+ */
+struct C2Segment {
+    uint32_t offset;
+    uint32_t size;
+
+    inline constexpr C2Segment(uint32_t offset_, uint32_t size_)
+        : offset(offset_),
+          size(size_) {
+    }
+
+    inline constexpr bool isEmpty() const {
+        return size == 0;
+    }
+
+    inline constexpr bool isValid() const {
+        return offset <= ~size;
+    }
+
+    inline constexpr operator bool() const {
+        return isValid() && !isEmpty();
+    }
+
+    inline constexpr bool operator!() const {
+        return !bool(*this);
+    }
+
+    C2_ALLOW_OVERFLOW
+    inline constexpr bool contains(const C2Segment &other) const {
+        if (!isValid() || !other.isValid()) {
+            return false;
+        } else {
+            return offset <= other.offset
+                    && offset + size >= other.offset + other.size;
+        }
+    }
+
+    inline constexpr bool operator==(const C2Segment &other) const {
+        if (!isValid()) {
+            return !other.isValid();
+        } else {
+            return offset == other.offset && size == other.size;
+        }
+    }
+
+    inline constexpr bool operator!=(const C2Segment &other) const {
+        return !operator==(other);
+    }
+
+    inline constexpr bool operator>=(const C2Segment &other) const {
+        return contains(other);
+    }
+
+    inline constexpr bool operator>(const C2Segment &other) const {
+        return contains(other) && !operator==(other);
+    }
+
+    inline constexpr bool operator<=(const C2Segment &other) const {
+        return other.contains(*this);
+    }
+
+    inline constexpr bool operator<(const C2Segment &other) const {
+        return other.contains(*this) && !operator==(other);
+    }
+
+    C2_ALLOW_OVERFLOW
+    inline constexpr uint32_t end() const {
+        return offset + size;
+    }
+
+    C2_ALLOW_OVERFLOW
+    inline constexpr C2Segment intersect(const C2Segment &other) const {
+        return C2Segment(c2_max(offset, other.offset),
+                         c2_min(end(), other.end()) - c2_max(offset, other.offset));
+    }
+
+    /** clamps end to offset if it overflows */
+    inline constexpr C2Segment normalize() const {
+        return C2Segment(offset, c2_max(offset, end()) - offset);
+    }
+
+    /** clamps end to max if it overflows */
+    inline constexpr C2Segment saturate() const {
+        return C2Segment(offset, c2_min(size, ~offset));
+    }
+
+};
+
+/**
+ * Common aspect for all objects that have a linear capacity.
+ */
+class _C2LinearCapacityAspect {
+/// \name Linear capacity interface
+/// @{
+public:
+    inline constexpr uint32_t capacity() const { return mCapacity; }
+
+    inline constexpr operator C2Segment() const {
+        return C2Segment(0, mCapacity);
+    }
+
+protected:
+
+#if UINTPTR_MAX == 0xffffffff
+    static_assert(sizeof(size_t) == sizeof(uint32_t), "size_t is too big");
+#else
+    static_assert(sizeof(size_t) > sizeof(uint32_t), "size_t is too small");
+    // explicitly disable construction from size_t
+    inline explicit _C2LinearCapacityAspect(size_t capacity) = delete;
+#endif
+
+    inline explicit constexpr _C2LinearCapacityAspect(uint32_t capacity)
+      : mCapacity(capacity) { }
+
+    inline explicit constexpr _C2LinearCapacityAspect(const _C2LinearCapacityAspect *parent)
+        : mCapacity(parent == nullptr ? 0 : parent->capacity()) { }
+
+private:
+    uint32_t mCapacity;
+/// @}
+};
+
+/**
+ * Aspect for objects that have a linear range inside a linear capacity.
+ *
+ * This class is copiable.
+ */
+class _C2LinearRangeAspect : public _C2LinearCapacityAspect {
+/// \name Linear range interface
+/// @{
+public:
+    inline constexpr uint32_t offset() const { return mOffset; }
+    inline constexpr uint32_t endOffset() const { return mOffset + mSize; }
+    inline constexpr uint32_t size() const { return mSize; }
+
+    inline constexpr operator C2Segment() const {
+        return C2Segment(mOffset, mSize);
+    }
+
+private:
+    // subrange of capacity [0, capacity] & [size, size + offset]
+    inline constexpr _C2LinearRangeAspect(uint32_t capacity_, size_t offset, size_t size)
+        : _C2LinearCapacityAspect(capacity_),
+          mOffset(c2_min(offset, capacity())),
+          mSize(c2_min(size, capacity() - mOffset)) {
+    }
+
+protected:
+    // copy constructor (no error check)
+    inline constexpr _C2LinearRangeAspect(const _C2LinearRangeAspect &other)
+        : _C2LinearCapacityAspect(other.capacity()),
+          mOffset(other.offset()),
+          mSize(other.size()) {
+    }
+
+    // parent capacity range [0, capacity]
+    inline constexpr explicit _C2LinearRangeAspect(const _C2LinearCapacityAspect *parent)
+        : _C2LinearCapacityAspect(parent),
+          mOffset(0),
+          mSize(capacity()) {
+    }
+
+    // subrange of parent capacity [0, capacity] & [size, size + offset]
+    inline constexpr _C2LinearRangeAspect(const _C2LinearCapacityAspect *parent, size_t offset, size_t size)
+        : _C2LinearCapacityAspect(parent),
+          mOffset(c2_min(offset, capacity())),
+          mSize(c2_min(size, capacity() - mOffset)) {
+    }
+
+    // subsection of the parent's and [offset, offset + size] ranges
+    inline constexpr _C2LinearRangeAspect(const _C2LinearRangeAspect *parent, size_t offset, size_t size)
+        : _C2LinearCapacityAspect(parent),
+          mOffset(c2_min(c2_max(offset, parent == nullptr ? 0 : parent->offset()), capacity())),
+          mSize(std::min(c2_min(size, parent == nullptr ? 0 : parent->size()), capacity() - mOffset)) {
+    }
+
+public:
+    inline constexpr _C2LinearRangeAspect childRange(size_t offset, size_t size) const {
+        return _C2LinearRangeAspect(
+            mSize,
+            c2_min(c2_max(offset, mOffset), capacity()) - mOffset,
+            c2_min(c2_min(size, mSize), capacity() - c2_min(c2_max(offset, mOffset), capacity())));
+    }
+
+    friend class _C2EditableLinearRangeAspect;
+    // invariants 0 <= mOffset <= mOffset + mSize <= capacity()
+    uint32_t mOffset;
+    uint32_t mSize;
+/// @}
+};
+
+/**
+ * Utility class for safe range calculations using size_t-s.
+ */
+class C2LinearRange : public _C2LinearRangeAspect {
+public:
+    inline constexpr C2LinearRange(const _C2LinearCapacityAspect &parent, size_t offset, size_t size)
+        : _C2LinearRangeAspect(&parent, offset, size) { }
+
+    inline constexpr C2LinearRange(const _C2LinearRangeAspect &parent, size_t offset, size_t size)
+        : _C2LinearRangeAspect(&parent, offset, size) { }
+
+    inline constexpr C2LinearRange intersect(size_t offset, size_t size) const {
+        return C2LinearRange(*this, offset, size);
+    }
+};
+
+/**
+ * Utility class for simple and safe capacity and range construction.
+ */
+class C2LinearCapacity : public _C2LinearCapacityAspect {
+public:
+    inline constexpr explicit C2LinearCapacity(size_t capacity)
+        : _C2LinearCapacityAspect(c2_min(capacity, std::numeric_limits<uint32_t>::max())) { }
+
+    inline constexpr C2LinearRange range(size_t offset, size_t size) const {
+        return C2LinearRange(*this, offset, size);
+    }
+};
+
+/**
+ * Aspect for objects that have an editable linear range.
+ *
+ * This class is copiable.
+ */
+class _C2EditableLinearRangeAspect : public _C2LinearRangeAspect {
+    using _C2LinearRangeAspect::_C2LinearRangeAspect;
+
+public:
+/// \name Editable linear range interface
+/// @{
+
+    /**
+     * Sets the offset to |offset|, while trying to keep the end of the buffer unchanged (e.g.
+     * size will grow if offset is decreased, and may shrink if offset is increased.) Returns
+     * true if successful, which is equivalent to if 0 <= |offset| <= capacity().
+     *
+     * Note: setting offset and size will yield different result depending on the order of the
+     * operations. Always set offset first to ensure proper size.
+     */
+    inline bool setOffset(uint32_t offset) {
+        if (offset > capacity()) {
+            return false;
+        }
+
+        if (offset > mOffset + mSize) {
+            mSize = 0;
+        } else {
+            mSize = mOffset + mSize - offset;
+        }
+        mOffset = offset;
+        return true;
+    }
+
+    /**
+     * Sets the size to |size|. Returns true if successful, which is equivalent to
+     * if 0 <= |size| <= capacity() - offset().
+     *
+     * Note: setting offset and size will yield different result depending on the order of the
+     * operations. Always set offset first to ensure proper size.
+     */
+    inline bool setSize(uint32_t size) {
+        if (size > capacity() - mOffset) {
+            return false;
+        } else {
+            mSize = size;
+            return true;
+        }
+    }
+
+    /**
+     * Sets the offset to |offset| with best effort. Same as setOffset() except that offset will
+     * be clamped to the buffer capacity.
+     *
+     * Note: setting offset and size (even using best effort) will yield different result depending
+     * on the order of the operations. Always set offset first to ensure proper size.
+     */
+    inline void setOffset_be(uint32_t offset) {
+        (void)setOffset(c2_min(offset, capacity()));
+    }
+
+    /**
+     * Sets the size to |size| with best effort. Same as setSize() except that the selected region
+     * will be clamped to the buffer capacity (e.g. size is clamped to [0, capacity() - offset()]).
+     *
+     * Note: setting offset and size (even using best effort) will yield different result depending
+     * on the order of the operations. Always set offset first to ensure proper size.
+     */
+    inline void setSize_be(uint32_t size) {
+        mSize = c2_min(size, capacity() - mOffset);
+    }
+/// @}
+};
+
+/**************************************************************************************************
+  ALLOCATIONS
+**************************************************************************************************/
+
+/// \ingroup allocator Allocation and memory placement
+/// @{
+
+class C2LinearAllocation;
+class C2GraphicAllocation;
+
+/**
+ *  Allocators are used by the framework to allocate memory (allocations) for buffers. They can
+ *  support either 1D or 2D allocations.
+ *
+ *  \note In theory they could support both, but in practice, we will use only one or the other.
+ *
+ *  Never constructed on stack.
+ *
+ *  Allocators are provided by vendors.
+ */
+class C2Allocator {
+public:
+    /**
+     * Allocator ID type.
+     */
+    typedef uint32_t id_t;
+    enum : id_t {
+        BAD_ID = 0xBADD, // invalid allocator ID
+    };
+
+    /**
+     * Allocation types. This is a bitmask and is used in C2Allocator::Info
+     * to list the supported allocation types of an allocator.
+     */
+    enum type_t : uint32_t {
+        LINEAR  = 1 << 0, //
+        GRAPHIC = 1 << 1,
+    };
+
+    /**
+     * Information about an allocator.
+     *
+     * Allocators don't have a query API so all queriable information is stored here.
+     */
+    struct Traits {
+        C2String name;              ///< allocator name
+        id_t id;                    ///< allocator ID
+        type_t supportedTypes;      ///< supported allocation types
+        C2MemoryUsage minimumUsage; ///< usage that is minimally required for allocations
+        C2MemoryUsage maximumUsage; ///< usage that is maximally allowed for allocations
+    };
+
+    /**
+     * Returns the unique name of this allocator.
+     *
+     * This method MUST be "non-blocking" and return within 1ms.
+     *
+     * \return the name of this allocator.
+     * \retval an empty string if there was not enough memory to allocate the actual name.
+     */
+    virtual C2String getName() const = 0;
+
+    /**
+     * Returns a unique ID for this allocator. This ID is used to get this allocator from the
+     * allocator store, and to identify this allocator across all processes.
+     *
+     * This method MUST be "non-blocking" and return within 1ms.
+     *
+     * \return a unique ID for this allocator.
+     */
+    virtual id_t getId() const = 0;
+
+    /**
+     * Returns the allocator traits.
+     *
+     * This method MUST be "non-blocking" and return within 1ms.
+     *
+     * Allocators don't have a full-fledged query API, only this method.
+     *
+     * \return allocator information
+     */
+    virtual std::shared_ptr<const Traits> getTraits() const = 0;
+
+    /**
+     * Allocates a 1D allocation of given |capacity| and |usage|. If successful, the allocation is
+     * stored in |allocation|. Otherwise, |allocation| is set to 'nullptr'.
+     *
+     * \param capacity      the size of requested allocation (the allocation could be slightly
+     *                      larger, e.g. to account for any system-required alignment)
+     * \param usage         the memory usage info for the requested allocation. \note that the
+     *                      returned allocation may be later used/mapped with different usage.
+     *                      The allocator should layout the buffer to be optimized for this usage,
+     *                      but must support any usage. One exception: protected buffers can
+     *                      only be used in a protected scenario.
+     * \param allocation    pointer to where the allocation shall be stored on success. nullptr
+     *                      will be stored here on failure
+     *
+     * \retval C2_OK        the allocation was successful
+     * \retval C2_NO_MEMORY not enough memory to complete the allocation
+     * \retval C2_TIMED_OUT the allocation timed out
+     * \retval C2_REFUSED   no permission to complete the allocation
+     * \retval C2_BAD_VALUE capacity or usage are not supported (invalid) (caller error)
+     * \retval C2_OMITTED   this allocator does not support 1D allocations
+     * \retval C2_CORRUPTED some unknown, unrecoverable error occured during allocation (unexpected)
+     */
+    virtual c2_status_t newLinearAllocation(
+            uint32_t capacity __unused, C2MemoryUsage usage __unused,
+            std::shared_ptr<C2LinearAllocation> *allocation /* nonnull */) {
+        *allocation = nullptr;
+        return C2_OMITTED;
+    }
+
+    /**
+     * (Re)creates a 1D allocation from a native |handle|. If successful, the allocation is stored
+     * in |allocation|. Otherwise, |allocation| is set to 'nullptr'.
+     *
+     * \param handle      the handle for the existing allocation. On success, the allocation will
+     *                    take ownership of |handle|.
+     * \param allocation  pointer to where the allocation shall be stored on success. nullptr
+     *                    will be stored here on failure
+     *
+     * \retval C2_OK        the allocation was recreated successfully
+     * \retval C2_NO_MEMORY not enough memory to recreate the allocation
+     * \retval C2_TIMED_OUT the recreation timed out (unexpected)
+     * \retval C2_REFUSED   no permission to recreate the allocation
+     * \retval C2_BAD_VALUE invalid handle (caller error)
+     * \retval C2_OMITTED   this allocator does not support 1D allocations
+     * \retval C2_CORRUPTED some unknown, unrecoverable error occured during allocation (unexpected)
+     */
+    virtual c2_status_t priorLinearAllocation(
+            const C2Handle *handle __unused,
+            std::shared_ptr<C2LinearAllocation> *allocation /* nonnull */) {
+        *allocation = nullptr;
+        return C2_OMITTED;
+    }
+
+    /**
+     * Allocates a 2D allocation of given |width|, |height|, |format| and |usage|. If successful,
+     * the allocation is stored in |allocation|. Otherwise, |allocation| is set to 'nullptr'.
+     *
+     * \param width         the width of requested allocation (the allocation could be slightly
+     *                      larger, e.g. to account for any system-required alignment)
+     * \param height        the height of requested allocation (the allocation could be slightly
+     *                      larger, e.g. to account for any system-required alignment)
+     * \param format        the pixel format of requested allocation. This could be a vendor
+     *                      specific format.
+     * \param usage         the memory usage info for the requested allocation. \note that the
+     *                      returned allocation may be later used/mapped with different usage.
+     *                      The allocator should layout the buffer to be optimized for this usage,
+     *                      but must support any usage. One exception: protected buffers can
+     *                      only be used in a protected scenario.
+     * \param allocation    pointer to where the allocation shall be stored on success. nullptr
+     *                      will be stored here on failure
+     *
+     * \retval C2_OK        the allocation was successful
+     * \retval C2_NO_MEMORY not enough memory to complete the allocation
+     * \retval C2_TIMED_OUT the allocation timed out
+     * \retval C2_REFUSED   no permission to complete the allocation
+     * \retval C2_BAD_VALUE width, height, format or usage are not supported (invalid) (caller error)
+     * \retval C2_OMITTED   this allocator does not support 2D allocations
+     * \retval C2_CORRUPTED some unknown, unrecoverable error occured during allocation (unexpected)
+     */
+    virtual c2_status_t newGraphicAllocation(
+            uint32_t width __unused, uint32_t height __unused, uint32_t format __unused,
+            C2MemoryUsage usage __unused,
+            std::shared_ptr<C2GraphicAllocation> *allocation /* nonnull */) {
+        *allocation = nullptr;
+        return C2_OMITTED;
+    }
+
+    /**
+     * (Re)creates a 2D allocation from a native handle.  If successful, the allocation is stored
+     * in |allocation|. Otherwise, |allocation| is set to 'nullptr'.
+     *
+     * \param handle      the handle for the existing allocation. On success, the allocation will
+     *                    take ownership of |handle|.
+     * \param allocation  pointer to where the allocation shall be stored on success. nullptr
+     *                    will be stored here on failure
+     *
+     * \retval C2_OK        the allocation was recreated successfully
+     * \retval C2_NO_MEMORY not enough memory to recreate the allocation
+     * \retval C2_TIMED_OUT the recreation timed out (unexpected)
+     * \retval C2_REFUSED   no permission to recreate the allocation
+     * \retval C2_BAD_VALUE invalid handle (caller error)
+     * \retval C2_OMITTED   this allocator does not support 2D allocations
+     * \retval C2_CORRUPTED some unknown, unrecoverable error occured during recreation (unexpected)
+     */
+    virtual c2_status_t priorGraphicAllocation(
+            const C2Handle *handle __unused,
+            std::shared_ptr<C2GraphicAllocation> *allocation /* nonnull */) {
+        *allocation = nullptr;
+        return C2_OMITTED;
+    }
+
+    virtual ~C2Allocator() = default;
+protected:
+    C2Allocator() = default;
+};
+
+/**
+ * \ingroup linear allocator
+ * 1D allocation interface.
+ */
+class C2LinearAllocation : public _C2LinearCapacityAspect {
+public:
+    /**
+     * Maps a portion of an allocation starting from |offset| with |size| into local process memory.
+     * Stores the starting address into |addr|, or NULL if the operation was unsuccessful.
+     * |fence| will contain an acquire sync fence object. If it is already
+     * safe to access the buffer contents, then it will contain an empty (already fired) fence.
+     *
+     * \param offset        starting position of the portion to be mapped (this does not have to
+     *                      be page aligned)
+     * \param size          size of the portion to be mapped (this does not have to be page
+     *                      aligned)
+     * \param usage         the desired usage. \todo this must be kSoftwareRead and/or
+     *                      kSoftwareWrite.
+     * \param fence         a pointer to a fence object if an async mapping is requested. If
+     *                      not-null, and acquire fence will be stored here on success, or empty
+     *                      fence on failure. If null, the mapping will be synchronous.
+     * \param addr          a pointer to where the starting address of the mapped portion will be
+     *                      stored. On failure, nullptr will be stored here.
+     *
+     * \todo Only one portion can be mapped at the same time - this is true for gralloc, but there
+     *       is no need for this for 1D buffers.
+     * \todo Do we need to support sync operation as we could just wait for the fence?
+     *
+     * \retval C2_OK        the operation was successful
+     * \retval C2_REFUSED   no permission to map the portion
+     * \retval C2_TIMED_OUT the operation timed out
+     * \retval C2_DUPLICATE if the allocation is already mapped.
+     * \retval C2_NO_MEMORY not enough memory to complete the operation
+     * \retval C2_BAD_VALUE the parameters (offset/size) are invalid or outside the allocation, or
+     *                      the usage flags are invalid (caller error)
+     * \retval C2_CORRUPTED some unknown error prevented the operation from completing (unexpected)
+     */
+    virtual c2_status_t map(
+            size_t offset, size_t size, C2MemoryUsage usage, C2Fence *fence /* nullable */,
+            void **addr /* nonnull */) = 0;
+
+    /**
+     * Unmaps a portion of an allocation at |addr| with |size|. These must be parameters previously
+     * passed to and returned by |map|; otherwise, this operation is a no-op.
+     *
+     * \param addr          starting address of the mapped region
+     * \param size          size of the mapped region
+     * \param fence         a pointer to a fence object if an async unmapping is requested. If
+     *                      not-null, a release fence will be stored here on success, or empty fence
+     *                      on failure. This fence signals when the original allocation contains
+     *                      all changes that happened to the mapped region. If null, the unmapping
+     *                      will be synchronous.
+     *
+     * \retval C2_OK        the operation was successful
+     * \retval C2_TIMED_OUT the operation timed out
+     * \retval C2_NOT_FOUND if the allocation was not mapped previously.
+     * \retval C2_BAD_VALUE the parameters (addr/size) do not correspond to previously mapped
+     *                      regions (caller error)
+     * \retval C2_CORRUPTED some unknown error prevented the operation from completing (unexpected)
+     * \retval C2_REFUSED   no permission to unmap the portion (unexpected - system)
+     */
+    virtual c2_status_t unmap(void *addr, size_t size, C2Fence *fence /* nullable */) = 0;
+
+    /**
+     * Returns the allocator ID for this allocation. This is useful to put the handle into context.
+     */
+    virtual C2Allocator::id_t getAllocatorId() const = 0;
+
+    /**
+     * Returns a pointer to the allocation handle.
+     */
+    virtual const C2Handle *handle() const = 0;
+
+    /**
+     * Returns true if this is the same allocation as |other|.
+     */
+    virtual bool equals(const std::shared_ptr<C2LinearAllocation> &other) const = 0;
+
+protected:
+    // \todo should we limit allocation directly?
+    C2LinearAllocation(size_t capacity) : _C2LinearCapacityAspect(c2_min(capacity, UINT32_MAX)) {}
+    virtual ~C2LinearAllocation() = default;
+};
+
+class C2CircularBlock;
+class C2LinearBlock;
+class C2GraphicBlock;
+
+/**
+ *  Block pools are used by components to obtain output buffers in an efficient way. They can
+ *  support either linear (1D), circular (1D) or graphic (2D) blocks.
+ *
+ *  Block pools decouple the recycling of memory/allocations from the components. They are meant to
+ *  be an opaque service (there are no public APIs other than obtaining blocks) provided by the
+ *  platform. Block pools are also meant to decouple allocations from memory used by buffers. This
+ *  is accomplished by allowing pools to allot multiple memory 'blocks' on a single allocation. As
+ *  their name suggest, block pools maintain a pool of memory blocks. When a component asks for
+ *  a memory block, pools will try to return a free memory block already in the pool. If no such
+ *  block exists, they will allocate memory using the backing allocator and allot a block on that
+ *  allocation. When blocks are no longer used in the system, they are recycled back to the block
+ *  pool and are available as free blocks.
+ *
+ *  Never constructed on stack.
+ */
+class C2BlockPool {
+public:
+    /**
+     * Block pool ID type.
+     */
+    typedef uint64_t local_id_t;
+
+    enum : local_id_t {
+        BASIC_LINEAR = 0,  ///< ID of basic (unoptimized) block pool for fetching 1D blocks
+        BASIC_GRAPHIC = 1, ///< ID of basic (unoptimized) block pool for fetching 2D blocks
+        PLATFORM_START = 0x10,
+    };
+
+    /**
+     * Returns the ID for this block pool. This ID is used to get this block pool from the platform.
+     * It is only valid in the current process.
+     *
+     * This method MUST be "non-blocking" and return within 1ms.
+     *
+     * \return a local ID for this block pool.
+     */
+    virtual local_id_t getLocalId() const = 0;
+
+    /**
+     * Returns the ID of the backing allocator of this block pool.
+     *
+     * This method MUST be "non-blocking" and return within 1ms.
+     *
+     * \return the ID of the backing allocator of this block pool.
+     */
+    virtual C2Allocator::id_t getAllocatorId() const = 0;
+
+    /**
+     * Obtains a linear writeable block of given |capacity| and |usage|. If successful, the
+     * block is stored in |block|. Otherwise, |block| is set to 'nullptr'.
+     *
+     * \param capacity the size of requested block.
+     * \param usage    the memory usage info for the requested block. Returned blocks will be
+     *                 optimized for this usage, but may be used with any usage. One exception:
+     *                 protected blocks/buffers can only be used in a protected scenario.
+     * \param block    pointer to where the obtained block shall be stored on success. nullptr will
+     *                 be stored here on failure
+     *
+     * \retval C2_OK        the operation was successful
+     * \retval C2_NO_MEMORY not enough memory to complete any required allocation
+     * \retval C2_TIMED_OUT the operation timed out
+     * \retval C2_BLOCKING  the operation is blocked
+     * \retval C2_REFUSED   no permission to complete any required allocation
+     * \retval C2_BAD_VALUE capacity or usage are not supported (invalid) (caller error)
+     * \retval C2_OMITTED   this pool does not support linear blocks
+     * \retval C2_CORRUPTED some unknown, unrecoverable error occured during operation (unexpected)
+     */
+    virtual c2_status_t fetchLinearBlock(
+            uint32_t capacity __unused, C2MemoryUsage usage __unused,
+            std::shared_ptr<C2LinearBlock> *block /* nonnull */) {
+        *block = nullptr;
+        return C2_OMITTED;
+    }
+
+    /**
+     * Obtains a circular writeable block of given |capacity| and |usage|. If successful, the
+     * block is stored in |block|. Otherwise, |block| is set to 'nullptr'.
+     *
+     * \param capacity the size of requested circular block. (note: the size of the obtained
+     *                 block could be slightly larger, e.g. to accommodate any system-required
+     *                 alignment)
+     * \param usage    the memory usage info for the requested block. Returned blocks will be
+     *                 optimized for this usage, but may be used with any usage. One exception:
+     *                 protected blocks/buffers can only be used in a protected scenario.
+     * \param block    pointer to where the obtained block shall be stored on success. nullptr
+     *                 will be stored here on failure
+     *
+     * \retval C2_OK        the operation was successful
+     * \retval C2_NO_MEMORY not enough memory to complete any required allocation
+     * \retval C2_TIMED_OUT the operation timed out
+     * \retval C2_BLOCKING  the operation is blocked
+     * \retval C2_REFUSED   no permission to complete any required allocation
+     * \retval C2_BAD_VALUE capacity or usage are not supported (invalid) (caller error)
+     * \retval C2_OMITTED   this pool does not support circular blocks
+     * \retval C2_CORRUPTED some unknown, unrecoverable error occured during operation (unexpected)
+     */
+    virtual c2_status_t fetchCircularBlock(
+            uint32_t capacity __unused, C2MemoryUsage usage __unused,
+            std::shared_ptr<C2CircularBlock> *block /* nonnull */) {
+        *block = nullptr;
+        return C2_OMITTED;
+    }
+
+    /**
+     * Obtains a 2D graphic block of given |width|, |height|, |format| and |usage|. If successful,
+     * the block is stored in |block|. Otherwise, |block| is set to 'nullptr'.
+     *
+     * \param width  the width of requested block (the obtained block could be slightly larger, e.g.
+     *               to accommodate any system-required alignment)
+     * \param height the height of requested block (the obtained block could be slightly larger,
+     *               e.g. to accommodate any system-required alignment)
+     * \param format the pixel format of requested block. This could be a vendor specific format.
+     * \param usage  the memory usage info for the requested block. Returned blocks will be
+     *               optimized for this usage, but may be used with any usage. One exception:
+     *               protected blocks/buffers can only be used in a protected scenario.
+     * \param block  pointer to where the obtained block shall be stored on success. nullptr
+     *               will be stored here on failure
+     *
+     * \retval C2_OK        the operation was successful
+     * \retval C2_NO_MEMORY not enough memory to complete any required allocation
+     * \retval C2_TIMED_OUT the operation timed out
+     * \retval C2_BLOCKING  the operation is blocked
+     * \retval C2_REFUSED   no permission to complete any required allocation
+     * \retval C2_BAD_VALUE width, height, format or usage are not supported (invalid) (caller
+     *                      error)
+     * \retval C2_OMITTED   this pool does not support 2D blocks
+     * \retval C2_CORRUPTED some unknown, unrecoverable error occured during operation (unexpected)
+     */
+    virtual c2_status_t fetchGraphicBlock(
+            uint32_t width __unused, uint32_t height __unused, uint32_t format __unused,
+            C2MemoryUsage usage __unused,
+            std::shared_ptr<C2GraphicBlock> *block /* nonnull */) {
+        *block = nullptr;
+        return C2_OMITTED;
+    }
+
+    virtual ~C2BlockPool() = default;
+protected:
+    C2BlockPool() = default;
+};
+
+/// @}
+
+// ================================================================================================
+//  BLOCKS
+// ================================================================================================
+
+/**
+ * Blocks are sections of allocations. They can be either 1D or 2D.
+ */
+
+class C2LinearAllocation;
+
+/**
+ * A 1D block.
+ *
+ * \note capacity() is not meaningful for users of blocks; instead size() is the capacity of the
+ * usable portion. Use and offset() and size() if accessing the block directly through its handle
+ * to represent the allotted range of the underlying allocation to this block.
+ */
+class C2Block1D : public _C2LinearRangeAspect {
+public:
+    /**
+     * Returns the underlying handle for this allocation.
+     *
+     * \note that the block and its block pool has shared ownership of the handle
+     *       and if all references to the block are released, the underlying block
+     *       allocation may get reused even if a client keeps a clone of this handle.
+     */
+    const C2Handle *handle() const;
+
+    /**
+     * Returns the allocator's ID that created the underlying allocation for this block. This
+     * provides the context for understanding the handle.
+     */
+    C2Allocator::id_t getAllocatorId() const;
+
+protected:
+    class Impl;
+    /** construct a block. */
+    C2Block1D(std::shared_ptr<Impl> impl, const _C2LinearRangeAspect &range);
+
+    friend struct _C2BlockFactory;
+    std::shared_ptr<Impl> mImpl;
+};
+
+/**
+ * Read view provides read-only access for a linear memory segment.
+ *
+ * This class is copiable.
+ */
+class C2ReadView : public _C2LinearCapacityAspect {
+public:
+    /**
+     * \return pointer to the start of the block or nullptr on error.
+     *         This pointer is only valid during the lifetime of this view or until it is released.
+     */
+    const uint8_t *data() const;
+
+    /**
+     * Returns a portion of this view.
+     *
+     * \param offset  the start offset of the portion. \note This is clamped to the capacity of this
+     *              view.
+     * \param size    the size of the portion. \note This is clamped to the remaining data from offset.
+     *
+     * \return a read view containing a portion of this view
+     */
+    C2ReadView subView(size_t offset, size_t size) const;
+
+    /**
+     * \return error during the creation/mapping of this view.
+     */
+    c2_status_t error() const;
+
+    /**
+     * Releases this view. This sets error to C2_NO_INIT.
+     */
+    //void release();
+
+protected:
+    class Impl;
+    C2ReadView(std::shared_ptr<Impl> impl, uint32_t offset, uint32_t size);
+    explicit C2ReadView(c2_status_t error);
+
+private:
+    friend struct _C2BlockFactory;
+    std::shared_ptr<Impl> mImpl;
+    uint32_t mOffset; /**< offset into the linear block backing this read view */
+};
+
+/**
+ * Write view provides read/write access for a linear memory segment.
+ *
+ * This class is copiable. \todo movable only?
+ */
+class C2WriteView : public _C2EditableLinearRangeAspect {
+public:
+    /**
+     * Start of the block.
+     *
+     * \return pointer to the start of the block or nullptr on error.
+     *         This pointer is only valid during the lifetime of this view or until it is released.
+     */
+    uint8_t *base();
+
+    /**
+     * \return pointer to the block at the current offset or nullptr on error.
+     *         This pointer is only valid during the lifetime of this view or until it is released.
+     */
+    uint8_t *data();
+
+    /**
+     * \return error during the creation/mapping of this view.
+     */
+    c2_status_t error() const;
+
+    /**
+     * Releases this view. This sets error to C2_NO_INIT.
+     */
+    //void release();
+
+protected:
+    class Impl;
+    C2WriteView(std::shared_ptr<Impl> impl);
+    explicit C2WriteView(c2_status_t error);
+
+private:
+    friend struct _C2BlockFactory;
+    std::shared_ptr<Impl> mImpl;
+};
+
+/**
+ * A constant (read-only) linear block (portion of an allocation) with an acquire fence.
+ * Blocks are unmapped when created, and can be mapped into a read view on demand.
+ *
+ * This class is copiable and contains a reference to the allocation that it is based on.
+ */
+class C2ConstLinearBlock : public C2Block1D {
+public:
+    /**
+     * Maps this block into memory and returns a read view for it.
+     *
+     * \return a read view for this block.
+     */
+    C2Acquirable<C2ReadView> map() const;
+
+    /**
+     * Returns a portion of this block.
+     *
+     * \param offset  the start offset of the portion. \note This is clamped to the capacity of this
+     *              block.
+     * \param size    the size of the portion. \note This is clamped to the remaining data from offset.
+     *
+     * \return a constant linear block containing a portion of this block
+     */
+    C2ConstLinearBlock subBlock(size_t offset, size_t size) const;
+
+    /**
+     * Returns the acquire fence for this block.
+     *
+     * \return a fence that must be waited on before reading the block.
+     */
+    C2Fence fence() const { return mFence; }
+
+protected:
+    C2ConstLinearBlock(std::shared_ptr<Impl> impl, const _C2LinearRangeAspect &range, C2Fence mFence);
+
+private:
+    friend struct _C2BlockFactory;
+    C2Fence mFence;
+};
+
+/**
+ * Linear block is a writeable 1D block. Once written, it can be shared in whole or in parts with
+ * consumers/readers as read-only const linear block(s).
+ */
+class C2LinearBlock : public C2Block1D {
+public:
+    /**
+     * Maps this block into memory and returns a write view for it.
+     *
+     * \return a write view for this block.
+     */
+    C2Acquirable<C2WriteView> map();
+
+    /**
+     * Creates a read-only const linear block for a portion of this block; optionally protected
+     * by an acquire fence. There are two ways to use this:
+     *
+     * 1) share ready block after writing data into the block. In this case no fence shall be
+     *    supplied, and the block shall not be modified after calling this method.
+     * 2) share block metadata before actually (finishing) writing the data into the block. In
+     *    this case a fence must be supplied that will be triggered when the data is written.
+     *    The block shall be modified only until firing the event for the fence.
+     */
+    C2ConstLinearBlock share(size_t offset, size_t size, C2Fence fence);
+
+protected:
+    C2LinearBlock(std::shared_ptr<Impl> impl, const _C2LinearRangeAspect &range);
+
+    friend struct _C2BlockFactory;
+};
+
+/// @}
+
+/**************************************************************************************************
+  CIRCULAR BLOCKS AND VIEWS
+**************************************************************************************************/
+
+/// \defgroup circular Circular buffer support
+/// @{
+
+/**
+ * Circular blocks can be used to share data between a writer and a reader (and/or other consumers)-
+ * in a memory-efficient way by reusing a section of memory. Circular blocks are a bit more complex
+ * than single reader/single writer schemes to facilitate block-based consuming of data.
+ *
+ * They can operate in two modes:
+ *
+ * 1) one writer that creates blocks to be consumed (this model can be used by components)
+ *
+ * 2) one writer that writes continuously, and one reader that can creates blocks to be consumed
+ *    by further recipients (this model is used by the framework, and cannot be used by components.)
+ *
+ * Circular blocks have four segments with running pointers:
+ *  - reserved: data reserved and available for the writer
+ *  - committed: data committed by the writer and available to the reader (if present)
+ *  - used: data used by consumers (if present)
+ *  - available: unused data available to be reserved
+ */
+class C2CircularBlock : public C2Block1D {
+    // TODO: add methods
+
+private:
+    size_t mReserved __unused;   // end of reserved section
+    size_t mCommitted __unused;  // end of committed section
+    size_t mUsed __unused;       // end of used section
+    size_t mFree __unused;       // end of free section
+};
+
+class _C2CircularBlockSegment : public _C2LinearCapacityAspect {
+public:
+    /**
+     * Returns the available size for this segment.
+     *
+     * \return currently available size for this segment
+     */
+    size_t available() const;
+
+    /**
+     * Reserve some space for this segment from its current start.
+     *
+     * \param size    desired space in bytes
+     * \param fence   a pointer to an acquire fence. If non-null, the reservation is asynchronous and
+     *              a fence will be stored here that will be signaled when the reservation is
+     *              complete. If null, the reservation is synchronous.
+     *
+     * \retval C2_OK            the space was successfully reserved
+     * \retval C2_NO_MEMORY     the space requested cannot be reserved
+     * \retval C2_TIMED_OUT     the reservation timed out \todo when?
+     * \retval C2_CORRUPTED     some unknown error prevented reserving space. (unexpected)
+     */
+    c2_status_t reserve(size_t size, C2Fence *fence /* nullable */);
+
+    /**
+     * Abandons a portion of this segment. This will move to the beginning of this segment.
+     *
+     * \note This methods is only allowed if this segment is producing blocks.
+     *
+     * \param size    number of bytes to abandon
+     *
+     * \retval C2_OK            the data was successfully abandoned
+     * \retval C2_TIMED_OUT     the operation timed out (unexpected)
+     * \retval C2_CORRUPTED     some unknown error prevented abandoning the data (unexpected)
+     */
+    c2_status_t abandon(size_t size);
+
+    /**
+     * Share a portion as block(s) with consumers (these are moved to the used section).
+     *
+     * \note This methods is only allowed if this segment is producing blocks.
+     * \note Share does not move the beginning of the segment. (\todo add abandon/offset?)
+     *
+     * \param size    number of bytes to share
+     * \param fence   fence to be used for the section
+     * \param blocks  vector where the blocks of the section are appended to
+     *
+     * \retval C2_OK            the portion was successfully shared
+     * \retval C2_NO_MEMORY     not enough memory to share the portion
+     * \retval C2_TIMED_OUT     the operation timed out (unexpected)
+     * \retval C2_CORRUPTED     some unknown error prevented sharing the data (unexpected)
+     */
+    c2_status_t share(size_t size, C2Fence fence, std::vector<C2ConstLinearBlock> &blocks);
+
+    /**
+     * Returns the beginning offset of this segment from the start of this circular block.
+     *
+     * @return beginning offset
+     */
+    size_t begin();
+
+    /**
+     * Returns the end offset of this segment from the start of this circular block.
+     *
+     * @return end offset
+     */
+    size_t end();
+};
+
+/**
+ * A circular write-view is a dynamic mapped view for a segment of a circular block. Care must be
+ * taken when using this view so that only the section owned by the segment is modified.
+ */
+class C2CircularWriteView : public _C2LinearCapacityAspect {
+public:
+    /**
+     * Start of the circular block.
+     * \note the segment does not own this pointer.
+     *
+     * \return pointer to the start of the circular block or nullptr on error.
+     */
+    uint8_t *base();
+
+    /**
+     * \return error during the creation/mapping of this view.
+     */
+    c2_status_t error() const;
+};
+
+/**
+ * The writer of a circular buffer.
+ *
+ * Can commit data to a reader (not supported for components) OR share data blocks directly with a
+ * consumer.
+ *
+ * If a component supports outputting data into circular buffers, it must allocate a circular
+ * block and use a circular writer.
+ */
+class C2CircularWriter : public _C2CircularBlockSegment {
+public:
+    /**
+     * Commits a portion of this segment to the next segment. This moves the beginning of the
+     * segment.
+     *
+     * \param size    number of bytes to commit to the next segment
+     * \param fence   fence used for the commit (the fence must signal before the data is committed)
+     */
+    c2_status_t commit(size_t size, C2Fence fence);
+
+    /**
+     * Maps this block into memory and returns a write view for it.
+     *
+     * \return a write view for this block.
+     */
+    C2Acquirable<C2CircularWriteView> map();
+};
+
+/// @}
+
+/// \defgroup graphic Graphic Data Blocks
+/// @{
+
+/**
+ * C2Rect: rectangle type with non-negative coordinates.
+ *
+ * \note This struct has public fields without getters/setters. All methods are inline.
+ */
+struct C2Rect {
+// public:
+    uint32_t width;
+    uint32_t height;
+    uint32_t left;
+    uint32_t top;
+
+    constexpr inline C2Rect()
+        : C2Rect(0, 0, 0, 0) { }
+
+    constexpr inline C2Rect(uint32_t width_, uint32_t height_)
+        : C2Rect(width_, height_, 0, 0) { }
+
+    constexpr C2Rect inline at(uint32_t left_, uint32_t top_) const {
+        return C2Rect(width, height, left_, top_);
+    }
+
+    // utility methods
+
+    inline constexpr bool isEmpty() const {
+        return width == 0 || height == 0;
+    }
+
+    inline constexpr bool isValid() const {
+        return left <= ~width && top <= ~height;
+    }
+
+    inline constexpr operator bool() const {
+        return isValid() && !isEmpty();
+    }
+
+    inline constexpr bool operator!() const {
+        return !bool(*this);
+    }
+
+    C2_ALLOW_OVERFLOW
+    inline constexpr bool contains(const C2Rect &other) const {
+        if (!isValid() || !other.isValid()) {
+            return false;
+        } else {
+            return left <= other.left && top <= other.top
+                    && left + width >= other.left + other.width
+                    && top + height >= other.top + other.height;
+        }
+    }
+
+    inline constexpr bool operator==(const C2Rect &other) const {
+        if (!isValid()) {
+            return !other.isValid();
+        } else {
+            return left == other.left && top == other.top
+                    && width == other.width && height == other.height;
+        }
+    }
+
+    inline constexpr bool operator!=(const C2Rect &other) const {
+        return !operator==(other);
+    }
+
+    inline constexpr bool operator>=(const C2Rect &other) const {
+        return contains(other);
+    }
+
+    inline constexpr bool operator>(const C2Rect &other) const {
+        return contains(other) && !operator==(other);
+    }
+
+    inline constexpr bool operator<=(const C2Rect &other) const {
+        return other.contains(*this);
+    }
+
+    inline constexpr bool operator<(const C2Rect &other) const {
+        return other.contains(*this) && !operator==(other);
+    }
+
+    C2_ALLOW_OVERFLOW
+    inline constexpr uint32_t right() const {
+        return left + width;
+    }
+
+    C2_ALLOW_OVERFLOW
+    inline constexpr uint32_t bottom() const {
+        return top + height;
+    }
+
+    C2_ALLOW_OVERFLOW
+    inline constexpr C2Rect intersect(const C2Rect &other) const {
+        return C2Rect(c2_min(right(), other.right()) - c2_max(left, other.left),
+                      c2_min(bottom(), other.bottom()) - c2_max(top, other.top),
+                      c2_max(left, other.left),
+                      c2_max(top, other.top));
+    }
+
+    /** clamps right and bottom to top, left if they overflow */
+    inline constexpr C2Rect normalize() const {
+        return C2Rect(c2_max(left, right()) - left, c2_max(top, bottom()) - top, left, top);
+    }
+
+private:
+    /// note: potentially unusual argument order
+    constexpr inline C2Rect(uint32_t width_, uint32_t height_, uint32_t left_, uint32_t top_)
+        : width(width_),
+          height(height_),
+          left(left_),
+          top(top_) { }
+};
+
+/**
+ * Interface for objects that have a width and height (planar capacity).
+ */
+class _C2PlanarCapacityAspect {
+/// \name Planar capacity interface
+/// @{
+public:
+    inline constexpr uint32_t width() const { return _mWidth; }
+    inline constexpr uint32_t height() const { return _mHeight; }
+
+    inline constexpr operator C2Rect() const {
+        return C2Rect(_mWidth, _mHeight);
+    }
+
+protected:
+    inline constexpr _C2PlanarCapacityAspect(uint32_t width, uint32_t height)
+      : _mWidth(width), _mHeight(height) { }
+
+    inline explicit constexpr _C2PlanarCapacityAspect(const _C2PlanarCapacityAspect *parent)
+        : _mWidth(parent == nullptr ? 0 : parent->width()),
+          _mHeight(parent == nullptr ? 0 : parent->height()) { }
+
+private:
+    uint32_t _mWidth;
+    uint32_t _mHeight;
+/// @}
+};
+
+/**
+ * C2PlaneInfo: information on the layout of a singe flexible plane.
+ *
+ * Public fields without getters/setters.
+ */
+struct C2PlaneInfo {
+//public:
+    enum channel_t : uint32_t {
+        CHANNEL_Y,  ///< luma
+        CHANNEL_R,  ///< red
+        CHANNEL_G,  ///< green
+        CHANNEL_B,  ///< blue
+        CHANNEL_A,  ///< alpha
+        CHANNEL_CR, ///< Cr
+        CHANNEL_CB, ///< Cb
+    } channel;
+
+    int32_t colInc;       ///< column increment in bytes. may be negative
+    int32_t rowInc;       ///< row increment in bytes. may be negative
+
+    uint32_t colSampling; ///< subsampling compared to width (must be a power of 2)
+    uint32_t rowSampling; ///< subsampling compared to height (must be a power of 2)
+
+    uint32_t allocatedDepth; ///< size of each sample (must be a multiple of 8)
+    uint32_t bitDepth;       ///< significant bits per sample
+    /**
+     * the right shift of the significant bits in the sample. E.g. if a 10-bit significant
+     * value is laid out in a 16-bit allocation aligned to LSB (values 0-1023), rightShift
+     * would be 0 as the 16-bit value read from the sample does not need to be right shifted
+     * and can be used as is (after applying a 10-bit mask of 0x3FF).
+     *
+     * +--------+--------+
+     * |      VV|VVVVVVVV|
+     * +--------+--------+
+     *  15     8 7      0
+     *
+     * If the value is laid out aligned to MSB, rightShift would be 6, as the value read
+     * from the allocated sample must be right-shifted by 6 to get the actual sample value.
+     *
+     * +--------+--------+
+     * |VVVVVVVV|VV      |
+     * +--------+--------+
+     *  15     8 7      0
+     */
+    uint32_t rightShift;
+
+    enum endianness_t : uint32_t {
+        NATIVE,
+        LITTLE_END, // LITTLE_ENDIAN is reserved macro
+        BIG_END,    // BIG_ENDIAN is a reserved macro
+    } endianness; ///< endianness of the samples
+
+    /**
+     * The following two fields define the relation between multiple planes. If multiple planes are
+     * interleaved, they share a root plane (whichever plane's start address is the lowest), and
+     * |offset| is the offset of this plane inside the root plane (in bytes). |rootIx| is the index
+     * of the root plane. If a plane is independent, rootIx is its index and offset is 0.
+     */
+    uint32_t rootIx; ///< index of the root plane
+    uint32_t offset; ///< offset of this plane inside of the root plane
+
+    inline constexpr ssize_t minOffset(uint32_t width, uint32_t height) const {
+        ssize_t offs = 0;
+        if (width > 0 && colInc < 0) {
+            offs += colInc * (ssize_t)(width - 1);
+        }
+        if (height > 0 && rowInc < 0) {
+            offs += rowInc * (ssize_t)(height - 1);
+        }
+        return offs;
+    }
+
+    inline constexpr ssize_t maxOffset(uint32_t width, uint32_t height) const {
+        ssize_t offs = (allocatedDepth + 7) >> 3;
+        if (width > 0 && colInc > 0) {
+            offs += colInc * (ssize_t)(width - 1);
+        }
+        if (height > 0 && rowInc > 0) {
+            offs += rowInc * (ssize_t)(height - 1);
+        }
+        return offs;
+    }
+} C2_PACK;
+
+struct C2PlanarLayout {
+//public:
+    enum type_t : uint32_t {
+        TYPE_UNKNOWN = 0,
+        TYPE_YUV = 0x100,   ///< YUV image with 3 planes
+        TYPE_YUVA,          ///< YUVA image with 4 planes
+        TYPE_RGB,           ///< RGB image with 3 planes
+        TYPE_RGBA,          ///< RBGA image with 4 planes
+    };
+
+    type_t type;                    // image type
+    uint32_t numPlanes;             // number of component planes
+    uint32_t rootPlanes;            // number of layout planes (root planes)
+
+    enum plane_index_t : uint32_t {
+        PLANE_Y = 0,
+        PLANE_U = 1,
+        PLANE_V = 2,
+        PLANE_R = 0,
+        PLANE_G = 1,
+        PLANE_B = 2,
+        PLANE_A = 3,
+        MAX_NUM_PLANES = 4,
+    };
+
+    C2PlaneInfo planes[MAX_NUM_PLANES];
+};
+
+/**
+ * Aspect for objects that have a planar section (crop rectangle).
+ *
+ * This class is copiable.
+ */
+class _C2PlanarSectionAspect : public _C2PlanarCapacityAspect {
+/// \name Planar section interface
+/// @{
+private:
+    inline constexpr _C2PlanarSectionAspect(uint32_t width, uint32_t height, const C2Rect &crop)
+        : _C2PlanarCapacityAspect(width, height),
+          mCrop(C2Rect(std::min(width - std::min(crop.left, width), crop.width),
+                       std::min(height - std::min(crop.top, height), crop.height)).at(
+                               std::min(crop.left, width),
+                               std::min(crop.height, height))) {
+    }
+
+public:
+    // crop can be an empty rect, does not have to line up with subsampling
+    // NOTE: we do not support floating-point crop
+    inline constexpr C2Rect crop() const { return mCrop; }
+
+    /**
+     * Returns a child planar section for |crop|, where the capacity represents this section.
+     */
+    inline constexpr _C2PlanarSectionAspect childSection(const C2Rect &crop) const {
+        return _C2PlanarSectionAspect(
+                mCrop.width, mCrop.height,
+                // crop and translate |crop| rect
+                C2Rect(c2_min(mCrop.right() - c2_clamp(mCrop.left, crop.left, mCrop.right()),
+                              crop.width),
+                       c2_min(mCrop.bottom() - c2_clamp(mCrop.top, crop.top, mCrop.bottom()),
+                              crop.height))
+                .at(c2_clamp(mCrop.left, crop.left, mCrop.right()) - mCrop.left,
+                    c2_clamp(mCrop.top, crop.top, mCrop.bottom()) - mCrop.top));
+    }
+
+protected:
+    inline constexpr _C2PlanarSectionAspect(const _C2PlanarCapacityAspect *parent)
+        : _C2PlanarCapacityAspect(parent), mCrop(width(), height()) {}
+
+    inline constexpr _C2PlanarSectionAspect(const _C2PlanarCapacityAspect *parent, const C2Rect &crop)
+        : _C2PlanarCapacityAspect(parent),
+          mCrop(parent == nullptr ? C2Rect() : ((C2Rect)*parent).intersect(crop).normalize()) { }
+
+    inline constexpr _C2PlanarSectionAspect(const _C2PlanarSectionAspect *parent, const C2Rect &crop)
+        : _C2PlanarCapacityAspect(parent),
+          mCrop(parent == nullptr ? C2Rect() : parent->crop().intersect(crop).normalize()) { }
+
+private:
+    friend class _C2EditablePlanarSectionAspect;
+    C2Rect mCrop;
+/// @}
+};
+
+/**
+ * Aspect for objects that have an editable planar section (crop rectangle).
+ *
+ * This class is copiable.
+ */
+class _C2EditablePlanarSectionAspect : public _C2PlanarSectionAspect {
+/// \name Planar section interface
+/// @{
+    using _C2PlanarSectionAspect::_C2PlanarSectionAspect;
+
+public:
+    // crop can be an empty rect, does not have to line up with subsampling
+    // NOTE: we do not support floating-point crop
+    inline constexpr C2Rect crop() const { return mCrop; }
+
+    /**
+     *  Sets crop to crop intersected with [(0,0) .. (width, height)]
+     */
+    inline void setCrop_be(const C2Rect &crop) {
+        mCrop.left = std::min(width(), crop.left);
+        mCrop.top = std::min(height(), crop.top);
+        // It's guaranteed that mCrop.left <= width() && mCrop.top <= height()
+        mCrop.width = std::min(width() - mCrop.left, crop.width);
+        mCrop.height = std::min(height() - mCrop.top, crop.height);
+    }
+
+    /**
+     * If crop is within the dimensions of this object, it sets crop to it.
+     *
+     * \return true iff crop is within the dimensions of this object
+     */
+    inline bool setCrop(const C2Rect &crop) {
+        if (width() < crop.width || height() < crop.height
+                || width() - crop.width < crop.left || height() - crop.height < crop.top) {
+            return false;
+        }
+        mCrop = crop;
+        return true;
+    }
+/// @}
+};
+
+/**
+ * Utility class for safe range calculations using size_t-s.
+ */
+class C2PlanarSection : public _C2PlanarSectionAspect {
+public:
+    inline constexpr C2PlanarSection(const _C2PlanarCapacityAspect &parent, const C2Rect &crop)
+        : _C2PlanarSectionAspect(&parent, crop) { }
+
+    inline constexpr C2PlanarSection(const _C2PlanarSectionAspect &parent, const C2Rect &crop)
+        : _C2PlanarSectionAspect(&parent, crop) { }
+
+    inline constexpr C2PlanarSection intersect(const C2Rect &crop) const {
+        return C2PlanarSection(*this, crop);
+    }
+};
+
+/**
+ * Utility class for simple and safe planar capacity and section construction.
+ */
+class C2PlanarCapacity : public _C2PlanarCapacityAspect {
+public:
+    inline constexpr explicit C2PlanarCapacity(size_t width, size_t height)
+        : _C2PlanarCapacityAspect(c2_min(width, std::numeric_limits<uint32_t>::max()),
+                                  c2_min(height, std::numeric_limits<uint32_t>::max())) { }
+
+    inline constexpr C2PlanarSection section(const C2Rect &crop) const {
+        return C2PlanarSection(*this, crop);
+    }
+};
+
+
+/**
+ * \ingroup graphic allocator
+ * 2D allocation interface.
+ */
+class C2GraphicAllocation : public _C2PlanarCapacityAspect {
+public:
+    /**
+     * Maps a rectangular section (as defined by |rect|) of a 2D allocation into local process
+     * memory for flexible access. On success, it fills out |layout| with the plane specifications
+     * and fills the |addr| array with pointers to the first byte of the top-left pixel of each
+     * plane used. Otherwise, it leaves |layout| and |addr| untouched. |fence| will contain
+     * an acquire sync fence object. If it is already safe to access the
+     * buffer contents, then it will be an empty (already fired) fence.
+     *
+     * Safe regions for the pointer addresses returned can be gotten via C2LayoutInfo.minOffset()/
+     * maxOffset().
+     *
+     * \param rect          section to be mapped (this does not have to be aligned)
+     * \param usage         the desired usage. \todo this must be kSoftwareRead and/or
+     *                      kSoftwareWrite.
+     * \param fence         a pointer to a fence object if an async mapping is requested. If
+     *                      not-null, and acquire fence will be stored here on success, or empty
+     *                      fence on failure. If null, the mapping will be synchronous.
+     * \param layout        a pointer to where the mapped planes' descriptors will be
+     *                      stored. On failure, nullptr will be stored here.
+     * \param addr          pointer to an array with at least C2PlanarLayout::MAX_NUM_PLANES
+     *                      elements. Only layout.numPlanes elements will be modified on success.
+     *
+     * \retval C2_OK        the operation was successful
+     * \retval C2_REFUSED   no permission to map the section
+     * \retval C2_DUPLICATE there is already a mapped region and this allocation cannot support
+     *                      multi-mapping (caller error)
+     * \retval C2_TIMED_OUT the operation timed out
+     * \retval C2_NO_MEMORY not enough memory to complete the operation
+     * \retval C2_BAD_VALUE the parameters (rect) are invalid or outside the allocation, or the
+     *                      usage flags are invalid (caller error)
+     * \retval C2_CORRUPTED some unknown error prevented the operation from completing (unexpected)
+
+     */
+    virtual c2_status_t map(
+            C2Rect rect, C2MemoryUsage usage, C2Fence *fence,
+            C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) = 0;
+
+    /**
+     * Unmaps a section of an allocation at |addr| with |rect|. These must be parameters previously
+     * passed to and returned by |map|; otherwise, this operation is a no-op.
+     *
+     * \param addr          pointer to an array with at least C2PlanarLayout::MAX_NUM_PLANES
+     *                      elements containing the starting addresses of the mapped layers
+     * \param rect          boundaries of the mapped section
+     * \param fence         a pointer to a fence object if an async unmapping is requested. If
+     *                      not-null, a release fence will be stored here on success, or empty fence
+     *                      on failure. This fence signals when the original allocation contains
+     *                      all changes that happened to the mapped section. If null, the unmapping
+     *                      will be synchronous.
+     *
+     * \retval C2_OK        the operation was successful
+     * \retval C2_TIMED_OUT the operation timed out
+     * \retval C2_NOT_FOUND there is no such mapped region (caller error)
+     * \retval C2_CORRUPTED some unknown error prevented the operation from completing (unexpected)
+     * \retval C2_REFUSED   no permission to unmap the section (unexpected - system)
+     */
+    virtual c2_status_t unmap(
+            uint8_t **addr /* nonnull */, C2Rect rect, C2Fence *fence /* nullable */) = 0;
+
+    /**
+     * Returns the allocator ID for this allocation. This is useful to put the handle into context.
+     */
+    virtual C2Allocator::id_t getAllocatorId() const = 0;
+
+    /**
+     * Returns a pointer to the allocation handle.
+     */
+    virtual const C2Handle *handle() const = 0;
+
+    /**
+     * Returns true if this is the same allocation as |other|.
+     */
+    virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const = 0;
+
+protected:
+    using _C2PlanarCapacityAspect::_C2PlanarCapacityAspect;
+    virtual ~C2GraphicAllocation() = default;
+};
+
+class C2GraphicAllocation;
+
+/**
+ * A 2D block.
+ *
+ * \note width()/height() is not meaningful for users of blocks; instead, crop().width() and
+ * crop().height() is the capacity of the usable portion. Use and crop() if accessing the block
+ * directly through its handle to represent the allotted region of the underlying allocation to this
+ * block.
+ */
+class C2Block2D : public _C2PlanarSectionAspect {
+public:
+    /**
+     * Returns the underlying handle for this allocation.
+     *
+     * \note that the block and its block pool has shared ownership of the handle
+     *       and if all references to the block are released, the underlying block
+     *       allocation may get reused even if a client keeps a clone of this handle.
+     */
+    const C2Handle *handle() const;
+
+    /**
+     * Returns the allocator's ID that created the underlying allocation for this block. This
+     * provides the context for understanding the handle.
+     */
+    C2Allocator::id_t getAllocatorId() const;
+
+protected:
+    class Impl;
+    C2Block2D(std::shared_ptr<Impl> impl, const _C2PlanarSectionAspect &section);
+
+    friend struct _C2BlockFactory;
+    std::shared_ptr<Impl> mImpl;
+};
+
+/**
+ * Graphic view provides read or read-write access for a graphic block.
+ *
+ * This class is copiable.
+ *
+ * \note Due to the subsampling of graphic buffers, a read view must still contain a crop rectangle
+ * to ensure subsampling is followed. This results in nearly identical interface between read and
+ * write views, so C2GraphicView can encompass both of them.
+ */
+class C2GraphicView : public _C2EditablePlanarSectionAspect {
+public:
+    /**
+     * \return array of pointers (of layout().numPlanes elements) to the start of the planes or
+     * nullptr on error. Regardless of crop rect, they always point to the top-left corner of each
+     * plane. Access outside of the crop rect results in an undefined behavior.
+     */
+    const uint8_t *const *data() const;
+
+    /**
+     * \return array of pointers (of layout().numPlanes elements) to the start of the planes or
+     * nullptr on error. Regardless of crop rect, they always point to the top-left corner of each
+     * plane. Access outside of the crop rect results in an undefined behavior.
+     */
+    uint8_t *const *data();
+
+    /**
+     * \return layout of the graphic block to interpret the returned data.
+     */
+    const C2PlanarLayout layout() const;
+
+    /**
+     * Returns a section of this view.
+     *
+     * \param rect    the dimension of the section. \note This is clamped to the crop of this view.
+     *
+     * \return a read view containing the requested section of this view
+     */
+    const C2GraphicView subView(const C2Rect &rect) const;
+    C2GraphicView subView(const C2Rect &rect);
+
+    /**
+     * \return error during the creation/mapping of this view.
+     */
+    c2_status_t error() const;
+
+protected:
+    class Impl;
+    C2GraphicView(std::shared_ptr<Impl> impl, const _C2PlanarSectionAspect &section);
+    explicit C2GraphicView(c2_status_t error);
+
+private:
+    friend struct _C2BlockFactory;
+    std::shared_ptr<Impl> mImpl;
+};
+
+/**
+ * A constant (read-only) graphic block (portion of an allocation) with an acquire fence.
+ * Blocks are unmapped when created, and can be mapped into a read view on demand.
+ *
+ * This class is copiable and contains a reference to the allocation that it is based on.
+ */
+class C2ConstGraphicBlock : public C2Block2D {
+public:
+    /**
+     * Maps this block into memory and returns a read view for it.
+     *
+     * \return a read view for this block.
+     */
+    C2Acquirable<const C2GraphicView> map() const;
+
+    /**
+     * Returns a section of this block.
+     *
+     * \param rect    the coordinates of the section. \note This is clamped to the crop rectangle of
+     *              this block.
+     *
+     * \return a constant graphic block containing a portion of this block
+     */
+    C2ConstGraphicBlock subBlock(const C2Rect &rect) const;
+
+    /**
+     * Returns the acquire fence for this block.
+     *
+     * \return a fence that must be waited on before reading the block.
+     */
+    C2Fence fence() const { return mFence; }
+
+protected:
+    C2ConstGraphicBlock(
+            std::shared_ptr<Impl> impl, const _C2PlanarSectionAspect &section, C2Fence fence);
+
+private:
+    friend struct _C2BlockFactory;
+    C2Fence mFence;
+};
+
+/**
+ * Graphic block is a writeable 2D block. Once written, it can be shared in whole or in part with
+ * consumers/readers as read-only const graphic block.
+ */
+class C2GraphicBlock : public C2Block2D {
+public:
+    /**
+     * Maps this block into memory and returns a write view for it.
+     *
+     * \return a write view for this block.
+     */
+    C2Acquirable<C2GraphicView> map();
+
+    /**
+     * Creates a read-only const linear block for a portion of this block; optionally protected
+     * by an acquire fence. There are two ways to use this:
+     *
+     * 1) share ready block after writing data into the block. In this case no fence shall be
+     *    supplied, and the block shall not be modified after calling this method.
+     * 2) share block metadata before actually (finishing) writing the data into the block. In
+     *    this case a fence must be supplied that will be triggered when the data is written.
+     *    The block shall be modified only until firing the event for the fence.
+     */
+    C2ConstGraphicBlock share(const C2Rect &crop, C2Fence fence);
+
+protected:
+    C2GraphicBlock(std::shared_ptr<Impl> impl, const _C2PlanarSectionAspect &section);
+
+    friend struct _C2BlockFactory;
+};
+
+/// @}
+
+/// \defgroup buffer_onj Buffer objects
+/// @{
+
+// ================================================================================================
+//  BUFFERS
+// ================================================================================================
+
+/// \todo: Do we still need this?
+///
+// There are 2 kinds of buffers: linear or graphic. Linear buffers can contain a single block, or
+// a list of blocks (LINEAR_CHUNKS). Support for list of blocks is optional, and can allow consuming
+// data from circular buffers or scattered data sources without extra memcpy. Currently, list of
+// graphic blocks is not supported.
+
+class C2LinearBuffer;   // read-write buffer
+class C2GraphicBuffer;  // read-write buffer
+class C2LinearChunksBuffer;
+
+/**
+ * C2BufferData: the main, non-meta data of a buffer. A buffer can contain either linear blocks
+ * or graphic blocks, and can contain either a single block or multiple blocks. This is determined
+ * by its type.
+ */
+class C2BufferData {
+public:
+    /**
+     *  The type of buffer data.
+     */
+    enum type_t : uint32_t {
+        INVALID,            ///< invalid buffer type. Do not use.
+        LINEAR,             ///< the buffer contains a single linear block
+        LINEAR_CHUNKS,      ///< the buffer contains one or more linear blocks
+        GRAPHIC,            ///< the buffer contains a single graphic block
+        GRAPHIC_CHUNKS,     ///< the buffer contains one of more graphic blocks
+    };
+
+    /**
+     * Gets the type of this buffer (data).
+     * \return the type of this buffer data.
+     */
+    type_t type() const;
+
+    /**
+     * Gets the linear blocks of this buffer.
+     * \return a constant list of const linear blocks of this buffer.
+     * \retval empty list if this buffer does not contain linear block(s).
+     */
+    const std::vector<C2ConstLinearBlock> linearBlocks() const;
+
+    /**
+     * Gets the graphic blocks of this buffer.
+     * \return a constant list of const graphic blocks of this buffer.
+     * \retval empty list if this buffer does not contain graphic block(s).
+     */
+    const std::vector<C2ConstGraphicBlock> graphicBlocks() const;
+
+private:
+    class Impl;
+    std::shared_ptr<Impl> mImpl;
+
+protected:
+    // no public constructor
+    explicit C2BufferData(const std::vector<C2ConstLinearBlock> &blocks);
+    explicit C2BufferData(const std::vector<C2ConstGraphicBlock> &blocks);
+};
+
+/**
+ * C2Buffer: buffer base class. These are always used as shared_ptrs. Though the underlying buffer
+ * objects (native buffers, ion buffers, or dmabufs) are reference-counted by the system,
+ * C2Buffers hold only a single reference.
+ *
+ * These objects cannot be used on the stack.
+ */
+class C2Buffer {
+public:
+    /**
+     * Gets the buffer's data.
+     *
+     * \return the buffer's data.
+     */
+    const C2BufferData data() const;
+
+    ///@name Pre-destroy notification handling
+    ///@{
+
+    /**
+     * Register for notification just prior to the destruction of this object.
+     */
+    typedef void (*OnDestroyNotify) (const C2Buffer *buf, void *arg);
+
+    /**
+     * Registers for a pre-destroy notification. This is called just prior to the destruction of
+     * this buffer (when this buffer is no longer valid.)
+     *
+     * \param onDestroyNotify   the notification callback
+     * \param arg               an arbitrary parameter passed to the callback
+     *
+     * \retval C2_OK        the registration was successful.
+     * \retval C2_DUPLICATE a notification was already registered for this callback and argument
+     * \retval C2_NO_MEMORY not enough memory to register for this callback
+     * \retval C2_CORRUPTED an unknown error prevented the registration (unexpected)
+     */
+    c2_status_t registerOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg = nullptr);
+
+    /**
+     * Unregisters a previously registered pre-destroy notification.
+     *
+     * \param onDestroyNotify   the notification callback
+     * \param arg               an arbitrary parameter passed to the callback
+     *
+     * \retval C2_OK        the unregistration was successful.
+     * \retval C2_NOT_FOUND the notification was not found
+     * \retval C2_CORRUPTED an unknown error prevented the registration (unexpected)
+     */
+    c2_status_t unregisterOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg = nullptr);
+
+    ///@}
+
+    virtual ~C2Buffer() = default;
+
+    ///@name Buffer-specific arbitrary metadata handling
+    ///@{
+
+    /**
+     * Gets the list of metadata associated with this buffer.
+     *
+     * \return a constant list of info objects associated with this buffer.
+     */
+    const std::vector<std::shared_ptr<const C2Info>> info() const;
+
+    /**
+     * Attaches (or updates) an (existing) metadata for this buffer.
+     * If the metadata is stream specific, the stream information will be reset.
+     *
+     * \param info Metadata to update
+     *
+     * \retval C2_OK        the metadata was successfully attached/updated.
+     * \retval C2_NO_MEMORY not enough memory to attach the metadata (this return value is not
+     *                      used if the same kind of metadata is already attached to the buffer).
+     */
+    c2_status_t setInfo(const std::shared_ptr<C2Info> &info);
+
+    /**
+     * Checks if there is a certain type of metadata attached to this buffer.
+     *
+     * \param index the parameter type of the metadata
+     *
+     * \return true iff there is a metadata with the parameter type attached to this buffer.
+     */
+    bool hasInfo(C2Param::Type index) const;
+
+    /**
+     * Checks if there is a certain type of metadata attached to this buffer, and returns a
+     * shared pointer to it if there is. Returns an empty shared pointer object (nullptr) if there
+     * is not.
+     *
+     * \param index the parameter type of the metadata
+     *
+     * \return shared pointer to the metadata.
+     */
+    std::shared_ptr<const C2Info> getInfo(C2Param::Type index) const;
+
+    /**
+     * Removes a metadata from the buffer.
+     */
+    std::shared_ptr<C2Info> removeInfo(C2Param::Type index);
+    ///@}
+
+    /**
+     * Creates a buffer containing a single linear block.
+     *
+     * \param block the content of the buffer.
+     *
+     * \return shared pointer to the created buffer.
+     */
+    static std::shared_ptr<C2Buffer> CreateLinearBuffer(const C2ConstLinearBlock &block);
+
+    /**
+     * Creates a buffer containing a single graphic block.
+     *
+     * \param block the content of the buffer.
+     *
+     * \return shared pointer to the created buffer.
+     */
+    static std::shared_ptr<C2Buffer> CreateGraphicBuffer(const C2ConstGraphicBlock &block);
+
+protected:
+    // no public constructor
+    explicit C2Buffer(const std::vector<C2ConstLinearBlock> &blocks);
+    explicit C2Buffer(const std::vector<C2ConstGraphicBlock> &blocks);
+
+private:
+    class Impl;
+    std::shared_ptr<Impl> mImpl;
+};
+
+/**
+ * An extension of C2Info objects that can contain arbitrary buffer data.
+ *
+ * \note This object is not describable and contains opaque data.
+ */
+class C2InfoBuffer {
+public:
+    /**
+     * Gets the index of this info object.
+     *
+     * \return the parameter index.
+     */
+    const C2Param::Index index() const;
+
+    /**
+     * Gets the buffer's data.
+     *
+     * \return the buffer's data.
+     */
+    const C2BufferData data() const;
+};
+
+/// @}
+
+/// @}
+
+#endif  // C2BUFFER_H_
diff --git a/media/codec2/core/include/C2BufferBase.h b/media/codec2/core/include/C2BufferBase.h
new file mode 100644
index 0000000..2bd48f0
--- /dev/null
+++ b/media/codec2/core/include/C2BufferBase.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef C2BUFFER_BASE_H_
+#define C2BUFFER_BASE_H_
+
+/// \defgroup allocator Allocation and memory placement
+/// @{
+
+/**
+ * Buffer/memory usage bits. These shall be used by the allocators to select optimal memory type/
+ * pool and buffer layout. Usage bits are conceptually separated into read and write usage, while
+ * the buffer use life-cycle is separated into producers (writers) and consumers (readers).
+ * These two concepts are related but not equivalent: consumers may only read buffers and only
+ * producers may write to buffers; note, however, that buffer producers may also want or need to
+ * read the buffers.
+ *
+ * Read and write buffer usage bits shall be or-ed to arrive at the full buffer usage. Admittedly,
+ * this does not account for the amount of reading and writing (e.g. a buffer may have one or more
+ * readers); however, the proper information necessary to properly weigh the various usages would be
+ * the amount of data read/written for each usage type. This would result in an integer array of
+ * size 64 (or the number of distinct usages) for memory usage, and likely such detailed information
+ * would not always be available.
+ *
+ * That platform-agnostic Codec 2.0 API only defines the bare minimum usages. Platforms shall define
+ * usage bits that are appropriate for the platform.
+ */
+struct C2MemoryUsage {
+// public:
+    /**
+     * Buffer read usage.
+     */
+    enum read_t : uint64_t {
+        /** Buffer is read by the CPU. */
+        CPU_READ        = 1 << 0,
+        /**
+         * Buffer shall only be read by trusted hardware. The definition of trusted hardware is
+         * platform specific, but this flag is reserved to prevent mapping this block into CPU
+         * readable memory resulting in bus fault. This flag can be used when buffer access must be
+         * protected.
+         */
+        READ_PROTECTED  = 1 << 1,
+    };
+
+    /**
+     * Buffer write usage.
+     */
+    enum write_t : uint64_t {
+        /** Buffer is writted to by the CPU. */
+        CPU_WRITE        = 1 << 2,
+        /**
+         * Buffer shall only be written to by trusted hardware. The definition of trusted hardware
+         * is platform specific, but this flag is reserved to prevent mapping this block into CPU
+         * writable memory resulting in bus fault. This flag can be used when buffer integrity must
+         * be protected.
+         */
+        WRITE_PROTECTED  = 1 << 3,
+    };
+
+    enum : uint64_t {
+        /**
+         * Buffer usage bits reserved for the platform. We don't separately reserve read and
+         * write usages as platforms may have asymmetric distribution between them.
+         */
+        PLATFORM_MASK     = ~(CPU_READ | CPU_WRITE | READ_PROTECTED | WRITE_PROTECTED),
+    };
+
+    /** Create a usage from separate consumer and producer usage mask. \deprecated */
+    inline C2MemoryUsage(uint64_t consumer, uint64_t producer)
+        : expected(consumer | producer) { }
+
+    inline explicit C2MemoryUsage(uint64_t expected_)
+        : expected(expected_) { }
+
+    uint64_t expected; // expected buffer usage
+};
+
+/// @}
+
+#endif  // C2BUFFER_BASE_H_
+
diff --git a/media/codec2/core/include/C2Component.h b/media/codec2/core/include/C2Component.h
new file mode 100644
index 0000000..ecf8d2e
--- /dev/null
+++ b/media/codec2/core/include/C2Component.h
@@ -0,0 +1,976 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef C2COMPONENT_H_
+
+#define C2COMPONENT_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <list>
+#include <memory>
+#include <vector>
+#include <functional>
+
+#include <C2Enum.h>
+#include <C2Param.h>
+#include <C2Work.h>
+
+/// \defgroup components Components
+/// @{
+
+struct C2FieldSupportedValuesQuery {
+    enum type_t : uint32_t {
+        POSSIBLE, ///< query all possible values regardless of other settings
+        CURRENT,  ///< query currently possible values given dependent settings
+    };
+
+private:
+    C2ParamField _mField;
+    type_t _mType;
+public:
+    c2_status_t status;
+    C2FieldSupportedValues values;
+
+    C2FieldSupportedValuesQuery(const C2ParamField &field_, type_t type_)
+        : _mField(field_), _mType(type_), status(C2_NO_INIT) { }
+
+    static C2FieldSupportedValuesQuery
+    Current(const C2ParamField &field_) {
+        return C2FieldSupportedValuesQuery(field_, CURRENT);
+    }
+
+    static C2FieldSupportedValuesQuery
+    Possible(const C2ParamField &field_) {
+        return C2FieldSupportedValuesQuery(field_, POSSIBLE);
+    }
+
+    inline C2ParamField field() const { return _mField; };
+
+    inline type_t type() const { return _mType; }
+};
+
+/**
+ * Component interface object. This object contains all of the configuration of a potential or
+ * actual component. It can be created and used independently of an actual C2Component instance to
+ * query support and parameters for various component settings and configurations for a potential
+ * component. Actual components also expose this interface.
+ */
+
+class C2ComponentInterface {
+public:
+    // ALWAYS AVAILABLE METHODS
+    // =============================================================================================
+
+    /**
+     * Returns the name of this component or component interface object.
+     * This is a unique name for this component or component interface 'class'; however, multiple
+     * instances of this component SHALL have the same name.
+     *
+     * When attached to a component, this method MUST be supported in any component state.
+     * This call does not change the state nor the internal configuration of the component.
+     *
+     * This method MUST be "non-blocking" and return within 1ms.
+     *
+     * \return the name of this component or component interface object.
+     * \retval an empty string if there was not enough memory to allocate the actual name.
+     */
+    virtual C2String getName() const = 0;
+
+    /**
+     * Returns a unique ID for this component or interface object.
+     * This ID is used as work targets, unique work IDs, and when configuring tunneling.
+     *
+     * When attached to a component, this method MUST be supported in any component state.
+     * This call does not change the state nor the internal configuration of the component.
+     *
+     * This method MUST be "non-blocking" and return within 1ms.
+     *
+     * \return a unique node ID for this component or component interface instance.
+     */
+    virtual c2_node_id_t getId() const = 0;
+
+    /**
+     * Queries a set of parameters from the component or interface object.
+     * Querying is performed at best effort: the component SHALL query all supported parameters and
+     * skip unsupported ones, heap allocated parameters that could not be allocated or parameters
+     * that could not be queried without blocking. Any errors are communicated in the return value.
+     * Additionally, preallocated (e.g. stack) parameters that could not be queried are invalidated.
+     * Invalid or blocking parameters to be allocated on the heap are omitted from the result.
+     *
+     * \note Parameter values do not depend on the order of query.
+     *
+     * \todo This method cannot be used to query info-buffers. Is that a problem?
+     *
+     * When attached to a component, this method MUST be supported in any component state except
+     * released.
+     * This call does not change the state nor the internal configuration of the component.
+     *
+     * This method has a variable blocking behavior based on state.
+     * In the stopped state this method MUST be "non-blocking" and return within 1ms.
+     * In the running states this method may be momentarily blocking, but MUST return within 5ms.
+     *
+     * \param[in,out] stackParams  a list of params queried. These are initialized specific to each
+     *                             setting; e.g. size and index are set and rest of the members are
+     *                             cleared.
+     *                             \note Flexible settings that are of incorrect size will be
+     *                             invalidated.
+     * \param[in] heapParamIndices a vector of param indices for params to be queried and returned
+     *                             on the heap. These parameters will be returned in heapParams.
+     *                             Unsupported param indices will be ignored.
+     * \param[in] mayBlock         if true (C2_MAY_BLOCK), implementation may momentarily block.
+     *                             Otherwise (C2_DONT_BLOCK), it must be "non-blocking".
+     * \param[out] heapParams      a list of params where to which the supported heap parameters
+     *                             will be appended in the order they appear in heapParamIndices.
+     *
+     * \retval C2_OK        all parameters could be queried
+     * \retval C2_BAD_INDEX all supported parameters could be queried, but some parameters were not
+     *                      supported
+     * \retval C2_BAD_STATE when called in the released component state (user error)
+     *                      (this error code is only allowed for interfaces connected to components)
+     * \retval C2_NO_MEMORY could not allocate memory for a supported parameter
+     * \retval C2_BLOCKING  the operation must block to complete but mayBlock is false
+     *                      (this error code is only allowed for interfaces connected to components)
+     * \retval C2_TIMED_OUT could not query the parameters within the time limit (unexpected)
+     *                      (this error code is only allowed for interfaces connected to components
+     *                      in the running state)
+     * \retval C2_CORRUPTED some unknown error prevented the querying of the parameters
+     *                      (unexpected)
+     *                      (this error code is only allowed for interfaces connected to components)
+     */
+    virtual c2_status_t query_vb(
+        const std::vector<C2Param*> &stackParams,
+        const std::vector<C2Param::Index> &heapParamIndices,
+        c2_blocking_t mayBlock,
+        std::vector<std::unique_ptr<C2Param>>* const heapParams) const = 0;
+
+    /**
+     * Sets a set of parameters for the component or interface object.
+     *
+     * Tuning is performed at best effort: the component SHALL process the configuration updates in
+     * the order they appear in |params|. If any parameter update fails, the component shall
+     * communicate the failure in the return value and in |failures|, and still process the
+     * remaining parameters. Unsupported parameters are skipped, though they are communicated in
+     * ther return value. Most parameters are updated at best effort - such that even if client
+     * specifies an unsupported value for a field, the closest supported value is used. On the
+     * other hand, strict parameters only accept specific values for their fields, and if the client
+     * specifies an unsupported value, the parameter setting shall fail for that field.
+     * If the client tries to change the value of a field that requires momentary blocking without
+     * setting |mayBlock| to C2_MAY_BLOCK, that parameter shall also be skipped and a specific
+     * return value shall be used. Final values for all parameters set are propagated back to the
+     * caller in |params|.
+     *
+     * \note Parameter tuning DOES depend on the order of the tuning parameters. E.g. some parameter
+     * update may allow some subsequent values for further parameter updates.
+     *
+     * When attached to a component, this method MUST be supported in any component state except
+     * released.
+     *
+     * This method has a variable blocking behavior based on state.
+     * In the stopped state this method MUST be "non-blocking" and return within 1ms.
+     * In the running states this method may be momentarily blocking, but MUST return within 5ms.
+     *
+     * \param[in,out] params a list of parameter updates. These will be updated to the actual
+     *                       parameter values after the updates (this is because tuning is performed
+     *                       at best effort).
+     *                       \todo params that could not be updated are not marked here, so are
+     *                       confusing - are they "existing" values or intended to be configured
+     *                       values?
+     * \param[in] mayBlock   if true (C2_MAY_BLOCK), implementation may momentarily block.
+     *                       Otherwise (C2_DONT_BLOCK), it must be "non-blocking".
+     * \param[out] failures  a list of parameter failures and optional guidance
+     *
+     * \retval C2_OK        all parameters could be updated successfully
+     * \retval C2_BAD_INDEX all supported parameters could be updated successfully, but some
+     *                      parameters were not supported
+     * \retval C2_BAD_VALUE some supported parameters could not be updated successfully because
+     *                      they contained unsupported values. These are returned in |failures|.
+     * \retval C2_BAD_STATE when called in the released component state (user error)
+     *                      (this error code is only allowed for interfaces connected to components)
+     * \retval C2_NO_MEMORY some supported parameters could not be updated successfully because
+     *                      they contained unsupported values, but could not allocate a failure
+     *                      object for them.
+     * \retval C2_TIMED_OUT could not set the parameters within the time limit (unexpected)
+     *                      (this error code is only allowed for interfaces connected to components
+     *                      in the running state)
+     * \retval C2_BLOCKING  the operation must block to complete but mayBlock is false
+     *                      (this error code is only allowed for interfaces connected to components)
+     * \retval C2_CORRUPTED some unknown error prevented the update of the parameters
+     *                      (unexpected)
+     *                      (this error code is only allowed for interfaces connected to components)
+     */
+    virtual c2_status_t config_vb(
+            const std::vector<C2Param*> &params,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2SettingResult>>* const failures) = 0;
+
+    // TUNNELING
+    // =============================================================================================
+
+    /**
+     * Creates a tunnel from this component to the target component.
+     *
+     * If the component is successfully created, subsequent work items queued may include a
+     * tunneled path between these components.
+     *
+     * When attached to a component, this method MUST be supported in any component state except
+     * released.
+     *
+     * This method may be momentarily blocking, but MUST return within 5ms.
+     *
+     * \retval C2_OK        the tunnel was successfully created
+     * \retval C2_BAD_INDEX the target component does not exist
+     * \retval C2_DUPLICATE the tunnel already exists
+     * \retval C2_OMITTED   tunneling is not supported by this component
+     * \retval C2_CANNOT_DO the specific tunnel is not supported
+     * \retval C2_BAD_STATE when called in the released component state (user error)
+     *                      (this error code is only allowed for interfaces connected to components)
+     *
+     * \retval C2_TIMED_OUT could not create the tunnel within the time limit (unexpected)
+     * \retval C2_CORRUPTED some unknown error prevented the creation of the tunnel (unexpected)
+     *                      (this error code is only allowed for interfaces connected to components)
+     */
+    virtual c2_status_t createTunnel_sm(c2_node_id_t targetComponent) = 0;
+
+    /**
+     * Releases a tunnel from this component to the target component.
+     *
+     * The release of a tunnel is delayed while there are pending work items for the tunnel.
+     * After releasing a tunnel, subsequent work items queued MUST NOT include a tunneled
+     * path between these components.
+     *
+     * When attached to a component, this method MUST be supported in any component state except
+     * released.
+     *
+     * This method may be momentarily blocking, but MUST return within 5ms.
+     *
+     * \retval C2_OK        the tunnel was marked for release successfully
+     * \retval C2_BAD_INDEX the target component does not exist
+     * \retval C2_NOT_FOUND the tunnel does not exist
+     * \retval C2_OMITTED   tunneling is not supported by this component
+     * \retval C2_BAD_STATE when called in the released component state (user error)
+     *                      (this error code is only allowed for interfaces connected to components)
+     *
+     * \retval C2_TIMED_OUT could not mark the tunnel for release within the time limit (unexpected)
+     * \retval C2_CORRUPTED some unknown error prevented the release of the tunnel (unexpected)
+     *                      (this error code is only allowed for interfaces connected to components)
+     */
+    virtual c2_status_t releaseTunnel_sm(c2_node_id_t targetComponent) = 0;
+
+    // REFLECTION MECHANISM (USED FOR EXTENSION)
+    // =============================================================================================
+
+    /**
+     * Returns the set of supported parameters.
+     *
+     * When attached to a component, this method MUST be supported in any component state except
+     * released.
+     *
+     * This method MUST be "non-blocking" and return within 1ms.
+     *
+     * \param[out] params a vector of supported parameters will be appended to this vector.
+     *
+     * \retval C2_OK        the operation completed successfully.
+     * \retval C2_BAD_STATE when called in the released component state (user error)
+     *                      (this error code is only allowed for interfaces connected to components)
+     * \retval C2_NO_MEMORY not enough memory to complete this method.
+     */
+    virtual c2_status_t querySupportedParams_nb(
+            std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const = 0;
+
+    /**
+     * Retrieves the supported values for the queried fields.
+     *
+     * Client SHALL set the parameter-field specifier and the type of supported values query (e.g.
+     * currently supported values, or potential supported values) in fields.
+     * Upon return the component SHALL fill in the supported values for the fields listed as well
+     * as a status for each field. Component shall process all fields queried even if some queries
+     * fail.
+     *
+     * When attached to a component, this method MUST be supported in any component state except
+     * released.
+     *
+     * This method has a variable blocking behavior based on state.
+     * In the stopped state this method MUST be "non-blocking" and return within 1ms.
+     * In the running states this method may be momentarily blocking, but MUST return within 5ms.
+     *
+     * \param[in out] fields a vector of fields descriptor structures.
+     * \param[in] mayBlock   if true (C2_MAY_BLOCK), implementation may momentarily block.
+     *                       Otherwise (C2_DONT_BLOCK), it must be "non-blocking".
+     *
+     * \retval C2_OK        the operation completed successfully.
+     * \retval C2_BAD_STATE when called in the released component state (user error)
+     *                      (this error code is only allowed for interfaces connected to components)
+     * \retval C2_BAD_INDEX at least one field was not recognized as a component field
+     * \retval C2_TIMED_OUT could not query supported values within the time limit (unexpected)
+     *                      (this error code is only allowed for interfaces connected to components
+     *                      in the running state)
+     * \retval C2_BLOCKING  the operation must block to complete but mayBlock is false
+     *                      (this error code is only allowed for interfaces connected to components)
+     * \retval C2_CORRUPTED some unknown error prevented the operation from completing (unexpected)
+     *                      (this error code is only allowed for interfaces connected to components)
+     */
+    virtual c2_status_t querySupportedValues_vb(
+            std::vector<C2FieldSupportedValuesQuery> &fields, c2_blocking_t mayBlock) const = 0;
+
+    virtual ~C2ComponentInterface() = default;
+};
+
+class C2Component {
+public:
+    class Listener {
+    public:
+        virtual void onWorkDone_nb(std::weak_ptr<C2Component> component,
+                                std::list<std::unique_ptr<C2Work>> workItems) = 0;
+
+        virtual void onTripped_nb(std::weak_ptr<C2Component> component,
+                               std::vector<std::shared_ptr<C2SettingResult>> settingResult) = 0;
+
+        virtual void onError_nb(std::weak_ptr<C2Component> component,
+                             uint32_t errorCode) = 0;
+
+        // virtual void onTunnelReleased(<from>, <to>) = 0;
+
+        // virtual void onComponentReleased(<id>) = 0;
+
+        virtual ~Listener() = default;
+    };
+
+    /**
+     * Sets the listener for this component
+     *
+     * This method MUST be supported in all states except released.
+     * The listener can only be set to non-null value in stopped state (that does not include
+     * tripped or error). It can be set to nullptr in both stopped and running states.
+     * Components only use the listener in running state.
+     *
+     * If listener is nullptr, the component SHALL guarantee that no more listener callbacks are
+     * done to the original listener once this method returns. (Any pending listener callbacks will
+     * need to be completed during this call - hence this call may be temporarily blocking.)
+     *
+     * This method has a variable blocking behavior based on state.
+     * In the stopped state this method MUST be "non-blocking" and return within 1ms.
+     * In the running states this method may be momentarily blocking, but MUST return within 5ms.
+     *
+     * Component SHALL handle listener notifications from the same thread (the thread used is
+     * at the component's discretion.)
+     *
+     * \note This could also be accomplished by passing a weak_ptr to a component-specific listener
+     * here and requiring the client to always promote the weak_ptr before any callback. This would
+     * put the burden on the client to clear the listener - wait for its deletion - at which point
+     * it is guaranteed that no more listener callbacks will occur.
+     *
+     * \param[in] listener the component listener object
+     * \param[in] mayBlock if true (C2_MAY_BLOCK), implementation may momentarily block.
+     *                     Otherwise (C2_DONT_BLOCK), it must be "non-blocking".
+     *
+     * \retval C2_BAD_STATE attempting to change the listener in the running state to a non-null
+     *                      value (user error), or called in the released state
+     * \retval C2_BLOCKING  the operation must block to complete but mayBlock is false
+     * \retval C2_OK        listener was updated successfully.
+     */
+    virtual c2_status_t setListener_vb(
+            const std::shared_ptr<Listener> &listener, c2_blocking_t mayBlock) = 0;
+
+    /// component domain (e.g. audio or video)
+    enum domain_t : uint32_t;
+
+    /// component kind (e.g. encoder, decoder or filter)
+    enum kind_t : uint32_t;
+
+    /// component rank. This number is used to determine component ordering (the lower the sooner)
+    /// in the component list.
+    typedef uint32_t rank_t;
+
+    /// component attributes
+    enum attrib_t : uint64_t;
+
+    /**
+     * Information about a component.
+     */
+    struct Traits {
+    // public:
+        C2String name; ///< name of the component
+        domain_t domain; ///< component domain
+        kind_t kind; ///< component kind
+        rank_t rank; ///< component rank
+        C2String mediaType; ///< media type supported by the component
+        C2String owner; ///< name of the component store owning this component
+
+        /**
+         * name alias(es) for backward compatibility.
+         * \note Multiple components can have the same alias as long as their media-type differs.
+         */
+        std::vector<C2String> aliases; ///< name aliases for backward compatibility
+    };
+
+    // METHODS AVAILABLE WHEN RUNNING
+    // =============================================================================================
+
+    /**
+     * Queues up work for the component.
+     *
+     * This method MUST be supported in running (including tripped and error) states.
+     *
+     * This method MUST be "non-blocking" and return within 1 ms
+     *
+     * It is acceptable for this method to return OK and return an error value using the
+     * onWorkDone() callback.
+     *
+     * \retval C2_OK        the work was successfully queued
+     * \retval C2_BAD_INDEX some component(s) in the work do(es) not exist
+     * \retval C2_CANNOT_DO the components are not tunneled
+     * \retval C2_BAD_STATE when called in the stopped or released state (user error)
+     *
+     * \retval C2_NO_MEMORY not enough memory to queue the work
+     * \retval C2_CORRUPTED some unknown error prevented queuing the work (unexpected)
+     */
+    virtual c2_status_t queue_nb(std::list<std::unique_ptr<C2Work>>* const items) = 0;
+
+    /**
+     * Announces a work to be queued later for the component. This reserves a slot for the queue
+     * to ensure correct work ordering even if the work is queued later.
+     *
+     * This method MUST be supported in running (including tripped and error) states.
+     *
+     * This method MUST be "non-blocking" and return within 1 ms
+     *
+     * \retval C2_OK        the work announcement has been successfully recorded
+     * \retval C2_BAD_INDEX some component(s) in the work outline do(es) not exist
+     * \retval C2_CANNOT_DO the componentes are not tunneled
+     * \retval C2_BAD_STATE when called in the stopped or released state (user error)
+     *
+     * \retval C2_NO_MEMORY not enough memory to record the work announcement
+     * \retval C2_CORRUPTED some unknown error prevented recording the announcement (unexpected)
+     *
+     * \todo Can this be rolled into queue_nb?
+     * \todo Expose next work item for each component to detect stalls
+     */
+    virtual c2_status_t announce_nb(const std::vector<C2WorkOutline> &items) = 0;
+
+    enum flush_mode_t : uint32_t {
+        /// flush work from this component only
+        FLUSH_COMPONENT,
+
+        /// flush work from this component and all components connected downstream from it via
+        /// tunneling
+        FLUSH_CHAIN = (1 << 16),
+    };
+
+    /**
+     * Discards and abandons any pending work for the component, and optionally any component
+     * downstream.
+     *
+     * \todo define this: we could flush all work before last item queued for component across all
+     *                    components linked to this; flush only work items that are queued to this
+     *                    component
+     * \todo return work # of last flushed item; or all flushed (but not returned items)
+     * \todo we could make flush take a work item and flush all work before/after that item to allow
+     *       TBD (slicing/seek?)
+     * \todo we could simply take a list of numbers and flush those... this is bad for decoders
+     *       also, what would happen to fine grade references?
+     *
+     * This method MUST be supported in running (including tripped and error) states.
+     *
+     * This method may be momentarily blocking, but must return within 5ms.
+     *
+     * Work that could be immediately abandoned/discarded SHALL be returned in |flushedWork|; this
+     * can be done in an arbitrary order.
+     *
+     * Work that could not be abandoned or discarded immediately SHALL be marked to be
+     * discarded at the earliest opportunity, and SHALL be returned via the onWorkDone() callback.
+     * This shall be completed within 500ms.
+     *
+     * \param mode flush mode
+     *
+     * \retval C2_OK        the component has been successfully flushed
+     * \retval C2_BAD_STATE when called in the stopped or released state (user error)
+     * \retval C2_TIMED_OUT the flush could not be completed within the time limit (unexpected)
+     * \retval C2_CORRUPTED some unknown error prevented flushing from completion (unexpected)
+     */
+    virtual c2_status_t flush_sm(flush_mode_t mode, std::list<std::unique_ptr<C2Work>>* const flushedWork) = 0;
+
+    enum drain_mode_t : uint32_t {
+        /// drain component only and add an "end-of-stream" marker. Component shall process all
+        /// queued work and complete the current stream. If new input is received, it shall start
+        /// a new stream. \todo define what a stream is.
+        DRAIN_COMPONENT_WITH_EOS,
+        /// drain component without setting "end-of-stream" marker. Component shall process all
+        /// queued work but shall expect more work items for the same stream.
+        DRAIN_COMPONENT_NO_EOS = (1 << 0),
+
+        /// marks the last work item with a persistent "end-of-stream" marker that will drain
+        /// downstream components
+        /// \todo this may confuse work-ordering downstream
+        DRAIN_CHAIN = (1 << 16),
+
+        /**
+         * \todo define this; we could place EOS to all upstream components, just this component, or
+         *       all upstream and downstream component.
+         * \todo should EOS carry over to downstream components?
+         */
+    };
+
+    /**
+     * Drains the component, and optionally downstream components. This is a signalling method;
+     * as such it does not wait for any work completion.
+     *
+     * Marks last work item as "drain-till-here", so component is notified not to wait for further
+     * work before it processes work already queued. This method can also used to set the
+     * end-of-stream flag after work has been queued. Client can continue to queue further work
+     * immediately after this method returns.
+     *
+     * This method MUST be supported in running (including tripped) states.
+     *
+     * This method MUST be "non-blocking" and return within 1ms.
+     *
+     * Work that is completed SHALL be returned via the onWorkDone() callback.
+     *
+     * \param mode drain mode
+     *
+     * \retval C2_OK        the drain request has been successfully recorded
+     * \retval C2_BAD_STATE when called in the stopped or released state (user error)
+     * \retval C2_BAD_VALUE the drain mode is not supported by the component
+     *                      \todo define supported modes discovery
+     * \retval C2_TIMED_OUT the flush could not be completed within the time limit (unexpected)
+     * \retval C2_CORRUPTED some unknown error prevented flushing from completion (unexpected)
+     */
+    virtual c2_status_t drain_nb(drain_mode_t mode) = 0;
+
+    // STATE CHANGE METHODS
+    // =============================================================================================
+
+    /**
+     * Starts the component.
+     *
+     * This method MUST be supported in stopped state, as well as during the tripped state.
+     *
+     * If the return value is C2_OK, the component shall be in the running state.
+     * If the return value is C2_BAD_STATE or C2_DUPLICATE, no state change is expected as a
+     * response to this call.
+     * Otherwise, the component shall be in the stopped state.
+     *
+     * \note If a component is in the tripped state and start() is called while the component
+     * configuration still results in a trip, start shall succeed and a new onTripped callback
+     * should be used to communicate the configuration conflict that results in the new trip.
+     *
+     * \todo This method MUST return within 500ms. Seems this should be able to return quickly, as
+     * there are no immediate guarantees. Though there are guarantees for responsiveness immediately
+     * after start returns.
+     *
+     * \retval C2_OK        the component has started (or resumed) successfully
+     * \retval C2_DUPLICATE when called during another start call from another thread
+     * \retval C2_BAD_STATE when called in any state other than the stopped state or tripped state,
+     *                      including when called during another state change call from another
+     *                      thread (user error)
+     * \retval C2_NO_MEMORY not enough memory to start the component
+     * \retval C2_TIMED_OUT the component could not be started within the time limit (unexpected)
+     * \retval C2_CORRUPTED some unknown error prevented starting the component (unexpected)
+     */
+    virtual c2_status_t start() = 0;
+
+    /**
+     * Stops the component.
+     *
+     * This method MUST be supported in running (including tripped) state.
+     *
+     * This method MUST return withing 500ms.
+     *
+     * Upon this call, all pending work SHALL be abandoned and all buffer references SHALL be
+     * released.
+     * If the return value is C2_BAD_STATE or C2_DUPLICATE, no state change is expected as a
+     * response to this call.
+     * For all other return values, the component shall be in the stopped state.
+     *
+     * \todo should this return completed work, since client will just free it? Perhaps just to
+     * verify accounting.
+     *
+     * This does not alter any settings and tunings that may have resulted in a tripped state.
+     * (Is this material given the definition? Perhaps in case we want to start again.)
+     *
+     * \retval C2_OK        the component has started successfully
+     * \retval C2_DUPLICATE when called during another stop call from another thread
+     * \retval C2_BAD_STATE when called in any state other than the running state, including when
+     *                      called during another state change call from another thread (user error)
+     * \retval C2_TIMED_OUT the component could not be stopped within the time limit (unexpected)
+     * \retval C2_CORRUPTED some unknown error prevented stopping the component (unexpected)
+     */
+    virtual c2_status_t stop() = 0;
+
+    /**
+     * Resets the component.
+     *
+     * This method MUST be supported in all (including tripped) states other than released.
+     *
+     * This method MUST be supported during any other blocking call.
+     *
+     * This method MUST return withing 500ms.
+     *
+     * After this call returns all work SHALL be abandoned, all buffer references SHALL be released.
+     * If the return value is C2_BAD_STATE or C2_DUPLICATE, no state change is expected as a
+     * response to this call.
+     * For all other return values, the component shall be in the stopped state.
+     *
+     * \todo should this return completed work, since client will just free it? Also, if it unblocks
+     * a stop, where should completed work be returned?
+     *
+     * This brings settings back to their default - "guaranteeing" no tripped space.
+     *
+     * \todo reclaim support - it seems that since ownership is passed, this will allow reclaiming
+     * stuff.
+     *
+     * \retval C2_OK        the component has been reset
+     * \retval C2_DUPLICATE when called during another reset call from another thread
+     * \retval C2_BAD_STATE when called in the released state
+     * \retval C2_TIMED_OUT the component could not be reset within the time limit (unexpected)
+     * \retval C2_CORRUPTED some unknown error prevented resetting the component (unexpected)
+     */
+    virtual c2_status_t reset() = 0;
+
+    /**
+     * Releases the component.
+     *
+     * This method MUST be supported in stopped state.
+     *
+     * This method MUST return withing 500ms. Upon return all references shall be abandoned.
+     *
+     * \retval C2_OK        the component has been released
+     * \retval C2_DUPLICATE the component is already released
+     * \retval C2_BAD_STATE the component is running
+     * \retval C2_TIMED_OUT the component could not be released within the time limit (unexpected)
+     * \retval C2_CORRUPTED some unknown error prevented releasing the component (unexpected)
+     */
+    virtual c2_status_t release() = 0;
+
+    /**
+     * Returns the interface for this component.
+     *
+     * \return the component interface
+     */
+    virtual std::shared_ptr<C2ComponentInterface> intf() = 0;
+
+    virtual ~C2Component() = default;
+};
+
+C2ENUM(C2Component::kind_t, uint32_t,
+    KIND_OTHER,
+    KIND_DECODER,
+    KIND_ENCODER
+);
+
+C2ENUM(C2Component::domain_t, uint32_t,
+    DOMAIN_OTHER,
+    DOMAIN_VIDEO,
+    DOMAIN_AUDIO,
+    DOMAIN_IMAGE
+);
+
+class C2FrameInfoParser {
+public:
+    /**
+     * \return the content type supported by this info parser.
+     *
+     * \todo this may be redundant
+     */
+    virtual C2StringLiteral getType() const = 0;
+
+    /**
+     * \return a vector of supported parameter indices parsed by this info parser.
+     *
+     * This method MUST be "non-blocking" and return within 1ms.
+     *
+     * \todo sticky vs. non-sticky params? this may be communicated by param-reflector.
+     */
+    virtual const std::vector<C2Param::Index> getParsedParams() const = 0;
+
+    /**
+     * Resets this info parser. This brings this parser to its initial state after creation.
+     *
+     * This method SHALL return within 5ms.
+     *
+     * \retval C2_OK        the info parser was reset
+     * \retval C2_TIMED_OUT could not reset the parser within the time limit (unexpected)
+     * \retval C2_CORRUPTED some unknown error prevented the resetting of the parser (unexpected)
+     */
+    virtual c2_status_t reset() { return C2_OK; }
+
+    virtual c2_status_t parseFrame(C2FrameData &frame);
+
+    virtual ~C2FrameInfoParser() = default;
+};
+
+class C2AllocatorStore {
+public:
+    typedef C2Allocator::id_t id_t;
+
+    enum : C2Allocator::id_t {
+        DEFAULT_LINEAR,     ///< basic linear allocator type
+        DEFAULT_GRAPHIC,    ///< basic graphic allocator type
+        PLATFORM_START = 0x10,
+        VENDOR_START   = 0x100,
+        BAD_ID         = C2Allocator::BAD_ID, ///< DO NOT USE
+    };
+
+    /**
+     * Returns the unique name of this allocator store.
+     *
+     * This method MUST be "non-blocking" and return within 1ms.
+     *
+     * \return the name of this allocator store.
+     * \retval an empty string if there was not enough memory to allocate the actual name.
+     */
+    virtual C2String getName() const = 0;
+
+    /**
+     * Returns the set of allocators supported by this allocator store.
+     *
+     * This method MUST be "non-blocking" and return within 1ms.
+     *
+     * \retval vector of allocator information (as shared pointers)
+     * \retval an empty vector if there was not enough memory to allocate the whole vector.
+     */
+    virtual std::vector<std::shared_ptr<const C2Allocator::Traits>> listAllocators_nb() const = 0;
+
+    /**
+     * Retrieves/creates a shared allocator object.
+     *
+     * This method MUST be return within 5ms.
+     *
+     * The allocator is created on first use, and the same allocator is returned on subsequent
+     * concurrent uses in the same process. The allocator is freed when it is no longer referenced.
+     *
+     * \param id      the ID of the allocator to create. This is defined by the store, but
+     *                the ID of the default linear and graphic allocators is formalized.
+     * \param allocator shared pointer where the created allocator is stored. Cleared on failure
+     *                  and updated on success.
+     *
+     * \retval C2_OK        the allocator was created successfully
+     * \retval C2_TIMED_OUT could not create the allocator within the time limit (unexpected)
+     * \retval C2_CORRUPTED some unknown error prevented the creation of the allocator (unexpected)
+     *
+     * \retval C2_NOT_FOUND no such allocator
+     * \retval C2_NO_MEMORY not enough memory to create the allocator
+     */
+    virtual c2_status_t fetchAllocator(id_t id, std::shared_ptr<C2Allocator>* const allocator) = 0;
+
+    virtual ~C2AllocatorStore() = default;
+};
+
+class C2ComponentStore {
+public:
+    /**
+     * Returns the name of this component or component interface object.
+     * This is a unique name for this component or component interface 'class'; however, multiple
+     * instances of this component SHALL have the same name.
+     *
+     * This method MUST be supported in any state. This call does not change the state nor the
+     * internal states of the component.
+     *
+     * This method MUST be "non-blocking" and return within 1ms.
+     *
+     * \return the name of this component or component interface object.
+     * \retval an empty string if there was not enough memory to allocate the actual name.
+     */
+    virtual C2String getName() const = 0;
+
+    /**
+     * Creates a component.
+     *
+     * This method SHALL return within 100ms.
+     *
+     * \param name          name of the component to create
+     * \param component     shared pointer where the created component is stored. Cleared on
+     *                      failure and updated on success.
+     *
+     * \retval C2_OK        the component was created successfully
+     * \retval C2_TIMED_OUT could not create the component within the time limit (unexpected)
+     * \retval C2_CORRUPTED some unknown error prevented the creation of the component (unexpected)
+     *
+     * \retval C2_NOT_FOUND no such component
+     * \retval C2_NO_MEMORY not enough memory to create the component
+     */
+    virtual c2_status_t createComponent(
+            C2String name, std::shared_ptr<C2Component>* const component) = 0;
+
+    /**
+     * Creates a component interface.
+     *
+     * This method SHALL return within 100ms.
+     *
+     * \param name          name of the component interface to create
+     * \param interface     shared pointer where the created interface is stored
+     *
+     * \retval C2_OK        the component interface was created successfully
+     * \retval C2_TIMED_OUT could not create the component interface within the time limit
+     *                      (unexpected)
+     * \retval C2_CORRUPTED some unknown error prevented the creation of the component interface
+     *                      (unexpected)
+     *
+     * \retval C2_NOT_FOUND no such component interface
+     * \retval C2_NO_MEMORY not enough memory to create the component interface
+     *
+     * \todo Do we need an interface, or could this just be a component that is never started?
+     */
+    virtual c2_status_t createInterface(
+            C2String name, std::shared_ptr<C2ComponentInterface>* const interface) = 0;
+
+    /**
+     * Returns the list of components supported by this component store.
+     *
+     * This method MUST return within 500ms.
+     *
+     * \retval vector of component information.
+     */
+    virtual std::vector<std::shared_ptr<const C2Component::Traits>> listComponents() = 0;
+
+    // -------------------------------------- UTILITY METHODS --------------------------------------
+
+    // on-demand buffer layout conversion (swizzling)
+    //
+    virtual c2_status_t copyBuffer(
+            std::shared_ptr<C2GraphicBuffer> src, std::shared_ptr<C2GraphicBuffer> dst) = 0;
+
+    // -------------------------------------- CONFIGURATION API -----------------------------------
+    // e.g. for global settings (system-wide stride, etc.)
+
+    /**
+     * Queries a set of system-wide parameters.
+     * Querying is performed at best effort: the store SHALL query all supported parameters and
+     * skip unsupported ones, or heap allocated parameters that could not be allocated. Any errors
+     * are communicated in the return value. Additionally, preallocated (e.g. stack) parameters that
+     * could not be queried are invalidated. Parameters to be allocated on the heap are omitted from
+     * the result.
+     *
+     * \note Parameter values do not depend on the order of query.
+     *
+     * This method may be momentarily blocking, but MUST return within 5ms.
+     *
+     * \param stackParams   a list of params queried. These are initialized specific to each
+     *                      setting; e.g. size and index are set and rest of the members are
+     *                      cleared.
+     *                      NOTE: Flexible settings that are of incorrect size will be invalidated.
+     * \param heapParamIndices a vector of param indices for params to be queried and returned on the
+     *                      heap. These parameters will be returned in heapParams. Unsupported param
+     *                      indices will be ignored.
+     * \param heapParams    a list of params where to which the supported heap parameters will be
+     *                      appended in the order they appear in heapParamIndices.
+     *
+     * \retval C2_OK        all parameters could be queried
+     * \retval C2_BAD_INDEX all supported parameters could be queried, but some parameters were not
+     *                      supported
+     * \retval C2_NO_MEMORY could not allocate memory for a supported parameter
+     * \retval C2_CORRUPTED some unknown error prevented the querying of the parameters
+     *                      (unexpected)
+     */
+    virtual c2_status_t query_sm(
+        const std::vector<C2Param*> &stackParams,
+        const std::vector<C2Param::Index> &heapParamIndices,
+        std::vector<std::unique_ptr<C2Param>>* const heapParams) const = 0;
+
+    /**
+     * Sets a set of system-wide parameters.
+     *
+     * \note There are no settable system-wide parameters defined thus far, but may be added in the
+     * future.
+     *
+     * Tuning is performed at best effort: the store SHALL update all supported configuration at
+     * best effort (unless configured otherwise) and skip unsupported ones. Any errors are
+     * communicated in the return value and in |failures|.
+     *
+     * \note Parameter tuning DOES depend on the order of the tuning parameters. E.g. some parameter
+     * update may allow some subsequent parameter update.
+     *
+     * This method may be momentarily blocking, but MUST return within 5ms.
+     *
+     * \param params        a list of parameter updates. These will be updated to the actual
+     *                      parameter values after the updates (this is because tuning is performed
+     *                      at best effort).
+     *                      \todo params that could not be updated are not marked here, so are
+     *                      confusing - are they "existing" values or intended to be configured
+     *                      values?
+     * \param failures      a list of parameter failures
+     *
+     * \retval C2_OK        all parameters could be updated successfully
+     * \retval C2_BAD_INDEX all supported parameters could be updated successfully, but some
+     *                      parameters were not supported
+     * \retval C2_BAD_VALUE some supported parameters could not be updated successfully because
+     *                      they contained unsupported values. These are returned in |failures|.
+     * \retval C2_NO_MEMORY some supported parameters could not be updated successfully because
+     *                      they contained unsupported values, but could not allocate a failure
+     *                      object for them.
+     * \retval C2_CORRUPTED some unknown error prevented the update of the parameters
+     *                      (unexpected)
+     */
+    virtual c2_status_t config_sm(
+            const std::vector<C2Param*> &params,
+            std::vector<std::unique_ptr<C2SettingResult>>* const failures) = 0;
+
+    // REFLECTION MECHANISM (USED FOR EXTENSION)
+    // =============================================================================================
+
+    /**
+     * Returns the parameter reflector.
+     *
+     * This is used to describe parameter fields. This is shared for all components created by
+     * this component store.
+     *
+     * This method MUST be "non-blocking" and return within 1ms.
+     *
+     * \return a shared parameter reflector object.
+     */
+    virtual std::shared_ptr<C2ParamReflector> getParamReflector() const = 0;
+
+    /**
+     * Returns the set of supported parameters.
+     *
+     * This method MUST be "non-blocking" and return within 1ms.
+     *
+     * \param[out] params a vector of supported parameters will be appended to this vector.
+     *
+     * \retval C2_OK        the operation completed successfully.
+     * \retval C2_NO_MEMORY not enough memory to complete this method.
+     */
+    virtual c2_status_t querySupportedParams_nb(
+            std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const = 0;
+
+    /**
+     * Retrieves the supported values for the queried fields.
+     *
+     * Client SHALL set the parameter-field specifier and the type of supported values query (e.g.
+     * currently supported values, or potential supported values) in fields.
+     * Upon return the store SHALL fill in the supported values for the fields listed as well
+     * as a status for each field. Store shall process all fields queried even if some queries
+     * fail.
+     *
+     * This method may be momentarily blocking, but MUST return within 5ms.
+     *
+     * \param[in out] fields a vector of fields descriptor structures.
+     *
+     * \retval C2_OK        the operation completed successfully.
+     * \retval C2_BAD_INDEX at least one field was not recognized as a component store field
+     */
+    virtual c2_status_t querySupportedValues_sm(
+            std::vector<C2FieldSupportedValuesQuery> &fields) const = 0;
+
+    virtual ~C2ComponentStore() = default;
+};
+
+// ================================================================================================
+
+/// @}
+
+#endif  // C2COMPONENT_H_
diff --git a/media/codec2/core/include/C2Config.h b/media/codec2/core/include/C2Config.h
new file mode 100644
index 0000000..3820f90
--- /dev/null
+++ b/media/codec2/core/include/C2Config.h
@@ -0,0 +1,2149 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef C2CONFIG_H_
+#define C2CONFIG_H_
+
+#include <C2.h>
+#include <C2Component.h>
+#include <C2Enum.h>
+#include <C2ParamDef.h>
+
+/// \defgroup config Component configuration
+/// @{
+
+/**
+ * Enumerated boolean.
+ */
+C2ENUM(c2_bool_t, uint32_t,
+    C2_FALSE, ///< true
+    C2_TRUE,  ///< false
+)
+
+typedef C2SimpleValueStruct<c2_bool_t> C2BoolValue;
+
+typedef C2SimpleValueStruct<C2EasyEnum<c2_bool_t>> C2EasyBoolValue;
+
+/**
+ * Enumerated set tri-state.
+ *
+ * Used for optional configurations to distinguish between values set by the client,
+ * default values set by the component, or unset values.
+ */
+C2ENUM(c2_set_t, uint32_t,
+    C2_UNSET,   // parameter is unset and has no value
+    C2_SET,     // parameter is/has been set by the client
+    C2_DEFAULT, // parameter has not been set by the client, but is set by the component
+)
+
+/** Enumerations used by configuration parameters */
+struct C2Config {
+    enum aac_packaging_t : uint32_t;        ///< AAC packaging (RAW vs ADTS)
+    enum aac_sbr_mode_t : uint32_t;         ///< AAC SBR mode
+    enum api_feature_t : uint64_t;          ///< API features
+    enum api_level_t : uint32_t;            ///< API level
+    enum bitrate_mode_t : uint32_t;         ///< bitrate control mode
+    enum drc_compression_mode_t : int32_t;  ///< DRC compression mode
+    enum drc_effect_type_t : int32_t;       ///< DRC effect type
+    enum intra_refresh_mode_t : uint32_t;   ///< intra refresh modes
+    enum level_t : uint32_t;                ///< coding level
+    enum ordinal_key_t : uint32_t;          ///< work ordering keys
+    enum pcm_encoding_t : uint32_t;         ///< PCM encoding
+    enum picture_type_t : uint32_t;         ///< picture types
+    enum platform_feature_t : uint64_t;     ///< platform features
+    enum platform_level_t : uint32_t;       ///< platform level
+    enum prepend_header_mode_t : uint32_t;  ///< prepend header operational modes
+    enum profile_t : uint32_t;              ///< coding profile
+    enum scaling_method_t : uint32_t;       ///< scaling methods
+    enum scan_order_t : uint32_t;           ///< scan orders
+    enum secure_mode_t : uint32_t;          ///< secure/protected modes
+    enum supplemental_info_t : uint32_t;    ///< supplemental information types
+    enum tiling_mode_t : uint32_t;          ///< tiling modes
+};
+
+namespace {
+
+enum C2ParamIndexKind : C2Param::type_index_t {
+    C2_PARAM_INDEX_INVALID             = 0x0,    ///< do not use
+    C2_PARAM_INDEX_STRUCT_START        = 0x1,    ///< struct only indices
+    C2_PARAM_INDEX_PARAM_START         = 0x800,  ///< regular parameters
+    C2_PARAM_INDEX_CODER_PARAM_START   = 0x1000, ///< en/transcoder parameters
+    C2_PARAM_INDEX_PICTURE_PARAM_START = 0x1800, ///< image/video parameters
+    C2_PARAM_INDEX_VIDEO_PARAM_START   = 0x2000, ///< video parameters
+    C2_PARAM_INDEX_IMAGE_PARAM_START   = 0x2800, ///< image parameters
+    C2_PARAM_INDEX_AUDIO_PARAM_START   = 0x3000, ///< image parameters
+    C2_PARAM_INDEX_PLATFORM_START      = 0x4000, ///< platform-defined parameters
+
+    /* =================================== structure indices =================================== */
+
+    kParamIndexColorXy = C2_PARAM_INDEX_STRUCT_START,
+    kParamIndexMasteringDisplayColorVolume,
+    kParamIndexChromaOffset,
+    kParamIndexGopLayer,
+
+    /* =================================== parameter indices =================================== */
+
+    kParamIndexApiLevel = C2_PARAM_INDEX_PARAM_START,
+    kParamIndexApiFeatures,
+
+    /* ------------------------------------ all components ------------------------------------ */
+
+    /* generic component characteristics */
+    kParamIndexName,
+    kParamIndexAliases,
+    kParamIndexKind,
+    kParamIndexDomain,
+    kParamIndexAttributes,
+    kParamIndexTimeStretch,
+
+    /* coding characteristics */
+    kParamIndexProfileLevel,
+    kParamIndexInitData,
+    kParamIndexSupplementalData,
+    kParamIndexSubscribedSupplementalData,
+
+    /* pipeline characteristics */
+    kParamIndexMediaType,
+    __kParamIndexRESERVED_0,
+    kParamIndexDelay,
+    kParamIndexMaxReferenceAge,
+    kParamIndexMaxReferenceCount,
+    kParamIndexReorderBufferDepth,
+    kParamIndexReorderKey,
+    kParamIndexStreamCount,
+    kParamIndexSubscribedParamIndices,
+    kParamIndexSuggestedBufferCount,
+    kParamIndexBatchSize,
+    kParamIndexCurrentWork,
+    kParamIndexLastWorkQueued,
+
+    /* memory allocation */
+    kParamIndexAllocators,
+    kParamIndexBlockPools,
+    kParamIndexBufferType,
+    kParamIndexUsage,
+    kParamIndexOutOfMemory,
+    kParamIndexMaxBufferSize,
+
+    /* misc. state */
+    kParamIndexTripped,
+    kParamIndexConfigCounter,
+
+    /* resources */
+    kParamIndexResourcesNeeded,
+    kParamIndexResourcesReserved,
+    kParamIndexOperatingRate,
+    kParamIndexRealTimePriority,
+
+    /* protected content */
+    kParamIndexSecureMode,
+
+    // deprecated
+    kParamIndexDelayRequest = kParamIndexDelay | C2Param::CoreIndex::IS_REQUEST_FLAG,
+
+    /* ------------------------------------ (trans/en)coders ------------------------------------ */
+
+    kParamIndexBitrate = C2_PARAM_INDEX_CODER_PARAM_START,
+    kParamIndexBitrateMode,
+    kParamIndexQuality,
+    kParamIndexComplexity,
+    kParamIndexPrependHeaderMode,
+
+    /* --------------------------------- image/video components --------------------------------- */
+
+    kParamIndexPictureSize = C2_PARAM_INDEX_PICTURE_PARAM_START,
+    kParamIndexCropRect,
+    kParamIndexPixelFormat,
+    kParamIndexRotation,
+    kParamIndexPixelAspectRatio,
+    kParamIndexScaledPictureSize,
+    kParamIndexScaledCropRect,
+    kParamIndexScalingMethod,
+    kParamIndexColorInfo,
+    kParamIndexColorAspects,
+    kParamIndexHdrStaticMetadata,
+    kParamIndexDefaultColorAspects,
+
+    kParamIndexBlockSize,
+    kParamIndexBlockCount,
+    kParamIndexBlockRate,
+
+    kParamIndexPictureTypeMask,
+    kParamIndexPictureType,
+    kParamIndexHdr10PlusMetadata,
+
+    /* ------------------------------------ video components ------------------------------------ */
+
+    kParamIndexFrameRate = C2_PARAM_INDEX_VIDEO_PARAM_START,
+    kParamIndexMaxBitrate,
+    kParamIndexMaxFrameRate,
+    kParamIndexMaxPictureSize,
+    kParamIndexGop,
+    kParamIndexSyncFrameInterval,
+    kParamIndexRequestSyncFrame,
+    kParamIndexTemporalLayering,
+    kParamIndexLayerIndex,
+    kParamIndexLayerCount,
+    kParamIndexIntraRefresh,
+
+    /* ------------------------------------ image components ------------------------------------ */
+
+    kParamIndexTileLayout = C2_PARAM_INDEX_IMAGE_PARAM_START,
+    kParamIndexTileHandling,
+
+    /* ------------------------------------ audio components ------------------------------------ */
+
+    kParamIndexSampleRate = C2_PARAM_INDEX_AUDIO_PARAM_START,
+    kParamIndexChannelCount,
+    kParamIndexPcmEncoding,
+    kParamIndexAacPackaging,
+    kParamIndexMaxChannelCount,
+    kParamIndexAacSbrMode, // aac encode, enum
+    kParamIndexDrcEncodedTargetLevel,  // drc, float (dBFS)
+    kParamIndexDrcTargetReferenceLevel, // drc, float (dBFS)
+    kParamIndexDrcCompression, // drc, enum
+    kParamIndexDrcBoostFactor, // drc, float (0-1)
+    kParamIndexDrcAttenuationFactor, // drc, float (0-1)
+    kParamIndexDrcEffectType, // drc, enum
+
+    /* ============================== platform-defined parameters ============================== */
+
+    kParamIndexPlatformLevel = C2_PARAM_INDEX_PLATFORM_START, // all, u32
+    kParamIndexPlatformFeatures, // all, u64 mask
+    kParamIndexStoreIonUsage, // store, struct
+    kParamIndexAspectsToDataSpace, // store, struct
+    kParamIndexFlexiblePixelFormatDescriptor, // store, struct
+    kParamIndexFlexiblePixelFormatDescriptors, // store, struct[]
+    kParamIndexDataSpaceToAspects, // store, struct
+    kParamIndexDataSpace, // u32
+    kParamIndexSurfaceScaling, // u32
+
+    // input surface
+    kParamIndexInputSurfaceEos, // input-surface, eos
+    kParamIndexTimedControl, // struct
+    kParamIndexStartAt, // input-surface, struct
+    kParamIndexSuspendAt, // input-surface, struct
+    kParamIndexResumeAt, // input-surface, struct
+    kParamIndexStopAt, // input-surface, struct
+    kParamIndexTimeOffset, // input-surface, struct
+    kParamIndexMinFrameRate, // input-surface, float
+    kParamIndexTimestampGapAdjustment, // input-surface, struct
+
+    kParamIndexSurfaceAllocator, // u32
+};
+
+}
+
+/**
+ * Codec 2.0 parameter types follow the following naming convention:
+ *
+ * C2<group><domain><index><type>
+ *
+ * E.g. C2StreamPictureSizeInfo: group="" domain="Stream" index="PictureSize" type="Info".
+ * Group is somewhat arbitrary, but denotes kind of objects the parameter is defined.
+ * At this point we use Component and Store to distinguish basic component/store parameters.
+ *
+ * Parameter keys are named C2_PARAMKEY_[<group>_]<domain>_<index> as type is not expected
+ * to distinguish parameters. E.g. a component could change the type of the parameter and it
+ * is not expected users would need to change the key.
+ */
+
+/* ----------------------------------------- API level ----------------------------------------- */
+
+enum C2Config::api_level_t : uint32_t {
+    API_L0_1 = 0,   ///< support for API level 0.1
+};
+
+// read-only
+typedef C2GlobalParam<C2Setting, C2SimpleValueStruct<C2Config::api_level_t>, kParamIndexApiLevel>
+        C2ApiLevelSetting;
+constexpr char C2_PARAMKEY_API_LEVEL[] = "api.level";
+
+enum C2Config::api_feature_t : uint64_t {
+    API_REFLECTION       = (1U << 0),  ///< ability to list supported parameters
+    API_VALUES           = (1U << 1),  ///< ability to list supported values for each parameter
+    API_CURRENT_VALUES   = (1U << 2),  ///< ability to list currently supported values for each parameter
+    API_DEPENDENCY       = (1U << 3),  ///< have a defined parameter dependency
+
+    API_STREAMS          = (1ULL << 32),  ///< supporting variable number of streams
+
+    API_TUNNELING        = (1ULL << 48),  ///< tunneling API
+};
+
+// read-only
+typedef C2GlobalParam<C2Setting, C2SimpleValueStruct<C2Config::api_feature_t>, kParamIndexApiFeatures>
+        C2ApiFeaturesSetting;
+constexpr char C2_PARAMKEY_API_FEATURES[] = "api.features";
+
+/* ----------------------------- generic component characteristics ----------------------------- */
+
+/**
+ * The name of the component.
+ *
+ * This must contain only alphanumeric characters or dot '.', hyphen '-', plus '+', or
+ * underline '_'. The name of each component must be unique.
+ *
+ * For Android: Component names must start with 'c2.' followed by the company name or abbreviation
+ * and another dot, e.g. 'c2.android.'. Use of lowercase is preferred but not required.
+ */
+// read-only
+typedef C2GlobalParam<C2Setting, C2StringValue, kParamIndexName> C2ComponentNameSetting;
+constexpr char C2_PARAMKEY_COMPONENT_NAME[]  = "component.name";
+
+/**
+ * Alternate names (aliases) of the component.
+ *
+ * This is a comma ',' separated list of alternate component names. Unlike component names that
+ * must be unique, multiple components can have the same alias.
+ */
+// read-only
+typedef C2GlobalParam<C2Setting, C2StringValue, kParamIndexAliases> C2ComponentAliasesSetting;
+constexpr char C2_PARAMKEY_COMPONENT_ALIASES[]  = "component.aliases";
+
+/**
+ * Component kind.
+ */
+// read-only
+typedef C2GlobalParam<C2Setting, C2SimpleValueStruct<C2Component::kind_t>, kParamIndexKind>
+        C2ComponentKindSetting;
+constexpr char C2_PARAMKEY_COMPONENT_KIND[]  = "component.kind";
+
+/**
+ * Component domain.
+ */
+// read-only
+typedef C2GlobalParam<C2Setting, C2SimpleValueStruct<C2Component::domain_t>, kParamIndexDomain>
+        C2ComponentDomainSetting;
+constexpr char C2_PARAMKEY_COMPONENT_DOMAIN[]  = "component.domain";
+
+/**
+ * Component attributes.
+ *
+ * These are a set of flags provided by the component characterizing its processing algorithm.
+ */
+C2ENUM(C2Component::attrib_t, uint64_t,
+    ATTRIB_IS_TEMPORAL = 1u << 0, ///< component input ordering matters for processing
+)
+
+// read-only
+typedef C2GlobalParam<C2Setting, C2SimpleValueStruct<C2Component::attrib_t>, kParamIndexAttributes>
+        C2ComponentAttributesSetting;
+constexpr char C2_PARAMKEY_COMPONENT_ATTRIBUTES[] = "component.attributes";
+
+/**
+ * Time stretching.
+ *
+ * This is the ratio between the rate of the input timestamp, and the rate of the output timestamp.
+ * E.g. if this is 4.0, for every 1 seconds of input timestamp difference, the output shall differ
+ * by 4 seconds.
+ */
+typedef C2GlobalParam<C2Tuning, C2FloatValue, kParamIndexTimeStretch> C2ComponentTimeStretchTuning;
+constexpr char C2_PARAMKEY_TIME_STRETCH[]  = "algo.time-stretch";
+
+/* ----------------------------------- coding characteristics ----------------------------------- */
+
+/**
+ * Profile and level.
+ *
+ * Profile determines the tools used by the component.
+ * Level determines the level of resources used by the component.
+ */
+
+namespace {
+
+enum : uint32_t {
+    _C2_PL_MP2V_BASE = 0x1000,
+    _C2_PL_AAC_BASE  = 0x2000,
+    _C2_PL_H263_BASE = 0x3000,
+    _C2_PL_MP4V_BASE = 0x4000,
+    _C2_PL_AVC_BASE  = 0x5000,
+    _C2_PL_HEVC_BASE = 0x6000,
+    _C2_PL_VP9_BASE  = 0x7000,
+    _C2_PL_DV_BASE   = 0x8000,
+    _C2_PL_AV1_BASE  = 0x9000,
+
+    C2_PROFILE_LEVEL_VENDOR_START = 0x70000000,
+};
+
+}
+
+enum C2Config::profile_t : uint32_t {
+    PROFILE_UNUSED = 0,                         ///< profile is not used by this media type
+
+    // AAC (MPEG-2 Part 7 and MPEG-4 Part 3) profiles
+    PROFILE_AAC_LC = _C2_PL_AAC_BASE,           ///< AAC Low-Complexity
+    PROFILE_AAC_MAIN,                           ///< AAC Main
+    PROFILE_AAC_SSR,                            ///< AAC Scalable Sampling Rate
+    PROFILE_AAC_LTP,                            ///< AAC Long Term Prediction
+    PROFILE_AAC_HE,                             ///< AAC High-Efficiency
+    PROFILE_AAC_SCALABLE,                       ///< AAC Scalable
+    PROFILE_AAC_ER_LC,                          ///< AAC Error Resilient Low-Complexity
+    PROFILE_AAC_ER_SCALABLE,                    ///< AAC Error Resilient Scalable
+    PROFILE_AAC_LD,                             ///< AAC Low Delay
+    PROFILE_AAC_HE_PS,                          ///< AAC High-Efficiency Parametric Stereo
+    PROFILE_AAC_ELD,                            ///< AAC Enhanced Low Delay
+    PROFILE_AAC_XHE,                            ///< AAC Extended High-Efficiency
+
+    // MPEG-2 Video profiles
+    PROFILE_MP2V_SIMPLE = _C2_PL_MP2V_BASE,     ///< MPEG-2 Video (H.262) Simple
+    PROFILE_MP2V_MAIN,                          ///< MPEG-2 Video (H.262) Main
+    PROFILE_MP2V_SNR_SCALABLE,                  ///< MPEG-2 Video (H.262) SNR Scalable
+    PROFILE_MP2V_SPATIALLY_SCALABLE,            ///< MPEG-2 Video (H.262) Spatially Scalable
+    PROFILE_MP2V_HIGH,                          ///< MPEG-2 Video (H.262) High
+    PROFILE_MP2V_422,                           ///< MPEG-2 Video (H.262) 4:2:2
+    PROFILE_MP2V_MULTIVIEW,                     ///< MPEG-2 Video (H.262) Multi-view
+
+    // H.263 profiles
+    PROFILE_H263_BASELINE = _C2_PL_H263_BASE,   ///< H.263 Baseline (Profile 0)
+    PROFILE_H263_H320,                          ///< H.263 H.320 Coding Efficiency Version 2 Backward-Compatibility (Profile 1)
+    PROFILE_H263_V1BC,                          ///< H.263 Version 1 Backward-Compatibility (Profile 2)
+    PROFILE_H263_ISWV2,                         ///< H.263 Version 2 Interactive and Streaming Wireless (Profile 3)
+    PROFILE_H263_ISWV3,                         ///< H.263 Version 3 Interactive and Streaming Wireless (Profile 4)
+    PROFILE_H263_HIGH_COMPRESSION,              ///< H.263 Conversational High Compression (Profile 5)
+    PROFILE_H263_INTERNET,                      ///< H.263 Conversational Internet (Profile 6)
+    PROFILE_H263_INTERLACE,                     ///< H.263 Conversational Interlace (Profile 7)
+    PROFILE_H263_HIGH_LATENCY,                  ///< H.263 High Latency (Profile 8)
+
+    // MPEG-4 Part 2 (Video) Natural Visual Profiles
+    PROFILE_MP4V_SIMPLE,                        ///< MPEG-4 Video Simple
+    PROFILE_MP4V_SIMPLE_SCALABLE,               ///< MPEG-4 Video Simple Scalable
+    PROFILE_MP4V_CORE,                          ///< MPEG-4 Video Core
+    PROFILE_MP4V_MAIN,                          ///< MPEG-4 Video Main
+    PROFILE_MP4V_NBIT,                          ///< MPEG-4 Video N-Bit
+    PROFILE_MP4V_ARTS,                          ///< MPEG-4 Video Advanced Realtime Simple
+    PROFILE_MP4V_CORE_SCALABLE,                 ///< MPEG-4 Video Core Scalable
+    PROFILE_MP4V_ACE,                           ///< MPEG-4 Video Advanced Coding Efficiency
+    PROFILE_MP4V_ADVANCED_CORE,                 ///< MPEG-4 Video Advanced Core
+    PROFILE_MP4V_SIMPLE_STUDIO,                 ///< MPEG-4 Video Simple Studio
+    PROFILE_MP4V_CORE_STUDIO,                   ///< MPEG-4 Video Core Studio
+    PROFILE_MP4V_ADVANCED_SIMPLE,               ///< MPEG-4 Video Advanced Simple
+    PROFILE_MP4V_FGS,                           ///< MPEG-4 Video Fine Granularity Scalable
+
+    // AVC / MPEG-4 Part 10 (H.264) profiles
+    PROFILE_AVC_BASELINE = _C2_PL_AVC_BASE,     ///< AVC (H.264) Baseline
+    PROFILE_AVC_CONSTRAINED_BASELINE,           ///< AVC (H.264) Constrained Baseline
+    PROFILE_AVC_MAIN,                           ///< AVC (H.264) Main
+    PROFILE_AVC_EXTENDED,                       ///< AVC (H.264) Extended
+    PROFILE_AVC_HIGH,                           ///< AVC (H.264) High
+    PROFILE_AVC_PROGRESSIVE_HIGH,               ///< AVC (H.264) Progressive High
+    PROFILE_AVC_CONSTRAINED_HIGH,               ///< AVC (H.264) Constrained High
+    PROFILE_AVC_HIGH_10,                        ///< AVC (H.264) High 10
+    PROFILE_AVC_PROGRESSIVE_HIGH_10,            ///< AVC (H.264) Progressive High 10
+    PROFILE_AVC_HIGH_422,                       ///< AVC (H.264) High 4:2:2
+    PROFILE_AVC_HIGH_444_PREDICTIVE,            ///< AVC (H.264) High 4:4:4 Predictive
+    PROFILE_AVC_HIGH_10_INTRA,                  ///< AVC (H.264) High 10 Intra
+    PROFILE_AVC_HIGH_422_INTRA,                 ///< AVC (H.264) High 4:2:2 Intra
+    PROFILE_AVC_HIGH_444_INTRA,                 ///< AVC (H.264) High 4:4:4 Intra
+    PROFILE_AVC_CAVLC_444_INTRA,                ///< AVC (H.264) CAVLC 4:4:4 Intra
+    PROFILE_AVC_SCALABLE_BASELINE = _C2_PL_AVC_BASE + 0x100,  ///< AVC (H.264) Scalable Baseline
+    PROFILE_AVC_SCALABLE_CONSTRAINED_BASELINE,  ///< AVC (H.264) Scalable Constrained Baseline
+    PROFILE_AVC_SCALABLE_HIGH,                  ///< AVC (H.264) Scalable High
+    PROFILE_AVC_SCALABLE_CONSTRAINED_HIGH,      ///< AVC (H.264) Scalable Constrained High
+    PROFILE_AVC_SCALABLE_HIGH_INTRA,            ///< AVC (H.264) Scalable High Intra
+    PROFILE_AVC_MULTIVIEW_HIGH = _C2_PL_AVC_BASE + 0x200,  ///< AVC (H.264) Multiview High
+    PROFILE_AVC_STEREO_HIGH,                    ///< AVC (H.264) Stereo High
+    PROFILE_AVC_MFC_HIGH,                       ///< AVC (H.264) MFC High
+    PROFILE_AVC_MULTIVIEW_DEPTH_HIGH = _C2_PL_AVC_BASE + 0x300,  ///< AVC (H.264) Multiview Depth High
+    PROFILE_AVC_MFC_DEPTH_HIGH,                 ///< AVC (H.264) MFC Depth High
+    PROFILE_AVC_ENHANCED_MULTIVIEW_DEPTH_HIGH = _C2_PL_AVC_BASE + 0x400,  ///< AVC (H.264) Enhanced Multiview Depth High
+
+    // HEVC profiles
+    PROFILE_HEVC_MAIN = _C2_PL_HEVC_BASE,       ///< HEVC (H.265) Main
+    PROFILE_HEVC_MAIN_10,                       ///< HEVC (H.265) Main 10
+    PROFILE_HEVC_MAIN_STILL,                    ///< HEVC (H.265) Main Still Picture
+    PROFILE_HEVC_MONO = _C2_PL_HEVC_BASE + 0x100,  ///< HEVC (H.265) Monochrome
+    PROFILE_HEVC_MONO_12,                       ///< HEVC (H.265) Monochrome 12
+    PROFILE_HEVC_MONO_16,                       ///< HEVC (H.265) Monochrome 16
+    PROFILE_HEVC_MAIN_12,                       ///< HEVC (H.265) Main 12
+    PROFILE_HEVC_MAIN_422_10,                   ///< HEVC (H.265) Main 4:2:2 10
+    PROFILE_HEVC_MAIN_422_12,                   ///< HEVC (H.265) Main 4:2:2 12
+    PROFILE_HEVC_MAIN_444,                      ///< HEVC (H.265) Main 4:4:4
+    PROFILE_HEVC_MAIN_444_10,                   ///< HEVC (H.265) Main 4:4:4 10
+    PROFILE_HEVC_MAIN_444_12,                   ///< HEVC (H.265) Main 4:4:4 12
+    PROFILE_HEVC_MAIN_INTRA,                    ///< HEVC (H.265) Main Intra
+    PROFILE_HEVC_MAIN_10_INTRA,                 ///< HEVC (H.265) Main 10 Intra
+    PROFILE_HEVC_MAIN_12_INTRA,                 ///< HEVC (H.265) Main 12 Intra
+    PROFILE_HEVC_MAIN_422_10_INTRA,             ///< HEVC (H.265) Main 4:2:2 10 Intra
+    PROFILE_HEVC_MAIN_422_12_INTRA,             ///< HEVC (H.265) Main 4:2:2 12 Intra
+    PROFILE_HEVC_MAIN_444_INTRA,                ///< HEVC (H.265) Main 4:4:4 Intra
+    PROFILE_HEVC_MAIN_444_10_INTRA,             ///< HEVC (H.265) Main 4:4:4 10 Intra
+    PROFILE_HEVC_MAIN_444_12_INTRA,             ///< HEVC (H.265) Main 4:4:4 12 Intra
+    PROFILE_HEVC_MAIN_444_16_INTRA,             ///< HEVC (H.265) Main 4:4:4 16 Intra
+    PROFILE_HEVC_MAIN_444_STILL,                ///< HEVC (H.265) Main 4:4:4 Still Picture
+    PROFILE_HEVC_MAIN_444_16_STILL,             ///< HEVC (H.265) Main 4:4:4 16 Still Picture
+    PROFILE_HEVC_HIGH_444 = _C2_PL_HEVC_BASE + 0x200,  ///< HEVC (H.265) High Throughput 4:4:4
+    PROFILE_HEVC_HIGH_444_10,                   ///< HEVC (H.265) High Throughput 4:4:4 10
+    PROFILE_HEVC_HIGH_444_14,                   ///< HEVC (H.265) High Throughput 4:4:4 14
+    PROFILE_HEVC_HIGH_444_16_INTRA,             ///< HEVC (H.265) High Throughput 4:4:4 16 Intra
+    PROFILE_HEVC_SX_MAIN = _C2_PL_HEVC_BASE + 0x300,  ///< HEVC (H.265) Screen-Extended Main
+    PROFILE_HEVC_SX_MAIN_10,                    ///< HEVC (H.265) Screen-Extended Main 10
+    PROFILE_HEVC_SX_MAIN_444,                   ///< HEVC (H.265) Screen-Extended Main 4:4:4
+    PROFILE_HEVC_SX_MAIN_444_10,                ///< HEVC (H.265) Screen-Extended Main 4:4:4 10
+    PROFILE_HEVC_SX_HIGH_444,                   ///< HEVC (H.265) Screen-Extended High Throughput 4:4:4
+    PROFILE_HEVC_SX_HIGH_444_10,                ///< HEVC (H.265) Screen-Extended High Throughput 4:4:4 10
+    PROFILE_HEVC_SX_HIGH_444_14,                ///< HEVC (H.265) Screen-Extended High Throughput 4:4:4 14
+    PROFILE_HEVC_MULTIVIEW_MAIN = _C2_PL_HEVC_BASE + 0x400,  ///< HEVC (H.265) Multiview Main
+    PROFILE_HEVC_SCALABLE_MAIN = _C2_PL_HEVC_BASE + 0x500,  ///< HEVC (H.265) Scalable Main
+    PROFILE_HEVC_SCALABLE_MAIN_10,              ///< HEVC (H.265) Scalable Main 10
+    PROFILE_HEVC_SCALABLE_MONO = _C2_PL_HEVC_BASE + 0x600,  ///< HEVC (H.265) Scalable Monochrome
+    PROFILE_HEVC_SCALABLE_MONO_12,              ///< HEVC (H.265) Scalable Monochrome 12
+    PROFILE_HEVC_SCALABLE_MONO_16,              ///< HEVC (H.265) Scalable Monochrome 16
+    PROFILE_HEVC_SCALABLE_MAIN_444,             ///< HEVC (H.265) Scalable Main 4:4:4
+    PROFILE_HEVC_3D_MAIN = _C2_PL_HEVC_BASE + 0x700,  ///< HEVC (H.265) 3D Main
+
+    // VP9 profiles
+    PROFILE_VP9_0 = _C2_PL_VP9_BASE,            ///< VP9 Profile 0 (4:2:0)
+    PROFILE_VP9_1,                              ///< VP9 Profile 1 (4:2:2 or 4:4:4)
+    PROFILE_VP9_2,                              ///< VP9 Profile 2 (4:2:0, 10 or 12 bit)
+    PROFILE_VP9_3,                              ///< VP9 Profile 3 (4:2:2 or 4:4:4, 10 or 12 bit)
+
+    // Dolby Vision profiles
+    PROFILE_DV_AV_PER = _C2_PL_DV_BASE + 0,     ///< Dolby Vision dvav.per profile (deprecated)
+    PROFILE_DV_AV_PEN,                          ///< Dolby Vision dvav.pen profile (deprecated)
+    PROFILE_DV_HE_DER,                          ///< Dolby Vision dvhe.der profile (deprecated)
+    PROFILE_DV_HE_DEN,                          ///< Dolby Vision dvhe.den profile (deprecated)
+    PROFILE_DV_HE_04 = _C2_PL_DV_BASE + 4,      ///< Dolby Vision dvhe.04 profile
+    PROFILE_DV_HE_05 = _C2_PL_DV_BASE + 5,      ///< Dolby Vision dvhe.05 profile
+    PROFILE_DV_HE_DTH,                          ///< Dolby Vision dvhe.dth profile (deprecated)
+    PROFILE_DV_HE_07 = _C2_PL_DV_BASE + 7,      ///< Dolby Vision dvhe.07 profile
+    PROFILE_DV_HE_08 = _C2_PL_DV_BASE + 8,      ///< Dolby Vision dvhe.08 profile
+    PROFILE_DV_AV_09 = _C2_PL_DV_BASE + 9,      ///< Dolby Vision dvav.09 profile
+
+    // AV1 profiles
+    PROFILE_AV1_0 = _C2_PL_AV1_BASE,            ///< AV1 Profile 0 (4:2:0, 8 to 10 bit)
+    PROFILE_AV1_1,                              ///< AV1 Profile 1 (8 to 10 bit)
+    PROFILE_AV1_2,                              ///< AV1 Profile 2 (8 to 12 bit)
+};
+
+enum C2Config::level_t : uint32_t {
+    LEVEL_UNUSED = 0,                           ///< level is not used by this media type
+
+    // MPEG-2 Video levels
+    LEVEL_MP2V_LOW = _C2_PL_MP2V_BASE,          ///< MPEG-2 Video (H.262) Low Level
+    LEVEL_MP2V_MAIN,                            ///< MPEG-2 Video (H.262) Main Level
+    LEVEL_MP2V_HIGH_1440,                       ///< MPEG-2 Video (H.262) High 1440 Level
+    LEVEL_MP2V_HIGH,                            ///< MPEG-2 Video (H.262) High Level
+    LEVEL_MP2V_HIGHP,                           ///< MPEG-2 Video (H.262) HighP Level
+
+    // H.263 levels
+    LEVEL_H263_10 = _C2_PL_H263_BASE,           ///< H.263 Level 10
+    LEVEL_H263_20,                              ///< H.263 Level 20
+    LEVEL_H263_30,                              ///< H.263 Level 30
+    LEVEL_H263_40,                              ///< H.263 Level 40
+    LEVEL_H263_45,                              ///< H.263 Level 45
+    LEVEL_H263_50,                              ///< H.263 Level 50
+    LEVEL_H263_60,                              ///< H.263 Level 60
+    LEVEL_H263_70,                              ///< H.263 Level 70
+
+    // MPEG-4 Part 2 (Video) levels
+    LEVEL_MP4V_0 = _C2_PL_MP4V_BASE,            ///< MPEG-4 Video Level 0
+    LEVEL_MP4V_0B,                              ///< MPEG-4 Video Level 0b
+    LEVEL_MP4V_1,                               ///< MPEG-4 Video Level 1
+    LEVEL_MP4V_2,                               ///< MPEG-4 Video Level 2
+    LEVEL_MP4V_3,                               ///< MPEG-4 Video Level 3
+    LEVEL_MP4V_3B,                              ///< MPEG-4 Video Level 3b
+    LEVEL_MP4V_4,                               ///< MPEG-4 Video Level 4
+    LEVEL_MP4V_4A,                              ///< MPEG-4 Video Level 4a
+    LEVEL_MP4V_5,                               ///< MPEG-4 Video Level 5
+    LEVEL_MP4V_6,                               ///< MPEG-4 Video Level 6
+
+    // AVC / MPEG-4 Part 10 (H.264) levels
+    LEVEL_AVC_1 = _C2_PL_AVC_BASE,              ///< AVC (H.264) Level 1
+    LEVEL_AVC_1B,                               ///< AVC (H.264) Level 1b
+    LEVEL_AVC_1_1,                              ///< AVC (H.264) Level 1.1
+    LEVEL_AVC_1_2,                              ///< AVC (H.264) Level 1.2
+    LEVEL_AVC_1_3,                              ///< AVC (H.264) Level 1.3
+    LEVEL_AVC_2,                                ///< AVC (H.264) Level 2
+    LEVEL_AVC_2_1,                              ///< AVC (H.264) Level 2.1
+    LEVEL_AVC_2_2,                              ///< AVC (H.264) Level 2.2
+    LEVEL_AVC_3,                                ///< AVC (H.264) Level 3
+    LEVEL_AVC_3_1,                              ///< AVC (H.264) Level 3.1
+    LEVEL_AVC_3_2,                              ///< AVC (H.264) Level 3.2
+    LEVEL_AVC_4,                                ///< AVC (H.264) Level 4
+    LEVEL_AVC_4_1,                              ///< AVC (H.264) Level 4.1
+    LEVEL_AVC_4_2,                              ///< AVC (H.264) Level 4.2
+    LEVEL_AVC_5,                                ///< AVC (H.264) Level 5
+    LEVEL_AVC_5_1,                              ///< AVC (H.264) Level 5.1
+    LEVEL_AVC_5_2,                              ///< AVC (H.264) Level 5.2
+    LEVEL_AVC_6,                                ///< AVC (H.264) Level 6
+    LEVEL_AVC_6_1,                              ///< AVC (H.264) Level 6.1
+    LEVEL_AVC_6_2,                              ///< AVC (H.264) Level 6.2
+
+    // HEVC (H.265) tiers and levels
+    LEVEL_HEVC_MAIN_1 = _C2_PL_HEVC_BASE,       ///< HEVC (H.265) Main Tier Level 1
+    LEVEL_HEVC_MAIN_2,                          ///< HEVC (H.265) Main Tier Level 2
+    LEVEL_HEVC_MAIN_2_1,                        ///< HEVC (H.265) Main Tier Level 2.1
+    LEVEL_HEVC_MAIN_3,                          ///< HEVC (H.265) Main Tier Level 3
+    LEVEL_HEVC_MAIN_3_1,                        ///< HEVC (H.265) Main Tier Level 3.1
+    LEVEL_HEVC_MAIN_4,                          ///< HEVC (H.265) Main Tier Level 4
+    LEVEL_HEVC_MAIN_4_1,                        ///< HEVC (H.265) Main Tier Level 4.1
+    LEVEL_HEVC_MAIN_5,                          ///< HEVC (H.265) Main Tier Level 5
+    LEVEL_HEVC_MAIN_5_1,                        ///< HEVC (H.265) Main Tier Level 5.1
+    LEVEL_HEVC_MAIN_5_2,                        ///< HEVC (H.265) Main Tier Level 5.2
+    LEVEL_HEVC_MAIN_6,                          ///< HEVC (H.265) Main Tier Level 6
+    LEVEL_HEVC_MAIN_6_1,                        ///< HEVC (H.265) Main Tier Level 6.1
+    LEVEL_HEVC_MAIN_6_2,                        ///< HEVC (H.265) Main Tier Level 6.2
+
+    LEVEL_HEVC_HIGH_4 = _C2_PL_HEVC_BASE + 0x100,  ///< HEVC (H.265) High Tier Level 4
+    LEVEL_HEVC_HIGH_4_1,                        ///< HEVC (H.265) High Tier Level 4.1
+    LEVEL_HEVC_HIGH_5,                          ///< HEVC (H.265) High Tier Level 5
+    LEVEL_HEVC_HIGH_5_1,                        ///< HEVC (H.265) High Tier Level 5.1
+    LEVEL_HEVC_HIGH_5_2,                        ///< HEVC (H.265) High Tier Level 5.2
+    LEVEL_HEVC_HIGH_6,                          ///< HEVC (H.265) High Tier Level 6
+    LEVEL_HEVC_HIGH_6_1,                        ///< HEVC (H.265) High Tier Level 6.1
+    LEVEL_HEVC_HIGH_6_2,                        ///< HEVC (H.265) High Tier Level 6.2
+
+    // VP9 levels
+    LEVEL_VP9_1 = _C2_PL_VP9_BASE,              ///< VP9 Level 1
+    LEVEL_VP9_1_1,                              ///< VP9 Level 1.1
+    LEVEL_VP9_2,                                ///< VP9 Level 2
+    LEVEL_VP9_2_1,                              ///< VP9 Level 2.1
+    LEVEL_VP9_3,                                ///< VP9 Level 3
+    LEVEL_VP9_3_1,                              ///< VP9 Level 3.1
+    LEVEL_VP9_4,                                ///< VP9 Level 4
+    LEVEL_VP9_4_1,                              ///< VP9 Level 4.1
+    LEVEL_VP9_5,                                ///< VP9 Level 5
+    LEVEL_VP9_5_1,                              ///< VP9 Level 5.1
+    LEVEL_VP9_5_2,                              ///< VP9 Level 5.2
+    LEVEL_VP9_6,                                ///< VP9 Level 6
+    LEVEL_VP9_6_1,                              ///< VP9 Level 6.1
+    LEVEL_VP9_6_2,                              ///< VP9 Level 6.2
+
+    // Dolby Vision levels
+    LEVEL_DV_MAIN_HD_24 = _C2_PL_DV_BASE,       ///< Dolby Vision main tier hd24
+    LEVEL_DV_MAIN_HD_30,                        ///< Dolby Vision main tier hd30
+    LEVEL_DV_MAIN_FHD_24,                       ///< Dolby Vision main tier fhd24
+    LEVEL_DV_MAIN_FHD_30,                       ///< Dolby Vision main tier fhd30
+    LEVEL_DV_MAIN_FHD_60,                       ///< Dolby Vision main tier fhd60
+    LEVEL_DV_MAIN_UHD_24,                       ///< Dolby Vision main tier uhd24
+    LEVEL_DV_MAIN_UHD_30,                       ///< Dolby Vision main tier uhd30
+    LEVEL_DV_MAIN_UHD_48,                       ///< Dolby Vision main tier uhd48
+    LEVEL_DV_MAIN_UHD_60,                       ///< Dolby Vision main tier uhd60
+
+    LEVEL_DV_HIGH_HD_24 = _C2_PL_DV_BASE + 0x100,  ///< Dolby Vision high tier hd24
+    LEVEL_DV_HIGH_HD_30,                        ///< Dolby Vision high tier hd30
+    LEVEL_DV_HIGH_FHD_24,                       ///< Dolby Vision high tier fhd24
+    LEVEL_DV_HIGH_FHD_30,                       ///< Dolby Vision high tier fhd30
+    LEVEL_DV_HIGH_FHD_60,                       ///< Dolby Vision high tier fhd60
+    LEVEL_DV_HIGH_UHD_24,                       ///< Dolby Vision high tier uhd24
+    LEVEL_DV_HIGH_UHD_30,                       ///< Dolby Vision high tier uhd30
+    LEVEL_DV_HIGH_UHD_48,                       ///< Dolby Vision high tier uhd48
+    LEVEL_DV_HIGH_UHD_60,                       ///< Dolby Vision high tier uhd60
+
+    // AV1 levels
+    LEVEL_AV1_2    = _C2_PL_AV1_BASE ,          ///< AV1 Level 2
+    LEVEL_AV1_2_1,                              ///< AV1 Level 2.1
+    LEVEL_AV1_2_2,                              ///< AV1 Level 2.2
+    LEVEL_AV1_2_3,                              ///< AV1 Level 2.3
+    LEVEL_AV1_3,                                ///< AV1 Level 3
+    LEVEL_AV1_3_1,                              ///< AV1 Level 3.1
+    LEVEL_AV1_3_2,                              ///< AV1 Level 3.2
+    LEVEL_AV1_3_3,                              ///< AV1 Level 3.3
+    LEVEL_AV1_4,                                ///< AV1 Level 4
+    LEVEL_AV1_4_1,                              ///< AV1 Level 4.1
+    LEVEL_AV1_4_2,                              ///< AV1 Level 4.2
+    LEVEL_AV1_4_3,                              ///< AV1 Level 4.3
+    LEVEL_AV1_5,                                ///< AV1 Level 5
+    LEVEL_AV1_5_1,                              ///< AV1 Level 5.1
+    LEVEL_AV1_5_2,                              ///< AV1 Level 5.2
+    LEVEL_AV1_5_3,                              ///< AV1 Level 5.3
+    LEVEL_AV1_6,                                ///< AV1 Level 6
+    LEVEL_AV1_6_1,                              ///< AV1 Level 6.1
+    LEVEL_AV1_6_2,                              ///< AV1 Level 6.2
+    LEVEL_AV1_6_3,                              ///< AV1 Level 6.3
+    LEVEL_AV1_7,                                ///< AV1 Level 7
+    LEVEL_AV1_7_1,                              ///< AV1 Level 7.1
+    LEVEL_AV1_7_2,                              ///< AV1 Level 7.2
+    LEVEL_AV1_7_3,                              ///< AV1 Level 7.3
+};
+
+struct C2ProfileLevelStruct {
+    C2Config::profile_t profile;  ///< coding profile
+    C2Config::level_t   level;    ///< coding level
+
+    C2ProfileLevelStruct(
+            C2Config::profile_t profile_ = C2Config::PROFILE_UNUSED,
+            C2Config::level_t level_ = C2Config::LEVEL_UNUSED)
+        : profile(profile_), level(level_) { }
+
+    DEFINE_AND_DESCRIBE_C2STRUCT(ProfileLevel)
+    C2FIELD(profile, "profile")
+    C2FIELD(level,   "level")
+};
+
+// TODO: may need to make this explicit (have .set member)
+typedef C2StreamParam<C2Info, C2ProfileLevelStruct, kParamIndexProfileLevel>
+        C2StreamProfileLevelInfo;
+constexpr char C2_PARAMKEY_PROFILE_LEVEL[] = "coded.pl";
+
+/**
+ * Codec-specific initialization data.
+ *
+ * This is initialization data for the codec.
+ *
+ * For AVC/HEVC, these are the concatenated SPS/PPS/VPS NALs.
+ *
+ * TODO: define for other codecs.
+ */
+typedef C2StreamParam<C2Info, C2BlobValue, kParamIndexInitData> C2StreamInitDataInfo;
+constexpr char C2_PARAMKEY_INIT_DATA[] = "coded.init-data";
+
+/**
+ * Supplemental Data.
+ *
+ * This is coding-specific supplemental informational data, e.g. SEI for AVC/HEVC.
+ * This structure is not a configuration so it does not have a parameter key.
+ * This structure shall be returned in the configuration update, and can be repeated as needed
+ * in the same update.
+ */
+C2ENUM(C2Config::supplemental_info_t, uint32_t,
+    INFO_NONE = 0,
+
+    INFO_PREFIX_SEI_UNIT = 0x10000, ///< prefix SEI payload types add this flag
+    INFO_SUFFIX_SEI_UNIT = 0x20000, ///< suffix SEI payload types add this flag
+
+    INFO_SEI_USER_DATA = INFO_PREFIX_SEI_UNIT | 4,    ///< closed-captioning data (ITU-T T35)
+    INFO_SEI_MDCV      = INFO_PREFIX_SEI_UNIT | 137,  ///< mastering display color volume
+    INFO_SET_USER_DATA_SFX = INFO_SUFFIX_SEI_UNIT | 4, ///< closed-captioning data (ITU-T T35)
+
+    INFO_VENDOR_START = 0x70000000
+)
+
+struct C2SupplementalDataStruct {
+    C2SupplementalDataStruct()
+        : type_(INFO_NONE) { }
+
+    C2SupplementalDataStruct(
+            size_t flexCount, C2Config::supplemental_info_t type, std::vector<uint8_t> data_)
+        : type_(type) {
+            memcpy(data, &data_[0], c2_min(data_.size(), flexCount));
+    }
+
+    C2Config::supplemental_info_t type_;
+    uint8_t data[];
+
+    DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(SupplementalData, data)
+    C2FIELD(type_, "type")
+    C2FIELD(data, "data")
+};
+typedef C2StreamParam<C2Info, C2SupplementalDataStruct, kParamIndexSupplementalData>
+        C2StreamSupplementalDataInfo;
+
+/**
+ * Supplemental Data Subscription
+ */
+typedef C2StreamParam<C2Tuning, C2SimpleArrayStruct<C2Config::supplemental_info_t>,
+                kParamIndexSubscribedSupplementalData>
+        C2StreamSubscribedSupplementalDataTuning;
+constexpr char C2_PARAMKEY_SUBSCRIBED_SUPPLEMENTAL_DATA[] = "output.subscribed-supplemental";
+
+/* ---------------------------------- pipeline characteristics ---------------------------------- */
+
+/**
+ * Media-type.
+ *
+ * This is defined for both port and stream, but stream media type may be a subtype of the
+ * port media type.
+ */
+typedef C2PortParam<C2Setting, C2StringValue, kParamIndexMediaType> C2PortMediaTypeSetting;
+constexpr char C2_PARAMKEY_INPUT_MEDIA_TYPE[] = "input.media-type";
+constexpr char C2_PARAMKEY_OUTPUT_MEDIA_TYPE[] = "output.media-type";
+
+typedef C2StreamParam<C2Setting, C2StringValue, kParamIndexMediaType> C2StreamMediaTypeSetting;
+
+/**
+ * Pipeline delays.
+ *
+ * Input delay is the number of additional input frames requested by the component to process
+ * an input frame.
+ *
+ * Output delay is the number of additional output frames that need to be generated before an
+ * output can be released by the component.
+ *
+ * Pipeline delay is the number of additional frames that are processed at one time by the
+ * component.
+ *
+ * As these may vary from frame to frame, the number is the maximum required value. E.g. if
+ * input delay is 0, the component is expected to consume each frame queued even if no further
+ * frames are queued. Similarly, if input delay is 1, as long as there are always exactly 2
+ * outstanding input frames queued to the component, it shall produce output.
+ */
+
+typedef C2PortParam<C2Tuning, C2Uint32Value, kParamIndexDelay | C2Param::CoreIndex::IS_REQUEST_FLAG>
+        C2PortRequestedDelayTuning;
+constexpr char C2_PARAMKEY_INPUT_DELAY_REQUEST[] = "input.delay"; // deprecated
+constexpr char C2_PARAMKEY_OUTPUT_DELAY_REQUEST[] = "output.delay"; // deprecated
+
+typedef C2GlobalParam<C2Tuning, C2Uint32Value,
+                kParamIndexDelay | C2Param::CoreIndex::IS_REQUEST_FLAG>
+        C2RequestedPipelineDelayTuning;
+constexpr char C2_PARAMKEY_PIPELINE_DELAY_REQUEST[] = "algo.delay"; // deprecated
+
+// read-only
+typedef C2PortParam<C2Tuning, C2Uint32Value, kParamIndexDelay> C2PortDelayTuning;
+typedef C2PortDelayTuning C2PortActualDelayTuning; // deprecated
+constexpr char C2_PARAMKEY_INPUT_DELAY[] = "input.delay";
+constexpr char C2_PARAMKEY_OUTPUT_DELAY[] = "output.delay";
+
+// read-only
+typedef C2GlobalParam<C2Tuning, C2Uint32Value, kParamIndexDelay> C2PipelineDelayTuning;
+typedef C2PipelineDelayTuning C2ActualPipelineDelayTuning; // deprecated
+constexpr char C2_PARAMKEY_PIPELINE_DELAY[] = "algo.delay";
+
+/**
+ * Reference characteristics.
+ *
+ * The component may hold onto input and output buffers even after completing the corresponding
+ * work item.
+ *
+ * Max reference age is the longest number of additional frame processing that a component may
+ * hold onto a buffer for. Max reference count is the number of buffers that a component may
+ * hold onto at the same time at the worst case. These numbers assume single frame per buffers.
+ *
+ * Use max-uint32 if there is no limit for the max age or count.
+ */
+typedef C2StreamParam<C2Tuning, C2Uint32Value, kParamIndexMaxReferenceAge>
+        C2StreamMaxReferenceAgeTuning;
+constexpr char C2_PARAMKEY_INPUT_MAX_REFERENCE_AGE[] = "input.reference.max-age";
+constexpr char C2_PARAMKEY_OUTPUT_MAX_REFERENCE_AGE[] = "output.reference.max-age";
+
+typedef C2StreamParam<C2Tuning, C2Uint32Value, kParamIndexMaxReferenceCount>
+        C2StreamMaxReferenceCountTuning;
+constexpr char C2_PARAMKEY_INPUT_MAX_REFERENCE_COUNT[] = "input.reference.max-count";
+constexpr char C2_PARAMKEY_OUTPUT_MAX_REFERENCE_COUNT[] = "output.reference.max-count";
+
+/**
+ * Output reordering.
+ *
+ * The size of the window to use for output buffer reordering. 0 is interpreted as 1.
+ */
+// output only
+typedef C2PortParam<C2Tuning, C2Uint32Value, kParamIndexReorderBufferDepth>
+        C2PortReorderBufferDepthTuning;
+constexpr char C2_PARAMKEY_OUTPUT_REORDER_DEPTH[] = "output.reorder.depth";
+
+C2ENUM(C2Config::ordinal_key_t, uint32_t,
+        ORDINAL,
+        TIMESTAMP,
+        CUSTOM)
+
+// read-only, output only
+typedef C2PortParam<C2Setting, C2SimpleValueStruct<C2Config::ordinal_key_t>, kParamIndexReorderKey>
+        C2PortReorderKeySetting;
+constexpr char C2_PARAMKEY_OUTPUT_REORDER_KEY[] = "output.reorder.key";
+
+/**
+ * Stream count.
+ */
+// private
+typedef C2PortParam<C2Tuning, C2Uint32Value, kParamIndexStreamCount> C2PortStreamCountTuning;
+constexpr char C2_PARAMKEY_INPUT_STREAM_COUNT[] = "input.stream-count";
+constexpr char C2_PARAMKEY_OUTPUT_STREAM_COUNT[] = "output.stream-count";
+
+/**
+ * Config update subscription.
+ */
+// private
+typedef C2GlobalParam<C2Tuning, C2Uint32Array, kParamIndexSubscribedParamIndices>
+        C2SubscribedParamIndicesTuning;
+constexpr char C2_PARAMKEY_SUBSCRIBED_PARAM_INDICES[] = "output.subscribed-indices";
+
+/**
+ * Suggested buffer (C2Frame) count. This is a suggestion by the component for the number of
+ * input and output frames allocated for the component's use in the buffer pools.
+ *
+ * Component shall set the acceptable range of buffers allocated for it. E.g. client shall
+ * allocate at least the minimum required value.
+ */
+// read-only
+typedef C2PortParam<C2Tuning, C2Uint64Array, kParamIndexSuggestedBufferCount>
+        C2PortSuggestedBufferCountTuning;
+constexpr char C2_PARAMKEY_INPUT_SUGGESTED_BUFFER_COUNT[] = "input.buffers.pool-size";
+constexpr char C2_PARAMKEY_OUTPUT_SUGGESTED_BUFFER_COUNT[] = "output.buffers.pool-size";
+
+/**
+ * Input/output batching.
+ *
+ * For input, component requests that client batches work in batches of specified size. For output,
+ * client requests that the component batches work completion in given batch size.
+ * Value 0 means don't care.
+ */
+typedef C2PortParam<C2Tuning, C2Uint64Array, kParamIndexBatchSize> C2PortBatchSizeTuning;
+constexpr char C2_PARAMKEY_INPUT_BATCH_SIZE[] = "input.buffers.batch-size";
+constexpr char C2_PARAMKEY_OUTPUT_BATCH_SIZE[] = "output.buffers.batch-size";
+
+/**
+ * Current & last work ordinals.
+ *
+ * input port: last work queued to component.
+ * output port: last work completed by component.
+ * global: current work.
+ */
+typedef C2PortParam<C2Tuning, C2WorkOrdinalStruct, kParamIndexLastWorkQueued> C2LastWorkQueuedTuning;
+typedef C2GlobalParam<C2Tuning, C2WorkOrdinalStruct, kParamIndexCurrentWork> C2CurrentWorkTuning;
+
+
+/* ------------------------------------- memory allocation ------------------------------------- */
+
+/**
+ * Allocators to use.
+ *
+ * These are requested by the component.
+ *
+ * If none specified, client will use the default allocator ID based on the component domain and
+ * kind.
+ */
+typedef C2PortParam<C2Tuning, C2SimpleArrayStruct<C2Allocator::id_t>, kParamIndexAllocators>
+        C2PortAllocatorsTuning;
+constexpr char C2_PARAMKEY_INPUT_ALLOCATORS[] = "input.buffers.allocator-ids";
+constexpr char C2_PARAMKEY_OUTPUT_ALLOCATORS[] = "output.buffers.allocator-ids";
+
+typedef C2GlobalParam<C2Tuning, C2SimpleArrayStruct<C2Allocator::id_t>, kParamIndexAllocators>
+        C2PrivateAllocatorsTuning;
+constexpr char C2_PARAMKEY_PRIVATE_ALLOCATORS[] = "algo.buffers.allocator-ids";
+
+/**
+ * Allocator to use for outputting to surface.
+ *
+ * Components can optionally request allocator type for outputting to surface.
+ *
+ * If none specified, client will use the default BufferQueue-backed allocator ID for outputting to
+ * surface.
+ */
+typedef C2PortParam<C2Tuning, C2Uint32Value, kParamIndexSurfaceAllocator>
+        C2PortSurfaceAllocatorTuning;
+constexpr char C2_PARAMKEY_OUTPUT_SURFACE_ALLOCATOR[] = "output.buffers.surface-allocator-id";
+
+/**
+ * Block pools to use.
+ *
+ * These are allocated by the client for the component using the allocator IDs specified by the
+ * component. This is not used for the input port.
+ */
+typedef C2PortParam<C2Tuning, C2SimpleArrayStruct<C2BlockPool::local_id_t>, kParamIndexBlockPools>
+        C2PortBlockPoolsTuning;
+constexpr char C2_PARAMKEY_OUTPUT_BLOCK_POOLS[] = "output.buffers.pool-ids";
+
+typedef C2GlobalParam<C2Tuning, C2SimpleArrayStruct<C2BlockPool::local_id_t>, kParamIndexBlockPools>
+        C2PrivateBlockPoolsTuning;
+constexpr char C2_PARAMKEY_PRIVATE_BLOCK_POOLS[] = "algo.buffers.pool-ids";
+
+/**
+ * The max number of private allocations at any one time by the component.
+ * (This is an array with a corresponding value for each private allocator)
+ */
+typedef C2GlobalParam<C2Tuning, C2Uint32Array, kParamIndexMaxReferenceCount>
+        C2MaxPrivateBufferCountTuning;
+constexpr char C2_PARAMKEY_MAX_PRIVATE_BUFFER_COUNT[] = "algo.buffers.max-count";
+
+/**
+ * Buffer type
+ *
+ * This is provided by the component for the client to allocate the proper buffer type for the
+ * input port, and can be provided by the client to control the buffer type for the output.
+ */
+// private
+typedef C2StreamParam<C2Setting, C2SimpleValueStruct<C2EasyEnum<C2BufferData::type_t>>,
+                kParamIndexBufferType>
+        C2StreamBufferTypeSetting;
+constexpr char C2_PARAMKEY_INPUT_STREAM_BUFFER_TYPE[] = "input.buffers.type";
+constexpr char C2_PARAMKEY_OUTPUT_STREAM_BUFFER_TYPE[] = "output.buffers.type";
+
+/**
+ * Memory usage.
+ *
+ * Suggested by component for input and negotiated between client and component for output.
+ */
+typedef C2StreamParam<C2Tuning, C2Uint64Value, kParamIndexUsage> C2StreamUsageTuning;
+constexpr char C2_PARAMKEY_INPUT_STREAM_USAGE[] = "input.buffers.usage";
+constexpr char C2_PARAMKEY_OUTPUT_STREAM_USAGE[] = "output.buffers.usage";
+
+/**
+ * Picture (video or image frame) size.
+ */
+struct C2PictureSizeStruct {
+    inline C2PictureSizeStruct()
+        : width(0), height(0) { }
+
+    inline C2PictureSizeStruct(uint32_t width_, uint32_t height_)
+        : width(width_), height(height_) { }
+
+    uint32_t width;     ///< video width
+    uint32_t height;    ///< video height
+
+    DEFINE_AND_DESCRIBE_C2STRUCT(PictureSize)
+    C2FIELD(width, "width")
+    C2FIELD(height, "height")
+};
+
+/**
+ * Out of memory signaling
+ *
+ * This is a configuration for the client to mark that it cannot allocate necessary private and/
+ * or output buffers to continue operation, and to signal the failing configuration.
+ */
+struct C2OutOfMemoryStruct {
+    C2BlockPool::local_id_t pool;   ///< pool ID that failed the allocation
+    uint64_t usage;                 ///< memory usage used
+    C2PictureSizeStruct planar;     ///< buffer dimensions to be allocated if 2D
+    uint32_t format;                ///< pixel format to be used if 2D
+    uint32_t capacity;              ///< buffer capacity to be allocated if 1D
+    c2_bool_t outOfMemory;           ///< true if component is out of memory
+
+    DEFINE_AND_DESCRIBE_C2STRUCT(OutOfMemory)
+    C2FIELD(pool, "pool")
+    C2FIELD(usage, "usage")
+    C2FIELD(planar, "planar")
+    C2FIELD(format, "format")
+    C2FIELD(capacity, "capacity")
+    C2FIELD(outOfMemory, "out-of-memory")
+};
+
+typedef C2GlobalParam<C2Tuning, C2OutOfMemoryStruct, kParamIndexOutOfMemory> C2OutOfMemoryTuning;
+constexpr char C2_PARAMKEY_OUT_OF_MEMORY[] = "algo.oom";
+
+/**
+ * Max buffer size
+ *
+ * This is a hint provided by the component for the maximum buffer size expected on a stream for the
+ * current configuration on its input and output streams. This is communicated to clients so they
+ * can preallocate input buffers, or configure downstream components that require a maximum size on
+ * their buffers.
+ *
+ * Read-only. Required to be provided by components on all compressed streams.
+ */
+typedef C2StreamParam<C2Info, C2Uint32Value, kParamIndexMaxBufferSize> C2StreamMaxBufferSizeInfo;
+constexpr char C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE[] = "input.buffers.max-size";
+constexpr char C2_PARAMKEY_OUTPUT_MAX_BUFFER_SIZE[] = "output.buffers.max-size";
+
+/* ---------------------------------------- misc. state ---------------------------------------- */
+
+/**
+ * Tripped state,
+ *
+ * This state exists to be able to provide reasoning for a tripped state during normal
+ * interface operations, as well as to allow client to trip the component on demand.
+ */
+typedef C2GlobalParam<C2Tuning, C2BoolValue, kParamIndexTripped>
+        C2TrippedTuning;
+constexpr char C2_PARAMKEY_TRIPPED[] = "algo.tripped";
+
+/**
+ * Configuration counters.
+ *
+ * Configurations are tracked using three counters. The input counter is incremented exactly
+ * once with each work accepted by the component. The output counter is incremented exactly
+ * once with each work completed by the component (in the order of work completion). The
+ * global counter is incremented exactly once during to each config() call. These counters
+ * shall be read-only.
+ *
+ * TODO: these should be counters.
+ */
+typedef C2PortParam<C2Tuning, C2Uint64Value, kParamIndexConfigCounter> C2PortConfigCounterTuning;
+typedef C2GlobalParam<C2Tuning, C2Uint64Value, kParamIndexConfigCounter> C2ConfigCounterTuning;
+constexpr char C2_PARAMKEY_INPUT_COUNTER[] = "input.buffers.counter";
+constexpr char C2_PARAMKEY_OUTPUT_COUNTER[] = "output.buffers.counter";
+constexpr char C2_PARAMKEY_CONFIG_COUNTER[] = "algo.config.counter";
+
+/* ----------------------------------------- resources ----------------------------------------- */
+
+/**
+ * Resources needed and resources reserved for current configuration.
+ *
+ * Resources are tracked as a vector of positive numbers. Available resources are defined by
+ * the vendor.
+ *
+ * By default, no resources are reserved for a component. If resource reservation is successful,
+ * the component shall be able to use those resources exclusively. If however, the component is
+ * not using all of the reserved resources, those may be shared with other components.
+ *
+ * TODO: define some of the resources.
+ */
+typedef C2GlobalParam<C2Tuning, C2Uint64Array, kParamIndexResourcesNeeded> C2ResourcesNeededTuning;
+typedef C2GlobalParam<C2Tuning, C2Uint64Array, kParamIndexResourcesReserved>
+        C2ResourcesReservedTuning;
+constexpr char C2_PARAMKEY_RESOURCES_NEEDED[] = "resources.needed";
+constexpr char C2_PARAMKEY_RESOURCES_RESERVED[] = "resources.reserved";
+
+/**
+ * Operating rate.
+ *
+ * Operating rate is the expected rate of work through the component. Negative values is
+ * invalid.
+ *
+ * TODO: this could distinguish set value
+ */
+typedef C2GlobalParam<C2Tuning, C2FloatValue, kParamIndexOperatingRate> C2OperatingRateTuning;
+constexpr char C2_PARAMKEY_OPERATING_RATE[] = "algo.rate";
+
+/**
+ * Realtime / operating point.
+ *
+ * Priority value defines the operating point for the component. Operating points are defined by
+ * the vendor. Priority value of 0 means that the client requires operation at the given operating
+ * rate. Priority values -1 and below define operating points in decreasing performance. In this
+ * case client expects best effort without exceeding the specific operating point. This allows
+ * client to run components deeper in the background by using larger priority values. In these
+ * cases operating rate is a hint for the maximum rate that the client anticipates.
+ *
+ * Operating rate and priority are used in tandem. E.g. if there are components that run at a
+ * higher operating point (priority) it will make more resources available for components at
+ * a lower operating point, so operating rate can be used to gate those components.
+ *
+ * Positive priority values are not defined at the moment and shall be treated equivalent to 0.
+ */
+typedef C2GlobalParam<C2Tuning, C2Int32Value, kParamIndexRealTimePriority>
+        C2RealTimePriorityTuning;
+constexpr char C2_PARAMKEY_PRIORITY[] = "algo.priority";
+
+/* ------------------------------------- protected content ------------------------------------- */
+
+/**
+ * Secure mode.
+ */
+C2ENUM(C2Config::secure_mode_t, uint32_t,
+    SM_UNPROTECTED,    ///< no content protection
+    SM_READ_PROTECTED, ///< input and output buffers shall be protected from reading
+)
+
+typedef C2GlobalParam<C2Tuning, C2SimpleValueStruct<C2Config::secure_mode_t>, kParamIndexSecureMode>
+        C2SecureModeTuning;
+constexpr char C2_PARAMKEY_SECURE_MODE[] = "algo.secure-mode";
+
+/* ===================================== ENCODER COMPONENTS ===================================== */
+
+/**
+ * Bitrate
+ */
+typedef C2StreamParam<C2Info, C2Uint32Value, kParamIndexBitrate> C2StreamBitrateInfo;
+constexpr char C2_PARAMKEY_BITRATE[] = "coded.bitrate";
+
+/**
+ * Bitrate mode.
+ *
+ * TODO: refine this with bitrate ranges and suggested window
+ */
+C2ENUM(C2Config::bitrate_mode_t, uint32_t,
+    BITRATE_CONST_SKIP_ALLOWED = 0,      ///< constant bitrate, frame skipping allowed
+    BITRATE_CONST = 1,                   ///< constant bitrate, keep all frames
+    BITRATE_VARIABLE_SKIP_ALLOWED = 2,   ///< bitrate can vary, frame skipping allowed
+    BITRATE_VARIABLE = 3,                ///< bitrate can vary, keep all frames
+    BITRATE_IGNORE = 7,                  ///< bitrate can be exceeded at will to achieve
+                                         ///< quality or other settings
+
+    // bitrate modes are composed of the following flags
+    BITRATE_FLAG_KEEP_ALL_FRAMES = 1,
+    BITRATE_FLAG_CAN_VARY = 2,
+    BITRATE_FLAG_CAN_EXCEED = 4,
+)
+
+typedef C2StreamParam<C2Tuning, C2SimpleValueStruct<C2Config::bitrate_mode_t>,
+                kParamIndexBitrateMode>
+        C2StreamBitrateModeTuning;
+constexpr char C2_PARAMKEY_BITRATE_MODE[] = "algo.bitrate-mode";
+
+/**
+ * Quality.
+ *
+ * This is defined by each component, the higher the better the output quality at the expense of
+ * less compression efficiency. This setting is defined for the output streams in case the
+ * component can support varying quality on each stream, or as an output port tuning in case the
+ * quality is global to all streams.
+ */
+typedef C2StreamParam<C2Tuning, C2Uint32Value, kParamIndexQuality> C2StreamQualityTuning;
+typedef C2PortParam<C2Tuning, C2Uint32Value, kParamIndexQuality> C2QualityTuning;
+constexpr char C2_PARAMKEY_QUALITY[] = "algo.quality";
+
+/**
+ * Complexity.
+ *
+ * This is defined by each component, this higher the value, the more resources the component
+ * will use to produce better quality at the same compression efficiency or better compression
+ * efficiency at the same quality. This setting is defined for the output streams in case the
+ * component can support varying complexity on each stream, or as an output port tuning in case the
+ * quality is global to all streams
+ */
+typedef C2StreamParam<C2Tuning, C2Uint32Value, kParamIndexComplexity> C2StreamComplexityTuning;
+typedef C2PortParam<C2Tuning, C2Uint32Value, kParamIndexComplexity> C2ComplexityTuning;
+constexpr char C2_PARAMKEY_COMPLEXITY[] = "algo.complexity";
+
+/**
+ * Header (init-data) handling around sync frames.
+ */
+C2ENUM(C2Config::prepend_header_mode_t, uint32_t,
+    /**
+     * don't prepend header. Signal header only through C2StreamInitDataInfo.
+     */
+    PREPEND_HEADER_TO_NONE,
+
+    /**
+     * prepend header before the first output frame and thereafter before the next sync frame
+     * if it changes.
+     */
+    PREPEND_HEADER_ON_CHANGE,
+
+    /**
+     * prepend header before every sync frame.
+     */
+    PREPEND_HEADER_TO_ALL_SYNC,
+)
+
+typedef C2GlobalParam<C2Setting, C2SimpleValueStruct<C2Config::prepend_header_mode_t>,
+                kParamIndexPrependHeaderMode>
+        C2PrependHeaderModeSetting;
+constexpr char C2_PARAMKEY_PREPEND_HEADER_MODE[] = "output.buffers.prepend-header";
+
+/* =================================== IMAGE/VIDEO COMPONENTS =================================== */
+
+/*
+ * Order of transformation is:
+ *
+ * crop => (scaling => scaled-crop) => sample-aspect-ratio => flip => rotation
+ */
+
+/**
+ * Picture (image- and video frame) size.
+ *
+ * This is used for the output of the video decoder, and the input of the video encoder.
+ */
+typedef C2StreamParam<C2Info, C2PictureSizeStruct, kParamIndexPictureSize> C2StreamPictureSizeInfo;
+constexpr char C2_PARAMKEY_PICTURE_SIZE[] = "raw.size";
+
+/**
+ * Crop rectangle.
+ */
+struct C2RectStruct : C2Rect {
+    C2RectStruct() = default;
+    C2RectStruct(const C2Rect &rect) : C2Rect(rect) { }
+
+    bool operator==(const C2RectStruct &) = delete;
+    bool operator!=(const C2RectStruct &) = delete;
+
+    DEFINE_AND_DESCRIBE_BASE_C2STRUCT(Rect)
+    C2FIELD(width, "width")
+    C2FIELD(height, "height")
+    C2FIELD(left, "left")
+    C2FIELD(top, "top")
+};
+
+typedef C2StreamParam<C2Info, C2RectStruct, kParamIndexCropRect> C2StreamCropRectInfo;
+constexpr char C2_PARAMKEY_CROP_RECT[] = "raw.crop";
+constexpr char C2_PARAMKEY_CODED_CROP_RECT[] = "coded.crop";
+
+/**
+ * Pixel format.
+ */
+// TODO: define some
+
+typedef C2StreamParam<C2Info, C2Uint32Value, kParamIndexPixelFormat> C2StreamPixelFormatInfo;
+constexpr char C2_PARAMKEY_PIXEL_FORMAT[] = "raw.pixel-format";
+
+/**
+ * Extended rotation information also incorporating a flip.
+ *
+ * Rotation is counter clock-wise.
+ */
+struct C2RotationStruct {
+    C2RotationStruct(int32_t rotation = 0)
+        : flip(0), value(rotation) { }
+
+    int32_t flip;   ///< horizontal flip (left-right flip applied prior to rotation)
+    int32_t value;  ///< rotation in degrees counter clockwise
+
+    DEFINE_AND_DESCRIBE_BASE_C2STRUCT(Rotation)
+    C2FIELD(flip, "flip")
+    C2FIELD(value, "value")
+};
+
+typedef C2StreamParam<C2Info, C2RotationStruct, kParamIndexRotation> C2StreamRotationInfo;
+constexpr char C2_PARAMKEY_ROTATION[] = "raw.rotation";
+constexpr char C2_PARAMKEY_VUI_ROTATION[] = "coded.vui.rotation";
+
+/**
+ * Pixel (sample) aspect ratio.
+ */
+typedef C2StreamParam<C2Info, C2PictureSizeStruct, kParamIndexPixelAspectRatio>
+        C2StreamPixelAspectRatioInfo;
+constexpr char C2_PARAMKEY_PIXEL_ASPECT_RATIO[] = "raw.sar";
+constexpr char C2_PARAMKEY_VUI_PIXEL_ASPECT_RATIO[] = "coded.vui.sar";
+
+/**
+ * In-line scaling.
+ *
+ * Components can optionally support scaling of raw image/video frames.  Or scaling only a
+ * portion of raw image/video frames (scaled-crop).
+ */
+
+C2ENUM(C2Config::scaling_method_t, uint32_t,
+    SCALING_ARBITRARY,   ///< arbitrary, unspecified
+)
+
+typedef C2StreamParam<C2Tuning, C2SimpleValueStruct<C2Config::scaling_method_t>,
+                kParamIndexScalingMethod>
+        C2StreamScalingMethodTuning;
+constexpr char C2_PARAMKEY_SCALING_MODE[] = "raw.scaling-method";
+
+typedef C2StreamParam<C2Tuning, C2PictureSizeStruct, kParamIndexScaledPictureSize>
+        C2StreamScaledPictureSizeTuning;
+constexpr char C2_PARAMKEY_SCALED_PICTURE_SIZE[] = "raw.scaled-size";
+
+typedef C2StreamParam<C2Tuning, C2RectStruct, kParamIndexScaledCropRect>
+        C2StreamScaledCropRectTuning;
+constexpr char C2_PARAMKEY_SCALED_CROP_RECT[] = "raw.scaled-crop";
+
+/* ------------------------------------- color information ------------------------------------- */
+
+/**
+ * Color Info
+ *
+ * Chroma location can vary for top and bottom fields, so use an array, that can have 0 to 2
+ * values. Empty array is used for non YUV formats.
+ */
+
+struct C2Color {
+    enum matrix_t : uint32_t;  ///< matrix coefficient (YUV <=> RGB)
+    enum plane_layout_t : uint32_t;  ///< plane layout for flexible formats
+    enum primaries_t : uint32_t;  ///< color primaries and white point
+    enum range_t : uint32_t;  ///< range of color component values
+    enum subsampling_t : uint32_t;  ///< chroma subsampling
+    enum transfer_t : uint32_t;  ///< transfer function
+};
+
+/// Chroma subsampling
+C2ENUM(C2Color::subsampling_t, uint32_t,
+    MONOCHROME,     ///< there are no Cr nor Cb planes
+    MONOCHROME_ALPHA, ///< there are no Cr nor Cb planes, but there is an alpha plane
+    RGB,            ///< RGB
+    RGBA,           ///< RGBA
+    YUV_420,        ///< Cr and Cb planes are subsampled by 2 both horizontally and vertically
+    YUV_422,        ///< Cr and Cb planes are subsampled horizontally
+    YUV_444,        ///< Cr and Cb planes are not subsampled
+    YUVA_444,       ///< Cr and Cb planes are not subsampled, there is an alpha plane
+)
+
+struct C2ChromaOffsetStruct {
+    // chroma offsets defined by ITU
+    constexpr static C2ChromaOffsetStruct ITU_YUV_444() { return { 0.0f, 0.0f }; }
+    constexpr static C2ChromaOffsetStruct ITU_YUV_422() { return { 0.0f, 0.0f }; }
+    constexpr static C2ChromaOffsetStruct ITU_YUV_420_0() { return { 0.0f, 0.5f }; }
+    constexpr static C2ChromaOffsetStruct ITU_YUV_420_1() { return { 0.5f, 0.5f }; }
+    constexpr static C2ChromaOffsetStruct ITU_YUV_420_2() { return { 0.0f, 0.0f }; }
+    constexpr static C2ChromaOffsetStruct ITU_YUV_420_3() { return { 0.5f, 0.0f }; }
+    constexpr static C2ChromaOffsetStruct ITU_YUV_420_4() { return { 0.0f, 1.0f }; }
+    constexpr static C2ChromaOffsetStruct ITU_YUV_420_5() { return { 0.5f, 1.0f }; }
+
+    float x;    ///< x offset in pixels (towards right)
+    float y;    ///< y offset in pixels (towards down)
+
+    DEFINE_AND_DESCRIBE_C2STRUCT(ChromaOffset)
+    C2FIELD(x, "x")
+    C2FIELD(y, "y")
+};
+
+struct C2ColorInfoStruct {
+    C2ColorInfoStruct()
+        : bitDepth(8), subsampling(C2Color::YUV_420) { }
+
+    uint32_t bitDepth;
+    C2Color::subsampling_t subsampling;
+    C2ChromaOffsetStruct locations[]; // max 2 elements
+
+    C2ColorInfoStruct(
+            size_t /* flexCount */, uint32_t bitDepth_, C2Color::subsampling_t subsampling_)
+        : bitDepth(bitDepth_), subsampling(subsampling_) { }
+
+    C2ColorInfoStruct(
+            size_t flexCount, uint32_t bitDepth_, C2Color::subsampling_t subsampling_,
+            std::initializer_list<C2ChromaOffsetStruct> locations_)
+        : bitDepth(bitDepth_), subsampling(subsampling_) {
+        size_t ix = 0;
+        for (const C2ChromaOffsetStruct &location : locations_) {
+            if (ix == flexCount) {
+                break;
+            }
+            locations[ix] = location;
+            ++ix;
+        }
+    }
+
+    DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(ColorInfo, locations)
+    C2FIELD(bitDepth, "bit-depth")
+    C2FIELD(subsampling, "subsampling")
+    C2FIELD(locations, "locations")
+};
+
+typedef C2StreamParam<C2Info, C2ColorInfoStruct, kParamIndexColorInfo> C2StreamColorInfo;
+constexpr char C2_PARAMKEY_COLOR_INFO[] = "raw.color-format";
+constexpr char C2_PARAMKEY_CODED_COLOR_INFO[] = "coded.color-format";
+
+/**
+ * Color Aspects
+ */
+
+/* The meaning of the following enumerators is as described in ITU-T H.273. */
+
+/// Range
+C2ENUM(C2Color::range_t, uint32_t,
+    RANGE_UNSPECIFIED,          ///< range is unspecified
+    RANGE_FULL,                 ///< full range
+    RANGE_LIMITED,              ///< limited range
+
+    RANGE_VENDOR_START = 0x80,  ///< vendor-specific range values start here
+    RANGE_OTHER = 0XFF          ///< max value, reserved for undefined values
+)
+
+/// Color primaries
+C2ENUM(C2Color::primaries_t, uint32_t,
+    PRIMARIES_UNSPECIFIED,          ///< primaries are unspecified
+    PRIMARIES_BT709,                ///< Rec.ITU-R BT.709-6 or equivalent
+    PRIMARIES_BT470_M,              ///< Rec.ITU-R BT.470-6 System M or equivalent
+    PRIMARIES_BT601_625,            ///< Rec.ITU-R BT.601-6 625 or equivalent
+    PRIMARIES_BT601_525,            ///< Rec.ITU-R BT.601-6 525 or equivalent
+    PRIMARIES_GENERIC_FILM,         ///< Generic Film
+    PRIMARIES_BT2020,               ///< Rec.ITU-R BT.2020 or equivalent
+    PRIMARIES_RP431,                ///< SMPTE RP 431-2 or equivalent
+    PRIMARIES_EG432,                ///< SMPTE EG 432-1 or equivalent
+    PRIMARIES_EBU3213,              ///< EBU Tech.3213-E or equivalent
+                                    ///
+    PRIMARIES_VENDOR_START = 0x80,  ///< vendor-specific primaries values start here
+    PRIMARIES_OTHER = 0xff          ///< max value, reserved for undefined values
+)
+
+/// Transfer function
+C2ENUM(C2Color::transfer_t, uint32_t,
+    TRANSFER_UNSPECIFIED,           ///< transfer is unspecified
+    TRANSFER_LINEAR,                ///< Linear transfer characteristics
+    TRANSFER_SRGB,                  ///< sRGB or equivalent
+    TRANSFER_170M,                  ///< SMPTE 170M or equivalent (e.g. BT.601/709/2020)
+    TRANSFER_GAMMA22,               ///< Assumed display gamma 2.2
+    TRANSFER_GAMMA28,               ///< Assumed display gamma 2.8
+    TRANSFER_ST2084,                ///< SMPTE ST 2084 for 10/12/14/16 bit systems
+    TRANSFER_HLG,                   ///< ARIB STD-B67 hybrid-log-gamma
+
+    TRANSFER_240M = 0x40,           ///< SMPTE 240M or equivalent
+    TRANSFER_XVYCC,                 ///< IEC 61966-2-4 or equivalent
+    TRANSFER_BT1361,                ///< Rec.ITU-R BT.1361 extended gamut
+    TRANSFER_ST428,                 ///< SMPTE ST 428-1 or equivalent
+                                    ///
+    TRANSFER_VENDOR_START = 0x80,   ///< vendor-specific transfer values start here
+    TRANSFER_OTHER = 0xff           ///< max value, reserved for undefined values
+)
+
+/// Matrix coefficient
+C2ENUM(C2Color::matrix_t, uint32_t,
+    MATRIX_UNSPECIFIED,             ///< matrix coefficients are unspecified
+    MATRIX_BT709,                   ///< Rec.ITU-R BT.709-5 or equivalent
+    MATRIX_FCC47_73_682,            ///< FCC Title 47 CFR 73.682 or equivalent (KR=0.30, KB=0.11)
+    MATRIX_BT601,                   ///< Rec.ITU-R BT.470, BT.601-6 625 or equivalent
+    MATRIX_240M,                    ///< SMPTE 240M or equivalent
+    MATRIX_BT2020,                  ///< Rec.ITU-R BT.2020 non-constant luminance
+    MATRIX_BT2020_CONSTANT,         ///< Rec.ITU-R BT.2020 constant luminance
+    MATRIX_VENDOR_START = 0x80,     ///< vendor-specific matrix coefficient values start here
+    MATRIX_OTHER = 0xff,            ///< max value, reserved for undefined values
+)
+
+struct C2ColorAspectsStruct {
+    C2Color::range_t range;
+    C2Color::primaries_t primaries;
+    C2Color::transfer_t transfer;
+    C2Color::matrix_t matrix;
+
+    C2ColorAspectsStruct()
+        : range(C2Color::RANGE_UNSPECIFIED),
+          primaries(C2Color::PRIMARIES_UNSPECIFIED),
+          transfer(C2Color::TRANSFER_UNSPECIFIED),
+          matrix(C2Color::MATRIX_UNSPECIFIED) { }
+
+    C2ColorAspectsStruct(C2Color::range_t range_, C2Color::primaries_t primaries_,
+                         C2Color::transfer_t transfer_, C2Color::matrix_t matrix_)
+        : range(range_), primaries(primaries_), transfer(transfer_), matrix(matrix_) {}
+
+    DEFINE_AND_DESCRIBE_C2STRUCT(ColorAspects)
+    C2FIELD(range, "range")
+    C2FIELD(primaries, "primaries")
+    C2FIELD(transfer, "transfer")
+    C2FIELD(matrix, "matrix")
+};
+
+typedef C2StreamParam<C2Info, C2ColorAspectsStruct, kParamIndexColorAspects>
+        C2StreamColorAspectsInfo;
+constexpr char C2_PARAMKEY_COLOR_ASPECTS[] = "raw.color";
+constexpr char C2_PARAMKEY_VUI_COLOR_ASPECTS[] = "coded.vui.color";
+
+/**
+ * Default color aspects to use. These come from the container or client and shall be handled
+ * according to the coding standard.
+ */
+typedef C2StreamParam<C2Tuning, C2ColorAspectsStruct, kParamIndexDefaultColorAspects>
+        C2StreamColorAspectsTuning;
+constexpr char C2_PARAMKEY_DEFAULT_COLOR_ASPECTS[] = "default.color";
+
+/**
+ * HDR Static Metadata Info.
+ */
+struct C2ColorXyStruct {
+    float x; ///< x color coordinate in xyY space [0-1]
+    float y; ///< y color coordinate in xyY space [0-1]
+
+    DEFINE_AND_DESCRIBE_C2STRUCT(ColorXy)
+    C2FIELD(x, "x")
+    C2FIELD(y, "y")
+};
+
+struct C2MasteringDisplayColorVolumeStruct {
+    C2ColorXyStruct red;    ///< coordinates of red display primary
+    C2ColorXyStruct green;  ///< coordinates of green display primary
+    C2ColorXyStruct blue;   ///< coordinates of blue display primary
+    C2ColorXyStruct white;  ///< coordinates of white point
+
+    float maxLuminance;  ///< max display mastering luminance in cd/m^2
+    float minLuminance;  ///< min display mastering luminance in cd/m^2
+
+    DEFINE_AND_DESCRIBE_C2STRUCT(MasteringDisplayColorVolume)
+    C2FIELD(red, "red")
+    C2FIELD(green, "green")
+    C2FIELD(blue, "blue")
+    C2FIELD(white, "white")
+
+    C2FIELD(maxLuminance, "max-luminance")
+    C2FIELD(minLuminance, "min-luminance")
+};
+
+struct C2HdrStaticMetadataStruct {
+    C2MasteringDisplayColorVolumeStruct mastering;
+
+    // content descriptors
+    float maxCll;  ///< max content light level (pixel luminance) in cd/m^2
+    float maxFall; ///< max frame average light level (frame luminance) in cd/m^2
+
+    DEFINE_AND_DESCRIBE_BASE_C2STRUCT(HdrStaticMetadata)
+    C2FIELD(mastering, "mastering")
+    C2FIELD(maxCll, "max-cll")
+    C2FIELD(maxFall, "max-fall")
+};
+typedef C2StreamParam<C2Info, C2HdrStaticMetadataStruct, kParamIndexHdrStaticMetadata>
+        C2StreamHdrStaticInfo;
+constexpr char C2_PARAMKEY_HDR_STATIC_INFO[] = "raw.hdr-static-info";
+
+/**
+ * HDR10+ Metadata Info.
+ */
+typedef C2StreamParam<C2Info, C2BlobValue, kParamIndexHdr10PlusMetadata>
+        C2StreamHdr10PlusInfo;
+constexpr char C2_PARAMKEY_INPUT_HDR10_PLUS_INFO[] = "input.hdr10-plus-info";
+constexpr char C2_PARAMKEY_OUTPUT_HDR10_PLUS_INFO[] = "output.hdr10-plus-info";
+
+/* ------------------------------------ block-based coding ----------------------------------- */
+
+/**
+ * Block-size, block count and block rate. Used to determine or communicate profile-level
+ * requirements.
+ */
+typedef C2StreamParam<C2Info, C2PictureSizeStruct, kParamIndexBlockSize> C2StreamBlockSizeInfo;
+constexpr char C2_PARAMKEY_BLOCK_SIZE[] = "coded.block-size";
+
+typedef C2StreamParam<C2Info, C2Uint32Value, kParamIndexBlockCount> C2StreamBlockCountInfo;
+constexpr char C2_PARAMKEY_BLOCK_COUNT[] = "coded.block-count";
+
+typedef C2StreamParam<C2Info, C2FloatValue, kParamIndexBlockRate> C2StreamBlockRateInfo;
+constexpr char C2_PARAMKEY_BLOCK_RATE[] = "coded.block-rate";
+
+/* ====================================== VIDEO COMPONENTS ====================================== */
+
+/**
+ * Frame rate (coded and port for raw data)
+ *
+ * Coded frame rates are what is represented in the compressed bitstream and should correspond to
+ * the timestamp.
+ *
+ * Frame rates on raw ports should still correspond to the timestamps.
+ *
+ * For slow motion or timelapse recording, the timestamp shall be adjusted prior to feeding an
+ * encoder, and the time stretch parameter should be used to signal the relationship between
+ * timestamp and real-world time.
+ */
+typedef C2StreamParam<C2Info, C2FloatValue, kParamIndexFrameRate> C2StreamFrameRateInfo;
+constexpr char C2_PARAMKEY_FRAME_RATE[] = "coded.frame-rate";
+
+typedef C2PortParam<C2Info, C2FloatValue, kParamIndexFrameRate> C2PortFrameRateInfo;
+constexpr char C2_PARAMKEY_INPUT_FRAME_RATE[] = "input.frame-rate";
+constexpr char C2_PARAMKEY_OUTPUT_FRAME_RATE[] = "output.frame-rate";
+
+/**
+ * Time stretch. Ratio between real-world time and timestamp. E.g. time stretch of 4.0 means that
+ * timestamp grows 1/4 the speed of real-world time (e.g. 4x slo-mo input). This can be used to
+ * optimize encoding.
+ */
+typedef C2PortParam<C2Info, C2FloatValue, kParamIndexTimeStretch> C2PortTimeStretchInfo;
+constexpr char C2_PARAMKEY_INPUT_TIME_STRETCH[] = "input.time-stretch";
+constexpr char C2_PARAMKEY_OUTPUT_TIME_STRETCH[] = "output.time-stretch";
+
+/**
+ * Max video frame size.
+ */
+typedef C2StreamParam<C2Tuning, C2PictureSizeStruct, kParamIndexMaxPictureSize>
+        C2StreamMaxPictureSizeTuning;
+typedef C2StreamMaxPictureSizeTuning C2MaxVideoSizeHintPortSetting;
+constexpr char C2_PARAMKEY_MAX_PICTURE_SIZE[] = "raw.max-size";
+
+/**
+ * Picture type mask.
+ */
+C2ENUM(C2Config::picture_type_t, uint32_t,
+    SYNC_FRAME = (1 << 0),  ///< sync frame, e.g. IDR
+    I_FRAME    = (1 << 1),  ///< intra frame that is completely encoded
+    P_FRAME    = (1 << 2),  ///< inter predicted frame from previous frames
+    B_FRAME    = (1 << 3),  ///< backward predicted (out-of-order) frame
+)
+
+/**
+ * Allowed picture types.
+ */
+typedef C2StreamParam<C2Tuning, C2SimpleValueStruct<C2EasyEnum<C2Config::picture_type_t>>,
+                kParamIndexPictureTypeMask>
+        C2StreamPictureTypeMaskTuning;
+constexpr char C2_PARAMKEY_PICTURE_TYPE_MASK[] = "coding.picture-type-mask";
+
+/**
+ * Resulting picture type
+ */
+typedef C2StreamParam<C2Info, C2SimpleValueStruct<C2EasyEnum<C2Config::picture_type_t>>,
+                kParamIndexPictureType>
+        C2StreamPictureTypeInfo;
+typedef C2StreamPictureTypeInfo C2StreamPictureTypeMaskInfo;
+constexpr char C2_PARAMKEY_PICTURE_TYPE[] = "coded.picture-type";
+
+/**
+ * GOP specification.
+ *
+ * GOP is specified in layers between sync frames, by specifying the number of specific type of
+ * frames between the previous type (starting with sync frames for the first layer):
+ *
+ * E.g.
+ *      - 4 I frames between each sync frame
+ *      - 2 P frames between each I frame
+ *      - 1 B frame between each P frame
+ *
+ *      [ { I, 4 }, { P, 2 }, { B, 1 } ] ==> (Sync)BPBPB IBPBPB IBPBPB IBPBPB IBPBPB (Sync)BPBPB
+ *
+ * For infinite GOP, I layer can be omitted (as the first frame is always a sync frame.):
+ *
+ *      [ { P, MAX_UINT } ]   ==> (Sync)PPPPPPPPPPPPPPPPPP...
+ *
+ * Sync frames can also be requested on demand, and as a time-based interval. For time-based
+ * interval, if there hasn't been a sync frame in at least the given time, the next I frame shall
+ * be encoded as a sync frame.  For sync request, the next I frame shall be encoded as a sync frame.
+ *
+ * Temporal layering will determine GOP structure other than the I frame count between sync
+ * frames.
+ */
+struct C2GopLayerStruct {
+    C2GopLayerStruct() : type_((C2Config::picture_type_t)0), count(0) {}
+    C2GopLayerStruct(C2Config::picture_type_t type, uint32_t count_)
+        : type_(type), count(count_) { }
+
+    C2Config::picture_type_t type_;
+    uint32_t count;
+
+    DEFINE_AND_DESCRIBE_C2STRUCT(GopLayer)
+    C2FIELD(type_, "type")
+    C2FIELD(count, "count")
+};
+
+typedef C2StreamParam<C2Tuning, C2SimpleArrayStruct<C2GopLayerStruct>, kParamIndexGop>
+        C2StreamGopTuning;
+constexpr char C2_PARAMKEY_GOP[] = "coding.gop";
+
+/**
+ * Sync frame can be requested on demand by the client.
+ *
+ * If true, the next I frame shall be encoded as a sync frame. This config can be passed
+ * synchronously with the work, or directly to the component - leading to different result.
+ * If it is passed with work, it shall take effect when that work item is being processed (so
+ * the first I frame at or after that work item shall be a sync frame).
+ */
+typedef C2StreamParam<C2Tuning, C2EasyBoolValue, kParamIndexRequestSyncFrame>
+        C2StreamRequestSyncFrameTuning;
+constexpr char C2_PARAMKEY_REQUEST_SYNC_FRAME[] = "coding.request-sync-frame";
+
+/**
+ * Sync frame interval in time domain (timestamp).
+ *
+ * If there hasn't been a sync frame in at least this value, the next intra frame shall be encoded
+ * as a sync frame. The value of MAX_I64 or a negative value means no sync frames after the first
+ * frame. A value of 0 means all sync frames.
+ */
+typedef C2StreamParam<C2Tuning, C2Int64Value, kParamIndexSyncFrameInterval>
+        C2StreamSyncFrameIntervalTuning;
+constexpr char C2_PARAMKEY_SYNC_FRAME_INTERVAL[] = "coding.sync-frame-interval";
+
+/**
+ * Temporal layering
+ *
+ * Layer index is a value between 0 and layer count - 1. Layers with higher index have higher
+ * frequency:
+ *     0
+ *   1   1
+ *  2 2 2 2
+ */
+typedef C2StreamParam<C2Info, C2Uint32Value, kParamIndexLayerIndex> C2StreamLayerIndexInfo;
+constexpr char C2_PARAMKEY_LAYER_INDEX[] = "coded.layer-index";
+
+typedef C2StreamParam<C2Info, C2Uint32Value, kParamIndexLayerCount> C2StreamLayerCountInfo;
+constexpr char C2_PARAMKEY_LAYER_COUNT[] = "coded.layer-count";
+
+struct C2TemporalLayeringStruct {
+    C2TemporalLayeringStruct()
+        : layerCount(0), bLayerCount(0) { }
+
+    C2TemporalLayeringStruct(size_t /* flexCount */, uint32_t layerCount_, uint32_t bLayerCount_)
+        : layerCount(layerCount_), bLayerCount(c2_min(layerCount_, bLayerCount_)) { }
+
+    C2TemporalLayeringStruct(size_t flexCount, uint32_t layerCount_, uint32_t bLayerCount_,
+                             std::initializer_list<float> ratios)
+        : layerCount(layerCount_), bLayerCount(c2_min(layerCount_, bLayerCount_)) {
+        size_t ix = 0;
+        for (float ratio : ratios) {
+            if (ix == flexCount) {
+                break;
+            }
+            bitrateRatios[ix++] = ratio;
+        }
+    }
+
+    uint32_t layerCount;     ///< total number of layers (0 means no temporal layering)
+    uint32_t bLayerCount;    ///< total number of bidirectional layers (<= num layers)
+    /**
+     * Bitrate budgets for each layer and the layers below, given as a ratio of the total
+     * stream bitrate. This can be omitted or partially specififed by the client while configuring,
+     * in which case the component shall fill in appropriate values for the missing layers.
+     * This must be provided by the component when queried for at least layer count - 1 (as the
+     * last layer's budget is always 1.0).
+     */
+    float bitrateRatios[];   ///< 1.0-based
+
+    DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(TemporalLayering, bitrateRatios)
+    C2FIELD(layerCount, "layer-count")
+    C2FIELD(bLayerCount, "b-layer-count")
+    C2FIELD(bitrateRatios, "bitrate-ratios")
+};
+
+typedef C2StreamParam<C2Tuning, C2TemporalLayeringStruct, kParamIndexTemporalLayering>
+        C2StreamTemporalLayeringTuning;
+constexpr char C2_PARAMKEY_TEMPORAL_LAYERING[] = "coding.temporal-layering";
+
+/**
+ * Intra-refresh.
+ */
+
+C2ENUM(C2Config::intra_refresh_mode_t, uint32_t,
+    INTRA_REFRESH_DISABLED,     ///< no intra refresh
+    INTRA_REFRESH_ARBITRARY,    ///< arbitrary, unspecified
+)
+
+struct C2IntraRefreshStruct {
+    C2IntraRefreshStruct()
+        : mode(C2Config::INTRA_REFRESH_DISABLED), period(0.) { }
+
+    C2IntraRefreshStruct(C2Config::intra_refresh_mode_t mode_, float period_)
+        : mode(mode_), period(period_) { }
+
+    C2Config::intra_refresh_mode_t mode; ///< refresh mode
+    float period;         ///< intra refresh period in frames (must be >= 1), 0 means disabled
+
+    DEFINE_AND_DESCRIBE_C2STRUCT(IntraRefresh)
+    C2FIELD(mode, "mode")
+    C2FIELD(period, "period")
+};
+
+typedef C2StreamParam<C2Tuning, C2IntraRefreshStruct, kParamIndexIntraRefresh>
+        C2StreamIntraRefreshTuning;
+constexpr char C2_PARAMKEY_INTRA_REFRESH[] = "coding.intra-refresh";
+
+/* ====================================== IMAGE COMPONENTS ====================================== */
+
+/**
+ * Tile layout.
+ *
+ * This described how the image is decomposed into tiles.
+ */
+C2ENUM(C2Config::scan_order_t, uint32_t,
+    SCAN_LEFT_TO_RIGHT_THEN_DOWN
+)
+
+struct C2TileLayoutStruct {
+    C2PictureSizeStruct tile;       ///< tile size
+    uint32_t columnCount;           ///< number of tiles horizontally
+    uint32_t rowCount;              ///< number of tiles vertically
+    C2Config::scan_order_t order;   ///< tile order
+
+    DEFINE_AND_DESCRIBE_C2STRUCT(TileLayout)
+    C2FIELD(tile, "tile")
+    C2FIELD(columnCount, "columns")
+    C2FIELD(rowCount, "rows")
+    C2FIELD(order, "order")
+};
+
+typedef C2StreamParam<C2Info, C2TileLayoutStruct, kParamIndexTileLayout> C2StreamTileLayoutInfo;
+constexpr char C2_PARAMKEY_TILE_LAYOUT[] = "coded.tile-layout";
+
+/**
+ * Tile handling.
+ *
+ * Whether to concatenate tiles or output them each.
+ */
+C2ENUM(C2Config::tiling_mode_t, uint32_t,
+    TILING_SEPARATE,    ///< output each tile in a separate onWorkDone
+    TILING_CONCATENATE  ///< output one work completion per frame (concatenate tiles)
+)
+
+typedef C2StreamParam<C2Tuning, C2TileLayoutStruct, kParamIndexTileHandling>
+        C2StreamTileHandlingTuning;
+constexpr char C2_PARAMKEY_TILE_HANDLING[] = "coding.tile-handling";
+
+/* ====================================== AUDIO COMPONENTS ====================================== */
+
+/**
+ * Sample rate
+ */
+typedef C2StreamParam<C2Info, C2Uint32Value, kParamIndexSampleRate> C2StreamSampleRateInfo;
+constexpr char C2_PARAMKEY_SAMPLE_RATE[] = "raw.sample-rate";
+constexpr char C2_PARAMKEY_CODED_SAMPLE_RATE[] = "coded.sample-rate";
+
+/**
+ * Channel count.
+ */
+typedef C2StreamParam<C2Info, C2Uint32Value, kParamIndexChannelCount> C2StreamChannelCountInfo;
+constexpr char C2_PARAMKEY_CHANNEL_COUNT[] = "raw.channel-count";
+constexpr char C2_PARAMKEY_CODED_CHANNEL_COUNT[] = "coded.channel-count";
+
+/**
+ * Max channel count. Used to limit the number of coded or decoded channels.
+ */
+typedef C2StreamParam<C2Info, C2Uint32Value, kParamIndexMaxChannelCount> C2StreamMaxChannelCountInfo;
+constexpr char C2_PARAMKEY_MAX_CHANNEL_COUNT[] = "raw.max-channel-count";
+constexpr char C2_PARAMKEY_MAX_CODED_CHANNEL_COUNT[] = "coded.max-channel-count";
+
+/**
+ * Audio sample format (PCM encoding)
+ */
+C2ENUM(C2Config::pcm_encoding_t, uint32_t,
+    PCM_16,
+    PCM_8,
+    PCM_FLOAT
+)
+
+typedef C2StreamParam<C2Info, C2SimpleValueStruct<C2Config::pcm_encoding_t>, kParamIndexPcmEncoding>
+        C2StreamPcmEncodingInfo;
+constexpr char C2_PARAMKEY_PCM_ENCODING[] = "raw.pcm-encoding";
+constexpr char C2_PARAMKEY_CODED_PCM_ENCODING[] = "coded.pcm-encoding";
+
+/**
+ * AAC SBR Mode. Used during encoding.
+ */
+C2ENUM(C2Config::aac_sbr_mode_t, uint32_t,
+    AAC_SBR_OFF,
+    AAC_SBR_SINGLE_RATE,
+    AAC_SBR_DUAL_RATE,
+    AAC_SBR_AUTO ///< let the codec decide
+)
+
+typedef C2StreamParam<C2Info, C2SimpleValueStruct<C2Config::aac_sbr_mode_t>, kParamIndexAacSbrMode>
+        C2StreamAacSbrModeTuning;
+constexpr char C2_PARAMKEY_AAC_SBR_MODE[] = "coding.aac-sbr-mode";
+
+/**
+ * DRC Compression. Used during decoding.
+ */
+C2ENUM(C2Config::drc_compression_mode_t, int32_t,
+    DRC_COMPRESSION_ODM_DEFAULT, ///< odm's default
+    DRC_COMPRESSION_NONE,
+    DRC_COMPRESSION_LIGHT,
+    DRC_COMPRESSION_HEAVY ///<
+)
+
+typedef C2StreamParam<C2Info, C2SimpleValueStruct<C2Config::drc_compression_mode_t>,
+                kParamIndexDrcCompression>
+        C2StreamDrcCompressionModeTuning;
+constexpr char C2_PARAMKEY_DRC_COMPRESSION_MODE[] = "coding.drc.compression-mode";
+
+/**
+ * DRC target reference level in dBFS. Used during decoding.
+ */
+typedef C2StreamParam<C2Info, C2FloatValue, kParamIndexDrcTargetReferenceLevel>
+        C2StreamDrcTargetReferenceLevelTuning;
+constexpr char C2_PARAMKEY_DRC_TARGET_REFERENCE_LEVEL[] = "coding.drc.reference-level";
+
+/**
+ * DRC target reference level in dBFS. Used during decoding.
+ */
+typedef C2StreamParam<C2Info, C2FloatValue, kParamIndexDrcEncodedTargetLevel>
+        C2StreamDrcEncodedTargetLevelTuning;
+constexpr char C2_PARAMKEY_DRC_ENCODED_TARGET_LEVEL[] = "coding.drc.encoded-level";
+
+/**
+ * DRC target reference level in dBFS. Used during decoding.
+ */
+typedef C2StreamParam<C2Info, C2FloatValue, kParamIndexDrcBoostFactor>
+        C2StreamDrcBoostFactorTuning;
+constexpr char C2_PARAMKEY_DRC_BOOST_FACTOR[] = "coding.drc.boost-factor";
+
+/**
+ * DRC target reference level in dBFS. Used during decoding.
+ */
+typedef C2StreamParam<C2Info, C2FloatValue, kParamIndexDrcAttenuationFactor>
+        C2StreamDrcAttenuationFactorTuning;
+constexpr char C2_PARAMKEY_DRC_ATTENUATION_FACTOR[] = "coding.drc.attenuation-factor";
+
+/**
+ * DRC Effect Type (see ISO 23003-4) Uniform Dynamic Range Control. Used during decoding.
+ */
+C2ENUM(C2Config::drc_effect_type_t, int32_t,
+    DRC_EFFECT_ODM_DEFAULT = -2, ///< odm's default
+    DRC_EFFECT_OFF = -1,    ///< no DRC
+    DRC_EFFECT_NONE = 0,    ///< no DRC except to prevent clipping
+    DRC_EFFECT_LATE_NIGHT,
+    DRC_EFFECT_NOISY_ENVIRONMENT,
+    DRC_EFFECT_LIMITED_PLAYBACK_RANGE,
+    DRC_EFFECT_LOW_PLAYBACK_LEVEL,
+    DRC_EFFECT_DIALOG_ENHANCEMENT,
+    DRC_EFFECT_GENERAL_COMPRESSION
+)
+
+typedef C2StreamParam<C2Info, C2SimpleValueStruct<C2Config::drc_effect_type_t>,
+                kParamIndexDrcEffectType>
+        C2StreamDrcEffectTypeTuning;
+constexpr char C2_PARAMKEY_DRC_EFFECT_TYPE[] = "coding.drc.effect-type";
+
+/* --------------------------------------- AAC components --------------------------------------- */
+
+/**
+ * AAC stream format
+ */
+C2ENUM(C2Config::aac_packaging_t, uint32_t,
+    AAC_PACKAGING_RAW,
+    AAC_PACKAGING_ADTS
+)
+
+typedef C2StreamParam<C2Info, C2SimpleValueStruct<C2EasyEnum<C2Config::aac_packaging_t>>,
+        kParamIndexAacPackaging> C2StreamAacPackagingInfo;
+typedef C2StreamAacPackagingInfo C2StreamAacFormatInfo;
+constexpr char C2_PARAMKEY_AAC_PACKAGING[] = "coded.aac-packaging";
+
+/* ================================ PLATFORM-DEFINED PARAMETERS ================================ */
+
+/**
+ * Platform level and features.
+ */
+enum C2Config::platform_level_t : uint32_t {
+    PLATFORM_P,   ///< support for Android 9.0 feature set
+};
+
+// read-only
+typedef C2GlobalParam<C2Setting, C2SimpleValueStruct<C2Config::platform_level_t>,
+                kParamIndexPlatformLevel>
+        C2PlatformLevelSetting;
+constexpr char C2_PARAMKEY_PLATFORM_LEVEL[] = "api.platform-level";
+
+enum C2Config::platform_feature_t : uint64_t {
+    // no platform-specific features have been defined
+};
+
+// read-only
+typedef C2GlobalParam<C2Setting, C2SimpleValueStruct<C2Config::platform_feature_t>,
+                kParamIndexPlatformFeatures>
+        C2PlatformFeaturesSetting;
+constexpr char C2_PARAMKEY_PLATFORM_FEATURES[] = "api.platform-features";
+
+/**
+ * This structure describes the preferred ion allocation parameters for a given memory usage.
+ */
+struct C2StoreIonUsageStruct {
+    inline C2StoreIonUsageStruct() {
+        memset(this, 0, sizeof(*this));
+    }
+
+    inline C2StoreIonUsageStruct(uint64_t usage_, uint32_t capacity_)
+        : usage(usage_), capacity(capacity_), heapMask(0), allocFlags(0), minAlignment(0) { }
+
+    uint64_t usage;        ///< C2MemoryUsage
+    uint32_t capacity;     ///< capacity
+    int32_t heapMask;      ///< ion heapMask
+    int32_t allocFlags;    ///< ion allocation flags
+    uint32_t minAlignment; ///< minimum alignment
+
+    DEFINE_AND_DESCRIBE_C2STRUCT(StoreIonUsage)
+    C2FIELD(usage, "usage")
+    C2FIELD(capacity, "capacity")
+    C2FIELD(heapMask, "heap-mask")
+    C2FIELD(allocFlags, "alloc-flags")
+    C2FIELD(minAlignment, "min-alignment")
+};
+
+// store, private
+typedef C2GlobalParam<C2Info, C2StoreIonUsageStruct, kParamIndexStoreIonUsage>
+        C2StoreIonUsageInfo;
+
+/**
+ * Flexible pixel format descriptors
+ */
+struct C2FlexiblePixelFormatDescriptorStruct {
+    uint32_t pixelFormat;
+    uint32_t bitDepth;
+    C2Color::subsampling_t subsampling;
+    C2Color::plane_layout_t layout;
+
+    DEFINE_AND_DESCRIBE_C2STRUCT(FlexiblePixelFormatDescriptor)
+    C2FIELD(pixelFormat, "pixel-format")
+    C2FIELD(bitDepth, "bit-depth")
+    C2FIELD(subsampling, "subsampling")
+    C2FIELD(layout, "layout")
+};
+
+/**
+ * Plane layout of flexible pixel formats.
+ *
+ * bpp: bytes per color component, e.g. 1 for 8-bit formats, and 2 for 10-16-bit formats.
+ */
+C2ENUM(C2Color::plane_layout_t, uint32_t,
+       /** Unknown layout */
+       UNKNOWN_LAYOUT,
+
+       /** Planar layout with rows of each plane packed (colInc = bpp) */
+       PLANAR_PACKED,
+
+       /** Semiplanar layout with rows of each plane packed (colInc_Y/A = bpp (planar),
+        *  colInc_Cb/Cr = 2*bpp (interleaved). Used only for YUV(A) formats. */
+       SEMIPLANAR_PACKED,
+
+       /** Interleaved packed. colInc = N*bpp (N are the number of color components) */
+       INTERLEAVED_PACKED,
+
+       /** Interleaved aligned. colInc = smallest power of 2 >= N*bpp (N are the number of color
+        *  components) */
+       INTERLEAVED_ALIGNED
+)
+
+typedef C2GlobalParam<C2Info, C2SimpleArrayStruct<C2FlexiblePixelFormatDescriptorStruct>,
+                kParamIndexFlexiblePixelFormatDescriptors>
+        C2StoreFlexiblePixelFormatDescriptorsInfo;
+
+/**
+ * This structure describes the android dataspace for a raw video/image frame.
+ */
+typedef C2StreamParam<C2Info, C2Uint32Value, kParamIndexDataSpace> C2StreamDataSpaceInfo;
+constexpr char C2_PARAMKEY_DATA_SPACE[] = "raw.data-space";
+
+/**
+ * This structure describes the android surface scaling mode for a raw video/image frame.
+ */
+typedef C2StreamParam<C2Info, C2Uint32Value, kParamIndexSurfaceScaling> C2StreamSurfaceScalingInfo;
+constexpr char C2_PARAMKEY_SURFACE_SCALING_MODE[] = "raw.surface-scaling";
+
+/* ======================================= INPUT SURFACE ======================================= */
+
+/**
+ * Input surface EOS
+ */
+typedef C2GlobalParam<C2Tuning, C2EasyBoolValue, kParamIndexInputSurfaceEos>
+        C2InputSurfaceEosTuning;
+constexpr char C2_PARAMKEY_INPUT_SURFACE_EOS[] = "input-surface.eos";
+
+/**
+ * Start/suspend/resume/stop controls and timestamps for input surface.
+ *
+ * TODO: make these counters
+ */
+
+struct C2TimedControlStruct {
+    c2_bool_t enabled; ///< control is enabled
+    int64_t timestamp; ///< if enabled, time the control should take effect
+
+    C2TimedControlStruct()
+        : enabled(C2_FALSE), timestamp(0) { }
+
+    /* implicit */ C2TimedControlStruct(uint64_t timestamp_)
+        : enabled(C2_TRUE), timestamp(timestamp_) { }
+
+    DEFINE_AND_DESCRIBE_C2STRUCT(TimedControl)
+    C2FIELD(enabled,   "enabled")
+    C2FIELD(timestamp, "timestamp")
+};
+
+typedef C2PortParam<C2Tuning, C2TimedControlStruct, kParamIndexStartAt>
+        C2PortStartTimestampTuning;
+constexpr char C2_PARAMKEY_INPUT_SURFACE_START_AT[] = "input-surface.start";
+typedef C2PortParam<C2Tuning, C2TimedControlStruct, kParamIndexSuspendAt>
+        C2PortSuspendTimestampTuning;
+constexpr char C2_PARAMKEY_INPUT_SURFACE_SUSPEND_AT[] = "input-surface.suspend";
+typedef C2PortParam<C2Tuning, C2TimedControlStruct, kParamIndexResumeAt>
+        C2PortResumeTimestampTuning;
+constexpr char C2_PARAMKEY_INPUT_SURFACE_RESUME_AT[] = "input-surface.resume";
+typedef C2PortParam<C2Tuning, C2TimedControlStruct, kParamIndexStopAt>
+        C2PortStopTimestampTuning;
+constexpr char C2_PARAMKEY_INPUT_SURFACE_STOP_AT[] = "input-surface.stop";
+
+/**
+ * Time offset for input surface. Input timestamp to codec is surface buffer timestamp plus this
+ * time offset.
+ */
+typedef C2GlobalParam<C2Tuning, C2Int64Value, kParamIndexTimeOffset> C2ComponentTimeOffsetTuning;
+constexpr char C2_PARAMKEY_INPUT_SURFACE_TIME_OFFSET[] = "input-surface.time-offset";
+
+/**
+ * Minimum fps for input surface.
+ *
+ * Repeat frame to meet this.
+ */
+typedef C2PortParam<C2Tuning, C2FloatValue, kParamIndexMinFrameRate> C2PortMinFrameRateTuning;
+constexpr char C2_PARAMKEY_INPUT_SURFACE_MIN_FRAME_RATE[] = "input-surface.min-frame-rate";
+
+/**
+ * Timestamp adjustment (override) for input surface buffers. These control the input timestamp
+ * fed to the codec, but do not impact the output timestamp.
+ */
+struct C2TimestampGapAdjustmentStruct {
+    /// control modes
+    enum mode_t : uint32_t;
+
+    inline C2TimestampGapAdjustmentStruct();
+
+    inline C2TimestampGapAdjustmentStruct(mode_t mode_, uint64_t value_)
+        : mode(mode_), value(value_) { }
+
+    mode_t mode;    ///< control mode
+    uint64_t value; ///< control value for gap between two timestamp
+
+    DEFINE_AND_DESCRIBE_C2STRUCT(TimestampGapAdjustment)
+    C2FIELD(mode, "mode")
+    C2FIELD(value, "value")
+};
+
+C2ENUM(C2TimestampGapAdjustmentStruct::mode_t, uint32_t,
+    NONE,
+    MIN_GAP,
+    FIXED_GAP,
+);
+
+inline C2TimestampGapAdjustmentStruct::C2TimestampGapAdjustmentStruct()
+    : mode(C2TimestampGapAdjustmentStruct::NONE), value(0) { }
+
+typedef C2PortParam<C2Tuning, C2TimestampGapAdjustmentStruct> C2PortTimestampGapTuning;
+constexpr char C2_PARAMKEY_INPUT_SURFACE_TIMESTAMP_ADJUSTMENT[] = "input-surface.timestamp-adjustment";
+
+/// @}
+
+#endif  // C2CONFIG_H_
diff --git a/media/codec2/core/include/C2Enum.h b/media/codec2/core/include/C2Enum.h
new file mode 100644
index 0000000..b0fad8f
--- /dev/null
+++ b/media/codec2/core/include/C2Enum.h
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef C2ENUM_H_
+#define C2ENUM_H_
+
+#include <C2Param.h>
+#include <_C2MacroUtils.h>
+
+#include <utility>
+#include <vector>
+
+/** \file
+ * Tools for easier enum support.
+ */
+
+/// \cond INTERNAL
+
+/* ---------------------------- UTILITIES FOR ENUMERATION REFLECTION ---------------------------- */
+
+/**
+ * Utility class that allows ignoring enum value assignment (e.g. both '(_C2EnumConst)kValue = x'
+ * and '(_C2EnumConst)kValue' will eval to kValue.
+ */
+template<typename T>
+class _C2EnumConst {
+public:
+    // implicit conversion from T
+    inline _C2EnumConst(T value) : _mValue(value) {}
+    // implicit conversion to T
+    inline operator T() { return _mValue; }
+    // implicit conversion to C2Value::Primitive
+    inline operator C2Value::Primitive() { return (T)_mValue; }
+    // ignore assignment and return T here to avoid implicit conversion to T later
+    inline T &operator =(T value __unused) { return _mValue; }
+private:
+    T _mValue;
+};
+
+/// mapper to get name of enum
+/// \note this will contain any initialization, which we will remove when converting to lower-case
+#define _C2_GET_ENUM_NAME(x, y) #x
+/// mapper to get value of enum
+#define _C2_GET_ENUM_VALUE(x, type) (_C2EnumConst<type>)x
+
+/// \endcond
+
+class _C2EnumUtils {
+    static C2String camelCaseToDashed(C2String name);
+
+    static std::vector<C2String> sanitizeEnumValueNames(
+            const std::vector<C2StringLiteral> names,
+            C2StringLiteral _prefix = nullptr);
+
+    friend class C2UtilTest_EnumUtilsTest_Test;
+
+public:
+    // this may not be used...
+    static C2_HIDE std::vector<C2String> parseEnumValuesFromString(C2StringLiteral value);
+
+    template<typename T>
+    static C2_HIDE C2FieldDescriptor::NamedValuesType sanitizeEnumValues(
+            std::vector<T> values,
+            std::vector<C2StringLiteral> names,
+            C2StringLiteral prefix = nullptr) {
+        C2FieldDescriptor::NamedValuesType namedValues;
+        std::vector<C2String> sanitizedNames = sanitizeEnumValueNames(names, prefix);
+        for (size_t i = 0; i < values.size() && i < sanitizedNames.size(); ++i) {
+            namedValues.emplace_back(sanitizedNames[i], values[i]);
+        }
+        return namedValues;
+    }
+
+    template<typename E>
+    static C2_HIDE C2FieldDescriptor::NamedValuesType customEnumValues(
+            std::vector<std::pair<C2StringLiteral, E>> items) {
+        C2FieldDescriptor::NamedValuesType namedValues;
+        for (auto &item : items) {
+            namedValues.emplace_back(item.first, item.second);
+        }
+        return namedValues;
+    }
+};
+
+#define DEFINE_C2_ENUM_VALUE_AUTO_HELPER(name, type, prefix, ...) \
+    _DEFINE_C2_ENUM_VALUE_AUTO_HELPER(__C2_GENERATE_GLOBAL_VARS__, name, type, prefix, \
+            ##__VA_ARGS__)
+#define _DEFINE_C2_ENUM_VALUE_AUTO_HELPER(enabled, name, type, prefix, ...) \
+    __DEFINE_C2_ENUM_VALUE_AUTO_HELPER(enabled, name, type, prefix, ##__VA_ARGS__)
+#define __DEFINE_C2_ENUM_VALUE_AUTO_HELPER(enabled, name, type, prefix, ...) \
+    ___DEFINE_C2_ENUM_VALUE_AUTO_HELPER##enabled(name, type, prefix, ##__VA_ARGS__)
+#define ___DEFINE_C2_ENUM_VALUE_AUTO_HELPER(name, type, prefix, ...) \
+template<> \
+C2FieldDescriptor::NamedValuesType C2FieldDescriptor::namedValuesFor(const name &r __unused) { \
+    return _C2EnumUtils::sanitizeEnumValues( \
+            std::vector<C2Value::Primitive> { _C2_MAP(_C2_GET_ENUM_VALUE, type, __VA_ARGS__) }, \
+            { _C2_MAP(_C2_GET_ENUM_NAME, type, __VA_ARGS__) }, \
+            prefix); \
+}
+#define ___DEFINE_C2_ENUM_VALUE_AUTO_HELPER__C2_GENERATE_GLOBAL_VARS__(name, type, prefix, ...)
+
+#define DEFINE_C2_ENUM_VALUE_CUSTOM_HELPER(name, names) \
+    _DEFINE_C2_ENUM_VALUE_CUSTOM_HELPER(__C2_GENERATE_GLOBAL_VARS__, name, names)
+#define _DEFINE_C2_ENUM_VALUE_CUSTOM_HELPER(enabled, name, names) \
+    __DEFINE_C2_ENUM_VALUE_CUSTOM_HELPER(enabled, name, names)
+#define __DEFINE_C2_ENUM_VALUE_CUSTOM_HELPER(enabled, name, names) \
+    ___DEFINE_C2_ENUM_VALUE_CUSTOM_HELPER##enabled(name, names)
+#define ___DEFINE_C2_ENUM_VALUE_CUSTOM_HELPER(name, names) \
+template<> \
+C2FieldDescriptor::NamedValuesType C2FieldDescriptor::namedValuesFor(const name &r __unused) { \
+    return _C2EnumUtils::customEnumValues( \
+            std::vector<std::pair<C2StringLiteral, name>> names); \
+}
+#define ___DEFINE_C2_ENUM_VALUE_CUSTOM_HELPER__C2_GENERATE_GLOBAL_VARS__(name, names)
+
+/**
+ * Defines an enum type with the default named value mapper. The default mapper
+ * finds and removes the longest common prefix across all of the enum value names, and
+ * replaces camel-case separators with dashes ('-').
+ *
+ * This macro must be used in the global scope and namespace.
+ *
+ *  ~~~~~~~~~~~~~ (.cpp)
+ *  C2ENUM(c2_enum_t, uint32_t,
+ *    C2_VALUE1,
+ *    C2_VALUE2 = 5,
+ *    C2_VALUE3 = C2_VALUE1 + 1)
+ *  // named values are: C2_VALUE1 => "1", C2_VALUE2 => "2", ...
+ *  // longest common prefix is "C2_VALUE"
+ *  ~~~~~~~~~~~~~
+ *
+ * \param name name of the enum type (This can be an inner class enum.)
+ * \param type underlying type
+ */
+#define C2ENUM(name, type, ...) \
+enum name : type { __VA_ARGS__ }; \
+DEFINE_C2_ENUM_VALUE_AUTO_HELPER(name, type, nullptr, __VA_ARGS__)
+
+/**
+ * Defines an enum type with the default named value mapper but custom prefix. The default
+ * mapper removes the prefix from all of the enum value names (if present), and
+ * inserts dashes at camel-case separators (lowHigh becomes low-high) and also replaces
+ * non-leading underscores with dashes ('-').
+ *
+ * This macro must be used in the global scope and namespace.
+ *
+ *  ~~~~~~~~~~~~~ (.cpp)
+ *  C2ENUM_CUSTOM_PREFIX(c2_enum_t, uint32_t, "C2_",
+ *    C2_VALUE1,
+ *    C2_VALUE2 = 5,
+ *    C2_VALUE3 = C2_VALUE1 + 1)
+ *  // named values are: C2_VALUE1 => "VALUE1", C2_VALUE2 => "VALUE2", ...
+ *  ~~~~~~~~~~~~~
+ *
+ * \param name name of the enum type (This can be an inner class enum.)
+ * \param type underlying type
+ * \param prefix prefix to remove
+ */
+#define C2ENUM_CUSTOM_PREFIX(name, type, prefix, ...) \
+enum name : type { __VA_ARGS__ }; \
+DEFINE_C2_ENUM_VALUE_AUTO_HELPER(name, type, prefix, __VA_ARGS__)
+
+/**
+ * Defines an enum type with custom names.
+ *
+ * This macro must be used in the global scope and namespace.
+ *
+ *  ~~~~~~~~~~~~~ (.cpp)
+ *  C2ENUM_CUSTOM_NAMES(SomeStruct::c2_enum_t, uint32_t, ({
+ *      { "One", SomeStruct::C2_VALUE1 },
+ *      { "Two", SomeStruct::C2_VALUE2 },
+ *      { "Three", SomeStruct::C2_VALUE3 } }),
+ *    C2_VALUE1,
+ *    C2_VALUE2 = 5,
+ *    C2_VALUE3 = C2_VALUE1 + 1)
+ *
+ *  // named values are: C2_VALUE1 => "One", C2_VALUE2 => "Two", ...
+ *  ~~~~~~~~~~~~~
+ */
+#define C2ENUM_CUSTOM_NAMES(name, type, names, ...) \
+enum name : type { __VA_ARGS__ }; \
+DEFINE_C2_ENUM_VALUE_CUSTOM_HELPER(name, names)
+
+/**
+ * Make enums usable as their integral types.
+ *
+ * Note: this makes them not usable in printf()
+ */
+template<class E>
+struct C2EasyEnum {
+    using U = typename std::underlying_type<E>::type;
+    E value;
+    // define conversion functions
+    inline constexpr operator E() const { return value; }
+    inline constexpr C2EasyEnum(E value_) : value(value_) { }
+    inline constexpr C2EasyEnum(U value_) : value(E(value_)) { }
+    inline constexpr C2EasyEnum() = default;
+};
+
+// make C2EasyEnum behave like a regular enum
+
+namespace std {
+    template<typename E>
+    struct underlying_type<C2EasyEnum<E>> {
+        typedef typename underlying_type<E>::type type;
+    };
+
+    template<typename E>
+    struct is_enum<C2EasyEnum<E>> {
+        constexpr static bool value = true;
+    };
+}
+
+#endif  // C2ENUM_H_
+
diff --git a/media/codec2/core/include/C2Param.h b/media/codec2/core/include/C2Param.h
new file mode 100644
index 0000000..51d417a
--- /dev/null
+++ b/media/codec2/core/include/C2Param.h
@@ -0,0 +1,1687 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef C2PARAM_H_
+#define C2PARAM_H_
+
+#include <C2.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <algorithm>
+#include <string>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+/// \addtogroup Parameters
+/// @{
+
+/// \defgroup internal Internal helpers.
+
+/*!
+ * \file
+ * PARAMETERS: SETTINGs, TUNINGs, and INFOs
+ * ===
+ *
+ * These represent miscellaneous control and metadata information and are likely copied into
+ * kernel space. Therefore, these are C-like structures designed to carry just a small amount of
+ * information. We are using C++ to be able to add constructors, as well as non-virtual and class
+ * methods.
+ *
+ * ==Specification details:
+ *
+ * Restrictions:
+ *   - must be POD struct, e.g. no vtable (no virtual destructor)
+ *   - must have the same size in 64-bit and 32-bit mode (no size_t)
+ *   - as such, no pointer members
+ *   - some common member field names are reserved as they are defined as methods for all
+ *     parameters:
+ *     they are: size, type, kind, index and stream
+ *
+ * Behavior:
+ * - Params can be global (not related to input or output), related to input or output,
+ *   or related to an input/output stream.
+ * - All params are queried/set using a unique param index, which incorporates a potential stream
+ *   index and/or port.
+ * - Querying (supported) params MUST never fail.
+ * - All params MUST have default values.
+ * - If some fields have "unsupported" or "invalid" values during setting, this SHOULD be
+ *   communicated to the app.
+ *   a) Ideally, this should be avoided.  When setting parameters, in general, component should do
+ *     "best effort" to apply all settings. It should change "invalid/unsupported" values to the
+ *     nearest supported values.
+ *   - This is communicated to the client by changing the source values in tune()/
+ *     configure().
+ *   b) If falling back to a supported value is absolutely impossible, the component SHALL return
+ *     an error for the specific setting, but should continue to apply other settings.
+ *     TODO: this currently may result in unintended results.
+ *
+ * **NOTE:** unlike OMX, params are not versioned. Instead, a new struct with new param index
+ * SHALL be added as new versions are required.
+ *
+ * The proper subtype (Setting, Info or Param) is incorporated into the class type. Define structs
+ * to define multiple subtyped versions of related parameters.
+ *
+ * ==Implementation details:
+ *
+ * - Use macros to define parameters
+ * - All parameters must have a default constructor
+ *   - This is only used for instantiating the class in source (e.g. will not be used
+ *     when building a parameter by the framework from key/value pairs.)
+ */
+
+/// \ingroup internal
+
+/**
+ * Parameter base class.
+ */
+struct C2Param {
+    // param index encompasses the following:
+    //
+    // - kind (setting, tuning, info, struct)
+    // - scope
+    //   - direction (global, input, output)
+    //   - stream flag
+    //   - stream ID (usually 0)
+    // - and the parameter's type (core index)
+    //   - flexible parameter flag
+    //   - vendor extension flag
+    //   - type index (this includes the vendor extension flag)
+    //
+    // layout:
+    //
+    //        kind : <------- scope -------> : <----- core index ----->
+    //      +------+-----+---+------+--------+----|------+--------------+
+    //      | kind | dir | - |stream|streamID|flex|vendor|  type index  |
+    //      +------+-----+---+------+--------+----+------+--------------+
+    //  bit: 31..30 29.28       25   24 .. 17  16    15   14    ..     0
+    //
+public:
+    /**
+     * C2Param kinds, usable as bitmaps.
+     */
+    enum kind_t : uint32_t {
+        NONE    = 0,
+        STRUCT  = (1 << 0),
+        INFO    = (1 << 1),
+        SETTING = (1 << 2),
+        TUNING  = (1 << 3) | SETTING, // tunings are settings
+    };
+
+    /**
+     * The parameter type index specifies the underlying parameter type of a parameter as
+     * an integer value.
+     *
+     * Parameter types are divided into two groups: platform types and vendor types.
+     *
+     * Platform types are defined by the platform and are common for all implementations.
+     *
+     * Vendor types are defined by each vendors, so they may differ between implementations.
+     * It is recommended that vendor types be the same for all implementations by a specific
+     * vendor.
+     */
+    typedef uint32_t type_index_t;
+    enum : uint32_t {
+            TYPE_INDEX_VENDOR_START = 0x00008000, ///< vendor indices SHALL start after this
+    };
+
+    /**
+     * Core index is the underlying parameter type for a parameter. It is used to describe the
+     * layout of the parameter structure regardless of the component or parameter kind/scope.
+     *
+     * It is used to identify and distinguish global parameters, and also parameters on a given
+     * port or stream. They must be unique for the set of global parameters, as well as for the
+     * set of parameters on each port or each stream, but the same core index can be used for
+     * parameters on different streams or ports, as well as for global parameters and port/stream
+     * parameters.
+     *
+     * Multiple parameter types can share the same layout.
+     *
+     * \note The layout for all parameters with the same core index across all components must
+     * be identical.
+     */
+    struct CoreIndex {
+    //public:
+        enum : uint32_t {
+            IS_FLEX_FLAG    = 0x00010000,
+            IS_REQUEST_FLAG = 0x00020000,
+        };
+
+    protected:
+        enum : uint32_t {
+            KIND_MASK      = 0xC0000000,
+            KIND_STRUCT    = 0x00000000,
+            KIND_TUNING    = 0x40000000,
+            KIND_SETTING   = 0x80000000,
+            KIND_INFO      = 0xC0000000,
+
+            DIR_MASK       = 0x30000000,
+            DIR_GLOBAL     = 0x20000000,
+            DIR_UNDEFINED  = DIR_MASK, // MUST have all bits set
+            DIR_INPUT      = 0x00000000,
+            DIR_OUTPUT     = 0x10000000,
+
+            IS_STREAM_FLAG  = 0x02000000,
+            STREAM_ID_MASK  = 0x01F00000,
+            STREAM_ID_SHIFT = 20,
+            MAX_STREAM_ID   = STREAM_ID_MASK >> STREAM_ID_SHIFT,
+            STREAM_MASK     = IS_STREAM_FLAG | STREAM_ID_MASK,
+
+            IS_VENDOR_FLAG  = 0x00008000,
+            TYPE_INDEX_MASK = 0x0000FFFF,
+            CORE_MASK       = TYPE_INDEX_MASK | IS_FLEX_FLAG,
+        };
+
+    public:
+        /// constructor/conversion from uint32_t
+        inline CoreIndex(uint32_t index) : mIndex(index) { }
+
+        // no conversion from uint64_t
+        inline CoreIndex(uint64_t index) = delete;
+
+        /// returns true iff this is a vendor extension parameter
+        inline bool isVendor() const { return mIndex & IS_VENDOR_FLAG; }
+
+        /// returns true iff this is a flexible parameter (with variable size)
+        inline bool isFlexible() const { return mIndex & IS_FLEX_FLAG; }
+
+        /// returns the core index
+        /// This is the combination of the parameter type index and the flexible flag.
+        inline uint32_t coreIndex() const { return mIndex & CORE_MASK; }
+
+        /// returns the parameter type index
+        inline type_index_t typeIndex() const { return mIndex & TYPE_INDEX_MASK; }
+
+        DEFINE_FIELD_AND_MASK_BASED_COMPARISON_OPERATORS(CoreIndex, mIndex, CORE_MASK)
+
+    protected:
+        uint32_t mIndex;
+    };
+
+    /**
+     * Type encompasses the parameter's kind (tuning, setting, info), its scope (whether the
+     * parameter is global, input or output, and whether it is for a stream) and the its base
+     * index (which also determines its layout).
+     */
+    struct Type : public CoreIndex {
+    //public:
+        /// returns true iff this is a global parameter (not for input nor output)
+        inline bool isGlobal() const { return (mIndex & DIR_MASK) == DIR_GLOBAL; }
+        /// returns true iff this is an input or input stream parameter
+        inline bool forInput() const { return (mIndex & DIR_MASK) == DIR_INPUT; }
+        /// returns true iff this is an output or output stream parameter
+        inline bool forOutput() const { return (mIndex & DIR_MASK) == DIR_OUTPUT; }
+
+        /// returns true iff this is a stream parameter
+        inline bool forStream() const { return mIndex & IS_STREAM_FLAG; }
+        /// returns true iff this is a port (input or output) parameter
+        inline bool forPort() const   { return !forStream() && !isGlobal(); }
+
+        /// returns the parameter type: the parameter index without the stream ID
+        inline uint32_t type() const { return mIndex & (~STREAM_ID_MASK); }
+
+        /// return the kind (struct, info, setting or tuning) of this param
+        inline kind_t kind() const {
+            switch (mIndex & KIND_MASK) {
+                case KIND_STRUCT: return STRUCT;
+                case KIND_INFO: return INFO;
+                case KIND_SETTING: return SETTING;
+                case KIND_TUNING: return TUNING;
+                default: return NONE; // should not happen
+            }
+        }
+
+        /// constructor/conversion from uint32_t
+        inline Type(uint32_t index) : CoreIndex(index) { }
+
+        // no conversion from uint64_t
+        inline Type(uint64_t index) = delete;
+
+        DEFINE_FIELD_AND_MASK_BASED_COMPARISON_OPERATORS(Type, mIndex, ~STREAM_ID_MASK)
+
+    private:
+        friend struct C2Param;   // for setPort()
+        friend struct C2Tuning;  // for KIND_TUNING
+        friend struct C2Setting; // for KIND_SETTING
+        friend struct C2Info;    // for KIND_INFO
+        // for DIR_GLOBAL
+        template<typename T, typename S, int I, class F> friend struct C2GlobalParam;
+        template<typename T, typename S, int I, class F> friend struct C2PortParam;   // for kDir*
+        template<typename T, typename S, int I, class F> friend struct C2StreamParam; // for kDir*
+        friend struct _C2ParamInspector; // for testing
+
+        /**
+         * Sets the port/stream direction.
+         * @return true on success, false if could not set direction (e.g. it is global param).
+         */
+        inline bool setPort(bool output) {
+            if (isGlobal()) {
+                return false;
+            } else {
+                mIndex = (mIndex & ~DIR_MASK) | (output ? DIR_OUTPUT : DIR_INPUT);
+                return true;
+            }
+        }
+    };
+
+    /**
+     * index encompasses all remaining information: basically the stream ID.
+     */
+    struct Index : public Type {
+        /// returns the index as uint32_t
+        inline operator uint32_t() const { return mIndex; }
+
+        /// constructor/conversion from uint32_t
+        inline Index(uint32_t index) : Type(index) { }
+
+        /// copy constructor
+        inline Index(const Index &index) = default;
+
+        // no conversion from uint64_t
+        inline Index(uint64_t index) = delete;
+
+        /// returns the stream ID or ~0 if not a stream
+        inline unsigned stream() const {
+            return forStream() ? rawStream() : ~0U;
+        }
+
+        /// Returns an index with stream field set to given stream.
+        inline Index withStream(unsigned stream) const {
+            Index ix = mIndex;
+            (void)ix.setStream(stream);
+            return ix;
+        }
+
+        /// sets the port (direction). Returns true iff successful.
+        inline Index withPort(bool output) const {
+            Index ix = mIndex;
+            (void)ix.setPort(output);
+            return ix;
+        }
+
+        DEFINE_FIELD_BASED_COMPARISON_OPERATORS(Index, mIndex)
+
+    private:
+        friend struct C2Param;           // for setStream, MakeStreamId, isValid
+        friend struct _C2ParamInspector; // for testing
+
+        /**
+         * @return true if the type is valid, e.g. direction is not undefined AND
+         * stream is 0 if not a stream param.
+         */
+        inline bool isValid() const {
+            // there is no Type::isValid (even though some of this check could be
+            // performed on types) as this is only used on index...
+            return (forStream() ? rawStream() < MAX_STREAM_ID : rawStream() == 0)
+                    && (mIndex & DIR_MASK) != DIR_UNDEFINED;
+        }
+
+        /// returns the raw stream ID field
+        inline unsigned rawStream() const {
+            return (mIndex & STREAM_ID_MASK) >> STREAM_ID_SHIFT;
+        }
+
+        /// returns the streamId bitfield for a given |stream|. If stream is invalid,
+        /// returns an invalid bitfield.
+        inline static uint32_t MakeStreamId(unsigned stream) {
+            // saturate stream ID (max value is invalid)
+            if (stream > MAX_STREAM_ID) {
+                stream = MAX_STREAM_ID;
+            }
+            return (stream << STREAM_ID_SHIFT) & STREAM_ID_MASK;
+        }
+
+        inline bool convertToStream(bool output, unsigned stream) {
+            mIndex = (mIndex & ~DIR_MASK) | IS_STREAM_FLAG;
+            (void)setPort(output);
+            return setStream(stream);
+        }
+
+        inline void convertToPort(bool output) {
+            mIndex = (mIndex & ~(DIR_MASK | IS_STREAM_FLAG));
+            (void)setPort(output);
+        }
+
+        inline void convertToGlobal() {
+            mIndex = (mIndex & ~(DIR_MASK | IS_STREAM_FLAG)) | DIR_GLOBAL;
+        }
+
+        inline void convertToRequest() {
+            mIndex = mIndex | IS_REQUEST_FLAG;
+        }
+
+        /**
+         * Sets the stream index.
+         * \return true on success, false if could not set index (e.g. not a stream param).
+         */
+        inline bool setStream(unsigned stream) {
+            if (forStream()) {
+                mIndex = (mIndex & ~STREAM_ID_MASK) | MakeStreamId(stream);
+                return this->stream() < MAX_STREAM_ID;
+            }
+            return false;
+        }
+    };
+
+public:
+    // public getters for Index methods
+
+    /// returns true iff this is a vendor extension parameter
+    inline bool isVendor() const { return _mIndex.isVendor(); }
+    /// returns true iff this is a flexible parameter
+    inline bool isFlexible() const { return _mIndex.isFlexible(); }
+    /// returns true iff this is a global parameter (not for input nor output)
+    inline bool isGlobal() const { return _mIndex.isGlobal(); }
+    /// returns true iff this is an input or input stream parameter
+    inline bool forInput() const { return _mIndex.forInput(); }
+    /// returns true iff this is an output or output stream parameter
+    inline bool forOutput() const { return _mIndex.forOutput(); }
+
+    /// returns true iff this is a stream parameter
+    inline bool forStream() const { return _mIndex.forStream(); }
+    /// returns true iff this is a port (input or output) parameter
+    inline bool forPort() const   { return _mIndex.forPort(); }
+
+    /// returns the stream ID or ~0 if not a stream
+    inline unsigned stream() const { return _mIndex.stream(); }
+
+    /// returns the parameter type: the parameter index without the stream ID
+    inline Type type() const { return _mIndex.type(); }
+
+    /// returns the index of this parameter
+    /// \todo: should we restrict this to C2ParamField?
+    inline uint32_t index() const { return (uint32_t)_mIndex; }
+
+    /// returns the core index of this parameter
+    inline CoreIndex coreIndex() const { return _mIndex.coreIndex(); }
+
+    /// returns the kind of this parameter
+    inline kind_t kind() const { return _mIndex.kind(); }
+
+    /// returns the size of the parameter or 0 if the parameter is invalid
+    inline size_t size() const { return _mSize; }
+
+    /// returns true iff the parameter is valid
+    inline operator bool() const { return _mIndex.isValid() && _mSize > 0; }
+
+    /// returns true iff the parameter is invalid
+    inline bool operator!() const { return !operator bool(); }
+
+    // equality is done by memcmp (use equals() to prevent any overread)
+    inline bool operator==(const C2Param &o) const {
+        return equals(o) && memcmp(this, &o, _mSize) == 0;
+    }
+    inline bool operator!=(const C2Param &o) const { return !operator==(o); }
+
+    /// safe(r) type cast from pointer and size
+    inline static C2Param* From(void *addr, size_t len) {
+        // _mSize must fit into size, but really C2Param must also to be a valid param
+        if (len < sizeof(C2Param)) {
+            return nullptr;
+        }
+        // _mSize must match length
+        C2Param *param = (C2Param*)addr;
+        if (param->_mSize != len) {
+            return nullptr;
+        }
+        return param;
+    }
+
+    /// Returns managed clone of |orig| at heap.
+    inline static std::unique_ptr<C2Param> Copy(const C2Param &orig) {
+        if (orig.size() == 0) {
+            return nullptr;
+        }
+        void *mem = ::operator new (orig.size());
+        C2Param *param = new (mem) C2Param(orig.size(), orig._mIndex);
+        param->updateFrom(orig);
+        return std::unique_ptr<C2Param>(param);
+    }
+
+    /// Returns managed clone of |orig| as a stream parameter at heap.
+    inline static std::unique_ptr<C2Param> CopyAsStream(
+            const C2Param &orig, bool output, unsigned stream) {
+        std::unique_ptr<C2Param> copy = Copy(orig);
+        if (copy) {
+            copy->_mIndex.convertToStream(output, stream);
+        }
+        return copy;
+    }
+
+    /// Returns managed clone of |orig| as a port parameter at heap.
+    inline static std::unique_ptr<C2Param> CopyAsPort(const C2Param &orig, bool output) {
+        std::unique_ptr<C2Param> copy = Copy(orig);
+        if (copy) {
+            copy->_mIndex.convertToPort(output);
+        }
+        return copy;
+    }
+
+    /// Returns managed clone of |orig| as a global parameter at heap.
+    inline static std::unique_ptr<C2Param> CopyAsGlobal(const C2Param &orig) {
+        std::unique_ptr<C2Param> copy = Copy(orig);
+        if (copy) {
+            copy->_mIndex.convertToGlobal();
+        }
+        return copy;
+    }
+
+    /// Returns managed clone of |orig| as a stream parameter at heap.
+    inline static std::unique_ptr<C2Param> CopyAsRequest(const C2Param &orig) {
+        std::unique_ptr<C2Param> copy = Copy(orig);
+        if (copy) {
+            copy->_mIndex.convertToRequest();
+        }
+        return copy;
+    }
+
+#if 0
+    template<typename P, class=decltype(C2Param(P()))>
+    P *As() { return P::From(this); }
+    template<typename P>
+    const P *As() const { return const_cast<const P*>(P::From(const_cast<C2Param*>(this))); }
+#endif
+
+protected:
+    /// sets the stream field. Returns true iff successful.
+    inline bool setStream(unsigned stream) {
+        return _mIndex.setStream(stream);
+    }
+
+    /// sets the port (direction). Returns true iff successful.
+    inline bool setPort(bool output) {
+        return _mIndex.setPort(output);
+    }
+
+public:
+    /// invalidate this parameter. There is no recovery from this call; e.g. parameter
+    /// cannot be 'corrected' to be valid.
+    inline void invalidate() { _mSize = 0; }
+
+    // if other is the same kind of (valid) param as this, copy it into this and return true.
+    // otherwise, do not copy anything, and return false.
+    inline bool updateFrom(const C2Param &other) {
+        if (other._mSize <= _mSize && other._mIndex == _mIndex && _mSize > 0) {
+            memcpy(this, &other, other._mSize);
+            return true;
+        }
+        return false;
+    }
+
+protected:
+    // returns |o| if it is a null ptr, or if can suitably be a param of given |type| (e.g. has
+    // same type (ignoring stream ID), and size). Otherwise, returns null. If |checkDir| is false,
+    // allow undefined or different direction (e.g. as constructed from C2PortParam() vs.
+    // C2PortParam::input), but still require equivalent type (stream, port or global); otherwise,
+    // return null.
+    inline static const C2Param* IfSuitable(
+            const C2Param* o, size_t size, Type type, size_t flexSize = 0, bool checkDir = true) {
+        if (o == nullptr || o->_mSize < size || (flexSize && ((o->_mSize - size) % flexSize))) {
+            return nullptr;
+        } else if (checkDir) {
+            return o->_mIndex.type() == type.mIndex ? o : nullptr;
+        } else if (o->_mIndex.isGlobal()) {
+            return nullptr;
+        } else {
+            return ((o->_mIndex.type() ^ type.mIndex) & ~Type::DIR_MASK) ? nullptr : o;
+        }
+    }
+
+    /// base constructor
+    inline C2Param(uint32_t paramSize, Index paramIndex)
+        : _mSize(paramSize),
+          _mIndex(paramIndex) {
+        if (paramSize > sizeof(C2Param)) {
+            memset(this + 1, 0, paramSize - sizeof(C2Param));
+        }
+    }
+
+    /// base constructor with stream set
+    inline C2Param(uint32_t paramSize, Index paramIndex, unsigned stream)
+        : _mSize(paramSize),
+          _mIndex(paramIndex | Index::MakeStreamId(stream)) {
+        if (paramSize > sizeof(C2Param)) {
+            memset(this + 1, 0, paramSize - sizeof(C2Param));
+        }
+        if (!forStream()) {
+            invalidate();
+        }
+    }
+
+private:
+    friend struct _C2ParamInspector; // for testing
+
+    /// returns true iff |o| has the same size and index as this. This performs the
+    /// basic check for equality.
+    inline bool equals(const C2Param &o) const {
+        return _mSize == o._mSize && _mIndex == o._mIndex;
+    }
+
+    uint32_t _mSize;
+    Index _mIndex;
+};
+
+/// \ingroup internal
+/// allow C2Params access to private methods, e.g. constructors
+#define C2PARAM_MAKE_FRIENDS \
+    template<typename U, typename S, int I, class F> friend struct C2GlobalParam; \
+    template<typename U, typename S, int I, class F> friend struct C2PortParam; \
+    template<typename U, typename S, int I, class F> friend struct C2StreamParam; \
+
+/**
+ * Setting base structure for component method signatures. Wrap constructors.
+ */
+struct C2Setting : public C2Param {
+protected:
+    template<typename ...Args>
+    inline C2Setting(const Args(&... args)) : C2Param(args...) { }
+public: // TODO
+    enum : uint32_t { PARAM_KIND = Type::KIND_SETTING };
+};
+
+/**
+ * Tuning base structure for component method signatures. Wrap constructors.
+ */
+struct C2Tuning : public C2Setting {
+protected:
+    template<typename ...Args>
+    inline C2Tuning(const Args(&... args)) : C2Setting(args...) { }
+public: // TODO
+    enum : uint32_t { PARAM_KIND = Type::KIND_TUNING };
+};
+
+/**
+ * Info base structure for component method signatures. Wrap constructors.
+ */
+struct C2Info : public C2Param {
+protected:
+    template<typename ...Args>
+    inline C2Info(const Args(&... args)) : C2Param(args...) { }
+public: // TODO
+    enum : uint32_t { PARAM_KIND = Type::KIND_INFO };
+};
+
+/**
+ * Structure uniquely specifying a field in an arbitrary structure.
+ *
+ * \note This structure is used differently in C2FieldDescriptor to
+ * identify array fields, such that _mSize is the size of each element. This is
+ * because the field descriptor contains the array-length, and we want to keep
+ * a relevant element size for variable length arrays.
+ */
+struct _C2FieldId {
+//public:
+    /**
+     * Constructor used for C2FieldDescriptor that removes the array extent.
+     *
+     * \param[in] offset pointer to the field in an object at address 0.
+     */
+    template<typename T, class B=typename std::remove_extent<T>::type>
+    inline _C2FieldId(T* offset)
+        : // offset is from "0" so will fit on 32-bits
+          _mOffset((uint32_t)(uintptr_t)(offset)),
+          _mSize(sizeof(B)) { }
+
+    /**
+     * Direct constructor from offset and size.
+     *
+     * \param[in] offset offset of the field.
+     * \param[in] size size of the field.
+     */
+    inline _C2FieldId(size_t offset, size_t size)
+        : _mOffset(offset), _mSize(size) {}
+
+    /**
+     * Constructor used to identify a field in an object.
+     *
+     * \param U[type] pointer to the object that contains this field. This is needed in case the
+     *        field is in an (inherited) base class, in which case T will be that base class.
+     * \param pm[im] member pointer to the field
+     */
+    template<typename R, typename T, typename U, typename B=typename std::remove_extent<R>::type>
+    inline _C2FieldId(U *, R T::* pm)
+        : _mOffset((uint32_t)(uintptr_t)(&(((U*)256)->*pm)) - 256u),
+          _mSize(sizeof(B)) { }
+
+    /**
+     * Constructor used to identify a field in an object.
+     *
+     * \param pm[im] member pointer to the field
+     */
+    template<typename R, typename T, typename B=typename std::remove_extent<R>::type>
+    inline _C2FieldId(R T::* pm)
+        : _mOffset((uint32_t)(uintptr_t)(&(((T*)0)->*pm))),
+          _mSize(sizeof(B)) { }
+
+    inline bool operator==(const _C2FieldId &other) const {
+        return _mOffset == other._mOffset && _mSize == other._mSize;
+    }
+
+    inline bool operator<(const _C2FieldId &other) const {
+        return _mOffset < other._mOffset ||
+            // NOTE: order parent structure before sub field
+            (_mOffset == other._mOffset && _mSize > other._mSize);
+    }
+
+    DEFINE_OTHER_COMPARISON_OPERATORS(_C2FieldId)
+
+#if 0
+    inline uint32_t offset() const { return _mOffset; }
+    inline uint32_t size() const { return _mSize; }
+#endif
+
+#if defined(FRIEND_TEST)
+    friend void PrintTo(const _C2FieldId &d, ::std::ostream*);
+#endif
+
+private:
+    friend struct _C2ParamInspector;
+    friend struct C2FieldDescriptor;
+
+    uint32_t _mOffset; // offset of field
+    uint32_t _mSize;   // size of field
+};
+
+/**
+ * Structure uniquely specifying a 'field' in a configuration. The field
+ * can be a field of a configuration, a subfield of a field of a configuration,
+ * and even the whole configuration. Moreover, if the field can point to an
+ * element in a array field, or to the entire array field.
+ *
+ * This structure is used for querying supported values for a field, as well
+ * as communicating configuration failures and conflicts when trying to change
+ * a configuration for a component/interface or a store.
+ */
+struct C2ParamField {
+//public:
+    /**
+     * Create a field identifier using a configuration parameter (variable),
+     * and a pointer to member.
+     *
+     * ~~~~~~~~~~~~~ (.cpp)
+     *
+     * struct C2SomeParam {
+     *   uint32_t mField;
+     *   uint32_t mArray[2];
+     *   C2OtherStruct mStruct;
+     *   uint32_t mFlexArray[];
+     * } *mParam;
+     *
+     * C2ParamField(mParam, &mParam->mField);
+     * C2ParamField(mParam, &mParam->mArray);
+     * C2ParamField(mParam, &mParam->mArray[0]);
+     * C2ParamField(mParam, &mParam->mStruct.mSubField);
+     * C2ParamField(mParam, &mParam->mFlexArray);
+     * C2ParamField(mParam, &mParam->mFlexArray[2]);
+     *
+     * ~~~~~~~~~~~~~
+     *
+     * \todo fix what this is for T[] (for now size becomes T[1])
+     *
+     * \note this does not work for 64-bit members as it triggers a
+     * 'taking address of packed member' warning.
+     *
+     * \param param pointer to parameter
+     * \param offset member pointer
+     */
+    template<typename S, typename T>
+    inline C2ParamField(S* param, T* offset)
+        : _mIndex(param->index()),
+          _mFieldId((T*)((uintptr_t)offset - (uintptr_t)param)) {}
+
+    template<typename S, typename T>
+    inline static C2ParamField Make(S& param, T& offset) {
+        return C2ParamField(param.index(), (uintptr_t)&offset - (uintptr_t)&param, sizeof(T));
+    }
+
+    /**
+     * Create a field identifier using a configuration parameter (variable),
+     * and a member pointer. This method cannot be used to refer to an
+     * array element or a subfield.
+     *
+     * ~~~~~~~~~~~~~ (.cpp)
+     *
+     * C2SomeParam mParam;
+     * C2ParamField(&mParam, &C2SomeParam::mMemberField);
+     *
+     * ~~~~~~~~~~~~~
+     *
+     * \param p pointer to parameter
+     * \param T member pointer to the field member
+     */
+    template<typename R, typename T, typename U>
+    inline C2ParamField(U *p, R T::* pm) : _mIndex(p->index()), _mFieldId(p, pm) { }
+
+    /**
+     * Create a field identifier to a configuration parameter (variable).
+     *
+     * ~~~~~~~~~~~~~ (.cpp)
+     *
+     * C2SomeParam mParam;
+     * C2ParamField(&mParam);
+     *
+     * ~~~~~~~~~~~~~
+     *
+     * \param param pointer to parameter
+     */
+    template<typename S>
+    inline C2ParamField(S* param)
+        : _mIndex(param->index()), _mFieldId(0u, param->size()) { }
+
+    /** Copy constructor. */
+    inline C2ParamField(const C2ParamField &other) = default;
+
+    /**
+     * Equality operator.
+     */
+    inline bool operator==(const C2ParamField &other) const {
+        return _mIndex == other._mIndex && _mFieldId == other._mFieldId;
+    }
+
+    /**
+     * Ordering operator.
+     */
+    inline bool operator<(const C2ParamField &other) const {
+        return _mIndex < other._mIndex ||
+            (_mIndex == other._mIndex && _mFieldId < other._mFieldId);
+    }
+
+    DEFINE_OTHER_COMPARISON_OPERATORS(C2ParamField)
+
+protected:
+    inline C2ParamField(C2Param::Index index, uint32_t offset, uint32_t size)
+        : _mIndex(index), _mFieldId(offset, size) {}
+
+private:
+    friend struct _C2ParamInspector;
+
+    C2Param::Index _mIndex; ///< parameter index
+    _C2FieldId _mFieldId;   ///< field identifier
+};
+
+/**
+ * A shared (union) representation of numeric values
+ */
+class C2Value {
+public:
+    /// A union of supported primitive types.
+    union Primitive {
+        // first member is always zero initialized so it must be the largest
+        uint64_t    u64;   ///< uint64_t value
+        int64_t     i64;   ///< int64_t value
+        c2_cntr64_t c64;   ///< c2_cntr64_t value
+        uint32_t    u32;   ///< uint32_t value
+        int32_t     i32;   ///< int32_t value
+        c2_cntr32_t c32;   ///< c2_cntr32_t value
+        float       fp;    ///< float value
+
+        // constructors - implicit
+        Primitive(uint64_t value)    : u64(value) { }
+        Primitive(int64_t value)     : i64(value) { }
+        Primitive(c2_cntr64_t value) : c64(value) { }
+        Primitive(uint32_t value)    : u32(value) { }
+        Primitive(int32_t value)     : i32(value) { }
+        Primitive(c2_cntr32_t value) : c32(value) { }
+        Primitive(uint8_t value)     : u32(value) { }
+        Primitive(char value)        : i32(value) { }
+        Primitive(float value)       : fp(value)  { }
+
+        // allow construction from enum type
+        template<typename E, typename = typename std::enable_if<std::is_enum<E>::value>::type>
+        Primitive(E value)
+            : Primitive(static_cast<typename std::underlying_type<E>::type>(value)) { }
+
+        Primitive() : u64(0) { }
+
+        /** gets value out of the union */
+        template<typename T> const T &ref() const;
+
+        // verify that we can assume standard aliasing
+        static_assert(sizeof(u64) == sizeof(i64), "");
+        static_assert(sizeof(u64) == sizeof(c64), "");
+        static_assert(sizeof(u32) == sizeof(i32), "");
+        static_assert(sizeof(u32) == sizeof(c32), "");
+    };
+    // verify that we can assume standard aliasing
+    static_assert(offsetof(Primitive, u64) == offsetof(Primitive, i64), "");
+    static_assert(offsetof(Primitive, u64) == offsetof(Primitive, c64), "");
+    static_assert(offsetof(Primitive, u32) == offsetof(Primitive, i32), "");
+    static_assert(offsetof(Primitive, u32) == offsetof(Primitive, c32), "");
+
+    enum type_t : uint32_t {
+        NO_INIT,
+        INT32,
+        UINT32,
+        CNTR32,
+        INT64,
+        UINT64,
+        CNTR64,
+        FLOAT,
+    };
+
+    template<typename T, bool = std::is_enum<T>::value>
+    inline static constexpr type_t TypeFor() {
+        using U = typename std::underlying_type<T>::type;
+        return TypeFor<U>();
+    }
+
+    // deprectated
+    template<typename T, bool B = std::is_enum<T>::value>
+    inline static constexpr type_t typeFor() {
+        return TypeFor<T, B>();
+    }
+
+    // constructors - implicit
+    template<typename T>
+    C2Value(T value)  : _mType(typeFor<T>()), _mValue(value) { }
+
+    C2Value() : _mType(NO_INIT) { }
+
+    inline type_t type() const { return _mType; }
+
+    template<typename T>
+    inline bool get(T *value) const {
+        if (_mType == typeFor<T>()) {
+            *value = _mValue.ref<T>();
+            return true;
+        }
+        return false;
+    }
+
+    /// returns the address of the value
+    void *get() const {
+        return _mType == NO_INIT ? nullptr : (void*)&_mValue;
+    }
+
+    /// returns the size of the contained value
+    size_t inline sizeOf() const {
+        return SizeFor(_mType);
+    }
+
+    static size_t SizeFor(type_t type) {
+        switch (type) {
+            case INT32:
+            case UINT32:
+            case CNTR32: return sizeof(_mValue.i32);
+            case INT64:
+            case UINT64:
+            case CNTR64: return sizeof(_mValue.i64);
+            case FLOAT: return sizeof(_mValue.fp);
+            default: return 0;
+        }
+    }
+
+private:
+    type_t _mType;
+    Primitive _mValue;
+};
+
+template<> inline const int32_t &C2Value::Primitive::ref<int32_t>() const { return i32; }
+template<> inline const int64_t &C2Value::Primitive::ref<int64_t>() const { return i64; }
+template<> inline const uint32_t &C2Value::Primitive::ref<uint32_t>() const { return u32; }
+template<> inline const uint64_t &C2Value::Primitive::ref<uint64_t>() const { return u64; }
+template<> inline const c2_cntr32_t &C2Value::Primitive::ref<c2_cntr32_t>() const { return c32; }
+template<> inline const c2_cntr64_t &C2Value::Primitive::ref<c2_cntr64_t>() const { return c64; }
+template<> inline const float &C2Value::Primitive::ref<float>() const { return fp; }
+
+// provide types for enums and uint8_t, char even though we don't provide reading as them
+template<> constexpr C2Value::type_t C2Value::TypeFor<char, false>() { return INT32; }
+template<> constexpr C2Value::type_t C2Value::TypeFor<int32_t, false>() { return INT32; }
+template<> constexpr C2Value::type_t C2Value::TypeFor<int64_t, false>() { return INT64; }
+template<> constexpr C2Value::type_t C2Value::TypeFor<uint8_t, false>() { return UINT32; }
+template<> constexpr C2Value::type_t C2Value::TypeFor<uint32_t, false>() { return UINT32; }
+template<> constexpr C2Value::type_t C2Value::TypeFor<uint64_t, false>() { return UINT64; }
+template<> constexpr C2Value::type_t C2Value::TypeFor<c2_cntr32_t, false>() { return CNTR32; }
+template<> constexpr C2Value::type_t C2Value::TypeFor<c2_cntr64_t, false>() { return CNTR64; }
+template<> constexpr C2Value::type_t C2Value::TypeFor<float, false>() { return FLOAT; }
+
+// forward declare easy enum template
+template<typename E> struct C2EasyEnum;
+
+/**
+ * field descriptor. A field is uniquely defined by an index into a parameter.
+ * (Note: Stream-id is not captured as a field.)
+ *
+ * Ordering of fields is by offset. In case of structures, it is depth first,
+ * with a structure taking an index just before and in addition to its members.
+ */
+struct C2FieldDescriptor {
+//public:
+    /** field types and flags
+     * \note: only 32-bit and 64-bit fields are supported (e.g. no boolean, as that
+     * is represented using INT32).
+     */
+    enum type_t : uint32_t {
+        // primitive types
+        INT32   = C2Value::INT32,  ///< 32-bit signed integer
+        UINT32  = C2Value::UINT32, ///< 32-bit unsigned integer
+        CNTR32  = C2Value::CNTR32, ///< 32-bit counter
+        INT64   = C2Value::INT64,  ///< 64-bit signed integer
+        UINT64  = C2Value::UINT64, ///< 64-bit signed integer
+        CNTR64  = C2Value::CNTR64, ///< 64-bit counter
+        FLOAT   = C2Value::FLOAT,  ///< 32-bit floating point
+
+        // array types
+        STRING = 0x100, ///< fixed-size string (POD)
+        BLOB,           ///< blob. Blobs have no sub-elements and can be thought of as byte arrays;
+                        ///< however, bytes cannot be individually addressed by clients.
+
+        // complex types
+        STRUCT_FLAG = 0x20000, ///< structs. Marked with this flag in addition to their coreIndex.
+    };
+
+    typedef std::pair<C2String, C2Value::Primitive> NamedValueType;
+    typedef std::vector<NamedValueType> NamedValuesType;
+    //typedef std::pair<std::vector<C2String>, std::vector<C2Value::Primitive>> NamedValuesType;
+
+    /**
+     * Template specialization that returns the named values for a type.
+     *
+     * \todo hide from client.
+     *
+     * \return a vector of name-value pairs.
+     */
+    template<typename B>
+    static NamedValuesType namedValuesFor(const B &);
+
+    /** specialization for easy enums */
+    template<typename E>
+    inline static NamedValuesType namedValuesFor(const C2EasyEnum<E> &) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wnull-dereference"
+        return namedValuesFor(*(E*)nullptr);
+#pragma GCC diagnostic pop
+    }
+
+private:
+    template<typename B, bool enabled=std::is_arithmetic<B>::value || std::is_enum<B>::value>
+    struct C2_HIDE _NamedValuesGetter;
+
+public:
+    inline C2FieldDescriptor(uint32_t type, uint32_t extent, C2String name, size_t offset, size_t size)
+        : _mType((type_t)type), _mExtent(extent), _mName(name), _mFieldId(offset, size) { }
+
+    inline C2FieldDescriptor(const C2FieldDescriptor &) = default;
+
+    template<typename T, class B=typename std::remove_extent<T>::type>
+    inline C2FieldDescriptor(const T* offset, const char *name)
+        : _mType(this->GetType((B*)nullptr)),
+          _mExtent(std::is_array<T>::value ? std::extent<T>::value : 1),
+          _mName(name),
+          _mNamedValues(_NamedValuesGetter<B>::getNamedValues()),
+          _mFieldId(offset) {}
+
+    /// \deprecated
+    template<typename T, typename S, class B=typename std::remove_extent<T>::type>
+    inline C2FieldDescriptor(S*, T S::* field, const char *name)
+        : _mType(this->GetType((B*)nullptr)),
+          _mExtent(std::is_array<T>::value ? std::extent<T>::value : 1),
+          _mName(name),
+          _mFieldId(&(((S*)0)->*field)) {}
+
+    /// returns the type of this field
+    inline type_t type() const { return _mType; }
+    /// returns the length of the field in case it is an array. Returns 0 for
+    /// T[] arrays, returns 1 for T[1] arrays as well as if the field is not an array.
+    inline size_t extent() const { return _mExtent; }
+    /// returns the name of the field
+    inline C2String name() const { return _mName; }
+
+    const NamedValuesType &namedValues() const { return _mNamedValues; }
+
+#if defined(FRIEND_TEST)
+    friend void PrintTo(const C2FieldDescriptor &, ::std::ostream*);
+    friend bool operator==(const C2FieldDescriptor &, const C2FieldDescriptor &);
+    FRIEND_TEST(C2ParamTest_ParamFieldList, VerifyStruct);
+#endif
+
+private:
+    /**
+     * Construct an offseted field descriptor.
+     */
+    inline C2FieldDescriptor(const C2FieldDescriptor &desc, size_t offset)
+        : _mType(desc._mType), _mExtent(desc._mExtent),
+          _mName(desc._mName), _mNamedValues(desc._mNamedValues),
+          _mFieldId(desc._mFieldId._mOffset + offset, desc._mFieldId._mSize) { }
+
+    type_t _mType;
+    uint32_t _mExtent; // the last member can be arbitrary length if it is T[] array,
+                       // extending to the end of the parameter (this is marked with
+                       // 0). T[0]-s are not fields.
+    C2String _mName;
+    NamedValuesType _mNamedValues;
+
+    _C2FieldId _mFieldId;   // field identifier (offset and size)
+
+    // NOTE: We do not capture default value(s) here as that may depend on the component.
+    // NOTE: We also do not capture bestEffort, as 1) this should be true for most fields,
+    // 2) this is at parameter granularity.
+
+    // type resolution
+    inline static type_t GetType(int32_t*)     { return INT32; }
+    inline static type_t GetType(uint32_t*)    { return UINT32; }
+    inline static type_t GetType(c2_cntr32_t*) { return CNTR32; }
+    inline static type_t GetType(int64_t*)     { return INT64; }
+    inline static type_t GetType(uint64_t*)    { return UINT64; }
+    inline static type_t GetType(c2_cntr64_t*) { return CNTR64; }
+    inline static type_t GetType(float*)       { return FLOAT; }
+    inline static type_t GetType(char*)        { return STRING; }
+    inline static type_t GetType(uint8_t*)     { return BLOB; }
+
+    template<typename T,
+             class=typename std::enable_if<std::is_enum<T>::value>::type>
+    inline static type_t GetType(T*) {
+        typename std::underlying_type<T>::type underlying(0);
+        return GetType(&underlying);
+    }
+
+    // verify C2Struct by having a FieldList() and a CORE_INDEX.
+    template<typename T,
+             class=decltype(T::CORE_INDEX + 1), class=decltype(T::FieldList())>
+    inline static type_t GetType(T*) {
+        static_assert(!std::is_base_of<C2Param, T>::value, "cannot use C2Params as fields");
+        return (type_t)(T::CORE_INDEX | STRUCT_FLAG);
+    }
+
+    friend struct _C2ParamInspector;
+};
+
+// no named values for compound types
+template<typename B>
+struct C2FieldDescriptor::_NamedValuesGetter<B, false> {
+    inline static C2FieldDescriptor::NamedValuesType getNamedValues() {
+        return NamedValuesType();
+    }
+};
+
+template<typename B>
+struct C2FieldDescriptor::_NamedValuesGetter<B, true> {
+    inline static C2FieldDescriptor::NamedValuesType getNamedValues() {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wnull-dereference"
+        return C2FieldDescriptor::namedValuesFor(*(B*)nullptr);
+#pragma GCC diagnostic pop
+    }
+};
+
+#define DEFINE_NO_NAMED_VALUES_FOR(type) \
+template<> inline C2FieldDescriptor::NamedValuesType C2FieldDescriptor::namedValuesFor(const type &) { \
+    return NamedValuesType(); \
+}
+
+// We cannot subtype constructor for enumerated types so insted define no named values for
+// non-enumerated integral types.
+DEFINE_NO_NAMED_VALUES_FOR(int32_t)
+DEFINE_NO_NAMED_VALUES_FOR(uint32_t)
+DEFINE_NO_NAMED_VALUES_FOR(c2_cntr32_t)
+DEFINE_NO_NAMED_VALUES_FOR(int64_t)
+DEFINE_NO_NAMED_VALUES_FOR(uint64_t)
+DEFINE_NO_NAMED_VALUES_FOR(c2_cntr64_t)
+DEFINE_NO_NAMED_VALUES_FOR(uint8_t)
+DEFINE_NO_NAMED_VALUES_FOR(char)
+DEFINE_NO_NAMED_VALUES_FOR(float)
+
+/**
+ * Describes the fields of a structure.
+ */
+struct C2StructDescriptor {
+public:
+    /// Returns the core index of the struct
+    inline C2Param::CoreIndex coreIndex() const { return _mType.coreIndex(); }
+
+    // Returns the number of fields in this struct (not counting any recursive fields).
+    // Must be at least 1 for valid structs.
+    inline size_t numFields() const { return _mFields.size(); }
+
+    // Returns the list of direct fields (not counting any recursive fields).
+    typedef std::vector<C2FieldDescriptor>::const_iterator field_iterator;
+    inline field_iterator cbegin() const { return _mFields.cbegin(); }
+    inline field_iterator cend() const { return _mFields.cend(); }
+
+    // only supplying const iterator - but these names are needed for range based loops
+    inline field_iterator begin() const { return _mFields.cbegin(); }
+    inline field_iterator end() const { return _mFields.cend(); }
+
+    template<typename T>
+    inline C2StructDescriptor(T*)
+        : C2StructDescriptor(T::CORE_INDEX, T::FieldList()) { }
+
+    inline C2StructDescriptor(
+            C2Param::CoreIndex type,
+            const std::vector<C2FieldDescriptor> &fields)
+        : _mType(type), _mFields(fields) { }
+
+private:
+    friend struct _C2ParamInspector;
+
+    inline C2StructDescriptor(
+            C2Param::CoreIndex type,
+            std::vector<C2FieldDescriptor> &&fields)
+        : _mType(type), _mFields(std::move(fields)) { }
+
+    const C2Param::CoreIndex _mType;
+    const std::vector<C2FieldDescriptor> _mFields;
+};
+
+/**
+ * Describes parameters for a component.
+ */
+struct C2ParamDescriptor {
+public:
+    /**
+     * Returns whether setting this param is required to configure this component.
+     * This can only be true for builtin params for platform-defined components (e.g. video and
+     * audio encoders/decoders, video/audio filters).
+     * For vendor-defined components, it can be true even for vendor-defined params,
+     * but it is not recommended, in case the component becomes platform-defined.
+     */
+    inline bool isRequired() const { return _mAttrib & IS_REQUIRED; }
+
+    /**
+     * Returns whether this parameter is persistent. This is always true for C2Tuning and C2Setting,
+     * but may be false for C2Info. If true, this parameter persists across frames and applies to
+     * the current and subsequent frames. If false, this C2Info parameter only applies to the
+     * current frame and is not assumed to have the same value (or even be present) on subsequent
+     * frames, unless it is specified for those frames.
+     */
+    inline bool isPersistent() const { return _mAttrib & IS_PERSISTENT; }
+
+    inline bool isStrict() const { return _mAttrib & IS_STRICT; }
+
+    inline bool isReadOnly() const { return _mAttrib & IS_READ_ONLY; }
+
+    inline bool isVisible() const { return !(_mAttrib & IS_HIDDEN); }
+
+    inline bool isPublic() const { return !(_mAttrib & IS_INTERNAL); }
+
+    /// Returns the name of this param.
+    /// This defaults to the underlying C2Struct's name, but could be altered for a component.
+    inline C2String name() const { return _mName; }
+
+    /// Returns the parameter index
+    inline C2Param::Index index() const { return _mIndex; }
+
+    /// Returns the indices of parameters that this parameter has a dependency on
+    inline const std::vector<C2Param::Index> &dependencies() const { return _mDependencies; }
+
+    /// \deprecated
+    template<typename T>
+    inline C2ParamDescriptor(bool isRequired, C2StringLiteral name, const T*)
+        : _mIndex(T::PARAM_TYPE),
+          _mAttrib(IS_PERSISTENT | (isRequired ? IS_REQUIRED : 0)),
+          _mName(name) { }
+
+    /// \deprecated
+    inline C2ParamDescriptor(
+            bool isRequired, C2StringLiteral name, C2Param::Index index)
+        : _mIndex(index),
+          _mAttrib(IS_PERSISTENT | (isRequired ? IS_REQUIRED : 0)),
+          _mName(name) { }
+
+    enum attrib_t : uint32_t {
+        // flags that default on
+        IS_REQUIRED   = 1u << 0, ///< parameter is required to be specified
+        IS_PERSISTENT = 1u << 1, ///< parameter retains its value
+        // flags that default off
+        IS_STRICT     = 1u << 2, ///< parameter is strict
+        IS_READ_ONLY  = 1u << 3, ///< parameter is publicly read-only
+        IS_HIDDEN     = 1u << 4, ///< parameter shall not be visible to clients
+        IS_INTERNAL   = 1u << 5, ///< parameter shall not be used by framework (other than testing)
+        IS_CONST      = 1u << 6 | IS_READ_ONLY, ///< parameter is publicly const (hence read-only)
+    };
+
+    inline C2ParamDescriptor(
+        C2Param::Index index, attrib_t attrib, C2StringLiteral name)
+        : _mIndex(index),
+          _mAttrib(attrib),
+          _mName(name) { }
+
+    inline C2ParamDescriptor(
+        C2Param::Index index, attrib_t attrib, C2String &&name,
+        std::vector<C2Param::Index> &&dependencies)
+        : _mIndex(index),
+          _mAttrib(attrib),
+          _mName(name),
+          _mDependencies(std::move(dependencies)) { }
+
+private:
+    const C2Param::Index _mIndex;
+    const uint32_t _mAttrib;
+    const C2String _mName;
+    std::vector<C2Param::Index> _mDependencies;
+
+    friend struct _C2ParamInspector;
+};
+
+DEFINE_ENUM_OPERATORS(::C2ParamDescriptor::attrib_t)
+
+
+/// \ingroup internal
+/// Define a structure without CORE_INDEX.
+/// \note _FIELD_LIST is used only during declaration so that C2Struct declarations can end with
+/// a simple list of C2FIELD-s and closing bracket. Mark it unused as it is not used in templated
+/// structs.
+#define DEFINE_BASE_C2STRUCT(name) \
+private: \
+    const static std::vector<C2FieldDescriptor> _FIELD_LIST __unused; /**< structure fields */ \
+public: \
+    typedef C2##name##Struct _type; /**< type name shorthand */ \
+    static const std::vector<C2FieldDescriptor> FieldList(); /**< structure fields factory */
+
+/// Define a structure with matching CORE_INDEX.
+#define DEFINE_C2STRUCT(name) \
+public: \
+    enum : uint32_t { CORE_INDEX = kParamIndex##name }; \
+    DEFINE_BASE_C2STRUCT(name)
+
+/// Define a flexible structure without CORE_INDEX.
+#define DEFINE_BASE_FLEX_C2STRUCT(name, flexMember) \
+public: \
+    FLEX(C2##name##Struct, flexMember) \
+    DEFINE_BASE_C2STRUCT(name)
+
+/// Define a flexible structure with matching CORE_INDEX.
+#define DEFINE_FLEX_C2STRUCT(name, flexMember) \
+public: \
+    FLEX(C2##name##Struct, flexMember) \
+    enum : uint32_t { CORE_INDEX = kParamIndex##name | C2Param::CoreIndex::IS_FLEX_FLAG }; \
+    DEFINE_BASE_C2STRUCT(name)
+
+/// \ingroup internal
+/// Describe a structure of a templated structure.
+// Use list... as the argument gets resubsitituted and it contains commas. Alternative would be
+// to wrap list in an expression, e.g. ({ std::vector<C2FieldDescriptor> list; })) which converts
+// it from an initializer list to a vector.
+#define DESCRIBE_TEMPLATED_C2STRUCT(strukt, list...) \
+    _DESCRIBE_TEMPLATABLE_C2STRUCT(template<>, strukt, __C2_GENERATE_GLOBAL_VARS__, list)
+
+/// \deprecated
+/// Describe the fields of a structure using an initializer list.
+#define DESCRIBE_C2STRUCT(name, list...) \
+    _DESCRIBE_TEMPLATABLE_C2STRUCT(, C2##name##Struct, __C2_GENERATE_GLOBAL_VARS__, list)
+
+/// \ingroup internal
+/// Macro layer to get value of enabled that is passed in as a macro variable
+#define _DESCRIBE_TEMPLATABLE_C2STRUCT(template, strukt, enabled, list...) \
+    __DESCRIBE_TEMPLATABLE_C2STRUCT(template, strukt, enabled, list)
+
+/// \ingroup internal
+/// Macro layer to resolve to the specific macro based on macro variable
+#define __DESCRIBE_TEMPLATABLE_C2STRUCT(template, strukt, enabled, list...) \
+    ___DESCRIBE_TEMPLATABLE_C2STRUCT##enabled(template, strukt, list)
+
+#define ___DESCRIBE_TEMPLATABLE_C2STRUCT(template, strukt, list...) \
+    template \
+    const std::vector<C2FieldDescriptor> strukt::FieldList() { return list; }
+
+#define ___DESCRIBE_TEMPLATABLE_C2STRUCT__C2_GENERATE_GLOBAL_VARS__(template, strukt, list...)
+
+/**
+ * Describe a field of a structure.
+ * These must be in order.
+ *
+ * There are two ways to use this macro:
+ *
+ *  ~~~~~~~~~~~~~ (.cpp)
+ *  struct C2VideoWidthStruct {
+ *      int32_t width;
+ *      C2VideoWidthStruct() {} // optional default constructor
+ *      C2VideoWidthStruct(int32_t _width) : width(_width) {}
+ *
+ *      DEFINE_AND_DESCRIBE_C2STRUCT(VideoWidth)
+ *      C2FIELD(width, "width")
+ *  };
+ *  ~~~~~~~~~~~~~
+ *
+ *  ~~~~~~~~~~~~~ (.cpp)
+ *  struct C2VideoWidthStruct {
+ *      int32_t width;
+ *      C2VideoWidthStruct() = default; // optional default constructor
+ *      C2VideoWidthStruct(int32_t _width) : width(_width) {}
+ *
+ *      DEFINE_C2STRUCT(VideoWidth)
+ *  } C2_PACK;
+ *
+ *  DESCRIBE_C2STRUCT(VideoWidth, {
+ *      C2FIELD(width, "width")
+ *  })
+ *  ~~~~~~~~~~~~~
+ *
+ *  For flexible structures (those ending in T[]), use the flexible macros:
+ *
+ *  ~~~~~~~~~~~~~ (.cpp)
+ *  struct C2VideoFlexWidthsStruct {
+ *      int32_t widths[];
+ *      C2VideoFlexWidthsStruct(); // must have a default constructor
+ *
+ *  private:
+ *      // may have private constructors taking number of widths as the first argument
+ *      // This is used by the C2Param factory methods, e.g.
+ *      //   C2VideoFlexWidthsGlobalParam::AllocUnique(size_t, int32_t);
+ *      C2VideoFlexWidthsStruct(size_t flexCount, int32_t value) {
+ *          for (size_t i = 0; i < flexCount; ++i) {
+ *              widths[i] = value;
+ *          }
+ *      }
+ *
+ *      // If the last argument is T[N] or std::initializer_list<T>, the flexCount will
+ *      // be automatically calculated and passed by the C2Param factory methods, e.g.
+ *      //   int widths[] = { 1, 2, 3 };
+ *      //   C2VideoFlexWidthsGlobalParam::AllocUnique(widths);
+ *      template<unsigned N>
+ *      C2VideoFlexWidthsStruct(size_t flexCount, const int32_t(&init)[N]) {
+ *          for (size_t i = 0; i < flexCount; ++i) {
+ *              widths[i] = init[i];
+ *          }
+ *      }
+ *
+ *      DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(VideoFlexWidths, widths)
+ *      C2FIELD(widths, "widths")
+ *  };
+ *  ~~~~~~~~~~~~~
+ *
+ *  ~~~~~~~~~~~~~ (.cpp)
+ *  struct C2VideoFlexWidthsStruct {
+ *      int32_t mWidths[];
+ *      C2VideoFlexWidthsStruct(); // must have a default constructor
+ *
+ *      DEFINE_FLEX_C2STRUCT(VideoFlexWidths, mWidths)
+ *  } C2_PACK;
+ *
+ *  DESCRIBE_C2STRUCT(VideoFlexWidths, {
+ *      C2FIELD(mWidths, "widths")
+ *  })
+ *  ~~~~~~~~~~~~~
+ *
+ */
+#define DESCRIBE_C2FIELD(member, name) \
+  C2FieldDescriptor(&((_type*)(nullptr))->member, name),
+
+#define C2FIELD(member, name) _C2FIELD(member, name, __C2_GENERATE_GLOBAL_VARS__)
+/// \if 0
+#define _C2FIELD(member, name, enabled) __C2FIELD(member, name, enabled)
+#define __C2FIELD(member, name, enabled) DESCRIBE_C2FIELD##enabled(member, name)
+#define DESCRIBE_C2FIELD__C2_GENERATE_GLOBAL_VARS__(member, name)
+/// \endif
+
+/// Define a structure with matching CORE_INDEX and start describing its fields.
+/// This must be at the end of the structure definition.
+#define DEFINE_AND_DESCRIBE_C2STRUCT(name) \
+    _DEFINE_AND_DESCRIBE_C2STRUCT(name, DEFINE_C2STRUCT, __C2_GENERATE_GLOBAL_VARS__)
+
+/// Define a base structure (with no CORE_INDEX) and start describing its fields.
+/// This must be at the end of the structure definition.
+#define DEFINE_AND_DESCRIBE_BASE_C2STRUCT(name) \
+    _DEFINE_AND_DESCRIBE_C2STRUCT(name, DEFINE_BASE_C2STRUCT, __C2_GENERATE_GLOBAL_VARS__)
+
+/// Define a flexible structure with matching CORE_INDEX and start describing its fields.
+/// This must be at the end of the structure definition.
+#define DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(name, flexMember) \
+    _DEFINE_AND_DESCRIBE_FLEX_C2STRUCT( \
+            name, flexMember, DEFINE_FLEX_C2STRUCT, __C2_GENERATE_GLOBAL_VARS__)
+
+/// Define a flexible base structure (with no CORE_INDEX) and start describing its fields.
+/// This must be at the end of the structure definition.
+#define DEFINE_AND_DESCRIBE_BASE_FLEX_C2STRUCT(name, flexMember) \
+    _DEFINE_AND_DESCRIBE_FLEX_C2STRUCT( \
+            name, flexMember, DEFINE_BASE_FLEX_C2STRUCT, __C2_GENERATE_GLOBAL_VARS__)
+
+/// \if 0
+/*
+   Alternate declaration of field definitions in case no field list is to be generated.
+   The specific macro is chosed based on the value of __C2_GENERATE_GLOBAL_VARS__ (whether it is
+   defined (to be empty) or not. This requires two level of macro substitution.
+   TRICKY: use namespace declaration to handle closing bracket that is normally after
+   these macros.
+*/
+
+#define _DEFINE_AND_DESCRIBE_C2STRUCT(name, defineMacro, enabled) \
+    __DEFINE_AND_DESCRIBE_C2STRUCT(name, defineMacro, enabled)
+#define __DEFINE_AND_DESCRIBE_C2STRUCT(name, defineMacro, enabled) \
+    ___DEFINE_AND_DESCRIBE_C2STRUCT##enabled(name, defineMacro)
+#define ___DEFINE_AND_DESCRIBE_C2STRUCT__C2_GENERATE_GLOBAL_VARS__(name, defineMacro) \
+    defineMacro(name) } C2_PACK; namespace {
+#define ___DEFINE_AND_DESCRIBE_C2STRUCT(name, defineMacro) \
+    defineMacro(name) } C2_PACK; \
+    const std::vector<C2FieldDescriptor> C2##name##Struct::FieldList() { return _FIELD_LIST; } \
+    const std::vector<C2FieldDescriptor> C2##name##Struct::_FIELD_LIST = {
+
+#define _DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(name, flexMember, defineMacro, enabled) \
+    __DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(name, flexMember, defineMacro, enabled)
+#define __DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(name, flexMember, defineMacro, enabled) \
+    ___DEFINE_AND_DESCRIBE_FLEX_C2STRUCT##enabled(name, flexMember, defineMacro)
+#define ___DEFINE_AND_DESCRIBE_FLEX_C2STRUCT__C2_GENERATE_GLOBAL_VARS__(name, flexMember, defineMacro) \
+    defineMacro(name, flexMember) } C2_PACK; namespace {
+#define ___DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(name, flexMember, defineMacro) \
+    defineMacro(name, flexMember) } C2_PACK; \
+    const std::vector<C2FieldDescriptor> C2##name##Struct::FieldList() { return _FIELD_LIST; } \
+    const std::vector<C2FieldDescriptor> C2##name##Struct::_FIELD_LIST = {
+/// \endif
+
+
+/**
+ * Parameter reflector class.
+ *
+ * This class centralizes the description of parameter structures. This can be shared
+ * by multiple components as describing a parameter does not imply support of that
+ * parameter. However, each supported parameter and any dependent structures within
+ * must be described by the parameter reflector provided by a component.
+ */
+class C2ParamReflector {
+public:
+    /**
+     *  Describes a parameter structure.
+     *
+     *  \param[in] coreIndex the core index of the parameter structure containing at least the
+     *  core index
+     *
+     *  \return the description of the parameter structure
+     *  \retval nullptr if the parameter is not supported by this reflector
+     *
+     *  This methods shall not block and return immediately.
+     *
+     *  \note this class does not take a set of indices because we would then prefer
+     *  to also return any dependent structures, and we don't want this logic to be
+     *  repeated in each reflector. Alternately, this could just return a map of all
+     *  descriptions, but we want to conserve memory if client only wants the description
+     *  of a few indices.
+     */
+    virtual std::unique_ptr<C2StructDescriptor> describe(C2Param::CoreIndex coreIndex) const = 0;
+
+protected:
+    virtual ~C2ParamReflector() = default;
+};
+
+/**
+ * Generic supported values for a field.
+ *
+ * This can be either a range or a set of values. The range can be a simple range, an arithmetic,
+ * geometric or multiply-accumulate series with a clear minimum and maximum value. Values can
+ * be discrete values, or can optionally represent flags to be or-ed.
+ *
+ * \note Do not use flags to represent bitfields. Use individual values or separate fields instead.
+ */
+struct C2FieldSupportedValues {
+//public:
+    enum type_t {
+        EMPTY,      ///< no supported values
+        RANGE,      ///< a numeric range that can be continuous or discrete
+        VALUES,     ///< a list of values
+        FLAGS       ///< a list of flags that can be OR-ed
+    };
+
+    type_t type; /** Type of values for this field. */
+
+    typedef C2Value::Primitive Primitive;
+
+    /**
+     * Range specifier for supported value. Used if type is RANGE.
+     *
+     * If step is 0 and num and denom are both 1, the supported values are any value, for which
+     * min <= value <= max.
+     *
+     * Otherwise, the range represents a geometric/arithmetic/multiply-accumulate series, where
+     * successive supported values can be derived from previous values (starting at min), using the
+     * following formula:
+     *  v[0] = min
+     *  v[i] = v[i-1] * num / denom + step for i >= 1, while min < v[i] <= max.
+     */
+    struct {
+        /** Lower end of the range (inclusive). */
+        Primitive min;
+        /** Upper end of the range (inclusive if permitted by series). */
+        Primitive max;
+        /** Step between supported values. */
+        Primitive step;
+        /** Numerator of a geometric series. */
+        Primitive num;
+        /** Denominator of a geometric series. */
+        Primitive denom;
+    } range;
+
+    /**
+     * List of values. Used if type is VALUES or FLAGS.
+     *
+     * If type is VALUES, this is the list of supported values in decreasing preference.
+     *
+     * If type is FLAGS, this vector contains { min-mask, flag1, flag2... }. Basically, the first
+     * value is the required set of flags to be set, and the rest of the values are flags that can
+     * be set independently. FLAGS is only supported for integral types. Supported flags should
+     * not overlap, as it can make validation non-deterministic. The standard validation method
+     * is that starting from the original value, if each flag is removed when fully present (the
+     * min-mask must be fully present), we shall arrive at 0.
+     */
+    std::vector<Primitive> values;
+
+    C2FieldSupportedValues()
+        : type(EMPTY) {
+    }
+
+    template<typename T>
+    C2FieldSupportedValues(T min, T max, T step = T(std::is_floating_point<T>::value ? 0 : 1))
+        : type(RANGE),
+          range{min, max, step, (T)1, (T)1} { }
+
+    template<typename T>
+    C2FieldSupportedValues(T min, T max, T num, T den) :
+        type(RANGE),
+        range{min, max, (T)0, num, den} { }
+
+    template<typename T>
+    C2FieldSupportedValues(T min, T max, T step, T num, T den)
+        : type(RANGE),
+          range{min, max, step, num, den} { }
+
+    /// \deprecated
+    template<typename T>
+    C2FieldSupportedValues(bool flags, std::initializer_list<T> list)
+        : type(flags ? FLAGS : VALUES),
+          range{(T)0, (T)0, (T)0, (T)0, (T)0} {
+        for (T value : list) {
+            values.emplace_back(value);
+        }
+    }
+
+    /// \deprecated
+    template<typename T>
+    C2FieldSupportedValues(bool flags, const std::vector<T>& list)
+        : type(flags ? FLAGS : VALUES),
+          range{(T)0, (T)0, (T)0, (T)0, (T)0} {
+        for(T value : list) {
+            values.emplace_back(value);
+        }
+    }
+
+    /// \internal
+    /// \todo: create separate values vs. flags initializer as for flags we want
+    /// to list both allowed and required flags
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wnull-dereference"
+    template<typename T, typename E=decltype(C2FieldDescriptor::namedValuesFor(*(T*)nullptr))>
+    C2FieldSupportedValues(bool flags, const T*)
+        : type(flags ? FLAGS : VALUES),
+          range{(T)0, (T)0, (T)0, (T)0, (T)0} {
+              C2FieldDescriptor::NamedValuesType named = C2FieldDescriptor::namedValuesFor(*(T*)nullptr);
+        if (flags) {
+            values.emplace_back(0); // min-mask defaults to 0
+        }
+        for (const C2FieldDescriptor::NamedValueType &item : named){
+            values.emplace_back(item.second);
+        }
+    }
+};
+#pragma GCC diagnostic pop
+
+/**
+ * Supported values for a specific field.
+ *
+ * This is a pair of the field specifier together with an optional supported values object.
+ * This structure is used when reporting parameter configuration failures and conflicts.
+ */
+struct C2ParamFieldValues {
+    C2ParamField paramOrField; ///< the field or parameter
+    /// optional supported values for the field if paramOrField specifies an actual field that is
+    /// numeric (non struct, blob or string). Supported values for arrays (including string and
+    /// blobs) describe the supported values for each element (character for string, and bytes for
+    /// blobs). It is optional for read-only strings and blobs.
+    std::unique_ptr<C2FieldSupportedValues> values;
+
+    // This struct is meant to be move constructed.
+    C2_DEFAULT_MOVE(C2ParamFieldValues);
+
+    // Copy constructor/assignment is also provided as this object may get copied.
+    C2ParamFieldValues(const C2ParamFieldValues &other)
+        : paramOrField(other.paramOrField),
+          values(other.values ? std::make_unique<C2FieldSupportedValues>(*other.values) : nullptr) { }
+
+    C2ParamFieldValues& operator=(const C2ParamFieldValues &other) {
+        paramOrField = other.paramOrField;
+        values = other.values ? std::make_unique<C2FieldSupportedValues>(*other.values) : nullptr;
+        return *this;
+    }
+
+
+    /**
+     * Construct with no values.
+     */
+    C2ParamFieldValues(const C2ParamField &paramOrField_)
+        : paramOrField(paramOrField_) { }
+
+    /**
+     * Construct with values.
+     */
+    C2ParamFieldValues(const C2ParamField &paramOrField_, const C2FieldSupportedValues &values_)
+        : paramOrField(paramOrField_),
+          values(std::make_unique<C2FieldSupportedValues>(values_)) { }
+
+    /**
+     * Construct from fields.
+     */
+    C2ParamFieldValues(const C2ParamField &paramOrField_, std::unique_ptr<C2FieldSupportedValues> &&values_)
+        : paramOrField(paramOrField_),
+          values(std::move(values_)) { }
+};
+
+/// @}
+
+// include debug header for C2Params.h if C2Debug.h was already included
+#ifdef C2UTILS_DEBUG_H_
+#include <util/C2Debug-param.h>
+#endif
+
+#endif  // C2PARAM_H_
diff --git a/media/codec2/core/include/C2ParamDef.h b/media/codec2/core/include/C2ParamDef.h
new file mode 100644
index 0000000..0a33283
--- /dev/null
+++ b/media/codec2/core/include/C2ParamDef.h
@@ -0,0 +1,931 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/** \file
+ * Templates used to declare parameters.
+ */
+#ifndef C2PARAM_DEF_H_
+#define C2PARAM_DEF_H_
+
+#include <type_traits>
+
+#include <C2Param.h>
+
+/// \addtogroup Parameters
+/// @{
+
+/* ======================== UTILITY TEMPLATES FOR PARAMETER DEFINITIONS ======================== */
+
+/// \addtogroup internal
+/// @{
+
+/// Helper class that checks if a type has equality and inequality operators.
+struct C2_HIDE _C2Comparable_impl
+{
+    template<typename S, typename=decltype(S() == S())>
+    static std::true_type TestEqual(int);
+    template<typename>
+    static std::false_type TestEqual(...);
+
+    template<typename S, typename=decltype(S() != S())>
+    static std::true_type TestNotEqual(int);
+    template<typename>
+    static std::false_type TestNotEqual(...);
+};
+
+/**
+ * Helper template that returns if a type has equality and inequality operators.
+ *
+ * Use as _C2Comparable<typename S>::value.
+ */
+template<typename S>
+struct C2_HIDE _C2Comparable
+    : public std::integral_constant<bool, decltype(_C2Comparable_impl::TestEqual<S>(0))::value
+                        || decltype(_C2Comparable_impl::TestNotEqual<S>(0))::value> {
+};
+
+///  Helper class that checks if a type has a CORE_INDEX constant.
+struct C2_HIDE _C2CoreIndexHelper_impl
+{
+    template<typename S, int=S::CORE_INDEX>
+    static std::true_type TestCoreIndex(int);
+    template<typename>
+    static std::false_type TestCoreIndex(...);
+};
+
+/// Macro that defines and thus overrides a type's CORE_INDEX for a setting
+#define _C2_CORE_INDEX_OVERRIDE(coreIndex) \
+public: \
+    enum : uint32_t { CORE_INDEX = coreIndex };
+
+
+/// Helper template that adds a CORE_INDEX to a type if it does not have one (for testing)
+template<typename S, int CoreIndex>
+struct C2_HIDE _C2AddCoreIndex : public S {
+    _C2_CORE_INDEX_OVERRIDE(CoreIndex)
+};
+
+/**
+ * \brief Helper class to check struct requirements for parameters.
+ *
+ * Features:
+ *  - verify default constructor, no virtual methods, and no equality operators.
+ *  - expose PARAM_TYPE, and non-flex FLEX_SIZE.
+ */
+template<typename S, int CoreIndex, unsigned TypeFlags>
+struct C2_HIDE _C2StructCheck {
+    static_assert(
+            std::is_default_constructible<S>::value, "C2 structure must have default constructor");
+    static_assert(!std::is_polymorphic<S>::value, "C2 structure must not have virtual methods");
+    static_assert(!_C2Comparable<S>::value, "C2 structure must not have operator== or !=");
+
+public:
+    enum : uint32_t {
+        PARAM_TYPE = CoreIndex | TypeFlags
+    };
+
+protected:
+    enum : uint32_t {
+        FLEX_SIZE = 0,
+    };
+};
+
+/// Helper class that checks if a type has an integer FLEX_SIZE member.
+struct C2_HIDE _C2Flexible_impl {
+    /// specialization for types that have a FLEX_SIZE member
+    template<typename S, unsigned=S::FLEX_SIZE>
+    static std::true_type TestFlexSize(int);
+    template<typename>
+    static std::false_type TestFlexSize(...);
+};
+
+/// Helper template that returns if a type has an integer FLEX_SIZE member.
+template<typename S>
+struct C2_HIDE _C2Flexible
+    : public std::integral_constant<bool, decltype(_C2Flexible_impl::TestFlexSize<S>(0))::value> {
+};
+
+/// Macro to test if a type is flexible (has a FLEX_SIZE member).
+#define IF_FLEXIBLE(S) ENABLE_IF(_C2Flexible<S>::value)
+/// Shorthand for std::enable_if
+#define ENABLE_IF(cond) typename std::enable_if<cond>::type
+
+template<typename T, typename V=void>
+struct C2_HIDE _c2_enable_if_type {
+    typedef V type;
+};
+
+/// Helper template that exposes the flexible subtype of a struct.
+template<typename S, typename E=void>
+struct C2_HIDE _C2FlexHelper {
+    typedef void FlexType;
+    enum : uint32_t { FLEX_SIZE = 0 };
+};
+
+/// Specialization for flexible types. This only works if _FlexMemberType is public.
+template<typename S>
+struct C2_HIDE _C2FlexHelper<S,
+        typename _c2_enable_if_type<typename S::_FlexMemberType>::type> {
+    typedef typename _C2FlexHelper<typename S::_FlexMemberType>::FlexType FlexType;
+    enum : uint32_t { FLEX_SIZE = _C2FlexHelper<typename S::_FlexMemberType>::FLEX_SIZE };
+};
+
+/// Specialization for flex arrays.
+template<typename S>
+struct C2_HIDE _C2FlexHelper<S[],
+        typename std::enable_if<std::is_void<typename _C2FlexHelper<S>::FlexType>::value>::type> {
+    typedef S FlexType;
+    enum : uint32_t { FLEX_SIZE = sizeof(S) };
+};
+
+/**
+ * \brief Helper class to check flexible struct requirements and add common operations.
+ *
+ * Features:
+ *  - expose CORE_INDEX and FieldList (this is normally inherited from the struct, but flexible
+ *    structs cannot be base classes and thus inherited from)
+ *  - disable copy assignment and construction (TODO: this is already done in the FLEX macro for the
+ *    flexible struct, so may not be needed here)
+ */
+template<typename S, int ParamIndex, unsigned TypeFlags>
+struct C2_HIDE _C2FlexStructCheck :
+// add flexible flag as _C2StructCheck defines PARAM_TYPE
+        public _C2StructCheck<S, ParamIndex | C2Param::CoreIndex::IS_FLEX_FLAG, TypeFlags> {
+public:
+    enum : uint32_t {
+        /// \hideinitializer
+        CORE_INDEX = ParamIndex | C2Param::CoreIndex::IS_FLEX_FLAG, ///< flexible struct core-index
+    };
+
+    inline static const std::vector<C2FieldDescriptor> FieldList() { return S::FieldList(); }
+
+    // default constructor needed because of the disabled copy constructor
+    inline _C2FlexStructCheck() = default;
+
+protected:
+    // cannot copy flexible params
+    _C2FlexStructCheck(const _C2FlexStructCheck<S, ParamIndex, TypeFlags> &) = delete;
+    _C2FlexStructCheck& operator= (const _C2FlexStructCheck<S, ParamIndex, TypeFlags> &) = delete;
+
+    // constants used for helper methods
+    enum : uint32_t {
+        /// \hideinitializer
+        FLEX_SIZE = _C2FlexHelper<S>::FLEX_SIZE, ///< size of flexible type
+        /// \hideinitializer
+        MAX_SIZE = (uint32_t)std::min((size_t)UINT32_MAX, SIZE_MAX), // TODO: is this always u32 max?
+        /// \hideinitializer
+        BASE_SIZE = sizeof(S) + sizeof(C2Param), ///< size of the base param
+    };
+
+    /// returns the allocated size of this param with flexCount, or 0 if it would overflow.
+    inline static size_t CalcSize(size_t flexCount, size_t size = BASE_SIZE) {
+        if (flexCount <= (MAX_SIZE - size) / S::FLEX_SIZE) {
+            return size + S::FLEX_SIZE * flexCount;
+        }
+        return 0;
+    }
+
+    /// dynamic new operator usable for params of type S
+    inline void* operator new(size_t size, size_t flexCount) noexcept {
+        // TODO: assert(size == BASE_SIZE);
+        size = CalcSize(flexCount, size);
+        if (size > 0) {
+            return ::operator new(size);
+        }
+        return nullptr;
+    }
+};
+
+/// Define From() cast operators for params.
+#define DEFINE_CAST_OPERATORS(_Type) \
+    inline static _Type* From(C2Param *other) { \
+        return (_Type*)C2Param::IfSuitable( \
+                other, sizeof(_Type), _Type::PARAM_TYPE, _Type::FLEX_SIZE, \
+                (_Type::PARAM_TYPE & T::Index::DIR_UNDEFINED) != T::Index::DIR_UNDEFINED); \
+    } \
+    inline static const _Type* From(const C2Param *other) { \
+        return const_cast<const _Type*>(From(const_cast<C2Param *>(other))); \
+    } \
+    inline static _Type* From(std::nullptr_t) { return nullptr; } \
+
+/**
+ * Define flexible allocators (AllocShared or AllocUnique) for flexible params.
+ *  - P::AllocXyz(flexCount, args...): allocate for given flex-count. This maps to
+ *          T(flexCount, args...)\
+ *
+ * Clang does not support args... followed by templated param as args... eats it. Hence,
+ * provide specializations where the initializer replaces the flexCount.
+ *
+ * Specializations that deduce flexCount:
+ *  - P::AllocXyz(T[], args...): allocate for size of (and with) init array.
+ *  - P::AllocXyz(std::initializer_list<T>, args...): allocate for size of (and with) initializer
+ *            list.
+ *  - P::AllocXyz(std::vector<T>, args...): allocate for size of (and with) init vector.
+ *  These specializations map to T(flexCount = size-of-init, args..., init)
+ */
+#define DEFINE_FLEXIBLE_ALLOC(_Type, S, ptr, Ptr) \
+    template<typename ...Args> \
+    inline static std::ptr##_ptr<_Type> Alloc##Ptr(size_t flexCount, const Args(&... args)) { \
+        return std::ptr##_ptr<_Type>(new(flexCount) _Type(flexCount, args...)); \
+    } \
+    template<typename ...Args, typename U=typename S::FlexType> \
+    inline static std::ptr##_ptr<_Type> Alloc##Ptr( \
+            const std::initializer_list<U> &init, const Args(&... args)) { \
+        return std::ptr##_ptr<_Type>(new(init.size()) _Type(init.size(), args..., init)); \
+    } \
+    template<typename ...Args, typename U=typename S::FlexType> \
+    inline static std::ptr##_ptr<_Type> Alloc##Ptr( \
+            const std::vector<U> &init, const Args(&... args)) { \
+        return std::ptr##_ptr<_Type>(new(init.size()) _Type(init.size(), args..., init)); \
+    } \
+    template<typename ...Args, typename U=typename S::FlexType, unsigned N> \
+    inline static std::ptr##_ptr<_Type> Alloc##Ptr(const U(&init)[N], const Args(&... args)) { \
+        return std::ptr##_ptr<_Type>(new(N) _Type(N, args..., init)); \
+    } \
+
+/**
+ * Define flexible methods AllocShared, AllocUnique and flexCount.
+ */
+#define DEFINE_FLEXIBLE_METHODS(_Type, S) \
+    DEFINE_FLEXIBLE_ALLOC(_Type, S, shared, Shared) \
+    DEFINE_FLEXIBLE_ALLOC(_Type, S, unique, Unique) \
+    inline size_t flexCount() const { \
+        static_assert(sizeof(_Type) == _Type::BASE_SIZE, "incorrect BASE_SIZE"); \
+        size_t sz = this->size(); \
+        if (sz >= sizeof(_Type)) { \
+            return (sz - sizeof(_Type)) / _Type::FLEX_SIZE; \
+        } \
+        return 0; \
+    } \
+
+/// Mark flexible member variable and make structure flexible.
+#define FLEX(cls, m) \
+    C2_DO_NOT_COPY(cls) \
+private: \
+    C2PARAM_MAKE_FRIENDS \
+    /** \if 0 */ \
+    template<typename, typename> friend struct _C2FlexHelper; \
+public: \
+    typedef decltype(m) _FlexMemberType; \
+    /* default constructor with flexCount */ \
+    inline cls(size_t) : cls() {} \
+    /* constexpr static _FlexMemberType cls::* flexMember = &cls::m; */ \
+    typedef typename _C2FlexHelper<_FlexMemberType>::FlexType FlexType; \
+    static_assert(\
+            !std::is_void<FlexType>::value, \
+            "member is not flexible, or a flexible array of a flexible type"); \
+    enum : uint32_t { FLEX_SIZE = _C2FlexHelper<_FlexMemberType>::FLEX_SIZE }; \
+    /** \endif */ \
+
+/// @}
+
+/**
+ * Global-parameter template.
+ *
+ * Base template to define a global setting/tuning or info based on a structure and
+ * an optional ParamIndex. Global parameters are not tied to a port (input or output).
+ *
+ * Parameters wrap structures by prepending a (parameter) header. The fields of the wrapped
+ * structure can be accessed directly, and constructors and potential public methods are also
+ * wrapped.
+ *
+ * \tparam T param type C2Setting, C2Tuning or C2Info
+ * \tparam S wrapped structure
+ * \tparam ParamIndex optional parameter index override. Must be specified for base/reused
+ * structures.
+ */
+template<typename T, typename S, int ParamIndex=S::CORE_INDEX, class Flex=void>
+struct C2_HIDE C2GlobalParam : public T, public S,
+        public _C2StructCheck<S, ParamIndex, T::PARAM_KIND | T::Type::DIR_GLOBAL> {
+    _C2_CORE_INDEX_OVERRIDE(ParamIndex)
+private:
+    typedef C2GlobalParam<T, S, ParamIndex> _Type;
+
+public:
+    /// Wrapper around base structure's constructor.
+    template<typename ...Args>
+    inline C2GlobalParam(const Args(&... args)) : T(sizeof(_Type), _Type::PARAM_TYPE), S(args...) { }
+
+    DEFINE_CAST_OPERATORS(_Type)
+};
+
+/**
+ * Global-parameter template for flexible structures.
+ *
+ * Base template to define a global setting/tuning or info based on a flexible structure and
+ * an optional ParamIndex. Global parameters are not tied to a port (input or output).
+ *
+ * \tparam T param type C2Setting, C2Tuning or C2Info
+ * \tparam S wrapped flexible structure
+ * \tparam ParamIndex optional parameter index override. Must be specified for base/reused
+ *         structures.
+ *
+ * Parameters wrap structures by prepending a (parameter) header. The fields and methods of flexible
+ * structures can be accessed via the m member variable; however, the constructors of the structure
+ * are wrapped directly. (This is because flexible types cannot be subclassed.)
+ */
+template<typename T, typename S, int ParamIndex>
+struct C2_HIDE C2GlobalParam<T, S, ParamIndex, IF_FLEXIBLE(S)>
+    : public T, public _C2FlexStructCheck<S, ParamIndex, T::PARAM_KIND | T::Type::DIR_GLOBAL> {
+private:
+    typedef C2GlobalParam<T, S, ParamIndex> _Type;
+
+    /// Wrapper around base structure's constructor.
+    template<typename ...Args>
+    inline C2GlobalParam(size_t flexCount, const Args(&... args))
+        : T(_Type::CalcSize(flexCount), _Type::PARAM_TYPE), m(flexCount, args...) { }
+
+public:
+    S m; ///< wrapped flexible structure
+
+    DEFINE_FLEXIBLE_METHODS(_Type, S)
+    DEFINE_CAST_OPERATORS(_Type)
+};
+
+/**
+ * Port-parameter template.
+ *
+ * Base template to define a port setting/tuning or info based on a structure and
+ * an optional ParamIndex. Port parameters are tied to a port (input or output), but not to a
+ * specific stream.
+ *
+ * \tparam T param type C2Setting, C2Tuning or C2Info
+ * \tparam S wrapped structure
+ * \tparam ParamIndex optional parameter index override. Must be specified for base/reused
+ *         structures.
+ *
+ * Parameters wrap structures by prepending a (parameter) header. The fields of the wrapped
+ * structure can be accessed directly, and constructors and potential public methods are also
+ * wrapped.
+ *
+ * There are 3 flavors of port parameters: unspecified, input and output. Parameters with
+ * unspecified port expose a setPort method, and add an initial port parameter to the constructor.
+ */
+template<typename T, typename S, int ParamIndex=S::CORE_INDEX, class Flex=void>
+struct C2_HIDE C2PortParam : public T, public S,
+        private _C2StructCheck<S, ParamIndex, T::PARAM_KIND | T::Index::DIR_UNDEFINED> {
+    _C2_CORE_INDEX_OVERRIDE(ParamIndex)
+private:
+    typedef C2PortParam<T, S, ParamIndex> _Type;
+
+public:
+    /// Default constructor.
+    inline C2PortParam() : T(sizeof(_Type), _Type::PARAM_TYPE) { }
+    template<typename ...Args>
+    /// Wrapper around base structure's constructor while specifying port/direction.
+    inline C2PortParam(bool _output, const Args(&... args))
+        : T(sizeof(_Type), _output ? output::PARAM_TYPE : input::PARAM_TYPE), S(args...) { }
+    /// Set port/direction.
+    inline void setPort(bool output) { C2Param::setPort(output); }
+
+    DEFINE_CAST_OPERATORS(_Type)
+
+    /// Specialization for an input port parameter.
+    struct input : public T, public S,
+            public _C2StructCheck<S, ParamIndex, T::PARAM_KIND | T::Index::DIR_INPUT> {
+        _C2_CORE_INDEX_OVERRIDE(ParamIndex)
+        /// Wrapper around base structure's constructor.
+        template<typename ...Args>
+        inline input(const Args(&... args)) : T(sizeof(_Type), input::PARAM_TYPE), S(args...) { }
+
+        DEFINE_CAST_OPERATORS(input)
+
+    };
+
+    /// Specialization for an output port parameter.
+    struct output : public T, public S,
+            public _C2StructCheck<S, ParamIndex, T::PARAM_KIND | T::Index::DIR_OUTPUT> {
+        _C2_CORE_INDEX_OVERRIDE(ParamIndex)
+        /// Wrapper around base structure's constructor.
+        template<typename ...Args>
+        inline output(const Args(&... args)) : T(sizeof(_Type), output::PARAM_TYPE), S(args...) { }
+
+        DEFINE_CAST_OPERATORS(output)
+    };
+};
+
+/**
+ * Port-parameter template for flexible structures.
+ *
+ * Base template to define a port setting/tuning or info based on a flexible structure and
+ * an optional ParamIndex. Port parameters are tied to a port (input or output), but not to a
+ * specific stream.
+ *
+ * \tparam T param type C2Setting, C2Tuning or C2Info
+ * \tparam S wrapped flexible structure
+ * \tparam ParamIndex optional parameter index override. Must be specified for base/reused
+ *         structures.
+ *
+ * Parameters wrap structures by prepending a (parameter) header. The fields and methods of flexible
+ * structures can be accessed via the m member variable; however, the constructors of the structure
+ * are wrapped directly. (This is because flexible types cannot be subclassed.)
+ *
+ * There are 3 flavors of port parameters: unspecified, input and output. Parameters with
+ * unspecified port expose a setPort method, and add an initial port parameter to the constructor.
+ */
+template<typename T, typename S, int ParamIndex>
+struct C2_HIDE C2PortParam<T, S, ParamIndex, IF_FLEXIBLE(S)>
+    : public T, public _C2FlexStructCheck<S, ParamIndex, T::PARAM_KIND | T::Type::DIR_UNDEFINED> {
+private:
+    typedef C2PortParam<T, S, ParamIndex> _Type;
+
+    /// Default constructor for basic allocation: new(flexCount) P.
+    inline C2PortParam(size_t flexCount) : T(_Type::CalcSize(flexCount), _Type::PARAM_TYPE) { }
+    template<typename ...Args>
+    /// Wrapper around base structure's constructor while also specifying port/direction.
+    inline C2PortParam(size_t flexCount, bool _output, const Args(&... args))
+        : T(_Type::CalcSize(flexCount), _output ? output::PARAM_TYPE : input::PARAM_TYPE),
+          m(flexCount, args...) { }
+
+public:
+    /// Set port/direction.
+    inline void setPort(bool output) { C2Param::setPort(output); }
+
+    S m; ///< wrapped flexible structure
+
+    DEFINE_FLEXIBLE_METHODS(_Type, S)
+    DEFINE_CAST_OPERATORS(_Type)
+
+    /// Specialization for an input port parameter.
+    struct input : public T,
+            public _C2FlexStructCheck<S, ParamIndex, T::PARAM_KIND | T::Index::DIR_INPUT> {
+    private:
+        /// Wrapper around base structure's constructor while also specifying port/direction.
+        template<typename ...Args>
+        inline input(size_t flexCount, const Args(&... args))
+            : T(_Type::CalcSize(flexCount), input::PARAM_TYPE), m(flexCount, args...) { }
+
+    public:
+        S m; ///< wrapped flexible structure
+
+        DEFINE_FLEXIBLE_METHODS(input, S)
+        DEFINE_CAST_OPERATORS(input)
+    };
+
+    /// Specialization for an output port parameter.
+    struct output : public T,
+            public _C2FlexStructCheck<S, ParamIndex, T::PARAM_KIND | T::Index::DIR_OUTPUT> {
+    private:
+        /// Wrapper around base structure's constructor while also specifying port/direction.
+        template<typename ...Args>
+        inline output(size_t flexCount, const Args(&... args))
+            : T(_Type::CalcSize(flexCount), output::PARAM_TYPE), m(flexCount, args...) { }
+
+    public:
+        S m; ///< wrapped flexible structure
+
+        DEFINE_FLEXIBLE_METHODS(output, S)
+        DEFINE_CAST_OPERATORS(output)
+    };
+};
+
+/**
+ * Stream-parameter template.
+ *
+ * Base template to define a stream setting/tuning or info based on a structure and
+ * an optional ParamIndex. Stream parameters are tied to a specific stream on a port (input or
+ * output).
+ *
+ * \tparam T param type C2Setting, C2Tuning or C2Info
+ * \tparam S wrapped structure
+ * \tparam ParamIndex optional paramter index override. Must be specified for base/reused
+ *         structures.
+ *
+ * Parameters wrap structures by prepending a (parameter) header. The fields of the wrapped
+ * structure can be accessed directly, and constructors and potential public methods are also
+ * wrapped.
+ *
+ * There are 3 flavors of stream parameters: unspecified port, input and output. All of these expose
+ * a setStream method and an extra initial streamID parameter for the constructor. Moreover,
+ * parameters with unspecified port expose a setPort method, and add an additional initial port
+ * parameter to the constructor.
+ */
+template<typename T, typename S, int ParamIndex=S::CORE_INDEX, class Flex=void>
+struct C2_HIDE C2StreamParam : public T, public S,
+        private _C2StructCheck<S, ParamIndex,
+                T::PARAM_KIND | T::Index::IS_STREAM_FLAG | T::Index::DIR_UNDEFINED> {
+    _C2_CORE_INDEX_OVERRIDE(ParamIndex)
+private:
+    typedef C2StreamParam<T, S, ParamIndex> _Type;
+
+public:
+    /// Default constructor. Port/direction and stream-ID is undefined.
+    inline C2StreamParam() : T(sizeof(_Type), _Type::PARAM_TYPE) { }
+    /// Wrapper around base structure's constructor while also specifying port/direction and
+    /// stream-ID.
+    template<typename ...Args>
+    inline C2StreamParam(bool _output, unsigned stream, const Args(&... args))
+        : T(sizeof(_Type), _output ? output::PARAM_TYPE : input::PARAM_TYPE, stream),
+          S(args...) { }
+    /// Set port/direction.
+    inline void setPort(bool output) { C2Param::setPort(output); }
+    /// Set stream-id. \retval true if the stream-id was successfully set.
+    inline bool setStream(unsigned stream) { return C2Param::setStream(stream); }
+
+    DEFINE_CAST_OPERATORS(_Type)
+
+    /// Specialization for an input stream parameter.
+    struct input : public T, public S,
+            public _C2StructCheck<S, ParamIndex,
+                    T::PARAM_KIND | T::Index::IS_STREAM_FLAG | T::Type::DIR_INPUT> {
+        _C2_CORE_INDEX_OVERRIDE(ParamIndex)
+
+        /// Default constructor. Stream-ID is undefined.
+        inline input() : T(sizeof(_Type), input::PARAM_TYPE) { }
+        /// Wrapper around base structure's constructor while also specifying stream-ID.
+        template<typename ...Args>
+        inline input(unsigned stream, const Args(&... args))
+            : T(sizeof(_Type), input::PARAM_TYPE, stream), S(args...) { }
+        /// Set stream-id. \retval true if the stream-id was successfully set.
+        inline bool setStream(unsigned stream) { return C2Param::setStream(stream); }
+
+        DEFINE_CAST_OPERATORS(input)
+    };
+
+    /// Specialization for an output stream parameter.
+    struct output : public T, public S,
+            public _C2StructCheck<S, ParamIndex,
+                    T::PARAM_KIND | T::Index::IS_STREAM_FLAG | T::Type::DIR_OUTPUT> {
+        _C2_CORE_INDEX_OVERRIDE(ParamIndex)
+
+        /// Default constructor. Stream-ID is undefined.
+        inline output() : T(sizeof(_Type), output::PARAM_TYPE) { }
+        /// Wrapper around base structure's constructor while also specifying stream-ID.
+        template<typename ...Args>
+        inline output(unsigned stream, const Args(&... args))
+            : T(sizeof(_Type), output::PARAM_TYPE, stream), S(args...) { }
+        /// Set stream-id. \retval true if the stream-id was successfully set.
+        inline bool setStream(unsigned stream) { return C2Param::setStream(stream); }
+
+        DEFINE_CAST_OPERATORS(output)
+    };
+};
+
+/**
+ * Stream-parameter template for flexible structures.
+ *
+ * Base template to define a stream setting/tuning or info based on a flexible structure and
+ * an optional ParamIndex. Stream parameters are tied to a specific stream on a port (input or
+ * output).
+ *
+ * \tparam T param type C2Setting, C2Tuning or C2Info
+ * \tparam S wrapped flexible structure
+ * \tparam ParamIndex optional parameter index override. Must be specified for base/reused
+ *         structures.
+ *
+ * Parameters wrap structures by prepending a (parameter) header. The fields and methods of flexible
+ * structures can be accessed via the m member variable; however, the constructors of the structure
+ * are wrapped directly. (This is because flexible types cannot be subclassed.)
+ *
+ * There are 3 flavors of stream parameters: unspecified port, input and output. All of these expose
+ * a setStream method and an extra initial streamID parameter for the constructor. Moreover,
+ * parameters with unspecified port expose a setPort method, and add an additional initial port
+ * parameter to the constructor.
+ */
+template<typename T, typename S, int ParamIndex>
+struct C2_HIDE C2StreamParam<T, S, ParamIndex, IF_FLEXIBLE(S)>
+    : public T,
+      public _C2FlexStructCheck<S, ParamIndex,
+              T::PARAM_KIND | T::Index::IS_STREAM_FLAG | T::Index::DIR_UNDEFINED> {
+private:
+    typedef C2StreamParam<T, S, ParamIndex> _Type;
+    /// Default constructor. Port/direction and stream-ID is undefined.
+    inline C2StreamParam(size_t flexCount) : T(_Type::CalcSize(flexCount), _Type::PARAM_TYPE, 0u) { }
+    /// Wrapper around base structure's constructor while also specifying port/direction and
+    /// stream-ID.
+    template<typename ...Args>
+    inline C2StreamParam(size_t flexCount, bool _output, unsigned stream, const Args(&... args))
+        : T(_Type::CalcSize(flexCount), _output ? output::PARAM_TYPE : input::PARAM_TYPE, stream),
+          m(flexCount, args...) { }
+
+public:
+    S m; ///< wrapped flexible structure
+
+    /// Set port/direction.
+    inline void setPort(bool output) { C2Param::setPort(output); }
+    /// Set stream-id. \retval true if the stream-id was successfully set.
+    inline bool setStream(unsigned stream) { return C2Param::setStream(stream); }
+
+    DEFINE_FLEXIBLE_METHODS(_Type, S)
+    DEFINE_CAST_OPERATORS(_Type)
+
+    /// Specialization for an input stream parameter.
+    struct input : public T,
+            public _C2FlexStructCheck<S, ParamIndex,
+                    T::PARAM_KIND | T::Index::IS_STREAM_FLAG | T::Type::DIR_INPUT> {
+    private:
+        /// Default constructor. Stream-ID is undefined.
+        inline input(size_t flexCount) : T(_Type::CalcSize(flexCount), input::PARAM_TYPE) { }
+        /// Wrapper around base structure's constructor while also specifying stream-ID.
+        template<typename ...Args>
+        inline input(size_t flexCount, unsigned stream, const Args(&... args))
+            : T(_Type::CalcSize(flexCount), input::PARAM_TYPE, stream), m(flexCount, args...) { }
+
+    public:
+        S m; ///< wrapped flexible structure
+
+        /// Set stream-id. \retval true if the stream-id was successfully set.
+        inline bool setStream(unsigned stream) { return C2Param::setStream(stream); }
+
+        DEFINE_FLEXIBLE_METHODS(input, S)
+        DEFINE_CAST_OPERATORS(input)
+    };
+
+    /// Specialization for an output stream parameter.
+    struct output : public T,
+            public _C2FlexStructCheck<S, ParamIndex,
+                    T::PARAM_KIND | T::Index::IS_STREAM_FLAG | T::Type::DIR_OUTPUT> {
+    private:
+        /// Default constructor. Stream-ID is undefined.
+        inline output(size_t flexCount) : T(_Type::CalcSize(flexCount), output::PARAM_TYPE) { }
+        /// Wrapper around base structure's constructor while also specifying stream-ID.
+        template<typename ...Args>
+        inline output(size_t flexCount, unsigned stream, const Args(&... args))
+            : T(_Type::CalcSize(flexCount), output::PARAM_TYPE, stream), m(flexCount, args...) { }
+
+    public:
+        S m; ///< wrapped flexible structure
+
+        /// Set stream-id. \retval true if the stream-id was successfully set.
+        inline bool setStream(unsigned stream) { return C2Param::setStream(stream); }
+
+        DEFINE_FLEXIBLE_METHODS(output, S)
+        DEFINE_CAST_OPERATORS(output)
+    };
+};
+
+/* ======================== SIMPLE VALUE PARAMETERS ======================== */
+
+/**
+ * \ingroup internal
+ * A structure template encapsulating a single element with default constructors and no core-index.
+ */
+template<typename T>
+struct C2SimpleValueStruct {
+    T value; ///< simple value of the structure
+    // Default constructor.
+    inline C2SimpleValueStruct() = default;
+    // Constructor with an initial value.
+    inline C2SimpleValueStruct(T value) : value(value) {}
+    DEFINE_BASE_C2STRUCT(SimpleValue)
+};
+
+// TODO: move this and next to some generic place
+/**
+ * Interface to a block of (mapped) memory containing an array of some type (T).
+ */
+template<typename T>
+struct C2MemoryBlock {
+    /// \returns the number of elements in this block.
+    virtual size_t size() const = 0;
+    /// \returns a const pointer to the start of this block. Care must be taken to not read outside
+    /// the block.
+    virtual const T *data() const = 0; // TODO: should this be friend access only in some C2Memory module?
+    /// \returns a pointer to the start of this block. Care must be taken to not read or write
+    /// outside the block.
+    inline T *data() { return const_cast<T*>(const_cast<const C2MemoryBlock*>(this)->data()); }
+
+protected:
+    // TODO: for now it should never be deleted as C2MemoryBlock
+    virtual ~C2MemoryBlock() = default;
+};
+
+/**
+ * Interface to a block of memory containing a constant (constexpr) array of some type (T).
+ */
+template<typename T>
+struct C2ConstMemoryBlock : public C2MemoryBlock<T> {
+    virtual const T * data() const { return _mData; }
+    virtual size_t size() const { return _mSize; }
+
+    /// Constructor.
+    template<unsigned N>
+    inline constexpr C2ConstMemoryBlock(const T(&init)[N]) : _mData(init), _mSize(N) {}
+
+private:
+    const T *_mData;
+    const size_t _mSize;
+};
+
+/// \addtogroup internal
+/// @{
+
+/// Helper class to initialize flexible arrays with various initalizers.
+struct _C2ValueArrayHelper {
+    // char[]-s are used as null terminated strings, so the last element is never inited.
+
+    /// Initialize a flexible array using a constexpr memory block.
+    template<typename T>
+    static void init(T(&array)[], size_t arrayLen, const C2MemoryBlock<T> &block) {
+        // reserve last element for terminal 0 for strings
+        if (arrayLen && std::is_same<T, char>::value) {
+            --arrayLen;
+        }
+        if (block.data()) {
+            memcpy(array, block.data(), std::min(arrayLen, block.size()) * sizeof(T));
+        }
+    }
+
+    /// Initialize a flexible array using an initializer list.
+    template<typename T>
+    static void init(T(&array)[], size_t arrayLen, const std::initializer_list<T> &init) {
+        size_t ix = 0;
+        // reserve last element for terminal 0 for strings
+        if (arrayLen && std::is_same<T, char>::value) {
+            --arrayLen;
+        }
+        for (const T &item : init) {
+            if (ix == arrayLen) {
+                break;
+            }
+            array[ix++] = item;
+        }
+    }
+
+    /// Initialize a flexible array using a vector.
+    template<typename T>
+    static void init(T(&array)[], size_t arrayLen, const std::vector<T> &init) {
+        size_t ix = 0;
+        // reserve last element for terminal 0 for strings
+        if (arrayLen && std::is_same<T, char>::value) {
+            --arrayLen;
+        }
+        for (const T &item : init) {
+            if (ix == arrayLen) {
+                break;
+            }
+            array[ix++] = item;
+        }
+    }
+
+    /// Initialize a flexible array using another flexible array.
+    template<typename T, unsigned N>
+    static void init(T(&array)[], size_t arrayLen, const T(&str)[N]) {
+        // reserve last element for terminal 0 for strings
+        if (arrayLen && std::is_same<T, char>::value) {
+            --arrayLen;
+        }
+        if (arrayLen) {
+            memcpy(array, str, std::min(arrayLen, (size_t)N) * sizeof(T));
+        }
+    }
+};
+
+/**
+ * Specialization for a flexible blob and string arrays. A structure template encapsulating a single
+ * flexible array member with default flexible constructors and no core-index. This type cannot be
+ * constructed on its own as it's size is 0.
+ *
+ * \internal This is different from C2SimpleArrayStruct<T[]> simply because its member has the name
+ * as value to reflect this is a single value.
+ */
+template<typename T>
+struct C2SimpleValueStruct<T[]> {
+    static_assert(std::is_same<T, char>::value || std::is_same<T, uint8_t>::value,
+                  "C2SimpleValueStruct<T[]> is only for BLOB or STRING");
+    T value[];
+
+    inline C2SimpleValueStruct() = default;
+    DEFINE_BASE_C2STRUCT(SimpleValue)
+    FLEX(C2SimpleValueStruct, value)
+
+private:
+    inline C2SimpleValueStruct(size_t flexCount, const C2MemoryBlock<T> &block) {
+        _C2ValueArrayHelper::init(value, flexCount, block);
+    }
+
+    inline C2SimpleValueStruct(size_t flexCount, const std::initializer_list<T> &init) {
+        _C2ValueArrayHelper::init(value, flexCount, init);
+    }
+
+    inline C2SimpleValueStruct(size_t flexCount, const std::vector<T> &init) {
+        _C2ValueArrayHelper::init(value, flexCount, init);
+    }
+
+    template<unsigned N>
+    inline C2SimpleValueStruct(size_t flexCount, const T(&init)[N]) {
+        _C2ValueArrayHelper::init(value, flexCount, init);
+    }
+};
+
+/// @}
+
+/**
+ * A structure template encapsulating a single flexible array element of a specific type (T) with
+ * default constructors and no core-index. This type cannot be constructed on its own as it's size
+ * is 0. Instead, it is meant to be used as a parameter, e.g.
+ *
+ *   typedef C2StreamParam<C2Info, C2SimpleArrayStruct<C2MyFancyStruct>,
+ *           kParamIndexMyFancyArrayStreamParam> C2MyFancyArrayStreamInfo;
+ */
+template<typename T>
+struct C2SimpleArrayStruct {
+    static_assert(!std::is_same<T, char>::value && !std::is_same<T, uint8_t>::value,
+                  "use C2SimpleValueStruct<T[]> is for BLOB or STRING");
+
+    T values[]; ///< array member
+    /// Default constructor
+    inline C2SimpleArrayStruct() = default;
+    DEFINE_BASE_FLEX_C2STRUCT(SimpleArray, values)
+    //FLEX(C2SimpleArrayStruct, values)
+
+private:
+    /// Construct from a C2MemoryBlock.
+    /// Used only by the flexible parameter allocators (AllocUnique & AllocShared).
+    inline C2SimpleArrayStruct(size_t flexCount, const C2MemoryBlock<T> &block) {
+        _C2ValueArrayHelper::init(values, flexCount, block);
+    }
+
+    /// Construct from an initializer list.
+    /// Used only by the flexible parameter allocators (AllocUnique & AllocShared).
+    inline C2SimpleArrayStruct(size_t flexCount, const std::initializer_list<T> &init) {
+        _C2ValueArrayHelper::init(values, flexCount, init);
+    }
+
+    /// Construct from an vector.
+    /// Used only by the flexible parameter allocators (AllocUnique & AllocShared).
+    inline C2SimpleArrayStruct(size_t flexCount, const std::vector<T> &init) {
+        _C2ValueArrayHelper::init(values, flexCount, init);
+    }
+
+    /// Construct from another flexible array.
+    /// Used only by the flexible parameter allocators (AllocUnique & AllocShared).
+    template<unsigned N>
+    inline C2SimpleArrayStruct(size_t flexCount, const T(&init)[N]) {
+        _C2ValueArrayHelper::init(values, flexCount, init);
+    }
+};
+
+/**
+ * \addtogroup simplevalue Simple value and array structures.
+ * @{
+ *
+ * Simple value structures.
+ *
+ * Structures containing a single simple value. These can be reused to easily define simple
+ * parameters of various types:
+ *
+ *   typedef C2PortParam<C2Tuning, C2Int32Value, kParamIndexMyIntegerPortParam>
+ *           C2MyIntegerPortParamTuning;
+ *
+ * They contain a single member (value or values) that is described as "value" or "values".
+ *
+ * These structures don't define a core index, and as such, they cannot be used in structure
+ * declarations. Use type[] instead, such as int32_t field[].
+ */
+/// A 32-bit signed integer parameter in value, described as "value"
+typedef C2SimpleValueStruct<int32_t> C2Int32Value;
+/// A 32-bit signed integer array parameter in values, described as "values"
+typedef C2SimpleArrayStruct<int32_t> C2Int32Array;
+/// A 32-bit unsigned integer parameter in value, described as "value"
+typedef C2SimpleValueStruct<uint32_t> C2Uint32Value;
+/// A 32-bit unsigned integer array parameter in values, described as "values"
+typedef C2SimpleArrayStruct<uint32_t> C2Uint32Array;
+/// A 64-bit signed integer parameter in value, described as "value"
+typedef C2SimpleValueStruct<int64_t> C2Int64Value;
+/// A 64-bit signed integer array parameter in values, described as "values"
+typedef C2SimpleArrayStruct<int64_t> C2Int64Array;
+/// A 64-bit unsigned integer parameter in value, described as "value"
+typedef C2SimpleValueStruct<uint64_t> C2Uint64Value;
+/// A 64-bit unsigned integer array parameter in values, described as "values"
+typedef C2SimpleArrayStruct<uint64_t> C2Uint64Array;
+/// A float parameter in value, described as "value"
+typedef C2SimpleValueStruct<float> C2FloatValue;
+/// A float array parameter in values, described as "values"
+typedef C2SimpleArrayStruct<float> C2FloatArray;
+/// A blob flexible parameter in value, described as "value"
+typedef C2SimpleValueStruct<uint8_t[]> C2BlobValue;
+/// A string flexible parameter in value, described as "value"
+typedef C2SimpleValueStruct<char[]> C2StringValue;
+
+template<typename T>
+const std::vector<C2FieldDescriptor> C2SimpleValueStruct<T>::FieldList() {
+    return { DESCRIBE_C2FIELD(value, "value") };
+}
+template<typename T>
+const std::vector<C2FieldDescriptor> C2SimpleValueStruct<T[]>::FieldList() {
+    return { DESCRIBE_C2FIELD(value, "value") };
+}
+template<typename T>
+const std::vector<C2FieldDescriptor> C2SimpleArrayStruct<T>::FieldList() {
+    return { DESCRIBE_C2FIELD(values, "values") };
+}
+
+/// @}
+
+/// @}
+
+#endif  // C2PARAM_DEF_H_
diff --git a/media/codec2/core/include/C2Work.h b/media/codec2/core/include/C2Work.h
new file mode 100644
index 0000000..6923f3e
--- /dev/null
+++ b/media/codec2/core/include/C2Work.h
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef C2WORK_H_
+
+#define C2WORK_H_
+
+#include <C2Buffer.h>
+#include <C2Param.h>
+
+#include <memory>
+#include <list>
+#include <vector>
+
+#include <stdint.h>
+#include <stdbool.h>
+
+/// \defgroup work Work and data processing
+/// @{
+
+/**
+ * Information describing the reason a parameter settings may fail, or
+ * may be overriden.
+ */
+struct C2SettingResult {
+    enum Failure : uint32_t {
+        /* parameter failures below */
+        BAD_TYPE,   ///< parameter is not supported
+        BAD_PORT,   ///< parameter is not supported on the specific port
+        BAD_INDEX,  ///< parameter is not supported on the specific stream
+        READ_ONLY,  ///< parameter is read-only and cannot be set
+        MISMATCH,   ///< parameter mismatches input data
+
+        /* field failures below */
+        BAD_VALUE,  ///< strict parameter does not accept value for the field at all
+        CONFLICT,   ///< strict parameter field value is in conflict with an/other setting(s)
+
+        /// parameter field is out of range due to other settings (this failure mode
+        /// can only be used for strict calculated parameters)
+        UNSUPPORTED,
+
+        /// field does not access the requested parameter value at all. It has been corrected to
+        /// the closest supported value. This failure mode is provided to give guidance as to what
+        /// are the currently supported values for this field (which may be a subset of the at-all-
+        /// potential values)
+        INFO_BAD_VALUE,
+
+        /// requested parameter value is in conflict with an/other setting(s)
+        /// and has been corrected to the closest supported value. This failure
+        /// mode is given to provide guidance as to what are the currently supported values as well
+        /// as to optionally provide suggestion to the client as to how to enable the requested
+        /// parameter value.
+        INFO_CONFLICT,
+    };
+
+    Failure failure;    ///< failure code
+
+    /// Failing (or corrected) field or parameterand optionally, currently supported values for the
+    /// field. Values must only be set for field failures other than BAD_VALUE, and only if they are
+    /// different from the globally supported values (e.g. due to restrictions by another param or
+    /// input data).
+    C2ParamFieldValues field;
+
+    /// Conflicting parameters or fields with optional suggestions with (optional) suggested values
+    /// for any conflicting fields to avoid the conflict. Must only be set for CONFLICT, UNSUPPORTED
+    /// and INFO_CONFLICT failure codes.
+    std::vector<C2ParamFieldValues> conflicts;
+};
+
+// ================================================================================================
+//  WORK
+// ================================================================================================
+
+/** Unique ID for a processing node. */
+typedef uint32_t c2_node_id_t;
+
+enum {
+    kParamIndexWorkOrdinal,
+};
+
+/**
+ * Information for ordering work items on a component port.
+ */
+struct C2WorkOrdinalStruct {
+//public:
+    c2_cntr64_t timestamp;     /** frame timestamp in microseconds */
+    c2_cntr64_t frameIndex;    /** submission ordinal on the initial component */
+    c2_cntr64_t customOrdinal; /** can be given by the component, e.g. decode order */
+
+    DEFINE_AND_DESCRIBE_C2STRUCT(WorkOrdinal)
+    C2FIELD(timestamp, "timestamp")
+    C2FIELD(frameIndex, "frame-index")
+    C2FIELD(customOrdinal, "custom-ordinal")
+};
+
+/**
+ * This structure represents a Codec 2.0 frame with its metadata.
+ *
+ * A frame basically consists of an ordered sets of buffers, configuration changes and info buffers
+ * along with some non-configuration metadata.
+ */
+struct C2FrameData {
+//public:
+    enum flags_t : uint32_t {
+        /**
+         * For input frames: no output frame shall be generated when processing this frame, but
+         * metadata shall still be processed.
+         * For output frames: this frame shall be discarded and but metadata is still valid.
+         */
+        FLAG_DROP_FRAME    = (1 << 0),
+        /**
+         * This frame is the last frame of the current stream. Further frames are part of a new
+         * stream.
+         */
+        FLAG_END_OF_STREAM = (1 << 1),
+        /**
+         * This frame shall be discarded with its metadata.
+         * This flag is only set by components - e.g. as a response to the flush command.
+         */
+        FLAG_DISCARD_FRAME = (1 << 2),
+        /**
+         * This frame is not the last frame produced for the input.
+         *
+         * This flag is normally set by the component - e.g. when an input frame results in multiple
+         * output frames, this flag is set on all but the last output frame.
+         *
+         * Also, when components are chained, this flag should be propagated down the
+         * work chain. That is, if set on an earlier frame of a work-chain, it should be propagated
+         * to all later frames in that chain. Additionally, components down the chain could set
+         * this flag even if not set earlier, e.g. if multiple output frame is generated at that
+         * component for the input frame.
+         */
+        FLAG_INCOMPLETE = (1 << 3),
+        /**
+         * This frame contains only codec-specific configuration data, and no actual access unit.
+         *
+         * \deprecated pass codec configuration with using the \todo codec-specific configuration
+         * info together with the access unit.
+         */
+        FLAG_CODEC_CONFIG  = (1u << 31),
+    };
+
+    /**
+     * Frame flags */
+    flags_t  flags;
+    C2WorkOrdinalStruct ordinal;
+    std::vector<std::shared_ptr<C2Buffer>> buffers;
+    //< for initial work item, these may also come from the parser - if provided
+    //< for output buffers, these are the responses to requestedInfos
+    std::vector<std::unique_ptr<C2Param>>      configUpdate;
+    std::vector<std::shared_ptr<C2InfoBuffer>> infoBuffers;
+};
+
+struct C2Worklet {
+//public:
+    // IN
+    c2_node_id_t component;
+
+    /** Configuration changes to be applied before processing this worklet. */
+    std::vector<std::unique_ptr<C2Tuning>> tunings;
+    std::vector<std::unique_ptr<C2SettingResult>> failures;
+
+    // OUT
+    C2FrameData output;
+};
+
+/**
+ * Information about partial work-chains not part of the current work items.
+ *
+ * To be defined later.
+ */
+struct C2WorkChainInfo;
+
+/**
+ * This structure holds information about all a single work item.
+ *
+ * This structure shall be passed by the client to the component for the first worklet. As such,
+ * worklets must not be empty. The ownership of this object is passed.
+ */
+struct C2Work {
+//public:
+    /// additional work chain info not part of this work
+    std::shared_ptr<C2WorkChainInfo> chainInfo;
+
+    /// The input data to be processed as part of this work/work-chain. This is provided by the
+    /// client with ownership. When the work is returned (via onWorkDone), the input buffer-pack's
+    /// buffer vector shall contain nullptrs.
+    C2FrameData input;
+
+    /// The chain of components, tunings (including output buffer pool IDs) and info requests that the
+    /// data must pass through. If this has more than a single element, the tunnels between successive
+    /// components of the worklet chain must have been (successfully) pre-registered at the time that
+    /// the work is submitted. Allocating the output buffers in the worklets is the responsibility of
+    /// each component. Upon work submission, each output buffer-pack shall be an appropriately sized
+    /// vector containing nullptrs. When the work is completed/returned to the client, output buffers
+    /// pointers from all but the final worklet shall be nullptrs.
+    std::list<std::unique_ptr<C2Worklet>> worklets;
+
+    /// Number of worklets successfully processed in this chain. This shall be initialized to 0 by the
+    /// client when the work is submitted. It shall contain the number of worklets that were
+    /// successfully processed when the work is returned to the client. If this is less then the number
+    /// of worklets, result must not be success. It must be in the range of [0, worklets.size()].
+    uint32_t workletsProcessed;
+
+    /// The final outcome of the work (corresponding to the current workletsProcessed). If 0 when
+    /// work is returned, it is assumed that all worklets have been processed.
+    c2_status_t result;
+};
+
+/**
+ * Information about a future work to be submitted to the component. The information is used to
+ * reserve the work for work ordering purposes.
+ */
+struct C2WorkOutline {
+//public:
+    C2WorkOrdinalStruct ordinal;
+    std::vector<c2_node_id_t> chain;
+};
+
+/// @}
+
+#endif  // C2WORK_H_
diff --git a/media/codec2/core/include/_C2MacroUtils.h b/media/codec2/core/include/_C2MacroUtils.h
new file mode 100644
index 0000000..04e9ba5
--- /dev/null
+++ b/media/codec2/core/include/_C2MacroUtils.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef C2UTILS_MACRO_UTILS_H_
+#define C2UTILS_MACRO_UTILS_H_
+
+/** \file
+ * Macro utilities for the utils library used by Codec2 implementations.
+ */
+
+/// \if 0
+
+/* --------------------------------- VARIABLE ARGUMENT COUNTING --------------------------------- */
+
+// remove empty arguments - _C2_ARG() expands to '', while _C2_ARG(x) expands to ', x'
+// _C2_ARGn(...) does the same for n arguments
+#define _C2_ARG(...) , ##__VA_ARGS__
+#define _C2_ARG2(_1, _2) _C2_ARG(_1) _C2_ARG(_2)
+#define _C2_ARG4(_1, _2, _3, _4) _C2_ARG2(_1, _2) _C2_ARG2(_3, _4)
+#define _C2_ARG8(_1, _2, _3, _4, _5, _6, _7, _8) _C2_ARG4(_1, _2, _3, _4) _C2_ARG4(_5, _6, _7, _8)
+#define _C2_ARG16(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \
+        _C2_ARG8(_1, _2, _3, _4, _5, _6, _7, _8) _C2_ARG8(_9, _10, _11, _12, _13, _14, _15, _16)
+
+// return the 65th argument
+#define _C2_ARGC_3(_, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, \
+        _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, \
+        _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, \
+        _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, ...) _64
+
+/// \endif
+
+/**
+ * Returns the number of arguments.
+ */
+// We do this by prepending 1 and appending 65 designed values such that the 65th element
+// will be the number of arguments.
+#define _C2_ARGC(...) _C2_ARGC_1(0, ##__VA_ARGS__, \
+        64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, \
+        42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, \
+        20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
+
+/// \if 0
+
+// step 1. remove empty arguments - this is needed to allow trailing comma in enum definitions
+// (NOTE: we don't know which argument will have this trailing comma so we have to try all)
+#define _C2_ARGC_1(_, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, \
+        _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, \
+        _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, \
+        _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, ...) \
+    _C2_ARGC_2(_ _C2_ARG(_0) \
+    _C2_ARG16(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \
+    _C2_ARG16(_17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32) \
+    _C2_ARG16(_33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48) \
+    _C2_ARG16(_49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64), \
+    ##__VA_ARGS__)
+
+// step 2. this is needed as removed arguments cannot be passed directly as empty into a macro
+#define _C2_ARGC_2(...) _C2_ARGC_3(__VA_ARGS__)
+
+/// \endif
+
+/* -------------------------------- VARIABLE ARGUMENT CONVERSION -------------------------------- */
+
+/// \if 0
+
+// macros that convert _1, _2, _3, ... to fn(_1, arg), fn(_2, arg), fn(_3, arg), ...
+#define _C2_MAP_64(fn, arg, head, ...) fn(head, arg), _C2_MAP_63(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_63(fn, arg, head, ...) fn(head, arg), _C2_MAP_62(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_62(fn, arg, head, ...) fn(head, arg), _C2_MAP_61(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_61(fn, arg, head, ...) fn(head, arg), _C2_MAP_60(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_60(fn, arg, head, ...) fn(head, arg), _C2_MAP_59(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_59(fn, arg, head, ...) fn(head, arg), _C2_MAP_58(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_58(fn, arg, head, ...) fn(head, arg), _C2_MAP_57(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_57(fn, arg, head, ...) fn(head, arg), _C2_MAP_56(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_56(fn, arg, head, ...) fn(head, arg), _C2_MAP_55(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_55(fn, arg, head, ...) fn(head, arg), _C2_MAP_54(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_54(fn, arg, head, ...) fn(head, arg), _C2_MAP_53(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_53(fn, arg, head, ...) fn(head, arg), _C2_MAP_52(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_52(fn, arg, head, ...) fn(head, arg), _C2_MAP_51(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_51(fn, arg, head, ...) fn(head, arg), _C2_MAP_50(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_50(fn, arg, head, ...) fn(head, arg), _C2_MAP_49(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_49(fn, arg, head, ...) fn(head, arg), _C2_MAP_48(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_48(fn, arg, head, ...) fn(head, arg), _C2_MAP_47(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_47(fn, arg, head, ...) fn(head, arg), _C2_MAP_46(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_46(fn, arg, head, ...) fn(head, arg), _C2_MAP_45(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_45(fn, arg, head, ...) fn(head, arg), _C2_MAP_44(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_44(fn, arg, head, ...) fn(head, arg), _C2_MAP_43(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_43(fn, arg, head, ...) fn(head, arg), _C2_MAP_42(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_42(fn, arg, head, ...) fn(head, arg), _C2_MAP_41(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_41(fn, arg, head, ...) fn(head, arg), _C2_MAP_40(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_40(fn, arg, head, ...) fn(head, arg), _C2_MAP_39(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_39(fn, arg, head, ...) fn(head, arg), _C2_MAP_38(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_38(fn, arg, head, ...) fn(head, arg), _C2_MAP_37(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_37(fn, arg, head, ...) fn(head, arg), _C2_MAP_36(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_36(fn, arg, head, ...) fn(head, arg), _C2_MAP_35(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_35(fn, arg, head, ...) fn(head, arg), _C2_MAP_34(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_34(fn, arg, head, ...) fn(head, arg), _C2_MAP_33(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_33(fn, arg, head, ...) fn(head, arg), _C2_MAP_32(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_32(fn, arg, head, ...) fn(head, arg), _C2_MAP_31(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_31(fn, arg, head, ...) fn(head, arg), _C2_MAP_30(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_30(fn, arg, head, ...) fn(head, arg), _C2_MAP_29(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_29(fn, arg, head, ...) fn(head, arg), _C2_MAP_28(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_28(fn, arg, head, ...) fn(head, arg), _C2_MAP_27(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_27(fn, arg, head, ...) fn(head, arg), _C2_MAP_26(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_26(fn, arg, head, ...) fn(head, arg), _C2_MAP_25(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_25(fn, arg, head, ...) fn(head, arg), _C2_MAP_24(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_24(fn, arg, head, ...) fn(head, arg), _C2_MAP_23(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_23(fn, arg, head, ...) fn(head, arg), _C2_MAP_22(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_22(fn, arg, head, ...) fn(head, arg), _C2_MAP_21(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_21(fn, arg, head, ...) fn(head, arg), _C2_MAP_20(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_20(fn, arg, head, ...) fn(head, arg), _C2_MAP_19(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_19(fn, arg, head, ...) fn(head, arg), _C2_MAP_18(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_18(fn, arg, head, ...) fn(head, arg), _C2_MAP_17(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_17(fn, arg, head, ...) fn(head, arg), _C2_MAP_16(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_16(fn, arg, head, ...) fn(head, arg), _C2_MAP_15(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_15(fn, arg, head, ...) fn(head, arg), _C2_MAP_14(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_14(fn, arg, head, ...) fn(head, arg), _C2_MAP_13(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_13(fn, arg, head, ...) fn(head, arg), _C2_MAP_12(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_12(fn, arg, head, ...) fn(head, arg), _C2_MAP_11(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_11(fn, arg, head, ...) fn(head, arg), _C2_MAP_10(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_10(fn, arg, head, ...) fn(head, arg), _C2_MAP_9(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_9(fn, arg, head, ...) fn(head, arg), _C2_MAP_8(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_8(fn, arg, head, ...) fn(head, arg), _C2_MAP_7(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_7(fn, arg, head, ...) fn(head, arg), _C2_MAP_6(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_6(fn, arg, head, ...) fn(head, arg), _C2_MAP_5(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_5(fn, arg, head, ...) fn(head, arg), _C2_MAP_4(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_4(fn, arg, head, ...) fn(head, arg), _C2_MAP_3(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_3(fn, arg, head, ...) fn(head, arg), _C2_MAP_2(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_2(fn, arg, head, ...) fn(head, arg), _C2_MAP_1(fn, arg, ##__VA_ARGS__)
+#define _C2_MAP_1(fn, arg, head, ...) fn(head, arg)
+
+/// \endif
+
+/**
+ * Maps each argument using another macro x -> fn(x, arg)
+ */
+// use wrapper to call the proper mapper based on the number of arguments
+#define _C2_MAP(fn, arg, ...) _C2_MAP__(_C2_ARGC(__VA_ARGS__), fn, arg, ##__VA_ARGS__)
+
+/// \if 0
+
+// evaluate _n so it becomes a number
+#define _C2_MAP__(_n, fn, arg, ...) _C2_MAP_(_n, fn, arg, __VA_ARGS__)
+// call the proper mapper
+#define _C2_MAP_(_n, fn, arg, ...) _C2_MAP_##_n (fn, arg, __VA_ARGS__)
+
+/// \endif
+
+#endif  // C2UTILS_MACRO_UTILS_H_
diff --git a/media/codec2/core/include/android-C2Buffer.h b/media/codec2/core/include/android-C2Buffer.h
new file mode 100644
index 0000000..26beab7
--- /dev/null
+++ b/media/codec2/core/include/android-C2Buffer.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2BUFFER_H_
+#define ANDROID_C2BUFFER_H_
+
+#include <cutils/native_handle.h>
+#include <hardware/gralloc.h>
+
+/* Use android native handle for C2Handle */
+typedef ::native_handle_t C2Handle;
+
+namespace android {
+
+/**
+ * Android platform buffer/memory usage bits.
+ */
+struct C2AndroidMemoryUsage : public C2MemoryUsage {
+    inline C2AndroidMemoryUsage(const C2MemoryUsage &usage) : C2MemoryUsage(usage) { }
+
+// public:
+    /**
+     * Reuse gralloc flags where possible, as Codec 2.0 API only uses bits 0 and 1.
+     */
+    enum consumer_t : uint64_t {
+        RENDERSCRIPT_READ = GRALLOC_USAGE_RENDERSCRIPT,
+        HW_TEXTURE_READ   = GRALLOC_USAGE_HW_TEXTURE,
+        HW_COMPOSER_READ  = GRALLOC_USAGE_HW_COMPOSER,
+        // gralloc does not define a video decoder read usage flag, so use encoder for
+        // now
+        HW_CODEC_READ     = GRALLOC_USAGE_HW_VIDEO_ENCODER,
+        READ_PROTECTED    = GRALLOC_USAGE_PROTECTED,
+    };
+
+    enum producer_t : uint64_t {
+        RENDERSCRIPT_WRITE = GRALLOC_USAGE_RENDERSCRIPT,
+        HW_TEXTURE_WRITE   = GRALLOC_USAGE_HW_RENDER,
+        HW_COMPOSER_WRITE  = GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_RENDER,
+        HW_CODEC_WRITE     = GRALLOC_USAGE_HW_VIDEO_ENCODER,
+        // gralloc does not define a write protected usage flag, so use read protected
+        // now
+        WRITE_PROTECTED    = GRALLOC_USAGE_PROTECTED,
+    };
+
+    /**
+     * Convert from gralloc usage.
+     */
+    static C2MemoryUsage FromGrallocUsage(uint64_t usage);
+
+    /**
+     * Convert to gralloc usage.
+     */
+    uint64_t asGrallocUsage() const;
+};
+
+}  // namespace android
+
+#endif  // ANDROID_C2BUFFER_H_
diff --git a/media/codec2/core/include/media/stagefright/codec2/1.0/InputSurface.h b/media/codec2/core/include/media/stagefright/codec2/1.0/InputSurface.h
new file mode 100644
index 0000000..0a82a68
--- /dev/null
+++ b/media/codec2/core/include/media/stagefright/codec2/1.0/InputSurface.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_C2_V1_0_INPUT_SURFACE_H
+#define ANDROID_HARDWARE_MEDIA_C2_V1_0_INPUT_SURFACE_H
+
+#include <memory>
+
+#include <C2Component.h>
+#include <media/stagefright/codec2/1.0/InputSurfaceConnection.h>
+
+namespace android {
+
+class GraphicBufferSource;
+
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::sp;
+
+typedef ::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer
+        HGraphicBufferProducer;
+typedef ::android::IGraphicBufferProducer BGraphicBufferProducer;
+
+// TODO: ::android::TWGraphicBufferProducer<IInputSurface>
+typedef ::android::TWGraphicBufferProducer<HGraphicBufferProducer> InputSurfaceBase;
+
+class InputSurface : public InputSurfaceBase {
+public:
+    virtual ~InputSurface() = default;
+
+    // Methods from IInputSurface
+    sp<InputSurfaceConnection> connectToComponent(
+            const std::shared_ptr<::C2Component> &comp);
+    // TODO: intf()
+
+    static sp<InputSurface> Create();
+
+private:
+    InputSurface(
+            const sp<BGraphicBufferProducer> &base,
+            const sp<::android::GraphicBufferSource> &source);
+
+    sp<::android::GraphicBufferSource> mSource;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace c2
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_MEDIA_C2_V1_0_INPUT_SURFACE_H
diff --git a/media/codec2/core/include/media/stagefright/codec2/1.0/InputSurfaceConnection.h b/media/codec2/core/include/media/stagefright/codec2/1.0/InputSurfaceConnection.h
new file mode 100644
index 0000000..5eae3af
--- /dev/null
+++ b/media/codec2/core/include/media/stagefright/codec2/1.0/InputSurfaceConnection.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_C2_V1_0_INPUT_SURFACE_CONNECTION_H
+#define ANDROID_HARDWARE_MEDIA_C2_V1_0_INPUT_SURFACE_CONNECTION_H
+
+#include <memory>
+
+#include <C2Component.h>
+#include <media/stagefright/bqhelper/GraphicBufferSource.h>
+#include <media/stagefright/codec2/1.0/InputSurfaceConnection.h>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_0 {
+namespace implementation {
+
+// TODO: inherit from IInputSurfaceConnection
+class InputSurfaceConnection : public RefBase {
+public:
+    virtual ~InputSurfaceConnection();
+
+    // From IInputSurfaceConnection
+    void disconnect();
+
+private:
+    friend class InputSurface;
+
+    // For InputSurface
+    InputSurfaceConnection(
+            const sp<GraphicBufferSource> &source, const std::shared_ptr<C2Component> &comp);
+    bool init();
+
+    InputSurfaceConnection() = delete;
+
+    class Impl;
+
+    sp<GraphicBufferSource> mSource;
+    sp<Impl> mImpl;
+
+    DISALLOW_EVIL_CONSTRUCTORS(InputSurfaceConnection);
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace c2
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_MEDIA_C2_V1_0_INPUT_SURFACE_CONNECTION_H
diff --git a/media/codec2/docs/doxyfilter.sh b/media/codec2/docs/doxyfilter.sh
new file mode 100755
index 0000000..d813153
--- /dev/null
+++ b/media/codec2/docs/doxyfilter.sh
@@ -0,0 +1,100 @@
+#!/usr/bin/env python3
+import re, sys
+
+global in_comment, current, indent, hold
+in_comment, current, indent, hold = False, None, '', []
+
+class ChangeCStyleCommentsToDoxy:
+    def dump_hold():
+        global hold
+        for h in hold:
+            print(h, end='')
+        hold[:] = []
+
+    def doxy_hold():
+        global current, hold
+        if current == '//':
+            for h in hold:
+                print(re.sub(r'^( *//(?!/))', r'\1/', h), end='')
+        else:
+            first = True
+            for h in hold:
+                if first:
+                    h = re.sub(r'^( */[*](?![*]))', r'\1*', h)
+                    first = False
+                print(h, end='')
+        hold[:] = []
+
+    def process_comment(t, ind, line):
+        global current, indent, hold
+        if t != current or ind not in (indent, indent + ' '):
+            dump_hold()
+            current, indent = t, ind
+        hold.append(line)
+
+    def process_line(ind, line):
+        global current, indent
+        if ind in (indent, ''):
+            doxy_hold()
+        else:
+            dump_hold()
+        current, indent = None, None
+        print(line, end='')
+
+    def process(self, input, path):
+        for line in input:
+            ind = re.match(r'^( *)', line).group(1)
+            if in_comment:
+                # TODO: this is not quite right, but good enough
+                m = re.match(r'^ *[*]/', line)
+                if m:
+                    process_comment('/*', ind, line)
+                    in_comment = False
+                else:
+                    process_comment('/*', ind, line)
+                continue
+            m = re.match(r'^ *//', line)
+            if m:
+                # one-line comment
+                process_comment('//', ind, line)
+                continue
+            m = re.match(r'^ */[*]', line)
+            if m:
+                # multi-line comment
+                process_comment('/*', ind, line)
+                # TODO: this is not quite right, but good enough
+                in_comment = not re.match(r'^ *[*]/', line)
+                continue
+            process_line(ind, line)
+
+class AutoGroup:
+    def process(self, input, path):
+        if '/codec2/include/' in path:
+            group = 'API Codec2 API'
+        elif False:
+            return
+        elif '/codec2/vndk/' in path:
+            group = 'VNDK Platform provided glue'
+        elif '/codec2/tests/' in path:
+            group = 'Tests Unit tests'
+        else:
+            group = 'Random Misc. sandbox'
+
+        print('#undef __APPLE__')
+
+        for line in input:
+            if re.match(r'^namespace android {', line):
+                print(line, end='')
+                print()
+                print(r'/// \addtogroup {}'.format(group))
+                print(r'/// @{')
+                continue
+            elif re.match(r'^} +// +namespace', line):
+                print(r'/// @}')
+                print()
+            print(line, end='')
+
+P = AutoGroup()
+for path in sys.argv[1:]:
+    with open(path, 'rt') as input:
+        P.process(input, path)
diff --git a/media/codec2/docs/doxygen.config b/media/codec2/docs/doxygen.config
new file mode 100644
index 0000000..5c3bea3
--- /dev/null
+++ b/media/codec2/docs/doxygen.config
@@ -0,0 +1,2446 @@
+# Doxyfile 1.8.11
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME           = Codec2
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER         = 
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          = 
+
+# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
+# the logo to the output directory.
+
+PROJECT_LOGO           = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = out/target/common/docs/codec2/api
+
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS         = NO
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES    = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB  = YES
+
+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES        = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH        = frameworks/av/media/libstagefright/codec2
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF           = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
+# page for each member. If set to NO, the documentation of a member will be part
+# of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES                = 
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST              = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. For
+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
+#
+# Note: For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING      = 
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT       = YES
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT    = YES
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# If one adds a struct or class to a group and this option is enabled, then also
+# any nested class or struct is added to the same group. By default this option
+# is disabled and one has to add nested compounds explicitly via \ingroup.
+# The default value is: NO.
+
+GROUP_NESTED_COMPOUNDS = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT   = YES
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO,
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. If set to YES, local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO, only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO, these classes will be included in the various overviews. This option
+# has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO, these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO, these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS          = YES
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES, upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES, the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES       = YES
+
+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
+# append additional text to a page's title, such as Class Reference. If set to
+# YES the compound reference will be hidden.
+# The default value is: NO.
+
+HIDE_COMPOUND_REFERENCE= NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC  = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
+# list. This list is created by putting \todo commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
+# list. This list is created by putting \test commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS       = INTERNAL
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES, the
+# list will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES        = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER    = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE            = 
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. See also \cite for info how to create references.
+
+CITE_BIB_FILES         = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS               = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO, doxygen will only warn about wrong or incomplete
+# parameter documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC       = NO
+
+# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
+# a warning is encountered.
+# The default value is: NO.
+
+WARN_AS_ERROR          = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
+# Note: If this tag is empty the current directory is searched.
+
+INPUT                  = frameworks/av/media/libstagefright/codec2/
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# read by doxygen.
+#
+# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
+# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
+# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
+# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f, *.for, *.tcl,
+# *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js.
+
+FILE_PATTERNS          = C2*.c \
+                         C2*.cpp \
+                         C2*.h
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = ._*
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS       = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+INPUT_FILTER           = frameworks/av/media/libstagefright/codec2/docs/doxyfilter.sh
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES    = YES
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS = 
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION    = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS        = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS       = YES
+
+# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
+# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
+# cost of reduced performance. This can be particularly helpful with template
+# rich C++ code for which doxygen's built-in parser lacks the necessary type
+# information.
+# Note: The availability of this option depends on whether or not doxygen was
+# generated with the -Duse-libclang=ON option for CMake.
+# The default value is: NO.
+
+CLANG_ASSISTED_PARSING = YES
+
+# If clang assisted parsing is enabled you can provide the compiler with command
+# line options that you would normally use when invoking the compiler. Note that
+# the include paths will already be set by doxygen for the files and directories
+# specified with INPUT and INCLUDE_PATH.
+# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
+
+CLANG_OPTIONS          = -std=c++14
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX     = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET        = 
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefore more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET  = 
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES       = 
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the style sheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to YES can help to show when doxygen was last run and thus if the
+# documentation is up to date.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP         = NO
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS  = YES
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET        = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP      = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE               = 
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION           = 
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated
+# (YES) or that it should be included in the master .chm file (NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI           = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING     = 
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated
+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME   = 
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS  = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS  = 
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION           = 
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW      = YES
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH         = 250
+
+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT         = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS     = 
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE       = 
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE           = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH    = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH        = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL       = 
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE        = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID     = 
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS  = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE             = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. The package can be specified just
+# by its name or with the correct syntax as to be used with the LaTeX
+# \usepackage command. To get the times font for instance you can specify :
+# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
+# To use the option intlimits with the amsmath package you can specify:
+# EXTRA_PACKAGES=[intlimits]{amsmath}
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
+# string, for the replacement values of the other commands the user is referred
+# to HTML_HEADER.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER           = 
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER           = 
+
+# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# LaTeX style sheets that are included after the standard style sheets created
+# by doxygen. Using this option one can overrule certain style aspects. Doxygen
+# will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_STYLESHEET = 
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES      = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES, to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE        = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES     = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE        = plain
+
+# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_TIMESTAMP        = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE    = 
+
+# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
+# with syntax highlighting in the RTF output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_SOURCE_CODE        = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION          = .3
+
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR             = 
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT             = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK       = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT         = docbook
+
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
+# AutoGen Definitions (see http://autogen.sf.net) file that captures the
+# structure of the code including all documentation. Note that this feature is
+# still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO, the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
+# in the source code. If set to NO, only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION        = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF     = YES
+
+# If the SEARCH_INCLUDES tag is set to YES, the include files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH           = /Volumes/A/aosp/prebuilts/clang/darwin-x86/host/3.6/lib/clang/3.6/include \
+                         /Volumes/A/aosp/external/libcxx/include \
+                         /Volumes/A/aosp/bionic/libc/include \
+                         /Volumes/A/aosp/bionic/libc/kernel/uapi \
+                         /Volumes/A/aosp/bionic/libc/kernel/uapi/asm-arm64 \
+                         /Volumes/A/aosp/external/gtest
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED             = __APPLE__= \
+                         __ANDROID__=1 \
+                         ANDROID:=1 \
+			 __unused=
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED      = DEFINE_FLEXIBLE_METHODS \
+                         DEFINE_CAST_OPERATORS
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have a unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
+# the class index. If set to NO, only the inherited external classes will be
+# listed.
+# The default value is: NO.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS        = YES
+
+# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES         = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            = 
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH               = 
+
+# If set to YES the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT               = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS        = 0
+
+# When you want a differently looking font in the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK               = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH          = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command. Disabling a call graph can be
+# accomplished by means of the command \hidecallgraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command. Disabling a caller graph can be
+# accomplished by means of the command \hidecallergraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. For an explanation of the image formats see the section
+# output formats in the documentation of the dot tool (Graphviz (see:
+# http://www.graphviz.org/)).
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
+# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
+# png:gdiplus:gdiplus.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG        = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS           = 
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS           = 
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS           = 
+
+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
+
+PLANTUML_JAR_PATH      = 
+
+# When using plantuml, the specified paths are searched for files specified by
+# the !include statement in a plantuml block.
+
+PLANTUML_INCLUDE_PATH  = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP            = YES
diff --git a/media/codec2/faultinjection/Android.bp b/media/codec2/faultinjection/Android.bp
new file mode 100644
index 0000000..a0ad3ce
--- /dev/null
+++ b/media/codec2/faultinjection/Android.bp
@@ -0,0 +1,29 @@
+cc_library_shared {
+    name: "libcodec2_component_wrapper",
+    vendor_available: true,
+
+    srcs: [
+        "C2ComponentWrapper.cpp",
+        "SimpleMethodState.cpp",
+    ],
+
+    shared_libs: [
+        "libcodec2",
+        "libcodec2_vndk",
+        "libcutils",
+        "liblog",
+        "libstagefright_foundation",
+        "libutils",
+    ],
+
+    sanitize: {
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+        cfi: true,
+    },
+
+    ldflags: ["-Wl,-Bsymbolic"],
+}
+
diff --git a/media/codec2/faultinjection/C2ComponentWrapper.cpp b/media/codec2/faultinjection/C2ComponentWrapper.cpp
new file mode 100644
index 0000000..c45f8bf
--- /dev/null
+++ b/media/codec2/faultinjection/C2ComponentWrapper.cpp
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "C2ComponentWrapper"
+
+#include <chrono>
+#include <functional>
+#include <thread>
+
+#include <C2ComponentWrapper.h>
+#include <C2Config.h>
+#include <C2PlatformSupport.h>
+
+namespace android {
+
+namespace {
+
+using namespace std::chrono_literals;
+
+c2_status_t WrapSimpleMethod(
+        std::function<c2_status_t(void)> op, const SimpleMethodState &state) {
+    c2_status_t result = C2_OK;
+    switch (state.getMode()) {
+        case SimpleMethodState::EXECUTE:
+            result = op();
+            break;
+        case SimpleMethodState::NO_OP:
+            break;
+        case SimpleMethodState::HANG:
+            while (true) {
+                std::this_thread::sleep_for(1s);
+            }
+            break;
+    }
+    (void)state.overrideResult(&result);
+    return result;
+}
+
+}  // namespace
+
+C2ComponentWrapper::Injecter::Injecter(C2ComponentWrapper *thiz) : mThiz(thiz) {}
+
+SimpleMethodState::Injecter C2ComponentWrapper::Injecter::start() {
+    return SimpleMethodState::Injecter(&mThiz->mStartState);
+}
+
+C2ComponentWrapper::Listener::Listener(
+        const std::shared_ptr<C2Component::Listener> &listener) : mListener(listener) {}
+
+void C2ComponentWrapper::Listener::onWorkDone_nb(std::weak_ptr<C2Component> component,
+        std::list<std::unique_ptr<C2Work>> workItems) {
+    mListener->onWorkDone_nb(component, std::move(workItems));
+}
+
+void C2ComponentWrapper::Listener::onTripped_nb(std::weak_ptr<C2Component> component,
+        std::vector<std::shared_ptr<C2SettingResult>> settingResult) {
+    mListener->onTripped_nb(component,settingResult);
+}
+
+void C2ComponentWrapper::Listener::onError_nb(
+        std::weak_ptr<C2Component> component, uint32_t errorCode) {
+    mListener->onError_nb(component, errorCode);
+}
+
+C2ComponentWrapper::C2ComponentWrapper(
+        const std::shared_ptr<C2Component> &comp) : mComp(comp) {}
+
+c2_status_t C2ComponentWrapper::setListener_vb(
+        const std::shared_ptr<C2Component::Listener> &listener, c2_blocking_t mayBlock) {
+    mListener = std::make_shared<Listener>(listener);
+    return mComp->setListener_vb(mListener, mayBlock);
+}
+
+c2_status_t C2ComponentWrapper::queue_nb(std::list<std::unique_ptr<C2Work>>* const items) {
+    return mComp->queue_nb(items);
+}
+
+c2_status_t C2ComponentWrapper::announce_nb(const std::vector<C2WorkOutline> &items) {
+    return mComp->announce_nb(items);
+}
+
+c2_status_t C2ComponentWrapper::flush_sm(
+        C2Component::flush_mode_t mode, std::list<std::unique_ptr<C2Work>>* const flushedWork) {
+    return mComp->flush_sm(mode, flushedWork);
+}
+
+c2_status_t C2ComponentWrapper::drain_nb(C2Component::drain_mode_t mode) {
+    return mComp->drain_nb(mode);
+}
+
+c2_status_t C2ComponentWrapper::start() {
+    return WrapSimpleMethod([this] { return mComp->start(); }, mStartState);
+}
+
+c2_status_t C2ComponentWrapper::stop() {
+    return mComp->stop();
+}
+
+c2_status_t C2ComponentWrapper::reset() {
+    return mComp->reset();
+}
+
+c2_status_t C2ComponentWrapper::release() {
+    return mComp->release();
+}
+
+std::shared_ptr<C2ComponentInterface> C2ComponentWrapper::intf(){
+    return mComp->intf();
+}
+
+C2ComponentWrapper::Injecter C2ComponentWrapper::inject() {
+    return Injecter(this);
+}
+
+}  // namespace android
diff --git a/media/codec2/faultinjection/C2ComponentWrapper.h b/media/codec2/faultinjection/C2ComponentWrapper.h
new file mode 100644
index 0000000..737350d
--- /dev/null
+++ b/media/codec2/faultinjection/C2ComponentWrapper.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef C2_COMPONENT_WRAPPER_H_
+#define C2_COMPONENT_WRAPPER_H_
+
+#include <C2Component.h>
+
+#include "SimpleMethodState.h"
+
+namespace android {
+
+/**
+ * Creates a Wrapper around the class C2Component and its methods. The wrapper is used to
+ * simulate errors in the android media components by fault injection technique.
+ * This is done to check how the framework handles the error situation.
+ */
+class C2ComponentWrapper
+        : public C2Component, public std::enable_shared_from_this<C2ComponentWrapper> {
+public:
+    class Injecter {
+    public:
+        explicit Injecter(C2ComponentWrapper *thiz);
+
+        SimpleMethodState::Injecter start();
+    private:
+        C2ComponentWrapper *const mThiz;
+    };
+
+    /**
+     * A wrapper around the listener class inside C2Component class.
+     */
+    class Listener : public C2Component::Listener {
+    public:
+        explicit Listener(const std::shared_ptr<C2Component::Listener> &listener);
+        virtual ~Listener() = default;
+
+        void onWorkDone_nb(std::weak_ptr<C2Component> component,
+                           std::list<std::unique_ptr<C2Work>> workItems) override;
+        void onTripped_nb(std::weak_ptr<C2Component> component,
+                          std::vector<std::shared_ptr<C2SettingResult>> settingResult) override;
+        void onError_nb(std::weak_ptr<C2Component> component, uint32_t errorCode) override;
+
+    private:
+        std::shared_ptr<C2Component::Listener> mListener;
+    };
+
+    explicit C2ComponentWrapper(const std::shared_ptr<C2Component> &comp);
+    virtual ~C2ComponentWrapper() = default;
+
+    virtual c2_status_t setListener_vb(
+            const std::shared_ptr<C2Component::Listener> &listener,
+            c2_blocking_t mayBlock) override;
+    virtual c2_status_t queue_nb(std::list<std::unique_ptr<C2Work>>* const items) override;
+    virtual c2_status_t announce_nb(const std::vector<C2WorkOutline> &items) override;
+    virtual c2_status_t flush_sm(
+            flush_mode_t mode, std::list<std::unique_ptr<C2Work>>* const flushedWork) override;
+    virtual c2_status_t drain_nb(drain_mode_t mode) override;
+    virtual c2_status_t start() override;
+    virtual c2_status_t stop() override;
+    virtual c2_status_t reset() override;
+    virtual c2_status_t release() override;
+    virtual std::shared_ptr<C2ComponentInterface> intf() override;
+
+    Injecter inject();
+
+private:
+    std::shared_ptr<Listener> mListener;
+    std::shared_ptr<C2Component> mComp;
+
+    SimpleMethodState mStartState;
+};
+
+}  // namespace android
+
+#endif // C2_COMPONENT_WRAPPER_H_
diff --git a/media/codec2/faultinjection/SimpleMethodState.cpp b/media/codec2/faultinjection/SimpleMethodState.cpp
new file mode 100644
index 0000000..179d64e
--- /dev/null
+++ b/media/codec2/faultinjection/SimpleMethodState.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "SimpleMethodState"
+#include <log/log.h>
+
+#include "SimpleMethodState.h"
+
+namespace android {
+
+SimpleMethodState::Injecter::Injecter(SimpleMethodState *thiz) : mThiz(thiz) {}
+
+void SimpleMethodState::Injecter::hang() {
+    mThiz->mMode = HANG;
+}
+
+void SimpleMethodState::Injecter::fail(c2_status_t err, bool execute) {
+    mThiz->mMode = execute ? EXECUTE : NO_OP;
+    mThiz->mOverride = true;
+    mThiz->mResultOverride = err;
+}
+
+SimpleMethodState::SimpleMethodState()
+    : mMode(EXECUTE), mOverride(false), mResultOverride(C2_OK) {}
+
+SimpleMethodState::Mode SimpleMethodState::getMode() const {
+    return mMode;
+}
+
+bool SimpleMethodState::overrideResult(c2_status_t *result) const {
+    if (!mOverride) {
+        return false;
+    }
+    *result = mResultOverride;
+    return true;
+}
+
+}  // namespace android
diff --git a/media/codec2/faultinjection/SimpleMethodState.h b/media/codec2/faultinjection/SimpleMethodState.h
new file mode 100644
index 0000000..dc0459d
--- /dev/null
+++ b/media/codec2/faultinjection/SimpleMethodState.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SIMPLE_METHOD_STATE_H_
+#define SIMPLE_METHOD_STATE_H_
+
+#include <C2.h>
+
+namespace android {
+
+/**
+ * State for a simple method which returns c2_status_t and takes no parameters.
+ */
+class SimpleMethodState {
+public:
+    enum Mode {
+        // Execute the normal operation
+        EXECUTE,
+        // Don't do anything
+        NO_OP,
+        // Hang; never return
+        HANG,
+    };
+
+    /**
+     * Injecter class that modifies the internal states of this class.
+     */
+    class Injecter {
+    public:
+        explicit Injecter(SimpleMethodState *thiz);
+
+        /**
+         * Hang the operation.
+         */
+        void hang();
+
+        /**
+         * Fail the operation with given params.
+         *
+         * \param err       error code to replace the actual return value
+         * \param execute   whether the wrapper should execute the operation
+         */
+        void fail(c2_status_t err, bool execute = false);
+
+    private:
+        SimpleMethodState *const mThiz;
+    };
+
+    SimpleMethodState();
+
+    /**
+     * Get execution mode.
+     */
+    Mode getMode() const;
+
+    /**
+     * Override result from running the operation if configured so.
+     */
+    bool overrideResult(c2_status_t *result) const;
+
+private:
+    Mode mMode;
+    bool mOverride;
+    c2_status_t mResultOverride;
+};
+
+}  // namespace android
+
+#endif // SIMPLE_METHOD_STATE_H_
diff --git a/media/codec2/hidl/1.0/utils/Android.bp b/media/codec2/hidl/1.0/utils/Android.bp
new file mode 100644
index 0000000..63fe36b
--- /dev/null
+++ b/media/codec2/hidl/1.0/utils/Android.bp
@@ -0,0 +1,126 @@
+// DO NOT DEPEND ON THIS DIRECTLY
+// use libcodec2-hidl-client-defaults instead
+cc_library {
+    name: "libcodec2_hidl_client@1.0",
+
+    defaults: ["hidl_defaults"],
+
+    srcs: [
+        "ClientBlockHelper.cpp",
+        "types.cpp",
+    ],
+
+    header_libs: [
+        "libcodec2_internal", // private
+    ],
+
+    shared_libs: [
+        "android.hardware.media.bufferpool@2.0",
+        "android.hardware.media.c2@1.0",
+        "libbase",
+        "libcodec2",
+        "libcodec2_vndk",
+        "libcutils",
+        "libgui",
+        "libhidlbase",
+        "liblog",
+        "libstagefright_bufferpool@2.0",
+        "libui",
+        "libutils",
+    ],
+
+    export_include_dirs: [
+        "include",
+    ],
+
+    export_shared_lib_headers: [
+        "android.hardware.media.c2@1.0",
+        "libcodec2",
+        "libgui",
+        "libstagefright_bufferpool@2.0",
+        "libui",
+    ],
+}
+
+
+// DO NOT DEPEND ON THIS DIRECTLY
+// use libcodec2-hidl-defaults instead
+cc_library {
+    name: "libcodec2_hidl@1.0",
+    vendor_available: true,
+
+    defaults: ["hidl_defaults"],
+
+    srcs: [
+        "Component.cpp",
+        "ComponentInterface.cpp",
+        "ComponentStore.cpp",
+        "Configurable.cpp",
+        "InputBufferManager.cpp",
+        "InputSurface.cpp",
+        "InputSurfaceConnection.cpp",
+        "types.cpp",
+    ],
+
+    header_libs: [
+        "libsystem_headers",
+        "libcodec2_internal", // private
+    ],
+
+    shared_libs: [
+        "android.hardware.graphics.bufferqueue@1.0",
+        "android.hardware.graphics.bufferqueue@2.0",
+        "android.hardware.graphics.common@1.0",
+        "android.hardware.media@1.0",
+        "android.hardware.media.bufferpool@2.0",
+        "android.hardware.media.c2@1.0",
+        "android.hardware.media.omx@1.0",
+        "libbase",
+        "libcodec2",
+        "libcodec2_vndk",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libstagefright_bufferpool@2.0",
+        "libstagefright_bufferqueue_helper",
+        "libui",
+        "libutils",
+    ],
+
+    export_include_dirs: [
+        "include",
+    ],
+
+    export_shared_lib_headers: [
+        "android.hardware.media.c2@1.0",
+        "libcodec2",
+        "libcodec2_vndk",
+        "libhidlbase",
+        "libstagefright_bufferpool@2.0",
+        "libui",
+    ],
+}
+
+// public dependency for Codec 2.0 HAL service implementations
+cc_defaults {
+    name: "libcodec2-hidl-defaults",
+    defaults: ["libcodec2-impl-defaults"],
+
+    shared_libs: [
+        "android.hardware.media.c2@1.0",
+        "libcodec2_hidl@1.0",
+    ],
+}
+
+// public dependency for Codec 2.0 HAL client
+cc_defaults {
+    name: "libcodec2-hidl-client-defaults",
+    defaults: ["libcodec2-impl-defaults"],
+
+    shared_libs: [
+        "android.hardware.media.c2@1.0",
+        "libcodec2_hidl_client@1.0",
+    ],
+}
diff --git a/media/codec2/hidl/1.0/utils/ClientBlockHelper.cpp b/media/codec2/hidl/1.0/utils/ClientBlockHelper.cpp
new file mode 100644
index 0000000..50790bc
--- /dev/null
+++ b/media/codec2/hidl/1.0/utils/ClientBlockHelper.cpp
@@ -0,0 +1,371 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2-block_helper"
+#include <android-base/logging.h>
+
+#include <android/hardware/graphics/bufferqueue/2.0/IGraphicBufferProducer.h>
+#include <codec2/hidl/1.0/ClientBlockHelper.h>
+#include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h>
+
+#include <C2AllocatorGralloc.h>
+#include <C2BlockInternal.h>
+#include <C2Buffer.h>
+#include <C2PlatformSupport.h>
+
+#include <iomanip>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_0 {
+namespace utils {
+
+using HGraphicBufferProducer = ::android::hardware::graphics::bufferqueue::
+        V2_0::IGraphicBufferProducer;
+using B2HGraphicBufferProducer = ::android::hardware::graphics::bufferqueue::
+        V2_0::utils::B2HGraphicBufferProducer;
+
+namespace /* unnamed */ {
+
+// Create a GraphicBuffer object from a graphic block.
+sp<GraphicBuffer> createGraphicBuffer(const C2ConstGraphicBlock& block) {
+    uint32_t width;
+    uint32_t height;
+    uint32_t format;
+    uint64_t usage;
+    uint32_t stride;
+    uint32_t generation;
+    uint64_t bqId;
+    int32_t bqSlot;
+    _UnwrapNativeCodec2GrallocMetadata(
+            block.handle(), &width, &height, &format, &usage,
+            &stride, &generation, &bqId, reinterpret_cast<uint32_t*>(&bqSlot));
+    native_handle_t *grallocHandle =
+            UnwrapNativeCodec2GrallocHandle(block.handle());
+    sp<GraphicBuffer> graphicBuffer =
+            new GraphicBuffer(grallocHandle,
+                              GraphicBuffer::CLONE_HANDLE,
+                              width, height, format,
+                              1, usage, stride);
+    native_handle_delete(grallocHandle);
+    return graphicBuffer;
+}
+
+template <typename BlockProcessor>
+void forEachBlock(C2FrameData& frameData,
+                  BlockProcessor process) {
+    for (const std::shared_ptr<C2Buffer>& buffer : frameData.buffers) {
+        if (buffer) {
+            for (const C2ConstGraphicBlock& block :
+                    buffer->data().graphicBlocks()) {
+                process(block);
+            }
+        }
+    }
+}
+
+template <typename BlockProcessor>
+void forEachBlock(const std::list<std::unique_ptr<C2Work>>& workList,
+                  BlockProcessor process) {
+    for (const std::unique_ptr<C2Work>& work : workList) {
+        if (!work) {
+            continue;
+        }
+        for (const std::unique_ptr<C2Worklet>& worklet : work->worklets) {
+            if (worklet) {
+                forEachBlock(worklet->output, process);
+            }
+        }
+    }
+}
+
+sp<HGraphicBufferProducer> getHgbp(const sp<IGraphicBufferProducer>& igbp) {
+    sp<HGraphicBufferProducer> hgbp =
+            igbp->getHalInterface<HGraphicBufferProducer>();
+    return hgbp ? hgbp :
+            new B2HGraphicBufferProducer(igbp);
+}
+
+status_t attachToBufferQueue(const C2ConstGraphicBlock& block,
+                             const sp<IGraphicBufferProducer>& igbp,
+                             uint32_t generation,
+                             int32_t* bqSlot) {
+    if (!igbp) {
+        LOG(WARNING) << "attachToBufferQueue -- null producer.";
+        return NO_INIT;
+    }
+
+    sp<GraphicBuffer> graphicBuffer = createGraphicBuffer(block);
+    graphicBuffer->setGenerationNumber(generation);
+
+    LOG(VERBOSE) << "attachToBufferQueue -- attaching buffer:"
+            << " block dimension " << block.width() << "x"
+                                   << block.height()
+            << ", graphicBuffer dimension " << graphicBuffer->getWidth() << "x"
+                                           << graphicBuffer->getHeight()
+            << std::hex << std::setfill('0')
+            << ", format 0x" << std::setw(8) << graphicBuffer->getPixelFormat()
+            << ", usage 0x" << std::setw(16) << graphicBuffer->getUsage()
+            << std::dec << std::setfill(' ')
+            << ", stride " << graphicBuffer->getStride()
+            << ", generation " << graphicBuffer->getGenerationNumber();
+
+    status_t result = igbp->attachBuffer(bqSlot, graphicBuffer);
+    if (result != OK) {
+        LOG(WARNING) << "attachToBufferQueue -- attachBuffer failed: "
+                        "status = " << result << ".";
+        return result;
+    }
+    LOG(VERBOSE) << "attachToBufferQueue -- attachBuffer returned slot #"
+                 << *bqSlot << ".";
+    return OK;
+}
+
+bool getBufferQueueAssignment(const C2ConstGraphicBlock& block,
+                              uint32_t* generation,
+                              uint64_t* bqId,
+                              int32_t* bqSlot) {
+    return _C2BlockFactory::GetBufferQueueData(
+            _C2BlockFactory::GetGraphicBlockPoolData(block),
+            generation, bqId, bqSlot);
+}
+} // unnamed namespace
+
+class OutputBufferQueue::Impl {
+    std::mutex mMutex;
+    sp<IGraphicBufferProducer> mIgbp;
+    uint32_t mGeneration;
+    uint64_t mBqId;
+    std::shared_ptr<int> mOwner;
+    // To migrate existing buffers
+    sp<GraphicBuffer> mBuffers[BufferQueueDefs::NUM_BUFFER_SLOTS]; // find a better way
+    std::weak_ptr<_C2BlockPoolData>
+                    mPoolDatas[BufferQueueDefs::NUM_BUFFER_SLOTS];
+
+public:
+    Impl(): mGeneration(0), mBqId(0) {}
+
+    bool configure(const sp<IGraphicBufferProducer>& igbp,
+                   uint32_t generation,
+                   uint64_t bqId) {
+        size_t tryNum = 0;
+        size_t success = 0;
+        sp<GraphicBuffer> buffers[BufferQueueDefs::NUM_BUFFER_SLOTS];
+        std::weak_ptr<_C2BlockPoolData>
+                poolDatas[BufferQueueDefs::NUM_BUFFER_SLOTS];
+        {
+            std::scoped_lock<std::mutex> l(mMutex);
+            if (generation == mGeneration) {
+                return false;
+            }
+            mIgbp = igbp;
+            mGeneration = generation;
+            mBqId = bqId;
+            mOwner = std::make_shared<int>(0);
+            for (int i = 0; i < BufferQueueDefs::NUM_BUFFER_SLOTS; ++i) {
+                if (mBqId == 0 || !mBuffers[i]) {
+                    continue;
+                }
+                std::shared_ptr<_C2BlockPoolData> data = mPoolDatas[i].lock();
+                if (!data ||
+                    !_C2BlockFactory::BeginAttachBlockToBufferQueue(data)) {
+                    continue;
+                }
+                ++tryNum;
+                int bqSlot;
+                mBuffers[i]->setGenerationNumber(generation);
+                status_t result = igbp->attachBuffer(&bqSlot, mBuffers[i]);
+                if (result != OK) {
+                    continue;
+                }
+                bool attach =
+                        _C2BlockFactory::EndAttachBlockToBufferQueue(
+                                data, mOwner, getHgbp(mIgbp),
+                                generation, bqId, bqSlot);
+                if (!attach) {
+                    igbp->cancelBuffer(bqSlot, Fence::NO_FENCE);
+                    continue;
+                }
+                buffers[bqSlot] = mBuffers[i];
+                poolDatas[bqSlot] = data;
+                ++success;
+            }
+            for (int i = 0; i < BufferQueueDefs::NUM_BUFFER_SLOTS; ++i) {
+                mBuffers[i] = buffers[i];
+                mPoolDatas[i] = poolDatas[i];
+            }
+        }
+        ALOGD("remote graphic buffer migration %zu/%zu", success, tryNum);
+        return true;
+    }
+
+    bool registerBuffer(const C2ConstGraphicBlock& block) {
+        std::shared_ptr<_C2BlockPoolData> data =
+                _C2BlockFactory::GetGraphicBlockPoolData(block);
+        if (!data) {
+            return false;
+        }
+        std::scoped_lock<std::mutex> l(mMutex);
+
+        if (!mIgbp) {
+            return false;
+        }
+
+        uint32_t oldGeneration;
+        uint64_t oldId;
+        int32_t oldSlot;
+        // If the block is not bufferqueue-based, do nothing.
+        if (!_C2BlockFactory::GetBufferQueueData(
+                data, &oldGeneration, &oldId, &oldSlot) || (oldId == 0)) {
+            return false;
+        }
+        // If the block's bqId is the same as the desired bqId, just hold.
+        if ((oldId == mBqId) && (oldGeneration == mGeneration)) {
+            LOG(VERBOSE) << "holdBufferQueueBlock -- import without attaching:"
+                         << " bqId " << oldId
+                         << ", bqSlot " << oldSlot
+                         << ", generation " << mGeneration
+                         << ".";
+            _C2BlockFactory::HoldBlockFromBufferQueue(data, mOwner, getHgbp(mIgbp));
+            mPoolDatas[oldSlot] = data;
+            mBuffers[oldSlot] = createGraphicBuffer(block);
+            mBuffers[oldSlot]->setGenerationNumber(mGeneration);
+            return true;
+        }
+        int32_t d = (int32_t) mGeneration - (int32_t) oldGeneration;
+        LOG(WARNING) << "receiving stale buffer: generation "
+                     << mGeneration << " , diff " << d  << " : slot "
+                     << oldSlot;
+        return false;
+    }
+
+    status_t outputBuffer(
+            const C2ConstGraphicBlock& block,
+            const BnGraphicBufferProducer::QueueBufferInput& input,
+            BnGraphicBufferProducer::QueueBufferOutput* output) {
+        uint32_t generation;
+        uint64_t bqId;
+        int32_t bqSlot;
+        bool display = displayBufferQueueBlock(block);
+        if (!getBufferQueueAssignment(block, &generation, &bqId, &bqSlot) ||
+            bqId == 0) {
+            // Block not from bufferqueue -- it must be attached before queuing.
+
+            mMutex.lock();
+            sp<IGraphicBufferProducer> outputIgbp = mIgbp;
+            uint32_t outputGeneration = mGeneration;
+            mMutex.unlock();
+
+            status_t status = attachToBufferQueue(
+                    block, outputIgbp, outputGeneration, &bqSlot);
+            if (status != OK) {
+                LOG(WARNING) << "outputBuffer -- attaching failed.";
+                return INVALID_OPERATION;
+            }
+
+            status = outputIgbp->queueBuffer(static_cast<int>(bqSlot),
+                                         input, output);
+            if (status != OK) {
+                LOG(ERROR) << "outputBuffer -- queueBuffer() failed "
+                           "on non-bufferqueue-based block. "
+                           "Error = " << status << ".";
+                return status;
+            }
+            return OK;
+        }
+
+        mMutex.lock();
+        sp<IGraphicBufferProducer> outputIgbp = mIgbp;
+        uint32_t outputGeneration = mGeneration;
+        uint64_t outputBqId = mBqId;
+        mMutex.unlock();
+
+        if (!outputIgbp) {
+            LOG(VERBOSE) << "outputBuffer -- output surface is null.";
+            return NO_INIT;
+        }
+
+        if (!display) {
+            LOG(WARNING) << "outputBuffer -- cannot display "
+                         "bufferqueue-based block to the bufferqueue.";
+            return UNKNOWN_ERROR;
+        }
+        if (bqId != outputBqId || generation != outputGeneration) {
+            int32_t diff = (int32_t) outputGeneration - (int32_t) generation;
+            LOG(WARNING) << "outputBuffer -- buffers from old generation to "
+                         << outputGeneration << " , diff: " << diff
+                         << " , slot: " << bqSlot;
+            return DEAD_OBJECT;
+        }
+
+        status_t status = outputIgbp->queueBuffer(static_cast<int>(bqSlot),
+                                              input, output);
+        if (status != OK) {
+            LOG(ERROR) << "outputBuffer -- queueBuffer() failed "
+                       "on bufferqueue-based block. "
+                       "Error = " << status << ".";
+            return status;
+        }
+        return OK;
+    }
+
+    Impl *getPtr() {
+        return this;
+    }
+
+    ~Impl() {}
+};
+
+OutputBufferQueue::OutputBufferQueue(): mImpl(new Impl()) {}
+
+OutputBufferQueue::~OutputBufferQueue() {}
+
+bool OutputBufferQueue::configure(const sp<IGraphicBufferProducer>& igbp,
+                                  uint32_t generation,
+                                  uint64_t bqId) {
+    return mImpl && mImpl->configure(igbp, generation, bqId);
+}
+
+status_t OutputBufferQueue::outputBuffer(
+    const C2ConstGraphicBlock& block,
+    const BnGraphicBufferProducer::QueueBufferInput& input,
+    BnGraphicBufferProducer::QueueBufferOutput* output) {
+    if (mImpl) {
+        return mImpl->outputBuffer(block, input, output);
+    }
+    return DEAD_OBJECT;
+}
+
+void OutputBufferQueue::holdBufferQueueBlocks(
+        const std::list<std::unique_ptr<C2Work>>& workList) {
+    if (!mImpl) {
+        return;
+    }
+    forEachBlock(workList,
+                 std::bind(&OutputBufferQueue::Impl::registerBuffer,
+                           mImpl->getPtr(), std::placeholders::_1));
+}
+
+}  // namespace utils
+}  // namespace V1_0
+}  // namespace c2
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
diff --git a/media/codec2/hidl/1.0/utils/Component.cpp b/media/codec2/hidl/1.0/utils/Component.cpp
new file mode 100644
index 0000000..a9f20a4
--- /dev/null
+++ b/media/codec2/hidl/1.0/utils/Component.cpp
@@ -0,0 +1,486 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2-Component"
+#include <android-base/logging.h>
+
+#include <codec2/hidl/1.0/Component.h>
+#include <codec2/hidl/1.0/ComponentStore.h>
+#include <codec2/hidl/1.0/InputBufferManager.h>
+
+#include <hidl/HidlBinderSupport.h>
+#include <utils/Timers.h>
+
+#include <C2BqBufferPriv.h>
+#include <C2Debug.h>
+#include <C2PlatformSupport.h>
+
+#include <chrono>
+#include <thread>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_0 {
+namespace utils {
+
+using namespace ::android;
+
+// ComponentListener wrapper
+struct Component::Listener : public C2Component::Listener {
+
+    Listener(const sp<Component>& component) :
+        mComponent(component),
+        mListener(component->mListener) {
+    }
+
+    virtual void onError_nb(
+            std::weak_ptr<C2Component> /* c2component */,
+            uint32_t errorCode) override {
+        sp<IComponentListener> listener = mListener.promote();
+        if (listener) {
+            Return<void> transStatus = listener->onError(Status::OK, errorCode);
+            if (!transStatus.isOk()) {
+                LOG(ERROR) << "Component::Listener::onError_nb -- "
+                           << "transaction failed.";
+            }
+        }
+    }
+
+    virtual void onTripped_nb(
+            std::weak_ptr<C2Component> /* c2component */,
+            std::vector<std::shared_ptr<C2SettingResult>> c2settingResult
+            ) override {
+        sp<IComponentListener> listener = mListener.promote();
+        if (listener) {
+            hidl_vec<SettingResult> settingResults(c2settingResult.size());
+            size_t ix = 0;
+            for (const std::shared_ptr<C2SettingResult> &c2result :
+                    c2settingResult) {
+                if (c2result) {
+                    if (!objcpy(&settingResults[ix++], *c2result)) {
+                        break;
+                    }
+                }
+            }
+            settingResults.resize(ix);
+            Return<void> transStatus = listener->onTripped(settingResults);
+            if (!transStatus.isOk()) {
+                LOG(ERROR) << "Component::Listener::onTripped_nb -- "
+                           << "transaction failed.";
+            }
+        }
+    }
+
+    virtual void onWorkDone_nb(
+            std::weak_ptr<C2Component> /* c2component */,
+            std::list<std::unique_ptr<C2Work>> c2workItems) override {
+        for (const std::unique_ptr<C2Work>& work : c2workItems) {
+            if (work) {
+                if (work->worklets.empty()
+                        || !work->worklets.back()
+                        || (work->worklets.back()->output.flags &
+                            C2FrameData::FLAG_INCOMPLETE) == 0) {
+                    InputBufferManager::
+                            unregisterFrameData(mListener, work->input);
+                }
+            }
+        }
+
+        sp<IComponentListener> listener = mListener.promote();
+        if (listener) {
+            WorkBundle workBundle;
+
+            sp<Component> strongComponent = mComponent.promote();
+            beginTransferBufferQueueBlocks(c2workItems, true);
+            if (!objcpy(&workBundle, c2workItems, strongComponent ?
+                    &strongComponent->mBufferPoolSender : nullptr)) {
+                LOG(ERROR) << "Component::Listener::onWorkDone_nb -- "
+                           << "received corrupted work items.";
+                endTransferBufferQueueBlocks(c2workItems, false, true);
+                return;
+            }
+            Return<void> transStatus = listener->onWorkDone(workBundle);
+            if (!transStatus.isOk()) {
+                LOG(ERROR) << "Component::Listener::onWorkDone_nb -- "
+                           << "transaction failed.";
+                endTransferBufferQueueBlocks(c2workItems, false, true);
+                return;
+            }
+            endTransferBufferQueueBlocks(c2workItems, true, true);
+        }
+    }
+
+protected:
+    wp<Component> mComponent;
+    wp<IComponentListener> mListener;
+};
+
+// Component::Sink
+struct Component::Sink : public IInputSink {
+    std::shared_ptr<Component> mComponent;
+    sp<IConfigurable> mConfigurable;
+
+    virtual Return<Status> queue(const WorkBundle& workBundle) override {
+        return mComponent->queue(workBundle);
+    }
+
+    virtual Return<sp<IConfigurable>> getConfigurable() override {
+        return mConfigurable;
+    }
+
+    Sink(const std::shared_ptr<Component>& component);
+    virtual ~Sink() override;
+
+    // Process-wide map: Component::Sink -> C2Component.
+    static std::mutex sSink2ComponentMutex;
+    static std::map<IInputSink*, std::weak_ptr<C2Component>> sSink2Component;
+
+    static std::shared_ptr<C2Component> findLocalComponent(
+            const sp<IInputSink>& sink);
+};
+
+std::mutex
+        Component::Sink::sSink2ComponentMutex{};
+std::map<IInputSink*, std::weak_ptr<C2Component>>
+        Component::Sink::sSink2Component{};
+
+Component::Sink::Sink(const std::shared_ptr<Component>& component)
+        : mComponent{component},
+          mConfigurable{[&component]() -> sp<IConfigurable> {
+              Return<sp<IComponentInterface>> ret1 = component->getInterface();
+              if (!ret1.isOk()) {
+                  LOG(ERROR) << "Sink::Sink -- component's transaction failed.";
+                  return nullptr;
+              }
+              Return<sp<IConfigurable>> ret2 =
+                      static_cast<sp<IComponentInterface>>(ret1)->
+                      getConfigurable();
+              if (!ret2.isOk()) {
+                  LOG(ERROR) << "Sink::Sink -- interface's transaction failed.";
+                  return nullptr;
+              }
+              return static_cast<sp<IConfigurable>>(ret2);
+          }()} {
+    std::lock_guard<std::mutex> lock(sSink2ComponentMutex);
+    sSink2Component.emplace(this, component->mComponent);
+}
+
+Component::Sink::~Sink() {
+    std::lock_guard<std::mutex> lock(sSink2ComponentMutex);
+    sSink2Component.erase(this);
+}
+
+std::shared_ptr<C2Component> Component::Sink::findLocalComponent(
+        const sp<IInputSink>& sink) {
+    std::lock_guard<std::mutex> lock(sSink2ComponentMutex);
+    auto i = sSink2Component.find(sink.get());
+    if (i == sSink2Component.end()) {
+        return nullptr;
+    }
+    return i->second.lock();
+}
+
+// Component
+Component::Component(
+        const std::shared_ptr<C2Component>& component,
+        const sp<IComponentListener>& listener,
+        const sp<ComponentStore>& store,
+        const sp<::android::hardware::media::bufferpool::V2_0::
+        IClientManager>& clientPoolManager)
+      : mComponent{component},
+        mInterface{new ComponentInterface(component->intf(), store.get())},
+        mListener{listener},
+        mStore{store},
+        mBufferPoolSender{clientPoolManager} {
+    // Retrieve supported parameters from store
+    // TODO: We could cache this per component/interface type
+    mInit = mInterface->status();
+}
+
+c2_status_t Component::status() const {
+    return mInit;
+}
+
+// Methods from ::android::hardware::media::c2::V1_0::IComponent
+Return<Status> Component::queue(const WorkBundle& workBundle) {
+    std::list<std::unique_ptr<C2Work>> c2works;
+
+    if (!objcpy(&c2works, workBundle)) {
+        return Status::CORRUPTED;
+    }
+
+    // Register input buffers.
+    for (const std::unique_ptr<C2Work>& work : c2works) {
+        if (work) {
+            InputBufferManager::
+                    registerFrameData(mListener, work->input);
+        }
+    }
+
+    return static_cast<Status>(mComponent->queue_nb(&c2works));
+}
+
+Return<void> Component::flush(flush_cb _hidl_cb) {
+    std::list<std::unique_ptr<C2Work>> c2flushedWorks;
+    c2_status_t c2res = mComponent->flush_sm(
+            C2Component::FLUSH_COMPONENT,
+            &c2flushedWorks);
+
+    // Unregister input buffers.
+    for (const std::unique_ptr<C2Work>& work : c2flushedWorks) {
+        if (work) {
+            if (work->worklets.empty()
+                    || !work->worklets.back()
+                    || (work->worklets.back()->output.flags &
+                        C2FrameData::FLAG_INCOMPLETE) == 0) {
+                InputBufferManager::
+                        unregisterFrameData(mListener, work->input);
+            }
+        }
+    }
+
+    WorkBundle flushedWorkBundle;
+    Status res = static_cast<Status>(c2res);
+    beginTransferBufferQueueBlocks(c2flushedWorks, true);
+    if (c2res == C2_OK) {
+        if (!objcpy(&flushedWorkBundle, c2flushedWorks, &mBufferPoolSender)) {
+            res = Status::CORRUPTED;
+        }
+    }
+    _hidl_cb(res, flushedWorkBundle);
+    endTransferBufferQueueBlocks(c2flushedWorks, true, true);
+    return Void();
+}
+
+Return<Status> Component::drain(bool withEos) {
+    return static_cast<Status>(mComponent->drain_nb(withEos ?
+            C2Component::DRAIN_COMPONENT_WITH_EOS :
+            C2Component::DRAIN_COMPONENT_NO_EOS));
+}
+
+Return<Status> Component::setOutputSurface(
+        uint64_t blockPoolId,
+        const sp<HGraphicBufferProducer2>& surface) {
+    std::shared_ptr<C2BlockPool> pool;
+    GetCodec2BlockPool(blockPoolId, mComponent, &pool);
+    if (pool && pool->getAllocatorId() == C2PlatformAllocatorStore::BUFFERQUEUE) {
+        std::shared_ptr<C2BufferQueueBlockPool> bqPool =
+                std::static_pointer_cast<C2BufferQueueBlockPool>(pool);
+        C2BufferQueueBlockPool::OnRenderCallback cb =
+            [this](uint64_t producer, int32_t slot, int64_t nsecs) {
+                // TODO: batch this
+                hidl_vec<IComponentListener::RenderedFrame> rendered;
+                rendered.resize(1);
+                rendered[0] = { producer, slot, nsecs };
+                (void)mListener->onFramesRendered(rendered).isOk();
+        };
+        if (bqPool) {
+            bqPool->setRenderCallback(cb);
+            bqPool->configureProducer(surface);
+        }
+    }
+    return Status::OK;
+}
+
+Return<void> Component::connectToInputSurface(
+        const sp<IInputSurface>& inputSurface,
+        connectToInputSurface_cb _hidl_cb) {
+    Status status;
+    sp<IInputSurfaceConnection> connection;
+    auto transStatus = inputSurface->connect(
+            asInputSink(),
+            [&status, &connection](
+                    Status s, const sp<IInputSurfaceConnection>& c) {
+                status = s;
+                connection = c;
+            }
+        );
+    _hidl_cb(status, connection);
+    return Void();
+}
+
+Return<void> Component::connectToOmxInputSurface(
+        const sp<HGraphicBufferProducer1>& producer,
+        const sp<::android::hardware::media::omx::V1_0::
+        IGraphicBufferSource>& source,
+        connectToOmxInputSurface_cb _hidl_cb) {
+    (void)producer;
+    (void)source;
+    (void)_hidl_cb;
+    return Void();
+}
+
+Return<Status> Component::disconnectFromInputSurface() {
+    // TODO implement
+    return Status::OK;
+}
+
+namespace /* unnamed */ {
+
+struct BlockPoolIntf : public ConfigurableC2Intf {
+    BlockPoolIntf(const std::shared_ptr<C2BlockPool>& pool)
+          : ConfigurableC2Intf{
+                "C2BlockPool:" +
+                    (pool ? std::to_string(pool->getLocalId()) : "null"),
+                0},
+            mPool{pool} {
+    }
+
+    virtual c2_status_t config(
+            const std::vector<C2Param*>& params,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2SettingResult>>* const failures
+            ) override {
+        (void)params;
+        (void)mayBlock;
+        (void)failures;
+        return C2_OK;
+    }
+
+    virtual c2_status_t query(
+            const std::vector<C2Param::Index>& indices,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2Param>>* const params
+            ) const override {
+        (void)indices;
+        (void)mayBlock;
+        (void)params;
+        return C2_OK;
+    }
+
+    virtual c2_status_t querySupportedParams(
+            std::vector<std::shared_ptr<C2ParamDescriptor>>* const params
+            ) const override {
+        (void)params;
+        return C2_OK;
+    }
+
+    virtual c2_status_t querySupportedValues(
+            std::vector<C2FieldSupportedValuesQuery>& fields,
+            c2_blocking_t mayBlock) const override {
+        (void)fields;
+        (void)mayBlock;
+        return C2_OK;
+    }
+
+protected:
+    std::shared_ptr<C2BlockPool> mPool;
+};
+
+} // unnamed namespace
+
+Return<void> Component::createBlockPool(
+        uint32_t allocatorId,
+        createBlockPool_cb _hidl_cb) {
+    std::shared_ptr<C2BlockPool> blockPool;
+    c2_status_t status = CreateCodec2BlockPool(
+            static_cast<C2PlatformAllocatorStore::id_t>(allocatorId),
+            mComponent,
+            &blockPool);
+    if (status != C2_OK) {
+        blockPool = nullptr;
+    }
+    if (blockPool) {
+        mBlockPoolsMutex.lock();
+        mBlockPools.emplace(blockPool->getLocalId(), blockPool);
+        mBlockPoolsMutex.unlock();
+    } else if (status == C2_OK) {
+        status = C2_CORRUPTED;
+    }
+
+    _hidl_cb(static_cast<Status>(status),
+            blockPool ? blockPool->getLocalId() : 0,
+            new CachedConfigurable(
+            std::make_unique<BlockPoolIntf>(blockPool)));
+    return Void();
+}
+
+Return<Status> Component::destroyBlockPool(uint64_t blockPoolId) {
+    std::lock_guard<std::mutex> lock(mBlockPoolsMutex);
+    return mBlockPools.erase(blockPoolId) == 1 ?
+            Status::OK : Status::CORRUPTED;
+}
+
+Return<Status> Component::start() {
+    return static_cast<Status>(mComponent->start());
+}
+
+Return<Status> Component::stop() {
+    InputBufferManager::unregisterFrameData(mListener);
+    return static_cast<Status>(mComponent->stop());
+}
+
+Return<Status> Component::reset() {
+    Status status = static_cast<Status>(mComponent->reset());
+    {
+        std::lock_guard<std::mutex> lock(mBlockPoolsMutex);
+        mBlockPools.clear();
+    }
+    InputBufferManager::unregisterFrameData(mListener);
+    return status;
+}
+
+Return<Status> Component::release() {
+    Status status = static_cast<Status>(mComponent->release());
+    {
+        std::lock_guard<std::mutex> lock(mBlockPoolsMutex);
+        mBlockPools.clear();
+    }
+    InputBufferManager::unregisterFrameData(mListener);
+    return status;
+}
+
+Return<sp<IComponentInterface>> Component::getInterface() {
+    return sp<IComponentInterface>(mInterface);
+}
+
+Return<sp<IInputSink>> Component::asInputSink() {
+    std::lock_guard<std::mutex> lock(mSinkMutex);
+    if (!mSink) {
+        mSink = new Sink(shared_from_this());
+    }
+    return {mSink};
+}
+
+std::shared_ptr<C2Component> Component::findLocalComponent(
+        const sp<IInputSink>& sink) {
+    return Component::Sink::findLocalComponent(sink);
+}
+
+void Component::initListener(const sp<Component>& self) {
+    std::shared_ptr<C2Component::Listener> c2listener =
+            std::make_shared<Listener>(self);
+    c2_status_t res = mComponent->setListener_vb(c2listener, C2_DONT_BLOCK);
+    if (res != C2_OK) {
+        mInit = res;
+    }
+}
+
+Component::~Component() {
+    InputBufferManager::unregisterFrameData(mListener);
+    mStore->reportComponentDeath(this);
+}
+
+}  // namespace utils
+}  // namespace V1_0
+}  // namespace c2
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
diff --git a/media/codec2/hidl/1.0/utils/ComponentInterface.cpp b/media/codec2/hidl/1.0/utils/ComponentInterface.cpp
new file mode 100644
index 0000000..39e5357
--- /dev/null
+++ b/media/codec2/hidl/1.0/utils/ComponentInterface.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2-ComponentInterface"
+#include <android-base/logging.h>
+
+#include <codec2/hidl/1.0/Component.h>
+#include <codec2/hidl/1.0/ComponentInterface.h>
+#include <codec2/hidl/1.0/ComponentStore.h>
+
+#include <hidl/HidlBinderSupport.h>
+#include <utils/Timers.h>
+
+#include <C2BqBufferPriv.h>
+#include <C2Debug.h>
+#include <C2PlatformSupport.h>
+
+#include <chrono>
+#include <thread>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_0 {
+namespace utils {
+
+using namespace ::android;
+
+namespace /* unnamed */ {
+
+// Implementation of ConfigurableC2Intf based on C2ComponentInterface
+struct CompIntf : public ConfigurableC2Intf {
+    CompIntf(const std::shared_ptr<C2ComponentInterface>& intf) :
+        ConfigurableC2Intf{intf->getName(), intf->getId()},
+        mIntf{intf} {
+    }
+
+    virtual c2_status_t config(
+            const std::vector<C2Param*>& params,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2SettingResult>>* const failures
+            ) override {
+        return mIntf->config_vb(params, mayBlock, failures);
+    }
+
+    virtual c2_status_t query(
+            const std::vector<C2Param::Index>& indices,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2Param>>* const params
+            ) const override {
+        return mIntf->query_vb({}, indices, mayBlock, params);
+    }
+
+    virtual c2_status_t querySupportedParams(
+            std::vector<std::shared_ptr<C2ParamDescriptor>>* const params
+            ) const override {
+        return mIntf->querySupportedParams_nb(params);
+    }
+
+    virtual c2_status_t querySupportedValues(
+            std::vector<C2FieldSupportedValuesQuery>& fields,
+            c2_blocking_t mayBlock) const override {
+        return mIntf->querySupportedValues_vb(fields, mayBlock);
+    }
+
+protected:
+    std::shared_ptr<C2ComponentInterface> mIntf;
+};
+
+} // unnamed namespace
+
+// ComponentInterface
+ComponentInterface::ComponentInterface(
+        const std::shared_ptr<C2ComponentInterface>& intf,
+        ComponentStore* store)
+      : mInterface{intf},
+        mConfigurable{new CachedConfigurable(std::make_unique<CompIntf>(intf))} {
+    mInit = mConfigurable->init(store);
+}
+
+c2_status_t ComponentInterface::status() const {
+    return mInit;
+}
+
+Return<sp<IConfigurable>> ComponentInterface::getConfigurable() {
+    return mConfigurable;
+}
+
+}  // namespace utils
+}  // namespace V1_0
+}  // namespace c2
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
diff --git a/media/codec2/hidl/1.0/utils/ComponentStore.cpp b/media/codec2/hidl/1.0/utils/ComponentStore.cpp
new file mode 100644
index 0000000..1e0a190
--- /dev/null
+++ b/media/codec2/hidl/1.0/utils/ComponentStore.cpp
@@ -0,0 +1,437 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2-ComponentStore"
+#include <android-base/logging.h>
+
+#include <codec2/hidl/1.0/ComponentStore.h>
+#include <codec2/hidl/1.0/InputSurface.h>
+#include <codec2/hidl/1.0/types.h>
+
+#include <android-base/file.h>
+#include <media/stagefright/bqhelper/GraphicBufferSource.h>
+#include <utils/Errors.h>
+
+#include <C2PlatformSupport.h>
+#include <util/C2InterfaceHelper.h>
+
+#include <chrono>
+#include <ctime>
+#include <iomanip>
+#include <ostream>
+#include <sstream>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_0 {
+namespace utils {
+
+using namespace ::android;
+using ::android::GraphicBufferSource;
+using namespace ::android::hardware::media::bufferpool::V2_0::implementation;
+
+namespace /* unnamed */ {
+
+struct StoreIntf : public ConfigurableC2Intf {
+    StoreIntf(const std::shared_ptr<C2ComponentStore>& store)
+          : ConfigurableC2Intf{store ? store->getName() : "", 0},
+            mStore{store} {
+    }
+
+    virtual c2_status_t config(
+            const std::vector<C2Param*> &params,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2SettingResult>> *const failures
+            ) override {
+        // Assume all params are blocking
+        // TODO: Filter for supported params
+        if (mayBlock == C2_DONT_BLOCK && params.size() != 0) {
+            return C2_BLOCKING;
+        }
+        return mStore->config_sm(params, failures);
+    }
+
+    virtual c2_status_t query(
+            const std::vector<C2Param::Index> &indices,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2Param>> *const params) const override {
+        // Assume all params are blocking
+        // TODO: Filter for supported params
+        if (mayBlock == C2_DONT_BLOCK && indices.size() != 0) {
+            return C2_BLOCKING;
+        }
+        return mStore->query_sm({}, indices, params);
+    }
+
+    virtual c2_status_t querySupportedParams(
+            std::vector<std::shared_ptr<C2ParamDescriptor>> *const params
+            ) const override {
+        return mStore->querySupportedParams_nb(params);
+    }
+
+    virtual c2_status_t querySupportedValues(
+            std::vector<C2FieldSupportedValuesQuery> &fields,
+            c2_blocking_t mayBlock) const override {
+        // Assume all params are blocking
+        // TODO: Filter for supported params
+        if (mayBlock == C2_DONT_BLOCK && fields.size() != 0) {
+            return C2_BLOCKING;
+        }
+        return mStore->querySupportedValues_sm(fields);
+    }
+
+protected:
+    std::shared_ptr<C2ComponentStore> mStore;
+};
+
+} // unnamed namespace
+
+ComponentStore::ComponentStore(const std::shared_ptr<C2ComponentStore>& store)
+      : mConfigurable{new CachedConfigurable(std::make_unique<StoreIntf>(store))},
+        mStore{store} {
+
+    std::shared_ptr<C2ComponentStore> platformStore = android::GetCodec2PlatformComponentStore();
+    SetPreferredCodec2ComponentStore(store);
+
+    // Retrieve struct descriptors
+    mParamReflector = mStore->getParamReflector();
+
+    // Retrieve supported parameters from store
+    mInit = mConfigurable->init(this);
+}
+
+c2_status_t ComponentStore::status() const {
+    return mInit;
+}
+
+c2_status_t ComponentStore::validateSupportedParams(
+        const std::vector<std::shared_ptr<C2ParamDescriptor>>& params) {
+    c2_status_t res = C2_OK;
+
+    for (const std::shared_ptr<C2ParamDescriptor> &desc : params) {
+        if (!desc) {
+            // All descriptors should be valid
+            res = res ? res : C2_BAD_VALUE;
+            continue;
+        }
+        C2Param::CoreIndex coreIndex = desc->index().coreIndex();
+        std::lock_guard<std::mutex> lock(mStructDescriptorsMutex);
+        auto it = mStructDescriptors.find(coreIndex);
+        if (it == mStructDescriptors.end()) {
+            std::shared_ptr<C2StructDescriptor> structDesc =
+                    mParamReflector->describe(coreIndex);
+            if (!structDesc) {
+                // All supported params must be described
+                res = C2_BAD_INDEX;
+            }
+            mStructDescriptors.insert({ coreIndex, structDesc });
+        }
+    }
+    return res;
+}
+
+// Methods from ::android::hardware::media::c2::V1_0::IComponentStore
+Return<void> ComponentStore::createComponent(
+        const hidl_string& name,
+        const sp<IComponentListener>& listener,
+        const sp<IClientManager>& pool,
+        createComponent_cb _hidl_cb) {
+
+    sp<Component> component;
+    std::shared_ptr<C2Component> c2component;
+    Status status = static_cast<Status>(
+            mStore->createComponent(name, &c2component));
+
+    if (status == Status::OK) {
+        onInterfaceLoaded(c2component->intf());
+        component = new Component(c2component, listener, this, pool);
+        if (!component) {
+            status = Status::CORRUPTED;
+        } else {
+            reportComponentBirth(component.get());
+            if (component->status() != C2_OK) {
+                status = static_cast<Status>(component->status());
+            } else {
+                component->initListener(component);
+                if (component->status() != C2_OK) {
+                    status = static_cast<Status>(component->status());
+                }
+            }
+        }
+    }
+    _hidl_cb(status, component);
+    return Void();
+}
+
+Return<void> ComponentStore::createInterface(
+        const hidl_string& name,
+        createInterface_cb _hidl_cb) {
+    std::shared_ptr<C2ComponentInterface> c2interface;
+    c2_status_t res = mStore->createInterface(name, &c2interface);
+    sp<IComponentInterface> interface;
+    if (res == C2_OK) {
+        onInterfaceLoaded(c2interface);
+        interface = new ComponentInterface(c2interface, this);
+    }
+    _hidl_cb(static_cast<Status>(res), interface);
+    return Void();
+}
+
+Return<void> ComponentStore::listComponents(listComponents_cb _hidl_cb) {
+    std::vector<std::shared_ptr<const C2Component::Traits>> c2traits =
+            mStore->listComponents();
+    hidl_vec<IComponentStore::ComponentTraits> traits(c2traits.size());
+    size_t ix = 0;
+    for (const std::shared_ptr<const C2Component::Traits> &c2trait : c2traits) {
+        if (c2trait) {
+            if (objcpy(&traits[ix], *c2trait)) {
+                ++ix;
+            } else {
+                break;
+            }
+        }
+    }
+    traits.resize(ix);
+    _hidl_cb(Status::OK, traits);
+    return Void();
+}
+
+Return<void> ComponentStore::createInputSurface(createInputSurface_cb _hidl_cb) {
+    sp<GraphicBufferSource> source = new GraphicBufferSource();
+    if (source->initCheck() != OK) {
+        _hidl_cb(Status::CORRUPTED, nullptr);
+        return Void();
+    }
+    sp<InputSurface> inputSurface = new InputSurface(
+            this,
+            std::make_shared<C2ReflectorHelper>(),
+            source->getHGraphicBufferProducer(),
+            source);
+    _hidl_cb(inputSurface ? Status::OK : Status::NO_MEMORY,
+             inputSurface);
+    return Void();
+}
+
+void ComponentStore::onInterfaceLoaded(const std::shared_ptr<C2ComponentInterface> &intf) {
+    // invalidate unsupported struct descriptors if a new interface is loaded as it may have
+    // exposed new descriptors
+    std::lock_guard<std::mutex> lock(mStructDescriptorsMutex);
+    if (!mLoadedInterfaces.count(intf->getName())) {
+        mUnsupportedStructDescriptors.clear();
+        mLoadedInterfaces.emplace(intf->getName());
+    }
+}
+
+Return<void> ComponentStore::getStructDescriptors(
+        const hidl_vec<uint32_t>& indices,
+        getStructDescriptors_cb _hidl_cb) {
+    hidl_vec<StructDescriptor> descriptors(indices.size());
+    size_t dstIx = 0;
+    Status res = Status::OK;
+    for (size_t srcIx = 0; srcIx < indices.size(); ++srcIx) {
+        std::lock_guard<std::mutex> lock(mStructDescriptorsMutex);
+        const C2Param::CoreIndex coreIndex = C2Param::CoreIndex(indices[srcIx]).coreIndex();
+        const auto item = mStructDescriptors.find(coreIndex);
+        if (item == mStructDescriptors.end()) {
+            // not in the cache, and not known to be unsupported, query local reflector
+            if (!mUnsupportedStructDescriptors.count(coreIndex)) {
+                std::shared_ptr<C2StructDescriptor> structDesc =
+                    mParamReflector->describe(coreIndex);
+                if (!structDesc) {
+                    mUnsupportedStructDescriptors.emplace(coreIndex);
+                } else {
+                    mStructDescriptors.insert({ coreIndex, structDesc });
+                    if (objcpy(&descriptors[dstIx], *structDesc)) {
+                        ++dstIx;
+                        continue;
+                    }
+                    res = Status::CORRUPTED;
+                    break;
+                }
+            }
+            res = Status::NOT_FOUND;
+        } else if (item->second) {
+            if (objcpy(&descriptors[dstIx], *item->second)) {
+                ++dstIx;
+                continue;
+            }
+            res = Status::CORRUPTED;
+            break;
+        } else {
+            res = Status::NO_MEMORY;
+            break;
+        }
+    }
+    descriptors.resize(dstIx);
+    _hidl_cb(res, descriptors);
+    return Void();
+}
+
+Return<sp<IClientManager>> ComponentStore::getPoolClientManager() {
+    return ClientManager::getInstance();
+}
+
+Return<Status> ComponentStore::copyBuffer(const Buffer& src, const Buffer& dst) {
+    // TODO implement
+    (void)src;
+    (void)dst;
+    return Status::OMITTED;
+}
+
+Return<sp<IConfigurable>> ComponentStore::getConfigurable() {
+    return mConfigurable;
+}
+
+// Called from createComponent() after a successful creation of `component`.
+void ComponentStore::reportComponentBirth(Component* component) {
+    ComponentStatus componentStatus;
+    componentStatus.c2Component = component->mComponent;
+    componentStatus.birthTime = std::chrono::system_clock::now();
+
+    std::lock_guard<std::mutex> lock(mComponentRosterMutex);
+    mComponentRoster.emplace(component, componentStatus);
+}
+
+// Called from within the destructor of `component`. No virtual function calls
+// are made on `component` here.
+void ComponentStore::reportComponentDeath(Component* component) {
+    std::lock_guard<std::mutex> lock(mComponentRosterMutex);
+    mComponentRoster.erase(component);
+}
+
+// Dumps component traits.
+std::ostream& ComponentStore::dump(
+        std::ostream& out,
+        const std::shared_ptr<const C2Component::Traits>& comp) {
+
+    constexpr const char indent[] = "    ";
+
+    out << indent << "name: " << comp->name << std::endl;
+    out << indent << "domain: " << comp->domain << std::endl;
+    out << indent << "kind: " << comp->kind << std::endl;
+    out << indent << "rank: " << comp->rank << std::endl;
+    out << indent << "mediaType: " << comp->mediaType << std::endl;
+    out << indent << "aliases:";
+    for (const auto& alias : comp->aliases) {
+        out << ' ' << alias;
+    }
+    out << std::endl;
+
+    return out;
+}
+
+// Dumps component status.
+std::ostream& ComponentStore::dump(
+        std::ostream& out,
+        ComponentStatus& compStatus) {
+
+    constexpr const char indent[] = "    ";
+
+    // Print birth time.
+    std::chrono::milliseconds ms =
+            std::chrono::duration_cast<std::chrono::milliseconds>(
+                compStatus.birthTime.time_since_epoch());
+    std::time_t birthTime = std::chrono::system_clock::to_time_t(
+            compStatus.birthTime);
+    std::tm tm = *std::localtime(&birthTime);
+    out << indent << "Creation time: "
+        << std::put_time(&tm, "%Y-%m-%d %H:%M:%S")
+        << '.' << std::setfill('0') << std::setw(3) << ms.count() % 1000
+        << std::endl;
+
+    // Print name and id.
+    std::shared_ptr<C2ComponentInterface> intf = compStatus.c2Component->intf();
+    if (!intf) {
+        out << indent << "Unknown component -- null interface" << std::endl;
+        return out;
+    }
+    out << indent << "Name: " << intf->getName() << std::endl;
+    out << indent << "Id: " << intf->getId() << std::endl;
+
+    return out;
+}
+
+// Dumps information when lshal is called.
+Return<void> ComponentStore::debug(
+        const hidl_handle& handle,
+        const hidl_vec<hidl_string>& /* args */) {
+    LOG(INFO) << "debug -- dumping...";
+    const native_handle_t *h = handle.getNativeHandle();
+    if (!h || h->numFds != 1) {
+       LOG(ERROR) << "debug -- dumping failed -- "
+               "invalid file descriptor to dump to";
+       return Void();
+    }
+    std::ostringstream out;
+
+    { // Populate "out".
+
+        constexpr const char indent[] = "  ";
+
+        // Show name.
+        out << "Beginning of dump -- C2ComponentStore: "
+                << mStore->getName() << std::endl << std::endl;
+
+        // Retrieve the list of supported components.
+        std::vector<std::shared_ptr<const C2Component::Traits>> traitsList =
+                mStore->listComponents();
+
+        // Dump the traits of supported components.
+        out << indent << "Supported components:" << std::endl << std::endl;
+        if (traitsList.size() == 0) {
+            out << indent << indent << "NONE" << std::endl << std::endl;
+        } else {
+            for (const auto& traits : traitsList) {
+                dump(out, traits) << std::endl;
+            }
+        }
+
+        // Dump active components.
+        {
+            out << indent << "Active components:" << std::endl << std::endl;
+            std::lock_guard<std::mutex> lock(mComponentRosterMutex);
+            if (mComponentRoster.size() == 0) {
+                out << indent << indent << "NONE" << std::endl << std::endl;
+            } else {
+                for (auto& pair : mComponentRoster) {
+                    dump(out, pair.second) << std::endl;
+                }
+            }
+        }
+
+        out << "End of dump -- C2ComponentStore: "
+                << mStore->getName() << std::endl;
+    }
+
+    if (!android::base::WriteStringToFd(out.str(), h->data[0])) {
+        PLOG(WARNING) << "debug -- dumping failed -- write()";
+    } else {
+        LOG(INFO) << "debug -- dumping succeeded";
+    }
+    return Void();
+}
+
+
+}  // namespace utils
+}  // namespace V1_0
+}  // namespace c2
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
diff --git a/media/codec2/hidl/1.0/utils/Configurable.cpp b/media/codec2/hidl/1.0/utils/Configurable.cpp
new file mode 100644
index 0000000..ec9c170
--- /dev/null
+++ b/media/codec2/hidl/1.0/utils/Configurable.cpp
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2-Configurable"
+#include <android-base/logging.h>
+
+#include <codec2/hidl/1.0/Configurable.h>
+#include <codec2/hidl/1.0/ComponentStore.h>
+#include <codec2/hidl/1.0/types.h>
+
+#include <C2ParamInternal.h>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_0 {
+namespace utils {
+
+using namespace ::android;
+
+CachedConfigurable::CachedConfigurable(
+        std::unique_ptr<ConfigurableC2Intf>&& intf)
+      : mIntf{std::move(intf)} {
+}
+
+c2_status_t CachedConfigurable::init(ComponentStore* store) {
+    // Retrieve supported parameters from store
+    c2_status_t init = mIntf->querySupportedParams(&mSupportedParams);
+    c2_status_t validate = store->validateSupportedParams(mSupportedParams);
+    return init == C2_OK ? C2_OK : validate;
+}
+
+// Methods from ::android::hardware::media::c2::V1_0::IConfigurable follow.
+Return<uint32_t> CachedConfigurable::getId() {
+    return mIntf->getId();
+}
+
+Return<void> CachedConfigurable::getName(getName_cb _hidl_cb) {
+    _hidl_cb(mIntf->getName());
+    return Void();
+}
+
+Return<void> CachedConfigurable::query(
+        const hidl_vec<uint32_t>& indices,
+        bool mayBlock,
+        query_cb _hidl_cb) {
+    typedef C2Param::Index Index;
+    std::vector<Index> c2heapParamIndices(
+            (Index*)indices.data(),
+            (Index*)indices.data() + indices.size());
+    std::vector<std::unique_ptr<C2Param>> c2heapParams;
+    c2_status_t c2res = mIntf->query(
+            c2heapParamIndices,
+            mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK,
+            &c2heapParams);
+
+    hidl_vec<uint8_t> params;
+    if (!createParamsBlob(&params, c2heapParams)) {
+        LOG(WARNING) << "query -- invalid output params.";
+    }
+    _hidl_cb(static_cast<Status>(c2res), params);
+    return Void();
+}
+
+Return<void> CachedConfigurable::config(
+        const hidl_vec<uint8_t>& inParams,
+        bool mayBlock,
+        config_cb _hidl_cb) {
+    // inParams is not writable, so create a copy as config modifies the parameters
+    hidl_vec<uint8_t> inParamsCopy = inParams;
+    std::vector<C2Param*> c2params;
+    if (!parseParamsBlob(&c2params, inParamsCopy)) {
+        LOG(WARNING) << "config -- invalid input params.";
+        _hidl_cb(Status::CORRUPTED,
+                hidl_vec<SettingResult>(),
+                hidl_vec<uint8_t>());
+        return Void();
+    }
+    // TODO: check if blob was invalid
+    std::vector<std::unique_ptr<C2SettingResult>> c2failures;
+    c2_status_t c2res = mIntf->config(
+            c2params,
+            mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK,
+            &c2failures);
+    hidl_vec<SettingResult> failures(c2failures.size());
+    {
+        size_t ix = 0;
+        for (const std::unique_ptr<C2SettingResult>& c2result : c2failures) {
+            if (c2result) {
+                if (objcpy(&failures[ix], *c2result)) {
+                    ++ix;
+                } else {
+                    LOG(DEBUG) << "config -- invalid setting results.";
+                    break;
+                }
+            }
+        }
+        failures.resize(ix);
+    }
+    hidl_vec<uint8_t> outParams;
+    if (!createParamsBlob(&outParams, c2params)) {
+        LOG(DEBUG) << "config -- invalid output params.";
+    }
+    _hidl_cb((Status)c2res, failures, outParams);
+    return Void();
+}
+
+Return<void> CachedConfigurable::querySupportedParams(
+        uint32_t start,
+        uint32_t count,
+        querySupportedParams_cb _hidl_cb) {
+    C2LinearRange request = C2LinearCapacity(mSupportedParams.size()).range(
+            start, count);
+    hidl_vec<ParamDescriptor> params(request.size());
+    Status res = Status::OK;
+    size_t dstIx = 0;
+    for (size_t srcIx = request.offset(); srcIx < request.endOffset(); ++srcIx) {
+        if (mSupportedParams[srcIx]) {
+            if (objcpy(&params[dstIx], *mSupportedParams[srcIx])) {
+                ++dstIx;
+            } else {
+                res = Status::CORRUPTED;
+                LOG(WARNING) << "querySupportedParams -- invalid output params.";
+                break;
+            }
+        } else {
+            res = Status::BAD_INDEX;
+        }
+    }
+    params.resize(dstIx);
+    _hidl_cb(res, params);
+    return Void();
+}
+
+Return<void> CachedConfigurable::querySupportedValues(
+        const hidl_vec<FieldSupportedValuesQuery>& inFields,
+        bool mayBlock,
+        querySupportedValues_cb _hidl_cb) {
+    std::vector<C2FieldSupportedValuesQuery> c2fields;
+    {
+        // C2FieldSupportedValuesQuery objects are restricted in that some
+        // members are const.
+        // C2ParamField - required for its constructor - has no constructors
+        // from fields. Use C2ParamInspector.
+        for (const FieldSupportedValuesQuery &query : inFields) {
+            c2fields.emplace_back(_C2ParamInspector::CreateParamField(
+                    query.field.index,
+                    query.field.fieldId.offset,
+                    query.field.fieldId.size),
+                    query.type == FieldSupportedValuesQuery::Type::POSSIBLE ?
+                    C2FieldSupportedValuesQuery::POSSIBLE :
+                    C2FieldSupportedValuesQuery::CURRENT);
+        }
+    }
+    c2_status_t c2res = mIntf->querySupportedValues(
+            c2fields,
+            mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK);
+    hidl_vec<FieldSupportedValuesQueryResult> outFields(inFields.size());
+    size_t dstIx = 0;
+    for (const C2FieldSupportedValuesQuery &result : c2fields) {
+        if (objcpy(&outFields[dstIx], result)) {
+            ++dstIx;
+        } else {
+            outFields.resize(dstIx);
+            c2res = C2_CORRUPTED;
+            LOG(WARNING) << "querySupportedValues -- invalid output params.";
+            break;
+        }
+    }
+    _hidl_cb((Status)c2res, outFields);
+    return Void();
+}
+
+}  // namespace utils
+}  // namespace V1_0
+}  // namespace c2
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
diff --git a/media/codec2/hidl/1.0/utils/InputBufferManager.cpp b/media/codec2/hidl/1.0/utils/InputBufferManager.cpp
new file mode 100644
index 0000000..a023a05
--- /dev/null
+++ b/media/codec2/hidl/1.0/utils/InputBufferManager.cpp
@@ -0,0 +1,461 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2-InputBufferManager"
+#include <android-base/logging.h>
+
+#include <codec2/hidl/1.0/InputBufferManager.h>
+#include <codec2/hidl/1.0/types.h>
+
+#include <android/hardware/media/c2/1.0/IComponentListener.h>
+#include <android-base/logging.h>
+
+#include <C2Buffer.h>
+#include <C2Work.h>
+
+#include <chrono>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_0 {
+namespace utils {
+
+using namespace ::android;
+
+void InputBufferManager::registerFrameData(
+        const sp<IComponentListener>& listener,
+        const C2FrameData& input) {
+    getInstance()._registerFrameData(listener, input);
+}
+
+void InputBufferManager::unregisterFrameData(
+        const wp<IComponentListener>& listener,
+        const C2FrameData& input) {
+    getInstance()._unregisterFrameData(listener, input);
+}
+
+void InputBufferManager::unregisterFrameData(
+        const wp<IComponentListener>& listener) {
+    getInstance()._unregisterFrameData(listener);
+}
+
+void InputBufferManager::setNotificationInterval(
+        nsecs_t notificationIntervalNs) {
+    getInstance()._setNotificationInterval(notificationIntervalNs);
+}
+
+void InputBufferManager::_registerFrameData(
+        const sp<IComponentListener>& listener,
+        const C2FrameData& input) {
+    uint64_t frameIndex = input.ordinal.frameIndex.peeku();
+    LOG(VERBOSE) << "InputBufferManager::_registerFrameData -- called with "
+                 << "listener @ 0x" << std::hex << listener.get()
+                 << ", frameIndex = " << std::dec << frameIndex
+                 << ".";
+    std::lock_guard<std::mutex> lock(mMutex);
+
+    std::set<TrackedBuffer> &bufferIds =
+            mTrackedBuffersMap[listener][frameIndex];
+
+    for (size_t i = 0; i < input.buffers.size(); ++i) {
+        if (!input.buffers[i]) {
+            LOG(VERBOSE) << "InputBufferManager::_registerFrameData -- "
+                         << "Input buffer at index " << i << " is null.";
+            continue;
+        }
+        const TrackedBuffer &bufferId =
+                *bufferIds.emplace(listener, frameIndex, i, input.buffers[i]).
+                first;
+
+        c2_status_t status = input.buffers[i]->registerOnDestroyNotify(
+                onBufferDestroyed,
+                const_cast<void*>(reinterpret_cast<const void*>(&bufferId)));
+        if (status != C2_OK) {
+            LOG(DEBUG) << "InputBufferManager::_registerFrameData -- "
+                       << "registerOnDestroyNotify() failed "
+                       << "(listener @ 0x" << std::hex << listener.get()
+                       << ", frameIndex = " << std::dec << frameIndex
+                       << ", bufferIndex = " << i
+                       << ") => status = " << status
+                       << ".";
+        }
+    }
+
+    mDeathNotifications.emplace(
+            listener,
+            DeathNotifications(
+                mNotificationIntervalNs.load(std::memory_order_relaxed)));
+}
+
+// Remove a pair (listener, frameIndex) from mTrackedBuffersMap and
+// mDeathNotifications. This implies all bufferIndices are removed.
+//
+// This is called from onWorkDone() and flush().
+void InputBufferManager::_unregisterFrameData(
+        const wp<IComponentListener>& listener,
+        const C2FrameData& input) {
+    uint64_t frameIndex = input.ordinal.frameIndex.peeku();
+    LOG(VERBOSE) << "InputBufferManager::_unregisterFrameData -- called with "
+                 << "listener @ 0x" << std::hex << listener.unsafe_get()
+                 << ", frameIndex = " << std::dec << frameIndex
+                 << ".";
+    std::lock_guard<std::mutex> lock(mMutex);
+
+    auto findListener = mTrackedBuffersMap.find(listener);
+    if (findListener != mTrackedBuffersMap.end()) {
+        std::map<uint64_t, std::set<TrackedBuffer>> &frameIndex2BufferIds
+                = findListener->second;
+        auto findFrameIndex = frameIndex2BufferIds.find(frameIndex);
+        if (findFrameIndex != frameIndex2BufferIds.end()) {
+            std::set<TrackedBuffer> &bufferIds = findFrameIndex->second;
+            for (const TrackedBuffer& bufferId : bufferIds) {
+                std::shared_ptr<C2Buffer> buffer = bufferId.buffer.lock();
+                if (buffer) {
+                    c2_status_t status = buffer->unregisterOnDestroyNotify(
+                            onBufferDestroyed,
+                            const_cast<void*>(
+                            reinterpret_cast<const void*>(&bufferId)));
+                    if (status != C2_OK) {
+                        LOG(DEBUG) << "InputBufferManager::_unregisterFrameData "
+                                   << "-- unregisterOnDestroyNotify() failed "
+                                   << "(listener @ 0x"
+                                        << std::hex
+                                        << bufferId.listener.unsafe_get()
+                                   << ", frameIndex = "
+                                        << std::dec << bufferId.frameIndex
+                                   << ", bufferIndex = " << bufferId.bufferIndex
+                                   << ") => status = " << status
+                                   << ".";
+                    }
+                }
+            }
+
+            frameIndex2BufferIds.erase(findFrameIndex);
+            if (frameIndex2BufferIds.empty()) {
+                mTrackedBuffersMap.erase(findListener);
+            }
+        }
+    }
+
+    auto findListenerD = mDeathNotifications.find(listener);
+    if (findListenerD != mDeathNotifications.end()) {
+        DeathNotifications &deathNotifications = findListenerD->second;
+        auto findFrameIndex = deathNotifications.indices.find(frameIndex);
+        if (findFrameIndex != deathNotifications.indices.end()) {
+            std::vector<size_t> &bufferIndices = findFrameIndex->second;
+            deathNotifications.count -= bufferIndices.size();
+            deathNotifications.indices.erase(findFrameIndex);
+        }
+    }
+}
+
+// Remove listener from mTrackedBuffersMap and mDeathNotifications. This implies
+// all frameIndices and bufferIndices are removed.
+//
+// This is called when the component cleans up all input buffers, i.e., when
+// reset(), release(), stop() or ~Component() is called.
+void InputBufferManager::_unregisterFrameData(
+        const wp<IComponentListener>& listener) {
+    LOG(VERBOSE) << "InputBufferManager::_unregisterFrameData -- called with "
+                 << "listener @ 0x" << std::hex << listener.unsafe_get()
+                 << std::dec << ".";
+    std::lock_guard<std::mutex> lock(mMutex);
+
+    auto findListener = mTrackedBuffersMap.find(listener);
+    if (findListener != mTrackedBuffersMap.end()) {
+        std::map<uint64_t, std::set<TrackedBuffer>> &frameIndex2BufferIds =
+                findListener->second;
+        for (auto findFrameIndex = frameIndex2BufferIds.begin();
+                findFrameIndex != frameIndex2BufferIds.end();
+                ++findFrameIndex) {
+            std::set<TrackedBuffer> &bufferIds = findFrameIndex->second;
+            for (const TrackedBuffer& bufferId : bufferIds) {
+                std::shared_ptr<C2Buffer> buffer = bufferId.buffer.lock();
+                if (buffer) {
+                    c2_status_t status = buffer->unregisterOnDestroyNotify(
+                            onBufferDestroyed,
+                            const_cast<void*>(
+                            reinterpret_cast<const void*>(&bufferId)));
+                    if (status != C2_OK) {
+                        LOG(DEBUG) << "InputBufferManager::_unregisterFrameData "
+                                   << "-- unregisterOnDestroyNotify() failed "
+                                   << "(listener @ 0x"
+                                        << std::hex
+                                        << bufferId.listener.unsafe_get()
+                                   << ", frameIndex = "
+                                        << std::dec << bufferId.frameIndex
+                                   << ", bufferIndex = " << bufferId.bufferIndex
+                                   << ") => status = " << status
+                                   << ".";
+                    }
+                }
+            }
+        }
+        mTrackedBuffersMap.erase(findListener);
+    }
+
+    mDeathNotifications.erase(listener);
+}
+
+// Set mNotificationIntervalNs.
+void InputBufferManager::_setNotificationInterval(
+        nsecs_t notificationIntervalNs) {
+    mNotificationIntervalNs.store(
+            notificationIntervalNs,
+            std::memory_order_relaxed);
+}
+
+// Move a buffer from mTrackedBuffersMap to mDeathNotifications.
+// This is called when a registered C2Buffer object is destroyed.
+void InputBufferManager::onBufferDestroyed(const C2Buffer* buf, void* arg) {
+    getInstance()._onBufferDestroyed(buf, arg);
+}
+
+void InputBufferManager::_onBufferDestroyed(const C2Buffer* buf, void* arg) {
+    if (!buf || !arg) {
+        LOG(WARNING) << "InputBufferManager::_onBufferDestroyed -- called with "
+                     << "null argument (s): "
+                     << "buf @ 0x" << std::hex << buf
+                     << ", arg @ 0x" << std::hex << arg
+                     << std::dec << ".";
+        return;
+    }
+    TrackedBuffer id(*reinterpret_cast<TrackedBuffer*>(arg));
+    LOG(VERBOSE) << "InputBufferManager::_onBufferDestroyed -- called with "
+                 << "buf @ 0x" << std::hex << buf
+                 << ", arg @ 0x" << std::hex << arg
+                 << std::dec << " -- "
+                 << "listener @ 0x" << std::hex << id.listener.unsafe_get()
+                 << ", frameIndex = " << std::dec << id.frameIndex
+                 << ", bufferIndex = " << id.bufferIndex
+                 << ".";
+
+    std::lock_guard<std::mutex> lock(mMutex);
+
+    auto findListener = mTrackedBuffersMap.find(id.listener);
+    if (findListener == mTrackedBuffersMap.end()) {
+        LOG(DEBUG) << "InputBufferManager::_onBufferDestroyed -- "
+                   << "received invalid listener: "
+                   << "listener @ 0x" << std::hex << id.listener.unsafe_get()
+                   << " (frameIndex = " << std::dec << id.frameIndex
+                   << ", bufferIndex = " << id.bufferIndex
+                   << ").";
+        return;
+    }
+
+    std::map<uint64_t, std::set<TrackedBuffer>> &frameIndex2BufferIds
+            = findListener->second;
+    auto findFrameIndex = frameIndex2BufferIds.find(id.frameIndex);
+    if (findFrameIndex == frameIndex2BufferIds.end()) {
+        LOG(DEBUG) << "InputBufferManager::_onBufferDestroyed -- "
+                   << "received invalid frame index: "
+                   << "frameIndex = " << id.frameIndex
+                   << " (listener @ 0x" << std::hex << id.listener.unsafe_get()
+                   << ", bufferIndex = " << std::dec << id.bufferIndex
+                   << ").";
+        return;
+    }
+
+    std::set<TrackedBuffer> &bufferIds = findFrameIndex->second;
+    auto findBufferId = bufferIds.find(id);
+    if (findBufferId == bufferIds.end()) {
+        LOG(DEBUG) << "InputBufferManager::_onBufferDestroyed -- "
+                   << "received invalid buffer index: "
+                   << "bufferIndex = " << id.bufferIndex
+                   << " (frameIndex = " << id.frameIndex
+                   << ", listener @ 0x" << std::hex << id.listener.unsafe_get()
+                   << std::dec << ").";
+        return;
+    }
+
+    bufferIds.erase(findBufferId);
+    if (bufferIds.empty()) {
+        frameIndex2BufferIds.erase(findFrameIndex);
+        if (frameIndex2BufferIds.empty()) {
+            mTrackedBuffersMap.erase(findListener);
+        }
+    }
+
+    DeathNotifications &deathNotifications = mDeathNotifications[id.listener];
+    deathNotifications.indices[id.frameIndex].emplace_back(id.bufferIndex);
+    ++deathNotifications.count;
+    mOnBufferDestroyed.notify_one();
+}
+
+// Notify the clients about buffer destructions.
+// Return false if all destructions have been notified.
+// Return true and set timeToRetry to the time point to wait for before
+// retrying if some destructions have not been notified.
+bool InputBufferManager::processNotifications(nsecs_t* timeToRetryNs) {
+
+    struct Notification {
+        sp<IComponentListener> listener;
+        hidl_vec<IComponentListener::InputBuffer> inputBuffers;
+        Notification(const sp<IComponentListener>& l, size_t s)
+              : listener(l), inputBuffers(s) {}
+    };
+    std::list<Notification> notifications;
+    nsecs_t notificationIntervalNs =
+            mNotificationIntervalNs.load(std::memory_order_relaxed);
+
+    bool retry = false;
+    {
+        std::lock_guard<std::mutex> lock(mMutex);
+        *timeToRetryNs = notificationIntervalNs;
+        nsecs_t timeNowNs = systemTime();
+        for (auto it = mDeathNotifications.begin();
+                it != mDeathNotifications.end(); ) {
+            sp<IComponentListener> listener = it->first.promote();
+            if (!listener) {
+                ++it;
+                continue;
+            }
+            DeathNotifications &deathNotifications = it->second;
+
+            nsecs_t timeSinceLastNotifiedNs =
+                    timeNowNs - deathNotifications.lastSentNs;
+            // If not enough time has passed since the last callback, leave the
+            // notifications for this listener untouched for now and retry
+            // later.
+            if (timeSinceLastNotifiedNs < notificationIntervalNs) {
+                retry = true;
+                *timeToRetryNs = std::min(*timeToRetryNs,
+                        notificationIntervalNs - timeSinceLastNotifiedNs);
+                LOG(VERBOSE) << "InputBufferManager::processNotifications -- "
+                             << "Notifications for listener @ "
+                                 << std::hex << listener.get()
+                             << " will be postponed.";
+                ++it;
+                continue;
+            }
+
+            // If enough time has passed since the last notification to this
+            // listener but there are currently no pending notifications, the
+            // listener can be removed from mDeathNotifications---there is no
+            // need to keep track of the last notification time anymore.
+            if (deathNotifications.count == 0) {
+                it = mDeathNotifications.erase(it);
+                continue;
+            }
+
+            // Create the argument for the callback.
+            notifications.emplace_back(listener, deathNotifications.count);
+            hidl_vec<IComponentListener::InputBuffer> &inputBuffers =
+                    notifications.back().inputBuffers;
+            size_t i = 0;
+            for (std::pair<const uint64_t, std::vector<size_t>>& p :
+                    deathNotifications.indices) {
+                uint64_t frameIndex = p.first;
+                const std::vector<size_t> &bufferIndices = p.second;
+                for (const size_t& bufferIndex : bufferIndices) {
+                    IComponentListener::InputBuffer &inputBuffer
+                            = inputBuffers[i++];
+                    inputBuffer.arrayIndex = bufferIndex;
+                    inputBuffer.frameIndex = frameIndex;
+                }
+            }
+
+            // Clear deathNotifications for this listener and set retry to true
+            // so processNotifications will be called again. This will
+            // guarantee that a listener with no pending notifications will
+            // eventually be removed from mDeathNotifications after
+            // mNotificationIntervalNs nanoseconds has passed.
+            retry = true;
+            deathNotifications.indices.clear();
+            deathNotifications.count = 0;
+            deathNotifications.lastSentNs = timeNowNs;
+            ++it;
+        }
+    }
+
+    // Call onInputBuffersReleased() outside the lock to avoid deadlock.
+    for (const Notification& notification : notifications) {
+        if (!notification.listener->onInputBuffersReleased(
+                notification.inputBuffers).isOk()) {
+            // This may trigger if the client has died.
+            LOG(DEBUG) << "InputBufferManager::processNotifications -- "
+                       << "failed to send death notifications to "
+                       << "listener @ 0x" << std::hex
+                                          << notification.listener.get()
+                       << std::dec << ".";
+        } else {
+#if LOG_NDEBUG == 0
+            std::stringstream inputBufferLog;
+            for (const IComponentListener::InputBuffer& inputBuffer :
+                    notification.inputBuffers) {
+                inputBufferLog << " (" << inputBuffer.frameIndex
+                               << ", " << inputBuffer.arrayIndex
+                               << ")";
+            }
+            LOG(VERBOSE) << "InputBufferManager::processNotifications -- "
+                         << "death notifications sent to "
+                         << "listener @ 0x" << std::hex
+                                            << notification.listener.get()
+                                            << std::dec
+                         << " with these (frameIndex, bufferIndex) pairs:"
+                         << inputBufferLog.str();
+#endif
+        }
+    }
+#if LOG_NDEBUG == 0
+    if (retry) {
+        LOG(VERBOSE) << "InputBufferManager::processNotifications -- "
+                     << "will retry again in " << *timeToRetryNs << "ns.";
+    } else {
+        LOG(VERBOSE) << "InputBufferManager::processNotifications -- "
+                     << "no pending death notifications.";
+    }
+#endif
+    return retry;
+}
+
+void InputBufferManager::main() {
+    LOG(VERBOSE) << "InputBufferManager main -- started.";
+    nsecs_t timeToRetryNs;
+    while (true) {
+        std::unique_lock<std::mutex> lock(mMutex);
+        while (mDeathNotifications.empty()) {
+            mOnBufferDestroyed.wait(lock);
+        }
+        lock.unlock();
+        while (processNotifications(&timeToRetryNs)) {
+            std::this_thread::sleep_for(
+                    std::chrono::nanoseconds(timeToRetryNs));
+        }
+    }
+}
+
+InputBufferManager::InputBufferManager()
+      : mMainThread{&InputBufferManager::main, this} {
+}
+
+InputBufferManager& InputBufferManager::getInstance() {
+    static InputBufferManager instance{};
+    return instance;
+}
+
+}  // namespace utils
+}  // namespace V1_0
+}  // namespace c2
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+
+
diff --git a/media/codec2/hidl/1.0/utils/InputSurface.cpp b/media/codec2/hidl/1.0/utils/InputSurface.cpp
new file mode 100644
index 0000000..2b4ca85
--- /dev/null
+++ b/media/codec2/hidl/1.0/utils/InputSurface.cpp
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2-InputSurface"
+#include <android-base/logging.h>
+
+#include <codec2/hidl/1.0/InputSurface.h>
+#include <codec2/hidl/1.0/InputSurfaceConnection.h>
+
+#include <C2Component.h>
+#include <C2Config.h>
+
+#include <memory>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_0 {
+namespace utils {
+
+using namespace ::android;
+
+// Derived class of C2InterfaceHelper
+class InputSurface::Interface : public C2InterfaceHelper {
+public:
+    explicit Interface(
+            const std::shared_ptr<C2ReflectorHelper> &helper)
+        : C2InterfaceHelper(helper) {
+
+        setDerivedInstance(this);
+
+        addParameter(
+                DefineParam(mEos, C2_PARAMKEY_INPUT_SURFACE_EOS)
+                .withDefault(new C2InputSurfaceEosTuning(false))
+                .withFields({C2F(mEos, value).oneOf({true, false})})
+                .withSetter(EosSetter)
+                .build());
+    }
+
+    static C2R EosSetter(bool mayBlock, C2P<C2InputSurfaceEosTuning> &me) {
+        (void)mayBlock;
+        return me.F(me.v.value).validatePossible(me.v.value);
+    }
+
+    bool eos() const { return mEos->value; }
+
+private:
+    std::shared_ptr<C2InputSurfaceEosTuning> mEos;
+};
+
+// Derived class of ConfigurableC2Intf
+class InputSurface::ConfigurableIntf : public ConfigurableC2Intf {
+public:
+    ConfigurableIntf(
+            const std::shared_ptr<InputSurface::Interface> &intf,
+            const sp<GraphicBufferSource> &source)
+        : ConfigurableC2Intf("input-surface", 0),
+          mIntf(intf),
+          mSource(source) {
+    }
+
+    virtual ~ConfigurableIntf() override = default;
+
+    virtual c2_status_t query(
+            const std::vector<C2Param::Index> &indices,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2Param>>* const params
+            ) const override {
+        return mIntf->query({}, indices, mayBlock, params);
+    }
+
+    virtual c2_status_t config(
+            const std::vector<C2Param*> &params,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2SettingResult>>* const failures
+            ) override {
+        c2_status_t err = mIntf->config(params, mayBlock, failures);
+        if (mIntf->eos()) {
+            sp<GraphicBufferSource> source = mSource.promote();
+            if (source == nullptr || source->signalEndOfInputStream() != OK) {
+                // TODO: put something in |failures|
+                err = C2_BAD_VALUE;
+            }
+            // TODO: reset eos?
+        }
+        return err;
+    }
+
+    virtual c2_status_t querySupportedParams(
+            std::vector<std::shared_ptr<C2ParamDescriptor>>* const params
+            ) const override {
+        return mIntf->querySupportedParams(params);
+    }
+
+    virtual c2_status_t querySupportedValues(
+            std::vector<C2FieldSupportedValuesQuery>& fields,
+            c2_blocking_t mayBlock) const override {
+        return mIntf->querySupportedValues(fields, mayBlock);
+    }
+
+private:
+    const std::shared_ptr<InputSurface::Interface> mIntf;
+    wp<GraphicBufferSource> mSource;
+};
+
+Return<sp<InputSurface::HGraphicBufferProducer>> InputSurface::getGraphicBufferProducer() {
+    return mProducer;
+}
+
+Return<sp<IConfigurable>> InputSurface::getConfigurable() {
+    return mConfigurable;
+}
+
+Return<void> InputSurface::connect(
+        const sp<IInputSink>& sink,
+        connect_cb _hidl_cb) {
+    Status status;
+    sp<InputSurfaceConnection> connection;
+    if (!sink) {
+        _hidl_cb(Status::BAD_VALUE, nullptr);
+        return Void();
+    }
+    std::shared_ptr<C2Component> comp = Component::findLocalComponent(sink);
+    if (comp) {
+        connection = new InputSurfaceConnection(mSource, comp, mStore);
+    } else {
+        connection = new InputSurfaceConnection(mSource, sink, mStore);
+    }
+    if (!connection->init()) {
+        connection = nullptr;
+        status = Status::BAD_VALUE;
+    } else {
+        status = Status::OK;
+    }
+    _hidl_cb(status, connection);
+    return Void();
+}
+
+// Constructor is exclusive to ComponentStore.
+InputSurface::InputSurface(
+        const sp<ComponentStore>& store,
+        const std::shared_ptr<C2ReflectorHelper>& reflector,
+        const sp<HGraphicBufferProducer>& producer,
+        const sp<GraphicBufferSource>& source)
+      : mStore{store},
+        mProducer{producer},
+        mSource{source},
+        mIntf{std::make_shared<Interface>(reflector)},
+        mConfigurable{new CachedConfigurable(
+                std::make_unique<ConfigurableIntf>(
+                    mIntf, source))} {
+
+    mConfigurable->init(store.get());
+}
+
+}  // namespace utils
+}  // namespace V1_0
+}  // namespace c2
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
diff --git a/media/codec2/hidl/1.0/utils/InputSurfaceConnection.cpp b/media/codec2/hidl/1.0/utils/InputSurfaceConnection.cpp
new file mode 100644
index 0000000..c9932ef
--- /dev/null
+++ b/media/codec2/hidl/1.0/utils/InputSurfaceConnection.cpp
@@ -0,0 +1,529 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2-InputSurfaceConnection"
+#include <android-base/logging.h>
+
+#include <codec2/hidl/1.0/InputSurfaceConnection.h>
+#include <codec2/hidl/1.0/InputSurfaceConnection.h>
+
+#include <memory>
+#include <list>
+#include <mutex>
+#include <atomic>
+
+#include <hidl/HidlSupport.h>
+#include <media/stagefright/bqhelper/ComponentWrapper.h>
+#include <system/graphics.h>
+#include <ui/GraphicBuffer.h>
+#include <utils/Errors.h>
+
+#include <C2.h>
+#include <C2AllocatorGralloc.h>
+#include <C2BlockInternal.h>
+#include <C2Buffer.h>
+#include <C2Component.h>
+#include <C2Config.h>
+#include <C2Debug.h>
+#include <C2PlatformSupport.h>
+#include <C2Work.h>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_0 {
+namespace utils {
+
+constexpr int32_t kBufferCount = 16;
+
+using namespace ::android;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+
+namespace /* unnamed */ {
+
+class Buffer2D : public C2Buffer {
+public:
+    explicit Buffer2D(C2ConstGraphicBlock block) : C2Buffer({ block }) {
+    }
+};
+
+} // unnamed namespace
+
+// Derived class of ComponentWrapper for use with
+// GraphicBufferSource::configure().
+//
+struct InputSurfaceConnection::Impl : public ComponentWrapper {
+
+    Impl(const sp<GraphicBufferSource>& source,
+         const std::shared_ptr<C2Component>& localComp)
+          : mSource{source}, mLocalComp{localComp}, mSink{}, mFrameIndex{0} {
+        std::shared_ptr<C2ComponentInterface> intf = localComp->intf();
+        mSinkName = intf ? intf->getName() : "";
+    }
+
+    Impl(const sp<GraphicBufferSource>& source,
+         const sp<IInputSink>& sink)
+          : mSource{source}, mLocalComp{}, mSink{sink}, mFrameIndex{0} {
+        Return<sp<IConfigurable>> transResult = sink->getConfigurable();
+        if (!transResult.isOk()) {
+            LOG(ERROR) << "Remote sink is dead.";
+            return;
+        }
+        mSinkConfigurable =
+                static_cast<sp<IConfigurable>>(transResult);
+        if (!mSinkConfigurable) {
+            LOG(ERROR) << "Remote sink is not configurable.";
+            mSinkName = "";
+            return;
+        }
+
+        hidl_string name;
+        Return<void> transStatus = mSinkConfigurable->getName(
+                [&name](const hidl_string& n) {
+                    name = n;
+                });
+        if (!transStatus.isOk()) {
+            LOG(ERROR) << "Remote sink's configurable is dead.";
+            mSinkName = "";
+            return;
+        }
+        mSinkName = name.c_str();
+    }
+
+    virtual ~Impl() {
+        mSource->stop();
+        mSource->release();
+    }
+
+    bool init() {
+        if (mSource == nullptr) {
+            return false;
+        }
+        status_t err = mSource->initCheck();
+        if (err != OK) {
+            LOG(WARNING) << "Impl::init -- GraphicBufferSource init failed: "
+                         << "status = " << err << ".";
+            return false;
+        }
+
+        // TODO: read settings properly from the interface
+        C2StreamPictureSizeInfo::input inputSize;
+        C2StreamUsageTuning::input usage;
+        c2_status_t c2Status = queryFromSink({ &inputSize, &usage },
+                                         {},
+                                         C2_MAY_BLOCK,
+                                         nullptr);
+        if (c2Status != C2_OK) {
+            LOG(WARNING) << "Impl::init -- cannot query information from "
+                            "the component interface: "
+                         << "status = " << asString(c2Status) << ".";
+            return false;
+        }
+
+        // TODO: proper color aspect & dataspace
+        android_dataspace dataSpace = HAL_DATASPACE_BT709;
+
+        // TODO: use the usage read from intf
+        // uint32_t grallocUsage =
+        //         C2AndroidMemoryUsage(C2MemoryUsage(usage.value)).
+        //         asGrallocUsage();
+
+        uint32_t grallocUsage =
+                mSinkName.compare(0, 11, "c2.android.") == 0 ?
+                GRALLOC_USAGE_SW_READ_OFTEN :
+                GRALLOC_USAGE_HW_VIDEO_ENCODER;
+
+        err = mSource->configure(
+                this, dataSpace, kBufferCount,
+                inputSize.width, inputSize.height,
+                grallocUsage);
+        if (err != OK) {
+            LOG(WARNING) << "Impl::init -- GBS configure failed: "
+                         << "status = " << err << ".";
+            return false;
+        }
+        for (int32_t i = 0; i < kBufferCount; ++i) {
+            if (!mSource->onInputBufferAdded(i).isOk()) {
+                LOG(WARNING) << "Impl::init: failed to populate GBS slots.";
+                return false;
+            }
+        }
+        if (!mSource->start().isOk()) {
+            LOG(WARNING) << "Impl::init -- GBS failed to start.";
+            return false;
+        }
+        mAllocatorMutex.lock();
+        c2_status_t c2err = GetCodec2PlatformAllocatorStore()->fetchAllocator(
+                C2AllocatorStore::PLATFORM_START + 1,  // GRALLOC
+                &mAllocator);
+        mAllocatorMutex.unlock();
+        if (c2err != OK) {
+            LOG(WARNING) << "Impl::init -- failed to fetch gralloc allocator: "
+                         << "status = " << asString(c2err) << ".";
+            return false;
+        }
+        return true;
+    }
+
+    // From ComponentWrapper
+    virtual status_t submitBuffer(
+            int32_t bufferId,
+            const sp<GraphicBuffer>& buffer,
+            int64_t timestamp,
+            int fenceFd) override {
+        LOG(VERBOSE) << "Impl::submitBuffer -- bufferId = " << bufferId << ".";
+        // TODO: Use fd to construct fence
+        (void)fenceFd;
+
+        std::shared_ptr<C2GraphicAllocation> alloc;
+        C2Handle* handle = WrapNativeCodec2GrallocHandle(
+                buffer->handle,
+                buffer->width, buffer->height,
+                buffer->format, buffer->usage, buffer->stride);
+        mAllocatorMutex.lock();
+        c2_status_t err = mAllocator->priorGraphicAllocation(handle, &alloc);
+        mAllocatorMutex.unlock();
+        if (err != OK) {
+            return UNKNOWN_ERROR;
+        }
+        std::shared_ptr<C2GraphicBlock> block =
+                _C2BlockFactory::CreateGraphicBlock(alloc);
+
+        std::unique_ptr<C2Work> work(new C2Work);
+        work->input.flags = (C2FrameData::flags_t)0;
+        work->input.ordinal.timestamp = timestamp;
+        work->input.ordinal.frameIndex = mFrameIndex.fetch_add(
+                1, std::memory_order_relaxed);
+        work->input.buffers.clear();
+        std::shared_ptr<C2Buffer> c2Buffer(
+                // TODO: fence
+                new Buffer2D(block->share(
+                        C2Rect(block->width(), block->height()), ::C2Fence())),
+                [bufferId, source = mSource](C2Buffer* ptr) {
+                    delete ptr;
+                    if (source != nullptr) {
+                        // TODO: fence
+                        (void)source->onInputBufferEmptied(bufferId, -1);
+                    }
+                });
+        work->input.buffers.push_back(c2Buffer);
+        work->worklets.clear();
+        work->worklets.emplace_back(new C2Worklet);
+        std::list<std::unique_ptr<C2Work>> items;
+        items.push_back(std::move(work));
+
+        err = queueToSink(&items);
+        return (err == C2_OK) ? OK : UNKNOWN_ERROR;
+    }
+
+    virtual status_t submitEos(int32_t bufferId) override {
+        LOG(VERBOSE) << "Impl::submitEos -- bufferId = " << bufferId << ".";
+        (void)bufferId;
+
+        std::unique_ptr<C2Work> work(new C2Work);
+        work->input.flags = (C2FrameData::flags_t)0;
+        work->input.ordinal.frameIndex = mFrameIndex.fetch_add(
+                1, std::memory_order_relaxed);
+        work->input.buffers.clear();
+        work->worklets.clear();
+        work->worklets.emplace_back(new C2Worklet);
+        std::list<std::unique_ptr<C2Work>> items;
+        items.push_back(std::move(work));
+
+        c2_status_t err = queueToSink(&items);
+        return (err == C2_OK) ? OK : UNKNOWN_ERROR;
+    }
+
+    virtual void dispatchDataSpaceChanged(
+            int32_t dataSpace, int32_t aspects, int32_t pixelFormat) override {
+        // TODO
+        (void)dataSpace;
+        (void)aspects;
+        (void)pixelFormat;
+    }
+
+    // Configurable interface for InputSurfaceConnection::Impl.
+    //
+    // This class is declared as an inner class so that it will have access to
+    // all Impl's members.
+    struct ConfigurableIntf : public ConfigurableC2Intf {
+        sp<Impl> mConnection;
+        ConfigurableIntf(const sp<Impl>& connection)
+              : ConfigurableC2Intf{"input-surface-connection", 0},
+                mConnection{connection} {}
+        virtual c2_status_t config(
+                const std::vector<C2Param*> &params,
+                c2_blocking_t mayBlock,
+                std::vector<std::unique_ptr<C2SettingResult>> *const failures
+                ) override;
+        virtual c2_status_t query(
+                const std::vector<C2Param::Index> &indices,
+                c2_blocking_t mayBlock,
+                std::vector<std::unique_ptr<C2Param>> *const params) const override;
+        virtual c2_status_t querySupportedParams(
+                std::vector<std::shared_ptr<C2ParamDescriptor>> *const params
+                ) const override;
+        virtual c2_status_t querySupportedValues(
+                std::vector<C2FieldSupportedValuesQuery> &fields,
+                c2_blocking_t mayBlock) const override;
+    };
+
+private:
+    c2_status_t queryFromSink(
+            const std::vector<C2Param*> &stackParams,
+            const std::vector<C2Param::Index> &heapParamIndices,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2Param>>* const heapParams) {
+        if (mLocalComp) {
+            std::shared_ptr<C2ComponentInterface> intf = mLocalComp->intf();
+            if (intf) {
+                return intf->query_vb(stackParams,
+                                      heapParamIndices,
+                                      mayBlock,
+                                      heapParams);
+            } else {
+                LOG(ERROR) << "queryFromSink -- "
+                           << "component does not have an interface.";
+                return C2_BAD_STATE;
+            }
+        }
+
+        CHECK(mSink) << "-- queryFromSink "
+                     << "-- connection has no sink.";
+        CHECK(mSinkConfigurable) << "-- queryFromSink "
+                                 << "-- sink has no configurable.";
+
+        hidl_vec<ParamIndex> indices(
+                stackParams.size() + heapParamIndices.size());
+        size_t numIndices = 0;
+        for (C2Param* const& stackParam : stackParams) {
+            if (!stackParam) {
+                LOG(DEBUG) << "queryFromSink -- null stack param encountered.";
+                continue;
+            }
+            indices[numIndices++] = static_cast<ParamIndex>(stackParam->index());
+        }
+        size_t numStackIndices = numIndices;
+        for (const C2Param::Index& index : heapParamIndices) {
+            indices[numIndices++] =
+                    static_cast<ParamIndex>(static_cast<uint32_t>(index));
+        }
+        indices.resize(numIndices);
+        if (heapParams) {
+            heapParams->reserve(heapParams->size() + numIndices);
+        }
+        c2_status_t status;
+        Return<void> transStatus = mSinkConfigurable->query(
+                indices,
+                mayBlock == C2_MAY_BLOCK,
+                [&status, &numStackIndices, &stackParams, heapParams](
+                        Status s, const Params& p) {
+                    status = static_cast<c2_status_t>(s);
+                    if (status != C2_OK && status != C2_BAD_INDEX) {
+                        LOG(DEBUG) << "queryFromSink -- call failed: "
+                                   << "status = " << asString(status) << ".";
+                        return;
+                    }
+                    std::vector<C2Param*> paramPointers;
+                    if (!parseParamsBlob(&paramPointers, p)) {
+                        LOG(DEBUG) << "queryFromSink -- error while "
+                                   << "parsing params.";
+                        status = C2_CORRUPTED;
+                        return;
+                    }
+                    size_t i = 0;
+                    for (auto it = paramPointers.begin();
+                            it != paramPointers.end(); ) {
+                        C2Param* paramPointer = *it;
+                        if (numStackIndices > 0) {
+                            --numStackIndices;
+                            if (!paramPointer) {
+                                LOG(DEBUG) << "queryFromSink -- "
+                                              "null stack param.";
+                                ++it;
+                                continue;
+                            }
+                            for (; i < stackParams.size() &&
+                                    !stackParams[i]; ) {
+                                ++i;
+                            }
+                            CHECK(i < stackParams.size());
+                            if (stackParams[i]->index() !=
+                                    paramPointer->index()) {
+                                LOG(DEBUG) << "queryFromSink -- "
+                                              "param skipped (index = "
+                                           << stackParams[i]->index() << ").";
+                                stackParams[i++]->invalidate();
+                                continue;
+                            }
+                            if (!stackParams[i++]->updateFrom(*paramPointer)) {
+                                LOG(DEBUG) << "queryFromSink -- "
+                                              "param update failed (index = "
+                                           << paramPointer->index() << ").";
+                            }
+                        } else {
+                            if (!paramPointer) {
+                                LOG(DEBUG) << "queryFromSink -- "
+                                              "null heap param.";
+                                ++it;
+                                continue;
+                            }
+                            if (!heapParams) {
+                                LOG(WARNING) << "queryFromSink -- "
+                                                "too many stack params.";
+                                break;
+                            }
+                            heapParams->emplace_back(C2Param::Copy(*paramPointer));
+                        }
+                        ++it;
+                    }
+                });
+        if (!transStatus.isOk()) {
+            LOG(ERROR) << "queryFromSink -- transaction failed.";
+            return C2_CORRUPTED;
+        }
+        return status;
+    }
+
+    c2_status_t queueToSink(std::list<std::unique_ptr<C2Work>>* const items) {
+        if (mLocalComp) {
+            return mLocalComp->queue_nb(items);
+        }
+
+        CHECK(mSink) << "-- queueToSink "
+                     << "-- connection has no sink.";
+
+        WorkBundle workBundle;
+        if (!objcpy(&workBundle, *items, nullptr)) {
+            LOG(ERROR) << "queueToSink -- bad input.";
+            return C2_CORRUPTED;
+        }
+        Return<Status> transStatus = mSink->queue(workBundle);
+        if (!transStatus.isOk()) {
+            LOG(ERROR) << "queueToSink -- transaction failed.";
+            return C2_CORRUPTED;
+        }
+        c2_status_t status =
+                static_cast<c2_status_t>(static_cast<Status>(transStatus));
+        if (status != C2_OK) {
+            LOG(DEBUG) << "queueToSink -- call failed: "
+                         << asString(status);
+        }
+        return status;
+    }
+
+    sp<GraphicBufferSource> mSource;
+    std::shared_ptr<C2Component> mLocalComp;
+    sp<IInputSink> mSink;
+    sp<IConfigurable> mSinkConfigurable;
+    std::string mSinkName;
+
+    // Needed for ComponentWrapper implementation
+    std::mutex mAllocatorMutex;
+    std::shared_ptr<C2Allocator> mAllocator;
+    std::atomic_uint64_t mFrameIndex;
+
+};
+
+InputSurfaceConnection::InputSurfaceConnection(
+        const sp<GraphicBufferSource>& source,
+        const std::shared_ptr<C2Component>& comp,
+        const sp<ComponentStore>& store)
+      : mImpl{new Impl(source, comp)},
+        mConfigurable{new CachedConfigurable(
+            std::make_unique<Impl::ConfigurableIntf>(mImpl))} {
+    mConfigurable->init(store.get());
+}
+
+InputSurfaceConnection::InputSurfaceConnection(
+        const sp<GraphicBufferSource>& source,
+        const sp<IInputSink>& sink,
+        const sp<ComponentStore>& store)
+      : mImpl{new Impl(source, sink)},
+        mConfigurable{new CachedConfigurable(
+            std::make_unique<Impl::ConfigurableIntf>(mImpl))} {
+    mConfigurable->init(store.get());
+}
+
+Return<Status> InputSurfaceConnection::disconnect() {
+    std::lock_guard<std::mutex> lock(mImplMutex);
+    mImpl = nullptr;
+    return Status::OK;
+}
+
+InputSurfaceConnection::~InputSurfaceConnection() {
+    mImpl = nullptr;
+}
+
+bool InputSurfaceConnection::init() {
+    std::lock_guard<std::mutex> lock(mImplMutex);
+    return mImpl->init();
+}
+
+Return<sp<IConfigurable>> InputSurfaceConnection::getConfigurable() {
+    return mConfigurable;
+}
+
+// Configurable interface for InputSurfaceConnection::Impl
+c2_status_t InputSurfaceConnection::Impl::ConfigurableIntf::config(
+        const std::vector<C2Param*> &params,
+        c2_blocking_t mayBlock,
+        std::vector<std::unique_ptr<C2SettingResult>> *const failures) {
+    // TODO: implement
+    (void)params;
+    (void)mayBlock;
+    (void)failures;
+    return C2_OK;
+}
+
+c2_status_t InputSurfaceConnection::Impl::ConfigurableIntf::query(
+        const std::vector<C2Param::Index> &indices,
+        c2_blocking_t mayBlock,
+        std::vector<std::unique_ptr<C2Param>> *const params) const {
+    // TODO: implement
+    (void)indices;
+    (void)mayBlock;
+    (void)params;
+    return C2_OK;
+}
+
+c2_status_t InputSurfaceConnection::Impl::ConfigurableIntf::querySupportedParams(
+        std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const {
+    // TODO: implement
+    (void)params;
+    return C2_OK;
+}
+
+c2_status_t InputSurfaceConnection::Impl::ConfigurableIntf::querySupportedValues(
+        std::vector<C2FieldSupportedValuesQuery> &fields,
+        c2_blocking_t mayBlock) const {
+    // TODO: implement
+    (void)fields;
+    (void)mayBlock;
+    return C2_OK;
+}
+
+}  // namespace utils
+}  // namespace V1_0
+}  // namespace c2
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
diff --git a/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/ClientBlockHelper.h b/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/ClientBlockHelper.h
new file mode 100644
index 0000000..0a2298c
--- /dev/null
+++ b/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/ClientBlockHelper.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CLIENT_BLOCK_HELPER_H
+#define CLIENT_BLOCK_HELPER_H
+
+#include <gui/IGraphicBufferProducer.h>
+#include <codec2/hidl/1.0/types.h>
+#include <C2Work.h>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_0 {
+namespace utils {
+
+// BufferQueue-Based Block Operations
+// ==================================
+
+// Manage BufferQueue and graphic blocks for both component and codec.
+// Manage graphic blocks ownership consistently during surface change.
+struct OutputBufferQueue {
+
+    OutputBufferQueue();
+
+    ~OutputBufferQueue();
+
+    // Configure a new surface to render graphic blocks.
+    // Graphic blocks from older surface will be migrated to new surface.
+    bool configure(const sp<IGraphicBufferProducer>& igbp,
+                   uint32_t generation,
+                   uint64_t bqId);
+
+    // Render a graphic block to current surface.
+    status_t outputBuffer(
+            const C2ConstGraphicBlock& block,
+            const BnGraphicBufferProducer::QueueBufferInput& input,
+            BnGraphicBufferProducer::QueueBufferOutput* output);
+
+    // Call holdBufferQueueBlock() on output blocks in the given workList.
+    // The OutputBufferQueue will take the ownership of output blocks.
+    //
+    // Note: This function should be called after WorkBundle has been received
+    // from another process.
+    void holdBufferQueueBlocks(
+            const std::list<std::unique_ptr<C2Work>>& workList);
+
+private:
+
+    class Impl;
+    std::unique_ptr<Impl> mImpl;
+};
+
+}  // namespace utils
+}  // namespace V1_0
+}  // namespace c2
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // CLIENT_BLOCK_HELPER_H
diff --git a/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/Component.h b/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/Component.h
new file mode 100644
index 0000000..86dccd0
--- /dev/null
+++ b/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/Component.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_HIDL_V1_0_UTILS_COMPONENT_H
+#define CODEC2_HIDL_V1_0_UTILS_COMPONENT_H
+
+#include <codec2/hidl/1.0/ComponentInterface.h>
+#include <codec2/hidl/1.0/Configurable.h>
+#include <codec2/hidl/1.0/types.h>
+
+#include <android/hardware/media/bufferpool/2.0/IClientManager.h>
+#include <android/hardware/media/c2/1.0/IComponent.h>
+#include <android/hardware/media/c2/1.0/IComponentInterface.h>
+#include <android/hardware/media/c2/1.0/IComponentListener.h>
+#include <android/hardware/media/c2/1.0/IComponentStore.h>
+#include <android/hardware/media/c2/1.0/IInputSink.h>
+#include <hidl/Status.h>
+#include <hwbinder/IBinder.h>
+
+#include <C2Component.h>
+#include <C2Buffer.h>
+#include <C2.h>
+
+#include <map>
+#include <memory>
+#include <mutex>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_0 {
+namespace utils {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::IBinder;
+using ::android::sp;
+using ::android::wp;
+
+struct ComponentStore;
+
+struct Component : public IComponent,
+                   public std::enable_shared_from_this<Component> {
+    Component(
+            const std::shared_ptr<C2Component>&,
+            const sp<IComponentListener>& listener,
+            const sp<ComponentStore>& store,
+            const sp<::android::hardware::media::bufferpool::V2_0::
+                IClientManager>& clientPoolManager);
+    c2_status_t status() const;
+
+    typedef ::android::hardware::graphics::bufferqueue::V1_0::
+            IGraphicBufferProducer HGraphicBufferProducer1;
+    typedef ::android::hardware::graphics::bufferqueue::V2_0::
+            IGraphicBufferProducer HGraphicBufferProducer2;
+
+    // Methods from IComponent follow.
+    virtual Return<Status> queue(const WorkBundle& workBundle) override;
+    virtual Return<void> flush(flush_cb _hidl_cb) override;
+    virtual Return<Status> drain(bool withEos) override;
+    virtual Return<Status> setOutputSurface(
+            uint64_t blockPoolId,
+            const sp<HGraphicBufferProducer2>& surface) override;
+    virtual Return<void> connectToInputSurface(
+            const sp<IInputSurface>& inputSurface,
+            connectToInputSurface_cb _hidl_cb) override;
+    virtual Return<void> connectToOmxInputSurface(
+            const sp<HGraphicBufferProducer1>& producer,
+            const sp<::android::hardware::media::omx::V1_0::
+            IGraphicBufferSource>& source,
+            connectToOmxInputSurface_cb _hidl_cb) override;
+    virtual Return<Status> disconnectFromInputSurface() override;
+    virtual Return<void> createBlockPool(
+            uint32_t allocatorId,
+            createBlockPool_cb _hidl_cb) override;
+    virtual Return<Status> destroyBlockPool(uint64_t blockPoolId) override;
+    virtual Return<Status> start() override;
+    virtual Return<Status> stop() override;
+    virtual Return<Status> reset() override;
+    virtual Return<Status> release() override;
+    virtual Return<sp<IComponentInterface>> getInterface() override;
+    virtual Return<sp<IInputSink>> asInputSink() override;
+
+    // Returns a C2Component associated to the given sink if the sink is indeed
+    // a local component. Returns nullptr otherwise.
+    //
+    // This function is used by InputSurface::connect().
+    static std::shared_ptr<C2Component> findLocalComponent(
+            const sp<IInputSink>& sink);
+
+protected:
+    c2_status_t mInit;
+    std::shared_ptr<C2Component> mComponent;
+    sp<ComponentInterface> mInterface;
+    sp<IComponentListener> mListener;
+    sp<ComponentStore> mStore;
+    ::android::hardware::media::c2::V1_0::utils::DefaultBufferPoolSender
+            mBufferPoolSender;
+
+    struct Sink;
+    std::mutex mSinkMutex;
+    sp<Sink> mSink;
+
+    std::mutex mBlockPoolsMutex;
+    // This map keeps C2BlockPool objects that are created by createBlockPool()
+    // alive. These C2BlockPool objects can be deleted by calling
+    // destroyBlockPool(), reset() or release(), or by destroying the component.
+    std::map<uint64_t, std::shared_ptr<C2BlockPool>> mBlockPools;
+
+    void initListener(const sp<Component>& self);
+
+    virtual ~Component() override;
+
+    friend struct ComponentStore;
+
+    struct Listener;
+};
+
+}  // namespace utils
+}  // namespace V1_0
+}  // namespace c2
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // CODEC2_HIDL_V1_0_UTILS_COMPONENT_H
diff --git a/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/ComponentInterface.h b/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/ComponentInterface.h
new file mode 100644
index 0000000..a5d235e
--- /dev/null
+++ b/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/ComponentInterface.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_HIDL_V1_0_UTILS_COMPONENT_INTERFACE_H
+#define CODEC2_HIDL_V1_0_UTILS_COMPONENT_INTERFACE_H
+
+#include <codec2/hidl/1.0/Configurable.h>
+#include <codec2/hidl/1.0/types.h>
+
+#include <android/hardware/media/c2/1.0/IComponentInterface.h>
+#include <hidl/Status.h>
+
+#include <C2Component.h>
+#include <C2Buffer.h>
+#include <C2.h>
+
+#include <memory>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_0 {
+namespace utils {
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct ComponentStore;
+
+struct ComponentInterface : public IComponentInterface {
+    ComponentInterface(
+            const std::shared_ptr<C2ComponentInterface>& interface,
+            ComponentStore* store);
+    c2_status_t status() const;
+    virtual Return<sp<IConfigurable>> getConfigurable() override;
+
+protected:
+    std::shared_ptr<C2ComponentInterface> mInterface;
+    sp<CachedConfigurable> mConfigurable;
+    c2_status_t mInit;
+};
+
+
+}  // namespace utils
+}  // namespace V1_0
+}  // namespace c2
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // CODEC2_HIDL_V1_0_UTILS_COMPONENT_INTERFACE_H
diff --git a/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/ComponentStore.h b/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/ComponentStore.h
new file mode 100644
index 0000000..be80c62
--- /dev/null
+++ b/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/ComponentStore.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_HIDL_V1_0_UTILS_COMPONENTSTORE_H
+#define CODEC2_HIDL_V1_0_UTILS_COMPONENTSTORE_H
+
+#include <codec2/hidl/1.0/Component.h>
+#include <codec2/hidl/1.0/ComponentInterface.h>
+#include <codec2/hidl/1.0/Configurable.h>
+
+#include <android/hardware/media/bufferpool/2.0/IClientManager.h>
+#include <android/hardware/media/c2/1.0/IComponentStore.h>
+#include <hidl/Status.h>
+
+#include <C2Component.h>
+#include <C2Param.h>
+#include <C2.h>
+
+#include <chrono>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <set>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_0 {
+namespace utils {
+
+using ::android::hardware::media::bufferpool::V2_0::IClientManager;
+
+using ::android::hardware::hidl_handle;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct ComponentStore : public IComponentStore {
+    ComponentStore(const std::shared_ptr<C2ComponentStore>& store);
+    virtual ~ComponentStore() = default;
+
+    /**
+     * Returns the status of the construction of this object.
+     */
+    c2_status_t status() const;
+
+    /**
+     * This function is called by CachedConfigurable::init() to validate
+     * supported parameters.
+     */
+    c2_status_t validateSupportedParams(
+            const std::vector<std::shared_ptr<C2ParamDescriptor>>& params);
+
+    // Methods from ::android::hardware::media::c2::V1_0::IComponentStore.
+    virtual Return<void> createComponent(
+            const hidl_string& name,
+            const sp<IComponentListener>& listener,
+            const sp<IClientManager>& pool,
+            createComponent_cb _hidl_cb) override;
+    virtual Return<void> createInterface(
+            const hidl_string& name,
+            createInterface_cb _hidl_cb) override;
+    virtual Return<void> listComponents(listComponents_cb _hidl_cb) override;
+    virtual Return<void> createInputSurface(
+            createInputSurface_cb _hidl_cb) override;
+    virtual Return<void> getStructDescriptors(
+            const hidl_vec<uint32_t>& indices,
+            getStructDescriptors_cb _hidl_cb) override;
+    virtual Return<sp<IClientManager>> getPoolClientManager() override;
+    virtual Return<Status> copyBuffer(
+            const Buffer& src,
+            const Buffer& dst) override;
+    virtual Return<sp<IConfigurable>> getConfigurable() override;
+
+    /**
+     * Dumps information when lshal is called.
+     */
+    virtual Return<void> debug(
+            const hidl_handle& handle,
+            const hidl_vec<hidl_string>& args) override;
+
+protected:
+    sp<CachedConfigurable> mConfigurable;
+
+    // Does bookkeeping for an interface that has been loaded.
+    void onInterfaceLoaded(const std::shared_ptr<C2ComponentInterface> &intf);
+
+    c2_status_t mInit;
+    std::shared_ptr<C2ComponentStore> mStore;
+    std::shared_ptr<C2ParamReflector> mParamReflector;
+
+    std::map<C2Param::CoreIndex, std::shared_ptr<C2StructDescriptor>> mStructDescriptors;
+    std::set<C2Param::CoreIndex> mUnsupportedStructDescriptors;
+    std::set<C2String> mLoadedInterfaces;
+    mutable std::mutex mStructDescriptorsMutex;
+
+    // ComponentStore keeps track of live Components.
+
+    struct ComponentStatus {
+        std::shared_ptr<C2Component> c2Component;
+        std::chrono::system_clock::time_point birthTime;
+    };
+
+    mutable std::mutex mComponentRosterMutex;
+    std::map<Component*, ComponentStatus> mComponentRoster;
+
+    // Called whenever Component is created.
+    void reportComponentBirth(Component* component);
+    // Called only from the destructor of Component.
+    void reportComponentDeath(Component* component);
+
+    friend Component;
+
+    // Helper functions for dumping.
+
+    std::ostream& dump(
+            std::ostream& out,
+            const std::shared_ptr<const C2Component::Traits>& comp);
+
+    std::ostream& dump(
+            std::ostream& out,
+            ComponentStatus& compStatus);
+
+};
+
+}  // namespace utils
+}  // namespace V1_0
+}  // namespace c2
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // CODEC2_HIDL_V1_0_UTILS_COMPONENTSTORE_H
diff --git a/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/Configurable.h b/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/Configurable.h
new file mode 100644
index 0000000..8095185
--- /dev/null
+++ b/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/Configurable.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_HIDL_V1_0_UTILS_CONFIGURABLE_H
+#define CODEC2_HIDL_V1_0_UTILS_CONFIGURABLE_H
+
+#include <android/hardware/media/c2/1.0/IConfigurable.h>
+#include <hidl/Status.h>
+
+#include <C2Component.h>
+#include <C2Param.h>
+#include <C2.h>
+
+#include <memory>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_0 {
+namespace utils {
+
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct ComponentStore;
+
+/**
+ * Codec2 objects of different types may have different querying and configuring
+ * functions, but across the Treble boundary, they share the same HIDL
+ * interface, IConfigurable.
+ *
+ * ConfigurableC2Intf is an abstract class that a Codec2 object can implement to
+ * easily expose an IConfigurable instance. See CachedConfigurable below.
+ */
+struct ConfigurableC2Intf {
+    C2String getName() const { return mName; }
+    uint32_t getId() const { return mId; }
+    /** C2ComponentInterface::query_vb sans stack params */
+    virtual c2_status_t query(
+            const std::vector<C2Param::Index> &indices,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2Param>>* const params) const = 0;
+    /** C2ComponentInterface::config_vb */
+    virtual c2_status_t config(
+            const std::vector<C2Param*> &params,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2SettingResult>>* const failures) = 0;
+    /** C2ComponentInterface::querySupportedParams_nb */
+    virtual c2_status_t querySupportedParams(
+            std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const = 0;
+    /** C2ComponentInterface::querySupportedParams_nb */
+    virtual c2_status_t querySupportedValues(
+            std::vector<C2FieldSupportedValuesQuery>& fields, c2_blocking_t mayBlock) const = 0;
+
+    virtual ~ConfigurableC2Intf() = default;
+
+    ConfigurableC2Intf(const C2String& name, uint32_t id)
+          : mName{name}, mId{id} {}
+
+protected:
+    C2String mName; /* cached component name */
+    uint32_t mId;
+};
+
+/**
+ * Implementation of the IConfigurable interface that supports caching of
+ * supported parameters from a supplied ComponentStore.
+ *
+ * CachedConfigurable essentially converts a ConfigurableC2Intf into HIDL's
+ * IConfigurable. A Codec2 object generally implements ConfigurableC2Intf and
+ * passes the implementation to the constructor of CachedConfigurable.
+ *
+ * Note that caching happens
+ */
+struct CachedConfigurable : public IConfigurable {
+    CachedConfigurable(std::unique_ptr<ConfigurableC2Intf>&& intf);
+
+    c2_status_t init(ComponentStore* store);
+
+    // Methods from ::android::hardware::media::c2::V1_0::IConfigurable
+
+    virtual Return<uint32_t> getId() override;
+
+    virtual Return<void> getName(getName_cb _hidl_cb) override;
+
+    virtual Return<void> query(
+            const hidl_vec<uint32_t>& indices,
+            bool mayBlock,
+            query_cb _hidl_cb) override;
+
+    virtual Return<void> config(
+            const hidl_vec<uint8_t>& inParams,
+            bool mayBlock,
+            config_cb _hidl_cb) override;
+
+    virtual Return<void> querySupportedParams(
+            uint32_t start,
+            uint32_t count,
+            querySupportedParams_cb _hidl_cb) override;
+
+    virtual Return<void> querySupportedValues(
+            const hidl_vec<FieldSupportedValuesQuery>& inFields,
+            bool mayBlock,
+            querySupportedValues_cb _hidl_cb) override;
+
+protected:
+    // Common Codec2.0 interface wrapper
+    std::unique_ptr<ConfigurableC2Intf> mIntf;
+
+    // Cached supported params
+    std::vector<std::shared_ptr<C2ParamDescriptor>> mSupportedParams;
+};
+
+}  // namespace utils
+}  // namespace V1_0
+}  // namespace c2
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // CODEC2_HIDL_V1_0_UTILS_CONFIGURABLE_H
+
diff --git a/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/InputBufferManager.h b/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/InputBufferManager.h
new file mode 100644
index 0000000..b6857d5
--- /dev/null
+++ b/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/InputBufferManager.h
@@ -0,0 +1,294 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_HIDL_V1_0_UTILS_INPUT_BUFFER_MANAGER_H
+#define CODEC2_HIDL_V1_0_UTILS_INPUT_BUFFER_MANAGER_H
+
+#include <android/hardware/media/c2/1.0/IComponentListener.h>
+#include <utils/Timers.h>
+
+#include <C2Buffer.h>
+#include <C2Work.h>
+
+#include <set>
+#include <map>
+#include <thread>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_0 {
+namespace utils {
+
+using namespace ::android;
+
+/**
+ * InputBufferManager
+ * ==================
+ *
+ * InputBufferManager presents a way to track and untrack input buffers in this
+ * (codec) process and send a notification to a listener, possibly in a
+ * different process, when a tracked buffer no longer has any references in this
+ * process.
+ *
+ * InputBufferManager holds a collection of records representing tracked buffers
+ * and their callback listeners. Conceptually, one record is a triple (listener,
+ * frameIndex, bufferIndex) where
+ *
+ * - (frameIndex, bufferIndex) is a pair of indices used to identify the buffer.
+ * - listener is of type IComponentListener. Its onInputBuffersReleased()
+ *   function will be called after the associated buffer dies. The argument of
+ *   onInputBuffersReleased() is a list of InputBuffer objects, each of which
+ *   has the following members:
+ *
+ *     uint64_t frameIndex
+ *     uint32_t arrayIndex
+ *
+ * When a tracked buffer associated to the triple (listener, frameIndex,
+ * bufferIndex) goes out of scope, listener->onInputBuffersReleased() will be
+ * called with an InputBuffer object whose members are set as follows:
+ *
+ *     inputBuffer.frameIndex = frameIndex
+ *     inputBuffer.arrayIndex = bufferIndex
+ *
+ * IPC Optimization
+ * ----------------
+ *
+ * Since onInputBuffersReleased() is an IPC call, InputBufferManager tries not
+ * to call it too often. Any two calls to the same listener are at least
+ * mNotificationIntervalNs nanoseconds apart, where mNotificationIntervalNs is
+ * configurable via calling setNotificationInterval(). The default value of
+ * mNotificationIntervalNs is kDefaultNotificationInternalNs.
+ *
+ * Public Member Functions
+ * -----------------------
+ *
+ * InputBufferManager is a singleton class. Its only instance is accessible via
+ * the following public functions:
+ *
+ * - registerFrameData(const sp<IComponentListener>& listener,
+ *                     const C2FrameData& input)
+ *
+ * - unregisterFrameData(const sp<IComponentListener>& listener,
+ *                       const C2FrameData& input)
+ *
+ * - unregisterFrameData(const sp<IComponentListener>& listener)
+ *
+ * - setNotificationInterval(nsecs_t notificationIntervalNs)
+ *
+ */
+
+struct InputBufferManager {
+
+    /**
+     * The default value for the time interval between 2 subsequent IPCs.
+     */
+    static constexpr nsecs_t kDefaultNotificationIntervalNs = 1000000; /* 1ms */
+
+    /**
+     * Track all buffers in a C2FrameData object.
+     *
+     * input (C2FrameData) has the following two members that are of interest:
+     *
+     *   C2WorkOrdinal                ordinal
+     *   vector<shared_ptr<C2Buffer>> buffers
+     *
+     * Calling registerFrameData(listener, input) will register multiple
+     * triples (listener, frameIndex, bufferIndex) where frameIndex is equal to
+     * input.ordinal.frameIndex and bufferIndex runs through the indices of
+     * input.buffers such that input.buffers[bufferIndex] is not null.
+     *
+     * This should be called from queue().
+     *
+     * \param listener Listener of death notifications.
+     * \param input Input frame data whose input buffers are to be tracked.
+     */
+    static void registerFrameData(
+            const sp<IComponentListener>& listener,
+            const C2FrameData& input);
+
+    /**
+     * Untrack all buffers in a C2FrameData object.
+     *
+     * Calling unregisterFrameData(listener, input) will unregister and remove
+     * pending notifications for all triples (l, fi, bufferIndex) such that
+     * l = listener and fi = input.ordinal.frameIndex.
+     *
+     * This should be called from onWorkDone() and flush().
+     *
+     * \param listener Previously registered listener.
+     * \param input Previously registered frame data.
+     */
+    static void unregisterFrameData(
+            const wp<IComponentListener>& listener,
+            const C2FrameData& input);
+
+    /**
+     * Untrack all buffers associated to a given listener.
+     *
+     * Calling unregisterFrameData(listener) will unregister and remove
+     * pending notifications for all triples (l, frameIndex, bufferIndex) such
+     * that l = listener.
+     *
+     * This should be called when the component cleans up all input buffers,
+     * i.e., when reset(), release(), stop() or ~Component() is called.
+     *
+     * \param listener Previously registered listener.
+     */
+    static void unregisterFrameData(
+            const wp<IComponentListener>& listener);
+
+    /**
+     * Set the notification interval.
+     *
+     * \param notificationIntervalNs New notification interval, in nanoseconds.
+     */
+    static void setNotificationInterval(nsecs_t notificationIntervalNs);
+
+private:
+    void _registerFrameData(
+            const sp<IComponentListener>& listener,
+            const C2FrameData& input);
+    void _unregisterFrameData(
+            const wp<IComponentListener>& listener,
+            const C2FrameData& input);
+    void _unregisterFrameData(
+            const wp<IComponentListener>& listener);
+    void _setNotificationInterval(nsecs_t notificationIntervalNs);
+
+    // The callback function tied to C2Buffer objects.
+    //
+    // Note: This function assumes that sInstance is the only instance of this
+    //       class.
+    static void onBufferDestroyed(const C2Buffer* buf, void* arg);
+    void _onBufferDestroyed(const C2Buffer* buf, void* arg);
+
+    // Persistent data to be passed as "arg" in onBufferDestroyed().
+    // This is essentially the triple (listener, frameIndex, bufferIndex) plus a
+    // weak pointer to the C2Buffer object.
+    //
+    // Note that the "key" is bufferIndex according to operator<(). This is
+    // designed to work with TrackedBuffersMap defined below.
+    struct TrackedBuffer {
+        wp<IComponentListener> listener;
+        uint64_t frameIndex;
+        size_t bufferIndex;
+        std::weak_ptr<C2Buffer> buffer;
+        TrackedBuffer(const wp<IComponentListener>& listener,
+                      uint64_t frameIndex,
+                      size_t bufferIndex,
+                      const std::shared_ptr<C2Buffer>& buffer)
+              : listener(listener),
+                frameIndex(frameIndex),
+                bufferIndex(bufferIndex),
+                buffer(buffer) {}
+        TrackedBuffer(const TrackedBuffer&) = default;
+        bool operator<(const TrackedBuffer& other) const {
+            return bufferIndex < other.bufferIndex;
+        }
+    };
+
+    // Map: listener -> frameIndex -> set<TrackedBuffer>.
+    // Essentially, this is used to store triples (listener, frameIndex,
+    // bufferIndex) that's searchable by listener and (listener, frameIndex).
+    // However, the value of the innermost map is TrackedBuffer, which also
+    // contains an extra copy of listener and frameIndex. This is needed
+    // because onBufferDestroyed() needs to know listener and frameIndex too.
+    typedef std::map<wp<IComponentListener>,
+                     std::map<uint64_t,
+                              std::set<TrackedBuffer>>> TrackedBuffersMap;
+
+    // Storage for pending (unsent) death notifications for one listener.
+    // Each pair in member named "indices" are (frameIndex, bufferIndex) from
+    // the (listener, frameIndex, bufferIndex) triple.
+    struct DeathNotifications {
+
+        // The number of pending notifications for this listener.
+        // count may be 0, in which case the DeathNotifications object will
+        // remain valid for only a small period (specified
+        // nanoseconds).
+        size_t count;
+
+        // The timestamp of the most recent callback on this listener. This is
+        // used to guarantee that callbacks do not occur too frequently, and
+        // also to trigger expiration of a DeathNotifications object that has
+        // count = 0.
+        nsecs_t lastSentNs;
+
+        // Map: frameIndex -> vector of bufferIndices
+        // This is essentially a collection of (framdeIndex, bufferIndex).
+        std::map<uint64_t, std::vector<size_t>> indices;
+
+        DeathNotifications(
+                nsecs_t notificationIntervalNs = kDefaultNotificationIntervalNs)
+              : count(0),
+                lastSentNs(systemTime() - notificationIntervalNs),
+                indices() {}
+    };
+
+    // The minimum time period between IPC calls to notify the client about the
+    // destruction of input buffers.
+    std::atomic<nsecs_t> mNotificationIntervalNs{kDefaultNotificationIntervalNs};
+
+    // Mutex for the management of all input buffers.
+    std::mutex mMutex;
+
+    // Tracked input buffers.
+    TrackedBuffersMap mTrackedBuffersMap;
+
+    // Death notifications to be sent.
+    //
+    // A DeathNotifications object is associated to each listener. An entry in
+    // this map will be removed if its associated DeathNotifications has count =
+    // 0 and lastSentNs < systemTime() - mNotificationIntervalNs.
+    std::map<wp<IComponentListener>, DeathNotifications> mDeathNotifications;
+
+    // Condition variable signaled when an entry is added to mDeathNotifications.
+    std::condition_variable mOnBufferDestroyed;
+
+    // Notify the clients about buffer destructions.
+    // Return false if all destructions have been notified.
+    // Return true and set timeToRetry to the duration to wait for before
+    // retrying if some destructions have not been notified.
+    bool processNotifications(nsecs_t* timeToRetryNs);
+
+    // Main function for the input buffer manager thread.
+    void main();
+
+    // The thread that manages notifications.
+    //
+    // Note: This variable is declared last so its initialization will happen
+    // after all other member variables have been initialized.
+    std::thread mMainThread;
+
+    // Private constructor.
+    InputBufferManager();
+
+    // The only instance of this class.
+    static InputBufferManager& getInstance();
+
+};
+
+}  // namespace utils
+}  // namespace V1_0
+}  // namespace c2
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // CODEC2_HIDL_V1_0_UTILS_INPUT_BUFFER_MANAGER_H
+
diff --git a/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/InputSurface.h b/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/InputSurface.h
new file mode 100644
index 0000000..29ed7ff
--- /dev/null
+++ b/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/InputSurface.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_HIDL_V1_0_UTILS_INPUTSURFACE_H
+#define CODEC2_HIDL_V1_0_UTILS_INPUTSURFACE_H
+
+#include <codec2/hidl/1.0/ComponentStore.h>
+
+#include <android/hardware/graphics/bufferqueue/2.0/IGraphicBufferProducer.h>
+#include <android/hardware/media/c2/1.0/IInputSink.h>
+#include <android/hardware/media/c2/1.0/IInputSurface.h>
+#include <hidl/Status.h>
+#include <media/stagefright/bqhelper/GraphicBufferSource.h>
+
+#include <util/C2InterfaceHelper.h>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_0 {
+namespace utils {
+
+using ::android::hardware::hidl_handle;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct InputSurface : public IInputSurface {
+
+    typedef ::android::hardware::graphics::bufferqueue::V2_0::
+            IGraphicBufferProducer HGraphicBufferProducer;
+
+    typedef ::android::
+            GraphicBufferSource GraphicBufferSource;
+
+    virtual Return<sp<HGraphicBufferProducer>> getGraphicBufferProducer() override;
+
+    virtual Return<sp<IConfigurable>> getConfigurable() override;
+
+    virtual Return<void> connect(
+            const sp<IInputSink>& sink,
+            connect_cb _hidl_cb) override;
+
+protected:
+
+    class Interface;
+    class ConfigurableIntf;
+
+    sp<ComponentStore> mStore;
+    sp<HGraphicBufferProducer> mProducer;
+    sp<GraphicBufferSource> mSource;
+    std::shared_ptr<Interface> mIntf;
+    sp<CachedConfigurable> mConfigurable;
+
+    InputSurface(
+            const sp<ComponentStore>& store,
+            const std::shared_ptr<C2ReflectorHelper>& reflector,
+            const sp<HGraphicBufferProducer>& base,
+            const sp<GraphicBufferSource>& source);
+
+    virtual ~InputSurface() override = default;
+
+    friend struct ComponentStore;
+
+};
+
+
+}  // namespace utils
+}  // namespace V1_0
+}  // namespace c2
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // CODEC2_HIDL_V1_0_UTILS_INPUTSURFACE_H
diff --git a/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/InputSurfaceConnection.h b/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/InputSurfaceConnection.h
new file mode 100644
index 0000000..758b6b2
--- /dev/null
+++ b/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/InputSurfaceConnection.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_HIDL_V1_0_UTILS_INPUTSURFACECONNECTION_H
+#define CODEC2_HIDL_V1_0_UTILS_INPUTSURFACECONNECTION_H
+
+#include <codec2/hidl/1.0/Component.h>
+#include <codec2/hidl/1.0/Configurable.h>
+
+#include <android/hardware/media/c2/1.0/IComponent.h>
+#include <android/hardware/media/c2/1.0/IConfigurable.h>
+#include <android/hardware/media/c2/1.0/IInputSurfaceConnection.h>
+
+#include <media/stagefright/bqhelper/GraphicBufferSource.h>
+
+#include <hidl/HidlSupport.h>
+#include <hidl/Status.h>
+
+#include <C2Component.h>
+
+#include <memory>
+#include <mutex>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_0 {
+namespace utils {
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+using ::android::GraphicBufferSource;
+
+// An InputSurfaceConnection connects an InputSurface to a sink, which may be an
+// IInputSink or a local C2Component. This can be specified by choosing the
+// corresponding constructor. The reason for distinguishing these two cases is
+// that when an InputSurfaceConnection lives in the same process as the
+// component that processes the buffers, data parceling is not needed.
+struct InputSurfaceConnection : public IInputSurfaceConnection {
+
+    virtual Return<Status> disconnect() override;
+
+    virtual Return<sp<IConfigurable>> getConfigurable() override;
+
+protected:
+
+    InputSurfaceConnection(
+            const sp<GraphicBufferSource>& source,
+            const std::shared_ptr<C2Component>& comp,
+            const sp<ComponentStore>& store);
+
+    InputSurfaceConnection(
+            const sp<GraphicBufferSource>& source,
+            const sp<IInputSink>& sink,
+            const sp<ComponentStore>& store);
+
+    bool init();
+
+    friend struct InputSurface;
+
+    InputSurfaceConnection() = delete;
+    InputSurfaceConnection(const InputSurfaceConnection&) = delete;
+    void operator=(const InputSurfaceConnection&) = delete;
+
+    struct Impl;
+
+    std::mutex mImplMutex;
+    sp<Impl> mImpl;
+    sp<CachedConfigurable> mConfigurable;
+
+    virtual ~InputSurfaceConnection() override;
+};
+
+}  // namespace utils
+}  // namespace V1_0
+}  // namespace c2
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // CODEC2_HIDL_V1_0_UTILS_INPUTSURFACECONNECTION_H
diff --git a/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/types.h b/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/types.h
new file mode 100644
index 0000000..a9928b3
--- /dev/null
+++ b/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/types.h
@@ -0,0 +1,350 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_HIDL_V1_0_UTILS_TYPES_H
+#define CODEC2_HIDL_V1_0_UTILS_TYPES_H
+
+#include <bufferpool/ClientManager.h>
+#include <android/hardware/media/bufferpool/2.0/IClientManager.h>
+#include <android/hardware/media/bufferpool/2.0/types.h>
+#include <android/hardware/media/c2/1.0/IComponentStore.h>
+#include <android/hardware/media/c2/1.0/types.h>
+#include <android/hidl/safe_union/1.0/types.h>
+
+#include <C2Component.h>
+#include <C2Param.h>
+#include <C2ParamDef.h>
+#include <C2Work.h>
+#include <util/C2Debug-base.h>
+
+#include <chrono>
+
+using namespace std::chrono_literals;
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_0 {
+namespace utils {
+
+using ::android::hardware::hidl_bitfield;
+using ::android::hardware::hidl_handle;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::status_t;
+using ::android::sp;
+using ::android::hardware::media::bufferpool::V2_0::implementation::
+        ConnectionId;
+
+// Types of metadata for Blocks.
+struct C2Hidl_Range {
+    uint32_t offset;
+    uint32_t length; // Do not use "size" because the name collides with C2Info::size().
+};
+typedef C2GlobalParam<C2Info, C2Hidl_Range, 0> C2Hidl_RangeInfo;
+
+struct C2Hidl_Rect {
+    uint32_t left;
+    uint32_t top;
+    uint32_t width;
+    uint32_t height;
+};
+typedef C2GlobalParam<C2Info, C2Hidl_Rect, 1> C2Hidl_RectInfo;
+
+// Make asString() and operator<< work with Status as well as c2_status_t.
+C2_DECLARE_AS_STRING_AND_DEFINE_STREAM_OUT(Status);
+
+/**
+ * All objcpy() functions will return a boolean value indicating whether the
+ * conversion succeeds or not.
+ */
+
+// C2SettingResult -> SettingResult
+bool objcpy(
+        SettingResult* d,
+        const C2SettingResult& s);
+
+// SettingResult -> std::unique_ptr<C2SettingResult>
+bool objcpy(
+        std::unique_ptr<C2SettingResult>* d,
+        const SettingResult& s);
+
+// C2ParamDescriptor -> ParamDescriptor
+bool objcpy(
+        ParamDescriptor* d,
+        const C2ParamDescriptor& s);
+
+// ParamDescriptor -> std::shared_ptr<C2ParamDescriptor>
+bool objcpy(
+        std::shared_ptr<C2ParamDescriptor>* d,
+        const ParamDescriptor& s);
+
+// C2FieldSupportedValuesQuery -> FieldSupportedValuesQuery
+bool objcpy(
+        FieldSupportedValuesQuery* d,
+        const C2FieldSupportedValuesQuery& s);
+
+// FieldSupportedValuesQuery -> C2FieldSupportedValuesQuery
+bool objcpy(
+        C2FieldSupportedValuesQuery* d,
+        const FieldSupportedValuesQuery& s);
+
+// C2FieldSupportedValuesQuery -> FieldSupportedValuesQueryResult
+bool objcpy(
+        FieldSupportedValuesQueryResult* d,
+        const C2FieldSupportedValuesQuery& s);
+
+// FieldSupportedValuesQuery, FieldSupportedValuesQueryResult -> C2FieldSupportedValuesQuery
+bool objcpy(
+        C2FieldSupportedValuesQuery* d,
+        const FieldSupportedValuesQuery& sq,
+        const FieldSupportedValuesQueryResult& sr);
+
+// C2Component::Traits -> ComponentTraits
+bool objcpy(
+        IComponentStore::ComponentTraits* d,
+        const C2Component::Traits& s);
+
+// ComponentTraits -> C2Component::Traits
+bool objcpy(
+        C2Component::Traits* d,
+        const IComponentStore::ComponentTraits& s);
+
+// C2StructDescriptor -> StructDescriptor
+bool objcpy(
+        StructDescriptor* d,
+        const C2StructDescriptor& s);
+
+// StructDescriptor -> C2StructDescriptor
+bool objcpy(
+        std::unique_ptr<C2StructDescriptor>* d,
+        const StructDescriptor& s);
+
+// Abstract class to be used in
+// objcpy(std::list<std::unique_ptr<C2Work>> -> WorkBundle).
+struct BufferPoolSender {
+    typedef ::android::hardware::media::bufferpool::V2_0::
+            ResultStatus ResultStatus;
+    typedef ::android::hardware::media::bufferpool::V2_0::
+            BufferStatusMessage BufferStatusMessage;
+    typedef ::android::hardware::media::bufferpool::
+            BufferPoolData BufferPoolData;
+
+    /**
+     * Send bpData and return BufferStatusMessage that can be supplied to
+     * IClientManager::receive() in the receiving process.
+     *
+     * This function will be called from within the function
+     * objcpy(std::list<std::unique_ptr<C2Work>> -> WorkBundle).
+     *
+     * \param[in] bpData BufferPoolData identifying the buffer to send.
+     * \param[out] bpMessage BufferStatusMessage of the transaction. Information
+     *    inside \p bpMessage should be passed to the receiving process by some
+     *    other means so it can call receive() properly.
+     * \return ResultStatus value that determines the success of the operation.
+     *    (See the possible values of ResultStatus in
+     *    hardware/interfaces/media/bufferpool/2.0/types.hal.)
+     */
+    virtual ResultStatus send(
+            const std::shared_ptr<BufferPoolData>& bpData,
+            BufferStatusMessage* bpMessage) = 0;
+
+    virtual ~BufferPoolSender() = default;
+};
+
+// Default implementation of BufferPoolSender.
+//
+// To use DefaultBufferPoolSender, the IClientManager instance of the receiving
+// process must be set before send() can operate. DefaultBufferPoolSender will
+// hold a strong reference to the IClientManager instance and use it to call
+// IClientManager::registerSender() to establish the bufferpool connection when
+// send() is called.
+struct DefaultBufferPoolSender : BufferPoolSender {
+    typedef ::android::hardware::media::bufferpool::V2_0::implementation::
+            ClientManager ClientManager;
+    typedef ::android::hardware::media::bufferpool::V2_0::
+            IClientManager IClientManager;
+
+    // Set the IClientManager instance of the receiving process and the refresh
+    // interval for the connection. The default interval is 4.5 seconds, which
+    // is slightly shorter than the amount of time the bufferpool will keep an
+    // inactive connection for.
+    DefaultBufferPoolSender(
+            const sp<IClientManager>& receiverManager = nullptr,
+            std::chrono::steady_clock::duration refreshInterval = 4500ms);
+
+    // Set the IClientManager instance of the receiving process and the refresh
+    // interval for the connection. The default interval is 4.5 seconds, which
+    // is slightly shorter than the amount of time the bufferpool will keep an
+    // inactive connection for.
+    void setReceiver(
+            const sp<IClientManager>& receiverManager,
+            std::chrono::steady_clock::duration refreshInterval = 4500ms);
+
+    // Implementation of BufferPoolSender::send(). send() will establish a
+    // bufferpool connection if needed, then send the bufferpool data over to
+    // the receiving process.
+    virtual ResultStatus send(
+            const std::shared_ptr<BufferPoolData>& bpData,
+            BufferStatusMessage* bpMessage) override;
+
+private:
+    std::mutex mMutex;
+    sp<ClientManager> mSenderManager;
+    sp<IClientManager> mReceiverManager;
+    int64_t mReceiverConnectionId;
+    int64_t mSourceConnectionId;
+    std::chrono::steady_clock::time_point mLastSent;
+    std::chrono::steady_clock::duration mRefreshInterval;
+};
+
+// std::list<std::unique_ptr<C2Work>> -> WorkBundle
+// Note: If bufferpool will be used, bpSender must not be null.
+bool objcpy(
+        WorkBundle* d,
+        const std::list<std::unique_ptr<C2Work>>& s,
+        BufferPoolSender* bpSender = nullptr);
+
+// WorkBundle -> std::list<std::unique_ptr<C2Work>>
+bool objcpy(
+        std::list<std::unique_ptr<C2Work>>* d,
+        const WorkBundle& s);
+
+/**
+ * Parses a params blob and returns C2Param pointers to its params. The pointers
+ * point to locations inside the underlying buffer of \p blob. If \p blob is
+ * destroyed, the pointers become invalid.
+ *
+ * \param[out] params target vector of C2Param pointers
+ * \param[in] blob parameter blob to parse
+ * \retval true if the full blob was parsed
+ * \retval false otherwise
+ */
+bool parseParamsBlob(
+        std::vector<C2Param*> *params,
+        const hidl_vec<uint8_t> &blob);
+
+/**
+ * Concatenates a list of C2Params into a params blob.
+ *
+ * \param[out] blob target blob
+ * \param[in] params parameters to concatenate
+ * \retval true if the blob was successfully created
+ * \retval false if the blob was not successful (this only happens if the
+ *         parameters were not const)
+ */
+bool createParamsBlob(
+        hidl_vec<uint8_t> *blob,
+        const std::vector<C2Param*> &params);
+bool createParamsBlob(
+        hidl_vec<uint8_t> *blob,
+        const std::vector<std::unique_ptr<C2Param>> &params);
+bool createParamsBlob(
+        hidl_vec<uint8_t> *blob,
+        const std::vector<std::shared_ptr<const C2Info>> &params);
+bool createParamsBlob(
+        hidl_vec<uint8_t> *blob,
+        const std::vector<std::unique_ptr<C2Tuning>> &params);
+
+/**
+ * Parses a params blob and create a vector of C2Params whose members are copies
+ * of the params in the blob.
+ *
+ * \param[out] params the resulting vector
+ * \param[in] blob parameter blob to parse
+ * \retval true if the full blob was parsed and params was constructed
+ * \retval false otherwise
+ */
+bool copyParamsFromBlob(
+        std::vector<std::unique_ptr<C2Param>>* params,
+        Params blob);
+bool copyParamsFromBlob(
+        std::vector<std::unique_ptr<C2Tuning>>* params,
+        Params blob);
+
+/**
+ * Parses a params blob and applies updates to params.
+ *
+ * \param[in,out] params params to be updated
+ * \param[in] blob parameter blob containing updates
+ * \retval true if the full blob was parsed and params was updated
+ * \retval false otherwise
+ */
+bool updateParamsFromBlob(
+        const std::vector<C2Param*>& params,
+        const Params& blob);
+
+/**
+ * Converts a BufferPool status value to c2_status_t.
+ * \param BufferPool status
+ * \return Corresponding c2_status_t
+ */
+c2_status_t toC2Status(::android::hardware::media::bufferpool::V2_0::
+        ResultStatus rs);
+
+// BufferQueue-Based Block Operations
+// ==================================
+
+// Call before transferring block to other processes.
+//
+// The given block is ready to transfer to other processes. This will guarantee
+// the given block data is not mutated by bufferqueue migration.
+bool beginTransferBufferQueueBlock(const C2ConstGraphicBlock& block);
+
+// Call beginTransferBufferQueueBlock() on blocks in the given workList.
+// processInput determines whether input blocks are yielded. processOutput
+// works similarly on output blocks. (The default value of processInput is
+// false while the default value of processOutput is true. This implies that in
+// most cases, only output buffers contain bufferqueue-based blocks.)
+void beginTransferBufferQueueBlocks(
+        const std::list<std::unique_ptr<C2Work>>& workList,
+        bool processInput = false,
+        bool processOutput = true);
+
+// Call after transferring block is finished and make sure that
+// beginTransferBufferQueueBlock() is called before.
+//
+// The transfer of given block is finished. If transfer is successful the given
+// block is not owned by process anymore. Since transfer is finished the given
+// block data is OK to mutate by bufferqueue migration after this call.
+bool endTransferBufferQueueBlock(const C2ConstGraphicBlock& block,
+                                 bool transfer);
+
+// Call endTransferBufferQueueBlock() on blocks in the given workList.
+// processInput determines whether input blocks are yielded. processOutput
+// works similarly on output blocks. (The default value of processInput is
+// false while the default value of processOutput is true. This implies that in
+// most cases, only output buffers contain bufferqueue-based blocks.)
+void endTransferBufferQueueBlocks(
+        const std::list<std::unique_ptr<C2Work>>& workList,
+        bool transfer,
+        bool processInput = false,
+        bool processOutput = true);
+
+// The given block is ready to be rendered. the given block is not owned by
+// process anymore. If migration is in progress, this returns false in order
+// not to render.
+bool displayBufferQueueBlock(const C2ConstGraphicBlock& block);
+
+}  // namespace utils
+}  // namespace V1_0
+}  // namespace c2
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // CODEC2_HIDL_V1_0_UTILS_TYPES_H
diff --git a/media/codec2/hidl/1.0/utils/types.cpp b/media/codec2/hidl/1.0/utils/types.cpp
new file mode 100644
index 0000000..07dbf67
--- /dev/null
+++ b/media/codec2/hidl/1.0/utils/types.cpp
@@ -0,0 +1,1838 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2-types"
+#include <android-base/logging.h>
+
+#include <codec2/hidl/1.0/types.h>
+#include <media/stagefright/foundation/AUtils.h>
+
+#include <C2AllocatorIon.h>
+#include <C2AllocatorGralloc.h>
+#include <C2BlockInternal.h>
+#include <C2Buffer.h>
+#include <C2Component.h>
+#include <C2Param.h>
+#include <C2ParamInternal.h>
+#include <C2PlatformSupport.h>
+#include <C2Work.h>
+#include <util/C2ParamUtils.h>
+
+#include <algorithm>
+#include <functional>
+#include <iomanip>
+#include <unordered_map>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_0 {
+namespace utils {
+
+using ::android::hardware::Return;
+using ::android::hardware::media::bufferpool::BufferPoolData;
+using ::android::hardware::media::bufferpool::V2_0::BufferStatusMessage;
+using ::android::hardware::media::bufferpool::V2_0::ResultStatus;
+using ::android::hardware::media::bufferpool::V2_0::implementation::
+        ClientManager;
+using ::android::hardware::media::bufferpool::V2_0::implementation::
+        TransactionId;
+
+const char* asString(Status status, const char* def) {
+    return asString(static_cast<c2_status_t>(status), def);
+}
+
+namespace /* unnamed */ {
+
+template <typename EnumClass>
+typename std::underlying_type<EnumClass>::type underlying_value(
+        EnumClass x) {
+    return static_cast<typename std::underlying_type<EnumClass>::type>(x);
+}
+
+template <typename Common, typename DstVector, typename SrcVector>
+void copyVector(DstVector* d, const SrcVector& s) {
+    static_assert(sizeof(Common) == sizeof(decltype((*d)[0])),
+            "DstVector's component size does not match Common");
+    static_assert(sizeof(Common) == sizeof(decltype(s[0])),
+            "SrcVector's component size does not match Common");
+    d->resize(s.size());
+    std::copy(
+            reinterpret_cast<const Common*>(&s[0]),
+            reinterpret_cast<const Common*>(&s[0] + s.size()),
+            reinterpret_cast<Common*>(&(*d)[0]));
+}
+
+// C2ParamField -> ParamField
+bool objcpy(ParamField *d, const C2ParamField &s) {
+    d->index = static_cast<ParamIndex>(_C2ParamInspector::GetIndex(s));
+    d->fieldId.offset = static_cast<uint32_t>(_C2ParamInspector::GetOffset(s));
+    d->fieldId.size = static_cast<uint32_t>(_C2ParamInspector::GetSize(s));
+    return true;
+}
+
+struct C2ParamFieldBuilder : public C2ParamField {
+    C2ParamFieldBuilder() : C2ParamField(
+            static_cast<C2Param::Index>(static_cast<uint32_t>(0)), 0, 0) {
+    }
+    // ParamField -> C2ParamField
+    C2ParamFieldBuilder(const ParamField& s) : C2ParamField(
+            static_cast<C2Param::Index>(static_cast<uint32_t>(s.index)),
+            static_cast<uint32_t>(s.fieldId.offset),
+            static_cast<uint32_t>(s.fieldId.size)) {
+    }
+};
+
+// C2WorkOrdinalStruct -> WorkOrdinal
+bool objcpy(WorkOrdinal *d, const C2WorkOrdinalStruct &s) {
+    d->frameIndex = static_cast<uint64_t>(s.frameIndex.peeku());
+    d->timestampUs = static_cast<uint64_t>(s.timestamp.peeku());
+    d->customOrdinal = static_cast<uint64_t>(s.customOrdinal.peeku());
+    return true;
+}
+
+// WorkOrdinal -> C2WorkOrdinalStruct
+bool objcpy(C2WorkOrdinalStruct *d, const WorkOrdinal &s) {
+    d->frameIndex = c2_cntr64_t(s.frameIndex);
+    d->timestamp = c2_cntr64_t(s.timestampUs);
+    d->customOrdinal = c2_cntr64_t(s.customOrdinal);
+    return true;
+}
+
+// C2FieldSupportedValues::range's type -> ValueRange
+bool objcpy(
+        ValueRange* d,
+        const decltype(C2FieldSupportedValues::range)& s) {
+    d->min = static_cast<PrimitiveValue>(s.min.u64);
+    d->max = static_cast<PrimitiveValue>(s.max.u64);
+    d->step = static_cast<PrimitiveValue>(s.step.u64);
+    d->num = static_cast<PrimitiveValue>(s.num.u64);
+    d->denom = static_cast<PrimitiveValue>(s.denom.u64);
+    return true;
+}
+
+// C2FieldSupportedValues -> FieldSupportedValues
+bool objcpy(FieldSupportedValues *d, const C2FieldSupportedValues &s) {
+    switch (s.type) {
+    case C2FieldSupportedValues::EMPTY: {
+            d->empty(::android::hidl::safe_union::V1_0::Monostate{});
+            break;
+        }
+    case C2FieldSupportedValues::RANGE: {
+            ValueRange range{};
+            if (!objcpy(&range, s.range)) {
+                LOG(ERROR) << "Invalid C2FieldSupportedValues::range.";
+                d->range(range);
+                return false;
+            }
+            d->range(range);
+            break;
+        }
+    case C2FieldSupportedValues::VALUES: {
+            hidl_vec<PrimitiveValue> values;
+            copyVector<uint64_t>(&values, s.values);
+            d->values(values);
+            break;
+        }
+    case C2FieldSupportedValues::FLAGS: {
+            hidl_vec<PrimitiveValue> flags;
+            copyVector<uint64_t>(&flags, s.values);
+            d->flags(flags);
+            break;
+        }
+    default:
+        LOG(DEBUG) << "Unrecognized C2FieldSupportedValues::type_t "
+                   << "with underlying value " << underlying_value(s.type)
+                   << ".";
+        return false;
+    }
+    return true;
+}
+
+// ValueRange -> C2FieldSupportedValues::range's type
+bool objcpy(
+        decltype(C2FieldSupportedValues::range)* d,
+        const ValueRange& s) {
+    d->min.u64 = static_cast<uint64_t>(s.min);
+    d->max.u64 = static_cast<uint64_t>(s.max);
+    d->step.u64 = static_cast<uint64_t>(s.step);
+    d->num.u64 = static_cast<uint64_t>(s.num);
+    d->denom.u64 = static_cast<uint64_t>(s.denom);
+    return true;
+}
+
+// FieldSupportedValues -> C2FieldSupportedValues
+bool objcpy(C2FieldSupportedValues *d, const FieldSupportedValues &s) {
+    switch (s.getDiscriminator()) {
+    case FieldSupportedValues::hidl_discriminator::empty: {
+            d->type = C2FieldSupportedValues::EMPTY;
+            break;
+        }
+    case FieldSupportedValues::hidl_discriminator::range: {
+            d->type = C2FieldSupportedValues::RANGE;
+            if (!objcpy(&d->range, s.range())) {
+                LOG(ERROR) << "Invalid FieldSupportedValues::range.";
+                return false;
+            }
+            d->values.resize(0);
+            break;
+        }
+    case FieldSupportedValues::hidl_discriminator::values: {
+            d->type = C2FieldSupportedValues::VALUES;
+            copyVector<uint64_t>(&d->values, s.values());
+            break;
+        }
+    case FieldSupportedValues::hidl_discriminator::flags: {
+            d->type = C2FieldSupportedValues::FLAGS;
+            copyVector<uint64_t>(&d->values, s.flags());
+            break;
+        }
+    default:
+        LOG(WARNING) << "Unrecognized FieldSupportedValues::getDiscriminator()";
+        return false;
+    }
+    return true;
+}
+
+} // unnamed namespace
+
+// C2FieldSupportedValuesQuery -> FieldSupportedValuesQuery
+bool objcpy(
+        FieldSupportedValuesQuery* d,
+        const C2FieldSupportedValuesQuery& s) {
+    if (!objcpy(&d->field, s.field())) {
+        LOG(ERROR) << "Invalid C2FieldSupportedValuesQuery::field.";
+        return false;
+    }
+    switch (s.type()) {
+    case C2FieldSupportedValuesQuery::POSSIBLE:
+        d->type = FieldSupportedValuesQuery::Type::POSSIBLE;
+        break;
+    case C2FieldSupportedValuesQuery::CURRENT:
+        d->type = FieldSupportedValuesQuery::Type::CURRENT;
+        break;
+    default:
+        LOG(DEBUG) << "Unrecognized C2FieldSupportedValuesQuery::type_t "
+                   << "with underlying value " << underlying_value(s.type())
+                   << ".";
+        d->type = static_cast<FieldSupportedValuesQuery::Type>(s.type());
+    }
+    return true;
+}
+
+// FieldSupportedValuesQuery -> C2FieldSupportedValuesQuery
+bool objcpy(
+        C2FieldSupportedValuesQuery* d,
+        const FieldSupportedValuesQuery& s) {
+    C2FieldSupportedValuesQuery::type_t dType;
+    switch (s.type) {
+    case FieldSupportedValuesQuery::Type::POSSIBLE:
+        dType = C2FieldSupportedValuesQuery::POSSIBLE;
+        break;
+    case FieldSupportedValuesQuery::Type::CURRENT:
+        dType = C2FieldSupportedValuesQuery::CURRENT;
+        break;
+    default:
+        LOG(DEBUG) << "Unrecognized FieldSupportedValuesQuery::Type "
+                   << "with underlying value " << underlying_value(s.type)
+                   << ".";
+        dType = static_cast<C2FieldSupportedValuesQuery::type_t>(s.type);
+    }
+    *d = C2FieldSupportedValuesQuery(C2ParamFieldBuilder(s.field), dType);
+    return true;
+}
+
+// C2FieldSupportedValuesQuery -> FieldSupportedValuesQueryResult
+bool objcpy(
+        FieldSupportedValuesQueryResult* d,
+        const C2FieldSupportedValuesQuery& s) {
+    d->status = static_cast<Status>(s.status);
+    return objcpy(&d->values, s.values);
+}
+
+// FieldSupportedValuesQuery, FieldSupportedValuesQueryResult ->
+// C2FieldSupportedValuesQuery
+bool objcpy(
+        C2FieldSupportedValuesQuery* d,
+        const FieldSupportedValuesQuery& sq,
+        const FieldSupportedValuesQueryResult& sr) {
+    if (!objcpy(d, sq)) {
+        LOG(ERROR) << "Invalid FieldSupportedValuesQuery.";
+        return false;
+    }
+    d->status = static_cast<c2_status_t>(sr.status);
+    if (!objcpy(&d->values, sr.values)) {
+        LOG(ERROR) << "Invalid FieldSupportedValuesQueryResult::values.";
+        return false;
+    }
+    return true;
+}
+
+// C2Component::Traits -> IComponentStore::ComponentTraits
+bool objcpy(
+        IComponentStore::ComponentTraits *d,
+        const C2Component::Traits &s) {
+    d->name = s.name;
+
+    switch (s.domain) {
+    case C2Component::DOMAIN_VIDEO:
+        d->domain = IComponentStore::ComponentTraits::Domain::VIDEO;
+        break;
+    case C2Component::DOMAIN_AUDIO:
+        d->domain = IComponentStore::ComponentTraits::Domain::AUDIO;
+        break;
+    case C2Component::DOMAIN_IMAGE:
+        d->domain = IComponentStore::ComponentTraits::Domain::IMAGE;
+        break;
+    case C2Component::DOMAIN_OTHER:
+        d->domain = IComponentStore::ComponentTraits::Domain::OTHER;
+        break;
+    default:
+        LOG(DEBUG) << "Unrecognized C2Component::domain_t "
+                   << "with underlying value " << underlying_value(s.domain)
+                   << ".";
+        d->domain = static_cast<IComponentStore::ComponentTraits::Domain>(
+                s.domain);
+    }
+
+    switch (s.kind) {
+    case C2Component::KIND_DECODER:
+        d->kind = IComponentStore::ComponentTraits::Kind::DECODER;
+        break;
+    case C2Component::KIND_ENCODER:
+        d->kind = IComponentStore::ComponentTraits::Kind::ENCODER;
+        break;
+    case C2Component::KIND_OTHER:
+        d->kind = IComponentStore::ComponentTraits::Kind::OTHER;
+        break;
+    default:
+        LOG(DEBUG) << "Unrecognized C2Component::kind_t "
+                   << "with underlying value " << underlying_value(s.kind)
+                   << ".";
+        d->kind = static_cast<IComponentStore::ComponentTraits::Kind>(
+                s.kind);
+    }
+
+    d->rank = static_cast<uint32_t>(s.rank);
+
+    d->mediaType = s.mediaType;
+
+    d->aliases.resize(s.aliases.size());
+    for (size_t ix = s.aliases.size(); ix > 0; ) {
+        --ix;
+        d->aliases[ix] = s.aliases[ix];
+    }
+    return true;
+}
+
+// ComponentTraits -> C2Component::Traits, std::unique_ptr<std::vector<std::string>>
+bool objcpy(
+        C2Component::Traits* d,
+        const IComponentStore::ComponentTraits& s) {
+    d->name = s.name.c_str();
+
+    switch (s.domain) {
+    case IComponentStore::ComponentTraits::Domain::VIDEO:
+        d->domain = C2Component::DOMAIN_VIDEO;
+        break;
+    case IComponentStore::ComponentTraits::Domain::AUDIO:
+        d->domain = C2Component::DOMAIN_AUDIO;
+        break;
+    case IComponentStore::ComponentTraits::Domain::IMAGE:
+        d->domain = C2Component::DOMAIN_IMAGE;
+        break;
+    case IComponentStore::ComponentTraits::Domain::OTHER:
+        d->domain = C2Component::DOMAIN_OTHER;
+        break;
+    default:
+        LOG(DEBUG) << "Unrecognized ComponentTraits::Domain "
+                   << "with underlying value " << underlying_value(s.domain)
+                   << ".";
+        d->domain = static_cast<C2Component::domain_t>(s.domain);
+    }
+
+    switch (s.kind) {
+    case IComponentStore::ComponentTraits::Kind::DECODER:
+        d->kind = C2Component::KIND_DECODER;
+        break;
+    case IComponentStore::ComponentTraits::Kind::ENCODER:
+        d->kind = C2Component::KIND_ENCODER;
+        break;
+    case IComponentStore::ComponentTraits::Kind::OTHER:
+        d->kind = C2Component::KIND_OTHER;
+        break;
+    default:
+        LOG(DEBUG) << "Unrecognized ComponentTraits::Kind "
+                   << "with underlying value " << underlying_value(s.kind)
+                   << ".";
+        d->kind = static_cast<C2Component::kind_t>(s.kind);
+    }
+
+    d->rank = static_cast<C2Component::rank_t>(s.rank);
+    d->mediaType = s.mediaType.c_str();
+    d->aliases.resize(s.aliases.size());
+    for (size_t i = 0; i < s.aliases.size(); ++i) {
+        d->aliases[i] = s.aliases[i];
+    }
+    return true;
+}
+
+namespace /* unnamed */ {
+
+// C2ParamFieldValues -> ParamFieldValues
+bool objcpy(ParamFieldValues *d, const C2ParamFieldValues &s) {
+    if (!objcpy(&d->paramOrField, s.paramOrField)) {
+        LOG(ERROR) << "Invalid C2ParamFieldValues::paramOrField.";
+        return false;
+    }
+    if (s.values) {
+        d->values.resize(1);
+        if (!objcpy(&d->values[0], *s.values)) {
+            LOG(ERROR) << "Invalid C2ParamFieldValues::values.";
+            return false;
+        }
+        return true;
+    }
+    d->values.resize(0);
+    return true;
+}
+
+// ParamFieldValues -> C2ParamFieldValues
+bool objcpy(C2ParamFieldValues *d, const ParamFieldValues &s) {
+    d->paramOrField = C2ParamFieldBuilder(s.paramOrField);
+    if (s.values.size() == 1) {
+        d->values = std::make_unique<C2FieldSupportedValues>();
+        if (!objcpy(d->values.get(), s.values[0])) {
+            LOG(ERROR) << "Invalid ParamFieldValues::values.";
+            return false;
+        }
+        return true;
+    } else if (s.values.size() == 0) {
+        d->values.reset();
+        return true;
+    }
+    LOG(ERROR) << "Invalid ParamFieldValues: "
+                  "Two or more FieldSupportedValues objects exist in "
+                  "ParamFieldValues. "
+                  "Only zero or one is allowed.";
+    return false;
+}
+
+} // unnamed namespace
+
+// C2SettingResult -> SettingResult
+bool objcpy(SettingResult *d, const C2SettingResult &s) {
+    switch (s.failure) {
+    case C2SettingResult::BAD_TYPE:
+        d->failure = SettingResult::Failure::BAD_TYPE;
+        break;
+    case C2SettingResult::BAD_PORT:
+        d->failure = SettingResult::Failure::BAD_PORT;
+        break;
+    case C2SettingResult::BAD_INDEX:
+        d->failure = SettingResult::Failure::BAD_INDEX;
+        break;
+    case C2SettingResult::READ_ONLY:
+        d->failure = SettingResult::Failure::READ_ONLY;
+        break;
+    case C2SettingResult::MISMATCH:
+        d->failure = SettingResult::Failure::MISMATCH;
+        break;
+    case C2SettingResult::BAD_VALUE:
+        d->failure = SettingResult::Failure::BAD_VALUE;
+        break;
+    case C2SettingResult::CONFLICT:
+        d->failure = SettingResult::Failure::CONFLICT;
+        break;
+    case C2SettingResult::UNSUPPORTED:
+        d->failure = SettingResult::Failure::UNSUPPORTED;
+        break;
+    case C2SettingResult::INFO_BAD_VALUE:
+        d->failure = SettingResult::Failure::INFO_BAD_VALUE;
+        break;
+    case C2SettingResult::INFO_CONFLICT:
+        d->failure = SettingResult::Failure::INFO_CONFLICT;
+        break;
+    default:
+        LOG(DEBUG) << "Unrecognized C2SettingResult::Failure "
+                   << "with underlying value " << underlying_value(s.failure)
+                   << ".";
+        d->failure = static_cast<SettingResult::Failure>(s.failure);
+    }
+    if (!objcpy(&d->field, s.field)) {
+        LOG(ERROR) << "Invalid C2SettingResult::field.";
+        return false;
+    }
+    d->conflicts.resize(s.conflicts.size());
+    size_t i = 0;
+    for (const C2ParamFieldValues& sConflict : s.conflicts) {
+        ParamFieldValues &dConflict = d->conflicts[i++];
+        if (!objcpy(&dConflict, sConflict)) {
+            LOG(ERROR) << "Invalid C2SettingResult::conflicts["
+                       << i - 1 << "].";
+            return false;
+        }
+    }
+    return true;
+}
+
+// SettingResult -> std::unique_ptr<C2SettingResult>
+bool objcpy(std::unique_ptr<C2SettingResult> *d, const SettingResult &s) {
+    *d = std::unique_ptr<C2SettingResult>(new C2SettingResult {
+            .field = C2ParamFieldValues(C2ParamFieldBuilder()) });
+    if (!*d) {
+        LOG(ERROR) << "No memory for C2SettingResult.";
+        return false;
+    }
+
+    // failure
+    switch (s.failure) {
+    case SettingResult::Failure::BAD_TYPE:
+        (*d)->failure = C2SettingResult::BAD_TYPE;
+        break;
+    case SettingResult::Failure::BAD_PORT:
+        (*d)->failure = C2SettingResult::BAD_PORT;
+        break;
+    case SettingResult::Failure::BAD_INDEX:
+        (*d)->failure = C2SettingResult::BAD_INDEX;
+        break;
+    case SettingResult::Failure::READ_ONLY:
+        (*d)->failure = C2SettingResult::READ_ONLY;
+        break;
+    case SettingResult::Failure::MISMATCH:
+        (*d)->failure = C2SettingResult::MISMATCH;
+        break;
+    case SettingResult::Failure::BAD_VALUE:
+        (*d)->failure = C2SettingResult::BAD_VALUE;
+        break;
+    case SettingResult::Failure::CONFLICT:
+        (*d)->failure = C2SettingResult::CONFLICT;
+        break;
+    case SettingResult::Failure::UNSUPPORTED:
+        (*d)->failure = C2SettingResult::UNSUPPORTED;
+        break;
+    case SettingResult::Failure::INFO_BAD_VALUE:
+        (*d)->failure = C2SettingResult::INFO_BAD_VALUE;
+        break;
+    case SettingResult::Failure::INFO_CONFLICT:
+        (*d)->failure = C2SettingResult::INFO_CONFLICT;
+        break;
+    default:
+        LOG(DEBUG) << "Unrecognized SettingResult::Failure "
+                   << "with underlying value " << underlying_value(s.failure)
+                   << ".";
+        (*d)->failure = static_cast<C2SettingResult::Failure>(s.failure);
+    }
+
+    // field
+    if (!objcpy(&(*d)->field, s.field)) {
+        LOG(ERROR) << "Invalid SettingResult::field.";
+        return false;
+    }
+
+    // conflicts
+    (*d)->conflicts.clear();
+    (*d)->conflicts.reserve(s.conflicts.size());
+    for (const ParamFieldValues& sConflict : s.conflicts) {
+        (*d)->conflicts.emplace_back(
+                C2ParamFieldValues{ C2ParamFieldBuilder(), nullptr });
+        if (!objcpy(&(*d)->conflicts.back(), sConflict)) {
+            LOG(ERROR) << "Invalid SettingResult::conflicts.";
+            return false;
+        }
+    }
+    return true;
+}
+
+// C2ParamDescriptor -> ParamDescriptor
+bool objcpy(ParamDescriptor *d, const C2ParamDescriptor &s) {
+    d->index = static_cast<ParamIndex>(s.index());
+    d->attrib = static_cast<hidl_bitfield<ParamDescriptor::Attrib>>(
+            _C2ParamInspector::GetAttrib(s));
+    d->name = s.name();
+    copyVector<uint32_t>(&d->dependencies, s.dependencies());
+    return true;
+}
+
+// ParamDescriptor -> C2ParamDescriptor
+bool objcpy(std::shared_ptr<C2ParamDescriptor> *d, const ParamDescriptor &s) {
+    std::vector<C2Param::Index> dDependencies;
+    dDependencies.reserve(s.dependencies.size());
+    for (const ParamIndex& sDependency : s.dependencies) {
+        dDependencies.emplace_back(static_cast<uint32_t>(sDependency));
+    }
+    *d = std::make_shared<C2ParamDescriptor>(
+            C2Param::Index(static_cast<uint32_t>(s.index)),
+            static_cast<C2ParamDescriptor::attrib_t>(s.attrib),
+            C2String(s.name.c_str()),
+            std::move(dDependencies));
+    return true;
+}
+
+// C2StructDescriptor -> StructDescriptor
+bool objcpy(StructDescriptor *d, const C2StructDescriptor &s) {
+    d->type = static_cast<ParamIndex>(s.coreIndex().coreIndex());
+    d->fields.resize(s.numFields());
+    size_t i = 0;
+    for (const auto& sField : s) {
+        FieldDescriptor& dField = d->fields[i++];
+        dField.fieldId.offset = static_cast<uint32_t>(
+                _C2ParamInspector::GetOffset(sField));
+        dField.fieldId.size = static_cast<uint32_t>(
+                _C2ParamInspector::GetSize(sField));
+        dField.type = static_cast<hidl_bitfield<FieldDescriptor::Type>>(
+                sField.type());
+        dField.extent = static_cast<uint32_t>(sField.extent());
+        dField.name = static_cast<hidl_string>(sField.name());
+        const auto& sNamedValues = sField.namedValues();
+        dField.namedValues.resize(sNamedValues.size());
+        size_t j = 0;
+        for (const auto& sNamedValue : sNamedValues) {
+            FieldDescriptor::NamedValue& dNamedValue = dField.namedValues[j++];
+            dNamedValue.name = static_cast<hidl_string>(sNamedValue.first);
+            dNamedValue.value = static_cast<PrimitiveValue>(
+                    sNamedValue.second.u64);
+        }
+    }
+    return true;
+}
+
+// StructDescriptor -> C2StructDescriptor
+bool objcpy(std::unique_ptr<C2StructDescriptor> *d, const StructDescriptor &s) {
+    C2Param::CoreIndex dIndex = C2Param::CoreIndex(static_cast<uint32_t>(s.type));
+    std::vector<C2FieldDescriptor> dFields;
+    dFields.reserve(s.fields.size());
+    for (const auto &sField : s.fields) {
+        C2FieldDescriptor dField = {
+            static_cast<uint32_t>(sField.type),
+            sField.extent,
+            sField.name,
+            sField.fieldId.offset,
+            sField.fieldId.size };
+        C2FieldDescriptor::NamedValuesType namedValues;
+        namedValues.reserve(sField.namedValues.size());
+        for (const auto& sNamedValue : sField.namedValues) {
+            namedValues.emplace_back(
+                sNamedValue.name,
+                C2Value::Primitive(static_cast<uint64_t>(sNamedValue.value)));
+        }
+        _C2ParamInspector::AddNamedValues(dField, std::move(namedValues));
+        dFields.emplace_back(dField);
+    }
+    *d = std::make_unique<C2StructDescriptor>(
+            _C2ParamInspector::CreateStructDescriptor(dIndex, std::move(dFields)));
+    return true;
+}
+
+namespace /* unnamed */ {
+
+// Find or add a hidl BaseBlock object from a given C2Handle* to a list and an
+// associated map.
+// Note: The handle is not cloned.
+bool _addBaseBlock(
+        uint32_t* index,
+        const C2Handle* handle,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    if (!handle) {
+        LOG(ERROR) << "addBaseBlock called on a null C2Handle.";
+        return false;
+    }
+    auto it = baseBlockIndices->find(handle);
+    if (it != baseBlockIndices->end()) {
+        *index = it->second;
+    } else {
+        *index = baseBlocks->size();
+        baseBlockIndices->emplace(handle, *index);
+        baseBlocks->emplace_back();
+
+        BaseBlock &dBaseBlock = baseBlocks->back();
+        // This does not clone the handle.
+        dBaseBlock.nativeBlock(
+                reinterpret_cast<const native_handle_t*>(handle));
+
+    }
+    return true;
+}
+
+// Find or add a hidl BaseBlock object from a given BufferPoolData to a list and
+// an associated map.
+bool _addBaseBlock(
+        uint32_t* index,
+        const std::shared_ptr<BufferPoolData> bpData,
+        BufferPoolSender* bufferPoolSender,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    if (!bpData) {
+        LOG(ERROR) << "addBaseBlock called on a null BufferPoolData.";
+        return false;
+    }
+    auto it = baseBlockIndices->find(bpData.get());
+    if (it != baseBlockIndices->end()) {
+        *index = it->second;
+    } else {
+        *index = baseBlocks->size();
+        baseBlockIndices->emplace(bpData.get(), *index);
+        baseBlocks->emplace_back();
+
+        BaseBlock &dBaseBlock = baseBlocks->back();
+
+        if (bufferPoolSender) {
+            BufferStatusMessage pooledBlock;
+            ResultStatus bpStatus = bufferPoolSender->send(
+                    bpData,
+                    &pooledBlock);
+
+            if (bpStatus != ResultStatus::OK) {
+                LOG(ERROR) << "Failed to send buffer with BufferPool. Error: "
+                           << static_cast<int32_t>(bpStatus)
+                           << ".";
+                return false;
+            }
+            dBaseBlock.pooledBlock(pooledBlock);
+        }
+    }
+    return true;
+}
+
+bool addBaseBlock(
+        uint32_t* index,
+        const C2Handle* handle,
+        const std::shared_ptr<const _C2BlockPoolData>& blockPoolData,
+        BufferPoolSender* bufferPoolSender,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    if (!blockPoolData) {
+        // No BufferPoolData ==> NATIVE block.
+        return _addBaseBlock(
+                index, handle,
+                baseBlocks, baseBlockIndices);
+    }
+    switch (blockPoolData->getType()) {
+    case _C2BlockPoolData::TYPE_BUFFERPOOL: {
+            // BufferPoolData
+            std::shared_ptr<BufferPoolData> bpData;
+            if (!_C2BlockFactory::GetBufferPoolData(blockPoolData, &bpData)
+                    || !bpData) {
+                LOG(ERROR) << "BufferPoolData unavailable in a block.";
+                return false;
+            }
+            return _addBaseBlock(
+                    index, bpData,
+                    bufferPoolSender, baseBlocks, baseBlockIndices);
+        }
+    case _C2BlockPoolData::TYPE_BUFFERQUEUE:
+        uint32_t gen;
+        uint64_t bqId;
+        int32_t bqSlot;
+        // Update handle if migration happened.
+        if (_C2BlockFactory::GetBufferQueueData(
+                blockPoolData, &gen, &bqId, &bqSlot)) {
+            android::MigrateNativeCodec2GrallocHandle(
+                    const_cast<native_handle_t*>(handle), gen, bqId, bqSlot);
+        }
+        return _addBaseBlock(
+                index, handle,
+                baseBlocks, baseBlockIndices);
+    default:
+        LOG(ERROR) << "Unknown C2BlockPoolData type.";
+        return false;
+    }
+}
+
+// C2Fence -> hidl_handle
+// Note: File descriptors are not duplicated. The original file descriptor must
+// not be closed before the transaction is complete.
+bool objcpy(hidl_handle* d, const C2Fence& s) {
+    (void)s; // TODO: implement s.fd()
+    int fenceFd = -1;
+    d->setTo(nullptr);
+    if (fenceFd >= 0) {
+        native_handle_t *handle = native_handle_create(1, 0);
+        if (!handle) {
+            LOG(ERROR) << "Failed to create a native handle.";
+            return false;
+        }
+        handle->data[0] = fenceFd;
+        d->setTo(handle, true /* owns */);
+    }
+    return true;
+}
+
+// C2ConstLinearBlock -> Block
+// Note: Native handles are not duplicated. The original handles must not be
+// closed before the transaction is complete.
+bool objcpy(Block* d, const C2ConstLinearBlock& s,
+        BufferPoolSender* bufferPoolSender,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    std::shared_ptr<const _C2BlockPoolData> bpData =
+            _C2BlockFactory::GetLinearBlockPoolData(s);
+    if (!addBaseBlock(&d->index, s.handle(), bpData,
+            bufferPoolSender, baseBlocks, baseBlockIndices)) {
+        LOG(ERROR) << "Invalid block data in C2ConstLinearBlock.";
+        return false;
+    }
+
+    // Create the metadata.
+    C2Hidl_RangeInfo dRangeInfo;
+    dRangeInfo.offset = static_cast<uint32_t>(s.offset());
+    dRangeInfo.length = static_cast<uint32_t>(s.size());
+    if (!createParamsBlob(&d->meta, std::vector<C2Param*>{ &dRangeInfo })) {
+        LOG(ERROR) << "Invalid range info in C2ConstLinearBlock.";
+        return false;
+    }
+
+    // Copy the fence
+    if (!objcpy(&d->fence, s.fence())) {
+        LOG(ERROR) << "Invalid C2ConstLinearBlock::fence.";
+        return false;
+    }
+    return true;
+}
+
+// C2ConstGraphicBlock -> Block
+// Note: Native handles are not duplicated. The original handles must not be
+// closed before the transaction is complete.
+bool objcpy(Block* d, const C2ConstGraphicBlock& s,
+        BufferPoolSender* bufferPoolSender,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    std::shared_ptr<const _C2BlockPoolData> bpData =
+            _C2BlockFactory::GetGraphicBlockPoolData(s);
+    if (!addBaseBlock(&d->index, s.handle(), bpData,
+            bufferPoolSender, baseBlocks, baseBlockIndices)) {
+        LOG(ERROR) << "Invalid block data in C2ConstGraphicBlock.";
+        return false;
+    }
+
+    // Create the metadata.
+    C2Hidl_RectInfo dRectInfo;
+    C2Rect sRect = s.crop();
+    dRectInfo.left = static_cast<uint32_t>(sRect.left);
+    dRectInfo.top = static_cast<uint32_t>(sRect.top);
+    dRectInfo.width = static_cast<uint32_t>(sRect.width);
+    dRectInfo.height = static_cast<uint32_t>(sRect.height);
+    if (!createParamsBlob(&d->meta, std::vector<C2Param*>{ &dRectInfo })) {
+        LOG(ERROR) << "Invalid rect info in C2ConstGraphicBlock.";
+        return false;
+    }
+
+    // Copy the fence
+    if (!objcpy(&d->fence, s.fence())) {
+        LOG(ERROR) << "Invalid C2ConstGraphicBlock::fence.";
+        return false;
+    }
+    return true;
+}
+
+// C2BufferData -> Buffer
+// This function only fills in d->blocks.
+bool objcpy(Buffer* d, const C2BufferData& s,
+        BufferPoolSender* bufferPoolSender,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    d->blocks.resize(
+            s.linearBlocks().size() +
+            s.graphicBlocks().size());
+    size_t i = 0;
+    for (const C2ConstLinearBlock& linearBlock : s.linearBlocks()) {
+        Block& dBlock = d->blocks[i++];
+        if (!objcpy(
+                &dBlock, linearBlock,
+                bufferPoolSender, baseBlocks, baseBlockIndices)) {
+            LOG(ERROR) << "Invalid C2BufferData::linearBlocks. "
+                       << "(Destination index = " << i - 1 << ".)";
+            return false;
+        }
+    }
+    for (const C2ConstGraphicBlock& graphicBlock : s.graphicBlocks()) {
+        Block& dBlock = d->blocks[i++];
+        if (!objcpy(
+                &dBlock, graphicBlock,
+                bufferPoolSender, baseBlocks, baseBlockIndices)) {
+            LOG(ERROR) << "Invalid C2BufferData::graphicBlocks. "
+                       << "(Destination index = " << i - 1 << ".)";
+            return false;
+        }
+    }
+    return true;
+}
+
+// C2Buffer -> Buffer
+bool objcpy(Buffer* d, const C2Buffer& s,
+        BufferPoolSender* bufferPoolSender,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    if (!createParamsBlob(&d->info, s.info())) {
+        LOG(ERROR) << "Invalid C2Buffer::info.";
+        return false;
+    }
+    if (!objcpy(d, s.data(), bufferPoolSender, baseBlocks, baseBlockIndices)) {
+        LOG(ERROR) << "Invalid C2Buffer::data.";
+        return false;
+    }
+    return true;
+}
+
+// C2InfoBuffer -> InfoBuffer
+bool objcpy(InfoBuffer* d, const C2InfoBuffer& s,
+        BufferPoolSender* bufferPoolSender,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    // TODO: C2InfoBuffer is not implemented.
+    (void)d;
+    (void)s;
+    (void)bufferPoolSender;
+    (void)baseBlocks;
+    (void)baseBlockIndices;
+    LOG(INFO) << "InfoBuffer not implemented.";
+    return true;
+}
+
+// C2FrameData -> FrameData
+bool objcpy(FrameData* d, const C2FrameData& s,
+        BufferPoolSender* bufferPoolSender,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    d->flags = static_cast<hidl_bitfield<FrameData::Flags>>(s.flags);
+    if (!objcpy(&d->ordinal, s.ordinal)) {
+        LOG(ERROR) << "Invalid C2FrameData::ordinal.";
+        return false;
+    }
+
+    d->buffers.resize(s.buffers.size());
+    size_t i = 0;
+    for (const std::shared_ptr<C2Buffer>& sBuffer : s.buffers) {
+        Buffer& dBuffer = d->buffers[i++];
+        if (!sBuffer) {
+            // A null (pointer to) C2Buffer corresponds to a Buffer with empty
+            // info and blocks.
+            dBuffer.info.resize(0);
+            dBuffer.blocks.resize(0);
+            continue;
+        }
+        if (!objcpy(
+                &dBuffer, *sBuffer,
+                bufferPoolSender, baseBlocks, baseBlockIndices)) {
+            LOG(ERROR) << "Invalid C2FrameData::buffers["
+                       << i - 1 << "].";
+            return false;
+        }
+    }
+
+    if (!createParamsBlob(&d->configUpdate, s.configUpdate)) {
+        LOG(ERROR) << "Invalid C2FrameData::configUpdate.";
+        return false;
+    }
+
+    d->infoBuffers.resize(s.infoBuffers.size());
+    i = 0;
+    for (const std::shared_ptr<C2InfoBuffer>& sInfoBuffer : s.infoBuffers) {
+        InfoBuffer& dInfoBuffer = d->infoBuffers[i++];
+        if (!sInfoBuffer) {
+            LOG(ERROR) << "Null C2FrameData::infoBuffers["
+                       << i - 1 << "].";
+            return false;
+        }
+        if (!objcpy(&dInfoBuffer, *sInfoBuffer,
+                bufferPoolSender, baseBlocks, baseBlockIndices)) {
+            LOG(ERROR) << "Invalid C2FrameData::infoBuffers["
+                       << i - 1 << "].";
+            return false;
+        }
+    }
+
+    return true;
+}
+
+} // unnamed namespace
+
+// DefaultBufferPoolSender's implementation
+
+DefaultBufferPoolSender::DefaultBufferPoolSender(
+        const sp<IClientManager>& receiverManager,
+        std::chrono::steady_clock::duration refreshInterval)
+    : mReceiverManager(receiverManager),
+      mSourceConnectionId(0),
+      mLastSent(std::chrono::steady_clock::now()),
+      mRefreshInterval(refreshInterval) {
+}
+
+void DefaultBufferPoolSender::setReceiver(
+        const sp<IClientManager>& receiverManager,
+        std::chrono::steady_clock::duration refreshInterval) {
+    std::lock_guard<std::mutex> lock(mMutex);
+    if (mReceiverManager != receiverManager) {
+        mReceiverManager = receiverManager;
+    }
+    mRefreshInterval = refreshInterval;
+}
+
+ResultStatus DefaultBufferPoolSender::send(
+        const std::shared_ptr<BufferPoolData>& bpData,
+        BufferStatusMessage* bpMessage) {
+    if (!mReceiverManager) {
+        LOG(ERROR) << "No access to receiver's BufferPool.";
+        return ResultStatus::NOT_FOUND;
+    }
+    ResultStatus rs;
+    std::lock_guard<std::mutex> lock(mMutex);
+    if (!mSenderManager) {
+        mSenderManager = ClientManager::getInstance();
+        if (!mSenderManager) {
+            LOG(ERROR) << "Failed to retrieve local BufferPool ClientManager.";
+            return ResultStatus::CRITICAL_ERROR;
+        }
+    }
+    int64_t connectionId = bpData->mConnectionId;
+    std::chrono::steady_clock::time_point now =
+            std::chrono::steady_clock::now();
+    std::chrono::steady_clock::duration interval = now - mLastSent;
+    if (mSourceConnectionId == 0 ||
+            mSourceConnectionId != connectionId ||
+            interval > mRefreshInterval) {
+        // Initialize the bufferpool connection.
+        mSourceConnectionId = connectionId;
+        if (mSourceConnectionId == 0) {
+            return ResultStatus::CRITICAL_ERROR;
+        }
+
+        int64_t receiverConnectionId;
+        rs = mSenderManager->registerSender(mReceiverManager,
+                                            connectionId,
+                                            &receiverConnectionId);
+        if ((rs != ResultStatus::OK) && (rs != ResultStatus::ALREADY_EXISTS)) {
+            LOG(WARNING) << "registerSender -- returned error: "
+                         << static_cast<int32_t>(rs)
+                         << ".";
+            return rs;
+        } else {
+            mReceiverConnectionId = receiverConnectionId;
+        }
+    }
+
+    uint64_t transactionId;
+    int64_t timestampUs;
+    rs = mSenderManager->postSend(
+            mReceiverConnectionId, bpData, &transactionId, &timestampUs);
+    if (rs != ResultStatus::OK) {
+        LOG(ERROR) << "ClientManager::postSend -- returned error: "
+                   << static_cast<int32_t>(rs)
+                   << ".";
+        return rs;
+    }
+    if (!bpMessage) {
+        LOG(ERROR) << "Null output parameter for BufferStatusMessage.";
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    bpMessage->connectionId = mReceiverConnectionId;
+    bpMessage->bufferId = bpData->mId;
+    bpMessage->transactionId = transactionId;
+    bpMessage->timestampUs = timestampUs;
+    mLastSent = now;
+    return rs;
+}
+
+// std::list<std::unique_ptr<C2Work>> -> WorkBundle
+bool objcpy(
+        WorkBundle* d,
+        const std::list<std::unique_ptr<C2Work>>& s,
+        BufferPoolSender* bufferPoolSender) {
+    // baseBlocks holds a list of BaseBlock objects that Blocks can refer to.
+    std::list<BaseBlock> baseBlocks;
+
+    // baseBlockIndices maps a raw pointer to native_handle_t or BufferPoolData
+    // inside baseBlocks to the corresponding index into baseBlocks. The keys
+    // (pointers) are used to identify blocks that have the same "base block" in
+    // s, a list of C2Work objects. Because baseBlocks will be copied into a
+    // hidl_vec eventually, the values of baseBlockIndices are zero-based
+    // integer indices instead of list iterators.
+    //
+    // Note that the pointers can be raw because baseBlockIndices has a shorter
+    // lifespan than all of base blocks.
+    std::map<const void*, uint32_t> baseBlockIndices;
+
+    d->works.resize(s.size());
+    size_t i = 0;
+    for (const std::unique_ptr<C2Work>& sWork : s) {
+        Work &dWork = d->works[i++];
+        if (!sWork) {
+            LOG(WARNING) << "Null C2Work encountered.";
+            continue;
+        }
+
+        // chain info is not in use currently.
+
+        // input
+        if (!objcpy(&dWork.input, sWork->input,
+                bufferPoolSender, &baseBlocks, &baseBlockIndices)) {
+            LOG(ERROR) << "Invalid C2Work::input.";
+            return false;
+        }
+
+        // worklets
+        if (sWork->worklets.size() == 0) {
+            LOG(DEBUG) << "Work with no worklets.";
+        } else {
+            // Parcel the worklets.
+            hidl_vec<Worklet> &dWorklets = dWork.worklets;
+            dWorklets.resize(sWork->worklets.size());
+            size_t j = 0;
+            for (const std::unique_ptr<C2Worklet>& sWorklet : sWork->worklets)
+            {
+                if (!sWorklet) {
+                    LOG(WARNING) << "Null C2Work::worklets["
+                                 << j << "].";
+                    continue;
+                }
+                Worklet &dWorklet = dWorklets[j++];
+
+                // component id
+                dWorklet.componentId = static_cast<uint32_t>(
+                        sWorklet->component);
+
+                // tunings
+                if (!createParamsBlob(&dWorklet.tunings, sWorklet->tunings)) {
+                    LOG(ERROR) << "Invalid C2Work::worklets["
+                               << j - 1 << "]->tunings.";
+                    return false;
+                }
+
+                // failures
+                dWorklet.failures.resize(sWorklet->failures.size());
+                size_t k = 0;
+                for (const std::unique_ptr<C2SettingResult>& sFailure :
+                        sWorklet->failures) {
+                    if (!sFailure) {
+                        LOG(WARNING) << "Null C2Work::worklets["
+                                     << j - 1 << "]->failures["
+                                     << k << "].";
+                        continue;
+                    }
+                    if (!objcpy(&dWorklet.failures[k++], *sFailure)) {
+                        LOG(ERROR) << "Invalid C2Work::worklets["
+                                   << j - 1 << "]->failures["
+                                   << k - 1 << "].";
+                        return false;
+                    }
+                }
+
+                // output
+                if (!objcpy(&dWorklet.output, sWorklet->output,
+                        bufferPoolSender, &baseBlocks, &baseBlockIndices)) {
+                    LOG(ERROR) << "Invalid C2Work::worklets["
+                               << j - 1 << "]->output.";
+                    return false;
+                }
+            }
+        }
+
+        // worklets processed
+        dWork.workletsProcessed = sWork->workletsProcessed;
+
+        // result
+        dWork.result = static_cast<Status>(sWork->result);
+    }
+
+    // Copy std::list<BaseBlock> to hidl_vec<BaseBlock>.
+    {
+        d->baseBlocks.resize(baseBlocks.size());
+        size_t i = 0;
+        for (const BaseBlock& baseBlock : baseBlocks) {
+            d->baseBlocks[i++] = baseBlock;
+        }
+    }
+
+    return true;
+}
+
+namespace /* unnamed */ {
+
+struct C2BaseBlock {
+    enum type_t {
+        LINEAR,
+        GRAPHIC,
+    };
+    type_t type;
+    std::shared_ptr<C2LinearBlock> linear;
+    std::shared_ptr<C2GraphicBlock> graphic;
+};
+
+// hidl_handle -> C2Fence
+// Note: File descriptors are not duplicated. The original file descriptor must
+// not be closed before the transaction is complete.
+bool objcpy(C2Fence* d, const hidl_handle& s) {
+    // TODO: Implement.
+    (void)s;
+    *d = C2Fence();
+    return true;
+}
+
+// C2LinearBlock, vector<C2Param*>, C2Fence -> C2Buffer
+bool createLinearBuffer(
+        std::shared_ptr<C2Buffer>* buffer,
+        const std::shared_ptr<C2LinearBlock>& block,
+        const std::vector<C2Param*>& meta,
+        const C2Fence& fence) {
+    // Check the block meta. It should have exactly 1 C2Info:
+    // C2Hidl_RangeInfo.
+    if ((meta.size() != 1) || !meta[0]) {
+        LOG(ERROR) << "Invalid C2LinearBlock::meta.";
+        return false;
+    }
+    if (meta[0]->size() != sizeof(C2Hidl_RangeInfo)) {
+        LOG(ERROR) << "Invalid range info in C2LinearBlock.";
+        return false;
+    }
+    C2Hidl_RangeInfo *rangeInfo =
+            reinterpret_cast<C2Hidl_RangeInfo*>(meta[0]);
+
+    // Create C2Buffer from C2LinearBlock.
+    *buffer = C2Buffer::CreateLinearBuffer(block->share(
+            rangeInfo->offset, rangeInfo->length,
+            fence));
+    if (!(*buffer)) {
+        LOG(ERROR) << "CreateLinearBuffer failed.";
+        return false;
+    }
+    return true;
+}
+
+// C2GraphicBlock, vector<C2Param*>, C2Fence -> C2Buffer
+bool createGraphicBuffer(
+        std::shared_ptr<C2Buffer>* buffer,
+        const std::shared_ptr<C2GraphicBlock>& block,
+        const std::vector<C2Param*>& meta,
+        const C2Fence& fence) {
+    // Check the block meta. It should have exactly 1 C2Info:
+    // C2Hidl_RectInfo.
+    if ((meta.size() != 1) || !meta[0]) {
+        LOG(ERROR) << "Invalid C2GraphicBlock::meta.";
+        return false;
+    }
+    if (meta[0]->size() != sizeof(C2Hidl_RectInfo)) {
+        LOG(ERROR) << "Invalid rect info in C2GraphicBlock.";
+        return false;
+    }
+    C2Hidl_RectInfo *rectInfo =
+            reinterpret_cast<C2Hidl_RectInfo*>(meta[0]);
+
+    // Create C2Buffer from C2GraphicBlock.
+    *buffer = C2Buffer::CreateGraphicBuffer(block->share(
+            C2Rect(rectInfo->width, rectInfo->height).
+            at(rectInfo->left, rectInfo->top),
+            fence));
+    if (!(*buffer)) {
+        LOG(ERROR) << "CreateGraphicBuffer failed.";
+        return false;
+    }
+    return true;
+}
+
+// Buffer -> C2Buffer
+// Note: The native handles will be cloned.
+bool objcpy(std::shared_ptr<C2Buffer>* d, const Buffer& s,
+        const std::vector<C2BaseBlock>& baseBlocks) {
+    *d = nullptr;
+
+    // Currently, a non-null C2Buffer must contain exactly 1 block.
+    if (s.blocks.size() == 0) {
+        return true;
+    } else if (s.blocks.size() != 1) {
+        LOG(ERROR) << "Invalid Buffer: "
+                      "Currently, a C2Buffer must contain exactly 1 block.";
+        return false;
+    }
+
+    const Block &sBlock = s.blocks[0];
+    if (sBlock.index >= baseBlocks.size()) {
+        LOG(ERROR) << "Invalid Buffer::blocks[0].index: "
+                      "Array index out of range.";
+        return false;
+    }
+    const C2BaseBlock &baseBlock = baseBlocks[sBlock.index];
+
+    // Parse meta.
+    std::vector<C2Param*> sBlockMeta;
+    if (!parseParamsBlob(&sBlockMeta, sBlock.meta)) {
+        LOG(ERROR) << "Invalid Buffer::blocks[0].meta.";
+        return false;
+    }
+
+    // Copy fence.
+    C2Fence dFence;
+    if (!objcpy(&dFence, sBlock.fence)) {
+        LOG(ERROR) << "Invalid Buffer::blocks[0].fence.";
+        return false;
+    }
+
+    // Construct a block.
+    switch (baseBlock.type) {
+    case C2BaseBlock::LINEAR:
+        if (!createLinearBuffer(d, baseBlock.linear, sBlockMeta, dFence)) {
+            LOG(ERROR) << "Invalid C2BaseBlock::linear.";
+            return false;
+        }
+        break;
+    case C2BaseBlock::GRAPHIC:
+        if (!createGraphicBuffer(d, baseBlock.graphic, sBlockMeta, dFence)) {
+            LOG(ERROR) << "Invalid C2BaseBlock::graphic.";
+            return false;
+        }
+        break;
+    default:
+        LOG(ERROR) << "Invalid C2BaseBlock::type.";
+        return false;
+    }
+
+    // Parse info
+    std::vector<C2Param*> params;
+    if (!parseParamsBlob(&params, s.info)) {
+        LOG(ERROR) << "Invalid Buffer::info.";
+        return false;
+    }
+    for (C2Param* param : params) {
+        if (param == nullptr) {
+            LOG(ERROR) << "Null param in Buffer::info.";
+            return false;
+        }
+        std::shared_ptr<C2Param> c2param{
+                C2Param::Copy(*param).release()};
+        if (!c2param) {
+            LOG(ERROR) << "Invalid param in Buffer::info.";
+            return false;
+        }
+        c2_status_t status =
+                (*d)->setInfo(std::static_pointer_cast<C2Info>(c2param));
+        if (status != C2_OK) {
+            LOG(ERROR) << "C2Buffer::setInfo failed.";
+            return false;
+        }
+    }
+
+    return true;
+}
+
+// FrameData -> C2FrameData
+bool objcpy(C2FrameData* d, const FrameData& s,
+        const std::vector<C2BaseBlock>& baseBlocks) {
+    d->flags = static_cast<C2FrameData::flags_t>(s.flags);
+    if (!objcpy(&d->ordinal, s.ordinal)) {
+        LOG(ERROR) << "Invalid FrameData::ordinal.";
+        return false;
+    }
+    d->buffers.clear();
+    d->buffers.reserve(s.buffers.size());
+    for (const Buffer& sBuffer : s.buffers) {
+        std::shared_ptr<C2Buffer> dBuffer;
+        if (!objcpy(&dBuffer, sBuffer, baseBlocks)) {
+            LOG(ERROR) << "Invalid FrameData::buffers.";
+            return false;
+        }
+        d->buffers.emplace_back(dBuffer);
+    }
+
+    std::vector<C2Param*> params;
+    if (!parseParamsBlob(&params, s.configUpdate)) {
+        LOG(ERROR) << "Invalid FrameData::configUpdate.";
+        return false;
+    }
+    d->configUpdate.clear();
+    for (C2Param* param : params) {
+        d->configUpdate.emplace_back(C2Param::Copy(*param));
+        if (!d->configUpdate.back()) {
+            LOG(ERROR) << "Unexpected error while parsing "
+                          "FrameData::configUpdate.";
+            return false;
+        }
+    }
+
+    // TODO: Implement this once C2InfoBuffer has constructors.
+    d->infoBuffers.clear();
+    return true;
+}
+
+// BaseBlock -> C2BaseBlock
+bool objcpy(C2BaseBlock* d, const BaseBlock& s) {
+    switch (s.getDiscriminator()) {
+    case BaseBlock::hidl_discriminator::nativeBlock: {
+            native_handle_t* sHandle =
+                    native_handle_clone(s.nativeBlock());
+            if (sHandle == nullptr) {
+                LOG(ERROR) << "Null BaseBlock::nativeBlock.";
+                return false;
+            }
+            const C2Handle *sC2Handle =
+                    reinterpret_cast<const C2Handle*>(sHandle);
+
+            d->linear = _C2BlockFactory::CreateLinearBlock(sC2Handle);
+            if (d->linear) {
+                d->type = C2BaseBlock::LINEAR;
+                return true;
+            }
+
+            d->graphic = _C2BlockFactory::CreateGraphicBlock(sC2Handle);
+            if (d->graphic) {
+                d->type = C2BaseBlock::GRAPHIC;
+                return true;
+            }
+
+            LOG(ERROR) << "Unknown handle type in BaseBlock::nativeBlock.";
+            if (sHandle) {
+                native_handle_close(sHandle);
+                native_handle_delete(sHandle);
+            }
+            return false;
+        }
+    case BaseBlock::hidl_discriminator::pooledBlock: {
+            const BufferStatusMessage &bpMessage =
+                    s.pooledBlock();
+            sp<ClientManager> bp = ClientManager::getInstance();
+            std::shared_ptr<BufferPoolData> bpData;
+            native_handle_t *cHandle;
+            ResultStatus bpStatus = bp->receive(
+                    bpMessage.connectionId,
+                    bpMessage.transactionId,
+                    bpMessage.bufferId,
+                    bpMessage.timestampUs,
+                    &cHandle,
+                    &bpData);
+            if (bpStatus != ResultStatus::OK) {
+                LOG(ERROR) << "Failed to receive buffer from bufferpool -- "
+                           << "resultStatus = " << underlying_value(bpStatus)
+                           << ".";
+                return false;
+            } else if (!bpData) {
+                LOG(ERROR) << "No data in bufferpool transaction.";
+                return false;
+            }
+
+            d->linear = _C2BlockFactory::CreateLinearBlock(cHandle, bpData);
+            if (d->linear) {
+                d->type = C2BaseBlock::LINEAR;
+                return true;
+            }
+
+            d->graphic = _C2BlockFactory::CreateGraphicBlock(cHandle, bpData);
+            if (d->graphic) {
+                d->type = C2BaseBlock::GRAPHIC;
+                return true;
+            }
+
+            LOG(ERROR) << "Unknown handle type in BaseBlock::pooledBlock.";
+            return false;
+        }
+    default:
+        LOG(ERROR) << "Unrecognized BaseBlock's discriminator with "
+                   << "underlying value "
+                   << underlying_value(s.getDiscriminator()) << ".";
+        return false;
+    }
+}
+
+} // unnamed namespace
+
+// WorkBundle -> std::list<std::unique_ptr<C2Work>>
+bool objcpy(std::list<std::unique_ptr<C2Work>>* d, const WorkBundle& s) {
+    // Convert BaseBlocks to C2BaseBlocks.
+    std::vector<C2BaseBlock> dBaseBlocks(s.baseBlocks.size());
+    for (size_t i = 0; i < s.baseBlocks.size(); ++i) {
+        if (!objcpy(&dBaseBlocks[i], s.baseBlocks[i])) {
+            LOG(ERROR) << "Invalid WorkBundle::baseBlocks["
+                       << i << "].";
+            return false;
+        }
+    }
+
+    d->clear();
+    for (const Work& sWork : s.works) {
+        d->emplace_back(std::make_unique<C2Work>());
+        C2Work& dWork = *d->back();
+
+        // chain info is not in use currently.
+
+        // input
+        if (!objcpy(&dWork.input, sWork.input, dBaseBlocks)) {
+            LOG(ERROR) << "Invalid Work::input.";
+            return false;
+        }
+
+        // worklet(s)
+        dWork.worklets.clear();
+        for (const Worklet& sWorklet : sWork.worklets) {
+            std::unique_ptr<C2Worklet> dWorklet = std::make_unique<C2Worklet>();
+
+            // component id
+            dWorklet->component = static_cast<c2_node_id_t>(
+                    sWorklet.componentId);
+
+            // tunings
+            if (!copyParamsFromBlob(&dWorklet->tunings, sWorklet.tunings)) {
+                LOG(ERROR) << "Invalid Worklet::tunings";
+                return false;
+            }
+
+            // failures
+            dWorklet->failures.clear();
+            dWorklet->failures.reserve(sWorklet.failures.size());
+            for (const SettingResult& sFailure : sWorklet.failures) {
+                std::unique_ptr<C2SettingResult> dFailure;
+                if (!objcpy(&dFailure, sFailure)) {
+                    LOG(ERROR) << "Invalid Worklet::failures.";
+                    return false;
+                }
+                dWorklet->failures.emplace_back(std::move(dFailure));
+            }
+
+            // output
+            if (!objcpy(&dWorklet->output, sWorklet.output, dBaseBlocks)) {
+                LOG(ERROR) << "Invalid Worklet::output.";
+                return false;
+            }
+
+            dWork.worklets.emplace_back(std::move(dWorklet));
+        }
+
+        // workletsProcessed
+        dWork.workletsProcessed = sWork.workletsProcessed;
+
+        // result
+        dWork.result = static_cast<c2_status_t>(sWork.result);
+    }
+
+    return true;
+}
+
+constexpr size_t PARAMS_ALIGNMENT = 8;  // 64-bit alignment
+static_assert(PARAMS_ALIGNMENT % alignof(C2Param) == 0, "C2Param alignment mismatch");
+static_assert(PARAMS_ALIGNMENT % alignof(C2Info) == 0, "C2Param alignment mismatch");
+static_assert(PARAMS_ALIGNMENT % alignof(C2Tuning) == 0, "C2Param alignment mismatch");
+
+// Params -> std::vector<C2Param*>
+bool parseParamsBlob(std::vector<C2Param*> *params, const hidl_vec<uint8_t> &blob) {
+    // assuming blob is const here
+    size_t size = blob.size();
+    size_t ix = 0;
+    const uint8_t *data = blob.data();
+    C2Param *p = nullptr;
+
+    do {
+        p = C2ParamUtils::ParseFirst(data + ix, size - ix);
+        if (p) {
+            params->emplace_back(p);
+            ix += p->size();
+            ix = align(ix, PARAMS_ALIGNMENT);
+        }
+    } while (p);
+
+    if (ix != size) {
+        LOG(ERROR) << "parseParamsBlob -- inconsistent sizes.";
+        return false;
+    }
+    return true;
+}
+
+namespace /* unnamed */ {
+
+/**
+ * Concatenates a list of C2Params into a params blob. T is a container type
+ * whose member type is compatible with C2Param*.
+ *
+ * \param[out] blob target blob
+ * \param[in] params parameters to concatenate
+ * \retval C2_OK if the blob was successfully created
+ * \retval C2_BAD_VALUE if the blob was not successful created (this only
+ *         happens if the parameters were not const)
+ */
+template <typename T>
+bool _createParamsBlob(hidl_vec<uint8_t> *blob, const T &params) {
+    // assuming the parameter values are const
+    size_t size = 0;
+    for (const auto &p : params) {
+        if (!p) {
+            continue;
+        }
+        size += p->size();
+        size = align(size, PARAMS_ALIGNMENT);
+    }
+    blob->resize(size);
+    size_t ix = 0;
+    for (const auto &p : params) {
+        if (!p) {
+            continue;
+        }
+        // NEVER overwrite even if param values (e.g. size) changed
+        size_t paramSize = std::min(p->size(), size - ix);
+        std::copy(
+                reinterpret_cast<const uint8_t*>(&*p),
+                reinterpret_cast<const uint8_t*>(&*p) + paramSize,
+                &(*blob)[ix]);
+        ix += paramSize;
+        ix = align(ix, PARAMS_ALIGNMENT);
+    }
+    blob->resize(ix);
+    if (ix != size) {
+        LOG(ERROR) << "createParamsBlob -- inconsistent sizes.";
+        return false;
+    }
+    return true;
+}
+
+/**
+ * Parses a params blob and create a vector of new T objects that contain copies
+ * of the params in the blob. T is C2Param or its compatible derived class.
+ *
+ * \param[out] params the resulting vector
+ * \param[in] blob parameter blob to parse
+ * \retval C2_OK if the full blob was parsed and params was constructed
+ * \retval C2_BAD_VALUE otherwise
+ */
+template <typename T>
+bool _copyParamsFromBlob(
+        std::vector<std::unique_ptr<T>>* params,
+        Params blob) {
+
+    std::vector<C2Param*> paramPointers;
+    if (!parseParamsBlob(&paramPointers, blob)) {
+        LOG(ERROR) << "copyParamsFromBlob -- failed to parse.";
+        return false;
+    }
+
+    params->resize(paramPointers.size());
+    size_t i = 0;
+    for (C2Param* const& paramPointer : paramPointers) {
+        if (!paramPointer) {
+            LOG(ERROR) << "copyParamsFromBlob -- null paramPointer.";
+            return false;
+        }
+        (*params)[i++].reset(reinterpret_cast<T*>(
+                C2Param::Copy(*paramPointer).release()));
+    }
+    return true;
+}
+
+} // unnamed namespace
+
+// std::vector<const C2Param*> -> Params
+bool createParamsBlob(
+        hidl_vec<uint8_t> *blob,
+        const std::vector<const C2Param*> &params) {
+    return _createParamsBlob(blob, params);
+}
+
+// std::vector<C2Param*> -> Params
+bool createParamsBlob(
+        hidl_vec<uint8_t> *blob,
+        const std::vector<C2Param*> &params) {
+    return _createParamsBlob(blob, params);
+}
+
+// std::vector<std::unique_ptr<C2Param>> -> Params
+bool createParamsBlob(
+        hidl_vec<uint8_t> *blob,
+        const std::vector<std::unique_ptr<C2Param>> &params) {
+    return _createParamsBlob(blob, params);
+}
+
+// std::vector<std::unique_ptr<C2Tuning>> -> Params
+bool createParamsBlob(
+        hidl_vec<uint8_t> *blob,
+        const std::vector<std::unique_ptr<C2Tuning>> &params) {
+    return _createParamsBlob(blob, params);
+}
+
+// std::vector<std::shared_ptr<const C2Info>> -> Params
+bool createParamsBlob(
+        hidl_vec<uint8_t> *blob,
+        const std::vector<std::shared_ptr<const C2Info>> &params) {
+    return _createParamsBlob(blob, params);
+}
+
+// Params -> std::vector<std::unique_ptr<C2Param>>
+bool copyParamsFromBlob(
+        std::vector<std::unique_ptr<C2Param>>* params,
+        Params blob) {
+    return _copyParamsFromBlob(params, blob);
+}
+
+// Params -> std::vector<std::unique_ptr<C2Tuning>>
+bool copyParamsFromBlob(
+        std::vector<std::unique_ptr<C2Tuning>>* params,
+        Params blob) {
+    return _copyParamsFromBlob(params, blob);
+}
+
+// Params -> update std::vector<std::unique_ptr<C2Param>>
+bool updateParamsFromBlob(
+        const std::vector<C2Param*>& params,
+        const Params& blob) {
+    std::unordered_map<uint32_t, C2Param*> index2param;
+    for (C2Param* const& param : params) {
+        if (!param) {
+            LOG(ERROR) << "updateParamsFromBlob -- null output param.";
+            return false;
+        }
+        if (index2param.find(param->index()) == index2param.end()) {
+            index2param.emplace(param->index(), param);
+        }
+    }
+
+    std::vector<C2Param*> paramPointers;
+    if (!parseParamsBlob(&paramPointers, blob)) {
+        LOG(ERROR) << "updateParamsFromBlob -- failed to parse.";
+        return false;
+    }
+
+    for (C2Param* const& paramPointer : paramPointers) {
+        if (!paramPointer) {
+            LOG(ERROR) << "updateParamsFromBlob -- null input param.";
+            return false;
+        }
+        decltype(index2param)::iterator i = index2param.find(
+                paramPointer->index());
+        if (i == index2param.end()) {
+            LOG(DEBUG) << "updateParamsFromBlob -- index "
+                       << paramPointer->index() << " not found. Skipping...";
+            continue;
+        }
+        if (!i->second->updateFrom(*paramPointer)) {
+            LOG(ERROR) << "updateParamsFromBlob -- size mismatch: "
+                       << params.size() << " vs " << paramPointer->size()
+                       << " (index = " << i->first << ").";
+            return false;
+        }
+    }
+    return true;
+}
+
+// Convert BufferPool ResultStatus to c2_status_t.
+c2_status_t toC2Status(ResultStatus rs) {
+    switch (rs) {
+    case ResultStatus::OK:
+        return C2_OK;
+    case ResultStatus::NO_MEMORY:
+        return C2_NO_MEMORY;
+    case ResultStatus::ALREADY_EXISTS:
+        return C2_DUPLICATE;
+    case ResultStatus::NOT_FOUND:
+        return C2_NOT_FOUND;
+    case ResultStatus::CRITICAL_ERROR:
+        return C2_CORRUPTED;
+    default:
+        LOG(WARNING) << "Unrecognized BufferPool ResultStatus: "
+                     << static_cast<int32_t>(rs) << ".";
+        return C2_CORRUPTED;
+    }
+}
+
+namespace /* unnamed */ {
+
+template <typename BlockProcessor>
+void forEachBlock(C2FrameData& frameData,
+                  BlockProcessor process) {
+    for (const std::shared_ptr<C2Buffer>& buffer : frameData.buffers) {
+        if (buffer) {
+            for (const C2ConstGraphicBlock& block :
+                    buffer->data().graphicBlocks()) {
+                process(block);
+            }
+        }
+    }
+}
+
+template <typename BlockProcessor>
+void forEachBlock(const std::list<std::unique_ptr<C2Work>>& workList,
+                  BlockProcessor process,
+                  bool processInput, bool processOutput) {
+    for (const std::unique_ptr<C2Work>& work : workList) {
+        if (!work) {
+            continue;
+        }
+        if (processInput) {
+            forEachBlock(work->input, process);
+        }
+        if (processOutput) {
+            for (const std::unique_ptr<C2Worklet>& worklet : work->worklets) {
+                if (worklet) {
+                    forEachBlock(worklet->output,
+                                 process);
+                }
+            }
+        }
+    }
+}
+
+} // unnamed namespace
+
+bool beginTransferBufferQueueBlock(const C2ConstGraphicBlock& block) {
+    std::shared_ptr<_C2BlockPoolData> data =
+            _C2BlockFactory::GetGraphicBlockPoolData(block);
+    if (data && _C2BlockFactory::GetBufferQueueData(data)) {
+        _C2BlockFactory::BeginTransferBlockToClient(data);
+        return true;
+    }
+    return false;
+}
+
+void beginTransferBufferQueueBlocks(
+        const std::list<std::unique_ptr<C2Work>>& workList,
+        bool processInput, bool processOutput) {
+    forEachBlock(workList, beginTransferBufferQueueBlock,
+                 processInput, processOutput);
+}
+
+bool endTransferBufferQueueBlock(
+        const C2ConstGraphicBlock& block,
+        bool transfer) {
+    std::shared_ptr<_C2BlockPoolData> data =
+            _C2BlockFactory::GetGraphicBlockPoolData(block);
+    if (data && _C2BlockFactory::GetBufferQueueData(data)) {
+        _C2BlockFactory::EndTransferBlockToClient(data, transfer);
+        return true;
+    }
+    return false;
+}
+
+void endTransferBufferQueueBlocks(
+        const std::list<std::unique_ptr<C2Work>>& workList,
+        bool transfer,
+        bool processInput, bool processOutput) {
+    forEachBlock(workList,
+                 std::bind(endTransferBufferQueueBlock,
+                           std::placeholders::_1, transfer),
+                 processInput, processOutput);
+}
+
+bool displayBufferQueueBlock(const C2ConstGraphicBlock& block) {
+    std::shared_ptr<_C2BlockPoolData> data =
+            _C2BlockFactory::GetGraphicBlockPoolData(block);
+    if (data && _C2BlockFactory::GetBufferQueueData(data)) {
+        _C2BlockFactory::DisplayBlockToBufferQueue(data);
+        return true;
+    }
+    return false;
+}
+
+}  // namespace utils
+}  // namespace V1_0
+}  // namespace c2
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
diff --git a/media/codec2/hidl/1.0/vts/OWNERS b/media/codec2/hidl/1.0/vts/OWNERS
new file mode 100644
index 0000000..6733e0c
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/OWNERS
@@ -0,0 +1,9 @@
+# Media team
+lajos@google.com
+pawin@google.com
+taklee@google.com
+wonsik@google.com
+
+# VTS team
+yim@google.com
+zhuoyao@google.com
diff --git a/media/codec2/hidl/1.0/vts/functional/audio/Android.bp b/media/codec2/hidl/1.0/vts/functional/audio/Android.bp
new file mode 100644
index 0000000..65f0d09
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/audio/Android.bp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+cc_test {
+    name: "VtsHalMediaC2V1_0TargetAudioDecTest",
+    defaults: ["VtsHalMediaC2V1_0Defaults"],
+    srcs: [
+        "VtsHalMediaC2V1_0TargetAudioDecTest.cpp",
+        //"media_audio_hidl_test_common.cpp"
+    ],
+}
+
+cc_test {
+    name: "VtsHalMediaC2V1_0TargetAudioEncTest",
+    defaults: ["VtsHalMediaC2V1_0Defaults"],
+    srcs: [
+        "VtsHalMediaC2V1_0TargetAudioEncTest.cpp",
+        //"media_audio_hidl_test_common.cpp"
+    ],
+}
diff --git a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp
new file mode 100644
index 0000000..a8a552c
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp
@@ -0,0 +1,943 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// #define LOG_NDEBUG 0
+#define LOG_TAG "codec2_hidl_hal_audio_dec_test"
+
+#include <android-base/logging.h>
+#include <gtest/gtest.h>
+#include <algorithm>
+#include <stdio.h>
+#include <fstream>
+
+#include <codec2/hidl/client.h>
+#include <C2AllocatorIon.h>
+#include <C2Config.h>
+#include <C2Debug.h>
+#include <C2Buffer.h>
+#include <C2BufferPriv.h>
+
+using android::C2AllocatorIon;
+
+#include <VtsHalHidlTargetTestBase.h>
+#include "media_c2_audio_hidl_test_common.h"
+#include "media_c2_hidl_test_common.h"
+
+struct FrameInfo {
+    int bytesCount;
+    uint32_t flags;
+    int64_t timestamp;
+};
+
+class LinearBuffer : public C2Buffer {
+   public:
+    explicit LinearBuffer(const std::shared_ptr<C2LinearBlock>& block)
+        : C2Buffer(
+              {block->share(block->offset(), block->size(), ::C2Fence())}) {}
+};
+
+static ComponentTestEnvironment* gEnv = nullptr;
+
+namespace {
+
+class Codec2AudioDecHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   private:
+    typedef ::testing::VtsHalHidlTargetTestBase Super;
+
+   public:
+    ::std::string getTestCaseInfo() const override {
+        return ::std::string() +
+                "Component: " + gEnv->getComponent().c_str() + " | " +
+                "Instance: " + gEnv->getInstance().c_str() + " | " +
+                "Res: " + gEnv->getRes().c_str();
+    }
+
+    // google.codec2 Audio test setup
+    virtual void SetUp() override {
+        Super::SetUp();
+        mDisableTest = false;
+        ALOGV("Codec2AudioDecHidlTest SetUp");
+        mClient = android::Codec2Client::CreateFromService(
+            gEnv->getInstance().c_str());
+        ASSERT_NE(mClient, nullptr);
+        mListener.reset(new CodecListener(
+            [this](std::list<std::unique_ptr<C2Work>>& workItems) {
+                handleWorkDone(workItems);
+            }));
+        ASSERT_NE(mListener, nullptr);
+        for (int i = 0; i < MAX_INPUT_BUFFERS; ++i) {
+            mWorkQueue.emplace_back(new C2Work);
+        }
+        mClient->createComponent(gEnv->getComponent().c_str(), mListener,
+                                 &mComponent);
+        ASSERT_NE(mComponent, nullptr);
+
+        std::shared_ptr<C2AllocatorStore> store =
+            android::GetCodec2PlatformAllocatorStore();
+        CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR,
+                                       &mLinearAllocator),
+                 C2_OK);
+        mLinearPool = std::make_shared<C2PooledBlockPool>(mLinearAllocator,
+                                                          mBlockPoolId++);
+        ASSERT_NE(mLinearPool, nullptr);
+
+        mCompName = unknown_comp;
+        struct StringToName {
+            const char* Name;
+            standardComp CompName;
+        };
+        const StringToName kStringToName[] = {
+            {"xaac", xaac},
+            {"mp3", mp3},
+            {"amrnb", amrnb},
+            {"amrwb", amrwb},
+            {"aac", aac},
+            {"vorbis", vorbis},
+            {"opus", opus},
+            {"pcm", pcm},
+            {"g711.alaw", g711alaw},
+            {"g711.mlaw", g711mlaw},
+            {"gsm", gsm},
+            {"raw", raw},
+            {"flac", flac},
+        };
+        const size_t kNumStringToName =
+            sizeof(kStringToName) / sizeof(kStringToName[0]);
+
+        // Find the component type
+        std::string comp = std::string(gEnv->getComponent());
+        for (size_t i = 0; i < kNumStringToName; ++i) {
+            if (strcasestr(comp.c_str(), kStringToName[i].Name)) {
+                mCompName = kStringToName[i].CompName;
+                break;
+            }
+        }
+        mEos = false;
+        mFramesReceived = 0;
+        mTimestampUs = 0u;
+        mTimestampDevTest = false;
+        if (mCompName == unknown_comp) mDisableTest = true;
+        if (mDisableTest) std::cout << "[   WARN   ] Test Disabled \n";
+    }
+
+    virtual void TearDown() override {
+        if (mComponent != nullptr) {
+            if (::testing::Test::HasFatalFailure()) return;
+            mComponent->release();
+            mComponent = nullptr;
+        }
+        Super::TearDown();
+    }
+
+    struct outputMetaData {
+        uint64_t timestampUs;
+        uint32_t rangeLength;
+    };
+    // callback function to process onWorkDone received by Listener
+    void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
+        for (std::unique_ptr<C2Work>& work : workItems) {
+            if (!work->worklets.empty()) {
+                // For decoder components current timestamp always exceeds
+                // previous timestamp
+                bool codecConfig = ((work->worklets.front()->output.flags &
+                                     C2FrameData::FLAG_CODEC_CONFIG) != 0);
+                if (!codecConfig &&
+                    !work->worklets.front()->output.buffers.empty()) {
+                    EXPECT_GE(work->worklets.front()->output.ordinal.timestamp.peeku(),
+                        mTimestampUs);
+                    mTimestampUs =
+                        work->worklets.front()->output.ordinal.timestamp.peeku();
+                    uint32_t rangeLength =
+                        work->worklets.front()->output.buffers[0]->data()
+                        .linearBlocks().front().map().get().capacity();
+                    //List of timestamp values and output size to calculate timestamp
+                    if (mTimestampDevTest) {
+                        outputMetaData meta = {mTimestampUs, rangeLength};
+                        oBufferMetaData.push_back(meta);
+                    }
+                }
+                bool mCsd = false;
+                workDone(mComponent, work, mFlushedIndices, mQueueLock,
+                         mQueueCondition, mWorkQueue, mEos, mCsd,
+                         mFramesReceived);
+                (void)mCsd;
+            }
+        }
+    }
+
+    enum standardComp {
+        xaac,
+        mp3,
+        amrnb,
+        amrwb,
+        aac,
+        vorbis,
+        opus,
+        pcm,
+        g711alaw,
+        g711mlaw,
+        gsm,
+        raw,
+        flac,
+        unknown_comp,
+    };
+
+    bool mEos;
+    bool mDisableTest;
+    bool mTimestampDevTest;
+    standardComp mCompName;
+    uint64_t mTimestampUs;
+    uint32_t mFramesReceived;
+    std::list<uint64_t> mFlushedIndices;
+    std::list<uint64_t> mTimestampUslist;
+    ::android::List<outputMetaData> oBufferMetaData;
+
+    C2BlockPool::local_id_t mBlockPoolId;
+    std::shared_ptr<C2BlockPool> mLinearPool;
+    std::shared_ptr<C2Allocator> mLinearAllocator;
+
+    std::mutex mQueueLock;
+    std::condition_variable mQueueCondition;
+    std::list<std::unique_ptr<C2Work>> mWorkQueue;
+
+    std::shared_ptr<android::Codec2Client> mClient;
+    std::shared_ptr<android::Codec2Client::Listener> mListener;
+    std::shared_ptr<android::Codec2Client::Component> mComponent;
+
+   protected:
+    static void description(const std::string& description) {
+        RecordProperty("description", description);
+    }
+};
+
+void validateComponent(
+    const std::shared_ptr<android::Codec2Client::Component>& component,
+    Codec2AudioDecHidlTest::standardComp compName, bool& disableTest) {
+    // Validate its a C2 Component
+    if (component->getName().find("c2") == std::string::npos) {
+        ALOGE("Not a c2 component");
+        disableTest = true;
+        return;
+    }
+
+    // Validate its not an encoder and the component to be tested is audio
+    if (component->getName().find("encoder") != std::string::npos) {
+        ALOGE("Expected Decoder, given Encoder");
+        disableTest = true;
+        return;
+    }
+    std::vector<std::unique_ptr<C2Param>> queried;
+    c2_status_t c2err =
+        component->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE},
+                         C2_DONT_BLOCK, &queried);
+    if (c2err != C2_OK && queried.size() == 0) {
+        ALOGE("Query media type failed => %d", c2err);
+    } else {
+        std::string inputDomain =
+            ((C2StreamMediaTypeSetting::input*)queried[0].get())->m.value;
+        if (inputDomain.find("audio/") == std::string::npos) {
+            ALOGE("Expected Audio Component");
+            disableTest = true;
+            return;
+        }
+    }
+
+    // Validates component name
+    if (compName == Codec2AudioDecHidlTest::unknown_comp) {
+        ALOGE("Component InValid");
+        disableTest = true;
+        return;
+    }
+    ALOGV("Component Valid");
+}
+
+// Set Default config param.
+bool setupConfigParam(
+    const std::shared_ptr<android::Codec2Client::Component>& component,
+    int32_t* bitStreamInfo) {
+    std::vector<std::unique_ptr<C2SettingResult>> failures;
+    C2StreamSampleRateInfo::output sampleRateInfo(0u, bitStreamInfo[0]);
+    C2StreamChannelCountInfo::output channelCountInfo(0u, bitStreamInfo[1]);
+
+    std::vector<C2Param*> configParam{&sampleRateInfo, &channelCountInfo};
+    c2_status_t status =
+        component->config(configParam, C2_DONT_BLOCK, &failures);
+    if (status == C2_OK && failures.size() == 0u) return true;
+    return false;
+}
+
+// In decoder components, often the input parameters get updated upon
+// parsing the header of elementary stream. Client needs to collect this
+// information and reconfigure
+void getInputChannelInfo(
+    const std::shared_ptr<android::Codec2Client::Component>& component,
+    Codec2AudioDecHidlTest::standardComp compName, int32_t* bitStreamInfo) {
+    // query nSampleRate and nChannels
+    std::initializer_list<C2Param::Index> indices{
+        C2StreamSampleRateInfo::output::PARAM_TYPE,
+        C2StreamChannelCountInfo::output::PARAM_TYPE,
+    };
+    std::vector<std::unique_ptr<C2Param>> inParams;
+    c2_status_t status =
+        component->query({}, indices, C2_DONT_BLOCK, &inParams);
+    if (status != C2_OK && inParams.size() == 0) {
+        ALOGE("Query media type failed => %d", status);
+        ASSERT_TRUE(false);
+    } else {
+        size_t offset = sizeof(C2Param);
+        for (size_t i = 0; i < inParams.size(); ++i) {
+            C2Param* param = inParams[i].get();
+            bitStreamInfo[i] = *(int32_t*)((uint8_t*)param + offset);
+        }
+        switch (compName) {
+            case Codec2AudioDecHidlTest::amrnb: {
+                ASSERT_EQ(bitStreamInfo[0], 8000);
+                ASSERT_EQ(bitStreamInfo[1], 1);
+                break;
+            }
+            case Codec2AudioDecHidlTest::amrwb: {
+                ASSERT_EQ(bitStreamInfo[0], 16000);
+                ASSERT_EQ(bitStreamInfo[1], 1);
+                break;
+            }
+            case Codec2AudioDecHidlTest::gsm: {
+                ASSERT_EQ(bitStreamInfo[0], 8000);
+                break;
+            }
+            default:
+                break;
+        }
+    }
+}
+
+// number of elementary streams per component
+#define STREAM_COUNT 2
+
+// LookUpTable of clips and metadata for component testing
+void GetURLForComponent(Codec2AudioDecHidlTest::standardComp comp, char* mURL,
+                        char* info, size_t streamIndex = 0) {
+    struct CompToURL {
+        Codec2AudioDecHidlTest::standardComp comp;
+        const char mURL[STREAM_COUNT][512];
+        const char info[STREAM_COUNT][512];
+    };
+    ASSERT_TRUE(streamIndex < STREAM_COUNT);
+
+    static const CompToURL kCompToURL[] = {
+        {Codec2AudioDecHidlTest::standardComp::xaac,
+         {"bbb_aac_stereo_128kbps_48000hz.aac",
+          "bbb_aac_stereo_128kbps_48000hz.aac"},
+         {"bbb_aac_stereo_128kbps_48000hz.info",
+          "bbb_aac_stereo_128kbps_48000hz_multi_frame.info"}},
+        {Codec2AudioDecHidlTest::standardComp::mp3,
+         {"bbb_mp3_stereo_192kbps_48000hz.mp3",
+          "bbb_mp3_stereo_192kbps_48000hz.mp3"},
+         {"bbb_mp3_stereo_192kbps_48000hz.info",
+          "bbb_mp3_stereo_192kbps_48000hz_multi_frame.info"}},
+        {Codec2AudioDecHidlTest::standardComp::aac,
+         {"bbb_aac_stereo_128kbps_48000hz.aac",
+          "bbb_aac_stereo_128kbps_48000hz.aac"},
+         {"bbb_aac_stereo_128kbps_48000hz.info",
+          "bbb_aac_stereo_128kbps_48000hz_multi_frame.info"}},
+        {Codec2AudioDecHidlTest::standardComp::amrnb,
+         {"sine_amrnb_1ch_12kbps_8000hz.amrnb",
+          "sine_amrnb_1ch_12kbps_8000hz.amrnb"},
+         {"sine_amrnb_1ch_12kbps_8000hz.info",
+          "sine_amrnb_1ch_12kbps_8000hz_multi_frame.info"}},
+        {Codec2AudioDecHidlTest::standardComp::amrwb,
+         {"bbb_amrwb_1ch_14kbps_16000hz.amrwb",
+          "bbb_amrwb_1ch_14kbps_16000hz.amrwb"},
+         {"bbb_amrwb_1ch_14kbps_16000hz.info",
+          "bbb_amrwb_1ch_14kbps_16000hz_multi_frame.info"}},
+        {Codec2AudioDecHidlTest::standardComp::vorbis,
+         {"bbb_vorbis_stereo_128kbps_48000hz.vorbis", ""},
+         {"bbb_vorbis_stereo_128kbps_48000hz.info", ""}},
+        {Codec2AudioDecHidlTest::standardComp::opus,
+         {"bbb_opus_stereo_128kbps_48000hz.opus", ""},
+         {"bbb_opus_stereo_128kbps_48000hz.info", ""}},
+        {Codec2AudioDecHidlTest::standardComp::g711alaw,
+         {"bbb_g711alaw_1ch_8khz.raw", ""},
+         {"bbb_g711alaw_1ch_8khz.info", ""}},
+        {Codec2AudioDecHidlTest::standardComp::g711mlaw,
+         {"bbb_g711mulaw_1ch_8khz.raw", ""},
+         {"bbb_g711mulaw_1ch_8khz.info", ""}},
+        {Codec2AudioDecHidlTest::standardComp::gsm,
+         {"bbb_gsm_1ch_8khz_13kbps.raw", ""},
+         {"bbb_gsm_1ch_8khz_13kbps.info", ""}},
+        {Codec2AudioDecHidlTest::standardComp::raw,
+         {"bbb_raw_1ch_8khz_s32le.raw", ""},
+         {"bbb_raw_1ch_8khz_s32le.info", ""}},
+        {Codec2AudioDecHidlTest::standardComp::flac,
+         {"bbb_flac_stereo_680kbps_48000hz.flac", ""},
+         {"bbb_flac_stereo_680kbps_48000hz.info", ""}},
+    };
+
+    for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) {
+        if (kCompToURL[i].comp == comp) {
+            strcat(mURL, kCompToURL[i].mURL[streamIndex]);
+            strcat(info, kCompToURL[i].info[streamIndex]);
+            return;
+        }
+    }
+}
+
+void decodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
+                   std::mutex &queueLock, std::condition_variable& queueCondition,
+                   std::list<std::unique_ptr<C2Work>>& workQueue,
+                   std::list<uint64_t>& flushedIndices,
+                   std::shared_ptr<C2BlockPool>& linearPool,
+                   std::ifstream& eleStream,
+                   android::Vector<FrameInfo>* Info,
+                   int offset, int range, bool signalEOS = true) {
+    typedef std::unique_lock<std::mutex> ULock;
+    int frameID = offset;
+    int maxRetry = 0;
+    while (1) {
+        if (frameID == (int)Info->size() || frameID == (offset + range)) break;
+        uint32_t flags = 0;
+        std::unique_ptr<C2Work> work;
+        // Prepare C2Work
+        while (!work && (maxRetry < MAX_RETRY)) {
+            ULock l(queueLock);
+            if (!workQueue.empty()) {
+                work.swap(workQueue.front());
+                workQueue.pop_front();
+            } else {
+                queueCondition.wait_for(l, TIME_OUT);
+                maxRetry++;
+            }
+        }
+        if (!work && (maxRetry >= MAX_RETRY)) {
+            ASSERT_TRUE(false) << "Wait for generating C2Work exceeded timeout";
+        }
+        int64_t timestamp = (*Info)[frameID].timestamp;
+        if ((*Info)[frameID].flags) flags = 1u << ((*Info)[frameID].flags - 1);
+        if (signalEOS && ((frameID == (int)Info->size() - 1) ||
+                          (frameID == (offset + range - 1))))
+            flags |= C2FrameData::FLAG_END_OF_STREAM;
+
+        work->input.flags = (C2FrameData::flags_t)flags;
+        work->input.ordinal.timestamp = timestamp;
+        work->input.ordinal.frameIndex = frameID;
+        {
+            ULock l(queueLock);
+            flushedIndices.emplace_back(frameID);
+        }
+        int size = (*Info)[frameID].bytesCount;
+        char* data = (char*)malloc(size);
+        ASSERT_NE(data, nullptr);
+
+        eleStream.read(data, size);
+        ASSERT_EQ(eleStream.gcount(), size);
+
+        work->input.buffers.clear();
+        if (size) {
+            std::shared_ptr<C2LinearBlock> block;
+            ASSERT_EQ(C2_OK,
+                    linearPool->fetchLinearBlock(
+                        size, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE},
+                        &block));
+            ASSERT_TRUE(block);
+
+            // Write View
+            C2WriteView view = block->map().get();
+            if (view.error() != C2_OK) {
+                fprintf(stderr, "C2LinearBlock::map() failed : %d", view.error());
+                break;
+            }
+            ASSERT_EQ((size_t)size, view.capacity());
+            ASSERT_EQ(0u, view.offset());
+            ASSERT_EQ((size_t)size, view.size());
+
+            memcpy(view.base(), data, size);
+
+            work->input.buffers.emplace_back(new LinearBuffer(block));
+            free(data);
+        }
+        work->worklets.clear();
+        work->worklets.emplace_back(new C2Worklet);
+
+        std::list<std::unique_ptr<C2Work>> items;
+        items.push_back(std::move(work));
+
+        // DO THE DECODING
+        ASSERT_EQ(component->queue(&items), C2_OK);
+        ALOGV("Frame #%d size = %d queued", frameID, size);
+        frameID++;
+        maxRetry = 0;
+    }
+}
+
+TEST_F(Codec2AudioDecHidlTest, validateCompName) {
+    if (mDisableTest) return;
+    ALOGV("Checks if the given component is a valid audio component");
+    validateComponent(mComponent, mCompName, mDisableTest);
+    ASSERT_EQ(mDisableTest, false);
+}
+
+TEST_F(Codec2AudioDecHidlTest, configComp) {
+    description("Tests component specific configuration");
+    if (mDisableTest) return;
+    ASSERT_EQ(mComponent->start(), C2_OK);
+    int32_t bitStreamInfo[2] = {0};
+    ASSERT_NO_FATAL_FAILURE(
+        getInputChannelInfo(mComponent, mCompName, bitStreamInfo));
+    setupConfigParam(mComponent, bitStreamInfo);
+    ASSERT_EQ(mComponent->stop(), C2_OK);
+}
+
+class Codec2AudioDecDecodeTest
+    : public Codec2AudioDecHidlTest,
+      public ::testing::WithParamInterface<std::pair<int32_t, bool>> {
+};
+
+TEST_P(Codec2AudioDecDecodeTest, DecodeTest) {
+    description("Decodes input file");
+    if (mDisableTest) return;
+
+    uint32_t streamIndex = GetParam().first;
+    bool signalEOS = GetParam().second;
+    mTimestampDevTest = true;
+    char mURL[512], info[512];
+    std::ifstream eleStream, eleInfo;
+
+    strcpy(mURL, gEnv->getRes().c_str());
+    strcpy(info, gEnv->getRes().c_str());
+    GetURLForComponent(mCompName, mURL, info, streamIndex);
+    if (!strcmp(mURL, gEnv->getRes().c_str())) {
+        ALOGV("EMPTY INPUT gEnv->getRes().c_str() %s mURL  %s ",
+              gEnv->getRes().c_str(), mURL);
+        return;
+    }
+
+    eleInfo.open(info);
+    ASSERT_EQ(eleInfo.is_open(), true);
+    android::Vector<FrameInfo> Info;
+    int bytesCount = 0;
+    uint32_t flags = 0;
+    uint32_t timestamp = 0;
+    while (1) {
+        if (!(eleInfo >> bytesCount)) break;
+        eleInfo >> flags;
+        eleInfo >> timestamp;
+        bool codecConfig =
+            ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0;
+        if (mTimestampDevTest && !codecConfig)
+            mTimestampUslist.push_back(timestamp);
+        Info.push_back({bytesCount, flags, timestamp});
+    }
+    eleInfo.close();
+    // Reset total no of frames received
+    mFramesReceived = 0;
+    mTimestampUs = 0;
+    int32_t bitStreamInfo[2] = {0};
+    if (mCompName == raw) {
+        bitStreamInfo[0] = 8000;
+        bitStreamInfo[1] = 1;
+    } else if (mCompName == g711alaw || mCompName == g711mlaw) {
+        // g711 test data is all 1-channel and has no embedded config info.
+        bitStreamInfo[0] = 8000;
+        bitStreamInfo[1] = 1;
+    } else {
+        ASSERT_NO_FATAL_FAILURE(
+            getInputChannelInfo(mComponent, mCompName, bitStreamInfo));
+    }
+    if (!setupConfigParam(mComponent, bitStreamInfo)) {
+        std::cout << "[   WARN   ] Test Skipped \n";
+        return;
+    }
+    ASSERT_EQ(mComponent->start(), C2_OK);
+    ALOGV("mURL : %s", mURL);
+    eleStream.open(mURL, std::ifstream::binary);
+    ASSERT_EQ(eleStream.is_open(), true);
+    ASSERT_NO_FATAL_FAILURE(decodeNFrames(
+        mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices,
+        mLinearPool, eleStream, &Info, 0, (int)Info.size(), signalEOS));
+
+    // If EOS is not sent, sending empty input with EOS flag
+    size_t infoSize = Info.size();
+    if (!signalEOS) {
+        ASSERT_NO_FATAL_FAILURE(
+            waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, 1));
+        ASSERT_NO_FATAL_FAILURE(
+            testInputBuffer(mComponent, mQueueLock, mWorkQueue,
+                            C2FrameData::FLAG_END_OF_STREAM, false));
+        infoSize += 1;
+    }
+    // blocking call to ensures application to Wait till all the inputs are
+    // consumed
+    ASSERT_NO_FATAL_FAILURE(
+        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+    eleStream.close();
+    if (mFramesReceived != infoSize) {
+        ALOGE("Input buffer count and Output buffer count mismatch");
+        ALOGE("framesReceived : %d inputFrames : %zu", mFramesReceived,
+              infoSize);
+        ASSERT_TRUE(false);
+    }
+    ASSERT_EQ(mEos, true);
+    if (mTimestampDevTest) {
+        uint64_t expTs;
+        uint32_t samplesReceived = 0;
+        // Update SampleRate and ChannelCount
+        ASSERT_NO_FATAL_FAILURE(
+            getInputChannelInfo(mComponent, mCompName, bitStreamInfo));
+        int nSampleRate = bitStreamInfo[0];
+        int nChannels = bitStreamInfo[1];
+        std::list<uint64_t>::iterator itIn = mTimestampUslist.begin();
+        android::List<outputMetaData>::iterator itOut = oBufferMetaData.begin();
+        EXPECT_EQ(*itIn, itOut->timestampUs);
+        expTs = *itIn;
+        while (itOut != oBufferMetaData.end()) {
+            EXPECT_EQ(expTs, itOut->timestampUs);
+            if (expTs != itOut->timestampUs) break;
+            // buffer samples = ((total bytes) / (ac * (bits per sample / 8))
+            samplesReceived += ((itOut->rangeLength) / (nChannels * 2));
+            expTs = samplesReceived * 1000000ll / nSampleRate;
+            itOut++;
+        }
+        itIn = mTimestampUslist.end();
+        --itIn;
+        EXPECT_GT(expTs, *itIn);
+        oBufferMetaData.clear();
+        mTimestampUslist.clear();
+    }
+    ASSERT_EQ(mComponent->stop(), C2_OK);
+}
+// DecodeTest with StreamIndex and EOS / No EOS
+INSTANTIATE_TEST_CASE_P(StreamIndexAndEOS, Codec2AudioDecDecodeTest,
+                        ::testing::Values(std::make_pair(0, false),
+                                          std::make_pair(0, true),
+                                          std::make_pair(1, false),
+                                          std::make_pair(1, true)));
+
+// thumbnail test
+TEST_F(Codec2AudioDecHidlTest, ThumbnailTest) {
+    description("Test Request for thumbnail");
+    if (mDisableTest) return;
+
+    char mURL[512], info[512];
+    std::ifstream eleStream, eleInfo;
+
+    strcpy(mURL, gEnv->getRes().c_str());
+    strcpy(info, gEnv->getRes().c_str());
+    GetURLForComponent(mCompName, mURL, info);
+
+    eleInfo.open(info);
+    ASSERT_EQ(eleInfo.is_open(), true);
+    android::Vector<FrameInfo> Info;
+    int bytesCount = 0;
+    uint32_t flags = 0;
+    uint32_t timestamp = 0;
+    while (1) {
+        if (!(eleInfo >> bytesCount)) break;
+        eleInfo >> flags;
+        eleInfo >> timestamp;
+        Info.push_back({bytesCount, flags, timestamp});
+    }
+    eleInfo.close();
+    int32_t bitStreamInfo[2] = {0};
+    if (mCompName == raw) {
+        bitStreamInfo[0] = 8000;
+        bitStreamInfo[1] = 1;
+    } else {
+        ASSERT_NO_FATAL_FAILURE(
+            getInputChannelInfo(mComponent, mCompName, bitStreamInfo));
+    }
+    if (!setupConfigParam(mComponent, bitStreamInfo)) {
+        std::cout << "[   WARN   ] Test Skipped \n";
+        return;
+    }
+    ASSERT_EQ(mComponent->start(), C2_OK);
+    ALOGV("mURL : %s", mURL);
+
+    // request EOS for thumbnail
+    // signal EOS flag with last frame
+    size_t i = -1;
+    do {
+        i++;
+        flags = 0;
+        if (Info[i].flags) flags = 1u << (Info[i].flags - 1);
+
+    } while (!(flags & SYNC_FRAME));
+    eleStream.open(mURL, std::ifstream::binary);
+    ASSERT_EQ(eleStream.is_open(), true);
+    ASSERT_NO_FATAL_FAILURE(decodeNFrames(
+        mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices,
+        mLinearPool, eleStream, &Info, 0, i + 1));
+    ASSERT_NO_FATAL_FAILURE(
+        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+    eleStream.close();
+    EXPECT_GE(mFramesReceived, 1U);
+    ASSERT_EQ(mEos, true);
+    ASSERT_EQ(mComponent->stop(), C2_OK);
+}
+
+TEST_F(Codec2AudioDecHidlTest, EOSTest) {
+    description("Test empty input buffer with EOS flag");
+    if (mDisableTest) return;
+    typedef std::unique_lock<std::mutex> ULock;
+    ASSERT_EQ(mComponent->start(), C2_OK);
+    std::unique_ptr<C2Work> work;
+    // Prepare C2Work
+    {
+        ULock l(mQueueLock);
+        if (!mWorkQueue.empty()) {
+            work.swap(mWorkQueue.front());
+            mWorkQueue.pop_front();
+        } else {
+            ASSERT_TRUE(false) << "mWorkQueue Empty at the start of test";
+        }
+    }
+    ASSERT_NE(work, nullptr);
+
+    work->input.flags = (C2FrameData::flags_t)C2FrameData::FLAG_END_OF_STREAM;
+    work->input.ordinal.timestamp = 0;
+    work->input.ordinal.frameIndex = 0;
+    work->input.buffers.clear();
+    work->worklets.clear();
+    work->worklets.emplace_back(new C2Worklet);
+
+    std::list<std::unique_ptr<C2Work>> items;
+    items.push_back(std::move(work));
+    ASSERT_EQ(mComponent->queue(&items), C2_OK);
+
+    {
+        ULock l(mQueueLock);
+        if (mWorkQueue.size() != MAX_INPUT_BUFFERS) {
+            mQueueCondition.wait_for(l, TIME_OUT);
+        }
+    }
+    ASSERT_EQ(mEos, true);
+    ASSERT_EQ(mWorkQueue.size(), (size_t)MAX_INPUT_BUFFERS);
+    ASSERT_EQ(mComponent->stop(), C2_OK);
+}
+
+TEST_F(Codec2AudioDecHidlTest, FlushTest) {
+    description("Tests Flush calls");
+    if (mDisableTest) return;
+    typedef std::unique_lock<std::mutex> ULock;
+    char mURL[512], info[512];
+    std::ifstream eleStream, eleInfo;
+
+    strcpy(mURL, gEnv->getRes().c_str());
+    strcpy(info, gEnv->getRes().c_str());
+    GetURLForComponent(mCompName, mURL, info);
+
+    eleInfo.open(info);
+    ASSERT_EQ(eleInfo.is_open(), true);
+    android::Vector<FrameInfo> Info;
+    int bytesCount = 0;
+    uint32_t flags = 0;
+    uint32_t timestamp = 0;
+    mFlushedIndices.clear();
+    while (1) {
+        if (!(eleInfo >> bytesCount)) break;
+        eleInfo >> flags;
+        eleInfo >> timestamp;
+        Info.push_back({bytesCount, flags, timestamp});
+    }
+    eleInfo.close();
+    int32_t bitStreamInfo[2] = {0};
+    if (mCompName == raw) {
+        bitStreamInfo[0] = 8000;
+        bitStreamInfo[1] = 1;
+    } else {
+        ASSERT_NO_FATAL_FAILURE(
+            getInputChannelInfo(mComponent, mCompName, bitStreamInfo));
+    }
+    if (!setupConfigParam(mComponent, bitStreamInfo)) {
+        std::cout << "[   WARN   ] Test Skipped \n";
+        return;
+    }
+    ASSERT_EQ(mComponent->start(), C2_OK);
+    ALOGV("mURL : %s", mURL);
+    eleStream.open(mURL, std::ifstream::binary);
+    ASSERT_EQ(eleStream.is_open(), true);
+    // Decode 128 frames and flush. here 128 is chosen to ensure there is a key
+    // frame after this so that the below section can be covered for all
+    // components
+    uint32_t numFramesFlushed = 128;
+    ASSERT_NO_FATAL_FAILURE(decodeNFrames(
+        mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices,
+        mLinearPool, eleStream, &Info, 0, numFramesFlushed, false));
+    // flush
+    std::list<std::unique_ptr<C2Work>> flushedWork;
+    c2_status_t err =
+        mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
+    ASSERT_EQ(err, C2_OK);
+    ASSERT_NO_FATAL_FAILURE(
+        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
+            (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
+    uint64_t frameIndex;
+    {
+        //Update mFlushedIndices based on the index received from flush()
+        ULock l(mQueueLock);
+        for (std::unique_ptr<C2Work>& work : flushedWork) {
+            ASSERT_NE(work, nullptr);
+            frameIndex = work->input.ordinal.frameIndex.peeku();
+            std::list<uint64_t>::iterator frameIndexIt =
+                std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
+                          frameIndex);
+            if (!mFlushedIndices.empty() &&
+                (frameIndexIt != mFlushedIndices.end())) {
+                mFlushedIndices.erase(frameIndexIt);
+                work->input.buffers.clear();
+                work->worklets.clear();
+                mWorkQueue.push_back(std::move(work));
+            }
+        }
+    }
+    // Seek to next key frame and start decoding till the end
+    mFlushedIndices.clear();
+    int index = numFramesFlushed;
+    bool keyFrame = false;
+    flags = 0;
+    while (index < (int)Info.size()) {
+        if (Info[index].flags) flags = 1u << (Info[index].flags - 1);
+        if ((flags & SYNC_FRAME) == SYNC_FRAME) {
+            keyFrame = true;
+            break;
+        }
+        flags = 0;
+        eleStream.ignore(Info[index].bytesCount);
+        index++;
+    }
+    if (keyFrame) {
+        ASSERT_NO_FATAL_FAILURE(
+            decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                          mFlushedIndices, mLinearPool, eleStream, &Info, index,
+                          (int)Info.size() - index));
+    }
+    eleStream.close();
+    err =
+        mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
+    ASSERT_EQ(err, C2_OK);
+    ASSERT_NO_FATAL_FAILURE(
+        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
+            (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
+    {
+        //Update mFlushedIndices based on the index received from flush()
+        ULock l(mQueueLock);
+        for (std::unique_ptr<C2Work>& work : flushedWork) {
+            ASSERT_NE(work, nullptr);
+            frameIndex = work->input.ordinal.frameIndex.peeku();
+            std::list<uint64_t>::iterator frameIndexIt =
+                std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
+                          frameIndex);
+            if (!mFlushedIndices.empty() &&
+                (frameIndexIt != mFlushedIndices.end())) {
+                mFlushedIndices.erase(frameIndexIt);
+                work->input.buffers.clear();
+                work->worklets.clear();
+                mWorkQueue.push_back(std::move(work));
+            }
+        }
+    }
+    ASSERT_EQ(mFlushedIndices.empty(), true);
+    ASSERT_EQ(mComponent->stop(), C2_OK);
+}
+
+TEST_F(Codec2AudioDecHidlTest, DecodeTestEmptyBuffersInserted) {
+    description("Decode with multiple empty input frames");
+    if (mDisableTest) return;
+
+    char mURL[512], info[512];
+    std::ifstream eleStream, eleInfo;
+
+    strcpy(mURL, gEnv->getRes().c_str());
+    strcpy(info, gEnv->getRes().c_str());
+    GetURLForComponent(mCompName, mURL, info);
+
+    eleInfo.open(info);
+    ASSERT_EQ(eleInfo.is_open(), true) << mURL << " - file not found";
+    android::Vector<FrameInfo> Info;
+    int bytesCount = 0;
+    uint32_t frameId = 0;
+    uint32_t flags = 0;
+    uint32_t timestamp = 0;
+    bool codecConfig = false;
+    // This test introduces empty CSD after every 20th frame
+    // and empty input frames at an interval of 5 frames.
+    while (1) {
+        if (!(frameId % 5)) {
+            if (!(frameId % 20)) flags = 32;
+            else flags = 0;
+            bytesCount = 0;
+        } else {
+            if (!(eleInfo >> bytesCount)) break;
+            eleInfo >> flags;
+            eleInfo >> timestamp;
+            codecConfig = flags ?
+                ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0 : 0;
+        }
+        Info.push_back({bytesCount, flags, timestamp});
+        frameId++;
+    }
+    eleInfo.close();
+    int32_t bitStreamInfo[2] = {0};
+    if (mCompName == raw) {
+        bitStreamInfo[0] = 8000;
+        bitStreamInfo[1] = 1;
+    } else {
+        ASSERT_NO_FATAL_FAILURE(
+            getInputChannelInfo(mComponent, mCompName, bitStreamInfo));
+    }
+    if (!setupConfigParam(mComponent, bitStreamInfo)) {
+        std::cout << "[   WARN   ] Test Skipped \n";
+        return;
+    }
+    ASSERT_EQ(mComponent->start(), C2_OK);
+    ALOGV("mURL : %s", mURL);
+    eleStream.open(mURL, std::ifstream::binary);
+    ASSERT_EQ(eleStream.is_open(), true);
+    ASSERT_NO_FATAL_FAILURE(decodeNFrames(
+        mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices,
+        mLinearPool, eleStream, &Info, 0, (int)Info.size()));
+
+    // blocking call to ensures application to Wait till all the inputs are
+    // consumed
+    if (!mEos) {
+        ALOGV("Waiting for input consumption");
+        ASSERT_NO_FATAL_FAILURE(
+            waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+    }
+
+    eleStream.close();
+    if (mFramesReceived != Info.size()) {
+        ALOGE("Input buffer count and Output buffer count mismatch");
+        ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived,
+              Info.size());
+        ASSERT_TRUE(false);
+    }
+
+    ASSERT_EQ(mComponent->stop(), C2_OK);
+}
+
+}  // anonymous namespace
+
+int main(int argc, char** argv) {
+    gEnv = new ComponentTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    gEnv->init(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        int status = RUN_ALL_TESTS();
+        LOG(INFO) << "C2 Test result = " << status;
+    }
+    return status;
+}
diff --git a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp
new file mode 100644
index 0000000..01baf7e
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp
@@ -0,0 +1,650 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// #define LOG_NDEBUG 0
+#define LOG_TAG "codec2_hidl_hal_audio_enc_test"
+
+#include <android-base/logging.h>
+#include <gtest/gtest.h>
+#include <stdio.h>
+#include <fstream>
+#include <algorithm>
+
+#include <codec2/hidl/client.h>
+#include <C2AllocatorIon.h>
+#include <C2Config.h>
+#include <C2Debug.h>
+#include <C2Buffer.h>
+#include <C2BufferPriv.h>
+
+using android::C2AllocatorIon;
+
+#include <VtsHalHidlTargetTestBase.h>
+#include "media_c2_audio_hidl_test_common.h"
+#include "media_c2_hidl_test_common.h"
+
+class LinearBuffer : public C2Buffer {
+   public:
+    explicit LinearBuffer(const std::shared_ptr<C2LinearBlock>& block)
+        : C2Buffer(
+              {block->share(block->offset(), block->size(), ::C2Fence())}) {}
+};
+
+static ComponentTestEnvironment* gEnv = nullptr;
+
+namespace {
+
+class Codec2AudioEncHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   private:
+    typedef ::testing::VtsHalHidlTargetTestBase Super;
+
+   public:
+    ::std::string getTestCaseInfo() const override {
+        return ::std::string() +
+                "Component: " + gEnv->getComponent().c_str() + " | " +
+                "Instance: " + gEnv->getInstance().c_str() + " | " +
+                "Res: " + gEnv->getRes().c_str();
+    }
+
+    // google.codec2 Audio test setup
+    virtual void SetUp() override {
+        Super::SetUp();
+        mDisableTest = false;
+        ALOGV("Codec2AudioEncHidlTest SetUp");
+        mClient = android::Codec2Client::CreateFromService(
+            gEnv->getInstance().c_str());
+        ASSERT_NE(mClient, nullptr);
+        mListener.reset(new CodecListener(
+            [this](std::list<std::unique_ptr<C2Work>>& workItems) {
+                handleWorkDone(workItems);
+            }));
+        ASSERT_NE(mListener, nullptr);
+        for (int i = 0; i < MAX_INPUT_BUFFERS; ++i) {
+            mWorkQueue.emplace_back(new C2Work);
+        }
+        mClient->createComponent(gEnv->getComponent().c_str(), mListener,
+                                 &mComponent);
+        ASSERT_NE(mComponent, nullptr);
+
+        std::shared_ptr<C2AllocatorStore> store =
+            android::GetCodec2PlatformAllocatorStore();
+        CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR,
+                                       &mLinearAllocator),
+                 C2_OK);
+        mLinearPool = std::make_shared<C2PooledBlockPool>(mLinearAllocator,
+                                                          mBlockPoolId++);
+        ASSERT_NE(mLinearPool, nullptr);
+
+        mCompName = unknown_comp;
+        struct StringToName {
+            const char* Name;
+            standardComp CompName;
+        };
+        const StringToName kStringToName[] = {
+            {"aac", aac},
+            {"flac", flac},
+            {"opus", opus},
+            {"amrnb", amrnb},
+            {"amrwb", amrwb},
+        };
+        const size_t kNumStringToName =
+            sizeof(kStringToName) / sizeof(kStringToName[0]);
+
+        // Find the component type
+        std::string comp = std::string(gEnv->getComponent());
+        for (size_t i = 0; i < kNumStringToName; ++i) {
+            if (strcasestr(comp.c_str(), kStringToName[i].Name)) {
+                mCompName = kStringToName[i].CompName;
+                break;
+            }
+        }
+        mEos = false;
+        mCsd = false;
+        mFramesReceived = 0;
+        if (mCompName == unknown_comp) mDisableTest = true;
+        if (mDisableTest) std::cout << "[   WARN   ] Test Disabled \n";
+        getInputMaxBufSize();
+    }
+
+    virtual void TearDown() override {
+        if (mComponent != nullptr) {
+            if (::testing::Test::HasFatalFailure()) return;
+            mComponent->release();
+            mComponent = nullptr;
+        }
+        Super::TearDown();
+    }
+    // callback function to process onWorkDone received by Listener
+    void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
+        for (std::unique_ptr<C2Work>& work : workItems) {
+            if (!work->worklets.empty()) {
+                workDone(mComponent, work, mFlushedIndices, mQueueLock,
+                         mQueueCondition, mWorkQueue, mEos, mCsd,
+                         mFramesReceived);
+            }
+        }
+    }
+    enum standardComp {
+        aac,
+        flac,
+        opus,
+        amrnb,
+        amrwb,
+        unknown_comp,
+    };
+
+    bool mEos;
+    bool mCsd;
+    bool mDisableTest;
+    standardComp mCompName;
+    uint32_t mFramesReceived;
+    int32_t mInputMaxBufSize;
+    std::list<uint64_t> mFlushedIndices;
+
+    C2BlockPool::local_id_t mBlockPoolId;
+    std::shared_ptr<C2BlockPool> mLinearPool;
+    std::shared_ptr<C2Allocator> mLinearAllocator;
+
+    std::mutex mQueueLock;
+    std::condition_variable mQueueCondition;
+    std::list<std::unique_ptr<C2Work>> mWorkQueue;
+
+    std::shared_ptr<android::Codec2Client> mClient;
+    std::shared_ptr<android::Codec2Client::Listener> mListener;
+    std::shared_ptr<android::Codec2Client::Component> mComponent;
+
+   protected:
+    static void description(const std::string& description) {
+        RecordProperty("description", description);
+    }
+
+    // In encoder components, fetch the size of input buffer allocated
+    void getInputMaxBufSize() {
+        int32_t bitStreamInfo[1] = {0};
+        std::vector<std::unique_ptr<C2Param>> inParams;
+        c2_status_t status = mComponent->query(
+            {}, {C2StreamMaxBufferSizeInfo::input::PARAM_TYPE}, C2_DONT_BLOCK,
+            &inParams);
+        if (status != C2_OK && inParams.size() == 0) {
+            ALOGE("Query MaxBufferSizeInfo failed => %d", status);
+            ASSERT_TRUE(false);
+        } else {
+            size_t offset = sizeof(C2Param);
+            for (size_t i = 0; i < inParams.size(); ++i) {
+                C2Param* param = inParams[i].get();
+                bitStreamInfo[i] = *(int32_t*)((uint8_t*)param + offset);
+            }
+        }
+        mInputMaxBufSize = bitStreamInfo[0];
+    }
+
+};
+
+void validateComponent(
+    const std::shared_ptr<android::Codec2Client::Component>& component,
+    Codec2AudioEncHidlTest::standardComp compName, bool& disableTest) {
+    // Validate its a C2 Component
+    if (component->getName().find("c2") == std::string::npos) {
+        ALOGE("Not a c2 component");
+        disableTest = true;
+        return;
+    }
+
+    // Validate its not an encoder and the component to be tested is audio
+    if (component->getName().find("decoder") != std::string::npos) {
+        ALOGE("Expected Encoder, given Decoder");
+        disableTest = true;
+        return;
+    }
+    std::vector<std::unique_ptr<C2Param>> queried;
+    c2_status_t c2err =
+        component->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE},
+                         C2_DONT_BLOCK, &queried);
+    if (c2err != C2_OK && queried.size() == 0) {
+        ALOGE("Query media type failed => %d", c2err);
+    } else {
+        std::string inputDomain =
+            ((C2StreamMediaTypeSetting::input*)queried[0].get())->m.value;
+        if (inputDomain.find("audio/") == std::string::npos) {
+            ALOGE("Expected Audio Component");
+            disableTest = true;
+            return;
+        }
+    }
+
+    // Validates component name
+    if (compName == Codec2AudioEncHidlTest::unknown_comp) {
+        ALOGE("Component InValid");
+        disableTest = true;
+        return;
+    }
+    ALOGV("Component Valid");
+}
+
+// Set Default config param.
+bool setupConfigParam(
+    const std::shared_ptr<android::Codec2Client::Component>& component,
+    int32_t nChannels, int32_t nSampleRate) {
+    std::vector<std::unique_ptr<C2SettingResult>> failures;
+    C2StreamSampleRateInfo::input sampleRateInfo(0u, nSampleRate);
+    C2StreamChannelCountInfo::input channelCountInfo(0u, nChannels);
+
+    std::vector<C2Param*> configParam{&sampleRateInfo, &channelCountInfo};
+    c2_status_t status =
+        component->config(configParam, C2_DONT_BLOCK, &failures);
+    if (status == C2_OK && failures.size() == 0u) return true;
+    return false;
+}
+
+// LookUpTable of clips and metadata for component testing
+void GetURLForComponent(Codec2AudioEncHidlTest::standardComp comp, char* mURL) {
+    struct CompToURL {
+        Codec2AudioEncHidlTest::standardComp comp;
+        const char* mURL;
+    };
+    static const CompToURL kCompToURL[] = {
+        {Codec2AudioEncHidlTest::standardComp::aac,
+         "bbb_raw_2ch_48khz_s16le.raw"},
+        {Codec2AudioEncHidlTest::standardComp::amrnb,
+         "bbb_raw_1ch_8khz_s16le.raw"},
+        {Codec2AudioEncHidlTest::standardComp::amrwb,
+         "bbb_raw_1ch_16khz_s16le.raw"},
+        {Codec2AudioEncHidlTest::standardComp::flac,
+         "bbb_raw_2ch_48khz_s16le.raw"},
+        {Codec2AudioEncHidlTest::standardComp::opus,
+         "bbb_raw_2ch_48khz_s16le.raw"},
+    };
+
+    for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) {
+        if (kCompToURL[i].comp == comp) {
+            strcat(mURL, kCompToURL[i].mURL);
+            return;
+        }
+    }
+}
+
+void encodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
+                   std::mutex &queueLock, std::condition_variable& queueCondition,
+                   std::list<std::unique_ptr<C2Work>>& workQueue,
+                   std::list<uint64_t>& flushedIndices,
+                   std::shared_ptr<C2BlockPool>& linearPool,
+                   std::ifstream& eleStream, uint32_t nFrames,
+                   int32_t samplesPerFrame, int32_t nChannels,
+                   int32_t nSampleRate, bool flushed = false,
+                   bool signalEOS = true) {
+    typedef std::unique_lock<std::mutex> ULock;
+
+    uint32_t frameID = 0;
+    uint32_t maxRetry = 0;
+    int bytesCount = samplesPerFrame * nChannels * 2;
+    int32_t timestampIncr =
+        (int)(((float)samplesPerFrame / nSampleRate) * 1000000);
+    uint64_t timestamp = 0;
+    while (1) {
+        if (nFrames == 0) break;
+        uint32_t flags = 0;
+        std::unique_ptr<C2Work> work;
+        // Prepare C2Work
+        while (!work && (maxRetry < MAX_RETRY)) {
+            ULock l(queueLock);
+            if (!workQueue.empty()) {
+                work.swap(workQueue.front());
+                workQueue.pop_front();
+            } else {
+                queueCondition.wait_for(l, TIME_OUT);
+                maxRetry++;
+            }
+        }
+        if (!work && (maxRetry >= MAX_RETRY)) {
+            ASSERT_TRUE(false) << "Wait for generating C2Work exceeded timeout";
+        }
+        if (signalEOS && (nFrames == 1))
+            flags |= C2FrameData::FLAG_END_OF_STREAM;
+        if (flushed) {
+            flags |= SYNC_FRAME;
+            flushed = false;
+        }
+        work->input.flags = (C2FrameData::flags_t)flags;
+        work->input.ordinal.timestamp = timestamp;
+        work->input.ordinal.frameIndex = frameID;
+        {
+            ULock l(queueLock);
+            flushedIndices.emplace_back(frameID);
+        }
+        char* data = (char*)malloc(bytesCount);
+        ASSERT_NE(data, nullptr);
+        eleStream.read(data, bytesCount);
+        ASSERT_EQ(eleStream.gcount(), bytesCount);
+        std::shared_ptr<C2LinearBlock> block;
+        ASSERT_EQ(C2_OK, linearPool->fetchLinearBlock(
+                             bytesCount, {C2MemoryUsage::CPU_READ,
+                                          C2MemoryUsage::CPU_WRITE},
+                             &block));
+        ASSERT_TRUE(block);
+        // Write View
+        C2WriteView view = block->map().get();
+        if (view.error() != C2_OK) {
+            fprintf(stderr, "C2LinearBlock::map() failed : %d", view.error());
+            break;
+        }
+        ASSERT_EQ((size_t)bytesCount, view.capacity());
+        ASSERT_EQ(0u, view.offset());
+        ASSERT_EQ((size_t)bytesCount, view.size());
+
+        memcpy(view.base(), data, bytesCount);
+        work->input.buffers.clear();
+        work->input.buffers.emplace_back(new LinearBuffer(block));
+        work->worklets.clear();
+        work->worklets.emplace_back(new C2Worklet);
+        free(data);
+
+        std::list<std::unique_ptr<C2Work>> items;
+        items.push_back(std::move(work));
+
+        // DO THE DECODING
+        ASSERT_EQ(component->queue(&items), C2_OK);
+        ALOGV("Frame #%d size = %d queued", frameID, bytesCount);
+        nFrames--;
+        timestamp += timestampIncr;
+        frameID++;
+        maxRetry = 0;
+    }
+}
+
+TEST_F(Codec2AudioEncHidlTest, validateCompName) {
+    if (mDisableTest) return;
+    ALOGV("Checks if the given component is a valid audio component");
+    validateComponent(mComponent, mCompName, mDisableTest);
+    ASSERT_EQ(mDisableTest, false);
+}
+
+class Codec2AudioEncEncodeTest
+    : public Codec2AudioEncHidlTest,
+      public ::testing::WithParamInterface<std::pair<bool, int32_t>> {
+};
+
+TEST_P(Codec2AudioEncEncodeTest, EncodeTest) {
+    ALOGV("EncodeTest");
+    if (mDisableTest) return;
+    char mURL[512];
+    strcpy(mURL, gEnv->getRes().c_str());
+    GetURLForComponent(mCompName, mURL);
+    bool signalEOS = GetParam().first;
+    // Ratio w.r.t to mInputMaxBufSize
+    int32_t inputMaxBufRatio = GetParam().second;
+
+    // Setting default sampleRate
+    int32_t nChannels = 2;
+    int32_t nSampleRate = 44100;
+    switch (mCompName) {
+        case aac:
+            nChannels = 2;
+            nSampleRate = 48000;
+            break;
+        case flac:
+            nChannels = 2;
+            nSampleRate = 48000;
+            break;
+        case opus:
+            nChannels = 2;
+            nSampleRate = 48000;
+            break;
+        case amrnb:
+            nChannels = 1;
+            nSampleRate = 8000;
+            break;
+        case amrwb:
+            nChannels = 1;
+            nSampleRate = 16000;
+            break;
+        default:
+            ASSERT_TRUE(false);
+    }
+    int32_t samplesPerFrame =
+        ((mInputMaxBufSize / inputMaxBufRatio) / (nChannels * 2));
+    ALOGV("signalEOS %d mInputMaxBufSize %d samplesPerFrame %d", signalEOS,
+          mInputMaxBufSize, samplesPerFrame);
+
+    if (!setupConfigParam(mComponent, nChannels, nSampleRate)) {
+        std::cout << "[   WARN   ] Test Skipped \n";
+        return;
+    }
+    ASSERT_EQ(mComponent->start(), C2_OK);
+    std::ifstream eleStream;
+    uint32_t numFrames = 16;
+    eleStream.open(mURL, std::ifstream::binary);
+    ASSERT_EQ(eleStream.is_open(), true);
+    ALOGV("mURL : %s", mURL);
+    ASSERT_NO_FATAL_FAILURE(
+        encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                      mFlushedIndices, mLinearPool, eleStream, numFrames,
+                      samplesPerFrame, nChannels, nSampleRate, false,
+                      signalEOS));
+
+    // If EOS is not sent, sending empty input with EOS flag
+    if (!signalEOS) {
+        ASSERT_NO_FATAL_FAILURE(
+            waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, 1));
+        ASSERT_NO_FATAL_FAILURE(
+            testInputBuffer(mComponent, mQueueLock, mWorkQueue,
+                            C2FrameData::FLAG_END_OF_STREAM, false));
+        numFrames += 1;
+    }
+
+    // blocking call to ensures application to Wait till all the inputs are
+    // consumed
+    ASSERT_NO_FATAL_FAILURE(
+        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+    eleStream.close();
+    if (mFramesReceived != numFrames) {
+        ALOGE("Input buffer count and Output buffer count mismatch");
+        ALOGE("framesReceived : %d inputFrames : %u", mFramesReceived, numFrames);
+        ASSERT_TRUE(false);
+    }
+    if ((mCompName == flac || mCompName == opus || mCompName == aac)) {
+        if (!mCsd) {
+            ALOGE("CSD buffer missing");
+            ASSERT_TRUE(false);
+        }
+    }
+    ASSERT_EQ(mEos, true);
+    ASSERT_EQ(mComponent->stop(), C2_OK);
+}
+
+// EncodeTest with EOS / No EOS and inputMaxBufRatio
+// inputMaxBufRatio is ratio w.r.t. to mInputMaxBufSize
+INSTANTIATE_TEST_CASE_P(EncodeTest, Codec2AudioEncEncodeTest,
+                        ::testing::Values(std::make_pair(false, 1),
+                                          std::make_pair(false, 2),
+                                          std::make_pair(true, 1),
+                                          std::make_pair(true, 2)));
+
+
+TEST_F(Codec2AudioEncHidlTest, EOSTest) {
+    description("Test empty input buffer with EOS flag");
+    if (mDisableTest) return;
+    ASSERT_EQ(mComponent->start(), C2_OK);
+
+    typedef std::unique_lock<std::mutex> ULock;
+    std::unique_ptr<C2Work> work;
+    {
+        ULock l(mQueueLock);
+        if (!mWorkQueue.empty()) {
+            work.swap(mWorkQueue.front());
+            mWorkQueue.pop_front();
+        } else {
+            ALOGE("mWorkQueue Empty is not expected at the start of the test");
+            ASSERT_TRUE(false);
+        }
+    }
+    ASSERT_NE(work, nullptr);
+    work->input.flags = (C2FrameData::flags_t)C2FrameData::FLAG_END_OF_STREAM;
+    work->input.ordinal.timestamp = 0;
+    work->input.ordinal.frameIndex = 0;
+    work->input.buffers.clear();
+    work->worklets.clear();
+    work->worklets.emplace_back(new C2Worklet);
+
+    std::list<std::unique_ptr<C2Work>> items;
+    items.push_back(std::move(work));
+    ASSERT_EQ(mComponent->queue(&items), C2_OK);
+    uint32_t queueSize;
+    {
+        ULock l(mQueueLock);
+        queueSize = mWorkQueue.size();
+        if (queueSize < MAX_INPUT_BUFFERS) {
+            mQueueCondition.wait_for(l, TIME_OUT);
+        }
+    }
+    ASSERT_EQ(mEos, true);
+    ASSERT_EQ(mComponent->stop(), C2_OK);
+}
+
+TEST_F(Codec2AudioEncHidlTest, FlushTest) {
+    description("Test Request for flush");
+    if (mDisableTest) return;
+
+    typedef std::unique_lock<std::mutex> ULock;
+    char mURL[512];
+    strcpy(mURL, gEnv->getRes().c_str());
+    GetURLForComponent(mCompName, mURL);
+
+    // Setting default configuration
+    mFlushedIndices.clear();
+    int32_t nChannels = 2;
+    int32_t nSampleRate = 44100;
+    int32_t samplesPerFrame = 1024;
+    switch (mCompName) {
+        case aac:
+            nChannels = 2;
+            nSampleRate = 48000;
+            samplesPerFrame = 1024;
+            break;
+        case flac:
+            nChannels = 2;
+            nSampleRate = 48000;
+            samplesPerFrame = 1152;
+            break;
+        case opus:
+            nChannels = 2;
+            nSampleRate = 48000;
+            samplesPerFrame = 960;
+            break;
+        case amrnb:
+            nChannels = 1;
+            nSampleRate = 8000;
+            samplesPerFrame = 160;
+            break;
+        case amrwb:
+            nChannels = 1;
+            nSampleRate = 16000;
+            samplesPerFrame = 160;
+            break;
+        default:
+            ASSERT_TRUE(false);
+    }
+
+    if (!setupConfigParam(mComponent, nChannels, nSampleRate)) {
+        std::cout << "[   WARN   ] Test Skipped \n";
+        return;
+    }
+    ASSERT_EQ(mComponent->start(), C2_OK);
+
+    std::ifstream eleStream;
+    uint32_t numFramesFlushed = 30;
+    uint32_t numFrames = 128;
+    eleStream.open(mURL, std::ifstream::binary);
+    ASSERT_EQ(eleStream.is_open(), true);
+    ALOGV("mURL : %s", mURL);
+    ASSERT_NO_FATAL_FAILURE(
+        encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                      mFlushedIndices, mLinearPool, eleStream, numFramesFlushed,
+                      samplesPerFrame, nChannels, nSampleRate));
+    std::list<std::unique_ptr<C2Work>> flushedWork;
+    c2_status_t err =
+        mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
+    ASSERT_EQ(err, C2_OK);
+    ASSERT_NO_FATAL_FAILURE(
+        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
+            (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
+    uint64_t frameIndex;
+    {
+        //Update mFlushedIndices based on the index received from flush()
+        ULock l(mQueueLock);
+        for (std::unique_ptr<C2Work>& work : flushedWork) {
+            ASSERT_NE(work, nullptr);
+            frameIndex = work->input.ordinal.frameIndex.peeku();
+            std::list<uint64_t>::iterator frameIndexIt =
+                std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
+                          frameIndex);
+            if (!mFlushedIndices.empty() &&
+                (frameIndexIt != mFlushedIndices.end())) {
+                mFlushedIndices.erase(frameIndexIt);
+                work->input.buffers.clear();
+                work->worklets.clear();
+                mWorkQueue.push_back(std::move(work));
+            }
+        }
+    }
+    mFlushedIndices.clear();
+    ASSERT_NO_FATAL_FAILURE(
+        encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                      mFlushedIndices, mLinearPool, eleStream,
+                      numFrames - numFramesFlushed, samplesPerFrame,
+                      nChannels, nSampleRate, true));
+    eleStream.close();
+    err =
+        mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
+    ASSERT_EQ(err, C2_OK);
+    ASSERT_NO_FATAL_FAILURE(
+        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
+            (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
+    {
+        //Update mFlushedIndices based on the index received from flush()
+        ULock l(mQueueLock);
+        for (std::unique_ptr<C2Work>& work : flushedWork) {
+            ASSERT_NE(work, nullptr);
+            frameIndex = work->input.ordinal.frameIndex.peeku();
+            std::list<uint64_t>::iterator frameIndexIt =
+                std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
+                          frameIndex);
+            if (!mFlushedIndices.empty() &&
+                (frameIndexIt != mFlushedIndices.end())) {
+                mFlushedIndices.erase(frameIndexIt);
+                work->input.buffers.clear();
+                work->worklets.clear();
+                mWorkQueue.push_back(std::move(work));
+            }
+        }
+    }
+    ASSERT_EQ(mFlushedIndices.empty(), true);
+    ASSERT_EQ(mComponent->stop(), C2_OK);
+}
+
+}  // anonymous namespace
+
+int main(int argc, char** argv) {
+    gEnv = new ComponentTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    gEnv->init(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        int status = RUN_ALL_TESTS();
+        LOG(INFO) << "C2 Test result = " << status;
+    }
+    return status;
+}
diff --git a/media/codec2/hidl/1.0/vts/functional/audio/media_c2_audio_hidl_test_common.h b/media/codec2/hidl/1.0/vts/functional/audio/media_c2_audio_hidl_test_common.h
new file mode 100644
index 0000000..4d773ce
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/audio/media_c2_audio_hidl_test_common.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MEDIA_C2_AUDIO_HIDL_TEST_COMMON_H
+#define MEDIA_C2_AUDIO_HIDL_TEST_COMMON_H
+
+
+#endif  // MEDIA_C2_AUDIO_HIDL_TEST_COMMON_H
diff --git a/media/codec2/hidl/1.0/vts/functional/common/Android.bp b/media/codec2/hidl/1.0/vts/functional/common/Android.bp
new file mode 100644
index 0000000..a011ba3
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/common/Android.bp
@@ -0,0 +1,33 @@
+cc_library_static {
+    name: "VtsHalMediaC2V1_0CommonUtil",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "libcodec2-hidl-client-defaults",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/codec2/hidl/client/include",
+    ],
+
+    srcs: [
+        "media_c2_hidl_test_common.cpp",
+    ],
+
+    export_include_dirs: ["."],
+}
+
+cc_defaults {
+    name: "VtsHalMediaC2V1_0Defaults",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "libcodec2-hidl-client-defaults",
+    ],
+
+    static_libs: [
+        "VtsHalMediaC2V1_0CommonUtil",
+    ],
+
+    shared_libs: [
+        "libcodec2_client",
+    ],
+}
diff --git a/media/codec2/hidl/1.0/vts/functional/common/README.md b/media/codec2/hidl/1.0/vts/functional/common/README.md
new file mode 100644
index 0000000..f2f579c
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/common/README.md
@@ -0,0 +1,36 @@
+# Codec2 VTS Hal @ 1.0 tests #
+
+## master :
+Functionality of master is to enumerate all the Codec2 components available in C2 media service.
+
+usage: `VtsHalMediaC2V1_0TargetMasterTest -I default`
+
+## component :
+Functionality of component test is to validate common functionality across all the Codec2 components available in C2 media service. For a standard C2 component, these tests are expected to pass.
+
+usage: `VtsHalMediaC2V1_0TargetComponentTest -I software -C <comp name>`
+
+example: `VtsHalMediaC2V1_0TargetComponentTest -I software -C c2.android.vorbis.decoder`
+
+## audio :
+Functionality of audio test is to validate audio specific functionality of Codec2 components. The resource files for this test are taken from `frameworks/av/media/codec2/hidl/1.0/vts/functional/res`. The path to these files on the device can be specified with `-P`. (If the device path is omitted, `/data/local/tmp/media/` is the default value.)
+
+usage: `VtsHalMediaC2V1_0TargetAudioDecTest -I default -C <comp name> -P <path to resource files>`
+
+usage: `VtsHalMediaC2V1_0TargetAudioEncTest -I software -C <comp name> -P <path to resource files>`
+
+example: `VtsHalMediaC2V1_0TargetAudioDecTest -I software -C c2.android.flac.decoder -P /data/local/tmp/media/`
+
+example: `VtsHalMediaC2V1_0TargetAudioEncTest -I software -C c2.android.opus.encoder -P /data/local/tmp/media/`
+
+## video :
+Functionality of video test is to validate video specific functionality of Codec2 components. The resource files for this test are taken from `frameworks/av/media/codec2/hidl/1.0/vts/functional/res`. The path to these files on the device can be specified with `-P`. (If the device path is omitted, `/data/local/tmp/media/` is the default value.)
+
+usage: `VtsHalMediaC2V1_0TargetVideoDecTest -I default -C <comp name> -P <path to resource files>`
+
+usage: `VtsHalMediaC2V1_0TargetVideoEncTest -I software -C <comp name> -P <path to resource files>`
+
+example: `VtsHalMediaC2V1_0TargetVideoDecTest -I software -C c2.android.avc.decoder -P /data/local/tmp/media/`
+
+example: `VtsHalMediaC2V1_0TargetVideoEncTest -I software -C c2.android.vp9.encoder -P /data/local/tmp/media/`
+
diff --git a/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.cpp b/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.cpp
new file mode 100644
index 0000000..d73b731
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// #define LOG_NDEBUG 0
+#define LOG_TAG "media_c2_hidl_test_common"
+#include <stdio.h>
+
+#include "media_c2_hidl_test_common.h"
+
+// Test the codecs for NullBuffer, Empty Input Buffer with(out) flags set
+void testInputBuffer(
+    const std::shared_ptr<android::Codec2Client::Component>& component,
+    std::mutex& queueLock, std::list<std::unique_ptr<C2Work>>& workQueue,
+    uint32_t flags, bool isNullBuffer) {
+    std::unique_ptr<C2Work> work;
+    {
+        typedef std::unique_lock<std::mutex> ULock;
+        ULock l(queueLock);
+        if (!workQueue.empty()) {
+            work.swap(workQueue.front());
+            workQueue.pop_front();
+        } else {
+            ASSERT_TRUE(false) << "workQueue Empty at the start of test";
+        }
+    }
+    ASSERT_NE(work, nullptr);
+
+    work->input.flags = (C2FrameData::flags_t)flags;
+    work->input.ordinal.timestamp = 0;
+    work->input.ordinal.frameIndex = 0;
+    work->input.buffers.clear();
+    if (isNullBuffer) {
+        work->input.buffers.emplace_back(nullptr);
+    }
+    work->worklets.clear();
+    work->worklets.emplace_back(new C2Worklet);
+
+    std::list<std::unique_ptr<C2Work>> items;
+    items.push_back(std::move(work));
+    ASSERT_EQ(component->queue(&items), C2_OK);
+}
+
+// Wait for all the inputs to be consumed by the plugin.
+void waitOnInputConsumption(std::mutex& queueLock,
+                            std::condition_variable& queueCondition,
+                            std::list<std::unique_ptr<C2Work>>& workQueue,
+                            size_t bufferCount) {
+    typedef std::unique_lock<std::mutex> ULock;
+    uint32_t queueSize;
+    uint32_t maxRetry = 0;
+    {
+        ULock l(queueLock);
+        queueSize = workQueue.size();
+    }
+    while ((maxRetry < MAX_RETRY) && (queueSize < bufferCount)) {
+        ULock l(queueLock);
+        if (queueSize != workQueue.size()) {
+            queueSize = workQueue.size();
+            maxRetry = 0;
+        } else {
+            queueCondition.wait_for(l, TIME_OUT);
+            maxRetry++;
+        }
+    }
+}
+
+// process onWorkDone received by Listener
+void workDone(
+    const std::shared_ptr<android::Codec2Client::Component>& component,
+    std::unique_ptr<C2Work>& work, std::list<uint64_t>& flushedIndices,
+    std::mutex& queueLock, std::condition_variable& queueCondition,
+    std::list<std::unique_ptr<C2Work>>& workQueue, bool& eos, bool& csd,
+    uint32_t& framesReceived) {
+    // handle configuration changes in work done
+    if (work->worklets.front()->output.configUpdate.size() != 0) {
+        ALOGV("Config Update");
+        std::vector<std::unique_ptr<C2Param>> updates =
+            std::move(work->worklets.front()->output.configUpdate);
+        std::vector<C2Param*> configParam;
+        std::vector<std::unique_ptr<C2SettingResult>> failures;
+        for (size_t i = 0; i < updates.size(); ++i) {
+            C2Param* param = updates[i].get();
+            if (param->index() == C2StreamInitDataInfo::output::PARAM_TYPE) {
+                csd = true;
+            } else if ((param->index() ==
+                        C2StreamSampleRateInfo::output::PARAM_TYPE) ||
+                       (param->index() ==
+                        C2StreamChannelCountInfo::output::PARAM_TYPE) ||
+                       (param->index() ==
+                        C2StreamPictureSizeInfo::output::PARAM_TYPE)) {
+                configParam.push_back(param);
+            }
+        }
+        component->config(configParam, C2_DONT_BLOCK, &failures);
+        ASSERT_EQ(failures.size(), 0u);
+    }
+    if (work->worklets.front()->output.flags != C2FrameData::FLAG_INCOMPLETE) {
+        framesReceived++;
+        eos = (work->worklets.front()->output.flags &
+               C2FrameData::FLAG_END_OF_STREAM) != 0;
+        auto frameIndexIt = std::find(flushedIndices.begin(), flushedIndices.end(),
+                                      work->input.ordinal.frameIndex.peeku());
+        ALOGV("WorkDone: frameID received %d",
+              (int)work->worklets.front()->output.ordinal.frameIndex.peeku());
+        work->input.buffers.clear();
+        work->worklets.clear();
+        {
+            typedef std::unique_lock<std::mutex> ULock;
+            ULock l(queueLock);
+            workQueue.push_back(std::move(work));
+            if (!flushedIndices.empty()) {
+                flushedIndices.erase(frameIndexIt);
+            }
+            queueCondition.notify_all();
+        }
+    }
+}
+
+// Return current time in micro seconds
+int64_t getNowUs() {
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+
+    return (int64_t)tv.tv_usec + tv.tv_sec * 1000000ll;
+}
diff --git a/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.h b/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.h
new file mode 100644
index 0000000..db59e54
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.h
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MEDIA_C2_HIDL_TEST_COMMON_H
+#define MEDIA_C2_HIDL_TEST_COMMON_H
+
+#include <codec2/hidl/client.h>
+
+#include <android/hardware/media/c2/1.0/types.h>
+
+#include <C2Component.h>
+#include <C2Config.h>
+#include <getopt.h>
+#include <hidl/HidlSupport.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/foundation/Mutexed.h>
+
+using namespace ::android::hardware::media::c2::V1_0;
+using namespace ::android::hardware::media::c2::V1_0::utils;
+
+using ::android::Mutexed;
+using ::android::hardware::Void;
+using ::android::hardware::Return;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+
+#include <VtsHalHidlTargetTestEnvBase.h>
+
+#define MAX_RETRY 20
+#define TIME_OUT 400ms
+#define MAX_INPUT_BUFFERS 8
+
+/*
+ * Handle Callback functions onWorkDone(), onTripped(),
+ * onError(), onDeath(), onFramesRendered()
+ */
+struct CodecListener : public android::Codec2Client::Listener {
+   public:
+    CodecListener(
+        const std::function<void(std::list<std::unique_ptr<C2Work>>& workItems)> fn =
+            nullptr)
+        : callBack(fn) {}
+    virtual void onWorkDone(
+        const std::weak_ptr<android::Codec2Client::Component>& comp,
+        std::list<std::unique_ptr<C2Work>>& workItems) override {
+        /* TODO */
+        ALOGD("onWorkDone called");
+        (void)comp;
+        if (callBack) callBack(workItems);
+    }
+
+    virtual void onTripped(
+        const std::weak_ptr<android::Codec2Client::Component>& comp,
+        const std::vector<std::shared_ptr<C2SettingResult>>& settingResults)
+        override {
+        /* TODO */
+        (void)comp;
+        (void)settingResults;
+    }
+
+    virtual void onError(
+        const std::weak_ptr<android::Codec2Client::Component>& comp,
+        uint32_t errorCode) override {
+        /* TODO */
+        (void)comp;
+        ALOGD("onError called");
+        if (errorCode != 0) ALOGE("Error : %u", errorCode);
+    }
+
+    virtual void onDeath(
+        const std::weak_ptr<android::Codec2Client::Component>& comp) override {
+        /* TODO */
+        (void)comp;
+    }
+
+    virtual void onInputBufferDone(
+        uint64_t frameIndex, size_t arrayIndex) override {
+        /* TODO */
+        (void)frameIndex;
+        (void)arrayIndex;
+    }
+
+    virtual void onFrameRendered(
+        uint64_t bufferQueueId,
+        int32_t slotId,
+        int64_t timestampNs) override {
+        /* TODO */
+        (void)bufferQueueId;
+        (void)slotId;
+        (void)timestampNs;
+    }
+    // std::mutex mQueueLock;
+    // std::condition_variable mQueueCondition;
+    // std::list<std::unique_ptr<C2Work>> mWorkQueue;
+    std::function<void(std::list<std::unique_ptr<C2Work>>& workItems)> callBack;
+};
+
+// A class for test environment setup
+class ComponentTestEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+   private:
+    typedef ::testing::VtsHalHidlTargetTestEnvBase Super;
+
+   public:
+    virtual void registerTestServices() override {
+        registerTestService<IComponentStore>();
+    }
+
+    ComponentTestEnvironment() : res("/data/local/tmp/media/") {}
+
+    void setComponent(const char* _component) { component = _component; }
+
+    void setInstance(const char* _instance) { instance = _instance; }
+
+    void setRes(const char* _res) { res = _res; }
+
+    const hidl_string getInstance() const { return instance; }
+
+    const hidl_string getComponent() const { return component; }
+
+    const hidl_string getRes() const { return res; }
+
+    int initFromOptions(int argc, char** argv) {
+        static struct option options[] = {
+            {"instance", required_argument, 0, 'I'},
+            {"component", required_argument, 0, 'C'},
+            {"res", required_argument, 0, 'P'},
+            {0, 0, 0, 0}};
+
+        while (true) {
+            int index = 0;
+            int c = getopt_long(argc, argv, "I:C:P:", options, &index);
+            if (c == -1) {
+                break;
+            }
+
+            switch (c) {
+                case 'I':
+                    setInstance(optarg);
+                    break;
+                case 'C':
+                    setComponent(optarg);
+                    break;
+                case 'P':
+                    setRes(optarg);
+                    break;
+                case '?':
+                    break;
+            }
+        }
+
+        if (optind < argc) {
+            fprintf(stderr,
+                    "unrecognized option: %s\n\n"
+                    "usage: %s <gtest options> <test options>\n\n"
+                    "test options are:\n\n"
+                    "-I, --instance: software for C2 components, else default\n"
+                    "-C, --component: C2 component to test\n"
+                    "-P, --res: Resource files directory location\n",
+                    argv[optind ?: 1], argv[0]);
+            return 2;
+        }
+        return 0;
+    }
+
+   private:
+    hidl_string instance;
+    hidl_string component;
+    hidl_string res;
+};
+
+/*
+ * common functions declarations
+ */
+void testInputBuffer(
+    const std::shared_ptr<android::Codec2Client::Component>& component,
+    std::mutex& queueLock, std::list<std::unique_ptr<C2Work>>& workQueue,
+    uint32_t flags, bool isNullBuffer);
+
+void waitOnInputConsumption(std::mutex& queueLock,
+                            std::condition_variable& queueCondition,
+                            std::list<std::unique_ptr<C2Work>>& workQueue,
+                            size_t bufferCount = MAX_INPUT_BUFFERS);
+
+void workDone(
+    const std::shared_ptr<android::Codec2Client::Component>& component,
+    std::unique_ptr<C2Work>& work, std::list<uint64_t>& flushedIndices,
+    std::mutex& queueLock, std::condition_variable& queueCondition,
+    std::list<std::unique_ptr<C2Work>>& workQueue, bool& eos, bool& csd,
+    uint32_t& framesReceived);
+
+int64_t getNowUs();
+
+#endif  // MEDIA_C2_HIDL_TEST_COMMON_H
diff --git a/media/codec2/hidl/1.0/vts/functional/component/Android.bp b/media/codec2/hidl/1.0/vts/functional/component/Android.bp
new file mode 100644
index 0000000..7ec64ee
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/component/Android.bp
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+cc_test {
+    name: "VtsHalMediaC2V1_0TargetComponentTest",
+    defaults: ["VtsHalMediaC2V1_0Defaults"],
+    srcs: ["VtsHalMediaC2V1_0TargetComponentTest.cpp"],
+}
+
diff --git a/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp b/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp
new file mode 100644
index 0000000..9dc541c
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "codec2_hidl_hal_component_test"
+
+#include <android-base/logging.h>
+#include <gtest/gtest.h>
+
+#include <C2Config.h>
+#include <codec2/hidl/client.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+#include "media_c2_hidl_test_common.h"
+
+/* Time_Out for start(), stop(), reset(), release(), flush(), queue() are
+ * defined in hardware/interfaces/media/c2/1.0/IComponent.hal. Adding 50ms
+ * extra in case of timeout is 500ms, 1ms extra in case timeout is 1ms/5ms. All
+ * timeout is calculated in us.
+ */
+#define START_TIME_OUT                  550000
+#define STOP_TIME_OUT                   550000
+#define RESET_TIME_OUT                  550000
+#define RELEASE_TIME_OUT                550000
+#define FLUSH_TIME_OUT                  6000
+#define QUEUE_TIME_OUT                  2000
+
+// Time_Out for config(), query(), querySupportedParams() are defined in
+// hardware/interfaces/media/c2/1.0/IConfigurable.hal.
+#define CONFIG_TIME_OUT                 6000
+#define QUERY_TIME_OUT                  6000
+#define QUERYSUPPORTEDPARAMS_TIME_OUT   2000
+
+#define CHECK_TIMEOUT(timeConsumed, TIME_OUT, FuncName)          \
+    if (timeConsumed > TIME_OUT) {                               \
+        ALOGW(                                                   \
+            "TIMED_OUT %s  timeConsumed=%" PRId64 " us is "      \
+            "greater than threshold %d us",                      \
+            FuncName, timeConsumed, TIME_OUT);                   \
+    }
+
+static ComponentTestEnvironment* gEnv = nullptr;
+
+namespace {
+
+// google.codec2 Component test setup
+class Codec2ComponentHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   private:
+    typedef ::testing::VtsHalHidlTargetTestBase Super;
+
+   public:
+    virtual void SetUp() override {
+        Super::SetUp();
+        mEos = false;
+        mClient = android::Codec2Client::CreateFromService(
+            gEnv->getInstance().c_str());
+        ASSERT_NE(mClient, nullptr);
+        mListener.reset(new CodecListener(
+            [this](std::list<std::unique_ptr<C2Work>>& workItems) {
+                handleWorkDone(workItems);
+            }));
+        ASSERT_NE(mListener, nullptr);
+        mClient->createComponent(gEnv->getComponent().c_str(), mListener,
+                                 &mComponent);
+        ASSERT_NE(mComponent, nullptr);
+        for (int i = 0; i < MAX_INPUT_BUFFERS; ++i) {
+            mWorkQueue.emplace_back(new C2Work);
+        }
+    }
+
+    virtual void TearDown() override {
+        if (mComponent != nullptr) {
+            // If you have encountered a fatal failure, it is possible that
+            // freeNode() will not go through. Instead of hanging the app.
+            // let it pass through and report errors
+            if (::testing::Test::HasFatalFailure()) return;
+            mComponent->release();
+            mComponent = nullptr;
+        }
+        Super::TearDown();
+    }
+    // callback function to process onWorkDone received by Listener
+    void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
+        for (std::unique_ptr<C2Work>& work : workItems) {
+            if (!work->worklets.empty()) {
+                bool mCsd = false;
+                uint32_t mFramesReceived = 0;
+                std::list<uint64_t> mFlushedIndices;
+                workDone(mComponent, work, mFlushedIndices, mQueueLock, mQueueCondition,
+                         mWorkQueue, mEos, mCsd, mFramesReceived);
+            }
+        }
+    }
+
+    bool mEos;
+    std::mutex mQueueLock;
+    std::condition_variable mQueueCondition;
+    std::list<std::unique_ptr<C2Work>> mWorkQueue;
+
+    std::shared_ptr<android::Codec2Client> mClient;
+    std::shared_ptr<android::Codec2Client::Listener> mListener;
+    std::shared_ptr<android::Codec2Client::Component> mComponent;
+
+   protected:
+    static void description(const std::string& description) {
+        RecordProperty("description", description);
+    }
+};
+
+// Test Empty Flush
+TEST_F(Codec2ComponentHidlTest, EmptyFlush) {
+    ALOGV("Empty Flush Test");
+    c2_status_t err = mComponent->start();
+    ASSERT_EQ(err, C2_OK);
+
+    std::list<std::unique_ptr<C2Work>> flushedWork;
+    err = mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
+    ASSERT_EQ(err, C2_OK);
+
+    err = mComponent->stop();
+    ASSERT_EQ(err, C2_OK);
+    // Empty Flush should not return any work
+    ASSERT_EQ(flushedWork.size(), 0u);
+}
+
+// Test Queue Empty Work
+TEST_F(Codec2ComponentHidlTest, QueueEmptyWork) {
+    ALOGV("Queue Empty Work Test");
+    c2_status_t err = mComponent->start();
+    ASSERT_EQ(err, C2_OK);
+
+    // Queueing an empty WorkBundle
+    std::list<std::unique_ptr<C2Work>> workList;
+    mComponent->queue(&workList);
+
+    err = mComponent->reset();
+    ASSERT_EQ(err, C2_OK);
+}
+
+// Test Component Configuration
+TEST_F(Codec2ComponentHidlTest, Config) {
+    ALOGV("Configuration Test");
+
+    C2String name = mComponent->getName();
+    EXPECT_NE(name.empty(), true) << "Invalid Component Name";
+
+    c2_status_t err = C2_OK;
+    std::vector<std::unique_ptr<C2Param>> queried;
+    std::vector<std::unique_ptr<C2SettingResult>> failures;
+
+    // Query supported params by the component
+    std::vector<std::shared_ptr<C2ParamDescriptor>> params;
+    err = mComponent->querySupportedParams(&params);
+    ASSERT_EQ(err, C2_OK);
+    ALOGV("Number of total params - %zu", params.size());
+
+    // Query and config all the supported params
+    for (std::shared_ptr<C2ParamDescriptor> p : params) {
+        ALOGD("Querying index %d", (int)p->index());
+        err = mComponent->query({}, {p->index()}, C2_DONT_BLOCK, &queried);
+        EXPECT_NE(queried.size(), 0u);
+        EXPECT_EQ(err, C2_OK);
+        err = mComponent->config({queried[0].get()}, C2_DONT_BLOCK, &failures);
+        ASSERT_EQ(err, C2_OK);
+        ASSERT_EQ(failures.size(), 0u);
+    }
+}
+
+// Test Multiple Start Stop Reset Test
+TEST_F(Codec2ComponentHidlTest, MultipleStartStopReset) {
+    ALOGV("Multiple Start Stop and Reset Test");
+
+    for (size_t i = 0; i < MAX_RETRY; i++) {
+        mComponent->start();
+        mComponent->stop();
+    }
+
+    ASSERT_EQ(mComponent->start(), C2_OK);
+
+    for (size_t i = 0; i < MAX_RETRY; i++) {
+        mComponent->reset();
+    }
+
+    ASSERT_EQ(mComponent->start(), C2_OK);
+    ASSERT_EQ(mComponent->stop(), C2_OK);
+
+    // Second stop should return error
+    ASSERT_NE(mComponent->stop(), C2_OK);
+}
+
+// Test Component Release API
+TEST_F(Codec2ComponentHidlTest, MultipleRelease) {
+    ALOGV("Multiple Release Test");
+    c2_status_t err = mComponent->start();
+    ASSERT_EQ(err, C2_OK);
+
+    // Query Component Domain Type
+    std::vector<std::unique_ptr<C2Param>> queried;
+    err = mComponent->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE},
+                            C2_DONT_BLOCK, &queried);
+    EXPECT_NE(queried.size(), 0u);
+
+    // Configure Component Domain
+    std::vector<std::unique_ptr<C2SettingResult>> failures;
+    C2PortMediaTypeSetting::input* portMediaType =
+        C2PortMediaTypeSetting::input::From(queried[0].get());
+    err = mComponent->config({portMediaType}, C2_DONT_BLOCK, &failures);
+    ASSERT_EQ(err, C2_OK);
+    ASSERT_EQ(failures.size(), 0u);
+
+    for (size_t i = 0; i < MAX_RETRY; i++) {
+        mComponent->release();
+    }
+}
+
+class Codec2ComponentInputTests : public Codec2ComponentHidlTest,
+        public ::testing::WithParamInterface<std::pair<uint32_t, bool> > {
+};
+
+TEST_P(Codec2ComponentInputTests, InputBufferTest) {
+    description("Tests for different inputs");
+
+    uint32_t flags = GetParam().first;
+    bool isNullBuffer = GetParam().second;
+    if (isNullBuffer) ALOGD("Testing for null input buffer with flag : %u", flags);
+    else ALOGD("Testing for empty input buffer with flag : %u", flags);
+    mEos = false;
+    ASSERT_EQ(mComponent->start(), C2_OK);
+    ASSERT_NO_FATAL_FAILURE(testInputBuffer(
+        mComponent, mQueueLock, mWorkQueue, flags, isNullBuffer));
+
+    ALOGD("Waiting for input consumption");
+    ASSERT_NO_FATAL_FAILURE(
+        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+
+    if (flags == C2FrameData::FLAG_END_OF_STREAM) ASSERT_EQ(mEos, true);
+    ASSERT_EQ(mComponent->stop(), C2_OK);
+    ASSERT_EQ(mComponent->reset(), C2_OK);
+}
+
+INSTANTIATE_TEST_CASE_P(NonStdInputs, Codec2ComponentInputTests, ::testing::Values(
+    std::make_pair(0, true),
+    std::make_pair(C2FrameData::FLAG_END_OF_STREAM, true),
+    std::make_pair(0, false),
+    std::make_pair(C2FrameData::FLAG_CODEC_CONFIG, false),
+    std::make_pair(C2FrameData::FLAG_END_OF_STREAM, false)));
+
+// Test API's Timeout
+TEST_F(Codec2ComponentHidlTest, Timeout) {
+    ALOGV("Timeout Test");
+    c2_status_t err = C2_OK;
+
+    int64_t startTime = getNowUs();
+    err = mComponent->start();
+    int64_t timeConsumed = getNowUs() - startTime;
+    CHECK_TIMEOUT(timeConsumed, START_TIME_OUT, "start()");
+    ALOGV("mComponent->start() timeConsumed=%" PRId64 " us", timeConsumed);
+    ASSERT_EQ(err, C2_OK);
+
+    startTime = getNowUs();
+    err = mComponent->reset();
+    timeConsumed = getNowUs() - startTime;
+    CHECK_TIMEOUT(timeConsumed, RESET_TIME_OUT, "reset()");
+    ALOGV("mComponent->reset() timeConsumed=%" PRId64 " us", timeConsumed);
+    ASSERT_EQ(err, C2_OK);
+
+    err = mComponent->start();
+    ASSERT_EQ(err, C2_OK);
+
+    // Query supported params by the component
+    std::vector<std::shared_ptr<C2ParamDescriptor>> params;
+    startTime = getNowUs();
+    err = mComponent->querySupportedParams(&params);
+    timeConsumed = getNowUs() - startTime;
+    CHECK_TIMEOUT(timeConsumed, QUERYSUPPORTEDPARAMS_TIME_OUT,
+                  "querySupportedParams()");
+    ALOGV("mComponent->querySupportedParams() timeConsumed=%" PRId64 " us",
+          timeConsumed);
+    ASSERT_EQ(err, C2_OK);
+
+    std::vector<std::unique_ptr<C2Param>> queried;
+    std::vector<std::unique_ptr<C2SettingResult>> failures;
+    // Query and config all the supported params
+    for (std::shared_ptr<C2ParamDescriptor> p : params) {
+        startTime = getNowUs();
+        err = mComponent->query({}, {p->index()}, C2_DONT_BLOCK, &queried);
+        timeConsumed = getNowUs() - startTime;
+        CHECK_TIMEOUT(timeConsumed, QUERY_TIME_OUT, "query()");
+        EXPECT_NE(queried.size(), 0u);
+        EXPECT_EQ(err, C2_OK);
+        ALOGV("mComponent->query() for %s timeConsumed=%" PRId64 " us",
+              p->name().c_str(), timeConsumed);
+
+        startTime = getNowUs();
+        err = mComponent->config({queried[0].get()}, C2_DONT_BLOCK, &failures);
+        timeConsumed = getNowUs() - startTime;
+        CHECK_TIMEOUT(timeConsumed, CONFIG_TIME_OUT, "config()");
+        ASSERT_EQ(err, C2_OK);
+        ASSERT_EQ(failures.size(), 0u);
+        ALOGV("mComponent->config() for %s timeConsumed=%" PRId64 " us",
+              p->name().c_str(), timeConsumed);
+    }
+
+    std::list<std::unique_ptr<C2Work>> workList;
+    startTime = getNowUs();
+    err = mComponent->queue(&workList);
+    timeConsumed = getNowUs() - startTime;
+    ALOGV("mComponent->queue() timeConsumed=%" PRId64 " us", timeConsumed);
+    CHECK_TIMEOUT(timeConsumed, QUEUE_TIME_OUT, "queue()");
+
+    startTime = getNowUs();
+    err = mComponent->flush(C2Component::FLUSH_COMPONENT, &workList);
+    timeConsumed = getNowUs() - startTime;
+    ALOGV("mComponent->flush() timeConsumed=%" PRId64 " us", timeConsumed);
+    CHECK_TIMEOUT(timeConsumed, FLUSH_TIME_OUT, "flush()");
+
+    startTime = getNowUs();
+    err = mComponent->stop();
+    timeConsumed = getNowUs() - startTime;
+    ALOGV("mComponent->stop() timeConsumed=%" PRId64 " us", timeConsumed);
+    CHECK_TIMEOUT(timeConsumed, STOP_TIME_OUT, "stop()");
+    ASSERT_EQ(err, C2_OK);
+
+    startTime = getNowUs();
+    err = mComponent->release();
+    timeConsumed = getNowUs() - startTime;
+    ALOGV("mComponent->release() timeConsumed=%" PRId64 " us", timeConsumed);
+    CHECK_TIMEOUT(timeConsumed, RELEASE_TIME_OUT, "release()");
+    ASSERT_EQ(err, C2_OK);
+
+}
+
+}  // anonymous namespace
+
+// TODO: Add test for Invalid work,
+// TODO: Add test for Invalid states
+int main(int argc, char** argv) {
+    gEnv = new ComponentTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    gEnv->init(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        status = RUN_ALL_TESTS();
+        LOG(INFO) << "C2 Test result = " << status;
+    }
+    return status;
+}
diff --git a/media/codec2/hidl/1.0/vts/functional/master/Android.bp b/media/codec2/hidl/1.0/vts/functional/master/Android.bp
new file mode 100644
index 0000000..53e323e
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/master/Android.bp
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+cc_test {
+    name: "VtsHalMediaC2V1_0TargetMasterTest",
+    defaults: ["VtsHalMediaC2V1_0Defaults"],
+    srcs: ["VtsHalMediaC2V1_0TargetMasterTest.cpp"],
+}
+
diff --git a/media/codec2/hidl/1.0/vts/functional/master/VtsHalMediaC2V1_0TargetMasterTest.cpp b/media/codec2/hidl/1.0/vts/functional/master/VtsHalMediaC2V1_0TargetMasterTest.cpp
new file mode 100644
index 0000000..e88fbc7
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/master/VtsHalMediaC2V1_0TargetMasterTest.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "codec2_hidl_hal_master_test"
+
+#include <android-base/logging.h>
+#include <gtest/gtest.h>
+
+#include <codec2/hidl/client.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+#include "media_c2_hidl_test_common.h"
+
+static ComponentTestEnvironment* gEnv = nullptr;
+
+namespace {
+
+// google.codec2 Master test setup
+class Codec2MasterHalTest : public ::testing::VtsHalHidlTargetTestBase {
+   private:
+    typedef ::testing::VtsHalHidlTargetTestBase Super;
+
+   public:
+    virtual void SetUp() override {
+        Super::SetUp();
+        mClient = android::Codec2Client::CreateFromService(
+            gEnv->getInstance().c_str());
+        ASSERT_NE(mClient, nullptr);
+    }
+
+   protected:
+    static void description(const std::string& description) {
+        RecordProperty("description", description);
+    }
+
+    std::shared_ptr<android::Codec2Client> mClient;
+};
+
+void displayComponentInfo(const std::vector<C2Component::Traits>& compList) {
+    for (size_t i = 0; i < compList.size(); i++) {
+        std::cout << compList[i].name << " | " << compList[i].domain;
+        std::cout << " | " << compList[i].kind << "\n";
+    }
+}
+
+// List Components
+TEST_F(Codec2MasterHalTest, ListComponents) {
+    ALOGV("ListComponents Test");
+
+    C2String name = mClient->getName();
+    EXPECT_NE(name.empty(), true) << "Invalid Codec2Client Name";
+
+    // Get List of components from all known services
+    const std::vector<C2Component::Traits> listTraits =
+        mClient->ListComponents();
+
+    if (listTraits.size() == 0)
+        ALOGE("Warning, ComponentInfo list empty");
+    else {
+        (void)displayComponentInfo;
+        for (size_t i = 0; i < listTraits.size(); i++) {
+            std::shared_ptr<android::Codec2Client::Listener> listener;
+            std::shared_ptr<android::Codec2Client::Component> component;
+            listener.reset(new CodecListener());
+            ASSERT_NE(listener, nullptr);
+
+            // Create component from all known services
+            component = mClient->CreateComponentByName(
+                listTraits[i].name.c_str(), listener, &mClient);
+            ASSERT_NE(component, nullptr) << "Create component failed for "
+                                          << listTraits[i].name.c_str();
+        }
+    }
+}
+
+}  // anonymous namespace
+
+int main(int argc, char** argv) {
+    gEnv = new ComponentTestEnvironment();
+    ::testing::InitGoogleTest(&argc, argv);
+    gEnv->init(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        status = RUN_ALL_TESTS();
+        LOG(INFO) << "C2 Test result = " << status;
+    }
+    return status;
+}
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_352x288_420p_30fps_32frames.yuv b/media/codec2/hidl/1.0/vts/functional/res/bbb_352x288_420p_30fps_32frames.yuv
new file mode 100644
index 0000000..b5a3e4b
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_352x288_420p_30fps_32frames.yuv
@@ -0,0 +1 @@
+ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÒÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;<?;?<=<?>?A=AA>CCDB@A>:;?DDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌÌÌËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFK=8765999<>9?<C9;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;>BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÔÓÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937677<;>:=:::88:;;88::;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::>;D<=:<<98:9::9;<::;9><>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA=366:;<8C<AA><A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖËËËÌËËËËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9>CE?<;999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNG¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖËËÌÌËËËËËËËËËËËËÊÊËËËËÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÚÛÛÛÙÙÙÙÙÙÙÙÚÚÚÚÚÚØÖ×××××××Ø×Ø×××ÚÛÚÚÚÚÚÚÚÛÜÛÛÛÜÜÜÜÜÜÜÜÝÜÛÛÛÛÚÔÓÓÓÓÓÓÓÓÓÓÔÔÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXdIILN@99:3;@<7=9AC=@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMMF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÏÐÏÏÏÏÏÏÏÏÏÏÏÏÖÞÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`ccccccccccdde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¹´‹‹‹‹‹‹‹‹‹ŠŠŠ‹‡‚‚‚‚‚‚‚‘ÓÓÓÓÓÓÓÒÒÒÒÓÓÓÛâáââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑrliNRbLLVM<::77>C?8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKPFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÌÐÒÒÒÒÒÒÒÒÒÒÒÒÑÞëëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§£££££££££££¤œXRSSSSSSSSSSSTMCDDDDDDCCCDC?]ÑÓÓÓÓÓÓÒÒÒÒÒÒÒßêëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘wliJN_MRUM><<7;@C>6:7>?;=B@9<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÌÌÐÒÒÒÒÒÒÒÒÒÒÒÒÑÝêééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤¦ž\VWWWWWWWWWWWXQIIIIIIIIHHHHD`ÐÓÒÒÒÒÒÒÒÒÒÒÒÑßêêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;>@@8:;8<<<;>::;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÍÏÑÑÒÒÒÒÒÒÑÒÑÑÐÜèççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbabaabbbbbb^Œ¬©©©©©©©©©©©ª£gabbbbbbbbbbbb\TTTTTTTTTTTUQkÐÒÒÒÒÒÒÒÒÒÒÒÒÑßéééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB>;=:9::=<;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÍÎÎÎÎÎÎÎÎÎÍÌÌÌÎÏÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÎÎÎÎÎÎÎÍËÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÅÆÆÆËÌËÌËÌÌÌÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÑÍÌÌÌÌÌÌÌÌÌËËËËÊÊÊÊÊÊÊÊËËÊÊËËÍÕÕÕÖÖÖÖÖÖÖÖÖÖÕ×ØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<7@A<=8:;898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÎÒÓÏÏÏÒÔÏÏÒÔÕÔÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÐÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÕÖÖÖÖÖÖ××××××××ÖÖÖÖÖÖÖ×××××××××××ØØ×ÖÖÖÖÖ×××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?89:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšÌÏÎÎÎÎÎÒ«œÏÐÓ¹ŸÑМ‚„ŠÈÏÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLB@==<=:<=B>BB@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÎÒ¶œ¥£Õ²—˜µ¶“¸¹¯¢ÒÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?><7:>9?D>@98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÏ͜‘Ã¢¦«Ò‘}~¯°ÑÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>><<96?B?B9648:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ˜ªÔÏÏÏÑ¿˜ ›²­È†™­ÕÒ͞žÃÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>?>:8E@?B;749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­˜ªÔÏÏÏÓ´™–ª¸¤Û£˜­ÕÓÀ  ÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<=<964:98::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯Ê £¿Êœ¥Œ§­Øª™ªÔÏÏÏÔ«š~£ Ø¡˜­ÕÕ°¢©ÔÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>9<97659:6:<;7<@@<::=:<?>=<9@<<::9?@==<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÔ¬›§‹–¡Ù¡˜­ÕÔ£¡ºÔÑÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖ×××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CGDAA8;?<=;<<7558968;:9<:>?<==9<?>=::>9=::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÓ¶²²¥™©Ú¡˜®Ö͞ŸÉÒÑÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ђl]\oghb]OF?HHFE@<<>><==<756:96:;::;8@?:<<9<>=;;:?9?:;9=>=><;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦ÕÄ¢™–›´Ú£˜¯ØŸ¡ÒÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;557<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸« ÇÕ¢«¤šÌØ¡™­Ú²¤¦ÖÒÒÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKK@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÓÓȑ´ÕÔ±„ÃÖ¹ƒ¿ÕÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUij[L_MJLJULFB<<?FEGKH=667:979:;:<=9>99:8;=>>A>=9<<:=>>;=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÔÈÁÕÑÒÑÃÕÒÑÂÓÒÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?ADLL@>775;8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÑÓÔÒÒÒÒÕÓÓÓÕÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEJ==786977899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9599:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EIKAALD??;9889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEHIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDCI;AA;<886586987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGJB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFID<AA<;876797799=?A?<:9@?<>B?:8776=?@@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD88867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE><HF89757875898;>>=;89A>=@?A>7596;>AB??@@AB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCDECALH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HQA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßßààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELBA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<<DDDD>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGHNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAD?@;<88996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDE><<8:87995686673:>;>=7:>99996::87<CEG??;?>@=>A<;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;99:86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AD?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€iixsg~‰‰xp‚†{w}~…Š¼ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkqty€‚wt|„‚}sp€Šx‚yƒÈÞÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxu|v}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsnupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9886543956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µ¶¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿½¾¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78473156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;;>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»º¹¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¸¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjcmgb\XQPQKTJB:IQ?A7<94:565454688686;:9<==;:86688:767>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®¯³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸¸·······¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPF>8;727967443588797;9:==<::974:98668??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹º¹¹¸··¶µµ¶¶¶······¶¶µ¶¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿœ¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269664737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³µµ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´µ´¶¶··¶µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶······¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸···¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™™š™—————–™›˜™™™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B@?C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­«¬¯°±¯¯°²µµ¶·µµ¶µµµµµ¶µ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©©¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­®«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶···¸·¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜™š›œœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@AA:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬«ª§¥¥¥¥¥¦¨¨¨¨¨¥§¨¨§¨¨§¨¨©ª§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸·¶······¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637465738:::::<=::A<6=8378837;@??@@:BEC@BDCA?;;@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¥¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥£¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¥§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§¦¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©«««¬ªªª¨¦¦¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤¤£¢¢£¢¡ ŸŸžžœœœœœžŸ ¢¡¢£££¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¥¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™˜——––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@?BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž¤¤¡ŸžŸ  žœœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747578;=8::99;=;;89>6789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥£¢¡¡¡¡¢£¥§¦¦§¬«§¦ œœ›¡¡ž››šœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥¤¥¤¥¥¦¨¨§¨§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡££££¢£¥¦¦¦§§§¦Ÿ›š›¢ š–—•š›š——˜™šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¦¤£¡  ŸŸ¡¡Ÿ  š˜˜™›œ¡¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364689:89788:<;<9;;::67899>?@><=@>@:9@A?=A?>AA>AA?:9=>:P Ÿœ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~ššwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§§¥¤¢¡£§¦¥¥£¢¥¦¦¥¦§¦¦ ›™›¡ —’“’—šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¢¢¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB?DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¤¦¦¥¥¦§¦¦¢œŸ¡Ÿ—‘‘”—š˜–—–˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸŸŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡  Ÿ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846799=88;:;?;:;<:9:7768;<;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¦¦¥¤¦§¦¥¥¦¦¥¥£  ¡¡ ™’–›™žœ–———™›œœœšš™—™››žŸœœ™™šœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡ ¡ŸŸœœœœžžš—––•”““’’’’‘’’“’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:737959989<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš›››šœ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢£¢£¤¤¦¦¥¤¤£¢¡¡žœ›•’”˜œš›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œŸ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸžŸ žœ››œœœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::78:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸŸ  ¡¢££¤¤¤¤¢¡¡ž›š™—¡µž™™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢Ÿ›ž¡¢£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;866:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š™—˜™œœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œ››œŸžœœœœŸ   ¡¡¡    ¢¤¡¢¢¡¡ žœ›››™Ÿ«›œš›™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86:756::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥¤¤¤¢  Ÿ Ÿ ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¢¢¢¡ ¥³¬  ŸŸžœ™™šš›®jvž›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›šœ›š›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>99;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤¤¢ ŸŸ›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ ŸžŸ ¡ Ÿ¦’›«Ÿ  ž›š™š™¨„DŸžžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›š›š›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›šš››™˜™™˜——–•””“‘‘‘’“““’““”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9<<>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœœœž žbœ¦žžœšš›œ¡£QGƒ žœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœš››››š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8:;<=:<>9?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš›››››š¦f]£ ›š™›œ®uIL† œœœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\Q<@<68CVHDB:8;:>;7796=:99647:;<>9::;>;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™™˜¤€Rx¢™™š› ¤_VN‡¡œœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œ›››œœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡ ¡ŸŸŸŸ™š›œš™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd\\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?=CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š›››œœ›˜˜™ ˆ[_”š™›œœ£dZL¢žžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[[LF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ›››››››™˜™Ÿ—]]v—šœ¢dYM~¢žžžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž››šœœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ›››››œš˜™™š`a`€–œž˜tcUN€¢ŸŸŸžž¡ žžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_^]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜˜——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜™™Ÿi^[eœœžŒj_PR†ž›œœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±´­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=:F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B@AB>>;CDD@CC>>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œš››œ›˜™š˜˜™›šš—“shaTv“—œ‡\VPWŠ’Ž’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨ª¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‘‹‘‹Œ‘‘Ž’šž’} £–¤œnLOc††‚‹†‰Š‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜ž—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VQQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;?<:=:>BA8?<:?86429;B@?B>=8@B??@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹Œ†Š‹‹‰‡„†ƒ€„ Žl–¥•Ÿ€‰_r€‚’†„„…ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=99974869388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A>?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹Ž‹‰‰…‚‚~€¢‹|nRuœŒŒZq}|~}|†Ž‹†”‘‹—”—’˜¡–ž–•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¦›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>89875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ‚†‹‡ˆ…„ˆˆŠ…€‚}˜šwXOLp”†‚L`oqwˆ…ŠŽ‹™œ””” ššŸ¢­±®©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPEMISWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}€~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‘‹ˆŒ‹‹‡‘£U/0=w‡wvAD^km„‰‰””˜•œšž¨®²°°µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWMO_^\NUUbQDTM;?9<895875795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš™ž¡“—›¡š›¢¦œgAZH;wykgE/8[ls‹˜šŒ”š—œ› ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUJTOOJDPK_bXZQ\T`MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ªª©§¢¥¨©«©©¯Ko¡xA{wcbPPZG`nŠ¡¡¤ž›š¤§¤©«®¬¥¤¨«¯±´®ª¬®³¯¬¬´´´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdWOYKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®««¬¤¡¢¦©§¨£x`¿Ö¦C{Œ€uOmŽuRd£¨§ ¢¡®¬«ª§­®¨¥¤©©ª©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_VZNRNQOSe\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢™œ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨§¦¨©§©©¤§§™¤¥£¢b½À¯wž£š”eLaxmQt•¢¢ ¡Ÿ¡¡¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOWP^edlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@<><99<ABEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤ ¢¡¢§¡¦®¦¦žj„œº¦Ð¡™±¨XL¬“Se ž  ž £™–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvxb_\UYQUW[c_s_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?B?:8:>?C@DA:;>=@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯««¬¨¨«¯©¨ª¨¢ ¡¨ª­±²¯«¢¢†w~}rÎɱ›§¯kUª°bZ‡¦Ÿ¥¢¡Ÿ¢˜•ž›ŸŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸŸ¡¦¢›—’šš •|wo}yf[[`_Z\U\hdocmiib^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9><B??ADB9:€ž¤§¡ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£ £ªª§¯··´µ¶³­®­†ƒnÍ¹•¢—tTozsn{•¦ª§£Ÿž£›¡š–ž¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¡™˜¥ ¤§ª©¨ª­¬¥©¤¥©§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§£¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›€wrvxjb[__\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>AE@=9;@B>C=;9>9@@@?BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢ «²·»»»¹¹Á¸´µ ˆydYŸ·À¦¨ˆwkqoxxz}†Ž’˜œ¢¥¦«¥¤˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨©«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥ ¡¨§¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†vxyxc[RYT__amhvkqhiibZSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;>CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶´º±ª®´±°²´µ·ÁÆÌÏÎÌɾ³¤sfRD‹—‰‰ˆ~xqngflikqrqqrt|Œ©ÄÄ»¢§ª¬§«©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¡¤§§¡Ÿž–“œ —™’ŒŒ—–Ÿ›–œšœš“–””˜“š˜Š‹‡€€|‚xa^YSaiaftotitdidb[LK>:9898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÄÇÃÅÇÛããÚ˼¯¤—ˆtYZQCizlounkeeYW^X\ciihe`h‰´ÀÀ¹©¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡ž¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`b_^kcbnxuwom[bRV\MG;<97979:7444143768<;:<<@@=@?>?>::9:7:?>EEE<==@BBBAA;<8@CC@D?;5^ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–••‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±°§¼¼¾ÅÄÆÉÇÅƾÍÑÕʹ§”†r^QTKD[f^dkea`hYTXRVXY\XZt™¶»«´²­³­©®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|„jfhaklgnvrrvrg^`\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@93[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÄ¿ÂÁÇËÈ·”ueUPOTH>^k^_eb`]daSVVUSTWr›«°ª¨ª­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|uklndomiqxoyjia]gaQFDA<997644:8465333656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB<89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÄÄù¸Ã›aIDGKD=[ebahc`[c_WQNOOU´º¬®¥¤¢§¤  ¥™ª´±¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿ”“‰‰~†ˆŒ–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ——œ›Ÿž£œž–˜—“–œ™™œ”–”–“‰vyz{wnkihvZgsxszgg^d[RXIF?;78876169744333646;8:;;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÊÆÄÄÄÂÄÁ­ƒOFME;M[_eke_[`YXRMT¢ª¹µ³«©£¡­ª¬§­Ÿ¬´´¿Ã¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“Œ•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyvvefijh^kpnyxcba`^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈÌÊÂÂÄÉÌÍÎÏÌÃÇÆÈÉÈÈÉÇÅÉÇÈÇÂƖjXG??G^cbj`ZXWSUv™¶¾»¼º¼¬­¦©»º¹·¿³µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«¬±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqocahvijjunyl^d[V`YLHD6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÁÃÄÆÉÅÌÐÍÇÌÉÂÂÇÂËËÈÇÌÉÎÅÆƽ©rPK0XSUfaSNOp©ÈÈÂÄÆÀ¼¾´±°°Á¾¾ÁÆÀ¾·¶Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­¯µ¥¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—Ž‹”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›ž–œ£ ¡¢¤£¤¢žš™›››žœƒ}r}xpg`kjwmifvotc]cUWUTMG:7;9977:748784523425;:9>:=<?=8:=999=<@A@EBABAA?@?DEDE@<9>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÄÇÈÆÒÉÁÃÿ¿¾ÄËÈÊËɼ¼ÈÇÉÍÈÃÈÉÉÅÅÂÃÂÁ¼‘?Nv~‰VLo¤ËÔŶ¿¿À¿ºº½µ³³À¿¹¿Â¹Á·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œœŸž£ ¦™yzy€spfegdkebknoo_Y]WVNPJF99;97677637895613527<<<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾƹ»Ãº¸¹¼¾ÁÇÁÆ»¹ÈÈÃÅÄÀÃÁÁÀÄÁ½¼Å§wjƒ˜o©ÈÈÇÑÁ¯½½¸¹»»¾¸µ±º¿´¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­°§¦¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥£ šž ¤¢£œ¢¡£ žœžž©¥¨•}zƒxnfaebacddjcgd[ZZ]YQOE=;9:;77996499:5314527:;;@=?<<977;:9:<>@?>D<BAD@?>=BDBBB=:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶·´´µ¿»½¿¹¾ºº´À¸µ·²®º»·À·¼ÊÏÀº¿À¼»Å½ºÀÄ¿½¾¯se}‘‹‰ÑÅ¿¿É¿°Á¿º·»¾¹¶¸´¸¼µ½¸µ´¯³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|yˆ}qdacchkggjfj^VVTYOTLF8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“““˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´´±°µ·µ»Á¸¾¹¿¼¼·´·¯®·µ¹¿»Á֍·¿»ÃµºÇ¶µ¸º¼¸¹¶ª£˜ŽƒÉ¿¿»Á¾¹Æ½Â¿¼Å¸··µ¸¶¶¼»¹¶´¸ºµ³¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒyqmeegojelhYYOKKKRJLHD9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’™”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿¾¼²­¯¬±°·¼·»½ÁĹ··¶µ¹¹º»¿¼ÏÄw§Ì½Ç·¹·­¶´·¹³µ±¼ÉÕKzʾ¿¾½¼¿ÈÃÅžǸµ³³¾¸¹¸¾»º¹¼»º´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~†|knqgqktfcn`\UHKJDJCCG?:;8><7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘ŽŽ˜“½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼»À·ª­¤®°¸»²½¾»Ä¶µ¸µ·¿¾Ä¼ÂÄÖ¯tºÈÏÂÀ¸®´´»½·¹±½ÃʏCtÍÿ¾½¼ÇÌÇÇÄǼ¶µ·Á½»¼Àû¿Â¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†qfljouoxdhc\cQKUHEECGC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?>??FD@A?>:7?@CC?@=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼ªª£°¹½¼²¼¾¼Å¸±¸¹¼ÆÉÊÂÆÉҚqr«ÒÑÌÊĵº¿ÄȾ¾´¿ÀÀyRmËƾÁ¼¿ÃÌÊÇÅÆÁ¹¾½Ä¿À¿ÂȽÇÆÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtpmmtlmo`c_bbNIM?E@?DC;;::;:8;<:9<>::>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´»ÄÐú¾¼Ä¾·¼À¿ÉÏÇÈÊʇrs£ËÌËÍÊÆÂÃËÎÁ¼¸½º±pcb»ÈÄÀÀ¿ÄÀÊÉÃÃÃùþ¾¹À½ÃÆÂÊÎÇƽºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢¦¡Ÿ›‚{zˆ{mmx|`qd\_``TI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA??ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸´¼·»»«Úþ¶¾À¾¾º¦œ©²¶Ã¿¥zvxšÄÇËÈÁÃÀÀÉÊÁ¿»¹±¡}sj­ÈÅÄ¿ÀÁ¿ËÇÃÀÈÀ»Â»¹´»»ÃÃÁÍÐÊĽµ¼»¹¿¹ºµµ³¿À¾·´³´¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥ž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}znsythp^\_]ZRFEDMIAD=H;;59;:<<:;;;<?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘—žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯··²µ³·¹¼»¶»»Ä¹m¬Î½¶¹À¼«~nhnlr•˜sw|—½¿ÆÀ¹À¼¾ÅĽ½¸±°™~€›ÊÂü½¿¿Ãþ¿È½¾À¸È¾«¡¡¡¦¹ÁÉŸ²¸¸·½¹»±¶²ÈÀ»¶´±°·¬³©°­­´·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|wmu{qoj\`aZTQAFIGK@ECI<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿ››œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹ÀÍ´v€³½¶µÂ¥‡iZ]`MR[Znsw€Ÿ¸¸Âº³»·»½¿º»»®¤›™ˆ‘~ÀÄþ¼¿»»¸¶Á¶À»È¬¼­º¸Ÿ“‘›£·´°´´µ¼¹¾¹º»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶¼´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰{‚zsvwxnra_g][UJ=??GG=GCC9:5;99><<9:<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Âɨ„x‰ ¯µžkefVX_IIMPSlw…¥°·¾¹²µ²»¹¼¶¹¾´•œ§–¡p®ÉÄÀ½¿¹³®²½»®»»”ÎÜæâѸš’†­¯®³º·º¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtwrm`db\^OIB?=IDFMD@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·¿Å«ˆ|vŒ ™`TCWVHakVOFI` «¯¶ºµ´²¬¼¹¸µ¸Á½‹™²£¦r¥Ë¿¹ºµ®¥¬³°¦³¹šèãÛÕ×ÕϺ‰ujl˜¬§¯¶³²ºµ»»»µ¸¶°µÄ²¾¼¾¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´¶¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wp|ovsod^hY]^SONB?JCAKJ@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜š‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³²­¶º¯­¼³¸¸¿µ‘‚xˆoNJ?cZANw€”kMA\°µ³µ²´¯¬»º¸¶¹¿Æv„ªŸ›e§¿¸µ²±­­Ÿ¤§§«¢½Ë«¨µÊÏÏ˙tklr ¤ª­®§°¬¯±±­±®®¯¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvtmvjl]\kU^\PNHDGMBGNG8665:5:=8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹º¶¹»µµ³·¶•Œˆ„{XFAN†ZJJXv€c@R¢¹³´²°±­°¹¸¶»·º½¢²¬¤s«°©«­«£¨ ž˜š®³Z8KyªÅÊÆ¢€…’ˆˆž£©¨ ¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬ª¯£¤£¡© ›“Ž”’’™–š¤¥ Ÿž§˜•’”™ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±¬ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wryiutoeUbdX]ROMI@ISDNC=8875:7<=:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯±»ª™™•iN@RxqPIIKg›YEQ­»±¬³¯®¬­¶¶²´µ®©¦Ÿš›Ÿ¦¨ž ¨©Ÿ¡§–›–—Œ¬}2RhVt¯µ±žŒš¢¢›–£¢Ÿž¤ ¤¬¥¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›ª¨««Ÿ¦¢›£œ•Œ“—•–˜Ÿžžš™¦—“’–¢ ¥¢¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ª©¤©«¦©¬«¦¡ˆyƒ|vzcxmn\QiUPOGPMMCPR@?;>4::5;:=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢ª¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¤¬¨¼Â«¤¾iERœ‚QWII_KSŽadb€®µª²´®ª«¯°²³­¥‘—“˜ Ÿ¢ œ£¤Ÿ¨“™”•‹ c^†‡tZŒ£™›˜¡¤§¦žŸ œ¡Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£žžžš—š«¦ª±£¥¨ž œ–“’‘™–•˜—Ÿ˜›š›¤™—”•š §¨¥ £¢¡£Ÿœ ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’~}€uv}nl{dhVSdNJHGOSNKNH<E@=2@859;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜——–¡¨¬®¶¶º¹º··»®¨ ¡©¡ªÆ¿Ê¡PAržxOnKKbeus`[^p±¯®³µª¦¬¬£›™”‘•—˜˜œŸ¢¢œ¤žš¤–––”ˆn‡º¿£cg“‡”‘Žž£¢¦¢Ÿ¦žŸ£¦¨ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¡¥¢›™ž¯¨®²«¦«ª ›˜˜˜•“–š“•–š–›—˜˜¡žœœ—›¡›žš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡Ÿ ¥¢¦ ‰|€~wy}eyyabSVaIIKLSUJSQM9>A67=65;:<<9;;8:<=;;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??855=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—“’œž¤¨®­¬««¯ª¯©ž—ž¥£ÇǏWSId£]e~or]Pkc[d_]k´°°¸¬¦¡œš”˜š™Ž‘•‘ŒŽ“™¢œ—¢˜™––™ˆz¤ÇÖ՟Ol‰€ƒ”š˜›«£¡°£š£¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««¨¬¬§¡ £±®²±´ª²¯£™œž¡˜››š˜™›•–›–™œ¥¡ š£¡š™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨¢§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ ž ž ¥¡žž¥ ¦™{|vvsh‚me\S[ZMRKOOVMTMB7>C78=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=?758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’‘œ˜¡ª¢§ ž§¡¥Ÿœ’›¢šž«¤zUiruuqbvvXWc`cgYXWe¬®¬¯§Ÿž¢¡—‘”œ œ™˜’“Ÿœ¡£šžš–ž™–š—wŸÊÚ²²gFfzxƒ{Šµ¯¦³¬¡­­£¯¥¤¦¡©¨®µ³²½¶¾°¬±®­©ª´±°¨«¨³µ¸³¸­²´¤ ¥ ¬¡¡¢¡ š™–– œ›˜¥¡ ž£¡ Ÿ›œ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§ƒ|xvjwu^m[RaIRVHFVWKCMH=KI8E<77;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©¨®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“Ÿ™¨®Ÿ§žœ¡žš™’˜ž›¢¡ ¤€n‚p`cXL[SZMLPXRHMMG—¬ª©¥ Ÿš‘’”˜˜––•Œˆ‹Ž•œœž–˜¥ š“p†½²SŠuyqeije^Pk¬º¬´´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ·»¶«®±¸·¼¯³°µÁ¼·¾³³µ¢¬¢©©²©«¨§¨š™žšª§ ™¨ ŸŸ¨¨¥¥Ÿª¢¢ž›Ÿ¨ ¤§­™ £žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰†…~vrmiwmhn]X[CWNJGNGCGN=>L>5<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©©”’—™”šššœ˜˜™œš˜™ª ±¢·¤°¦Ÿž—˜•™ž›œ£ŸŠbW^e`WMQG>>?CC?>BQx¨­©ª¦ žŸ¡£žŸž›œ”“••žž˜”…™Ÿ™©¢¬ ’‚{ˆƒz¥‡sZK_ZI@§Áµ¹»Àù½»¬®§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¸Â¾¸´»ÆĽü¸´ª³­ª³´¯³®ª¯£ž¬¨·²­£°¦¡£°±®°¤¥®£¡ š¡¦¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¤ž¦š›¢¤žŸ›››œ‡†|trkkurqhW\QFUHDJPI?FB4FH96<>7;<><<::89<89;8;:9;<7;>=>=68@9;;=@<=@97<<;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž  œœ˜šŸ šŸŸ•}`^e`QGD=C?E<?96Nª³§¤¤¢ ž¥¬¦Ÿ˜•’šž™•ŒŠ†ˆ†xl†Ÿ¢¡©©´‘yŒ‡‡–£¤¦ˆbnk‘®€LD·Ä¿ÄÈÍÐÈËò·µ¾²¾Å»¾ÌÍÆÌÌÌÒǾ¿À½ÇǸÄÊÉÄÁÇ¿º´º»´»·°¶²«»²®»·À»º«¸­«ª¸»µ¼®®¸£¦£ž¦¥¢£©¦™›Ÿ™š§ª§ ¡¡¤˜”£•”™‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ…~zrkdioxkfZ\FLMEDTMEBE7:?;549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;:::??=B>?7:A@=<=866<:<@?AAA>’« §®§¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ²²¸§¡¡«ª¡œž¡¡›š}sjaWNE>IY|pbB=\Ž®¬¡™›œžž™——˜“——”Œ‚ƒ‚vrplo¤«­²§svynll‚„{…YVyŒÀ§anÌÄÄËÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÑÓÍÓÐÓÓÌÊÁÆÆÆÊÈÏ¿ÉÑÍÇÆÉƽÄÁ¾¾¿µ¾³­¿ÀÃÄÈÅÈį¿¹²¸½ÄÂÁ»¼¼µ®§§®¨ ¢©¤š– š™¨«©£¤¤ž—›‹™‰•˜› Ÿ£—žš““‹•…yusebgrog_ZZDOMCFQIDCA55589B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>9;AA;;>786:;>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›¢¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¤¨¬­ª £ž›–kf]TID@?K…ž¥š„ ²­£žœŸš˜—”“”—‘ˆ„„‰‡ƒ€€yqqnjv¡·µ™—oef\MVƒ€pzho_´§lŸÓÏÄÍÔÕØÑ×ÍÆÇÉÌÃÅÊÏÊÒ×Ò×ÒÕÖÓÔÈÌÇÌÍÊÓÍÎÓÍÆÉÊËÂÇÌÇÉÉƿó³ÈÅËËÌÏÇÊ¿¾¿½ÁÇÅÌÌÉÉÀÃÀ®°³¨ž¡ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›–Œ†‘‹€{ruvgcgwjeWXRDNG@IQC>B=:22A<E<78<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<@?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­³·¬®£ž£¢¡cSLJDC?BR­Ñ½²¯¦œœœ ¤¡›””•”Š}yqlebhrpr{…Š€upmprmƒ¬˜‹šiWcX_dp€m~rOs›™€ÆÐÑÂÏÓÖØÕÕÒËÉÎÐËÆÍÒÉÒÕ×ÙÖØÓÖØÍÒÊÎÑÌÏÑÍÓÐÀÉÈËÄÌÍÌÏÐÆÇȶÀËÀÒÍÌÐÇÊÉÀÄÃÈÏÍÐÑÏÍÊÈ͸·»¨Ÿ¥«§Ÿ˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„}xsvpcaesc]R\JKGAFIJ?;A8>5586;86:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÁűµ¨¡¥¥ ¢£[I@ADAFPu±¯¦š”—Ÿœš  ž›š•‰wida_``_^__]alusponkpnr†‹ŽbO\T\`Qf^XeZMjwy‡ÕÑÐËÐÍÓ×ÖÓÕÐÏÒÓÑÉÓÑÇÐ××ØÒØÒ×ÙÔÖÌÏÏÉÍÒÌÏÑÀÇÄÉÇÏÎÒÑÑÈÌÍÀËÍÆÔÏÍÏÈÅËÇÇÉÌËÔÔÑÕÏÒÌÓ¹ű¥¨µ®¨›¨«¥²¨°³¬¬““ŽˆŠŽƒ‹„Ž™“™‚…Œ|zqstmacim_VQ`JJCFCSN?<>43:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B<:<74:><?@=FAD=‚¤œ ¥ž¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯­ªª«¥®·¨«·×ÔÕÙÙÑÎп¼Ìɶ¾®§ª¨¡£¬gC8=>DX‚ª¨Ÿ—•—™šœŸ˜›“}qecb__a_^a`^a`_`emppmjmost{qkeTGIQPGE=JP\_u[sÕÔÐÉÎÌÒÖÒÑÖÍÏÕÕÑÅÑÓÊÐÔÕÖÎÓÑØ×××ÌÈÎÄÊÏÍÊÍÀÊÁÉÊÎÏÐÌÐÎÎÌÏÐÈÌÑÑËÎËÃÊÈÊÍËÌÒÓÎÔÒÑÐÐʽȹ°®»¹µ«¶°­¨¸­³¿»±šŽ ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…‰zvopokadnpaX\[IFFEMYE;@=33<<87865;>@=9<<8<>9<@;@:=8?98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§  £§š›Ÿœ—žž¡ššœš¦›Ÿ¤§Ÿ¸¶µµ¬¤¬®¾´°ÀØÒ×ÚÜÖÎÍÊÃÒÏÁÁ±©¬­©¤²|HFB;V¡›•“–›žžžœ“–—”ˆk^^^adb``aa```^__]\bmrnmqqrqwiO~jQXKWOK`@K[RmbvÑÒÎÆÍÌÍÔËÎÒÌÊÖÖÐÌÐÓËÌÐÒÓÊÎÑÕÒÕÖÊÀÊÂÆÍÃÉÊÃÍÄÆÉËËÏËÎÍÑÎÔÌÇÉÐÍÉÇËÆÇÂÆÊÌÎÑÑÇÐÏÍÎÌÐÅÇÁ¸¹½Ä½ù²²¾°»Ãõª˜¥¡˜–‘••’‹”š‘””•‚‰†yqrkmh``qhYXhVMGMIQQB;D?;68:8:;57==A;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÄÂÁ¿»µ²±Ç¸ÊÕÖÙÚÛØÌÌÏÈÖÕĵ¯´¨ ­—xloovšŒ—•“‘‘•–•‹{ebbb`]^acb`__`aa`_][]gqqopqminpf}‹zfg[JV]c<AVKaiwÎÍÆÄÆÍÊÑÇÊÍÍÅÐÒÏÍÌÔÊÇÊÎÏÇÆÎÒËÐÏźĿÆʽÃÇÉÎÅÃÈÀÇÎÈÄÍËÍÐÉÅÅÐÉÆÂÆÉÅ¿ÁÈÍÌÌÏÃÊÌÉÇÌÐÅÅÈ»ÇÃÉÉÂÏÀ½¼¿°ÁÉƹ½ª°²§¥¢œ˜›£™—™‘•˜‰‚xoudk`^fqa[W`GIHGIMUG?J=64355==48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ¼¹ÌÌÆÐÕÕØÚÛØÐÉÏÏÑÓÈ·»»­¤¶~g‚†¡©“–…ƒƒƒ}„„s_[^]^`^`cdc_]\^_``_[Z\akrpmmhgijvƒ‘’}hhTWfPBE\VW]yÊĿ¿ÂÇÉÈÈÉÇ¿ÄËÅÇÊÌÉÄÁÊÉÁÁËÏÄËÈ¿¹Á¼ÆȾÀÆÏËÄÀûÊÇÈ»ÉÆÅÊÁ¾ÂËÆÅľƾ½ÁÄÆÌÆż¿ÊÃÅÇÒÅÁÉÀÊÊÇÈÆÐÃÃÆîÄËÇÃÊ·¿¼º³©¬¤¥˜Ÿ˜¬£¡¦›£ ›•|wsufj[anmZ\XRDLGCGDLDFS@54335@=3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¾¸¼ÊÏÑÌÇÂÃÆÍÎÎÌÕÏÕÙØÙÏËÒÍÍÎÈÁµÃ¾²°¶m^z{‘Š’–†z€„…uxurp_Z[\``bcdded`[\^]^]_[YZ\anqmifgkhl’ŽseZ[SABEORSV‘·¸»¹·ÀÁÁý½¸¼¾¸ÃÉÄÆÁ¼Æ¿·ºÃÈ¿ÁÉ»¶»»Åÿ¼ÂÎÃƾ¾µÁ¾Ä»½Ç¼Ãºµ½ÆÄÂ÷À¶¶¿¿¼ÍĽ¶ºÈ»¿¾ÌÄÂÆÃÆÉÇÉÆÐÆÂÌDzÇÉÃÎÌÀÅ¿¼²·°²§¨¨¹°¥­°ª­¬”zwxkeh`hodV^YJFJFHKAFBFJA9:658853;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µ«·´²¡žŸ—š”–šŸ¦¢ž·ÅÂÄÈÎÒÊÊÊÇÍÍÎÑÈÐÆÖÔÕ×ÍÊÏÅÉÅÇÁºÅ½¬®§`cw€’‹ˆ‹„x††}ƒ{ttc\\]^_`bcbbdeb]\[\^\^]Z[\]grokdciikr‰¢’fYQQSN@;GLp ³®²²²²²º´»°¶¯³®±ºÁ»ÀÄ»¿º´±º¾À¸Ç¸´¼¶Á½¸½ÆÁûµ¯³µ»¿´Å¸»µ¬¹½¾À½±º¶°·º³Æ½·¯¼¿µ·µÅ½¾ÃÆÀÄÆÆÇÌÅ¿ÅÆ»ÇË¿ÏÉÇÃÅÁ÷ý½¶¹¾Ç¿¬µ»µ·¶Žytxggebkn^V^`FKHHJGBDAEF?=:566633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÍÈÅÈÍÌÐËÍÈÉÈÊÉÊÄÐÍÒÏÍÅÇÁÅÁ¿º¸É·«°š[goˆŽ…ˆ‰zx~…†vw|sh]]]]^`_`da^cec_^\[^\]^Z[[]_kolfcfhgju‘ƒm_SXd]ODD]•˜£¦­ª¨ª§²¬´¯±§­¦«²º¹µÂ¹¹¹¯ª´¹º³Á¹¯À±½¼»µ»Ç¹Ã¶­ª¨°²À¶¸½°±¨²³µ»¼«®¶§®¶®¼²°ª¸°®»®»¸»ÀÀ¾ºÃ¿ÆÃÅÀ¼ÆÁÇʸÅÇÅ¿ÇùÄÆ»ÆÉÌ˳¹Â½»³‰tvwki`bliYWW[ALLMJEAC?FA;::996854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÅÍÒËÃÅÁÄÏÆÍÁÃÆ¿ÄÄÃÃÊÂÉÊ¿À¼Âº³µµÃ¯ª±“[i~’ˆŽ{x}‰…y{„€wn^]\\]_`__dcbdcb`_]Z[ZZ]ZZZZ\cmmfdddfgjx‡~oh\cliqs„”—’¤ª¡¦¡©¨«©¯¢¥ž©¬´µ°¼¸¯¶®§­·³³»·³¼¯¸¹µ²»Á²Á¯¥©£«±³³¨½ª«¨«¬®µ´¦¨®¡¤°©³¦§¨®¦¨·¬±³·ºº»²¼¾¾¾Ä¿µÁÀÇÈ·¾¿Å·Äÿ»¿Ä¾ÄÈÌÊ¿¿ÄÀÀ©‡stsji\aodWVXPHZSSKFFE>?@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÐÏÌÃǹ¹ËÁ˾»É¶½Ã¾ºÊ¸Áõ¶¼¶±¯µ¼®¨«“cmˆƒ‡‹€z}~xt~|swe_]\\^_`^_ccab`a_]]\ZXY[[XWY\_ejdbcaddhmzwqqhthk“š†˜›¤  ž££¥¥¬ž›š£¥«°¯¶¶¦¯«¦©³«³¹°µµ­¶¹²°ºº±¶¥ ¤ ¦±¨¬©¹ª¥§§¨§³­ §¦Ÿœ¤¥¬ŸŸ§¤¡¡±­­¬²µ³³°µ¼¶»ÁÀ²º¾ÃÁ±¹¹Â³À½Àµ¸»½¾¼ÂÇÄÃÄ¿¿Ä „xqlbf`ko`UY_HNhOTHFKF<=@=:;;826536999;9::<:7<?<<;<88<9;:;78::<98>:?=98<:;>97776788666;::;9:;<859<:>>@;Èµ¶½¸ºÁº½¶ ž• ¦º¶«³³»³ÄÏÉËŸ·ÇÀÌ¿¸Ê·»Å¸³Å¸³¿À¬¶¼²¬¦¯´­¡£’ir†…†€|xusomjiipi_`]\\\^__acb``a`^\[\\XYXXXVXZ]^cb`cccbefivxto|ƒ|Rg•ŠŠ€”™œ¢™œ¡£¡¥œ™¡š©®¬°´¢¨¨©««¤´¸¬¶¯¬²´®³µ¯°ªŸžŸ¤¢²¤¦ª¸­¢¦¦ ¨­ª™ŸŸž™Ÿ¥š™£œœž°©¬¨ª«¬­°²¸¯¸¹º°¶¼»º«³²¹³½´·²±µ´¿µ½À½Ã»»½—„{sl_e^ddXTW^IW]KPGJJGA<??A;?<05635:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»¸ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÅÏÈÈÀÆ»»ÃÃϾ¹È¸¸¿·²Â´±»»¬ºº±¢Ÿ©«§˜žm~…†xrmomkb^bff]]^]]]\]_`abccba_\[[ZZYXWWWWWXWZ]abccbbcddmzrnw~g=eŒ’†Š‚‘™š¢›—š¡¤ ¢šŸ™—¬¬¬­° ¤¡¬ª¦¡´¯°±¬¨¯²§º³¦µ ¢Ÿœ£¢­£¢ª¶ª¢£¦ž¦¦£–˜—™š š—œœ­¡¬¨£¤¦­«²³ªµ°²«²¹µ¯ª¯²²³·³¯©­®±·±º¶º½¿·³±”†zvf_f_[YVSZUK[QLJEHKIC=?BB@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½¸½¿¶¾¼¿²¥£˜¥±Ãµ¶½­´¸ÂÌÈƿŶÁÀÇηÀý³¹¹²À¶±¹»­²µ¯Ÿš¤ª ”›xƒ„xoqtqhedhdc\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXWUW`bcaab``dfrpkr{P9[}†Œ…Œ˜–š™’œ¦¡œ¥›š˜©¤­®©š¡¡¶¨ Ÿ­¨µ©¦§­°¤·°£· £œ™™ª¦¡š­¹¯£¡¤œ¢ Ÿ“•¡”––œ™˜–—œ•Ÿ©žª¤¢£ªª°­¨´¬ª¦­²°¥«­³±¯°¯¯§¨§²­±´°»´º·®£”‚zwe_aWYXSRTKM^LPLGHMLE=@>=B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´ºÂ±¾·½­§§¢ª»À½À¹®´¸ÁÌÈÅÂýŸÈ̲ÁÂÁ®¼»µ»¼µ¹¹°°±ªœš¡ª•‘Š‹€€|wqilrtphhedfa\\ZYZ\\\]^]\[\^\[[Y[[ZXVWWVWXWWVUZbb``a__`bgpinn9.0L€‰‡Š“˜–š‘›š£¢ ¤¤›¤©­¤ž ¡µ¦  ¢§²¡¥§¥¯¥±­«µž ••©¡¢”­±±Ÿ¢£žž™›“‹ “‘“˜˜’—˜˜—ž§›§¡¢š¤¥¥«¤¥°§¥¢«¬­¦©®¯¯«¨ªª³¦¦«¯´±®¼¶±°¯Ÿ’{xseb\[]XNLQHRaMVPOJNOEBD?9=69:764599;9887;89=>;>;<69;7;6;7;;:85:;:;;6<;8847763321./2556;:8;7876<;:;;A8x»»±¶½°¼±·¬ž¥¦¬¸»¼Áź²¹µÄÉÉÀÂÆÅǶÆijÁ¿Å«··½¶½º»µ²¬­¨™™ ¤ŒŠt‰ˆ~vncafihfgifil`]\[ZZZZ\]\[\^_\ZY[YYZ[WUXWTTVVRTRT__]^_\]]`ahkka.+Lu„Š…ˆŽš“š‘—›¡ž©¢¡¡¡¢ š§¨¢˜œ¢°©  œ¤©§¢ž¬¬ª©­­¢¡¡•˜¢šœ«¨°œŸ¢Ÿž—™“Š‘’“•˜˜“œ¡£œ¤¡¢• ¢¤¥›£«¥¢¤ª¤«­¥­²©¦¥¦¦µ¦©¨­³µ´¹º¯«¬žŒsqpa[WVVRGQOHZ\ORJTKSLEGJC8;;=<9667:9;:976977:;:=<<6;<8>598:88659:;<97?<9678452121..1426:8698598989;9@9{µ´¬´»²°«±­¨§¯¹¹³ÀȺµÀ¯ÅÈ̺ÁÉÌȵɽ±¾ÃÉ­±¸Áµ¼À¼´µª¬¦–šœœ‰rˆƒ{tiijlgjlmkjle]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURRNPX\Z[\\\]\_bijb=+=Ln€‡ƒ‡ˆ’“›••š¤¤¦¤¨¤§¤ –£«¢“—£­§Ÿ›˜šŸž®™œª³Ÿ¥¦Ÿ££¡””›––’©©­šœŸ¡ ›”Œ™‹‘’–•¡ £œ£•›¡£¡˜¢¨£¢¨« «¯£­¸¥£¤¢¬­ª¨«¯´·²½µ³«®˜…uti\YYSURFXLQ[XMUOPLQRIOIB=??A?=75799<<977:79:;<=>;7;::=68:;8976989:6:=99577571141-+/434988::8::748=8?9~³­§³¶®¨¨¯®›©¨¬·¶¬¼Ê»¶¿¬ÌÆŸÀÎÏdzĻ·»Âȱ­¸¿·¼¾»³¶¦© –˜™—ˆzt€vwnmhmmmpggifd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUSSNPPXYYY\[Z[]^cnsSDP[`|‚}‰†Ž™˜”™¦¤¢ª¨¥­¡¥–œ©““¢§¥œ—Ž™­–˜§ª˜Ÿ”¥ ž’‘’‘“•¨ª¥š˜™žž—ŽŒ‹“…ˆƒ‹‘•‘ ž¡¤™–Ÿ•š¡¢ž”›¥¥¨¨¨ °°¦±½§Ÿ£¬´ª®§¯´°¹µÀ±®°«‘stbWTUNRJGVPRRLLXNKLOSGNKACFDC>B75889;9:7::7<=:;@>:9;9:?759:9876958779;85576661320-*.102877;99;8948;8@8´¬¦±·ª¥¢±«ª§©²°¤¶Æ´¹º³ÊŹºÁËÐʱ¶¸¼½Àñ°±·®´´»³´££˜—•„€vkglnqnqjokdege^ZYZYZZZZZZZ\\]\ZXXXYYWXWUUTRSUSVTQMNMRWXYXXWZ[[`jifn_n\jxˆŠŠ“‘—£–š¥£¢¨›¤•¢™Œ¡™––…„‘š£•£œ•–•‡¢š›“ŒŽŠš¥§›••—œ‘“ˆ”Ž‹‹€‹’’’¡š ¢–”™˜•¢¦š™¥§¨§¡ ´²¨³¸¡£¶¬ª­¤²²¦µ¼´«¬±¢Šztn^NQQMODNNNPKFNNJJNNQHMJAHLIHD?958889:;69:68;99><8:>9;?8789:885857688974577820301+)-/12876:999984988A7w¶§¤¶°¤§¤ª¥ ©¦¤³ª¢²Äµµ²³ÆÅ·ºÃÊÌƳ¬º½´¸À¯­©°ž¦®»¯­ š›ž••ˆ|„n__frpuqinieghj_XXXXXYYYZZY[[\\YXXWYYXUVRRSPQTQSUQNMKKSWWVWWWWZ\aeY_\l_^xoƒz„€‹‰‹–›Š•—Ÿž –£“ž™“Š„—™‹sŒ‚}–•…’™“Ž{™œŒ‚‰€Š˜ £ž“˜–…Ž‚”~~sŠŽz‡“›šš’–žŽ¢£Ž‰š ¡£¤›¢´¯¬¯­Ÿ˜¦¸¦¥°¡±®œ±»ª©¯©™„xtdVMRPPMCSNLPMBPQHINSNIJJEKMGKK>849888;;69;7:<9::;79?9>@79:<89764445874312485/0102)(,-02764789::65:87A7x·¡£´¨¦¥¨£¦¥¦¦¦²§¦´Á¸¯´°Éĸ¹ÀÎƾ³­»Á¬­Ä­§¡¦’¦·­£ ‘–—’~xfWV_gfighnciifb\XWXXXYYYYYYZ[[[YYYVWWWSTPNONOOPSTQMMJGNSSSTTSUXZ\hXZWimedEOiˆy~…•†ŽŒ›•š”•”‘Œ”ˆ~’ˆ^;Vn{Š“‰€Œ‘Œ††r‹„–y{†”•ƒ–Žƒ†}“xqo†~‰Ž˜š™“‹ŠˆŸ˜ˆˆ–žš¡ —§®©­©©ž–­³¢¥­™­«˜¨´£©­¢“tn`[NSRWLDTJPLLFNOIELQMKPJINPGJJ=7599999:7:;:>>8:==7:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9y· ¢­¡¦¦ª §©§£ª°¨§´Â¹°µ°Ç¸³½Ï¿¹¯®µÂ§ªÄª¢˜ƒ”œ±£š™‡”‹‡~sv]PLQUYZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MNQMKHFHNQQLORTUWY``TRbncE87y‰‡u€†€…ˆ–‰”•‰‘…ƒ’„w‡~_IPmwŠ‘ƒ}„ŒŠ„m~“wuvx„špQˆŠ†|~y”vgw†ˆ~Šˆ•‹Ž‘“—Œ„Š‰•„›‚„’›–ž”¤£¨©¥¥ž›°ª¡¤¤‘¦ª–¢ªœ¡¦§Šwnf^\HQQSMIUMSILKOIHFJNLMUKQRPGJD=769:8:;;8:;8>?99>=8;<6;;478;6775344696/3/.125221/,')+*,4833989:99::::?9w¶›¢§Ÿ¡®¡§¨¥§§¯¬ªµ¼¶¸·³Á»¶§¹È¸¶¨¨µ¶ª²¼§ž•ŽŠ”©–•‹Ž„ƒ~xqoXMKMNOLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDCINOhYNQSSUZf\T`gWXPJˆ|Œ€lw{w‡Ž~™‹Žxƒ~s~wqmtpt€z~‰ª„z{hv{Žprmx‹’x{€{€wsr’xhu…„„…|•‹ˆŠ‹€„‹€”„|€˜”œ–‘Ÿ©ž ¡ ©¥Ÿ˜§¤’  –žž¤‚sib]]JWPRHKXROJMLRJJJLPHLQLRUNFIB=78;99>=:;<98@?::>=7==79937785675251472/2.,//200/-+(().12721987:8775:<;7v®™£¡˜œŸ´©¯ª¥­«°±ª½´²»¸¶º´±Ÿ·º²ª¬©¨²¯¢š‘”ŽœŽ‘w†x|vpojYKHIHGEHHPTTTWWSUUUUVWXWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LNQQSV^b^\aUe~’‰Šs`rypsyƒ‹x€˜’~n„ztynj}­|tŠ~z†’€|tfu|†lohs|Šˆ€mzq}qmvqhq~ŽpD‹…‚ƒ…wxzŒ†}Œ{u}Ž’˜‹’››£–™›ž¡œ–‹¥›Ž—Ž–˜yongc[XXUQJSUTOPNPVKNKOOJQOIOPLFD=;79;::?=9<:99??;8;=7<9999266856633611224.,,--.-0-+*''*.1362/876966527995y¦— ž– ¦°¬®«§©°¯±«»¸«º¾¸³¬§›°§¬›–œ¥©¤¡˜šŽ„’z‰‹‹vq|muqjmjXKFGEA@CDHLLMQQOQSTTTUVVWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zYJNOQTX\\[WVw—›»zko[sphvs‚‹uxˆƒli‰vrwhh~q–‘Š€}•I’™ngw~‚mjdly…’†ksl|nr|†imps‰…†{}~{wput†‚yyp|Ž‹Š“ƒ––˜š“––™––Œƒ‰Ÿ’‹’†–€ojoooYVXTRRYORUTSXUMOHMKMOKCINGF@:99;99:><9<;::=>:8:<9?868727565541432/024*+**-.+-*(*(',-1250,5567485HA895w™‘›˜šŸ¤¬¯¢­ª¨µ¯®¬³¿«¼Â¿¦¢š•¤˜ž„‹”¡¢˜™‘“‹sŽz€†Œ†uotlqmekkYNDFC@<>>BFFGKKKLORRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_JMNORVZQVRP˜zW_ho]vigyt…„q}ƒqj–rqzhhœŽLy„‘ˆ„f1v‡rk}}ƒtfeu~„„…€filukp€|hqq|n“{t}}qqovmƒwyujyˆ‚ˆ‰ƒ–’’‹‘””Ž—€yˆ—ˆ‡Š†€ˆxlkpheXR[XYY[NPUVYXNIHEJJHGB@GECG=998;9:9<:9;:::@<9:<98>787715234533645031.**+),,++)(+'),,226,,4775478iO8;5m’ˆš™–¤¨­ž±ž§º¯«²°Â±»Ãǚ–Ž•™‹Ž…z„˜•‘Œ‡q‡‚t‡Œ†zpsqopdpg_TFIC?<;9:?@ADCEGIKOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOOQUKAHPF]¥©—fqndufk|{|v‚‚voœ‘qw~qs’†5qœ§œ ¡„¢…vp†{†|sŒ­‰hgbjnrmpƒuioXupŽ›‘vm{}nrnp€{svnbuƒ†€…ŠŠ‰‘‹‘‹‹ŽƒuxŠŽ€~ƒ€}Ž|trqm`\]^\ZYa_RN[ZXWLHIFIH?CABH?CD=;:7=;:;;9:99;:?<88=:8;66650121253474531./,,+)*))***)(*)+/3DM2166643<vR7=7b‘’‡•‘¤§ž¯•¥´©­±®Á²»ÁŖŒ”€ˆ|n’‰ƒŠ‡…uƒƒl•ˆˆ|uxxmxnwdj^IPG>?7448;:;=>@BEHKLLLNPQRTUVWXZXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMMPL7CMPQBF{itrrmvfpvx~{ˆzsž–w|„ƒ˜ƒšœ`…©žœ‹ƒŽzv‡~‰ˆŽsŠ—„{]dqtz|wŠmhjbyo…‚zoxu…zptzxkni]v†}‡|‡†ŽŠ’—ƒ…Œ†}q„„}vw{|‰xqtugh`[\^S\g^WPTX[UGJJELG?F@DD?AA=;97<;;=<::99;;=>79>9985654244004645554-,)+('''&(())((+++/00Uq=23331E~W4=9\ŒxŠ“Œ‘œž¦‘ « ±¨¯À²»Åº–Ž‘“‡z†vk‹‘ƒ}ŠƒŽŒxƒ€s „Š}}p~zhwkRXL@E211276688:<>AEFFGIKMOQRSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFIKMNQKJSZVNF_w}qqtjuˆ…uw„‚z‘ƒt–†„Œ“¤Œ¬©H†¬¯®Š€”ŠŠ„‘©‡˜˜Šœtm|†‡~Žhghyn…‡‚…q„†Gm€wryvhmk_v}‚ˆ‡„‹y”œ›‰Šˆ‘zuŠv|xmow~uusm\^^\cdXgf\UPPWYPDLKFOICFCCA@CA=978:::;;:888::?>6;>7585773344236656778;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|}‰„‡‘Ž•—’– ¬ ¦¸¯³½³—’‹˜‹}tp~‰’~}Œƒ’”}†~†¤‡ˆ‚ˆ…x‡‰~s„x_cWKB60./23124668:=>?BEGHJLNQSTUTTVUSQOGC?80,#‡[??84.]–ps£UFIKLMOW_ViWXZa‡{Šx|y}ŠŒy€„Œ|•’ž•’™™¤¬’™»±¦ºÇ狌¡¥Ž“‰‘|qƒžŸ‘w……Š‡ihp„tŒ†„Šr†‚w‡€{v„|mvuf”Ž†ˆˆ†‡‡ ª¢–ˆŽ—zˆzyogkx~|€ulf^Z[^j^ag`ZPLNWRQIPJDNGCJDC@DDB<:87=<:<:88778:==8<=68656623444576867<BB?<8:>CQ^e\G2'&,,--.1(?‹[.310Oƒ_4?;nuofw‚zŒŽŠšš¤œ¡¬¦ª®°—‘‘„¡”„xwŒ”|’†’•Š€’›Ž„€ŒŠ‚‰ƒŠlpj]BA4.-//..02234778;=?BDHINQRTRSSTRPOHEB<87/9C><<63.l“—MPHJLKJMU_^wcbgl‚ˆ‹ƒ†ˆ“ƒ‹™‡œœŸ¦¢¡©’§´¡§Á­ǯx¹”š|¡ž˜„“…‚Ž¡Ÿ”™‘…Š…š‘–lpuŠŒ‚•ŒŽw„qm…Š–‘‚…ˆrˆ •†‘‰–¤´¨›Œ”¢‚‡’ƒ}kjj|‚ƒƒuc^e`[hl]ml_WKHNRPNLLFIPCDNFBCEFC>:96=<:;:987767;:6=:785456344566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYo‚ou†pv‘†~—–š”žžœ§ ©–“˜žge¤š~„’‘y€’ˆ‘’}Š„˜’ƒ€€‹Œ‰†‡„‰†xxgMR>//.,/.-/000212567:?CENORTPPQSQNPIED>;<:DF?><752<?R5HHHLKMNQ]iwmzu’Žœ›™’™œ—š¤š£¦œ¥¨§¨³–ª½ª´ÆȶÈÐϾ› piª©Ÿ„“’…œ š›™¦‘‘ˆ•£›šwz~”˜“¡“——”ž{w•’ª²ˆŒ–ž|“›‘•˜£¡¥µ¯œ‘˜§†–€ˆlss}~sjb^b`bhe`gg\REJKPOIJLFGMCHLFFCBGEB;85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Ppt`m|aw}{“ŽŽŠŸ’—ž–›ª˜žªBD}‡‰‡˜x‚‹Ž|Š†Ž‚€‰‹Š…’…ƒ†‰€‡v^bP560-1/,.0/./..0015>AAMPRSQRSTRNSLEE@<>=FG@A@8662<9;FHGIIMNPYi~‰rŒ‚•›ª´°§¥§£¤°§­²®®ª¸¯±¼›±Ãª¸É˷ÿ·¥¢°³¬¬ª£‹–˜„¥¦ £—¦™¢ª¨¥ˆ…”¤¡¡ª ¤©›°‹•£¦·º› ¢¯’¢œ¡¢¡«®«²´¡”¤©‡™ˆ’‰•yz~†ibi]fc_dd_gg_[OCIHSNFHKFJGFFHAKFCFFB;87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLhbWinXy„v“…‡‚œƒ‘Œ’Úȝ–sV—ˆˆœ|†ŒŽŠŠz‡‚‡‘Žƒ„‹…†ˆ’†‚…‰‡ˆ‡‡qna@E64<2/110-,+-0..4>CAMUPRSUUVUN[PGHD<>>FHCDA7;<5C;=FKIFHQNPW}‹˜¥›¦ §·À¼¥®À³¨¯¼¯´º²¼²¿´¹¹¢·Ä§µÈǵ½¸´¨£³­°±›™’šŸˆ§¯«¥”vŸ¤—¡¬²´™–ª®¨¯¶º²º¬¯µ¢±«±µ»¶´­´Ÿ¦§¢¦™¨¯¬±¸··§šµ¨‹¤’ž†x‚…x[cfWgcbdaaga[TJDDLTPHIIDIGEA@@KDBMG=867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AFWQJL[YQbbWyuq“}„†“u…€Œ{¿»£¼‚´”“›„ˆ’‰‰y†€Œ“Œ‡„Ž‰††ˆ†Š‡‘{xn]W@DN<6:46AB7640/6CHCQ[OQUWU\WP_UIKKA?>GKFED;>@7D7?BJJEFVSO^Š§ž«¬¸«¯¸Åı·Áº°°¾´µ¾±¼®µs¯²¤¹Ä£¯Æ¸°³±³§¤µ¶ª° ¢–›¢’¥°®¦­«§¤˜¡­´»¢¨²ºµ¼¿Ì¿ÅŽ½³Á·º·¾¶º·¸««°¤¯¨¬½¯¼ºÁÁ«˜¹§”­Ž——©ˆ}ƒ~mXecYlfkfW\dYVSIGFLPGCHIAHD>?BBL@?MD99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FRLALQVSYUZvjp~„€Ž…nzsx‡b¹¡™£‰””–’”“—’‡‡{†•Š€„Šz|Š‡†}Šƒ‚‹„–}xzufP\dGEL;Qca[^SG?;HPDZcQQYXZgYT`_LRODA?IJHEEA@C<E6B>HGJLSZT]¨±¯µ²Á·³·ÅÉ·¹¿ºµ³¹¸µ¼²¸°Ä_s°¤±šª¼¨¤¨«ª£¢²µ¡ª¨Ÿ•–ž˜ ®¥§¦¥Ÿ¤”£¨±´¨²³½¶Â¾ÓÉÉÓÆÂÅÌÂÊÃÀ½¼¾»»¶´¯¸¶¶Â¹Å½Âǯž¸©¡«¤§µˆtadc_Yc`jgSXaVRUIEEMJ@>GD=KA=B@=F>;H@796379>489:57045/26389374426?8@>GKRTSQPOQQPJA9/,,,*+((,-+/P>(.48€}<2Kˆq9>CKE@IMPRKQ]glkp…skrrs‡ÕÀµ™ •˜™‘Ž—‘––Ž†‡}†ƒŒ–Š~ƒ€‚x{‹ƒ‡{‹zŠ‚—~t}zlepuY^\Pedb`ed]\XW\MdmURmm_n_XgdTYUJDBKKIFHHHGBI:D?HKSTU\Z[´»´¹±ÁºµµÇÈ·´¸´·¸±µ³²­´µ˜ct§œ­p^¢¬›— ¢›¤žª¥”ŸŸ“Ž•˜˜¨ž¦Ÿžš™ƒ¤­¥ª°­¸°½¹ÔÑÏ×ÐÊÌÒÌÏÍÊÆ¿¾ÁɼÀ¼ÀÀÄÄÄɾÇͲ£º°´®š«·»˜€|n_b^[`cZdcQ\`SQJCAEFE<@F?AHB?C<:E>=J?47535;=468977022/24169775555D3ELM>51/006:477@IOI;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODQ[Yi_o–’”nkotu‡´¬¡¡Ÿ‹™œ™Œ•‘›’…ŠŠ~ˆ†Œ‹ˆ|ƒs|Šƒ…{‰tŠ†•s{ylmu{hreilifjji`fiilZms–­¤¼ˆ†g\og]YYTHKNPJKPKSQILAJFJO_^afi`–³Â­µ¯·¹²¯Âij®·¯¯¹ª±°¥ª¶«‹µ§œš¦šM™ŒŽŸ–‘¦˜¥•Š““‰‰‘‘›¡—š•–‡Ÿš§›¬¯©°¨´´ÔÔÔÖÓÌÐÓÕÍÒÏÌÄÁÉнÉÉÊÉÑÆÌÍÂÏÑ·¯Ã¼Ã¹¤µ¹Á¢„qe^__ZbYZgZQ]XNPABHEBH;@C>AG??A7;C>@H=46655;:687654/10146278875367C5B8?-0-1349=97,.,1;FK=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYReVr˜‚gqoxyƒ¡ªž¦—Œš›—‹•‘šŽ}‰‹…ŠŠŠ‡|„‚p‡†{‡rƒ’‹Ž}qxvlpx~qzmxsmiqmcjmpxiw|~˾Áߧmcxnc[a`JPRUNY^O]\NPNTPTT\nmv‚q•¬µ©±¤­³¨«º¾¯©³¥£·¥ª­ «³¢°­™—˜ŒŽ‘‘„Ž›¦‘œ‰ƒ‹„‹‰„‹„”–˜—”›‘œ—™šŸŸ«¬¥¨¢¬­ÏÒÕÒÎÌÓÔÔÏÔÑÎÇÃÔÑÆÍÒÓÓÖÌÑÑÄÑÖÅÀÎÇǨ½¶Îž|qh`d_XaT_[PQTQOH>@FABE<@A>DC>??:==<<JA45465<888664412/03526768533;=<E=@11+/249>5901022-2DN3)/3.32=N238C}_2A†tD:==I>@CFH<UQMNZt†…Šwlwp}~¡žž¡ŒŒ˜““‹Œ“•…y…‹‰ˆ†~‚{q~€‡z„u…“ˆovsls}{w{s‚xrksripqzyrz¾Ëš}‹±„vr„vgaj]CZY[VecXcjSX\]`c]cwz}‹—¨££ŸŸ¦¤©®·©¥²¡¡¬ ¢­¡¦±žˆ¦š“’‘‰Žˆ“ˆj•¢Œ™„†~‘ƒƒ“—­‹•”™Ž†’‘ž—¨°¢¡¡¥¤©ÉÍÏÈÃÌÑÕÒÔÒÎÓÍÆÖÒÌÔØÖÖØÔ×ÕÉÔÚÍÈ××ÑÊ«ÂÂˍuqebaZV[T]QKGJJJ@;:;DAD<BC>GB>BB:<9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/--;R017/532FD28>nb5=tM99@I<AD?A;OLFJXp€u}hrxr‚Š€•”…‹•‰Ž‰ˆ†Žxƒ“˜ŠŒˆˆ‹ˆ~‚xs{}‚ˆwz†‘•€ƒnwpmvvx|t†|zm‡vto}v„ux{µŒ;AŠÅ¥~Œ|ieWICfcecgjcmw[^fhknhm€‚‡‘ŠœŸœ–—¢£¤°££±ž¡¤œŸ¨Ÿ¢±›…‘‘’ŠŠŠ†ƒƒ~œ›‹‚„…y”‚©•£’Š—’Œ~˜‹š’«³˜›œ¨œ§¾Ãƹ·ÇÎÒÑÒÐÌÒËÈÔÎÐÕÚ××ØÔÙØÍØÛÎÉÙÚÑÕ¾Ê˵zypg_[TWS\XFGKIEE=:7:@@B9GD?DCACB;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?1*(.BS39254/7K75<`bA<svV87AH:?C><9QECJTknnpbpqt†}—‘‹~‡’ƒ‰†„‰‡|x…––‰Ž‚‡…‡z„yqz{ƒ…uy…Žœy‹p|ppz€q{€qƒ‡nŽzuw||‚u~|†‡¯sX©Â¶‘‚pmb=^hrpqpnxvehoruxqy‹†“‘š•Ÿ”†‹’šŸšœ¨ž «š¡™˜¤Ÿ«™Š™‹‘„{‡‡ƒ„‹Ÿ™“ˆƒ‡~l™z„™†ˆ“Œ”Œ†|œ‰”®ª”–˜Ÿ™§¯¶½©®¾ÇÌÉÊÌËÐÉÃÒÊÔ×Ù×Ø×ÕÛ×ÓÙÛÕÐÚÚÑÖÈÔʖ|~kk]\QUTaJCFJH>A>=7:=?;=G<?AAADA>?:87DB755479.556435532323647553458EBDCEB56<FNSM[nfcnskaV>,4LG865434BF4=W_hLux^8;?F<<B<99D>CGRj^mdbfkv€ˆq‘š€z€~‚„~ƒ{|„˜‡‹}…‡€w‚yo{{†ty’žŽ vu‚tu~t€ƒo‚o’„u|…zv†{‰·Å¤Áɹ–›wpeOfczw†¢Šxyv{ƒ{„vm“–“”Ž—‚‰Ž•™–•¤›–ž•’‘–¢˜ª•‰Œ‘‚‹ƒˆˆ…‘š™ˆ…‹…—zˆ‰Ÿ—ˆ‰‹‚}¡‰‘Œ¼¡˜“˜™©¦¦®Ÿ¨¶¿ÀÁ¹ÈÊÎÎÄÍÊÑÖÕÕÙÕ×ÛÔ×ÙÚÛ×ÛÚÙØÎÛƈ}|jlhbVYWXNLENC;==<8:;=9=@6=??<>==9867CA6455=80665547745613955564557HH=DJE7925;H>;9:7IP][RUXK9T>;95327I8=NYMHxxd5=>C==@:6:>>@EQ_Xea][htzylŠ’wvzŠ{~~€|„z}‘‰„…z„‡{u}tm|}†s~’ž‘ž‚{†~x~yŠŠn‚š€t™†}‰…|~z©ŽÃ¡½Œœ£}‰„}‰r‹Š~s¦šœ˜“…{Žˆ„hGq ¤Œ‹‘„ˆŠ’”œ™’“•Œ‹”ž›“Ÿ”Š~ŽŠƒˆ’–™žžˆ‹”‘‘Š¥˜ˆ„…„¥†ŠŒ·˜‘•–¢§¡žž¤¯·ºµ¬ÀÆÊÐÈÇÌÏÓÓÒØÓÕ×À×ØÙÛØÚÚÙÙ×Û¸{|{nlhZb]TQOIDLB<<>99;:99;<6?=><=99;;37D?7378>70688357<37804976755546FP5DNI8938AK=;3C@I<:DWN<MTHN?96333>C;[X>5YypZ<<A<=>8689?=CQSRX^UXfmmmiŽŠqryŠ{z|{‡z|{‹†‚}tƒ…yrysm€~„~w…œ¡›”‘Œˆ€˜ˆ€œ’oˆ¨…z¡‹|‘ƒˆ„œ}š‰Œ££ ¤¯ Š‹…‹’†Wr­‹Ÿ«›ƒ˜›Ž\‚¢‘‚ŒŸ“”‹†‡‹’’‹“““Ž‹Ž‰‡•™›Ž”•Š‘“…Š‡‘ŒŠ‰œ–˜¡¡†’•ŸŠ‰ˆ›ƒ‡Ž‚‡†¤…Œ‘²˜’•—¡¢Ÿ™’œ¨²¸­¦½ÂÇÍÈÆÏÍÐÌÏ×ÑÑÕ®ÖÕØÚØÚÚ×ÖÙÙ r€wji_`ZUXYC@IC?>>:48:;7:;:3;;?=>7;::1:G=:27=@50677255?65;55858:57735HR7GOK994=EJB>1FCLA98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:;@;BQKKSYPTcczma~’ƒnmw‹xy~z|†{{w†„sp…‚zuvvt„‚„~’¦£Ÿ¥¢–Š•—‹Š§—sŠ²„¨’„™“…™Œ¢•Ÿ˜’ˆšž£“©° ”Žˆ–Œn·…šÄȲ›¡¥›œ˜–±‘d¤ÍȕŽ†‡ˆ’ŒŒ‘“ˆ„‰ˆ…•˜™Ž“’†“–ƒ~‹™‡ª––¢¡ˆ˜ž–šˆŽ‡——‰„ŽŒ‡¥‰Ž“¨š—“—™¡™Ÿ™“›£³µ¦£¼Â¾ÈÅÅÉÈÉÂËÔÍÍÔ©ÒÑÖÕÖØÚÔÒÙ΅uƒkfa``QKV\BBGC;A=837;<:9=649:<:82?992:I:>67BC32:96264>=4;>6949;57944JQ<JQK9A7BGI@64JELF><88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBeƒGu‚Ž||m}ˆxz~zƒ~vv€‚{lnŠ~y|wx|„†‹~‹£´¨¤«³¡–§ ¦¤–•¯¢ƒ¸•‘³šŒ¡ Œ¤›¯£¤˜¨—©™®°¤—”•”‹˜š– ÀŽ£É¸«š£¥­™‘›œ²†…¨¢œ—…ˆˆ”‹Š’Ž†€…†ˆ‘—“‹Š“’†“—…ƒ›s˜²•–£ ‡›š“ŠŠ–šˆŠ–†}Œ˜žŠœš™“™˜Ÿ” ”ž›¡±®£¤¸¿´ÄÇĽÃÿÇÎËÉÒ§ÏÌÓÒÐÖØÒÏؼu}z`cXcYRIKOFBCD5>;76:?;<7=42669774=5;5<K<>;<BA75<;5277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=89567=:JFDGM\]YJha;H„‹z{m…†y|„x€„}px|}|orŒy}{x†‹‰†„“¨¼­©³½°¥®³´©£¢°­Ššµž£¹¥•¬£—©­¸¦¤£Ÿ™©˜ª¤°±ª™˜œ”•‘— —š»»­Ê¡i¶¸ª°•˜ž£«’—½£^©²‚‰‰Œ”†|Ž|ƒ…““ˆ†’•‹Ž•ŒŠŒ–˜‘›™³–”ªŠ›”‘Œ‘‹˜š‰‘Š‰•Ÿ¡Ž•—™’œ˜ž”¡ ”œ¦®¨¢¤³¸«ÂÈĵº½»ÆÈÈÂСÆÉÍÍÄ×ÖÐÊÔ£s}l_]VbSQHD><CAA7?874>F<<6<35355454B39:BM:A;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPgHa`bpJ@‹‰~€s‡‡|‰uŠƒ~m}||~pw‡w‡{Œ†Œš«ÃÀ°½Æ¼³´Á½´­¬³·Œ¨²®®½«›º£¨­¹¸«§¦¢¡££ª¯²±«œ£™›˜—ž¢¥¥’£¹®¨¿»¬­²¹¥£§}ˆ†­¼°‚‹‹Šƒƒ‘Žz†Œ›‡‡–ŒŠ”–“™–›§™°™ªœŽš‘Ž••–Ž ˆ•›£¬•–”œž” ›˜Ÿ ”šŸ¨§¤¢£°³¦ÀÆ𰻶ÅÅÿͧÇÃÇüÖÐÌÄʊwve_]b^OLCL@EG?A>B<:4>A==5=6>333242A17@BM>G@CNCA=C<;86CC5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GE?CF\iF_ig[]\“ŒŒˆ{‡‹†ƒŒu…Šn~{~q~z”z’”•˜“–¨´ÆÉÀÂÌÂùȽº°«¹»˜²¶¹²À®¥À£«°¼½ª®«££ž§¬¯µ±ª› ªœ¢œ–Ÿ¯³§Œ£ººµÁ¼«¨œ²¤£¨”„ŽªÄ䂋Ž†‡„†•”ŒzƒŒŽ‘ ‹‹“Ž‡—Ÿ—’˜”–¥Ÿ®œ‹©›–‘‘”•”‘Ž¡“†—ŸŸ³Ÿ”›”Ÿ¡š¤Ÿš › ”˜ž§¤¦§¤¯­¥¿Ã®¨·µÉþ¶Î²Ä¾Ã»³ÑÉÈÁµx|p_[_mTNIDLLLJ@A=BD<5AD;:3=8B332262A15IEM>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBh]Me\fTcjš–Š‹ˆ’†‰y…“r€{w‡‚y¡–¨š›˜º¾ÉÈÊÂÒÉËÂͽÁ³­¼¿§º¿½¼Ä¸¬Á©¬³¼¾ª°ª¤¥£¬®µ®·¶ Ÿ®Ÿ¦£˜£³¼©œ¨¼Á£¶·¯«“°¬ª¬—†šª§¥‚Œ’¤•‰€u‰‘y„‘Ÿ‘Ž’ŠŽ‹“¢—–š”“¡©ž¤™‹Ž•–ˆ|Ž•’‘¢š” ¢œ¶¦Ÿ—¥¤£¥Ÿž¦˜ž•—›¥£¨¨¢²¬¨»¿Ã¯¥³·ÌÀº®Ã³»½Á¹¬ÂÂÁ¿šq|d\Y^]LMNKGECHAAADK:4DH:;4<7F.12352A26SHN<JBJQEKCEE:ELB<7EV=<=89?<I?:EUIAWQF7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>lJ_XaZdeXž–Žž’‰Šˆž’„w…”~ˆ‰€– š®§¤˜Ä¾ÈÄÈÆÒÍÎÍ˼¸°º¼´½Ë»Ã·¶¼­´¿º¼®¯¨¡©¨¶®¯ª²¸šž¬¢¨¢«··ª¥¯¾Ä±½¹³§ª´³­®–•¥­© ‘Ž’±Å§”Ž|‘•}‡‘˜©˜—’’Ž’”’¤œ’œ˜“ ¡¡›˜ž—Š‹ŽžˆZ–—’–¤™f™¤Ÿ³¥–£•«¬«¨œŸ¦—™–˜•¢¤¨¦žµ«©º¼Â´¦´µËÁ¸ª¶¬³»¸®¨¸º¼·„oq][WXPGKTNK?AGDDHFF85FM;>7>AK.32025B55PWN<LFKRLOGGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|hV<>@BFBsFiIRfdMF¦”œ•¡—¨•Œƒ†¥’ˆ‡‚š„ƒ•“Žš¡Ÿ¯¾®¡È¾ÅÅÈÇÎÎÏÒʾ¼¶±»»¼¿Ï¶Ä¾¸¹·³³¶³¸´¬§œ«¬¹«©¨¯°˜£®¥¨¤¥µÀ°«¬´¾Ã¹À¸³§¸´·²¯•¤­°°¥‹“” sÁ™|–™„Ž–š‹°•™™”‘‘™˜¤¢”žš•™§œš Ÿ˜ŠŒ•_J–œš”™¥—T–°Ÿ¯Ÿ¥•¯¯­¦›¡¦”“™˜Ž ¦¡™´©ª³¼»»«°²ÇÀ¸¥««­±±£¡²²´¥srh_]QSMFQQPQ;HJHFGAC=9KT?A:=FM/7534:B44NWN<JKOUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@CAF3>58JKCA=C;5FA:A?>H@5*B52,>c]g:35tde@R7&#3}iW<:BC@=REWStbVFHª—™Ÿ¡¨®˜‘—‡Š§–Žˆ’„Ÿ‡„—Ž š£¥µÉµ©Ç¼ÃÄÉËÉÈÌÎÇ¿»³¯º¹ÀÂ͵ȻÁ¹¶º²¯¯´µ§¤œ«´µ«ª¦®¬š¤­¦¥©¬º¿¨«··¾ÁÀ¾¸²²Â°·¼¬£®µ­º¦ˆš–¥›u¾Ÿ„˜œŽ’˜š‹®– ›š–”™žŸ¨¦Ÿ˜™©™ ¦—Œ‚mu’¢š•œ¢Ÿ®²¢«–ª«˜«¯¥¥¡¥ª’’™œ‰•œ¢ž–°¦©ªº¶¾³²®¾¹¶ £¦¨¥¦œœ­©©fidbTMNHIOJVL=LDMIJ@CD<QU<AABEO18=77?B75UXN?HNQXRPQTJQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CC:9C><@>;;G7-2>-1‚hNz\/0kh`<=BB86{fW<:=..SaLVH~e^HF¬”›¡Ÿ»®˜”ž‹’ª›‘’“ˆª‡¢žŒ£­”£¤¶Ç½´Á»ÂÂÈÉÆÂÎȾº²¯¹µÁÃʶƲÁ¼µ»¬©­­±¤£™ªµ»§ª§¬ª¨¯¨¤««¾»¨­½´·¾Ç¼¶µ¸À°½À³ªµ¶¬¿¦¢– Ÿ»ž‰šŸ™–¶ž¨›¤¢š› ™§¤± š¥œ§©œ—“Ž”›Š–ˆŒ¤¡”œ¢ž¡µ¯¥¥“²¬š«­ŸŸ¥¤«’–• „žŸœ•¨¤¡¡³´º¶­¨µ²²£¥š—•™ª¡žxd`b`LIGHNQIMEFFBQJH@DGAVSDH<AGQ1:B7:BF79]YKALPTUSMWRNUJD@JJNO9C?5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-1:h]FDCœpbGD¨—¤žžÃ¬›—¤—˜¨›•™šŽª–•¨¦•¬­™¡«·ÅÁ»¿¸ÁÂÀÈÄ¿ÍǼ¾º²°¸´¿ÃȶÀ°¼¶º·§¤«¬­¡¡›««Ä¢¥¨¬¦ž«¯­¢ª¨¾¸¦­¿°··Ç·´¹¸¿±¾Á¶´²µ°¾¤–£•’š“­Ÿ¡¢¤¢¢ž¾¤¨¨«œœ š¥Ÿ¼¢—£ž¡¨ª œ”Œ”“†Ž„“ž¤ ¶¬¥œ—³§š°© ›«Ÿ¢Žš– …Ž¡šœ’¥¤š—«±¶²«¥ª­¬œ˜  ’Ž–©Ÿ”if\c_QJHKOMHEDI@=OH@;FIH[ROK=HNU4BF8>HG5Cb[KCNRUWVQXTRUH@8QQPM:G@4CHQSIC;C>GVKC@O>K<06;GF>;FA56?9:?9;15D0--0Mv\4KZ5,MnW<-=)#zbQ5CKQ9oSF<KxfcXN¢›£›žÅ¬ ž«œ­Ÿ‘¢ž–¤ ¦ª«—·±£ª³¶Å½À¶¿Á¼É¿Êȶ¸¶´±´´·ÂÆ·¿±¸µº¶ §­«­ŸžŸ¥¤Á¥¡ª® ¤©­°¢¦¨½µ¥±¼·¶¶Ä²³·º¾²ÃÀ·¸­´µµ£œ¤”‘“ ¬ž˜¡œ¨¨ª¢šÂ¬¨«­šš˜¥Ÿ½¡œ¤—ª««¥ ˜šŸ’ˆŽW–ž¥¡ ¹«§“™·£Ÿ³¢¡œ±˜¡›–ž‚ ——Ž¢£•¥®²¬©¢¢¥¤••˜‹’“¤Ÿ‰cg\ebNJKKOFEAGK>=IA:8JJN]QQI=LV\9FI=EMI8Hc\KCLPSYYVWOZ^IA=WQIK?H?5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+waS6SZkWsHE6=ue\LPžŸ¡˜žÃ§¥¢³ ›±¦’©£Ÿ£Ÿ­©«¼±©¬µ²ÈÃÁóÂýÇĽÅʽ°±¶®±µ°¿Åµº±°º¶­›©°ª«œž¦¡¨Á­œ­±œ©¢®±ª¤¨½·¦¶»½¯·Ä­³´Â¿²Æ³º·«µ¶­ª¢¥•”“¢« ŸŸš§ª®¯¯»±¥Ÿ©©˜˜—’¡£¸  £‘®¯«¤¥‘ ”ŽŒ”š¢Ÿ¨µ§§™µœ£°› °‘¡•™•›’¢–Ž  “‹¥¬°¥¦¢ ž’’š“†‹’œŸ€dh]igKJMJSAC@IG;;F>99NMU_RSJ>O^^=HPBMMI8Nd\LELRTY[SUO\bHA?ZQAHAKA7FELKN>;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0;v]^?[U_gr@8<H–weA4Ÿ¤ž›ŸÂ§£©± £´©”±ª¦¢¤²¬­©»³­°´´Ç¿Äõ¿Ä¾ÊŶÁɶ¬µ©±¸¬ÀÄ´¸¯­¶º¥™«²¬«™¡§˜­»´œ¨°›¬Ÿ®´²¨«º²§¹´·²¹Áª·³Ã½´Å§¾®­·µ©¨¬¡–•‘¥£¢¢——¤®·­±´¶Ÿž¨¤™””“£ ¶¢¤¥•­±±¥¨¤ š™™•—¨ Ÿ™¢ž¯³¢¦˜¯š¥­˜› §“ž–š›†— ”ž“‹¨©«¡§ šž–™‚†–‰•Ÿzek^mkNQNNT=CANC;:I?77QN]_RVQAWa]BISHWKH:Td]NFON[W[RPQX]GAB[PBG>NC9HGHNP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1[cZ33906p[bH05JqjWDWFŒyfC;¤¤œ ¥¿¥¨®® ©µ©œ·¯«£ª´¶±°¸·°··¸Å¼Ãǽ¼ÃÂÈÁºÂÆ»ª¶¥­»®Áø¸«®²¼£•®±®³—¦¨‘ªº©¡§°ª ¯´³«ª¶µ¬»¬³²º·¬¹°Âº¾¿¦Ãª°·¯©««¦˜˜ª ¡ ‘— °®³ª°¸™›ªŸ™–’—¦Ÿ¶¨¤¢¢¯°³«±¦ªŸ›ŸŸ›¥¡˜£´°œŸ‘”¦›¡ªœ–¤¢˜›Œ—š”–—ž”‰‘›™”Ž©¨§Ÿ£›™›“‡™‹}Œ—†šlinbnoXQRZTACDU@;:IA7:XPd^PWWEY_^MLSN^LJ?Zd^NIQN[UYPKSWZI?DXPDF>N?=IGGQPB=DFBM?:2D?77547?=95E4+75/251.-.,1>*'+=\p=>1.1e[e@1747gYaF(@8m}i\V;‰{cC=¨Ÿœ¡©¼¡ª¯ª¢°·¨¤³²«¡¬µ½®³¹½»½·¶Á¿ÉùÄÃÁÁ¹Å¾Á¹°¶¨¬·²¼¿¿µª¯²¸Ÿ—¬­©¯˜©©Ž§»ž¥­³Ÿ«¢±°³¬ªµ³µ¼­¯±µ¬°µ²ÀºÅ·«½¯±·¬­©¢±¥ž¥¨ž£–˜Ÿ²©²©©²™§›š”Œ ¦¤´®§¢¬¬­°§²ª°©¢›ž¨£ž”¡™œ¨·©˜š“’ŸšŸ¢ ’­¡››ˆ—šŒžš”‹——š—¦¥£ –––“€•„{“„Œ—gmrhqs_GYfVDCNXDZ9HB5>]Qh\NZ]H[_^NMSXdJKC]c`PLMNXWXPJVVWL=EUJEDAM?AFHHQPA;GDFK=87B=68719><65D0+80/05/*,/-*=,+%2+*5K1.'__aU151=`V_8)C3YU\hK5ŒzfL@¥š ¤¬µ£¬¨¥®­µ¨®²¸¦§°·Å·±·¿Á¶µºÅ¾ËĹÃÁ»ÀºÅ¸Áº³´¬ªº·»»¾µ«¯±·™™¨¬¬¬­««½ž«¯±£©Ÿ±­³¯®¶±¹¶ª­¯²¨¶°´º¼Ê²ªµ´±´°¯§¡³Ÿš¨¬Ÿ¤••š™±¢­ ¥¯–¢¤™™’Œ¢¥§²©¡¦±«©´¥®¯³®£˜­§›—žšš¬¹£˜”‘™¡™˜•®¢ —ƒ–›ž™—‘Š”“žš¥¢£¡™–“’•{Œ…z‹ƒ‹“lnyov}aF`jZIHZ\={JGE6AcTi[M\aK\][RRSbaLKE`a`QLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`Va.5(C^Q\.+A/JGP[G3cXTLEš–Ÿ°¨°©¬¤£®­µ¨¶²·£¬³·É»µ»¼À¾µ´·ÃÀÌǼý¸¿ÀÀ¸À½²½®¨ºº¸·Ã·¬®²º–—§¯­¨¤²ª”¯»¤¬²²§§£²´±²±µ°·³©®¬²§¸¯¶´ÃŶ©µµ«°­ª§£¶žŸ§±Ÿ£”›˜”±ž§›Ÿ©©£œ•—¥¥¤·§¢±³«§°§­¯´¬¤˜ ¬¨œœœ•ª¹œ•Œ™¢˜‘™©¥¢™†”˜‘žœ˜——‰——š¨¤ ’–’•v„†{†ƒ„ŒŒnqxv|€\Lel\KNc]>b{GI8GhWe[L^bMYZWTXUj]PPHa^_PKGQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANIg27'FaLV%-B.=ELQ<3qjLED‘˜¤­¤¬­ª¥£°±³©¶¯µŸ«´¹Èº®Â½Ã¸³²µÂÃÎÄÀ¾µ¾ÁÀ»¿½´Ä©«º±·¸À¼°­´´ž¡§±®¦¦±¥±µ¬©²°«¨©µº¬µ²µ«³¬ª«©¬©¹®²°Ç¿¸¤¹¯©­­¦§­±¥¤£®£¨œ›š®™£¢¢£¬Ÿ£ Ÿ¡©¦¥¸¤«´´¤ª«©¬®¶®¢£¨ªœ š›“¤´™ŠŽˆ‘£¡–•Ÿ£—–‡••ž›™–•ˆ˜“•™§¡Ÿ“‘Žw~„|}~‡ŠŠrts~}\Scn_NYg\FD–[G:MnXb[NabOVWVWTYh^QSMc[[UKFOTSNGIVS\N;P^JBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3De;6*HdHJ+:I?3CIS,>l@HIš¨©¡¨¯¤¦¢³³°³´¯° «­½Ì»®Á½Ç±´®´ÂÃÑÄſ³¿Âü¿¸½Å¨­·¬´¹½À±¬³®¢¤§®ª¨¥°£©°ª­ª±®®¬«³»§¶°²©³©«¦¥¤®º¬ª±Ã¹´«¹©©¨­©§±¥©¤£­©¨¢ž›¢¬•¤—ž™¬¢§¨¡¬¦£­¬·±° ©¢ ª®°¬ž§¨©š£˜™¡¨˜‡„‹‹Ÿ¡˜Ÿ“’ˆ‰“—¡–™–‡—““—¥œŒ’‰ˆ„{w€‡…‡ttr‰wl_Y`ncQsr\K;„|F>WuXaYOd\NVVUWQ\b_SPOhYWWKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=398;*35>10485(5/*,.30;),,'%234$,2-860)(2=^K0.IgDF8<B05EKX1@”]ANF•–¬§ ©±œ§¨°µ¬·´­ª¤«ª½É¼±¿¹Ã¯±­³ÄÃÍÎÿÀ´ÀÃĺÁ´ÉĬ¯·®³ºÀ¾´¯¯¬§¨ª±©§¨±¥³¬ª¯­­±®²­³»¥¸³¬«®§« £ž±¸«ª­º¶¤µµ¤ª§¬¬ª­ ¨§§°±£¦¥¡¡¬–ª¡“› ¦ž¤¢ª£¬¢ž¦±¶¬¬¡¥¢š©ª®ªœ¡¥¤¤™ ™–˜ž”‚ƒ‰…¡ŒŽœ’”Ž…š¥›“’›Œ“’’”£šœš‹‹‹|†‚zuƒuxŠ¢†xj^`nfWe‡dN@g’LDbzWbXRfUMVVVTO\]aUKOiWVVHJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*49?./463)4+*,+.#4.-+&(+79*&6+<.2,&07XZ.0JgAA<<C+:JO^4D‡CJID–¯¤¡ª¯—¨§­µªµ°ª¤«ª¨¼ÁÀ¹º´¼µ¦²¯ÄÉËÑ¿Á»¸¿ÀúºÂÄ®²µ²´¼Á½³²¯­¬­§¶ª¦­¯ª·­§°°®±«µª¶¶§µ·«¬¤©©œ¤ž´³©¨¤³´Ÿµ­¡ª¨ª¨¬§Ÿ«¬©¸µ©©ª©¡© ­›‘ª¡ ¤£¦£ªœ¦´®§¤©¢£—¤¦§ªœ¢¤£ š˜ ‘™Žˆ‡„žž‰†ŒŒ‘‘“…‰—£šŽ›‘’’ ˜š—‹„t†‚~xuƒ{x~‡œpqfgqx\atˆjO]˜VHmyUeVSdPMVUUQOX[bVIPjUWTGOXUI>IHOQPxMNV=<KD?@A<@CUC9AK=5;E23;:7*4:=+-341*8**+*,)*(/*&)%3;,$2)2/22%/3Rc02?f=NX?C,?LT_/Il8RF;•Œ¯ ¤ª«™©£­®²´¯©¥¯©¨»¿¼Á²°¹­¢¶¯ÈÇÇÐÀ¿½»¼Ã¾»Ä¿¿¯²³²¶¾¼Â±²´«´©¥µ©¥­²²·®¢¬´±¯±¹«¸®©®·¬ªžª« £¡¶­©¡Ÿ¯²¡´ªŸ¨§ª¢ª¡¡¬­¨½®«®­¡§§Ÿ¬™°¢˜¢¡¨§ž§›™©°©¢ž«¡¡’¡¢£§˜™©¥˜˜™‹‡•ˆ}Ž†„…¤—†ƒ„ˆ‘’†‡–¡—ˆ’ž’“‘•—‹†‡xt€|twy€{ut{k‚‡¤vi^elugˆŒ|RVo^KxsTdSR_MMSZgNMWYeYGSiRR?BNQaQ:IHLSIqQLS;<I?;<=;@@W<<>H73CB15:93-5::)-31--6)(+-,52#2)',%.;.&1.0-14%,0Mh:38_=ad?F1CP[[+HO;YD3± ¤¥©£¤¢¬¦³²°¨¤°§ª¸¾Á¼±©¹ª§®°ÉÆÇÐþÀ¾¹¿À½É¼Á¸±°µ²º¼¹À³´¼¬¹¬£´¦¦«°µ·±¥¦¹´¬³»¯¼¥­­¶«­œ©¯¤Ÿ¤¬ª¨œžª²¤³¨š«§ª¤¨¢©§ª½ª´°®©¤ ®œš³£–¥œ¥¤Ÿ¥šš¨«¥žš¨¡›‘› ¤™—©ª’™š’‹ƒ…~‚ˆŸ‡ˆ“‘‘†ƒ•›”…“£Ž”‘‹‘›“–‡Š€qzy}|hv|zuqr~j†y…ˆd_gcr…{mhy]^UAW{mTaPRYLLNpt]IZ[hZFVfPC>JODCA9HGKS?jaIQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11&/>KI1%90%,,09/,,+6'17#-/GjI14X=fbAJ7GS`U*=;F]@*‘°˜žŸ¨¤¢¡«¤¶±±¤©°¦­¹Á½¶±¤¹¬¨¨°ÂÈÈÌ·½¿µ¸Á¹È¶Âµµ³µ²½¹º½¶¯¹¶¿¬¢³¦ªª®´¶³¨›¹»¨°¾²º ®´¶©«Ÿ­±£œ¥¨©£›¥°¦¯ Ÿ«©§¡©›£¨ ­¼§®°®¡ª¢¤®žž­¦˜Ÿš¡¢œŸ›™£ª¢šš¢¤•–”Ÿ¡–›–¥¬ŒŸ‘‘Œ‚Š€€€{š•Š}€ˆ’‘‹†“˜‘†”£‹’‘ˆ™”‰}yk}vxxbzzqoqtxk‚uk‚gcgbnsŽmbjo`o@\ylU^NQRKJMTYVM\^mWEY`P^OHMDF;7HEKO<rhJK9AE;;==;;=J49B<3;G<4?18-78;2(09/,5..=-*L>*49&'.34.0+/4&,:$40AhZ13S=e_DL6KVdN)=3R^>#‘–¬˜ž—§¢ Ÿ§£·¯­¡¯¯¨¬¸Ã»´® ¹¯«¨´ºÇÊÇ¿¸Á½¯´¿·Ä·Ã³°º±²À¶»¾·ª¹¸¾ª¤µ§¨©¯¬¸¯§˜¹»£­¾´´ ­·µ§¦§°³ ž¥¦§ ¤™ž¬§¨ž ª¯§ ¦–¢¨Ÿ±¸Ÿ¤±¯ «¡¬¤œ¦§¨š›œŸ£•œ›š©¦–›ž¨‘˜“™“™–¡ª‘›ŠŽ‡}‡‚Ž}|¡‰z„Ž†ŒŽ†Š“šŽˆ•Ÿ‰‘•‚Œ—’}…|sp|qst_xwinqqpk€tezlgedbf†€`[rjrMM€iXZMQLKHPSPGL[`oTFYZRgOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23/:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%53=fd24M?e\FO=RZgH*?0]\5(•›¦˜›•¬ž¡£ ¶ª¯£´³©©¹Å·³® ·­­¬°µÅÇÀ·¿Á¹°µ½·¿»¾°¬¾°³¿²¼Â¸ª»º¸§¨µ§§ª¯ª±®¤—»µ£ªºµ¯ž±¸¯©¥§¯±›¡¤ ¤£ –›¯¥¡ž¢¨¯¡ ¡’£¤¢·°¡¦±«Ÿ«£®˜ª¥¨Ÿ˜›¤“™›š¥©™››¥•”—•œŽ“˜¢©¢‘Š‹†z„~„‹zŽ—ŠŽ‡{ƒ‰„ŠŽ†“˜ŒŽ•™‹—~†—Œz{prwnos^wwdlllkj…ogrijei]ds`[kviZJ^[YNOKHHSVG38^_lPEYVZeMIIEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<"8R=*113>D5,-'42*;+139cm74GAf[HTDT]hD.<2dW,1”¡¡–”›ª›£¡¢¡¶©­ »·¥¬½Å´°¯£¶°¬¬®´Ãü³¾º¶°³¹¸º·º¯®À³³¹¯¿À·¬½ºµ¥¢²©¦¨±©«°Ÿ™¿´¤§´µ¨ž²¼©¨¥©¯«™¢§œ£¥”— ±¤™ž¤©¨œ¡Ÿ’¤ ¤¸©¤§®§¤¡¨“ ©¢¡¡™›œŸ’™›–Ÿ¢ª›š˜ ”‘•—š““¤©¤‰Š†z„{„…|Š‹‡{‚…ˆ‰Š‘†—’’‹””Ž”zƒ—‹w~|ltrlks`wthhjggp‡hhhdfij`jcjh[f{b`StT\[RLJGIPT@!*h_iMEXU_`LJHEC.:B<F<6KPD8:D357==895?:;4>8@K=>93)8><:9*6@3.E4(+,?0-N?.+-7,1195,&.5-80576`tA3CDh[JWGU`hB379gP'2ž¢¤‘Ž£§™œž£³¬§ªº¶¦¬ÃÁ¸±¬£¶®§­®¶¿¿¼²Á¶°­²¶¶¸¶¶­ª½³®²±¼¾·¯¼»±¥Ÿµ©¤¤³¦¨­œÀª§¤¯³©¬µ»ž©©¬°¥˜©¦¤‘˜¥¬¡˜¤©¡›¡›–Ÿ§µ¦°ª®  ¡• ¦ ¢ š›™›’˜“¥¬¡—–”“•˜‹Ž˜›© ’‰Š‹‰y…v‚‡‹ƒ‰~€†‰‡‡‘„—”Ž‘‘‘Œ“zƒ•†s~~fyojjketskbgddvceffejjckr[_Y]lcaNiXZ`VJGHKMSW>9^lhHDVT][IJGFA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A=-5B37=+*,0B*JK./*+3722(57$+7.72685]yN2>Hi[LZJVbf@:3BhH%5š£ Œ«¡–– –¤²±¢²½¶¡±Å¼º²±£·¬ª­©¸¼ºº­À±®®®¶¯²¸³©«¹±¯®³µºµ°¸½¬¦ž´©Ÿ °¢¨­›¢¿Ÿ°£®±¯·®µž­¯­­¢™¦¨¥Ÿ•š§¥Ÿ˜¤¢¨šŸš“œž¬¯¦º¨®¢¡š›ž™ž¤š¤—ž˜›”˜Ÿ’¨•ª§š“šš’Œ•™””›ª§ŽŽŠŠ|‚sŠ˜…‡}‰Š††‹‹“…•›“’Ž‘–Ž€Žƒofymgkifprk\gcct‚bfgjnlgjjin]llrp`TcicfZIFMMOXQPUae€UAWSYTGIFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9A1-+.3<;K60.+,-24;6#3*)6.55465Z|]19Kj[M[KXdd@A1JfC&4‘¡›Ž¯™“¡š©±¯ž¸¿µ ´Á»¾º±¦·°§­¤·¸·¶¬»®¬ª«·ª³·®¦²µ²®©°µµ°²µ¹¦¨Ÿ´§œ¨ §«š§½—¬£®°µµ­­ ±­°¨¡›œ£«§›”›¦£š©¢¤•šŸ››¤ª«ª» §¤ ˜š™¡k¢–™œp‚•™£€u’©§ž””ž‰˜š€–Š¢y‡”ƒmjwƒql†‹†~…Œ‡q_dag„˜…kŠ”’tw‹„~ƒ€g‡€guheW\hsnMPicgr…h_efnmj]`aŠƒ„eNKD9GTh^JHQQUULHSapteF[QUPFHEC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=A@@=28@E=1,,08=G701.*.*/568,#1'214:276Xl16Ok[N\K[fb>G1Qd=*.‹¤™†•°›š“ ›ª¬ª£½Å®©·Â·½¼­§·°¤ª¢·³±²°¹¬©¦¬´¥¯´£©·µµ¨§«¶²­´­³¡¨Ÿ²©¡£™¤¥˜«¹“¥¥¯³·­¯¥ª®ª¬¤¡žœ ¦¦›– ¥¤››§¦“žž—¨©¤¶°¤£¢œ–˜——£ˆ¡Ž’š† ‡’œ ¥¦ªž’’š‘ˆ„sxŽ…ˆ¡v‰i—‰f~sx oˆ‡„~}¡  ™€}‡žs†Žu›Šl‡ƒmieczlraS…mbli˜qXiqoˆY^i[ll[ˆrnzr…f†„Z_GN?G_NFRVVQQRWUg]MVIRROFHG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82*/1<I9/01.*.(-4573%&2115>1<8Xƒu25Rk[N\L\g_=K1Wa7/(Š§–ƒ«˜˜Ÿª©§ª¿Ã®±º¼·À¿ª¥·°¨¬¥²´®®³¶ª¨¤°­¥´²œ®µ¶´¦§§²°¬²¨­© °§Ÿ£¢˜Ÿ¡š­²“£¥¥µ½¦­§«ª¬¨¥ Ÿ˜Ÿ¦£™˜¥¢£˜œ¤¨–“¢›““£¥¦¡¸¤¤ £˜•“—“œˆ¯—”‰©‹–¡œ…±€£¬“™”y‚Ô¨€‡•ÁœÆyx±¥·—e€Àœ¿y„…z’„}‘Êr—»œÅzrµ¦»{€m—±«°yhlX±®nei¼’¼ngznrØ~Skc¶²~s”sš¡ªWOWbOVNFU[XQPS]W[QA]DPNEHI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>:B<?A8:J>52*22BE/.32.+/(-/186- /416A1=9Wƒw21Tk\O[M^g\>L1[]41!‹§“§©Ÿ—œ¥¬±¨°Â½²µÀµ¶¾Á«¦³¬¬¨¦®³©®¶³¦§¥´¥§·­œ³±µ«¦¤§°­¬°¦©œ¦£¯¢ Ÿ•™žœ­«“¢Ÿ³º£«©¢­®¥¡›š™¡§Ÿ—š§Ÿž—ž¦§‘œ¦™“¡¦¢¡±£ŸŸ£—–’—’™…¯kjŠª~fƒ•†­dp”™¦”p®¡¤~x»}l¡v±_j´[¥€eœagƒ{g€kyk©e¾qg¦‹u±j{±xt’”cnm§n[„¡Ehf‡–Euœ`~g|¤§‚Z`Œ«h€•xyj§7J¯\XSld[KOX`\WV;N‹OWW/ITSJDFF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=03.33E4..53/+/(.0.:6/'$203B/>;U‚v2-Vj\OYL_gY:M5_X30¢•ƒ­§¥ž£¤ª±·¬µ½¾°¶Ä±·ºÁ¦¨°ª®¨¨¯®£°º¯£¤­²£©·§ž²²°£¥¡©¬®«¯¦¦¢¡¯š¡›–”–š›¬¤•š¡ž³³¢¬œ£­­ ™–Ÿ¡¨œ˜ž£Ÿ›™¡¦¤œ¢™– Ÿªž§¦¡š ¡••‘–š…µ›µx…©™µ™v†³›·~“––©”k¦{‚†ˆ“”“w«gk±\«z†”t‰r‡‰—x‚‹—‹ƒ Žƒ°vwŸqlll|‹N¤XHbb™~ch¦_yruS“‡^Q©mcq}†€bœ.Q¡o[Skh`LJ\eY\ZB>²{XXA#MhFCEA@A19>88:84;99<9:A:E::;6:CB8=?KNG:5:@FB@AD<FD;0201;F-0.940,.(/3,>831/2-D1=<S}n3+Xj\OXM_gX7J8aU50” •‡³¦¦¡¯©¨²¬©»¶Â°»Á­¸·¿©¬­­­¥¬±© ®»ª §³­£ª´£¦²²§£¢ž¦ª±§¯§¤ŸŸ®•ž™”””˜¬ ™™¤¨µ¯¢ªª¨ª›”— ¥§šžœ¢ž›Ÿ¢¤¢•›ž—™¢©›¦šœ›¢¡—“‘’“œƒÕ“™¹p°Á~ņ|֔›»|š•¥¤{Žˆ¤ƒ¥ƒz¬yV¯zˆ~Ÿk¹[ºw‡„~¦‚”{—zªxz±nŽ„t‘¼…o”P¯§ÅŠQ zc`ªbsrˆm—ˆ`Sµ´È…€‰|c¤3Bv]PjicP@XhZdaJHMqQ\QOYfZCE?E?0=<59;74<;8=:<C:F:;>6:@C;6@OLH<9;DHCBCD<EF81211DB./0483+-).323971#%5*>3==Qwj6*Yi[K]O_fT7H:aP71%›¢”˜²¨¨¦´ª¥´©¤¼·Á°¹¿°µ´º²´§°¯¢¯²¥Ÿ­µ¨š§¸­¢¯°Ÿ³´° ¤žŸ¦©°¨³¨£›œª•˜—•–“– ©œ™–§­°©£Ÿ­¢¨–•› ¥ ˜¡ ¡ š¡¡§šž¡ž”˜š¦ œ§•››Ÿ¡˜’”ˆ²nhµq«‡nŽ¦r´sr¶{š—¤‹¢~‘¡¦±wƒ‘ÒÒv\®{…¤o›ª¦k‡…}­}˜™Ž{±q’žŽw³e—t„žožg”QȋZÂ\ yb_¬`us‡b—ˆ^Yʝo¿uMKµSUÆdTQjceXAPk`lhPVGJ9=URZWXID?J<2?;5=<46>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>HI91746A?/.24252-).26,742&60;5:=Pqh9'Wi\BOT_eP5G=`L620¢’¤±­£«¼­¦´¦§µº¼²º¾¶µ³¹¸²¤´² °±¢ž«¯£—¦¸­¤±°œ´·© ¥ž¡©¤±§¬©£™›™§•“——’¡§Ÿ•“¥ª°¦¢—“­ ¦’“Ÿ›£¥ž•š¥¦ š¢Ÿ­™¡ž•›¡œ¥••™¢ž•˜•‘›…¬{w¨v£ˆ†©o­Š‚§ƒ˜˜¡Š’›‹¢“š‰®„€‚³\r³R®}‚‚£rØ~x†~†š™v¯†‡‘œ‡v´ašeš‚‚•m’Z°XKšu˜yf`¬^uwˆh˜ˆk]¯w•žxl5yÈ®²_BTo^g`EPm`pmVVM.feiSYP;BE@L:5?91=<16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK96<46:>/04333.2..18*.32%!03767=Pke>&Vg\@>V_cN6GB_H:99 ž• ¹±—´Â®¨²¨©²º·³·¾¸·±´º´¤·²ž³¬ŸŸ¨«ž”§µ«¨°±ª­³£›© Ÿ§¡µ¦¥©¢˜œ”¤ “’›—‘”¢¤š’¦­¯¦¡–™© ¢Ž¡™§¤Ÿ•™¤¨œ¤ž¬œ¡œŸŒ“Ÿš¡™™›–—¢ “—¦†©}}¥x¡Ž‚ªp­‹§†–Ÿ¡‰˜˜ˆ£ƒ’ˆ”«}€‹yo±Z¨‚‚ˆŸztـwˆt¨Ž›Œ’¤{”Ÿ„z²^d ~ƒ•m’]«[Z“€‘hgªcq{k˜‡s]«Z‰ ŽkoeOJC¡\[Lt]bgM[a_qs_KW7Jœ˜XGE=HGAM35A8.;>05A78@<6=<F?:<6?=B7.HVJEAH6KIN@IK@EN::@5.;>102144+*05/7,&21($$6671<PeeA&Uf[?2U_bL7FH^B2?8£ž™šÁ«—´Â®«¬©¦´°·°µ¾¹¸±°µº¨º³Ÿ¯¤¤¦¦ž“©¯¨®¨µ«©®¡˜  ¦¤£¹¡¢« –š¡Ÿ”“ž™“˜žŸŒŒ©°°§ž—›¨¦ Œ‘£—§ª¦”—¨§žž ¢­¤¡ž¡Œ“¡˜Ÿ ’ž—œ•¡•–ªœ®mr´s©‹uŠ§s´xs³€‘¤£‘Ž‰¤‡w¸p{‹¢jk¶Z¡…e——i ¢§n”r´t“™~²j…‘‡­ju³af¢o‡“k—]­`M¡|†’Rs£ky~o˜‡q\¯V<œwfTon.\§OcSkebmYc]ap{cT[S>=nq3CB@?L:!7@6.;@37C58??3;<CDBJFMIF62JTKEBI6IJP?HNCFP=<E50;;010/75,+,426/#00,,289/9N`eD'UdY>/U^aL5FM^81C8¦œ›ž¼¡œ²À¯­««§·©·®µ¿´º¯®·¶ªÀµ¨© ›¥£¡œ‘©©§´¢²§­© —œ§Ÿ¤«¸¢¬š•˜Ž£¢•Œ ›˜œŸ‘“”«¶±¨™•œ¬©—Œ“¥˜¤¬¢‘•ª±£Ÿž¦«±™¡£˜¢– ›–œ–¡“œ©œ”ª™‡Ô’š»s°Ã€Ã†~Ֆ›¸xˆ˜Œ˜‹Œ§ˆz¤¶u~wv‚š²`ƒºyÀ}v¸cµŒ‡©}•«©q{t¼ˆ§ ia¦Ž¯¡~Œu‡«}¾os¼t²ƒtxŠnšˆqn¤t½^w}Zay¼kZV\jy^j`fgcmxoY\ZC@@t@CG+4G"';?10<?7:B99=C4<@NZ^```__ZPPRKEFJ4HLR@JNEFOB=E84=9020.87-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-7A9¨›ž£½¡—²Ã°­©ª¬±¦·¯¶Ã°¸°­¸®­À°«£¢£¡œ›¨£ª²¤´¥¬¤ž•šª˜¦¬¸œ¢­—”Ÿ¤Ÿ’Œœ¢ž—š‘•“¯¹²¬–˜¤¨§”–¤œ£¬Ÿ¨«žšŸ¨¢³Ÿ£¥Ž§¡”¢›˜•£˜¯Ÿ‘”©ž…˜¶‘Œ·•x‚“šµwmknsoy…ŠtŸÁ»½š{±¨p€s‘¹ƒ}‡†‡|Š‡˜|¤»¹½œty´£tw—vt°u™žf‡j¶trqx¶Œ^z}‰hƒynzc‹¬pu…X[§jEdZTf`c^cQggpluCNQLC:ZM?K2;/ 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITBKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7LT_G'SbW8*O^]=+:VU'>;<¨ž¡¢À¥–µÄ´¬ª¨¬ª©¹®°Å­³²­µ¦´¸¬©¡¡¥ž ™“ª£¬ª¥µ§¦Ÿ›• £¬¤¼¥ ©–“›¡›’¡§¡’—”˜•²µ·­™ž¤¤¢‹’‘¥›¤ª›•¨¤¥›™¡¨¦§¤ª¡’­ž—¤ž˜——ž¯¨“›¥¡j}iš¥w†r}šŽtyd‡{½¾Àºo“ƒr–ˆaskZ_›Šacˆ•k`€–dnžwc–lš•”e^`bp™ˆir‹}†•gkrtx}b\xthP]nƒ}{‹kXkz‚sJJo†pNtLEX]gaL[Xfc_O[muiqRQDEM;GI=M?2,2A?8/5?C<9;@;=C>RVVWYZ[[\]`aaa`\UG5DFUEJOHFPIIH;8=51:.0;:.0-76=5&"/*2,%;8-7JR_I'S_V4)P_L(2=[O'?2>© ¨¢Â£›µ»¶¢¬¥®§§´±¬Ç«¯²ª³¢½°°¥Ÿ¢§£›™™«¦®£¤´©¤›˜• š¦­¨½§¨¤”“š•Ÿ™’–¤©¨ž‘˜°³¿¬›§ž§¢ˆ“‘©š§£›šª £™š£§¬£ ¬£›±›”§ —•Ÿ–°¤— §˜š››¡¡—¤¡™œ™™™•gm}qw’˜”’†Œ¶«‡˜–ŽŠŒ˜–‡”•‹„“”’‰Ž“”™”˜–™Ÿ¡™š“ œ‚z¥…mk}}€u‹Šq‚xyvu‰|‰jstƒuev}wkozm_d]phMYZfj_WZoymmfUOFR9NYMRO(+:KB635=@A::C><ENSSTVWXZZ\\`bba_^^[TKCSGKNDGPLOI<:;389,2;810)6IRO8")+/2#4;*7FO[J&R^S10T^:+=8\J,<-@³¡³£À¡¤²²· ©¥²§¥¯´ªÇª¬¯¤³¤À§³ ¤¤œ£••Ÿª¦¬¢£¶«Ÿ˜–•Ÿ—­©¥Àžª£•‘š—ž˜’“¡žž¢§“’š©¨³Ä°š««Ÿ––¨ªœœŸ«˜ š›¢¤¯§¢¦¨ ¯˜—§™™ žœ¯ œ ¥”–‘—“žŸ”¡— Ž–“ŠŠŽ—®|–œƒ’‚‹«©…™—‰„žˆz„ˆ†š’ˆ‡Š–›——£•˜’œŽg¡³¯…Š…v{’Š}wyzofy‰kuyˆsis{vƒ†‚judzf`jecdfkYk{oij]SLPD^TE@?>,4@F;45;>A;<?>>HNNOPSUVVXZ[_bca_^^]^]XVJKLBIOMRJ;<:786/2964.(&$-1./)+*7%+<(6CMMD/T\Q05N[17E3[G5<,@´¡¹°¿¬«¯²± ª§²­¢¬²¯Ä¯©ª¢±­¼¢³›Ÿ¦¢¡œ˜—§¥©¥¤¥²´ž”“™™°¥­¾ «¢™™”‘•¡œ—¨„ž¬¬£´È´ ª¤«—•—š¦¨šž£ª“žŸ ª¯ª¦¤¬£¯›Ÿ  ˜¤žœžœ®£˜ž§’––›¢—–§œš–e‚’|e~šcyŽmhk{’¥«je›˜}g†Šeeih{Ž¢lh˜‘£wkjŠ˜¢ž—skmz„ŽˆzXf^†ƒ^mŒŠv\hswv‘ˆ‚mwxsny„tv‰‡Žƒ|j‡Y^lue]s‰ik{pkc_RNWIdXAJ4>F7?FD71<=?AD;;DGHHILNPRRUW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%/*+'6*$;'/AJ[J/7ZO6)EY/DO2YC;?.=¥ º¼º¯¬´±ª¥¨­®°¦­¬°»°¨¦£¬­°ž¬–Ÿ£¢™™¦ªœ­£¥§¨²®ž”¢¢¯¥µ¸¥­¢Ž™ ™“’› ™™¥–|¥¯£¨µÅ¸¥¢§¯žœ”ž¢ž£›¢¨¨‘ž ¡ª°«¬¤«¡ª›§Ÿ§Ÿ«– ›¥¯£–›¨•Ÿœš‘¢•œ©—}½ƒˆr´r„†­hx¹Ä¸q”££z¦™™r«‚|ËÀÀ»qŒ£ˆƒž|–˜‰À½–ŒœÁÁ|‚|“šÃÀ~l¥²oŒoÊz›vƒŽuy€€yqz‡pw…Œ“ymx”bg`xd_e‚b^sglddYLVIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNQSVY^__`_^^^^___]\SMPGUNA??=6468276*&%#)*&.+*)109*#>I[L*#BP.#F[3PY/UAB;/8–£¹Ãµ°°Áª¨”£¯¨°®­¥²³®©¤¥¥¯«žª˜š¢Ÿœšª¦¡«¢¤¨¤¤´¤œ¢’¥­«·³§­¢‘˜œ¥’ ¡˜œŸˆ§­¥¬®ÁÀ±¡©®©–’ž¡™¡¢©£’  ž¬¯«®§¤¤¨¡¦¥¬¨‘£š¨¬©šœ§šªŸ•–£”Ÿ¡•›~Δxz¤y•–›_®^Ž¨‚£¡|§–›s«ƒ€¯^cª{¨‡… t—“ˆ³c‚«† ³j„¯u}—ˆ·bƒ­Z£Ínv{Ú{™p}ˆ’v}ez‡vvk|‡n}…‘~mƒ`qlph`_ye\qgjdg`RTRW]KOD5AHDD8>6;@?A;=8@>??BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5578164('$!',&&/(&+360$7;SL+,-J0';\;L-!P@F4.1­ÂÀ¿µ´°¸—‘£ª¨­³«¥²ª«ª¢«¦®©Ÿ¦›™¥˜œ¢¯Ÿ Ÿ¨§£¥ ž°«š•¦­«°ª¨«Ÿ”‘šŸ¤’Ÿ¥—ž§£Ÿ¯¦­±©Àdz¨©±®–’›¡—Ÿ¨©ž” Ÿ­°©¬«œ¨¨¥¢«’«²–¤¡ª©¢¥¤Ÿ®Ÿ‘˜¥—ž™’“— q…Œ—u…¨†q±}žr¬¢Ÿ¥Ÿv«‚}­œs­¬‡†Ÿv™’{|—~ªˆ¡‹‘‹}«{‰• {­WÅ{p“Á}•lupŒmeve…oawnro‰Š’Žƒn“’fpuuqagmf_ohingdWT]aZRSC9JI@D<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;91478452&# 1' 1' '45-&7=WJ-<(=1)3W@F!G:C1.+°ÓÆƲ³Ÿœ¢Ž£¢¢¬®¶®¨±¥¨©¦­ªª§¡£™¢•Ÿ¥«Ÿ¡¥Ÿ¨¨¢ž°¬—š–©§®«¨¦§ž—”™£¡’”¡­›§£¯­¥®¶«ºÎ±­¦®«–•œ¢˜ž­«œ– ™Ÿ©³«««œ­«¥£¬š®±¡§«­¥—¤©§§¯ ”¢¢˜“„¤j¤u‰z©tz²p‚¦Š™Œq‰ š†¤`aR¬…®ƒ›v­‚¨†…Ÿ{™—…zf€£‰¤˜†‚£}©~–ˆ®_|©Vž£’z£Ÿ€{îċr¯³³¹qb©¯ÂthŒŒ˜Žnœ•qozxyplfferpf}jc]W`jXYUMMQLCCAB;C@@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799664,&$" ('"+-"$.!3-&@DWH,G+55*2PKL# A9D4,'ÃÉÖÔ¿¡™«§ ®¢ž¯´°®©¬¢§¥©ªª¨¤¦ ›¤ž¦§§£œ«™¢¬¡£Ÿ¯¡š’«¤´®® §š•“¦¢‘›¢¨  ¦±¦¦©²­·É²µª«©–‘œœ¢˜Ÿ¥³œ™ ”Ÿ§¬­¥°›­«££ª¡²­¡©²°¡™¨§¬­³¡‘”¡¥–™{©lž„‡u«y|°o‚¥Œ‰Ÿ–– •Ò¸´·É²_`”©ƒ¥ˆ‡ z™•šxªÉt™¤”©©’›€ŠšÆÆyg¡‚¥tŸŽ‚}¯]o´b°uK£‡m§G‚“dŽž’|q™•q{u~|n\fjsqfk_aYdn\_YIMMKEDAB>A<B?I;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75685/)(%&%$&),4ENPPMFKJVF*L0/=-5OTQ;<F2,$§¤ÀƸ­¨²­¬¤¢›²¸¬ª ¥š¨¤©«ª§Ÿ¦¦˜ª£ ¯«ž¥ ¬šž©¥§µž¢—“©ªµ±¬›¤œ ”¥¬‘šœ§£¡ª§®¢¦¨ª±µÃ²³ª¬¨“‰—œ¤š¡£®¥—¡•™œ¥¦­œ±ž®©§Ÿ«¢¶¬ °¸®š­¦°±°¢’–¦¡˜ž‚NxšŸz„£}ƒ¤…‡¦ŸŸ”„¸{|y¹‚Ìƶx›¡‘‹ž~š–—ŠvŸ—Š¥—¤©°…† „¬}š•c¦m¤p…|–‚r¬`£rp€š`¼}RUtŽ’£–{~”“Œv{s‡€q]mnxrj‚o[d_joce]KMQTAIHFI:9K?B108866877-*5==?BDGILNPTVYYZ[\__^]__\ZZZYUSOH@882.,*.+*''?QTVWWWYXXWUOUF<E3:P[T6?H,- ‹‡˜©«¤ª¸ª® › ¬²³¥ž •¥­­­ª§œ¦§›£¨¡³¯£©§² ˜¨¤”¢µ¢¢•—¢©´¸£›¡œ£’¡±™žœ§¦¡¢°®¦©£¶³Å°­©¬©‘‡œ§œ¢¤œ¥–ž˜™š¦¥«œ±¢¯¥¦˜¯¤»­¡µµ¬œœ³°¶¯°¤•œ®ž¢œ…ÑµÃ·y‡Ž…‘“€¦y”¡wŒ ’„¥‚Šqª†…µnriš¤œ•ŠŸ}˜™†‡s¯‚¦›£Ž¦‹“‹•›nq²]¥t“zœl˜{™|m©a¢qq~Ÿbs²¸hw”¦˜}Ž•Žz}yƒnjyizsou^eeonfh`J[XX<HH@U4@F><*)63.013)&4:;<=>@CEIKNPRTVWWY]__^^`_][Z[XURRQF:223//++(@QRTUTSTVWWXXWUUUUQOQ[U%!2AH$)%’sŒŠ­½¾¼¹´ž–§¤­µ¡¡˜•£§¦­«¬™¦£Ÿ¦¡¡¶¨£©§°£”«£Ž¥­£™šª³³¤œ£œ¨‘”—®Ÿ ž§¤¨¶š£«¤¶­Ä°©«©¢Œ„Žœ¢ ¦¢•™™œ™›™§¦¨™­¨¯£¥›¬¦½¬”¼¯¬¡®°·©°¤˜§¯¡¦–y¨}|°wŠ€¤¥ˆœm²p¡‡­|¡ƒ¨•˜€¬‰…®… •ª ¢—†Ÿš•€{’~«€š—‹ªw ’Š”’z¯^¤}¦§d|—rj¯]¤jp†™]`[Œ m•‘¦™‚•šŽ||„š€kn€ctn€z`gfqoihgCZa[=KU3U8BBC8$$3+''3, /6674359@CFIKMNQSSSVZ]_a`aaa]][ZWSPONI7042.*,ATVVVTTUTUUTTUTSTVWWXVUUQHFIJ#((½’šƒ¨ÅÁ¶À³žš¬ ­·¥£Ž›¤¢ °°«Ÿ¥ ž­™Ÿ¹¡£« ¯©š­¡«¨¤–‰›­°¬¦ž¥›­—˜¬¡¡¥¡š¥¯™¢©§·ªÁ¯¥¨¤ž‹€›šŸ¦ž’”˜š”›š¦¥¦›ª¬­¤¤ž©¨¾¥–Áª©¡ ª°·©«¤ž²­¦¨—u¯~‹œ…‡~º­Š™e°e•­}¡ƒ§•š¬Š„°…¦š¤¡¢‘…¡]lk³`­{{ƒ±mgn™™‰±[~µ\¤„kÈ¢dŸ€{»WvµY²}R®€z¬W€¡m—¨›Œ˜’š™|z‘ duc†xu}bkhrngfePUd\AV`>I(>9=4!",%2. *1/04579:<ACFHJLNPQRTWZ^```ab^_\[XUPNJGC553./@UYXWXWXXWWWWVWWVWXWWXYZZ[\XWWGB;ҟ²±¶½º³Á²¢œ¬¦¤µ¨ Šš œ³³ªŸ¤¡ž¶™¡´¨ª¬ž°­ž«œ•¯§¡Žˆ›¯«¨¦¡¥™®’˜¨™¢¥Ÿš¤£¦š¡£ª³ª½¯¤¨žŽ}‹›•  ™‘™›’š˜© £š©®¨¥¥¢¤¨ºžŸÄ¥£§Ÿ©²³ª¬¤¹«ª«”€©’£¯Ž›€‡¤—™‚€¸ÃºƒŽœ“„§—œ‚¬Š‚¯‰§œ›¦«‘~ֽªb¤¿½}~£‚ƒ×»¸µ†–”„ž½¾„m£‚o«„lœ€z²°Çƒi«°¼¬wv¡¾¼s€–Ž¦‘œ’š {ƒ“ž|c~{egzƒ|alfmkcQa[Sj\@UbCN)=:4/$%2 $(0496678;>ACEGIKMNNQTW]a\__a^`[\YTQMHC?=A?5=SYYXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ»•³³°¿¸±¼²¢œ­¦¥²¦‹˜¥Àª¸²¨¢À§¨³Ÿ²º¨Ÿ®¯¥¦•”°«—Œ‚›‘®¥¢¬ £œªŸ—Š£“§ž§œ›¡©¤™ ¢¬®ªº­¨£›—’|ˆ™‘¥›’Ž—™˜“©š¡™ª©¡ª§ £ªº¨Ã¢Ÿ¬¡©°²¨­§ž¸¥¬¬™svª¤¸†d‰ ph®‘‹nnw¤™Ÿu®™”p‹q–¨¤›˜¯¤smmmf‹xon‚™pzjqigŠ˜–™rij…ˆgq†d]ˆbjoY\f}v¦_apneeŒ“¡™™š“™¡}‰‘˜wfˆxil{€zemdhmcKdXJkZ;QfFQ'K:+# #,)-2.5:457:<?ABDFHKLMOQSV\WZ\``a]][TPLHD=:AB7MXZZYYZYXXYXWWWWY]^^]\\\]^]^][[UW^©•¬³¨¹¸±³ª©¡­ž£²ª˜’¿³Å˾·«ŸÁ­®¤¢©­ º£¤®¬­¥–®©‹…––¬ž¦ª ¤£ ‘‹¤“§™©š—¤«¢—Ÿ§¦¨°»«¬š›’’|„—¥˜‘˜”Ž˜•¨• ™©£›°¦¢«¹Ÿ¯¿§£±¤ª®¯¨«©¥µ¢¬¶•Š¡©¦·‰–£™ˆª›‘•’©³™š¢ª ²–¢¡Ÿ¢¡¥¢•¬§““‡“œœ•‘™“™‘–†¥›™–Œ””Œ‡„~g‰~t‚us‡Šp§lz““‘€Ž•¢—š™¥„‰—‘tk‘wrŒxx}zjmfepeU`Y@j[HdbPY+F=+'!750.!%2(*699469;>?ABDEJKKMPPQXUWY^`ac]^TQKEC>9=@ASX[\ZWXXXXXYXXZZ[\^__`^^^__```_YY`¦–©©¤´µ®®¢°£­Ÿ µ±¬È¾Æ»º«£¦Ÿ§Ÿ²ª¤·§©µ§§‘˜­¢‹‡‰›§•¬¤Ÿ™¨Ÿž’”£—¨š¨š•§¢¤‘œ¨š¡¶»§ª™š|•‹ ”Š•‘–”—¦‘ ›© œµ£¦ª¶§®À­¢µ¤­­®ª§¦°¶Ÿ¬º˜‘¥£§¶¢’ž§ Žª Ž“Ÿ£«°š £°¨°—£ œ£ªŸžž—¬ž“š¢œ”–«šŽ™™—‘— ’ˆ¡ž—•‡“‘Ž•‹~e‹…u†tw‡‚sœj†Ž’“‰}‹•’’˜”£”Ÿ™¤…‰›Š}t—t|Œ€s|€jof_qj`[`ZndPafQZ:GGE>2=>9/*&+)&&3166589==?AACIJGJKLMSSTUZ``iaeVPKACB:9EMV[^^[Z\[[[\]]^_]^_`abbaaa`bbbdb\[c—•£¦¢¯±«®£©¦¬Ÿ§µª¤µ½°­­£¤›|Ÿ¤³¥¦±©—›¸¦£”™ªœŽ†Š‰œ¢®ž¢•¨Ÿ ’–™›®‹ª–ªš©š©Ÿ¹¶¤¥™œˆy“‹š“Š”‘“’—£ŸŸ¨žŸ¸¢ƒ®µ¢®®t¢»¡°žvxž§¯¸“t«£ž‰«d\bv Ž¥Ÿ„˜}m’³¢¦­ª£eŸ’syš—q™©˜m£¨Šeœ¦’—˜–Œ“‘†ž›‘–„“ˆ’‰…wjŽ†v…pz…`h‡Š“‘ŠZu”ghs|¨œœf{›Š…z™j†Œ„pz€kqf`wplki\ffbcqT[>NNNSG>@UD:1/&4:306678<;>@AAFHBGFIKMSTUY\`hfgWQJ<DG<8UR[`ab`^__`aa_\]__`aabcdabaaedchd^]f›•¥¢ ®¯««©¥¨­¢¦­¥’•«·±³§›¬¨­˜tŸ± ¨«§”—¹  œ¤ž‘‰ˆ›žŒ«™¢•§¡Ž—’…v­‰§œª’™¤Šœ»³§ ™˜‹ˆuw’–“‰“‘”Œ”¡œ¡§™œ±•Œ›´œ³Œ’¹¥Ÿ}§¢y ¬´¥žƒ‹†±ª¯‹—¤›z‹¬…œž¡¦¨§‡•…˜w¥›z‡œ—§ƒ‚{³zŠ†¡˜š•˜–‚‘——„›šcz‡‘…’‹ƒmpŽ‡yp€„}…s…ƒ”‘w–h’t št}™„£ ‰˜•Ž‡†škŽ‡ly|rqhfypjlk\eljgu]^ITLR@E6.[UU7)!09>>743468;:=>>@DI?IEJLGSX[Y\bahfYQH9EL;>aV^bded`aa`bb_]`aabbbcfgcba`edcgcaahœ—¢ž¥¬¬«§¬ §°¦¦©¦™“¯ÉÀ²¢—¨ª·Ÿ‘…Ÿ­œ§¢ Ž¾žšŸš }†Ž™—‡«œ¢– ¡‘“Š…€’§‡£ž¥•™ž‡ º±§ž›’Ž…pv‰•Š”›‹’ ’˜¡¤–ž«‡Ÿ´‰´™­ŠÊ†¨¬ˆ¶…Œ¯®«‚¨Œ¦˜}¨s{wœ§—h•¤y´‹ ¥§’˜Â€«ˆ˜¡rž€š¥~—…•³¡}¡”¡˜—”œ‹™’Œ}…“‡Ž–’Šƒms…~yq†€ƒ{ƒt„€•€Åf©‡£kž…¤…š‘‰Œšq•†jyv|xhivqhhl^dpmgnYgG]QM3E57Nbd7&3<EGD:64658;8>==?BM?NJJLCPZ]\Wb^jm\QE=KM@IcX]cfhgbbbbdc`_babccceiicbbbecafcbbi”–¡ž¯¦§¨¥«Ÿ¤·°©«§š• £¥¬¥˜¦¬¹¤°¢©¦žŠ”¼š“¡’žz„––‘‡«™››š¢…ŽŒwšœŸˆŸ¥œ˜š™ˆ£¹­¤™œŒ~bmŠ“Œ—Œ’ ”  ™¡§~¡§‡­Ÿ•­œ›œ„ Œ¨¬…£©™Œš¢u™”k‚­vM«x‡œ‘š§¦€©«}ƒ¡{z§jž’lg˜†˜·‰ž~n`dYƒ—€|dh‹r™}y–l]}—n_Rpƒ\_kx‚_Xd€|ƒ–p§ªkƒ£nr¥pŸ… jg m\pŽ~gZ`„cXQpwfnvtljp_kqnljYiO]XF9A5HE_l5,IDRMN=84859;6@;;>BP>QRLMBJ\]_W]^cv`MD:MONTa\\ffiibbdbddbab`cdcacjkdbddgdbgeach—•œŸ¸Ÿ©£¦¬‘¡µ»ª®£™˜¡¢¥­®¡ž°¶¤©“¢¡ §œšŽ™´š‹žŒ•‹u”’Š§••™žŸ~“……¬¥‡›‹šª™››’‰¦±§¡•šˆ‰€inˆ‡‹ŽŽ‰‹’‹“£Œ”ŸŸ›¡¤“¢ “ vœ”Ž§Ÿ¥~…§ª‚¥x‰|„š~¢ps”ˆ–|Ÿym†›Œ™š¨™Ž‡{‚¢sv¦fž~w¤_˜z}”t¢n˜·´ºt“ˆƒ€µ¨dÆ¸{p•¶Œr€š£cs¬«`|i³~m|†‚‹˜q£lr£tŸ…¤`š´—s}˜Ÿ³ut\ž²ƒkcpuxripYkmtsg]j^bLE=D6RBZs3=SG`JR=<395::6D;;@JP?UMOQ@E__[ZX``|dHC8MWUWbaZefkkbbeadd`ab`dc_`cknccddhdbgfchh“–”¢·˜ª›“Ÿ¤·´­¬ š¢¤¤¦¯œ³¯­”™¢›¡¥š›•ž«›‹ˆ’y‹…q–ŽŠ ’”ž˜}‘ŠŽ¨¡‡—ŽŠ’¤•›Œ©¨¥ž—‡„~j{†~}‚‹‰”¡ƒ—žŸœŸž‹‰wœ˜¡ŒŸq¡Š†©‡š£”¥¨|­Œ~z ™z£“xt–ˆœ}–Ÿ†›Ž˜š¥…¢d¡|ˆ–›mžh›Žoš™{€‹§~sit«ƒŸƒtªh•š]›…v…žgªk€¸f\¨oœ`•Œ^§vu‡ˆ~gšu†“’—Ž€Ÿoš‘o¨š^©y¼lª\Ž„]´h]or{xlj\qkzzd`gXbBQFO7WDRo5K[[_NZD@151<;7H?:CHU>YRY]>Db^V`Qac}jEB9N\^YdfXfgnmbbe_aa__``eb^bdoq`deekecihgki•›ˆ©³š¦ˆc”›«º±°¬ž¦œœ© Ÿ¯œž²©®Ÿ˜¥œ¡ ™—– £™†‰j‰€r{—ˆ‹––ƒ‘”™z‹„•¤œŠ•†Ÿ“ž‰©£ šŒ’Š€€i†x–ŒzˆŽŽˆ–›“¢žŸ “˜rhŸ‰žŽ‹p’Œ€©†— ¤ž¥{°­£¢¸—w£³£¤€‰”y{«™~¢Žœš–ˆ—q¡|…¯µ}kš‘¡y~™µ£¤«¨„™|›}ž›tªZ]o{–‹xžbL{z…cy—BLŸX¢iq{Žl€ˆƒ™u›x†‰±³€›“§wƒžnt~•pštk¤^•vHedatrofaliw|eebQ_W^UW@ZFQhETW]bX^ID=B8@A:IF8LEXAWR[WDFb\Z`K`m}rEB<U_bZeiVghmobfg^aa\]^`hb_edvl]egfkdeliiki“œ€¯¬˜ƒS^ ¦³¹²²©š£Œœ¬œª•¢­¥£© Ÿ›š–˜¡–ˆ‡‰w†‚oy•…‘›‹|‘“—ˆr‰‘¡›s‘‰š–¡œ†ªœ›•‹‹Š|ƒl„…q¡‹x…ˆ‡“™–|“£Ÿ¢ˆ­†}µ„œ{¥•y©€”šŽˆžš{§hwm~™t¡sr|ž†™p“ƒ®}£ƒ¥˜€£o^¨gu¢co¥aœÓ}{™xstb¢†‘£t¤vk³Œ`‚˜‰sª²¨¼wƒm~¿¦©´]œm{p–mr¢q]¤gs¦`h¦m›Ôš}†›p{{˜lœ}x˜sn©¤gafzr…lhfeowxiacS\gRRbHXJUaXT\fk\eQECKMJKBKE8O@QNXSYOSQ`fejRdwywIFEc^fZhjTihjocjg`c_]]]_hbaie|d^dgdkdjlfhlh—š¯«T[J~©¯±³¯²£›™…™ª ¢¥¦©¡š«‹›™™”™““¡˜Žˆ†{p}„h}ƒ•›w‘Ž‰o†“’l—”|Š“”¥—ƒ«›”’‹†‰yƒvˆ€nŸ†w€’†ˆ™£—z”¢¢™Ÿ‰³¡¢¶‹y¬§¤®¥o¨™…€™z¤¡™†˜rž„¤®¯Š—Œ€¤•‚­ “vµ¶µÉ¡s”‹Ÿ`ž—©mz•‡¡œu¢ˆw ~“˜‹pMf£’pš‡s¥{ytaƒk} kqd_œq}s–hzi³µ³Æ¦r˜}zkœ›«v…›nxy˜jš|v™sQE}³_jwlzˆgkhcuvqoW_TYiQSiJWMYTV^iloVgWMKAJMKHKOBQKPecjmetrsy|nu‰{{TQOl^i\kiRjhilglfce_]]]^ibdik{_]dhcjfomeile ›‡®¥ƒd?“¡²ª®¯µ¢¢€˜ª¢£¦¦¨Ÿž§„›˜—Ž—œ“Žˆƒzjy‡eƒ˜ yu‰Œ‚i„…‘ƒŒ…zŒ—§”„˜ª˜Œ‘‹‚‰z€}‹xp¡†y‚•‡‰– •”¤¦›••ƒfnxœl¢d{p¥w›—pe¦€”‰z¤yŸ–ƒ—sžwŠ•—¹n‘Š¢b}˜ ”ˆmriªku mo¦`›i‹i–‡›–u¢~š`Œ†uoˆbh ež~i›uocfˆmq¢Y^Zb¡l]ˆ‹mz}sqd¥mx¢dg§h™sŒ™p¢pU‰p `f¨U‹^T˜nntlsƒnqikytkpRYWWfZTmJZP]IXiisjYkVQRFV]LXSbUik_xt{}p||rƒ{€sv€„v^RrbgbpgPjhhllnhdg_]^]`jbjivt]\chcjjslfkmcœ£—¥ydslŠ¦­£©°±¦ŸŒ€˜¬žŸ§£¢œ¤£–™”ŽšŒ˜ŽŠ{‡q€ˆh‹‹|™›su‰~{eƒ†”Š‰•š‚|‰ˆ˜¨’£­‘†‹‚Š~€€Žri¦„}‡“‰˜ ‡“©¥œˆ¦x•›~¥ˆ–Š±—‚®–ž¤v“…x©s¥„šn¤¢Œ’„ƒ»n}¥¯ƒ†…†“•›Ÿ|¥zr¨• –gž~o¬d–Š–“w¨mª¢‰v‰ƒx«‘¦ˆk‘°kv³Œ©kŠ…mmŸž‘”_}«‹ªv}~Š¤vŸ|ƒ¤• j›ˆx¬hŸ®Œ¶ux¾¤“Zƒ§Ž«avsur|uqckohmTW[Vab]lM]R^J^mow`[qY\`[guenorbrt`xz~yryƒs„~{{Œƒ€vbxddnsdRkgholrjfia_^\akbllzo\\bibljwmglnb•¤©›€£–©©¨¦­¤™Šƒ˜¬›Ÿ¦Šœ¦ž«ž…›‡œ‘†’Œt‡{ˆ„p…~™“tt†r‘ƒn‹‘‡…”}|ƒ‡™§€§§Ž‰…•v‚‡’nl‹©€ƒ‹”Ž‰œŸ‰Œ“©¢ŸŽt“—ˆ~x“®¢~šp…vŽ‰‚}{r§Œq~}z˜–›„y{~‡”•“Šv˜ ƒ{}‰kŒ…[yyrzqin~’Šr€u””q‡„ƒeŒ`€‹wus”uoynm‡lƒ†^ugwŽe€…Œ§™}t{•j‰ˆpv}‡wnnitz|˜x…\lXyioxsspxxp]l‡ojhW[`W]fkdWcU_R`pyymkwgjkkw}rsusaovbt{‚xuy‚v€€y‹…ƒ~{nldyn^Vngiukxjiie\`ZcielqtnZ[bldllynhloaŽ“¶§¦Š ¡š¦£˜¥œ«¢¡„„˜­’ž¢Š›¨›ª˜ƒ‚œŒ—”‡ŽŠ‰rƒ|}~„{˜tr„q•…{|‘‹††…y~€‰›¥Ž|¨¡‹……•‚†Ž˜vr„©†Ž’‰ŸžˆŒš¦žŸªƒˆ•š~~ˆ–¬§Ž‘¥wn›Žxn}¨…q~•qkp}‚ €“Ž‹hl\‚‹‹›šžŽs•‹ˆqtk‚wtYrn‡‘‚~Œi]je{†„Š€`iy{›{‚‹‚u…gwŠ†j`oq€u^q‰€ˆŽ¥“„e‹ƒnw‹„q†zqhif}„{–[]khnv\|zxvotsƒh]n‹llcZZ_ZYmr\`bZ_^ft|vpudkkk|~s|yudnuhm|~vz|{yz€~o…‰„{}t~ysiT\qilvpugkgd]aXjhkkqrnW[enlgsyohjm`‹Š¨¯ ¢ ™ž—ž˜¨£¢~ƒ™®Ž •ˆ£‘¦•€|™†}’™Š‰‡‡‹s~Œv…‹‚„—Šro€r˜†„~‘ƒ„†Š{…œ¡‘ƒ¨¢ˆxŽ—‰•Š‹œ—„ƒy­‚‘˜š•Šžˆˆ ©ž¡¡£Š‡“›œ¢™•© ¦¤ž‘š…“‹yvŒƒ§~’“”²¦›•Ÿ±’—ƒ¤‹Œ”šŸ‰›‚ˆ‘Šk|Žwxeƒ‡‘‹|‰ž„‡Œ‘‰‰……w|ztš ‰†Š‰„“~}Š€tns„}v…†‰Ž£‚„Œ†‚ŒŒ}‡Œ‹‘„zn…†~z™ksiat‹q~{wwpwu‚]^o‡hna_Z]]SiqVe]]bmhv|}topekji€}ny€rjpqmg{s‚x}…zm‚Œ†|zx{}z„yNdvjsnpzekecb`[tepgrqmV^ltmhyzqgikdŒ‡œ¸ž–¡ —”˜™”˜¤ ž|€š¬ŸŽ†¡Œž–~y•„|ŽšŠ‡„„‡nysˆ~‰”„mk~z—‡„ƒ~€†„†}ˆ…œŸ”ˆ¬ „sŠ†’‘‹œ‘}zª„Ž“˜—œ–‡†›¤ž¡™œ…‚’š™˜™¦Ÿ¤œ›•~Ž‡tz…ƒ¥{}‘†˜«¡ž”Ž©€‹ˆ“™ž‚—~†Žƒpx†ru`„†u™ƒƒ‡…†…•nyvt’¢ŠŒ…š„ƒŒs‰|{qpz†‚zvˆƒ‘¤Ž„‚Ž€ƒŠ‰Šw†‰‹~rn€‚}oilnh^z€h~}wvwu|x]`q~nuad[]_RgnTf\^bkiw{rlmdkjhlt‚lmupzp†yn‡€v‚€}…vq‚ˆ~{|||‚‹`h{juii‚djc`i\duhobumlUcqyepz{sejmm‹ˆžµ™ ¢ž’‘•˜ŠšŸŸŸ{yŸ§‘œ‹‡¦•Œ˜™z{†}‰’ƒƒ‚ƒn|€ys€…~‹’}kh}‚—‰ˆ|}†…‡}ƒ‘“Š©q‹‹Œ’† ¡‰…Œ|§‘‰“˜”–“xŒ¢žŸ•˜~€š˜’‹š¢ ¢˜•™|‹‚w‚Ž† ~Œ|˜¤¢¢“š‘¦ŒŽš‘‰’–›~“’~‡Žut‚qwa~Ž†r‹—}‰Œrƒ†‡ixrxŒ˜‘–~‡‰r†{{owz‰ƒyxŽ‹”£’Š„z††‡„vƒ„‰‰|ht~z|rmlh_~si}vvu~sk_atwqxedY__RkiVfZ`ahjwz‚rgldlhf€kn~horly‡{lŒs~‚tv‚†|{~irƒntia‡hlb_qVtoln`xhmWjtvcuz{rbjoz‰Œž°‘¤¤œŽ—†œ ›ž|w¥¡Ž˜£‹‰š–y|†ˆƒŠ‰ƒr€{tv‚…~‹‘xgc}†—Š‚Š‹x}€Ž„y—ƒ–™˜Ž—¡œp‹‘“…¥›ˆ‰ƒ¦•…“Œ—˜’’w‘Ÿ —“–y~Ž——–šœ£œ—‘“™wƒvƒ•~‚‰Œs—£Ÿ¢”™¡ŒŠ‚–—ƒ’•™~˜|ˆvq~n{d}‹…qˆ”€’‚l‰„‚Š…fvo{…‘˜Œ|’x‹‡{†{zp}wˆ„x‚Ž‡‰–Ÿ”‚Švˆƒƒ‚w|ƒŠ‡xbzzuxhmfbjkxtuw~r}ddasnusnaZa_[meSdYaaikvz‡rckcmfh}‚liuinpi€}‚zn†rƒƒt|ƒŒ~z‚ƒ~|mv‰sumeŠljbbuV„ipn`xglbjvpfy|zq`rl†…›¬–¦§žŒ—‡†Ÿ“—™~xª‹™{˜žŒŒ™y|Œ~}„|ƒxtzzt}€„€‰‹€d_}‹”‡„†t}~‹€~™†—–™Ž¥£™€s‡{“’‰¦ŒŽŠ’ ‘„’•—‘‹Ž—žš‘r‘“ˆœœž¥—–‹“•q‹‹‰k„—™zˆˆ‰o—ž›¤”•‹Œž‹…‘œ’’•†™ˆ{ŠŠzqzlul|Œ~n†“„•xpƒ„~‹€erj{–—ƒ~t‡‚x†|tv~|„{Š‚Š’¡xƒt‰‡}€tu‚‰…qc|v{r~pbpde|copwsyxtubw`plvnp]\`^^k^Q^Ycaint|Šl`jejchw‡ngmikmh}{xoˆs€ƒ…}t†‰{ƒ}z‚„}}ŽryŠxxml‡kh_irc‡gqoewgnlazij}{xpaxm‹€˜˜©Ÿ£¨‰Š’†Š‹•™~x¯™—~Ÿ”‘—”ˆw~|Š}|€wx€€put|p†|Š|a\~‘†€ƒ‚rz€ˆ{“Š““ž”§•‚}}Š‘£‰ŽŠ˜š†’™”•Ž‰‡‹‘›’ŽŒŒm„‘ˆž™¡ –”ˆ•l†—‚e„˜Ž“z‰„Šp–›”£“’‰‹™Œž}’Ž’Œ™Ž{Š…‡tsvlqnv}‹to†’“qu|‚ƒ‰}fqmy|™“|ƒˆt‰€s‡xm~|„{ƒŠ†‹“¦‹z†{}Š„w~qp‡„fizuvq|c_qakt_qk{zzmsqfz^omsmsX[_`bl[QXYecgqr€ˆg]jigbgqodjheiizwvoŽ…t‚ƒ|u‚ˆ†x…|x„…z‰w~‹{{sx‚jk_pht€kromrgole|cn€zvqlwwŠ~¢—¡§¡¦›†‹‹œ‡“v‚¬–“Ž‡¡–”€t|w…xyss{†lsp{nŠv€‡op[Y~‘‡€vu¡‡’‹•ž™¢–˜yŠ€ŒˆœŠ†’˜–…‰•š–‹‹‹‹›‰‚m‰‹‰œ–¡›–“„–†h‚¡e„›‰~‹ƒ‹w“™“Ÿ’‘‰ˆ”Œ~}Ž—{ŒŽš’|Š€‚ovplmoq|†jt„™‹qw€u‚‰ƒzgsnu€™Žz‡„y“yu‡so‡z„Šx‰„€†Œ™¡†{ƒuŠxxnk„ƒ_tutrry[_qaqk_pk~|qnnknwappkrmYYbaboXQT[fgcup…ƒc]kmdbfk’n`gg_hkursp‹€uƒ€yv€‹€x…xˆ†wƒ…|†Œ{wŠjqc|c†|nqmtjholvx`qy|tut€ƒ~¤•™¬ž§–„„—”ƒ vŒ •“†‹›–Ž‹zrxu‚pr…trw‰lpnvmˆvƒ~€mmUQª”†ƒw~wr„{ƒ¢„”ƒ–”™“›y’{ƒŒ’£™“Ž‰•™’„‡—šŒ“ŠˆŽ†œƒ‰{r‹…ŠŽ‡œšŸš”“~’|fƒš…f…Ÿ‡‘„‘‚‰qƒ—œŒ‹Œwz‘zŽŠŒ’–Œ|ˆ|€kvkoklm{az~˜‚w{‚xƒ}zhtls†•Š}‡…{’Žqyƒov‹y‡‹x‡|‰Žœ›ƒ{zvŠ|vpjl‚„{ayqomstV_pcrb`mozripfguuirlbwe]WfaasTQO]ge^yp‰}`]irbbff‘j_he[gp~plqtŠ}v}†€uv~Œy{…xˆƒs†…ŒŒƒ{z”xfqkƒ`ˆ}ookz`jnuu_t}y‡xts…}x ™°œ¥Ž‚‹ƒšˆ€Ÿ€Œš”…ˆ˜Ž„wtwt€qp…tpr„pljwnƒn}}mtsRM‚ßȒ֒{pu…w…¢„•x–’š‘š|”s…ž¡’“‰“œ”†—–ˆŒ‡Œ‡›~€wzŒ~‰Œ‰œ›œš”’xŒte†…k‡¡„‘ˆ—ƒ†cŒ‘™–‹—ŒŠŠqz“ˆ{ŽˆŠ“‘‰y…{m|erokm{z\z‘{~€€‡{{isjsŠŽˆ€…„|”Šl~~m‰}Š†{ƒxŒ’˜˜‰|uwƒxrmgq€…nkupjkvnT_pepZ`msyhlkcgysqqd`xa`Vl`_wQNLbgc]zqŠv]\evabfeŽdagbYissnkrwŒ}tz†‚uv~‹s†{‰r‰ˆ‚Š‡|~˜vesn|eˆ~opl€Ylnyys`vz{wswŠwyž‹š®šŸ‚…wˆ•~}‹žˆ† ’…Œ˜„“‡uxpyqo…pmoseeyq}my}jhkc¤šÁÜ®ð rlv…w†¥‡“o˜’—¢–œ‚’r†‹¢—ˆ•Š–ƒ–…‰€‰ˆ•}†zt‰w‡„›š˜˜Žu‰ul„‡‰|‰¢„‘‰œ„…^‹“˜‹‰Ž‹Š„‰m{•}ˆ…‰‘†v…}~k}dxvkoysX‰{’ˆ†z†Œzfri‰‰‚Š•„k€um†€Ž‚|x}“—trw‡Œusqguz„cunqckwhSarhlV`ouzasd`iqso[dsabWn[^yNMMegb^wtŠn\]ey_`ee…`cc_YjsknksxŒ~tw„xw{‰qƒ„}~‰{t‹‰ˆ–†‹~—shuqylŒ{ntqWqzvyrdwy‡Œiw€Šrœ†˜§œ£’„}qŒ”xyŒž…†¡|–€šˆ„{sxptjp‚ljm}u_ayw{qu{g`d|ëÚµÉÃ܇rltƒw‹‹kš‘‘ž–”‚‰q„ˆŸ„‹•ŠŒ˜”|“ˆƒˆ{‹…Ž€uxƒ„rˆ“›–”—…‹u†}nƒ€‡†—¡‚“Œžƒ‰aƒ”‡Š†Š‡‡i|“}ƒƒ‰Ž‚q†~qwhvsjuxlZ}’„†~‚…‚…‹ƒwark‡Ž‰€~~|mkw„„z€{}ŽŽ”‡mpyŒ…tkqkry‚aujp^lwaResifS`qwuapa]h„rtkXhiciYnW\vMKMfg^bst†k\\ey_^dg{ad_]YkoenjtxŠ~st~{vzˆs…‚}ˆwvŠ†˜Œ‚{“ulwvyx“tnx{}Xz†qogxw’‚dv††p‰–…™¡š¢Š‡to’Œqw~‹š‰Š} „š€xrtnodrigmxx\`y{{qq€iagaÕ¶‘¦wnqx}r”’Ž‰l›Š“Œ‡{i‡‹˜†’‘†‡˜Ž|‰{ŽŒ}ˆ„zszƒzp‡€•™Ž“’€‡t‚„t~ˆ‘›ž†•Ÿ~ˆb“‡…‰…‹‚g|€~‚Œ~mƒ|ƒulmwutwvlcŽ‚†}†€…‰€p_qo„{Š€{~‡zpƒeyˆ…Šz„|}‘Œ‘‚mny‹~umnjl|dilkZnwYSjsibQcsxmcf^Zk…ouc\h_em`oU\pOIOgf\hor€mZ\cs`[clwee]]Zlmcmjtw‡qp|}tx†x…‚}€ˆuy‰’•|ˆ†vˆ€oxy{ƒ“on{w^ƒt‚mizt”sgsˆ|q‘ƒšŸ› †ˆvv”mw”˜ˆ‘„‹Žš}Œšw}vqoljau}gbjuzZ`x|zlp~ecggW_rt—¾Å…xr–‹‘€t™‡ž”‰sjˆ•€{”‹„›Œ|Š†}|ˆŒ~’‡t‡…vv}qu†ž”†”Ž‚‚q~†s‚zˆ–›–…’€ˆf}“‚†„Š‰r}g}‹{y‡‹}i€}„vfpyxsxtlk†‹‚Œ€zƒ‚„„€k^pvz}‹‡„{€Ž~r€hw†‰„w‚z~”ŠŽ‹|mkzˆ|vtohh~xe]rcYqtTTosibNhuyga^]XppuZec^knaqPZlSDThbZlon|pZ[^mcZcowdg\]`kjclisw‚ƒqo~{tuƒzƒ‚|‚†v~‰–xƒŠt‡ryy~oo{qj‚yz~nm|v•kjx„tk“Œ…ž˜ ™…ˆo}Œvjy™€ƒ‹ƒ–˜Šy–oysqljd`t{i_fr{[as}zfpzaedŽ±²wKcZ¥ÛҘs|“’z€—†š’‡ol…’‘yy“†€„™Š|‡€yxˆŠƒ”n‰†qs}{jy†ƒ¥„’Œ‚~n}tw„™—“‰’”…ˆpz’„~„ƒ‰ƒnxh€…xrƒŠ‡|e|~„vcqs€izqovš‡„Œ}xy…{ƒk\o|r†ƒˆ|„‡zˆq€mo‚…‚‚qƒw–ŠŒ‚vll}„~vzehjraZx\ZrnOXrtg`Knwub^\[YvtpXg^gkr`oOXiS?Zg_[qkgzr\[YleYdqy_h]^elhfkiqwˆol~up‚z€ƒ€v…ˆ—Šq‚q{…|zy„”Œukzlp~u~or|{“poxg‘Š‚¡˜’ƒ†g‡„pgz—Š€…‚šŠ‚|ixrllf_aozn_cpy]dlƒz`pv_deÕ뾋3:>Œ€sz‡‹‘x…™Ž€”nm…Œ‹u|…‚•‰|ƒxnv†…‚•vm‡„kt{ueyƒ„§ŒƒŽ‹‚|m~rt‚x„šŠ‘’Œ‡{’ˆy€…Žƒl€ri€xm||Šƒway„‚rdqinvruƒ‚‡€tv~€sp[k|swˆ‰z†|ˆxypj†‚Ž‚ˆp€w}“ˆ‰}smju€€uu\iiyqYW~T[rfM[srf\Jryq^\[Z]v€vjZb[hfodjNXgR>_f\^vf`uq[YUodZeqy[h^`fmhjkhpx~Žmj„yn€{}‚{v‚‚Œ“…p€‹nx}€{{ˆ“‰€i{~jt|r†{sw~Œzx„~|k‹Œƒ›–Œ‚€m~liŽ|~ƒ”‚}Šˆkuqgic[cgso`bluahp‰zass^bd› n]6[°¶uk‹”ˆwˆ™ˆuŒŠwpm…‚†ty‰x‰}“ˆzsgu‡}|–no…}hvynez‰…¤‡€†Œ‰}m}t}{Š—†€“˜‰‹…Š|Šq|~†|i~mk€{yjzw‚‡r_w‚~rdrhvƒnu|†–“‚~ƒpxz|umWm}us‰€…v†u‰zwrl‡Žƒq}{|†‡ymmhl‚tn\hfurR\|O]r]O\spdVKtykXZYZarvb^]agdijfOZiNAbe\awa\unXXSubZeosXj_bhkgmlipw|“li„Š}}p~|‚{w€€ŠŒ„q{‡orwƒ{‰„j~{nxyv‹w}x€‚‡€ƒ~~zm„Œˆ˜£…„{v‹ykm…Š’y~|‚’€€~‹ƒprpcf^Xg_pp`ahqfjo‰taso[acjv{¿¨¥Ê¹r‡†t•~z‰•„u’Ž‡rspƒz‚su†tˆw”‰yyqcv…x’hqƒvfvucj|„ˆž‚~Ž|q}r‚w}Ž‚v•”ˆ‚ˆ{‰Šlyz€uh{ilysizv€ƒ}g`w‡}kjth|jv’–|r}w|ubUu{qr‡{‚p†‰wwon€‹}|w|zsŒ„€tgpgkˆqo]hctoLfwM_oVUZtnbQPuycSXX]brƒt]b\ieedleQ\qIDeb\dr_]xhUWVx^[fniWl^ajgeonipwz“niˆŒy~s{~y‚‚|v}ƒˆ†ƒpwƒsnw‚‚~‰‹”q€|xzz‹uƒx‚„z€un}‰‹›žˆ~†{w‡|hu‡‘z€|Š†„w€gpn`e\XeZnsaaaqmlh‰n`siX^cm€w©Ú©È‡ˆ³s‹zqw}‰‘‚{”‹€utu}vopn…t”†xul`y€x‡dq‚ngum[m}“€€x’‘|wzl…s}Šƒr•Š‘ˆ††{†nuwmhwem|vmkww|`bx†zhuvc~|hu‡Ž—}vwr€{}n€ZVq|os…}wkˆ†sxjs~‚‚|y{wzq‰zrfrdl‹ƒlsZj`vfIooM]cXWVynbPSuwZQVX^as…p]acned^ocU^sGCg`^gi]Z|cRV]v[[glbWk`anfflphpvxtkŽvwx}w„|u}ƒˆˆƒoququ~…‰‹{wx„|}…‡xˆ|}}„€{~rux‹ŽŸŒ‰{Šwuƒz^~‡šy‡„t†‡…w‰{bnm\b[[aVjtda\hopg‡qaqfW\ck|Ê·º¢knoŒns†s~†Œ€{’…zytyttzjlvc„v’‚vpg^|€xŠ‡dq€jjqcXm{†œˆ‚r—“v}zm†oˆŠ†p–Žˆ†Œ„{yrrp~ghrcnxqjlrx}|y]dy€xiuyg‚whuˆŒ–~sˆkp€yn}]Wo|lr}ˆz€mn‰€pvfv~~€tzoyr…zwpdq`mŒkrWk_y]IplNXV_TU|kbOTvsRRTW^cv†j^akkfcZobYdqHAi]ag_\V|^OVfqZ[jh]Xha_rfjhqgqsv‡yn”Šu{x~yƒˆ€ut†…Žƒpo{xwuz†…†Œ†z|u‹}†„„‡~~}†|xvyv‘”Ÿ~}‹nu€zd„ˆ˜†s’‹p……‚zƒucnjY`Z]^ThseaYdrrgrakeWZ_ix¾®{ ·ncuˆiv}s{…ˆ{~€wxswnzvejo`‡uŽsjb^}vxŠ‚ep}gkkZVox‹£…p™’pvs€l~€†r”ˆˆ…‰…}yuspizajmamvjgkkywzwZf}}xer~n…tfv†‡—€qŒhl{ƒumub[mzjry‰z€et†}mpgt}v}~pzjyywvodk`lŠ}lmUj`xVLlmPSPhNY}hbOUvlMQTU_hw„g^aqig`Wj]]ljJEk[ceWYVzZNWokY]le\Zec^ufleqgsptxp™…vx|†‡}vt‚ˆ€•ƒnsy{{ss…†ˆˆ„y}v}…‰Ž„ƒz~‹ƒ{w|vv™˜zŠƒ‡jv~}m……•r‚q†‚~‚€pflgX]Z\[Teqe_XcsuivpeecW[[hpor€sŠefz€kvwtu…†x‚…zwtvnjzpahkg†t„nf^^{myˆ|glwfjdUWspŽ¦|„{v–s{qzxlyyƒu—|ˆ†„‡„}uqsmhu]mi`ludggizo{rYgvuhp€x‚vbw…‹}–‚oŒln|qfse`jxfpuˆy|atƒvikpsyoyxr{e}}}vumbd`l†|ljUibrTLklPMOpH^|faNVueKOSXblxf^gske`WdXcr^LLlXdbUTVtWMYweZ_la\[de_vgmbpjtoq~ut™x€x€~†„z}v‚ƒ~˜…nrt|{tq……‚€z‹vt‘€|•Ž…„|~Œ†z~€vz£¦Šy‰†…lu}|v„ƒ{o†sz…}‚ƒuojieV][[ZScoe[Yat{jhmh`aX^Zi€ilo€hmbi{zkuuup‡‚z~wvnzhjyj_enhw„geXavh}†xnioff]UXoh¨vz|xtn}mqtx~w”t†ƒ€†‰vjtwhio\me^ns_gbjxh{m[mƒrtjo~zxbw……y‘†t‰spzrcqh[mudoq†zwarpgiwsqkwvsub‚y|utocbal||kkUibgTLniPHSkFbyfbMTr^JNUZfmx{f_nrjd]VaVooXKTiXg^XNVlTK]z`\_l]][bf`zhlaoovnowuz—}w€y€€‡†zyzƒ}“„qst~zvt…ˆ~}‘ls•|ƒŸ…‡}†‚€Š{v„«Ÿzˆˆ…lq‚{v€‚uoˆn}€tŠ€jpnedX_ZZZUbkg\Z_u‚i^ml\aW[\kert}jk^mxwivxso‡|~~zvrlzhiwg]dshzw’€cbTcne„uvfhiaWVYhd§n~w€‹ypn{ewmyŠzvŽq„~€‡ndwtehi]lb^po[h_luezh]t€nrkq{vvcu†Œ|‰ˆ€ysv~taplXpqano‚zscq€lalynihyxspd„sxxsoc`cls}ikTh^_ULudQHVbHcwfbLTqYKMXYilw{eenrgcZX^YxgUJ]dXiYYIWfPIcy[^_m[^]bd^ij`otymonvƒ—yr€}‰Œ†~vv†x†Œ}suu‚yzz‚ŒŽ}…‰jt—{‹~~†z€{~|†‰sq­Œ{|‡~fq‰{t~}wsp†l|~mzcppbe^eVZYWdfl`]]t…hXpm[^XZ\l{cqwvnc\ouuivwro†yzwnotehte[gufvv‘y_]Reeis|abi\TX^cd¤hxt‚…wlmxfvl{ƒyt‡ry}y€ifwmaga_j`^ukYf]oobze[w|knopxytues„“€‰„‰{wps}raxcYnn`nozreq€d^muhcfwzrlmsq{qpa]dln|eiSgYZUNz`RKZYHcudaJUnUKMZWjms{dlmtcaYZ\bx]TLd^YjTWHYaNHkwY_an\\_bc\…ihbnxzmojvym‚~€’ˆ„wu‰t‹†trvvx}}~Œ“~px–ƒ}™“y€wy~sˆ„sp™¡{{‰•yeu‰zsywluply|p’s^poahblT[ZWidnf\\r‰eSrn[ZYW`lvcjukk_[ournuuuk‡}|wonldipc[krdtvŽs\VSc_p~}p€\ac^SZa\d’žerq…ƒskixknnyyzq€vs{z{dfvh^b[ah\_whWb_phawa[|vjjrnxttuiq‚–„ˆ€†vtkp|lfwW[ilaop~wseo}[`opb^ip}kjr}povin_ZdklzafSfUXSQx]SPYRHdtbaGVlQIPZVlll|emora\ZXZmqXSQgWWjTUFZ]OIsvY`cncYaaa^Œjcemzyloivy†{kƒ}€„š|‚„y}ˆn†qnvz}t‚‚}‹ƒƒ—tx‚”…Ÿ‰u€sp‡ƒvo¢—s{†Œ‡{fw‹on|pgyr{lsvsk^tobgfkS^\Vhbmm[\qŒdNom]VXUfishcuee^[pwoqvvzlˆ}}ˆwscdkoa\nmcsx‡kZTVabv{{o„\c^cSZ`Zc–”cnp‚…‰rifxmdruqzkytuo{v_gsd[^WbdYbueU`amdaq]\~ohisqtquwlm…•ƒŠ}†rsgo|oqoRZeidoq~trbluUbqjZ^nd{dkt{pqqhl^Xcijx^eSdUWQVoXRWTPHes`bFXkOIXTWnie|ilykbW]V\ueTSXiRZgUTI[ZPNyw[_emiZba_^nbgkyvnoivv~lƒ€}†˜{‡Šk“ˆrgs€{u€ƒ~‰ŽŒ“s}Š‘…‡Ÿ†{†Œs€†s}‚un¤Œs‚Œwxnz`e}qgztymmqwƒgd|mcggiT`_Ug`mp\^nŽhMil`UVSogskfxef^Zrvns|ytn‰{wœzykaelm^`ojeqy~gZUW_kvzyn‚^a]hVY`Xdœˆbkp†|vkiuk[upjyiurno|sYkn`Y^VbdXeqcT_biablZ`~kfltuomxwlh†€Š|ˆnqfp{lqlaX_gfmqrr^ilSepdUbmaxaotztinji^W`fhu\dUaVTOYgSO\OPIep]cGZjNJ`LYme`xio€e`U_U^v\USahO^cUTK]ZQZvv]_fmhXca[^Žqchjxqsmgvty‚s‚ƒzˆ|ŠˆŽznŠtlstˆ…‡’„•z}Œˆ‘›„€{Œ„rstwqn““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz|~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~~~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’’’’’’’’’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z|}}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ“““““““““’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z||}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ>.1110/o‡„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ…wegfffh\CDDDDCGdhgggggkonmnnqJ+....+H…ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽ.h…‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚‚ƒr]____aR4555549\`_____egggggj<;ƒ€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}zzz|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‘‰ˆˆˆˆˆ‡Œ‡‡‡‡‡‡‰’“’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†…………†ˆ‰ˆ‰‰‰‰ŠŠŠŠŠŠ‰…ƒƒƒƒƒƒ…ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z||{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘“““““Ž‘’‘‰‡ŽŠ’“‘‹ŽŽ…Š‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…‹…‰‰‰Žˆ‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wwx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰ˆ…‡‰‰ŒŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹}{wvw{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰ŒŠŽˆ…ˆŒ‰‡ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}}}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹Œ‹„ŠŒˆŽ‡ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ}wxz{zz|||{}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒŠŽ‹ŒŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzzz{}|{{}~~~~~~~€€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†€{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{z{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰‡‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†……………„„„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰Ž‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†Š‹‡‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{~~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““”””””””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••”””“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””“’“““’’’’“““““”••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘‘’“’“““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’‘’‘‘’’“ˆ…“‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘’‚‚’‘‘Žu†‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ˆp„|tˆŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒsoŠŠrx‡ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}~~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒwm{‚sx†ŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||~~~~}~~~€€€€€€€€€€€€€ƒ„………ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡sno„{uv€…ƒ„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\YXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxz}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzoq{xy{|{xw{xuwttvuuvwtb^d_akqfhklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFEEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkiffggghhb]jl]efgeccbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFFHIJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__ac_\_]`]^ZZjwlbnrjbYY_[XWSNMKKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{xvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSTPMJMNPROM[krkamtrfQQSPPNNOMJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTtsuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMN]cokXisupSMOPPPONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKKFBFHUbglopomlZLLNMNOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHECFGHMZghgrnnhfd`^^XLJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:;>IZ]Z\elnjommlkihkdSGEEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@:;><;;;=K[imnojomkjlmfQGEDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnppsttsqrvxy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;:;;99:88;<979;:=HcosmnlklhUC>CFDCCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqtstrqtxxy}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<:79::979::78:99=J`ssphT?:;=@A@=;;><=<@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyz{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>><==?@===?C;==><:Bl}j@:;>=>?@@@??A?@@A@@@=??=<:;==<?@@BBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquutusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCDA?=>@A?@;[n@>DE?@AD_d;==;:=>AA??@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJKHVppqssttuyz{||~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???BFD><<=@=8::mwH8;:=>A;Hd=<=<8:;@?=<=<<@==<<>;=<=>A@BA@@@BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII`pprrrtuvy{}}|~~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC?>AAABA@YR=<=ILFEuvN788:;>?WjA;<<::;>>>==79?==>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC@CrzJ;\ƒz|wW<=?==>EhtL:=>?==>NSURLC@@?>A=;?B@BCB@BCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGEE?AGGFCFDGHJGC>Hloppqtuvy|||||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCEAGrzkbƒ„ƒ‚ƒ€}^>@C@@=Js{Y:=AEBAGfhlha_OCAA?>=@A>>>?<>@DGE@>@A?@CFECBCC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{{{}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@Ent}‚‚ƒ~}„vMACE@?>Y{€]?CEIIIWjjhihfgODGEEEDECA?@>>BFJJGEEGFFJNNKJIGGHKLIGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z|{}}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@EEhs}|„~y…rCDEDCWu†‡‡~XGHJMMSmwpimoqeKJIHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHHHGFEFFFDFHGEEHHFHGHFQnnpqruvy{{{z}}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJG`{€w„…ƒ„‰lAAVt‡‰‡‡‡ˆƒWHLNMTrxxrnoolMGIGFHFHECDDFEDDHHCCCFIKKLLLLLLIJKJJHIIHJHHGHIHGGHFFFHJIIIIH]ooqrtwwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLLN[|‚‚ƒƒ…††ˆ„Vl…‡†††‡ˆˆ‡|PLMJ[wz‚qnmmlKCCBCFFEB@>>@AB@BD?>?DFHDFGIKIJHHHGIIJJIHFJJJJIJIJJJFILLJJKKfoprrtvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKLKJTƒ„„‚‚…††„‚……„„†††‡‡†ŠuJJG[ghjfiszqC=;:<AA@><998<<<;>;8;?AB@ACCB@AADDBCFHIHHHLMLGIJMMNMJJKKJLMSlpqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHHJIIe…„„„‚ƒ‚ƒƒ„……†‡ˆˆˆˆ‰ŒgEVdjlaelx€e796479;<:8567789787588;;;=@;999=<>;<=ACEHJMLLGIGORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@CGIIh†„„~ƒƒƒ‚ƒ„†‰ŠŒŒ‹‹‰Š‹ŠeboplhkqmxQ3873568:876565676767:67889:7578979866:<@GFIGIFEFOSRSSROPPRTepqsttvy{{{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@6788=:=ECBe…ƒ€‚ƒƒƒƒƒ†‰‹Š‰‰ŠŠŠŠ‹Š‹‹ˆquvppupjnK488557699776765:9:::;798987669:98878589;A=>>BA?AKLOQPQOOORWkqrttuvy{{{}}~~~}}}}~€~~€€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897;B:=q„€ƒ„„„„…†‰ŠŠˆ‡‡ˆˆŠŠŒ‹Š‹ŽˆvxwvxrmmJ8;<9:;9:;::9;:9===>;;<<:>;9;;<;<;9:<8::::999<?<<ABDIJMKIKLWorsusvx{{{|{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<:89989:::;?>H~„‚‚„………†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹ŠŒ‚ux{xrqjHAAB>@CA@>=>>@???@?@==?B>@A?A?=@@@>?A<><;:;:9;?=;<==AACABCAXpqtttvz{{|}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::<<::;==?@BR‚‚‚„…„…„†‰‰ˆˆ†††‡ˆ‰Š‹‹‹‹ŒŒŒx{zzkWLHHHEFHGECA@BECCABCB?@DHECECEDAFDFDEFD@B>=@>=?@>?>?>?>>:;=<`qrttuwzzz}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD:7:>:<;>???=A@CDFW„‚ƒ„…†††ˆ‰‰ˆ‡†††‡‰‰Š‹ŒŒŒŒŒŒŒ~yzwYNSMKKIJJJIEDDGHFDDEFDBHIKGHGFHGEKIKIJKJCECCDBAACBDCCDDCA=;=@hpsttwwyx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLKABBA98<>;<;>@?A>BBGGIY„‚ƒ……†‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒŽ‰zzu]QTOLNKJKHKGDGIIIEFIFFELLMIJGGHIJNMOLLNKGFGGEECFEFFDEHHFCA?@Llptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?EGG=<@@87<;;=:>@>?@CFIIP_ƒ…„…††‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒ„yzt^QPNNLJIFJIEKIGKJIJGGGKLNLLHHIJMQNONLOKIGIJHIDIHHFFGGIGCBACTnpuwwyzxyz{||}~~~~}~}~~~~~€€€€€€€€€€€€€€TDAABGHB?8?@9:<8=>;=A>?ADHJLUqƒ„…„„…†‡ˆˆˆˆˆ‡†ˆˆˆˆ‰‰ŒŒ‹ŒŒŒŒŒŒvvxmTSPMLIGDHKHMLGKOLKJJLMLOPNHIKLOQQPQOOJHJJLJKFGHGFFIFEEBABB\orwxyzyyyzz{{~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<9@>>@BGGAGKLPVy…ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹ŠŒŒŒŒŒŒŽdgmYXUQOMLEFGMPOPWUQPOQSRMSTOMSLPSUVRSQPLJMMMKNHGJFEHJEDEEBECcpuyyzzz{z{zz|~}}~}}}}|}~~€€€€€€€€TFFGGGGHF>@B=?==B@BBGVNFNPPTX{†ƒ……„…‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŒŒoacodHUSSRK;;STR`u]UVTVYYRXXRZfPUWZ]RTWQOMRQPPQLLKHHJHEFIIIHIirvyxyyz{{|z{|}|}~}}}}}}~€€€€€€€€~~SHJIHGGFE??AAEACGEDELXRMTUVXZ|†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ~aŠ‹‹ˆsbjY>[[ZUR?@WVY\d`VYbr]]W]ZVEQYZ[Y_TYgRVVXUTVTOOMKLJIILMKOMSotvxyxxzzz{zz|}|~~}~}}}~}~€€€€€€€€€€~~~VJJIHGEDDBA?HMIMPKIKPTSSXZZ\\x…„…………†‡‡‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~Œ‰‹Œ}ts[^^]TUSWWV[[uƒYU}a\X]_WIV]][[_YHYXY[]XXYWRQMPQMMOSQQURassvwwvxxxz{z|}}}~}~}}}~~€€€€€€€€€€€xy}YNKIIHFBD@A:PQQWXPQOQSTTXXYZ[n‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—‰Šn†‰ˆ‡„Š€j]]^[VWUXTSXVc–€RerXZW_hP`f[[X\gaGOZhg][\]]WROSPPRVVVVYZnrtwvvuxxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPNMKJEC?@;PPZZ[SSQPRRRUSVTW_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†~}`UY[VTWTRRMPMLfz[]TYUV]ZLTZUST^ZXWWWzjX[\\^TQQPINOWVX[Zdprvvttvxyy{{||}~~}}}~}}~€€€~~zxwvsu{€€tk~kry^[VUSROKFCDAM^ƒlVRSNOQOQURSRRUcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡ˆzpsZNOQQMOLJKEFIFC?TdURQQNKQTQMOYRMNQSVUMQSRPOMLHCIHRTUZ\lquuusswzz{{|}{}}}~}}}~}~€}}~~€~{vsw}~~du}iqt_d]^[YVQLILIal’tPQSNQRQR[RSRQRUTas{|€‚}{{€ƒ‚…†‡‚†††„†…†va`PHBEEDDDAEQCEAC>CIGV@HNLG]iPHFNFDEFIGHBDHGIKGDBAD@OQMSdrtvustuz|{{{{||}|{~}}}~~€€€||}€€€}vt{mh|gnqfiedb\XSQPURsWe[OONLQSPUYSUQQTROV_klrv{{xyurnstsyx}ƒ€ƒƒ‚€‚€ƒ‚lOIBC=<>@A@@?kQK`EFHIEB?GLNGMRUIBE?><=<==?=?ACC@?==B>JNGUnttustvxz|{|||}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QQZ\Y^JJPPNKLQRQTUUWQQWUPX[a]agmmlokg`nrjmlqu{z}{xz||xwxeEBBC>;CCBBDB\]O{NOONKLMOOQLKMWMHG@B<:77599=;;;8:8:?<BH?\stuvuvwy|||}||}}~}|}}}}~}xuvz{zwyxuw{|yxuywcqhipmnmmhf^OP_]ZIHPRQOMPQNQRTVXSSYTOYZ\WY]^^_e_]^qvk^`gkwooljonnlebYHGHHCBGIFFFDMROaWSWQPSSRU[OOQVPMICF?:96587979:365795<C>essvwwyy{}}||{|}~~}{}~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`VW^ZXMKTTSPQUOLRSTWXTTYRMXYZVXXVXY]WWXhsk]Vatkaa_^da_^YUQNOOMIHJLJIFCQPSZWTTNQSYS\eUOSTRNKIHC?A999897885757859:Gnqtwxz{{|~}}|{}|~~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPXVVSTVOOUVXXYSUTLKTVUUUWPSTWTUR]n_RNZ`[WY;DVXT[fJLPSRONMNNNLJFQPUYSTOJOOUST\VRUSROMLIHHF??<:787659967675Wppswyz{|}~}~||}|~}}y}}|~~~}||}}~}|rvqxxrvuqqnppopuvtnjddjppqrpnfedc\]RTZWXUTWTRXXYYYSUOJGOPOOMRJOPOPNNOTLMIPOSTU2=XMI@Q=caQSQPNPQPNNMQNTRPSMIMKORPRRSTQROLMKLLHCBA=::876;B5566:doqtwx{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqptuvcjgeWhtrrqnhihpVVTUXUWURWVUZYXWUQSFEAFGGHFJDHJIGEHLHJHFLMPMG/E_R>3?>joaSRQ@GTQPQPQNQOQPLJLLOPNNPQQNPOJLMMKGEECA;=<<:=G6677Dmptvy{{}|}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknaePSTRSTOWVVYYVQQQO@=;=?ABAC@BEDA@GHGHEFHJMLEGCORC8ENS]gTQSAGUPOQQPMMOMKLKLNOOQLOOMHLKIKKLKGFFED<AA>;@E;<89Sprtx{{{}{|{y|z{~~|{uturvvz{xzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLONLQSLTUTWWULLKI<987;>@><=A@B=>EHFCEFIGJJ@FAA@FHEJOHQRb\RPROSOOPLMOMLMMNON[WKMQOGIHCIJLLKFFFE?BC><BG?B?Adpsvzz{{|{zzw{wy~~|{qstprswsxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCD=9779?B>;?B@@>@DJECGGIGIEBB?>=CBAGIDMObeQMONWKLNKLNMMLLONSdNJLRIIIEAHJLMNJGIGBAB@?EFEHDKnovyyy{{z|zwsxtx||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGMMJMPMPOHJD?A=989:?B?<ABAADEGJFDHHGGHCD?B??@A>CECKNRTLJIMTFIIJLJKLIJMMOPRPJGCLGCBJILMONIJIGCCCDHJMLIYrmwyxz{zy|vrpurtxyvxjqnjllnttmtu{stxrompovsnporpopstyjN`gsjt|ygosqiqhdqHKDGHIGJKIJKDFB=>=:9:;@B?=ABCCGFIKJEIIFGGCC;A@B>@@CECIMPHHKGHKDHJLMHJLHIJLKM]RHHDNFACJJMLPMKLJKFGGJNNQNLbmivvwzy{z}rmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoiktgdoFKCFFGEFFGEGBC@><=9::;@C@>ACEEIEIJLFIIGFFCB;ABC>@CDCDGLNHKNHDHEILNMGILGFGIILNKIGENHBFMKMLOMMNMKIHIORRSNRfffrosxv{z|lhjnekqlspfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGIDFFECCBE@DB>?>:;;=:<>CA>ACDFJFIHLHGGGFEC@=DDB>ACCCEGIIGMQJFFGKNOKFHIFEDEIJHKIFHOKCILKOMONOONJJILRUUSOWd``mgproryzgehhdilgqlflmgiklslpvutpnvrosrsutqssutsuvvvyvutwljuumrvqlnlerLHEEHCBABD=BA>A=::=?:>=@B>@ADGJFIFIHFFGDCBAAFFCBBCDEEGGHFLQLIOJJMLIGHEGEDCIIHKJGKRMBNNLONOOMNOKKKOUWVUSX_^\ianjnhrsbdfedhhfnjfmmhkkmriqvtsqmvnoqrswsrstuvvvvwvwwvtwujsunutsqrkkrMGGFHBBADE<A@@C<8:<>9?<?B@@@DFHEHFFHGFFDCECDIECFEBEGEFGGEIMKIQMJKHHIEFHHECIJIKLKPSNDQROPQNOMNPMLMSWVXXUX]Z]d`icjigk_defcgggkggkmkmlprhttursnvoqprtxqssuvu‚‘yvvtxuuwxmouorsuqqinyMHGHHBBBFE<?BBD<7;=>:>:@B>??BEFDGDEHEDFCDFEFJEEIGCGHFHGECFKJHNKLKHJLFIIKHEKKLMNORTOHSTRPROQMNQNMPWZVZYVZ]YXa`a`^hec`dehgjhhifhnllnmqpiuuxrrpupppruvpusuwu{~}xvtwvvvxplupmstnprrxNHHHIDBCHE<@EBE=89>>=<<AB<?>AAFCFCDIDDEEFGGGIFGKHDHHGIGFDHKIGKIMKJKLHLKLKJNKONORUVOKUVSPSQRLOQPOTYZY\ZY[]^]`c^\ackb`dghr…hgifjmnponsrjtuxrsstrnpqvrquruus~yŽ}uuvvvvxrhuqkrtlqvptLIKIKFBEGE<@GCD@:<>@?>?BB<@>BAFCEEEIFFEGFGHFHHIKJFJHHKHFFLIHGJGLLMLLIMKMMMPLPPQUVWOKVUTRSQRLORRQVZZ]^[\^^^``ad]c`ef`ehjdssfjgfkorqossnswwquvtsmoruorspurvrtvuuuwvuwtgtrkqrkrvnvJKLJLGCEDE<@FDDC;??A@@@CA?B?ACHCFFGIFJFGDIHGIHJLHHJJILJFJKHIKJGKKMMJJMLNNNPKOPRUXVMMTUTRQQPMNTSRW[]^_]]`_`aa`acebdhbdijgv‹ljiglosqpqppryvruutsmmssmqrotutrpswtuuwvuuteqskpqjrunwKLLLMGDCAE<?EEEC=AACBBCDACEAAEGCHHIHGJGCGIGHJFIMHIJMKNLGKIHKKNQKRQMSMKNNOPPOTOWXX[NRPW\ZRWPNTUTTXZ_bb_da^`b^`eaacingchhhnxvlhimosrpqrrrvtsusssnksqmprotvrqquvuswywutucmtkopjqtowLNLLLGEA@D>>DEFC@DBEDDFBCEGCCIFCIJJIIKGDKJGIJIILHJJNLOKILHKLKZfJd\KlSHON_nUks[qpbwcSPavuhucav`Xnqbdvinzf[lt`ljT_wvijghfglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqrqyLNJJJFB?@B?=DEFDCDCEEDFBFFGDEKFFJMLKLLGGMIGJKHKKIKKNLMLLLILML[sbdp^lmUMNfs]ffqlntgpi_aYnnbppbkjjfoqtetno\ougpMJqyvka`keemxlkvlmpsrprqpqrqrrrtrmmsnnopsutqsstuuutwxvutbmukpplrrqzKLIHGED?AB@>CFGCFCFEFEDCHHHDEKHGLNNLMMFJNHJKJILKJJKLMNNMMJMMN[roonpplkMPQlWMibtrpamnu\YlP\nmZqmkomxxtsip]_rkqjUuyxoc^kfbgpojjnoprspqpqqrrqqrrtlmrmnnorutqtrtuutuuzvutenukpolsrryIKGGEEEBBB>@@FHCGDIFEEBFIHHEHLKGMMOLMNGLMILKIJMIKJJJNPONLLNNL\hdu]lqWlNPQmTYk^klvaldsSecNmYl\tpkilxjwuhp]^rkhWbcw|oc`ggaditxknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtvHLFIDEECAB=BACFDHGLHECCHKIHFJLLFNLLSRLGLLHNJHHNHJJIHNOMNLJNMJZsppoqqmlOQRnYrkgooqqomt]nXat_nopoqronusttj[^tcwxrjnzhaacfbbimtupsuvsqppqoqt{~}wlkqnlmnprsqttsuutxxyxtukoumtonssvsHKHIBEDEAA>DDBGDHIMIFCFJLJGFKNLFOJKWQKGKJJNJHJLIKJHHKMMMMIKKKSkc[i^_icrrZ_Yjn_eeUk_c[aaQ`lh]j\niid[oedp]Z\k[mqcpsldgccg``jmqpntyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunvqqutwrGGFIDEDFA@BFEDGBHJLHFDGKLIEFJOLIPILZPJEHHKMIHJJKKIHIFKKKLGHKKLMMLJKMNT[\TPTLPONOOVQONQNOQJJOPQdqiTYV\[\VY[]X]\\cfaaebcf__fknimtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyxxuvqruovrtsuusGCDGEEAEC@DHDFGCIKLHFCGKLIEGIPKLOKLWLIEEHIJHIKIMJHFGGIGHIEFLIJLOMJP\W^P\[`^MXYS\\b^MXZMXaRKYaZR_d\aX[ddVVX\YZX\VY\]b^daa_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtrxrxsqrurtOBCDLMBDDBEIEGGFKJKHEEIJKFEHHPKMMJMRIGE@HFKIKLJLJHFDIFDFGEFJHCJMLLU_Y`X`a[`TXYT^^Z_RY\P^\YN^\^SZ^c^Z]`c`Y_c[`^[TXWY^]cbcacehekrpoppnow††……†‚{€……††††…uqprrsvyyzyyxxxwryvxrqxvtvaRJJMIECBCGHFHGIKJJIDFKKKEFIJNKNKHLNGGE>GGKIKLJKKIGDIDCDEAFJEAKLJO[cY_^a_RTRW_`\]Y^QY\MV_WKQY[PZ_aa]^ca`bbbcceZQYUU\Y]c`__cdbhomnllllu…„ƒyu|„………††……††ƒ}wrrtxyyyy~}yuyvvrnzwvxYQKFDGEBEGHFGHHFGIGHGHKILDDKKNMLKHJJHIF?GGNKKKMKKKIFGCD@DAHIC@JKHP]aZ[d]_TQRX]\\\_ZKW\LR\YIM^PO\_accccb]dcbdcfXQVTQZWZ`_^^aa_dlkmjjlnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMC@IFDFKJFFFHGGIGFFILJNFDKKMNJLIKJHHFBHHQMLKOMJKIGGED?ECIICCHGET]Y^X_Y_[]UXXP]]QKJV^X^[]UYaRQ__bb``bb`cbaddbXOQPQZR[]]]]^__chgljnnp{{|~{€‚ƒ„…„…………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKCAHFDGMRHCQJEGHHEFKJMPEFIJKNLLIKKIIGDHKQOMMPLLKKHICDAEDIGCCHFDWUE\T]SV_XOTUNZZMIJT`a[_X^^a]NXa\``_bcb]abW__TPOOOWQ\[[\\^_affeleoow|{€{}€„„„„„„……ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~JNFDFFHDIRbPCV^IGGHDFMJPPEIIJKNLKJLKIJGEJNQQNOOMNLMHKADBCDGDCCFGBMHBKKOONLFMFGIJHGLKMOPILOPOSPKOSRUZYWYXXdWOSTPPNMNTRZXXZ]\``decgcklpsryy{z„„„…„„„„‚„€~{ƒ}{…„†††‡‡………„„„‚€}KIEEHFGDKM]LGGXLGHJHGMLQPHKKKKNMUNOJJKGGKPSSNPONONNGKF`ED_LEgdFN\I^[rmOMUmYLDP`UkWgJ]WU^DLQULLSVQRTXWTXUT\UPfZhhdXRjRVUT[\[`_abab_fhfnkhrz|}~„„„„ƒƒƒ}|zr{z{‚€ƒ„„……„…ƒƒ~z{LIEGFHEEKOSIJF`SGJOJIOMRPLMLLORUROOIKNGHMQ[YOPPNOOOIJQQI|YYrtYQmHqnoaVPqqsPCksmqspSo_ZnX]V\XUkhU]VcZ`Y[_VVXjtuu^_v^Wa[[f[^`aaa]_agmpl_pwtx‚ƒƒ‚~}€vxzlv~tx}€|~€‚„|€ƒz~wwNJEHMNBDLLFIKEQULKNIKRXWQNNOMQTNOQOKKNGMOS[ZTQROPPPJHZx]TxehZSURvgtlpbnfjQrOMwmjrpsrqrooo€]ezuxqqzq~s}ku}bRh|essorr{|o~xn€r_``baZ`_gknkblfglw~€‚}{xw€tvzir~ns|~wx{~€ƒx|€u|||ssNLG`]GAELMGJJGIONMMJNV^YULQSNXZMSSRMKOHQRTYWWPTPPPQKHgxlcxrm[LNVypumubovPeeJfvqmwo€jfxwiWrQhzmijzz}lxzohoYvvjvup€_rf}ilx|o^__baZ]bdgiidgbcdllppstssszqrxblugry{rrvy~suzn|}yxrnNKSuNCBFPPHJKIKPNNOMPZ`ZWKTWPa^RVQYRLPISTUXWWPUPONRJKrouuquqdiaWnLqp^FhyWvTKhy}x`y{sna]mocRgqunmypwlvttrln]t~zkmy|ktl|kpvux^__b^\_ddiggee^abiiijknokqomjpacfcowxompsynqpk{ztromLL[VHGEGRPILMJKPQPPPPW\YUMUYUeXRRY]SLNITTWWYWOSNNNQIRmHiwK`dvwVXlOnl{sajgvULWkh}lmlx_Zpz{^`zscroxqhd}ir|^TLl_vukiu{zm~xk|p\^^b[^addfeeebZccikkrsrvglihdgaakagsrlgmmr}kmhk{tmmkmOHKKHJHHQPLNOLKRRROSRWRVTPWZVVTTTa_PNMJTSTQVVNNLMOPKHQNPULKLSTSSTPVUQQNQQXYRNPUTXXX[[URSW[WXWZOSUWXXR^YW^WUPYRWWWWX^Zgr^[[Y\]_cZ_ccdfdccbZcbgfemnmueegcaf_]g`dlhfgkhpzhggjujhgilPIKLLMKJSQMQQOLVUTPTUXUZUQZ]UUTWUYWOOKMVTQNUSNOMLQPLJRQKQMKLPRUSQRSSIHLNOQRQPQTVRXW\WSRPRTUUSZQNSRXVTYWUZVTRVTTUWXV\Y]`][ZZ\\_c[]bcdfdddaY`acabhhimbad^_c\Zd\ama^fefmsdigjkedcfhPJKLOOLMSPNSQPMXWUTUWWWYUS\`VWVYUXRPPJNWSPNUPNQNLSPMOUSNRNMOQUQUQRTUNKMOQTTRRQVWUYZ[YSURTWVVY[TPTUXUUZVXZUSRXVUW[XY^\UX^\^\[]``][bbcgfedbX_ab^`gdfea^_]]^ZZ_Z_g`^]]bhkagfgfd`bcbOLMLQQLOTOOSQOQ[YWWXZYXYV]jdVXYZWVSSOJNVTPOTPPPMMRRPRXTQQOMPTVOXRTUUONMQTUUTTRTWV[]\ZVVQQVXV[[WQTVVVVYTXXVSSYWVZ^Y\^^U^\^`\[___^ZbbdhgddbXa`b^^fcc`b]\\\\YZ[X[a\_]\_b__bdebd__`\PMNNRQMRROSTQOU\ZZW[[\YZ[dqmhd_[XUUWQLMVSMNROQROLPSRUZUSPPMQXWRWSSSXMOOQTXVUUSUYX[^][[VQNUVU[[WRSWVWXVTY[UTSZXW\^Z^__Ta\`a]`b_\`]c`cghdf`Yc`a__ed_`b[Z\[\ZZYXW\Z\[`^_[^^a`_b\Y`[QNONVQPTQOTTSPW\\\X^\^V[^jqwy€c\[UUWPMOVSNQQORTRLRTTY[WUOROSXWTSURRZOPRRV[VWWSVZX\][[]VRMTUU[\VRUVVXYSUZ\USS]XZ]^\``_Va[cb]ad^\bab^cfidf][d`a``ce_b^YZ^[\ZYXYWWZZZa\][]\\Z]`W[[ZPOOOYPUTRQWRTP[^^][`\`U\]hjr}slg[TWWQNRZSRQTRTUTKRWV[YZSOSQVVVTOWRRZRTTTX]WXYSX]X^]YZ]TTNUVW^[XRUUYYYUWZ\VTW^Z]]`]bb]Y_[ea_dd^^cca]efidf]]da`aabd`b^XZ_Z\[XXXWW[Y[`\[[\[XY[^V^Y]QOORZPZTUVVSTT^^`^^b\`U]^bkytl}kZTYTPPS\TUTUTVYWLR[W][]ROUSXWWTPXRSWSVUU[]X[YUZ^X_^Y\YRVQYXY_[ZTUVZYZWXZ\WU[^]^`a_cc\^]]eaafd^^dc`\gdheda_da`a`bb_`^WX^Z\\ZYYWV]Z]^ZY[\[WY\]VXW]SOPVYQ]UVYWWUX__aa`c]_U]^beeuzhWXYSUSV[XWWVVW]XOU]Z^]\TRXSWWUSTXRSVTXWX]^X][V]_X__X\VQXTYZZaZ\VWX[Z[YYZ[YW^_`_cbadd\b\`fadfd^_dba[fchecf`f__aaaa`_^VU]Y[\[Y[YX]Z[[XXY[YZZ]_]TY]UNSYVS\TVWYVV\`abc`c^_V[`da_zuohYZYTWTW[ZZ[YXY`WPU^\``\TTXPUWVTVWRSUWZZ[_^Z_\V__Y]^Y]URXWYY]bZ^WX[\[\[[Z\ZZ__``dbcddbdZaebffe^ab`c]bcidcg_g^aacaa`^_XT[ZZ[[X[XX\[Z[XVYXW\[[`]V]]SOVYVVZUXUXWX]_badad`^YYadb`lfh^\\ZVWXY\\]_[Y[bVUX^]ac\RVYPWWWWWVSUTX\\^``]`\Wa^[^[Z^WUXX[Z_`\_YY\\]^_\[]Y[`a^`dcdeeebXcedhgd^c``ec\eidei_f]cbcaa`__[XYZYZZXYXW[[Z[WXZTY]\Z`\U^bNSWYVWYX[\XWY^`badada]^Yacb_a``^\\\WW[[]]__\Z]cYZX]`cd_RXYPWWXYYWVWV\]^`a`_b^Ya]]^Y\^YXUV[\`^]_[Z^]^^a][[Z\`b_becefefbZdffigb_c^afdYhhbfice^bbca``_]\ZX\YYXXZXWZ[ZYWXUU[]]]``bbxKXW[YV\[\]ZW\]_`bdaba]`Xbcbacab][\[XW\\_]`_][`d]\X[becaR\ZOYXZ[[ZWZY`]`bb`ac_\b]_][^]YXTW]^_`_`\[^^`bc\\X\^`bbcedfdefd\efgifcab[cg_\ihbhied`baca_`_\]\Y\YXWXYXW\ZZWVXOXZ]acefrkJYW\ZZ_\[^[X][^_acbaa]b[bdb`bbb\[[ZWXiq`\`_]\ac_^YYcedaS_ZRYX\]][Z[[c`bbc`bda`c^`\^^^YXU[_^]ab`^[`abfc_]T]``cddfegeffe^efhhgdd`Zeg]aghchhfc`bacb___]][Z[YXXXVZV\[ZVVUMXW\hikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡„‚‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vvvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyz{{{{{{{zzzzzzzz{{{{zz{{{{{{{||||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vvuvvvvuvvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{zzzzzzzz{{{{{zz{|{{||}|||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚‚ƒ‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||vˆ‹‹‹‹‹‹}}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ¼†‰‰‰‰ˆÌÓÒÒÒÓÓĽ¾¿¾¾À¢ŠŒŒŽ‰~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}vŒƒ~~†“y1333332j‚€€€{­éääääèʉŒŒŒŒŠ”ÝæääåäåÓÌÌÌÌÌϪ‹}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}vxxxxxxxwwwwwwwxyyyyyzwopppppprrrrrrrwzyyzzz~ƒƒƒƒƒ„||||||}ƒ„„„„ƒƒ‚‚‚‚‚‚‚~|}}}}}}|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚ƒ‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vvvuuuyvvvz{x{xwvwzwyyz~|yyxxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{yyyyyyyyyyyyyz{{{|||||||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwvy}||{y|{xwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰Œ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwvz}|z{x|zxxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒ„‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z{xwv{}{y{x|yxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzyz}zy{y|xxxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyx{xyzyyxxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyyyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†„ƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{|||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}|||||||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠˆ††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}|}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚‚€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚‚‚‚€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrsuuttssssrrqpoooopqsssrrrrstttsqqqrststttttsstsssttttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqsttssrqqqponnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqrsssssqpqpponnnnnonoppqqqqqppqroonopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrrrsssrrppppppoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpqqqsqrrqpn|‚oppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqqqp‡†prqor˜‚npppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqq}¡‚pro‹ž|nppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsqu‹‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqqu¡wqwŸœ}oqqqqpppppqqqpqpppqpppppppppppppppqqqpqqpppqppqqqqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrrq˜¨o‚£~pqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxwwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒƒyrssrrrsrrssssrstr“©¤yˆ |rsssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~€~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz~|~}|vvwwvuxzxxxxxwxyyŸ´©¤¨¨—}{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~|{|{{‰¯¦¡µ«¬£~{zzxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}}}}}˜¥–¡² ™§“}€}}}€ƒ‚€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€œœŽ ¯ Ÿ¢Ÿ€€€~~~€~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰‡‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~€€€—šŽ˜±¡˜–œ…|~~~€~~~~€€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽŒ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~€~~€~~Ÿ«¥–¤››– Ÿ†~}€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“ŠŠŠ‹‹‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚ƒ‚ƒƒ†Ÿ²¨¢ ˜¦¨­¨ ™‡€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒ‘‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒƒƒ† ­±¦›š ›žœœ¡¤£”‡ƒƒ‚ƒƒƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒƒƒƒ‹—™—–˜ ›™š—‰††‡††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ„„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒƒ„ƒ…………††ˆ“““’‘ŒŠˆ‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„ƒƒƒ…„‚†Ž”“—šœœ›”‰‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž““’ŽŽ‘’‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„„ƒ„ƒƒˆ“•˜’‡ƒ‚………ƒ„„……ƒ‚€€€€„ƒƒ„……„‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡‡…†††‡ˆ‘“‘ŽŽ‘‘Œ‰ˆ…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€‚ƒ‚‚‚€‡›ˆ‹‡‚‚‚€€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„„„„…„…†’“‘ŽŽŽ‰ˆ‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆˆ‡ˆ‡…„‚~~€€€~~€‚‚€„ƒ€€€€ƒˆŽ€‚ƒƒ€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“‘Ž‰†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚‚ƒ„‚‚„„‚ƒ‰–ˆ„‚„‚‚Œ•‚‚‚„ƒ‚‚ƒƒƒ‚ƒƒƒƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘Œ‡…ƒƒƒ‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒ€ƒ‚……„„ƒƒƒ‚„Ž™‹ƒ…„„„‚€‘™†‚‚‚„ƒƒƒ‚„„…„ƒƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”“’“ŒŠ…„„ƒƒ‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~Œƒ~}|}ŒœŽ€‚‚‚„””Œ‚‚ƒƒ‹œš¡šŠ‚‚‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†””’“’Œˆƒ„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††††††…†ƒƒƒƒ€‚‚‚‚€~•—‰€}}}}{˜Œ€ƒ€Ž”Œ‚‚‚‰’Œ–££‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“’Š†ƒ„ƒ„‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„………………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€€•ŸŠ~~€}‡‹~„„ƒ„‚ƒƒ‚‰…Œ‚‚ƒ‚ƒ‚“”–˜’—žœ‰‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†„…ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„‘¡ŠŒ…}†‰€~………„…‚}}}‚„ƒƒ„„‹™”š™—–•’„„„„„ƒ„„„ƒ„ƒƒ…†………„……………„…††††…………………………††…†††…†††‡†…………ƒ„„„‡“““’’ŒŠˆ…†……‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…ƒ‰‘ƒ„‹…‚~}‡†ƒ€~~~€ƒ„ƒ„„‘•ƒ‰–˜–•”ˆ„………„…„†…………†††…†……†……‡†††††…„……………„…†††‡†††††‡‡ˆˆˆ†………„……†”“’‘‹Š‡†‡†„‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„„„‚‚‰~}~…~€€„…„…“˜™˜˜–‹…†…†……†‡‡‡ˆ†‡‡†††‡‡‡††‡‡†††…ƒƒ„……†„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘”“‘‘‹‰ˆ…†…ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒ„„„ƒ€€€„„~}~€€€€……ˆ¡ ››Ÿž’Š‡ˆˆˆ††‡ˆ‰‰‰‰ˆ‡†‡‡‡‰ˆ†‡‡‡‡††…ƒƒ„…††………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†……„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡†…ƒƒ…„„ƒƒ€€Œ‰€‚€€~{z€ˆš šš£¢›ŒŒŠˆŠ‹Šˆˆˆ‰‰‹‹ŠŠˆ‡‡ˆˆˆ‡‡ˆˆ‡‡†‡†„ƒƒ…‡‡‡†……„„ƒ……„……†„„„………†…†…ƒ‰”’‘ŽŠ†…†…ƒ‚‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡†„„…„ƒƒ‚€€€„„‚‚‚ƒƒ‚‚€~}}}}~~|{{”¡—–™ŸŸ›˜‹‹‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰††††‡…†ˆˆˆˆ††‡„ƒ‚„‡ˆˆˆ‡…‚‚‚ƒƒ‚ƒƒ„‚‚ƒ‚„ƒ„ƒŽ“’‹ˆ……†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„……‚€ƒ„‚ƒ‚‚ƒƒ~}}~~~~~~}~}}•“—˜“˜š—‡‡‡ˆ‡‡‰‡‡†ˆ‡†‰‰„ƒ„ƒ…„„……†ˆˆ†…ƒ‚‚ƒ…‡†‡††„‚ƒƒ„‚ƒƒ„‚‚ƒƒ„ƒ„‘’ŽŽ‹‡…††„‚ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…‡ˆ‹Š†„†„‚††‚‚„„ƒƒƒƒ‚ƒ}|}€~~~}|}~|z€‘ŽŽ“˜™Šƒ†……ƒƒ…„„„„„„…„‚‚‚„„‚ƒƒ…†…„‚‚‚‚ƒƒ…„„„…„„†ƒƒƒ…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰…„…„…‚ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€€„„ƒƒƒ‚‚€}}€€}~~}|}}{zz…Œ”—”„€‚‚~‚ƒ‚‚‚‚ƒ„€€€‚‚€€€€‚ƒ‚„ƒƒ„„‚ƒ„ƒ‚‚‚„ƒ……†‹“‘‹ˆ……ƒƒ„€‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€€ƒ‚~~~~}‚„„‚ƒ‚ƒ‚~}~€€€~}}}}~}|z{{ˆ†~€€~}€~€€€€€~}}€~€€€€€€€‚€€‚€‚€‚„ƒ†’ŽŠ‡‡†ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€ƒ„‚‚ƒ‚ƒ„…€€||}~}}~€€~}~}~€ƒƒƒ‚‚}}~€€€}}}}|{{{zzz{‹†~~~~~€~€€€~}~~}|~€~~€€~€€~€~€…’’Ž‹‹‡‰…„ƒ‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€}~~}~€~€„ƒ‚€~}~~€€€~}}}}{{|zzzzyŽŽ”Š~€€~€€‚€|~~~~}|€~~~€~€€~~~~~~~}}}}…“’ŽŒ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒ‚‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚‚‚€ƒƒƒ€€}}}~~~~}}}}}|||{zzzzyƒ•Œ‚€€€€€€‚‚€~€~~~~~€€€€€€€~€~~€}~~}{|†“‘Œ‹Š‡‡Šˆ††„„‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…‚ƒƒƒ…„„„„„ƒƒƒ„‚‚‚‚‚~~}}}~~€}}}}}}}}}|zzyyy{‡ˆ”•„ƒ‚ƒ€‚€‚ƒ‚ƒƒ€€€ƒ„‚€€€€€‚€€€€€€~~||‰”Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…ƒ„…„…†…†††…†…ƒƒƒ‚‚€}}}}}}~~}}}}}}|}}|{yyyyy|‚‡‘„ƒ‚„ƒ‚‚ƒ…‡‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚‚ƒ„ƒ‚ƒ‚‚‚€€€€~Ž“Œ‡ˆ‡ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€~}}}~~~€ƒ„‡‡„†††…††‡‡†‡‡ˆ‡‡‡†}€€€‚~}}}}}}}}}}}}||~~~|{yxxyyz}‡‚Š„ƒ„„„——ƒƒ„}~‚‚ƒ†ˆŒ…ƒ‚‚„‚ƒƒ‚ƒ…„„…ƒƒƒƒ‚ƒƒ‚‚‚‚ƒƒ‚‚‘‹ˆˆ‡‰‡††„†…„„„ƒ‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€€~}~~€‚………‡†‡‡‡‡‡ˆ†‡‡‡‡†‡…~}}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yyz{}|…‘ƒƒƒ„„”“€~~„Œ€€€„†‰…„‚‚……‹‚‚……††„„……ƒ„„ƒƒ„ƒ„„„ˆ’Œ‰ˆˆ‰‡‡‡…†…„„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„ƒ…„~}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|yzzzz{‚€ƒ‚€~}{ˆ‘||Ž–€}~‚†Š…ƒƒ„ƒ‚ƒŒ‰~ƒ„……ƒ…†…„……ƒ„……†„„Ž‘ŒŠŠŒ‰ˆ‰‡………ƒƒƒ‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚€‚€~}}||}}|||}||}|}}}|||{‹‘—Œz{|zyz{|yx|}~€€}{{~}‚•‘„ˆ}|~‚„||‚„ƒ‡ƒ}‚€‚‚€ƒƒƒ„„„„‚„ƒ„…„‘‘Ž‹ŒŒŽŠ‰‰………ƒƒƒ‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚ƒ…ƒƒ…………ƒƒƒ„‚‚ƒ‚ƒ‚‚€€~~}}}||||||||||||||}|||~~Š‚{z{zxz{{|}{~~~~~~}}|€€}†~}‚~~€‚||€‚€€~|{Š‚}€~€€‚‚€€€€‹”Œ‹ŽŽˆˆ‡………„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ……†‡…„€†”ˆ€‚€~~~€|||||||||||||}|||||}|yz{{xxy{{z|‚€€}€}€‚‚€€€‚‘€€~€~~~€}}}{}}}|}||}€€€~€~~‚”’ŽŽŠ…††…„„…ƒ‚ƒ‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚‚„†‡††~ˆ•Š~€€€~€~~~|{||||||||||}}|{}|||{|||zzy{|z}…ƒƒ~€€~…‚~€~~€…†‚€~~ƒ†}|~€€~}}}}~{|}€}~Œ‘ŽŽ‡„††…„„„ƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}€‚„††……~€€€~~}€€€€}|||}~}|}}}}}}|~|}|{}||z{z|}}†…ƒ€€}~}~~‹„‡~}||~‚‚}|}}|{}|~„ƒ€~~~~}|~€}~€~~„’ŒŒŠ†„…„„„ƒƒƒ‚ƒ‚ƒ‚ƒ‚€€}|||}~{{}w~vx~}|}|}~~‚ƒz~~|~~€€~~~€€€€~~~~~~}~~}|~}~}}}{|||{{z}~€€ƒƒ‚~|||}||ƒ~Œ~|{{}~}~}}|{{}|{{{{€†„‚„ƒ€~‚‚‚‚‚€‹Œ‹Šˆ„„„ƒ„ƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~€€€}€~~~~~|‚}~}}}{{}}|z||}‚€€€}}}|||||}|~{~{{{|||}|{|{{||zz}z~‚~‚„„‚‚…†……††‡…„‘‹Š‹‡‡…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}{€~~€~~€‚€~~€€~}ƒ||}}|}}}}{|~~~~~~||}||}|}~{|{||||}|}|}|}|{{{|y{|{{}z}~~€€ƒ‡‰‰‰Š‰Š‰…ˆ’‰Š‡……ƒ‚‚ƒ„„ƒ‚‚‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€~€€~~~}€€€€ƒ‚€€€€€€€€~|y|~}~}}~~Œ†}}~{{ƒƒ}}}|}|}}}}}}|}{}|}}~}~}}~}|{{{|{||{z{{zzz{~}‚†ˆ‡ˆŠŠ‹‹‰Œ‘ŽŠ‰†…„‚‚‚‚ƒƒƒƒ‚‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚ƒƒ€€€€‚~~~€~{~‘Œ|}Š€Œ~~}}}~}}~}}||}}}}|}}}~}}~~|{{{|{}|{z{{yzzyz{~ƒƒ„ˆ‰Šˆ‰ŽŽŒ‰‰…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{}||~~}}€€€€€‚„ƒ„‚‚‚‚€€ƒ‚€}~€~|~ˆ‚~ƒ‘„„ƒ~}|‡}}~}}}~~|}}|}}~~}~|}|{|}~||{|}zzzyyyz{~~€ƒ‡„ˆŽ‹Š‡…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{}}}}}zx‚€‚‚€€€€‚‚‚‚……„‚‚‚€€‚„~}~~}~€€}~„€~~}~}}Š…}~}~~€~}}||~~~}€}}}|}||{|}{{{zzzz{|}~}‚€‰Ž‹Œˆ………„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv}€ƒ‚‚‚‚‚ƒƒƒ‚…†„ƒ€€€ƒ€„~~€~~€~}~~€€~~€€}~€~€~|}}|~~~~€}‚€|}€€}{}~}||{||{{{|{||}}|ŠŠ‰‰††……„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€‚€€€ƒ~~€}€}}~~€€‚€€€€€}€€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{|~|}|||{|{|~Š‡‡…†ˆ…„…„‚‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz~}yxtt€€‚‚‚ƒ‚ƒ„ƒ„ƒ‚ƒ„„„ƒ…„€€~€‚~~~~€}~€}}}}€€€€€€~~€€€€~}}}~}~~}}„€~}}}~}~~}~|{|z|{z€ˆƒ„„…„„„…ƒ‚‚€€‚‚ƒ‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xyuu}‚ƒƒƒƒƒ…„…ƒƒƒ„ƒƒ„…ƒ€€~}}~~~~~€}}|}}~€€€‚€€€ƒ‚€€~€€€~~}~~~}~……€ƒ~€~€~}{z{z|{z‚…€ƒ‚‚‚‚‚ƒ€€‚€€‚‚ƒ‚ƒ„ƒ„‚„‚‚‚‚€~€~}~~~~}~}}z{|…„{{sy{|pwuvwyutz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€€}}}~}~~}~|}}~€€€€€€ƒ‚€~€€€€€€€‚‚‚€ƒ‚ƒ‚€€~|z{z|{|‚‚€‚‚‚€~‚‚ƒƒƒ‚„‚„‚‚€~€€}~~}}}~}}{{z€x|vyz|qtxwvxury……‚„„‚„……†„ƒ‚„ƒƒ€€€|}}~€}~}|~~~~€ƒ‚ƒ€‚€€€€€€‚ƒ€„€}ƒ„€€‚€}z{{|||}€|}}€€~}}~~‚€‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxzzruyyvwwsu†…ƒ…„„„…„„„ƒ‚ƒ€~~€~€}}}~€~€~~}}€|~€~€‚ƒ€€ƒ…‚€€€€€ƒƒ€ƒ€~‚ƒ„€€‚‚‚„‚~{{|||}}}~}z~}}x~|||~~~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„‚„„…„ƒƒ‚ƒƒ€}~}}}€~~}}}€€~|~~~‚‚ƒ‡…~~€€€€€€‚€€~€‚‚ƒƒ‚ƒƒ…‚}}}|{||yz{z~y{yx~{|{~}}€~€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst…„„…ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚}€€~€}~}~€€~|~€€€}~~€}€€ƒƒƒ~}~~€€€€‚€}€‚‚€ƒ‚„…†„€~}|}||{yvyyzyvyv~|{{{~}{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtu†„„…„ƒƒƒƒƒ‚‚ƒ‚ƒ‚~~€}}}}~€€€|€€€|€~~~€~}~~‚‚~~}~~~~€}€€~~}~~€‚‚‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{{{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvpxyrx…………ƒ„„ƒ‚„‚‚‚‚€~~~~€~}~|~€€€€€€|€~€€€}€~~~}}}~€€~~~~}}~~~|~€~~~‚~~€€~ƒ‚ƒƒ†„€~|}||{|xw{xuywwy|{{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}|{|z{}zzx{|zz{xtxuqrtpxxqy„………ƒ„ƒ‚ƒƒ‚‚‚€‚€€€€}~~€}|~|€€€€€€|€€€}~~}}|€€€€~~~~}|~~|}€~}~€‚€~‚„‚‚ƒ……‚‚~}|{{{|yw{ywxwwx{{{{|…‰}{zwz|}}||}}}~|}~~}}}|}}~}}||{zz|{{zyzz{zxswuqqsoxwq{…†……ƒ…‚ƒƒ‚€‚€€€€~~}|~~€‚€€}~€~€}}|}€€€€~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y|||{zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚‚€€~}~€€‚‚}~€€€‚€€~|~|€€€€€~}~~€€‚€€€€€€€„‚‚€~|}~~z}„~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚€€€€€€~}€€‚‚‚€~€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€€‚€€~}~{’z|}|{}y{zzxzxy{||}|||||||}}}||}|~}~~~}|z||{|}{yzzzyytuuooqpwst}…†ƒƒ‚ƒ‚€€‚ƒ‚€‚‚€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€€‚€€€}~~|†‰||~{{~yz{z{wwy{|{}||||{}|}}}}|}|~~~~|z|}{}}{yz{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚€‚‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€€‚‚€€€€€€}~€}€ƒ‚{~~{|}{z||{‡zxxy|||}{||}}}||}}~}}}~~€}{|||||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€‚€‚‚‚‚ƒƒ‚€‚€€‚‚‚ƒ‚„„€~‚€€€€‚~€€‚€€€€€€€€~}€~€€€€€€€€€€€€€€€€~}~}~~{}|}{||wxuxxy{||}|||||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒ„ƒƒ‚‚‚ƒ€€‚„ƒƒ„ƒ‚‚‚€€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€‚€€€€€€€€€€€€€€€€€€€€€€€€‚ƒ‚‚€‚‚€€€‡~~|{}|{}~xwvyyz{}||}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚‚„„€€ƒ†ƒƒ„‚„€„ƒ‚‚€€‚‚„‚ƒ‚€€ƒ‚€€€ƒ€€ƒ‚~‚€€~€€€€€€€‚‚‚ƒ‚‚ƒƒƒ‚€€„}}}|}z}{zvzxy{{|}}{|}}}}~€€€€€€ƒƒ€|~~~}yy{zzzysrtowqwysw{…‚‚‚‚ƒ„‚ƒ„ƒ€ƒƒ†ƒƒƒ‚‚„„ƒƒ€€‚ƒ‚‚‚€€€‚‚‚‚€€€€‚‚„€~ƒ‚€ƒ‚€€‚ƒ‚€‚ƒ‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ‚€‚€}€|z||{w|yyy{z}~}||||}~~€€€€„„€}€~{{{z{ztpxqytvxtv{„‚ƒ‚ƒƒ„‚„ƒƒ‚‚„†„‚ƒ‚ƒ„„ƒƒ€ƒ‚‚‚‚‚‚€€€‚‚‚‚‚€‚‚‚ƒ€~ƒ‚„„ƒ‚‚ƒ‚‚‚„ƒƒ„€‚ƒ‚ƒ‚‚‚‚ƒƒ„ƒ„„„„„…ƒ„‚ƒ‚ƒ€€~||€}|x|yzyz|}|{||}}}||€€€€€‚€€€€€{{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„‚ƒ………ƒƒ‚ƒ„‚„…‚‚‚ƒƒ‚‚€€~€‚ƒ‚‚‚‚€‚‚ƒ‚‚‚€ƒ‚€‚„ƒƒ‚‚‚ƒ‚‚ƒƒƒƒƒ„€‚ƒ‚ƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€€{}€~|y|zzz}||}z||}}|z{~~~€€€€€€‚€€}}|}}|vrwxxvtvu}‡‡ƒ‚„…ƒƒ„…„‚„†„„ƒ‚ƒ„„ƒ…ƒ‚‚‚ƒƒƒ‚€‚€}€€‚ƒ‚‚‚‚„‚€‚‚ƒƒ‚‚‚ƒ‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚ƒ‚‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz{}€}||z|~}|}}~~€€€€~~€€€€~|}}~~}||xvvw„‡ƒ‚ƒ…ƒƒ„†„‚††…„„ƒƒ„„‚„…„‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚‚ƒƒ„ƒ‚‚ƒƒƒƒ‚‚ƒ‚‚ƒ„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒƒ„„„„„…„ƒƒ„…„…„ƒ‚€}‚€}||{||€}}~€~~}~|||}}~~~€~}~€~~}}}~}}~~€|}€‚‚ƒƒ†ƒ„ƒ†„‚ˆ†…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~‚ƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒ‚‚‚ƒƒ‚‚ƒƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒƒ‚ƒƒƒ„ƒƒƒ„„ƒ„„…„„„…………„ƒƒƒ~„€}}||||~}}{|}}}}}~~€€€}|~‚~~~~}}€€€€„„„ƒ„…ƒ„ƒ…~‚Š‹……„ƒ‚„…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ„ƒƒ„…„……‡‡†‡…„„…„ƒ~~|~~}€~||~|z|}}}}}~~~€}}|€€~~~~~‚€……„ƒ„„‚„ƒ†€‚„…‹ˆ„…„„……ƒ‡††„„„„…„„„„ƒ„„‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ„€}uyƒ~„„‚ƒ‚ƒƒ„ƒ„„…ƒ„…†„„†}ƒz}~ƒ{…ƒ„ƒ€}~~~ƒ}{}~€~}|||}}}}|}}~€‚}}|€€€€‚ƒƒ‚‚†„„„…„ƒ„…ƒ„…ƒŠˆ………ƒ†…„†††ƒ„„………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€„j|{qq|s†stt}‚ƒusqƒ†spurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚…„‚hzrss|€r‚„~ƒƒ}}~~}~‚ƒ‚|}€}}||||}}||~}~}}}€‚€‚‚‚‚‚„‡„…„…„‚‚„††ƒ…„†ˆ††…ƒ††‡‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ…„†††„†„ƒ„„†}p{pyv~ƒ‚nypus|vyy†r„ƒpvxqvtturstvi€nrotvnulwmzsn€‡zm}rsvsvmnwlpylu}|~€}€}€€}}|||}|}~}€€€~|~€€€€€€€€‚ƒ‚‚ƒ…‡…†€‚…ƒƒ…‡†ƒ………†‡‡„ƒ†‡ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoolw}x†pqzprtfu~n{ysoy€}~{~}€~€€~~€€€~~~€~}€}€€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„………††ˆ„„†‡ˆˆ†‡„††‹‰…„†‡‡…ƒ…„…„‚…………†……†…†quprsoszy~„tˆtu~ˆvn‚r„…ynjrqmsw|ut|„~xquwnyuzqvxuzy„rioyxpkyszozwvvp~~z~}|~}~}€ƒƒ€‚ƒ‚„‚€}~~~€~~‚€€‚„‡†ƒƒ‡„„„…‡†…………‡†ˆ……†…‡‡††„††‰ˆ…„‰Šˆ…„……†…ƒ……„††††††ƒx‹yrˆz{pp…„x…xyks~y{krƒ‡ƒz|mzyyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozks|nv‚~~}}{}{|}}~}‚‚ƒ„€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡……………‡‡ˆ†„†…‡††…„……„……†‰‰‡……†…††…††„†††††…†‡‡‡††ƒ†…†‡ˆ‡…‡††ƒ‡†……ƒ„…†…†„†„ƒ„„†„„ƒƒ„ƒ…„…„…„†ƒ…†……„„…‡†„„…†……}w…ƒ„„ƒ~~{|{~{|}~}|~€}€~~~€~~~~}}}~|{|~||‰†…„†††…††…………††‡ˆ†„†…‡†……ƒ„…†…„††‡†…„†„…††††„‡†‡‡†…‡ˆˆˆˆ†…‡…††ˆ†…ˆ‡‡…‡††ˆ……†‡…††…ƒ‚……†……ƒ…ƒ„„†„††„……ƒ††…†…„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ}€{{|~{||}~~||~}€}€~~€}}|€}~~~~||}~{|||{{~ˆ‡„„ˆ††…‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„†…††……†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ……ˆ…†‡†‡†‡†‡…‡‡†‡……†‡…††…‚ƒ…††„„ƒ„„ƒ„†„††„……ƒ††…†…„†‡…„„……ƒ„‡†„‚ƒ„ƒ„‚~€|{}~{|{~~}||~}~~}~}}~~}}||~~|}|||}|||~z{{|~ˆ‡‚…ˆ‡‡††††…„††‡†ˆ†„„„‡†„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆŠˆ…†ˆ…†‡…‡†‡†‡…ˆˆ‡‡…††‡…††…‚„„…†……„„„ƒ„…„†††…†„†…††……††…„ƒ„„ƒ„‡ƒ„‚„…ƒ€€€{{}}|||~}|||}~|}|~}||}||||}|~}{|€}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††„…†…†††…ƒ„„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡„††…‡‡‡…‡†ˆˆ‡‡†‡†‡…†‡„‚„ƒ„†…‡…„„„„„…†††††…‡……‡…†…†…„ƒ„ƒƒ„‡ƒ€‚ƒ„‚‚‚€{|~}|||~}||}|}{||{||}}{{{}|{~}{|}}|}}~}|zz{{||ˆ‡‚†‡††‡††…„…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡ˆˆ‡‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡…‡‡††‡‡…‡†ˆˆ‡†…‡†ˆ††ˆ„ƒ„„ƒ††‡……„„„…†††††…†‡††ˆ††„†…ƒƒƒƒ‚ƒ†ƒ~‚‚ƒ€ƒ‚~|~~||}}|}}|~{{{z{|||{{{~{{}{{{~||||}~}{z|z||‰‡ƒ†…†…†††…„……………„ƒ„†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…‰Š‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……ˆƒ„†„„††‡†…„ƒ……†††††…†‡††‡‡…ƒ……ƒ‚‚ƒ…‚ƒ~‚„‚~~~€~||}}{}}|~zz{y{|}{{{{~||||z{}||||~}|{{{{||‰‡„†„†„††…„…†…„„ƒ„‚€ƒ†ƒ‚z„Œ{€„…‡†††„„‡ˆ‡†‡……‡‰‡„‡…††ˆ†…‡„†‡‰††ˆ‡‡‡†‡ˆ†„†††‡……ˆƒ„…„††…‡……„ƒ……††‡††…†††…†‡„ƒ„…‚‚€„ƒ‚‚}€ƒ~€}|}}~}{~}|}yzzy{|}zz{{}|}||zz}||}|~~€{{{|~}|ˆ‡…†…†„†………………ƒƒƒ€…‚€}|{„…††„…„„‡‡†††…„†‰†‚†„†††……‡††ˆ‰†…ˆ‡‰‡†‡‡…„†……†…„‡„„…„ˆ††ˆ……„‚……†…††‡„†††……†‚ƒƒ…€€€€„€ƒ€|€~~ƒ€}}€|}~}~{~}||yzzyz}}yz{{|{|{{z{}}|}|~~|{{}~}|ˆ†…†††„……„……„ƒ‚€‚€€€ƒ~~€yz}€ƒƒ…‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ†…ˆ‡‰‡†………ƒ†„…‡ƒ„†…„…„‡†††…†„‚……†††††„…††„……‚‚ƒ„~€€€€„€|}~‚~~€~€~}}~}~{}{zyzzyz|}yz{{{z|{{{{|}}}|~}|||~|{‡……††††„…„…ƒ…‚€€€€~‚‚}}{‚ƒƒ…†…„ƒƒ†ƒƒ„‚€…‡…‚ƒƒ„„…††‡‡‡……ˆ†‰‡†„„„‚…ƒƒ†‚ƒ……„†„‡†…†……ƒƒ…„…†…†„„„„…ƒ…„€€‚ƒ~€„|€}}‚}€~~~~~}}{|{zyyzyz{|yzzz{{|z{{{|}}}}€}}|{}€}|†ƒ††…††ƒ„‚…‚…€€€~|~~€‚‚‚„„ƒ‚‚„€ƒ‚€„…„‚€‚ƒ‚„……‡††„…‡…‡…†‚ƒ‚‚ƒ‚‚…ƒ„„…†„†††‡†…ƒ„„ƒ„………ƒ„ƒƒ„‚„„€‚‚}~~~~„~{||€~€}~ƒ|~~}}~{~{{zyzzyzz{yzzz{{|z||{|~~}€|}||}€~€†„……„‡„„ƒ‚†‚ƒ€€~~€~‚|}~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚‚†…‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡………„ƒƒƒ„……„ƒƒ‚„ƒƒ€€~}}~~|~ƒ~|~||~‚}‚|~}}|||{{zzzzy{yzzyzzz{|y{}{{~€}~}~}€€€†ƒ„…„…‚„‚‚„‚€‚€~}~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…ƒ…ƒ‚ƒ……‚„ƒ€€€‚€„ƒƒ†……‡†……„…‚‚‚ƒ…„‚€…ƒ~€~||~}|~ƒ}{~|}€€ƒ}}€~}||}}{{zyzyy{yzzyzz{{{z{}||‚€~€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌÌÌËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFK=8765999<>9?<C9;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;>BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÔÓÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937676=;>:=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<:<<98:9:::;<::;9><>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA=366:;<8C<AA><A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖËËËËËËËËËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9>CE?<;999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNG¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖËËÑÓÓÓÓÓÓÓÓÓÓÓÓÓÎÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø×Ø×××ÚÛÚÚÚÚÚÚÚÛÜÛÛÜÙ××××××××ÖÖÖÖÖ×ÚÛÚÚÚÚÚÚÚÚÚÛÜÜ×ÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXdIILN@99:4;@<7=9AC=@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMMF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖË̃mpppppppppppj§ãÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¹´‹‹‹‹‹‹‹‹‹ŠŠŠˆ¡¿½½½½½½¼¼¼¼¼½´‹ŠŠŠŠŠŠŠŠŠŠŠ‹‡½æáââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑrliNRbLLVM<::77>C?8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKPFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ËÍN&+++++++++++"ŠôëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§£££££££££££¤œXRSSSSSSSSSSSNz®ªªªªªªª©©©©¬›TSSSSSSSSSSSSKªòëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘wliJN_MRUM><<7;?C>6:7>?;=B@9<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ËÍR,11111111111'óééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤¦ž\VWWWWWWWWWWWS}°««««««««ªªª­YXXWWWWWWWWWWO«ñêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;?@@8:;8<<<;>::;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÌÎ\9===========5“ðççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©ª¢fabbbbbbbbbbb^…³¯¯¯¯¯¯¯¯¯¯¯±¡cbbbbbbbbbbbb[¯ïééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB>;=:9::=<;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÌÍÄÂÃÃÃÃÃÃÃÃÃÃÃÂÉÐÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÎÎÎÎÎÎÎÍËÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÑÍÌÌÌÌÌÌÌÌÌËËËËÎÒÒÒÒÒÒÒÒÒÒÒÓÓÑÌÍÍÍÍÍÍÍÍÍÍÍÍÍÔØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<7@A<=8:;898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÍÍÏÐÐÏÏÏÏÏÏÏÐÔÐÐÎÌÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÎÒÓÏÏÐÔÒÏÏÏÓÒÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÖÖÖÖÖÖÕÕÖÖÖÖÕÖÖÖÖÖ×ÖÖ×ØØØØÙÙÙÙÙÙÙÙÙØ×ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?89:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÎÒ«œÏÑȔ§ÒÑǒ«ÑÎÎÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLB@==<=:<=B>BB@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÎÒ¶œ¥¤Ñš¬œ°Ñ™¬š²ÒÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?><7:>9?D>@98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÏ͜‘ž¼•ˆœžÄ’†œÍÏÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>><<96?B?B:648:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÑ¿˜ ›²®Áɘ˜Å¼É—™ÅÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8E@?B:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÓ´™–ª¸¤Ö”–ŸÎђ™¡ÏÐÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<=<964:98::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯Ê £¿Êœ¥Œ§­Øª™ªÔÏÏÏÔ«š~£¤³ŸÃ›Ú­£¿žÕÑÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>9<97659:6:<;7<@@<::=:<?>=<9@<<::9?@==<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÔ¬›§‹•¡ÐŠ’žÇˈ•žÈÒÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖ×××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CGDAA8;?<=;<<7558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÓ¶²²¥™ªÑÛ¥™³ÐÛ£™µÕÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ђl]\oghb]OF?HHFE@<<>><==<756:96:;::;8@?:<<9<>=;;:?9?:;9=>=><;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦ÕÄ¢™–«’§š ­§˜ž»ÕÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;557<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸« ÇÕ¢«¤±¤¥¨ ¯§¢©ÐÓÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKK@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÓÓȑ´Ö’ºÕš’Ž¾ÖÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUij[L_MJLJULFB<<?FEGKH=667:979:;:<=9>99:8;=>>A>=9<<:=>>;=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÔÈÁÕÓÓ¹ÇÕÓÓ¹ÈÕÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?ADLL@>775:8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÑÓÔÒÒÒÕÔÓÓÓÖÔÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEJ==786977899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9599:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EIKAALD??;9889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEHIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDCI;AA;<886586987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGJB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFID<AA<;876797799=?A?<:9@?<>B?:8776=?@@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD88867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE><HF89757875898;>>=;89A>=@?A>7596;>AB??@@AB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCDECALH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HQA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELBA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<<DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGHNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAD?@;<88996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8:87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;99:86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€iixsg~‰‰xp‚†{w}~…Š¼ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkqty€‚wt|„‚}sp€Šx‚yƒÈÞÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxu|v}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsnupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9886543956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿½¾¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78473156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;;>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»º¹¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjcmgb\XQPQKTJB:IQ?A7<94:565455688686;:9<==;:86688:767>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸¸·······¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPF>8;727967443588797;9:==<::974:98668??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹º¹¹¸··¶µµ¶¶¶······¶¶µ¶¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269664737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³µµ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶··¶µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶······¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸···¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B@?C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­«¬¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©©¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶···¸·¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@AA:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¥¥¥¥¦¨¨¨¨¨¥§¨¨§¨¨§¨¨©ª§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸·¶······¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637465738:::::<=::A<6=8378837;@??@@:BEC@BDCA?;;@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥¤¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¥§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§¦¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©«««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤¤£¢¢£¢¡ ŸŸžžœœœœœžŸ ¢¡¢£££¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™—˜—––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@?BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž¤¤¡ŸžŸ  œœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747578;=8::99;=;;89>6789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥£¢¡¡¡¡¢£¥§¦¦§¬«§¦ œ›¡¡ž››šœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””““““’”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¦¦§§§¦Ÿ›š›¢ š–—•š›š——˜™šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¦¤£¡  ŸŸ¡¡Ÿ  š˜˜™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364689:89788:<;<9;;::67899>?@><=@>@:9@A?=A?>AA>AA?:9=>:P Ÿœ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~ššwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§§¥¤¢¡£§¦¥¥£¢¥¦¦¥¦§¦¦ ›™›¡ —’“’—šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB?DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¤¦¦¥¥¦§¦¦¢œŸ¡Ÿ—‘‘”—š˜–—–˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡  Ÿ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846799=88;:;?;:;<:9:7768;<;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¦¦¥¤¦§¦¥¥¦¦¥¥£  ¡¡ ™’–›™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡  ŸŸœœœœžžš—––•”““’’’’‘’’“’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:737959989<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢£¢£¤¤¦¦¥¤¤£¢¡¡žœ›•’”˜œš›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œŸ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸžŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::78:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸŸ  ¡¢££¤¤¤¤¢¡¡ž›š™—¡µž™™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢Ÿ›ž¡¢£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;866:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š™—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££ ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œ››œŸžœœœœŸ   ¡¡¡    ¢¤¡¢¢¡¡ žœ›››™Ÿ«›œš›™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86:756::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥¤¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¢¢¢¡ ¥³¬  ŸŸžœ™™šš›®jvž›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›šœ›š›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>99;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤¤¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ ŸžŸ ¡ Ÿ¦’›«Ÿ  ž›š™š™¨„DŸžžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›šš››š˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9<<>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœœœž žbœ¦žžœšš›œ¡£QGƒ žœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8:;<=:<>9?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš›››››š¦f]£ ›š™›œ®uIL† œœœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\Q<@<68CVHDB:8;:>;7796=:99647:;<>9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™™˜¤€Rx¢™™š› ¤_VN‡¡œœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡ ¡ŸŸŸŸ™š›œš™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd\\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š›››œœ›˜˜™ ˆ[_”š™›œœ£dZL¢žžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[[LF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ›››››››™˜™Ÿ—]]v—šœ¢dYM~¢žžžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž››šœœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<9798:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ›››››œš˜™™š`a`€–œž˜tcUN€¢ŸŸŸžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_^]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜˜——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜™™Ÿi^[eœœžŒj_PR†ž›œœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±´­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=:F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B@AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œš››œ›˜™š˜˜™›šš—“shaTv“—œ‡\VPWŠ’Ž’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨ª¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‘‹‘‹Œ‘‘Ž’šž’} £–¤œnLOc††‚‹†‰Š‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜ž—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VQQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹Œ†Š‹‹‰‡„†ƒ€„ Žl–¥•Ÿ€‰_r€‚’†„„…ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974869388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹Ž‹‰‰…‚‚~€¢‹|nRuœŒŒZq}|~}|†Ž‹†”‘‹—”—’˜¡–ž–•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¦›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ‚†‹‡ˆ…„ˆˆŠ…€‚}˜šwXOLp”†‚L`pqwˆ…ŠŽ‹™œ””” ššŸ¢­±®©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPEMISWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}€~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‘‹ˆŒ‹‹‡‘£U/0=w‡wvAE^km„‰‰””˜•œšž¨®²°°µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWMO_^\NUTbQDTM;?9<895875795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš™ž¡“—›¡š›¢¦œgAZH;wykgE08Yls‹˜šŒ”š—œ› ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUJTOOJDPK_bXZQ\T_MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ªª©§¢¥¨©«©©¯Jo¡xA{wdaPQ[G`nŠ¡¡¤ž›š¤§¤©«®¬¥¤¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdWOYKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®««¬¤¡¢¦©§¨£x`ÀÖ¦C{Œ€uOmŽvSd£¨§ ¢¡®¬«ª§­®¨¥¤©©ª©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_VZNRNQOSe\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢™œ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨§¦¨©§©©¤§§™¤¥£¢b½À¯wž£š”eLaxmQt•¢¢ ¡Ÿ¡¡¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOXO^edlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤ ¢¡¢§¡¦®¦¦žj„œº¦Ð¡™±¨XL¬“Se ž  ž £™–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvxb_\UYQUW[c_s_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?B?:8:>?C@DA:;>=@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯««¬¨¨«¯©¨ª¨¢ ¡¨ª­±²¯«¢¢†w~}rÏɱ›§¯kUª°bZ‡¦Ÿ¥¢¡Ÿ¢˜•ž›ŸŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸŸ¡¦¢›—’šš •|wo}yf[[`_Z\U\hdocmiib^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¡ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£ £ªª§¯··´µ¶³­®­†ƒnÍ¹•‘£—tTozsn{•¦ª§£Ÿž£›¡š–ž¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¡™˜¥ ¤§ª©¨ª­¬¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxjb[__\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>BE@=9;@A>C<;9?9@@@?BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢ «²·»»»¹¹Á¸´µ ˆydYŸ·À¦©ˆwkqoxxz}†Ž’˜œ¢¥¦«¥¤˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨¨«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥¡¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxxxc[RYT__amhvkqhiibZSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶´º±ª®´±°²´µ·ÁÆÌÏÎÌɾ³¤sfRD‹—‰‰ˆ~xqngflikqrqqrt|Œ©ÄÄ»¢§ª¬§«©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš’–””˜“š˜Š‹‡€€|‚xa^YSaiaftotitdidb[LK>:9898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÄÇÃÅÇÛããÚ˼¯¤—ˆtYZQCizlounkeeYW^X\ciihe`h‰´ÀÀ¹©¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`b_^kcbnxuwom[bRV\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAA;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–••‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±°§¼¼¾ÅÄÆÉÇÅƾÍÑÕʹ§”†r^QTKD[f^dkea`hYTXRVXY\XZt™¶»«´²­³­©®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|„jfhaklgnvrrvrg^`\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÄ¿ÂÁÇËÈ·”ueUPOTH>^k^_eb`]daSVVUSTWr›«°ª¨ª­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|uklndomiqxoyjia]gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÄÄù¸Ã›aIDGKD=[ebahc`[c_WQNOOU´º¬®¥¤£§¤  ¥™ª´±¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿ”“‰‰~†ˆŒ–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyz{wnkihvZgsxszgg^d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÊÆÄÄÄÂÄÁ­ƒOFME;M[_eke_[`YXRMT¢ª¹µ²¬©£¡­ª¬§­Ÿ¬´´¿Ã¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyvvefjjh^kpnyxcba`^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÎÏÌÃÇÆÈÉÈÈÉÇÅÉÇÈÇÂƖjXG??G^cbj`ZXWSUv™¶¾»¼º¼¬­¦©»º¹·¿³µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«¬±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqocahvhjjunyl^d[V`YLHD6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÌÐÍÇÌÉÂÂÇÂËËÈÇÌÉÎÅÆƽ©rPK0XSUfaSNOp©ÈÈÂÄÆÀ¼¾´±°°Á¾¾ÁÆÀ¾·¶Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­¯µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—Ž‹”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r}xpg`kjwmifvotc]cUWUSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<9>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÄÇÈÆÒÉÁÃÿ¿¾ÄËÈÊËɼ¼ÈÇÉÍÈÃÈÉÉÅÅÂÃÂÁ¼‘?Ov~‰VLo¤ËÔŶ¿¿À¿º»½µ³³À¿¹¿Â¹Á·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzy€spfegdlebknoo_Y]WVNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾƹ»Ãº¸¹¼¾ÁÇÁÆ»¹ÈÈÃÅÄÀÃÁÁÀÄÁ½¼Å§wkƒ˜o©ÈÈÇÑÁ¯½½¸¹»»¾·´±º¿´¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}zƒxnfaebacddjcgd[ZZ]YQOE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶·´´µ¿»½¿¹¾ºº´À¸µ·²®º»·À·¼ÊÏÀº¿À¼»Å½ºÀÄ¿½¾¯se}‘‹‰ÑÅ¿¿É¿°Á¿º·»¾¹µ¸´¸¼µ½¸µ´¯³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|yˆ}qdacchkggjfj^VVTYOSLF8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“““˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´´±°µ·µ»Á¸¾¹¿¼¼·´·¯®·µ¹¿»Á֍·¿»ÃµºÇ¶µ¸º¼¸¹¶ª£˜ŽƒÉ¿¿»Á¾¹Æ½Â¿¼Å¸··´¸¶¶¼»¹¶´·ºµ³¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒyqmeegojelhYYOKKKRJLHD9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’™”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿¾¼²­¯¬±°·¼·»½ÁĹ··¶µ¹¹º»¿¼ÏÄw§Ì½Ç·¹·­¶´·¹³µ±¼ÉÕKzʾ¿¾½¼¿ÈÃÅžǸ¶³µ½¸¸¸¾»º¹¼»º´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~†|knqgqktfcn`\UHKJDJCCG?:;8><7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘Ž˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼»À·ª­¤®°¸»²½¾»Ä¶µ¸µ·¿¾Ä¼ÂÄÖ¯tºÈÏÂÀ¸®´´»½·¹±½ÃʏCtÍÿ¾½¼ÇÌÇÇÄǼ´ÀÁÀ½»¼ÀúÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†qfljouoxdhc\cQKUHEECGC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?>??FD@A?>:7?@CC?@=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼ªª£°¹½¼²¼¾¼Å¸±¸¹¼ÆÉÊÂÆÉҚqr«ÒÑÌÊĵº¿ÄȾ¾´¿ÀÀyRmËƾÁ¼¿ÃÌÊÇÅÆÁ¹ÂºÅ¿À¿ÂȽÇÇÆżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtpmmtlmo`c_bbNIM?E@?DC;;::;:8;<:9<>::>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´»ÄÐú¾¼Ä¾·¼À¿ÉÏÇÈÊʇrs£ËÌËÍÊÆÂÃËÎÁ¼¸½º±pcb»ÈÄÀÀ¿ÄÀÊÉÃÃÃû·´Á¹À½ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢¦¡Ÿ›‚{zˆ{mmx|`qd\_`_TI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA??ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸´¼·»»«Úþ¶¾À¾¾º¦œ©²¶Ã¿¥zvxšÄÇËÈÁÃÀÀÉÊÁ¿»¹±¡}sj­ÈÅÄ¿ÀÁ¿ËÇÃÀÈÀ½¬«À³»»Á¾ÀÊÎÊĽµ¼»¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}znsythp^\_]ZRFEDMIAD=H;;59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘—žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯··²µ³·¹¼»¶»»Ä¹m¬Î½¶¹À¼«~nhnlr•˜sw|—½¿ÆÀ¹À¼¾ÅĽ½¸±°™~€›ÊÂü½¿¿Ãþ¿È½¿¥•Ã´¶µ½¾¾ÎÌ̸²¸¸·½¹»±¶²ÈÀ»¶´±°·¬³©°­­´·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|wmu{qoj\`aZTQAFIGK@ECI<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿ››œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹ÀÍ´v€³½¶µÂ¥‡iZ]`MR[Znsw€Ÿ¸¸Âº³»·»½¿º»»®¤›™ˆ‘~ÀÄþ¼¿»»¸¶Á¶ §¶ª°¾ÂºÒÉÈñ°´´µ¼¹¾ºº»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶¼´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰{‚zsvwxnra_g][UJ=??GG=GCC9:5;99><<9:<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Âɨ„x‰ ¯µžkefVX_IIMPSlw…¥°·¾¹²µ²»¹¼¶¹¾´•œ§–¡p®ÉÄÀ½¿¹³®²½»®¿Ÿrz£“œŸ¥Ã¿½¬ª¯­²º·º¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtwrm`db\^OIB?=IDFMD@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·¿Å«ˆ|vŒ ™`TCWVHakVOFI` «¯¶ºµ´²¬¼¹¸µ¸Á½‹™²£¦r¥Ë¿¹ºµ®¥¬³°¦´¡y„§—‘ŽŽ™°´¥¨©®Áµ³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´¶¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wp|ovsod^hY]^SONB?JCAKJ@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜š‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³²­¶º¯­¼³¸¸¿µ‘‚xˆoNJ?cZANw€”kMA\°µ³µ²´¯¬»º¸¶¹¿Æv„ªŸ›e§¿¸µ²±­­Ÿ¤§§§ªºÅËÓÀ¤”—‚ƒ  ¤¥¼Ä¬®§°«¯±±­±®®¯¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvtmvjl]\kU^\PNHDGMBGNG8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹º¶¹»µµ³·¶•Œˆ„{XFAN†ZJJXv€c@R¢¹³´²°±­°¹¸¶»·º½¢²¬¤s«°©«­«£¨ ž˜˜ÎæááßÕƧ‘‰ymq—¡©Á¦¨¨¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬ª¯£¤£¡© ›“Ž”’’™–š¤¥ Ÿž§˜•’”™ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±¬ª©®¯°­¥¦ª¤¨³®­«¨¦¦©«¦ª§«²¬¯³±«©–wryiutoeUbdX]ROMI@IRDNC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯±»ª™™•iN@RxqPIIKg›YEQ­»±¬³¯®¬­¶¶²´µ®©¦Ÿš›Ÿ¦¨ž ¨©Ÿ¡§–›–•›ÛÏÆÆÌÏÌ¿›}lje{¥Æª—¢¢ŸŸ¥ ¤¬¥¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›ª¨««Ÿ¦¢›£œ•Œ“—•–˜Ÿžžš™¦—“’–¢ ¥¢¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ª©¤©«¦©¬«¦¡ˆyƒ|vzcxmn\QiUPOGPMMCPR@>;>4::5;:=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢ª¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¤¬¨¼Â«¤¾iERœ‚QWII_KSŽ`cb€®µª²´®ª«¯°²³­¥‘—“˜ Ÿ¢ œ£¤Ÿ¨“™”“®œcr´ÆÇÇ«|iinf”µ‹›žŸ¡œ¡Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£žžžš—š«¦ª±£¥¨ž œ–“’‘™–•˜—Ÿ˜›š›¤™—”•š §¨¥ £¢¡£Ÿœ ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’~}€uv}nl{dhVSdNJHGOSNKNH<E@=2@859;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜——–¡¨¬®¶¶º¹º··»®¨ ¡©¡ªÆ¿Ê¡PAržxOnKKbeus_Z^p±¯®³µª¦¬¬£›™”‘•—˜˜œŸ¢¢œ¤žš¤–––—¡K-HZˆ³ÂÁ«€qƒ‰ƒx}”¢žŸ¦žŸ£¦¨ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¡¥¢›™ž¯¨®²«¦«ª ›˜˜˜•“–š“•–š–›—˜˜¡žœœ—›¡›žš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡Ÿ ¥¢¦ ‰|€~wy|eyyabSVaIIKLSUJSQM9>A67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—“’œž¤¨®­¬««¯ª¯©ž—ž¥£ÇǏWSId£\e~or]Pkc[d_]k´°°¸¬¦¡œš”˜š™Ž‘•‘ŒŽ“™¢œ—¢˜™•œ„Rki`”¯®žƒž£šªª¥¡°£š£¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««¨¬¬§¡ £±®²±´ª²¯£™œž¡˜››š˜™›•–›–™œ¥¡ š£¡š™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨¢§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ ž ž ¥¡žž¥ ¦™{|vvsi‚me\S[ZMRKOOVMTMB7>C78=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’‘œ˜¡ª¢§ ž§¡¥Ÿœ’›¢šž«¤zUhruuqbvvXWc`cgYXWe¬®¬¯§Ÿž¢¡—‘”œ œ™˜’“Ÿœ¡£šžš–ž™–˜|k¢‹^p™˜‹ž£¥§§·µ°¦³¬¡­­£¯¥¤¦¡©¨®µ³²½¶¾°¬±®­©ª´±°¨«¨³µ¸³¸­²´¤ ¥ ¬¡¡¢¡ š™–– œ›˜¥¡ ž£¡ Ÿ›œ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§ƒ|xvjwv^m[RaIRVHFVWKCMH=KI8F<77;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©¨®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“Ÿ™¨®Ÿ§žœ¡žš™’˜ž›¢¡ ¤€n‚p`cXL[SZMLPXRHMMG—¬ª©¥ Ÿš‘’”˜˜––•Œˆ‹Ž•œœž–˜¥Ÿ‘€³Êʓbƒ…†ˆ• £¡®¼¾¸¬´´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ·»¶«®±¸·¼¯³°µÁ¼·¾³³µ¢¬¢©©²©«¨§¨š™žšª§ ™¨ ŸŸ¨¨¥¥Ÿª¢¢ž›Ÿ¨ ¤§­™ £žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰†…~vrmiwmhn]X[CWNJGMHCFN=>L>4<:6:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©©”’—™”šššœ˜˜™œš˜™ª ±¢·¤°¦Ÿž—˜•™ž›œ£ŸŠbW^e`WMQG>>?CC?>BQx¨­©ª¦ žŸ¡£žŸž›œ”“••žž˜”…™Ÿ™ª¥~°ÔÒ±tas{ƒx–™•¥ÀÀ¾µ¹»Àù½»¬®§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¸Â¾¸´»ÆĽü¸´ª³­ª³´¯³®ª¯£ž¬¨·²­£°¦¡£°±®°¤¥®£¡ š¡¦¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¤ž¦š›¢¤žŸ›››œ‡†|trklurqhW\QFUHDJPI?EB4FH96<>7;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<<;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž  œœ˜šŸ šŸŸ•}`^e`QGD=C?E<?96Nª³§¤£¢ ž¥¬¦Ÿ˜•’šž™•ŒŠ†ˆ†xl†Ÿ¢¡©­}p¤Õ”{‡KZptq‚ƒzx“½È¿ÄÈÍÐÈËò·µ¾²¾Å»¾ÌÍÆÌÌÌÒǾ¿À½ÇǸÄÊÉÄÁÇ¿º´º»µ»·°¶²«»²®»·À»º«¸­«ª¸»µ¼®®¸£¦£ž¦¥¢£©¦™›Ÿ™š§ª§ ¡¡¤˜”£•”™‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ…~zrkdioxkfZ\FLMEDTMEBE7:?;549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<@?AAA>’« §®§¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ²²¸§¡¡«ª¡œž¡¡›š}sjaWNE>IY|pbB=\Ž®¬¡™›œžž™——˜“——”Œ‚ƒ‚vrplo¤«®®Ž…fƒ¨|v_b`dihc[RvÀÊÄÄËÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÑÓÍÓÐÓÓÌÊÁÆÆÆÊÈÏ¿ÉÑÍÇÆÉƽÄÁ¿¿¿µ¾³­¿ÀÃÄÈÅÈį¿¹²¸½ÄÂÁ»¼¼µ®§§®¨ ¢©¥š– š™¨«©£¤¤ž—›‹™‰•˜› Ÿ£—žš““‹•…yusebgrog_ZZDOMCFQIDCA55589B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>9;AA;;>786:;>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›¢¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¤¨¬­ª £ž›–kf]TID@?K…ž¥š„ ²­£žœŸš˜—”“”—‘ˆ„„‰‡ƒ€€yqqnjv¢¶²—t}|zz~y{’„e\PliZ<nÎÏÐÄÍÔÕØÑ×ÍÆÇÉÌÃÅÊÏÊÒ×Ò×ÒÕÖÓÔÈÌÇÌÍÊÓÍÎÓÍÆÉÊËÂÇÌÇÉÉƿó³ÈÅËËÌÏÇÊ¿¾¿½ÁÇÅÌÌÉÉÀÃÀ®°³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›–Œ†‘‹€{ruvgcgwjeWXRDNG@IQC>B=:22A<E<78<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<969:>=<<@?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­³·¬®£ž£¢¡cSLJDC?BR­Ñ½²¯¦œœœ ¤¡š””•”Š}yqlebhrpr{…Š€upmprm„¤™†e|xw—œihfd¨¥u?¤ØÏÑÂÏÓÖØÕÕÒËÉÎÐËÆÍÒÊÒÕ×ÙÖØÓÖØÍÒÊÎÑÌÏÑÍÓÐÀÉÈËÄÌÍÌÏÏÆÇȶÀËÀÒÍÌÐÇÊÉÀÄÃÈÏÍÐÑÏÍÊÈ͸·»¨Ÿ¥«§ž˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„}xsvpcaesc]R\JKGAFIJ?;A8>5586;86:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÁűµ¨¡¥¥ ¢£[I@ADAFPu±¯¦š”—Ÿœš  ž›š•‰wida_``_^__]alusponkpnr„†^_^YWqƒ}|\SqUŠ·‰cÏÕÒÐÌÐÍÓ×ÖÓÕÐÏÒÓÑÉÓÑÈÐ××ØÒØÒ×ÙÔÖÌÏÏÉÍÒÌÏÑÀÇÄÉÇÏÎÒÑÒÈÌÍÀËÍÆÔÏÍÏÈÅËÇÇÉÌËÔÔÑÕÏÒÌÓ¹ű¥¨µ®¨›¨«¥²¨°³¬¬““ŽˆŠŽƒ‹„Ž™“™‚…Œ|zqstmacim_VQ`JJCFCSN?<>43:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B<:<74:><?@=FAD=‚¤œ ¥ž¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯­ªª«¥®·¨«·×ÔÕÙÙÑÎп¼Ìɶ¾®§ª¨¡£¬gC8=>DX‚ª¨Ÿ—•—™šœŸ˜›“}qecb__a_^a`^a`_`emppmjmost†~OORJQo{l~lSrZ’¬‚‘ÐÕÔÐÉÏÌÒÖÒÑÖÍÏÕÕÑÅÑÓÊÐÔÕÖÎÓÑØ×××ÌÈÎÄÊÏÍÊÍÀÊÁÉÊÎÏÐÌÐÎÎÌÏÐÈÌÑÑËÎËÃÊÈÊÍËÌÒÓÎÔÒÑÐÐʽȹ°®»¹µ«¶°­¨¸­³¿»±šŽ ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…‰zvopokadnpaX\[IFFEMYE;@=33<<87865;>@=9<<8<>9<@;@:=8?98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§  £§š›Ÿœ—žž¡ššœš¦›Ÿ¤§Ÿ¸¶µµ¬¤¬®¾´°ÀØÒ×ÚÜÖÎÍÊÃÒÏÁÁ±©¬­©¤²|HFB;V¡›•“–›žžžœ“–—”ˆk^^^adb``aa```^__^\bmrnmqqrrvqTONM\aufz…vYgƒŒtžÌÒÑÍÆÎÌÍÔËÎÒÌÊÖÖÐÌÐÓËÌÐÒÓÊÎÑÕÒÕÖÊÀÊÂÆÍÃÉÊÃÍÄÆÉËËÏËÎÍÑÎÔÌÇÉÐÍÉÇËÆÇÂÆÊÌÎÑÑÇÐÏÍÍÌÐÅÇÁ¸¹½Ã½ù²²¾°»Ãõª˜¥¡˜–‘••’‹”š‘””•‚‰†yqrkmh``qhYXhVMGMIQQB;D?;68:8:;57==A;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÄÂÁ¿»µ²±Ç¸ÊÕÖÙÚÛØÌÌÏÈÖÕĵ¯´¨ ­—xloovšŒ—•“‘‘•–•‹{ebbb`]^acb`__`aa`_][]gqqopqmimrq]JCMN][`qbH]ogV‘ÆÍÍÆÄÆÍÊÑÇÊÍÍÅÐÒÏÍÌÔÊÇÊÎÏÇÆÎÒËÐÏźĿÆʽÃÇÉÎÅÃÈÀÇÎÈÄÍËÍÐÉÅÅÐÉÆÂÆÉÅ¿ÁÈÍÌÌÏÃÊÌÉÇÌÐÄÅÈ»ÇÃÉÉÂÏÀ½¼¿°ÁÉƹ½ª°²§¥¢œ˜›£™—™‘•˜‰‚xoudk`^fqa[W`GIHGIMUG?J=64355==48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ¼¹ÌÌÆÐÕÕØÚÛØÐÉÏÏÑÓÈ·»»­¤¶~g‚†¡©“–…ƒƒƒ}„„s_[^]^`^`cdc_]\^_``_[Z\akrpmmhgiiwƒ`FDHGB?MLQTg^N—½ÇÄÀ¿ÂÇÉÈÈÉÇ¿ÄËÅÇÊÌÉÄÁÊÉÁÁËÏÄËÈ¿¹Á¼ÆȾÀÆÏËÄÀûÊÇÈ»ÉÆÅÊÁ¾ÂËÆÅľƾ½ÁÄÆÌÆż¿ÊÃÅÇÒÅÁÉÀÊÊÇÈÆÐÃÃÆîÄËÇÃÊ·¿¼º³©¬¤¥˜Ÿ˜¬£¡¦›£ ›•|wsufj[anmZ\XRDLGCGDLDFS?54335@=3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¾¸¼ÊÏÑÌÇÂÃÆÍÎÎÌÕÏÕÙØÙÏËÒÍÍÎÈÁµÃ¾²°¶m^z{‘Š’–†z€„…uxurp_Z[\``bcdded`[\^]^]_[YZ\anqmifgkhl~q[MIG8F?CSJTdX”¯¿¸¸»¹·ÀÁÁý½¸¼¾¸ÃÉÄÆÁ¼Æ¿·ºÃÈ¿ÁÉ»¶»»Åÿ¼ÂÎÃƾ¾µÁ¾Ä»½Ç¼Ãºµ½ÆÄÂ÷À¶¶¿¿¼ÍĽ¶ºÈ»¿¾ÌÄÂÆÃÆÉÇÉÆÐÆÂÌDzÇÉÃÎÌÀÅ¿¼²·°²§¨¨¹°¥­°ª­¬”zwxkeh`hodV^YJFJFHKAEBFJ@9:658853;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µ«·´²¡žŸ—š”–šŸ¦¢ž·ÅÂÄÈÎÒÊÊÊÇÍÍÎÑÈÐÆÕÔÕ×ÍÊÏÅÉÅÇÁºÅ½¬®§`cw€’‹ˆ‹„x††}ƒ{ttc\\]^_`bcbbdeb]\[\^\^]Z[\]grokdciiktmXKCNW9:MFH[T•¢³°³²²²²º´»°¶¯³®±ºÁ»ÀÄ»¿º´±º¾À¸Ç¸´¼¶Á½¸½ÆÁûµ¯³µ»¿´Å¸»µ¬¹½¾À½±»¶°·º³Æ½·¯¼¿µ·µÅ½¾ÃÅÀÄÆÆÇÌÅ¿ÅÆ»ÇË¿ÏÉÇÃÅÁ÷ý½¶¹¾Ç¿¬µ»µ·¶Žytxggebkn^V^`FKHHJGBDADF?=:566633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÍÈÅÈÍÌÐËÍÈÉÈÊÉÊÄÐÍÒÏÍÅÇÁÅÁ¿º¸É·«°š[goˆŽ…ˆ‰zx~…†vw|sh]]]]^`_`da^cec_^\[^\]^Z[[]_kolfcfhhjw{_OQYE98FIDJaŸ—¤§®ª¨ª§²¬´¯±§­¦«²»¹µÂ¹¹¹¯ª´¹»³Áº¯À±½¼»µ»Ç¹Ã·­ª¨°²À¶¸½°±¨²³µ»¼«®¶§®¶®¼²°ª¸°®»®»¸»ÀÁ¾ºÃ¿ÆÃÅÀ¼ÆÁÇʸÅÇÅ¿ÇùÄÆ»ÆÉÌ˳¹Â½»³‰tvwki`bliYWW[ALLMJEAC?FA:::996854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÅÍÒËÃÅÁÄÏÆÍÁÂÆ¿ÄÄÃÃÊÂÉÊ¿À¼Âº³µµÃ¯ª±“[i~’ˆŽ{x}‰…y{„€wn^]\\]_`__dcbdcb`_]Z[ZZ]ZZZZ\cmmfdddfgjzlOZ[D@;6:=MŠš‘”Ÿ¤ª¡¦¡©¨«©¯¢¥ž©¬´µ°¼¸¯¶®§­·´³»·³¼¯¸¹µ²»Á²À¯¥©£«±³³¨½ª«¨«¬®µ´¦¨®¡¥°©³§§¨®¦¨·¬±³·ºº»²¼¾¾¾Ä¿µÁÀÇÈ·¾¿Å·Åÿ»¿Ä¾ÄÈÌÊ¿¿ÄÀÀ©‡stsji\aodWVXPHZSSKFFE>?@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÐÏÌÃǹ¹ËÁ˾»É¶½Ã¾ºÊ¸Áõ¶¼¶±¯µ¼®¨«“cmˆƒ‡‹€z}~xt~|swe_]\\^_`^_ccab`a_]]\ZXY[[XWY\_ejdbcaddhmw]LJVVQQ>Bz‘Ž‡™œ¥  ž££¥¥¬ž›š£¤«±®¶¶¦¯«¦©³«³¹°µµ­¶¹²°ºº±¶¥ ¥ ¦±¨¬©¹ª¥§§¨§³­ §¦Ÿœ¤¥¬ŸŸ§¤¡¡±­­¬²µ³³°µ¼¶»ÁÀ²º¾ÃÁ±¹¹Â³À½Àµ¸»½¾¼ÂÇÄÃÄ¿¿Ä „xqlbf`ko`UY_HNhOTHFKF<=@=:;;826536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;>97776788666;::;9:;<859<:>>@;Èµ¶½¸ºÁº½¶ ž• ¦º¶«³³»³ÄÏÉËŸ·ÇÀÌ¿¸Ê·»Å¸³Å¸³¿À¬¶¼²¬¦¯´­¡£’ir†…†€|xusomjiipi_`]\\\^__acb````^\[\\XYXXXVXZ]^cb`cccbefkrWP`gojZ|–Œ‹‚–šœ¢šœ¡£¡¥œ™¡š©®¬°´¢¨¨©««¤´¸¬¶¯¬²´®³µ¯°ªŸžŸ¤¢²¤¦ª¸­¢¦¦Ÿ¨­ª™ŸŸž™Ÿ¥š™£œœž°©¬¨ª«¬­°²¸¯¸¹»°¶¼»º«³²¹³½´·²±µµ¿µ½À½Ã»»½—„{sl_e^ddXTW^IW]KPGJJGA<??A;?<05635:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»¸ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÅÏÈÈÀÆ»»ÃÃϾ¹È¸¸¿·²Â´±»»¬ºº±¢Ÿ©«§˜žm~…†xrmomkb^bff]]^]]]\]_`abccba_\[[ZZYXWWWWWXWZ]abccbbcddolet|oJO‚”ŠŒ…“š›£›—™¢¤ ¢šŸ™—¬«¬­° ¤¡¬ª¦¡´¯°±¬¨¯²§º³¦µ ¢Ÿœ£¢­£¢ª¶ª¢£¦ž¦¦£–˜—™š š—œœ­¡¬¨£¤¦­«²³ªµ°²«²¹µ¯ª¯²²³·³®©­®±·±º¶º½¿·³±”†zvf_f_[YVSZUK[QLJEHKIC=?BB@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½¸½¿¶¾¼¿²¥£˜¥±Ãµ¶½­´¸ÂÌÈƿŶÁÀÇηÀý³¹¹²À¶±¹»­²µ¯Ÿš¤ª ”›xƒ„xoqtqhedhdc\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXWUW`bcaab``dfqqvy`>L`r‰ŽˆŽ˜—›™’¦¡œ¦›š˜©¤­®©š¡¢¶¨ Ÿ­¨µ©¦§­°¤·°£· £œ™™ª¦¡š­¹¯£¡¤œ¢ Ÿ“•¡”––›™˜–—œ•Ÿ©žª¤¢£ªª°­¨´¬ª¦­²°¥«­³±°°¯¯§¨§²­±´°¼´º·®£”‚zwe_aWYXSRTKM^LPLGHMLE=@>=B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾·½­§§¢ª»À½À¹®´¸ÁÌÈÅÂýŸÈ̲ÁÂÁ®¼»µ»¼µ¹¹°°±ªœš¡ª•‘Š‹€€|wqilrtphhedfa\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWVUZbb``a__`bgpotR1,)?xŽŽ‰Œ”˜–š‘››¤¢ ¤¤›¤©­¤ž ¡µ¦  ¢§²¡¥§¥¯¥±®«µž ••©¡¢”­±±Ÿ¢£žž˜›“‹ “‘“˜˜’–˜˜—ž§›§¢¢š¤¥¥«¤¥°§¥¢«¬­¦©®¯¯«¨ªª³¦¦«¯´±®¼¶±°¯Ÿ’{xseb\[]XNLQHRaMVPOJNOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8847763321./2556;:8;7876<;:;;A8x»»±µ½°¼±·¬ž¥¦¬¸»¼Áź²¹µÄÉÉÀÂÆÅǶÆijÁ¿Å«··½¶½º»µ²¬­¨™™ ¤ŒŠt‰ˆ~vncafihfgifil`]\[ZZZZ\]\[\^_\ZY[YYZ[WUXWTTVVRTRT__]^_\]]`ahonI+)Eo“‡ŠŽ›“›’—›¡ž©¢¡¢¡¡ š§©¢˜œ¢°©  œ¤©§¢ž¬¬ª©­­¢¡¡•˜¢šœ«¨°œŸ¢ŸŸ—™“Š‘’“–˜˜“œ¡£œ¥¡¢• ¢¤¥›£«¥¢¤ª¤ª­¥­²©¦¥¦¦µ¦©¨­³µ´¹º¯«¬žŒsqpa[WVVRGQOHZ\ORJTKSLEGJC8;;=<9667:9;:976977:;:=<<6;<8>598:88659:;<97?<9678452121..1426:8698598989;9@9{µ´¬´»²°«±­¨§¯¹¹³ÀȺµÀ¯ÅÈ̺ÁÉÌȵɽ±¾ÃÉ­±¸Áµ¼À¼´µª¬¦–šœœ‰rˆƒ{tiijlgjlmkjle]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURRNPX\Z[\\\]\_bkjJ;/=I\‡Ž…‰‰“”œ––›¤¤¦¤©¤§¤¡–£«¢“—£­§Ÿ›˜šŸž®™œª³Ÿ¥¦Ÿ££¡””›––’©©­šœŸ¡ ›”Œ™‹‘’–•¡ £œ£•›¡£¡˜¢¨£¢¨« «¯¤®¸¥£¤¢¬­ª¨«¯´·²½µ³«®˜…uti\YYSURFXLQ[XMUOPLQRIOIB=??A?=75799<<977:79:;<=>;7;;:=68:;8976989:6:=99577571141-+/434988::8::748=8?9~³­§³¶®¨¨¯®›©¨¬·¶¬¼Ê»¶¿¬ÌÆŸÀÎÏdzĻ·»Âȱ­¸¿·¼¾»³¶¦© –˜™—ˆzt€vwnmhmmmpggifd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUSSNPPXYYY\[Z[]^cplMBOtlk„€‹‡‘š™•š¦¤¢ª¨¥­¢¥–œ©““¢§¥œ—Ž™­–˜§ª˜Ÿ”¥ ž’‘’‘“•¨ª¥š˜™žž–ŽŒ‹“…ˆƒ‹‘•‘ ž¡¤™–Ÿ•š¡¢ž”›¥¥¨¨¨ °°§±½§Ÿ£¬´ª®§¯´°¹µÀ±®°«‘stbWTUNRJGVPRRLLXNKLOSGNKACFDC>B75889;9:7::7<=:;@>:9;9:?759:9876958779;85576661320-*.102877;99;8948;8@8´¬¦±·ª¥¢±«ª§©²°¤¶Æ´¹º³ÊŹºÁËÐʱ¶¸¼½Àñ°±·®´´»³´££˜—•„€vkglnqnqjokdege^ZYZYZZZZZZZ\\]\ZXXXYYWXWUUTRSUSVTQMNMRWXYXXWZ[[`ijflduva{|‹Œ‹”’—£–›¦£¢¨›¤•¢˜Œ¡™––…„‘š£•£œ•–•‡¢š›“ŒŽŠš¥§›••—œ‘“ˆ”Ž‹‹€‹’’’¡š ¢–”™˜•¢¦š™¥§¨§¡ ´²¨³¸¡£¶¬ª­¤²²¦µ»´«¬±¢Šztn^NQQMODNNNPKFNNJJNNQHMJAHLIHC>958889:;69:68;99><8:>9;?8789:885857688974577820301+)-/12876:999984988A7w¶§¤¶°¤§¤ª¥ ©¦¤³ª¢²Äµµ²³ÆÅ·ºÃÊÌƳ¬º½´¸À¯­©°ž¦®»¯­ š›ž••ˆ|„n__frpuqinieghj_XXXXXYYYZZY[[\\YXXWYYXUVRRRPQTQSUQNMKKSWWVWWWWZ\aeZ`[nxevr…z…Œ‰Œ—›Š•— ž —£“ž™“‹…—™‹sŒ‚}—•…’™“Ž{™œŒ‚‰€Š˜ £ž“˜–…Ž‚”~~sŠŽz‡“›šš’–žŽ££Ž‰š ¡£¤›¢´¯¬¯­ ˜¦¸¦¥°¡±®œ±¼ª©¯©™„xtdVMRPPMCSNLPMBPQHINSNIJJEKMGKK>849888;;69;7:<9::;79?9>@79:<89764445874312485/0102)(,-02764789::65:87A7x·¡£´¨¦¥¨£¦¥¦¦¦²§¦´Á¸¯´°Éĸ¹ÀÎƾ³­»Á¬­Ä­¨¡¦’¦·­£ ‘–—’~xfWV_gfighnciigb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTQMMJGNSSSTTSUXZ\hXZXiqkfFPi‰zŽ…–‘†ŽŒ›•š••”‘Œ”ˆ~’ˆ^;Vn{‹“‰€Œ‘Œ††r‹„–y{†”•ƒ–Žƒ†}“xqo†~‰Ž—š™“‹ŠˆŸ˜ˆˆ–žš¡ —§®©­©¨ž–­³¢¥­™­«˜¨´£©­¢“tn`[NSRWLDTJPLLFNOIELQMKPJINPGJJ=7599999:7:;:>>8:==7:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9y· ¢­¡¦¦ª §©§£ª°¨§´Â¹°µ°Ç¸³½Ï¿¹¯®µÂ§ªÄª¢˜ƒ”œ±£š™‡”‹‡~sv]PLQUYZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MNQMKHFHNQQLORTUWY``USdlcF98zŽŠˆv‡…ˆ—Š”•‰‘…ƒ’„w‡~_IPmwŠ‘ƒ}„ŒŠ„m~“wuvx„špQˆŠ†|~y”vgw†ˆ~Šˆ•‹Ž‘“—Œ„Šˆ•„›‚„’›–ž”¤£¨©¥¤ž›°ª¡¤¤‘¦ª–¢ªœ¡¦§Šwnf^\HQQSMIUMSILKOIHFJNMMUKQRPGJD=769:8:;;8:;8>?99>=8;<6;;478;6775344696/3/.115221/,')+*,4833989:99::::?9w¶›¢§Ÿ¡®¡§¨¥§§¯¬ªµ¼¶¸·³Á»¶§¹È¸¶¨¨µ¶ª²¼§ž•Ž‰”©–•‹Ž„ƒ~xqoXMKMNOLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDCINOhYNQSSUZf]VaiZZQKˆ}€lw{w€‡~™‹Žyƒ}s~wqmtpt€z~‰ª„z{hv{Žprmx‹’x{€{€wsr’xhu…„„…|•‹ˆŠ‹€„‹€”„|€˜”œ–‘Ÿ©ž ¡ ©¥Ÿ˜§¤’  –žž¤‚sib]]JWPRHKXROJMLRJJJLPILQMRUNFIB=78;99>=:;<98@?::><7==79937785675251472/2.,./200/-+(().12721987:8775:<;7v®™£¡˜œŸ´©¯ª¥­«°±ª½´²»¸¶º´±Ÿ·º²ª¬©¨²¯¢š‘”ŽœŽ‘w†x|vpojYKHIHGEHHPTTTWWSUUUUVWXWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LNQQSV^ba`cVhŽ’‰‹t`rzpsz„Œy˜’~o„zuynj}­|tŠ~z†’€|tfu|†lohs|Š‡€mzq}qmvqhq~ŽpD‹…‚ƒ…wxzŒ†}Œ{u}Ž’˜‹’››£–™›ž¡œ–‹¥›Ž—Ž–˜yongc[XXUQJSUTOPNPVKNKOOJQOIOPLFD=;79;::?=9<:99??;8;=7<9999266856633611224.,,-..-0-+*''*.1362/876966527995y¦— ž– ¦°¬®«§©°¯±«»¸«º¾¸³¬§›°§¬›–œ¥©¤¡˜šŽ„’y‰‹‹vq|muqjmjXKFGEA@CDHLLMQQOQSTTTUVVWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zYJNOQTX\^`\Yy™œ¼{mp\tqivsƒŒvy‰ƒmj‰wrwhiq–‘Š€}•I’™ngw~‚mjdly…’†ksl|nr|†imps‰…†{}~{wput†‚yyp|ŽŒŠ“ƒ––˜š“––™––Œƒ‰Ÿ’‹’†–€ojoooYVXTRRYORUTRXUMOHMKMOKCINGF@:99;99:><9<;::=>:8:<9?868727565541432/024*+**-.+-*(*(',-1250,5567485HA895w™‘›˜šŸ¤¬¯¢­ª¨µ¯®¬³¿«¼Â¿¦¢š•¤˜ž„‹”¡¢˜™‘“‹sŽz€†Œ†uotlqmekkYNDFC@<>>BFFGKKKLORRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_JMNORVZQWUS›{X`jp^wjhyu†…r~„qj–rqziiœŽLy„‘ˆ„f1v‡rk}}ƒtfeu~„„…€filukp€|hqq|n“{t}}qqovmƒwyujyˆ‚ˆ‰ƒ–’’‹‘””Ž—€yˆ—ˆ‡Š†€ˆxlkpheXR[XYY[NPUVYXNIHEJJHGB@GECG=998;9:9<:9;:::@<9:<98>787715234533645031.**+),,++)(+'),,226,,4775478iO8;5m’ˆš™–¤¨­ž±ž§º¯«²°Â±»Ãǚ–Ž•™‹Ž…z„˜•Œ‡q‡‚t‡Œ†zpsqopdpg_TFIC?<;9:?@ADCEGIKOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOOQUKAHOG^¦ª˜groevgl}|€}v€‚‚vo’rw~qs’†5qœ§œ ¡„¢…vp†{†|sŒ­‰hfbjnrmpƒuioXupŽ›‘vm{}nrnp€{svnbuƒ†€…ŠŠ‰‘‹‘‹‹ŽƒuxŠŽ€~ƒ€}Ž|trqm`\]^\ZYa_RN[ZXWLHIFIH?CABH?CD=;:7=;:;;9:99;:?<88=:8;66650121253474531./,,+)*))***)(*)+/3DM2166643<vR7=7b‘“‡•‘¤§ž¯•¥´©®°®Á²»ÁŖŒ”€ˆ|n’‰ƒŠ‡…uƒƒl•ˆˆ|uxxmxnwdj^IPG>?7448;:;=>@BEHKLLLNPQRTUVWXZXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMMPL7CMPQBF|jurrnwgp‚wy€{ˆ{sž—x|„~ƒ˜ƒšœ`…©žœ‹ƒŽzv‡~‰ˆŽsŠ—„{\dqtz|wŠmhjbyo…‚zoxu…zptzxkni]v†}‡|‡†ŽŠ’—ƒ…Œ†}q„„}vw{|‰xqtugh`[\^S\g^WPTX[UGJJELG?F@DC?AA=;97<;;=<::99;;=>79>9985654244004645554-,)+('''&(())((+++/00Uq=23331E~W4=9\ŒxŠ“Œ‘œž¦‘ « ±¨¯À²»Åº–Ž‘“‡z†vk‹‘ƒ}ŠƒŽŒxƒ€s „Š}}p~zhwkRXL@E211276688:<>AEFFGIKMOQRSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFIKMNQKJSZVOG`xr€rtkv‰†ux„ƒz’ƒu–†„Œ“¤Œ¬©H†¬¯®Š€”ŠŠ…’©‡˜˜Šœtm|†‡~Žhghyn…‡‚…q„†Gm€wryvhmk_v}‚ˆ‡„‹y”œ›‰Šˆ‘zuŠv|xmow~uusm\^^\cdXgf\UPPWYPDLKFOICFCCA?CA=978:::;;:888::?>6;>7585773344236656778;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|}‰…‡Ž•—’– ¬ ¦¸¯³¼³—’‹˜‹}tp~‰’~}Œƒ’”}†~†¤‡ˆ‚ˆ…x‡‰~s„x_cWKB60./23124668:=>?BEGHJLNQSTUTTVUSQOGC?80,#‡[??84.]–ps£UFIKLMOW_VkWYZb‰|‹y|z‹Œz„Œ}–‘ž•’™™¤¬’™»±¦ºÇ狌¡¥Ž“‰‘|qƒžŸ‘w……Š‡ihp„tŒ†„Šr†‚w‡€{v„|mvuf”Ž†ˆˆ†‡‡ ª¢–ˆŽ—zˆzyogkx~|€ulf^Z[^j^ag`ZOLNWRQHPJDNGCJDCADCB<:87=<:<:88778:==8<=68656623444576867<BB?<8:>CQ^e\G2'&,,--.1(?‹[.310Oƒ_4?;nuofw‚zŒŽŠšš¤œ¡¬¦ª®°—‘‘„¡”„xwŒ”|’†’•Š€’›Ž„€ŒŠ‚‰ƒŠlpj]BA4.-//..02234778;=?BDHINQRTRSSTRPOHEB<87/9C><<63.l“—MPHJLKJNV__zdchmƒŠ‹„‡ˆ”ƒŽ‹™‡œœ §¢¡©’§´¡§Á­ǯx¹”š|¡ž˜„“…‚Ž¡Ÿ”™‘…Š…š‘–lpuŠŒ‚•ŒŽw„qm…Š–‘‚…ˆrˆ •†‘‰–¤´¨›Œ”¢‚‡’ƒ}kjj|‚ƒƒuc^e`[hl]ml_WKHNRPNLLFIPCDNFBCEFC>:96=<:;:987767;:6=:785456344566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYo‚ou†pv‘†~—–š”žžœ§ ©–“˜žge¤š~„’‘y€’ˆ‘’}Š„˜’ƒ€€‹Œ‰†‡„‰†xxgMR>//.,/.-/000212567;?CENORTPPQSQNPIED>;<:DF?><752<?R5HHHLKMNQ^j„xo{v“’žœš“›‘˜š¤š¤§œ¦©§¨³–ª½ªµÇȶÈÐϾ› piª©Ÿ„“’…œ š›™¦‘‘ˆ•£››xz~”˜“¡“——”ž{w•’ª²ˆŒ–ž|“›‘•˜£¡¥µ¯œ‘˜§†–€ˆlss}~sjb^b`bhe`gg\REJKONIILFGMCHMFFCBGEB;85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Ppt`m|awŽ}{“ŽŽŠŸ’—–›ª˜žªBD}‡‰‡˜x‚‹Ž|Š†Ž‚€‰‹Š…’…ƒ†‰€‡v^bP560-1/,.0/./..0015>AAMPRSQRSTRNSLEE@<>=FG@A@8662<9;FHGIIMNPYjŠsƒ—œŸ«µ±ž¨¦¨£¤°¨­³®®ª¸¯±¼›±Ãª¹É˷ÿ·¥¢°³¬¬ª£‹–˜„¥¦ £—¦™¢ª¨¥ˆ…”¤¡¡ª ¤©›°‹•£¦·º› ¢¯’¢œ¡¢¡«®«²´¡”¤©‡™ˆ’‰•yz~†ibi]fc_dd_gg_[OCIHSNFHKFJGFFHAKFDFFB;87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLhbWhoXy„v“…‡‚œƒ‘Œ’Úȝ–sV—ˆˆœ|†ŒŽŠŠz‡‚‡‘Žƒ„‹…†ˆ’†‚…‰‡ˆ‡‡qna@E64<2/110-,+-0.-4?CAMUPRSUUVUM[PGHD<>>FHCDA7;<5C;=FKIFHQNPW~Žš€¦œ¨ ¨¸Á½¥¯Á³©°½°µº³¼²¿´¹¹¢·Ä§µÈǵ½¸´¨£³­°±›™’šŸˆ§¯«¥”vŸ¤—¡¬²´™–ª®¨¯¶º²º¬¯µ¢±«±µ»¶´­´Ÿ¦§¢¦™¨¯¬±¸··§šµ¨‹¤’ž†x‚…x[cfWgcbdaaga[TJDDLTPHIIDIGEA@@KDBMG=867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AFWQJL[YQabWytq”}„†“u…€Œ{¿»£¼‚´”“›„ˆ’‰‰y†€Œ“Œ‡„Ž‰††ˆ†Š‡‘{xn]W@DN<6:45AB7640/6CHCQ[OQUWU\WO_UIKKA?>GKFED;>@7D7?BJJEFVSO^‹ž¨Ÿ¬­¹¬°¹ÆIJ¸Á»±±¾´µ¿²¼®µs¯²¤¹Ä£¯Æ¸°³±³§¤µ¶ª° ¢—›¢’¥°®¦­«§¤˜¡­´»¢¨²ºµ¼¿Ì¿ÅŽ½³Á·º·¾¶º·¸««°¤¯¨¬½¯¼ºÁÁ«˜¹§”­Ž——©ˆ}ƒ~mXecYlfkfW\dYVSIGFLPGCHIAHD>?BBL@?MD99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FRLALQVSYUZvjp~Ž„€Ž…nzsx‡b¹¡™£‰””–’”“—’‡‡{†•Š€„Šz|Š‡†|Š‚‚‹„–}xzueP\dGEL;Qca[^SG?;HPDZcQQYXZgYS`_LSPEA?IJHEEA@C<E6B>HGJLSZT]ª²°¶²Â·´·Åʸ¹¿º¶³¹¹µ¼²¸°Ä_s°¤±šžª¼¨¤¨«ª£¢²µ¡ª¨Ÿ•–ž˜ ®¥§¦¥Ÿ¤”£§±´¨²³½¶Â¾ÓÉÉÓÆÂÅÌÂÊÃÀ½¼¾»»¶´¯¸¶¶Â¹Å½Âǯž¸©¡«¤§µˆtadd_Yc`jgSXaVRUIEEMJA>GD=KA=B@=F>;H@796379>489:57045/26389374426?8@>GKRTSQPOQQPJA9/,,,*+((,-+/P>(.48€}<2Kˆq9>CKE@IMPRKQ]glkp…skrrs‡ÕÀµ™ •˜™‘Ž—‘––Ž†‡}†ƒŒ–Š~ƒ€‚x{‹ƒ‡{‹yŠ‚—~t}zkepuY^\Pedb`ed]\XW\MdmURmm_n_XgdTYUJDBKKIFHHHGBI:D?HKSTU\Z[´»´º±Áº¶µÇÈ·´¸´·¸±µ³²­´µ—ct§œ­o^¢¬›— ¢›¤žª¥”ŸŸ“Ž•˜˜¨ž¦ žš™ƒ¤ž­¥ª°­¸°½¹ÔÑÏ×ÐÊÌÒÌÏÎÊÆ¿¾ÁɼÀ¼ÀÀÄÄÄɾÇͲ£º°´®š«·»˜€|n_b^Z`cZddQ\`SQJCAEFE<@F>AHB?C=:E>=J?47535;=468977022/24169775555D3ELM>51/006:477@IOI;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODQ[Yh_o–’”nkotu‡´¬¡¡Ÿ‹™œ™Œ•‘š’†ŠŠ~ˆ†‹‹ˆ|ƒs{Šƒ…{‰t‚Š†•s{ylmu{hreilifjjh`fiilZms–­¤¼ˆ†g\og]ZZTHKNPJKPKSQILAJFJO_^afi`–´Ã®µ®¸¹²¯Âij®·¯¯ºª±°¥ª¶«‹µ§œš¦šM™ŒŽŸ–‘¦˜¥•Š““‰‰‘‘›¡—›•–‡Ÿš§›¬¯©°¨´´ÔÔÔÖÓÌÐÓÕÍÒÏÌÄÁÉнÉÉÊÉÑÆÌÍÂÏÑ·¯Ã¼Ã¹¤µ¹Á¢„qe^__ZbYZfZQ]XNPABHEBH;AC>AG??A7;C>@H=46655;:687654/10146278875367C5B8?-0-1349=97,.,1;FK=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYReVs˜‚gqoxyƒ¡ªž¦—Œš›—‹•‘šŽ}‰‹…Š‰Š‡|„‚p‡†{‡rƒ’‹Ž}qxulpx~qzmxsmi€pmcjmpxhw|~˾Áߧmcxnc[a`JPRUNY^O]\NPNTPTT\nmv‚q•¬µª±¤­³¨«º¾¯©³¥£·¥ª­ «³¢°­™—˜ŒŽ‘‘„Ž›¦‘œ‰ƒ‹„‹‰„‹„”–˜—“›‘œ—™šŸŸ«¬¥¨¢¬­ÏÒÕÒÎÌÓÔÔÏÔÑÎÇÃÔÑÆÍÒÓÓ×ÌÑÑÄÑÖÅÀÎÇǨ½¶Îž|qh`d_XbS_[PQTQOH>@FABE<@A>DC>??:==<<JA45465<888664412/03526768533;=<E=@11+/249>5901022-2DN3)/3.32=N238C}_2A†tD:==I>@CFH<UQMNZu†…Šwlwp}~¡žž¡ŒŒ˜““‹Œ’•…y…‹‰ˆ†~‚{q~€€‡z„u…“ˆovsls}{w{s‚xrk€sripqzyrz¾Ëš}‹±„vr„vhaj]CZY[VecXcjSX\]`c]cwz}‹—¨££ŸžŸ¦¤©®·©¥²¡¡­ ¢­¡¦±žˆ¦š“’‘‰Žˆ“‰j”¢Œ™„†~‘ƒƒ“—­‹•”™Ž†“‘ž—¨°¢¡¡¥¤©ÉÍÏÈÃÌÑÔÒÔÒÎÓÍÆÖÒÌÔØÖÖØÔ×ÕÉÔÚÍÈ××ÑÊ«ÂÂˍuqebaZVZT]QKGJJJ@;:;DAD<BC>GB>BB:<9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/--;R017/532FD28>nb5=tM99@I<AD?A;OLFJXp€u}hrxr‚‰€•”…‹•‰Ž‰ˆ†Žxƒ“˜ŠŒˆˆ‹ˆ~‚xs{}‚‡wz†‘•€ƒnwpmvvx}t…|zm‡vuo}v„ux{µŒ;AŠÅ¥~Œ|ieWICfcecgjcmw[^fhknhm€‚‡‘ŠœŸœ–—¢£¤°¢£±ž¡¤œŸ¨Ÿ¢±›…‘‘‘ŠŠŠ†ƒƒ~œ›‹‚„…y”‚©•£’Š—’Œ~˜‹›’«³˜›œ¨œ§¾Ãƹ·ÇÎÒÑÒÐÌÒËÈÔÎÐÕÚ××ØÔÙØÍØÛÎÉÙÚÑÕ¾Ê˵zypg_[TWR\XFGKIEE=:7:@@B:GD?DCACB;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?1*(.BS39254/7K75<`bA<svV87AH:?C><9QECJTknnpbpqt†|—‘‹~‡’ƒ‰†„‰‡|x…––ˆŽ‚‡…‡z„yqz{ƒ…uy…Žœy‹o|ppz€q{€qƒ‡nŽzuw||‚u~|†‡¯sX©Â¶‘‚pmb=^hrpqpnxvehoruxqy‹†“‘š•Ÿ”†‹’šŸš¨ž «›¡™˜¤ž«™Š™‹‘„{‡‡ƒ„‹Ÿ™“ˆƒ‡~l™z„˜†ˆ“Œ”Œ†|œ‰”®ª”–˜Ÿ™§¯¶½©®¾ÇÌÉÉÌËÐÉÃÒÊÔ×Ù×Ø×ÕÛ×ÓÙÛÕÐÚÚÑÖÈÔʖ|~kk]\QUTaJCFJH>A>=7:=?;=G<?AAADA>?:87DB755479.556435532323647553458EBDCEB56<FNSM[nfcnskaV>,4LG865434BF4=W_hLux^8;?F<<B<99D>CGRj^mdbfkv€ˆq‘š€z€~‚„~ƒ{|„˜‡‹}…‡€w‚yo{{†ty’žŽ vŽu‚tu~t€„o‚o’„u|…zv†{‰·Å¤Áɹ–šwpeNfczw†¢Šxyv{ƒ{„vm“–“”Ž—‚‰Ž–™–•¤›—ž•’‘–¢™ª•‰Œ‘‚‹ƒˆˆ…‘›™‰…‹…˜zˆ‰Ÿ—ˆŠ‹‚}¡‰‘Œ¼¡˜“˜™©¦¦®Ÿ¨¶¿ÀÁ¹ÈÊÎÎÅÍÉÑÖÕÕÙÕ×ÛÔ×ÙÚÛ×ÛÚÙØÎÛƈ}|jlhbVYWXNLENC;==<8:;=9=@6=??<>==9867CA6455=80665547745613854564557HH=DJE7925;H>;9:7IP][RUXK9T>;95327I8=NYMHxxd5=>C==@:6:>>@EQ_Xea][htzylŠ’wvzŠ{~~€|„z}‘‰„…z„‡{u}tm|}†~s~’ž‘žƒ‘{†~x~yŠŠn‚š€t™†}‰…|~z©ŽÃ¡½Œœ£œ}‰„}‰r‹Š~s¦šœ˜“…{Žˆ„hGq ¤Œ‹‘„ˆŠ’“œ™’“•Œ‹”žœ“Ÿ”Š~ŽŠƒˆ’–šžžˆ‹”‘‘‹¥˜ˆ„‚…„¥†ŠŒ·˜‘•–¢§¡žž¤¯·ºµ¬ÀÆÊÐÈÇÌÏÓÓÒØÓÕ×À×ØÙÛØÚÚÙÙ×Û¸{|{nlhZb]TQOIDLB<<>99::99;<6?=><=99;;37D?7378>70688357<37804976755546FP5DNI8938AK=;3C@I<:DWN<MTHN?96333>C;[X>5YypZ<<A<=>8689?=CQSRX^UXfmmmiŽŠqryŠ{z|{‡z|{‹†‚}tƒ…yrysm€~„~w…›¡›”’Œˆ€˜ˆ€œ’nˆ¨…z¡‹|‘ƒˆ„œ}š‰Œ££ ¤¯ŸŠ‹…‹’†Wr­‹Ÿ«›ƒ˜›Ž\‚¢‘‚ŒŸ“”‹†‡‹’’‹“““Ž‹Ž‰‡•šœŽ”–Š‘“…Š‡‘ŒŠ‰œ–˜¢¢†’• Š‰ˆ›ƒ‡Žƒ‡†¤…Œ‘²˜’”—¡¢Ÿ™’œ¨³¹­¦½ÂÇÍÈÆÏÍÐÌÏ×ÑÑÕ®ÖÕØÚØÚÚ×ÕÙÙ r€wji_`ZUXYC@IC?>>:48:;7:;:3;;?=>7;::1:G=:27=@50677255?65;55858:57735HR7GOK994=EJB>1FCLA98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:;@;BQKKSYPTcbzma~’ƒomw‹xy~z}†{{w†„sp…‚zuvvt„‚„~’¦£Ÿ¥¢–Š•—‹Š§—rŠ²„¨’„™“…™Œ¢•Ÿ—’‰›ž£“ª°Ÿ”Žˆ–Œn·…šÄȲ›¡¥›œ˜–±‘d¤ÍȕŽ†‡ˆ’ŒŒ‘“ˆ„‰ˆ…•™šŽ“’†“–ƒ~‹™‡ª—–¢¢ˆ˜ž–šˆŽ†——‰„ŽŒ‡¤ˆŽ“¨š—“—™¡™Ÿ™“›£³µ¦£¼Â¾ÇÅÅÉÈÉÂËÔÍÍÔ©ÒÑÖÕÖØÚÔÒÚ΅uƒkga``QKV\BBGC;A=837;<:9=649:<:82?992:I:>67BC32:96264>=4;>6949;57944JQ<JQK9A7BGI@64JELF><88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBeƒGu‚Ž||m~ˆxz~zƒ~vv€‚{lnŠ~y|wx|„†‹~‹£´¨¤«³¡–§ ¦¤–•¯¢ƒ¸•‘³šŒ¡ Œ¤›¯£¥˜§—©™®°¤—”•”‹˜š– ÀŽ£É¸«š£¥­™‘›œ²†…¨¢œ—…ˆˆ”‹Š’†€…†ˆ’—“‹Š“’†“—…ƒ›s˜²•–£¡ˆœ™“ŠŠ–šˆŠ–†}Œ˜ŸŠœš™“™˜ ” ”ž›¡±®£¤¸¿´ÄÇĽÃÿÇÎËÉÒ§ÏÌÓÒÐÖØÒÏؼu}z`cWcXRIKOFBCD5>;76:?;<7=42669774=5;5<K<>;<BA75<;5277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=89567=:JFDGM\]YJha;H„‹zzm…†y|„x€…}px|}|orŒy}{x†‹‰†„’¨¼­©³½°¥®³´©£¢°­Ššµž£¹¥•¬¤—©­¸¦¥£Ÿ™©˜ª¤°±ª™˜œ”•‘— —š»»­Ê¡i¶¸ª°•˜ž¢«’—½£^©²‚‰‰Œ”†|Ž|ƒ…““ˆ†’•‹Ž”ŒŠŒ–˜‘›™´–”ª‹›”‘’‹˜š‰‘‹Š–Ÿ¢•˜™’œ˜ž”¡ ”œ¦®§¢¤³¸«ÂÈĵº½¼ÆÈÈÂСÆÉÍÍÄ×ÖÐÊÓ£s}l`]VbTQGD><CAA7?874>F<<6<35355454B39:BM:A;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPgHa`bpJ@‹‰~€r‡‡|‰u‚Šƒm}||~pw‡w‡{Œ†Œš«ÃÀ°½Æ¼³´Á½´­¬³¶Œ¨²­®½«›»£¨­¹¸«§¦¢¡££ª¯²±ªœ£˜›˜—ž¢¦¥’£¹¯¨¿¼¬­²¹¥£§}ˆ†­¼°‚‹‹Šƒƒ‘Žy†Œ›‡‡–ŒŠ”–“™–›§š±™ªœŽš‘Ž••–Ž ˆ”›£¬•–”œž” ž›˜Ÿ ”šŸ¨§¤¢£°³¦ÀÆ𰻶ÅÄþ̧ÇÃÇüÖÐÌÄʊwve_]b^OLCL@EG?A>B<:4>A==5=6>333242A17@BM>G@CNCA=C<;86CC5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GE?CF\iF_ig[]\“ŒŒˆ{‡‹†ƒŒu†Šo~{~q~z”z’”•˜“•¨´ÆÉÀÂÌÂùȽº°«¹»—²¶¹²À®¥À¤«°¼½ª®«££ž§¬¯µ±©› ªœ¢œ–Ÿ°´§Œ£ººµÁ»«¨œ²¤¤¨”„ŽªÄ䂋Ž†‡„†•”ŒyƒŒŽ‘ ‹‹“Ž‡—Ÿ—’˜”–¥ ®œŒ©œ–‘‘”•”‘Ž¡“†—ŸŸ³Ÿ”›”Ÿ¡™¤Ÿš › ”˜Ÿ¦¤¥§¤¯­¥¿Ã®¨·µÉþ¶Î²Ä¾Ã»³ÑÉÈÁµx|p_[_mTNIDLLLJ@A=BD<5AD;:3=8B332262A15IEM>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBh]Me\fTcjš–Š‹ˆ’†‰y†“r€{Œw‡‚y¡–¨š›˜º¾ÉÈÊÂÒÉËÂͽÁ³­¼¿§ºÀ½¼Ä¸¬Á©­³¼¾ª±ª¤¥£¬®´®·µ Ÿ®Ÿ¦¢˜£´¼©œ¨¼Á£¶¶¯«“°¬ª¬—†šª§¥‚Œ’¤•‰€u‰‘y„Œ‘Ÿ‘Ž’ŠŽ‹“¢—–š”“¡ž©ž¤™‹•–ˆ|Ž•’‘¢š” ¢œ¶¦Ÿ—¤¤£¥Ÿž¦˜ž•—›¥£¨¨¢²¬¨»Àį¥³·ÌÀº®Ã³»½Á¹¬ÂÂÁ¿šq|d[Z^]LMNKGECHAAADK:4DH:;4<7F.12352A26SHN<JBJQEKCEE:ELB<7EV=<=89?<I?:EUIAWQF7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>lJ_XaZdeXžŽ–Žž’‰Š‰Ÿ’„x…”~ˆ‰€– š®§¤˜Ã¾ÈÄÈÆÒÍÎÍ˼¸°º½´½Ë»Ä¶¶¼­´¿º¼®¯¨¡¨¨¶®®©²·šž¬¢¨¢«··ª¥¯¾Ä±½¹³§ª´³­­—•¥­© ‘Ž’±Å§”Ž|‘•|†˜©˜—’’Ž’”’¤œ’œ˜“ ¡¡›˜ž—ŠŒžˆZ–—’–¤™f™£ž³¥–£–«­«§œŸ¦—™–˜•¡¤¨¦žµ«©º¼Â´¦´µËÁ¸ªµ¬³»¸®¨¸º¼·„pq][WXPGKTNK?AGDDHFF85FM;>7>AK.32025B55PWN<LFKRLOGGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|hV<>@BFBsFiIRfdMF¦”œ•¡—¨–Œƒ†¥’ˆ‡‚šƒƒ•“Žš¡Ÿ¯¾®¡Ç¾ÅÅÈÇÎÎÎÒʾ»¶±»»¼¿Ï¶Ä¾·¹·³²µ³¸´¬§œ«¬¹«©¨°°˜£®¥¨¤¥´À°«¬´¾Â¹À¹³§¸´·²¯•¤­°°¥‹“” sÁ™}–™„Ž–™‹°•™™”‘‘™˜¤¢”žš•™¨œš¡Ÿ˜ŠŒ•_J–œš”™¤—T–°Ÿ¯Ÿ¥•¯°­¥›¡¥”“™˜ŽŸ¦¡™´©ª³¼»»«°²ÇÀ¸¦««­±±£¡²²´¥srh_]QSMFQQPQ;HJHFGAC=9KT?A:=EM/7534:B44NWN<JKOUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@CAF3>58JKCA=C;5FA:A?>H@5*B52,>c]g:35tde@R7&#3}hX<:BC@=REWStbVFH«—™Ÿ¡¨®˜‘—‡Š§–ˆ’„Ÿ‡„—Ž š£¥µÉµ©Ç¼ÃÄÉËÉÈÍÍÇ¿»³¯º¸ÀÂ͵ȻÁ¹¶º²¯¯´µ§¤œ«´µ«ª¦®¬š¤­¦¥©¬º¿¨«··¾ÁÀ¾·²²Ã°·½¬£®µ­º¦ˆš–¥›u¾Ÿ„™Ž’˜š‹®– ›š–”šžŸ¨¦Ÿ™™©™ ¦–Œ‚mu’¢š•œ¢Ÿ®²¢«–ªª˜«¯¥¥¡¥ª’’™œ‰•œ¢ž–°¦©ªº¶¾³²®¾¹¶ £§¨¥¦œœ­©©ficbTMNHIOJUL=LDMIJ@CD<QU<AABDO18=77?B75UXN?HNQXRPQTJQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CC:9C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW<:=..SaLVH~e^HF¬•œ¡Ÿ»®˜”ž‹“ª›‘‘“ˆª‡¢žŒ£­”£¤¶Ç½´Á»ÂÂÈÉÅÂÎȾº²¯¹µÀÂʶƲÁ¼µ»¬©­­±££™ªµ»¦ª§¬ª¨¯¨¤«ª½»¨¬½´·¾Ç¼¶µ¸À°½À³ªµ·¬¿¦¢– Ÿ»ž‰š ˜–Ž¶ž¨›¤¢š› ™§¤± š¥œ§©œ—“Ž”›Š–ˆŒ¤¡”œ¢ž µ°¤¥“²«š«­ŸŸ¥¤ª’–• „žŸœ•©¥¡¡³´º¶­¨µ²²žœ£¥š—•™ª¡žxd`a`LIGHNQIMEFFBQJH@DGAVSDH<AGQ1:B7:BF79]YKALPTUSMWRNUJD@JJNO9C?5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-1:h]FDCœpbGD¨—¤žŸÃ¬›—¤—™¨›•™šŽª–•¨¦•¬­™¢«·Å¼¿¸ÁÂÀÈÄ¿ÍƼ¾¹²°¹´¿ÂȶÀ°¼·º·§¤«¬­¡¡›««Ä¢¥¨¬¦ž«¯­¢ª¨¾¸¦­¾°··Ç·´¹¸¿°¾Á·µ²µ°¾¤–£•’š“­Ÿ¡¢¤¢¢ž½¤¨¨«œœ š¥Ÿ¼¢—£ž¡¨ª œ”Œ”“†Ž„“ž¤ ¶¬¦œ—³§š°¨ œ«Ÿ¢š– …Ž¡šœ’¥¥š—«±¶²ª¥ª­¬œ˜  ’Ž–©Ÿ”if\c_QJHKOLGEDI@=OH@;FIH[RPK=HNU4BF8>HG5Cb[KCNRUWVQXTRUH@8QQPM:G@4CHQSIC;C>GVKC@O>K<06;GF>;FA56?9:?9;15D0--0Mv\4KZ5,MnW<-=)#zbQ5CKQ9oSF<KxfcXN¢›£›žÅ« ž«œ­Ÿ‘¢ž–¤Ÿ¦ª«—¶±£ª³¶ÅýÀ¶¿Á¼É¿Êȶ¹µ´±´´·ÂÆ·¿±¸µºµ §¬«¬žžŸ¥¤Á¥ ª® ¤©­°¢¦¨½µ¥±¼·¶¶Ã²³·º¾²ÃÀ·¸®´µµ£œ¤”‘“ ¬ž˜¡œ¨¨ª¢šÁ¬¨«­šš˜¥Ÿ½¡œ¤—ªª«¥ ˜šŸ’ˆW–ž¥¡ ¹ª§“™·£Ÿ³¢¡œ°˜¡›•ž‚ ——Ž¢£•¥®²¬©¢¢¥¤••œ˜‹’“¤Ÿ‰cg\ebNJKKNFEAGK>=IA:8JJN]QQI=LV\9FI=DMI8Hc\KCLPSYYVWOZ^IA=WQIK?H?5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+waS6SZkWsHE6=ue\LPž  ˜žÃ§¤¢³ ›±¦’©£Ÿ£ž­©«»±©¬µ±ÈÄÁóÂýÇĽÅʽ°±¶®±µ¯¿Åµº±±º¶¬›©°ªª›Ÿ¦¡§Á­›¬±œ©¢®±ª¤¨½·¦¶»½¯·Ä­³´Â¿²Æ³º·«µ¶®«¢¥••“¢« žŸš§ª®®¯»±¥Ÿ¨©™˜—’¢£· ¡£‘­®«¤¥‘ ”ŽŒ”š¢Ÿ¨µ§§™µœ£¯›Ÿœ°‘¡•™•›€’¢–Ž ¡“‹¦¬°¥§¢ ž’’š“…‹’œŸ€dh]hfKJLKSAC@IG;;F>99NMU_RSJ>O^^=HPBMLI8Nd]LELRTY[SUO\bHA?ZQAHAKA7FELKN>;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<w]^?[U_gr@8<H–weA4Ÿ¤žš Â§£©± £´©•±«¦¢¤²¬­©»³­°µ´Ç¿Äõ¿Ä¾ÊŶÁɵ¬µ©°¹¬¿Ä´¸¯­¶º¦™«²¬«˜¡§˜­»´œ¨°›¬Ÿ®´²§ªº²§¹´¸²¹Áª·³Ã½´Å§¾®­·µ©¨¬¡––‘¥£¡¡——¤®·­±´¶Ÿž¨¤™“”“£ ¶¢¤¥•­±±¥¨¤ š™š•—¨ Ÿ™¢ž¯³¢¦˜¯š¥¬˜›Ÿ§“ž•™›†— ”ž“‹©©«¡§ šž–™‚†–‰•Ÿzek^lkNQNNT=CANC;:I?77QN]_RVQBW`]BJSHWKH:Td]NFON[W[RPQX]GAB[PBG>NC9HGHNP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1\cZ33906p[bH05JqjWDWFŒyfC;¤¤œ ¥¾¥¨®® ©µª·¯«£ª´¶±°¸·°·¸¸Å½Ãǽ¼ÃÂÈÁºÂƺª¶¥­»­Áø¸ª­²¼£•®°®³—¦¨‘ªºª ¦°ª ¯´³ªª¶µ¬»¬³²º·¬¹°Âº½¿¦Ãª°·¯©««¦˜˜ª ¡ ‘— °®³ª°¸™›©Ÿ™–‘—¦ ¶¨¥¢¢¯°³«±¦ªŸ›ŸŸš¥¡˜£´°œŸ‘”¦›¡©œ–£¢˜šŒ—š”–—ž”‰‘›™”Ž©©§Ÿ£œ™›“‡™‹~Œ—…›linbnoXQQZTACDU@;:IA7:XPd^QWWEY_^MLSO^LJ>Zd^NIQN[UYPKSWZI?DXPDF>N?=IGGQPB=DFBM?:2D?77547?=95E4+75/251.-.,1>*'+=\p=>1.1e[d@1747gYaF(@8m}i\V;‰{cC=¨Ÿœ¡©¼ ª¯ª¢°·¨¤³²«¡­µ½¯³¹½»½··Á¿ÉùÄÃÁÀ¹Å¾Á¸°¶¨«·²¼¿¿´ª¯²¸Ÿ—«­©®˜©©Ž§»Ÿ¥­³Ÿ«¢±°³¬ªµ³µ¼­°±µ¬°µ²ÀºÅ¶«½¯±·¬­ª£±¥ž¥¨ž£–˜Ÿ²©²©©²™§›š”ŒŸ¦¤´®§¢¬¬­°§²ª°©¢›ž§£ž•¡™œ¨¶©˜š’’Ÿ™ž¡ ’­¡›šˆ—šŒžš”‹——š—¦¦£ ž–––“€•„{“ƒŒ—gmrhqs_GYfVDCMXDZ9HB5>]Qh\OZ]G[_^NMSXcJKC\c`PLMNXWXPJVVWL=EUJEDAM?AFHHQPA;GDFK=87B=68719><65D0+80/05/*,/-*=,+%2+*5K1.'__aV151=`V_8)C3YU\hK5ŒzfL@¥™Ÿ¤¬µ£¬¨¤®­µ¨®³¸¦§°·Æ·±·¿Á¶µºÅ¾ÌŹÃÁºÀºÅ¸Áº³´¬ªº·»º¾µ«¯±·˜˜¨¬«¬œ®««½«®±£©Ÿ±­³®®µ±¹¶ª­¯²¨¶°´º¼É²ªµ´±´°¯§¡³Ÿš¨«Ÿ¤••š™±¢­ ¥¯–¢¤™™’Œ¢¥§²©¡¦±«©´¥®¯³®£˜­§›—žšš¬¸¢˜“‘˜œ¡™˜•®¡Ÿ—ƒ•šŽžš—‘Š”“žš¥££¡™–“’•{Œ…{‹ƒ‹“lnyov}aF`jZIHZ[={JGE6AcTi[M]aK\][RRSbaLKE`a`QLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`Va.5(C^Q\.+A/JGP[G3cXTLEš–Ÿ°¨°©¬¤£®­µ¨¶³·£¬³·É»µ»»¿¾µ´·ÃÀÌǼý·¿¿Á¸À½²½®¨ºº¸·Â·¬®±º–—§®­©¤²©”¯»¤¬²²¦§¢²´±²±µ°·³©®¬²§¸¯¶´ÃŶ©µµ«°­ª§£¶ŸŸ§°Ÿ£”›˜”±ž§›Ÿ©©¢›•—¥¥¤·§¢±³«§°§­¯´¬¤˜ ¬¨œœœ•ª¹œ•ŽŒ˜¢˜‘™¨¤¡™†”˜‘žœ˜——‰——›¨¥¡’–’•v„†{†‚„nqxv|€\Lel\KOd]?b{GI8GhWe\L^bMYZWTXUj]OPHa^_PKGQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANIg27'FaLV%-B.=ELQ<3rjLED‘™¤­¤¬­ª¥¢°±²©·¯µŸ«´¹È¹®Á¼Ã¸³²µÂÃÎÄÀ¾µ¾ÀÀ»¿½´Ä©ª¹±¶·À¼°¬´´ž¡§±¯¦§±¥±µ¬ª²°«¨¨µº¬µ²µ«³¬ª«©¬©¹®²±È¿¸¤¹°©­­¦¨­±¥¤£®£¨œ›š®™£¢¢£¬Ÿ£ Ÿ¡©¦¥¸¤«´´¤ª«©¬®µ®¢£¨ªœ š›“¤µš‰Žˆ‘£¡––Ÿ£—–‡‘••ž›™—•ˆ˜“•™§¡ “‘Žw~„}|}‡ŠŠrts~}\Scn^NZg]FD–[G:MnXa[MabNVWVWUYh^QSMc[[TKFOTSNGIVS\N;P^JBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3De;6*HdHJ+:I?3CIS,>k@HIš¨©¡¨¯¤¦£³³°³´°° «­½Ì»®Â½Ç²´®´ÂÃÑÄſ³¾Âü¿¸½Å¨­·¬³¹½À±¬²­¢¤§®«¨¥°£ª°ª®ª±®®¬«³»§·°±¨²ª«¥¥£¯º¬ª±Â¹´¬¹©©¨­©§±¥©¤¢­©¨¢ž›¢¬•¥—ž™¬¡§¨¡¬¦£­¬¶°± ©¢ ª­°¬ž§§©š¤˜™¡¨˜†„‹ŠŸ¡˜ž’’ˆ‰’–¡–™–‡—““—¥Œ’‰ˆ„|w‡…†utr‰wl_Y_nbQsq\K;„|F>WuWaYOd\NVVUWQ\b_SPNhYXWKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=398;*35>10485(5/*,.30;),,'%234$,2-860)(2=^K0.IgDF8<B05EKX1@”]@NF•–¬§ ©±œ§¨°µ¬¸µ­©¤«ª½É¼±¿¹Ã¯°­³ÄÃÍÎÿÀ³ÀÃĺÁ´ÉĬ¯·®³ºÀ¾´®®¬§©ª±©§¨±¥³­ª¯­­°®²­³»¥·³¬¬®¨«Ÿ£ž±·«ª­º¶¤µµ¤ª§«¬ª­ ¨¦¦°±£§¥¡¡«–ª¡“› ¦ž£¢ª£¬¢ž¦±¶¬¬¢¥¢š©ª®©œ¡¥¤¤™ ™–˜“‚‰… ‹Žœ‘“…š¥›“’›Œ“’‘”£šœš‹‹‹|†‚‚zuƒ~uxŠ¢†xj]_nfWe‡dN@g’LDbzWbXRfUMVVVTO\]aVKOiXVVHJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*49?./463)4+*,+.#4.-+&(+79*&6+<.2,&07XZ.0JgAA<<C+:JO^4D‡BIID–®¤¡ª¯—©¨­µªµ±ª¤«ª©¼ÁÀ¸º´¼µ¦³¯ÄÉËÒ¿Á»¸¿¿ÃºÂºÁÄ®±µ²´¼Á¾³²¯­¬­§·ª¦­¯ª·®§°¯®±ªµª¶¶§´·«¬¤©ªœ¤ž´³¨¨¤³´Ÿµ­¡ª¨«¨«§Ÿ«¬¨¸µ©ª©©¢¨Ÿ­›‘ª¡ ¤¢¦¢ªœ¦´®§¥©¢£—¤¦§ªœ¢¤£ š˜Ÿ‘™‡Œ‡„žž‰†ŒŒ‘‘“…ˆ—£šŽŽ›’’’ ˜™—‹„t†‚~xuƒ{x~‡pqffpw\atˆjO]˜VHmyUdVRcPMVTUQOX[bUIQjUWTGOXUI>IHOQPxMNV=<KD?@A<@CUC9AK=5;E23;:7*4:=+-341*8**+*,)*(/*&)%3;,$2)2/22%/3Rc02?f=NX?C,?LT_/Ik7RF;•Œ¯ ¤ª¬™©£­®²´¯©¤¯©¨»¿¼Á²°¹­¢¶¯ÈÇÈÐÀ¿½º¼Ã¾»Ä¿¿¯²³²µ½¼Á²²´«´©¥µ©¥­³²¸®¡¬´±¯±¹«¹®ª®·«ªžª« £¡¶­©¡Ÿ®² ´ªŸ¨§ª¢ª¡¡¬­¨½®«®­¡§§Ÿ¬™°¢˜¢ ¨§ž§›™©°¨¢Ÿ«¢¡’¡¢¢§™™©¥˜˜™‹‡•ˆ}Ž†„…¤—†ƒ„ˆ‘’†‡–¡—ˆ‘ž’“‘•˜‹††xt|twy€{ut{kƒ‡¤vi^ek€ugˆŒ|RVo^KxsTdSQ_MMSZgNMWYeYGSjRR?BNQaQ:IHLSIqQLS;<I?;<=;@@W<<>H73CB15:93-5::)-31--6)(+-,52#2)',%.;.&1.0-14%,0Mh:38_=ad?F1CP[[+HP;YC3± £¥ª££¢¬¦³²±¨¤°§ª¸¾Á½±©ºª§®°ÉÆÈÐþ¿½¹¿À½É¼Á¸±°µ²º¼¹¿³´¼¬¹¬£´¦¦«±µ·±¥¦¹´¬³¼¯¼¥­­µ«­œ©¯¤Ÿ¤¬ª¨œª²£³¨š«§©¤¨¢©§©½ª´°®©¤ ®œš³¢–¤œ¥¤Ÿ¥šš¨ª¥žš©¡›‘› ¤™–¨©‘™š’‹‚…~‚ˆŸ‡ˆ“‘‘†ƒ•›”…“¢Ž”‘‹‘›“–‡Š€qzy}{gv|zuqr~j†y…ˆd_gcr…{mhy]^UAW{mTbPRYKLNpt]IZ[hZFVfPC>JODCA9HGKS?jaIQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11&/>KI1%90%,,09/,,+6'17#-/GjI14X=fbAJ7GS`U*=<F\@*Ž‘°˜žŸ¨¤¡¡«¤¶±±¤©°¦­¹Á½·±¤¹¬¨¨¯ÃÉÈÌ·½¿µ¸ÁºÈ¶Âµ´²µ²½¹º½¶®¹¶¿¬¢³¦ªª®´¶³¨›¹»¨°¾²º ®´¶©«Ÿ­°£œ¥©©£›¤°¦¯ Ÿª©§¡©›£¨ ­¼§®°®¡ª¢¤®žž­¦˜Ÿ›¡¢œŸ›™£ª¢š™££•–” ¡–›–¥¬ŒŸ’‘Œ‚Š€€€{š•Š}€ˆ’‘‹†“˜‘†”¤Š“’ˆš”‰}yk}vxxbzzqoqtxj‚uk‚gcgansŽmbjo`o@\ykV^NQRKIMTYVM\^mWEY`P^OHMDF;7HEKO<rhJK9AE;;==;;=J49B<3;G<4?18-78;2(09/,5..=-*L>*49&'.34.0+/4&,:$40AhZ13S=e_DL6KVdN)=3R^>#‘–¬˜ž—§¢ Ÿ§£·¯­¢¯¯¨¬¸Ã»´® ¹¯«¨³ºÇÊÇ¿¸Á½¯´¿·Ä¶Ã²¯º±²À¶»½·ª¹¸¾ª¤´¦¨©¯­¸¯§—¸¼£­¾´´ ­¸µ§¦§°³Ÿž¥¦¨ ¥˜ž¬§¨ž ª¯§ ¦—¢¨Ÿ°¸Ÿ¤±¯ «¡¬¤œ¦§¨š››ž£•œ›š©¦–›ž¨‘˜’™“™–¡ª‘šŠ‡}‡~‚Ž||¡‰z„†Œ†Š“šŽˆ” Š‘•‚Œ—’}…|sp}qss_xwinqqpk€sdzlgecaf†€`[rjrMM€iXZMQLKHPSPGL[`oTFYZRhOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23/:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%53=fd24M?e]FO=RZgH*?0]\5(•›¥˜›•¬Ÿ¡£ ¶«°£´³©©¹Å·³®¡¸­­¬¯µÅÇÀ·¿Á¹°µ½·¿»¾°¬¾°³¿²¼Â¸ª»º¸§§´§§ª¯«²¯¤—»µ¤«ºµ¯ž±¹¯©¥§¯±›¡¤ ¤£ –›¯¦¡ž¢¨¯¡ ¡’¤¤¡·°¡¦±«Ÿ«£®˜ª¥¨Ÿ˜š¤“™›š¥©™››¤•”—•œŽ“—¢©¢‘ŠŠ†z„~„‹y—Š‡{ƒ‰…ŠŽ†“˜ŒŽ•™‹—~†—Œz{prwnos^wvdlllkj…nfrijeh]ds`[kviZJ^[XOOKHHSVG39^_lPEYVYfMIIEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<"8R=*113>D5,-'42*;+139cm74GAf[HTDT]hD.<2dW,1”¡¡–”›ª›£¡¢¡¶ª­ »·¥¬½Å´°¯£µ¯¬¬¯´Ãü³¾º¶°³¹¸º·º¯­À³³¸¯¿À·¬½ºµ¥¢²©§©±©«°Ÿ™¿´¤§´µ¨ž²¼©¨¥©¯«™¢§œ£¥”— ²¤™ž¤©©œ¢Ÿ’¤ ¤¸©¥§®§¥¡¨“ ©¢¡¡™›œŸ‘™›–Ÿ¡ª›š˜ ”‘”—šŽ““¤¨¤‰Š†z„{„†}Š‹‡{‚…ˆ‰Š’†—’’‹•”ŽŽ”{ƒ—‹w~|ltrlksawthhjhgp†hhidfii`jcjh[f{b`StT\[RLJGIPT@!*h_iMDWU^`LJHEC.:B<F<6KPD8:D357==895?:;4>8@K=>93)8><:9*6@3.E4(+,?0-N?.+-7,1195,&.5-80576`tA3CDg[KWGU`hB379gP'2ž¢¤‘Ž£§™œž£³¬§ªº¶§¬ÃÁ¸±¬£¶®§­¯·¿¿¼²Á¶°®²¶¶¸¶¶­ª½³®²°¼¾·¯»»±¥Ÿµ©¥¤³¦¨­œœÀª§¥¯³ª¬µ»ž©©¬°¥˜©¦¤‘˜¥¬¢˜¤©¡›¡›–Ÿ§µ¦°ª®  ž¡• ¦ ¢ š›™›’˜“¥¬¡—–”“•—‹˜›© ’‰Š‹‰y…v‚‡‹ƒ‰~€†‰‡†‘„—”Ž‘‘‘Œ“{ƒ•†s~~fyojjkftskbgddvceffejickr[_Y]lcaNiXZ`VJGIKMSX>9_lhHCVT\[IJGFA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A=-5B37=+*,0B*JK./*+3722(57$+7.72685]yN2>HiZLZJVbf@:3BhH%5š£ Œ¬¡–– •¤²±¢²½¶¡±Å¼º²±£·¬ª­©¸¼ºº­À±®®®¶¯³¸³©«¹±¯®³µºµ°¸¼«¦ž´©ŸŸ¯¢¨­›¡¿Ÿ°£®±¯·®µž­¯­­¢™¦¨¥Ÿ•š§¥Ÿ˜¤¢¨šŸš“œž¬¯¦º¨®¢¡š›ž™ž¤š¤—ž˜›”˜Ÿ’¨•ª§š“šš’Œ•™””›ª§ŽŽŠŠ{‚sŠ˜…‡}‰Š††‹ŒŠ“…•›“’Ž‘—Ž€Žƒofymgkifprk\gcctbfgjnlgjjhn]llrp`TcicfZIFLMOXQQUae€UAWSYTFIFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9A1-+.3<;K60.+,-24;6#3*)6.55465Z|]19Kj[M[KXdd@A1JfC&4‘¡›Ž¯˜“¡š©±¯ž¸¿µ ´Â»¾º±¦·¯§­¤¶··¶¬»®¬ª«¶ª³·®¦²µ±®©°µµ°³µ¹¦¨Ÿµ§œ¨ §«š§½—¬£®°µµ­­ ±­°¨¡›œ£«§›”›¦£š©¢¤–šŸ››¤ª«©» §¤ ˜š™¡k¢–™œp‚•™£u‘©§ž””ž‰˜š€–Š¢y‡”ƒmiwƒql†‹†~…Œ‡q_dag„˜…kŠ”’tw‹„~ƒ€g‡€guheW\hsnMPicgr…h_efnmj]`aŠƒ„eNKD9GTh^JHQPUULHSapteF[QUPFHEC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=A@@=28@E=1,,08=G701.*.*/568,#1'214:176Xl16Ok[N\K[fb>G1Qd=*.‹¤™†•°››“ ›ª¬ª£½Å¯©·Â·½¼­¦·°¥ª¢¶³²²°¹¬©¦¬´¥¯´£©·µµ¨§«¶²­´­²¡¨ž²©¡£™¤¥˜«¹“¥¥¯³·­¯¥ª®ª¬¤¡žœ ¦¦›– ¥¤››§¦“žž—§©¤¶°¤¢¢–˜——£ˆ¡Ž’š† ‡’œ ¥¥ªž’’š‘ˆ„sxŽ…ˆ¡v‰i—ˆf~sx oˆ‡„~}¡  ™€}‡žs†Žu›Šl‡ƒmieczlraS…mbli˜qXiqpˆY^i[ll[ˆrnzr…f†„Z_GN?G_NFRVVQQRWUg]MVIRROFHG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82*/1<I9/01.*.(-4583%&2115>1<8Xƒu25Rk[N\L\g_=K1Wa7/(Š§—ƒœ«˜˜žª©§ª¿Ã¯±º¼¶À¾ª¥·°¨¬¥²´®®³¶ª¨¤°­¥´²œ®µ¶´¦§§²°¬²§­© °§Ÿ£¢˜Ÿ¡š¬³“£¥¥µ½¦­§«ª¬¨¤¡ ˜Ÿ¦£™˜¥¢£˜œ¤¨–“¢›“’£¥¦¡·¤¤ £˜•“—“œˆ¯—”‰©‹–¡œ…±€£¬“™”y‚Ô¨€‡•ÁœÆyx±¥·—e€Àœ¿y„…z’„}‘Êr—»œÅzrµ§º{€m—±«°yhlX±®nei¼’¼ngznrØ~Skc¶²~r”sš¡ªWOWbOVNFU[XQQS]W[QA]DQNEHI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>:B<?A8:J>52*22BE/.32.+/(-/186- /416A1=9Wƒw21Tk\O[M^g\>L1[]41!Œ§“§ªŸ—œ¥¬±¨°Â½²µÀµ¶¾Áª¦³¬¬¨¦®³©®µ³¦§¥´¥§¸­œ³±µ«¦¤§±­­°¦ªœ¦£¯¢ Ÿ•™žœ­«“¢Ÿ³º£«©¢­®¥¡œš™¡§Ÿ—š§Ÿž—ž¦§‘œ¦™“¡¦¢¡±£ŸŸ£––’—’™…¯kjŠª~fƒ•†­dp”™¦”p®¡¤~x»}l¡v±_j´[¥€eœagƒ{g€kyk©e¾qg¦‹u±j{±xt’”cnm§n[„¡Ehf‡–Euœ`~g|¤§‚Z`Œ«h€”xyj§7J¯\XSld[KOX_\WV;NŠOWW/ITSJDFF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=03.33E3..53/+/(.0.:5/'$203B/=;U‚v2-Vj\OYL_gY:M5_X30¢•ƒ­§¥ž£¤ª±·¬µ½¾°¶Ä²·ºÁ¦¨°ª®¨¨¯®£°º¯£¤­²£©¸§ž²²°£¥¡©¬®«¯¦¦ž¢¡¯š¡›–”–šš«¥•š¡ž³³¢¬œ£­¬ ™–Ÿ¡¨œ˜ž£Ÿ›™¡¦¤œ¢™– Ÿªž§¦¡š ¡–•‘–š…µ›µx…©™µ™v†³›·~“––©”k¦{‚†ˆ“”“w«gk±\«z†”t‰r‡‰—x‚‹—‹ƒ „°vwŸqlll|‹N¤XHbb™~ch¦`yruS“‡^Q©mcq}†€bœ.Q¡o[Skh`LJ[dX\ZB>²{XXA#MhFCEA@A19>88:84;99<9:A:E::;6:CB8=?KNG:5:@FB@AD<FD;0201;F,0.840,.(/3,>831/2-D1<<S}n3+Xj\OXM_gX7J8aU50” •ˆ³¦¦¡¯©¨³¬©»¶Â°»Á­¸·¿©¬­­­¥¬±© ®»ª §³¬£«´£¦²²§£¢ž¦ª±§¯§¤ŸŸ®•ž™”””—¬ ™™¤¨µ¯¢ªª¨ª›”— ¥§šžœ¢ž›Ÿ¢¤¢•›ž—™œ¢©š¦šœ›¢¡—“‘’“ƒÕ“™¹p°Á~ņ|֔›»|š•¥¤{Žˆ¤ƒ¥ƒz¬yV¯zˆ~Ÿk¹[ºw‡„~¦‚”{—zªxz±nŽ„t‘¼…o”P¯§ÅŠQ zc`ªbsrˆm—ˆ`Sµ´È…€‰|c¤3Bv]PjicP@XhZdaJHMqP\QOYfZCE?E?0=<59;74<;8=:<C:F:;>6:@C;6@OLH<9;DHCBCD<EF81211DC./0483+-).323971#%5*>3==Qwj6*Yi[K]O_fT7H:aP71%›¢”˜²¨¨¦´ª¥´©¤¼·Á°¹¿°µ´º²´§°¯¢¯²¥Ÿ­µ§š§¸­¢¯±Ÿ³´° ¤žŸ¦©°¨³¨£›œª•˜—••“• ©œ™–§­°©£Ÿ­¢¨–•› ¥ —¡ ¡ š¡¡§›ž¡ž”˜š¦ ›§•››Ÿ¡˜’”ˆ²nhµq«‡nŽ¦r´sr¶{š—¤‹¢~‘¡¦±wƒ‘ÒÒv\®{…¤o›ª¦k‡…}­}˜™Ž{±q’žŽw³e—t„žožg”QȋZÂ\ yb_¬`us‡b—ˆ^Yʝo¿uMKµSUÆdTQjceXAPk`lhPVGJ9=URZWXID?J<2?;5=<46>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>HI91746A>/.24252-).26,742&60;5:=Pqh9'Wi\BOT_eP5G=`L620¢’¥±­£«¼­¦´¦§µº¼±º¾¶µ³¹¸²¤´² °±¢ž«¯£—¦¸­¤±°œ´·© ¥ž¡©¤±§¬©£™›™§•“——‘¡¦Ÿ•“¥ª°¦¢–“­ ¦’“Ÿ›£¥ž•š¥¦ š¢Ÿ­™¡ž”›¡œ¥••™¢ž•˜•‘š…¬{w¨v£ˆ†©o­Š‚§ƒ˜˜¡Š’›‹¢“š‰®„€‚³\r³R®}‚‚£rØ~x†~†š™v¯†‡‘œ‡v´ašeš‚‚•m’Z°XKšu˜yf`¬^uwˆh˜ˆk]¯w•žxl5yÈ®²_BTo^g`EPl`pmVVM.feiSYP;BE@L:5?91=<16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK96<46:>/04333.2..18*.32%!03767=Pke>&Vg\@>V_cN6GB_H:99 ž• ¹°—´Â®¨³¨©²º·³·¾¸·±´º´¤·²ž³¬ŸŸ¨«ž”§µ«¨°±ª­³£›© Ÿ§¡µ¦¥©¢˜œ”¤ “’›—‘”¡¤š’¦­¯¦¡•™ª ¢Ž¡™§¤Ÿ”™¥¨œœ¤ž¬œ¡œŸŒ“Ÿš¡˜™›–—¢ “—¦†©}}¥x¡Ž‚ªp­‹§†–Ÿ¡‰˜˜ˆ£ƒ’ˆ”«}€‹yo±Z¨‚‚ˆŸztـwˆt¨Ž›Œ’¤{”Ÿ„z²^d ~ƒ•m’]«[Z“€‘hgªcq|‚k˜‡s]«Z‰ ŽkoeOJC¡\[Lt]bgN[a_qs_KW7Jœ˜XGE=HGAM35A8.;>05A78@<6=<F?:<6?=B7.HVJEAH6KIN@IK@EN::@5.:>102144+*05/7,&21($$6671<PeeA&Uf[?2U_bL7FH_C2?8¢žššÁ«—´Â®«­©¥´°·°µ¾¹¸±°µº¨º³Ÿ¯¤¤¦¦ž“©¯¨®¨´«©®¡˜  ¦¤£¹¡¢« –š¡Ÿ”“ž™“—žŸŒŒ¨°°§ž—›¨¦ Œ‘£—§ª¦”—¨§ž ¢­¤¡ž¡Œ”¡˜Ÿ ’ž—œ•¡•–ªœ®mr´s©‹uŠ§s´xs³€‘¤£‘Ž‰¤‡w¸p{‹¢jk¶Z¡…e——i ¢§n”r´t“™~²j…‘‡­ju³af¢o‡“k—]­`M¡|†’Rs£kx~o˜‡q\¯V<œwfTon.\§OcSkebmYc]ap{cT[R>=nq3CB@?L:!7@6.;@37C58??3;<CDBJFMIF62JTKEBI6IJP?HNCFP=<E50;;010/75,+,426/#00,,289/9N`eD'UdY>/U^aL5FL^81C8¦œ›ž¼¡›²À¯­««§·©·®µ¿´º¯®·¶ªÀµ¨©¡›¥£¡œ‘©©§´¢²§­© —œ§Ÿ¤«¸£¬š•˜Ž£¢•Œ ›˜œŸ‘“”ª¶°¨™•œ¬©—Œ“¥˜¤¬¢‘•ª±£Ÿž¦«±™¡£˜¢–Ÿ›–œ–¡“œ©œ”ª™‡Ô’š»s°Ã€Ã†~Ֆ›¸xˆ˜Œ˜‹Œ§ˆz¤¶u~wv‚š²`ƒºyÀ}v¸cµŒ‡©}•«©q{t¼ˆ§ ia¦Ž¯¡~Œu‡ª}¾os¼t²ƒtxŠnšˆqn¤t½^w}Zay¼kZV\jy^jafgcmwoY\ZC@@t@CG+4G"';?10<?7:B99=C4<@NZ^```__ZPPRKEFJ4HLR@JNEFOB=E84=9020.87-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-7A9§›ž¢½¡—²Ã°­ªª«±¦·¯¶Ã¯¸°­¸®­À°«£¢£¡œ›¨£©²¤´¥¬¤ž•šª˜¦¬¸œ¡­˜”Ÿ¤ž’Œœ¢—™‘•’¯¹²¬–˜¤¨§”–¤›£¬Ÿ¨«ŸšŸ¨£´Ÿ£¥Ž§¡”¢šœ˜•£˜¯Ÿ’”©ž…˜¶‘Œ·•x‚“šµwmknsoy…ŠtŸÁ»½š{±¨p€s‘¹ƒ}‡†‡|Š‡˜|¤»¹½œty´£tw—vt°u™žf‡jµtrqx¶Œ^z}‰hƒynzc‹¬pu…X[§jEeZTf`c^cQggpluCNQMD:[M?J3;/ 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITBKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7LT_G'SbW8*O^]=+:VU'>;<§ž¡¢À¥–µÃ´«ª¨¬ª©¹®°Å­³²­µ¦³·«©¡¡¤ž ™“ª£¬ª¥µ§¦Ÿ›• £«¤½¦ ©–“›¡š‘Ž¡§¡’œ—”˜”±µ·®™ž¤¤¢‹’‘¦š¥ª›•§¤¥›™¡¨¥§¤ª¡’­ž—¤ž———ž¯¨“›¥¡j}iš¥w†r}šŽtyd‡{½¾Àºo“ƒr–ˆaskZ_›Šacˆ•k`€–dnžwc–l€š•”e^`bp™ˆir‹}†•gkrtx}b[wthP]mƒ}{‹kXkz‚sJJo†pNtLEX]gaL[Wgc_O[mtiqRQDEM;GI<M?2,2A?8/5?C<9;@;=C>RVVWYZ[[\]`aaa`\UG5DFUEJOHFPIIH;8=51:.0;:.0-76=5&"/*2,%;8-7JR_I'S_V4)P_L(2=[O'?2>© ¨¢Â£›µ»¶£¬¥®§§´±¬È«®²ª³¢½°±¥Ÿ¢§£›™™«¦®£¤´¨¤›˜” š¥­§¾§¨¤”“š•Ÿ™’—¤©¨ž‘˜œ°³¿­œ§ž§¢‰“‘©š¨£ššª £™š£§¬£ ¬£š±›”§ –•Ÿ–°¤— §˜š››¡¡—¤¡™œ™™™•gm}qw’˜”’†Œ¶«†˜–ŽŠŒ˜–‡”•‹„“”’‰Ž“”˜”˜–™Ÿ¡™š“ œ‚z¥…mk}}€uŠŠq‚xyvu‰|Šjstƒuew}wkozm_d]phMYZfj`WZoxmmfUOFR9OYMRO(+:KB635=@A9:C><ENSSTVWXZZ\\`bba_^^[TKCSGKNDGPLOI<:;389,2;820)6IRO8")+/2#4;*7FO[J&R^S10T^:+=8\J,<-@³ ³¢À¡¤²²· ©¥²§¥¯´ªÇª«¯¥³¤À§³ £¤œ£••Ÿª¦¬¢¢¶«Ÿ˜–•Ÿ—­©¤Àž«£”‘š–˜’”¡žž¢§“‘™¨§³Ä°š««Ÿ––¨ª›œŸ«˜¡šœ¢¤¯§¢¦¨Ÿ®˜—§™™ ž›¯ œ¡¥”–‘—“žŸ”¡— Ž–“ŠŠŽ—®|–œƒ’‚‹«©…€™—‰„žˆz„ˆ†š’ˆ‡Š–›——£•˜’œŽg¡³¯…Š…v{’Š}wyzofy€‰juyˆsis{vƒ†‚judzf`jecdfkYl{oij]SLPD^TE@?>,4@F;45;>A;<?>>HNNOPSUVVXZ[_bca_^^]^]XVJKLBIOMRJ;<:786/2964.(&$-1./)+*7%+<(6CMMD/T\Q05N[17E3[G5<,@´ ¹°¿¬¬¯²± ª§²¬¢¬²¯Ä¯©ª¢±­¼¢³›Ÿ¦¢¡œ˜—§¥©¥¤¥²´ž”“™™¯¥­¾ «¢™™”•¡œ—¨œ„ž«¬£´È´ ª¤ª–•—š¦¨š£ª”žŸ ª¯ª¦¤¬£¯›Ÿ ¡—¤žœžœ®£˜ž§’––›¢—–§œš–e‚’|e~šcyŽmhk{’¥«je›˜}g†Šeeih{Ž¢lh˜‘£wkjŠ˜¢ž—skmz„ŽˆzXf^†ƒ^mŒŠv\hswv‘€ˆ‚nx‚xsny„tv‰‡Žƒ|j‡Y^ltd]s‰ik|pkc_RNWIdXAJ4>F7?FD71<=?AD;;DGHHILNPRRUW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%/*+'6*$;'/AJ[J/7ZO6)EY/DO2YC;?.=¦ º¼º¯¬´±ª¥¨­®°¦­¬°»°¨¦£­­°ž«–Ÿ£¡™™¦ªœ­£¥§©²®ž”£¢¯¥µ¹¥­¢Ž™ ˜“’š ™™¥•|¦®£¨´Å¸¥¢§¯žœ•ž¢ž£›¢¨¨‘ž¡¡ª°¬¬¥«¡ª›§Ÿ¨ ¬– ›¥¯£–›¨”Ÿœš‘¢•œ©—}½ƒˆr´r„†­hx¹Ä¸q”££z¦™™r«‚|ËÀÀ»qŒ£ˆƒž|—™‰À½–ŒœÁÁ|‚|“šÃÀ}l¥²oŒoÊz›wƒŽuy€yqz‡pw…Œ“ymx”cg`xd`e‚b^sglddYLVIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNQSVY^__`_^^^^___]\SMPGUNA??=6468276*&%#)*&.+*)109*#>I[L*#BP.#F[3PY/UAB;/8–£¹Ãµ°°Áª¨”£¯©°®­¥²³®©¤¥¥¯ªŸ«˜š¢Ÿœšª¦¡œ«¢¤¨£¤´¤œ¢’¥­ª¶³§­¡‘™œ¤’Ÿ¡˜› ˆ§­¥¬®ÀÀ±¡©¯©–’Ÿ¡™¢£©£’ ¡ž­¯«®¨¤¤¨¡¦¥¬¨‘£š¨¬©šœ§šªŸ•–£”Ÿ¡•›~Δxz¤y•–›_®^Ž¨‚£¡|§–›s«ƒ€¯^cª{¨‡… t—“ˆ³c‚«† ³j„¯u}—ˆ·bƒ­Z£Ínv{Ú{™p}ˆ’v}e{‡vvk|‡n}…‘~mƒ`rmph`_ye\qgidg`RTSW]KOD5AHDD8>6;@?A;=8@>??BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5578164('$!',&&/(&+360$7;SL+,-J0';\;L-!P@F4.1­ÂÀ¿µ´°¸—‘£ª¨­´«¥²««ª¢«¦®ªŸ¦›™¥—œ¢¯Ÿ ž¨§¢¥ Ÿ°«š•¦®«°ª¨«Ÿ”‘šŸ¤’ž¥˜ž§£Ÿ®¦¬±¨¿Ç³¨©±®–’œ¡—Ÿ©ªž” Ÿ®°©¬«œ©¨¥¢«’¬²–¤¡ª©¢¥¤Ÿ®Ÿ‘˜¥—ž™’“— q…Œ—u…¨†q±}žr¬¢Ÿ¥Ÿv«‚}­œs­¬‡†Ÿv™’{|—~ªˆ¡‹‘Œ}«{‰• {­WÅ{p“Á}•lupŒmevd†nawnro‰Š’ƒn’‘fpuuqagmf_ohingdWT]aZRSC9II@D<>=@FECEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;91478452&# 1' 1' '45-&7=WJ-<(=1)3W@F!G:C1.+°ÓÆƲ³ œ¢Ž¢¢¢¬®¶®¨±¥¨©¦­««¦¡£˜¢•Ÿ¥«Ÿ¡¥Ÿ¨¨¢ž°¬—š–¨§®«¨¦§ž—”™¢¡’” ­›§£°­¥­µ«ºÍ±­¦®«–•œ¢˜ž®¬œ– ™žŸ©³«««œ­«¥£¬š®±¡§«­¥—¤©§§¯ ‘•¢¢˜“„¤j¤u‰z©tz²p‚¦Š™Œq‰ š†¤`aR¬…®ƒ›v­‚¨†…Ÿ{™—…zf€£‰¤˜†‚£}©~‚–ˆ®_|©Vž£’z£Ÿ€{îċr¯³³¹qb©¯ÂthŒŒ˜Žnœ•qozxyplfferpf}jc]W`jXYUMMQLCCAB;C@@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799664,&$" ('"+-"$.!3-&@DWH,G+55*2PKL# A9D4,'ÃÉÖÔ¿¡™«§ ®¢ž¯´°®¨¬¢§¥¨ª«©¤¦ ›¤ž¥§§£œ«™¢¬ £Ÿ¯¡œš’«¤´®® §š•“¦¢‘›¢¨  ¦±¦¦©²­·È²µª«©–‘œ¢˜Ÿ¥³™¡”Ÿ§¬­¥°›­«££ª¡²­¡©²°¡™¨§¬­³¡‘”¡¥–™{©lž„‡u«y|°o‚¥Œ‰Ÿ–– •Ò¸´·É²_`”©ƒ¥ˆ‡ z™•šxªÉt™¤”¨©’›ŠšÆÆyg¡‚¥tŸŽ‚}¯]o´b°uK£‡m§G‚“dŽ’|q™•q{u~|n\fjsqfk_aYdn\_YIMMKEDAB>A<B?I;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75685/)(%&%$&),4ENPPMFKJVF*L0/=-5OTQ;<F2,$§¤ÀƸ­©²¬¬¥¢›²¸«ª¡¥š§¤©«ª¦Ÿ¦¦˜ª£Ÿ®«¥ ¬šž©¥œ§µž¢—“©ªµ±¬›¥œ ”¥¬‘šœ§£¡ª§®¢¥§ª°µÃ±³ª¬¨”Š—œ¥š¡£®¥—¡•™œ¦¦­œ±ž®©§Ÿ¬£¶¬ ±¸®™­¦°±°¢’–¦¡˜ž‚NxšŸz„£}ƒ¤…‡¦ŸŸ”„¸{|y¹‚Ìƶx›¡‘‹ž~š–—ŠvŸ—Š¥—¤©°…† „¬}š•c¦m¤p…|–‚r¬`£rq€š`¼}RUtŽ’£—{~”“Œv{s‡€q]mnxrj‚o[d`iocd]KLQTAIHFI:9K?B108866877-*5==?BDGILNPTVYYZ[\__^]__\ZZZYUSOH@882.,*.+*''?QTVWWWYXXWUOUF<E3:P[T6?H,- ‹‡˜©«¤«¸ª® › ¬³²¥ž •¥­­®ª§œ¦§›£¨¡³®¢©¦² ˜©¤”£µ¢¢•—¢©´¸£›¡œ¢’¡±™žœ§¦¡¢°®¦©£¶³Å±­©¬©‘‡œ§œ¢¤œ¥—ž™šš¦¥«œ±¢¯¥¦˜¯¤»­¡¶µ¬œ³°¶¯°¤–œ®ž¢œ…ÑµÃ·y‡Ž…‘“€¦y”¡wŒ ’„¥‚Šqª†…µnriš¤œ•ŠŸ}˜™†‡s¯‚¦›£Ž¦‹“‹•›nq²]¥t“zœl˜{™|m©a¢qqŸbs²¸hw”¦˜}Ž•Žz}yƒnjyizsou^eeonfh`J[XX<HG@U4@F><*)63.013)&4:;<=>@CEIKNPRTVWWY]__^^`_][Z[XURRQF:223//++(@QRTUTSTVWWXXWUUUUQOQ[U%!2AH$)%’sŒŠ­¾¾¼¹´ž–§¤­´¡¡™”¢§¦®ª«˜¦£Ÿ¥¡ ¶§£¨§°£”«£Ž¤­£ššª³³¤œ¤œ¨‘”–®ŸŸž§¤¨¶›£«¤¶¬Ä°©«¨¡Œ„Žœ¢ ¦¢•™™œ™œ™§¦¨™­¨¯£¦›¬¦½¬”¼¯¬ž¡®±·©°¤™§¯¡¦–y¨}|°wŠ€¤¥ˆœm²p¡‡­|¡ƒ¨•˜€¬‰…®… •ª ¢—†Ÿš•€{’~«€š—‹ªw ’Š”’z¯^¤}¦§d|—rj¯]¤kp†™]`[Œ m•‘¦™‚•šŽ||„™€kn€ctn€z`hfqoihgCYa[=KT3U8BBC8$$3+''3, /6674359@CFIKMNQRSSVZ]_a`aaa]][ZWSPONI7042.*,ATVVVTTUTUUTTUTSTVWWXVUUQHFIJ#((½’šƒ¨Å¶À³žš¬ ­·¥£Ž›¤¢ °¯ªŸ¥ ž­™ž¹¡£« ¯©š®¡«¨¤–‰š­¯¬¦ž¥›¬—˜¬¡¡¥¡š¥¯™¢©§·ªÁ¯¤©£ž‹€›šŸ¦ž’”™š”›š¦¥¦›ª¬­¤¥Ÿ©¨¾¤–Áª©¡ ª°·©«¤²­¦¨—u¯~‹œ…‡~º­Š™e°e•­}¡ƒ§•š¬Š„°†§š¤¡¢‘…¡]lk³`­{{ƒ±mgn™™‰±[~µ\¤„kÈ¢dŸ€{»WvµY²|R®€z¬W€¡m—¨›Œ˜’š™|z‘ duc†xu}bjgqngfePUd[AV`>I(>9=4!",%2. *1/045799<ACFHJLNOQRTWZ^```ab^_\[XUPNJFC553./@UYXWXWXXWWWWVWWVWXWWXYZZ[\XWWGB;ҟ²±¶½º³Á²¢œ¬¦¤µ¨ Šš œ³³©Ÿ¤¡ž¶™¡´¨ª¬ž¯­ž«›•¯§¡Žˆ›Ž¯«¨¦¡¥™®’˜¨™¡¥Ÿš¤£¦š¡£ª³ª½¯¤§žœŽ}‹›•  ™‘š›’š˜© £š©®¨¥¦¢¤¨»žŸÅ¥£§Ÿ©²³ª¬¤¹«ª«”€©’£¯Ž›€‡¤—™‚€¸ÃºƒŽœ“„§—œ‚¬Š‚¯‰§œ›¦«‘ֽªb¤¿½}~£‚ƒ×»¸µ†–”„ž½¾„m£‚o«„lœ€z²°Çƒi«°¼¬wv¡¾¼s€–Ž¦‘œ’š {ƒ“ž|c~{egzƒ|alfkkcQa[Sj\@UbCN)=:4/$%2 $(0496677;>ACFGIKMNNQTW]a\__a^`[\YTQMHC?=A?5=SYYXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ»•³³°¿¸±¼²¢œ­¥¥²¦‹˜¥Àª¸²¨¢À§¨³Ÿ²º¨Ÿ­¯¥¦•”°«—Œƒ›‘®¥¢¬ £œªŸ—Š£’¦ž§››¡©¤™ ¢¬®ªº­¨£›–’|ˆ™‘¥›’‘˜™˜“©›¡™ª©¡ª§ £ªºž¨Ã¢Ÿ¬¡©±²§­§ž¸¥¬¬™svª¤¸†d‰ ph®‘‹nnw¤™Ÿu®™”p‹q–¨¤œ˜¯¤smmmf‹xon‚™pzjqigŠ˜–™rij…ˆgq†d]ˆbjoY\f}v¦_apneeŒ“¡™™š“™¡}‰‘˜wfˆxilz€zemdgmcKdXJkZ:QfER'K:+# #,)-2.5:457:<?ABDEHKLMOQSV\WZ\``a]][TPLHD=:AB7MXZZYYZYXXYXWWWWY]^^]\\\]^]^][[UW^©•¬³¨¹¸±³ª©¡­ž£²ª˜’¿³Åʾ·ªŸÁ­®¤¢¨¬Ÿº£¤®¬­¥–®©‹…––¬¦ª ¤£ ‘‹¤“§™©š—¤«¢—ž§¦¨°»«¬š›’’|„—¥—‘˜•Ž˜•©– ™©£›±¦¢«¹Ÿ¯À¦£±¤«®¯¨«©¥µ¢¬¶•Š¡©¦·‰–£™ˆª›‘•’©³™š¢ª ²–¢¡Ÿ¢¡¥¢•¬§““‡“œœ•‘™“™‘•…¥›™–Œ””Œ‡„~g‰~t‚us‡Šp§lz““‘€Ž•¢—š™¥„‰—tj‘wrŒxx}zjmedpeU`Y@j\HdbPY+F=+'!750.!%2(*699469;>?ABDEJKKMPPQXUWY^`ac]^TQKEC>9=@ASX[\YWXXXXXYXXZZ[\^__`^^^__```_YY`¦–©©¤´µ®®¢°£­ŸŸµ±¬È¾Æ»º«£¦Ÿ§Ÿ±©£¶§©µ§§‘˜­¢‹‡‰›§•¬¤Ÿ™¨Ÿž’”£—¨š¨š•§¢¤‘œ¨™¢¶º¨ª˜š|•‹ ”Š•‘–‘”—¦‘ ›© œ¶£¦«·§®À­¢µ¤®­®ª§§±¶Ÿ¬º˜‘¥£§¶¢’ž§ Žª Ž“Ÿ£«°š £°¨°—£ œ£ªŸžž—¬ž“š¢œ”–«šŽ™™—— ’ˆ¡ž—•‡“‘Ž•‹~e‹…u†tw‡‚sœj…’“‰}‹•’’˜”£”Ÿ™¤…‰›Š}s—s{Œ€s|joe_qj`[`ZndQaeQZ:GGE>2=>9/*&+)&&316668:==?AACIJGJKLMSSTUZ``iaeVPKACB:9EMV[^^[Z\[[[\]]^_]^_`abbaaa`bbbdb\[c—•£¦¢¯±«®£©¦¬Ÿ§µª¤µ½°­­£¤›|Ÿ¤²¤¥±©—›¸¦£”™ªœŽ†Š‰œ¢®ž¢•¨Ÿ ’–™›®‹©–©šªš©Ÿ¹·¤¥™œˆy“Œš“Š”‘”Ž’—£ŽŸŸ¨žŸ¸£ƒ¯µ¢®®t¢»¡°žvxž§¯¸“t«£ž‰«d\bv Ž¥Ÿ„˜}m’³¢§­ª£ežŸ’syš˜q™©˜m¢©Šeœ¦’—˜–Œ“œ‘†ž›‘–„“ˆ’‰…wjŽ†v…pz…`h‡‰“‘ŠZu”ghs|¨œœf{›Š…y™j…Œ„oz€kqe`wplki\febbqT[>NNNSG>@UD:1/&4:306678<;>@AAFHBGFIKMSTUY\`hfgWQJ<DG<8UR[`ab`^__`aa_\]__`aabcdabaaedchd^]f›•¥¢ ®¯««©¥¨­¢§­¤’–«¶±³§›«¨­˜tŸ± ¨«§”—¹  œ¤ž‘‰ˆ›žŒ¬™¢•§¡Ž—’…v­‰§›©’˜¥Šœ»´§ ™˜‹‰uw“–“‰“‘””¡œ¡§™œ±•€Œ›´œ²Œ’¹¥Ÿ}§¢y ¬µ¥žƒ‹†°ª¯‹—¤›z‹¬…œž¡¦¨§‡•…˜w¥›zˆœ—§ƒ‚{œ³zŠ†¡˜š•˜–‚‘——„›™czˆ…’‹ƒmpŽ‡yp€„}…s…ƒ”‘w–h’t št}™„£ ‰˜•†…škŽ‡ly|rqheypjlk\elkfu]^ITLR@E6.[UU7)!09>>743568;:=>>@DI?IEJLGSX[Y[bahfYQH9EL;>aV^bdfd`aa`bb_]`aabbbcfgcba`edcgcaahœ—¢ž¥¬¬«§¬ §°¦¦©¥™”¯È¿±¢—¨ª·Ÿ‘…ž­œ§¢ Ž¾žšŒŸš }†˜—‡¬œ¡–Ÿ¡‘“‰…€’§‡£ž¤•™Ÿ‡Ÿº²§›’Ž…qv‰•Š”›Œ’ ’˜¡¤–ž«‡Ÿ´‰´™­ŠÊ†¨¬ˆ¶…Œ¯®«‚¨Œ¦˜}¨s{wœ§—h•¤y´Œ ¥§’˜Â«ˆ˜¡rž€š¥~—…•³¡}¡“¡˜—”œ‹™’Œ}…“‡–’‰ƒms…~yq†€ƒ{ƒt„€•€Åf©‡£kž…¤„šŽ‰Œšq”†iyv|xhivrhhl^dpmgnYgG]RM3E57Nbd7&3<EGD:64658;8>==?BM?NJJLCPZ]\Wa^il\QE=KM@IcX]cfhgbbbbdc`_babccceiicbbbecafcbbi”–¡ž¯¦§¨¥«Ÿ¤·°©«¦š” £¤¬¥˜¦¬¹¤°¢©¦ž‰”¼™“¡‘žz„—–‘‡«™›œš¢„ŒwšœŸˆŸ¥œ—š™‡£¹­¤šœŒŒ~bmŠ“Œ˜Œ’ •¡¡™ §~¡§‡­Ÿ–­œ›œ„ Œ¨¬…£©™Œš¢u™”k‚­vM«x‡œ‘š§¦€©«}ƒ¡{z§jž’lg˜†˜·‰ž~n`dYƒ—€|dh‹r™}y–l]}—m_Rpƒ\_kx‚_Xd€|ƒ–p§ªkƒ£nr¥pŸ… jg m\pŽ~gZ`„cXQpwfnuskjp^kqnljYiO]YF9A5HE_l5,IDRMN=84859;6@;;>BP>QRLMBJ\]_W]^bu`MD:MONTa\\ffiibbdbddbab`bdcacikdbddgdbgeach—•œŸ¸Ÿ©£¦¬‘¡µ»ª®¢™˜¡¢¥­¯¡ž°¶¤©“¢¡ §œšŽ™´™‹ŸŒ•‹u‚”’ŒŠ¦••˜žŸ~“……¬¤‡›‹š«™››’ˆ¦±§¡•šˆ‰€inˆ‡‹ŽŽ‰‹’Œ“£”ŸŸœ¡¤“¢ “Ÿvœ”Ž§Ÿ¥~…§ª‚¥x‰|„š~¢ps”ˆ–|Ÿym†›Œ™š¨™Ž‡{‚¢sv¦fž~w¤_˜z}”t¢n˜·´ºt“ˆƒ€µ¨dÆ¸{p•¶Œr€š£cs¬«`|i³~m|†‚‹˜q£lr£tŸ…¤a™´—s}˜Ÿ³ut\ž²ƒkcpuwripYlmssg]j^bLE=D6RBZs3=SG`JR=<395::6D;;@JP?UMOQ@E__[ZX``|dHC8MWUWbaZefkkbbeadd`ab`dd_`cknccddhdbgfchh“–”¢·˜ª›“Ÿ¤·´¬­ š¢¤£¦¯œ³¯­”™¢š¡¥™š•Ÿ«›‹ˆ’x‹…q€–‰¡“”˜}‘Š¨¡‡—Ž‰“¤•œ›Œ©¨¥ž—‡„~j{‡~}‚‹‰”¡ƒ—ž Ÿž‹‰wœ˜¡ŒŸq¡Š†©‡š¤”¥¨|­Œ~z ™z£“xt–ˆœ}–Ÿ†›Ž˜š¥…¢d¡|ˆ–›mžh›Žoš™{€‹§}rit«ƒŸƒtªh•š]›…v…žgªk€¸f\¨pœ`•Œ^§vu‡ˆ~gšu†“’—Ž€Ÿoš‘n§š^©y»k~ª\Ž„]´h]nrzxlj\qkyzdagXbBRFO7WDRo5K[[_NZDA251<;7H?:CHU>YRY]>Db^V`Qac}jEB9N\^YdfXfgnmbbe_aa__``ec^bdoq`deekecihgki•›ˆ©³š¦ˆc”›«º±¯¬ž¦œœ© Ÿ¯œž²©®Ÿ˜¤›¡ ™—– £™†‰iˆ€r{—ˆ‹––„‘•˜z‹„•¤œŠ”†Ÿ“ž‰‘©£ šŒ’Š€€i†x–Œz‰ŽŽˆ—›”¢žŸ “˜rhŸ‰žŽ‹p’Œ€©†˜ ¤ž¥{°­£¢¸—w£³£¤€‰”y{«™~¢Žœš–ˆ—q¡|…¯µ}kš‘¡y~™µ£¤«¨„™|›}ž›tªZ]o{–‹xžbL{z…cy—BLŸX¢iq{Žl€ˆƒ™u›x†‰±³€›“§wƒžnt~•pštk¤^•vHedatr~ofaliw|eebQ_W]UW@ZFQhETW]bX^ID=B8@A:IF8LEXAWR[WDFb\Z`K`m}rEB<U_bZeiVghmobfg^aa\]^`hb_ecvl]egfkdeliiki“œ€¯¬˜ƒS^ ¦³¹±²¨š¢Œœ¬œœª•¢­¥£©Ÿžž›š–˜¡–ˆ‡‰w†oy•…‘›‹|‘“—ˆr‰‘¡›s‘‰š–¡›…ªœ›•‹‹Š|ƒl„…q¡‹x†ˆ‡“™–|“¤ ž¢ˆ­†}µ„œ{¥•y©€”šŽˆžš{§hwm~™t¡sr|ž†™p“ƒ®}£ƒ¥˜€£o^¨gu¢co¥aœÓ}{™xstb¢†~£t¤vk³Œ`‚˜‰sª²¨¼wƒm~¿¦©´]œm{p–mr¢q]¤gs¦`h¦m›Ôš~†›p{{˜lœ|x˜sn©¤gaezr€…lhfdovxhacS\fQRbHXJUaXT\fk\eQFCKMJKBKE8O@QNXSYOSQ`ffjRdwywIFEc^fZhjTihjocjg`c_]]]_hbaie|d^dgdkdjlfhlh—š¯«T[J~©¯±³¯²£›™…™ª ¢¥¦©¡š«‹›™™”™““¡˜Žˆ…{p}„h}ƒ•›w‘ŽŠo†“’l—”|Š“”¥—ƒ«›”’‹†‰yƒvˆ€mŸ†w€“†ˆ™£˜{”¢£™Ÿ‰³¡¢¶‹y¬§¤®¥o¨™…€™z¤¡™†˜rž„¤®¯Š—Œ€¤•‚­ “vµ¶µÉ¡s”‹Ÿ`ž—©mz•‡¡œu¢ˆw ~’—‹pMf£’pš‡s¥{ytaƒk} kqd_œq}s–hzi³µ³Æ¦r˜}zkœ›«v…›nwy˜jš|v˜sQE}³_jwlzˆgkhcuvqoW_TYiPSiJWMYTV^iloVhWMKAJMKHJOBQKPecjmetrsy|nu‰{{TQOl^i\kiRjhilglfce_]]]^ibdik{_]dhcjfomeile ›‡®¥ƒd?“¡²ª®®´¢¢€˜ª¢£¦¦¨Ÿž§„›˜—Ž—œ“Žˆƒzjy‡eƒ˜ yuŽ‰Œi„…‘ƒŒ…zŒ—¦”„˜ª˜Œ‘‹‰z€}‹xp¡†y‚•‡‰– –”¥§›••ƒfnxœl¢d{p¥w›—pe¦€”‰z¤yŸ–ƒ—sžwŠ•—¹n‘Š¢b}˜ ”ˆmriªku mo¦`›i‹i–‡›–u¢~š`Œ†upˆbh ež~i›uocfˆmq¢Y^Zb¡l]ˆ‹mz}sqd¥mx¢dg§h™sŒ™p¢pU‰p `f¨U‹^T˜nntlsƒnqikytkpRYWWfZTmJZP]IXiisjYlWQRFV\LXSbUik_xt{}p||rƒ{€sv€„v^RrbgcpgPjhhllnhdg_]^]`jbjivt]\chcjjslfkmcœ£—¥ydslŠ¦­£©°±¦Ÿ‹€˜¬žŸ§£¢œ¤£–™”ŽšŒ˜ŽŠ{‡q€ˆh‹‹|˜›st‰~{eƒ†”ŠŠ–š‚|‰ˆ˜¨’£­‘†‹‚‰~€€Žri¦„}‡“‰˜ ˆ“©¥œˆ¦x•›~¥ˆ–Š±—‚®–ž¤u“…x©s¥„šn¤¢Œ’„ƒ»n}¥¯ƒ†…†’•œŸ|¥zr¨• –gž~o¬d–Š–“w¨mª¢‰v‰ƒw«‘¦ˆk‘°kv³Œ©kŠ…mmŸž‘”_}«‹ªv}~Š¤vŸ|ƒ¤• j›ˆx¬hŸ®¶ux¾¤“Zƒ§Ž«ausur|uqckohmTW[Vab]lM]R^J^mow`[qY[`[gtenorbrt`xz~yryƒs„~{{Œƒ€vbxdcnrdRkgholrjfia_^\akbml{o\\bibljwmglnb•¤©›€£–©©¨¦­¤™Š‚˜¬›Ÿ¦Šœ¦ž«ž…›‡œ‘†’Œt‡{ˆ„p…~˜“tt†r‘ƒn‹‘‡†”}|ƒ‡™§€§§Ž‰…”v‚‡’nl‹©€ƒŒ”Ž‰Ÿ‰“©¢ŸŽt“—ˆ~x“®¢~šp…vŽ‰‚}{r§Œq~}z˜–›„y{~‡”•“Šv˜ž ƒ{~‰kŒ…[yyrzqin~’Šr€u”“q‡„ƒeŒ_€‹wus”uoynm‡lƒ†^ugwŽe€…¨š}t{•j‰ˆpv}‡wnnhtz|˜x…\lXyioxsrpxxp]l‡ojhW[`W]gkdWcU_R`pyymkwfkkkw}rrusaovbt{‚xuz‚u€€€y‹…ƒ}{nldyn^Vnghukxjiie\`ZcielqunZ[bldllynhkoaŽ“¶§¦Š ¡š¦£˜¥œ«¢¡„„˜­’ž¢Š›¨›ª˜ƒ‚œŒ—”‡ŽŠ‰rƒ|}~„{˜ts„q•…{|‘‹††…y~€‰›¥|¨¡‹……•‚†Ž˜vr„©†Ž’‰ŸžˆŒ›¦žŸªƒˆ•š~~ˆ–¬§Ž‘¥wn›Žxn}¨…q~•qkp}‚ €“Ž‹hl\‚‹‹›šžŽs•‹ˆqtk‚wtYrn‡‘‚~Œj]je{†„Š€`iy{›{‚‹‚u…gwŠ†j`oq€u^q‰€‰Ž¥“„e‹ƒnw‹„q†zqhif}…{–[]khnv\|zxvotsƒh]n‹llcZZ_ZYmr\`bZ_^ft|vpudkkk|}s|yudnuhm|~vz}{yz€~o…‰„{}t~ysiT\qilvpugkgd]aXjhkkqrnW[enlgsyohjl`‹Š¨¯ ¢ ™ž—ž˜¨£¢~ƒ™®Ž •ˆ£‘¦•€|™†}’™Š‰‡‡‹s~Œv…‹‚„—Šro€r˜†„~‘ƒƒ†Š{…œ¡‘ƒ¨¢ˆxŽ—ˆ”Š‹œ—„ƒy¬‚‘˜š•Šžˆˆ¡©ž¡¡£Š‡“›œ¢™•© ¦¤ž‘š…“‹zvƒ§~’“”²¦›•Ÿ±’—ƒ¥ŒŒ•šŸ‰‘›‚ˆ‘Šk|Žwxeƒ‡‘‹|‰ž„‡Œ‰‰……w|ztš ‰†Š‰„“~}Š€tns„}v…†‰Ž¤‚„Œ†‚ŒŒ}‡‹Š‘„zn„†~z™ksiat‹q~{xwpxu‚]^o‡io`_Z]]SirVe]]bmhv|}topekji€}ny€rjpqmg{s‚w~…zm‚Œ†|zx{}z„yNdvjsnpzekecb`[tepfrqmV^ltmhyzqgikeŒ‡œ¸ž–¡ —”˜™”˜¤ ž|š¬ŸŽ†¡Œž–~y•„|ŽšŠ‡„„‡nysˆ~‰”„mk~z—‡„ƒ~€†„†}ˆ…œŸ”ˆ¬ „rŠ†’‘‹‘}z©„Ž“˜—œ–‡†›¤ž¡™œ…‚’š™˜˜¦Ÿ¤œ›•~Ž‡tz†ƒ¥{}‘†˜«¡ž”Ž©€Œˆ“™ž‚—~†Žƒpx†ru`„†u™ƒƒ‡…†…•nyvt’¢ŠŒ…š„ƒŒs‰||qqz†‚zvˆƒ‘¤Ž„‚Ž€ƒŠ‰Šw†‰‹~rm€‚}oilnh^z€h~}wvwv{x]`q~nuad[]_RgnUf\^bkiw{rlmdkjhlt‚llupzp†yn‡v‚€}…vq‚ˆ~{||{‚Š`h{juhi‚djc`i\duhobumlUcqyepz{sejmm‹ˆžµ™ ¢Ÿ’‘•˜ŠšŸŸŸ{xŸ§‘œ‹‡¦•Œ˜™z{†}‰’ƒƒ‚ƒn|€ys€…~‹’}kh}‚—‰ˆ|}†„‡}ƒ‘“Š©p‹‹Œ’†Ÿ¡Š…Œ|§‘ˆ“˜”–“xŒ¢žŸ•˜~€š˜’‹™¢ £˜•™|‹‚w‚Ž† ~Œ|˜¤¢¢“š‘¦ŒŽš‰’–›~“’~‡Žut‚qwa~Ž†r‹—}‰ŒrŒ€ƒ…†ixrxŒ˜‘–~‡‰r†{{owz‰ƒyxŽ‹‚”£’Š„z††‡„v‚„‰‰}hs~z|rmlh_~si}vvt}t€k_`twqxedY__RkiVfZ`aijwz‚rgldlhf€kn~hoqly‡{lŒs€~‚tv‚†|{}irƒntia‡hlb_qVtoln`xhmWjtvcuz{rbjoz‰Œž°‘¤¤œŽ—†œ ›ž|w¥¡Ž˜€£Š‰š–y|†ˆƒŠ‰ƒr€{tv‚…~‹‘xgc}†—Š‚Š‹x}€Ž„y—ƒ–™˜Ž—¡›p‹‚‘“…¥›‡Œ‰ƒ¦•…“Œ—˜’’w‘œŸ —“–y~Ž——–šœ£œ—‘“™wƒvƒ•~‚‰Œs—£Ÿ¢”™¡ŒŠ‚–—ƒ’•™~˜|ˆvq~n{d}‹…q‡“€‘‚lˆƒ‚€‰…fvo{…‘˜‹|’x‹‡{†{zp}wˆ„x‚Ž‡Š—Ÿ”‚‹vˆƒƒ‚w|ƒŠ‡xazzuxhmfbjkxttw~r}cdasnusnaZa^[meSdYaailvz‡rckcmfh}‚liuhnpj€}‚zn†r€ƒƒt|ƒŒ~z‚ƒ~|mv‰sumeŠljbbuV„ipn`xglbjvpfy|zq`rl†…›¬–¦§žŒ—‡†Ÿ“—™~xª‹™z˜ŒŒ™y|Œ~}„|ƒxtzzt}€„€‰‹€d_}‹”‡„†t}~‹€~™†—•˜Ž¥¢˜€s‡{“‘‰¦ŒŽŠ’ ‘„’•—‘‹—žš‘r‘“ˆœœž¥—–‹“•q‹‹‰k„—™zˆˆ‰o—ž›¤”•‹Œž‹…‘œ’’•†™ˆ{ŠŠzqzlul|Œ~n†“ƒ•wpƒ„~‹€erj{–—ƒ~t‡‚x†|tv~|„{Š‚‹’¡xƒt‰‡}€tu‚‰…qb|v{r~pbpde|copwsyxtubw`plvnp]\`^^k^Q^Ycaint|Šl`jekchw‡ngmikmi‚}{xoˆt„„}t†‰{ƒ}z„}}Žry‹xxml‡jh_irc‡gqoewgnlazij}{xpaxm‹€˜˜©Ÿ£¨‰Š’†Š‹•™~x¯™—~Ÿ”‘—”ˆw~|Š}|€wx€€put|p†}Š|a\~‘†€ƒ‚rz€ˆ{“Š““”¦•‚}}Š‘£‰ŽŠ˜š†’™”•Ž‰ˆŒ‘›’ŽŒŒm„‘ˆž™¢ –”ˆ•l†—‚e„˜Ž“z‰„Šp–›•£“’‰‹™Œž}’Ž’Œ™Ž{Š…‡tsvlqnv}‹to‡‘“qu|‚ƒˆ|fqmy|™“|ƒˆt‰€s‡xm~|„{ƒŠ†‹”¦‹z†{~Š„w~qp†„fizuvq|c_qakt_qk{zzmsqfz^omsmsX[_`bl[PXYechrr€ˆg]jigbgqodjheiizwvpŽ…t‚ƒ|u‚ˆ…x…|x„…z‰w~‹{{sxƒjk_pht€kromrgole|cn€zvqlwwŠ~¢—¡§ ¦›†‹‹œ‡“v‚«•“Ž‡¡–”€t|w…xyss{†lsp{n‹v€‡op[Y~‘‡€vu¡‡’‹”ž™¢•˜yŠŒˆœŠ†’˜–…‰•š—Œ‹Œ‹›‰‚m‰‹‰œ–¡›—”„–†h‚¡e„›‰~‹ƒ‹w“™“Ÿ“‘‰ˆ”Œ~}Ž—{‘ŒŽš’|Š€‚ovplmoq|†jt„™‹qw€u‚‰‚ygsnu€™Ž{‡„y“yu‡rn‡z„Šx‰„€†š¡†{ƒuŠxxnk„ƒ_tutrry[_qapk_pk~|qnnknwappkrmYYbaboXQT[fgcup…ƒc]kmdbfk’n`gg_hkursq‹€uƒyv€‹€x…xˆ†wƒ…|†‹{wŠjqc|c†|nqmtjholvx`qy|tut€ƒ~¤•™¬ž§–„„—”ƒ vŒ ”“†‹›–Ž‹zrxu‚pr…trw‰lpnvmˆvƒ~€mmUQª”†ƒw~wrƒzƒ¢ƒ”‚–”™“›y‘{ƒŒ’£™“Ž‰”™’„‡—šŒ”‹‰ŽŽ†œƒ‰{r‹…ŠŽ‡œšŸš•“~’|fƒš…f…Ÿ‡‘„‘‚‰qƒ—œ‹Œwz‘zŽ‹Œ’–Œ|ˆ|€kvkoklm{az~—‚wz‚xƒŒ|zhtls†•‹}‡…{’qyƒou‹yˆ‹x‡|‰Ž›ƒ{zv‚Š|wpjl‚„|ayqomstV_pbrb`mozripfguuirlbwe]Wfa`sTQO]ge^yp‰}`\irbbff‘j_he[gp~plqtŠ}v}…€uu~Œy{…xˆƒs†…ŒŒ„|z”xfqkƒ`ˆ}ookz`jntu_t}y‡xts…}x ™°œ¥Ž‚‹ƒšˆ€Ÿ€Œš”…ˆ˜Ž„wtwt€qp…tpr„pljwnƒn}}mtrRM‚ßȒ֒{pu„v…¡„”x—’™‘š|”s…ž¡““Š“œ”†—–ˆ‡‘Œ‡›~€wzŒ~‰Œ‰œ›œš”’xŒte†…k‡¢„‘ˆ—ƒ†cŒ‘™–‹—ŒŠŠqz“ˆ{ŽˆŠ“‘‰y…|m|erokl{z\z{}€€†ŽzzisjsŠ‰…„|”Šl~~mŠ}Š…{ƒx“™˜Š|uwƒxsmgp€…nkupikunT_pepZ`msyhlkcgyspqd`xa`Vl__wQNLbgc]zqŠv]\evabfeŽdagbYissnkrwŒ}tz†‚uv}‹s†{‰~r‰ˆ‚Šˆ|~˜vesn|eˆ~opl€Ylnyys`vz{vrwŠwyž‹š®šŸ‚…wˆ•~}‹žˆ† ’…Œ˜„“‡uxpyqo„pmoseeyq}my}jgkc¤šÁÜ®ð rlv…w†¤†“o˜’–¡•œ‚’q†Š¢—‰•Š–ƒ–…‰€‰ˆ•}†zt‰w‡„œš˜˜Žu‰ul„‡‰|‰¢„‘‰œ„…^‹“˜‹‰Ž‹Š„ˆl{•}ˆ…‰‘†v…}~k}dxvjnysX‰{’ˆ†z†Œzfri‰‰‚Š•„kum‡Ž‚}x}Ž”‘—trw‡Œusqguz„cunqckwhRarhlV`ouzard`iqso[drabWn[]yNMMegb^wsŠn\]dy^`ee…`cc_YjsknksxŒ~tw„xw{‰qƒ„}~‰zt‹‰ˆ•†Œ~—shuqylŒ{ntqWqzvyrdwy†Œiv€‰rœ†˜§›£’„}qŒ”xyŒž…†¡|•€šˆ„{sxpsjp‚ljm}u_axw{qu{g`d|ëÚµÉÃ܇rlt‚w‹œŠkš‘ž–”‰q„ˆŸ„‹•ŠŒ˜”|“ˆƒˆ{‹…Ž€uxƒ„rˆ“›–”—…‹u†}nƒ€‡†—¡‚“Œžƒ‰aƒ”‡Š†Š‡‡i|“}ƒ„‰Ž‚q†~qwhvsjuwlZ|’ƒ†~„…Š‚vark‡Ž‰~~‘}nkw„Ž„z€{}‘Ž”ˆmpyŒ…tkpkry‚aujp]lwaResifS`qwuap`]h„rtkXhiciYnW\vMKMfg^bst†k\\ey^^dg{ad_]YkoenjtxŠ~st~{vzˆs…ƒ|ˆvvŠ†˜Œ‚{“ulwvyx“tnx{}Xy†qogxw’‚dv†…p‰–…™¡š¢Š‡to’Œqw~‹š‰Š} „š€xrtnodrifmxx\`y{{qq€jagaÕ¶‘¦wnqx}q”’Žˆk›Š“Œ‡{h‡Š™†’‘†‡˜Ž|‰{Œ}ˆ„zszƒzp‡€•™Ž““€‡t‚„t~ˆ‘›†•Ÿ~ˆb€“‡…ˆ…‹‚g|€~‚Œ~mƒ|ƒulmwutwvlcŽ‚€†}†€…‰p_qo„{Ž‹|~ˆzpƒeyˆ…Š€z„|}‘‘‚mny‹~umnkk{dilkZnwZSjsibQcsxmcf^Zk„ntb\h_em`oU\pOIOgf\hor€mZ\cs`\clwee]]Zlmcmjtw†€rp|}tx†x…‚}€ˆux‰“•|ˆ†vˆ€oxy{ƒ“on{w^ƒtmizt”sgsˆ|q‘ƒšŸ› †ˆvv”mw”˜ˆ‘„ŠŽš}Œšw}vqoljau}gbjuzZ`x|zlpecggW_rs–½Å…wr•‹‘€t™‡ž”‰sjˆŽ•€{”Œ„›Œ|Š†}|ˆŒ~“‡t‡…vv}qu†ž”†”Ž‚‚q~†s‚zˆ–›–†“€ˆf~“ƒ†„Š‰r‚~g}‹{y‡‹}i€}„vfpyxsxtlk†‹‚‹€yƒ„„€k^pvz}‹‡„{€Ž~r€hw…‰„w‚z~•ŠŽ‹|mkz‰|vtohh~we]rdYqtTTosibNhuyga^]YpptZec^knaqPZlSDThbZlon|pZ[^mcZcowdg\]`kjcljsw‚ƒqo~{tuƒzƒ‚|‚†v~‰–‘xƒŠt‡ryy~oo{qj‚yz~nm|v•kjx„tk“Œ…ž˜ ™…ˆo~Œvjy™€‚‹‚–˜Šy–oysqljd`t{i`fr{[ar}zfpzaedŽ±²wKbZ¥ÛҘs|’‘y—Œ…š’‡ol…’‘zy“†€„™Š|‡€yx‰Šƒ•n‰†qs}{jy†ƒ¥„’Œ‚~n}tw„™—’Š“”…ˆp{“„~„ƒ‰ƒnxh€…xrƒŠ‡|e|~„vcqs€izqovš†„‹}wy…{ƒk\o|r‡ƒˆ|„‡zˆq€mo‚…Œ‚‚qƒw~–ŠŒƒwml}„~vzehj~raZx[ZsnOXrtg`Knwub^\[Yu~toXg^fkq_oOXiS?Zg_[qkgzr\[YleYdqy_h]^elhfkiqw‡ol~up‚z€ƒ€v…ˆ—Šq‚q{…|zy„”Œukzlp~u}or|{“poxf‘Š‚¡™’ƒ†g‡„pgz—Š€…‚šŠ|ixrllf_aozn_cpy\dlƒz`pv_deÕ뾋3:>Œ€sz†ŠŽw…™Ž”Žnm…Œ‹u|…‚•‰|ƒxnv†„‚•vm‡„ku{ueyƒ„§ŒƒŽ‹‚|m~rt‚xƒšŠ‘’Œ‡{’ˆy€…Žƒl€ri€xm||Šƒxby„‚rdqinvru‚Œ€†sv~sp[k|sxˆŠ{†|ˆxypj†‚Ž‚ˆp€w}“‰Š}smjv€€uu\iiyqYW~T[rfM[srf\Jryp]\[Z]v€vjZb[hfocjNXgR>_f]^vf`uq[YUodZeqy[h^`fmhjkhpx~Žmj„yn{}‚zuŒ“…p€‹nx}€{{ˆ“‰€i{~jt|r†{sv~Œzx„~|k‹Œƒ›ž—Œ‚m~liŽ|~€ƒ”‚}Šˆkuqgic[cgso`bltahp‰zass^bc› n]6[°¶ukŠ~”‡wˆ™‡uŒŠwpm…‚†ty‰x‰}“ˆzsguˆ}|–no…}hvynez‰…¤‡€†Œ‰}m}t}{Š—†€“˜‰‹…Š|Šq|~†|i~mk€{yjzw‚‡r`w‚~rdrgvƒnu|†•’‚~ƒ€pwz|umWm}us‰€…v†t‚‰zwrl‡Žƒq}{|‡‡ymmhl‚tn\hfurR\}O]r]O\spdVKtykXZZZarvb^]agdijfOZiNAbe\awa\unXXSub[eosXj_bhkgmlipw|“li„Š}|p~{‚{w€€‰Œ„r{‡orwƒ{‰„j~{nxyvŠw}x€‚‡€ƒ~~zm„Œˆ˜£…„{v‹ykm…‰’y~|‚’€€~Š„prpcf^Yg_pp``hqfjo‰taso[`djv{¿¨¥Ê¹r†…t•~z‰•„t’Ž‡rspƒz‚su†tˆw”‰yyqcv…y’hqƒufvucj|„ˆž‚~Ž|q}r‚w~Ž‚v•”ˆ‚ˆ{‰Šlyz€uh{ilysizv€ƒ}h`w‡}kjth{jv’•|r|w|tbUu{qr‡‚{p†Šwxon‚‹}|w|zsŒ„€ugpglˆqo]hctoLfwM_oVTZtncQPuybRXX]brƒt]b\ieeckdR\qIDeb\dq^]xhVWVx^\fniWl^ajgeonhpwz“niˆŒy}s{~y‚‚}v}ƒˆ†ƒpvƒsnw‚‚~ˆ‹”q€|xzz‹uƒx‚„z€un}‰‹›žˆ~†{w‡|hu†‘z€|‰†„v€gon`e\XfYnsaaaqllh‰n`siY^cm€w©Ú©È‡ˆ³s‹zqv}‰‘{”‹€utu}vopm…t”†xul`y€x‡eq‚ngum[m}“€€x’‘|wzl…s~Šƒr•Š‘ˆ††{†muwmhwem|vmkww|abx†zhuvc~|hu‡Ž–}vvr€z}m€ZUq|os…}wkˆ†sxjs‚‚|y{wzq‰{rfsdm‹ƒlsZj`vfIooM\cXWVynbPSuwYQVX^as…p]acmec^ocU^sGCg`^gi]Z|cRV]v[[glbWk`anfflphpvxtkŽvvx}w„{t}ƒˆˆƒoququ~…ˆ‹{wx„|}…‡xˆ|}}„€{~rux‹ŽŸŒ‰{Šwuƒz^~‡šy‡„t†‡…w‰{bnm\b[[aVjtda\hopg‡qapfW\ck|Ê·º¢knoŒnr…s~†Œ{“…zytyttzjlvc„v’‚vpg^|€xŠ‡dq€jjqcXm{†œˆ‚r—“v}zm†oˆŠ†p–Žˆ†Œ„{yrrp~ghrcnxqjlrx}|y]ey€xiuyg‚whuˆŒ–~sˆjp~€xn}]Wo|ls~ˆz€nn‰pvfv~~€uzoyr…zxqeq`mŒkrWk_y]IplNXV_UV|kbOTvsRRTW^cv†j^akkfcZobYcqHAi]ag_\V|^OVfqZ[jh]Xha_rfjhqgqsv‡yn•Šu{x~yƒˆ€us……Žƒpo{xwuz†…†Œ†z|u‹}†ƒ„‡~~}†|xvyv‘”Ÿ~}‹nu€zd„ˆ˜†s’Šo……‚zƒudnjY_[]]ThsfaYdrrgrakdWZ_ix¾®{ ·ncuˆiu}s{…ˆ{~€wxswnzvejo`‡uŽsjb^}vxŠ‚ep}gkkZVox‹£…~p™’qvs€l~€†q”ˆˆ…‰…}yuspizajmamvjgkkywzwZf}}xer~n…tfv††—€qŒhl{‚tmub[mzjsz‰z€et‡}mpgt}v}~pzjyyxvodk`m‰}lmUj`xVLlmPSPiNY|hbOUvlMQTU_gw„g^aqigaWi]]ljJEk[ceWYVzZNWokY]le\Zec^ufleqgsptxp™…vx|†‡}vs‚‡•ƒnsy{{ss…†ˆ‰„y}v}…‰Ž„ƒz~‹ƒ{w|vv™˜zŠƒ‡iv~}m……•r‚q†‚~‚€pflgX][\[Seqe_XcsuivpdebW[[hpor€sŠefz€kvwtu…†x‚…zwtvnjzpahkg†t„nf^^{nyˆ|glwfjdVWspŽ¦|„{v–s{qzxlyzƒu—|ˆ†„‡„}uqsmhu]mi`mudggizo{rYgwuhp€x‚vbw…‹}•‚oŒkn{qese`jxfpuˆy|auƒvjkptyoyxr{e}}}vumcd`l†|ljUjbrTLklPMOqH^|faNVueKNTXakxf^gsje`WdXcr^LLlYdbUTUtWMYweZ_la\[de_wgmbojtoq~ut™x€x€~†„z}v‚ƒ~—…nrt|{tq……‚z‹vt‘€|•Ž€…„|~Œ†z~€v{£¦Šy‰†…lu}|v„ƒ{o†sz…}‚ƒunjieV][[ZScoe[Xat{jhmh`aX^Zi€ikp€hmbi{zkuuup‡‚z~wvnzhjyj_enhw„geXavh}†ynioff]UXoh¨w€z|xtn}mqtx~w”t†ƒ€†‰vjswhio\me^ns_gbjxh{m[mƒstjo~zxbw……y‘†sˆrpzrcqh[mudnq†zwas€pgiwsqkwvsub‚y}utocbbl}|kkUibgTLniPHSlFbyfbMTr^JMUZfmx{f_mqjd]V`VooXKTiXg^XNVlTK]z`\_l]][be`zhlaopvnowuz˜}w€y€€‡†zyzƒ}“„qtt~zvt…ˆ~}‘ls•{‚Ÿ…‡}€~†‚€Š{v„¬Ÿzˆˆ„lrƒ{v€‚uoˆn}€tŠ€jonedX_ZZZUbkg\Z_v‚i^ml\aW[\kert}jj^mxwiuxso‡|~~zvrlzhiwg]dshzw’€cbTcne„uvfhiaWVYhd¨o~w€‹ypn{fwmyŠzvŽq„~€‡ndwtehi]lb^po[h_muezh]t€nrkq{vvcu†Œ|‰ˆ€xrv~taplXpqano‚zscq€lamznjhyxspd„txxtoc`cms}ikTh^_ULudQHWbHcwfbLTqYKLXYilw{eenrfcZX^YwgUJ]dXiYYIWeQIcy[^_m[^]bd^ij`ntxmonvƒ—yr€}‰Œ†~vv†x†Œ}tuu‚yzz‚‹}…‰jt—{Š}~…y€{~|†‰sq®Œ{{‡~fq‰{t~}wsp†m|~mzcppbe]eVZYWdfl`]]t†hYpm[^XZ\l{bqwvmc\ouuivwro†yzwnotehte[gtfvv‘y_]Reeis|abi\TX^cd¥hxt‚…wlmxfwl{ƒyt‡ry}y€iewm`ga_j`^ukYf]oobze[w|knopxytues„”€‰ƒ‰{wpr}raxcZmn`nozseq€d^nuhcfwzrkmsq{qpa]dmo}diShYZUNz`RKZYHcudaJUnUJLZWjms{dlltcaYZ\bw\TLd^YjTWHYaNHkwY_an[[_bc]…ihbnxymojvym‚~€’ˆ„wu‰tŒ‡trvvw}}~Œ“~px–ƒ}™’y€€xy~s‡„sp™¡{{‰–yeu‰zsywltply|p’s^poagblT[ZWidnf\\r‰eSrm[YXW`lvcjujj_[ournutuk‡}|wonldipc[krdtvŽs\VSc_p~~p€\ac^SZa\d’Ÿerq…ƒskixknnyyzq€vs{z{dfvh^c[ah\_whWb_phawa[|vjjrnxttuiq‚–„ˆ…vskp{lfwW[ilaoq~xseo~[`ppa^ip}kjr}povio`Zdkm{afSfUXSQx]SPZRHdtbaGVlQIPZVlll|emora[ZXZmqXSPgXWjTUFZ]OIsvY`cncXaaa^Œjcemzyloivy†{kƒ}€„š|‚„y}ˆm†qovz}t‚‚}‹ƒƒ—tx‚”†Ÿ‰u€t‚p‡ƒvo¢—s{†Œ‡{fw‹on|pgxq{lsvsk^tobgfkS^\Vhbmm[\qŒdNom\VWUfishctee^[pwoqvvzlˆ}}ˆwscdkoa\nmcsx‡kZTVabw{|o„\c^cSZ`Zc–”cnp‚…‰rifxmdruqzkytuo{v_gsd\_WbdYbueU`amdaq]]~ohisqtquwlm…”ƒŠ|†rrgn{oqoRZdidoq~tsbmuUbqj[^ne|dku|pqqhl^Xcijx^fTdUWQVoXRWTPHes`bFXkOIYUWnie|ilykbW\V\ueTSWiRZgUTI[ZPNyw[_emjZba^^nbglzvnoivv~mƒ€}†˜{‡Šk“ˆrgt€{u€ƒ~‰ŽŒ“s}Š‘…‡Ÿ†{†Œs€†s}‚un¤Œs‚Œwxnz`e}qgztymmqwƒgd|mcgghS`_Ug`mp\^nŽhNjl`UVSogskfxef^Zrvns|ytn‰{€wœ{zkaelm^`ojeqy~gZUW_kwzzn‚^a]hVY`Xdœˆbkp†|vkiuk[upjyiurno|sYkn`Y^VbdXeqcT_biablZ`~kfltuomxwlh†€Š{ˆnqfp{lqlaX_ggmqrr^ilSeqdUbmaxaotztinji^W`fhu\dUaVTOYgSO]OPIep]cGZjNJ`LYme`xio€e`U^T^v\USagO^cUTK]ZQZvv]_fmhXca[^Žqchjxrsmgvty‚s‚ƒzˆ|ŠˆŽznŠtlstˆ…‡’„•z}Œ‡‘›„€|„rstwqn““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~~~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’‘‘‘‘‘‘‘’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’‘’’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ”ÎÚØØØØښ„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDCGdhgggge¢    £€dggggfo„ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ”Ûéççççêœ~‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR4555549\`____]‘¦¤¤¤¤§|]____^j‚€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}zzz|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹’—˜˜˜˜™™’Œ‡‡‡‡‡‡‰““’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†…………†ˆ‰ˆ‰‰‰‰‹ˆˆˆˆˆˆ‰ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z||{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘‹Ž‘‘‰‡ŽŠ’“‘‹ŒŽ‡‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…‹…‰Š††‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰ˆ…†Š…Ž†‹ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹}{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰ŒŠŽˆ…ˆŒ†ŒˆˆŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}}}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹Œ‹„ˆ‡†ˆ…‰ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ}wxz{zz|||{}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒŠŽŠ‹ŠŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzzz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†€{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{z{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰‡‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†……………„„„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰Ž‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{~~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““”””””””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••”””“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””“’“““’’’’“““““”••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘‘’“’“““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’‘’‘‘’’“ˆ…“‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘’‚‚’‘‘Žu†‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ˆp„|tˆŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒsoŠŠrx‡ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}~~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒwm{‚sx†ŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||~~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡sno„{uv€…ƒ„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\YXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxz}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzoq{xy{|{xw{xuwttvuuvwtb^d_akqfhklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkiffggghhb]jl]efgeccbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFFHIJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__ac_\_]`]^ZZjwlbnrjbYY_[XWSNMKKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{xvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSTPMJMNPROM[krkamtrfQQSPPNNOMJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTtsuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMN]cokXisupSMOPPPONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKKFBFHUbglopomlZLLNMNOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHECFGHMZghgrnnhfd`^^XLJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:;>IZ]Z\elnjommlkihkdSGEEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@:;><;;;=K[imnojomkjlmfQGEDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnppsttsqrvxy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;:;;99:88;<979;:=HcosmnlklhUC>CFDCCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqtstrqtxxy}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<:79::979::78:99=J`ssphT?:;=@A@=;;><=<@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyz{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>><==?@===?C;==><:Bl}j@:;>=>??A@??A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquutusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCDA?=>@A?@;[n@>DE?@AD_d;==;:=?AA??@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJKHVppqssttuyz{||~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???BFD><<=@=8::mwH8;:=>A;Hd=<=<8:;DD<<=<<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII`pprrrtuvz{}}|~~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC?>AAABA@YR=<=ILFEuvN788:;>?WjA;<<::;LR===9:?<=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC@CrzJ;\ƒz|wW<=?==>EhtL:=>?=<OhK@<8<A?>>A=;?B@BCB@BCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGEE?AGGFCFDGHJGC>Hloppqtuvy|||||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCEAGrzkbƒ„ƒ‚ƒ€}^>@C@@=Js{Y:=AEBAPn^TPHACCAA?>=@A>>>?<>@DGE@>@A?@CFECBCC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{{{}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@Ent}‚‚ƒ~}„vMACE@?>Y{€]?CEIJIThge_`XFMMFEEEDECA?@>>BFJJGEEGFFJNNKJIGGHKLIGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z|{}}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@EEhs}|„~y…rCDEDCWu†‡‡~XGHJMM\ihjebgZaNIIHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHHHGFEFFFDFHGEEHHFHGHFQnnpqruvy{{{z}}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJG`{€w„…ƒ„‰lAAVt‡‰‡‡‡ˆƒWHLNMfvohkilnaGHHGFHFHECDDFEDDHHCCCFIKKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrtwwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLLN[|‚‚ƒƒ…††ˆ„Vl…‡†††‡ˆˆ‡|PLMNlxvnmoqpQ?DCBCFFEB@>>@AB@BD?>?DFHDFGIKIJHHHGIIJJIHFJJJJIJIJJJFILLJJKKfopsrtvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKLKJTƒ„„‚‚…††„‚……„„†††‡‡†ŠuJIRtzƒwpmlnV;?;:<AA@><998<<=;>;8;?AB@ACCB@AADDBCFHIHHHLMLGIJMMNMJJKKJLMSlpqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHHJIIe…„„„‚ƒ‚ƒƒ„……†‡ˆˆˆˆ‰ŒgEYkoznloqsO696479;<:8567789787588;;;=@;999=<>;<=ACEHJMLLGIGORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@CGIIh†„„~ƒƒƒ‚ƒ„†‰ŠŒŒ‹‹‰Š‹Šgdjlceius<4873568:876565676767:67889:7578979776:<@GFIGIFEFOSRSSROPPRTepqsttvy{{{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@6788=:=ECBe…ƒ€‚ƒƒƒƒƒ†‰‹Š‰‰ŠŠŠŠ‹Š‹‹‡sqofgpr}e4688557699776765:9:::;798987669:98868589;A=>>BA?AKLOQPQOOORWkqrttuvy{{{}}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897;B:=q„€ƒ„„„„…†‰ŠŠˆ‡‡ˆˆŠŠŒ‹Š‹‡xsnosmqa9:;<9:;9:;::9;:9===>;;<<:>;9;;<;<;9:<8::::999<?<<ABDIJMKIKLWorsusvx{{{|{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<:89989:::;?>H~„‚‚„………†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹ŠŒŽ„wuyroo]BBAB>@CA@>=>>@???@?@==?B>@A?@?=@@@>?A<><;:;:9;?=;<==AACABCAXpqtttvz{{|}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::<<:;;==?@BR‚‚‚„…„…„†‰‰ˆˆ†††‡ˆ‰Š‹‹‹‹Œ{{vsqVKHHHEFHGECA@BECCABCB?@DHECECEDAFEFDEFD@B><@>=?@>?>?>?>>:;=<`qrttuwzzz}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>???=A@CDFW„‚ƒ„…†††ˆ‰‰ˆ‡†††‡‰‰Š‹ŒŒŒŒŒŒŒz{t^ORLKKIJJJIFDDGHFDDEFDBHIKGHGFHGEKIKIJKJCECCDBABCBDCCDDCA=;=@hpsttwwyx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLK@BBA98<>;<;>@?A>BBGGIY„‚ƒ……†‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŽ‰{zp\QRNLNKJKIKGDGIIIEFIFFELLMIJGGHIJNMOLLNKGFGGEECFEFFDEHHFCA?@Llptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?EGG=<@@87<;;=:>@>?@CFIIP_ƒ…„…††‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒ„zzxdPOMNLJIFJIEKIGKJIJGGGKLNLLHHIJMQNONLOKIGIJHIDIHHFFGGIGCBACTnpuwwyzxyz{||}~~~~}~}~~~~~€€€€€€€€€€€€€€TDAABGHB?8?@9:<8=>;=A>?ADHJLUqƒ„…„„…†‡ˆˆˆˆˆ‡†ˆˆˆˆ‰‰ŒŒ‹ŒŒŒŒŒŒŒvwtqURPMLIGDHJHMLGKOLKJJLMLOPNHIKLOQQPQOOJHJJLJKFGHGFFIFEEBABB\orwxyzyyyzz{{~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<9@>>@BGGAGKLPVy…ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹ŠŒŒŒŒŒŒŽ~d`h]WUQOMLEFGMPOPWUQPOQSRMSTOMSLPSUVRSQPLJMMMKNHGJFEHJEDEEBECcpuyyzzz{z{zz|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?==B@BBGVNFNPPTX{†ƒ……„…‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŒŒo_^odHUSSRK;;STR`u]UVTVYYRXXRZfPUWZ]RTWQOMRQPPQLLKHHJHEFIIIHIirvyxyyz{{|z{|}|}~}}}}}}~€€€€€€€€€~~SHJIHGGFE??AAEACGEDELXRMTUVXZ|†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ~aŠ‹‹ˆsbiY=[ZYTR?@WVY\d`VYbr]]W]ZVEQYZ[Y_TYgRVVXUTVTOOMKLJIILMKOMSotvxyxxzzz{zz|}|~~}~}}}~}~€€€€€€€€€€~~~VJJIHGEDDBA?HMIMPKIKPTSSXZZ\\x…„…………†‡‡‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~Œ‰‹Œ}ss[^]\SUSWWU[ZuƒYU}a\X]_WIV]][[_YHYXY[]XXYWRQMPQMMOSQQURassvwwvxxxz{z|}}}~}~}}}~~€€€€€€€€€€€xy}YNKIIHFBD@A:PQQWXPPOQSTTXXYZ[n‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—‰Šn†‰ˆ‡„‹€i\\][VWUXTRXVc–€RerXZW_hP`f[[X\gaGOZhg][\]]WROSPPRVVVVYZnrtwvvuxxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZ[RSQPRRRUSVTW_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†~€}`TX[VTVSRRMPMLfz[]TYUV]ZLTZUST^ZXWWWzkX[\\^TQQPINOWVX[Zdprvvttvxyy{{||}~~}}}~}}~€€€~~zxwvsu{€€tk~~kry^[VUSROKFCDAM^ƒlVRSNOQOQURSRRUcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡ˆzosZNNQQMOLJKEFIFC?TdURQQNKQTQMOYRMNQSUUMQSRPOMLHCIHRTUZ\lquuusswzz{{|}{}}}~}}}~}~€}}~~€~{vsw}~~du}iqt_d]^\YUQLILIal’tPQSNQRQR[RSRQRUTas{|€‚}z{€ƒ‚…†‡‚†††„†…†va^OGAEEDDCAEQCEAC>CIGV@HNLG]iPHFNFDEFIGHBDHGIKGDBAD@OQMSdrtvustuz|{{{{||}|{~}}}~~€€€||}€€€}vt{mh|gnqfiedb\XSQPURsWe[OONLQSPUYSUQQTROV_klrv{{xytrnstsyx}ƒ€ƒƒ‚€‚€ƒ‚lOIBB<<>@A@@?kQK`EFHIEB?GLNGMRUIBE?><=<==?=?ACC@?==B>JNGUnttustvxz|{|||}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QQZ\Y^JJPQNKLQRQTUUWQQWUPX[a]agmmlokg`nrjmlqu{z}{xz||xwxeDBBB>;CCBBDB\]O{NOONKLMOOQLKMWMHG@B<:77599=;;;8:8:?<BH?\stuuuvwy|||}||}}~~|}}}}~}xuvz{zwyxuw{|yxuywcqhipmnmmhf^OP_]ZIHPRQOMPQNQRTVXSSYTOYZ\WY]^^_e_]^qvk^`gkwooljonnlebYHGHHCBGIFFFDMROaWSWQPSSRU[OOQVPMIDF>:96587979:365795<C>essvwwzy{}}||{|}~~~{}~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`VW^ZXMKTTSPQUOLRSTWXTTYRMXYZVXXVXY]WWXhsk]Vatkaa_^da_^YUQNOOMIHJLJIFCQPSZWTTNQSYS\eUOSTRNKIHC?A999897885757859:Gnqtwxz{{|~}}|{}|~~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPXVVSTVOOUVXXYSUTLKTVUUUWPSTWTUR]n_RNZ`[WY;DVXT[fJLPSRONMNNNLJFQPUYSTOJNOUST\VRUSROMLIHHF??=:787659967675Wppswyz{|}~}~||}|~}}y}}|~~~}||}}~}|rvqxxrvuqqnppopuvtnjddjppqrpnfedc\]RTZWXUTWTRXXYYYSUOJGOPOOMRJOPOPNNOTLMIPOSTU2=XMI@Q=caQSQPNPQPNNMQNTRPSMILJORPRRSTQROLMKLLHCBA=::876;B5566:doqtwx{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqptuvcjgeWhtrrqnhihpVVTUXUWURWVUZYXWUQSFEAFGGHFJDHJIGEHLHJHFLMPMG/E_R>3?>joaSRQ@GTQPQPQNQOQPLJLLOPNNPQQNPOJLMMKGEEDB;=<<9=G6677Dmptvy{{}}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknaePSTRSTOWVVYYVQQQO@=;=?ABAC@BEDA@GHGHEFHJMLEGCORC8ENS]gTQSAGUPOQQPMMOMKLKLNOOQLOOMHLLIKKLKGFFED<AA>;@E;<89Sprtx{z{}||{y|zz~~|{uturvvz{xzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLONLQSLTUTXWULLKI<987;>@><=A@B=>EHGCEFIGJJ@FAA@FHEJOHQRb\QPROSOOPLMONLMMNON[WKMQOGIHCHJLLKFFFE?BC><BG?B?Adptvzzz{|{zzw{wy~~|{qstprswsxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCD=9779?B>;?B@@>ADJECGGIGIEBB?>=CBAGIDMObeQMONWKLNKLNMMLLONSdNJLRIIIEAHJLMNJGIGBAB@?EFEHDKnovyyy{{z|zwsxtx||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGMMJMPMPOHJD?A=989:?B?<ABAADEGKFCHHGGHCD?B??@A>CECKNRTLJIMTGIIJLJKLIJMMOPRPJGCLGCBJILMONIJIGCCCDHJMLIYrmwyxz{zy|vrpurtxyvxjqnjllnttmtu{stxrompovsnporpopstyjN`gsjt|ygosqiqhdqGKDGHHGJKIJKDFB=>=:9:;@B?=ABCCGFIKJDIIFGGCC;A@B>@@CECIMPHHKGHKDHJLMHJLHIJLKM]RHHDNFACJJMLPMKMJKFGGJNNQNLbmivvwzy{z}rmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoiktgdoFKDFEGEFFGEGBC@><=9::;@C@>ACDEIEIJLFIIGFFCB;ABC>@CDCDGLNHKNHDHEILNMGILGFGIILNKIGENHBFMKMLOMMNMKHHIORRSNRfffqosxu{z|lhjnekqlspfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGIDFFECCBE@DB>?>:;;=:<>CA>ACDFJFIHLHGGGFEC@=DDB>ACCCDGHIGMQIFFGKNOKFHIFEDEIJHKIFHOKCILKOLNMOONJJILRUUROWd`amgqroryzgehhdilgqlflmgiklslpvutpnvrosrsutqssutsuvvvyvutwljuumrvqlnlerLHEEHCBABD<BA>A=::=?;>>@B>@ADGJEIFIHGFGDCBAAFFCBBBDEDGGHFLQLIOJJMLIGHEGEDCIIHKJGKRMBNNLPNOOMNOKKKOUWVUSX_^\iaminhrsbdfedhhfnjfmmhkkmriqvtsqmvnoqrswsrstuvvvvwvwwvtwujsunutsqrjksMGHFHBBADE<A@@C<8:<>9?<?B@@@DFHEHFFHGFFDCECDIECFEBEGEFGGEIMKHQMJKHHIEFHHECIIIKMKOSNDQROPQNOMNPMLMSWVXXUX]Z]d`ibjigk_defcgggkggkmkmlprhttursnvoqprtxqssuvu‚‘yvvtxuuwxmouorsuqqinyMHGHHBBBFE<?BBD<7;=>:>:@B>??BEFDGDEHEDECDEFGJEEIGCGHFHGECFJJGNKLKHJLFIIKHEKKLMNORTOHSTRPROQMNQNMPWZVZYVZ]ZXa`a`^hec`dehgjhhifhnllnmqpiuuxrrpupppruvpusuwu{~}xvtwvvvxplupmstnprrxNHHGIDBCHE<@ECE=89>>=<<AB<?>AAFCFCDIDDEEFGGGIFGKHDIHGIGFDHKIGKHMKJKLHLKLKIMKONORUVOKUVSPSQRLOQPOTYZY\ZY[^^]`c^\ackb`dghr…hgifjmnponsrjtuxrsstrnpqvrquruus~yŽ}uuvvvvxrhuqkrtlqvptLIKIKFBEGE<@GCD@:<>@?>?BA<@>BAFCEEEIEFEGFHHFHHIKJFJHHKHFFLHHHJGLLMLLIMKMMMOLPPQUVWOKVUTRRQRLORRQV[[]^[\^^^``ad]c`ef`ehjdssfjggkorqossnswwquvtsmoruorspurvrtvuuuwvuwtgtrkqrkrvnvJKLJLGCEDE<@FDDC;??B@@@DA?B?ACHCFFGIFJFGDIHGIHJLHHJJILJFJLHIKJGKKMMJJMLNNMPKOPRTXVMMTUTRRQPMNTSRW[]^_]]`_`aa`acebdhbdijgv‹ljigmosqpqppryvruutsmmssmqrotutrpswtuuwvuuteqskpqjrunwKLLLMGDCAD<?EEEC=AACBBCDACEAAEGCHHIHGJGCGJGHJFIMHIJMKNLGKIHKKNQKRQMSMKNNOPPOTOWXX[NRPW\ZRWPNTUTTXZ_bb_da^`b^`eaacingbihhnxvlhimosrpqrrrvtsusssnksqmprotvrqquvuswywutucmtkopjqtowLNLLLGEA@D>>DEFC@DBEDDFBCEGCCIFCIJJIIKGDKJGIJIILHJJNLOKILHJLKZfJd\KlSHON_nUks[qpbwcSPavuhucav`Xnqbdvinzf[lt`ljT_wvijghfglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqrqyLNJJJFC?@B?=DEFDCDCEEDFBFFGDEKFFJMLKLLGGMIGJKHKKIKKNLMLLLILML[sbdp^lmUMNfs]ffqlntgpi_aYnnbppbkjjfoqtetno\ougpMJqyvka`keemxlkvlmpsrprqpqrqrrrtrmmsnnopsutqsstuuutwxvutbmukpplrrqzKLIHGED?AB@>CFGCFCFEFEDCHHHDEKHGLNNLMMFJNHJKJILKJJKLMNNMMJMMN[roonpplkMPQlWMibtrpamnu\YlP\nmZqmkomxxtsip]_rkqjUuyxoc^kfbgpojjnoprspqpqqrrqqrrtlmrmnnorutqtrtuutuuzvutenukpolsrryIKGGEEEBBB>@@FHCGDIFEEBFIHHEHLKGMMOLMNGLMILKIJMIKJJKOPONLLNNL\hdu]lqWlNPQmTYk^klvaldsSecNmYl\tpkilxjwuhp]^rkhWbcw|oc`ggaditxknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtvHLFIDEECAB=BACFDHGLHECCHKIHFJLLFNLLSRLGLLHNJIHNHJJIHNOMNLJNMJZsppoqqmlOQRnYrkgooqqomt]nXat_nopoqronusttj[^tcwxrjnzhaacfbbimtupsuvsqppqoqt{~}wlkqnlmnprsqttsuutxxyxtukoumtonssvsHKHIBEEEAA>DDBGDHIMIFCFJLJGFKNLFOJKWRKGKJJNIHJLIKJHHKMMMMIKKKSkc[i^_icrrZ_Yjn_eeUk_c[aaQ`lh]j\niid[pfdp]Z\k[mqcpsldgcdg``jmqpntyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunvqqvtwrGGFIDECFA@BFEDGBHJLHFDGKLIEFJOLIPIL[QJEHHKMIHJJKKIHIFKKKLGHKKLMMLJKMNT[\TPTLPONOOVQONQNOQJJOPQdqiTYW\[\VY[]X]\\cfaaebcf__fknimtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyxxuvqruovrtsuusGCEGEEAEC@DHDFGCIKLHFDGKLIEGIPKLOKLWLIEEHIJHIKIMJHFGGIGHIEFLIJLOMJP\W^P\[`^MXYS\\b^MXZMXaRKYaZR_d\aX[ddVVX\YZX\VY\]b^d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtrxrxsqrurtOBCDLMBDDBEIEGGFKJKHEEIJKFEHHPKMMJMRHGEAHFJIKLJLJHFDIFDFGEFKHCJMLLU_Y`X`a[`TXYT^^Z_RY\P^\YN^\^SZ^c^Z]`c`Y_c[`^[TXWY^]cbcacehekrpoppnow††……†‚{€……††††…uqprrsvyyzyyxxxwryvxrqxvtvaRJJMIECBCGHFHGHKJJIDFKKKEFIJNKNKHLNGHE>GGLIKLKKKIGDHDCDEAFJEAKLJO[cY_^a_RTRW_`\]Y^QY\MV_WKQY[PZ_aa]^ca`bbbcceZQYUU\Y]c`__cdbhomnllllu…„ƒyu|„………††……††ƒ}wrrtxyyyy~}yuyvvrnzwvxYQKFDGEBEGIFGHHFFIGHGHKILDDKKNMLKHKJHIF?GGNKKKMKKKIFGCD@DAHIC@JKHP]aZ[d]_TQRX]\\\_ZKW\LR\YIM^QO\_accccb]dcbdcfXQVTQZWZ`_^^aa_dlkmjjlnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMC@IFDFKJFFFHGGIGFFILJNFDKKMNJLIKJHIFBHHQMLKOMJKIGGED?ECIICCHGET]Y^X_Y_[]UXXP]]QKJV^X^[]UYaRQ__bb``bb`cbaddbXOQPQZR[]]]]^__dhgljnnp{{|~{€‚ƒ„…„…………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKCAHFDGMRHCQJEGHHEFKJMPEFIJKNLLIKLIIHDHKQOMMPLLKKHICDAEDIGCCHFDWUE\T]SV_XOTUNZZMIJT`a[_X^^a]NXa\``_bcb]abW__TPOOOWQ\[[\\^_bffeleoow|{€{}€„„„„„„……ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~JNFDFFHDIRbPCV^IGGHDFMJPPEIIJKNLKKLKIJGEJNQQNOOMMLMHKADACDGDCCFGBMHBKKOONLFMFGIJHGLKMOPILOPOSPKOSRUZYWYXXdWOSTPPNMNTRZXXZ]\`adecgcklpsryy{z„„„…„„„„‚„€~{ƒ}{…„†††‡‡………„„„‚€}KIEEHFGDKM]LFGXLGHJHGMLQPHKKKKMMUNOJJKGGKPSSNPOMNNNGKF`ED_LEgdFN\I^[rmOMUmYLDP`UkWgJ]WU^DLQULLSVQRTXWTXUT\UPfZhhdXRjRVUT[\[``abab_fhfnkhrz|}~„„„„ƒƒƒ}|zr{z{‚€ƒ„„……„…ƒƒ~z{LIEGFHEEKOSIJF`SHJOJIOMRQLMLLORUROOILNGHMQ[YOPPNOOOIJQQI|YYrtYQmHqnoaVPqqsPCksmqspSo_ZnX]V\XUkhU]VcZ`Y[_VVXjtuu^_v^Wa[[f[_`aaa]_agmpl_pwtx‚ƒƒ‚~}€vxzlv~tx}€|~€‚„|€ƒz~wwNJEHMNBDLLFIKEQULKNIKRXWQNNOMQTNOQOKKNGMPS[ZTQROPPPJHZx]TxehZSURvgtlpbnfjQrOMwmjrpsrqrooo€]ezuxqqzq~s}ku}bRh|essorr{|o~xn€r_``baZ`_gknkblfgmw~€‚}{xw€tvzir~ns|~wx{~€ƒx|€u|||ssNLG`]GAEMMHJJGIONMMJNV^YULQSNXZMSSRMKOHQRTYWWQTPPPQKHgxlcxrm[KNVypumubovPeeIfvqmwo€jfxwiWrQhzmijzz}lxzohoYvvjvup€_rf}ilx|o^__baZ]bdgiidgbcdllppstssszqrxblugry{srvy~suzn|}yxrnNKSuNCBFPPHJKIKPNNOMPZ`ZWKTWPa^RVQYRLPISTUXWWPUPONRJKrouuquqdibWnLqp^FhyWvTLiy}x`y{sna]mocRgqunmypwlvttrln]t~zkmy|ktl|kpvux^__b^\_ddiggee^abiiijknokqomjpacfcowxompsynqpk{ztromLL[VHGEGRPILMJKPQPPPPW\YUMUYUeXRRY]SLNITTWWYWOSNNNQIRmHiwK`dvvVXlOnl{sajgvULWkh}lmlx_Zpz{^`zscroxqhd}ir|^TLl_vukiu{zm~xk|p\^^b[^addfeeebZccikkrsrvglihdgaakagsrlgmmr}kmhk{tmmkmOHKKHJHHQPLNOLKRRROSRWRVTPWZVVUTTa_PNMJTSTQVVNNLMOPKHQNPULKLSTTSTPVUQQNQQXYRNPUTXXX[[URSW[WXWZOSUWXXR^YW^WUPYRWWWWX^Zgr^[[Y\]_cZ_ccdfdccbZcbgfemnmueegcaf_]g`dlhfgkhpzhggjujhgilPIKLLMKJSQMQQOLVUTPTUXUZUQZ]UUTWUYWOOKMVTQNUSNOMLQPLJRQKQMKLPRUSQRSSIHLNOQRQPQTVRXW\WSRPRTUUSZQNSRXVTYWUZVTRVTTUWXV\Y]`][ZZ\\_c[]bcdfdddaY`acabhhimbad^_c]Zd\bma^fefmsdigjkedcfhPJKLOOLMSPNSQPMXWUTUWWWYUS\`VWVYUXRPPJNWSPNUPNQNLSPMOUSNRNMOQUQUQRTUNKMOQTTRRQVWUYZ[YSURTWVVY[TPTUXUUZVXZUSRXVUW[XY^\UX^\^\[]``][bbcgfedbX_ab^`gdfea^_]]^ZZ_Z_g`^]]bhkagfgfd`bcbOLMLQQLOTOOSQOQ[YWWXZYXYV]jdVXYZWVSSOJNVTPOTPPPMMRRPRXTQQOMPTVOXRTUUONMQTUUTTRTWVZ]\ZVVQQVXV[[WQTVVVVYTXXVSRYWVZ^Y\^^U^\^`\[___^ZbbdhgddbXa`b^^fcc`b]\\\\YZ[X[a\_]\_b__bdebd__`\PMNNRQMRROSTQOU\ZZW[[\XZ[dqmhd_[XUUWQLMVSMNROQROLQSRUZUSPPMQXWRWSSSXMOOQTXVUUSUYX[^][[VQNUVU[[WRSWVWXVTY[UTRZXW\^Z^__Ta\`a]`b_\`]c`cghdf`Yc`a__ed_`b[Z\[\YZYXW\Z\[`^_[^^a`_c\Y`[QNONVQPTQOTTSPW\\\X^\^V\^jqwy€c\[UUWPMOVSNQQORTRLRTTYZWUOROSXWTSURRZOPRRV[VWWSVZX\][[]VRMTUU[\VRUVVXYSUZ\USS]XZ]^\``_Va[cb]ad^\bab^cfidf][d`a``ce_b^YZ^[\[XXYWWZZZa\][]\\Z]`W[[ZPOOOYPUTRQWRTP[^^][`\`U\]hjr}slg[TWWQNRZSRQTRTUTKRWV[ZZSOSQVVVTOWRSZRTTTX]WXYSX]X^]YZ]TTNUVW^[XRUUYYYUWZ\VSW^Z]]`]bb]Y_[ea_dd^^cca]efidf]]da`aabd`b^XZ_Z\[XXXWW[Y[`\[[\[XZ[^V^Y]QOORZPZTUVVSTT^^`^^b\`U]^bkytl}kZTYTPPS\TUTUTVYWLR[W][]ROUSXWWTPXRSWSVUU[]X[YUZ^X_^Y\YRVQYXY_[ZTUVZYZWXZ\WU[^]^`a_cc\^]]eaafd^^dc`\gdheda_da`a`bb_`^WX^Z\\ZYYWV]Z]^ZY[\[WY\]VXW]SOPVYQ]UVYWWUX__aa`c]_U]^beeuzhWXYSUSV\XWWVVW]XOU]Z^]\TRXSWWUSTXRSVTXWX]^X][V]_X__X\VQXTYZZaZ\VWX[Z[YYZ[YW^_`_cbadd\b\`fadfd^_dba[fchecf`f__aaaa`_^VU]Y[\[Y[YX]Z[[XXY[YZZ]_]TY]UNSYVS\TVWYVV\`abc`c^_V[`da_zuohYZYUWTW[ZZ\YXY`WPU^\``\TTXPUWVTVWRSUWZZ[_^Z_\V__Z]^Y]URXWYY]bZ^WX[\[\\[Z\ZZ__``dbcdebdZaecffe]ab`c]bcidcg_g^aacaa`^_XT[ZZ[[X[XX\[Z[XVYXW\[[`]V]]SOVYVVZUXUXWX]_badad`^YYadb`lfh^\\ZVWXY\\]_[Y[bVTX^]ac\RVYPWWWWWVSUTX\\^``]`\Wa^[^[Z^WUWW[[_`\_XY\\]^^\[]Y[`a^`dcdeefbXcedhgd^c``ec\eidei_f]cbcaa`__[XYZYZZXYXW[[Z[WXZTY]\Z`\U^bNSWYVWYX[\XWY^`badada]^Yacb_a``^\\\WW[[]]__\Z]cYZX]`cd_RXYPWWXYYWVWV\]^`a`_b^Ya]]^Y\^YXUV[\`^]_ZZ^]^^a]\[Z\`b_becefefbZdffigb_c^afdYhhbfice^bbca``_]]ZX\YYXXZXWZ[ZYWXUU[]]]``bbxKXW[YV\[[]ZW\]_`bdaba]`Xbcbacab][\[XW\\_]`_][`d]\X[becaR\ZOYXZ[[ZWZY`]`bb`ac_\b]_][^]YXTX]]_`_`\[^^`bc\\X\^`bbcedfdefd\efgifcab[cg_\ihbhied`baca_`_\]\Y\YXWXYXW\ZZWVXOXZ]acffrkJYW\ZZ_\[^[X][^_acbaa]b[bdb`bbb\[[ZWXiq`\`_]\ac_^YYcedaS_ZRYX\]][Z[[c`bbc`bda`c^`\^^^YXU[_^]ab`^[`abfc_]T]`acddfegeffe^efhhgdd`Zeg]aghchhfc`bacb___\][Z[YXXXVZV\[ZVVVMXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡„‚‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vvvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{zzzzzzz{||||{|{zzzzz{{|||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vvvvvvvwwvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyyz{{{{{zzzzzzzz|}}|||}|{zzzz{{||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚‚ƒ‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||upooooppz~}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ¼†‰‰‰‰ˆÌÓÒÒÒÓØZ%****"ŒÛÒÒÒÒÖº}~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}upnoooooz€~†“y1333332j‚€€€{­éääääèʉŒŒŒŒŠ”ÝæääååëTïååååéÇ}~}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}vuuuuuuuvwwwwwwxyyyyyzxopppppprrrrrrrwzyyzzz~ƒƒƒƒƒ„||||||}ƒ„„„„ƒ„xssssss}„„„„„…‚|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚ƒ‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vvvvvvywvvz{x{xwvwzxzyy}zyyxxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{yyyyyyy|}}}}}}{zzzzzz{||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwvy}{{}z|{xwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰Œ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwvz}|{~y|zxxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒ„‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z{xwv{}|y|z|{wxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzyz}{{|{}{xxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyx{xzzy{yxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyxyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†„ƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{|||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}|||||||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}|}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚‚‚‚€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrsuuttssssrrqpoooopqsssrrrrstttsqqqrstttttttsstsssttttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqsttssrqqqponnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqrsssssrqqpponnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrrrsssrrqqppppoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpqqqsqrrqqo|‚oppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqqqp‡†prqps˜‚npppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqq}¡‚pro‹ž|nppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsqu‹‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqqu¡wqwŸœ}oqqqqpppppqqqpqpppqpppppppppppppppqqqpqqpppqppqqqqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrrq˜¨o‚£~pqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxwwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒƒyrssrrrsrrssssrstr“©¤yˆ |rsssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~€~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz~|~}|vvwwvuxzxxxxxwxyyŸ´©¤¨¨—}{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~|{|{{‰¯¦¡µ«¬£~{zzxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}}}}}˜¥–¡² ™§“}€}}}€ƒ‚€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€œœŽ ¯ Ÿ¢Ÿ€€€~~~€~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~€€€—šŽ˜±¡˜–œ…|~~~€~~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽŒ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~€~~€~~Ÿ«¥–¤››– Ÿ†~}€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹Š‹‹‹‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚ƒ‚ƒƒ†Ÿ²¨¢ ˜¦¨­¨ ™‡€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒ‘‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒƒƒ† ­±¦›š ›žœœ¡¤£”‡ƒƒ‚ƒƒƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒƒƒƒ‹—™—–˜ š™š—‰††‡††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ„„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠˆ‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„ƒƒƒ…„‚†Ž”“—šœœ›”‰‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž““’ŽŽ‘’‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„„ƒ„ƒƒˆ“Ž”˜’‡ƒ‚………ƒ„„……ƒ‚€€€€„ƒƒ„……„‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘“‘ŽŽ‘‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€‚ƒ‚‚‚€‡›‡‹‡‚‚‚€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„„„„…„…†’“‘ŽŽŽ‰‰‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~€‚‚€„ƒ€€€€ƒˆŽ€‚ƒƒ€€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“‘Ž‰†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚‚ƒ„‚‚„„‚ƒ‰–ˆ„‚„‚‚Œ•‚‚‚„ƒ‚‡ˆ‚‚„ƒƒ‚ƒƒƒƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘Œ‡…ƒƒƒ‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒ€ƒ‚……„„ƒƒƒ‚„Ž™‹ƒ…„„„‚€‘™†‚‚‚„ƒ‚Œ‘„…„ƒ„ƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”“’“ŒŠ…„„ƒƒ‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~Œƒ~}|}ŒœŽ€‚‚‚„””Œ‚‚ƒŽ›‰ƒƒƒƒƒƒƒƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†””’“’Œˆƒ„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~•—‰€}}}}{˜Œ€ƒ€Ž”Œ‚‚‚Ž¡¥ ‘„‚ƒ„‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“’Š†ƒ„ƒ„‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€€•ŸŠ~~€}‡‹~„„ƒ„‚ƒƒ‚‰…Œ‚‚ƒ‚ƒƒ‹’™¦¥—„Šˆ‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†„…ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„‘¡ŠŒ…}†‰€~………„…‚}}}‚„ƒƒ„†”•’˜  ˜”†ƒ„„„ƒ„„„ƒ„ƒƒ…†………„……………„…††††…………………………††…†††…†††‡†…………ƒ„„„‡“““’’ŒŠˆ…†……‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…ƒ‰‘ƒ„‹…‚~}‡†ƒ€~~~€ƒ„ƒ„‡˜—›˜–™˜š“†„………„…„†…………†††…†……†……‡†††††…„……………„…†††‡†††††‡‡ˆˆˆ†………„……†”“’‘‹Š‡†‡†„‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„„„‚‚‰~}~…~€€„…ƒŒ›‰™™–”“‡††…†……†‡‡‡ˆ†‡‡†††‡‡‡††‡‡†††…ƒƒ„……†„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘”“‘‘‹‰ˆ…†…ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒ„„„ƒ€€€„„~}~€€€€†„–™€}‘˜˜—•ˆ‡ˆˆˆ††‡ˆ‰‰‰‰ˆ‡†‡‡‡‰ˆ†‡‡‡‡††…ƒƒ„…††………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†……„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡†…ƒƒ…„„ƒƒ€€Œ‰€‚€€~{z€‹Ÿ¡“š›—•’‰ˆŠ‹Šˆˆˆ‰‰‹‹ŠŠˆ‡‡ˆˆˆ‡‡ˆˆ‡‡†‡†„ƒƒ…‡‡‡†……„„ƒ……„……†„„„………†…†…ƒ‰”’‘ŽŠ†…†…ƒ‚‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡†„„…„ƒƒ‚€€€„„‚‚‚ƒƒ‚‚€~}}}}~~|{{•£œ›¡¡Ÿ‚Š‹‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰††††‡…†ˆˆˆˆ††‡„ƒ‚„‡ˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚ƒ‚„ƒ„ƒŽ“’‹‰……†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„……‚€ƒ„‚ƒ‚‚ƒƒ~}}~~~~~~}~}}“•– ¡›”‡‰ˆ‡‡‡ˆ‡‡‰‡‡†ˆ‡†‰‰ƒƒ„ƒ…„„……†ˆˆ†…ƒ‚‚ƒ…‡†‡††„‚‚ƒ„‚ƒƒ„‚‚ƒƒ„ƒ„‘’ŽŽ‹‡„††„‚ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…‡ˆ‹Š†„†„‚††‚‚„„ƒƒƒƒ‚ƒ}|}€~~~}|}~|z”™›šš•Žƒ„†……ƒƒ…„„„„„„…„‚‚‚„„‚ƒƒ…†…„‚‚‚‚ƒƒ…„„„…„„†ƒƒƒ…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰…„…„…‚ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€€„„ƒƒƒ‚‚€}}€€}~~}|}}{zzƒ‘Ž•—˜‚‚~‚ƒ‚‚‚‚ƒ„€€€‚‚€€€€‚ƒ‚„ƒƒ„„‚ƒ„ƒ‚‚‚„ƒ……†‹“‘‹ˆ……ƒƒ„€‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€€ƒ‚~~~~}‚„„‚ƒƒƒ‚~}~€€€~}}}}~}|z{{†Œ‘”–…€€~}€~€€€€€~}}€~€€€€€€€‚€€‚€‚€‚„ƒ†’ŽŠ‡‡†ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€ƒ„‚‚ƒ‚ƒ„…€€|}}~}}~€€~}~}~€ƒƒƒ‚‚}}~€€€}}}}|{{{zzz{‰’‰~~~~€~€€€~}~~}|~€~~€€~€€~€~€…’’Ž‹‹‡‰…„ƒ‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~~}~€~€„ƒ‚€~}~~€€€~}}}}{{|zzzzyŽŽ”Š‚~€€~€€‚€|~~~~}|€~~~€~~€€~~~~~~~}}}}…“’ŽŒ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒ‚‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚‚‚€ƒƒƒ€€}}}~~~~}}}}}|||{zzzzyƒ‹””‚‚€€€€€€‚‚€~€~~~~~€€€€€€~€~~€}~~}{|†“‘Œ‹Š‡‡Šˆ††„„‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…‚ƒƒƒ…„„„„„ƒƒƒ„‚‚‚‚‚~~}}}~~€}}}}}}}}}|zzyyyz‡ˆ–‡ƒ‚ƒ€‚€‚ƒ‚ƒƒ‚€€€ƒ„‚€€€€€‚€€€€€€~~||‰”Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…ƒ„…„…†…†††…†…ƒƒƒ‚‚€}}}}}}~~}}}}}}|}}|{yyyyy|‚„‡‚‚„ƒ‚‚ƒ…‡‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚‚ƒ„ƒ‚ƒ‚‚‚€€€€~Ž“Œ‡ˆ‡ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€~}}}~~~€ƒ„‡‡„†††…††‡‡†‡‡ˆ‡‡‡†}€€€‚~}}}}}}}}}}}}||~~~|{yxxyyz~ƒ‚Š„ƒ„„„——ƒƒ„}~‚‚ƒ†ˆŒ…ƒ‚‚„‚ƒƒ‚ƒ…„„…ƒƒƒƒ‚ƒƒ‚‚‚‚ƒƒ‚‚‘‹ˆˆ‡‰‡††„†…„„„ƒ‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€€~}~~€‚………‡†‡‡‡‡‡ˆ†‡‡‡‡†‡…~}}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yyz{}|…‘ƒƒƒ„„”“€~~„‹€€€„†‰…„‚‚……‹‚‚……††„„……ƒ„„ƒƒ„ƒ„„„ˆ’Œ‰ˆˆ‰‡‡‡…†…„„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„ƒ…„~}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|yzzz{{‚€ƒ‚€~}{ˆ‘||Ž–}‚†Š…ƒƒ„ƒ‚ƒ‰~ƒ„……ƒ„†…„……ƒ„……†„„Ž‘ŒŠŠŒ‰ˆ‰‡………ƒƒƒ‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚€‚€~}}||}}|||}||}|}}}|||{‹‘—Œz{|zyz{|yx|}~€€}{|~}‚•‘„ˆ}|~‚„||‚„ƒ‡ƒ}‚€‚‚€ƒƒ„„„„„‚„ƒ„…„‘‘Ž‹ŒŒŽŠ‰‰………ƒƒƒ‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚ƒ…ƒƒ…………ƒƒƒ„‚‚ƒ‚ƒ‚‚€€~~}}}||||||||||||||}|||~~Š‚{z{zxz{{|}{~~~~~~}}|€€}†~}‚~~€‚||€‚€€~|{Š‚}€~€€‚‚€€€€‹”Œ‹ŽŽˆˆ‡………„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ……†‡…„€†”ˆ€‚€~~~€|||||||||||||}|||||}|yz{{xxy{{z|‚€€}€}€‚‚€€€‚‘€€~€~~~€}}}{}}}|}||}€€€~€~~‚”’ŽŽŠ…††…„„…ƒ‚ƒ‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚‚„†‡††~ˆ•Š~€€€€~€~~~|{||||||||||}}|{}|||{|||zzy{|z}…ƒƒ€~€€~…‚~€~~€…†‚€~~ƒ†}|~€€~}}}}~{|}€}~Œ‘ŽŽ‡„††…„„ƒƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}€‚„††……~€€€~~}€€€€}|||}~}|||}}}}|~|}|{}||z{z|}}†…ƒ€€€}~}~~‹„‡~}||~‚}}}}|{}|~„ƒ€~~~~}|~€}~€~~„’ŒŒŠ†„…„„„ƒƒƒ‚ƒ‚ƒ‚ƒ‚€€}|||}~{{}w~vx~}|}|}~~‚ƒz~~|~~€€~€~~€€€€~~~~~~}~~}|~}~}}}{|||{{z}~€€ƒƒ‚~|||}||ƒ~Œ~|{{}~}~~}{{{}|{{{{€†„‚„ƒ€~‚‚‚‚‚€‹Œ‹Šˆ„„„ƒƒƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~€€€}€~~~~|‚}~}}}{{}}|z||}‚€€€}}}|||||}|~{~{{{|||}|{{{{||zz}z~‚~‚„„‚€‚…†……††‡…„‘‹Š‹‡‡…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}{€~~€~~€‚€~~€€~}ƒ||}}|}}}}{|~~~~~~||}||}|}~{|{||||}|}|}|}|{{{|y{|{{}z}~~€€ƒ‡‰‰‰Š‰Š‰…ˆ’‰Š‡……ƒ‚‚ƒ„„ƒ‚‚‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€~€€~~~}€€€€ƒ‚€€€€€€€€~|y|~}~}}~~Œ†}}~{{ƒƒ}}}|}|}}}}}}|}{}|}}~}~}}}}|{{{|{||{z{{zzz{~~‚†ˆ‡ˆ‹Š‹‹‰Œ‘ŽŠ‰†…„‚‚‚‚ƒƒƒƒ‚‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„ƒ€€€€‚~~~€~{~’Œ|}Š€Œ~~}}}~}}~}}||}}}}|}}}~}}~~|{{{||}|{z{{yzyyy{~ƒƒ„‡‰Šˆ‰ŽŽŒ‰‰…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{}||~~}}€€€€‚…ƒ„‚‚‚‚€€ƒ‚€}~€~|‰‚~ƒ‘„„ƒ~}|‡}}~}}}~~|}}|}}~~}~|}|{|}~||{|}zzyyyyz{~~€ƒ‡„ˆŽ‹‹‡…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{}}}}}zx‚€‚‚€€€€‚‚‚‚†…„‚‚‚€€‚„~€}~~}~€€}~€„€~~}~}}Š…}~}~~€~}}||~~~}€}}}|}||{|}{{{zzzz{|}~}‚€‰Ž‹Œˆ………„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv}€ƒ‚‚‚‚‚ƒƒƒ‚…†„ƒ€€€ƒ€„~~€}~€~}~~€€~€€}€~€~|}}|~~~~€}‚€|}€€}{}~}||{||{{{|{||}}|ŠŠ‰‰††……„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€‚€€€ƒ~~€}€}}~~€€‚€€€€€}€€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{|~|}|||{|{|~Š‡‡…†ˆ…„…„‚‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz~}yxtt€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„ƒ…„€€~€‚~~~~€}~€}}}~€€€€€€~~€€€€€~}}}~}~~}}„€~}}}~}~~}~|{|z|{z€ˆƒ„„…„„„…ƒ‚‚€€‚‚ƒ‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xyuu}‚ƒƒƒƒƒ…„…ƒƒƒ„ƒƒ„…ƒ€€~}}~~~~~€}}|}}~€€€‚€€€ƒ‚€€~€€€€~~}~~~}~……€ƒ~€~€~}{z{z|{z‚…€ƒ‚‚‚‚‚ƒ€€‚€€‚‚ƒ‚ƒ„ƒ„‚„‚‚‚‚€~€~}~~~~}~}}z{|…„{{sy{|pwuvwyutz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€€}}}~}~~}~|}}~€€€€€€ƒ‚€~€€€€€€€‚‚‚€ƒ‚ƒ‚€€|z|z|{|‚€‚€‚‚€~‚‚ƒƒƒ‚„‚„‚‚€~€€}~~}}}~}}{{z€x|vyz|qtxwvxury……‚„„‚„……†„„‚„ƒƒ€€€€|}}~€}~~}|~~~€€~€ƒ‚ƒ€€‚€€€€€€€€‚ƒ€„€}ƒ„€€‚}z{{||}€}€|}}€€~}}~‚‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxzzruyyvwwsu†…ƒ……‚„„…„„„ƒ‚ƒ€~~€~€}}}~€~€~~}|€|~€~€‚ƒ€€ƒ„‚€€€€€ƒƒ€ƒ€~‚ƒ„€€‚‚‚„‚~{{|||}~}~}z~}}x~|||~~~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„……‚„„…„ƒƒ‚ƒƒ€}~}}}€~~}}}€€~|~~~‚‚ƒ†…~~€€€€€€‚‚€€~€‚‚ƒƒ‚ƒƒ…ƒ}}}|{||yz{z~y{yx~{|{~}}€~€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst…„„†ƒ‚„„„ƒ‚‚‚ƒ‚‚€}€€~€}~}~€€|~€€€~}~~€}€€ƒƒƒ~}~~€€€‚€}~€‚‚€ƒ‚„„†„€~~||||zyvyyzyvyv~|{{{~}{}€~}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…„ƒƒƒƒƒ‚‚ƒ‚ƒ‚~~€}}}}~€€€|€€€|€~~~€~}~~‚‚~~}~~~~€}€€€~~}~~€‚‚‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{{{…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvpxyrx…………ƒ„„ƒ‚„‚‚€‚€~~~~€~}~|~€€€€€€|€~€€€}€~~~~}}~€€~~~~}}~~~|~€~~~‚~~€€~ƒ‚ƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}|{|z{}zzx{|zz{xtxuqrtpxxqy„………ƒ„ƒ‚ƒƒ‚‚‚€‚€€€€}~~€}|~|€€€€€€|€€}~~}}|€€€€~~~~}|~~|}€~}~€‚~€€~‚„‚‚ƒ……‚‚~}|{{{|yw{ywxwwx{{z{|…‰}{zwz|}}||}}}~|}~~}}}|}~~}}||{zz|{{zyzz{zxswuqqsoxwq{…†……ƒ…‚ƒƒ‚€‚€€€€~~}|~~€‚€€}~€~€€}}|}€€€€~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y|||{zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚‚€€~}~€€‚‚}~€€€‚€€~|~|€€€€€~}~~€€‚€€€€€€€„‚‚€~|}~~z}„~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚‚€€€€€€~}€€‚‚‚€~€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€€‚€€~}~{’z|}|{}y{zzxzxy{||}|||||||}}}||}|~}~~~}|z||{|}{yzzzyytuuooqpwst}…†ƒƒ‚ƒ‚€€‚ƒ‚€‚‚€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€€‚€€€}~~|†‰||~{{~yz{z{wwy{|{}||||{}|}}}}|}|~~~~|z|}{}}{yz{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚€‚‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€€‚‚€€€€€€}~€}€ƒ‚{~~{|}{z||{‡zxxy|||}{||}}}||}}~}}}~~€}{|||||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ‚„„€~‚€€€€‚~€€‚€€€€€€€€~}€~€€€€€€€€€€€€€€€€~}~}~~{}|}{||wxuxxy{||}|||||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒ„ƒƒ‚‚‚ƒ€€‚„ƒƒ„ƒ‚‚‚€€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€€€€€€€€€€€€€€€€€€€€€€€€‚ƒ‚‚€‚‚€€€‡~~|{}|{}~xwvyyz{}||}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚‚„„€€ƒ†ƒƒ„‚„€„ƒ‚‚€€‚‚„‚„‚€€ƒ‚€€€ƒ€€ƒ‚~‚€€~€€€€€€€‚‚‚ƒ‚‚ƒƒƒ‚€€„}}}|}z}{zvzxy{{|}}{|}}}}~€€€€€€ƒƒ€|~~~}yy{zzzysrtowqwysw{…‚‚‚‚ƒ„‚ƒ„ƒ€€ƒƒ†ƒƒƒ‚‚„„ƒƒ€€‚ƒ‚‚‚~€€€‚‚‚‚€€€€€‚‚„€~ƒ‚€ƒ‚€€‚ƒ‚€‚ƒ‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ‚€‚€}€|z||{w|yyy{z}~}||||}~~€€€€„„€}€~{{{z{ztpxqytvxtv{„‚ƒ‚ƒƒ„‚„ƒƒ‚‚„†„‚ƒ‚ƒ„„ƒƒ€ƒ‚‚‚‚‚€‚€€€‚‚‚‚‚€ƒ‚‚ƒ€~ƒ‚„„ƒ‚‚ƒ‚‚‚„ƒƒ„€‚ƒ‚ƒ‚‚‚‚ƒƒ„ƒ„„„„„…ƒ„‚ƒ‚ƒ€€~||€}|x|yzyz{}|{||}}}||€€€€€‚€€€€€{{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„‚ƒ………ƒƒ‚ƒ„‚„…‚‚‚ƒƒ‚‚€€~€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€ƒ‚€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒƒƒƒ„€‚ƒ‚ƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€€{}€~|y|zzz}||}z||}}|z{~~~€€€€€€‚€€}}||}|vrwxxvtvu}‡‡ƒ‚„…ƒƒ„…„‚„†„„ƒ‚ƒ„„ƒ…ƒ‚‚‚ƒƒƒ‚€‚€}€€‚ƒ‚‚‚‚„‚€‚‚ƒƒ‚‚€€ƒ‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz{}€}||z|~}|}}~~€€€€~~€€€€~|}~~~}||xvvw„‡ƒ‚ƒ…ƒƒ„†„‚…†…„„ƒƒ„„‚„…„‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„ƒ‚‚ƒƒ‚ƒ‚‚ƒ‚‚ƒ„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒƒ„„„„„…„ƒƒ„…„…„ƒ‚€}‚€}||{||€}}~€~~}~|||}}~~~€~}~€~~}~}~}}~~€|}€‚‚ƒƒ†ƒ„ƒ†„‚ˆ†…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~‚ƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒƒ‚‚ƒƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒƒ‚ƒƒƒ„ƒƒƒ„„ƒ„„…„„„…………„ƒƒƒ~„€}}||||~}}{|}}}}}~~€€€}|~‚~~~~}}€€€€„„„ƒ„…ƒ„ƒ…~‚Š‹……„ƒ‚„…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ„ƒƒ„…„……‡‡†‡…„„…„ƒ~~|~~}€~||~|z|}}}}}~~~€}}|€€~~~~~‚€……„ƒ„„‚„ƒ†€‚„…‹‰„„„„……ƒ‡††„„„„…„„„„ƒ„„‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ„€}uyƒ~„„‚ƒ‚ƒ‚ƒ„ƒ„„…ƒ„…†„…†}ƒz}~ƒ{…ƒ„ƒ€}~~~ƒ}{}~€~}|||}}}}|}}~€‚}}|€€€€‚ƒƒ‚‚†„„„…„ƒ„…ƒ„…ƒŠˆ………ƒ……„†††ƒ„„………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†spurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚…„‚hzrss|€r‚„~ƒƒ}}~~‚ƒ‚|}€}}||||}}||~}~}}}€‚€‚‚‚‚‚„‡„…„…„‚‚„††ƒ…„†ˆ††…ƒ†††‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„„†}p{pyv~ƒ‚nypus|vyy†r„ƒpvxqvtturstvi€nrotvnulwmzsn€‡zm}rsvsvmnwlpylu}~|~€}€}€€}}|||}|}~}€€€~|~€€€€€€€€‚ƒ‚‚ƒ…‡…†€‚…ƒƒ…‡†ƒ………†‡‡„ƒ††ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoolw}x†pqzprtfu~n{ysoy€}~€{~}€~€€~~€€€~~~€~}€}€€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„………††ˆ„„†‡ˆˆ†‡„††‹Š…„†‡‡…ƒ…„…„‚…………†……†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„rioyxpkyszozwvvp€~~z~}}~}~}€ƒƒ€‚ƒ‚„‚‚€}~~~€~~‚€€‚„‡†ƒƒ‡„„„…‡†…………‡†ˆ……†…‡‡††„††‰ˆ…„‰Šˆ…„……†…ƒ……„†††††…ƒx‹yrˆz{pp…„x…xyks~y{krƒ‡ƒz|mzyyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozks|nv‚~~}}{}{|}}~}‚‚ƒ„€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡……………‡‡ˆ†„†…‡††…„……„……†‰‰‡……†…††…††„†††††…†‡‡‡††ƒ†…†‡ˆ‡…‡††ƒ‡†……ƒ„…†…†„†„ƒ„„†„„ƒƒ„ƒ…„…„…„†ƒ…†……„„…‡†„„…†……}w…ƒ„„ƒ‚~~{|{~{|}~}|~€€}€~~~€~~~~}}}~|{|~||‰†…„†††…††…………††‡ˆ†„†…‡………ƒ„…†…„††‡†…„†„…††††„‡†‡‡†…‡ˆˆˆˆ†…‡…††ˆ†…ˆ‡‡…‡††ˆ……†‡…††…ƒ‚……†……ƒ…ƒ„„†„††„……ƒ††…†…„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ}€{{|~{||}~~||~}€~}€~~€}}|€}~~~~||}~{|||{{~ˆ‡„„ˆ††…‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„†…††……†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ……ˆ…†‡†‡†‡†‡…‡‡†‡……†‡…††…‚ƒ…††„„ƒ„„ƒ„†„††„……ƒ††…†…„†‡…„„……ƒ„‡†„‚ƒ„ƒ„‚~€|{}~{|{~~}||~}~~}~}}~~|}||~~|}|||}|||~z{{|~ˆ‡‚…ˆ‡‡††††…„††‡†ˆ†„„„‡†„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆŠˆ…†ˆ…†‡…‡†‡†‡…ˆ‡‡‡…††‡…††…‚„„…†……„„„ƒ„…„†††…†„†…††……††…„ƒ„„ƒ„‡ƒ„‚„…ƒ€€{{~}|||~}|||}~|}|~}||}||||}|~}{|€}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††„…†…†††…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡„††…‡‡‡…‡†ˆˆ‡‡†‡†‡…†‡„‚„ƒ„†…‡…„„„„„…†††††…‡……‡…†…†…„ƒ„ƒƒ„‡ƒ€‚ƒ„‚‚‚€{}}|||~}||}|}{||{||}}{{{}|{~}{|}}|}}~}|zz{{||ˆ‡‚†‡††‡††…„…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡ˆˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡…‡‡††‡‡…‡†ˆˆ‡†…‡†ˆ††ˆ„ƒ„„ƒ††‡……„„„…†††††…†‡††ˆ††„†…ƒƒƒƒ‚ƒ†ƒ~‚‚ƒ€ƒ‚|~||}}|}}|~{{{z{|||{{{~{{}{z{~||||}~}{z|z||‰‡ƒ†…†…†††…„……………„ƒ„†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…‰Š‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……ˆƒ„†…ƒ††‡†…„ƒ……†††††…††‡†‡‡…ƒ……ƒ‚‚ƒ…‚ƒ~‚„‚~~~||}}{}}|~zz{y{|}{{{{~||||z{}||||~}|{{{{||‰‡„†„†„††…„…†…„„ƒ„‚€ƒ†ƒ‚z„Œ{€„…‡†††„„‡ˆ‡†‡……‡‰‡„‡…††ˆ†…‡„†‡ˆ††ˆ‡‡‡†‡ˆ†„†††‡……ˆƒ„…„†††ˆ……„ƒ……††‡†‡…†††…††„ƒ„…‚‚€„ƒƒ‚}€ƒ~€||}}~}{~}|}yzzy{}}zz{{}|}||zz}||}|~~€{{{|~}|ˆ‡…†…†„†„……………ƒƒƒ€…‚€}|{„…††„…„„‡‡†††…„†‰†‚†„†††……‡††ˆ‰†…ˆ‡‰‡††‡…„†……‡…„‡ƒ„…„ˆ††ˆ……„‚……†…††‡„…††……†‚ƒƒ…€€€€„€ƒ€|€~~ƒ€}}€|}~}~{~}||yzzyz}}yz{{|{|{{z{}}|}|~~|{{}~}|ˆ†…†††………„……„ƒ‚€‚€€€ƒ~~~€yz}€ƒ„…‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ†…ˆ‡‰‡†………ƒ†„…‡ƒƒ†„„…„‡†††…†„‚……†††††„…††„……‚‚ƒ„~€€€€ƒ€|}~‚~~€~€}}~}{}{zyzzyz|}yz{{{z|{{{{|}}}|~}|||~|{‡……††††„…„…ƒ…‚€€€€~‚‚}}{‚ƒƒ…†…„ƒƒ†ƒƒ„‚€…‡…‚ƒƒ„„…††‡‡‡……ˆ†‰‡…„„„‚…ƒ„†‚ƒ…„„†„‡†…†……ƒƒ…„…†…†„„„„…ƒ…„€€‚ƒ~€ƒ|€}}‚}€~~~~~}}{|{zyyzyz{|yzzz{{|z{{{|}}}}€}}||}€}|†ƒ††…††ƒ„‚…‚…€€€~|~~€‚‚‚„„ƒ‚‚„€ƒ‚€„…„‚€‚ƒ‚„……‡††„…‡…‡…†‚ƒ‚‚ƒ‚‚…ƒ„„…†„†††††…ƒ„„ƒ„………ƒ„ƒƒ„‚„„€‚‚}~~~~„~{||€}€}~ƒ}~~}}~{~{{zyzzyzz{yzzz{{|z{|{|~~}|}||}€~€†„……„‡„„ƒ‚†‚ƒ€€~~€}‚|}~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚‚†…‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡†……„ƒƒƒ„……„ƒƒ‚„ƒƒ€€~}}~~|~ƒ~|~||~‚~‚|~}}|||{{zzzzy{y{zyzzz{|y{}{{~€}}}}€€€†„„…„…‚„‚‚„‚€€~}~~~~€}}€~~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…ƒ…ƒ‚ƒ……‚„ƒ€€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚€…ƒ~€~||~}|~ƒ}{~|}€€ƒ}}€€~}||}}{{zyzyy{yzzyzz{{{z{}}|‚€~€€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌÌÌËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFK=8765999<>9?<C9;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;>BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937676=;>:=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi`dSXlHHHK@=78476::?;D<<:<<98:9:::;<::;9><>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA=366:;<8C<BA><A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖËËËËËÊÊÊËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÒÓÓÓÓÓÔÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9>CE?<;999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNG¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖËËÐÑÐÐÐÐÐÑÑÑÑÑÑÑÍÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø×Ø×××ÚÛÚÚÚÚÚÚÚÛÜÛÛÜÙ××××××××ÖÖÖÖÖÖÓÒÒÓÓÓÓÓÓÔÕÔÔÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILN@99:4;@<7=9AC=@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMMF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖË̕…†††††‡‡‡‡‡‡‚²âÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¹´‹‹‹‹‹‹‹‹‹ŠŠŠˆ¡¿½½½½½½½¼¼¼¼»¿ÒÒÒÓÓÓÓÒÒÓÔÓÓÓÛâáââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑrliNSbLLVM<::77>C?8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKPFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ËÌnPSSSSSTTTTTTL óëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§£££££££££££¤œXRSSSSSSSSSSSNz®ªªªªªªª©©©©¨°ÒÒÒÓÓÓÓÒÒÒÒÒÒÒßëêëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘wliJN_MRUM><<7;?C>6:7>?;=B@9<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ËÌqUXWWWXXXXXXXQ¡ñééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤¦ž\VWWWWWWWWWWWS}°««««««««ªªª©²ÒÒÒÒÒÒÒÒÒÒÒÒÒÑßêêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;?@@8:;8<<<;>::;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÌÍx^a````aaaaaaZ¤îççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©ª¢fabbbbbbbbbbb^…³¯¯¯¯¯¯¯¯¯¯¯®¶ÒÒÒÒÒÒÒÒÒÒÒÒÒÑßéééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB>;=:9::=<;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÌÌÇÅÅÅÅÅÅÅÅÅÅÅÅÅÊÐÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÎÎÎÏÎÎÎÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÑÍÌÌÌÌÌÌÌÌÌËËËËÎÒÒÒÒÒÒÒÒÒÒÒÓÓÒÕÓÔÖÖÖÖÖÖÖÖÖÖÕ×ØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<7@A<=8:;898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÍÍÏÏÏÏÏÏÏÏÏÏÏÓÏÏÎÌÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÎÒÓÏÎÑÔÔÓÎÎÓÓÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖ×××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oVJ_cRQZKHAA<B==;:>><>?==?89:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÎÒ«œÏÒ­ƒƒ•ÏÑ¥¢ÐÎÎÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==<=:<=B>BB@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÎÒ¶œ¥¤Ê›¼¸™µ³ ¢ªÒÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?><7:>9?D>@98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÏ͜‘ž³¦Æž˜–œÇÏÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>><<96?B?B:648:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÑ¿˜ ›µ˜£Š«Öº˜¢ž¯±ÒÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8E@?B:74:::9;;8;=?=>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÓ´™–ª»Š­«›¥±™–°³©ÔÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<=<964:98::97;?@<<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯Ê £¿Êœ¥Œ§­Øª™ªÔÏÏÏÔ«š~£‘¥œ–§™„“£ÕÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>9<97659:6:<;7<@@<::=:<?>=<9@<<::9?@==<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÔ¬›§‹–¢¨´ªž ©…™¥ÕÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CGDAA8;?<=;<<7558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÓ¶²²¥™«ÏØÁœ€¼­¦˜¯ÖÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ђl]\oghb]OF?HHFE@<<>><==<756:96:;::;8@?:<<9<>=;;:?9?:;9=>=><;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦ÕÄ¢™–§‘¡žž™¨–˜šºÕÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;557<:7:;::;9==:::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸« ÇÕ¢«¤œ¸¤«£žÃ «¤›ÐÒÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKK@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÓÓȒ´Ù©¬×»ÔÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUij[L_MJLJULFB<<?FEGKI=667:979:;:<=9>99:8;=>>A>=9<<:=>>;=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÔÈÁÕÒÕÀ¿ÖÒÕÅÄÕÑÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??>>ADLLA>775:8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÑÓÔÒÒÒÔÕÓÓÓÔÔÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEJ==786977899;;=?@<<89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9599:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EIKAALD??;9889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEHIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDCI;AA;<886586987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGJB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFID<BA<;876797799=?A?<:9@?<>B?:8776=?@@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD88867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE><HF89757875898;>>=;89A>=@?A>7596;>AB??@@AB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCDECALH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HQA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELBA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<<DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGHNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAD?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8:87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€iixsg~‰‰xp‚†{w}~…Š¼ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9768579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€‚wt|„‚}sp€Šx‚yƒÈÞÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsnupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9886553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿½¾¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;;>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»º¹¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545659756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjcmgb\XQPQKTJB:IQ?A7<94:565455588686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸¸·······¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPF>8;727967453588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µ¶¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@BD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³µµ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶······¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸···¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬«««¯°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899::;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©©¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶···¸·¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¥¥¥¥¦¨¨¨¨¨¥§¨¨§¨¨§¨¨©ª§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸·¶······¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::9:9<>::A<6=8378837;@??@@:BEC@BDCA?;;@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥¤¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¥§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§¦¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?A?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©«««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤¤£¢¢£¢¡ŸŸŸžžœœœœœžŸ ¢¡¢£££¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™—˜—––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@?BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž¤¤¡ŸžŸ  œœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747578;=8::99;=;;89>6789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥£¢¡¡¡¡¢£¥§¦¦§¬«§¦ œ›¡¡ž››šœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¦¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””““““’”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¦¦¦§§¦Ÿ›š›¢ š–—•š›š——˜™šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¦¤£¡  ŸŸ¡¡Ÿ  š˜˜™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364689:89788:<;<9;;::67899>?@><=@>@:9@A?=A?>AA>AA?:9=>:P Ÿœ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~ššwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥£¢¥¦¦¥¦§¦¦ ›™›¡ —’“’—šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;989:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB?DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¤¦¦¥¥¦§¦¦¢œŸ¡Ÿ—‘‘”—›˜–—–˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡  Ÿ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;=::;7768;<;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¦¦¥¤¦§¦¥¥¥¦¥¥£  ¡¡ ™’–›™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡  ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:737959888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢£¢£¤¤¦¦¥¤¤£¢¡¡žœ›•’”˜œš›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œŸ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸžŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::78:64795<968979<;;<::<;:<<8687>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸŸ  ¡¢££¤¤¤¤¢¡¡ž›š™—¡µž™™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢Ÿ›ž¡¢£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š™—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ ¡¢¤£¢£¤¢­§W^]TW_nkšš›œ››œŸžœœœœŸ   ¡¡¡    ¢¤¡¢¢¢¡ žœ›››™Ÿ«›œš›™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥¤¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¢¢¢¡ ¥³¬  ŸŸžœ™™šš›®jvž›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›š››š›š˜™˜˜˜˜˜˜•”“‘‘’’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>99;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤¤¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ ŸžŸ ¡ Ÿ¦’›«Ÿ  ž›ššš™¨„D€ŸŸžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›šš››š˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9<<>98;9:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœœœž žbœ¦žžœšš›œ¡£QH„ žœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:<>9?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš›››››š¦f]£ ›š™›œ®uIL†¡œœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\Q<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™™˜¤€Rx¢™™š› ¤_VN‡¡œœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡ ¡ŸŸŸŸ™š›œš™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd\\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š›››œœ›˜˜™ ˆ[_”š™›œœ£dZM¢žžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[[LF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ›››››››™˜™Ÿ—]]v—šœ¢dYM¢žŸžžžœœœžŸŸŸž  Ÿžœ›œž›š››žžž››šœœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ›››››œš˜™™š`a`€–œž˜tcUO¢ŸŸŸžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_^]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;979:;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜˜——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜™™Ÿi^[eœœžŒj_PS†ž›žœœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±´­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=:F??:7;;;6397:9>8::<=998;9;<:>=;@@;<B<@:847<;B@AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œš››œ›˜™š˜˜™›šš—“shaTv“—œ‡\VPWŠ’Ž’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨ª¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥£¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‘‹‘‹Œ‘‘Ž’šž’} £–¤œnLOc††‚‹†‰Š‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜ž—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VQQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹Œ†Š‹‹‰‡„†ƒ€„ Žk–¥•Ÿ‰_r€‚’†„„…ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974869388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹Ž‹‰‰…‚‚~€¢‹|nRuœŒŒYq}|~}|†Ž‹†”‘‹—”—’˜¡–ž–•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¦›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=;?:8<999=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ‚†‹‡ˆ…„ˆˆŠ…€‚}˜šwXOLq”†‚K_pqwˆ…ŠŽ‹™œ””” ššŸ¢­±®©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPEMISWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}€~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‘‹ˆŒ‹‹‡‘£T/0=x‡ww@D]km„‰‰””˜•œšž¨®²°°µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWMO_^\NUUbQDTM;?9<895875795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš™ž¡“—›¡š›¢¦œgB[H;xykgE18Zls‹˜šŒ”š—œ› ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUJTOOJDPK_bXZQ\T`MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ªª©§¢¥¨©«©©¯Jr¢yA|xdbQS]I`nŠ¡¡¤ž›š¤§¤©«®¬¥¤¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdWOYKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®««¬¤¡¢¦©§¨£x`ÁÖ¥C|‚uOmŽvSd£¨§ ¢¡®¬«ª§­®¨¥¤©©ª©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_VZNRNQOSe\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@DB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢™œ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨§¦¨©§©©¤§§™¤¥£¢b½À®x £š•eLaxmQt•¢¢ ¡Ÿ¡¡¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOXO^edlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤ ¢¡¢§¡¦®¦¦žj„œº¨Ñ¢š³¨XL¬“Se ž  ž £™–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvxb_\UYQUW[c_s_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?B?:8:>?C@DA:;>=@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯««¬¨¨«¯©¨ª¨¢ ¡¨ª­±²¯«¢¢†w~}rÏÈ°š§¯kUª°c[‡¥Ÿ¥¢¡ž ¢˜•ž›ŸŸ¤¡œ•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸŸ¡¦¢›—’šš •|wo}yf[[`_Z\U\hdocmiib^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¡ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£ £ªª§¯··´µ¶³­®­†ƒn‘Ì»”“¤–tTozsp}–¦ª§¤ Ÿ£›¡š–ž¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¡™˜¥ ¤§ª©¨ª­¬¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxjb[__\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>BE@=9;@A>C<;9?9@@@@CC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢ «²·»»»¹¹Á¸´µ ˆydXŸ¶½¦§šˆwkqoxy{~†Ž’˜£¥¦«¥¤˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨¨«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥¡¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxxxc[RYT__amhvkqhiibZSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶´º±ª®´±°²´µ·ÁÆÌÏÎÌɾ³¤sfRD‹•†††}xqngflilrrqrru}©ÄÄ»¢§ª¬§«©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš’–””˜“š˜Š‹‡€€|‚xa^YSaiaftotitdidb[LK>:9898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÄÇÃÅÇÛããÚ˼¯¤—ˆtYZQDixkntnkeeYW]X\cjjifaiŠµÁÀ¹©¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`b_^kcbnxuwom[bRV\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAA;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–••‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±°§¼¼¾ÅÄÆÉÇÅƾÍÒÕʹ§”†r^QTKD[e^cjea`hYTXSVYZ]Y[uš·¼¬´²­³­©®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|„jfhaklgnvrrvrg^`\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÄ¿ÂÁÇËÈ·”ueUPOTH>^l^_eb`]daSUWVUUXsœ­±ª¨ª­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|uklndomiqxoyjia]gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÄÄù¸Ã›aIDGKD=[ebbic`[c_WROPPV€´º¬®¥¤£¨¤  ¥™©´±¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿ”“‰‰~†ˆŒ–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyz{wnkihvZgsxszgg^d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÊÆÄÄÄÂÄÁ­ƒOFME;M[_eke_[`YYSNU€£«¹µ²¬©£¡­©¬§­Ÿ¬´´¿Ã¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyvvefjjh^kpnyxcba`^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÎÏÌÃÇÆÈÉÈÈÉÇÅÉÇÈÇÂƖjXG??G^cbj`ZXWTVwš·À»¼º¼¬­¦©»º¹·¿³µ¸²Áƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«¬±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqocahvhjjunyl^d[V`YLHD6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÌÐÍÇÌÉÂÂÇÂËËÈÇÌÉÎÅÆƽ©rPK0XSUfaSNPq©ÈÈÂÄÇÀ¼¾´°°°Â¾¾ÁÆÀ¾·¶Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­¯µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—Ž‹”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r}xpg`kjwmifvotc]cUWUSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<9>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÄÇÈÆÒÉÁÃÿ¿¾ÄËÈÊËɼ¼ÈÇÉÍÈÃÈÉÉÅÅÂÃÂÁ¼‘?Ov~‰VLo¥ËÔŶ¿¿À¿º»½µ³³À¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzy€spfegdlebknoo_Y]WVNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾƹ»Ãº¸¹¼¾ÁÇÁÆ»¹ÈÈÃÅÄÀÃÁÁÀÄÁ½¼Å§wkƒ—oªÉÈÇÑÁ¯½½¸¹»»¾·´°¹¾³¼¾±¹µ¸¼¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfaebacddjcgd[ZZ]YQOE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶·´´µ¿»½¿¹¾ºº´À¸µ·²®º»·À·¼ÊÏÀº¿À¼»Å½ºÀÄ¿½¾¯se}‘ŠŠÑÅ¿¿É¿°Á¿º·»¾¹µ¸´¸¼´½¸µ´°³¼±··¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|yˆ}qdacchkggjfj^VVTYOSLF8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=96<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“““˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´´±°µ·µ»Á¸¾¹¿¼¼·´·¯®·µ¹¿»ÁՍ¸¿»ÃµºÇ¶µ¸º¼¸¹¶ª¤˜Ž~„É¿¿»Á¾¹Æ½Â¿¼Å¸¶·´¸¶¶»»¸¶´·ºµ³¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒyqmeegpjelhYYOKKKRJLHD9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’™”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿¾¼²­¯¬±°·¼·»½ÁĹ··¶µ¹¹º»¿¼ÏÄw¨Ì½Ç·¹·­¶´·¹³µ±½ÉĕJ{ʾ¿¾½¼¿ÈÃÅžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~‡}knqgqktfcn`\UHKKDJCCG?:;8><7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘Ž˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼»À·ª­¤®°¸»²½¾»Ä¶µ¸µ·¿¾Ä¼ÂÄÖ®t€»ÈÏÂÀ¸®´´»½·¹±½ÃʎCuÍÿ¾½¼ÇÌÇÇÄǽµµ¶Á½»»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†rfljouoxdhc\cQKUHEECGC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?>??FD@A?>:7?@CC?@=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼ªª£°¹½¼²¼¾¼Å¸±¸¹¼ÆÉÊÂÆÉҙqr«ÑÑÌÊĵº¿ÄȾ¾´¿ÀÀyRnËƾÁ¼¿ÃÌÊÇÅÆÀ¹½¼Ä¿¿¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtpmmtlmo`c_bbNIM?E@?DC;;::;:8;<:9<>::>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´»ÅÐú¾¼Ä¾·¼À¿ÉÏÇÈÊʆrs£ÌÌËÍÊÆÂÃËÎÁ¼¸½º²pcb»ÈÄÀÀ¿ÄÀÊÉÃÃÄùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{zˆ{mmx|`qd\_`_TI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA??ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸´¼·»»«Úþ¶¾À¾¾º¦œ©²¶Ã¿¥yux™ÄÇËÈÁÃÀÀÉÊÁ¿»¹±¡}sk­ÈÅÄ¿ÀÁ¿ËÇÃÀÈÀºÁ¿Ã³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}znsxthp^\_]ZRFEDMIAD=H;;59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘—žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯··²µ³·¹¼»¶»»Ä¹m¬Î½¶¹À¼¬}nhnmr•˜sw|—½¿ÆÀ¹À¼¾ÅĽ½¸±°˜}€›ÊÂü½¿¿Ãÿ¿Ç¼¼Âµ¬®´´¼¾¿ÎÍË·²¸··½¹»±¶²ÈÀ»¶´±°·¬³©°­­´·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|wmu{qoj\`aZTQAFIGK@ECI<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿ››œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹Àδv€³½¶µÂ¥‡iZ^`MR[Znsw€Ÿ¸¸Âº³»·»½¿º»»®¤›˜‡‘~ÀÄþ¼¿»»¸¶ÁµÁº€ °¬¯½À¹ÏÊÉñ°µ´´½º¾ºº»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶¼´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰{‚zsvvxnra_g][UJ=??GG=GCC9:5;99><<9:<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Âɨ„x‰ ¯µjegVY`IIMPSlw†¥°·¾¹²µ²»¹¼¶¹¾´•œ¥–¡p®ÉÄÀ½¿¹³®²¼º®Á~p¢«¦¬º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtwrm`db\^OIB?=IDFMD@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·¿Å«ˆ|v‹ ™`TCXUGajVOEJ` ¬¯¶ºµ´²¬¼¹¸µ¸Á½‹˜°¢¥r¥Ë¿¹ºµ®¥¬³°©¤T€–¡ž¥­¶´Á¶µ³¥§ª¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´¶¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wp|pvsod^hY]^SONB?JCAKJ@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜š‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³²­¶º¯­¼³¸¸¿µ‘‚x‡oNJ?dYBNw€”jNA]°µ³µ²´¯¬»º¸¶¹¿Ævƒªžšd§¿¸µ²±­­Ÿ¤¦§¥ˆIƒ™˜™Ÿ©­¸«ªªž¤©¤«®¯§°«¯±±­±®®¯¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvtmvjl]\kU^\PNHDGMBGNG8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹º¶¹»µµ³··•Œˆ„{XFAN‡YJJXwcAS£¹³´²°±­°¹¸¶»·º½¢²«£r«°©«­«£¨ ž¤oJ{†‰ˆ…›¨­£¢£ž«¯¡£©¨¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬ª¯£¤£¡© ›“Ž”’’™–š¤¥ Ÿž§˜•’”™ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wryiutoeUbdX]ROMI@IRDNC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯²¼ª™™•iN@RxqPIIKf›YER®»±¬³¯®¬­¶¶²´µ¯©¦Ÿš›ž¦¨ž ¨©Ÿ¡§–›•§zbnl{ƒ~€ˆ›¨ŸžŸ¡º¤¥££ ž¥ ¤¬¥¦¨¥¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›ª¨««Ÿ¦¢›£œ•Œ“–•–˜Ÿžžš™¦—“’–¢ ¥¢¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ª©¤©«¦©¬«¦¡ˆxƒ|vzcxmn]QiUPOGPMMCPRA?;>4::5;:=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢ª¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¤¬¨½Â«¥¾iER‚QWIJ_ISŽ`cb€®µª²´®ª«¯°²³­¥‘—“˜ Ÿ¢ œ£¤Ÿ¨”š• µžƒ~‘‹ƒz{Œ™œ§ª’ªœŸ ¡œ¡Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£žžžš—š«¦ª±£¥¨ž œ–“’‘™–•˜—Ÿ˜œ™›¤™—”•š §¨¥ £¢¡£Ÿ ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’~|€uv}nl|diVSdNJHGOSNKNH<E@=2@859;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜——–¡¨¬®¶¶º¹º··»®¨ ¡© ªÆ¿Ë¡PAsžxOnKKbets`Z^p±¯®³µª¦¬¬£›™”‘•—˜˜œŸ¢¢œ¤žš¤––•ÃÚú¶¡‘ŒŒ„skz™Ÿ±›«¡Ÿ §ŸŸ£¦¨ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¢¥¢›™ž¯¨®²«¦«ª ›˜˜˜•“–š“•–š–›—˜˜¡žœœ–›¡›žš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰|€~wy|eyyabSVaIIKLSUJSQM9?A67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—“’œž¤¨®­¬««¯ª¯©ž—ž¥œ¤ÇǏWSId¤\e~or]Pkc[d_]k´°°¸¬¦¡œš”˜š™Ž‘•‘ŒŽ“™¢œ—¢˜–ªáÝÕÕѹ¡ŠŠ‹uf`Ž¼¡rª®«¦¢±£š£¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§¡ £±®²±´ª²®£™œž¡˜››š˜™›•–›–™œ¥¡ š£¡š™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ ž ž ¥¡žž¥ ¦™{|vvsi‚me\S[ZMRKOOVMTMB7>C78=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’‘œ˜¡ª¢§ ž§¡¥Ÿœ’›¢šž«¤zUirvupcvvXWc`cgYXWf­®¬¯§Ÿž¢ –“› œ™—’“Ÿœ¡£šž›–ž™½µ²¾ÃÄÁ±”€xlia´q†·¸¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½¶¾°¬±®­©ª´±°¨«¨³µ¸³¸­²´¤ ¥ ¬¡¡¢¡ š™––Ÿ››˜¥¡ ž£¡ Ÿ›œ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚|xvjwu^m[RaIRVHFVWKCMH=KI8F<77;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©¨®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“Ÿ™¨®Ÿ§žœ¡žš™’˜ž›¢¡ ¤€n‚p`cXL[SZMLPXRHMMH˜¬ª©¥ Ÿš’‘”˜˜–––Œˆ‹Ž”œž–—¬—OZƒ£·¼¶¢nehir_ªº½¿º­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ·»¶«®±¹·¼¯³°µÁ¼·¾³³µ¢¬¢©©²©«¨§¨š™žšª§ ™§ ŸŸ¨¨¥¥Ÿª¢¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰……~vrmiwmhn\X\CWNJGMHCFN=>L>4<:6:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©©”’—™”šššœ˜˜™œš˜™ª ±¢·¤°¦Ÿž—˜•™ž›œ£ŸŠbW^e`WMQG>>?CC?>BQx©­©ª¦ žŸ¢£Ÿž››”“•”žž˜”…™Ÿ™¬fARZz£²·¨‚hahqp`Ç¾¿Â¿¶º»Àù½»¬®§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¸Â¾¸´»ÆĽü¸´ª³­ª³´¯³®ª¯£ž¬¨·²­£°¦¡£°±®°¤¥¯£¡ š¡¦¡¤ªª™ ™š¢ ¦¨¡œž¢ž™¤žž˜˜££¡¤ž¦š›¢¤žŸ›››œ‡†|trklurqhW\QFUHDJPI?EB4FH96<>7;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<<;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž  œœ˜šŸ šŸŸ•}`^e`QGD<C>E<?96N~ª³§¤£¢ ž¥¬¦Ÿ˜•’šž™•ŒŠ†ˆ†xl†Ÿ¢¤›lo{jaƒ¦®¦fhyˆŒ~³ÇÄÂÇÁÀÅÈÍÐÈËò·µ¾²¾Å»¾ÌÍÆÌÌÌÒǾ¿ÀþÇǸÄÊÉÄÁÇ¿º´º»µ»·°¶²«»²¯¼·À»º«¸­«ª¸»µ¼®®¸£¦£ž¦¥¢£©¦™›Ÿ™š§ª§ ¡¡¤˜”£•”™‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ…~zrkdioxkeZ\FLMEDTMEBE7:?;549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<@?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ²²¸§¡¡«ª¡œž¡¡›š~sjaWNE>IY|obB=\Ž®¬ ™›œžž™——˜“——”Œ‚ƒ‚vrplo¤­t|¢•ef”ž™yh|¢©ÁÍËÆÈÄÅÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÑÓÍÓÐÓÓÌÊÁÆÇÆÊÈÏÀÉÑÍÇÆÈƽÄÁ¿¿¿µ¾³­¿ÀÃÃÇÅÈį¿¹²¸½ÄÂÁ»¼¼µ®§§®¨ ¢©¥š– š™¨«©£¤¤ž—›‹™‰•˜› Ÿ£—žš““‹•…yusebgrog^ZZDOMCFQIDCA55589B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>9;AA;;>786:;>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›¢¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¤¨¬­ª £ž›–kf]TID@?K†ž¥š„ ²­£žœŸš˜—”“”—‘ˆ„„‰‡ƒ€€yqqnjv¢±ˆr¸Å›b{Š…tqˆ”¡¥¥¸ÑÌÌÍÏÄÍÔÕØÑ×ÍÆÇÉÌÃÅÊÏÊÒ×Ò×ÒÕÖÓÔÈÌÇÌÍÊÓÍÎÓÍÆÉÊÊÂÇÌÇÉÉƿó³ÈÅËËËÏÇÊ¿¾¿½ÁÇÅÌÌÉÉÀÃÀ®°³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›–Œ†‘‹€{ruvgcgvjeVXRDNG@IQC>B=:22A<E<78<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<@?>9:@A:9>9:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­³·¬®£ž£¢¡œcSLJDC?CR®Ñ½²¯¦œœœ ¤¡š””•”Š}yqlebhrpr{…Š€upmprm…Ÿ…i„µ×—jlvrxwƒ›››¶ÔÓÒÏÒÃÐÓÖØÕÕÒËÉÎÐËÆÍÒÊÒÕ×ÙÖØÓÖØÍÒÊÏÑÌÏÑÍÓÐÀÉÈËÄÌÍÌÏÏÆÇȶÀËÀÒÍÌÐÇÊÉÀÄÃÈÏÍÐÑÏÍÊÈ͸·»¨Ÿ¥«§ž˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„}xsvpcaerc]R\JKGAFIJ?;A8>5586;86:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÁűµ¨¡¥¥ ¢¢[I@ADAFQv²¯¦š”—Ÿœš  ž›š•‰wida____^__]alusponkpns‚‰fl§µh|c_etpxˆŠ‰Š§ÕÓÓÑÑÌÐÍÓ×ÖÓÕÐÏÒÓÑÉÓÑÈÐ××ØÒØÒ×ÙÕÖÌÏÏÉÍÒÌÎÑÀÇÄÉÇÏÎÑÑÒÈÌÍÀËÍÆÔÏÍÏÉÅËÇÇÉÌËÔÔÑÕÏÒÌÓ¹ű¥¨µ®¨›¨«¥²¨°³¬¬““ŽˆŠŽƒ‹„Ž™“™‚…Œ|zqstmacim_VQ`JJCECSN?<>43:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><?@=FAD=‚¤œ ¥ž¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯­ªª«¥®·¨«·×ÔÕÙÙÑÎп¼Ìɶ¾®§ª¨¡£¬gC8=>DX‚ª¨Ÿ—•—™šœŸ˜›“}qecb__a__a`^``_`emppmjmosu€h^ƒ˜ŠƒYLZgbqxrjh—ÔÌÕÔÑÊÏÌÓÖÒÑÕÍÏÕÕÑÅÑÓÊÐÔÕÖÎÓÑØØØ×ËÈÎÄÊÏÍÊÌÀÉÁÉÊÎÏÐÌÐÎÎÌÏÐÈÌÐÑËÎËÃÊÈÊÍËÌÒÓÎÔÒÑÐÐʽȹ°®»¹µ«¶°­¨¸­³¿»±šŽ ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…‰zvopokadnpaX\[IFFDMYE;@=33<<87855;>@=9<<8<>9<@;@:=8?98:?<=8;>B::=<:A==<:6==?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§  £§š›Ÿœ—žž¡ššœš¦›Ÿ¤§Ÿ¸¶µµ¬¤¬®¾´°ÀØÒ×ÚÜÖÎÍÊÃÒÏÁÁ±©¬­©¤²|HFB;V¡›•“–›žžžœ“–—”ˆk^^^adb```````^`_^\bmrnmpprrvsgipqdXPQWXab\WK§ÐÉÒÒÎÆÎÌÍÔËÎÒÌÊÖÖÐÌÐÓËÌÐÑÓÊÎÑÕÒÕÖÊ¿ÊÂÆÍÃÈÊÃÍÄÆÉËËÏËÎÍÑÎÔÌÇÉÐÍÉÇËÆÇÂÆÊÌÎÑÑÇÐÏÎÎÌÐÅÇÁ¸¹½Ã½ù²²¾°»Ãõª˜¥¡˜–‘••’‹”š‘””•‚‰†yqrkmh``qhYXhVMGLIQQB;D?;68:8:;57==A;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;776?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÄÂÁ¿»µ²±Ç¸ÊÕÖÙÚÛØÌÌÏÈÖÕĵ¯´¨ ­—xlopwšŒ—•“‘‘•–•‹|ebbb`]^acb`__`aa`_][]gqqopqmimuneqsrxpVONTywUnÁÀÃÎÎÇÅÇÍÊÑÇÊÍÍÅÐÒÏÍÌÔÊÇÊÎÏÇÇÏÒËÐÏźĿÆʽÃÇÉÎÅÃÈÀÇÎÈÄÍËÍÐÉÅÅÐÉÆÂÆÉÅ¿ÁÈÍÌÌÏÃÊÌÉÇÌÐÅÅÈ»ÇÃÉÉÂÏÁ½¼¿°ÁÉƹ½ª°²§¥¢œ˜›£™—™‘•˜‰‚xoudk`^fqa[W`GIHGIMUG?J=64355==48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ¼¹ÌÌÆÐÕÕØÚÛØÐÉÏÏÑÓÈ·»»­¤¶~g‚†¢ª“–…ƒƒƒ}„„~s_[^]^`^`cdc_]\^_``_[Z\akrpmmhgijs_e|†…hWZNV –e›º¶»ÇÅÁÃÀÃÈÉÈÈÉÇ¿ÄËÅÇÊÌÉÄÁÊÉÁÁËÏÄËÈ¿¹Á¼ÆȾÀÆÏËÄÀûÊÇÈ»ÉÆÅÊÁ¾ÂËÆÅľƾ½ÁÄÆÌÆż¿ÊÃÅÇÒÅÁÉÀÊÊÇÈÆÐÃÃÆîÄËÇÃÊ·¿¼º³©¬¤¥˜Ÿ˜¬£¡¦›£ ›•|wsufj[anmZ\XRDLGCGDLDFS?54335@=3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¾¸¼ÊÏÑÌÇÂÃÆÍÎÎÌÕÏÕÙØÙÏËÒÍÍÎÈÁµÃ¾²°¶m^z|ž‘Š’–†z€„…uxurp_Z[]``bcdded`[\^]^]_[YZ\anqmifgkhnr[mpoYK]^y¡‰m ±®­À¹¹»¹¸ÀÁÁý½¸¼¾¸ÃÉÄƽÆÀ·»ÃÈ¿ÁÉ»¶»»Åÿ¼ÂÎÃƾ¾µÁ¾Ä»½Ç¼Ãºµ½ÆÄÂ÷À¶¶¿¿¼ÍĽ¶ºÈ»¿¾ÌÄÂÆÃÆÉÇÉÆÐÆÂÌȲÇÉÃÎÌÀÅÿ¼²·°²§¨¨¹°¥­°ª­¬”zwxkeh`hodV^YJFJFHKAEBFJA9:658853;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µ«·´²¡žŸ—š”–šŸ¦¢ž·ÅÂÄÈÎÒÊÊÊÇÍÍÎÑÈÐÆÕÔÕ×ÍÊÏÅÉÅÇÁºÅ½¬®§`cv’‹ˆ‹„x††}ƒ{ttc\\]^``bcbbdeb]\[\^\^]Z[\]grokdciikvwf`h`Ffbwo^—ª¨¢´±´³²²³»´»°¶¯³®±ºÁ»Àļ¿º´²º¾À¸Ç¸´¼¶À½¸½ÇÁûµ¯³µ»¿´Å¸»µ¬¹½¾À½±»¶°·º³Æ½·¯¼¿µ·µÅ½¾ÃÆÀÄÆÆÇÌÅ¿ÆÆ»ÇË¿ÏÉÇÃÆÁ÷ý½¶¹¾Ç¿¬µ»µ·¶Žytxggebkn^V^`FKHHJGBDAEF?=:566633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÅËÍÈÅÈÍÌÐËÍÈÉÈÊÉÊÄÐÍÒÏÍÅÇÁÅÁ¿º¸É·«°š[goˆŽ†ˆ‰zx~…†vw|sh]]]]_`_`da^cec_^\[^\]^Z[[\_kolfcfhhjxpSend]Wb]LZ™¦¢˜¦¨¯«©«¨²¬´¯±§­¦«²»¹µÂ¹º¹°ª´¹»³Á¹¯À±½¼»µ»Ç¹Ã·­ª¨°²À¶¸½°±¨²³µ»¼«®¶§®¶®¼²°ª¸°®»®»¸»ÀÁ¾ºÃ¿ÆÃÅÀ¼ÆÁÇʸÅÇÅ¿ÇÃùÄÆ»ÆÉÌ˳¹Â½»³‰tvwki`bliYWW[ALLMJEAC?FA:::996854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÅÎÒËÃÅÁÄÏÇÍÁÂÆ¿ÄÄÃÃÊÂÉÊ¿À¼Âº³µµÃ®ª±“[i~’ˆŽ{x}‰…y{„€wn^]\\]_`__dcbdcb`_]Z[ZZ]ZZZZ\cmmfdddfglyYRhcEKZS>]˜Ÿš“– ¦«¢¦¡ª¨«ª¯¢¥ž©¬´µ°¼¸¯·¯¨­¸´³»·³¼¯¸¹µ²¼Á²À®¥©£«±³³¨½ª«¨«¬®µ´¦©®¡¥°©³¦§¨®¦¨·¬±³·º»»²¼¾¾¾Ä¿µÁÀÇÈ·¾¿Å·ÅÃÀ»¿Ä¾ÄÈÌÊ¿¿ÄÀÀ©‡stsji\aodWVXPHZSSKFFE>?@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÐÏÌÃǹ¹ËÂ˾»É¶½Ã¾ºÊ·Áõ¶¼¶±¯µ¼­©«“cmˆƒ‡‹€z}~xt~|swe_]\\^_`^_ccab`a_]]\ZXY[[XWY\_ejdbcaddhnrBFEDDFSI^–œ“Š›ž¥¡¡ž¤¤¦¥¬Ÿœš£¥¬²°¶¶§°«§ª´«³¹°µµ­¶¹²°ºº±¶¤ ¤ ¦±¨¬©¹ª¥§§¨§³­ §§Ÿœ¥¦¬ŸŸ§¤¡¡±­­¬²µ³´°µ¼¶»ÁÀ²»¾ÃÁ±¹¹Â³À½Àµ¸¼½¾¼ÂÇÄÃÄ¿ÀÄ „yqlbf`ko`UY_HNhOTHFKF<=@=:;<826536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;>97776788666;::;9:;<859<:>>@;Èµ¶½¸ºÁº½¶ ž• ¦º¶«³³»³ÄÏÉËŸ·ÇÀÌ¿¸Ê·»Å¸³Å¸³¿À¬¶¼²¬¦¯´­¡£’ir†…†€|xusomjiipi_`]\\\^__acb````^\[\\XYXXXVXZ]^cb`cccbeemf35B=5GCn•š„—œ£›¢¤¢¦š¡šžª®¬±´£¨©©«¬¤´¸¬¶¯¬²´®³µ¯°ªŸžŸ¤¢²¥¦ª¸­¢¦¦Ÿ¨­«™Ÿ Ÿ™Ÿ¥š™£œœž°©¬¨ª«¬­°³¹¯¸¹º°¶¼»º«³²¹³½´·²±¶µ¿µ½À½Ã»»½—„{sl_e^ddXTW^IW]KPGJJGA<??A;?<05636:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»¸ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÅÏÈÈÀÆ»»ÃÃϾ¹È¸¸¿·²Â´±»»¬ºº±¢Ÿ©«§˜žm~…†xrmomkb^bff]]^]]]\]_`abccba_\[[ZZYXWWWWWXWZ]abccbbcdeqR1:4/8B^cŒ–‡•œ¥œ˜›£¥¡£›žŸ˜˜­¬­®± ¤¢­«§¡µ°±±¬¨¯²§º³§¶¡¢Ÿœ£¡­£¢ª¶ª¢£¦ž¦¦£–™—™š š—œœ­¡¬¨£¤¦­«³³ªµ°²«²¹´¯ª¯²²³·³®©­®²¸°º¶º½¿·³±”†zvf_f_[YVSZUK[QLJEHKIC=?BB@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½¸½¿¶¾¼¿²¥£˜¥±Ãµ¶½­´¸ÂÌÈÆÀŶÁÀÇηÀý³¹¹²¿¶±¹»­²µ¯Ÿš£ª¡”šxƒ„xoqtqhfdiec\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXWUW`bcaab``dgpPQ?,1+$:k¥•‰š™œš“žž§¢œ¦›š™ª¦®°©›¢¢·©¡ ®¨µª¦§­°¤·°¤· £œ™™ª¦¡š­¹°£¡¤œ¢  “•¡”––œ™˜–—œ•Ÿ©žª¤¢ž£ªª±­¨´¬ª§­³°¥«®³±¯°¯¯§¨¨²®²´°¼´º¸®£”‚zwe_aWYXSRTKM^LPLGHMLE=@>=B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾·½­§§¢ª»À½À¹®´¸ÁÌÇÅÂýŸÈ̲ÁÂÁ®¼»µ»¼µ¹¹°°±ªœš¡©•‘Š‹€€|wqilrtphhedfa\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWVUZbba`a__`bhphJ1"&JI–‹Ž•š—œ’œœ¤£¡¤¥›ž¥žª®¥Ÿ ¢¶§¡¡¢¨³¢¥§¥¯¥±®«µŸ¡–•©¡¢”­±±Ÿ££žž˜œ“Œ ”‘“˜˜’–˜˜—ž§›§¢¢š¤¥¥«¤¥°§¥£«¬­¦©®¯¯«¨ªª³¦¦«¯´±®¼¶±¯¯Ÿ’{xseb\[]XNLQHRaMVPOJNOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8847763321./2556;:8;7876<;:;;A8x»»±µ½°»±·¬ž¥¦¬¸»¼Áź²¹µÄÉÉÀÂÆÅǶÆijÁ¿Å«··½¶½º»µ²¬­¨™™Ÿ£‹Št‰ˆ~vncafihfgifil`]\[ZZZZ\]\[\^_\ZY[YYZ[WUXWTTVVRTRT__]^_\]^_ajiG:4/:i|p„‹Œ•œ“˜œ¢Ÿ©£¢¢¡¢¡›¨ª£™£°©¡ ¤ªž¨¢ž¬¬ª©®­¢¢¢•˜¢šœ«©°œŸ¢ŸŸ—™“Š‘’”–˜˜“œ¡£œ¥¡¢– ¢¤¥›£«¥¢¤ª¤«­¥®²©¦¥§¦µ¦ª¨­³µ´¹º¯ª¬žŒsqp`[WVVRGQOHZ\ORJTKSLEGJC8;;=<8667:9;:976977:;:=<<7;<8>598:88659:;<97?<9678452121..1426:8698598989;9@9{µ´¬´»²°«±­¨§¯¹¹³ÀȺµÀ¯ÅÈ̺ÁÉÌȵɼ±¾ÃÉ­±¸Áµ¼À¼´µª¬¦–šœœ‰rˆƒ{tiiilgjlmkjle]\\[[\ZXZ][[^``\XXZYXWXWTUVUTUURSNPY\[[\\\]\_bkK5BBR}†w{Š‹‹••——¤¥§¥©¥¨¥¡—¤¬¢”˜¤­¨Ÿ›˜šŸž®™œª³Ÿ¥¦Ÿ££¡””›––’©©­›œŸ¡ ›”Œ™Œ‘’–•¡ £œ£•›¡£¡˜¢¨£¢¨« «°¤®¸¥£¤£¬­ª¨«¯´·²½µ³«®˜…uti[YYSURFXLQ[XMUOPLQRIOJB=??A?=75799<<977:79:;<=>;7;;:=68:;8976989:6:=99577571141-+/434988::8::748=8?9~³­§³·®¨¨¯®›©¨¬·¶¬¼Ê»¶¿¬ÌÆŸÀÎÏdzĻ·»Âȱ­¸¿·¼¾»³¶¦© –˜™—ˆzt€vwnmhmmmpggifd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUSSNOQXYYY\[Z[]^fcUXlm|z€‚‰‘“œ›–›§¥£«©¦®£¦—ªž””£§¥œ—Ž™­–˜§ª˜Ÿ”¥ ž’‘’‘“•¨ª¥š˜™žž–ŽŒ‹“†‰ƒ‹’•‘ ž¡¤™–Ÿ•š¡¢ž”›¥¥§©¨ °°¦±½§Ÿ£¬´ª®§¯´°¹µÀ±®°«‘~rtcVTUNQJGVPRRLLXNKLOSGNKACFEC>B75889;9:7::7<=:;?>:9;9:?759:9876958779;85576661320-*.102877;99;8948;8@8´¬¦±·ª¥¢±«ª§©²°¤¶Æ´¹º³ÊŹºÁËÐʱ·¸¼½Àñ°±·®´´»³´££˜—•„€vkglnqnqjokdege^ZYZYZZZZZZZ\\]\ZXXXYYWXWUUTRSUSVTQMNMRWXYXXWZ[[`jpjpew}xƒ}‚Ž‘–“™¤—œ§¤¤©œ¥—ž£š‘ž¡™––…„‘š£•¢œ•–•‡¢š›“ŒŽŠš¥§›••—œ‘“ˆ”Ž‹Œ€‹’’’¡š ¢–”™˜•¢¦š™¤§©§¡ ´²¨³¸¡£¶¬ª®¤²²¦µ»´«¬±¢Šzsn^NQQMODNNNPKFNNJJNNQHMJAHLIHC>958889:;69:68;99><8:>9;?8789:886857688974577820301+)-/12876:999984988A7w¶§¤¶°¤§¤ª¥ ©¦¤³ª¢²Äµµ²³ÆÅ·ºÃÊÌƳ­º½´¸À¯®©°ž¦®»¯­ š›ž••ˆ|„n__frpuqinieghj_XXXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQNMKKSWWVWWWWZ]ag_c^rxs|t‡}‡ƒŽ‹Ž™‹–™¡Ÿ¡—¤”Ÿš”Œ†˜™‹s‚}––†’š“Ž{™œŒ‚‰€Š˜ £ž“˜–…Ž‚”~~tŠŽzˆ“›šš’–žŽ££Ž‰š ¡¤¤›¢´¯¬°­Ÿ˜¦¸¦¥°¡±®œ±¼ª©¯©™„xtdVMRPPMCSNLPMBPQHINSNIJJEKMGKK>849888;;69;7:<9::;79?9>@79:<89764445874312485/0102)(,-02764789::66:87A7x·¡£´¨¦¥¨£¥¥¦¦¦²§¦´Á¸¯´°Éĸ¹ÀÎƾ³¬ºÁ¬­Ä­¨¢¦’¦·­£ ‘–—’~xfWV_gfighnciigb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTQMMJGNSSSTTSUYZ]h\^[lumiGRkŠ|‡—’‡–›•••’•ˆ“‰_;Wo{‹“‰€Œ’Œ††r‹„–y{†”•ƒ–Žƒ†}“xqp†}‰Ž—š™“‹ŠˆŸ˜‡ˆ–žš¡ —§®©­©©ž–­³¢¥­™­«˜¨´£©­£“tn`[NSRWLDTJPMLFNOIELQMKPJINPGJJ=7599999:7:;:>>8:==7:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9y· ¢­¡¦¦ª ¦©§£ª°¨§´Â¹°µ°Ç¸³½Ï¿¹¯®µÂ§ªÄª¢˜ƒ”œ±£š™‡”‹‡~sv]PLQUYZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MNQMKHFHNQQLORTUXYacZVhpeH;:{ŒŠx‚ˆ€†‰˜‹••‰‘†„“…xˆ`JQnwŠ‘ƒ~„Œ‹„m~“wuvx„špQˆŠ†|~y”vgw†ˆ~Šˆ•‹Ž‘“—Œ„Šˆ•„›‚…’›–ž”¤¢¨©¥¤ž›°ª¡¤¤‘¦ª–¢ªœ¡¦§Šwnf^\HQQSMIUMRILKOIHFJNMMUKQRPGJD=768:8:;;8:;8>?99>=8;<6;;478;7775344696/3/.115221/,')+*,4833989:99::::?9w¶›¢§Ÿ¡®¡§¨¥§¨¯¬ªµ¼¶¸·³Á»¶§¹È¸¶¨¨µ¶ª²¼§ž•Ž‰”©–•‹Ž„ƒ~xqoXMKMNOLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDCINOhYOQSSUZhf\dm\]SMŠ€‚oy|x‰™‹z„~txrnuptŽŽz~Š«…z{hv{Žprmx‹’x{€{€wsr’xhu…„„…|•ŠˆŠ‹€„‹€”„|˜”œ–‘Ÿ©ž ¡ ©¥Ÿ˜§¤’  –žŸ¤sib]]JWPRHKXROJMLRJJJLPILQMRUMFIB=78;99>=:;<98@?::><7==79947785675251472/2.,./200/-+(().12721987:8775:<;7v®™£¡˜Ÿ´©¯ª¥­«°±ª½´²»¸¶º´±Ÿ·º²ª¬©¨²¯¢š‘”ŽœŽ‘w†x|vpojYKHIHGEHHPTTTWVSUUUUVWXWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LNQQSV^hmihYkƒ”‹Œvbt{ru{…z‚˜’p…zvznk~­|t‹z†’€|tfu|†lohs|Š‡€mzq}qmvqhq~ŽpD‹…‚ƒ…wwzŒ†}Œ{u}Ž’˜‹’››£–™›ž¡œ–‹¥›Ž—Ž–˜xongc[XXUQJSUTOPNPVKNKOOJQOIOPLFD=;79;::?=9<:99??;8;=7<9999266856633611224.,,-..-0-+*''*.1362/876966527995y¦— ž– ¦°¬®«§©°¯±«»¸«»¾¸³¬§›°§¬›–œ¥©¥¡˜šŽ„’y‰‹‹vq|muqjmjXKFGEA@CDHLLMQROQSTTTUVVWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zYJNOQTX]agc^|œ ½|nr^vsjwt…wz‰„nkŠwsxij‚q–‘Œ}•I’™ngw~‚mjdly…’†ksl|nr|†imps‰…†{~{wptt†‚yyp|ŽŒŠ“ƒ––˜š“––™––Œƒ‰Ÿ’‹’†—€pjoooYVXTRRYORUTRXUMOHMKMOKCINGF@:99;99:><9<;::=>:8:<9?868727565541432/024*+**-.+-*(*(',-1250,5567485HA895w™‘›˜›Ÿ¤¬¯¢­ª¨µ¯®¬³¿«¼Ã¿¦¢š•¤˜ž„‹”¡¡˜™‘“‹sŽz€†Œ†uotlqmekkYNDFC@<>>AFFGKKKLORRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_IMOORVZQWXW~[“blr`yki{v‡…s…ƒrk—rr{ijŽLy…“‰„f1v‡rk}}ƒtfeu„„…€filukp€|hqq|n“{t~}qqoumƒwyujyˆ‚ˆ‰ƒ–’’‹‘””Ž—€yˆ—ˆ‡Š†€ˆxlkpheXR[XYY[NPUVYXNIHEJJHGB@GECG=998;9:9<:9;:::@<9:<98>787715234533645031.**+),,++)(+'),,226,,4775478iO8;5m’ˆš™–¤¨­ž±ž§º¯«²°Â±»Ãǚ–Ž•™‹Ž…z„˜•Œ‡q‡‚t‡Œ†zpsqopdpg_TFIC?<;9:?@ADCEGIKOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOOQUKAIPH_©­šjtqgxhm~}~wƒƒwpž’rw€rt“‡5p¨ ¡„¢…vp†{†|tŒ®‰hgbjnrmpƒuioXupŽ›‘vm{}nrnp€{svnbuƒ†€…ŠŠ‰‘‹‘‹‹ŽƒuxŠŽ€~ƒ€}Ž|srqm`\]^\ZYa_RN[ZXWLHIFIH?CABH?CD=;:7=;:;;9:99;9?<88=:8;66650121253474531./,,+)*))***)(*)+/3DM2166643<vR7=7b‘’ˆ•‘¤§ž¯•¥´©®°®Á²»ÁŖŒ”€ˆ|n’‰ƒŠ‡†u‚„l•ˆˆ|uxxmxnwdj^IPG>?7448;:;=>@BEHLLLLNPQSTUVWXZXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL7CMRRCH~mxutpyhrƒ„xz€|‰{tŸ—x}…€„™„šœa†ªžœ‹ƒŽzwˆ~‰ˆŽt‹—„{]dqtz|wŠmhjbyo…‚zoxu…zptzxkni]v†}‡|‡†ŽŠ’—ƒ…Œ†}q„„}vw{|‰xqtugh`[\^S\g^WQTX[UGJJELG?F@DC>AA=;97<;;=<::99;;=>79>9985654244004645554-,)+('''&(())((+++/00Uq=23331E~W4=9\ŒxŠ“Œ‘œž¥‘ « ±¨¯À²»Äº–Ž‘“‡z†vk‹‘ƒ}ŠƒŽŒxƒs „Š}}p~zhwkRXL@E211376688:<>AEFFGIKMOQRSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFIKMOQKJT[WPHb{t‚tvmx‹‡vy…„{“„už—††‘”¥Œ¬©H†­¯®Š€”‹‚‹‚„’©ˆ˜˜Šœtm|†‡~Žhghyn…‡‚…q„†Hl€wryvhmk_v}‚ˆ‡„‹y”œ›‰‹ˆ‘zuŠv|xmow~uusm\^^\cdXge\UPPWYPDLKFOICFCCA@CA=978:::;;:888::?>6;>7595773344236656778;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|}‰…‡Ž•—’– ¬ ¦¸¯³½³—’‹˜‹}tp~‰’~}Œƒ’”}†~†¤‡ˆ‚ˆ…x‡‰~s„x_cWKB60./23123668:=>?BEGHJLNQSTUTTVUSQOGC?80,#‡[??94.]–ps£UFIKLMOW`WlXZ[d„‹~{~|€ŒŽ{‚…~—’€žŸ–“š™¥­’™»±¦ºÇ狌¡¥Ž“‰‘|qƒžŸ‘w……‹‡ihp„tŒ‡„Šr†‚wˆ€{v„|mvuf”Ž†ˆˆ†‡‡ ª¢–‰Ž—zˆyyogkx~|€ule^[[^j^bg`ZOLNWRQHPJDNGCJDC@DCA<:87=<:<:88778:==8<=68756623444576867<BB?<8:>CQ^e\G2'&,,--.1(?‹[.310Oƒ_4?;nupfw‚zŒ‘ŽŠš›¤¡¬¦ª®°—‘‘„¡”„xwŒ”|’†’•Š€’›Ž„€ŒŠ‚‰ƒŠlpj]B@4--//./02234779;=?BDHINQRTRSSTRPOHEB<87/9C><<63.l“—MPHJLKJMV_a{edio“’†“Œ†‰Š•„Œšˆ ¨£¢ª“¨µ¡§Á­ǯx¹”š|¡ž™„“…‚Ž¡Ÿ”™‘…Š…š‘–lpuŠŒ‚•ŒŽw„qm…Š–‘‚…ˆrˆ •†‘‰–¤´¨›Œ”¢ƒ‡’ƒ}kjj|‚ƒƒuc_e`[hl^ll^WKHNRPNLLFIPCDNFBCEFC>:96=<:;:987767;:6=:785456344566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYo‚ou†qv’†~—–š”žžœ§ ©–“˜žge¤š~„’‘y€’ˆ‘’}Š„˜’ƒ€€‹Œ‰†‡„‰…xx~gMR>/..,/.-/000212467;?CENORTPPQSQNPIED>;<:DF?><852<?R5HHHLKMNR^k†yp}x–”’ Ÿœ•œ’ž‘™›¥›¥¨¦ª¨©´–«¾«µÇȶÈÐϾ› pi«©Ÿ„“’…œ š›™¦’‘ˆ•£››xz~”˜“¡“——”ž{w•’ª²ˆŒ–ž|“›‘•˜£¡¥µ¯œ˜§‡–€ˆlss}~sja^b`bhd`hg\REJKONIILFGMCHLFFCBGEB;85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Ppt`m}awŽ}{”ŽŽŠŸ’—ž–›ª˜žªBD}‡‰‡˜x‚‹Ž|Š†Ž‚€‰‹Š…’…ƒ†‰€‡w^bP460-2/,.0/./..0015>AAMQRSQRSURNSLEE@<>=FG@A@8662<9;FHGIJMNQYk‚Œt…™Ÿ¡­·³ ©¨©¤¦±©®´¯¯«¹°²½›²Ã«¹É˷ÿ·¥¢°³¬­ª£‹–˜„¥¦ £—¦™¢ª¨¥ˆ…”¤¡¡ª ¤¨œ±‹•£¦·º› ¢¯’¢œ¡¢¡«®«²´¡”¤©ˆ™ˆ’‰•yz~†ibi]fc_ed^gg_[OCIHSNFHKFJGFFHAKFDFFB;87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLhbWinXz„v“…ˆ‚›ƒ’‘Œ’Úȝ–sV—ˆˆœ|†ŒŽŠŠz‡‚‡‘Žƒ„‹…†ˆ’†‚…‰‡ˆ‡‡qna@E64<3/110-,+-0.-4?CAMUPRSUUVUN[PGHD<>>FHCDA8;<5C;=FKIFHQNPW›¨žª£ªºÂ¿§°Â´ª±¾±¶»³½³Àµ»º¢¸Å¨µÈǵ½¸´¨£´­°±›™’šŸˆ§¯«¥”vŸ¤—¡¬²´™–ª®¨¯¶º²º¬°µ¢±¬±µ»¶´­´Ÿ¦§¢¦™¨¯¬±¸·¸¦šµ¨Œ¤Ž’Ÿ†x‚…x[ceWgcbdaag`[TJDDLTPHIIDIGEA@@KDBMG=867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AFWQJL[YQbbWyuq”}„†“u…€Œ{¿»£¼‚´”“›„ˆ’‰‰y†€Œ“Œ‡„Ž‰††ˆ†Š‡zxn]W@EN<6:45AB764//6CHBQ[OQUWU\WP_UIKKA?>GKFED;>@7D7?BJJEFVSP^Œ ª ®®»¯²»Èų¹Ã»²²¿µ¶À³½¯¶t°³¥ºÄ£¯Æ¸°³±³§¤µ¶ª± ¢—›¢’¥°®¦­«§¤˜¡­´»¢¨²ºµ¼¿Ì¿ÅŽ½³Á·º·¾¶º·¸««°¤¯¨¬½¯¼ºÁÁ«˜¹§”­Ž——©ˆ~ƒ~mXdbYlfkfX\cYVSIGFLPGCHIAHD>?BBL@?MD99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FRLALQVSXUZvjp~Žƒ€Ž„nzsx‡b¹¡™£‰””–’”“—’‡‡{†•Š€„Šz|Š‡†|Š‚‹ƒ•}wzueP\dGEL;Qca[^SF?;HPEZcQQYXZgYT`_LSPEA?IJHEEA@D<E6B>HGJLSZT]‘«³±·³Ä¹¶¹ÇʹºÀ»¶´º¹µ¼³¹±Å`t±¤±šžª½©¥¨«ª£¢²µ¡«¨Ÿ•–Ÿ™ ®¥§¦¥Ÿ¤”£§±´¨²³½¶Â¾ÓÉÉÓÆÃÅÌÂÊÃÀ½¼¾»»¶´¯¸¶¶Â¹Å½Âǯž¸©¡«¤§µˆtacc_Xc`jgSX`VRUIEEMJA>GD=KA=B@=G>;H@796379>489:57045/26389374426?8@>GKRTSQPOQQPJA9/,,,*+((,-+/P>(.48€}<2Kˆq9>CKE@IMPRKQ]glkp…slrrs‡ÕÀµ™ •˜™‘Ž—‘––Ž†‡}†ƒŒ–Š~ƒ€‚x{‹ƒ‡{‹yŠ‚—~s}zkfpuY^\Pedb`ed][XW\MdmURmm_n_XgdTYUJDBKKIFHHHHBI:D?HKSTU\Z[’¶½µ»³Â¼·¶Èɸµºµ·¸²¶³²­µ¶˜du§œ­p^¢¬œ˜ ¢›¤žª¥”ŸŸ“Ž–™˜¨Ÿ¦ žš™ƒ¤ž­¥ª°­¸°½¹ÔÑÏ×ÐÊÌÒÌÏÍÊÆ¿¾ÁɼÀ¼ÀÀÄÄÄɾÇͲ£º°´®š«·»˜€|m_b^Z`cZdcQ[`SPKCAEFE<@F?AHB?C=:E>=J?47535;=468977022/24169775555D3ELM>51/006:477@IOI;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODQ[Yh_o–’”nlotu‡´¬¡¡Ÿ‹™œ™Œ•‘š’†ŠŠ~ˆ†‹‹ˆ|ƒs{Šƒ…{‰t‚Š†•s{ylmu{hreilifjji`fiilZms–­¤¼ˆ†g\og]ZZTHKNPJKPKSQILAJFJO_^afia—µÄ®¶°¹º³¯ÂÅ´®¸°°»«²°¥ª·«Œµ§š§šM™ŒŽŸ–‘¦˜¥•Š““‰‰‘‘›¡—š•—‡Ÿš§›¬¯¨°¨´´ÔÔÔÖÓÌÐÓÕÍÒÏÌÄÁÉнÉÉÊÉÑÆÌÍÂÏÑ·¯Ã¼Ã¹¤µ¹Á¢„qe^__ZbYZgZQ]XOPBBHEBH;@C>AG??A7;C>@H=46655;:687654/10146278875367C5B8?-0-1349=97,.,1;FK=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYReVs˜‚gqoyyƒ¡ªž¦—Œš›—‹•‘šŽ}‰‹…Š‰Š‡|„‚p‡†{‡rƒ’‹Ž}qxulqx~qzmxsmi€pmcimpxiw|~˾Áߧmcxnc[b`JPRUNY^O]\NPNTPTT\nmv‚q–¬¶«²¥¯´©«»¿°ª´¦¤¸¦«­Ÿ«´£Ž°­š—˜Œ’‘„Ž›¦‘œ‰ƒ‹„Š‰„‹„”•˜—”›‘œ—™šŸŸ«¬¥¨¢¬­ÏÒÕÒÎÌÓÔÔÐÔÑÎÇÃÔÑÆÍÒÓÓ×ÌÑÑÄÒÖÅÁÎÇǨ½·Îž|qh`e_XbS_[PQTQOH>@FABE<@A>DC>??:==<<JA45465<888664412/03526768533;=<E=@11+/249>5901022-2DN3)/3.32=N238C}_2A†tD:==I>@CFH<UQMNZu†…Šwlwp}~¡žž¡ŒŒ˜““‹Œ’•…y…‹‰ˆ†~‚{q~€€‡z„u…“ˆovrks}{w{s‚xrk€srioqzyqz¾Ëš}‹±„vr„vhak]CZZ[VecXdjSX\]`c]cwz}‹˜©£¤ ž §¥ª¯¸ª¥³¢¡­¡£­¡¦±žˆ¦š“’‘‰Žˆ“‰j”¢Œ™„†~‘ƒƒ“—­‹••™Ž†’‘ž—¨°¢¡¡¥¤©ÉÍÏÈÂÌÑÔÒÔÒÎÓÍÆÖÒÌÔØÖÖØÔ×ÕÉÔÚÍÉ××ÑʬÃÂˍuqebaZVZT\QKGJJJ@;:;DAD<BC>GB>BB:<9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/--;R017/532FD28>nb5=tM99@I<AD?A;OLFJXp€u}hsxr‚‰€•”…‹•‰Ž‰ˆ†Žxƒ“˜ŠŒˆˆ‹ˆ~‚xs{}‚‡wz†‘•ƒnwpmuux}t…|ym‡vtn}v„tx{µŒ;AŠÅ¥~Œ|ieWICfcecgjcmw[^fhknhn€‚‡‘‹œ œ—˜ž££¥±£¤²Ÿ¡¥ ¨Ÿ¢±›…ž’‘‘ŠŒŠ†ƒ„œ›Œ‚„…y”‚©•£Œ‘‰—’‹~˜‹›’«³˜›œ¨œ§¾Ãƹ¶ÆÎÒÑÒÐÌÒËÈÔÎÐÕÚ××ØÔÙØÍØÛÎÉÙÚÑÕ¾Ê˵zypg_[TWR\WFGJIEE=:7:@@B9GD?DCACB;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?1*(.BS39254/7K75<`bA<svV87AH:?C><9QECJTknnpbpqt†|—‘‹~‡’ƒ‰†„‰‡|x…—–ˆŽ‚‡…‡z„yqz{ƒ…uy…Žœy‹p|oozq{€qƒ‡nŽzuw}|‚t~|†‡¯sX©Â¶‘‚pmb=^hrpqpnxvehoruxqz‹†“‘š•Ÿ•‡‹“› š©ž «›¡š˜ž¤žŸ«™Šš‹‘„|‡‡ƒ…‹ŽŸ™“ˆƒ‡~l™z„˜†ˆ“Œ”Œ†|œ‰”®ª”–˜Ÿ™§¯¶½©­¾ÇÌÉÉÌËÐÉÃÒÊÔ×Ø×Ø×ÕÛ×ÓÚÛÕÐÚÚÑÖÈÔ˖|~kk]\QUTaICFIH>A>=7:=?;=G<?AAADA>?:87DB755479/556435532323647553458EBDCEB56<FNSM[nfcnskaV>,4LG865434BF4=W_hLux^8;?F<<B<99D>CGRj^mdbfkv€ˆq‘š€z€~‚‚ƒ~ƒ{|„˜‡‹~…‡€w‚yn{{†ty’žŽ vŽu‚su}s€„o‚o’„u|…zv†{‰·Å¤Áɸ–›wpeNfczw†¢Šxyv{ƒ{„vm“–””Ž—‚‰Ž–™–•¤›—ž•’‘–¢™«•‰Œ‘‚Œ„ˆˆ…‘›™‰…‹…˜zˆ‰Ÿ—ˆŠ‹‚}¡‰‘Œ¼¡˜“˜™œ©¦¦®Ÿ¨¶¿ÀÁ¹ÈÊÎÎÅÍÉÑÖÕÕÙÕ×ÛÔÖÙÚÛ×ÚÚÙØÎÛƈ}|jlhbVYWWNLENC;==<8:;=9=@6=??<>==9867CA6455=80665547745613854564557HH=DJE7925;H>;9:7IP][SUXK9T>;95327I8=NYMHxxd5=>C==@:6:>>@EQ_Xea][htzylŠ’wvzŠ{~€~|„z~‚‘‰„…y„‡{u}tm|}†~s~’ž‘žƒ‘{†~x~xŠŠn‚š€t™†~‰„{~z©ŽÃ¡½‹œ¤}‰„}‰r‹Š~s¦šœ˜“…{Žˆ„hGq ¤Œ‹‘„ˆŠ’“œ™’“•Œ‹”žœ” ”‹~Šƒˆ’–šžžˆ‹”‘‘‹¥˜ˆ„‚…„¥†ŠŒ¸˜‘•–¢§¡žž¤¯·ºµ¬ÀÆÊÐÈÇÌÏÓÓÒØÓÕ×À×ØÙÛØÚÚÙÙ×Û¸{|{nlhZb]TPOIDLB<<>99;:99;<6?=><=99;;37D@8378>60688357<37804976755546FP5DNI8938AK=;3C@I<:DWN<MTHN?96333>C;[X>5YypZ<<A<=>8689?=CQSRX^UXfmmmiŽŠqryŠ{z|{‡z|{‹†‚}tƒ…yszsm€~„~w…›¢›”’Œˆ˜‡€›’nˆ¨…z¡‹|‘ƒˆ„œ}šŠŒ£¢ ¤¯Ÿ‹‹…‹“†Wr­‹Ÿ«›ƒ˜›Ž\‚¢‘‚ŒŸ“”‹†‡‹’’‹“““Ž‹Ž‰‡•šœ”–Š‘“†€‹ˆ‘ŒŠ‰œ–˜¢¢†’• Š‰ˆ›ƒ‡Žƒ‡†¤…Œ‘³˜’”—¡¢Ÿš’œž¨²¸­¦½ÂÇÍÈÆÏÍÐÌÏ×ÑÑÕ®ÖÕØÚØÚÚ×ÕÙÙ r€wji_`ZUYYCAIC?>>:48:;7:;:3;;?=>7;::1:G=:37=@50677255?65;55858:57735HR7GOK994=EJB>1FCLB:8:GX@5HWI66223:ECeX?&_yi_z>>9<;98:;@;BQKKSYPTcbzma~’ƒomw‹xyz|†|{w†„sp…‚zuwvt„‚„~’¦¤Ÿ¥¢—Š”—‹Š¨—sŠ²„¨’„™“…™Œ¢•Ÿ˜’ˆ›ž£’©°Ÿ”Žˆ–Œn·…šÄȲ›¡¥›œ˜–²‘d¤ÍȕŽ†‡ˆ’ŒŒ‘“ˆ„‰ˆ…•™š”’†“–ƒ‹™‡ª—–¢¢ˆ˜ž–šˆŽ†——‰„ŽŒ‡¤ˆŽ“¨š—“—™¡™Ÿ™”›£³´¦£¼Â¾ÇÆÅÉÈÉÂËÓÍÍÔ©ÒÑÖÖÖØÚÔÒÚ΅uƒkga``QKV\BBGC;A=837;<:9=649:<:82?992:I:>67BC32:96264>=4;>6949;57944JQ<JQK9A7BGI@64JELF><88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBeƒGu‚Ž||m~ˆxz~z‚~vv€‚{ln‹~y|wx|„†‹~‹£´¨¤«³¡–§ ¥¤–•¯¢ƒ¸•’³š¡ Œ¤›¯¢¤˜§—©™­°¤—”•”‹˜š– ÀŽ£É¸«š¢¥­™‘›œ²†…¨¢œ—…ˆˆ”‹Š’†€…†ˆ’˜”ŒŠ“’†“—†„‘œs˜²•–£¡ˆœ™“ŠŠ–šˆŠ–†}Œ˜ŸŠœš™“™˜ ” •Ÿ›¡±­£¤¸¿´ÄÇĽÃÿÆÎÊÉÒ§ÏÌÓÑÐÖØÒÏؼu}y`cWcXRIKOEBCD5>;76:?;<7=42669774=5;5<L<>;<BA75<;5277?@6??784987;<55OMDPRL8@=EAGA5:IENED:6A@BS>9DO323575=v\<R\tiZM]S<=89567=:JFDGM\\YJha;H„‹zzm…†y|„x€…}px|}|orŒz}{x†‹‰†„’¨¼­©³½°¥®³³©£¢°­Ššµ£¹¥•­¤—©­·¦¤£Ÿ™©˜ª¤¯±ªš™œ”•‘˜ —š»»­Ê¡i¶·ª°•˜ž¢«’—½¤^©²‚‰‰Œ”†|Ž|ƒ…””ˆ‡’–‹Ž•‹Œ—˜‘›™´–”ª‹œ”‘Œ’‹˜š‰‘‹Š–Ÿ¢•—™“œ˜ž”¡ ”œ¦®¨¢¤³¸«ÂÈĶº½¼ÅÈÈÂСÆÉÍÍÄ×ÖÐÊÓ£s}l`]VbTQGD><CAA8?874>F<<6<35355454B39:BM:A;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPfHa`bpJ@‹‰€r†‡|‰u‚Šƒ~m}||~pw‡w‡{Œ†Œš«ÃÀ°½Æ¼³´Á¼´¬«³¶Œ¨²­®½«›»£¨­¹¸«¦¦¢¢¤£ª¯²±ªœ£˜›˜˜ž¢¦¥“£¹¯¨¿¼¬­²¹¥£§}ˆ†œ­½°‚‹‹Šƒƒ‘Žy†Œ›‡‡–ŒŠ”–“™–›§š±™ªœŽš‘Ž••–Ž ˆ”›£¬•–”œž” ›˜Ÿ •›Ÿ§§¤¢¤°³¦ÀÆ𰻶ÅÅÿͧÇÃÇüÕÐÌÄʊwve_]b^OLCL@EG?A?B<:4>A==5=6>333241A17@BN>G@CNCA=C=;86CC5BIB:878;5B>79VKDWOF8=4K@C>4EJHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GE?CF\hF_ig[]\“ŒŒˆ{‡‹†ƒŒu†Šo~{~q~z”z’””˜‘“•¨´ÇÉÀÂÌÂùǼº¯«¹»—²¶¹²Á®¥À¤«°¼¼ª®«££ž§¬¯µ±©› ªœ¢œ–Ÿ°´§Œ£ººµÁ»«¨œ²¤¤¨”„Ž©ÄĤ‚‹Ž‡ˆ„†•”ŒyƒŒŽ‘ ‹‹“Ž‡—Ÿ—’˜”–¥ ®œŒ©œŽ–‘”•”‘Ž¡“†—Ÿ ²Ÿ”›” ¡™¤Ÿš › ”™Ÿ§¤¦§¤¯­¥¿Ã®¨·µÉþ¶Î²Ä¾Ã»³ÑÉÈÁµx|p_[_mTNIDLLLJ@A=BD<5AD;:3=8B332263A15IEM>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBg\Me\fTcjš–Š‹ˆ’†‰y†“r€{Œw‡‚y¡–¨š›˜º¾ÉÈÊÂÒÉËÂͽÁ³­¼¿§º¿½¼Ä¸¬Á©­³¼½ª°ª¤¥£¬®´®·µ Ÿ®Ÿ¦¢™£´½©œ¨¼Á£¶¶¯«“°¬ª¬–†šª§¥‘‚Œ’¤•‰€u‰‘y„Œ‘Ÿ‘Ž’ŠŽ‹“¢—–š”“¡ž©ž¤™ŒŽ•–ˆ|Ž•’‘¢š” ¢œµ¦ —¥¤£¥Ÿž¦˜ž•—œ¥£¨¨¢²­¨»Àį¥³·ÌÀº®Ã³»½Á¹­ÂÂÁ¿šq|d[Z_^LMNKGECHAAADK:4DH:;4<7F.12352A26SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQF7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>lI_XaZdeXžŽ—Žž’‰ŠˆŸ’„x…”~ˆ‰€–¡š­§¤˜Ã¾ÉÄÈÆÓÍÎÍ˼·°º½´½Ë»Ä¶¶¼­´¿¹¼®¯¨¡©¨¶®®©²·šž¬¢¨¢«··ª¥¯¾Ä±½¹³§ª´³­­–•¥­¨ ‘Ž’±Å§•Ž|‘•|†˜©˜—’’Ž’”’¤œ’œ˜“ ¡¡›˜ž—Š‹ŽŽˆZ–—’–¤™f™£ž³¥–¢–¬­¬§œŸ¦—˜–˜•¡£¨¦Ÿµ«©º»Ã´¦´µËÁ¸ª¶¬³»¸®¨¸º¼·„pq][VWPGKTNK?AGDDHFF85FM;>7>AK.32025B55PWN<LFKRLOGGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|hV<>@BFBsFiIRfdMF¦”œ–¡—¨–Œƒ‡¥’ˆ‡‚›ƒƒ•“Žš¢Ÿ¯¾®¡Ç¾ÆÅÈÇÎÎÏÒʾ»¶±»»¼¿Ï¶Ä¾·¹·³²µ³¸³¬§œ«¬¹«©¨°°˜£®¥¨¤¥µÁ°«­´¾Ã¹À¹³§¸´·²¯•¤­°¯¥‹“” sÁ™}–™„Ž–™‹°•™™”‘‘™˜¤¢”žš•™¨œš¡Ÿ˜‰‹Ž”œ_J–œš”™¤—T–°Ÿ¯œŸ¥•¯¯­¦›¡¦”“™˜ŽŸ¦¡™´©ª³¼¼»«°²ÇÀ¸¦¬«­±±£¡²²´¥srh_]QRLFQQPQ;HJHFGAC=9KT?A:=EM/7534:B44NWN<JKOUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@CAF3>58JKCA=C;5EA:A?>H@5*B52,>c]g:35tde@R7&#3}hX<:BC@=REWStbVFH«—™Ÿ¡¨®˜—‡Š§–ˆ’…Ÿ‡„—Ž š£¤µÉµ©Ç¼ÄÄÉËÉÈÌÎǾº³¯º¸ÀÁ͵ȻÁ¹¶º²¯¯³´§¤œ«´µ«ª¦®¬š¤­¦¥©¬º¿¨«··¾ÁÀ¾·²²Ã°·½¬£®µ­º¦ˆ›—¥›u¾Ÿ„™Ž’˜š‹®– ›š–”šžŸ¨¦Ÿ™™©™ ¦–Œœ‚mu’¢š•œ¢Ÿ®²¢«•©ª˜ª¯¦¥¡¥ª’’™œ‰•œ¢ž–°§©ªº·¾³²®¾¹¶ £§¨¥¦œœ­©©ficbTMMGIOJUL=LDMIJ@CD<QU<AABDO18=77?B75UXN?HNQXRPQTJQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CC:9C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW<:=..SaMVH~e^HF¬”œ¡Ÿ»®˜”ž‹“ª›‘‘“ˆª‡¢žŒ£­”£¤¶Ç½´Á»ÂÂÈÉÅÂÎȽ¹²¯¹µÀÃʶƲÁ¼µ»¬©­­±££™ªµ»¦ª§¬ª¨¯¨¤«ª¾»¨­½´·¾Ç¼¶µ¸À°½¿³©µ·¬¿¥¢—¡Ÿ¼ž‰š ˜–Ž¶ž¨›¥¢š› ™§¤± š¥œ§©œ—“Ž“›Š–‰Œ¤¡”œ¢Ÿ µ°¥¦”±«š«­ŸŸ¥¤ª’–• „žŸœ–©¥¡¡³´»¶­¨µ²²žœ£¥š—•™ª¡žxd_a`LIFHNQINEFFBQJH@DGAVSDH<AGQ1;B7:BF79]YKALPTUSMWRNUJD@JJNO9C?5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-1:h]FDCœpbGD¨—¤žŸÃ¬›—¤—™¨›•ššŽª–•¨¦•­¬™¢«·Å¼¿¸ÁÂÀÈÄ¿ÍÆ»¾¹²°¹´¾ÃȶÀ°¼¶º·§¤«¬­¡¡›««Ä¢¥¨¬¦ž«¯­¢ª¨¾¸¦­¾°··Ç·´¸¸¾±¾À¶´²µ¯¾£–£•’š“­Ÿ¡¡¤¢¢ž¾¤¨¨«œœ š¥Ÿ¼¢—£ž¡¨ª œ••ž“ž‡Ž„“ž¤ ¶¬¦—³§š°¨ œ«Ÿ¢š•Ÿ„Ž¡šœ’¥¥š—«±¶²ª¥ª­¬œ˜  ’–©Ÿ”if\b^PJHKOLHEDI@=OH@;FIH[RPK=HNU4BF8>HG5Cb[KCNRUWVQXTRUH@8QQPM:G@4CHQSIC;C>GVKC@O>K<06;GF>;FA56?9:?9;15D0--0Mv\4KZ5,MnW<-=)#zbQ5CKQ9oRF<KxfcXN¢›£›žÅ« ž«œ­Ÿ‘¢ž–¤Ÿ¦ª«—¶±£ª³¶ÅýÀ¶¿Á¼É¿Êȶ¸µ´±´´·ÂÆ·¿±¹µº¶ §¬«¬žŸ ¥¤Á¥¡ª® ¤©­°¢¦¨½µ¥±¼·¶¶Ã²²·º¾²ÃÀ¸¸­´´µ£¤”‘“ ¬Ÿ˜¡¨¨ª¢šÂ¬¨«­šš˜¥Ÿ½¡œ¤—«««¥ ™š ’žˆŽX–Ÿ¦¡ ¹ª§”™·£Ÿ³¢¡œ°˜¡š•ž‚ —–Ž¢£•¥®²¬©¢¢¥¤••œ˜‹’“¤Ÿ‰cg\eaMJKKOFEAGK>=IA99JJN]QQI=LV]9FI=DMI8Hc\KCLPSYYVWOZ^IA=WQIK?H@5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+waS6SZkWsHE6=ue\LPž  ˜žÃ§¤¢³ ›±§’ª£Ÿ£ž­©¬»±©¬µ±ÈÄÁóÂýÇĽÄʽ°±¶®±µ°Àŵº±±º¶­š©°ªª›Ÿ¦¡§Â­œ­±œ©¢®±ª¤¨½·¦µ»½¯·Ä­³³Â¿²Æ³º·«´¶­ª¢¦••“¢«¡ŸŸ™§ª®®¯»±¥Ÿ©©™˜—’¢£· ¡£‘®®«¤¥ž‘¡ž”Ž”š£Ÿ¨µ§§™µœ£¯› œ°‘¡•˜•›€’¢–Ž ¡“‹¦¬°¥§¢ ž’’š“…‹’œŸ€dh]hfKJLKSAC@IG;;F>89NMU_RSJ>O^^=HPBMLI8Nd]LELRTY[SUO\bHA?ZQAHAKB7FELKN>;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<w]^?[U_gr@8<H–weA4Ÿ¤žš Â§£©± £´©•±«¦¢¤²¬­©»²­°µ´Ç¿Äõ¿Ä¾ÊŶÀɵ¬µ©°¹¬ÀÄ´¸¯­¶º¥™«²¬«˜¡§˜­»´œ¨°›¬Ÿ®´²§ªº²¦¸³¸²¹Áª·²Ã½´Å§¾®­·µ©§¬¡––‘¥£¡¡——¤®·­±´¶Ÿž¨¤™“”“£ ¶¢¤¥•­±±¥¨¤¡™™š•˜¨ Ÿ™¢ž¯³¢¦˜¯š¥¬˜›Ÿ§“ž•™š†– •Œž“‹©©«¡§¡šž–™‚†•‰•Ÿzek^lkNQNNT=CANC;:I?77QN]_RVQBW`]BJSHVKH:Td]NFON[W[RPQX]GAB[PBG>NC9HGHNP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1\cZ33906p[bH05JqjVCWFŒyfC;¤¤œ ¥¿¦¨®® ©µª·¯«£ª´¶°°¸·°·¸¸Å½Ãǽ¼ÃÂÈÁºÁÆÁºª¶¥­»­Áø¸ª­²¼£•­°®³—¦¨‘ª¹ª¡§°ª ¯´³ªª¶µ¬º«³²º·¬¸°Áº½¿¦Ãª°¶®©««¦˜˜ª ¡ ‘— °®³ª°¸™›©Ÿ™–‘—¦ ¶¨¥¢¢¯°³«±§«ŸšŸŸ›ž¥¡˜£´°œŸ‘”¦š¡©œ–¤¢˜šŒ–™”–—”‰‘›™”Ž©©§Ÿ£œ™›“‡™‹~—†šlinbnnXQQZTACDU@;;H@7:XPd^QWWEY_^NLSO_LJ>Zd^NIQN[UYPKSWZI?DXPDF>N?=IGGQPB=CFBM?:2D?77547?=95E4+75/251.-.,1>*'+=\p=>1.1e[d@1747gYaF(@8m}h\V:‰{cC=¨Ÿœ¡©¼ ª¯ª¢°·©¥´²«¡­µ½¯³¸¼»½··Á¿ÉùÄÃÁÀ¹Å½Á¸¯¶¨«·²¼¿¿´ª¯²¸Ÿ—«­©®˜©©Ž§»Ÿ¥­³Ÿ«¢±°³¬ªµ³µ»¬¯±µ¬°µ²ÀºÅ¶«¼¯±·¬­ª£±¥ž¥¨ž£–˜Ÿ²©²©©²™§›š”ŒŸ¦¤´®§¢¬¬­°§²«±©¢›ž¨¤ž•¡™œ¨¶©˜š’’Ÿ™Ÿ¡ ’®¡›šˆ—™Œš”‹——š—¦¦£ ž—––”€•„{“ƒŒ—gmrhqs`GYfVDCMXDZ9HB6>]Qh\OZ]G[^^OMSXdJKC\c`PLMNXWXPJVVWL=EUJEDAM?AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,+%2+*5K1.'__aV151=`V_8)C3YU\gK5ŒzfL@¥™Ÿ¤«¶£¬¨¤®­µ©¯³¹¦§°·Æ·±·¿Á¶µºÅ¾ÌŹÃÁºÀºÅ¸Áº³´¬ªº¸»º¾µ«¯±·˜˜¨««¬œ®««½«®±£ªŸ±­³®®µ±¹·ª­¯²¨¶¯³º¼É³ªµµ±´°¯§¡³Ÿš¨¬ ¥•–š™±¢­ ¥¯–¢¤™™’Œ¢¥§²©¡¦±«©´¥®¯³®£™ž­§›—žš™¬¸¢˜“‘˜œ¡™˜•®¡Ÿ–‚•™Žžš—‘Š”“žš¥££ ™—“’–{Œ‘…{‹ƒ‹“lnyov}bF`jZIHZ[={JGE6AcTi[M\aK\\ZRRRbaLKE`aaQMIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`Va.5(C^Q\.+A/JGP[G3cXTLEš–Ÿ°¨±©¬¤£®­µ¨·³·£¬´·É»µ»»À¾µ´·ÃÀÌǼý·¿¿Á¸À½²½®¨º¹¸·Â·¬®±º–—§®¬¨¤²©”¯»¤¬²²¦§£²´±²±µ°·³©®¬²§¸¯µ³ÄŶ©µµ«°®ª§£¶ŸŸ¦° £”›™”°ž§›Ÿ©©¢›•—¥¥¤·§¢°³«§°§­¯´¬¤˜¡¬¨œœœ”ª¹œ•Œ˜¢˜‘™¨¤¡˜…”—‘œ˜——‰——›¨¥¡’–’–w„‘†|†‚„nqxv|€]Lel\KOd]?b{GI8GhWe[M^bMYYWUXUj]OPHa^_PKGQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANHg27'FaLV%-B.=ELQ<3rjLED‘™¤­¤¬­ª¦¢°±²ª·°µŸ«µ¹É¹®Á¼Ã¸³²µÂÃÎÄÀ¾µ¾ÀÀ»¿½´Ä©ª¹±¶·À¼¯¬´´ž¡§±®¥¦±¥ž²µ¬ª²°«¨¨µº¬µ²µ«´­ª«©¬©¹­²°Ç¿¸¥¹°©­­¦¨­±¥¤£®£¨œ›š¯™¢¢¢£¬Ÿ£ Ÿ¡©¦¥¸¤«´´¤ª«©¬®µ®¢œ£¨«œ ™›’¤µš‰Žˆ‘£¡––Ÿ£—•†•”ž›™—•ˆ˜“•™§œ  “’Ž‘x~…}|}‡ŠŠrts~~]Scn^NZg]FD–[G:MnXa[NabNVVVWUYh^QSMcZ[TKFOTSNGIVS\N;P^JBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3Dd;6*HdHJ+:I?3CIS,>k@HIš¨©¡©°¤§£³³°´µ°° «­½Ì»®Â½Ç²´®´ÂÃÑÄſ³¾Âü¿¸½Å¨­·¬´¸¼À±¬²­¢¤§®ª¨¥±£ª±ª®ª±®®¬«³»§·°²©²ª«¦¥¤®º¬ª°Â¹´¬¹©©¨­©§±¥©¤¢®©¨¢žœ¢¬•¥˜ž™¬¡§¨¡¬¦£­¬¶°± ©¢ ª­°¬ž§§©š£˜™ ¨˜†„‹‹Ÿ¡˜ž’’ˆˆ’–¡–™–‡—““—¥žŒ’ŽŠˆ…|w‡…‡utr‰wl_Y_nbQsq\K;„|F>WuWaYOc\NUVUWQ\b_SOOhXXWKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=398;*35>10485(5/*,.30;),,'%234$,2-860)(1<^K0.JgDF8<B05EKX1@”]@NF•–¬§ ©±œ§¨°µ¬¸µ­ª¤ªª½É¼±¿¹Ã¯°­³ÄÃÍÎÿÀ³ÀÃĺÁ´ÉĬ¯·®³ºÀ¾´®®¬§©ª±©¦©±¦´­ª¯­­±®²­´»¥·³¬¬®¨« £ž±·«ª­¹¶¤µµ¤ª§¬¬ª­ ¨¦§±±¤§¥¡¡¬–ª¡“› ¦ž£¢ª£¬¢ž¦±¶¬¬¢¥¢š©ª®©œ¡¥¤¤™ ™–˜“‚‰… ‹Žœ‘“…Ž™¥›“’›Œ“’‘”£šœš‹‹Œ|†‚‚zuƒ~uw‹¢‡xj^_nfWe‡dN@g’LEbzWbXRfUMVVUTO\]aVLOjXVVHJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*49?./463)4+*,+.#4.-+&(+79*&6+<-2,&06XZ.0JgAA<<C+:JO^4D‡BIID–®¤¡ª¯˜¨¨­µªµ±ª¥«ª©½ÀÀ¸º´¼µ¦³¯ÄÉËÒ¿Á»¸¿¿ÃºÂºÁÄ®±µ²´¼Á¾³±¯­¬­§·ª¥­°«¸®§°¯®±«µª¶µ§´·«¬¤ªªœ¤ž´³¨¨¤³´Ÿµ­¡ª¨«¨«§Ÿ««¨¹¶©ªªª¢©Ÿ­›‘ª¡ ¤¢¦¢ªžœ¦´®§¥©¢£˜¤¦§ªœ¢¤£ ™˜Ÿ‘Ž™‡Œ‡„žž‰†ŒŒ‘‘“…ˆ–£šŽŽ›’’’Ÿ˜™—‹„€t‡‚~xuƒ{x~ˆpqffpw\atˆjO]˜VHmyUdVSdPMUUUQOX[bVIQjUWTGOXUI>IHOQPxMNV=<KD?@A<@CUC9AK=5;E23;:7*4:=+-341*8**+*,)*(/*&)%3;,$2)2021%/2Rc02@f=NX?C,?LT_/Ik7RF;•Œ¯ ¤ª¬™©£­®²´¯ª¤¯©¨»¿¼Á²°¹­¢¶¯ÈÇÇÐÀ¿½º¼Ã¾»ÄÂÀ¿®²³³¶½¼Á±²´«´©¥µ©¥­³²¸®¡¬´±¯±¹«¹®ª®·«ªžª« £¡µ­¨¡Ÿ¯²¡´ªŸ¨§ª¢ª¡¡¬­¨½®«®­¡§¨Ÿ¬™°¢˜¢ ¨§ž§›™©°©¢Ÿ¬¢¡’¡¢¢§™™©¦˜˜™‹‡•ˆ}Ž†„…¤—†ƒ„‡’…†–¡—ˆ‘‘“‘•˜‹††xt}txz€{ut{k‚‡¤vi^ek€ugˆ‹|RVp_KxsTdSQ_MMSZfNMWYeYGSjRR>BNQaQ:IHLSIqQLS;<I?;<=;@@W<<>H73CB15:93-5::)-31--6)(+-,52#2)',%.;.&1.0-14%,0Mh:38_=ad?F1CP[[+HP;YC3± ¤¥ª£¤¢¬¦³²±¨¤°§ª¸¿Á½±©ºª§­°ÉÆÇÐþÀ½¹¿À½É¼Â¸±°µ²º¼¹À³µ¼¬¹¬£´¦¦«±µ·±¥¦¹´­´¼¯¼¥­­¶«­œ©¯¤Ÿ¤¬ª¨œª²¤³¨š«§©¤¨¢©§©½«´°®©¤ ¯œš³¢–¤›¥¤Ÿ¥šš¨ª¥žš©¡›‘› ¤™–©ª‘™š“‹‚…~ƒ€ˆŸ‡ˆ’…‚•›”†“¡”‘‹‘›“–‡Š€rzy}{gv|{uqr~j†y…ˆd_gcr…{mgy]^VBW{mTbPRYKLNpt]IZ[hYFVgOC>KODCA9HGKS?jaIQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11&/>KI1%90%,,09/,,+6'17#-/GjI14X=fbAJ7GS`U*=<F\@*Ž‘°˜ŸŸ©¤¢¡«¤¶²±¤©°¦­¹Â½·±¤¹¬©¨°ÂÈÈÌ·½¿µ¸ÁºÈ¶Ãµ´³µ²½¹º½¶®¹¶¿¬¢³¦ªª®´¶³¨›¹»¨±¾²º ®´¶©«Ÿ­±£œ¥¨©£›¥°¦¯ Ÿª©§¡©›£¨ ­¼§®±®¡ª¢¤®žž­¦˜Ÿš¡¢›Ÿ›™£ª¢š™££•–” ¡–›–¦¬ŒŸ’‘Œ‚Š€€{š•Š}€Œ‡‘Š…“˜‘†“£Š’‘‡™”ˆ}zl}vxxbzzrpqtxj‚uk‚gcgansŽmbjo_pA]ykV^NQQKIMSYVM\^lWEXaO^PHMDF;7HEKO<rhJK9AE;;==;;=J49B<3;G<4?18-78;2(09/,5..=-*L>*49&'.34.0+/4&,:$40AhZ13S=e_DL6KVdN)=3R]>#‘–¬˜Ÿ—§£¡Ÿ§£·¯­¢¯¯¨¬¸Ã»´® ¹¯«§³ºÇÊÇ¿¸Â½¯´¿·Ä¶Ã²°º±²À¶»½·ª¹¸¾ª¤´¦¨©¯­¸¯§—¸¼£­¾´´¡­¸µ§¦¨°³ ž¥¥§ ¥™ž¬§¨ž ª¯§ ¦—¢¨Ÿ°¸Ÿ£±¯¡«¡¬¤œ§§¨š››Ÿ¢•œœš©¦–›ž¨‘˜’™“™–¡ª‘›ŠŽ‡}‡~‚Ž||¡‰z„…‹Ž…‰“šŽˆ”Ÿ‰•‚Œ—‘|…|tp|qss_xxjoqqpk€sdzlgecaf‡€`[rjrMN€iXZMQLKHPRPGM[_oTEYZRgOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23/:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%53=fd24M?e]FO=RZgH*?0][5(•›¥˜œ•¬Ÿž¡£ ¶«°£´³©©ºÅ·³®¡¸­­«¯µÅÇÀ·¿Â¹°µ½·¿»¾°¬¾°³¿²¼Â¸ª»º¸§§´§§ª¯«²¯¤—»µ¤«ºµ¯ž±¹¯©¥§¯²œ¡¤ ¤£ –›¯¥¡ž¢¨¯¡ ¡’£¤¢¶°¡¦±«Ÿ¬£®˜ª¥¨Ÿ˜š£“š›š¥ªš››¥•”—•œŽ“—¢©¢‘Š‹†z„~„‹z—Š‡{ƒˆ„‰…“˜ŒŽ•™‹–~†—Œz{prvnos^xwelllkj…nfrijeh]ds`[kviZJ^[XOOKHHRUG39]^lPEYUYeMIIEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<"8R=*113>D5,-'42*;+139cm74GAf[HTDT]hD.<2dW,2”¡¡–”›ªœ£¡¢¡¶©­ »·¥¬¾Å´°¯£µ¯¬¬®´Ãü³¿º·±³¹¸º¸º¯®À³³¸¯¿À·­½ºµ¥¢²©§©±©«°Ÿ™¿´¤§´µ¨ž²¼©¨¥©¯¬™¢§œ¤¥”— ±¤™ž¤©©œ¢Ÿ’¤ ¤¸©¤§®¦ž¥¡¨“ ©¢¡¡™›Ÿ‘™›–Ÿ¡ª›š˜ ”‘”—šŽ““¤¨¤‰Š†z„{„†}Š‹‡{‚…‡ˆŠ’…–’’‹•”Ž”{ƒ˜‹w~|ltrlksawuhhjhgp†hhidfii`jcjh[f{c`StT\[RLJFIOS@!*h^iLDWU^`KIHEC.:B<F<6KPD8:D357==895?:;4>8@K=>93)8><:9*6@3.E4(+,?0-N?.+-7,1195,&.5-80576`tA3CDg[KWGU`hB379gP'2ž¢¤‘Ž¤§™œž£´¬§ªº¶§¬ÃÁ¸±¬£¶®§­®·À¿¼²Â¶°®²¶¶¹¶¶­ª½³®²±¼¿·¯»»±¥Ÿµ©¥¤³¦¨­œœÀª§¥¯³ª¬µ»ž©ª«±¥˜žª¦¤‘˜¥¬¡˜¤©¡›¡›–Ÿ§µ¦°ª®¡¡ž¡• ¦ ¢ š›™›’˜“¥¬¡—–”“•—‹˜›© ’‰Š‹‰y…w‚‡‹ƒ‰~€…ˆ‡†‘„—”Ž‘‘‘Œ“{ƒ•†s~~fyojjkftskcgddvceffejickr[_Y]ldaNiXZ`VJGHKMRX>9_lhHCUT][IIGFA.<?9A89RG@7:B037=7692:<97:9DM=B<0*<@;A=-5B37=++,0B*JK./*+3722(57$+7.72685]yN2>HiZLZJVbf@:3BhH%5š£ Œ¬¡–– –¤³±¢²½¶¡±Å¼»²±£·¬ª­©¸¼»º­À±®®®¶¯³¸³©«¹±¯®³¶º¶¯¸½¬¦ž´©ŸŸ¯¢¨­›¡¿Ÿ°£®±¯·®µž­¯­­¢™§©¥Ÿ•š§¥Ÿ˜¤¢¨šŸš“œž¬¯¦º¨®¢¡š›ž™ž¤š¤—ž˜›”˜Ÿ’¨•ª§š“šš’Œ•™””›ª§ŽŽŠŠ{‚sŠ˜…‡|‰Š††ŠŒ‰’…•›“’Ž‘—Ž€Žƒofymgkifprk\gcctbfgjnlgjjhn]llrp`TcicfYIFLMOXRQUae€UAWSYTGIFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9A1-+.3<;K6/.+,-24;6#3*)6.55465Z|]19Kj[M[KXdd@A1JfC&4‘¡›Ž¯˜“¡š©±¯Ÿ¹¿µ ´Â»¾º±¦·¯§­¤·¸··¬»®¬ª«·ª³·®¦²µ²®©°¶¶°³µº¦©Ÿµ§œ¨ §«š§½—¬¤®°¶µ¬­Ÿ±­°©¢›œ£«¨›”›¦£š©¢¤–šŸ››¤ª«ª¼Ÿ§¤ ˜š™¡k¢–™œp‚•š£u‘©§ž””žˆ˜š€–Š¢y‡”ƒmiwƒql†‹†}…Œ‡q^cag„˜…kŠ”’tw‹„~ƒ€g‡€guheW\hsnMPicgs…h_efnmj]`aŠƒ„eNKD9GTh^JGPPUULHSapteF[QUPFHEC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=A@@=28@E=1,,08=G701.*.*/568,#1'214:175Xl16Ok[N\K[fb>G1Qd=*.‹¤™†•°›š“ ›ª­ª£½Å¯©·Â·½½­¦·°¥ª¢·³²²°¹¬©¦¬´¦¯´¢©·¶¶¨§¬¶²®´­³¡©Ÿ²©¡£™¤¥˜«¹“¥¥¯³·­®¥©®«¬¥¡žœ¡§¦›– ¥¤››§¦“žž—§©¤¶°¤£¢–˜——£ˆ¡Ž’š†¡‡“œ ¥¥ªž’’š‘ˆ„sxŽ…ˆ¡vŠi—ˆf~sx oˆ‡„~}¡  ™€}‡žs†Žu›Šl‡ƒmieczlraS…mbli˜qXiqpˆY^i[ll[ˆrnzr…f†„Z_GN?G_MERVVQQRWUg]MVHRROFHG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82*/1<I9/01.*/(-4583%&2115>1<8Xƒu25Rk[N\L\g_=K1Wa7/(Š§—ƒœ«˜˜Ÿª©§ª¿Ã¯±º¼¶À¿ª¥·°¨¬¥²´®®²µ©¨¥°­¥´²›­µ¶µ¦§¨²°¬²§­© °§Ÿ£¢˜Ÿ¡š¬³“£¥¥¶½¦­§«ª¬¨¥¡ ˜ ¦£™˜¥¢£˜œ¤¨–“¢›“’£¥¦¡·¤¤ £˜•“—“œˆ¯—”‰©‹–¡œ…±€£¬“™”y‚Ô¨€‡•ÁœÆyx±¥·—e€Àœ¿y„…z’„|‘Êr—»œÅzrµ§º{€m–±«°yhlX±®nei¼’¼ngzorØ~Skc¶²~r”sš¡ªWOWbOVNFU[XQQS]W[QA\DQNEHI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>:B<?A8:J>52*22BE/.32.+/(-/186- /416A1=:Wƒw21Tk\O[M^g\>L1[]41!Œ§“§ªŸ—œž¥¬²©°Â½²µÀµ¶¾Á«§´¬¬¨¦®³©¯µ²¦§¥´¥§¸­œ³²¶«¥¤§±­¬°¦ª¦£¯¢ Ÿ•™žœ­«“¢Ÿ³º£ª©¢­®¥¡œšš¢§Ÿ—š§Ÿž—ž¦§‘œ¦™“¡¦¢¡±£ŸŸ£––’—’™…¯kjŠª~fƒ•†­dp”™¦”q®¡¤~x»}l¡v±_j´[¥€eœ‘`gƒ{gjxk©e¾qg¦‹u±j{±xt’”cnm§n[„¡Ehf‡–Euœ`~g|¤§‚Z`Œ«h€•xyj§7J¯\XSld[KNX_\WV;NŠOWW/ITSJDFF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=03.33E3..53/+/(.0.:5/'$203B/=;U‚v2-Vj\OYL_gY:M5_Y30¢•ƒ­§¥ž£¤ª±·¬µ½¿°¶Ä²·ºÁ¦©°ª®¨¨°®£°¹®£¤­²£©¸§ž³³°£¥ ©¬¯«¯¦§ž£¡¯š¡›–”–šš«¤•š¡Ÿ´³¢«œ£­­ ž™– ¢¨œ˜£Ÿ›™¡¦¤œ¢™— Ÿªž¦¦ š ¡–•‘–š…µ›µx…©™µ™v†³›·~“––©”~k‚¦{‚†ˆ“”“w«gk±\«z†”t‰r‡€ˆ—x‚‹—‹ƒ „°vwŸqlll|‹N¤XHbb™~ch¦`yruS“‡^Q©mcq~‡€bœ.Q¡o[Skh`LK[dX\ZB>²{XXA#MhFCEA@A19>88:84;99<9:A:E::;6:CB8=?KNG:5:AFB@AD<FD;0201;F,0.840,.(/3,>831/2-D1=<S}n3+Xj\OXM_gW7J8aU50” •ˆ³¦¦¡¯©§²¬©»¶Â°»Á­¸·¿©¬­­­¥¬±© ®»ª §³¬£«´£¦²²§£¢ž§ª±§°§¥žž®•ž™”””—¬¡™™¤¨µ¯¢ªª¨ª›•— ¥§™ž£Ÿ›Ÿ£¥£•›ž—™œ¢©›¦šœ›¢ —“‘’“ƒÕ“™¹p°Á~ņ|֔›»|š•¥¤{Žˆ¤ƒ¥‚z¬yV¯zˆ~Ÿj¹Z¹v†„~¦‚”{—zªxz±nŽ„t‘¼…o”P¯§ÅŠQ zc`ªbsrˆm—ˆ`Sµ´È…€‰|c¤3Bv]PjicP@XgZdaJHMqP\QOYfYCD?E?0=<59;74<;8=:<C:F:;>6:@C;6@OLH<:;DHCBCD<EF81211DC./0483+-).323971#%5*>3==Qwj6*Yi[K]O_fT7G:aP71%›¢”˜²¨¨¦´ª¥´©¤¼·Á°¹¿±µ´º²´§°¯¢¯²¥Ÿ­µ¨š§¸­¢¯°Ÿ³´° ¤žŸ¦©°¨´¨£šœª•˜—••“• ©œ™–§­°©£Ÿ­£¨––›¡¥Ÿ—¡¡¢¡š¡¢§›ž ž”˜š¦ ›§•››Ÿ¡˜’”ˆ²nhµq«‡nŽ¦r´sr¶{š—¤‹¢‘¡¦±vƒ‘ÒÒv\®{…¤o›ª¦k‡…}­}˜™Ž{±q’žŽx³e—t„žožg”QȋZÂ\Ÿyb_­`vs‡b—ˆ^Yʝo¿uMKµSUÆdTQjceXAOk`lhPVGJ9=URZWXIC?J<2?;5=<46>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>HI91746A>/.24252-).26,742&60;5:=Pqh9'Wi\BOT_eP5G=aL620¢’¥±­£«¼­¦´¦§¶»¼²º¾¶¶´¹¸²¤´² °±¢ž«¯£—¦¸­¤±°œ´·© ¥ž¡©¤±§¬©£™š™§•“——‘¡¦Ÿ•“¥ª°¦¢–“­ ¦’” ›¤¥ž”š¥§¡š£Ÿ­™ žž•›¡œ¥••š¢Ÿ•˜•‘š…¬{w¨v£ˆ†©o­Š‚§ƒ˜˜¡‰’š‹¢“š‰®…‚³\r³R®}‚‚¤q×}x…~†š™v¯†‡‘œ‡w´ašeš‚‚•m’Z°XKšu˜yf`­^vwˆh˜ˆl]¯w•žxl5yÈ®²_BTo^g`EPl`pmVVM.feiSYP;AD@L:5?91=<16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK96<46:>/04333.2..18*.32%!03767=Pke>&Vg\@>V_cN6GC`H:99 ž• ¹°—´Â­¨³¨©²º·³·¾¹·±´º´¤·²ž³¬ŸŸ¨«ž”§µ«¨¯±ª­³£›© Ÿ§¡µ¦¦©¢˜”¤ “’›—‘”¡¤š’¦­¯¦¡•™ª £‘¡˜§¤ ”š¥¨œ¤ž­¡œŸŒ“žš —™›–—¢ ”—¦†©}}¥x¡Ž‚ªp­‹§†–Ÿ¡‰——ˆ£‚‘ˆ”ª|€‹xo±Z¨‚‚ˆ ytØvˆt¨Ž›Œ’¤{”Ÿ„{²^d ~ƒ•m’]«[Z“€‘hgªdr{k˜‡s^«Z‰ ŽkoeOJC¡\[Lt]bgN[a_rs_KW7J›–XHE=GFAM35A8.;>05A78@<6=<F?:<6?=B7.HVJEAH6KIN@IK@EN::@5.:>102144+*05/7,&21($$6671<PeeA&Uf[?2U_bL7FI_C2?8¢žššÁ«—´Â®«­©¥´°·°µ¾¹¹±°´¹¨º³Ÿ¯¤¤¦¦ž“©°©¯©´«©®¡˜  ¦¤£¹¢¢« –›‘¡Ÿ”“ž™“—žŸŒŒ¨°°§ž—›¨¦ Œ’¤–¦ª§”˜©§ž ¢­¤¡ž Œ”¡˜ŸŸ‘—œ•ž¡•–ªœ®mr´s©‹uŠ§s´xs³€‘¤£’œŽ‰¤‡w¸p{‹¢jk¶Z¡…e——i¡¢§m”r´t“™~²j…‘‡­ju³af¢o‡“k—]­`M¡|‡‘Rs£ly~o˜‡r]¯V<œwfTon.\§OcSkebmZc]ap{cT[R>=np3CB@?M:!7@6.;@37C58??3;<CDBJFMIF62JTKEBI6IJP?HNCFP=<E50;;010/75,+,426/#00,,289/9N`eD'UdY>/U^aL5FM^81C8¦œ›ž¼¡›²À®­«¬§·©·¯µ¿´»¯®¶µªÀµ¨©¡›¥£¡œ‘©©§µ¢²§­© —œ§Ÿ¤«¸¢¬š•™Ž£¢•Œ ›˜œŸ‘“”ª¶°¨™•œ¬©—Œ”¥—£¬¢‘–«±£Ÿž¦«±™¡¢˜¢–Ÿ›•œ–¡“©œ”ª™‡Ô’š»s°Ã€Ã†}Ֆ›¸xˆ˜Œ—‹Œ§ˆz¤¶u~wv‚š²`ƒºyÀ|u¸cµŒ‡©}•«©q{t¼ˆ§ ia¦Ž¯¡~Œu‡ª}¾os¼t²ƒuxŠnšˆrn¤t½^w}Zay¼kZV\jy^jaegcmxoY\ZC@@s@CF+5G"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB=E84=9020.87-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-7A9§›ž¢½¡—²Ã°­ª«¬±§·¯¶Ã°¸°­¹®­À°«£¢ž£¡œ›¨£ª²¤´¥¬¤ž•šª˜¦¬¸œ¢­—”Ÿ¤Ÿ’Œœ¢—š‘–’¯¹²¬–˜¤¨§”–¤›£­ž‘ ¨«ŸšŸ¨£´Ÿ¢¤Ž§¢”¢šœ—•£˜¯Ÿ’”©ž„˜¶‘Œ·•x‚“šµwmknsoy…ŠtŸÁ»½š{±¨q€s‘¹ƒ}‡†Œ‡|Š‡˜|¤»¹½œty´£tw—vt°u™žf‡jµtrqw¶Œ^z}‰hƒynzc‹¬pu…X[§jEeZTf`c^cQggpluCNQMD:ZM?J3;0 8>;.3=A99?=;<C6BSYZZ[[Z[^`b`]SGGH4DITBKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7LT_G'SbW9*O^]=+:VU'>;<§ž¡¢À¥–µÃ´¬«¨¬«©º®°Å­³²­¶¦³·«©¡¡¥ž ™“ª£¬©¥µ§§Ÿ›• £«¤½¦¡©–“›¡›‘¡§¡’œ—”˜”±µ·­™ž¤¤¢‹’’¦›¥ª›•©¥¥›™¡¨¥§¤ª ‘­ž—¤ž———ž¯¨“›¥¡j}i›¥w†r}šŽtyd‡{½¾Àºo“ƒr–ˆaskZ^›‰`cˆ•k`€–dnžwc–l€š•”e^`bp™ˆir‹}†•gkrtx}b[wthP\mƒ}{‹kXkz‚sJJo†pNtLEX]gaL[Wgc_O[mtiqRQDEM;GI=M?2,2A?8/5?C<9;@;=C>RVVWYZ[\\]`aaa`\UG5DFUEJOHFPIIH;8=51:.0;:.0-76=5&"/*2,%;8-7JR_I'S_V4)P_L(3>[O'?2>© ¨¢Â£›µº¶£¬¥®§§µ±¬È«¯²ª³¢½°±¥Ÿ¢§£›™™«¦®£¤´¨¥›—” š¥­¨½§¨¤”“›•Ÿ™’—¤©¨ž‘˜œ°²¿¬œ§ž§¢‰“‘©š¨£šš« £™š£§¬£ «¢š±›”§ –”Ÿ–°¤— §˜›œœ¡¡—¤¡™œ™™™•gm}qw’˜”’†Œ¶«†˜•ŽŠŒ˜–‡”•‹„“”’‰Ž“”˜”˜–™Ÿ¡™š“ œ‚z¥…mk}}€uŠŠq‚xyvu‰|Šjstƒuew}wkozm_d]phMYZfj`WZoxmmfUPFS9OZMRO(+:KB635=@A9:C><ENSSTVWXYZ\]`bba_^^[TKCSGKNDGPLOI<:;389,2;820)6IRO8")+/2#4;*7FO[J&R^S10T^:+=8\J,<-@³¡³¢À¡¤²²¶ ©¥²§¥°´ªÈª¬¯¥´¥À§³ ¤¤œ£••Ÿª¦¬¢£¶«Ÿ˜–•Ÿ—­©¥Àž«£”‘›——’”¡žž¢§“’™¨§²Ä°›««Ÿ––¨ªœœŸ¬˜¡›œ¢¤¯§¢¥§Ÿ®˜—§™™ žœ¯ œ¡¥”–‘—“žŸ”¡— Ž–“ŠŠŽ—®|–œƒ’‚‹«©…€™—‰„žˆz„ˆ†š’ˆ‡Š–›——£•˜’œŽg¡³¯…Š…v{’Š}wyzofy€‰juyˆsis{vƒ‡‚judzf`jecdfkYl{oik]SLPD^TF@?>,4@F;45;>A;<?>>HNNOPSUVVXZ\_bca_^^]^]XVJKLBIOMRJ;<:786/2964.(&$-1./)+*7%+<(6CMMD/T\Q05N[17E4[G5<,@´ ¹°¿¬¬¯²± ª¦²­¢¬³¯Ä¯©ª¢±­»¢³›Ÿ¦¢¡œ˜—§¥©¥¤¥²µž”“™™¯¥­¾ «¢‘™™”‘•¡œ—¨œ„Ÿ«¬£´È´ ª¤«—–—š¦©›Ÿ¤«”žŸ ª¯©¥£«¢¯›Ÿ  ˜¤žœžœ®£˜ž§’–•›‘£—–§œš–e‚’|e~šcyŽmhk{’¥«je›˜}g†Šeeih{Ž¢lh˜‘£wkjŠ˜¢ž—skmz„ŽˆzXf^†ƒ^mŒŠv\hswv‘€ˆ‚mwxsmy„tv‰ˆƒ|j‡Y^ltd^s‰ik|pkd_RNXIdXAJ4>F7?FD71<=?AD;;DGHHILNPRRTW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%/*+'6*$;'/AJ[J/7ZO6)EY/DO2YC;?.=¦ º½º¯¬´±ª¥¨­®°¦­­°¼°¨¦£­®°ž«–Ÿ£¡™™¦ªœ­£¥§©²­ž”£¢¯¥¶¹¥®¢ŽŽš¡™“’š ™™¥•|¦®£¨´Ä¸¥¢§¯Ÿ•ž¢ž£œ£©¨’Ÿ¡¡ª°««¤ª ª›§Ÿ§ ¬– ›¥¯£–›©”Ÿ›™‘£•œ©—}½ƒˆr´r„†­hx¹Ä¸q”££z¦™™r«‚|ËÀÀ»qŒ£ˆƒž|—™‰À½–ŒœÁÁ|‚|“šÃÀ}l¥²oŒoÊz›vƒŽuy€€yqz‡pw…Œ“ymx”cg`xd`e‚b^sglddYLVIQZHOD2IE?DB>/<?>@A:8CCBCEHIKMNPSVY^__a_^^^^___]\SMPGUNA??=6468276*&%#)*&.+*)109*#>I[L*#BP.#F[3PY/VAB;/8–£¹Ãµ°°À©¨”£¯¨°®­¦²³®©¤¥¦¯ªž«˜š¢Ÿœšª¦¡œ«¢¤¨£¤´¤œ¢’¥­«·³§®¢‘™œ¥’‘Ÿ¡˜› ˆ§­¥«®ÀÀ±¡©¯©–’Ÿ¢™¢¤ª£“ ¢ž­¯ª­§££¨¡¥¥¬¨‘£š¨¬©šœ§›ªŸ”–£”Ÿ¡•›Δxz¤y•–›_®^Ž¨‚£¡|§–›s«ƒ€¯^cª{¨‡… t—“ˆ³c‚«† ³j„¯u}—ˆ·aƒ­Z£Ínv{Ú{™p}‡’v}ez‡vvk|‡n}†‘‘~mƒ`rmph``zd\qgidg`RTSW]KOD5AHDD8>6;@?A;=7@>>?BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5578164('$!',&&/(&+360$7;SL+,-K0';\;L-!P@F4.1­ÂÀ¿µ´°¸—‘£ª§­³«¦²««ª¢«¦®ªŸ¦›™¥—œ¢¯Ÿ ž¨§¢¥ Ÿ°«š•¦®¬°ª¨«Ÿ”‘šŸ¤’ž¤—ž§£Ÿ®¦¬±¨¿Ç³¨©±®–’œ¡—Ÿ©ªŸ•¡Ÿ®°©¬ªœ¨¨¥¢«’¬²–¤¡ª©¢¥¤Ÿ®Ÿ‘˜¥—ž™““‘— q…Œ—u…¨†q±}žr¬¢Ÿ¥žv«‚}­œs­¬‡†Ÿv™’{|—~ª‡¢Œ’Œ~«{‰”Ÿ€{­WÅ{p“Á}•muoŒmevd…nawnro‰Š’ƒn’‘fpuuqagme_oiiogdXT]aZRSC9II@C<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^\[ZRC>;92478452&# 1' 1' '45-&7=WJ-<(>1)3W@F!G:C1.+°ÓÆƲ´ £Ž£¢¢¬¯¶®¨±¥¨©¦­««¦¡£™¢•Ÿ¥«Ÿ¡¥Ÿ¨¨¢ž°¬—š–¨§®«§¦§ž—”™¢¡’” ­›§¤°­¥­µ«ºÍ±­¦®«–•œ¢™ž®¬œ— šžŸ©³«««›¬«¥£¬š®±¡§«­¥—¤©§§¯ ‘•¢¢˜“„¤j¤u‰z©tz²p‚¦Š™Œq‰ ›‡¤``R«…®ƒ›v­‚¨†…Ÿ{™—…zf€£‰¤™†‚£}©~‚–‡®_|©Vž£’z£Ÿ€{ïŋr¯³³¹qb©¯ÂthŒŒ˜Ž‚nœ•qozxypmgeerpf}jc]W`jXYUMMQLCCAB;CA@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^aa`_^]\][SIB6799664,&$" ('"+-"$.!3-&@DWH,G+56*2PKL# A9D4,'ÃÉÖÔ¿¡™«§ ¯¢ž°´°®©¬¢§¥¨ª«©¤¦ ›¤ž¥§§£œ«™¢¬ £Ÿ¯¡œš’«¤µ¯® §š•“¦¢‘›¢¨  ¦±¦¦©²­·È²µª«©–‘œ¢™ ¥³š¡”Ÿ§¬­¤°›­«££ª¡²­¡©²°¡™¨§¬­³¡‘”¡¥–™{ªlž„‡u«y|°o‚¥Œ‰Ÿ–– •Ò¸´¸É²_`”©ƒ¥ˆ‡ z™•šxªÉt™¤•¨©‘“šœŠšÆÆyg¡‚¥tŸŽ‚}¯]p´b°uK£‡m§G‚“dž‘|q™•q|u~|n\fjsqfk_aYdn\_YIMMKEDAB>A<B?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75685/)(%&%$&),4ENPPMFKJVF*L0/=-5OTQ;<F2,$§¤ÀƸ­¨²­¬¥¢œ²¸¬ª¡¥š§¤©«ª¦Ÿ¦¦˜ª£Ÿ®«¥ ¬šž©¥œ§¶ž¢—“©ªµ²¬›¥œ ”¥¬‘šœ§£¡ª§®¢¥§ª°µÃ±³ª¬¨”Š—œ¥›¡£®¥—¡•™œ¦¦­œ±ž®©§Ÿ¬£¶¬ ±¸®š­¦°±°¢’–¦¡˜ž‚NxšŸz„£}ƒ¤…‡¦ŸŸ”„¸{{y¹‚Ìƶx›¡‘‹Ÿ~š–—ŠvŸ—Š¥˜¤©°…† „¬}š•c¦m¤p…}–‚r¬`£sq€š`¼}RUtŽ’£–{~”“w{s†q\nnxrj‚o[d`iocd]KLQTAIHFI:9K>B108866877-*5==?BDGILNPTVYYZ[\__^]__]ZZZXUSOH@882.,*.+*''?QTVWWWYXXWUOUF<E3:P[T6?H,- ‹‡˜©«¤«¹ª®Ÿ›¡¬²³¥ž •¥­­®ª§œ¦§›£¨¡³®¢©¦² ˜©¤”£¶¢¢•—¢©´¸£›¡œ¢’¡±™žœ§¦¡¢°®¦©£¶³Å±­©¬©‘‡œ¨¢¤œ¥—ž™šš¦¥«›°¢¯¥¦˜¯¤»­¡¶µ¬œœ³°¶¯°¤–œ®ž¢œ…ÑµÃ·y‡Ž…‘“€¦y”¡wŒ ’„¥Šqª†…´nrjš¤œ•ŠŸ}˜™†‡s¯‚¦œ£Ž¦‹“‹–›nq²]¥t“zœl™{™|m©a£qqŸbs²¸hw”¦˜}Ž•Žz~yƒnjyizsou^eeonfh`J[XX<HH@U4@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^__][[ZXURRQF:223//++(@QRTUTSTVWWXXWUUVTQOQ[U%!2AH$)%’rŒŠ­¾¿¼º´ž–§¤­µ¡¢™”¢§¦®ª«˜¦£Ÿ¥¡¡¶§£¨§°£”«£Ž¤­¢ššª³³¤œ¤œ¨‘”–®ŸŸž§¤¨¶›£«¤¶¬Ä°©«¨¡Œ„Žœ¢ ¦£–™š™œ™§¦§™­¨¯£¥›¬¦½¬”¼¯¬ž¡®±·©°¤™§¯¡¦–y¨‘}|°wŠ€¤¥ˆœm²p¡‡­|¡ƒ¨•˜€¬‰…­… •ª ¢—†Ÿš•€{’~«€›–‹«x¡’Š”’z¯^¤}¦§d€|—sj¯]¥kp…™]`[Œ m•‘¦™ƒ–ŽšŽ||„™€knctn€z`hfqoihgCYa[>KU3U8BBC7$$3+''3, /6674359@CFIKMNQRSSVZ]_a``aa^][ZXSPONI7042.*,ATVVVUTUUUUTTUTTTVWWXVUUQHFIJ#((½“šƒ¨Å¶À³žš¬ ­·¥£Ž›¤¢ °¯ªŸ¥ ž­™ž¹¡£« ¯©™®¡«¨£–‰š®°¬¦ž¥›¬——¬¡¡¥ š¥®˜¢©§·ªÁ¯¤©£ž‹Ž›šŸ¦ž’”™›•›š¦¥¦›ª¬­¤¥Ÿ©¨¾¤–«©¡ ª°·©«¤ž²­¦¨—u¯~‹œ…‡~º­Š™e°e•­}¡„§•š¬Š„°…¦š¤¡¢‘…¡\lj³`­{{ƒ±mgo™™Œˆ±[~µ\¤„kÈ¢dŸ€{¼Xv´Y²}R®€z¬X€¡n˜¨œŒ˜’šš|z‘ duc†xu}bjgqngfePUd\AU`>I(>9=4!",%2. *1/045799<ACFHJLNPQRTWZ^````b^_\[XUPNJFC553./@UYXWXWXXWWXWVWWVWXWWXYZZ[\XWWGB;ҟ²±·½º³Á²¢œ¬¦¤µ© Šš žœ³³©Ÿ¤¡ž¶™ ´¨ª¬ž¯­¬›•¯§¡Žˆ›Ž¯«¨¦¡¥™®’˜©™¢¤ž™££¥™¡£ª³ª½¯¤§ž~‹›–¡ ˜‘šœ’š˜© £š©®¨¦¦¢¥¨»žŸÅ¦£§Ÿ©³³ª¬£º«ª«”€©’£¯Ž›€‡¤—™‚€¸ÃºƒŽœ“„§—œ‚¬Š‚¯ˆ§œ›¦«‘ֽªb£¿½}~£‚ƒ×º¸µ…•“ƒž½¾„m£‚o«„lœz²°Çƒi«°½¬xw¢¾¼s€–Ž§‘œ’š {ƒ“ž|c~{egzƒ|alfkkcQa[Sj\@UbCN)=:4/$%2 $(0496677;>ACFGIKMNNQTW]a\__a^`[\YTQMHC?=A?5=SYXXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ¼•³³°¿¸±¼²¢œ®¦¥²¦‹˜¥Àª¸²¨¢À§¨³Ÿ²º¨Ÿ­¯¥§””°«—Œƒ›‘®¥¢¬ £œª —‹£’¦ž¦›š¡©£™ ¢¬®ªº­¨£›—“}ˆ™‘¦›’‘˜™˜”©›¡™ª©¡«§ £ªºž¨Ã¢Ÿ­¢©²²¨­§ž¸¥¬¬™svª¥¸†d‰ ph®‘‹‘nnw¤™Ÿu®™”p‹q•¨¤œ˜¯¤smmlf‹xon‚™qzjqigŠ—–˜qii†ˆgq†d]ˆbjoY\f}v¦_aqŽ‘ned“¢™™š“™¡}‰‘˜wfˆxil{€zemdgmcKdXJkZ:QfER'K:+# #,)-2.5:457:<?ABDEHKLMOQSV\WZ\``a]][TPLHD=:AB7MXZZYYZYXXYXWWWWY]^^]\\\]^]^][[UW^©”¬³©¹¸²³ª©¡®ž£³ª˜’¿³ÅÊ¿·ªŸÁ­®¤¢¨¬Ÿº£¤®«­¦Ž—®©‹…•–­ž¥© ¤£ ‘‹¥’§™¨™—£«¡—¦¦¨°»«¬š›’’|„–¥˜‘‘™•Ž˜–©– ™ª£œ±¦¢«¹Ÿ¯À¦£±¤«®¯¨«©¥µ¢¬¶•Š¡¨¦·‰–£™ˆª›‘•’©³™š£ª ²–¢¡Ÿ¢œ¡¥¢•¬§““Œ‡“œ•‘™“™‘•…¥›˜–Ž‹””Œ‡„~g‰~t‚us‡Šp§lz““’€•¢—š™¥„‰—tj‘wrŒxx}zjmedpeU`Y@j\HdbPY+F=+'!750.!%2(*699469;>?ABDEJKKMPPQXUWY^`ac]^TQKEC>9=@ASX[\YWXXXXXYXXZZ[\^__`^^^__```_YY`¦–¨ª¤´¶®®¡°£­Ÿ ¶±Ž¬È¾Æ¼º«£¦Ÿ§Ÿ±©£¶§©´¦¨‘˜¬¢‹‡‰œ§•«£Ÿ˜§žž’”£—¨š§™”¦¢¥‘›§™¢¶º¨ª˜šŒ|”‹¡”Š•‘–‘”˜¦ ›ª ¶£¦«·§®À­¢µ¥®­®ª§§±¶Ÿ¬º˜‘¥¤¦¶¢’ž§ Žª Ž“Ÿ£«°š £°¨°—£ œ£ªžžžœ–¬ž“š¢›”–«šŽ™™—‘–Ÿ‘ˆ¡ž–•†’‘Ž•‹~e‹…u†ux‡‚sœj…’“‰}‹•’’˜”£”Ÿ™¤…‰›Š}s—t|Œ€s|joe_qj`[`ZndQaeQZ:GGE>2=>9/*&+)&&416668:==?AACIJGJKLMSSTUZ``iaeVPKACB:9EMV[^^[Z\[[[\]]^_]^_`abcaaa`bbbdb\[c—•£§¢¯±«®£©¦¬Ÿ§µª¥µ½°®­£¤›|Ÿ¤²¤¥±©—›¹¦£“™ªœŽ†Š‰œ£­¢•¨Ÿ ’–™›®‹¨•¨šª™©Ÿ¹·¤¥™œŒˆy‚”Œ›“Š•’”‘’—£ŸŸ©žŸ¸£ƒ¯µ¢®®t¢»¡±žvwž¨¯¸“t«£ž‰€«d\bv ¥Ÿ„˜}m’³œ£§­ª£ežŸ’syš˜p€˜©˜m¢¨Šeœ¦’˜˜–’œ†ž›‘—„’‡’‰…wjŽ†v†p{…`h‡‰“‘‹Zu”ghs|¨œœf{›Š…y™j†Œ„oz€kre`wplki\febbqT[>NNNSG>@UD:1/&4:306678<;>@AAFHBGFIKMSUUY]`hfgXQJ<DG<8UR[`ab`^__`aa_\]__`aabcdabaaedchd^]f›•¦£ ®¯¬«©¥¨­¢§­¤’–«¶±³§›«¨­˜tŸ± ¨«§”—¹  œ¤‘‰ˆ›žŒ«™¢•§¡Ž–’ž…u­ˆ§›ª’˜¥Šœ»´§ ™˜‹‰uw“–“Š“‘‘””¡œ¡§™œ²•€Œ›´œ²Œ’Žº¥Ÿ}§¡y ¬µ¥žƒ‹†°ª¯‹—¤›z‹¬…œ¡§¨§‡•…˜w¥›zˆœ€—§‚{œ³zŠ†¡˜š•˜–‚‘——„›™c{‡…’‹ƒmpŽ‡y€p€„~…s…ƒ”‘x–h’t šu}™„£ ‰˜•†…škŽ‡ly|rqheypjlk\elkfu]^ITLR@E6.ZUU7)!09>>743568;:=>>@DI?IEJLGSX[Y\bahfZQH9EL;>aV^bdfd`aa`bb_]`aabbbcfgcba`edcgcaahœ—¢Ÿ¦¬­«¨¬ §°¦¦©¥™”¯È¿±¢—¨ª·Ÿ‘…ž­œ§¢ Ž¾žšŒŸš |†˜—‡¬œ¢–Ÿ ‘Œ“‰…€’§‡£ž¤•™Ÿ‡Ÿº²§›’Ž…qv‰•Š”›Œ’ ’˜¡¤–ž«‡Ÿ´‰´™­ŠÊ‡©¬ˆ¶…Œ¯®«‚¨Œ¦˜}¨s{wœ§—h•¤y´ŒŸž¦§’˜Â«ˆ˜¡rž€š¥}—…•³¡}¡”¡˜—”œ‹™’‹}…“‡–’‰ƒms…~yq†€ƒ{ƒt„€–€Åf©‡£kž…¤„šŽ‰Œšq”†iyv|xhivrhhl^dpmgnYgG]RM3E57Nbd7&3<EGD:64658;8>==?BM?NIJLCPZ]\Wa^il\QE=KM@JcX]cfhgbbbbdc`_babccceiicbbbecafcbbi”–¢Ÿ¯§¨¨¥«Ÿ¤·°©«¦š” £¤¬¥˜¦¬¹¤°¢©¦ž‰”½™“¡’žy„—–‘‡«™››™¡„ŽŒwšœŸˆž¥œ—š™‡£¹­¤šœŒŒ~bm‹“˜Œ‘“ •¡¡™¡§~¡§‡­Ÿ–­œœ„ Œ¨¬…£©™Œš¢u™”k‚­vM«x‡œ‘š¨¦€©«}ƒ¡{z§jž’kg—†˜·‰ž~n`dYƒ—€|dh‹r™}y–l]}—m_Rpƒ\_kx‚_Xd|ƒ—p§ªkƒ£nr¥pŸ… jg m\pŽ~gZ`„cXQpwfnuskjp^kqnljYiO]YF9A5HD_l5,IDRMN=84859;6@;;>BP>QRLMBJ\]_W]^bu`MD:MONTb\\ffiibbdbddbab`bdcacikdbddgdbgeach—• ¸ ©£¦¬‘¡µ»ª®¢™˜¡¢¥­¯¡ž°¶¤©“¢¡ §œšŽ™´™‹ŸŒ•‹u”’ŒŠ¦••™žž~’……¬¤‡›Š™ª™››’ˆ¦±§¡•šˆ‰€inˆ‡‹ŽŽŠ‹’Œ‘“£”ŸŸœ¢¤“¢ “Ÿvœ•§Ÿ¥~…§ª‚¥x‰|„š~¢ps”ˆ–|Ÿym†›Œ™›¨™Ž‡{‚¢sv¦fž~w¤_˜z}”t¢n˜·´ºt“ˆƒ€µ¨dÆ¸{p•¶Œr€š£cs¬«`|i³~m|†‚‹˜q£lr£tŸ…¤a™´—s}˜Ÿ³ut\ž²ƒkcpuwripYlmssg]j^bLE=D6QBZs3=SG`JR=<395:96D;;@JP?UMOQ@E__[ZX``|dHC8MWUWbaZefkkbbeadd`ab`dd_`cknccddhdbgfchh“•”£·˜ª›“Ÿ¤·´­­ š¢¤£¦¯œ³¯­”™¢š¡¥™›•Ÿ«›‹ˆ’x‹…q€–‰¡’”˜}‰¨¡‡—Ž‰’¤•œ›Œ©¨¥ž—‡„~j{‡~}ƒ‹‘‘‰”¡ƒ—ž Ÿž‹‰wœ˜¡ŒŸq¡Š‡©‡š¤Ž•¥¨|­Œ~z ™z£“xt–ˆœ}–Ÿ†›Ž˜›¥…¢d¡|ˆ–›mžh›Žoš™z€‹§}rit«ƒŸƒtªh•š]›…v…žgªk€¸f\¨pœ`•Œ^§vu‡ˆ~žhšu†“’—Ž€Ÿoš‘n§š^©y»k~ª\Ž„]´h]nrzxlj\qkyzdagXbBRFO7WCRo5L[[_NZDA251<:7H?:CHU>YRY]>Db^V`Qac}jEB9N[^YdfXfgnmbbe_aa__``ec^bdoq`deekecihgki•›‰©´š§ˆc”›«º±¯¬ž¦œœ© Ÿ¯œž²©®Ÿ˜¥›¡ ™—— £™†‰jˆ€r{—ˆ‹––„‘•˜zŠ„•¤œŠ”†ŒŸ“ž‰‘©£ šŒ’Š€€i†y—Œ{‰ŽŽˆ—›”¢žŸ¡“˜rhŸ‰žŽ‹p’Œ©†˜¡¥ž¥{°­£¢¸—w£³£¤€‰”y{«™~¢Žœš–ˆ—q¡|…¯µ}kš‘¡y~˜µ¢¤«¨„™|›}ž›tªZ]o{–‹xžbL{z…cy—BLŸX¢jq{Žl€ˆ„™u›x†‰±³€›“§wƒžnt~•pštk¤^•vHedatrofaliw|eebQ_W]UW@ZFQhETW]bX^ID=B8?B:IF8LEXAWR[VDFb\Z`K`m~rEB<U_bZeiVghmobfg^aa\]^`hb_ecvl]egfkdeliiki“œ€°­™„S^ ¦³¹²²©š¢Œœ¬œœª•¢­¥£© Ÿž›š–™¡–ˆ‡‰w†oy•…‘›‹|‘“–ˆr€ˆ‘¡›s‰š–¡›…ªœ›•‹‹Š|ƒl„…q‚¡Œx†ˆˆ“™–|“¤ ž¢ˆ­†}µ„œ{¥–z©€”š‰žš{§hwm~™t¡sr|ž†™p“ƒ®}¤ƒ¥™€£o^©gu¢co¥aœÓ}{™xssb¢†~£t¤vk³Œ`‚˜‰sª²¨¼wƒm~¿¦©´]›m|p–mr¢r]¤gs¦`h¦m›Ôš~†›p{{˜lœ|x˜sn©¤gaezr€…lhfdovxhacS\fQRbHYJUaWT\fk\eQFCKMJKBKE8O@QNXSYOSQ`ffjRcwywIFEc]eZhjTihjocjg`c_]]]_hbaie|d^dgdkdjlfhlh—š¯ªT\K~©¯±³¯²£›™…™© ¢¥¦©¡š«‹›™™”™“’¡˜Ž‡…{p}„h}ƒ•›€w‘Ž‰o…Ž’’l—“|‰’”¥—ƒ«›”’‹†‰yƒvˆ€n‚Ÿ†w€“†ˆ™£˜{”¢£™Ÿ‰³¡¢¶‹z¬§¤®¥p©€™Ž…€™z¤€¡™†˜rž„¤®¯Š—Œ€¤•ƒ­ “vµ¶µÉ¡s”‹Ÿ`ž—©my–‡ ›t¢ˆw ~“—‹pMf£’p›‡s¥{ytaƒk~ kqd_œq}s–hyi³µ´Æ¦s˜}zkœ›«v…›nwy˜jš{v˜sQE}³_jwlzˆgkhcuvqoW_TYiPShIWMYTV^iloVhWNKAJMKHJOAQKPecjmetrsy|nu‰{{TQOl^i\kiRjhilglfce_\]]^ibdik{_]dgcjfomeile¡›ˆ®¥ƒd?“¡²ª®¯µ¢¢€—ª¢£¦¦¨Ÿž§„›˜—Ž—œ“Žˆƒzjy‡eƒ˜ yu‰Œi„…‘‚Œ…yŒ—¦”„™ª˜‘‹‰z€}‹xp¡†z•‡‰– –”¤¦›••ƒfnxœl¢d{q¥w›˜pf¦€”‰z¤zŸ–ƒ—sžwŠ•—¹n‘Š¢b}˜ •ˆnriªku mo¦`›i‹i–‡›–u¢~š`Œ†upˆbh ež~i›uocfˆmq¢Y^Zb¡l]ˆ‹nz}srd¥mx¢dg§h™sŒ™p¢pU‰o _f¨U‹^T˜nntksƒnqilytkpRYWWfZTmIZP]IXiisjYlWQRFV\LXSaUik_wt{}p||rƒ{€sv€„v^RrbgcpgPjhhklnhdg_]^]`jbjivu]\chcjjslfkmcœ£—¥ydsm‹¦­£©°±¦Ÿ‹€˜«Ÿ§£¢œ¤£–™”Žš‹˜ŽŠ{‡q€ˆi‹‹|˜›su‰~{dƒ‡”‰Š•™‚|ˆ‡˜¨’£­‘†‹‚‰~€€Žri¦„}‡“ˆ™ ˆ“©¥œˆ¦x•›~¤ˆ–‹±˜‚¯—Ÿ¤u“…x©s¥„šn¤¢Œ’„ƒ»n}¥¯ƒ‡…†“•œŸ|¥zr¨• –gž~o¬d–Š–“w¨mª¢‰v‰ƒw«‘¦ˆk‘°kv³Œ©kŠ…mmŸž‘”_}«‹ªv~~‹¥žvŸ|ƒ¤• j›ˆx¬hŸ®Œ¶tw¾¤“Zƒ§Ž«avsur|uqckohmTW[Vab]kM]R^J^mow`[qY\`[gtenorcrt`wz~yryƒs„{{Œƒ€vbxdcnrdRkgholrjfia`^\akbmlzo\\bibljwmglnb•¤©œ£–©©¨¦®¤™Š‚˜¬šŸ¦Šœ¦ž«ž…›‡œ‘…’Œt‡{ˆ„o…~˜“tt†s’‚m‹‘‡†“Ž}{‚‡™§€§§Ž‰…”v‚‡’nl‹©ƒŒ”Ž‰Ÿ‰Œ”©¢ŸŽt“—ˆ~y”®¢šq†wŽ‰‚}{r§Œr~}z˜–›„y{~‡”•“Šv˜ž ƒ{}‰kŒ…[yyrzqin~’‰q€u”“q‡„‚eŒ_€€‹wus”uoynm‡lƒ†^ugwŽe€„Œ¨š}t{•j‰ˆpv}‡wnnhtz|˜x…\lXyioxsrpxxp]l‡ojhW[`W]fkdVcU_R`pyymkwfkkkw}rrutaovbt{‚xuz‚u€€€y‹…ƒ}{nldyn^Wnghukxjije\`Zcjemqtn[[bldllynhkoa“·¨¦‰ ¢š¦£˜¥œ«¢¡„„˜­’ž¢Š›¨›ª˜ƒ‚œŒ–”‡ŽŠ‰rƒ|}~„{˜tr„q•…{}’‹††„y~€ˆ›¥|¨¢Œ†…•‚†Ž˜vr„©†Ž’‰ŸžˆŒ›¦žŸªƒˆ•š~~‰–­§’¥wo›Žxn~¨…q~•qkp}‚ €“Ž‹hl\‚‹‹›šžŽs•‹ˆqtk‚wtYrn‡‘~Œj]je{†„‰€`ixz›{‚‹‚u…gwŠ†j`oq€u^q‰€ˆŽ¦”…e‹ƒnw‹„q†zqhif|„{–[]khnv\|zxvotsƒh]n‹llcZZ_[Ylq\_aZ_^ft|vpudkkk|}s|yuenuhm|~wz|{yz€€~o…‰„{}t~yshT\qilvpugkhd]aXkhkkqrnW[enlgsyohjl`‹Š©°¡¢¡šž—ž˜¨£¢~ƒ™®Ž •‰£‘¦•€|˜†}’™‰‰†‡Šs~Œv…‹‚„—Šro€r˜†ƒ~’ƒ„†‰€z„œ¡‘ƒ¨¢ˆyŽ—ˆ”Š‹œ—„ƒz­‚‘˜š•Šž‡ˆ¡©ž¡¡£Š‡“›œ£™•ª¡§¦Ÿ’š†”‹zvƒ§~“’”²¦›•Ÿ±’—ƒ¥ŒŒ•šŸ‰›‚ˆ‘Šk|Žwxeƒ†‘‹|‰ž„‡Œ‰‰…„w|ztš ‰†Š‰„“~}Š€tnr„}v……‰Ž¥‚…Œ†‚ŒŒ}ˆŒŠ‘„zn„…~z™ksiat‹q~{xwpxu‚]^oˆio`_Z]]ShrVd]]bmhv|}topekji}ny€rjpqlg{r‚€x}„zm‚Œ†|zx{}zƒxNcvjsnpzekecb`[tfpgrqmU]ltmhyzqgikeŒ‡œ¹ž–¡ ˜”˜™”˜¤¡Ÿ|š¬ŸŽ† Œž–}y•„|Ž™Š†ƒ„‡nysˆ~‰”„mk~z—‡ƒƒ~€‡„…|‡…œŸ“ˆ¬ „sŠ†’‘‹‘}{ª„Ž“˜–œ—‡‡›¤ž¡™œ…‚’š™˜™¦Ÿ¤œ›•Ž‡tz†„¥{|Ž‘†™«¢ž”Ž©€Œˆ“™ž‚—~‡Žƒox†ru`„†tŒ™ƒƒ‡……„•nyvt’¢ŠŒ…š„„Œs‰|{qqz†‚zwˆƒ‘¦…ƒŽ€ƒŠ‰Šw†‰‹~rm€‚}oilnh^z€i~}wvwv{x]`q~nu`c[]_RgnUf[^bkivzrlmdkjhlt‚llupzp†yn‡€v‚€~…vq‚ˆ~{||{‚Š`h{juii‚djc`i\cuhobumlUcqyepz{sejmm‹‰ž¶™ £Ÿ’‘•˜‹šŸŸŸ{xŸ§‘œ‹‡¥•Œ™™z{†}‰‘„Œ‚‚ƒn|€ys…~‹’}kh}‚—‰ˆ{}†„†|‚“‰©q‹‹Œ’† ¡Š…Œ|¨‘‰’—“–“xŒ¢žŸ•˜~€š˜’‹™¢ £˜•™|‹‚w‚Ž† ~ŒŒ|˜¥¢¢“š‘¦Œš‰’–›~“’~‡Žut‚qwa~Ž†q‹—}‰ŒrŒ‚…†hxrxŒ˜‘–~ˆ‰r†{{owzŠƒyx‹‚•¤“Š…{††‡„vƒ„‰‰}hs~z|rmlh_~ti}vvt}sk_`tvpwdcY__RkiVfZ`aijvy‚rgldlhf€kn~hoqly‡zlŒs~tv‚†|{}irƒntia‡hlb_qVtolm`xhmWjtvcuz{rbjoz‰Œž±‘¥¤œŽ—†œ ›ž|w¥¡Ž˜€£‹‰š–y|†ˆƒ‰‰‚r{tvƒ…~‹‘xgc}†—Š‚Š‹x|€ƒy–‚–™˜Ž—¡›pŒ‚‘“†¥›‡Œ‰ƒ¦–…“‹–—“’v‘Ÿ —“–y~Ž——–šœ£œ—‘“™wƒvƒ–~‰Œs—£Ÿ¢”™¢ŒŠ‚–—ƒ’•™~˜|ˆvq~n{d€|‹…p‡“€‘‚lˆƒ€‰…fuo{…‘˜‹|“x‹ˆ{†{zp}wˆ…xƒ‡Š—¡•ƒ‹vˆ„ƒ‚w|ƒŠ†xazzu€yhmfbjkxttw~r}cdasnurmaZa^[meSdYaaikuy†rckcmfh}‚liuhnpj€}ƒym†r€ƒƒ~t|ƒŒ~z‚ƒ~|mv‰sumeŠljbbuV„ipn`xglbjvpfy|zq`rl†…›­—¦§žŒ—‡†Ÿ“—™~xª‹™z—ŒŒ™y|Œ~|„|ƒxtyzt}€„€‰‹€d_}‹”‡„†t|~‹}˜†—•˜¤¢˜€s‡{“‘‰¦ŒŽŠ“ ’„’”—‘‹—žš‘r‘“ˆœœž¥—–‹“•q‹‹‰k„—™z‡ˆ‰o—ž›¤”–‹Œž‹†‘œ’’•†™ˆ{ŠŠyrzlul|‹~m…“ƒ•wpƒ„~~‹€eri{–—ƒ~t‡‚x†}tv~|„€{‹‚‹“£xƒt‰‡}€tv‚‰…qb|v{r~pcpde|copwsyxtubv`plvno\\`^^k^Q^Ycaint{Šl`jekchw‡ngmikmi‚}{woˆs€„„}t†‰{ƒ}z„}}Žrz‹xxml‡jh_irc‡gqoewgnlayik}{xpaxm‹€˜˜©Ÿ¤¨ŠŠ’†Š‹•™~x¯™—}Ÿ”‘—”ˆw~|Š}|€wx€€put|o†}Š|a\~‘†€ƒ‚rz€‡z’‰“’“¦•‚}}ŽŠ‘£‰ŽŠ˜š†’™”–ŽŠˆŒ‘›’ŽŒŒm„‘ˆž™¢ –”ˆ•l†—‚e„˜Ž“z‰„Šp–›•£”“‰‹™Œž}’Ž’Œ™Ž{Š…‡ssvlqnu|Što‡‘“qu|ˆ|eply|™“|ƒˆt‰€s‡xn|€…{„Š†‹”§Œz†{~‹…x~qp‡…fizuvq|c_qakt_qk{zylsqey^olsmrX[_`bl[PXYechrrˆg]jigbgqodjheiizwuoŽ…t‚ƒ{u‚ˆ…x…|x„…z‰w‹{{rxƒjk_pht€kromrgole|cn€zvqlwwŠ~¢—¡§ ¦›‡‹‹œ‡“v‚«•“Ž‡¡–”€t|w…xyrs{†kspzn‹v€‡op[Y~‘‡€ut€€ ‡’‹”ž˜¢•˜yŠˆœŠ†’˜–…‰•š—ŒŒ‹›‰‚m‰‹‰œ–¡›—”„–†h‚¡e„œ‰~‹ƒ‹w“™“ “’‰‰”~}Ž—{‘ŒŽš’|Š€‚ovplmop{†it„™‹qwu‚ˆƒyfrnu€™Ž{‡„y“yu‡soˆz„ŠyŠ„€†›¢‡{ƒu‚‹xynl…ƒ_tutrry[_qapk_pk~|qnnkmvapokqmYYbaboXQT[fgcup…ƒc]kmdbfk’n`gg_hkursp‹€uƒ€yv€‹€x…xˆ†wƒ…|†‹{vŠjqc|c†|nqmtjholvx_qy|tut€ƒ~¤•š­ž§–…„—”ƒ vŒ ”“†‹›–Ž‹zryu‚pr…tqvˆlpnvmˆvƒ~€mmUQª”†‚wvqƒzƒ¡ƒ“‚•”™“›x‘{ƒŒ’£™“Ž‰•™’„‡—™Œ”‹‰Ž†œƒ‰{r‹…ŠŽ‡œšŸš”“~’|fƒš…f…Ÿ‡‘„‘‚‰qƒ‘˜œŒŒw{‘zŽ‹Œ’–Œ|ˆ|€kwjnkll{az~—‚w{‚xƒŒ}ygsls†•‹}‡…z“qyƒou‹yˆŠyˆ{€ŠŽœ„{zv‚‹|wqjl‚„{ayqonstV_pbrb`mozqipfgsuirlbwe]WfaasTQO]ge^yp‰}`]irbbff‘j_he[gp~plqtŠ}v|†€uv~Œy{…xˆƒs†…~ŒŒ„|y•xfrjƒ`ˆ~ookz`jntu_t}y‡xts…}x ™±œ¥Ž‚‹ƒšˆ€ŒŸ€‹š”…ˆ˜Ž„wtwt€qo…tpr„pkiwnƒn}}mtrRM‚ßȒ֓{pu„v…¡„”x—’™‘™{”s…ž¡“”‘Š“œ”†—–ˆ‡‘Œ‡›~€wzŒ~‰ŒŠœ›œš“‘xŒte†…k‡¢„‘ˆ–ƒ†cŒ‘™–‹—ŒŒŠŠqz”ˆ{ŽˆŠ“‘‰y…|m|esoklzz[yz~€†Ž{{isjsŠ‰…„|”Šk}~mŠ}Š…|„x€“™˜‰|uwƒxrmgq€…nlupikvoS_pepZ`msyhlkcgxrpqd`xa`Vl__wQNLbgc]zrŠv^]evabeeŽdagbYissnkqvŒ|tz†‚uv}‹s†{‰r‰ˆ‘‹ˆ|~˜vesn|eˆ~opl€Ylnyys`vz{vrwŠwyž‹›®š ‚…wˆ•~|Šžˆ† ’…Œ˜„“‡txpyqo„pmoseeyq}my}jgkc¤šÁÜ®ð¡slv…w†¤†“o˜’–¢–œ’r†‹¢—ˆŽ–‹–ƒ–…‰€‰ˆ•}†zt‰w‡„Žœš˜˜Žu‰ul„‡‰|‰¢ƒ‘‰œ„…^‹“˜‹‰‹‹„‰m{–}ˆ…‰‘†v…}~k}dxvjnysX‰{’ˆ…z~†Œyfri‰‰‚~‹•„kum†Ž‚}x~Ž”‘—trw‡Œusqgvz„cunqckxhRarhlV`ouzard`i}pso[drabWn[]yOMLegb^wtŠn]]dy^_ee…`cc_YjsknkswŒ}tw„xw{‰qƒ„}~ˆ{t‹‰ˆ–†Œ~—sgurylŒ{ntqWqzvyrdwy†Œiv€‰rœ†˜§›£’„}qŒ”wyŒž……¡|–€šˆ„{swptjp‚ljm|u_axw{qu{g`d|ëÚµÉÃ܇slt‚w‹œŠkš‘ž–”‰q…ˆŸ„‹–‹Œ˜”|“ˆƒ‰{‹…Ž€uxƒ„rˆ‚“œ–”—„‹u†}n‚€‡†˜¡‚“Œžƒ‰aƒ”‡Š†ŠŽ‡‡i|“}ƒ„‰Ž‚q†~qwhvsjtwlZ}“ƒ…}€„„Š‚vark‡Ž‰~~‘}mkw…Ž„{€{}‘Ž”ˆmpyŒ…tkqlsy‚aujp^mxaResifS`qwuap`]hƒqtkXhiciYnW\vMKLfg^bst†k\\ey^^dg{ad_]YkofojtxŠ~ss~{vzˆt…ƒ|‡vwŠ†™Œ‚{“ulwvyx“tnx{}Xy†qogxw’‚dv†…pŠ–…™¡š¢Šˆto’Œqwœ~‹š‰‰} „š€xrtnodrifmxx\`y{{qq€jagaÕ¶Ž‘¦xoqx}q”’Žˆk›Š“Œ†{i‡‹™†’‘†‡˜Ž|‰{Œ}ˆ„zszƒzp†€–šŽ““€‡t‚„t}ˆ›ž†•Ÿ~ˆb€“‡…‰…‹€€ƒg|€~‚Œ~mƒ|‚tlmwutwvlcŽ€…~}†„‰p_qo„{Ž‹{~ˆypƒeyˆ…Š€z„|~’‘‚mny‹~umnkl{dilkZoxZSjsibQcsxmcf^Zk„ntb\h_em`oU\pOHOgf\hoq€n[\cs`\clwee]]Zlmcmjsw†rq€|}tx†x…‚}€ˆuy‰“•|‰†vˆpxy{„“on{w^ƒ€tmizt”sgsˆ|q’‘ƒ™Ÿ› †ˆvv”mw”˜ˆ„‹Žš}Œšw~vrpljau}gbjuz[`x|zlpecggW_qs–½Å…wr•‹‘€t™‡”ˆskˆ•€{”‹„›Œ|Š†}|‰Œ~“‡t‡…vv}qu†ž•†”Žq~†s‚y‡•›–†“€ˆf~“ƒ†„Š‰r}g}‹{y‡‹}i€|ƒvfpyxswtlk†‹‚‹yƒ„„€k^pvz}‹‡„{€Ž~r€hx…‰„w‚{•ŠŽ‹|mkz‰|vtoih~we]rdYquTTosibNhuyga^]YoptZec^knaqPZlRDThbZlom{pZ[^mcZcowdg\]`kjcliswƒro~{tuƒzƒ‚|‚†v~‰–‘xƒŠtˆsyy~oo{qj‚yz~nm|v•kjx„tk“Œ…ž˜ ™…ˆo~Œvjy™€‚Š‚–˜Šy–ozsqljd`t{i`fr{[ar}zfpzaedŽ±²wKbZ¥ÚҘs|’‘z—Œ…š’†ol…’‘yy“†€„™Š|‡€yx‰Šƒ•n‰†qs}{jy†ƒ¥‘„’Œ‚~n}tvƒ™—’Š“”…ˆp{“„~„ƒ‰ƒoxh€…xrƒŠ‡|e|~ƒucqs€iyqou™†„‹|wy€„z‚k\o|r‡ƒˆ}…‡zˆq€mp‚…Œ‚‚qƒw–ŠŒƒwml~„vzehj~raZx[ZsoOXrtg`Knwvb^\[Yu~spXg^fkr_oOXiS?Yg_[qkgyr\[YleZcpy_h]^elhflirx‡pn€}vp‚{€ƒv…‰—Šq‚q{†|zy„”Œukzlp~u}or|{“poyf’Š‚¡˜‘ƒ†g‡„pgz—Š€…‚šŠ|ixrllf_aoym`coy\dlƒzaqv_deÕ뾋3:>‹€ry†ŠŽx†™Ž”Žnm…Œ‹u}…‚•‰|ƒxnv‡„‚•vm‡„ku{ueyƒ„§ŒƒŽ‹‚|l~rtxƒšŠ‘’Œ‡{’ˆy€…Žƒl€ri€xm||Šƒxby„‚rdqinuru‚œŒ€†tv~€sp[k|sxˆŠ{†|ˆwypk‡ƒ‚ˆp€w}“‰Š}smjv€€uu]iiyqZW~T[rfM[srf\Jryq][[Z^v€viZb[hfocjNXgR>^f]^vf_uq[YUodZeqy[h^`gmhjkipx~Žmj‚„€yn{}‚zu‚Œ“…p€‹nw}€{{ˆ“‰€i{}kt|r†{sv}~Œzx„~|kŒŒ„›–Œ‚m~liŽ|~ƒ”‚}Šˆkuqgic[cgso`altahp‰zast^bc› n]6[°¶uj€‰~”‡xˆ™‡uŒŠwpm…‚†ty‰x‰}“ˆzsgvˆ}|–no…}hvynez‰…¥‡€†Œ‰}m}t}{Š—†€“˜‰‹…Š|Šq|~†|i~mk€{yjzw‚‡r`w‚~rdrgvƒnu{†•’‚}‚€pwz|umWm}us‰€…v†t‚‰zwrmˆ€Žƒq}{|‡‡ynmhm‚un]hgurR\}O]r]O\spdVKtykXYYZbrva^]agdijfOZiNAbd\`wa]unXXSub[eosXj_bhkgmlipw|“lh„Š}|p~{‚zw€€‰‹„r{‡oqw„{‰„j~{nxyvŠw}x‡„~~zm„Œˆ˜£…„|v‹zkm…‰“z}{‚’€€~Š„prpcf^Yg_pp`ahpfjo‰tato[`djv{¿¨¥É¸r…„t•~z‰•„t’Ž‡rsp„z‚su†tˆw”‰yyqdw†y’hqƒufwvdj|„ˆž‚~Ž|q}r‚w~Ž‚v•”ˆ‚ˆ{‰Šlyz€uh{ilysizv€ƒ}h`wˆ}kjth{€jv‘•|~~q|w|tbUu{qr‡‚{p†‰wxoo‚‚‹}|w|zsŒ„€uhpglˆrp]hctoLfwM_oVTZtnbQOuybRXX]bqƒt\b]ieeckdR\qIDeb\dq^]xhVWVx^\fniVl^ajgeonhpwz“niˆŒy}s{~y‚‚|v}ƒˆ†ƒpvƒsnw‚‚~ˆ‹”q€|xzz‹uƒx~€‚„z€uo}Š‹›žˆ~†{w†|hu‡’z€|‰†„v€gpn`e\XfYmsaaaqllh‰n`siX^cm€w©Ú©È‡ˆ³rŠyqv}‰‘{”‹€utu~vopm…t”†xul`y€x‡eq‚ngun[m}“€€x’‘|wzl…s~Šƒr•Š‘ˆ††{†muwmhwem|vmkww|`bx†zhuvc~{hu†Ž–}u€vr€{}m€ZUq|os…}wkˆ†sxjtƒ‚|y{wzq‰{rgsdm‹„ls[j`vfIooM\cXWVymbPSuwYQVX^ar…p]acmec^ocU^sGCg`^gi]Z{cRV]v[[glbVk``nfflphpvxtkŽvvx}wƒ{t}ƒˆˆƒoququ}…‰‹{wx„|}…‡xˆ|}}„€{~rvx‹ŽŸŒ‰{Šwuƒz^~‡šz‡„t†‡…w‰{bnm\b[[aUjtd`[hopg‡qaqfW\ck|Ê·º¢kno‹nr…s~†Œ{“…zytzutzjlvc„v’‚vog_|€xŠ‡dq€jjqcXm{†œ‰ƒr—“v}zm†oˆŠ†p–Žˆ†Œ„{yrrp~ghrcnxqjlrx}|y]ez€xiuyg‚whu‡ŒŽ•}s‡jo~€xn}]Wo|ls~ˆz€nnŠpvfv€~€uzoyr…zxqer`mŒkrXk_y]IplOXV_UV|kbOTvsRRTW^cu†j]akkfcZobYcqHAi]ag_\U{^OVfqZ[jh]Xha_rfjhqgqsv‡yn•Šu{x~yƒ‡€us……Žƒpp{xwuy†…‡Œ†z|u‹}†ƒ„‡~~}†|xvyv’”Ÿ~}‹nu€zd„ˆ˜†t’Šo…†‚zƒucnjY_[]]Uhse`YdrrgrakdWZ_ix¾®{ ·nbt‡iu}s{…ˆ{~€wxswozvejoa‡uŽsjb^}wxŠ‚ep}gkk[Vox‹¤…p™’qvs€l~€†r”ˆˆ…‰…}yuspizajmamvjgkkywzw[g}|yfr~n…tfu††–€p‹gk{‚tmub[mzjsz‰z€et†|mpgt~w}~pzjyyxvodlal‰}lnVjaxVLlmPSPiNY}hbOUvlMQTU_hw„g^aqigaWi]]ljJEl[beWYTyZNWokY]le\Zec^tfleqgsptxp™…vx|…‡}us‚‡•ƒnsy{{sr…†ˆ‰„y}v}…‰Ž„ƒz~‹ƒ{w|wvš˜zŠƒ‡jv~}m……•s‚q†‚‚€pflgW][\[Sepe_XcruivpdebW[[hpor€sŠefzjvwuu…†x‚…zwtvnkzpahkg†t„ng^_|nyˆ|glwfjdVWspŽ§}„{v–t{qzxlyzƒu—|ˆ†„‡„}uqsmhu]mi`mudggizo{sYgvuhpx‚vbw…‹}•‚oŒkm{qese`jwfpuˆy|auƒvjkqtzpywr{e}}}vumce`l†|mkVjcrTLklPMOpG^|faNVueKNTXalxf^gsje`WdXcr^LLlXdbUTUsWMYweZ_la\[de_wgmbojtoq~ut™x€x€~†„z}v‚ƒ~˜…nrt|{uq……‚z‹ut‘€|•Ž…„|~Œ†z~v{£¦Šy‰†…lu||u„ƒ{o†tz…}‚ƒunjieV][[ZScne\Ybt{jhmh`aW]Zi€ikp€hmbi{zkuuup‡‚z~wvn{hjyj_enhw„geXavi}†ynioff]UXoh¨w{|Žxtn}mqtx~w”t†ƒ€†‰vjtwhio\me^ns_gbjxh{m[mƒstjo~zwaw……z‘†sˆrpzrcqh[mudnq†zwas€phjxtqkwvsub‚y}utocbbl}|kkUibgTLniPHRlEayfbNTr^JMUZfmx{f_mqjd]V`VpoWJTiXg^XNVlTK]z`\_l]][be`zhlanpvnowuz˜}w€y€€‡†zyzƒ}“„qttzvt…ˆ~}‘ls•{‚Ÿ…‡}€~†‚€Š{u„¬Ÿzˆˆ„lr‚zv€‚uoˆo}€tŠ€jonedX_ZZZUbjg\Z_u‚i^ml\aVZ[kert}jj^mxwhuxso‡|~~zvslzhiwg]dsgzw’€ccTdof„uvfhiaWVYhd¨owŠŽzpn{fwmyŠzvŽq„~€‡ndwtehi]lb^po[h_muezh]t€nrkq{vubu†Œ|‰ˆ€xru~taplXpqano‚zscq€lam{pjgywspd„txxtoc`cms}jlTi^_ULudQHWbGcwfbLTqYKLXYilw{eenrfcZX^YwfTI]dXiYYIWeQIcy[^_m[^]bd^ij`ntxmonvƒ—yr€}‰Œ†~uv†x†Œ}tuu‚yzz‚‹}…‰jt–{Š}~…y€{~|†‰sq®Œ||‡~fqˆzt~}wsp†m|~mzcppbe]eVZYWcfk`]]t†hYpm[^WY[l{bqwvmc\ntuhvwro†yzwootehte[gufvv‘y_]Seejs|abi\TX^cd¥iyt‚…wlmxfwl{ƒyt‡ry}y€ifwmaga_k`^ukYf]oobze[w|knopxytuesƒ“€‰ƒ‰zvor}raxcYnn`opzseq€d_nvjcfxzrlmsq{qpa]dmo}eiThYZUNz`RKZYHcudaJUnUJLZWjms{dlltcaYZ\bw\TKd^YjTWHYaNHkwY_an[[_bc]…ihbnxymojvynƒ~€‚’ˆ„vu‰t‹†tqvvw}}~Œ“~px–ƒ}™’y€€xy~s‡„sp™¢{{‰–yeuˆzsywltply|p’s^poagblT[ZWidmf\\r‰eSrm[YXW`lvcjujj_[ntrmutuk‡}|wonldipc[krdtvŽs\WTd`q~~p€\ac^SZa\d“Ÿerq…ƒskixknnyyzq€vs{z{dfvh^c[ah\_whWb_phawa[|vjjrnxtttiq‚–„‡…vsjp|mfwW[ilaoqxseo~[aqqb_io|kjr}povjp`Zdkm{agTgUXSQx]SPYRHdtbaGVlQIPZVlll|emora[ZXZmqXSPgXWjTUFZ]OIsvY`cncXaaa^Œjcemzyloivy†{k„}€…™|‚„y}ˆm†qovz}t‚‚}‹ƒƒ—tx‚”…Ÿ‰u€t‚p‡ƒvo¢—t{†Œ‡{fw‹on|pgxq{lsvsk^tobgfkS^\Vhbll[\qŒdNom\VWUfishctee^Zpvoqvvzlˆ}}ˆwscdkoa\nmcsx‡kZTVbcw{|o„\c^cT[`Zc—•cnp‚…‰rifxmdruqzkytuo{v_gsd\_WbdYbueU`amdaq]]~ohisqtquvlm…”ƒŠ|…qrgn|oqoRZeidprtsbmuUcrk\^nd{dku|pqqim_Xcijx^fUdUWQVoXRWTPHes`bFXkOIYUWnie|ilykbW\V\ueTSWiRZgUTI[ZPNyw[_emjZba^^nbglzvnoivv~m„€~†—{‡Šk“ˆrgt€{v€ƒ~‰ŽŒ“s}Š‘…‡Ÿ†{†Œs€†s}‚un¤Œs‚Œwxnz`e}qgztymmqwƒgd|mcgghS`_Ug`lo\^nŽhNjl`UVSogskfxef^Zrvns|ytn‰{€wœ{zkaelm^`njeqy~gZVX_lxzzn‚^a]hVX`Xdœˆbkp†|vkiuk[upjyiurno|sYkn`Y^VcdYeqcT_biablZ`~kfltuomxvlh†€Š{ˆmqfp{lqlaX_gfnrrr^ilSfqeVbmaxaotztinkj_W`fhu\dVbVTOYgSO]OPHep]cGZjNJ`LYme`xio€e`U^T^v\USagO^cUTK]ZQZvv]_fmhXca[^Žqchjxrsmgvsyƒs‚ƒ{ˆŽ~|ŠˆŽznŠtls‚tˆ…‡’„•z}Œˆ‘›„€|„rstwqn““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~~~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’’’’’’’’’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’““““’““’’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ‘mfggggg}…„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDCGdhgggge¢    ¥^*....+H…ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‘g_```_^yƒ‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR4555549\`____]‘¦¤¤¤¤ªV;ƒ€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}zzz|}{|~}~}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‘ŽŒ‡‡‡‡‡†‰““’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†…………†ˆ‰ˆ‰‰‰‰ˆ‚ƒƒ‚ƒ‚…ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z||{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘’’’’’’‘‰‡ŽŠ’“‘‹ŠŠ‰‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŽŽŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…‹…‡†‹Š…ˆŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰ˆ………ˆ‡…‡ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰ŒŠŽˆ…ˆ‰„†‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ~|vvx||{|}}}}}~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹Œ‹„‰ˆ‡ˆƒŠŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz|zz|||{}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒŠŽŠ‹Ž‰ŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzyz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{z{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz||||}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||~~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰‡‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†…………………„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰Ž‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{~~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~€€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““”””””””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}~~~~~}~~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••”””“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””“’“““’’’’“”““““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘‘’“’“““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’‘’‘‘’’“ˆ…“‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘’‚‚’‘‘Žu†‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ˆp…|uˆŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒsoŠŠrx‡ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}|~~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒwm{‚sx†ŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡sno„{uv€…ƒ„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\YXXWTPQRSRSMMJIFEHJGGHGGLNIgsuxz}zxwy||||~~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzoq{xy{|{xw{xuwttvuuvwtb^d_akqfhklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkiffggghhb]jl]ffgeccbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHIJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__ac_\_]`]^ZZjwmbnsjaYY_[XWSNMKKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{xvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSTPMJMNPROM[krlanurfQQSPPNNOMJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTtsuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMN]cokYisupSMOPPPONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKKFBFHUbhlopomlZLLNMNOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtttwz|~}~~~~~~~~~€€€€€€€€€€€€‚oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHECFGHMZghgrnnhfd`^^XLJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:;>IZ][\elnkommlkihkdSGEEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxz}}}}~~~~€~~€€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@:;><;;;=K\imnojomkjlmfQGEDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnppsttsqrvxy}}}~}~~~€~~€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;:;;99:88;<979;:=HcosmnlkliUC>CFDBCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqtstrqtxxy}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<:79::979::78:99=J`ssphT?:;=@A@=;;><=<@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyz{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>><==?@===?C;==><:Bl}j@:;>=>?@A@??A@@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquutusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCDA?=>@A?@;[n@>DE?@AD_d;==;:=>AA@>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJGVppqssttuyz{||~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???BFD><<=@=8::mwI8;:=>A;Hd=<=<8:;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pprrrtuvz{}}|~~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC?>AAABA@YR=<=ILFEuvN788:;>?WjA;<<::;>??==9:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC@CszJ;\ƒz|wW<=?==>EhtL:=>?=<ASD?<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hlopoqtuvy|||||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCEAGrzkbƒ„ƒ‚ƒ€}^>@C@@=Js{Y:=AEA@YaGC==@DDA@?>=@A>>>?<>@DGE@>@A?@CFECBBC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqprutwz|{{{}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@Eot}‚‚ƒ~}„vMACE@?>Y{€]?CEIJIjfQMECGFGEGEEEDECA?@>>BFJJGEEGFFJNNKJIGGHKLIGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@EEhs}|„~y…rCDEDCWu†‡‡~XGHJLNig[[VLHNMHIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHHHGFEFFFDFHGEEHHFHFHFQnnpqruvy{{{z}}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJG`{€w„…ƒ„‰lAAVt‡‰‡‡‡ˆƒWHLMVedb`e`N_IGGGGFHFHECDDFEDDHHCCCFIKKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrtwwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLLN[|‚‚ƒƒ…††ˆ„Vl…‡†††‡ˆˆ‡|PLMcjihcfhg_@@CCCCFFEB@>>@AA@BD?>?DFHDFGIJIJHHHGIIIJIHFJJJJIJIJJJFILLJJKKfopsrtvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKLKJTƒ„„‚‚…††„‚†…„„†††‡‡†ŠuIMmumjiiikI:<>;:<AA@><998<<=;>;8;?AB@ACCB@AADDBCFHIHHHLMKGIJMMNMJJKKJLMSloqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHHJIIe…„„„‚ƒ‚ƒƒ„……†‡ˆˆˆˆ‰ŒfQuxtmmnolD7896479;<:8567789787588;;;=@;999=<>;<=ACEHJMLLGIGORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@CGIIh†„„~ƒƒƒ‚ƒ„†‰ŠŒŒ‹‹‰Š‹Šmv|„qoponK26873568:876565676767:67889:7578979776:<@GFIFIFEFOSRSSROPPRTepqsttvy{|{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@6788=:=ECBe…ƒ€‚ƒƒƒƒƒ†‰‹Š‰‰ŠŠŠŠ‹Š‹‹ˆrs|rqnonD3688557699776765:9:::;798987669:98868689;A=>>BA?AKLOQPQOOORWkqrttuvz{{{}}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897;B:=q„€ƒƒ„„„…†‰ŠŠˆ‡‡ˆˆŠŠŒ‹Š‹…lhloy}f>;;;<9:;9:;::9;:9===>;;<<:>;9;;<;<;9:<8::::999<?<<ABDIJMKIKLWorsusux{{{|{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<:89989:::;?>H~„‚‚„………†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹ŠŒfloy~^ECBAB>@CA@>=>>@???@?@==?B>@A?@?=@@@>?A<><;:;:9;?=;;==AACABCAXpqtttvz{{|}{}~~}}}~~~~~~€€€€€€€€€€~REBAGJNOLIGK:8:;9::<=:;;==?@BR‚‚‚„…„…„†‰‰ˆˆ†††‡ˆ‰Š‹‹‹‹Œyprov]KLHHHEFHGECA@CEDCABCB?@DHECECEDAFEFDEFD@B><@>=?@>?>?>?>>:;=<`qrttuwzzz}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>???=A@CDFW„‚ƒ„……††‡‰‰ˆ‡†††‡‰‰Š‹ŒŒŒŒŒŒ|srpXLRLKKIJJJIFDDGHGDDEFDBHIKGHGFHGEKIKIJKJCFCCDBAACBDCCDDC@=;=@hpsttwwyx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLK@BBA98<>;<;>@?A>BBGGIY„‚ƒ……†‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŠywuocQNLNKJKHKGDGIIIEFIFFELLMIJGGHIJNMOLLNKHFGGEECFFFFDEHHFCA?@Llptuvxyyy|||}}~~~}}}}~~~~~€€€€€€€€€€€€QA?>?EGG=<@@88<;;=:>@>?@CFIIP_ƒ………††‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒŽ…y|xrYNMNLJIFJIFKIGKJIJGGGKLNLMHHIJMQNONMOKIGIJHIDIHHFFGGIGCBACTnpuwwyzxyz{||}~~~~}~}~~~~~€€€€€€€€€€€€€€TDAABGHB?8?@9:<8=>;=A>?ADHJLUqƒ„„„……†‡ˆˆˆˆˆ‡†ˆˆˆˆˆ‰ŒŒ‹ŒŒŒŒŒŒŒyrb][PPMLIGDHJHMLGKOLKJJLMLOPNHIKLOQPPQOOJHJJLJLFGHGFFHFEEBABB\orwxyzyyyzz{|~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<9@>>@BGGAGKLPVy…ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹ŠŒŒŒŒŒŒ`\WWWUQOMLEFGMPOPWUQPOQSRMSTOMSLPSUVRSQPLJMMMLNGGJFFHJEDEEBECcpuyyzzz{z{zz|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?==B@BBGVNFNPPTX{†ƒ……„…‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŒ‹n_[mdHUSSRK;;STS`u]UVTVYYRXXRZfPUWZ]RTWQOMRQPPQKLKHHJHEFIIIHIirvyxyxz{{|z{|}|}~}}}}}}~€€€€€€€€€~~SHJIHGGFE??AAEACGEDELXRMTUVXZ|†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ~aŠ‹‹ˆrahX=[ZYTR?@WVY\d`VYbr]]W]ZVEQYZ[Y_TYgRVVXUTVTOOMJLJIILMKOMSosvxyxxzyz{z{|}{~~}~}}}~}~€€€€€€€€€€~~~VJJIHGEDDBA?HMIMPKIKPTSSXZZ\\x…„†………†‡‡‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~Œ‰‹Œ|rs[^]\SUSWWU[ZuƒYU}a\X]_WIV]][[_YHYXY[]XXYWRQMPQMMOSQQURassvwwvxxxz{z|}}}~}~}}}~~€€€€€€€€€€€xy}YNKIIHFBD@A:PQQWXPPOQSTTXXYZ[n‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—‰Šn†‰ˆ‡„‹€i\\][VWUXTRXVc–€RerXZW_hP`f[[X\gaGOZhg][\]]WROSPPRVVVVYZnrtwvvuxxx{{|}}}~~~}~}}}€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZ[RSQPRRRVSVTW_ux€…„„…††††‡‡‡‡ˆˆˆˆ‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†~€}`TX[VTVSRRMPMLfz[]TYUV]ZLTZUST^ZXWWWzkX[\\^TQQPINOWVX[Zdprvvttvxyy{{|}}}~}}}~}}~€€€~~zxwvsu{€€tk~kry^[VUSROKFCDAM^ƒlVRSNOQOQURSRRUcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰‰‡†ƒ‡‡‡zosZMNQQMOLJKEFIFC?TdURQQNKQTQMOYRMNQSUUMQSRPOMLHCIHRTUZ\lquuusswzz{{|}{}}}~}}}~}~€}}~~€~{vsw}~~du}iqt_d]^\YUPLILIal’tPQSNQRQR[RSRQRUTbs{|€‚}{{€ƒ‚…†‡‚†††„†…†va^OFAEEDDCAEQCEAC>CIGV@HNLG]iPHFNFDEFIGHBDHGIKGDBAD@OQMSdrtvustuz|{{{{|}}|{~}}}~~€€€||}€€€}vt{mh|gnqfiedb\XSQPURsWe[OONLQSQUYSUQQTSOV`klrv{{xytrnstsyx~ƒ€ƒƒ‚€‚€‚‚lOIBB<<>@A@@?kQK`EFHIEB?GLNGMQUIAE??<=<==?=?ACC@?==B>JNGUnutustvx{|{||||}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljjf`[QRZ\Y^JJPQNKLQRQTVUWQQWUPX[b]agmmlokg`nrjmlqu{z}{xz||xwxeDBBB>;CCBBDB\]O{NOONKLMOOQLKMWMHG@A<977599=;;;8:8:?<BH?\stuuuvwy|||}||}}}~|~}}}~}xuvz{zwyxuw{|yxuywcqhipmnmmhf^OP_]ZIHPRQOMPQNQRTVXSSYTOYZ[WY]^^_e`]^qvk^`gkwooljonnlfbYHGHHCBGIFFFDMRPaWSXQPSSRU[OOQVPMIDF>:96587979:365795<C>essvwwyy{}}||{|}~~~{~~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`VW^ZXMKTTSPQUOLRSTWXTTYRMWYZVXXVXY]WWXhsk]Vaskba_^da_^YUQNOOMIHJLJIFCQPS[WTTNQSYS\eUOSTRNKIHC?A9998978857578599Gmrtwxy{{|~}}|{}|~~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPXVVSTVOOUVXXYSUTLKTVUUUWPSUWTUR]n^RNZ_[VY;DVXT[fJLPSRONMNNNLJFQPUYSTOJNOUST\VRUSROMLIHHF??<:787659967665Wppswyz{|}}}~||}|~}}y}}|~~~}||}}~}|rvqxxrvuqqnppopuvtnjddjppqrpofedc\]RTZVWUTWTRXXYYYSUOJGOPOOMRJPPOPNNOTLMIPOSTU2=XMI@Q=caQSQPNPQPNNMQNTRPSMILJORPRRSTQROLMKLLHCBA=::876;B5566:doqtwx{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqptuvcjgeWhtrrqnhihpVVTUXUWURWVUZYXWUQSFEAFGGHFJDHJIGEHLHKHFLMPMG/E_R>3?>joaSRQ@GTQPQPQNQOQPLJLLOPONPQQNPOJLMMKGEEDB;==<9=G6677Dmptvy{{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknaePSTRSTOWVVYYVQQQO@=;=?ABAC@BEDA@GHGHEFHJMLEGCORC8ENS]gTQSAGUPOQQPMMOMKLKLNOOQLOOMHLLIKKLKGFFED<AA>;@E;<89Sprtx{z{}||{y|zz~~|{uturvvz{xzr|{|yymqoxrqunnqroootssrutkgg^ejmpknqmimcLOOMQSLTUTXWULLKI<987;>@><=A@B=>EHGCEFIGJJ@FAA@FHEJOHQRb\QPROSOOPLMONLMMNON[WKMQOGIHCHJLLKFFFE?BC><BG?B?Adptvzzz{|{zzw{wy~~|{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCD=9779?B>;?B@@>@DIECGGJGIEBB?>=CBAGIDMObeQMONWKLNKLNMMLLONSdNJLRIIIEAHJLMNJGIGBAB@?EFEHDKnovyyy{{z{zwtxtx||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGMMJMPMPOHJD?A=98::?B?<ABAADEGKFCHHGGHCC?B??@A>DECKNRTLJIMTFIIJLJKLIJMMOPRPJGCKGCBIILMONIJIGCCCDHJMLIYrmwyxz{zy|vrpurtxyvxjqnjllnttmtu{stxronqovsnporpopstyjN`gsjt|ygosqiqhdqGKDGHHGJKIJKDFB=>=:9:;@B?=ABCCGFIKJDIIFGGCC;A@B>@@BECIMPHHKGHKDHJLMHJLHIJLKM]RHHDNFACJJMLPMKMJKFGGJNNQNLbmivvwzy{z}rmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoiktgdoFKDFEGEFFGDGBC@><=9:::@C@>ACDEIEIJLFHHGFFCB;ABC>@CDCDGLNHKNHDHEIMNMGILGFGIILNKIGENHBFMKMLOMMNMKHHIORRSNRfffqosxu{y|lhjnekqlspfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGIDFFECCCE@DB>?>:;;=:<>CA>ACEFJFIHLHGGGFEC@=DDB>ACCCDGHIGMPJFFGKNOKFHIFEDEIJHJIFHOKDILKOMONOONJJILRUUROWd`amgqroryzgehhdilgqlflmgiklslpvutpnvrosrsutqssutsuvvvyvutwljuumrvqlnlerLHEEHCBABD<BA>A=::=?;=>@B>@BDGJEIFIHGFGECBAAFFCBBBDEDGGIFLQLIOJJMLIGHEGEDCIIHKJGKRMBNNLPNOOMNOKKKOUWVUSX_^\iaminhrsbeffdhhfnjfmmhkkmriqvtsqmvnoqrswsrstuvvvvwvwwvtwujsunutsqrjksMGHFHBBADE<A@@C<8:<>9?<?B@@@DFHEHFFHGFFDCECDIECGEBEGEFGGEJMKHQMJKHHIEFHHECIIIKMKOSNDQROPQNOMNPMLMSWVXXUX]Z]d`ibjigk_eefcgggkggkmkmlprhttursnvoqprtxqssuvu‚‘yvvtxuuwxmouorsuqqinyMHGHHBBBFE<?BBD<7;==:>:@B>??CEFDFDEHEDECDEFGJEEJGCGHFHGECFJJGNKLKHJLFIIKHEKKLMNORTOHSTSPROQMNQNMPWZVZYVZ]ZXa`a`^hec`dfhgjhhifhnllnmqpiuuxrrpupppruvpusuwu{~}xvtwvvvxplupmstnprrxNHHGIDBCHE<@EBE=89>>=<<AB<?>AAFCFCDIDDEEFGGGIFGKHDIHGIGFDHKIGKHMKJKLHLKMKIMKONORUVOKUVSPSQRLOQPOTYZY\ZY[^^]`b^\ackb`dfgr…hgifjmnponsrjtuxrsstrnpqvrquruus~yŽ}uuvvvvxrhuqkrtlqvptLIKIKFBEGE<@GCD@:<?@?>?BA<@>BAFCEEEIEFEGFHHFHHIKJFJHHKHFFLIHHJGLLMLLIMKMMMOLPPQUVWOKVVUSRQRLORRPV[[]^[\^^^``ad]c`ef`ehjdssfjggkorqossnswwquvtsmoruorspurvrtvuuuwvuwtgtrkqrkrvnvJKLJLGBEDE<@FDDC;??A@@@CA?B?ACHCFFGIFJFGDIHGIHJLHHJJILJFJKHIKJGKKMMJJMLNNMPKOPRTXVMNTUTRRQPMNTSRW[]^_]]`_`aa`acebdhbdijgv‹ljigmosqpqppryvruutsmmssmqrotutrpswtuuwvuuteqskpqjrvnwKMLLMGCCAD<?EEEC=AACBCCDACDAAEGCHHIHGJGCHIGHJFIMHIJMKNLGKIHKKNQKRQMSMKNNOPPOTOWXX[NSPW\ZRWPNTUTTXZ_bb_da^`b^`eaacingbihhnxvlhimosrpqrrrvtsusssnksqmprotvrqquvuswywutucmtkopjqtowLNLLLGEA@D>>DEFC@DBEDDFBCEGCCIFCIJJIIKGDKJGHJIILHJJNLOKILHJLKZfJd\KlSHON_nUks[qpbwcSPavuhucav`Xnqbdvinzf[lt`ljT_wvijgifglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqrqyLNJJJFC?@B?=DEFDCDCEEDFBFFGDEKFFJMLKLLGGMIGJKHKKIKKNLMLLLILML[sbdp^lmUMNfs]ffqlntgpi_aYnnbppbkjjfoqtetno\ougpMJqyvka`keemxlkvmnpsrprqpqrqrrrtrmmsnnopsutqsstuuutwxvttbmukpplrrqzKLIHGED?AB@>CFGCFCFEFEDCHHHDEKHGLNNLMMFJNHJKJILKJJKLMNNMMJMMN[roonpplkMPQlWMibtrpamnu\YlP\nmZqmkomxxtsip]_rkqjUuyxoc^kfbgpojjopprspqpqqrrqqrrtlmrmnnorutqtrtuutuuzvutenukpolsrryIKGGEEEBBB>@@FHCGDIFEEBFIHHEHLJGMMOLMNGLMILKIJMIKJJKOPONLLNNL\hdu]lqWlNPQmTYk^klvaldsSecNmYl\tpkilxjwuhp]^rkhWbcw|oc`ggadityknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtvHLFIDEECAB=BACFDHGLHECCHKIHFJLLFNLLSRLGLLHNJIHNHJJIHNOMNLJNMJZsppoqqmlOQRnYrkgooqqomt]nXat_nopoqronusttj[^tcwxrjnzhaacfbbimtupsuvsqppqoqt{~}wlkqnlmnprsqttsuutxxyxtukoumtontsvsHKHIBEEEAA>DDBGDHIMIFCFJLJGFKNLFOJKWRKGKJJNIHJLIKJHHKMMMMIKKKSkc[i^_icrrZ_Yjn_eeUk_c[aaQ`lh]j\niid[pfdp]Z\k[mqcpsldgcdg``kmqpntyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunvqqvtwrGGFIDECFA@BFEDGBHJLHFCGKLIEFJOLIPIL[QJEHHKMIHJJKKIHIFKKKLGHKKLMMLJKMNT[\TPTLPONOOVQONQNOQJJOPQdqiTYW\[\VY[]X]\\cfaaebcf__fkmhmtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyxxuvqruovrtsuusGCDGEEAEC@DHDFGCIKLHFDGKLIEGIPKLOKLWLIEEHIJHIKIMJHFGGIHHIEFLIJLOMJP\W^P\[`^MXYS\\b^MXZMXaRKYaZR_d\aX[ddVVX\YZX\VY\]b^daa_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtrxrxsqrurtOBCDLMBDDBEIEHGFKJKHEFIJKFEHHPKMMJMRIGEAHFJIKLJMJHFDIFDFGEFKHCJNLLU_Y`X`a[`TXYT^^Z_RY\P^\YN^\^SZ^c^Z]`c`Y_c[`^[TXWY^]cbcacehekrpoppnow††……†‚{€……††††…uqprrsvyyzyyxxxvryvxrqxvuvaSJJMIECBCGHFHGHKJJIDFKKKEFIJNKNKHLNGHE>GGLIKLKKKIGDHDCDEAFJEAKLJO[cY_^a_RTRW_`\]Y^QY\MV_WKQY[PZ_aa]^ca`bbbcceZQXUU\Y]c`__cdbhomnllllu…„ƒyu|„………††……††ƒ}wrrtxyyyy~}yuyvvrnzwvxYQKFCGEBEHIFGHHFFIGHGIKILDDKKNMLKHKJHIF?GGNKKKMKKKIFGCD@DAHIC@JKHP]aZ[d]_TQRX]\\\_ZKW\LR\YIM^QO\_accccb\dcbdcfXQUTQ[WZ`_]^aa_dlkmjjlnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMC@IFCFKJFFFHGGIGFFILJNFDKJMNJLIKJHIFBHHQMLKOMJKIGGED?ECIICCHGET]Y^X_Y_[]UXXO]]QKJV^X^[]UY`RQ__bb``bb`cbaddbXOQQQZRZ]]]]^__dhgljnnp{{|~{€‚ƒ„…„…………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡ˆ‡…ƒ€|x\SKCAHFDGMRHCQJEGHHEFKIMPEFIJKNLLIKLIIHDHKQOMMPLLJKHICDAEDIGCCHFDWUE\T]SV_XOTUNZZMIJT`a[_X^^a]OYa\``_bcb]abW`_TPOOOWQ\[[\\^_bffeleoow|{€{}€„„„„„„……ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDFFHDIRbPCV^IGGHDFMKPPEIIJKNLKKLKIJGEJNQQNOOMNLMHKADACDGECCFGBMHBKKOONLFMFGIJHGLLMOPILOPOSOLPSRUZYWYXXdWOSTPPNMNTRZXXZ]\`adecgcklpsryy{z„„„…„„„„‚„€~{ƒ}{…„†††‡‡………„„„‚€}KIEEHFGDKM]LGGXLGHJHGMLQQHLKKKNMUNOJJKGGKPSSNPONNNNHKF`ED_LEgdFN\I^[rmOMUmYLDP`UkWgJ]WU^DLQULLSVQRTXWTXUT\UPfZhhdXRjRVUT[\[``abab`fhfnkhrz|}~„„„„ƒƒƒ}|zr{z{‚€ƒ„„……„…ƒƒ~z{LIFGFHEEKOSIJF`THIOJIOMRQKMLLORUROOILMGHMQ[YOPPNOOOIJQQI|YYrtYQmHqnoaVPqqsPCksmqspSo_ZnX]V\XUkhU]VcZ`Y[_VVXjtuu^_v^Wa[[f[_`a`a]`agmpl`pwtx‚ƒ„‚}€vxzlv~tx}€|~€‚„|€ƒz~wwNJEHMNBDLLGIKERVLKNIKRXWQMOOLQTNOQOKKNGMPS[ZSQROPPPJHZx]TxehZSURvgtlpbnfjQrOMwmjrpsrqrooo€]ezuxqqzq~s}ku}bRh|essorr{|o~xn€r_``baZ`_gknkblfgmw~€‚~{xw€tvzir~ns|~wx{~€ƒx|€u|||ssNKG`]GAEMMHJJGJPOMMJNV^YULQSNXZMSSRNLOHQRTYWVPTPPPQKHgxlcxrm[KNVypumubovPeeJfvqmwo€jfxwiWrQhzmijzz~lxzohoYvvjvup€_rf}ilx|o^__ba[]bdgijdgbcdllppstsssyqrxblugqy{sruy~suzn|}yxrnNKSuNCBFPOHJKIKPOOOMPZ`ZXKTWPa^RVQYRLOISTUXWWPUPONRJKrouuquqdibWnLqp^FhyWvTLiy}x`y{sna]mocRhqunmypwlvttrln]t~zkmy|ktl|kpvux^__b^\_ddighee^abiiijknokqomjpacfcowxompsy~nqpk{ztromLL[VHGEGRPILMJKPQPPPPW\XUMUYUeXRRY^SLNITTWWYWOSNNNQIRmHiwK`dvvVXlOnl{sajgvULWkh}lmlx_Zpz{^`zscroxqhd}ir|^ULl`vukiu{zm~xk|p\^^b[^addgeeebZccikkrsrvglihdgaakagsrlglmr|kmhk{tmmkmOHKKHJHHQPLNOLKRRROSRWRVTPWZVVTTTa_PNMKTSTQVVNNLMOPKHQNPULKLSTTSTPVUQQNQQXYRNPUTXXX[[URSW[WXXZOSUWXXR^YW^VTPYRWWWWX^Zgr^[[Y\]_cZ_ccdfdccbZcbgfemnmueegcaf_]g`dlhfgkhpzhggjujhgilQIKLLMKJSQMQPOLVUTPTUXUYUQZ]VUTWUYWOOLMVTQNUSNOMLQPLJRQKQMKLPSUSQRSSIHLNOQRQPQTVRXW\WSRPRTUVSZQNSRXVTYVUZVTRUSTUWXV\Y^`]\ZZ\\_c[]bcdfdddaY`acabhhimbad^_c]Zd\bma^fefmsdigjkedcfhPJKLOOLMSPNSQQMXWUTUWWWZUS\`VWVYUXSPPJNWSPNUPNQNLSPMOUSNRNMOQUQUQRTUNKMOQTTRRQVWUYZ[YSURTWVVY[TPTUXUUZUWZVSRWVUW[XZ_\UX^\^][]``][bbcgfedbX_ab^`gdfea^_]]^ZZ_Z_g`^]]chkagfhfd`bcbOLMLQQLOTOOSQOQ[YWWX[YXXV]jdVXYZWVSSOJNVTPOUPPPNMRRPRXTQQOMPTVOXRTUUONMQSVUTTRTWVZ]\ZVVQQVXV[[WQTVVVVYTXXVSRYWVZ^Y]_^U^\^`\[___^ZbbdhgddbXa`b^^fcd`b]\\\\YZ[X[a[^]\_b__bdebd__`\PMNNRQMRROSTQOU\ZZW[[\YZ[dqmhd_[XVUWQLMVSMNROQROLQSRUZUSPPMQXWRWSSSXMOOQTXVUUSUXX[^][[VQNUVU[\WRSWVWXVTY[UTRZXW\^Z^_`Ua\aa]`b_\`]cacghdf`Yc`a__ed_`b[Z\[\YZYXW\Z\[`^_[^^a`^b\Y`[QNONVQPTQOTTSPW\\\X^\^W\^jqwy€c\[UUWPMOVSNQQORTQLRTTY[WUOROSXWTSURRZOPRRV[VWWTVZX\][[]VSMTUU[\VRUVVXYSUZ\USS]XZ]^\```Va[cb]ad^\bac_cfidf^[d`a``ce_b^YZ^[\[YXYVWZZZa\][]\\Z]`W[[ZPOOOYPUTRQWRTP[^^][`\`U\]hjr}slg\TWWQORZSRQTRTUTKRWV[YZSOSQVVWTOWRSZRTTTX]WXYSX\X^]YZ]TUNUVW^[XRUUYYYUWZ\VSW^Z]]`]bb]Y_[ea_dd^^cca^efidf^]da`aabd`b^XZ_[\[XXXWW[Y[`\[[\[XZ[^V^Y]QOORZPZTUVVTTT^^`^^b\`U]^bkytl}kZUYTPPS\TUTUTVYWLR[W][]ROUSXWWTPXRSWSVUU[]X[ZUZ^X_^Y\YQWRYYY_[ZTUVZYZWXZ]WU[^]^`a_dc\^]]eaafd^^dc`\gdhedb_da`a`bb_`^WX^Z\\ZYYWV]Z]^ZY[\[WY\]VXW]SNPVYQ]UVYWWUX__aa`c]_T]_beeuzhWYYSUSV\XWWVVW]XOU]Z^]\TRXSWWUSTXRSVTXWX]^X][V]_X__X\VQXTYZZaZ\VWX[Z[YYZ[YW^_`_cbadd\b\`fadfd^_dbb[fchecf`f__aaaa`_^VU]Y[\[Y[YY][[[XXY[YZZ]_]TY]UNSYVS\TVWYVV\`abc`c^_V[`da_zuohY[YUWTW[ZZ\YXY`WPU^\``\TTXPUWVTVWRSUWZZ[_^Z_\V__Z]^Y]URYWYY]bZ^WX[\[\[[Z\ZZ__``dbcddbdYafcffe^ab`c^bcidcg_g^aacaa`^_XT[ZZ[[X[XX\[Z[XWYXW\[[`]V]]SOVYVVZUXUXWX]_badad`^YYadb`lfh^[\ZVWXY\\]_[Y[bVTX^]ac\RVYPWWWWWVSUTX\\^``]`\Wa^[^[Z^XUXW[[_`\_XY\\]^_\[]Y[`a^`ecdeefbXcedhgd^c``ec\eidei_f]cbcaa`__[XY[YZZXYXW[[Z[WXZTY]\Z`\U^bNSWYVWYX[\XWY^`badada]^Yacb_a``^\\\WW[[]]__\Z]cYZX]`cd_RXYPWWXYYWVWV\]^`a`_b^Ya]]^Y\^YXUW[\`^]_ZZ^]^^a]\[Z\`b_becefefbZdffigb_c^afdZhhbfice^bbca``_]]ZX[YYXXZXWZ[ZYWXUU[]]]``bbxKXW[YV\[\]ZW\]_`bdaba]`Xbcbacab][\[XW[\_]`_][`d]\X[becaR\ZOYXZ[[ZWZY`]`bb`ac_\b]_][^]YYTX]]_`_`\[^^`bc]\X\^`bbcedfdefd\efgifcab[cg`\ihbhied`baca_`_\]\Y\YXWXYXW\ZZWWXOXZ]acffrkJYW\ZZ_\[^\X][^_acbaa]b[bdb`bbb\[[ZWXiq`\`_]\ac_^YYcedaS_ZRYX\]][Z[[c`bbc`bda`c^`\^^^YXU[_^]ab`^[`abfc_]T]`acddfegeffe^efhhgdd`Zeg^aghchhfc`bacb___\][Z[YXXXVZV\[ZVVVMXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡„‚‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vuuuuuuuvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{zzzzzzz{||||||{{{{{{{||||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vutuuuutuvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{zzzzzzzz|}}}}|||{||{{||||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚‚ƒ‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||xÅÔÒÒÒÒԓ{}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰ˆÌÓÒÒÒÓØZ%+++*%c’ŒŒ‰~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}xÕçääääç™{~†“y1333332j‚€€€{­éääääèʉŒŒŒŒŠ”ÝæääååëT]–‘‘Œ}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}v~ywwwwwwxyyyyy{xpoooppprrrrrrrwzyyzzz~ƒƒƒƒƒ„||||||}„…„„„ƒ„xssssssy}||}}}}|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚ƒ‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vtttttwtvwz{x{xwvwzxzzy~yxxyxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{yyyyyyy|}}}}}}|{{{||||||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwvy}|}z{~{wwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰Œ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwvz}}|}|~|wxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒ„„‚‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z{xwv{}|y{}~|xxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzyz}{|}|~{xxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyx{xz{y|xxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyxyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰…„ƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxyyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oxyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒƒ‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{{{|||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}|}}}|||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚‚‚‚‚‚€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrsuuttssssrrqpoooopqsssrrrrstttsqqqrstttttttsstsssttttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqsttssrqqqponnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqrsssssrqqpponnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnnnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrrrsssrrqqppppoooooooopopooooppqooopppppopoppqrqqqrrqrqqqqqqqqpppppqoonnnmmnnnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚€‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpqqqsqrrqqo|‚oppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqqqp‡†prqps˜‚npppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqq}¡‚pro‹ž|oppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsqu‹‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqrqt¡vqwŸœ}oqqqqpppppqqqpqpppqpppppppppppppppqqqpqqpppqppqqqqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrrq˜¨o‚£~pqqrqqqqqqqqqqqpqqqqqqrssrrssuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒƒyrssrrrsrrssssrstr“©¤yˆ |rsssrssttuuuuutuwxwwwwwxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~€~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz~|~}|vvwwvuxzxxxxxwxyyŸ´©¤¨¨—}{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~|{|{{‰¯¦¡µ«¬£~{zzxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}}}}}˜¥–¢² ™§“}€}}}€ƒ‚€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€€~€€€€€œœŽ ° Ÿ¢Ÿ€€€~~~€~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~€€€—šŽ˜²¡˜–œ…|~~~€~~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽŒ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~€~€~~Ÿ«¤–¤››– Ÿ†~~€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹Š‹‹Š‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚ƒ‚ƒƒ†Ÿ²¨¢ ˜¦¨­¨ ™‘‡€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒŽ‘‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒƒƒ† ­±¦›š ›žœœ¡¤£”‡ƒƒ‚ƒƒƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒƒƒ‚ƒ‹—š—–˜ ššš˜‰†‡‡††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ„„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠˆ‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„ƒƒƒ…„‚†Ž”“—šœœ›”‰‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž““’ŽŽ‘’‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„„ƒ„ƒƒˆ“Ž”˜’‡ƒ‚………ƒ„„……ƒ‚€€€€„ƒƒ„……„‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘“’ŽŽ‘‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚‚ƒ‚‚‚€‡›‡‹‡‚ƒ‚€€€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„„„„…„…†’“‘ŽŽŽŽ‰‰‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~€‚‚€„ƒ€€€€ƒˆŽ€‚ƒƒ€€€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“‘Ž‰†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚‚ƒ„‚‚„„‚ƒ‰–ˆ„‚„‚‚Œ•‚‚‚„ƒ€‚‚ƒƒ‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘‘Œ‡…ƒƒƒ‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒ€ƒ‚……„„ƒƒƒ‚„Ž™‹ƒ…„„„‚€‘™†‚‚‚„ƒƒ‚…‚„…„ƒƒƒ‚ƒƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”“““ŒŠ…„„ƒƒ‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~Œƒ~}|}ŒœŽ€‚‚‚…””Œ‚‚ƒ‚…“ƒƒ…ƒƒ„ƒƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†””““’Œˆƒ„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~–—‰€}}}}{˜Œ€ƒ€Ž”Œ‚‚‚‚‘”ƒƒ‚ƒƒƒ‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“’Š†ƒ„ƒ„‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€•ŸŠ~~€}‡‹~„„ƒ„‚ƒƒ‚‰…Œ‚‚ƒ‚ƒ†–•Œ‚‚ƒ„„ƒƒƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒ„„„„ƒƒ‚‚ƒ”“’’‹Œˆ†„…ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„‘¡ŠŒ„}†‰€~………„…‚}}}€ƒ„ƒ„„‹™ ª¨›Š„Ž‰ƒ„„„„ƒ„„„ƒ„ƒƒ…†………„……………„…††††…………………………††…†††…†††‡†…………ƒ„„„‡“““‘’Šˆ…†……‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…ƒ‰‘ƒ„‹…‚~}‡†ƒ€~~ƒ„„…Š“˜ ¥¤›–‡…„………„…„†…………†††…†……†……†††‡††…„……………„…†††‡†††††‡‡ˆˆˆ†……†………†”“’‘‹Š‡†‡†„‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„„„‚‚‰~}~…‚~€€„„†•—•—ŸŸž’‡ˆ††…†……†‡‡‡ˆ†‡‡†††‡†‡††‡‡†††…ƒƒ„……†„……††‡‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘”“‘‘‹ˆˆ…†…ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒ„„„ƒ€€€„„~~€€€€…Œœ›š—šœ›™Ž‡ˆ‡ˆˆˆ††‡ˆˆ‰‰‰ˆ‡†‡‡‡‰ˆ†‡‡‡‡†‡…ƒƒ„…††………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†……„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡†…ƒƒ…„„„ƒ€€Œ‰€‚‚€€~{z™—Š”™™˜•”Œ‰‰‰Š‹Šˆˆˆ‰‰‹‹ŠŠˆ‡‡ˆˆˆ‡‡ˆˆ‡‡†‡†„ƒƒ…‡‡‡†……„„ƒ……„……†„„„………†…†…ƒ‰”’‘ŽŠ†…†…ƒ‚‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡†„„…„ƒƒ‚€€€„„‚‚‚‚‚‚‚€~}}}}~~|{|š•–˜—•“‰‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰††††‡…†ˆˆˆˆ††‡„ƒƒ„‡ˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚ƒ‚„ƒ„ƒŽ“’‹‰……†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„……‚€ƒ„‚ƒ‚‚‚ƒ~}}~~~~~~}~}}—Œ˜–˜—“‰‡‡‡‡ˆ‡‡‰†‡†ˆ‡‡‰‰ƒƒ„ƒ…„„……†ˆˆ†…ƒ‚‚ƒ…‡†‡††„‚‚ƒ„‚ƒƒ„‚‚ƒƒ„ƒ„‘’ŽŽ‹‡„††„‚ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…‡ˆ‹Š†„†„‚††‚‚„„ƒƒƒƒ‚ƒ}|}€~~~}|}~|z‚šŸœ˜Š‹ƒ„„†……ƒƒ…„„„„„„…„‚‚‚„„‚ƒƒ…†…„‚‚‚‚ƒƒ…„„„…„„†„ƒ„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰†„…„…‚ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€€„„ƒƒƒ‚‚€}}€€}~~}|}}{zy‡ žšŒ‡ˆ€‚‚‚~‚ƒ‚‚‚‚ƒ„€€€‚‚€€€€‚ƒ‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†‹“‘‹ˆ……ƒƒ„€‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€ƒ‚~~~~}‚„ƒ‚ƒƒƒ~}~€€€~}}}}~}|z{z›—–’‰~€€€~}€€€€€€~}}€~€€€€€€€‚€€‚€ƒ€‚„ƒ†’ŽŠ‡‡†ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€ƒ„‚‚ƒ‚ƒ„…€€|}}~}}~€}~}~€ƒƒ‚‚‚}}~€€€~}}}|{{{zzz{Ž—•—†~~~~~€~€€€~~~~}|~€~~€€€€~€~€…’’Ž‹‹‡‰…„„‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~~}~€€~€„ƒ‚€~}~~€€€~}}}}{{|zzzzy‘‘~€€~€€‚€|~~~~}|€~~€~~€€~~€~~~~~}}}}…“’ŽŒ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒ‚‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚‚‚€ƒƒƒ€€}}}~~~~}}}}}|||{zzzzy‚‰–‡€€€€€€‚‚€~€~~~~€€€€€€~€~~€}~}}{|†“‘Œ‹Š‡‡Šˆ††…„‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…‚ƒƒƒ…„„„„„ƒƒƒ„‚‚‚‚€~}}}~~€}}}}}}}}}|zzyyy{ˆ‰‡‡ˆƒ‚ƒ€‚€‚ƒƒƒƒ€€€ƒ„‚€€€€€‚€€€€€€~~||‰”Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…„„…„…†††††…†…ƒƒƒ‚‚€}}}}}}~~}}}}}}}}}|{yyyyy|‚‚„…ƒ‚„ƒ‚‚ƒ…‡‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚‚ƒ„ƒ‚ƒ‚‚‚€€€€€~Ž“Œ‡ˆ‡ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€~}}}~~~€ƒ„‡‡„†††…††‡‡†‡‡ˆ‡‡‡†}€€€‚~}}}}}}}}}}}}||~~~|{yxxyyz~‚‚‹„ƒ„„„——ƒƒ„}~‚‚‚‚ƒ†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ…„„…ƒƒ„ƒ‚ƒƒ‚‚‚‚ƒƒ‚‚‘‹ˆ‰‡‰‡††„†…„„„ƒ‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€€~}~~€‚………‡†‡‡‡‡‡ˆ†‡‡‡‡†‡…~}}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yyz|€}†“ƒƒƒ„„”“€€~~„‹€€„†‰…„‚‚……‹ƒ‚……††„„……ƒ„„ƒƒ„ƒ„…„ˆ’Œ‰ˆˆ‰‡‡‡…†…„„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„ƒ…„~}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|yzzz{}€‚‚ƒ‚€~}{ˆ‘||Ž–}‚†Š…ƒƒ„ƒ‚ƒ‰}ƒ„……ƒ„†…„……ƒ„……†„„Ž‘ŒŠŠŒ‰ˆ‰‡………ƒ„ƒ‚‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚€‚€~}}||}}|||}||}|}}}|||{‹‘—Œz{|zyz{|yy}~€}{|~}‚•‘„ˆ}|~‚„||‚„ƒ‡ƒ}‚€‚‚€ƒƒ„„„„„‚„ƒ„…„‘‘Ž‹ŒŒŽŠ‰‰………ƒƒƒ‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚ƒ…ƒƒ„………ƒƒƒ„‚‚ƒ‚ƒ‚‚€€~~}~}||||||||||||||}|||~Š‚{z{zxz{{|}{~~~~~~}|€€~†~}‚~~€‚||€‚€€~|{Š‚}€~€€‚‚€€€€‹”ŒŒŽŽˆˆ‡………„ƒ‚‚‚‚ƒƒ‚‚ƒƒ‚€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ……††„„€†”ˆ€‚€~~~€|||||||||||||}|||||}|yz{{xxy{{z|‚€€}€}€‚‚€€€‚‘€€~€~~~€}}}{}}}|}||}€€€~€~~‚”’ŒŽŠ…††…„„…ƒ‚ƒ‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚‚„†‡††~ˆ•Š~€€€€~€~~~|{||||||||||}}|{}|||{|||zzy{|{}…ƒƒ€~€€~…‚~€~~€…†‚€~~ƒ†}|~€€~}}}}~{|}€}~Œ‘ŽŽ‡„††…„„„ƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}€‚„††……~€€€~~~€€€}}||}~}|}}}}}}|}|}|{}||z{z|}}†…ƒ€€€}~}~~‹„‡~}||~~‚‚}}}}|{}|~„ƒ€~~~~}|~€}~€~~„’Œ‹Š†„…„„„ƒƒƒ‚ƒ‚ƒ‚ƒ‚€€}|||}~{{}w~vx~}|}}}~~‚ƒ€z~~|~~€€~€~~€€€€~~~~~~}~~}|~}~}}}{|||{{z}~€€ƒƒ‚~|||}|}ƒ~Œ~|{{}~}~~}{{{}|{{{{€†„‚„ƒ€~‚‚‚‚‚€‹Œ‹Šˆ„„„ƒ„ƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~€€€}€~~~~|‚}~}}}{{}}|z||}‚€€€}}}|||||}|~{~{{{|||}|{{{{||zz}z~‚~‚„„‚‚…†……††‡…„‘‹Š‹‡‡…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}{€~~€~~€‚€~~€€~}ƒ||}}|}}}}{|~~~~~||}||}|~~{|{||||}|}|~|}|{{{|y{|{{}z}~~€€ƒ‡‰‰‰Š‰Š‰…ˆ‘‰Š‡……ƒ‚‚ƒƒ„ƒ‚‚‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€€~~~}€€€ƒ‚€€€€€€€€~|z|}}~}}~~Œ†}}~{{ƒƒ}}}|}|}}}}}~|}|}|}}~}~}}}}|{{{|{||{z{{zzz{~~ƒ…ˆ‡ˆŠ‹‹Š‰Œ‘ŽŠ‰†…„‚‚‚‚ƒƒƒƒ‚‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„„€€€€‚~}~€~{~’Œ|}Š€Œ~~}}}~}}}}}||}}}}|}}}~}}~~|{{{||}|{z{{yzyxy{~ƒƒ„‡‰Šˆ‰ŽŽŒ‰‰…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{}||~~}}€€€‚…ƒ„‚‚‚€€ƒ‚€}~€~|‰‚~‚‘„„ƒ~}|‡}}~}}|~|}}|}}~~}~|}|{|}~||{|}zzyyyyz{~~€ƒ‡„ˆŽ‹‹‡…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{}}}}}zx‚€‚‚€€€€‚‚‚‚†…„‚‚ƒ€€‚„~€}~~}~€€}~„€~~}~}}Š…}~}~~€~}}||~~~}€}}}|}||{|}{{{zzz{{|}~~€ƒ€‰Ž‹Œˆ………„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv}€ƒ‚‚‚‚‚ƒƒƒ‚…†„ƒ€€€ƒ€„~~€}~€~}~~€€~€€}€~€~|}}|~~~~€}‚€|}€€}{}}}||||}{{{|{||}}|ŠŠ‰‰††……„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚ƒƒ„ƒ…†ƒ‚€‚€€€ƒ€~~€}€}}~~€€‚€€€€€}€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{}~|}|||{|{|~Š‡‡…†ˆ…„…„‚‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz~}yxtt€€‚‚‚‚‚ƒ…ƒ„ƒ‚ƒ„„„ƒ…„€€~€‚~~~~€}~€}}}~€€€€€€~~€€€€€~}}}~|~~}}„€~}}}~}~~}~|{|z|{z€ˆƒ„„…„„„„ƒ‚‚€€‚‚ƒ‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xyuu}‚ƒƒƒƒƒ…„…ƒƒƒ„ƒƒ„…ƒ€€€€~}}~~~~~€}}|}}~€€€‚€€€ƒ‚€€~€€€€~~}~~}~~……€ƒ~€~~€~}{z{z|{z‚…€ƒ‚‚‚‚‚ƒ€€‚€€‚‚ƒ‚ƒ„ƒ„‚„‚‚‚‚€~€~}~~~~}~}}z{|…„{{sy{|pwuvwyutz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€€€}}}~}~~}~|}}~€€€€€€ƒ‚€~€€€€€€‚‚‚€ƒ‚ƒ‚€€|{{z|{|‚€‚€‚‚‚€~‚‚ƒƒƒ‚„‚„‚‚€~€€}~~}}}~}~{{z€x|vyz|qtxwvxury……‚„„‚„………„„‚„ƒƒ€€€€|}}~€}~~}|~~~€~€€ƒƒƒ€‚€€€€€€€€€‚ƒ€„€}ƒ„€€‚}z{{||}€~€}}}€€~}}~‚‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxzzruyyvwwsu†…ƒ……‚„„…„„ƒƒ‚ƒ€~~€~€}}}~€~€~~}|€|~€~€‚ƒ€€‚ƒ„‚€€€€€ƒ‚€ƒ€~‚ƒ„€€‚‚‚„‚~{{|||}~}~}z~}}x~|||~~~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vwvst†„„……‚„„…ƒƒƒƒƒ€}~}}}€~~}}}€€~|~~~‚‚ƒ‡…~~€€€€€€€‚‚€€~€‚‚ƒƒ‚ƒƒ…ƒ}}}|{||yz{z~y{yx~{||~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst†„„†ƒ‚ƒ„„ƒ‚‚‚ƒ‚€}€€~€}~}~€€€|€€€~}~~€}€€ƒƒƒ~}~~€€‚€~€~€‚‚€ƒ‚„…†„€~~||||zyvyyzyvyv~|{{{~}|}€~}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…„ƒƒƒƒƒ‚‚ƒƒ‚~~€}}}}~€€€|€€€€|€~~~€}~~‚‚~~}~~~~€}€€€~~}~~€‚‚ƒ‚ƒ„‡„€€~|}||{|uxyxxxyw{|{{{…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvpxyrx…………ƒ„„ƒ‚„‚‚€‚€~~~~€~}~|~€€€€€€|€~€€€€}€~~~~}}~€€~~~~}}~~~|~€~~~‚~~€€~ƒ‚ƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}|{|z{}zzx{|zz{xtxuqrtpxxqy„………ƒ„ƒ‚ƒƒ‚‚‚€€€€€}~~€}|~|€€€€€€|€~€~~~}}|€€€€~~~~}|~~|}€~}~€‚~€€~‚„‚‚ƒ……‚‚~}|{{{|yw{ywxwwx{{z{|…‰}{zwz|}}||}}}~|}~~}}}|}~~}}||{zz|{{zyzz{zxswuqqsoxwq{…†……ƒ…‚ƒƒ‚‚€‚€€€€~~}|~~€‚€€}~€~€€}}|}€€€€~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{||{zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚€€}}~€€‚‚}~~~€€‚€€~|~|€€€€€~}~~€€‚€€€€€€€„‚‚€~|}~~z}„~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚‚€€€€€€~}€€‚‚‚€~€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€€‚€€~}~{’z|}|{}y{zzxzxy{||}|||||||}}}||}|~}~~~}|z||{}}{yzzzyytuuooqpwst}…†ƒƒ‚ƒ‚€€‚ƒ‚€‚‚€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€€‚€€€}~~|†‰||~{{~yz{z{wwy||{}|{|||}|}}}}|}|~~~~|z|}{}}{yz{zyxstunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚€‚‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€€‚‚€€€€€€}~€}€ƒ‚{~~{|}{z||{‡zxxy|||}{||}|}||}}~}}}~~€}{|||||{zy{{yysrunvrpxqvv……ƒ„ƒ‚‚€€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ‚„„€~‚€€€€€‚~€€‚€€€€€€€€~}€€€€€€€€€€€€€€€€€~}~}~~{}|}||}xxuxxy{||}{{|||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒ„ƒƒ‚‚‚ƒ€€‚„ƒƒ„ƒ‚‚‚€€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€€€€€€€€€€€€€€€€€€€€€€€€‚ƒ‚‚€‚‚€€€€‡~~|{}|{}xwvyyz{||||{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzrvy……‚ƒ‚ƒƒ‚‚„„€€ƒ€†ƒƒ„‚„€„ƒ‚‚€€‚‚„‚„‚€€ƒ‚€€€ƒ€ƒ‚~‚€€~€€€€€€€‚‚‚ƒ‚‚ƒƒƒ‚€€„}}}|}z}{yvzxy{{|}}{|}}}}~€€€€€€ƒƒ€|~~~}yy{zzzysrtowqwysw{…ƒ‚ƒ‚ƒ„‚ƒ„ƒ€ƒƒ†ƒƒƒ‚‚„„ƒƒ€€‚ƒ‚‚‚~€€€‚‚‚‚€€€€‚‚„€~ƒ‚~€ƒ‚€€‚ƒ‚€‚ƒ‚ƒƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ‚€‚€}€|z||{w|yyy{z}~}|}||}~~€€€ƒ„€}€~{{{z{ztqxqytvxtv{„‚ƒ‚ƒƒ„‚„ƒƒ‚‚„…„‚ƒ‚ƒ„„ƒƒ€ƒ‚‚‚‚‚‚€€€‚‚‚‚‚€‚‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚ƒƒƒ„€‚ƒ‚ƒ‚‚‚‚ƒƒ„ƒ„ƒ„…„…ƒ„‚ƒ‚ƒ€€~||€}|x|yzyz|}|{||}}}||€€€€€‚€€€€€{{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„‚ƒ………ƒƒ‚ƒ„‚„…‚‚‚ƒƒ‚‚€€~€‚ƒ‚‚‚‚€‚‚ƒ‚‚‚€‚‚€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒ„ƒƒ„€‚ƒ‚ƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€€{}~|y|zzz}||}z||}}|z{~~~€€€€€€€€}}||}{vrvxxvtvu}‡‡ƒ‚„…ƒƒ„…„‚„†„„ƒ‚ƒ„„ƒ…ƒ‚‚‚ƒƒƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚€‚‚ƒƒ‚‚€€ƒ‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚ƒ‚„„‚„ƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz|}€}||z|~}|}}~~€€€€~~€€€€~|}~~~}||xvvw„‡ƒ‚ƒ†ƒƒ„†„‚…†…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„ƒ‚‚ƒƒ‚ƒ‚‚ƒ‚‚ƒ„ƒƒ‚„‚„ƒƒƒƒ„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒƒ„„„„„…„ƒƒ„…„…„ƒ‚€}‚€}||{||€}}~€~~}~|||}}~~~€~}~€~~}~}~~~~~€|}€‚‚ƒƒ…ƒ„ƒ†„‚ˆ†…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~‚ƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒƒ‚‚ƒƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒƒ‚ƒƒ‚„ƒƒƒ„„ƒ„„…„„„…………„ƒƒƒ~ƒ€}}||||~}}{|}}}}}~~€€€}|~‚~~~~}}€€€„„ƒƒƒ…ƒ„ƒ…~‚Š‹……„ƒ‚„…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ„ƒƒ„…„……‡‡†‡…„„…„ƒ~~|~~}€~||~|z|}}}}}~~~€}}|€€~~~~~‚€……„ƒ„„‚„ƒ†€‚„…Š‰„„„„……‚‡††„„„„…„…„„ƒ„„‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ‚}„~~ruƒ‚v~ƒ…€}uz„„„‚ƒ‚‚ƒ„ƒ„„…ƒ„…†„…†}„z}~ƒ{…ƒ„ƒ}~~~‚ƒ}{}~€~}|||}}}}|}}~€‚}}|€€€€‚ƒƒ‚‚†„„„†„ƒ„…ƒ„…„Šˆ………ƒ……„†††ƒ„…………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†spurstƒv{}u‚ƒ€‚vy…€ƒ€„…„‚……‚hzrss|€r‚„~ƒƒ}}~~‚ƒ‚|}€}}||||}}||~}~}}}€‚€‚‚‚‚‚„‡„…„…„‚‚„††ƒ…„†ˆ††…‚†††‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„„†}p{pyv~ƒ‚nypus|vyy†s„ƒpvxqvtturstvi€nrotvnulwmzsn€‡ym}rsvsvmnwlpylu}~|~€}€}€€}}|||}|}~}€€€~|~€€€€€€€€‚ƒ‚‚ƒ…‡††€‚…ƒƒ…‡†ƒ………†‡‡„ƒ†‡ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpu‚rƒ~ozyymonzoolw}x†pqzprtfu~n{ysoy€}~€{~}€~€€~~€€€~~~~€€~}€}€€€~~€~‚ƒ‚‚„…‡‡„~‡„„ƒ…‡†„………††ˆ„„†‡ˆˆ†‡„††‹‰…„†‡‡…„…„…„‚…………†……†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„rioyxpkyszozwvvp€~~z~}}}~}€ƒƒ€‚ƒ„‚€‚€}~~}~€~~‚€€‚„‡†ƒƒ†„…„…‡†…………‡†ˆ……†…‡‡…†„††‰ˆ…„‰Šˆ…„†…†…ƒ……„†††††…ƒx‹yrˆz{pp…„x…xyks~y{krƒ‡ƒz|mzyyt}€vno€€ot|uwpy}}m~uoƒ…†z€rr{|upozks|nv‚~~}}{}{|}}}}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡……………‡‡ˆ†„†…†††…„……………†‰Š‡……†…††…††„†††††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„††…†„†„ƒ„„†„ƒ„ƒ„ƒ…ƒ…„…„†ƒ…†……„„…‡†„„…†……}w…„„„ƒ‚~~{|{~||}~}}~€}€~~~€~~~~}}}~|{|~||‰†…„†††…††…………††‡ˆ†„†…‡………ƒ„…†…„††††……†„…††††„‡†‡‡†…‡ˆˆˆˆ†…‡…††ˆ†…ˆ‡ˆ…‡††ˆ……††…††…ƒ‚……†……ƒ„„„„†„††„……ƒ††………„†††„„…†ƒ…„‚„ƒƒ…ƒƒ}€{{|~{||}~~||~}€~}€~~€}}|€}~~~~~|}}~{|||{{~ˆ‡„„ˆ††…‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡…††……†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ……ˆ…†‡†‡†‡†‡…‡‡†‡……†‡…††…ƒƒ…††„„ƒ„„ƒ„†„††………ƒ††…†…„†‡…„„……ƒ„ˆ†„ƒƒ„ƒ„‚~€|{}~{|{~~}||~}~~}~}}~~}}||~~|}|||}|||~z{{|~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†„…„‡†„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆŠˆ…†ˆ…†‡…‡†‡†‡…ˆˆ‡‡…††‡…††…‚„„…†……„„„ƒ„…„†††…†„†…††……†‡…„ƒ„„ƒ„‡ƒ„‚„…ƒ€€€{{~~|||~}|||}~|}|~}|}}||||}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††„…†…†…†…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡„††…‡‡‡…‡†ˆˆ‡‡…‡‡‡††‡„‚„ƒ„†…‡…„„„„„…††††……‡……‡…†…†…„ƒ„ƒƒ„‡ƒ€‚ƒ„‚‚‚€{}~~|||~}||}|}{|||||}}{{{}|{~}{|}}|}}~}|zz{{||ˆ‡‚†‡††‡††…„…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡ˆˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ†…‡‡††‡‡…‡†ˆˆ‡†…‡‡ˆ††‡ƒƒ„„ƒ††‡……„„„…†††††…†‡††ˆ††„†…ƒƒƒƒ‚ƒ†ƒ~‚‚ƒ€ƒ‚|~~||}}|}}|~{{{z{|||{{{~{{}{z{~||||}~}{z|z||‰‡ƒ†…†…††……„……………„ƒ„†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…‰Š‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……ˆƒ„†…ƒ††‡†…„ƒ……†††††…††‡†‡‡…ƒ……ƒ‚‚ƒ…‚ƒ~‚„‚~~~||}}{}}|~zz{y{|}{{{{~||||z{}||||~}|{{{{||‰‡„†„†„††…„………„„ƒ„‚€ƒ†‚‚z„Œ{€„…‡†††…„‡ˆ‡†‡……‡‰‡„‡…††ˆ†…‡„†‡‰††ˆ‡‡‡†‡ˆ†„†††‡……‡ƒ„…„†††‡……„ƒ……††‡†‡…†††…††„ƒ„…‚‚€„ƒƒ‚}~ƒ~€||}}~}{~}|}zzzy{}}zz{{}|}||zz}||}|~~€{{{|~}|ˆ‡…†…‡„†„…………„ƒƒƒ€‚…‚€€}|{„…††„…„„‡‡†††…„†‰†‚†„†††……‡††ˆˆ†…ˆ‡‰‡††‡…„†……‡…„‡ƒ„…„ˆ††‡……„‚……†…††‡……††……†‚ƒƒ…€€€„€ƒ€|€~~‚€}€}€|}~}~{~}||yzzyz}}yz{{|{|{{z{}}|}|~~|{{}~}|ˆ†…†††………„……„„‚‚€‚€€€ƒ~~~€yz}€ƒ„…‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ†…ˆ‡‰‡†………ƒ†„…‡ƒƒ†„„…„‡†…†…†„‚……†††††„…††„……‚‚ƒ„~€€€€ƒ€|}~‚~~€~€}}~}{}{zyzzyz|}yz{{{z|{{{{|}}}|~}||}~|{‡……††††„…„…ƒ…‚€€€€~‚‚}}{‚ƒƒ…†…„ƒƒ†ƒƒ„‚€…‡…‚ƒƒ„„…††‡‡‡……ˆ†‰‡…„„„‚…ƒ„†‚ƒ†„„†„‡††………ƒƒ…„…†…†„„„„…ƒ…„€€‚ƒ~€ƒ|€}}‚}€~~~~~}}{|{zyzzyz{|yzzz{{|z{{{|}~}}€}}||}€}|†ƒ††…††ƒ„ƒ†‚…€€€~|~~€‚‚‚„„ƒ‚‚„€ƒ‚€„…„‚€‚ƒ‚„……‡††„…‡…‡…†‚ƒ‚‚ƒ‚‚…ƒ…„…†„†††††…ƒ„„ƒ„………ƒ„ƒƒ„‚„„€‚‚}~~~~„~{||€}€}~ƒ}~~}}~{~{{zyzzyzz{yzzz{{|z||||~~}|}||}€~€†„……„‡„„ƒ‚†‚ƒ€€~~€}‚|}~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚‚†…‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡†……„ƒƒƒ„……„ƒƒ‚„ƒƒ€€~}}~~|~ƒ~|~||~‚~‚|~}}|||{{zzzzy{y{zyzzz{|y{}{{~€}}}}€€€†„„…„…‚„‚‚„‚‚€€~}~~~~€}}€~~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„…ƒ‚ƒ……‚„ƒ€€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚€…ƒ~€~||~}|~ƒ}{~|}€€ƒ}}€~}||}}{{zyzyy{yzzyzz{{{z{}||‚€~€€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌÌÌËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFK=8765999<>9?<C9;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;>BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937676=;>:=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<:<<98:9:::;<::;9><>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA=366:;<8C<BA><A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖËËËÌËËËËËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÓÓÔÔÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9>CE?<;999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNG¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖËËÌÌËËËËËËËËËËËËÊÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø×Ø×××ÚÛÚÚÚÚÚÚÚÛÜÛÛÛÙ××××××××××××Ö×ÚÛÚÚÚÚÚÚÚÚÚÛÜÜ×ÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILN@99:4;@<7=9AC=@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMMF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÏÐÏÏÏÏÏÏÏÏÏÏÏÏÖÞÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¹´‹‹‹‹‹‹‹‹‹ŠŠŠˆŸ»¹¹¹¹¹¹¸¸¸¸¸¹°‹‹‹ŠŠŠŠŠŠŠŠŠ‹‡½æáââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑrliNSbLLVM<::77>C?8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKPFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÌÐÒÒÒÒÒÒÒÒÒÒÒÒÑÞìëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§£££££££££££¤œXRSSSSSSSSSSSOw¨¤¤£££££££££¥•SSSSSSSSSSSSSKªòëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘wliJN_MRUM><<7;?C>6:7>?;=B@9<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÌÌÐÒÒÒÒÒÒÒÒÒÒÒÒÑÝêééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤¦ž\VWWWWWWWWWWWSz©¥¥¥¤¤¤¤¤¤¤¤¦—WWWWWWWWWWWWWO«ñêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;?@@8:;8<<<;>::;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÍÏÑÑÒÒÒÒÒÒÑÒÑÑÑÜèççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©ª¢fabbbbbbbbbbb^‚­©©©©©©©©©©©«žcabbbbbbbbbbb[¯ïééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB>;=:9::=<;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÍÎÎÎÎÎÎÎÎÎÎÍÍÍÎÏÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÎÎÏÎÎÎÎÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÑÍÌÌÌÌÌÌÌÌÌËËËËÍÒÒÒÒÒÒÒÒÒÒÒÒÒÑÍÌÍÍÍÍÍÍÍÍÍÍÍÍÔØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<7@A<=8:;898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÎÒÓÏÏÎÐÓÐÎÒÔÕÔÐÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÖÖ××ÖØØØØØÙÙÙÙÙÙÙÙÙØ×ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oVJ_cRQZKHAA<B==;:>><>?==?89:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÎÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÎÒ«œÏÏÒ¹¾Ôœ‚„ŠÆÏÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==<=:<=B>BB@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÎÒ¶œ¥£ÔÀ”°œ±–¸¹¯¡ÒÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?><7:>9?D>@98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÏ͜‘Å¤ ‹‘Ó}~¯°ÑÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>><<96?B?B:648:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÑ¿˜ ›³§‡ºÔÒ͞žÃÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8E@?B:74:::9;;8;=?=>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÓ´™–ª¹—œŸ ÒÓÀ  ÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<=<964:98::97;?@<<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÔ«š~£’Š¬¯‘¡¹×¯¢©ÔÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>9<97659:6:<;7<?@<::=:<?>=<9@<<::9?@==<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÔ¬›§‹˜Š¡š­›©Ø£¡ºÔÑÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CGDAA8;?<=;<<7558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÓ¶²²¥››š¦Å˜¢ÑžŸÉÒÑÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ђl]\oghb]OF?HHFE@<<>><==<756:96:;::;8@?:<<9<>=;;:?9?:;9=>=><;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦ÕÄ¢™–œ¯žœ››­ÇŸ¡ÒÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;557<:7:;::;9==:::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸« ÇÕ¢«¤šÏ¦«¤žÅ´¤¦ÖÒÒÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKK@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÓÓȒ´Ö̓§×¹ƒ¿ÕÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUij[L_MJLJULFB<<?FEGKI=667:979:;:<=9>99:8;=>>A>=9<<:=>>;=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÔÈÁÕÑÔʽÕÒÑÂÓÒÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?ADLLA>775:8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÑÓÔÒÒÒÓÕÓÓÓÕÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEJ==786977899;;=?@<<89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9599:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EIKAALD??;9889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEHIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDI;AA;<886586987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGJB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<AA<;876797799=?A?<:9@?<>B?:8776=?@@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD88867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE><HF89757875898;>>=;89A>=@?A>7596;>AB??@@AB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCDECALH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HQA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELBA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<<DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGHNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAD?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8:87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€iixsg~‰‰xp‚†{w}~…Š¼ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9768579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€‚wt|„‚}sp€Šx‚yƒÈÞÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsnupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9886553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿½¾¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;;>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»º¹¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjcmgb\XQPQKTJB:IQ?A7<94:565455688686;:9<==;:86688:867>=<=>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸¸·······¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPF>8;727967453588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µ¶¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³µµ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶······¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸···¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬«««¯°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899::;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©©¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶···¸·¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™ššš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¥¥¥¥¦¨¨¨¨¨¥§¨¨§¨¨§¨¨©ª§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸·¶······¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::9:9<=::A<6=8378837;@??@@:BEC@BDCA?;;@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥¤¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¥§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§¦¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?A?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©«««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤¤£¢¢£¢¡ ŸŸžžœœœœœžŸ ¢¡¢£££¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™—˜—––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@?BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž¤¤¡ŸžŸ  œœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747578;=8::99;=;;89>6789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥£¢¡¡¡¡¢£¥§¦¦§¬«§¦ œ›¡¡ž››šœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””““““’”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¦¦¦§§¦Ÿ›š›¢ š–—•š›š——˜™šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¦¤£¡  ŸŸ¡¡Ÿ  š˜˜™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364689:89788:<;<9;;::67899>?@><=@>@:9@A?=A?>AA>AA?:9=>:P Ÿœ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~ššwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥£¢¥¦¦¥¦§¦¦ ›™›¡ —’“’—šœš–——˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB?DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¤¦¦¥¥¦§¦¦¢œŸ¡Ÿ—‘‘”—›˜–—–˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡  Ÿ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;<;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¦¦¥¤¦§¦¥¥¥¦¥¥£  ¡¡ ™’–›™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡  ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:737959888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢£¢£¤¤¦¦¥¤¤£¢¡¡žœ›•’”˜œš›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œŸ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸžŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::78:64795<968979<;;<::<;:<<8687>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸŸ  ¡¢££¤¤¤¤¢¡¡ž›š™—¡µž™™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢Ÿ›ž¡¢£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š™—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ ¡¢¤£¢£¤¢­§W^]TW_nkšš›œ››œŸžœœœœŸ   ¡¡¡    ¢¤¡¢¢¢¡ žœ›››™Ÿ«›œš›™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86:746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥¤¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¢¢¢¡ ¥³¬  ŸŸžœ™™šš›®jvž›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›š››š›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>99;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤¤¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ ŸžŸ ¡ Ÿ¦’›«Ÿ  ž›š™š™¨„D€ŸŸžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›šš››š˜™™˜———•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9<<>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœœœž žbœ¦žžœšš›œ¡£QH„ žœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:<>9?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš›››››š¦f]£ ›š™›œ®uIL†¡œœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\Q<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™™˜¤€Rx¢™™š› ¤_VN‡¡œœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡ ¡ŸŸŸŸ™š›œš™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd\\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š›››œœ›˜˜™ ˆ[_”š™›œœ£dZM¢žžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[[LF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ›››››››™˜™Ÿ—]]v—šœ¢dYM¢žŸžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž››šœœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ›››››œš˜™™š`a`€–œž˜tcUO¢ŸŸŸžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_^]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;879:;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜˜——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜™™Ÿi^[eœœžŒj_QS†ž›žœœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±´­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=:F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B@AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œš››œ›˜™š˜˜™›šš—“shaTv“—œ‡\WPWŠ’Ž’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨ª¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥£¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‘‹‘‹Œ‘‘Ž’šž’} £–¤œnMPc††‚‹†‰Š‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜ž—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VQQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹Œ†Š‹‹‰‡„†ƒ€„ Ž~j”¥•}ˆ€_r€‚’†„„…ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974869388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹Ž‹‰‰…‚‚~€¢‹{mQuœŒŒZq}|~}|†Ž‹†”‘‹—”—’˜¡–ž–•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¦›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ‚†‹‡ˆ…„ˆˆŠ…€‚}˜šwWNKr“†ƒM_oqwˆ…ŠŽ‹™œ””” ššŸ¢­±®©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPEMISWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}€~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‘‹ˆŒ‹‹‡‘£T//=x‡wvAD]km„‰‰””˜•œšž¨®²°°µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWMO_^\NUUbQDTM;?9<895875795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš™ž¡“—›¡š›¢¦œgB[H;xykgE18Zls‹˜šŒ”š—œ› ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUJTOOJDPK_bXZQ\T`MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ªª©§¢¥¨©«©©¯Jr¢yA|xdbQT^I`nŠ¡¡¤ž›š¤§¤©«®¬¥¤¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdWOYKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®««¬¤¡¢¦©§¨£x`ÁÖ¥C|ŽƒuOnŽvSd£¨§ ¢¡®¬«ª§­®¨¥¤©©ª©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_VZNRNQOSe\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢™œ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨§¦¨©§©©¤§§™¤¥£¢b½À®y¡¤š•eL_xmQt•¢¢ ¡Ÿ¡¡¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOXO^edlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤ ¢¡¢§¡¦®¦¦žj„œºŽ©Ñ¢š³¨XL­“Se ž  ž £™–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvxb_\UYQUW[c_s_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?B?:8:>?C@DA:;>=@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯««¬¨¨«¯©¨ª¨¢ ¡¨ª­±²¯«¢¢…w~}rÎƯ™¦¯kUª°c[‡¥Ÿ¥¢¡ž ¢˜•ž›ŸŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸŸ¡¦¢›—’šš •|wo}yf[[`_Z\U\hdocmiib^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¡ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£ £ªª§¯··´µ¶³­®¬Ž†ƒn‘̼””¥–tTozsp}–¦ª§¤ Ÿ£›¡š–ž¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¡™˜¥ ¤§ª©¨ª­¬¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxjb[__\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>BE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢ «²·»»»¹¹Á¸´µŸ‡ydXŸµ»¦§™ˆwkqoxy{~…Ž’˜£¥¦«¥¤˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨¨«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥¡¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxxxc[RYT__amhvkqhiibZSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶´º±ª®´±°²´µ·ÁÆÌÏÎÌɾ³¤rfRD‹•………}xqngflilrrqrru}©ÄÄ»¢§ª¬§«©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš’–””˜“š˜Š‹‡€€|‚xa^YSaiaftotitdidb[LK>:9898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÄÇÃÅÇÛããÚ˼®£•ˆtYZQDiwjntnkeeYW]X\cjjifai‹¶ÁÀ¹©¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`b_^kcbnxuwom[bRV\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAA;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–••‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±°§¼¼¾ÅÄÆÉÇÅƾÍÒÕʹ¦œ“…r^QTKD[e^cjea`hYTXSWYZ]Y[uš·¼¬´²­³­©®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|„jfhaklgnvrrvrg^`\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÄ¿ÂÁÇËȶ“tcUPOTH>^l__eb`]daSUWVUUXsœ­±ª¨ª­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|uklndomiqxoyjia]gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÄÄù¸Ã›aIDGKD=[eabic`[c_WROPPW´º¬®¥¤£¨¤  ¥™©´±¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿ”“‰‰~†ˆŒ–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyz{wnkihvZgsxszgg^d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÊÆÄÄÄÂÄÁ­ƒOFME;MZ]ele_[`YYSNU€£«¹µ²¬©£¡­©¬§­Ÿ¬´´¿Ã¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyvvefjjh^kpnyxcba`^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÎÏÌÃÇÆÈÉÈÈÉÇÅÉÇÈÇÂƖjXG??F]baj`ZXWTVwš·¿»¼º¼¬­¦©»º¹·¿³µ¸²Áƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«¬±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqocahvhjjunyl^d[V`YLHD6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÌÐÍÇÌÉÂÂÇÂËËÈÇÌÉÎÅÆƽ©rPK0XSVeaSNPq©ÈÈÂÄÇÀ¼¾´°°°Â¾¾ÁÆÀ¾·¶Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­¯µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—Ž‹”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r}xpg`kjwmifvotc]cUWUSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<9>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÄÇÈÆÒÉÁÃÿ¿¾ÄËÈÊËɼ¼ÈÇÉÍÈÃÈÉÉÅÅÂÃÂÁ¼‘?Ow€ŠVLo¥ËÔŶ¿¿À¿º»½µ³³À¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzy€spfegdlebknoo_Y]WVNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾƹ»Ãº¸¹¼¾ÁÇÁÆ»¹ÈÈÃÅÄÀÃÁÁÀÄÁ½¼Å§wk‚—o«ÈÈÇÑÁ¯½½¸¹»»¾·´°¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfaebacddjcgd[ZZ]YQOE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶·´´µ¿»½¿¹¾ºº´À¸µ·²®º»·À·¼ÊÏÀº¿À¼»Å½ºÀÄ¿½¾¯sd}‘ŠŠÑÅ¿¿É¿°Á¿º·»¾¹µ¸´¸¼´½¸µ´°³¼±··¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|yˆ}qdacchkggjfj^VVTYOSLF8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“““˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´´±°µ·µ»Á¸¾¹¿¼¼·´·¯®·µ¹¿»ÁՍ¸¿»ÃµºÇ¶µ¸º¼¸¹¶ª¤˜~„É¿¿»Á¾¹Æ½Â¿¼Å¸¶·´¸¶¶»»¸¶´·ºµ³¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒyqmeegpjelhYYOKKKRJLHD9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’™”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿¾¼²­¯¬±°·¼·»½ÁĹ··¶µ¹¹º»¿¼ÏÄw¨Ì½Ç·¹·­¶´·¹³µ±½ÉĔI{ʾ¿¾½¼¿ÈÃÅžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~‡}knqgqktfcn`\UHKKDJCCG?:;8><7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘Ž˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼»À·ª­¤®°¸»²½¾»Ä¶µ¸µ·¿¾Ä¼ÂÄÖ®t€»ÈÏÂÀ¸®´´»½·¹±½ÃʍCuÍÿ¾½¼ÇÌÇÇÄǽµµ¶Á½»»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†rfljouoydhc\cQKUHEECGC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?>??FD@A?>:7?@CC?@=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼ªª£°¹½¼²¼¾¼Å¸±¸¹¼ÆÉÊÂÆÉҙqr«ÑÑÌÊĵº¿ÄȾ¾´¿ÀÁxRnËƾÁ¼¿ÃÌÊÇÅÆÀ¹½¼Ä¿¿¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtpmmtlmo`c_bbNIM?E@?DC;;::;:8;<:9<>::>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´»ÅÐú¾¼Ä¾·¼À¿ÉÏÇÈÊʆrs£ÌÌËÍÊÆÂÃËÎÁ¼¸½º±ocb»ÈÄÀÀ¿ÄÀÊÉÃÃÄùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{zˆ{mmx|`qd\_`_TI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA??ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸´¼·»»«Ûþ¶¾À¾¾º¦œ©²¶Ã¿¥yux™ÄÇËÈÁÃÀÀÉÊÁ¿»¹± |rl­ÈÅÄ¿ÀÁ¿ËÇÃÀÈÀºÂ»¹³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}znsxthp^\_]ZRFEDMIAD=H;;59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘—žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯··²µ³·¹¼»¶»»Ä¸m­Î½¶¹À¼¬}nhnmr•˜sw|—½¿ÆÀ¹À¼¾ÅĽ½¸±°˜}€›ÊÂü½¿¿Ãÿ¿Ç¼¼À´³®´´¼¾¿ÎÍË·²¸··½¹»±¶²ÈÀ»¶´±°·¬³©°­­´·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|wmu{qoj\`aZTQAFIGK@ECI<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿ››œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹Àͳv³½¶µÂ¥‡iZ^`MR[Znsw€Ÿ¸¸Âº³»·»½¿º»»®¤›˜‡~ÀÄþ¼¿»»¸¶Áµ¿º´­®¬¯½À¹ÏÊÉñ°µ´´½º¾ºº»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶¼´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰{‚zsvvxnra_g][UJ=??GG=GCC9:5;99><<9:<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Âɨ„xŠ ¯µjegVY`IIMPSlw†¥°·¾¹²µ²»¹¼¶¹¾´–œ¥•¡q®ÉÄÀ½¿¹³®²¼º®»´³¥ª¦¬º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtwrm`db\^OIB?=IDFMD@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·¿Åªˆ|uŒ ™`TCXUGajVOEJ` ¬¯¶ºµ´²¬¼¹¸µ¸Á½‹˜°¡¥r¥Ë¿¹ºµ®¥¬³±¦²°¨ ž¤­¶´Á¶µ³¥§ª¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´¶¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wp|pvsod^hY]^SONB?JCAKJ@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜š‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³²­¶º¯­¼³¸¸¿µ‘‚xˆoNJ?dYBNw€”jNA]°µ³µ²´¯¬»º¸¶¹¿Åuƒªž™c©¿¸µ²±­­Ÿ¤§¦¢®¦œ•˜—™ž¨­¸«ªªž¤¨¤«®¯§°«¯±±­±®®¯¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvtmvjl]\kU^\PNHDGMBGNG8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹º¶¹»µµ³·¶•Œˆ„{XFAN‡YJJXwcAS£¹³´²°±­°¹¸¶»·º¼¡²«£r¬°©«­«£¨ ¥š…Ÿ””–Ž–§­£¢£Ÿ¡¦¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬ª¯£¤£¡© ›“Ž”’’™–š¤¥ Ÿž§˜•’”™ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wryiutoeUbdX]ROMI@IRDNC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯²¼©™™•iN@RxqPIIKgœYER®»±¬³¯®¬­¶¶²´µ®¨¦Ÿš›ž¦¨ž ¨©Ÿ¡§–Ÿ‘Už‘ŒŽ”‹•™¢§ŸŸ¡¢¡¥¥œ££ ž¥ ¤¬¥¦¨¥¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›ª¨««Ÿ¦¢›£œ•Œ“—•–˜Ÿžžš™¦—“’–¢ ¥¢¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ª©¤©«¦©¬«¦¡ˆxƒ|vzcxmn]QiUPOGPMMCPRA?;>4::5;:=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢ª¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¤¬¨½Â«¥¾iER‚QWIJ`JTŽ`cb€®µª²´®ª«¯°²³­¥‘—“— Ÿ¡ œ£¤Ÿž¨”£UV‡•‹Œ”–š §žŸŸ £¥¨œŸ ¡œ¡Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£žžžš—š«¦ª±£¥¨ž œ–“’‘™–•˜—Ÿ˜œ™›¤™—”•š §¨¥ £¢¡£Ÿ ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’~|€uv}nl{diVSdNJHGOSNKNH<E@=2@859;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜——–¡¨¬®¶¶º¹º··»®¨ ¡© ªÆ¿Ë¡PAržwOnKKcfus`Z^p±¯®³µª¦¬¬£›™”‘•—˜˜œŸ¢¢œ¤žš¤š“:d„Œ‹Ž—”™ž¢©¡ œ¦§«¢Ÿ §ŸŸ£¦¨ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¢¥¢›™ž¯¨®²«¦«ª ›˜˜˜•“–š“•–š–›—˜˜¡žœœ–›¡›žš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰|€~wy|eyyabSVaIIKLSUJSQM9?A67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—“’œž¤¨®­¬««¯ª¯©ž—ž¥œ¤ÇǎWSIe£[e~or]Qkc[d_]k´°°¸¬¦¡œš”—š™Ž‘•‘ŒŽ“™¢œ—¢£€=d€{y”˜££§ž¦«Ÿ§®®ª¦¢±£š£¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§¡ £±®²±´ª²®£™œž¡˜››š˜™›•–›–™œ¥¡ š£¡š™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ ž ž ¥¡žž¥ ¦™{|vvsi‚me\S[ZMRKOOVMTMB7>C78=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’‘œ˜¡ª¢§ ž§¡¥Ÿœ’›¢šž«¤zUirvupcvvXWc`cgYXWf­®¬¯§Ÿž¢ –“› œ™—’“Ÿœ¡£šž›–ž ƒjcfpzxu~Œ›¦©«¥µ²Ÿ­´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½¶¾°¬±®­©ª´±°¨«¨³µ¸³¸­²´¤ ¥ ¬¡¡¢¡ š™––Ÿ››˜¥¡ ž£¡ Ÿ›œ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚|xvjwu^m[RaIRVHFVWKCMH=KI8F<77;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©¨®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“Ÿ™¨®Ÿ§žœ¡žš™’˜ž›¢¡ ¤€n‚p`cXL[SZMLPXRHMMH˜¬ª©¥ Ÿš’‘”˜˜–––Œˆ‹Ž”œœž–ž¶«g†}uy{´®³Á˜©·¸½¿º­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ·»¶«®±¹·¼¯³°µÁ¼·¾³³µ¢¬¢©©²©«¨§¨š™žšª§ ™§ ŸŸ¨¨¥¥Ÿª¢¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰……~vrmiwmhn\X\CWNJGMHCFN=>L>4<:6:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©©”’—™”šššœ˜˜™œš˜™ª ±¢·¤°¦Ÿž—˜•™ž›œ£ŸŠbW^e`WMQG>>?CC?>BQx©­©ª¦ žŸ¢£Ÿž››”“•”žž˜”…™ ¼Õ¹•…ˆŒ…zqpl€©»Äœ¹Ã¾¿Â¿¶º»Àù½»¬®§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¸Â¾¸´»ÆĽü¸´ª³­ª³´¯³®ª¯£ž¬¨·²­£°¦¡£°±®°¤¥¯£¡ š¡¦¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¤ž¦š›¢¤žŸ›››œ‡†|trklurqhW\QFUHDJPI?EB4FH96<>7;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž  œœ˜šŸ šŸŸ•}`^e`QGD<C>E<?96N~ª³§¤£¢ ž¥¬¦Ÿ˜•’šž™•ŒŠ†ˆ†xm‡Ÿ³ÛÔ¼«œ‰†‹‚rh]]Î¶s­ÇÅÅÃÈÂÀÅÈÍÐÈËò·µ¾²¾Å»¾ÌÍÆÌÌÌÒǾ¿ÀþÇǸÄÊÉÄÁÇ¿º´º»µ»·°¶²«»²¯¼·À»º«¸­«ª¸»µ¼®®¸£¦£ž¦¥¢£©¦™›Ÿ™š§ª§ ¡¡¤˜”£•”™‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ…~zrkdioxkeZ\FLMEDTMEBE7:?;549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<@?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ²²¸§¡¡«ª¡œž¡¡›š~sjaWNE>IY|obB=\Ž®¬ ™›œžž™——˜“——”Œ‚ƒ‚vrpmp‘»ÃÇÄÀ·–ƒ‚„„r`W…¹€€ÐÌÌÌÇÊÅÅÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÑÓÍÓÐÓÓÌÊÁÆÇÆÊÈÏÀÉÑÍÇÆÈƽÄÁ¿¿¿µ¾³­¿ÀÃÃÇÅÈį¿¹²¸½ÄÂÁ»¼¼µ®§§®¨ ¢©¥š– š™¨«©£¤¤ž—›‹™‰•˜› Ÿ£—žš““‹•…yusebgrog^ZZDOMCFQIDCA55589B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>9;AA;;>786:;>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›¢¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¤¨¬­ª £ž›–kf]TID@?K†ž¥š„ ²­£žœŸš˜—”“”—‘ˆ„„‰‡ƒ€€yqrol{ˆgŽ­¶µ¡Ž}zzkheq„_ºÔÑÑÍÍÎÐÄÍÔÕØÑ×ÍÆÇÉÌÃÅÊÏÊÒ×Ò×ÒÕÖÓÔÈÌÇÌÍÊÓÍÎÓÍÆÉÊÊÂÇÌÇÉÉƿó³ÈÅËËËÏÇÊ¿¾¿½ÁÇÅÌÌÉÉÀÃÀ®°³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›–Œ†‘‹€{ruvgcgvjeVXRDNG@IQC>B=:22A<E<78<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<@?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­³·¬®£ž£¢¡œcSLJDC?CR®Ñ½²¯¦œœœ ¤¡š””•”Š}yqlebhrpr{…Š€upmqqpyQY|˜¤£–~ojcfjf]“ØÑÒÓÔÒÏÑÃÐÓÖØÕÕÒËÉÎÐËÆÍÒÊÒÕ×ÙÖØÓÖØÍÒÊÏÑÌÏÑÍÓÐÀÉÈËÄÌÍÌÏÏÆÇȶÀËÀÒÍÌÐÇÊÉÀÄÃÈÏÍÐÑÏÍÊÈ͸·»¨Ÿ¥«§ž˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„}xsvpcaerc]R\JKGAFIJ?;A8>5586;86:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÁűµ¨¡¥¥ ¢¢[I@ADAFQv²¯¦š”—Ÿœš  ž›š•‰wida____^__]alusppnlqou€cZw’›™…ia_cicyÌÔÍÏÕÔÔÑÑÌÐÍÓ×ÖÓÕÐÏÒÓÑÉÓÑÈÐ××ØÒØÒ×ÙÕÖÌÏÏÉÍÒÌÎÑÀÇÄÉÇÏÎÑÑÒÈÌÍÀËÍÆÔÏÌÏÉÅËÇÇÉÌËÔÔÑÕÏÒÌÓ¹ű¥¨µ®¨›¨«¥²¨°³¬¬““ŽˆŠŽƒ‹„Ž™“™‚…Œ|zqstmacim_VQ`JJCECSN?<>43:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><?@=FAD=‚¤œ ¥ž¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯­ªª«¥®·¨«·×ÔÕÙÙÑÎп¼Ìɶ¾®§ª¨¡£¬gC8=>DX‚ª¨Ÿ—•—™šœŸ˜›“}qecb__a_^a`^a`_`emppmknqrv|`]€”˜ŠgYY^mu—ÇÔÎËÒÍÕÔÑÊÏÌÓÖÒÑÖÍÏÕÕÑÅÑÓÊÐÔÕÖÎÓÑØØØ×ËÈÎÄÊÏÍÊÌÀÉÁÉÊÎÏÐÌÐÎÎÌÏÐÈÌÐÑËÎËÃÊÈÊÍËÌÒÓÎÔÒÑÐÐʽȹ°®»¹µ«¶°­¨¸­³¿»±šŽ ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…‰zvopokadnpaX\[IFFDMYE;@=33<<87855;>@=9<<8<>9<@;@:=8?98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§  £§š›Ÿœ—žž¡ššœš¦›Ÿ¤§Ÿ¸¶µµ¬¤¬®¾´°ÀØÒ×ÚÜÖÎÍÊÃÒÏÁÁ±©¬­©¤²|HFB;V¡›•“–›žžžœ“–—”ˆk^^^adb``aa```^__^\bmqnnqqrqww[g‡ŠbUYj‚‘³ÍÎÄÍÊÒÒÎÆÎÌÍÔËÎÒÍË×ÖÐÌÑÔËÌÐÑÓÊÎÑÕÒÕÖÊÀÊÂÆÍÃÈÊÃÍÄÆÉËËÏËÎÍÑÎÔÌÇÉÐÍÉÇËÆÇÂÆÊÌÎÑÑÇÐÏÎÎÌÐÅÇÁ¸¹½Ã½ù²²¾°»Ãĵª˜¥¡˜–‘••’‹”š‘””•‚‰†yqrkmh``qhYXhVMGLIQQB;D?;68:8::57==A;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÄÂÁ¿»µ²±Ç¸ÊÕÖÙÚÛØÌÌÏÈÖÕĵ¯´¨ ­—xlopwšŒ—•“‘‘•–•‹|ebbb`]^acb`__`aa`_][]gqqpqqmimxhUxƒ|[Ti’›Ÿ®ÅÆ¿ÁÄÎÎÇÅÇÍÊÑÇÊÍÍÆÑÒÏÍÌÔÊÇÊÎÏÇÇÏÒËÐÏźĿÆʽÃÇÉÎÅÃÈÀÇÎÈÄÍËÍÐÉÅÅÐÉÆÂÆÉÅ¿ÁÈÍÌÌÏÃÊÌÉÇÌÐÅÅÈ»ÇÃÉÉÂÏÁ½¼¿°ÁÉǹ½ª±²§¥¢œ˜›£™—™‘•˜‰‚xoudk`^fqa[W`GIHGIMUG?J=64355==48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ¼¹ÌÌÆÐÕÕØÚÛØÐÉÏÏÑÓÈ·»»­¤¶~g‚…¢ª“–…ƒƒƒ}„„~s_[^]^`^`cdc_]\^_``_[Z\akrpmmhgikq_eojX\w‚‘——¢·ºº¸»ÈÅÁÃÀÃÈÉÈÈÉÇÁÅËÅÇÊÍÉÄÁÊÉÁÁËÏÄËÈ¿¹Á¼ÆȾÀÆÏËÄÀûÊÇÈ»ÉÆÅÊÁ¾ÂËÆÅľƾ½ÁÄÆÌÆż¿ÊÃÅÇÒÅÁÉÀÊÊÆÈÆÐÃÃÆîÄËÇÃÊ·¿¼º³©¬¤¥˜Ÿ˜¬£¡¦›£ ›•|wsufj[anmZ\XRDLGCGDLDFS?54335@=3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¾¸¼ÊÏÑÌÇÂÃÆÍÎÎÌÕÏÕÙØÙÏËÒÍÍÎÈÁµÃ¾²°¶m^z|ž‘Š’–†z€„…uxurp_Z[]``bcdded`[\^]^]_[YZ\bnqnifgkinv\ZZ\`s~††‚’®¯±¯®À¹º»¹¸ÀÁÁý½¹¼¿¹ÄÉÅƽÆÀ·»ÃÈ¿ÁÉ»¶»»Åÿ¼ÂÎÃƾ¾µÁ¾Ä»½Ç¼Ãºµ½ÆÄÂ÷À¶¶¿¿¼ÍĽ¶ºÈ»¿¾ÌÄÂÆÃÆÉÇÉÆÐÆÂÌȲÇÉÃÎÌÀÅÿ¼²·°²§¨¨¹°¥­°ª­¬”zwxkeh`hodV^YJFJFHKAEBFJA9:658853;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µ«·´²¡žŸ—š”–šŸ¦¢ž·ÅÂÄÈÎÒÊÊÊÇÍÍÎÑÈÐÆÕÔÕ×ÍÊÏÅÉÅÇÁºÅ½¬®§`cv’‹ˆ‹„x††}ƒ{ttc\\]^``bcbbdeb]\[\^\^]Z[\]grpkdcijjupHO\Yhsoid“¥¦ª¨£µ±µ³²²³»µ¼°¶¯³¯²»Â»Áļ¿º´²º¾À¸È¸´¼¶À½¸½ÇÁûµ¯³µ»¿´Å¸»µ¬¹½¾À½±»¶°·º³Æ½·¯¼¿µ·µÅ½¾ÃÆÀÄÆÆÇÌÅ¿ÆÆ»ÇË¿ÏÉÇÃÆÁ÷ý½¶¹¾Ç¿¬µ»µ·¶Žytxggebkn^V^`FKHHJGBDAEF?=:566633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÅËÍÈÅÈÍÌÐËÍÈÉÈÊÉÊÄÐÍÒÏÍÅÇÁÅÁ¿º¸É·«°š[goˆŽ†ˆ‰zx~…†vw|sh]]]]_`_`da^cec_^\[^\]^Z[[\_kolfcfhgjy_CPL\\VRs¡šž¦¢š§©¯«©«¨³­µ¯±§­¦¬³»º¶Ã¹º¹°ª´¹»³Â¹¯À±½¼»µ»Ç¹Ã·­ª¨°²À¶¸½°±¨²³µ»¼«®¶§®¶®¼²°ª¸°®»®»¸»ÀÁ¾ºÃ¿ÆÃÅÀ¼ÆÁÇʸÅÇÅ¿ÇÃùÄÆ»ÆÉÌ˳¹Â½»³‰tvwki`bliYWW[ALLMJEAC?FA:::996854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÅÎÒËÃÅÁÄÏÇÍÁÂÆ¿ÄÄÃÃÊÂÉÊ¿À¼Âº³µµÃ®ª±“[i~’ˆŽ{x}‰…y{„€wn^]\\]_`__dcbdcb`_]Z[ZZ]ZZZZ]cmmfdddeglxQ=ELX_Z—¥–Ÿ›•—¡§«¢¦¡ª©«ª¯¢¥žª­µ¶±½¸¯·¯¨­¸´³¼·³¼°¸¹µ²¼Á²À®¥©£«±³³¨½ª«¨«¬®µ´¦©®¡¥°©³¦§¨®¦¨·¬±³·º»»²¼¾¾¾Ä¿µÁÀÇÈ·¾¿Å·ÅÃÀ»¿Ä¾ÄÈÌÊ¿¿ÄÀÀ©‡stsji\aodWVXPHZSSKFFE>?@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÐÏÌÃǹ¹ËÂ˾»É¶½Ã¾ºÊ·Áõ¶¼¶±¯µ¼­©«“dmˆƒ‡‹€z}~xt~|swe_]\\^_`^_ccab`a_]]\ZXY[[XWY\_ejdbcaddhnsFDdp]”™‡œ®–’Œœž¦¡¡Ÿ¤¥¦¥¬Ÿœ›¤¥¬²°¶¶§°«§ª´«³¹°µµ®¶¹³°ºº±¶¤ ¤ ¦±¨¬©¹ª¥§§¨§³­ §§Ÿœ¥¦¬ŸŸ§¤¡¡±­­¬²µ³´°µ¼¶»ÁÀ²»¾ÃÁ±¹¹Â³À½Àµ¸¼½¾¼ÂÇÄÃÄ¿ÀÄ „yqlbf`ko`UY_HNhOTHFKF<=@=:;<826536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;>97776788666;::;9:;<859<:>>@;Èµ¶½¸ºÁº½¶ ž• ¦º¶«³³»³ÄÏÉËŸ·ÇÀÌ¿¸Ê·»Å¸³Å¸³¿À¬¶¼²¬¦¯´­¡£’ir†…†€|xusomjiipi_`]\\\^__acb````^\[\\XYXXXVXZ]^cb`cccbeelkY{y_T\D^b“¤‘‡˜ž¤›ž¢¤¢¦š¢›žª®¬±´£¨©©«¬¤´¸¬¶¯­³µ¯³µ¯°ªŸžŸ¤¢²¥¦ª¸­¢¦¦Ÿ¨­«™Ÿ Ÿ™Ÿ¥š™£œœž°©¬¨ª«¬­°³¹¯¸¹º°¶¼»º«³²¹³½´·²±¶µ¿µ½À½Ã»»½—„{sl_e^ddXTW^IW]KPGJJGA<??A;?<05636:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»¸ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÅÏÈÈÀÆ»»ÃÃϾ¹È¸¸¿·²Â´±»»¬ºº±¢Ÿ©«§˜žm~…†xrmomkb^bff]]^]]]\]_`abccba_\[[ZZYXWWWWWXWZ]abccbbcdeofYXH2!"\X_Ž”‰–ž¥œ™›£¥¡¤›ž š˜­­­®± ¤¢­«§¡µ°±±¬©¯³¨º³§¶¡¢Ÿœ£¡­£¢ª¶ª¢£¦ž¦¦£–™—™š š—œœ­¡¬¨£¤¦­«³³ªµ°²«²¹´¯ª¯²²³·³®©­®²¸°º¶º½¿·³±”†zvf_f_[YVSZUK[QLJEHKIC=?BB@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½¸½¿¶¾¼¿²¥£˜¥±Ãµ¶½­´¸ÂÌÈÆÀŶÁÀÇηÀý³¹¹²¿¶±¹»­²µ¯Ÿš£ª¡”šxƒ„xoqtqhediec\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXWUW`bcaab``dfqQ:3!+h”x‘Œ‘›™š”ŸŸ¨¢ž§œš™ª¦®°ª›¢£·©¡ ®¨µª¦§®±¤¸°¤· £œ™™ª¦¡š­¹°£¡¤œ¢  “•¡”––œ™˜–—œ•Ÿ©žª¤¢ž£ªª±­¨´¬ª§­³°¥«®³±¯°¯¯§¨¨²®²´°¼´º¸®£”‚zwe_aWYXSRTKM^LPLGHMLE=@>=B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´ºÂ±¾·½­§§¢ª»À½À¹®´¸ÁÌÇÅÂýŸÈ̲ÁÂÁ®¼»µ»¼µ¹¹°°±ªœš¡©•‘Š‹€€|wqilrtphhedfa\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWVUZbb``a__`bii=3-2N“Œ“Ž–›˜œ“¥¤¢¥¦žœž¥Ÿª®¥Ÿ¡£¶§¡¡¢©³¢¥¨¥°¦±®«µŸ¡–•©¡¢”­±±Ÿ££žž˜œ“Œ ”‘“˜˜’—˜˜—ž§›§¢¢š¤¥¥«¤¥°§¥£«¬­¦©®¯¯«¨ªª³¦¦«¯´±®¼¶±¯¯Ÿ’{xseb\[]XNLQHRaMVPOJNOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8847763321./2556;:8;7876<;:;;A8x»»±¶½°»±·¬ž¥¦¬¸»¼Áź²¹µÄÉÉÀÂÆÅǶÆijÁ¿Å«··½¶½º»µ²¬­¨™™Ÿ£‹Št‰ˆ~vncafihfgifil`]\[ZZZZ\]\[\^_\ZY[YYZ[WUXWTTVVRTRT__]^_\]]`akX4?Mt„Š‰Œ’ŒŽ‘ž•”™£ «¤££¢£¡›©ª£™¤±©¡ ¥ªž¨¢Ÿ­¬ª©®­¢¢¢•˜¢šœ¬©°œŸ¢ŸŸ—™“Š‘’”–˜˜“œ¡£œ¥¡¢• ¢¤¥›£«¥¢¤ª¤«­¥®²©¦¥¦¦µ¦ª¨­³µ´¹º¯ª¬žŒsqpa[WVVRGQOHZ\ORJTKSLEGJC8;;=<9667:9;:976977:;:=<<6;<8>598:88659:;<97?<9678452121..1426:8698598989;9@9{µ´¬´»²°«±­¨§¯¹¹³ÀȺµÀ¯ÅÈ̺ÁÉÌȵɼ±¾ÃÉ­±¸Áµ¼À¼´µª¬¦–šœœ‰rˆƒ{tiijlgjlmkjle]\\[[\ZXZ][[^``\XXZYXWXWTUVUTUURSNPY][[\\\]\_ch@Rq‡{…†…ŠŒŒ—–ž˜˜ž¥¦©¦ª¦¨¥¢˜¤­£”˜¤®© œ™› Ÿ®™œª³Ÿ¥¦Ÿ££¡””›––’©©­›œŸ¡ ›”Œ˜Œ‘’–•¡ £œ£•›¡£¡˜¢¨£¢¨« «°¤®¸¥£¤£¬­ª¨«¯´·²½µ³«®˜…uti[YYSURFXLQ[XMUOPLQRIOIB=??A?=75799<<977:79:;<=>;7;;:=68:;8976989:6:=99577571141-+/434988::8::748=8?9~³­§³·®¨¨¯®›©¨¬·¶¬¼Ê»¶¿¬ÌÆŸÀÎÏdzĻ·»Âȱ­¸¿·¼¾»³¶¦© –˜™—ˆzt€vwnmhmmmpggifd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUSSNOQXYYY\[Z[]^eqyvs€…‰„‹’”›—œ¨§¤¬ª§¯£¦˜ž«Ÿ””£¨¦—‘šž®–˜§ª˜Ÿ”¥ ž’‘’‘“•¨ª¥š˜™žž–ŽŒ‹“†‰ƒ‹’•‘ ž¡¤™–Ÿ•š¡¢ž”›¥¥§©¨ °°¦±½§Ÿ£¬´ª®§¯´°¹µÀ±®°«‘~rtcVTUNRJGVPRRLLXNKLOSGNKACFEC>A75889;9:7::7<=:;@>:9;9:?759:9876958779;85576661320-*.102877;99;8948;8@8´¬¦±·ª¥¢±«ª§©²°¤¶Æ´¹º³ÊŹºÁËÐʱ·¸¼½Àñ°±·®´´»³´££˜—•„€vkglnqnqjokdege^ZYZYZZZZZZZ\\]\ZXXXYYWXWUUTRSUSVTQMNMRWXYXXWZ[[`jtlri{‚|†„Ž“—•š¥˜¨¥¤ª¦—ž¤š‘Žž¢š——†…’›¤•¢œ•–•‡¢š›“ŒŽŠš¥§›••—œ‘“ˆ”Ž‹Œ€‹’’’¡š ¢–”™˜•¢¦š™¤§©§¡ ´²¨³¸¡£¶¬ª®¤²²¦µ»´«¬±¢Šzsn^NQQMODNNNPKFNNJJNNQHMJAHLIHC>958889:;69:68;99><8:>9;?8789:886857688974577820301+)-/12876:999984988A7w¶§¤¶°¤§¤ª¥ ©¦¤³ª¢²Äµµ²³ÆÅ·ºÃÊÌƳ­º½´¸À¯®©°ž¦®»¯­ š›ž••ˆ|„n__frpuqinieghj_XXXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQNMKKSWWVWWWVZ]aidhcv|v~w‰~ˆ…šŒ—š¢ ¢˜¤• š”Œ†˜š‹sƒ~Ž—–†’š“Ž{™œŒ‚‰€Š˜ £ž“˜–…Ž‚”~~tŠŽzˆ“›šš’–Ž££Ž‰š ¡¤¤›¢´¯¬°­Ÿ˜¦¸¦¥°¡±®œ°»ª©¯©™„xtdVMRPPMCSNLPMBPQHINSNIJJEKMGKK=749888;;69;7:<9::;79?9>@79:<89764445874312485/0102)(,-02764789::66:87A7x·¡£´¨¦¥¨£¥¥¦¦¦²§¦´Á¸¯´°Éĸ¹ÀÎƾ³¬ºÁ¬­Ä­¨¢¦’¦·­£ ‘–—’~xfWV_gfighnciigb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTQMMJGNSSSTTSUYZ]h_c`qxqkISm‹}‘‚ˆ˜“ˆ‘Žž—œ•••“•‰“‰_;Vo|Œ”Š€Œ’Œ††r‹„–y{†”•ƒ–Žƒ†}“xqp†}‰Ž—š™“‹ŠˆŸ˜‡ˆ–žš¡ —§®©­©©ž–­³¢¥­™­¬˜§³£©­£“tn`[NSRWLDTJPMLFNOIELQMKPJINPGJJ=7599999:7:;:>>8:==7:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9y· ¢­¡¦¦ª ¦©§£ª°¨§´Â¹°µ°Ç¸³½Ï¿¹¯®µÂ§ªÄª¢˜ƒ”œ±£š™‡”‹‡~sv]PLQUYZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MNQMKHFHNQQLORTUXY`e^[muiJ=;|’‹y„‰‚‡Š™Œ•”‰‘†„”…xˆ`JQnx‹’„~„Œ‹„m~“wuvx„špQˆŠ†|~y”vgw†ˆ~Šˆ•‹Ž‘“—Œ„Šˆ”…›‚…’›–ž”¤¢¨©¥¤ž›°ª¡¤¤‘¦ª–¡©œ¡¦§Šwnf^\HQQSMIUMSILKOIHFJNLMUKQRPGJD=769:8:;;8:;8>?99>=8;<6;;478;6775344696/3/.115221/,')+*,4833989:99::::?9w¶›¢§Ÿ¡®¡§¨¥§¨¯¬ªµ¼¶¸·³Á»¶§¹È¸¶¨¨µ¶ª²¼§ž•Ž‰”©–•‹Ž„ƒ~xqoXMKMMNLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDCINOhYNQSSUZktdhq`_UOŒƒ„pz‚}y‚Š‘€‘™‹z…ŽtxrnuptŽŽz~Š«…z{hv{Žprmx‹’x{€{€wsr’xhu…„„…|•ŠˆŠ‹€„‹€”„|˜”œ–‘Ÿ©ž ¡ ©¥Ÿ˜§¤’ Ÿ–žŸ¤sib]]JWPRHKXROJMLRJJJLPHLQMRUMFIB<78;99>=:;<98@?::><7==79937785675251472/2.,./200/-+(().12721987:8775:<;7v®™£¡˜Ÿ´©¯ª¥­«°±ª½´²»¸¶º´±Ÿ·º²ª¬©¨²¯¢š‘”ŽœŽ‘w†x|vpojYKHIHGEHHPTTTWWSUUUUVWXWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LNQQSV^qzpk\n†‘•ŒŒwcu}su|†Ž{‚˜’p†Ž{vznk~­|t‹z†’€|tfu|†lohs|Š‡€mzq}qmvqhq~ŽpD‹…‚ƒ…wwzŒ†}Œ{u}Ž’˜‹’››£–™›ž¡œ–‹¥›Ž—Ž–˜xongc[XXUQJSUTOPNPVKNKOOKROIOPLFD=;79;::?=9<:99??;8;=7<9999266856633611224.,,-..-0-+*''*.1362/876966527995y¦— ž– ¦°¬®«¨©±¯±«¼¸«»¾¸³¬§›°§¬›–œ¥©¥¡˜šŽ„’y‰‹‹vq|muqjmjXKFGEA@CDHLLMQQOQSTTTUVVWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zYJNOQTX]dmibŸ£¾|pt_wtkxu†ŽxzŠ„nk‹‘xsxij‚q–‘Œ}•I’™ngw~‚mjdly…’†ksl|nr|†imps‰…†{~{wptt†‚yyp|Ž‹Š“ƒ––˜š“––™—–Œƒ‰Ÿ’‹’†—€pjoooYVXTRRYORUTRXUMNHMKMOKCINGF@:99;99:><9<;::=>:8:<9?868727565541432/024*+**-.+-*(*(',-1250,5567485HA895w™‘›˜›Ÿ¤¬¯¢­ª¨µ¯®¬´¿«¼Ã¿¦¢š•¤˜ž„‹”¡¡˜™‘“‹sŽz€†Œ†uotlqmekkYNDFC@<>>AFFGKKKLORRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_IMOORVZQXZZ ]•cmtazlj|wˆ†t€…„sk˜sr{ijŽLy…“‰„f1v‡rk}}ƒtfeu„„…€filukp€|hqq|n“{t~}qqoumƒwyujyˆ‚ˆ‰ƒ–’’‹‘””Ž—€yˆ—ˆ‡Š†€ˆxlkpheXR[XYY[NPUVYXNIHEJJHGB@GECG=998;9:9<:9;:::@<9:<98>787715234533645031.**+),,++)(+'),,226,,4775478iO8;5m’ˆš™–¤¨­ž±ž§º¯«²°Â±»Ãǚ–Ž•™‹Ž…z„˜•Œ‡q‡‚t‡Œ†zpsqopdpg_TFIC><;9:?@ADCEGIKOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOOQUKAIQH`ª®œlurhyin~‚x‚„„xqŸ“sw€rt“‡5p¨ ¡„¢…vp†{†|tŒ®‰hgbjnrmpƒuioXupŽ›‘vm{}nrnp€{svnbuƒ†€…ŠŠ‰‘‹‘‹‹ŽƒuxŠŽ€~ƒ€}Ž|srqm`\]^\ZYa_RN[ZXWLHJFIH?CABH?CD=;:7=;:;;9:99;:?<88=:8;66650121253474531./,,+)*))***)(*)+/3DM2166643<vR7=7b‘’ˆ•‘¤§ž¯•¥´©®°®Á²»ÁŖŒ”€ˆ|n’‰ƒŠ‡†u‚„l•ˆˆ|uxxmxnwdj^IPG=?7449;:;=>@BEHLLLLNPQRTUVWXZXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL7CMQRCH€ozwvqzis„…y{‚}Š|t ˜y}…€„™„šœa†ªžœ‹ƒŽzwˆ~‰ˆŽt‹—„{]dqtz|wŠmhjbyo…‚zoxu…zptzxkni]v†}‡|‡†ŽŠ’—ƒ…Œ†}q„„}vw{|‰xqtugh`[\^S\g^WQTX[UGJJDKG?F@DC>AA=;97<;;=<::99;;=>79>9985654244004645554-,)+('''&(())((+++/00Uq=23331E~W4=9\ŒxŠ“Œ‘œž¦‘ ª ±¨¯À²»Äº–Ž‘“‡z†vk‹‘ƒ}ŠƒŽŒxƒ€s „Š}}p~zhwkRXL@E211376688:<>AEFFGJKMOQRSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFIKMOQKJT[WQId}ƒv„uwny‹ˆwz†„}”…vŸ˜‡†‘”¥Œ¬©H†­¯®Š€”‹‚‹‚„’©ˆ˜˜Šœtm|†‡~Žhghyn…‡‚…q„†Hl€wryvhmk_v}ƒˆ‡…‹y”œ›‰‹ˆ‘zuŠv|xmow~uusm\^^\cdXge\UPPWYPDLKFOICFCCA@CA=978:::;;:888::?>6;>7585773344236656778;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|}‰…‡Ž•—’– ¬ ¦¸¯³½³—’‹˜‹}tp~‰’~}Œƒ’”}†~†¤‡ˆ‚ˆ…x‡‰~s„x_cWKB60./23123668:=>?BEGHJMNQSTUTTVUSQOFC?80,#‡[??84.]–ps£UFIKLMOW`XmXZ\e†€|€}|ƒ†Ž˜“€Ÿ —”š™¥­’™»±§»Ç狌¡¥Ž“‰‘|qƒžŸ‘w……‹‡ihp„tŒ‡„Šr†‚wˆ€{v„|muuf”Ž†ˆˆ‡ˆ‡ ª¢–‰Ž—zˆzyogkx~|€ule^[[^j^bg`ZOLNXRQHPJDNGCJDCADDB<:87=<:<:88778:==8<=68756623444576867<BB?<8:>CQ^e\G2'&,,--.1(?‹[.310Oƒ_4?;nupfw‚zŒ‘ŽŠš›¤¡¬¦ª®°—‘‘„¡”„xwŒ”|’†’•Š€’›Ž„€ŒŠ‚‰ƒŠlpj]B@4--//..02234778;=?BDHINQRTRSSTRPOHDB<87/9C><<63.l“—MPHJLKJMV_a|eejq•”ˆ•Ž‡Š‹–…›‰žž¡©¤¢ª“¨µ¡§Á­ǯx¹”š|¡ž™„“…‚Ž¡Ÿ”™‘…Š…š‘–lpuŠŒ‚•ŒŽw„qm…Š–‘‚…ˆqˆ –†‘‰–¤´¨›Œ”¢ƒ‡’ƒ}kjj|‚ƒƒuc_e`[hl^ll^WKHNRQNLLFIPCDNFBCEFC=:96=<:;:987767;:6=:785456344566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYo‚ou†qv’†~—–š”žžœ§ ©–“˜žge¤š~„’‘y€’ˆ‘’}Š„˜’ƒ€€‹Œ‰†‡„‰…xx~gMR>/..,/.-/000212467;?CENORTPPQSQNPIED>;<:DF?><752<?R5HHHLKMNR^l‡zq~y˜–•¢ –“Ÿ’šœ¦œ¦©§«¨©´–«¾«¶ÇÈ·ÈÐϾ› pi«©Ÿ„“’…œ š›™¦’‘ˆ•£››xz~”˜“¢’——”ž{w•’ª²ˆŒ—Ÿ|”›‘•˜£¡¥µ¯œ˜§‡–€ˆlss}~sja^b`bhd`hg\REJKPOIILFFMCHLFFCBGDA:85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Ppt`m}awŽ}{”ŽŽŠŸ’—ž–›ª˜žªBD}‡‰‡˜x‚‹Ž|Š†Ž‚€‰‹Š…’…ƒ†‰€‡w^bP460-2/,.0/./..0015>AAMQRSQRSURNSLEE@<>=FG@A@8662<9;FHGIIMOQYlƒu†œ £¯¹´ ª©ª¥¦²©®´°°¬º°²½›²Ã«ºÉ˸ÿ·¥¢°³¬­ª£‹–˜„¥¦ £—¦™¢ª¨¥ˆ…”¤¡ «¡¤¨œ±‹•£¦·º› ¢¯’¢œ¡£¡«®«²´¡”¤©ˆ™ˆ’‰•yz~†ibi]fc_ed^gg_[OCIHSNFHLFJGFFHAKFCFFA;87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLhbWinXz„v“…ˆ‚›ƒ’‘Œ’Úȝ–sV—ˆˆœ|†ŒŽŠŠz‡‚‡‘Žƒ„‹…†ˆ’†‚…‰‡ˆ‡‡qna@E64<3/110-,+-0.-4?CAMUPRSUUVUN[PGGD<>>FHCEA7;<5C;=FKIFHQNPW€‚ªŸ­¥¬¼ÄÀ§°Ãµª±¾±¶¼´½³Àµ»º¢¸Å¨µÉǵ½¸´¨£´­°±›™’šŸˆ§¯«¥”vŸ¤—¡¬²´™–ª®¨®¶»²º¬°µ¢±¬±µ»¶´®´Ÿ¦§¡¦š©¯¬±¸·¸¦šµ¨Œ¤Ž’Ÿ†x‚…x[ceWgcbdaag`[TJDDLUQHIJDIGEA@@KDBMG<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AFWQJL[YQbbWyuq”}„†“u…€Œ{¿»£¼‚´”“›„ˆ’‰‰y†€Œ“Œ‡„Ž‰††ˆ†Š‡zxn]W@EN<6:45AB764//6CHBQ[OQUWU\WP_UIKJA?>GKFED;>@7D7?BJJEFVSP^¡ª¡®°½°³¼ÉÆ´¹Ã¼²²¿µ¶À³¾¯¶t°³¥ºÄ¤¯Æ¹°³±³§¤µ¶ª± ¢—›¢’¥°®¦­«§¤˜¡­´»¢¨²ºµ¼¿Ì¿ÅŽ½³Á·º·¾¶º·¹¬«°¤¯©­½°¼ºÁÁ«˜¹§”­Ž——©ˆ~ƒ~mXdbYlfkfX\cYVSIGFLQGCHIAHD>?BBL@@MD99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FRLALQVSYUZvjp~Žƒ€Ž„nzsx‡b¹¡™£‰””–’”“–‘‡†{†•Š€„Šz|Š‡†|Š‚‹ƒ•}wzueP\dGEL;Qca[^SF?;HPEZcQRYXZgYT`_LSPEA?IJHEEA@D<E6B>HGJLSZT]’¬´²¸µÅ»¶ºÇ˹ºÀ»¶´º¹¶½³¹±Å`t±¤±šžª½©¥¨«ª£¢²µ «¨Ÿ•–Ÿ™ ®¥§¦¥Ÿ¤”£§±´¨²³½¶Á¾ÓÉÉÓÆÃÅÌÂÊÃÀ¾½¾»¼·´¯¸·¶Ã¹Å½Âǯž¸©¡«¤§µˆtacc_Yc`jgSX`VRUIEENKA>GD=KA=B@=F>;H@796379>489:57045/26389374426?8@>GKRTSQPOQQPJA9/,,,*+((+-,/P>(.48€}<2Kˆq9>CKE@IMPRKQ]glkp…slrrs‡ÕÀµ™ •˜™‘Ž—‘––Ž†‡}†ƒŒ–Š~ƒ‚x{‹ƒ‡{‹yŠ‚—~t}zkfpuY^\Pedb`ed][XW\MdmURmm_n_XgdTYUJDBKKIFHHHHBI:D?HKSTU\Z[’¶¾¶»´Ã¼¸·Èɹµ¹µ·¸²¶´³®µµ˜du§œ­p^¢¬œ˜ ¢›¤žª¥”ŸŸ“Ž–™˜¨Ÿ¦ žš™ƒ¤ž­¥ª°­¸°½¹ÔÑÏ×ÐÊÌÒÌÏÎÊÆ¿¾ÂɽÁ¼ÁÀÄÄÅʾÇͲ£º°´®š«·»˜€|m_b^Z_cZdcQ[`SPKCAEFE<@F>AHB@C=:E>=J?47535;=468977022/24169775555D3ELM>51/006:477@IOI;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODQ[Yh_o–’”nlotu‡´¬¡¡Ÿ‹™œ™Œ•‘š‘…ŠŠ~ˆ†Œ‹ˆ|ƒs{Šƒ…{‰t‚Š†•s{ylmu{hreiligjji`fiilZms–­¤¼ˆ†g[og]ZZTHKNPJKPKSQILAJFJO_^afia—µÅ¯·±¹»³°ÃÅ´¯¸°°»«²°¦ª·«Œµ§š§šM™ŒŽŸ–‘¦˜¥•Š““‰‰‘‘›¡—š•—‡Ÿš§›¬¯¨°¨´´ÔÔÔÖÓÌÐÓÕÍÒÏÌÅÂÉоÉÉÊÉÑÇÌÍÂÏÑ·¯Ã¼Ã¹¤µ¹Á¢„qe^__ZbYZgZQ]XOPBBHEBH;AC>AG??A7;D>@H=46655;:687654/10146278875367C5B8?-0-1349=97,.,1;FK=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYReVs˜‚gqoyyƒ¡ªž¦—Œš›—‹•‘šŽ}‰‹„ŠŠŠ‡|„‚p‡†{‡rƒ’‹Ž}qxulqx~qzmxsmipmcimpxiw|~Ë¿Áߧmcxnc[b`JPRUNY^O]\NPNTPTT\nmv‚q–­·«²¥¯´©«»¿°ª´¦¤¸¦«® «´£Ž°­š—˜Œ’‘„Ž›¦‘œ‰ƒ‹„Š‰„‹„”•˜—”›‘œ—™šŸŸ«¬¥¨¢¬­ÏÒÕÒÎÌÓÔÔÏÔÑÎÇÃÔÑÇÍÒÓÓ×ÌÑÑÄÒÖÅÁÎÇǨ½·Îž|qh`e_XbS_[PQTQOH>@FABE<@A>ED>??:==<<JA45465<888664412/03526768533;=<E=@11+/249>5901022-2DN3)/3.32=N238C}_2A†tD:==I>@CFH<UQMNZu†…Šwlwp}~¡žž¡ŒŒ˜““‹Œ’•…y…ŠŠˆ†~‚{r~€€‡z„u…“ˆovrks}{w{s‚xrk€srioqzyqz¾Ëš~Œ²„vr„vhak]CZZ[VecXdjSX\]`c]cwz}‹˜©£¤ ž §¥ª¯¸ª¥³¢¡­¡£­¡§±Ÿˆ¦š“’‘‰Žˆ“‰j”¢Œ™„†~‘ƒƒ“—­‹••™Ž†’‘ž—¨°¢¡¡¥¤©ÉÍÏÈÂÌÑÔÒÔÒÎÓÍÆÖÒÌÔØÖÖØÔ×ÕÉÔÚÍÉ××ÑʬÃÂˍuqebaZVZU\QKGJJJ@;:;DAD<BC>GB>BB;<9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/--;R017/532FD28>nb5=tM99@I<AD?A;OLFJXp€u}hsxr‚‰€•”…‹•‰Ž‰ˆ†Žxƒ“˜ŠŒ‡ˆ‹ˆ~‚ws{}‚‡wz†‘•ƒnwpmuux}t…|yl‡vtn}v„tx{µŒ;A‹Å¥~Œ|ieWICfcecgjcmw[^fhknhn€‚‡‘‹œ œ—˜ž££¥±£¤²Ÿ¡¥ ¨ £±œ…ž’‘‘ŠŒŠ†ƒ„œ›Œ‚„…y”‚©•£Œ‘‰—’‹~˜‹›’«³˜›œ¨œ§¾Ãƹ¶ÆÎÒÑÒÐÌÒËÈÔÎÐÕÚ××ØÔÙØÍØÛÎÉÙÚÑÕ¾Ê˵zypg_\TWR]WFGJIEE=:7:@@B:FD?DCADB;?;;7DC75655;0679443341014558744449@>DBC<33.6FTWOQJAJF?1*(.BS39254/7K75<`bA<svV87AH:?C><9QECJTknnpbpqt†|—‘‹~‡’ƒ‰†„‰‡|x…—–ˆŽƒ‡…‡z„xqz{ƒ…uy…Žœy‹p|oozq{€qƒ‡nŽzuw}|‚t~|†‡¯sX©Â¶‘‚pmb=^hrpqpnxvehoruxqz‹†“‘š•Ÿ•‡‹“› š©ž¡¬›¡š˜ž¥žŸ«™‹š‹‘„|‡‡ƒ…‹ŽŸ™“ˆ„‡~l™z„˜†ˆ“Œ”Œ†|œ‰”®ª”–˜Ÿ™§¯¶½©­¾ÇÌÉÉÌËÐÉÃÒÊÔ×Ù×Ø×ÕÛ×ÓÙÛÕÐÚÚÑÖÈÔ˖|}kj]\QUTaICFIH>A>=7:=?;=G=?AAADA>>:87DB755479.556435532323647553458EBDCEB56<FNSM[nfcnskaV>,4LG865434BF4=W_hLux^8;?F<<B<99D>CGRj^mdbfkv€ˆq‘š€z€~‚‚ƒ~ƒ{|„˜‡‹~…†€w‚yn{{†ty’žŽ vŽu‚su}s€„o‚o’„u|…zv†{‰·Å¤Áɸ–›wpeNfczw†¢Šxyv{ƒ{„vm“–””Ž—ƒ‰–™–•¥œ—Ÿ•ž“‘—¢™«•ŠŒ‘‚Œ„ˆˆ…‘›™‰†Œ…˜zˆ‰Ÿ—ˆŠ‹‚}¡‰‘Œ¼¡˜“˜™©¦¦®Ÿ¨¶¿ÀÁ¹ÇÊÎÎÅÍÉÑÖÕÕÙÕ×ÛÔ×ÙÚÛ×ÛÚÙØÎÛƈ}|ikgaVYWWNLENC;==<8:;=9=@6=?@<?=<9867CA6455=80665547745613854564557HH=DJE7925;H>;::7IP][SUXK9T>;95327I8=NYMHxxd5=>C==@:6:>>@EQ_Xea][htzylŠ’wvzŠ{~€~|„z~‚‘‰„…z„‡{u}tm|}†~s~’ž‘žƒ‘{†~x~xŠŠn‚š€t™†~‰„{~z©ŽÃ¡½‹œ¤}‰„}‰r‹Š~s¦šœ˜“…{Žˆ„hGq ¤Œ‹’…ˆŠ’“œ™’“–‹•Ÿœ” ”‘‹~ŽŠƒˆ’–šžžˆŒ•’‘‹¥™ˆ„‚…„¥†ŠŒ¸˜‘•–¢¨¡žž¤¯·ºµ¬ÀÆÊÐÈÇÌÏÓÓÒØÓÕ×À×ØÙÛØÚÚÙÙ×Û¸{|znkhYb]TPOIDLB<<>99::99;=6?>><=9:;;37D@8378>70688357<37804976755546FP5DNI8938AK=;3C@I<:DWN<MTHN?96333>C;[X>5YypZ<<A<=>8689?=CQSRX^UXfmmmiŽŠqryŠ{z|{‡z|{‹†‚}tƒ…yszsm€~„~w…›¢›”’Œˆ˜‡€›’nˆ¨…z¡‹|‘ƒˆ„œ}šŠŒ£¢ ¤¯Ÿ‹‹…‹“†Wr­‹Ÿ«›ƒ˜›Ž\‚¢‘‚ŒŸ“”Œ†ˆ‹’’‹“““Ž‹Š‡–šœ”–Š‘“†€‹ˆ‘ŒŠ‰œ–˜¢¢†“– Š‰ˆ›ƒˆŽƒ‡†¤…Œ‘³˜’”—¡¡žš’œž¨²¸­¦½ÂÇÍÈÆÏÍÐÌÏ×ÑÑÕ®ÖÕØÚØÚÚ×ÕÙÙ r€wjh__ZUYYCAIC?>>:49:;7:;:3;;?=>7;9:1:G=:37=@50677255?65;55858:57735HR7GOK994=EJB>1FCLB:8:GX@5HWI66223:ECeX?&_yi_z>>9<;98:;@;BQKKSYPTcbzma~’ƒomw‹xyz|†|{w†„sp…‚zuwvt„‚„~’¦¤Ÿ¥¢—Š”—‹Š¨—sŠ²„¨’„™“…™Œ¢•Ÿ˜’ˆ›ž£’©°Ÿ”Žˆ–Œn·…šÄȲ›¡¥›œ˜–²‘d¤ÍȕŽ†‡ˆ’ŒŒ’“‰…Š‰…–™š”“†”—ƒ‹™‡ª—–¢¢ˆ™ž–šˆŽ†——‰„ŽŒ‡¤ˆŽ“¨š—“—™¡™Ÿ™“›£³´¦£¼Á¾ÇÅÅÉÈÉÂËÓÍÍÔ©ÒÑÖÖÖØÚÔÒÚ΅uƒkf``_QKV\BBGC;A=837;<:8=649:<:82?992:I:>67BC32:96264>=4;>6949;57944JQ<JQK9A7BGI@64JELF><88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBeƒGu‚Ž||m~ˆxz~z‚~vv€‚{ln‹~y|wx|„†‹~‹£´¨¤«³¡–§ ¥¤–•¯¢ƒ¸•’³š¡ Œ¤›¯¢¤˜§—©™­°¤—”•”‹˜š– ÀŽ£É¸«š¢¥­™‘›œ²†…¨¢œ˜…ˆˆ”‹‹“‡€†‡ˆ’˜”ŒŠ““†”˜†„‘œs˜²•–£¡ˆœ™“ŠŠ–š‰Š–†}Œ˜ŸŠœš™“™˜ ”¡•Ÿ›¡±­£¤·¾³ÅÇĽÃÿÆÎÊÉÒ§ÏÌÓÑÐÖØÒÏؼu}y`bWbXRIKOEBCD5>;76:?;<7=42669774=5;5<L<>;<BA75<;4277?@6??784987;<55OMDPRL8@=EAGA5:IENED:6A@BS>9DO323575=v\<R\tiZM]S<=89567=:JFDGM\\YJha;H„‹zzm…†y|„x€…}px|}|osz}{x†‹‰†„’¨¼­©³½°¥®³³©£¢°­Ššµ£¹¥•­¤—©­·¦¤£Ÿ™©˜ª¤¯±ªš™œ”•‘˜ —š»»­Ê¡i¶·ª°•˜ž¢«’—½¤^ª²‚‰‰Œ”†|ŽŽ}ƒ†Ž””ˆ‡’–‹•‹Œ—˜‘›™´–•ª‹œ”’’‹˜šŠ’‹Š–Ÿ¢•—™“œ˜ž”¡ ”œ¦®¨¢¤³¸«ÂÈĶº½¼ÅÈÈÂСÆÉÍÍÄ×ÖÐÊÓ£s}l_\UaSQHD><CAA8?874>F<<6<35355454B39:BM:A;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPfHa`bpJ@‹‰€r†‡|‰u‚Šƒ~m}||~pw‡w‡{Œ†Œš«ÂÀ°½Æ¼³´Á¼´¬«³¶Œ¨²­­½«›»£¨­¹¸«¦¦¢¢¤£ª¯²±ªœ¤˜›˜˜ž¢¦¥“£¹¯¨¿¼¬­²¹¥£§}ˆ†œ­½°‚‹‹Šƒƒ‘Žz‡Žœˆˆ—Š”—”š–›§š±š‘«Žš’Ž••–Ž ˆ•œ¤¬”–”œž” ›˜Ÿ •›Ÿ¨§¤¢¤°³¦ÀÆ𰻶ÅÅÿͧÇÃÇüÕÐÌÄʊvud_]b]OLCL@EG>A?B<:4>A==5=6>333241A17@BN>G@CNCA=C=;86CB5BIB:878;5B>79VKDWOF8=4K@C>4EJHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GE?CF\hF_ig[]\“ŒŒˆ{‡‹†ƒŒu†Šn~{~q~z”z’””˜‘“•¨´ÇÉÀÂÌÂùǼº¯«¹»—²¶º²À¯¥À£«°¼¼ª®«££ž§¬¯µ±©› ªœ¢œ–Ÿ°´§Œ£ººµÁ»«¨œ²¤¤¨”„Ž©ÄĤ‚‹Ž‡ˆ„†•”ŒzƒŒ‘Ž‘¡ŒŒ”‘Ž‡— ˜“™•–¥ ®ŒªœŽ–’‘••”‘Ž¡“†—Ÿ ²Ÿ”›” ¡™¤Ÿš › ”™Ÿ§¤¦§¤¯­¥¿Ã®¨·µÉþ¶Î²Ä¾Ã»³ÑÉÇÁµw{o^[_mTNIDMKKJ@A=BD<5AD;:3=8B332263A15IEM>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBg\Me\fTcjš–Š‹ˆ’†‰y†“r€{Œw‡‚y¡–¨šš˜»¾ÉÈÊÂÒÉÊÂͽÁ³­¼¿§º¿½¼Ä¸­Á©¬³¼½ª°ª¤¥£¬®´®¶µ Ÿ®Ÿ¦¢™£´½©œ¨¼Á£¶¶¯«“°¬ª¬–†šª§¥‘‚Œ’¤•‰€u‰‘y…‘žŸ’”‹‹“£™—›”“¡ž©Ÿ‘¥šŒ•–ˆ|Ž•’‘¢š• ¢œµ¦ —¥¤£¥Ÿž¦˜ž•—œ¥£¨¨¢²­¨»Àį¥³·ÌÀº®Ã³»½Á¹­Â¿™p{c[Y_^LMNKGDCHBAADK:4DH:;4<7F.12352A26SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQF7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>lI_XaZdeXžŽ—Žž’‰ŠˆŸ’„x…”~ˆ‰€–¡š®§£˜Ã¾ÉÄÈÆÓÍÎÍ˼·°º½´½Ë»ÃÁ¶·¼­´À¹¼®¯¨¡©¨¶®®©²·šž¬¢¨¢«··ª¥¯¾Ä±½¹³§ª´³­­–•¥­¨ ‘Ž’±Å§•}‘•}‡‘˜ª™—“““”’¥“™“ ¡¡œ˜Ÿ˜‹ŒžˆZ–—’–¤™f™£ž³¥–¢–¬­¬§œŸ¦—˜–˜•¡£¨¦Ÿµ«©º»Ã´¦´µËÁ¸ª¶¬³»¸®¨¸º¼·„op\ZVWPGLTNK?AHDDHFF85FM;>7>AK.32025B55PWN<LFKRLOGGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|hV<>@BFBsFiIRfdMF¦”œ–¡—¨–Œƒ‡¥’ˆ‡‚›ƒƒ•”Žš¢Ÿ¯¾®¡Ç¾ÆÅÈÇÎÎÏÒʾ»¶±»»¼¿ÏµÄ½·¹·³²¶³¸³¬§œ«¬¹«©¨¯¯—£®¥¨¤¥µÁ°«­´¾Â¹À¹³§¸´·²¯•¤­°¯¥‹“” sÁ™}—™„Ž–š‹±•š™•’’™˜¥£•Ÿš•™¨œ›¡ ™ŠŒ–`J–œš”™¤—T–°Ÿ¯œŸ¥•¯¯­¦›¡¦”“™˜ŽŸ¦¡™´©ª³¼¼»«°²ÇÀ¸¦¬«­±±£¡²²´¥sqg^\PRMFQQPQ;HKHFGAC=9KT?A:=EM/7534:B44NWN<JKOUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@CAF3>58JKCA=C;5EA:A?>H@5*B52,>c]g:35tde@R7&#3}hX<:BC@=REWStbVFH«—™Ÿ¡¨®˜—‡Š§–ˆ’…Ÿ‡„—Žž š£¤µÉ´©Ç¼ÃÄÉËÉÈÌÎƾº³¯º¸ÀÁ͵ȺÁ¹µº²¯¯³´§¤œ«´µ«ª§­¬™¤®¦¥©¬º¿¨«··¾ÁÀ¾·²²Ã°·½¬£®´­º¦ˆ›—¥šu¾Ÿ„˜Ž’˜š‹®–¡œ›—”šž ©ž§ ˜™©™¡§—‘ƒmu“¢š•œ¢Ÿ®²¢«•©ª˜ª¯¦¥¡¥ª’’™œ‰•œ¢ž–°§©ªº·¾³²®¾¹¶ £§¨¥¦œœ­©©fhc`SMMGIOJUL=LEMIJ@CD<QU<AABDO18=77?B75UXN?HNQXRPQTJQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CC:9C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW<:=..SaMVH~e^HF¬”œ¡Ÿ»®˜”ž‹“ª›‘‘“ˆª‡¢žŒ£¬”£¤¶Ç½´Â»ÃÂÈÉÅÂÎȽ¹²¯¹µÀÃʶƲÁ¼µ»¬©­¬°££™ªµ»¦ª§¬ª¨¯¨¤««¾¼¨­¼´·¾Æ¼¶µ¸À°½¿³©µ·¬¿¥¢—¡Ÿ¼ž‰š ™—·ž¨œ¥£š› š§¥²¡š¥œ§©˜””›‹–‰Œ¤¡”œ¢Ÿ µ°¥¦”±«š«­ŸŸ¥¤ª’–• „žŸœ–©¥¡¡´´º¶­¨µ²²žœ£¥š—•™ª¡žxc_a_LIFHNQINEFFBQJH@DGAVSDH<AGQ1;B7:BF79]YKALPTUSMWRNUJD@JJNO9C?5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-1:h]FDCœpbGE¨—¤žŸÃ¬›—¤—™¨›•ššŽª–•¨¦•­¬™¢«·Å¼¿·ÁÂÀÈÄ¿ÍÆ»¾¹²°¹´¾ÃȵÀ°¼¶º·§¤««­¡¡›««Ä¢¥¨¬¦ž«¯¬¢ª¨¾¸¦­¾°··Æ·´¸¸¾±¾À¶´²µ°¾£–£•“š“­Ÿ¡¡¤¢£ž¾¤¨¨«œœ ›¦Ÿ½¢˜¤ž¢©« ••ž“ž‡Ž„“ž¤ ¶¬¦—³§š°¨ œ«Ÿ¢š•Ÿ„Ž¡šœ’¥¤š˜«±µ±ª¥ª­¬œ˜  ’–©Ÿ”ie\b^PJHKOLHEDI@=OH@;FIH[RPK=HNU4BF8>HG5Cb[KCNRUWVQXTRUH@8QQPM:G@4CHQSIC;C>GVKC@O>K<06;GF>;FA56?9:?9;15D0--0Mv\4KZ5,MnW<-=)#zbQ5CKQ9oRF<KxfcXN¢›£›žÅ« ž«œ­Ÿ‘¢ž–¤Ÿ¦ª«—¶±£©³¶Å½À¶À¼É¿Êȶ¸µ´±´´·ÂÆ·¿±¹µº¶ §¬«¬žŸ ¥¤Á¥¡ª­ ¤©­°¢§¨½µ¥±»·¶µÃ²²·º¾²ÃÀ¸¸­´µµ£¤”‘“ ­Ÿ˜¡¨¨ª¢šÂ¬¨«­šš˜¦ ½¡¤˜««¬¦¡™šŸ’žˆŽX–Ÿ¦¡ ¹ª§”™·£Ÿ³¢¡œ°˜¡š•ž‚ ——Ž¢£•¥®³«©¢¢¥¤••œ˜‹’“¤Ÿ‰cg\eaMJKKOFEAGK>=IA99JJN]QQI=LV]9FI=DMI8Hc\KCLPSYYVWOZ^IA=WQIK?H@5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+waS6SZkWsHE6=ue\LPž  ˜žÃ§¤¢³ œ²§’ª£Ÿ£ž­©¬»±©¬µ±ÈÃÁóÂþÇĽÄʽ°±¶®±µ°Àŵº±±º¶­š©°©ª›Ÿ¦¡§Â­œ­±œª¢®±ª¤¨½·¦¶»½¯·Ã­³³Â¿²Æ³º·«µ¶®ª¢¦••”¢«¡ŸŸ™§«¯¯¯»±¥Ÿ©©™˜—“¢¤¸ ¡£’®¯«¤¥ž‘¡ž”Ž”š£Ÿ¨µ§§™µœ£¯› œ°‘¡•˜•›€’¢–ŽŸ “‹¦¬°¥§¢ ž’’š“…‹’œŸ€dh]hfKJLKSAC@IG;;F>89NMU_RSJ>O^^=HPBMLI8Nd]LELRTY[SUO\bHA?ZQAHAKB7FELKN>;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<w]^?[U_gr@8<H–weA4Ÿ¤žš Â§£©± £´©•±«¦¢¤²¬­©»²­°µ´Æ¿ÄĶ¿Ä¾ÊŶÀɵ¬µ©°¹¬ÀÄ´¸¯­¶º¥™«²¬ª˜¡§˜­»´œ¨°›­Ÿ®µ²§ª»³§¹³¸²¸Àª·²Ã½´Å§¾®­·µ©§¬¡––‘¥¤¡¡——¤®·­±´¶Ÿž¨¤™“”“£ ·£¤¥•®±±¥©¥¡ž›™š•˜¨ Ÿ™¢ž¯³¢¦˜¯š¥¬˜›Ÿ§“ž•™š†— •ž”‹©©ª¢§¡šž–™‚†•‰•Ÿzej]lkNQNNT=CANC;:I?77QN]_RVQBW`]BJSHVKH:Td]NFON[W[RPQX]GAB[PBG>NC9HGHNP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1\cZ33906p[bH05JqjVCWFŒyfC;¤¤œ ¥¿¦¨®® ©µª·¯«£ª´¶°°¸·°·¸·Ä½Ãǽ¼ÃÂÇÁºÁÆÁºª¶¥­»­Áø¸ª­²¼£•­±­²—¦¨‘ª¹ª¡§°« ¯´³ªª·µ¬»¬³²¹·¬¸°Áº½¿¦Ãª°¶®©««¦˜˜ª¡¡ ‘— °¯³«°¸™›©Ÿ™–’—¦ ·©¥¢¢¯±³«±§« œ Ÿ›ž¥¡˜£´°œŸ‘”¦š¡©œ–¤¢˜šŒ–™”–—ž”‰’›™”Ž©©§ £œ™›“‡™‹~—†›limbnnXQQZTACDU@;;H@7:XPd^QWWEY_^NLSO_LJ>Zd^NIQN[UYPKSWZI?DXPDF>N?=IGGQPB=CFBM?:2D?77547?=95E4+75/251.-.,1>*'+=\p=>1.1e[d@1747gYaF(@8m}h\V:‰{cC=¨Ÿœ¡©¼ ª¯ª£±·©¥´²«¡­µ½¯³¸¼»½·¶À¿ÉĹÄÃÀÀ¹Å½Á¸¯¶¨«·²¼¿¿´ª¯²¸Ÿ—¬­¨®˜©©Ž§»Ÿ¥­³ž«¢±°³¬ª¶³µ¼­°±µ¬°µ²ÀºÅ¶«¼¯±·¬­ª£±¥ž¥¨ž£–˜Ÿ²ª³©ª²™§›š”Œ ¦¤´®§¡¬¬­±§³«±©£›ž¨¤ž•¡šœ¨¶©˜š’’Ÿ™Ÿ¡ ’­¡›šˆ—™Œšž”‹——š—§¥£ ž—––”€•„{“„—gmrhqs`GYfVDCMXDZ9HB5>]Qh\OZ]G[^^OMSXdJKC\c`PLMNXWXPJVVWL=EUJEDAM?AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,+%2+*5K1.'__aV151=`V_8)C3YU\gK5ŒzfL@¥™Ÿ¤«¶£¬¨¥®­µ©¯³¹¦§°·Æ·±·¿Â¶µºÅ¾ÌŹÃÁºÀºÅ¸Áº³´¬ªº¸»º¾µ«¯±·™˜¨««¬œ®««¾ž«¯±£ªŸ±­³®®µ±¹·ª­®±§µ°³º¼É²ªµµ±´°®¦ ³ š¨¬ ¥•–š™±¢­ ¥¯–¡¤š™’¢¥§²©¡¦±¬ªµ¥®°´¯£™­§›—ž›š¬¸¢˜“‘˜œ¡™˜•®¡Ÿ—ƒ–›Žžœš—‘‹”“ž™¥££¡™—“’–{Œ‘…{‹ƒŒ“lnyov}bF`jZIHZ[={JGE6AbUi[M\aK\\ZRSSbaLKE`a`PMIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`Va.5(C^Q\.+A/JGP[G3cYTLEš–Ÿ°¨±©¬¤£®­µ¨·³·£¬´·É»µ»»À¾µ´·ÃÀÌǻĽ·¿¿Á¸À½²½®¨º¹¸·Â·¬®²º–—§¯¬¨¤²©”¯»¤¬²²¦§£²´±²±µ°·³©®«²¦¸¯µ³ÄŶ©µµ«°®©§¢¶žŸ¦° £”›™”°ž§›Ÿ©©¢ž›•—¥¥¤·§¢°³«§°§­¯´¬¤™¡¬¨œœ•ª¹œ•Œ˜£˜‘˜¨¤¡™†•˜‘œ˜—–ˆ——›¨¥¡’–’–w„‘†|†‚„nqxv|€]Lel\JOd]?b{GI8GgWf[M^bMYYWUXUi]OPHa^_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANHg27'FaLV%-B.=ELQ<3rkLED‘™¤­¤¬­ª¦£°²²ª·°µŸ«µ¹É¹®Á¼Ã¸³²µÂÃÏÄÀ¾µ¾ÀÀ»¿½´Ä©ª¹±¶·À¼¯¬´´ž¡§±®¥¦±¥ž²µ­ª²±«¨¨µº¬µ²µ«´­ª«¨¬©¹­²°Ç¿¸¥¹°©­­¦§­°¥¤£®£¨œ›š¯™¢¢¢£¬Ÿ£ Ÿ¡©¦¥¸¤«´´¤ª«©¬®¶®¢£¨«œ ™›“¤µš‰Žˆ‘£¡––Ÿ£—–‡‘–”ž›™–•‡˜’•™§œ  “’Ž‘x~…}}}‡ŠŠrts~~]Scn^NZg]FD–[G:NmXb[NabNVVVWUYh^QSMcZ[TKGOTSNGIVS\N;P^JBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3Dd;6*HdHJ+:I?3CIS,>l@HIš¨©¡©°¤§£³´°´´°° «­½Ì»®Â½Ç²´®´ÁÃÑÄÆ¿Á²¾Âü¿¸½Å¨­·¬´¸¼À±¬²®¡£§®ª¨¥±£ª°ª®«±®®¬«³»§·°²©²ª«¦¥£­º­«°Â¹´¬¹©©¨­©§±¥©¤¢®©¨¢žœ¢¬•¥˜ž™¬ž¢§¨¡¬¦£­¬¶°± ©£ ª­°¬ž§§©š£˜™ ¨˜†„‹‹Ÿ ŒŽ—ž’’ˆ‰’–¡–™–†—“”—¥œžŒ’ŽŠˆ„|w€‡…‡utr‰wl_Y`ncQsq\K;„|F>WuX`YOc\NUVUWQ\b_SOOhYWVKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=397;*35>10485(5/*,.30;),,'%234$,2-860)(1<^K0.JgDF8<B05EKX1@”]@NF•–¬§ ©±œ§¨°µ¬¸µ­ª¤ªª½É¼±¿¹Ã¯°­³ÃÄÎÎÿÀ´ÀÃĺÁ´ÉĬ¯·®³ºÀ¾´®®¬¦¨ª±©¦©²¦´­ª¯­­±®²­´»¥·³¬¬®¨« £ž°·¬ª­¹¶¤µµ¤ª§¬¬ª­ ¨¦§±±¤§¥¡¡«–ª¡“› ¦ž¤£ª£¬¢ž¦±¶¬¬¢¥£š©«®©¡¥¤¤™ ™–˜“‚‰… ‹œ‘“…Ž™¥›“‘›Œ“’’”£šœš‹‹Œ|†‚‚zu„~uw‹¢‡xj^`nfWf‡dN@g’LEbzWbXRfUMVVUTO\]aVLOjWVVIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72;::*49?./463)4+*,+.#4.-+&(+79*&6+<-2,&06XZ.0JgAA<<C+:JO^4D‡BIID–®¤¡ª¯˜©¨­µªµ±ª¥«ª©¼ÀÀ¹º´¼µ¦³¯ÃÉËÑ¿Á»¹¿¿ÃºÂºÁÄ®±µ²´¼Á¾³±¯­¬¬§·ª¥­°«¸®¨°¯®±«µª¶µ§´·«¬¤ªªœ¤ž³³©¨¤³´Ÿµ­¡ª¨«¨«§Ÿ««¨¹¶©ªª©¢©Ÿ­›‘ª¡ ¤£¦¢ªžœ¦´®§¥©¢¤˜¥¦§ªœ¢¤£ ™˜Ÿ‘Ž™‡Œ‡„žž‰†ŒŒ“…ˆ–£šŽ›‘’’Ÿ˜™—‹„€t‡‚~xuƒ€zx~ˆpqfgqx\atˆjO]˜VHmyUdVScPMUUUQOX[bVIQjTVTGPYUI>IHOQPxMNV=<KD?@A<@CUC9AK=5;E23;97*4:=+-341*8**+*,)*(/*&)%3;,$2)2021%/2Rc02@f=NX?C,?LT_/Ik7RF;•¯ ¥ª¬™ª£­®²´¯ª¤¯©¨»¿¼Á²°¹­¢¶¯ÈÇÈÑÀ¿½º¼Ã¾»ÄÂÀ¿¯²³³¶½¼Á±²´«´©¥¶©¥­³²¸¯¢­´±¯±¹«¹®ª®·«ªžª« £¡µ­©¡Ÿ®²¡´ªž¨§«£ª¡¡¬­¨½®«®­¡§¨Ÿ¬™°¡˜¢ ¨¦ž§›™©°©¢Ÿ¬¢¡’¢¢£§™š©¦˜˜™‹‡•ˆ}Ž†„…¤–†ƒ„ˆ‘’†‡–¡—‰‘ž‘“‘œ•˜‹††xt€}txz€{tt{j‚ˆ¤vi^ekugˆ‹|RVp_KxsTdSQ_MMSZfNMWYeYGSjRQ>BNQaQ:IHLSIqQLS;<I?;<=;@@W<<>H73CB15:93-5::)-31--6)(+-,52#2)',%.;.&1.0-14%,0Mh:38_=ad?F1CP[[+HP;YC3Ž° ¤¥ª£¤£¬¦´³±¨¤°§ª¸¿Á½±©ºª§­°ÉÆÈÐþÀ½¹¿À½É¼Â¸±°µ²º¼¹À³µ¼¬¹¬£µ§§¬±¶¸²¥§¹µ­´¼¯¼¥­­¶«­œ©¯¤Ÿ¤¬ª¨œª²¤³¨šª§ª¤©¢©§©½«´°®©¤ ¯œš³¢–¥›¥¤Ÿ¥šš¨ª¥žš©¡›‘› ¤ž™—©ª‘™š’‹‚…~ƒ€ˆŸ‡‰“‘†ƒ•›”†“¢Ž”‘‹‘›“–‡Š€rzy~|hv|{uqq~j†z…ˆd_gcr…{mgy]^VBW{mTaPRYKLNpt]IZ[hYFVgOC>KNDCA9HGKS?jaIQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11&/>KI1%90%,,09/,,+6'17#-/GjI14X=fbAJ7GS`U*=<F\@*Ž’°™ŸŸ©¤¢¡«¤¶²±¤©°¦­¹Â½·°¤¹¬©¨°ÂÈÉÌ·½¿µ¸ÁºÈ¶Ãµ´³µ²½¹º½¶®¹¶¿¬¢´¦ª«®µ·´©œ¹»¨±¾²º ®´¶©«Ÿ­±£œ¥¨©£›¤°¦¯¡Ÿª©§¢ªœ£¨ ­¼§®±®¡ª¢¤®žž¬¦˜Ÿš¡¢›Ÿ›™£ª¢š™££•–”Ÿ¡–œ–¦¬ŒŸ’‘Œ‚Š€€{š•Œ‰}€ˆ’‹‡“˜‘‡”¤Š’‘‡™”ˆ}zl}vyxbzzrpqsxj‚uk‚gcgansŽmbjo_pA]ykV^NQQKIMSYVM\^lWEXaO^PHMDF;7HEKO<rhJK9AE;;==;;=J49B<3;G<4?18-78;2(09/,5..=-*L>*49&'.34.0+/4&,:$40AhZ13S=e_DL6KVdN)=3R]>#‘–«˜Ÿ—§¢¡Ÿ¨¤·¯­¢¯¯¨¬¸Ãº´® ¹¯«§³ºÇÊÇ¿¸Â½¯´¿·Ä¶Ã²°º±²À¶»½·ª¹¸¾ª¤µ§¨ª¯­¸¯¨˜¸¼¤­¾´´¡­¸µ§¦¨°³ ž¥¥§¡¥™ž¬§¨ž ª¯§ ¦—¢¨Ÿ°¸Ÿ£±¯¡«¡¬¤œ§¦¨š››Ÿ¢•œœš©¦–›ž¨‘˜’™“™–¡ª‘›ŠŽ‡}‡~‚Ž||¡Œ‰z„†ŒŽ†Š“š‰• ‰•‚Œ—‘|…|tp|qst`xxjoqqpksdzlhecaf‡€`[rjrMN€iXZMQLKHPRPGM[_oTEYZRgOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23/:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%53=fd24M?e]FO=RZgH*?0][5(•›¥˜œ•¬Ÿž¡¤¡·«°£´³©©ºÅ·³®¡¸­­«¯µÅÇÀ·¿Â¹°µ½·¿»¾°¬¾°³¿²¼Â¸ª»º¸§¨µ¨§«¯«²¯¤˜»¶¤«ºµ¯ž±¹¯©¥§¯²œ¡¤ ¤£ –›¯¦¡Ÿ¢¨¯¡ ¢“£¤¢¶°¡¦±«Ÿ¬£®˜ª¥¨Ÿ˜š£“š›š¥ªš››¥•”—•œŽ“—¢©¢‘Š‹†z„~„‹z—Š‡z‚ˆ…Š†“˜ŒŽ–™‹–~†—Œz{prvnos_xwellljj…nfrikeh]ds`[kviZJ^\XOOKHHRUG39]^lPEYUYeMIIEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<"8R=*113>D5,-'42*;+139cm74GAf[HTDT]hD.<2dW,2”¡¡—”›ªœ£¡¢¡·ª­ »·¥¬½Å´±¯£µ¯¬¬®´Ãü³¿º·±³¹¸º¸º¯®À³³¸¯¿À·­½ºµ¥¢²©§©±ª­±Ÿ™¿µ¤§´µ¨ž²¼©¨¥©¯¬™¢§œ¤¥”— ²¤™ž£¨©œ¢Ÿ’¤ ¤¸©¤§®¦ž¥¡¨“ ©¢¡¡™›Ÿ‘™›–Ÿ¡ª›š˜ ”‘”—š”“¤¨¤‰Š†z„{„†}Š‹‡z…ˆ‰Š’†—’’‹•”Ž”{ƒ˜‹w~|ltrllsawuhhjggp‡hhidfii`jcjh[f{c`StT\[RLJFIOS@!*h^iLDWU^`KIHEC.:B<F<6KPD8:D357==895?:;4>8@K=>93)8><:9*6@3.E4(+,?0-N?.+-7,1195,&.5-80576`tA3CDg[KWGU`hB379gP'2ž¢¤‘Ž¤¦šž£´­§ªº¶§¬ÄÁ¸±¬£¶®§­®·À¿¼²Â·°®²¶¶¹¶¶­ª½³®²±¼¿·®»»±¥Ÿ¶ª¥¥³§©­œÀ«§¥¯³ª¬µ»ž©ª«±¥˜žª¦¤‘˜¥¬¢˜ž¤©¡œ¡›–Ÿ§µ¦°ª®¡¡ž¡• ¦Ÿ¡ š›™›’˜“¥¬¡—–”“•—‹˜›©Ÿ’‰Š‹‰y…w‚‡‹‚Š}€…ˆ‡†‘„—”Ž‘‘‘Œ“{ƒ•†s~~fyojjkftskcgddvbefffjickr[_Y^mdaNiXZ`VJGHKMRX>9_lhHCUT][IIGEA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A=-5B37=+*,0B*JK./*+3722(57$+7.72685]yN2>HiZLYJVbf@:3BhH%5š£ Œ­¡—— –¤³±¢²½¶¡±Æ¼º²±£·¬ª­©¸¼»º­À²®®®¶¯³¸³©«¹±¯®³¶º¶¯¸½¬¦žµªŸ ¯£©®›¡¿ °£®±¯·®µž­¯­­¢™§©¥Ÿ•š§¥Ÿ™¤¢¨šŸš“œž¬¯¦º¨®¢¡š›ž™ž¤š¤—ž˜›”˜Ÿ’¨•ª§š“šš’Œ•™Ž””š©¦ŽŽŠŠ{‚sŠ˜…‡|‰Š††ŠŒ‰’…•›“’‘—Ž€Žƒofymgkifqrk\hcctbfgjnlgjjhn]llsp`TcicfYIFLMOXRQUae€UAWSYTGIFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24;6#3*)6.55465Z|]19Kj[M[KXdd@A1JfC&4‘¡›°™“¡š©±¯Ÿ¹¿µ ´Â»¾º±¦·¯§­¤·¸··­»®­ª«·ª³·®¦²µ²®©°¶¶°³µº¦©Ÿµ¨œ¨ ¨¬š§½˜¬¤®¯¶µ¬­Ÿ±­°©¢›œ£«¨œ”œ§£š©¢¤–šŸ››¤ª«ª¼Ÿ§¤ ˜š™¡k¢–™œp‚•š£u‘©§ž””žˆ˜š€–Š¡y‡”ƒmiwƒql†‹†}…Œ‡q^cag„˜†k‹Ž”’tw‹„~ƒ€g‡€guheW\hsmNPjcgs…h_efnmj]`aŠƒ„eNKD9GTh^JGPPUULHR`oteF[QUPFHEC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=A@@=28@E=1,+08=G701.*.*/568,#1'214:175Xl16Ok[N\K[fb>G1Qd=*.‹¤™†•°››“ ›ª­ª£½Å¯©·Â·½½­¦·°¥ª¢·³²²±¹¬©¦¬´¦¯´¢©·¶¶¨§¬¶²®´­³¡©Ÿ³©¡£›¥¦˜«¹”¥¥¯³·­®¥©®«¬¥¡žœ¡§¦›— ¥¥››§¦“žž—§©¤¶°¤£¢–˜——£ˆ¡Ž’š†¡‡“œ ¥¥ªž’’š‘ˆ„sxŽ…ˆ¡v‰i—ˆf~sx oˆ‡„~}¡  ™€}ˆžt‡Žu›Šl‡ƒmieczlraS…mbli˜qXiqpˆX^i[ll[ˆrnzr…g†„Z_GN?G_MERVVQQSWTg]MVHRROFHG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82).1<I9/01.*/(-4583%&2115>1<8Xƒu25Rk[N\L\g_=K1Wa7/(Š§—ƒœ«œ˜˜Ÿª©§ª¿Ã¯±º¼·À¿ª¥·°©¬¤²´®®³·ª¨¥°­¥´²›­µ¶µ¦§¨²°¬²§­© ±§Ÿ£¢™Ÿ¡š¬³”£¥¥¶½¦­§«ª¬¨¥¡ ˜ ¦£™™¥£¤˜œ¤©–”¢›“’£¥¦¡·¤¤ £˜•“—’œˆ¯—”‰©‹–¡œ…±€£¬“™”y‚Ô¨€‡•Á›Çyx±¥·—e€Àœ¿y„…z’„|‘Êr—¼œÅzrµ¦»{€m–±«°yhlX±®nei½’¼ngzorØ~Skc¶²~r”sš¡ªWOWbOVNFU[XQQSŒ\W[PA\DQNEHI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>:B<?A8:J>52*22BE/.32.+/(-/186- /416A1=:Wƒw21Tk\O[M^g\>L1[]41!Œ§“§ªŸ—œž¥¬²©°Â¾²µ¿µ¶¾Á«§´¬¬©¦®³©¯¶³§§¦´¥§¸­œ³²¶«¥¤§±­¬°¦ª¦¤°¢¡Ÿ–šžœ­«“¢Ÿ³º£ª©¢­®¥¡œšš¢§Ÿ—›§ Ÿ˜ž§§‘œ¦š“¡¦¢¡±£ŸŸ£––’—’™…¯kjŠª~fƒ•†­dp”™¦”q®¡¤~x»}k¡v±_j´[¥€eœ‘`gƒ{gjxk©e¾rg¦Œu±j|±xt’”cnm§n[„¡Ehf‡–Euœ`~g|¤§‚Z_Œ«h€•xyj§7J¯\XSld[KNX_\WV;N‰OWW/ITSJCFF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3..53/+/(.0.:5/'$203B/=;U‚v2-Vj\OYL_gY:M5_Y30¢•ƒ­§¥ž£¤ª±·¬µ½¿°¶Ä²·ºÁ¦©°ª®¨¨¯®£°º¯£¤­²£©¸§ž³³°£¥ ©¬¯«¯¦§ž£¡¯›¢›–•–šš«¥•š¡Ÿ´³¢«œ£­­ ž™– ¢¨œ˜£Ÿ›™¡¦¤œ¢™— Ÿªž¦¦ š ¡–•‘–š…µ›µx…©™µ™v†³›·~“––©”~k‚¦{‚†ˆ“”“w«gk±\«z†”t‰r‡€ˆ—x‚‹˜‹ƒ „°vwŸqlll|‹N¤XHbb™~ch¦`yruS“‡^P©mcq~‡€bœ.Q¡o[Skh`LK[dX\ZB>±yWXA#MhFCEA@A19>88:84;:9<8:A:E::;6:CB8=?KNG:5:AFB@AD<FD;0201;F,0.840,.(/3,>831/2-D1=<S}n3+Xj\OXM_gW7J8aU50” •ˆ³¦¦¡¯©§³¬©»¶Â°»Á­¸·¿©¬­­­¦­±© ®»ª §´¬£«´¤¦²³§£¢ž§ª±§°§¥ŸŸ®•ž™””•˜¬ ™™¤¨µ¯¢ªª¨ª›•— ¥¨šžœ¢ž›Ÿ£¥£•›ž—™œ¢©›¦™œ›¢ —“‘““œƒÕ“™¹p°Á~ņ|֔›»|š•¥¤{Žˆ¤ƒ¥‚z¬yV¯zˆ~Ÿj¹Z¹v†„~¦‚”{˜zªxz±nŽ„t‘¼…o”P¯§ÅŠQ zc`ªbsrˆm—ˆ`Sµ´È…€‰|c¤3Bv]PjicP@XgZdaJHMnN\QOYfYCD?E?0=<59;74<;8=:<C:F:;>6:@C;6@OLH<:;DHCBCD<EF81211DB./0483+-).323971#%5*>3==Qwj6*Yi[K]O_fT7G:aP71%›¢”˜²¨¨¦´ª¥´©¤¼·Á°¹¿±µ´º²´§±¯¢°²¦Ÿ­µ§š§¹­¢¯°Ÿ³´°¡¤žŸ¦©°¨´¨£›ª•˜—••”– ©œ™–§­°©£Ÿ­£¨––›¡¥¡˜¡¡¡¡š¡¢§›ž ž”˜š¦ ›§•››Ÿ¡˜’”ˆ²nhµq«‡nŽ¦r´sr¶{š—¤‹¢‘¡¦±vƒ‘ÒÒv\®{…¤o›ª¦k‡…}­}˜™Ž{±q’žŽx³e—t„žožf”QȋZÂ\Ÿyb_­`vs‡b—ˆ^Yʝo¿uMKµSUÆdTQjceXAOk`lhPVGI9=URZWXIC?J<2?;5=<46>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>HI91746A>/.24252-).26,742&60;5:=Pqh9'Wi\BOT_eP5G=aL620¢’¥°¬£«¼­¦´¦§¶»¼²º¾¶¶´¹¸²¥´³ ±±¢ž«¯¤—¦¹­¤±°›´¸ª ¥ž¡©¤±§¬©£™œ™§•“——‘’¡¦Ÿ•“¥ª°¦¢–“­ ¦’” ›¤¦Ÿ•š¥¦¡š£Ÿ­™ žž•›¡œ¥••š¢Ÿ•˜•‘›…¬{w¨v£ˆ†©o­Š‚§ƒ˜˜¡‰’š‹¢“š‰®…‚³\r³R®}‚‚¤q×}x…~†š™v¯†‡‘œ‡w´ašeš‚‚•m’Z°XKšu˜yf`­^vwˆh˜ˆl]¯w•žxl5yÈ®²_BTo^g`EPl`pmVVM.fdiSYP;AD@L:5?91=<16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK96<46:>/04333.2..18*.32%!03767=Pke>&Vg\@>V_cN6GC`H:99 ž• ¹°—´Â­¨³¨©²º·³·¾¹·±´º´¤·²Ÿ³¬Ÿž¨«Ÿ”§µ«¨¯±ª­´¤›© Ÿ§¡µ¦¦©¢˜”¤ “’›—‘”¡¤š’¦­¯¦¡•™ª £‘¡™¨¤ •™¥¨œ¤ž­¡ “žš¡˜™›–—¢ ”—¦†©}}¥x¡Ž‚ªp­‹§†–Ÿ¡‰——ˆ£‚‘ˆ”ª|€‹xo±Z¨‚‚ˆ ytØvˆt¨Ž›Œ’¤{”Ÿ„{²^d ~ƒ•m’\«[Z“€‘hgªdr{k˜‡s^«Z‰ ŽkoeOJC¡\[Lt]bgN[a_rs_KV7J›•YGE=GFAM35A8.;>05A78@<6=<F?:<6?=B7.HVJEAH6KIN@IK@EN::@5.;>102144+*05/7,&21($$6671<PeeA&Uf[?2U_bL7FI_C2?8¢žššÀ«˜´Â®«­©¥´°·°µ¾¹¹±°µº¨º´Ÿ¯¤¤§§ž“©°©¯©´«ª®¡˜  ¦¤£¹¢¢« –›‘¡Ÿ”“ž™“—žŸŒŒ¨°°§ž—›¨¦ Œ’¤—¨ª§”—©§žž ¢­¤¡ž¢Œ”¡˜Ÿ ’ž—œ•ž¡•–Ž«œ®mr´s©‹uŠ§s´xs³€‘¤£’œŽ‰¤‡w¸p{‹¢jk¶Z¡…e——i¡¢§m”r´t“™~²j…‘‡­ju³af¢o‡“k—\­_M¡|‡‘Rs£ly~o˜‡r]¯V<œwfTon.\§OcSkebmZc]ap{cTZR>?np3CB@?M:!7@6.;@37C58??3;<CDBJFMIF62JTKEBI6IJP?HNCFP=<E50;;010/75,+,426/#00,,289/9N`eD'UdY>/U^aL5FM^81C8¦œ›ž¼¡›²À®­«¬§·©·¯µ¿´»¯®·¶ªÀµ¨© š¥£¡œ‘ª©§µ¢²§®© —œ§Ÿ¤«¸¢¬š•™Ž£¢•Œ ›˜œŸ‘“”ª¶°¨™•œ¬©—Œ”¥™¥¬¢‘–ª²£Ÿž¦«±™¡£˜¢–Ÿ›–œ–¡“©œ”«™‡Ô’š»s°Ã€Ã†~Ֆ›¸xˆ˜Œ—‹Œ§ˆz¤¶u~wv‚š²`ƒºyÀ|u¸cµ‚Œ‡©}•«©q{t¼ˆ§ ia¦Ž¯¡~Œt‡ª}¾os¼t²ƒuxŠnšˆrn¤t½^w}Zay¼kZV\jy^jaegcmxoZ\YCAAs@CF+5G"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB=E84=9020.87-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-7A9§›ž¢½¡—²Ã°­ª«¬±§·¯¶Ä°¸°­¹®­À°«£¡ž£¡œ›¨£ª²¤´¥¬¥ž•šª˜¦¬¸œ¢­—”Ÿ¤Ÿ’Œœ¢—š‘–’¯¹²¬–˜¤¨§”–¤œ¤¬ž ¨«ŸšŸ¨£³Ÿ£¥Ž§¢”¢šœ˜•£˜¯ ’”©ž„˜¶‘Œ·•x‚“šµwmknsoy…ŠtŸÁ»½š{±¨q€s‘¹ƒ|††Œ‡|Š‡˜|¤»¹½œtz´£tw—vt°u™žf†jµtrqw¶Œ^z}‰hƒynzc‹¬pu…X[§jEeZTf`c^cQggpluCNPMD;ZM?J3;0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITAKNGEOF?G<7>7070/9:.,/-*8/%&2(4$(>7/7LT_G'SbW8*O]]=+:VU'>;<§ž¡¢¿¥–´Ã´¬«¨¬«©º®°Å­³²­¶¦³¸«©¡¡¥ž ™“ª£¬©¥µ§§Ÿ›• £«¤½¦¡©–“›¡›‘¡§¡“œ—”˜”±µ·­™ž¤¤¢‹’’¦›¥ª›•©¥¥›™¡¨¥§¤©¡‘­Ÿ–¤ž———ž¯¨”›¦¡j}i›¦w‡r}™Žtyd‡{½¾Àºo“ƒr–ˆ`rjZ^›‰`cˆ•k`€•cmwb•l€š•”e^`cpšŠir‹}†•gkrux}~b[wthP\mƒ}{‹kXkz‚sJJo†pNtMEX]gaL[Wgc_O[muiqRQDEM;GI=M?2,2A?8/5?C<9;@;=C>RVVWYZ[\\]`aaa`\UG5DFUEKOHFPIIH;8=51:.0;:.0-76=5&"/*2,%;8-7JR_I'S`V4)P_L(3>[O'?2>© ¨¢Â£›µº¶£¬¥®§§µ±¬È«¯²ª³¢½°±¦Ÿ¢§£›™™«¦®£¤´¨¥›—” ›¦­¨½§¨¤”“›•Ÿ™’—¤¨¨‘˜œ°²¿¬œ§ž§¢‰“‘©š¨£šš« £™š£§¬£ «£š°›•§ –”Ÿ—°¥˜¡§™›œœ¢¢˜¥¡™›™™™•gm}qw’˜”’…‹µª†˜•ŽŠŒ˜–‡”•Š„“”‘‰Ž“”˜”˜–š ¡š›” œ‚z¥…mk}‘|€uŠŠq‚xyvu‰|Šjstƒuew}wkozm`c]phMYZfj`WZoymmfTPFS9OZMQO(+:KB635=@A9:C><ENSSTVWXYZ\]`bba_^^[TKCSGKNDGPLOI<:;389,2;820)6IRO8")+/2#4;*7FO[J&R^S10T^:+=8\J,<-@³¡³¢À¡¤²²¶ ©¥²§¥°´ªÈª¬¯¥´¥À¦³ ¤¤œ£••Ÿª¦¬¢£¶«Ÿ˜–•Ÿ–­©¥Àž«£”‘›——’”¡žž¢§“’™¨§²Ä°›««Ÿ––¨ªœœŸ¬˜¡›œ¢¤¯§¢¥¨Ÿ®˜—§™™ žœ¯ œ¡¦•—’—“Ÿ ”¢— Ž–“ŠŠŽ—®|–œƒ’‚‹ª©…€™—‰„žˆz„‡†š’ˆ†Š–›—‘˜¤–™“œŽg¡³¯…Š„v{’Š}wyzofy€‰juyˆsis{vƒ‡‚kudyf`jecdfkYl{oik]SLPD^TE@?>,4@F;45;>A;<?>>HNNOPSUVVXZ\_bca_]^]^]XVJKLBIOMRJ;<:786/2964.(&$-1./)+*7%+<(6CMMD/T]Q05M[17E4[G5<,@´ ¹°¿¬«®²± ª¦²­¢¬³¯Ä¯©ª¢±­¼¢³›Ÿ¦¢¡œ˜—§¥©¥¤¥²µž”“™™¯¥­¾ «¢‘™™”‘•¡œ—¨œ„Ÿ«¬£´È´ ª¤«—–—š¦©›Ÿ¤«”žŸ ª¯ª¦¤«¢®›Ÿ  ˜¤žœŸœ¯£˜ž§’—–œ‘£˜—§œš—e‚’|e~šcyŽmhk{’¤ªje›˜}g†Šeeih{Ž¡kg˜‘£wkj‹™£Ÿ˜slmz„ŽˆzXf^†ƒ^mŒŠv\hswv‘€ˆ‚mwxsmy„tv‰ˆƒ|k‡Y^ltd^s‰ik|qkd_RNXIdXAJ4>G7?FD71<=?AD;;DGHHILNPRRTW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%/*+'6*$;'/AJ[J/7ZO6)EY/DO2YC;?.=¦ º½º¯¬´±ª¥¨­®°¦­­°¼°¨¦£­®°ž¬–Ÿ£¡™™¦ªœ­£¥§©²­ž”£¢¯¥¶¹¥®¢ŽŽš¡™“’š ™™¤•|¦®£¨´Ä¸¥¢§¯Ÿ•ž¢ž£œ£©¨’Ÿ¡¡ª°««¤« ªœ§Ÿ§ ¬–¡›¥°¤—›©• š‘£–©—}½ƒˆr´r„†­hx¹Ä¸q“¢£z¦™™r«‚|ËÀÀ»qŒ£ˆ‚Ÿ}—™‰À½‚—žÂÁ|‚|“šÃÀ}l¥²oŒoÊz›vƒŽuy€€yqz‡pw…Œ“ynx”cg`xd`e‚c^tglddYLVIQZHOD2IE?DB>/<?>@A:8CCBCEHIKMNPSVY^__`_^^^^___]\SMPGUNA??=6468276*&%#)*&.+*)109*#>I[L*#BP.#F[3PY/VAB;/8–£¹Ãµ°°À©¨”£¯¨°®­¦²³®©¤¥¦¯«Ÿª˜š¢Ÿœšª¦¡œ«¢¤¨¤¤´¤œ¢’¦­«·³§®¢‘™œ¥’‘Ÿ¡˜›Ÿˆ§­¥¬®ÀÀ±¡©¯©–’Ÿ¢š¢¤ª£“ ¢ž­¯ª­§¤¤¨¡¦¥¬¨‘£š¨­©šœ¨›« •–¤•Ÿ¢–œ~Δxz¤y•–›_®^Ž§¢ |§–›s«ƒ€¯^cª{¨‡… u—“ˆ³c‚«†¡Ž³j„¯t}—ˆ·aƒ­Z£Ínv{Ú{™p}‡’v}ez‡vvk|‡n}†‘‘~mƒarmph``zd\qhjdg`RTSW]KOC5AHDD8>6;@?A;=8@>??BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5578164('$!',&&/(&+360$7;SL+,-K0';\;L-!P@F4.1­ÂÀ¿µ´°¸—‘£ª§­³«¦²««ª£ª¦¯©Ÿ¦›™¥—œ¢¯Ÿ Ÿ¨§¢¥ Ÿ°«š•§®¬°ª¨«Ÿ”‘šŸ¤’ž¥˜ž§£Ÿ®¦¬±©Àdz¨©±®–’œ¢—Ÿ©ªŸ•¡Ÿ®°©¬ªœ¨¨¥¢«’¬²–¥¢ªª¢¥¤ ®Ÿ‘˜¦˜Ÿ™““‘— q…Œ—u…¨†q±}žr¬~¢Ÿ¥žv«‚}­œs­¬‡†Ÿv™’{|—~ªˆ¢Œ’Œ~«{‰”Ÿ€{­WÅ{p“Á}•muoŒmeve†oawnro‰Š’ƒn’‘fpuuqagme_oiiogdXT]aZRSD9II@D<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^\[ZRC>;91478452&# 1' 1' '45-&7=WJ-<'>1)3W@F!G:C1.+°ÓÆƲ´ £Ž£¢¢¬¯¶®¨±¦¨ª¦­««¦¡£™¢•Ÿ¥«Ÿ¡¥Ÿ¨¨¢ž°¬—š–¨§®«§¦§ž—”™£¡‘” ­›§£°­¥­¶«ºÎ²­¦®¬—•œ¢™ž®¬œ— šžŸ©³«««›­«¥£«š®±¡§«­¥˜¤©¨¨¯¡‘•¢£™“‘„¤j¤u‰z©tz²p‚¦Š™Œq‰ ›‡¤``R«…®ƒ›v­‚¨†…Ÿz™—†{f€£‰¤™†‚£}©~‚–‡®_|©Vž£’z£Ÿ€{ïŋr¯³³¹rb©¯ÂthŒŒ˜Ž‚nœ•qozxypmgeerpf}jc]W`jXYUMMQLCCAB;C@@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799664,&$" ('"+-"$.!3-&@DWH,G+56*2PKL# A9D4,'ÂÉÕÔ¿¡™«§ ¯¢ž°´°®©¬¢§¦¨ª«©¤¦ ›¤ž¥§§£œ«š¢¬¡£Ÿ¯¡œš’«¤µ¯® §š•“¦¢š¢¨  ¦œ±¦¦©²®·È²µª¬©–‘œ¢™ ¥³š¡”Ÿ§¬­¤°›­«££ª¡³­¡ª³±¡š¨§­®´¡‘”¢¦—š‘{ªlž„‡u«y|°o‚¥Œ‰Ÿ–– •Ò¸´¸É²_`”©ƒ¥ˆ‡ z˜–šxªÉtš¤•¨©‘“šœŠšÆÆyg¡‚¥tŸŽ‚}¯]p´b°uK£‡m§G‚“dž‘|q™•q|u~|n\fjsqfk_aYdn\_YINMKEDAB>A<B?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75685/)(%&%$&),4ENPPMFKJVF*L0/=-5OTQ;<F2,$§¤ÀƸ­¨²­¬¥¢œ²¸¬ª¡¥š¨¤ª«ª¦Ÿ¦¦˜ª£Ÿ®«¥ ¬šž©¥œ§¶ž¢—“©«µ²¬›¥œ ”¥¬‘™œ¨£¡ª§®¢¥§©°µÃ²³ª­¨“Š—œ¥›¡£®¥—¡•™œ¦¦­œ±ž¯©§Ÿ¬£·¬¡±¸¯š®¦±²±£“–¦¢˜žŽ‚NxšŸz„£}ƒ¤…‡¦ŸŸ”„¸{{y¹‚Ìƶx›¡‘‹Ÿ~š–—Švž˜Š¤—£©°…† „¬}š•c¦m¤p…}–‚r¬`£sq€š`¼}RUtŽ’£–{~”“w{s†q\nnxrj‚p[d`iocd]LMQTAIHFI:9K>B108866877-*5==?BDGILNPTVYYZ[\__^]__]ZZZXUSOH@882.,*.+*''?QTVWWWYXXWUOUF<E3:P[T6?H,- ‹‡™©«¤«¹ª®Ÿ›¡¬²³¥ž •¥­­®ª§œ¦§›£¨¡³®¢©¦² ˜©¤”£¶¢¢•—¢©´¸£›¡œ¢’¡±™ž›§¦¡¢°®¦©¢¶²Å±­©­©‘‡œ¨¢¤œ¥—ž™šš¦¥«›°¢¯¥§˜¯¤»¬¡¶¶­œ´±·¯±¥—œ®Ÿ¢…ÑµÃ·y‡Ž…‘“€¦y”¡wŒ ’„¥Šqª†…´nriš¤œ•ŠŸ|˜™†‡s¯‚¥›¢Ž¦‹“‹–›nq²]¥t“zœl™{™|m©a£qqŸbs²¸hw”¦˜}Ž•Žz~yƒnjyizsou^eeonfh`K[XX<HH@U4@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^__][[ZXURRQF:223//++(@QRTUTSTVWWXXWUUVTQOQ[U%!2AH$)%’sŒŠ­¾¿¼º´ž–§¤­µ¡¢™”¢¨¦®««˜¦£Ÿ¥¡¡¶§£¨§°£”¬£Ž¤­¢ššª³³¤œ¤œ¨‘”—®ŸŸž§¤¨¶›£«¤¶¬Ä°©«©¢Œ„Žœ¢ ¦¢–™š™œ™§¦§™­¨¯¤¦›­¦½¬”½¯¬Ÿ¡¯²·©²¥š¨°¢§—y¨‘}|°wŠ€¤¥ˆœm²p¡‡­|¡ƒ§•˜€¬‰…­… •ª ¢—†Ÿ€™•€{’~«€š–‹«x¡’Š”’z¯^¤}¦§d€|—sj¯]¥kp…™]`[Œ m•‘¦™ƒ–ŽšŽ||„™€knctn€z`hfqoihhCZa[>KU3U8BBC7$$3+''3, /6674359@CFIKMNQRSSVZ]_a`aaa^][ZXSPONI7042.*,ATVVVUTUUUUTTUTTTVWWXVUUQHFIJ#((½“šƒ¨Å¶À³žš¬ ­·¥£Ž›¤¢Ÿ°°ªŸ¥ ž­™ž¹¡£« ¯©™®¡«¨£–‰š®°¬¦ž¥›¬——¬¡¡¦¡š¥®˜¡¨§·©Á¯¤©¤ž‹Ž›šŸ§Ÿ’”™›•›š¦¥¦›ª¬­¤¥Ÿ©¨¾¤–¬ª¢ ª±·¨¬¥ž²­§¨—u¯~‹œ…‡~º­Š™e°e•­}¡„¦•š¬Š„°…¦š¤¡¡‘…¡\lj³`­{{ƒ±mgo™™Œˆ±[~µ\¤„kÈ¢dŸ€{¼Xv´Y²}R®€z¬X€¡m˜¨›Œ˜’šš|z‘Ÿeuc†xt}bjgqngffPUd\AU`>I(>9=4!",%2. *1/045799<ACFHJLNPQRTWZ^`_`ab^_\[XUPNJFC553./@UYXWXWWXWWWWVWWVWXWWXYZZ[\XWWGB;ҟ²±·½º³Á²¢œ¬¦¤µ© Šš žœ³³©Ÿ¤¡ž¶™ ´¨ª¬ž¯­¬›•¯§¡Žˆ›Ž¯«¨¦¡¥™®’˜©™¢ž¥Ÿš££¥™ ¢ª³©½¯¤¨ž~‹›–¡¡š‘šœ’š˜© ¢š©®¨¦¦¢¤©»ž Æ¦¤¨ ©³³ª­¥žº¬««”€©’£¯Ž›€‡¤—™‚€¸ÃºƒŽœ“„§—œ‚¬Š‚¯ˆ§œ›¦ª~սªb£¿½}~£‚„׺¸µ…•“ƒž½¾„m£‚o«„lœz²°Çƒi«°½¬xw¢¾¼s€–Ž§‘›’š {ƒ“{d~{egy‚|alfkkcQb[Sj\?UbCM)=:4/$%2 $(0496677;>ACFGIKMNNQTW]a\__a^`[\YTQMHC?=A?5=SYXXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ¼•³³°¿¸±¼²¢œ®¦¥²¦‹˜¥Àª¸²¨¢À§¨³Ÿ²º¨Ÿ­¯¥§””°«—Œƒ›‘®¥¢¬ £œª —‹£’¦ž§œš¡©£™Ÿ¡¬®ªº­§£š—“}ˆ™‘¦œ“‘˜™˜”©›¡™ª©¡«§ £ª»ž¨Ä¢Ÿ­¢¨²²§®©Ÿ¹¦­­™svª¥¸†d‰ ph®‘‹nnw¤™Ÿu®˜”p‹q•¨£š—®¤rlllf‹xon‚™qzjqigŠ—–˜qii†ˆgq†d]ˆbjoY\f}v¦_aqŽ‘ned“¢™™™“š¢~‰‘˜wg‰xiky€zemdgmcKeXJkZ:QfFQ'K:+# #,)-2.5:457:<?ABDEHKLMOQSV\WZ\`_a]][TPLHD=:AB7MXZZYYZYXXYXWWWWY]^^]\\\]^]^][[UW^©”¬³©¹¸²³ª©¡®ž£³ª˜’¿³ÅÊ¿·ªŸÁ­®¤¢¨¬Ÿº£¤®«­¦Ž—®©‹…•–­ž¦ª ¤£ ‘‹¥’§™©š—£ª¡–ž¦§¨°»««š›““|„–Ž¦™Ž’‘™•Ž˜–©– ™©£œ±¦¢«¹Ÿ¯Á§£²¥ª®°©«©¥µ¢¬¶•Š¡¨¦·‰–£™ˆª›‘•’©³™š£ª ²–¢¡Ÿ¢œ¡¥¢•«§’’Œ‡“œ•‘™“™‘•…¥›˜–Ž‹””Œ‡…~g‰~t‚us‡Šp§lz““’€•¢—šš¥„‰—sk‘wqŒxw}zjmedpeUaY@j\HcbPY+F=+'!750.!%2(*699469;>?ABDEJKKMPPQXTVY^`ac]^TQKEC>9=@ASX[\YWXXXXXYXXZZ[\^__`^^^__```_YY`¦–¨ª¤´¶®®¡°£­Ÿ ¶±Ž¬È¾Æ¼º«£¦Ÿ§Ÿ±©£¶§©´¦¨‘˜¬¢‹‡‰œ§•¬¤Ÿ˜§žž’”£—¨š¨š”¦¡¤‘œ©š¢¶»§ª˜š}•Œ¢•‹•‘–‘”˜¦ ›ª ¶£¦«·§®À­¢¶¥®®¯«§§±¶Ÿ­»˜‘¥¤¦¶¢’ž§ Žª Ž“Ÿ£«°š £°¨¯˜£ œ£ªžžž—¬“™¡›”–«šŽ™™—‘–Ÿ‘ˆ¡ž–•…’‘Ž•‹~f‹…u†ux‡‚sœj…’“‰}‹•’’˜”£“Ÿ™¤…Š›Š}t—t{Œ€s|joe_qj`[`ZndPafQZ:GGE>2=>9/*&+)&&416668:==?AACIJGJKLMSSSUZ``iaeVPKACB:9EMV[^^[Z\[[[\]]^_]^_`abbaaa`bbbdb\[c—•£§¢¯±«®£©¦¬Ÿ§µª¥µ½°®­£¤›|Ÿ¤²¤¥±©—›¹¦£“™ªœŽ†Š‰œ¢®ž¢•¨Ÿ ’–™›®‹©–¨™¨šªŸº·¤¤˜œ‰z‚”œ”‹•’”‘’—£ŸŸ©žŸ¸£ƒ¯µ¢¯®t£¼¢°žwxž§¯¸”u¬£ž‰€«d\bv ¥Ÿ„˜}m’³œ£§­ª¢ežŸ’syš—q™¨˜m¢¨Šeœ¦’˜˜–’œ†ž›–„’‡’‰…wjŽ‡v†p{…`h‡‰“‘‹Zu”ghs{¨œœf{›Š…z™j…Œ„oz€kre`wplki\ffbbqT[>NNNSG>@UD:1/&4:306678<;>@AAFHBGFIKMSTUY]`hfgXQJ<DG<8UR[`ab`^__`aa_\]__`aabcdabaaedchd^]f›•¦£ ®¯¬«©¥¨­¢§­¤’–«·±³§›«¨­˜tž± ¨«§”—¹  œ¤‘‰ˆšžŒ«™¡”§¡Ž–’ž„v­ˆ§›©’™¥Š»´¨ ™˜‹‰uw“—“Š”‘‘””¡œ¡§™œ²•€Œ›µ³Œ’Žº¦Ÿ}§¢y ¬´Ž¥žƒ‹†°ª¯‹—¤›z‹¬…œ¡§¨§‡•…˜w¥›z‡œ—§‚‚{œ²zŠ†¡˜š•˜–‚‘——„›™bz‡…’‹ƒmp‡y€p€„~…s…ƒ”‘x–h’t šu}™…£ ‰˜”Œ……škŽ†ly|qqhexpjlk\eljfu]^ITLR@E6.ZUU7)!09>>743568;:=>>@DI?JEJKGSX[Y\bahfZQH9EL;>aV^bdfd`aa`bb_]`aabbbcfgcba`edcgcaahœ—¢Ÿ¦¬­«¨¬ §¯¦¦©¥™”¯ÉÀ±¢—¨ª·Ÿ‘…ž­œ§¢ Ž¾žšŒŸš |…Ž˜—‡ª› •Ÿ ‘Œ“‰†€‘§‡£ž¤•™ŸˆŸº²¨žš’Ž…qv‰•Š”›Œ’ ’˜¡¤–ž«‡Ÿ´‰´š­ŠÊ‡©¬ˆ¶…°¯¬‚¨Œ¦˜}¨s{w§—h•¤y´ŒŸž¦§’˜Â«ˆ˜¡rž€š¥}—…•²¡}¡”¡˜—”œ‹™’‹}…“‡–’‰ƒmr…~yq†€ƒ{ƒt„€–€Åf©‡£kž…¤…šŽ‡‹šq”†iyu|xhivrhhl^dpmgnYgG]RM3E47Nbd7&3<EGD:64658;8>==?BM?NIJLCPZ]\Wa^il\QE=KM@JcX]cfhgbbbbcc`_babccceiicbbbecafcbbi”–¢Ÿ¯§¨¨¥«Ÿ£·°©«¦š” ¤¥¬¥˜¦¬¹¤°¢©¦ž‰”½™“¡’žy„–•‘‡ª˜šš™¡„Ž‹w›œŸˆž¥œ—š™ˆ¤¹®¥šœŒŒ~bm‹“˜Œ‘“ •¡¡™¡§~¡§‡­ –­œœ…€ Œ©¬…£©™Œš¢u™”l‚­vM«x‡œ‘š¨¦€©«}ƒ¡{z§jž’kg—†—·‰ž~n`dYƒ—€{dh‹r™}y–l]}—m_Rpƒ\_kx‚_Xd|ƒ—p§ªkƒ£nr¥pŸ… jg m[oŒ}gZ`„cXQpwfnuskjo]jqnljYiO]YF9A5HD_l5,IDRMN=84859;6@;;>BP>QRLMBJ\]_W]^bu`MD:MONTb\\ffiibbdbddbab`bdcacikdbddgdbgeach—• ¸ ©£¦¬‘ ¶»ª®¢™˜¡£¦­¯¡ž°¶¤©“¢¡ §œšŽ™´™‹ŸŒ•‹u“’ŒŠ¦””˜ž~’……¬¤‡›Š™ª™››’‰§±§¢–šˆ‰€inˆ‡‹ŽŽŠ‹’Œ‘“£”ŸŸœ¢¤“¢¡” vœ•§‚ ¦…§«ƒ¥x‰|„š~¢ps”ˆ–|Ÿym†›Œ™›¨™Ž‡{‚¢sv¦fž~w¤_˜z}“t¢n˜·´ºt“ˆƒ€µ¨dÆ¸{p•¶Œr€š£bs¬«`|i³~m|†‚‹˜q£lr£tŸ…¤a™³–r}˜Ÿ³ut\ž²ƒkcpuwrioXkmssg]i^bLE=D6QBZs3=SG`JR=<395:96D;;@JP?UMOQ@D__[ZX``|dHC8MWUWbaZefkkbbeadc`ab`dd_`cknccddhdbgfchh“•”£·˜ª›“Ÿ¤¶´­­ š¢¤£¦¯œ³¯­”™¢š¡¥™›•Ÿ«›‹ˆ’x‹…q–Š Ž’”˜}‰¨ ‡—Ž‰’¤•œ›‹©¨¥ž—‡…~j{‡~}ƒ‹‘‘‰”¡ƒ—ž Ÿž‹‰wœ˜¢Ÿq¡Š‡©‡›¥Ž”¦©}­Œ~z ™z£“xt–ˆœ}–Ÿ†›Ž˜›¥…¢d¡|ˆ–›mžh›Žoš™z€‹§}rit«ƒŸƒtªh•š]›…v…žgªk€¸f\¨pœ`•Œ^§vu‡ˆ~žhšu†“’—Ž€Ÿoš‘n§š]©y»k~ª\Ž„]´h]nrzxki\qkyzd`fXbBQFO7WCRo5L[[_NZDA251<;7H?:CHU>YRY]>Db^V`Qac}jEB9N[^YdfXfgnmbbe_aa__``ec^bdoq`deekecihgki•›‰©´š§ˆc”›«¹±¯¬ž¦œœ© Ÿ¯œž²©®Ÿ˜¥›¡ ™—— £™†‰jˆ€r{—ˆ‹–•ƒ‘•˜zŠ„•¤œŠ”†ŒŸ“ž‰©£ šŒ’Š€i†y—Œ{‰ŽŽˆ—›”¢žŸ¡“˜rhŸ‰ŸŒp’Œ©‡˜ž¡¥ž¦{°­£¢¸—w£³£¤€‰”y{«™~¢Žœš–ˆ—q¡|…¯µ}kš‘¡y~˜µ¢¤«¨„™|›}ž›tªZ]o{–‹xžbL{z…cy—BLŸX¢jq{Žl€ˆ„™u›x†‰±³€›“§wƒžns}•pštk¤^•vHedatrof`liw|eeaQ_W]TW@ZFQhETW]bX^ID=B8?B:IF8LEXAWR[VDFb\Z`K`m~rEB<U_bZeiVghmobfg^aa\]^`hb_ecvm]egfkdeliiki“œ€°­™„S^ ¦³¹²²©š¢Œœ¬œœª•¢­¥£© Ÿ›š–™¡–ˆ‡‰w†oy•…‘›Š{‘“–ˆr€ˆ’¡œs‘‰š–¡œ…©œ›•‹‹‹}ƒl„…q‚¡Œx†ˆˆ“™–|“£ ž¢ˆ­†}µ„Žž{¥–z©€•›‰Ÿ›|§hwm~™t¡sr|ž†™p“ƒ®}¤ƒ¥™€£o^¨gu¢co¥aœÓ}{™xssb¢†~£t¤vk³Œ`‚˜‰sª²¨¼wƒm~¿¦©´]›m|p–mr¢r]¤gs¦`h¦m›Ôš~†›pz{—lœ|x—sn©¤gaezr€…lhfdovxh`cS\fQQbHYJUaWT\fk\eQFCKMJKBKE8O@QNXSYOSQ`ffjRcwywIFEc]eZhjTihjocjg`c`\]]_hbaie|d^dgdkdjlghlh—š¯ªT\K~©¯±³¯²£›™…™ª¡¢¥¦©¡š«‹›™™”™““¡˜Ž‡…{p}„h}ƒ”š€w‘Ž‰o…Ž’’l—“|Š“”¥—ƒ«›”“‹†‰yƒvˆn‚Ÿ†x’†ˆ™£˜{”¢£™Ÿ‰³¡¢¶‹z¬§¤®¥p©€šŽ…€š{¤€¡™†˜rž„¤®¯Š—Œ€¤•ƒ­ “vµ¶µÉ¡s”‹Ÿ`ž—©my–‡ ›t¢ˆw ~“—‹pMf£’p›‡s¤{ytaƒk~ kqd_œq}s–hyh²µ´Æ¦s˜}zkœ›«v…›nwy˜jš{u˜rQE}³_jwlzˆgkhcuuqnW_TYiPShIWMYTV^iloVhWNKAJMKHJOAQKPecjmetrsy|nu‰{{TQOl^i\kiRjhilhlfce_\]]^ibdik{_]dgcjfomeile¡›ˆ®¥ƒd?“¡²ª®¯µ¢¢€˜«££¦¦¨Ÿž§„›˜—Ž—œ“Žˆƒzjy‡eƒ˜ yu‰Œi„…‘‚Œ…zŽŒ—¦”„™ª˜’‹‰z€}Œyp¡†z‚•‡‰– –”¥¨œ••ƒfnxœl¢d{q¥w›˜pg¦€•Šz¤zŸ–ƒ—sžwŠ•—¹n‘Š¢b}™ •ˆnriªku mo¦`›i‹i–‡›–u¢~š`Œ†upˆbh ež~i›uocfˆmq¢Z^[b¡l]ˆ‹nz}qqd¥mx¢dg§h™sŒ™p¢pU‰o _f¨T‹^T˜nntksƒnqilytkpRYWWfZTmIZP]IXiisjYlWQRFV\LXSaUik_wt{}p||rƒ{€sv€„v^RrbgcpgPjhhklnhdg_]^]`jbjivu]\chcjjsmfkmcœ£—¥ydsm‹¦­£©°±¦Ÿ‹€˜¬žŸ§£¢œ¤£–™”ŽšŒ˜ŽŠ{‡q€ˆi‹‹|˜›su‰~{dƒ‡”‰Š•™‚|‰ˆ˜¨’£­‘†‹‚Š~€€ti¦„}‡”ˆ™ ˆ“©¦ˆ¦x•›~¤ˆ–‹±˜‚¯—Ÿ¥v”†x©s¥„šn¤¢Œ’„ƒ»n}¥¯ƒ†…†“•œŸ|¥zr¨• –gž~o¬d–Š–“w¨mª¢‰v‰ƒw«‘¦ˆk‘°kv³Œ©kŠ…mmŸž’•`~«‹ªv~~Š¤žwŸ|ƒ¤• j›ˆx¬hŸ®Œ¶tw¾¤“Zƒ§Ž«avsur|uqckoimSW[Vab]kM]R^J^mow`[qY\`[gtenorcrt`wz~yryƒs„{{Œƒ€vbxdcnrdRkgholrjfia`^\akbmlzo\\bibljxmglnb•¤©œ£–©©¨¦®¤™Š‚˜¬›Ÿ¦Šœ¦ž«ž…›‡œ‘†’ŒŒs†zˆ„oŒ„}™“tt†s’‚m‹‘‡†“Ž}{‚‡™§€§§Ž‰…•v‚‡’ol‹©ƒŒ”Ž‰Ÿ‰Œ”ª¢Ÿ€u”—ˆ~y”®¢šq†wŽ‰‚}{r§Œr~}z˜–›„y{~‡”•“Šv˜ž ƒ{}‰kŒ…[yyrzqin~’‰q€u”“q‡„‚eŒ_‹wtr”uoynm‡lƒ…]ugwŽe€„Œ§™}t{•j‰ˆpv}‡wnnhtz|˜x…\lXyioxsrpxxp]l‡njgV[`W]fkdVcU_R`pyymkwfkkkw}rrutaovbt{‚xuz‚u€€€x‹…ƒ}{nldyn^Wnghukxjije\`Zcjemqtn[[bldllynhloa“·¨¦‰ ¢š¦£˜¤œ«¢¡„„˜­’ž¢Š›¨›ª™ƒ‚œŒ—”‡ŽŠ‰q‚|}~Ž„{˜tr„q•…{}’‹††„y~€ˆ›¥|¨¢Œ†…•ƒ†Ž˜vr„©†Ž’‰ŸžˆŒ›§ŸŸªƒ‰Ž•š~~‰–­§‘¥wo›xn~¨…q~•qkp}‚ €“Ž‹hl\‚‹‹›šžŽs•‹ˆqtk‚wtYrn‡‘~Œj]je{†„‰€`ixzš{‚Šu…gwŠ†j_oqu^q‰€ˆ¤”…e‹ƒnw‹„q†zqhif|„{–[\khnv[|yxvotsƒh]n‹kkbZZ_[Ylq\_aZ_^ft|vpudkkk|}s|yudnuhm|~wz|{yz€€~o†Š„{}t~yshT\qilvpugkhd]aXkhkkqrnW[enlgszohjm`‹Š©°¡¢¡šž—ž˜¨£¢~ƒ™®Ž •‰£‘¦•€|˜†}’™Š‰‡‡Šr}Œv…‹„—Šro€r˜†ƒ~’ƒ„†‰€z„œ¡‘ƒ¨¢ˆyŽ—‰•‹‹œ—„ƒz­‚‘˜š•Šž‡ˆ¡ªŸ¡¢¤‹ˆ“›œ£™•ª¡§¦Ÿ’š†”Œzvƒ§~’’”²¦›•Ÿ±’—ƒ¥ŒŒ•šŸ‰›‚ˆ‘Šk|Žwxeƒ‡‘‹|‰ž„‡Œ‰‰…„w|zt™ ˆ†‰‰„“~}Š€tnr„}v……‰Ž¤‚…Œ†‚ŒŒ}ˆŒŠ‘„zn„…~z™ksiatŠq~{xwpxu‚]^o‡hn_^Z]]ShrVd]]bmhv|}topekji€}ny€rjpqlg{r‚€x}„{m‚Œ†|zx{}zƒxNcvjsnpzekecb`[tfpgrqmU]ltmiyzqgikdŒ‡œ¹ž–¡ ˜”˜™”˜¤¡ž|š¬ŸŽ‡ Œž–}y•„|Ž™Š†„„†nys‡}‰”„mk~z—‡ƒƒ~€‡„…|ˆ…œŸ“ˆ¬ „s‹†’‘‹‘}{ª„Ž“˜–œ—‡‡›¥Ÿ¢™œ…‚’š™˜š§Ÿ¥œ•ˆu{†„¥{|Ž‘†™«¢ž”Ž©€Œˆ“™ž‚—~†Žƒox†ru`„†u™ƒƒ‡……„•nyvt’¡Š‹…š„„Œs‰{|qqz‡‚zwˆƒ‘¥Ž…ƒŽ€ƒŠ‰Šw†‰‹~rm€‚}oilnh^zi~}wvwv{x]`q~nt`c[]_RgnTf[^bkivzrlmdkjhlt‚lluozp†zn‡€v‚€~…vq‚ˆ~{||{‚Š`h{juii‚djc`i\cuhobumlUcqyepz{sejmm‹‰ž¶™ £Ÿ’‘•˜‹šžŸž{xŸ§‘œ‹‡¥•Œ™™zz†}‰‘„Œ‚‚ƒn|€ys„}‹’}kh}‚—‰ˆ{}†„†|ƒ‘“‰©qŒ‹Œ’† ¡Š…Œ|¨‘‰’—“–“x£Ÿ •˜~€š˜’Œ›£¡£™–š}Œƒw‚Ž† ~ŒŒ|˜¥¢¢“š‘¦Œš‘‰’—›~“’~‡Žut‚qwa~€Ž†r‹–}ˆŒrŒ‚…†hxrx‹˜‘–~ˆ‰r†{|pwzŠƒyx‹‚•¤“Š…{††‡„vƒ„‰‰}hs~z|rmlh_~ti}vvt}sk_`tvpwdcY__RkiVfZ`ahjvy‚qgkdlhf€€kn~hoql~x‡{lŒs~tv‚†|{€}irƒntia‡hlb_qVtolm`xhmWjtvcuz{rbjoz‰Œž±‘¥¤œŽ—†œ ›}w¥¡Ž˜€£‹‰š–y|†ˆƒ‰‰‚r{tvƒ…}Š‘wgc~†—Š‚Š‹x|€ƒy—ƒ–™˜—¡œpŒ‚‘“†¥›‡Œ‰ƒ¦–…“‹–—“’v‘ ¡—“•x~Ž——–›¤˜’”šx„‚wƒ•~‰Œs—£Ÿ¢”™¢ŒŠ‚–—ƒ’–™~˜|ˆvq~n{d€|‹…q‡“€‘‚l‡ƒ€‰…fuo{†‘—‹|“x‹ˆ{†{zq}wˆ…xƒ‡Š—¡•ƒ‹vˆ„ƒ‚w|ƒŠ†xazzu€yhmfbjkxttw~r}cdasnurmaZa^[leSdYaahkvy†qckcmfh|ƒmiuhnpi€}ƒzn†r€ƒƒ~t|ƒŒ€~{‚ƒ~|mv‰sumeŠljbbuV„ipn`xglbjvpfy|zq`rl†…›­—¦§žŒ—‡†Ÿ“—™~xª‹š{—ŒŒ™y|Œ~|„|ƒxtyzt}€„‰‹€d_}‹”‡„†t}~‹}™†—•˜¤¢™€s‡{“‘‰¦ŒŽŠ“ ’„’”—‘‹—Ÿš‘r‘“‰ž¦——Œ”•r‹Œ‰k„—™z‡ˆ‰o—ž›¤”•‹Œž‹†‘œ’’•†™ˆ{ŠŠyqzlul|‹~n†“ƒ•xq‚„~~‹€eri{•–ƒ~t‡‚x†}uw|„€{‚‹‚‹“£xƒt‰‡}€tv‚‰…qb|v{r~pcpde|copwsyxtubw`plvno\\_^^k^P^Ycahnt{‰l`iekciw‡ngmikmh}{xoˆs€„„}t†‰{ƒ}z„}}Žrz‹xxml‡jh_irc‡gqoewgnlayik}{xpaxm‹€˜˜©Ÿ¤¨ŠŠ’†Š‹•˜~x¯™˜~Ÿ”‘—”ˆw~|Š}|€wx€€put|o†}Š|a\~‘†€ƒ‚s{€‡z’‰“’•¦œ–‚}}ŽŠ‘£‰ŽŠ˜š†’™”–ŽŠˆŒ’œ’‹‹m„‘ˆž™¢ –•ˆ–m‡˜ƒe…˜Ž“z‰„Šp–›•£“’‰‹™Œ}’Ž’Œ™Ž{Š…‡ssvlqnu|Štn†‘“qu|ˆ|eply{˜“|ƒˆt‰€s‡xn|€…{„‹‡‚‹”§Œz†{~‹…x~qp‡…fizuvq|c_qakt_qk{zylsqfz^olsmrX[_`al\PWXecgqqˆg]iigbgqodjheiizwuoŽ…t‚ƒ{u‚ˆ…x…|x„…z‰w‹{{rxƒjk_pht€kromrgole|cn€zwqlwwŠ~¢—¡§ ¦›‡‹‹œ‡“v‚«•“ˆ¡–”€t|w…xyrs{†kspzn‹v€‡op[Y~‘‡€vu€€€ ‡’‹”žš¢•˜xŠˆœŠ†’˜–…‰•š—ŒŒŒœ‰Ž‚l‰‹‘‘Š–¡›—”„—†iƒ¢e„œ‰~‹ƒ‹w“™“Ÿ’‘‰‰”~}Ž—{‘ŒŽš’|Š€‚ovplmop{†itƒ™‹qw€u‚ˆƒyfrnu˜Ž{‡„y“yu‡soˆz„ŠyŠ…†›¢‡{ƒu‚‹xynl…ƒ_tutrry[_qapk_pk~|qnnknwapokqmYYbaboYQTZfgcup„ƒc]kndcfk’n`gg_hkursp‹€uƒ€yv€‹€y…xˆ†wƒ…|†‹{vŠjqc|c†|nqmtjholvx_qy|tut€ƒ~¤•š¬ž§–…„—”ƒ vŒ ”“‡Œ›–Ž‹zryu‚pr…tqvˆlpnvmˆvƒ~€mmUQ«”†‚wwrƒzƒ¡ƒ“‚•”š“›x’{ƒŒ’£™“Ž‰•™’„‡—™Œ”‹‰‡„Š{r‹…ŠŽˆœšŸ›•““}g„›†g…Ÿ‡‘„‘‚‰qƒ‘˜œŒŒŒw{‘zŽ‹Œ’–Œ|ˆ|€kwjnkll{bz~—v{xƒŒ}ygsls†”‹~‡…z’qyƒou‹yˆŠyˆ|€ŠŽœ„{zv‚‹|wqjl‚„{ayqomstV_pbrb`mozqipfguuirlbwe]Wfa`sTQO\fe]ypˆ}`\irbbef‘j_he[gp~pkqtŠ}v|†€uv~Œy{…xˆƒs†…~ŒŒ„|y•xfrjƒ`ˆ~ookz`jntu_t}y‡xts…}x ™°œ¥Ž‚‹ƒš‡€ŒŸ€‹š”…ˆ˜Ž„wtwt€qp…tpr„pkiwnƒn}}mtsRM‚ßȒ֓{pu„v…¡„”w–‘™‘™{”s…ž¡’“‘‹“œ”†—–ˆ‡‘‡›~€wz~‰ŒŠœ›œš”’yŒuf‡…k‡¢„‘ˆ–ƒ†cŒ‘™•‹—ŒŒŠŠqz”ˆ{ŽˆŠ“‘‰z†|m|esoklzz[yz~€†Ž{{isjsŠ‰…„|”Šk}~mŠ}Š…|„y€“™˜‰|uwƒxsmgq€…nlupijunS_pepZ`msyhlkcgyspqd`xa`Vl__vPNLbgc]zq‰u]\evabeeŽdagbYissnkqvŒ|tz†‚uv}‹s€†{‰r‰ˆ‘‹ˆ|~˜vesn|eˆ~npl€Ylnyys`vz{vrwŠwyž‹›®š ‚…wˆ•~|Šžˆ† ’…Œ˜„“‡txpyqo„pmoseeyq}my}jhkc¤šÁÜ®ð¡slv…w†¤†“p—‘–¡•œ’r†‹¢—‰–‹–ƒ–…‰€‘‹‰•}†zu‰x‡„Žœš˜˜Žv‰um…ˆ‰|‰¢ƒ‘‰œ„…^‹“—‹‰‹‹„‰m{–}ˆ…‰‘†v†~~k}dxvjnysX‰{’ˆ…z~†Œyfri‰‰‚~‹•„kum†Ž‚}x~Ž”‘—trw‡Œusqgvz„cunqcjvhRarhlV`ouzard`iqso[drabWn[]xNMLegb^ws‰n\\dy^_ee…`cc_YjsknkswŒ}tw„xw{‰qƒ„}~ˆ{t‹‰ˆ–†Œ~—sgurylŒ{ntqWqzvyrdwy†Œiv€‰rœ†˜§›£’„}qŒ”wyŒž……¡|–€šˆ„{swptjp‚ljm|u_axw{qu{g`d|ëÚµÉÃ܇slt‚w‹œŠj™‘ž–”‰q…ˆŸ„‹–‹Œ˜”|“ˆƒ‰{‹…Ž€uxƒ„rˆ‚“œ–”—…Œu†}oƒ‡†˜¡‚“Œžƒ‰aƒ”‡Š†ŠŽ‡‡i|“}ƒ„‰Ž‚r‡qwhvsjtwlZ}“ƒ…}€„„Š‚varkˆŽ‰~~‘}mkw…Ž„{€|}‘Ž”ˆmpyŒ…tkplsy‚aujp^lwaResifS`qwuap`]h„rtkXhhciYmW\uLKLfg^bss…j\\ey^^dg{ad_]YkofojtxŠ~ss~{vzˆs…ƒ|‡vwŠ†™Œ‚{“ulwvyx“tnx{}Xy†qogxw’‚dv†…pŠ–…™¡š¢Šˆto’Œqwœ~‹š‰‰} „š€xrtnodrifmxx\`y{{qq€iagaÕ¶Ž‘¦xoqx}q”’Žˆkš‰“Œ†{i‡‹™†’‘†‡˜Ž|‰{ŽŒ}ˆ„zszƒ{q†€–šŽ““ˆt‚…u‚‰‘œ†•Ÿ~ˆb“‡…ˆ…‹€€ƒg|€~‚Œ~mƒ|ƒulmwuuxvlcŽ€…~}†„‰p_qp„{Ž‹{~ˆypƒeyˆ…Š€z„|~’‘‚mny‹~umnkl{dilkZnwZSjsibQcsxmcf^Zk„ntb\h_em`oU\pOHOgf\hor€n[\cs`\clwee]]Zlmcmjsw†qp|}tx†x…‚|€‡uy‰“•|‰†vˆpxy{„“on{w^ƒ€tmizt”sgsˆ|q’‘ƒ™Ÿ› †ˆvv”mw”˜ˆ„‹Žš}Œšw~vrpljau}gbjuz[`x|zlp~ecggW_qs–½Å…wr•‹‘€t˜Œ‡”ˆskˆ•€{”‹„›Œ|Š†}|‰Œ~“‡t‡…vv}‚qu†ž•†”‚‚q~‡sƒzˆ–›–†“€ˆf}“‚€†„Š‰r}g}‹{y‡‹}i€}„vfpyxtxtlk†‹‚‹yƒ„„€k^pvz}‹‡„{€Ž~r€hx…‰„w‚{•ŠŽ‹|mkz‰|vtohh~we]rdYptSTosibNhuyga^]YoptZec]knaqPZlRDThbZlon|pZ[^mcZcowdg\]`kjcliswƒqn~{tuƒz„‚|‚…v~‰–‘xƒŠtˆsyy~oo{qj‚yz~nm|v•kjx„tk“Œ…ž˜ ™…ˆo~Œvjy™€‚Š‚–˜Šy–ozsqljd`t{i`fr{[ar}zfpzaedŽ±²wKbZ¥ÚҘs|’‘z–Œ…š’†ol…’‘yy“†€„™Š|‡€yx‰Šƒ•n‰†qs}{jy†ƒ¥‘„“Œ‚n~‚u‚w„š—’Š“”…ˆpz’„~ƒ„‰ƒoxh€…xrƒŠ‡|e|~„vcqs€jzqou™†„‹|wy€„z‚k\p|r‡ƒˆ}…‡zˆq€mp‚…‚‚qƒw–ŠŒƒwml}„~vzehj~raZx[ZrnNXrtg`Knwvb^\[Yu~spXg^fkq_oOXiS?Yg_[qkhzr\[YkeYcpy_h]^elhfliqx‡om}up‚{€ƒv…‰—Šq‚q{†|zy„”Œukzlp~t}or|{“poyf’Š‚¡˜‘ƒ†g‡„pgz—Š€…‚šŠ|ixrllf_aoym_boy\dlƒzaqv_deÕ뾋3:>‹€ry†ŠŽx…™Ž”Žnm…Œ‹u}…‚•‰|ƒxnv‡„‚•vm‡„ku{ueyƒ„§ŒƒŒƒ}msu‚x„š‹‘’ŒŒ‡{’ˆy€…Žƒl€ri€~xm|{Šƒxby„‚rdqinvru‚œŒ€†tv~€so[k}sxˆŠ{†|ˆwypk‡‚Ž‚ˆp€w}“‰Š}smjv€€uu]iiyqZW~T[rfM[srf\Jryq][[Z^v€viZb[gfocjNXfQ=^f]^vf_uq[YUodZdqz\h^`gmgjkipx}Žmj‚„€yn{}‚zu‚Œ“…p€‹nw}€{{ˆ“‰€i{}kt|r†{sv}Œzx„~|kŒŒ„›–Œ‚m~liŽ|~ƒ”‚}Šˆkuqgic[cgso`altahp‰zast^bc› n]6[°¶uj€‰~”‡wˆ™‡uŒŠwpm…‚†ty‰x‰}“ˆzsgvˆ}|–no…}hvynez‰…¥‡€‡‰}m}t~{Š—†’˜‰‹…Š|Šq|~†|i~mk€{yjzv‚‡r`w‚~rdrgvƒnu|†•’‚}‚€pwz|u~mWm}us‰€…v†t‚‰zwrmˆŽƒq}{|‡‡ymmhl‚un]hgurR\}O]r]O\spdVKtykXYYZbrva^]agdijfOZhNAad\`wa\umXXSubZeosXj_bhkgmlipw|“li„Š}|p~{‚zw€€‰‹„r{‡oqw„{‰„j~{nxywŠw}x€‚‡„~~zm„Œˆ˜£…„|v‹zkm…‰“z}{‚’€€~Š„prpcf^Yg_pp`ahpfjo‰tato[`djv{¿¨¥É¸r…„t•~z‰•„t’Ž‡rsp„z‚su†tˆw”‰yyqdw†y’hqƒufwvdj|„ˆž‚€ŽŽ}q~rƒx~Ž‚w•Œ”ˆ‚ˆ{‰Šlyz€uh{ilysizv€ƒ}h`wˆ}kjth{jv‚‘•|~~q|v|t~bUu{qr‡‚{p†‰wxoo‚‹}|w|zsŒ„€ugpglˆrp]hctoLfwM_oVTZtnbQOuybRXX]bqƒt\b]ieeckdR\qIDdb\dq^\xhUWVx^\fniWl^ajgennhpwz“niˆŒy~s{~y‚‚|v}ƒˆ†ƒpvƒsnw‚‚~ˆ‹”q€|xzz‹uƒx‚„z€uo}Š‹›žˆ~†{w†|hu‡’z€|‰†„v€gpn`e\XfYmsaaaqllh‰n`siX^cm€w©Ú©È‡ˆ³rŠyqv}‰‘{”‹€utu~vopm…t”†xul`yyˆeq‚ngun[m}“€y’’}wzl…tŠƒr•‰‘ˆ††{†muwmhwem|vmjwv|`bx†zhuvc~|hu‡Ž–}u€vr€z}m€YVr}os…}wkˆ†sxjt‚‚|y{wzq‰{rfsdm‹„ls[j`vfIooM\cXWVymbPSuwYQVX^ar…p]acmec^ocU^rGBf_^gi]Z{cRV]v[[gkaWk``nfflqhpvxtkŽvwx}wƒ{t}ƒˆˆƒoququ}…‰‹{wx„|}…‡xˆ|}}„€{~rvx‹ŽŸŒ‰{Šwuƒz^~‡šz‡„t†‡…w‰{bnm\b[[aUjtd`[hopg‡qaqfW\ck|Ê·º¢kno‹nr…s~†Œ{“…zytzutzjlvc„v’‚vog_|y‹ˆdq€jjqcXm{†œ‰ƒ‚r—“w}{m†o€‰Š†p–Žˆ†Œ„{yrrp~ghrcnxqjlqw}|y]ez€xiuyg‚whuˆŒŽ•}s‡jo~€xn}]Wp}ms~ˆz€nnŠpvfv~~€uzoyr…zxqeq`mŒkrXk_y]IplOXV_UV|kbOTvsRRTW^cu†j]akkfcZobYcpGAh]ag_\V|^OVfqZ[jh]Xha_rfjhqgqsv‡yn•Šu€{w~yƒ‡€us……Žƒpp{xwuy†…‡Œ†z|u‹~}†ƒ„‡~~}†|xvyv’”Ÿ~}‹nu€zd„ˆ˜†t’Šo…†‚zƒucnjY_[]]Uhse`YdrrgrakdWZ_ix¾®{Ÿ¸nbt‡iu}s{…ˆ{~€wxswozvejoa‡uŽsjb^}wy‹‚ep}gkk[Vox‹¤…p™’qwt€l€†r“‡Œˆ…‰…}yuspizajmamvjgkkywzw[g}|yfr~n…tfv††–€p‹gk{ƒtlub[nzjsz‰z€et†|mpgt}v|~pzjyyxvodk`m‰}lnVjaxVLlmPSPiNY}hbOUvlMQTU_hw„g^aqigaWi]]liJDjZbeWYUyZNWokY]le]Zec^tfleqfsptxp™…v€x|…‡}us‚‡•ƒnsy{{sr…†ˆ‰„y}v}„‰Ž„ƒz~‹ƒ{w|wvš˜zŠƒ‡jv~}m……•s‚q†‚‚€pflgX][\[Tepe_XcruivpdebW[[hpor€sŠefzjvwtt…†x‚…zwtvnkzpahkg†tƒmg^_|oz‰|hlwfjdVWspŽ§}„|v–s{q{xlyzƒu—{ˆ†„‡„}uqsmhu]mi`ludgfizo{rYgvuhpx‚wcx…‹}•‚oŒkm{qfse`kxfpuˆy|auƒuikqtyoxwr{e}}}vumcd`l†|mkVjcrTLklPMOpG^|faNVueKNTXalxf^gsje`WdXcr^LKkYdbVTUsVMYweZ_l`\[de_wgmboitoq~ut™x€x€†„z}v‚ƒ~˜…nrt|{uq……Ž‚z‹ut€}•Ž€…„|~Œ†z~v{£¦Šy‰†…lu||u„ƒ{o†tz…}‚ƒunjieV][[ZScne\Ybt{jhmh`aW^Zi€ikp€hmbi{zkuuup‡‚z~wvn{hjyj_enhw„geXavi}†ynioff]UXoh¨wz|Žxtn}mqtx~w”t†ƒ€†‰vjswhio\me^ns_gbjxh{m[mƒstjo~zxbw……z‘†sˆrpzrcqh[mudnq†zwar€ogixsqkwvsub‚y}utocbbl}|kkUibgTLnhPHRlEayfbMTr^JMUZfmy{f_mqjd]V`VooXKTiXg_YNUlTK]z_\_l]][be`zhlanpvnowuz˜}w€y€€‡†zyzƒ}“„qttzvt…ˆ~}‘ls•{‚Ÿ…‡}€~†‚€Š{u„¬Ÿzˆˆ„lr‚zv€‚uoˆo}€tŠ€jonedX_ZZZUbjg\Z_u‚i^ml\aW[\kert}jj^mxwhuxso‡|~~zvslzhiwg]dsgzw’€ccTdof„vvfhiaWVYhd¨owŠŽzpo{fwmyŠzvŽq„~€‡ndwtehi]lb^pp[g_muezh]t€nrkq{vvdu†Œ|‰ˆ€xru~taplXpqano‚zscq€k`lznihywspd„txxtoc`cms}jlTi^_ULucQGWbGcwfaLTqYKLXYimw{eenrfcZX^YwfUK]dXiXZIWeQIcx[]_m[^\bd^ij`ntxmonvƒ—yr€}‰Œ†~uv†x†Œ}tuu‚yzz‚ŒŽ}…‰jt–{Š}~…y€{~|†‰sq®Œ||‡~fqˆzt~}wsp†m|~mzcppbe]eVZYWcfk`]]t†hXpm[^XZ\l{bqwvmc\ntuivwrn†yzwootehte[gufvv‘y_]Seej‚s|abi\TX^cd¥iyt‚…xlmyfwl{ƒyt‡ry}y€iewm`ga_k`^ukYf]oobze[w|knopxytufsƒ“€‰ƒ‰zvor}raxcYnn`op€zseq€d^muhcfxzrlmsq{qpa]dmo}eiThYZUNy_RJZYHcudaJUnUJL[Wjms{dllucaYZ\bw\TLd^YjTWHYaNHjvX_an[[_bc]…ihbnxymojvynƒ~€‚’ˆ„vu‰tŒ†tqvvw}}~Œ“~px–ƒ}™’y€€xy~s‡„sp™¢{{‰–yeuˆzsywltply|p’s^poagblT[ZWidmf\\r‰eSrn[YXW`lvcjujj_[nusnutuk‡}|wonldipc[krdtvŽs\WTd`q~q\ac^SZa\d“Ÿerq…ƒskjxlnnyyzq€vs{z{dfvh^c[ah\_whWb^phawa[|vjjrnxttujr‚–„‡…vsjp|mfwW[ilaoqyseo~Z`ppa^io|kjr}povjp`Zdkm{agTgUXSQw\RPYRHdsb`GVlQIPZUklk|emora[ZXZmqXSPgXWiTUGZ\OIsuX`cncXaaa^Œjcemzyloivy†{k„}€…™|‚„y}ˆm†qovz}t‚‚}‹ƒƒ—tx‚”…Ÿ‰u€t‚p‡ƒvo¢—t{†Œ‡{fw‹on|pgxq{lsvsk^tobgfkS^\Vhbll[\qŒdNom\VWUgishctee^Zpvprvvzlˆ}}ˆwscdkoa\nmcsx‡kZTVbcw||p„\c^cT[`Zc—•cnp‚…‰rifyndruqzkytuo{v_gsd\_WbdYbueU_`mdaq]]~ohisqtquwmm…”ƒŠ|…qrgn|oqoRZeidprusbluUbqj[^nd{dku|pqqim_Xcijx^fUdUWQVoXQWTPHer_aFXkOIYTVnid|ilykbW\V\ueTRViRYgUTIZ[PNyw[_emjZba^^nbglzvnoivv~m„€~†—{‡Šk“ˆrgt€{u€ƒ~‰ŽŒ“s}Š‘…‡Ÿ†{†Œs€†s}‚un¤Œs‚Œwxnz`e}qgztymmqwƒgd|mdgghS`_Ug`lo\^nŽhMil`UVSogskfxef^Zrvot|ytnŠ{wœ{zkaelm^`njeqy~gZVX_lx{zoƒ^a]hVX`Xdœˆbkp†|vkjvl[upjyiurno|sYkn`Y^VcdYeqcT_biablZ`~kfltuomxwmi†€Š{ˆmqfp{lqlaX_gfnr€sr^ilSepdUbmaxaotztinkj_W`fhu\dVbVTOYgSO]OPHep]cGZjNJ`KXme_xioe`U^T^v\UR`gP^bUTK\ZQZvv]_fmhXca[^Žqchjxrsmgvsyƒs‚ƒ{ˆŽ~|ŠˆŽynŠtls‚tˆ…‡’„•z}Œˆ‘›„€|„rstwqn““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~~~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’’’’’’’’’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’”“““““““’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ?/1110/o‡„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDCGdhgggghMBCCDDCXhfgggfo„ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ-h†‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR4555549\`___`aA565554Ma____^j‚€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}zzz|}{|~}~}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‘‰‡‡ˆˆˆ‡ŽŒ‡‡‡‡‡†‰’“’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†…………†ˆ‰ˆ‰‰‰‰‡………………‡‰ˆˆˆˆˆ‰ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z||{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘“““““Ž‘’‘‰‡ŽŠ’“‘‹Ž‹…Š‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…‹…ˆ‡ŠŽˆ‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰ˆ………ˆ‰ŒŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰ŒŠŽˆ…‡‡ˆŒˆŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ~|vvx||{|}}}}}~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹Œ‹„‰ˆ…ŒˆŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz|||{}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒŠŽŒ‹ŒŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzyy{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{z{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz||||}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||~~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰‡‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†………………„„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰Ž‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{~~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““”””””””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}~~~~~}~~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••”””“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””“’“““’’’’““’““”••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘‘’“’“““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’‘’‘‘’’“ˆ…“‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘’‚‚’‘‘Žu†‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ˆp…|uˆŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒsoŠŠrx‡ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒwm{‚sx†ŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡sno„{uv€…ƒ„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\YXXWTPQRSRSMMJIFEHJGGHGGLNIgsuxz}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzoq{xy{|{xw{xuwttvuuvwtb^d_blqfhklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkiffggghhb]jl]ffgeccbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHIJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__ac_\_]`]^ZZjwmbnrjaYY_[XWSNMKKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{xvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSTPMJMNPROM[krlamurfQQSPPNNOMJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTtsuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMN]cokYisupSMOPPPONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKKFBFHUbhkopomlZLLNMNOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHECFGHMZghgrnnhfd`^^XLJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:;>IZ]Z\elnkommlkihkdSGEEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@:;><;;;=K[imnojomkilmfQGEDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnppsttsqrvxy}}}~}~~~€~~€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;:;;99:88;<979;:=HcosmnljkhUC>CFDBCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqtstrqtxxy}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<:79::979::78:99=J`stpgT?:;=@A@=;;><=<@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyz{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>><==?@===?C;==><:Bl|j?9;>=>?@@@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquutusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCDA?=>@A?@;[n@>DE?@AD_d;==;:=>AA@>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJGVppqssttuyz{||~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???BFD><<=@=8::mwI8;:=>A;Hd=<=<8:;??=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pprrrtuvz{}}|~~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC?>AAABA@YR<==ILFEuvN788:;>?WjA;<<::;>??==9:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC@CsyI;\ƒz|wW<=?==>EhtL:=>?==>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hloppqtuvy|||||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCEAGrykbƒ„ƒ‚ƒ€}^>@C@@=Js{Y:=AEABBFHC=<@DDA@?>=@A>>>?<>@DGE@>@A?@CFECBCC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{{{}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@Eot}‚‚ƒ~}„vMACE@?>Y{€]?CEIILQMMKECFGGEGEEEDECA?@>>BFJJGEEGFFJNNKJIGGHKLIGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@EEhs}|„~y…rCDEDCWu†‡‡~XGHJNiZOPNIGIHHIIHHGGHHECEEEFFHJJFEGIJMOOMMKJKJMNKIHGHHHGFEFFFDFHGEEHHFHGHFQnnpqruvy{{{z}}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJG`{€w„…ƒ„‰lAAVt‡‰‡‡‡ˆƒWHKVs^VQKHHHHDGGGGFHFHECDDFEDDHHCCCFIKKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrtwwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLLN[|‚‚ƒƒ…††ˆ„Vl„‡†††‡ˆˆ‡|PJYne^]TGCMF@@CCCCFFEB@>>@AA@BD?>?DFHDFGIJIJHHHGIIJJIHFJJJJIJIJJJFILLJJKKfopsrtvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKLKJTƒ„„‚‚…††„‚†…„„†††‡‡†ŠuJ`baaceSNX<<<>;:<AA@><998<<=;>;8;?AB@ACCB@AADDBCFHIHHHLMLGIJMMNMJJKKJLMSlpqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHHJIIe…„„„‚ƒ‚ƒƒ„……†‡ˆˆˆˆ‰ŒŽqhhgegifhF68896479;<:8567789787588;;;=@;999=<>;<=ACEHJMLLGIGORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@CGIIh†„„~ƒƒƒ‚ƒ„†‰ŠŒŒ‹‹‰Š‹ŒŒxmlihijY5655873568:876565676767:67889:7578979776:<@GFIFIFEFOSRSSROPPRTepqsttvy{{{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@6788=:=ECBe…ƒ€‚ƒƒƒƒƒ†‰‹Š‰‰ŠŠŠŠ‹ŠŠ‹‰vmmmllU785688557699776765:9:::;798987669:98868589;A=>>BA?AKLOQPQOOORWkqrttuvz{{{}}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897;B:=q„€ƒ„„„„…†‰ŠŠˆ‡‡ˆˆŠŠŒ‹Š‹ˆrnoope@>:;;<9:;9:;::9;:9===>;;<<:>;9;;<;<;9:<8::::999<?<<ABDIJMKIKLWorsusvx{{{|{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<:89989:::;?>H~„‚‚„………†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹ŠŒŽ‚rrqqcGFCBAB>@CA@>=>>@???@?@==?B>@A?@?=@@@>?A<><;:;:9;?=;<==AACABCAXpqtttvz{{|}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::<=:;;==?@BR‚‚‚„…„…„†‰‰ˆˆ†††‡ˆ‰Š‹‹‹‹Œ~rsrSKJKHHHEFHGECA@BECCABCB?@DHECECEDAFEFDEFD@B><@>=?@>?>?>?>>:;=<`qrttuwzzz}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>???=A@CDFW„‚ƒ„……††ˆ‰‰ˆ‡†††‡‰‰Š‹ŒŒŒŒŒŒ‹{zt^g]PKKKIJJJIFDDGHGDCEFDBHIKGHGFHGEKIKIJKJCFCCDBAACBDCCDDCA=;=@hpsttwwyx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLK@BBA98<>;<;>@?A>BBGGIY„‚ƒ……†‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŽ‰{x{ogUMLMJJKHKGDGIHIEEHFFELLMIJGGHIJNMOLLNKHFGGEECFFFFDEHHFCA?@Llptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?EGG=<@@88<;;=:>@>?@CFIIP_ƒ…„…††‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŽ‚xrURROMNKIIFJIEKIGKJIJGGGKLNLLHHIJMQNPNMOKIGIJHIDIHHFFGGIGCBACTnpuwwyzxyz{||}~~~~}~}~~~~~€€€€€€€€€€€€€€TDAABGHB?8?@9:<8=>;=A>?ADHJLUqƒ„„„„…†‡ˆˆˆˆˆ‡†ˆˆˆˆ‰‰ŒŒ‹ŒŒŒŒŒŒŒs[VTQQOLKHGCHJHMLGKOLKJJLMLOPNHIKLOQQPQOOJHJJLJLFGHGFFIFEEBABB\orwxyzyyyzz{{~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<9@>>@BGGAGKLPVy…ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹ŠŒŒŒŒŒŒ|\[WVWUQNLKEFGMPOPWUQPOQSRMSTOMSLPSUVRSRPLJMMMKNGGJFFHJEDEEBECcpuyyzzz{z{zz|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?==B@BBGVNFNPPTX{†ƒ……„…‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒ‹‹l]ZmbGUSRQK;;STS`u]UVTVYYRXXRZfPUWZ]RTWQOMRQPPQKKKHHJHEFIIIHIirvyxyxz{{|z{|}|}€~}}}}}}~€€€€€€€€€~~SHJIHGGFE??AAEACGEDELXRMTUVXZ|†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ~aŠ‹‹‡o_gX<YZYTQ?@WVY\d`VYbr]]W]ZVEQYZ[Y_TYgRVVXUTVTOOMJLJIILMKOMSosvxyxwyyz{z{|}{~~}~}}}~}~€€€€€€€€€€~~~VJJIHGEDDBA?HMIMPKIKPTSSXZZ\\x…„…………†‡‡‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~‹‰‹Œ{qrZ]]\SUSWWU[ZuƒYU}a\X]_WIV]][[_YHYXY[]XXYWRQMPQMMOSQQURassvwwvxxxz{z|}}}~}~}}}~~€€€€€€€€€€€xy}YNKIIHFBD@A:PQQWXPPOQSTTXXYZ[n‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡„‹€h[\]ZUWUXSRXVc–€RerXZW_hP`f[[X\gaGOZhg][\]]WROSPPRVVVVYZnrtwvvuxxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZ[RSQPRRRUSVTW_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†~€}_SWZVSVTRRMPMLfz[]TYUV]ZLTZUST^ZXWWWzkX[\\^TQQPINOWVX[Zdprvvttvxyy{{|}}}~}}}~}}~€€€~~zxwvsu{€€tk~kry^[VUSROKFCDAM^ƒlVRSNOQOQURSRRUcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡zorYLMPPMOLJKEFIFC?TdURQQNKQTQMOYRMNQSUUMQSRPOMLHCIHRTUZ\lquuusswzz{{|}{}}}~}}}~}~}}~~€~{vsw}~~du}iqt_d]^\YUPLILIal’tPQSNQRQR[RSRQRUTbs{|€‚}{{€ƒ‚…†‡‚†††„†…†v`^NE@DDDDCAEQCEAC>CIGV@HNLG]iPHFNFDEFIGHBDHGIKGDBAD@OQMRdrtvustuz|{{{{||}|{~}}}~~€€€||}€€€}vt{mh|gnqfiedb\XSQPURsWe[OONLQSQUYSUQQTSOV`klrv{{xytrnstsyx~ƒ€ƒƒ‚€‚€‚‚lNHAA<<>@A@@?kQK`EFHIEB?GLNGMQUIAE??<=<==?=?ACC@?==B>JNGUnutustvx{|{||||}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QRZ\Y^JJPQNKLQRQTVUWQQWUPX[b]agmmlokg`nrjmlqu{z}{xz||xwxeDBAB=;CCBBDB\]O{NOONKLMOOQLKMWMHG@A<977599=;;;8:8:?<BH?\stuuuvwy|||}||}}}~|}}}}~}xuvz{zwyxuw{|yxuywcqhipmnmmhf^OP_\ZIHPRQOMPQNQRTVXSSYTOYZ[WY]^^_e`]^qvk^`gkwooljonnlfbYHGHHCBGIFFEDMRPaWSXQPSSRU[OOQVPMIDF>:96587979:365795<C>essvwwyy{}}||{|}~~~{}~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`VW^ZXMKTTSPQUOLRSTXXTTYRMWYZVXXVXY]WWXhsk]Vaskba_^da_^YUQNOOMIHJLJIFCQPS[WTTNQSYS\eUOSTRNKIHC?A999897885757859:Gmrtwxy{{|~}}|{}|~~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPXVVSTVOOUVXXYSUTLKTVUUUWPSUWTUR]n^RNZ_[VY;DVXT[fJLPSRONMNNNLJFQPUYSTOJOOUST\VRUSROMLIHHF?><:787659967675Wopswyz{|}}}}|}}|~}}y}}|~~~}||}}~}|rvqxxrvuqqnppopuvtnjddjppqrpofedc\]RTZVWUTWTRXXYYYSUOJGOPOOMRJPPOPNNOTLMIPOSTU2=XMI@Q=caQSQPNPQPNNMQNTRPSMILKORPRRSTQROLMKLLHCBA=::876;B5566:doqtwx{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqptuvcjgeWhtrrqniihpVVTUXUWURWVUZYXWUQSFEAFGGHFJDHJIGEHLHKHFLMPMG/E_R>3?>joaSRQ@GTQPQPQNQOQPLJLLOPNNPQQNPOJLMMKGEEDB;=<<9=G6677Dmptuy{{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknaePSTRSTOWVVYYVQQQO@=;=?ABAC@BEDA@GHGHEFHJMLEGCORC8ENS]gTQSAGUPOQQPNMNMKLKLNOOQLOOMHLLIKKLKGFFED<AA>;@E;<89Sprtx{z{}{|{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLOOMQSLTUTXWULLKI<987;>@><=A@B=>EHGCEFIGJJ@FAA@FHEJOHQRb\QPROSOOPLLOMLMMNON[WKMQOGIHCHJLLKFFFE?BC><BG?B?Adpswzzz{|{zzw{wy~~|{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCD=9779?B>;?B@@>@DIECGGIGIEBB?>=CBAGIDMObeQMONWKLNKLMMMLLONSdNJLRHIIEAHJLMNJGIGBAB@?EFEHDKnovyyy{{z|zwsxtx||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGMMJMPMPOHJD?A=98::?B?<ABAADEGKFCHIGGHCC?B??@A>DECKNRTLJIMTFIIJLJKLIJMMOPRPJGCLGCBJILMONIJIGCCCDHJMLIYrmwyxz{zy|vrpurtxyvxjqnjllnttmtu{stxronqovsnporpopstyjN`gsjt|ygosqiqhdqGKDGHHGJKIJKDFB=>=99:;@B?=ABCCGFIKJDIIFGGCC;A@B>@@BECIMPHHKGHKDHJLMHJLHIJLKM]RHHDNFACJJMLPMKMJKFGGJNNQNLbmivvwzy{z}rmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoiktgdoFKDFEGEFFGEGBC@><=9:::@C@>ACDEIEIJLFIIGFFDB;ACC>@CDCDGLNHKNHDHEILNMHILGFGIILNKIGENHBFMKMLOMMNMKHHIORRSNRfffqosxu{z|lhjnekqlspfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGIDFFECCCE@DB>?>:;;=:=>CA>ACEFJFIHLHGGGFEC@=DEB>ACCCDGHIGMPJFFGKNOKFHIFEDEIJHJIFHOKCIMKOMONOPNJJILRUUROWd`amgproryzgehhdilgqlflmgiklslpvutpnvrosrsutqssutsuvvvyvutwljuumrvqlnlerLHEEHCBABD=BA>A=::=?;=>@B>@BDGJEIFIHGFGECBAAFFCBBBDEDGGIFLQLIOJJMLIGHEGFDCIIHKJGKRMBNNMPNOOMNOKKKOUWVUSX_^\iaminhrsbeffdhhfnjfmmhkkmriqvtsqmvnoqrswsrstuvvvvwvwwvtwujsunutsqrjksMGHFHBBADE<A@@C<8:=>9?<?B@@@DFHEHFFHGFFDCECDIECGEBEGEFGGEJMKHQMJKHHIEFHHECIIIKMKOSNDQRPPQNOMNPMLMSWVXXUX]Z]d`hbjigk_eefcgggkggkmkmlprhttursnvoqprtxqssuvu‚‘yvvtxuuwxmouorsuqqinyMHGHHBBBFE<?BBD<7:>=:>:@B>??CEFDFDEHFDECDEFGJEEJGCGHFHGECFJJGNKLKHJLFIIKHEKKLMNORTOHSUSPROQMNQNMPWZVZYVZ]YXa`a`^hec`dfhgjhhifhnllnmqpiuuxrrpupppruvpusuwu{~}xvtwvvvxplupmstnprrxNHHGIDBCHE<@EBE=89>>=<<AB<?>AAFCFCDIEDEEFGGGIFGKHDIHGIGFDHKIGKHMKJKLHLKMKJNKONORUVOKUWSPSQRLOQPOTYZY\ZY[^^]`c^\ackb`dggr…hgifjmnponsrjtuxrsstrnpqvrquruus~yŽ}uuvvvvxrhuqkrtlqvptLIKIKFBEGE<@GCD@:<?@?>?BA<@>AAFCEEEIEFEGFHHFHHIKJFJHHKHFFLIHHJGLLMLLIMKNMMPLPPQUVWOKVVUSSQRLORRPV[[]^[\^__a`ad]c`ef`ehjdssfjggkorqossnswwquvtsmoruorspurvrtvuuuwvuwtgtrkqrkrvnvJKLJLGCEDE<@FDDC;??B@@@CA?B?ACHCFFGIFIFGDIHGIHJLHHJJILJFJKHIKJGKKMMJJMMNNNPKOQRTXVMNTVTRRQPMNTSRW[]^_]]`_`aa`acebdhbdijgv‹ljigmosqpqppryvruutsmmssmqrotutrpswtuuwvuuteqskpqjrvnwKLLLMGDCAD<?EEEC=AACBBCDACDAAEGCHHIHGJGCHIGHJFILHIJMKNLGKIHKKNQKRQMSMKNNOPPOTOWXX[NSPW\ZRWPNTUTTXZ_bb_da^`b^`eaacingbihhnxvlhimosrpqrrrvtsusssnksqmprotvrqquvuswywutucmtkopjqtowLNLLLGEA@D>>DEFC@DBEDDFBCEGCCIFCHJKIIKGDKJGHJIIKHJJNLOKILHJLKZfJd\KlSHON_nUks[qpbwcSPavuhucav`Xnqbdvinzf[lt`ljT_wvijgifglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqrqyLNJJJFC?@B?=DEFDCDCFEDFBFFGDEKFFJMLKLLGGMIGJKHKKIKKNLMLLLILML[sbdp^lmUMNfs]ffqlntgpi_aYnnbppbkjjfoqtetno\ougpMJqyvka`keemxlkvmnpsrprqpqrqrrrtrmmsnnoprutqsstuuutwxvutbmukpplrrqzKLIHGED?AB@>CFGBFCFEFEDCHHHDEKHGLNNLMMFJNHJKJILJJJKLMNNMMJMMN[roonpplkMPQlWMibtrpamnu\YlP\nmZqmkomxxtsip]_rkqjUuyxoc^kfbgppjjopprspqpqqrrqqrrtlmrmnnorutqtrtuutuuzvutenukpolsrryIKGGEEEBBB>@@FGBGDIFEEBFIHIEHLJGMMOLMNGLMILKIJMIKJJKOPONMLNNL\hdu]lqWlNPQmTYk^klvaldsSecNmYl\tpkilxjwuhp]^rkhWbcw|oc`ggadiuyknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtvHLFIDEECAB=BACGDHGLHECCHJIHFJLLFNLLSRLGLLHNJIHNHJJIHNOMNLJNMJZsppoqqmlOQRnYrkgooqqomt]nXat_nopoqronusttj[^tcwxrjnzhaacfbbimtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyxtukoumtonssvsHKHIBEEEAA>DDBGDHIMIFCFJLJGFKNLFOJKWRKGKJJNIHJLIKJHHKMMMMIKKKSkc[i^_icrrZ_Yjn_eeUk_c[aaQ`lh]j\niid[pfdp]Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunwqrvtwrGGFIDECFA@BFEDGBHJLHFDGKLIEFJOLIPIL[QJEHHKMIHJJKKIHIGKKKLGHKKLMMLJKMNT[\TPTLPONOOVQOOQNOQJJOPQdqiTYW\[\VY[]X]\\cfaaebcf__fkmhmtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyxxuvqruovrtsuusGCEGFEAEC@DHDFGCIKLHFDGKLIEGIPKLOKLWLIEEHIJHIKIMJHFGGIGHIEFLIJLOMJP\W^P\[`^MXYS\\b^MXZMXaRKYaZR_d\aX[ddVVX\YZX\VY\]b^d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtOBCDLMBDCBEIEGGFKJKHEEIJKFEHHPKMMJMRIGEAHFJIKLJLJHFDIFDFGEFKHCJNLLU_Y`X`a[`TXYT^^Z_RY\P^\YN_\^SZ^c^Z]`c`Y_c[`^[TXWY^]cbcacehekrpoppnow††……†‚{€……††††…uqprrsvyyzyyxxxwryvxrqxvtvaSJJMIECBCGHFHGHKJJIDFKKKEFIJNKNKHLNGHE>GGLIKLKKKIGDHDCDEAFJE@JLJO[cY_^a_RTRW_`\]Y^QY\MV_WKQY[PZ_aa]^ca`bbbcceZQXUU\Y]c`__cdbhomnllllu…„ƒyu|„………††……††ƒ}wrrtxyyyy~}yuyvvrnzwvxXQKFCGEBEGIFGHHFFIGHGHKILDDKKNMLKHKJHIF?GGNKKKMKKKIFGCD@DAHIC@IJHP]aZ[d]_TQRX]\\\_ZKW\LR\YIM^QO\_accccb\dcbdcfXQUTQ[WZ`_^^aa_dlkmjjlnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMC@IFDFKJFFFHGGIGFFILJNFDKKMNJLIKJHHFBHHQMKKOMJKIGGED?ECIIBBGFET]Y^X_Y_[]UXXO]]QKJV^X^[]UY`RQ__bb``bb`cbaddbXOQQQZR[]]]]^__dhgljnnp{{|~{€‚ƒ„…„…………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKCAHFDGMRHCQJEGHHEFKJMPEFIJKNLLIKLIHGDHKQOMMPLLJKHICDAEDIGCBGFDWUE\T]SV_XOTUNZZMIJT`a[_X^^a]OYa\``_bcb]abW`_TPOOOWQ\[[\\^_bffeleoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDFFHDIRbPCV^IGGHDFMKPPEIIJKNLKKLKIJGEJNQQNOOMNLMHKADACDGECBEGBMHBKKOONLFMFGIJHGLKMOPILOPOSOLPSRUZYWYXXdWOSTPPNMOTSZXXZ]\`adecgcklpsryy{z„„„…„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKM]LGGXLGHJHGMLQQHKKKKNMUNOJJKGGKPSSNPONNNNGKF`ED_LEfdEN\I^[rmOMUmYLDP`UkWgJ]WU^DLQULLSVQRTXWTXUT\UPfZhhdXRjRVUT[\[``abab`fhfnkhrz|}~„„„„ƒƒƒ}|zr{z{‚€ƒ„„……„…€ƒƒ~z{LIFGFHEEKOSIJF`THIOJIOMRQLMLLORUROOIKMGHMQ[YOPPNOOOIJQQI|YYrtYQmHqnoaVPqqsPCksmqspSo_[nX]V\XUkhU]VcZ`Y[_VVXjtuu^_v^Wa[[f[_`a`a]`agmpl`pwtx‚ƒƒ‚}€vxzlv~tx}€|~€‚„|€ƒz~wwNJEHMNBDLLFIKERVLKNIKRXWQMOOMQTNOQOKKNGMPS[ZSQROPPPJHZx]TxehZSURvgtlpbnfjQrOMwmjrpsrqrpoo€]ezuxqqzq~s}ku}bRh|essorr{|o~xn€r_``baZ`_gknkblfgmw~€‚~{xw€tvzir~ns|~wx{~€ƒx|€u|||ssNKG`]GAEMMHJJGJPOMMJNV^YULQSNXZMSSRNKOHQRTYWVPTPPPQKHgxlcxrm[KNVypumubovPeeJfvqmwo€jfxxiWrQhzmijzz}lxzohoYvvjvup€_rf}ilx|o^__ba[]bdgiidgbcdllppstsssyqrxblugqy{srvy~suzn|}yxroNKSuNCBFPPHJKIKPOOOMPZ`ZWKTWPa^RVQYRLPISTVXWWOUPONRJKrouuquqdibWnLqp^FhyWvTLiy}x`y{sna]mocRhqunmypwlvttrln]t~zkmy|ktl|kpvux^__b^]_ddiggee^abiiijknokqomjpacfcowxompsy~nqpk{ztsomLL[VHGEGRPILMJKPQPPPPW\XUMUYUeXRRY^SLNITTVWYWOSNNNRIRmHiwK`dvvVXlOnl{sajgvULWkh}lmlx_Zpz{^`zscroxqhd}ir|^TLl`vukiu{zm~xk|p\^^b[^bddgeeebZccikkrsrvglihdg`akagsrlgmmr|kmhk{tmnkmOHKKHJHHQPLNOLKRRROSRWRVTPWZVVTTTa_PNMKTSTQVVNNLMOPKHQNPULKLSTTSTPVUQQNQQXYRNPUTXXX[[URSW[WXXZOSUWXXR^YW^VTPYRWWWWX^Zgr^[[Y\]_cZ_ccdfdccbZcbgfemnmueegcaf_]g`dlhfgkhpzhggjujhgilQIKLLMKJSQMQPOLVUTPTUXUYUQZ]VUTWUYWOOLMVTQNUSNOMLQPLJQQKQMKLPRUSQRSSIHLNOQRQQQTVRXW\WSRPRTUVSZQNSRXVTYVUZVTRUTTUWXV\Y^`]\ZZ\\_c[]bcdfdddaY`acabhhimbad^_c]Zd\bma^fefmsdigjkedcfhPJKLOOLMSPNSQQMXWUTUWWWZUS\`VWVYUXSPPJNWSPNUPNQNLSPMOUSNRNMOQUQUQRTUNKMOQTTRRQVWUYZ[YSURTWVVY[TPTUXUUZUWZVSRWVUW[XZ_\UX^\^][]aa^[bbcgfedbX_ab]`gdfea^_]]^ZZ`Z_g`^]]bhkagfhfd`bcbOLMLQQLOTOOSQOQ[YWWX[YXYV]jdVXYZWVSSOJNVTPOUPPPMMRRPRXTQQOMPTVOXRTUUONMQTVUTTRTWVZ]\ZVVQQVXV[[WQTVVVVYTXXVSRYWVZ^Y]_^U^\^`\[____ZbbdhgddbXa`b^^fcc`b]\\\\YZ[X[a[^]\_b__bdebd__`\PMNNRQMRROSTQOU\ZZW[[\XZ[dqmhd_[XVUWQLMVSMNROQROLQSRUZUSPPMQXWRWSSSXMOOQTXVUUSUYX[^][[VQNUVU[\WRSWVWXVTY[UTRZXW\^Z^_`Ua\aa]`b_\`]cacghdf`Yc`a__ed_`b[Z\[\YZYXW\Z\[`^_[^^a`^b\Y`[QNONVQPTQOTTSPW\\\X^\^V\^jqwy€c\[UUWQMOVSNQQORTRLRTTYZWUOROSXWTSURRZOPSRV[VWWSVZX\][[]VSMTUU\\WRUVVXYSUZ\USS]XZ]^\```Va[cb]ad^\bac_cfidf^[d`a``ce_b^YZ^[\[YXYWWZZZa\][]\\Z]`W[[ZPOOOYPUTRQWRTP[^^][`\`U\]hjr}slg\TWWQNRZSRQTRTUTKRWV[ZZSOSQVVVTOWRSZRTTTX]WXYSX]X^]YZ]TUNUVW^[YRUUYYYUWZ\VSW^Z]]`\bb]Y_[ea_dd^^cca^efidf^]da`aabd`b^XZ_[\[XXXWW[Y[`\[[\[XZ[^V^Y]QOORZPZTUVVSTT^^`^^b\`U]^bkytl}kZUYTPPS\TUTUTVYWLR[W][]ROUSXWWTPXRSWSVUU[]X[YUZ^X_^Y\YQWRYXY_[ZTUVZYZWXZ]WU[^]^`a_dc\^]]eabfd^^dc`\gdhedb_da`a`bb_`^WX^Z\\ZYYWV]Z]^ZY[\[WY\]VXW]SNPVYQ]UVYWWUX__aa`c]_T]_beeuzhWYYSUSV\XWWVVW]XOU]Z^]\TRWSWWUSTXRSVTXWX]^X][V]_X__X\VQXTYZZaY\VWX[Z[YYZ[YW^_`_cbadd\b\`fadfd^_dbb[fchecf`f__aaaa`_^VU]Y[\[Y[YY][[[XXY[YZZ]_]TY]UNSYVS\TVWYVV\`abc`c^_V[`da_zuohY[YUWTW[ZZ\YXY`WPU^\``\TTXPUWVTVWRSUWZZ[_^Z_\V__Z]^Y]URYWYY]bZ^WX[\[\[[Z\ZZ__``dbcddbdYafcffe^ab`c^bcidcg_g^abcaa`^_XT[ZZ[[X[XX\[Z[XWYXW\[[`]V]]SOVYVVZUXUXWX]_badad`^YYadb`lfh^[\ZVWXY\\]_[Y[bVTX^]ac\RVYPWWWWWVSUTX\\^``]`\Wa^[^[Z^XUXW[[_`\_XY\\]^_\[]Y[`a^`ecdeefbXcedhgd^c``ec\eidei_f]cbcaa`__[XY[YZZXYXW[[Z[WXZTY]\Z`\U^bNSWYVWYX[\XWY^`badada]^Yacb_a``^\\\WW[[]]__\Z]cYZX]`cd_RXYPWWXYYWVWV]]^`a`_b^Ya]]^Y\^YXUW[\`^]_ZZ^]^^a]\[Z\`b_becefefbZdffigb_c^afdZihbfice^bbca``_]]ZX\YYXXZXWZ[ZYWXUU[]]]``bbxKXW[YV\[\]ZW\]_`bdaba]`Xbcbacab][\[XW[\_]`_][`d]\X[becaR\ZOYXZ[[ZWZY`]`bb`ac_\b]_][^]YYTX]]_`_`\[^^`bc]\X\^`bbcedfdefd\efgifcab\cg`\ihbhied`baca_`_\]\Y\YXWXYXW\ZZWWXOXZ]acffrkJYW\ZZ_\[^\X][^_acbaa]b[bdb`bbb\[[ZWXiq`\`_]\ac_^YYcedaS_ZRYX\]][Z[[c`bbc`bda`c^`\^^^YXU[_^]ab`^[`abfc_]T]`acddfegeffe^efhhgdd`[fg^ahhbhhfc`b`cb___\][Z[YXXXVZV\[ZVVUMXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡„‚‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vvvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{zzzzzzz{{{|{{{{zzzzz{{|||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vvuvvvvuvvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{zzzzzzzz{{{{{{{{zzzzz{{||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚‚ƒ‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||vˆ‹‹‹‹‹‹}}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰ˆÌÓÒÒÒÓ՞†‰‰‰‰†³ÖÒÒÒÒÖº}~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}vŒƒ~~†“y1333332j‚€€€{­éääääèʉŒŒŒŒŠ”Ýæääåä祉ŒŒŒŒˆ¿éååååéÇ}~}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}vxxxxxxxwwwwwwwxyyyyyywopppppprrrrrrrwzyyzzz~ƒƒƒƒƒ„||||||}„…„„„„„~|||||{„„„„„…‚|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚ƒ‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vvvuuuyvvvz{x{xwvwzwyzz~|yyxxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{yyyyyyyz{{z{{{zzzzzzz{||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwvy}||zy|{xwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰Œ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwvz}}~}y{zxxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒ„„‚‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z{xwv{}|||z|yxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzyz}{|}z|xxxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyx{xz{yyxxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyyyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰…„ƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒƒ‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{{{|||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}||}}|||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}|}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚‚‚‚‚‚€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrsuuttssssrrqpoooopqsssrrrrstttsqqqrstttttttsstsssttttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqsttssrqqqponnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqrsssssrqqpponnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnnnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrrrsssrrqqppppoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnnnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpqqqsqrrqqo|‚oppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqqqp‡†prqps˜‚npppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqq}¡‚oro‹ž|oppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsqu‹‰ƒ‚…‡ƒƒ‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqrqu¡vqwŸœ}oqqqqpppppqqqpqpppqpppppppppppppppqqqpqqpppqppqqqqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrrq˜¨o‚£~pqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒƒyrssrrrsrrssssrstr“©¤yˆ¡ž|rsssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~€~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz~|~}|vvwwvuxzxxxxxwxyyŸ´©¤§©—}{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~|{|{{‰¯¦¡µª¬£~{zzxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}}}}}˜¥–¢² ™§“}€}}}€ƒ‚€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€€~€€€€€œœŽ ° Ÿ¢Ÿ€€€~~~€~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~€€€—šŽ˜±¡˜•œ…|~~~~~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽŒ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~€~~€~~Ÿ«¤—¤››–¡Ÿ†}}€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹Š‹‹Š‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚ƒ‚ƒƒ†ŽŸ²¨¢ ™¦¨¬¨ ™‘‡€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒŽ‘‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒƒƒ† ­±¦›š ›žœœ¡¤£”‡ƒƒ‚ƒƒƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒƒƒƒ‹—š—–˜ ›™š—‰†‡‡††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ„„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠˆ‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„ƒƒƒ…„‚†Ž”“—šœœ›”‰‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž““’ŽŽ‘’‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„„ƒ„ƒ„ˆ“”˜’‡ƒ‚………ƒ„„……ƒ‚€€€€„ƒƒ„……„‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘“’ŽŽ‘‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€‚ƒ‚‚‚€‡›ˆ‹‡‚‚‚€€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„„„„…„…†’“‘ŽŽŽŽ‰ˆ‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~€‚‚€„ƒ€€€€ƒˆŽ€‚ƒƒ€€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“‘Ž‰†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚‚ƒ„‚‚„„‚ƒ‰–ˆ„‚„‚‚Œ•‚‚‚„‚‚‚ƒƒ‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘‘Œ‡…ƒƒƒ‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒ€ƒ‚……„„ƒƒƒ‚„Ž™‹ƒ…„„„‚€‘™†‚‚‚„ƒƒ‚‚„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”“’“ŒŠ…„„ƒƒ‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~Œƒ~}|}ŒœŽ€‚‚‚„””Œ‚‚ƒ‚‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……„……„ƒƒ„ƒ„ƒ‚†””’“’Œˆƒ„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~–—‰€}}}}{˜Œ€ƒ€Ž”Œ‚‚‚ƒ‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“’Š†ƒ„ƒ„‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€•ŸŠ~~€}‡‹~„„ƒ„‚ƒƒ‚‰…Œ‚‚ƒƒ‚Š‚ƒƒ‚ƒƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†„…ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„‘¡ŠŒ„}†‰€~………„…‚}}}€ƒ„ƒƒ†˜‚ƒ„„„„…ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„……………„…††††…………………………††…†††…†††‡†…………ƒ„„„‡“““’’ŒŠˆ…†……‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…ƒ‰‘ƒ„‹…‚~}‡†ƒ€~~ƒ„ƒ™•’ˆ„…„……„„„………„…„†…………†††…†……†……‡†††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„„„‚‚‰~}~…~€€„…”›£«¢“‡…‡†‡††…†……†‡‡‡ˆ†‡‡†††‡‡‡††‡‡†††…ƒƒ„……†„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘”“‘‘‹‰ˆ…†…ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒ„„„ƒ€€€„„~~€€€€‰’¥¦¦¢“’ˆ‡ˆ‡ˆˆˆ††‡ˆ‰‰‰‰ˆ‡†‡‡‡‰ˆ†‡‡‡‡†‡…ƒƒ„…††………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†……„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡†…ƒƒ…„„ƒƒ€€Œ‰€‚‚€€~{y‰˜—œ¡ šŒˆ‰‰‰Š‹Šˆˆˆ‰‰‹‹ŠŠˆ‡‡ˆˆˆ‡‡ˆˆ‡‡†‡†„ƒƒ…‡‡‡†……„„ƒ……„……†„„„………†…†…ƒ‰”’‘ŽŠ†…†…ƒ‚‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡†„„…„ƒƒ‚€€€„„‚‚‚‚‚‚‚€~}}}}~}|{~’›™žœ“‡ˆ‰‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰††††‡…†ˆˆˆˆ††‡„ƒƒ„‡ˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚ƒ‚„ƒ„ƒŽ“’‹‰……†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„……‚€ƒ„‚ƒ‚‚‚ƒ~}}~~~~~~}~}}€•š™›š™’…†‡‡‡‡ˆ‡‡‰‡‡†ˆ‡†‰‰ƒƒ„ƒ…„„……†ˆˆ†…ƒ‚‚ƒ…‡†‡††„‚‚ƒ„‚ƒƒ„‚‚ƒƒ„ƒ„‘’ŽŽ‹‡„††„‚ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…‡ˆ‹Š†„†„‚††‚‚„„ƒƒƒƒ‚ƒ}|}€~~~}|}~|z€–™™˜•’‚‚„„†……ƒƒ…„„„„„„…„‚‚‚„„‚ƒƒ…†…„‚‚‚‚ƒƒ…„„„…„„†„ƒ„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰…„…„…‚ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€€„„ƒƒƒ‚‚€}}€€}~~}|}}{{z†——•–‚‚‚~‚ƒ‚‚‚‚ƒ„€€€‚‚€€€€‚ƒ‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†‹“‘‹ˆ……ƒƒ„€‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€ƒ‚~~~~}‚„„‚ƒ‚ƒ‚~}~€€€~}}}}~}|z|{Š––“„€€€€~}€~€€€€€~}}€~€€€€€€€‚€€‚ƒ€‚„ƒ†’ŽŠ‡‡†ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€ƒ„‚‚ƒ‚ƒ„…€€|}}~}}~€€}~}~€ƒƒƒ‚‚}}~€€€~}}}|{{{z{{|ŒŠ‹—Œ}~~~€~€€€~}~~}|~€~~€€€€€~€~€…’’Ž‹‹‡‰…„„‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~~}~€€~€„ƒ‚€~}~~€€€~}}}}{{|zzzzy~ŒŠ‘~€€~€€‚€|~~~~}|€~~~€~€€~~€~~~~~}}}}…“’ŽŒ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒ‚‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚‚‚€ƒƒƒ€€}}}~~~~}}}}}|||{zzzzy†Ž‡‚‚ƒ‚€€€€€€‚‚€~€~~~~~€€€€€€~€~~€}~~}{|†“‘Œ‹Š‡‡Šˆ††„„‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…‚ƒƒƒ…„„„„„ƒƒƒ„‚‚‚‚‚~~}}}~~€}}}}}}}}}|zzyyy{…„‚‚„ƒ‚ƒ€‚€‚ƒƒƒƒ‚€€€ƒ„‚€€€€€‚‚€€€€€€~~||‰”Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…„„…„…†…†††…†…ƒƒƒ‚‚€}}}}}}~~}}}}}}|}}|{yyyyx|‚ƒ„…ƒ„ƒ‚‚ƒ…‡‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚‚ƒ„ƒ‚ƒ‚‚‚€€€€€~Ž“Œ‡ˆ‡ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€~}}}~~~€ƒ„‡‡„†††…††‡‡†‡‡ˆ‡‡‡†}€€€‚~}}}}}}}}}}}}||~~~|{yxxyyz‚‚ƒ‹„ƒ„„„——ƒƒ„}~‚‚‚ƒ†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ…„„…ƒƒ„ƒ‚ƒƒ‚‚‚‚ƒƒ‚‚‘‹ˆˆ‡‰‡††„†…„„„ƒ‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€€~}~~€‚………‡†‡‡‡‡‡ˆ†‡‡‡‡†‡…~}}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yyy|€€}‡”ƒƒƒ„„”“€~~„‹€€€„†‰…„‚‚……‹ƒ‚……††„ƒ……ƒ„„ƒƒ„ƒ„„„ˆ’Œ‰ˆˆ‰‡‡‡…†…„„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„ƒ…„~}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|yzz{|}‚‚ƒ‚€~}{ˆ‘||Ž–}‚†Š…ƒƒ„ƒ‚ƒ‰}ƒ„……ƒ…††„……ƒ„……†„„Ž‘ŒŠŠŒ‰ˆ‰‡………ƒ„ƒ‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚€‚€~}}||}}|||}||}|}}}|||{‹‘—Œz{|zyz{|yy}~€}{|~}‚•‘„ˆ}|~‚„||‚„ƒ‡ƒ}‚€‚‚€ƒƒ„„„„„‚„ƒ„…„‘‘Ž‹ŒŒŽŠ‰‰………ƒƒƒ‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚ƒ…ƒƒ…………ƒƒƒ„‚‚ƒ‚ƒ‚‚€€~~}}}||||||||||||||}|||~~Š‚{z{zxz{{|}{~~~~~~}|€€~†~}‚~~€‚||€‚€€~|{Š‚}€~€€‚€‚€€€€‹”ŒŒŽŽˆˆ‡………„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ…„††…„€†”ˆ€‚€~~~€|||||||||||||}|||||}|yz{{xxy{{z|‚€€}€}€‚‚€€€‚‘€€~€~~~€}}}{}}}|}||}€€€~€~~”’ŒŽŠ…††…„„…ƒ‚ƒ‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚‚„†‡††~ˆ•Š~€€€€~€~~~|{||||||||||}}|{||||{|||zzy{|z}…ƒƒ€~€€~…‚~€~~€…†‚€~~ƒ†}|~€€~}}}}~{|}€}~Œ‘ŽŽ‡„††…„„ƒƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}€‚„††……~€€€~~}€€€}}||}~}||}}}}}|~|}|{}||z{z|}}†…ƒ€€€}~}~~‹„‡~}||~‚‚}}}}|{}|~„ƒ€~~~~}|~€}~€~~„’ŒŒŠ†„…„„ƒƒƒƒ‚ƒ‚ƒ‚ƒ‚€€}|||}~{{}w~vx~}|}|}~~‚ƒ€z~~|~~€~~~€€€€~~~~~~}~~}|~}~}}}{|||{{z}~€€ƒƒ‚~|||}||ƒ~Œ~|{{}~}~~}{{{}|{{{{€†„‚„ƒ‚€~‚‚‚‚‚€‹Œ‹Šˆ„„„ƒƒƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€€€}€~~~~|‚}~}}}{{}}|z||}‚€€€}}}|||||}|~{~{{{|||}|{{{{||zz}z~‚~‚„„ƒ‚…†……††‡…„‘‹Š‹‡‡…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}{€~~€~~€‚€~~€€~}ƒ||}}|}}}}{|~~~~~||}||}|~~{|{||||}|}|~|}|{{{|y{|{{}z}~~€€ƒ‡‰‰‰ŠˆŠ‰…ˆ’‰Š‡……ƒ‚‚ƒƒ„ƒ‚‚‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€€~~~~€€€€ƒ‚€€€€€€€€~|z|}}~}}~~Œ†}}~{{ƒƒ}}}|}|}}}}}~|}{}|}}~}~}}}}|{{z|{||{z{{zzz{~~ƒ…ˆ‡ˆŠ‹‹‹‰Œ‘ŽŠ‰†…„‚‚‚‚ƒƒƒƒ‚‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„„€€€€‚~}~€~{~’Œ|}Š€Œ~~}}}~~}~}|||~}}}|}}}~}}~~|{{{||}|{z{{yzzyy{~ƒƒ„‡‰Šˆ‰ŽŽŒ‰‰…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€~{zy{}}x|zr}{{}||~~}}€€€‚…ƒ„‚‚‚‚€€ƒ‚€}~€~|‰‚~ƒ‘„„ƒ~}|‡}}~}}|~|}}|}}~~}~|}|{|}~||{|}zzyyyyz{~~€ƒ‡„ˆŽ‹Š‡…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{}}}}}zx‚€‚‚€€€€‚‚‚‚……„‚‚‚€‚„~€}~~}~€€}~€„€~~}~}}Š…}~}~~€~}}||~~~}€}}}|}||{|}{{{zzz{{|}~~€ƒ€‰Ž‹Œˆ………„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv}€ƒ‚‚‚‚‚ƒƒƒ‚…†„ƒ€€€ƒ€„~~€}~€~}~~€€~€€}€~€~|}}|~~~~€}‚€|}€€}{}}}||||}{{{|{||}}|ŠŠ‰‰††……„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€‚€€€ƒ€~~€}€}}~~€€‚€€€€€}€€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{}~|}|||{|{|~Š‡‡…†ˆ…„…„‚‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz~}yxtt€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚~~~~€}~€}}}~€€€€€€~~€€€€~}}}~}~~}}„€~}}}~}~~}~|{|z|{z€ˆƒ„„…„„„…ƒ‚‚€€‚‚ƒ‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xyuu}‚ƒƒƒƒƒ…„…ƒƒƒ„ƒƒ„„ƒ€€€€~}}~~~~~€}}|}}~€€€€‚€€€ƒ‚€€~€€€€~~~~~}~~……€ƒ~€~€~}{z{z|{z‚…€ƒ‚‚‚‚‚ƒ€€‚€€‚‚ƒ‚ƒ„ƒ„‚„‚‚‚‚€~€~}~~~~}~}}z{|…„{{sy{|pwuvwyutz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€€}}}~}~~}~|}}~€€€€€ƒ‚€~€€€€€€€‚‚‚€ƒ‚ƒ‚€€|z|z|{|‚€‚€‚‚€~‚‚ƒƒƒ‚„‚„‚‚€~€€}~~}}}~}}{{z€x|vyz|qtxwvxury……‚„„‚„……†„„‚„ƒƒ€€€€|}}~€}~~}|~~~€~€ƒ‚ƒ€€‚€€€€€€€€‚ƒ€„€}ƒ„€€‚}z{{||}€}€|}}€€~}}~‚‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxzzruyyvwwsu†…ƒ……‚„„…„„„ƒ‚ƒ€~~€~€}}}~€~€~~}|€€|~€~€‚ƒ€€ƒ„‚€€€€€ƒƒ€ƒ€~‚ƒ„€€‚‚‚„‚~{{|||}~}~}z~}}x~|||~~~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„……‚„„…ƒƒƒƒƒ€}~}}}€~~~}}€€~|~~~‚‚ƒ‡…~~€€€€€€€‚‚€€~€‚‚ƒƒ‚ƒƒ…ƒ}}}|{||yz{z}y{yx~{|{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst…„„†ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€}€€~€}~}~€€|€€€~}~~€}€€ƒƒƒ~}~~€€€‚€~€~€‚‚€ƒ‚„„†„€~~||||zyvyyzyvyv~|{{{~}{}€~}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…„ƒƒƒƒƒ‚‚ƒ‚ƒ‚~~€}}}}~€€€|€€€€|€~~}~~‚‚~~}~~~~€}€€€~~}~~€‚‚‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{{{…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvpxyrx…………ƒ„„ƒ‚„‚‚€‚€~~~~€~}~|~€€€€€€|€~€€€€}€~~~}}~€€~~~~}}~~~|~€~~~‚~~€€~ƒ‚ƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}|{|z{}zzx{|zz{xtxuqrtpxxqy„………ƒ„ƒ‚ƒƒ‚‚‚€‚€€€€}~~€}|~|€€€€€€|€€~€}~~}}|€€€€€~~~~}|~~|}€~}~€‚~€€~‚„‚‚ƒ……‚‚~}|{{||yw{ywxwwx{{z{|…‰}{zwz|}}||}}}~|}~~}}}|}~~}}||{zz|{{zyzz{zxswuqqsoxwq{…†……ƒ…‚ƒƒ‚‚€‚€€€~~}|~~€‚€€}~€~€€}}|}€€€€~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{||{zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚€€}}~€€‚‚}~~~€€‚€€~|~|€€€€€~}~~€€‚€€€€€€€„‚‚€~|}~~z}„~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚‚€€€€€€~}€€‚‚‚€~€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€€‚€€~}~{’z|}|{}y{zzxzxy|||}|||||||}}}||}|~}~~~}|z||{|}{yzzzyytuuooqpwst}…†ƒƒ‚ƒ‚€€‚ƒ‚€‚‚€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€€‚‚€€€}~~|†‰||~{{~yz{z{wwy{|{}||||{}|}}}}|}|~~~~|z|}{|}{yz{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚€‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€€‚‚‚€€€€€€}~€}€ƒ‚{~~{|}{z||{‡zxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ‚„„€~‚€€€€‚~€€‚€€€€€€€~}€~€€€€€€€€€€€€€€€€~}~}~~{}|}{|}xxuxxy{||}{||||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒ„ƒƒ‚‚‚ƒ€€‚„ƒƒ„ƒ‚‚‚€€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€€€€€€€€€€€€€€€€€€€€€€€€‚ƒ‚‚€‚‚€€€‡~~|{}|{}xwvyyz|||||{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚‚„„€€ƒ†ƒƒ„‚„€„ƒ‚‚€€‚‚„‚„‚€€ƒ‚€€€ƒ€€ƒ‚~‚€€~€€€€€€€‚‚‚ƒ‚‚ƒƒƒ‚€€„}}}|}z}{zvzxy{{|}}{|}}}}~€€€€€€ƒƒ€|~~~}yy{zzzysrtowqwysw{…‚‚‚‚ƒ„‚ƒ„ƒ€€ƒƒ†ƒƒƒ‚‚„„ƒƒ€€‚ƒ‚‚‚~€€€‚‚‚‚‚€€€€‚‚„€~ƒ€ƒ‚€€‚ƒ‚€‚ƒ‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ‚€‚€}€|z|{{w|yyy{z}~}||||}~~€€€€„„€}€~{{{z{ztpxqytvxtv{„‚ƒ‚ƒƒ„‚„ƒƒ‚‚„†„‚ƒ‚ƒ„„ƒƒ€ƒ‚‚‚‚‚‚€€€‚‚‚‚‚€ƒ‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚‚„ƒƒ„€‚„‚ƒ‚‚‚‚ƒƒ„ƒ„ƒ„„„…ƒ„‚ƒ‚ƒ€€~||€}|x|yzyz|}|{||}}}||€€€€€‚€€€€€{{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„‚ƒ………ƒƒ‚ƒ„‚„…‚‚‚ƒƒ‚‚€€~€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€ƒ‚€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒƒƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€€{}~|y|zzz}||~z||}}|z{~~~€€€€€€‚€€}}||}|vrvxxvtvu}‡‡ƒ‚„…ƒƒ„…„‚„†„„ƒ‚ƒ„„ƒ…ƒ‚‚‚ƒƒƒ‚€‚€}€€‚ƒ‚‚‚‚„‚€‚‚ƒƒ‚‚€€‚ƒ‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz|}€}||z|~}|}}~~€€€€~~€€€€~|}~~~}||xvvw„‡ƒ‚ƒ†ƒƒ„†„‚…†…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„ƒ‚‚ƒƒ‚ƒ‚‚ƒ‚‚ƒ„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒƒ„„„„„…„ƒƒ„…„…„ƒ‚€}‚€}||{||€}}~€~~}~|||}}~~~€~}~€~~}~}~}}~~€|}€‚‚ƒƒ†ƒ„ƒ†„‚ˆ†…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~‚ƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒƒ‚‚ƒƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒƒ‚ƒƒ‚„ƒƒƒ„„ƒ„„…„„„…………„ƒƒƒ~„€}}||||~~}}{|}}}}}~~€€€}|~‚~~~~}}€€€€„„ƒƒƒ…ƒ„ƒ…~‚Š‹……„ƒ‚„…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ„ƒ„„…„……‡‡†‡…„„…„ƒ~~|~~}€~||~|z|}}}}}~~~€}}|€€~~~~~‚€……„ƒ„„‚„ƒ†€‚„…‹‰„„„„……‚‡††„„„„…„„„„ƒ„ƒ‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ„€}uz„~„„‚ƒ‚‚ƒ„ƒ„„…ƒ„…†„…†}„y}~ƒ{…ƒ€„ƒ€}~~~ƒ}{}~€~}|||}}}}|}}~€‚}}|€€€€‚ƒƒ‚‚†„„„…„ƒ„…ƒ„…„Šˆ………ƒ……„†††ƒ„„………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†spurstƒv{}u‚ƒ€‚vy…€ƒ€„…„‚……‚hzrss|€r„~ƒƒ}}~~‚ƒ‚|}€}}||||}|||~}~}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ…„†ˆ††…ƒ†††‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„„†}p{pyv~ƒ‚nypus|vyy†r„ƒpvxqvtturstvi€nrotvnulwmzsn€‡ym}rsvsvmnwlpylu}~|~€}€}€€}}||}}|}~}€€€~|~€€€€€€€‚ƒ‚‚ƒ…‡††€‚…ƒƒ…‡†ƒ………†‡‡„ƒ††ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoolw}x†pqzprtfu~n{ysoy€}~€{~}~€€~~€€€~~~~€~}€}€€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„………††ˆ„„†‡ˆˆ†‡„††‹Š…„†‡‡…„…„…„‚…………†……†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„rioyxpkyszozwvvp€~~z~}}}~}€ƒƒ€‚ƒ„‚‚€}~~}~€~~‚€€‚„‡†ƒƒ†„„„…‡†…………‡†ˆ……†…‡‡…†„††‰ˆ…„‰‹ˆ…„†…†…ƒ……„†††††…ƒx‹yrˆz{pp…„x…xyks~y{krƒ‡ƒz|mzyyt}€vno€€ot|uwpy}}m}uoƒ…†z€rr{|upozks|nv‚~~}}{}{|}}~}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡……………‡‡ˆ†„†…‡††…„……„……†‰Š‡……†…††…††„†††††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„…†…†„†„ƒ„„†„ƒƒƒ„ƒ…ƒ…„…„†ƒ…†……„„…‡†„„…†……}w…ƒ„„ƒ‚~~{|{~{|}~}|~€}€~~~€~~~~}}}~|{|~||‰†…„†††…†‡…………††‡ˆ†„†…‡………ƒ„…†…„††‡†…„†„…††††„‡†‡‡††‡ˆˆˆˆ†…‡…††ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…ƒ‚……†……ƒ…„„„†„†…„……ƒ††………„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ}€{{|~{||}~~||~}€~}€~~€}}|€}~~~~||}~{|||{{~ˆ‡„„ˆ††…‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡…††……†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ……ˆ…†‡†‡†‡†‡…‡‡†‡……†‡…††…ƒƒ…††„„ƒ„„ƒ„†„††………ƒ††…†…„†‡…„„……ƒ„ˆ†„ƒƒ„ƒ„‚~€|{}~{|{~~}||~}~~}~}}~~|}||~~|}|||}|||~z{{|~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†„…„‡†„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆŠˆ…†ˆ…†‡†‡†‡†‡…ˆˆ‡‡…††‡…††…‚„„…†……„„„ƒ„…„†††…†„†…††……††…„ƒ„„ƒ„‡ƒ„‚„…ƒ€€{{~}|||~}|||}~|}|~}|}}||||}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††„…†…†††…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡„†††‡‡‡…‡†ˆˆ‡‡…‡‡‡…†‡„‚„ƒ„†…‡…„„„„„…†††††…‡……‡…†…†…„ƒ„ƒƒ„‡ƒ€‚ƒ„‚‚‚€{}}|||~}|}}|}{||{||}}{{{}|{~}{|}}|}}~}|zz{{||ˆ‡‚†‡††‡††…„…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡ˆˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡…‡‡††‡‡…‡†ˆˆ‡†…‡†ˆ††ˆ„ƒ„„ƒ††‡……„„„…†††††…†‡††ˆ††„†…ƒƒƒƒ‚ƒ†ƒ~‚‚ƒ€ƒ‚|~||}}|}}|~{{{z{|||{{{~{{}{z{~||||}~}{z|z||‰‡ƒ†…†…††……„……………„ƒ„†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…‰Š‡…‡†‡ˆˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……ˆƒ„†…ƒ††‡†…„ƒ……†††††…††‡†‡‡…ƒ……ƒ‚‚ƒ…‚ƒ~‚„‚~~||}}{}}|~zz{y{|}{{{{~||||z{}||||~}|{{{{||‰‡„†„†„††…„………„„ƒ„‚€ƒ†ƒ‚z„Œ{€„…‡†††„„‡ˆ‡†‡……‡‰‡„‡…††ˆ†…‡„†‡ˆ††ˆ‡‡‡†‡ˆ†„†††‡……ˆƒ„…„†††‡……„ƒ……††‡†‡…†††…††„ƒ„…‚‚€„ƒ‚‚}~ƒ~€||}}~}{~}|}yzzy{|}zz{{}|}||zz}||}|~~€{{{|~}|ˆ‡…†…‡„†„…………„ƒƒƒ€‚…‚€}|{„…††„…„„‡‡†††…„†‰†‚†„†††……‡…‡ˆˆ†…ˆ‡‰‡††‡…„†……‡…„‡ƒ„…„ˆ††‡……„‚……†…††‡……††……†‚ƒƒ…€€€„€ƒ€|€~~‚€}€}€|}~}~{~}|{yzzyz}}yzz{|{|{{z{}}|}|~~|{{}~}|ˆ†…†††………„……„ƒ‚‚€‚€€€ƒ~~~€yz}€ƒ„…‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………†‡†ˆˆ†…ˆ‡‰‡†………ƒ†„…‡ƒƒ†„„…„‡†…†…†„‚……†††††„…††„……‚‚ƒ„~€€€€ƒ€|}~‚~~€~€}}~}{}{zyzzyz|}yzz{{z|{{{{|}}}|~}|||~|{‡……††††„…„…ƒ…‚€€€€~‚‚}}{‚ƒƒ…†…„ƒƒ†ƒƒ„‚€…‡…‚ƒƒ„„…††‡‡‡……ˆ†‰‡…„„„‚…ƒ„†‚ƒ†„„†„‡††………ƒ„…„…†…†„„„„…ƒ…„€€‚ƒ~€ƒ|€}}‚}€~~~~~}}{|{zyzzyz{|yzz{{{|z{{{|}}}}€}}||}€}|†ƒ††…††ƒ„ƒ†‚…€€€~|~~€‚‚‚„…ƒ‚‚„€ƒ‚€„…„‚€‚ƒ‚„……‡††„…‡…‡…†‚ƒ‚‚ƒ‚‚…ƒ…„…†„†††††…ƒ„„ƒ„………ƒ„ƒƒ„‚„„€‚‚}~~~~„~{||€}€}~ƒ}~~}}~{~{{zy{zyzz{yzzz{{|z||||~~}|}||}€~€†„……„‡„„ƒ‚†‚ƒ€€~~€}‚|}~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚‚†…‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡†……„ƒƒƒ„……„ƒƒ‚„ƒƒ€€~}}~~|~ƒ~|~||~‚~‚|~}}|||{{zzzzy{y{zyzzz{|y{}{{~€}}}}€€€†„„…„…‚„‚‚„‚‚€€~}~~~~€}}€~~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„…ƒ‚ƒ……‚„ƒ€€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚€…ƒ~€~||~}|~ƒ}{~|}€€ƒ}}€~}|||}{{zyzyy{yzzyzz{{{z{}||‚€~€€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌÌÌËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFK=8765999<>9?<C9;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;>BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937676=<>:=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<:<<98:9:::;<::;9><>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA=366:;<8C<BA><A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖËËËËËËËËËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9>CE?<;999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNG¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖËËÑÓÓÓÓÓÓÓÓÓÓÓÓÓÎÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø×Ø×××ÚÛÚÚÚÚÚÚÚÛÜÛÛÛÙ×××××××××××××ÖÔÓÓÓÓÓÓÓÓÓÓÔÔÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILN@99:4;@<7=9AC>@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMMF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖË̃mpppppppppppj§ãÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¹´‹‹‹‹‹‹‹‹‹ŠŠŠˆŸ»¹¹¹¹¹¹¸¸¸¸¸·½ÓÓÓÓÓÓÓÒÒÒÒÓÓÓÛâáââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑrliNSbLLVM<::77>C?8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKPFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ËÍN&+++++++++++"ŠôëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§£££££££££££¤œXRSSSSSSSSSSSOw¨¤¤£££££££££¢«ÓÒÒÓÓÓÓÒÒÒÒÒÒÒßëêëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘wliJN_MRUM><<7;?C>6:7>?;=B@9<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ËÍR,11111111111'óééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤¦ž\VWWWWWWWWWWWSz©¥¥¥¤¤¤¤¤¤¤¤£¬ÒÒÒÒÒÒÒÒÒÒÒÒÒÑßêêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;?@@8:;8<<<;>::;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÌÎ\9===========5“ðççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©ª¢fabbbbbbbbbbb^‚­©©©©©©©©©©©¨°ÒÒÒÒÒÒÒÒÒÒÒÒÒÑßéééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB>;=:9::=<;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÌÍÄÂÃÃÃÃÃÃÃÃÃÃÃÂÉÐÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÎÎÎÎÎÎÎÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÑÍÌÌÌÌÌÌÌÌÌËËËËÍÒÒÒÒÒÒÒÒÒÒÒÒÒÒÔÓÔÖÖÖÖÖÖÖÖÖÖÕ×ØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<7@A<=8:;898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÍÍÏÐÐÏÏÏÏÏÏÏÐÔÐÐÎÌÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÎÒÓÏÏÏÓÓÏÏÐÓÒÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖ×××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oVJ_cRQZKHAA<B==;:>><>?==?89:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÎÒ«œÏÐС–ËÓǒ«ÑÎÎÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==<=:<=B>BB@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÎÒ¶œ¥£Ö§ «ŸÏ™¬š²ÒÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?><7:>9?D>@98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÏ͜‘ž¹ž–¡´•†œÍÏÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>><<96?B?B:648:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÑ¿˜ ›µ—Ÿ ¨™µ¿É—™ÅÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8E@?B:74:::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÓ´™–ª¹œ¦ ‹ŸÄӑ™¡ÏÐÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<=<964:98::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯Ê £¿Êœ¥Œ§­Øª™ªÔÏÏÏÔ«š~£¥›Çɔح£¿žÕÑÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ×××××××××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>9<97659:6:<;7<@@<::=:<?>=<9@<<::9?@==<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÔ¬›§‹—”Ÿ••¤»Íˆ•žÈÒÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CGDAA8;?<=;<<7558968;:9<:>?<<=9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÓ¶²²¥†ž¯³¥ÐÛ£™µÕÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ђl]\oghb]OF?HHFE@<<>><==<756:96:;::;8@?:<<9<>=;;:?9?:;9=>=><;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦ÕÄ¢™– £›¢œœ‘§˜ž»ÕÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;557<:7:;::;9==:::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸« ÇÕ¢«¤œ¾ž¨¡£ž¨¢©ÐÓÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFRQKK@>=D<?CF=557;96:;:;=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÓÓȑ´Ù¯‘¥Ôš’Ž¾ÖÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUij[L_MJLJTLFB<<?FEGKI=667:979:;:;=9>98:8;=>>A>=9<<:=>>;=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÔÈÁÕÒÕÀ½ÖÔÓ¹ÈÕÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?ADLLA>775:88899:<><>7::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÑÓÔÒÒÒÔÕÓÓÓÖÔÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEJ==786977899;;=?@<<89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9599:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EIKAALD??;9889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEHIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDI;AA;<886586987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGJB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<AA<;876797799=?A?<:9@?<>B?:8776=?@@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDKIMKFIE>BD88867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE><HF89757875898;>>=;89A>=@?A>7596;>AB??@@AB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCDECALH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÔÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HQA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELBA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD;:<864887666?>>:<9<;:==<<8;<<DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDE@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<877966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGHNOEHFMII@;D>HI@=<::;868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAD?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8:87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;99:86885668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßá mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€iixsg~‰‰xp‚†{w}~…Š¼ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9768579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€‚wt|„‚}sp€Šx‚yƒÈÞÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsnupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9886553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿½¾¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»º¹¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956535658756578;><;999:8779769=;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¹¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjcmgb\XQPQKTJB:IQ?A7<94:565455588686<:9<==;:86688:767>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸¸·······¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPF>8;728967443588797;9:==<::974:98668?>@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µ¶¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269664737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³µµ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶······¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸···¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬«««¯°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:9358963:=>@?@:@BBB??@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·³°°­¬«ª©©¨§¨©©©¨¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶···¸·¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜˜™™™™ššš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<699367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¥¥¥¥¦¨¨§¨¨¥¦¨¨§¨¨§¨¨©ª§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸·¶······¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™˜˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<>::A<7<8378837;@??@@:BEC@BDCA?;;@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬¬¬«ª©¨¥£¤¥¦¦¥¦§§ª¨¦¦§§§¨¨§§¨¨§¥¤¤¢¡¡¡ ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¥§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§¦¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°­«©©®«¨¥¥¦¦§¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜™šš™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<?=?A?<?BC?BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©«««¬ªªª¨¦¥¥£¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤££¢¢£¢¡ŸŸŸžžœœœœœžŸ ¢¡¢£££¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™˜——––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>>;:99=7669656>B>>A?=>CA>CC@@;@?BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž£¤¡ŸžŸ  œœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¤¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747578;=8::99;=;;89>6789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥£¢¡¡¡¡¢£¥§¦¦§¬«§¦ œ›¡¡ž››šœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””““““’”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899898=;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡££¢££¤¤¥¦¦¥¤¤¢¡¡££££¢£¥¦¦¦¦§§¦Ÿ›š›¢ š–—•š›š——˜™šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¦¤£¡  ŸŸ¡¡Ÿ  š˜˜™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364689:89788:=;<9;;::67899>?@><=@>@:9@A?=A?>AA>AA?:9=>:P Ÿœ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~ššwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž ¡ ¤§§¦¥£¢¡£§¦¦¥££¦¦¦¦¦§¦¦ ›™›¡ —’“’—šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢£¥¤¥¥¥¥¥¥¥¤£¤£¢¢¢¡  ¡ žŸŸŸŸŸžžŸ Ÿœ›š™—•”””“‘‘’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB?DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šœž¡¦¦¦¥¤£¢¢¦§§¦£¤¦¦¥¥¦§¦¦¢œŸ¡Ÿ—‘‘”—›˜–——˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢££¤¥¤£¤¤¤¤¢¢¢¡¢¡  Ÿ žžžŸž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:865846789=88;:;?;:;<:::7768;<;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–—˜——šž¢¢¡¢£¤¤££¦¦¥¤¦§¦¥¥¥¦¥¥£  ¡¡ ™’–›šžœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡  ŸŸœœœœžžš—––•”““’’’‘‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¥¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžŸŸ £¤¢¡¡¢£¢£¤¤¦¦¥¤¤£¢¡¡žœ›•“•™œš›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œŸ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸžŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::78:64795<968979<;;<::<;:<<8687>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœœžžžŸ ¡ ŸŸ   ¡¢££¤¤¤¤¢¡¡žœš™—£·Ÿ™™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢Ÿ›ž¡¢£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™˜™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š™—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££ ŸŸ ¡¢¤£¢£¤¢­§W^]TW_nkšš›œ››œŸžœœœœŸ  ¡ ¡¡  ¡¡¢¦¡¢¢¢¡ žœ›››™¡©–œ››™œžš–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’‘’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA==;::;;;75;86;746::>;:=>>=;;;><:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥¤¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¥¡ž ¡¢¢¢¡ ¥²­  ŸŸžœ™™ššœ®fxž›™šœ™—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›š›šš›š˜™˜˜˜˜˜˜•”“‘‘‘’“’‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>99;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤¤¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ žžŸ   Ÿ¦“˜¬Ÿ Ÿ›ššš™ª€DŸžžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ Ÿž›ššš›š˜™™˜——–•””“‘‘‘’’““’““”—™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9<<=98;8:;79:589;=<9=;=><=>;??:9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š››Ÿ¢¢ž›œœœœž Ÿa™¨Ÿžœšš›œ£¡OH„ žœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ ¡ œŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸžœ™›šœœ›šš™–––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;BC9<??;:97;8887489<;<8;;<=:<>9?A<:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜—˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš›››››š§j\¢ ›™™›œ¯rJL†¡œœœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™˜˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\Q<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™™˜¥‚Sw¢™™š› £_WN‡¡œœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž›šœœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡ ¡ŸŸŸŸ™š›œš™˜•–—–•––“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd\\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š›››œœ›˜˜™ Š\`“›š›œ£eZM¢žžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[[LF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ››››››œ™˜™ž™]^u–šœ¢eZM¢žŸžžžœœœžŸŸŸž  Ÿžœ›œž››››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<9=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœœ›››››œš˜™™›ab`~•žœž—tcUO¢žŸŸžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜™š˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’™˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_^]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799:=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜˜——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžœš››œ›››˜™™Ÿi][c}œœž‹i^PS‡Ÿ›žœœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒŽ‹‹–ˆˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢ª±·´¹µ±´­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=:F??:7;;;63:7:9>8::<=998:9;<:>=;@@;<B<@:847<;B@AB>>;CDD@CC=>>9a™•‹‘†–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œšœ›œ›˜™š˜˜™›šš—“vnfVy”˜‰[TPY‹’Ž’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨ª¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::8;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‘Œ‘‹Œ‘‘Ž“Ÿ’¢¥˜¦tOPd‡‡‚‹†‰Š‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜ž—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VQQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8::@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹Œ†Š‹‹‰‡„†ƒ€…¢›Œ|f’¥“œ{ˆƒct€€‚’†„„…ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974869388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹Ž‹‰‰…‚‚~~‚£‰ylQsœ‹Xp{|~|…Ž‹†”‘‹—”—’˜¡–ž–•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¦›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:8758885979:=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ‚†‹‡ˆ…„ˆˆŠ…€‚}™™uSKKs“…‚L^oqw‰…ŠŽ‹™œ””” ššŸ¢­±®©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPEMISWRe^gTPL\QHLRCA997958866;79:;:=88;:9:<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K€‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}€~z|ƒ~‚}€ƒ‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‘‹ˆŒ‹‹‡‘Ž£‹P0/;x†vu@B[jn‚‰‰””˜•œšž¨®²°°µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWMO_^\NUUbQDTM;?:<895875795:::9<8:<=:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš™ž¡“—›¡š›¢§œcC_K<xxifG16Wmr‹˜šŒ”š—œ› ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUJTOOJDPK_bXZQ\T`MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FC>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ªª©§¢¥¨©«©ª®ŽIxª~@|xebQVcJ^oŠ¡¡¤ž›š¤§¤©«®¬¥¤¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdWOYKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GE>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®««¬¤¡¢¦©§¨¢vcÂÔ¥E}„xOmxVb€£¨§ ¢¡®¬«ª§­®¨¥¤©©ª©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_VZNRNQOSe\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@DB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢™œ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨§¦¨©§ª©¤§§™¤¥£¢žc»À®|¤£š—lI\{pRt•£¢ ¡Ÿ¡¡¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOXO^edlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;@AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤ ¢ ¢§¡¦®¦¦œŸlƒ˜¹‹¬Ó£›´¬\M¯šUe¡ž  ž £™–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvxb_\UYQUW[c_s_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?B?:8:>?C@DA:;>=@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯««¬¨¨«¯©¨ª¨¢ ¡¨ª­±²¯«££‡w~zsÑÄ°™£­lV§®f]‡¦ ¥¢¡Ÿ¢˜•ž›ŸŸ¤¡œ•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸŸ¡¦¢›—’šš •|wo}yf[[`_Z\U\hdocmiib^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¡ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£ £ªª§¯··µµ¶²­°­‡m’˽••¦•tVmwus•¦ª§¤¡Ÿ£›¡š–ž¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¡™˜¥ ¤§ª©¨ª­¬¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxjb[__\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>BE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢ «²¸»¼¼ººÂ¹µ´ž†vaVžµ»¦§™‡xmrpxyz}„Œ‘–›¡¦§¬¦¥˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨¨«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥¡¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxxxc[RYT__amhvkqhiibZSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶´º±ª®´±°²´µ¸ÂÈÎÒÐÌȽ±£peRDˆ”………}xrofekhkqsqqrt{‹©ÆÆ»¢§ª¬§«©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš’–””˜“š˜Š‹‡€€|‚xa^YSaiaftotitdidb[LK>:9898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÄÇÃÅÇÛäãÙÉ»®£•†rYZQDfwjntnkeeYX]X\bijheak¸ÁÀ¹©¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`b_^kcbnxuwnm[bRV\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAA;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–••‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±°§¼¼¾ÅÄÆÉÇÅƾÌÐÔʹ¦š‘„p\QTKD[f^cjebah[UYTWYZ\Y]yž¸º«´²­³­©®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|„jfhaklgnvrrurg^`\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅľÃÁÇËɸ•taTOOSH>_l__ecb_dbTVWVTU[y¢®°ª¨«­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|uklndomiqxoyjia]gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÄÄù¸ÃŸfKDGKD=Zdbbjda\d_XSPPR\‡¶º¬®¥¤£¨¤  ¥™©´±¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿ”“‰‰~†ˆŒ–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyz{wnkihvZgrxszgg^d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÊÆÄÄÄÂÄÁ°ŠSGME;KZ_flg_\`YZTOY‡§¬¸µ²¬©£¡­©¬§­Ÿ¬´´¿Ã¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyvvefjjh^konyxcba`^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÎÏÌÃÇÆÈÉÈÈÉÇÅÉÇÈÇÂǝq\H??D^bakb[XWSY€¡¹¿»¼º¼¬­¦©»º¹·¿³µ¸²Áƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqocahvhjjtnyl^d[U`YLHD6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÌÐÍÇÌÉÂÂÇÂËËÈÇÌÉÎÆÆÆÀ¯zUN/VTWhaRNTz²ÉÈÂÄÇÀ¼¾´°°°Â¾¾ÁÆÀ¾·¶Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—Ž‹”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r}xpg`kjwmifvotc]cUWUSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<9>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÄÇÈÆÒÉÁÃÿ¿¾ÄËÈÊËɼ¼ÈÇÉÍÈÃÈÉÉÅÅÂÂÂÃÁ•CNyƒŽVPy­ÍÓŶ¿¿À¿º»½µ³³À¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzy€spfegdlebknoo_Y]WVNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾƹ»Ãº¸¹¼¾ÁÇÁÆ»¹ÈÈÃÅÄÀÃÁÁÀÄÁ¾¼Ç¦ym‚‘–r´ÌÈÇÑÁ¯½½¸¹»»¾·´°¹¾³¼¾±¹µ¸¼¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}zƒxnfaebacddjcgd[ZZ]YQOE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶·´´µ¿»½¿¹¾ºº´À¸µ·²®º»·À·¼ÉÏÀº¿À¼»Å½ºÀÄ¿½¿®pa|‘Š‹ÑÅ¿¿É¿°Á¿º·»¾¹µ¸´¸¼´½¸µ´°³¼±··¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬¬§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ §¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|yˆ}qdacchkggjfj^VVTYOSLF8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=96<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“““˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´´±°µ·µ»Á¸¾¹¿¼¼·´·¯®·µ¹¿»ÁԌ¸¿»ÃµºÇ¶µ¸º¼¸¹¶«¥˜|„É¿¿»Á¾¹Æ½Â¿¼Å¸¶·´¸¶¶»»¸¶´·ºµ³¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¡¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒyqmeegpjelhYYOKKKRJLHD9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’™”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿¾¼²­¯¬±°·¼·»½ÁĹ··¶µ¹¹º»¿¼ÏÃv¨Ì½Ç·¹·­¶´·¹³µ±½ÉŕH|ʾ¿¾½¼¿ÈÃÅžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~‡}knqgqktfcn`\UHKKDJCCG?:;8><7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘Ž˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼»À·ª­¤®°¸»²½¾»Ä¶µ¸µ·¿¾Ä¼ÂÄ×­s€»ÈÏÂÀ¸®´´»½·¹±½ÃʍDvÍÿ¾½¼ÇÌÇÇÄǽµµ¶Á½»»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†rfljnuoydhc\cQKUHEECGC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?>??FD@A?>:7?@CC?@=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼ªª£°¹½¼²¼¾¼Å¸±¸¹¼ÆÉÊÂÆÉјps¬ÑÑÌÊĵº¿ÄȾ¾´¿ÀÀwQoËƾÁ¼¿ÃÌÊÇÅÆÀ¹½¼Ä¿¿¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtpmltlmo`c_bbNHN?E@?DC;;::;:8;<:9<>::>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´»ÅÑú¾¼Ä¾·¼À¿ÉÏÇÈÊÉÁ…qs¥ÌÌËÍÊÆÂÃËÎÁ¼¸½º°ncc¼ÈÄÀÀ¿ÄÀÊÉÃÃÄùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{zˆ{mmx|`qd\_`_TI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA??ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸´¼·»»«Ûþ¶¾À¾¾º¦œ©²¶Ã¿¥xux›ÄÆËÈÁÃÀ¿ÉÊÁ¿»¹± |rk®ÈÅÄ¿ÀÁ¿ËÇÃÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¤žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}znsxthp^\_]ZRFEDMIAD=H;;59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘—žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯··²µ³·¹¼»¶»»Ä·m­Î½¶¹À¼¬}nhnmr•˜sw|—½¿ÆÀ¹À¼¾ÅĽ½¸±°˜|€›ÊÂü½¿¿Ãÿ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸··½¹»±¶²ÈÀ»¶´±°·¬³©°­­´·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|wmu{poj\`aZTQAFIGK@ECI<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿ››œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹ÀͲv³½¶µÂ¥‡iZ^`MR[ZnswŸ¸¸Âº³»·»½¿º»»®¤š—†~ÀÄþ¼¿»»¸¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ°µ´´½º¾ºº»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶¼´±¬£¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰{‚zsvvwnra_f][UJ=??GG=GCC9:5;99><<9:<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Âɧ…xŠ ¯µjegVY`IIMPSlw†¥°·¾¹²µ²»¹¼¶¹¾´–›¥• q®ÉÄÀ½¿¹³®²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtwrl_ca\^OIB?=IDFMD@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·¿Åªˆ|uŒ ˜`TCXUGajVOEJa ¬¯¶ºµ´²¬¼¹¸µ¸Á½‹—¯¡¥r¥Ë¿¹ºµ®¥¬³°¦¯­¨ Ÿ¥­¶µÂ·¶´¥¨ª¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´¶¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wp|ovsnc^gY]^SONB?JCAKJ@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜š‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³²­¶º¯­¼³¸¸¾´‚xˆoNJ?dYBNw€”jNA]°µ³µ²´¯¬»º¸¶¹¿Åu‚¨™c©¿¸µ²±­­Ÿ¤¦¦œ£¥œ–™™šŸ©®¹¬««Ÿ¥¨¤«®¯§°«¯±±­±®®¯¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmujl]\kT^\PNHDGMBGNG8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹º¶¹»µµ³·¶•Œˆ„{XFAN‡YJJXwcAS£¸³´²°±­°¹¸¶»·º¼¡±ª£r¬°©«­«£¨ ž–—¡•‘•——ž¨®¤£¤ ¢¦¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬ª¯£¤£¡© ›“Ž”’’™–š¤¥ Ÿž§˜•’”™ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wryhutoeUadW]ROMI@IRDNC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯²¼ª™™•iM@RxqPIIKgœYDR®»±¬³¯®¬­¶¶²´µ®¨¦žš›ž¦¨ž ¨©Ÿ¡§–š–—›’ŒŽ”Œ–š£¨ Ÿ¡¢¡¦¥œ££ ž¥ ¤¬¥¦¨¥¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›ª¨««Ÿ¦¢›£œ•Œ“—•–˜Ÿžžš™¦—“’–¢ ¥¢¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ª©¤©«¦©¬«¦¡ˆxƒ|vzcxmn]QiUPOGPMMCPRA?;>4::5;:=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢ª¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¤¬¨½Â«¥¾iER‚QWIJ`KTŽacb®µª²´®ª«¯°²³­¥‘—“— Ÿ¡ œ£¤Ÿž¨”™”•Š”ŽŠ•‘—›¡©žžŸ £¥¨œŸ ¡œ¡Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£žžžš—š«¦ª±£¥¨ž œ–“’‘™–•˜—Ÿ˜œ™›¤™—”•š §¨¥ £¢¡£Ÿ ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’~|€uv}nl{diVRdNIHGOSNKNH<E@=2@859;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜——–¡¨¬®¶¶º¹º··»®¨ ¡© ªÆ¿Ë¡PAswPnKLcfus`Z^p±¯®³µª¦¬¬£›™”‘•—˜˜œŸ¢¢œ¤žš¤•š”—–šž£©  ž¦§«¢Ÿ §ŸŸ£¦¨ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¢¥¢›™ž¯¨®²«¦«ª ›˜˜˜•“–š“•–š–›—˜˜¡žœœ–›¡›žš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰|€~wy|eyyabSVaHIKLSUJSQM9?A67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—“’œž¤¨®­¬««¯ª¯©ž—ž¥œ¤ÇǎWSJe£Ze~or]Qkc[d_\k´°°¸¬¦¡œš”—š™Ž‘•‘ŒŽ“™¢œ–§¥¡••–‘––”›™£¤¨Ÿ¥£ž§®®ª¦¢±£š£¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§¡ £±®²±´ª²®£™œž¡˜››š˜™›•–›–™œ¥¡ š£¡š™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ ž ž ¥¡žž¥ ¦™{|vvsi‚me\S[ZMQKOOVMTMB7>C78=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’‘œ˜¡ª¢§ ž§¡¥Ÿœ’›¢šž«¤zUirvupcvvXWc`cgYXWg­®¬¯§Ÿž¢ –“› œ™—’“Ÿœ¡£šžš˜£n}—™ ›¢žœ¢œ¢¦«­§«¨¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½¶¾°¬±®­©ª´±°¨«¨³µ¸³¸­²´¤ ¥ ¬¡¡¢¡ š™––Ÿ››˜¥¡ ž£¡ Ÿ›œ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚|xvjwu^m[RaIRVHFVWKCMH=KI8F<77;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©¨®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“Ÿ™¨®Ÿ§žœ¡žš™’˜ž›¢¡ ¤€n‚p`cXL[SZMLPXRHMMH˜¬ª©¥ Ÿš’‘”˜˜–––Œˆ‹Ž”œœŸ™HGŸŸ¦£®§¤¬ ¨«µ°´°°­¶¸½¿º­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ·»¶«®±¹·¼¯³°µÁ¼·¾³³µ¢¬¢©©²©«¨§¨š™žšª§ ™§ ŸŸ¨¨¥¥Ÿª¢¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰……~vrmiwmhn\X\CWNJGMHCFN=>L>4<:6:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©©”’—™”šššœ˜˜™œš˜™ª ±¢·¤°¦Ÿž—˜•™ž›œ£Ÿ‰aW^e`WMQG>>?CC?>BQx©­©ª¦ žŸ¢£Ÿž››”“•”žž˜”…¦v*`’ž£«®¸¯¯®¯¯¸¼»»¸µ¸Ã¾¿Â¿¶º»Àù½»¬®§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¸Â¾¸´»ÆĽü¸´ª³­ª³´¯³®ª¯£ž¬¨·²­£°¦¡£°±®°¤¥¯£¡ š¡¦¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¤ž¦š›¢¤žŸ›››œ‡†|trklurqhW\QFUHDJPI?EB4FH96<>7;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž  œœ˜šŸ šŸŸ•|_^e`QGD<C>E<?96N~ª³§¤£¢ ž¥¬¦Ÿ˜•’šž™•ŒŠ†ˆ†xl‹W5f…|y€–¼¼¼°¹ÁÃÂÆ¿¾ÂÆÆÅÃÈÂÀÅÈÍÐÈËò·µ¾²¾Å»¾ÌÍÆÌÌÌÒǾ¿ÀþÇƸÄÊÉÄÁÇ¿º´º»µ»·°¶²«»²¯¼·À»º«¸­«ª¸»µ¼®®¸£¦£ž¦¥¢£©¦™›Ÿ™š§ª§ ¡¡¤˜”£•”™‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ…~zrkdioxkeZ\FLMEDTMEBE7:?;549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<@?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ²²¸§¡¡«ª¡œž¡¡›š}sjaWNE>IY|obB=\Ž®¬ ™›œžž™——˜“——”Œ‚ƒ‚vrplplT`kprns®Ä¾ÁÌÍÐÈÄÈÐÌÌÌÇÊÅÅÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÑÓÍÓÐÓÓÌÊÁÆÇÆÊÈÏÀÉÑÍÇÆÈƽÄÁ¿¿¿µ¾³­¿ÀÃÃÇÅÈį¿¹²¸½ÄÂÁ»¼¼µ®§§®¨ ¢©¥š– š™¨«©£¤¤ž—›‹™‰•˜› Ÿ£—žš““‹•…yusebgrog^ZZDOMCFQIDCA55589B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>9;AA;;>786:;>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›¢¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¤¨¬­ª £ž›–kf]TID@?K†ž¥š„ ²­£žœŸš˜—”“”—‘ˆ„„‰‡ƒ€€yqqnj{€dXwwrnr¾ÏÍÓʳÑÐÐÑÑÍÍÎÐÄÍÔÕØÑ×ÍÆÇÉÌÃÅÊÏÊÒ×Ò×ÒÕÖÓÔÈÌÇÌÍÉÓÍÎÓÍÆÉÊÊÂÇÌÇÉÉƿó³ÈÅËËËÏÇÊ¿¾¿½ÁÇÅÌÌÉÉÀÃÀ®°³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›–Œ†‘‹€{ruvgcgvjeVXRDNG@IQC>B=:22A<E<78<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<@?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­³·¬®£ž£¢¡œcTLJDC?CR®Ñ½²¯¦œœœ ¤¡š””•”Š}yqlebhrpr{…Š€upmpro„{v€}truotžÏÐә¶×ÓÑÒÔÔÒÏÑÃÐÓÖØÕÕÒËÉÎÐËÆÍÒÊÒÕ×ÙÖØÓÖØÍÒÊÏÑÌÏÑÍÓÐÀÉÈËÄÌÍÌÏÏÆÇȶÀËÀÒÍÌÐÇÊÉÀÄÃÈÏÍÐÑÏÍÊÈ͸·»¨Ÿ¥«§ž˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„}xsvpcaerc]R\JKGAFIJ?;A8>5586;86:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÁűµ¨¡¥¥ ¢¢[I@ADAFQv²¯¦š”—Ÿœš  ž›š•‰wida____^__]alusponkposƒ€{ymih^m¾Ó£ÒÖÔÎÏÕÔÔÑÑÌÐÍÓ×ÖÓÕÐÏÒÓÑÉÓÑÈÐ××ØÒØÒ×ÙÕÖÌÏÏÉÍÒÌÎÑÀÇÄÉÇÏÎÑÑÒÈÌÍÀËÍÆÔÏÌÏÉÅËÇÇÉÌËÔÔÑÕÏÒÌÓ¹ű¥¨µ®¨›¨«¥²¨°³¬¬““ŽˆŠŽƒ‹„Ž™“™‚…Œ|zqstmacim_VQ`JJCECSN?<>43:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><?@=FAD=‚¤œ ¥ž¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯­ªª«¥®·¨«·×ÔÕÙÙÑÎп¼Ìɶ¾®§ª¨¡£¬fC8=>DX‚ª¨Ÿ—•—™šœŸ˜›“}qecb__a_^a`^a`_`emppmjlosv}ry€rb\SY£­r«ÚÏÓÎËÒÍÕÔÑÊÏÌÓÖÒÑÖÍÏÕÕÑÅÑÓÊÐÔÕÖÎÓÑØØØ×ËÈÎÄÉÏÍÊÌÀÉÁÉÊÎÏÐÌÐÎÎÌÏÐÈÌÐÑËÎËÃÊÈÊÍËÌÒÓÎÔÒÑÐÐʽȹ°®»¹µ«¶°­¨¸­³¿»±šŽ ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…‰zvopokadnpaX\[IFFDMYE;@=33<<87855;>@=9<<8<>9<@;@:=8?98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§  £§š›Ÿœ—žž¡ššœš¦›Ÿ¤§Ÿ¸¶µµ¬¤¬®¾´°ÀØÒ×ÚÜÖÎÍÊÃÒÏÁÁ±©¬­©¤²{HFB;W¡›•“–›žžžœ“–—”ˆk^^^adb``aa```^__^\bmrnnpqrqvtowytc[\{wˆÑÔÉÌÍÄÍÊÒÒÎÆÎÌÍÔËÎÒÍË×ÖÐÌÑÔËÌÐÒÓÊÎÑÕÒÕÖÊÀÊÂÆÍÃÈÊÃÍÄÆÉËËÏËÎÍÑÎÔÌÇÉÐÍÉÇËÆÇÂÆÊÌÎÑÑÇÐÏÎÎÌÐÅÇÁ¸¹½Ã½ù²²¾°»Ãĵª˜¥¡˜–‘••’‹”š‘””•‚‰†yqrkmh``qhYXhVMGLIQQB;D?;68:8:;57==A;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÄÂÁ¿»µ²±Ç¸ÊÕÖÙÚÛØÌÌÏÈÖÕĵ¯´¨ ­—xlopwšŒ—•“‘‘•–•‹|ebbb`]^acb`__`aa`_][]gqqopqmimsphrtgfc]wÂÅÇÇÄĽÁÅÎÎÇÅÆÍÊÑÈËÍÍÆÑÒÏÍÌÔÊÇÊÎÏÇÇÏÒËÐÏźĿÆʽÃÇÉÎÅÃÈÀÇÎÈÄÍËÍÐÉÅÅÐÉÆÂÆÉÅ¿ÁÈÍÌÌÏÃÊÌÉÇÌÐÅÅÈ»ÇÃÉÉÂÏÁ½¼¿°ÁÉǹ½ª±²§¥¢œ˜›£™—™‘•˜‰‚xoudk`^fqa[W`GIHGIMUG?J=64355==48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<::79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ¼¹ÌÌÆÐÕÕØÚÛØÐÉÏÏÑÓÈ·»»­¤¶~g‚…¢ª“–…ƒƒƒ}„„~s_[^]^`^`cdc_]\^_``_[Z\akrpmmhgijujcb^be]¨Æ¸¿Á¹¹¸¸½ÈÅÁÃÀÃÇÊÈÈÉÈÁÅÌÆÈÊÍÉÄÁÊÉÁÁËÏÄËÈ¿¹Á¼ÆȾÀÆÏËÄÀûÊÇÈ»ÉÆÅÊÁ¾ÂËÆÅľƾ½ÁÄÆÌÆƼ¿ÊÃÅÇÒÅÁÉÀÊÊÆÈÆÐÃÃÆîÄËÇÃÊ·¿¼º³©¬¤¥˜Ÿ˜¬£¡¦›£ ›•|wsufj[anmZ\XRDLGCGDLDFS?54335@=3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¾¸¼ÊÏÑÌÇÂÃÆÍÎÎÌÕÏÕÙØÙÏËÒÍÍÎÈÁµÃ¾²°¶l^y|Ÿ‘Š’–†z€„…uxurp_Z[]``bcdded`[\^]^]`[YZ\anqmifgkinw\XV]aiªÁ­µ¸°°±¯¯Áºº»º¸ÀÁÁľ½¹½À¹ÄÊÅƽÆÀ·»ÃÈ¿ÁÉ»¶»»Åÿ¼ÂÎÃƾ¾µÁ¾Ä»½Ç¼Ãºµ½ÆÄÂ÷À¶¶¿¿¼ÍĽ¶ºÈ»¿¾ÌÄÂÆÃÆÉÇÉÆÐÆÂÌȲÇÉÃÎÌÀÅÿ¼²·°²§¨¨¹°¥­°ª­¬”zwxkeh`hodV^YJFJFHKAEBFJA9:658853;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µ«·´²¡žŸ—š”–šŸ¦¢ž·ÅÂÄÈÎÒÊÊÊÇÍÍÎÑÈÐÆÕÔÕ×ÍÊÏÅÉÅÇÁºÅ½¬®¦`cv’‹ˆ‹„x††}ƒ{ttc\\]^``bcbbdeb]\[\^\^]Z[\]grokdcijkwrOQWbqš´«®®¤§«©¤µ²µ³²³´»µ½±·°µ¯²»Â»Áļ¿º´²º¾À¸È¸´¼¶À½¸½ÇÁûµ¯³µ»¿´Å¸»µ¬¹½¾À½±»¶°·º³Æ½·¯¼¿µ·µÅ½¾ÃÆÀÄÆÆÇÌÅ¿ÆÆ»ÇË¿ÏÉÇÃÆÁ÷ý½¶¹¾Ç¿¬µ»µ·¶Žytxggebkn^V^`FKHHJGBDAEF?=:566633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÅËÍÈÅÈÍÌÐËÍÈÉÈÊÉÊÄÐÍÒÏÍÅÇÁÅÁ¿º¸É·«°™[goˆ†ˆ‰zx~…†vw|sh]]]]_`_`da^cec_^\[^\]^Z[[]_kolfcfhhl{eI\u‡”¨¨¨£›Ÿ§¤›¨©°¬©«©³­µ°²¨­§¬³»º¶Ã¹º¹°ª´¹»³Â¹¯À±½¼»µ»Ç¹Ã·­ª¨°²À¶¸½°±¨²³µ»¼«®¶§®¶®¼²±ª¸°®»®»¸»ÀÁ¾ºÃ¿ÆÃÅÀ¼ÆÁÇʸÅÇÅ¿ÇÃùÄÆ»ÆÉÌ˳¹Â½»³‰tvwki`bliYWW[ALLMJEAC?FA:::996854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÅÎÒËÃÅÁÄÏÇÍÁÂÆ¿ÄÄÃÃÊÂÉÊ¿À¼Âº³µµÃ®ª°’[i~’ˆŽ{x}‰…y{„€wn^]\\]_`__dcbdcb`_]Z[ZZ]ZZZZ\cmmfdddfhmydm„“›¢¥®š›¡–™¢¨¬£§¡«©««°£¦Ÿ©­µ¶±½¸¯·¯¨­¸´³¼·³½°¸¹µ²¼Á²À¯¥©£«±³³¨½ª«¨«¬®µ´¦©®¡¥¯©³¦¨¨®¦¨·¬±³·º»»²¼¾¾¾Ä¿µÁÀÇÈ·¿¿Å·ÅÃÀ»¿Ä¾ÄÈÌÊ¿¿ÄÀÀ©‡stsji\aodWVXPHZSSKFFE>?@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÐÏÌÃǹ¹ËÂ˾»É¶½Ã¾ºÊ·ÁÄÁ´¶¼¶±¯µ¼­©«“dmˆƒ‡‹€z}~xt~|swe_]\\^_`^_ccab`a_]]\ZXY[[XWY\_ejdbcaddhmyy€‡†“˜‘•­¦ ˜”Žž §¢¢Ÿ¤¤¦¥­Ÿœ›£¥¬²°¶·§°¬¨ª´«³¹°¶¶®¶º³°ºº±¶¤ ¤ ¦±¨¬©¹ª¥§§¨§³­ §§Ÿœ¤¦¬ŸŸ§¤¡¡±­­¬²µ³´°µ¼¶»ÁÀ²»¾ÃÁ±¹¹Â³À½Àµ¸¼½¾¼ÂÇÄÃÄ¿ÀÄ „yqlbf`ko`UY_HNhOTHFKF<=@=:;;826536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;>97776788666;::;9:;<859<:>>@;Èµ¶½¸ºÁº½¶ ž• ¦º¶«³³»³ÄÏÉËŸ·ÇÀÌ¿¸Ê·»Å¸³Å¸³¿À¬¶¼²¬¦¯´­¡£’ir†…†€|xusomjiipi_`]\\\^__acb````^\[\\XYXXXVXZ]^cb`cccbeflysqjX[oE{ Ÿ”’‰šžŸ¥›žž¢¤¢§›¢›žª®¬±µ¤¨ª©¬¬¤´¸¬·°¬³µ¯³µ¯°ªŸžŸ¤¢²¥¦ª¸­¢¦¦Ÿ¨­«™Ÿ ž™Ÿ¥š™£œœž°©¬¨ª«¬­°³¹¯¸¹º°¶¼»º«³²¹³½´·²±¶µ¿µ½À½Ã»»½—„{sl_e^ddXTW^IW]KPGJJGA<??A;?<05636:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»¸ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÅÏÈÈÀÆ»»ÃÃϾ¹È¸¸¿·²Â´±»»¬¹º±¢Ÿ©«§˜žm~…†xrmomkb^bff]]^]]]\]_`abccba_\[[ZZYXXWWWWXWZ]abccbbcdepjXA":qhi‡œ’’Œ—žž¦š›£¥¡¤›Ÿ ™˜®­­¯² ¤¢­«§¡µ°±²¬©°³¨º³§¶¡¢Ÿœ£¡­£¢ª¶«¢£¦ž¦¦£–™—™šŸš—œœ­¡¬¨£¤¦­«³³ªµ°²«²¹´¯ª¯²²³·³®©­®²¸°º¶º½¿·³±”†zvf_f_[YVSZUK[QLJEHKIC=?AA@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½¸½¿¶¾¼¿²¥£˜¥±Ãµ¶½­´¸ÂÌÈÆÀŶÁÀÇηÀý³¹¹²¿¶±¹»­²µ¯Ÿš£ª¡”šxƒ„xoqtqhediec\\[[]]\[^`a^__`^\[Z\ZYXVWVVXWXWUW`bcaab``dfrDHŠ”Ž™‘”Ž“œšž›•ŸŸ§¢§›šš«§¯°ªœ££·©¡ ®¨µª§§®±¤¸°¤· £œ™™ª¦¡š­¹°£¡¤œ¢  “•¡”––œ™˜–—œ•Ÿ©žª¤¢ž£ªª±­¨´¬ª§­³°¥«®³±¯°¯¯§¨¨²®²´°¼´º¸®£”‚zwe_aWYXSRTKM^LPLGHMLE=@>=B<:7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´ºÂ±¾·½­§§¢ª»À½À¹®´¸ÁÌÇÅÂýŸÈ̲ÁÂÁ®¼»µ»¼µ¹¹°¯°ªœš¡©•‘Š‹€€|wqilrtphhedfa\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWVUZbb``a__`bj_%7n‡‹ŽŽ”’–‘˜œ™”ž¥¤¢¥¦žœŸ¦ «¯¦Ÿ¡£¶§¡¡¢©³¢¥¨¥°¦±®«µŸ¡–•©¡¢”­±±Ÿ££žž˜œ“Œ ”‘“˜˜’—˜˜—ž§›§¢¢š¤¥¥«¤¥°§¥£«¬­¦©®¯¯«¨ªª³¦¦«¯´±®¼¶±¯¯Ÿ’{xseb\[]XNLQHRaMVPOJNOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8847763321./2556;:8;7876<;:;;A8x»»±¶½°»±·¬ž¥¦¬¸»¼Áź²¹µÄÉÉÀÂÆÅǶÆijÁ¿Å«··½¶½º»µ²¬­¨™™Ÿ£‹Št‰ˆ~vncafihfgifil`]\[ZZZZ\]\[\^_\ZY[YYZ[WUXWUTVVRTRT__]^_\]]`alW\‡ƒ‰‡‹•Ž“ —ž•šž£ «¤££¢¤¢œª«¤šž¥±ª¡¡ž¥ªž¨¢Ÿ­¬ª©®­¢¢¢•˜¢šœ«©°œŸ¢ŸŸ—™“Š‘’”–˜˜“œ¡£œ¥¡¢• ¢¤¥›£«¥¢¤ª¤«­¥®²©¦¥¦¦µ¦ª¨­³µ´¹º¯ª¬žŒsqp`[WVVRGQOHZ\ORJTKSLEGJC8;;=<9666:9;:976977:;:=<<6;<8>598:88659:;<97?<9678452121..1426:8698598989;9@9{µ´¬´»²°«±­¨§¯¹¹³ÀȺµÀ¯ÅÈ̺ÁÉÌȵɼ±¾ÃÉ­±¸Áµ¼À¼´µª¬¦–šœœ‰rˆƒ{tiijlgjlmkjle]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURSNPY][[\\\]\_bkƒ‰}Šˆˆ‡’ŒŽ˜˜ ™™Ÿ¦§ª§«§©¥¢˜¤®¤•˜¤¯© œ™› Ÿ®™œª³Ÿ¦¦Ÿ££¡•”›––’©©­›œŸ¡¡›”Œ˜Œ‘’–•¡ £œ£•›¡£¡˜¢¨£¢¨« «°¤®¸¥£¤£¬­ª¨«¯´·²½µ³«®˜…uti[YYSURFXLQ[XMUOPLQRIOIB=??A?=75799<<977:79:;<=>;7;;:=67:;8976989:6:=99577571141-+/434988::8::748=8?9~³­§³·®¨¨¯®›©¨¬·¶¬¼Ê»¶¿¬ÌÆŸÀÎÏdzĻ·»Âȱ­¸¿·¼¾»³¶¦© –˜™—ˆzt€vwnmhmmmpgghfd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUSSNOQXYYY\[Z[]^dz„zƒw„ˆƒ‹‡‘Œ“–ž˜ž©¨¥­«©°£§™ž¬ ””£¨§˜šž®–˜§ª˜Ÿ”¥ ž’‘’‘“•¨ª¥š˜™žž—ŽŒ‹“†‰ƒ‹’•‘ ž¡¤™–Ÿ•š¡¢ž”›¥¥§©¨ °°¦±½§Ÿ£¬´ª®§¯´°¹µÀ±®°«‘~rtcVTUNQJGVPRRLLXNKLOSGNKACFEC>A75889;9:7::7<=:;@>:9;9:?759:9876958779;85576661320-*.102877;99;8948;8@8´¬¦±·ª¥¢±«ª§©²°¤¶Æ´¹º³ÊŹºÁËÐʱ·¸¼½Àñ°±·®´´»³´££˜—•„€vkglnqnqjokdege^ZYZYZZZZZZZ\\]\ZXXXYYWXWUUTRSUSVTRMNMRWXYXXWZ[[`iwpvm…ˆ‚‘†”˜–›¦™ž©¦¥«¦˜ž¥›’Žž¢š——†…’›¤•¢œ––•‡¢š›“ŒŽŠš¥§œ••—œ‘“ˆ”Ž‹Œ€‹’’’¡š ¢–”™˜•¢¦š™¤§©§¡ ´²¨³¸¡£¶¬ª®¤²²¦µ»µ«¬±¢Šzsn^NQQMODNNNPKFNNJJNNQHMJAHLIHC>958889:;69:68;99><8:>9;?8789:886857688974577820301+)-/12876:999984988A7w¶§¤¶°¤§¤ª¥ ©¦¤³ª¢²Ãµµ²³ÆÅ·ºÃÊÌƳ­º½´¸À¯®©°ž¦®»¯­ š›ž••ˆ|„n__frpuqinieghj_XXXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQNMKKSWWVWWWVZ]alimg{zzŒ€Š†‘›Ÿ˜›£¡£˜¤–¡›”‡™šŒsƒ~Ž—–†’š”Ž{™Œ‚‰€Š˜ £ž“˜–…Ž‚”~~tŠŽzˆ“›šš’–Ž££Ž‰š ¡¤¤›¢´¯¬°­Ÿ˜¦¸¦¥°¡±®œ±¼ª©¯©™„xtdVMRPPMCSNLPMBPQHINSNIJJEKMGKK=749888;;69;7:<9::;79?9>@79:<89764445874312485/0102)(,-02764789::66:87A7x·¡£´¨¦¥¨£¥¥¦¦¦²§¦´Á¸¯´°Éĸ¹ÀÎƾ³¬ºÁ¬­Ä­¨¢¦’¦·­£ ‘–—’~xfWV_gfighnciigb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTQMMJGNSSSTTSUX[]idgdu|tmKUnŒ“ƒŠš•‰’ž˜•”–“•‰€”‰_;Vo|Œ”Š€Œ’Œ††r‹„–y{†”•ƒ–Žƒ†}“xqp†}‰Ž—š™“‹ŠˆŸ˜‡ˆ–žš¡ —§®©­©©ž–­³¢¥­™­«˜¨´£©­£“tn`[NSRWLDTJPMLFNOIELQMKPJINPGJJ=7599999:7:;:>>8:==7:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9y· ¢­¡¦¦ª ¦©§£ª°¨§´Á¹°µ°Ç¸³½Ï¿¹¯®µÂ§ªÄª¢˜ƒ”œ±£š™‡”‹‡~sv]PLQUYZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MNQMKHFHNQQLORTUXY`id^qylL?=}“z…’Šƒˆ‹š–”‰‘†„“…y‰`JQnx‹’„~„Œ‹„m~“wuvx„špQˆŠ†|~y”vgw†ˆ~Šˆ•‹Ž‘“—Œ„Šˆ”…›‚…’›–ž”¤¢¨©¥¤ž›°ª¡¤¤‘¦ª–¢ªœ¡¦§Šwnf^\HQQSMIUMRILKOIHFJNLMUKQRPGJD=768:8:;;8:;8>?99>=8;<6;;478;6775344696/3/.115221/,')+*,4833989:99::::?9w¶›¢§Ÿ¡®¡§¨¥§¨¯¬ª¶¼¶¸·³Á»¶§¹È¸¶¨¨µ¶ª²¼§ž•Ž‰”©–•‹Žƒ‚~xqoXMKMMNKMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDCINOhYNQSTUZm}jmvccXRŽ†’…q|„~zƒ‹’’™‹Žz…uxsouptŽŽz~Š«…z{hv{Žprmx‹’x{€{€wsr’xhu…„„…|•ŠˆŠ‹€„‹€”„|˜”œ–‘Ÿ©ž ¡ ©¥Ÿ˜§£“ Ÿ–žŸ¤sib]]JWPRHKXROJMLRJJJLPHLQMRUMFIB=78;99>=:;<98@?::>=7==79947785675251472/2.,./200/-+(().12721987:8775:<;7v®™£¡˜Ÿ´©¯ª¥­«°±ª½´²»¸¶º´±Ÿ·º²ª¬©¨²¯¢š‘”ŽœŽ‘~w†w|wpojYKHIHGEHHPTTTWWSTUUUVWXWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LNQQSV^s~vraq‰”—ydw~tv}‡|ƒ˜‘p†{v{ok~­|t‹z†’€|tfu|†lohs|Š‡€myq}qmvqhq~ŽpD‹…‚ƒ…wwzŒ†}Œ{u}Ž’˜‹’š›£–™›ž¡œ–‹¥šŽ—Ž–˜xongc[XXUQJSUTOPNPVKNKOOJROIOPLFD=;79;::?=9<:99??;8;=7<9999266856633511224.,,-..-0-+*''*.1362/876966527995y¦— ž– ¦°¬®«¨©±¯±«¼¸«»¾¸³¬§›°§¬›–œ¥©¥¡˜šŽ„’y‰‹‹vq|mupjmjXKFGEA@CDHLLMQRPQSTTTUVVWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zYJNOQTX]eoogƒ¥©À}qv`yvlyw†y{‹…nk‹’xsxij€‚q–‘Œ}•I’™ngw~‚mjdly…’†krl|nr|†imps‰…†{~{wptt†‚yyp|Ž‹Š“ƒ–—˜š“––™—–Œƒ‰Ÿ’‹’†—€pjoooYVXTRRYORUTRXUMNHMKMOKCINGF@:99;99:><9<;::=>:8:<9?868727565541432/024*+**-.+-*(*(',-1250,5567485HA895w™‘›˜›Ÿ¤¬¯¢­ª¨µ¯®¬´¿«¼Ã¿¦¢š•¤˜ž„‹”¡¡˜™‘“‹sŽz€†Œ†uotlpmekkYNDFC@<>>AFFGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_IMOORVZQX[^¥†a˜eoub|mk}x‰‡u‡…sk™‘ts|ijŽLy…“‰„Žf1v‡rk}}ƒtfeu„„…€filukp€|hqq|n“{t~}qqoumƒwyujyˆ‚ˆ‰ƒ–’’‹‘””Ž—€yˆ—ˆ‡Š†€ˆxlkpheXR[XYY[NPUVYXNIHEJJHGB@GECG=998;9:9<:9;:::@<9:<98>787715233533645031.**+),,++)(+'),,226,,4775478iO8;5m’ˆš™–¤¨­ž±ž§º¯«²°Â±»Ãǚ–Ž•™‹Ž…z„˜•Œ‡q‡‚tˆŒ†zpsqopdpg_TFIC><;9:?@ADCEGJLOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOOQULBIQIb®²žnwtizjo€ƒ€yƒ……yr ”tx€st”‡5p¨¡¡„¢…vp†{†|tŒ®‰hgbjnrmpƒuioXupŽ›‘vm{}nrnp€{svnbuƒ†€…ŠŠ‰‘‹‘‹‹ŽƒuxŠŽ€~ƒ€}Ž|srqm`\]^\ZYa_RN[ZXWLHJFIG?CABH?CD=;:7=;:;;9:99;:?<88=:8;66651111253474531./,,+)*))***)(*)+/3DM2166643<vR7=7b‘’ˆ•‘¤§ž¯•¥´©®°®Á²»ÁŖŒ”€ˆ|n’‰ƒŠ‡†u‚„l•ˆˆ{uxxlwnwdj^IPG=?7448;:;=>@BEHLLLLNPQSTUVWXZXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL8DNRSDJ„s|yys{jt…†z|ƒ‚~‹}u¡™y~…€„™„šœa†ªŸŠƒŽzwˆ~‰ˆŽs‹—„{]dqtz|wŠmhjbyo…‚zoxu…zptzxkni]v†}‡|‡†ŽŠ’—ƒ…Œ†}q„„}vw{|‰xqtugh`[\^S\g^WQTX[UGJJDKG?F@DC>AA=;97<;;=<::99;;=>79>9985653244004645554-,)+('''&(())((+++/00Uq=23331E~W4=9\ŒxŠ“Œ‘œž¦‘ ª ±¨¯À²»Äº–Ž‘“‡z†vk‹‘ƒ}ŠƒŽŒxƒ€s¡„Š}}p~zhwkRXL@E211376688:<>AEFFGJKMOQRSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMOQLKT\XRKg…x†wyoz‰x{‡…~–‡v ™‡†Ž’”¥¬©H†®°®‹€”‹‚‹‚„’©‡€˜˜Šœtm|†‡~Žhghyn…‡‚…q„†Hl€wryvhmk_v}ƒˆ‡…‹y”œ›‰‹ˆ‘zuŠv|xmow~uusm\^^\cdXgf\UPPWYPDLKFOICFCCA@CA=978:::;;:888::?>6;>7585773344236656778;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|}‰…‡Ž•—’– ¬ ¦¸¯³½³—’‹˜‹}tp~‰’~}Œƒ’”}†~†¤‡ˆ€‚ˆ…x‡‰~s„x_cWKB60./23123668:=>?BEGHJMNQSTUTTVUSQOGC?80,#‡[??94.]–ps£UFIKMMPW`XoY[]g‰ƒ‘~ƒ|„‡€™”Ÿ —”›š¦­“™»±§»Ç苌¡¥Ž“‰‘|qƒžŸ‘w……‹‡ihp„tŒ‡„Šr†‚wˆ€{v„|muuf”Ž†ˆˆ‡ˆ‡ ª¢–‰Ž—zˆyyogkx~|€ule^[[^j^bg`ZOLNXRQIPJDNGCJDCADDB<:87=<:<:88778:==8<=68656623444576867<BB?<8:>CQ^e\G2'&,,--.1(?‹[.310Oƒ_4?;nupfw‚zŒŽŠš›¤¡¬¦ª®°—‘‘„¡”„xwŒ”|~’†’•Š€’›Ž„€ŒŠ‚‰ƒŠlpj]B@4--//..02234778;=?BDHINQRTRSSTRPOHDB<87/9C><<63.l“—MPHJLLKNV_b~ffkr˜–‹—ˆ‹Œ—†‘ŽœŠŸŸ‘¢©¤£«“©¶¢¨Á­ǯxº”š|¡ž™„“…‚Ž¡Ÿ”™‘…Š…™‘–lpuŠŒ‚•ŒŽw„qm…Š–‘‚…ˆqˆ –†‘‰–¤´¨›Œ”¢ƒ‡’ƒ}kjj|‚ƒƒuc_e`[hl^ll^WKHNRQMLLFIPCDNFBCEFC=:96=<:;:987767;:6=:785456344566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYo‚ou†qv’†~—–š”žžœ§ ©–“˜žge¤š~„’‘y’ˆ‘’}Š„˜’ƒ€€‹Œ‰†‡„‰…xx~gMR>/..,/.-/000212467;?CENORTPPQSQNPIED>;<:DF?><852<?R5HHHLLMNR^m‰{r{›™—¤¢Ÿ—ž” “›§§ªž§«©ªµ—«¿«¶ÇÈ·ÈÐϾ› pi«©Ÿ„“’…œ š›™¦’‘ˆ•¢››xz~”˜“¢’——”ž{w•’ª²ˆŒ—Ÿ|”›‘•˜£¡¥µ¯œ˜§‡–€ˆlss}~sja^b`bhd`hg\REJKPOIILFFMCHLFFCBGDA:85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Ppt`m}awŽ}{”ŽŽŠŸ’—ž–›ª˜žªBD}‡‰‡˜x‚ŠŽŒ|Š†Ž‚€‰‹Š…’…ƒ†‰€‡w^bP460-1/,.0/./..0015>AAMQRSQRSURNSLEE@<>=FG@A@8662<9;FHGIJNOQYl„Žv’ˆž¢¦±»¶¢¬ª«¦§³ª¯µ±±­º±³½›²Ã«ºÉ˷ÿ¸¥¢°³¬­ª£‹–˜„¥¦ £—¦™¢«¨¥ˆ…”¤¡ «¡¤¨œ±‹•£¦·º› ¢¯’£¢£¡«®«²´¡”¤©ˆ™ˆ’‰•yz~†ibi]fc_ed^gg_[OCIHSNFHLFJGFFHAKFCFFA;87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLhbWinXz„v“…ˆ‚›ƒ’‘Œ’Úȝ–sV—ˆˆœ|†ŒŽŠŠz‡‚‡‘Žƒ„‹…†ˆ’†‚…‰‡ˆ‡‡qna@E64<2/110-,+-0.-4?CAMUPRSUUVUN[PGGD<>>FHCEA8;<5C;=FKIGHQOQW€‘žƒ«¡¯§®¾ÅÁ¨±Äµ«²¿²·½µ¾´Á¶»º£¸Å¨µÈǵ½¹´¨£´­°±›™’šŸˆ§¯«¥”vŸ¤—¡¬²´™–ª®¨®¶»²º¬°µ¢±¬±µ»¶´®´ §¨£§š©¯¬±¸·¸¦šµ¨Œ¤Ž’Ÿ†x‚…x[ceWgcbdaag`[TJDDLUQHIJDIGEA@@KDBMG<967;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AFWQJL[YQbbWyup”}„†“u…€Œ{¿»£¼‚´”“›„ˆ’‰ˆy†€Œ“Œ‡„Ž‰††ˆ†Š‡zxn]V@EN<6:45AB764//6CHBQ[OQUWU\WP_UIKJA?>GKFFD;>@7D7?BJJEFVTP^Ž£¬¢°±¿²µ¾ÊǵºÄ½²³À¶·Á´¾°·t±³¦ºÄ¤°Æ¹°²±´¨¤µ¶ª± ¢—›¢’¥°®¦­«§¤˜ ¬´»¢¨²ºµ¼¿Ì¿ÅŽ½³Á·º·¾¶º·¹¬¬±¥°©­½°¼ºÁÁ«˜¹§”­Ž——©ˆ~ƒ~mXdbYlfkfX\cYVSIGFLQGCHIAHD>?BBL@@MD99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FRLALQVSYUZvjo~Žƒ€Ž„nzsx‡b¹¡™£‰””–’”“–‘‡†{†•Š€„Šz|Š‡†|Š‚‹ƒ•}wzueP\dGEL;Qca[^SF?;HPEZcQRXXZgYT`_LSPEA?IJHEEA@D<E6B>HGJLSYT]’­¶³¹¶Ç¼¸»É̺»À»·µ»º¶½³¹±Å`u²¤±šžª½©¥¨«ª¤¢²µ «¨Ÿ•–Ÿ™ ®¥§¦¥Ÿ£“£§±´¨²³½¶Á¾ÓÉÉÓÆÃÅÌÂÊÃÀ½¼¾»¼·´¯¸·¶Ã¹Å½Âǯž¸©¡«¤§µˆtacc_Yc`jgSX`VRUIEENK@>GD=KA=B@=F>;H@796379>489:57045/26389374426?8@>GKRTSQPOQQPJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKEAIMPRKQ]glkp…slrrs‡ÕÀµ™ •˜™‘Ž—‘––Ž†‡}†ƒŒ–Š~ƒ‚x{‹ƒ‡{‹yŠ‚—~t}zkfpuY^\Pedb`ed][XW\MdmURmm_n_XgdTYUJDBKKIFHHHHBI:D?HKSTU\Z[’·¾·¼µÄ¾¹¸Éʺ¶¹µ·¹²·´³®µ¶˜du§œ­p^¢¬œ˜ ¢›¤žª¥”ŸŸ“Ž–™˜¨Ÿ¦ žš™ƒ¤ž¬¥ª°­¸°½¹ÔÑÏ×ÐÊÌÒÌÏÎÊÆ¿¾ÂʽÁ¼ÁÀÄÄÅʾÇͲ£º°´®š«¸»˜€|m_b^Z_cZdcQ[`SPKCAEFE<@E>AHB@C=:E>=J?47535;=468977022/24169775555D3ELM>51/006:477@IOI;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODQ[Yh_o–’”nlotu‡´¬¡¡Ÿ‹™œ™Œ•‘š‘…ŠŠ~ˆ†Œ‹ˆ|ƒs{Šƒ…{‰t‚Š†•s{ylmu{hreiligjji`fiilZms–­¤¼ˆ†g[og]ZZTHKNPJKPKSQILAJFJO_^afia–µÅ°¸²º»³°ÄƵ¯¸°°»«²±¦ª·«Œµ§š§šN™ŒŽŸ–‘¦˜¥•Š““‰‰‘‘›¡—š•–‡žš§›¬¯¨°¨´´ÔÔÔÖÓÌÐÓÕÍÒÏÌÄÂÉоÉÉÊÉÑÇÌÍÂÏÑ·¯Ã¼Ã¹¤µ¹Á¢„qe^__ZbYZgZQ]XOPBBHEBH;AC>AG??A7;D>@H=46655;:687654/10146278875367C5B8?-0-1349=97,.,1;FK=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYReVs˜‚gqoyyƒ¡ªž¦—Œš›—‹•‘šŽ}‰‹„ŠŠŠ‡|„‚p‡†{‡rƒ’‹Ž}qxulqx~qzmxsmipmcimpxiw|~Ë¿Áߧmcxnc[b`JPRUNY^O]\NPNTPTT\nmv‚q–¬·«³¦¯µ©«»¿°ª´¥¤¸¦«® «´£Ž°­š—˜Œ“‘„Ž›¦‘œ‰ƒ‹„Š‰„‹„”•˜—”›‘œ—™šŸŸ«¬¥¨¢¬­ÏÒÕÒÎÌÓÔÔÏÔÑÎÇÃÔÑÇÍÒÓÓ×ÌÑÑÄÒÖÅÁÎÇǨ½·Îž|qh`e_XbS_[PQTQOH>@FABE<@A>ED>??:==<<JA45465<888664412/03526768533;=<E=@11+/249>5901022-2DN3)/3.32=N238C}_2A†tD:==I>@CFH<UQMNZu†…Šwlwp}~¡žž¡ŒŒ˜““‹Œ’•…y…ŠŠˆ†~‚{r~€€‡z„u…“ˆovrks}{w{s‚xrk€srioqzyqz¾Ëš~Œ²„vr„vhak]CZZ[VecXdjSX\]`c]cwz}‹˜©¤¤¡Ÿ §¥ª¯¸ª¥²¡¡­¡£­¡§±Ÿˆ¦š“’‘‰‘Žˆ“‰j”¢Œ™„†~‘ƒƒ“—­‹••™Ž†’‘ž—¨°¢¡¡¥¤©ÉÍÏÈÂÌÑÔÒÔÒÎÓÍÆÖÒÌÔØÖÖØÔ×ÕÉÔÚÍÉ××ÑʬÃÂˍuqebaZVZU\QKGJJJ@;:;DAD<BC>GB>BB;<9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/--;R017/532FD28>nb5=tM99@I<AD?A;OLFJXp€u}hsxr‚‰€•”…‹•‰Ž‰ˆ†Žxƒ“˜ŠŒ‡‡‹ˆ~‚ws{}‚‡wz†‘•ƒnwpmuux}t…|yl‡vtn}v„tx{µŒ;A‹Å¥~Œ|ieWICfcecgjcmw[^fhknhn€‚‡‘‹œ —˜ž££¥±££±ž¡¥ ¨ £±œ…ž’‘‘‹‹†ƒ„œ›Œ‚„…y”‚©•£Œ‘‰—’‹~˜‹š’«³˜›œ¨œ§¾Ãƹ¶ÆÎÒÑÒÐÌÒËÈÔÎÐÕÚ××ØÔÙØÍØÛÎÉÙÚÑÕ¾Ê˵zypg_\TWR]WFGJIEE=:7:@@B:FD?DCADB;?;;7DC75655;0679443341014558744449@>DBC<33.6FTWOQJAJF?1*(.BS39254/7K75<`bA<svV87AH:?C><9QECJTknnpbpqt†|—‘‹~‡’ƒ‰†„‰‡|x…––ˆŽ‚‡…‡z„xqz{ƒ…uy…Žœy‹p|oozq{€qƒ‡€nŽzuw}|‚t~|†‡¯sX©Â¶‘‚pmb=^hrpqpnxvehoruxqz‹†“‘š•Ÿ•‡Œ“š šž©Ÿ ¬›¡š˜Ÿ¥žŸ«™‹š‹’…}ˆ‡ƒ…‹Ž ™“ˆƒ‡~l™z„˜†ˆ“Œ”Œ†|œ‰”®ª”–˜Ÿ™§¯¶½©­¾ÇÌÉÉÌËÐÉÃÒÊÔ×Ù×Ø×ÕÛ×ÓÙÛÕÐÚÚÑÖÈÔ˖{}kj]\QTU`ICFIH>A>=7:=?;=G=?AAADA>>:87DB755479.566435542323647553458EBDCEB56<FNSM[nfcnskaV>,4LG865434BF4=W_hLux^8;?F<<B<99D>CGRj^mdbfkv€ˆq‘š€z€~‚‚ƒ~ƒ{|„˜‡‹~…†€w‚yn{{†ty’žŽ vŽu‚su}s€„o‚o’„u|…zv†{‰·Å¤Áɸ–›wpeNfczw†¢Šxyv{ƒ{„vm“–””Ž—‘ƒ‰–š––¥œ—Ÿ–ž’‘—¢™«•ŠŒ‘‚Œ…ˆˆ†‘ž›™ˆ†Œ…—zˆ‰Ÿ—ˆŠ‹‚}¡‰‘Œ¼¡˜“˜™©¦¦®Ÿ¨¶¿ÀÁ¹ÇÊÎÎÅÍÉÑÖÕÕÙÕ×ÛÔÖÙÚÛ×ÛÚÙØÎÛƈ}{ikgaUYVWNLENC;==<8:;=9=@6=?@<?=<9867CA6455=80665547745613854564557HH=DJE7925;H>;::7IP]ZRUXK9T>;95327I8=NYMHxxd5=>C==@:6:>>@EQ_Xea][htzylŠ’wvzŠ{~€~|„z}‚‘‰„…z„‡{u}tm|}†~t’ž‘žƒ‘{†~x~xŠŠn‚š€t™†~‰„{~z©ŽÃ¡½‹œ¤}‰„}‰r‹Š~s¦šœ˜“…{Žˆ„hGq ¤Œ‹’…ˆŠ“”Žœ™’”–Œ•Ÿœ” ”‘‹~ŽŽŠ„‰’–šžŸ‰Œ”’‘‚‹€¥™ˆ„‚…„¥†ŠŒ¸˜‘•–¢¨¡žž¤¯·ºµ¬ÀÆÊÐÈÇÌÏÓÓÒØÓÕ×À×ØÙÛØÚÚÙÙ×Û¹{{znkhYb]TPOIDLB<<>99::99;=6?>><=9:;;37D?7378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWN<MTHN?96333>C;[X>5YypZ<<A<=>8689?=CQSRX^UXfmmmiŽŠqryŠ{z|{‡z|{‹†‚}tƒ…yszsm€~„~w…›¢›”’Œˆ˜‡€›’nˆ¨…z ‹|‘ƒˆ„œ}šŠŒ£¢ ¤¯Ÿ‹‹…‹“†Wr­‹Ÿ«›ƒ˜›Ž\‚¢‘‚ŒŸ“•Œ‡ˆŒ’’‹””“Ž‹Š‡–šœ”–Š‘“†€‹ˆ’ŠŠœ–˜¢¢†“– Š‰ˆ›ƒˆŽ€ƒ‡†¤…Œ‘³˜’”—¡¡žš’œž¨²¸­¦½ÂÇÍÈÆÏÍÐÌÏ×ÑÑÕ®ÖÕØÚØÚÚ×ÕÙÙ rwjh_^YUYYCAIC?>>:49:;7:;:3;;?=>7;9:0:G=:37=@50677255?65;55858:57735HR7GOK994=EJB>1FCLB98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:;@;BQKKSYPTcbzma~’ƒomw‹xyz|…{{v…„sp…‚zuwvt„‚„~’¦¤Ÿ¥¢—Š”—‹Š¨—sŠ±„§’„™“…™Œ¢•Ÿ˜“ˆšž£’©°Ÿ”Žˆ–Œn·…šÄȲ›¡¥›œ˜–²‘d¤ÍȖ†‡ˆ’’“‰…Š‰…–™š”“†”—ƒ‹™ˆª–—££ˆ™ž–šˆŽ†–—‰„ŽŒ‡¤ˆŽ“¨š—“—™¡™Ÿ™“›£³´¦£¼Á¾ÇÅÅÉÈÉÂËÓÍÍÔ©ÒÑÖÖÖØÚÔÒÚ΄u‚kf``_PKV\BBGC;A=837;<:8=649:<:82?9929I:>67BC32:96264>=4;>6949;57944JQ<JQK9A7BGI@64JELF><88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBeƒGu‚Ž||m~ˆxz~z‚~vv€‚{ln‹~y|wx|„†Š~‹£´¨¤ª³¡–§ ¥¤–•¯¢ƒ¸•’³š¡ Œ¤›¯¢¤˜§—©™­°¤—”•”‹˜š– ÀŽ£É¸«š¢¥­™‘›œ²†…¨¢œ˜…ˆˆŽ”ŒŠ“‡€†‡ˆ“˜”ŒŠ““†”˜†„‘œt˜²•–¤¡ˆœ™“ŠŠ–š‰Š–†}Œ˜ŸŠœš™“™˜ ”¡•Ÿ›¡±­£¤·¾³ÅÇĽÃÿÆÎÊÉÒ§ÎÌÓÑÐÖØÒÏؼu|x_bWbXRIKOEBCD5>;76:?;<7=42669774=5;5<L<>;<BA75<;4277?@6??784987;<55OMDPRL8@=EAGA5:IENED:6A@BS>9DO323575=v\<R\tiZM]S<=89567=:JFDGM\\YJha;H„‹zzm…†y|„x€…}px|}|osz}{x†‹‰†„’¨¼­©²½°¥®³³©£¢°­Ššµ¢¸¥•­¤—©­·¦¤£Ÿ™©˜ª¤¯±ªš™œ”•‘˜ —š»»­Ê¡i¶·ª°•˜ž¢«’—½¤^ª²‚‰ŠŒ”‡|ŽŽ}ƒ†Ž””ˆ‡’–‹•‹Œ—™’œ™´–•«ž‹œ”’’‹˜šŠ’‹‰– ¢•—™“œ˜ž”¡ ”œ¦®¨¢¤³¸«ÂÈĶº½¼ÅÈÈÂСÆÉÍÍÄ×ÖÐÊÓ£s}k_[UaSQGD><CAB8?874>F<<6<35355454B39:BM:A;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAE@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPfHa`bpJ@‹‰€r†‡|‰u‚Šƒ~m}||~pw‡w‡{Œ†Œš«ÂÀ°½Æ¼³´Á¼´¬«³¶Œ¨²­­½«›»£¨­¹¸«¦¦¢¢¤£ª¯²±ªœ¤˜›˜˜ž¢¦¥“£¹¯¨¿¼¬­²¹¥£§}ˆ†œ­½°‚‹‹Šƒƒ‘Žz‡Žœˆˆ—Š”—”š–œ§š°š‘«Žš’Ž–‘•—Ž‘ ˆ”›¤¬”–”œž”¡ž›˜  •šž§§¤¢¤°³¦ÀÆ𰻶ÅÅÿͧÇÃÇüÕÐÌÄʊvvd_\b]OLCL@EG>A?B<:4>A==5=6>333241A17@BN>G@CNCA=C=;86CB5BIB:878;5B>79VKDWOF8=4K@C>4EJHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GE?CF\hF_ig[]\“ŒŒˆ{‡‹†ƒŒu†Šn~{~q~z”z’””˜‘“•¨´ÇÉÀÂÌÂùǼº¯«¹»—²¶º²À¯¥À£«°¼¼ª®«£¢ž§¬¯µ±©› ªœ¢œ–Ÿ°´§Œ£ººµÁ»«¨œ²¤¤¨”„Ž©ÄĤ‚‹Ž†ˆ„†•”ŒzƒŒ‘‘¡ŒŒ”‘ˆ— ˜“™”–¥ ®œŒªœŽ–’‘••”‘¡“†—Ÿ ²Ÿ”›” ¡™¤ š › ”˜ž§¤¦§¤¯­¥¿Ã®¨·µÉþ¶Î²Ä¾Ã»³ÑÉÇÁµw{o^[^lTNIDMKKJ@A=BD<5AD;:3=8B332263A05IEM>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBg\Me\fTcjš–Š‹ˆ’†‰y†“r€{Œw‡‚‚y¡–¨šš˜»¾ÉÈÊÂÒÉÊÂͽÁ³­¼¿§º¿½¼Ä¸­Á©¬³¼½ª°ª¤¥£¬®´®¶µ Ÿ®Ÿ¦¢™£´½©œ¨¼Á£¶¶¯«“°¬ª¬–†šª§¥‘‚Œ’¤•‰€u‰‘y…‘žŸ’”‹Œ”£™—›”“¢ž©Ÿ‘¥šŒ•–ˆ|Ž•’’£š• ¢œµ¦ —¥¤£¥Ÿž¦˜ž•—œ¥£¨¨¢²¬¨»Àį¥³·ÌÀº®Ã³»½Á¹­Â¿™p{c[Y^]MMNKGDCHBAADK:4DH:;4<7F.12352B26SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQF7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>lI_XaZdeXžŽ—Žž’‰ŠˆŸ’„x…”~ˆ‰€–¡š®§£˜Ã¾ÉÄÈÆÓÍÎÍ˼·°º½´½Ë»ÃÁ¶·¼­´À¹¼®¯¨¡©¨¶®®©²·šž¬¢¨¢«··ª¥¯¾Ä±½¹³§ª´³­­–•¥­¨ ‘Ž’±Å§•}‘•}‡‘˜ª™—““Ž“•“¥“™“ ¢¡œ˜Ÿ˜‹ŒžˆZ–—’–¤™f™£ž³¥–¢–¬­¬§œŸ§—˜–˜–¡£¨¦Ÿµ«©º»Ã´¦´µËÁ¸ª¶¬³»¸®¨¸º¼·„op\ZVWPGLTNK?AHDDHFF85FM;>7>AK.32025B55PWN<LFKRLOGGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|hV<>@BFBsFiIRfdMF¦”œ–¡—¨–Œƒ‡¥’ˆ‡‚›ƒƒ•”Žš¢Ÿ¯¾®¡Ç¾ÆÅÈÇÎÎÏÒʾ»¶±»»¼¿ÏµÄ½·¹·³²¶³¸³¬§œ««¹«©¨¯¯—£®¥¨¤¥µÁ°«­´¾Â¹À¹³§¸´·²¯•¤­°¯¥‹“” sÁ™}—™„Ž–™‹±•š™•’’™™¥£•Ÿ›–š¨œ›¡ ™ŠŒ–`J–œš•™¥—T–°Ÿ¯œŸ¥•¯¯­¦›¡¦”“™™ŽŸ¦¡™´©ª³¼¼»«°²ÇÀ¸¦¬«­±±£¡²²´¥sqg^\PSMFQQPQ;HKHFGAC=9KT?A:=EM/7534:B34NWN<JKOUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@CAF3>58JKCA=C;5EA:A?>H@5*B52,>c]g:35tde@R7&#3}hX<:BC@=REWStbVFH«—™Ÿ¡¨®˜—‡Š§–ˆ’…Ÿ‡„œ—Žž š£¤µÉ´©Ç¼ÃÄÉËÉÈÌÎƾº³¯º¸ÀÁ͵ȺÁ¹µº²¯¯³´§¤œª´µ«ª§­¬™¤®¦¥©¬ºÀ¨«··¾ÁÀ¾·²²Ã°·½¬£®µ­º¦ˆ›—¥šu¾Ÿ„˜Ž’˜š‹®–¡œ›—”šŸ ©ž§ ™šª™¡§ž—‘ƒmu“¢š•œ¢Ÿ­²¢«•©ª˜ª¯¦¥¡¥ª“’™œ‰•œ¢ž–°§©ªº·¾³²®¾¹¶ £§¨¥¦œœ­©©fhc`SMMGIOJUL=MEMIJ@CD<QU<AABDO18=77?B75UXN?HNQXRPQTJQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CC:9C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW<:=..SaMVH~e^HF¬”œ¡Ÿ»®˜”ž‹“ª›‘‘“ˆªŒ†¡žŒ£¬”£¤¶Ç½´Â»ÃÂÈÉÅÂÎȽ¹²¯¹µÀÃʶƱÁ¼µ»¬©­¬°££™ª´»¦ª§¬ª¨¯¨¤««¾¼¨­¼´·¾Æ¼¶µ¸À°½¿³©µ·¬¿¥¢—¡Ÿ¼ž‰š ™—·Ÿ©œ¥£šœ¡š§¤³¡›¥œ§©˜””›‹–‰Œ¤¢”œ£Ÿ µ°¥¦“±«š«­ŸŸ¥¤ª’–• „žŸœ–©¤¡¡´µº¶­¨µ²²žœ¢¦š—•™«¡žxc_a_LIFHNQINEFGBQJH@DGAVSDH<AGQ1;B7:BF79]YKALPTUSMWRNUJD@JJNO9C?5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-1:h]FDCœpbGE¨—¤žŸÃ¬›—¤—™¨›•ššŽª–•¨¦•­¬™¢«·Å¼¿·ÁÂÀÈÄ¿ÍÆ»¾¹²°¹´¾Ãȵ¿°¼¶º·§¤««­¡¡›«ªÄ¢¥¨¬¦ž«¯¬¢ª¨¾¸¦­¾°··Æ·´¸¸¾±¾À¶´²µ¯¾£–£•“š“­Ÿ¡¡¤¢£ž¾¤©©¬¡›¦Ÿ½¢˜£ž¢©« ••ž“ž‡Ž„“ž¤ ¶¬¦œ–²¦™°¨ œ«Ÿ¡š•Ÿ„Ž¡šœ’¥¤š˜«±µ±ª¥ª­¬›˜ ¡’Ž–©Ÿ”ie\b^PJHKOLHEDI@=OH@;FIH[ROK=HNU4BF8>HG5Cb[KCNRUWVQXTRUH@8QQPM:G@4CHQSIC;C>GVKC@O>K<06;GF>;FA56?9:?9;15D0--0Mv\4KZ5,MnW<-=)#zbQ5CKQ9oRF<KxfcXN£›£›žÅ« ž«œ­Ÿ‘¢ž–¤Ÿ¦ª«—¶±£©³¶Å½À¶À¼É¿Êȶ¸µ´±´´·ÂÆ·¾±¸´º¶ §¬ª«žžŸ¥¤Á¥¡ª­ ¤©­°¢§¨½µ¥±»·¶µÃ²²·º¾²ÃÀ¸¸­´´µ£¤”‘“ ¬Ÿ˜¡¨¨ª¢šÂ¬¨¬­››ž˜¦ ½¡¤˜««¬¦¡™šŸ’žˆŽX–Ÿ¦¡ ¹ª§”˜¶£ž³¢¡œ±˜ š•ž‚ —–Ž¢£•¥®³«©¢¢¥¤••œ™‹’“¤Ÿ‰cg\eaMJKKOFEAGK>=IA99JJN]QQI=LV\8FI=DMI8Hc\KCLPSYYVWOZ^IA=WQIK?H@5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+waS6SZkWsHE6=ue\LPŸ  ˜žÃ§¤¢³ œ²§’ª£Ÿ£ž­©¬»±©¬µ±ÈÃÁóÂþÇĽÄʽ°±¶®±µ°Àŵº±°º¶­š©°©©›ž¦¡§Â­œ­±œª¢®±ª¤¨½·¦¶»½¯·Ã­³³Â¿²Æ³º·«´¶­ª¢¦••”¢«¡ŸŸ™§«¯¯¯»²¥Ÿ©©™™—“¢¤¸ ¡£’®¯«¤¥ž‘¡ž”Ž”š£Ÿ¨µ§§˜´œ£¯› œ°‘¡”˜•›€’¢–Ž  “‹¦¬°¥§¢ ž’’š”…‹’œŸ€dh]hfKJLKSAC@IG;;F>89NMU_RSJ>O^]=HPBMLI8Nd]LELRTY[SUO\bHA?ZQAHAKB7FELKN>;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<w]^?[U_gr@8<H–weA4Ÿ¤Ÿ› Â§£©± £´©•±«¦¢¤²¬­©»²­°µ´Æ¿ÄĶ¿Ä¾ÊŶÀɵ¬µ©°¹¬ÀÄ´·¯­¶º¥™«²¬ª˜¡§˜­»´œ¨°›­Ÿ®µ²§ª»³§¹³¸²¸Àª·²Ã½´Å§¾®­·µ©§¬¡––‘¥¤¡¡——¤®·­±´¶ŸŸ©¤™“”“£ ·£¤¥•®±±¥©¥¡ž›™š•—¨ Ÿ™¢Ÿ¯³£¦Œ—¯š¥«—›Ÿ§“•™š†– •Œž”‹©©ª¢§¡šž–Œ™†•ˆ•Ÿzej]lkNQNNT=CANC;:I?77QN]_RVQAW`\BJSHVKH:Td]NFON[W[RPQX]GAB[PBG>NC9HGHNP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1\cZ33906p[bH05JqiVCWFŒyfC;¤¤œ¡¥¿¦¨®® ©µª·¯«£ª´¶±°¸·°·¸·Ä½Ãǽ¼ÃÂÇÁºÁÆÁºª¶¥­»­Á÷·ª­²¼£•­±­²—¦¨‘ª¹ª¡§°« ¯´³ªª·µ¬»¬³²¹·¬¸°Áº½¿¦Ãª°¶®©««¦˜˜ª¡¡ ‘— °¯³«°¹™›©Ÿ™–’—¦ ·©¥¢¢¯±³«±§« œ Ÿ›ž¥¡˜¤´°œŸ“¦š¡©›–£¡˜š‹–™”–—”‰’›™”Ž©©§ £œ™›“‡™‹~Œ—†›limbnnXQQZTACDU@;;H@7:XPd^PWWDY^^NLSN_LJ>Zd^NIQN[UYPKSWZI?DXPDF>N?=IGGQPB=CFBM?:2D?77547?=95E4+75/251.-.,1>*'+=\p=>1.1e[d@1747gYaF(@8l}h\V:‰{cC=¨Ÿœ¡©¼ ª¯ª£±·©¥´²«¡­µ½¯³¸¼»½·¶À¿ÉĹÄÃÀÀ¹Å½Á¸¯¶¨«·²¼¿¿´ª®²¸Ÿ—¬­¨®˜¨©Ž§»Ÿ¥­³ž«¢±°³¬ª¶³µ¼­°±µ¬°µ²ÀºÅ¶«¼¯±·¬­ª£±¥ž¤¨ž£–˜Ÿ²ª³©ª³™§›š” ¦¤´®§¡¬¬­±§³«±©£›ž¨¤ž•¡™œ¨¶©˜š’‘ž™ž¡Ÿ’­ šš‡—™Œš”‹——š—§¦£ ž—––”•…{“ƒŒ—gmrhqs`GYfVDCMXDZ9HB5>]Qh\NZ]G[^]OMSXdJKC\c`PLMNXWXPJVVWL=EUJEDAM?AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,+%2+*5K1.'__aV151=`V_8)C3YU\gK5ŒzfL@¥™Ÿ¤«¶£«¨¥®­µ©®³¸¦§°·Æ¶°·¿Á¶´ºÅ¾ÌŹÃÁºÀºÄ¸Áº³µ¬ªº¸»º¾µ«¯±·™˜¨««¬œ®««¾ž«¯±£ªŸ±­³®®¶±¸¶ª­®±§µ°³º¼É²ªµµ±´°®¦ ³ š¨¬ ¤••š™±¢­ ¥¯–¢¤š™’Œ¢¥§²©¡¦±¬ªµ¤®°´¯£™­§›—žš™¬¸¢—“‘˜œ¡™˜•®¡Ÿ–‚•™Žžœš—‘‹”“ž™¥££¡™—“’–{Œ‘…{‹ƒŒ“lnyov}bF`jZIHZ[={JGE6AbUi[M\aJ\\ZRSSbaLKE`a`PMIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`Va.5(C^Q\.+A/JGP[G3cYTLEš–Ÿ°¨±©¬¤£®­µ¨·³·£¬´·Éº´»»À¾´³·ÃÀÌǻĽ·¿ÀÀ¸À½²½®¨º¹¸·Â·¬®²º–—§¯¬¨¤³©”¯»¤¬²²¦§£²´±²±µ°·²©®«²¦¸¯µ³ÄŶ©µµ«°®©§¢¶žŸ¦° £”›™”°ž§›Ÿ©©¢›•—¥¥¤·§¢°³«§±§­¯µ¬¤™ ¬¨œœœ”ª¹œ•Œ˜£˜‘˜¨¤ ˜…“—‘œ˜—–ˆ——›¨¥¡’–’–w„‘†|†‚„nqxv|€\Lel\JOd]?b{GI8GgWf[L^bLYYWUXUi]OPHa^_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANHg27'FaLV%-B.=ELQ<3rkLED‘™¤­¤¬­ª¦£°²²ª·°µŸ«µ¹É¸®Á¼Ã·³±µÂÃÏÄÀ¾µ¾ÁÀ»¿¼´Ä¨ª¹±¶·À¼¯¬´´ž¡§±®¥¦±¥ž²µ¬ª²±«¨¨µº¬µ²µ«³¬ª«¨¬©¹­²°Ç¿¸¥¹°©­­¦§­°¥¤£®£¨››š¯™¢¢¢£¬Ÿ£ Ÿ¡©¦¥¸¤«´´¤ª«¨¬®¶®¢£¨«œ ™›’¤µš‰Žˆ‘£¡––Ÿ¢–•†•”ž›™–•‡˜’•™§œ  “’Ž‘x~Ž„}}}‡ŠŠrts~~\Scn^NZg]FD–[G:NmXbZMabNVVVWUYh^QSMcZ[TKGOTSNGIVS\N;P^JBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3Dd;6*HdHJ+:I?3CIS,>l@HIš¨©¡©¯¤§£³´°´´°° «­½Ìº®Á¼Ç±´­³ÁÃÑÄÆ¿Á²¾Ã¼¿¸½Å¨­·¬´¸¼À±¬²®¡£§®ª¨¥±£ª°ª®«±®®¬«³»§·°²©²©ª¦¥£­º­«°Â¹´¬¹©©¨­©§±¥©¤¢®ª¨¡ž›£¬•¥˜ž™«¡§¨¡¬¦£­¬¶°± ©¢Ÿª­°«ž§§©š£˜™ ¨˜†ƒ‹‹Ÿ ŒŽ—ž’‘ˆˆ’–¡–™–†—“”—¥œžŒ’ŽŠˆ„}w€‡…‡utr‰wl_Y`ncQsq\K;„|F?WuX`YOc\MUVUWQ\b_SOOhYWVKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=397;*35>10485(5/*,.30;),,'%234$,2-860)(1<^K0.JgDF8<B05EKX1@”]@NF•–¬§ ©±›¨¨°µ¬¸µ­©¤«ª½É¼±¾¸Ã¯°¬³ÃÄÎÎÿÀ´ÀÄĺÁµÉĬ¯·®³ºÀ¾´®®¬¦¨ª±©¦©²¦´­ª¯­­±®²­´»¥¸³¬¬­§« £ž°·¬ª­¹¶¤µµ¤ª§¬¬ª­ ¨¦§±±¤¦¥¡¡«–ª¡“› ¥ž££ª£¬¢ž¦±¶¬¬¢¥£š©«­©¡¥¤¤™ ™–˜“‚‰… ‹›’…Ž™¥›“‘›Œ“’’”£šœš‹‹Œ|‡‚‚{u„~uw‹£‡xj^`nfWf‡dN@g’LEbzWbXReUMVVUTO\]aVLOjWVVIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72;::*49?./463)4+*,+.#4.-+&(+79*&6+<-2,&06XZ.0JgAA<<C+:JO^4D‡BIID–®¤¡©¯˜©¨­µªµ°ª¤«ª©¼ÀÀ¹¹´¼µ¦²¯ÃÉËÑ¿Á»¹ÀÀºÁºÂÄ®±µ²´¼Á¾³±¯­¬¬§·ª¥­°«¸®¨°¯®±«µª¶µ§µ·¬¬¤©ªœ¤ž³³©¨¤³´Ÿµ­¡ª¨«¨«§Ÿ««¨¹¶©ªª©¡©Ÿ­›‘ª¡ ££¦¢ªžœ¦´®§¥©¢¤—¤¦§ªœ¢¤£ ™˜Ÿ‘Ž™~‡Œ‡…žž‰…Œ‹’Ž…ˆ—£šŽ›‘’’Ÿ˜™—‹„€t‡~xuƒ€zx~ˆpqfgqx\atˆjO]˜VHmyUdVRbOLUUUQOX[bVIQjTVTGPYUI>IHOQPxMNV=<KD?@A<@CUC9AK=5;E23;97*4:=+-341*8**+*,)*(/*&)%3;,$2)2021%/2Rc02@f=NX?C,?LT_/Ik7RF;•¯ ¥©¬™ª£­®²´¯ª¤¯©¨»¿¼Á²°¹­¢¶¯ÈÇÈÑÀ¿½º¼Ã¾»ÄÁÀ¿¯²³³¶½¼Á²²´«´©¥¶©¥­³²¸¯¢­µ±¯±¹«¹®ª®·«ªžª« £¡µ­©¡Ÿ®²¡´ªž¨§«£ª¡¡¬­¨½®«®­¡§¨Ÿ¬™°¡˜¢ ¨§ž§›˜©°©¢Ÿ¬¢¡’¡¢£§˜š©¦˜˜™‹‡•ˆ|†„…¤–†ƒƒŒ‡’…‡• –‰‘‘“‘œ•˜‹††xt}txz€{tt{j‚ˆ¤vi^elugˆ‹|RVp^KxsTdSQ_MMSZfNMWYeYGSjRQ>BNQaQ:IHLSIqQLS;<I?;<=;@@W<<>H73CB15:93-5::)-31--6)(+-,52#2)',%.;.&1.0-14%,0Mh:38_=ad?F1CP[[+HP;YC3Ž° ¤¥ª¢¥£¬¦´³±¨¤°§ª¸¿Á½±©ºª§­°ÉÆÈÐþÀ½¹¿À½É¼Â¸±°µ²º¼¹À³µ¼­¹¬£µ¦§¬±¶¸²¦§¹µ­´¼¯¼¥­­µ«­œ©¯¤Ÿ¤¬ª¨œª²¤³¨šª§ª¤©¢©§©½«³°®©¤ ¯œš³¢–¥›¥¤Ÿ¥š™¨ª¥žš©¡›‘› ¤™—©ª‘™š’‹‚…}ƒ€ˆž‡€~Œˆ’‘…‚”š“†“¢”‘‹‘›“–‡Š€rzy~|hv|{uqq~j†z…ˆd_hcr…{mgy]^VBW{mTaPRYKLNpt]IZ[hYFVgOC>KNDCA9HGKS?jaIQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11&/>KI1%90%,,09/,,+6'17#-/GjI14X=fbAJ7GS`U*=<F\@*Ž’°™ŸŸ©¤¢¡«¤¶²±¤©°¦­¹Â½·°¤¹¬©¨°ÂÈÉÌ·½¿µ¸ÁºÈ¶Ãµ´³µ²½¹º½¶®¹¶¿­¢³¦ª«®´·´©œ¹»¨±¾²º ®´¶©«ž­±£œ¥¨©£›¤°¦¯¡Ÿª©§¢ªœ£¨ ­¼§®±®¡ª¢¤®žž¬¦˜Ÿš¡¢›Ÿ›™£ª¢š™££•–”Ÿ¡–œ–¦¬ŒŸ’‘Œ‚Š€€{š”Œ‰}Œ‡‘Š†’—‘‡”£Š’‘‡™”ˆ}zl}vyxbzzrpqsxj‚uk‚gcgansŽmbjo_pA]ykV^NQQKIMSYVM\^lWEXaO^PHMDF;7HEKO<rhJK9AE;;==;;=J49B<3;G<4?18-78;2(09/,5..=-*L>*49&'.34.0+/4&,:$40AhZ13S=e_DL6KVdN)=3R]>#‘–«˜Ÿ—§¢¡Ÿ¨¤·¯­¢¯¯¨¬¸Ãº´® ¹¯«§³ºÇÊÇ¿¸Â½¯´¿·Ä¶Ã²°º±²À¶»½·ªº¸¾ª¤µ§¨ª¯­¸°¨˜¸¼£­¾´´¡­·µ¦¦¨°³ ž¥¥§¡¤™ž¬§¨ž ª¯§ ¦—¢¨Ÿ°¸Ÿ£±¯¡«¡¬¤œ§¦¨š››Ÿ¢•œ›š©¦–›ž¨‘˜’™“™–¡ª‘›ŠŽ‡}‡‚Ž||¡ŒŒ‰z„…‹Ž…‰“šŽ‰•Ÿ‰•‚Œ—‘|…|tp|qst`xxjoqqpksdzlhedaf‡€`[rjrMN€iXZMQLKHPRPGM[_oTEYZRgOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23/:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%53=fd24M?e]FO=RZgH*?0][5(•›¥˜œ•¬Ÿž¡¤¡·«°£´³©©ºÅ·³®¡¸­­«¯µÅÇÀ·¿Â¹°µ½·¿»¾°¬¾°³¿²¼Â¸ª»º¸§¨µ¨§«¯«²¯¤˜»¶¤«ºµ¯ž±¸¯©¥§¯²œ¡¤ ¤£ –›¯¦¡Ÿ¢¨¯¡ ¢“£¤¢¶°¡¦±«Ÿ¬£®˜ª¥¨Ÿ˜š£“š›š¥ªš››¥•”—•œŽ“—¢©¢‘Š‹†zƒ~„‹y—Š‡z‚ˆ„‰…“˜ŒŽ–™‹–~†—Œz{prvnos_xwellljj…ofrikfh^ds`[kviZJ^\XOOKHHRUG39]^lPEYUYeMIIEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<"8R=*113>D5,-'42*;+139cm74GAf[HTDU]hD.<2dW,2”¡¡—”›ªœ£¡¢¡·ª­ »·¥¬½Å´±¯£µ¯¬¬®´Ãü³¿º·±³¹¸º¸º¯®À³³¸¯¿À·­½ºµ¦¢²©§©±ª­± ™¿µ¤§´µ¨ž²¼©¨¥©°¬™¢§œ¤¥”— ²¤™ž£¨©œ¢Ÿ’¤ ¤¸©¤§®¦ž¥¡¨“ ©¢¡¡™›Ÿ‘™›–Ÿ¡ª›š˜ ”‘”–™”“¤¨¤‰Š†y„{„†}‰Š‡z„‡ˆŠ’…–““‹–”Ž”{ƒ˜‹w~|ltrllsawuhhjggp‡hhicfjj`kcjh[f{c`StT\[RLJFIOS@!*h^iLDWU^`KIHEC.:B<F<6KPD8:D357==895?:;4>8@K=>93)8><:9*6@3.E4(+,?0-N?.+-7,1195,&.5-80576`tA3CDg[KWGU`hB379gP'2ž¢¤‘Ž¤¦šž£´­§ªº¶§¬ÄÁ¸°¬£¶®§­®¶À¿¼²Â¶°®²¶µ¸¶¶­ª½³®²±¼¿·¯¼»±¥Ÿ¶ª¥¥³§©­œÀ«§¥¯³ª¬µ»ž¨ª«±¥˜žª¦¤‘˜¥¬¢˜ž¤©¡œ¢œ–Ÿ§µ¦°ª®¡¡ž¡• ¦Ÿ¡ š›™›’˜“¥¬¡—–”“•—‹˜›©Ÿ’ˆŠ‹ˆx…v‚‡Š‚Š}…ˆ‡†‘„–”Ž‘‘‘Œ“{ƒ•†s~~fyokjkfuskcgddvbefffjjckr[_Y^mdaNiXZ`VJGHKMRX>9_lhHCUT][IIGEA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A=-5B37=++,0B*JK./*+3722(57$+7.72685]yN2>HiZLYJVbf@:3BhH%5š£ Œ­¡—— –¤³±¢²½¶¡±Æ¼º±±£·¬ª­©¸¼»º­À²®®®¶®²¸³©«¹±¯®³¶º¶¯¸½¬¦žµ©ŸŸ¯£©®œ¡¿ °£®±¯·®µž­¯­®¢™§©¥Ÿ•š§¥Ÿ™¤¢¨šŸš”œž¬¯¦º¨®¢¡š›ž™ž¤š¤—ž—›“˜Ÿ’¨•ª§š“šš’Œ•™Ž””š©¦ŽŠ‰Ž{sŠ˜…‡|‰‰……ŠŒ‰’„”›“’‘—Ž€Žƒofymhkifqrk\hcctbfgjnlgkjhn]llsp`TcicfYIFLMOXQQUae€UAWSYTFHFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24;6#3*)6.55465Z|]19Kj[M[KXdd@A1JfC&4‘¡›°™“¡š©±¯Ÿ¹¿µ ´Â»½º±¦·¯§­¤··¶·­»®¬ª«¶©³·®¦²µ²®©°¶¶°³¶º¦©Ÿµ¨œ¨ ¨¬š§½˜¬¤®¯¶µ¬­Ÿ±­°©¢›œ£«¨œ”œ§¤š©¢¤–šŸ››¤ª«ª¼Ÿ§¤ ˜š™¡k¢–™œp‚•š£u‘©§ž””žˆ˜š€–Š¡y‡”Œƒmi~vƒql†‹†}…Œ‡p^cag„˜…k‹Ž”’tw‹„~ƒ€g‡€guheW\hsmNPjcgs…h_efnmj^_aŠƒ„eNKD9GTh^JGQPTULHR`oteF[QUPFHEC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=A@@=28@E=1,+08=G701.*.*/568,#1'214:175Xl16Ok[N\K[fb>G1Qd=*.‹¤™†•°››“ ›ª­ª£½Å¯©·Â·½½­¦·°¥ª¢¶³±²±¹¬©¦¬´¥¯´¢©·¶¶¨§¬¶²®´­³¡©Ÿ³ªž £›¥¦—«¹”¥¥¯³·­®¥©®«¬¥¡žœ¡§¦›— ¥¥››§¦“žŸ˜ž¨©¤¶°¤£¢–˜——£ˆ¡Ž’š† ‡“œ ¥¥ªž’’š‘ˆ„sxŽ…ˆ¡vˆŒi—ˆf}sx oˆ‡ƒ~Ž|¡  ™€|‡žt‡Žu›Šl‡ƒmieczlraS…mbli˜qXiqpˆX^i[ll[ˆrnzr…g†„Z_GN?G_MERVVQQSWTg]MVHRROFGG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82).1<I9/01.*/(-4583%&2115>1<8Xƒu25Rk[N\L\g_=K1Wa7/(Š§—ƒœ«œ˜˜Ÿ©©§ª¿Ã¯±º¼¶À¿ª¥·¯©¬¤²´®®³¶ª¨¥°­¥´²›­µ¶µ¦§¨²°¬²§­ª ±§Ÿ¢¢™ ¡š¬³”£¥¥¶½¦­§«ª¬¨¦¡ ˜ ¦£™™¥£¤˜œ¤©–”¢œ““£¥¦¡·¤¤ £˜•“—’œˆ¯—”‰©‹–¡œ…±€£¬“™”y‚Ô¨€‡•Á›Çyx±¥·—d€Àœ¿y„„y‘„|‘Êr—¼œÅzrµ¦»{€m–±«°yhlX±®nei½’¼ngzorØ~Skc¶²r”sš¡ªWOWbOVNFU[XQPRŒ\W[PA\DQNEGI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>:B<?A8:J>52*22BE/.32.+/(-/186- /416A1=:Wƒw21Tk\O[M^g\>L1[]41!Œ§“§ªŸ—œž¥¬²¨°Â¾²µ¿µ¶¾Á«§³¬¬©¦®³©®¶³§§¦´¥§·­œ³²¶«¥¤§±­¬°¦ª¦£°¢¡Ÿ–šžœ­«“¢Ÿ´º£ª©¢­®¥¡šš¢§Ÿ—›§ Ÿ˜ž§§‘œ¦š“¡¦¢¡±£ŸŸ£––’—’™…¯kjŠª~fƒ•†­dp”™¦”q®¡¤~x»}k¡v±_j´[¥€eœ‘`f‚{fjxk©e¾rg¦Œu±j|±xt’”cnm§n[„¡Ehf‡–Euœ`~g|¤§‚Z_Œ«h€•xyj§7J¯\XSld[KNX_\WV;N‰OWW/ITSJCFF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3..53/+/(.0.:5/'$203B/=;U‚v2-Vj\OYL_gY:M5_Y30¢•ƒ­§¥ž£¤ª±·¬µ½¿°¶Ä²·ºÁ¦©°ª®¨¨¯®¢°º¯£¤­²£¨¸§ž³³°£¥ ©¬¯«¯¦§ž£¡¯›¢š–•–™š«¥•š¡Ÿ´³¢«œ£­­ žš– ¢¨œ˜£Ÿ›™¡¦¤œ¢™— Ÿªž¦¦ šŸ¡–•‘–š…µ›µx…©™µ™v†³›·~“––©”~k‚¦{‚†ˆ’”’w«gk±\«z†”t‰r†€ˆ—x‚‚‹˜‹ƒ „°vwŸqlll|‹N¤XHbb™~ch¦`yruS“‡^P©mcq~‡€bœ.Q¡o[Skh`LK[dX\ZB>±yWXA#MhFCEA@A19>88:84;:9<9:A:E::;6:CB8=?KNG:5:AFB@AD<FD;0201;F,0.840,.(/3,>831/2-D1<<S}n3+Xj\OXM_gX7J9aU50• •ˆ³¦¦¡¯©§³¬©»¶Â°»Á­¸·¿©¬­­­¦­±© ®»ª §´¬£«´¤¦²³§£¢ž§ª±§°§¥žŸŸ®•ž™”••—« ™™¤¨µ¯¢©©¨ª›•— ¥¨šžœ¢ž›Ÿ£¥£•›ž—™œ¢©›¦™œ›¢ —“‘““œƒÕ“™¹p°Á~ņ|֔›»|š•¥¤{Ž‡¤‚¥‚z¬yV¯zˆ~Ÿj¹Z¹v†ƒ}¦‚“|˜zªxz±nŽ„t‘¼…o”P¯§ÅŠQ zc`©bsrˆm—ˆ`Sµ´È†€‰|c¤3Bv]PjicP@XgZdaJHMnN\QOYfYCD?E?0=<59;74<<8=:<C:F::?6:@C;6@OLH<:;DHCBCD<EF81211DC./0483+-).323971#%5*>3==Qwj6*Yi[K]O_fT7G:aP71%›¢”™²¨¨¦´ª¥´©¤¼·Á°¹¿±µ´º²´§±¯¢°²¦Ÿ­µ§š§¹­¢¯°Ÿ³´°¡¤žŸ¦©°¨´¨£›ª•˜–•–”– ¨œ™–¨­°©£ž­¢¨–—› ¥¡˜¡¡¡¡š¡¢§›ž ž”˜š¦ ›§•››Ÿ¡˜’”ˆ²nhµq«‡nŽ¦r´sr¶{š—¤‹¢‘¡¥~°vƒ‘ÒÒv\®{…¤o›ª¦k†„|­}—™Ž{°r’Žx³e—t„žožf”QȋZÂ\Ÿyb_­`vs‡b—ˆ^Yʝo¿uMKµSUÆdTQjceXAOk`lhPVGI9=URZWXIC?J<2?;5=<46>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>HI91746A>/.24252-).26,742&60;5:=Pqh9'Wi\BOT_eP5G=aL620¢“¥°¬£«¼­¦´¦§¶»¼²º¾¶¶´¹¸²¥´³ ±±¢ž«¯¤—¦¹­¤±°›´¸ª ¥¡©¤±§¬©£™œ™§•“——‘‘¡¦Ÿ•’¥«°¦¢–“­ ¥’” ›¤¦Ÿ•š¥¦¡š£Ÿ­™ žž•›¡œ¥••š¢Ÿ•˜•‘›…¬{w¨v£ˆ†©o­Š‚§ƒ˜˜¡‰’š‹¢“š‰®…‚³\r³R®}‚‚¤q×}x…~Ž…ššv¯†‰‘œ‡w´ašeš‚‚•m’Z°XKšu˜yf`­^vwˆh˜ˆl]¯w•žxl5yÈ®²_BTo^g`EPl`pmVVM.fdiSYP;AD@L:5?91=<16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK96<46:>/04333.2..18*.32%!03767=Pke>&Vg\@>V_cN6GC`H:99 ž• ¹°—´Â­¨³¨©²º·³·¾¹·±´º´¤·²Ÿ³¬Ÿž¨«Ÿ”§µ«¨¯±ª­´¤›© Ÿ§¡µ¦¦©¢˜”¤ “’›˜‘”¡¤š’¦­¯¦ •™© ¢‘¡™¨¤ •™¥¨œ¤ž­¡ “žš¡˜™›–—¢ ”—¦†©}}¥x¡Ž‚ªp­‹§†–Ÿ¡‰——ˆ£‚‘ˆ”ª|€‹xo±Z¨‚‚ˆ ytØv‡s¨Ž›’¤|–Ÿ„{²^d ~ƒ•m’\«[Z“€‘hgªdr{k˜‡s^«Z‰ ŽkoeOJC¡\[Lt]bgN[a_rs_KV7J›”XGE=GFAM35A8.;>05A78@<6=<F?:<6?=B7.HVJEAH6KIN@IK@EN::@5.;>102144+*05/7,&21($$6671<PeeA&Uf[?2U_bL7FI_C2?8¢žššÀ«˜´Â®«­©¥´°·°µ¾¹¹±°µº¨º´Ÿ¯¤¤§§ž“©°©¯©µ«ª®¡˜ Ÿ¦¤£¹¢£« –›¡Ÿ”“ž™“—žŸŒ‹¨°°§—›¨¦ŸŒ’¤—¨ª§”—©§žž ¢­¤¡ž¢Œ”¡˜Ÿ ’ž—œ•ž¡•–Ž«œ®mr´s©‹uŠ§s´xs³€‘¤£’œŽ‰¤‡w¸oŒ{‹¢jk¶Z¡…e——i¡¢§m“r´t“˜²j…’ˆ­ju³af¢o‡“k—\­_M¡|‡‘Rs£ly~o˜‡r]¯V<œwfTon.\§OcSkebmZc]ap{cTZR>>mo3CB@?M:!7@6.;@37C58??3;<CDBJFMIF62JTKEBI6IJP?HNCFP=<E50;;010/75,+,426/#00,,289/9N`eD'UdY>/U^aL5FM^81C8¦œ›Ÿ¼¡›²À®­«¬§·©·¯µ¿´»¯®·¶ªÀµ¨© š¥£¡œ‘ª©§µ¢²§®© —›§Ÿ¤«¸¢¬š•™Ž£¢•Œœ ›˜œŸ‘“”ª¶°¨™”›¬ª—Œ”¥˜¥¬¢‘–ª²£Ÿž¦«±™¡£˜¢–Ÿ›–œ–¡“©œ”«™‡Ô’š»s°Ã€Ã†~Ֆ›¸xˆ˜Œ—‹Œ§ˆz¤¶u}wv‚š²`ƒºyÀ|u¸cµ‚Œ‡©|•¬©q{t¼ˆ§ ia¦Ž¯¡~Œt‡ª}¾os¼t²ƒuxŠnšˆrn¤t½^w}Zay¼kZV\jy^jaegcmxoZ\YCA@s@CF+5G"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-7A9§›ž¢½¡—²Ã°­ª«¬±§·¯¶Ä°¸°­¹®­À°«£¡ž£¡œ›©£ª²¤´¥¬¥ž•™ª˜¦¬¸œ¢­—”Ÿ¤Ÿ’Œœ¢—š‘•’¯¹²¬–˜¤¨§”–¤œ¤­ž‘ ¨«Ÿ›Ÿ¨£³Ÿ£¥Ž§¢”¢šœ˜•£˜¯ ’”©ž„˜¶‘Œ·•x‚“šµwmknsoy…ŠtŸÁ»½š{±¨q€s‘¹ƒ|††Œ‡|Š‡Œ—|¤»¹½œuz´£tw—vt°u™žf†jµtrqw¶Œ^z}‰hƒynzc‹¬pu…X[§jEeZTf`c^cQggpluCNPMD:ZM?J3;0 8>;.3=A99?=;<C6BSYZZ[[Z[^`b`]SGGH4DITAKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7LT_G'SbW8*O^]=+:VU'>;<§ž ¢¿¥–´Ã´¬«¨¬«©º®°Å­³²­µ¦³¸«©¡¡¥ž ™“«¤¬©¥µ§§Ÿ›• £«¤½¦¡©–“›¡š‘¡§¡“œ—“—”±µ·­™ž¤¤¢‹’’¦›¥ª›•©¤¥œš¡¨¥§¤©¡‘­Ÿ–¤ž———ž¯¨”›¦¡j}i›¦x‡r}™Žtyd‡{½¾Àºo“ƒr–ˆ`rjZ^›‰`cˆ•k`€•cmwb•l€š•”e^`cqšŠir‹}†•gkrux}~b[wthP\nƒ}{‹kXkz‚sJJo†pNtMEX]gaL[Xgc_O[muiqRQDEM;GI=M?2,2A?8/5?C<9;@;=C>RVVWYZ[\\]`aaa`\UG5DFUEJOHFPIIH;8=51:.0;:.0-76=5&"/*2,%;8-7JR_I'S`V4)P_L(3>[O'?2>© ¨¢Â£›µº¶£¬¥®§§µ±¬È«¯²ª³¢½°±¦Ÿ¢§£›™™«¦®£¤´¨¤›—” ›¦­¨½§¨¤”“š•Ÿ™’—¤¨¨‘˜œ°²¿¬œ§ž§¢‰“‘©š¨£›š« £™›£§¬£ «£š°›•§ –”Ÿ—°¥˜¡§™›œœ¢£˜¥¡™›™™™•gm}qw’˜”’…‹µª†˜•ŽŠŒ˜–‡”•Š„“”‘‰Ž“”˜”˜–š ¡šœ”¡Ž‚z¥…mk}‘|€uŠŠq‚xyvvŠ€|Škstƒuew}wkozm`c]phMYZfj`WZoymmfTPFS9OZMQO(+:KB635=@A9:C><ENSSTVWXYZ\]`bba_^^[TKCSGKNDGPLOI<:;389,2;820)6IRO8")+/2#4;*7FO[J&R^S10T^:+=8\J,<-@³ ³¢À¡¤²²¶ ©¥²§¥°´ªÈª¬¯¤´¥À¦³ ¤¤œ£••Ÿª¦¬¢£¶«Ÿ˜–•Ÿ–­©¥Àž«£”‘›——’“¡žž¢§’’™¨§²Ä°›««Ÿ––§ª›œŸ¬˜¡›œ¢¤¯§¢¥¨Ÿ®˜—§™™ žœ¯ œ¡¦•—’—“Ÿ •¢— Ž–“ŠŠŽ—®|–œƒ’‚‹ª©…€™—‰„žˆz„‡†š’ˆ†Š–›—‘˜¤–š“‘Žg¡³¯…Š„v{’Š}wyzofy€‰kuzˆsis{vƒ‡‚kudyf`jfcdfkYl{oik]SLPD^TE@?>,4@F;45;>A;<?>>HNNOPSUVVXZ\_bca_]^]^]XVJKLBIOMRJ;<:786/2964.(&$-1./)+*7%+<(6CMMD/T]Q05M[17E4[G5<,@´ ¹¯¿¬«®²± ª¦²­¢¬³¯Ä¯©ª¢±­¼¢³›Ÿ¦¢¡œ˜—§¥©¥¤¥²µ”“™™¯¥­¾ «¢‘™˜””¡œ—¨œ„žª«£´È´ ª¤«—–—™¥©šž£«”žŸž ©¯ª¦¤«¢®›Ÿ  ˜¤žœŸœ¯£˜ž§’—–œ‘£˜—§œš—e‚’|e~šcyŽmhk{’¤ªje›˜}g†Šeeih{Ž¡kg˜‘£wkj‹™£Ÿ˜slnz„ŽˆzXf^†ƒ^m‹‰v\hswv’€ˆ‚nx‚x€smy„tv‰ˆƒ|k‡Y^ltd^s‰ik|qkd_RNXIdXAJ4>G7?FD71<=?AD;;DGHHILNPRRTW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%/*+'6*$;'/AJ[J/7ZO6)EY/DO2YC;?.=¥Ÿº¼º¯¬´±ª¥¨­®°¦­­°¼°¨¦£­®°ž¬–Ÿ£¡™™¦ªœ¬£¥§¨²­ž”£¢¯¥¶¹¥®¢ŽŽš¡™“’š ™™¤•{¥­¢¨´Ä¸¥¢§¯Ÿ”¡ž£›¢©¨’Ÿ¡ž ©°««¤« ªœ§Ÿ§ ¬–¡›¥°¤—›©• š‘£–©—}½ƒˆr´r„†­hx¹Ä¸q“¢£z¦™™r«‚|ËÀÀ»qŒ£ˆ‚Ÿ}—™‰À½‚—žÂÁ|‚|“šÃÀ}l¥²oŒoÊz›w‘ƒŽvy€yqz‡pw…Œ“ynx”cg`xd`e‚c^tglddYLVIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^__a_^^^^___^\SMPGUNA??=6468276*&%#)*&.+*)109*#>I[L*#BP.#F[3PY/VAB;/8–£¹Ãµ°°À©¨”£¯¨°®­¦²³®©¤¥¦¯«Ÿª˜š¢Ÿœšª§¢«¢¤¨¤¤´£œ¢’¦­«·³§®¢‘‘™œ¥’‘Ÿ¡—›Ÿˆ¦¬¤¬­ÀÀ±¡©¯©—‘žœ¢™¡£ª£“¡¢¬®ª­§¤¤§¡¦¥¬¨‘£š¨­©šœ¨›« ••¤• ¢–œ~Δxz¤y•–›_®^Ž§¢ |§–›s«ƒ€¯^cŒª{¨‡… u˜“ˆ³c‚«†¡Ž³j„¯u}—ˆ·aƒ­Z£Ínv{Ú{™p~‡’v~e{ˆvvk|‡n}†‘‘~mƒarmph``yd\qhjdg`RTSW]KOC5AHDD8>6;@?A;=8@>>?BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5578164('$!',&&/(&+360$7;SL+,-K0';\;L-!P@F4.1­ÂÀ¿µ´°¸—‘£ª§­³«¦²««ª£ª¦¯©Ÿ¦›™¤—œ¢¯Ÿ Ÿ¨§¢¥ Ÿ°¬š•§®¬°ª¨«Ÿ”‘šŸ¤’ž¤—§£Ÿ­¥«°¨Àdz¨©±®–’œš¡—Ÿ©©Ÿ•¡Ÿœ¬®¨¬ªœ¨¨¤¢«’¬²–¥¢ªª¢¥¤ ®Ÿ‘˜¦™Ÿ™““— q…Œ—u…¨†q±}žr¬~¢Ÿ¥žv«‚}­œr­~«‡†Ÿv™’{|—~ªˆ¢Œ’Œ~«{‰”Ÿ€{­WÅ{p“Á}•muoŒmeve†oawnro‰Š’ƒn“‘fpuuqagme_oiingdXS]aYRSC9II@D<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;91478452&# 1' 1' '45-&7=WJ-<'>1)3W@F!G:C1.+°ÓÆƲ´ £Ž£¢¢¬¯¶®¨±¦¨ª¦­««¦¡£™¡•Ÿ¥«Ÿ¡¥Ÿ¨¨¢ž°¬—š–¨§®«§¦§ž—”™£¡‘” ¬š¦£¯¬¤¬µªºÎ²­¦®¬—”›œ¢™ž®¬œ— šžŸ¨±ª««›­«¥£«š®±¡¨«®¥˜¤©¨¨¯¡‘•¢£™“‘„¤j¤u‰z©tz²p‚¦Š™Œq‰ ›‡¤``R«…®ƒ›v­§†…Ÿz™—†{f€£‰¤™†‚£}©~‚–‡®_|©Vž£’z£Ÿ€{ïŋr¯³³¹rb©¯ÂthŒŒ˜Ž‚nœ•qozxypmgeerpf|ic]W`jXYULLQLCCAB;C@@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^aa`_^]\][SIB6799664,&$" ('"+-"$.!3-&@DWH,G+56*1PKL# A9D4,'ÂÉÕÔ¿¡™«§ ¯¢ž°´°®©¬¢§¦¨ª«©¤¥Ÿ›¤ž¥§§£œ«š¢¬¡£Ÿ¯¡œš’«£µ¯® §š•“¦¢š¢§ŸŸ¥œ±¥¤¨±­·È²µª¬©–’œ›¢™Ÿ¥³š¡”Ÿ¦¬­¤°›­ª££ª¡³­¡ª³±¡š¨§­®´¡‘”¢¦—š‘|©lž„‡u«y|°o‚¥Œ‰Ÿ–– •Ò¸´¸É²_`”©ƒ¤‰‡ z˜–šxªÉtš¤•¨©‘“šœŠšÆÆyg¡‚¥tŸŽ‚}¯]p´b°uK£‡m§G‚“dž‘|q™•q|u~|n\fjsqfk^aYdm\_YIMLKEDAB>A<B?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75685/)(%&%$&),4ENPPMFKJVF*L0/=-5OTQ;<F2,$§¤ÀƸ­¨²­¬¥¢œ²¸¬ª¡¥š¨¤ª«ª¦Ÿ¦¥˜ª£Ÿ®«¥ ¬šž©¥œ§¶ž¢—“¨ªµ²¬›¥œ ”¥¬‘™œ§£Ÿ©§®¡¥§©°µÃ²³ª­¨“Š—œ¥›¡£¯¥—¡•™œ¥¦­œ±ž®¨¦Ÿ¬£·¬¡²¸¯š®¦±²±£“–¦¢™žŽ‚NxšŸz„£}ƒ¤…‡¦ŸŸ”„¸{{y¹‚Ìƶx›¡‹Ÿ~š–—Švž˜Š¥˜¤©°…† „¬}š•c¦m¤p…}–‚r¬`£sq€š`¼}RUtŽ’£–{~”“Œv{s†€q\nnxrjo[d_inbd^LLQTAIHFI:9K>B108866877-*5==?BDGILNPTVXYZ[\__^]__]ZZZXUSOH@882.,*.+*''?QTVWWWYXXWUOUF<E3:P[T6?H,- ‹‡™©«¤«¹ª®Ÿ›¡¬²³¥ž •¥­­®ª§œ¦¦š£§¡³®¢©¦² ˜©¤”£¶¢¢•—¡©´¸£›¡œ¢’¡±™ž›¦¥ ¡¯®œ¥¨¢¶²Å±­©­©‘‡œ¨œ¢¤œ¥—ž˜šš¦¤«›°¢®¤¦˜¯¤»¬¡¶¶­œ´±·¯±¥—œ® £œ…ÑµÃ·y‡Ž…‘“€¦y”¡wŒ ’„¥Šqª†…´nrj™£œ•Šž|˜™†‡s¯‚¦œ£Ž¦‹“‹–›nq²]¥t“zœl™{™|m©a£qqŸbs²¸hw”¦˜}Ž•Žy~yƒnjyizso€u^eeomfg`J[XX<HH@U4@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^__][[ZXURRQF:223//++(@QRTUTSTVWWXXWUUVTQOQ[U%!2AH$)%’sŒŠ­¾¿¼º´ž–§¤­µ¡¢™”¢¨¦®««˜¦¢Ÿ¦  ¶§£¨§°£”¬£Ž¤­¢ššª³³¤œ¤œ¨‘”—®ŸŸž¦¢œ§µš¢ª¤¶¬Ä°©«©¡Œ„Žœ¢ ¦¢•™š™›™¦¥¨™­¨®£¥›­¦½¬”½¯¬Ÿ¡¯²¸©²¥š¨°¢§—y¨‘}|°wŠ€¤¥ˆœm²p¡‡­|¡ƒ§•˜€¬‰…®…Ÿ”ª ¡—†Ÿ€™•€{’~«€›–‹«x¡’Š”’z¯^¤}¦§d€}—sj¯]¥kp…™]`[Œ m•‘¦™ƒ–Ž™Ž||„™€knctn€z`gfqnhghCYa[>KU3U8BBC7$$3+''3, /6674359@CFIKMNQRSSVZ]_a`aaa^][ZXSPONI7042.*,ATVVVTTUTUUTTUTSTVWWXVUUQHFIJ#((½“šƒ¨Å¶À³žš¬ ­¸¥£Ž›¤¢Ÿ°°ªŸ¤Ÿ­™ž¹ £« ¯©™®¡«¨£–‰š®°¬¦ž¥›¬——¬¡ ¦¡š¤®˜¡¨§·©Á¯¥©¤ž‹€Ž›šŸ¦ž’”™›”›š¦¥¦›ª¬¬¤¥Ÿ©¨¾¤–¬ª¢ «²¸©¬¥ž²­§¨—u¯~‹œ…‡~º­Š™e°e•­} ƒ¦•š¬Š„°…¦š¤¡¡„ \lj³`­{{ƒ±mgo™™Œˆ±[~µ\¤„kÈ¢dŸ€{¼XvµY²}R®€z¬X€¡m˜¨›Œ˜’šš|z‘Ÿeu~c†xt|ajgpmgefOUd\AU_>I(>9=4!",%2. *1/045799<ACFHJLNPQRTWZ^`_`aa^_\[XUPNJFC553./@UYXWXWWXWWXWVWWWWXWWXYZZ[\XWWGB;ҟ²±·½º³Á²¢œ¬¦¤µ¨ Šš žœ³³©Ÿ£ žµ™ ´¨ª¬ž¯­¬›•¯§¡Žˆ›Ž¯«¨¦¡¥™®’˜¨™¡¥Ÿš££¥™ ¢ª³©½°¥¨žœŽ}‹›–¡ ˜‘šœ’š˜© ¢š©®¨¦¦¢¥©»ž Æ¦¤¨ ª´´«­¥žº¬««”€©’£¯Ž›€‡¤—™‚€¸ÃºƒŽœ’„§—œ‚¬Š‚¯ˆ§œ›¦ª~սªb£¿½}~£‚ƒ×º¸µ…•“ƒž½¾„m£‚o«„lœz²°Çƒi«°½¬xw¢¾¼s€–Ž¦‘›’š {ƒ“œ{d~{egy‚{alekjcPb[Sj\?TaCN)=:4/$%2 $(0496677;>ACFGIKMNNQTW]a\__a^`[\YTQMHC?=A?5=SYYXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ¼•³³°¿¸±¼²¢œ®¦¤²¦‹˜¥Àª¸²¨¡¿¦§²œž±œº¨Ÿ­¯¥§””°«—Œƒ›‘®¥¢¬ £œª —‹£’¦§œš¡©£™Ÿ¡¬­ªº®¨£š–’|ˆ™‘¦›’‘˜™˜”©›¡™ª©¡«§ £ª»ž¨Ä¢Ÿ­¢©³³©®¨Ÿ¹¦­­™svª¥¸†d‰ ph®‘Šnnw¤™Ÿu®˜”p‹q•¨£›—®¤rlllf‹xon‚™qzjqigŠ—–˜qii…ˆgq†d]ˆbjoY\f}v¦_aqŽ‘ned“¡˜™™“š¢~‰‘–vgˆxiky€yemcflbKeXJlZ:PeER'K:+# #,)-2.5:457:<?ABDEHKLMOQSV\WZ\``a]][TPLHD=:AB7MXZZYYZYXXYXWWVWY\^^]\\\]^]^][[UW^©”¬³©¹¸²³ª©¡®£²©—’¿³ÅÊ¿·«žÀ¬­¤¢§¬Ÿº£¤®«­¦Ž—®©‹…•–­ž¦ª ¤£ ‘‹¤’¦˜©š—£ª¡–¦¦§¯º¬¬š›’‘{„–¥˜‘‘™•Ž˜–©– ˜©£›±¦¢«¹Ÿ¯Á§£²¥«¯°©¬ª¦µ¢¬¶•Š¡¨¦·‰–£™‡ª›‘•’©²™š£ª ²–¢¡Ÿ¢œ¡¥¡•«§’’Œ‡“œ•‘™“™‘–†¥›˜–Ž‹””Œ†„}g‰~t‚us‡Šp§lz”‘“’•¢—šš¥„‰—sj‘wqŒxw}zjmdcodUaY@j\HcaOY+F=+'!750.!%2(*699469;>?ABDEJKKMPPQXUVY^`ac]^TQJED>9=@ASX[\YWXXXXXYXXZZ\\^__`^^^__```_YY`¦–¨ª¤´¶®®¡°£­Ÿ µ±Ž¬È¾Æ¼º«£¥žœ§Ÿ±©£¶§©´¦¨‘˜¬¢‹‡‰œ§•¬¤Ÿ˜§žž’”£–§™¨š”¦¡¤›¨™¡µº¨«™šŒ|”‹¡”Š•‘–‘”˜¦ ›ªŸœ¶£¦«·§®À­¢¶¥®¯¯«¨¨±· ­»˜‘¥¤¦¶¢’ž§ Žª Ž’Ÿ£«¯š £¯¨¯˜£ œ£ªžžžœ–«“™¡›”–«šŽ™™—‘–Ÿ’‰¡ž–•…’‘Ž•‹€}f‹…u†ux‡‚sœj…”“‰}‹•’’˜”£“Ÿ™¤…Šš‰|s—s{Œ€s|jod^pj`[`ZndP`ePZ:GGE>2=>9/*&+)&&416668:==?AACIJGJKLMSSSUZ``iaeVPJACB:9EMV[^^[Z\[[[\]]^_]^__aabaaa`bbbdb\[c—•£§¢¯±«®£©¦¬Ÿ§µª¥µ½°®­¢£šzž£²¤¥±©—›¹¦£“™ªœŽ†Š‰œ¢®ž¢•¨Ÿ ’–™›­Š©–¨™©™©ž¹¶¤¥™œŒˆy‚”Œ›“Š•’”‘’—£ŸŸ©žŸ¸£ƒ¯µ¢¯®t£¼¢±ŸwxŸ¨°¹”u¬£ž‰€«d\bv ¥Ÿ„—}m’³œ£§­ª¢ežŸ’syš—p€˜¨˜m¢¨Šeœ¦’˜˜–’œ’†ž›–„’‡’‰…wjŽ†v†p{…`h‡Š”’‹Zu”ghs{¨œœf{›‰„y™j…Œ„oz€kre_vqlkh\ffbbpS[>NNNSG>@UD:1/&4:306678<;>@AAFHBGFIKMSTUY]`hfhXPJ<DG<8UR[`ab`^__`aa_\]__`aabcdabaaedchd^]f›•¦£ ®°¬«©¥¨­¢§­¤’–«¶±³§›«§¬—sŒ° ¨«§”—¹  œ¤‘‰ˆ›žŒ¬š¢•§¡Ž–’ž„u­ˆ§›©‘—¤‰œº³¨ ™˜‹‰uw“–“Š”‘‘””¡œ¡§™œ²•€Œ›µ³Œ’Žº¦ ~§¢z¡­µ€Ž¥žƒ‹†±ª¯ŒŠ—¤›z€‹¬†›¡§¨§‡•…˜w¥›z‡œ—§‚‚{œ²zŠ†¡˜š•˜–ƒ‘——…›™bz‡…’‹ƒmpŽ‡y€p€„~…s…„•‘x–h’t šu}™…£ ‰˜”Œ……škŽ†lx{qqgdwojlk\ekjft\^ITLR@E6.ZUU7)!09>>743568;:=>>@DI?IEJLGSX[Y\bahfZQH9DL;>aV^bdfd`aa`bb_]`aabbbcfgcba`edcgcaahœ—¢Ÿ¦¬­«¨¬ §¯¦¦©¥™”¯È¿±¢—¨©¶ž„¬œ§¢ Ž¾žšŒŸš |†™—‡¬œ¡–Ÿ ‘Œ“‰†€‘§‡£¤”˜ž†žº²¨žš’Ž…qv‰•Š”›Œ’Ÿ’—¡¥–ž«‡Ÿ´‰´š­ŠÊ‡©¬ˆ¶…°¯¬‚¨Œ¦˜}¨r{wœ§—h•¤y´ŒŸž¦§’˜Â«ˆ˜¡rž€š¥}—…•²¡}¡”¡™—”œ‹™’‹}…“‡Ž–’‰ƒmr…~yq†€ƒ{ƒt„€–€Åf©‡£kž…¤…šŽ‡‹šq”…hxu|xhhvphhl^dplgnYgG]RM3E47Nbd7&3<EGD:64658;8>==?BM?NIJLCPZ]\Wa^il\QE=KM@JcX]cfhgbbbbcc`_babccceiicbbbecafcbbi”–¢Ÿ¯§¨¨¥«Ÿ£·°©«¦š” £¤«¤—¦«¸£¯€¡¨¦ž‰”½™“¡’žy„––‘‡«™›œ™¡„Ž‹w›œŸˆž¤œ–š˜‡£¹®¥šœŒŒ~bm‹“˜Œ‘’ ”¡¡™¡§~¡§‡­ –­œœ…€ Œ©­…£©™Œš¢u€™”k‚­vM«x‡œ‘š¨¦€©«}ƒ¡{z§jž’kg—†—·‰ž~n`dYƒ—€{dh‹r™}y–l]}—m_Rpƒ\_kx‚_Xd|ƒ–p§ªkƒ£nr¥pŸ… jg m[oŒ}gZ`„€bXPowfmtrkjo]jplljYiO]YF9A5HD_l5,IDRMN=84859;6@;;>BO>QRLMBJ\]_W]^bu`MD:MONTb\\ffiibbdbddbab`bdcacikdbddgdbgeach—• ¸ ©£¦¬‘ ¶»ª®¢™˜¡¢¥­®¡ž¯µ£¨’¡  §œšŽ™´™‹ŸŒ•‹u”’ŒŠ¦••™žž~’……¬¤‡›Š™©™š›’ˆ¦±§¢–šˆ‰€inˆ‡‹ŽŽŠ‹’Œ‘“£”Ÿ œ¡¤“¢¡” vœ•§‚ ¦…§«ƒ¥x‰|„š~¢ps”ˆ–|Ÿym†›Œ™›¨™Ž‡{‚¢sv¦fž~w¤_˜z}“t¢n˜·´ºt“ˆƒ€µ¨dÆ¸{p•¶Œr€š£bs¬«`|i³~m|†‚‹˜q£lr£tŸ…¤a™³–r}˜Ÿ³us[ž²ƒjbotvqioXklrsg]i^bLE=D6QBZs3=SG`JR=<395:96D;;@JP?UMOQ@E__[ZX``|dHC8MWUWbaZefkkbbeadc`ab`dd_`cknccddhdbgfchh“•”£·˜ª›“Ÿ¤¶´­­ š¢¤£¦®œ²®¬“˜¢š¡¤™›•Ÿ«›‹ˆ’x‹…q€–ŽŠ¡’”˜}‰¨ ‡—Ž‰’¤”œ›‹©¨¥ž—‡…~j{‡~}ƒ‹‘‘‰”¡ƒ—ž  ž‹‰wœ˜¢Ÿq¡Š‡©‡›¥Ž”¦©}­Œ~z ™z£“xt–ˆœ}–Ÿ†›Ž˜›¥…¢d¡|ˆ–›mžh›Žoš™z€‹§}rit«ƒŸƒtªh•š]›…v…žgªk€¸f\¨pœ`•Œ^§vu‡ˆ~žhšu†“’—Ž€Ÿoš‘n§š]©y»k~ª\Ž„]´g\nrzxki\qjxyd`fXbBQFO7WCRo5L[[_NZDA251<;6H?:CHU>YRY]>Db^V`Qac}jEB9N[^YdfXfgnmbbe_aa__``ec^bdoq`deekecihgki•›‰©´š§ˆc”›«¹±°¬ž¦œœ© Ÿ¯œž±©­ž—¤›¡ ™—— £™†‰jˆ€r{—ˆŒ––„‘•˜zŠ„•£œŠ”†ŒŸ’‰©£ šŒ’Š€i†y—Œ{‰ŽŽˆ—›”£Ÿ ¡“˜rhŸ‰ŸŒp’Œ©‡˜ž¡¥ž¦{°­£¢¸—w£³£¤€ˆ”y{«™~¢Žœš–ˆ—q¡|…¯µ}kš‘¡y~˜µ¢¤«¨„™|›}ž›tªZ]o{–‹xžbL{z…cy—BLŸX¢jq{Žl€ˆ„™u›x†‰±³€›“§wƒžns}•pštk¤]•vHed`tq~~of`liv|eeaQ_W]TW@ZFQhETW]bX^ID=B8?B:IF8LEXAWR[VDFb\Z`K`m~rEB<U_bZeiVghmobfg^aa\]^`hb_ecvm]egfkdflihki“œ€°­™„S^ ¦³¹²²©š¢Œœ¬œœª”¢¬¤£¨ ž›š–™¡–ˆ‡‰w†oy•…‘›‹|‘“–ˆr€ˆ’¡œs‘‰š•¡›…©œ›•‹‹‹|ƒl„…q‚¡Œx†ˆˆ“™–|“¤ ž¢ˆ­†}µ„Žž{¥–z©•›‰Ÿ›|§hwm~™t¡sr|†™p“ƒ®}¤ƒ¥™€£o^©gu¢co¥aœÓ}{™xssb¢†~£t¤vk³Œ`‚˜‰sª²¨¼wƒm~¿¦©´]›n|p–mr¢r]¤gs¦`h¦m›Ôš~†›pz{˜lœ|x—sn©¤g`ezq€…lhfdnuxh`cS\fQQbHYJUaWT\fk\eQFCKMJKBKE8O@QNXSYOSQ`ffjRcwywIFEc]eZhjTihjocjg`c`\]]_hbaie|d^dgdkdjmghlh—š¯ªT\K~©¯±³¯²£›™…™© ¡¤Ž¦©¡™ª‹›™™”™“’¡˜Ž‡…{p}„h}ƒ”š€w‘Ž‰o†“’l—“|‰’“¥—ƒ«›”“‹†‰yƒv‡€n‚Ÿ†w€’†ˆ™£˜{”£¤™Ÿ‰³¡¢¶‹z¬§¤®¥p©€šŽ…€š{¤€¡™†˜rž„¤®¯Š—Œ€¤•ƒ­ “vµ¶µÉ¡s”‹Ÿ`ž—©my–‡ ›t¢ˆw ~“—‹pMf£’p›‡s¤{ytaƒk~ kqd_œq}s–hyi³µ´Æ¦s˜}zkœ›«v…›mvx˜jš{u˜rQE}³_jvkzˆfkhcuuqnW_TYiPShIWMYTV^iloVhWNKAJMKHJOAQKPecjmetrsy|nu‰{{TQOl^i\kiRjhilhlfce_\]]^ibdik{_]dhcjfomeile¡›ˆ®¥ƒd?“¡²ª®¯µ¢¢€—ª¢£¥Œ¥§ž¦ƒ›˜—Ž—œ“Žˆƒzjy‡eƒ˜ yu‰Œi„…’ƒŒ…y‹–¦“„™ª˜’‹‰z€}‹yp¡†y€•‡‰– –”¥¨œ••ƒfnxœl¢d{q¥w›˜pg¦€•Šz¤zŸ–ƒ—sžwŠ•—¹n‘Š¢b}™ •ˆnriªku mo¦`›i‹i–‡›–u¢~š`Œ†upˆbh ež~i›uocfˆmq¢Z^[b¡m]ˆ‹nz}srd¥mx¢dg§h™sŒ™p¢oU‰o _f¨T‹^T˜nmskr‚mpilytkpRYWWfZTmIYO]IXiiskYlWQRFV\LXSaUik_wt{}p||rƒ{€sv€„v^RrbgcpgPjhhklnhdg_]^]`jbjivu]\chcjjsmfkmcœ£—¥ydsm‹¦­£©°±¦Ÿ‹€˜«Ÿ¦Œ£¢›£¢–™”Žš‹˜ŽŠ{‡q€ˆi‹‹|˜›su‰~{dƒ‡•ŠŠ•™‚|ˆ‡—¨‘£­‘†‹‚Š~€€Žsi¦„}†“ˆ™ ˆ“©¦ˆ¦x•›~¤ˆ–‹±˜‚¯—Ÿ¥v”†x©s¥„šn¤¢Œ’„ƒ»n}¥¯ƒ†…†“•œŸ|¥zr¨• –gž~o¬d–Š–“w¨mª¢‰v‰ƒw«‘¦ˆk‘°kv³Œ©kŠ…mmŸž’•`~«‹ªv~~‹¥žvŸ|ƒ¤• j›ˆx¬hž­Œ¶tw¾¤“Zƒ§Ž«aurtp|uqckoimSW[Vab]kM]R]J^mow`[qY\`[gtenorcrt`wz~yryƒs„{{Œ‚€vbxdcnrdRkgholrjfia`^\akbmlzo\\bibljxmglnb•¤©œ£–©©¨¦®¤™Š‚˜¬šŸ¥Š›¦©…›‡œ‘…’Œt‡{ˆ„o…~˜“tt†s’‚m‹‘‡†“Ž}{‚†˜¦Ž§§Ž‰…•v‚‡’ol‹©ƒŒ”Ž‰Ÿ‰Œ”ª¢Ÿ€u”—ˆ~y”®¢›q†wŽ‰‚}{r§Œr~}z˜–›„y{~‡”•“Šv˜ž ƒ{}‰kŒ…[yyrzqin~’‰q€u”“q‡„‚eŒ_‹wtr”uoynm‡l„…^ugwŽe€€…¨š}t{•j‰ˆpv}‡wnnhŒsz|˜x…\lXyioxrqoxxp]k‡njgV[`W]fkdVcU_Q_pyymkwfkkkw}rrutaovbt{‚xuz‚u€€€x‹…ƒ}{nldyn^Wnghukxjije\`Zcjemqtn[[bldllynhloa“·¨¦‰ ¢š¦£˜¤œ«¢¡„„˜­’ž¡‰›§›©˜ƒ‚œŒ–”‡ŽŠ‰rƒ|}~…{˜tr„q•…{}’‹††„y~€‡š¥Ž|¨¢Œ†…•ƒ†Ž˜wr„©†Ž’‰ŸžˆŒ›§ŸŸª„‰Ž•š~~‰–­§‘¦wo›xn~¨…q~•qkp}‚ €“Ž‹hl\‚‹‹›šžŽs•‹ˆqtk‚wtYrn‡‘~Œj]jd{†„‰€`ixzš{‚Šu…gwŠ†japqt^qŠˆŽ¥”…e‹ƒnw‹„q†zqhhe|„{–[\khnv[|yxunssƒg\m‹kkbZZ_[Ylq\_aZ_]et|vpudkkk|}s|yudnuhm|~wz|{yz€€~o†Š„{}t~yshT\qilvpugkhd]aXkhkkqrnW[enlgszohjm`‹Š©°¡¢¡šž—ž˜¨£¢~ƒ™®Ž •ˆœ¢‘¥•|˜†}’™‰‰†‡Šs~Œv…Œ‚„—Šro€r˜†ƒ~’ƒ„†‰€z„Œœ¡‘ƒ§¢ˆyŽ—‰•‹‹œ—„ƒz­‚‘˜š•Šž‡ˆ¡ªŸ¡¢£‹ˆ“›œ£™•ª¡§¦Ÿ’š‡•Œzvƒ§~’“”²¦›•Ÿ±’—ƒ¥ŒŒ•šŸ‰›‚ˆ‘Šk|Žwxeƒ‡‘‹|‰ž„‡Œ‰ˆ…„w|zt™ ˆ†‰‰„“~}Š€€uor„‚~w…†Š¥‚…Œ†‚ŒŒ}ˆŒŠ‘„zmƒ…~z™ksiatŠq~zwwowt‚]^o‡hn_^Z]]ShrVd]]blhv|}topekji€}ny€rjpqlg{r‚€x}„{m‚Œ†|zx{}zƒxNcvjsnpzekecb`[tfpgrqmU]ltmiyzqgikdŒ‡œ¹ž–¡ ˜”˜™”˜¤ ž|š¬ŸŽ† ‹ž–}y•„|Ž™Š†ƒ„‡nysˆ~‰”„mk~z—‡„ƒ€‡„…|‡…œŸ“ˆ¬ „s‹†’‘‹‘}{ª„Ž“˜–œ–‡‡›¥Ÿ¢š…‚’šš˜™¦Ÿ¥œ•ˆu{†„¥{|Ž‘†™«¢ž”Ž©€Œˆ“™ž‚—~‡Žƒox†ru`„†u™ƒƒ‡……„•nyvt’¡Š‹…šƒ„Œs‰{|rqz‡‚zw‰ƒ‘¦…ƒŽ€ƒŠ‰Šw†‰‹Œ~qm‚|ohlmh_zh~|vuvu{x\_q~nt`c[]_RgnTe[^bkivzrlmdkjhltlluozp†yn‡€v‚€~…vr‚ˆ~{||{‚Š`h{juii‚djc`i\cuhobumlUcqyepz{sejmm‹‰ž¶™ £Ÿ’‘•˜‹šžŸž{xŸ§‘œ‹‡¥•‹˜™yz…|‰‘„Œ‚‚ƒn|€ys…~‹‘}kh}‚—‰ˆŽ|~†„†|‚“‰©qŒ‹Œ’† ¡Š…Œ|¨‘ˆ’—“–“x£Ÿ –™€›™’Œš¢ £™—š}Œƒw‚Ž† ~ŒŒ|˜¤¡¢“š‘¦Œš‘‰’—›~“’~‡Žut‚qwa~€Ž†r‹–}ˆŒrŒ‚…†hxrx‹˜‘–}ˆŠr†{|pwzŠ‚xx‹”¥’‹…{…†‡„vƒ„‰‰|gs}€y{qmkg_~sh|uvt|s€j^`tvpwdcY__RkiUeY`ahjvy‚qgkdlhf€€kn~hoql~y‡zlŒs~tv‚†|{€}irƒntia‡hlb_qVtomm`xhmWjtvcuz{rbjoz‰Œž±‘¥¤œŽ—†œ ›}w¥¡Ž˜€£‹ˆš–y{†‡~ƒ‰‰‚r{tvƒ…~Š‘xgc~†—Š‚ŠŒy}€ƒy–‚–™˜—¡œpŒ‚‘“†¥›‡Œ‰ƒ¦•…“‹–˜“’w‘ ¡—”–y~Ž˜˜Ž–šœ£˜’”šx„‚wƒ•~‰Œs—£Ÿ¢”™¢ŒŠ‚–—ƒ’–™~˜|ˆvq~n{d€|‹…q‡“€‘‚l‡ƒ€‰…fuo{…‘—‹|’w‹ˆ{†{zq}wˆƒxƒ‡‰—¡•ƒ‹vˆ„ƒ‚w|ƒŠ‡x`zy~txgmeajjwstv~q|cc`snurmaZa^[leRcYaahkvy†qckcmfh|ƒmiuhnpi€}‚ym†r€ƒƒ~t|ƒŒ€~{‚ƒ~|mv‰sumeŠljbbvV„ipn`xglbjvpfy|zq`rl†…›­—¦§žŒ—‡†Ÿ“—™~xª‹™z—‹Œ˜y|Œ~|„|ƒxtyzt}€„€‰‹€d_}‹•‡…†u}~‹}˜†—•˜¤¢™€s‡{“‘‰¦ŒŽŠ“ ‘ƒ’•—‘‹—Ÿš‘s’”‰ž¦——Œ”•r‹Œ‰k„—™z‡ˆ‰o—š¤”•‹ŒžŒ†‘œ’’•†™ˆ{ŠŠyqzlul|‹~n†“ƒ•xq‚„~~‹€eri{–—ƒ~s‡‚x†}uw|„{‚‹ƒŠ“£xƒt‰‡}€tv‚‰…pb|v{r}pbocd|cnpvsxwstbv`olvno\\_^^j^P]Ycahnt{‰l`iekciw‡nglikmh}{woˆs€„„}t†‰{ƒ}z„}}Žrz‹xxml‡jh_irc‡gqoewgnlayik}{xpaxm‹€˜˜©Ÿ¤¨ŠŠ’†Š‹•˜~x¯™—}Ÿ”‘—“ˆw~{Š}|€wx€€put|o†}Š|a\~‘†€ƒƒs{€‡z’‰“’•¦œ–‚}}ŽŠ‘£ˆŽŠ˜š†’™”–ŽŠˆŒ’œ’ŒŒn„‘ˆž™¢ –•‰–m‡˜ƒe…˜Ž“z‰„Šp–š”£“’‰‹™Œ}’Ž’Œ™Ž{Š…‡ssvlqnu|Štn†‘“qu|ˆ|eply|™“|ƒˆt‰€s‡xn|€…{„‹‡‚‹”§Œz†{~Š…w~qp‡…fizuvq|b_pakt_qj{yylspey^nlsmrX[_`ak[PWXecgqqˆg]iigbgqodiheiizwuoŽ…t‚ƒ{u‚ˆ…x…|x„…z‰w‹{{rxƒjk_pht€kromrgole|cn€zwqlwwŠ~¢—¡§ ¦›‡‹‹œ‡“v‚«•“Ž‡¡–”s|v…xyss{†kspzn‹v€ˆoq[Y~‘‡€vu€€€ ‡’‹”žš¢•˜xŠˆœŠ†’˜–…‰•š—‹‹Œœ‰ƒm‰‹‘Š–¡›—”…—‡iƒ¢e„œ‰~‹ƒ‹w“˜’Ÿ“‘‰‰”~}Ž—{‘ŒŽš’|Š€‚ovplmop{†itƒ™‹qw€u‚ˆƒyfrnu€™Ž{‡ƒy“yu‡so‡z„ŠyŠ…‡š¢†{ƒu‚‹wynl…ƒ_tusqqyZ_qapk^pj}{qmmjmv`ookqmYYbabnXQTZfgcup„ƒc]kndcfk’n`gg_hkursp‹€uƒ€yv€‹€y…xˆ†wƒ…|†‹{vŠjqc|c†|nqmtjholvx_qy|uut€ƒ~¤•š¬ž§–…„—”ƒ vŒ ”“‡‹›–Ž‹yqxt‚pr…tqvˆlpnvmˆvƒ~€nnUQ«•‡ƒxwrƒzƒ ‚“‚•”š“›x’{ƒŒ’£™“Ž‰•™’„‡—™Œ”‹‰‡„Š|s‹…ŠŽˆœšŸ›•““}h„›†g…Ÿ‡‘„‘‚‰qƒ‘˜œŒŒŒw{‘zŽ‹Œ‘–Œ|ˆ|€kwjnkll{bz~—v{xƒŒ}ygsls†•‹~‡…z“qyƒov‹yˆŠyˆ|Š„{zv‚‹|wqjl‚„{ayqnmrtV_pbra`mozqhoffstiqkbwe]Wf``rSQO\fe]ypˆ}`\irbbef‘j_he[gp~pkqtŠ}v|†€uv~Œy{…xˆƒs†…~ŒŒ„|y•xfrkƒ`ˆ~ookz`jntu_t}y†xts…}x ™°›¥Ž‚‹ƒšˆ€ŒŸ€‹š”…ˆ˜Ž„vtwt€qp…tpr„pkiwnƒn}}musRM‚ßȒ֓{pu„v„ ƒ”w–‘™‘™{”s…ž¡““‰“œ”†—–ˆˆ‘Œ‡›Ž€wz~‰ŒŠœ›œš”’yŒuf‡…k‡¢„‘ˆ—ƒ†cŒ‘™•‹—ŒŒŠŠqz”ˆ{ŽˆŠ’‘‰z†|m|esoklzz[yz~€†Ž{zhrjsŠ‰…„|”Šk}~m‹}Š…|ƒx€Ž”™™Š|uwƒxrmgq€…nkuphjunS_oepZ`lrxgkjbfxrpqc_w``Vk_^vPNLagc]zq‰u]\evabeeŽdagbYissnkqvŒ|tz†‚uv~‹s€†{‰r‰ˆ‘‹ˆ|~˜vesn|eˆ~npl€Ylnyys`vz{vrwŠwyž‹›®š ‚…wˆ•~|Šžˆ† ’…Œ˜„“Ž‡txpyqo„omoseeyq}mz}jhkc¤šÁÜ®ð¡slv„v…£†“p—‘–¡•œ’r†‹¢—‰•Š–ƒ–…‰€‘‰‰–~‡zu‰x‡„Žœš˜˜Žv‰um…ˆ‰|‰¢ƒ‘‰œ„…^‹“—‹‰‹‹„‰m{–}ˆ…‰‘†v†~~k}dxvjnysX‰{’ˆ…z~†Œyeri‰‰‚~‹•„kum‡Žƒ}x~”’˜trw‡Œusqgvz„cunqcjvhRaqglV_otzard`i}pso[cr`bVnY\xNMLdfb^ws‰n\\dy^_ee…`cc_YjsknkswŒ}tw„xw{‰qƒ„}~ˆ{t‹‰ˆ–†Œ~—sgurylŒ{ntqWqzvyrewy‡iv€‰rœ†˜¦›£’„}qŒ”wyŒž……¡|–€™ˆ„{swptjplim|u_axw|qu|h`d|ëÚµÉÃ܇slt‚w‹›‰j™‘ž–”‰q…ˆŸ„‹•ŠŒ˜”|“ˆƒ‰{Š…vxƒ„rˆ‚“œ–”—…Œu†~oƒ‡†˜¡‚“Œžƒ‰aƒ”‡Š†ŠŽ‡‡i|“}ƒ„‰Ž‚r‡qwhvsjtwlZ}“ƒ…}€„„Š‚varkˆŽ‰~~‘}mkw„Ž„‚{€|~‘•ˆnpyŒ…tkqlsy‚aujo]lwaRerifS`pvuap`]hƒqskWghbiXmV[uLKLeg^bss…j\\ey^^dg{ad_]YkofojtxŠ~ss~{vzˆs…ƒ|‡vwŠ†™Œ‚{“ulwvyx“tnx{}Xy†q€ogyw’ƒdv†…pŠ–…™ š¢Š‡to’Œqwœ~‹š‰‰} ƒ™€xrtnodrifmxx\`y{{qq€jagaÕ¶Ž‘¦xnqw|q“‘ˆkš‰“Œ†{i‡‹™†’‘†‡˜Ž|Š|Œ}‰„ztzƒ{q†€–šŽ““ˆu‚…t‚‰‘œ†”Ÿ~ˆb“‡…ˆ…‹€€ƒg|€~‚Œ~mƒ|ƒulmwuuxvlcŽ€…~}†„‰p_qo„{Ž‹{~ˆypƒey‰…Šz„|~’‘ƒmny‹~umnkl{diljYnwZSjsibQcrxmcf^Zjƒntb\h_dl_nU[pOHOge\goq€mZ\cs`\clwee]]Zklcmjsw†qp|}tx†x…‚|€‡uy‰’•|‰†vˆpxy{„“on{w^ƒ€t‚mizt”sgsˆ|q’‘ƒ™ž› †ˆvv”mw”˜ˆ„‹Žš|‹šw~vqpljau|gbjuz[`x|zmqechgW_qs–¼Ä„wq”Š€t˜Œ‡”ˆskˆ•€{”‹„›Œ|Š†}|‰Œ“‡tˆ…vv}‚qu†ž•†”‚‚q~‡sƒzˆ–›–†’œ€ˆf}“‚€†„Š‰r}g}‹{y‡‹}i€}„vfpyxtxtlk†‹‚‹yƒ„„€k^pwz}‹‡…{€Ž~r€hx†‰„‚w‚z–‹Ž‹|mkzˆ|vtoih~we]qcXptSTosibNhuyga^]Xo€otYec]jm`pOYlRDThbZlom{oY[^mcZcowdg\]`kjcliswƒqn~{tuƒz„‚|‚…v~‰–‘xƒŠtˆsyy~oo{qj‚yz~nm|v–kjx„tk“Œ…ž˜ ™…ˆo~Œvjy™€‚Š‚–˜ŠyŽ–ozsqljd`t{i`fr{[as}zgpzaedŽ±²wKbZ¥Úїr{’Œ‘y–Œ…š’†ol…’‘yy“†€„™Š|‡€yx‰Š„•€oŠ‡qt}{jy†ƒ¥‘„“Œ‚n~‚u‚w„š—’Š“”…‡pz’„~ƒ„Šƒoxh€…xrƒŠ‡|e|~„vcqs€jzqou™†„‹|wy€„z‚k\o|r†ƒˆ}…‡zˆq€mp‚…‚ƒqƒw—‹ƒwmm~ƒvzehj~raZxZYrnNXrtf`Kmwub^\[Yu}rpWg^fjq_oNWiS?Yg_[pkgyq[[YkeYcpy_h]^elhfliqx‡om}vp‚{€ƒv…‰—Šq‚q{†|zy„”Œukzlp~t}or|{”po€yf’Š‚¡˜‘ƒ†g‡„pgz—Š~€…‚™Š|ixrllf_aoym_boy\dlƒzaqv_deÕ뾋2:>‹Ž€ry†‰w…™Ž”Žnm…Œ‹u}…‚•‰|ƒxnv‡…‚–wn‡„ku{teyƒ„§ŒƒŒƒ}msu‚x„š‹‘’Œ‹‡{’‡x€…ƒl€si€~xm|{Šƒxby„‚rdqinvru‚œŒ€†tv~€soZk}sxˆŠ{†|ˆwypk‡‚Ž‚‰q€w}”‰Š}tmjv€€uu\iiyqZW}SZrfM[srf\Jqxp][[Z]uuiYb[genbiMWfQ=^f]^vf_uq[YUodZdpy[h^`gmgjkipx}Žmj‚„€yn{}‚zu‚Œ“…p€‹nw}€{{ˆ“‰€i{~kt|r†{sw}Œzx„~|kŒŒ„›–Œ‚l~khŽ|~ƒ”‚}Šˆkuqgic[cgso`altahp‰zast^bc› n\5Z¯µuj€Š~“‡wˆ˜‡uŒŠwpm…‚†ty‰x‰}“ˆzsguˆ~}—oq…}hvynez‰…¥‡€‡‰}m}t~{Š—†’˜‰‹…Š|‰r|~…|i~mk{yjzv‚‡r`w‚~rdrgvƒnu|†•’‚}‚€pwz|u~mXm}usŠ†v†t‚‰zwrmˆŽƒq}{|‘‡ˆzmmhm‚un]hftrR\|N\q]O\spdVKtykXYYZaqua]]`fdhhfNZhNAad\`va\umXXSta[eorWj_bhkgmlipw|“li„Š}|p~{‚zw€€‰‹„r{‡oqw„{‰„j~{nxywŠw}x€‚‡„~~zm„Œˆ˜£…„{v‹zkm…‰’y}{‚’€€}Š„prpcf^Yg_pp`ahpfjo‰tato[`djv{¾œ§¤É¸r…„s”}yˆ”„t’Ž‡rsp„z‚su†tˆw”‰yyqdw†z€’hq„ufwvdj|„ˆž‚€ŽŽ}q~rƒx~Ž‚w•Œ”ˆ‚ˆz‰‰lyzuhzilysizv€ƒ}h`xˆ}kjth{jv‚‘•|~~q|v|t~bUu{qrˆ‚‚{p†‰wxoo‚‹}|w|{t„uhpglˆ‚rp]hctoLfvL^oVTZtnbQOtybRXX]ap‚s[a]heecjdQ[qIDdb\dq^\xhUWVw^\fnhVl^ajgennhpwz“niˆŒy}s{~y‚‚|v}ƒˆ†ƒpvƒsnw‚‚~ˆ‹”q€|xzz‹tƒx‚„z€uo}Š‹›žˆ~†{w†{gu‡‘z€|‰†„v€gpn`e\XfYmsaaaqllh‰n`siX^cm€w©Ú©Ç†ˆ³rŠypŽv}ˆ{”‹€utu~vopm…t”†xul`yyˆŽeqƒogun[m}“€y’’}wzl…tŠƒr•‰‘ˆ††{†muvmhwfm|vmjwv|`bx†zhuvc~|hu‡Ž–}u€vr€z}m€YVr}os‚†~wkˆ†sxjt‚‚|y{wyqŠ{rgsdm‹„ls[j_vfIooL[cXWVymbPSuvYQVX^`r„o\`cmdc]ocT]rGBf_^fi]Z{cRV\u[[gkaVk``nfflqhpvxtkŽvvx}wƒ{t~ƒˆˆƒoququ}…‰‹{wx„|}…‡x‡|}}„€{~rvx‹ŽŸŒ‰{Šwuƒz^~‡šy‡„t†‡„w‰{bnm\b[[aUjtd`[hopg‡qaqfW\ck|Ê·º¢kno‹mr„r~†‹{’…zytzutzjlvc„v’‚vog_|y‹ˆeq€jjqcXm{†œ‰ƒ‚r—“w}{m†o€‰Š†p–Žˆ†Œ„{yrrp~ghrcnxqjlqw}|y]ez€xiuyg‚whuˆŒŽ•}s‡jo~€xn}]Wp}ms~‰{€mnŠpvfv~~€u{pxr…{xqer`m‹krXk_x]IplNWV_TU|kbOTvrQRTW^bt†i]`kjfbYnaXcpGAh]af_\V|^OVeqY[jh]Xha_rfjhqgqsw‡yn•Šu{w~yƒ‡€us……Žƒpp{xwuy†…‡Œ†z|u‹~}†„„‡~~}†|xvyv’”Ÿ~}‹nu€zd„ˆ˜†t’Šo……‚zƒucnjY_[]]Uhse`YdrrgrakdWZ_ix¾®zŸ¸nbt‡iu|rz„‡{~€wxswozvejoa‡uŽsjb^}wxŠ‚ep}hkkZVox‹¤…p™’qwt€l€†r“‡Œˆ…‰…}yusoiyajmamvjgkkywzw[g}|yfr~n…tfv††–€p‹gk{ƒtlub[nzjszŠ{€et‡|mpgt}v|~pzjxyxwoelal‰}lnVjaxVKklOROiNY}hbOUukMQTU^fv„g]aqhgaWi\\kiJEjZbeWXUyZNWnjY]le\Zec^tfleqfsptxp™…vx|…‡}ut‚‡•ƒnsy{{sr…†ˆˆ„y}v}„‰Ž„ƒz~‹ƒ{w|wvš˜zŠƒ‡jv~}l„†•r‚q†‚~‚€oflgX][\[Tepe_XcruivpdebW[[hpor€sŠefzjuwtt„†x‚…zwtvnkzpahkg†t„nf^_|oz‰}hmwfjdVWspŽ§}„|v–s{q{xlyzƒu—|ˆ†ƒ‡„}uqsmhu]mi`mudgfizo{sYgvuhpx‚vbw…‹}•‚oŒkm{qfse_kxfqu‰z}auƒuikqtyoxwr{e|}~wunce`l†|mkVjcrTLjkPLOpH^|faNVtdKOTXakw~f]gsie_WcWcq]KKkXdbUTUsVMYveZ_l`\[de_wgmbpitoq~ut™x€x€†„z}v‚ƒ~˜…nrt|{tq……Žz‹ut€}”Ž€…„|~Œ†z~v{£¦Šy‰†…lu||u„ƒ{o…sz…}‚ƒunjieV][[ZScne[Xbt{jimh`aW^Zi€ilo€gmbi{zktuuo†‚z~wvn{hjyj_enhw„geXavi}†ynioff]UXoi¨wz|Žxtn}mqtx~w”t†ƒ€…‰vjsvhio\me^ns_gbjxh{m[mƒstjo~zwaw……z‘†sˆrpzrcqh[mvdor‡zwar€ogixsqkwvsub‚z}vuocbbm||kkUibgTLnhPHRlEayfbMTr_JMUYelx{f_mpjc]V`VpoWJShXg^XMUlTK]z_\_l]][be`zhlaoovnowuz˜}w€y€€‡†zyzƒ}“„qtt~zvt…ˆ~}‘ls•{‚Ÿ…‡}€~†‚€Š{u„¬Ÿzˆˆ„lr‚zv‚un‡o}€tŠ€jonedX_ZZZUbjg\Z_u‚i^ml\aW[\kequ}ij^mxwhuxsn‡|~~zvslzhiwg]dsgzw’ccTdof„vvfhjaWVYhc¨owŠŽzpo{fwmyŠzvŽq„}‡ndwtehi]lb^pp[g_muezh]t€nrkq{vubu†Œ|‰ˆ€xru~taplXpraopƒztcq€k`lznihywspdƒtxxtpd`cmr}jlTi^_ULucQGWbGcwfaLTqYKLXXhlvzedmqfcZX]XwgTJ\cXiXXHWeQIcx[]_m[^\bd^ij`otxmonvƒ—yr€}‰Œ†~uv†x†Œ}tuu‚yzz‚ŒŽ}…‰jt–{Š}~…y€{~|†‰sq®Œ||‡~fqˆzt~}vro†l|~mzcppbe]eVZYWcfk`]]s†iYqn[^XZ\l{bqwvlc\ntuhuwqn†yzwootehte[gufvv’z_]Seej‚s|aci\TW^bd¥iyt‚…xlmyfwl{ƒyt‡rx|y€iewm`ga_k`^ukYf]oobze[w|knopxytuesƒ“€‰ƒ‰zvor}raxcZno`op€zseq€d^muhcfxzrkm€sr{qqa^emn}diThYZUNy_RJZYHcudaJUnUJLZWilr{dllsbaYZ[aw]TKc]YjSVGYaNHjvX_an[[_bc]…ihbnxymojvynƒ~€‚’ˆ„vu‰tŒ†tqvvw}}~Œ“~px–ƒ}™’y€€xy~s‡„sp™¢{{‰–yeuˆzsywltply|p’s^poagblT[ZWidmf\\q‰eSrn[YXW`kudjujj_[ntrmttuk‡}}wonldipc[krdtvŽs\WTc_p~q\bc^SZa\d“Ÿerq…ƒskjxlnnyyzq€vs{z{dfvh^c[ah\^whWb^phawa[|vjjrnxtttiq‚–„‡…vsjp|mfwW[ilapqxseo~Z`ppa^io|kjr}qovio`[dkl{afTgUXSQw\RPYRHdsb`GVlQIPZUklk|emora[ZXYlpWSPfWWiSTFZ\OIsuX`cncXaaa^Œjcemzylnivy†{k„}€…™|‚„y}ˆm†qovz}t‚‚}‹ƒƒ—tx‚”…Ÿ‰ut‚p‡ƒvo¢—t{†Œ‡{fw‹on|pgxq{lsvsk^tobgfkS^\Vhbll[\qdOom\VWUfhshctee^Zpvoqvvzlˆ}€}ˆwscdkoa\nmcsx‡kZTVbbv||p„\c_cTZ`Zc—•cnp‚…‰rifyndruqzkytuo{v_gsd\_WbdYaueU_`mdaq]]~ohisqtquvlm…”ƒŠ|…qrgn|oqoRZeidprusbluUbqj[^nd{dkt|qqqil_Xdijx^fUdUWQVoXQWTPHer_aFXkOIYTVnid|ikxkaW\U[tdSRVhQYgTSHZ[PNyw[_emjZba^^nbglyvnnivv~m„€~†—{‡Šk“ˆrgt€{u€ƒ~‰ŽŒ“s}Š‘…‡Ÿ†{†Œs€†s}‚un¤Œs‚Œwxnz`e}qgztylmqwƒgd|mdgghS`_Ug`lo\^nŽhMil`UVSoerkfxee]Zrvns{ysnŠ{€wœ{zkaelm^`njepy~gZVX_jw{zoƒ_b^gVY`Xdœˆbkp†|wkjvl[upjyiurno{sXko`Y^VcdXeqcT_biablZ`~kfltuomxvlh†€Š{ˆmqfp{lqlaX_ggnrsr^ilSepdUbmaxaotztinkj^W`fhu\dVbVTOYgSO]OPHep]cGZjNJ`KXme_xhn~d`U^T]u[TR`gN^bUSJ\ZQZvv]_fmhXca[^Žqchjxrsmhvsyƒs‚ƒ{ˆŽ~|ŠˆŽynŠtls‚sˆ…‡’„•z}Œˆ‘›„€|Œ„rstwqn““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~~~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’‘‘‘‘‘‘‘’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’‘’’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ”ÎÚØØØØښ„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDCGdhgggghMBCCDDE9.....+H…ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ”Ûéççççêœ~‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR4555549\`___`aA565557';ƒ€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}zzz|}{|~}~}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹’—˜˜˜˜™™’Œ‡‡‡‡‡‡‰““’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†…………†ˆ‰ˆ‰‰‰‰‡………………„ƒƒƒ‚ƒ‚…ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z||{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘‹Ž‘‘‰‡ŽŠ’“‘‹Œ‡‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…‹…‡‡‡Œ†‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰ˆ……†…Ž†‹ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰ŒŠŽˆ…††‡ŒˆˆŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ~|vvx||{|}}}}}~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹Œ‹„ˆ††ˆ…‰ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz|zz|||{}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒŠŽŠŠŒŠŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzyz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{z{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz||||}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||~~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰‡‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†…………………„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰Ž‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{~~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~€€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““”””””””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““”””••••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••”””“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””’’“““’’’’“”““““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}}~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘‘’“’“““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’’‘‘’’“‡…“‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘’‚’‘‘’Žu†‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ˆp„‘|uˆŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}}}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒsoŠ‰rx‡ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒvn{‚sx†ŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡smnƒztv€…ƒ„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\YXXWTPQRSRSMMJIFEHJGGHGGLNIgsuxz}zxwy||||~~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzoq{xy{|{xw{xuwttvuuvwtb^d_bkqfhklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkiffggghhb^ll]fggebcbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHIJHHHIIHIVpsuyz{yvvyzz{}~}}~~~~~€~€€€€€€€€l[YVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__ac_\_]`]^ZZkwmbnsjbZY_[XWSNMKKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{yvwxwz{}~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSTPMJMNPROM[krlamtrgQQSPPNNOMJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTtsuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMN\dokYisupSMOPPPONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKKFBEIVcgkopnmlZMLNMNOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€‚oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHECGHIN[gigrnnifd`__XLJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:;>IZ][]flnkommlkiikcRGEEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@:;><;;;=J[innojomkjllePGEDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnppsttsqrvxy}}}~}~~~€~~€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;:;;99:88;<979::=GbnsnnlklgTB?CFDBCC?;>>@CCA?>?A>@@B?@<?B@ACEFEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqtstrqtxxy}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<:79::979::78:99<I_stqfR?:;=@A@=;;><=<@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyz{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>><==?@===?C;==><:Bl}i>:;>=>?@@@>?A@@@A@@@=??=<:;==<?@ABBA@ADFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquutusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCDA?=>@A?@<\n@>DE??AD_d<==;;=>AA@>@@?A??=<><=;;<=>A@?@>@CCDBCEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVppqssttuyz{||~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???BFD><<=@=8:;mwH8;:=>A:Ie=<=<8:;??=<=;<@==<==;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIGHHHJIJKJJNLII_pprrrtuvz{}}|~~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC?>AAABA@YR<<=ILFFuwM788:;>?WjA;<<:;;>??==8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC@CryI;\ƒz|wW<=?==>EhtL:=>?==?AC@<9;A?>>A=;?A@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hloppqtuvy||}||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCEAGrykbƒ„ƒ‚ƒ€}^>@C@@=Js{Y:=AEABBFHC=<@DDA@?>=@A>>>?<>@DGE@>@A?@CFECBCC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{{{}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@Ent}‚‚ƒ~}„vMACE@?>Y{€]?CEIJJIMMKECFFGEGEEEDECA?@>>BFJJGEEGFFJNNKJIGGHKLIGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@EEhs}|„~y…rCDEDCWu†‡‡~XGHJLNOPPMIGIGHIIHHGGHHECEEEFFHJJFEGIJMOOMMKJKJMNKIHGHHHGFEFFFDFHGEEHHFHGHFQnnpqruvy{{{z}}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJG`{€w„…ƒ„‰lAAVt‡‰‡‡‡ˆƒWHJONOOMKGGGGDGGGGFHFHECDDFEDDHHCCCFIKKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrtwwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLLN[|‚‚ƒƒ…††ˆ„Vl„‡†††‡ˆˆ‡|OXdLIIGGDDCC@@CCCCFFEB@>>@AA@BD?>?DFHDFGIJIJHHHGIIJJIHFJJJJIJIJJJFILLJJKKfopsrtvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKLKJTƒ„„‚‚…††„‚†…„„†††‡‡†ŠvoiSM@>A???<<<>;:<AA@><998<<=;>;8;?AB@ACCB@AADDBCFHIHHHLMLGIJMMNMJJKKJLMSlpqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHHJIIe…„„„‚ƒ‚ƒƒ„……†‡ˆˆˆˆ‰ŒŽ~lbaR>8?@778896479;<:8567789787588;;;=@;999=<>;<=ACEHJMLLGIGORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@CGIIh†„„~ƒƒƒ‚ƒ„†‰ŠŒŒ‹‹‰Š‹Œo`deYAW=5655873568:876565676777:67889:7578979776:<@GFIFIFEFOSRSSROPPRTepqsttvy{|{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@6788=:=ECBe…ƒ€‚ƒƒƒƒƒ†‰ŠŠ‰‰ŠŠŠŠ‹Š‹Œ†jfkifQ7885588557699776765:9:::;798987669:98868589;A=>>BA?AKLOQPQOOORWkqrttuvz{{{}}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897;B:=q„€ƒ„„„„…†‰ŠŠˆ‡‡ˆˆŠŠŒ‹Š‹Ž„klkb?<>?99;<9:;9:;::9;:9===>;;<<:>;9;;<;<;9:<8::::999<?<<ABDIJMKIKLWorsusvx{{{|{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<:89989:::;?>H~„‚‚„………†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹ŠŒŽ€ml`EDFFBAAB?@CA@>=>>@???@?@==?B>@A?@?=@@@>?A<><;:;:9;?=;<==AACABCAXpqtttvz{{}}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::<=:;;==?@BRƒ‚‚„…„…„†‰‰ˆˆ†††‡ˆ‰Š‹‹‹‹ŒŒ{mkOKMKJGHHEFHGECA@BECCABCB?@DHECECEDAFEFDEFD@B>=@>=?@>?>?>?>>:;=<`qrttuwzzz}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>???=A@CDFW„‚ƒ„……††ˆ‰‰ˆ‡†††‡‰‰Š‹ŒŒŒŒŒ‹xmamdMOKKKIIJJIFDDGHGDCEFDBHIKGHGFHGEKIKIJKJCFCCDBAACBDCCDDCA=;=@hpsttwwyx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLK@BBA98<>;<;>@?A>BBGGIY„‚ƒ……†‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒŒ‡yyeaOOMLMJIJHKGDGIHIEEHFFELLMIJGGHIJNMNLLNKHFGGEECFFFFDEHHFCA?@Llptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?EGG=<@@88<;;=:>@>?@CFIIP_ƒ…„…††‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒ‹Œ†iRRONNMNJHHEJIEKIGKJIJGGGKLNLMHHIJMQNPNMOKIGIJHIDIHHFFGGIGCBACTnpuwwyzxyz{||}~~~~}~}~~~~~€€€€€€€€€€€€€€TDAABGHB?8?@9:<8=>;=A>?ADHJLUqƒ„„„„…†‡ˆˆˆˆˆ‡†ˆˆˆˆˆ‰ŒŒ‹ŒŒŒŒŒŒŒaTUSPPOLKHGCHJGLKGKOLKJJLMLOPNHIKLOQQPQOOJHJJLJLFGHGFFIFEEBABB\orwxyzyyyzz{{~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<9@>>@BGGAGKLPVy…ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹ŠŒŒŒŒŒŒŽ}ZXUUVUPNLKEFFLONPWUQPOQSRMSTOMSLPSUVRSRPLJMMMKNGGJFFHJEDEEBECcpuyyzzz{z{zz|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?==B@BBGVNFNPPTX{†ƒ……„„‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŒŒjZXlcGTRRQK;;RSR`u]UVTVYYRXXRZfPUWZ]RTWQOMRQPPQKKKHHJHEFIIIHIirvyxyxz{{|z{|}|}~}}}}}}~€€€€€€€€€~~SHJIHGGFE??AAEACGEDELXRMTUVXZ|†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠ‹Œ~aŠ‹‹‡n]eV;YZYTQ?@VUX\d`VYbr]]W]ZVEQYZ[Y_TYgRVVXUTVTOOMJLJIILMKOMSosvxyxwzzz{z{|}{~~}~}}}~~~€€€€€€€€€€~~~VJJIHGEDDBA?HMIMPKIKPTSSXZZ\\x…„…………†‡‡‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~‹‰ŠŒzopZ\]\SUSVVU[ZuƒYU}a\X]^WIV]][[_YHYXY[]XXYWRQMPQMMOSQQURassvwwvxxxz{z|}}}~}~}}}~~€€€€€€€€€€xy}YNKIIHFBD@A:PQQWXPPOQSTTXXYZ[n‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡„‹~gZZ\ZUWUWRQWVc–€RerXZW_hP`f[[X\gaGOZhg][\]]WROSPPRVVVVYZnrtwvvuxxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZ[SSQORRRUSVTW_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†~€|^RWYVSVSRQLOMKfy[]TYUV]ZLTZUST^ZXWWWzkX[\\^TQQPINOWVX[Zdprvvttvxyy{{||}~~}}}~}}~€€~~zxwvsu{€€tk~kry^[VUSROKFCDAN^ƒlVRSNOQOQURSRRUcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰‰‡†ƒ‡‡‡yorXKMOPMOLJKDEIEC>TdURQQNKQTQMOYRMNQSUUMQSRPOMLHCIHRTUZ\lquuusswzz{{|}{}}}~}}}~}~€}}~~€~{vsw}~~du}iqt_d]^\YUPLILIal’tPQSNQRQR[RSRQRUTbs{|€‚}{{€ƒ‚…†‡‚†††„†…†v`^ME@DDDDCAEPBCAC=CIGV@HNLG]iPHFNFDEFIGHBDHGIKGDBAD@OQMRdrtvustuz|{{{{||}|{~}}}~~€€€||}€€€}vt{mh|gnqfiedb\XSQPURsWe[OONLQSQUYSUQQTSOV`klrv{{xytrnstsyx~ƒ€ƒƒ‚€‚€‚‚lNH@A;<>@@?@?kPJ`EFHIEB?GLNGMQUIAE>?<=<==?=?ACC@?==B>JNGUnutustvx{|{|||}}}}|~}}|~~€€zywxwvvx{~€~}{xv|uaxglpjljif`[QRZ\Y^JJPQNKLQRQTVUWQQWUPX[b]agmmlokg`nrjmlqu{z}{xz||xwxeDBAB=:BCAADB\]O{NOONKLMOOQLKMWMHG@A<977599=;;;8:8:?<BH?\stuuuvwy|||}||}}~~|~}}}~}xuvz{zwyxuw{|yxuywcqhipmnmmhf^OP_]ZIHPRQOMPQNQRTVXSSYTOYZ[WY]^^_e`]^qvk^`gkwooljonnlfbYHGHHBAGIEEFDMRPaWRWQPSSRU[OOQVPMIDF>:96587979:365795<C>essvwwyy{}}||{|}~~~{~~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`VW^ZXMLTTSPQUOLRSTXXTTYRMWYZVXXVXY]WWXhsk]Vaskba_^da_^YTQNONLIHJLIIFCQPS[WTTNQSYS\eUOSTQNKIHC?A9998978857578599Gmrtwxy{{|~}}|{}|~~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPXVVSTVOOUVXXYSUTLKTVUUUWPSUWTUR]n^RNZ_[VY;DVXT[fJLPSROMMNNNLJFQPUYSTOJNOUST\VRUSROMLIHHF?><:787659967665Wppswyz{|}~}~||}|~}}y}}|~~~}||}}~}|rvqxxrvuqqnppopuvtnjddjppqrpofedc\]RTZVWUTWTRXXYYYSUOJGOPOOMRJPPOPNNOTLMIPOSTU2=XMI@Q=caQSQPNPQPNNMQNTRPSMILJORPRRSTQROLMKLLHCBA=::876;B5566:doqtwx{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqptuvcjgeWhtrrqniihpVVTUXUWURWVUZYXWUQSFEAFGGHFJDHJIGEHLHKHFLMPMG/E_R>3?>joaSRQ@GUQPQPQNQOQPLJLLOPONPQQNPOJLMMKGEEDB;=<<9=G6677Dmptuy{{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknaePSTRSTOWVVYYVQQQO@=;=?ABAC@BEDA@GHGHEFHJMLEGCORC8ENS]gTQSAGUPOQQPNMNMKLKKNOOQLOOMHLLIKKLKGFFED<AA>;@E;<89Sprtx{z{}||{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpknqmimcLOOMQSLTUTXWULLKI<987;>@><=A@B=>EHGCEFIGJJ@FAA@FHEJOHQRb\QPROSOOPLLOMLMLMON[WKMQOGIHCHJLLJFFFE?BC><BG?B?Adpswzz{{|{zzw{wy~~|{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCD=9779?B>;?A@@>@DIECGGIGIEBB?>=CBAGIDMObeQMONWKLMKLMMMLLONSdNKLRIIIEAHJLMNJGIGBAB@?EFEHDKnovyyy{{z|zwtxux||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGMMJMPMPOHJD?A=98::?B?<@BAADEGKFCHIGGHCC?B??@A>DECKNRTLJIMTGIIJLIKLIJMMOPRPKGCKGCBIILMONIJIGCCCDIJMLIYrmwyxz{zy|vrpurtxyvxjqnjllnttmtu{stxronqovsnporpopstyjN`gsjt|ygosqiqhdqHKDGHHGJKIJKDFB=>=99:;@B?=BBCCGFIKJDIIFGGCC;A@B>@@BECIMPHHKGHKDHILMHJLHIJLKM]RHHDNFACJJMLPMKMJKFGGJMNQNLbmivvwzy{z}rmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoiktgdoFKDFEGEFFGEGBC@><=9:::@C@>BCDEIEIJLFIIGFFDB;ACC>@CDCDGLNHKNHDHEILNMGILGFGIILNKIGENHBFMKMLOMMNMKHHIORQRNRfffqosxu{z|lhjnekqlspfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGIDFFECCBE@DA>?>:;;=:<>CA>ACEFJFIHLHGGGFEC@=DEB>ACCCDGHIGMPJFFGKNOKFHIFEDEIJHJIFHOKCIMKOMONOONJJILRUUROWd`amgproryzgehhdilgqlflmgiklslpvutpnvrosrsutqssutsuvvvyvutwljuumrvqlnlerLHEEHCBABD=BA>A=::=?:=>@B>@BDGJEIFIHFFGECBAAFFCBBBDEDGGIFLQLIOJJLLIGHEGFDCIIHKJGKRMBNNMPNOOMNOKKKOUWVUSX_^\iaminhrsbeffdhhfnjfmmhkkmriqvtsqmvnoqrswsrstuuvvvwvwwvtwujsunutsqrjksMGHFHBBADE<A@@C<8:=>9?<?B@@@DFHEHFFHGFFDCECDIECGEBEGEFGGEJMKHQMJKHHIEFHHECIIIKMKOSNDQRPPQNOMNPMLMSWVXXUX]Z]d`hbjigk_eefcgggkggkmkmlprhttursnvoqprtxqssuvu‚‘yvvtxuuwxmouorsuqqinyMHGHHBBBFE<?BBD<7:>>:>:@B>??CEFDFDEHEDECDEFGJEEJGCGHFHGECFJJGNKLKHJLFIIKHEKKLMNORTOHSUSPROQMNQNMPWZVZYVZ]YXa`a`^hec`dfhgjhhifhnllnmqpiuuxrrpupppruvpusuwu{~}xvtwvvvxplupmstnorrxNHHGIDBCHE<@EBE=89>>=<<AB<?>AAFCECCIDDEEFGGGIFGKHDIHGIGFDHKIGKHMKJKLHLKMKJNKONORUVOKUWSPSQRLOQPOTYZY\ZY[^^]`c^\ackb`dfgr…hgifjmnponsrjtuxrsstrnpqvrquruus~yŽ}uuvvvvxrhuqkrtlqvptLIKIKFBEGE<@GCD@:<?@?>?BA<@>AAFCEEDIEFEGFHHFHHIKJFJHHKHFFLIHHJGLLMLLIMKNMMOLPPQUVWOKVVUSRQQLORRPV[[]^[\^__a`ad]c`ef`ehjcssfjggkorqossnswwquvtsmoruorspurvrtvuuuwvuwtgtrkqrkrvnvJKLJLGBEDE<@FDDC;??A@@@CA?B?ACHCFEFIFIFGDIIGIHJLHHJJILJFJKHIKJGKKMMJJMMNNNPKOPRTXVMNTVTRRQPLNTSRW[]^_]]`_`aa`acebdhbdijgv‹ljigmnsqpqppryvruutsmmssmqrotutrpswtuuwvuuteqskpqjrvnwKLLLMGCCAD<?EEEC=AACBBCDACDAAEGCHGHHGJGCHIGHJFILHIJMKNLGKIHKKNQKRQMSMKNNOPPOTOWXX[NSPW\ZRWPNTUTTXZ_bb_da^`b^`eaacingbihhnxvlhimnsrpqrrrvtsusssnksqmprotvrqquvuswywutucmtkopjqtowLNLLLGEA@D>>DEFC@CAEDDFBCEGCCIFCIJJIIKGDKJGHJIIKHJJNLOKILHJLKZfJd\KlSHON_nUks[qpbwcSPavuhucav`Xnqbdvinzf[lt`ljT_wvijgifglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqrqyLNJJJFC?@B?=DEFDCDBEEDFBFFGDEKFEJMLKLLGGMIGJKHKKIKKNLNLLLILLL[sbdp^lmUMNfs]ffqlntgpi_aYnnbppbkjjfoqtetno\ougpMJqyvka`keemxlkvmnpsrprqpqrqrrrtrmmsnnoprutqsstuuutwxvttbmukpplrrqzKLIHGED?AB@>CFGBFCFEFEDCHHGDEKHGLNNLMLFJNHJKJILJJJKLMNNMMJMMN[roonpplkMPQlWMibtrpamnu\YlQ\mmZqmkomxxtsip]_rkqjUuyxoc^kfbgppjiopprspqpqprrqqrrtlmrmnnorutqtrtuutuuzvutenukpolsrryIKGGEEEBBB>@@FGBGDIFEEBFIHHEHLJGMMNKMNGLNILKIJMIKJJKOPONMLNNL\hdu]lqWlNPQmTYk^klvaldsSecNmYl\tpkilxjwuhp]^rkhWbcw|oc`ggadiuyknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtvHLFIDEECAB=BACGDHGLHECCHKIHFJLLFNLLSRLGLLHNJIHNHJJIHNOMNLJNMJZsppoqqmlOQRnYrkgooqqomt]nXat_nopoqronusttj[^tcwxrjnzhaacfbbimtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyxtukoumtonssvsHKHIBEEEAA>DDBGDHIMIFCFJLJGFKNLEOJKWRKGKJJNIHJLIKJHHKMMMMIKKKSkc[i^_icrrZ_Yjn_eeUk_c[aaQ`lh]j\niid[pfdp]Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunwqrvtwrGGFIDECFA@BFEDGBHJLHFDGKLIEFJOLIPIL[QJEHHKMIHJJKKIHIGKKKLGHKKLMMLJKMNT[\TPTLPONOOVQOOQNOQJJOPQdqiTYW\[\VY[]X]\\cfaaebcf__fkmhmtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyxxuvqruovrtsuusGCEGFEAEC@DHDFGCIKLHFDGKLIEGIPKLOKLWLIEEHIJHIKIMJHFGGIGHIEFLIJLOMJP\W^P\[`^MXYS\\b^MXZMXaRKYaZR_d\aX[ddVVX\YZX\VY\]b^daa_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtOBCDLMBDCBEIEGGFKJKHEFIJKFEHHPKMMJMRIGEAHFJIKLJLJHFDIFDFGEFJHCJNKLU_Y`X`a[`TXYT^^Z_RY\P^\YN_\^SZ^c^Z]`c`Y_c[`^[TXWY^]cbcacehekrpoppnow††……†‚{€……††…†…uqprrsvyyzyyxxxwryvxrqxvtvaSJJMIECBCGHFHGHKJJIDFKKKEFIJNKNKHLNGHE>GGLIKLKKKIGDHDCDEAFJD@JLJO[cY_^a_RTRW_`\]Y^QY\MV_WKQY[PZ_aa]^ca`bbbcceZQXUU\Y]c`__cdbhomnllllu…„ƒyu|„………††……††ƒ}wrrtxyyyy~}yuyvvrnzwvxXQKFCGEBEGIFGHHFFIGHGHKILDDKKNMLKHKJHIF?GGNKKKMKKKIFGCD@DAHIB?IJHO]aZ[d]_TQRX]\\\_ZKW\LR\YIM^QO\_accccb\dcbdcfXQUTQ[WZ`_^^aa_dlkmjjlnv~uz|„………………††…†……††‚zrsuu{…‡‡‡†…„~xpzwvx\RMC@IFCFKJFFFHGGIGFFILJNFDKKMNJLIKJHHFBHHQMKKOLJKIGGED?ECIIBBGFET]Y^X_Y_[]UXXO]]QKJV^X^[]UY`RQ__bb``bb`cbaddbXOQQQZR[]]]]^__dhgljnnp{{|~{€‚ƒ„…„…………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡ˆ‡…ƒ€|x\SKCAHFDGMRHCQJEGHHEFKJMPEFIJKNLLIKLIHGDHKQOMMPLLJKHICDAEDIGCBGFDWUE\T]SV_XOTUNZZMIJT`a[_X^^a]OYa\``_bcb]abW`_TPOOOXQ\[[\\^_bffeleoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDFFHDIRbPCV^IGGHDFMKPPEIIJKNLLKLKIJGEJNQQNOOMNLMHKADACDGECBEGBMHBKKOONLFMFGIJHGLKMOPILOPOSOLPSRUZYWYXXdWOSTPPNMOTSZXXZ]\`adecgcklpsryy{z„„„…„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKM]LGGXLGHJHGMLQQHLKKKNMUNOJJKGGKPSSNPONNNNGKF`ED_LEfdEN\I^[rmOMUmYLDQ`UkWgJ]WU^DLQULLSVQRTXWTXUT\UPfZhhdXRjRVUT[\[``abab`fhfnkhrz|}~„„„„ƒƒƒ}|zr{z{‚€ƒ„„……„…ƒƒ~z{LIFGFHEEKOSIJF`THIOJIOMRQLMLLORUROOILMGHMQ[YOPPNOOOIJQQI|YYrtYQmHqnoaVPqqsPCksmqspSo_[nX]V\XUkhU]VcZ`Y[_VVXjtuu^_v^Wa[[f[_`a`a]`agmpl`pwtx‚ƒƒ‚}€vxzlv~tx}€|~€‚„|€ƒz~wwNJEHMNBDLLFIKEQVLKNIKRXWQNOOMQTNOQOKKNGMPS[ZSQROPPPJHZx]TxehZSURvgtlpbnfjQrOMwmjrpsrqrpoo€]ezuxqqzq~s}ku}bRh|essorr{|o~xn€r_``baZ`_gknkblfgmw~€ƒ~{xw€tvzir~ns|~wx{~€ƒx|€u|||ssNKG`]GAEMMHJJGJPOMMJNV^YULQSNXZMSSRNKOHQRTYWVPTPPPQKHgxlcxrm[KNVypumubovPeeJfvqmwo€jfxxiWrQhzmijzz~lxzohoYvvjvup€_rf}ilx|o^__ba[]bdgijdgbcdllppstsssyqrxblugqy{srvy~suzn|}yxrnNKSuNCBFPPHJKIKPOOOMPZ`ZWKTWPa^RVQYRLPISTVXWWOUPONRJKrouuquqdibWnLqp^FhyWvTLiy}x`y{sna]mocRhqunmypwlvttrln]t~zkmy|ktl|kpvux^__b^]_ddighee^abiiijknokqomjpacfcowxompsynqpk{ztsomLL[VHGEGRPILMJKPQPPPPW\XUMUYUeXRRY^SLNITTVWYWOSNNNQHRmHiwK`dvvVXlOnl{sajgvULWkh}lmlx_Zpz{^`zscroxqhd}ir|^TLl`vukiu{zm~xk|p\^^b[^bddgeeebZccikkrsrvglihdg`akagsrlgmmr|kmhk{tmnkmOHKKHJHHQPLNOLKRRROSRWRVTPWZVVTTTa_PNMKTSTQVVNNLMOPJHQNPULKLSTTSTPVUQQNQQXYRNPUTXXX[[URSW[WXXZOSUWXXR^YW^VTPYRWWWWX^Zgr^[[Y\]_cZ_ccdfdccbZcbgfemnmueegcaf_]g`dlhfgkhpzhggjujhgilQIKLLMKJSQMQPOLVUTPTUXUYUQZ]VUTWUYWOOLMVTQNUSNOMLQPLJQQKQMKKPSUSQQSSIHLNOQRQQQTVRXW\WSRPRTUVSZQNSRWVTYVUZVTRUTTTWXV\Y^`]\ZZ\\_c[]bcdfdddaY`acabhhimbad^_c]Zd\bma^fefmsdigjkedcfhPJKLOOLMSPNSQQMXWUTUWWWZUS\`VWVYUXSPPJNWSPNUPNQNLSPMOUSNQNMNQUQUQRTUNKMOQTTRRQVWUYZ[YSURTWVVY[TPTUXUUZUWZVSRWVUW[XZ_\UX^\^][]`a^[bbcgfedbX_ab]`gdfea^_]]^ZZ`Z_g`^]]bhkagfhfd`bcaOLMLQQLOTOOSQOQ[YWWX[YXXV\jdVXYZWVSSOJNVTPOTPPPMMRRPRXTQQOMOSVOXRTUUONMQTVUTTRTWVZ]\ZVVQQVXV[[WQTWVVVYTXXVSRYWUZ^Y]_^U^\^`\[____ZbbdhgddaXa`b^^fcc`b]\\\\YZ[X[a[^]\_b__bdebd__`\PMNNRQMRROSTQOU\ZZW[[\YZ[dqmhd_[XVUWQLMVSMNROQROLQSRUZUSPPMQWWRWSSSXMOOQTXVUUSUYX[^][[VQNUVU[\WRTWVWXVTX[UTRZXW\^Z^_`Ua\aa]`b_\`]c`cghdf`Yc`a__ed_`b[Z\[\YZYXW\Z\[`^_[^^a`^c\Y`ZQNONVQPTQOTTSPW\\\X^\^W\^jqwy€c\[UUWQMOVSNQQORTRLRTTYZWUOROSXWTSURRZOPSRV[VWWTV[X\][[]VSMTUU\\VRUVVXYSUZ\USS]XZ]^\```Va[cb]ad^\bab_cfidf^[d`a``ce_b^YZ^[\[YXYWWZZZa\][]\\Z]`W[[ZPOOOYPUTRQWRTP[^^][`\`U\]hjr}slg\TWWQNRZSRQTRTUTKRWV[ZZSOSQVVVTOWRSZRTTTX]WXYSX]X^]YZ]TUNUVW^[XRUUYYYUWZ\VTW^Z]]`]bb]Y_[ea_dd^^cca^efidf^]da`aabd`b^XZ_[\[XXXWW[Y[`\[[\[XZ[^V^Y]QOORZPZTUVVSTT^^`^^b\`U]^bkytl}kZUYTPPS\TUTUTVYWLR[W][]ROUSXWWTPXRSWSVUU[]X[YUZ^X_^Y\YQWRYXY_[ZTUVZYZWXZ\WU[^\^`a_dc\^]]eaafd^^dc`\gdhedb_da`a`bb_`^WX^Z\\ZYYWV]Z]^ZY[\[WY\]VXW]SNPVYQ]UVYWWUX__aa`c]_T]_beeuzhWYYSUSV\XWWVVW]XOU]Z^]\TRWSWWUSTXRSVTXWX]^X][V]_X__X\VQXTYZZaY\VWX[Z[YYZ[YW^_`_cbadd\b\`fadfd^_dbb[fchecf`f__aaaa`_^VU]Y[\[Y[YY][[[XXY[YZZ]_]TY]UNSYVS\TVWYVV\`abc`c^_V[`da_zuohY[YUWTW[ZZ\ZXY`WPU^\``\TTXPUWVTVWRSUWZZ[_^Z_\V__Z]^Y]URYWYY]bZ^VW[\[\\[Z\ZZ__``dbcddbdYafbffe^ab`c^bcidcg_g^abcaa`^_XT[ZZ[[X[XX\[Z[WWYXW\[\`]V]]SOVYVVZUXUXWX]_badad`^YYadb`lfh^[\ZVWXY\\]_[Y[bVTX^]ac\RVYPWWWWWVSUTX\\^``]`\Wa^[^[Z^XUXW[[_`\_XY\\]^_\[]Y\`a^`ecdeefbXcedhgd^c``ec\eidei_f]cbcaa`__[XY[YZZXYXW[[Z[WXZTY]\Z`\U^bNSWYVWYX[\XWY^`badada]^Yacb_a``^\\\WW[[]]__\Z]cYZX]`cd_RXYPWWXYYWVWV\]^`a`_b^Ya]]^Y\^YXUW[\`^]_ZZ^]^^a]\[Z\`b_becefefbZdffigb_c^afdZihbfice^bbca``_]\ZX[YYXXZXWZ[ZYWXUU[]]]``bbxKXW[YV\[\]ZW\]_`bdaba]`Xbcb`cab][\[XW[\_]`_][`d]\X[becaR\ZOYXZ[[ZWZY`]`bb`ac_\b]_][^]YYTX]]_`_`\[^^`bc]\X\^`bbcedfdefd\efgifcab\cg`\ihbhied`baca_`_]]\Y\YXWXYXW\ZZWWXOXZ]acffrkJYW\ZZ_\[^\X][^_acbaa]b[bdb`bbb\[[ZWXiq`\`_]\ac_^YYcedaS_ZRYX\]][Z[[c`bbc`bda`c^`\^^^YXU[_^]aa`^[`abfc_]T]``cddfegeffe^efhhgdd`Zfg^ahhbhhfc`b`cb___\][Z[YXXXVZV\[ZVVUMXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡„‚‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vvvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{zzzzzzz{{{|{{{{{{{{{{||||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vvvvvvvwwvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{zzzzzzzz{{{{{{{{{{{{{}|||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚‚ƒ‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||upooooppz~}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰ˆÌÓÒÒÒÓ՞†‰‰‰‰‰‹ŒŒŒŒŽ‰~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}upnoooooz€~†“y1333332j‚€€€{­éääääèʉŒŒŒŒŠ”Ýæääåä祉ŒŒŒŒŒ‹}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}vuuuuuuuvwwwwwwxyyyyyzxooooppprrrrrrrwzyyzzz~ƒƒƒƒƒ„||||||}ƒ„„„„„„~|||||||}||}}}}|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚ƒ‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vvvvvvywvvz{x{xwvwzxzzy}yxxyxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{yyyyyyyz{{z{{{{{{{||||||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwvy}|}}z|{wwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰Œ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwvz}}}}y|zwxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒ„„‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z{xwv{|}|{z|{wxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzyz}|}|{}{xxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyx{xz{y{yxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyxyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰…„ƒ„ƒƒ‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxyyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oxyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„‚ƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒƒ‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{{||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}|}}}|||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚‚‚‚‚€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrsuuttssssrrqpoooopqsssrrrrstttsqqqrstttttttsstsssttttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqsttssrqqqponnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqrsssssrqqpponnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnnnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrrrsssrrqqppppoooooooopopooooppqooopppppopoppqrqqqrrqrqqqqqqqqpppppqoonnnmmnnnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚€‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpqqqtqrrqqo~‚nppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqqqp‡ˆprqptšnpppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqq}¢ƒoroŸ|oppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsqu‹‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqrquž¢wqw œ}oqqqqpppppqqqpqpppqpppppppppppppppqqqpqqpppqppqqqqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrrq˜©o‚£~pqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒƒyrssrrrsrrssssrstr“©¤{‰¡|rsssrssttuuuuutuwxwwwwwxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~€~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz~|~}|vvwwvuxzxxxxxwxyy ´©¦©©—}{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~|{|{{Š¯¤¡µª¬£{zzxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}}}}}™¥–¢± ™§”}€}}}€ƒ‚€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€œœ ° Ÿ¢Ÿ€€€~~~€~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~€€€—›˜±¡˜•…}~~~€~~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŒŽŒ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~€~~€~¡«¥–¤››˜¢ ‡~~€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹Š‹‹‹‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„ƒƒ‚ƒ‚„„‡¡²§¡ ™¦¨¬©¡š‘‡€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒ‘‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒƒƒ†Ÿ­±¦›š ›žœœž¡¤£”ˆƒƒ‚ƒƒƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒƒƒ‚ƒŠ—™—–˜ ›žšš—‰†‡‡††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ„„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠˆ‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„ƒƒƒ…„‚†Ž”“—šœœ•‰‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž““’ŽŽ‘’‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„„ƒ„ƒƒˆ”Ž”˜‘‡‚‚………ƒ„„……ƒ‚€€€€„ƒƒ„……„‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘“’ŽŽ‘‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚‚ƒ‚‚‚€‡›ˆŒ‡‚ƒ‚€€€€€€€€€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„„„„…„…†’“‘ŽŽŽŽ‰ˆ‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~€‚‚€„ƒ€€€ƒ‰Ž€‚ƒƒ€€€€€€€€€‚ƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“‘Ž‰†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚‚ƒ„‚‚„„‚ƒŠ–ˆ„‚„‚Œ•‚‚‚„ƒ‚‚ƒƒ‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘Œ‡…ƒƒƒ‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒ€ƒ‚…†„„ƒƒƒ‚„Ž™‹ƒ…„„„‚€‘™†‚‚‚„ƒƒ‚ƒ„…„ƒƒƒ‚‚ƒ„„ƒ„ƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”“’’ŒŠ…„„ƒƒ‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~Œƒ~}|}ŒœŽ€‚‚‚…””Œ‚‚ƒ‚‚‚‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……„……„ƒƒ„ƒ„ƒ‚†””’”’Œˆƒ„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~–—‰€}}}}{˜Œ€ƒ€Ž”Œ‚‚‚‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“’Š†ƒ„ƒ„‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€•ŸŠ~~€}‡‹~„„ƒ„‚ƒƒ‚‰…Œ‚‚ƒƒƒ‚‚ƒƒƒ‚ƒƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†„…ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„‘¡ŠŒ…}†‰€~………„…‚}}}€ƒ„ƒ‚ƒ„ƒ„ƒƒ„„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„……………„…††††…………………………††…†††…†††‡†…………ƒ„„„‡“““’’Šˆ…†……‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…ƒ‰‘ƒ„‹…‚~}‡†ƒ€~~ƒƒ„‹†„„„„……„„„„„………„…„†…………†††…†……†……‡†††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„„„‚‚‰~}~…~€€ƒ—†…†……………†‡‡††…†……†‡‡‡ˆ†‡‡†††‡‡‡††‡‡†††…ƒƒ„……†„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘”“‘‘‹ˆˆ…†…ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒ„„„ƒ€€€„„~~€€€€•–’ˆˆ‡‡†‡ˆ‡ˆ‡ˆˆˆ††‡ˆ‰‰‰‰ˆ‡†‡‡‡‰ˆ†‡‡‡‡†‡…ƒƒ„…††………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†……„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡†…ƒƒ…„„„ƒ€€Œ‰€‚‚€€~{zŠ§¤˜Œ‰‹‹ˆ‰‰‰‰Š‹Šˆˆˆ‰‰‹‹ŠŠˆ‡‡ˆˆˆ‡‡ˆˆ‡‡†‡†„ƒƒ…‡‡‡†……„„ƒ……„……†„„„………†…†…ƒ‰”’‘ŽŠ†…†…ƒ‚‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡†„„…„ƒƒ‚€€€„„‚‚‚‚‚‚‚€~}}}}~~|{}™§¤¢˜•‹ˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰††††‡…†ˆˆˆˆ††‡„ƒƒ„‡ˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚ƒ‚„ƒ„ƒŽ“’‹‰……†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„……‚€ƒ„‚ƒ‚‚‚ƒ~}}~~~~~~}~}|œ œ†…†‡‡‡‡ˆ‡‡‰‡‡†ˆ‡†‰‰ƒƒ„ƒ…„„……†ˆˆ†…ƒ‚‚ƒ…‡†‡††„‚‚ƒ„‚ƒƒ„‚‚ƒƒ„ƒ„‘’ŽŽ‹‡„††„‚ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…‡ˆ‹Š†„†„‚††‚‚„„ƒƒƒƒ‚ƒ}|}€~~~}|}~|zƒœ›œ•„ƒ‚ƒƒ„†……ƒƒ…„„„„„„…„‚‚‚‚„„‚ƒƒ…†…„‚‚‚‚ƒƒ…„„„…„„†„ƒ„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰…„…„…‚ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€€„„ƒƒƒ‚‚€}}€€}~~}|}}{zy‰››—…€‚‚~‚ƒ‚‚‚‚ƒ„€€€‚‚€€€€‚ƒ‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†‹“‘‹ˆ……ƒƒ„‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€ƒ‚~~~~}‚„„‚ƒ‚ƒ‚~}~€€€~}}}}~}|zz{š•…‚€€€~}€€€€€€~}}€~€€€€€€€‚€€‚ƒ€‚„ƒ†’ŽŠ‡‡†ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€ƒ„‚‚ƒ‚ƒ„…€€|}}~}}~€€}~}~€ƒƒƒ‚‚}}~€€€~}}}|{{{zzz{“‘š~~~~~€~€€€~}~~}|~€~~€€€€€~€~€…’’Ž‹‹‡‰…„„‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~~}~€€~€„ƒ‚€~}~~€€€~}}}|{{|zzzzy€ŒŒŒ‹~~€€~€€‚€|~~~~}|€~~~€~€€~~€~~~~~}}}}…“’ŽŒ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒ‚‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚‚‚€ƒƒƒ€€}}}~~~~}}}}}|||{zzzzy…€€‚€€€€€€‚‚€~€~~~~~€€€€€€~€~~€}~}}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…‚ƒƒƒ…„„„„„ƒƒƒ„‚‚‚‚‚~}}}~~€}}}}}}}}||zzyyyz‚‚‚…ƒ‚ƒ€‚€‚ƒƒƒƒ‚€€€ƒ„‚€€€€€‚‚€€€€€€~~||‰”Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…„„…„…†…†††…†…ƒƒƒ‚‚€}}}}}}~~}}}}}}|}}|{yyyyy|‚ƒ„…‚„ƒ‚‚ƒ…‡‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚‚ƒ„ƒ‚ƒ‚‚‚€€€€€~Ž“Œ‡ˆ‡ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€~}}}~~~€ƒ„‡‡„†††…††‡‡†‡‡ˆ‡‡‡†}€€€‚~}}}}}}}}}}}}||~~~|{yxxyyy€‚ƒƒŒ„ƒ„„„——ƒƒ„}~‚‚‚„†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ…„„…ƒƒ„ƒ‚ƒƒ‚‚‚‚ƒƒ‚‚‘‹ˆˆ‡‰‡††„†…„„„ƒ‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€€~}~~€‚………‡†‡‡‡‡‡ˆ†‡‡‡‡†‡…~}}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yyy|~ˆ•ƒƒƒ„„”“€€~~„‹€€„†‰…„‚‚……‹ƒ‚……††„ƒ……ƒ„„ƒƒ„ƒ„„„ˆ’Œ‰ˆˆ‰‡‡‡…†…„„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„ƒ…„~}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|yzz{|~ƒ‚ƒ‚€~}{ˆ‘||Ž–}‚†Š…ƒƒ„ƒ‚ƒ‰}ƒ„……ƒ…†…„……ƒ„……†„„Ž‘ŒŠŠŒ‰ˆ‰‡………ƒ„ƒ‚‚‚ƒ„ƒƒƒ€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚€‚€~}}||}}|||}||}|}}}|||{‹‘—Œz{|zyz{|yy}}€}{{~}‚•‘„ˆ}|~‚„||‚„ƒ‡ƒ}ƒ€‚‚€ƒƒ„„„„„‚„ƒ„…„‘‘Ž‹ŒŒŽŠ‰‰………ƒƒƒ‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚ƒ…ƒƒ„………ƒƒƒ„‚‚ƒ‚ƒ‚‚€€~~}}}||||||||||||||}|||~Š‚{z{zxz{{|}|~~~~~~}|€€}†~}‚~~€‚||€‚€€~}{Š‚}€~€€‚€‚€€€€‹”ŒŒŽŽˆˆ‡………„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ……†‡…„€†”ˆ€‚€€~~~€|||||||||||||}|||||}|yz{{xxy{{z|‚€€}€}€‚‚€€€‚‘€€~€~~~€}|}{}}}|}||}€€€~€~~‚”’ŒŽŠ…††…„„…ƒ‚ƒ‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚‚„†‡††~ˆ•Š~€€€€~€~~~|{{|||||||||}}|{}|||{|||zzy{|{}…ƒƒ€~€€…‚~€~~€…†‚€~~ƒ†}|~€€~}}}}~{|}€}~Œ‘ŽŽ‡„††…„„ƒƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}€‚„††……~€€€~~~€€€€}}||}~}||}}}}}|~|}|{}||z{z|}}†…ƒ€€€}~}~~Œ„‡~}||~‚‚}}}}|{}|~„ƒ€~~~~}|~€}~€~~„’ŽŒŒŠ†„…„„ƒƒƒƒ‚ƒ‚ƒ‚ƒ‚€€}|||}~{{}w~vx~}|}|}~~‚ƒz~~|~~€~~~€€€€~~~~~~}~~}|~}~}}}{|||{{z}~€€ƒƒ‚~|||}|}ƒ~Œ~|{{}~}~~}{{{}|{{{{€†„‚„ƒ€~‚‚‚‚‚€‹Œ‹Šˆ„„„ƒƒƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€€€}€~~~~|‚}~}}}{{}}|z||}‚€€€}}}|||||}|~{~{{{|||}|{{{{||zz}z~‚~‚„„‚€‚…†……††‡…„‘‹Š‹‡‡…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}{€~~€~~€‚€~~€€~}ƒ||}}|}}}}{|~~~~~~||}||}|~~{|{||||}|}|~|}|{{{|z{|{|}z}~~€€ƒ‡‰‰‰Š‰Š‰…ˆ’‰Š‡……ƒ‚‚ƒ„„ƒ‚‚‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€€~~~}€€€€ƒ‚€€€€€€€€~|z|}}~}}~~Œ†}}~{{ƒƒ}}}}}|}}}}}~|}|}|}}~|~}}}}|{{z|{||{z{{zzz{~~‚…ˆ‡ˆŠ‹‹‹‰Œ‘ŽŠ‰†…„‚‚‚‚ƒƒƒƒ‚‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„„€€€€‚~}~€~{~’Œ|}Š€Œ~~}}}~~}~}|||~}|}|}}}~}}~~|{{{||}|{{{{yzyyy{~ƒƒ„‡‰Šˆ‰ŽŽŒ‰‰…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{}||~~}}€€€€‚…ƒ„‚‚‚€€ƒ‚€}~€~|‰‚~ƒ‘„„ƒ~}|‡}}~}}|~~|}}|}}~~}~|}}{|}~||{|}zzyyyyz{~~€ƒ‡„ˆŽ‹Š‡…„„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{}}}}}zx‚€‚‚€€€€‚‚‚‚……„‚‚‚€‚„~€}~~}~€€}~€„€~~}~}}Š…}~}~~€~|}||~~~}€}}}|}||{|}{{{zzz{{|}~~€ƒ€‰Ž‹Œˆ………„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv}€ƒ‚‚‚‚‚ƒƒƒ‚…†„ƒ€€€ƒ€„~~€}~€~}~~€€€€}€~€~|}}|~~~~€}‚€|}€€}{}}}||{|}{{{|{||}}|ŠŠ‰‰††……„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€‚€€€ƒ€~~€}€}}~~€€‚€€€€€}€€€€€€~|}}}}~~}‚}€~‚€}~€|~~}}}{}~|}|||{|{|~Š‡‡…†ˆ…„…„‚‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz~}yxtt€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚~~~~€}~€}}}~€€€€€€~~€€€€€~}}}~|~~}}„€~}}}~}~~}~|{|z|{z€ˆƒ„„…„„„„ƒ‚‚€€‚‚ƒ‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}}~~{{z~‰‡~xry}qzx{xyuu}‚ƒƒƒƒƒ…„…ƒƒƒ„ƒƒ„„ƒ€€€€~}}~~~~~€}}|}}~€€€€‚€€€ƒ‚€€~€~€€€~~~~~}~~……€ƒ~€~~€~}{z{z|{z‚…€ƒ‚‚‚‚‚ƒ€€‚€€‚‚ƒ‚ƒ„ƒ„‚„‚‚‚‚€~€~}~~~~}~}}z{|…„{{sy{|pwuvwyutz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€€€}}}~}~~}~|}}~€€€€€ƒ‚€~€€€€€€€€‚‚‚€ƒ‚ƒ‚€€|z|z|{|‚€‚€‚‚€~‚‚ƒƒƒ‚„‚„‚‚€~€€}~~}}}~}}{{z€x|vyz|qtxwvxury……‚„„‚„……†„„‚„ƒƒ€€€€|}}~€}~~}|~~~€~€€ƒ‚ƒ‚€€€€€€€€‚ƒ€„€}ƒ„€€‚}z{{||}€~€|}}€€~}}~‚‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxzzruyyvwwsu†…ƒ……‚„„…„„ƒƒ‚ƒ€~~€~€}}}~€~€~~}|€|~€~€‚ƒ€€‚ƒ„‚€€€€€ƒƒ€ƒ€~‚ƒ„€€‚‚‚„‚~{{|||}~}~}z~}}x~|||~~~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„……‚„„…ƒƒƒƒƒ€}~}}}€~~~}}€€~|~~~‚‚ƒ‡…~~€€€€€€€‚‚€€~€‚‚ƒƒ‚ƒƒ…ƒ}}}|{||yz{z}y{yx~{||~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzswvst†„„†ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€}€€~€}~}~€€|€€€~}~~€}€€ƒƒƒ~}~~€€€‚€~~€‚‚€„‚„„†„€~~||||zyvyyzyvyv~|{{{~}{}€~}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…„ƒƒƒƒƒ‚‚ƒ‚ƒ‚~~€}}}}~€€€|€€€€|€~~}~~‚‚~~}~~~~€}€€€~~~~~€‚‚‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{{{…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvpxyrx…………ƒ„„ƒ‚„‚‚€‚€~~~~€~}~|~€€€€€€|€~€€€€}€~~~}}~€€~~~~}}~~~|~€~~~‚~~€€~ƒ‚ƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}|{|z{}zzx{|zz{xtxuqrtpxxqy„………ƒ„ƒ‚ƒƒ‚‚‚€‚€€€€}~~€}|~|€€€€€€|€~€}~~}}|€€€€~~~~}|~~|}€~}~€‚~€€~„‚‚ƒ……‚‚~}}{{||yw{ywxwwx{{{{|…‰}{zwz|}}||}}}~|}~~}}}|}~~}}||{zz|{{zyzz{zxswuqqsoxwq{…†……ƒ…‚ƒƒ‚‚€‚€€€€~~}|~~€‚€€}~€~€€}}|}€€€€~~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{||{zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚€€€}}~€€‚‚}~~~€€‚€€~|~|€€€€€~}~~€€‚€€€€€€€„‚‚€~|}~~z}…~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚€€€€€€~}€€‚‚‚€~€€€‚}}~‚€€€€€€€€~~}€~€€€€€€€€€‚€€~}~{“z|}|{}y{zzxzxy|||}|||||||}}}||}|~}~~~}|z||{}}{yzzzyytuuooqpwst}…†ƒƒ‚ƒ‚€€‚‚€‚‚€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€€‚‚€€€}~|†‰||~{{~yz{z{wwy{|{}||||{}|}}}}|}|~~~~|z|}{|}{yz{zyxstunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚€‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€€‚‚‚€€€€€€}~€}€ƒ‚{~~{|}{z||{‡zxxy|||}{||}}}|}}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ‚„„€~‚€€€€‚~€€‚€€€€€€€~}€~€€€€€€€€€€€€€€€€€~}~}~~{}|}{|}xxuxxy{||}{||||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒ„ƒƒ‚‚‚ƒ€€‚„ƒƒ„ƒ‚‚‚€€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€€€€€€€€€€€€€€€€€€€€€€€€‚ƒ‚‚€‚‚€€€€‡~~|{}|{}xwvyyz{}||}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚‚„„€€ƒ€†ƒƒ„‚„€„ƒ‚‚€€‚‚„‚„‚€€ƒ‚€€€ƒ€€ƒ‚~‚€€~€€€€€€€‚‚‚ƒ‚‚ƒƒƒ‚€€„}}}|}{}{zvzxy{{|}}{|}}}}~€€€€€€€ƒƒ€|~~~}yy{zzzysrtowqwysw{…‚‚‚‚ƒ„‚ƒ„ƒ€ƒƒ†ƒƒƒ‚‚„„ƒƒ€€‚ƒ‚‚‚~€€€‚‚‚‚€€€€‚‚„€~ƒ€ƒ‚€€‚ƒ‚€‚ƒ‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ‚€‚€}€|z|{{w|yyy{z}~}||||}~~€€€€„„€}€~{{{z{ztpxqytvxtv{„‚ƒ‚ƒƒ„‚„ƒƒ‚‚„…„‚ƒƒƒ„„ƒ€ƒ€ƒ‚‚‚‚‚‚€€€‚‚‚‚‚€‚‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚‚„ƒƒ„€‚„‚ƒ‚‚‚‚ƒƒ„ƒ„ƒ„„„…ƒ„‚ƒ‚ƒ€€~||€}|x|yzyz|}|{||}}}||€€€€€‚€€€€€{{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„‚ƒ………ƒƒ‚ƒ„‚„…‚‚‚ƒƒ‚‚€€~€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€ƒ‚€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒƒƒƒ„€‚„ƒ„ƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€€{}~|y|zzz}||}z||}}|z{~~~€€€€€€‚€€}}||}|vrvxxvtvu}‡‡ƒ‚„…ƒƒ„…„‚„†„„ƒ‚ƒ„„ƒ…ƒ‚‚‚ƒƒƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚€‚‚ƒƒ‚‚€€ƒ‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz|}€}||z|~}|}}~~€€€€~~€€€€~|}~~~}||xvvw„‡ƒ‚ƒ†ƒƒ„†„‚…†…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„‚‚‚ƒƒ‚ƒ‚‚ƒ‚‚ƒ„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒƒ„„„„„…„ƒƒ„…„…„ƒ‚€}‚€}||{||€}}~€~~}~|||}}~~~€}}~€~~}~}~~~~~€|}€‚‚ƒƒ…ƒ„ƒ†„‚ˆ†…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~‚ƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒƒ‚‚ƒƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒƒ‚ƒƒƒ„ƒƒƒ„„ƒ„„…„„„…………„ƒƒƒ~„€}}||||~~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒƒ…ƒ„ƒ…~‚Š‹……„ƒ‚„…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ„ƒƒ„…„……‡‡†‡…„„…„ƒ~~|~~}€~||~|z|}}}}}~~~€}}|€€~~~~~‚€……„ƒ„„‚„ƒ†€‚„…‹‰„„„„……‚‡††„„„„…„…„„ƒ„„‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ…€}uz„~…„‚ƒƒ‚ƒ„ƒ„„…ƒ„…†„…†}„y|~ƒ{…ƒ„ƒ€}~~~ƒ}{}~€~}|||}}}}|}}~€‚}}|€€€€‚ƒƒ‚‚†„„„…„ƒ„…ƒ„…„Šˆ………ƒ……„†††ƒ„„………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†spurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚……‚hzrss|€rƒƒƒ}}~~‚ƒ‚|}€}}||||}|||~}~}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ…„†ˆ††…‚†††‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}p{pyv~ƒ‚nypus|vyy†r„ƒpvxqvtturstvi€nrotvnulwmzsn€‡ym}rsvsvmnwlpylu}~|~€}€}€€}}|||}|}~}€€€~|~€€€€€€€€‚ƒ‚‚„…‡††€‚…ƒƒ…‡†ƒ………†‡‡„ƒ††ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoolw}x†pqzprufu~n{ysoy€}~€{~|€~€€~~€€€~~~~€~}€}€€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„………††ˆ„„†‡ˆˆ†‡„††‹‰…„†‡‡…„………„‚…………†……†…†quprsoszy~ƒtˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„rioyxpkyszozwvvp€~~z~}|}~}€ƒƒ€‚ƒ„‚‚€}~~}~€~~‚€€‚„‡†ƒƒ†„„„…‡†…………‡†ˆ……†…‡‡…†„††‰ˆ…„‰‹ˆ…„†…†…ƒ……„†††††…ƒx‹yrˆz{pp……x…xyks~y{krƒ‡ƒz|mzyyt}€vno€€ot|uwpy}}m}uoƒ…†z€rr{|upozks|nv‚~~}}{}{|}|}}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡……………‡‡ˆ†„†…‡††…„……………†‰Š‡……†…††…††„†††††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„…†…†„†„ƒ„„†„„„ƒ„ƒ…ƒ…„…„†ƒ…†……„„…‡†„„…†……}w…ƒ„„ƒ‚~~{|{~|||}}}~€}€~~~€~~~~}}}~|{|~||‰†…„†††…††…………††‡‰†„†…‡………ƒ„…†…„††‡†…„†„…††††„‡†‡‡†…‡ˆˆˆˆ……‡…††ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…ƒ‚……†……ƒ„„„„†„†…„……ƒ††………„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ}€{{|~{||}~~||~}€~}€~~€}}|€}}~~~||}~{|||{{~ˆ‡„„ˆ††…‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡…††……†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ……ˆ…†‡†‡†‡†‡…‡‡†‡……†‡…††…ƒƒ…††„„ƒ„„ƒ„†„†…………ƒ††…†…„†‡…„„……ƒ„‡†ƒ‚ƒ„ƒ„‚~€|{}~{|{~~}||~}~~}~}}~~|}||~~|}|||}|||~z{{|~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†„…„‡†„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆ‰ˆ…†ˆ…†‡†‡†‡†‡…ˆˆ‡‡…††‡…††…‚„„…†……„„„ƒ„……†††…†„†…††……†‡…„ƒ„„ƒ„‡ƒ„‚„…ƒ€€€{{~~|||~}|||}~|}|~}|}}||||}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††„…†…†…†…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡„†††‡†‡…‡†ˆˆ‡‡…‡‡‡††‡„‚„ƒ„†…‡…„„„„„…†††††…‡……‡…†…†…„ƒ„ƒƒ„‡ƒ€‚ƒ„‚‚‚€{}~~|||~}|}}|}{||{||}}{{{}|{~}{|}}|}}~}|zz{{||ˆ‡‚†‡††‡††…„…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡ˆˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡…‡‡††‡‡…‡†ˆˆ‡†…‡‡ˆ††ˆ„ƒ„„ƒ††‡……„„„…†††††…†‡††‡††„†…ƒƒƒƒ‚ƒ†ƒ~‚‚ƒ€ƒ‚|~~||}}|}}|~{{{z{|||{{{~{|}{z{~||||}~}{z|z||‰‡ƒ†…†…††……„……………„ƒ„†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…‰Š‡…‡†‡ˆˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……ˆƒ„†„ƒ††‡†…„ƒ……†††††…††‡†‡‡…ƒ……ƒ‚‚ƒ…‚ƒ~‚„‚~~~~||}}{}}|~zz{y{|}{{{{~||||z{}||||~}|{{{{||‰‡„†„†„††…„………„„ƒ„‚€ƒ†‚‚z„Œ{€„…‡†††„„‡ˆ‡†‡……‡‰‡„‡…††ˆ†…‡„†‡ˆ††ˆˆ‡‡†‡ˆ†„†††‡……ˆƒ„…„†††‡……„ƒ……††‡††…†††…††„ƒ„…‚‚€„ƒ‚‚}~ƒ~€||}}~}{~}|}yzzy{}}zz{{}|}||zz}||}|~~€{{{|~}|ˆ‡…†…‡„†„……………ƒƒƒ€‚…‚€€}|{„…††„…„„‡‡†††…„†‰†‚†„†††……‡…‡ˆˆ†…ˆ‡ˆ‡††‡…„†……‡…„‡ƒ„…„ˆ††‡……„‚……†…††‡„…††……†‚ƒƒ…€€€€ƒ€ƒ€|€~~‚€}€}€|}~}~{~}|{yzzyz}}yz{{|{|{{z{}}|}|~~|{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€€ƒ~~~€yz}€ƒ„…‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………†‡†ˆˆ†…ˆ‡‰‡†………ƒ†„…‡ƒƒ†„„…„‡†…†…†„‚……†††††„…††„……‚‚ƒ„~€€€€ƒ€|€}~‚~~€~€}}~}{}{zyzzyz|}yzz{{z|{{{{|}}}|~}|||~|{‡……††††„…„…ƒ…‚€€€€~‚‚}}{‚ƒƒ…†…„ƒƒ†ƒƒ„‚€…‡…‚ƒƒ„„…††‡‡‡……ˆ†‰‡…„„„‚…ƒ„†‚ƒ†„„†„‡††………ƒ„…„…†…†„„…„…ƒ…„€€‚ƒ~€ƒ|€~}‚}€~~~~~}}{|{zyzzyz{|yzzz{{|z{{{|}~}}€}}||}€}|†ƒ††…††ƒ„ƒ…‚…€€€~|~~€€‚‚‚„„ƒ‚‚„€ƒ‚€ƒ…„‚€‚ƒ‚„……‡††„…‡…‡…†‚ƒ‚‚ƒ‚‚…ƒ…„…†„†††††…ƒ„„ƒ„………ƒ„ƒƒ„‚„„€‚‚}~~~~„~{||€}€}~ƒ|~~}}~{~{{zyzzyzz{yzzz{{|z||||~~}|}||}€~€†„……„‡„„ƒ‚†‚ƒ€€~~€}‚|}~~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚‚†…‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡†……„ƒƒƒ„……„ƒƒ‚„ƒƒ€€~}}~~|~ƒ~|~||~‚~‚|~}}|||{{zzzzy{yzzyzzz{|y{}{{~€}}}}€€€†„„…„…‚„‚‚„‚‚€€~}~~~~€}}€~~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„…ƒ‚ƒ……‚„ƒ€€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚€…ƒ~€~||~}|~ƒ}{~|}€€ƒ}}€~}|||}{{zyzyy{yzzyzz{{{z{}||‚€~€€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌÌÌËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFK=8765999<>9?<C9;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;>BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÔÓÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937676=;>:=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<:<<98:9:::;<::;9><>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA=366:;<8C<BA>;A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖËËËËËÊÊÊËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÔÔÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9>CE?<;999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNG¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖËËÐÑÐÐÐÐÐÑÑÑÑÑÑÑÍÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø×××××ØÙØØØØØØØØÙÙÙÙÛÜÜÜÜÜÜÜÝÜÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÜÜ×ÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILN@99:4;@<7=9AC=@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMMF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖË̕…†††††‡‡‡‡‡‡‚²âÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¸·©§§§§§§§§§§§§©—€‚‚‚‚‚‚‚ƒ‹ŠŠŠŠŠŠŠŠŠŠŠ‹‡½æáââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑrliNSbLLVM<::77>C?8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKPFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ËÌnPSSSSSTTTTTTL óëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§££££££££££££ ‡„„„„„„„„„„„„ˆg@DDDDDDCCCDDCFSSSSSSSSSSSSSKªòëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘wliJN_MRUM><<7;?C>6:7>?;=B@9<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ËÌqUXWWWXXXXXXXQ¡ñééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤¥¢Š†‡‡‡‡‡‡‡‡‡‡‡ŠjFIIIIIIIHHHHGJWWWWWWWWWWWWWO«ñêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;?@@8:;8<<<;>::;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÌÍx^a````aaaaaaZ¤îççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©©§ŽŽŽŽŽsQTTTTTTTTTTUTV`bbbbbbbbbbbb[¯ïééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB>;=:9::=<;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÌÌÇÅÅÅÅÅÅÅÅÅÅÅÅÅÊÐÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÎÎÎÏÎÎÏÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÒÐÐÐÐÐÏÏÏÏÏÏÏÏÏÍÊÊÊÊÊÊÊËËÊËËËËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÔØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<7@A<=8:;898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÍÍÏÏÏÏÏÏÏÏÏÏÏÓÏÏÎÌÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÎÑÔÏÏÎÒÒÏÎÎÓÓÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÖ×××××××××××ØØ×ØØØØØÙÙÙÙÙÙÙÙÙØ×ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?89:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÎÓ»ÏÏÒ§žÐÏÑ¥¢ÐÎÎÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<=B>BB@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÎÒµ•›³Ö³ž£¦Ö° ¢ªÒÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?><7:>9?D>@98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÏџ ª®Ðš“Àž˜–œÇÏÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>><<96?B?B:648:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÏÑҚ´À˜¡œ´˜œ¢ž¯±ÒÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8E@?B:74:::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÏÏÖ§™µ¶™–­¹†ž–°³©ÔÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<=<964:98::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯Ê £¿Êœ¥Œ§­Øª™ªÔÏÏÏÏÏÕ¥™¶­˜ –x›„ž“£ÕÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>9<97659:6:<;7<@@<::=:<?>=<9@<<::9?@==<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÐÐÖ¥™¶®›¨ˆœyŸ©…™¥ÕÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CGDAA8;?<=;<<7558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÐÐÕ¥š¶·µ¯¦œŠ½­¦˜¯ÖÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ђl]\oghb]OF?HHFE@<<>><==<756996:;::;8@?:<<9<>=;;:?9?:;9=>=><;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦ÓÐÖ¦š´Æ£——¥§–˜šºÕÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;557<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡ÇÒ×¥›±ØŸ«¤›ÐŸ«¤›ÐÒÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKK@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÓÑÔµ‚ÃÕՍ·×»ÔÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUij[L_MJLJULFB<<?FEGKI=667:979:;:<=9>99:8;=>>A>=9<<:=>>;=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÑÑÃÔÑÔÇÃÕÑÕÅÄÕÑÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?ADLLA=775:8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÒÒÔÒÒÒÔÕÓÓÓÔÔÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEJ==786977899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9599:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EIKAALD??;9889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEHIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDI;AA;<886586987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGJB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFID<AA<;876797799=?A?<:9@?<>B?:8776=?@@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD88867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE><HF89757875898;>>=;89A>=@?A>7596;>AB??@@AB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCDECALH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HQA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELBA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<<DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGHNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAD?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€iixsg~‰‰xp‚†{w}~…Š¼ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€‚wt|„‚}sp€Šx‚yƒÈÞÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsnupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9886553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿½¾¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;;>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»º¹¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjcmgb\XQPQKTJB:IQ?A7<94:565455688686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸¸·······¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µ¶¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶······¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸···¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶···¸·¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨§¨¨§¨¨©ª§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸·¶······¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<=::A<6=8378837;@??@@:BEC@BDCA?;;@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥¤¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¥§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§¦¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©«««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤¤£¢¢£¢¡ŸŸŸžžœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@?BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž¤¤¡ŸžŸ  œœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747578;=8::99;=;;89>6789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥£¢¡¡¡¡¢£¥§¦¦§¬«§¦ œ›¡¡ž››šœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””““““’”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¦¦§§§¦Ÿ›š›¢ š–—•š›š——˜™šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¦¤£¡  ŸŸ¡¡Ÿ  š˜˜™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364689:89788:<;<9;;::67899>?@><=@>@:9@A?=A?>AA>AA?:9=>:P Ÿœ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~ššwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥£¢¥¦¦¥¦§¦¦ ›™›¡ —’“’—šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB?DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥¦§¦¦¢œŸ¡Ÿ—‘‘”—›˜–—–˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡  Ÿ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;<;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¦¦¥¤¦§¦¥¥¦¦¥¥£  ¡¡ ™’–›™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡  ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢£¢£¤¤¦¦¥¤¤£¢¡¡žœ›•“•™œš›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œŸ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸžŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::78:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸŸ  ¡¢¢£¤¤¤¤¢¡¡ž›š™–¦¹Ÿ™™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢Ÿ›ž¡¢£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œ››œŸžœœœœŸ   ¡¡¡  ¡ £¦¡¢¡¢¡ žœ›››™£¦‘œ›œ™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥¤¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¢¢¢¡ ¦±®  ŸŸžœ™™šš­ayž›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›šœ›š›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>99;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤¤¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ ŸžŸ   Ÿ¦’•­Ÿ  ž›š™š™«{CŸžžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›šš››š˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9<<>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœœœžŸ¡a–¨žžœšš››¤ŸMI„ žœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:<>9?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš›››››™§lZ  ›šš›œ¯nKL†¡œžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\Q<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™™˜¥„Tt¢š™š›¡¡`XN‡¡œœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡ ¡ŸŸŸŸ™š›œš™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd\\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š›››œœ›˜˜™ ‹]`‘š™›œ£ŽeZL€¢žžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[[LF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ›››››››™˜™ž™^_s•šœ¡€eZM¢žŸžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ›››››œš˜™˜›ab`|”žœž–scUO¡žŸŸžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_^]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜˜——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜™˜ j\Za{›œž‰i^PTˆž›žœœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±´­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=:F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B@AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œš››œ›˜™š˜˜™›šš–’xskX|•˜žŠ[TPY‹’Ž’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨ª¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‘‹‘‹Œ‘‘Ž•ŸŸ’€¤§™¦šyUOd‡‡‚‹†‰Š‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜ž—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VQQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹Œ†Š‹‹‰‡„†ƒ€…¤™‹zbŽ£’˜s……hu€‚’†„„…ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974869388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹Ž‹‰‰…‚‚~~„¢‡vjPq›ŠWny{~|…Ž‹†”‘‹—”—’˜¡–ž–•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¦›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ‚†‹‡ˆ…„ˆˆŠ…€‚}™˜rNGIs’ƒ€J\nov‰…ŠŽ‹™œ””” ššŸ¢­±®©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPEMISWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}€~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‘‹ˆŒ‹‹‡‘£ˆL32;y„ur?=Vjm‰‰””˜•œšž¨®²°°µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWMO_^\NUUbQDTM;?9<895875795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš™ž¡“—›¡š›¢§›_EdN=ywgdH56Tnq‹˜šŒ”š—œ› ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUJTOOJDPK_bXZQ\T`MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ªª©§¢¥¨©«©©®ŒK‚¶†@{{hcR_qQ[oŠ¡¡¤ž›š¤§¤©«®¬¥¤¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdWOYKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®««¬¤¡¢¦©§¨¢thÅÒ¨I€•Œ}OlŠ{Z`€£¨§ ¢¡®¬«ª§­®¨¥¤©©ª©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_VZNRNQOSe\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢™œ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨§¦¨©§©©¤§§™¤¥£¢žb‚¸¿ª…¯£šwGWrRs”¢¢ ¡Ÿ¡¡¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOXO^edlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤ ¢¡¢§¡¦®¦¦œžo‚”³ˆ¶Ö¦œ¸±bP´£Vd¡ž  ž £™–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvxb_\UYQUW[c_s_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?B?:8:>?C@DA:;>=@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯««¬¨¨«¯©¨ª¨¢ ¡¨ª­±²¯«££‰wuxÓ»©“ž¨lU¡ªh_‡§ ¥¢¡Ÿ¢˜•ž›ŸŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸŸ¡¦¢›—’šš •|wo}yf[[`_Z\U\hdocmiib^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¡ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£ £ªª§¯··µ´¶²¬°­ˆl˜Çėœª’vZisuu’¥©§¤ Ÿ£›¡š–ž¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¡™˜¥ ¤§ª©¨ª­¬¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxjb[__\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>BE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢ ª²·»¼¼ººÂ¹´³„t^Q°¯¤¢‘„wnsqwxy|‚‰Ž”™ ¥§¬¦¥˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨¨«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥¡¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxxxc[RYT__amhvkphiibZSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶´º±ª®´±°²´µ¸ÃÉÐÔÑÌǼ¯¡ŒmcRCƒ~~€yuomddigjqrqqqry‰©ÇǼ¢§ª¬§«©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš’–””˜“š˜Š‹‡€€|‚xa^YSai`ftotitdidb[LK>:9898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÄÇÃÄÇÛäã×ǹ­¢”„oWXPDargkrkhceXW\W[`higd`l’ºÀ¿¹©¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`b_^kcbnxuwnm[bRV\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAA;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–••‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±°§¼¼¾ÅÄÆÉÇÅƾËÏÔ˹¥˜‚nZPTJC\f]ahdaai\TXUWXY[X_}¡¸¹«´²­³­©®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|„jfhaklgnurrurg^`\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅľÃÁÇËɺ—t_RNORG=^l`_eca^dcTUWVTU]§®¯ª¨«­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|uklndomiqxoyjia]gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÄÄù·Ä£jLCEJD=Yaadlda\e_YSPPUa‹·¹¬®¥¤£§¤  ¥™©´±¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿ”“‰‰~†ˆŒ–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyz{wnkihvZgrxszgg^d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÊÆÄÄÄÂÄÁ³VHMF;IX_hmh_\_YZTP]ª¬¸µ²¬©£¡­©¬§­Ÿ¬´´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyvuefjjh^konyxcba`^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÎÏÌÃÇÆÈÉÈÈÉÇÅÉÇÈÇÂÈ£w`H??A^]\kd[XVR]ˆ¨º¾º¼º¼¬­¦©»º¹·¿³µ¸²Áƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqocahvhjjtnyl^d[U`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÌÐÍÇÌÉÂÂÇÂËËÈÇÌÉÍÆÆǵ]T/UY]l_QMW„¹ÊÇÂÄÆÀ¼¾´°°°Â¾¾ÁÆÀ¾·¶Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—Ž‹”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r}xpg`kjwmifvotc]cUWUSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<9>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÄÇÈÆÒÉÁÃÿ¿¾ÄËÈÊËɼ¼ÈÇÉÍÈÃÈÉÉÅÅÁÂÂÅƜNR€‰•UTƒµÎÒŶ¿¿À¿º»½µ³³À¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzy€spfegdlebknoo_Y]WVNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾƹ»Ãº¸¹¼¾ÁÇÁÆ»¹ÈÈÃÅÄÀÃÁÁÀÄÁ¾¼Å§|t€‘”u¼ÎÇÇÐÀ¯½½¸¹»»¾·´°¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfaebacddjcgc[ZZ]YQOE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶·´´µ¿»½¿¹¾ºº´À¸µ·²®º»·À·¼ÉÏÀº¿À¼»Å½ºÀÄ¿½¾±sa€‘‰ŠÏÄ¿Àɾ°Á¿º·»¾¹µ¸´¸¼´½¸µ´°³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|yˆ}qdabcgjggjfj^VVTYOSLF8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“““˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´´±°µ·µ»Á¸¾¹¿¼¼·´·¯®·µ¹¿»ÁԌ¸¿»ÃµºÇ¶µ¸º¼¸¹¶³¶žt„É¿¿»Á¾¹Æ½Â¿¼Å¸¶·´¸¶¶»»¸¶´·ºµ³¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒyqmeefpjelhYYOKKKRJLHD9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’™”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿¾¼²­¯¬±°·¼·»½ÁĹ··¶µ¹¹º»¿¼ÏÃv¨Ì½Ç·¹·­¶´·¹³µ±»ÆǖB|ʾ¿¾½¼¿ÈÃÅžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~†|knqgqktfcn`\UHKKDJCCG?:;8><7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘Ž˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼»À·ª­¤®°¸»²½¾»Ä¶µ¸µ·¿¾Ä¼ÂÄ×­s€»ÈÏÂÀ¸®´´»½·¹°½ÃȌFvÍÿ¾½¼ÇÌÇÇÄǽµµ¶Á½»»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†€rfljnuoxchc\cQKUHEECGC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?>??FD@A?>:7?@CC?@=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼ªª£°¹½¼²¼¾¼Å¸±¸¹¼ÆÉÊÂÆÉјps¬ÑÑÌÊĵº¿ÄȾ¾´¿À¿wSoËƾÁ¼¿ÃÌÊÇÅÆÀ¹½¼Ä¿¿¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtpmltlln_c_bbNHN?E@?DC;;::;:8;<:9<>::>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´»Åк¾¼Ä¾·¼À¿ÉÏÇÈÊÉÁ†qs¥ÌÌËÍÊÆÂÃËÎÁ¼¸½º°odc»ÈÄÀÀ¿ÄÀÊÉÃÃÄùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{zˆ{mmx|`qc[_`_TI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA??ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸´¼·»»«Úþ¶¾À¾¾º¦œ©²¶Ã¿¥xux›ÄÆËÈÁÃÀÀÉÊÁ¿»¹± ~sl­ÈÅÄ¿ÀÁ¿ËÇÃÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³µ¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}znsxthp^\_]ZRFEDMIAD=H;;59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘—žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯··²µ³·¹¼»¶»»Ä·m­Î½¶¹À¼¬}nhnmr•˜rw|—½¿ÆÀ¹À¼¾ÅĽ½¸±°™~‚œÊÂü½¿¿Ãÿ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸··½¹»±¶²ÈÀ»¶´±±·¬³©°­­´·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|wmu{poj\`aZSQAFIGK@ECI<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿ››œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹ÀͲu³½¶µÂ¥‡iZ^`MR[ZnsvŸ¸¸Âº³»·»½¿º»»¯¤š—ˆ’~ÀÄþ¼¿»»¸¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ°µ´´½º¾ºº»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶¼´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰{‚zsvvwnra_f][UJ=??GG=GCC9:5;99><<9:<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Âɧ„xŠ ¯µjegVY`IIMPSlv†¥°·¾¹²µ²»¹¼¶¹¾´•œ¦—¡r®ÉÄÀ½¿¹³®²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtwrl_ca\^OIB?=IDFMD@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·¿Åªˆ|uŒ ˜`TCXUGajVOEJ` ¬¯¶ºµ´²¬¼¹¸µ¸Á½Š—°¡¦s¥Ë¿¹ºµ®¥¬³±¦°­¨ Ÿ¥­¶µÂ·¶´¥¨ª¨°¶³²ºµ»»»µ¸¶°¶Ä²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´¶¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wp|ovsnc^gY]^SONA?JCAKJ@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜š‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³²­¶º¯­¼³¸¸¾´‚xˆoNJ?dYBNw€”jN@\¯µ³µ²´¯¬»º¸¶¹¿Åu©šd§¿¸µ²±­­Ÿ¤¦§¤¥œ–™™™Ÿ©®¹¬««Ÿ¥¨¤«®¯§°«¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrwsmujl]\kT^\PNHDGMBGNG8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹º¶¹»µµ³·¶•Œˆ„{XFAN‡YJJXwc@S£¹³´²°±­°¹¸¶»·º¼¡±«¤s«°©«­«£¨ žž—— •’–—˜Ÿ¨®¤£¤ ¢¦¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬ª¯£¤£¡© ›“Ž”’’™–š¤¥ Ÿž§˜•’”™ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wryhutoeUadW]ROMI@IRDNC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯²¼ª™™•hN@RxpPIIKgœ€YDR®»±¬³¯®¬­¶¶²´µ®¨¦žš›Ÿ¦¨ž ¨©Ÿ¡§–š–—Ž“Ž–—›¤¨  ¢¢¡¥¥œ££ ž¥ ¤¬¥¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›ª¨««Ÿ¦¢›£œ•Œ“—•–˜Ÿžžš™¦—“’–¢ ¥¢¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ª©¤©«¦©¬«¦¡ˆxƒ|vzcwmn]QiUPOGPMMCPR@>;>49:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢ª¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¤¬¨½Â«¥½hER‚QWIJ`JT`cb®µª²´®ª«¯°²³­¥‘—“— Ÿ¢ œ£¤Ÿž¨”š•–‹–‘—’˜¢ªŸŸŸ £¥¨œŸ ¡œ¡Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£žžžš—š«¦ª±£¥¨ž œ–“’‘™–•˜—Ÿ˜œ™›¤™—”•š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’~|€uv}nk{diVRdNIHGOSNKNH<E@=2@859;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜——–¡¨¬®¶¶º¹º··»®¨ ¡© ªÆ¿Ë PAswPnKKcfts_Z^p±¯®³µª¦¬¬£›™”‘•—˜˜œŸ¢¢œ¤žš¤–——•‘‘‘’š—› ¤ªž¡¡ž¦§«¢Ÿ §ŸŸ£¦¨ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¢¥¢š™ž¯¨®²«¦«ª ›˜˜˜•“–š“•–š–›—˜˜¡žœœ–›¡›žš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰|€~wy|eyz`bSVaHIKKSTJSQM9?A67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—“’œž¤¨®­¬««¯ª¯©ž—ž¥œ¤ÇǎWSJe£Ze~or\Qkc[d_\j´°°¸¬¦¡œš”—š™Ž‘•‘ŒŽ“™¢œ—¢˜™——˜”™˜–›Ÿ¥¥© ¦¤ž§®®ª¦¢±£š£¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§¡ £±®²±´ª²®£™œž¡˜››š˜™›•–›–™œ¥¡ š£¡š™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ ž ž ¥¡žž¥ ¦™{|vvsi‚lf[S[ZMQKOOVMSMB7>C78=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’‘œ˜¡ª¢§ ž§¡¥Ÿœ’›¢šž«¤ŒyUirvupcvvXWc`cgXWVg­®¬¯§Ÿž¢ –“› œ™—’“Ÿœ¡£šž›–žšž—š¢¤ ž£ž¤¨¬­¨¬¨¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½¶¾°¬±®­©ª´±°¨«¨³µ¸³¸­²´¤ ¥ ¬¡¡¢¡ š™––Ÿ››˜¥¡ ž£¡ Ÿ›œ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚|xvjxu^m[RaIRVHFVWJCMH=KI8F<77;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©¨®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“Ÿ™¨®Ÿ§žœ¡žš™’˜ž›¢¡ £€n‚p`cXL[SZMLPXRGLLG˜¬ª©¥ Ÿš’‘”˜˜–––Œˆ‹Ž”œœž–™¦Ÿ §¥°©¦­¢ª­¶°µ²°­¶¸½¿º­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«®±¹·¼¯³°µÁ¼·¾³³µ¢¬¢©©²©«¨§¨š™žšª§ ™§ ŸŸ¨¨¥¤žª¢¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰……~vrmiwmhn\X\CWNJGMHCFN=>L>4<:6:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©©”’—™”šššœ˜˜™œš˜™ª ±¢·¤°¦Ÿž—˜•™ž›œ£ŸŠaW^e`WMQG>>?CC?>BQx©­©ª¦ žŸ¢£žžš›”“•”žž˜”…ž ™«£«±¯¹±±°±°º½¼¼¹¶¸Ã¾¿Â¿¶º»Àù½»¬®§±­±Â¶¸ÂÆÀÈÊÀÉ¿°¹¹½¸Â¾¸´»ÆĽü¸´ª³­ª³´¯³®ª®£ž¬¨¶²­£°¦¡£°±®°¤¥¯£¡ š¡¦¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¤ž¦š›¢¤žŸ›››œ‡†|trklurqhW\QFUHEJPI?EB4FH96<>7;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž  œœ˜šŸ šŸŸ•|_^e`QGD<C>E<?96N~ª³§¤£¢ ž¥¬¦ž—œ”‘šž™•ŒŠ†ˆ†xlŠ¥¢¢««²¼¶Ã½¾²»ÁÃÂÅ¿¿ÂÆÆÅÃÈÂÀÅÈÍÐÈËò·µ¾²¾Å»¾ÌÍÆÌÌÌÒǾ¿ÀþÇƸÄÊÉÄÁÇ¿º´º»µ»·°¶²«»²¯¼·¿»º«¸­«ª¸»µ¼®®¸£¦£ž¦¥¢£©¦™›Ÿ™š§ª§ ¡¡¤˜”£•”™‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ…~zrkdioxkeZ\FLMEDTMEBE7:?;549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<@?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ²²¸§¡¡«ª¡œž¡¡›š}sjaWNE>IY|obB=\Ž®¬ ™›œžž™——˜’——”Œ‚ƒ‚vrpmp‡¥¬­´¸ÄºÍÇ˾ÂÌÍÍÌÇÈÐÌÌÌÇÊÅÅÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÑÓÍÓÐÓÓÌÊÁÆÇÆÊÈÏÀÉÑÍÇÆÈƼÃÁ¿¿¿µ¾³­¿ÀÃÃÇÅÇį¿¹²¸½Äº¼¼µ®§§®¨ ¢©¥š– š™¨«©£¤¤ž—›‹™‰•˜› Ÿ£—žš““‹•…yusebgrog^ZZDOMCEPIDCA55589B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>9;AA;;>786:;>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›¢¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¤¨¬­ª £ž›–kf]TID@?K†ž¥š„ ²­£žœŸš˜—”“”—‘Œ‡„„ˆ†ƒ€€yqrokx¢¶»¹¼ÊÁÓÒÒÈÍÎÑÓÑÑÐÐÑÑÍÍÎÐÄÍÔÕØÑ×ÍÆÇÉÌÃÅÊÏÊÒ×Ò×ÒÕÖÓÔÈÌÇÌÍÉÓÍÎÓÍÆÉÊÊÂÆÌÇÉÉƿó³ÈÅËËËÏÇÊ¿¾¿½ÁÇÅÌÌÉÉÀÃÀ®°³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›–Œ†‘‹€{ruvgcgvjeVXRDNG@IQC>B=:22A<E<78<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<@?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­³·¬®£ž£¢¡œcTLJDC?CR®Ñ½²¯¦œœœ ¤¡š””•”Š}xqkebhrpr{…Š€upmqro„œ­¼ÇÑÑ×ÖÕÑÖÍÔÖÖÓÓÑÒÔÔÒÏÑÃÐÓÖØÕÕÒËÉÎÐËÆÍÒÊÒÕ×ÙÖØÓÖØÍÒÊÏÑÌÏÑÍÓÐÀÉÈËÄÌÍÌÏÏÆÇȶÀËÀÒÍÌÐÇÊÈÀÄÃÈÏÍÐÑÏÍÊÈ͸·»¨Ÿ¥«§ž˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„}xsvpcaerc]R\JKGAFIJ?;A8>5586;86:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÁűµ¨¡¥¥ ¢¢[I@ADAFQv²¯¦š”—Ÿœš  ž›œš•‰wica____^__]alusppnlpou€w˜¸Õ×Ö×ÖÓ×ÏÕÔÙÔÔÎÏÕÔÔÑÑÌÐÍÓ×ÖÓÕÐÏÒÓÑÉÓÑÈÐ××ØÒØÒ×ÙÕÖÌÏÏÉÍÒÌÎÑÀÇÄÉÇÏÎÒÑÒÈÌÍÀËÍÆÔÏÌÎÉÅËÇÇÉÌËÔÔÑÕÏÒÌÓ¹ű¥¨µ®¨›¨«¥²¨°³¬¬““ŽˆŠŽƒ‹„Ž™“™‚…Œ|zqstmacim_VQ`JJCECSM@<>43:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><?@=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯­ªª«¥®·¨«·×ÔÕÙÙÑÎп¼Ìɶ¾®§ª¨¡£¬fC8=>DX‚ª¨Ÿ—•—™šœŸ˜›œ“}qecb__a_^a`^a`_`emppmknptyvi|©ÍÔØØØÑÅÓÒ×ÏÓÎËÒÍÕÔÑÊÏÌÓÖÒÑÖÍÏÕÕÑÅÑÓÊÐÔÕÖÎÓÑØØØ×ËÈÎÄÉÏÍÊÌÀÉÁÉÊÎÎÐÌÐÎÎÌÏÏÈÌÐÑËÎËÃÉÇÊÍËÌÒÓÎÓÒÑÐÐʽȹ°®»¹µ«¶°­¨¸­³¿»±šŽ ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…‰zvopokadnpaX\[IFFDMYE;@=33<<87855;>@=9<<8<>9<@;@:=8?98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ¤§Ÿ¸¶µµ¬¤¬®¾´°ÀØÒ×ÚÜÖÎÍÊÃÒÏÁÁ±©¬­©¤²{HFB;W¡›•“–›žžžœ“–—”ˆk^^^adb``aa```^__^\bmqnnrrtuzqbmžÇÕÔФÊÏÎÓÊÍÎÄÍÊÒÒÎÆÎÌÍÔËÎÒÍÊÖÖÐÌÑÔËÌÐÑÓÊÎÑÕÒÕÖÊÀÊÁÆÍÃÈÊÃÍÄÆÉËËÏËÎÍÐÎÔÌÆÉÐÍÉÇËÆÇÂÆÊÌÎÑÑÇÐÏÎÎÌÐÅÇÁ¸¹½Ã½ù²²¾°»Ãĵª˜¥¡˜–‘••’‹”š‘””•‚‰†yqrkmh``qhYXhVMGLIQQB;D?;68:8:;57==A;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÄÂÁ¿»µ²±Ç¸ÊÕÖÙÚÛØÌÌÏÈÖÕĵ¯´¨ ­—xlopwšŒ—•“‘‘•–•‹|ebbb`]^acb`__`aa`_][]gqqpqrokqytenŸÏ͛—ÖÉÃÈÈÅƾÂÅÎÎÇÅÆÍÊÑÈËÍÍÅÐÒÏÍÌÔÊÇÊÎÏÇÇÏÒËÐÏźĿÆʽÃÇÉÎÅÃÈÀÇÎÈÄÍÊÌÐÈÅÅÐÉÆÂÆÉÅ¿ÁÈÍÌÌÏÃÊÌÉÇÌÐÅÅÈ»ÇÃÉÉÂÏÁ½¼¿°ÁÉǹ½ª±²§¥¢œ˜›£™—™‘•˜‰‚xoudk`^fqa[W`GIHGIMTG?J=64355==48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ¼¹ÌÌÆÐÕÕØÚÛØÐÉÏÏÑÓÈ·»»­¤¶~g‚…¢ª“–…ƒƒƒ}„„~s_[^]^`^`cdc_]\^_``_[Z\akrpnnijmnzgU€À¢y»Ïø¿Âººº¸½ÈÅÁÃÀÃÇÊÈÈÉÇÀÅËÆÈÊÍÉÄÁÊÉÁÁËÏÄËÈ¿¹Á¼ÆȾÀÆÏËÄÀûÊÇÈ»ÉÆÅÊÁ¾ÂËÆÅľƾ½ÁÄÆÌÆƼ¿ÊÃÅÇÒÅÁÉÀÊÊÆÈÆÐÃÃÆîÄËÇÃÊ·¿¼º³©¬¤¥˜Ÿ˜¬£¡¦›£ ›•|wsufj[anmZ\XRDLGBGDLDFR@54335@=3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¾¸¼ÊÏÑÌÇÂÃÆÍÎÎÌÕÏÕÙØÙÏËÒÍÍÎÈÁµÃ¾²°¶l^y|Ÿ‘Š’–†z€„…uxurp_Z[]``bcdded`[\^]^^`[YZ\bnqnjhinmsyVj”{«ÃÅÀ®µ¸°±²°°Á»»»¹¸ÀÁÁľ½¹½¿¹ÄÉÅƽÆÀ·»ÃÈ¿ÁÉ»¶»»Åÿ¼ÂÎÃƾ¾µÁ¾Ä»½Ç¼Ãºµ½ÆÄÂ÷À¶¶¿¿¼ÍĽ¶ºÈ»¿¾ÌÄÂÆÃÆÉÇÉÆÐÆÂÌȲÇÉÃÎÌÀÅÿ¼²·°²§¨¨¹°¥­°ª­¬”zwxkeh`hodV^YJFJFHKAEBFJA9:658853;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µ«·´²¡žŸ—š”–šŸ¦¢ž·ÅÂÄÈÎÒÊÊÊÇÍÍÎÑÈÐÆÕÔÕ×ÍÊÏÅÉÅÇÁºÅ½¬®¦`cv’‹ˆ‹„x††}ƒ{ttc\\]^``bcbbdeb]\[\^\^]Z[\]grplfelmo{x^f’ǹ¿·¬¯®¥¨¬ª¥·³µ³²³´»µ½±·°µ®²»Â»Áļ¿º´²º¾À¸È¸´¼¶À½¸½ÇÁûµ¯³µ»¿´Å¸»µ¬¹½¾À½±»¶°·º³Æ½·¯¼¿µ·µÅ½¾ÃÆÀÄÆÆÇËÅ¿ÆÆ»ÇË¿ÏÉÇÃÆÁ÷ý½¶¹¾Ç¿¬µ»µ·¶Žytxggebkn^V^`FKHHJGBDAEF?=:566633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÍÈÅÈÍÌÐËÍÈÉÈÊÉÊÄÐÍÒÏÍÅÇÁÅÁ¿º¸É·«°™[goˆŽ†ˆ‰zx~…†vw|sh]]]]_`_`da^cec_^\[^\]^Z[[\_komgehklo~mhº¸¶³®¨«¥œ §¥œ©ª±¬©«©³­µ°²¨­¦¬³»º¶Ã¹º¹°ª´¹»³Â¹¯À±½¼»µ»Ç¹Ã·­ª¨°²À¶¸½°±¨²³µ»¼«®¶§®¶®¼²±ª¸°®»®»¸»ÀÁ¾ºÃ¿ÆÃÅÀ¼ÆÁÇʸÅÇÅ¿ÇÃùÄÆ»ÆÉÌ˳¹Â½»³‰tvwki`bliYWW[ALLMJEAC?FA:::996854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÅÎÒËÃÅÁÄÏÇÍÁÂÆ¿ÄÄÃÃÊÂÉÊ¿À¼Âº³µµÃ®ª°’[i~’ˆŽ{x}‰…y{„€wn^]\\]_`__dcbdcb`_]Z[ZZ]ZZZZ\dmnfefgikpz‰·¯´¬£¢¤¤˜ž¢ž˜š£©¬£§¡«©¬«°£¦Ÿª­´¶±½¸¯·¯¨­¸´³¼·³½°¸¹µ²¼Á²À¯¥©£«±³³¨½ª«¨«¬®µ´¦©®¡¥¯©³¦¨¨®¦¨·¬±³·ºº»²¼¾¿¾Ä¿µÁÀÇÈ·¿¿Å·ÅÃÀ»¿Ä¾ÄÈÌÊ¿¿ÄÀÀ©‡stsji\aodWVXPHZSSKFFE>?@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÐÏÌÃǹ¹ËÂ˾»É¶½Ã¾ºÊ·ÁÄÁ´¶¼¶±¯µ¼­©«’cmˆƒ‡‹€z}~xt~|swe_]\\^_`^_ccab`a_]]\ZXY[[XWY\_fkecedfhlq‚¥¤ª¢š™ž¡‘š¢˜•Ÿ §¢¢Ÿ¥¥§¥­Ÿœ›¤¦¬²°¶·§°¬¨ª´«³¹°¶¶®¶º³°ºº±¶¤ ¤ ¦±¨¬©¹ª¥§§¨§³­ §§Ÿœ¤¦¬ŸŸ§¤¡¡±­­¬²µ³³°µ¼¶»ÁÀ²»¾ÃÁ±¹¹Â³À½Àµ¸¼½¾¼ÂÇÄÃÄ¿ÀÄ „yqlbf`ko`UY_HNhOTHFKF<=@=:;;826536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;>97776788666;::;9:;<859<:>>@;Èµ¶½¸ºÁº½¶ ž• ¦º¶«³³»³ÄÏÉËŸ·ÇÀÌ¿¸Ê·»Å¸³Å¸³¿À¬¶¼²¬¦¯´­¡£’ir†…†€|xusomjiipi_`]\\\^__acb````^\[\\XYXXXVX[]^dbadeedhjl†œ§¥¢–—“˜Ÿ•“‰›Ÿ ¥›žŸ£¥¢§š¢›Ÿª¯­±µ¤¨ª©¬¬¤´¸¬·°¬³µ¯³µ¯°ªŸžŸ¤¢²¥¦ª¸­¢¦¦ ¨­«™Ÿ ž™Ÿ¥š™£œœž°©¬¨ª«¬­°²¹¯¸¹º°¶¼»º«³²¹³½´·²±¶µ¿µ½À½Ã»»½—„{sl_e^ddXTW^IW]KPGJJGA<??A;?<05635:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»¸ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÅÏÈÈÀÆ»»ÃÃϾ¹Ç¸¸¿·²Â´±»»¬¹º±¢Ÿ©«§˜žm~…†xrmomkb^bff]]^]]]\]_`abccba_\[[ZZYXXWWWWXWZ]accddefgiq‰‚“«—–“—’“™ŸŸ¦›œ¤¦¡¤›Ÿ¡›˜®­­®² ¤¢­«§¡µ°±²¬©°³¨º³§¶¡¢Ÿœ£¡­£¢ª¶«¢£¦¦¦£–™—™šŸš—œœ­¡¬¨£¤¦­«³³ªµ°²«²¹´¯ª¯²²³·³®©­®²¸°º¶º½¿·³±”†zuf_f_[YVSZUK[QLJEHKIC=?AA@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½¸½¿¶¾¼¿²¥£˜¥±Ãµ¶½­´¸ÁÌÈƿŶÁÀÇζÀý³¹¹²¿¶±¹»­²µ¯Ÿš£ª¡”šxƒ„xoqtqhediec\\[[]]\[^`a^__`^\[Z\ZYXVWVVXWXWUWacdbbcccfissGM}’“š“–‘”›Ÿ›–  ¨£žž¨œ›š«§®°ªœ££·©¡ ®¨µª§§®±¤¸°¤· £œ™™ª¦¡š­¹°£¡¤œ£  “•¡”––œ™˜–—œ•Ÿ©žª¤¢£ªª±­¨´¬ª§­³°¥«®³±¯°¯¯§¨¨²®²´°¼´º¸®£”‚zve_aWYXSRTKM^LPLGHLKE=@>=B<:7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´ºÂ±¾·½­§§¢ª»À½À¹®´¸ÁÌÇÅÂýŸÈ̲ÁÂÁ®¼»µ»¼µ¹¹°¯°ªœš¡©•‘Š‹€€|wqilrtphhedfa\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWVUZbbaab`acdkregnˆŽ–”˜’’˜š•Ÿž¦¥£¦§ŸŸ¦ ª¯¦Ÿ¡£¶§¡¡¢©³¢¥¨¥°¦±®«µŸ¡–•©¡¢”­±±Ÿ¢£ž˜œ“Œ ”‘“˜˜’—˜˜—ž§›§¡¢š¤¥¥«¤¥°§¥£«¬­¦¨®¯¯«¨ªª³¦¦«¯´±®¼¶±¯¯Ÿ’{xseb\[]XNLQHRaMVPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8847763321./2556;:8;7876<;:;;A8x»»±¶½°»±·¬ž¥¦¬¸»¼Áź²¹µÄÉÉÀÂÆÅǶÅijÁ¿Å«··½¶½º»µ²¬­¨™™Ÿ£‹Št‰ˆ~vncafihfgifil`]\[ZZZZ\]\[\^_\ZY[YYZ[WUXWTTVVRTRT__^_`]__aci……‹‰Ž—‘“¡—ž•›ž¤¡¬¥¤¤££¢œª«¤šž¥±ª¡¡ž¥ªž¨¢Ÿ­¬ª©®­¢¢¢•˜¢šœ«©°›Ÿ¢ŸŸ—™“Š‘’”–˜˜“œ¡£œ¤ ¢• ¢¤¥›£«¥¢¤ª¤«­¥®²©¦¥¦¦´¦ª¨­³µ´¹º¯ª¬žŒsqp`[WVVRGQOHZ\ORJTKSLEGIC8;;=<9667:9;:976977:;:=<<6;<8>598:88659:;<97?<9678452121..1426:8698598989;9@9{µ´¬´»²°«±­¨§¯¹¹³ÀȺµÀ¯ÅÈ̺ÁÉÌȵɼ±¾ÃÉ­±¸Áµ¼À¼´µª¬¦–šœœ‰rˆƒ{tiijlgjlmkjle]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURSNPY][\]]]^^aclˆŠ~‹Š‹‰”™™¡ššŸ§¨ª¨«§©¦£™¥¯¤•™¥¯© œ™› Ÿ®™œª³Ÿ¦¦Ÿ££¡””›––’©©­›œŸ¡¡›”Œ˜Œ‘’–•¡ £œ£•›¡£¡˜¢¨£¢¨« «°¤®¸¥£¤£¬­ª¨«¯´·²½µ³«®˜…uti[XYSURFXLQ[XMUOPLQRIOIB=??A?=75799<<977:79:;<=>;7;;:=67:;8976989:6:=99577571141-+/434988::8::748=8?9~³­§³·®¨¨¯®›©¨¬·¶¬¼Ê»¶¿¬ÌÆŸÀÎÏdzĻ·»Âȱ­¸¿·¼¾»³¶¦© –˜™—ˆzt€vwnmhmmmpggifd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUSSNOQYYYY\\\]^_dz†|„y†‹…‰“”—Ÿž™žª¨¦®¬©°¤¨šŸ¬ ••¤¨§˜šž®–˜§ª˜Ÿ”¥ ž’‘’‘“•¨ª¥š˜™žž—ŽŒ‹“†‰ƒ‹’•‘ ž¡¤™–Ÿ•š¡¢ž”›¥¥§©¨ °°¦±½§Ÿ£¬´«®§¯´°¹µÀ±®°«‘~rtcVTUNQJGVPRRLLXNKMORGNKACFDC>A75889;9:7::7<=:;@>:9;9:?759:9876958779;85576661320-*.102877;99;8948;8@8´¬¦±·ª¥¢±«ª§©²°¤¶Æ´¹º³ÊŹºÁËÐʱ·¸¼½Àñ°±·®´´»³´££˜—•„€vkglnqnqjokdege^ZYZYZZZZZZZ\\]\ZXXXYYWXWUUTRSUSVTQMNMRWXYXYX[[\`iztyo‚‡‚‹…“‡‘‘•˜—œ§šŸª¦¦«§™ ¥›’Ÿ£š——†…’›¤•¢œ––•‡¢š›“ŒŽŠš¥§œ••—œ‘“ˆ”Ž‹Œ€‹’’’¡š ¢–”™˜•¢¦š™¤§©§¡ ´²¨³¸¡£·¬ª®¤²²¦µ»µ«¬±¢Šzsn^NQQMODNNNPKFNNJJNNQIMJAHLIHC>958889:;69:68;99><8:>9;?8789:886857688974577820301+)-/12876:999984988A7w¶§¤¶°¤§¤ª¥ ©¦¤³ª¢²Ãµµ²³ÆÅ·ºÃÊÌƳ­º½´¸À¯®©°ž¦®»¯­ š›ž••ˆ|„n__frpuqinieghj_XXXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQNMKLSWWVWXXWZ]allpj~‚}ƒ|‹‡’Ž‘œ Ž™œ£¡£˜¤—¡œ•‡™šŒsƒ~Ž—–†’š”Ž{™Œ‚‰€Š˜ £ž“˜–…Ž‚”~~tŠŽzˆ“›šš’–Ž££Ž‰š ¡¤¤›¢´¯¬°­Ÿ˜¦¸¦¥°¡±®œ±¼ª©¯©™„xtdVMRPPMCSNLPMBPQHINSMHJJDKMFKK=749888;;69;7:<9::;79?9>@79:<89764445874312485/0102)(,-02764789::66:87A7x·¡£´¨¦¥¨£¥¥¦¦¦²§¦´Á¸¯´°Éĸ¹ÀÎƾ³¬ºÁ¬­Ä­¨¢¦’¦·­£ ‘–—’~xfWV_gfighnciigb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTQMMJGNSSSTUTVXZ]ifkgywpLVo€”„‹š–‰’ž˜•”–”–Š€”‰_;Vo|Œ”Š€Œ’Œ††r‹„–y{†”•ƒ–Žƒ†}“xqp†}‰Ž—š™“‹ŠˆŸ˜‡ˆ–žš¡ —§®©­©©ž–­³¢¦­™­«˜¨´£©­¢“tn`[NSRWLDTJPMLFNOIELQMKOJIMPFIJ=7599999:7:;:>>8:==7:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9y· ¢­¡¦¦ª ¦©§£ª°¨§´Á¹°µ°Ç¸³½Ï¿¹¯®µÂ§ªÄª¢˜ƒ”œ±£š™‡”‹‡~sv]PLQUYZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MNQMKHFHNQQMORTUXY`jhbu|oM@>~•Ž{†“‹ƒ‰Œš–”‰’‡…•†y‰`JQnx‹’„~„Œ‹„m~“wuvx„špQˆŠ†|~y”vgw†ˆ~Šˆ•‹Ž‘“—Œ„Šˆ”…›‚…’›–ž”¤¢¨©¥¤ž›°ª¡¤¤‘¦ª–¢ªœ¡¦§Šwnf^\HQQSMIUMSILKOIHFJNLMTKQQOFJD=769:8:;;8:;8>?99>=8;<6;;478;6775344696/3/.115221/,')+*,4833989:99::::?9w¶›¢¦Ÿ¡®¡§¨¥§¨¯¬ª¶¼¶¸·³Á»¶§¹È¸¶¨¨µ¶ª²¼§ž•Ž‰”©–•‹Žƒ‚~xqoXMKMMNLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDCINOhYNQSTUZnnpxeeYRŽˆ“†r}…{„‹“’™‹{†€uxsouptŽŽz~Š«…z{hv{Žprmx‹’x{€{€wsr’xhu…„„…|•ŠˆŠ‹€„‹€”„|˜”œ–‘Ÿ©ž ¡ ©¥Ÿ˜§£“ Ÿ–žŸ¤sib]]JWPRHKXROJMLRJJJLPHLQMRTMFIB=78;99>=:;<98@?::>=7==79937785675251472/2.,./200/-+(().12721987:8775:<;7v®™£¡˜Ÿ´©¯ª¥­«°±ª½´²»¸¶º´±Ÿ·º²ª¬©¨²¯¢š‘”ŽœŽ‘~w†w|wpojYKHIHGEHHPTTTWWSTUUUVWWWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LNQQSV^uytbsŠ”—zexuw~ˆ|ƒ˜’€q†{v{ok~­|t‹z†’€|tfu|†lohs|Š‡€myq}qmvqhq~ŽpD‹…‚ƒ…wwzŒ†}Œ{u}Ž’˜‹’š›£–™›ž¡œ–‹¥šŽ—Ž–˜xongc[XXUQJSUTOPNPVKNKOOJROIOPLFD=;79;::?=9<:99??;8;=7<9999266856633611224.,,-..-0-+*''*.1362/876966527995y¦— ž– ¦°¬®«¨©±¯±«¼¸«»¾¸³¬§›°§¬›–œ¥©¤¡˜™Ž„’y‰‹‹vq|mupjmjXKFGEA@CDHLLMQRPQSTTTUVVWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zYJNOQTX]fppi…¥©À}rwazwmzw‡y{‹…olŒ’xsxij€‚q–‘Œ}•I’™ngw~‚mjdly…’†krl|nr|†imps‰…†{~{wptt†‚yyp|Ž‹Š“ƒ–—˜š“––™—–Œƒ‰Ÿ’‹’†—€pjoooYVXTRRYORUTRXUMNHMKMOKCINGF@:99;99:><9<;::=>:8:<9?868727565541432/024*+**-.+-*(*(',-1250,5567485HA895w™‘›˜›Ÿ¤¬¯¢­ª¨µ¯®¬´¿«¼Ã¿¥¢™•¤˜ž„‹”¡¡˜™‘“‹sŽz€†Œ†uotlpleljYNDFC@<>>AFFGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_IMOORVZQY[_¦†a˜fpwc|nl~yŠˆu‡…tl™‘ts|ijŽLy…“‰„Žf1v‡rk}}ƒtfeu„„…€filukp€|hqq|n“{t~}qqoum‚wyujyˆ‚ˆ‰ƒ–’’‹‘””Ž—€yˆ—ˆ‡Š†€ˆxlkpheXR[XYY[NPUVYXNIHEJJHGB@GECG=998;9:9<:9;:::@<9:<98>787715234533645031.**+),,++)(+'),,226,,4775478iO8;5m’ˆš™–¤¨­ž±ž§º¯«²°Â±»Ãǚ–•™‹Ž…z„˜•Œ‡q‡‚tˆŒ†zpsqopdpg_TFIC><;9:?@ADCEGJLOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOOQULBIQIb®²žpyuj{kp‚€„€z„……yr ”tx€st”‡5p¨¡¡„¢…vp†{†|tŒ®‰hgbjnrmpƒuioXupŽ›‘vm{}nrnp€{svnbuƒ†€…ŠŠ‰‘‹‘‹‹ŽƒuxŠŽ€~ƒ€}Ž|srqm`\]^\ZYa_RN[ZXWLHJFIG?CABH?CD=;:7=;:;;9:99;:?<88=:8;66651121253474531./,,+)*))***)(*)+/3DM2166643<vR7=7b‘’ˆ•‘¤§ž¯•¥´©®°®Á²»ÁŖŒ”€ˆ|n’‰ƒŠ‡†u‚„l•ˆˆ{uxxlwnwcj^IPG=?7449;:;=>@BEHLLLLNPQRTUVWXZXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL8DNRSDJ„s~zzt}ku†‡{|„ƒ~‹}u¡™y~…€„™„šœa†ªŸŠƒŽzwˆ~‰ˆŽs‹—„{]dqtz|wŠmhjbyo…‚zoxu…zptzxkni]v†}‡|‡†ŽŠ’—ƒ…Œ†}q„„}vw{|‰xqtugh`[\^S\g^WQTX[UGJJDKG?F@DC>AA=;97<;;=<::99;;=>79>9985653244004645554-,)+('''&(())((+++/00Uq=23331E~W4=9\ŒxŠ“Œ‘œž¦‘ ª ±¨¯À²»Åº–Ž‘“‡z†vk‹‘ƒ}ŠƒŽŒxƒ€s „Š}}p~zhvkRXL@E211376688:<>AEGFGJKMOQRSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMOQLKT\XRKg‡zˆxzp{ŽŠy{ˆ†~–‡v¡™‡†Ž’”¥¬©H†®°®‹€”‹‚‹‚„’©‡€˜˜Šœtm|†‡~Žhghyn…‡‚…q„†Hl€wryvhmk_v}ƒˆ‡…‹y”œ›‰‹ˆ‘zuŠv|xmow~uusm\^^\cdXgf\UPPWYPDLKFOICFCCA@CA=978:::;;:888::?>6;>7585773344236656778;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|}‰…‡Ž•—’– ¬ ¦¸¯³½³—’‹˜‹}tp~‰’~}Œƒ’”}†~†¤‡ˆ‚ˆ…x‡‰~s„x_cWKB60./23124668:=>?BEGHJMNQSTUTTVUSQOGC?80,#‡[??84.]–ps£UFIKMMPW`XoY[]h‹‘…“‚€ƒ‘}…ˆ€™” ¡˜”›š¦­“™»±§»Ç苌¡¥Ž“‰‘|qƒžŸ‘w……‹‡ihp„tŒ‡„Šr†‚wˆ€{v„|muuf”Ž†ˆˆ‡ˆ‡ ª¢–‰Ž—zˆzyogkx~|€ule^[[^j^bg`ZOLNXRQIPJDNGCJDCADDB<:87=<:<:88778:==8<=68656623444576867<BB?<8:>CQ^e\G2'&,,--.1(?‹[.310Oƒ_4?;nupfw‚zŒŽŠš›¤¡¬¦ª®°—‘‘„¡”„xwŒ”|~’†’•Š€’›Žƒ€ŒŠ‚‰ƒŠlpj]B@4--//..02234778;=?BDHINQRTRSSTRPOHDB<87/9C><<63.l“—MPHILLKNV`cffltš˜˜‘‘‰Œ˜‡’‹ Ÿ‘£ª¥£«“©¶¢¨Á­ǯxº”š|¡ž™„“…‚Ž¡Ÿ”™‘…Š…™‘–lpuŠŒ‚•ŒŽw„qm…Š–‘‚…ˆqˆ –†‘‰–¤´¨›Œ”¢ƒ‡’ƒ}kjj|‚ƒuc_e`[hl^ll^WKHNRQMLLFIPCDNFBCEFC=:96=<:;:987767;:6=:785456344566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYo‚ou†qv’†~—–š”žžœ§ ©–“˜žge¤š~„’‘y’ˆ‘’}Š„˜’‚€€‹Œ‰†‡„‰…xx~gMR>/..,/.-/000212467;?CENORTPPQSQNPIED>;<:DF?><752<?R5HHHLLMNR^nŠ{r€|šš¥¤ ˜Ÿ–¡”œž§¨ªŸ¨¬©ªµ—«¿«¶ÇÈ·ÈÐϾ› pi«©Ÿ„“’…œ š›™¦’‘ˆ•¢››xz~”˜“¢’——”ž{w•’ª²ˆŒ—Ÿ|”›‘•˜£¡¥µ¯œ˜§‡–€ˆlss}~sja^b`bhd`hg\REJKPOIILFFMCHLFFCBGDA:85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Ppt`m}awŽ}{”ŽŽŠŸ’—ž–›ª˜žªBD}‡‰‡˜x‚ŠŽŒ|Š†Ž‚€‰‹Š…’…ƒ†‰€‡w^bP460-1/,.0/./..0015>AAMQRSQRSURNSLEE@<>=FG@A@8662<9;FHGIJNOQYm…v”‰ ¤§²¼·£­««¦¨³«¯µ±±­»±³½›²Ã«ºÉ˷ÿ¸¥¢°³¬­ª£‹–˜„¥¦ £—¦™¢«¨¥ˆ…”¤¡ «¡¤¨œ±‹•£¦·º› ¢¯’¡¢£¡«®«²´¡”¤©ˆ™ˆ’‰•yz~†€ibi]fc_ed^gg_[OCIHSNFHLFJGFFHAKFCFFA;87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLhbWinXz„v“…ˆ‚›ƒ’‘Œ’Úȝ–sV—ˆˆœ|†ŒŽŠŠz‡‚‡Žƒ„‹…†ˆ’†‚…‰‡ˆ‡‡qna@E64<2/110-,+-0.-4?CAMUPRSUUVUN[PGGD<>>FHCEA7;<5C;=FKIGHQOPW€’Ÿƒ¬¢±©°¿Æ©²Åµ«²¿²·½µ¿´Á¶»º£¸Å¨µÈǵ½¹´¨£´­°±›™’šŸˆ§¯«¥”vŸ¤—¡¬²´™–ª®¨®¶»²º¬°µ¢±¬±µ»¶´®´Ÿ¦§£§š©¯¬±¸·¸¦šµ¨Œ¤Ž’Ÿ†x…w[ceWgcbdaag`[TJDDLUQHIJDIGEA@@KDBMG=867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AFWQJL[YQbbWyup”}„†“u…€Œ{¿»£¼‚´”“›„ˆ’‰ˆy†€Œ’Œ‡„Ž‰††ˆ†Š‡zxn]V@EN<6:45AB764//6CHBQ[OQUWU\WP_UIKJA?>GKFFD;>@7D7?BJJEFVTP^Ž£¬¢±³Á´¶ÀËȵ»Ä½²³¿¶·Á´¿°·t±³¦ºÄ¤°Æ¹°²±´¨¤µ¶ª± ¢—›¢’¥°®¦­«§¤˜ ¬´»¢¨²ºµ¼¿Ì¿ÅŽ½³Á·º·¾¶º·¹¬«°¥°©­½°¼ºÁÁ«˜¹§”­Ž——©ˆ~ƒ~lXdbYlfkfX\cYVSIGFLQGCHIAHD>?BBL@@MD99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FRLALQVSYUZvjo~Žƒ€Ž„nzsx‡b¹¡™£‰””–’”“–‘‡†{†•Š€„Šz|Š‡†}Š‚‹ƒ•}wzueP\dGEK;Qca[^SF?;HPEZcQRYXZgYT`_LSPEA?IJHEEA@D<E6B>HGJLSYT]“®·´¹·È¾¸¼É̺»À»·µ»º¶½³¹±Å`u±¤±šžª½©¥¨«ª¤¢²µ «¨Ÿ•–Ÿ™ ®¥§¦¥Ÿ£“£§±´¨²³½¶Á¾ÓÉÉÓÆÃÅÌÂÊÃÀ¾½¾»¼·´¯¸·¶Ã¹Å½Âǯž¸©¡«¤§µˆsacc_Yc`jgSX`VRUIEENK@>GD=KA=B@=F>;H@796379>489:57045/26389374426?8@>GKRTSQPOQQPJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKE@IMPRKQ]glkp…slrrs‡ÕÀµ™ •˜™‘Ž—‘––Ž†‡}†ƒŒ–Š~ƒ‚x{Šƒ‡{‹yŠ‚—~t}zkfpuY]\Pedb`ed][XW\MdmURmm_n_XgdTYUJDBKKIFHHHHBI:D?HKSTU\Z[“¸¿¸½¶Å¿º¸Éʺ¶¹µ·¹²·´³®µ¶˜du§œ­p^¢¬œ˜ ¢›¤žª¥”ŸŸ“Ž–™˜¨Ÿ¦ žš™ƒ¤ž¬¥ª°­¸°½¹ÔÑÏ×ÐÊÌÒÌÏÎÊÆ¿¾ÂʽÁ¼ÁÀÄÄÅʾÇͲ£º°´®š«¸º˜€{m_a]Z_bZdcQ[`SPKCAEFE<@E>AHB@C=:E>=J?47535;=468977022/24169775555D3ELM>51/006:477@IOI;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODQ[Yh_o–’”nlotu‡³« ¡Ÿ‹™œ™ŒŒ•‘š‘…ŠŠ~ˆ†Œ‹ˆ|ƒs{Š‚…{‰t‚Š†•s{ylmu{hreiligjji`fiilZms–­¤¼ˆ†g[og]YZTHKNPJKPKSQILAJFJO_^afia—¶Æ°¸²º¼´°ÄƵ¯¸°°»«²±¦ª·«Œµ§š§šN™ŒŽŸ–‘¦˜¥•Š““‰‰‘‘›¡—š•–‡žš§›¬¯¨°¨´´ÔÔÔÖÓÌÐÓÕÍÒÏÌÅÂÉоÉÉÊÉÑÇÌÍÂÏÑ·¯Ã¼Ã¹¤µ¹Á¢ƒpe^__ZaXZgZQ]XOPBBHEBH;AC>AG??A7;D>@H=46655;:687654/10146278875367C5B8?-0-1349=97,.,1;FK=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYReVs˜‚gqoyyƒ ©ž¦—Œš›—‹•‘šŽ}‰‹„ŠŠŠ‡|„‚p‡†{‡rƒ’‹Ž}qxulqx~qznxsmipmcimpxiw|~Ë¿Áߧmcxnc[b`JPRUNY^O]\NPNTPTT\nmv‚q–­·«³¦¯µ©¬»¿°ª´¦¤¸¦«® «´£Ž°­š—˜Œ‘“‘„Ž›¦‘œ‰ƒ‹„Š‰„‹„”•˜—”›‘œ—™šŸŸ«¬¥¨¢¬­ÏÒÕÒÎÌÓÔÔÏÔÑÎÇÃÔÑÇÍÒÓÓ×ÌÑÑÄÒÖÅÁÎÇǨ½·Îž|pg_d_WaS_[PQTQOH>@FABE<@A>ED>??:==<<JA45465<888664412/03526768533;=<E=@11+/249>5901022-2DN3)/3.32=N238C}_2A†tD:==I>@CFH<UQMNZu†…Šwlwp}~¡žž¡ŒŒ˜““‹Œ’•…y…ŠŠˆ†~‚{r~€‡z„u…“ˆovrks}{w{sxrk€srioqzyqz¾Ëš~‹±„vr„vhak]CZZ[VecXdjSX\]`c]cwz}‹˜©¤¤¡Ÿ §¥ª¯¸ª¥³¢¡­¡£­¡§±Ÿˆ¦š“’‘‰’ˆ“‰j”¢Œ™„†~‘ƒƒ“—­‹••™Ž†’‘ž—¨°¢¡¡¥¤©ÉÍÏÈÂÌÑÔÒÔÒÎÓÍÆÖÒÌÔØÖÖØÔ×ÕÉÔÚÍÉ××ÑʬÃÂˍupebaYUZT\QKGJJJ@;:;DAD<BC>GB>BB;<9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/--;R017/532FD28>nb5=tM99@I<AD?A;OLFJXp€u}hsxr‚‰€œ””…‹•‰Ž‰ˆ†Žxƒ“˜ŠŒ‡ˆ‹ˆ~‚ws{}‚‡wz†‘•ƒnwpmuux}t…|yl‡vtn}v„tx{µŒ;@‹Å¥~Œ|ieWICfcecgjcmw[^fhknhn€‚‡‘‹œ —˜ž££¥±£¤²Ÿ¡¥ ¨ £±œ…ž’‘‘‹Ž‹†ƒ„œ›Œ‚„…y”‚©•£Œ‘‰—’‹~˜‹š’«³˜›œ¨œ§¾Ãƹ¶ÆÎÒÑÒÐÌÒËÈÔÎÐÕÚ××ØÔÙØÍØÛÎÉÙÚÑÕ¾Ê˵zypf_[SWR\WFGJIEE=:7:@@B:FD?DCADB;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?1*(.BS39254/7K75<`bA<svV87AH:?C><9QECJTknnpbpqt†|—‹~‡’ƒ‰†„‰‡|x…––ˆŽƒ‡…†z„xqz{ƒ†uy…Žœy‹p|oozq{€qƒ‡€nŽzuw}|‚t~|†‡¯sXªÂ¶‘‚pmb=^hrpqpnxvehoruxqz‹†“‘š•Ÿ•‡Œ“š šž©Ÿ¡¬›¡š˜Ÿ¥žŸ«™‹š‹‘…}ˆ‡ƒ…‹Ž ™“ˆƒ‡~l™z„˜†ˆ“Œ”Œ†|œ‰”®ª”–˜Ÿ™§¯¶½©­¾ÇÌÉÉÌËÐÉÃÒÊÔ×Ù×Ø×ÕÛ×ÓÙÛÕÐÚÚÑÖÈÔ˖{}jj]\QTT`ICFIH>A>=7:=?;=G=?AAADA>>:87DB755479.556435532323647553458EBDCEB56<FNSM[nfcnskaV>,4LG865434BF4=W_hLux^8;?F<<B<99D>CGRj^mdbfkv€ˆq‘š€z€~‚‚ƒ~ƒ{|„˜‡‹~…†€v‚yn{{†ty’žŽ vŽu‚su}s€„o‚o’„u|…zv†{‰·Å¤Áɸ–›wpeNfczw†¢Šxyv{ƒ{„vm“–“”Ž—‘ƒ‰–š––¥œ—Ÿ–ž’‘—¢™«•ŠŒ‘‚Œ…ˆˆ†‘ž›™ˆ†Œ…—zˆ‰Ÿ—ˆŠ‹‚}¡‰‘‹¼¡˜“˜™©¦¦®Ÿ¨¶¿ÀÁ¹ÇÊÎÎÅÍÉÑÖÕÕÙÕ×ÛÔ×ÙÚÛ×ÛÚÙØÎÛƈ}{ikgaUYVWNLENC;==<8:;=9=@6=?@<?=<9867CA6455=80665547745613854564557HH=DJE7925;H>;::7IP]ZRUXK9T>;95327I8=NYMHxxd5=>C==@:6:>>@EQ_Xea][htzylŠ’wvzŠ{~€~|„z}‚‘‰„…z„‡zu}tm|}†~t’ž‘žƒ‘{†~x~xŠŠn‚š€t™†~‰„{~z©ŽÃ¡½‹œ¤œ}‰„}‰r‹Š~s¦šœ˜“…{Žˆ„hGq ¤‹‹’…ˆŠ“”Žœ™’”–Œ•Ÿœ” ”‘‹~ŽŽ‹„‰’–šžŸ‰Œ”’‘‚‹€¥™ˆ„‚…„¤‡‹‹¸˜‘•–¢¨¡žž¤¯·ºµ¬ÀÆÊÐÈÇÌÏÓÓÒØÓÕ×À×ØÙÛØÚÚÙÙ×Û¹{{znkhYb]TPOIDLB<<>99::99;=6?>><=9:;;37D?7378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWN<MTHN?96333>C;[X>5YypZ<<A<=>8689?=CQSRX^UXfmmmiŽŠqryŠ{z|{‡z|{‹†‚}tƒ…yrzsm€~„~w…›¢›”’Œˆ˜‡€›’n‡¨…z ‹|‘ƒˆ„œ}šŠŒ£¢ ¤¯Ÿ‹‹…‹“†Wr­‹Ÿ«›ƒ˜›Ž\‚¢‘‚ŒŸ“•Œ‡ˆŒ’’‹””“Ž‹Š‡–šœ”–Š‘“†€‹ˆ’ŠŠœ–˜¢¢†“– Š‰ˆ›ƒˆŽ€ƒ‡…¤†Œ³˜’”—¡¡ž™’œž¨²¸­¦½ÂÇÍÈÆÏÍÐÌÏ×ÑÑÕ®ÖÕØÚØÚÚ×ÕÙÙ rwjh_^YUYYCAIC?>>:49:;7:;:3;;?=>7;9:0:G=:37=@50677255?65;55858:57735HR7GOK994=EJB>1FCLB98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:;@;BQKKSYPTcbzma~’ƒomw‹xyz|…{{v…„sp…zuvvt„‚„~’¦¤Ÿ¥¢—Š”—‹Š¨—rŠ±„§’„™“…™Œ¢•Ÿ˜“ˆšž£’©°Ÿ”Žˆ–Œn·…šÄȲ›¡¥›œ˜–²‘d¤ÍǕ†‡ˆ’’“‰…Š‰…–™š”“†”—ƒ‹™ˆª–—££ˆ™ž–šˆŽ†–—‰„ŽŒ‡¤‰Ž”¨š—“—™¡™Ÿ™“›£³´¦£¼Á¾ÇÅÅÉÈÉÂËÓÍÍÔ©ÒÑÖÖÖØÚÔÒÚ΄u‚kf``_PKV\BBGC;A=837;<:8=649:<:82?9929I:>67BC32:96264>=4;>6949;57944JQ<JQK9A7BGI@64JELF><88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBeƒGu‚Ž||m~ˆxz~z‚~vv€‚{loŠ~y|wx|„†Š~‹£´¨¤ª³¡–§ ¥¤–•¯¢ƒ¸•’³š¡ Œ¤›¯¢¤˜§—©™­°¤—”•”‹˜š– ÀŽ£É¸«š¢¥­™‘›œ²†…¨¢œ˜…ˆˆŽ”ŒŠ“‡€†‡ˆ“˜”ŒŠ““†”˜†„‘œt‘˜²•–¤¡ˆœ™“ŠŠ–š‰Š–†}Œ˜ŸŠœš™“™˜ ”¡•Ÿ›¡±­£¤·¾³ÅÇĽÃÿÆÎÊÉÒ§ÎÌÓÑÐÖØÒÏؼu|x_bWbXRIKOEBCD5>:76:?;<7=42669774=5;5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=89567=:JFDGM\\YJha;H„‹zzm…†y|„x€…}px|}|osŒy}{x†‹‰†„’¨¼­©²½°¥®³³©£¢°¬Ššµ¢¸¥•­¤—©­·¦¤£Ÿ™©˜ª¤¯±©™˜›”•‘˜ —™»»­Ê¡i¶·ª°•˜ž£«’—½¤^ª³‚‰ŠŒ”‡|ŽŽ}ƒ†Ž””ˆ‡’–‹•‹Œ—™“œ™´–•«ž‹œ”’’‹˜šŠ’‹‰• ¢•—™“œ˜ž”¡ ”œ¥®¨¢¤³¸«ÂÈĶº½¼ÅÈÈÂСÆÉÍÍÄ×ÖÐÊÓ£s}k_[UaSQGD><CAB8?874>F<<6<35355454B39:BM:A;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPfHa`bpJ@‹Š~€r†‡|‰u‚Šƒ~m}||~pw‡w‡{Œ†Œš«ÃÀ°½Æ¼³´Á¼´¬«³¶Œ¨²­­½«›»£¨­¹¸«¦¦¢¢¤£ª¯²±ªœ£˜›˜˜ž¢¥¥“£¹¯¨À»¬­²¹¥£§}ˆ†œ­½°‚‹‹Šƒƒ‘Žz‡Žœˆˆ—Š”—”š—§š°š‘«Žš’Ž•‘•—Ž‘ ˆ”›¤¬”–”œž”¡ž›˜Ÿ •šž§§¤¢¤°³¦ÀÆ𰻶ÅÅÿͧÇÃÇüÕÐÌÄʊvvd_\b]OLCL@EG>A?B<:4>A==5=6>333242A17@BN>G@CNCA=C=;86CC5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GE?CF\hF_ig[]\“ŒŒˆ{‡‹†ƒŒu†Šn~{~q~z”z’””˜‘“•¨´ÇÉÀÂÌÂùǼº¯«¹»—²¶º²À¯¥À£«°¼¼ª®«£¢ž§¬¯µ±©› ªœ¢œ–Ÿ°³§Œ¢ººµÁ»«¨œ²¤£¨”„Ž©ÄĤ‚‹Ž†ˆ„†•”ŒzƒŒ‘‘¡ŒŒ”‘ˆ— ˜“™•—¥ ®œŒªœŽ–’‘••”‘¡“†—Ÿ ²Ÿ”›” ¡™¤ š › ”˜ž§¤¦§¤¯­¥¿Ã®¨·µÉþ¶Î²Ä¾Ã»³ÑÉÈÁµw{o^[^lTNIDMKKI@A=BD<5AD;:3=8B332263A05IEM>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBg\Me\fTcj™–‰‹ˆ’†‰y†“r€{Œw†‚y¡–¨šš˜»¾ÉÈÊÂÒÉÊÂͽÁ³­¼¿§º¿½¼Ä¸­Á©¬³¼½ª°ª¤¥£¬®´®¶µ Ÿ®Ÿ¦¢™£´¼©›©¼Á£¶¶¯«“¯«ª¬–†šª§¥‘‚Œ’¤•‰€u‰‘y…‘žŸ’”‹Œ”£™—›•”¢ž©Ÿ‘¥šŒ•–ˆ|Ž•’’£š• ¢œµ¦ —¥¤£¥Ÿž¦˜ž•—œ¥£¨¨¢²¬¨»Àį¥³·ÌÀº®Ã³»½Á¹­Â¿™p{c[Y^]MMNKGDCHBAACK:4DH:;4<7F.12352B26SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQF7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>lI_XaZdeWžŽ—Žž’‰ŠˆŸ’„x…”~ˆ‰€–¡š®§£˜Ã¾ÉÄÈÆÓÍÎÍ˼·°º½´½Ë»ÃÁ¶·¼­´À¹¼®¯¨¡©¨¶®®©²·šž¬¢¨¢«··©¥¯¾Ä±½¸³§ª´³­®–•¥­¨ ‘Ž’±Å§•}‘•}‡‘˜ª™—““Ž“•“¥“™” ¢¡œ˜Ÿ˜‹ŒžˆZ–—’–¤™f™£ž³¥–¢–¬­¬§œŸ§—˜–˜–¡£¨¦Ÿµ«©º»Ã´¦´µËÁ¸ª¶¬³»¸®¨¸º¼·„op\ZVWPGLTNK?AHDDHFF85FM;>7>AK.32025B55PWN<LFKRLOGGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|hV<>@BFBsFiIRfcMF¦”œ–¡—¨–Œƒ‡¥’ˆ‡‚›ƒƒ•”Žš¢Ÿ¯¾®¡Ç¾ÆÅÈÇÎÎÏÒʾ»¶±»»¼¿ÏµÄ½·¹·³²¶³¸³¬§œ««¹«©¨¯¯—£®¥¨¤¥µÁ°«¬´¾Ã¹À¸³§¸´·²¯•¤­°¯¤‹“” sÁ™}—™„Ž–™‹±•š™•’’™™¥£•Ÿ›–š¨œ›¡ ™ŠŒ–`J–œš•™¥—T–°Ÿ¯œŸ¥•¯¯­¦›¡¦”“™™ŽŸ¦¡™´©ª³¼¼»«°²ÇÀ¸¦¬«­±±£¡²²´¥sqg^\PSMFQQPQ;HKHFGAC=9KT?A:=EM/7544:B34NWN<JKNUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@CAF3>58JKCA=C;5EA:A?>H@5*B52,>c]g:35tde@R7&#3}hX<:BC@=REWSsbVFH«—™Ÿ¡¨®˜—‡Š§–ˆ’…Ÿ‡„œ—Ž š£¤µÉ´©Ç¼ÃÄÉËÉÈÌÎǾº³¯º¸ÀÁ͵ȺÁ¹µº²¯¯³´§¤œª´µ«ª§­¬™¤®¦¥©¬ºÀ¨«·¶¾ÁÀ¾·²²Ã°·¼¬£®µ­º¥ˆ›—¥šu¾Ÿ„˜Ž’˜š‹®–¡œ›—”šŸ ©ž§ ™šª™¡§ž—‘ƒmu“¢š”œ£Ÿ­²¢«•©ª˜ª¯¦¥¡¥ª“’™œ‰•œ¢ž–°§©ªº·¾³²®¾¹¶ £§¨¥¦œœ¬©©fhc`SMMGIOJUL=MEMIJ@CD<QU<AABDO18=77?B75UXN?HNQXRPQTJQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CC:9C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW<:=..SaMVH~e^HF¬”œ¡Ÿ»®˜”ž‹“ª›‘‘“ˆªŒ†¡žŒ£¬”£¤¶Ç½´Â»ÃÂÈÉÅÂÎȽ¹²¯¹µÀÃʶƱÁ¼µ»¬©­¬°££™ª´»¦ª§¬ª¨¯¨¤«ª¾¼¨­¼´·¾Æ¼¶µ¸À°½¿³©µ·¬¿¥¢—¡Ÿ¼ž‰š ™—¶Ÿ©œ¥£š› š§¥³¡›¥œ¨ª˜””›‹–‰Œ¤¡”œ¢Ÿ µ°¥¦“±«š«­ŸŸ¥¤ª’–• „žŸœ–©¤¡¡´µº¶­¨µ²²žœ¢¦š—•™ª¡žxc_a_LIFHNQINEFGBQJH@DGAVSDH<AGQ1;B7:BF79]YKALPTUSMWRNUJD@JJNO9C?5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-1:h]FDCœpbGE¨—¤žŸÃ¬›—¤—™¨›•ššŽª–•¨¦•­¬™¢«·Å¼¿·ÁÂÀÈÄ¿ÍÆ»¾¹²°¹´¾Ãȵ¿°¼¶º·§¤««­¡¡›«ªÄ¢¥¨¬¦ž«¯¬¢ª¨¾¸¦­¾°··Æ·´¸¸¾±¾À¶´²µ¯¾£–£•“š“­Ÿ¡¡¤¢£ž¾¤¨©¬œœ ›¦Ÿ½¢˜£ž¢©« ••ž“ž‡Ž„“ž¤ ¶¬¦œ–²¦™°¨ œ«Ÿ¡š•Ÿ„Ž¡šœ’¥¤š˜«±µ±ª¥ª­¬›˜ ¡’Ž–©Ÿ”ie\b^PJHKOLHEDI@=OH@;FIH[ROK=HNU4BF8>HG5Cb[KCNRUWVQXTRUH@8QQPM:G@4CHQSIC;C>GVKC@O>K<06;GF>;FA56?9:?9;15D0--0Mv\4KZ5,MnW<-=)#zbQ5CKQ9oRF<KxfcXN£›£›žÅ« ž«œ­Ÿ‘¢ž–¤Ÿ¦ª«—¶±£©³¶Å½À¶À¼É¿Êȶ¸µ´±´´·ÂÆ·¾±¸´º¶ §¬ª«žžŸ¥¤Á¥¡ª­ ¤©­°¢¦¨½µ¥±»·¶µÃ²²·º¾²ÃÀ¸¸­´´µ£¤”‘“ ¬Ÿ˜¡¨¨ª¢šÂ¬¨¬­šš˜¦ ½¡¤˜«««¦ ™šŸ’žˆŽX–Ÿ¦¡ ¹ª¦”˜¶£ž³¢¡œ±˜ š•ž‚ —–Ž¢£•¥®³«©¢¢¥¤••œ™‹’“¤Ÿ‰cg\eaMJKKOFEAGK>=IA99JJN]QQI=LV\8FI=DMI8Hc\KCLPSYYVWOZ^IA=WQIK?H@5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+waS6SZkWsHE6=ue\LPŸŸ ˜žÃ§¤¢³ œ²§’©£Ÿ£ž­©¬»±©¬µ±ÈÃÁóÂþÇĽÄʽ°±¶®±µ°Àŵº±°º¶­š©°©©›ž¦¡§Â­œ­±œª¢®±©¤§½·¦¶»½¯·Ã­³³Â¿²Æ³º·«´¶­ª¢¦••”¢«¡ŸŸ™§«¯¯¯»²¥Ÿ©©™˜—’¢¤¸ ¡£’®¯«¤¥ž‘¡ž”Ž”š£Ÿ¨µ§§˜´œ£¯› œ°‘¡”˜•›€’¢–Ž  “‹¦¬°¥§¢ ž’’š”…‹’œŸ€dh]hfKJLKSAC@HG;;F>89NMU_RSJ>O^]=HPBMLI8Nd]LELRTY[SUO\bHA?ZQAHAKB7FELKN>;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<w]^?[U_gr@8<H–weA4Ÿ¤ž› Â§£©± £´©•±«¦¢¤²¬­©»²­°µ´Æ¿ÄĶ¿Ä¾ÊŶÀɵ¬µ©°¹¬ÀÄ´·¯­¶º¥™«²¬ª˜¡§˜­»´œ¨°›­Ÿ®´±§ªº³§¹³¸²¸Àª·²Ã½´Å§¾®­·µ©§« ––‘¥¤¡¡——¤®·­±´¶ŸŸ©¤™“”“£ ·£¤¥•®±²¥©¥¡ž›™š•—¨Ÿž™¢Ÿ¯³¢¦˜¯š¥«—›Ÿ§“•™š†– •Œž”‹©©ª¢§¡™ž–Œ™†•ˆ•Ÿzej]lkNQNNT=CANC;:I?77QN]_RVQAW`\BJSHVKH:Td]NFON[W[RPQX]GAB[PBG>NC9HGHNP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1\cZ33906p[bH05JqiVCWFŒyfC;¤¤œ ¥¿¦¨®® ©µª·¯«£ª´¶±°¸·°·¸·Ä½Ãǽ¼ÃÂÇÁºÁÆÁºª¶¥­»­Á÷·ª­²¼£•­±­²—¦¨‘ª¹ª¡§°« ¯´³ªª·µ¬»¬³²¹·¬¸°Áº½¿¦Ãª°¶®©««¦˜˜ª¡¡ ‘— °¯³«°¹™›©Ÿ™–’—¦ ·©¥¢¢¯±³«±§« œ Ÿ›ž¥¡˜£´°›Ÿ‘”¦š¡©›–£¡˜š‹–™”–—”‰’›™”Ž©©§ £œ˜›“‡™‹~Œ—†›limbnnXQQZTACDT@;;H@7:XPd^PWWDY^^NLSN_LJ>Zd^NIQN[UYPKSWZI?DXPDF>N?=IGGQPB=CFBM?:2D?77547?=95E4+75/251.-.,1>*'+=\p=>1.1e[d@1747gYaF(@8l}h\V:‰{cC=¨Ÿœ¡¨¼ ©¯ª¢±·¨¤´±ª¡­µ½¯³¸¼»½·¶À¿ÉĹÄÃÀÀ¹Å½Á¸¯¶¨«·²¼¿¿´ª®²¸Ÿ—¬­¨®˜¨©Ž§»Ÿ¥­³ž«¢±°³¬ª¶³µ¼­°±µ¬°´²ÀºÅ¶«¼¯±·¬­©£±¥ž¤¨ž£–˜Ÿ²ª³©ª³™§›š” ¦¤´®§¡¬¬­±§²«±©£›ž¨¤ž” ™œ¨¶©—š“’Ÿ™ž¡Ÿ’­ šš‡—™Œš”‹——š—§¦£ ž–––”•…{“ƒŒ—gmrhqs`GYfVDCMXDZ9HB5>]Qh\NZ]G[^]OMSXdJKC\c`PLMNXWXPJVVWL=EUJEDAM?AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,+%2+*5K1.'__aV151=`V_8)C3YU\gK5ŒzfL@¤š ¤«¶£«¨¤®­µ©®³¸¦§°·Æ¶°·¿Á¶´ºÅ¾ÌŹÃÁºÀºÄ¸Áº³µ¬ªº¸»º¾µ«¯±¶™˜¨««¬œ®««¾ž«¯±£ªŸ±­³®®¶±¸¶ª­®±§µ°³º¼É²ªµ´°´°®¦ ³ š¨¬ ¤••š™±¢­ ¥¯–¢¤š™’Œ¢¥§²©¡¦±¬ªµ¤®°´¯£™­§›—žš™¬¸¢—“‘˜œ¡™˜•®¡Ÿ–‚•™Žžœš—‘‹”“ž™¥££¡™—“’–{Œ‘…{‹ƒŒ“lnyov}bF`jZIHZ[={JGE6AbUi[M\aJ\\ZRSSbaLKE`a`PMIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`Va.5(C^Q\.+A/JGP[G3cXTKEš– °§±©¬¤£®­´¨·³·£¬´·Éº´»»À¾´³·ÃÀÌǻĽ·¿ÀÀ¸À½²½®¨º¹¸·Â·¬®±¹•—§¯¬¨¤³©”¯»¤¬²²¦§£²´°²±´°·²©®«²¦¸¯µ³ÄŶ©µµ«°­©§¢¶žŸ¦° £”›™”°ž§›Ÿ©©¢›•—¥¥¤·§¢°³«§±§­¯µ¬¤™ ¬¨œœœ”ª¹œ•Œ˜£˜‘˜¨¤ ˜…“—‘œ˜—–ˆ——›¨¥¡’–’–w„‘†|†‚„nqxv|€\Lel\JOd]?b{GI8GgWf[L^bLYYWUXUi]OPHa^_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANHg27'FaLV%-B.=ELQ<3rkLDD‘™¤­£¬­ª¦£°²²ª·°µŸ«µ¹É¸®Á¼Ã·³±µÂÃÏÄÀ¾µ¾ÁÀ»¿¼´Ä¨ª¹±¶·À¼¯¬´´ž¡§±®¥¦±¥ž²µ¬ª²±«¨¨´º¬´²´«³¬ª«¨¬©¹­²°Ç¿¸¤¹°©­­¦§­°¥¤£®£¨››š¯™¢¢¢£¬Ÿ£ Ÿ¡©¦¥¸¤«´´¤ª«¨¬®¶®¢£¨«œ ™›’¤µš‰Žˆ‘£¡––Ÿ¢–•†•”ž›™–•‡˜’•™§œ  “’Ž‘x~Ž„}}}‡ŠŠrts~~\Scn^NZg]FD–[G:NmXbZMabNVVVWUYh^QSMcZ[TKGOTSNGIVS\N;P^JBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3Dd;6*HdHJ+:I?3CIS,>k?HI›©©¡©¯¤§£³³°´´°° «­½Ìº®Á¼Ç±´­³ÁÃÑÄÆ¿Á²¾Ã¼¿¸½Å¨­·¬´¸¼À±¬²­¡£§®ª¨¥±£ª°ª®«±®®¬«³º¦·°²©²©ª¦¥£­º¬ª°Â¹´¬¹¨¨¨­©§±¥©¤¢®ª¨¡ž›£¬•¥˜ž™«¡§¨¡¬¦£­¬¶°± ©¢Ÿª­°«ž§§©š£˜™ ¨˜†ƒ‹‹Ÿ ŒŽ—ž’‘ˆˆ’–¡–™–†—“”—¥œžŒ’ŽŠˆ„}w€‡…‡utr‰wl_Y`ncQsq\K;„{F?WuX`YOc\MUVUWQ\b_SOOhYWVKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*35>10485(5/*,.30;),,'%234$,2-860)(1<^K0.IgDF8<B05EKX1@”]@NF•–¬§ ©±›¨¨°µ¬¸µ­©¤«ª½É¼±¾¸Ã¯°¬³ÃÄÎÎÿÀ´ÀÄĺÁµÉĬ¯·®³ºÀ¾´®®¬¦¨©±©¦©²¦´­ª¯­­±®²­³º¤¸³¬¬­§« £ž°·«ª­¹¶¤µµ£©§¬¬ª­ ¨¦§±±¤¦¥¡¡«–ª¡“› ¥ž££ª£¬¢ž¦±¶¬¬¢¥£š©«­©¡¥¤¤™ ™–˜“‚‰… ‹›’…Ž™¥›“‘›Œ“’’”£šœš‹‹Œ|‡‚‚{u„~uw‹£‡xj^`nfWf‡dN@g’LDbzWbXReUMVVUTO\]aVLOjWVVIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*49?./463)4+*,+.#4.-+&(+79*&6+<-2,&06XZ.0JgAA<<C+:JO^4D†BIID–‘¯¤¢©¯˜©¨­µªµ°ª¤«ª©¼ÀÀ¹¹´¼µ¦²¯ÃÉËÑ¿Á»¹ÀÀºÁºÂÄ®±µ²´¼Á¾³±®­¬¬§·ª¥­°«¸®¨°¯®±«µª¶µ¦´·¬¬¤©ªœ¤ž³³¨¨¤³´Ÿµ­¡©¨«¨«§Ÿ««¨¹¶©ªª©¡©Ÿ­›‘ª¡ ££¦¢ªžœ¦´®§¥©¢¤—¤¦§ªœ¢¤£ ™˜Ÿ‘Ž™~‡Œ‡…žž‰…Œ‹’Ž…ˆ–£šŽ›‘’’Ÿ˜™—‹„€t‡~xuƒ€zx~ˆpqfgqx\atˆjO]˜VHmyUdVRbOLUUUQOX[bVIQjTVTGPYUI>IHOQPxMNV=<KD?@A<@CUC9AK=5;E13;97*4:=+-341*8**+*,)*(/*&)%3;,$2)2021%/2Rc02?f=NX?C,?LT_/Ik7RF;•¯ ¥©¬™ª£¬®²´¯ª¤¯©¨»¿¼Â²¯¹­¢¶¯ÈÇÈÑÀ¿½º¼Ã½»ÃÁ¿¿¯±³²¶½¼Á²²´«´©¥¶©¥­³²¸¯¢­µ±¯±¹ª¸®ª®·«ªžª« £¡µ­©¡Ÿ®²¡´ªž¨§«£ª¡¡¬­¨½®«®­¡§§Ÿ«™°¢˜¢ ¨§ž§›˜©°©¢Ÿ¬¡¡’¡¢£§˜š¨¥˜˜˜œ‹‡•ˆ|†„…¤–†ƒƒŒ‡’…‡•¡–‰‘ž‘“‘œ•˜‹††xt}txy€{tt{j‚ˆ¤vi^elugˆ‹|RVp^JxsTdSQ_MMSZfNMWYeYGSjRQ>BNQaQ:IHLSIqQLS;<I?;<=;@@W<<>H73CB15:93-5::)-31--6)(+-,52#2)',%.;.&1.0-14%,0Mh:38_=ad?F1CP[[+HP;YC3Ž° ¤¥ª¢¥£¬¦´³±¨¤°§ª¸¾Á½°¨¹ª§­°ÉÆÈн¿½¹¿¿½É¼Â¸±°µ±º¼¹À³´¼­¹¬£µ¦§¬±¶¸²¦§¹µ­´¼¯»¥­­µ«­œ©¯¤Ÿ¤¬ª¨œª²¤³¨šª§ª¤©¢©§©½«³°®©£ ®›š³¢–¥›¥¤Ÿ¥š™¨ª¥žš© ›‘š ¤™—©©‘™š’‹‚…}ƒ€ˆž‡€~Œˆ’‘…‚”›”†“¢”‘‹‘›“–‡Š€rzy~|hv|{upr~j†z…ˆd_hcr…{mgy]^VBW{mTaPRYKLNpt]IZ[hYFVgOC>KNDCA9HGKS?jaIQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11&/>KI1%90%,,09/,,+6'17#-/GjI14X=fbAJ7GS`U*=<F\@*Ž’°™ŸŸ©¤¢¡«¤¶²±¤©°¦­¹Â½·°¤¹¬©¨°ÂÈÉÌÁ·½¿µ¸ÁºÈµÃµ´³µ²½¹º½¶®¹¶¿­¢³¦ª«®´·´©œ¹»¨±¾²º ®´¶©«ž­±£œ¥¨©£›¤°¦¯¡Ÿª©§¢ªœ£¨ ­¼§®±®¡ª¢£®žž¬¦˜Ÿš¡¢›Ÿ›™£ª¢šš££•–“Ÿ¡–œ–¦¬‹Ÿ‘‘Œ‚‹€€{š”Œ‰}Œ‡‘Š†“˜‘‡”£Š’‘‡™”ˆ}zl}vyxbzzrppsxj‚uk‚gcgansŽmbjo_pA]ykV^NQQKIMSYVM\^lWEXaO^PHMDF;7HEKO<rhJK9AE;;==;;=J49B<3;G<4?18-78;2(09/,5..=-*L>*49&'.34.0+/4&,:$40AhZ13S=e_DL6KVdN)=3R]>#‘–«˜Ÿ—§¢¡Ÿ§£·¯­¢¯¯¨«¸Âº³­ ¹¯«§³ºÇÊÇ¿·Â½¯´¾·Ä¶Â²°¹±²À¶»½·ª¹¸¾ª¤µ§¨ª¯­¸°¨˜¸¼£­¾´´¡­·µ¦¦¨°³ ž¥¥§¡¤™ž¬§¨ž ª¯§ ¦—¢¨Ÿ°¸Ÿ£±¯¡«¡¬¤œ¦¦¨š››Ÿ¢•œ›š©¦–›ž¨‘˜’˜“™–¡ªš‰‡}‡‚Ž||¡ŒŒ‰z„…‹Ž…‰“šŽ‰•Ÿ‰•‚Œ—‘|…|tp|qst`xxiopqpksdzlhedaf‡€`[rjrMN€iXZMQLKHPRPGM[_oTEYZRgOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23/:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%53=fd24M?e]FO=RZgH*?0][5(•›¥˜œ•¬Ÿž¡¤¡·«°£´³©©ºÄ·²®¡¸­­«¯µÅÇÀ·¿Á¹°´½·¿»¾°¬¾°³¿±¼Â¸©»º¸§¨µ¨§«¯«²¯¤˜»¶¤«ºµ¯ž±¸¯©¥§¯²œ¡¤ ¤£ –›¯¦¡Ÿ¢¨¯¡ ¢“£¤¢¶°¡¦±«Ÿ¬£®—œª¥¨Ÿ˜š£“š›š¥ªš››¥””—•œŽ“—¢¨¡‰Š†zƒ~„‹y—Š‡z‚ˆ„‰…“˜ŒŽ–™‹–~†—Œz{prvnos_xwdllljj…ofrikfh^ds`[kviZJ^\XOOKHHRUG39]^lPEYUYeMIIEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<"8R=*113>D5,-'42*;+139cm74GAf[HTDU]hD.<2dW,2”¡¡—”›ªœ£¡¢¡·ª­ »·¥¬½Å´±¯£µ¯¬¬®´Ãü³¿º·±³¹¸º·º¯®À³´¹¯¿À·¬½ºµ¦¢²©§©±ª­± ™¿µ¤§´µ¨ž²¼©¨¥©°¬™¢§œ¤¥”— ²¤™ž£¨©œ¢Ÿ’¤ ¤¸©¤§®¦ž¥¡¨’Ÿ©¢¡¡™›Ÿ‘™›–Ÿ¡ª›š˜¡”‘”–™”“¤¨¤‰‰Ž†y„{„†}‰Š‡z„‡ˆŠ’…–““‹–”Ž”{ƒ˜‹w~|ltrllsawthhjggp‡hhicfii`jcjh[f{c`StT\[RLJFIOS@!*h^iLDWU^`KIHEC.:B<F<6KPD8:D357==895?:;4>8@K=>93)8><:9*6@3.E4(+,?0-N?.+-7,1195,&.5-80576`tA3CDg[KWGU`hB379gP'2ž¢£¤¦šž£´­§ªº¶§¬ÄÁ·±¬£¶®§­®¶À¿¼²Â¶°®²¶µ¸¶¶­ª½³®²±¼¿·®¼»±¥Ÿ¶ª¥¥³§©­œÀ«§¤¯²©¬µ»ž¨ª«±¥˜žª¦¤‘˜¥¬¢˜ž¤©¡œ¢›–Ÿ§µ¦°ª®¡¡ž¡” ¦Ÿ¡ š›™›’˜“¥¬¡—–““•—‹˜›¨Ÿ‘ˆ‰‹ˆx…v‚‡Š‚Š}…ˆ‡†‘„–”Ž‘‘‘Œ“{ƒ•†s~~fyokjkftskcgddvbefffjjckr[_Y^mdaNiXZ`VJGHKMRX>9_lhHCUT][IIGFA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A=-5B37=+*,0B*JK./*+3722(57$+7.72685]yN2>HiZLZJVbf@:3BhH%5š£ Œ­¡—— –¤³±¢²½¶¡±Æ¼º±±£·¬ª­©¸¼»º­À²®®®¶®²¸³©«¹±¯®³¶º¶°¸½¬¦µ©ŸŸ¯£©®œ¡¿ °£®°®·®µž­¯­®¢™§©¥Ÿ•š§¥Ÿ™¤¢¨šŸš”œž¬¯¦º¨®¢¡š›ž™ž¤š¤—ž—›“˜Ÿ’¨•ª§š“šš’Œ•™””š©¦ŽŠ‰Ž{sŠ˜…‡|‰‰……ŠŒ‰’„”›“’‘—Ž€Žƒofymhkifqrk\hcctbfgjnlgkjhn]llsp`TcicfYIFLMOXQQUae€UAWSYTFHFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24;6#3*)6.55465Z|]19Kj[M[KXdd@A1JfC&4‘¡›°™“¡š©±¯Ÿ¹¿µ ´Â»½º±¦·¯§­¤··¶·­»®¬ª«¶©³·®¦²µ²®©°¶¶°³¶º§¨Ÿµ¨œ¨ ¨¬š§½˜¬£®¯µµ­­Ÿ±­°©¢›œ£«¨œ”œ¦¤š©¢¤–šŸ››£ª«ª¼Ÿ§¤ ˜š™¡k¢–™œp‚•š£u‘©§ž””žˆ—™€–Š¡y‡”Œƒmi~vƒql†‹†}…Œ‡p^cag„˜…k‹Ž”’tw‹„~ƒ€g‡€guheW\hsmNPjcgs…h_efnmj^_aŠƒ„eNKD9GTh^JGQPTULHR`oteF[QUPFHEC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=A@@=28@E=1,+08=G701.*.*/568,#1'214:175Xl16Ok[N\K[fb>G1Qd=*.Š£™…•°››“ ›ª­ª£½Å¯©·Â·½½­¦·°¥ª¢¶³±²±¹¬©¦¬´¥¯´¢©·¶¶¨§¬¶²®´­³¡©ž³ªž £›¥¦—«¹”¥¥¯³·­®¥©®«¬¥¡žœ¡§¦›— ¥¥š›§¦“žŸ—¨©¤¶°¤£¢–˜——£ˆ¡Ž’š† ‡“œ ¥¥ªž’’š‘ˆ„rxŽ…ˆ¡vˆŒi—ˆf}sx oˆ‡ƒ~Ž|¡  ™€|‡žt‡Žu›Šl‡ƒmieczlraS…mbli˜qXiqpˆX^i[ll[ˆrnzr…g†„Z_GN?G_MERVVQQSWTg]MVHRROFGG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82).1<I9/01.*/(-4583%&2115>1<8Xƒu25Rk[N\L\g_=K1Wa7/(Š¦–‚œ«œ˜˜Ÿ©©§ª¿Ã®±º¼¶À¿ª¥·¯©¬¤²´®®³¶ª¨¥°­¥´²›­µ¶µ¦§¨²°¬²§­©Ÿ±§Ÿ¢¢™ ¡š¬³”£¤¥µ¼¦­§«ª¬¨¦¡ ˜ ¦£™™¥£¤˜œ¤©–“¢œ“’£¥¦¡·¤¤ £˜•“—’œˆ¯—”‰©‹–¡œ…±€£¬“™”y‚Ô¨€‡•Á›Çyx±¥·—d€Àœ¿y„„y‘„|‘Êr—¼œÅzrµ¦»{€m–±«°yhlX±®nei½’¼ngzorØ~Skc¶²r”sš¡ªWOWbOVNFU[XQPRŒ\W[PA\DQNEGI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>:B<?A8:J>52*22BE/.32.+/(-/186- /416A1=:Wƒw21Tk\O[M^g\>L1[]41!Œ¦’€§ªŸ—œž¥¬²¨°Â½±µ¿µ¶¾Á«§³¬¬©¦®³©®¶³§§¦´¥§·­œ³²¶«¥¤§±­¬°¦ª¦£°¢¡Ÿ–šžœ­«“¢Ÿ´º£ª©¢­®¥¡šš¢§Ÿ—›§ Ÿ˜ž§§‘œ¦š“¡¦¢¡±£ŸŸ£––’—’™…¯kjŠª~fƒ•†­dp”™¦”q®¡¤~x»}k¡v±_j´[¥€eœ‘`f‚{fjxk©e¾rg¦Œu±j|±xt’”cnm§n[„ Ehf‡–Euœ`~g|¤§‚Z_Œ«h€•xyj§7J¯\XSld[KNX_\WV;N‰OWW/ITSJCFF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3..53/+/(.0.:5/'$203B/=;U‚v2-Vj\OYL_gY:M5_Y30¢•‚­§¥ž£¤ª±·¬´½¿¯¶Ä²·ºÁ¦©°ª®¨¨¯®¢°º¯£¤­²£¨¸§ž³³°£¥ ©¬¯«¯¦§ž£¡¯›¢š–•–™š«¥•š¡ž´³¢«œ£­­ ž™– ¢¨œ˜£Ÿ›™¡¦¤œ¢™– Ÿªž¦¦ šŸ¡–•‘–š…µ›µx…©™µ™v†³›·~“––©”~k¦{‚†ˆ’”’w«gk±\«z†”t‰r†€ˆ—x‚‚‹˜‹ƒ „°vwŸqlll|‹N¤XHbb™~ch¦`yruS“‡^P©mcq~‡€bœ.Q¡o[Skh`LK[dX\ZB>±yWXA#MhFCEA@A19>88:84;:9<9:A:E::;6:CB8=?KNG:5:AFB@AD<FD;0201;F,0.840,.(/3,>831/2-D1<<S}n3+Xj\OXM_gX7J8aT50• •ˆ³¦¦¡¯©§³¬©»¶Â°»Á­¸·¿©¬­­­¦­±© ®»ª §´¬£«´¤¦²³§£¢ž§ª±§°§¤žŸŸ®•ž™”••—« ™™¤¨´¯¢©©¨ª›•— ¥¨šžœ¢ž›Ÿ£¥£•›ž—™œ¢©›¦™œ›¢ —“‘““œƒÕ“™¹p°Á~ņ|֔›»|š•¥¤{Ž‡£‚¥‚z¬yV¯zˆ~Ÿj¹Z¹v†ƒ}¦‚“|˜zªxz±nŽ„t‘¼…o”P¯§ÅŠQ zc`©bsrˆm—ˆ`Sµ´È†€‰|c¤3Bv]PjicP@XgZdaJHMnN\QOYfYCD?E?0=<59;74<;8=:<C:F:;>6:@C;6@OLH<:;DHCBCD<EF81211DC./0483+-).323971#%5*>3==Qwj6*Yi[K]O_fT7G:aP71%›¢”™²¨¨¦´ª¥´©¤¼·Á°¹¿±µ´º²´§±¯¢°²¦Ÿ­µ§š§¹­¢¯°Ÿ³´°¡¤žŸ¦©°¨´¨£›ª•˜–•–”– ¨œ™–§­°©£ž­¢¨–—› ¥¡˜¡¡¡¡š¡¢§›ž ž”˜š¦ ›§•››Ÿ¡˜’”ˆ²nhµq«‡nŽ¦r´sr¶{š—¤‹£‘¡¥~°vƒ‘ÒÒv\®{…¤o›ª¦k†„|­}—™Ž{°r’Žx³e—t„žožf”QȋZÂ\Ÿyb_­`vs‡b—ˆ^Yʝo¿uMKµSUÆdTQjceXAOk`lhPVGI9=URZWXIC?J<2?;5=<46>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>HI91746A>/.24252-).26,742&60;5:=Pqh9'Wi\BOT_eP5G=aL620¡’¥°¬£«¼­¦´¦§¶»¼²º¾¶¶´¹¸²¥´³ ±±¢ž«¯¤—¦¹­¤±°›´¸ª ¥¡©¤±§¬©£™œ™§•“——‘‘¡¦Ÿ•’¥ª°¦¢–“­ ¥’” ›¤¦Ÿ•š¥¦¡š¢Ÿ¬™ žž•›¡œ¥••š¢Ÿ•˜•‘›…¬{w¨v£ˆ†©o­Š‚§ƒ˜˜¡‰’š‹¢“š‰®…‚³\r³R®}‚‚¤q×}x…~Ž…ššv¯†‰‘œ‡w´ašeš‚‚•m’Z°XKšu˜yf`­^vwˆh˜ˆl]¯w•žxl5yÈ®²_BTo^g`EPl_pmVVM.fdiSYP;AD@L:5?91=<16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK96<46:>/04333.2..18*.32%!03767=Pke>&Vg\@>V_cN6GC`H:99 ž• ¹°—´Â­¨³¨©²º·³·¾¸·±´º´¤·²Ÿ³¬Ÿž¨«ž”§µ«¨¯±ª­´¤›© Ÿ§¡µ¦¦©¢˜”¤ “’›˜‘”¡¤š’¦­¯¦ •™© ¢‘¡™¨¤ •™¥¨œ¤ž¬œ¡ “žš¡˜™›–—¢ ”—¦†©}}¥x¡Ž‚ªp­‹§†–Ÿ¡‰——ˆ£‚‘ˆ”ª|€‹xo±Z¨‚‚ˆ ytØv‡s¨Ž›’¤|–Ÿ„{²^d ~ƒ•m’\«[Z“€‘hgªdr{k˜‡s^«Z‰ ŽkoeOJC¡\[Lt]bgN[a_rs_KV7J›”XGE=GFAM35A8.;>05A78@<6=<F?:<6?=B7.HVJEAH6KIN@IK@EN::@5.;>102144+*05/7,&21($$6671<PeeA&Uf[?2U_bL7FI_C2?8¢žšš¿«˜´Â®«­©¥´°·°µ¾¸¸±°µº¨º´Ÿ¯¤¤§§“©°©¯©´«ª®¡˜ Ÿ¦¤£¹¢£« –›¡Ÿ”“ž™“—žŸŒ‹¨°¯§—›¨¦ŸŒ’¤—¨ª§”—©§žž ¢­¤¡ž¢Œ”¡˜Ÿ ’ž—œ•ž¡•–Ž«œ®mr´s©‹uŠ§s´xs³€‘¤£’œŽ‰¤‡w¸oŒ{‹¢jk¶Z¡…e——i¡¢§m“r´t“˜²j…’ˆ­ju³af¢o‡“k—\­_M¡|‡‘Rs£ly~o˜‡r]¯V<œwfTon.\§OcSkebmZc]`p{cTZR>>mo3CB@?M:!7@6.;@37C58??3;<CDBJFMIF62JTKEBI6IJP?HNCFP=<E50;;010/75,+,426/#00,,289/9N`eD'UdY>/U^aL5FM^81C8¦œ›ž»¡›²À®­«¬§·©·¯µ¿´º¯®·¶ªÀµ¨© š¥£¡œ‘ª©§µ¢²§®© —›§Ÿ¤«¸¢¬š•™Ž£¢•Œœ ›˜œŸ‘“”ª¶°¨™”œ¬ª—Œ”¥˜¥¬¢‘–ª²£Ÿ¦«±™¡£˜¢–Ÿ›–œ–¡“©œ”«™‡Ô’š»s°Ã€Ã†~Ֆ›¸xˆ˜Œ—‹Œ§ˆz¤¶u}wv‚š²`ƒºyÀ|u¸cµ‚Œ‡©|•¬©q{t¼ˆ§ ia¦Ž¯¡~Œt‡ª}¾os¼t²ƒuxŠnšˆrn¤t½^w}Zay¼kZV\jy^jaegbmxoZ\YCA@s@CF+5G"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-7A9§›ž¢½¡—²Ã°­ª«¬±§·¯¶Ã°¸°­¹®­À°«£¡¢¡››©£ª²¤´¥¬¥ž•™ª˜¦¬¸œ¢­—“Ÿ¤Ÿ’Œœ¢—š‘•’¯¹²¬•—£§§”–¤œ¤¬ž ¨«Ÿ›Ÿ¨£³Ÿ£¥Ž§¢”¢šœ˜•£˜¯ ’”©ž„˜¶‘Œ·•x‚“šµwmknsoy…ŠtŸÁ»½š{±¨p€s‘¹ƒ|††Œ‡|Š‡Œ—|¤»¹½œuz´£tw—vt°u™žf†jµtrqw¶Œ^z}‰hƒynzc‹¬pu…X[§jEeZTf`c^cQgfpluCNPMD:ZM?J3;0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITBKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7LT_G'SbW8*O^]=+:VU'>;<§ž ¢¿¥–´Ã´¬«¨¬«©º®°Å­³²­µ¦³¸«©¢¡¥ž ™“«£¬©¥µ§§Ÿ›• £«¤½¦¡©–“›¡š‘¡§¡“œ—“—”±µ·­™ž¤¤¢‹’’¦›¥ª›•©¤¥œš¡¨¥§¤©¡‘­Ÿ–¤ž———ž¯¨”›¦¡j}i›¦x‡r}™Žtyd‡{½¾Àºo“ƒr•‡`rjZ^›‰`cˆŽ•k`€•cmwb•k€š•”e^`cpšŠhr‹}†•gkrux}~b[wthP\nƒ}{‹kXkz‚sJJo†pNtMEX]gaLZXgc_O[muiqRPDEM;GI=M?2,2A?8/5?C<9;@;=C>RVVWYZ[\\]`aaa`\UG5DFUEJOHFPIIH;8=51:.0;:.0-76=5&"/*2,%;8-7JR_I'S`V4)P_L(3>[O'?2>© ¨¢Â£›µº¶£¬¥®§§µ±¬È«¯²ª³¢½°±¦Ÿ¢§œ£›™™«¦®£¤´¨¤›—” ›¦­¨½§¨¤”“š•Ÿ™’—¤¨¨‘˜œ°²¿¬›§ž§¢‰“‘©š¨£›š« £™›£§¬£ «£š°›•§ –”Ÿ—°¥˜¡§™›œœ¢£˜¥¡™›™™™•gm}qw’—”’…‹µª†˜•ŽŠŒ˜–‡”•Š„“”‘‰Ž’”˜“˜–š ¡šœ” Ž‚z¥…mk}‘|€uŠŠq‚xyvvŠ€|Šjstƒuew}wkozm`c]phMXZfj`WZoymmfTOFS9OZMQO(+:KB635=@A9:C><ENSSTVWXYZ\]`bba_^^[TKCSGKNDGPLOI<:;389,2;820)6IRO8")+/2#4;*7FO[J&R^S10T^:+=8\J,<-@³ ³¢À¡¤²²¶ ©¥²§¥°´ªÈª¬¯¤´¥À¦³ ¤¤œ£••Ÿª¦¬¢£¶«Ÿ˜–•Ÿ–­©¥Àž«£”‘›——’“¡žž¢§’’™¨§²Ä°š«ªŸ––¨ª›œŸ¬˜¡›œ¢¤¯§¢¥¨Ÿ®˜—§™™ žœ¯ œ¡¦•—’—“Ÿ •¢— Ž–“ŠŠŽ—®|–›ƒ’‚‹ª©…€™—‰ƒžˆz„‡†š’ˆ†Š–Ž›—‘˜¤–š“‘Žg¡³¯…Š„v{’Š}wyzofy€‰kuzˆsis{vƒ‡‚kudyf`jecdfkYl{oik\SLPD^TE@?>,4@F;45;>A;<?>>HNNOPSUVVXZ\_bca_^^]^]XVJKLBIOMRJ;<:786/2964.(&$-1./)+*7%+<(6CMMD/T]Q05M[17E4[G5<,@´ ¹¯¿¬«®²± ª¦²­¢¬³¯Ä¯©ª¢±­¼¢³›Ÿ¦¢¡œ˜—§¥©¥¤¥²µ”“™™¯¥­¾ «¢‘™˜””¡œ—¨œ„žª«£´È´Ÿª¤ª––—š¦©šž£«”žŸž ©¯ª¦¤«¢®›Ÿ  ˜¤žœŸœ¯£˜ž§’—–œ‘£˜—§œš—e‚’|e~šcyŽmik{’¤ªje›˜}g†Šeeih{Ž¡kg˜‘£wkj‹™£Ÿ˜slnz„ŽˆzXf^†ƒ^m‹‰v\hswv’€‡‚nw‚x€smy„tvˆˆƒ|k‡Y^ltd^s‰ik|qkd_RNXIdXAJ4>G7?FD71<=?AD;;DGHHILNPRRTW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%/*+'6*$;'/AJ[J/7ZO6)EY/DO2YC;?.=¥Ÿº¼º¯¬´±ª¥¨­®°¦­­°¼°¨¦£­®°ž¬–Ÿ£¡™™¦ªœ¬£¥§¨²­ž”£¢¯¥¶¹¥®¢ŽŽ™¡™“’š ™™¤•{¥­¢¨´Ä¸¥¢§¯Ÿ”ž¢ž£›¢©¨’Ÿ¡ž ©°««¤« ªœ§Ÿ§ ¬–¡›¥°¤—›©• š‘£–©—}½ƒˆr´r„†­hx¹Ä¸q“¢£z¦™™r«‚|ËÀÀ»qŒ£ˆ‚Ÿ}–˜‰À½‚—žÂÁ|‚|“šÃÀ}l¥²oŒoÊz›w‘ƒŽvy€€yqz‡pw…Œ“ynx”cg`xd`e‚c^tgldcXLVIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^__`_^^^^___]\SMPGUNA??=6468276*&%#)*&.+*)109*#>I[L*#BP.#F[3PY/VAB;/8–£¹Ãµ°°À©¨”£¯¨°®­¦²³®©¤¥¦¯«Ÿª˜š¢Ÿœšª§¢œ«¢¤¨¤¤´£œ¢’¦­«·³§®¡‘‘™œ¥’Ÿ¡˜›Ÿˆ¦¬¤¬­ÀÀ±¡©¯©—‘Ÿ¢™¡£ª£“¡¢ž¬¯ª­§¤¤§¡¦¥¬¨‘£š¨­©šœ¨›« •–¤• ¢–œ~Δxz¤y•–›_®^Ž§¢ |§–›s«ƒ€¯^cŒª{¨‡… t—“ˆ³c‚«†¡Ž³j„¯u}—ˆ·aƒ­Z£Ínv{Ú{™p~‡’v~e{ˆvvk|‡n}†‘‘~mƒarmph``yd\qhjdg`RTSW]KOC5AHDD8>6;@?A;=8@>??BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5578164('$!',&&/(&+360$7;SL+,-K0';\;L-!P@F4.1­ÂÀ¿µ´°¸—‘£ª§­³«¦²««ª£ª¦¯©Ÿ¦›™¤—œ¢¯Ÿ ž¨§¢¥ Ÿ°¬š•§®¬°ª¨«Ÿ”‘šŸ¤’ž¥˜ž§£Ÿ­¥«°¨Àdz¨©±®–’›¢—Ÿ©©Ÿ•¡Ÿ­¯©¬ªœ¨¨¥¢«’¬²–¥¢ªª¢¥¤ ®Ÿ‘˜¦™Ÿ™““— q…Œ—u…¨†q±}žr¬~¡ž¥žv«‚}­œr­~«‡†Ÿv™’{|—~ªˆ¢Œ’Œ~«{‰”Ÿ€{­WÅ{p“Á}•muoŒmeve†oawnrn‰Š’ƒn“‘fpuuqagme_oiingdXS]aYRSC9II@D<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;91478452&# 1' 1' '45-&7=WJ-<'>1)3V@F!G:C1.+°ÓÆƲ´ £Ž£¢¢¬¯¶®¨±¦¨ª¦­««¦¡£™¡•Ÿ¥«Ÿ¡¥Ÿ¨¨¢ž°¬—š–¨§®«§¦§ž—”™£¡‘” ­›¦£¯¬¤¬µªºÎ²­¦®¬—•œ¢™ž®¬œ— šžŸ©²«««›­«¥£«š®±¡¨«®¥˜¤©¨¨¯¡‘•¢£™“‘„¤j¤u‰z©tz²p‚¦Š™Œqˆ š‡¤``R¬…®ƒ›v­§†…Ÿz™—†{f€£‰¤™†‚£}©~‚–‡®_|©Vž£’z£Ÿ€{ïŋr¯³³¹qb©¯ÂthŒŒ˜Ž‚nœ•qozxypmgeerpf|ic]W`jXYULLQLCCAB;C@@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799664,&$" ('"+-"$.!3-&@DWH,G+56*1PKL# A9D4,'ÂÉÕÔ¿¡™«§ ¯¢ž°´°®©¬¢§¦¨ª«©¤¥Ÿ›¤ž¥§§£œ«š¢¬¡£Ÿ¯¡œš’«£µ¯® §š•“¦¢š¢¨ Ÿ¥œ±¥¤¨±­·È²µª¬©–‘œ¢™Ÿ¥³š¡”Ÿ§¬­¤°›­ª££ª¡³­¡ª³±¡š¨§­®´¡‘”¢¦—š‘|©lž„‡u«y|°o‚¥Œ‰Ÿ––Ÿ”Ò¸´¸É²_`”©ƒ¤‰‡ z˜–šxªÉtš¤•¨©‘’šœŠšÆÆyg¡‚¥tŸŽ‚}¯]p´b°uK£†m§G‚“dž‘|q™•q|u~|n\fjsqfk^aYdm\_YIMLKEDAB>A<B?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75685/)(%&%$&),4ENPPMFKJVF*L0/=-5OTQ;<F2,$§¤ÀƸ­¨²­¬¥¢œ²¸¬ª¡¥š¨¤ª«ª¦Ÿ¦¥˜ª£Ÿ®«¥ ¬šž©¥œ§¶ž¢—“¨ªµ²¬›¥œ ”¥¬‘™œ¨£ ª§®¡¥§©°µÃ²³ª­¨“Š—œ¥›¡£¯¥—¡•™œ¥¦­œ±ž¯©§Ÿ¬£·¬¡±¸¯š®¦±²±£“–¦¢™žŽ‚NxšŸz„£}ƒ¤…‡¦Ÿœž“„¸{{y¹‚Ìƶx›¡‹Ÿ~š–—Švž˜Š¥˜¤©°…† „¬}š•c¦m¤p…}–‚r¬`£sq€š`¼}RUtŽ’£–{~”“Œv{s†€q\nnxrjo[d_inbd^LLQTAIHFI:9K>B108866877-*5==?BDGILNPTVXYZ[\__^]__]ZZZXUSOH@882.,*.+*''?QTVWWWYXXWUOUF<E3:P[T6?H,- ‹‡™©«¤«¹ª®Ÿ›¡¬²³¥ž •¥­­®ª§œ¦¦š£§¡³®¢©¦² ˜©¤”£¶¢¢•—¡©´¸£›¡œ¢’¡±™ž›§¦¡¢°®œ¥¨¢¶²Å±­©­©‘‡œ¨œ¢¤œ¥—ž˜šš¦¤«›°¢¯¥§˜¯¤»¬¡¶µ­œ´±·¯±¥—œ® £œ…ÑµÃ·y‡Ž…‘“€¦y”¡wŒ ‘„¥Šqª†…´nrj™£œ•Šž|˜™†‡s¯‚¦œ£Ž¦‹“‹–›nq²]¥t“zœl™{™|m©a£qqŸbs²¸hw”¦˜}Ž•Žy~yƒnjyizso€u^eeomfg`J[XX<HH@U4@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^__][[ZXURRQF:223//++(@QRTUTSTVWWXXWUUVTQOQ[U%!2AH$)%’sŒŠ­¾¿¼º´ž–§¤­µ¡¢™”¢¨¦®««˜¦¢Ÿ¦  ¶§£¨§°£”¬£Ž¤­¢ššª³³¤œ¤œ¨‘”—®ŸŸž§¤¨µš¢ª¤¶¬Ä°©«©¡Œ„Žœ¢ ¦¢•™š™›™¦¥¨™­¨¯¤¦›­¦½¬”½¯¬ž¡¯²¸©²¥š¨°¢§—y¨‘}|°wŠ€¤¥ˆœm²p¡‡­|¡ƒ§•˜€¬‰…®…Ÿ”ª ¡—†Ÿ€™•€{’~«€›–‹«x¡’Š”’z¯^¤}¦§d€|—sj¯]¥kp…™]`[Œ m•‘¦™ƒ–Ž™Ž||„™€knctn€z`gfqnhghCYa[>KU3U8BBC7$$3+''3, /6674359@CFIKMNQRSSVZ]_a`aaa^][ZWSPONI7042.*,ATVVVTTUTUUTTUTSTVWWXVUUQHFIJ#((½“šƒ¨Å¶À³žš¬ ­¸¥£Ž›¤¢Ÿ¯°ªŸ¤Ÿ­™ž¹ £« ¯©™®¡«¨£–‰š®°¬¦ž¥›¬——¬¡ ¦¡š¥®˜¡¨§·©Á¯¥©¤ž‹€Ž›šŸ¦ž’”™›”›š¦¥¦›ª¬­¤¥Ÿ©¨¾¤–ì©¢ «²¸©¬¥ž²­§¨—u¯~‹œ…‡}º­Š™e°e•­} ƒ¦•š¬Š„°…¦š¤¡¡„ \lj³`­{{ƒ±mgo™™Œˆ±[~µ\¤„kÈ¢dŸ€{¼XvµY²}R®€z¬X€¡m˜¨›Œ˜’™™|zŸeu~c†xt|ajgpmgefOUd\AU_>I(>9=4!",%2. *1/045799<ACFHJLNPQRTWZ^```ab^_\[XUPNJFC553./@UYXWXWXXWWXWVWWWWXWWXYZZ[\XWWGB;ҟ²±·½º³Á²¢œ¬¦¤µ¨ Šš žœ³³©Ÿ£ žµ™ ´¨ª¬ž¯­¬›•¯§¡Žˆ›Ž¯«¨¦¡¥™®’˜¨™¡¥Ÿš££¥™ ¢ª³©½°¥¨žœŽ}‹›–¡ ˜‘šœ’š˜© ¢š©®¨¦¦¢¤©»ž Æ¦¤¨ ª´´«­¥žº¬««”€©’£¯Ž›‡¤—™‚€¸ÃºƒŽœ’„§—œ‚¬Š‚¯ˆ§œ›¦ª~սªb£¿½}~£‚ƒ×º¸µ…•“ƒž½¾„m£‚o«„lœz²°Çƒi«°½¬xw¢¾¼s€–Ž¦‘›’šŸ{‚’œ{d~{egy‚{alekjcPb[Sj\?TaCN)=:4/$%2 $(0496677;>ACFGIKMNNQTW]a\__a^`[\YTQMHC?=A?5=SYYXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ¼•³³°¿¸±¼²¢œ®¦¤²¦‹˜¥Àª¸²¨¡¿¦§²œž±œº¨Ÿ­¯¥§””°«—Œƒ›‘®¥¢¬ £œª —‹£’¦§œš¡©£™Ÿ¡¬­ªº®¨£š–’|ˆ™‘¦›’‘˜™˜”©›¡™ª©¡«§ £ª»ž¨Ä¢Ÿ­¢©³³©®¨Ÿ¹¦­­™svª¥¸†d‰ ph®‘Šnnw¤™Ÿu®˜”p‹q•¨£›—®¤rlllf‹xon‚™qzjqigŠ—–˜qii…ˆgq†d]ˆbjoY\f}v¦_aqŽ‘nee“¡˜™™“™¡~ˆ‘–wgˆxiky€yemcflbKeXJlZ:PeER'K:+# #,)-2.5:457:<?ABDEHKLMOQSV\WZ\``a]][TPLHD=:AB7MXZZYYZYXXYXWWVWY\^^]\\\]^]^][[UW^©”¬³©¹¸²³ª©¡®£²©—’¿³ÅÊ¿·ªžÀ¬­¤¢§¬Ÿº£¤®«­¦Ž—®©‹…•–­ž¦ª ¤£ ‘‹¤’§˜©š—£ª¡–¦¦§°»¬¬š›’‘{„–¥˜‘‘™•Ž˜–©– ˜©£›±¦¢«¹Ÿ¯Á§£²¥«¯°©¬ª¦µ¢¬¶•Š¡¨¦·‰–£™‡ª›‘•’©²™š£ª ²–¢¡Ÿ¢œ¡¥¡•«§’’Œ‡“œ•‘™“™‘•†¥›˜–Ž‹””Œ†„}g‰~t‚us‡Šp§lz”‘“’•¢—šš¤„‰–sj‘wqŒxw}zjmdcodUaY@j\HcaOY+F=+'!750.!%2(*699469;>?ABDEJKKMPPQXUVY^`ac]^UQJED>9=@ASX[\YWXXXXXYXXZZ\\^__`^^^__```_YY`¦–¨ª¤´¶®®¡°£­Ÿ µ±Ž¬È¾Å»¹«¢¥žœ§Ÿ±©£¶§©´¦¨‘˜¬¢‹‡‰œ§•¬¤Ÿ˜§žž’”£–¨š¨š”¦¡¤›¨™¡¶»¨«™šŒ|”‹¡”Š•‘–‘”˜¦ ›ªŸœ¶£¦«·§®À­¢¶¥®¯¯«¨¨±· ­»˜‘¥¤¦¶¢’ž§ Žª Ž’Ÿ£«¯š £¯¨¯˜£ œ£ªžžžœ–«“™¡›”–«šŽ™™—‘–Ÿ’‰¡ž–•…’‘Ž•‹€}f‹…u†ux‡‚sœj…”“‰|‹•’’˜”£“Ÿ™¤…Šš‰|s—s{Œ€s|jod^pj`[`ZndP`ePZ:GGE>2=>9/*&+)&&416668:==?AACIJGJKLMSSSUZ``i`eVPJACB:9EMV[^^[Z\[[[\]]^_]^__aabaaa`bbbdb\[c—•£§¢¯±«®£©¦¬Ÿ§µª¥µ¼°­­¢£šzž£²¤¥±©—›¹¦£“™ªœŽ†Š‰œ¢®ž¢•¨Ÿ ’–™›®‹ª–¨™©™©Ÿº·¤¥™œŒˆy‚”Œ›“Š•’”‘’—£ŸŸ©žŸ¸£ƒ¯µ¢¯®t£¼¢±ŸwxŸ¨°¹”u¬£ž‰€«d\bv ¥Ÿ„—}m’³œ£§­ª¢ežŸ’syš—p€˜¨˜m¢¨Šeœ¦’˜˜–’œ’†ž›–„’‡’‰…wjŽ†v†p{…`h‡Š”’‹Zu”ghs{¨œ›fzš‰„y™j…Œ„oz€kre_vqlkh\ffbbpS[>NNNSG>@UD:1/&4:306678<;>@AAFHBGFIKMSTUY]`hfgXPJ<DG<8UR[`ab`^__`aa_\]__`aabcdabaaedchd^]f›•¦£ ®¯¬«©¥¨­¢§­¤’–«¶±³§›«§¬—sŒ° ¨«§”—¹  œ¤‘‰ˆ›žŒ¬š¢•§¡Ž–’ž„u­ˆ§›©‘—¤‰œ»´¨ ™˜‹‰uw“–“Š”‘‘””¡œ¡§™œ²•€Œ›µ³Œ’Žº¦ ~§¢z¡­µ€Ž¥žƒ‹†±ª¯ŒŠ—¤›z€‹¬†›¡§¨§‡•…˜w¥›z‡œ—§‚‚{œ²zŠ†¡˜š•˜–ƒ‘——…›™bz‡…’‹ƒmpŽ†y€p€„~…s…„•‘x–g’t šu}™…£ ˆ˜”Œ……škŽ†lx{qqgdwojlk\ekjet\^ITLR@E6.ZUU7)!09>>743568;:=>>@DI?IEJLGSX[Y[aahfZQH9DL;>aV^bdfd`aa`bb_]`aabbbcfgcba`edcgcaahœ—¢Ÿ¥¬¬«¨¬ §¯¦¦©¥™”¯È¿±¢—¨©¶ž„¬œ§¢ ¾žšŒŸš |†™—‡¬œ¡–Ÿ ‘Œ“‰†€‘§‡£¤”˜ž†žº²¨žš’Ž…qv‰•Š”›Œ’Ÿ’—¡¥–ž«‡Ÿ´‰´š­ŠÊ‡©¬ˆ¶…°¯¬‚¨Œ¦˜}¨r{wœ§—h•¤y´ŒŸž¦§’˜Â«ˆ˜¡rž€š¥}—…•²¡}¡”¡˜—”œ‹™’‹}…“‡Ž–’‰ƒmr…~yq†€ƒ{ƒt„€–€Åf©‡£kž…¤„šŽ‡‹šq”…hxu|xhhvphhl^dplflXgG]RM3E46Nbd7&3<EGD:64658;8>==?BM?NIJLCPZ]\Wa^il\QE=KM@JcX]cfhgbbbbcc`_babccceiicbbbecafcbbi”–¢Ÿ¯§¨¨¥«Ÿ£·°©«¦š” £¤«¤—¦«¸£¯€¡¨¦ž‰”½™“¡’žy„––‘‡«™›œ™¡„Ž‹w›œŸˆž¤œ–š˜‡£¹®¥šœŒŒ~bm‹“˜Œ‘’ ”¡¡™¡§~¡§‡­ –­œœ…€ Œ©­…£©™Œš¢u€™”k‚­vM«x‡œ‘š¨¦€©«}ƒ¡{z§jž’kg—†—·‰ž~n`dYƒ—€{dh‹r™}y–l]}—m_Rpƒ\_kx‚_Xd|ƒ—p§ªkƒ£nr¥pŸ… jg m[oŒ}gZ`„€bXPowfmtrkjo]jqmkiXiO]YF9A5HD_l5,ICRMN=84859;6@;;>BO>QRLMBJ\]_W]^bu`MD:MONTb\\ffiibbdbddbab`bdcacikdbddgdbgeach—• ¸ ©£¦¬‘ ¶»ª®¢™˜¡¢¥­®¡ž¯µ£¨’¡  §œšŽ™´™‹ŸŒ•‹u”’ŒŠ¦••™žž~’……¬¤‡›Š™©™š›’ˆ¦±§¢–šˆ‰€inˆ‡‹ŽŽŠ‹’Œ‘“£”Ÿ œ¡¤“¢¡” vœ•§‚ ¦…§«ƒ¥x‰|„š~¢ps”ˆ–|Ÿym†›Œ™›¨™Ž‡{‚¢sv¦fž~w¤_˜z}“t¢n˜·´ºt“ˆƒ€µ¨dÆ¸{p•¶Œr€š£bs¬«`|i³~m|†‚‹˜q£lr£tŸ…¤a™³–r}˜Ÿ³us[ž²ƒjbotvqioXkmsrf]i^bLE=D6QBZs3=SG_JR=<395::6D;;@JP?UMOQ@E__[ZX``|dHC8MWUWbaZefkkbbeadc`ab`dd_`cknccddhdbgfchh“•”£·˜ª›“Ÿ¤¶´¬­ š¢¤£¦®œ²®¬“˜¢š¡¤™š”ž«›‹ˆ’x‹…q€–ŽŠ¡’”˜}‰¨ ‡—Ž‰’¤”œ›‹©¨¥ž–‡…~j{‡~}ƒ‹‘‘‰”¡ƒ—ž  ž‹‰wœ˜¢Ÿq¡Š‡©‡›¥Ž”¦©}­Œ~z ™z£“xt–ˆœ}–Ÿ†›Ž˜›¥…¢d¡|ˆ–›mžh›Žoš™z€‹§}rit«ƒŸƒtªh•š]›…v…žgªk€¸f\¨pœ`•Œ^§vu‡ˆ~žhšu†“’—Ž€Ÿoš‘n§š]©y»k~ª\Ž„]´g\nrzxki\qkyyc`fXbBQFO7WCRo5K[Z_NZDA251;;6H?:CHU>YRY]>Db^V`Qac}jEB9N[^YdfXfgnmbbe_aa__``ec^bdoq`deekecihgki•›‰©´š§ˆc”›«¹±¯¬ž¦œœ© Ÿ¯œž±©­ž—¤›¡ ™–– £™†‰jˆ€r{—ˆŒ––„‘•˜zŠ„•£œŠ”†ŒŸ’‰©£ šŒ’Š€i†y—Œ{‰ŽŽˆ—›”£Ÿ ¡“˜rhŸ‰Ÿ‹p’Œ€©‡˜ž¡¥ž¦{°­£¢¸—w£³£¤€ˆ”y{«™~¢Žœš–ˆ—q¡|…¯µ}kš‘¡y~˜µ¢¤«¨„™|›}ž›tªZ]o{–‹xžbL{z…cy—BLŸX¢jq{Žl€ˆ„™u›x†‰±³€›“§wƒžns}•pštk¤]•vHed`tq~~of`liv|debQ_W]TW@ZFQhDSW\bX^ID=B8?B:IF8LEXAWR[VDFb\Z`K`m~rEB<U_bZeiVghmobfg^aa\]^`hb_ecvm]egfkdflihki“œ€°­™„S^ ¦³¹²²¨š¢Œœ¬œœª”¢¬¤£¨ ž›™–˜¡–ˆ‡‰w†oy•…‘›‹|‘“–ˆr€ˆ’¡œs‘‰š•¡›…©œ›•‹‹‹|ƒl„…q‚¡Œx†ˆˆ“™–|“¤ ž¢ˆ­†}µ„Žžœ{¥–z©•›‰Ÿ›|§hwm~™t¡sr|†™p“ƒ®}¤ƒ¥™€£o^¨gu¢co¥aœÓ}{™xssb¢†~£t¤vk³Œ`‚˜‰sª²¨¼wƒm~¿¦©´]œm|p–mr¢r]¤gs¦`h¦m›Ôš~†›py{—lœ|x—sn©¤g`ezq€…lhfdnvxg`cS\fQQbHXJUaWT[ej\eQFCKMJKBKE8O@QNXSYOSQ`ffjRcwywIFEc]eZhjTihjocjg`c`\]]_hbaie|d^dgdkdjmghlh—š¯ªT\K~©¯±³¯²£›™…™© ¡¤Ž¦©¡™ªŠš˜˜“™“’¡˜Ž‡…{p}„h}ƒ”šw‘Ž‰o†“’l—“|‰’“¥—ƒ«›”“‹†‰yƒv‡€n‚Ÿ†x’†ˆ™£˜{”£¤™Ÿ‰³¡¢¶‹z¬§¤®¥p©€šŽ…€š{¤€¡™†˜rž„¤®¯Š—Œ€¤•‚­ “vµ¶µÉ¡s”‹Ÿ`—©mz•‡ ›t¢ˆw ~“—‹pMf£’pš‡s¤{ytaƒk} kqd_œq}s–hyi³µ´Æ¦s˜}zkœ›«v…›mvx˜jš{u˜rQE}³_jvkzˆfkhcuuqnW_TYiPShIVMYTV]hknVgWNKAJMKHJOAQKPecjmetrsy|nu‰{{TPNl^i\kiRjhilhlfce`\]]^ibdik{_]dhcjfnmeile¡›ˆ®¥ƒd?“¡²ª®¯µ¢¢€—ª¢£¥Œ¥§ž¦ƒš—–Ž—œ“Žˆƒzjy‡eƒ˜ yu‰Œi„…’ƒŒ…y‹–¦“ƒ˜ª˜’‹‰z€}‹yp¡†z‚•‡‰– –”¥¨œ••ƒfnxœl¢d{q¥w›˜pg¦€•Šz¤zŸ–ƒ—ržwŠ•—¹n‘Š¢b}˜ •ˆmriªku mo¦_ši‹i–‡›–u¢~š`Œ†upˆbh ež~i›uocfˆmq¢Z^[b¡m]ˆ‹nz}srd¥mx¢dg§h™sŒ™p¢oU‰o _f¨T‹^T˜nmskr‚mpilytkpRYWWfZTmIYO]IXiisjYkVQRFV\LXSaUik_wt{}p||rƒ{€sv€„v^QrbgcpgPjhhklnhdg_]^]`jbjivu]\chcjjsmfkmcœ£—¥ydsm‹¦­£©°±¦Ÿ‹€˜«Ÿ¦Œ£¢›£¢–˜“Žš‹˜ŽŠ{‡q€ˆi‹‹|˜›su‰}{dƒ‡•ŠŠ•™‚|ˆ‡—¨‘£¬†‘‹‚Š~€€Žsi¦„}‡”ˆ™ ˆ“©¦ˆ¦x•›~¤ˆ–‹±˜‚¯—ž¥v”†x©s¥„šn¤¢Œ’„ƒ»n}¥¯‚†…†“•œŸ|¥zr¨• –fž~o¬d–Š–“w¨mª¢‰v‰ƒw«‘¦ˆk‘°kv³Œ©kŠ…mmŸž’•`~«‹ªv~~‹¥žvŸ|ƒ¤• j›ˆx¬hž­Œ¶tw¾¤“Zƒ§Ž«aurtp|uqckoimSW[Vab]kM]R]J^mnw_[qY\`[gtenorcrt`wz~yryƒs„{{Œ‚€vbxdcnrdRkgholrjfia`^\akbmlzo\\bibmjxmglnb•¤©œ£–©©¨¦®¤™Š‚˜¬šŸ¥Š›¦©…Œš†œ‘…’Œt‡{ˆ„o…~˜“tt†r‘‚m‹‘‡†“Ž}{‚†˜¦Ž¦§ŽŽ‰…•v‚‡’ol‹©ƒŒ”Ž‰Ÿ‰Œ”ª¢Ÿ€u”—ˆ~y”®¢›q†wŽ‰‚}{r§Œq}}z˜–›„y{~‡”•“Šv˜ž ƒ{}‰kŒ…[yyrzqin~’‰q€u”“q‡„‚eŒ_‹wtr”uoynm‡l„…^ugwŽe€€…¨š}t{•j‰ˆpv}‡wnnhŒsz|˜x…\lXyioxrqoxxp]k‡njgV[`W]fkdVcU_Q_pxylkvfkkkw}rrutaovbt{‚xuz‚u€€€x‹…ƒ}{nldyn^Wnghukxjije\`Zcjemqtn[[bldllynhloa“·¨¦‰ ¢š¦£˜¤œ«¢¡„„˜­’ž¡‰›§›©˜ƒ›‹–”‡ŽŠ‰rƒ|}~…{˜tr„p•…{}’‹††„y~€‡š¥Ž|¨¡‹†…•ƒ†Ž˜wr„©†Ž’‰ŸžˆŒ›§ŸŸªƒˆŽ•š~~‰–­§‘¦wo›xn~¨…p}•qkp} €“Ž‹hl\‚‹‹›šžŽs•‹ˆqtkvtYrn‡‘~Œj]jd{†„‰€`ixzš{‚Šu…gwŠ†japqt^qŠˆŽ¥”…e‹ƒnw‹„q†zqhhe|„{–[\khnv[|yxunssƒg\m‹kkbZZ_[Ylq\_aZ_]et{uptdkkk|}s|yudnuhm|~wz|{yz€€~o†Š„{}t~yshT\qilvpugkhd]aXkhkkqrnW[enlgszohjm`‹Š©°¡¢¡šž—ž˜¨£¢~ƒ™®Ž •ˆœ¢‘¥•{˜…}’™‰‰†‡Šs~Œv…Œ‚„—Šro€r˜†ƒ~’ƒ„†‰€z„Œœ¡‘ƒ§¢ˆyŽ—‰•‹‹œ—„ƒz­‚‘˜š•Šž‡ˆ¡ªŸ¡¢£‹‡“›œ£™•ª¡§¦Ÿ’š‡•Œzvƒ§~’“”²¦›•Ÿ±’—ƒ¥ŒŒ•šŸ‰›‚ˆ‘Šk|Žwxeƒ‡‘‹|‰ž„‡Œ‰ˆ…„w|zt™ ˆ†‰‰„“~}Š€€uor„‚~w††Š¥‚…Œ†‚ŒŒ}ˆŒŠ‘„zmƒ…~z™ksiatŠq~zwwowt‚]^o‡hn_^Z]]ShrVd]]blhu||sopdkji€}ny€rjpqlg{r‚€x}„{m‚Œ†|zy{}zƒxNcvjsnpzekecb`[tfpgrqmU]ltmhyzqgikdŒ‡œ¹ž–¡ ˜”˜™”˜¤ ž|š¬ŸŽ† ‹ž–}y”ƒ{Ž™Š†ƒ„‡nysˆ~‰”„mk~z—‡„ƒ€‡„…|‡…œŸ“‡« „s‹†’‘‹‘}{ª„Ž“˜–œ–‡‡œ¥Ÿ¢š…‚’š™˜™¦Ÿ¥œ•ˆu{†„¥{|Ž‘†™«¡ž”Ž©€Œˆ“™ž‚—~†Žƒox†qu`„†u™ƒƒ‡……„•nyvt’¡Š‹…šƒ„Œs‰{|rqz‡ƒzw‰Žƒ‘¦…ƒŽ€ƒŠ‰Šw†‰‹Œ~qm‚|ohlmh_zh~|vuvu{x\_q~nt`c[]_RgnTe[^bkivyqlmdkjhltlluozp†yn‡€v‚€~…vq‚ˆ~{{|{‚Š`h{juhi‚djc`i\cuhobumlUcqyepz{sejmm‹‰ž¶™ £Ÿ’‘•˜‹šžŸž{xŸ§‘œ‹‡¥•‹˜™yz…|‰‘„Œ‚‚ƒn|€ys…~‹‘}kh}‚—‰ˆŽ|~†„†|‚“‰¨€pŒ‹Œ’† ¡Š…Œ|¨‘ˆ’—“–“x£Ÿ –™€š˜’Œš¢ £™—š}Œƒw‚Ž† ~ŒŒ|˜¤¡¢“š‘¦Œš‘‰’—›~“’~‡Žus‚pwa~€Ž†r‹–}ˆŒrŒ‚…†hxrx‹˜‘–}ˆŠq†{|pwzŠƒyyŒ‚”¤’‹…{…†‡„vƒ„‰‰|gs}€y{qmkg_~sh|uvt|s€j^`tvpwdcY__RkiUeY`ahjvy‚qgkdlhf€€kn~hoql~y‡zlŒs~tv‚†|z}irƒntia‡hlb_qVtomm`xhmWjtvcuz{rbjoz‰Œž±‘¥¤œŽ—†œ ›}w¥¡Ž˜€£‹ˆš–y{†‡~ƒ‰‰‚r{tvƒ…~Š‘xgc~†—Š‚ŠŒy}€ƒy–‚–™˜Ž—¡œ~pŒ‚‘“†¥›‡Œ‰ƒ¦•…“‹–˜“’w‘ ¡—”–y~Ž——–šœ£˜’”šx„‚wƒ•~‰Œs—£Ÿ¢”™¢ŒŠ‚–—ƒ’–™~˜|ˆvq}n{d€|‹…q‡“€‘‚l‡ƒ€‰…fuo{…‘—‹|’w‹ˆ{…{zq}wˆ„yƒˆŠ—¡•ƒ‹vˆ„ƒ‚w|ƒŠ‡x`zy~txgmeajjwstv~q|cc`snurmaZa^[leRcYaahkvy†qckcmfh|ƒmiuhnpi€}‚ym†r€ƒƒt|ƒŒ€}z‚ƒ~|mv‰sumeŠljbbvV„ipn`xglbjvpfy|zq`rl†…›­—¦§žŒ—‡†Ÿ“—™~xª‹™z—‹Œ˜y|Œ~|„|ƒxtyzt}€„€‰‹€d_}‹•‡~„†u}~‹}˜†—•˜¤¢™r‡{“‘‰¦ŒŽŠ“ ‘ƒ’•—‘‹˜Ÿš‘s‘“‰ž¦——Œ”•r‹Œ‰k„—™z‡ˆ‰o—š¤”•‹Œž‹†‘œ’’•†™ˆ{ŠŠyqykul|‹~n†“ƒ•xq‚„~~‹€eri{–—ƒ~s‡ƒx†|uw|„{‚‹ƒ‹“£xƒt‰‡}€tv‚‰…pa|v{r}pbocd|cnpvsxwstbv`olvno\\_^^j^P]Ycahnt{‰k`iekciw‡nglikmh}{woˆs€„„}t†‰{ƒ}z„}}Žrz‹xxml‡jh_irc‡gqoewgnlayik}{xpaxm‹€˜˜©Ÿ£¨ŠŠ’…Š‹•˜~x¯™—}Ÿ”‘—“ˆw~{Š}|€wx€€put|o†}Š|a\~‘†ƒƒs{€‡z’‰“’“¦œ–‚}}ŽŠ‘£ˆŽŠ˜š†’™”–ŽŠˆŒ’œ’ŒŒn„‘ˆž™¢ –•‰–m‡˜ƒe…˜Ž“z‰„Šp–š”£“’‰‹™Œ}’Ž’Œ™Ž{Š…‡ssvkpnu|Štn†‘“qu|ˆ|eply|™“|ƒˆt‰€s‡xn|€…{„‹‡‚‹”§Œz†{~Š…w~qp‡„ehyuvq|b_pakt_qj{yylspey^nlsmrX[_`ak[PWXecgqq‡f]iigbgqodiheiizwuoŽ…t‚ƒ{u‚ˆ…x…|x„…z‰w‹{{rxƒjk_pht€kromrgole|cn€zwqlwwŠ~¢—¡§ ¦›‡‹‹œ‡“v‚«•“Ž‡¡–”s|v…xyss{†kspzn‹v€ˆoq[Y~‘‡€vu€€€ ‡’‹”ž˜¢•˜xŠˆœŠ†’˜–…‰•š—‹‹ŒŒœ‰Žƒm‰‹‘Š–¡›—”…—‡iƒ¢e„œ‰~‹ƒ‹w“˜’Ÿ“‘‰‰”~}Ž—{‘ŒŽš’|Š€‚ovplmop{†itƒ™‹qw€u‚ˆƒyfrnu€™Ž{‡ƒy“yu‡so‡z„ŠyŠ…‚‡š¢†{ƒu‚‹wynl…ƒ^susqqyZ_qapk^pj}{qmmjmv`pokqmYYbabnXQTZfgcup„‚b]kndcfk’n`gg_hkursp‹€uƒ€xu€‹€y…x‡†wƒ…|†‹{vŠjqc|c†|nqmtjholvx_qy|uut€ƒ~¤•š¬ž§–…„—”ƒ vŒ ”“†‹›–Ž‹yqxt‚pr…tqvˆlpnvmˆvƒ~€nnUQ«”‡ƒxwrƒzƒ ‚“‚•”™œ“›x’{ƒŒ’£™“Ž‰•™’„‡—™Œ”‹‰‡„Š|s‹…ŠŽˆœšŸ›•““}h„›†g…Ÿ‡‘„‘‚‰qƒ‘˜›ŒŒŒw{‘zŽ‹Œ‘–Œ|ˆ|€kvjnkll{bz~—v{xƒŒ}ygsls†•‹}‡…z“pyƒov‹yˆŠyˆ|‹„{zv‚‹|wqjl‚„{`xqnmrtV_pbra`mozqhoffstiqkbwe]Wf``rSQO\fe]ypˆ|`\irbbef‘j_he[gp~pkqtŠ}v|†€uu~Œy{…xˆƒs†…~ŒŒ„|y•xfrkƒ`ˆ}ookz`jnuu_t}y†xts…}x ™°›¥Ž‚‹ƒ™‡€ŒŸ€‹š”…ˆ˜„vtwt€qp…tpr„pkiwnƒn}}musRM‚ßȒ֓{pu„v„ ƒ”w–‘™‘™{”s…ž¡““‰“œ”†—–ˆˆ’ˆ›Ž€wz~‰ŒŠœ›œš”’yŒuf‡…k‡¢„‘ˆ—ƒ†cŒ‘™•‹—ŒŒŠ‹qz”ˆ{ŽˆŠ’‘‰y…|l{espklzz[yz~€†Ž{zhrjsŠŽ‰„„|”Šk}~m‹}Š…|ƒx€Ž”™™Š|uwƒxrmgq€…nkuphjunS_oepZ`lrxgkjbfxrppc`w``Vk_^vPNLagb]zq‰u]\evabeeŽdagbYissnkqvŒ|tz†‚uv~‹s€†{‰r‰ˆ‘‹ˆ|~˜vesn|eˆ~opl€Ylnyys`vz{vrwŠwyž‹›®š ‚…wˆ•~|Šžˆ† ’…Œ˜„“Ž‡txpyqo„omoseeyq}mz}jhkc¤šÁÜ®ð¡slv„v…£†“p—‘–¡•œ’r†‹¢—‰•Š–ƒ–…‰€‘Š‰–~‡zu‰x‡„Žœš˜˜Žv‰tm…ˆ‰|‰¢ƒ‘‰œ„…^‹“—‹‰‹‹„‰m{–}ˆ…‰‘†v…}~k}dxujnysX‰{’ˆ…z~†Œyeri‰‰‚~‹•„kum†Žƒ}x~”’˜trw‡Œusqgvz„cunqcjvhRaqglV_otzard`i}prn[cr`bVnY\xNMLdfb^ws‰n\\dy^_ee…`cc_YjsknkswŒ}tw„xw{‰qƒ„}~ˆ{t‹‰ˆ–†Œ~—sgurylŒ{ntqWqzvyrewy‡iv€‰rœ†˜¦›£’„}qŒ”wyŒž……¡|–€™ˆ„{swptjplim|u_axw|qu|h`d|ëÚµÉÃ܇slt‚w‹›‰j™‘ž–”‰q…ˆŸ„‹•ŠŒ˜”|“ˆƒ‰{‹…vxƒ„rˆ‚“œ–”—…Œu†~oƒ‡†˜¡‚“Œžƒ‰aƒ”‡Š†‰‡‡i|“}ƒ„‰Ž‚q†~qwhvritwlZ}“ƒ…}€„„Š‚varkˆ€Ž‰~~‘}mkw„„‚{€|~‘•ˆnpyŒ…tkqlsy‚aujo]lwaRerifS`pvuap`]hƒqsjWghbiXmV[uLKLeg^bss…j\\ey^^dg{ad_]YkofojtxŠ~ss~{vzˆs…ƒ|‡vwŠ†™Œ‚{“ulwvyx“tnx{}Xz†q€ogyw’ƒdv†…pŠ–…™ š¢Š‡to’Œqwœ~‹š‰‰| „™€xrtnodrifmxx\`y{{qq€jagaÕ¶Ž‘¦xnqw|q“‘ˆkš‰“Œ†{i‡‹™†’‘†‡˜Ž|Š|Œ}‰„ztzƒ{q†€–šŽ““ˆt‚…t‚‰‘œ†”Ÿ~ˆb“‡…ˆ„Š€€ƒg|€~‚Œ~mƒ|‚tkmwutwvlcŽ€…~}†„‰p_qo„{Ž‹{~ˆypƒey‰…Šz„|~’‘ƒmny‹~umnkl{diljYnwZSjsibQcrxmcf^Zjƒnsb[g_dl_nU[pOHOge\goq€mZ\cs`\clwee]]Zklcmjsw†qp|}tx†x…‚|€‡uy‰’•|‰†vˆpxy{„“on{w^ƒ€t‚mizt”sgsˆ|q’‘ƒ™ž› †ˆvv”mw”˜ˆ„‹Žš}Œšv~vqpljau|gbjuz[`x|zmqechgW_qs–¼Ä„wq”Š€t˜Œ‡”ˆskˆ•€{”‹„›Œ|Š†}|‰Œ“‡t‰…vv}‚qu†ž•†”‚‚q~‡sƒzˆ–›–†’œ€ˆf}“‚€†ƒ‰‰r}g}‹{y‡‹}i€|ƒvfoyxswtlk†‹‚‹yƒ„„€k^pwz}‹‡„{€Ž~r€hx†‰„‚w‚z–‹Ž‹|mkzˆ|vtoih~we]qcXptSTosibNhuyga^]Xo€otYda]jm`pOYlRDThbZlom{oY[^mcZcowdg\]`kjcliswƒqn~{tuƒz„‚|‚…v~‰–‘xƒŠtˆsyy~oo{qi‚yz~nm|v–kjx„tk“Œ…ž˜ ™…ˆo~Œvjy™€‚Š‚–˜Šz–ozsqljd`t{i`fr{[as}zgpzaedŽ±²wKbZ¥Úїr{’Œ‘y–Œ…š’†ol…’‘yy“†€„™Š|‡€yx‰Š„•€oŠ‡qt}{jy†ƒ¥‘„“Œ‚~n~‚u‚w„š—’Š“”…‡pz’„~ƒƒ‰ƒoxh€…xrƒŠ‡|e|~ƒvcps€iyqou™†„‹|wy€„z‚k\o|r‡ƒˆ}…‡zˆq€mp‚…‚ƒqƒw˜‹ƒwmm~ƒvzehj~raZxZYrnNXrtf`Kmwub^\[Yu}rpWf]fjq_oNWiS?Yg_[pkgyq[[YkeYcpy_h]^elhfliqx‡om}up‚{€ƒv…‰—Šq‚q{†|zy„”Œukzko~t}or|{”po€yf’‰‚¡˜‘ƒ†g‡„pgz—Š~€…‚™Š|ixrllf_aoym`boy\dlƒzaqv_deÕ뾋2:>‹Ž€ry†‰w…™Ž”nm…Œ‹u}…‚•‰|ƒxnv‡…‚–wn‡„ku{teyƒ„§ŒƒŒƒ}msu‚x„š‹‘’Œ‹†~{’‡x€…ƒl€ri~xm|{Šƒxby„‚qdqh~nuru‚œŒ€†tv~€so[k}sxˆŠ{†|ˆwypk‡‚Ž‚‰q€w}”‰Š}tmjv€€uu\iiyqZW}SZrfM[srf\Jqxp][[Z]uuiYb[genbiMWfQ=^f]^vf_uq[YUodZdpy[h^`gmgjkhpx}Žmj„yn{}‚zu‚Œ“…p€‹nw}€{{ˆ“‰€i{~jt|r†{sw}Œzx„~|kŒŒƒ›–Œ‚l~khŽ|~ƒ”‚}Šˆkuqgic[cgso`altahp‰zast^bc› n\5Z¯µuj€Š~“‡wˆ˜‡uŒŠwpm…‚†ty‰x‰}“ˆz~sguˆ~}—oq†}hvynez‰…¥‡€‡‰}m}t~{Š—†’˜ˆ‹„‰|‰r|~…|i~mk€{yjzv‚‡€r`w~qdrgu‚nu{†•’‚}‚€pwz|u~mWm}usŠ†v†t‚‰zwrmˆŽƒq}{|‘‡ˆzmmhm‚un]hftrR\|N\q]O\spdVKsyjXYYZaqua]]`fdhhfNZhNAad\`va\umXXSta[eorWj_bhkgmlipw|“lh„‰}|p~{‚zw€€‰‹„r{‡oqw„{‰„j~{nxywŠw}x€‚‡„~~zm„Œˆ˜£…„{v‹zkm…‰’y}{‚’€€}Š„prpcf^Yg_pp`ahpfjo‰tato[`djv{¾œ§¤É¸r…„s”}yˆ”„t’‡rsp„z‚su†tˆw”‰yyqdw†z€’hq„ufwvdj|„ˆž‚€ŽŽ}q~rƒx~Ž‚w•Œ”ˆ‚ˆz‰‰lyzuhzilysizv€ƒ}h`x‡}jjth{€jv‘•|~~q|v|t~bUu{qrˆ‚‚{p†‰wxoo‚‹}|w|{s„uhpglˆ‚rp]hctoLfvL^oVTZtnbQOtybRXX]ap‚s[a]heecjdQ[qIDdb\dq^\xhUWVw^\fnhVl^ajgennhpwz“niˆŒy}s{~y‚‚|v}ƒˆ†ƒpvƒsnw‚‚~ˆ‹”q€|xzz‹tƒx‚„z€uo}‰‹›žˆ~†{w†{gu‡‘z€|‰†„v€gpn`e\XfYmsaaaqllh‰n`siX^cm€w©Ú©Ç†ˆ³rŠypŽv}ˆ{”‹€utu~vopm…t”†xtl`yyˆŽeqƒogun[m}“€y’’}wzl…tŠƒr•‰‘‡……{†muvmhwfm|vmjwv|`bx†zhuvc~{hu†Ž–}u€vr€z}m€YVr}os‚†~wkˆ†sxjt‚‚|y{wzqŠ{rgsdm‹„ls[j_vfIooL[cXWVymbPSuwYQVX^`r„o\`cmdc]ocT]rGBf_^fi]Z{cRV\u[[gkaVk``nfflqhpvxŽtkŽŒuvx}wƒ{t~ƒˆˆƒoququ}…‰‹{wx„|}…‡x‡|}~…€{~rvx‹ŽŸŒ‰{Šwuƒz^~‡šy‡„t†‡„w‰{bnm\b[[aUjtd`[hopg‡qaqfW\ck|Ê·º¢kno‹mr„r~†‹{’…zytyutzjlvc„v’‚vog_|y‹ˆeq€jjqcXm{†œ‰ƒ‚r—“w}{m†o€‰Š†p–Žˆ†Œ„{yrrp~ghrcmxqjlqw}|y]ey€wiuxf‚whu‡ŒŽ•}s‡jo~€xn}]Wp}ms~‰{€mnŠpvfv~~€u{pys…{xqer`m‹krXk_x]IplNWV_TU|kbOTvsRRUW^bt†i]`kjfbYnaXcpGAh]af_\V|^OVeqY[jh]Xha_rfjhqgqsv†yn•Št{w~yƒ‡€us……Žƒpp{xwuy†…‡Œ†z|u‹~}†„„‡~}‡|xvyv‘“Ÿ~}‹nu€zd„ˆ˜†t’Šo……‚zƒucnjY_[]]Uhse`YdrrgrakdWZ_ix¾®zŸ¸nbt‡iu|rz„‡{~€wxrwozvejoa‡uŽsjb^}wxŠ‚ep}hkkZVox‹¤…p™’qwt€l€†r“‡Œˆ…‰…}yusoiyajmamvjgkkywzw[g}|xer}n„tfu††–€p‹gk{ƒtlub[nzjszŠ{€et‡|mpgt}v|~pzjyz€xvoelal‰}lnVjaxVKklOROiNY}hbOUvlMQTU^fv„g]aqhgaWi\\kiJEkZbeWXUyZNWnjY]le]Zec^tfleqfsptxp™…vx|…‡}us‚‡•ƒnsy{{sr…†ˆˆ„y}v}„‰Ž„ƒ{~‹ƒ{w|wvš—zŠƒ‡jv~}l„†•r‚q…‚~‚€oflgX][\[Tepe_XcruivpdebW[[hpor€sŠefzjuwtt„…x…zwtunkzpahkg†t„nf^_|oz‰}hmwfjdVWspŽ§}„|v–s{q{xlyzƒu—|‡†ƒ‡„}uqsmhu]mi`mudgfizo{rYgvuhp€x‚vbw…‹|•‚oŒkm{qfse`kxfqu‰z}auƒuikqtyoxwr{e}}~wunbe`l†|mkVjcrTLjkPLOpH^|faNVueJOSXakw~f]gsie_WcWbq]KKkXdbUTUsVMYveZ_l`\[ce_wgmbpitoq~ut™w€x€†„z}v‚ƒ~˜…nrt|{tq……Ž€z‹ut€}”Ž€…„}~Œ†z~v{£¥Šy‰†…lu||u„ƒ{o…sz…}‚ƒunjieV][[ZScne[Xbt{jimh`aW^Zi€ilo€gmbi{zktuuo†‚z~vunzhjyj_enhw„heXavi}†yniofg]UXoi¨wz|Žxtn}mqtx~w”t…ƒ€…‰vjsvhio\me^ns_gbjxh{m[mƒrtjo€~ywaw…„x†sˆrpzrcqh[mvdor‡zwar€ogixsqkwvsub‚z}vuocbbm||kkUibgTLnhPHRlEayfbMTr^JMUYelx{f_mpjc]V`UonWJShXg^XMUlTK]z_\_l]][be`zhlaoovnowuz˜}w€y€€‡†zyzƒ}“„qtt~zvt…ˆ~}ls•{‚Ÿ…‡}€~†‚€Š{u„¬Ÿzˆˆ„lr‚zv‚un‡o}€tŠ€jonedX_ZZZUbjg\Z_u‚i^ml\aW[\kequ}ij^mxwhuxsn‡|~~zvslzgiwg]dsgzw’ccTdof„vvfhjaWVYhc¨owŠŽzpo{fwmyŠzvŽqƒ}‡ndwtehi]lb^pp[g_muezh]t€nrkq{~uubu†Œ{ˆˆ€xru~taplXpraopƒztcq€k`lznihywspdƒtxxtpd`cmr}jlTi^_ULucQGWbGcwfaLTpYKLXXhlvzedmqfcZX]XvfTJ\cXiXXHWeQIcx[]_m[^\bc^ij`ntxmonvƒ—yr€}‰Œ†~uv†x†Œ}tuu‚yzz‚ŒŽ}~…‰jt–{Š}~…y€{~|†‰sq®Œ{{‡~fqˆzt~}vro†l|~mzcppbe]eVZYWcfk`]]s†hYqn[^XZ\l{bqwvlc\ntuhuwqn…yzwootehte[gufvv’z_]Seej‚s|aci\TW^bd¥iyt‚…xlmyfwl{ƒyt‡r€x|y€iewm`ga_k`^ukYf]oobze[w|knnpxytuesƒ“ˆƒ‰zvor}raxcZno`op€zseq€d^muhcfxzrkm€sr{qqa^emn}diThYZUNy_RJZYHcudaJTmUJLZWilr{dllsbaYZ[av\TKc]YjSVGYaNHjvX_an[[_bc]…ihbnwymojvxmƒ~€‚’ˆ„vu‰tŒ†tqvvw}}~Œ“~px–ƒ}™’y€€xy~s‡„sp™¢z{€‰•yeuˆzsywltply|p’s^poagblT[ZWidmf\\q‰eSrn[YXW`lvdjujj_[ntrmttuk†}€}wonldipc[krdtvŽs\WTd`q~q\bc^SZa\d“Ÿerq…ƒskjxlnnyyzq€vs{z{dfvh^c[ah\^whWb^phawa[|vjjroxtstiq‚•ƒ‡…vsjp|mfwW[ilapqxseo~Z`ppa^io|kjr}qovio`[dkl{afTgUXSQw\RPYRHdsb`GVkQIPZUklk|emora[ZXYlpWSPfWWiSTFZ\OIsuX`cncXaab]Œjcemzylnivy†zk„}€…™|‚„y}ˆm†qovz}t‚‚}‹ƒ‚—tx‚”…Ÿ‰ut‚p‡ƒvo¢—s{†‹‡{fw‹on|pgxq{lsvsk^tobgekS^\Vhbll[\qdNom\VWUgithctee^Zpvoqvvzlˆ}€}ˆwscdkoa\nmcsx‡kZTVbcw||p„\c_cTZ`Zc—•cnp‚…‰rifyndruqzkytuo{v_gsd\_WbdYaueU_`mdaq]]~ohisqtpuvlm…”‚‰|…qrgn|oqoRZeidprusbluUbqj[^nd{dkt|qqqil_Xdijx^fUdUWQVoXQWTPHer_aFXkOIXTVnid|ikxkaW\U[tdSRVhQYgTSHZ[PNyw[_emjZb`_^nagkyvnnivv~m„€~†—{‡Šk“ˆrgt€{u€ƒ~‰Ž‹“s}Š‘…‡Ÿ†{†Œs€†s}‚un¤Œs‹wxnz`e}qgztylmqwƒgd|mcgghS`_Ug`lo\^nŽhMil`UVSofskfxee]Zrvns{ysn‰{€wœ{zkaelm^`njepy~gZVX_lx{zoƒ_b^gVY`Xdœˆbkp†|wkjvl[upjyiurno|sXko`Y^VcdXeqcT_biablZ`~kflsuomxvlh†Œ‰{ˆmqfp{lqlaX_ggnrsr^ilSepdUbmaxaotztinkj^W`fhu\dVbVTOYgSO]OPHep]cGZjNJ`KXme_xhn~d`U^T]u[TR`gN^bUSJ\ZQZvv]_fmhXca[^Žpchjwrsmhvty‚s‚ƒzˆŽ~|ŠˆŽynŠtls‚sˆ…‡’„•z}Œˆ‘›„€|Œ„rstwqn““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~~~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’’’’’’’’’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’““““’““’’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ‘mfggggg}…„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDBK’š™™™™šzlnmnnojfggggfo„ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‘g_```_^yƒ‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR455553?“žœœœœwegggghc_____^j‚€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}zzz|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‘ŽŒ‡‡‡‡‡‡‰““’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†…………†ŽŽŽŽŽŽ‹ŠŠŠŠ‰Š‰ˆˆˆˆˆˆ‰ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z||{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘’’’’’’‘‰‡ŽŠ’“‘‹’Ž‘ˆ‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…Ž…‡†‰†ˆŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰ˆ‹†…„…‡ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰ŒŠŽˆ‹„‡„†‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}}}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹ŒˆŒ††ˆƒŠŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz|zz|||{}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒ‹ŽŒ‹Ž‰ŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzyz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{z{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†……………„„„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰Ž‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{~~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““”””””””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••”””“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””“’““’’’’’““““““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’‘‘‘‘’“’’’“’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’’‘‘’’“†…“‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘‘‚€’‘’u‡‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ˆp‚{uˆŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒsn‰‰rx‡ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒvmz‚sx†ŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡smm‚ytu€…ƒ„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\YXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxz}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzoq{xy{|{xw{xuwttvuuvwta^d_bjpfhklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkiffggghha_ml]fggebcbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__ac_\_]`]^ZZkwlbosjbZY_[XWSNMKKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{xvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSTPMJMNPROM[jrk_ltsgQQSPPNNOMJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTtsuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMN\cnkZisupSMOPPPONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKKECEIVbfkqpnmlZMLNMNOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHECGHIN[ghgqnnifd`__XLJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:<=HY\[^flnkommlkiijbQGEEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@:;><;;;=JZhnnpjnmkjlldOGEDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnppsttsqrvxy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;:;;99:88;<979;:=E`nsnnlllfQB?CFDCCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqtstrqtxxy}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<:79::979::78:99<H\tuqeP>:;=@A@=;;><=<@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyz{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>><==?@===?C;==><:Aj|i=9;>=>?@@@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquutusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCDA?=>@A?@<\n@>DE?@AA[c<==;:=>AA@>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVppqssttuyz{||~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???BFD><<=@=8:;mwH8;:=>A:Id=<=<8:;??=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pprrrtuvz{}}|~~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC?>AAABA@YR<==ILFFuwM788:;>>VjA;<<::;>??==9:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC@CryI;\ƒz|wW<=?==>EhtL:=>?==?AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hloppqtuvy|||||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCEAGrykbƒ„ƒ‚ƒ€}^>@C@@=Js{Y:=AEABBFHC=<@DDA@?>=@A>>>?<>@DGE@>@A?@CFECBCC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{|{}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@Ent}‚‚ƒ~}„vMACE@?>Y{€]?CEIJIIMMKECFGGEGEEEDDCA?@>>BFJJGEEGFFJNNKJIGGHKLIGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z{{~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@EEhs}|„~y…rCDEDCWu†‡‡~XGHJMLNOOLHGHGHIIHHGGHHECEEEFFHJJFEGIJMOOMMKJKJMNKIHGHHHGFEFFFDFHGEEHHFHGHFQnnpqruvy{{{z|}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJG`{€w„…ƒ„‰lAAVt‡‰‡‡‡ˆƒWHLMLMNLIFGGGDGGGGFHFHECDDFEDDHHCCCFIKKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrtwwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLLN[|‚‚ƒƒ…††ˆƒVl„‡†††‡ˆˆ‡|PKLKHHFFDDCC@@CCCCFFEB@>>@AA@BD?>?DFHDEGIJIJHHHGIIJJIHFJJJJIJIJJJFILLJJKKfopsrtvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKLKJTƒ„„‚‚…††ƒ‚†…„„†††‡‡†ŠuKJFB??@???<<<>;:<AA@><998<<=;>;8;?AB@ACCB@AADDBCFHIHHHLMLGIJMMNMJJKKJLMSlpqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHHJIIe…„„„‚ƒ‚ƒƒ„……†‡ˆˆˆˆ‰ŒhCA=88::9878896479;<:8567789787588;;;=@;999=<>;<=ACEHJMLLGIGORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@CGIIh†„„~ƒƒƒ‚ƒ„†‰ŠŒŒ‹‹‰Š‹Œ‰`C7555766655873568:876565676767:67889:7578979776:<@GFIGIFEFOSRSSROPPRTepqsttvy{{{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@6788=:=ECBe…ƒ€‚ƒƒƒƒƒ†‰‹Š‰‰ŠŠŠŠ‹‰ŠŠ‡fI59@58874578557699776765:9:::;798987669:98868589;A=>>BA?AKLOQPQOOORWkqrttuvz{{{}}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897;B:=q„€ƒ„„„„…†‰ŠŠˆ‡‡ˆˆŠŠŒ‹ŠŠŒƒePZC:<=>99:;8:;9:;::9;:9===>;;<<:>;9;;<;<;9:<8::::999<?<<ABDHIMKIKLWorsusvx{{||{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<:89989:::;?>H~„‚‚„………†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹Š‹‹Œ}jS=BDEEBA@B?@CA@>=>>@???@>?==?B>@A?@?=@@@>?A<><;:;:9;?=;<==AACABCAXpqtttvz{{|}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::<=:;;==?@BR‚‚‚„…„…„†‰‰ˆˆ†††‡ˆ‰Š‹‹‹‹‹ŒŠ‹tECGJLJJGGHEFHGEBA@CEDCABBB?@DHECECEDAFEFDEFD@B><@>=?@>?>?>?>>:;=<`qrttuwzz{}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>???=A@CDFW„‚ƒ„……††ˆ‰‰ˆ‡†††‡‰‰Š‹ŒŒŒŒ‹‹‰ZJPNNLOJJKIIJJIECDFGFDCEFDBHIKGHGFHGEKIKIJKJCFCCDBAACBDCCDDCA=;=@hpsttwwyx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLK@BBA98<>;<;>@?A>BBGGIY„‚ƒ……†‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹ŒlmUNMOLJLJIJHJFDGIHIEEHFFELLMIJGGHIJNMNLLNKHFGGEECFFFFDEHHFCA?@Llptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?EGG=<@@87<;;=:>@>?@CFIIP_ƒ…„…††‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒ‹‹Ž}`XPONMLMJHHEIIEKIGJJIJGGGKLNLLHHIJMQNPNMOKIGIJHIDIHHFFGGIGCBACTnpuwwyzxyz{||}~~~~}~}~~~~~€€€€€€€€€€€€€€TDAABGHB?8?@9:<8=>;=A>?ADHJLUqƒ„„„„…†‡ˆˆˆˆˆ‡†ˆˆˆˆ‰‰ŒŒ‹ŒŒŒŒ‹‹Š_TTROONKJGFBGJGLKFKOLKJJLMLOPNHIKLOQQPQOOJHJJLJKFGHGFFHFEEBABB\orwxyzyyyzz{{~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<9@>>@BGGAGKLPVy…ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹ŠŒŒŒŒ‹‹Ž}ZXTTVTOMKJDEGLONOWUQPOQSRMSTOMSLPSUVRSQPLJMMMKNGGJFFHJDDEEBECcpuyyzzz{z{zz|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?==B@BBGVNFNPPTX{†ƒ……„„‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŒŒiYXkbFTQQPJ;;RSR`u]UVTVYYRXXRZfPUWZ]RTWQOMRQPPQKKKHHJHEFIIIHIirvyxyyz{{|z{|}|}€~}}}}}}~€€€€€€€€€~~SHJIHGFFE??AAEACGEDELXRMTUVXZ|†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ~aŠ‹‹‡m\eV:YYXSQ?@VUX\d`VYbr]]W]ZVEQYZ[Y_TYgRVVXTTVTOOMJLJIILMKOMSotvxyxwzyz{zz|}{~~}~}}}~}~€€€€€€€€€€~~~VJJIHGEDDBA?HMIMPKIKPTSSXZZ\\x…„…………†‡‡‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~‹‰ŠŒzopY[\[RTRVVU[ZuƒYU}a\X]^WIV]][[_YHYXY[]XXYWRQMPQMMOSQQURassvwwvxxxz{z|}}}~}~}}}~~€€€€€€€€€€€xy}YNKIIHFBD@A:PQQWXPPOQSTTXXYZ[n‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡„‹~gYY\YTVTWRQWVc–€QerXZW_hP`f[[X\gaGOZhg][\]]WROSPPRVVVVYZnrtwvvuxxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZ[RSQORRRUSVTW_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†~€|]QVXURUSQQLOMKfy[]TYUV]ZLTZUST^ZXWWWzkX[\\^TQQPINOWVX[Zdprvvttvxyy{{||}~~}}}~}}~€€€~~zxwvsu{€€tk~~kry^[VUSROKFCDAM^ƒlVRSNOQOQURSRRUcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ymqWJLNOKNKIJDEIEC>TdURQQNKQTQMOYRMNQSUUMQSRPOMLHCIHRTUZ\lquuusswzz{{|}{}}}~}}}~}~€}}~~€~{vsw}~~du}iqt_d]^\YUPLILIal’tPQSNQRQR[RSRQRUTbs{|€‚}{{€ƒ‚…†‡‚†††„†…†u_]LD?CCCCB@DPBCAC=CIGV@HNLG]iPHFNFDEFIGHBDHGIKGDBAD@OQMRdrtvustuz|{{{{||}|{~}}}~~€€€||}€€€}vt{mh|gnqfiedb\XSQPURsWe[OONLQSQUYSUQQTSOV`klrv{{xytrnstsyx}ƒ€ƒƒ‚€‚€‚‚kMG?@;;>????>kPJ`EFHIEB?GLNGMRUIBE??<=<==?=?ACC@?==B>JNGUnttustvxz|{|||}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QRZ\Y^JJPQNKLQRQTUUWQQWUPX[b]agmmlokg`nrjmlqu{z}{xz||xwxeC@@B=:BCAADB\]O{NONNKLMOOQLKMWMHG@B<977599=;;;898:?<BH?\stuuuvwy|||}||}}~~|}}}}~}xuvz{zwyxuw{|yxuywcqhipmnmmhf^OP_]ZIHPRQOMPQNQRTVXSRYTOYZ[WY]^^_e`]^qvk^`gkwooljonnlfbYHFFHBAGIEEFDMRPaWRWQPSSRU[OOQVPMIDF>:96587979:365795<C>essvwwyy{}}||{|}~~~{}~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`VW^ZXMKTTSPQUOLRSTXXTTYRMWYZVXXVXY]WWXhsk]Vaskaa_^da_^YTQNONLIHJLIIFCQPS[WTTNQSYS\eUOSSQNKIHC?A999897885757859:Gnqtwxy{{|~}}|{}|~~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPXVVSTVOOTVXXYSUTLKTVUUUWPSUWTUR]n^RNY_[VY;DVXT[fJLPSSOMMNNNLJFQPUYSTOJNOUST\VRUSROMLIHHF?>=:787659967675Wppswyz{|}~}~||}|~}}y}}|~~~}||}}~}|rvqxxrvuqqnppopuvtnjddjppqrpnfedc\]RTZVWUTWTRXXYYYSUOJGOPOOMRJPPOPNNOTLMIPOSTU2=XMI@Q=caQSQPNPQPNNMQNTRPRMILJORPRRSTQROLMKLLHCBA=::876;B5566:doqtwx{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqptuvcjgeWhtrrqniihpVVTUXUWURWVUZYXWUQSFEAFGGHFJDHJIGEHLHKHFLMPMG/E_R>3?>joaSRQ@GUQPQPQNQOPOLJLLOPNNPQQNPOJLMMKGEEDB;=<<9=G6677Dmptuy{{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknaePSTRSTOWVVYYVQQQO@=;=?ABAC@BEDA@GHGHEFHJMLEGCORC8ENS]gSQSAGUPOQQPNMNMKLKKNOOQMOOMHLLIKKLKGFFED<AA>;@E;<89Sprtx{z{}||{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLOOMQSLTUTXWULLKI<987;>@><=A@B=>EHGCEFIGJJ@FAA@FHEJOHQRa\QPROSOOPLLOMLMLMON[WKMQOGIHCHJLLJFFFE?BC><BG?B?Adpswzzz{|{zzw{wy~~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCD=9779?B>;?B@@>@DIECGGIGIEBB?>=CBAGIDMObeQMONWKLMKLMMMLLONSdNJLRIIIEAHJLMNJGIGBAB@?EFEHDKnovyyy{{z|zwsxtx||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGMMJMPMPOHJD?A=98::?B?<@BAADEGKFCHIGGHCC?B??@A>DECKNRTLJIMTGIIJLJKLIJMMOPRPKGCLGCBJJLMONIJIGCCCDIJMLIYrmwyxz{zy|vrpurtxyvxjqnjllnttmtu{stxronqovsnporpopstyjN`gsjt|ygosqiqhdqHKDGHHGJKIJKDFB=>=99:;@B?=BBCCGFIKJDIIFGGCC;A@B>@@BECIMPHHKGHKDHILMHJLHIJLKM]RHHDNFACJJMLPMKMJKFGGJMNQNLbmivvwzy{z}rmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoiktgdoFKDFEGEFFGEGBC@><=9:::@C@>BCDEIEIJLFIIGFFDB;ACC>@CDCDGLNHKNHDHEILNMGILGFGIILNKIGENHBFMKMLOMMNMKHHIORQRNRfffqosxu{z|lhjnekqlspfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGIDFFECCBE@DB>?>:;;=:=>CA>ACEFJFIHLHGGGFEC@=DEB>ACCCDGHIGMPJFFGKNOKFHIFEDEIJHJIFHOKCIMKOMONOPNJJILRUUROWd`amgproryzgehhdilgqlflmgiklslpvutpnvrosrsutqssutsuvvvyvutwljuumrvqlnlerLHEEGCBABD=BA>A=::=?:=>@B>@BDFJEIFIHFFGECBAAFFCBBBDEDGGIFLQLIOJJLLIGHEGFDCIIHKJGKRMBNNMPNOOMNOKKKOUWVUSX_^\iaminhrsbeffdhhfnjfmmhkkmriqvtsqmvnoqrswsrstuvvvvwvwvvtwujsunutsqrjksMGHFHBBADE<A@@C<8:=>9?<?B@@@DFHEHFFHGFFDCECDIECGEBEGEFGGEJMKHQMJKHHIEFHHECIIIKMKOSNDQRPPQNOMNPMLMSWVXXUX]Z]d`hbjigk_eefcgggkggkmkmlprhttursnvoqprtxqssuvu‚‘yvvtxuuwxmouorsuqqinyMHGHHBBBFE<?BBD<7:>=:>:@B>??CEFDFDEHEDECDEFGJEEJGCGHFHGECFJJGNKLKHJLFIIKHEKKLMNORTOHSUSPROQMNQNMPWZVZYVZ]YXa```^hec`dfhgjhhifhnllnmqpiuuxrrpupppruvpusuwu{~}xvtwvvvxplupmstnprrxNHHGIDBCHE<@EBE=89>>=<<AB=?>ABFCECCIDCEEFGGGIFGKHDIHGIGFDHKIGKHMKJKLHLKMKJNKONORUVOKUWSPSQRLOQPOTYZY\ZY[^^]`c^\ackb`dggr…hgifjmnponsrjtuxrsstrnpqvrquruus~yŽ}uuvvvvxrhuqkrtlqvptLIKIKFBEGE<@GCD@:<?@?>?BA<@>AAFCEEDIEFEGFHHFHHIKJFJHHKHFFLIHGJGLLMLLIMKMMMOLPPQUVWOKVVUSSQQLORRPV[[]^[\^__a`ad]c`ef`ehjdssfjggkorqossnswwquvtsmoruorspurvrtvuuuwvuwtgtrkqrkrvnvJKLJLGCEDE<@FDDC;??B@@@CA?B?ACHCFEFIFIFGDIIGIHJLHHJJILJFJKHIKJGKKMMJJMLNNNPKOQRTXVMNTVTRRQPLNTSRW[]^_]]`_`aa`acebdhbdijgv‹ljigmosqpqppryvruutsmmssmqrotutrpswtuuwvuuteqskpqjrvnwKLLLMGDCAD<?EEEC=AACBBCDACDAAEGCHGHHGJGCHIGHJFILHIJMKMLGKIHKKNQKRQMSMKNNOPPOTOWXX[NSPW\ZRWPNTUTTXZ_bb_da^`b^`eaacingbihhnxvlhimosrpqrrrvtsusssnksqmprotvrqquvuswywutucmtkopjqtowLNLLLGEA@D>>DEFC@CAEDDFBCEGCCIFCIJJIIKGDKJGHJIIKHJJNLNKILHJLKZfJd\KlSHON_nUks[qpbwcSPavuhucav`Xnqbdvinzf[lt`ljT_wvijgifglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqrqyLNJJJFC?@B?=DEFDCDBEEDFBFFGDEKFEJMLKLLGGMIGJKHKKIKKNLNLLLILML[sbdp^lmUMNfs]ffqlntgpi_aYnnbppbkjjfoqtetno\ougpMJqyvka`keemxlkvmnpsrprqpqrqrrrtrmmsnnoprutqsstuuutwxvutbmukpplrrqzKLIHGED?AB@>CFGBFCFEFEDCHHGDEKHGLNNKMMFJNHJKJILKJJKLMNNMMJMMN[roonpplkMPQlWMibtrpamnu\YlQ\mmZqmkomxxtsip]_rkqjUuyxoc^kfbgppjjopprspqpqqrrqqrrtlmrmnnorutqtrtuutuuzvutenukpolsrryIKGGEEEBBB>@@FGBGDIEEEBFIHHEHLJGMMNKMNGLMILKIJMIKIJKOPONMLNNL\hdu]lqWlNPQmTYk^klvaldsSecNmYl\tpkilxjwuhp]^rkhWbcw|oc`ggadiuyknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtvHLFIDEECAB=BACGDHGLHECCHKIHFJLLFNLLSRLGLLHNJIHNHJJIHNOMNLJNMJZsppoqqmlOQRnYrkgooqqomt]nXat_nopoqronusttj[^tcwxrjnzhaacfbbimtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyxtukoumtonssvsHKHIBEEEAA>DDBGDHIMIFCFJLJGFKNLEOJKWRKGKJJNIHJLIKJHHKMMMMIKKKSkc[i^_icrrZ_Yjn_eeUk_c[aaQ`lh]j\niid[pfdp]Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunwqrvtwrGGFIDECFA@BFEDGBHJLHFDGKLIEFJOLIPIL[QJEHHKMIHJJKKIHIGKKKLGHKKLMMLJKMNT[\TPTLPONOOVQOOQNOQJINPQdqiTYW\[\VY[]X]\\cfaaebcf__fkmhmtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyxxuvqruovrtsuusGCEGFEAEC@DHDFGCIKLHFDGKLIEGIPKLOKLWLIEEHIJHIKIMJHFGGIGHIEFLIJLOLIP\W^P\[`^MXYS\\b^MXZMXaRJYaZR_d\aX[ddVVX\YZX\VY\]b^d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtOBCDLMBDCBEIEGGFKJKHEEIJKFEHHPKMMJMRIGEAHFJIKLJLJHFDIFDFGEFJHCJMKLU_Y`X`a[`TXYT^^Z_RY\P^\YN^\^SZ^c^Z]`c`Y_c[`^[TXWY^]cbcacehekrpoppnow††……†‚{€……††…†…uqprrsvyyzyyxxxwryvxrqxvtvaSJJMIECBCGHFHGHKJJIDFKKKEFIJNKNKHLNGHE>GGLIKLKKKIGDHDCDEAFJD@JLJO[cY_^a_RTRW_`\]Y^QY\MV_WKQY[PZ_aa]^ca`bbbcceZQXUU\Y]c`__cdbhomnllllu…„ƒyu|„………††……††ƒ}wrrtxyyyy~}yuyvvrnzwvxXQKFCGEBEGIFGHHFFIGHGHKILDDKKNMLKHKJHIF?GGNKKKMKKKIFGCD@DAHIB?IJHO]aZ[d]_TQRX]\\\_ZKW\LR\YIM^QO\_accccb\dcbdcfXQUTQ[WZ`_^^aa_dlkmjjlnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMC@IFCFKJFFFHGGIGFFILJNFDKKMNJLIKJHHFBHHQMKKOLJKIGGED?ECIIBBGFET]Y^X_Y_[]UXXO]]QKJV^X^[]UY`RQ__bb``bb`cbaddbXOQQQZR[]]]]^__dhgljnnp{{|~{€‚ƒ„…„…………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKCAHFDGMRHCQJEGHHEFKJMPEFIJKNLLIKLIHGDHKQOMMPLLJKHICDAEDIGCBGFDWUE\T]SV_XOTUNZZMIJT`a[_X^^a]OYa\``_bcb]abW__TPOOOWQ\[[\\^_bffeleoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDFFHDIRbPCV^IGGHDFMKPPEIIJKNLKKLKIJGEJNQQNOOMNLMHKADACDGECBEGBMHBKKOONLFMFGIJHGLKMOPILOPOSOLPSRUZYWYXXdWOSTPPNMOTSZXXZ]\`adecgcklpsryy{z„„„…„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEHFGDKM]LGGXLGHJHGMLQQHLKKKNMUNOJJKGGKOSSNPONNNNGKF`ED_LEfdEN[I^[rmOMUmYLDP`UkWgJ]WU^DLQULLSVQRTXWTXUT\UPfZhhdXRjRVUT[\[``abab`fhfnkhrz|}~„„„„ƒƒƒ}|zr{z{‚€ƒ„„……„…ƒƒ~z{LIFGFHEEKOSIJF`THIOJIOMRQKMLLORUROOILMGHLP[YOPPNOOOIJQQI|YYqtYQmHqnoaVPqqsPCksmqspSo_[nX]V\XUkhU]VcZ`Y[_VVXjtuu^_v^Wa[[f[_`aaa]`agmpl`pwtx‚ƒƒ‚}€vxzlv~tx}€|~€‚„|€ƒz~wwNJEHMNBDLLFIKEQVLKNIKRXWQMOOMQTNOQOKKNGMOR[ZSQROPPPJHZx]TxehZSURvgtlpbnfjQrOMwmjrpsrqrpoo€]ezuxqqzq~s}ku}bRh|essorr{|o~xn€r_``baZ`_gknkblfgmw~€ƒ~{xw€tvzir~ns|~wx{~€ƒx|€u|||ssNKF`]GAEMMHJJGJPOMMJNV^YULQSNXZMSSRNKOHQRTYWVPTPPPQKHgxlcxrm[KNVypumubovPeeIfvqmwo€jfxxiWrQhzmijzz}lxzohoYvvjuup€_rf}ilx|o^__ba[]bdgiidgbcdllppstsssyqrxblugqy{srvy~suzn|}yxrnNJSuNCBFPPHJKIKPOOOMPZ`ZWKTWPa^RVQYRLOISTUXWWPUPONRJKrouuquqdibWnLqp^FhyWvTLiy}x`y{sna]mocRhqunmypwlvttrln]t~zkmy|ktl|kpvux^__b^]_ddighee^abiiijknokqomjpacfcowxompsy~nqpk{ztsomLL[VHGEGRPILMJKPQPPPPW\XUMUYUeXRRY^SMMITTVWYWOSNNNQHRmHiwK`dvvVXlOnl{sajgvULWkh}lmlx_Zpz{^`zscroxqhd}ir|^TLl`vukiu{zm~xk|p\^^b[^bddgeeebZccikkrsrvglihdg`akagsrlgmmr|kmhk{tmmkmOHKKHJHHQPLNOLKRRROSRWRVTPWZVVTTTa_PNMJTSTQVVNNLMOPJHQNPULKLSTSSTPVUQQNQQXYRNPUTXXX[[URSW[WXXZOSUWXXR^YW^VTPYRWWWWX^Zgr^[[Y\]_cZ_ccdfdccbZcbgfemnmueegcaf_]g`dlhfgkhpzhggjujhgilQIKLLMKJSQMQPOLVUTPTUXUYUQZ]VUTWUYWOOLMVTQNUSNOMLQPKJQQKQMKKPRUSQRSSIHLNOQRQQQTVRXW\WSRPRTUVSZQNSRWVTYVTZVTRUTTTWXV\Y^`]\ZZ\\_c[]bcdfdddaY`acabhhimbad^_c]Zd\bma^fefmsdigjkedcfhPJKLOOLMSPNSQQMXWUTUWWWZUS\`VWVYUXSPPJNWSPNUPNQNLSPMOUSNQNMNQUQUQRTUNKMOQTTRRQVWUYZ[YSURTWVVY[TPTUXUUZUWZVSRWVUW[XZ_\UX^\^][]`a^[bbcgfedbX_ab]`gdfea^_]]^ZZ_Z_g`^]]bhkagfhfd`bcaOLMLQQLOTOOSQOQ[YWWX[YXYV\jdVXYZWVSSOJNVTPOTPPPMMRRPRXTQQOMOSVOXRTUUONMQSVUTTRTWVZ]\ZVVQQVXV[[WQTWVVVYTXXUSRYWUZ^Y]_^U^\^`\[____ZbbdhgddbXa`b^^fcc`b]\\\\YZ[X[a[^]\_b__bdebd__`\PMNNRQMRROSTQOU\ZZW[[\XZ[dqmhd_[XVUWQLMVSMNROQROLQSRUZUSPPMQXWRWSSSXMOOQTXVUUSUXX[^][[VQNUVU[\WRTWVWXVTX[TSRZXW\^Z^_`Ua\aa]`b_\`]c`cghdf`Yc`a__ed_`b[Z\[\YZYXW\Z\[`^_[^^a`^b\Y`ZQNONVQPTQOTTSPW\\\X^\^V\^jqwy€c\[UUWQMOVSNQQORTRLRTTYZWUOROSXWTSURRZOPSRV[VWWTVZX\][[]VSMTUU\\VRTVVXYSUZ\USS]XZ]^\```Va[cb]ad^\bab_cfidf^[d`a``ce_b^YZ^[\[YXYWWZZZa\][]\\Z]`W[[ZPOOOYPUTRQWRTP[^^][`\`U\]hjr}slg\TWWQNRZSRQTRTUTKRWV[ZZSOSQVVVTOWRSZRTTTX]WXYSX\X^]YZ]TUNUVW^[XRUUYYYUWZ\VTW^Z]]`]bb]Y_[ea_dd^^cca^efidf^]da`aabd`b^XZ_[\[XXXWW[Y[`\[[\[XZ[^V^Y]POORZPZTUVVSTT^^`^^b\`U]^bkytl}kZUYTPPS\TUTUTVYWLR[W][]ROUSXWWTPXRSWSVUU[]X[YUZ^X_^Y\YQWRYXY_[ZTUVZYZWXZ\VU[^\^`a^dc\^]]eaafd^^dc`\gdhedb_da`a`bb_`^WX^Z\\ZYYWV]Z]^ZY[\[WY\]VXW]SNPVYQ]UVYWWUX__aa`c]_T]_beeuzhWYYSUSV\XWWVVW]XOU]Z^]\TRWSWWUSTXRSVTXWX]^X][V]_X__X\VQXTYZZaY\VWX[Z[YYZ[XW^_`_cbadd\b\`fadfd^_dbb[fchecf`f__aaaa`_^VU]Y[\[Y[YY][[[XXY[YZZ]_]TY]UNSYVS\TVWYVV\`abc`c^_V[`da_zuohY[YUWTW[ZZ\YXY`WPV^\``\TTXPUWVTVWRSUWZZ[_^Z_\V__Z]^Y]URYWYY]bZ^VW[\[\[[Z\YZ__``dbcddbdYafcffe^ab`c^bcidcg_g^abcaa`^_XT[ZZ[[X[XX\[Z[WWYXW\[\`]V]]SOVYVVZUXUXWX]_badad`^YYadb`lfh^[\ZVWXY\\]_[Y[bVTX^]ac\RVYPWWWWWVSUTX\\^``]`\Wa^[^[Z^XUXW[[_`\_XY\\]^_\[]X[`a^`ecdeefbXcedhgd^c``ec\eidei_f]cbcaa`__[XY[YZZXYXW[[Z[WXZTY]\Z`\U^bNSWYVWYX[\XWY^`badada]^Yacb_a``^\\\WW[[]]__\Z]cYZX]`cd_RXYPWWXYYWVWV]]^`a`_b^Ya]]^Y\^YXUW[\`^]_ZZ^]^^a]\[Z\`b_becefefbZdffigb_c^afdZihbfice^bbca``_]\ZX\YYXXZXWZ[ZYWXUU[]]]``bbxKXW[YV\[\]ZW\]_`bdaba]`Xbcbacab][\[XW[\_]`_][`d]\X[becaR\ZOYXZ[[ZWZY`]`bb`ac_\b]_][^]YYTX]]_`_`\[^^`bc]\X\^`bbcedfdefd\efgifcab\cg`\ihbhied`baca_`_\]\Y\YXWXYXW\ZZWWXOXZ]acffrkJYW\ZZ_\[^\X][^_acbaa]b[bdb`bbb\[[ZWXiq`\`_]\ac_^YYcedaS_ZRYX\]][Z[[c`bbc`bda`c^`\^^^YXU[_^]aa`^[`abfc_]T]``cddfegeffe^efhhgdd`Zfg^ahhbhhfc`b`cb___\][Z[YXXXVZV\[ZVVUMXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡„‚‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vuuuuuuuvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyz{{{{{{{{{{{{{{{{{{{{zzzzzzz{{|||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vutuuuutuvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{{|||||||z{{{{z{{{zzzz{{||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚‚ƒ‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||xÅÔÒÒÒÒԓ{}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ¼†‰‰‰‰Š‚E>????;›Ã¾¿¾¾½ÊÔÒÒÒÒÖº}~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}xÕçääääç™{~†“y1333332j‚€€€{­éääääèʉŒŒŒŒƒ:23333.¡ÒÌÌÌÌËÙåååååéÇ}~}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}v~ywwwwwwxyyyzzzxopppppprrrrrrrwzyyzzz~ƒƒƒƒƒ„|||||||vuuuuuu~ƒ‚‚‚‚‚ƒ„„„„„…‚|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚ƒ‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vtttttwtvwz{x{xwvwzxzzy~zyyxxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{|||||||zyyyyyzzzzzzzz{||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwwx}y}}|}{xwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwww|z}}|}}xxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒ„‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z{xwww|z}{|}|xxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzzx|z}|{}{xxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyxzyzzx{xxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyxyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†„ƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{|||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}|||||||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}|}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚‚‚‚€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrsuuttssssrrqpoooopqsssrrrrstttsqqqrstttttttsstsssttttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqsttssrqqqponnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqrsssssrqqpponnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrrrrssrrqqppppoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpqqqtqrrqqnƒnppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqqqpˆˆpqqptš€npppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqq|¢„prpŽž|nppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsqu‹‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqquž£xpx œ}oqqqqpppppqqqpqpppqpppppppppppppppqqqpqqpppqppqqqqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrrq˜©‘o‚£~pqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒƒyrssrrrsrrsssssssr“ª¥|Š¡|rsssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz~|~}|vvwwvuxzxxxxxwxxy¡³©§©ª—}{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~|{|{{Š¯¢¡µ©«¤{zzxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}}}}}™¤–¡±Ÿ˜¦•}€}}}€ƒ‚€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€œ›ŒŸ°¡ ¢ž€€€~~~€~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~€€€—›—° ˜”œ†|~~~€~~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽŒ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~€~€~€¡¬¥—¢šœ™¢¡ˆ€~~€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹Š‹‹‹‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚ƒ‚„„ˆ¢²¦ ¡™¦§¬©¡›’‡€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒ‘‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒƒƒ†Ÿ­¯¤šš ›œ ¤¢œ“‡ƒƒ‚ƒƒƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒƒƒƒ‰•˜–•˜Ÿ›žš™—ˆ†‡‡††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ„„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠˆ‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„ƒƒƒ…„‚…”“–™œœ•‰‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ‘’‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„„ƒ„ƒƒ‡•”˜†ƒ‚………ƒ„„……ƒ‚€€€€„ƒƒ„……„‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘’’ŽŽ‘‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€‚ƒ‚‚‚€†™ˆŒ†‚‚‚€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„„„„…„…†’“‘ŽŽŽŽ‰ˆ‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~€‚‚€„ƒ€€€€‚‰Ž€‚ƒƒ€€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“‘Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚‚ƒ„‚‚„„‚ƒ‰–ˆ„‚„‚‚Œ•‚‚‚„ƒ‚‚ƒƒ‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘Œ‡…ƒƒƒ‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒ€ƒ‚……„„ƒƒƒ‚„Ž™‹ƒ…„„„‚€‘™†‚‚‚„ƒƒ‚ƒ„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”“’’ŒŒŠ…„„ƒƒ‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~Œƒ~}|}ŒœŽ€‚‚‚„””Œ‚‚ƒ‚‚‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†””’”’Œˆƒ„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~–—‰€}}}}{˜Œ€ƒ€Ž”Œ‚‚‚‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“’Š†ƒ„ƒ„‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€•ŸŠ~~€}‡‹~„„ƒ„‚ƒƒ‚‰…Œ‚‚ƒ‚ƒ‚‚ƒƒƒ‚ƒƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†„…ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„‘¡ŠŒ…}†‰€~………„…‚}}}€ƒ„ƒƒ„ƒƒ„ƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„……………„…†…††…………………………††…†††…†††‡†…………ƒ„„„‡“““‘’ŒŠˆ…†……‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…ƒ‰‘ƒ„‹…‚~}‡†ƒ€~~ƒ„ƒ„„„„„„„„„„„„„………„…„†…………†††…†……†……‡†††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„„„‚‚‰~}~…~€€„„„…†††………††‡‡††…†……†‡‡‡ˆ†‡‡†††‡‡‡††‡‡†††…ƒƒ„……†„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘”“‘‘‹‰ˆ…†…ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒ„„„ƒ€€€„„~~€€€€€‰…†ˆˆˆ‡‡††ˆ‡ˆ‡ˆˆˆ††‡ˆ‰‰‰‰ˆ‡†‡‡‡‰ˆ†‡‡‡‡†‡…ƒƒ„…††………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†……„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡†…ƒƒ…„„ƒƒ€€Œ‰€‚‚€€~{{‚†‡‰ŠŠ‰‰‰ˆ‰‰‰‰Š‹Šˆˆˆ‰‰‹‹ŠŠˆ‡‡ˆˆˆ‡‡ˆˆ‡‡†‡†„ƒƒ…‡‡‡†……„„ƒ……„……†„„„………†…†…ƒ‰”’‘ŽŠ†…†…ƒ‚‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡†„„…„ƒƒ‚€€€„„‚‚‚‚‚‚‚€~}}}}~~|{{‹Œˆ‹Š‹Š‰ˆˆ‰‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰††††‡…†ˆˆˆˆ††‡„ƒ‚„‡ˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚ƒ‚„ƒ„ƒŽ“’‹‰……†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„……‚€ƒ„‚ƒ‚‚‚ƒ~}}~~~~~~}~}}—ˆŒŽ‡‡…†‡‡‡‡ˆ‡‡‰‡‡†ˆ‡†‰‰ƒƒ„ƒ…„„……†ˆˆ†…ƒ‚‚ƒ…‡†‡††„‚‚ƒ„‚ƒƒ„‚‚ƒƒ„ƒ„‘’ŽŽ‹‡„††„‚ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…‡ˆ‹Š†„†„‚††‚‚„„ƒƒƒƒ‚ƒ}|}€~~~}|}~|z„š“–Šƒƒ‚ƒ„†……ƒƒ…„„„„„„…„‚‚‚„„‚ƒƒ…†…„‚‚‚‚ƒƒ…„„„…„„†„ƒ„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰…„…„…‚ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€€€ƒƒƒƒƒ‚‚€}}€€}~~}|}}{zzˆƒ‚€‚‚~‚ƒ‚‚‚‚ƒ„€€€‚‚€€€€‚ƒ‚„ƒƒ…„ƒ„ƒ‚‚‚„ƒ……†‹“‘‹ˆ……ƒƒ„€‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€ƒ‚~~~~}‚ƒƒ‚ƒ‚ƒ‚~}~€€€~}}}}~}|z{{Š…‚€~€€~}€~€€€€€~}}€~~€€€€€€€‚€€‚ƒ€‚„ƒ†’ŽŠ‡‡†ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€ƒ„‚‚ƒ‚ƒ„…€€|}}~}}~€€}~}~€ƒƒƒ‚‚}}~€€€~}}}|{{{zzz{ƒ„ƒ~€~~}~€~€€€~}~~}|~€~~~€€€~€€~€~€…’’Ž‹‹‡‰…„„‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~~}~€€~€„ƒ‚€~}~~€€€~}}}|{{|zzzzy~–“ƒ€~~€€~€‚€|~~~~}|€~~~€~€€~~~~~~~}}}}…“’ŽŒ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒ‚‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚‚‚€ƒƒƒ€€~}}~~~~}}}}}|||{zzzyy‚‹„€€€€€€€‚‚€~€~~~~~€€€€€~€~~€}~~}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…‚ƒƒƒ…„„„„„ƒƒƒ„‚‚‚‚‚~}}}~~€}}}}}}}}}|zzyyyz€‚‚‚…ƒ‚ƒ€‚€‚ƒ‚ƒƒ‚€€€ƒ„‚€€€€€€‚‚€€€€€€~~||‰”Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…„„…„…†…†††…†…ƒƒƒ‚‚€}}}}}}~~}}}}}}|}}|{yyyyx}‚ƒ„…‚„ƒ‚‚ƒ…‡‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚‚ƒ„ƒ‚ƒ‚‚‚€€€€€~Ž“Œ‡ˆ†ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€~}}}~~~€ƒ„‡‡„†††…††‡‡†‡‡ˆ‡‡‡†}€€€‚~}}}}}}}}}}}}||~~~|{yxxyyy€ƒƒƒŒ„ƒ„„„——ƒƒ„}~‚‚ƒ†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ…„„…ƒƒƒƒ‚ƒƒ‚‚‚‚ƒƒ‚‚‘‹ˆˆ‡‰‡††„†…„„„ƒ‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€€~}~~€‚………‡†‡‡‡‡‡ˆ†‡‡‡‡†‡…~}}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yyy|~ˆ–ƒƒƒ„„”“€~~„‹€€€„†‰…„‚‚……‹ƒ‚……††„ƒ……ƒ„„ƒƒ„ƒ„„„ˆ’Œ‰ˆˆ‰‡‡‡…†…„„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„ƒ…„~}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|yzz{|~ƒ‚ƒ‚€~}{ˆ‘||Ž–}‚†Š…ƒƒ„ƒ‚ƒ‰~ƒ„……ƒ…†…„……ƒ„……†„„Ž‘ŒŠŠŒ‰ˆ‰‡………ƒ„ƒ‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚……„„……„†„ƒ„ƒ‚€‚€~}}||}}|||}||}|}}}|||{‹‘—Œz{|zyz{|yy}}€€|{{~~}‚•‘„ˆ}|~‚„||‚„ƒ‡ƒ}‚€‚‚€ƒƒ„„„„„‚„ƒ„…„‘‘Ž‹ŒŒŽŠ‰‰………ƒƒƒ‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚ƒ…ƒƒ…………ƒƒƒƒ‚‚ƒ‚ƒ‚‚€€~~}}}||||||||||||||}|||~~Š‚{z{zxz{{|}|~~~~~}}}|€}†~}‚~~€‚||€‚€€~|{Š‚}€~€€‚‚€€€€‹”Œ‹ŽŽˆˆ‡………„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ…„†‡…„€†”ˆ€‚€~~~€|||||||||||||}|||||}|yz{{xxy{{z|‚€€}~~}€‚‚€€€‚‘€€~€~~~€}}}{}}}|}||}€€€~€~~‚”’ŒŽŠ…††…„„…ƒ‚ƒ‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚‚„†‡††~ˆ•Š~€€€€~€~~~|{{|||||||||}}|{}|||{|||zzy{|z}…ƒƒ€~€~€~…‚~€~~€…†‚€~~ƒ†}|~€€~}}}}~{|}€}~Œ‘ŽŽ‡„††…„„ƒƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}€‚„††……~€€€~~}€€€€}}||}~}||}}}}}|~|}|{}||z{z|}}†…ƒ€€€}~}~~‹„‡~}||~‚}}}}|{}|~„ƒ€~~~~}|~€}~€~~„’ŒŒŠ†„…„„ƒƒƒƒ‚ƒ‚ƒ‚ƒ‚€€}|||}~{{}w~vx~}|}|}~~‚ƒz~~|~~€~~~€€€€~~~~~~}~~}|~}~}}}{|||{{z}~€€ƒƒ‚~|||}||ƒ~Œ~|{{}~}~~}{{{}|{{{{€†„‚„ƒ‚€~‚‚‚‚‚€‹Œ‹Šˆ„„„ƒƒƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€€€}€~~~~|‚}~}}}{{}}|z||}‚€€€}}}|||||}|~{~{{{|||}|{{{{||zz}z~‚~‚„„ƒ‚…†……††‡…„‘‹Š‹‡‡…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}{€~~€~~€‚€~~€€~}ƒ||}}|}}}}{|~~~~~~||}||}|}~{|{||||}|}|~|}|{{{|y{|{{}z}~~€€ƒ‡‰‰‰Š‰Š‰…ˆ’Œ‰Š‡……ƒ‚‚ƒ„„ƒ‚‚‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€€~~~}€€€€€ƒ‚€€€€€€€€~|z|}}~}}~~Œ†}}~{{ƒƒ}}}|}|}}}}}}|}|}|}}~|~}}}}|{{z|{||{z{{zzz{~~‚…ˆ‡ˆŠ‹‹‹‰Œ‘ŽŠ‰†…„‚‚‚‚ƒƒƒƒ‚‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„„€€€€‚~}~€~{~’Œ|}Š€Œ~~}}}~}}~}|||~}|}|}}}~}}~~|{{{||}|{z{{yzyyy{~ƒƒ„‡‰Šˆ‰ŽŽŒ‰‰…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{}||~~}}€€€€‚…ƒ„‚‚‚‚€€ƒ‚€}~€~|‰‚~ƒ‘„„ƒ~}|‡}}~}}|~~|}}|}}~~}~|}}{|}~||{|}zzyyyyz{~~€ƒ‡„ˆŽ‹Š‡…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{}}}}}zx‚€‚‚€€€€‚‚‚‚†…„‚‚‚€‚„~€}~~}~€€}~€„€~~}~}|Š…}~}~~€~}}||~~~}€}}}|}||{|}{{{zzz{{|}}}€ƒ€‰Ž‹Œˆ………„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv}€ƒ‚‚‚‚‚ƒƒƒ‚…†„ƒ€€€ƒ€„~~€}~€~}~~€€~€€}~~€~€~|}}|~~~~€}‚€|}€€}{}~}||{|}{{{|{|||}|ŠŠ‰‰††……„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€‚€€€ƒ€~~€}€}}~~€€‚€€€€€}€€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{}~|}|||{|{|~Š‡‡…†ˆ…„…„‚‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz~}yxtt€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚~~~~€}~€}}}~€€€€€€~~€€€€€~}}}~}~~}}„€~}}}~}~~}~|{|z|{z€ˆƒ„„…„„„…ƒ‚‚€€‚‚ƒ‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xyuu}‚ƒƒƒƒƒ…„…ƒƒƒ„ƒƒ„„ƒ€€€€~}}~~~~~€}}|}}~€€€€‚€€€ƒ‚€€~€~€€€~~~~~}~~……€ƒ~€~€~}{z{z|{z‚…€ƒ‚‚‚‚‚ƒ€€‚€€‚‚ƒ‚ƒ„ƒ„‚„‚‚‚‚€~€~}~~~~}~}}z{|…„{{sy{|pwuvwyutz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€€}}}~}~~}~|}}~€€€€€ƒ‚€~€€€€€€€‚‚‚€ƒ‚ƒ‚€€|z|z|{|‚€‚€‚‚€~‚‚ƒƒƒ‚„‚„‚‚€~€€}~~}}}~}}{{z€x|vyz|qtxwvxury……‚„„‚„……†„„‚„ƒƒ€€€€|}}~€}~~}|~~~€~€ƒ‚ƒ€€‚€€€€€€€‚ƒ€„€}ƒ„€€‚}z{{||}€}€|}}€€~}}~‚‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxzzruyyvwwsu†…ƒ…„‚„„…„„„ƒ‚ƒ€~~€~€}}}~€~€~~}|€|~€~€‚ƒ€€ƒ„‚€€‚€€€ƒƒ€ƒ€~‚ƒ„€€‚‚‚„‚~{{|||}~}~}z~}}x~|||~~~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„‚„„…ƒƒƒƒƒ€}~}}}€~~~}}€€~|~~~‚‚ƒ‡…~~€€€€€€€‚‚€€~€‚‚ƒƒ‚ƒƒ…ƒ}}}|{||yz{z}y{yx~{|{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst…„„†ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€}€€~€}~}~€€|€€~}~~€}€€ƒƒƒ~}~~€€€€‚€~~€‚‚€ƒ‚„„†„€~~||||zyvyyzyvyv~|{{{~}{}€~}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…„ƒƒƒƒƒ‚‚ƒ‚ƒ‚~~€}}}}~€€€|€€€€|€~~}~~‚‚~~}~~~~€}€€€~~~~~€‚‚‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{{{…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvpxyrx…………ƒ„„ƒ‚„‚‚€‚€~~~~€~}~|~€€€€€€|€~€€€€}€~~~}}~€€~~~~}}~~~|~€~~~‚~~€€~ƒ‚ƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}|{|z{}zzx{|zz{xtxuqrtpxxqy„………ƒ„ƒ‚ƒƒ‚‚‚€‚€€€€}~~€}|~|€€€€€€|€~€}~~}}|€€€€~~~~}|~~|}€~}~€‚~€€~‚„‚‚ƒ……‚‚~}|{{||yw{ywxwwx{{z{|…‰}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzz{zxswuqqsoxwq{…†……ƒ…‚ƒƒ‚‚€‚€€€€~~}|~~€‚€€}~€~€€}}|}€€€€~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{||{zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚€€€}}~€€‚‚}~~~€€‚€€~|~|€€€€€~}~~€€‚€€€€€€€„‚‚€~|}~~z}…~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚€€€€€€~}€€‚‚‚€~€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€€‚€€~}~{“z|}|{}y{zzxzxy{||}|||||||}}}||}|~}~~~}|z||{|}{yzzzyytuuooqpwst}…†ƒƒ‚ƒ‚€€‚ƒ‚€‚‚€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€€‚‚€€€}~~|†‰||~{{~yz{z{wwy{|{}||||{}|}}}}|}|~~~~|z|}{|}{yz{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚€‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€€‚‚‚€€€€€€}~€}€ƒ‚{~~{|}{z||{‡zxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ‚„„€~‚€€€€‚~€€‚€€€€€€€~}€~€€€€€€€€€€€€€€€€~}~}~~{}|}{||wxuxxy{||}|||||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒ„ƒƒ‚‚‚ƒ€€‚„ƒƒ„ƒ‚‚‚€€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€€€€€€€€€€€€€€€€€€€€€€€€‚ƒ‚‚€‚‚€€€‡~~|{}|{}xwvyyz||||}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚‚„„€€ƒ†ƒƒƒ‚„€„ƒ‚‚€€‚‚„‚„‚€€ƒ‚€€€ƒ€€ƒ‚~‚€€~€€€€€€€‚‚‚ƒ‚‚ƒƒƒ‚€€„}}}|}z}{zvzxy{{|}}{|}}}}~€€€€€€ƒƒ€|~~~}yy{zzzysrtowqwysw{…‚‚‚‚ƒ„‚ƒ„ƒ€€ƒƒ†ƒƒƒ‚‚„„ƒƒ€€‚ƒ‚‚‚~€€€‚‚‚‚€€€€‚‚„€~ƒ€ƒ‚€€‚ƒ‚€‚ƒ‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ‚€‚€}€|z|{{w|yyy{z}~}||||}~~€€€€„„€}€~{{{z{ztpxqytvxtv{„‚ƒ‚ƒƒ„‚„ƒƒ‚‚„†„‚ƒƒƒ„„ƒ€ƒ€ƒ‚‚‚‚‚€‚€€€‚‚‚‚‚€ƒ‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚‚„ƒƒ„€‚„‚ƒ‚‚‚‚ƒƒ„ƒ„„„„„…ƒ„‚ƒ‚ƒ€€~||€}|x|yzyz|}|{||}}}||€€€€€‚€€€€€{{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„‚ƒ………ƒƒ‚ƒ„‚„…‚‚‚ƒƒ‚‚€€~€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€ƒ‚€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒƒƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€€{}~|y|zzz}||}z||}}|z{~~~€€€€€€€‚€€}}||}|vrvxxvtvu}‡‡ƒ‚„…ƒƒ„…„‚„†„„ƒ‚ƒ„„„…ƒ‚‚‚ƒƒƒ‚€‚€}€€‚ƒ‚‚‚‚„‚€‚‚ƒƒ‚‚€€ƒ‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz|}€}||z|~}|}}~~€€€€~~€€€€~|}~~~}||xvvw„‡ƒ‚ƒ†ƒƒ„†„‚…†…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„ƒ‚‚ƒƒ‚ƒ‚‚ƒ‚‚ƒ„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒƒ„„„„„…„ƒƒ„…„…„ƒ‚€}‚€}||{||€}}~€~~}~|||}}~~~€}}~€~~}~}~}}~~€|}€‚‚ƒƒ†ƒ„ƒ†„‚ˆ†…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~‚ƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒƒ‚‚ƒƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒƒ‚ƒƒƒ„ƒƒƒ„„ƒ„„…„„„…………„ƒƒƒ~„€}}||||~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒƒ…ƒ„ƒ…~‚Š‹……„ƒ‚„…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ„ƒƒ„…„……‡‡†‡…„„…„ƒ~~|~~}€~||~|z|}}}}}~~~€}}|€€~~~~~‚€……„ƒ„„‚„ƒ†€‚„…‹‰„„„„……‚‡††„„„„…„„„„ƒ„ƒ‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ„€}uyƒ~„„‚ƒ‚ƒƒ„ƒ„„…ƒ„…†„…†}„y|~ƒ{…ƒ„ƒ€}~~~ƒ}{}~€~}|||}}}}|}}~€‚}}|€€€€‚ƒƒ‚‚†„„„…„ƒ„…ƒ„…„Šˆ………ƒ……„†††ƒ„„………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†spurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚……‚hzrss|€r‚„~ƒƒ}}~~‚ƒ‚|}€}}||||}|||~}~}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ…„†ˆ††…ƒ†††‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}p{pyv~ƒ‚nypus|vyy†r„ƒpvxqvtturstvi€nrotvnulwmzsn€‡ym}rsvsvmnwlpylu}~|~€}€}€€}}|||}|}~}€€€~|~€€€€€€€€‚ƒ‚‚„…‡††€‚…ƒƒ…‡†ƒ………†‡‡„ƒ††ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoolw}x†pqzprtfu~n{ysoy€}~€{~|€~€€~~€€€~~~€~}€}€€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„………††ˆ„„†‡ˆˆ†‡„††‹Š…„†‡‡…ƒ…„…„‚…………†……†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„rioyxpkyszozwvvp€~~z~}|}~}€ƒƒ€‚ƒ„‚‚€}~~~€~~‚€€‚„‡†ƒƒ‡„„„…‡†…………‡†ˆ……†…‡‡…†„††‰ˆ…„‰‹ˆ…„……†…ƒ……„†††††…ƒx‹yrˆz{pp…„x…xyks~y{krƒ‡ƒz|mzyyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozks|nv‚~~}}{}{|}|~}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡……………‡‡ˆ†„†…‡††…„……„……†‰Š‡……†…††…††„†††††…†‡‡‡††ƒ†…†‡ˆ‡…‡††ƒ‡†……ƒ„…†…†„†„ƒ„„†„„ƒƒ„ƒ…„…„…„†ƒ…†……„„…‡†„„…†……}w…ƒ„„ƒ‚~~{|{~{||}}|~€}€~~~€~~~~}}}~|{|€~||‰†…„†††…††…………††‡ˆ†„†…‡………ƒ„…†…„††‡†…„†„…††††„‡†‡‡†…‡ˆˆˆˆ†…‡…††ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…ƒ‚……†……ƒ…„„„†„†…„……ƒ††…†…„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ}€{{|~{||}~~||~}€~}€~~€}}|€}~~~~||}~{|||{{~ˆ‡„„ˆ††…‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡…††……†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ……ˆ…†‡†‡†‡†‡…‡‡†‡……†‡…††…‚ƒ…††„„ƒ„„ƒ„†„†…………ƒ††…†…„†‡…„„……ƒ„‡†ƒ‚ƒ„ƒ„‚~€|{}~{|{~~}||~}~~}~}}~~|}||~~|}|||}|||~z{{|~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†„…„‡†„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆŠˆ…†ˆ…†‡…‡†‡†‡…ˆˆ‡‡…††‡…††„‚„„…†……„„„ƒ„…„†††…†„†…††……††…„ƒ„„ƒ„‡ƒ„‚„…ƒ€€{{~}|||~}|||}~|}|~}|}}||||}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††„…†…†††…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡„†††‡‡‡…‡†ˆˆ‡‡…‡‡‡…†‡„‚„ƒ„†…‡…„„„„„…†††††…‡……‡…†…†…„ƒ„ƒƒ„‡ƒ€‚ƒ„‚‚‚€{}}|||~}|}}|}{||{||}}{{{}|{~}{|}}|}}~}|zz{{||ˆ‡‚†‡††‡††…„…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡ˆˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡…‡‡††‡‡…‡†ˆˆ‡†…‡†ˆ††‡„ƒ„„ƒ††‡……„„„…†††††…†‡††ˆ††„†…ƒƒƒƒ‚ƒ†ƒ~‚‚ƒ€ƒ‚|~||}}|}}|~{{{z{|||{{{~{{}{z{~||||}~}{z|z||‰‡ƒ†…†…††……„……………„ƒ„†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…‰Š‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……ˆƒ„†…ƒ††‡†…„ƒ……†††††…††‡†‡‡…ƒ……ƒ‚‚ƒ…‚ƒ~‚„‚~~~||}}{}}|~zz{y{|}{{{{~||||z{}||||~}|{{{{||‰‡„†„†„††…„…†…„„ƒ„‚€ƒ†ƒ‚z„Œ{€„…‡†††„„‡ˆ‡†‡……‡‰‡„‡…††ˆ†…‡„†‡ˆ††ˆ‡‡‡†‡ˆ†„†††‡……ˆƒ„…„†††‡……„ƒ……††‡††…†††…††„ƒ„…‚‚€„ƒ‚‚}~ƒ~€||}}~}{~}|}yzzy{|}zz{{}|}||zz}||}|~~€{{{|~}|ˆ‡…†…‡„†„……………ƒƒƒ€‚…‚€}|{„…††„…„„‡‡†††…„†‰†‚†„†††……‡…‡ˆˆ†…ˆ‡‰‡††‡…„†……‡…„‡ƒ„…„ˆ††‡……„‚……†…††‡„…††……†‚ƒƒ…€€€€ƒ€ƒ€|€~~‚€}€}€|}~}~{~}|{yzzyz}}yzz{|{|{{z{}}|}|~~|{{}~}|ˆ†…†††„……„……„ƒ‚€‚€€€ƒ~~~€yz}€ƒ„…‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………†‡†ˆˆ†…ˆ‡‰‡†………ƒ†„…‡ƒƒ†„„…„‡†…†…†„‚……†††††„…††„……‚‚ƒ„~€€€€ƒ€|}~‚~~€~€}}~}{}{zyzzyz|}yzz{{z|{{{{|}}}|~}|||~|{‡……††††„…„…ƒ…‚€€€€~‚‚}}{‚ƒƒ…†…„ƒƒ†ƒƒ„‚€…‡…‚ƒƒ„„…††‡‡‡……ˆ†‰‡…„„„‚…ƒ„†‚ƒ†„„†„‡††……†ƒ„…„…†…†„„…„…ƒ…„€€‚ƒ~€ƒ|€}}‚}€~~~~~}}{|{zyzzyz{|yzz{{{|z{{{|}}}}€}}||}€}|†ƒ††…††ƒ„ƒ†‚…€€€~|~~€€‚‚‚„„ƒ‚‚„€ƒ‚€„…„‚€‚ƒ‚„……‡††„…‡…‡…†‚ƒ‚‚ƒ‚‚…ƒ…„…†„†††††…ƒ„„ƒ„………ƒ„ƒƒ„‚„„€‚‚}~~~~„~{||€}€}~ƒ}~~}}~{~{{zy{zyzz{yzzz{{|z||||~~}|}||}€~€†„……„‡„„ƒ‚†‚ƒ€€~~€}‚|}~~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚‚……‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡†……ƒƒƒƒ„……„ƒƒ‚„ƒƒ€€~}}~~|~ƒ~|~||~‚~‚|~}}|||{{zzzzy{yzzyzzz{|y{}{{~€}}}}€€€†„„…„…‚„‚‚„‚‚€€~}~~~~€}}€~~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„…ƒ‚ƒ……‚„ƒ€€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚€…ƒ~€~||~}|~ƒ}{~|}€€ƒ}}€~}|||}{{zyzyy{yzzyzz{{{z{}||‚€~€€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌÌÌËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFK=8765999<>9?<C9;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;>BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937676=;>:=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHKA=78476::?;D<<:<<98:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA>;A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÔÒÓÔÔÔÔÔÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9>CE?<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMOH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËÊÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø×××××ØÙØØØØØØØØÙÙÙÙÛÜÜÜÜÜÜÜÝÜÛÛÛÜÚÓÒÓÓÓÓÓÔÔÔÔÔÔÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILN@99:4;@<7=9AC=@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÏÐÏÏÏÏÏÏÏÏÏÏÏÏÖÞÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¸·©§§§§§§§§§§§§©—€‚‚‚‚‚‚‚€ÒÒÒÒÒÒÒÓÓÓÒÓÓÓÜãâââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑrliNSbLLVM<::77>C?8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKPFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÌÐÒÒÒÒÒÒÒÒÒÒÒÒÑÞìëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§££££££££££££ †„„„„„„„„„„„„ˆg@DDDDDDCCCDC?\ÓÓÒÒÒÒÒÒÒÒÒÒÒÑàìëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘wliJN_MRUM><<7;?C>6:7>?;=B@8<:=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÌÌÑÒÒÒÒÒÒÒÒÒÒÒÒÑÝêééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤¥¢‰‡‡‡‡‡‡‡‡‡‡‡‡ŠjFIIIIIIIHHHHC`ÒÓÒÒÒÒÒÒÒÒÒÒÒÑßëêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;?@@8:;8<<<<>::;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÍÐÒÒÒÒÒÒÒÒÑÑÑÑÐÜèççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©©§ŽŽŽŽŽsQTTTTTTTTTTUQjÒÓÒÒÒÒÒÒÒÒÒÒÒÒßéééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB>;=:9;:=<;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÎÎÎÎÎÎÎÎÍÍÍÍÍÍÎÏÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÎÎÎÎÎÎÎÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÒÐÐÐÐÐÏÏÏÏÏÏÏÏÏÍÊÊÊÊÊÊÊËËÊËÌÌÌÓÔÔÕÕÕÕÕÕÖÕÖÖÖØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<7@A<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÎÑÔÏÏÎÑÒÎÏÒÔÕÔÐÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÕÕÕÕÕÖ×××××××××××ØØ×ÖÖÖÖÖ×××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?89:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÎÓ»ÏÏÓ¸žÏќ‚„ŠÆÏÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<=B>BB@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÎÒµ•›³Õ²—™¹º•¸¹¯¡ÒÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?><7:>9?D>@98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÏџ ª®Ôœ£¨²Ñ’}~¯°ÑÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<<96?B?B:647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÏÑҚ±ÕƚµÕÓ͞žÃÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8E@?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÏÏÖ§™±ÔÖ£˜´ÔÓÀ  ÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<==964:99::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÏÏÔ¤™±ÔÕ¢™´ÔÕ°¢©ÔÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:<?>=<9@<<::9?@==<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÐÐÔ¤™²ÕÕ¢™µÔÔ£¡ºÔÑÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CGDAA8;?<=;<<7558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÐÐÕ¤š³ÕÕ¢š¶Ô͞ŸÉÒÑÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ђl]\oghb]OF?HHFE@<<>><==<7569969;::;8@?:<<9<>=;;:?9?:;9=>=><;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦ÓÐÕ¤š³ÕÖ£š¶×ß ÒÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;557<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡ÇÒÖ£›±Ö×¢›´Ú²¤¦ÖÒÒÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKL@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÓÑÕµ‚ÃÓÕ±ƒÆÖ¹ƒ¿ÕÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<<?GEGKI=667:979:;:<=9>99:8;=>>A>=9<<:=>>;=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÑÑÃÔÒÒÐÃÕÑÑÂÓÒÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??>>AELLA>775;8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÒÒÔÒÒÒÒÕÓÓÓÕÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEK>>786977899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9699:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:69896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EIKAALD??;9889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEHIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDI;AA;<886586987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGJB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<AA<;876797799=?A?<:9@?<>B?:8776=?@@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE><HF89757875898;>>=;89A>=@?A>7596;>AB??@@AB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCDEC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<;979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELBA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:9;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<<DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGHNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAD?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€iixsg~‰‰xp‚†{w}~…Š¼ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€‚wt|„‚}sp€Šx‚yƒÈÞÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsnupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿½¾¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ººººººººº¹ºººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»º¹¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjcmgb\XQPQKTJB:IQ?A7<94:565455688686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸¸·······¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µ¶¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸···¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶···¸·¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨¨¨¨§¨¨©ª§¥¤£¢¢¢£¢ ¢¢¡¡¡  ¡¡¢£¤££¥¥¦¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸·¶······¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥¤¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¦¥¥§¦¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©«««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤¤£¢¢£¢¡ŸŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99>7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž¤¤¡ŸžŸ  œœœœššš››œœ›››œžžŸ    Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89>6789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥£¢¡¡¡¡¢£¥§¦¦§¬«§¦ œ›¡¡ž››šœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¦¦§§§§Ÿ›š›¢ š–—•š›š——˜™šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜˜™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿœ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥£¢¥¦¦¦¦§¦¦ ›™›¡ —’“’—šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB?DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥§§¦¦¢žœŸ¡Ÿ—‘”—›˜–—–˜›™ššššš™—˜š›¡¡ŸžŸœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡  Ÿ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:766846789=88;:;?;:;<:9:7768;<;=<::<=<7;>CBDC?=AC@DA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¦¦¥¤¦§¦¥¥¦¦¥¥£  ¡¡ ™’Ž–›™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›˜•••—šŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡¡¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?B@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢£¢£¤¤¦¦¥¤¤£¢¡¡žœ›”™ªœ›š›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œŸ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸžŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::78:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸŸ  ¡¢¢£¤¤¤¤¢¡¡ž›š™š­ªž™™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢Ÿ›ž¡¢£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ ¡¢¤£¢£¤¢­§W^]TW_nkšš›œ››œŸžœœœœŸ   ¡¡¡  ¡ ¢°§¡¢¢¢ žœ›››š®yz››œ™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥¤¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¢¢¢¡ ¤¥­§Ÿ  žœ™™š™¦“Kž›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›š›šš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>99;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤¤¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ ŸžŸ ¡ Ÿ£¢yª¤  ž›šš›¨ZI„Ÿžžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢¤¤¢ žžœ›šš››š˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9<<>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœœœžž¨mo«¢Ÿœššœœ¬‚KO‡Ÿžžœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:<>9?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››››œš¤ˆT„¨›š™›œžªdTQˆ œ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš››œšš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\Q<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™™™ “bb›˜››¢–f]Q‡¡œ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›œš™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š›››œœœ™˜™œ™ec}œ˜›œ¤‡g\Q‚¢žœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\LF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ››››››œ™™™š¤hgfˆ—œœžœyfZTƒ¢žŸžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ›››››œš˜™˜Ÿnebl†ŸocVW‡¡Ÿ Ÿžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_^]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜˜——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜™™Ÿysr^x™œ¡ŽaYSZŽ›žœœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±´­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=:F??:7;;;6397:9>8::<=998;9;<:>=;@@;<B<@:847<;B@AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œš››œ›˜™š˜˜™›šš–’›Ÿ”yš¨¡ª”|bR`’Ž’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨ª¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‘‹‘‹Œ‘‘Ž ŸŽ}b‰©˜šnƒ‡kpˆ‡‚‹†‰Š‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜ž—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VQQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹Œ†Š‹‹‰‡„†ƒŒ¨xiRpŒVmy{‚~‚’†„„…ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹Ž‹‰‰…‚‚~~ zOCIv”ƒƒIWosw‚{†Ž‹†”‘‹—”—’˜¡–ž–•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¦›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ‚†‹‡ˆ…„ˆˆŠ…€€ ”S44;y…urC8Nko€‡ŠŽ‹™œ””” ššŸ¢­±®©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPEMISWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}€~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‘‹ˆŒ‹‹‡‘¡nFdU?zzgdL<9MnuŠ‰””˜•œšž¨®²°°µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWMO_^\NUUbQDTM;?9<895875795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš™ž¡“—›¡š›¢¤˜Qt°‘H{‡xmRiYWqˆŒ˜šŒ”š—œ› ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUJTOOJDPK_bXZQ\T`MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ªª©§¢¥¨©«©©¬„_¿Ø¬F’£š]k‚{^^ƒ¢¡¤ž›š¤§¤©«®¬¥¤¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdWOYKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®««¬¤¡¢¦©§¨¦oz½ÀªšÌ¨ž³šHV„pRxŸ©§ ¢¡®¬«ª§­®¨¥¤©©ª©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_VZNRNQOSe\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢™œ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨§¦¨©§©©¤¨§š¤¥£¢¢r™®ŽÉ➰²nS¾ Tl”£¢ ¡Ÿ¡¡¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOXO^edlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤ ¢ £§¡¦®¦¦œ }…{†Ð½˜—¨œrRš¬gcŽ£  ž £š–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvxb_\UYQUW[c_s_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?B?:8:>?C@DA:;>=@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯««¬¨¨«¯©¨ª©¢ ¢¨ª®±²®«¤©˜ˆ{j½Ã«®ž‰vdpxzv‡£¤§£¡ ¢™•ž›ŸŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸŸ¡¦¢›—’šš •|wo}yf[[`_Z\U\hdocmiib^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¡ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£ £ªª§¯·¶´³¶²°²§‰u^N–Ÿ€{spsqx|~…’¡¤£¢¤›¡š–ž¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¡™˜¥ ¤§ª©¨ª­¬¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxjb[__\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>BE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢ «²¶»¾¿À¿Å¿µ«“pfXGw€suzqnihbbiiovwx}ƒ˜£¨¬¦¤™¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨¨«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥¡¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxxxc[RYT__amhvkqhiibZSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶´º±ª®´±°²´µºÈÒÙÜÕǺ­Ÿx\[OE^kejphdbgYW]Y^fnnmmln¨ÈÆ»¢§ª¬§«©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš’–””˜“š˜Š‹‡€€|‚xa^YSai`ftotitdidb[LK>:9898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÄÇÃÄÅÙâßϽ°¨œxbUWME^lacjeabi]U\WYZ^ca\c€©ÅÀ½¸©¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`b_^kcbnxuwnm[bRV\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAA;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–••‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±°§¼¼¾ÅÄÆÉÇÅƼÇÇÎÐÄ«{o\STVK@^lefneb^faUXZXVWWbƒ¥¶»¹«´²­³­©®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|„jfhaklgnurruqg^`\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÄ¿ÄÂÆÉÉÀ¤ˆZLHJNH>Z`blqha_e\XUSTQV€¶Ã¯¬ªªª­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|uklndomiqxoyjia]gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÇÆÄÄø³Áº wLJQI=MTbjinc__Z\USZš­·´«®¥¤£§¤  ¥™ª´±¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆŒ–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyz{wnkihvZfrxszgg^d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÊÆÄÃÄÂŽ»¾‘eVKBJ=^VXkg[ZYXVp°±«¸µ³¬©£¡­©¬§­ ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyvuefijh^jonyxcba`^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÎÏÌÃÇÆÈÉÈÈÉÇÅÉÇÈÈ¿Æƶ lKYARr{€ZRPSkŸ¾Àº½»¼º¼¬­¦©»º¹·À³µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqocagvijjtnyl^d[U`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÌÐÍÇÌÉÂÂÇÂËËÈÇÌÉÍÅÅÅÄÉÀªxoŒ™SOqŸÂÒÇÄÁÄÇÁ¼¾´±°°Â¾¾ÁÆÀ¿¸¶Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r}xpg`kjwlifuotc]cUWUSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<9>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÄÇÈÆÒÉÁÃÿ¿¾ÄËÈÊËɼ¼ÈÇÉÍÈÃÈÉÉÅÅÁÁÀÂμsj…™—Z‘ËËÍÏŶ¿¿ÀÀº»½µ³³À¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzy€spfefckdbkmoo_Y]WVNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾƹ»Ãº¸¹¼¾ÁÇÁÆ»¹ÈÈÃÅÄÀÃÁÁÀÄÁ½¼ÂÁ™€Ž™ˆÒËÄÈÑÁ¯½½¸¹»»¾·´°¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfaebaccdjcgc[ZZ]YQOE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶·´´µ¿»½¿¹¾ºº´À¸µ·²®º»·À·¼ÊÏÀ»¿À¼»Ä½ºÀÄ¿½½¶¾È¤”fÍÄ¿ÀÉ¿°Á¿º·»¾¹µ¸´¸¼´½¸µ´°³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|yˆ}qdabchjggjej^VVTYOSLF8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“““˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´´±°µ·µ»Á¸¾¹¿¼¼·´·¯®·µ¹¿»ÁՍº¿»ÃµºÇ·¶¹»¼¸¹µºÄɦB‹É¿¿»Á¾¹Æ½Â¿¼Å¸¶·´¸¶¶»»¸¶´·ºµ³¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒyqmeefpjelhXYOKKKRJLHD9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’™”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿¾¼²­¯¬±°·¼·»½ÁĹ··¶µ¹¹º»¿¼ÏÄx©Ì½Ç·¹¸­¶´·¹³µ²ºÅʚF€Ê¿¿¾½¼¿ÈÃÅžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~†|knqgqktfbn`\THKKDJCCG?:;8><7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘Ž˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼»À·ª­¤®°¸»²½¾»Ä¶µ¸µ·¿¾Ä¼ÂÄ×®t»ÈÏÂÀ¸®µµ»½·¹±¾ÃǎL{Íÿ¾½¼ÇÌÇÇÄǽµµ¶Á½»»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†€rfljnuoxchb\cQKUHEECGC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?>??FD@A?>:7?@CC?@=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼ªª£°¹½¼²¼¾¼Å¸±¸¹¼ÆÉÊÂÇÉҙqt®ÑÑÌÊĵº¿ÄȾ¾´¾ÀÀ{YsËƾÁ¼¿ÃÌÊÇÅÆÀ¹½¼Ä¿¿¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtolltlln_c_abNHN?E@?DC;;::;:8;<:9<>::>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´»Åк¾¼Ä¾·¼À¿ÉÏÇÈÊÊÁ†rt¦ÌÌËÍÊÆÂÃËÎÁ¼¸¼º±rif»ÈÄÀÀ¿ÄÀÊÉÃÃÄùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{zˆ{mmx|`qc[_`_TI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA??ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸´¼·»»«Úþ¶¾À¾¾º¦œ©²¶ÃÀ¥yvyœÄÆËÈÁÃÀÀÉÊÁ¿»¹±¡xq®ÈÅÄ¿ÀÁ¿ËÇÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³µ¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}znsxthp^\_]ZRFEDMIAD=H;;59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘—žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯··²µ³·¹¼»¶»»Ä·m­Î½¶¹À½«}nhnmr•˜sx}˜½¿ÆÀ¹À¼¾ÅĽ½¸±¯œ•ƒˆœÊÂü½¿¿Ãþ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸··½¹»±¶²ÈÀ»¶´±±·¬³©°­­´·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|wmu{qoj\``ZSPAFIGK@ECI<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿ››œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹ÀͲv³½¶µÂ¥‡iZ^`MR[[ntw‚¡¸¸Âº³»·»½¿º»»®£žŽ™¿Äþ¼¿»»¸¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ°µ´´½º¾ºº»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰{‚zsvvwoqa_f][UJ=??GG=GCC9:5;99><<9:<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Âɧ…xŠ ¯µjfgVY`IIMPTlw‡¦°·¾¹²µ²¼¹¼¶¹¾µ• «¨t®ÉÄÀ½¿¹³®²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtwrl_ca\^OIB?=IDFMD@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•›•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·¿Åªˆ|vŒ¡˜`TCXUGajVOEJaŽ¡¬¯¶ºµ´²¬¼¹¸µ¸Á½‹š³¦ªt¦Ë¿¹ºµ®¥¬³±¦°­¨ Ÿ¥­¶µÂ·¶´¥¨ª¨°¶³²ºµ»»»µ¸¶°¶Ä²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´¶¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wp|ovsnc^gY]]SONA?JCAJJ@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜š‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³²­¶º¯­¼³¸¸¿´‚yˆoOJ?dYBNw€”jNA\‚°µ³µ²´¯¬»º¸¶¹¿Æv„¬ œe©¿¸µ²±­­Ÿ¤¦§¤¥œ–™™™Ÿ©®¹¬««Ÿ¥¨¤«®¯§°«¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrwsmujl]\kU^\PNHDGMBGNF8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹º¶¹»µµ³·¶•Œˆ„|XFAO‡YJJXwcAS£¹³´²°±­°¹¸¶»·»¼¢±«¤s¬°©«­«£¨¡ž—— •’–—˜Ÿ¨®¤£¤ ¢¦¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬ª¯£¤£¡© ›“Ž”’’™–š¤¥ Ÿž§˜•’”™ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wryhutneUadW]ROMI@ISENC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯²¼©˜™”hM?RxqPIIKgœ€ZES¯»±¬³¯®¬­¶¶²´µ®©¦žš›Ÿ¦¨ž ¨©Ÿ¡§–›–—Ž“–—›¤¨  ¢¢¡¥¥œ££ ž¥ ¤¬¥¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›ª¨««Ÿ¦¢›£œ•Œ“–•–˜Ÿžžš™¦—“’–¢ ¥¢¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦¡ˆxƒ|vzcwmn]QiUPOGPMMCPR@>;>49:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¤¬¨½Âª¥½hDR‚QWIJ`JUadc®µª²´®ª«¯°²³­¥‘—“— Ÿ¢ œ£¤Ÿž¨”›––Œ—‘—“˜£ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨¨œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£žžžš—š«¦ª±£¥¨ž œ•“‘‘™–•˜—Ÿ˜œ™›¤™—”•š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’~|uv}nl{diVRdNJHGOSNKNH<E@<2@859;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜——–¡¨¬®¶·º¹º··»®¨ ¡© ªÆ¿Ê PAsvOmJKcfts`[`q±¯®³µª¦¬¬£›™”‘•–˜˜œŸ¢¢œ¤žš¤———–’‘’“š—› ¤ªž¡¡ž¦§«¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¢¥¢š™ž¯¨®²«¦«ª ›˜˜˜•“–š“••š–›——˜¡žœœ–›¡›žš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}wy|eyz`bSUaHIJKSTJSQM9?A67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—“’œž¤¨®­¬««¯ª¯©ž—ž¥œ¤ÆƌWSJe¤Ze}or\Qkc[e`^k´°°¸¬¦¡œš”—š™Ž‘•‘ŒŽ“™¢œ—£™š—˜™”™˜–›Ÿ¥¦© ¦¤ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§¡ £±®²±´ª²®£™œž¡˜››š—™›”–›–™œ¥¡ š£¡š™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ ž ž ¥¡žž¥ ¦™{|vvsi‚lf\SZZMQKOOVMSMB7>C78=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’‘œ˜¡ª¢§ ž§¡¥Ÿœ’›¢šŸª£ŒyUiqvupcvvXXc`chZYWg­®¬¯§Ÿž¢ –“› ›™—’“Ÿœ¡£›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­©¬©¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½¶¾°¬±®­©ª´±°¨«¨³¶¸³¸­²´¤ ¥ ¬¡¡¢¡ š˜–•Ÿ››˜¥¡ ž£¡ Ÿ›œ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚€}xvjxu^m[RaIRUHFUWJCMG=KI8E<77;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“Ÿ™¨®Ÿ§žœ¡žš™’˜ž›¡¡ £€o‚p`cXL[RZMLPXRHMMG˜¬ª©¥ Ÿš’‘”˜˜–––Œˆ‹Ž•œž—ž™¦Ÿ ¨¥±ª§®£«®¶°µ²±®¶¸½¿º­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«®±¹¸¼¯³°µÂ¼·¾³³µ¢¬¢©©²©«¨§¨š™žšª§ ™§ ŸŸ¨¨¥¤žª¢¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰……~vrmiwmin\X\CWNJGMHCFN=>L>4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜™ª ±¢·¤°¦Ÿž—˜•™ž›œ£žŠbW^e`WMQG=?@CC?>BQx©­©ª¦ŸžŸ¢£žš›”“•”žž˜”…š š«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶º»ÀĹ½»¬¯§±­±Â¶¸ÂÆÀÈÊÀÉ¿°¹¹½¹Â¾¸´»ÆĽü·³ª³­ª³´¯³®ª¯£¬¨¶±­£°¦¡£°±®°¤¥¯£¡ š¡¦¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¤ž¦š›¢¤žŸ›››œ‡†|trklurqhW\QFUHDJPI?EB4FH95<>7;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<<;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž  œœ˜šŸ š Ÿ•|_^e`QGE<C>F<>96N~ª³§££¢ ž¥«¦ž—œ”‘šž™•ŒŠ†ˆ†xmˆ ¤¢«¬´¼¶Ã½¾³»ÁÃÂÅÀ¿ÂÆÅÅÃÈÂÀÅÇÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌÌÌÒǾ¿ÀþÇÆ·ÃÊÉÃÁÇ¿º´º»µ»·°¶²ªº²®¼¸¿»º«¸­«ª¸»µ¼®®¸£¦£ž¦¥¢£©¦™›Ÿ™š§ª§ ¡¡¤˜”£–”™‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ…~zrkdioxkeZ\FLMEDTMECE7:?;549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;?>=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ²²¸§¡¡«ª¡œž¡¡›š}sjaWOE>IZ|obB=\Ž®¬ ™››žž™———’——”Œ‚ƒ‚wrqmp¦­®´¹Å»ÍÇ˾ÁÌÍÍÌÈÈÐÌÌÌÇÊÅÆÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÑÓÍÓÐÓÓÌÊÁÆÆÆÊÈÏÀÉÑÍÇÆÈƼÄÁ¾¿¿¶¾³­¿ÀÃÃÇÄÇį¿¹²¸½Äº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›‹™‰•˜› Ÿ£—žš““‹•…ytsebgrog^ZZDOMDEPIDCA55589B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A?<@?>9;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›¢¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¤¨¬­ª £žœ•jf]TIDA?K†ž¥™„ ²­£žœŸš˜—”’”–‘Œ‡„„ˆ†ƒ€€yqroly¤¶º¹¾ËÁÓÑÓÈÍÎÑÓÑÒÐÐÑÑÍÎÏÐÅÍÔÕØÑ×ÍÆÇÉÌÃÅÊÏÊÓ×Ñ×ÒÕÖÓÔÈÌÆÌÍÉÓÍÎÓÍÆÉÊÊÂÆÌÇÉÉƿó³ÈÅËËËÏÇÊ¿¾¿½ÁÇÅÌÌÉÉÀÃÀ®¯³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›–Œ†‘‹€{ruvgcgvjeVXRDNF@IQC>B=:22A<E<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<@?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­³·¬®£ž£¢¡œbTLJDC?CR¯Ñ½²¯¦œœœ ¤¡š”“•”‰}xqkebhrpr{…Š€upnqsp…³Ã¾ÅÑÐ×ÖÕÒÖÍÔÖÖÔÓÑÒÓÔÒÏÒÃÐÓÖØÕÕÒËÊÎÑËÆÍÒÊÒÕÖÙÖØÓÖØÍÒÊÏÑÌÏÑÌÓÐÀÉÈËÄÌÍÌÏÏÅÇȶÀËÀÒÍÌÐÆÊÉÀÄÃÈÎÍÐÑÏÍÊÈ͸·»¨Ÿ¥«§Ÿ˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„}xsvpc`erc]R\JKGAEIJ>;A8>5586;86:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÁűµ¨¡¤¥ ¢¡ZI@ADAFQv²¯¦š”—Ÿœš  ž›œš•‰wica____^__]alusppolqqu’ÄÈÇÔÖ××ÖÓÖÐÕÔÙÔÔÎÏÕÔÔÑÑÌÑÍÓ×ÖÓÕÐÏÒÓÑÉÓÑÈÐØ×ØÑØÒ×ÙÔÖÌÏÏÉÍÒËÎÑÀÆÄÉÇÏÎÑÑÒÈÌÍÀËÍÆÔÏÌÏÈÄËÇÇÈÌËÔÔÑÕÏÒÌÓ¹ű¥¨µ®§›¨«¥²¨°³­¬““Žˆ‹Žƒ‹„Ž™“™‚…Œ|zqstmbcim_VQ`JJCECRM@<>43:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><?@=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯­ªª«¥®·¨«·ØÔÕÙÙÑÎп¼Ìɶ¾®¦ª¨¡£¬fC8=>DX‚ª¨Ÿ—•—™šœŸ˜œœ’}qecb__a_^a`_``_`emppnkorvwœÌÁÓÕÓØØÖÙÑÒÒ×ÏÓÎËÒÍÕÔÑÊÏÌÓÖÒÑÕÍÏÕÕÑÅÑÔÊÐÔÕÖÎÓÑØ×××ËÈÎÄÉÏÌÊÌÀÉÁÉÊÎÎÏËÐÎÎÌÏÏÈÌÐÐËÎËÃÊÇÉÍËÌÒÓÎÔÒÑÐÐʽȹ°®»¹µ«¶°­¨¸­³¾»±šŽ ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…‰zvopokadnpaX\[JFFDMXE;@=33<<87855;>@=9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6==?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ£§Ÿ¸¶µµ¬¤¬®¾´°ÀØÒ×ÚÜÖÎÍÊÃÒÏÁÁ±©¬­©¤±zHFB;W¡›•“–›žžžœ“–—”ˆk^^^adb``aa```^`_^\bmroostuvy¤¿ÌÕÑÖÓÓØÖÎÎÓËÎÎÅÎÊÒÒÏÇÎÍÍÔËÎÒÍË×ÖÐÌÑÔËËÐÒÓÊÎÑÕÒÕÕÊÀÊÁÆÍÂÉÊÃÍÄÆÉËËÏÊÎÍÐÎÔÌÆÉÐÍÉÇËÅÇÂÆÊÌÍÐÒÇÐÏÎÎÌÐÅÇÁ¸¹½Ãýù³²¾±»ÃĶª˜¥¡˜–’••’‹”š‘””•‚‰†yqrkmh``qhYXhVMGLIPQB;D?;68:8:;57==@;:<=9<=9==:>:<7;=9;@<>;>>A<9=>=B=;776?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÄÂÁ¿»µ²±Ç¸ÊÕÖÙÚÛØÌÌÏÈÖÕĵ¯´¨ ­—xlopwšŒ—•“‘‘•–•‹{ebbb`]^acb`_``aa__][]grrprspmry¥ÇÓÎÌÐÏÓÔÉÄÈÈÅÆ¿ÃÅÏÎÇÅÇÍÊÑÈËÎÍÆÑÒÐÎÌÔÊÇÊÎÏÇÇÏÒËÐÏźĿÆʽÃÈÊÎÅÃÇÀÇÍÈÄÌÊÌÏÈÄÄÐÉÆÂÆÉÅ¿ÁÇÌËÌÏÂËÌÉÇËÐÅÅÇ»ÇÃÉÉÂÏÁ½¼¿°ÁÉǺ½ª±²§¥¢œ˜›£™—™‘•˜‰‚xoudk`^fqa[W`GHHGIMTG?J=64355==48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ¼¹ÌÌÆÐÕÕØÚÛØÐÉÏÏÑÓÈ·»»­¤¶~g‚…¢ª“–…ƒƒƒ}„„~s`[^]^`^`cdc_]]^_``_[Z\`lrqnokloo}¹ÑËÂÂÏËÍĺ¿Ãº»º¹¾ÈÆÂÃÀÃÈÊÉÈÊÈÁÅÌÆÈÊÍÉÄÁÊÉÁÁËÐÅËÈ¿¹Á¼ÆǾÀÆÏËÄÀûÉÇɼÉÇÅÊÁ¾ÂËÆÅľƽ½ÁÃÅÌÅƼÀÉÃÅÇÒÄÁÉ¿ÊÊÆÈÆÑÃÃÆîÄËÇÃÊ·¿¼º´©¬¤¥˜Ÿ˜¬£¡¦›£ ›•|wsufj[anmZ\XRDLGBGELDFS@54335@=3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ÊÏÑÌÇÂÃÆÍÎÎÌÕÏÕÙØÙÏËÒÍÍÎÈÁµÃ¾²°¶l^y|Ÿ‘Š’–†z€……uxurp_[[]``bddded`\\^]^^`[YZ\bornkikposÈ»˜ÀÌÀÆÁ°¶¹±±³±°Á»»¼º¸ÁÁÁľ½¹½¿¹ÄÊÅƽÆÀ·»ÃÉ¿ÁÉ»¶»ºÆÿ¼ÂÎÃƾ¾µÁ½Ã»½Ç¼Ãº´½ÆÄÂ÷À¶¶¾¿»Ìý¶ºÈ»¿¾ËÃÁÆÃÆÉÇÉÆÐÆÂÌDzÇÉÃÎÍÁÅÿ½²·°²§¨¨¹°¥­°ª­¬”zwxkeh`hodV^YJFJFHKAFBFJA9:658853;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÅÂÄÈÎÒÊÊÊÇÍÍÎÑÈÐÆÕÔÕ×ÍÊÎÅÉÅÇÁºÅ½¬®¦`cu’‹ˆ‹„x††}ƒ{ttc\\]^``bcbbdeb]\[\^\^]Z[\^hsqmggnory›ŽŸÄúÀ¸­°°¦©­«¥·³µ´³³´»¶½²·°´®²»Â¼Áļ¿º´²º¾À¸È¸´¼¶Á½¸½ÇÁÄ»µ¯²µº¿´Å¸»µ¬¹½¾À½±»¶°·º³Æ¼·¯»¿µ·µÅ¼¿ÃÆÀÄÅÆÇÌÅÀÆÆ»ÇËÀÏÉÇÃÆÁ÷ý½¶¹¾Ç¿¬µ»µ·¶Žytxggebkn^V^`FKHHJFBDAEF?=:566633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÍÈÅÈÍÌÐËÍÈÉÈÊÉÊÄÐÍÒÏÍÅÇÁÅÁ¿º¸É·«°™[go‰Ž†ˆ‰zx~††vw|sh]]]]_`_`da^cec_^\[^\]^Z[[]_lpnifjmns{Š¿¿¸¸´¯ª«¦¡¨¦©ª±­ª¬©´­¶°³©®§¬³»º¶Ã¹º¹°«´¹»´Â¹¯À±¾¼»¶¼È¹Ã·­ª¨°²À¶¸½°±¨±³µ»¼¬®¶¦®¶®»²±ª¹°®»®¼¸¼ÀÀ¾ºÃ¿ÆÃÅÀ¼ÆÂÈ˸ÅÇÅ¿ÇÄúÄÆ»ÆÉÌ˳¹Â½»³‰tvwki`bliYWW[ALKMJEAC@GA;::996854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÅÎÒËÃÅÁÄÏÇÍÁÂÆ¿ÄÄÃÃÊÂÉÊ¿À¼Áº³µµÃ®ª°’[i~’ˆŽ{x}‰…z{„€wn^]\\]_`__dcbcdb`_^Z[ZZ]ZZZZ\enohfgiknr„­¹°µ­¤£¥¥™Ÿ£Ÿ˜š¤ª­¤¨¢«ª¬«°£¦Ÿª­µ¶±½¸¯·¯¨®¸´´¼¸³¼°¸¹¶²¼Á²Á¯¦©£«±³´¨½ª«¨«­®µ´¦¨­¡¤¯©²¦¨¨®¥¨·¬±³·ºº»²¼¾¾¿Å¿µÂÁÇÈ·¿ÀÅ·ÄÃÀ»¿Ä¾ÄÈÌÊ¿¿ÄÀÀ©‡stsji\aodWVXPHZRSKFFE>?@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÐÏÍÃǹ¹ËÂ˾»É¶½Ã¾ºÊ·ÁÃÁ´¶¼¶±¯µ¼­©«’cmˆƒ‡‹€z}~xt~|swe_]\\^_`^_ccab``_^]\ZXY[[YXZ\_fkfdfehkor…©¥«£œšŸ£“›£™– ¡¨££Ÿ¥¥§¦® ›¤¦¬²°··§°¬¨ª´«´º±¶¶®¶º³°»º±·¥ ¤ §±¨¬©ºª¥¦§¨§³­ ¨§Ÿœ¤¦¬ŸŸ§¤ ¡±­­¬²µ³´±µ½¶»ÁÀ²»¾ÃÁ²¹¹Â³À½Àµ¸¼½¾¼ÂÇÄÃÄ¿ÀÄ „xqlbf`ko`UY_HNhOTHFKF<=@=:;;826536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;>97776788666;::;9:;<859<:>>@;Èµ¶½¸ºÀº½µ ž”¡¦º¶«³³»³ÄÏÉËÂƸ·ÇÀÌ¿¸Ê·»Å¸³Å¸³¿À¬µ¼²¬¦¯´­¡£’ir†…†€|xusomjiipi_`]\\\^__acb````^\[\\XYXXXVX[]_dccfgggkmn‡¨““—ž”™ –”‹œ ¡¦œŸŸ£¥£§ž›¢œŸ«°­±µ¤©ªª¬¬¥´¸­·°¬³µ¯³¶¯±ªŸžŸ¤¢²¥¦ª¹­¢¦¦ ¨­«™  ž™Ÿ¥šš£œœž°©¬¨ª«¬­°³¹¯¸¹º°¶¼»º¬³³¹³½´·±±¶µ¿µ½À½Ã»»½—„{sl_e^ddXTW^IW]KPGJJGA<??A;?<05536:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»¸ÁÁÁ´¤¤™š¤¦À²¯¶¬µ·ÅÏÈÈÀÆ»»ÃÃϾ¹Ç¸¸¿·²Â´±»»¬¹º±¢Ÿ©«§˜žm~…†xrmomkb^bff]]^]]]\]_`abccba_\[[ZZYXXWWWXXXZ]bddfffhikrŒ§š‘‘˜”˜ž“”Žš  §ž›¥¦¢¥›Ÿ¡š™¯®®¯²¡¥£®«¨¢µ°²²¬©°³¨»³§¶¡£Ÿœ£¢®£¢ª¶«££¦ž¦¦£–™—™› š—œœ­¡¬¨£¤¦­«³´ªµ°²«³¹´¯ª°²²³·³®©­®²·°º¶º½À¸³±”†yuf_f_[ZVSZUK[QLJEHKIC=?AA@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½¸½¿¶¾¼¿³¥£˜¥±Ãµ¶½­´¹ÁÌÈƿŶÁÀÇζÀý³¹¹²¿¶±¹»­²´¯Ÿš£ª¡”šxƒ„xoqtqhediec\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXWVWadecdeddhjv ™‘“”œ”—’•žœ œ–¡¡©£žž¨œšš«§¯°«œ£¤¸ª¡ ¯¨·«§§®±¤¸°¤· £œ™™«¦¡š­¹°£¡¤œ¢ Ÿ“”¡”––›™˜–—œ•Ÿ©žª¤¢£ªª±­¨´¬ª§­³°¥«®³±¯°¯¯§¨¨²®±´°¼´º¸¯£•‚zve_aWYXSRTKM^LPLGHLKE=@>=B<:7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´ºÂ±¾·½®§§¢ª»À½À¹®´¸ÁÌÇÅÂýŸÈ̲ÁÂÁ®¼»µ»¼µ¹¹°¯°ªœš¡©•‘Š‹€€|wqilrtphhedfa\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWWV[bccbcbbcfi€’Ž‘‰Ž‘—•™“”™ž›ž• Ÿ¦¥£¦§ŸœŸ¦ «¯¦ ¢£·¨¡¡¢©³¢¥¨¥°¦±®¬µŸ¡–•©¡¢”­±±Ÿ££žž˜›“‹¡”‘“˜˜“—˜˜—ž§›§¡¢š¤¥¥«¤¥°§¥£«¬­¦©®°¯«¨ªª³¦¦«¯´±®¼¶±°¯ “{xseb\[]XNLQHRaMVPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8847763321./2556;:8;7876<;:;;A8x»»±¶½°»±·¬ž¥¦¬·»¼Áź²¹µÄÉÉÀÃÆÅǶÆijÁ¿Å«··½¶½º»µ²¬­¨™™Ÿ£‹Št‰ˆ~vncafihfgifil`]\[ZZZZ\]\[\^_\ZY[YYZ[WUXWUTVVRTRU`a_`a_``bdi~ŽŽ†‹Ž™‘“•¢˜Ÿ–œ ¥¡¬¥¤¤£¤£««¥šŸ¥±ª¡¡ž¥ªž¨¢Ÿ®¬ª©®­¢¢¢•˜¢›œ«©°œŸ¢ŸŸ—˜“‰ž‘’“–˜˜“œ¡£œ¤ ¢• ¢¤¥›£«¥¢£«¤«­¥®²ª¦¥¦¦´¦ª¨­³µ´¹º°«¬žŒsqp`[WVVRGQOHZ\ORJTKSLEGJD8;;><9667:9;:976977:;:=<<6;<8>598:88659:;<97?<9678452121..1426:8698598989;9@9{µ´¬´»²°«²­¨§¯¹¹³ÀȺ¶À¯ÅÈ̺ÁÉÌȵɼ±½ÃÉ­±¸Áµ¼À¼´µª¬¦–šœœ‰rˆƒ{tiijlgjlmkjle]\\[[\ZXZ][[^``\XXZYXWXWTUVUTUURRNQY]\]]^^__bdm‰‹‚‹‹–‘›š¡›› ¨©«¨¬§©¦¤™¥¯¤•™¥¯© œ™› Ÿ®šœ«³ ¦¦Ÿ¢¤¡””›––’©ª­›Ÿ¡¡›”Œ™ŽŒ‘Œ’–•¡ £œ£•›¡£¡˜¢¨£¢¨« «°¤®¸¦£¤£¬­©¨«¯´·²½µ³«¯˜…uti[XYRURFXLQ[XMUOQLQRINJB=??A?=75799<<977:79:;<=>;7;;:=67:;8976989:6:=99577571141-+/434988::8::748=8?9~³­§³¶®¨¨¯®›©¨¬·¶¬¼Ê»¶¿¬ËÆŸÁÎÏdzĺ·»Âȱ­¸¿·¼¾»³¶¦© –˜™—ˆzt€vwnmhmmmpggifd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUSSNOQYZZZ]\\]_`d{ˆ}†zˆŒ†Š”•— ŸšŸ«©¦¯¬¨°¥©šŸ­¡•–¤¨§˜šž¯—™§ª™ ”¥¡Ÿ’‘’‘“•¨«¥š™™žž—ŽŒ‹“†‰ƒ‹’•‘ ž¡¤™–Ÿ•š¡¢ž”›¥¥§©¨ °°¦±½¨ £¬´ª®§°´°¹µÀ±®±«~rtcVTVNRJGVPRRLLXNKMORHNKACFDD>A75889;9:7::7<=:;@>:9;9:?759:9876958779;85576661320-*.102877;99;8948;8@8´¬¦±·ª¥¢±«ª§©²°¤¶Æ´¹º³ÊŹºÁËÐʲ¶¸¼½Àñ°±·®´´»³´££˜—•„€vkglnqnrjokdege^ZYZYZZZZZZZ\\]\ZXXXYYWXWUUTRSUSVTRNNNRWXZYYX\\]aj|v{q„‰ƒ†•ˆ’’–š˜¨› «¦¦¬ž¨™ ¦œ“Ÿ£š——†…’›¤•£–––ˆ¢››”ŒŽŠš¥§œ••—›‘“ˆ”Ž‹Œ€‹’’’¡š ¢–”™˜•¢¦š™¤§©§¡ ´²¨³¸¡£·¬©­¤³²¦µ»µ«¬±£Šzsn^NQQMODNNNPKFNNJJNNQIMJAHLHHC>958889:;69:68;99><8:>9;?8789:886857688974577820301+)-/12876:999984988A7w¶¦¤·±¥§¤ª¥ ©¦¤³ª¢²Ãµµ²³ÆÆ·ºÃÊÌƳ¬¹½´¸À¯®©°ž¦®»¯­ š›ž••ˆ|„n__frpvqjnieghj_XXXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQMMKLSWWVXXXXZ]annrl€„…}‚ˆ’’¡Žš£¢¤˜¥–¢œ•ˆ™šŒsƒ~Ž—–†’š”ŽŽ{™‚‰€Š˜ £ž“˜–…Žƒ”~~tŠŽzˆ“›šš’–Ž££Ž‰š ¡¤¤›¢´¯¬°­Ÿ˜¦¸¦¥°¡±®œ±¼ª©¯ª™ƒxtdVMRPPMCSNLPMBPQHINSMHJJDKMFKK=749888;;69;7:<9::;79?9>@79:<89764445874312585/0102)(,-02764789::66:87A7x·¡£´¨¦¥¨£¥¥¦¦¦²§¦´Á¸¯´°Éĸ¹ÀÎƾ³¬ºÁ¬­Ä­¨¢¦’¦·­£ –—’~xfWV_gfighociigb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTQMMJHNTSSTUUWY[]ihmh{yqMVpŽ•…Œ›—Š“‘Ÿ˜•”–”–Š€”‰_;Vo|Œ”Š€Œ’Œ††s‹…—y{†”•ƒ–Ž‘ƒ†}“xqp†}‰Ž—š™“‹ŠˆŸ˜ˆˆ–žš¡ —§®©­©©ž–­³¢¦®™¬¬˜¨´£©­£“tn`[NSRWLDTJPMLFNOIELQMKOJIMPFIJ=7599999:7:;:>>8:==7:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9y· £­¡¦¦© ¦©§£ª°¨§´Á¹°µ°Ç¸³½Ï¿¹¯®µÂ§ªÄª¢˜ƒ”œ±£š˜‡”‹‡~sv]PLQUYZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MNQMKIFHNQQMORTVXZ`kjdv~qNA?•‘|‡”Œ„Š›Ž–•‰’ˆ†•‡y‰`JQnx‹’„~„‹…€m”xvvx„špQˆŠ†|~x”vhw†ˆ~Šˆ•‹Ž‘“—Œ„Šˆ•„›ƒ„’›–ž”¤¢¨©¥¤ž›°ª¡¤¤’¦ª–¢ªœ¡¦¨‰vng^\HQQSMIUMRILKOIHFJNLMTKQQOGJD=769:8:;;8:;8>?99>=8;<6;;478;6775344696/3/.125221/,')+*,4833989:99::::?9w¶œ£§Ÿ¡®¡§¨¥§¨¯¬ª¶¼¶¸·³Á»¶¨¹È¸¶¨¨µ¶ª²¼§ž•‰”©–•‹Žƒ‚~xqoXMKMNOLMQW[\ZXZUUVVVWYYXXYYXYYYZXXVVWUSPMJE@@›kssIMKEDCINOhYOQSTUZnpszgfZS‰”‡s~†€|…Œ“‚’™‹{†€v€xsouqtŽŽz~Š«…z{iv{Žprmx‹’x{€{€wss’xgu…„„…|•ŠˆŠ‹€„‹€”„|€˜”œ–‘Ÿ©ž ¡ ©¥ž˜§¤“ Ÿ–žŸ¤sib]]JWPRGKXROJMLRJJJLPHLQLRTMFIB=78;99>=:;<98@?::>=7==79937785675251472/2.,//200/-+(().12721987:8775:<;7v®™£¡˜Ÿ´©¯ª¥­«°±ª½´²»¸¶º´±Ÿ·º²ª¬©¨²¯¢š‘”ŽœŽ‘v†w|voojYKHHHGEHHPTTTWWSTUUUVWWWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQQSV^u‚zvdt‹•˜Ž{fy€vxˆ|ƒ˜’€q‡|w{ok~­}t‹z†’}tfv|†lohs|Š‡€myq}qmvqhq~ŽpD‹…‚ƒ…wwzŒ†}Œ{u}Ž’˜‹’š›£–™šž¡œ–‹¥›Ž—Ž–˜xongc[XXUQJSUTOPNPVKNKOOJROHNPLFD<;79;::?=9<:99??;8;=7<9999266856633511224.,,-..-0-+*''*.1362/876966527995y¦— ž– ¦°¬®«¨©±¯±«¼¸¬»¾¸³¬§›°§¬›–¥©¤¡˜™…’y‰‹‹vq|mupjmjXKFGEA@CDHLLMQRPQSTTTUVVWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNPQTX]eopj†¥ªÀ~sxb{wn{x‡y{‹†omŒ’ytyjj€‚q–‘Œ}•€J“™nhw~‚mjdly…’†krl|nr|†imps‰…‡{~{wptt†‚yyp|Ž‹Š“ƒ–—˜š“––™—–Œƒ‰Ÿ’‹’†—€ojoooYVXTRQYORTTRXUMNHMKMOKCINGF@:99;99:><9<;::=>:8:<9?868727565541432/024*+**-.+-*(*(',-1250,5567485HA895w™‘›˜›Ÿ¥­¯¢­ª¨µ¯®¬´¿«¼Ã¿¥¢š•¤˜ž„‹”¡¡˜™‘“‹sŽz€†Œ†uotkpldljYNDFC@<>>AFFGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_IMOORVZQX[_¦‡a™grxd}olyŠˆu‡…tlš’tt|jjŽMy…“‰„Žg1v‡sl~~ƒtfeu„„…€filukp€|hqq|n“|t~}qqnum‚wyujyˆ‚ˆ‰ƒ–’’‹‘””Ž—€yˆ—ˆ‡Š†€ˆxlkpheXR[XYY[MPUVYXNIHEJJHGC@GECG=998;9:9<:9;:::@<9:<98>787715234533645031/**+),,++)(+'),,226,,4775478iO8;5m’ˆš™–¤¨­ž±ž§º¯«²°Â±»Ãǚ–”™‹Ž…z„˜”Œ†q‡‚tˆŒ†zprpoodqg_TFIC><;9:?@ADCEGILOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOOQULAIQIb¯²Ÿpzvk|lq‚„€z„……yr •tx€su”‡5q¨Ž¡¡„£…vp‡|‡|tŒ®‰hgbjnrmpƒuipXupŽ›‘vm{}mrnp€{svnbuƒ†€…ŠŠ‰‘‹‘‹‹ŽƒuxŠŽ€~ƒ€}Ž{sqqm`[]^\ZYa_RN[ZXWLHJFIG?CABG?CD=;97=;:;;9:99;:?<88=:8;66651121253474531./,,+)*))***)(*)+/3DM2166643<vR7=7b’’ˆ•‘¤§ž¯•¥´©®°®Á²»ÁŖŒ”€ˆ|n’‰ƒŠ‡†u‚„l•ˆˆ{uxxmwnwdj^IPG=?7449;;;=>@BEHLLLLNPQRTUVWXZXVUTSPLE<5*K[@-gI94/?’ƒ©®_HLMNPL7CMQSDK…t{{u~lv‡‡{|„ƒ~‹}u¢šz~†„™„šœa†ªŸŠƒŽzw‰~‰ˆŽs‹—„{]dqtz|wŠmhjbyo…‚zoxu„zptzxkni]v†}‡|‡†ŽŠ’—ƒ…Œ†}q„„}vw{|‰xqtufg`[[^S\g^WPTX[UGJJEKG?F@DC>AA=;97<;;=<::99;;=>79>9985653244004645554-,)+(&''&(())((+++/00Uq=23331E~W4=9\xŠ“Œ‘œŸ¦‘ ª ±¨¯À²»Åº–Ž‘”‡{†vkŒ‘‚}ŠƒŽŒxƒ€s „Š}}p~zhvlRXL@E211376688:<>AEGFGJKMOPQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMOQLKT]YRKh‚‡z‰y{q|‹y|ˆ†~–‡v¡šˆ‡’”¥­©H†®¯®‹€”‹‚‹‚„’©‡€˜˜Šœtm|†‡~Žhghyn…‡‚…q„†Hl€wryvhmk_v}ƒˆˆ„‹y•œ›‰‹ˆ‘zuŠv|xmow~uusm\^^[cdXge\TPPVYPDLKFOICFCC@@CA=978:::;;:888::?>6;>7595773344236656768;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|}‰…‡‘Ž–—’– ž¬ ¦¸¯³½³—’‹˜‹}tp~‰’~}Œƒ’”}†~†¤‡ˆ‚ˆ…x‡‰~s„x_cWKB60./33123668:=>?BEGHJMNQSTUTTVUSQOGC?80,#‡[??84.]–ps£UFIKMMPW`YoY\^iŒ’†”€ƒ„‘’~…ˆ‘š•‚¡¡˜•›š¦­“™»±§»Ç苌¡¥Ž”‰‘|qƒžŸ‘w……‹‡ihp„tŒ‡„Šr†‚wˆ€{v„|nvuf”Ž‡ˆ‰‡ˆ‡¡«¢–‰Ž—zˆyypgkx|ule^[[^j^bg`ZOLNWRQIPJDNGCJDCADDA<:87=<:<:88778:==8<=68756623444576867<BB?<8:>CQ^e\G2'&,,--.1(?‹[.310Oƒ_4?;nupfwƒzŒŽŠš›¤¡¬¦«¯°—‘‘„¡”„xwŒ”|~’†’•Š€’›Žƒ€ŒŠ‚‰ƒŠ€mpj]B@4--//..02234779;=?BDHINQRTRSSTRPOHDB<87/9C><<63.l“—MPIILLKNV`cfgmt›™Ž™’’ŠŽ™ˆ’‹  ’£ª¥¤¬“©¶¢¨Á®ǯxº”š|¡ž™„“…‚Ž¡Ÿ”™‘…Š…™‘–lpuŠŒ‚–ŒŽw„qm…Š–‘ƒ…ˆqˆ –†’‰–¤´©›Œ”¢ƒ‡’ƒ}kjj|‚ƒuc^d`[gl]ll^WKHNRQMLLFIPCDMFBCEFB=997=<:;:987767;:6=:785456344566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYo‚ou†qv’†~—–š”žžœ§ ©–“˜žge¤š~„’‘y’ˆ‘’}Š„˜’‚€€‹Œ‰†‘‡…‰…xx~gMR>/..,/.-/000212467;?CENORTPPQSQNPIED>;<:DF?><752<?R5HHHLLMNR^nŠ|s|žœ›§¥¡™ –¢”œž¨ž¨«Ÿ¨¬©ª¶—«¿«¶ÈÈ·ÈÐϾ› pi«©Ÿ„“’…œ š›™¦’‘ˆ•¢››xz~”˜“¢“——”ž{w•’«²‰—Ÿ|”›’•˜£¡¦µ¯œ˜¨‡–€ˆlss}~si`^b`bhd`gf\REJKPOIILFFMCHLFGCBGEA:85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Ppt`m|awŽ}{”ŽŽŠŸ’—ž–›ª˜žªBD}‡‰‡˜x‚ŠŽŒ|Š†Ž‚€‰‹Š„’…ƒ‡‰€‡v^bP460-1/,.0///..0015>AAMQRSQRSTRNSLEE@<>=FG@A@8662<9;FHGIJNOQYm…w”‰¡¥¨³¼·¤®««¦¨´«°¶²±­»±³¾œ³Ã«ºÉʷÿ¸¥¢°³¬­ª£‹–˜…¦¦ £—¦™¢«¨¥ˆ…”¤¡ «¡¤¨œ±‹•£¦·º› ¢°’¢¢£¡«¯¬²µ¢”¤ªˆ™ˆ’‰•yz~†€ibi]fc^dd^gg_[OCIHSNFHLFJGFFHAKFCFFA;87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLhbWioXz…v“…ˆ‚›ƒ’Œ’Úȝ–sV—ˆˆœ|†ŒŽŠŠz‡‚‡Žƒ„‹…†ˆ’†ƒ…‰‡ˆ‡‡qna@E64<3/110-,+-1.-4?CAMUQRSUUVUN[PGHE<>>FHCEA7;<5C;=FKIGHQOPW’Ÿ„­¢±©±Àƪ³Å¶«³¿³¸¾¶¿´Á¶»º£¸Å¨¶Éǵ¾¹´¨£´­°±›™’šŸˆ§¯«¥”vŸ¤—¡¬²´™–ª®©®¶»²º¬°µ¢±¬±µ»·µ®´ §¨£§š©¯¬²¹·¸¦›¶©Œ¤Ž‘“Ÿ†x…w[ceWgcbd`ag`[TJDDLUQHIJDIGEA@@KDBMG<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AFWQJL[YQbcWyup”}„†“u…€Œ{¿»£¼‚´”“›„ˆ’‰ˆy†€Œ’Œ‡„Ž‰‡€†ˆ…Š‡‘zxn]V@EM<6:56AB764//6CHBQ\PQUWU\VP_UILKA?>GKFFD;>@7D7?BJJEFVSP^¤­£±³Áµ·ÁÌȵ»Ä½³³À¶¸Áµ¿¯·t±³¥ºÄ¤°Æ¹±³±´¨¤µ¶ª± ¢—›¢’¥°®¦­«§¤˜ ¬´»¢¨²ºµ¼¿Ì¿ÅŽ½³Á·º·¾·º·¹¬¬°¥°©­½°¼ºÁÁ«˜¹§”­Ž——ªˆ~ƒ~lXdbYkfjfW\cYVSIGFLQGCHIAHD>?BBL@@MD99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FRLALQVSYUZvjo~Ž„€„nzsx‡b¹¡™£‰””–’”“–’‡†{†•Š€„Šz|‹‡†}Š‚‹„•}wzueP\dGEL;Qca[^SF?;HPEZcQRXXZgYT``LSPEA?IJHEEA@D<E6B>HGJLSZT]“®¸´º¸È¿¹½ÉÌ»¼Á»·µ»º¶½´º±Æ`u²¤±šž«½©¥¨«ª¤¢²µ «¨Ÿ•–Ÿ™ ®¥§¦¥Ÿ¤“¢§±´§²²½¶Á¾ÓÉÉÓÆÃÅÌÂÊÃÀ¾½¾»¼·´¯¸·¶Ã¹Å½Âǯž¹©¡«Ž¤¨µˆs`cc_Xc`jgRX`VRUIEENK@>GD=JA=B@=F>;HA796379>489:57045/26389374426?8@>GKRTSQPOQQPJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKE@IMPRKQ]glkpŒ„slrrs‡ÕÀµ™ •˜™‘Ž—’––Ž†‡}†ƒ–Š~ƒƒx{‹ƒ‡|‹yŠ‚—~t}zkfpuY]\Pedb`ed][XW\MdmURmm_n_XgdUYUJDBKKIFHHHHBI:D?HKTTV\Z[’¹À¸½¶Å¿º¸Éʺ¶¹µ·¹²·µ³®¶¶˜du¨œ­p^¢¬œ˜ ¢›¤žª¥”Ÿ “Ž–™˜¨Ÿ¦ žš™ƒ¤ž¬¥ª°­¸°½¹ÔÑÏÖÐÊÌÒÌÏÎÊÆ¿¾ÂʽÁ¼ÁÀÄÄÅʾÈ㤻°´¯š«¸»˜{m^a]Z_bZdcP[`SPKCAEFE<@E>AHA@D=:E>=J?37535;=468977022/24169775555D3ELM>51/006:477@IOI;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODQ\Yh_o–‘”nlotu‡³« ¡Ÿ‹™œ™ŒŒ•‘›’…ŠŠ~ˆ‡Œ‹‰|ƒs{Šƒ…{‰t‚Š†•s{ylmu{hreiligjih`fiilZms–­¤¼ˆ†g[oh]ZZTHKNPJKPKSQHLAJFJO_^bgia—·Ç°¹²º½µ±ÄƵ¯¸±°»«²±§«·«Œ¶§š§šNšŒŽŸ–‘¦˜¥•Š““‰‰‘‘›¡—š•–‡žš§›¬¯¨°¨´´ÔÕÕÖÓËÐÔÕÍÓÏÍÅÂÉоÉÉÊÉÑÇÌÍÂÐÑ·¯Ã¼Ä¹¥µºÂ¢ƒpe^^_YaXZfZQ]XOPBBHEBH;AC>AG??A7;D>@H=46655;:687654/10146278875367C5B8?-0-1349=97,.,1;FK=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYReVs˜‚hqoyyƒ ©ž¦—Œš›—‹•‘šŽ}‰‹„ŠŠ‹ˆ|„‚p‡†{‡rƒ’‹Ž}qxulqx~qznxslipmcjmpxiw|~Ë¿Áߧmcxnc[a`JPRUNY^P]\NPNTQUT\nmv‚q–­¸¬´¦°µª¬¼¿°ª´¦¤¸¦«® «´£Ž±®š—˜Œ‘“‘„Ž›¦‘œ‰ƒ‹„Š‰„‹„”•˜—“›œ˜™šŸž«¬¥¨¢¬­ÏÒÕÒÎÌÓÔÔÐÔÑÎÈÃÔÑÇÍÒÓÓ×ÌÑÑÅÒÖÅÀÎÇǨ¾·Îž{pg_d^XaS^ZPQTQOH>@FABE<@A>ED>??:==<<JA45465<888664412/03526768533;=<E=@11+/249>5901022-2DN3)/3.32=N238C}_2A†tD:==I>@CFH<VRMNZu†…Šwlwo}~¡žž¡ŒŒ˜““‹Œ’–„y…Š‰ˆ‘†‚{r~€‡z„u…“ˆovrks}{w{sxrj€srioqzyqz¾Ëš~Œ²„vr„vhak]CZZ[VecYdjTX\]`d^cwz~‹˜©£¥¡Ÿ ¨¥ª°¸ª¥³£¡­¢£­¡§±Ÿˆ¦š“’‘‰‘Žˆ“‰j”¢Œ™„†~‘ƒƒ“—­‹•”šŽ†“‘ž—§°¡¡¡¥¤©ÈÍÏÈÂÌÑÔÒÔÒÎÓÍÆÖÒÌÔØÖÖØÔ×ÕÉÔÚÍÉ××ÑʬÃÂˌtpebaYUZT\PKGIJJ@;:;DAD<BC>GB>BB;<9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/--;R017/532FD28>nb5=tM99@I<AD?A;PLFKYp€u}hsxr‚‰€œ””…‹•‰Šˆ‡Žxƒ“˜ŠŒˆˆ‹‰~ƒxs{}ƒ‡wz†‘•ƒnwpmuvx}t…|yl‡vtn}v„tx{µŒ;A‹Å¥~Œ|ieWICfcecgjdnw[^fhknin€ƒˆ‹œ —˜ž££¥±£¤³Ÿ¡¥ ¨ £±œ…ž’’’ŠŽ‹†ƒ„~œ›Œ‚„…z”‚©•£Œ‘Š—’‹~˜‹š’«³˜›œ¨œ§½Ãƹ¶ÆÎÒÑÒÐÌÒËÉÔÎÐÕÚ××ØÔÙØÍØÛÎÉÙÚÑÖ¾Ë˵zxpf^[SWR[VFGJIEE=:7:@@B:FD?DCADB;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?1*(.BS39254/7K75<`bA<svV87AH:?C><9QECJTknnpbpqs…|—‹‡’ƒ‰†…‰‡|x…––ˆŽ‚‡…†z„yq{{ƒ†uz…Žœy‹p|oozq{qƒ‡€nŽztw}|‚u~{†‡¯sX©Â¶‘‚pnb=^hrpqpnxvehoruxqz‹†Ž“‘›•Ÿ•‡Œ“› šž©Ÿ¡¬›¡š™Ÿ¥žŸ«™‹šŒ‘„}ˆ‡ƒ…‹Ž ™“ˆƒ‡~l™z„™†ˆ“Œ”Œ†|œ‰”®ª”–˜Ÿ™§¯¶½©­¾ÇÌÉÉÌËÐÉÃÒÊÔ×Ø×Ø×ÕÛ×ÓÙÛÕÐÛÚÑÖÈÔ˖{}jj\[QTT_HCFIH>A>=7:=?;=G=?AAADA>?:87EB755479/566435542323647553458EBDCEB56<FNSM[nfcnskaV>,4LG865434BF4=W_hLux^8;?F<<B<99D?CGRj^mdbfkv€ˆq‘š€z€~‚‚ƒ~ƒ{|„˜‡‹~…†€v‚yo{{†tz’žŽ vŽu‚tu}s€„o‚o’„u|…zv†{ˆ·Å¤Áɸ–›wpeNfczw†¢Šxyv{ƒ{„vm“–”•—‘„‰–™—–¥œ˜Ÿ–ž“’—£™«•‰Œ‘‚Œ…ˆˆ†‘ž›™ˆ†Œ…—zˆ‰Ÿ—ˆŠ‹‚}¡Š‘‹¼¡˜”˜™œ©¦¦®Ÿ¨¶¿ÀÀ¹ÇÊÎÎÅÍÊÑÖÕÕÙÕ×ÛÔÖÙÚÛ×ÛÚÚØÎÛƈ}{ikgbUXVVNLENC;==<8:<>8=@6=?@=?><9867DA6455=80665547745613854564557HH=DJE7925;H>;::7IP]ZRUXK9T>;95327I8=NYMHxxd5=>C==@:6:>>@EQ_Xea][htzyl‰Œ’wvzŠ{~€~|„z}‚‘‰„…z„‡zu}tm|}†~t“ž‘žƒ‘|†~x~xŠŠn‚š€t™†~‰…|}z©ŽÃ¡½Œœ£œ}‰„}‰r‹Š~s¦šœ˜“…{Žˆ„hGq ¤Œ‹’…‰‹’”Žš’”–Œ•Ÿœ” ”‘‹~ŽŽ‹„‰’–šžŸ‰Œ”’‘‚‹€¦™ˆ„‚…„€¥‡Š‹¸˜‘•–¢¨¡žž¤¯·ºµ¬ÀÆÊÐÈÇÌÏÓÓÒØÓÕ×À×ØÙÛØÚÚÙÙ×Û¹{{zmkgYb\TPOIDLB<<>99::99;=6?>><=9:;;37D@8378>60688357<37804976755546FP5DNI8938AK=;3C@I<9DWN<MTHN?96333>C;[X>5YypZ<<A<=>8689?=DRSRX^UXfmmmiŽŠqsyŠ{z|{‡z|{‹†‚}tƒ…yrzsm€~„~w…œ¢›”’€Œˆ˜‡€œ‘n‡¨…z ‹|‘ƒˆ„›}šŠŒ£¢ ¤¯Ÿ‹‹…‹“†Wr­‹Ÿ«›ƒ˜›Ž\‚¢‘‚ŒŸ“•Œ‡ˆŒ’“‹””“Ž‹Š‡–›œ”–Š’“†€‹ˆ’ŠŠ–™¢¢†“– Š‰ˆœƒˆŽƒ‡…¤†Œ³˜’•—¡¢Ÿ™’œ¨²¹¬¦½ÂÇÍÈÆÏÍÐÌÏ×ÑÑÕ®ÖÕØÚØÚÚ×ÕÙÙ rwih_^YTXYCAHC?>>:49:;7:;;3;;?=>7;9:1:H>:37=@51677255?65;55858:57735HR7GOK994=EJB>1FCLB98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:;@;BQKKSYPTcczma~‘ƒomw‹xyz|…{{v…„sp…zuvvt„ƒ…~’¦¤Ÿ¦¢–Š”—‹Š¨—sŠ±„§’„™“…™Œ¢•Ÿ˜“ˆšž£’©° ”Žˆ–Œn·…šÄȲ›¡¥›œ˜–²‘d¤ÍȖ†‡ˆ’’“‰…Š‰…–™›”“†”—ƒ‹™ˆª–—££ˆ™Ÿ–šˆŽ†–—Š„Žˆ¤‰“¨š—“—™¡™Ÿ™“›£³´¦£¼Á¾ÇÅÅÉÈÉÂËÓÍÍÔ©ÒÑÖÖÖØÚÔÓÚ΄u‚kf``_PKV\BBGC;A=837;<:8=649:<:82?992:I:=67BC32:96264>=4;>6949;57944JQ<JQK9A7BGI@64JELF><88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBeƒGu‚Ž}|m}ˆxz~z‚~vv€‚{lo‹~y|wx|„‡‹~‹£´¨¤«³¡–§ ¥¤–•¯¢ƒ¸•’³™¡ Œ¤›¯¢¤˜§—©™­°¤—”•”‹˜š– ÀŽ£É¹«š¢¥­™‘›œ²†…¨¢˜…ˆˆŽ•Œ‹“‡†‡ˆ“˜”ŒŠ““†”˜†„‘œt‘™²•–¤¡ˆœš“ŠŠ—š‰‹–†}Œ™žŠœš™“™˜ •¡•Ÿ›¡±®£¤·¾³ÅÇĽÃÿÆÎÊÉÒ§ÏÍÓÑÐÖØÒÏؼu|x_bWbXRIKOEBCD5>:76:?;<7=42669774=5;5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=89567=:JFDGM[\YIha;H„Šz{m…†y|„x€…}px|}|osŒz}‚{x…‹‰†ƒ’¨¼­©³½¯¥®³³©£¢°¬Ššµ¢¸¥•­¤—©­·¦¤£Ÿ™©˜ª¤¯±ªš˜›”•‘˜ —™»»­Ê¡i¶·ª°•˜ž¢«’—½¤^©²‚‰ŠŒ”‡‘|Ž}ƒ†Ž””ˆ‡’–‹•‹–™“š´–•«ž‹œ”’’‹˜›Š’‹‰• ¡•—™“œ™ž•¢ ”œ¥¯¨¡¥³¸«ÂÈĶ»½¼ÅÈÈÂСÆÉÍÍÄ×ÖÐËÓ£s}k_\UaSQGD><CAB8?874>F<<6<35355454B39:BM:A;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPfHa`bpI@‹‰€r†‡|‰u‚Šƒ~m}}|~pw‡w‡{Œ†Œš«ÃÀ°½Æ»³´Á¼´¬«³·Œ¨²­­½«›º¤¨­¹·ª¦¦¢¢¤£ª¯²±ªœ£˜›˜—ž¢¥¥’£¹®¨À»¬­²¹¥¤§}ˆ†œ­½¯‚‹‹ŠƒŽƒ‘Žy‡Žœˆˆ—Š”—”š—§š°š‘«Žš’Ž••—Ž‘ ˆ”›£¬•–”œž” ž›˜ ¡”šž§§¤¢¤°³¦ÁÆ𰻶ÅÄÿͧÇÃÇüÖÐÌÄʊvud_\b]OKCL@EG>A?B<:4>A==5=6>333242A17@BN?G@CNCA=C=;86CB5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GE?CF\hF_igZ]\“ŒŒˆ{‡‹†ƒŒu†Šn~{~q~z•z’””˜‘“•¨´ÇÉÀÂÌÁúǼº¯«¹»—²¶º³À®¥À¤«°¼¼ª®«££ž¨¬¯µ°ª› ªœ¢œ–Ÿ°´§‹¢ººµÁ»«¨œ²¤¤¨”„Ž©Ä䂋Ž‡ˆ„†•”ŒyƒŒ‘’¡ŒŒ”‘ˆ— —’™•—¦ ®œŒªœŽ–’‘••Ž•‘¡“†—Ÿ ²Ÿ”›” ¡™¤ š œ ”˜ž§¤¦§¤¯­¥¿Ä®©·µÉþ¶Ï²Å¾Ã¼³ÑÉÇÁµw{o_Z^lTNIDMKKI@A=BD<5AD;:3=8B332263A05IEN>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBg\Me\fTcj™—‰‹ˆ’†‰y†“r€{w†‚z¡–¨šš˜»¾ÉÈÊÂÒÉÊÂͼÁ³­¼¿§º¿¾¼Ä¸¬Á©¬³»½ª°ª¤¥£¬®´­¶µ  ®Ÿ¥¢˜£´¼©›¨¼Á£µ¶¯«’¯¬ª«–†šª§¥‘‚Œ“¤•Š€u‰’y…‘ž ’Ž”‹Œ”£™–›””£ž©Ÿ‘¥šŒ•–ˆ}•’’£š• ¢œµ¦Ÿ—¥¤£¥Ÿž¦˜ž•—œ¥£¨¨¢²­¨»Àį¥³·ÌÀ¹®Ã³»½Á¹­Â¿™p{c[X^\MMNJGDCHBBACK:4DH:;4<7E.12352B26SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQF7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>lI_XaZddWž—Žž’‰ŠˆŸ’„x…•~ˆŠ€• ™®§£˜Ã¾ÉÄÈÆÒÍÎÍ˼·°º½´½Ë»ÃÁ¶·¼­³À¹¼®¯¨¡©¨¶­®©²·šž¬¢§¡«··©¥¯¾Ä±½¹³§©³³­®–•¥­¨ ‘Ž’±Å§•}‘•}‡‘˜ª™˜““Ž“•“¥ž“™“¡¢¡œ˜Ÿ˜‹ŒžˆZ–—’–¥™e˜£ž³¥–¢–«­«§œŸ§—˜–˜•¡¤©§Ÿ¶¬©º¼Ãµ¦´µËÁ¸ª¶¬³»¸®¨¸º¼·„np\ZVWPGKSMK?AHEDHFF85FM;>7>AJ.32025B55PWN<LFKRLOGGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|hV<>@BFBsFiIRecLF¥”œ•¡—¨–Œƒ‡¥’ˆ‡‚›„ƒ•‘”Žš¢Ÿ¯¾®¡Ç¾ÆÅÈÇÎÎÎÒʾ»¶±º»¼¿ÏµÄ½·¹·²²¶³·³¬¦œ««¹«©¨¯°—£®¤§¤¥´Á°«¬³¾Â¹À¹³§¸´·³¯•¤­°¯¥‹“•¡sÁ™}–™„Ž–™‹±•šš•’’™™¦£• ›–š©œ›¡ ™ŠŒ–`J–œš•™¥—T–°Ÿ¯œŸ¥”¯¯­¦›¡¦”“™™Ž §¡™´©ª³½¼»«°²ÇÀ¸¦¬«­±±£¡²²´¥sqg^\PRMEQQPQ;HKIFGAC=9KT?A:=EM07544:B34NWO<JKNUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@CAF3>58JKCA=C;4EA:A?>H@5*B52,>c]g:35tde@R7&#3}hX<:BC@=REWSsbVFH«—™Ÿ¡¨®˜—‡Š§–Žˆ“… ˆ„œ—ž ›£¥µÉ´©Æ¼ÃÄÈËÉÈÌÎǾº³®¹¹ÁÁ͵ȻÁ¹µº±¯¯²´§¤œª´µ«©¦­¬™¤®¥¥¨¬ºÀ¨«¶¶¿ÁÀ¿¸²²Ã°·½«£®µ­º¥ˆ›—¦›v¾Ÿ„˜œŽ’˜š‹®–¡œ›—”šŸ¡©ž¨ š›ª™¡§ž—‘ƒmu“¢š•£Ÿ®²£«•©ª˜«¯¥¥¡¥ª“’™œ‰•œ¢ž–±¦©«º·½³²®¾¹¶ £§©¥¦œœ¬©©fhb`SLMGHNJUL=MEMIJ@CD<QU<AABDO18=77?B75UXN?HNQXRPQTJQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW<:=..SaMVH~e^HF¬•œ¡Ÿ»®™”ž‹“ª›‘’“‰ª†¡žŒ£¬”¤¤¶Ç½´Á»ÂÂÇÉÅÂÎȽ¹²¯¹µÀÂʶƱÁ¼µ»«©­¬°££™ª´º¦ª§¬ª¨¯§¤«ª¾¼¨­¼´¸¾Æ¼¶µ¸À°½À³©µ¶«¿¥£—‘¡Ÿ»ž‰š ™—¶ž©œ¥£›œ¡š§¥³¢›ž¥œ¨ª˜•”›‹–‰Œ¤¡”œ¢Ÿ¡µ¯¥¦“±«š«­ŸŸ¥¤ª‘–• „žŸœ–©¤¡¡´´ºµ­¨µ²²žœ£¦š—•™ª¡žxc_a_LIFHNQIMDFFBQKHADGAVRDH<AGQ1;A7:BF79]YKALPTUSMWRNUJD@JJNO9C?5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-1:h]FDCœpbGE§—¤žžÃ¬›—¤—™¨›•ššª–•¨¦•­¬™¢ª¶Å¼¿¸ÀÂÀÈÄ¿ÍÆ»¾¹²°¸´¿Ãȵ¿°¼·º·§¤««¬¡¡›«ªÄ¢¥©¬¦ž«¯¬¢ª¨¿¸¦­¾°··Æ¶´¹¸¾²¿Á¶´²´¯½£–£•’›“­Ÿ¡¡¤¢£ž¾¤©©¬ ›¦Ÿ½¢˜£ž¢©« –•ž“ž‡Ž„“ž¤¡µ¬¦œ–²¦™°© ›«Ÿ¡š•Ÿ„Ž¡š›’¥¤š˜«±µ±ª¥ª­¬œ˜ ¡’Ž•¨Ÿ”je\b^PJHKOMHECI@=OH@;GIH[ROK=HNU4BE8>HG5Cb[KCNRUWVQXTRUH@8QQPM:G@4CHQSIC;C>GVKC@O>K<06;GF>;FA56?9:?9;15D0-,0Mv\4KZ5,MnW<-=)#zbQ5CKQ9oRF<KxfcXN¢›¤›žÅ¬¡Ÿ¬œ­Ÿ’¢ž–¥ ¦©¬—¶±£ª³¶Å½À¶¿Á»É¿Êȶ¸µµ±´´·ÂÆ·¾±¸µº¶ §­ª«žŸ¥¤Á¥ ©® ¤©­°¢¦¨½µ¦²¼·¶µÃ²³·º¾³ÄÀ¸¸®´´´£¤”‘“ ¬Ÿ˜¡¨¨ª¢šÂ­©¬­››ž˜¦ ½¡¤˜«««¦ ™™Ÿ’žˆŽX–ž¦¡ ¸ª¦”˜¶£ž²¢¡œ°˜ š”ž‚ —–Ž¢£•¥®³«©¢¢¥¥••œ™‹‘“¤Ÿ‰cg\eaMJKKOFEAFK>=IA99JJN]QQI=LV\8FI=DMI8Hc\KCLPSYYVWOZ^IA=WQIK?H@5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+waS6SZkWsHE6=ue\LOž ¡˜žÃ§¥¢³ œ²§“ª£Ÿ£Ÿ¬©¬»±©¬µ±ÈÃÁóÂþÇĽÄʽ°°¶®±µ°Àŵº±°º¶­š©°©©›ž¦¡¨Â­›¬±œª¢®±ª¤§½·¦·»½¯·Ã­³³Â¿²Ç³º·«´¶­ª¢¦••”¢«¡ŸŸ™§«¯¯¯»²¦Ÿ©©™™—“¢¤¸¡¡£’®¯«¤¥ž’¡ž”Ž”š£Ÿ§´§§˜´œ£¯›Ÿœ¯‘ ”˜”š€’¢–Ž  “‹¦¬°¥§¢ ž’’š”…‹’œŸ€dh]hfKJLKSBC@IG;;F>89NMU_RSJ>O^]=HPBMLI8Nd]LELRTY[SUO\bHA?ZQAHAKB7FELKN>;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<w]^?[U_fr@8<H–weA4Ÿ¤Ÿ›ŸÂ¨£ª± £´©•²«¦¢¤²¬­©»²­°´´Æ¿ÄĵÀľÊŶÀɵ«µ©±¹¬ÀÅ´¸®­¶º¥™«²«ª˜¡§—­»µ›¨°›­Ÿ®´²§ªº³§¹²¸²¸Àª¸²Â½´Å§¾®­·µ©§¬¡––‘¥¤¡¡——¤®·­²µ¶Ÿž¨¤™””“£ ·£¤¥•®±²¥©¤¡žš™š•˜¨Ÿž˜¢Ÿ¯²¢§—¯˜¥«˜›Ÿ¦’•˜š†– •Œž”‹©©ª¢§¡™–Œ™†–‰•Ÿzfj]lkOQNNT=BANC;:I?77QN]_RVQAW`\BJSHVKH:Td]NFON[W[RPQX]GAB[PBG>NC9HGHNP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1\cZ33906p[bH05JqjVCWFŒyfC;¤¤œ¡¥¿¦¨®® ©µª¸¯«¤ª´·±°¸·°·¸·Å½Ãǽ¼ÄÂÇÁ¹ÁÆÁºª¶¥­»­Á÷¸ª­²¼£•­°­²—¦¨‘ª¹ª¡§°« ¯´³ªª·µ¬»¬³²¹·¬¸°Áº½¿¦Ãª°¶®©ª«¦˜˜ª¡¡ ‘— °®³«°¹™›©Ÿ™–’—¦ ·©¥¢¢¯±³«±§« œ Ÿ›ž¥ —¤´°›Ÿ”¦š ©›–£ —™‹–™”–—”‰’›™”Ž©©§ £œ˜›“‡™‹~Œ—†šljmbnnXQQZTACEU@;;H@7:XPd^PWWDY^^NLSO_LJ>Zd^NIQN[UYPKSWZI?DXPDF>N?=IGGQPB=CFBM?:2D?77547?=95E4+75/251.-.,1>*'+=\p=>1.1e[d@1747gYaF(@8m}h\V:‰{cC=¨Ÿœ¡©¼¡ª¯ª¢±·©¥´²«¡­µ½¯³¸½»½·¶ÁÿÉĹÅÃÀÀ¹Å¾Á¸¯¶¨«·²¼¿¿´ª®²¸Ÿ—¬­¨®˜¨©Ž§»Ÿ¥­³Ÿ«¢±°³¬ª¶³µ¼­°±µ¬°µ±ÀºÅ¶«¼¯±·¬¬©¢±¥ž¤¨Ÿ£–˜Ÿ²ª³©ª³™§›š” ¦¤´®§¡¬¬­±§²«±©£›ž¨¤ž” ™›©¶©—š’’Ÿ™ž¡Ÿ’­ š™‡—˜Œš”‹–—š—¦¦£ ž––—”•…{“ƒŒ—gmshps_GYfVDCNXDZ9HB5>]Qh\NZ]G[^]OMRXdKKC]c`PLMNXWXPJVVWL=EUJEDAM?AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,+%2+*5K1.'__aV151=`V_8)C3YU\gK5ŒzfL@¤šŸ¤¬¶£¬¨¤®­µ©®³¸¦¦°¸Æ¶°·¿Á¶´ºÅ¾ÌŹÃÁºÀºÄ¸Á¹²µ¬ªº¸»º¾µ«¯±·™˜¨«««œ®««¾ž«¯±£ªŸ±­²®®¶²¸¶ª­®±§µ¯´º¼É²ªµ´±´¯®¦ ³Ÿš¨¬ ¤••š™±¢­ ¥¯–¡¤™™’¢¥¦²©¡¦±¬ªµ¤®°´¯£™­§›—™™¬¸¢—“‘™œ¡˜˜”­¡Ÿ–‚•™Žžš–‘Š”“žš¥££¡™—“’–{Œ‘…{‹ƒ‹“lnyou|aF`jZIHZ[={JGE6AbUi[M\aJ[\ZSSSbaLKE`a`PLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`Va.5(C^Q\.+A/JGP[G3cXTKEš–Ÿ¯¨±©¬¥£®®µ©·³·£¬´·Êº´»»À¾´³·ÄÀÌǼĽ·¿ÀÀ¸À½²½®¨º¹¸·Â·¬®²¹•—§®¬§¤²ª”¯»¤¬²²¦§¢±³°²±µ°·²©®«²¦¸¯µ³ÄŶ©µµ«°­©§¢¶ŸŸ¦± ¤”›˜”°ž§›Ÿ©©¢›•—¥¥¤¶§¢°³«§±§­°µ¬¤™¡¬¨œœ›”ª¹œ•Œ˜¢˜‘˜¨¤ ˜…“—‘œ˜——ˆ–—›¨œ¤¡’–’–w„‘†|†‚„Œnqxv|]Kel\JOd\?b{GI8GgWf[L^bMXYWUXUi]OOHa]_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANHg27'FaLV%-B.=ELQ<3rkLDD‘™¤­¤¬­«¦£°²²ª·°µŸ«µºÉ¸®Á¼Ã·³±µÂÃÏÄÀ¾´½ÁÀ»¿¼´Ä¨ª¹±¶·À¼¯¬´´¡§±­¥¦±¥ž²µ¬ª²±«¨¨´¹¬´²µ¬³¬ª«¨¬©¹­²°Ç¿¸¤¹°©­­¦§¬°¥¤£®£©œ›š¯™¢¢¢£¬Ÿ£ Ÿ¡©¦¥¸¤«´´¤ª«¨¬®¶®¢£¨ªœ ™š’¤´™‰Žˆ‘£ –Ž•Ÿ¢–•†•”ž›™–•‡—’•™§œ  “’Ž‘x~Ž„}}}‡ŠŠrts~~\Sdn^NZg]FD–[G:NmXbZMabNVVVWTYh^QRLdZ[TKGOTSNGIVS\N;P^JBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3Dd;6*HdHJ+:I?3CIS,>k?HI›©ª¡©¯¤§£³´°´µ±° «­½Ìº®Á¼Ç±´­´ÂÃÑÄÅ¿Á²¾Ã¼¿¸½Å¨­·¬´¸¼À±¬²®¡£§®ª§¥±£«±ª®«±®®¬«²º§·±²©²©ª¦¥£­º¬ª°Â¹´¬¹¨©¨­©§°¥©¤¢®ª¨¢žœ¢¬•¥—ž˜«¡§¨¡¬¦¢¬¬¶°± ©¢Ÿª­°¬ž¦§©š£—˜ ¨˜†ƒ‹‹Ÿ ŒŽ—ž’‘ˆˆ’–¡–˜–†–““—¥œŒ’Šˆ„}w€‡…‡utr‰vl_Y`ncQsr\K<„|F?WuX`YOc\MUVUWQ\b_SOOhXWVKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*35>10485(5/*,.30;),,'%234$,2-860)(1<^K0.IgDF8<B05EKX1@”]@NF•—¬§¡©±œ¨¨¯µ¬¸µ®©¤««½É»°¾¸Ã¯°¬²ÄÄÎÎÿ¿´ÁÄĺÁ´ÉĬ¯·®³ºÀ¾´®®¬¦§©±©¦¨²¦´­ª°­­±¯²¬³º¤¸³¬¬­§« £ž°·«ª­¹¶¤µµ£©¨¬¬ª¬ ¨¦§±±£¦¥¡¡«–ª¡”› ¥ž£¢ª£¬¢ž¦±¶¬¬¢¥£š©«®©¡¥¤¤™Ÿ™•˜“‚‰… ‹›“…Ž™¥›’‘›‹“‘‘”£š›š‹‹‹|‡‚‚{u„~ux‹£‡xk^`ngWf‡dN@g’LDbzWbXReUMVUUTO\]aVKNiWVVIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*49?./463)4+*,+.#4.-+&(+79*&6+<-2,&06XZ.0JgAA<<C+:JO^4D†BIID—‘¯¤¢©¯˜©¨­µª¶°ª¤«©©¼ÁÀ¸¹´¼µ¦²¯ÄÊËÑ¿Á»¸ÀÀºÁºÂÄ®±µ²´¼Á¾³±¯­¬¬¨·ª¦­°«¸®¨±°®±«µªµ¶§µ·«¬¤©ªœ¤ž³³¨¨¤³´Ÿµ­¡©¨«¨«¦Ÿ««¨¹¶©ª©©¡©Ÿ­›‘©¡ £¢¦¢ª›¦´®§¥©¢¤—¥¦§ªœ¢££Ÿ™˜Ÿ‘Ž˜~‡Œ‡…žžˆ…‹‹’Ž…ˆ–£šŽš‘’Ž’Ÿ—™–‹„t‡~xuƒ€zx~€ˆprggqx\atˆiO]˜VHmyUdVRbOLVTUQOX[bVHPjTVTGPYUI>IHOQPxMNV=<KD?@A<@CUC9AK=5;E13;97*4:=+-341*8**+*,)*(/*&)%3;,$2)2021%/2Rc02?f=NX?C,?LT_/Ik7RF;•¯Ÿ¥ª¬™ª¤­®²´¯ª¥¯©©»¾»Á±°¹­¢¶¯ÉÇÈÑÀ¿½º¼Ã½»ÃÁ¿¿¯²³²¶½¼Á±²³«³©¥µ¨¤¬³²¸¯¢­µ±¯±¹ª¸®ª¯·«ªžª« £¡µ­©¡Ÿ¯²¡µªž¨§ª£ª¡¡¬­¨½¯«®­¡§§Ÿ«™¯¢˜¢ ¨¦ž§›˜©°©¢Ÿ¬¢¡’¡¢£§˜š¨¥˜˜˜‹‡”ˆ|†„…¤–†ƒ‚Œ‡’…‡•¡–‰’‘“‘œ”—Š††xt}txz{tt{j‚ˆ£vi^elugˆ‹|RWp^KxsTdSQ_MMSZgNMWYeYGSjRQ>BNQaQ:IHLSIqQLS;<I?;<=;@@W<<>H73CB15:93-5::)-31--6)(+-,52#2)',%.;.&1.0-14%,0Mh:38_=ad?F1CP[[+HP;YC4Ž°ž¤¥ª¢¥£¬¦´³±©¤°§ª¸¾Á¼°¨¹ª§®°ÉÇÈѽÀ¾¹¿¿½É¼Â¸±°µ²º¼¹À³´¼­¹¬£µ¦§¬±¶¸²¦§¹µ­´¼¯»¥­­¶ª­œ©¯¤Ÿ¥¬«¨œª²¤´©šª§©¤©£©¨©½«³°®©£ ®›š²¢–¤›¥¤Ÿ¥š™§ª¥žš©¡›‘› ¤™–¨©‘™š’‹‚…}‚ˆž‡€~Œˆ’‘…‚”›”†“¢“‘‹‘š’•‡Š€rzx~|hw|{uqr~i†z„ˆd`hcr…{mhy]^VCX{mTaPRYKKMpt]IZ[gZFVgOC>KNDCA9HGKS?jaIQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11&/>KI1%90%,,09/,,+6'17#-/GjI14X=fbAJ7GS`U*=<F\@*Ž’¯˜Ÿž©¤£¡ª¤·²±¤©±§­¹Á½µ°¤¹¬¨¨°ÃÉÉÌÁ·½¿µ¸ÁºÈµÃµ´³µ²½¹º½¶®¹¶¿­¢³¦ª«®µ·´©œº»¨±¿²º ¯´¶©¬ž­±£œ¥§©£œ¤¯¦¯¡Ÿ«©§¢ªœ£© ­»§®±®¡ª¢£®žž¬¦—Ÿš¡¢›Ÿš™¢ª¢šš££•–“Ÿ¡–œ–¥¬‹Ÿ‘‘Œ‚Š€zš”Œ‰}Œ‡‘Š†“˜‘‡”£Š‘‘‡™“ˆ}yl}vyxb{zrpqsxj‚ujƒgchansŽmbjp`oB]ykV^NQQKIMSYVM\^mWEXaO^PHMDF;7HEKO<rhJK9AE;;==;;=J49B<3;G<4?18-78;2(09/,5..=-*L>*49&'.34.0+/4&,:$40AhZ13S=e_DL6KVdN)=3R]=#‘—«˜Ÿ—§£¡Ÿ§£·¯®¢¯°©«¹Âº³­ ¹¯«§³ºÇÊÈ¿·Á¾¯´¾·Ä¶Â²°º±²À¶»¾·ª¹¸½ª¤´¦¨ª¯­¹°¨˜¸¼£­¾´³¡®¸µ§¦¨°³ ž¤¥¨¡¤™ž¬¨¨ž ª¯§ ¦—¢¨ °¸Ÿ£±¯¡«¡¬¤œ¦¦©šš›Ÿ¢•œ›™©¦–›ž¨—’˜“™–¡©š‰‡}‡~‚|{¡Œˆy„†‹Ž†‰“šŽ‰•Ÿ‰•ƒŒ–‘}…|tp|qst`yxjopqpjsdzlhedbf‡€`[rjqMN€iXZMQLKHPRQHM\_oTEYZRgOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23/:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%53=fd24M?e]FO=RZgH*?0][5(•›¥˜œ•¬Ÿž¡¤¡·«°£´´©©ºÅ·³® ¸­®¬°µÅÇÀ¶¿Â¹°´½·¿»¾°¬¾°³¿²½Â¹ª»º¸§¨µ¨§«¯«³°¥˜»¶¤«ºµ®ž±¸¯©¥§¯²œ¡¤ ¤¤¡–›¯¦¡Ÿ£¨¯¡ ¢“¤¤¢·°¡¦±«Ÿ¬£¯—œª¥¨Ÿ˜š£“š›™œ¥ªš››¤””—•œŽ“—¢¨¡‰Š†zƒ}ƒŠyŽ—Š‡z‚ˆ„‰…“˜ŒŽ–™‹Ž–†—Œy{prvnot_xwemlljj„ofrikfh^dt`[kviZJ^\XOOKHHRUG39]^lQEYUYeMHIEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<"8R=*113>D5,-'42*;+139cm74GAf[HTDU]hD.<2dW,2”¡¡—”œªœ¤¡¢ ·ª® »¸¥¬½Å´±¯£µ°¬¬®µÃü³¿º·±³¹¸º·º¯®À³´¹°¿À¸­½ºµ¥¢²©§©±«­± ™¿µ¤§µµ¨ž²¼©¨¥©°¬™£§œ¤¥”˜¡±¥™Ÿ£¨©œ¢Ÿ“¥ ¤¸¨¤§®¦ž¥¡¨’Ÿ¨¢¡¡™›Ÿ‘š›–Ÿ¡ª›š˜ ”“–™”“£§¤‰‰Ž†y„z„…|‰Š‡z„‡‰Š’…–““‹–””|ƒ—Ž‹w~|ltrllsawuiijggo†hhicfii`jcjh\f{c`StT\[SLJGIOS@!*h^jMDWU^`KIGEC.:B<F<6KPD8:D357==895?:;4>8@K=>93)8><:9*6@3.E4(+,?0-N?.+-7,1195,&.5-80576`tA3CDg[KWGU`hB379gP'2¢¤¤¦šž£´­§ªº¶§¬ÄÁ·±¬£¶®§®®¶¿¾¼²Á·°®²¶¶¸¶¶­ª½³®²±½¿·®¼»±¤Ÿ¶ª¥¥³¨ª­œÀ«§¥¯²©¬µ»ž¨©«±¥˜ž©¦¤‘™¦¬¢˜ž¤©¡›¡œ–Ÿ§µ¦°ª®¡¡ž¡” ¦Ÿ¡ š›™›’˜œ“¥¬¡—–œ”’•—‹˜›©Ÿ‘ˆ‰‹ˆx…v‚‡Š‚‰}…ˆ‡†‘„–”Ž‘‘‘Œ’{ƒ•Ž†s}}fxokjkfuskcgddvcefffjjcks[_Z]mdaNiXZ`VJGHKMSX>9_liHCUT][IHFFA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A=-5B37=+*,0B*JK./*+3722(57$+7.72685]yN2>HiZLZJVbf@:3BhH%5š£ ‹¬¡˜— –¤³±¢²½¶¡±Æ¼º±±¤¶¬ª®¨¸»º¹­À²®®®¶®²¸³©¬¹±¯®³¶º¶°¸½¬¦žµ©ŸŸ¯£©®œ¢À ±£®°®·­µž­®­­¢š¦©¥Ÿ•š§¥Ÿ™¥¢¨šŸ›”œž¬¯¦º¨®¢¡š›ž™ž¤š¤—ž—›“˜Ÿ’¨•ª§š“šš’Œ•™””š©¦ŽŠ‰Ž{tŠ˜…‡|‰‰……ŠŒŠ’„”›“’–Ž€ŒŽ‚p€~fymhkifqrk\hcctbfgjnlgjjhn]lltpaTcidfZIFLMOYQPVaeUAWSYTFHFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24;6#3*)6.55465Z|]19Kj[M[KXdd@A1JfC'4‘¡›Ž°žš“¡š©±¯Ÿ¹¿µ ´Â»½º±¦¶¯¨­¤¶·¶¶¬¼¯¬ª«¶ª³¸®¦³µ²®©°¶¶±³µº¦©Ÿµ¨œ¨¡¨¬š§½˜¬£®¯µµ¬¬Ÿ±­¯©¢›œ¢«¨œ”œ¦¤šª¢¤–šŸœ›¤ªªª¼Ÿ§¤ ˜š™¡k¢–™œp‚•š£u‘©§ž””ž‰—™€–Š¡y‡”Œƒmi~vƒql†‹†}…Œ‡p^cag„˜…k‹”’tw‹„~ƒg†€guheW\hsnNPjcgs…h_efnmj]`aŠ„„fNKD9GTg^JGPPUULHSaptfF[QUPFHEC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=A@@=28@E=1,+08=G601.*.*/568,#1'214:175Xl16Ok[N\K[fb>G1Qd=*.‹£™…•°››“ ›ª­ª£½Å¯©¸Â¸½¼­§¶°¥«£¶²±²°¹­©¦¬´¦¯µ£©¸¶¶¨§¬¶²®´­³¡©Ÿ³ªž £›¥¦˜«¹”¥¥¯³·­®¥©­ª¬¥¡žœ §¦›— ¥¥››§¦“ŸŸ˜ž¨©¤¶°¤£¢–˜——£ˆ Ž’™† ‡“œ ¤¥ªž’’š’ˆ„rxŽ…ˆ¡vˆŒi—ˆf}sx oˆ‡ƒ~Ž|¡  ™€|‡žt‡Žu›Šl‡ƒlheczlqaS…mbli˜qXiqpˆX^i[ll[ˆqnzr…g†„Z^GN?G_MERVVQQRWUg^MWIRRPFGG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82).1<I9/01.*/(-4583%&2115>1<8Xƒu25Rk[N\L\g_=K1Wa70(Š¦–ƒœ«œ™˜Ÿªª§ª¿Ã®±º½·À¾ª¥·°©¬¥²´®¯²¶ª©¥°­¥´³œ­µ¶µ¦§¨³°­²§®ªŸ±§Ÿ¢¢™¡¡š­³”£¥¥µ½¦¬§«ª¬¨¥¡ ˜Ÿ¦£™™¥£¤˜œ¤©–”£œ”“£¤¦¡·¤¤ £˜•“—’œˆ¯—”‰©‹–¡œ…±€£¬“™”y‚Ô¨€‡•Á›Çyx±¥·—d€Àœ¿y„„y‘„|‘Êr—¼œÅzrµ¦»{€l–±«°xhkX±®nei¼’¼ngzorØ~Skc¶²r•tš¡ªWOWbPVNFU[XQPR\W[QA]DQNEGI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22BE/.32.+/)-/186- /416A1=:Wƒw21Tk\O[M^g\>L1[]41!Œ¦’€§ªŸ—œ¥¬²¨°Â½±µ¿µ·¾Áª§³¬¬©§®³©¯µ³¦§¦´¥§¸¯œ³²¶«¥¤§±®®°¦ª§£°¢¡Ÿ–šžœ­«“ž¢Ÿ´º¢ª©¡­®¥¡šš¡§Ÿ—›§ Ÿ˜ž§§‘œ§š”¡¦¢¡±£ŸŸ£––’—’™…¯kjŠª~fƒ•†­dp”™¦”q®¡¤~x»}k¡v±_j´[¥€eœ‘`f‚{fjxk©e¾rg¦Œu±j|±xt’“cmm§n[„ Ehf‡–Euœ`~g|¤§‚Z_‹«i€•xyj§7J¯\XSld[KNX_\WV;N‰PWW/ITSJDEF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3..53/+/(.0.:5/'$203B/=;U‚v2-Vj\OYL_gY:M5_Y30¢•‚¬¨¥ž£¤ª±·¬´½¿¯¶Ä²·ºÁ¦©°«®¨©¯®£°º®£¤­²£¨¸¨ž³³°£¥ ª­¯¬¯¦§Ÿ£¡¯›¢š–•–šš¬¥–›¡Ÿ´³¢«œ¢­­ š— ¡¨œ˜£Ÿœ™¡¦¤¢™—¡Ÿªž¦¦ šŸ¡–•‘–š…µ›µx…©™µ™v†³›·~“––©”k¦{‚†ˆ’”’w«gk±\«z†”t‰r†€ˆ—x‚‚‹˜‹ƒ „°vwŸqkkl|‹N¤XHbb™~ch¦`yruS“‡^P©mcq~‡€bœ.Q¡o[Skh`LK[dX\ZB?²yXXA#MhFCDA@A19>88:84;:9<9:A:E::;6:CB8=?KNG:5:AFB@AD<FD;0201;F,0.940,.(/3,>831/2-D1<<S}n3+Xj\OXM_gX7J8aU50•Ÿ•ˆ³¦¦¡¯©§³¬©»¶Â°»Â­¸¶¿ª¬­­­¦­±© ®¼ª §´¬£«µ¤¦²³§¤¢ž§ª²¨°§¥žŸŸ­•Ÿ˜”••—« ™™¤¨´®¢©©¨ª›•˜ ¤§šžœ¢Ÿ› £¤£•›ž—™¢©›¦™œœ¢ —“‘““ƒÕ“™¹p°Á~Ɔ|֔›»|š•¥¤{Ž‡¤‚¥‚z¬yV¯zˆ~Ÿj¹[ºw‡„}¦‚“|˜z©x{±nŽ„t‘¼…o”P¯§ÅŠQ zc`ªbsrˆm—ˆ`Sµ´È†€‰|c¤3Bv]PjidP@XgZdaJHNnN\ROYfYCD?E?0=<59;74<;8=:<C:F:;>6:@C;6@OLH<:;DHCBCD<EF81211DC./0483+-(.323971#%5*>3==Qwj6*Yi[K]O_fT7G:aQ71%›¢”™²¨¨¦´ª¥´©¤¼·Á°¹À±µ´º³µ§±¯¢°²¦Ÿ­¶¨š§¹­£¯± ³´±¡¤žŸ§©°¨´¨¤›©•˜—•—•– ¨œ™–§­°©£Ÿ­¢¨–ž—›¡¥¡˜¡¡¡¡š¡¢¦›ž¡ž”™›¦Ÿ›§•›œŸ¡˜‘”‘ˆ²nhµq«‡nŽ¦r´sr¶{š—¤‹£‘¡¥~°vƒ‘ÒÒv\®{…¤o›ª¦k‡…}­}—™Ž{°r’Žx³e–t„žožf”RȋZÂ\Ÿyb_­`vs‡b—ˆ^Yʝo¿uMKµSUÆdTQjcfXAOk`lhPUHI9=VRZWXIC?J<2?;5=<46>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>HI91746A>/.24252-).26,742&60;5:=Pqh9'Wi\BOT_eP5G=aM620¡’¥°¬£«¼­¦´¦§¶»¼²º¿·¶³¹¹²¤´³ ±±¢ž«°¤—¦¹­¤±°œ´¸ª ¦¡©¤±¨¬©¤™›™¦•“—˜’’¡¦Ÿ•’¥ª°¦¢–“­ ¥’” ›¤¦Ÿ•›¦¦¡š¢Ÿ­™ žž•›¡œ¦•–š¢Ÿ•˜•‘›…¬{w¨v£ˆ†©o­Š‚§ƒ˜˜¡‰’š‹¢“™‰®…‚³\r³R®}‚‚¤rØ~x†~…ššv¯†‰‘œ‡w´ašeš‚‚”l’Z°XKšu˜yf`­^vwˆh˜ˆk]¯w•žxl5yÈ®²_BTo^g`EPm_pmVVM.fdiSXQ;AD@L:5?91=<16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK97<46:>/04333.2..18*.32%!03767=Pke>&Vg\@>V_cN6GC`I:99Ÿž” ¹°—´Â­¨³¨©²º·³¸¾¹·±´»µ¤·²Ÿ³¬Ÿž¨¬Ÿ”§µ«¨°±«­´¤›© Ÿ¨¡µ¦¦©¢™”£¡“’›˜‘”¡¤š’¦­¯¦¡•™©Ÿ¢Ž‘¡™¨¥¡•™¥©œ¤ž¬¡ “žš¡˜™›–—¢ “—¦ž†©}}¥x¡Ž‚ªp­‹§†–Ÿ¡‰——ˆ£‚‘ˆ”ª|€‹xo±Z¨‚‚ˆ ytـwˆt¨Ž›’¤|–Ÿ„{²^œd ~ƒ•l’\«[Z“€‘hgªdr{k˜‡s]«Z‰ ŽkoeOJC¡\[Lt]bgM[a_rt_KV7J›”XGE=GFAM35A8.;>05A78@<6=<F?:<6?=B7.HVJEAH6KIN@IK@EN::@4.;>102144+*05/7,&21($$6671<PeeA&Uf[?2U_bL7FI_C2?8¢žšš¿«˜´Â®«­©¥´°·±µ¾¹¹²°¶º¨º´Ÿ¯¤¤§§ž“ª°©¯©µ¬ª¯¡˜¡ ¦¤¤¹¢£« –›¡Ÿ”“ž™“—žžŒ‹¨°¯§—›¨¦ŸŒ’£—¨«§•—©§žž £­¤¡ž¢”¡˜Ÿ ’ž—œ•ž¡•–Ž«œ®mr´s©‹uŠ§s´xs³€‘¤£’œŽ‰¤‡w¸oŒ{‹¢jk¶Z¡…e——i ¢§n”r´t“˜²j…’ˆ­ku³af¢o‡“j—\­_M¡|‡‘Rs£ly~o˜‡q\¯V<œwfTon.\§OcSkebmZc]ap{cTZR>>mo3CB@?L9!7@6.;@37C58??3;<CDBJFMIF62JTKEBI6IJP?HNCFP=<E50;;010/75,+,426/#00,,289/9N`eD'UdY>/U^aL5FM^81C8¦››»¡›²À¯­«¬§·©·¯µÀ´»¯®·¶ªÀµ¨© š¥£¡œ‘ª©§µ£²¨®ª —œ§ ¥«¹£­›–™Ž¤¢•Œ ›˜œŸ‘“”ª¶°¨™”œ¬©—Œ“¥™¥­£‘–ª²¤Ÿž¦«±™¡£™¢– ›–œ—¡“©œ”«™‡Ô’š»s°Ã€Ã†~Ֆ›¸xˆ˜Œ—‹Œ§ˆz£¶u}wv‚š²`ƒºyÀ|u¸cµŒ‡©}•¬©q{t¼ˆ§ ia¦Ž¯¢~Œt‡ª}¾os¼t²ƒuxŠnšˆqn¤t½^w}Zay¼kZV\jy^jaegcmxoZ\ZDA@s@CF+5G"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-7A9§šž¢¼¡—²Ã°­ª««±§¸¯¶Ä°¹°¬¹®­À±«£¢ž£¡››©¤ª²£´¦­¥Ÿ–šª™§¬¹£­˜” ¥Ÿ’Œœ¢˜š‘•’¯¹²¬•—£§§”–¤œ¤­ž‘ ¨«Ÿ›Ÿ¨£³Ÿ£¥Ž¨¡”¢šœ˜•£˜¯ ’”©ž„˜¶‘Œ·•x‚“šµwmknsoy…ŠtžÁ»½™z±¨p€s‘¹ƒ|††Œ‡|Š‡—|¤»¹½œuz´£tv—vt°u™žf†jµtrqw¶Œ^z}‰hƒynyb‹¬pu…X[§jEeZTf`c^cQhgqmuBNPMD;ZM?J3;0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITBKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>707LT_G'SbW8*O^]=+:VV'>;<§ž ¡¿¥–´Ã´¬«¨¬«©º®°Å®´±¬¶¦´¸¬©¡¡¥ž ™“«¤­©¥´§§Ÿ›– £¬¤¾¦¡ª–“œ¡š‘¡§¡“œ—“—”±µ·­™ž¤¤¢‹’’¦›¥ª›–©¥¥œš¡¨¥§¤©¡’­ž–£ž———ž¯¨”›¦¡j}i›¦x‡r}™Žtyd‡{½¾Àºo“ƒr•‡asjZ]š‰acˆŽ•k`€•cmwb•k€š•”e^`cpšŠhr‹}…•gj~rux}~b[wthP\nƒ}|‹kXk{‚rJJo†pNtMEX]gaLZXgc_O[nuirRPDEN;HI=M?2,2A?8/5?C<9;@;=C>RVVWYZ[\\]`aaa`\UG5DFUEJOHFPIIH;8=51:.0;:.0-76=5&"/*2,%;8-7JR_I'S`V4)P_L(3>[O'?2>© ¨¢Â£›µºµ£¬¥®§§µ±¬È«¯±©³¢½±±¦ ¢¨œ¢›™™¬¦¯££´©¥›—•¡›¦­¨¾§¨¥”“›•Ÿ™’—¤¨¨ž‘˜œ°²¿¬›§ž§¢‰“‘©š¨£šš¬ £™›£§¬£ «£š±›”§ –”Ÿ—°¥—¡§™›œœ¢£˜¥¡™›™™™•gm}qw’—”’…‹µªŒ…—•ŽŠŒ˜–‡”•Š„“”‘‰Ž’”˜”˜–š ¡šœ” ‚z¥†lj|‘|€uŠŠq‚xyvvŠ€|Šjsuƒuew}wkozm`c]phMXZfj`WZpznmfTOFS9OZMRO(+:KB635=@A9:C><ENSSTVWXYZ\]`bba_^^[TKCSGKNDGPLOI<:;389,2;820)6IRO8")+/2#4;*7FO[J&R^S10T^:+=8\K,<-@³¡³¢À¡¤²²¶ ª¦²§¥°´ªÈª¬¯¤´¥À§³ ¤¤œ£•• ª§¬£¢¶«Ÿ™––Ÿ—­ª¥Áž«£•‘›——’“¡ž¡§“’™¨§²Ä°š««Ÿ—–¨ª›œŸ­™¡›¢¤¯§¢¥¨Ÿ®˜—§œ™š žœ¯ œ¡¦•—’—“Ÿ •¢— Ž–“ŠŠŽ—®|–›ƒ’‚‹ª©…€˜—‰ƒžˆz„‡†š’ˆ†Š–›—‘˜£–š“‘Žf¡³¯…Š„v{’Š}vyzofy€‰kuzˆris{vƒ‡‚kudyf`jecdfkYl{pij\SLPD^TF@?>,4@F;45;>A;<?>>HNNOPSUVVXZ\_bca_^^]^]XVJKLBIOMRJ;<:786/2964.(&$-1./)+*7%+<(6CMMD/T]Q05M[17E4[G5<,@´ º¯¿¬«®²± «¦±­¢¬³¯Ä¯ª«¢²­¼£³›Ÿ¦¢¡œ™—¨¥©¦¤¥²´ž•”™™°¥®¾ ¬¢‘™™”‘”¡œ—¨œ„Ÿª«£´È´Ÿª¤«––—š¦©šž£¬”žŸž ©¯ª¦¤¬¢®›Ÿ  ˜¤žœŸœ¯£˜ž§’—–œ‘£˜—§œš—e‚’|e~šcyŽmik{’¤ªjdš—}g†Šeeih{Ž¡lh˜‘£wkj‹™£ž™slnzƒ‡zXe^†ƒ^m‹‰v\hsww’€‡‚nx‚x€smy„tvˆˆƒ|k‡Y^lud^s‰ik|qkc^RNXIdXAJ4>G7?FD71<=?AD;;DGHHILNPRRTW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%/*+'6*$;'/AJ[J/7ZO6)EY/DO2YC;?.=¥Ÿº¼¹¯¬´±ª¥¨­­°¦­­°¼°©¦£­®°ž¬– £¢™™¦ªœ­£¥¨©²­ž•£¢¯¥¶¹¦®£ŽŽš¡™“’šŸ™™¤•{¥­¢¨´Ä¸¥¢§¯Ÿž”ž¢ž£›¢©©’Ÿ¡ž ª°«¬¤« ª›§Ÿ§ «•¡›¥°¤—›ª• œš‘£–©—}½ƒˆr´r„†­hx¹Ä¸q“¢£z¥™˜s«‚|ËÀÀ»qŒ¢ˆƒŸ}–˜‰À½‚—ÂÁ|‚{’šÃÀ~l¥²nŒoÊz›w‘ƒŽvy€yqz‡pw…Œ“ynx”cf_yd`e‚c^thldcXLWIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^__`_^^^^___]\SMPGUNA??=6468276*&%#)*&.+*)109*#>I[L*#BP.#F[3PY/VAB;/8–£¹Ã´°°À©¨”£¯©°®­¦³´¯©¥¥¦°«Ÿ«˜š¢Ÿœšª§¢¬¢¥¨¤¤´¤¢’¦­«·³§®¢‘‘™œ¥’‘Ÿ ˜›Ÿ‡¦¬¤«­ÀÀ±¡©¯©—‘Ÿ¢š¡£ª£“ ¢žž­¯ª­§¤¤§¡¦¥­¨‘¤š¨­©šœ©›« ••¤• ¢–œ~Δxz¤y•–›_®^Ž§¢ |§–›s«ƒ€¯^cª{§‡… u—“ˆ³c‚«†¡³j„®t}—ˆ·a‚­Z£Ímu{Ú{™p~ˆ’v~e{ˆvvk|ˆn}†‘‘mƒarlph``yd\qhjdg`RTSW]KOC5AHDD8>6;@?A;=8@>??BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5477164('$!',&&/(&+360$7;SL+,-K0';\;L-!P@F4.1­ÂÀ¿µ´°¸—‘£ª§­³«¦²¬¬ª¢ª§¯© §›™¥—œ¢¯Ÿ ž¨§£¦¡Ÿ°¬š•§®¬°ª¨¬Ÿ”’›Ÿ¤“ž¤—§£ž®¥«°¨¿Ç³¨©±®–’›¢—Ÿ©ªŸ• Ÿ­¯©¬ª¨¨¤¢«’¬²–¥¢ªª£¦¤¡¯Ÿ‘˜¦˜Ÿ™““‘— q…Œ—u…¨†q±}žr¬~¡ž¥žwª‚}­œs­~«‡†Ÿv™’{|—~ªˆ¢Œ‘Œ~«zˆ”Ÿ€{­VœÄzo’Á}•muoŒmeve†oawnro‰Š’„n’‘fpuuqagme_oiingdXS]aZRSC9II@D<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;92478452&# 1' 1' '45-&7=WJ-<(>1)3V@F!G:C1.+°ÓÆƲ´ £Ž£¢¢¬¯¶®¨°¦¨ª¦­««¦¡¤™¡• ¥«Ÿ¢¥ ¨¨£Ÿ°¬—š–©§®¬¨§¨ž—”š£¡’” ­›¦¢¯¬¤¬µª¹Í²­¦®¬—•œ¢˜ž­¬— ™žŸ©²«««œ¬«¤£¬›¯±¢¨«®¥˜¥ª¨©°¡‘•¢¤™“‘„¤j¤u‰z©tz²p‚¦Š™Œqˆ š‡¤``R«„®ƒ›v­§††Ÿz™—†{f€£‰¤™†‚£}©~–‡®_}©U¢’z¢Ÿ€{ïŋr¯³³¹qb©¯ÂthŒŒ˜Ž‚nœ•qnzxypmgeerpf|ic]W`jXYULLQLCCAB;C@@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799664,&$" ('"+-"$.!3-&@DWH,G+56*1PKL# A9D4,'ÃÉÕÕ¿¡™«§ ¯¢ž°´°®©¬¢§¦¨ª«©¤¦Ÿ›¤ž¦§§£œ¬š¢¬¡£Ÿ¯¢œ›“«¤µ¯® ¨š–”¦£š¢¨Ÿ ¥œ°¦¤¨±¬¶È²µª¬©–‘œ¡˜Ÿ¤³š¡”Ÿ§¬­¥°›­ª£¢ª¡³­¡ª³°¡š¨§®®´¢’•¢¦˜š‘{ªlž„‡u«y|°o‚¤‹‰Ÿ––Ÿ”Ò¸´¸É€²_`”©ƒ¤‰‡ z˜–šxªÉtš¤•¨©‘“šŒ€œŠšÆÇxf¡‚¥sŸŽ‚}¯]p´b°uK£†m§G‚“dŽž’|q™•q|u~|n\fjsqfk^aYdm\_YINLKEDAB>A<B?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75685/)(%&%$&),4ENPPMFKJVF*L0/=-5OTQ;<F2,$§¤ÀƸ­¨²­¬¥¢œ²¸¬ª ¥š¨¥ª«©¦Ÿ¦¦˜ª£ ®«¦ ¬šž©¥§¶Ÿ¢—“©ª¶²­›¥œ ”¥¬‘™œ§¢ ©¦®¡¤§©°µÃ²³ª­¨“‰—¥š¡£®¥—¡•™œ¥¦­œ±ž¯©§ž¬£·¬¡±¸¯š®¦²²²£“–§¢™žŽ‚NxšŸz„£}ƒ¤„‡¦žœž“„¸{{y¹‚Ìƶx›¡‹Ÿ~š–—Švž˜Š¥˜¤¨°…† „¬}š”b¥l¤p„}–‚r¬`£sq€š`¼}RUtŽ’£–{~”“Œv|s†€q\nnxrjo[d_inbd^LLQTAIHFI:9K>B108866877-*5==?BDGILNPTVXYZ[\__^]__]ZZZYUSOH@882.,*.+*'&?QTVWWWYXXWUOUF<E3:P[T6?H,- ‹‡™©«¤«¹ª®Ÿ›¡¬²³¥ž •¥®­®«§œ¦¦š£§¡³¯¢©§² ™ª¥”¢µ¢¢•—¡©´¸¤›¢£’¡±™ž›¦¤¡¢¯®œ¥¨¢¶²Ä±­©­©‘‡œ§œ¢¤œ¥—ž˜šš¦¤«›°¢¯¥¦˜¯¤»¬¡¶¶­œ´±·°±¥—œ®Ÿ£œ…ÑµÃ·y‡Ž…‘“€¦x”¡wŒ ‘„¥Šqª†…´nrj™£œ•Šž|˜™†‡s¯‚¥›¢¦‹“‹–›mq²]¥s“z›k™{™|m©a£qqŸbs²¸hw”¦˜}Ž•y~yƒnjyiyro€u^eeomfg`J[XX<HH@U4@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^__][ZZXURRQF:2230/++(@QRTUTSTVWWXXWUUVTQOQ[U%!2AH$)%“sŠ­¿¿¼º´ž–§¥­µ¡¢™•£¨¦®«¬™¦¢Ÿ¦ ¡¶§£©§±£”¬£Ž¥­£ššª³³¤œ¤œ©‘”—®ŸŸž¦£œ§œµ™¢ª¤¶«Ã°©«©¡Œ„Žœ¢ ¦£•ššœ™›™§¥¨™­©¯£¥›­¦½¬”½°¬ž¡¯²¹ª²¥š¨°¢§—y¨}|°wŠ€¤¥ˆœm²o ‡­|¡ƒ§•˜€¬‰…®…Ÿ”ª ¡—†Ÿ€™•€{’~«€š–‹«x ’Š”’z¯^£}¦§c€|—sj¯]¥kp…™]`[Œ m•‘¦™ƒ–Ž™||„˜€knctn€zagfqnhghCZa[>KU3U8BBC7$$3+''3, /6674359@CFIKMNQSSSVZ]_a``aa]][ZXSPONI8052.*,ATVVVUTUUUUTTUTTTVWWXVUUQHFIJ#((½“šƒ©Æ¶Á³Ÿš¬ ­¸¥£Ž›¤£Ÿ°°ªŸ¤Ÿ­™Ÿ¹ £« ¯©š®¡«¨¤–‰›®°¬¦ž¦›¬——¬¡ ¥¡™¤œ®˜¡¨§·©Á¯¥©¤ž‹€Ž›šŸ¦ž’•š›”›š¦¥¥›ª¬­¤¥Ÿª¨¾¤–«©¢ «²¸©­¥Ÿ²­§¨—v¯~‹œ…‡}º­Š™e±e•­} ƒ¦•š¬Š„°…¦š¤¡¡‘… [lj³`­{{ƒ±mgo™˜Œˆ±[~µ]¤„kÈ¢dŸ€{¼XvµY²}R®€z¬X€¡m˜¨›Œ˜’™˜|zžeuc…xt€|bjgqmgefOVd\AU_>I(>:=4!",%2. *1/04579:<ACFHJLNPQRTWZ^`_`ab^_\[XUPNJGC553./@UZXWXWXXWWXWVWWWWXWWXYZZ[\XWWGB;ҟ³±·½º³Á³£œ¬¦¤¶¨ Šš Ÿ³³©Ÿ£ žµ™ ´¨ª¬ž¯­ž¬›•¯¨¢Žˆ›Ž¯¬¨§¡¦™®’˜¨™¡¤Ÿ™££¦™ ¢ª³©½¯¤¨ž}‹›–¡ ™’šœ’š˜© ¢š©®¨¦¦¢¥©»ž Æ¦¤¨ ª´´«­¥žº¬««”€©’£¯Ž›‡¤—™‚€¸ÃºƒŽœ’„§—œ‚¬Š‚¯ˆ§œ›¦ª~սªb£¿½}~£‚ƒ×º¸µ…•“ƒž½¾„l£‚o«„lœz²°Çƒi«°½¬xw¢¾¼s€–Ž¦‘›’šŸ{‚’œ{d~|eŽgy‚{alekjcPa[Sj\?UbCN)=:4/$%2 $(0496678;>ADFGJKMNNQTW]a\__a^`[\YTQMHC?=A?5=SYYXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ¼•³³±¿¹²½²¡œ®¦¥²¦Œ˜¥¿ª¸²¨¢¿§§²œž±œº¨Ÿ­¯¦§””°¬—Œƒ›‘®¥¢¬ £œª —Š¢’¦§œš¡¨¢™Ÿ¡¬®ªº­¨£š—“|‡™‘¦›’‘˜˜˜”©›¡™ª©¡ª§ £ª»¨Å¢ ®£©³³©®¨Ÿ¹¦­­™suª¤·†d‰ ph®‘Šnnw¤™Ÿu®˜”p‹q•¨£›—®¤rmllf‹xon‚™qzjqigŠ—–˜qii…ˆgq†d]ˆbjoY\f}v¦_aqŽ‘nee“¡˜™™“™¡~‰‘–wgˆxiŽkzyelcflbKdXJlZ:PeER'K:+# ",)-2.5:457:<?ABDEHKLMOQSV\WZ\``a]][TPLHD=:AB7MXZZYYZYXXYYWWVWY\^^]\\\]^]^][[UW^©”¬³©¹¸²³ª©¡®ž£²©—’¾²ÄÊ¿·ªŸÀ¬­¤¡§¬ º£¤®¬®§Ž—®©‹…–—­¦ª ££ ‘‹¤’¦™¨™–£ª –¦¦§°»¬¬š›“’{„–¥˜‘‘™”Ž˜–©– ˜©£›±¦¢«¹Ÿ¯Á§£²¥«¯°©¬ª¦¶¢¬¶•Š ¨¥¶‰–£™‡ª›‘•’©²™š£ª ²–¢¡Ÿ¢œ¡¥¡•«§’’Œ‡“œ•‘™“™‘Ž•†¥›˜–Ž‹””‹†„}g‰~t‚us†Šp§lz”‘“’•¢—š™¤„‰–sj‘wqŒxw|zjmdcodUaY@j\HcaOY+F=+'!750.!%2(*699469;>?ABDEJKKMPPQXTVY^`ac]^UQJED>9=@ASX[\YWXXXXXYXXZ[\\^__`^^^__```_YY`¦–¨ª¥´¶®®¢°£­Ÿ µ±Ž¬Ç¾Æ»¹«£¥žœ¦Ÿ±©¤·§©µ§¨‘˜­¢‹‡‰œ§•¬¤Ÿ˜§žž’”£–§š¨™”¦¡¤›¨™¡¶»¨«™šŒ|”‹¡”Š•‘–”˜¦Ÿ›ªŸœ¶£ž§«·§®Á­£¶¥®¯¯«¨¨²· ­»˜‘¥¤¦¶¢’ž§ Žª Ž’Ÿ£¬¯š £¯¨¯˜£ œ£ªžžœ–«“™¡›”–«šŽ™™––Ÿ’‰¡ž••…’‘Ž•‹€}f‹…u†ux‡‚sœj…”“‰|‹•’’˜”£“Ÿ™¤…Šš‰|s—sz‹€s|jod^pj`[`YndP`ePZ:GGE>2=>9/*&+)&&416668:==?AACIJGJKLMSSSUZ``i`eVPJACB:9EMV[^^[Z\[[[\]]__]^_`aabaaa`bbbdb\[c—•£§£¯²¬®£©¦­Ÿ§µª¥µ¼°­­¢£š{ž£²¤¥±©—›¹§£“™ªœŽ†Š‰œ¢®ž¢•¨Ÿ ’–˜š­‹©–¨™©™©žº·¤¥™›ˆy”Œ›“Š•’”‘’—£žŸ©žŸ¸£€„¯µ¢¯¯t£½£±ŸwyŸ©°¹”u¬£ž‰€ªd\bv ¥Ÿ„—}m’³œ£§­ª¢ežŸ’syš—p€˜¨—m¢¨Šeœ¦’˜˜–Œ’œ’†žš–„’‡’‰…wjŽ†v†p{…`h‡Š”’‹Zu”ghs{¨œ›fzš‰„y™j„‹„oy€kre_vplkh[gfbbpS\>NNNSG>@UD91/&4:306678<;>@AAFHBGFIKMSTUY]`hfgWQJ<DG<8UR[`ab`^__`aa_\]__`aabcdabaaedchd^]f›•¦£ ®°¬«©¥¨®¢¦­¤’–«¶±³§›«§¬—tŒ° ¨«§”—¹  œ¤‘‰ˆ›ž¬š¢•§¡Ž–‘ž„u­ˆ¦›©‘—¤‰œ»´¨ ™˜‹‰uw“–“Š“‘‘”Œ”¡›¡§™œ²–€Œ›µœ³Œ’Ž»¦ ~§¢z¡­µ€Ž¥žƒ‹†±ª¯ŒŠ—¤›z€‹¬†œ¡§¨§‡•…˜w¥›z‡›˜§‚‚{œ²zŠ†¡˜š•˜–‚‘——…›™cz‡…’‹ƒmpŽ†y€p€„~…s…„•‘x–g’t šu}™…£Ÿˆ˜”Œ……škŽŽ†lx{qqgdxojlk[eljet\^ITLR@E5.ZUU6)!09=>743568;:=>>@DI?IEJLGSX[Y[aahfYQH9EL<>bV^bdfd`aa`bb_]`aabbbcfgcba`edcgcaahœ—¢Ÿ¥¬¬«¨¬Ÿ¨°¦¦©¥™”¯È¿±¢—¨©µž…¬œ§¢ ¾žšŸš |†™˜ˆ¬œ¢–Ÿ¡‘Œ“‰†€‘§‡¢¤”˜ž‡Ÿº²¨žš’Ž…qv‰•Š”›Œ’Ÿ’—¡¥–ž«‡Ÿ´‰´š­ŠÊ‡©­ˆ·…°®¬‚¨Œ¦˜}¨r{wœ§—h•¤y´ŒŸž¦§’˜Â«ˆ˜¡rž€š¥}—…•²¡}¡“ ˜—Ž“œ‹™’Œ}…“‡Ž–’‰ƒmr…~yq†€ƒ{ƒt„€–€Åf©‡£kž„¤„šŽ‡‹šq”…hxu|xhhvqhhl^dpmgmXgG]RM2D46Nbe7&3<EGD:64658;8>==?BM?NIJLCPZ]\Wa^il\QE=LM@JdX]cfhgbbbbcc`_babccceiicbbbecafcbbi”–¢Ÿ¯§¨¨¥«Ÿ£·°©ª¦š” £¤«¤—¦«¸£°¡¨¦ž‰”½š“¡’žy„––‘ˆ«™››™¢…Ž‹w›œŸˆž¥œ–š˜‡£¹®¥šœŒŒ~bm‹“˜Œ‘’ ” ¡™¡§~¡§‡­ –­žœ‘…€ Œ©­…£©™Œš£u€™”k‚­vM«x‡œ‘š¨§€©«}ƒ¡{z§jž’kg—†—·‰ž~n`dYƒ—Œ{dh‹s™}y–l]}—m_Spƒ\_kx‚_Xd|ƒ—p§ªkƒ£nr¥pŸ… jf m[oŒ}gZ`„€bXPowfmtskjo^kqmkiXiO^YF9A4HD_l5,ICRMN=84859;6@;;>BO>QRLMBJ\]_W^^bu`MD:MONTb\\ffiibbdbddbab`bdcacikdbddgdbgeach—• ¸ ©£¦¬‘ ¶»«­¢™˜¡¢¥­®¡ž¯µ£¨“¡  §œšŽ™´š‹ŸŒ•‹u”’Š§–•˜žŸ’……¬¤‡šŠ™©™š›’ˆ¦±§¢–šˆ‰€inˆ‡‹ŽŽŠ‹’Œ‘“£”Ÿ œ¡¤“£¡” wœ•§ƒ¡¦…§«ƒ¥x‰|„š~¢ps”ˆ–|Ÿym‡›Œ™›¨š‡{‚¢sv¦fž~w¤_˜z}“t¢n˜·´ºt“‡‚µ¨dÆ¸{p•¶Œr€š¤cs¬«`|i³~m|†‚‹˜q£lr£tŸ…¤`™³–q}˜Ÿ³us[ž²ƒjcotvqhoXkmsrf]i^cLE=D6RBZs3=SG_JR=<395::6D;;@JP?UMOQ@E_^[ZX``|dHC8LWUWcaZffkkbbeadc`ab`dd_`cknccddhdbgfchh“•”£·˜ª›“ ¤·´­­ š¢¤£¦®œ²®¬“˜¡š¡¤™š”Ÿ«›‹ˆ’x‹…q€–ŽŠ¡’”˜}‰¨ ‡—Ž‰’£”œ›‹©¨¥ž—‡…~j{‡~}ƒ‹‘‰”¡ƒ—Ÿ  ž‹‰wœ˜¢ŒŸr¡‹‡©ˆ›¥Ž”¦©}­Œ~z ™z£“xt–ˆœ}–Ÿ†›Ž˜›¥†¢d¡|ˆ–›mžh›Žoš™{€‹§}rht«ƒžƒtªh•š]›…v…gªk€¸f\¨pœ`•Œ^§vu‡ˆ~žhšt…“’—Ž€Ÿošn§š]¨~x»k~ª\Ž„]´g\nrzxki\qkyyc`fXbBQFO7WDSo5K[Z_OZD@151;;6H?:CHU>YRY]>Db^V`Qac}jEB9N[^YegXfgnmbbe_aa__``ec^bdoq`deekecihgki•›‰©´š§ˆc”›«º±¯¬ž¦œœ© Ÿ¯œž±©­—¤›¡ ™––¡¤™†‰jˆ€r{—ˆ‹––„‘•˜zŠ„•¤œŠ”†Œž’‰©£ šŒ’Š€i†y—Œ{‰ŽŽˆ—›”£Ÿ ¡“˜rhŸŠŸŒp’Œ©‡˜ž¡¥ž¦{°­£¢¸—w£³£¤€ˆ”y{ªš¢Žœš–ˆ—q¡|…¯µ}kš‘¡y~™µ£¤«¨„™|›}štªZ]o{–‹xžbL{z…cy—BLŸX¢jq{Žl€ˆ„™u›x†‰±³€›“§wƒns}•pštk¤]•vHed`tq~~nf`liv{ddbQ_X]UW@ZFQhESW\bX^ID=B8?A:IF8LEXAWR[VDFb\Z`K`m~rEC<U_bZfjVghmobfg^aa\]^ahb_ecvm]egfkdflihki“œ€°­™„S^ ¦³¹²²©š¢Œœ¬œœª”¢¬¤¢¨ ž›™–˜¡–ˆ‡‰w†oy•…‘›‹|‘“–ˆr€ˆ’¡›s‰š•¡›…©œ›•‹‹‹}ƒl„…q‚¡Œx†ˆˆ“™–|”¤¡ž¢ˆ­†}µ„Žžœ{¥–z©•›‰Ÿ›|§hwm~™t¡sr|†™p“ƒ®}¤ƒ¦™¤o^¨gu¢co¥aœÓ}{™xstb¢†~£s¤uk³Œ`‚˜‰sª²¨¼wƒm~¿¦©´]›n|p–mr¢r]¤gs¦`h¦m›Ôš}†›pz{˜lœ|x—sn©¤g`ezq€„lgfdouwgacS\fQQbIXJUaWS[ej[eQFDKMJKBKE8O@QNXSYOSQaeejRcwywIFEc]eZhjTihjocjg`c`\]]_hbahe|d^dgdkdjmghlh—š€°«T\K~©¯±´¯³£›™…™© ¡¤Ž¥©¡™ªŠš˜˜“™“’¡˜ˆ†{p}…h}ƒ”šw‰o…“’l—“|‰’“¥–ƒ«›”“‹†Šyƒvˆ€n‚Ÿ†w€’†ˆš£˜{”£¤šŸ‰³¡¢¶‹z¬§¤®¥p©€šŽ…€š{¤€¡™†˜rž„£®¯Š—Œ€¤•ƒ­ ”vµµµÉ¡s”‹Ÿ`—©my•‡ ›t¢‡w ~“—‹oMf£’pš‡s¤{ztaƒk} kqd_œq}s–hyi³µ´Æ¦s˜}zkœ›«v…›mvx˜jš{u˜rPE}³_jvky‡fkhcuupnW_TYiQShIVMYTV]hknVgWNKBJMKHJOAQKPecjmetss~y|nu‰{{TPOl^i\kiRjhilglfce`\]]^ibdik{_]dhcjfnmeile¡›ˆ®¦„e?“¡²ª®¯µ¢¢€—ª¢£¥Œ¥§ž¦ƒ›—–Ž—œ“Žˆƒzjy‡eƒ˜ yuˆŒi„…‘ƒŒ…z‹–¦“ƒ™ª˜’‹‰z}‹yp¡†z•‡‰– –”¥¨œ––„fnxœl¢d|q¥w›˜pg¦€•Šz¤zŸ–ƒ—rŸwŠ•—¹n‘Š¢b}™ •ˆmriªku mo¦_ši‹i–‡›•t¢€}š`Œ†uoˆbh ež~i›uocfˆ‚mq¢Z^[c¡m]ˆ‹nz}srd¥mx¢dg§h™sŒ™p¢oU‰o _f¨T‹^T˜nmskr‚mpilyskoRYWWfZTmIYO]IXiisjYkVQRFV\MXSaUik_wt{}p}|rƒ{€sv€„v^QrbgcpgPjhhklnhdg_]^]`jcjivu]\cicjjsmfkmcœ¤˜¥zdtm‹§®£©°±¦ŸŒ€˜«Ÿ¦Œ£¢›£¢–˜“Žš‹˜ŽŠ|‡q€‰i‹‹|˜œst‰}|d‚‡”‰‰•™‚|ˆ‡—¨‘£¬†‘‹‚Š~€€si¦„}†”ˆ™ ˆ“©¦ˆ¦x•›~¥ˆ–Œ²˜ž‚¯—Ÿ¥v”†x©s¥„šn¥¢Œ’„ƒ»n}¥¯ƒ†…†“•œŸ|¥zr¨• –fž~o¬c•Š–“w¨mª¢‰vˆƒw«‘¦ˆk‘°kv³Œ©kŠ†mmŸž’•`~«‹ªv~~‹¥žvŸ|ƒ¤• j›ˆx¬hž­Œ¶tw¾¤“Yƒ§Ž«aurtq|uqckohlSW[Vab]kM]R]J^mnw_[qY\`[gtenorbqt`wz~yryƒsƒ{{Œ‚€vbxdcnrdRkgholrjfia`^\bkbmlzo\\bibljxmglnb•¥ªœ€£–©ª¨¦®¤™Š‚˜¬šŸ¥Š›¦©…Œš‡œ‘…’Œt‡{‰„p…~˜”tt…r’ƒm‹‘‡†“Ž}{‚†˜¦Ž¦§ŽŽ‰…•v‚‡“ol‹©ƒŒ”Ž‰ŸŠŒ”«£ €u”—ˆ~y”®£›q†wŽ‰‚}{r§Œq}}z˜–›„y{~‡“•“Šv˜ž ƒ{}‰kŒ…[yyrzqin~’‰q€u”“q†„‚eŒ_€‹wtr”uoynn‡l„…^ugwŽe€€…¨š}t{•j‰ˆpv}‡wnmgŒsz|˜x…\kXyioxrroxxp]k‡njgV[`W]fkdVbU_Q_pxylkvfjklw}rrusaoubt{xuzƒu€€xŠ…ƒ}{mldyn_Wnghukxjije\`Zcjemqtn[[bldllynhloa”¸¨¦‰ ¢š¦¤˜¥œ«¢¡„„˜­’ž¡‰›§›©˜ƒ›‹–”‡ŽŠ‰rƒ|}~…{˜trƒp•…{|’‹††…y~€‡š¥Ž|¨¡‹†…•ƒ†Ž˜wr„©†Ž’‰ŸžˆŒ›¨Ÿ ªƒˆŽ•š~~‰–­¨‘¦wo›xn~¨…p}•qkp} €“ŽŒhm]ƒ‹‹›šžŽs•‹ˆqtkvtYrn†‘~~Œj]jd{…„‰€`ixzš{‚Šu…‚gwŠ†japqu^qŠ€ˆŽ¥”…e‹ƒnw‹„q†zqghe|„{–[\jgnv[|yxunssƒg\m‹kkbZZ_[Zlq\_aZ_]ft~{uptckkk|~s|xudmuhm|~vz|{yz€€~o†Š„{}s~yshU\qiluougkhd]aXkhlkqrmW[enlgszohjm`‹‹ª° ¢¡šž—ž˜¨£¢~ƒ™®Ž •ˆœ¢‘¥•{˜…}’™‰‰†‡Šs~Œv…Œ‚…—Šqo€r˜†ƒ~’ƒ„†Šz…Œœ¡‘ƒ§¢ˆyŽ—‰•‹‹œ˜„ƒz­‚‘—š•Šžˆˆ¡ªŸ¡¢£‹‡“›œ£™–ª¡§¦Ÿ’š†”Œzvƒ§~’’“œ²¦›•Ÿ²“—ƒ¥ŒŒ•šŸ‰›‚ˆ‘Šk|Žwxe‚†‹|‰„‡Œˆˆ€„„w|zt™ ˆ†‰‰„“~}Š€€uor„}w††Š¥‚…Œ†‚ŒŒ}‡ŒŠ‘„ymƒ…~z™krhatŠq~zwwpwt‚]^o‡hn_^Z]]ShrVd\]blhu{|sopdkkj€}ny€rjpplg{r‚€x}„{m‚†|yx{}zƒxNdvjrmpzekecb`[tfpfrqmU]ltmiyzqgikdŒ‡œ¹ž–¢ ˜”˜˜”˜¤ ž|š¬ŸŽ† ‹ž–}x”ƒ|Ž™Š†ƒ„‡nysˆ~‰”„mk~z—†ƒ‚€‡„†}‡…Žœž“‡« „s‹†’‘‹’}{ª„Ž“˜–œ–‡‡œ¥Ÿ¢š…‚’š™™š¦Ÿ¥•ˆu{†„¥{|Ž‘†˜«¡ž”Žª€Œˆ“™ž‚—~†Žƒow†qu`~ƒ†uŒ˜€ƒ‚†…~…„”nyut‘¡Š‹…š„„Œs‰||rqz‡‚zwŠŽƒ‘¦…ƒŽ€ƒŠ‰Šw†‰‹~pl‚|nhlmh_zi~|vuvu{x\_p~nu`c[]_RgnTe[^bkivz~qlmdkjh€lslluoyo†yn‡€v‚€~…vq‚ˆ~{z|{‚Š`i|juhi‚djc`i\cuhobumlUcqyepz{sejmm‹‰ž·š¡£Ÿ‘‘•—‹šžŸž{xŸ§‘œ‹‡¥”‹˜™yz…|‰‘„Œ‚‚ƒn|€ys…~‹‘}jh}‚—ˆ‡}~†„†}‚œ’‰¨€pŒ‹Œ’‡ ¡Š…Œ}¨‘‰’—“–“xŒ£  –™€š˜’Œ›£¡¤™—‘š}Œƒw‚Ž†Ÿ~ŒŒ|˜¥¡¢“š‘¦Œš‘‰’—›~“’~‡Žut‚pwa}€†q‹•|ˆŒqŒ‚…†hwqx‹˜‘–}‡Šq†{|pwzŠƒyyŒ‚”¥’‹…{††‡„vƒ„‰‰|gs}€y{qlkg_~sh|uvt}s€j^`tvpwdcY__RkiUeY_ahjvy‚qgkdmhf€kn}horl~y‡zlŒs~tv‚†|z}irƒnsia‡hlb_qVtomm`xhmWjtvcuz{rbjoz‰Œž²’¥¥œŽ—†œ ›|v¥¡Ž˜€£‹ˆš–y{†‡~ƒ‰‰‚r{tvƒ…~Š‘xgc}†—‰€‰‹y}€ƒy—‚–™——¡œ~pŒ‚‘”†¦›ˆŒ‰ƒ¦•…“‹–—“’w‘ ¡—“–yŽ˜—Ž–šœ¤˜’”šxŽ„‚wƒ•~‰Œs—£Ÿ¢“™¢Œ‹ƒ–˜ƒ’–™~˜Œ|ˆvq}n{d€|Š…p‡“‘‚l‡ƒ‚€‰…eun{…‘—‹|“w‹ˆ{…|zq}wˆ„x„ˆŠ—¡•ƒ‹vˆ„ƒ‚w|ƒŠ‡xazy~txgmeajjwstu}q|bc`tnurmaZa^[leRcY`ahkvy†qcjcmeh}ƒlhthnpi€}‚ym†q€„ƒt|ƒŒ€}z‚ƒ~|mv‰ttmeŠljbbvV„ipn`xglbjvpfy|zq`rl†…œ­—¦¨žŒ—‡†Ÿ“—™~xª‹™z—‹‹˜y|Œ~|ƒ|ƒxty{t}„€‰‹€d_}‹”†~„†u}~Š}™…—•˜¤£™s‡{”’Š¦ŒŽŠ“¡’ƒ‘•—‘‹—Ÿš’s’”‰ž¦——Œ”•r‹‰k„—™z‡ˆ‰o—š¤”•‹ŒŸŒ†‚’œ’’•‡™ˆ|ŠŠzqykul{~‹~m…’‚”xpƒ~~‹€dqi{–—„~Œs‡ƒx†|uw|„{‚‹„‹“£xƒt‰‡}€tv‚‰…pa|vzq}obocd|cnovsxwstav`olumo\\_^^j^P]Ycahmt{‰l`ifjciwˆnflijmh}{woˆs€„„}t†‰{ƒ}z„}}Žrz‹xxnl‡jh_irc‡gqoewgnlayik}{xpaxm‹€˜™ª £¨ŠŠ‘†Š‹•˜~x¯™—}Ÿ”‘–“ˆw~|Š}|€wx€€put|o†}Š|a\~’†ƒƒs{€‡{’‰“’“¦œ–‚}}ŽŠ’¤‰ŽŠ˜›†‘˜”–ŠˆŒ’œ’‹Œmƒ‘‰ž™¢¡—•ˆ–m‡˜ƒf…˜Ž“zˆ„Šp–š”£“’‰‹™Œ‚}’’Œ™Ž{Š…‡srukpnu|Štn†Ž’qu€|‚ˆ|dply|™“}ƒˆs‰€s‡xn|…{„‹‡ƒ‹”§Œ{‡{~‹…w~qp‡„ehyuup|b_pakt^qj{yylspex]nlsmrX[_`ak[PWXecgqq‡f]jigbgqodigeiizwuoŽ…t‚ƒ{u‚ˆ…x…|x„…z‰w‹{{rxƒjk`pht€kromrgole|cn€zwqlwwŠ~¢—¡¨ ¦›‡ŒŠœ‡“v‚«•“Ž‡¡–“t|w…xyss{†kspzn‹w€ˆoq[Y~‘ˆ€wu€ †‘‹“˜¡•˜xŠ‰œŠ†’˜–…‰•™—‹‹ŒŒœ‰‚m‰‹‘Š–¡œ—”…—‡iƒ¢‚e„œ‰~‹ƒ‹w“˜’Ÿ“‘‰‰•~—|‘Žš‘|Š€ƒouplmop{…isƒŽ˜‹qw€u‚‰ƒyfrnu€šŽ{‡ƒy“yv‡soˆz„‹yŠ…‚‡š¢‡{ƒu‚‹wynl‚…ƒ^susqpyZ_qapk^pj}{qmmjlv`oojqmYYbabnXQTZfgcvp„‚b]kndbfk’n`gf`hkursp‹€uƒ€xu€‹€y…w‡†wƒ…|‡Œ{wŠjqc|c†|nqmtjholvx_qy|uut€ƒ~¤•š­ž¦–…ƒ—”ƒ vŒ ”“†‹›–Ž‹zrxt‚pr…tqvˆlpnvm‰wƒ~€nnUQ«”‡‚x€wrƒz‚¡‚“‚•”™œ“›x’{ƒŒ’¤š“Ž‰•™’„‡—™Œ”‹‰‡„Š|r‹…‰ŽˆœšŸ›•”“}h„›†g…Ÿ‡’„‘‚‰qƒ‘˜œŒŒw{’‘zŽ‹Œ‘–Œ|ˆ|€kvjnkll{az~Ž–‚vz€xƒŒ|yfsks†•‹~‡…z“Žpy„ov‹yˆ‹y‡|‹„|{v‚‹}wpjl‚„{ayqnmstV_pbra`lnzqhpffsthqkawe]Wfa`rSQO\fe]ypˆ|`\irbbef‘j_he[gp~plqtŠ}v|…€uu~Œy{…xˆƒs†…~Œ„|y•xfrkƒ`ˆ~ookz`jntu_t}y†xts…}x ™°œ¥Ž‚Šƒšˆ€Œž€‹š”…ˆ˜„wtwt€qp…tpr„pkiwnƒn}}nusRM‚ßȒ֓{puƒu„ ƒ”w–’™œ‘™{”s…Ÿ¡““‘‰“œ”†—–‰Žˆ’ˆœŽwzŒ~‰ŒŠœ›œ›•’yŒuf‡†k‡¢„‘ˆ—ƒ†cŒ‘™•‹—ŒŒŠ‹qz”ˆ{ŽˆŠ’‘‰y…|~l{espkkzy[€yz}~†Ž{zgrjrŠŽ‰…„|”Šk}~m‹~Š…|ƒy€Ž”™™‰|uwƒxrmgq€…nkuphjunT_oepZ`lrxgkkbfxrppc_w``Vk_^vPNKagc]zqŠu]\evabeedafbYissnkrwŒ}tz†‚uv~‹s€†{‰r‰ˆ‘‹ˆ|~˜vesn}eˆ~npl€Ylnyytav{{vrwŠwyŸ‹›®›Ÿ‚…wˆ•~}Šˆ† ‘…Œ˜„“Ž‡txpyqo„omoseeyq}mz}jhkc¤šÁÜ®ð¡rlv„v…£†’o—‘–¡–œ’r†‹£—‰Ž•Š‘–ƒ–†Š€‘Š‰–~‡zu‰x‡„Žœš˜™Žv‰um…ˆŠ|‰¢ƒ‘‰œ„…^‹“—‹‰‹‹…‰m{–}ˆ…‰‘†v…}}k}dxujnysWˆz’‡…y~€†Œyeri‰Ž‰‚~‹–„kum‡Žƒ}x~”’˜trw‡Œusqgvz„cunqcjwhRaqglV_otzard_h~prnZcr`bVnY\xNMLdgb^ws‰n\\dy^`de…`cc_YjrknkswŒ~tw„xw{‰qƒ„}~ˆ{t‹‰ˆ–†Œ~—sguryl‹{ntqWqzvyrewy‡Œiv€‰rœ‡˜§œ£’…}qŒ”xyŒž„…¡Ž|–€™‡„{rwptjplim|u_axw{qu|h`d|ëÚµÉÃ܇rltv‹›‰Žj™–”‰q…‰ Ž…‹•ŠŒ˜”|“ˆƒ‰{‹…vxƒ„rˆ‚“œ–”—†Œu†}nƒˆ†˜¡‚“Œžƒ‰aƒ”‡Š†‰‡‡j}”€}ƒ„‰Ž‚q†~qwhvritwkZŒ|’‚…}ƒ€„Š‚uarj‡€Š~~‘|mkw…Ž…‘‚{€|~‘•ˆnpyŒ†ukqlsy‚`ujo]kw`RerifS`pvtap`]hƒqsjWghbiXmV[uLKLeg_bss…j\\ey^^dg{ad_]YkneojtxŠ~ss~{vz‡s…ƒ|‡vwŠ†™Œ‚{“ulwvyx“tnxz}Xz†q€ogyw’‚dv†…pŠ–…™¡š¢Š‡to“‹rwœ~‹š‰‰| „™xrtnodrifmxx\_y{{qq€jafaÕ¶Ž‘¦xnqw|q“‘‡kš‰œ“Œ†{i‡‹™‡’‘†‡˜Ž|Š|Œ}‰„ztzƒ{q†€–šŽ“”ˆuƒ…u‚‰‘œž†”Ÿ~ˆb“‡…ˆ„Š€€ƒg}‘€~‚Œ~m‚|‚tkmwutwvkcŽ€…~|…„‰p_qo„{Ž‹{~‡ypƒey‰†‹‚zƒ|~’‘ƒnny‹~umnkl{~diljYnwZRjsibQcsxlbe^Zjƒnsb\h_dl`nU[pNHOge\goq€mZ\cs`\clwde]]Zllcmjsw‡qp€{}tx†x…‚|€ˆuy‰’–|‰†v‰pxy{„“on|w^ƒt‚mizs”sgsˆ|r’‘ƒšŸ› †ˆvv•mw•˜~ˆ„Šš}Œšv~vqpljau|gbjuz[`x|zmqecggW_qs–¼Ä„wq”Šs˜Œ‡”ˆtkˆ•€{”Œ„›Œ|Š†}|‰Œ“ˆu‰…vv}qu†ž•†”‚‚q‡sƒzˆ–›—†“œ€ˆf}“‚€†ƒ‰‰r‚~g}‹{y‡‹}i€}ƒvfoyxswsljŽ…ŠŠx‚„„€k]pwz}‹ˆ…{€Ž}q€hx†Š…ƒw‚z–‹Ž‹|mkz‰|vtoih}we]qcXptSTosibNhtxfa^]Xo€otYec]jm`pOYlRDThbZlom{oY[^mcZcpvdg\]`ljclisw‚qn~{tuƒz„‚|‚†v~‰–‘xƒŠtˆsyy~oo{qiyz~nm|v–kjx„tk”…ž˜ ™…ˆo~Œvjy™‚Š‚•—Šz–ozspljd`t{i`fr{[as}zgpzaedŽ±²wKbZ¥Úїr{’Œ‘y–Œ…™’†ol†’‘zy“‡„™Š|‡yx‰Š„•€oŠ‡qt}{jy†ƒ¥‘…“ƒn~‚u‚w…™—“Š“”…‡p{’„~ƒƒ‰ƒoxh€…xrƒŠ‡|e|~„vcps€hyqou™Œ†ƒŠ{vx€„z‚k[o|r‡ƒˆ}…ˆzˆq€mp‚…ƒ„qƒw˜‹ƒwmm}ƒvzehj~raZx[YrnNXrsf`Kmwub^[[Yu}rpXh^fjq_oNWiR?Yg_[pkgyq[[YkeYcqy_h]^elhfliqx‡om}up{€ƒv…‰—Šq‚q{†|zy„”Œukzlo~t€}or|{”po€yf’Š‚¡˜’ƒ…g‡ƒpgz—Š~€…‚šŠ|ixrkkf_aoym_boy]dlƒzaqv_deÕ뾋2:>‹Ž€ry†‰w…˜“nm…ŒŒu}…‚•‰|ƒxnv‡…ƒ–wn‡„ku{ueyƒ„§ŒƒŒƒ}msu‚x„š‹‘’Œ‹†~{’‡x€…ƒl€ri€~xm|{Šƒxby„qdqh~muqu›‹…~su}€r€oZk|sxˆŠ{†|‡wypk†‚Ž‚‰q€w~•ŠŠ~tmjv€€uu\iixqZW~SZreL[srf[Jqxp^[ZY\uuiYb[genbiMXfQ=^f]^vf_uq[YUodZeqy[h^`gmgikipx}Žmj„yn€{}‚zu‚Œ“…p€‹nw~{{ˆ“‰i{}kt|r†{sw}Œzx„~|kŒŒ„›–Œ‚€l~khŽ{~ƒ•‚}Šˆkuqgic[cgso`altahp‰zast^bc› n\5Z¯µuj€Š~“†w‡˜‡uŒŠxpm…ƒ‡ty‰x‰}“ˆz~rgvˆ~}—oq†}hvynez‰…¥‡€‡‰}m}u~{Š—†“—ˆ‹„‰|‰q|~…|i~mk{yjzv‚‡€r`w‚~qdrgu‚mu{†”‘}owy{t}lWm}usŠ€†w†u‰zwrmˆŽƒq}{|‘‡ˆznmim‚‚un]hftrR\|N\q\O\sodVKsykXYXY`q€ua]]`gdhhfNZhNAad\`va\umXXSta[eosWj_bhkgmlipw|“lh„‰}|p~~|‚zw€€‰‹„r{‡oqw„{‰ƒj~{nxywŠw}x€‚‡„~~zm„Œˆ˜£…„{v‹ykm…‰’y}{‚’€€}Šƒprpbf^Yg_pp`ahpfjo‰tato[`djv{¾œ§¤É¸r…„s“}yˆ”„t‘ˆrsp„{ƒsu†tˆw”‰yypcw†y€’ir„ufwvcj|„ˆž‚€Ž}q~sƒx~Ž‚w•”ˆ‚ˆ{‰‰lyzvhzilysizv€ƒ}h`xˆ}jjsh{€jvŒ‘”~z}~q{v{s}aUu{qsˆ‚{‚p†‰wwoo‚‹}|w|{t„uhqhlˆ‚rp]hctoLfvL^oUTYsnbQOtybSWW\ap‚s[a]heecjdQ[qIDdb\dq^\xhUWVw^\fniVl^ajgennhpwz“niˆŒy}r{~y‚‚|v}ƒˆ†ƒpvƒsmw‚‚~‰‹”q€|xzz‹tƒx‚„z€uo}‰‹›žˆ~†{w‡|hu†‘z€|‰†„v€gpn_d\XfYmsaaaqllh‰n`siX^cm€w©Ù©Ç†ˆ³rŠypŽv}ˆz”‹€utu~wppn…t”†xtl`zyˆŽeqƒogun[m}“€y‘’}wzl…t~Šƒr•ŠŽ‡……{†muvnhwem|vmjwv|`bx†zhuuc~{gu†Ž•|tuq€z|l~YVr|ot‚†~wkˆ†sxjt‚‚|y{wzqŠ|rgtdm‹„mt[k`vfIooL[cXWVxmbPSuvYQUW]`r„o\`cmdc]ocT]rGBf_^fi]Z{cRV\u[[gkaVk``nfflqhpvxtkŽŒuvx}wƒ{t~ƒˆˆƒoq€uqu~†‚‰‹{wx„|}…‡x‡|}~…€{~svx‹ŽŸ‰{Šwuƒz^~‡šy‡„t†‡„w‰zbnl[b[[aUjtd`[hopg‡qaqfW\ck|ÊΆ¹¢knn‹mr…r~…‹{’†zytzuu{jlvc„v’‚vog_|y‹ˆeq€jjqcXl{†œ‰ƒ‚r—”v}{m‡p€‰Š†p–Žˆ…‹„{yrrp~ghrcnxqjlqw}}z]ez€wiuyf‚vgt‡‹”}r†jo~€xm{\Xp}ls~‰{mn‰pvfv~€~€uzpys…{xqer`m‹ksXk_y]IplNWV_TU|kbOTvsQRTV]bt†i\`kjfbYnaXcpGAh]af_\V|^OVeqY[jh]Xga_rfjhqgqsw‡yn•Št{w~yƒ‡€us†…Žƒpp|xwuy‡†‡Œ†z|u‹~}†„„‡~~}‡|xvyv‘“Ÿ~}‹nu€zd„ˆ—†s’Šo……‚zƒudnjY_[]]Uhse`YdrrgrakdWZ_ix¾®zŸ·nbt‡it|rz„‡{~€xxswo{wejo`‡uŽsjb^~xxŠ‚ep}hkkZVow‹¤…q™’qwtl†r“‡Œ‡„‰…}yusoiyajmamvjgkkywzw[g~|xes~n„tfv††•o‹fkz‚tltb[nzjszŠzet†}mpgt~w|~pzjyz€xwoelal‰}lnVkaxVLklOROiNY}gbOUvlMQTU^fv„g^aqhgaWi]\kiJEkZbeWXUyZNWnjY]le]Zec^ufleqfsptxp™…vx|…‡}vt‚‡€•ƒnsy{{ss…‡ˆˆ„y}v}„‰Žƒƒ{~‹ƒ{w|wvš—zŠƒ‡jv~}l„†”€r‚q†‚~‚€pflgW][\[Sepe_XcruivpdebW[[hpors‰efzjuvtt„…x…zwtunkzqbhkg†tƒmf^_|oz‰}hmwfjdVWspŽ§}„|v–s{r{ylzzƒv—|‡†ƒ‡„}uqsmhu]mi_ludgfizo{rYgwuhp€x‚vbw…‹|”n‹jm{€pere_kxfqu‰z}auƒvikqtzoxxr{e}~~wunceal†|mkVjcrTLklPLOpH^{eaNVueKOSW`kw~f]gsie_WcWbq]LKkXdbUTUsWMYveZ_l`\[ce_wgmbpitoq~ut™w€x€†„z}v‚ƒ~˜…nrt|{tq……‚€z‹ut€}”Ž€…„|~Œ†z~v{£¥Šy‰†…lu}{u„ƒzo…sz…}‚„unjieV][[ZScne[Xbt{jhmh`aW_Zi€ikoglbi{zktuuo†‚{}vvnzhjyj_eniw„geXbwi~†ynioff]UYpi¨wz|Žxuo}nrtxŽ~w”t…‚€†ˆvjsvhio\me^ns_gbjxh{m[mƒstjo€~ywav…„y†sˆqoyqbph[mvcpr‡zwar€ogixsqkwvtub‚z}vuoccbm||kkUibgTLnhPHRlEaxeaMTs^JMUYelx{f_mpjd]V`UooWJShXg^XMUlTK\z_\_k]][be`zhlaoovnowuz—}w€y€€‡†zyzƒ}“„qtt~zvt…ˆ}|ls•{‚Ÿ…‡}€~†‚€Š{v„¬Ÿzˆˆ„lr‚zv‚tn‡o}€tŠ€jonddX_ZZZUbjg\Z_u‚i^ml\aV[\keqt|ij]mxwhuxsn†|~~zvslzhixg]dshzw’ccTdog„vvfhiaWVYhd¨ox€‹Žzpo{fxnyŠzvŽqƒ}†ndwsdii]lb^po[g_muezh]t€orkq{~uvbu…‹{ˆˆ€wru~s`plXprappƒ{scq€k`lzoigywtpdƒtyytqdadmr~jkTi^_ULucQGWbGcveaLTqYKLXXglvzeemqfcZX]XwfTJ\cXiXXHWeQIbx[]_m[^]bc^€ik`otxmonvƒ—yr€}‰Œ†~uv†x†Œ}tuu‚yzz‚ŒŽ}„‰jt–{Š}~…y€{~|†‰sq®Œ{{‡~fqˆzt~}vro†l{~mzcpobe]eVZYWcfk`]]s†iXpm[^WZ\l{bqwulb[ntuhuwrn†yzwootehte[gufvv’z`]Sefj‚s|aci\TX^bd¥iyt‚…xlnxfwl{ƒytˆr€x|x€ifwm`ha_k`^ukYf]oobze[w|knnpxyttesƒ’ˆƒˆzvoq|qawcZno`op€{req€d^muicfxzrlm€tr|rqa^emn}eiThYZUNy`RKZYHbtc`JUnUJLZVilr{cllscaZZ[aw\TKc]YjSVGYaNHjvX_am[[_bc]…ihbnxylojvxm‚~€’ˆ„vu‰t‹†tqvv‚w}}~Œ“~px–ƒ}™’y€€xy~sˆ„sp™¢{{‰–xdu‰ysyvktply|p‘r^po`gblT[ZWidmf\\r‰fRrm[YXW`lvdjuji_[nurmtuuk†}€|wonleiqc[krdtvŽs\WTd`q~q\bc^SZa\d“Ÿerq„ƒskjxlnoyyzq€vszz{dfvh^c[ah\^wiWb^phawa[|vjjroxtsthq‚•ƒ‡„urjp{levW[ilapqyseo~Z`oqb^io|kjr}qovio`[dkl{agTgUXRQw\SPYRHcsb`GVlQIPZVklk|emora[ZXYlpWSPfWWiSTFZ\OIsuX`dmcX`ab]Œjdemzxkoiuy…{k„}€„™}‚„y}ˆm†qovz}t‚‚}‹ƒ‚—tx‚“†Ÿ‰ut‚p‡‚uo¢—s{†Œ‡{fw‹on|pgxq{lsvsk^tnagfkS^\Vhbll[\qŒdNom\VWUfithctee]Zpvoqvvzlˆ}€}ˆwscekoa]nmdsxˆkZTVbcw||p„\c_cTZ`Zc—•cnpƒ„‰rjgyneruqzkytuoz~v_gsd\_WbdYaufV_`mdaq]]~phisqtquvkm…“‚‰|…qqfn{opnRZeidprusbluUbqk[^nd{dkt|qqqil_Xdijx^fUeUVPUoXRWTPHer_aFXkOIXTVnid|ikxkaW\V[tdSRWhQYgTSHZ[PNxw[_fmjZb`_^nbgkyvnnivv~~m„€~†—{‡Š~k“ˆrgt€{u€ƒ~‰Ž‹“s}Š‘…‡Ÿ†{†Œs€†s}‚un¤ŒsŒwxnz`e}qgztylmqwƒgd|mcfghS`_Ug`lo\^nŽhMil`UVSnfskfxde]Zrvns{ytn‰{wœ{zlbelm^`ojeqygZVX_lx{zoƒ_b^hVY`Xdœˆbkq†|wkjvl[upjyiurno{€sXko_Y^WcdXeqcT_biablZ`~kflsuomxvkh…Œ‰zˆmpeo{lqlbX_ggnrsr^ilSepdUbmaxbouztjnkj_X`fhu]dWbVSOYgSO]OOHeo]cGZjNJ_KXme_xhn~d`U^T]u[TS`gN^bUSJ\ZQZvv]_fmhXca[^Žqchjxrsmgvsyƒs‚ƒ{ˆŽ~|ŠˆŽynŠtls‚tˆ…‡‘„•z}Œˆ‘›„€|Œ„rstwqn““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~~~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’’’’’’’’’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’““““““““’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŒŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ>.1111/o‡„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDBK’š™™™™šzlnmnnqI,00//,I…ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ-h†‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR455553?“žœœœœweggggk<;ƒ€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}zzz|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‘‰‡ˆˆˆˆ†Œ‡‡‡‡‡‡‰’“’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†…………†ŽŽŽŽŽŽ‹ŠŠŠŠ‰‰†‚‚‚‚‚‚„ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z||{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘“““““Ž’’‘‰‡ŽŠ’“‘‹’ŽŽŽ…Š‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…Ž…Ž‰‰Žˆ‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰ˆŽ‰‘‰ŒŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰ŒŠŽ‰ŽŒ‰ˆŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{||}}}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹‹ˆŒ‰Ž‡ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz|||{}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒŒŽ‹ŒŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzyy{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|{{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{z{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}|{}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz||||}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†………………„„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰Ž‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡‡ˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{~~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““”””””””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}~~~~~}~~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••”””“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””“’“““’’’’“““”““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘‘’““‘“’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘‘’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’Ž‘‘‘’“„“‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘’„y‘’ˆs‰‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘p{wvˆŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽul…‡rx‡ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒxmuŽtv†ŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹ˆpbgxsou‚…ƒ„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxz}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzoq{xy{|{xw{xuwttvuuvwr\bi\bdkghklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkiffggghh`ctl^jngdbcbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__ac_\_]`]^Z[kskamtneYY_[XWSNMKKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{xvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSTPMJMNPROM[eokZistkRQSPPNNOMJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTtsuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMNXbhmnopqnSLOPPPONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKKECFIVcfgqnmhg]QNNNOOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEEKMMR_jmhnmmjhfcccZLJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:<>ET]_cilnimlljjkjg^OGEEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@:;><;;;;GV_npqkmkjimgXIEEDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnppsttsqrvxy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;:;;99:88;<979;;<=QeqrsolhXE@?CFDCCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqtsurqtxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<:79::979::78:999<Kn{qVA8:<=@A@=;;><=<@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyz{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>><==?@===?C;====<;Jle9:;==>?@A@??A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquutusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCDA?=>@A?@<\n@>DE??A:F_>>=;:=>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVppqssttuyz{||~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???BFD><<=@=8:;mwH8;:==A<Kd=<=<8:;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pprrrtuvz{}}|~~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC?>AAABA@YR<<=IMFFuwM788:;>>WjA;<<::;>??==9:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC@CsyI;]ƒz|wW<=?==>FhtL:=>?==?AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hloppqtuvy||}||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCEAHrykbƒ„ƒƒƒ€}^>@C@A=Jr{Y:=AEABBFHC=<@DDA@?>=@A>>>?<>@DGE@>@A?@CFECBBC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{{{}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@Fot}‚‚ƒ~}…vMACE@?>Y{€]?CEIJIIMMKECFGGEGEEEDDCA?@>>BFJJGEEGFFJNNKJIGGHKLIGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@EEhs}|„~y…rCDEDCWu†‡‡~XGHJMLNOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHHHGFEFFFDFHGEEHHFHFHFQnnpqruvy{{{z|}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJG`{€w„…ƒ„ŠlAAVt‡‰‡‡‡ˆƒWHLMLMNLIGGGGDGGGGFHFHECDDFEDDHHCCCFIKKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrtwwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLLN[|‚‚ƒƒ…††ˆƒVl„‡†††‡ˆˆ‡|PKLKHGFFDECC@@CCCCFFEB@>>@AA@BD?>?DFHDEGIJIJHHHGIIJJIHFJJJJIJIJJJFILLJJKKfopsrtvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKLLJTƒ„„‚‚…††„‚†…„„†††‡‡†ŠuIIFB??@???<<<>;:<AA@><998<<=;>;8;?AB@ACCB@AADDBCFHIHHHKMLGIJMMNMJJKKJLLSlpqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHHJJIe…„„„‚ƒ‚ƒƒ„……†‡ˆˆˆˆ‰ŒŽfBB=88::9878896479;<:8557789787588;;;=@;999=<>;<=ACEHJMLLGIHORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@CGIIh†„„~ƒƒƒ‚ƒ„†‰ŠŒŒ‹‹‰Š‹Œ‰T:8656766656773568:876565676768:67889;7578979876:<@GFIFIFEFPSRSSROPPRTeqqsttvy{{{|}~~~~}}}}}~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:=ECBe…ƒ€ƒƒƒƒƒ…‰‹Š‰‰ŠŠŠŠ‹‰ŠŠG566468874578567699776765:9:::;798987779:98878689;A=>>BA?AKLOQPQOOORWkqrttuvz{{{}}~~~}}}}~€~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897;B:=q„€ƒƒ„„„…†‰ŠŠˆ‡ˆˆˆŠŠŒŠ‰‰Œz><:8;<=>9::;8:;9:;::9;:9===>;;<=:=;9;;<;<<9:<8::::999<?<<ABDIJLKIKLWorsusux{{||{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<:89989:::;?>H~„‚‚„………†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒoO>>BDEEBA@B?@BA@>=>>@???@??==?B?AA?@?=@@@>?A=><;:;99;?=;<==AACABCAXpqtttvz{{}}{}~~}}}~~~~~~€€€€€€€€€€~REBAGJNOLIGK:8:;9::<=:;;==?@BR‚‚‚„…„…„†‰‰ˆˆ†††‡ˆ‰Š‹‹‹ŠŠ‹‰Œc>DFJLJJFGHEFGGEBA@CECCABCB?@DHDCECEEAFEFDEFD@B><@>=?@>?>?>?>>:;=<`qrttuwzz{}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>???=A@CCFW„‚ƒ„……††ˆ‰‰ˆ‡†††‡‰‰Š‹ŒŒŒ‹ŠŠ‡VHMMNLOJJKIIJJIECDFGFDCEFDBHIKHHGFHGEJIKIJKJCFCCDBAACBDCCDDCA=;=@hpsttwwyx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLKABBA98<>;<;>@?A>BBGGJY„‚ƒ……†‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒ‹ŠŒPNPOMOLJLJIIHJFDFHHIEEHFFELLMIJGFHIJNMNLLNKHFGGEECFFFFDEHHFCA?@Llptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?EGG=<@@87<;<=:>@>?@CFIJQ_ƒ…„…††‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒ‹‹ŠrNSQONMLMJHGEIIEJHGJJIJGGGKLNLMHHIJMPNPNMOKIGIJHIDIHHFFGGIGCBACUnpuwwyzxyz{||}~~~~}~}~~~~~€€€€€€€€€€€€€€TDAABGHB?8?@8:<8=>;=A>?ADHJLUqƒ„„„„…†‡ˆˆˆˆˆ‡†ˆˆˆˆˆ‰ŒŒ‹ŒŒŒ‹‹‹‹`TTROONKJHFBGJGLJFKOLKJJKMLOPNHIKLOQQPQOOJHJJLJKFGHGFFHFEEBABB\orwxyzyyyzz{{~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<9@>>@BGGAGKLPVy…ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹ŠŒŒŒŒ‹‹Ž}YXTTUTOMKJDEFKONOWUQPOQSRMSTOMSLPSUVRSQPLJMMMKNGGJFFHJDDEEBECcpuyyzzz{z{zz|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?==B?BBGVNFNPPTX{†ƒ……„„‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŽ‹‹ŒiYWkaFTQQPI;;RSR`u]UVTVYYRXXRZfPUWZ]RTWQOMRQPPQKKKHHJHEFIIIHIirvyxyxz{{|z{|}|}€~}}}}}}~€€€€€€€€€~~SHJIHGFFE??AAEACGEDELXRMTUVX[|†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ}aŠ‹‹‡m\eU:YYXSQ?@VUY\d`VYbr]]W]ZVEQYZ[Y_TYgRVVXTTVTOOMJLJIILMKOMSosvxyxwyyz{z{|}{~~}~}}}~}~€€€€€€€€€€~~~VJJIHGEDDBA?HMIMPKIKPTSSXZZ\\x…„…………†‡‡‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~‹‰Š‹yopY[\[RTRVVT[ZuƒYU}a]X]^WIV]][[_YHYXY[]XXYWRQMPQMMOSQQURassvwwvxxxz{z|}}}~}~}}}~~€€€€€€€€€€€xy}YNKIIHFBD@A:PQQWXPPOQSTTXXYZ[n‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡„Š~gYY\YTVTWRQWVc–€QerXZW_hP`f[[X\gaGOZhg\[\]]WROSPPQVVVVYZnrtwvvuxxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZ[SSQORRRUSVTW_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€|\QVXURURQQLOMKfy[]TYUV]ZLTZUST^ZXWWWzkX[[\^TQQPINOWVX[Zdprvvttvxyy{{|}}}~}}}~}}~€€€~~zxwvsu{€€tk~~kry^[VUTROKFCDAM^ƒlVRSNOQOQURSRRUcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ynqVJLNOKMKHJDEIEC>TdURQQNKQTQMOYRMNQSUUMQSRPOMLHCIHRTUZ\lquuusswzz{{{}{}}}~}}}~}~}}~~€~{vsw}~~du}iqt_d]^[YVPLILIal’tPQSNQRQR[RSRQRUTbs{|€‚}{{€ƒ‚…†‡‚†††„†…†u_]LD?CCCCB?DPBC@C=CIGV@HNLG]iPHFNFDEFIGHCDHGHKGDBAD@OQMRdrtvustuz|{{{{|}}|{~}}}~~€€€||}€€€}vt{mh|gnqfiedb\XSQPURsWe[OOOLQSQUYSUQQTSOV`klrv{{xytrnstsyx~ƒ€ƒƒ‚€‚€‚‚kMG?@;;>@@??>kPKaEFHIEB?GLNGMQUIAE??<=<==?=?ACC@?<=B>JNGUnttustvxz|{}||}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QRZ\Y^JJPQNLLQRQTVTWRQWVPX[b]agmmlokg`nrjmlqu{z}{xz||xwxeC@@B=:BCBBDB\]O{NONNKLMOOQLKMWMHG@A<977599=;;;8989?<BH?\stuvuvwy|||}||}}~~|}}}}~}xuvz{zwyxuw{|yxuywcqhipmnmmhf^OP^\ZIHPRQOMPQNQRTVXSRYTNYZ[WY]^^_e`]^qvk^`gkwooljonnlfbYHFFHBAGIEEFDMRPaWRWQPSSRU[OOQVPMIDF>:96587979:365795<C>essvwwyy{}}||{|}~~~{}~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZXMLTTSPQUOLRSTWXTTXQLWYZVXXVXY]WXXhsk]Vaskba_^da_^YTQNNNLIHJLIIFCQPS[WTTNQSYS\eUOSSQNKIHC?A9998978857578599Gmqtwxy{{|}}}|{}|~~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnpppnmd]__YWOPXVVSTVOOTVXXYSUTLKTVUUUWPSUWTUR]n^RNY_[VY;DVXT[fJLORROMMNNNMJFQPUYSTOJNOUST\VRUSROMLIHHF?>=:787659967665Wppswyz{|}~}~|}}|}}}y}}|~~~}||}}~}|rvqxxrvuqqnppopuvtnjddjppqrpofedc\]RTZVWUTWTRXXYYYRUOJGOPOOMRJPPOPNNOTLMIPOSTU2=XMI@Q=caQSQPNPQPNNMQNTRPRMILKORPRRSTQROLMKLLHCBA=::876;B5566:doqtwx{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqptuvcjgeWhtrrqniihpVVTUXUWURWVUZYXWUQSFEAFGGHFJDHJIGEHLHKIFLMPMG/E_R>3?>joaRRQ@GUQPQPQNQOPOLJLLOPNNPQQNPOJLMMKGEEDB;=<<9=G6677Dmptuy{{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknaePSTRSTOWVVYYVQQQO@=;=?ABAC@BEDA@GHGHFFHJMLEGCORC8ENS]gSPSAGUPOQQPMMNMKLKLNOOQMOOMHLLIKKLKGFFED<AA>;@E;<89Sprtx{z{}||{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLOOMQSLTUTXWUMLKI<987;>@><=A@B=>EHGCFFIGJJ@FAA@FHEJOHQRa\QPROSOOPLLOMLMLMON[WKMQOGIHCHJLLJFFFE?BC><BG?B?Adpswzz{{|{zzw{wy~~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHDD=9779?B>;?B@@>ADJECGGIFIEBB?>=CBAGIENObeQMONWKLMKLMMMLKONSdNJLRIIIEAHJLMNJGIFBAB@?EFEHDKnovyyy{{z{zwtxux||yznqrmnorrvrsx|xvvmpmsputlpprooorvvrVVnqgly„jmqrnnjhoHJCGMMJMPMPOHJD?A=98::?B?<@BAADEGJFCHIGGHCC?B??@A>DECLNRTLJIMTGIIJLJKLIJLMOPRPKGCLGCBJILMONIJIGCCCDIJMLIYrmwyxz{{y|vrpurtxyvxjqnjllnttmtu{stxronqovsnporpopstyjN`gsjt|ygosqiqhdqGKDGHHGJKIJKDGB=>=:9:;AB?=BBCCGFIKJDIIFGGCC;A@B>@@CEDIMPHHKGHKDHILMHJLHIJLKM]RHHDNFADJJMMPMKMJKFGGJMNQNLbmivvwzy|z}rmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoiktgdoFKDFEGEFFGEGBC@><=9::;@C@>BCEEIEIJLFIIGFFDB;ACC>@CCCDGLNHKNHDHEILNMGILGFGIILNKIGENHCGMKMLOMMNMKHHIORQRNRfffqosxu{z|lhjoekqlspfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGJDFFECCBE@DA>?>:;;=:=>CA>ACEFJFIHLHGGGFEC@=DEB>ACCCDGHIGMPJFFGKNOKFHIFEDEIJHJIFHPKDIMKOMONOPNJJILRUUROWd`amgproryzgehhdilgqlflmgiklslpvutpnvrosrsutqssutsuvvvyvutwljuumrvqlnlerLHEEHCBABD=BA>A=::=?:=>@B>@BDGJEIFIHFFGECBAAFFCBBBDEEGGIFLQLIOJJLLIGHEGFDCIIHKJGKRMBNOMQNOOMNOKKKOUWVUSX_^\iaminhrsbeffdihfnifmmhkkmriqvusqmvnoqrswsrstuvvvvwvwvvtwujsunutsqrjksMGHFHBBADD<A@@C<89=>9?<?B@@@DFHEIFFHGFFDCECDIECGEBEGEFGGEJMKHQMJKHHIEFHHECIIIKMKOSNDQRPQQNPMNPMLMSWVXWUX]Z]d`hbjigk_eefcgggkggkmkmlprhttursnvoqprtxqssuvu‚‘yvvtxuuwxmouorsuqqinyMHGHHBBBFD<?BBD<7:>>:>:@B>??BEFDGDEHFDEDDEFGJEEJGCGHFHGECFJJGMKLKHJLFIIKHEKKLLNORTPHSUSPSOQMNQNMPWZVZYVZ]ZXa```^hec`dfhgjhhifhnllnmqpiuuxrrpupppruvpusuvu{~}xvtwvvvxplupmstnprrxNIHGICACHE<@EBE=9:>>=<<AB<?>ABFCECCHECEEFGGGIFGKHDHHGIGFDHKIGKHMKJKLHLKMKJNLOOORUVOKUWSQSQRLOQPOTYZY\ZY[^^^`c^\ackb`dghr…hgifjmnponsrjtuxrsstrnpqvrquruus~yŽ}uuvvvvxrhuqkrtlqvptMIKHJFBEGE<@GCD@:<>@?>?BA<@>AAFCEEDIEFEGFHHFHHIKJFJHHKHFFLIHHJGLLMLLIMKMMMOLPPQUVWOKVVUSSQQLORRPV[[]^[\^__a`ad]c`ef`ehjcssfjgglprqossnswwquvtsmoruorspurvrtvuuuwvuwtgtrkqrkrvnvJJLJLGCEDE<@FDDC;??A@@@CA?B?ACHCFEFIFIFFEIIGIHJLHHJJILJFJKHIJJGKKMMJJMLNNNPLOPRTXVMNTVTRRQPLNTSRW[^^_]]`_`aa`acebdhbdijgv‹ljigmosqpqppryvruutsmmssmqrotutrpswtuuwvuuteqskpqjrvnwKMLKMGDCAD<?EEEC=AACBBCDACDAAEGCHGHHGJGDHIGHJFILHIJMKMLGKIHKKNQKRQMSMKNNOPPOTOWXX[NSPW\ZRWPNTUTTXZ_bb_da^`b^`eaacinhcihhnxvlhimosrpqrrrvtsusssnksqmprotvrqquvuswywutucmtkopjqtowLNLLLGEA@D>>DEFC@CAEDDFBCEGCCIECIJJIIKGEKJGHJIIKHJJNLNKILHJLKZfJd\KlSHON_nUks[qpbwcSPavuhucav`Xnqbdvinzf[lt`ljT_wvijgifglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqrqyLNJJJFC?@B?=DEFDCDBEEDFBFFGDEJEEJMMKLLGGMIGJKHKKIKKNLNLLLILML[sbdp^lmUMNfs]gfqlntgpi_aYnnbppbkjjgoqtetno\ougpMJqyvkb`keemxlkvmnpsrprqpqrqrrrtrmmsnnoprvtqsstuuutwxvutbmukpplrrqzKLIHGED?AB@>CFGBFCFEFEDCHHGDEKHGLMNLMMFJNHJKJILJJJKLMNNMMJNMM[roonpplkMPQlWNibtrpamnu\YlQ\mmZqmkomxxtsip]_rkqjUuyxpc^kfbgppjjopprspqpqqrrqqrrtlmrmnnorutqtrtuutuuzvutenukpolsrryIKGGEEEBBB>@@FGBGDIEEEBFIHHEGKJGMMNKMNGLNILKIJMIKIJKOPONMLNNL\hdu]lqWlNPQmUZk^klvaldsSecNmYl\tpkilxjwuhp]^rkhWbcw|oc`ggadjuyknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtvHLFIDEECAB=BACGDHGLHECCHKHHFJLLFNLLSRLGLMHNJHHNHJJIHNOMNLJNMJZsppoqqmlOQRnYqkgooqqomt]nXat_nopoqronusttj[]tcwxrjnzhaacfbbjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyxtukoumtontsvsHKHIBEEEA@>DDBGDHIMIFCFJLIGFJMLEOJKWRKGKKJNIIJLIKJIHJMMMMIKKKSkc[i^_icrrZ_Yjo_eeUk_c[aaQ`lh]j\niid[pfdp]Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxtunqunwqrvtwrGGFIDEDFA@BFEDGBHJLHFDGKLIEFJOLIPIL[QJEHHKMIHKJKKIHIGKKKLGHKKLMMLJKMNT[\TPTLPONOOVQOOQNOQJINPQdqiTYW\[\UY[]X]\\cfaaebce__fkmhmtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyxxuvqruovrtsuusGCEGFFAEC@DHDFGCIKLHFDGKLHDGIPKLOKLWLIEEHIJHIKIMJHFGGIGHIEFLIJLOLIP\W^P\[`^MXYS\\b^MXZMXaRJYaZR_d\aX[ddVVX\YZX\VY\]b^d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstxyyxyxwxtqxrxsqrurtOBCELMBDCBEIEGGFKJKHEFIJKFEHHPJMMJMRIHEAHFJIKLJMJHFDIFDFGEEJHCJMKLU_Y`X`a[`TXYT^^Z_RY\P^\YN^\^SZ^c^Z]`c`Y_c[`^[TXWY^]cbbacehekrpoppnow††……†‚{€……††…†…uqprrsvyyzyyxxxwryvxrqxvtvaSJJMIDBBCGHFHGHKIIIDGKKKEFIJNKNLHLNGHE>GGLIKLKKKIGDIDCDEBFJD@JLJO[cY_^a_RTRW_`\]Y^QY\MV_WKQYZPZ_aa]^ca`bbbcceZQYVU\Y]c`__cdbhomnllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxXQKFCGEBEGIFGHHFFJGHGIKILDDKJMMLLHJJHJF?GGNKKKMKKKIFGCD@DAHIB?IJHP]aZ[d]_TQRX]\\\_ZKW\LR\YIM^QO\_accccb\dcbdcfXQUTR[WZ`_^^aa_dlkmjjlnv~uz|„………………††…†……††‚zrsuu{…‡‡‡†…„~xpzwvx\RMC@IFCFKJFFFHGFIFFFILJNFDKKLNJLIKJHIFBHIQMLKOLJKIGGED?ECHHABGGET]Y^X_Y_[]UXXO]]QKJV^X^[]UY`RQ__bb``bb`cbaddaXOQQQZR[]]]]^__dhgljnnp{{|~{€‚ƒ„„„…………„„…ƒ„…‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKCAHFDGMRHCQJFHHHEFKJMPEFIJKNLLILLHIGDHKQNMLPLLJKHICDAEDHGBAGEDWUE\T]SV_XOTUNZZMIJT`a[_X^^a]OYa\``_bcb]abW__TPOOOWQ\[[\\^`bffelfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDFFHDIRbPCV^IGGHDFMKPPEIIJKNLLLMKJJGEJNQQNOOMNLMHKADACDFDCBEFBMHBKKOONLFMFGIJHGLKMOPILOPOSOLPSRUZYWYXXdWOSTPPNMOTRZXXZ]\`adecgcklpsrzy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEHFGDKM]LGGXMHHJHGMLQQHLKKKNMUNOKKKGGKPSSNPONONNGKF`ED_LEfdEM[I^[rmOMUmYLDP`UkWgJ]XU^DLQULLSVQRTXWTXUT\UPfZhhdXRjRVUT[\[``abbb`fhfnkhrz|}~„„„„ƒƒƒ}|zr{z{‚ƒ„„……„…ƒƒ~z{LIFGFHEEKOSIJF`THIOJIOMRQKMLLORUROOIKMGHMQ[YOPPNOOOIJQQI|YYqtYQmHqnoaVPqqsPCksmqspSo_[nX]V\XUkhU]VcZ`Y[`VVXjtuu__v_Xa[[f[_`aaa]`bgmpl`pwtx‚ƒƒ‚}€vxzlv~tx}€|~€‚„|€ƒz~wwNJEHMNBDLLGILEQVLKNIKRXWQMOOMQTNOQPKKNGMPS[ZSQROPPPJHZx]TxehZSURvgtlpbnfjQrOMwmjrpsrqrpoo€]ezuxqqzq~s}ku}bRh|essosr{|o~xn€r_``baZ``gknkblfgmw~€ƒ~{xw€tvzir~ns|~wx{~€ƒx|€u|||ssNKF`]GAEMMHJKGJPOMMJNV^YULQSNYZMSSRNKOHQRSYWVPTPPPQKHgxlcxrm[KNVypumubnvPdeJfvqmwo€jfxxiWrQhzmijzz}lxzohoYvvjuup`rf}ilx|o^__ba[]cdgiidgbcdllppstsssyqrxblugqy{srvy~suzn|}ywrnNJSuNCBFPPHJKIKPOOOMPZ`ZWKTWPa^RVQYRLOISTUXWWPUPONRJLrouuquqdibWnLqp^FhyWvTLiy}x`y{sna]mocRhqunmypwlvttrln]t~zkmy|ktl|kpvux^__b^]_ddighee^abiiijknokqnmjpacfcowxompsy~nqpj{ztsomLL[VHGEGRPILMJKPQPPPPW\XUMUYUeXRRY^SLNITTVWYWOSNNNQHRmHiwK`dvvVXlOnl{sajgvULWkh}lmlx_[pz{^`zscroxqhd}ir|^TLl`vukiu{{m~xk|p\^_b[^bddgeeebZccikkrsrwglihdg`akagsrlgmmr|kmhk{tmmkmOGKKIJHHQPLNOLKRRROSRWRVTPW[VVTTTa_PNMKTSTQUVNNLMOPJHQNPULKLSTSSTPVUQQNQQXYRNPUTXXX[ZURSW[WXWZOSUWXXR^YW^VTPYRWWWWX^[gr^[[Y\]_cZ_ccdfdccbZccffemnmueegcaf_]g`dlhfgkhpzhggkujhgilQIKLMMKJSQMQPOLVUTPTUXUYUQZ]VUTWUYWOOKMVTQNUSNOMLQPKJRQKQMKKPRUSQRSSIHLNOQRQQQTVRXW\WSSPRTUVSZQNSRXVTYVTZVTRUTTUWXV]Y^`]\ZZ\\_c[]bcdfdddaY`acabhhimbad^_c]Zd\bma^fefmsdihkkedcfhPJKKOOLMSPNSQQMXWUTUWWWZUS\`VWVYUXSPPJNWSPNUPNQNLSPLOUSNQNMNQUQUQRTUNKMOQTTRRQVWUYZ[YSURTWWWY[TPTUXUUZUWZVSRWVUW[XZ_\UX^\^][]`a^[bbcgfedbX_ab]`gdfea^_]]^ZZ_Z_g`^]]bhkagfhfd`bcaPLMLPQLOTOOSQOQ[ZXWX[YXYV\jdVXYZWVSSOJNVTPOTPPPNLQQPRXTQQOMOSVOWRTUUONMQSVUTTRTWVZ]\ZVVQQVXV[[WQTWVVVYTXXVSRYWVZ^Y]_^U^\^`\[____ZbbdhgddbXa`b^^fcc`b]\\\\YZ[X[a[^]\_b__bdebd__`\PMNNRQMRROSTQOU\ZZW[[\XZ[dqmhd_[YVUWQLMVSMNROQROLPSRUZUSPPMQXWRWSSSXMOOQTXVUUSUYX[^][[VROUVV[[WRTWVWXVTX[TSRZXW\^Z^_`Ua\aa]`b_]`]c`cghdf`Yc`a__ed_`c[Z\[\YZYXW\Y\[`^_[^^a`^b\Y`ZQNONVQPTROUTSPW\\\X^\^V\^jqwy€c\[UUXQMOVSNQQPRTRKQTTYZWUOROSXWTSURRZOPSRV[VVWSVZX]^[[^VSNTUV\\VRTVVXYSTY\USS]XZ]^\```Va[cb]ac_\bab_cfidf^[d`a`acd_b_YZ^[\[YXYWWZZZa\][]\\Z]`W[[ZPOOOYPUTRQWRTP[^^][`\`U\]hjr}slg\TWWQNRZSRQTRTUTKRVV[ZZSOSQVVVTOWRSZRTTTX]WXXSX\X^]YZ]TUNVWW^[XRUUYYYUWY\UTW^Y]]`]bb^Y_[ea_dd^^cca^efidf]]da``abd`b^XZ_[\[XXXWW[Z\`\[[\[XZ[^V^Y]POORZP[TUVVTTT^^`^^b\`U]^bkytl}kZUYUQQS\TUTUTVYWLR[W][]ROUSXWWTPXRSWSVUU[]X[YUZ^X_^Y\YRWRYYY_[ZTUVZYZWXZ\VUZ^\^`a_dc\^]]eaafd^^dc`\gdhedb_da_a`bb_`^WX^Z\\ZYYWV]Z]^ZY[\[WY\]VXW]SOPWYQ\UVYWWUX__aa`c]_T]_beeuzhXYYSUSV\XWWVVW]XOU]Z^]\TRWSWVUSTXRSVTXWX]^X][V]_X__X\VQYTYZZaY\VWX[Z[YYZ[XV]_`_cbadd]b\`fadfd^_dbb[fchecfaf__aaaa`_^VU]Y[\[Y[YY][[[XXY[YZZ]_]TY]UNTYVS\TVWYVV\`abcac^_V[`da_zuohY\ZUWTW[ZY\YXY`WPV^\``\TTXPUWVTVWRSUWZZ[_^Z_\V__Y]^Y^USYWYY]bZ^VW[\[\[[Z[YY__``dccdebdYafcffe^ab`c^bcidcg_g^abcaa`^_XT[ZZ[[X[XX\[Z[WWYXW\[\`]V]]SOVZVVZUXUXWX]_badad`^YYadb`lfh^[][VWXY\\\_[Y[bVTX^]ac\RVYPWVWWWVSUTX\\^``]`\Wa^[^\[^XVXX[[_`\_XY\\]^^\[]X[`a^`ecdeefbXcedhgd^c``ec]eidei_f]cbcaa`__[XY[YZZXYXW[[Z[WXZTY]\Z`\U^bNSWYVWZX[\XWY^`badada]^Yacb_a``^\\\WW[[]]__\Z]cYZX]`cd_RXYPWWXYYWVWV]]^`a`_b^Ya]]^Y]^YXUW[\`^]_ZZ^]^^a]\[Z\`b_becefefbZdffigc_c^afdZiicfice^bbca``_]]ZX\YYXXZXWZ[ZYWXUU[]]]``bbxKXW[YW][\]ZW\]_`bdaba]`Xbcbacab][\[XW[]_]`_][`d]\XZbecaR\ZOXXZ[[ZWZY`]`bb`ac_\b]_][^^YYTX]^_`_`\[^^`bc]\X\^`bbcedfdefd\efgifcab\cg`\iibhied`baca_`_]]\Y\YXWXYXW\ZZWWXOXZ]acffrkJYW\ZZ_\[^\X][^_acbaa]b[bdb`bcb\[[ZWXiq`\`_]\ac_^YYcedaS_ZRYX\]]\Z[[c`bbc`bda`c^`\^^^ZXV[_^]aa`^[`abec_]T]``cddfegeffe^efhhgdd`[eg^ahhbhhfc`b`cb___]][Z[YXXXVZV\[[VVUMXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡…ƒ‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vvvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{{{{{{{{{{{{{{z{{{{{{{||||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vvuvvvvuvvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{{|||||||z{{{{zzz{{{{{||||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚‚ƒ‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||vˆ‹‹‹‹‹‹}}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰Š‚E>????;›Ã¾¿¾¾Á¢ŠŒŒŒŒ‰~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}vŒƒ~~†“y1333332j‚€€€{­éääääèʉŒŒŒŒƒ:23333.¡ÒÌÌÌÌϪ’‹}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}vxxyxxxxwwwwwwwxyyyzyywopppppprrrrrrrwzyyzzz~ƒƒƒƒƒ„|||||||vuuuuuu~ƒ‚‚‚‚‚€||}}}}}|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚ƒ‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vvvvuuyvvvz{x{xwvwzwyyz~|yyxxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{|||||||zyyyyyzz|{{||{|||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwwx}y{{y|{xwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwww{yy{x|zxxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒ„‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z{xwww{yz{w|yxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚ƒ‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzzw{yz|y|xxxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyxzyyzyyxxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyyyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰…ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„……„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„‚ƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{{||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}||}}|||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}|}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚‚‚‚€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrsuuttssssrrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqsttssrqqqponnmmmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqrsssssrqqpponnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wppopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrrrrssrrqpruppoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpqqrwtqrrqn‰†nppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqprp…“rqqo{ž~npppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqqw£pqq•Ÿ}oppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsqu‹‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqrsœ¨o{¢ž~pqqqqpppppqqqpqpppqpppppppppppppppqqqpqqpppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrrq”«›pƒ£Ÿ~pqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxwxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrsssssssr“±ª‹•¦{ssssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz~|~~|vvwwvuxzxxxxxxxx|©¯£±­¯Ÿ|{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~||||{«™¡´¤Ÿ©ˆz{zxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}}}}}™¡•£¯Ÿœ£š~}}}€ƒ‚€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€™›‰˜°¡ƒ€€~€~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~€€—¤”£›™‘ˆ{}~~€~~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~€~€~†¨¯¦ž™Ÿ¦©¦…€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹Š‹‹‹‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚ƒ‚…†š«¯ ›£Ÿž¢¤ª«¥Ÿ”‡€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒ‘‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒ„ƒ†ŒŸ«© ™™¢žžŸž¡ š†ƒƒ‚ƒƒƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒƒƒ‚‚†’”•—œœžŸž™˜“ˆ†‡‡††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ„„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““‘’‘ŒŠˆ‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„ƒƒƒ…„‚€ƒˆ•”—š‘Š†‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ‘’‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„„ƒ„ƒ‚ƒŒ›‡”Š„‚ƒ………ƒ„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘’’ŽŽ‘‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€‚ƒ‚‚‚‚ˆ‡ƒ‚ƒ‚€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„„„„…„…†’“‘ŽŽŽŽ‰ˆ‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~€‚‚€„ƒ€€€€‰‘€‚ƒƒ€€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“‘Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚‚ƒ„‚‚„„‚ƒ‰–ˆ„‚„‚‚€Œ•‚‚‚„‚‚‚ƒƒ‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘Œ‡…ƒƒƒ‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒ€ƒ‚……„„ƒƒƒ‚„Ž™‹ƒ…„„„‚€‘™†‚‚‚„„ƒ‚‚„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”“’’ŒŒŠ…„„ƒƒ‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~Œƒ~}|}ŒœŽ€‚‚‚…””Œ‚‚ƒƒ‚‚‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†””’”’Œˆƒ„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~–—‰€}}}}{˜Œ€ƒ€”Œ‚‚‚‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“’Š†ƒ„ƒ„‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€•ŸŠ~~€}‡‹~„„ƒ„‚ƒƒ‚Ž‰…Œ‚‚ƒ‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚ƒƒƒ‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†„…ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„‘¡ŠŒ…}†‰€~………„…‚~}}€‚„ƒƒƒƒƒ„ƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„……………„…†…††…………………………††…†††…†††‡†…………ƒ„„„‡“““’’Œ‹ˆ…†……‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…ƒ‰‘ƒ„‹…‚~}‡†ƒ€~~ƒ„ƒƒ„„„„„„„„„„„„………„…„†…………†††…†……†……‡†††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†………†”“’‘‹Š‡†‡†„‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„„„‚‚‰~}~…~€€„…„…†††………††‡‡††…†……†‡‡‡ˆ†‡‡†††‡†‡††‡‡‡††…„ƒ„……†………†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘”“‘‘‹‰ˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒƒ„„ƒ€€€„„~~€€€€……†ˆˆˆ‡‡‡‡ˆ‡ˆ‡ˆˆˆ††‡ˆ‰‰‰‰ˆ‡†‡‡‡‰ˆ†‡‡‡‡†‡…„ƒ„…††………†††‡‡…†‡†‡†‡‡‡‡‡‡‡‡‡…‡““‘‘‹‡†……„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡†…ƒƒ…„„„ƒ€€Œ‰€‚‚€€~{z€†‡ˆŠŠ‰‰‰ˆ‰‰‰‰Š‹Šˆˆˆ‰‰‹‹ŠŠˆ‡‡ˆˆ‰‡‡ˆˆ‡ˆ†‡†„ƒƒ…‡‡‡†……„„„……„……†„„„………†…†…ƒ‰”“ŽŠ†…†…ƒ‚‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡†„„…„ƒƒ‚€€€…„‚‚‚‚‚‚‚€~}}}}~~|{|ƒ‡‰‹‹ŠŠ‰ˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰‡†††‡…†ˆˆ‰ˆ††‡„ƒ‚„ˆˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚ƒ‚„ƒ„ƒŽ“’‹‰……†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„……‚€ƒ„‚ƒ‚‚‚ƒ~}}~~~~~~}~}}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡‡‰‡‡†ˆ‡‡‰‰ƒƒ„ƒ…„„……‡ˆˆ†…ƒƒ‚ƒ…‡†‡††„‚‚ƒ„‚ƒ„„‚‚ƒƒ„ƒ„‘’ŽŽ‹‡„††„‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚‚„„ƒ‚…‡ˆ‹Š†„†„‚††‚‚„„ƒƒƒƒ‚‚}|}€~~~}|}}|y|ƒˆˆ†„ƒ‚‚ƒ„†……ƒƒ…„„„„„„…„‚‚‚‚„„‚ƒƒ…†…„‚‚‚ƒƒ…„„„…„„†„ƒ„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰†„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„„……†‡‡‡†€…ƒƒ„…„‡ˆ…‚€€€ƒƒƒƒƒ‚‚€}}€€}~~}|}}{zz„„‚€€‚‚~‚ƒ‚‚‚‚ƒ„€€€‚‚€€€€€ƒ‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†‹“‘‹ˆ……ƒƒ„€‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€ƒ‚~~~~}‚ƒƒ‚ƒ‚ƒ‚~}~€€€~}}}}~}|zy|ƒ‚‚~€€~}€~€€€€€~}}€€~€€€€€€€€€‚€€‚ƒ€‚„ƒ†’ŽŠ‡‡†ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒ‚ƒ„…€€|}}~}}~€€}~}~€ƒƒ‚‚‚}}~€€€~}}}|{{{zzzz€€€~~}~€~€€€~~~~}|~€~~€€~€€~€~€…’’ŽŒ‹‡‰…„ƒ‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~~}~€€~€„ƒ‚€~}~~€€€~}}}|{{|zzyyy{€€€€~~€€~€€‚€|~~~~}|€~~€~€€~}€~~~~~}}}}…“’ŽŒ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒ‚‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚‚‚€ƒƒƒ€€~}}~~~~}}}}}|||{zyyyx}€€€€€€€€‚‚€~€~~~~~€€€€€~€~~€}~~}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…ƒƒƒƒ…„„„„„ƒƒƒ„‚‚‚‚‚~}}}~~€}}}}}}}}}{zzyyyz‚‚‚…ƒ‚ƒ€‚€‚ƒ‚ƒƒ‚€€€ƒ„‚€€€€€€‚‚€€€€€€~~||Š”Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚†„…ƒ„…„…†…†††…†…ƒƒƒ‚‚€}}}}}}~~}}}}}}|}}|{yyyxx}ƒƒ„…‚„ƒ‚‚ƒ…‡‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚‚ƒ„ƒ‚ƒ‚‚‚€€€€€~Ž“Œ‡ˆ†ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€~}}}~~~€ƒ„‡‡„†††…††‡‡†‡‡ˆ‡‡‡†}€€€‚~}}}}}}}}}}}}||~~~|{yxwxyy€ƒƒƒ„ƒ„„„——ƒƒ„}‚‚‚‚ƒ†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ…„„…ƒƒƒƒ‚ƒƒ‚‚‚‚ƒƒ‚‚‘‹ˆ‰‡‰‡††„††…„„ƒ‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€€~}~~€‚………‡†‡‡†‡‡ˆ†‡‡‡‡†‡…~}}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yyy|~ˆ–„ƒƒ„„”“€~~…‹€€€„†‰…„‚‚……‹ƒ‚……††„ƒ…„ƒ„„ƒƒ„ƒ„„„ˆ’Œ‰ˆˆ‰‡‡‡…†…„…„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„ƒ…„~}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|yzz{|ƒ‚ƒ‚€~}~~{ˆ‘||Ž–}‚†Š…ƒƒ„ƒƒ‰}ƒ„……ƒ………„……ƒ„……†„„Ž‘ŒŠŠŒ‰ˆ‰‡………ƒƒƒ‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚€‚€~}}||}}|||}||}|}}}|||{‹‘—Œz{|€zyz{|yy}}€€|{{~~}‚•‘„ˆ}|~‚„||‚„‚€‡ƒ}‚‚‚€ƒƒ„„„„„‚„ƒ„…„‘‘Ž‹ŒŒŽŠ‰‰………ƒƒƒ‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚‚ƒ…ƒƒ…………ƒƒƒ„‚‚ƒ‚ƒƒ‚€€~~}}}||||||||||||||}|||~~Š‚{z{zxz{{|}|~~~~~}}}|€}†}}‚~~€‚||€‚€‚€~|{Š‚}€~€€‚‚€€€€‹”ŒŒŽŽˆˆ‡………„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ…„††„„€†”ˆ€‚€~~~€|||||||||||||}|||||}|yz{{xxy{zz|‚€}~~}€‚‚€€€‚‘€€~€~~~€}}}{}}}|}||}€€€~€~~‚”’ŒŽŠ…††…„„…ƒ‚ƒ‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚‚„†‡††~ˆ•Š~€€€€~€~~~|{{|||||||||~}|{||||{|||zzy{|z}…ƒƒ€~€~€~…‚~€~~€…†‚€~~ƒ†}|~€€~}}}}~{|}€}~Œ‘ŽŽ‡„††…„„ƒƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}€‚„††……~€€€~~~€€€}}||}~}||}}}}}|~|}|{}||z{z|}}†…ƒ€€€}~}~~Œ„‡~}||~‚}}}}|{}|~„ƒ€~~~~}|~}~€~~„’ŒŒŠ†„…„„„ƒƒƒ‚ƒ‚ƒ‚ƒ‚€€}|||}~{{}w~vx~}|}|}~~‚ƒ€z~~|~~€~~~€€€€~~~~~~}~~}|~}~}}}{|||z{z}€€ƒƒ‚~|||}||ƒ~Œ~|{{}~}~~}{{{}|{{{{€†„‚„ƒ‚€~‚‚‚‚‚€‹Œ‹Šˆ„„„ƒƒƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€€€}€~~~~|‚}~}}}{{}}|z||~€‚€€€}}}|||||}|~{~{{{|||}|{{{{||zz}z~‚~‚„„ƒ‚…†……††‡…„‘‹Š‹‡‡…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~€€‚€~~€€~}ƒ||}}|}}}}{|~~~~~||}||}|}~{|{||||}|}|}|}|{{{|y{|{{}z}~~€€ƒ‡‰‰‰Š‰Š‰…ˆ’Œ‰Š‡……ƒ‚‚ƒ„„ƒ‚‚‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||||||~€€€~~~}€€€€ƒ‚€€€€€€~|z|}}~}}~~Œ†}}~{{ƒƒ}~~}}|}}}}}}|}{}|}}~|~}}}}|{{z|{||{z{{zzz{~~ƒ…ˆ‡ˆŠ‹‹‹‰Œ‘ŽŠˆ†…„‚‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„„€€€€‚~}~€~{~’Œ|}Š€Œ~~}}}~~}~}|||~}|}|}}}~}}~~|{{{||}|{z{{yzzxy{~ƒƒ„‡‰Šˆ‰ŽŽŒ‰‰…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{}||~~}}‚€€€€‚…ƒ„‚‚‚‚€€ƒ‚€}~€~|‰‚~‚‘„„ƒ~}|‡}}~}}|~~|}}|}}~~}~|}}{|}~||{|}zzyyyy{{~~€ƒ‡„ˆŽ‹‹‡…„„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{}}}}}zx‚€‚‚€€€€‚‚‚‚†…„‚ƒ€‚„~€}~~}~€€}~„€~~}~}}Š…}~}~~€~|}||~~~}€}}}|}||{|}{{{zzz{{|}~~€ƒ€‰Ž‹Œˆ………„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv}€ƒ‚‚‚‚‚ƒƒƒ‚…†„ƒ€€ƒ€„~~€~~€~}~~€€€}€~€~|}}|~~~~€}‚€|}€€}{}}}|||{|{{{|{||}}|Š‹‰ˆ††……„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚ƒƒ„ƒ…†ƒ‚€ƒ€€€ƒ~~€}€}}~~€€‚€€€€}€€€€€€~|}}}}~~~‚}€~‚€}~€|~~}}}{|~|}|||{|{|~Š‡‡…†ˆ…„…„‚‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz~}yxtt€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚€~~~~€}~€}}}~€€€€€~~€€€€€~}}}~|~~}}„€~}}}~}~~}~|{|z|{z€ˆƒ„„…„„„…ƒ‚‚€€‚‚ƒ‚ƒ„ƒ„ƒƒ‚‚ƒ€€~~~~~}~~~{{z~‰‡~xry}qzx{xyuu}‚ƒƒƒƒƒ…„…ƒƒƒ„ƒƒ„„ƒ€€€~}}~~~~~€}}|}}~€€€€‚€€€ƒ‚€€~€~€€€~~~~~}~~……€€ƒ~€~€~}{z{z|{z‚…€ƒ‚‚‚‚‚ƒ€€‚€€‚‚ƒ‚ƒ„ƒ„‚„‚‚‚‚€~€~}~~~~}~}}z{|…„{{sy{|pwuvwyutz„„„„ƒ„……†„ƒƒ„„‚ƒƒ‚€€}}}~}~~}~|}}~€€€€€ƒ‚€~€€€€€€€‚‚‚€ƒ‚ƒ‚€€|z|z|{|‚€‚€‚‚€~‚‚ƒƒƒ‚„‚„‚‚€~€€}~~}}}~}}{{z€x|vyz|qtxwvxury……‚„„‚„……†„„‚„ƒƒ€€€€|}}~€}~~}|~~~€~€ƒ‚ƒ€€‚€€€€€€€€‚ƒ€„€}ƒ„€€‚}z{{|||~€|}}€€~}}~‚‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxzzruyyvwwsu†…ƒ…„‚„„…„„ƒƒ‚ƒ€~€~€}}}~€~€~~}|€|~€~€‚ƒ€€ƒ„‚€€€€€ƒƒ€ƒ€~‚ƒ„€€‚‚‚„‚~{{||||}}~}z~}}x~|||~~~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„‚„„…ƒƒƒƒƒ€}~}}}€~~~}}€€~|~~~‚‚ƒ‡…~~€€€€€‚‚€€~€‚‚ƒƒ‚ƒƒ…ƒ}}}|{||yz{z~y{yx~{|{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst†„„†ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€}€€~€}~}~€€€|€€~}~~€}€€ƒƒƒ~}~~€€‚€~~€‚‚€ƒ‚„„†„€~~||||zyvyyzyvyv~|{{{~}{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…„ƒƒƒƒƒ‚‚ƒ‚ƒ‚~~€}}}|~€€€|€€€€|€~~€}~~‚‚~~}~~~~€}€€€~~~~~€‚‚‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{{{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvpxyrx…………ƒ„„ƒ‚„‚‚€‚€~~~~€~}~|~€€€€€€€|€~€€€€}~~}}~€‚~~~~}}~~~|~€~~~‚~~€€~ƒƒƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}|{|z{}zzx{|zz{xtxuqrtpxxqy„………ƒ„ƒ‚ƒƒ‚‚‚€€€€}~~€}|~}€€€€€€|€~€~~~}}|€€€€~~~}|~~|}€~}~€‚~€€~‚„‚‚ƒ……‚‚~}|{{||yw|ywxwwx{{{{|…‰}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzz{zxswuqqsoxwq{…†……ƒ…‚ƒƒ‚‚€€€€~~}|~}€‚€€}~€~€€}}|}€€€€~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{||{zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚€€}}~€€‚‚}~~~€€‚€€~|~|€€€€€~}~~€€‚€€€€€€€„‚‚€~|}~~z}…~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚€‚€€€€€€~}€€‚‚‚€~€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€€‚€€~}~{“z|}|{}y{zzxzxy{||}|||||||}}}||}|~}~~~}|z||{|}{yzzzyytuuooqpwst}…†ƒƒ‚ƒ‚€€‚ƒ‚€‚€€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€€‚‚€€€}~~|†‰||~{{~yz{z{wwy{|{}||||{}|}}}}|}|~~~~|z|}{|}{yz{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚€‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€€‚‚‚€€€€€€}~€}€ƒ‚{~~{|}{z||{‡zxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ‚„„€~‚€€€€‚~€€‚€€€€€€€~}€~€€€€€€€€€€€€€€€€~}~}~~{}|}|||xxuxxy{||}|||||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒ„ƒƒ‚‚‚ƒ€€‚„ƒƒ„ƒ‚ƒ‚€€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€€€€€€€€€€€€€€€€€€€€€€€€‚ƒ‚‚€‚€€€€‡~~|{}|{}xwvyyz{}||}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚‚„„€€ƒ†ƒƒƒ‚„€„ƒ‚‚€€‚‚„‚„‚€€ƒ‚€€€ƒ€€ƒ‚~‚€€~€€€€€€€‚‚‚ƒ‚‚ƒƒƒ‚€€„}}}|}{}zyvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysrtowqwysw{…‚‚‚‚ƒ„‚ƒ„ƒ€€ƒƒ†ƒƒƒ‚‚„„ƒƒ€€‚„‚‚‚~€€€‚‚‚‚€€€€‚‚„€~ƒ‚€ƒ‚€€‚ƒ‚€‚ƒ‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ‚€‚€}€|z|{{w|yyy{z}~}||||}~~€€€€„„€}€~{{{z{ztpxqytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚ƒ„†„‚ƒ‚ƒ„„ƒƒ€ƒ‚‚‚‚‚‚€€€‚‚‚‚€‚‚‚ƒ€~ƒ€„„ƒ‚‚ƒ‚‚ƒƒƒ„€‚„‚ƒ‚‚‚‚ƒƒ„ƒ„„„„„…ƒ„‚ƒ‚ƒ€€~||€}|x|yzyz|}|{||}}}||€€€€€‚~€€€€{{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚ƒ†……ƒƒ‚ƒ„‚„…‚‚‚ƒƒ‚‚€~€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€ƒ‚€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒ„ƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{}~|y|zzz}||}z||}}|z{~~~€€€€€€€‚€€}}||}|vrvxxvtvu}‡‡ƒ‚„…ƒƒ„…„€‚……„„ƒ‚ƒ„„„…ƒ‚‚‚ƒƒƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚€‚‚ƒ„‚‚€€ƒ‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒ„ƒ„ƒ€‚ƒ‚„ƒ‚‚ƒ‚„„‚„ƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz|}}||z|~}|}}~~€€€€~~€€€€~|}~~~}||xvvw„‡ƒ‚ƒ†ƒƒ„†„‚…†…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„ƒ‚‚ƒƒ‚ƒ‚ƒ‚‚„„ƒƒ‚„‚„ƒƒƒ‚„„ƒƒ‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒƒ„„„„„…„ƒƒ„…„…„ƒ‚€}‚€}||{||€}}~€~~}~|||}}~~~€}}~€~~}~}~}}~~€|}€‚‚ƒƒ…ƒ„ƒ†„‚ˆ‡…„ƒ‚„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒƒ‚‚ƒƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒ‚‚ƒƒ‚„ƒƒƒ„„ƒ„„…„„„…………„ƒƒƒ~„€}}||||~~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒƒ…ƒ„ƒ…~‚Š‹……„ƒ‚„…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ„ƒƒ„…„……‡‡†‡…„„…„ƒ~~|~~}€~||~|z|}}}}}~~~€}}|€€~~~~~‚€……„ƒ„„‚„ƒ†€‚……Š‰„„„„……‚‡††„…„„…„…„„ƒ„ƒ‚‚ƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ„€}uz„~„„‚ƒ‚‚ƒ„ƒ„„…ƒ„…†„…†}„y|~ƒ{…ƒ„ƒ€}~}~ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚ƒƒ‚‚†„„„…„ƒ„…ƒ„…„Šˆ………ƒ……„†††ƒ„…………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†spurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚……‚hzrss|€r„~ƒƒ}}~}~‚ƒ‚|}€}}||||}|||~}~}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ…ƒ†ˆ††…ƒ†††‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vyy†r„ƒpvxqvtturstvi€nrotvnulwmzsn€‡ym}rsvsvmnwlpylu~|~€}€}€€}}|||}|}~}€€€~|~€€€€€€€€‚ƒ‚‚„…‡††€‚…ƒƒ…‡†ƒ………†‡‡„ƒ††ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoolw}x†pqzprtfu~n{ysoy€}~€{~|€~€€~~€€€~~~€~}€}€€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„†……††ˆ„„†‡ˆˆ†‡„††‹‰…„†‡‡…ƒ…„…„‚…………†……†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„rioyxpkyszozwvvp€~~z~}|}~}€ƒƒ€‚ƒ„‚‚€}~~~€~~‚€€‚„‡†ƒƒ†„……†‡†…………‡†ˆ……†…‡‡…†„††‰ˆ…„‰‹ˆ†„†…†…ƒ……„†††††…ƒx‹yrˆz{pp…„x…xyks~y{krƒ‡ƒz|mzyyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozks|nv‚~~}}{}{|}|~}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡……………‡‡ˆ†„†…‡††…„……„……†‰Š‡…„†…††…††„†††††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„…†…†„†„ƒ„„†„„ƒƒ„ƒ…„…„…„†ƒ…†……„„…‡†„„…†……}x…ƒ„„ƒ‚~~{|{~{||}}|~€}€~~~€~~~~}}}~|{|~||‰†…„†††…††…………††‡ˆ†„†…‡………ƒ„…†…„††††…„†„…††††„‡†‡‡†…‡ˆˆˆˆ†„‡…††ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…ƒ‚……†……ƒ…„„„†„††„……ƒ††…†…„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ}€{{|~{||}~~||~}€~}€~~€}}|€}~~~~||}~{|||{{~ˆ‡„„ˆ††…‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡…††……†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ……ˆ…†‡†‡†‡†‡…‡‡†‡……†‡…††…‚ƒ…††„„ƒ„„ƒ„†„†…………ƒ††…†…„†‡…„„……ƒ„‡†ƒ‚ƒ„ƒ„‚~€|{}~{|{~~}||~}~~}~}}~~|}||~~|}|||}|||~z{{|~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†„…„‡†„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…†‡…‡†‡†‡…ˆˆ‡‡…††‡…††„„„…†……„„„ƒ„…„†††…†„†…††……††…„ƒ„„ƒ„‡ƒ„‚„…ƒ€€€{{~}|||~}|||}}|}|~}|}}||||}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††ƒ…†…†††…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡„†††‡‡‡…‡†ˆˆ‡‡…‡‡‡…†‡„‚„ƒ„†…‡…„„„„„…†††††…‡……‡…†…†…„ƒ„ƒƒ„‡ƒ€‚ƒ„‚‚‚€{}}|||~}|}}|}{||{||}}{{{}|{~}{|}}|}}~}|zz{{||ˆ‡‚††††‡††…ƒ…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡ˆˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡…‡‡††‡‡…‡†ˆˆ‡†…‡†ˆ††‡ƒƒ„„ƒ††‡……„„„…†††††…†‡††ˆ††„†…ƒƒƒƒ‚ƒ†ƒ~‚‚ƒ€ƒ‚|~||}}|}}|~{{{z{|||{{{~{{}{z{~||||}~}{z|z||‰‡ƒ†…†…††…„„……………„ƒ„†„‚„„|€†‚……†……†…„‡‡ˆ‡ˆ†…‰Š‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……ˆƒ„†…ƒ††‡†…„ƒ……†††††…††‡†‡‡…ƒ……ƒ‚‚ƒ…‚ƒ~‚„‚~~~||}}{}}|~zz{y{|}{{{{~||||z{}||||~}|{{{{||‰‡„†„†„††…„…†…„„ƒ„‚€ƒ†ƒ‚z„Œ{€„…‡†††„„‡ˆ‡‡‡……‡‰‡„‡…††ˆ†…‡„†‡ˆ††ˆ‡‡‡†‡ˆ†„†††‡……‡ƒ„…„†††‡……„ƒ……††‡††…†††…††„ƒ„…‚‚€„ƒƒ‚}~ƒ~€}|}}~}{~}|}yzzy{|}zz{{}|}||zz}||}|~~€{{{|~}|ˆ‡…†…‡„†„……………ƒƒƒ€‚…‚€}|{„…††„…„„‡‡†††…„†‰†‚†„†††……‡…‡ˆ‰†…ˆ‡‰‡††‡…„†……‡…„‡ƒ„…„ˆ††‡……„‚……†…††‡„…††……†‚ƒƒ…€€€€ƒ€ƒ€|€~~‚€}€‚}€|}~}~{~}||yzzyz}}yzz{|{|{{z{}}|}|~~|{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€€ƒ~~~€yz}€ƒƒ…‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ†…ˆ‡‰‡†………ƒ†„…‡ƒ„†„„…„‡†…†…†„‚……†††††„…††„……‚‚ƒ„~€€€€ƒ€{}~‚~~€~€}}~}{}{zyzzyz|}yzz{{z|{{{{|}}}|~}|||~|{‡……††††„…„…ƒ…‚€€€€~‚‚}}{‚ƒƒ…†…„ƒƒ†ƒƒ„‚€…‡…‚ƒƒ„„…††‡‡‡……ˆ†‰‡…„„„‚…ƒ„†‚ƒ…„„†„‡†………†ƒ„…„…†…†„„…„…ƒ…„€€‚ƒ~€ƒ|€}}‚}€~~~~~}}{|{zyzzyz{|yzz{{{|z{{{|}}}}€}}||}€}|†ƒ††…††ƒ„ƒ†‚…€€€~‚|~~€€‚‚‚„„ƒ‚‚„€ƒ‚€„…„‚€‚ƒƒ„……‡††„…‡…‡…†‚ƒ‚‚ƒ‚‚…ƒ…„…†„††‡††…‚„„ƒ„†……ƒ„ƒƒ„‚„„€‚‚}~~~„~{||€}€}~ƒ}~~}}~{~{{zy{zyzz{yzzz{{|z||||~~}|}||}€~€†„……„‡„„ƒ‚†‚ƒ€€~~€}~‚|}~~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡†……ƒƒƒƒ„……„ƒƒ‚„ƒƒ€€~}}~~|~ƒ~|~||€~‚~‚|~}}|||{{zzzzy{yzzyzzz{|y{}{{~€}~}}}€€€†„„…„…‚„‚‚„‚‚€€~}~~~~€}}€~~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„…ƒ‚ƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚€…ƒ~€~|}~}|~ƒ}{~|}€ƒ}}€~}|||}{{zyzyy{yzzyzz{{{z{}||‚€~€€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌÌÌËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFK=8765999<>9?<C9;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÔÓÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937676=;>:=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<:<<98:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA>;A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9>CE?<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÑÓÓÓÓÓÓÓÓÓÓÓÓÓÎÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø×××××ØÙØØØØØØØØÙÙÙÙØ××××××××ÖÖÖÖÖ×ÚÛÚÚÚÚÚÚÚÚÚÛÜÜ×ÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILN@99:4;@<7=9AC=@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌ̈́mpppppppppppj§ãÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¸·©§§§§§§§§§§§§¦±¾½½½½½½½¼¼¼¼½´‹ŠŠŠŠŠŠŠŠŠŠŠ‹‡½æáââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVM<::77>C?8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÎN&+++++++++++"ŠôëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§££££££££££££ †„„„„„„„„„„„„‚•¬ªªªªªªª©©©©¬›TSSSSSSSSSSSSKªòëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;?C>6:7>?;<B@8<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÍÎR+11111111111'óééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤¥¢‰‡‡‡‡‡‡‡‡‡‡‡‡…—­««««««««ªªª­YXXWWWWWWWWWWO«ñêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;?@@8:;8<<<<>::;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÏ\9===========5“ðççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©©§ŽŽŽŽŽ‹œ±¯¯¯¯¯¯¯¯¯¯¯±¡cbbbbbbbbbbbb[¯ïééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB>;=:9;:=<;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÅÂÃÃÃÃÃÃÃÃÃÃÃÂÉÐÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÎÎÎÎÎÎÎÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÒÐÐÐÐÐÏÏÏÏÏÏÏÏÎÐÓÒÒÒÒÒÒÒÒÒÒÓÓÑÌÍÍÍÍÍÍÍÍÍÍÍÍÍÔØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<7@A<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÏÐÐÏÏÏÏÏÏÏÐÔÐÐÎÌÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÎÑÔÏÏÐÔÒÏÏÏÓÒÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ×ÖÖØØØØØÙÙÙÙÙÙÙÙÙØ×ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?89:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÎÓ»ÏÑȔ§ÒÑǒ«ÑÎÎÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<=B>BB@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÎÒµ•›´Ñš¬œ°Ñ™¬š²ÒÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?><7:>9?D>@98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÏџ ª¯Í“ˆœžÄ’†œÍÏÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<<96?B?B:647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÏÑҚ±×½É˜˜Å¼É—™ÅÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8E@?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÏÏÖ§™±ÕҔ–ŸÎђ™¡ÏÐÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<==964:99::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÏÏÕ¥™±Ù°ŸÃ›Ú­£¿žÕÑÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:<?>=<9@<<::9?@==<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÐÐÖ¥™²Ö͊’žÇˈ•žÈÒÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CFCAA8;?<=;<<7558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÐÐÕ¥š³ÖÍÛ¥™³ÐÛ£™µÕÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF?HHGE@<<>><==<7569969;::;8@?:<<9<>=;;:?9?:;9=>=><;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦ÓÐÖ¦š´ÍŽ§š ­§˜ž»ÕÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@C;557<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡ÇÒ×¥›´¼£¥¨ ¯§¢©ÐÓÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKL@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÓÑÔµ‚Ä՝’ºÕš’Ž¾ÖÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<<?GEGKH=657:979:;:<=9>99:8;=>>A>=9<<:=>>:=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÑÑÃÔÓÓ¹ÇÕÓÓ¹ÈÕÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?AELLA=775;8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÒÒÔÒÒÒÕÔÓÓÓÖÔÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEK>>786977899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9699:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:69896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EIKAALD??;9889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEHIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDI;AA;<886586987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGJB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<AA<;876797799=?A?<:9@?<>B?:8776=?@@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE>;HF89757875898;>>=;89A>=@?A>7596;>AB??@@AB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCDEC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELBA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<<DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGHNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAD?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€iixsg~‰‰xp‚†{w}~…Š¼ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€‚wt|„‚}sp€Šx‚yƒÈÞÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsnupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿½¾¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»º¹¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjcmgb\XQPQKTJB:IQ?A7<94:565455688686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸¸·······¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µ¶¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸···¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶···¸·¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨§¨¨§¨¨©ª§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸·¶······¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥¤¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§¦¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©«««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤¤£¢¢£¢¡ŸŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž¤¤¡ŸžŸ  œœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=6789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥£¢¡¡¡¡¢£¥§¦¦§¬«§¦ œ›¡¡ž››šœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¦¦§§§§Ÿ›š›¢ š–—•š›š——˜™šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜˜™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿœ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥£¢¥¦¦¥¦§¦¦ ›™›¡ —’“’—šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB?DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥¦§¦¦¢žœŸ¡ ˜’‘”—›˜–—–˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;<;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¦¦¥¤¦§¦¥¥¦§¦¥£  ¡¡Ÿ™’•¤šš™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡¡¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢£¢£¥¤¥¥¥¤¤£¢¡¡œš–©ª›š›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œŸ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸžŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::78:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸŸ  ¡¢¦¤£¤¤¤¢¡¡ž›š™ª}~œ™™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢Ÿ›ž¡¢£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œ››œŸžœœœœŸ   ¡¡¡  ¡  ±µ¤ ¢¡ žœ›šš¢—Pƒœ›œ™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥¤¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¢¢¢¡ ¡§’±¢ŸŸžœ™™š›ªbL‡ž›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›š›šš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>99;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤¤¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ ŸžŸ ¡  Ÿª}®¢ ž›™šš§ŒNSŠŸžžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›šš››š˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9<<>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœœœžž¢—Y‰­žœ™›œ«jUUŠžžœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:<>9?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››››œ›¢mcž ™™œ¡ši`XŒ œžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™™™›¢si¢˜›œœ£‹j_X† œœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›œš™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š›››œœœ™˜™™©upj‹—œ›|h_\‡¡žœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ››››››œ™˜™˜£{lko‡œœž”pe[_Š¡žŸžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ›››››œš˜™™Ÿ‰‹’t~œ £‘xeU`¡Ÿ Ÿžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_^]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜˜——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜™š ¦œlˆ±§¤xŠ†ca—œ›žœœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±´­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=:F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œš››œ›˜™š˜˜™›šš–¥ ˆx[k§––[t|v”’’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨ª¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‘‹‘‹Œ‘’¨kTPrœŠ‹N]tx€ˆ‡‚‹†‰Š‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜ž—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VQQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹Œ†Š‹‹‰‡„†ƒ“¨z;/<xzyG:Sou€‚’†„„…ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹Ž‹‰‰…‚‚~ž™OOT?{„nfN;5Ppz~…Ž‹†”‘‹—”—’˜¡–ž–•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¦›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ‚†‹‡ˆ…„ˆˆŠ…€€¤uSxP|•‰yRh|R\u„ŠŽ‹™œ””” ššŸ¢­±®©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPEMISWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}€~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‘‹ˆŒ‹‹‡‘ŸaÖÀ_¦¯¤¦pqŠVh†‹‰””˜•œšž¨®²°°µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWMO_^\NUUbQDTM;?9<895875795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš™ž¡“—›¡š›¢£‘e¿Ð­•Û·¦À±T^wiU„‹˜šŒ”š—œ› ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUJTOOJDPK_bXZQ\T`MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ªª©§¢¥¨©«©ª²s³¯ÑÅ¢˜¬­qjŇP{Ÿ¢¤ž›š¤§¤©«®¬¥¤¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdWOYKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®««¬¤¡¢¦©§¨¬~“„ŠÈ೪’tF®±[p©§ ¢¡®¬«ª§­®¨¥¤©©ª©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_VZNRNQOSe\dc[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢™œ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨§¦¨©§©©¤¨¦š¤¥£¢¥¡Œƒo˜±£žœ‡tczŒum”¤¢ ¡Ÿ¡¡¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOXO^edlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤ ¢ £§¡¦®¦¦œ¨kQŒ’€~‚vtopst~€£¡¡Ÿž £š–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvxb_\UYQUW[c^s_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?B?:8:>?C@DA:;>=@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯««¬¨¨«¯©¨ª¨¢ ¡¨ª­±²®¬«©ƒp_Hounqvkiehfgqv~Š–¡¤¥Ÿ ¢™•ž›ŸŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸŸ¡¦¢›—’šš •|wo}yf[[`_Z\U\hdocmiib^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¡ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£ £ªª§¯·µ³¶º½»¯”jcWH\kfjqgcceZZabkuz~ˆ”£¦œ š–ž¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¡™˜¥ ¤§ª©¨ª­¬¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxjb[__\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>BE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢ «²·¾ÅÍÐÇÀµ¦“w^]SG\tkjqe`ciZX^Y^enpqtx…˜¦®§¥˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨¨«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥¡¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxxxc[RYT__amhvkqhiibZSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶´º±ª®´±°²´µ¼ÐÜàÙÊ»¯ ‘yc\^SA_ljqwgb^g^U\\[[^edbcn‰²É¹¡§ª¬§«©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš’–””˜“š˜Š‹‡€€|‚xa^YSai`ftotitdidb[LK>:9898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÄÇÃÄÀÎ×Ø꣏|o]VXXL=^bhtrmbaf[WWXXVXX]q’°Å˺¸·©¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`b_^kcbnxuwnm[bRV\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAA;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–••‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±°§¼¼¾ÅÄÆÉÇÅƺÄÀÇÏÒǦ…]OKOSL=VWhb`qha_XZWXVT^‡±Ä½³´¶ªµ²­³­©®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|„jfhaklgnurruqg^`\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÄ¿ÃÃÆÆÁ¶Ç³Œ\SVPCVS\afpeX[Z^XYg¯¿º¶¦©©©ª­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|uklndomiqxoyjia]gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÃÄĹ´¿¹»Ê®y]PNW|t—–UTXWYa°·©«²´¬®¥¥£§¤  ¥™ª´±¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyy{wnkihvZfrxsyff^d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÊÆÄÃÄž·½Ãò}VLpw—¥NQS[t µ·²­¬¸µ³¬©£¡­©¬§­Ÿ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuuefijh^jonyxcba`^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÎÏÌÃÇÆÈÉÈÈÉÇÅÉÇÈÇ¿ÄÇÃÇÈ°€`X‘¦’HLm—³Â¼¾¹¼º¼º¼¬­¦©»º¹·¿²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqocagvijjtnyl]d[U`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÌÐÍÇÌÉÂÂÇÂËËÈÇÌÉÍÅÅÅÂÅÅÍÐǓ‹¨‹Em¹ÅÉÍÆÅÁÄÇÁ¼¾´±°°Â¾¾ÁÆ¿¾¸¶Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`kjwlifuotc]bTWUSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<9>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÄÇÈÆÒÉÁÃÿ¿¾ÄËÈÊËɼ¼ÈÇÉÍÈÃÈÉÉÅÅÁÁÀÁÅÆÉαŒ^iÄÐÇËÏŶ¿¿ÀÀº»½µ³³À¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrpfefckdbkmno^Y]VVNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾƹ»Ãº¸¹¼¾ÁÇÁÆ»¹ÈÈÃÅÄÀÃÁÁÀÄÁ½¼ÁÁ¿Àɓ?”ÒÌÅÈÑÁ¯½½¸¹»»¾·´°¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfaebaccdjcgc[ZZ]YQOE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶·´´µ¿»½¿¹¾ºº´À¸µ·²®º»·À·¼ÉÎÁ»¿À¼»Ä½ºÀÄ¿½¼¸»ÀÅ«H•ÌÄÀÀÉ¿°Á¿º·»¾¹µ¸´¸¼´½¸µ´°³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|yˆ}qdabchjggjej^VVTYOSLF8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“““˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´´±°µ·µ»Á¸¾¹¿¼¼·´·¯®·µ¹¿»Áԍº¿»ÃµºÇ·¶¹»¼¸¹µºÃÉ©LÉ¿¿»Á¾¹Æ½Â¿¼Å¸¶·´¸¶¶»»¸¶´·ºµ³¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒyqmeefpjelhXYOKKKRJLHD9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’™”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿¾¼²­¯¬±°·¼·»½ÁĹ··¶µ¹¹º»¿¼ÏÄxªË½Ç·¹¸­¶´·¹³µ²ºÅɜM„Ê¿¿¾½¼¿ÈÃÅžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~†|knqgqktfbn`\THKKDJCCG?:;8><7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘Ž˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼»À·ª­¤®°¸»²½¾»Ä¶µ¸µ·¿¾Ä¼ÂÄ×®u‚¼ÈÏÂÀ¸®µµ»½·¹±¾ÃǑTÍÿ¾½¼ÇÌÇÇÄǽµµ¶Á½»»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†€rfljnuoxchb\cQKUHEECGC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?>??FD@A?>:7?@CC?@=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼ªª£°¹½¼²¼¾¼Å¸±¸¹¼ÆÉÊÂÇÉҙrt®ÑÑÌÊĵº¿ÄȾ¾´¾À¿avËƾÁ¼¿ÃÌÊÇÅÆÀ¹½¼Ä¿¿¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtolltlln_c_abNHN?E@?DC;;::;:8;<:9<>::>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´»Åк¾¼Ä¾·¼À¿ÉÏÇÈÊÊÁ†st¦ÌÌËÍÊÆÂÃËÎÁ¼¸¼º°xqi»ÈÄÀÀ¿ÄÀÊÉÃÃÄùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{zˆ{mmx|`qc[_`_TI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA??ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸´¼·»»«Úþ¶¾À¾¾º¦œª²¶ÃÀ¥ywzœÄÆËÈÁÃÀÀÉÊÁ¿»¹²¢Šu®ÈÅÄ¿ÀÁ¿ËÇÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}‚znsxthp^\_]ZRFEDMIAD=H;;59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘—žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯··²µ³·¹¼»¶»»Ä·m­Î½¶¹À¼ª}nhnmr–˜tx}™½¿ÆÀ¹À¼¾ÅĽ½¸±® ŸŒŽÊÂü½¿¿Ãþ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸··½¹»±¶²ÈÀ»¶´±°·¬³©°­­´·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|wmu{qoj\``ZSPAFIGK@ECI<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿš›œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹ÀͲu³½¶µÁ¤†iZ^`MR[[otxƒ¢¸¸Âº³»·»½¿º»»®¢¢¦—Ÿ€¾Äþ¼¿»»¸¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ°µ´´½º¾ºº»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰{‚zsvvwoqa_f][UJ=??GG=GCC9:5;99><<9:<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Âɦ„xŠ ¯µœjfgVY`IIMPTmxˆ§°·¾¹²µ²¼¹¼¶¹¾µ•¥µ¥­v­ÉÄÀ½¿¹³®²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtwrl_ca\^OIB?=IDFMD@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·¿Æ©ˆ|vŒ¡˜_SCXUGajVOEJaŽ¢­¯¶ºµ´²¬¼¹¸µ¸Á½‹ž¹«®u¦Ë¿¹ºµ®¥¬³±¦°­¨ Ÿ¥­¶µÂ·¶´¥¨ª¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´¶¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wp|ovsnc^gY]]SONA>JB@JJ@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³²­¶º¯­¼³¸¸¿´‚yˆnNK?dYBNw€”iMA]ƒ°µ³µ²´¯¬»º¸¶¹¿Æv‡°¤œf©¿¸µ²±­­Ÿ¤¦§¤¥œ–™™™Ÿ©®¹¬««Ÿ¥¨¤«®¯§°«¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmujl]\kU^\PNHDGMBFNF8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹º¶¹»µµ³·¶•Œˆ„|XFAO‡YJJXwb@S£¹³´²°±­°¹¸¶»·»¼‘£³­¤t¬°©«­«£¨¡ž—— •’–—˜Ÿ¨®¤£¤ ¢¦¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬ª¯£¤£¡© ›“Ž”’’™–š¤¥ Ÿž§˜•’”™ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wryhutneUadW]ROMI@IRDNC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯²¼©˜™”hM?RxqPIIKhœ€ZER®»±¬³¯®¬­¶¶²´µ®©§Ÿš›Ÿ¦¨ž ¨©Ÿ¡§–›–—Ž”–—›¤¨  ¢¢¡¥¥œ££ ž¥ ¤¬¥¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›ª¨««Ÿ¦¢›£œ•Œ“—•–˜Ÿžžš™¦—“’–¢ ¥¢¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦¡ˆxƒ|vzcxmn]QiUPOGPMMCPQ@>;>49:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¤¬¨½Âª¥½hDR‚QWIJ`JUadc®µª²´®ª«¯°²³­¥‘—“— Ÿ¢ œ£¤Ÿž¨”›––Œ—‘—“˜¢ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨¨œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£žžžš—š«¦ª±£¥¨ž œ•“‘‘™–•˜—Ÿ˜œ™›¤™—”•š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’~|uv}mk{dhVRdNJHGOSNKNH<E@<2?859;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜——–¡¨¬®¶·º¹º··»®¨ ¡© ªÆ¿Ê PAsvOmJKcfts`\`r±¯®³µª¦¬«¢›™”‘•–˜˜œŸ¢¢œ¤žš¤———–’‘‘“š—› ¤ªž¡¡ž¦§«¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¢¥¢š™ž¯¨®²«¦«ª ›˜˜˜•“–š“••š–›——˜¡žœœ–›¡›žš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}wy|eyz`bSUaHIJKSTJSQM9?A67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—“’œž¤¨®­¬««¯ª¯©ž—ž¥œ¤ÆƌWSJe¤Ze}or[Qkc[ea^k´°°¸¬¦¡œš”—š™Ž‘•‘ŒŽ“™¢œ—£™š—˜™”™˜–›Ÿ¥¦© ¦£ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§¡ £±®²±´ª²®£™œž¡˜››š—™›”–›–™œ¥¡ š£¡šœ™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ ž ž ¥¡žž¥ ¦™{|vvsi‚lf[SZZMQKOOVMSMB7>C78=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’‘œ˜¡ª¢§ ž§¡¥Ÿœ’›¢šŸª£ŒyUiqvupcvvXWc`chZYWg­®¬¯§Ÿž¢ –“› ›™—’“Ÿœ¡£›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬©¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½¶¾°¬±®­©ª´±°¨«¨³¶¸³¸­²´¤ ¥ ¬¡¡¢¡ š˜–•Ÿ››˜¥¡ ž£¡ ž›œ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚€}xvjxu]m[RaIRUHFUWJCMG=KI8E<77;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“Ÿ™¨®Ÿ§žœ¡žš™’˜ž›¡¡ £€o‚p`cXL[RZLKPXRHMMG˜¬ª©¤ŸŸ™’’”˜˜–––Œˆ‹Ž•œž—ž™¦Ÿ ¨¥±ª§®£«®¶°µ²±®¶¸½¿º­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«®±¹¸¼¯³°µÂ¼·¾³³µ¢¬¢©©²©«¨§¨š™žšª§ ™§ ŸŸ¨¨¥¤žª¢¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰……~vrmiwmim\X\CWNJGMHCFN=>L>4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜™ª ±¢·¤°¦Ÿž—˜•™žšœ£žŠbW^e`WMQG=>?CC?>BQx©­©ª¥ŸžŸ¢£žš›”“•”ž˜”…š š«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶º»ÀĹ½»¬¯§±­±Â¶¸ÂÆÀÈÊÀÉ¿°¹¹½¹Â¾¸´»ÆĽü·³ª³­ª³´¯³®ª¯£¬¨¶±­£°¦¡£°±®°¤¥¯£¡ š¡§¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¤ž¦š›¢¤žŸ›››œ‡†|trklurqhW\QFUHDJPI?EB4FH95<>7;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž  œœ˜šŸ š Ÿ•|_^e`QFD;C>F<?96N~ª³§££¢ ž¥«¦ž—œ”‘šž™•ŒŠ†ˆ†xmˆ ¤¢«¬´¼¶Ã½¾³»ÁÃÂÅÀ¿ÂÆÅÅÃÈÂÀÅÇÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌÌÌÒǾ¿ÀþÇÆ·ÃÊÉÃÁÇ¿º´º»µ»·°¶²ªº²®¼¸¿»º«¸­«ª¸»µ¼®®¸£¦£ž¦¥¢£©¦™›Ÿ™š§ª§ ¡¡¤˜”£–”™‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ…~zrkdioxjeZ[FLMEDTMECE7:?;549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ²²¸§¡¡«ª¡œž¡¡›š}sjaWNE>IY|oaB=\Ž®¬ ™››žž™———’——”Œ‚ƒ‚wrqmp¦­®´¹Å»ÍÇ˾ÁÌÍÍÌÈÈÐÌÌÌÇÊÅÆÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÑÓÍÓÐÓÓÌÊÁÆÆÆÊÈÏÀÉÑÍÇÆÈƼÄÁ¾¿¿¶¾³­¿ÀÃÃÇÄÇį¿¹²¸½Äº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›‹™‰•˜› Ÿ£—žš““‹•…ytsebgrof^ZZDOMDEPIDCA55589B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>9;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›¢¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¤¨¬­ª £žœ•jf]TID@?J…ž¤™ƒ ²­£žœŸš˜—”’”–‘Œ‡„„ˆ†ƒ€€yqroly¤¶º¹¾ËÁÓÑÓÈÍÎÑÓÑÒÐÐÑÑÍÎÏÐÅÍÔÕØÑ×ÍÆÇÉÌÃÅÊÏÊÓ×Ñ×ÒÕÖÓÔÈÌÆÌÍÉÓÍÎÓÍÆÉÊÊÂÆÌÇÉÉƿó³ÈÅËËËÏÇÊ¿¾¿½ÁÇÅÌÌÉÉÀÃÀ®¯³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›–Œ†‘‹€{ruvgcgvjdVWRDNF@IQC>B=:22A<E<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<@?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­³·¬®£ž£¢¡›bTLJDC?CR¯Ñ½²¯¦œœœ ¤¡š”“•”‰}xqkebhrpr{…Š€upnqsp…³Ã¾ÅÑÐ×ÖÕÒÖÍÔÖÖÔÓÑÒÓÔÒÏÒÃÐÓÖØÕÕÒËÊÎÑËÆÍÑÊÒÕÖÙÖØÓÖØÍÒÊÏÑÌÏÑÌÓÐÀÉÈÊÄÌÌÌÏÏÅÇȶÀËÀÒÍÌÐÆÊÉÀÄÃÈÎÍÐÑÏÍÊÈ͸·»¨Ÿ¥«§Ÿ˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„}xsvpc`erc]R\IKGAEIJ>;A8>5586;86:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÁűµ¨¡¤¥ ¢¡ZI@ADAFQv±¯¦š”—Ÿœš  ž›œš•‰wica____^__]alusppolqqu’ÄÈÇÔÖ××ÖÓÖÐÕÔÙÔÔÎÏÕÔÔÑÑÌÑÍÓ×ÖÓÕÐÏÒÓÑÉÓÑÈÐØ×ØÑØÒ×ÙÔÖÌÏÏÉÍÒËÎÑÀÆÃÈÆÏÎÑÑÒÈÌÍÀËÍÆÔÏÌÏÈÄËÇÇÈÌËÔÔÑÕÏÒÌÓ¹ű¥¨µ®§›¨«¥²¨°³­¬““Žˆ‹Žƒ‹„Ž™“™‚…Œ|zqstmbcim_VQ`JJCECRM@<>43:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><?@=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯­ªª«¥®·¨«·×ÔÕÙÙÑÎп¼Ìɶ¾®¦ª¨¡£«fC8=>DX‚ª¨Ÿ—•—™šœŸ˜œœ’}qecb__a_^a`^a`_`emppnkorvwœÌÁÓÕÓØØÖÙÑÒÒ×ÏÓÎËÒÍÕÔÑÊÏÌÓÖÒÑÖÍÏÕÕÑÅÑÔÊÐÔÕÖÎÓÑØ×××ËÈÎÄÉÏÌÊÌÀÊÀÉÊÎÎÏËÐÎÎÌÏÏÈÌÐÐËÎËÃÊÇÉÍËÌÒÓÎÔÒÑÐÐʽȹ°®»¹µ«¶°­¨¸­³¾»±š ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…‰zvopokadnpaX\ZJFFDMXE;@=33<<87855;>@=9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ¤§Ÿ¸¶µµ¬¤¬®¾´°ÀØÒ×ÚÜÖÎÍÊÃÒÏÁÁ±©¬­©¤±{HFB;W¡›•“–›žžžœ“–—”ˆk^^^adb``aa`a`^__^\bmroostuvy¤¿ÌÕÑÖÔÓØÖÎÎÓËÎÎÅÎÊÒÒÏÇÎÍÍÔËÎÒÍË×ÖÐÌÑÔËËÐÒÓÊÎÑÕÒÕÕÊÀÊÁÆÍÂÈÊÃÌÄÆÈËËÏÊÎÍÐÎÔÌÆÉÏÍÉÇËÅÇÂÆÊÌÍÐÒÇÐÏÎÎÌÐÅÇÁ¸¹½Ãýù³²¾±»Ãĵª˜¥¡˜–’••’‹”š‘””•‚‰†yqrkmh``qhYXhVMGLIPQB;C>;68:8:;57==A;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÄÂÁ¿»µ²±Ç¸ÊÕÖÙÚÛØÌÌÏÈÖÕĵ¯´¨ ­—xlopwšŒ—•“‘‘•–•‹|eabb`]^aca````aa__][]grrprspmry¥ÇÓÏËÐÐÓÔÉÄÈÉÅÆ¿ÃÅÏÎÇÅÇÍÊÑÈËÎÍÆÑÒÐÎÌÔÊÇÊÎÏÇÇÏÒËÐÏźĿÆʽÃÈÉÎÅÃÇÀÇÍÈÄÌÊÌÏÈÄÄÐÉÆÂÆÉÅ¿ÁÇÌËÌÏÂËÌÉÇËÐÅÅÇ»ÇÃÉÉÂÏÁ½¼¿°ÁÉǹ¼ª°²§¥¢œ˜›£™—™‘•˜‰‚xoudk`^fqa[W`GHHGIMTG?J=64355==48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ¼¹ÌÌÆÐÕÕØÚÛØÐÉÏÏÑÓÈ·»»­¤¶~g‚…¢ª“–…ƒƒƒ}„„~s_[^]^`^`cdc_]]^_``_[Z\`lrqnokloo}¹ÑÈÉÊÏËÍĺ¿Ãº»º¹½ÈÆÂÃÀÃÈÊÈÈÊÈÁÅÌÆÈÊÍÉÄÁÊÉÁÁËÐÅËÈ¿¹Á¼ÆǾÀÆÏËÄÀûÉÇɼÉÇÅÊÁ¾ÂËÆÅľƽ½ÁÃÅÌÅƼÀÉÃÅÇÒÄÁÉ¿ÊÊÆÈÆÑÃÃÆîÄËÇÄÊ·¿¼º´©¬¤¥˜Ÿ˜¬£¡¦›£ ›•|wsufj[anmZ\XRDLGBGELDFS@54335@=3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ÊÏÑÌÇÂÃÆÍÎÎÌÕÏÕÙØÙÏËÒÍÍÎÈÁµÃ¾²°¶l^y|Ÿ‘Š’–†z€……uxurp_Z[]``bcdded`\\^]^^`[YZ\bornkikposÇ½ÉÅËÀÆÁ°¶¹±±³²±Â¼¼¼º¸ÀÁÁľ½¹½¿¹ÄÊÅƽÆÀ·»ÃÉ¿ÁÉ»¶»ºÆÿ¼ÂÎÃƾ¾µÁ½Ã»½Ç¼Ãº´½ÆÄÂ÷À¶¶¾¿»Ìý¶ºÈ»¿¾ËÃÁÆÃÆÉÇÉÆÐÆÂÌDzÇÉÃÎÌÁÅÿ½²·°²§¨¨¹°¥­°ª­¬”zvxkeh`hodV^YJFJFHKAFBFI@9:658853;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÅÂÄÈÎÒÊÊÊÇÍÍÎÑÈÐÆÕÔÕ×ÍÊÎÅÉÅÇÁºÅ½¬®¦`cu’‹ˆ‹„x††}ƒ{ttc\\]^``bcbbdeb]\[\^\^]Z[\^hsqmggnory½ËÁúÀ¸­°°¦©­«¦¸´¶´³³³»¶½±·°´®²»Â¼Áļ¿º´²º¾À¸È¸´¼¶Á½¸½ÇÁÄ»µ¯²µº¿´Å¸»µ¬¹½¾À½±»¶°·º³Æ¼·¯»¿µ·µÅ¼¿ÃÆÀÄÅÆÇËÅÀÆÆ»ÇËÀÎÉÇÃÆÁ÷ý½¶¹¾Ç¿¬µ»µ·¶Žytxggebkn^V^`FKHHJFBDAEE?=:566633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÍÈÅÈÍÌÐËÍÈÉÈÊÉÊÄÐÍÒÏÍÅÇÁÅÁ¿º¸É·«°™[go‰Ž†ˆ‰zx~††vw|sh]]]]_`_`da^cec_^\[^[]^Z[[]_lpnifjmnr|¤Æ¿¸¸´¯ª«§ž¡©¦žª¬²­ª¬©´­¶±³©®§¬³»º¶Ã¹º¹°«´¹»´Â¹¯À±¾¼»¶¼Ç¹Ã·­ª¨°²À¶¸½°±¨±³µ»¼¬®¶¦®¶®»²±ª¹°®»®¼¸¼ÀÀ¾ºÃ¿ÆÃÅÀ¼ÆÂÈ˸ÅÇÅ¿ÇÄúÄÆ»ÆÉÌ˳¹Â½»³‰tvwki`bliYWW[ALKMJEAC@FA:::996854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÅÎÒËÃÅÁÄÏÇÍÁÂÆ¿ÄÄÃÃÊÂÉÊ¿À¼Áº³µµÃ®ª°’[i~’ˆŽ{x}‰…z{„€wn^]\\]_`__dcbcdb`_^Z[ZZ]ZZYZ\enohfgiknr­º°µ­¥£¦¦™Ÿ¤Ÿ™›¤ª®¤¨¢«ª¬ª°£¦Ÿª­µ¶±¼¸¯·¯¨®¸´´¼¸³¼¯¸¹µ²¼Á²Á¯¥©£«±²³¨½ª«¨«­®µ´¦¨­¡¤¯©²¦¨¨®¥¨·¬±³·ºº»²¼¾¾¾Ä¿µÁÁÇÈ·¾ÀÅ·ÅÃÀ»¿Ä¾ÄÈÌÊ¿¿ÄÀÀ©‡stsji\aodWVXPHZRSKFFE>?@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÐÏÍÃǹ¹ËÂ˾»É¶½Ã¾ºÊ·ÁÃÁ´¶¼¶±¯µ¼­©«’cmˆƒ‡‹€z}~xt~|swe_]\\^_`^_ccab``_^]\ZXY[[YXZ\_fkfdfehkor…©¥«¤› £“œ£š— ¢©£¢Ÿ¥¦§¦­ ›¤¦¬²¯··§°¬¨ª´«´º±¶¶®¶¹²°ºº±·¤ ¤ ¦±¨¬©ºª¥§§¨§³­ ¨§Ÿœ¤¦¬ŸŸ§¤ ¡±­­¬²µ³´±µ½¶»ÁÀ²»¾ÃÁ±¹¹Â³Á½Àµ¸¼½¾¼ÂÇÄÃÄ¿ÀÄ „xqlbf`ko`TY_HNhOTHFKF<=@=:;;826536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;>97776788666;::;9:;<859<:>>@;Èµ¶½¸ºÀº½µ ž”¡¦º¶«³³»³ÄÏÉËÂƸ·ÇÀÌ¿¸Ê·»Å¸³Å¸³¿À¬µ¼²¬¦¯´­¡£’ir†…†€|xusomjiipi_`]\\\^__acb````]\[\\XYXXXVX[]_dccfgggkmn‡¨ž””™Ÿ”™¡—•‹ ¡¦œŸŸ¤¥¢§ž›¢›Ÿ«°­±µ¤©ªª¬¬¤´¸­·°¬³¶¯³µ¯°ªŸžŸ¤¢²¥¦ª¹­¢¦¦ ¨­«™  ž™Ÿ¥šš£œœž°©¬¨ª¬­­°³¹¯¸¹º°¶¼»º«³³¹³½´·±±¶µ¿µ½À½Ã»»½—„{sl_e^ddXTW^IW]KPGJJGA<??A;?<05535:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»¸ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÅÏÈÈÀÆ»»ÃÃϾ¹Ç¸·¿·²Â´±»»¬¹º±¢Ÿ©«§˜žm~…†xrmomkb^aff]]^]]]\]_aabccba_\[[ZZYXXWWWXXXZ]bddfffhikrŒ§›‘’’™•™Ÿ”•›¡¡¨ž›¥¦¢¥› ¡š™¯®­¯²¡¥£®«¨¢µ°²²¬©¯³§º³¦¶¡£Ÿœ£¡­£¢ª¶«££¦ž¦¦£–™—™› š—œœ­¡¬¨£¤¦­«³´ªµ°²«³¹´¯«¯²²³¸³®©­®²·°º¶º½À¸³±”†yuf_f_[YVSZUK[QLJEHKIB=?AA@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½¸½¿¶¾¼¿³¥£˜¥±Âµ¶½­´¸ÁÌÈƿŶÁÀÇζÀý³¹¹²¿¶±¹»­²´¯Ÿš£ª ”šxƒ„xoqtqhechdc\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXWVWadecdeddhjv š‘‘Ž’”••—“–Ÿ œ–¡¡¨¤ŸŸ©››«¦¯°«œ£¤¸©  ¯¨·«§§­°¤·°¤· £œ™™ª¦¡›­¹°£¡¤œ¢ Ÿ“”¡”––›™˜–—œ•Ÿ©žª¤¢£ªª±­¨´¬ª§­³°¥«®³±°°¯¯§¨¨²®±´°¼´º¸®£•‚zve_aWYXSRTKM^LPLGHLKE=@>=B<:7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´ºÂ±¾·½®§§¢ª»À½À¹®´¸ÁÌÇÅÂýŸÈ̲ÁÂÁ®¼»µ»¼µ¹¹°¯°ªœš¡©•‘Š‹€€|wqilrtphhedfa\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWWV[bccbcbbcfi€“’Š‘’˜–›“”šŸ›ž•ŸŸ§¦¤§¨ Ÿ¦ «¯¦ ¢£·¨¡¡¢©³¢¥¨¥°¦±®¬µž¡–•©¡¢”­±±Ÿ££žž˜›“‹¡”‘“˜˜“—˜˜—ž§›¨¡¢š¤¥¥«¤¥°§¥£«¬­¦©®¯¯«¨ªª³¦¦«¯´±®¼¶±°¯ ’{xseb\[]XNLQHRaMVPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8847763321./2556;:8;7876<;:;;A8x»»±¶½°»±·¬ž¥¦¬·»¼Áź±¹µÄÉÉÀÃÆÅǶÆijÁ¿Å«··½¶½º»µ²¬­¨™™Ÿ£‹Št‰ˆ~vncafihfgifil`]\[ZZZZ\]\[\^_\ZY[YYZ[WUXWTTVURTRU`a_`a_``bdi‡Ž‹‘‘š’“•£™ –œ ¥¡­¦¥¥¤¤£ª«¥šŸ¥±ª¡¡ž¥ªž¨¢Ÿ®¬ª©­­¢¢¢•—¢šœ«©°œŸ¢ŸŸ—˜“‰ž‘’“–˜˜“œ¡£œ¤¡¢• ¢¤¥›£«¥¢£«¤«­¥®²ª¦¥¦¦´¦ª¨­³µ´¹º°«¬žŒsqp`[WVVRFPOHZ\ORJTKSLEGJD8;;><9667:9;:976977:;:=<<6;<8>598:88659:;<97?<9678452121..1426:8698598989;9@9{µ´¬´»²°«²­¨§¯¹¹³ÀȺµÀ¯ÅÈ̺ÁÉÌȵɼ±½ÃÉ­±¸Áµ¼À¼´µª¬¦–šœœ‰rˆƒ{tiijlgjlmkjle]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURRNQY]\]]^^__bdmŠŒŽƒŒ—‘’‘œš¡œ› ¨©«¨¬§©¦¤™¥¯¤•™¥¯© œ™› ž®šœ«´ ¦¦Ÿ£¤¡”“›––’©ª­› ¡¡›”Œ™ŽŒ‘Œ’–•¡ £œ£•›¡£¡˜¢¨£¢¨« «°¤®¸¦£¤£¬­©¨«¯´·²½µ³«¯˜…uti[XYRUREXLQ[XMUOQLQRINJB=??A?=75799<<977:79:;<=>;7;;:=67:;8976989:6:=99577571141-+/434988::8::748=8?9~³­§³¶®¨¨¯®›©¨¬·¶¬¼Ê»¶¿¬ËÆŸÁÎÏdzĺ·»Âȱ­¸¿·¼¾»³¶¦© –˜™—ˆzt€vwnmhmmmpggifd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUSSNOQYZZZ]\\]_`d|‰ˆ|‰‡‹•–˜¡Ÿš «ª¦¯¬¨°¥©šŸ­¡•–¤¨§˜šž¯—™§ª™ ”¥¡Ÿ’‘’‘“•¨«¥š™™žž–ŽŒ‹“†‰ƒ‹’•‘ ž¡¤™–Ÿ•š¡¢ž”›¥¥§©¨ °°¦±½¨ £¬´ª®§°´°¹µÀ±®±«~rtcVTVNRJGVPRRLLXNJLORGMKACFDD>A75889;9:7::7<=:;@>:9;9:?759:9876958779;85576661320-*.102877;99;8948;8@8´¬¦±·ª¥¢±«©§©²°¤¶Æ´¹º³ÊŹºÁËÐʲ¶¸¼½Àñ°±·®´´»³´££˜—•„€vkglnqnrjokdege^ZYZYZZZZZZZ\\]\ZXXXYYWXWUUTRSUSVTRNNNRWXZYYX\\]aj}w|r…‹„Ž‡•ˆ“’—š˜ž¨›Ÿ«¦¦¬ž¨™ ¦œ“Ÿ£š——†…’›¤•£–––ˆ¢››“ŒŽŠš¥§œ••—›‘’‡”Ž‹Œ€‹’’’¡š ¢–”˜˜•¢¦š™¤§©§¡ ´²¨³¸¡œ£·¬©­¤³²¦µ»µ«¬±£Šzsn^NQQMODNNNPKFNNJJNNQIMJAHLHHC>958889:;69:68;99><8:>9;?8789:886857688974577820301+)-/12876:999984988A7w¶¦¤·±¥§¤ª¥ ©¦¤³ª¢²Ãµµ²³ÆƶºÃÊÌƳ¬¹½´¸À¯®©°ž¦®»¯­ š›ž••ˆ|„n__frpvqinieghj_XXXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQMMKLSWWVXXXXZ]anosm……~‚‰“’¡Žšœ£¢¤˜¥–¢œ•ˆ™šŒsƒ~Ž—–†’š”ŽŽ{™Œ‚‰€Š˜ £ž“˜–…Žƒ”~~tŠŽzˆ“›šš’–Ž££Ž‰š ¡¤¤›¢´¯¬°­Ÿ˜¦¸¦¥°¡±®œ±¼ª©¯ª™ƒxtdVMRPPMCSNLPMBPQHINSMHJJDKMFKK=749888;;69;7:<9::;79?9>@79:<89764445874312585/0102)(,-02764789::65:87A7x·¡£´¨¦¥¨£¥¥¦¦¦²§¦´Á¸¯´°ÉÄ·¹ÁÎƾ³¬ºÁ¬­Ä­¨¢¦’¦·­£ –—’~xfWV_gfighnciigb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTQMMJHNTSSTUUWY[]iioj|‚zrMWqŽ–…Œœ—‹“‘Ÿ˜•”–”–Š€”‰_;Vo|Œ”Š€Œ’Œ††s‹…—y{†”•ƒ•Ž‘ƒ†}“xqp†}‰Ž—š™“‹ŠœˆŸ˜ˆˆ–žš¡ —§®©­¨¨ž–­³¢¦®™¬¬˜¨´£©­£“tn`[NSRWLDTJPMLFNOIELQMKOJIMPFIJ=7599999:7:;:>>8:==7:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9y· £­¡¦¦© ¦©§£ª°¨§´Á¹°µ°Ç·³½Ï¿¹¯®µÂ§ªÄª¢˜ƒ”œ±£š˜‡”‹‡~sv]PLQUYZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MNQMKIFHNQQMORTVXZ`klfxrOA?•‘|ˆ”Œ„Š›Ž–•‰’ˆ†•‡y‰`JQnx‹’„~„‹…€m”wuvx„špQˆŠ†|~x”vhw†ˆ~Šˆ•‹Ž‘“—Œ„Šˆ”„›ƒ„’›–ž”¤¢¨©¥¤ž›°ª¡¤¤’¦ª–¢ªœ¡¦¨‰vng^\HQQSMIUMSILKOIHFJNLMTKQQOGJD=769:8:;;8:;8>?99>=8;<6;;478;6775344696/3/.125221/,')+*,4833989:99::::?9w¶œ£§Ÿ¡®¡§¨¥§¨¯¬ª¶¼¶¸·³Á»¶¨¹È¸¶¨¨µ¶ª²¼§ž•‰”©–•‹Žƒ‚~xqoXMKMNOLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDCINOhYNQSTVZn‚qt|hg[S‰”ˆs~†|…Œ“‚’™‹{†€v€xsouqtŽŽz~Š«…zzhv{Žprmx‹’x{€{€wss’xgu…„„…|•ŠˆŠ‹€„‹€”„|€˜”œ–‘Ÿ©žŸ¡ ©¥ž˜§¤“ Ÿ–žŸ¤sib]]JWPRGKXROJMLRJJJLPHLQLRTMFIB<78;99>=:;<98@?::>=7==79937785675251472/2.,//200/-+(().12721987:8775:<;7v®™£¡˜Ÿ´©¯ª¥­«°±ª½´²»¸¶º´±Ÿ·º²ª¬©¨²¯¢š‘”ŽœŽ‘v†w|voojYKHHHGEHHPTTTWWSTUUUVWWWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQQSV^t‚{weu‹•˜Ž|gx€vx‰}„˜’€q‡|w{ok~­}t‹z†’€|tfv|†lohs|Š‡€myq}qmvqhq~ŽpD‹…‚ƒ…wwzŒ†}Œ{u}Ž’˜‹’š›£–™šž¡œ–‹¥›Ž—Ž–˜xongc[XXUQJSUTOPNPVKNKOOJROHNPLFD<;79;::?=9<:99??;8;=7<9999266856633611224.,,-..-0-+*''*.1362/876966527995y¦— ž– ¦°¬®«¨©±¯±«¼¸¬»¾¸³¬§›°§¬›–¥©¤¡˜™…’y‰‹‹vq|mupjmjXKFGEA@CDHLLMQRPQSTTTUVVWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNOQTX]epqk‡¦ªÀ~txb{wn{yˆy|‹†omŒ’ytyjj€‚q–‘Œ}•I’™nhw~‚mjdly…’†krl|nr|†imps‰…†{~{wptt†‚yyp|Ž‹Š“ƒ–—˜š“––™—–Œƒ‰Ÿ’‹’†—€ojoooYVXTRQYORTTRXUMNHMKMOKCINGF@:99;99:><9<;::=>:8:<9?868727565541432/024*+**-.+-*(*(',-1250,5567485HA895w™‘›˜›Ÿ¤­¯¢­ª¨µ¯®¬´¿«¼Ã¿¥¢š•¤˜ž„‹”¡¡˜™‘“‹sŽz€†Œ†totkpldljYNDFC@<>>AFFGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_IMOORVZQY\_§‡a™hryd~olz‹‰v‚ˆ†tlš’tt|jjŽMy…“‰„Žf1v‡sl~~ƒtfeu„„…€filukp€|hqq|n“{t~}qqnum‚wyujyˆ‚ˆ‰ƒ–’’‹‘””Ž—€yˆ—ˆ‡Š†€ˆxlkpheXRZXYY[MPUVYXNIHEJJHGC@GECG=998;9:9<:9;:::@<9:<98>787715234533645031.**+),,++)(+'),,226,,4775478iO8;5n’ˆš™–£¨­ž±ž§º¯«²°Â±»Ãǚ–”™‹Ž…z„˜”Œ†q‡‚t‡Œ†yprpoodqg_TFIC><;9:?@ADCEGILOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOOQULAIQIb¯²Ÿqzwk|lq‚…z„††yr •tx€su”‡5q¨Ž¡¡„¢…vp‡|‡|s‹­‰hgbjnrmpƒuioXupŽ›‘vm{}mrnp€{svnbuƒ†€…ŠŠ‰‘‹‘‹‹ŽƒuxŠŽ€~ƒ€}Ž{sqqm`[]^\ZYa_RN[ZXWKHJFIG?CABG?CD=;97=;:;;9:99;:?<88=:8;66651121253474531./,,+)*))***)(*)+/3DM2166643<vR7=7b’’ˆ•‘¤§ž¯•¥´©®°®Á²»ÁŖŒ”€ˆ|n’‰ƒŠ‡†u‚„l•ˆˆ{txxmwnwdj^IPG=?7449;;;=>@BEHLLLLNPQRTUVWXZXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL7CMQSDK†u|{u~lvˆˆ|}„ƒŒ~u¢šz~†„™„šœa†ªŸŠƒŽzw‰~‰ˆŽsŠ—„{]dqtz|wŠmhjbyo…‚zoxu…zptzxkni]v†}‡|‡†ŽŠ’—ƒ…Œ†}q„„}vw{|‰xqtufg`[[^S\g^WPTX[UGJJEKG?F@DC>AA=;97<;;=<::99;;=>79>9985653244004645554-,)+('''&(())((+++/00Uq=23331E~W4=9\ŒxŠ“Œ‘œŸ¦‘ ª ±¨¯À²»Åº–Ž‘”‡{†vkŒ‘‚}ŠƒŽŒxƒ€s „Š||p}zhvlRXL@E211366688:<>AEGFGJKMOQQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMOQLKT]YRKhƒˆ{‰y{q|Œz|‰‡~—‡v¡šˆ‡’”¥­©H†®¯®‹€“Š‚‹‚„’©‡€˜˜Šœtm|†‡~Žhghyn…‡‚…q„†Hl€wryvhmk_v}‚ˆ‡„‹y”œ›‰‹ˆ‘zuŠv|xmow~€uusm\^^[ccXgf\TPPWYPDLKFOICFCC@@CA=978:::;;:888::?>6;>7585773344236656768;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|}‰…‡‘Ž–—’– ž¬ ¦¸¯³½³—’‹˜‹}tp~‰’~}Œƒ’”}†~†¤‡ˆ‚ˆ…x‡ˆ~s„x_cWKB60./23124668:=>?BEGHJMNQSTUTTVUSQOGC?80,#‡[??84.]–ps£UFIKMMPW`XpY\^iŒ“†”€„…‘’~…ˆ‘€š•‚¡¡˜•›š¦­“™»±§»Ç苌¡¥”‰‘|qƒžŸ‘w……‹‡ihp„tŒ‡„Šr†‚w‡{v„|nvuf”Ž‡ˆˆ‡ˆ‡ ª¢–‰Ž—zˆzypgkx{ule^[[^j^bg`ZOLNWRQIPJDNGCJDCADDA<:87=<:<:88778:==8<=68656623444576867<BB?<8:>CQ^e\G2'&,,--.1(?‹[.310Oƒ_4?;nupfwƒzŒŽŠš›¤¡¬¦«¯°—‘‘„¡”„xwŒ”|~’†’•Š€’›Žƒ€ŒŠ‚‰ƒŠ€mpj]B@4--//..02234778;=?BDHINQRSRSSTRPOHDB<87/9C><<63.l“—MPHILLKNV`cfgmt›šŽ™’’ŠŽ™ˆ’‹  ’£ª¥¤¬“©¶¢¨Á®ǯxº”š|¡ž™„“…‚Ž¡Ÿ”™‘…Š…™‘–lpuŠŒ‚–ŒŽw„qm…Š–‘ƒ…ˆqˆ •†’‰–¤´©›Œ”¢ƒ‡’ƒ}kjj|‚ƒuc^d`[gl]ll^WKHNRQMLLFIPCDMFBCEFB=997=<:;:987767;:6=:785456344566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYo‚ou†qv’†~—–š”žžœ§ ©–“˜žge¤š~„’‘y’ˆ‘’}Š„˜’‚€€‹Œ‰†‡…‰…xx~gMR>/..,/.-/000212467;?CENORTPPQSQNPIED>;<:DF?><752<?R5HHHLLMNR^nŠ|s}Ÿœ›§¥¡™¡—¢”œž¨ž¨«Ÿ¨¬©ª¶—«¿«¶ÈÈ·ÈÐϾ› pi«©Ÿ„“’…œ š›™¦’‘ˆ•¢››xz~”˜“¢“——”ž{w•’«²‰—Ÿ|”›’•˜£¡¦µ¯œ˜¨‡–€ˆlss}}si`^b`bhd`gf\REJKPOIILFFMCHLFGCBGEA:85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Ppt`m|awŽ}{”ŽŽŠŸ’—ž–›ª˜žªBD}‡‰‡˜x‚ŠŽŒ|Š†Ž‚€‰‹Š„’…ƒ†‰€†v^bP460-1/,.0///..0015>AAMQRTQRSTRNSLEE@<>=FG@A@8662<9;FHGIJNOQYm…w”Š¢¦©´¼¸¤­¬¬¦¨´«°¶²±­»±³¾œ³Ã«ºÉ˷ÿ¸¥¢°³¬­ª£‹–˜…¦¦ £—¦™¢«¨¥ˆ…”¤¡ «¡¤¨œ±‹•£¦·º› ¢°’¢¢£¡«¯¬²µ¢”¤ªˆ™ˆ’‰•yz~†€ibi]fc^dd^gg_[OCIHSNFHLFJGFFHAKFCFFA;87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLhbWioXz…v“…ˆ‚›ƒ’Œ’Úȝ–sV—ˆˆœ|†ŒŽŠŠz‡‚‡Žƒ„‹…†ˆ’†‚„‰‡ˆ‡‡qna@E64<3/110-,+-1.-4?CAMUQRSUUVUN[PGHE<>>FHCEA7;<5C;=FKIGHQOPW’Ÿ„­£²©±Àƪ³Å¶«³¿³¸¾¶¿´Á¶»º£¸Å¨¶Éǵ¾¹´¨£´­°±›™’šŸˆ§¯«¥”vŸ¤—¡¬²´™–ª®©®¶»²º¬°µ¢±«±µ»·µ®´ §¨£§š©¯¬²¹·¸¦›¶©Œ¤Ž‘“Ÿ†x…wZceWgcbd`ag`[TJDDLUQHIJDIGEA@@KDBMG<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AFWQJL[YQbcWyup”}„†“u…€Œ{¿»£¼‚´”“›„ˆ’‰ˆy†€Œ’Œ‡„Ž‰‡€†ˆ…Š‡‘zxn]V@EN<6:56AB764//6CHBQ\PQUWU\VP_UIKKA?>GKFFD;>@7D7?BJJEFVSP^¤­£±´Âµ·ÁËȵ»Ä½³³À¶¸Áµ¿¯·t±³¥ºÄ¤°Æ¹±³±´¨¤µ¶ª± ¢—›¢’¥°®¦­«§¤˜ ¬´»¢¨²ºµ¼¿Ì¿ÅŽ½³Á·¹·¾·º·¹¬¬°¥°©­½°¼ºÂÁ«˜¹§”­Ž——ªˆ~ƒ~lXdbYkfjfW\cYVSIGFLQGCHIAHD>?BBL@@MD99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FRLALQVSYUZvjo~Ž„€„nzsx‡b¹¡™£‰””–’”“–’‡†{†•Š€„Šz|‹‡†}Š‚‹„•}wzueP\dGEL;Qca[^SF?;HPEZcRRYXZgYT``LSPEA?IJHEEA@D<E6B>HGJLSZT]“®¸´º¸È¿¹½ÉÌ»»À»·µ»º¶½´º±Æ`u²¤±šž«½©¥¨«ª¤¢²µ «¨ž•–Ÿ™Ÿ®¥§¦¥Ÿ¤“¢§±´§²²½¶Á¾ÓÉÉÓÆÃÅÌÂÊÃÀ¾½¾»¼·´¯¸·¶Ã¹Å½Âǯž¹©¡«Ž¤¨µˆs`cc_Xc`jgRX`VRUIEENK@>GD=KA=B@=F>;HA796379>489:57045/26389374426?8@>GKRTSQPOQQPJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKE@IMPRKQ]glkpŒ„slrrs‡ÕÀµ™ •˜™‘Ž—’––Ž†‡}†ƒŒ–Š~ƒƒx{‹ƒ‡|‹yŠ‚—~t}zkfpuY]\Pedb`ed][XW\MdmURmm_n_XgdUYUJDBKKHFHHHHBI:D?HKTTV\Z[’¹À¸½¶Å¿º¸Éʺ¶¹µ·¹²·µ³®¶¶˜du¨œ­p^¢¬œ˜ ¢›¤žª¥”Ÿ “Ž–™—§ž¦ žš™ƒ¤ž¬¥ª°­¸°½¹ÔÑÏÖÐÊÌÒÌÏÎÊÆ¿¾ÂʽÁ¼ÁÀÄÄÅʾÈ㤻°´¯š«¸»˜{m^a]Z_bZdcP[`SPKCAEFE<@E>AHA@D=:E>=J?37535;=468977022/24169775555D3ELM>51/006:477@IOI;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODQ\Yh_o–‘”nlotu‡³« ¡Ÿ‹™œ™ŒŒ•‘›’…ŠŠ~ˆ‡Œ‹‰|ƒs{Šƒ…{‰t‚Š†•s{ylmu{hreiligjih`fiilZms–­¤¼ˆ†g[oh]ZZTHKNOJKPKSQHLAJFJO_^bgia—·Ç°¸²º½µ±ÄƵ¯¸°°»«²±§«·«Œ¶§š§šNšŒŽŸ–‘¦˜¥•Š““ˆ‰‘‘›¡—š•–‡žš§›¬¯¨°¨´´ÔÕÕÖÓÌÐÓÕÍÓÏÍÅÂÉоÉÉÊÉÑÇÌÍÂÐÑ·¯Ã¼Ä¹¥µºÂ¢ƒpe^^_YaXZfZQ]XOPBBHEBH;AC>AG??A7;D>@H=46655;:687654/10146278875367C5B8?-0-1349=97,.,1;FK=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYReVs˜‚hqoyyƒ ©ž¦—Œš›—‹•‘šŽ}‰‹„ŠŠ‹‡|„‚p‡†{‡rƒ’‹Ž}qxulqx~qznxslipmcjmpxiw|~Ë¿Áߧmcxnc[a`JPRUNY^P]\NPNTQUT\nmv‚q–­¸¬´¦°µª¬¼¿°«´¦¤¸¦«® «´£Ž±®š—˜Œ‘“‘„Ž›¦‘œ‰ƒ‹„Š‰„‹„”•——“›œ˜™šŸž«¬¥¨¢¬­ÏÒÕÒÎÌÒÔÔÐÔÑÎÈÃÔÑÇÍÒÓÓ×ÌÑÑÅÒÖÅÀÎÇǨ¾·Îž{pg_d^XaS^ZPQTQOH>@FABE<@A>ED>??:==<<JA45465<888664412/03526768533;=<E=@11+/249>5901022-2DN3)/3.32=N238C}_2A†tD:==I>@CFH<VRMNZu†…Šwlwo}~¡žž¡ŒŒ˜““‹Œ’–„y…Š‰‡‘†~{r~‡z„u…“ˆovrks}{v{sxrj€srioqzyqz¾Ëš~Œ²„vr„vhak]CZZ[VecYdjTX\]`d^cwz~‹˜©£¤¡Ÿ ¨¥ª°¸ª¥³£¡­¢£­¡§±Ÿˆ¦š“’‘‰‘Žˆ“‰j”¢Œ™„†~‘ƒƒ“—­‹•”šŽ†“‘ž—§°¡¡¡¥¤©ÈÍÏÈÂÌÑÔÒÔÒÎÓÍÆÖÒÌÔØÖÖØÔ×ÕÉÔÚÍÉ××ÑʬÃÂˌtpebaYUZT\PKGIJJ@;:;DAD<BC>GB>BB;<9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/--;R017/532FD28>nb5=tM99@I<AD?A;PLFKYp€u}hsxr‚‰€œ””…‹•‰Šˆ‡Žxƒ“˜ŠŒˆˆ‹ˆ~‚xs{}ƒ‡wz†‘•ƒnwpmuvx}t…|yl‡vtn}v„tx{µŒ;A‹Å¥~Œ|ieWICfcecgjcnw[^fhknin€ƒˆ‹œ —˜ž££¥±££²Ÿ¡¥ ¨ £±œ…ž’’’ŠŽ‹†ƒ„~œ›Œ‚„…z”‚©•£Œ‘Š—’‹~˜‹š’«³˜›œ¨œ§½Ãƹ¶ÆÎÒÐÒÐËÒËÉÔÎÐÕÚ××ØÔÙØÍØÛÎÉÙÚÑÖ¾Ë˵zxpf^[SWR[VFGJIEE=:7:@@B:FD?DCADB;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?1*(.BS39254/7K75<`bA<svV87AH:?C><9QECJTknnpbpqs…|—‹‡’ƒ‰†…‰‡|x…––ˆŽƒ‡…†z„yqz{ƒ†uz…Žœy‹p|oozq{qƒ‡€nŽztw}|‚u~{†‡¯sX©Â¶‘‚pnb=^hrpqpnxvehoruxqz‹†Ž“‘›•Ÿ•‡Œ“› šž©ž ¬›¡š™Ÿ¥žŸ«™‹šŒ‘„}ˆ‡ƒ…‹Ž ™“ˆƒ‡~l™z„™†ˆ“Œ”Œ†|œ‰”®ª”–˜Ÿ™§¯¶½©­¾ÇËÉÉÌËÏÉÄÒÊÔ×Ù×Ø×ÕÛ×ÓÙÛÕÐÛÚÑÖÈÔ˖{}jj\[QTT_HCFIH>A>=7:=?;=G=?AAADA>>:86DB755479.566435532323647553458EBDCEB56<FNSM[nfcnskaV>,4LG865434BF4=W_hLux^8;?F<<B<99D?CGRj^mdbfkv€ˆq‘š€z€~‚‚ƒ~ƒ{|„˜‡‹~…†€v‚yn{{†tz’ž vŽu‚tu}s€„o‚o’„u|…zv†{ˆ·Å¤Áɸ–šwpeNfczw†¢Šxyv{ƒ{„vm“–”•—‘„‰–™—–¥œ—Ÿ–ž“’—¢™«•‰Œ‘‚Œ…ˆˆ†‘ž›™ˆ…Œ…—zˆ‰Ÿ—ˆŠ‹‚}¡Š‘‹¼ ˜“—™©¦¦®Ÿ¨¶¿ÀÀ¹ÇÉÍÎÅÍÊÑÖÕÕÙÕ×ÛÔ×ÙÚÛ×ÛÚÚØÎÛƈ}{ikgbUXVVNLDMB;==<8:<>8=@6=?@=?><9867DA6455=80665547745613854564557HH=DJE7925;H>;::7IP]ZRUXK9T>;95327I8=NYMHxxd5=>C==@:6:>>@EQ_Xea][htzyl‰Œ’wvzŠ{~€~|„z}‚‘‰„…z„‡zu}tm|}†~t’ž‘žƒ‘|†~x~xŠŠn‚š€t™†~‰…|}z©ŽÃ¡½‹œ£œ}‰„}‰r‹Š~s¦šœ˜“…{Žˆ„hGq ¤Œ‹’…‰‹’”Žœ™’”–Œ•Ÿœ” ”‘‹~ŽŽ‹„‰’–šžŸ‰Œ”‘‘‚‹¥™ˆ„‚…„€¥‡Š‹¸˜‘•–¢¨¡žž¤¯·ºµ¬ÀÆÊÐÈÇÌÏÓÓÒØÓÕ×À×ØÙÛØÚÚÙÙ×Û¹{{zmkgYb\TPOICLA<<>99::99;=6?>><=9:;;37D@8378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWN<MTHN?96333>C;[X>5YypZ<<A<=>8689?=DRSRX^UXfmmmiŽŠqsyŠ{z|{‡z|{‹†‚}tƒ…yrzsm€~„~w…œ¡š”’€Œˆ˜‡€œ‘n‡¨…z ‹|‘ƒˆ„›}šŠŒ£¢ ¤®ŸŠ‹…‹“†Wr­‹Ÿ«›ƒ˜›Ž\‚¢‘‚ŒŸ“•Œ‡ˆŒ’“‹””“Ž‹Š‡–›œ”–Š’“†€‹ˆ’ŠŠœ–™¢¢†“– Š‰ˆœƒˆŽƒ‡…¤†Œ³˜’•—¡¡Ÿ™’œ¨²¹¬¦½ÁÇÍÈÆÏÍÐÌÏ×ÑÑÕ®ÖÕØÚØÚÚ×ÕÙÙ rwih_^YTXYCAHC?>>:49:;7:;;3;;?=>7;9:1:H>:37=@50677255?65;55858:57735HR7GOK994=EJB>1FCLB98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:;@;BQKKSYPTcbyma~‘ƒomw‹xyz|…{{v…„sp„zuvvt„ƒ…~’¦¤Ÿ¥¢–Š”—‹Š¨—sŠ±„§’„™“…™Œ¢•Ÿ˜“ˆšž£’©¯Ÿ‘”Žˆ–Œn·…šÄȱ›¡¥›œ˜–²‘d¤ÍȖ†‡ˆ’’“‰…Š‰…–™š”“†”—ƒ‹™ˆª–—££ˆ™Ÿ–šˆŽ†–—Š„Žˆ¤‰“¨š—“—™¡™Ÿ™“›£³´¦£¼Á¾ÇÅÅÉÈÉÂËÓÍÍÔ©ÒÑÖÖÖØÚÔÓÚ΄u‚kf``_PKV\BBFC;A=837;<:8=649:<:82?992:I:=67BC32:96264>=4;>6949;57944JQ<JQK9A7BGI@64JELF><88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBdƒGu‚Ž}|m}ˆxz~z‚~vv€‚{lnŠ~y|wx|„‡‹~‹£³¨¤«²¡–§ ¥¤–•¯¢ƒ¸•’³™¡ Œ¤›¯¢¤˜§—©™­¯¤—”•”‹˜š– ÀŽ£É¸«š¢¥­™‘›œ²†…¨¢˜…ˆˆŽ•Œ‹“‡†‡ˆ’˜”ŒŠ““†”˜†ƒ‘œt‘™²•–¤¡ˆœš“ŠŠ—š‰Š–†}Œ˜žŠœš™“™˜Ÿ” •Ÿ›¡±®£¤·¾³ÅÇĽÃÿÆÎÊÉÒ§ÏÍÓÑÐÖØÒÏؼu|x_bWbXRIKOEBCD5>:76:?;<7=42669774=5;5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=89567=:JFDGM[\YIha;H„Šz{m…†y|„x€…€}px|}|osŒz}‚{x…‹‰†ƒ’¨¼­©²½¯¥®³³©£¢°¬Ššµ¢¸¥•­¤—©­·¦¤£Ÿ™©˜ª¤¯°©š™›”•‘˜ —™»»­É¡i¶·ª°•˜ž¢«’—½£^©²‚‰ŠŒ”‡‘|ŽŽ}ƒ†””ˆ‡’–‹•‹Œ—™’š´–•«ž‹œ”’’‹˜šŠ’‹‰•Ÿ¡•—™“œ˜ž•¢ ”œ¥¯¨¡¥³¸«ÂÈĶ»½¼ÅÈÈÂСÆÉÍÍÄ×ÖÐÊÓ£s}k_\UaSQGD><CAB8?874>F<<6<35355454B39:BM:A;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPfHa`bpI@‹‰€r†‡|‰u‚Š‚~m}}|~pw‡w‡{Œ†Œš«ÃÀ°½Æ»³´Á¼´¬«³·Œ¨²­­½«›º¤¨­¹·ª¦¦¡¢££ª¯²±ªœ£˜›˜—ž¢¥¥’£¹®¨À»¬­²¹¥¤§}ˆ†œ­½¯‚‹‹ŠƒŽƒ‘Žz‡Žœˆˆ—Š”—”š—§š°š‘«Žš’Ž••—Ž‘ ˆ”›£¬•–”œž” ž›˜ ¡”šž§§¤¢¤°³¦ÁÆ𰻶ÅÄÿͧÇÃÇüÖÐÌÄʊvud_\b]OKCL@EF>A?A<:4>A==5=6>333242A17@BN>G@CNCA=C=;86CC5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GE?CF\hF_igZ]\“ŒŒˆ{‡‹†ƒŒu†Šn~{~q~z•z’””˜‘“•¨´ÇÉÀÂÌÁúǼº¯«¹»—²¶º³À®¥À¤«°¼¼ª®«¢¢ž§¬¯µ°ª› ªœ¢œ–Ÿ°´§‹¢ººµÁ»«¨œ²¤¤¨”„Ž©Ä䂋Ž‡ˆ„†•”ŒyƒŒ‘’¡ŒŒ”‘ˆ— —’™•—¦ ®œŒªœŽ–’‘••Ž•‘¡“†—Ÿ ²Ÿ”›” ¡™¤Ÿš œ ”˜ž¦¤¦§¤¯­¥¿Ä®©·µÉþ¶Î²Ä¾Ã»³ÑÉÇÁµw{o_Z^lTNIDMKKI@A=BD<5AD;:3=8B332262A05IEM>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBg\Me\fTcj™—‰‹ˆ’†‰y†“r{~w‡‚z¡–¨šš˜»¾ÉÈÊÂÒÉÊÂͼÁ³­»¿§º¿¾¼Ä¸¬Á©¬³»½ª°ª¤¥£¬®´­¶µ  ®Ÿ¥¢˜£´¼©›¨¼Á£µ¶¯«’¯¬ª«–†š©§¥‘‚Œ“¤•Š€u‰’y…‘ž ’Ž”‹Œ”£™–›””£ž©Ÿ‘¥šŒ•–ˆ}•’’£š• ¢œµ¦Ÿ—¥¤£¥Ÿž¦˜ž•—œ¥£¨¨¢²­¨»Àį¥³·ÌÀ¹®Ã³»¾Á¸­Â¿™p{c[X^\MMNJGDDHBBACK:4DH:;4<7E.12352B26SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQF7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>lI_XaZddWž—Žž’‰ŠˆŸ’„x…•~ˆŠ€• ™®§£˜Ã¾ÉÄÈÆÒÍÎÍ˼·°º½´¼Ë»ÃÁ¶·¼­³À¹¼®¯¨¡©¨¶­®©²·šž¬¢§¡«··©¥¯¾Ä±½¹³§©³³­®–•¥­¨ ‘Ž’±Å§•}‘•}‡‘˜ª™˜““Ž“•“¥ž“™“¡¢¡œ˜Ÿ˜‹ŒžˆZ–—’–¥™e˜£ž³¥–¢–«­«§œŸ§—˜–˜•¡¤¨§Ÿ¶¬©º¼Ãµ¦´µËÁ¸ª¶¬³»¸®¨¸º¼·„np\ZVWPGKSMK?AHDDHFF85FM;>7>AJ.32025B55PWN;LFKRLOGGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|hV<>@BFBsFiIRecLF¥”œ•¡—¨–Œƒ‡¥’ˆ‡‚›„ƒ•‘”Žš¢Ÿ¯¾®¡Ç¾ÆÅÈÇÎÎÎÒʾ»¶±º»¼¿ÏµÄ½·¹·²²¶³·³¬¦««¸«©¨¯°—£®¤§¤¥´Á°«¬³¾Â¹À¹³§¸´·³¯•¤­°®¤‹“•¡sÁ™}–™„Ž–™‹±•šš•’’™™¦£• ›–š©œ›¡ ™ŠŒ•œ`J–œš”š¥—T–°Ÿ¯œŸ¥”¯¯­¦›¡¦”“™™Ž §¢™´©ª³½¼»«°²ÇÀ¸¦¬«­²±£¡²²´¥sqg^\PRMEQQPQ;HKIFGAC=9KT?A:=EM07544:B34NWO<JKNUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@CAF3>58JKCA=C;4EA:A?>H@5*B52,>c]g:35tde@R7&#3}hX<:BC@=REWSsbVFH«—™Ÿ¡¨®˜—‡Š§–Žˆ’…Ÿˆ„œ—ž ›£¥µÉ´©Æ¼ÃÄÈËÉÈÌÎǾº³®¹¹ÀÁ͵ȻÁ¹µº±¯¯²´§£›ª´´«©¦­¬™¤®¥¥¨¬ºÀ¨«¶¶¿ÁÀ¿¸²²Ã°·½«£®´­¹¥ˆ›—¦›v¾Ÿ„˜œŽ’˜š‹®–¡œ›—”šŸ¡©ž¨ š›ª™¡§ž—ƒmu“¢š•œ¢Ÿ®²£«•©ª˜«¯¥¥ ¥ª“’™œ‰•œ¢ž–±¦©«º·½³²®¾¹¶ £§©¥¦œœ¬©©fhb`SLMGHNJUL=MDMIJACD<QU<AABDO18=77?B75UXN?HNQXRPQTJQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW<:=..SaMVH~e^HF¬•œ¡Ÿ»®˜”ž‹“ª›‘‘“‰ª†¡žŒ£¬”¤¤¶Ç½´Á»ÂÃÈÉÅÂÎȽ¹²¯¹´ÀÂʶƱÁ¼µ»«©­¬°££™ª´º¦ª§¬ª¨¯§¤««¾¼¨­¼´¸¾Æ¼¶µ¸À°½¿³©µ¶«¾¤¢—‘¡Ÿ»ž‰š ™—¶ž©œ¥£›œ¡š§¥³¢›ž¥œ¨ª˜•”›‹–‰Œ¤¡”œ¢ž¡µ¯¥¦“±«š«­ŸŸ¥¤ª‘–• „žŸœ–©¤¡¡´´ºµ­¨µ²²žœ£¦š—•™ª¡žxc_a_LIGHMQIMDFFAQKIADGAVRDH<AGQ1;B7:BF79]YKALPTUSMWRNUJD@JJNO9C?5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-1:h]FDCœpbGE¨—¤žžÃ¬›—¤—™¨›•ššª–•¨¦•­¬™¢ª¶ÅÁ¼¿¸ÁÃÁÈÄ¿ÍÆ»¾¹²°¸´¿Ãȵ¿°¼·º·§¤««¬¡¡›«ªÄ¢¥©¬¦ž«¯¬¢ª¨¿¸¦¬½°··Æ¶´¹¸¾°¾Á¶´²´¯½£–£•’›“­Ÿ¡¡¤¢£ž¾¤©©¬ ›¦Ÿ½¢˜£ž¢©« –•ž“ž‡Ž„“ž¤¡µ¬¦œ–²¦™°© ›«Ÿ¡š•Ÿ„Ž¡š›’¥¤š˜«±µ±ª¥ª­¬œ˜ ¡’Ž•¨Ÿ”ie[b^PJHKOLHECI@=OH@;GIH[ROK=HNU4BE8>HG5Cb[KCNRUWVQXTRUH@8QQPM:G@4CHQSIC;C>GVKC@O>K<06;GF>;FA56?9:?9;15D0-,0Mv\4KZ5,MnW<-=)#zbQ5CKQ9oRF<KxfcWM¢›¤›žÅ«¡Ÿ«œ­Ÿ’¢ž–¥ ¦©¬—¶±£ª³¶Å½À¶À¼É¿Êȶ¸µµ±´´·ÂÆ·¾±¸µº¶ §­ª«žŸ¥¤Á¥ ©® ¤©­¯¢¦¨½µ¥±»·¶µÃ²³·º¾±ÃÀ¸¸®´´´£œ¤”‘“ ¬Ÿ˜¡¨¨ª¢šÂ­©¬­››ž˜¦ ½¡¤˜«««¦ ™™Ÿ’žˆŽX–ž¦¡ ¸ª¦”˜¶£ž²¢¡œ°˜ š”ž‚ —–Ž¢£•¥®³«©¢¢¥¥••œ™‹‘“¤Ÿ‰cg\eaMJKKOFEAFK>=IA99JJN]QQI=LV\8FI=DMI8Hc\KCLPSYYVWOZ^IA=WQIK?H@5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+waS6SZkWsHE6=ue\LOž ¡˜žÃ§¥¢³ œ²§“ª£Ÿ£Ÿ¬©¬»±©¬µ±ÈÃÁó¾ǼÄʽ°°¶®±µ¯Àŵº±°º¶­š©°©©›ž¦¡¨Â­›¬±œª¢®°©¤§½·¦¶º½¯·Ã­³³Â¿±Æ³º·«´¶®ª¢¦••”¢«¡ŸŸ™§«¯¯¯»²¦Ÿ©©™™—“¢¤¸¡¡£’®¯«¤¥ž’¡ž”Ž”š£Ÿ§´§§˜´œ£¯›Ÿœ¯‘ ”˜”š€’¢–Ž  “‹¦¬°¥§¢ ž’’š”…‹’œŸ€dh]hfKJLKSBC@IG;;F>89NMU^RSJ>O^]=HPBMLI8Nd]LELRTY[SUO\bHA?ZQAHAKB7FELKN>;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<w]^?[U_fr@8<H–weA4Ÿ¤Ÿ›ŸÂ¨£©± £´©•²«¦¢¤²¬­©»²­°´´Æ¿Äĵ¿Ä¾ÊŶÀɵ«µ©±¸¬ÀÅ´¸®­¶º¥™«²«ª˜¡§—­»µ›¨°›­Ÿ®´²§ªº³§¹³¸²¸Àª¸²Â½´Å§¾®­·µ©§¬¡––‘¥¤¡¡——¤®·­²µ¶Ÿž¨¤™”•“£ ·£¤¥•®±²¥©¤¡žš™š•˜¨Ÿž˜¢Ÿ¯²¢§—¯˜¥«˜›Ÿ¦’•˜š†– •Œž”‹©©ª¢§¡™–Œ™†–‰•Ÿzej]lkOQNNT=BANC;:I?77QN]_RVQAW`\BJSHVKH:Td]NFON[W[RPQX]GAB[PBG>NC9HGHNP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1\cZ33906p[bH05JqjVCWFŒyfC;¤¤œ¡¥¿¦¨®® ¨µª¸¯«¤ª´·±°¸·°·¸·Å½Ãǽ¼ÄÂÇÁ¹ÁÆÁºª¶¥­»­Á÷¸ª­²¼£•­°­²—¦¨‘ª¹ª¡§°«Ÿ¯´³ªª·µ¬»«³²¹·¬¸°Áº½¿¦Ãª°¶®©ª«¦˜˜ª¡¡ ‘— °®³«°¹™›©Ÿ™–’—¦ ·©¥¢¢¯±³«±§« œ Ÿ›ž¥ —¤´°›Ÿ”¦š ©›–¤ —™‹–™”–—”‰’›™”Ž©©§ £œ˜›“‡™‹~Œ—†šljmbnnXQQZTACEU@;;H@7:XPd^PWWDY^^NLRO_LJ>Zd^NIQN[UYPKSWZI?DXPDF>N?=IGGQPB=CFBM?:2D?77547?=95E4+75/251.-.,1>*'+=\p=>1.1e[d@1747gYaF(@8m}h\V:‰{cC=¨Ÿœ¡©¼¡ª¯ª¢±·¨¥´²«¡­µ½¯³¸¼»½·¶ÁÿÉĹÅÃÀÀ¹Å¾Á¸¯¶¨«·²¼¿¿´©¯²¸Ÿ—¬­¨®˜¨©Ž§»Ÿ¥­³Ÿ«¢±°³¬ª¶³µ¼­¯±µ¬°µ±¿ºÅ¶«¼¯±·¬¬©¢±¥ž¤¨Ÿ£–˜Ÿ²ª³©ª³™§›š” ¦¤´®§¡¬¬­±§²«±©£›ž¨¤ž” ™›©¶©—š’’Ÿ™ž¡Ÿ’­ š™‡–™Œš”‹–—š—¦¦£ ž––—”•…{“ƒŒ—gmshps_GYfVDCNXDZ9HB5>]Qh\NZ]G[^]OMRXdJKC]c`PLMNXWXPJVVWL=EUJEDAM?AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,+%2+*5K1.'_^aV151=`V_8)C3YU\gK5ŒzfL@¤šŸ¤¬¶£¬¨¤®­µ©®³¸¦¦°¸Æ¶°·¿Âµ´ºÅ¾ÌŹÃÁºÀºÄ¸Á¹²µ¬ªº·»º¾µ«®±·™˜¨«««œ­««¾ž«¯±£ªŸ±­²®®µ±¸¶ª­®±§µ¯´º¼É²ªµ´±´¯®¦ ³Ÿš¨¬ ¤••š™±¢­ ¥¯–¡¤™™’¢¥¦²©¡¦±«ªµ¤®°´®£™­§›—™™¬¸¢—“˜œ¡™˜”­ ž•‚”™Žžš–‘Š”“žš¥££¡™—“’–{Œ‘…{‹ƒ‹“loyou|aF`jZIHZ[={JGE6AbUi[M\aJ[\ZRSSbaLKE`a`PLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`Va.5(C^Q\.+A/JGP[G3cXTKEš–Ÿ¯¨±©¬¥£®®µ©·³·£¬´·Êº´»»À¿µ³·ÄÀÌǼĽ·¿ÀÀ¸À½²½®¨º¹··Â·¬®²¹•—§®¬§¤²ª”¯»¤¬²²¦§¢±³°²±´°·²©®«²¦¸¯µ³ÄŶ©µµ«°­©§¢¶ŸŸ¦± ¤”›˜”°ž§›Ÿ©©¢›•—¥¥¤¶§¢°³«§±§­¯µ¬¤™¡¬¨œœ›”ª¹œ•ŽŽ‹˜œ¢˜‘˜¨£ ˜…“—‘žœ˜——ˆ–—›¨œ¤¡’–’–w„‘†|†‚„Œnqxv|]Kel\JOd\?b{GI8GgWf[L^bMXYWUXTi]POHa]_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANIg27'FaLV%-B.=ELQ<3rkLDD‘™¤­¤¬­«¦£°²²ª·°µŸ«µºÉ¸®Á¼Ã·³±µÂÃÏÄÀ¾´½ÁÀ»¿¼´Ä¨«º±¶·¿½¯¬´´¡§±­¥¦±¥ž²µ¬ª²±«¨¨´¹¬´²µ¬³¬ª«¨¬©¹­±°Ç¿¸¤¹¯©­­¦§¬°¥¤£®£©œ›š¯™¢¢¢£¬Ÿ£ Ÿ¡©¦¥¸¤«³´¤ª«¨¬®¶®¢£¨ªœ ™š’¤´™‰‡‘£ –Ž•Ÿ¢–•†””ž›™–•‡—’•™§œ  “’Ž‘x~Ž„}}}‡ŠŠrts~~\Rdn^NZg]FD–[G:NmXbZMabNVVVWTYh^QRLdZ[TKGOTSNGIVS\N;P^JBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3Ce;6*HdHJ+:I?3CIS,>k?HIš©ª¡©¯¤§£³´°´µ±° «­½Ìº®Á¼Ç±´®´ÂÃÑÄÅ¿Á²¾Ã¼¿¸½Å¨­·­´¹¼À°¬²®¡£§®ª§¥±£«±ª®ª°®®¬«²º§·±²©²©ª¥¥£­º¬ª°Â¹´¬¹¨©¨­©§°¥©¤¢®ª¨¢žœ¢¬•¥—ž˜«¡§¨¡¬¦¢¬¬·°± ©¢Ÿª­°«ž¦§©š£—˜ ¨˜†ƒŽŠ‹Ÿ ŒŽ—ž’‘‡ˆ‘•¡–˜–†–““—¥œŒ’Šˆ„}w€‡…‡utr‰vl_Y`ncQsr\K<„|F?WuX`YOc\MUVUWQ\b_TOOhXWVKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*35>10485(5/*,.30;),,'%234$,2-860)(1<^K0.IgDF8<B05EKX1@”]@MF•–¬§¡©±œ¨¨¯µ¬¸µ®©¤««½É»°¾¸Ã¯°­²ÄÄÎÎÿ¿´ÁÄĺÁ´ÉĬ¯¸®³¹À¿´®®¬¦§©±©¦¨²¦´­ª°­­±¯²¬³º¤¸³¬¬­§«Ÿ£ž°·«ª­¹¶¤µµ£©¨¬¬ª¬ ¨¦§±±£¦¥¡¡«–ª¡”› ¥ž£¢ª£¬¢ž¦±·¬¬¢¥¢š©ª­©¡¥¤¤™Ÿ™•˜“‚‰… ‹›’Œ…Ž™¤›’‘›‹“‘‘”£š›š‹‹‹|‡‚‚{u„~ux‹£‡xk^`ngWf‡dN@g’LDbzWbXReUMVUUTO\]bVKNiWVVIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*49?./463)4+*,+.#4.-+&(+79*&6+<-2,&06XZ.0JgAA<<C+:JO^4D†BIHD–¯¤¢©¯˜©¨­µª¶°ª¤«©©¼ÁÀ¸¹´¼µ¦²¯ÄÊËÑ¿Á»¸ÀÀºÁºÂÄ®±¶²´»Á¾³²¯­¬¬¨·ª¦­°«¸®§°°®±«µªµ¶§µ·«¬¤©ªœ£ž³³¨¨¤³´Ÿµ­¡©¨«¨«¦Ÿ««¨¹¶©ª©©¡©Ÿ­›‘©¡ £¢¦¢ª›¦´®§¥©¢£—¥¦¦©œ¢££Ÿ™˜Ÿ‘Ž˜~‡Œ‡…žžˆ…‹‹’…‡–£šŽš‘’Ž’Ÿ—™–‹„t‡~xuƒ€zx~€ˆprggqx\atˆiO]˜VHmyUdVRbOLVTUQOX[bVHPjTVTGPYUI>IHOQPxMNV=<KD?@A<@CUC9AK=5;E13;97*4:=+-341*8**+*,)*(/*&)%3;,$2)2021%/2Rc02?f=NX?C,?LT_/Ik7RF;•¯ ¥©¬™ª¤­®²´¯ª¥¯©©»¾»Á±°¹­¢¶¯ÉÇÈÐÀ¿½º¼Ã½»ÃÁÀ¿¯²³²¶½¼Á±²³«³©¥µ¨¤¬³²¸¯¢­´±¯±¹ª¸®ª¯·«ªž©« £¡µ­©¡ž¯²¡µªž¨§ª£ª¡¡¬­¨½¯«®¬¡§§Ÿ«™¯¢˜¢ ¨¦ž§›˜©°¨¢Ÿ¬¡¡’¡¢¢¦˜™¨¥˜˜˜Š‡”ˆ|†„…¤–†ƒ‚Œ‡‘…†”¡–‰‘“‘œ”—Š††xt}txz{tt{j‚ˆ£vi^elugˆ‹|RWp^KxsTdSQ_MMSZgNMWYeYGSjRQ>BNQaQ:IHLSIqQLS;<I?;<=;@@W<<>H73CB15:93-5::)-31--6)(+-,52#2)',%.;.&1.0-14%,0Mh:38_=ad?F1CP[[+HP;YC4Ž±Ÿ¤¥ª£¥£¬¦´³°©¤°§ª¸¾Á¼°¨¹ª§®°ÉÆÈнÀ¾¹¿¿½É¼Â¹±°µ²º¼¹À³´¼­¹¬£µ¦§¬±¶¸²¦§ºµ­´¼¯»¥­­µª­œ©¯¤Ÿ¥¬ª§œª²¤´©šª§ª¤©¢¨¨©½«³°­©£ ®œš²¢–¤›¤¤Ÿ¤š™§ª¥žš©¡›‘› ¤˜–¨©‘™™’‹‚…}‚ˆž‡€~Œˆ’…”›”†“¢Œ“‘‹‘š’•‡‰~€rzx~|hw|{uqr~i†z„ˆd`hcr…{mgy]^VCX{mTaPRYKKMpt]IZ[gZEVgOC>KNDCA9HGKS?jaIQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11&/>KI1%90%,,09/,,+6'17#-/GjI14X=fbAJ7GS`U*=<F\@*Ž’°™Ÿž©¤£¡ª¤¶²±¤©±§­¹Á½¶°¤¹¬¨¨°ÃÉÈÌÁ·½¿µ¸ÁºÈ¶Ä¶´³µ²½¹º½¶®¹¶¿­¢³¦ª«®µ·´©œº»¨±¿²º ®´µ¨¬ž®±£œ¥§©£œ¤¯¦¯¡Ÿ«©§¡©œ£¨ ­»§®±®¡ª¢£­žž¬¦˜Ÿ›¡¢›Ÿš™¢ª¢šš££•–“ž¡–›•¥¬‹ž‘‘Œ‚Š€zš”Œ‰}Œ‡ŒŠ†“˜‘‡”£‰‘‘‡™“ˆ|yl}vyxb{zrpqsxj‚ujƒgchansŽmbip`oB]ykV^NQQKIMSYVM\^mWEXaO^PHMDF;7HEKO<rhJK9AE;;==;;=J49B<3;G<4?18-78;2(09/,5..=-*L>*49&'.34.0+/4&,:$40AhZ13S=e_DL6KVdN)=3R]=#‘—¬˜Ÿ—¦£¡Ÿ§£·¯­¢¯°©«¹Âº³­ ¹¯«§³ºÇÊÈ¿·Á¾¯´¾·Ä¶Ã²°º±²À¶»¾·ª¹¸½ª¤´¦¨ª¯­¸°¨˜¸¼£­¾´³¡®·´¦¦§°³ ž¤¥§¡¤™ž¬¨¨ž ª¯§ ¦—¢¨Ÿ°¸Ÿ£±¯¡«¡­¤›¦¦©šš›ž¢•œ›™©¦–›ž¨—’˜“™–¡©š‰‡}‡~‚|{¡Œˆy„…Š…‰“šŽ‰•Ÿˆ•‚Œ–‘}„{sp|qst`yxjopqpjsdzlhedbf‡€`[rjqMN€iXZMQLKHPRQHM\_oTEYZRgOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23/:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%53=fd24M?e]FO=RZgH*?0][5(•›¥˜œ•¬Ÿž¡¤¡·«°£³´©©ºÅ¶²® ¸­®¬°µÅÇÀ¶¿Â¹°´½·¿»¾°¬¾°³¿²½Â¹ª»º¸§¨µ¨§«¯«³¯¥˜»¶¤«ºµ®ž°¸®©¥§¯²œ¡¤ ¤¤¡–›¯¦¡Ÿ£¨¯¡ ¢“£¤¡·°¡¦°«Ÿ«£¯—›ª¥¨Ÿ˜š£“š›™œ¥©™››¤””—•œŽ“—¢¨¡‰Š†zƒ}ƒŠyŽ—Š‡z‚ˆ„‰…“˜ŒŽ–™ŠŽ–~…—Œz€zpqvnot_xwemlljj„ofrikfh^dt`[kviZJ^\XOOKHHRUG39]^lQEYUYeMHIEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<"8R=*113>D5,-'42*;+139cm74GAf[HTDU]hD.<2dW,2”¡¡—”›ªœ¤¡¢ ·ª® »¸¥¬½Å³°®£µ°¬¬®´Ãü³¿º·±³¹¸º¸»¯®À³´¹°¿À¸­½ºµ¥¢²©§©²ª­±Ÿ™¿µ¤§µµ¨²¼¨§¥©¯¬™£§œ¤¥”˜¡±¥™Ÿ£¨©œ¢Ÿ’¤Ÿ£¸¨¤§­¦¥¡¨’Ÿ¨¢¡¡™›œŸ‘š›–Ÿ¡©›š˜ ”“–™““£§¤‰‰Ž†y„z„…|‰Š‡z„‡‰‰’…–“’‹•“Œ”{‚—Ž‹w~{ltqllsawuiijggo†hhicfii`jcjh\f{c`StT\[SLJGIOS@!*h^jMDWU^`KIGEC.:B<F<6KPD8:D357==895?:;4>8@K=>93)8><:9*6@3.E4(+,?0-N?.+-7,1195,&.5-80576`tA3CDg[KWGU`hB379gP'2¢¤¤¦šž£´¬§ªº·§¬ÄÁ¶°¬£¶®§®®·¿¿¼²Á·°®²¶¶¸¶¶®ª½³®²±½¿·®¼»±¤Ÿ¶ª¥¥³¨ª­œÀª§¥¯²©¬µ»ž¨©«±¥˜ž©¦¤‘™¦­¢˜ž¤©¡›¡œ–Ÿ§µ¦¯ª®¡¡¡” ¦Ÿ¡ š›™›’˜œ“¥œ«¡—–œ”’Œ•—‹˜š¨Ÿ‘ˆ‰Šˆx…v‚‡Š‚‰}€…ˆ‡†„–”Ž‘‘Œ’{ƒ•Ž†s}}fxokjkfuskcgddvcefffjjcksZ_Z]mdaNiXZ`VJGHKMSX>9_liHCUT][IHFFA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A=-5B37=+*,0B*JK./*+3722(57$+7.72685]yN2>HiZLZJVbf@:3BhH%5š£ ‹¬¡˜— –¤³±¢²½¶¡±Æ¼º±±¤¶¬ª®©¹¼»º­À²®®®¶®²¸³©¬¹±¯®³¶º¶°¸½¬¦žµª Ÿ¯£©®œ¢¿ ±£®°®·­µž­®­­¢š¦©¥Ÿ•š§¥Ÿ™¥¢¨šŸ›”œž¬¯¥º§®¢¡šš™ž¤š¤—ž—›“˜Ÿ’¨•©§š“šš‘‹•™””š¨¦ŽŠ‰Ž{tŠ˜…‡|‰‰……ŠŒŠ’„”›“’‘–Ž€ŒŽ‚p€~fymhkifqrk\hcctbfgjnlgjjhn]lltpaTcideZIFLMOYQPVaeUAVSYTFHFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24;6#3*)6.55465Z|]19Kj[M[KXdd@A1JfC'4‘¡›Ž°žš“¡™©±¯Ÿ¹¿µ ´Â»½º±¦¶¯¨­¥·¸··­»®¬ª«¶ª³¸­¦³µ²®©°¶¶±³µº¦©Ÿµ¨¨¡¨¬š§½˜¬£®¯µµ¬¬Ÿ±­¯©¢›œ¢«¨œ”œ¦¤šª¢¤–šŸœ›¤ªª©»Ÿ§¤ ˜™™¡k¢–™œp‚•š£u‘©§ž””žˆ—™€–Š¡x†”Œƒmi~vƒql†‹†}…Œ‡p^cag„˜…k‹”’tw‹„~ƒg†€guheW\hsnNPjcgs…h_efnmj]`aŠ„„fNKD9GTg^JGPPUULHRaotfF[QUPFHEC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,+08=G601.*.*/568,#1'214:175Xl16Ok[N\K[fb>G1Qd=*.‹£™…•°››’ ›ª­ª£½Å¯©¸Â¸½¼­§¶°¥«£·³²³±¹­©¦¬´¦¯µ¢©¸¶¶¨§¬¶²®´­³¡©Ÿ³ªž¡£›¥¦˜«¹”¥¥¯³·­®¥©­ª¬¥¡žœ §¦›— ¥¥››§§“ŸŸ˜ž§©£µ¯£¢¢–———£ˆ Ž’™† ‡“œ ¥¥ªž’‘š‘ˆ„rxŽ…ˆ¡vˆŒi—ˆf}rx oˆ‡„~Ž}¡  ™€|‡žt‡Žu›Šl‡ƒlheczlqaS…mbli˜qXjqpˆY^i[ll[ˆqnzr…g†„Z^GN?G_MERVVQQRWUg^MWIRRPFGG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82).1<I9/01.*/(-4583%&2115>1<8Xƒu25Rk[N\L\g_=K1Wa70(Š¦–ƒœ«œ™˜Ÿªª§ª¿Ã¯±º½·À¾ª¥·°©¬¥²´®¯³·ª©¥°­¥´³œ­µ¶µ¦§¨³°­²§®ª ²¨Ÿ¢¢™¡¡š­³“£¤¥µ¼¦¬§«ª¬¨¥¡ ˜Ÿ¦£™™¥£¤˜œ¤©–”£œ““£¤¦¡·£¤ £˜•’—“œˆ¯—”‰©‹–¡›…±€£¬“™”y‚Ô¨€‡•Á›Çyx±¥·—dÀœ¿y„„y‘„|‘Êq—¼œÅzrµ¦»{€l–±«°xhkX±®nei¼’¼ngzorØ~Skc¶²r•tš¡ªWOWbPVNFU[XQPR\W\PA]DQNEGI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22BE/.32.+/)-/186- /416A1=:Wƒw21Tk\O[M^g\>L1[]41!Œ¦’€§ªŸ—œ¥¬²¨±Â½²µ¿µ·¾Áª§³¬¬©§®³©¯¶´§§¥´¥§¸¯œ³²¶«¥¤§±®®°¦ª§¤°£¡Ÿ–šžœ­«“ž¢Ÿ³º¢ª©¡­®¥¡šš¡§Ÿ—›§ Ÿ˜ž§§‘œ§š”¡¦¡¡°¢ŸŸ£––’—’™…¯kjŠª~fƒ•†­dpœ”™¥”q®¡¤~x»}k¡v±_j´[¥€eœ‘`f‚{fjxk©d¾rg¦Œu±j|±xt’“cmm§n[„ Ehf‡–Euœ`~h|¤§‚Y_‹«i€•xyj§7J¯\XSld[KNX_\WV;N‰PWW/ITSJDEF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3..53/+/(.0.:5/'$203B/=;U‚v2-Vj\OYL_gY:M5_Y30¢•‚¬¨¥£¤ª±·¬µ½¿°¶Ä²·ºÁ¦©°«®¨©°®£°º¯£¤­²£¨¸¨ž³³°£¥ ª­¯¬¯¦§Ÿ£¢°›¢š–•–šš«¥•›¡ž³³¡«œ¢­­ š— ¡¨œ˜£Ÿœ™¡¦¤¢™—¡Ÿªž¦¦ŸšŸ¡••‘–š…µ›µx…©™µ™v†³›·~“––¨”~k¦{‚†ˆ’”’w«gk±[«z†”t‰r†€ˆ—x‚‚‹˜‹ƒ „°vwŸqkkl|‹N¤XHbb™~ch¦`ysvS’‡^P©mcq~‡€bœ.Q¡o[Skh`LK[dX\ZB?²yXXA#MhFCDA@A19>88:84;:9<9:A:E::;6:CB8=?KNG:5:AFB@AD<FD;0201;F,0.940,.(/3,>831/2-D1<<S}n3+Xj\OXM_gX7J8aU50•Ÿ•ˆ³¦¦ ¯©§²¬ª»¶Â°»Â­¸¶¿ª¬­­­¦­±©¡®¼ª §´¬£«µ¥¦²³§¤¢§ª²¨°§¥žŸŸ®–Ÿ˜”••—¬ ™™¤¨´®¡©©¨ª›•˜ ¤§šžœ¢Ÿ› £¤£•›ž—™¢¨›¥™œœ¢ –“‘““ƒÕ“™¹p°Á~ņ|֔›»|š•¤œ¤{Ž‡£‚¥‚z¬yV¯zˆ~Ÿj¹[ºw‡„}¦‚“|˜z©x{±nŽ„t‘¼…o”P¯§ÅŠQ zc`©bssˆm—ˆ`Sµ´È†€‰|c¤3Bv]PjidP@XgZdaJHNnN\ROYfYCD?E?0=<59;74<;8=:<C:F:;>6:@C;6@OLH<:;DHCBCD<EF81211DC./0483+-).323971#%5*>3==Qwj6*Yi[K]O_fT7G:aQ71%›¢”™²¨¨¥´ª¥´©¤¼·Â°¹À±µ´º³µ§±°¢°²¦Ÿ­¶¨š§¹­£¯± ³´°¡¤žŸ§©°¨´¨¤›ª–˜—•—•– ©œ™–§­°¨¢Ÿ¬¢¨––›¡¥¡˜¡¡¡¡š¡¢¦›ž¡ž”™›¦Ÿ›§•››Ÿ ˜‘”‘ˆ²nhµq«‡nŽ¦r´sr¶{š—£‹£‘¡¥~°vƒ‘ÒÒv\®{…¤o›ª¦k‡…}­}—™Ž{°r’Žx³e–t„žožf”RȋZÂ\Ÿyb_­`vt‡b—ˆ^Yʝo¿uMKµSUÆdTQjcfXAOk`lhPUHI9=VRZWXIC?J<2?;5=<46>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>HI91746@>/.24252-).26,742&60;5:=Pqh9'Wi\BOT_eP5G=aM620¡’¥°­£ª¼­¦´¦§¶»¼²º¿·¶³¹¹²¥´³¡±±¢Ÿ«°¤—¦¹­¤±°œ´¸ª ¦¡©¤±¨¬©¤™›™¨ž•“—˜’’¡¦Ÿ–’¥ª°¦¡•“­Ÿ¥’“ ›¤¦Ÿ•š¥¦¡š¢Ÿ­™ ž•›¡œ¥”•™¢ž•˜•‘›…¬{w¨v£ˆ†©o­Š‚§ƒ˜˜ ‰’šŠ¢“™‰®…‚³\r³R®}‚‚¤rØ~x†~†™™v¯†‰‘œ‡w´ašeš‚‚”l’Z°XKšu˜yf`­^vw‡h˜ˆk]¯w•žxl5yÈ®²_BTo^g`EPm_pmVVN.ediSXQ;AD@L:5?91=<16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK97<46:>/04333.2..18*.32%!03767=Pke>&Vg\@>V_cN6GC`I:99Ÿž” ¹°–´Â­¨³¨©²º·³¸¾¹·±´»µ¤¸²ž´¬Ÿž¨¬Ÿ”§µ«¨±±«­´¤›© Ÿ¨¡µ¦¦©¢™”¤¡“’›˜‘”¢¤š’¦­¯¦ •™©Ÿ¢Ž‘¡š¨¤ •™¥¨œ¤ž¬œ¡ “žš ˜™›–—¡ “—¦ž†©}}¥x¡Ž‚ªp­‹§†–Ÿ ‰——ˆ£‚‘ˆ”ª|€‹xo±Z¨‚‚ˆ ytـwˆt¨Ž›’¤|–Ÿ„{²^œd ~ƒ•l’\«[Z“€‘hgªdr{k˜‡s]¬Z‰ ŽkoeOJC¡\[Lt]bgM[a_rs_KV6J›”XGE=GFAM35A8.;>05A78@<6=<F?:<6?=B7.HVJEAH6KIN@IK@EN::@4.;>102144+*05/7,&21($$6671<PeeA&Uf[?2U_bL7FI_C2?8¢žšš¿«˜´Â®«­©¥´°·±µ¾¹¹²°¶º¨»´Ÿ°¤ž¤§§ž“ª°©¯©µ¬ª¯¡˜¡ ¦¤¤¹¢£« –›¡Ÿ”“ž™“—žŸŒ‹¨°¯¦–›¨¦ŸŒ’£—¨ª¦”–©§žž £­£¡ž¢”¡˜ŸŸ’ž—œ•¡•–Ž«œ®mr´s©‹uŠ§s´xs³€‘¤£’œ‰¤‡w¸oŒ{‹¢jk¶Z¡…e——i ¢§n”r´t“˜²j…’ˆ­ku³af¢o‡“j—\­_M¡|‡‘Rs£ly~o˜‡q\¯V<œwfTon.\§OcSkebmZc]ap{cTZQ>>mo3CB@?L9!7@6.;@37C58??3;<CDBJFMIF62JTKEBI6IJP?HNCFP=<E50;;010/75,+,426/#00,,289/9N`eD'UdY>/U^aL5FM^81C8¦››»¡›²À®­«¬§·©¸¯µÀ´»¯®·¶«Àµ¨© ›¥¤¡œ‘ª©§µ£²§®ª —œ§ ¤«¹£­›–™Ž¤¢•Œ ›˜œž‘’”ª¶°§˜”œ¬©—Œ“¥™¥¬¢‘–ª²£Ÿž¦«°™¡£™¢– ›–œ—¡’œ©œ”«™‡Ô’š»s°Ã€Ã†~Ֆ›¸xˆ˜Œ—ŠŒ§ˆz£¶u}wv‚š²`ƒºyÀ|u¸cµŒ‡©}•¬©q{t¼ˆ§ ia¦Ž¯¢~Œt‡ª}¾os¼t²ƒux‹nšˆqn¤t½^w}Zay¼kZV\jy^jaegbmxoY[YDA@s@CF+5G"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-7A9§šž¢¼¡—²Ã°¬ª««±§¸¯¶Ä°¹°­¹®­À±«£¢ž£¡››©£ª²¤µ¦­¥ž–šª™¦¬¹£­˜” ¥Ÿ’Œœ¢˜š‘•’®¹²¬•—£§§”–¤œ¤¬ž ¨«Ÿ›Ÿ¨£³Ÿ£¥Ž§¡”¢šœ—•£—¯ ’”©ž„˜¶‘Œ·•x‚“šµwmknsoy…ŠtžÁ»½š{±¨p€s‘¹ƒ|††Œ‡|Š‡—|¤»¹½œuz´£tv—vt°u™žf†jµtrqw¶Œ^z}‰hƒynyb‹¬pu…X[§jEeZTf`c^cQhgqmuBNPMD;ZM?J3;0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITBKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7LT_G'SbW8*O^]=+:VV'>;<§ž ¢¿¥–´Ã´¬«¨¬«©º®°Å®´²­¶¦´¸¬©¡¡¥ž ™“«¤­ª¦µ§§Ÿ›– £¬¤¾¦¡ª–“œ¡š‘¡§¡“œ—“—”±µ·­˜¤¤¢Š’’¥›¥ª›–¨¥¥œš¡¨¥§¤©¡’­ž–£ž———ž¯¨”›¦¡j}i›¦x‡r}™Žtyd‡{½¾Àºo“ƒr•‡asjZ^›‰acˆŽ•k`€•cmwb•k€š•”e^`cpšŠhr‹}…•gj~rtx}~b[wthP\nƒ}|‹kXlz‚rJJo†pNtLEW]gaLZXgc_O[nuirRPDEN;HI=M?2,2A?8/5?C<9;@;=C>RVVWYZ[\\]`aaa`\UG5DFUEJOHFPIIH;8=51:.0;:.0-76=5&"/*2,%;8-7JR_I'S`V4)P_L(3>[O'?2>© ¨¢Á¢›µºµ£¬¥®§§µ±¬È«¯²ª´¢½±±¦ ¢¨œ¢›™™¬¦¯¤¤µ©¥›—•¡›¦­¨¾§¨¥”“›•Ÿ™’—¤¨¨‘˜œ¯²¿¬›§ž§¢ˆ“‘©š¨£šš¬ £š›£§¬£ «£š±›”§ –”Ÿ—°¥—¡§™›œœ¢£˜¥¡™›™™™•gm}qw’—”’…‹µª†˜•ŽŠŒ˜–‡”•Š„“”‘‰Ž’”˜“˜–š ¡šœ” ‚z¥†lj||€uŠŠq‚xyvvŠ€|Šjsuƒuew}wkozm`c]phMXZfj`WZpznmfTOFS9OZMRO(+:KB635=@A9:C><ENSSTVWXYZ\]`bba_^^[TKCSGKNDGPLOI<:;389,2;820)6IRO8")+/2#4;*7FO[J&R^S10T^:+=8\K,<-@³¡³¢À¡¤²²· ª¦²§¥°´ªÈª¬°¤´¥À§³ ¤¤œ£•• ª§¬££¶«Ÿ™––Ÿ—­ª¥Áž«£•‘›——’“¡ž¡§“’™¨§²Ä¯š«ªŸ—–§ª›œŸ­™¡›¢¤¯§¢¥¨Ÿ®˜—§œ™š žœ¯ œ¡¦•—’—“Ÿ •¢— Ž–“ŠŠŽ—®|–›ƒ’‚‹ª©…€™—‰ƒžˆz„‡†š’ˆ†Š•›—‘˜£–š“‘Žf¡³¯…Š„v{’Š}vyzofy€‰kuyˆris{vƒ†‚kudyf`jecdfkYl{pij\SLPD^TF@?>,4@F;45;>A;<?>>HNNOPSUVVXZ\_aca_^^]^]XVJKLBIOMRJ;<:786/2964.(&$-1./)+*7%+<(6CMMD/T]Q05M[17E4[G5<,@´ º¯¿­«®²² «¦±­¢¬³¯Ä¯ª«¢²­¼£³›Ÿ¦¢¡œ™—¨¥©¦¤¥²´ž•”™™°¥®¾ ¬¢‘™™”‘”¡œ—¨œ„Ÿª«¢³È³Ÿª¤ª––—š¦¨šž£«”žŸž ©¯ª¦¤¬¢®›Ÿ  ˜¤žœŸœ¯£˜ž§’—–œ‘£˜—§œš—e‚’|e~šcyŽmik{’¤ªjdš—}g†Šeeih{Ž¡lhŒ—‘£wkj‹™£ž™slnzƒ‡zXe^†‚^m‹‰v\hsww’€‡‚nw‚xsmy„tvˆˆŽƒ|j‡Y^lud^s‰ik|qkc^RNXIdXAJ4>G7?FD71<=?AD;;DGHHILNPRRTW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%/*+'6*$;'/AJ[J/7ZO6)EY/DO2YC;?.=¥Ÿº¼º¯¬´±ª¥¨­­°¦­­°¼°©¦£­®°ž¬– £¢™™¦ªœ­£¥¨©²­ž•£¢¯¥¶¹¥­£ŽŽš¡™“’šŸ™™¤•{¥­¢¨´Ä¸¥¢§¯ž”ž¢ž£›¢©©’ž¡ž ª°«¬¤« ª›§Ÿ§ «•¡›¥°¤—›ª• œš‘£–©—}½ƒˆr´r„†­hx¹Ä¸q“¢£z¥™˜s«‚|ËÀÀ»qŒ¢ˆƒŸ}–˜‰À½‚—ÂÁ|‚{’šÃÀ}k¥²nŒoÊz›w‘ƒŽvy€yqz‡pw…Œ“ynx”cf_yd`e‚c^thldcXLWIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^__`_^^^^___]\SMPGUNA??=6468276*&%#)*&.+*)109*#>I[L*#BP.#F[3PY/VAB;/8–£¹Ãµ°°À©¨”£¯©°®­¦³´¯©¥¥¦°«Ÿ«˜š¢Ÿœšª§¢¬¢¥¨¤¤´¤¢’¦­«·³§®¢‘‘™œ¥’Ÿ ˜›Ÿœ‡¦¬¤«­ÀÀ± ©¯©—‘ž¡™¡£ª¤“ ¡žž­¯ª­§¤¤§¡¦¥­¨‘¤š¨­©šœ©›« ••¤• ¢–œ~Δxz¤y•–›_®^Ž§¢ |§–›s«ƒ€¯^cª{§‡… u—“ˆ³c‚«†¡³j„®t}—ˆ·aƒ­Y£Ímu{Ú{™p~ˆ’v~e{‡vvk|ˆn}…‘mƒarlph``yd\qhjdg`RTSW]KOC5AHDD8>6;@?A;=8@>??BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5578164('$!',&&/(&+360$7;SL+,-K0';\;L-!P@F4.1­ÂÀ¿µ´°¸—‘£ª¨­³«¦²¬¬ª¢ª§¯© §›™¤—œ¢¯Ÿ ž¨§£¥¡Ÿ°¬š•§®¬°ª¨¬Ÿ”’›Ÿ¤’ž¤—§£ž®¥«°¨¿Ç³¨©±®–’›¢—Ÿ©ªŸ• Ÿ­°¨¬ªœ¨¨¤¢«’¬²–¥¢ªª£¦¤¡¯Ÿ‘˜¦˜Ÿ™““‘— q…Œ—u…¨†q±}žr¬~¡ž¥žwª‚}­œs­~ª††Ÿv˜’{|—~ªˆ¢Œ‘Œ~«zˆ”Ÿ€{­VœÄzo’Á}•muoŒmeve†oawnro‰Š’„n’‘fpuuqagme_oiingdXS]aZRSC9II@D<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;91478452&# 1' 1' '45-&7=WJ-<'>1)3V@F!G:C1.+°ÓÆƲ´ £Ž££¢¬¯¶®¨°¦¨ª¦­««¦¡¤™¡• ¥«Ÿ¢¥ ¨¨¢ž°¬—š–©§®¬¨§¨ž—”š£¡‘“ ¬›¦¢¯¬¤¬µª¹Í²­¦­¬—•œ¢˜ž­¬— ™žž©²ª«ªœ¬«¤£¬›¯±¢¨«®¥˜¥ª¨©°¡‘•¢¤™“‘„¤j¤u‰z©tz²p‚¦Š™Œqˆ š‡¤``R«„®ƒ›v­§††Ÿz™—†{f€£‰¤™†‚£}©~‚•‡®_}©U¢’z¢Ÿ€{ïŋr¯³³¹qb©¯ÂthŒŒ˜Ž‚m›•qnzxypmgeerpf|ic]W`jXYULLQLCCAB;C@@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799664,&$" ('"+-"$.!3-&@DWH,G+56*1PKL# A9D4,'ÃÉÕÕ¿¡™«§ ¯¢ž°´°®©¬¢§¦¨ª«©¤¦Ÿ›¤ž¦§§£œ¬š¢¬¡£Ÿ¯¢œ›“«¤µ¯® ¨š–”¦¢š¢¨Ÿ ¥œ°¦¤¨±¬¶È²µª«©–‘œ¡˜Ÿ¤³š¡”ž§¬¬¥¯›­ª£¢ª¡³­¡ª³°¡š¨§®®´¢’•¢¦˜š‘{ªlž„‡u«y|°o‚¤‹‰Ÿ––Ÿ”Ò¸´¸É€²_`”©ƒ¤ˆ‡ z˜–šxªÉt™£•¨©‘“šŒ€œ‰šÆÇxf¡‚¥sŸŽ‚}¯]p´b°uK£†m§G‚“dŽž’|q˜•q|u~|n\fjsqfk^aYdm\_YINLKEDAB>A<B?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75685/)(%&%$&),4ENPPMFKJVF*L0/=-5OTQ;<F2,$§¤ÀƸ­¨²­¬¥¢œ²¸¬ª ¥š¨¥ª«©¦Ÿ¦¦˜ª£Ÿ®«¦ ¬šž©¥§µŸ¢—“©ª¶²­›¥œ ”¥¬‘™œ§¢ ©¦®¡¤§©°µÃ²²©¬¨“‰—œ¥š¡£®¥—¡•™œ¥¦¬›°ž®©§ž¬£·¬¡±¸¯š®¦²²²£“–¦¢™žŽ‚NxšŸz„£}ƒ¤„‡¦žœž“„¸{{y¹‚Ìƶx›¡‹Ÿ~š–—Švž˜Š¥˜¤¨°…œ…Ÿ„¬}š”b¥l¤p„}–‚r¬`£sq€š`¼}RUtŽ’£–{~““Œv|s†€q\nnxrjo[d_inbd^LLQTAIHFI:9K>B108866877-*5==?BDGILNPTVXYZ[\__^]__\ZZZYUSOH@882.,*.+*'&?QTVWWWYXXWUOUF<E3:P[T6?H,- ‹‡™©«¤«¹ª¯ ›¡¬²³¥ž •¥®­®«§œ¦¦š£§¡³¯¢©§² ˜©¤”¢µ¢¢•—¡©´¸¤›¢£’¡±˜ž›¦¤¡¢¯®œ¥¨¢¶²Ä±­©­©‘‡œ§œ¢¤œ¥—ž™™š¦¤ª›°¢¯¥¦˜¯¤»¬¡¶¶­œ´±·°±¥—œ®Ÿ¢…ÑµÃ·y‡Ž…‘“€¦x”¡wŒ ‘„¥Šqª†…´nrj™£œ•Šž|˜™†‡s¯‚¥›¢¦‹“Š•›mp²]¥s“z›k™{™|m©a£qqŸbs²¸hw”¦˜}Ž•y~yƒnjyiyro€u^eeomfg`J[XX<HH@U4@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^__][ZZXURRQF:2230/++(@QRTUTSTVWWXXWUUVTQOQ[U%!2AH$)%“sŠ­¿¿¼º´ž–§¥­µ¡¢™•£¨¦®«¬™¦¢Ÿ¦  ¶§£©§±£”¬£Ž¤­£ššª³³¤œ¤œ©‘”—­ŸŸ¦£œ§œµ™¢ª¤¶«Ã°©ª©¡Œ„Ž›¢ ¦£•ššœ™›™§¥§™­¨¯£¥›­¦½¬”½°¬ž¡¯²¹ª²¥š¨°¢¦—y¨}|°wŠ€¤¥ˆœm²o ‡­|¡ƒ§•˜€¬‰…®…Ÿ”ª ¡—†Ÿ€™•€{’~«€š–‹«xŸ‘‰”’€y¯^£}¦§c€|—sj¯]¥kp…™]`[Œ m•‘¦™ƒ•Ž™||„˜€knctn€z`geqnhghCZa[>KU3U8BBC7$$3+''3, /6674359@CFIKMNQSSSVZ]_a`aaa]][ZXSPONI8052.*,ATVVVTTUUUUTTUTSTVWWXVUUQHFIJ#((½“šƒ©Æ¶Á´Ÿš¬ ­¸¥£Ž›¤£Ÿ°°ªŸ¤Ÿ­™Ÿ¹ £« ¯©š®¡«¨¤–‰š®°¬¦ž¦›¬——¬¡ ¥¡™¤œ®˜¡¨¦¶©À¯¥©£ž‹€›šŸ¦ž’•š›”›š¦¥¥›ª¬­¤¥Ÿª¨¾¤–«©¢ «²¸©­¥Ÿ²­§¨—v¯~‹œ…‡}º­Š™e±e•­} ƒ¦•š¬Š„°…¦š¤¡¡… [lj³`­{{ƒ±mgo™˜Œˆ±[}´\¤ƒkÈ¢dŸ€{¼XvµY²}R®€z¬X€¡m˜§›Œ—‘˜˜|zžeuc…xt€|ajgqmgefOVd\AU_>I(>:=4!",%2. *1/04579:<ACFHJLNPQRTWZ^```ab^_\[XUPNJFC553./@UZXWXWXXWWXWVWWWWXWWXYZZ[\XWWGB;ҟ³±·½º³Á³£œ¬¦¤¶¨ Šš Ÿœ³´©Ÿ£ žµ™ ´¨ª¬ž¯­ž¬›•¯©¢Žˆ›Ž¯¬¨§¡¦™®’˜¨™¡¤Ÿ™££¦™ ¢©²©½¯¥¨ž}Œ›–  ™’šœ’š˜© ¢š©®¨¦¦¢¥©»ž Æ¦¤¨ ª´´«­¥žº¬««”€©’£¯Ž›‡¤—™‚€¸ÃºƒŽœ’„§—œ‚¬Š‚¯ˆ§œ›¦ª~սªb£¿½}~£‚ƒ×º¸µ…”“ƒž½¾„k¢o«„lœz²°Çƒi«°½¬xw¢¾¼s€–Ž¦œ‘›‘™ž{‚’œ{d~|eŽgy‚{alekjcPa[Sj\?UbCN)=:4/$%2 $(0496678:>ACFGJKMNNQTW]a\__a^`[\YTQMHC?=A?5=SYYXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ¼•³³±¿¹²½²¡œ®¦¥²¦Œ˜¥¿ª¸²¨¢¿§§²œž±œº¨Ÿ­¯¦§””°¬—Œƒ›‘®¥¢¬ £œª —Š¢’¦§œš¡¨¢™Ÿ¡¬­©¹­¨£š—“|‡™‘¦š’‘˜˜˜”©›¡™ª©¡ª§ £ª»¨Å¢ ®£©³³©®¨Ÿ¹¦­­™suª¤·†d‰ ph®‘Šnnw¤™Ÿu®˜”p‹q•¨£›—®¤rmllf‹xon‚™qzjqig‰––˜qii„‡fp†d]ˆbjoY\f}v¦_aqŽ‘nee“¡˜™™’˜¡~ˆ–wgˆxiŽkzyelcflbKdXJlZ:PeER'K:+# ",)-2.5:4579<?ABDEHKLMOQSV\WZ\``a]][TPLHD=:AB7MXZZYYZYXXYXWWVWY\^^]\\\]^]^][[UW^©”¬³©¹¸²³ª©¡®ž£²©—’¾²Äɾ·ªŸÀ¬­¤¡§¬ º£¤®¬®§Ž—®©‹…–—­¦ª ££ ‘‹¤’¦™¨™–£ª –¦¦§°º«¬š›“’{„–¥˜‘‘™”Ž˜–¨• ˜©£›±¦¢«¹Ÿ¯Á§£²¥«¯°©¬ª¦¶¢¬¶•Š ¨¥¶‰–£™‡ª›‘•’©²™š£ª ²–¢¡Ÿ¢œ¡¥¡•«§’’Œ‡“œœ”™“™‘Ž•…¤š—–Ž‹““‹†„}g‰~t‚us†Šp§lz”‘“’œ”¡–š˜£ƒ‰–sj‘wqŒxw|zjmdcodUaY@j\HcaOY+F=+'!750.!%2(*699469;>?ABDEJKKMPPQXUVY^`ac]^UQJED>9=@ASX[\YWXXXXXYXXZ[\\^__`^^^__```_YY`¦–¨ª¥´¶®®¡¯£­Ÿ µ±Ž¬Ç¾Æ»¹«£¥žœ¦Ÿ±©¤·§©µ§¨‘˜­¢‹‡‰œ§•¬¤Ÿ˜§žž’”£–§š¨™”¦¡¤›§™¡¶»¨«™šŒ|”‹¡”Š•‘–”˜¦Ÿ›ªŸœ¶£ž§«·§®Á­£¶¥®¯¯«¨¨²· ­»˜‘¥¤¦¶¢’ž§ Žª Ž’Ÿ£¬¯š £¯¨¯˜£ œ£ªžœ–«“™¡›”–ª™˜™—–ž‘ˆ ••…’Œ”Š€}f‹…u†ux‡‚sœj…”“‰|‹•’’—”¢“ž˜£…Šš‰|s—sz‹€s|jod^pj`[`YndP`ePZ:GGE>2=>9/*&+)&&416668:==?AACIJGJKLMSSSUZ``i`eVPJACB:9EMV[^^[Z\[[[\]]__]^_`aabaaa`bbbdb\[c—•£§£¯²¬®£©¦­Ÿ§µª¥µ¼°­­¢£š{ž£²¤¥±©—›¹¦£“™ªœŽ†Š‰œ¢®ž¢•¨Ÿ ’–˜š­‹©–¨™©™©žº¶¤¥™›ˆy”Œš“Š•’”‘’—£žŸ©žŸ¸£€„¯µ¢¯¯t£½£±ŸwyŸ©°¹”u¬£ž‰€ªd\bv ¥Ÿ„—}m’³œ£§­ª¢ežŸ’sy™—p€˜¨—m¢¨Šeœ¥œ‘—˜–Œ’œ‘†š•ƒ’‡ŽŽ’‰„wjŽ†v†p{…`h‡Š”’‹Zu”ghs{§››fzš‰„y™j„‹„oy€kre_vplkh[gfbbpS\>NNNSG>@UD91/&4:306678<;>@AAFHBGFIKMSTUY]`hfgWQJ<DG<8UR[`ab`^__`aa_\]__`aabcdabaaedchd^]f›•¦£ ®°¬«©¥¨®¢¦­¤’–«¶±²§›«§¬—tŒ°Ÿ¨«§”—¹  œ¤‘‰ˆ›ž¬š¢”§¡Ž–‘ž„u­ˆ¦›©‘—¤‰œ»´§ ™˜‹‰tw“–“Š“‘‘”” ›¡§™œ²–€Œ›µœ³Œ’Ž»¦ ~§¢z¡­µ€Ž¥žƒ‹†±ª¯ŒŠ—¤›z€‹¬†œ¡§¨§‡•…˜w¥›z‡›˜§‚‚{œ²zŠ† —™”˜–‚‘——„š™by‡„‘ŠƒmpŽ†y€p€„~…s…„•‘x–g’t šu}™„¢Ÿˆ˜”Œ……škŽ†lx{qqgdxojlk[eljet\^ITLR@E5.ZUU7)!09=>743568;:=>>@DI?IEJKGSX[Y[aahfYQH9EL<>bV^bdfd`aa`bb_]`aabbbcfgcba`edcgcaahœ˜£Ÿ¦¬­«¨¬Ÿ¨°¦¦©¥™”¯È¿±¢—¨©µž„¬œ§¢ ¾žšŸš |†™˜ˆ¬œ¢•Ÿ¡‘Œ’‰†€‘§‡¢¤”˜ž‡Ÿº²§›’Ž…pu‰•Š”›Œ’Ÿ’—¡¥–ž«‡Ÿ´‰´š­ŠÊ‡©­ˆ·…°¯¬‚¨Œ¦˜}¨r{wœ§—h•¤y´ŒŸž¦§’˜Â«ˆ˜¡rž€š¥}—…•²¡}¡“ ˜—Ž“›Š˜‘‹|…“†•’‰ƒmr…~yq†€ƒ{ƒt„€–€Åf©‡£kž„£œ„šŽ‡‹šq“…hwt|xhhvqhhl^dpmgmXgG]RM2D46Nbd7&3<EGD:64658;8>==?BM?NIJLCPZ]\Wa^il\QE=LM@JdX]cfhgbbbbcc`_babccceiicbbbecafcbbi”–¢ °§¨¨¥«Ÿ£·°©ª¦š” £¤«¤—¦«¸£°€¡¨¥ž‰”¼š”¡’žy„––‘ˆ«™››™¢…Ž‹wšœŸˆž¥œ–š˜‡£¹­¤šœŒŒ~bm‹“˜Œ‘’ ”¡¡™¡§~¡§‡­ –­žœ‘…€ Œª­…£©™Œš£u€™”k‚­vM«x‡œ‘š¨§€©«}ƒ¡{z§iž’kg—…—·‰ž~n`dYƒ—Œ{dh‹r™}y•l]|–m_Spƒ\_kx‚_Xd|ƒ—p§ªkƒ£nr¥pŸ… jf m[oŒ}gZ`„€bWPowfmtskjo^kqmkiXiO^XF9A4HD_k4,ICRMN=84859;6@;;>BO>QRLMBJ\]_W^^bu`MD:MONTb\\ffiibbdbddbab`bdcacikdbddgdbgeach—• ¸ ©£¦¬‘ ¶»«­¢™˜¡¢¥­®¡ž¯µ£¨“¡  §œšŽ™´š‹ŸŒ•‹u”’Š§–•˜žŸ’……«¤‡šŠ™©™š›’ˆ¦±§¡•šˆ‰€inˆˆ‹ŽŽŠ‹’Œ’£Œ”Ÿ œ¡¤“£¡” wœ•§ƒ¡¦†¨«ƒ¥x‰|„š~¢ps”ˆ–|Ÿym‡›Œ™›¨š‡{‚¢sv¦fž~w¤_˜z}“t¢n˜·´ºt“‡‚µ¨dÆ¸{p•¶Œqš¤bs¬«`|i³~m|†‚‹˜q£lr£tŸ…¤`™³–q}˜Ÿ³us[ž²ƒjcotvqhoXkmsrf\i^cLD=D6QBZr3=SG_JR=<395::6D;;@JP?UMNQ@E_^[ZX``|dHC8LWUWc`Zefkkbbeadc`ab`dd_`cknccddhdbgfchh“–”£·™«›“ ¤·´­­ š¢¤£¦®œ²®¬“˜¡™¡¤™š”Ÿ«›‹ˆ’x‹…q€–ŽŠ¡’”˜}‰§ ‡—Ž‰’£”œ›‹©¨¥ž—‡„~j{‡}ƒ‹‘‰” ƒ—ž  ž‹‰wœ˜¢ŒŸr¡‹‡©ˆ›¥•¦©}­Œ~z ™z£“xt–ˆœ}–Ÿ†›Ž˜›¥†¢d¡|ˆ–›lžhšnš™z€‹§}rht«ƒžƒtªh•š]›…v„gªj€¸f\¨pœ`•Œ^§vu‡ˆ~žhšt…“’—Ž€Ÿoš‘n§š]¨~x»k~ª\Ž„]´g\nrzxki\qkyyc_fXbBQFO7WCRo5K[Z_OZD@151;;6H?:CHU>YRY]>Db^V`Qac}jEB9N[^YefXfgnmbbe_aa__``ec^bdoq`deekecihgki•›‰©µ›§ˆc”š«¹±¯¬ž¦œœ© Ÿ¯œž±©­—¤›¡ ™––¡¤™†‰jˆ€r{—ˆ‹––„‘•˜zŠƒ•£œŠ”†Œž’‰©£ šŒ‘Š€€i€‡y—Œ{‰ŽŽˆ–›”¢Ÿ ¡“˜rhŸŠŸŒp’Œ©‡˜ž¡¥ž¦{°­£¢¸—w£³¢¤€ˆ”y{ªš¢Žœš–ˆ—q¡|…¯µ}kš‘¡x~˜´¢£«¨„™|›}štªZ]o{–‹xžbL~{z…cy—BLŸX¢jq{Žl€ˆ„™u›x†‰±³€›“§wƒns}•pštk¤]•vHed`tq~~nf`liv{ddaQ_W]UW@YFQhDSW\bX^ID=B8?B:IF8LEXAWR[VDFb\Z`K`m~rEC<U_bZfjVghmobfg^aa\]^ahb_ecvm]egfkdflihki“œ€°­™„S^ ¦³¹²²©š¢Œœ¬œœª”¢¬¤¢¨ ž›™–˜¡–ˆ‡‰w†oy•…‘›‹|‘“–ˆr€ˆ’ ›s‘‰š•¡›…©œ›•‹‹Š|ƒl„†q¡Œx†ˆˆ“™–|“£ ž¢ˆ­†}µ„Žžœ{¥–z©•›‰Ÿ›|§hwm~™t¡sq|ž†™p“ƒ®}¤ƒ¦™€¤o^¨gu¢co¥aœÓ|{™xrsc¢†~£s¤uk³Œ`‚˜‰sª²§¼wƒm~¾¦©´]›n|p–mr¢r]¤gs¦`h¦m›Ôš}†›pz{˜lœ|x—sn©¤g`ezq€„kgfdouwg`cS\fQQbIWJTaWS[ej[eQFCKMJKBKE8O@QNXSYOSQaeejRcwywIFEc]eZhjTihjocjg`c`\]]_hbahe|d^dgdkdjmghlh—š€°«T\K~©¯±´¯³£›™…™© ¡¤Ž¥© ™ªŠš˜˜“™“’¡˜ˆ†{p}„h}ƒ”šw‰o…’’l—“|‰’“¥–ƒª›”’‹…‰yƒvˆ€n‚Ÿ†w€“†ˆ™¢—z”£¤šŸ‰³¡¢¶‹z¬§¤®¥p©€šŽ…€š{¤€¡™†˜rž„£®¯Š—Œ€¤•ƒ­ ”v´µµÉ¡s”‹Ÿ`—©my•‡ ›t¢‡w ~’—‹oLf£’p›‡s¤{ztaƒk~ kqd_œq}s–hyi³µ´Æ¦s˜}zkœ›«v…›mvx˜jš{u˜rPE}´_jvky‡fjgcuupnV^TYiPRhIVMYTV]hknVgWNKAJMKHJOAQKPecjmetss~y|nu‰{{TPOl^i\kiRjhilglfce`\]]^ibdik{_]dhcjfnmeile¡›ˆ®¦„e?“¡²ª®¯µ¢¢€—ª¢£¥Œ¥§ž¦ƒ›—–Ž—œ“Žˆƒzjy‡eƒ˜ yuˆŒi„…‘ƒŒ…z‹–¦“ƒ˜©˜‘‹ˆz}‹yp¡†z•‡‰– –”¥¨œ––„fnxœl¢d|q¥w›˜pg¦€•Šz¤zŸ–ƒ—ržvŠ•—¹n‘Š¢b}™ •ˆmriªku mo¦_ši‹i–‡›•t¢€}š`Œ†uoˆbh ež~i›uocfˆ‚mq¢Z_[b¡m]ˆ‹nz}srd¥mx¢dg§h™sŒ™p¢oU‰o _f¨T‹^T˜nmskr‚mpilyskoRYWWgZSmIYO]IXiisjYkVQREV\LXSaUik_wt{}p}|rƒ{€sv€„v^QrbgcpgPjhhklnhdg_]^]`jcjivu]\cicjjsmfkmcœ¤˜¥zdtm‹§®£©°±¦ŸŒ€˜«Ÿ¦Œ£¢›£¢–˜“Žš‹˜ŽŠ{†q€ˆh‹‹|˜œst‰}|d‚‡”‰‰•™‚|ˆ‡—¨‘¢¬‘†Š‚Š~€€si¦„}†”‰™ ˆ“©¦ˆ¦x•›~¥ˆ–Œ²˜ž‚¯—Ÿ¥v”†x©s¥„šn¤¢Œ’„ƒ»n}¥¯ƒ†…†“•œŸ|¥zr¨• –fž~o¬c•Š–“w©l©¢‰vˆƒwª‘¦‡j‘°kv³Œ©kŠ†mmŸž’•`~«‹ªv~~‹¥žvŸ|ƒ¤• j›ˆx¬hž­Œ¶tw¾¤“Yƒ¦«aurtq|uqckohlSW[Vab]kM]R]J^mnw_[qY\`[ftenorbqt`wz~yryƒsƒ{{Œ‚€vbxdcnrdRkgholrjfia`^\bkbmlzo\\bibljxmglnb•¥ªœ€£–©ª¨¦®¤™Š‚˜¬šŸ¥Š›¥©…Œš‡œ‘…’Œt†zˆ„p…~˜”tt…r’ƒm‹‘‡†“Ž}{‚†™¦Ž¦¦ŽŽ‰…”v‚‡“ol‹©ƒŒ”Ž‰ŸŠŒ”«£ €u”—ˆ~y”®£›q†wŽ‰‚}{r§Œq}}z˜–›„y{~‡“•“Šv˜ž ƒ{}‰kŒ…[yyrzqin~’‰q€u”“q†„‚eŒ^€‹wtr”unynm†l„…^ugwŽe€€…¨š}t{•j‰ˆpv}‡wnmgŒsy|˜x…\kXyinxrroxxp]k‡njgV[`W\fkdVbU_Q_pxylkvfjkkv}qrusaoubt{xuzƒu€€xŠ…ƒ}{mldyn^Wnghukxjije\`Zcjemqtn[[bldllynhloa”¸¨¦‰ ¢š¦¤˜¥œ«¢¡„„˜­’ž¡‰›§š©˜ƒ›‹–”‡ŽŠ‰rƒ|}~…{˜trƒp•…{|’‹††…y~€‡š¥Ž|§¡‹†…•ƒ†Ž˜wr„ª†’‰ŸžˆŒ›¨Ÿ ªƒˆŽ•š~~‰–­¨‘¦wo›xn~¨…p}•qkp} €“ŽŒhm]ƒ‹‹›šžŽs•‹ˆqtkvtYrn†‘~~Œj]jd{…„‰€`iwzš{‚Šu…‚gw‰…japqu^qŠ€ˆŽ¥”…e‹ƒnw‹„q†zqghe|„z–[\jgnv[{yxunss‚g\m‹kkbZZ_ZYlq\_aZ_]ft~{uptckkk|}s|xudmuhm|~vz|{yz€€~o†Š„{}s~yshT\qiluougkhd]aXkhlkqrmW[enlgszohjm`‹‹ª° ¢¡šž—ž˜¨£¢~ƒ™®Ž •ˆœ¢‘¥•{˜…}’™‰‰†‡Šs}Œv…‹‚…—Šqo€r˜†ƒ}’ƒ„†Šz…Œœ¡‘ƒ¦¢ˆxŽ—‰•Š‹œ˜„ƒz­‚‘—š•Šžˆˆ¡«Ÿ¡¢£‹‡“›œ£™–ª¡§¦Ÿ’š†”Œzvƒ§~’“”œ²¦›•Ÿ²“—ƒ¥ŒŒ•šŸ‰›‚ˆ‘Šk|Žwxe‚†‹|‰„‡‹ˆˆ€„„w|yt™ ˆ†‰‰„“~}Šuor„}w††Š¥‚…Œ†‚ŒŒ}‡ŒŠ‘„ymƒ…}z™krhatŠq~zwwpwt]^o‡hn_^Z]]ThrVd\\blhu{|sopdkki€|ny€rjpplg{r‚€x}„{m‚†|yx{}zƒxNdvjrmpzekecb`[tfpfrqmU]ltmiyzqgikdŒ‡œ¹ž–¢ ˜”˜˜”˜¤ ž|š¬ŸŽ† ‹ž–}x”ƒ{Ž™‰†ƒ„‡ny€rˆ~‰”„mk~z—‡„ƒ€†„†}‡…Žœž“‡«Ÿ„r‹†’‘‹’}Ž{ª„Ž“˜–œ–‡†›¥Ÿ¢š…‚’š™™š¦Ÿ¥•ˆu{†ƒ¤z|Ž‘†˜«¡ž”ŽªŒˆ“™ž‚Ž—~†Žƒow†qu`~ƒ†uŒ˜€ƒ‚†„~…„”nxut‘¡Š‹…šƒ„Œsˆ{|rqz‡‚zwŠƒ‘¦Ž…ƒŽ€ƒŠ‰Šw†‰ŠŒ~pl‚|nhlmh_zi}|vuvu{w\_p~nu`c[]^RgnTe[^bkivz~qlmdkjg€lslluoyp…yn‡€v‚€~…vq‚ˆ~{z|{‚Š`i|juhi‚djc`i\cuhobumlUcqyepz{sejmmŠ‰ž·š¡£Ÿ‘‘•—‹šžŸž{xŸ§‘œ‹‡¥”‹˜™yz…|‰‘ƒ‚‚ƒn|ys…~‹‘}jh}‚˜‰ˆŽ|}†„†}‚œ’‰¨€pŒ‹Œ’‡ ¡Š…Œ}¨‘‰’—“–“xŒ£  –™€š˜’Œ›£¡¤™—‘š}Œƒw‚Ž†Ÿ~ŒŒ|˜¥¡¢“š‘¦Œš‘‰’—›~“’~‡Žtt‚pwa}€†q‹•|ˆŒqŒ‚…†Žhwqx‹—‘–}‡Šq†z|pwzŠƒyy‹‚”¥’‹„z††‡…v‚„‰‰|gs}€y{qlkg_~sh|uvt}s€j^`tvpwdcY_^RkiUeY_ahjvyqgkdmhf€kn}hoql~x‡zlŒs~tv‚†|z}irƒnsia‡hlb_qVtomm`xhmWjtvcuz{rbjozˆŒž²’¥¥œŽ—†œ ›|v¥¡Ž˜€£‹ˆš–y{†‡~ƒŠ‰‚r{tvƒ…~Š‘xgc}†—ŠŠŒx}€ƒy—‚–™—— œ~pŒ‚‘”†¦›ˆŒ‰ƒ¦•…“‹–—“’w‘ ¡—“–yŽ˜—Ž–šœ¤˜’”šxŽ„‚wƒ•œ}‰Œs—£Ÿ¢“™¢Œ‹ƒ–˜ƒ’–™~˜Œ|ˆ€vq}n{d€|Š…p‡“‘‚l‡‚€‰„eun{…‘—‹|’w‹ˆ{…{zq}wˆ„xƒˆŠ—¡”‚Švˆ„‚‚w|ƒŠ†xazy~txgmeajjwstu}q|bc`tnurmaZa^[leRcY`ahkvy†qbjcmeh}ƒlhthnpi€}‚ym†q€„ƒt|ƒŒ€}z‚ƒ~|mv‰ttmeŠljbbvV„ipn`xglbjvpfy|zq`rl†…œ®—¦¨žŒ—‡†Ÿ“—™~xª‹™z—‹‹˜y|‹}|„|ƒxtyzs}€„€‰‹€d_}‹•‡~„†t}~Š}™…—•˜¤¢™s‡{“’Š¦ŒŽŠ“¡’ƒ‘•—‘‹—Ÿš’s’”‰ž¦——Œ”•r‹‰k„—˜z‡ˆ‰o—š¤”•‹ŒžŒ†‚’œ’’•‡™ˆ|Š‰zqykul{~‹~m…’‚”xpƒ}~Šdqi{–—„~Œs‡‚x…|uw|„{‚‹ƒ‹’£xƒt‰‡}€tv‚‰…pa|vzq}obocd|cnovsxwstav`olumo\\_^^j^P]Ycahnt{ˆk`ifjciwˆnflijmh}{woˆs€„„}t†‰{ƒ}z„}|Žrz‹xxnl‡jh_irc‡gqoewgnlayik}{xpaxm‹€˜™ª £¨ŠŠ‘†Š‹•˜~x¯™—}Ÿ”‘–“ˆw~{Š|{€wx€€put|o†}Š|a\~’†ƒƒsz€‡z’‰“’“¦•‚}}Š’¤‰ŽŠ˜›†‘˜”–ŠˆŒ’œ’‹Œmƒ‘‰ž™¢¡—•ˆ–m‡˜ƒf…˜Ž“zˆ„Šp–š”£“’‰‹™Œ‚}’’Œ™Ž{Š…‡srukpnu|Štn†Ž’qu€{‡{dply|™“}ƒˆs‰€s‡xn|…{„‹‡ƒ‹”§Œz‡{}‹…w~qp†„ehyuup|b_pakt^qj{yylspex]nlsmrXZ__akZPWXecgqq‡f]jigbgqodigeihzwuoŽ…t‚ƒ{u‚‰…x…|x„…z‰w‹{{rxƒjk`pht€kromrgole|cn€zwqlwwŠ~¢—¡¨ ¦›‡ŒŠœ‡“v‚«•“Ž‡¡–“t|v…xyss{†kspzmŠv€ˆoq[Y~‘‡€vu€€€ †‘‹“˜¡•˜xŠ€Œ‰œŠ†’˜–…‰•™—‹‹ŒŒœ‰‚m‰‹‘Š–¡œ—”…—‡iƒ¢‚e„œ‰~‹ƒ‹w“˜’Ÿ“‘‰‰•~—|‘š‘|Š€ƒnuplmop{…isƒŽ˜‹qw€u‚ˆ‚xfrnu€™Ž{‡ƒy“yu‡soˆz„‹yŠ…‚‡š¢‡{ƒu‹wynl‚„‚^susqpyZ_qapk^pj}{qmmjlv`oojqmYXa`anXQTZfgcup„‚b]kndbfk’n`gf`gkursp‹€uƒ€xu€‹€y…w‡†wƒ…|‡Œ{wŠjqc|c†|nqmtjholvx_qy|uut€ƒ~¤•š­ž¦–…ƒ—”ƒ vŒ ”“†‹›–Ž‹zrxt‚pr…tqvˆlpmvmˆvƒ~€nmUQ«”‡‚x€wrƒz‚¡‚“‚•”™œ“›x’{ƒŒ’¤š“Ž‰•™’„‡—™Œ”‹‰‡„Š|r‹…‰ŽˆœšŸ›•”“}h„›†g…Ÿ‡‘ƒ‘‚‰qƒ‘˜œŒŒw{’‘zŽ‹Œ’–Œ|ˆ|€kvjnkll{az~Ž–‚vz€xƒŒ|yfsks†•‹~‡…z“Žpyƒou‹yˆ‹y‡|€‹„|zv‹|wpjl‚„{`yqnmstV^pbra`lnzqhpffsthqkawe]Vf``rSQN\fe]ypˆ|_\irbbef‘j_he[gp}plqtŠ}v|…€uu~‹z{…€xˆƒs†…~Œ„|y•xfrjƒ`ˆ}ookz`jntu_t}y†xts…}x ™°œ¥Ž‚Šƒšˆ€Œž€‹š”…ˆ˜„wtwt€pp…tpr„okiwnƒn}}nusRM‚ßȒ֓{puƒu„ ƒ”w–’™œ‘™{”s…Ÿ¡““‘‰“œ”†~––‰ˆ’ˆœŽ€wzŒ~‰ŒŠœ›œ›•’yŒvf‡†k‡¢„‘ˆ—ƒ†cŒ‘™•‹—ŒŠ‹qz”ˆ{ŽˆŠ“‘‰y…|~l{erokkzy[€yz}~†ŽzzgrjrŠŽ‰…„|”Šk}~mŠ}Š…|ƒy€Ž”™™Š|uwƒxrmgq€…nkuphjunT_pepZ`lrxgkkbfxrppc_w``Vk_^vPNKagc]zp‰t\\ev`aeedagbXissnkrwŒ}tz†‚uv~‹s€†z‰r‰‡‘‹ˆ|~˜vesn}eˆ~opl€Ylnyysav{{vrwŠwyŸ‹›®›Ÿ‚…wˆ•~}Šˆ† ‘…Œ˜„“Ž‡twpyqo„omoseeyq}mz}jhkc¤šÁÜ®ð¡rlv„v…£†’o—‘–¡–œ’r…‹£—‰Ž•Š‘–ƒ€•…‰€‘Š‰–~‡zu‰x‡„Žœš˜™Žv‰um…ˆŠ|‰¢ƒ‰œ„…^‹“—‹‰‹‹…‰m{–}ˆ…‰‘†v…}}k}dxujnysWˆz’‡…y~€€…Œ~xeri‰Ž‰‚~‹–„kum†Žƒ}x~”’˜trw‡Œusqgvz„cunqbjwhRaqgkV_otzard_h}prnZcr`bVnY\xNMLdga^ws‰n\\dy^_de…`cc_YjrknkswŒ~tw„xw{‰qƒ„|~ˆ{t‹‰‡–†Œ~—sguqym‹{ntqWqzvyrdwy‡Œiv€‰rœ‡˜§œ£’…}qŒ”xyŒž„…¡Ž|–€™‡„{rwptjpljm|u_axw{qu|h`d|ëÚµÉÃ܇rltv‹›‰Žj™–”‰q…‰ Ž…‹•ŠŒ˜”|’ˆƒ‰{‹…vxƒ„rˆ‚“œ–”—†Œu†}nƒˆ†˜¡‚“‹žƒ‰aƒ•‡Š†‰ˆ‡j}”€}ƒ„‰Ž‚q†~qwhvritwkZŒ|’‚…}ƒ€„Š‚uarj‡€Š~~‘|mkw„…‘‚{€|~‘•ˆnpyŒ†ukqlsy‚`ujo]kw`RerhfS`pvtap`]hƒqsjWghbiXmV[uLKLfg^brs…j[\ey^^dg{ad_]YkneojtxŠ~ss~{vz‡s…ƒ|‡vvŠ†Ž™Œ‚{“ulwuyx“tnxz}Xz†q€ogyw’‚dv†…pŠ–…™¡š¢Š‡to“‹rwœ~‹š‰‰| „™xrtnodrifmxx\_y{{qq€jafaÕ¶Ž‘¦xnqw|q“‘‡kš‰œ“Œ†{i‡‹™†’‘†‡˜Ž|Œ€Š|Œ}‰„ztzƒ{q†€–šŽ““ˆuƒ…u‚‰‘œ…”ŽŸ~ˆb€“ˆ…ˆ„ŠŽ€€ƒg}‘€~‚Œ~m‚|‚tkmwutwvkcŽ€…~|…„ˆ~o_qo„{Ž‹{~‡ypƒey‰…Šzƒ|~’’„nny‹~umnkl{~diljYnwZRjsibQcsxlbe^Zjƒnsa[g_dl_nU[pNHOge\gnq€lZ[cs`\clwde]]Zllcmjsw‡qp€{}tx†x…‚|€‡uy‰’–|‰†v‰pxy{„“on|w^ƒtmizs”sgsˆ|r’‘ƒšŸ› †ˆvv•mw•˜~ˆ„Šš}Œšv~vqpljau|gbjuzZ`x|zmqecggW_qs–¼Ä„wq”Šs˜Œ‡”ˆtkˆ•€{”Œ„›Œ|Š†}|‰Œ“ˆu‰…vv}qu†ž•†”‚‚q‡sƒzˆ–›–†“œ€ˆf}“‚€†„Š‰r‚~g}‹{y‡‹}i€}ƒvfoyxswsljŽ…ŠŠx‚€„ƒj]pwz}‹ˆ…{€Ž}q€hx†‰„‚w‚z–‹Œ}mkz‰|vtoih}we]qcXptSToshbNhtxfa^]Xo€osYeb]jm`pOYlRDTgaZlnm{oY[^lcZcpvdg\]`ljclisw‚qn~{tuƒz„‚|‚…v~‰–‘xƒŠtˆsyy~oo{qiyz~nm|v–kjx„tk”…ž˜ ™…ˆo~Œvjy™‚Š‚•—Šz–ozspljd`t{i`er{[as}zgpzaedŽ±²wKbZ¥Úїr{’Œ‘y–Œ…š’†ol†’‘zy“‡„™Š|†xx‰Š„•€oŠ‡qt}{jy†ƒ¥‘…“Œƒ~n~‚u‚w…™˜“Š’”…‡p{’ƒ}ƒ„Š„oxh€…xrƒŠ‡|e|~„vcps€hyqou™Œ†ƒŠ{vx€„yj[o|r‡ƒˆ}…ˆzˆq€mp‚…‚ƒqƒw˜‹Œ„wmm}„vzehj~raZx[YrnNXrsf`Kmwub^[[Yu}roWg]fjp_oNWiR?Yg_Zpkgyq[[YkeYcqy_h]^elhfliqx‡om}up{€‚v…‰—Šq‚q{†|zy„”Œukzko~t€}or|{”po€yf’Š‚¡˜’ƒ…g‡ƒpgz—Š~…‚™Š|ixrkkf_aoym_boy]dlƒz`qv_deÕ뾋2:>‹Ž€ry†‰w…˜“Žnl…Œu}…‚•‰|‚xnv‡…ƒ–wn‡„ku{ueyƒ„§ŒƒŒƒ}msu‚x„š‹‘’Œ‹†~{’‡x€…ƒl€ri€~xm|{Šƒxby„qdqh~muqu›‹…~su}€r€nZk|sxˆŠ{†|‡wypk†‚Ž‚‰q€w~•ŠŠ~tmjv€€uu\iixqZW~SZreL[srf[Jqxp^[[Y\uuiYb[genbiLWfQ=^f]]vf_uq[YUodZeqy[h^`gmgjkipx}Žmj„yn€{}€‚zu‚Œ“…p€‹nw~{{ˆ“‰i{}kt|r†{sw}Œzx„~|kŒŒ„›–Œ‚€l~khŽ{~ƒ”‚}Šˆkuqgic[cgso`altahp‰zast^bc› n\5Z¯µuj€Š~“†w‡˜‡uŒŠwpl…ƒ‡ty‰x‰}“ˆy~rgvˆ~}—op†}hvynez‰…¥‡€‡‰}m}u~{Š—†“—ˆ‹„‰|‰q|~…|i~mk{zjzv‚‡€r`w‚~qdrgu‚mu{†”‘}owy{t}lWm}usŠ€†w†u‰zwrmˆŽƒq}{|‘‡ˆznmim‚tn]hftrR\|N\q\O\sodVKsykXYYZ`q€ua]]agdhhfNZhNAad\`va\umXXSta[eosWj_bhkgmlipw|“lh„‰}|p~~|‚zw€€‰‹„r{‡oqw„{‰ƒj~{nxywŠw}x€‚‡„~~zm„Œˆ˜£…„{v‹ykm…‰’y}{‚’€€}Šƒprpbf^Yg_pp`ahpfjo‰tato[`djv{¾œ§¤È¸r…„s“}yˆ”„t‘ˆrsp„{ƒsu†tˆw”‰yypcw†y€’ir„ufwvcj|„ˆž‚€Ž}q~sƒx~Ž‚w•”ˆ‚ˆ{‰‰lyyvhzilysizv€ƒ}h`xˆ}jjsh{€jvŒ‘”~z}~q{v{s}aUu{qsˆ‚{‚p†‰wwoo‚‹}|w|{t„uhqhlˆ‚rp]hctoKfvL^oUTYsnbQOtybSXX\ap‚s[a\hedcjdQ[qIDdb\cq^\xhUWVw^\fniVl^ajgennhpwz“niˆŒy}r{~y‚€‚|v}ƒˆ†ƒpvƒsmw‚‚~‰‹”q€|xyz‹tƒx‚„z€uo}‰‹›žˆ~†{w‡|hu†‘z€|‰†„v€gpn_d\XfYmsaaaqllh‰n`siX^cm€w©Ù©Ç†‡³rŠypŽv}ˆz”Š€utu~w€opn…t”†xtl`zyˆŽeq‚ogun[m}“€y‘’}wzl…t~Šƒr•ŠŽ‡……{†muvnhwem|vmjwv|`bx†zhuuc~{gu†Ž•|tuq€z|l~YVr|ot‚†~wkˆ†sxjt‚‚|y{wzqŠ|rgtdm‹„mt[k`vfIooL[cXWVxmbPSuvYQVX]`r„o\`cmdc]nbT]rGBf_^fi]Z{cRV\u[[gkaVk``nfflqhpvxtkŽŒuvx}wƒ{t}ƒˆˆƒoq€uqu~†‚‰‹{wx„|}…‡x‡|}~„€{~svx‹ŽŸ‰{Šwuƒz^~‡šy‡„t†‡„w‰zbnl[b[[aUjtd`[hopf‡raqfW\ck|ÊΆ¹¢knn‹mr…r~…‹{’…zytyuu{jlvc„v’‚vog_|y‹ˆeq€jjqcXl{†œ‰ƒ‚r—”v}{m‡p€‰Š†p–Žˆ…‹„{yrrp~ghrcnxqjlqw}|z]ez€wiuyf‚vgt‡‹”}r†jo~€xm{\Xp}ls~‰{mn‰pvfv~€~€uzpys…{xqer`m‹ksXk_y]IplNWV_TU|kbOTvsQRTV]bt†i\`kjfbYnaXcpGAh]`f_\V|^OVepY[jh]Xga_rfkhqgqsw‡yn•Št{w~yƒ‡€us†…Žƒpp{xwuy‡†‡Œ†z|u‹~}†„„‡~~}‡|xvyv‘“Ÿ~}‹nu€yd„ˆ—†s’Šo……‚zƒudnjY_[]]Uhse`YdrrgrakdWZ_ix¾®zŸ·nbt‡it|rz„‡{~€wwswo{vejo`‡uŽsjb^~xxŠ‚ep}hkkZVox‹¤…q™’qwtl†r“‡Œ‡„‰…}yusoiyajmamvjgkkywzw[g~|xes~n„tfv††•o‹fkz‚tltb[mzjszŠzet†}mpgt~w|~pzjyz€xwoelal‰}lnVkaxVLklOROiNY}gbOUvlMQTU^fv„g^aphgaWi]\kiJDkZbdVXUyZNWnjY]le]Zec^ufmdrfsptxp™…vx|…‡}ut‚‡€•‚nsy{{ss…‡ˆˆ„y}v}„‰Žƒƒ{~‹ƒ{w|wvš—zŠƒ‡jv~|l„†”€r‚q…‚~‚€pflgW][\[Tepe_XcruiupdebW[[hpors‰deyjtvtt„…x„zwsunkzpahkg†tƒmf^_|oz‰}hmwfjdVWrpŽ§}„|v–s{r{ylzzƒv–{‡†ƒ‡„}uqsmhu]mi_mudgfizo{rYgvuhp€x‚vbw…‹|”n‹jm{€pere_kxfqu‰z}auƒvikqtzoxwq{e}~~wunceal†|mkVjcrTLjkPLNpH^{fbNVueKOSW`kw~f]gsie_VbWbp]KKkXdaUTUsVMYveZ_l`\[ce_wgmbpitoq~ut™w€x€†„z}v‚ƒ~˜…nrt|ztq……‚€z‹ut€}”Ž€…„|~Œ†z~v{£¥Šy‰†…lu}{u„ƒzo…sz…}‚„unjieV][[ZScne[Xbt{jhmh`aW_Ziiloglaizzktuto†‚{}vunzhjyj_eniw„geXbwi~†ynioff]UXoh¨wz|Žxuo}nrtxŽ~w”t…‚€†ˆvjsvhio\me^ns_gbjxh{m[mƒstjo€~ywav…„x…sˆqoyqbph[mvcpr‡zwar€ogixsqkwvsub‚z}vuoccbm||kkUibgTLmhPGRlEaxfbMTs^JMUYelx{f_mqjc\V_UnoWJShXg^XMUlTK\z_\_k]][be`zhlaoovnowuz—}w€y€€‡†zyzƒ}“„qtt~zvt…ˆ}|ls•{‚Ÿ…‡}€~†‚€Š{v„¬Ÿzˆˆ„lr‚zv‚tn‡o}€tŠ€jonddX_ZZZUbjg\Z_u‚i^ml\aV[\kert|ij]lxwhuwrn‡|~~zvslzhixg]dshzw’ccTdog„vvfhiaWVYhd¨ox€‹Žzpo{fxnyŠzvŽqƒ}†ndwsdii]lb^po[g_muezh]t€orkq{~uvbu…‹{‡‡€wru~s`plXprappƒ{scq€k`lzoihywspdƒtyytqdadmr~jlTi^_ULtcQGWbGcwfaLTqYKLXXglvzeemqfcZX]XvfTJ\cXiXXHWeQIbx[]_m[^]bc^€ij`ntxmonvƒ—yr€}‰Œ†~vv†x†Œ}tuuyzz‚ŒŽ}„‰jt–{Š}~…y€{~|†‰sq®Œ{{‡~fqˆzt~}vro†l{~mzcpobe]eVZYWcfk`]]s†iXpm[^WZ\l{cqwulb[ntuhuvqm…yywnotehte[gufvv’z`]Sefj‚s|aci\TX^bd¥iyt‚…xlnxfwl{ƒytˆr€x|x€ifwm`ha_k`^ukYf]oobze[w|knnpxyttesƒ’‡‚ˆzvoq|qawcYno`op€{req€d^muicfwyrkm€tr{rqa^emn}eiThYZUNy`RKZYHbudaJUnTJLZVilr{cllscaYZ[aw\TKc]YjSVGYaNHjvX_am[[_bc]…ihanwylojvxm‚~€’ˆ„vu‰t‹†tqvvw|}~Œ“~px–ƒ}™’y€€xy~sˆ„sp™¢{{‰–xdu‰ysyvktply|p‘r^po`gblT[ZWidmf\\r‰fRrm[YXW`kvcjuji_[mtrmtttk†}€|wonldiqc[krdtvŽs\WSd`q~q\bc^SZa\d“Ÿerq„ƒskjxlnoyyzq€vrzz{dfvh^c[ah\^wiWb^phawa[{vjjroxtsthq‚•ƒ†~„urjp{levW[ilapqyseo~Z`oqb^io|kjr}qovio`[dkl{agTgUXRQw\SPYRHcsbaGVlQIPZVklk|emoqa[ZXYlpWSOfWWiSTFZ\OIruX`dmcX`ab]Œjddmyxkoiuy…{k„}€„™}‚„y}ˆm†qovz}t‚}‹ƒ‚—tx‚“†Ÿ‰ut‚p‡‚uo¢—s{†Œ‡{fw‹on|pgxq{lsvsk^tnagfkS^\Vhbll[\qŒdNom\VWUfishctee]Zovoquuzlˆ}€}ˆwscekoa]nmdsxˆkZTVbcw||p„\c_cTZ`Zc—•cnpƒ„‰rjgyneruqzkysuoz~v_gsd\_WbdYaufV_`mdaq]]~ohisqtquvkm…“‰{…qqfn{opnRZeidprusbluUbqk[^nd{dkt|qqqil_Xdijx^fTeUVPUoXQWTPHer_aFXkOIXTVnid|ikxkaW\U[tdSRVhQYgTSHZ[PNxw[_fmjZb`_^nbgkyvnnivv~~m„€~†—{‡‰~k“ˆrgt€{uƒ~‰Ž‹“s}Š‘…‡Ÿ†{†Œs€†s}‚un¤ŒsŒwxnz`e}qgztylmqwƒgd|mcfghS`_Ug`lo\^nŽhMil`UVSnfskfxde]Zquns{xsn‰{wœ{zlbelm^`ojeqygZVX_lx{zoƒ_b^hVY`Xdœˆbkq†|wkjvl[upjyiurmo{€sXko_Y^WcdXeqcT_biablZ`~kfksuomxvkh…Œ‰z‡mpeo{lqlbX_ggnrsr^ilSepdUbmaxaotztjnkj_X`fhu]dVbVSOYgSO]OOHeo]cGZjNJ_KXme_xhn~d`U^T]t[TS`fN]bUSJ\ZQYuv]_fmhXca[^Žqchjxrsmgvsyƒs‚ƒ{ˆŽ~|ŠˆŽynŠtls‚tˆ…‡‘„•z}Œˆ‘›„€|Œ„rstwqn““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|}~}}~~~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’‘‘‘‘‘‘‘’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’‘’’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ”ÎÚØØØØښ„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDBK’š™™™™™ž     £€dggggfo„ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ”Ûéççççêœ~‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR455553?“žœœœ››¢¤¤¤¤¤§|]____^j‚€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}zzz|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹’—˜˜˜˜™™’Œ‡‡‡‡‡‡‰““’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†…………†ŽŽŽŽŽŽ‹ˆˆˆˆˆˆ‰ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z||{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘‹Ž‘‘‰‡ŽŠ’“‘‹‘ŒŽ‡‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…Ž…ŽŠ††‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰ˆŽŠ…Ž†‹ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰ŒŠŽˆŒ†ŒˆˆŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{||}}}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹Œˆ‹‡†ˆ…‰ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz|||{}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒ‹Š‹ŠŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzyy{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{z{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†……………„„„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰Ž‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{~~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““”””””””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••”””“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””“’“““’’’’““““““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’’‘‘’’“Š‡”’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’Œ‹’‘‘’‘w†“‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘‘‰rŠ’’€s‰‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘spŒŒtwˆŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽwkz†tw‡ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽ{ek†~qu†ŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹Š‹‡h^hegcn‚…ƒ„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxz}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzoq{xy{|{xw{xuwttvuuvwo^rl\imgehklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkiffggghh^hul]munfbcbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__ac_\_]`]^Z]gom_ksulYY_[XWSNMKKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{xvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSTPMJMNPROMVbhmsppsnRQTPPNNOMJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTtsuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMNTaeenmmihTMNOPPONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKKDCFLZhlhmlmigc[URONOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEEPTUZdkmgllkjjihig[LJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:;>BJYchlkolmljijki_TIEEEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@:;><;;;:FNMampptpjkiXKBEEDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnppsttsqrvyy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;:;;99:88;<979;;=;;K`m{sj[G=@@CFDCCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqtsurqtxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<:79::979::78:99:98BjmH97<<=@A@=;;><=<@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyy{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>><==?@===?C;===<=<;G\9<<>=>?@A@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquutusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCDA?=>@A?@<\n@>DE?>A<E^=>=;:=>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVppqssttuyz{{|~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???BFD><<=@=8:;mwH8;:==A<Kc=<=<8:;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pprrrtuvz{}}|~~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC?>AAABA@YR<==ILFFuwM788:;>>WjA;<<::;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC@CsyI;]ƒ€z|wV<=?==>FitL:=>?==>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hloppqtuvy|||||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCEAHrykb‚„ƒ‚ƒ€|]>@C@@=Jr{Y:=AEABBFHC=<@DDA@?>=@A>>>?<>@DGE@>@A?@CFECBCC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{{{}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@Fot}‚‚ƒ~}„uLACE@?>Y{€]?CEIJIIMMKECFGGEGEEEDDCA?@>>BFJJGEEGFFJNNKJIGGHKLIGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@EEhs}|„~y…rCDEDCWu†‡‡~XGHJMLNOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHHHGFEFFFDFHGEEHHFHGHFQnnpqruvy{{{z}}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJG`{€w„…ƒ„‰lAAVt‡‰‡‡‡ˆƒWHLMLMNLIGGGGDGGGGFHFHECDDFEDDHHCCCFIKKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrtwwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLLN[|‚‚ƒƒ…††ˆƒVl„‡†††‡ˆˆ‡|PKLKHGFFDECC@@CCCCFFEB@>>@AA@BD?>?DFHDEGIJIJHHHGIIJJIHFJJJJIJIJJJFILLJJKKfopsrtvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKLLJTƒ„„‚‚…††ƒ‚†…„„†††‡‡†ŠuIIFB??@???<<<>;:<AA@><998<<=;>;8;?AB@ACCB@AADDBCFHIHHHLMLGIJMMNMJJKKJLMSlpqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHHJJIe…„„„‚ƒ‚ƒƒ„……†‡ˆˆˆˆ‰ŒŽfBB=88::9878896479;<:8557789787588;;;=@;999=<>;<=ACEHJMLLGIHORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@CGIIh†„„~ƒƒƒ‚ƒ„†‰ŠŒŒ‹‹‰Š‹Œ‰T:8656766656773568:876565676768:67889;7578979776:<@GFIFIFEFOSRSSROPPRTepqsttvy{{{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:=ECBe…ƒ€‚ƒƒƒƒƒ…‰‹Š‰‰ŠŠŠŠ‹‰ŠŠG676468874578567699776765:9:::;798987779:98878589;A=>>BA?AKLOQPQOOORWkqrttuvz{{{}}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897;B:=q„€ƒ„„„„…†‰ŠŠˆ‡ˆˆˆŠŠŒŠ‰‰Œz>988;<>>9::;89;9:;::9;:9===>;;<=:=;9;;<;<<99<8::::999<?<<ABDIJMKIKLWorsusvx{{||{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<:89989:::;?>H~„‚‚„………†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>BCEEBA@B>@BA@>=>>@???@??==?B?AA?@?=@@@>?A=><;:;99;?=;<==AACABCAXpqtttvz{{|}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::<=:;;==?@BR‚‚‚„…„…„†‰‰ˆˆ†††‡ˆ‰Š‹‹ŠŠŠ‹Š‹^>DGILJJFGGDFGGEBA@CECCABCB?@DHDCECEEAFEFDEFD@B><@>=?@>?>?>?>>:;=<`qrttuwzz{}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>???=A@CCFW„‚ƒ„……††ˆ‰‰ˆ‡†††‡‰‰Š‹ŒŒŒ‹ŠŠˆVHMLNLNJIKIIJJIECDFGFDCEFDBHIKHGGFHGEJIKIJKJCFCCDBAACBDCCDDCA=;=@hpsttwwyx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLK@BBA98<>;<;>@?A>BBGGJY„‚ƒ……†‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒ‹ŠŒPNPNLOLJLJIIHJFDFHHIEEHFFELLMIJGFHIJNMNLLNKHFGGEECFFFFDEHHFCA?@Llptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?EGG=<@@87<;<=:>@>?@CFIJQ_ƒ…„…††‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒ‹‹ŠrNRPNMMLLJHGEIIEJHGJJIJGGGKLNLLHHIJMPNPNMOKIGIJHIDIHHFFGGHGCBACUnpuwwyzxyzz||}~~~~}~}~~~~~€€€€€€€€€€€€€€TDAABGHB?8?@8:<8=>;=A>?ADHJLUqƒ„„„„…†‡ˆˆˆˆˆ‡†ˆˆˆˆ‰‰ŒŒ‹ŒŒŒ‹‹‹‹_SSQNOMKJGEBGJGLJFKNKKJJKMLOPNHIKLOQQPQOOJHJJLJKFGHGFFIFEEBABB\orwxyzyyyzz{{~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<9@>>@BGGAGKLPVy…ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹ŠŒŒŒŒ‹‹|XWSSUSNLKJDEFKONOWUQPOQSRMSTOMSLPSUVRSQPLJMMMKNGGJFFHJDDEEBECcpuyyzzz{z{zz|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?==B?BBGVNFNPPTX{†ƒ……„„‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŽ‹‹‹hXWkaERQQPI;;RSR`u\UVTVYYRXXRZfPUWZ]RTWQOMRQPPQKKKHHJHEFIIIHIirvyxyyz{{|z{|}|}€~}}}}}}~€€€€€€€€€~~SHJIHGFFE??AAEACGEDELXRMTUVX[|†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ}aŠ‹‹‡m\dU:XXXSQ?@VUY\d`VYbr]]W]ZVEQYZ[Y_TYgRVVXTTVTOOMJLJIILMKOMSosvxyxwzyz{zz|}{~~}~}}}~}~€€€€€€€€€€~~~VJJIHGEDDBA?HMIMPKIKPTSSXZZ\\x…„…………†‡‡‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~‹‰Š‹ynpYZ[[RSRVVT[ZuƒYU}`\X]^WIV]][[_YHYXY[]XXYWRQMPQMMOSQQURassvwwvxxxz{z|}}}~}~}}}~~€€€€€€€€€€€xy}YNKIIHFBD@A:PQQWXPPOQSTTXXYZ[n‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡„Š~fYY\YSVTWRQWVc–€QerXZW_hP`f[[X\gaGOZhg\[\]]WROSPPQVVVVYZnrtwvvuxxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZ[RSQORRRUSVTW_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PUXTRTRQQLOMKfy[]TYUV]ZLTZUST^ZXWWWzkX[[\^TQQPINOWVX[Zdprvvttvxyy{{||}}~}}}~}}~€€€~~zxwvsu{€€tk~~kry^[VUTROKFCDAM^ƒlVRSNOQOQURSRRUcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ymqVIKMNKMKHJDEIEC>TdURQQNKQTQMOYRMNQSUUMQSRPOMLHCIHRTUZ\lquuusswzz{{{}{}}}~}}}~}~€}}~~€~{vsw}~~du}iqt_d]^[YVPLILIal’tPQSNQRQR[RSRQRUTbs{|€‚}{{€ƒ‚…†‡‚†††„†…†u_]LD?CCCCB?DPBC@C=CIGV@HNLG]iPHFNFDEFIGHCDHGHKGDBAD@OQMRdrtvustuz|{{{{||}|{~}}}~~€€€||}€€€}vt{mh|gnqfiedb\XSQPURsWe[OONLQSQUYSUQQTSOV`klrv{{xytrnstsyx~ƒ€ƒƒ‚€‚€‚‚kMG?@;;>@@??>kPKaEFHIEB?GLMGMRUIBE??<=<==?=?ACC@?<=B>JNGUnttustvxz|{}{|}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QRZ\Y^JJPQNKLQRQTUUWQQWVPX[b]agmmlokg`nrjmlqu{z}{xz||xwxeC@@B=:BCBBDB\]O{NONNKLMOOPLKMWMHG@B<977599=;;;8989?<BH?\stuvuvwy|||}||}}~~|}}}}~}xuvz{zwyxuw{|yxuywcqhipmnmmhf^OP^\ZIHPRQOMPQNQRTVXSRYTNYZ[WY]^^_e`]^qvk^`gkwooljonnlfbYHFGHBAGIEEFDMRPaWRWQPSSRU[OOQVPMIDF>:96587979:365795<C>essvwwyy{}}||{|}~~~{}~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZXMKTTSPQUOLRSTWXTTXQLWYZVXXVXY]WWXhsk]Vaskba_^da_^YTQNNNLIHJKIIFCQPS[WTTNQSYS\eUOSSQNKIHC?A999897885757859:Gnqtwxy{{|~}}|{}|~~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnpppnmd]__YWOPXVVSTVOOTVXXYSUTLKTVUUUWPSUWTUR]n^RNY_[VY;DVXT[fJLORROMMNNNLJFQPUYSTOJNOUST\VRUSROMLIHHF?>=:787659967675Wppswyz{|}~}~||}|~}}y}}|~~~}||}}~}|rvqxxrvuqqnppopuvtnjddjppqrpnfedc\]RTZVWUTWTRXXYYYRUOIGOPOOMRJPPOPNNOTLMIPOSTU2=XMI@Q=caQSQPNPQPNNMQNTRPRMILJORPRRSTQROLLKLLHCBA=::876;B5566:doqtwx{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqptuvcjgeWhtrrqniihpVVTUXUWURWVUZYXWUQSFEAFGGHFJDHJIGEHLHKIFLMPMG/E_R>3?>joaRRQ@GUQPQPQNQOPOLJLLOPNNPQQNPOJLMMKGEEDB;=<<9=G6677Dmptuy{{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknaePSTRSTOWVVYYVQQQO@=;=?ABAC@BEDA@GHGHEFHJMLEGCORC8ENS]gSPSAGUPOQQPMMNMKLKLNOOQMOOMHLLIKKLKGFFED<AA>;@E;<89Sprtx{z{}||{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLOOMQSLTUTXWUMLKI<987;>@><=A@B=>EHGCFFIGJJ@FAA@FHEJOHQRa\QPROSNOPLLOMKMLMON[WKMQOGIHCHJLLJFFFD?BC><BG?B?Adpswzzz{|{zzw{wy~~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHDD=9779?B>;?B@@>ADJECGGIGIEBB?>=CBAGIENObeQMONWKKMKLMMMLKONSdNJLRIIIEAHJLMNJGIFBAB@?EFEHDKnovyyy{{z|zwsxtx||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGMMJMPMPOHJD?A=98::?B?<@BAADEGKFCHIGGHCC?B??@A>DECLNRTLJIMTFIIJLJKLIJLMOPRPKGCLGCBJJLMONIJIGCCCDIJMLIYrmwyxz{{y|vrpurtxyvxjqnjllnttmtu{stxronqovsnporpopstyjN`gsjt|ygosqiqhdqGKDGHHGJKIJKDGB=>=:9:;AB?=BBCCGFIKJDIIFGGCC;A@B>@@CEDIMPHHKGHKDHILMHJLHIJLKM]RHHDNFADJJMMPMKMJKFGGJMNQNLbmivvwzy|z}qmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoiktgdoFKCFEGEFFGEGBC@><=9::;@C@>BCEEIEIJLFIIGFFDB;ACC>@CCCDGLNHKNHDHEILNMGILGFGIILNKIGENHCGMKMLOMMNMKHHIORQRNRfffqosxu{z|lhjoekqlspfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGJDFFECCBE@DB>@>:;;=:=>CA>ACEFJFIHLHGGGFEC@=DEB>ACCCDGHIGMPJFFGKNOKFHIFEDEIJHJIFHPKDIMKOMONOPNJJILRUUROWd`amgproryzgehhdilgqlflmgiklslpvutpnvrosrsutqssutsuvvvyvutwljuumrvqlnlerLHEEHCBABD=BA>A=9:=?:=>@B>@BDGJEIFIHFFGECBAAFFCBBBDEEGGIFLQLIOJJLLIGHEFEDCIIHKJGKRMBNOMQNOOMNOKKKOUWVUSX_^\iaminhrsbeffdihfnifmmhkkmriqvusqmvnoqrswsrstuvvvvwvwvvtwujsunutsqrjksMGHFHBBADD<A@@C<8:=>9?<?B@@@DFHEIFFHGFFDCECDIECGEBEGEFGGEJMKHQMJKHHIEFHHECIIIKMKOSNDQRPQQNPMNPMLMSWVXWUX]Z]d`hbjigk_eefcgggkggkmkmlprhttursnvoqprtxqssuvu‚‘yvvtxuuwxmouorsuqqinyMHGHHBBBFD<?BBD<7:>>:>:@B>??BEFDGDEHFDECDEFGJEEJGCGHFHGECFJJGMKLKHJLFIIKHEKKLMNORTPHSUSPSOQMNQNMPWZVZYVZ]ZXa```^hec`dfhgihhifhnllnmqpiuuxrrpupppruvpusuvu{~}xvtwvvvxplupmstnprrxNIHGICACHE<@EBE<8:>>=<<AB<?>ABFCECCHECEEFGGGIFGKHDHHGIGFDHKIGKHMKJKLHLKMKJNLONORUVOKUWSQSQRLOQPOTYZY\ZY[^^^`c^\ackb`dghr…hgifjmnponsrjtuxrsstrnpqvrquruus~yŽ}uuvvvvxrhuqkrtlqvptMIKHJFBEGE<@GCD@:<>@?>?BA<@>AAFCEEDIEFEGEHHFHHIKJFJHHKHFFLIHHJGLLMLLIMKMMMOLPPQUVWOKVVUSSQQLORRPV[[]^[\^__a`ad]c`ef`ehjcssfjgglprqossnswwquvtsmoruorspurvrtvuuuwvuwtgtrkqrkrvnvJJLJLGBEDE<@FDDC;??A@@@CA?B?ACHCFEFIFIFFDIIGIHJLHHJJILJFJKHIJJGKKMMJJMLNNNPLOPRTXVMNTVTRRQPLNTSRW[^^_]]`_`aa`acebdhbdijgv‹ljigmosqpqppryvruutsmmssmqrotutrpswtuuwvuuteqskpqjrvnwKMLKMGDCAD<?EEEC=AACBBCDACDAAEGCHGHHGJGDHIGHJFILHIJMKMLGKIHKKNQKRQMSMKNNOPPOTOWXX[NSPW\ZRWPNTUTTXZ_bb_da^`b^`eaacingbihhnxvlhimosrpqrrrvtsusssnksqmprotvrqquvuswywutucmtkopjqtowLNLLLGEA@D>>DEFC@CAEDDFBCEGCCIECIJJIIKGEKJGHJIIKHJJNLNKILHJLKZfJd\KlSHON_nUks[qpbwcSPavuhucav`Xnqbdvinzf[lt`ljT_wvijgifglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqrqyLNJJJFC?@B?=DEFDCDBEEDFBFFGDEJEEJMMKLLGGMIGJKHKKIKKNLNLLLILML[sbdp^lmUMNfs]geqlntgpi_aYnnbppbkjjgoqtetno\ougpMJqyvkb`keemxlkvmnpsrprqpqrqrrrtrmmsnnoprutqsstuuutwxvutbmukpplrrqzKLIHGED@BB@>CFGBFCFEFEDCHHGDEKHGLMNLMMFJNHJKJILJJJKLMNNMMJMMM[roonpplkMPQlWNibtrpamnu\YlQ\mmZqmkomxxtsip]_rkqjUuyxpc^kfbgppjjopprspqpqqrrqqrrtlmrmnnorutqtrtuutuuzvutenukpolsrryIKGGEEEBBB>@@FGBGDIEEEBFIHHEGKJGMMNKMNGLNILKIJMIJIJKOPONMKNNL\hdu]lqWlNPQmUZk^klvaldsSecNmYl\tpkilxjwuhp]^rkhWbcw|oc`ggadityknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtvHLFIDEECAB=BACGDHGLHECCHKHHFJLLFNLLSRLGLMHNJHHNHJJIHNOMNLJNMJZsppoqqmlOQRnYqkgooqqomt]nXat_nopoqronusttj[]tcwxrjnzhaacfbbjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyxtukoumtonssvsHKHIBEEEA@>DDBGDHIMIFCFJLIGFJMLEOJKWRKGKKJNIHJLIKJIHJMMMMIKKKSkc[i^_icrrZ_Yjo_eeUk_c[aaQ`lh]j\niid[pfdp]Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunwqrvtwrGGFIDEDFA@BFEDGBHJLHFDGKLIEFJOLIPIL[QJEHHKMIHJJKKIHIGKKKLGHKKLMMLJKMNT[\TPTLPONOOVQOOQNOQJINPQdqiTYW\[\UY[]X]\\cfaaebce__fkmhmtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyxxuvqruovrtsuusGCEGFFAEC@CHDFGCIKLHFDGKLHDGIPKLOKLWLIEEHIJHIKILJHFGGIGHIEFLIJLOLIP\W^P\[`^MXYS\\b^MXZMXaRJYaZR_d\aX[ddVVX\YZX\VY\]b^d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtOBCELMBDCBEIEGGFKJKHEEJJKFEHHPJMMJMRIGEAHFJIKLJLJHFDIFDFGEEJHCJMKLU_Y`X`a[`TXYT^^Z_RY\P^\YN^\^SZ^c^Z]`c`Y_c[`^[TXWY^]cbcacehekrpoppnow††……†‚{€……††…†…uqprrsvyyzyyxxxwryvxrqxvtvaSJJMIDBBCGHFHGHKIIIDFKKKEFIJNKNLHLNGHE>GGLIKLKKKIGDIDCDEBFJD@JLJO[cY_^a_RTRW_`\]Y^QY\MV_WKQY[PZ_aa]^ca`bbbcceZQYUU\Y]c`__cdbhomnllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxXQKFCGEBEGIFGHHFFJGHGHKILDDKJMMLLHJJHJF?GGNKKKMKKKIFGCD@DAHIB?IJHP]aZ[d]_TQRX]\\\_ZKW\LR\YIM^QO\_accccb\dcbdcfXQUTR[WZ`_^^aa_dlkmjjlnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMC@IFDFKJFFFHGFIFFFILJNFDKKLNJLIKJHIFBHHQMKKOLJKIGGED?ECHHABGGET]Y^X_Y_[]UXXO]]QKJV^X^[]UY`RQ__bb``bb`cbaddbXOQQQZR[]]]]^__dhgljnnp{{|~{€‚ƒ„………………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKCAHFDGMRHCQJFHHHEFKJMPEFIJKNLLILLHIGDHKQNMMPLLJKHICDAEDHGBAGEDWUE\T]SV_XOTUNZZMIJT`a[_X^^a]OYa\``_bcb]abW__TPNOOWQ\[[\\^_bffelfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDFFHDIRbPCV^IGGHDFMKPPEIIJKNLLLMKJJGEJNQQNOOMNLMHKADACDFDCBEFBMHBKKOONLFMFGIJHGLKMOPILOPOSOLPSRUZYWYXXdWOSTPPNMOTRZXXZ]\`adecgcklpsrzy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEHFGDKM]LGGXLGHJHGMLQQHLKKKNMUNOKKKGGKPSSNPONONNGKF`ED_LEfdEM[I^[rmOMUmYLDP`UkWgJ]WU^DLQULLSVQRTXWTXUT\UPfZhhdXRjRVUT[\[``abbb`fhfnkhrz|}~„„„„ƒƒƒ}|zr{z{‚€ƒ„„……„…ƒƒ~z{LIFGFHEEKOSIJF`SHJOJIOMRQKMLLORUROOIKMGHMQ[YOPPNOOOIJQQI|YYqtYQmHqnoaVPqqsPCksmqspSo_[nX]V\XUkhU]VcZ`Y[`VVXjtuu__v_Xa[[f[_`aaa]`bgmpl`pwtx‚ƒƒ‚}€vxzlv~tx}€|~€‚„|€ƒz~wwNJEHMNBDLLFILEQVLKNIKRXWQMOOMQTNOQPKKNGMPS[ZSQROPPPJHZx]TxehZSTRvgtlpbnfjQrOMwmjrpsrqrpoo€]ezuxqqzq~s}ku}bRh|essosr{|o~xn€r_``baZ``gknkblfgmw~€ƒ~{xw€tvzir~ns|~wx{~€ƒx|€u|||ssNKF`]GAEMMHJKGJPOMMJNV^YULQSNYZMSSRNKOHQRTYWVPTPPPQKHgxlcxrm[KMUypumubnvPdeJfvqmwo€jfxxiWrQhzmijzz}lxzohoYvvjuup`rf}ilx|o^__ba[]bdgiidgbcdllppstsssyqrxblugqy{srvy~suzn|}ywrnNKSuNCBFPPHJKIKPOOOMOZ`ZWKTWPa^RVQYRLOISTUXWWPUPONRJKrouuquqdibWnLqp^FhyWvTLiy}x`y{sna]mocRhqunmypwlvttrln]t~zkmy|ktl|kpvux^__b^]_ddighee^abiiijknokqnmjpacfcowxompsy~nqpj{ztsomLL[VHGEGRPILMJKPQPPPPW\XUMUYUeXRRY^SLNITTVWYWOSNNNQHRmHiwK`dvvVXlOnl{sajgvULWkh}lmlx_[pz{^`zscroxqhd}ir|^TLl`vukiu{{m~xk|p\^_b[^bddgeeebZccikkrsrwglihdg`akagsrlgmmr|kmhk{tmmkmOHKKIIHHQPLNOLKRRROSRWRVTPW[VVTTTa_PNMKTSTQUVNNLMOPJHQNPULKLSTSSTPVUQQNQQXYRNPUTXXX[ZURSW[WXWZOSUWXXR^YW^VTPYRVWWWX^[gr^[[Y\]_cZ_ccdfdccbZccffemnmueegcaf_]g`dlhfgkhpzhggkujhgilQIKLMMKJSQMQPOLVUTPTUXUYUQZ]VUTWUYWOOKMVTQNUSNOMLQPKJRQKQMKKPRUSQRSSIHLNOQRQQQTVRXW\WSSPRTUVSZQNSRXVTYVTZVTRUTTUWXV]Y^`]\ZZ\\_c[]bcdfdddaY`acabhhimbad^_c]Zd\bma^fefmsdihkkedcfhPJKKOOLMSPNSQQMXWUTUWWWZUS\`VWVYUXSPPJNWSPNUPNQNLSPLOUSNQNMNQUQUQRTUNKMOQTTRRQVWTYZ[YSURTWWWY[TPTUXUUZUWZVSRWVUW[XZ_\UX^\^][]`a^[bbcgfedbX_ab]`gdfea^_]]^ZZ_Z_g`^]]bhkagfhfd`bcaPKMLPQLOTOOSQOQ[ZXWX[YXYV\jdVXYZWVSSOJNVTPOTPPPNLQQPRXTQQOMOSVOWRTUUONMQSUUTTRTWVZ]\ZVVQQVXV[[WQTWVVVYTXXVSRYWVZ]Y]_^U^]^`\[____ZbbdhgddbXa`b^^fcc`b]\\\\YZ[X[a[^]\_b__bdebd__`\PMNNRQMRROSTQOU\ZZW[[\XZ[dqmhd_[YVUWQLMVSMNROQROLPSRUZUSPPMPXWRWSSSXMOOQTXVUUSUYX[^][[VROUVV[[WRTWVWXVTX[TSRZXW\^Z^_`Ua\aa]`b_]`]c`cghdf`Yc`a__ed_`c[Z\[\YZYXW\Y\[`^_[^^a`^b\Y`ZQNONVQPTROUTSPW\\\X^\^V\^jqwy€c\[UUXQMOVSNQQPRTRKQTTYZWUOROSXWTSURRZOPSRV[VVWSVZX]^[[^VSNTUV\\VRTVVXYSTY\USS]XZ]^\```Va[cb]ac_\bab_cfidf^[d`a`acd_b_YZ^[\[YXYWWZZZa\][]\\Z]`W[[ZPOOOYPUTRQWRTP[^^][`\`U\]hjr}slg\TWWQNRZSRQTRTUTKRVV[ZZSOSQVVVTOWRSZRTTTX]WXXSX\X^]YZ]TUNVWW^[XRUUYYYUWY\UTW^Y]]`]bb^Y_[ea_dd^^cca^efidf]]da``abd`b^XZ_[\[XXXXW[Z\`\[[\[XZ[^V^Y]POORZP[TUVVTTT^^`^^b\`U]^bkytl}kZUYUQQS\TUTUTVYWLR[W][]ROUSXWWTPXRSWSVUU[]X[YUZ^X_^Y\YRWRYXY_[ZTUVZYZWXZ\VUZ^\^`a_dc\^]]eaafd^^dc`\gdhedb_da_a`bb_`^WX^Z\\ZYYWV]Z]^ZY[\[WY\]VXW]SOPWYQ\UVYWWUX__aa`c]_T]_beeuzhXYYSUSV\XWWVVW]XOU]Z^]\TRWSWVUSTXRSVTXWX]^X][V]_X__X\VQYTYZZaY\VWX[Z[YYZ[XV]_`_cbadd\b\`fadfd^_dbb[fchecf`f__aaaa`_^VU]Y[\[Y[YY][[[XXY[YZZ]_]TY]UNTYVS\TVWYVV\`abcac^_V[`da_zuohY\ZUWTW[ZY\YXY`WPV^\``\TTXPUWVTVWRSUWZZ[_^Z_\V__Y]^Y^USYWYY]bZ^VW[\[\[[Z[YY__``dbcdebdYafcffe^ab`c^bcidcg_g^abcaa`^_XT[ZZ[[X[XX\[Z[WWYXW\[\`]V]]SOVZVVZUXUXWX]_badad`^YYadb`lfh^[][VWXY\\\_[Y[bVTX^]ac\RVYPWVWWWVSUTX\\^``]`\Wa^[^\[^XVXX[[_`\_XY\\]^^\[]X[`a^`dcdeefbXcedhgd^c``ec]eidei_f]cbcaa`__[XY[YZZXYXW[[Z[WXZTY]\Z`\U^bNSWYVWZX[\XWY^`badada]^Yacb_a``^\\\WW[[]]__\Z]cXZX]`cd_RXYPWWXYYWVWV]]^`a`_b^Ya]]^Y]^YXUW[\`^]_ZZ^]^^a]\[Z\`b_bdcefefbZdffigc_c^afdZiicfjce^bbca``_]]ZX\YYXXZXWZ[ZYWXUU[]]]``bbxKXW[YW][\]ZW\]_`bdaba]`Xbcbacab][\[XW[\_]`_][`d\\XZbecaR\ZOXXZ[[ZWZY`]`bb`ac_\b]_][^^YYTX]^_`_`\[^^`bc]\X\^`bbcedfdefd\efgifcab\cg`\iibhjed`baca_`_]]\Y\YXWXYXW\ZZWWXOXZ]acffrkJYW\ZZ_\[^\X][^_acbaa]b[bdb`bcb\[[ZWXiq`\`_]\ac_^YYcedaS_ZRYX\]][Z[[c`bbc`bda`c^`\^^^ZXV[_^]aa`^[`abec_]T]``cddfegeffe^efhhgdd`[eg^ahhbhhfc`b`cb___]][Z[YXXXVZV\[[VVUMXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡…‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vvvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{{{{{{{{{||||{|{zzzzz{{|||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vvvvvvvvvvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{{|||||||}}}}}|}|{zzzz{{||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚‚ƒ‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||upooooooy~}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰Š‚E>????@0*+++*"ŒÛÒÒÒÒÖº}~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}upnoooony€~†“y1333332j‚€€€{­éääääèʉŒŒŒŒƒ:233334!ïååååéÇ}~}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}vuuuuuuuvwwwwwwxyyyzyzxopppppprrrrrrrwzyyzzz~ƒƒƒƒƒ„|||||||vuuuuuutssssss}…„„„„…‚|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚ƒ‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vvvvvvywvvz{x{xwvwzxzyy}zyyxxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{||||||||}}}}}}{zzzzzz{||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwwx}y{}z|{xwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwww|y{~y|zxxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒ„‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z{xwww|yy|z|{wxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzzx|z{|{}{xxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyxzyzzy{yxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyxyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{|||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}|||||||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}|}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrsuuttssssrrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqsttssrqqqponnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqrsssssrqppponnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrrrrrssrqozopoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpqqqy{prqpq—ƒnppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqprq}žzpqo† |opppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqqrŸvptœŸ}oppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsqu‹‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqrp—¬n£Ÿ~pqqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrrpŽ±¨zˆ¦ }pqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrssssssssœ³¦¤§±¢vssssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz~|~~|vvwwvuxzxxxxxxww«¡¶¦¢§„zyyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~||||{’¦™£±¡›¤”z{zxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}}}}}•žŠ”¬žžŸš€}}}€ƒ‚€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€€”£œ”œ›—Ž›ƒ€~~€~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~€€~š²©£›ŸŸ¥§‘}|}~€~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~€~€„•¯¦ž¥ŸŸž¤¨­Ÿ‘‡€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹Š‹‹‹‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚ƒ‚†‰–¦±©ž›¥ŸžŸ Ÿ£¨¨£—‡€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒ‘‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒƒƒ…Š™£Ÿ™˜˜ž¡Ÿ›œ™“Œ…ƒƒ‚ƒƒƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒƒƒ€‡Œ‘•˜™•›˜”‡††‡‡††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠˆ‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„ƒƒƒ…„‚ƒ‹–œ‡Ž›šŒ‡†ˆˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ‘’‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„„ƒ„„‚„‹Š’Ž…„ƒƒ………ƒ„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘’’ŽŽ‘‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€‚ƒ‚‚‚€ˆ‘‚‚ƒ‚€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„„„„…„…†’“‘ŽŽŽŽ‰ˆ‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~€‚‚€„ƒ€€€€€€‰‘€‚ƒƒ€€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“‘Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚‚ƒ„‚‚„„‚ƒ‰–ˆ„‚„‚‚€Œ•‚‚‚„ƒ‚‚ƒƒ‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘Œ‡…ƒƒƒ‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒ€ƒ‚……„„ƒƒƒ‚„Ž˜Šƒ…„„„‚€’š†‚‚‚„ƒƒ‚ƒ„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”“’’ŒŒŠ…„„ƒƒ‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~Œƒ~}|}Œœ€‚‚‚…”“Œ‚‚ƒƒ‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†””’”’Œˆƒ„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~•—‰€}}}}{—Œ€ƒ€“Œ‚‚‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“’Š†ƒ„ƒ„‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€€•ŸŠ~~€}‡‹~„„ƒ„‚ƒƒ‚Ž‰…Œ‚‚ƒ‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†„…ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„‘¡ŠŒ…}†‰€~………„…‚~}}‚„ƒƒƒƒƒ„ƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„……………„…†…††…………………………††…†††…†††‡†…………ƒ„„„‡“““‘’ŒŠˆ…†……‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…ƒ‰‘ƒ„‹…‚~}‡†ƒ€~~~ƒ„ƒƒ„„„„„„„„„„„„………„…„†…………†††…†……†……‡†††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„„„‚‚‰~}~…~€€„…„…†††………††‡‡††…†……†‡‡‡ˆ†‡‡†††‡‡‡††‡‡†††…„ƒ„………„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘”“‘‘‹‰ˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒ„„„ƒ€€€„„~~€€€€……†ˆˆˆ‡‡‡‡ˆ‡ˆ‡ˆˆˆ††‡ˆ‰‰‰‰ˆ‡†‡‡‡‰ˆ†‡‡‡‡†‡…„ƒ„…†…………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†……„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡†…ƒƒ…„„ƒƒ€€Œ‰€‚‚€€~{z€†‡ˆŠŠ‰‰‰ˆ‰‰‰‰Š‹Šˆˆˆ‰‰‹‹ŠŠˆ‡‡ˆˆ‰‡‡ˆˆ‡ˆ†‡†„ƒƒ…‡‡‡†……„„ƒ……„……†„„„………†…†…ƒ‰”“‘ŽŠ†…†…ƒ‚‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡†„„…„ƒƒ‚€€€„„‚‚‚‚‚‚‚€~}}}}~~|{|ƒ‡‰‹‹ŠŠ‰ˆˆŠ‰ˆ‰‹Š‰‰ˆˆˆŠŠ‰‹‰‡†††‡…†ˆˆ‰ˆ††‡„ƒ‚„ˆˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚ƒ‚„ƒ„ƒŽ“’‹‰……†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„……‚€ƒ„‚ƒ‚‚‚ƒ~}}~~~~~~}~}}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡‡‰‡‡†ˆ‡†‰‰ƒƒ„ƒ…„„……‡ˆˆ†…ƒ‚‚ƒ…‡†‡††„‚‚ƒ„‚ƒ„„‚‚ƒƒ„ƒ„‘’ŽŽ‹‡„††„‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…‡ˆ‹Š†„†„‚††‚‚„„ƒƒƒƒ‚‚}|}€~~~}|}}|y|ƒ†††„ƒ‚ƒ„………ƒƒ…„„„„„„…„‚‚‚‚„„‚ƒƒ…†…„‚‚‚ƒƒ…„„„…„„†„ƒ„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰…„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„„……‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€€€ƒƒƒƒƒ‚‚€}}€€}~~}}}}{zz~„„„‚€‚‚~‚ƒ‚‚‚‚ƒƒ€€€‚‚€€€€€ƒ‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†‹“‘‹ˆ……ƒƒ„€‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€ƒ‚~~~~}‚ƒƒ‚ƒ‚ƒ‚}}~€€€~}}}}~}|zzz€‚‚~€€~}€~€€€€€€~}}€~€€€€€€€€‚€‚ƒ€‚„ƒ†’ŽŠ‡‡†ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒ‚ƒ„…€€|}}~}}~€€}~}~€ƒƒƒ‚‚}}~€€€~}}}|{{{zzzz€€~~|~€~€€~}~~}|~€~~~€€~€€~€~€…’’Ž‹‹‡‰…„ƒ‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~~}~€€~€„ƒ‚€~}~~€€€~}}}|{{|zzyyy{€€€€~~~€€~€‚€|~~~~}|€~~€~€€~}€~~~~~}}}}…“’ŽŒ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒ‚‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚‚‚€ƒƒƒ€€~}}~~~~}}}}}|||{zyyyx}€€€€€€‚‚€~€~~~~€€€€€~€~~€}~~}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚ƒƒ…ƒƒƒƒ…„„„„„ƒƒƒ„‚‚‚‚‚~}}}~~€}}}}}}}}}{zzyyyy€‚‚‚„ƒ€‚ƒ€‚€‚ƒ‚ƒƒ‚€€€ƒ„‚€€€€€€‚‚€€€€€€~~||Š”Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚†„…ƒ„…„…†…†††…†…ƒƒƒ‚‚€}}}}}}~~}}}}}}|}}|{yyyxx|‚ƒ„…‚„ƒ‚‚ƒ…‡‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚‚ƒ„ƒ‚ƒ‚‚‚€€€€€~Ž“Œ‡ˆ†ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€~}}}~~~€ƒ„‡‡„†††…††‡‡†‡‡ˆ‡‡‡†}€€€‚~}}}}}}}}}}}}||~~~|{yxwxyy€ƒƒƒ„ƒ„„„——ƒƒ„}~‚‚‚ƒ†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ…„„…ƒƒƒƒ‚ƒƒ‚‚‚‚ƒƒ‚‚‘‹ˆˆ‡‰‡††„†……„„ƒ‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€€~}~~€‚………‡†‡‡†‡‡ˆ†‡‡‡‡†‡…~}}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yyy|~ˆ–„ƒƒ„„”“€~~…‹€€€„†‰…„‚‚……‹ƒ‚……††„ƒ…„ƒ„„ƒƒ„ƒ„„„ˆ’Œ‰ˆˆ‰‡‡‡…†…„…„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„ƒ…„~}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|yzz{|ƒ‚ƒ‚€~}~~{ˆ‘||Ž–}‚†Š…ƒƒ„ƒƒ‰~ƒ„……ƒ………„……ƒ„……†„„Ž‘ŒŠŠŒ‰ˆ‰‡………ƒƒƒ‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚€‚€~}}||}}|||}||}|}}}|||{‹‘—Œz{|zyz{|yy}}~€€|{{~~}‚•‘„ˆ}|~‚„||‚„‚€‡ƒ}‚‚‚€ƒƒ„„„„„‚„ƒ„…„‘‘Ž‹ŒŒŽŠ‰‰………ƒƒƒ‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚ƒ…ƒƒ…………ƒƒƒ„‚‚ƒ‚ƒ‚‚€€~~}}}||||||||||||||}|||~~Š‚{z{zxz{{|}{~}~}}}}}|€}†~}‚~~€‚||€‚€‚€~|{Š‚}€~€€‚‚€€€€‹”ŒŒŽŽˆˆ‡………„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ…„††„„€†”ˆ€‚€~~~€|||||||||||||}|||||}|yz{{xxy{{z|‚€~€|~~~}€‚‚€€€‚‘€€~€~~~€}}}{}}}|}||}€€€~€~~‚”’ŒŽŠ…††…„„…ƒ‚ƒ‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚‚„†‡††~ˆ•Š~€€€~€~~~|{{|||||||||~}|{}|||{|||zzy{|z}…ƒƒ~~€~…‚~€~~€…†‚€~~ƒ†}|~€€~}}}}~{|}€}~Œ‘ŽŽ‡„††…„„ƒƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}€‚„††……~€€€~~}€€€}}||}~}||}}}}}|~|}|{}||z{z|}}†„ƒ€€}~}~~‹„‡~}||~‚}}}}|{}|~„ƒ€~~~~}|~}~€~~„’ŒŒŠ†„…„„ƒƒƒƒ‚ƒ‚ƒ‚ƒ‚€€}|||}~{{}w~vx~}|}|}~~‚ƒ€z~~|~~€~~~€€€€~~~~~~}~~}|~}~}}}{|||{{z}€€ƒƒ‚~|||}||ƒ~Œ~|{{}~}~~}{{{}|{{{{€†„‚„ƒ‚€~‚‚‚‚‚€‹Œ‹Šˆ„„„ƒƒƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€€€}€~~~~|‚}~}}}{{}}|z||~€‚€€€}}}|||||}|~{~{{{|||}|{{{{||zz}z~‚~‚„„ƒ‚…†……††‡…„‘‹Š‹‡‡…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~€€‚€~~€€~}ƒ||}}|}}}}{|~~~~~||}||}|}~{|{||||}|}|~|}|{{{|y{|{{}z}~~€€ƒ‡‰‰‰Š‰Š‰…ˆ’Œ‰Š‡……ƒ‚‚ƒ„„ƒ‚‚‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€€~~~}€€€€€ƒ‚€€€€€€€€~|z|}}~}}~~Œ†}}~{{ƒƒ}~~}}|}}}}}}|}|}|}}~|~}}}}|{{z|{||{z{{zzz{~~ƒ…ˆ‡ˆŠ‹‹‹‰Œ‘ŽŠˆ†…„‚‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„„€€€€‚~}~€~{~’Œ|}Š€Œ~~}}}~~}~}|||~}|}|}}}~}}~~|{{{||}|{z{{yzyyy{~ƒƒ„‡‰Šˆ‰ŽŽŒ‰‰…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{}||~~}}‚€€€€‚…ƒ„‚‚‚‚€€ƒ‚€}~€~|‰‚~ƒ‘„„ƒ~}|‡}}~}}|~~|}}|}}~~}~}}}{|}~||{|}zzyyyy{{~~€ƒ‡„ˆŽ‹‹‡…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{}}}}}zx‚€‚‚€€€€€‚‚‚‚†…„‚ƒ€‚„~€}~~}~€€}~„€~~}~}}Š…}~}~~€~}}||~~~}€}}}|}||{|}{{{zzz{{|}}}€ƒ€‰Ž‹Œˆ………„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv}€ƒ‚‚‚‚‚ƒƒƒ‚…†„ƒ€€€‚€„~~€~~€~}~~€€~€€}€~€~|}}|~~~~€}‚€|}€€}{}}}|||{|{{{|{|||}|Š‹‰ˆ††……„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€‚€€€ƒ~~€}€}}~~€€‚€€€€}€€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{|~|}|||{|{{~Š‡‡…†ˆ…„…„‚‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz~}yxtt€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚~~~~€}~€}}}~€€€€€~~€€€€€~}}}~|~~}}„€~}}}~}~~}~|{|z|{z€ˆƒ„„…„„„…ƒ‚‚€€‚‚ƒ‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xyuu}‚ƒƒƒƒƒ…„…ƒƒƒ„ƒƒ„„ƒ€€€~}}~~~~~€}}|}}~€€€€‚€€€ƒ‚€€~€~€€€~~~~~}~~……€€ƒ~€~€~}{z{z|{z‚…€ƒ‚‚‚‚‚ƒ€€‚€€‚‚ƒ‚ƒ„ƒ„‚„‚‚‚‚~€~}~~~~}~}}z{|…„{{syz|pwuvwyutz„„„„ƒ„……†„ƒƒ„„‚ƒƒ‚€€}}}~}~~}~|}}~€€€€€ƒ‚€~€€€€€€€‚‚‚€ƒ‚ƒ‚€€|z|z|{|‚€‚€‚‚€~‚‚ƒƒƒ‚„‚„‚‚€~€€}~~}}}~}}{{z€x|vyy{qtxwvxury……‚„„‚„……†„„‚„ƒƒ€€€|}}~€}~~}|~~~€~€ƒ‚ƒ€€‚€€€€€€€€‚ƒ€„€}‚„€€‚}z{{|||~€|}}€€~}}~‚‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxyzruyyvwwsu†…ƒ…„‚„„…„„„ƒ‚ƒ€~€~€}}}~€~€~~}|€|~€~€‚ƒ€€ƒ„‚€€€€€ƒƒ€ƒ€~‚‚„€€‚‚‚„‚~{{||||}}~}z~}}x~|||~~~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„‚„„…ƒƒƒƒƒ€}~}}}€~~~}}€€~|~~~‚‚ƒ‡…~~€€€€€‚‚€€~€‚‚ƒƒ‚ƒƒ…ƒ}}}|{||yz{z~y{yx~{|{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst†„„†ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€}€€~€}~}~€€|€€~}~~€}€€ƒƒƒ~}~~€€‚€~~€‚€ƒ‚„„†„€~~||||zyvyyzyvyv~|{{{~}{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…„ƒƒƒƒƒ‚‚ƒ‚ƒ‚~~€}}}|~€€€|€€€€|€~~~}~~‚‚~~}~~~~€}€€€~~~~~€‚‚‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{{{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvpxyrx…………ƒ„„ƒ‚„‚‚€‚€~~~~€~}~|~€€€€€€|€~€€€€}~~~}}~€‚~~~~}}~~~|~€~~~‚~~€€~ƒ‚ƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}|{|z{}zzx{|zz{xtxuqrtpxxqy„………ƒ„ƒ‚ƒƒ‚‚‚€€€€}~~€}|~}€€€€€€|€~€~~~}}|€€€€~~~}|~~|}€~}~€‚~€€~‚„‚‚ƒ……‚‚~}|{{||yw|ywxwwx{{{{|…‰}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzz{zxswuqqsoxwq{…†……ƒ…‚ƒƒ‚‚€€€€~~}|~}€‚€€}~€~€€}}|}€€€€~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{||{zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚€€}}~€‚‚}~~~€€‚€€~|~|€€€€€~}~~€€‚€€€€€€€„‚‚€~|}~~z}…~t|}zzzz|yyzz†…wy|||||}{||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚€‚€€€€€€~}€€‚‚‚€~€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€€‚€€~}~{“z|}|{}y{zzxzxy{||}||{||||}}}||}|~}~~~}|z||{|}{yzzzyytuuooqpwst}…†ƒƒ‚ƒ‚€€‚ƒ‚€‚‚€€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€€‚‚€€€}~~|†‰||~{{~yz{z{wwy{|{}||||{}|}}}}|}|~~~~|z|}{|}{yz{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€€‚‚‚€€€€€€}~€}€ƒ‚{~~{|}{z||{‡zxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ‚„„€~‚€€€€‚~€€‚€€€€€€€~}€~€€€€€€€€€€€€€€€€~}~}~~{}|}{||wxuxxy{||}|||||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒ„ƒƒ‚‚‚ƒ€€‚„ƒƒ„ƒ‚ƒ‚€€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€€€€€€€€€€€€€€€€€€€€€€€€‚ƒ‚‚€‚‚€€€‡~~|{}|{}xwvyyz||||}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚‚„„€€ƒ†ƒƒƒ‚„€„ƒ‚‚€€‚‚„‚ƒ‚€€ƒ‚€€€€ƒ€€ƒ‚~‚€€~€€€€€€€‚‚‚ƒ‚‚ƒƒƒ‚€€„}}}|}z}{yvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysrtowqwysw{…‚‚ƒƒƒ„‚ƒ„ƒ€€ƒƒ†ƒƒƒ‚‚„„ƒƒ€€‚„‚‚‚~€€€‚‚ƒ‚€€€€‚‚„€~ƒ€ƒ‚€€‚ƒ‚€‚ƒ‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ‚€‚€}€|z|{{w|yyy{z}~}||||}~~€€€€„„€}€~{{{z{ztpxqytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚ƒ„†„‚ƒƒ‚„‚„ƒƒ€ƒ‚‚‚‚‚€‚€€€‚‚‚‚‚€‚‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚‚„ƒƒ„€‚„‚ƒ‚‚‚‚ƒƒ„ƒ„„„„„…ƒ„‚ƒ‚ƒ€€~||€}|x|yzyz|}|{||}}}||€€€€€‚~€€€€{{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚ƒ†……ƒƒ‚ƒ„‚„…‚‚‚ƒƒ‚‚€€~€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€ƒ‚€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒƒƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{}~|y|zzz}||}z||}}|z{~~~€€€€€€€‚€€}}|}}|vrvxxvtvu}‡‡ƒ‚„…ƒƒ„…„€‚……„„ƒ‚ƒ„„„…ƒ‚‚‚ƒƒƒ‚€‚€}€€‚ƒ‚‚‚‚„‚€‚‚ƒ„‚‚€€ƒ‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz|}€}||z|~}|}}~~€€€€~~€€€€~|}}~~}||xvvw„‡ƒ‚ƒ†ƒƒ„†„‚…†…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„ƒ‚‚ƒƒ‚ƒ‚ƒ‚‚„„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒƒ„„„„„…„ƒƒ„…„…„ƒ‚€}‚€}||{||€}}~€~~}~|||}}~~~€}}~€~~}}}~}}~~€|}€‚‚ƒƒ†ƒ„ƒ†„‚ˆ‡…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~‚ƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒƒ‚‚ƒƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒƒ‚ƒƒƒ„ƒƒƒ„„ƒ„„…„„„…………„ƒƒƒ~„€}}||||~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒƒ…ƒ„ƒ…~‚Š‹……„ƒ‚ƒ…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ„ƒƒ„…„……‡‡†‡…„„…„ƒ~~|~~}€~||~|z|}}}}}~~~€}}|€€~~~~~‚€……„ƒ„„‚„ƒ†€‚……Š‰„„„„……‚‡††„„„„…„„„„ƒ„ƒ‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ„€}uyƒ~„„‚ƒ‚ƒƒ„ƒ„„…ƒ„…†„…†}„y|~ƒ{…ƒ„ƒ€}~}~ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚ƒƒ‚‚†„„„…„ƒ„…ƒ„…„Šˆ………ƒ……„†††ƒ„„………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†spurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚……‚hzrss|€rƒƒƒ}}~}~‚ƒ‚|}€}}||||}|||~}~}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ…ƒ†ˆ††…ƒ†††‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vyy†r„ƒpvxqvtturstvi€nrotvnulwmzsn€‡ym}rsvsvmnwlpylu~|~€}€}€€}}|||}|}~}€€€~|~€€€€€€€€‚ƒ‚‚„…‡††€‚…ƒƒ…‡†ƒ………†‡‡„ƒ††ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoolw}x†pqzprtfu~n{ysoy€}~€{~|€~€€~~€€€~~~€~}€}€€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„†……††ˆ„„†‡ˆˆ†‡„††‹Š…„†‡‡…ƒ…„…„‚…………†……†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„rioyxpkyszozwvvp€~~~z~}|}~}€ƒƒ€‚ƒ„‚‚€}~~~€~~‚€€‚„‡†ƒƒ†„……†‡†…………††ˆ……†…‡‡…†„††‰ˆ…„‰‹ˆ†„†…†…ƒ……„†††††…ƒx‹yrˆz{pp…„x…xyks~y{krƒ‡ƒz|mzyyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozks|nv‚~~}}z}{|}|~}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡……………‡‡ˆ†„†…‡††…„……„……†‰Š‡…„†…††…††„†††††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„…†…†„†„ƒ„„†„„ƒƒ„ƒ…„…„…„†ƒ…†……„„…‡†„„…†……}w…ƒ„„ƒ‚~~{|{~{||}}|~€}€~~~€~~~~}}}~|{|~||‰†…„†††…††…………††‡ˆ†„†…‡………ƒ„…†…„††††…„†„…††††„‡†‡‡†…‡ˆˆˆˆ†„‡…††ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…ƒ‚……†……ƒ…„„„…„†…„……ƒ††…†…„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ}€{{|~{||}~~||~}€~}€~~€}}|€}~~~~||}~{|||{{~ˆ‡„„ˆ††…‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡…††……†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ……ˆ…†‡†‡†‡†‡…‡‡†‡……†‡…††…‚ƒ…††„„ƒ„„ƒ„†„†…………ƒ††…†…„†‡…„„……ƒ„‡†ƒ‚ƒ„ƒ„‚~€|{}~{|{~~}||~}~~}~}}~~|}||~~|}|||}|||~z{{|~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†„…„‡†„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…†‡…‡†‡†‡…ˆˆ‡‡…††‡…††„„„…†……„„„ƒ„…„†††…†„†…††……††…„ƒ„„ƒ„‡ƒ„‚„…ƒ€€€{{~}|||~}|||}}|}|~}|}}||||}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††ƒ…†…†††…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡„†††‡‡‡…‡†ˆˆ‡‡…‡‡‡…†‡„‚„ƒ„†…‡…„„„„„…†††††…‡……‡…†…†…„ƒ„ƒƒ„‡ƒ€‚ƒ„‚‚‚€{}}|||~}|}}|}{||{||}}{{{}|{~}{|}}|}}~}|zz{{||ˆ‡‚††††‡††…ƒ…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡ˆˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡…‡‡††‡‡…‡†ˆˆ‡†…‡†ˆ††‡ƒƒ„„ƒ††‡……„„„…†††††…†‡††ˆ††„†…ƒƒƒƒ‚ƒ†ƒ~‚‚ƒ€ƒ‚|~||}}|}}|~{{{z{|||{{{~{|}{z{~||||}~}{z|z||‰‡ƒ†…†…††…„„……………„ƒ„†„‚„„|€†‚……†……†…„‡‡ˆ‡ˆ†…‰Š‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……ˆƒ„†…ƒ††‡†…„ƒ……†††††…††‡†‡‡…ƒ……ƒ‚‚ƒ…‚ƒ~‚ƒ~~~||}}{}}|~zz{y{|}{{{{~||||z{}||||~}|{{{{||‰‡„†„†„††…„…†…„„ƒ„‚€ƒ†ƒ‚z„Œ{€„…‡†††„„‡ˆ‡†‡……‡‰‡„‡…††ˆ†…‡„†‡ˆ††ˆ‡‡‡†‡ˆ†„†††‡……‡ƒ„…„†††‡……„ƒ……††‡††…†††…††„ƒ„…‚‚€„ƒƒ‚}~ƒ~€||}}~}{}}|}yzzy{|}zz{{}|}||zz}||}|~~€{{{|~}|ˆ‡…†…‡„†„……………ƒƒƒ€‚…‚€}|{„…††„…„„‡‡†††…„†‰†‚†„†††……‡…‡ˆ‰†…ˆ‡‰‡††‡…„†……‡…„‡ƒ„…„ˆ††‡……„‚……†…††‡„…††……†‚ƒƒ…€€€€ƒ€ƒ€|€~~‚€}€||}~}~{~}||yzzyz}}yzz{|{|{{z{}}|}|~~|{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€€ƒ~~~€yz}€ƒƒ…‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ†…ˆ‡‰‡†………ƒ†„…‡ƒ„†„„…„‡†…†…†„‚……†††††„…††„……‚‚ƒ„~€€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|{{{{|}}}|~}|||~|{‡……††††„…„…ƒ…‚€€€€~‚‚}}{‚ƒƒ…†…„ƒƒ†ƒƒ„‚€…‡…‚ƒƒ„„…††‡‡‡……ˆ†‰‡…„„„‚…ƒ„†‚ƒ…„„†„‡†………†ƒ„…„…†…†„„…„…ƒ…„€€‚ƒ~€ƒ|€}}‚}€~~~~~}}{|{zyzzyz{|yzz{{{|z{{{|}}}}€}}||}€}|†ƒ††…††ƒ„ƒ†‚…€€€~‚|~~€€‚‚‚„„ƒ‚‚„€ƒ‚€„…„‚€‚ƒƒ„……‡††„…‡…‡…†‚ƒ‚‚ƒ‚…ƒ…„…†„††‡††…‚„„ƒ„†……ƒ„ƒƒ„‚„„€‚‚}~~~„~{||€}€}~ƒ}~~}}~{~{{zy{zyzz{yzzz{{|z||||~~}|}||}€~€†„……„‡„„ƒ‚†‚ƒ€€~~€}~‚|}~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡†……ƒƒƒƒ„……„ƒƒ‚„ƒƒ€€~}}~~|~ƒ~|~||€~‚~‚|~}}|||{{zzzzy{yzzyzzz{|y{}{{~€}~}}}€€€†„„…„…‚„‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„…ƒ‚ƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚€…ƒ~€~|}~}|~ƒ}{~|}€ƒ}}€~}|||}{{zyzyy{yzzyzz{{{z{}||‚€~€€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌËËËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFK=8765999<>9?<C9;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937676=;>:=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<:<<98:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA>;A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËÊÊÊËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÒÓÔÔÔÔÔÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9>CE?<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÐÑÐÐÐÐÐÑÑÑÑÑÑÑÍÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø×××××ØÙØØØØØØØØÙÙÙÙØ××××××××ÖÖÖÖÖÖÓÒÓÓÓÓÓÔÔÔÔÔÔÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILN@99:4;A<7=9AC=@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌ͖„†††††‡‡‡‡‡‡‚²âÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¸·©§§§§§§§§§§§§¦±¾½½½½½½½¼¼¼¼»¿ÒÒÒÒÒÒÒÓÓÓÒÓÓÓÜãâââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVM<::77>C>8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÎnPSSSSSTTTTTSL óëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§££££££££££££ †„„„„„„„„„„„„‚•¬ªªªªªªª©©©©¨°ÒÒÒÒÒÒÒÒÒÒÒÒÒÑàìëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;?C>6:7>?;<B@8<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÌÎqTXWWWXXXXXXWP¡ñééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤¥¢‰‡‡‡‡‡‡‡‡‡‡‡‡…—­««««««««ªªª©²ÒÒÒÒÒÒÒÒÒÒÒÒÒÑßëêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;?@@8:;8<<<<>::;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÎx^a````aaaa``Z¤îççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©©§ŽŽŽŽŽ‹œ±¯¯¯¯¯¯¯¯¯¯¯®¶ÒÒÒÒÒÒÒÒÒÒÒÒÒÒßéééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB>;=:9;:=<;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÇÅÅÅÅÅÅÅÅÅÅÅÅÄËÐÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÎÎÎÏÎÏÏÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÒÐÐÐÐÐÏÏÏÏÏÏÏÏÎÐÓÒÒÒÒÒÒÒÒÒÒÓÓÒÕÔÔÕÕÕÕÕÕÖÕÖÖÖØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<7@A<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÏÏÏÏÏÏÏÏÏÏÏÓÏÏÎÌÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÎÑÔÏÏÑÔÔÓÎÎÓÓÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖ×××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?89:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÎÓ»ÏÒ­ƒƒ•ÏÒ¤¡ÐÎÎÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<=B>BB@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÎÒµ•›µÊš¼¸™µ³Ÿ¡©ÒÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?><7:>9?D>@98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÏџ ª°Ä¢Œ€Å—•œÈÐÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<<96?B?B:647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÏÑҚ³Àžˆ¬Öº—¡°²ÓÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8E@?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÏÏÖ§™µ»§«›¥²™–¯³ªÕÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<==964:99::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÏÏÕ¥™´Á –§š„“¤ÕÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ×××××××××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:<?>=<9@<<::9?@==<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÐÐÖ¥™²Ö£´«Ÿ ©…™¤ÕÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CFCAA8;?<=;<<7558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÐÐÕ¥š³ÖÉØÁœ€¼­¦˜¯ÖÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF?HHGE@<<>><==<756:969;::;8@?:<<9<>=;;:?9?:;9=>=><;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦ÓÐÕ¥™´É¡ŸŸ™¨–˜›»ÕÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@C;557<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡ÇÒÖ£š³Â¤ª£¡Ã «¤œÑÓÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKL@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÓÑÕµ‚ÃØ©¬×¼ÕÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<<?GEGKH=657:979:;:<=9>99:8;=>>A>=9<<:=>>:=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÑÑÂÔÒÕÁ¿ÖÒÕÅÄÕÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?AELLA>775;8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÒÒÔÒÒÒÔÕÓÓÓÔÔÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEJ=>786977899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9699:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:69896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EIKAALD??;9889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEHIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDI;AA;<886586987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGJB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<BA<;876797799=?A?<:9@?<>B?:8776=?@@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE><HF89757875898;>>=;89A>=@?A>7596;>AB??@@AB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCEEC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELBA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?BGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<<DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGHNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAD?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€iixsg~‰‰xp‚†{w}~…Š½ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€‚wt|„‚}sp€Šx‚yƒÈÞÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsnupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿¼½¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498566:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»ºº¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545659756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjcmgb\XQPQKTJB:IQ?A7<94:565455588686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸¸·······¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µ¶¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸···¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899::;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬¬­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶···¸·¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨¨¨¨§¨©©ª§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸·¶······¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::9:9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥¤¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§¦¥§¨¨¦¥¥¨¯´¶·¶µ´¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©«««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤¤£¢¢£¢¡ŸŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž£¤¡ŸžŸ  œœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=6789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥£¢¡¡¡¡¢£¥§¦¦§¬«¨¦ œ›¡¡ž››šœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¦¦§§§§Ÿ›š›¢ š–—•š›š——˜™šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜˜™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥£¢¥¦¦¥¦§¦¦ ›™›¡ —“’‘—šœš–——˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB?DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥§§¦¦¢žœŸ¡ ™‘’š–—š˜–—–˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;<;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¦¦¥¥¦§¦¥¥§§¦¥£  ¡ Ÿš“¦¯›š™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡¡¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢¢¢¤¥¤¦¦¦¤¤£¢¢¡žš£Š‡›œš›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œŸ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸžŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::78:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸ   ¡¢¦®¤¤¤¤¢¡¡ž››Ÿ [†œ™™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢Ÿ›ž¡¢£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œ››œŸžœœœœŸ   ¡¡¡  ¡  ª´°¢£¢ žœ›šš©pP‹››œ™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥¤¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¢¢¢¡¡ «“œ®  žš™š¢™SZœž›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›š›šš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>99;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤¤¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ ŸžŸ ¡   £¡h—¬Ÿ›š›œªsV_žžžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›šš››š˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9<<>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœœœžž¨th¤£›››œŸ¡kbb‘žžœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:<>9?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››››œ›š§‚l§››œœ¢’ldcŸœžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™™™š¦„vp“š›œ‚jeeŒ œœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›œš™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š›››œœœ™˜™™¦u||ŽšŸ–xf_e¡žœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ››››››œ™˜™™œ•”{œ¢ †Œ`f‘ žŸžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ›››››œš˜™™Ÿ©œŠkm®ª¡g‹zg—Ÿ  Ÿžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_^]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜˜——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜™—¦¥ˆp_j¤”˜Vg{}|œ›žœœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±´­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=:F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œš››œ›˜™š˜˜™›šš—©™gEHt™ƒ…OE`u€”‘’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨ª¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‘‹‘‹Œ‘–­„=:<xŒvnQ95^v‚‡‚‹†‰Š‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜ž—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VQQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹Œ†Š‹‹‰‡„†ƒ~˜£Z^lPy¡–ƒScjFgx‚’†„„…ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹Ž‹‰‰…‚‚~~ŒY˜£o¶¼±¼‚yš}Nu~…Ž‹†”’‹—”—’˜¡–ž–•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¦›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ‚†‹‡ˆ…„ˆˆŠ„‚} xŒÜֱ̳ž¸¼ebra`ˆ‹Ž‹™œ””” ššŸ¢­±®©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPEMISWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‘ŒˆŒ‹‹ˆ’Ššh³É´ÈÔ¯®º§t‹©jXˆ‹Š””˜•œšž¨®²°°µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWMO_^\NUUbQDTM;?9<895875795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš™‘ž¡“—›¡šžœ££“o©›‘¾¶±˜w]ʚU‚‹˜šŒ”š—œ› ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUJTOOJDPK_bXZQ\T`MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ªª©§¢¥¨©«ª©³ ‡y”¬”Œ}yrgœcx¢¤ž›š¤§¤©«®¬¥¤¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdWOYKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®««¬¤¡¢¥©§§©ªŽxWƒ{z€pnksv|}v ©§ ¢¢®¬«ª§­®¨¥¤©©ª©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_VZNRNQOSe\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢™œ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨§¦¨©§©©¤¨¦š¤¦¢¡©ž|hKitnpxjhdjknz„–¤£ ¡Ÿ¡¡¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOXO^ddlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤Ÿ¢¡£§¡¦®¦§§¯„lbK]snowgbce_^jt~Ž›¢¡Ÿ £™–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvxb_\UYQUW[c_s_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?B?:8:>?C@DA:;>=@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯««¬¨¨«¯©¨ª©¢ ¡¨©­°³µ¼²–oe\GVvrs|gadjZZ`cmxŠ™¢¢¡¢™–ž›ŸŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸŸ¡¦¢›—’šš •|wo}yf[[`_Z\V\hdocmiib^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¢ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£ £«ª¨®¶¸¼Áý¯™{ed[@]lnx{ka_g[X`^afpsy“¢¨ž¡š–ž¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¡™˜¥ ¤§ª©¨ª­¬¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxjb[__\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>BE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢ «³ºÆÐÚÕƸ¨–}gbcU=^jlvqrdbcYW\_]]ahjkn{’¥®§¥™¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨¨«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥¡¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxxxc[RYT__amivkphiibZSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶´º±ª®´±°²´µ½Òàáк¥’ƒraY[[O?Wri^[nl^]WYXZZXYY[dr†ºÈ¾·¡§ª¬§«©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš’–””˜“š˜Š‹‡€€|‚xa^YTai`ftotitdidb[LK>:9898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÄÇÃüÃÈÎÔÐÀ£~aUSUXQFI‚nzƒ^VXW\[]ZW`|œ²¼ÀÆÇ···©¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`b_^kcbnxuwnm[bRV\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAA;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–••‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±°§¼¼¾ÅÄÆÉÇÅÆ»ÄÁÅÈÈÅ¿Å­ŠeVXUQIku£¬£OU\_a\]l±Ä¼½®©²·«µ²­³­©®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|~„jfhaklgnurruqg^`\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8BBBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÄ¿ÄÃÆÆÀ±”ÄÈÒ»‹fUVQVf¢®NVWX[g‡³·®°­²¦ªªª«­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|uklndomiqxozjia]gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÄÄĹ´À¶³¾ÆÈ°€ZTSP™±‘GOVYqŽ¦¼°¥­´µ¬¯¥¥£§¤  ¥™ª´±¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyy{wnkihvZgrxsyff^d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÊÆÄÃÄž¸½ÀÂÂánUJ¶…EKZ~¡¢§´²­¬¸µ³¬©£¡­©¬§­Ÿ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuuefijh^jonyxcba`^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÎÏÌÃÇÆÈÉÈÈÉÇÅÉÇÈÇ¿ÄÇÄÄÈËƬs_v_KW–·¹À½¾¹¼º¼º¼¬­¦©»º¹·¿²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqocagvijjtnyl]d[U`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÌÐÍÇÌÉÂÂÇÂËËÈÇÌÉÍÅÅÅÃÆÅÈÌÔ̆ILW ÉÁÈÍÆÄÁÄÇÁ¼¾´±°°Â¾¾ÁÆ¿¾¸¶Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`kjwlifuotc]bTWUSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<9>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÄÇÈÆÒÉÁÃÿ¿¾ÄËÈÊËɼ¼ÈÇÉÍÈÃÈÉÉÅÅÂÃÁÂÆÆÆÊÌ{G…ÎÍÇÌÐŶ¿¿ÀÀº»½µ³³À¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrpfegcjdbkmno^Y]VVNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾƹ»Ãº¸¹¼¾ÁÇÁÆ»¹ÈÈÃÅÄÀÃÁÁÀÄÁ¾½ÁÀ¿ÀÇ¥JŸÒÌÅÉÑÁ¯½½¸¹»»¾·´±¹¾³¼¾±¹µ¸»¶¼´µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfadbaccdjcgc[ZZ]YQOE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶·´´µ¿»½¿¹¾ºº´À¸µ·²®º»·À·¼ÊÏÁ»¿À¼»Ä½ºÀÄ¿½¼¸¼ÀůO™ÍÄÀÁÉ¿°Á¿º·»¾¹µ¸´¸¼´½¸µ´°³¼±··¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|yˆ}qdabchjggiei^VVTYOSLF8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“““˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´´±°µ·µ»Á¸¾¹¿¼¼·´·¯®·µ¹¿»ÁՎ»¿»ÃµºÇ·¶¹»¼¸¹µºÄȪP‘É¿¿»Á¾¹Æ½Â¿¼Å¸¶·´¸¶¶»»¹¶´·ºµ³¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒyqmfefpjekhXYOKKKRJLHD9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’™”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿¾¼²­¯¬±°·¼·»½ÁĹ··¶µ¹¹º»¿¼ÏÅy¬Ì½Ç·¹¸­¶´·¹³µ²ºÅʞRˆÊ¿¿¾½¼¿ÈÃÅžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~‡}knqgqktfbn`\THKKDJCCG?:;8><7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘Ž˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼»À·ª­¤®°¸»²½¾»Ä¶µ¸µ·¿¾Ä¼ÂÄ×®v„½ÈÏÂÀ¸®µµ»½·¹±¾ÃǓXƒÎÿ¾½¼ÇÌÇÇÄǽµµ¶Á½»»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†€rfljnuoxcgb\cQKUHEECGC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?>??FD@A?>:7?@CC?@=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼ªª£°¹½¼²¼¾¼Å¸±¸¹¼ÆÉÊÂÇÉљsv°ÑÑÌÊĵº¿ÄȾ¾´¾À¿‚fxËƾÁ¼¿ÃÌÊÇÅÆÀ¹½¼Ä¿¿¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒ‚tolltlln_c^abNHN?E@?DC;;::;:8;<:9<>::>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´»Åк¾¼Ä¾·¼À¿ÉÏÇÈÊʇuv§ÌÌËÍÊÆÂÃËÎÁ¼¸¼º°}wk¼ÈÄÀÀ¿ÄÀÊÉÃÃÄùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{zˆ{mmx|`qd[^__TI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA??ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸´¼·»»¬Ûþ¶¾À¾¾º¦œª³·ÃÀ¦{y{žÄÆËÈÁÃÀÀÉÊÁ¿»¹±£‘…z¯ÈÅÄ¿ÀÁ¿ËÇÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}‚znsxthp^\_\ZQEEDMIAD=H;;59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘—žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯··²µ³·¹¼»¶»»Å·m®Î½¶¹À¼ª}nhnmt‚—™tz~š¾¿ÆÀ¹À¼¾ÅĽ½¸²®¤§’’ÊÃü½¿¿Ãþ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸··½¹»±¶²ÈÀ»¶´±°·¬³©°­­´·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|wmv{qoj\``YSPAFIGK@ECH<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿš›œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹ÀͲv‚³½¶µÁ¤†iZ^`NS[\puy„£¸·Âº³»·»½¿º»»¯¢¨­ž¤¾Åþ¼¿»»¸¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ°µ´´½º¾ºº»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰{‚zsvvwora_f][UJ=??GG=GCC9:5;99><<::<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Âɧ„x‹¡°µœjfgVY_IIMPTny‰©°·¾¹²µ²¼¹¼¶¹¾µ–ª¼«±w¬ÊÄÀ½¿¹³®²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|quwtwrl`ca\^OIB?=IDFMD@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·¿Æ©‡{vŒ¡˜_SCYUHbjUOEJc¤®¯¶ºµ´²¬¼¹¸µ¸Á½¢¾¯°v§Ë¿¹ºµ®¥¬³±¦°­¨ Ÿ¥­¶µÂ·¶´¥¨ª¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´¶¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wp|ovsnc^gY]]SONA>JB@JJ@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³²­¶º¯­¼³¸¸¿´yˆnNK?eYBOx“hMB^„±µ³µ²´¯¬»º¸¶¹¿ÅwŠ´§žfª¿¸µ²±­­Ÿ¤¦§¤¥œ–™™™Ÿ©®¹¬««Ÿ¥¨¤«®¯§°«¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶¯ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmujl]\kU][PNHDGMBFNF8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹º¶¹»µµ³·¶•Œˆ„|XFAO‡XJJYxŽƒcAT£¹³´²°±­°¹¸¶»·»½’£³®¤t¬°©«­«£¨¡ž—— •’–—˜Ÿ¨®¤£¤ ¢¦¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬ª¯£¤£¡© ›“Ž”’’™–š¤¥ Ÿž§˜•’”™ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wrxhutoeUadW]QOMH@IRDMC=8875:7<>:;=89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯²¼©˜™•hM@SyqPIIKhœ€ZET¯»±¬³¯®¬­¶¶²´µ®©§Ÿš›žŸ¦¨ž ¨©Ÿ¡§–›–—Ž”–—›¤¨  ¢¢¡¥¥££ ž¥ ¤¬¥¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›ª¨««Ÿ¦¢›£œ•Œ“—•–˜Ÿžž›™¦—“’–¢ ¥¢¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦¡ˆxƒ|vzcwln]QiUPOGPMLCPQ@>;>49:5;9=;:9<99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¤¬¨½Âª¥¼gDS›QXIKaJVŽbed‚¯µª²´®ª«¯°²³­¥‘—“Ž— Ÿ¢ œ£¤Ÿž¨”›–—Œ—‘—“˜£ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨¨œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£žžžš—š«¦ª±£¥¨ž œ•“‘‘™–•˜—Ÿ˜œ™›¤™—”•š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’~|uv}nk{dhVRdNJHGOSNKNH<E@<2?859;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜——–¡¨¬®¶·º¹º··»®¨ ¡© ªÆ¿ÊŸOAs˜sPnJLcfut`\bs‘²¯®³µª¦¬«¢›™”‘•–˜˜œŸ¢¢œ¤žš¤———–’‘‘“š—› ¤ªž¡¡ž¦§ª¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¢¥¢š™ž¯¨®²«¥ªª ›˜˜˜•“–š“••š–›——˜¡žœœ–›¡›žš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}wy|eyy`bSVaHIJKSTISQM9?B67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—“’œž¤¨®­¬««¯ª¯©ž—ž¥œ¥ÆƌWSJf¤Zf}or[Qkc\fb`l‘´°°¸¬¦¡œš”—š™Ž‘•‘ŒŽ“™¢œ—£™š—˜™”™˜–›Ÿ¥¦© ¦£ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§¡ £±®²±´ª²®£™œž¡˜››š˜™›”–›–™œ¥¡ š£¡šœ™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ ž ž ¥¡žž¥ ¦™{|vvsh‚le[SZZMQJOOVMSMB7>C78=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’‘œ˜¡ª¢§ ž§¡¥Ÿœ’›¢šŸª£ŒyUirwupcwvXWc`diZZWg­®¬¯§Ÿž¢ –“› ›™—’“Ÿœ¡£›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬©¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½¶¾°¬±®­©ª´±°¨«¨³¶¸³¸­²´¤ ¥ ¬¡¡¢¡ š˜–•Ÿ››˜¥¡ ž£¡ ž›œ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚€}xvjwu^m[RaIRUHFUWJCMG=KH8F<77;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“Ÿ™¨®Ÿ§žœ¡žš™’˜ž›¡¡ ¤o‚p`cXL[RZLLQYRHNNH™¬ª©¤ŸŸ™’’”˜˜––•Œˆ‹Ž•œž—ž™¦Ÿ ¨¥±ª§®£«®¶°´²±®¶¸½¿º­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«®±¹¸¼¯³°µÂ¼·¾³³µ¢¬¢©¨²©«¨§¨š™žšª§ ™§ ŸŸ¨¨¥¤žª¢¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰……~vrmiwmhm\X\CWNJGMGCFM<>L>4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜™ª ±¢·¤°¦Ÿž—˜•™ž›œ£žœ‰bW^e`WMQG=>@CD?>BRx©­©ª¥ŸžŸ¢£žšœ›”“•”ž˜”…š š«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶»»ÀĹ½»¬¯§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¹Â¾¸³»ÆĽü·³ª³­ª³´¯³®ª¯£¬¨¶±­£°¦ £°±®°¤¥¯£¡ š¡¦¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¤ž¦š›¢¤žŸ›››œ‡†|trkkurqhV\QFUHDJPI?EA4FH95<>7;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž  œœ˜šŸ š Ÿ•|_^e`QFD;C?F<>96N~ª³§££¢ ž¥«¦ž˜œ”‘™™•ŒŠ†ˆ†xmˆ ¤¢«¬´¼¶Ã½¾³»ÁÃÂÅÀ¿ÂÆÆÅÃÈÂÀÅÈÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌÌÌÒǾ¿À¾ÇÆ·ÃÊÊÃÁÇ¿º´º»µ»·°¶²ªº²®»¸¿»º«¸­«ª¸»µ¼®®¸£¦£ž¦¥¢£©¦™›Ÿ™š§ª§ ¡¡¤˜”£–”™‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ…~zrkdioxkeY[FKLEDTMECE7:?:549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;?>=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ²²¸§¡¡«ª¡œž¡¡›š}riaWNE>IZ|oaA=\Ž®¬ ™››žž™——˜’——“ŽŒ‚ƒ‚wrqmp¦­®´¹Å»ÍÇ˾ÁÌÍÍÌÇÉÑÌÌÌÇÉÅÆÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÑÓÍÔÐÓÓÌÊÂÅÆÆÊÈÏÀÉÑÌÇÆÈƼÃÁ¿¿¿¶¾³­¿ÀÃÃÇÅÇį¿¹²¸¼Äº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›‹™‰•˜› Ÿ£—žš““‹•…ytsebgrof^ZZCNLDFPIDC@55589B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A?<@?>9;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›¢¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¤¨¬­ª £žœž•if\TID@?K†ž¤˜ƒ ²­£žœŸš˜—”’”–‘Œˆ„ƒˆ‡ƒ€€yqroly¤¶º¹¾ËÁÓÑÓÈÍÎÑÓÑÒÑÐÑÑÍÎÎÐÅÎÔÕØÒ×ÍÆÇÉÌÃÅÊÏÊÓ×Ò×ÒÕÖÓÔÈÌÇÌÍÊÓÍÎÓÍÆÉÊÊÂÆÌÇÉÉƿó³ÈÅËËËÏÇÊ¿¾¿½ÁÆÅÍÌÉÉÀÃÀ®¯³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›–Œ†‘‹€{ruvgcgvjdVWQDNF@IQC>B<:22A<E<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<@?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­³·¬®£ž£¢¡›aSLJDC?CR°Ò½²¯¦œœœ ¤¡š”“•”‰}xqkebhroq{…Š€upnqtp…³Ã¾ÅÑÐ×ÖÕÒÖÍÔÖ×ÔÓÑÓÔÔÓÏÒÄÐÓÖØÕÖÒËÉÎÑËÆÍÑÊÒÕÖÙÖ×Ó×ØÎÒÊÏÑÌÏÐÌÓÐÀÉÈÊÄÌÌÌÏÏÅÇȶÀËÀÒÍÌÐÆÊÉÀÄÃÈÎÍÐÑÏÍËÈ͸·»¨Ÿ¥«§Ÿ˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„}xsvpc`erc]R\IJGAEIJ>;A8=5586;86:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÁűµ¨¡¤¥ ¢¡YI@ADAFQv²¯¦š”—Ÿœš  ž›œš•‰wica__`_^__]alusppolrqu’ÄÈÇÔÖ××ÖÓÖÐÕÔÚÔÔÎÏÕÔÔÑÑÌÑÎÓ×ÖÓÕÐÏÒÓÑÉÓÑÈÐØ×ØÑØÒ×ÙÔÕÌÏÏÊÍÒËÏÑÀÆÃÈÆÏÎÑÑÒÈÌÍÀËÍÆÓÏÌÎÈÄËÇÇÉÌÊÔÔÑÕÏÒÌÓ¹ű¥¨µ®§›¨«¥²¨°³­¬““Žˆ‹Žƒ‹„Ž™“™‚…Œ|zqstmbcim_VP_JJCFCRM@<>43:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><?@=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯­ªª«¥®·¨«·ØÔÕÙÙÑÎп¼Ìɶ¾®¦ª¨¡£«eC8=>DX‚ª¨Ÿ—•—™šœŸ˜œœ’}qecb__a_^a`_``_`emppnkorwwœÌÁÓÕÓØØÖÙÑÒÒ×ÏÓÎËÒÍÕÔÑËÏÍÓÖÒÑÕÍÏÕÕÑÅÑÔÊÐÔÕÖÎÓÑØ××ØËÈÎÄÉÏÌÊÌÀÊÀÉÊÎÎÏËÐÎÎÌÏÏÈÌÐÐËÎËÃÊÇÉÍÊÌÒÓÍÓÒÑÐÐʽȹ°®»¹µ«¶°­¨¸­³¾»±š ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…‰zvopokadnpaW\ZIFFDMXE;@=33<<87855;>@=9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ¤§Ÿ¸¶µµ¬¤¬®¾´°ÀØÒ×ÚÜÖÎÍÊÃÒÏÁÁ±©¬­©¤±zHFB;W¡›•“–›žžžœ“–—”ˆk^^^adb``aa``a^__^\bmroostvvy¤¿ÌÕÑÖÔÓØÖÎÎÓËÎÎÅÎÊÒÒÏÇÎÍÎÔÌÎÒÍË×ÖÐÌÑÔËÌÐÒÓÊÎÑÕÒÕÕÊÀÊÂÅÍÂÈÊÃÌÄÆÉÊËÏËÎÍÐÎÓÌÆÉÐÍÈÇËÅÇÂÆÊÌÍÐÒÇÐÏÎÎÌÐÅÇÁ¸¹½Ãýø²²¾±»Ãõª˜¥¡˜–’••’‹”š‘””•‚‰†yqrkmg``qhYXhVMGLIPQB;C>;68:8::57==@;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?;<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÄÂÁ¿»µ²±ÇøÊÕÖÙÚÛØÌÌÏÈÖÕĵ¯´¨Ÿ­—xlpqyšŒ—•“‘‘•–•‹|eabb`]^aca`__`aa`_][]grrprsqmry¥ÇÓÏËÐÐÓÔÊÅÉÉÆÆ¿ÃÅÏÎÇÅÇÍÊÒÈËÎÍÆÑÒÐÎÌÔÊÇËÎÏÇÇÏÒËÐÏƺĿÆʽÃÈÉÎÅÃÇÀÇÍÈÄÌËÌÏÈÄÄÐÉÆÂÆÉÅ¿ÁÇÌËÌÏÂËÌÉÇËÐÄÅÇ»ÇÃÈÉÂÏÁ½¼¿°ÁÉƹ½ª°²§¥¢œ˜›£™—™‘•˜‰‚xotdk`^fqa[W`GHHGIMTG?J=64355==48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ¼¹ÌÌÆÐÕÕØÚÛØÐÉÏÏÑÓÈ·»»­£¶~hƒ…¤«“–…ƒƒƒ}„„~s_[^^^`^`cdc_]]^_``_[Z\`lrqookloo}¹ÑÈÉÊÏËÍĺÀû»ºº¾ÉÆÂÃÀÃÈÊÉÈÊÈÁÅÌÆÈÊÍÉÄÂËÉÁÁËÐÅËÈ¿¹Â»ÆǾÀÆÏËÄÀûÉÇɼÉÇÅÊÀ¾ÂËÆÅľƽ½ÁÃÅÌÅƼÀÉÃÅÇÒÅÁÉ¿ÊÉÆÈÆÑÃÃÆïÄËÇÃÊ·¿¼º´©¬¤¥˜Ÿ˜¬£¡¦›£ ›•|wstfiZanmZ\XRDLFBGELDFS@54335?<3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ÊÏÑÌÇÂÃÆÍÎÎÌÕÏÕÚØÙÏËÒÍÍÎÈÁµÃ¾±¯¶l^z}¡‘Š’–†z€……vxurp_[[]``bcdded`\\]]_^`[YZ\borokikposÇ½ÊÅËÀÆ°¶º²²³²±Â¼¼¼º¸ÁÁÁľ½¹½¿¹ÄÊÅƽÆÀ¸»ÄÉ¿ÁÉ»·»ºÆÿ¼ÂÎÃƾ¾µÁ½Ä»½Ç»Ãº´½ÆÄÂ÷À¶¶¾¿»Ìý¶ºÈ»¿¾ËÃÁÆÂÅÉÇÉÆÐÆÂÌȲÇÉÃÎÌÀÅÿ½²·°²§¨¨¹°¥­°ª­¬”zvwjdg`hodV^YJFJFHKAFBFJ@9:658854;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÅÂÄÈÎÒÊÊÉÆÍÍÎÑÈÐÆÕÔÕ×ÍÊÎÅÉÅÇÁ¹Å½«®¦`duƒ“‹ˆ‹„x††~„{ttc\\]^``bcbbdeb]\[\^\^]Z[\^hsqmggnpry½ÌÀúÀ¸­°±§ª­¬§¸´¶´³³´»¶½±·°µ¯²»Â¼Áļ¿»µ²º¾À¸È¹´»·Á½¸½ÇÁļµ¯²¶»¿´Å·»µ«¹½¾À½±»¶°·º³Æ¼·¯»¿µ·µÅ¼¾ÃÅÀÄÅÆÇËÅÀÆÆ»ÇËÀÏÉÇÃÆÁ÷ý½¶¹¾Ç¿¬µ»µ·¶Žytxggebkn^V^`FKHHJFBDAEE?<:566633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÍÈÅÈÍÌÐÌÍÈÉÈÊÈÊÄÐÍÒÏÍÅÇÁÆÀ¿º·É¶ª°™[gpŠ…ˆ‰zx~††vw|sh]]]]_`_`da^cec__\[^\]^Z[[]_lpnifjmnr|¤ÇÀ¸¸µ°«¬§ž¢©§žª¬³­ª¬ª´­¶±³©®§¬³»º¶Ã¹ºº±«µ¹»´Âº°À±¾¼»¶¼Ç¹Ã¶­ª¨°²À¶¸½°±§±³µ»¼¬®¶¦®¶®»²±ª¹°®»®»¸»ÀÀ¾ºÃ¿ÆÃÅÀ¼ÆÁÇ˸ÅÇÅ¿ÇÃúÄÆ»ÆÉÌ˳¹Â½»³‰svvki`bliYWW[ALKMJEAC@FA:9:996854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÅÎÒËÃÅÁÄÐÇÍÁÃÆ¿ÄÄÃÃÊÂÉÊ¿À¼Âº³µµÃ®ª°’[j’‡Ž{x}‰…z{„wn^]\\]_`__dcbcdb`_]Z[ZZ]ZZZZ\enohfhiknr­º°µ®¥¤¦¦š ¤ ™œ¥«®¤¨¢«ª¬«°£¦Ÿª­´¶±½¹¯·°¨®¸´³¼¸´¼¯¸¹¶²¼Á²Á®¥¨£«±²³¨½ª«¨«­®µ´¦¨­¡¤¯©²¦¨¨®¦¨·¬±³·ºº»²¼¾¾¾Ä¿µÂÁÇÈ·¾ÀÄ·Äÿ»¿Ä¾ÄÈÌÊ¿¿ÃÀÀ©‡stsji\aodWVXPHYRSKFFE>?@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÐÏÍÃǹ¹ËÁ˾»É¶½Ã¾ºÊ·ÁÃÁ´¶¼¶±¯µ»­¨«’dmˆƒ‡‹€z}~xt~|swe_]\\^_`^_ccab`a_^]\ZXY[[YXZ\_fkfdgehkor…ª¥«¥žœ ¤”¤š—‘¡¢©££Ÿ¥¦§¦­ œ¤¦­²°¶·§±­¨ª´«´º±¶¶®¶¹³°ºº±·¥ ¤Ÿ¦±¨¬©ºª¤§§¨§²­ ¨§Ÿœ¤¦¬ŸŸ§¤ ¡±­­¬²´³´°µ¼¶»ÁÀ²»¾ÃÁ±¹¹Â³Á¾Àµ¸¼½¾¼ÂÇÅÃÄ¿ÀÄ „xqlbf`ko`TY_HNgOTHFKF<=@=:;;826536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;>97776788666;::;9:;<859<:>>@;È´¶½¸ºÀº½¶ ž”¡¦º¶«³³»³ÄÏÉËÃƸ·ÇÀÌ¿¸É·»Å¸³Å¸³¿À¬µ¼²¬¥¯³­¡£‘ir†…†€|xusomjiipi_`]\\\^__acb```a^\[\\XYXXXVX[^_dcbegggkmoˆ©Ÿ••š •š¢˜•Œ¡¢§œ Ÿ¤¥¢§ž›£œ «°­±µ¤©ªª¬¬¤´¸­·°¬³¶¯³µ¯°ªŸžŸ£¢²¥¦ª¹­¢¦¦ ¨­«™  ž™Ÿ¥šš£œœž¯©«¨ª¬­­°²¸¯¸¹º°¶¼»º«³²¹³½´¶±±¶µ¿¶½À¾Ã»º½—„{sk_e^ddXTW^IW\KPGJJGA<??@;?<05535:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»·ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÅÏÈÈÀÆ»»ÃÃϾ¹Ç¸·¾·²Â´±»»¬¹º±¢ž©«§˜žm~…†xrmomkb^aff]]^]]]\]_`abccba_\[[ZZYXXWWWXXXZ^bddfffhikr§œ’““š–š ••›¢¡¨žœ¥§¢¥œ ¡›™¯®®¯²¡¥£®«§¢µ°²²¬©¯³§º³¦¶¡£Ÿ›£¡­£¢ª¶«££¦ž¥¦£–™—™› š—žœ­¡«¨£¤¦­«²³ªµ°²«²¹´¯ª¯²²³·³®©­®²¸±º¶º½À¸³±”†zuf_f^[YVSZUK[QLJEHKIB=?AA@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½¸½¿¶¾¼¿³¥£˜¥±Âµ¶½­´¸ÁÌÈƿŶÁÀÇηÀĽ³¹¹²¿¶±¹»­²´¯Ÿš¤ª ”šxƒ„xoqtqhechdc\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXWVWadecdeddhjv ›’““•–ž–˜“—Ÿ¡œ–¡¡©¤ŸŸ©œ›«§¯°«œ£¤¸ª¡ ®¨¶ª§¨­±¤¸°¤· £œ™™ª§¡›­¹°£¡¤œ¢  “”¡”––›™˜–—œ•Ÿ©ž©¤¢£ªª±­¨´¬ª§­³°¥«®³±°°¯¯§¨¨²®²µ°¼´º¸®£•‚zwe_aVYXSRTKM^LPLGHLKE=@>=B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾·½®§§¢ª»À½À¹®´¸ÁÌÇÅÂýŸÈ̲ÁÂÁ®¼»µ»¼µ¹¹°¯°ªœ™¡©”‘Š‹€€|wqilrtphhedfa\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWWV[bcbbcbbcfi€”‘“‹’“™—œ••›ŸœŸ–  §¦¤§¨  ¦ ª¯¦Ÿ¢£·¨¡¡¢¨³¢¥¨¥°¦±­¬µž¡–•©¢¢”­²±Ÿ££žž˜›“‹¡”‘“˜˜“—˜˜—ž§›§¢¢š¤¥¥«¤¥°§¥£«¬­¦¨®¯¯«¨ªª³¦¦«¯´±¯¼¶±¯¯ ’{xsea\[]XNLQHRaMVPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8847763321./2556;:8;7876<;:;;A8x»»±µ½°»±·¬ž¥¦¬·»¼Áź±¹µÄÉÉÀÃÆÅǶÅijÁ¿Å«··½¶½º»µ²«­¨™˜Ÿ£‹‰t‰ˆ~vncafihfgifil`]\[ZZZZ\]\[\^_\ZZ[YYZ[WUXWTTVURTRU`a_`a_`acdi€‘‘‡’’œ“•–¤™ —œ ¥¢­¦¥¥¤¤£ª«¥šŸ¥±ª ¡ž¥«ž¨¢Ÿ®­©©®­¢¢¢•˜¢›œ«©±œŸ¢ŸŸ—˜“‰ž‘’“–˜˜”œ¡£¤¡¢• ¢¥¦›£«¥¢¤ª£«®¥®²©¦¥¦¦´¦ª¨­³µ´¹º°ª¬žŒsqp`[WVVRFPOHZ\ORJTLSLEGJD8;;=<8667:9;:976977:;:=<<6;<8>598:88659:;<97?<9678452121..1426:8698598989;9@9{µ´¬´»²°«²­¨§¯¹¹³ÀɺµÀ¯ÅÈ̺ÁÊÌȵɼ±½ÃÉ­±¸Áµ¼À¼´µª¬¦•™››ˆrˆƒ{tiijlgjlmkjle]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURSOQY]\\]^^__bdmŒ‚„Ž˜’“’œš¢œ›¡©©«©¬§©¦¤™¥¯¥•š¥¯© œ™›¡ž¯šœ«´ ¦¦Ÿ£¤¡”“›––’©ª­š ¡¡›”Œ™ŽŒ‘Œ’–•ž¢ £œ£•› £¡—¢¨££¨« «¯¤®¸¦£¤£¬­ª¨«¯³·²½µ³«¯˜…tsh[XYSUREXLQ[XMUOQLQRINJC=??A?=75799<<977:79:;<=>;7;;:=67:;8976989:6:=99577570141-+/434988::8::748=8?9~³­§³·¯¨§¯®›©¨¬·¶«¼Ê»¶¿¬ËÆŸÁÎÏȳĺ·»Âȱ­¸¿·¼½»³µ¦© –—˜–‡zt€vwnmhmmmpggifd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUSSNOQYZZZ]\\^_`e}Š€‰}ŠˆŒ–‘—™¢ › «ª¦¯¬¨±¥©š ­¡•–¤¨§˜šž®—™§ª™ ”¥¡Ÿ’‘’‘“•¨«¥š™™žž–ŽŒ‹“†‰ƒ‹’•‘ ž¡¤™–Ÿ•š¡¢ž”›¥¦¨¨¨ ±°¦±½¨ £¬´«®§°µ°¹µÀ±®±«‘~rsbVTVNRJGVPRRLLXNJLORGMKACFDD>A75889;9:7::7<=:;@>:9;9:?759:9876958779;85576761321-*.102877;99;8948;8@8´¬¦±·ª¥¢±«ª§©²°¤¶Æ´¹º³ÊŹºÁËÐʱ¶·¼½Áñ°±·­´´»³´¢£——”ƒ€vkglnqnrkpkdege^ZYZYZZZZZZZ\\]\ZXXXYYWXWUUTRSUSVTRNNNRWXZYYY\\]aj~x}s‡Œ…Žˆ—‰”“˜›˜ž©› «¦¦¬ž¨š¡¦œ“Ÿ£š——…„’›¤•£–––ˆ¢››”ŒŽŠš¥§œ••—›‘’‡”Ž‹Œ€‹’’’ š ¢–”™™•¢¦™™¤¦©¦¡ ´²¨³¸¡œ£·¬ª®¤²²¦µ¼µ«¬±£‰ysn]NQQLODNNNPKFNNJJNNQIMJAHLHHC>958889:;69:68;99><8:>9;?8789:886857688974577820301*)-/12876:999984988A7w¶¦¤·±¥§¤ª¥ ©¦¤³ª¢²Ãµµ²³ÆƶºÃÊÌƳ¬¹½´¸À¯­©°ž¦®º¯­Ÿ™š•”‡{ƒn__frpvqinieghj_XXXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQMMKLSWWVXXXX[]anptn‚†‡ƒŽŠ“‘“¡šœ£¢¤™¥—¢œ•ˆ™šŒsƒ~Ž—–†’š”ŽŽ{™Œ‚‰Š˜ £ž“˜–…Žƒ”~~tŠŽz‡“›šš’–Ž££Ž‰š ¡¤¤›¢´¯¬°­Ÿ™¦¸¦¦±¡°®œ°¼ª©¯ª™ƒwscVMROPMCSNLPMBPQHINSMHJJDKMFKK=749888;;69;7:<9::;79?9>@79:<89764445874312585/0102)(,-02764789::65:87A7x·¡£´©¦¥¨£¦¥¦¦¦³§¥´Á¸°´°ÉÄ·¹ÁÎƽ³¬ºÁ¬­Ã­¨¢¦’¦¶­£ •–’}w~fWV_gfighnciigb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTQMMJHNTSSTUUVY[]jjpk}ƒ{sNXr‚—†œ—‹”‘ ™•”–•—Š€”‰_;Vo|Œ”‰€Œ’Œ††s‹…—y{†“”ƒ•Ž‘ƒ†}“xqp†}Š‘—š™“‹ŠˆŸ˜‡ˆ–žš¡ —§®©­¨¨ž—®³¢¦®™¬«˜¨´£©­£“sn_[NSRWLDTJPMLFNOIELQMKOJIMPFIJ=7599999:7:;:>>8:==7:?8>?589;79675333760.-/344110//((++-3854779<:79;86A9y· £®¡¦¦ª ¦©§£©¯¨§´Â¹°µ°Ç·³½Ï¿¹¯®µÂ§ªÅª£˜ƒ”œ±¢š˜†”‹‡}su]PLQUYZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MNQMKIFHNQQMORTVXZ`lmgy€sPB?•’‘}ˆ•Œ„Š›Ž–•Š’ˆ†•‡y‰`JQnx‹’„~„‹…€m”wuvx„špQˆŠ†|~x”vhw†ˆ~Š‰–‹Ž‘“—Œ„Šˆ•„›‚„’š–ž”¤£¨©¥¤žœ±ª¡¤¤‘¦©–¢ªœ¢¦¨‰vmf^[HQQSMIUMSILKOIHFJNLMTKQQOGJD=768:8:;;8:;8>?99>=8;<6;;478;6775344696/3/.125221/,')**,4833989:99::::?9w¶œ£§Ÿ¡¯¡§¨¥§¨¯¬ªµ¼¶¸¶³Á»¶¨¹È¸¶¨¨µ¶ª²¼§ž–Š”¨–•Š~Žƒ‚}wpoXMKMMNLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMJEDCINOhYOQSTUZn‚ru}ih\T‰”ˆt~†|…Œ“‚’š‹{†€v€xsovqtŽŽz~Š«„zzhv{Žprmx‹’x{€{€vsr’xgu…„„…|•ŠˆŠ‹€„‹€”„|€˜•œ–‘Ÿ©žŸ  ©¥ž˜§¤’  –žŸ¤sha]]JWPRGKXROJLMRJJJLPHLQLRTMFIB<78;99>=:;<98@?::>=7==79937785675251472/2.,./200/-+(().12721987:8775:<;7v®™£¡˜Ÿ´©¯ª¥­«°±ª½´²¼¸¶º´±Ÿ·º²ª¬©¨²¯¢š‘”ŽœŽ‘~v†x|vooiXKHIHGEHHPTTTWWSTUUUVWWWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQQSV^t‚{xfvŒ–˜Ž|gyvx€‰}„˜’q‡|w{ok~­}t‹{†’€|tfv|†lohs|‰Œ‡€myq}qmvqhq~ŽpD‹…‚ƒ…wxzŒ†}Œ{u}Ž’˜‹’š›£–™œšž¡œ–‹¥šŽ—Ž–˜xongc[XXUQJSUTOPNQVKNKOOJROINPLFD<;79;::?=9<:99??;8;=7<9999266856633511224.,,-..-0-+*''*.1362/876966527995y¦— ž–¡¦°¬®«¨©±¯±«¼¸¬»¾¸³¬§›°§¬›–¥©¤¡˜™…’y‰Ž‹Šuq{mupjmjXKFGEA@CDHLLMQRPQSTTTUVVWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNPQTX]eprlˆ§ªÀ~tyb{xo|y‰z}‹†omŒ’ytyjj€‚q–‘‹~–€I’™nhw~‚mjdly…’†lrl|nr|†inps‰…†{~{wptt†‚yyp|ŽŒŠ”ƒ–—˜š’–—™—–Œƒ‰ž’‹’†–€ojoooYVXTRQYORTTRXUMNHMJMOKCINGF@:99;99:><9<;::=>:8:<9?868727565541432/024*+**-.+-*(*(',-1250,5567485HA895w™‘›™šŸ¥¬°£­ª¨µ¯®¬´¿«¼Ã¿¥¢š•¤˜ž„‹”¡¡˜™‘“‹sŽz€†Œ†totkpldljYNDFC@<>>AFFGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_IMOORWZQY\_§‡ašisye~omz‹‰v‚ˆ†tlš’tt|jjMy…“‰„Žg1v‡sl~~ƒtfeu„„…€gilukq€|hqq|n“|t~}qqnvm‚wyujy‰‚ˆ‰ƒ–’’‹‘””Ž—€yˆ—ˆ†Š†€ˆwkkphfXRZWYY[MPUVYXNIHEJJHGC@GECG=998;9:9<:9;:::@<9:<98>787715234533645031.**+),,++)(+'),,226,,4775478iO8;5n’ˆš‘™–£¨­ž±ž§º¯«²°Â±»Ãǚ–”™‹Ž…z„˜”Œ†q‡‚t‡Œ†yprpoodpf_TFIC?<;9:?@ADCEGILOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOPQVLAIQIb¯² q{xl}lq‚‚…z„††yr¡•txsu”‡5q¨Ž¡¡„¢…vp‡|‡|tŒ®‰hgbjnrmp‚uioXupŽ›’wm{}mrnp€{svnbvƒ†€…ŠŠ‰‘‹‘‹‹ŽƒuxŠŽ€~ƒ€}Ž{sqqm`\]^[YX`_RN[ZXWLHJFJG?CABH?CD=;97=;:;;9:99;:?<88=:8;66651121253474531./,,+)*))***)(*)+/3DM2166643<vR7=7b’’ˆ–‘¤§Ÿ¯•¥´©®±®Á²»ÁŖŒ”€ˆ|n’‰ƒŠ‡†u‚„l•ˆˆ{txxlwnwci^JPG>?6449;;;=>@BEHLLLLNPQRTUVWXZXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL7CMRSDJ†v€||v~lvˆˆ|~…ƒŒ~u¢šz~†„™„›œa†ªŸ‹ƒŽzw‰~‰ˆŽs‹—„{]eqtz|wŠmhjbyo…‚zoxu…zptyxkni]v†|‡|‡‡ŽŠ’—ƒ…Œ†}q„„}uw{|‰wpstfg`[[^S[g^WPTX[UGJJDKG?F@DC>AA=;97<;;=<::99;;=>79>9985653244004645554-,)+('''&(())((+++/00Uq=23331E~W4=9\ŒxŠ€”Œ‘œŸ¦‘ ª ±¨¯À²»Åº–Ž‘”‡{†vkŒ‘‚}Š„Œxƒ€s „Š}|p€~zgvkRWL@E211366688:<>AEGFGJKMOQQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMORLKT]YRJh„ˆ{‰y|q|Œz}‰‡~—‡v¡šˆ‡’”¥­ªH†®¯¯‹€“Š‚‹‚„’©‡€˜˜Šœtm|†‡}Žhghyn…‡‚…q„†Gl€wryvhmk_v}‚ˆ‡„‹y”œ‰‹ˆ‘zu‹v|xmpw~€ttrl[^^\ccXge\TOPVYPDLKFNICFCC@@CA=988:::;;:888::?>6;>7595773344236656768;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|}‰…‡‘Ž–—’— ž­¡¦¸¯³½³—’‹˜‹}tp~‰’~}Œ‚’”}†~†¤‡ˆ‚ˆ…x‡ˆ~s„x_cWKB60./23123668:=>?BEGHJMNQSTUTTVUSQOGC?80,#‡[>?84.]–ps£UFIKMMPW`XpY\^i“‡•€„‚…‘“~…ˆ‘š•‚¡¡˜•››¦­“š»±§»Ç苌¡¥”Š‘|qƒžŸ‘œv†…‹‡ihp„t‡„Šq†‚w‡{v…}nvuf”Ž‡ˆˆ‡ˆ‡ «¢–‰Ž—z‚ˆyyogkx{tle^[[^j^bg`ZOKNWRQIPJDNGCJDC@DDA<:87=<:<:88778:==8<=68756623444576867<BB?<8:>CQ^e\G2'&,,--.1(?‹[.310Oƒ_4?;nupfwƒ{€ŒŽŠš›¤¡¬¦«¯°—‘‘„¡”„xwŒ”|~’…’•Š€’›Žƒ€ŒŠ‚‰ƒŠ€mpj]B@4--//..02234778;=?BDHINQRSRSSTRPOHDB<87/9D><<63.l“—MPHILLKNV`cggmu›š’“‹Žšˆ“‹  ’£ª¥£¬“©¶¢¨Á®ǯxº”š|¡ž™„“…‚Ž¢Ÿ“˜’„Š…™‘–lpuŠŒ‚–ŒŽw„qm…Š–‘ƒ…ˆqˆ –†’‰Ž–¤µ©›”¢ƒ‡“ƒ}kjk}‚ƒuc^d`[gl]ll^WKGNRQMLLFIPCDMFBCEFB=997=<:;:987767;:6=:785456344566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYo‚ou†qv’†~—–š”žžœ§ ©–“˜žge¤š~„’‘y’ˆ‘’}Š„˜’‚€€‹Œ‰†‡…‰…xx~gMR>/..,/.-/000212467;?CENPRTPPQSQNPIED>;<:CF?><752<?R5HHHLLMNR^oŠ|s} ›§¥¢™¡—¢”œž¨ž¨«Ÿ¨¬©ª¶—«¿«¶ÈÈ·ÉÑϾ› pi«©Ÿ„“’…œ¡š›™§‘‘ˆ•¢››xz~”˜’¡“——”ž{w•’«²‰—Ÿ|”›’•˜£¢¦¶¯‘™¨‡–ˆlss}}si`^b`bhd`gf\REJKPOIILFFMCHLFGDBGEA:85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Ppt`m}awŽ}{”ŽŽŠŸ’—ž–›ª˜žªBD}‡‰‡˜x‚ŠŽ|Š†Ž‚€‰‹Š„’…ƒ†‰€†v^bP460-1/,.00//..0015>ABMQRSQRSTRNSLEE@<>=GG@A@8662<9;FHGIJNOQYm…w•Š£§ª´½¸¤­¬¬§¨´«°¶²²­»±³½œ³Ã«ºÉ˷ÿ¸¥¢°³¬­ª£‹–˜…¦¦ £—¦™¢«¨¥ˆ…”¤¡ «¡¤©›°‹•£¦·»›¡£°’¢¢£¡«¯¬²µ¢”¤ªˆ™‰’‰•zz~†€ibi]fc^dd^gg_[OCIHSNFHLFJGFFHAKFCFFA;87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLhcWioXz…v“…‡‚›ƒ’Œ’Úȝ–sV—ˆˆœ|†ŒŽŠŠz‡‚‡Žƒ„‹…†ˆ’†‚„‰†ˆ‡‡qna@E64<3/110-,+-1.-4?CAMUQRSUUVUN[PGHD<>>FHCEA8;<5C;=FKIGHQOPW’ „®£³ª²ÀÇê³Å¶¬³¿³¸¾¶¿´Á¶»º£¸Å¨¶Éǵ¾¹µ¨£´­°±›™’šŸˆ§¯«¥”vŸ¤—¡¬²´™–ª®¨®¶»²º¬¯µ¢±«±µ»·µ®´ §¨£§š©¯­²¹·¸§›¶¨Œ¤Ž‘“Ÿ†x‚„wZceWgbbd`af`[UJDDLUQHIJDIGEA@@KDBMG<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AFWQJL[ZQbcWyup”}„†“u…€Œ{¿»£¼‚´”“›„ˆ’‰ˆy†€Œ’Œ‡„Ž‰‡€†ˆ…‰‡‘zxn]V@EM<6:46AB764//6CHCQ[OQUWU\VP_UIKKA@?GKFED;>@7D7?BJJEFVSP^¤­£±´Ã¶¸ÁÌɶ»Ä½³³À¶¸Áµ¾¯·t±³¥ºÄ¤°Æ¹±³±´¨¤µ¶ª± ¢–›¢’¥°®¦­¬§¤˜ ¬´»¢¨²ºµ¼¿Ì¿ÅŽ½³Â·¹·¿·º·¹¬¬°¥°©­½°¼ºÂ¬™º¨“­——ªˆ}ƒ~lXdbYkfjfW\cYVSIGFLQGCHIAHD>?BBL@@MD99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FRLALRWSYUZvjo~Ž„€„nzsx‡b¹¡™¢ˆ””–’”“–’‡†{†•Š€„Šz|‹‡†}Š‚Šƒ•}wzueP\dGEL;Qca[^SF?;HPEZcQRXXZgYT``LSPEA?IJHEEA@C<E6B>HGJLSZT]“®¸µº¸È¿º½ÉÌ»¼À¼·µ»º¶½´º±Æ`u²¤±šž«½ª¥¨««¤¢²µ «§Ÿ•–Ÿ˜Ÿ®¥§¦¥Ÿ£”£§±´§²³½¶Á¾ÓÉÉÓÇÃÅÌÂÊÃÀ¾½¾»¼·´¯¸·¶Ã¹Å½Âǯž¹ª¡«Ž¤¨¶ˆs`cc_Xb`jgRX`VQUIEENK@>GD=JA=B@=F><H@796379>489:57045/26389373426?8@>GKRTSQPOQQPJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKE@IMPRKQ]glkp…slrss‡ÕÀµ™ •˜™‘Ž—’––Ž†‡}†ƒŒ–Š~ƒƒx{‹ƒ‡|‹yŠ‚—~s}zkfpuY]\Pedb`ed][XW\MdmURmm_n_XgdUYUJDBKJHFHHHGAI9D?HKTTV\Z[“¹À¸½·ÆÀ»¹Êʺ¶¹µ¸¹²·µ´®¶¶™du¨œ­p^¢¬œ˜ ¢›¤ž«¥”ŸŸ”Ž–˜—§Ÿ¥Ÿžš™ƒ¤¬¥ª°­¸°½¹ÔÑÎÖÏÉÌÒÌÏÎÊÆ¿¾ÂʽÁ¼ÁÀÄÄÅʾÈ㤻°´¯š«¸»˜{m^a]Z_aZdcP[`SPKCAEFE<@E>AHA@D=:E>=J?37535;=468977022/24169775554D3ELM>51/006:477@IOI;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODQ\Yh_o–’”nlouu‡³¬¡ Ÿ‹™œ™ŒŒ•‘›’…ŠŠ~ˆ‡Œ‹‰|„s{Šƒ…{‰t‚Š†•s{ylmu{hreiligjih`fiilZms–­¤¼ˆ‡g[oh]ZZTHKNOJKPKSQHLAJGJO_^bfia—·Ç°¸²»½µ±ÄƵ°¸°¯»«²±§«·«µ§š§šNšŒŽŸ–‘¦˜¥•Š““‰‰‘‘›¡—š•–‡žš§›¬¯¨°§´´ÔÔÔÖÒËÐÓÕÍÓÏÍÅÂÉоÉÉÊÉÑÇÌÍÂÐÑ·¯Ã¼Ä¹¥µºÂ¢ƒpe^^^YaXZfZQ]WOPBBHEBH;AC>AG??A8;D>@H=46655;:687654/10146278875367C5B8?-0-1349=97,.,1;FK=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYSeVs˜‚hqoyyƒ ªž¥–Œš›—‹•‘šŽ}‰‹„ŠŠ‹‡|„‚pˆ†{‡rƒ’‹Ž}qxulqx~q{nxslipmcjmpxiw|~Ë¿Áߧncxnc[a`JPRUNY^P]\NPNTQUT\nmv‚q–­¸¬´¦¯¶ª¬¼À°«´¦¤¸¦«® «´£Ž±­š—˜Œ‘“‘„Ž›¦‘œ‰ƒ‹„Š‰„‹ƒ”•——“œ‘œ˜™™Ÿž«¬¤§¢¬­ÏÒÕÑÍÌÒÔÔÐÔÑÎÈÃÔÑÇÍÒÓÓ×ÌÑÑÅÒÖÅÀÎÇǨ¾·Îž{pg_d^XaS^ZPQTPOH>@FABE<@B>ED>??:==<<JA45465<888664412/03526768533;=<E=@11+/249>5901022-2DN3)/3.32=N238C}_2A†tD:==I>@CFH<VRMNZu†…Šwlwp}~¡žž¡‹Œ˜““‹Œ’–„y…Š‰‡‘†~{r~€‡z„u…“ˆovrks}{v{sxrj€sripqzyrz¾Ëš~Œ²„vr„vhak]CZZ[VecXdjSX]]`d^cxz~‹˜©£¤¡Ÿ ¨¥ª°¸ª¥³£¡­¡£­¡§±Ÿ‰¦š“’‘‰‘ˆ”‰j”¢Œ™„€…~‘ƒƒ“–­‹••šŽ†’‘ž—§°¡ ¡¥¤¨ÈÎÏÈÂËÑÔÒÔÒÎÓÍÆÖÒÌÔØÖÖØÔ×ÕÉÔÚÍÉ××ÑʬÃÂˌtpebaYUZT\PKGIJJ@;:;DAD<BC>GB>BB;<9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/--;R017/532FD28>nb5=tM99@I<AD?A;PLFKYp€u}hsxr‚‰€•”…‹•‰Šˆ‡€x„”˜ŠŒˆˆ‹ˆ~‚xs{}ƒ‡wz†‘•ƒnwpmuux}t…|yl‡vtn}v„ux|µŒ;A‹Å¥~Œ|ieWICfcecgjdnx[^fhknin€ƒˆ‘‹œ —˜ž££¦±££³Ÿ¡¥ © £±œ†ž’’’ŠŽ‹†ƒ„~œ›Œ‚„…z”~‚©•£Œ‘Š—’‹}—Šš’«³˜šœ¨œ§½Ãƹ¶ÆÎÒÐÒÐËÒËÉÔÎÐÕÚ××ØÔÙØÍØÛÎÉÙÚÑÖ¾Ë˵zxpf^[SWR[VFGJIEE=:7:@@B:GD?DCADB;?;;7DC75655;0689443341014558754449@>DBC<33.6FTWOQJAJF?1*(.BS39254/7K75<`bA<svV87AH:?C><9QECJTknnpbpqt†}—‘‹~‡’ƒ‰†…‰‡|x…––ˆŽƒ‡…†z„yqz{„†uz…Žœy‹p|oozq{qƒ‡€nŽzuw}|‚u~{†‡¯sX©Â¶‘‚pnb=^hrpqpnxvehoruxqzŒ‡Ž“‘›•Ÿ•‡Œ“› ›žªŸ ¬œ¡š˜Ÿ¥žŸ«™‹šŒ‘„}ˆ‡ƒ…‹Ž ™“ˆ„‡~m™y„˜†ˆ“Œ”Œ†|œ‰”®ª”•˜Ÿ™§¯µ½©­¾ÇËÉÉÌËÐÉÃÒÊÔ×Ø×Ø×ÕÛ×ÓÙÛÕÐÚÚÑÖÈÔ˖{}ji\[QTT_HCFIH>A==7:=?;=G=?AAADA>?:86DB755479.566435532323646553457EBDCEB56<FNSM[nfcnskaV>,4LG865434BF4=W_hLux^8;?F<<B<::D?CGRj^mdbfkv€ˆr‘š€z€~‚‚ƒ~ƒ{|„˜‡‹~…†€v‚yn{{‡‚tz’ž vŽu‚tu}t€„oo’…t|€„zv†{ˆ·Å¤Áɸ–šwpeNfczw†¢Šxyv{ƒ{„vm“–”•—ƒ‰Ž–™—–¥œ—Ÿ–ž“‘—£™«•‰Œ‘‚Œ…ˆˆ†‘ž›™‰…Œ†—zˆˆŸ—ˆŠ‹‚}¡Š‘Œ¼¡˜“—™©¦¦®Ÿ¨¶¿ÀÀ¹ÇÊÎÎÅÍÉÑÖÕÕÙÕ×ÛÔÖÙÚÛ×ÛÚÚØÎÜƇ}{ikgaUXVVNLDMB;==<8:<>9=@6=?@=?><9867DA6455=80665547745613855564557HH=DJE7925;H>;::7IP]ZRUXK9T>;95327I8=NYMHxxd5=>C==@:6:>>@EQ_Yea][htzyl‰Œ’wvzŠ|~€~|„z}‚‘‰„…z„‡zu~um|}†~s~’ž‘žƒ‘|†~xŽ}xŠŠn‚š€t™†}ˆ„{}z©ŽÃ¡½‹œ£}‰„}‰r‹Š~s¦šœ˜“…{Žˆ„hGq ¤Œ‹’…‰Š’•š“”–Œ•Ÿœ” ”‘Š~ŽŽ‹„‰’–šžŸ‰Œ”’‘‚‹¥™ˆ„‚…„¥‡‹‹¸˜‘•–¢¨¡ž£¯·ºµ¬ÀÆÊÐÈÇÌÏÓÓÒØÓÕ×À×ØÙÛØÚÚÙÙ×Û¸z{zmkgXb\TPOICLA<<>99::99;=6?>><=9:;;37D@8378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWN<MTHN?96333>C;[X>5YypZ<<A<=>8689?=DRSRX_VXfmmmiŽŠqsyŠ{z|{‡z|{‹†‚}tƒ…yrzsm€~„~w…œ¡š”’€Œˆ˜‡€›’n‡¨…z ‹|‘‚ˆ„›}šŠŒ£¢ ¤® ‹‘‹…‹“†Wr­‹Ÿ«›ƒ˜›Ž\‚¢‘‚ŒŸ“”Œ†ˆŒ’“Œ”””‹Š‡–›•–Š’“…€‹ˆ’ŠŠœ–™¢£‡“– Š‰ˆœƒˆŽƒ‡†¤†Œ³˜’•—¡¡Ÿ™’œ¨²¹¬¦½ÂÇÍÈÆÏÌÐÌÏ×ÐÑÔ®ÖÕØÚØÚÚ×ÖÙٟqvih_^YTXYCAHC?>>:49:;7:;;3;;?=>7;9:1:H>:37=@50677255?65;55858:57735HR7GOK994=EJB>1FCLB98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:;@;BQKKSYPTcbymb~‘ƒomx‹xzz|…{{v…„sp„zuvvt„ƒ…}~’¦¤Ÿ¥¢–Š”—‹Š¨—rŠ±„§’„™“„™Œ¢•Ÿ˜“ˆšž£’©¯Ÿ•Žˆ–Œn·…šÄȲ›¡¥›œ˜–²‘d¤ÍǕŽ†‡‰’“”‰…Š‰…–™›”“†”—„‹™ˆª——££ˆ™Ÿ–šˆŽ‡——Š„Žˆ¥‰“©š—“—™¡™Ÿ™“›£³´¦£¼Á¾ÇÅÅÉÈÉÂËÓÍÍÔ©ÒÑÖÖÖØÚÔÓÚ΃sie`__PKV\BBFC;A=837;<:8=649:<:82?9:2:I:=67BC32:96264>=4;>6949;57944KQ<JQK9A7BGI@64JELF><88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBcFu‚Ž}|m~ˆxz~z‚~vv€‚{lnŠ~y|wx|„‡‹~‹£³¨¤«²¡–§ ¥¤–•®¢ƒ·•’³™¡ ‹¤›¯¢¤˜§—©™­¯¤—••”‹˜š– ÀŽ£É¸«š¢¥­™‘›œ²†…¨¢œ˜…ˆ‰Ž•‹“‡†‡ˆ“˜”Œ‹““†”˜†ƒ‘œt‘™²–—¤¡ˆœš“Š‹—š‰Š–Ž†}Œ™ŸŠœš™“™˜Ÿ” •Ÿ›¡²®£¥·¾³ÅÇĽÃÿÆÎÊÉÒ§ÎÍÓÒÐÖØÒÏØ»s{w^bWbXQIJOEBCD5>:76:?;<7=42669774=5<5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=89567=:JFDGN[\YJga;H„Šz{m…†y|„x€…€}px|}|osŒz}‚{x†‹‰…„’§¼­©²½¯¥®³³¨£¢°¬Ššµž¢¸¥•­¤—©­·¦¤£Ÿ™©˜ª¤¯°©š™œ”•‘˜ —™»»­É i¶¸«°•˜Ÿ¢«’—½£^ª²‚‰Š•‡‘|Ž}ƒ†Ž””ˆ‡’–‹•‹—™’™´–•«ž‹œ”’’Œ˜›Š’ž‹‰•Ÿ¢Ž•Ž˜š“œ˜ž•¢ ”œœ¥¯¨¢¥³¸«ÂÈĵ»½¼ÅÈÈÂÑ¡ÆÉÍÍÄÖÖÐËÓ¢q|j^\U`SQGD?=CAB8?874>F<<6<35345454B3::BM:A;AHB;:@<746<B9?@B874:96>=47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPeHb`cpJ@‹Š~€r†‡|‰u‚Š‚~m}}|pw‡w‡{Œ†Œš«ÂÀ°¾Æ»³´Á¼´¬«³¶Œ¨²®®½«›º¤¨­¹·«¦¦¢¡££ª¯²±ªœ£˜›˜—ž¢¥¥’£¹®¨À»¬­²¹¥¤§}ˆ†œ­½°ƒ‹Œ‹ƒƒ‘z‡Žœˆˆ—‹•—”š–œ§›±š‘«Ž™’Ž•–—‘ ‘ˆ•›¤¬•–”œž”¡ž›™ ¡”šž¨§¤¡¤°³¦ÁÆ𰻶ÅÄþͧÇÃÇüÖÐÍÄʉvud_\b]OKCL@EF>A?B;:4>A==5=6>333241A17@BN>G@CNCA=C=;86CC5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GE?CF\gG`igZ][“ŒŒˆ{‡‹†ƒŒu†Šn~{‚q~z•z’””˜‘“•¨´ÇÉÀÂÌÁúǼº¯«¹»—²¶º³À®¥À¤«°»»ª®«¢¢ž§¬¯µ°ª› ªœ¢œ–Ÿ°´§‹£ººµÁ»«¨œ²¤¤¨”„Ž©ÃĤ‚‹Ž‡ˆ„†•”zƒŒ‘‘¡ŒŒ”‘‰˜ —“™”—¦ ®ŒªœŽ•’‘••Ž•‘¡”†—Ÿ ³Ÿ”›” ¡™¤Ÿš œ ”˜ž§¤¦§¤¯­¥¿Ä®©·µÉþ¶Î²Å¾Ã»³ÑÉÈÁµw{o_Z^lTNIDMKKI@A=CD<5AD;:3=8B332263A05IEM>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBg\Me\fTcj™–‰‹ˆ’†‰y†“r{~w‡‚z¡–¨šš˜»¾ÉÈÊÂÒÉÊÂͼÁ³­»¾§º¿¾¼Ã¸¬Á©¬³»½ª°©¤¥£¬®´­¶µ  ®Ÿ¥¢˜£´½©›¨¼Á£¶¶¯«’¯¬ª«–†š©¦¥‘‚Œ“¥•‰€uŠ’y…‘ž ’Ž”‹”£™—›””£ž©Ÿ‘¥šŒ•–ˆ}•’’£š• ¢œµ¦Ÿ—¥¤£¥Ÿž¦˜ž•—œ¥£©¨¢²­¨»Àį¥³·ÌÀ¹®Ã³»¾Á¹­ÂÂÁÀ™p{c[Y^\MMNJGDCHBBACK:4DH:;4<7E.12352B26SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQF7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>kI_XaZdeVžŽ—Žž’‰Š‰Ÿ’„x…•~ˆŠ€• ™®§£˜Ã¾ÉÄÈÆÓÍÎÍ˼·°º¼´¼Ê¼ÃÁ¶·¼­´À¹¼­¯¨ ©§¶­®©²·šž¬¢§¡«·¸©¥¯¾Ä±½¹³§©³³­®–•¥¬§ ‘Ž’±Å§•|‘•}‡‘™ª™˜“““•“¥ž“™“¡£¢œ˜Ÿ™‹ŒžˆZ——’–¥™f™£Ÿ³¥–£–¬­«§œŸ§—˜–˜•¡¤¨¦ž¶¬©º¼Ãµ¦´¶ËÁ¸ª¶¬³»¸®¨¸º½¸ƒnp\ZVWPGKSMK?AHEDGFG85FM;>7>AJ.32025B55PWN;LFKRLOGGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|hW;=@BFBrFiIRebLF¦”œ–¡—¨–Œƒ‡¥’ˆ‡‚œ„ƒ•‘”Žš¢Ÿ¯¾®¡Ç¾ÆÅÈÇÎÎÎÒʾ»¶±º»¼¾Î¶Ä½·¹·²²µ³¸²«¦œ««¸«©¨°°—£®¤§¤¥´À°ª¬³¾ÂºÀ¹³§¸³·³®•¥­®®¤‹“•¡sÁ™}–™„Ž–š‹±•šš•’“™™¦£• ›–š¨œ›¡ ™‹Œ–`J–œš”š¥—T–°Ÿ¯œŸ¥”¯¯­¦›¡¦”“™™Ž §¢™´©ª³½¼»«°²ÇÀ¸¦««­±±£¡²²´¤rqg^\PRMEQQPQ;HKIFHAC>9KT?A:=EM07544:B34NWO<JKNUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@CAF3>58JKCA=C;4EA:A?>H@5*B52,>c]g:35tde@R7&#3}iX;:BC@=REWRsbWFH«—™Ÿ¡¨®˜—‡‹§–Žˆ’…Ÿˆ„œ—ž ›£¥µÉ´©Æ¼ÃÄÈÊÉÈÌÎǾº³¯¹¸ÀÁ͵ȺÀ¸µº±¯¯²´¦£›ª´´«©¦®¬™¤®¥¥¨¬º¿¨«¶¶¿ÁÀ¿¸³²Â¯·½«£®´¬¸¥ˆ›—¦›v¾ „˜œŽ“™š‹®–¡œ›—•› ¡©ž¨ ššª™¡§ž—‘ƒnv“¢š•¢Ÿ®²£«•©ª˜«®¥¥ ¥ª“’™œ‰•œ¢ž–±§ª«º·½³²®¾¹¶Ÿ£§¨¥¦œœ¬©©ehb`SLMGHNJUL=MDMIJACD<QU<AABDO18=77?B75UXN?HNQXRPQTJQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW;:=..SaMVHe^HF¬”œ¡Ÿ»®˜”ž‹“ª›‘’“‰«‡¢žŒ¤¬”££¶Ç½´Á»ÃÃÈÉÅÂÎȽ¹²¯¹´ÀÂʶƱÁ¼µ»«©­¬¯£¢˜ª´º¦ª§¬ª¨¯§¤««¾¼¨¬¼³¸¾Æ¼·µ¸À°½¿³©µ¶«¾¤¢—‘¢Ÿ¼Ÿ‰š ™—žŽ·Ÿ©œ¥£›œ¡š§¥³¢›¥œ¨ªž™•”š‹—‰¤¢”œ¢Ÿ µ¯¥¦“±«š«­ŸŸ¥¤ª’–• „žŸœ•©¥¢¡´µºµ­¨µ²²žœ¢¦š—•™ª¡žxb_a_LIGHMQIMEFFBRJHADGAVSDH<AGQ1;B7:BF79\YKALPTUSMWRNUJD@JJNO9C?5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-1:h]FDCœpbGE¨—¤žžÃ¬›—¥—™©œ–ššª–•¨¦•­¬™¡ª¶Ä¼¿¸ÁÃÁÈÄ¿ÍÆ»¾¹²°¸³¿ÃȵÀ°¼·¹·§¤««¬¡ šªªÄ¢¥©¬¦ž¬¯¬¢ª¨¿¸¦¬½°··Æ¶µ¹¸¾°¾Á¶´²´¯¾£–£–“›”­Ÿ¡¡¥££Ÿ¾¥©¨¬¡›¦Ÿ½¢˜¤ž¢©«¡–•ž“Ÿ‡…“ž¤ µ¬¦œ–²§™°© ›«Ÿ¡š•Ÿ„Ž¡š›’¥¤š˜¬±¶±ª¥ª­¬œ˜ ¡’Ž•¨Ÿ”ie[b^PJHKOLHECI@=OH@;GIH[ROK=HNU4BF9>HG5Cb[KCNRUWVQXTRUH@8QQPM:G@4CHQSIC;C>GVKC@O>K<06;GF>;FA56?9:?9;15D0-,0Mv\4KZ5,MnW<-=)#zbQ5CKQ9oRF<KxfcXM¢š£›žÅ«¡Ÿ¬­Ÿ’¢ž–¤ §ª¬—¶°£ª³¶Å½À¶À¼É¿Êȶ¸µµ±´´·ÁÆ·¾±¸µº¶ §­ª¬žŸ¥¤Á¥ ©® ¤©­¯¢¦§½¶¥±»·¶µÃ²³·º¾±ÃÀ¸¸®´´´¢œ¤•‘“ ­Ÿ˜¡¨¨«¢šÃ­©ž¬®››ž˜¦ ½¡¤˜«««¦¡™šŸ’ž‰ŽX–ž¦¡ ¸ª§“™·£Ÿ³¢¡œ°˜ š”ž‚ —–¢¤•¦®³«©¢¢¥¥••œ™‹‘“¤Ÿ‰cg\eaMJKKOFEAFK>=IA99JJN]QQI=LW\9FI=DMI8Hc\LCLPSYYVWOZ^IA=WQIK?H@5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+w`S6SZkWsHE6=ue\LOžŸ¡˜žÃ§¥¢³¡œ²§“ª¤Ÿ£Ÿ­©¬»°¨¬µ²ÈÃÁó¾ǼÅʽ°°¶®±µ¯¿Åµº±°º¶­š©±©ªšž¦¡§Â­›¬±œª¢®°©¤§½·¦¶º½¯·Ã­³³Â¿±Æ³º·«´¶­ª¢¥••”£«¡ŸŸ™§«¯¯¯»²¦ ©©™™—’¢¤¸¡¡¤’®¯¬¤¦Ÿ’¡ž•ž‘•š£Ÿ§´§§˜´œ£¯›Ÿœ¯‘ ”˜”š€’¢–Ž ¡“‹¦¬°¥§¢ ž’’š”…‹’œŸ€dh\hfKJLKSBC@IG;;F>89NMU^RSJ>O^^=HPBMLI9Nd]LELRTY[SUO\bHA?ZQAHAKB7FELKN>;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<v]^?[U^fr@8<H–weA4Ÿ¤Ÿ› Â¨£ª±¡£´©–²«¦¢¤²¬®©»²­°´´Æ¿ÄĶÀžÊŶÀɵ«µ©±¸¬ÀÄ´·®­·º¥™«²«ª˜Ÿ¦—­»µ›¨°›­Ÿ®´²§ªº³§º³¸²¸Àª·²Â¼´Å§½®­·µ©§¬¡—–‘¥¤¡¡——¤¯¸­²µ¶ Ÿ¨¤™”•“£ ·£¤¥•®±²¥©¥¢žššš•˜¨Ÿž˜¢ž®²¢¦˜¯™¥¬˜›Ÿ¦’•˜š†–Ÿ”Œœž”‹©©«¢§¡™–Œ™†–‰•Ÿzej]lkOQNNT=BANC;:I?77QO]^RVQAW`\BJSHWKH:Ud]NFON[W[RPQX]GAB[PBG>NC9HGHNP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1\cZ33906p[bH05JpiVCWFŒyfC;¤¤œ¡¥¿¦§¯¯¡©µª¹¯«¤ª´·±°¹¶°·¸¸Å½Ãǽ¼ÄÂÇÁ¹ÁÇÁºª¶¥­»­Á÷¸ª­²¼£•­°­²—¥¨‘ª¹ª §°ªŸ°´³ª©¶¶¬»¬³²¹·¬¹°Á¹½¾¦Â«°¶®©ª«¦˜˜ª¡¡ ‘— °®³«°¹š›©Ÿ™–’—¦ ·©¥¢¢¯±³«±§«Ÿ›  ›ž¥¡—£³°›Ÿ”¦š¡©›–¤ —™‹–™”–—“ˆ›™”Ž©©§ £œ˜›“‡™‹~Œ—†šljmbnnXRQZTACEU@;;H@7:XPd^PWWDY^^MLRO_KJ>Zd^NIQN[UYPKSWZI?DXPDF>N?=IGGQPB=CFBM?:2D?77547?=95E4+75/251.-.,1>*'+=\p=>1.1e[d@1747gY`F(@8l}h\V:‰{cC=¨Ÿœ¡©¼¡ª°ª£±¸©¥µ²«¡¬µ½¯³¸¼º½·¶Á¿ÉĹÅÃÁÀ¹Å¾Á¸¯¶§«·²¼¿¿µª®²¸Ÿ—¬­¨­—¨©Ž§»Ÿ¥­³ž«¢±°³¬ª¶³µ½­¯±µ¬°µ±À¹Ä¶«¼¯±·¬¬©¢±¥ž¤¨Ÿ£–˜Ÿ²ª³©ª³™§›™” ¦¤´®§¢¬¬®±§²¬²©£›Ÿ¨¤ž• ™›¨µ©—™’’Ÿ™Ÿ¡Ÿ’­ š™‡–™Œš“Š–—š—§¦£ ž––—”•…{“„Œ—gmshps_GYfVDCNXDZ9HB5>]Rh\NY]G[^]OMRXdJJC\c`PLMNXWXPJVVWL=EUJEDAM?AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,+%2+*5K1.'_^aV151=`V^8)C3YU\gK5ŒzfL@¤™ ¤¬¶£¬©¥®®¶ª®´¹¦¦°¸Æ·±·¾Áµ´»Å¾ÌŹÃÁºÀºÄ¸Á¹³µ¬ªº·»º¾µ«®±¶˜˜¨«ª«›­««½ž«®±£ªŸ±­³®®¶²¹·ª­®²§µ¯´º¼É²ªµ´±´¯®¦ ³Ÿ™¨¬ ¥••š™±¢­ ¥¯–¡¤™™’¢¥¦²©¡¦±«ªµ¤®°µ¯£˜ž­§›—ž™™¬¸¢—“˜œ¡™˜”­ ž•‚”™Žžš—‘‹”’žš¥££¡™–“’–{Œ‘…{‹ƒ‹”lnyou|aF`jZIHZ[={JGE6AbTiZM\aJ[\ZRRSbaLKE`a`PLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`Va.5(C^Q\.*A/JGP[G3cYTKD™—Ÿ¯¨±©¬¥£®®µ©¶´·£«´·Êº´»º¿¾µ´·ÃÁÍǼĽ·¿ÀÀ¸À½²½®§ºº··Â·¬®²¸•—¦®«§£³ª”¯º¤­²±¦§¢²³±²±µ±·²©®«²§¸¯µ³ÄĶ©´µ«°­©§¢¶Ÿž¦± ¤”›˜”±§›Ÿ©©¢›•—¥¥¤¶§¢°³«§±§­°µ¬¤™¡¬¨œœ›”ª¹œ•ŽŽ‹˜œ¢˜‘˜¨£ —„“—‘žœ˜—–ˆ–—š¨¤¡“–’–w…‘‡|†‚„nqxv|]Kel\JOd\?b{GI8GgWe[M^bMXYWUXTi]POHa]_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANIg27'FaLV%-B.=ELQ<3rkKDC‘˜¤­¤¬­«¦£°²³ª¶°¶Ÿ«µºÈ¹®Á»Ã·³²µÂÃÏÄÀ¾´½ÁÀº¿½³Ä¨ª¹±¶·À½°¬³³ §°­¥¦±¥ž²µ¬«²°¬©¨´º¬´³µ¬´¬©«¨¬©¹­±°Ç¾¸¤¹¯©­­¦§¬°¥££®£©œ›š¯™¢£¢£¬Ÿ£ Ÿ¡©¦¥¸¤«´´¤ª«¨¬®¶®¢£¨ªœ ™š’¤´™‰‡‘£ –Ž•Ÿ¡–”†””ž›™–•‡˜’•™§  “‘Ž‘x~Ž…}}}‡ŠŠrts~~\Rdn^NZg]FD–[G:NmXb[MabNVVVWTYg^QRLdZ[TKGOTSNGIVS\N;P^JBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3Ce;6*HdHJ+:I?3CIS,>k>HIš©ª¡©¯¤§£³´±´µ±±¡«­½Ìº®Á»Æ±´­´ÂÃÑÄÆ¿Á³¾Ã¼À¸¼Å¨­·¬³¸¼Á±¬²­¡¤§­©¨¤±£«±ª¯«±®®­«³»§·±²©²©«¦¥£­º¬ª°Â¹´¬¹¨©¨­©§°¥©¤¢®ª¨¢žœ¢¬•¤—ž˜«¡§¨¡¬¦¢¬«·±± ©¢Ÿª­°¬ž¦§©š£˜™ ¨˜†ƒŽŠ‹Ÿ ŒŽ—ž‘‡ˆ‘•¡–˜–†–““—¥Œ’ŽŠ€ˆ…}w€‡…‡usr‰vl_Y`ncQsr\K<„|F?WuX`YOc\NUVUWP\a_TOOhXWVKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*35>10485(5/*,.30;),,'%234$,2-860)(1<^K0.IgDF8<B05EKX1@”\@MF•–¬§¡©±œ¨©°¶¬¸´®ª¤««½É»±¾·Ã¯°­³ÄÄÎÎÿ¿´ÁÄĺÁ´ÉĬ¯·®²ºÀ¿´®®«¥¨ª°©¦¨²¦´­ª°®­±¯³¬³º¤¸³¬¬­§« ¢ž°·«ª­º¶¤µµ£©¨¬¬ª¬ ¨¦¦±²£¦¥¡¡«–© “š ¦ž£¢ª¤¬¢ž¦±·¬¬¢¥¢š©ª­©œ¡¥¤¤™ š•˜“‚‰… ‹›’Œ…Ž™¤œ“‘›Œ“‘‘”£››š‹Ž‹‹|‡‚‚{u„‚~uw‹¤‡yk^`ngWf‡dN@g’LDbzWbXReUMVUUTO\]aVKNiWVVIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*49?./463)4+*,+.#4.-+&(+79*&6+<-2,&06XZ.0JgAA<<C+:JO^4D†AIHD–‘¯¤¢©¯˜©¨­µ«¶°«¤«ª©¼ÁÀ¸¹³¼µ¦²¯ÄÉËÑ¿Á»¹ÀÀºÁºÂÄ®±µ²´»Á¾³²¯­«¬¨¶ª¥­°«¹®¨°°®±«µª¶µ¦´¶«¬¤©ªœ£³³¨¨¤³´ ¶®¡©¨«¨«¦Ÿ««¨¹¶©©©©¡©Ÿ­›‘¨¡ £¢¦¢ª›¦´®§¥©¢£—¥¦§ªœ¢££ ™˜Ÿ‘Ž˜~‡‡…žžˆ…‹‹‘…‡–£šŽš‘’‘Ž“Ÿ˜™–‹„t‡€xu„€{x~€ˆprggqx\atˆiO]˜VHmyUdVRcOLVTUQOXZbVHPjTVSGPYUI>IHOQPxMNV=<KD?@A<@CUC9AK=5;E13;97*4:=+-341*8**+*,)*(/*&)%3;,$2)2021%/2Rc02?f=NX?C,?LT_/Ik7QE;•¯ ¥ª¬™ª¤­®³´®ª¥¯©©»¾»Á±¯¸­¢µ¯ÉÇÈÐÀ¿½»¼Ã½ºÃÁÀ¿¯±³²¶½¼Á²²³«´©¥µ¨¤­³²¸¯¢­µ±¯±¹ª¸®ª®¶«ªž©« £¡µ­©¡ž¯²¡µªž¨¨ª£ª¡¡¬­¨½¯¬®¬¡§§Ÿ¬™¯¢˜¢ ¨§ž§›˜©°¨¢Ÿ¬¢¡’¡¢¢¦˜š¨¥˜˜˜Š‡”ˆ|†„…¤–†ƒ‚Œ‡‘…†”¡—‰‘“‘•—Š…†xs}txz{tt{j‚ˆ¤vi^elugˆ‹|RWp^KxsTdSQ_MMSZgNMWYeYGSjRQ>BNQaQ:IHLSIqQLS;<I?;<=;@@W<<>H73CB15:93-5::)-31--6)(+-,52#2)',%.;.&1.0-14%,0Mi:38_=ad?F1CP[[+HP;YC4Ž±Ÿ¤¥ª£¥£¬¦´³°©¤°§ª¸¾Á¼°¨¹ª§®°ÉÆÈнÀ¾¹¾¾¼É¼Â¹±°µ²º¼¹À³´»­¹¬£µ¦§¬±¶¸²¦§ºµ­´¼¯»¥­­µ«­œ©¯¤Ÿ¥¬ª§œª²¤´©šª§ª¤©¢¨¨©½«´¯­©£ ®›š²¢–¤›¤¥Ÿ¤š™§ª¥žš©¡›‘› ¤˜–©©‘™™’‹‚…}‚€ˆž‡€~Œˆ’…”›”†“¢Œ“‘‹‘›“•‡‰~€rzy~|hw|{uqr~i†z„ˆd`hcr…{mhy]^VCX{mTaPRYKKMpt]IZ[hZEVgOC>KNDCA9HGKS?jaIQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11&/>KI1%90%,,09/,,+6'17#-/GjI14X=fbAJ7GS`U*=<F\@*Ž’°™ŸŸ©¥£¡ª¤¶²±¤©±§­¹Á½µ°£¹­¨¨°ÃÉÈÌÁ·½Àµ·¿ºÈ¶Ãµ´³µ²½¹º½¶­¹¶¿­¢³¦ª«®µ·´ªº»¨±¿²º ¯´¶©¬ž®±£œ¥§©£œ¤¯¦¯¡Ÿª©§¡©œ£¨ ­»§®±® «¢£­žž¬¦˜Ÿ›¡¢œŸš™¢ª¢š™££•–“ž¡–›–¦¬‹ž‘‘Œ‚Š{š”Œ‰}Œ‡ŒŠ†“˜‘‡”£‰‘‘‡š“ˆ|yl}vyxb{zrpqsxj‚ujƒgchansŽmbjp`oB]ykV^NQQKIMSYVM\^mWDXaO^PHMDF;7HEKO<rhJK9AE;;==;;=J49B<3;G<4?18-78;2(09/,5..=-*L>*49&'.34.0+/4&,:$40AhZ13S=e_DL6KVdN)=3R]=#‘—¬˜Ÿ—§£¡Ÿ§£·¯­¢¯¯©«¹Âº³­Ÿ¹¯«¨´ºÇÊÈ¿·Â¾¯´¾¶Ä¶Ã²°º±²À¶»¾¸©¹¸½ª¤´¦¨ª¯­¸°©™¹¼£­¾´³¡®·µ§¦§°³ ž¤¥§¡¤™ž¬¨¨ž ª®§ ¦—¢¨Ÿ°¸Ÿ£±¯¡«¡­¤›¦¦©šš›Ÿ£•œ›™©¦–šž¨‘˜’˜“™–¡ªš‰‡}‡~‚||¡ŒŒˆy„…Š…‰“šŽ‰•Ÿˆ•‚Œ—‘}„{sp|qst`yxjopqpjsdzlhfdbf‡€`[rjqMN€iXZMQLKHPRQHM\_oTEXZRgOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23/:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%53=fd24M?e]FO=RZgH*?0][5(•›¥˜œ•¬ ž¡¤¡·ª°£´´©©ºÅ¶²® ·¬­­°µÅÇÀ¶¿Â¹°µ¼¶¾»¿¯¬¾°³¿²½Ã¹©»º¸§¨µ¨§«¯«³¯¥™¼¶¤«ºµ®Ÿ±¸¯©¥§¯²œ¡¤ ¤¤¡–›¯¦¡Ÿ£¨¯¡ ¢“£¤¢¶°¡¦°«Ÿ«£¯—›ª¥¨Ÿ˜š¤“š›™œ¥©™››¤””—•œŽ“—¢©¡‰Š†zƒ}ƒŠy—Š‡z‚ˆ„‰…“˜ŒŽ–™ŠŽ–~…—Œz€zpqvnot_xwemlljj„ofrikfi^dt`[kviZJ^\XOOKHHRUG39^^mQEXVYeMHIEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<"8R=*113>D5,-'42*;+139cm74GAf[HTDU]hD.<2dW,2”¡¡—”›ª¤¡¢¡·©® º¸¥¬½Å³°®£µ¯­­®´Ãü³¿º·±³¹·¹·º¯®À³´¹¯¿Á¸¬½ºµ¦¢²©§©²ª­± šÀµ¤§µµ¨ž²¼©§¥©¯¬™£§œ¤¥”˜¡±¥™Ÿ¤¨©œ¢Ÿ’¤Ÿ£¸¨¤§­¦¥¡¨’Ÿ¨¢¡¡™›œ ’š›–Ÿ¡ª›š˜ ”“–™““£¨¤‰‰Ž†y„zƒ…}‰Š‡z„‡‰‰’…–“’‹•“Œ”{‚—Ž‹w~{ltqllsawuiijggo†hhicfij`kcjh\e{c`StT\[SLJGIOS@!*i^jMDWU^`KIGEC.:B<F<6KPD8:D357==895?:;4>8@K=>93)8><:9*6@3.E4(+,?0-N?.+-7,1195,&.5-80576`tA3CDg[KWGU`hB379gP'2¢£‘¤§›žž£µ¬§ªº·§¬ÄÁ¶°¬£µ®§®¯·¿¿¼²Á·°®²¶µ¸¶¶­ª½³®²±½¿¸®¼»±¥Ÿ¶ª¥¥³¨ª­žÀ«¨¥¯²©¬µ»ž¨©«±¥˜ž©¦¤‘™¦­¢˜ž¤©¡›¡œ–Ÿ§¶¥¯ª®¡¡¡” ¦Ÿ¡ š›™œ‘˜œ“¥«¡—–œ”’Œ•—‹˜š© ‘ˆ‰Šˆy…v‚‚ˆ‹‚‰}…ˆ‡†„–•Ž‘‘Œ’{ƒ•Ž†s}}fxokjkguskcgddvcefffjjcksZ_Y]mdaNiXZ`VJGIKMRX>9_liHCUS\[IHFFA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A=-5B37=+*,0B*JK./*+3722(57$+7.72685]yN2>HiZLZJVbf@:3BhH%5š£ŸŒ­¡˜˜Ÿ–¤³±¢±½¶¡±Æ¼º±±¤·¬ª®©¹¼»º­À²®®®¶®²¸³¨«¹±¯®³¶º¶°¸½¬¦žµª  ¯£©®œ¢À ±£®¯­·®µž­®­­¢š§©¥Ÿ•š§¥Ÿ™¥¢¨šŸ›”œ¬¯¥º§®¢¡šš™ž¤š¤ž—ž˜›”™ ’¨•©§š“šš‘‹•™Ž””™©§ŽŠ‰|‚tŠ˜…‡|‰‰……ŠŒŠ’„”œ“’‘–Ž€Œ‚p€~fymhkigqrk\hcctbfhjnlgjjhn]lltpaUcideZIFLMOXQQVaeT@VSYUFHFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24;6#3*)6.55465Z|]19Kj[M[KXdd@A1JfC'4‘¡šŽ°žš“¡™¨²¯Ÿ¸¿¶ ´Â»½¹±¦¶°¨®¥·¸··­»®¬ª«¶ª³¸­¥³µ²®©°·¶±³µº¦©Ÿµ¨ž¨¡¨¬š§¾˜­£®®´µ­¬Ÿ±­¯©¢œ£«¨œ”œ¦¤šª¢¤–šŸœ›£«ª©»Ÿ§¤ ˜™™¡k¢–™œp‚•š£u‘©§ž””žˆ—™€–Š¡x†”Œƒni~vƒql†‹†}„Œ‡p^cag„˜†l‹”’tw‹„~ƒg†€guheW\hsnNPjcgs…g_dfnmj]`aŠƒ„eNKD9FTg^JGPPTUKHR`oteFZQUPFHFC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,+08>G601.*.*/568,#1'214:175Xl16Ok[N\K[fb>G1Qd=*.‹£™†•°›œ“ ›ª­ª£½Å¯©¸Â¸½¼­§¶°¥«£·³²³±¹­©¦¬´¦¯µ¢¨¸¶¶¨§¬·³®´­³¡©ž³ªž¡£›¥¦˜«º•¥¥¯²¶­®¤©®«¬¥¡Ÿœ §§›— ¥¥››§§“ŸŸ˜ž§ª£µ¯£¢¢–———£ˆ Ž’š‡¡‡“œ ¤¥ªž’‘š‘ˆ„rxŽ…ˆ¡vˆŒi—ˆf}rx¡oˆ‡„~Ž}¡  ™€|‡žt‡Žv›Šl‡ƒlheczkqaS…mcli˜qYjpoˆX^i[ll[ˆqnzr…g†„Z^GN?G_MERVVQQRWTg^MWIRSPFGG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82).1<I9/01.*/(-4583%&2115>1<8Xƒu25Rk[N\L\g_=K1Wa70(‹¦–ƒœ«œ™˜Ÿªª§ª¿Ã¯±º½·À¿ª¥·°©­¥²´®¯³·ª©¥°­¥´³œ­µ¶´¦§¨³±­²¨®ª ²¨ £¢™¡¡š­³”£¤¥µ¼¦¬§«ª¬¨¥¡ ˜ ¦£™™¥£¤˜œ¤©–”£œ”“¤¥¦¡·££ £˜•“—’œˆ¯˜”‰©‹—¡›…±€£¬“™”yƒÔ¨€‡•Á›Çyx±¥·—d€Àœ¿y„„y„|‘Êq—¼œÅzrµ¦»{€l–±«°xhkX±®nei¼’¼nhzorØ~Skc¶²r•tš¡ªWOWbPVNFU[XQPRŒ\W\P@\DQNEGJ<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22BE/.32.+/)-/186- /416A1=:Wƒw21Tk\O[M^g\>L1[]41!¦’€§ªŸ—œ¥­²¨±Â½²µÀµ·¾Â«¦³­¬©§®³©¯¶´§§¥´¥§·®œ³²¶ª¥¤§²®®±¦ª§¤±£¢Ÿ–šž®«”ž¢Ÿ³¹£ª©¢­®¥¡›š¢§Ÿ—›§ Ÿ˜ž§§‘œ§š“¡¦¢ °¢ŸŸ£––’—’™…¯kjŠª~gƒ•†­dp”™¥”q®¡¤~x»}k¡v±_j´[¥€fœ‘`f‚zfjxk©d¾rg¦Œu±j|±xt’“cmm§n[„ Ehf‡–Euœ`~h|¤§‚Y_‹«i€–xyj§7J¯\XSld[KNX_\WV;N‰OXW/ITTJDFF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3..53/+/(.0.:5/'$203B/=;U‚v2-Vj\OYL_gY:M5_Y30¢•‚¬§¥ž£¤ª²·¬´½¾°¶Ä²·ºÂ§©°«®©©°®£°º¯£¤­²£¨¸¨ž³²°£¥ ª­¯¬¯¦§Ÿ£¢°›¢›–•–šš¬¥–›¡ž³²¢«œ¢­­ š— ¡¨œ˜£Ÿœ™¡¦¤¢š— Ÿªž¦¦ ›Ÿ¡••‘–‘š…µ›µx…©™µ™v†³›·~“––¨”~l‚¦{‚†ˆ’”’w«gk±[«{‡”t‰q†€ˆ—x‚‚‹˜Œƒ „°vwŸqkkl|‹N¤XHcc™~ch¦`ysuS“‡^P©mcq~‡€bœ.Q¡o[Skh`LK[dX\ZB>±yXXA#MhFCEA@A19>88:84;:9<9:A:E::;6:CB8=?KNG:5:AFB@AD<FD;0201;F,0.940,.(/3,>831/2-D1<<S}n3+Xj\OXM_gX7J8aU50•Ÿ•‡³¦¦ ®©§²¬©»¶Â°»Â­¸¶¿ª¬­­®¦­±©¡®»ª §´¬£«µ¥¦³³§£¢§ª²¨°¨¥žŸŸ¯–Ÿ˜”••—¬¡™™¤¨´®¡©©¨ª›•˜ ¥§šžœ¢Ÿ› £¤£•›ž—™¢©›¥™œœ¢ –“‘““ƒÕ“™¹p°Â~ņ|֔›»|š•¤œ¤{Ž‡¤‚¥‚z¬yV¯zˆ~Ÿj¹Z¹v‡„}¦‚“|˜zªy{±nŽ„t¼…o”P¯§ÅŠQ zc`©bssˆm—ˆ`Sµ´È†€‰|c¤3Bv]PjidP@XgZdaJHNmM[ROYfYCD?E?0=<59;74<;8=:<C:F:;>6:@C;6@OLH<:<DHCBCD<EF81211DC./0483+-).323971#%5*>3==Qwj6*Yi[K]O_fT7G:aQ71%›¢“˜±¨¨¥³ª¥´©¤¼·Á°¹À±µ³º³µ§±°£°²¦Ÿ­µ§š§¹­£¯± ³´° ¤žŸ§©°©´¨¤›ž«—˜—•—•• ©œ™–§­°¨¢Ÿ¬¢¨––›¡¥¡˜¡¡¡¡š¡¢¦›ž¡ž”™›¦ ›§•››Ÿ ˜‘”‘ˆ²nhµq«‡nŽ¦r´sr¶{š—¤‹£‘¡¥~°vƒ‘ÒÒv\®{…¤o›ª¦k‡…}­}—™{±s’y³e–t„žožf”RȋZÂ\Ÿyb_­`vt‡b—ˆ^Yʝo¿uMKµSUÆdTQjcfXAOk`lhPUGI8=VQZWXIC?J<2?;5=<46>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>HI91746@>/.24252-).26,742&60;5:=Pqh9'Wi\BOT_eP5G=aM620¡’¥¯­¤ª¼­¦µ¥§¶»¼²º¿·µ³¹º³¥´´¡±±¢Ÿ«¯¤—¦¹­¤±°œ´¸ª ¦¡©¤²¨¬©¤™›š¨ž•”—˜’’¢§Ÿ–’¥ª°¦¡•“­Ÿ¥’“ ›¤¦Ÿ•š¥¦¡š¢Ÿ­™ ž•›¡œ¥”•™¢ž•˜•‘›…¬{w¨v£Žˆ†©o­Š‚§ƒ˜˜¡‰’šŠ¢“™‰®…‚³\r³R®}ƒ‚¤q×}x…~†™šw¯†Š‘œˆx³ašeš‚”l’Z°XKšu˜yf`­^vw‡h˜ˆk]¯w•žxl5yÈ®²_BTo^g`EPm_pmVUM.echRXQ;AD@L:5?91=<16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK97<46:>/04333.2..18*.32%!03767=Pke>&Vg\@>V_cN6GC`I:99Ÿ”Ÿ¸°—´Á­¨³¨©²º·³¸¿¹·±´»´¤¸³ž³¬Ÿž¨«ž”§µ«¨±±«­´¤›©  ¨¡¶§¦©¢™”¤¡“’›˜‘”¢¥š’¦­¯¦ •™©Ÿ¢Ž‘¡š¨¤ •™¥¨œ¤ž¬œ¡ ”žš ˜™›–—¡ “—¦ž†©}}¥x¡Ž‚ªp­‹§†–Ÿ¡‰——ˆ£‚‘ˆ”ª|€‹xo±Z¨‚‚ˆ ytØvˆt¨Ž›’£|–Ÿ„{²^œd ~ƒ•l’\«[Z“‘hgªdr{k˜‡s]¬Z‰ ŽkoeOJC¡\[Lt]bgM[a_rs_JV6J›“XHE=GFAM35A8.;>05A78@<6=<F?:<6?=B7.HVJEAH6KIN@IK@EN::@4.;>102144+*05/7,&21($$6671<PeeA&Uf[?2U_bL7FI_C2?8¡™™¿«—´Â®¬­©¦´°·±µ¿¹¹±°µº©º´ž¯¤ž¤§§“ª°©¯©µ¬ª¯¡˜¡ ¦¥¤º¢£« –›‘¢ ”“ž™“—žŸ‹¨°¯¦–›¨¦ŸŒ’£—¨ª¦”–©§žž £­£¡ž¢•¡˜ŸŸ’ž—œ•¡•–Ž«œ®mr´r©ŒvŠ§s´xs³€‘¤£’œ‰¤‡w¸oŒ{‹¢jk¶Z …e——i¡¢§m“r´t“˜²j…’ˆ­ku³af¢o‡’j—\­_M¡|‡‘Rs£ly~o˜‡q\¯V<œweTon.\§OcSkebmZc]ap{cTZQ>>mo3CB@?L9!7@6.;@37C58??3;<CDBJFMIF62JTKEBI6IJP?HNCFP=<E50;;010/75,+,426/#00,,289/9N`eD'UdY>/U^aL5FM^81C8¥š›»¡œ²À®®««§·©¸¯µÀµ»°®¸¶ªÁµ¨¨ ›¥¤¡œ‘ª©§µ£²¨¯ª —œ§ ¤«¸£­›–™¥£•Œ š˜œŸ‘“”ª¶°§˜”œ¬©—Œ“¥™¥¬¢‘–ª²£Ÿž¦«°™¡£™¢–Ÿ›–œ—¡’œ©œ”«™‡Ô’š»s°Ã€Ã†~Ֆ›¸xˆ˜Œ˜ŠŒ§ˆz£¶u}wv‚š²`ƒºyÀ|u¸bµŒ‡©}•¬©q{u¼ˆ§ ia¦Ž¯¡~Œt‡ª}¾ns¼t²ƒux‹nšˆqn¤t½^w}[ay¼kZV\jy^jaegbmxoY[YCA@r@CF+5G"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-7B9§›ž¡¼¢—±Ã°­ª«¬±§¸¯¶Ä±¹°­¹®­À±«£¢ž£¡œ›©£ª²¤µ¦­¥ž–™ª™¦¬¹£®˜” ¥Ÿ’Œœ£—›‘•’®¹²¬•—£§§”–¤œ¤¬ž ¨«Ÿšž¨£³ž£¥Ž§¢”¢šœ—•£˜¯ ’”©ž…™µ‘Œ·•x‚“šµwmknsoy„Ž‰tžÁ»½š{²¨p€t‘¹ƒ|††Œ†{Š‡—|¤»¹½œuz´£tv—ut°u™žf†jµtrqw¶Œ^€z}Šhƒymyc‹¬pu…Y[§jEeZTf`c^cQhgqmuBMPLD:ZM?J3;0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITBKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7LT_G'SbW8*O^]=+:VV'>;<§ž ¡¿¥–´Â´¬«¨¬«©º®°Å®´²­¶¦´¸¬©¡¡¥ž ™“«¤­ª¦µ§§Ÿ›– £¬¤¾¦¡ª—”œ¡š‘¡¨¡“˜“—”±µ·­˜¤¤¢Š’’¥›¥ª›•¨¥¥›™ ¨¦¦£©¡‘­ž–£ž———ž°¨”›§¡Žj~i›¥x‡r}šŽtzd‡{½¾Àºo’‚q•‡asjZ^›ŠacˆŽ•k`€•dmwb•k€š•”e^`cqšŠirŒ}…•gj~rtx}~b[wthP\n„}|‹kXlz‚sJJo†pNtLEW]gaLZXgc_O[nuirRODEN;HH=M?2,2A?8/5?C<9;@;=C>RVVWYZ[\\]`aaa`\UG5DFUEJOHFPIIH;8=51:.0;:.0-76=5&"/*2,%;8-7JR_I'S`V4)P_L(3=[O'?2>¨ ¨¡Â£š´¹µ£¬¥®§§µ±«È«°²ª´¢½±±¦ ¢¨œ¢›™™¬¦¯¤¤µ©¥›—•¡›¦­¨¾§¨¦•“›•Ÿ™’—¤©¨‘˜œ¯²¿¬›§ž§¢ˆ“‘©š¨£š›¬ £™™¢§¬¢Ÿ«¢š±›”§ –”Ÿ—±¤—¡¨™œ‘œ¢£˜¥¡šœšš™•gn}qw’—”‘…‹µª†˜•ŽŠŒ˜—‡”•Š„’”‘‰Ž’”˜”˜–š ¡šœ”¡ž‚z¤†lj||€uŠŠq‚xyvv‹€|Škstƒuev}wkozm`c]phMXZfj`WZpznmfSOFS9OYNRO(+:KB635=@A9:C><ENSSTVWXYZ\]`bba_^^[TKCSGKNDGPLOI<:;389,2;820)6IRO8")+/2#4;*7FO[J&R^S10T^:+=8\K,<-@³¡³¡¿¡¤±²· ª¦²§¥°´ªÈ«­°¤´¥À§³ ¤¤œ£•• ª§¬££¶«Ÿ™––Ÿ—­ª¥Áž«¤•’œ——’“¢Ÿž¢§“‘™¨§²Ä¯š«ªŸ—–§ª›œ ¬˜¡š›¡¤¯¦¡¥¨Ÿ®˜—§œ™š žžœ¯ œ¡¦•—’˜“Ÿ •¢˜ Ž–“ŠŠŽ—®|•›‚’‚‹ª¨†™—Š„Ÿˆ{„‡†š’ˆ†Š•›—‘˜£–š“‘žŽf¡³¯…Š„v{’Š}vyzofz‘€‰kuyˆsis{vƒ†‚kudyf`jecdfkYl{pij\SLPD_TF@?>,4@F;45;>A;<?>>HNNOPSUVVXZ\_aca_^^]^]XVJKLBIOMRJ;<:786/2964.(&$-1./)+*7%+<(6CMMD/T]Q05M[17E4\G5<,@´ ¹¯¿¬«®²± «¦±­¢¬³°Ä°ª«¢²­¼£³›Ÿ¦¢¡œ™—§¥©¦¤¥²´ž•”™™°¥®¾ «¢‘š™”‘”¢œ—¨œ„žª«¢³È³Ÿª¤ª––—š¦¨šŸ£ª“žŸ ©¯©¥£«¢®›Ÿ  ˜¤žœŸ¯£˜ž¨“—–›£˜—§œš—e‚’|e~šdylhk{’¤ªješ˜~g†Šeeih{Ž¡kh—‘£wkj‹™£ž™sln{„‡zXe^†‚^m‹‰v\hsww’€‡‚nx‚x€smy„tvˆˆŽƒ|j‡Y^lud]s‰ik|qkc^RNWJdXAJ4>G7?FD71<=?AD;;DGHHILNPRRTW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%/*+'6*$;'/AJ[J/7ZO6)EY/DO1YC;?.=¥Ÿº¼¹¯¬³±ª¥¨­­°¦­­°¼±©¦£­®°ž¬– £¢™™¦«œ­£¥¨©²­ž•£¢¯¥¶¹¥®£ŽŽš¡™“’š ™™¥•{¥­¢¨´Ä¸¤¢§¯ž”ž¢ž£œ£©¨‘ž¡ ª°ª«¤ª ª›§Ÿ§ «•¡›¥°¤—›ª• š‘¤–©—ž~½ƒˆr´r„†­hx¹Ä¸q“¢£z¦™™sª‚|ËÀÀ»qŒ¢ˆ‚Ÿ}–˜‰À½‚—ÂÁ|‚|’šÃÀ}k¥²nŒoÊz›w‘ƒŽvz€yqz‡pw…Œ“ynx”cf_yd`e‚c^thldbXLVIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^__`_^^^^___]\SMPGUNA??=6468276*&%#)*&.+*)109*#>I[L*#BQ/#F[3PY/UAB;/8–£¹Ã´°°À©¨”£¯©°®­¦³´¯©¥¦¦°«Ÿ«˜š¢Ÿœšª§¢¬£¥¨¤¤´¤¢’¦­«¸³§¯¢‘‘™¥’Ÿ¡˜›Ÿ‡§¬¤«­ÀÀ± ©¯©—‘ž¡™¢£©£’ ¡­®©¬§££§¡¦¥­¨‘¤š¨­©›œ©›¬ ••¤• ¢–œΔxz¤y•–›_®^Ž§¢ }§–›t«ƒ€¯^cª{§‡… u—“ˆ³c‚«†¡Ž³j…¯t}—ˆ·aƒ­Y£Ímu{Ú{™p~ˆ’v~e{ˆvvk|ˆn}…‘~mƒarlph`_yd\qhjdf`RTRW]KOC5AHDD8>6;@?A;=8@>??BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5578164('$!',&&/(&+360$7;SL+,-K0';\;L-!P@F4.1­ÂÀ¿µ´°¸—‘¤ª¨­³«¦²¬¬ª£ª¦¯ª §›™¤–œ¢¯Ÿ ž¨§£¥¡Ÿ°¬š•§®¬±ª¨¬ ”’›Ÿ¤’ž¥˜§£ž®¤«°¨¿Ç³¨©±®–’›¡—Ÿ©ªŸ” Ÿœ­¯§«©œ§¨¤¢«’¬²–¥¢ªª£¦¤¡° ’™¦˜Ÿ™“”‘— q…Œ—t„¨‡q±|q¬~¡ž¥žwª‚}­œs­~«‡†Ÿv˜’{|—~ªˆ¢Œ‘Œ~«{‰”Ÿ€{­VœÄzo’Á}•muoŒmeve†oawnro‰Š’ƒm’fpuuqagme_oiingdXS\aYQSC9II@C<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;91478452&# 1' 1' '45-&7=WJ-<'>1)3V@F!G:C1.+°ÔÆƲ´ œ£Ž££¢¬¯¶®¨°¦¨ª¦¬««§¢£™¡” ¥«Ÿ¢¥ ¨¨¢ž°¬—š–©§®¬¨¦©ž—”š£¡‘“ ­›¦£¯¬£¬µª¹Í²­¦­¬–•œ¢˜ž®¬– ™Ÿ©²©ªª›¬«¤£¬›¯±¢¨«®¥˜¥ª¨©±¢’–£¤™“‘„¤j¤u‰z©tz²p‚¦Š™Œqˆ š‡¤`aR«„®ƒ›v­¦††Ÿz™—†{f€£‰¤™†‚£}©‚•‡®_}©U¢’z¢Ÿ€{ïŋr¯³³¹qb©¯ÂthŒŒ˜Žmš”pnyxypmfeeqpf|jc]W`iXXULLQLCCAB;CA@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799664,&$" ('"+-"$.!3-&@DWH,G+56*1PKL# A9D4,'ÃÉÖÕ¿¡™«§¡¯¢ž°´°®©¬¢§¦©ª«©¤¦ ›¤œ¦§§£œ¬š¢¬¡£Ÿ¯¢œ›“«¤µ°¯ ©›–”¦¢š¢¨  ¥œ°¦¤¨±¬¶È²µª«©•‘œ¢˜Ÿ¥³š ”œŸ§¬¬¤®š­ª£¢ª¡³­¡ª³±¡š¨§®®¶¢’–¢¦˜š‘|ªlž„‡u«y|°o‚¤‹‰Ÿ––Ÿ”Ò¸´¸É€²_`”©ƒ£ˆ‡ z˜–šxªÉt™¤•¨©‘“šŒ€œŠšÆÇxf¡‚¥sŸŽ‚}¯]p´b°uK£†m§G‚“dŽž’|q—“€q{u~|o[fjrpek^aYcm\^YINLKEDAB>A<B?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75685/)(%&%$&),4ENPPMFKJVF*L0/=-5OTQ;<F2,$§¤ÀƸ­©³­¬¥¢œ²¸¬ª ¥š¨¥ª«ª§ ¦¥˜ª£Ÿ®«¦ ¬šž©¥§µŸ¢—“©ªµ²¬œ¥œ ”¥¬‘™›§£ ©¦®¡¤§©°µÃ²³ª­¨“ˆ–œ¤š¡£®¦˜¡•˜œ¥¦«›°®¨¦Ÿ¬£·¬¡±¹¯š®¦²²²¤“—§¢™žŽ‚NxšŸzƒ£}ƒ¤„†¦žœž“„¸{|y¹‚~Ìƶx›¡‹Ÿ~š–—Švž˜Š¥˜¤¨°……Ÿ„¬}š”b¥l¤p…}–‚r¬`£sq€š`¼}RUtŽ’£–{~“’‹u{s…q]nnxrjo[d_hnbd]LLQTAIHFI:9K>B108866877-*5==?BDGILNPTVXYZ[\__^]__\ZZZYUSOH@882.,*.+*'&?QTVWWWYXXWUOUF<E3:P[T6?H,- ‹‡™©«¤«¹ª¯ ›¡¬²³¥ž •¥®­®ª§¦¦š£§¡³®¢©§² ˜©¤”¢µ¢¢•—¡©´¹£›¢¢“¡±˜ž›§¥¡¢¯®¤¨¢¶²Ä±­©­©‘‡›§œ¢¤œ¥—ž˜™š¦¤©š¯¢®¥¦˜¯¤»¬¡¶·­´±·°²¦—®Ÿ¢…ÑµÃ·y‡Ž…‘“¦x”¡wŒ ‘„¥Šqª†„´nrj™£œ•Šž|˜™†‡s¯‚¥›¢¦‹“Š•›mp²\¥s“zœl™{™|m©a£qqŸbs²¸hw”¦˜}Œ”x}y‚njyiyrn€u^ednmfg`J[XX<HG@U3@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^__][ZZXURRQF:2230/++(@QRTUTSTVWWXXWUUVTQOQ[U%!2AH$)%“sŠ­¿¿¼º´ž–§¥­µ¡¢™•£¨§®«¬™¦¢Ÿ¦  µ§£©§±£”¬£Ž¤­£ššª´´¤¤œ©‘”—­ŸŸ§¤§œµš¡ª¤¶«Ã°©«©¡Œ„›¡ ¦¢•ššœ˜›™¦¤¦˜¬¨®£¥›­¦½¬”½°¬Ÿ¢¯²¹ª³¦š¨±¢¦—y¨}|°wŠ€¤¥ˆœm²o ‡­|¡Žƒ¨•™€¬‰…®…Ÿ”ª¡¡—†Ÿ€™•€{’~«€š–‹«xŸ‘Š”’z¯]£}¦§d€|—sj¯]¥kp…™]`[Œ m•‘¦™‚•Ž˜{{„˜lnc~tn€z`geqnhghBZa[>KT3U8BBC7$$3+''3, /6674359@CFIKMNQSSSVZ]_a`aaa]][ZXSPONI8052.*,ATVVVTTUUUUTTUTTTVWWXVUUQHFIJ#((½’šƒ©Æ¶Á´Ÿš¬ ­¸¥£Ž›¤£Ÿ°¯ªŸ¤Ÿ­™ž¹ £« ¯©š®¡«¨¤–‰š®±¬¦ž¦š¬——¬¡¡¥¡š¤œ­˜ ¨¦¶©À¯¥©¤Ÿ‹€›šŸ¦ž’”šš”šš¥¤¤š©¬¬¤¥Ÿª¨¾¤–쪢¡«²¹ª®¦Ÿ²­§¨—v¯~‹œ…‡}º®Š˜e°Œe•­}¡ƒ¦•š¬Š„°…¦™¤¡¡‘… [lj³`­{{‚±mgo™˜Œˆ°[}´\¤ƒkÈ¢dŸ€{¼XvµZ²}R®€z¬X€¡n˜¨›‹—‘—˜|zž~eu~b„xt€|ajfqmfefOVd\BU_>J(>:=4!",%2. *1/04579:<ACFHJLNPQRTWZ^`_`ab^_\[XUPNJFC553./@UZXWXWXXWWXWVWWWWXWWXYZZ\\XWWGB;ҟ³²·½º³Á³£›¬¦¤¶¨ ‹š Ÿœ³³©Ÿ£ žµ˜ ´¨ª¬ž¯­ž¬›•¯©¢Žˆ›Ž¯¬¨§¡¦™®’˜¨š¡ž¤Ÿ™££¥™Ÿ£©²©½¯¤¨žœŽ}‹š•  ™‘š›’š—¨Ÿ¡š¨®¨¦¦£¥©»ž Æ¦¤¨¡«´µ¬®¦žº¬««”€©’£¯Ž›€‡¤—˜€¸ÃºƒŽœ“„§–œ‚¬Š‚¯ˆ¦››¥ª‘~սªb£¿½}~£‚ƒ×º¸µ…”“ƒž½¾„k£o«„lœz²°Çƒj«°½¬xw¢¾¼s–Ž§œ›‘˜ž{‚’œ{d~{dŽgy‚{`kekjbPa[Sj\@UaCN)=:4/$%2 $(0496678:>ACFGJKMNNQTW]a\__a^`[\YTQMHC?<A?5=SYXXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ»•³´±¿¹²½²¢®¥¥²¦Œ˜¥¿ª¸²¨¡¿¦§²œž±œº¨Ÿ­¯¥¦””°¬—Œ‚›‘®¥¢¬ £œª —Š£’¦ž§œš¡¨¢™ž¡¬­©¹­¨£š—’{‡™‘¦›“Ž‘˜˜˜“¨š ˜©©¡ª§¡£ª»ž¨Ä¢ ®£ª³´ª¯©Ÿ¹¦­­™suª¤·†d‰ pg­Šmow¤™Ÿu®˜”p‹q•¨£›—®¤rmmlf‹xon‚™qzjqig‰–•˜qii„‡gp†d]ˆbjoY]g~w¦_aqŽ‘nee“¢˜™™‘˜ ~ˆ–wgˆxiŽkyydlcflbKdXJkZ:QeER'K:+# ",)-2.5:4579<?ABDEHKLMOQSV]WZ\``a]][TPLHD=:AB7MXZZYYZYXXYXWWVWY]^^]\\\]^]^][[UW^¨•­³©¹¸²³ª©¡®ž£²©˜’¾²Äɾ¶ªžÀ¬¬£¡¨¬ º£¤®¬­§—®©‹…•–­ž¦ª ££ ‘‹¤’§™¨™–£ª –œ¦¦§°º«¬š›“’{„—¥˜‘‘˜”—•¨•Ÿ˜©£›±¦ž¢«¹Ÿ¯À§¤²¥¬°±ª­ª¦¶¢¬¶•Š ¨¥¶‰–£™‡©š”’©³™›£« ±–¢  ¢œ ¥¡•«§“’Œ‡“œœ•š“˜‘Ž•…¤š—•‹““‹†„}g‰~t‚vt‡‹q§lz”‘“’•¡–š˜£ƒ‰–Žsj‘wq‹xw|zjldcodUaY@j[HcaOY+F=+'!740.!%2(*699469;>?ABDEJKKMPPQXTVY^`ac]^UQJED>9=@ASX[\ZWXXXXXYXXZ[[\^__`^^^__```_YY`¥–©ª¥´¶®®¢°£­Ÿ µ±Ž¬Ç½Å»¹«¢¦ž›¦Ÿ±¨£¶§©µ§©‘˜­¢‹‡‰›¨•¬¤Ÿ˜§žž’”£—¨š¨™”¦¡£š§™¡¶»¨«™š{”‹ ”Š•‘•“—¥Ÿšª œ¶£ž§«·§®Á®£¶¦¯¯°¬¨¨²·Ÿ­»˜‘¥¤¦¶¢’ž§Ÿ©Ÿ’Ÿ£¬¯›¡£°¨¯—£ œ£ªžžœ–«’™¡›”–ª™™™––ž‘‰ •”…’Œ”‹€}f‹…u†uyˆƒsœj…”“‰|‹–’’—”¢“ž˜£…‰šˆ{s—sz‹r|jod^pja[`YncP`dPZ:GGE>2==8/+&+)&&416668:==?AACIJGJKLMSSSUZ``i`eVPJACB:9EMV[^^[Z\[[[\]]__]^__aabaaa`bbbdb\[c—•¤¨¢¯²¬®£©¦­Ÿ§µª¥´¼¯­­¢£šz¢±¤¥±©—›¹§£”™ªœŽ†Š‰œ£®ž¢•§Ÿ ’–˜›®‹©–¨™¨Œ˜©Ÿº¶¤¥™›ˆy‚“‹š“Š•’”’—¢ž¨žŸ¸£€„¯µ¢¯¯u¤½£²ŸwyŸ©°¹”u«£ž‰€ªd\bv Ž¤ž„—}n“³£§­ª£eŸ’sy™–p€˜¨—l¢¨Šeœ¥œ‘—˜–Œ’œ‘†š•ƒ’‡’‰„wjŽ†v†p{†€€ai‡Š”’‹Zu”hhs{¦ššfzšˆ„y™j„‹ƒoy€kqe_vplkh[gebbpS\>NNNSG>@TD91/&4:306678<;>@AAFHBGFIKMTTUY]`hfgWQJ<DG<8UR[`ab`^`_`aa_\]__`aabcdabaaedchd^]f›•¦£ ¯°¬«©¥¨®£¦­¤’–«¶°²§›«¦¬—tŒ°Ÿ¨«§”—¹  œ¤‘‰ˆ›ž¬š¢•§¡Ž–‘ž„u­Žˆ¦š©‘—¤‰œº´§ ™˜‹‰uw“–“Š”‘”Œ“ Ž›¡§™œ²–€Œ›µ³Œ’»§ ~§¢z¢­µ€Ž¥žƒ‹†±ª¯ŒŠ–£šy€‹¬†œ¢§©§‡•…˜w¥›z‡›—§‚‚{œ²zŠ† —™”˜–‚‘——„š™cy‡„Ž‘‹ƒmpŽ‡y€p€…†t†„•‘x–g’t št}™„¢žˆ˜”‹……škŽŽ…lx{qqgdxojlj[ekjet\^ITLQ@E5.ZTU7)!09=>743568;:=>>@DI?JEJKGSX[Y[aahfYQH9EK<>aV^bdfd`aa`bb_]`aabbbcfgcba`edcgcaahœ—£Ÿ¦­®«¨¬Ÿ¨°¦¦©¥™”®È¾±¢—§©¶ž„¬œ§¢ ¾ž™Ÿš |†Ž™˜ˆ¬œ¡•Ÿ ‘“‰†€‘§Œ†¢¤”˜ž†Ÿº²§›’Ž…pu‰•Š”›‹‘Ÿ’—¡¥–ž«‡Ÿ´‰´š­ŠÊ‡ª­ˆ·…Œ¯‚°¬‚©¥˜}¨r{wœ§–h•¤y´ŒŸž¦¨’˜Â«ˆ˜¡rž€š¥}—…•±€¡}¡“ ˜—Ž“›Š˜‘‹|…“†•’‰ƒmr…yq†„|„u„–€Åf©‡£kžƒ£œƒšŽ‡‹šqŽ“…hwt|whhvqhhk^dpmgmXgG]RM2D46Nac7&3<EGD:64658;8>==?BM?NIJLCPZ]\Wa^jm\QE=LM@JdX]cfhgbbbbcc`_babccceiicbbbecafcbbi”—¢Ÿ°§©©¦«Ÿ£·°©ª¦š” £¤«¤—¥«¸£°€¡¨¥ž‰”½™“¡’žy„––‘ˆ«™››™¡…Œw›œž‡ž¤œ–š˜‡£¹®¤šœŒŒ~bm‹“˜Œ‘Ÿ”¡¡™¡§~¡§‡­ –­žœ‘…€ ª­…£©™Œš£u€™”k‚¬uM«x‡œ‘›¨§€©«}ƒ¡{z§iž’kg—†—¶‰ž~n`dYƒ—Œ{dh‹r™}y•l]|–m_Spƒ\_kyƒ`Ye‚}ƒ€—p§ªkƒ£nr¥pŸ… jf m[oŒ}gZ`ƒbWPowfmtskjo^kpmliXiO^XF9A4GD^k4,ICRMN=84859;6@;;>BO>QRLMBJ\]_W^^cv`MD:MOMTb\\ffiibbdbddbab`bdcacikdbddgdbgeach—– ¸ ª¤¦¬‘ ¶»«­¢™˜ ¢¥­®¡®¶£¨“¡  §œšŽ™´™‹ŸŒ•‹u”’Š¦–•˜žž’…†¬¤‡šŠ˜©™š›’ˆ¦±§¢•šˆ‰€inˆˆ‹ŽŠ‹’Œ‘¢Œ”Ÿ œ¡¤“£¡” wœ–§ƒ¡§†¨«ƒ¥xŠ|„š~¢ps”ˆ–{žŒym‡›Œ™›¨š‡{‚¢sv¦fž~w¤_˜z}’s¢n˜·´ºt“‡‚µ¨dÆ¸{p•·‹q€š¤bs¬«`}i³~n|†‚‚‹˜q£lr£tŸ…¤`™³–q}˜Ÿ´ts[ž²ƒjbotvqioXklrrf]i^cLD=D6QAYq3=SG_JR=<395::6D;;@JP?UMNQ@E_^[ZX``|dHC8LWUVcaZefkkbbeadc`ab`dd_`cknccddhdbgfchh”–•£¸™«œ“ ¤·´­­ š¢££¦®œ²®¬“˜ ˜¡¤™š”Ÿ«›‹ˆ’x‹…q€–ŽŠ¡’”—}‰Ž¨ ‡˜ŽŠ‘£”œ›‹©¨¥ž—‡„~k{‡~}ƒ‹‘‰” ƒ—ž  ž‹‰wœ˜¢ŒŸr¡‹‡¨ˆ›¥•¦©}­Œ~z ™z£“xt–ˆœ}•Ÿ†›Ž™›¦†¢d¡|ˆ–›lžhšnš™{€‹§}rht«ƒžƒtªh•š]›…v„hªj€¸f\¨pœ`•Œ^§vu‡‰~žhšu†“’—Ž€Ÿošm§š]¨~x»k~ª[Ž„]³g\nrzxki\qjxyc`fXbBQFO7VCRo5K[Z_OZD@151;;6H?:CHU>YRY]>Db^V`Qac}jEB9N[]YefXfgnmbbe_aa__``ec^bdoq_deekecihgki•œ‰ªµ›§ˆc”š«¹±¯¬ž¦œœ©ŸŸ¯œž±©­—£š¡ ™––¡¤™†‰jˆ€r{—ˆ‹––„‘”˜zŠ„–£Š”†‹ž’‰©£ šŒ‘Š€€i€†x—Œ{‰ŽŽˆ–š”¢Ÿ ¡“˜rhŸŠŸŒp’Œ©‡˜ž¡¦ž¦{°­£¢¸—w£³¢¤€ˆ”y{ªš¢Ž›—ˆ—q¡|…¯µ}kš‘¡x~˜´££«¨„™|›}štªZ]o{–‹xžbL~zz…cy—BLžY¢jr|Žm€ˆ„™u›x†‰±³€›“§w‚ns}•pštk¤]•vHedatq~~nf`liv{debR_W]UW@ZFQhDSW\bX^ID=B8?B:IF8LEXAWR[VDFb\Z`K`m~rEC<U_bZfjVghmobfg^aa\]^ahb_ecvl^egfkdflihki“œ°®™„T^ ¦³¹²²©š¢Œœ«œœª”¢¬¤¢¨ž›™–˜¡–ˆ‡‰w†oy•…‘›‹|‘“–ˆrˆ’¡›s‘ˆ™•¡›…Ž©œš•‹‹Š|ƒl„…q¡Œx†ˆˆ“˜•|“£ ž£ˆ­†}µ„Žžœ{¥–z©•œ‰Ÿ›|§hwm~™t¡sq|ž†™p“ƒ®}¤ƒ¦ž™€£o^¨gu£co¥aœÓ|{™xrsc¢†~£s¤vk³Œ`‚˜‰sª²¨¼wƒm~¾¦©´^œn}q—nr¢r]¤gs¦ah¦m›Ôš}…›pz{˜lœ|x—sn©¤gaezq€„kgfdnuwg`cS\fQQbIWJTaWS[ej\eQFCKMJKBKE8O@QNXSYOSQafejRcwywIFEc]eZhjTihjocjg`c`\]]_hbahe|d^dgdkdjmghlh—›°«T\K~©¯±´¯³£›™…™© ¡¤Ž¥¨ ˜©Šš˜˜“™“’ ˜Ž‡†{p}„h}ƒ”šw‰o†’’l–“|‰’“¥–ƒ«›”’‹…‰zƒv‡€nŸ†w€’†‡™¢—{”£¤šŸ‰³¡¢¶‹z¬§¤®¥p¨€š…€š{¤€¡™†˜rž„£®¯Š—ŒŒ¤•ƒ­¡”v´µµÉ¡s”ŠŸ`—©my•† ›u¡‡w ~’—‹oLf£’p›‡s¤{ztaƒk~ kqd_œq}t—izi³µ´Æ¦s˜~zkœ›«v…›mvx˜j™{u˜rPE}´^jvkyˆfjhbtupnV^TYiPSiJVMYTV]hknVhWNKAJMKHJOAQKPecjmeussy|nu‰{{TPOl^h[kiRjhilglfce`\]\^ibdik{_]dhcjfomeile¡œˆ¯¦„f?“¡²ª®¯µ¢¢€˜ª¢£¥Œ¦§¦‚›—–Ž—œ“Žˆƒyjy‡eƒ˜ yuˆŒi„…’‚Œ…z‹–¦“ƒ˜©˜‘‹‰z€}‹yp¡†y•‡‰– •”¥§œ––„fnxœl¢d|q¥w›˜pg¦€•Šz¤zŸ–ƒ—ržvŠ”–¹nŠ¢b}™¡•ˆmriªku mn¦_ši‹h–‡š•u¢€}š`Œ†uoˆbh ež~i›uocfˆ‚mr¢Z_[b¡m]‰Œn{~srd¥mw¢dg§h™sŒ™p¢oU‰o _f¨T‹^T˜nmskr‚mpikyskoRYWWgZTmJYO]IXiisjYkVQREV\LXSaUik_wt{}p}|rƒ{sv€„v^QrbgbpgPjhhklnhdg_]^]`kcjivu]\cicjjslfkmcœ¤˜¦zetm‹§®£©°±¦Ÿ‹€˜«Ÿ¦£¡›¢¢€–™“Žš‹˜ŽŠ{†q€ˆh‹‹|˜œst‰}{d‚‡•Š‰–™‚|ˆ‡—¨‘¢¬‘†Š‚Š~€€Žsi¥„}†”ˆ˜ Žˆ“ª¦‰¦x•›~¥ˆ–Œ²˜ž‚¯—Ÿ¥w”†x©s¥„šn¤¢Œ’„Œƒ»n}¥¯ƒ†††“•œŸ|¥zr¨• –fž~o«c–Š•’x¨l©¢‰vˆƒwª‘¦‡j‘°kv³Œ©kŠ†mmŸž’•`~«‹ªv~Œ¥žvŸ}„¤• j›ˆw¬gž­Œ¶tw¾¤“Yƒ¦«aurtq|tqcj~nhlSW[Vab]kM]R]J^mnv`[qY\`[ftenorbqt`wz~yryƒs„{{Œ‚€vbxdcmsdRkgholrjfia`^\bkbmlzo\\bibljwmglnb•¥ª€ž¤–©ª¨¦®¤™‰ƒ˜«šŸ¥Š›¥©…Œš‡œ‘…’Œt†zˆ„p…~˜”tt…r’ƒm‹’‡†“Ž}{‚†™¦Ž¦¦ŽŽŠ…”v‚‡’ol‹©€ƒ‹”Ž‰œŸ‰Œ”ª¢Ÿ€u”—ˆ~y”®£›q…xŠƒ~{r§Œq}}z—–›„Žx{~~‡”•“Šv˜Ÿ ƒ{}‰kŒ…[yyrzphn~’‰qu”“q†„‚eŒ^‹wtr”uoynn‡m„…^vhxŽe€€…©›}t|–j‰ˆpv}†vnmgŒsy{˜x…\kXyinxrroxxp]l†nigV[`W\fkdVbU_Q_pxxlkvfjkkv}qrusaoubt{xuzƒu€y‹…ƒ}{mldxn^Wnghukxjije\`Zcjemqtn[[bldllynhloa”¸¨¦‹¡¢š¦¤˜¥œ«¢¡„„˜¬’ž¡‰›§š©˜ƒ›‹–“‡ŽŠ‰rƒ|}~…{˜trƒp–…{}’‹††…y~€‡š¥Ž|§¡‹†…”ƒ†Ž˜wr…©…Ž‘ˆžžˆŒ›¨ŸŸªƒ‰Ž•š~~‰–­¨’¦woœ‚y‘n~¨…p}•qkp}ŸŒ“ŽŒhm]ƒ‹Œœ›žŽs•‹ˆqtk‚vtYrn†‘}~Œj]jd{…„‰€`ixzš{‚Šu…‚gwŠ†kapqv^rŠˆ¦•…eŒƒnw‹„q†zqghe{ƒz–[\jgnv[{yxunss‚f\mŠkkbZZ_ZYlq\_aZ_]ft~ztptckkk|}s|xudmuhm|~vz|{zz€€~o†Š„{}s~ysiT\qiluougkhd]aXkhlkqrmW[enlgsyohjm`‹‹ª°¡£¡šž—ž˜¨£¢~ƒ™­ •ˆœ¢‘¥•{˜…}’™‰ˆ†‡Šs}€Œv…‹‚…—Šqo€r˜†„~“„ƒ†Šz…Œœ¡‘‚¦¢ˆxŽ˜ˆ”‹‹œ—…ƒz¬‚‘—™”Šž‡ˆ¡«ž¡¡£‹ˆ“›œ£™–ª¡§¦ ’›‡•{wƒ§~’‘’“œ²¦›•ž²’—„¥ŒŒ•›Ÿ‰›‚ˆ‘Šk|Žwxe‚†‹|‰„‡‹ˆˆ€„„w|yt™ ˆ†‰žŠ„”~}Š€€uos„‚~w††Š¦ƒ…‡ƒŒ}ˆŒŠ‘„ymƒ„}z™jrhatŠp}zwwpwt]^o†hn_^Z]]ThrVc\\blhu||sopdkki€|ny€rjpplg{r‚€x~…{m‚Œ†|yx{}zƒyNdvjrmpzekecb`[tfpfrqmU]ltmiyzqgikdŒ‡¹ž–¢¡˜”˜˜”˜¤ ž{€š«ŽŸ† œ‹ž–}y”ƒ{Ž™‰†„„†nx€sˆ~‰”„mk~z—‡„ƒ€†„†}‡…Žœž“‡¬Ÿ„r‹†’‘‹‘}{ª„’˜–œ–‡†›¦Ÿ¡š†‚‘š™˜š¦Ÿ¥–‰u{†ƒ¤z|Ž‘†˜ª¡“ªŽ‘€Œ‰“šž‚Ž—~†Žƒox†rua~ƒ†u‹˜ƒ‚†…~…„”nyut’¡Š‹…šƒ„Œs‰||rr{‡ƒzxŠŽƒ’¦Ž…ƒŽ€ƒŠ‰Šw†‰ŠŒ~qm|nhlmh_zh}|vuvu{w\_p}nu`c[]^QgnTe[^bkivz~qlmdkjh€lslmunyp…yn‡€v‚€~…vq‚ˆ~{z|{‚Š`i|juhi‚ejc`i\duhobumlUcqyepz{sejml‹‰ž·š¡£Ÿ‘‘•—‹šŸŸž{xž§‘œŠ‡¤”‹˜™yz…|‰‘ƒŒ‚‚‚n|ys…}‹}kh}‚˜‰€‡|~†„†}‚œ’‰©€pŒ‹Œ“‡¡¢Š…Œ}¨‘ˆ’—“–“xŒ£Ÿ –™€š˜’Œš£¡£š—‘š}Œƒw‚Ž† ~ŒŒ|˜¤ ¡“™¦š‘‰“—›~“’~‡Žtt‚pv`}€†qŠ•|ˆŒqŒ‚…†Žhwqx‹˜‘~–}‡Šr†{|qxzŠ„zy‹‚•¥“‹„z††‡…v‚„‰ˆ|gs}y{qlkg_~sh|uvt}s€j^`svpwdcY_^RkiUeY_ahjvyqgkdmhe€km~hpqk}y‡zkŒs~tv‚†|z}jrƒnsib‡hlb_qVtomn`xhmWjtvcuz{rbjoy‰ž²’¥¥œŽ—† ›|v¥¡Ž˜€Œ¢Šˆš–x{†‡~ƒ‰ˆ‚q{tvƒ…~Š‘xgc}†—Š‰Œy}€ƒy—‚–™——¡œ~pŒ‚‘”†¦›‡Œ‰ƒ¦•…“‹–—“’w‘ ¡—“–y~Ž˜—Ž–š¤˜’”šx„‚wƒ–~‰Œr—£ž¡“™Ž¢Œ‹ƒ–˜ƒ’–™~˜Œ|ˆ€vq}nzd€|Š…p†“‚l‡‚€‰„euo{†’—Œ|’w‹ˆ{…|{q~wˆ…y„‰Š—¢•‚Švˆ„‚‚w|‚Š†xazy}txgmeajjwstu}q|bcasnurmaZa^[leRcY`ahkvy†qbjcmeh}ƒlhuinog}‚ym†q€„ƒt|ƒŒ€~z‚ƒ~|mv‰ttmeŠljbcuV„iqn`xglbjvpfy|zq_ql†…œ®—¦¨žŒ—‡†Ÿ“—™}xªœŠ™z—‹Œ˜y|Œ~|ƒ|€‚xtyzt}€„‰‹€d^}‹•‡~„†u}~Š}™…—•˜¤£™s‡{”’Š§ŒŽŠ“¡’ƒ‘”—‘‹—Ÿš’s’”‰ž¦——••sŒ‰k…—™z‡ˆ‰o—š£“•ŠžŒ†‚’œ’’•‡™ˆ|Š‰yqzkul{~‹~m…’‚”xp‚ƒ}~Šdri{€–—„~Œs‡ƒx†}vw|…€|‚Œƒ‹“¤xƒt‰‡}€tv‰…pb|vzq}obocd|cnovsxwstau`olumo\\_^_j^P]Ycahmt{ˆk_ifjchwˆnflijlg€}{wnˆs€„„}t†‰{ƒ}z„}}Žrz‹xxnl‡jh_irb‡hqoevgnlayik}{xpawm‹€™™ª £¨ŠŠ‘†Šž‹•˜~w®™—}Ÿ“‘–”ˆw~{Š}{€vx€ptt|o†}€Š|a[~’†ƒƒsz€‡z’‰“’“¦œ•‚}‚|Ž‹’¤‰ŽŠ˜›†‘˜“–ŠˆŒ’œ’‹Œnƒ‘ˆž™¢¡—–‰–‘n‡˜ƒf…˜Ž“zˆ„Šp•š”¢’’‰‹™Œ‚ž}’’Œ™Ž{Š„‡srukpnu|Štn†Ž’qu€{‡{dplx}™“}ƒˆs‰€s‡yn}€…{…‹ˆƒ‹•¨Œz‡{}‹…w~qp†„diyuup|b_pakt^qj{yylspex]nlsmrYZ__akZPWXecgqq~‡f]jigbgqndigdiizwuoŽ…t‚ƒ{u‚ˆ…x…|xƒ…z€‰w‹{zrxƒjk_pht€jromqgole|cn€zwqlwwŠ~¢—¡¨ ¦›‡ŒŠ‡“uª•“Ž‡¡Œ•“€t|v…xyrs{…krpzmŠv€‡nq[X~‘ˆwu€ †‘‹“˜¡•˜xŠ€‰œžŠ†’˜–…‰•™–‹‹ŒŒœ‰ƒm‰‹Š–¡œ—”…˜‡jƒ¢‚e…Š~‹ƒ‹w“˜‘ž‘‰‰•~˜|‘š‘|Š€‚nuplmop{…isƒŽ˜Šqw€u‚ˆ‚xfrnu™Ž{ˆƒy“yv‡soˆ{…‹zŠ…‚‡›£‡{ƒu‹wynl„‚^susqpxZ^qapk^pj}{qmmjlv`pojqmZXaabnXQTZfgcvo„‚b]kndbfk’n`ff_gkursp‹€uƒ€xu€‹€y…w‡†wƒ…|‡Œ{vŠjqc|c†|nqltjholvx_qy|tut€‚~¤•š­ž§–…ƒ—”ƒ u‹ ”’†‹›Œ•Ž‹zrxt‚pr…squˆkomvmˆvƒ~€mnUQ«•‡‚wws‚z‚¡‚“‚•”™œ“šx’{ƒ“¤š“Ž‰•™’…‡—™Œ”‹‰‡„Š|s‹…‰ŽˆœšŸ›•”“~h„›†g… ‡‘ƒ‘‚‰qƒ‘—›ŽŒŒx{’zŽ‹Œ’–Œ|ˆ|€kvjnkll{az~Ž–‚vz€xƒŒ|ygsls‡•Š~‡…z“ŽqyƒovŒz‰‹yˆ}‹ž„|zv‹}wpjl‚ƒzayqnmrtV^pbra`lnzqhpffsthpkawe]Vf``rSQN\fe]ypˆ|_\irbbef’j_hd[gp~pkqtŠ}v|…€tu~Œy{†€xˆƒs†…~„|y•xfrjƒ`ˆ}ookz`jntu_t}y†xts…|x ™°œ¥Ž‚Šƒš‡€Œž‹š”…ˆ˜ŽŽ„wtvs€po…tpr„pkjwnƒn}}musRM‚ßȒ֓|puƒv„ ƒ”w•’™œ‘™{”s…Ÿ¡““‘‰’›”†~––ˆˆ’ˆœŽ€wzŒ~‰ŒŠœ››•“yŒuf‡†k‡¢„‘ˆ—‚…cŒ‘™Ž•Š—‹Š‹qz”ˆ{ˆŠ“‘‰y…|~l{erokkzy[€yŽ€z}~†ŽzzhrjsŠŽ‰…„|”Šk}~n‹~‹†|ƒy€Ž”ššŠ|uwƒxrmgq€…nkuphjunS_pepZ`lrxgkkbfxrppc_w``Vk_^vPNKagc]zp‰t\\ev`aeecafbXissmjqvŒ}ty†uv~‹s€†z‰~r‰‡‘‹ˆ|~˜vesn}eˆ~opk€Zlnyysav{{vrwŠwyŸ‹›®› ‚…wˆ•~}Š‡† ‘…Œ˜„“Ž‡twpyqn„omoseeyq}my}jhkc¤šÁÜ®ï¡slv„v…£†’o—‘–¡–œ’r…‹£—‰Ž•Š–ƒ•…‰€‘Š‰–~‡zu‰x‡„Žœ›˜™Žv‰um…ˆŠ|‰¢ƒ‰œ„…^‹“—ŠŽ‰ŽŠŠ„‰m{–}ˆ…‰‘†v…}}k}dxujnysWˆz’‡…y~€€…Œ~xeri‰Ž‰‚~‹–„kum‡„}x~•“˜trw‡Œusqgvz„cunqbjwhRaqgkV_otzard_h}prmZcrabVnY\xNMLdgb^ws‰m\\dy^`de…`cc^YjrknkrwŒ~tw„xw{‰qƒ„|~ˆ{t‹‰‡–†Œ~—shuqym‹zntp€Wqzvyqexy‡Œiv€‰rœ‡™§œ£’…}pŒ”xy‹„…¡Ž|–€šˆ„{swpsjpljm|u_axw{qu{g`d|ëÚµÉÃ܈sltv‹›‰Žj™ž–”‰q…‰ Ž…‹•ŠŒ˜”|Ž“ˆƒ‰{‹…vxƒ„rˆ‚“œ—”—†Œu†}nƒˆ†˜¡‚“‹žƒ‰aƒ”†‰†‰‡‡j}”€}ƒ„‰Ž‚q†~qwhvritwkZŒ|’ƒ…}ƒ€„Š‚uaskˆ€Š~~‘|mkx…Ž…‘‚{€|~‘’–ˆnpyŒ†ukqlsy‚`ujo]kw`RerhfS`pvtap`]hƒqsjWghbiXmV[uLKLfg_brs…i[\ey^^dg{ad_]YknfoisxŠ~ss~zvzˆs…ƒ|‡vwŠ†Ž™Œ‚{“ulwuyx“tnx{|Xz†q€ogyw’‚dv†…qŠ–…™¡š¢Š‡so“‹rwŽœ~‹š‰‰|Ÿ„šxrsnodrifmxx\_y{{qq€jagaÕ¶Ž¦xnqw|q“‘‡kš‰“Œ†{i‡‹™†’‘†‡˜Ž|Š|Œ}‰„ztzƒ{q†€–šŽ“”ˆtƒ…u‚‰‘œ…”ŽŸ~ˆa“‡„ˆ„‰€ƒg}‘€~‚ŒŽ~m‚|‚tkmwutwvkc…~|„„ˆ~o^qp„{Ž‹{~‡ypƒfy‚Š†‹‚zƒ}“Ž’„nny‹~umnll{~ciljYnwZRjsibQcsxlbe^Zjƒnsa[g_dl_nU[pNHOge\gnq€l[[cs`\clwde]]Zklbmjtw†qp|}tx†x…‚|€‡uy‰’–|‰†v‰pwy{„“om|w^ƒtmizt”sgs‡|r’‘ƒšŸ› †ˆvv•~mv”—~ˆ‘„ŠŽš}Œšv}vqoljau|gbjuzZ`x|zmqedhgW^qs–¼Ä„vq”Šs˜Œ‡œ”ˆtkˆ•€{”Œ„›Œ|‹†}|‰Œ“ˆu‰…vv}qu†ž•†•‚‚q‡sƒzˆ–›–†“œ€ˆe}’‚…ƒ‰‰r‚~g}‹{y‡‹}i€}ƒvfoyxswslj…ŠŠy‚€„ƒj]pwz|‹ˆ…{€Ž}r€hx‚†Š…‚w‚{€—ŒŒ}mkz‰|vtoih}we]qcXptSToshbNhtxfa^]Xo€osYeb]jm`pOYlRDThaZknm{oZ[^lcZcpvdg\]`kjclisvƒqn~{tuƒz„‚|‚…v~‰–‘xƒŠtˆryyŽoo|qiyz~mm|v–kjx„tk”…Ÿ˜ š…ˆn}Œvjx˜‚Š‚•˜Šz–ozsqljd`t{i`fr{[as}zgpzaeeŽ±²wJbZ¤ÙЗr{’Œ‘y–Œ…š’†ol†’‘zy“‡„™Š|‡xx‰Š„•€oŠ‡qt}{jy†ƒ¥‘„“ƒ~n~‚u‚w…™˜“Š’”…‡oz’ƒ}ƒƒ‰ƒo‚xh€…xrƒŠ‡|e}~„ucps€hyqou˜…‚Š{vx€„yjZo|r‡ƒˆ}…ˆzˆr€mpƒ†ƒƒqƒx€˜Œ„wmm}ƒvzehj~raZx[YrnNXrsf`Kmwub^[[Yu}roWg]fjp_oNWiR?Yg_[pjgyq[[YkeYcqy_h]^elhfliqw‡om}€up{€‚v…‰—Šq‚q{†}zz„”Œujzlo~t}or|{”po€xf’Š‚¡˜œ’‚…g‡„phz—‰~€…‚™Š|ixrklf_aoym_boy]dlƒzaqv_eeÕ뾋2:>‹Ž€ry†‰w…˜“Žnl…Œu}…‚•‰|ƒxnv‡…ƒ—wnˆ„lu{ufy‚ƒ¨ŒƒŒƒ}mtvx„›‹‘’Œ‹†~{’‡x€„ƒl€si~xm|{Šƒxay„qdqi~mtqt›‹€„~su}€s€nZk}tx‰‚Š{†|ˆxypk‡‚Ž‚‰qx–ŠŠ~tmjv€€uu\iixqYW}SZreL[sre[Jqxp^[[Y\uuhYb[genbiMWfQ=^f]]vf_tp[YUodZeqyZh^`gmgilhpx~Žlj‚„yn€{}€‚zu‚Œ“…p€‹nw~{{ˆ“‰€i{~kt|r†{sw}Œzx„~|kŒŒƒ›–Œ€l~ki{~ƒ”‚}Šˆkuqghc[bgso`altahp‰zast^cd› n\5Y¯µuj€Š~“†w‡˜‡uŒŠwpl…ƒ‡ty‰x‰}“ˆzsgvˆ~}˜op†}hwynezˆ„¥‡‡Š~n~v~{Š˜†“—ˆ‹„‰|ˆq{}…|i~mk€{zjzv‚‡€r`w~qdrgu‚mu{…•‘|~owy{t}lWm}usŠ†w‡u‰zwrmˆŽƒr~|}’ˆˆznmim‚un]hftrR[{N\q\O\rodVKsykXYYZ`qu`]]agdhhfNZhNAad\`vb\umXXStaZdnrWj^bhkgmlipw|“li„Š}}p~~{‚zw€€‰‹„r{‡oqwƒ{Šƒj~{nxywŠw}x€‚‡ƒ~zm…Œˆ˜£„ƒ{vŒykm„‰’y}{‚‘€€}Šƒprpcf^Yg_pp`ahpfjoŠuato[adiv{¾œ¦£È¸r…„s“}yˆ”„t‘ˆrsp„{ƒsu†tˆw”‰yyqcw†y€“ir„ufwvcj|ƒˆž‚€ŽŽ}r~sƒw~‚w•”‡‚ˆz‰‰kxy~uhzilysizv€ƒ}h`w‡~jjsh{€ivŒ”~z}}q{v{s}aUu{qs‰ƒ‚|‚p†Šwwoo‚‹}|x}|u…‚vhqhlˆ‚rp]hctoKevL^oUTYsmbQOtybSXX\ap‚t[`\hedcjdP[qIDdb\cq_\whUWVw^\enhVl^ajgeoohpwz“niˆ‹y~s{~y‚‚|v}ƒˆ†ƒpvƒsmwƒƒ~‰‹”q€|xyz‹tƒx‚„y€vo~‰‹›žˆ}†zw‡|ht†‘z|‰†„v€gpn_d\XeYmsaaaqllh‰n`siY^dm€w©ÚªÇ†‡³rŠypŽv}ˆz”Š€utu~w€pq~m…t”…xtl`zyˆŽfqƒogun[m}“€y’’}x{m†t‹ƒr•ŠŽ‡……{…muvnhwfm|vmjwv|`bx†zhuuc~{gt†ŽŒ•{t€uq€z|l~YVr|otƒ†xkˆ†sxjt‚‚|y|w{rŠ€|sgtdm‹„mt[k`vfHnoL[cXWVxmbPSuwYQVX]`r„o\`cmdc]nbT]rGCf_^fi]Z{bRV\u[[gkaVk_anfflqhpvxtkŽuvx}wƒ{t}ƒˆˆƒoq€uqu~†‚‰Š{wx„|}…‡x‡|}~„€{~svyŒŽŸŒ‰z‰wuƒy^~†šy‡ƒt††„w‰{bnl[b[[aUjtd`[hopg‡raqfW]ck|Ê·¹¢knn‹mr…r~…‹{’…zytyuu{jmuc„v’vog_|y‹‰eqjjqcXm{†œ‰ƒ‚s—”w~{m‡p€‰Š†p–Žˆ…‹ƒzy~qqo}ghrcnxrjlqw}|z]ey€wiuyf‚vgt‡Œ”|r‡jn~€xm{\Xp}lsŠ|nn‰pvfv~€~€u{qzs†{yqer`mŒ‚lsXk_x]IolMWV_TU|kaOTvsQRTV]bt…h\`kjfbYnaXcpGAh]`f_\V{^OVepZ[jh]Wg`_rfjhrhqsw‡xn•Št{w~yƒ‡€us†…Ž‚pp{xwuy‡…‡Œ†z|u‹~}†„„‡~~}‡|xuyw‘“Ÿ~Œ}‹nu€ydƒˆ—†t’Šo……‚zƒucnjY_[]]Uhse`YdrrgsbkdW[`ix¾®{Ÿ·mbt‡it|rz„‡{~€xxswo{wejn`‡uŽ€rib_~xyŠƒfp}hjk[WoxŠ£…q™“q€xtm‡r“‡Œ‡ƒˆ…}ytrohyajmamvkgklzwzw[g}|xes~n„teu††•~p‹fkz‚tltb[mzjt{‹zft†}mpgt~w|~q{ky{ywpelal‰~mnVk`xVKklOROiNY}gbNUvlMQTU^fvƒf]aphgaWi]\liJEkZbdVXUyZNWnjY]le\Yec^tfldrgsptxp™…v€x|…‡}us‚‡€•‚nsy{{sr…‡ˆˆ„y}v}„‰Žƒƒ{~‹ƒ{w|wwš—zŠƒ‡iv~|l„…”€r‚q†‚~‚oflgW][\[Sepe_XcsuiupdebW\\h€por€s‰eeyjtvtt„…x‚„zwtunkzpagkg†tƒmf^_|o{‰}hmwfidVWrp§|„|v–s|r{ymzz„v–{‡†‚†ƒ}uprmgu]mi_ludgfizo{rYgvugp€x‚vbw…‹|”€n‹jmz€pere`kxfrv‰z}auƒvikqtzoxxr|e}~~xvnceal†|mkVjbrTLikPLNpH^{faNUueKOSW`kw~e]gsie_VcWbp]KKkXdaUTUsWMYveZ_k`\Zce_wgmbpitoq~ut™x€€x€~†„z}v‚ƒ~˜…nrt|ztq……‚€z‹ut€}”Ž€…„|~Œ†z~€v{£¥Šyˆ†…lu|{u„‚Œzo…sz…}‚ƒunjieV][[ZScne[Xat{jhmh`bW_[i€iko€glaizyjtuto†‚{}vunzhjyj_eniw„hfXbwi~‡zoiogf]UXoh§vz|Žxun}mqtxŽ~w”t…‚…ˆvjrvgho\me^ns_gbjxh{m[mƒstjo€~ywbw„„x…sˆqpyqbph[nwdps‡{xar€pgixsqkwvsub‚z~wupcccm|}kkUibgTLmiPGRlEaxfbMTs^JMUYelx{f_mqjc\V_UooWJShXg^XMUlTK\z_[_k]][be`zhlaoounowuz—}w€y€€‡†zyzƒ}“„qttzvt…ˆ}€}ls•{‚Ÿ…‡}€~†‚€Š{v„¬Ÿzˆ‡„lr‚yv€‚tn‡o}€tŠ€jonddX_ZZZUbjg\Z_u‚i^ml\aV\\kert}ij]lwvhuwrn‡|~~zvslzgiwg]dshzw’ccTdog‚„wvfhjaWVYhd§n~x€‹Žzpo{fxnyŠzvŽqƒ}~†ndvsdhh]lb^po[g^muezi]t€orkq{~uvcu…Š{‡‡€wru~s`plYprbqq„{udr€l`lzojhzwtpdƒtyyuqdadms~jlTi^_ULtcQGWbGcwfaLTqYKLXXglvzeemqfcZX]XvfTJ\cXiXXHWeQIcy[]`l[^\bd^€ij_otxnonvƒ—yr€}€‰Œ†~vv†x†Œ}tuu‚yzz‚ŒŽ}~„‰jt–{Š}~…y€{~|†ˆsq®Œ{{†~fqˆzt}}vro†m{~mzbpobe]eVZYWcfk`]]s†iXpm[^XZ\l{cqwvmc[ntthuvqm…yywnotehte[gufvv’z`]Sefj‚s}aci\UX^bd¥hyt‚…xlnxfwl{ƒytˆr€x{xhevm`fa_j`^ukYe]onbzf[x|knnpwytuerƒ’‡ƒˆzvoq|qawcZnoapq{seq€d^mvicfxzskm€ts|rqb^emo}eiThYZUNy`RKZYHbudaJUnTJLZVilr{cllscaYZ[aw\TKc]YjSVGYaNHjvX_bm[[_bc]…ihanxylojvxm‚~€‚’ˆ„vu‰t‹†tqvv‚x|}~Œ€~“~px–ƒ}™’y€€xy~sˆƒsp™¢{{€‰•yduˆysyvksply|p‘r^poagblT[ZWidmf\\r‰fRrm[YXX`lvdjujj_[mtrmtttk†}€|wonldipc[krdtvŽs\WSd`q~q‚\ac^SZa\d“Ÿerq„ƒskjxlnoyyzq€vryzzdfug^b[ah\^wiWb^phaxa[{vjjrowtstip”ƒ†~„vrjp{levW[jmbpr€zseo~[`oqb^io}ljr}qpwkp`[ekm{agTgUXRQw\SPYRHcsbaGVlQIPZVklk|emoqa[ZXYlpWSOfWWiSTFZ\OIruY`dmcXa`a^Œjcdmyxkoiuy…{k„}€…™}‚„y}ˆm†qowz|t‚‚}‹ƒ‚–tx‚“†Ÿ‰ut‚p‡‚uo¢—s{†‹‡{fw‹on|pfxq{lsvsk^tnagfkS^\Vhbll[\qŒdNom\VXUgithctee]Zovoquuzlˆ}€}ˆwscdkoa]nmdsxˆkZTVbcw||p…\c_cTZ`Zc–•cnpƒ„‰rjgyneruqzkysunz~u_fsc[^WbdYaufV_amcaq]]~ohisqspuukl„“‰{…qrfn{opnRZejeqs€vsblvUbqk[^nd|ekt|qrrjm`Ycijx^fTeUVPUoXQWTPHer_aFXkOIXTVnid|ikxkaW\U[tdSRVhQYgTSHZ[PNxw[`fliZb`^^nbfkyunnivv~~m„€~†—{‡‰~k“ˆrgt€zu€ƒ~‰‹“r}Š‘…‡Ÿ†{†Œs€†s}‚un¤Œs‹wxn{`d|qgysymmqvƒgd|mcfghS`_Ug`lo\^nŽhMil`UVSofslexde]Zquns{xsn‰{wœ{zlbelm^`ojeqygZVX_lx{{oƒ_b^hVY`Xdœˆbkq†|wkjvl[upjyiurmn{€rXjn^Y]VbdXeqdT_bibbmZ`~kfksunmwvkh…Œ‰z‡mqfo{lqlbX_hhos€ss^imSepdUbnaybotztjolj_X`fhu]eVbVSOYgSO]OOHeo]cGZjNJ_KXme_xhn~d`U^T]t[TS`fN]bUSJ\ZQYuv]_fmhXba[^Žqcgjwqsmgvsyƒs‚ƒ{ˆŽ~|ŠˆŽynŠtlssˆ…‡’„•z}Œˆ‘›„€|Œ„rstwqn““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|}~}}~~~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’’’’’’’’’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’’“““’““’’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ‘mfggggg}…„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDBK’š™™™™™ž     ¥^*///0,H…ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‘g_```_^yƒ‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR455553?“žœœœ››¢¤¤¤¤¤ªV:ƒ€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}zzz|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‘ŽŒ‡‡‡‡‡‡‰““’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†…………†ŽŽŽŽŽŽˆ‚ƒƒ‚‚‚…ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z{|{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘’’’’’’‘‰‡ŽŠ’“‘‹‹Š‰‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…Ž†Œ…ŠŠ†ˆŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰ˆŒ†ˆ‡…‡ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰ŒŠŽˆ‰„†ˆŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}}}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹ŒˆŒ‡…ˆƒŠŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz|||{}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒŒŽŠŠŽ‰ŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzyz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{z{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†…………………„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰Ž‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{~~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““”””””””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’“““”””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••””•“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””“’’““’’’’’”’‘”“••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’’‘‘’“”ƒ…”’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’Žƒ’‘‘“u‰“‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘‘Žo’‘‘|t‰‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘xj„‘ŠsvˆŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ{gqŽ„ru‡ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽy\hupdoˆŽŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹ŠŠ†dik\gjkƒ…ƒ„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxz}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzoq{xy{|{xw{xuwttvuuvwncul[junehklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkiffggghg`gooflrtjbcbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__ac_\_]`]^Y\bgjroqsmZY_[XWSNMKKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{yvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSTPMJMNPROMR_cemnnjhRQTPPNNOMJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTtsuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNOMMUckglmmgeYQOOPQONNONOPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKKEEKR^hmglmljjfb\UPOOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHFFS[]afjnjomkjkkjjfZKJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:;?@CS^cmllnwrjikh_TMFEEEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@:;><;;<;GKBNbmpzskj`KFBEFDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnppsttsqrvyy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;:;;99:88;<979;;=<:>M`tpcNC?@@CFDCCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqtsurqtxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<:79::979::78:99;:68WfA88;<=@A@=;;><==@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyy{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>><==?@===?C;===<<<:DY9<<==>?@A@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquutusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCDA?=>@A?@<]n@>DE??A<F]=>=;:=>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVppqssttuyz{{|~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???BFD><<=@=8:;mwI8;:==A<Kb=<=<8:;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pprrrtuvz{}}|~~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC?>AAABA@YR<==ILFFvwN788:;>>WiA;<<::;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvvw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC@CsyI;]ƒy|wV<=?==>EitM:=>?==>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hloppqtuvy|||||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCEAHrykb‚„ƒƒƒ€}]>@C@@=Ir{Z:=AEABBFHC=<@DDA@?>=@A>>>?<>@DGE@>@A?@CFECBCC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{{{}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@Fot}‚‚ƒ~}„uLACE@?>X{€]?CEIJIIMMKECFGGEGEEEDDCA?@>>BFJJGEEGFFJNNKJIGGHKLIGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@EEhs}|„~y…qCDEDCWu†‡‡~XGHJMLNOOLHGHHHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHHHGFEFFFDFHGEEHHFHGHFQnnpqrvvy{{{z|}~~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJG`{€w„…ƒ„ŠmAAVt‡‰‡‡‡ˆƒWHLMLMNLIGGGGDGGGGFHFHECDDFEDDHHCCCFIJKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrsvwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLLN[|‚‚ƒƒ…††ˆƒVl…‡†††‡ˆˆ‡|PKLKHGFFDECC@ACCCCFFEB@>>@AA@BD?>?DFHDEGIJIJHHHGIIIJIHFJJJJIJIJJJFILLKJKKfopsrtvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKLLJUƒ„„‚‚…††„‚†…„„†††‡‡†ŠuIIFB??@???<<<>;:<AA@><998<<=;>;9;?AB@ACCB@ABDDBCFHIHHHLMLGIJMMNMJJKKJLMSlpqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHHJJIe…„„„‚ƒ‚ƒƒ„……†‡ˆˆˆˆ‰ŒŽfBB=88::9878896479;<:8567789787688;;;=@;999=<>;;=ACEHJMLLGIHORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@CGIIj†„„~ƒƒƒ‚ƒ„†‰ŠŒŒ‹Š‰Š‹Œ‰T:8666766645773568:876565676778:67789;7578979876:<@GFIFIFEFOSRSSROPPRTepqsttwy{|{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:=ECBf…ƒ€‚ƒƒƒƒƒ…‰ŠŠ‰‰ŠŠŠŠ‹‰ŠŠG676468874578567699766765:9:;:;898987779:98878689;A=>>BA?AKLOQPQOOORWkqrttuwz{{{}}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897;B:=q„€ƒ„„„„„†‰ŠŠˆ‡ˆˆ‰ŠŠ‹Š‰‰Œz>988;<=>9::<9:;9:;:99;:9===>;;<=:>;9;;<;<<9:<8::;:999<?<=ABDIJMKIKLWorsusvx{{||{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<;89989:::;?>H~„‚‚„………†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>BCEEAA@B>@B@@>==>@?>?@?@==?B?@A?A?=@@@>?A=><;:;99;?=;<==AACABCAXpqtttvz{{}}{}~~}}}~~~~~~€€€€€€€€€€~REBAGJNOLIGK:8:;9::<=:;;==?@BR‚‚‚„…„…„†‰‰ˆˆ†††‡ˆ‰Š‹‹‹ŠŠ‹Š‹^>DGIKJIFGGDFHGEB@@CECB@BCB?@DHECECEEAFEFDEFD@B?<@>=?@>?>?>?>>:;=<`qrttuwzz{}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>???=A@CDFW„‚ƒ„……††ˆ‰‰ˆ‡†††‡‰‰Š‹ŒŒŒ‹ŠŠˆVHMLMLOIIKIIJJIECDFGFDCEFDBHIKHGGFHGEKIKIJKJCFCCDBAACBDCCDDCA=;=@hpsttwwyx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLK@BBA98<>;<;>@?A>BBGGIY„‚ƒ……†‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹‹ŠŒPNPNLNLJLJIIHJFDFHHIEEHFFELLMIJGGHIJNMNLLNKHGGGEECFFFFDEHHFCA?@Llptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?EGG=<@@88<;<=:>@>?@CFIIP_ƒ…„…††‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒ‹‹ŠrNRPNMMLLJHGEIIDJHGKJHJGGGKLNLLHHIJMQNPNMOKIGIJHIDIHHFFGGHGCBACUnpuwwyzxyzz||}~~~~}~}~~~~~€€€€€€€€€€€€€€TDAABGGB?8?@8:<8=>;=A>?ADHJLUqƒ„„„„…†‡ˆˆˆˆˆ‡†ˆˆˆˆ‰‰ŒŒ‹ŒŒŒ‹‹‹‹_RRPMNMKJGEBGJGLKFKNKKJJLMLOPNHIKLOQPPQOOJIJJLJLFGHGFFIFEEBABB\orwxyzzyyzz{{~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<9@>>@BGGAGKLPVy…ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹‹ŒŒŒŒ‹‹|XVRRTSOLKJDEFKONOWUQPOQSSMSTOMSLPSUVRSQPLJMMMKNGGJFFIJDDEEBDCcpuyyzzz{z{zz|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?==B?BBGVNFNPPTX{†ƒ……„„‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŽ‹‹‹hWUkaERQQPI;;RTR`u]UVTVYYRXXRZfPUWZ]RTWQONRPPPQKKKHHJHEFIIIHIirvyxyyz{{|z{|}|}€~}}}}}}~€€€€€€€€€~~SHJIHGGFE??AAEBCGEDELXRMTUVX[|†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠ‹Œ}aŠ‹‹‡l[dU:XXXSQ?@VUY\d`VYbr]]W]ZUEQYZ[Y_TYgRVVXTTVTOOMJLJIILMKOMSosvxyxwyyz{z{|}{~~}~}}}~}~€€€€€€€€€€~~~VJJIHGEDDBA?HMIMPKIKPTSSXZZ\\x…„…………†‡‡‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~‹‰Š‹ynpXZ\[RSRVVT[ZuƒYU}`\X]^WIV]][[_YHYXY[]XXYWRQNPQMMOSQQURassvwwvxxxz{z|}}}~}~}}}~~€€€€€€€€€€€xy}YNKIIHFBD@A:PQQWXPPOQSTTXXYZ[n‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡ƒŠ~fYY\YTUTWRQWVc–€QerXZW_hP`f[[X\gaGOZhg\[\]]WROSPPQVVVVYZnrtwvvuxxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZ[RSQORRRUSVTW_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PUXTRTRQQLOMKfy[]TYUV]ZKTZUST^ZXWWWzkX[[\^TQQPINOWVX[Zdprvvttvxyy{{||}}~}}}~}}~€€€~~zxwvsu{€€tk~~kry^[VUTROKFCDAM^ƒlVRSNOQOQURSRSUcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ymqVIKMNKMKHJDFHEC>TdURQQNKRTQMOYRMNQSUUMQSRPOMLHCIHRTUZ\lquvusswzz{{{}{}}}~}}}~}~€}}~~€~{vsw}~~du}iqt_d]^[YVPLILIal’tPQSNQRQR[RSRQRVTbs{|€‚}{{€ƒ‚…†‡‚†††„†…†u_]KC?CCCCB?DPBC@C=CIGV@HNLG]iPHFOFDEFIGHCDHGHKGDBAD@NQMRdrtvustuz|{{{{||}|{~}}}~~€€€||}€€€}vt{mh|gnqfiedb\XSQPURsWe[OONLQSQUYSUQQTROV`klrv{{xytrnstsyx~~ƒ€ƒƒ‚€‚€‚‚kMG?@:;>@@??>jQKaEFHIEB?GLNGMQUIBE??<=<==?=?ACC@?<=B>JMGUnttustvxz|z}{|}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljjf`[QRZ\Y^JJPQNKLQRQTVTWQQWVPX[b]agmmlokg`nrjmlqu{z}{xz||xwxeC@@B=:BCAADB\]O{NONNKLMOOQLKLWNHG@A<977699=;;;8989?<BH?\stuvuvxz|||}||}}~~|~}}}~}xuvz{zwyxuw{|yxuywcqhipmnmmhf^OP^\ZIHPRQOMPQNQRTVXSRYTNYZ[WY]^^_e`]^qvk^`gkwooljonnlfbYHFFHBAGIEEFDMRPaWRWQPSSRU[OOQWPMIDF>:96587979:365795<C>essvwwyy{}}||{|}}~~{~~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZXMLTTSPQUOLRSTWXTTXQLWYZVXXVXY]WXXhsk]Vaskaa_^da_^YTQNNNLIHJKIIFCQPS[WTTNQSYS\eUOSTQNKIHC?A9998978857578599Gnqtwxy{{}~}}|{}|~~~z}~|}~}~~~~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPXVVSTVOOTVXXYSUTLKTVUUUWPTUWTUR]n^RNY_[VY;DVXT[fJLORROMMNNNLJFQPUYSTOJNOUST\VRUSROMLIHHF??<:787659967665Wppswyz{|}~}~|}}|}}}y}}|~~~}||}}~}|rvqxxrvuqqnppopuvtnjddjppqrpofedc\]RTZVWUTWTRXXYYYRUOIGOPOOMRJOPOPNNOTLMIPOSTU2=XMI@Q=caQSQPNPQPNNMQNTRPRMILJORPRRSTQROLLKLLHCBA=::876;B5566:doqtwx{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqptuvcjgeWhtrrqniihpVVTUXUWURWVUZYXWUQSFEAFGGHFJDHJHGEHLHKIFLMPMG/E_R>3?>joaRRQ@GUQPQPQNQOPOLJLLOPNNPQQNPOJLMMKGEEDB;=<<9=G6677Dmptvz{{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknaePSTRSTOWVVYYVQQQO@=;=?ABAC@BEDA@GHGHEFHJMLEGCORC8ENS]fSQSAGUPOQQPMMNMKLKLNOOQMOOMHLLIKKLKGFFED<AA>;@E;<89Spruy{z{}||{y|zz~~|{utvrvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLOOMQSLTUTXWUMLKI<987;>@><=A@B=>EHGCFFIGJJ@FAA@FHEJOHPRa\QPRNSNOPLLOMKMLMON[WKMQOGIHCHJLLJFFFE?BC><BG?B?Adptw{z{{|{zzw{wy~~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHDD=9779?B>;?B@@>ADIECGGIGIEBB?>=CBAGIDMObeQMNNWKKMKLMMMLKNNSdMJLRIIIEAHJLMNJGIFBAB@?EFEHDKnovyyy{{z{zwtxux||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGLMIMPMPOHJD?A=999:?B?<@BBADEGKFCHIGGHCC?B??@A>DEDKMRTLJIMTGIIJLJKLIJLMOPQPKGCKGCBJJLMONIJIGCCCDIJMLIYrmwyxz{{y|vrpurtxyvxjqnjllnttmtu{stxronqovsnporpopstyjN`gsjt|ygosqiqhdqGKDGHHGJKIJKDGB=>=:::;AB?=BBCCHFILJDIIFGGCC;A@B>@@BEDIMPHHKGHKDHIKMHJLHIJKJM\RHHDNFADKJMMPMKMJKFGGJMNQNLbmivvw{x|z}qmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoiktgdoFKCFEGEFFGEGBC@=<=9:::AC@>BCEEIEIJLFIIGFFCB;ACC>@CCCDGLNHKNHDHEILNMGILGFGIILNKIHENIBFMLNLOMNNMKHHIORQSNRfffqosxu{y|lhjnekqlsqfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGJDFFECCCE@DB>@?:;;=:=>CA>ACEFJFIHLHGGGFEC@=EEB>BCCCDGHIGMPJFFGKNOKFHJFEDEIJHKIFHPKCIMLPMONOONJJILRUUROWd`amgproryzgehhdilfqlflmgiklslpvutpnvrosrsutqssutsuvvvyvutwljuumrvqlnlerLGEEHCBABD=CB>@=9:=?:=>@B>@BDGJFIFIHFFGECCAAFFCBCBDEEGGIFLQLIOJJLLIGHEFEDCIIHKJGKRMBNOMQNOOMNOKKKPUWVUTX_^\iaminhrsbeffdihfnifmmhkkmriqvusqmvnoqrswsrstuvvvvwvwvvtwujsunutsqrjksMGHFHBB@DD<BAAC<8:=>9?<?B@@@DFHEHFFHGFFDCECDIECFEBEGEFGGEJMKHQMJKHHIEFHHECIJIKMKOSNDQRPQQNPMNPMLMSWVXXVX]Z]d`hbjigk_eefcgggkggkmkmlprhttursnvoqprtxqssuvu‚‘yvvtxuuwxmouorsuqqioyMHGHHBBBFE<@CBD<7:>=:>:@B>??CEFDFDEHFDEDDEFGJEEJGCGHFHGECFJJGMJLKHJLFIIKHEKKLMNORTOHSUSPSOQMNQNMPWZVZYVZ]ZXa```_hec`dfhgjhhifhnllnmqpiuuxrrpupppruvpusuvu{~}xvtwvvvxplupmstnprrxNIHGICACHE<@EBE<8:>>=<<AB<?>ABFCECCHECEEFGGGIFGKHDIHGIGFDHKIGKHMKJKLHLKMKJNLONORUVOKUWSQSQRLOQPOTYZY\ZY[^^^`c^\ackb`dghr…hgifjmnponsrjtuxrsstrnpqvrquruus~yŽ}uuvvvvxrhuqkrtlqvptMIKHJFBEGE<@GCD@:<>@?>?BA<@>AAFCEEDIEFEGEHHFHHIKJFJHHKHFFLIHHJGLLLLLIMKMMMOLPPQUVWOKVVUSSQQLORRQV[[]^[\^__a`ad]d`ef`ehjcssfjgglprqossnswwquvtsmoruorspurvrtvuuuwvuwtgtrkqrkrvnvJKLJLGBEDE<@FDDC;??A@@@CA?B?ACHCFEFIFIFFDIIGIHJLHHJJILJFJKHIJJGKKMMJJMLNNNPLOPRTXVMNTVTRRQPLNTSRW[^^_]]`_`aa_acebdhbdijgv‹lkigmosqpqppryvruutsmmssmqrotutrpswtuuwvuuteqskpqjrvnwKMLKMGDCAD<?EEEC=AACBBCDACDAAEGCHGHHGJGDGIGHJFILHIJMKMLGKIHKKNQKRQMSMKNNOPPOTOWXX[NSQW\ZRWPNTUTTXZ_bb_da^`b^`eaacingbihhnxvlhimosrpqrrrvtsusssnksqmprotvrqquvuswywutucmtkopjqtowLNLLLGEA@D>>DEFC@CAEDDFBCEGCCIECIJJIIKGDKJGHJIIKHJJNLNLILHJLKZfJd\KlSHON_nUks[qpbwcSPbvuhucav`Xnqbdvinzf[lt`lkT_wvijgifglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqrqyLNJJJFC?@B?=DEFDCDBEEDFBFFGDEJEEJMMKLLGGMIGJKHKKIKKNLMMLLILML[sbdp^lmUMNfs]feqlntgpi_aYnnbppbkjjgoqtetnn\ougpMJryvkb`keemxlkvmnpsrprqpqrqrrrtrmmsnnoprutqsstuuutwxvutbmukpplrrqzKLIHGED@AB@>CFGBFCFEEEDCHHGDEKHGLMNLMMFJNHJKJILJJJKLMNNMMJMMM[roonpplkMPQlWNibtrpamnu\YlQ\mmZqmkomxxtsip]_rkqjUuyxpc^kfbgppjjopprspqpqqrrqqrrtlmrmnnorutqtrtuutuuzvutenukpolsrryIKGHEEEBBB>@@FGBGDIEEEBFIHHEGKJGMMNLMNGLNILKIJMIJIJKOPONMKNNL\hdu]lqWlNPQmUZk^klvaldsSecNmYl\tpkilxjwuhp]^rkhWbcw|oc`ggadityknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtvHMGIDEDCAB=BABFDGFLHECCHKHHFJLLFNLLSRLGLMHNJIHNHJJIHNOMNLJNMJZsppoqqmlOQRnYqkgooqqomt]nXat_nopoqronusttj[]tcwxrjnzhaacfbbjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyxtukoumtontsvsHKHIBEEEA@>DDBGDHIMIFCFJLIGFJMLFOJKWRKGKKJNIHJLIKJIHJMMMMIKKKSkb[i^_icrrZ_Yjo_eeUk_c[aaQ`mh]j\niid[pfdp]Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunwqrvtwrGGFIDEDFA@BFEDGBHJLHFDGKLIEFJOLIPIL[QJEHHKMIHJJKKIHIGKKKLGHKKLLLLJKMNT[\TPTLPONOOVQOOQNOQJINPQdqiTYW\[\UYZ]X]\\cfaaebce__fkmhmtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyxxuvqruovrtsuusGCEGFFAEC@CHDFGCIKLHFDGKLHDGIPKLOKLWLIEEHIJHIKILJHFGGIGHIEFKIJKNLIP\W^P\[`^MXYS\\b^MYZMXaRJYaZR_d\aX[ddVVX\YZX\VY\]b^d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtOBCELMBDCBEIEGGFKJKHEEJJKFEHHPJMMJMSHGEAHFJIKKILJHFEIFDFGEEJHCJMKLU_Y`X`a[`TXYT^^Z_RY\P^\YN^\^SZ^c^Z]`c`Y_b[`^[TXWY^]cbcacehekrpoppnnw††……†‚{€……††…†…uqprrsvyyzyyxxxwryvxrqxvtvaSJJMIDBBCGHEHGHKIIIDFKKKEFIJNKNLHLNGHE>GGLIKKJLKIGEIDCDEBFJD@JLJO[cY_^a_RTRW_`\]Y^QY\MV_WKQY[PZ_aa]^ca`bbbcceZQYVU\Y]c`__cdbhomnllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxXQKFCGEBEGIFGHHFFJGHGHKILDDKJMMLLHJJHJF?GFNKKKMKKKIGGCD@DAHIB?IJHP]aZ[d]_TQRX]\\\_ZKW\LR\YIM^QO\_accccb\dcbdcfXQUTR[WZ`_^^aa_dlkmjjlnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMC@IFCFKJFFFHGFIFFFILJNFDKJLNJLIKJHIFBHIQMKKOMKKIHGED?ECHHBBGGET]Y^X_Y_[]UXXP]]QKJV^X^[]UY`RQ__bb``bb`cbaddbXOQQQZR[]]]]^__dhgljnnp{{|~{€‚ƒ„………………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKCAGFDGMRHCQJFHHHEFKJMPEFIJKNLLILLIIGDHKQOMMPLMKKHICDAEDHGBAGEDWUE\U^SV_XNTUNZZMJKT`a[_X^^a]NYb\``_bcb]abW__TPNOOWQ][[\\^`bffelfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDFFHDIRbPCV^IGGHDFMKPPEIIKKNLLLMKJJGEJMQQNOPMNLNHKADACDFDCBEFBMHBKLPONLFMFGIJHGLKMOPILOPOSOLQSRUZYWYXXdWOSTPPNMOTS[YXZ]\`adecgcklpsrzy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKM]LGGXLGHJHGMLQQILKLKNMUNOKKLGGKPSSNPONONOHKF`ED_LDfdEM[I^[rmOMUmYLCQ`UkWgJ]XU^DMQULLSVQRTXWTXUT\UPfZhhdXRjSWVT[\[``aaab`fhfnkhrz|}~„„„„ƒƒƒ}|zr{z{‚€ƒ„„……„…ƒƒ~z{LHEGFHEEKOSIJF`SGJOJIOMRQKMLLORUROOJLNGHMQ[YOPPNOPOIJQQI|YYqsXPmHqnoaVPqqsPCksmqspSo_[nX]V\XUkhU]VcZ`Y[`VVXjtuu__v_Xa[\f[_aaaa^`bgmpl`pwtx‚ƒƒ‚}~€vxzlv~tx~€|~€‚„|€ƒz~wwNIEHMNBDLLGILEQVLKNIKRXWQMOOMQTNOQPKKNGMPS[ZTQROPPPJHZx]TxehZRTQvgtlpbnfjQrOMwmjrpsrqrpoo€]ezuxqqzq~s}ku}bRh|essosr{|o~yor_``baZ``gknkblfgmw~€ƒ~{xw€tvzir~nt|~wx{~€ƒx|€u|||ssNKF`]GAEMMHJKGJPOMMJNV^YULQSNXZLSSRNLPIQRTYWWPTPPPQKHgxlcxrm[KMUypumubnvPdeJfvqmwo€jfxxiWrQhzmijzz~lxzohoYvvjuup`rg|ilx|o^__ba[]bdgiidgbcdllppstsssyqrxblugry{ssuy~suzn|}ywrnNKStNCBFPPHJKJLQOOOMPZ`ZWKTWPa^RVQYRLOISTVXWWPUPONRJKrouuquqdibWnLqp^FhyWvTLiy}x`y{sna]mocRhqunmypwlvttrmn]t~zkmy|ktl|kpvux^__b^]_ddighfe^abiiijknokqnmjpacfdowxompsy~nqpj{ztromLL[VHGEGRPILMKLQQPPPQW\XUMUYUfXRRY^SLNITTVWYWOSNNNQHRmHiwK`dvvVXlOnl{sajgvULWkh}lmlx_[pz{^`zscroxqhd|ir|^TLl`vukiu|{m~xk|p]^_b[^bddgeeebZccikkrsrwglihdgaakagsrlgmmr|kmhk{tmmkmOHJKHIHHQPLNOMMSRROSRWRVTPW[VVTTTa_PNMKTSSQUVNNLMOPJHQNPULKKSTSRTPVUQPNQQXYRNPUTXXX[ZURSW[WXWZOSUWXXR]YW^WTPYRVWWWX_[gr^[[Y]]_cZ_ccdfdccbZccffemnmueegcaf_]g`dlhfgkhpzhggkujhgilQIKKLMKJSQMQPOLVUTPTUXUYUQZ]VUTWUYWOOLMVTPNUSNOMLQPKJRQKQMKKORURQRSRIHLNOQRQQQTVRXW\WSSPQUUVSZQOSRXVTYVTZUTRUSTUWXW]Z^a][ZZ\\`c[]bcdfdddaY`acabhhimcad^_c]Zd\bma^fegmsdihkkedcfhPJKLOOLMSPNSQQMXWUTUWWWZUS\`VWVYUXSPPKOWSPNUPNQNKSPLOUSNRNMNQTQUQSTUNKMOQTTRRQVWTYZ[YSURTWWWY[TOTUXUUZUWYURRWVUW[YZ_]UX^\^][]aa^[bbcgfddbX_`b^`hefea^_]]^ZZ_Z_g`^]]bhkagfhfd`bcaPKMLPQLOTOOSQOQ[ZXWXZZXYV\jdVXYZWVSSOJNVTPOTPPPNMQQPRXTQQOMOSVOXRTUUONMQSUUTTRTWVZ]\ZVWQRWXV[[WQTWVVVYTXXURRYWVZ]Y]_^V^]^`\[____ZbbdhgddbYb`a^^fcc`b]\\\\YZ[X[a[^]\_b__bdebd__`\PMNNRQMRROSTQOU\[ZW[[\YZ[dqmhd^[YVUWQLMVRMNROQROLPSRUZUSPPLPXWRWSSSXMOPRTXVUUSUYX[^][[VROUVV[[WRTWVWXVTX[TSRZXW\^Z^_`Ua\aa]`b_]`]c`cghdf`Zc`a__ed_`c[Z\[\YZYYW\Y\[`^_[^^a`^b\Y`ZQNONVQPTROUTSPW\]\X^\^V\^jqwy€b\[VVXQMOVSNQQPRTRKQTTYZWUOQNSXWTSURRZOPSSV[VVWTVZX]^[[^VSNTUV\\VRTVVXYSTY\USS]XZ]^\```Va[cb]ac_\bab_cfidf^[d`a`acd_b_YZ^[\[YXYWWZZZa\][]\\Z]`W[[ZPOOOYPUURQWRTP[]^^[`\`U\]ijr}slg\UYWPNRZSRQSRTUTKRVV[ZZSOSRVVVTOWRSZRTTTX]WXXSX\X^]YZ]TUNVWW^[XRUUYYYUWY\UTW^Y]]`]bb^Y_[ea_dd^^cca^efidf^^da``abd`b^XZ_[\[XXXXW[Z\`\[[\[XY[^V^Y]POORZPZTUVVSTT^^`_^b\`U]^bkytl}kZUYUQPS\TUTUTVYWLR[W][]ROUSXWWTPXRSWSVUU[]X[YUZ^X_^Y\YRWRYXY_ZZTUVZYZWXZ\VUZ^\^`a_dc\^]]eaafd^^dc`\gdhedb_da`a`bb_`^WX^Z\\ZYYWV]Z]^ZY[\[WY\]VXW]SOQWYQ]UVYWWUX__aa`c]`T]_beeuzhXYYSVSV\XWWVVW]XOU]Z^]]TRWSWVUSTXRSVTXXX]^X][V]_X__X]VQYTYZZaY\VWX[Z[YYZ[XV]_`^cbbed\b\`fadfd_`dbb[fchecfaf_`aaaa`_^VU]Y[\[Y[YY][[[XXY[YZZ]_]TY]UNTZVS\TVWYVV\`abcac__V[`da_zuohY\ZUXTW[ZY\YXY`WPV^\`a\TTXPUWVTVWRSUWZZ\_^Z_\V__Y^^Y^VSYWYY]bZ^VW[\[\[[Z[YY__``dbcdebdYbfcffe^ab`c^bcidcg_g^bbcaa`^_XT[ZZ[[X[XX\[Z[WWYXW\[\`]V]]SPVZVVZUXUXWX]_badad`^YYadb`lfh^\][VWXY\\\_[Y[bVTX^]ac\RVXPWVWWWVSUTX\\^``]`]Wa^[^\[^XVXX[[_`\_XY]\]^^\[]X[`a^`dcdeefbXcedhgd^c`_ec]eidei_f^cbcaa`__[XYZYZZXYXW[[Z[WXZTY]\Z`\U^bNSWYVWZX[\XWY^`badada]^Yacb_a``^\\\WW[[]]__\Z]cXZX]`cd_RXYPWWXYYWVWV]]^`a`_b^Ya]]^Y]^YXVW[\`^]`ZZ^]^^a\[[Z\_b^bdcefefbZdffigc_c^afeZiicfice^bbca``_]]ZX\YYXXZXWZ[ZYWXVU[]]]``bbxKXW\YW\[\]ZW\]_`bdaba]`Xbcbacab][\[XW[\_]`_][`d\\XZbecaR\ZOXXZ[[ZWZY`]`bb`ac_\b]_][^^YYUX]^_`_`\[^^`bc\\X\^`bbcedfdefd\efgifcab\cg`\iibhjed`baca_`_]][Y\YXWXYXW\[ZWWXOXZ]acffrkJYW]ZZ_\[^\X][^_acbaa]b[bdb`bbb\[[ZWXiq`\`_]\ac_^YYcedaS_ZRYX\]][Z[[c`bbc`bda`c^`\]^_ZXV[_^]aa`^[`abeb_]T]``cddfegeffe^efhhgdd`[eg^ahhbhhfc`b`cb___]]\Z[YXXXVZV\ZZVVUMXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡…‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vuuuuuuuvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{{{{{{{{{||||||{{{{{{{||||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vutuuuutuvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{{|||||||}}}}}|||{{{{{||||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚‚ƒ‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||xÅÔÒÒÒÒԓ{}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰Š‚E>????@0*+++*%b’ŒŒŽ‰~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}xÕçääääç™{~†“y1333332j‚€€€{­éääääèʉŒŒŒŒƒ:233334!]–‹}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}v~ywwwwwwxyyyzy{xnoooppprrrrrrrwzyyzzz~ƒƒƒƒƒ„|||||||vuuuuuutssssssy}}}}}}}|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚ƒ‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vtttttwtvwz{x{xwvwzx{zy}yxxyxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{||||||||}}}}}}|{{{{{||||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwwx}z}z{}{wwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwww|z}|}~|wxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒ„‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z{xwww|zz{}~|xxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzzx{y|}|~{xxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyxyxz{y|xxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyxyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{{||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}||}}|||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}|}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrsuuttssssrrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqstsstrqqpponnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqrsssssrpqsponnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrrrsqtsrqo†„npoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpqqqxƒqrrpwnppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqqqqv¡ˆprp¡}opppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqro•ªpw ¡}oppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsqu‹‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqrp±žp¥¡}pqqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrrpŒ¶ª‘›²¦zqqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrsssssssu §£³¨¦¥xtsssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz~|~~|vvwwvuxzxxxxxwxx‚¨Ÿ£±£›¤zyzyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~}|{||£‘“¥œ ¡–{{yxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}}}}}Ž ˜–™œ–™‚}}}€ƒ‚€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€€±ª¥Ÿ¡Ÿ¡¡ƒ~€~~€~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~€€ƒ¤®¡§¡  ¨¬ž…~}~€~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽŒ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~€~€…§±¤œ§¡  ¢£«©œŒ‚€€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹Š‹‹‹‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚ƒ‚†‹›©ª£š¢Ÿ¡ žŸ¢¥¡•†€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒŽ‘‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒƒ‚„‡˜˜–—™œŒ”Ÿ›œš”Œˆ„ƒƒ‚ƒƒƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒƒƒ‚„†Ž–—•‡šœ–Ž‰‡†‡‡‡††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠˆ‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„ƒƒƒ…„‚‚ˆ’—Ž”š“†‡‡ˆˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ‘’‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„„ƒ„„‚‚‚‡’–Š„„ƒƒ………ƒ„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘’’ŽŽ‘‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€‚ƒ‚‚‚‚‚‚ˆ‘‚ƒƒ‚€€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„„„„…„…†’“‘ŽŽŽŽ‰ˆ‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~€‚‚€„ƒ€€€€€€ˆ‘€‚ƒƒ€€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“’Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚‚ƒ„‚‚„„‚ƒ‰–ˆ„‚„‚‚€Œ–‚‚‚„ƒ‚‚ƒƒ‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘Œ‡…ƒƒƒ‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒ€ƒ‚……„„ƒƒƒ‚„Ž˜Šƒ…„„„‚€’š†‚‚‚„ƒƒ‚ƒ„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”“’“ŒŒŠ…„ƒƒƒ‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~Œƒ~}|}‹œ€‚‚‚†”“Œ‚‚ƒƒ‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†””’”’Œˆƒ„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~•—‰€}}}}{—‹€ƒ€“Œ‚‚‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“’Š†ƒ„ƒ„‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€€•ŸŠ~~€}‡Š}„…ƒ„‚ƒƒ‚Ž‰…Œ‚‚ƒ‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”“’’‹Œˆ†„…ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„‘¡ŠŒ…}†‰€~………„…‚~}}‚„ƒƒƒƒƒ„ƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„……………„…†…††…………………………††…†††…†††‡†…………ƒ„„„‡“““’’Œ‹ˆ…†……‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…ƒŠ‘ƒ„‹…‚~}‡†ƒ€~~~~ƒ„ƒƒ„„„„„„„„„„„„………„…„†……†…†††…†……†……‡†††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„„„‚‚‰~}~…‚~€€„…„…†††…………†‡‡††…†……†‡‡‡ˆ‡‡‡†††‡†‡††‡‡‡††…„ƒ„……†„……†††‡‡††††‡‡‡‡ˆˆ‡†‡†‡‡‡‘”“‘‘‹‰ˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒƒ„„ƒ€€€„„~~€€€€……†ˆˆˆ‡‡‡‡ˆ‡ˆ‡ˆˆˆ††‡ˆ‰‰‰‰ˆ‡†‡‡‡‰ˆ‡‡‡‡‡†‡…„ƒ„…†…………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†…†ƒ‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡†…ƒƒ…„„ƒƒ€€Œ‰€‚‚€€~{z€†‡ˆŠŠ‰‰‰ˆ‰‰‰‰Š‹Šˆˆˆ‰‰Š‹ŠŠˆˆ‡ˆˆˆ‡ˆˆˆ‡ˆ†‡†„ƒƒ…‡‡‡†……„„ƒ……„……†„„„………†††…ƒ‰”“ŽŠ†„†…ƒ‚‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡†„„…„ƒƒ‚€€„„‚‚‚‚‚‚‚€~}}}}~}|{|ƒ‡‰‹‹ŠŠŠˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰‡††‡‡…†ˆˆ‰ˆ††‡„ƒ‚„ˆˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚‚ƒ‚„ƒ„„Ž“’‹ˆ…„†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚ƒƒ…‰Š‰‡…‡…„……‚€ƒ„‚ƒ‚‚‚ƒ~}~~~~~~~}~}}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡ˆ‰‡ˆ†ˆ‡†‰‰ƒƒ„ƒ…„„……‡ˆˆ†…ƒ‚‚ƒ…‡†‡††„‚‚ƒ„‚ƒ„„‚‚ƒƒ„ƒ„‘’ŽŽ‹‡…††„‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…‡ˆ‹Š†„†„‚††‚‚„„ƒƒƒƒ‚‚}|}€~~~}|}}|y|ƒ†‡‡„ƒƒƒ„………ƒƒ…„„„„„„…„‚‚‚‚„„‚ƒƒ…†…„‚‚‚ƒƒ…„„„…„„†„ƒ„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰†„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„„……‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€ƒƒƒƒƒ‚‚}}€€}~~}|}}{zz~„„„‚€‚‚~‚ƒ‚‚‚‚ƒƒ€€€‚ƒ‚€€€€€ƒ‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†‹“‘‹ˆ……ƒƒ„‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€€ƒ‚~~~~}‚ƒƒ‚ƒ‚ƒ‚}}~€€€~}}}}~}|zzz€‚‚~€~}€€€€€€~}}€~€€€€€€€€‚€€‚‚€‚„ƒ†’ŽŠ‡‡†ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒ‚ƒ„…€€|}}~}}~€€}~}~ƒƒƒ‚‚}}~€€€~}}}|{{{zzzz€€€~~}~~€~€€€~~~~}|~€~~€€€€€~€~€…’’Ž‹‹‡‰…„ƒ‚‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~}~€€~€„ƒ‚€~}~~€€€~}}}|{{|zzyyy{€€€€~~~€€~€€‚€|~~~~}|€~~€~€€~~~~~~~}}}}…“’ŽŒ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒ‚‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚‚‚€ƒƒƒ€€~}}~~~~}}}}}|||{zyyyx~€€€€€€‚‚€~€~~~~~€‚€€€€€~€~~€}~}}{|†“’Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚ƒƒ…ƒƒƒƒ…„„„„„ƒƒƒ„‚‚‚‚‚~}}}~~€}}}}}}}}|{zzyyyy€‚‚‚„ƒ€‚ƒ€‚‚ƒ‚ƒƒ‚€€€ƒ„‚€€€€€€‚‚€€€€€€~~||Š“‰‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…ƒ„…„…†††††…†…ƒƒƒ‚‚€}}}}}}~~}}}}}}}}}|{yyyyx|‚ƒ„…‚„ƒ‚‚ƒ…‡‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚‚ƒ„ƒ‚ƒ‚‚‚‚€€€~Ž“Œ‡ˆ†ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€~}}}~~~€ƒ„‡ˆ„†††…††‡‡††‡ˆ‡‡‡†}€€‚~}}}}}}}}}}}}||~~~|{yxwxyy€‚ƒƒ„„„„„——ƒƒ„}~‚‚‚‚ƒ†ˆŒ…ƒ‚‚„‚ƒƒ‚ƒ…„„…ƒ‚ƒƒ‚ƒƒ‚‚‚‚ƒ‚‚‚’‹ˆˆ‡‰‡††„†……„„ƒ‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€~}~~€‚………‡†‡‡†‡‡ˆ†‡‡‡‡†‡…}}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yxy|~‰–„ƒƒ„„”“€~~…‹€€€„†‰…„‚‚……‹ƒ‚……††„ƒ……ƒ„„ƒƒ„ƒ…„„ˆ’Œ‰ˆˆ‰‡‡‡…†…„…„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„ƒ…„~}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|xyz{|€‚ƒ‚ƒ‚€~}~~{ˆ‘||Ž–}‚†Š…ƒƒ„‚ƒ‰}ƒ„……ƒ…†…„……ƒ„……†„„Ž‘ŒŠŠŒ‰ˆ‰‡………ƒƒƒ‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚€‚€~}}||}||||}||}|}}}|||{‹‘—Œz{|zzz{|yy}}~€€|{{~~}‚•‘„ˆ}|~‚„||‚„‚€‡ƒ}‚‚‚€ƒƒ„„„„„‚„ƒ„…„‘‘Ž‹Œ‹ŽŠ‰‰………ƒƒƒ‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚‚ƒ…ƒƒ„………ƒƒƒ„‚‚ƒ‚ƒ‚‚€€~~}}}||||||||||||||}|||~~Š‚{z{zxz{{|}{~}~}}}}}|€€}†}}‚~~€‚||€‚€‚€~}{Š‚}€~€€‚€‚€€€€‹”ŒŒŽŽˆˆ‡……„„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ……†‡„„€†”ˆ€‚€~~~€|||||||||||||}|||||||y{{{xxy{zz|‚€~|~~~}€‚‚€€€‚‘€€~€~~~€}|}{}}}|}||}€€€~€~~”’ŽŠ…††…„„…ƒ‚ƒ‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚‚„†‡††~ˆ•Š~€€€~€~~~|{{|||||||||~}|{||||{|||zzy{|z}…ƒƒ~~€~…‚~€~~€…†‚€~~ƒ†}}~€€€~}}}}~{|}€}~Œ‘ŽŽ‡„††…„„„ƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}€‚„††……~€€€~~}€€€}}||}~}||}}}}}|~|}|{}||z{z|}}†„ƒ€€}~}~}‹„†~}||~‚}}}}|{}|~„ƒ€~~~~}|~}~€~~„’Œ‹Š†„†„„„ƒƒƒ‚ƒ‚ƒ‚ƒ‚€€}|||}~{{}w~vx~}|}|}~~‚ƒ€z}}|~~€~~~€€€€~~~~~~}~~}|~}~}~|{|||z{z}€€„ƒ‚~|||}|}ƒ~Œ~|{{}~}~~}{{{}|{{{{€†„‚„ƒ‚€~‚‚‚‚‚€‹Œ‹Šˆ„„„ƒ„ƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€€€}€~~~~|‚~~}}}{|}}|z||~€‚€€€}|}|||||}|~{~{{{|||}|{{{{||zz}z~‚~‚„„ƒ‚…†……††‡…„‘‹Š‹‡ˆ…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~€€‚€~~€€~}ƒ||}}|}}}}{|~~~~~|}}|||{~~{|{||}|}|}|~|}|{{{|y{|{{}z}~~€€ƒ‡‰‰‰Šˆ‹‰…ˆ’Œ‰Š‡……ƒ‚‚ƒ„„ƒ‚‚‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||€€€~~~}€€€€€ƒ‚€€€€€€~|z|}}~}}~~Œ†}}~{{ƒƒ}~~}}|}}}}}}|}{}|}}~|~}}}}|{{{|{{|{z{{zzz{~~ƒ…ˆ‡ˆŠ‹‹Š‰Œ‘ŽŠˆ†…„‚‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„„€€€€‚~}~~{~’Œ|}Š€Œ~~}}}~~}~}|||~}|}|}}}~}}~~|{{{||}|{{{{yzyxy{~ƒƒ„‡‰Š‡‰ŽŽŒ‰‰…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{}||~~}}‚€€€€‚…ƒ„‚‚‚‚€€ƒ‚€}~€~|‰‚~ƒ‘„„ƒ~}|‡}}~}}|~~|}}|}}~~}~}}}{|}~||{|}zzyyyy{{~~€ƒ‡„ˆŽ‹‹‡…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{}}}}}zx‚€‚‚€€€€€‚‚‚‚……„‚‚ƒ€‚„~€}~~}~€€}~„€~~}~}}Š…}~}~~}}}|~~~}€}}}|}||{|}{{{zzz{{|}~~€ƒ€‰Ž‹Œˆ………„ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv}€‚‚‚‚‚‚ƒƒƒ‚…†„ƒ€€€ƒ€„~~€~~€~}~~€€€€}€~€~|}}|~~~~€}‚€|}€€}{}}}|||||{{{|{|||}|Š‹‰ˆ††…„„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€‚€€€€ƒ~~€}€}}~~€€‚€€€€}€€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{|~|}|||{|{|}‰‡‡…†ˆ…„…„‚‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz~}yxtt€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„„„„€€~€‚€~~~~~€}~€}}}~€€€€€~~€€€€€~}}}~|~~}}„€~}}}~}~~}~|{|z|{z€ˆƒ„„…„„„„ƒ‚‚€€‚‚ƒ‚‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xyuu}‚ƒƒƒƒƒ…„…ƒƒƒ„„ƒƒ„ƒ€€€~}~~~~~~€}}|}}~€€€€‚€€€ƒ‚€€~€~€€€~~~~}}~~……€€ƒ~€~~€~}{z{z|{z‚…€ƒ‚‚‚‚‚ƒ€€‚€€‚‚ƒ‚ƒ„ƒ„‚„‚‚‚‚~€~}~~~~}~}}z{|…„{{syz|pwuvwyutz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€€}}}~}~~}|}}~€€€€€ƒ‚€~€€€€€€€€‚‚‚ƒƒ‚€€|z{z|{|‚€‚€€‚‚‚€~‚‚ƒƒƒ‚„‚„‚‚€~€€}~~}}}~}}{{z€x|vyy{qtxwvxury……‚„„‚„……†„„‚„ƒƒ€€€€|}}~€}~~}|~~~~€ƒƒƒ€€‚€€€€€€€€€€‚ƒ€„€}ƒ„€€‚€}z{{|||~€|}}€€~}}~‚‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxyzruyyvwwsu†…ƒ…„‚„„…„„„ƒ‚ƒ€~€~€}}}~€~€~~}|€|~€~€‚ƒ€€‚ƒ„‚€€€€€ƒƒ€ƒ€~‚ƒ„€€‚‚‚„‚~{|||||}}~}z~}}x~|||~~~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„‚„„…ƒƒƒƒƒ€}~}}}€~~~}}€€~|~~~‚‚ƒ‡…~~€€€€€€€‚‚€€~€‚‚ƒƒ‚ƒƒ…‚}}}|{||yz{z~y{yx~{|{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst†„„†ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€}€€~€}~}~€€|~€€€~}~~€}€€ƒƒƒ~}~~€€€‚€€~€~€‚€ƒ‚„„†„€~}||||zyvyyzyvyv~|{{{~|{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…„ƒƒƒƒƒ‚‚ƒ‚ƒ‚~~€}}}|€€€|€€€€|€~~~}~~‚‚~~}~~~~€}€€€~~}~~€‚‚‚ƒ‚ƒ„‡„€€~|}||{|uxyxxxyw{|{{{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvpxyrx…………ƒ„„ƒ‚„‚‚€‚€~~~~€~}~|~€€€€€€|€~€€€€}~~}}}~€‚~~~~}}~~~|~€~~~‚~~€€~ƒ‚ƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}|{|z{}zzx{|zz{xtxuqrtpxxqy„………ƒ„ƒ‚ƒƒ‚‚‚€€€€}~~€}|~}€€€€€€€|€~€~~}}|€€€€~~~}|~~|}€~}~€‚~€€~‚„‚‚ƒ……‚‚~}|{{||yw|ywxwwx{{{{|…‰}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzz{zxswuqqsoxwq{…†……ƒ…‚ƒƒ‚‚€€€€~~}|~}€‚€€}~€~€€€}}|}€€€€~}|~}}~~~‚€€~ƒ‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{||{zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚€€}}~€‚‚}~~~€€‚€€~|~|€€€€€~}~~€€‚€€€€€€€„‚‚€~|}~~z}…~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚€€€€€€~}€€‚‚‚€~€€€‚}}~‚€€€€€€€€~~}€~€€€€€€€€€‚€€~}~z“z|}|{}y{zzxyxy{||}|||||||}}}||}|~}~~~}|z||{|}{yzzzyytuuooqpwst}…†ƒƒ‚ƒ‚€€‚‚€‚‚€€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€‚‚€€€}~|†‰||~{{~yz{z{Ž~wwy{|{}||||{}|}}}}|}|~~~~|z|}{|}{yz{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€~}~€~~€€€€€€ƒ‚€€€€€}~€}€ƒ‚{~~{|}{z|||‡yxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€‚€‚‚‚‚ƒƒ‚€‚€€‚‚‚ƒ‚„„€~‚€€€€‚~€€‚€€€€€€€~}€€€€€€€€€€€€€€€€€€€~}~}~~{}|}{||xxuxxy{||}|{|||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒƒƒƒ‚‚‚‚ƒ€€‚„ƒƒ„ƒ‚‚‚€€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€€€€€€€€€€€€€€€€€€€€€€€€€‚‚‚‚€‚‚€€€€‡~~|{}|{}xwvyyz|}||}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚‚„„€€ƒ†ƒƒƒ‚„€„ƒ‚‚€€‚‚„‚ƒ‚€€ƒ‚€€€€ƒ€€ƒ‚~‚€€~€€€€€€‚‚‚ƒ‚‚ƒƒƒ‚€€„}}}|}{}{yvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysruowqwysw{…‚‚‚‚ƒ„‚ƒ„ƒ€ƒƒ†ƒƒƒ‚‚„„ƒƒ€€‚„‚‚‚~€€€‚‚‚‚€€€€‚‚„€~ƒ‚€ƒ‚€€‚ƒ‚€‚‚‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ‚€‚€}€|z|{{w|yyy{z}~}||||}~~€€€€„„€}€~{{{z{ztpxrytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚ƒ„†„‚ƒ‚‚„„ƒƒ€ƒ‚‚‚‚‚‚€€€‚‚‚‚‚€‚‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚ƒƒƒ„‚„‚ƒ‚‚‚‚ƒƒ„ƒ„ƒ„…„…ƒ„‚ƒ‚ƒ€€~||€}|x|yzyz|}|{||}}}||€€€€€‚~€€€€{{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚ƒ†……ƒƒ‚ƒ„‚„…‚‚‚ƒƒ‚‚‚€€~€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€‚‚€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒ„ƒƒ„€‚„ƒ„ƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{}~|y|zzz}||~z||}}|z{~~~€€€€€€€‚€€}}|}}|vrvxxvtvu}‡‡ƒ‚„…ƒƒ„…„€‚……„„ƒ‚ƒ„„„…ƒ‚‚‚ƒƒƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚‚‚ƒ„‚‚€€ƒ‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒ„ƒ„ƒ€‚ƒ‚„ƒ‚‚~ƒ‚„„‚ƒƒƒ„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€|€||}zz|}€}||z|~}}}}~~€€€€~~€€€€~|}}~~}||xvvw„‡ƒ‚ƒ†ƒƒ„†„‚…†…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚ƒ~€€‚‚ƒ‚ƒƒƒ„ƒ‚‚ƒƒ‚ƒ‚‚ƒ‚‚„„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒƒ„„„„„…„ƒƒ„…„…„‚‚€}‚€}||{||€}}~€~~}~||}}}~~~€}}~€~~}}}~}}~~€|}€‚‚ƒƒ…ƒ„ƒ†„‚ˆ‡…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒƒ‚‚ƒƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒ‚‚ƒƒ‚„ƒƒƒ„ƒƒ„„…„„„…………„ƒƒƒ~„€}}||||~~~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒƒ…ƒ„ƒ…~‚Š‹……„ƒ‚„…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒ„ƒ…„……„„ƒƒ†‚ƒ‚ƒ‚„ƒ‚ƒƒ…ƒƒ„…„……‡‡†‡…„„…„ƒ~~|~~}€~||~|z|}}}}}~~~€}}|€€~~~~~‚€……„ƒ„„‚„ƒ†€‚……Š‰„„„„……‚‡††„„„„…„…„„ƒ„„‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ„€}uz„„„‚ƒƒ‚ƒ„ƒ„„…ƒ„…†„…†}„y|~ƒ{…ƒ„ƒ€}~}~ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚ƒƒ‚‚†„„„…„ƒ„…ƒ„…„Šˆ………ƒ……„†††ƒ„…………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†spurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚……‚hzrss|€rƒ~ƒƒ}}~}~‚ƒ‚|}€}}||||}|||~}~}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ…ƒ†ˆ††…‚†††‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vyy†r„ƒpvxqvtturstvi€nrotvnulwm{sn€‡ym}rsvsvmnwlpylu}|~€}€}€€}}|||}|}~}€€€~|~€‚€€€€€€€‚ƒ‚‚„…‡††€‚…ƒƒ…‡†ƒ………†‡‡„ƒ†‡ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoomw}x†pqzprtfu~n{ysoy€}~€{~|€~€€~~€€€~~~~€~}€}€€~~€~‚ƒ‚‚„…‡‡„~†„ƒƒ…‡†„†……††ˆ„„†‡ˆˆ†‡„††‹Š…„†‡‡…ƒ…„…„‚…………†……†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„rioyxpkyszozwvvp€~~~z~}|}~}€ƒƒ€‚ƒ„€}~~~€~~‚€€‚„‡†ƒƒ†„……†‡†…………††ˆ……†…‡‡…†„††‰ˆ…„‰‹ˆ†„†…†…ƒ……„†††††…ƒx‹yrˆz{pp……x…xyks~y{krƒ‡ƒz|mzyyt}€vno€€ot|uwqy}}m}uoƒ…†z€rr{|upozks|nv‚~~}}z}{|}}}}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ„†„…………†‡……………‡‡ˆ†„†…‡††…„……„……†‰Š‡…„†…††…††„†††††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„…†…†„†„ƒ„„†„ƒƒƒƒ„…„…„…„†ƒ…†……„„…‡†„„…†…†}w…„„„ƒ‚}~{|{~{||}~}}~€}€~~~€~~~~}}}~|{|~||‰†…„†††…†‡…………††‡ˆ†„†…‡†……ƒ„…†…„††††……†„…††††„‡†‡‡†…‡ˆˆˆˆ†„‡…††ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…ƒ‚……†……ƒ…„„„…„†…„……ƒ††………„†††„„…†ƒ…„‚„ƒƒ…ƒƒ}€|{|~{||}~||~}€~}€~~€}}|€}~~~~|}}~{|||{{~ˆ‡„„ˆ†††‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡…††……†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ……ˆ…†‡†‡†‡†‡…‡‡†‡……†‡…‡†…‚„…††„„ƒ„„ƒ„†„………†…ƒ††…†…„†‡……„……ƒ„‡†ƒ‚ƒ„ƒ„‚~€|{}~{|{~~}{|~}~~}~}}~~|}||~~|}€|||}|||~z{{|~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†„…„‡†„…‡ƒ„…„…‡„…††…†„††‡‡††ˆ‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…‡‡…‡†‡†‡…ˆˆ‡‡…††‡…††„„„…†……„„„ƒ„…„†††…†„†…††……†‡…„ƒ„„ƒ„‡ƒ„‚„…ƒ€€€{{~~|||~}|||}}|}|~}|}}}|||}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††„…†…†…†…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡…†††‡‡‡…‡†ˆˆ‡‡…‡‡‡††‡„‚„ƒ„†…‡…„„„„„…†††††…‡……‡…†…†…„ƒ„ƒƒ„‡ƒ€‚ƒ„‚‚‚€{}~~|||~}|}}|}{||{||}}{{{}|{~}{|}}|}}~}|zz{{||ˆ‡‚††††‡††…ƒ…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡ˆˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡…‡‡††‡‡…‡†ˆˆ‡†…‡‡ˆ††ˆ„ƒ„„ƒ††‡……„„„…†††††…†‡††‡††„†…ƒƒƒƒ‚ƒ†ƒ~‚‚ƒ€ƒ‚|~~||}}|}}|~{{{z{|||{{{~{|}{z{~||||}~}{z|z||‰‡ƒ†…†…††…„„……………„ƒ„†„‚„„|€†‚……†……†…„‡‡ˆ‡ˆ†…‰Š‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……ˆƒ„†…ƒ††‡†…„ƒ……†††††…††‡…‡‡…ƒ……ƒ‚‚ƒ…‚ƒ~‚ƒ~~~||}}{}}|~zz{y{|}{{{{~||||z{}||||~}|{{{{|{‰‡„†„†„††…„………„„ƒ„‚€ƒ†‚‚z„Œ{€„…‡†††…„‡ˆ‡‡‡……‡Š‡ƒ‡…††ˆ†…‡„†‡‰††ˆˆ‡‡†‡ˆ†„†††‡……ˆƒ„…„‡††‡……„ƒ……††‡††…†††…††„ƒ„…‚‚€„ƒƒ‚}~ƒ~€||}}~}{}}|}yzzy{}}zz{{}|}||zz}||}|~~€{{{|~}|ˆ‡…†…‡„†„……………ƒƒƒ€‚…‚€€}|{„…††„…„„‡‡†††…„†‰†‚†„†††……‡†‡ˆ‰†…ˆ‡‰‡††‡…„†……‡…„‡ƒ„…„ˆ††ˆ……„‚……†…††‡„…†††…†‚ƒƒ…€€€ƒƒ€|€~~‚€}€||}~}~{~}||yzzyz}}yz{{|{|{{z{}}|}|~~|{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€ƒ~~~€yz}€ƒƒ…‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ……ˆ‡‰‡†………ƒ†„…‡ƒ„†„„…„‡†…†…†„‚……†††††„…††………‚‚ƒƒ~€€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|{{{{|}}}|~}|||~|{‡……††††„…„…ƒ…‚€€€€~‚‚}~{‚ƒƒ…†…„ƒƒ†ƒƒ„‚€…‡…‚ƒƒ„„„††‡‡‡……ˆ†‰‡…„„„‚…ƒ„†‚ƒ…„…†„‡†………†ƒ„…„…†…†„„…„…ƒ…„€€‚ƒ~€ƒ{€}}‚~~~~~~}}{|{zyzzyz{|yzzz{{|z{{{|}~}}€}}||}€}|†ƒ††††…ƒ„ƒ…‚…€€€~‚|~~€€‚‚‚„„ƒ‚‚„€ƒ‚€„…„‚€‚ƒƒ„……‡††„…‡…‡…†‚ƒ‚‚ƒ‚‚…ƒ…„„†„††‡††…‚„„ƒ„………ƒ„ƒƒ„‚„„€‚‚~}~~~„~{||€}€}~ƒ|~~}}~{~{{zy{zyzz{yzzz{{|z||||~~}|}||}€~€†„……„‡„„ƒ‚†‚ƒ€€~~€}~‚|}~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡†……ƒƒƒƒ„……„ƒƒ‚„ƒƒ€€~}}~~|~ƒ~|~||€~‚~‚|~}}|||{{zzzzy{yzzyzzz{|y{}{{~€}~}}}€€€†„„…„…‚„‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„…ƒ‚ƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚€…ƒ~€~|}~}|~ƒ}{~|}€ƒ}}€~}|||}{{zyzyy{yzzyzz{{{z{}||‚€~€€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌËËËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFK=8765999<>9?<C9;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937676=;>:=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<:<<98:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA>;A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÔÔÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9>CE?<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËÊÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø×××××ØÙØØØØØØØØÙÙÙÙØ××××××Ø×××××Ö×ÚÚÚÚÚÚÚÚÚÚÚÛÜÜ×ÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILN@99:4;A<7=9AC=@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÏÐÏÏÏÏÏÏÏÏÏÏÏÏÖÞÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¸·©§§§§§§§§§§§§¦®¹¸¸¸¸¸¸¸¸¸¸¸¹°ŠŠŠŠŠŠŠŠŠŠŠŠ‹‡½æáââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVM<::77>C>8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÌÐÒÒÒÒÒÒÒÒÒÒÒÒÑÞìëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§££££££££££££ †„„„„„„„„„„„„‚’¥£££££££££££¥•SRSSSSSSSSSSSKªòëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;?C>6:7>?;<B@8<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÌÌÑÒÒÒÒÒÒÒÒÒÒÒÒÑÝêééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤¥¢‰‡‡‡‡‡‡‡‡‡‡‡‡…•¦¤¤¤¤¤¤¤¤¤¤¤¦—WWWWWWWWWWWWWO«ñêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;?@@8:;8<<<<>::;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÍÐÒÒÒÒÒÒÒÒÑÑÑÑÐÜèççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©©§ŽŽŽŽŽŒšª©©©©©©©©©©©«žbabbbbbbbbbbb[¯ïééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB>;=:9;:=<;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÎÎÎÎÎÎÎÎÍÍÍÍÍÍÎÏÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÎÎÏÎÎÏÎÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÒÐÐÐÐÐÏÏÏÏÏÏÏÏÎÐÑÒÒÒÒÒÒÒÒÒÒÒÒÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÔØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<7@A<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÎÑÔÏÏÎÐÓÐÎÒÔÕÔÐÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××ÖØØØØØÙÙÙÙÙÙÙÙÙØ×ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?89:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÎÓ»ÏÏÒ¹¾Ôœ‚„ŠÆÏÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<=B>BB@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÎÒµ•›³ÔÀ”°œ±–¸¹¯¡ÒÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?><7:>9?D>@98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÏџ ª®Ö¢ ‹‘Ó}~¯°ÑÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<<96?B?B:647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÏÑҚ±Ï˜‡ºÔÒ͞žÃÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8E@?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÏÏÖ§™³È™Ÿ ÒÓÀ  ÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<==964:99::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÏÏÕ¥™´¾©¯‘¡¹×¯¢©ÔÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:<?>=<9@<<::9?@==<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÐÐÖ¥™µ¿žš­›©Ø£¡ºÔÑÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CFCAA8;?<=;<<7558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÐÐÕ¥šµÆ–¦Å˜¢ÑžŸÉÒÑÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF?HHGE@<<>><==<756:969;::;8@?:<<9<>=;;:?9?:;9=>=><;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦ÓÐÕ¥™³Ñšœ››­ÇŸ¡ÒÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@C;557<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡ÇÒÖ£š°Ù¥«¤žÅ´¤¦ÖÒÒÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKL@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÓÑÕµ‚ÃÕ̓§×¹ƒ¿ÕÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<<?GEGKH=657:979:;:<=9>99:8;=>>A>=9<<:=>>:=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÑÑÂÔÒÔ˽ÕÒÑÂÓÒÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?AELLA=775;8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÒÒÔÒÒÒÓÕÓÓÓÕÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEJ=>786977899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9699:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:69896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EIKAALD??;9889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEHIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDI;AA;<886586987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGJB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<BA<;876797799=?A?<:9@?<>B?:8776=?@@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD88867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE><HF89757875898;>>=;89A>=@?A>7596;>AB??@@AB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCEEC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELBA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?BGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<<DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGHNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAD?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€iixsg~‰‰xp‚†{w}~…Š½ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€‚wt|„‚}sp€Šx‚yƒÈÞÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsnupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿¼½¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»ºº¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545659756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¸¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjcmgb\XQPQKTJB:IQ?A7<94:565455588686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¸¸¸¹¹¹¹¹¹¹º¹¸¸¸·······¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µ¶¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸¸·¸¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶·····¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨¨¨¨§¨©©ª§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸········¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::9:9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥¤¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§¦¥§¨¨¦¥¥¨¯´¶·¶µ´¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©«««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤¤£¢¢£¢¡ŸŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž¤¤¡ŸžŸ  œœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=6789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥£¢¡¡¡¡¢£¥§¦¦§¬«¨¦ œ›¡¡ž››šœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¦¦§§§§Ÿ›š›¢ š–—”š›š——˜™šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜˜™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥£¢¥¦¦¥¦§¦¦ ›™›¡ —“’”™šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB?DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥¦§¦¦¢žœŸ¡ ˜¡¬——›˜–—–˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;<;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¦¦¥¥¦§¦¥¥¦§¥¥£  ¡¡Ÿ™™š–˜›šžœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡¡¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢¢¢¤¥¤¦¥¥¤¤£¢¢¡œœ¢j‰›œš›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œŸ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸžŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::78:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸ   ¡¢¥¶©£¤¤¢¡¡žš™¥VŽ›šš˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢Ÿ›ž¡¢£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œ››œŸžœœœœŸ   ¡¡¡  ¡  §ª°¨ ¡ žœ›š¢Y]”š›œ™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥¤¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¢¢¢¡¡ ¦¢€«¥Ÿžš™™§Uf•œž›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›š›šš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>99;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤¤¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ ŸžŸ     Ÿªwv­¢žœššœ¤kai•œŸžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›šš››š˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9<<>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœœœžŸž¨ŒiŒ«œ››œ —nik–žœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:<>9?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››››œ›š£‘yuŸœšœ ˆkik’Ÿœžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™™šš£”x|…˜šœž™}jgl’Ÿœœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›œš™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š›››œœ›™™™š œ‹ž€~˜ œ…fm” žœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ››››››œ™™™šœ§¡‘qe¦¬¡hyk—ŸžŸžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ›››››œš˜™˜¡­’wef¦—šXg}xž  Ÿžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_^]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜˜——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜™—§¥xNJp›„„RDax‚››žœœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±´­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=:F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œš››œ›˜™š˜˜™›šš—«™N7<t’}pS?6azŽ’’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨ª¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‘‹‘‹Œ‘–­sTpW|°©™ZgnHk}ˆ‚‹†‰Š‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜ž—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VQQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹Œ†Š‹‹‰‡„†ƒ~–¤\…›|Êűŝ~zPx‚‚’†„„…ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹Ž‹‰‰…‚‚~~’‘rÏ×ÍÕ¦œ¹¼k]r]g€…Ž‹†”’‹—”—’˜¡–ž–•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¦›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ‚†‹‡ˆ…„ˆˆŠ„‚|™wšÑ½ÇÓÇÁ´œw¥¨cbŠŠŽ‹™œ””” ššŸ¢­±®©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPEMISWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‘Œˆ‹‹ˆ’Œ›o¢¦•¹¬¢¡‰…vaȋZˆŠ‰””˜•œšž¨®²°°µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWMO_^\NUUbQDTM;?9<895875795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš™‘ž¡“—›¡šžœ£ „“|¥…‹wupl¦—a‹˜šŒ”š—œ› ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUJTOOJDPK_bXZQ\T`MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ªª©§¢¥¨©¬ªª¯§–~Xr†yy€mkiuxxz ¡¤ž›š¤§¤©«®¬¥¤¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdWOYKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®««¬¤¡¢¥©¨§«©…pR`tqrzifbikp|…¢©§ ¢¡®¬«ª§­®¨¥¤©©ª©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_VZNRNQOSe\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢™œ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨§¦¨©§©©¤¨¦š¤¦¢£°˜piOVxvt|hadf__n}Š ¤  Ÿ¡¡¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOXO^ddlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤Ÿ¢ £§¢¦­§°²©|icIRsuxh`cjZ[bkuƒ‘¡  £™–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvxb_\UYQUW[c_s_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?B?:8:>?C@DA:;>=@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯««¬¨¨«¯©¨ª©¢ ¡¨©­µº¼½¬ŠmgaBZnp}~na_f[Yaahpxš ¡¢™–ž›ŸŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸŸ¡¦¢›—’šš •|wo}yf[[`_Z\V\hdocmiib^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¢ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£ £«ª§®¹ÁÆÌÅ·¥ŽrhiZ?SpoqlthaaZX_cabjqv{ŒŸ§ž¡š–ž¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¡™˜¥ ¤§ª©¨ª­¬¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxjb[__\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>BE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢ ª´¿ÎÙÛꫜˆo`abSCJyk`bml[[WZY][Z^cffhw¥¯§¥™¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨¨«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥¡¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxxxc[RYT__amivkphiibZSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶´º±ª®´±°²´µ¼ÎÚÝÔÀ¤Šve]YZ\SJCmj”ž”VTXW]\]]XUW[i~•ªÁǺ¶¡§ª¬§«©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš’–””˜“š˜Š‹‡€€|‚xa^YTai`ftotitdidb[LK>:9898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÄÇÃù½ÀÆÎÑÍ·’ud[YZWSIUoª³¦NU^ab___fw§º¾ÁÅÅ´¶¶©¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`b_^kcbnxuwnm[bRV\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAA;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–••‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±°§¼¼¾ÅÄÆÉÇÅÆ»ÅÁÅÆÁ¾¼ÌÄ°‘o\UXSPS¡µ›NY[]]`mŽªºÁµ¹©§±µ«µ²­³­©®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|~„jfhaklgnurruqg^`\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8BBBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÄ¿ÃÃÆÆÁ±’¿¿Îμ•iXWZL™¹“LTYW`¦¼°¦«¬²¦ª©©«­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|uklndomiqxozjia]gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÄÄŵÀ·³¼Áƾ©yXUQŠ·†LSU]„ ¦·¯¥­´´­®¥¤£§¤  ¥™ª´±¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyy{wnkihvZgrxsyff^d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÊÆÄÃÄž¸½Áÿǽ–lRZiZQRd”«Ÿ¦´²­¬¸µ²¬©£¡­©¬§­Ÿ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuuefijh^jonyxcba`^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÎÏÌÃÇÆÈÉÈÈÉÇÅÉÇÈÇ¿ÄÇÄÄÆÉÎʜVHOPk­»·À½¾¹¼º¼º¼¬­¦©»º¹·¿²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqocagvijjtnyl]d[U`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÌÐÍÇÌÉÂÂÇÂËËÈÇÌÉÍÅÅÅÃÅÄÉËÑÓ¤RL`°ÇÀÉÍÆÄÁÄÇÁ¼¾´±°°Â¾¾ÁÆ¿¾¸¶Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`kjwlifuotc]bTWUSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<9>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÄÇÈÆÒÉÁÃÿ¿¾ÄËÈÊËɼ¼ÈÇÉÍÈÃÈÉÉÅÅÂÃÁÂÆÆÆÈΊI“ÎÌÇÌÐŶ¿¿ÀÀº»½µ³³À¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrpfegcjdbkmno^Y]VVNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾƹ»Ãº¸¹¼¾ÁÇÁÆ»¹ÈÈÃÅÄÀÃÁÁÀÄÁ¾½ÁÀÀÀŪN¤ÑÌÅÉÑÁ¯½½¸¹»»¾·´±¹¾³¼¾±¹µ¸»¶¼´µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfadbaccdjcgc[ZZ]YQOE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶·´´µ¿»½¿¹¾ºº´À¸µ·²®º»·À·¼ÊÏÁ»¿À¼»Ä½ºÀÄ¿½½¸¼ÀįSœÌÄÀÁÉ¿°Á¿º·»¾¹µ¸´¸¼´½¸µ´°³¼±··¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|yˆ}qdabchjggiei^VVTYOSLF8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“““˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´´±°µ·µ»Á¸¾¹¿¼¼·´·¯®·µ¹¿»ÁՎ¼¾»ÃµºÇ·¶¹»¼¸¹µºÄɪT“È¿¿»Á¾¹Æ½Â¿¼Å¸¶·´¸¶¶»»¹¶´·ºµ³¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒyqmfefpjekhXYOKKKRJLHD9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’™”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿¾¼²­¯¬±°·¼·»½ÁĹ··¶µ¹¹º»¿¼ÏÅy­Ë½Ç·¹¸­¶´·¹³µ²»ÅʟU‹Ê¿¿¾½¼¿ÈÃÅžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~‡}knqgqktfbn`\THKKDJCCG?:;8><7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘Ž˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼»À·ª­¤®°¸»²½¾»Ä¶µ¸µ·¿¾Ä¼ÂÄׯv„¾ÈÏÂÀ¸®µµ»½·¹±¾Ãǔ\†Îÿ¾½¼ÇÌÇÇÄǽµµ¶Á½»»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†€rfljntoxcgb\cQKUHEECGC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?>??FD@A?>:7?@CC?@=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼ªª£°¹½¼²¼¾¼Å¸±¸¹¼ÆÉÊÂÇÉћtw±ÑÑÌÊĵº¿ÄȾ¾´¾¿¿…jzËƾÁ¼¿ÃÌÊÇÅÆÀ¹½¼Ä¿¿¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒ‚tolltlln_c^abNHN?E@?DC;;::;:8;<:9<>::>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´»Åк¾¼Ä¾·¼À¿ÉÏÇÈÊʈvw¨ÌÌËÍÊÆÂÃËÎÁ¼¸¼¹¯‚|m¼ÈÄÀÀ¿ÄÀÊÉÃÃÄùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{zˆ{mmx|`qd[^__TI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA??ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸´¼·»º¬Ûþ¶¾À¾¾º¦œª³·ÃÀ¦|z|ŸÄÆËÈÁÃÀÀÉÊÁ¿»¹±£˜Š~°ÈÅÄ¿ÀÁ¿ËÇÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}‚znsxthp^\_\ZQEEDMIAD=H;;59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘—žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯··²µ³·¹¼»¶»»Å¶m®Î½¶¹À¼ª}nhnmt‚—™u{œ¾¿ÆÀ¹À¼¾ÅĽ½¸±¯§¬——ÊÃü½¿¿Ãþ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸··½¹»±¶²ÈÀ»¶´±°·¬³©°­­´·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|wlv{qni\``YSPAFIGK@ECH<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿš›œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹Àͱv‚³½¶µÁ¤†iZ^`NS[\pvz…¤¸·Âº³»·»½¿º»»¯¢¬²¢¨‚¾Åþ¼¿»»¸¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ°µ´´½º¾ºº»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰{‚zsvvwoqa_f][UJ=??GF=GCC9:5;99><<::<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Âɦ„x‹¡¯µœjfgVY_IIMPTo{‹©°·¾¹²µ²¼¹¼¶¹¾µ–¯À°µx¬ÊÃÀ½¿¹³®²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|quwtwrl_ca\^OIB?=IDFMD@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·¿Æ¨‡{vŒ¡˜_SCYUHbjUOEJe‘¥¯¯¶ºµ´²¬¼¹¸µ¸Á½§Â²²v§Ê¿¹ºµ®¥¬³±¦°­¨ Ÿ¥­¶µÂ·¶´¥¨ª¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´¶¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wp|ovsnc^gY]]SONA>JB@KJ@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³²­¶º¯­¼³¸¸¿´yˆnNK?eYBOx“hMC^…±µ³µ²´¯¬»º¸¶¹¿ÅxŽ¸©Ÿf«¿¸µ²±­­Ÿ¤¦§¤¥œ–™™™Ÿ©®¹¬««Ÿ¥¨¤«®¯§°«¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmujl]\kU][PNHDGMBFNF8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹º¶¹»µµ³·¶•Œˆ…|XFAO‡XJJYxŽƒcAU£¹³´²°±­°¹¸¶»·»¼’¤³®¤t¬°©«­«£¨¡ž—— •’–—˜Ÿ¨®¤£¤ ¢¦¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬ª¯£¤£¡© ›“Ž”’’™–š¤¥ Ÿž§˜•’”™ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wrxhutoeUadW]QOMH@IRDMC=8875:7<>9;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯²¼©˜™•hM?SxqPIIKh€ZEU°º±¬³¯®¬­¶¶²´µ®©§ž™›žŸ¦¨ž ¨©Ÿ¡§–›–—Ž”–—›¤¨  ¢¢¢¥¥££ ž¥ ¤¬¥¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›ª¨««Ÿ¦¢›£œ•Œ“—•–˜Ÿžž›™¦—“’–¢ ¥¢¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦¡ˆxƒ|vzcwln]QiUPOGPMLCPQ@>;>49:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¤¬¨½Âª¥¼gDS›}QXIKaJVbeeƒ¯µª²´®ª«¯°²³­¥‘—“— Ÿ¢ œ£¤Ÿž¨”›–—Œ—‘—“˜¢ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨¨œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£žžžš—š«¦ª±£¥¨ž œ•“‘‘™–•˜—Ÿ˜œ™›¤™—”•š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’~|uv}nk{dhVRdNJHGOSNKNH<E@<2?859;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜——–¡¨¬®¶·º¹º··»®¨ ¡© «Æ¿ÊŸOAt˜qPnJLcfut`]bt’²¯®³µª¦¬«¢›™”‘•–˜˜œŸ¢¢œ¤žš¤———–’‘‘“š—› ¤ªž¡¡ž¦§ª¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¢¥¢š™ž¯¨®²«¥ªª ›˜˜˜•“–š“••š–›——˜¡žœœ–›¡›žš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}wy|eyy`bSVaHIJKSTISQM9?B67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—“’œž¤¨®­¬««¯ª¯©ž—ž¥œ¥ÆƌWSJf¤Yf}or[Rkc\gb`m‘´°°¸¬¦¡œš”—š™Ž‘•‘ŒŽ“™¢œ—£™š—˜™”™˜–›Ÿ¥¦© ¦£ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§¡ £±®²±´ª²®£™œž¡˜››š˜™›”–›–™œ¥¡ š£¡šœ™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ ž ž ¥¡žž¥ ¦™{|vvsh‚le[SZZMQJOOVMSMB7>C78=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’‘œ˜¡ª¢§ ž§¡¥Ÿœ’›¢šŸª£ŒyUirwupcwvXWb`di[ZWh­®¬¯§Ÿž¢ –“› ›™—’“Ÿœ¡£›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬©¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½¶¾°¬±®­©ª´±°¨«¨³¶¸³¸­²´¤ ¥ ¬¡¡¢¡ š˜–•Ÿ››˜¥¡ ž£¡ ž›œ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚€}xvjwu^m[RaIRUHFUWJCMG=KH8F<77;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“Ÿ™¨®Ÿ§žœ¡žš™’˜ž›¡¡ ¤o‚p`cXL[RZLLQYRHONH™¬ª©¤ŸŸ™’’”˜˜––•Œˆ‹Ž•œž—ž™¦Ÿ ¨¥±ª§®£«®¶°´²±®¶¸½¿º­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«®±¹¸¼¯³°µÂ¼·¾³³µ¢¬¢©¨²©«¨§¨š™žšª§ ™§ ŸŸ¨¨¥¤žª¢¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰……~vrmiwmhm\X\CWNJGMGCFM<>L>4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜™ª ±¢·¤°¦Ÿž—˜•™žšœ£žœ‰bW^e`WMQG=>@CD?>BRx©­©ª¥ŸžŸ¢£žšœ›”“•”ž˜”…š š«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶»»ÀĹ½»¬¯§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¹Â¾¸³»ÆĽü·³ª³­ª³´¯³®ª¯£¬¨¶±­£°¦ £°±®°¤¥¯£¡ š¡¦¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¤ž¦š›¢¤žŸ›››œ‡†|trkkurqhV\QFUHDJPI?EA4FH95<>7;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž  œœ˜šŸ š Ÿ•|_^e`QFD;C>F<>96N~ª³§££¢ ž¥«¦ž˜œ”‘™™•ŒŠ†ˆ†xmˆ ¤¢«¬´¼¶Ã¾¾³»ÁÃÂÅÀ¿ÂÆÆÅÃÈÂÀÅÈÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌÌÌÒǾ¿À¾ÇÆ·ÃÊÊÃÁÇ¿º´º»µ»·°¶²ªº²®»¸¿»º«¸­«ª¸»µ¼®®¹£¦£ž¦¥¢£©¦™›Ÿ™š§ª§ ¡¡¤˜”£–”™‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ…~zrkcioxkeY[FKLEDTMECE7:?:549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ²²¸§¡¡«ª¡œž¡¡›š}riaWNE>IY|oaA=\Ž®¬ ™››žž™———’——“ŽŒ‚ƒ‚wrqmp¦­®´¹Å»ÍÇË¿ÂÌÍÍÌÇÉÑÌÌÌÇÉÅÆÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÑÓÍÔÐÓÓÌÊÂÅÆÆÊÈÏÀÉÑÌÇÆÈƼÃÁ¿¿¿¶¾³­¿ÀÃÃÇÅÇį¿¹²¸¼Äº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›‹™‰•˜› Ÿ£—žš““‹•…ytsebgrof^ZZCNLDFPIDC@55589B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>9;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›¢¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¤¨¬­ª £žœž•if\TID@?J†ž¤˜ƒ ²­£žœŸš˜—”’”–‘Œ‡„ƒˆ‡ƒ€€yqroly¤¶º¹¾ËÁÓÒÓÈÍÎÑÓÑÒÑÐÑÑÍÎÎÐÅÎÔÕØÒ×ÍÆÇÉÌÃÅÊÏÊÓ×Ò×ÒÕÖÓÔÈÌÇÌÍÊÓÍÎÓÍÆÉÊÊÂÇÌÇÉÉƿó³ÈÅËËËÏÇÊ¿¾¿½ÁÆÅÍÌÉÉÀÃÀ®¯³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›•Œ†‘‹€{ruvgcgvjdVWQDNF@IQC>B<:22A<E<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<@?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­³·¬®£ž£¢¡›aSLJDC?CR°Ñ½²¯¦œœœ ¤¡š”“•”‰}xqkebhroq{…Š€upnqtp…³Ã¾ÅÑÐ×ÖÖÒÖÎÔÖ×ÔÓÑÓÔÔÓÏÑÄÐÓÖØÕÖÒËÉÎÑËÆÍÑÊÒÕÖÙÖ×Ó×ØÎÒÊÏÑÌÏÐÌÓÐÀÉÈÊÄÌÌÌÏÏÅÇȶÀËÀÒÍÌÐÇÊÉÀÄÃÈÎÍÐÑÏÍÊÈ͸·»¨Ÿ¥«§Ÿ˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„}xsvpc`erb]R\IJGAEIJ>;A8=5586;86:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÁűµ¨¡¤¥ ¢¡YI@ADAFQv²¯¦š”—Ÿœš  ž›œš•‰wica__`_^__]alusppolrqu’ÄÈÇÔÕ×××Ó×ÐÕÔÚÔÔÎÏÕÔÔÑÑÌÑÎÓ×ÖÓÕÐÏÒÓÑÉÓÑÈÐØ×ØÑØÒ×ÙÔÕÌÏÏÊÍÒËÏÑÀÆÃÈÆÏÎÑÑÒÈÌÍÀËÍÆÓÏÌÏÈÅËÇÇÉÌÊÔÔÑÕÏÒÌÓ¹ű¥¨µ®§›¨«¥²¨°³­¬““Žˆ‹Žƒ‹„Ž™“™‚…Œ|zqstmacim_VP_JJCFCRM@<>43:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><?@=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯­ªª«¥®·¨«·ØÔÕÙÙÑÎп¼Ìɶ¾®¦ª¨¡£«eC8=>DX‚ª¨Ÿ—•—™šœŸ˜œœ’}qecb__a_^a`_``_`emppnkorwwœÌÁÓÕÓØØÖÙÑÒÒ×ÏÓÎËÒÍÕÔÑÊÏÍÓÖÒÑÖÍÏÕÕÑÅÑÔÊÐÔÕÖÎÓÑØ××ØËÈÎÄÉÏÌÊÍÀÊÀÉÊÎÎÏËÐÎÎÌÏÏÈÌÐÐËÎËÃÊÇÉÍËÌÒÓÍÓÒÑÐÐʽȹ°®»¹µ«¶°­¨¸­³¾»±š ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…‰zvopokadnpaW\ZIFFDMXE;@=33<<87855;>@=9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ¤§Ÿ¸¶µµ¬¤¬®¾´°ÀØÒ×ÚÜÖÎÍÊÃÒÏÁÁ±©¬­©¤±zHFB;W¡›•“–›žžžœ“–—”ˆk^^^adb``aa``a^__^\bmroostvvy¤¿ÌÕÑÖÔÓØÖÎÎÓËÎÎÅÎÊÒÒÏÇÎÍÎÔÌÎÒÍË×ÖÐÌÑÔËÌÐÒÓÊÎÑÕÒÕÕÊÀÊÂÅÍÂÈÊÃÌÄÆÉÊËÏËÎÍÐÎÓÌÆÉÐÍÉÇËÅÇÁÆÊÌÍÐÒÇÐÏÎÎÌÐÅÇÁ¸¹½Ãýø²²¾±»Ãõª˜¥¡˜–’••’‹”š‘””•‚‰†yqrkmg``qhYXhVMGLIPQB;C>;68:8::57==A;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÄÂÁ¿»µ²±ÇøÊÕÖÙÚÛØÌÌÏÈÖÕĵ¯´¨Ÿ­—xlpqyšŒ—•“‘‘•–•‹|eabb`]^aca``_`aa`_][]grrprsqmry¥ÇÓÏËÐÐÓÔÊÅÉÉÆÆ¿ÃÅÏÎÇÅÇÍÊÒÈËÎÍÆÑÒÐÎÌÔÊÇËÎÏÇÇÏÒËÐÏƺĿÆʽÂÇÉÎÅÃÇÀÇÍÈÄÌËÌÏÈÄÄÐÉÆÂÆÈÄ¿ÁÇÌËÌÏÂËÌÉÇËÐÄÅÇ»ÇÃÈÉÂÏÁ½¼¿°ÁÉƹ½ª°²§¥¢œ˜›£™—™‘•˜‰‚xotdk`^fqa[W`GHHGIMTG?J=64355==48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ¼¹ÌÌÆÐÕÕØÚÛØÐÉÏÏÑÓÈ·»»­£¶~hƒ…¤«“–…ƒƒƒ}„„~s_[^^^`^`cdc_]]^_``_[Z\`lrqookloo}¹ÑÈÉÊÏËÍĺÀû»ºº¾ÉÆÂÃÀÃÈÊÉÈÊÈÁÅÌÆÈÊÍÉÄÂËÉÁÁËÐÅËÈ¿¹Â»ÆǾÀÆÏËÄÀûÉÇɼÉÇÅÊÀ¾ÂËÆÅľƽ¼ÁÃÅÌÅƼÀÉÃÅÇÒÅÁÉ¿ÊÉÆÈÆÑÃÃÆïÄËÇÃÊ·¿¼º´©¬¤¥˜Ÿ˜¬£¡¦›£ ›•|wstfiZanmZ\XRDLFBGELDFS@54335?<3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ÊÏÑÌÇÂÃÆÍÎÎÌÕÏÕÚØÙÏËÒÍÍÎÈÁµÃ¾±¯¶l^z}¡‘Š’–†z€……vxurp_[[]``bcdded`\\]]_^`[YZ\borokikposÇ½ÊÅËÀÆ°¶º²²³²±Â¼¼¼º¸ÁÁÁľ½¹½¿¹ÄÊÅƽÆÀ¸»ÄÉ¿ÁÉ»·»ºÆÿ¼ÁÎÃƾ¾µÁ½Ã»½Ç»Ãº´½ÆÄ·¿¶¶¾¿»Ìý¶ºÈ»¿¾ËÃÁÆÂÅÉÇÉÆÐÆÂÌȲÇÉÃÎÌÀÅÿ½²·°²§¨¨¹°¥­°ª­¬”zvwjdg`hodV^YJFJFHKAFBFJ@9:658854;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÅÂÄÈÎÒÊÊÉÆÍÍÎÑÈÐÅÕÔÕ×ÍÊÎÅÉÅÇÁ¹Å½«®¦`duƒ“‹ˆ‹„x††~„{ttc\\]^``bcbbdeb]\[\^\^]Z[\^hsqmggnory½ÌÀúÀ¸­°±§ª­¬§¸´¶´³³´»¶½±·°µ¯²»Â¼Áļ¿»µ²º¾À¸È¹´»·Á½¸½ÇÁļµ¯²¶»¿´Å·»µ«¹½¾À½±º¶°·º³Æ¼·¯»¿µ·µÅ¼¾ÃÅÀÄÅÆÇËÅÀÆÆ»ÇËÀÏÉÇÃÆÁ÷ý½¶¹¾Ç¿¬µ»µ·¶Žytxggebkn^V^`FKHHJFBDAEE?<:566633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÍÈÅÈÍÌÐÌÍÈÉÈÊÈÊÄÐÍÒÏÍÅÇÁÆÀ¿º·É¶ª°™[gpŠ…ˆ‰zx~††vw|sh]]]]_`_`da^cec__\[^\]^Z[[]_lpnifjmnr|¤ÇÀ¸¸µ°«¬§ž¢©§žª¬³­ª¬ª´­¶±³©®§¬³»º¶Ã¹ºº±«µ¹»´Âº°À±¾¼»¶¼È¹Ã¶­ª¨°²À¶¸½°±§±³µ»¼«®µ¦®¶®»²±ª¹°®»®»¸»ÀÀ¾ºÃ¿ÆÃÅÀ¼ÆÁÇ˸ÅÇÅ¿ÇÃúÄÆ»ÆÉÌ˳¹Â½»³‰svvki`bliYXW[ALKMJEAC?FA:9:996854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÅÎÒËÃÅÁÄÐÇÍÁÃÆ¿ÄÄÃÃÊÂÉÊ¿À¼Âº³µµÃ®ª°’[j’‡Ž{x}‰…z{„wn^]\\]_`__dcbcdb`_]Z[ZZ]ZZYZ\enohfhiknr­º°µ®¥¤§§š ¤ šœ¥«®¤¨¢«ª¬«°¤¦Ÿª­´¶±½¹¯·°¨®¸´³¼¸´¼¯¸¹µ²¼Á²Á®¥¨£«±²³¨½ª«¨«¬®µ³¥¨®¡¤¯©²¦¨¨®¦¨·¬±²·ºº»²¼¾¾¾Ä¿µÂÁÇÈ·¾ÀÄ·Äÿ»¿Ä¾ÄÈÌÊ¿¿ÃÀÀ©‡stsji\aodWWXPHYRSKFFE>?@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÐÏÍÃǹ¹ËÁ˾»É¶½Ã¾ºÊ·ÁÃÁ´¶¼¶±¯µ»­¨«’dmˆƒ‡‹€z}~xt~|swe_]\\^_`^_ccab`a_^]\ZXY[[YXZ\_fkfdgehjor…ª¥¬¥žœ¡¤”¤š—‘¡£©££Ÿ¥¦§¦­ œ¤¦­²°¶·§±­¨ª´«´º±¶¶®¶¹²°ºº±·¥ ¤Ÿ¦±¨¬©ºª¤§§¨§²­ §¦Ÿ›¤¦¬ŸŸ§¤ ¡±­­¬²´³´°µ¼¶»ÁÀ²»¾ÃÁ±¹¹Â³Á¾Àµ¸¼½¾¼ÂÇÅÃÄ¿ÀÄ „xqlbf`ko`UY_HNgOTHFKF<=@=:;;826536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;>97776788666;::;9:;<859<:>>@;È´¶½¸ºÀº½¶ ž”¡¦º¶«³³»³ÄÏÉËÃƸ·ÇÀÌ¿¸É·»Å¸³Å¸³¿À¬µ¼²¬¥¯³­¡£‘ir†…†€|xusomjiipi_`]\\\^__acb```a^\[\\XYXXXVX[^_dcbegggkmoˆ©Ÿ–•š¡–›¢˜•Œž¡¢§œ Ÿ¤¥¢§ž›£œ «°­±µ¤©ªª¬¬¤´¸­·°¬³¶¯³µ¯°ªŸžŸ£¢²¥¦ª¹­¢¦¦ ¨­«™ Ÿž™Ÿ¥šš£œœž¯©«¨ª¬­­°²¸¯¸¹º°¶¼»º«³²¹³½´¶±±¶µ¿¶½À¾Ã»º½—„{sk_e^ddXTW]IW\KPGJJGA<??@;?<05535:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»·ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÅÏÈÈÀÆ»»ÃÃϾ¹Ç¸·¾·²Â´±»»¬¹º±¢ž©«§˜žm~…†xrmomkb^aff]]^]]]\]_aabccba_\[[ZZYXXWWWXXXZ^bddeffhikr§œ“””š—š¡––›¢¡¨žœ¥§¢¥œ ¡›™¯®®¯²¡¥£®«§¢µ°²²¬©¯³§º³¦¶¡£Ÿ›£¡­£¢ª¶«££¦ž¥¦£–™—™› š—žœ­¡«¨£¤¦­«²³ªµ°²«²¹´¯ª¯²²³·³®©­®²¸±º¶º½À¸³±”†zuf_f^[YVSZUK[QLJEHKIB=?AA@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½¸½¿¶¾¼¿³¥£˜¥±Âµ¶½­´¸ÁÌÈƿŶÁÀÇηÀĽ³¹¹²¿¶±¹»­²´¯Ÿš¤ª ”šxƒ„xoqtqhechdc\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXWVWadecdeddhjv ›“““––ž–˜“— ¡œ–¡¡©¤ŸŸ©œ›«§¯°«œ£¤¸ª¡ ®¨¶ª§¨­±¤¸°¤· £œ™™ª§¡›­¹°£¡¤œ¢  “”¡”––›˜˜–—œ•Ÿ©ž©¤¢£ªª±­¨´¬ª§­³°¥«®³±°°¯¯§¨¨²®²µ°¼´º¸®£•‚zwe_aVYXSRSKM^LPLGHLKE=@>=B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾·½®§§¢ª»À½À¹®´¸ÁÌÇÅÂýŸÈ̲ÁÂÁ®¼»µ»¼µ¹¹°¯°ªœ™¡©”‘Š‹€€|wqilrtphhedfa\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWWV[bcbbcbbcfi•’”‹‘““š˜œ•–œŸœŸ–  §¦¤§¨  ¦ ª¯¦Ÿ¢£·¨¡¡¢¨³¢¥¨¥°¦±­¬µž¡–•©¢¢”­²±Ÿ££žž˜›“‹¡”‘“˜˜“—˜˜—ž§›§¢¢š¤¥¥«¤¥°§¥£«¬­¦¨®¯¯«¨ªª³¦¦«¯´±¯¼¶±¯¯ ’{xsea\[]XNLQHRaMVPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8847763321./2556;:8;7876<;:;;A8x»»±µ½°»±·¬ž¥¦¬·»¼Áź±¹µÄÉÉÀÃÆÅǶÅijÁ¿Å«··½¶½º»µ²«­¨™˜Ÿ£‹‰t‰ˆ~vncafihfgifil`]\[ZZZZ\]\[\^_\ZZ[YYZ[WUXWTTVURTRU``_`a_aacdi€’’ˆ“‘’œ”•–¤™ —œ ¥¢­¦¥¥¤¤£ª«¥šŸ¥±ª ¡ž¥«ž¨¢Ÿ®­©©®­¢¢¢•˜¢›œ«©±œ ¢ŸŸ—˜“Šž‘’“–˜˜”œ¡£¤¡¢• ¢¥¦›£«¥¢¤ª£«®¥®²©¦¥¦¦´¦ª¨­³µ´¹º°ª¬žŒsqo`[WVURFPNHZ\ORJTKSLEGJD8;;=<9667:9;:976977:;:=<<6;<8>598:88659:<<97?<9678452121..1426:8698598989;9@9{µ´¬´»²°«²­¨§¯¹¹³ÀȺµÀ¯ÅÈ̺ÁÊÌȵɼ±½ÃÉ­±¸Áµ¼À¼´µª¬¦–šœœ‰rˆƒ{tiijlgjlmkjle]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURRNQY]\]]^___bdmŒ‚…Ž˜’”’œš¢œ›¡©©«©¬§©¦¤™¥¯¥•™¥¯© œ™›¡ž¯šœ«´ ¦¦Ÿ£¤¡”“›––’©ª­š ¡¡›”Œ™ŽŒ‘Œ’–•ž¢ £œ£•› £¡—¢¨££¨« «¯¤®·¦£¤£¬­ª¨«¯³·²½µ³«¯˜…tsh[XYSUREXLQ[XMUOPLQRINJC=??A?=75799<<977:79:;<=>;7;;:=67:;8976989:6:=99576570141-+/434988::8::748=8?9~³­§³·¯¨¨¯®›©¨¬·¶«¼Ê»¶¿¬ËÆŸÁÎÏȳĺ·»Âȱ­¸¿·¼½»³µ¦© –˜™—ˆzt€vwnmhmmmpggifd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUSSNPQYZZZ]]\^_`e}Š€‰}ŠˆŒ–‘—™¢ › «ª¦¯¬¨±¥©š ­¡•–¥¨§˜šž®—™¨«™ ”¥¡Ÿ’‘’‘“•¨«¥š™™žž–ŽŒ‹“†‰ƒ‹’•‘ ž¡¤™–Ÿ•š¡¢ž”›¥¦¨¨¨ ±°¦±½¨ £¬´«®§°µ°¹µÀ±®±«‘~rsbVTVNRJGVPRRLLXNJLORGMKACFDD>A75889;9:7::7<=:;@>:9;9:?759:9876958779;85576661320-*.102877;99;8948;8@8´¬¦±·ª¥¢±«ª§©²°¤¶Æ´¹º³ÊŹºÁËÐʱ¶·¼½Áñ°±·­´´»³´¢£˜—•„€vkglnqnrkpkdege^ZYZYZZZZZZZ\\]\ZXXXYYWXWUUTRSUSVURNNNRWXYYYY\\]aj~x~t‡Œ…Žˆ—‰”“˜›˜ž©› «¦¦¬ž¨š¡¦œ“Ÿ£š——…„’›¤•£–––ˆ¢››”ŒŽŠš¥§œ••—›‘’‡”Ž‹Œ€‹’’’ š ¢–”˜™•¢¦™™¤¦©¦¡ ´²¨³¸¡œ£·¬ª®¤²²¦µ¼µ«¬±£‰ysn]NQQLODNNNPKFNNJJNNQIMJAHLHHC>858889:;69:68;99><8:>9;?8789:886857688974577820301*)-/12876:999984988A7w¶¦¤·±¥§¤ª¥ ©¦¤³ª¢²Ãµµ²³ÆƶºÃÊÌƳ¬¹½´¸À¯­©°ž¦®º¯­Ÿ™š••ˆ|ƒn__frpvqinieghj_XXXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQMMKLSWWVXXXX[]anpuoƒ‡‡ƒŽŠ“‘“¡šœ£¢¤™¥—¢œ•ˆ™šŒsƒ~Ž—–†‘š”ŽŽ{™Œ‚‰Š˜ £ž“˜–…Žƒ”~~tŠŽz‡“›šš’–Ž££Ž‰š ¡¤¤›¢´¯¬°­Ÿ™¦¸¦¦±¡°®œ°¼ª©¯ª™ƒxtdWMROPMCSNLPMBPQHINSMHJJDKMFKK=749888;;69;7:<9::;79?9>@79:<89764445874312585/0102)(,-02764789::65:87A7x·¡£´©¦¥¨£¦¥¦¦¦³§¥´Á¸°´°ÉÄ·¹ÁÎƽ³¬ºÁ¬­Ã­¨¢¦’¦¶­£ •–’~x~fWV_gfighnciigb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTQMMJHNSSSTUUVY[]jjpk~„{sNXr‚—†œ—‹”‘ ™•”–•–Š€”‰_;Vo|Œ”ŠŒ’Œ††s‹…—y{†“”ƒ•Ž‘ƒ†}“xqp†}Š‘—š™“‹ŠˆŸ˜‡ˆ–žš¡ —§®©­¨¨ž—®³¢¦®™¬«˜¨´£©­£“to`\OSRWLDTJPMLFNOIELQMKOJIMPFII=7599999:7:;:>>8:==7:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9y· £®¡¦¦ª ¦©§£©¯¨§´Â¹°µ°Ç·³½Ï¿¹¯®µÂ§ªÅª£˜ƒ”œ±¢š˜†”‹‡~su]PLQUYZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MORMKHFHNQQMORTVXZ`lngzsPB?•’‘}ˆ•Œ„Š›Ž–•Š’ˆ†•‡y‰`JQnx‹’„~„‹…m”wuvx„špQˆŠ†|~x”vhw†ˆ~Š‰–‹Ž‘“—Œ„Šˆ•„›‚„’š–ž”¤£¨©¥¤žœ±ª¡¤¤‘¦©–¢ªœ¢¦¨‰vng_]HQQSMIUMSILKOIHFJNLMTKQPOFIC=769:8:;;8:;8>?99>=8;<6;;478;6775344696/3/.125221/,')+*,4833989:99::::?9w¶œ£§Ÿ¡¯¡§¨¥§¨¯¬ªµ¼¶¸¶³Á»¶¨¹È¸¶¨¨µ¶ª²¼§ž–Š”¨–•Š~Žƒ‚}xqoXMKMMNLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDDINOhYNQSTUZnƒru}ih\T‰”ˆt~†|…Œ“‚’š‹{†€v€xsovqtŽŽz~Š«…y{hv{Žprmx‹’x{€{€vsr’xgu…„„…|•ŠˆŠ‹€„‹€”„|€˜•œ–‘Ÿ©žŸ  ©¥ž˜§¤’  –žŸ¤shb]]JWPRGKXROJLMRJJJLPHLQLRTMEHA=77;99>=:;<98@?::>=7==79937785675251472/2.,//200/-+(().12721987:8775:<;7v®™£¡˜Ÿ´©¯ª¥­«°±ª½´²¼¸¶º´±Ÿ·º²ª¬©¨²¯¢š‘”ŽœŽ‘~v†x|vooiXKHIHGEHHPTTTWWSTUUUVWWWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQQSV^t‚{xfvŒ–˜Ž|gyvx€‰}„˜’q‡|w{ok~­}t‹{†’|ufv|†logs|‰Œ‡€myq}qmvqhq~ŽpD‹…‚ƒ…wxzŒ†}Œ{u}Ž’˜‹’š›£–™œšž¡œ–‹¥šŽ—Ž–˜xomgc[XXUQJSUTOPNQVKNKOOJROINPLFD<<79;::?=9<:99??;8;=7<9999266856633611224.,,-..-0-+*''*.1362/876966527995y¦— ž–¡¦°¬®«¨©±¯±«¼¸¬»¾¸³¬§›°§¬›–¥©¤¡˜™…’y‰Ž‹Šuq{mupjmjXKFGEA@CDHLLMQRPQSTTTUVVWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNPQTX]eprlˆ§ªÀ~tyb{xo|y‰z}‹†omŒ’ytyjj€‚q–‘‹~–€I’˜nhx~‚midly…’†lrl|nr|†inps‰…†{~{wptt†‚yyp|ŽŒŠ”ƒ–—˜š’–—™—–Œƒ‰ž’‹’†–€ojoooYVXTRQYORTTRXUMNHMJMOKCINGF@:99;99:><9<;::=>:8:<9?868727565541432/024*+**-.+-*(*(',-1250,5567485HA895w™‘›™šŸ¥¬°£­ª¨µ¯®¬´¿«¼Ã¿¥¢š•¤˜ž„‹”¡¡˜™‘“‹sŽz€†Œ†totkpldljYNDFC@<>>AFFGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_IMOORWZQY\_§‡ašisye~omz‹‰v‚ˆ†tlš’tt|jjMy…“‰„Žg1v†sl~}ƒtfeu„„…€gilukq€|hqq|n“|t~}qqnvm‚wyujy‰‚ˆ‰ƒ–’’‹‘””Ž—€yˆ—ˆ†Š†€ˆwkkphfXRZWYY[MPUVYXNIHEJJHGC@GECG=998;9:9<:9;:::@<9:<98>787715234533645031.**+),,++)(+'),,226,,4775478iO8;5n’ˆš‘™–£¨­ž±ž§º¯«²°Â±»Ãǚ–”™‹Ž…z„˜”Œ†q‡‚t‡Œ†yprpoodpf_TFIC?<;9:?@ADCEGILOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOPQVLAIQIb¯² q{xl}lq‚‚…z„††yr¡•txsu”‡5q¨Ž¡¡„¢…vp‡|‡|tŒ®‰hgbjnrmp‚uioXupŽ›’wm{}mrnp€{svnbvƒ†€…ŠŠ‰‘‹‘‹‹ŽƒuxŠŽ€~ƒ€}Ž{sqqm`\]^[YX`_RN[ZXWLHJFJG?CABH?CD=;97=;:;;9:99;:?<88=:8;66651121253474531./,,+)*))***)(*)+/3DM2166643<vR7=7b’’ˆ–‘¤§Ÿ¯•¥´©®±®Á²»ÁŖŒ”€ˆ|n’‰ƒŠ‡†u‚„l•ˆˆ{txxlwnwci^JPG>?6449;;;=>@BEHLLLLNPQRTUVWXZXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL7CMRSDJ†v€||v~lvˆˆ|~…ƒŒ~u¢šz~†„™„›œa†ªŸ‹ƒzwˆ~‰‰Žs‹—„{]eqtz|wŠmhjbyo…‚zoxu…zptyxkni]v†|‡|‡‡ŽŠ’—ƒ…Œ†}q„„}uw{|‰wpstfg`[[^S[g^WPTX[UGJJDKG?F@DC>AA=;97<;;=<::99;;=>79>9985653244004645554-,)+('''&(())((+++/00Uq=23331E~W4=9\ŒxŠ€”Œ‘œŸ¦‘ ª ±¨¯À²»Åº–Ž‘”‡{†vkŒ‘‚}Š„Œxƒ€s „Š||p€~zgvkRWL@E211366688:<>AEGFGJKMOQQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMORLKT]YRJh„ˆ{‰y|q|Œz}‰‡~—‡v¡šˆ‡’”¥­ªH†®¯¯‹€“‹‚‹‚„’©‡€˜˜Šœtm|†‡}Žhghyn…‡‚…q„†Gl€wryvhmk_v}‚ˆ‡„‹y”œ‰‹ˆ‘zu‹v|xmpw~€ttrl[^^\ccXge\TOPVYPDLKFNICFCC@@CA=:88:::;;:888::?>6;>7595773344236656768;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|}‰…‡‘Ž–—’— ž­¡¦¸¯³½³—’‹˜‹}tp~‰’~}Œ‚’”}†~†¤‡ˆ‚ˆ…x‡ˆ~s„x_cWKB60./23124668:=>?BEGHJMNQSTUTTVUSQOGC?80,#‡[>?84.]–ps£UFIKMNPW`XpY\^i“‡•€„‚…‘“~…ˆ‘š•‚¡¡˜•››¦­“š»±§»Ç苌¡¥”Š‘|qƒžŸ‘œv†…‹‡ihp„t‡„Šq…‚w‡{v…}nvuf”Ž†‰ˆ‡ˆ‡ «¢–‰Ž—z‚ˆzyogkx{tle^[[^j^bg`ZOKNWRQIPJDNGCJDCADDA<:87=<:<:88778:==8<=68756623444576867<BB?<8:>CQ^e\G2'&,,--.1(?‹[.310Oƒ_4?;nupfwƒ{€ŒŽŠš›¤¡¬¦«¯°—‘‘„¡”„xwŒ”|~’…’•Š€’›Žƒ€ŒŠ‚‰ƒŠ€mpj]B@4--//..02234778;=?BDHINQRSRSSTRPOHDB<87/9D><<63.l“—MPHIKKKNV_cggmu›š’“‹Žšˆ“‹  ’£ª¥£¬“©¶¢¨Á®ǯxº”š|¡ž™„“…‚Ž¢Ÿ“˜’„Š…™‘–lpuŠŒ‚–ŒŽw„qm…Š–‘ƒ…ˆqˆ •†’‰Ž–¤µ©›”¢ƒ‡“ƒ}kjk}‚ƒuc^d`[gl]ll^WKGNRQMLLFIPCDMFBCEFB=997=<:;:987767;:6=:785456344566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYo‚ou†qv’†~—–š”žžœ§ ©–“˜žge¤š~„’‘y’ˆ‘’}Š„˜’‚€€‹Œ‰†‡…‰…xx~gMR>/..,/.-/000212467;?CENPRTPPQSQNPIED>;<:CF?><752<?R5HHHLLMNR^oŠ|s} ›§¥¢™¡—¢”œž¨ž¨«Ÿ¨¬©ª¶—«¿«¶ÈÈ·ÉÑϾ› pi«©Ÿ„“’…œ¡š›™§‘‘ˆ•¢››xz~”˜’¡“——”ž{w•’«²‰—Ÿ|”ž›’•˜£¢¦¶¯‘™¨‡–ˆlss}}si`^b`bhd`gf\REJKPOIILFFMCHLFGDBGEA:85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Ppt`m}awŽ}{”ŽŽŠŸ’—ž–›ª˜žªBD}‡‰‡˜x‚ŠŽ|Š†Ž‚€‰‹Š„’…ƒ†‰€†v^bP460-1/,.00//..0015>ABMQRSQRSTRNSLEE@<>=GG@A@8662<9;FHGIJNOQYm…w•Š£§ª´½¸¤­¬¬§¨´«°¶²²­»±³½œ³Ã«ºÉ˷ÿ¸¥¢°³¬­ª£‹–˜…¦¦ £—¦™¢«¨¥ˆ…”¤¡ «¡¤©›°‹•£¦·»›¡£°’¢¡£¡«¯¬²µ¢”¤ªˆ™‰’‰•zz~†€ibi]fc^dd^gg_[OCIHSNFHLFJGFFHAKFCFFA;87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLhcWioXz…v“…‡‚›ƒ’Œ’Úȝ–sV—ˆˆœ|†ŒŽŠŠz‡‚‡Žƒ…Œ…†ˆ’†‚„‰†ˆ‡‡pna@E64<2/110-,+-1.-4?CAMUQRSUUVUN[PGHE<>>FHCEA7;<5C;=FKIGHROPW’ „®£³ª²ÀÇê³Å¶¬³¿³¸¾¶¿´Á¶»º£¸Å¨¶Éǵ¾¹µ¨£´­°±›™’šŸˆ§¯«¥”vŸ¤—¡¬²´™–ª®¨®¶»²º¬¯µ¢±«±µ»·µ®´ §§¢§š©¯­²¹·¸§›¶¨Œ¤Ž‘“Ÿ†x‚„wZceWgbbd`af`[UJDDLUQHIJDIGEA@@KDBMG<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AFWQJL[ZQbcWyuq”}„†“u…€Œ{¿»£¼‚´”“›„ˆ’‰ˆy†€Œ’Œ‡…Ž‰‡€†ˆ…‰‡‘zxn]V@EM<6:46AB764//6CHCQ[OQUWU\VO^UIKKA@?GKFFD;>@7D7?BJJEFWTP^¤­£±´Ã¶¸ÁÌɶ»Ä½³³À¶¸Áµ¾¯·t±³¥ºÄ¤°Æ¹±³±´¨¤µ¶ª± ¢–›¢’¥°®¦­¬§¤˜ ¬´»¢¨²ºµ¼¿Ì¿ÅŽ½³Â·¹¸¿·º·¹¬¬°¥°ª­½°¼ºÂ¬™º¨“­——ª‰}ƒ~lXdbYkfjfW\cYVSIGFLQGCHIAHD>?BBL@@MD99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FRLALRWSYUZvjp~Ž„€„nzsx‡b¹¡™£‰””–’”“–’‡†{†•Š€„Šz|‹‡†}Š‚Šƒ–}wzueP\dGEL;Qca[^SF?;HPEZcQRYXZgYT``LSPEA?IJHEEA@C<E6B>HGJLSZT]“®¸µº¸È¿º½ÉÌ»¼À»·µ»º¶½´º±Æ`u²¤±šž«½ª¥¨««¤¢²µ «§Ÿ•–Ÿ˜Ÿ®¥§¦¥Ÿ£”£§±´§²³½¶Á¾ÓÉÉÓÇÂÅÌÂÊÃÀ¾½¿»¼·´¯¸·¶Ã¹Å½Âǯž¹ª¡«Ž¤§¶ˆs`cc_Xb`igRX`VQUIEENK@>GD=KA=B@=F>;H@796379>489:57045/26389374426?8@>GKRTSQPOQQPJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKE@IMPRKQ]glkp…slrss‡ÕÀµ™ •˜™‘Ž—‘––Ž†‡}†ƒŒ–‹~ƒƒx{‹ƒ‡|‹yŠ‚—~t}zkfpuY]\Pedb`ed][XW\MdmURmm_n_XgdUYUJDBKKHFHHHGAI9D?HKTTV\Z[“¹À¸½·ÆÀ»¹Êʺ¶¹µ¸¹²·µ´®¶¶™du¨œ­p^¢¬œ˜ ¢›¤ž«¥”ŸŸ”Ž–˜—§Ÿ¥Ÿžš™ƒ¤¬¥ª°­¸°½¹ÔÑÎÖÐÉÌÒÌÏÎÊÆ¿¿ÂʽÁ¼ÁÀÄÄÅʾÈ㤻°´¯š«¸»™€{m^a]Z_aZccP[`SPKCAEFE<@E>AHA@D=:E>=J?47535;=468977022/24169775555D3ELM>51/006:477@IOI;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODQ\Yh_o–’”nlouu‡³¬¡ Ÿ‹™œ™Œ•‘›’…ŠŠ~ˆ‡‹Œ‰|„s{Šƒ…{‰tŠ‡•s{ylmu{hreilifjih`fiilZms–­¤¼ˆ‡g[oh]ZZTHKNOJKPKSQHLAJGJO_^bfia—·Ç°¸²»½µ±ÄƵ°¸°¯»«²±§«·«µ§š§šNšŒŽŸ–‘¦˜¥•Š““‰‰‘‘›¡—š•–‡žš§›¬¯¨°§´´ÔÔÔÖÒËÏÔÕÍÓÏÍÅÂÉпÊÉÊÉÑÇÌÍÂÐÑ·¯Ã¼Ä¹¥¶ºÃ¢ƒpe^^^YaXZfZQ]WOPBBHEBH;AC>AG??A8;D>@H=46655;:687654/10146278875367C5B8?-0-1349=97,.,1;FK=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYSeVs˜‚hqoyyƒ ªž¥–Œš›—‹•‘šŽ}‰‹…ŠŠ‹‡|„‚pˆ†{‡rƒ’‹}qxulqx~q{nxslhpmcjmpxiw|~Ë¿Áߧncxnc[a`JPRUNY^P]\NPNTQUT\nmv‚q–­¸¬´¦¯¶ª¬¼À°«´¦¤¸¦«® «´£Ž±­š—˜Œ‘“‘„Ž›¦‘œ‰ƒ‹„Š‰„‹ƒ”•——“œ‘œ˜™™Ÿž«¬¤§¢¬­ÏÒÕÑÍËÒÓÔÐÔÑÎÈÃÔÑÇÍÒÓÓ×ÌÑÑÅÒÖÅÀÎÇǨ¾·Ïžzpf_d^XaS]ZPQTPOH>@FABE<@B>ED>??:==<<JA45465<888664412/03526768533;=<E=@11+/249>5901022-2DN3)/3.32=N238C}_2A†tD:==I>@CFH<VRMNZu†…Šwlwp}~¡žž¡‹Œ˜““Œ‹“–„y…‹Š‡‘‡‚{r~€‡z„u…“‘ˆovrks}{v{swqj€sripqzyrz¾Ëš~Œ²„vr„vhak]CZZ[VecXdjSX]]`d^cxz~‹˜©£¤¡Ÿ ¨¥ª°¸ª¥³£¡­¡£­¡§±Ÿ‰¦š“’‘‰‘ˆ”‰j”¢Œ™„€…~‘ƒƒ“–­‹••šŽ†’‘ž—§°¡ ¡¥¤¨ÈÎÏÈÂËÑÔÑÔÓÎÓÍÆÖÒÌÔØÖÖØÔ×ÕÉÔÚÍÉ××ÑʬÃÃ̌tpda`YUZT\PKGJJJ@;:;DAD<BC>GB>BB;<9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/--;R017/532FD28>nb5=tM99@I<AD?A;PLFKYp€u}hsxr‚‰€•”…‹•‰ŠˆŽ‡xƒ”˜Šˆˆ‹‰~‚xs{}ƒ‡wz‡‘–€ƒnwpmuux}t…|yl‡vtn}v„ux|µŒ;A‹Å¥~Œ|ieWICfcecgjdnx[^fhknin€ƒˆ‘‹œ —˜ž££¦±££³Ÿ¡¥ © £±œ†ž’’’ŠŽ‹†ƒ„~œ›Œ‚„…z”~‚©•£Œ‘Š—’‹}—Šš’«³˜šœ¨œ§½Ãƹ¶ÆÍÒÐÒÐÌÒËÉÔÎÐÕÚ××ØÔÙØÍØÛÎÉÙÚÑÖ¾ËÌ´ywpf^[SWR[VFGJIEE=:7:@@B:GD?DCADB;?;;7DC75655;0689443341014558754449@>DBC<33.6FTWOQJAJF?1*(.BS39254/7K75<`bA<svV87AH:?C><9QECJTknnpbpqt†}—‘‹~‡’ƒ‰†…‰‡|x…––ˆŽƒ‡…†z„yqz{„†uz…Žy‹p|oozq{qƒ‡€nŽzuw}|‚u~{†‡¯sX©Â¶‘‚pnb=^hrpqpnxvehoruxqzŒ‡Ž“‘›•Ÿ•‡Œ“› ›žªŸ ¬œ¡š˜Ÿ¥žŸ«™‹šŒ‘„}ˆ‡ƒ…‹Ž ™“ˆ„‡~m™y„˜†ˆ“Œ”Œ†|œ‰”®ª”•˜Ÿ™¦¯µ½©­¾ÇËÉÉÌËÐÉÃÒÊÔ×Ø×Ø×ÕÛ×ÓÙÛÕÐÚÚÑÖÈÔ˕{}ji\[QTT_HCFIH>A>=7:=?;=G=?AAADA>?:86DB755479.566435532323646553457EBDCEB56<FNSM[nfcnskaV>,4LG865434BF4=W_hLux^8;?F<<B<::D?CGRj^mdbfkv€ˆr‘š€z€~‚‚ƒ~ƒ||„˜Ž‡‹~††€w‚yn{{‡‚tz’ž vŽu‚tu}t€„oo’…t|€„zv†{ˆ·Å¤Áɸ‚–›wpeNfczw†¢Šxyv{ƒ{„vm“–”•—‘„‰–™—–¥œ—Ÿ–ž“’—£™«•‰Œ‘‚Œ…ˆˆ†‘ž›™‰…Œ†—zˆˆŸ—ˆŠ‹‚}¡Š‘Œ¼¡˜“—™©¦¦®Ÿ¨¶¿ÀÀ¹ÇÉÍÎÅÍÉÑÖÕÕÙÕ×ÛÔ×ÙÚÛ×ÛÚÚØÎÜƇ}{ikgaUXVVNLDMB;==<8:<>9=@6=?@=?><9867DA6455=80665547745613855564557HH=DJE7925;H>;::7IP]ZRUXK9T>;95327I8=NYMHxxd5=>C==@:6:>>@EQ_Yea][htzyl‰Œ’wvzŠ|~€~|„{~‚‘‰„…z„‡zu}um|}†~s~’‘žƒ‘|†~xŽ}xŠŠn‚š€t™†}ˆ„{}z¨ŽÃ¡½Œœ£}‰„}‰r‹Š~s¦šœ˜“…{Žˆ„hGq ¤Œ‹’…‰‹’•š“”–Œ•Ÿœ” ”‘Š~ŽŽ‹„‰’–šžŸ‰Œ”’‘‚‹¥™ˆ„‚…„¥‡‹‹¸˜‘•–¢¨¡ž£¯·ºµ¬ÀÅÊÐÈÇÌÏÓÒÒØÒÕ×À×ØÙÛØÚÚÙÙ×Û¸z{zmkgXb\TPOICLA<<>99::99;=6?>><=9:;;37D@8378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWN<MTHN?96333>C;[X>5YypZ<<A<=>8589?=DRSRX_VXfmmmiŽŠqsyŠ{z|{‡{|{‹‡~uƒ…yrzsm€~„~w…›¡šž”’€Œˆ˜‡€›’n‡¨…z ‹|‘‚ˆ„›}šŠŒ£¢ ¤® ‹‘‹…‹“†Wr­‹Ÿ«›ƒ˜›Ž\‚¢‘‚ŒŸ“•Œ‡ˆŒ’“Œ”””‹‰‡–›•–Š’“…€‹ˆ’ŠŠ–™¢£‡“– Š‰ˆœƒˆŽƒ‡†¤†Œ³˜’•—¡¡Ÿ™’œ¨²¹¬¦½ÂÇÍÈÆÏÌÐÌÎ×ÐÑÔ®ÖÕØÚØÚÚ×ÖÙٟqvih_^YTXYCAHC?>>:49:;7:;;3;;?=>7;9:1:H>:37=@50677255?65;55858:57735HR7GOK994=EJB>1FCLB98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:;@;BQKKSYPTcbymb~‘ƒomx‹xzz|†|{w†„sp…‚zuvvt„ƒ…}~’¦£Ÿ¥¢–Š”—‹Š¨—rŠ±„§’„™“„™Œ¢•Ÿ˜“‰šž£’©¯Ÿ•Žˆ–Œn·…šÄȲ›¡¥›œ˜–²‘d¤ÍȖ†‡‰’“”‰…Š‰…–™›”“†”—„‹™ˆª——££ˆ™Ÿ–šˆŽ‡——Š„Žˆ¥‰“©š—“—™¡™Ÿ™“›£³´¦£¼Á¾ÈÅÅÉÈÉÂÊÓÍÍÔ©ÒÑÖÖÖØÚÔÓÚ΃sie`__PKV\BBFC;A=837;<:8=649:<:82?9:2:I:=67BC32:96264>=4;>6949;57944KQ<JQK9A7BGI@64JELF><88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBcFu‚Ž}|m~ˆxz~z‚~vv€‚{ln‹y|xx|„‡‹~‹£³¨£«²¡–§ ¥¤–•®¢ƒ·•’³™¡ ‹¤›¯¢¤˜§–©™­¯¤—••”‹˜š– ÀŽ£É¸«š¢¥­™‘›œ²†…¨¢˜…ˆ‰Ž•‹“‡†‡ˆ“˜”Œ‹““†”˜†ƒ‘œt‘™²–—¤¡ˆœš“Š‹—š‰Š–Ž†}Œ™ŸŠœš™“™˜Ÿ” •Ÿ›¡²®£¥·¾´ÅÇĽÃÿÆÎÊÉÒ§ÎÍÓÒÐÖØÒÏØ»s{w^bWbXQIJOEBCD5>:76:?;<7=42669774=5<5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=89567=:JFDGN[\YJga;H„Šz{m…†y|„x€…}px}}|osz}{x†‹‰…„’¨»­¨²½¯¥®³³¨£¢°¬Ššµž¢¸¥•¬¤—©­·¦¤£Ÿ™©˜ª¤¯°©š™œ”•‘˜ —™»»­É i¶¸«°•˜Ÿ¢«’—½£^©²‚‰Š•‡‘|Ž}ƒ†””ˆ‡’–‹•‹—™’š³–•«ž‹œ”’’Œ˜›Š’ž‹‰•Ÿ¢Ž•Ž˜š“œ˜ž•¢ ”œœ¥¯¨¢¥³¸«ÂÈĵ»½»ÅÈÈÂÑ¡ÆÉÍÍÄÖÖÐËÓ¢q|j^\U`RQGD>=CAB8?874>F<<6<35355454B3::BM:A;AHB;:@<746<B9?@B874::6>=47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPeHb`cpJ@‹Š~€r†‡|‰u‚Š‚~m}}|pw‡w‡{Œ†Œš«ÂÀ°¾Æ»³´Á¼´­«³¶Œ¨²®®½ª›»¤¨­¹·«¦¦¢¡££ª¯²±ªœ¤˜›˜—ž¢¥¥’£¹®¨À»¬­²¹¥¤§}ˆ†œ­½°ƒ‹Œ‹ƒƒ‘z‡Žœˆˆ—‹•—”š–œ§š±š‘«Ž™’Ž•–—‘ ‘ˆ•›¤¬•–”œž”¡ž›™ ¡”šž¨§¤¡¤°³¦ÁÆ𰻶ÅÄþͧÇÃÇüÕÐÍÄʉvud^\a\OKCL@EF>A?B;:4>A==5<6>333242A17@BN>G@CNCA=C=;86CC5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GE?CF\gG`igZ][“ŒŒˆ{‡‹†ƒŒu†Šn~|‚q~z•z’””˜‘“•§´ÆÉÀÂÌÁúǻº¯«¹»—²¶º³À®¥À¤ª°»»ª®«¢¢ž§¬¯µ°ª› ªœ¢œ–Ÿ°´§‹£ººµÁ»«¨œ²¤¤¨”„Ž©ÃĤ‚‹Ž‡ˆ„†•”zƒŒ‘‘¡ŒŒ”‘‰˜ —“™”—¦ ®ŒªœŽ•’‘••Ž•‘¡”†—Ÿ ³Ÿ”›” ¡™¤Ÿš œ ”˜ž¦¤¦§¤¯­¥¿Ä®©·µÉþ¶Î²Å¾Ã¼³ÑÊÈÁµv{n^Z]lTNICLKJI@A=CD<5AD;:3=8B332262A05IEM>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBg\Me\fTcj™–‰‹ˆ’†‰y†“r€|~w‡‚z¡–¨šš˜º¾ÈÉÊÂÒÉÊÂͼÁ³­»¾§º¿¾¼Ã·¬Á©¬³»½ª°©¤¥£¬®´­¶¶  ¯Ÿ¥¢˜£´½©›¨¼Á£¶¶¯«’¯¬ª«–†š©¦¥‘‚Œ“¥•‰€uŠ’y…‘ž ’Ž”‹”£™—›””£ž©Ÿ‘¥šŒ•–ˆ}•’’£š• ¢œµ¦Ÿ—¥¤£¥Ÿž¦˜ž•—›¥£©¨¢²­¨»Àį¥³·ÌÀ¹®Ã³»¾Á¸­ÂÂÁÀ™p{cZX]\MLMIGDCHBBACK:4DH:;4<7E.12352B26SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQF7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>kI_XaZdeVžŽ—Žž’‰Š‰Ÿ’„x…•~ˆŠ€• ™®§£˜Â½ÉÄÈÆÓÍÎÍ˼·°º¼´¼Ê¼ÃÁ¶¶»­³¿¹¼­¯¨ ©§¶­®©²·šž­¢§¡«·¸©¥¯¾Ä±½¹³§©³³­®–•¥¬§ ‘Ž’±Å§•|‘•}‡‘™ª™˜“““•“¥ž“™“¡£¢œ˜Ÿ™‹ŒžˆZ——’–¥šf™£Ÿ³¥–£–¬­«§œŸ§˜™–™•¡¤¨¦ž¶¬©º¼Ãµ¦´¶ËÁ¸ª¶¬³º¸®¨¸º½¸ƒnp\ZVWOGKSMK?AHEDGFG85FM;>7>AJ.32025B55PWN;LFKRLOGGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|hW;=@BFBrFiIRebLF¦”œ–¡—¨–Œƒ‡¥’ˆ‡‚œ„ƒ•‘”Žš¢Ÿ¯¾®¡Ç½ÆÅÈÇÎÎÎÒʾ»¶±º»¼¾Î¶Ä½·¸·²²µ³¸²«¦œ««¸«©¨°°—£®¤§¤¥´À°ª¬³¾ÂºÀ¹³§¸³·³®•¥­®®¤‹“•¡sÁ™}–™„Ž–š‹±•šš•’“™š¦£• ›–š¨œ›¡ ™‹Œ–`J–œš”š¥—T–°Ÿ¯œŸ¥”¯¯­¦›¡¦”“™™Ž §¢™´©ª³½¼»«°²ÇÀ¸¦««­±±£¡²²´¤rpg^\PRMEPPPQ;HKIFHAC>9KT?A:=EM07544:B34NWO<JKNUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@CAF3>58JKCA=C;4EA:A?>H@5*B52,>c]g:35tde@R7&#3}iX;:BC@=REWRsbWFH«—™Ÿ¡¨®˜—‡‹§–Žˆ’…Ÿˆ„œ—ž ›£¥µÉ´©Æ»ÃÄÈÊÉÈÌÎǾº³¯¹¸ÀÁ͵ȺÀ¹µº±¯¯²´¦£›ª´´«©¦®¬™¤®¥¥¨¬º¿¨«¶¶¿ÁÀ¾¸³²Â¯·½«£®´¬¸¥ˆ›—¦›v¾ „˜œŽ“™š‹®–¡œ›—•› ¡©ž¨ ššª™¡§ž—‘ƒnv“¢š•¢Ÿ®²£«•©ª˜«¯¥¥ ¥ª“’™›ˆ”œ¢ž–±§ª«º·½³²®¾¹¶Ÿ£§¨¥§œœ¬©©ehb`SLMGHNJVL=MDMIJACD<QU<AABDO18=77?B75UXN?HNQXRPQTJQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW;:=..SaMVHe^HF¬”œ¡Ÿ»®˜”ž‹“ª›‘’“‰«‡¢žŒ¤¬”££¶Ç½´ÁºÃÃÈÉÅÂÎȽ¹²¯¹´ÀÂʶƱÁ¼µº«¨­¬¯£¢™ª´º¦©¦¬ª¨¯§¤«ª¾¼¨¬¼³·½Æ¼¶µ¸À°½¿³©´¶«¾¤¢—‘¢Ÿ¼Ÿ‰š ™—žŽ·Ÿ©œ¥£›œ¡š§¥³¢›¥œ¨ªž™•”š‹—‰¤¢”œ¢Ÿ µ¯¥¦“±«š«­Ÿž¥¤ª‘•• ƒžŸœ•©¥¢¡´µºµ­¨µ²³žœ¢¦š—•™ª¡žxb_a_LIGHMQIMEFFBRJHADGAVSDH<AGQ1;B7:BF79\YKALPTUSMWRNUJD@JJNO9C?5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-1:h]FDCœpbGE¨—¤žžÂ¬›—¥—™©œ–ššª–•¨¦•­¬™¡ª¶ÄÁ¼¿¸ÁÃÁÈÄ¿ÍÆ»¾¹²°¸³¿Ãȵ¿°¼·¹·§¤««¬¡¡›««Ä¢¥¨¬¦ž¬¯¬¢ª¨¿¸¦¬½°·¶Ç¶´¹¸¾°¾Á¶´²´¯¾£–£–“›”­Ÿ¡¢¥££Ÿ¾¥©¨¬¡›¦Ÿ½¢˜¤ž¢©«¡–•ž“Ÿ‡…“ž¤ µ¬¦œ–²§™°¨ ›«Ÿ¡™•Ÿ…Ž¡š›’¥¤š˜¬±¶±ª¥©­¬œ˜ ¡’Ž•©Ÿ”je[b^PJIKOMHFCI@=OH@;GIH[ROK=HNU4BF9>HG5Cb[KCNRUWVQXTRUH@8QQPM:G@4CHQSIC;C>GVKC@O>K<06;GF>;FA56?9:?9;15D0-,0Mv\4KZ5,MnW<-=)#zbQ5CKQ9oRF<KxfcXM¢š£›Ä«¡Ÿ¬­Ÿ’¢ž–¤ §ª¬—¶°£ª³¶Å½À¶À¼É¿Êȶ¸µµ±´´·ÁÆ·¾±¸µº¶ §­ª¬žŸ¥¤Á¥ ª® ¤©­¯¢¦§½¶¥±»·¶µÃ²³·º¾±ÃÀ¸¸­³´µ¢œ¤•‘“ ­ ™¡©¨«¢šÃ­©ž¬®››ž˜¦ ½¡¤˜«««¦¡™šŸ’ž‰ŽX–ž¦¡ ¸ª§“˜·£Ÿ³¢¡œ¯˜ ™”‚ —–¢¤•¦®³«©¢¢¥¥••™‹‘“¤Ÿ‰cf\eaMJKKOFEAFK>=JA99JJN]QQJ=LW\9FI=DMI8Hc\LCLPSYYVWOZ^IA=WQIK?H@5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+w`S6SZkWsHE6=ue\LOžŸ¡˜žÃ§¥¢³¡œ²§“ª¤Ÿ£Ÿ­©¬»°¨¬µ²ÈÃÁó¾ǼÅʽ°±·®±µ¯¿Åµº±°º¶­š©±©ª›ž¦¡¨Â­›¬±œª¢®°©¤§½·¦¶º¼¯·Ä­³³Â¿±Æ³º·«´¶­ª¢¥••”£«¡ŸŸš§«¯¯¯»²¦ ©©™™—’¢¤¸¡¡¤’®¯¬¤¦Ÿ’¡ž•ž‘•š£Ÿ§´§§˜´œ£¯›Ÿœ¯‘ ”—”š€’¡–Ž ¡“‹¦¬°¥§¢œ ž’’›”…‹’œž€cg\hfKJLKSBC@IG;;F?99NMU^RSJ>O^^=HPBMLI9Nd]LELRTY[SUO\bHA?ZQAHAKB7FELKN>;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<v]^?[U^fr@8<H–weA4Ÿ¤Ÿ› Â¨£ª±¡£´©–²«¦¢¤²¬®©»²­°´´Æ¿ÄĵÀžÊŶÀɶ«µ©±¸¬ÀÄ´·®­¶º¥™«²«ª˜ §—­»µ›¨°›­Ÿ®´²§ªº³§º³·²¸Àª·²Â¼´Å§¾®­·µ©§¬¡—–‘¥¤¢¢——¤¯¸­²µ¶ Ÿ¨¤™”•“£ ·£¤¥•®²²¥©¥¢žššš•˜¨ŸŸ˜¢ž®²¢¦—¯™¥¬˜›Ÿ¦’Ž•™›†—Ÿ”Œœž”‹©©«¢§¡™ž–Œ™†–‰”Ÿzej]lkOQNNT=BANC;:I@77QO]^RVQAW`\BJSHWKH:Ud]NFON[W[RPQX]GAB[PBG>NC9HGHNP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1\cZ33906p[bH05JpiVCWFŒyfC;¤¤œ¡¥¿¦¨¯¯¡©µª¹¯«¤ª´·±°¹¶°·¸¸Å½Ãǽ¼ÄÂÇÁ¹ÁÇÁºª·¥­»­Á÷¸ª­²¼£•­°­²—¦¨‘ª¹ª §°ªŸ°´³ª©¶¶¬»¬²²¹·¬¹°Á¹½¾¦Ã«°·®¨ª«¦˜˜ª¡¢ ‘— °®³«°¹š›©Ÿ™–’—¦ ·©¥¢¢¯±³«±§«Ÿ›  ›ž¥¡—£³°›Ÿ”¦š¡©›–£ —™Š–™”—˜“ˆ›™”Ž©©§ ¤›˜›“‡™‹~Œ–†Ž›kjnbnnXRQZTACEU@;:IA7:XPd^PWWDY^^MLRO_KJ>Zd^NIQN[UYPKSWZI?DXPDF>N?=IGGQPB=CFBM?:2D?77547?=95E4+75/251.-.,1>*'+=\p=>1.1e[d@1747gY`F(@8l}h\V:‰{cC=¨Ÿœ¡©½¡ª°ª£±¸©¥µ²«¡­µ½¯³¸¼º½·¶ÁÿÉĹÅÃÁÀ¹Å¾Á¸¯¶¨«·²¼¿¿µª®²¸Ÿ—¬­¨­—¨©§»Ÿ¥­³ž«¢±°³¬ª¶³µ½­¯±µ¬°µ±À¹Ä¶«¼¯±¸¬¬©¢±¥ž¤¨ž¤—˜Ÿ²ª³ªª³™§›™” ¦¤´®§¢¬¬®±§²¬²©£›Ÿ¨¤ž• ™›¨µ©—™’’Ÿ™Ÿ¡Ÿ‘¬Ÿ™™†–˜Œžš“Š–—š—§¦£ ž–•–”•…{’„Œ—fmshps_GYfVDCNXDZ9HB6>]Rh\NZ]G[^]OMRXdJJC\c`PLMNXWXPJVVWL=EUJEDAM?AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,+%2+*5K1.'_^aV151=`V^8)C3YU\gK5ŒzfL@¤™ ¤¬·£¬©¥®®¶ª®´¹¦§°¸Å·±·¾Áµ´»Å¾ÌŹÃÁº¿ºÄ·Á¹³µ¬ªº·»º¾µ«®±·™˜¨«ª«›­««½ž«®±£ªŸ±­³®®¶²¹·ª­®±§µ¯´º¼É²ªµ´±´¯®¦¡³Ÿš¨¬ ¥••š™±¢­ ¥¯–¡¤™™’¢¥¦²©¡¦±«ªµ¤®°µ¯£™­§›—ž™™¬¸¢—“˜œ¡™˜”­ ž•‚“™žœš—‘‹”’žš¥£¢¡™–“’–{Œ…{‹ƒ‹”lnyou|aF`jZIHZ[={JGE6AbTiZM\aJ[\ZRRSbaLKE`a`PLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`Va.5(C^Q\.*A/JGP[G3cYTKD™—Ÿ¯¨±©¬¥£®®µ©¶´·£¬´·Éº´»º¿¾µ´·ÃÁÍǼĽ·¾¿À·¿½²½®§ºº··Â·¬®²¹•—§®«§£³ª”¯º¤­²±¦§¢²³±²±µ±¸²©®«²§¸¯µ³ÄĶ©´µ«°­©§¢¶Ÿž¦± ¤”›™”±ž§›Ÿ©©¢›•—¥¥¤·§¢°³«§±§­°µ¬¤™¡¬¨›œ›”ª¹œ•Ž‹™¢˜‘˜¨£ —„’–œ˜—–ˆ–—š¨¤¡’–’–w„‡|†‚„nqxv|]Kel\JOd\?b{GI8GgWe[M^bMXYWUXTi]POHa]_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANIg27'FaLV%-B.=ELQ<3rkKDC‘˜¤­¤­­«¦£°²³ª¶°¶Ÿ«µ¹É¹®Á»Ã·³²µÂÃÏÄÀ¾µ½À¿º¿½³Ä¨ª¹±¶·À½°¬´´¡§°­¥¦±¥ž²µ¬«²°¬©¨´º¬´³µ¬´¬©«¨¬©¹­±°Ç¾¸¤¹¯©­­¦¨­°¥££®£©œ›š¯™¢£¢£¬Ÿ£ Ÿ¡©¥¥¸¤«´´¤ª«¨¬®¶®¢£¨ªœ ™š’¤´™‰‡‘£ –Ž•Ÿ¡–”†Ž”“›™–•‡˜’•™§  “‘Ž‘x~Ž…}}}‡ŠŠrts~~\Rdn^NZg]FD–[G:NmXb[MabNVVVWTYg^QRLdZ[TKGOTSNGIVS\N;P^JBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3Ce;6*HdHJ+:I?3CIS,>k>HIš©ª¡©°¤¨£³´±´µ±±¡¬­½Ëº®Á»Æ±´­´ÂÃÑÄÆ¿Á³¾Â¼¿¸¼Å¨­·¬³¸¼Á±¬²®¡¤§­©¨¤±£«±ª¯«±®®­«³»§·±²©²©«¦¥£­º¬ª°Â¹´¬¹¨¨¨­©§±¥©¤¢®ª¨¢ž›¢¬•¥—ž˜«¡§¨¡¬¥£­¬·±± ©¢Ÿª­°¬ž¦§©š£˜™ ¨˜†ƒŽŠ‹Ÿ Œ—ž‘‡ˆ‘•¡–˜–†–““—¥Œ’ŽŠ€ˆ…}w€‡…‡usr‰vl_Y`ncQsr\K<„|F?WuX`YOc\NUVUWP\a_TOOhXWVKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*35>10485(5/*,.30;),,'%234$,2-860)(1<^K0.IgDF8<B05EKX1@”\@MF•–¬§¡ª²œ©©°¶¬¸´®ª¤««½É»±¾·Ã¯°­³ÄÄÎÎÿ¿´ÁÃĺÀ´ÉĬ¯·®²ºÀ¿´®®¬¦¨ª°©¦¨²¦´­ª°®­±¯³¬³º¤¸³¬¬­§« ¢ž°·«ª­º¶¤µµ¤©§¬¬ª¬¡¨¦¦±²¤¦¥¡¡«–ª¡“š ¦ž£¢ª¤¬¢ž¦±·¬¬¢¥¢š©ª­©œ¡¥¤¤™ š•˜“‚ˆ… ‹›’Œ„™¥œ“‘›Œ“‘‘”£››š‹Ž‹‹|‡‚‚{u„‚~uw‹¤‡yk^`ngWf‡dN@g’LDbzWbXReUMVUUTO\]aVKNiWVVIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*49?./463)4+*,+.#4.-+&(+79*&6+<-2,&06XZ.0JgAA<<C+:JO^4D†AIHD–‘¯¤¢ª°˜ª¨­µ«¶°«¤«ª©¼ÁÀ¸¹³¼µ¦²¯ÄÉËÑ¿Á»¹ÀÀ¹ÁºÂÄ®±µ²´»Á¾³²¯­¬¬¨¶ª¥­°«¹®¨°°®±«µª¶µ¦´¶«¬¤©ªœ£³³¨¨¤³´ ¶®¡©¨«¨«§ ª«¨¹¶©ªª©¡©Ÿ­›‘¨¡ £¢¦¢©œ¦´®§¥©¢£—¥¦¦©œ¢££Ÿ™˜Ÿ‘Ž˜~‡‡…žžˆ…‹‹‘„†–£šŽš‘’‘Ž“Ÿ˜™–‹„t‡€xu„€{x~€ˆprggqx\atˆiO]˜VHmyUdVRcOLVTUQOXZbVHPjTVSGPYUI>IHOQPxMNV=<KD?@A<@CUC9AK=5;E13;97*4:=+-341*8**+*,)*(/*&)%3;,$2)2021%/2Rc02?f=NX?C,?LT_/Ik7RE;•¯ ¥ª¬™«¤­®³´®ª¥¯©©»¾»Á±¯¸­¢µ¯ÉÇÈÑÀ¿½»¼Ã½ºÃÁÀ¿¯±³²¶½¼Á²²³«´©¥µ©¤­³³¸¯¢­µ±¯±¹ª¸®ª®¶«ªžª« £¡¶­¨¡ž¯²¡´ªž¨§ª£ª¡¡¬­¨½¯¬®¬¡§§Ÿ¬™¯¢˜¢ ¨§ž§›˜©°¨¢Ÿ¬¢¡’¡¢¢¦˜š¨¥˜˜˜Š‡•ˆ}†„…¤–†ƒ‚Œ‡‘…†•¡—‰’‘“‘•—Š…†xs}txz{tt{j‚ˆ¤vi^elugˆ‹|RWp^KxsTdSQ_MMRZgNLVYeXGSjRQ>BNQaQ:IHLSIqQLS;<I?;<=;@@W<<>H73CB15:93-5::)-31--6)(+-,52#2)',%.;.&1.0-14%,0Mi:38_=ad?F1CP[[+HO;XB4Ž± ¤¥ª£¥£¬¦´³°©¤°§ª¸¾Á¼°¨¹ª§®°ÉÇÈнÀ¾¹¾¾¼É¼Â¹±°µ²º¼¹À³´»­¹¬£µ§§¬²¶¹²¦§ºµ­´¼¯¼¥­­µ«­œ©¯¤Ÿ¥¬ª§œª²¤³¨šª§ª¤©ž¢©¨©½«´¯­ž©£ ®œš²¢–¤›¤¥Ÿ¤š™§ª¥žš©¡›‘› ¤˜–©©‘™š“Š‚…}‚€ˆž‡€~Œ‡’…”›”†“¢”‘‹‘›“•‡‰~€rzy~|hw|{uqr~i†z„ˆd`hcr…{mhy]^VCX{mTaPRYKKMpt]HZ[gYEVgOC>KNDCA9HGKS?jaIQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11&/>KI1%90%,,09/,,+6'17#-/GjI14X=fbAJ7GS`U*=<F\@*Ž“±™ŸŸ©¥£¡ª¤¶²±¤©±§­¹Á½µ°£¹­¨¨°ÃÉÉÌÁ·½Àµ·¿ºÈ¶Ãµ´³µ²½¹º½¶­¹¶¿­¢³§ª«¯µ·´ªº»¨±¿²¹ ¯´¶©¬ž­±£œ¥¨ª£œ¤°¦¯ Ÿ«©§¡©œ£¨ ­»§®±®¡ª¢£­žž¬¦—Ÿ›¡¢œŸš™¢ª¢š™££•–“ž¡–›–¦¬‹ž‘‘Œ‚‹€{š”Œ‰}Œ‡ŒŠ†’˜‘‡”¤Š’’‡š“ˆ|yl}vyxb{zrpqsxj‚ujƒgchansŽmbjp`oB]ykV^NQQKILSYVM\^mWDXaO^PHMDF;7HEKO<rhJK9AE;;==;;=J49B<3;G<4?18-78;2(09/,5..=-*L>*49&'.34.0+/4&,:$40AhZ13S=e_DL6KVdN)=3Q]=#’—¬™Ÿ—§£¡Ÿ§£·¯­¢¯¯©«¹Âº³­Ÿ¹¯«¨´ºÇÊÇ¿·Â¾¯´¾·Ä¶Ã²°º±²À¶»¾¸©¹¸½ª¤µ§¨ª°­¹°©™¹¼£­¿´´¡®·µ¦¦§°³ Ÿ¥¦¨¡¤™ž¬¨©ž ª®§ ¦—¢¨Ÿ°¸Ÿ¤±® ¬¡­¤›¦¦©šš›Ÿ£•œ›™©¦–šž¨‘˜’˜“™–¡ªš‰‡}ˆ‚Ž||¡ŒŒˆy„…Š…‰“šŽ‰•Ÿ‰‘•ƒŒ—‘}„{sp|qst`yxjoqqpksdzlhfdbf‡€`[rjqMN€iXZMQLKHPRQHM[_oTDXZRgOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23/:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%53=fd24M?e]FO=RZgH*?0\[5(–›¥˜œ•¬ ž¡¤¡·ª°£´´©©ºÅ¶²® ·¬­­°¶ÅÇÀ·¿Â¹°µ¼·¿»¿¯¬¾°³¿²½Ã¹©»º¸§¨¶¨§«°¬³°¦˜¼¶£ªºµ®Ÿ±¸¯©¥§¯²›¡¤ ¤£¡–›¯¦¡Ÿ£¨¯¡ ¢“£¤¢¶°¡¦±«Ÿ¬£¯—›ª¥¨Ÿ˜š¤“š›™œ¥©™››¤””—•œŽ“—¢©¡‰Š†z„~„Šz—Š‡z‚ˆ„‰…Ž“˜ŒŽ–™Š—~†—Œz€zpqvnot_xwemllkj„ofrikfi^dt`[kviZJ^[XOOKHHRUF29]^mPDXVYeMHIEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<"8R=*113>D5,-'42*;+139cm74GAf[HTDU]hD.<2cV,2•¢¡—”›ª¤¡¢¡·©® º¸¥¬½Å³°®£µ¯­­¯´Ãü³¿º·±³¹¸º¸º¯®À³´¹¯¿Á¸¬½ºµ¦¢³ª§©²«­± šÀµ¤¦´µ¨ž²¼©¨¥©¯¬™£§œ¤¥”˜¡²¥™Ÿ¤¨©œ¢ “¤Ÿ£¸¨¤§®¦¥¡¨’Ÿ¨¢¡¡™›œ ’š›–Ÿ¡ª›š˜ ”“–™““£¨¤‰‰†y„{„†}‰Š‡z„‡‰‰’…–““Œ•”Ž”{ƒ—Ž‹w~{ltqllsawuiijggo†hhicfij`kcjh\e{c`StT\[SLJGIOS@!*h^jLCVU^`KIGEC.:B<F<6KPD8:D357==895?:;4>8@K=>93)8><:9*6@3.E4(+,?0-N?.+-7,1195,&.5-80576`tA3CDg[KWGU`hB379gO'2ž¢£‘Ž¤§›žž£µ¬§ªº·§¬ÄÁ¶°¬£µ®§®¯·À¿¼²Á·°®²¶¶¸¶¶­ª½³®²±½¿¸®¼»±¥Ÿ¶«¥¥´©ª®žÀ«¨¤¯²©¬µ»ž¨©«±¥˜ž©¦¤‘™¦­¢˜ž¤©¡›¡œ–Ÿ§¶¥¯ª®¡¡¡” ¦Ÿ¡¡š›™œ‘˜œ“¥«¡—–œ”’Œ•—‹˜š© ‘ˆ‰‹ˆy…w‚‚‚ˆ‹‚‰}€…ˆ‡†‘„—•Ž‘‘‘Œ’{ƒ•Ž†s}}fxokjkguskcgddvcefffjjdkrZ_Y]mdaNiX[`VJGIKMRX>9_liHBTS\[IHFFA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A=-5B37=+*,0B*JK./*+3722(57$+7.72685]yN2>HiZLZJVbf@:3BhH%5š£ŸŒ­¡˜˜Ÿ–¤³±¢±½¶¡±Æ¼º±±¤·¬ª®©¹¼»»®Á²®®®¶®²¸³¨«¹±¯®³¶º¶°¸½­¦žµª  °¤ª®œ¢À ±¤®°®·®µž­®­­¢š§©¥Ÿ•š§¥Ÿ™¥¢¨šŸ›”œ¬¯¥º¨®¢¡šš™ž¤š¤ž—ž˜›”™ ’¨•©§š“šš‘‹•™Ž””™©§ŽŠ‰|‚sŠ˜…‡|‰‰……ŠŒŠ’„”œ“’–Ž€Œ‚p€~fymhkigqrk\hcctbfhjnlgjjhn]lltpaUcideZIFLMOXQQVaeU@VSYUFHFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24;6#3*)6.55465Z|]19Kj[M[KXdd@A1JfC'4‘¡šŽ°žš“¡™¨²¯Ÿ¸¿¶ ´Â»½º±¦¶°¨®¥·¸··­»¯¬ª«¶ª³¸­¥³µ²®©°·¶±³µº§©Ÿµ¨ž¨¢©­š§¾˜­£®¯µµ­¬Ÿ±­¯©¢œ£«¨œ”œ¦¤šª¢¤–šŸœ›£«ª©»Ÿ§¤ ˜™™¡k¢–™œp‚•š£u‘©§ž””žˆ—™€–Š¡x†”Œƒni~vƒql†‹†}„Œ‡p^cag„˜†l‹”’tw‹„~ƒg†€guheW\hsnNPjcgs…g_dfnmj^_aŠƒ„eNKD9FTg^JGPPTUKHR`oteFZQUPFHFC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,+08>G601.*.*/568,#1'214:175Xl16Ok[N\K[fb>G1Qd=*.‹£™†•°›œ“ ›ª­ª£½Å¯©¸Â¸½½­§·°¥«¤·³²³±¹­©¦¬´¦¯µ¢¨¸¶¶¨§¬·³®´­³¢©Ÿ³ªž¡¤œ¦§˜«º•¦¥¯³·­®¤©®«¬¥¡Ÿœ §§›— ¥¥››§§“ŸŸ˜ž§ª£µ¯£££œ–———£ˆ Ž’š‡¡‡“œ ¤¥ªž’‘š‘ˆ„rxŽ…ˆ¡vˆŒi—ˆf}rx¡oˆ‡„~Ž}¡  ™€|‡žt‡Žv›Šl‡ƒlheczkqaS…mcli˜qYjpoˆX^i[kk[ˆqnzr…g†„Z^GN?G_MFRVVQQRWTg^MWIRSPFGG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82).1<I9/01.*/(-4583%&2115>1<8Xƒu25Rk[N\L\g_=K1Wa70(‹¦–ƒœ«œ™˜Ÿªª§©¾Ã¯±º½·À¿ª¥·°©­¦³´®¯³·«©¥±­¥´³œ­µ¶´¦§¨³±­²¨®ž« ²¨ £¢š¡¢š­³”£¥¥µ¼§¬§«ª¬¨¥¡ ˜ ¦£™™¥£¤˜œ¤©–”£œ”“¤¥¦¡·££ ¤˜”“—’œˆ¯˜”‰©‹—¡›…±€£¬“™”y‚Ô¨€‡•Á›Çyx±¥·—d€Àœ¿y„„y„|‘Êq—¼œÅzrµ¦»{€l–±«°xhkX±®nei¼’¼nhzorØ~Sjb¶²r•tš¡ªWOWbPVNFT[XQPRŒ\W\P@\DQNEGJ<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22BE/.32.+/)-/186- /416A1=:Wƒw21Tk\O[M^g\>L1[]41!¦’€§ªŸ—œ¥­²§°Â½²µÀµ·¾Â«§³­¬©§®³©¯¶´§§¦´¥§¸®œ³²¶ª¥¤§²®®±¦ªž§¤±£¢Ÿž—›Ÿ®«”¢Ÿ³º£ª©¢­®¥¡›š¡§Ÿ—›§ Ÿ˜ž§§‘œ§š“¡¦¢ °¢ŸŸ£–•’˜’™…¯kjŠª~gƒ•†­dp”™¥”q®¡¤~x»}k¡v±_j´[¥€fœ‘`f‚zfjxk©d¾rg¦Œu±j|±xt’“cmm§n[„ Ehf‡–Euœ`~h|¤§‚Y_‹«i€–xyj§7J¯\XSld[KNW_\WV;N‰OXW/ITTJDFF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3..53/+/(.0.:5/'$203B/=;U‚v2-Vj\OYL_gY:M5_Y30¢•‚¬§¥ž£¤ª²·«³½¾°¶Ä²·ºÁ§©°«®¨©°®£°º¯¤¤®²£©¸¨ž³²°£¥ ª­¯¬¯¦§Ÿ£¢°›¢›—•—››¬¥–›¡ž³³¢«œ¢­­ ™— ¡¨œ˜£Ÿœ™¡¦¤¢š— Ÿªž¦¦ ›Ÿ¡••‘–‘š…µ›µx…©™µ™v†³›·~“––¨”~l‚¦{‚†ˆ’”’w«gk±[«{‡”t‰q†€ˆ—x‚‚‹˜Œƒ „°vwŸqkkl|‹N¤XHcc™~ch¦`ysuS“‡^P©mcq~‡€bœ.Q¡o[Skh`LK[dX\ZB>±yXXA#MhFCEA@A19>88:84;:9<9:A:E::;6:CB8=?KNG:5:AFB@AD<FD;0201;F,0.940,.(/3,>831/2-D1<<S}n3+Xj\OXM_gX7J8aU50•Ÿ•‡³¦¦ ®©§²¬©»¶Â°»Â­¸¶¿©«­­®¦­±©¡¯¼ª¡§´¬£«µ¥¦³³§£¢§ª²¨°¨¥žŸŸ¯–Ÿ˜”••—¬¡™™¤¨´®¡©©¨©š•˜ ¥§›Ÿ¢Ÿ› £¤£•›Ÿ—™¢©›¥™œœ¢ —“‘““ƒÕ“™¹p°Â~ņ|֔›»|š•¤œ¤{Ž‡¤‚¥‚z¬yV¯zˆ~Ÿj¹Z¹v‡„}¦‚“|˜zªy{±nŽ„t¼…o”P¯§ÅŠQ zc`©bssˆm—ˆ`Sµ´È†€‰|c¤3Bv]PjidP@XgZdaJHNmM[ROYfYCD?E?0=<59;74<;8=:<C:F:;>6:@C;6@OLH<:<DHCBCD<EF81211DC./0483+-).323971#%5*>3==Qwj6*Yi[K]O_fT7G:aQ71%›¢“˜±¨¨¥³ª¥´©¤¼·Á°¹À±µ³º²´¦±°£°²¦Ÿ®¶¨š§¹­£¯± ³´° ¤žŸ§©°©´©¤œž«—˜—•—•• ©œ™–§­°¨£ž­¢¦•ž—œ¡¥¡™¢¡¡¡š¡¢¦›ž¡ž”™›¦ œ§•››Ÿ¡™‘”‘ˆ²nhµq«‡nŽ¦r´sr¶{š—¤‹£‘¡¥~°vƒ‘ÒÑv\®{…¤o›ª¦k‡…}­}—™{±s’y³e–t„žožf”RȋZÂ\Ÿyb_­`vt‡b—ˆ^Yʝo¿uMKµSUÆdTQjcfXAOk`lhPUGI8=VQZWXIC?J<2?;5=<46>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>HI91746@>/.24252-).26,742&60;5:=Pqh9'Wi\BOT_eP5G=aM620¡’¥¯­¤ª¼­¦µ¥§¶»¼²º¿·µ³¹¹²¤´´¡±±¢Ÿ¬°¤—¦¹­¤±°œ´¸ª ¦¡©¤²¨¬©¤šœš¨ž•”—˜’’¢§Ÿ–’¥ª°¦¢–“­Ÿ¤‘” ›¤¦Ÿ•›¦¦¡š¢Ÿ­š ž•›¡žœ¦•–™¢Ÿ•˜•‘›…¬{w¨v£Žˆ†©o­Š‚§ƒ˜˜¡‰’šŠ¢“™‰®…‚³\r³R®}ƒ‚¤q×}x…~†™šw¯†Š‘œˆx³ašeš‚”l’Z°XKšu˜yf`­^vw‡h˜ˆk]¯w•žxl5yÈ®²_BSo^g`EPm_pmVUM.echRXQ;AD@L:5?91=<16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK97<46:>/04333.2..18*.32%!03767=Pke>&Vg\@>V_cN6GC`I:99Ÿ• ¹°—´Á­¨³¨©²º·³¸¿¹·±´»´¤·³Ÿ´¬ŸŸ¨¬Ÿ”§µ«¨±±«­´¤›©  ¨¡¶§¦©¢™•¤¡“’›˜‘”¢¥š’¦­¯¦ •™©Ÿ¡‘¢™¨¥ ”™¥¨œ¤ž¬¡ ”žš¡˜™œ–—¡ “˜¦ž†©}}¥x¡Ž‚ªp­‹§†–Ÿ¡‰——ˆ£‚‘ˆ”ª|€‹yo±Z¨‚‚ˆ ytØvˆt¨Ž›’£|–Ÿ„{²^œd ~ƒ•l’\«[Z“‘hgªdr{k˜‡s]¬Z‰ ŽkoeOJC¡\[Lt]bgM[a^qs^JV6J›“XHE=GFAM35A8.;>05A78@<6=<F?:<6?=B7.HVJEAH6KIN@IK@EN::@4.;>102144+*05/7,&21($$6671<PeeA&Uf[?2U_bL7FI_C2?8¡šš¿«—´Â®¬­©¦´°·±µ¿¹¹±°µº©º´Ÿ°¤ž¥§§ž“ª°©¯©µ¬ª¯¡˜¡ ¦¥¤º¢£« —›‘¢ ”“ž™“—žŸ‹¨°¯¦–›¨¦ž‹’¤—¨«§”–©§žž £­¤¡ž¡•¡˜Ÿ ’—œ•¡•–«œ®mr´r©ŒvŠ¦s´xs³€‘¤£’œ‰¤‡w¸oŒ{‹¢kk¶Z …e——i¡¢§m“r´t“˜²j…’ˆ­ku³af¢o‡’j—\­_M¡|‡‘Rs£ly~o˜‡q\¯V<œweTon.\§OcRkebmZc\_ozbTZQ>>mo3CB@?L9!7@6.;@37C58??3;<CDBJFMIF62JTKEBI6IJP?HNCFP=<E50;;010/75,+,426/#00,,289/9N`eD'UdY>/U^aL5FM^81C8¥šœž»¡œ²À®®««§·©¸¯µÀµ»¯®¸¶ªÁ¶©© ›¦¤¢‘ª©§µ£²§¯ª —œ§ ¤«¸£­›–™¥£•Œ š˜œŸ‘“”ª¶°§™”œ¬©•‹“¥™¥­¢–ª²£Ÿž¦«°˜¡£™¢–Ÿ›–œ—¡’œ©œ”«™‡Ô’š»s°Ã€Ã†~Ֆ›¸xˆ˜Œ˜ŠŒ§ˆz£¶u}wv‚š²`ƒºyÀ|u¸bµŒ‡©}•¬©q{u¼ˆ§ ia¦Ž¯¡~Œt‡ª}¾ns¼t²ƒux‹nšˆqn¤t½^w}[ay¼kZV[jz^jaegalwnY[YCA@r@CG+5G"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-7A9§›ž¢¼¡—±Ã°­ª«¬±§¸¯¶Ä±¹±­º¯®À±«¤¢ž£¡œ›©£ª²¤µ¦­¥ž–™ª™¦¬¹£®˜” ¥Ÿ’Œœ£—›‘•’®¹²¬•—£§§“–¤œ¤¬ž ¨«Ÿ›Ÿ¨£³ž£¥Ž§¢”¢šœ˜•£˜° ’”©ž…™µ€‘Œ·•x‚“šµwmknsoy„Ž‰tžÁ»½š{²¨p€t‘¹ƒ|††Œ†{Š‡—|¤»¹½œuz´£tv—ut°u™žf†iµtrpw¶Œ^€z}Šhƒymyc‹¬pu…Z[§jEdYSf`c^cQgfpluBMPLD:ZM?J3<0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITBKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7LT_G'SbW8*O^]=+:VV'>;<§ž ¡¿¥–´Â´¬«¨¬«©º®°Å®´²®·§´¸­©¢¡¥ž ™“«¤­ª¦µ¨§Ÿ›– £¬¤¾¦¡ª—”œ¡š‘¡¨¡“˜“—”±µ·­˜¤¤¢Š’’¦›¥ª›–©¥¥œš¡¨¦¦£©¡‘­ž–£ž———ž°¨”›§¡Žj~iœ¦x‡r}šŽtzd‡{½¾Àºo’‚q•‡asjZ^›ŠacˆŽ•k`€•dmwb•k€š•”e^acqšŠirŒ}…•gj~rtx}~b[wthP\n„}|‹kXlz‚sJJo†pMuMEW^f`KZWgc_O[muirRODEN;HH=L?2-2A?8/5?C<9;@;=C>RVVWYZ[\\]`aaa`\UG5DFUEJOHFPIIH;8=51:.0;:.0-76=5&"/*2,%;8-7JR_I'S`V4)P_L(3=[O'?2>¨ ¨¡Â£š´¹µ£¬¥®§§µ±«È«°²«´£¾±²¦ ¢¨œ¢›™™¬¦¯¤¤µ©¥›—•¡›¦­¨¾§¨¦•“›•Ÿ™’—¤©¨‘˜œ¯²¿¬›§ž§¢ˆ“‘©š¨£š›¬ £šš£§¬¢Ÿ«¢š±›•§ —•Ÿ—±¤—¡¨™œ‘œ¢¤˜¦¢šœšš™•gn}qw’—”‘…‹µª†˜•ŽŠŒ˜—‡”•Š„’”‘‰Ž’”˜”˜—š ¢šœ”¡ž‚z¤†lj||€u‰Šq‚xyvv‹€|Škstƒuev}wkp{m`c]pgLXZfj`WZoymmfSOFS9OYMRO(+:KB635=@A9:C><ENSSTVWXYZ\]`bba_^^[TKCSGKNDGPLOI<:;389,2;820)6IRO8")+/2#4;*7FO[J&R^S10T^:+=8\K,<-@³¡³¡¿¡¤±²· ª¦²§¥°´ªÈ«¬°¥µ¦À§´ ¤¤œ£•• ª§¬££¶«Ÿ™––Ÿ—­ª¥Áž«¤•’œ——’“¢Ÿž¢§“‘™¨§²Ä¯š«ªŸ––¨ª›œ ¬˜¡›œ¢¤¯¦¡¥¨Ÿ®˜—§™š žžœ¯ œ¡¦•—’˜“ ¡•£ž— Ž–“ŠŠŽ—®|•›‚’‚‹ª¨†™—Š„Ÿˆ{„‡†š’ˆ†Š•›—‘˜ž£–š“‘žŽf¡³¯…Š„v{Š|vyzofz‘€‰kuyˆsiszuƒ‡‚kudyf`iecdfkYl{oij\RLPD_TE@??,4@F;45;>A;<?>>HNNOPSUVVXZ\_aca_^^]^]XVJKLBIOMRJ;<:786/2964.(&$-1./)+*7%+<(6CMMD/T]Q05M[17E4\G5<,@´ ¹¯¿¬«®²± «¦±­¢¬³°Ä°ª«£³®¼£´›Ÿ¦¢¡œ™—§¥©¦¤¥²´ž•”™™°¥®¾ «¢‘š™”‘”¢œ—¨œ„žª«¢³È³Ÿª¤ª––—š§¨šŸ¤«“žŸ ©¯©¥£«¢®›Ÿ ¡˜¤žœŸ¯£˜ž¨“—–œ‘¤˜—¨š—e‚’|e~šdylhk{’¤ªješ˜~g†Šeeih{Ž¡kh—‘£wkj‹™£ž™sln{„‡zXe^†‚^l‹‰€v\hsww’€‡‚nx‚x€smy„tw‰ˆŽ„|j†Y^ktd]s‰ik|qkc^QMWJdXAJ4=F7?FD71<=?AD;;DGHHILNPRRTW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%/*+'6*$;'/AJ[J/7ZO6)EY/DO1YC;?.=¥Ÿº¼¹¯¬³±ª¥¨­­°¦­­±¼±©§¤­¯°Ÿ­— £¢™™¦«œ­£¥¨©²­ž•£¢¯¦¶¹¥®£ŽŽš¡™“’š ™™¥•{¥­¢¨´Ä¸¤¢§¯ž”ž¢ž£œ£©¨’ž¡ ª°ª«¤ª ª›§Ÿ¨ ¬–¡›¥°¤—›ª• š’¥—žª˜ž~½ƒˆr´r„†­hx¹Ä¸q“¢£z¦™™sª‚|ËÀÀ»qŒ¢ˆ‚Ÿ}–˜‰À½‚—ÂÁ|‚|’šÃÀ}k¥²oŒoÊz›w‘ƒŽvz€yqz‡qx…“ynx”cf_yd`e‚c^tgldbWKUIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^__`_^^^^___]\SMPGUNA??=6468276*&%#)*&.+*)109*#>I[L*#BQ/#F[3PY/UAB;/8–£¹Ã´°°À©¨”£¯©°®­¦³´¯©¥¦¦±«Ÿ«˜š¢Ÿœšª§¢¬£¥¨¤¤´¤¢’¦­«¸³§¯¢‘‘™¥’Ÿ¡˜›Ÿ‡§¬¤«­ÀÀ± ©¯©—‘ž¡™¢£ª£“ ¡ž­®©¬§££§¡¦¥­©’¤š¨­©›œ©œ¬ ––¥•¡¢—œΔxz¤y•–›_®^Ž§¢ |§–›t«ƒ€¯^cª{§‡… t—“ˆ³c‚«†¡³j…¯t}—ˆ·aƒ­Y¢Ínu{Ú{™p~ˆ’v~e{ˆvvk|ˆo}…‘‘~mƒ`rlph`_yd\qhjcf_QTRW]KOC5AHED8>6;@?A;=8@>??BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5578164('$!',&&/(&+360$7;SL+,-K0';\;L-!P@F4.1­ÂÀ¿µ´°¸—‘¤ª¨­´«¦²¬¬«¤«¦°ª §›™¥—œ¢¯Ÿ ž¨§£¦¡Ÿ°¬š•¦­¬±ª¨¬ ”’›Ÿ¤’ž¥˜§£ž®¤«°¨¿Ç³¨©±®–’›¡—Ÿ©ªŸ• Ÿ®°§«©œ§¨¤¢«“¬³—¥¢ªª£¦¥¡° ’™¦™ š””‘— q…Œ—t„¨‡q±|q¬~¡ž¥žwª‚}­œs­~«‡†Ÿv˜’{|—~ªˆ¢Œ‘Œ~«{‰”Ÿ€{­VœÄzo’Á}•muoŒmeve†oawnro‰Š’ƒm’fpuuqagme_oiingcWS\aYRSC8II@D<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;91478452&# 1' 1' '45-&7=WJ-<'>1)3V@F!G:C1.+°ÔÆƲ´ œ£Ž££¢¬¯¶¯¨±¦¨ª§­««§¢£™¢• ¥«Ÿ¢¥ ¨¨¢Ÿ°¬—š—¨¦®¬¨¦©ž—”š£¡‘“ ­›¦£¯¬£¬µª¹Í²­¦­¬–•œ¢˜ž®¬– ™žŸª²©ªª›¬«¤£¬›¯±¢¨«®¥˜¦ª©©±¢’–£¤š”’…¤j¤u‰z©tz²p‚¦Š™Œqˆ š‡¤`aR«„®ƒ›v­¦††Ÿz™—†{f€£‰¤™†‚¤}©‚•‡®_}©U¢’z¢Ÿ€{ïŋr¯³³¹qb©¯ÂthŒŒ˜Žmš”pnyxypmfeeqpf|ib]W`iXXULLQLCCAB;C@@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799664,&$" ('"+-"$.!3-&@DWH,G+56*1PKL# A9D4,'ÃÉÖÕ¿¡™«§¡¯¢ž°´°¯©­¢§¦ª««©¤¦ ›¤ž¦§§£œ¬š¢¬¡¤Ÿ¯¢œ›“ª£µ°¯ ©›–”¦¢š¢¨  ¥œ°¦¤¨±¬¶È²µª«©•‘œ¢˜Ÿ¥³š ”Ÿ§¬¬¤®š­«££ª¢³®¢ª³±¡š©¨®¯¶¢’•¢§˜›‘|ªlž„‡u«y|°o‚¤‹‰Ÿ––Ÿ”Ò¸´¸É€²_`”©ƒ£ˆ‡ z˜–šxªÉt™¤•¨ª‘“šŒ€œŠšÆÇxf¡‚¥sŸŽ‚}¯]p´b°uK£†m§G‚“dŽž’|q—“€q{u~|n[fjrpej_aXdm\^YINLKEDAB>A<B?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75685/)(%&%$&),4ENPPMFKJVF*L0/=-5OTQ;<F2,$§¤ÀƸ­©³­¬¥¢œ²¹¬ª¡¦š¨¥ª«ª§ ¦¥˜ª£Ÿ¯«¦ ¬šž©¥§µŸ¢—“¨©µ²¬œ¥œ ”¥¬‘™›§£ ©¦®¡¤§©°´Â±³ª­¨“‰—¤š¡£®¦˜¡•™œ¦¦¬›°®©§ž¬¤·¬ ±¹¯›®§²³³¤“—§¢™ŸŽ‚NxšŸzƒ£}ƒ¤„†¦žœž“„¸{|y¹‚~Ìƶx›¡‹Ÿ~š–—Švž˜Š¥˜¤©°……Ÿ„¬}š”b¥l¤p…}–‚r¬`£sq€š`¼}RUtŽ’£–{~“’Œv{s…q\mnxrjo[d_hnbd]KLQTAIHFI:9K>B108866877-*5==?BDGILNPTVXYZ[\__^]__\ZZZYUSOH@882.,*.+*'&?QTVWWWYXXWUOUF<E3:P[T6?H,- ‹‡™©«¤«¹ª¯ ›¡¬³³¥Ÿ •¥®­®ª§¦¦š£§¡³®¢©§² ™©¤”¢µ¢¢•—¡¨´¹£›¢¢“¡±˜ž›§¥¡¢¯®¤¨¢¶°Ã±­©­©‘‡œ§œ¢¤œ¥—ž˜™š¦¤©š¯¡¯¥¦˜¯¥¼­¡¶·­µ²¸°³¦—¯ £…ÑµÃ·y‡Ž…‘“¦x”¡wŒ ‘„¥Šqª†„´nrj™£œ•Šž|˜™†‡s¯‚¥›¢Ž¦‹“Š•›mp²\¥s“zœl™{™|m©a£qqŸbs²¸hw”¦˜}Œ”Žy}y‚mixiyrn€u]ednmfg`J[XX<HG@U3@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^__][ZZXURRQF:2230/++(@QRTUTSTVWWXXWUUVTQOQ[U%!2AH$)%“sŠ­¿¿¼º´ž–§¥­µ¡¢™•£¨§®«¬™¦¢Ÿ¦  µ§£©§±£”¬£Ž¤­£šš¨³´¤¤œ©‘”—­ŸŸ§¤§œµš¡ª¤¶ªÂ°©«©¡Œ„Žœ¡ ¦£•ššœ˜›™§¥¦˜¬¨®£¥›­¦¾¬”½°¬Ÿ¢°²¹«´¦š¨±£§—z¨}|°wŠ€¤¥ˆœm²o ‡­|¡Žƒ¨•˜€¬‰„®…Ÿ”ª¡¡—†Ÿ€™•€{’~«€š—‹«xŸ‘Š”’z¯]£}¦§d€|—sj¯]¥kp…™]`[Œ m•‘¦™‚•Ž˜Ž|{„˜kmc~tn€z`geqnhggCZa[>KT3U8BBC7$$3+''3, /6674359@CFIKMNQSSSVZ]_a`aaa]][ZXSPONI8052.*,ATVVVTTUUUUTTUTSTVWWXVUUQHFIJ#((½“šƒ©Æ¶Á´Ÿš¬ ®¸¥£Ž›¤£Ÿ°¯ªŸ¤Ÿ­™ž¹ £« ¯©š®¡«¨¤–‰š®±¬¦ž¦š«–—Ž¬¡¡¥¡š¤œ­˜ ¨¦¶¨¿¯¥©¤Ÿ‹€›šŸ¦ž’”šš”šš¦¥¥›ª¬¬¤¥Ÿª¨¾¤–쪢¡«²¹ª®¦Ÿ³®¨©˜v¯~‹œ…‡}º®Š˜e°Œe•­}¡ƒ¦•š¬Š„°…¦™¤¡¡‘… [lj³`­{{‚±mgo™˜Œˆ±[}´\¤ƒkÈ¢dŸ€{¼XvµZ²}R®€z¬X€¡n˜¨›‹—‘˜˜|z~dt~b„xt€|ajgqmfeeOUd\BU_>J(>9=4!",%2. *1/04579:<ACFHJLNPQRTWZ^`_`ab^_\[XUPNJFC553./@UZXWXWXXWWXWVWWWWXWWXYZZ\\XWWGB;ҟ³²·½º³Á³£›¬¦¥¶¨ ‹š Ÿœ³³©Ÿ£ žµ˜ ´¨ª¬ž¯­ž¬›•¯¨¢Žˆ›Ž¯¬¨§¡¦˜­‘˜Ž¨š¡ž¤Ÿ™££¥™Ÿ£ª²¨»¯¤¨žœŽ}‹›–¡ ™‘š›’š˜© ¢š©®¨¦¦£¥©»ž Æ¦¤¨¡«´µ¬®¦ž»¬¬¬•€©’£¯Ž›€‡¤—˜€¸ÃºƒŽœ“„§–œ‚¬Š‚¯ˆ¦››¥ª‘~սªb£¿½}~£‚ƒ×º¸µ…”“ƒž½¾„k£o«„lœz²°Çƒj«°½¬xw¢¾¼s–Ž§œ›‘˜ž{‚’›zc}{dŽgy‚{`lekjbPaZSj\@UaBN*=:4/$%2 $(0496678:>ACFGJKMNNQTW]a\__a^`[\YTQMHC?<A?5=SYXXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ¼•´´±¿¹²½²¢®¦¥²¦Œ˜¥¿ª¸²¨¡¿¦§²œž±œº¨Ÿ­¯¦¦””°¬—Œƒ›‘®¥¢¬ £›¨ž—Š£’¦ž§œš¡¨¢™ž¡¬­¨¸­¨£›—’{‡™’¦›“Ž‘˜˜˜“©›¡™ª©¡ª§¡£ª»ž¨Ä¢ ®£ª³´ª¯¨Ÿº§®®šsuª¤·†d‰ pg­Šmow¤™Ÿu®˜”p‹q•¨£›—®¤rmmlf‹xon‚™qzjqig‰––˜rii„‡gp†d]ˆbjoY]g~w¦_aqŽ‘nee“¢˜™™‘˜ ~ˆ•vf‡xiŽkyydlcflbKdXJlZ:QeER'K:+# ",)-2.5:4579<?ABDEHKLMOQSV]WZ\``a]][TPLHD=:AB7MXZZYYZYXXYXWWVWY]^^]\\\]^]^][[UW^©•­³©¹¸²³ª©¡®ž£²©˜’¾²Äɾ¶ªžÀ¬¬£¡¨¬ º£¤®¬­¦—®©Œ…•–­ž¦ª £¢žŠ¤’§™¨™–£ª –œ¦¦§¯º«¬š›’’{„–¥˜‘‘˜”—•¨•Ÿ˜ª¤›±¦ž¢«¹Ÿ¯À§¤²¥¬°±ª­«¦·¢­·–Š ¨¥¶‰–£™‡©š”’©²™š£« ±–¢  ¢œ ¥¡•«§“’Œ‡“œœ•š“˜‘Ž•…¤™—–Ž‹““‹†„}g‰~t‚vt‡‹q§lz”‘“’•¡–š˜£ƒ‰–riwq‹xw|zjldcodU`X@i[HcaOZ+F=+'!740.!%2(*699469;>?ABDEJKKMPPQXUVY^`ac]^UQJED>9=@ASX[\YWXXXXXYXXZ[[\^__`^^^__```_YY`¦–©ª¤´¶®®¢°£­Ÿ µ±Ž¬Ç½Å»¹«¢¦ž›¦Ÿ±¨£¶§©´§¨‘˜¬¢‹‡‰›¨•¬¤Ÿ˜¦‘”£—¨š¨™”¦¡£š§™¡µ»¨«˜™{”Œ¡”Š•‘•“—¥Ÿ›ª œ¶£ž§«·§®Á®£¶¦¯¯°¬©©²¸ ®¼™‘¥¤¦¶¢’ž§Ÿ©Ÿ’Ÿ£¬¯š £°¨¯—£ œ£ªžžœ–«’™¡›”–ª™™™––ž‘‰ •”…’Œ”‹€}f‹…u†uyˆƒsœj…”“‰|‹–’’—”¢“ž˜£…‰™ˆ{r–sz‹r|jod^pja[_XmcP`dPZ:GGE>2==8/+&+)&&416668:==?AACIJGJKLMSSSUZ``i`eUPJACB:9EMV[^^[Z\[[[\]]__]^__aabaaa`bbbdb\[c—•¤¨£¯²¬®£©¦­ §µª¥´¼¯­­¢£šz¢±¤¥±©—œ¸¦£”™ªœŽ†Š‰œ£®ž¢•§ž ‘–˜›®‹©–¨™¨Œ˜©Ÿ¹¶¤¥˜šŒˆy‚”Œ›“Š•’”’—¢žŸ©žŸ¸£€„¯µ¢¯¯u¤½£²Ÿwy ª±º”u¬¤ž‰€ªd\bv Ž¤ž„—}n“³œ£§­ª£eŸ’sy™–p€˜¨—l¢¨Šeœ¥œ‘—˜–Œ’œ‘†š•ƒ’‡’‰„wjŽ†v†p{†€ai‡Š”’‹Zu”hhs{¦ššf{š‡ƒx˜j„‹ƒoy€kqe_vplkh[febbpS\>NNNSG>@TD91/&4:316678<;>@AAFHBGFIKMTTUY]`hfgWQJ<DG<8UR[`ab`^`_`aa_\]__`aabcdabaaedchd^]f›•¦£ ¯°¬«©¥©®£¦­¤’–«¶°²§›«¦¬—tŒ¯Ÿ¨«§”—¹Ÿ œ¤‘‰‰›žŒ«™¢”¦ œ–‘ž„u­Žˆ¦š©‘—¤ˆ›º³§ ™—Š‰uw“–“Š”‘”Œ“ ›¡§™œ²–€Œ›µ³Œ’»§ ~§¢z¢®¶€ŽŽ¦žƒ‹†±ª¯ŒŠ–£šy€‹¬†œ¡§©§‡•…˜w¥›z‡›—§‚‚{œ²zŠ† —™”˜–‚‘—–„š™by‡„Ž‘ŠƒmpŽ‡y€p€…†t†„•‘x–g’t št}™„¢žˆ˜“Š„„™kŽŽ…lx{qqgdxojljZekjet\_ITLQ@E5.ZTU7)!09=>743568;:=>>@DI?JEJKGSX[Y[aaifYQH9EK<>aV^bdfd`aa`bb_]`aabbbcfgcba`edcgcaahœ—£Ÿ¦­®«¨¬ ¨±¦¦©¥™”®È¾±¢—§©µž„¬œ§¢ ¾žšŸš |†Ž˜—‡ª› ”žŸ‘“‰†§Œ†¢¤”˜ž†ž¹°§›“Ž…pu‰•Š”›Œ’Ÿ’—¡¥–ž«‡Ÿ´‰´š­ŠÊ‡ª­ˆ·…Œ¯‚¯¬‚©¥˜}¨r{wœ§–h•¤y´ŒŸž¦¨’˜Â«ˆ˜¡rž€š¥}—…•±€¡}¡“ ˜—Ž“›Š˜‘‹|…’†•’‰ƒmr…yq†„|„u„–€Åf©‡£kžƒ£œ„š€Ž†Š™qŽ“…hwt|whhuqhhk]cpmgmXgG]RM2D46Nac7&3<EGD:64658;8>==?BM?NIJLCPZ]\Wa^jm\QE=LM@JdX]cfhgbbbbcc`_babccceiicbbbecafcbbi”—¢Ÿ°§©©¦« ¤¸°©ª¦š” £¤«¤—¥ª·£¯€¡§œ¥ž‰”½™“¡’žy„––†ª˜™š™ „Œwš›Žž‡ž¤œ–š˜†¢¸¬¤šœŒŒ~bm‹“˜Œ‘’ ”¡¡™¡§~¡§‡­ –­žœ‘…€ ª­…£©™Œš£u€™”k‚¬uM«x‡œ‘›¨§€©«}ƒ¡{z§iž’kg—†—¶‰ž~n`dYƒ—Œ{dh‹r™}y•l]|–m_Spƒ\_kyƒ`Ye‚}ƒ€—p§ªkƒ£nr¥pŸ… jf l[n‹|fZ`ƒbWPowfmtrkjo]jpmliXiO^XF9A4GD^k4,ICRMN=84859;6@;;>BO>QRLMBJ\]_W^^cv`MD:MOMTb\\ffiibbdbddbab`bdcacikdbddgdbgeach—– ¸ ª¤¦¬‘¡µ¼«®¢™˜ ¢¥¬®¡®µ£¨’¡ Ÿ¦›šŽ™´™‹ŸŒ•‹u”’ŒŠ¦•“—~’……«£‡šŠ˜©™š›‘‡¥°¦¡•šˆ‰€inˆˆ‹ŽŠ‹’Œ’£Œ”Ÿ œ¡¤“£¡” wœ–§ƒ¡§†¨«ƒ¥xŠ|„š~¢ps”ˆ–{žŒym‡›Œ™›¨š‡{‚¢sv¦fž~w¤_˜z}’s¢n˜·´ºt“‡‚µ¨dÆ¸{p•·‹q€š¤bs¬«`}i³~n|†‚‚‹˜q£lr£tŸ…¤`˜²•q|—Ÿ³ts[ž²ƒjbotvqioXjlrrf]i^cLD=D6QAYq3=SG_JR=<395::6D;;@JP?UMNQ@E_^[ZX``|dHC8LWUVcaZefkkbbeadc`ab`dd_`cknccddhdbgfchh”–•£¸™«œ“ ¤·µ®­ š¢££¦®œ›²®­“˜¡™¡¤™š”Ÿ«›‹ˆ’x‹…q€–Š¡‘“˜}‰¨ ‡˜ŽŠ‘£”œ›Œ‹¨¨¥ž—‡„~k{‡~}ƒ‹‘‰” ƒ—ž  ž‹‰wœ˜¢ŒŸr¡‹‡¨ˆ›¥•¦©}­Œ~z ™z£“xt–ˆœ}•Ÿ†›Ž™›¦†¢d¡|ˆ–›lžhšnš™{€‹§}rht«ƒžƒtªh•š]›…v„hªj€¸f\¨pœ`•Œ^§vu‡‰~žhšu†“’—Ž€Ÿošm§™\¨~x»j}©[Ž„]³g\nrzxki\pjxyc`fXbBQFO7VCRo5KZZ_OZD@151;;6H?:CHU>YRY]>Db^V`Qac}jEB9N[]YefXfgnmbbe_aa__``ec^bdoq_deekecihgki•œ‰ªµ›§ˆc”›«º²±¬ž¦œœ©Ÿž®›ž±©¬—¤š¡Ÿ˜––¡¤™†‰jˆ€r{—ˆ‹––„“˜zŠ„•£œŠ”†‹ž’‰Ž¨£ šŒ‘Š€€i€†x—Œ{‰ŽŽˆ–›”¢Ÿ ¡“˜rhŸŠŸŒp’Œ©‡˜ž¡¦ž¦{°­£¢¸—w£³¢¤€ˆ”y{ªš¢Ž›—ˆ—q¡|…¯µ}kš‘¡x~˜´££«¨„™|›}štªZ]o{–‹xžbL~zz…cy—BLžY¢jr|Žm€ˆ„™u›x†‰±³€›“§w‚mr}”o™rj£]•vHedasq~~nf`liv{debR_W]UW@ZEQhDSW\bX^ID=B8?B:IF8LEXAWR[VDFb\Z`K`m~rEC<U_bZfjVghmobfg^aa\]^ahb_ecvl^egfkdflihki“œ°­™„S^ ¦³¹³³©š¢Œœ«œœ©”¡¬¥¢¨Ÿžš™–˜¡–ˆ‡‰w†oy•…›‹|‘–ˆrˆ’ ›s‘ˆ™•¡›…¨œš•‹‹Š|ƒl„…q¡Œx†ˆ‡“™–|“£ ž£ˆ­†}µ„Žžœ{¥–z©•œ‰Ÿ›|§hwm~™t¡sq|ž†™p“ƒ®}¤ƒ¦ž™€£o^¨gu¢co¥aœÓ|{™xrsc¢†~£s¤vk³Œ`‚˜‰sª²¨¼wƒm~¾¦©´^œn}q—nr¢r]¤gs¦ah¦m›Ôš}…›oxz—k›{w—sn©¤gaeyq€„kgfdnuwg`cS\fQQbIWJTaWS[ej\eQFCKMJKBKE8O@QNXSYOSQafejRcwywIFEc]eZhjTihjocjg`c`\]]_hbahe|d^dgdkdjmghlh—›°«T\K~©¯±´°³£›™…™© ¡¤Ž¥¨ ˜©Šš˜˜“™“’ ˜Ž‡†{p}„h}ƒ”šwŒŽˆo~…’’l—“|‰‘’¤–ƒŽªš“’‹…‰zƒv‡€nŸ†w€“‡ˆ™¢—{”£¤šŸ‰³¡¢¶‹z¬§¤®¥p¨€š…€›‘{¤€¢™†˜rž„£®¯Š—ŒŒ¤•ƒ­¡”v´µµÉ¡s”Šž`—©my•† ›u¡‡w ~’—‹oLf£’p›‡s¤{ztaƒk~ kqd_œq}t—izi³µ´Æ¦s˜~zkœ›«u„›mux˜iš{u˜rPE}´^jvkyˆfjhbtupnV^TYiPSiJVLYTV]hknVhWNKAJMKHJOAQKPecjmeussy|nu‰{{TPNl^h[kiRjhilglfce`\]\^ibdik{_]dhcjfoleile¡œˆ¯¦„f?”¡³«¯¯¶¢¢€˜ª¢£¥Œ¦§¦‚›—–Ž—œ“Žˆƒyjy‡eƒŒ— yu‡‹€gƒ…‘ƒŒ…zŒ‹•¦“ƒ—©˜Œ‘‹‰z€}‹yp¡†y–ˆ‰– •”¥§œ––„fnxœl¢d|q¥w›˜pg¦€–‹{¤zŸ–ƒ—ržvŠ”–¹nŠ¢b}™¡•ˆmriªku mn¦_ši‹h–‡š•u¢€}š`Œ†uoˆbh ež~i›uocfˆ‚mr¢Z_[b¡m]‰Œn{~srd¥mw¢dg§h™sŒ™o¢oS‰o _f¨T‹^T˜nmskr‚mpikyskoRYWWgZTmJYO]IXiisjYkVQREV\LXSaUik_wt{}p}|rƒ{sv€„v^QrbgbpgPjhhklnhdg_]^]`kcjivu]\cicjjslfkmcœ¤˜¦zetm‹§®¤©°±¦Ÿ‹€˜«Ÿ¦£¡›¢¢€–™“Žš‹˜ŽŠ{†q€ˆh‹‹|˜›stˆ|zc†”‰‰•™‚|ˆ‡–¨‘¢¬‘†Š‚Š~€€Žsi¥„}†”Ž‰˜ Žˆ“ª¦‰¦x•›~¥ˆ–Œ²˜ž‚¯—Ÿ¥w”‡y©t¥„šn¤¢Œ’„Œƒ»n}¥¯ƒ†††“•œŸ|¥zr¨• –fž~o«c–Š•’x¨l©¢‰vˆƒwª‘¦‡j‘°kv³Œ©kŠ†mmŸž’•`~«‹ªv~Œ¥žvŸ}„¤• j›ˆw¬gŸ­Œ¶tw¾¤“Yƒ¦«aurtq|tqcj~nhlSW[Vab]kM]R]J^mnv`[qY\`[ftenoqbqt`wz~yryƒs„{{Œ‚€vbxdcmsdRkgholrjfia`^\bkbmlzo\\bibljwmglnb•¥ª€ž¤–©ª¨§®¤™‰ƒ˜«šŸ¥Š›¥©…Œš‡œ‘…’Œt†zˆ„p„~˜“tt…r’ƒl‹‘‡†“}{‚…˜¦Ž¥¦ŽŽ‰…•v‚‡’ol‹©€ƒ‹”Ž‰œŸ‰Œ”ª£ €u”—ˆ~y”®£›q…xŠƒ~{r§Œq}}z—–›„Žx{~~‡”•“Šv˜Ÿ ƒ{}‰kŒ…[yyrzphn~’‰qu”“q†„‚eŒ^‹wus”uoynn‡m„…^vhxŽe€€…©›}t|–j‰ˆpv}†vmmgŒsy{˜x…\kXyinxrroxxp]l†nifV[`W\fkdVbU_Q_pxxlkvfjkkv}qrtsaoubt{xuzƒu€y‹…ƒ}{mldxn^Wnghukxjije\`ZcjflqunZ[bldllynhloa”¸¨¦‹¡¢š¦¤™¥œ«£¡„„˜¬’ž¡‰›§š©˜ƒ›‹–“‡ŽŠ‰rƒ|}~…{—Žsrƒp•…{}’‹††…x}€†™¤Ž|§¡‹†…–ƒ†Ž˜wr…©…Ž‘ˆžžˆŒ›¨Ÿ ªƒ‰Ž•š~~‰–­¨’¦woœ‚y‘o~¨…p}•qkp}ŸŒ“ŽŒhm]ƒ‹Œœ›žŽs•‹ˆqtk‚vtYrn†‘}~Œj]jd{…„‰€`ixz›{‚‹‚u…‚gwŠ†kapqv^rŠˆ¦•…eŒƒnw‹„q†zpfge{ƒz–[\jgnv[{yxunss‚f\mŠkkaYZ_ZYlq\_aZ_]ft~ztptckkk|}s{xtdmuhm|~vz|{zz€€~o†Š„{}s~ysiT\qiluougkhd]aXkhlkqrmW[enlgsyohjm`‹‹ª°¡£¡šžž˜ž™¨££~ƒ™­ •ˆœ¢‘¥•{˜…}’™‰ˆ†‡Šs}Œv…‹„–Šqo€r˜†„~’ƒ„†Šz€ƒ‹› ‚§¡‡xŽ˜‰•‹‹œ—„ƒz¬‚‘—™”Šž‡ˆ¡«Ÿ¢¢£‹ˆ“›œ£™–ª¡§¦ ’›‡•{wŽ„§~’‘’“œ²¦›•ž²“—„¥ŒŒ•›Ÿ‰›‚ˆ‘Šk|Žwxe‚†‹|‰„‡‹ˆˆ€„„w|yt™¡ˆ†‰žŠ„”~}Š€€uos„‚~w††Š¦ƒ…‡ƒŒ}ˆŒŠ‘ƒwl‚„}z™jrhatŠp}zwwpwt]^o†hn^^Z]]ThrVc\\blhu||sopdkki€|nyqjpplg{r‚€x}„{m‚Œ†|zx|}zƒyNdwjrmpzekecb`[tfpfrqmU]ltmiyzqgikdŒ‡¹ž–¢¡˜•˜™•™¤¡ž|€š«Žž†Ÿœ‹ž–}y”ƒ{Ž™‰†„„†nx€€rˆ~‰”„mk~z—‡„ƒ€†„†}‡„Ž›’‡«Ÿ„r‹†“‘‹‘}{ª„’˜–œ–‡†›¦Ÿ¢š†‚’š™˜š¦ ¥–‰u|‡Ž„¥{|Ž‘†˜ª¢ž“ª‘€Œ‰“šž‚Ž—~†Žƒox†ruaƒ†u‹˜ƒ‚†…~…„”nyut’¢Š‹…š„„Œsˆ||rr{‡ƒzxŠŽƒ’¦…ƒŽƒŠ‰Šw†‰ŠŒ}ol~|nhlmh_zh}{vuvu{w\_p}nt_c[]^QgnTe[^bkivz~qlmdkjg€lslluoyp…yn‡€v‚€~…vq‚ˆ~{{|{‚Š`i{juhi‚djc`i\duhobtmlUcqyepz{sejml‹‰ž·š¡£Ÿ’‘–˜‹šŸŸž{xž§‘›Š†¤“‹˜™yz…|‰‘ƒŒ‚‚‚n{xs…}‹‘}kh}‚˜‰€‡|~†„‡}››‘‰¨œ€pŒ‹Œ“‡¡¢Š…Œ}¨‘ˆ’˜”–“xŒ£Ÿ –™€š˜’Œš£¡¤š—‘š}Œ„x€ƒŽ† ~ŒŒ|˜¤¢¢“™¦ŒŽ€š‘‰“—›~“’~‡Žtt‚pv`~€†qŠ•|ˆŒqŒ‚…†Žhwqx‹˜‘~—}‡Šr†{|qxzŠ„zy‹‚•¥“‹…{††‡…v‚„‰ˆ{fr|y{qljf_~sh|uvt}s€j^`svpwdcY_^RkiTdY_ahjvyqfkdlhe€km~hoql~x‡zkŒs~tv‚†|z}jr‚msib‡hlb_qVtomn`xhmWjtvcuz{rbjoy‰ž²’¥¥œŽ˜† ›|v¥¡Ž—Œ¢Šˆš–x{†‡~ƒ‰ˆ‚q{tv‚…~Š‘xgc}†—Š‰Œy}€ƒy–•˜–– ›~pŒ‚‘”†¦›‡Œ‰ƒ¦•…“‹—˜“’w‘  —“–y~Ž˜—Ž–š¤˜’”šxŽ„‚w„–~‰Œr—£Ÿ¢“™Ž¡‹Š‚–˜ƒ’–™~˜Œ|ˆ€vq}nzd€|Š…p†“‚l‡‚€‰„euo{†’—Œ|“wŠˆ{…|{q~wˆ…y„‰Š—¢•ƒ‹vˆ„‚‚w|‚Š†w`yx}txgleaijwstv}q|bcasnurmaZa^[leRcXaailvy†qcjcmeh}ƒlhuhlpi€}‚ym†q€„ƒt|ƒŒ€~z‚ƒ~|mvˆstneŠljbcuV„iqn`xglbjvpfy|zq_ql†…œ®—¦¨ž—‡†Ÿ“—™}xªœŠ™z–œ‹Œ˜y|Œ~|ƒ|€‚xtyzt}€„‰‹€d^}‹•‡~„†u}~Š}˜„—”—Œ¤¢˜s‡{”’Š§ŒŽŠ“¡’ƒ‘•˜‘‹˜Ÿš’s’”‰ž¦˜˜••rŒ‰k…—™z‡ˆ‰o—ž›¤“•Šž‹†’œ’’•‡™ˆ|Š‰yqzkul|~‹~m…’‚”xp‚ƒ}~Šdri{€–—„~sˆƒx†}vw|…€|‚Œ„Œ”¤x„‚t‰‡}€tv‰„oa{uzq}obocd{bnovsxwstau`olumo\\_^^k^P]Xcbimt{ˆk_jfjchwˆnflhjlh}{wnˆs„„}t†‰{ƒ}z„}}ŽrzŠxxnl‡jh_irb‡hqoevgnlayik}{xpawm‹€™™ª £¨ŠŠ‘†‹ž‹•˜~w®™—}ž“–”ˆw~{Š}{€vx€ptt{o…}€Š|a[~’†ƒƒsz€‡z’ˆ’‘œ“¥œ•‚}‚}Ž‹’¤‰ŽŠ˜›†‘˜“–ŠˆŒ’“‹Œnƒ‘ˆž™¢¡—–‰–m‡˜ƒf…˜Ž“zˆ„Šp•š”£’’‰‹™Œ‚ž}’’Œ™Ž{Š„‡srukpnu{‹tn†Ž’qu€{€€‡{dplx}™“}„ˆtŠ€s‡yn}€…{…‹ˆ„Œ•¨Œz‡|~‹…w~qp†„diytup|b_pakt^pj{yylspex]nlsmrYZ__bkZPWXecgqq~‡f]ihgbgqndigdihzwuoŽ…t‚ƒ{u‚ˆ…x…|xƒ…z€‰w‹{zrxƒjk_pht€jromqgole|cn€zwqlwwŠ~¢—¡¨ ¦›‡ŒŠ‚‡“uª•“Ž‡ Œ•“€t|v…xyrs{…krpzmŠv€‡nq[X~‘ˆwu€ †‘‹’˜¡•˜xŠ€‰œžŠ†’˜–…‰•™–‹‹Šƒm‰‹Š–¡œ˜•…˜‡iƒ¢‚f…Š~‹ƒ‹w“˜’Ÿ‘‰‰•~˜|‘š‘|Š€‚nuplmop{…isƒŽ˜Šqw€t‡‚xfrnu™Ž{ˆ„z“‘yv‡soˆ{…‹zŠ…‚ˆŽ›£‡{ƒu‚‹wynl„‚^strppyZ^p`pj^oj|{qmmjlv`pojqmZXaabnXQTZfgcvo„‚b]kmdbfk’n`ff_gkursp‹€uƒ€xu€‹€y…w‡†wƒ…|‡Œ{vŠjqc|c†|nqltjholvx_qy|tut€‚~¤•š­ž¦–…„—”ƒ u‹ ”“†‹šŒ•Ž‹zrxt‚pr…squˆkomumˆvƒ~€mnUQ«•‡‚wwsƒz‚ ‚’‚““˜œ“šx’{ƒ“¤š“Ž‰•™’…‡—™Œ”‹‰ˆž„Š|r‹…‰ŽˆœšŸ›–”“}g„›†g… ‡‘ƒ‘‚‰qƒ‘˜›ŽŒŒx{’zŽ‹Œ’–Œ|ˆ|€kvjnkll{~az~Ž–‚wz€w‚Œ|ygsls‡•Š~ˆ†{“qyƒovŒz‰‹zˆ}‹ž„|{w‚‹}vpjl‚ƒzaxpnlrtV^obr`_lnyqhpfgsthpkawe]Vf``rSQN\fe^ypˆ|_\hrbbef’j_hd[gp~pkqtŠ}v|…€tu~Œy{†xˆƒs†…~„|y•xfrjƒ`ˆ}ookz`jntu_t}y†xts…|x ™°œ¥Ž‚Šƒš‡€Œž‹š”…ˆ˜ŽŽ„wtvs€po…spqƒojivnƒn}}musRM‚ßȒ֓|puƒv„ ƒ“w•’™œ‘™{”s…Ÿ¡““’Š’›”†~––‰ˆ‘Œˆœ~Ž€wzŒ~ˆŒŠœœ›•“yŒufˆ‘†lˆ¢„‘ˆ—‚…cŒ‘™•Š—‹Š‹qz”ˆ{ŽˆŠ“‘‰y…|~l{erokkyy\€yŽ€{}~~…zzhrjsŠ‰‚…„|”Šk}~n‹~‹†|„yŽ”ššŠ|vxƒxrlgq€…nkuohjtmR^odpY_kqwgkkbfxropc_w``Vk_^vPNKagc]zp‰t\\ev`aeecafbXissmjqvŒ}ty†‚uv~‹s€†z‰~r‰‡‘‹ˆ|~˜vesn}eˆ~opk€Zlnyysav{{vrwŠwyŸ‹›¯› ‚…wˆ•~}Š‡† ‘…Œ˜„“Ž‡twpyqn„omn~rdexp}mz}jhkc¤šÁÜ®ï¡slv„v…£†’o—‘–¡–œ’r…‹£—‰Ž–‹–ƒ•…‰€‘Š‰–~‡{u‰x†„œ›˜™Žu‰um…ˆŠ}Š¢ƒ‰œ„…^‹“˜Œ‰ŽŠŠ„‰m{–}ˆ…‰‘†v…}}k}dxuinxsXˆz’‡…y~€„‹~xeri‰Ž‰‚‚‹–…kum‡„‚y•“˜uswˆuspgvz„cunpbivgQ`qglU_ntyard_h}prnZcrabVnY\xNMLdgb^ws‰m\\dy^`de…`cc^YjrknkrwŒ~tw„xw{‰qƒ„}~ˆ{t‹‰‡–†Œ~—shuqym‹zntp€Wqzvyqexy‡Œiv€‰rœ‡™§œ£’…}pŒ”xy‹„…¡Ž|–€šˆ„{swpsjokim|u^axw{qu{g`d|ëÚµÉÃ܈sltw‹›‰Žj™ž–”‰q…‰ Ž…‹–‹Œ˜”|Ž“ˆƒ‰{‹…vxƒ„r‡‚“›—”—†Œu†~o„‰†˜¡‚“‹žƒ‰aƒ”‡Š†‰‡‡j}”€}ƒ„‰Ž‚q†~qwhvrisvkZŒ|’ƒ…|ƒ€ƒ‰‚uaskˆŠ~~‘}mkx…Ž…‘ƒ||’–ˆnqyŒ†ulpksy‚`ujn]kv_QdqifS`pvt`p`]h‚qsiWghbiXmV[uLKLfg_brs…i[\ey^^dg{ad_]YknfoisxŠ~ss~zvz‡s…ƒ|€‡vwŠ†Ž™Œ‚{“ulwuyx“tnx{|Xz†q€ogyw’‚dv†…qŠ–…™¡™¢Š‡so“‹rwŽœ~‹š‰‰|Ÿ„šxrsnodr~hflwx[_y{{qq€i`faÕ¶Ž¦xnqw|q“‘‡kš‰œ“Œ†{i‡‹™†’‘†‡˜Ž|Š{}ˆ„ztzƒ{q‡–šŽ“”ˆt‚…u‚Š’œ…”ŽŸ~ˆa“ˆ…‰„‰€ƒg}‘€~‚ŒŽ~m‚|‚tkmwutvujb„}|„„ˆ~o_rp„{ŽŒ|~ˆypƒfy‚Š†‹‚{„}“Ž’„noyŒ~umokl{~diljYnvZRiribQbrwlbe^Zjƒmsb[g_dl_nU[pNHOge\gnq€l[[cs`\clwde]]Zklbmjtw†qp{}tx†x…‚}€‡uy‰’–|‰†v‰pwy{„“om|w^ƒtmizt”sgs‡|r’‘ƒšžšŸ†ˆvv•~mv”—~ˆ‘„ŠŽš}Œšv}vqoljau|fbiuzZ_w|zmqecggW^qs–¼Ä„vq”‰~s˜Œ‡œ”ˆtkˆ•€{”Œ„›Œ|‹†}|‰Œ”ˆu‰…uv}qu‡‚ž•†•‚‚q~‡tƒ{‰—œ–†“œ€ˆe}’ƒ€†ƒ‰‰r‚~g}‹{y‡‹}i€}ƒvfoyxsvrkj…Š‰~x‚€„ƒj^qwz}Œ‰…{€~r€hx‚†Š„ƒxƒ{€—ŒŒ}nlz‰}wtoih}we^rcXpsSTnsibNgtxf`^]Xn€osYeb]jm`pOYlRDThaZknm{oZ[^lcZcpvdg\]`kjclisvƒqn~{tuƒz„‚|…v~‰–‘xƒŠtˆsyyŽoo|qiyz~mm|v–kjx„tk”…Ÿ—Ÿ™…ˆn}Œvjx˜‚Š‚•˜Šz–ozsqljd`tzh_er{Zar|yfpzaddŽ±²wJbZ¤ÙЗr{‘‹‘x–Œ…š’†ol†’‘zy“‡„™Š|‡xx‰Š„–€oŠ‡qt}{jy†„¦‘„“ƒ~m}‚v‚x…š˜“‹’”…‡oz’„~ƒƒ‰ƒoxh€…xrƒŠ‡|e}~ƒucps€hxpnt˜…‚‰zvx€„yj[p|r€‡„‰}…ˆzˆr€mpƒ†ƒƒrƒx€˜Œ„wmn~„wzehj~raZxZYrmNXrsf`Jmvta^[[Yu}roWg]fjp_oNWiR?Yg_[pjgyq\ZYkeYcqy_h]^elhfliqw‡om}€up{€‚v…‰—Šq‚q{†}zz„”Œujzko~t}or|{”po€xf’Š‚¡˜œ’‚…g‡„phz—‰~…‚™Š|ixrklf_aoym_boy\dlƒy`pv_eeÕ뾋2:>‹Ž€ry…ˆŽv„˜“Žnl…Œu}…‚•‰|ƒxnv‡…ƒ—wnˆ„lu{tfyƒƒ¨ŒƒŒƒ}mtuƒy…š‹‘’Œ‹†~{’‡y€„ƒl€si~xm|{Šƒxby„qdqi~mtqt›‹€„}su~€s€o[k}tx‰‚Š{†|ˆxzqlˆ‚Ž‚‰qx•ŠŠ~tmjv€€uu\iixqYW}SZqeL[sre[Jpwo][ZY]t~thYb[genbiMWfQ=^f]]vf_tp[YUodZeqyZh^`gmgilipx}Žlj‚„yn€{}€‚zu‚Œ“…p€‹nw~{{ˆ“‰h{~kt|r†{sw}Œzx„~|kŒŒƒ›–Œ€l~ki{~ƒ”‚}Šˆkuqghc[bgso_altahp‰y`st^cd› n\5Y¯µuj€‰}’†v†˜‡uŒŠwpl…ƒ‡ty‰x‰}“ˆzsgvˆ~}—op†}hwynezˆ„¥‡‡Š~n~v~€|‹—†“—ˆ‹„‰|‰r|}…|i~mk€{zjzv‚‡€r`w~qdrgu‚mu{…•‘|~owy|t~mWm~vsŠ†w‡u‰zwsn‰€Žƒr~|}’ˆˆznmim‚un]hftrR[{N\q\O\rodVKsxjWYYZaq€t`]]`fdhhfNZhNAad[`va\umXXStaZdnrWj^bhkgmlipw|“li„Š}}p~~{‚zw€€‰‹„r{‡oqw„{Šƒj~{nxywŠw}x€‚‡ƒ~zm…Œˆ˜£„ƒ{vŒykm„‰’y}{‚‘€€}Šƒpqpcf^Yg_pp``hpfjoŠt`so[adiv{¾œ¦£È¸r…ƒs”}x‡”„t‘ˆrsp„{ƒsu†tˆw”‰yyqcw†y€“ir„ufwvcj|ƒˆž‚€ŽŽ}r~sƒyŽ‚w•”‡‚ˆz‰‰myy~uhzilysizv€ƒ}h`w‡~jjsh{€ivŒ”~z}}q{v{t}aUu|rs‰ƒ‚|‚p†Šwxppƒ‚‹}|x}|u…‚vhqhlˆ‚rp]hctoKevL^oUTZsmbQOtxaRWX\ap‚s[`\hedcjdP[qIDda\dq^\whUWVw^\enhVl^ajgeoohpw{“niˆ‹y~s{~y‚‚|v}ƒˆ†ƒpvƒsmwƒƒ~‰‹”p€|xyz‹tƒx‚„y€vo~‰‹›žˆ}†zw‡|ht†‘z|‰†„v€gom_d\XeYmsa`aqllh‰m_siY^dm€w©ÚªÇ†‡²rŠxpu{‡z”Š€utu~w€pq~m…t”†xul`zyˆŽfqƒogun[m}“€y’’}x{m†uŠƒs•ŠŽ‡……{…muvnhwfm|vmjwv|abx†zhuuc~{gt†ŽŒ•{t€uq€z|lYVr}otƒ†xkˆ†sxkuƒ‚|y|w{rŠ€|sgtem‹„mt[k`vfHnoL[cXWVxmbPStvXPUX^`q„o\`bldc^nbT]rGCf_]fh^Z{bRV\u[[gkaVk_anfflqhpvxtkŽuvx}wƒ{t}ƒˆˆƒoq€uqu~†‚‰Š{wx„|}…‡x‡|}~„€{~svyŒŽŸŒ‰z‰wuƒy^~†šy‡ƒt††„w‰{bnl[b[[aVjtc`[hopg‡q`qfW]ck|Ê·¹¢kmn‹mr…r}…‹{’…zytyuu{jmuc„v’‚wog_|y‹‰eqjjqcXm{†œ‰ƒ‚s—”w~{m‡p€‰Š†p–Žˆ…‹ƒzy~qqo}ghrcnxrjlqw}|z]ey€wiuyf‚vgt‡Œ”|r‡jn~€ym|]Xp}msŠ|nn‰pvgw~€~u{qzs†{yqeranŒ‚lsXk_x]IolMWV_TU|kaOTurQQTV^bt…h\`jiebYnaXcpGAh]`f^]V{^OVepZ[jh]Wg`_rfjhrhqsv‡xn•Št{w~yƒ‡€us†…Ž‚pp{xwuy‡…‡Œ†z|u‹~}†„„‡~~}‡|xuyw‘“Ÿ~Œ}‹nu€ydƒˆ—†t’Šo……‚zƒtcnjY_[]]Tgse`YdrrgrakdW[`ix¾®{Ÿ·nbs‡ht|rzƒ‡{~€xxswo{vejna‡uŽsjb_~xyŠƒfp}hjk[WoxŠ£…q™“q€xtl†r”‡Œ‡ƒˆ…}ytrohyajmamvkgklzwzw[g}|xes~n„teu††•~p‹fkzƒtltb[n{kt|‹zft†}mphu~w|}q{ky{ywpelam‰~mnVk`xVKklOROiNY|gbNUukMPTU^gvƒf]aogfaWi]\liJEjZbdWYUyZNWnjY]le\Yec^tfldrgsptxp™…v€x|…‡}us‚‡€•‚nsy{{sr…‡ˆˆ„y}v}„‰Žƒƒ{~‹ƒ{w|wwš—zŠƒ‡iv~|l„…”€r‚q†‚~‚oflfW][\[Tdpe_XcruivodebW\\h€por€s‰eeyjtvssƒ…x„zwtunkzpbgkg†t„nf^_|o{‰}hmwfidVWrp§|„|v–s|r{ylzz„v—{‡†‚†ƒ}uprmgu]mi_mudgfizo{rYgvugp€x‚uaw…‹|”n‹jmzqere`lygrv‰z}auƒvikquzpywr|f}~~xvnceam†|mkVjbqTLjkPLNpH^{eaMUtdKNSWajw~e]grhe_VcWbp]KKkXcaTSTsVLYveZ_k`\Zce_wgmbpisoq~ut™x€€x€~…„z}v‚ƒ~˜…nrt|ztq……‚€z‹ut€}”Ž€…„|~Œ†z~€v{£¦Šyˆ†…lu|{u„‚Œzo…sz…}‚ƒunjieV][[ZScne[Xat{jimh`bW_Zi€iko€glahzykttto†‚{€}vunzikzj_enhw„geXbwi~‡zoiogf]UXoh§vz|‘Žxuo~nrtxŽ~w”t…‚…ˆvjrvgho\me^ns_gbjxh{m[mƒstjo€~yw`v„„x…sˆqpyqcph[nvdps‡{xar€pgixsqkwvtvcƒ{~wupcccl{|kkUibgTKmiPGRlEaxeaMTr]KMUYdkwze_mpid\V_UonVIShXf^WLTkTK\z_[_k]][be`zhlaoounowuz—}v€y€‡†zyzƒ}“„qtt~yvt…ˆ}€}ls•{‚Ÿ…‡}€~†‚€Š{v„¬Ÿ€zˆ‡„lr‚yv€‚tn‡o}€tŠ€jonddX_ZZ[Ubjg[Z_u‚i^nl\aV\\kert}ij]lwvgtwrn‡|~~zvslzhjxf]drgzw’ccTdog‚„wvfhjaWVYhd§n~x€‹Žzpp|fxnyŠzvŽqƒ}~†ndvsdhh]lb^po[g^muezi]t€orkq{~uuat…Š{‡‡€wru~taplYprbqq„{udr€l`lzojhzwtqe„tyyuqdadlr}jlTi^^ULtcQGWbGcve`KTpXJMXXgkvzdempfcZX]XvfSI\cXhXXHVdPHby[]`l[^\bd^€ij_otxnonvƒ—yr€}‰‹†~uv†x†Œ}tuuyzz‚ŒŽ}~„‰jt–{Š}~…y€{~|†ˆsq®Œ|{†~fqˆzt}}vro†m{~mzbpobe]eVZYWcfk`]]s†iYqn[^XZ\l{cqwvmc[msthuvqm…yywnoteiue[gtfvv‘z_]Sefj‚s}aci\UX^bd¥hytƒ†xlnygwl{ƒytˆr€x{xhevm`fa_j`^ukYe]onbzf[x|knnpwyttdrƒ’‡‚ˆzvoq|rawcZnoapq{seq€d^mvicfxzslmts|rqb^emn}eiThYZUNy`RKZYHctc`ITmTJMZVilr{cllscaYZ[aw\SJc]XiSVGX`NGjvX_bm[[_bc]…ihanxylojvxm‚~€‚’ˆ„vu‰t‹†tqvvw|}~Œ€~“~px–ƒ}™’y€€xy~sˆƒspš¢{{€‰•yduˆysyvksply|p‘r^poagblT[ZWhcmf\\r‰fSrn[YXX`lvdjujj_[mtqmtttk†}€|wooleiqc[krdtvs\VSd`q~q‚\ac^SZa\d“Ÿerq„ƒtkjylnoyyzq€vryzzdfug^b[ah\^wiWb^phaxa[{vjjrowtstip”ƒ†~„vrjp|mevW[jmbpr€zseo~[`oqb^io{kks}rpwkp`[ekm{agTgUXRQw\SPYRHcsb`GVlRIPZUkkk|emoqa[ZXYlpWROfWVhSTFY\OIruY`dmcXa`a^Œjcdmyxkoiuy†{k„}€…™|‚„y}ˆm†qowz|t‚‚}‹ƒ‚–tx‚“†Ÿ‰ut‚p‡‚uo¢—t{†‹‡{fw‹on|pfxq{lsvsk^tnagfkS^\Vhbll[\qŒdNon]VXUgithctee]Znunpuuzkˆ}€}ˆwscekna\nmcsx‡kZTVbcw||p…\c_cTZ`Zc–•cnpƒ„Šsjgyneruqzkytunz~u_fsc[^WbdYaufV_amcaq]]~ohisqspuukl„“‰{…qrfn{oqnSZejeqs€vsblvUbqk[^nd{dku|rrrjm`Ycijx^fTeUVPUoXQWTPHer_aFXkOIXTVmhd|ikwjaW\U[tdSRVhQXeSSHYZPNxw[`fliZb`^^nbfkyunnivv~m„€~†—{‡‰~k“ˆrgt€{u€ƒ~‰‹“r}Š‘…‡Ÿ†{†Œs€†s}‚un¤Œs‹wxn{`d|qgysymmqvƒgd|mcfghS`_Ug`lo\^nŽhMim`UVSofslexde]Yqumr{xsm‰|wœ{zlbelm^`njepy~gZVX_lx{{oƒ_b^hVY`Xdœˆbkq†|wkjvl[upjyiurmn{€rXjn^Y]VbdXeqdT_bibbmZ`~kfksunmwvkh…Œ‰z‡mqfo{lqlbX_hhos€ss^imSepdUbnaxbou{ujolj_X`fhu]eVbVSOYgSO]OOHeo]cGZjNJ`KXmd_xhn}d`U^T]t[TR_fN\aTSJ[YQZvv]_fmhXba[^Žqcgjwqsmgvsyƒs‚ƒ{ˆŽ~|ŠˆŽynŠtlssˆ…‡’„•z}Œˆ‘›„€|Œ„rstwqn““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|}~}}~~~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’’’’’’’’’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’““““““““’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ>.1111/o‡„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDBK’š™™™™œ[ADDDDCXhggggfo„ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ-h†‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR455553?“žœœœœŸR155554Ma____^j‚€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}zzz|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‘‰‡‡ˆˆˆ‡ŽŒ‡‡‡‡‡‡‰’“’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†…………†ŽŽŽŽŽŽˆ†††………‡‰ˆˆˆˆˆ‰ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z{|{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘“““““Ž‘’‘‰‡ŽŠ’“‘‹’ŒŽ…Š‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…Ž…Ž‡ˆˆ‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰ˆŒ…†‰ŒŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰ŒŠŽˆŒ‡ˆŒˆŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}}}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹Œˆ‡…ŒˆŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz|||{}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒŒŒ‹ŒŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzyz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{z{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†………………„„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰Ž‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{~~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““”””””””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’“““”””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••””•“’’“’“•”••–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””“’“““’’’’’”Ž”“••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’’‘‘’’“|†”’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’~’‘“ˆsŒ“‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘tv‘xtŠ‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘‘|h}‘‰uv‰ŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€bjŠ~ltˆŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽw^jficlŠŽŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹Š‹†dom[irk†ƒ„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxz}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzoq{xy{|{xw{xuwttvuuvwocqoajsqehklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkiffggghhceknsprulccbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__ac_\_]`]^Y\`bcmoppmZY_[XWSNMKKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{xvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSTPMJMNPROMO_hflnmgeQPSPPNNOMJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTtsuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNOLLVdmfjmmjg\SOOPQONNONOPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKKGGOU`hnhllkjjhd_VOOOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEES^bfhjmlspjijlkjfXJJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:;>??MY^jmlnysjjlf\RLEEEEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@:;><;;;;GJ>GYjowpkiYGDAEFDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnpprttsqrvyy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;:;;99:88;<979;;>=:;DXml_HA>A@CFDCCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqtsurqtxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<:79::979::78:9:;:77Sc=78<<=@A@=;;><==@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyy{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>><==?@===?C;==>===;EY9;<>=>?@A@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquutusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCDA?=>@A?@<]n@>DE??A<E\===;:=>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVppqssttuyz{{|~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???BFD><<=@=8:;mvH8;:==A<Ja<<=<8:;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pprrrtuvz{}}|~~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC?>AAABA@YR<==ILFFvwM788:;>?WiA;<<::;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC@CsyI;]ƒy|wV<=?==>FjuM:=>?==>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hloppqtuvy|||||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCEAHrykb‚„ƒƒƒ€}]>@C@@=Js|Y:=AEABBFHC=<@DDA@?>=@A>>>?<>@DGE@>@A?@CFECBCC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{{{}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@Fot}‚‚ƒ~}„uLACE@?>Y|€]?CEIJIIMMKECFFGEGEEEDDCA?@>>BFJJGEEGFFJNNKJIGGHKLIGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@EEhs}|„~y…qBDEDCWu†‡‡~XGHJMLNOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHHHGFEFFFDFHGEEHHFHFHFQnnpqrvvy{{{z}}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJG`{€w„…ƒ„ŠlAAVt‡‰‡‡‡ˆƒWHLMLMNLJGGGGDGGGGFHFHECDDFEDDHHCCCFIJKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrsvwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLLN[|‚‚ƒƒ…††ˆƒVl„‡†††‡ˆˆ‡|PKLKHGFFDECC@ACCCCFFEB@>>@AA@BD?>?DFHDEGIJIJHHHGIIIJIHFJJJJIJIJJJFILLJJKKfopsrtvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKLLJUƒ„„‚‚…††„‚†…„„†††‡‡†ŠuIIFB??@???<<<>;:<AA@><998<<=;>;9;?AB@ACCB@ABDDBCFHIHHHLMLGIJMMNMJJKKJLMSlpqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHHJJIe…„„„‚ƒ‚ƒƒ„……†ˆˆˆˆˆ‰ŒŽfBB=88::9878896479;<:8567789787688;;;=@;999=<>;;=ACEHJMLLGIHORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@CGIIj†„„~ƒƒƒ‚ƒ„†‰ŠŒŒ‹Š‰Š‹Œ‰T:8656766645773568:876565676778:67789;7578979876:<@GFIFIFEFOSRSSROPORTepqsttwy{|{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:=ECBf…ƒ€‚ƒƒƒƒƒ…‰‹Š‰‰ŠŠŠŠ‹‰ŠŠG676468874578567699766765:9:;:;898987779:98868689;A=>>BA?AKLOQPQOOORWkqrttuwz{{{}}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897;B:=q„€ƒ„„„„„†‰ŠŠˆ‡ˆˆˆŠŠ‹Š‰‰Œz>988;<=>9::<9:;9:;:99;:9===>;;<=:>;9;;<;<<9:<8::;:999<?<=ABDIJMKIKLWorsusux{{{|{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<;89989:::;?>H~„‚‚„………†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>BCEEAA@B>@B@@>==>@?>?@?@==?B?@A?A?=@@@>?A=><;:;99;?=;<==AACABCAXpqtttvz{{}}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::<=:;;==?@BR‚‚‚„…„…„†‰‰ˆˆ†††‡ˆ‰Š‹‹ŠŠŠ‹Š‹^>DGIKJIFGGDFHGEB@@CECB@BCB?@DHECECEEAFEFDEFD@B?<@>=?@>?>?>?>>:;=<`qrttuwzz{}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>???=A@CDFW„‚ƒ„……††ˆ‰‰ˆ‡†††‡‰‰Š‹ŒŒŒ‹ŠŠˆVHMLMKNJIKIIJJIECDFGFDCEFDBHIKHGGFHGEKIKIJKJCFCCDBAACBDCCDDCA=;=@hpsttwwyx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLK@BBA98<>;<;>@?A>BBGGIY„‚ƒ……†‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹‹ŠŒPNPNLNKJLJIIHJFDFHHIEEHFFELLMIJGGHIJNMNLLNKHGGGEECFFFFDEHHFCA?@Llptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?EGG=<@@87<;<=:>@>?@CFIIP_ƒ…„…††‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒ‹ŠrNRONLLLLJHGEIIDJHGKJHJGGGKLNLLHHIJMPNPNMOKIGIJHIDIHHFFGGHFCBACUnpuwwy{xyzz||}~~~~}~}~~~~~€€€€€€€€€€€€€€TDAABGHB?8?@8:<8=>;=A>?ADHJLUqƒ„„„„…†‡ˆˆˆˆˆ‡†ˆˆˆˆ‰‰ŒŒ‹ŒŒ‹‹‹‹‹_RRPMNMKJGEBGJGLJFKNKKJJLMLOPNHIKLOQPPQOOJIJJLJLFGHGFGIFEEBABB\orwxyzzyyzz{{~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<9@>>@BGGAGKLPVy…ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹‹ŒŒŒŒ‹‹|XVRRTSOLKJDEFKONOWUQPORSSMSTOMSLPSUVRSQPLJMMMKNGGJFFIJDDEEBDCcpuyyzzz{z{zz|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?==B?BBGVNFNPPTX{†ƒ……„„‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŽ‹‹‹hWUkaERQQPI;;RTR`u]UVTVYYRXXRZfPUWZ]RTWQONRPPPQKKKHHJHEFIIIHIirvyxyyz{{|z{|}|}€~}}}}}}~€€€€€€€€€~~SHJIHGFFE??AAEACGEDELXRMTUVX[|†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ}aŠ‹‹‡l[dU:XXXSQ?@VUY\d`VYbr]]W]ZVEQYZ[Y_TYgRVVXTTVTOOMJLJIILMKOMSosvxyxwzyz{zz|}{~~}~}}}~}~€€€€€€€€€€~~~VJJIHGEDDBA?HMIMPKIKPTSSXZZ\\x…„…………†‡‡‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~‹‰Š‹znpXZ\[RSRVVT[ZuƒYU}`\X]^WIV]][[_YHYXY[]XXYWRQNPQMMOSQQURassvwwvxxxz{z|}}}~}~}}}~~€€€€€€€€€€€xy}YNKIIHFBD@A:PQQWXPPOQSTTXXYZ[n‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡ƒŠ~fYY\YTUTWRQWVc–€QerXZW_hP`f[[X\gaGOZhg\[\]]WROSPPQVVVVYZnrtwvvuxxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZ[RSQORRRUSVTW_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PUXTRTRQQLOMKfy[]TYUV]ZLTZUST^ZXWWWzkX[[\^TQQPINOWVX[Zdprvvttvxyy{{||}}~}}}~}}~€€€~~zxwvsu{€€tk~~kry^[VUTROKFCDAM^ƒlVRSNOQOQURSRSUcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ymqVIKMNKMKHJDFHEC>TdURQQNKRTQMOYRMNQSUUMQSRPOMLHCIHRTUZ\lquvusswzz{{{}{}}}~}}}~}~€}}~~€~{vsw}~~du}iqt_d]^[YVPLILIal’tPQSNQRQR[RSRQRVTbs{|€‚}{{€ƒ‚…†‡‚†††„†…†u_]KC?CCCCB?DPBC@C=CIGV@HNLG]iPHFOFDEFIGHCDHGHKGDBAD@NQMRdrtvustuz|{{{{||}|{~}}}~~€€€||}€€€}vt{mh|gnqfiedb\XSQPURsWe[OONLQSQUYSUQQTROV`klrv{{xytrnstsyx~~ƒ€ƒƒ‚€‚€‚‚kMG?@:;>@@??>jQKaEFHIEB?GLNGMQUIBE??<=<==?=?ACC@?<=B>JMGUnttustvxz|z}{|}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QRZ\Y^JJPQNKLQRQTUUWQQWVPX[b]agmmlokg`nrjmlqu{z}{xz||xwxeC@@B=:BCAADB\]O{NONNKLMOOQLKLWMHG@B<977599=;;;8989?<BH?\stuvuvxz|||}||}}}~|~}}}~}xuvz{zwyxuw{|yxuywcqhipmnmmhf^OP^\ZIHPRQOMPQNQRTVXSRYTNYZ[WY]^^_e`]^qvk^`gkwooljonnlfbYHFFHBAGIEEFDMRPaWRWQPSSRU[OOQWPMIDF>:96587979:365795<B=essvwwyz{}}||{|}}~~{~~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZXMLTTSPQUOLRSTWXTTXQLWYZVXXVXY]WWXhsk]Vaskaa_^da_^YTQNNNLIHJKIIFCQPS[WTTNQSYS\eUOSTQNKIHC?A9988978857578599Gmrtxxy{{}~}}|{}|~~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPXVVSTVOOTVXXYSUTLKTVUUUWPTUWTUR]n^RNY_[VY;DVXT[fJLORROMMNNNLJFQPUYSTOJNOUST\VRUSROMLIHHF??<:787659967675Wpptwyz{|}}}~|}}|}}}y}}|~~~}||}}~}|rvqxxrvuqqnppopuvtnjddjppqrpofedc\]RTZVWUTWTRXXYYYRUOIGOPOOMRJOPOPNNOTLMIPOSTU2=XMI@Q=caQSQPNPQPNNMQNTRPRMILJORPRRSTQROLLKLLHCBA=::876;B5566:doruxx{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqptuvcjgeWhtrrqniihpVVTUXUWURWVUZYXWUQSFEAFGGHFJDHJIGEHLHKIFLMPMG/E_R>3?>joaRRQ@GUQPQPQNQOPOLJLLOPNNPQQNPOJLMMKGEEDB;=<<9=G6677Dmptvz{{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknaePSTRSTOWVVYYVQQQO@=;=?ABAC@BEDA@GHGHEFHJMLEGCORC8ENS]gSQSAGUPOQQPMMNMKLKLNOOQMOOMHLLIKKLKGFFED<AA>;@E;<89Spruy{z{}||{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLOOMQSLTUTXWUMLKI<987;?@><=A@B=>EHGCFFIGJI@FAA@FHEJOHQRa\QPRNSNOPLLOMKMLMON[WKMQOGIHCHJLLJFFFE?BC><BG?B?Adptw{zz{|{zzw{wy~~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHDD=9779?B>;?A@@>ADIECGGIFIEBB?>=CBAGIEMObeQMNNWKKMKLMMMLKNNSdMJLRIIIEAHJLMNJGIFBAB@?EFEHDKnovyyy{{z|zwsxux||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGLMIMPMPOHJD?A=999:?B?<@BAADEGKFCHIGGHCC?B??@A>DEDLMRTLJIMTGIIJLJKLIJLMOPQPKGCKGCBJJLMONIJIGCCCDIJMLIYrmwyxz{{y|vrpurtxyvxjqnjllnttmtu{stxronqovsnporpopstyjN`gsjt|ygosqiqhdqHKDGHHGJKIJKDGB=>=:::;AB?=BBCCHFIKJDIIFGGCC;A@B>@@BECIMPHHKGHKDHIKMHJLHIJKJM\RHHDNFADKJMMPMKMJKFGGJMNQNLbmivvw{y{z}qmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoiktgdoFKCFEGEFFGEGBC@=<=9:::@C@>BCDEIEIJLFIIGFFDB;BCC>@CCCEGLNHKNHDHEILNMGILGFGIILNKIHENIBFMLNMOMNNMKIHIORQRNRfffqosxu{z|lhjnekqlsqfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGJDFFECCCE@DB>@?:;;=:=>CA>ACEFJFIHLHGGGFEC@=EEB>BDCCEGHIGMPJFFGKNOKFHJFEDEIJHKIFHPKCIMLPMONOONJJHMRUUROWd`amgproryzgehhdilfqlflmgiklslpvutpnvrosrsutqssutsuvvvyvutwljuumrvqlnlerLGEEHCBABD=BA>A=9:=?:=>@B>@BDGJFIFIHFFGECBAAFFCBCBDEEGGHFLQLIOJJLLIGHEFFDCIIHKJGKRMBNOMQOOOMNOKKKPUWVUTX_^\iaminhrsbeffdihfnifmmhkkmriqvusqmvnoqrswsrstuvvvvwvwvvtwujsunutsqrjksMGHFHBB@DD<A@@C<89=>9?<?B@@@DFHEHFFHGFFDCECDIECFEBEGEFGGEJMKHQMJKHHIEFHIFCIJIKMKOSNDQRPQRNPMNPMLMSWVXXVX]Z]d`hbjigk_eefcgggkggkmkmlprhttursnvoqprtxqssuvu‚‘yvvtxuuwxmouorsuqqioyMHGHHBBBFD<?BBD<7:>>:>:@B>??CEFDFDEHFDEDDEFGJEEJGCGHFHGECFJJGMJLKHJLFIIKHEKKLMNORTOHSUSPSOQMNQNMPWZVZYVZ]ZXa```_hec`dfhgjihifhnllnmqpiuuxrrpupppruvpusuvu{~}xvtwvvvxplupmstnprrxNIHGICACHE<@EBD=9:>>=<<AB<?>ABFCECCHECEEFGGGIFGKHCIHGIGFDHKIGKHMKJKLHLKMKJNLONORUVOKUWSQSQRLOQPOTYZY\ZY\__^`c^\ackb`dghr…hgifjmnponsrjtuxrsstrnpqvrquruus~yŽ}uuvvvvxrhuqkrtlqvotMIKHJFBEGE<@GCD@:<>@?>?BA<@>AAFCEEDIEFEGEHHFHHIKIEJHHKHFFLIHHJGLLLLLIMKMMMOLPPQUVWOKVVUSSQQLOSRPV[[]^[\^__a`ad]d`ef`ehjcssfjgglprqossnswwquvtsmoruorspurvrtvuuuwvuwtgtrkqrkrvnvJKLJLGBEDE<@FDDC;??A@@@CA?B?ACHCFEFIFIFFDIHGIHJMHHJJILJFJKHIJJGKKMMJJMLNNNPLOPRTXVMNTVTRRQPLNTSRW[^^_]]`_`aa_acebdhbdijgv‹ljigmosqpqppryvruutsmmssmqrotutrpswtuuwvuuteqskpqjrvowKMLKMGDCAD<?EEEC=AACBBCDACDAAEGCHGHHGJGDGIGHJFILHIJMKMLGKIHKKNQKRQMSMKNNOPPOTOWXX[NSQW\ZRWPNTUTTXZ_bb_da^`b^`eaacingbihhnxvlhimosrpqrrrvtsusssnksqmprotvrqquvuswywutucmtkopjqtowLNLLLGEA@D>>DEFC@CAEDDFBCEGCCIFCIJJIIKGDKJGHJIIKHJJNLNLILHJLKZfJd\KlSHON_nUks[qpbwcSPbvuhucav`Xnqbdvinzf[lt`lkT_wvijgifglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqrqyLNJJJFC?@B?=DEFDCDBEEDFBFFGDEKEEJMMKLLGGMIGJKHKKIKKNLMMLLILML[sbdp^lmUMNfs]geqlntgpi_aYnnbppbkjjgoqtetno\ougpMJryvkb`keemxlkvmnpsrprqpqrqrrrtrmmsnnoprutqsstuuutwxvutbmukpplrrqzKLIHGED@BB@>CFGBFCFEFEDCHHGDEKHGLMNLMMFJNHJKJILJJJKLMNNMMJMMM[roonpplkMPQlWNibtrpamnu\YlQ\mmZqmkomxxtsip]_rkqjUuyxpc^kfbgppjjopprspqpqqrrqqrrtlmrmnnorutqtrtuutuuzvutenukpolsrryIKGHEEEBBB>@@FGBGDIEEEBFIHHEGKJGMMNLMNGLMILKIJMIJIJKOPONMKNML\hdu]lqWlNPQmUZk^klvaldsSecNmYl\tpkilxjwuhp]^rkhWbcw|oc`ggadityknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtvHMGIDEECAB=BABFDHGLHECCHKHHFJLLFNLLSRLGLLHNJHHNHJJIHNOMNLJNMJZsppoqqmlOQRnYqkgooqqomt]nXat_nopoqronusttj[]tcwxrjnzhaacfbbjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyxtukoumtontsvsHKHIBEEEA@>DDBGCHIMIFCFJLIGFJMLFOJKWRKGKJJNIHJLIKJIHJMMMMIKKKSkb[i^_icrrZ_Yjo_eeUk_c[aaQ`lh]j\niid[pfdp]Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunwqrvtwrGGFIDEDFA@BFEDGBHJLHFDGKLIEFJOLIPIL[QJEHHKMIHJJJKIHIGKKKLGHKKLLLLJKMNT[\TPTLPONOOVQOOQNOQJINPQdqiTYW\[\UYZ]X]\\cfaaebcf__fkmhmtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyxxuvqruovrtsuusGCEGFFAEC@CHDFGCIKLHFDGKLHDGIPKLOKLWLIEEHIJHIKHLJHFGGIGHIEFLIJKNLIP\W^P\[`^MXYS\\b^MYZMXaRJYaZR_d\aX[ddVVX\YZX\VY\]b^d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtOBCELMBDDBEIEGGFKJKHEEJJKFEHHPJMMJMSHGEAHFJIKKILJHFEIFDFGEEJHCJMKLU_Y`X`a[`TXYT^^Z_RY\P^\YN^\^SZ^c^Z]`c`Y_b[`^[TXWY^]cbcacfhekrpoppnow††……†‚{€……††…†…uqprrsvyyzyyxxxwryvxrqxvuvaSJJMIDBBCGHEHGHKIIIDFKKKEFIJNKNLHLNGHE>GGLIKKJLKIGEIDCDDBFJD@JLJO[cY_^a_RTRW_`\]Y^QY\MV_WKQY[PZ_aa]^ca`bbbcceZQYVU\Y]c`__cdbhomnllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxXQKFCGEBEHIFGHHFFJGHFHKILDDKJMMLLHJJHJF?GFNJKKMKKKIGGCD@DAHIB?IJHP]aZ[d]_TQRX]\\\_ZKW\LR\YIM^QO\_accccb\dcbdcfXQUTR[WZ`_^^aa_dlkmjjlnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMC@IFCFKJFFFHGFIFFFILJNFDKJLNJLIKJHIFBHHQMKKOMKKIHGED?ECHHAAGGET]Y^X_Y_[]UXXP]]QKJV^X^[]UY`RQ__bb``bb`cbaddbXOQQQZR[]]]]^__dhgljnnp{{|~{€‚ƒ„………………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKCAGFDGMRHCQJFHHHEFKJMPEFIJKNLLILLIIGDHKQOMMPLMKKHICDAEDHGBAGEDWUE\U^SV_XNTUNZZMJKT`a[_X^^a]OYb\``_bcb]abW__TPNOOWQ][[\\^`bffelfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDEFGDIRbPCV^IGGHDFMJPPEIIKKNLLLMKJJGEJMQQNOPMNLNHKADACDFDCBEFBMHBKLPONLFMFGIJHGLKMOPILOPOSOLQSRUZYWYXXdWOSTPPNMOTS[XXZ]\`adecgcklpsrzy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKM]LGGXLGHJHGMLQQILKLKNMUNOKKLGGKPSSNPONONOHKF`ED_LDfdEM[I^[rmOMUmYLCP`UkWgJ]XU^DMQULLSVQRTXWTXUT\UPfZhhdXRjSWVT[\[``aaab`fhfnkhrz|}~„„„„ƒƒƒ}|zr{z{‚€ƒ„„……„…ƒƒ~z{LHEGFHEEKOSIJF`SHJOJIOMRQKMLLORUROOJLNGHMQ[YOPPNOPOIJQQI|YYqsXPmHqnoaVPqqsPBksmqspSo_[nX]V\XUkhU]VcZ`Y[`VVXjtuu__v_Xa[\f[_aaaa^`bgmpl`pwtx‚ƒƒ‚}~€vxzlv~tx~€|~€‚„|€ƒz~wwNIEHMNBDLLFIKEQVLKNIKRXWQNOOMQTNOQPKKNGMPS[ZTQROPPPJHZx]TxehZRTQvgtlpbnfjQrOMwmjrpsrqrpoo€]ezuxqqzq~s}ku}bRh|essosr{|o}yor_``baZ``gknkblfgmw~€ƒ~{xw€tvzir~nt|~wx{~€ƒx|€u|||ssNKF`]GAEMMHJJGJPOMMJNV^YULQSNXZMSSRNKOIQRTYWWQTPPPQKHgxlcxrm[KMUypumubnvPdeJfvqmwo€jfxxiWrQhzmijzz}lxzohoYvvjuup`rg|ilx|o^__ba[]bdgiidgbcdllppstsssyqrxblugry{ssuy~suzn|}ywrnNKStNCCFPPHJKJKPOOOMPZ`ZXKTWPa^RVQYRLOISTUXWWPUPONRJKrouuquqdibWnLqp^FhyWvTLiy}x`y{sna]mocRhqunmypwlvttrln]t~zkmy|ktl|kpvux^__b^]_ddighfe^abiiijknokqnmjpacfdowxompsy~nqpj{ztromLL[VHGEGRPILMJKPQPPPQW\XUMUYUfXRRY^SLNITTVWYWOSNNNQHRmHiwK`dvvVXlOnl{sajgvULWkh}lmlx_[pz{^`zscroxqhd|ir|^TLl`vukiu|{m~xk|p]^_b[_bddgeeebZccikkrsrwglihdg`akagsrlgmmr|kmhk{tmmkmOHJKHIHHRPLNOLKRRROSRWRVTPW[VVTTTa`PNMKTSSQUVNNLMOPJHQNPULKKSTSRTPVUQQNQQXYRNPUTXXX[ZURSW[WXWZOSUWXXR]YW^VTPYRVWWWX^[gr^[[Y\]_cZ_ccdfdccbZccffemnmueegcaf_]g`dlhfgkhpzhggkujhgilQIKLLMKJSQMQPOLVUTPTUXUYUQZ]VUTWUYXPOLMVTPNUSNOMLQPKJRQKQMKKORURQQSSIHLNOQRQQQTVRXW\WSSPQUUVSZQOSRXVTYVTYUTRUTTUWXW]Z^a]\ZZ\\`c[]bcdfdedaY`acabhhimcad^_c]Zd\bma^fefmsdihkkedcfhPJKLOOLMSPNSQQMXWUTUWWWZUS\`VWVYUXSQPKOWSPNUPNQNKSPLOUSNRNMNQTPTQSTUNKMOQTTRRQVWTYZ[YSURTWWWY[TOTUXUUZUWYURRXVUW[YZ`]UX^\^]\]aa^[bbcgfedbX_ab^`hefea^_]]^ZZ_Z_g`^]]bhkagfhfd`bcaPKMLPQLOTOOSQOQ[ZXWXZZXYV\jdVXYZWVSTOJNVTPOTPPPNMQQPRXTQQOMOSVNWRTUUONMQSUUTTRTWVZ]\ZVWQRWXV[[WQTVVVVYTXXURRXVVZ]Y]_^V^]^`\\`___ZbbdhgddbYb`b^^fcc`b]\\\\YZ[X[a[^]\_b__bdebd__`\PMNNRQMRROSTQPU\ZZW[[\YZ[dqmhd^[YVUWQLMVSMNROQROLPSRUZUSPPLPWWRWSSSXMOPRTXVUUSUYX[^][[VROUVV[[WRTWVWXVTX[TSRZWW\^Z^_`Ua\aa^`b_]`]c`cghdf`Zc`a__ed_`c[Z\[\YZXYW\Y\[`^_[^^a`^b\Y`ZQNONVQPTROUTSPW\]\X^\_W\^jqwy€b\[VVXQMOVSNQQPRTRKQTTYZWUORNSXWTSURRZOPSSV[VVWTVZX]^[[^VSNTUV\\VRTVVXYSTY\USS]XZ]^\```Vb[cb^ac_\bab_cfidf^[d`a`acd_b_YZ^[\[YXYWWZZZa\][]\\Z]`W[[ZPOOOYPUURQWRTP[]^^[`\`U\]ijr}slg\UXWPNRZSRQTRTUTKQWV[ZZSOSRVVVTOWRSZRTTTX]WXXSX\X^]YZ]TUNVWW^[XRUUYYYUWY\VTW^Y]]`]bb^Y_[eb_dd^^cca^efidf^^da`abbd`b^XZ_[\[XXXXW[Z\`\[[\[XZ[^V^Y]POORZPZTUVVTTT^^`_^b\`U]^bkytl}lZUYUQPS\TUTUTVYWLRZW][]ROUSXWVTPXRSWSVUU[]X[YUZ^X_^Y\YRWRYXY_ZZTUVZYZWXZ\VUZ^\^`a_dc\^]]eaafd^^dc`\gdhedb_da`a`bb_`^WX^Z\\ZYYWV]Z]^ZY[\[WY\]VXW]SOPWYQ]UVYWWUX__aa`c]`T]_beeuzhXYYSVSV\XWWVVW]XOU]Z^]]TRWSWVUSTXRSVTXXX]^X][V]_X__X]VQYTYZZaY\VWX[Z[YYZ[XV]_`^cbbed\b\`fadfd_`dbb[fchecfaf_`aaaa`_^VU]Y[\[Y[YY][[[XXY[YZZ]_]TY]UNTZVS\TVWYVV\`abcac__V[`da_zuohY\ZUXTW[ZY\YXY`WPV^\`a\TTXPUWVTVWRSUWZZ\_^Z_\V__Y^^Y^VSYWYZ]bZ^VW[\[\[[Z[YY__``dbcdebdZbfcgfe^ab`c^bcidcg_g^bbcaa`^_XT[ZZ[[X[XX\[Z[WWYXW\[\`]V]]SPVZVVZUXUXWX]_badad`^YYadb`lfh^\][VWXY\\\_[Y[bVTX^]ac\RVYPWVWWWVTVTX\\^``]`\Wa^[^\[^XVXX[[_`\_XY]\]^^\[]X[`a^`dcdeefbYceehgd^ca`ec]eidei_f^cbcaa`__[XY[YZZXYXW[[Z[WXZTY]\Z`\U^bNSWYVWZX[\XWY^`baeada]^Yacb_a``^\\\WW[[]]__\Z]cXZX]`cd_RXYPWWXYYWVWV]]^`aa_b^Ya]]^Y]^YXVW[\`^]_ZZ^]^^a\[[Z\`b^bdcefefbZdffigc_c_afeZiicfice^bbca``_]]ZW[YYXXZXWZ[ZYWXVU[]]]``bbxLXW\YW\[\]ZW\]_`bdbba]`Xbcbacab][\[XW[\_]`_][`d\\XZbecaR\ZOXXZ[[ZWZY`]`bb`ac_\b]_][^^YYUX]^_`_`\[^^`bc\\X\^`bbcedfdefd\efgifcab\dg`\iibhife`baca_`_]][Y\YXWXYXW\[ZWWXOXZ]acffrkJYW]ZZ_\[^\X][^_acbaa]b[bdb`bbb\[[ZWXiq`\`_]\ac_^YYcedaS_ZRYX\]][Z[[c`bbc`bda`c^`\]^_ZXV[_^]aa`^[`abeb_]T]``cddfegeffe^efhhgdd`[eg^ahhbhhfc`b`cb___]]\Z[YXXXVZV\ZZVVUMXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡…‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vvvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{{{{{{{{{{{|{{{{zzzzz{{|||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vvuvvvvuvvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{{||||||||||{{{{{zzzzz{{||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚‚ƒ‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||vˆ‹‹‹‹‹‹}}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰Š‚E>????=u‰‰‰‰†³ÖÒÒÒÒÖº}~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}vŒƒ~~†“y1333332j‚€€€{­éääääèʉŒŒŒŒƒ:233330sŒŒŒŒˆ¿éååååéÇ}~}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}vxxxxxwxwwwwwwwxyyyzyywopppppprrrrrrrwzyyzzz~ƒƒƒƒƒ„|||||||vuuuuuuz}}}||{„„„„„…‚|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚ƒ‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vvvuuuyvvvz{x{xwvwzwyzz~|yyxxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{|||||||{{{{{{{zzzzzzz{||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwwx}y}zy|{xwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwww|z~}y{zxxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒ„‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z{xwww|z||z|yxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzzx|y|}z|xxxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyxyxz{yyxxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxxyyyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{{||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}||}}|||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}|}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrsuuttssssrrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqsttstrqppponnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqrsstssqpuwoonnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrrrsrssrqoƒnpoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpqqqvŒurro} {nppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqpqqr•qqq•¢{opppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqro¯‰oy¢¢zoppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsqu‹‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqrpˆ²¦vŠ¬¤{pqqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrrp³¨¤¦±¨vqqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrsssssssv¡¡£´¦›¤|ssssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz~|~~|vvwwvuxzxxxxxwxx‚§Ÿœ§Ÿ££’zyzyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~}||||‹¡Ž˜š™›•{{yxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}}~}ˆ§§£ š“˜}}}€ƒ‚€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€²§©¢ ¡«¦„~€€~~€~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~€€Š©®Ÿ©£ ¡¥©¤Œ~|~€~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~€~ˆ•ª¯¤œ¤¡ ¡¡¡©« €€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹Š‹‹‹‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚ƒƒ†Œ›¦£œšŸ“˜¡ žž¡ ”…€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒ‘‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒ„‚„Œ”–——™˜‡››œ˜‘‹‡ƒƒƒ‚ƒƒƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒƒƒ‚€‚ƒ„Œ–™•‰’™œ’‹‡…†‡‡‡††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠˆ‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„ƒƒƒ…„‚‚„—”–™…‡‡ˆˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ‘’‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„„ƒ„„‚ƒƒ„‘–ˆ„…ƒƒ………ƒ„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘’’ŽŽ‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€‚ƒ‚‚‚‚‚‚‡‘‚ƒƒ‚€€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„„„„…„…†’“‘ŽŽŽŽ‰ˆ‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~€‚‚€„ƒ€€€€€€ˆ’€‚ƒƒ€€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“’Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚‚ƒ„‚‚„„‚ƒŠ–ˆ„‚„‚‚€Œ–‚‚‚„ƒ‚‚ƒƒ‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘Œ‡…ƒƒƒ‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒ€ƒ‚……„„ƒƒƒ‚„Ž˜Šƒ…„„„‚€’š†‚‚‚„ƒƒ‚ƒ„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”“’“ŒŒŠ…„ƒƒƒ‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~Œƒ~}|}‹œ€‚ƒ‚…”“Œ‚‚ƒƒ‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†””’”’Œˆ„„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~•—‰€}}}}{—Œ€ƒ€“‹‚‚‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“’Š†ƒ„ƒ„‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€€•ŸŠ~~€}‡Š}„„ƒ„‚ƒƒ‚Ž‰…Œ‚‚ƒ‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”“’’‹Œˆ†„…ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„‘¡ŠŒ…}†‰€~………„…‚~}}‚„ƒƒƒƒƒ„ƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„……………„…†…††…………………………††…†††…†††‡†…………ƒ„„„‡“““’’Šˆ…†……‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…ƒŠ‘ƒ„‹…‚~}‡†ƒ€~~~~ƒ„ƒƒ„„„„„„„„„„„„………„…„†……†…†††…†……‡……‡†††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†………†”“’‘‹Š‡†‡†„‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„„„‚‚‰~}~…~€€„…„…†††…………†‡‡††…†……†‡‡‡ˆ‡‡‡†††‡†‡††‡‡‡††…„ƒ„……†„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘”“‘‘‹‰ˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒ„„„ƒ€€€„„~~€€€€……†ˆˆˆ‡‡‡‡ˆ‡ˆ‡ˆˆˆ††‡ˆ‰‰‰‰ˆ‡†‡‡‡‰ˆ†‡‡‡‡†‡…„ƒ„…†…………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†…†ƒ‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡†…ƒƒ…„„„ƒ€€Œ‰€‚‚€€~{z€†‡ˆŠŠ‰‰‰ˆ‰‰‰‰Š‹Šˆˆˆ‰‰Š‹ŠŠˆˆ‡ˆˆˆ‡ˆˆˆ‡ˆ†‡†„ƒƒ…‡‡‡†……„„„……„……†„„„………†††…ƒ‰”“ŽŠ†„†…ƒ‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡†„„…„ƒƒ‚€€„„‚‚‚‚‚‚‚€~}}}}~}|{|ƒ‡‰‹‹ŠŠŠˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰‡†††‡…†ˆˆ‰ˆ††‡„ƒ‚„ˆˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚‚ƒ‚„ƒ„„Ž“’‹ˆ…„†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„……‚€ƒ„‚ƒ‚‚‚ƒ~}}~~~~~~}~|}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡‡‰‡ˆ†ˆ‡†‰‰ƒƒ„ƒ…„„……‡ˆˆ†…ƒ‚‚ƒ…‡†‡††„‚‚ƒ„‚ƒ„„‚‚ƒƒ„ƒ„‘’ŽŽ‹‡„††„‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…‡ˆ‹Š†„†„‚††‚‚„„ƒƒƒƒ‚‚}|}€~~~}|}}|y|ƒ††‡„ƒƒƒ„………ƒƒ…„„„„„„…„‚‚‚‚„„‚ƒƒ…†…„‚‚‚ƒƒ…„„„…„„†„ƒ„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰†„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„„……‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€ƒƒƒƒƒ‚‚}}€€}~~}}}}{zz~„„„‚€‚‚~‚ƒ‚‚‚‚ƒƒ€€€‚ƒ‚€€€€€ƒ‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†‹“‘‹ˆ……ƒƒ„‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€ƒ‚~~~~}‚ƒƒ‚ƒ‚ƒ‚}}~€€€~}}}}~}|zzz€‚‚~€~}€~€€€€€€~}}€~€€€€€€€€‚€€‚‚€‚„ƒ†’ŽŠ‡‡†ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒ‚ƒ„…€€|}}~}}~€€}~}~ƒƒƒ‚‚}}~€€€~}}}|{{{zzzz€€~~}~~€~€€~}~~}|~€~~€€€€€~€~€…’’Ž‹‹‡‰…„ƒ‚‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~}~€€~€„ƒ‚€~}~~€€€~}}}|{{|zzyyy{€€€~~~€€~€€‚€|~~~~}|€~€~€€~~~~~~~}}}}…“’ŽŒ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒ‚‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚‚‚€ƒƒƒ€€~}}~~~~}}}}}|||{zyyyx}€€€€€‚‚€~€~~~~€‚€€€€~€~~€}~~}{|†“’Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚ƒƒ…ƒƒƒƒ…„„„„„ƒƒƒ„‚‚‚‚‚~}}}~~€}}}}}}}}}{zyyyyy€‚‚‚„ƒ€‚‚€‚€‚ƒ‚‚ƒ‚€€€ƒ„‚€€€€€€‚‚€€€€€€~~||Š“‰‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…ƒ„…„…†…†††…†…ƒƒƒ‚‚€}}}}}}~~}}}}}}}}~|{yyyyx|‚ƒ„…‚„ƒ‚‚ƒ…‡‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚‚ƒ„ƒ‚ƒ‚‚‚‚€€€~Ž“Œ‡ˆ†ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€€~}}}~~~€ƒ„‡ˆ„†††…††‡‡†‡‡ˆ‡‡‡†}€€‚~}}}}}}}}}}}}||~~~|{yxwxyy€ƒƒƒ„„„„„——ƒƒ„}~‚‚‚‚„†ˆŒ…ƒ‚‚„‚ƒƒ‚ƒ…„„…ƒ‚ƒƒ‚ƒƒ‚‚‚‚ƒ‚‚‚’‹ˆˆ‡‰‡††„†……„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€~}~~€‚………‡†‡‡†‡‡ˆ†‡‡‡‡†‡…~}}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yxy|~‰–„ƒƒ„„”“€~~…‹€€€„†‰…„‚‚……‹ƒ‚……††„ƒ……ƒ„„ƒƒ„ƒ…„„ˆ’Œ‰ˆˆ‰‡‡‡…†…„…„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„ƒ…„~}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|xyz{|€‚ƒ‚ƒ‚€~}~~{ˆ‘||Ž–}‚†Š…ƒƒ„ƒƒ‰~ƒ„……ƒ…†…„……ƒ„……†„„Ž‘ŒŠŠŒ‰ˆ‰‡………ƒƒƒ‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚€‚€~}}||}}|||}||}|}}}|||{‹‘—Œz{|zzz{|yy}}~€€|{{~~}‚•‘„ˆ}|~‚„||‚„‚€‡ƒ}‚‚‚€ƒƒ„„„„„‚„ƒ„…„‘‘Ž‹ŒŒŽŠ‰‰………ƒƒƒ‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚ƒ…ƒƒ…………ƒƒƒ„‚‚ƒ‚ƒ‚‚€€~~}~}||||||||||||||}|||~~Š‚{z{zxz{{|}{~}~}}}}}|}†~}‚~~€‚||€‚€‚€~|{Š‚}€~€€‚‚€€€€‹”Œ‹ŽŽŒˆˆ‡………„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ…„†‡„„€†”ˆ€‚€~~~€|||||||||||||}|||||||y{{{xxy{{z|‚€~|~~~}€‚‚€€€‚‘€€~€~~~€}}}{}}}|}||}€€€~€~~‚”’ŽŠ…††…„„…ƒ‚ƒ‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚‚„†‡††~ˆ•Š~€€~€~~~|{{|||||||||~}|{}|||{|||zzy{|z}…ƒƒ~~€~…‚~€~~€…†‚€~~ƒ†}}~€€€~}}}}~{|}€}~Œ‘ŽŽŽ‡„††…„„„ƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}€‚„††……~€€€~~}€€€}}||}~}||}}}}}|~|}|{}||z{z|}}†„ƒ€€}~}~~‹„†~}||~‚}}}}|{}|~„ƒ€~~~~}|~}~€~~„’ŽŒ‹Š†„†„„„ƒƒƒ‚ƒ‚ƒ‚ƒ‚€€}|||}~{{}w~vx~}|}|}~~‚ƒ€z}}|~~€~~~€€€€~~~~~~}~~}|~}~}~|{|||z{z}€€„ƒ‚~|||}||ƒ~Œ~|{{}~}~~}{{{}|{{{{€†„‚„ƒ€~‚‚‚‚‚€‹Œ‹Šˆ„„„ƒƒƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€€€}€~~~~|‚~~}}}{{}}|z||~€‚€€€}|}|||||}|~{~{{{|||}|{{{{||zz}z~‚~‚„„‚‚…†……††‡…„‘‹Š‹‡‡…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~€€‚€~~€€~}ƒ||}}|}}}}{|~~~~~|}}|||{~~{|{||||}|}|~|}|{{{|y{|{{}z}~~€€ƒ‡‰‰‰ŠˆŠ‰…ˆ’Œ‰Š‡……ƒ‚‚ƒ„„ƒ‚‚‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||||||~€€€~~~}€€€€ƒ‚€€€€€€€€~|z|}}~}}~~Œ†}}~{{ƒƒ}~~}}|}}}}}}|}{}|}}~|~}}}}|{{z|{||{z{{zzz{~~ƒ…ˆ‡ˆŠ‹‹Š‰Œ‘ŽŠˆ†…„‚‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„„€€€€‚~}~€~{~’Œ|}Š€Œ~~}}}~~}~}|||~}|}|}}}~}}~~|{{{||}|{z{{yzzxy{~ƒƒ„‡‰Š‡‰ŽŽŒ‰‰…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{}||~~}}‚€€€‚…ƒ„‚‚‚‚€€ƒ‚€}~€~|‰‚~ƒ‘„„ƒ~}|‡}}~}}|~|}}|}}~~}~}}}{|}~||{|}zzyyyy{{~~€ƒ‡„ˆŽ‹‹‡…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{}}}}}zx‚€‚‚€€€€‚‚‚‚†…„‚ƒ€‚„~€}~~}~€€}~„€~~}~}}Š…}~}~~}}}|~~~}€}}}|}||{|}{{{zzz{{|}~}€ƒ€‰Ž‹Œˆ„……„ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv}€‚‚‚‚‚‚ƒƒƒ‚…†„ƒ€€€ƒ€„~~€~~€~}~~€€~€}€~€~|}}|~~~~€}‚€|}€€}{}}}|||||{{{|{|||}|Š‹‰ˆ††……„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚ƒƒ„ƒ…†ƒ‚€‚€€€€ƒ~~€}€}}~~€€‚€€€€}€€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{|~|}|||{|{|}‰‡‡……‡…„…„‚‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz~}ywtt€€‚‚‚‚‚ƒ…ƒ„ƒ‚ƒ„„„„„„€€~€‚€~~~~€}~€}}}~€€€€€‚~~€€€€€~}}}~|~~}}„€~}}}~}~~}~|{|z|{z€‡ƒ„„…„„„„ƒ‚‚€€‚‚ƒ‚‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xyuu}‚ƒ‚ƒƒƒƒ…„…ƒƒƒ„„ƒƒ„ƒ€€€~}~~~~~~€}}|}}~€€€€‚€€€ƒ‚€€~€~€€€~~~~~}~~……€€ƒ~€~€~}{z{z|{z‚…€ƒ‚‚‚‚‚ƒ€€‚€€‚‚ƒ‚ƒ„ƒ„‚„‚‚‚‚~€~}~~~~}~}}z{|…„{{syz|pwuvwyutz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€€}}}~}~~}~|}}~€€€€€ƒ‚€~€€€€€€€‚‚‚€ƒ‚ƒ‚€€|{{z|{|‚€‚€‚‚€~‚‚ƒƒƒ‚„‚„‚‚€~€€}~~}}}~}}{{z€x|vyy{qtxwvxury……‚„„‚„……†„„‚„ƒƒ€€~€€|}}~€}~~}|~~~~€€ƒƒƒ€€‚€€€€€€€€‚ƒ€„€}ƒ„€€‚}z{{|||}€}}}€€~}}~‚‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxyzruyyvwwsu†…ƒ…„‚„„…„„„ƒ‚ƒ€~€~€}}}~€~€~~}|€|~€~€‚ƒ€€ƒ„‚€€€€€ƒƒ€ƒ€~‚ƒ„€€‚‚‚„‚~{|||||}}~}z~}}x~|||~~~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„‚„„…ƒƒƒƒƒ€}~}}}€~~~}}€€~|~~~‚‚ƒ‡…~~€€€€€€€‚‚€€~€‚‚ƒƒ‚ƒƒ…ƒ}}}|{||yz{z~y{yx~{|{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst†„„†ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€}€€~€}~}~€€€|€€~}~~€}€€ƒƒƒ~}~~€€€€‚€~~€‚‚€ƒ‚„„†„€~}||||zyvyyzyvyv~|{{{~}{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…„ƒƒƒƒƒ‚‚ƒ‚ƒ‚~~€}}}|€€€|€€€€|€~~~}~~‚‚~~}~~~~€}€€€~~~~~€‚‚‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{{{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvpxyrx…………ƒ„„ƒ‚„‚‚€‚€~~~~€~}~|~€€€€€€{€~€€€€}~~}}}~€‚~~~~}}~~~|~€~~~‚~~€€~ƒƒƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}|{|z{}zzx{|zz{xtxuqrtpxxqy„………ƒ„ƒ‚ƒƒ‚‚‚€€€€}~~€}|~}€€€€€€|€€~€~~~}}|€€€€~~~}|~~|}€~}~€‚~€€~‚„‚‚ƒ……‚‚~}|{{||yw|ywxwwx{{{{|…Š}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzz{zxswuqqsoxwq{…†……ƒ…‚ƒƒ‚‚€€€€~~}|~}€‚€€}~€~€€}}|}€€€€~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{||{zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚€€}}~€‚‚}~~~€€‚€€~|~|€€€€€~}~~€€‚€€€€€€€„‚‚€~|}~~z}…~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚€‚€€€€€€~}€€‚‚‚€~€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€€‚€€~}~{“z|}|{}y{zzxyxy{||}|||||||}}}||}|~}~~~}|z||{|}{yzzzyytuuooqpwst}…†ƒƒ‚ƒ‚€€‚ƒ‚€‚‚€€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€€‚‚€€€}~~|†‰||~{{~yz{z{Ž~wwy{|{}||||{}|}}}}|}|~~~~|z|}{|}{yz{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€€‚‚‚€€€€€€}~€}€ƒ‚{~~{{}{z|||‡yxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€‚€‚‚‚‚ƒƒ‚€‚€€‚‚‚ƒ‚„„€~‚€€€€‚~€€‚€€€€€€€€€~}€€€€€€€€€€€€€€€€€€~}~}~~{}|}|||wxuxxy{||}|||||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒ„ƒƒ‚‚‚‚ƒ€€‚„ƒƒ„ƒ‚ƒ‚€€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€€€€€€€€€€€€€€€€€€€€€€€€‚ƒ‚‚€‚€€€€‡~~|z}|{}xwvyyz||||}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚‚„„€€ƒ†ƒƒƒ‚„€„ƒ‚‚€€‚‚„‚ƒ‚€€ƒ‚€€€€ƒ€€ƒ‚~‚€€~€€€€€€‚‚‚ƒ‚‚ƒƒƒ‚€€€„}}}{}z}{zvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysruowqwysw{…‚‚‚‚ƒ„‚ƒ„ƒ€€ƒƒ†ƒƒƒ‚‚„„ƒƒ€€‚„‚‚‚~€€€‚‚‚‚€€€€‚‚„€~ƒ‚~€ƒ‚€€‚ƒ‚€‚ƒ‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ‚€‚€}€|z|{{w|yyy{z}~}||||}~~€€€€„„€}€~{{{z{ztpxrytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚ƒ„†„‚ƒƒ‚„‚„ƒƒ€ƒ‚‚‚‚‚€‚€€€‚‚‚‚‚€ƒ‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚‚„ƒƒ„‚„‚ƒ‚‚‚‚ƒƒ„ƒ„„„„„…ƒ„‚ƒ‚‚ƒ€€~||€}|x|yzyz|}|{||}}}||€€€€€‚~€€€€{{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚ƒ†……ƒƒ‚ƒ„‚„…‚‚‚ƒƒ‚‚‚€€~€‚ƒ‚‚‚‚€‚‚„‚‚ƒ€ƒ‚€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒƒƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{}~}y|zzz}||}z||}}|z{~~~€€€€€€€‚€€}}|}}|vrvxxvtvu}‡‡ƒ‚„…ƒƒ„…„€‚……„„ƒ‚ƒ„„„…ƒ‚‚‚ƒƒƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚‚‚ƒ„‚‚€€ƒ‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚~ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz|}€}||z|~}|}}~~€€€€~~€€€€~|}}~~}||xvvw„‡ƒ‚ƒ†ƒƒ„†„‚…†…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„ƒ‚‚ƒƒ‚ƒ‚ƒ‚‚„„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒƒ„„„„„…„ƒƒ„…„…„ƒ‚€}‚€}||{||€}}~€~~}~|||}}~~~€}}~€~~}}}~}}~~€|}€‚‚ƒƒ…ƒ„ƒ†„‚ˆ‡…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒƒ‚‚ƒƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒ‚‚ƒƒƒ„„ƒƒ„ƒƒ„„…„„„…………„ƒƒƒ}„€}}||||~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒƒ…ƒ„ƒ…~‚Š‹……„ƒ‚ƒ…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ…ƒƒ„…„……‡‡†‡…„„…„ƒ~~|~~}€~||~|z|}}}}}~~~€}}|€€~~~~~‚€……„ƒ„„‚„ƒ†€‚……Š‰„„„„……‚‡††„„„„…„„„„ƒ„ƒ‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ„€}uz„„„‚ƒƒ‚ƒ„ƒ„„…ƒ„…†„…†}„y|~ƒ{…ƒ„ƒ€}~}~ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚ƒƒ‚‚†„„„…„ƒ„…ƒ„…„Šˆ………ƒ……„†††ƒ„„………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†spurstƒv{}u‚ƒ€‚vy…€ƒ€„…„‚……‚hzrss|€rƒƒƒ}}~~}~‚ƒ‚|}€}}||||}|||~}~}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ…ƒ†ˆ††…ƒ†††‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vyy†r„ƒpvxqvtturstvi€nrotvnulwm{sn€‡ym}rsvsvmnwlpylu}|~€}€}€€}}|||}|}~}€€€~|~€‚€€€€€€€‚ƒ‚‚„…‡††€‚…ƒƒ…‡†ƒ………†‡‡„ƒ††ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoomw}x†pqzprtfu~n{ysoy€}~€{~|€~€€~~€€€~~~€~}€}€€€~~€~‚ƒ‚‚„…‡‡„~†„ƒƒ…‡†„†……††ˆ„„†‡ˆˆ†‡„††‹Š…„†‡‡…ƒ………„‚…………†……†…†quprsoszy~ƒtˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„rioyxpkyszozwvvp€~~~z~}|}~}€ƒƒ€‚ƒ„‚€}~~~€~~‚€€‚„‡†ƒƒ†„……†‡†…………††ˆ……†…‡‡…†„††‰ˆ…„‰‹ˆ†„†………ƒ……„†††††…ƒx‹yrˆz{pp……x…xyks~y{krƒ‡ƒz|mzyyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozks|nv‚~~}}z}{|}}~}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ„†„…………†‡……………‡‡ˆ†„†…‡††…„……„……†‰Š‡…„†…††…††„†††††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„…†…†„†„ƒ„„†„„ƒƒ„„…„…„…„†ƒ…†……„„…‡†„„…†……}w†ƒ„„ƒ‚}~{|{~{||}~}|~€}€~~~€~~~~}}}~|{|~||‰†…„†††…††…………††‡ˆ†„†…‡………ƒ„…†…„††††…„†„…††††„‡†‡‡†…‡ˆˆˆˆ†„‡…††ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…ƒ‚……†……ƒ…„„„…„†…„……ƒ††…†…„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ}€{{|~{||}~||~}€~}€~~€}}|€}~~~~~||}~{|||{{~ˆ‡„„ˆ††…‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡…††……†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ……ˆ…†‡†‡†‡†‡…‡‡†‡……†‡…‡†…‚ƒ…††„„ƒ„„ƒ„†„†…………ƒ††…†…„††…„„……ƒ„‡…ƒ‚ƒ„ƒ„‚~€|{}~{|{~~}||~}~~}~}}~~|}||~~|}€|||}|||~z{{|~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†„…„‡†„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…‡‡…‡†‡†‡…ˆˆ‡‡…††‡…††„„„…†……„„„ƒ„…„†††…†„†…††……††…„ƒ„„ƒƒ‡ƒ„‚„…ƒ€€€{{~}|||~}|||}}|}|~}|}}||||}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††ƒ…†…†††…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡…†††‡‡‡…‡†ˆˆ‡‡…‡‡‡…†‡„‚„ƒ„†…‡…„„„„„…†††††…‡……‡…†…†…„ƒ„ƒƒ„‡ƒ€‚ƒ„‚‚‚€{}}|||~}|}}|~{||{||}}{{{}|{~}{|}}|}}~}|zz{{||ˆ‡‚††††‡††…ƒ…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡ˆˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡…‡‡††‡‡…‡†ˆˆ‡†…‡‡ˆ††‡ƒƒ„„ƒ††‡……„„„…†††††…†‡††ˆ††„†…ƒƒƒƒ‚ƒ†ƒ~‚‚ƒ€ƒ‚|~||}}|}}|~{{{z{|||{{{~{{}{z{~||||}~}{z|z||‰‡ƒ†…†…††…„„……………„ƒ„†„‚„„|€†‚……†……†…„‡‡ˆ‡ˆ†…‰Š‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……ˆƒ„†…ƒ††‡†…„ƒ……†††††…††‡†‡‡…ƒ……ƒ‚‚„…‚ƒ~‚ƒ~~~||}}{}}|~zz{y{|}{{{{~||||z{}||||~}|{{{{|{‰‡„†„†„††…„…†…„„ƒ„‚€ƒ†ƒ‚z„Œ{€„…‡†††…„‡ˆ‡†‡……‡‰‡„‡…††ˆ†…‡„†‡ˆ††ˆ‡‡‡†‡ˆ†„†††‡……‡ƒ„…„‡††‡……„ƒ……††‡††…†††…††„ƒ„…‚‚€„ƒƒ‚}~ƒ~€||}}~}{}}|}yzzy{}}zz{{}|}||zz}||}|~~€{{{|~}|ˆ‡…†…‡„†„……………ƒƒƒ€‚…‚€}|{„…††„…„„‡‡†††…„†‰†‚†„†††……‡…‡ˆ‰†…ˆ‡‰‡††‡…„†……‡…„‡ƒ„…„ˆ††‡………‚……†…††‡„††††…†‚ƒƒ…€€€€ƒƒ€|€~~‚€}€||}~}~{~}||yzzyz}}yzz{|{|{{z{}}|}|~~|{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€ƒ~~~€yz}€ƒƒ…‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ†…ˆ‡‰‡†………ƒ†„…‡ƒ„†„„…„‡†…†…†„‚……†††††„…††………‚‚ƒ„~€€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|{{{{|}}}|€~}|||~|{‡……††††„…„…ƒ…‚€€€€~‚‚}}{‚ƒƒ…†…„ƒƒ†ƒƒ„‚€…‡…‚ƒƒ„„„††‡‡‡……ˆ†‰‡…„„„‚…ƒ„†‚ƒ…„„†„‡†………†ƒ„…„…†…†„„…„…ƒ…„€€‚ƒ~€ƒ|€}}‚}€~~~~~}}{|{zyzzyz{|yzz{{{|z{{{|}}}}€}}||}€}|†ƒ††††…ƒ„ƒ†‚…€€€~‚|~~€€‚‚‚„„ƒƒ‚„€ƒ‚€„…„‚€‚ƒƒ„……‡††„…‡…‡…†‚ƒ‚‚ƒ‚‚…ƒ…„…†„††‡††…‚„„ƒ„………ƒ„ƒƒ„‚„„€‚‚}~~~„~{||€}€}~ƒ}~~}}~{~{{zy{zyzz{yzzz{{|z||||~~}|}||}€~€†„……„‡„„ƒ‚†‚ƒ€€~~€}‚|}~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡†……„ƒƒƒ„……„ƒƒ‚„ƒƒ€€~}}~~|~ƒ~|~||€~‚~‚|~}}|||{{zzzzy{yzzyzzz{|y{}{{~€}~}}}€€€†„„…„…‚„‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„…ƒ‚ƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚€…ƒ~€~|}~}|~ƒ}{~|}€ƒ}}€~}|||}{{zyzyy{yzzyzz{{{z{}||‚€~€€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌËËËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFK=8765999<>9?<C:;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937676=;>:=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<:<<98:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA>;A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9>CE?<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÑÓÓÓÓÓÓÓÓÓÓÓÓÓÎÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø×××××ØÙØØØØØØØØÙÙÙÙØ××××××Ø××××××ÖÔÓÓÓÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILN@99:4;A<7=9AC=@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌ̈́mpppppppppppj§ãÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¸·©§§§§§§§§§§§§¦®¹¸¸¸¸¸¸¸¸¸¸¸·½ÓÓÓÓÓÓÓÓÓÓÓÓÓÓÛââââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVM<::77>C>8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÎN&+++++++++++"ŠôëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§££££££££££££ †„„„„„„„„„„„„‚’¥£££££££££££¢«ÓÒÒÒÒÒÒÒÒÒÒÒÓÑßêêëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;?C>6:7>?;<B@8<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÍÎR+11111111111'óééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤¥¢‰‡‡‡‡‡‡‡‡‡‡‡‡…•¦¤¤¤¤¤¤¤¤¤¤¤£¬ÒÒÒÒÒÒÒÒÒÒÒÓÓÑßêêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;?@@8:;8<<<<>::;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÏ\9===========5“ðççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©©§ŽŽŽŽŽŒšª©©©©©©©©©©©¨°ÒÒÒÒÒÒÒÒÒÒÒÓÒÒàéééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB>;=:9;:=<;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÅÂÃÃÃÃÃÃÃÃÃÃÃÂÉÐÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÎÎÎÎÎÏÎÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÒÐÐÐÐÐÏÏÏÏÏÏÏÏÎÐÑÒÒÒÒÒÒÒÒÒÒÒÒÒÔÔÔÕÕÕÕÖÖÖÖÖÖ×ÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<7@A<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÏÐÐÏÏÏÏÏÏÏÐÔÐÐÎÌÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÎÑÔÏÏÏÓÓÏÏÏÓÒÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××ÖÕÖÖÖÖ××××××××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?89:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÎÓ»ÏÐС–ËÒǒ«ÑÎÎÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<=B>BB@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÎÒµ•›³Ö§ «ŸÏ™¬š²ÒÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?><7:>9?D>@98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÏџ ª¯Êœ–¡´•†œÍÏÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<<96?B?B:647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÏÑҚ³¿› ¨™µ¿É—™ÅÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8E@?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÏÏÖ§™²Ì£ ‹ŸÄӑ™¡ÏÐÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<==964:99::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÏÏÕ¥™±Ù˜Çɔح£¿žÕÑÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ×××××××××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:<?>=<9@<<::9?@==<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÐÐÖ¥™³Èœ••¤»Íˆ•žÈÒÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CFCAA8;?<=;<<7558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÐÐÕ¥š·±š¯³¥ÐÛ£™µÕÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF?HHGE@<<>><==<756:969;::;8@?:<<9<>=;;:?9?:;9=>=><;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦ÓÐÕ¥™·±ž›¢œœ‘§˜ž»ÕÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@C;557<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡ÇÒÖ£š²É¨¡£ž¨¢©ÐÓÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKL@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÓÑÕµ‚Ãׯ‘¥Ôš’Ž¾ÖÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<<?GEGKH=557:979:;:<=9>99:8;=>>A>=9<<:=>>:=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÑÑÂÔÒÕÀ½ÖÔÓ¹ÈÕÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?AELLA>675;8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÒÒÔÒÒÒÔÕÓÓÓÖÔÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEJ>>786977899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9699:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:69896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EIKAALD??;9889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEHIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDI;AA;<886586987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGJB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFID<BA<;876797799=?A?<:9@?<>B?:8776=?@@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE><HF89757875898;>>=;89A>=@?A>7596;>AB??@@AB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCEEC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK@;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A>HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AA?JO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ACCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELBA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?BGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<<DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGHNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAD?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€iixsg~‰‰xp‚†{w}~…Š½ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€‚wt|„‚}sp€Šx‚yƒÈÞÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsnupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495666788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643954775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿¼½¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573146498566:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730473786766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»ºº¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjcmgb\XQPQKTJB:IQ?A7<94:565455588686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸¸·······¸¹¹¸¸¸·¶·¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶µµ¶¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸¸·¸¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469444738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬¬­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶·····¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨§¨¨¥¦¨¨¨§¨§¨©©ª§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸········¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::9:9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª¨¥¦§§§¨¨§§¨¨§¥¤¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§¦¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©«««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤¤£¢¢£¢¡ŸŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žžž£¤¡ŸžŸ  œœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=6789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥£¢¡¡¡¡¢£¥§¦¦§¬«§¦ œ›¡¡ž››šœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¦¦§§§§Ÿ›šœ¢ š–••š›š——˜™šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜˜™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥£¢¥¦¦¦¦§¦¦ ›™›¡ —’ —šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB?DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥¦§§¦¢žŸ¡ —˜¨¢”—›˜–—–˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;<;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¦¦¥¥¦§¦¥¥¦¦¦¥£  ¡¡Ÿš t–š™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡¡¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢¢¢¤¥¥¬¦¤¥¤£¢¡¡›¦‚a”™›™›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œŸ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸžŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::78:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸ   ¡¢¤¶µ¥£¤¢¡¡ž›œ£]fš™š™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢Ÿ›ž¡¢£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œ››œŸžœœœœŸ   ¡¡¡  ¡  ¦¥“±¢¡ žœ›š§…Unœ™šœ™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥¤¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¢¢¢¡¡  ­zŒ­Ÿžššœ¦g]qœšž›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›š›šš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>99;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤¤¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ ŸžŸ ¡   Ÿ©iœ§œššŸ—jgr›žžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›šš››š˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9<<>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœœœžŸž¤–t}©œš›œ¢‹kip›žœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:<>9?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››››œ›š –{w‘šœžœ}jir›žœžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™™™š  zŠ…™ž’€kfsšŸœœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›œš™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š›››œœ›™™™š› — }r™¥›xŽ†ir›Ÿžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ››››››œ™™™™œ«ŸŠq`§©az‰ytžžžŸžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ›››››œš˜™˜Ÿ­p`i¢“T_y{… ž  ŸžŸ¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_^]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜˜——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜™—§§tEFn—€{P>[v„››žœœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±´­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=:F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œš››œ›˜™š˜˜™›š›–©šLDFp•‚qRG8`xŽ’’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨ª¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‘‹‘‹Œ‘•¬u]x_ƒ¶¯¥bv~Kj~ˆ‚‹†‰Š‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜ž—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VQQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹Œ†Š‹‹‰‡„†ƒ’¨`Ž³ŒÎìÀ¥€•zRz‚’†„„…ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹Ž‹‰‰…‚‚~~Š—rÐÖÉ×­Ÿº³cdpZn†‹†”’‹—”—’˜¡–ž–•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¦›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ‚†‹‡ˆ…„ˆˆŠ„‚}‘ÍµÂÎÈ¿¬”|ª¬_h‰ŒŽ‹™œ””” ššŸ¢­±®©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPEMISWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‘ŒˆŒ‹ˆ’‹˜u˜¢´ªž‡‚ph̀`‹‹Š””˜•œšž¨®²°°µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWMO_^\NUUbQDTM;?9<895875795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš™‘ž¡“—›¡šžœ£¡Šz†£Œ„‰wtmv£‹f†Œ˜šŒ”š—œ› ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUJTOOJDPK_bXZQ\T`MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ªª©§¢¥¨©¬ªª¯§™~[f†xxmjhuv}w„£¡¤ž›š¤§¤©«®¬¥¤¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdWOYKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®««¬¤¡¢¥ª¨§ª¬‡qV[tqryiebiip|‹£©§ ¢¡®¬«ª§­®¨¥¤©©ª©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_VZNRNQOSe\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢™œ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨§¦¨©§©©¤¨¦™ž¥¥¢¢°žqkRRvwt{haef^_o|‹ ¤  Ÿ¡¡¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOXO^ddlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤ ¢ £§¡¦®¨°²¬€hfKNpuw€i`biZ]bkuƒ‘¡  £š–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvxb_\UYQUW[c_s_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?B?:8:>?C@DA:;>=@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯««¬¨¨«¯©¨ª¨¢ ¡§©­¶¼¾½¬nhcFUno||n`^fZZabgpxŽš ¡¢˜–ž›ŸŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸŸ¡¦¢›—’šš •|wo}yf[[`_Z\V\hdocmjib^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¢ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£ £ªª§¯¼ÆËÍÆ·¦shj\BNpntnsgbaYX_cabjquzŽ¡¨œ¡š–ž¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¡™˜¥ ¤§ª©¨ª­¬¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxjb[__\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>BE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢ «´ÀÔÝÛ˹«›‡p``bUFEun`_mm\[WZY][[^bdehx’§¯¦¥˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨¨«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥¡¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxxxc[RYT__amivkphiibZSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶´º±ª®´±°²´´·ÅÒÙÖÉ®‘xf]Z[\TLAkjŒ˜YTXW\\]]XUX`r‰¡²Åô² §ª¬§«©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš’–””˜“š˜Š‹‡€€|‚xa^YTai`ftotitdidb[LK>:9898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÄÇÃù½¾ÁÇÍÐÄ ~i]YXWSITl§³¨NU^ab___fz–¯¿¾¾À²µ¶¨¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`b_^kcbnxuwnm[bRV\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAA;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–••‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±°§¼¼¾ÅÄÆÉÇÅÆ»ÅÁÅÆÀ¼¹Ìɹ—s\UXTQRœ³ŸNY\^]`mŽª»Á²¶§¦±µ«µ²­³­©®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|~„jfhaklgnurruqg^`\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8BBBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÄ¿ÃÃÆÆÁ±“¿¼Ëп˜jXWYL’·–MUYX`¦¼°¦«®³§ª©©«­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|tklndomiqxozjia]gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÄÄŵÀ¸³¼ÁÅ¿©wWUQŠ½MSV[ƒ ¦·¯¥­´´­¯¥¤£¨¤  ¥™ª´±¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyy{wnkihuZfrxsyff^d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÊÆÄÃÄž¸½ÁÿǻcQaePS`ªŸ¦´²­¬¸µ³«©£¡­©¬§­Ÿ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuuefijh]jonyxcba`^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÎÏÌÃÇÆÈÉÈÈÉÇÅÉÇÈÇ¿ÄÇÄÄÆÊ΍RIPQf§º·À½¾¹¼º¼º¼¬­¦©»º¹·¿²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqocagvhiitmyl]d[U`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÌÐÍÇÌÉÂÂÇÂËËÈÇÌÉÍÅÅÅÃÅÄÉÌÓӖMM\ªÇÀÈÍÆÄÁÄÇÁ¼¾´±°°Â¾¾ÁÆ¿¾¸¶Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`kjwlieuntc]bTWUSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<9>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÄÇÈÆÒÉÁÃÿ¿¾ÄËÈÊËɼ¼ÈÇÉÍÈÃÈÉÉÅÅÂÃÁÂÆÆÇÊÍIÍÍÇÌÐŶ¿¿ÀÀº»½µ³³À¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrpfegcjdbjmno^Y]VVNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾƹ»Ãº¸¹¼¾ÁÇÁÆ»¹ÈÈÃÅÄÀÃÁÁÀÄÁ¾½ÁÁÀÀǦM¤ÑÌÅÉÑÁ¯½½¸¹»»¾·´±¹¾³¼¾±¹µ¸»¶¼´µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfadbacccjbgc[ZZ]YQOE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶·´´µ¿»½¿¹¾ºº´À¸µ·²®º»·À·¼ÊÏÁ»¿À¼»Ä½ºÀÄ¿½½¸»ÀÄ°SžÍÄÀÁÉ¿°Á¿º·»¾¹µ¸´¸¼´½¸µ´°³¼±··¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|yˆ}qdabchjggiei^VVTYOSLF8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“““˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´´±°µ·µ»Á¸¾¹¿¼¼·´·¯®·µ¹¿»ÁՎ¼¾»ÃµºÇ·¶¸»½¹¹µºÃÈ«T—È¿¿»Á¾¹Æ½Â¿¼Å¸¶·´¸¶¶»»¹¶´·ºµ³¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒyqmeefpjekhXYOKKKRJLHD9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’™”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿¾¼²­¯¬±°·¼·»½ÁĹ··¶µ¹¹º»¿¼ÐÅy­Ë½Ç·¹¸­¶´·º´·³»ÅÊ UŽÉ¿¿¾½¼¿ÈÃÅžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~‡}knqgpksfbn`\THKKDJCCG?:;8><7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘Ž˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼»À·ª­¤®°¸»²½¾»Ä¶µ¸µ·¿¾Ä¼ÂÄدv„¾ÈÏÂÀ¸®µµ»¾·º²¾ÂȖ[ˆÍ¿¾½¼ÇÌÇÇÄǽµµ¶Á½»»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†€rfljntnwcgb\cQKUHEECGC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?>??FD@A?>:7?@CC?@=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼ªª£°¹½¼²¼¾¼Å¸±¸¹¼ÆÉÊÂÇÉћtw±ÑÑÌÊĵº¿ÄȾ¾µ¿ÀÀ‡h}ÍƾÁ¼¿ÃÌÊÇÅÆÀ¹½¼Ä¿¿¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒ‚tolltlln_c^abNHN?E@?DC;;::;:8;<:9<>::>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´»Åк¾¼Ä¾·¼À¿ÉÏÇÈÊʈvw¨ÌÌËÍÊÆÂÃËÎÁ¼¹½»±zmÀÇÄÀÀ¿ÄÀÊÉÃÃÄùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{zˆ{mmx|`qc[^__TI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA??ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸´¼·»º­Ûþ¶¾À¾¾º¦œª³·ÄÀ¦|z|ŸÄÆËÈÁÃÀÀÉÊÁÀ¼º²¥–ˆy³ÈÅÄ¿ÀÁ¿ËÇÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}‚znsxthp]\_\ZQEEDMIAD=H;;59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘—žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯··²µ³·¹¼»¶»»Å¶n¯Î½¶¹À¼ª}nhnmt‚—™u{œ¾¿ÆÀ¹À¼¾ÅĽ½¸±®¦«–”¢ÊÃü½¿¿Ãþ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸··½¹»±¶²ÈÀ»¶´±°·¬³©°­­´·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|wlu{pni\__YSPAFIGK@ECH<=6;99<;::;;=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿš›œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹Àͱv‚´½¶µÁ¤†iZ^`NS[\pvz…¤¸·Âº³»·»½¿º»»®¥­²¡¥‡ÁÅþ¼¿»»¸¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ°µ´´½º¾ºº»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰{‚zsvvwnqa_f][UJ=??GF=GCC9:5;99><<::<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Âɦ„x‹¢°µœjfgVY_IIMPTo{‹©°·¾¹²µ²¼¹¼¶¹¾µ™±¾®³x°ÉÄÀ½¿¹³®²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtwrl_ca\^OIB?=IDFMD@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·¿Æ¨‡{vŒ¡˜_SCYUHbjUOEJe‘¥¯¯¶ºµ´²¬¼¹¸µ¸Á½¬Ä´´w§Ê¿¹ºµ®¥¬³±¦°­¨ Ÿ¥­¶µÂ·¶´¥¨ª¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´¶¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wp|ovrnc]fY]]SONA>JB@KJ@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³²­¶º¯­¼³¸¸¿³yˆnNK@eYBOx“hMC^…±µ³µ²´¯¬»º¸¶¹¿Æ~“º«¢h«¿¸µ²±­­Ÿ¤¦§¤¥œ–™™™Ÿ©®¹¬««Ÿ¥¨¤«®¯§°«¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶¯ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmuil][jT][PNHDGMBFNF8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹º¶¹»µµ³·¶•Œˆ…|XFAO‡XIJYxŽƒcAU£¹³´²°±­°¹¸¶»·º½”§´¯§w­°©«­«£¨¡ž—— •’–—˜Ÿ¨®¤£¤ ¢¦¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬ª¯£¤£¡© ›“Ž”’’™–š¤¥ Ÿž§˜•’”™ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wrxhutneUacW]QOMH@IRDMC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯²¼©˜™•hM@SyqOIILi€ZEU°º±¬³¯®¬­¶¶²´µ®©¦Ÿš›Ÿ¦¨ž ¨©Ÿ¡§–›——Ž”–—›¤¨  ¢¢¢¥¥££ ž¥ ¤¬¥¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›ª¨««Ÿ¦¢›£œ•Œ“—•–˜Ÿžž›™¦—“’–¢ ¥¢¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦¡ˆxƒ|vzcwln]QiTPNGPMLCPQ@>;>49:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¤¬¨½Áª¥¼gDSœ~PXIKaJWŽbeeƒ¯µª²´®ª«¯°²³­¥‘—“— Ÿ¢ œ£¤Ÿž¨”›–—Œ—‘—“˜¢ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨¨œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£žžžš—š«¦ª±£¥¨ž œ•“‘‘™–•˜—Ÿ˜›™›¤™—”•š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’~|uv}nk{dhVRdMJHGOSNKNH<E@<2?859;>;98;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜——–¡¨¬®¶·º¹º··»®¨ ¡© «Æ¿ÊŸOAu™pPmJLdfvta]bt’²¯®³µª¦¬«¢›™”‘•–˜˜œŸ¢¢œ¤žš¤———–’‘‘“š—› ¤ªž¡¡ž¦§ª¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¢¥¢š™ž¯¨®²«¥ªª ›˜˜˜•“–š“••š–›——™¡žœœ–›¡›žš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}wy|eyy`bSU`HIJKSTISQM9?B67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—“’œž¤¨®­¬««¯ª¯©ž—ž¥œ¥ÇƋWSJf¤Yf}or[Rkd\gb`m‘µ°°¸¬¦¡œš”—š™Ž‘•‘ŒŽ“™¢œ—£™š—˜™”™˜–›Ÿ¥¦© ¦£ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§¡ £±®²±´ª²®£™œž¡˜››š˜™›”–›–™¥¡ š£¡šœ™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ ž ž ¥¡žž¥ ¦™{|vvsh‚le[S[YMQJOOVMSMB7>C78=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’‘œ˜¡ª¢§ ž§¡¥Ÿœ’›¢šŸª£ŒyUjrwupcwvXWb`di[ZWh­®¬¯§Ÿž¢ –“› ›™—’“Ÿœ¡£›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬©¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½¶¾°¬±®­©ª´±°¨«¨³¶¸³¸­²´¤ ¥ ¬¡¡¢¡ š˜–•Ÿ››˜¥¡ ž£¡ ž›œ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚€|xvjwu^m[R`HRUHFUWJCMG=KH8F<77;>=<:;98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“Ÿ™¨®Ÿ§žœ¡žš™’˜ž›¡¡ ¤o‚p`cWK[RZLLQYRHONH™¬ª©¤ŸŸ™’’”˜˜––•Œˆ‹Ž•œž—ž™¦Ÿ ¨¥±ª§®£«®¶°´²±®¶¸½¿º­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«®±¹¸¼¯³°µÂ¼·¾³³µ¢¬¢©¨²©«¨§¨š™žšª§ ™§ ŸŸ¨¨¥¤žª¢¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰…„~vrmiwmhm\X[CWNJGMGCFM<>L>4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜™ª ±¢·¤°¦Ÿž—˜•™žšœ£žœ‰bW^e`WMQG=?@CD?>BRx©­©ª¥ŸžŸ¢£žšœ›”“•”ž˜”…š š«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶»»ÀĹ½»¬¯§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¹Â¾¸³»ÆĽü·³ª³­ª³´¯³®ª¯£¬¨¶±­£°¦ £°±®°¤¥¯£¡ š¡¦¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¤ž¦š›¢¤žŸ›››œ‡†{trkkurqhV\QFUHDJPI?EA4FH95<>7;<>=<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž  œœ˜šŸ š Ÿ•|_^e`PFD;C>F<>96N~ª²§££¢ ž¥«¦ž˜œ”‘™™•ŒŠ†ˆ†xmˆ ¤¢«¬´¼¶Ã¾¾³»ÁÃÂÅÀ¿ÂÆÆÅÃÈÂÀÅÈÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌÌÌÒǾ¿À¾ÇÆ·ÃÊÉÃÁÇ¿º´º»µ»·°¶²ªº²®»¸¿»º«¸­«ª¸»µ¼®®¹£¦£ž¦¥¢£©¦™›Ÿ™š§ª§ ¡¡¤˜”£–”™‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ…~zrkcioxkeY[FKLEDTLDCE7:?:549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ²²¸§¡¡«ª¡œž¡¡›š}riaWNE>IY|oaA=\Ž®¬ ™››žž™———’——“ŽŒ‚ƒ‚wrqmp¦­®´¹Å»ÍÇË¿ÂÌÍÍÌÇÉÑÌÌÌÇÉÅÆÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÑÓÍÔÐÓÓÌÊÂÅÆÆÊÈÏÀÉÑÌÇÆÈƼÃÁ¾¿¿¶¾³­¿ÀÃÃÇÅÇį¿¹²¸¼Äº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›‹™‰•˜› Ÿ£—žš““‹•…ytsebgrof^ZZCNLDFPIDC@55589B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>9;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›¢¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¤¨¬­ª £žœž•if\TID@?K†ž¤˜ƒ ²­£žœŸš˜—”’”–‘Œ‡„ƒˆ‡ƒ€€yqroly¤¶º¹¾ËÁÓÒÓÈÍÎÑÓÑÒÑÐÑÑÍÎÎÐÅÎÔÕØÒ×ÍÆÇÉÌÃÅÊÏÊÓ×Ò×ÒÕÖÓÔÈÌÇÌÍÊÓÍÎÓÍÅÉÊÊÂÇÌÇÉÉƿó³ÈÅËËËÏÇÊ¿¾¿½ÁÆÅÍÌÉÉÀÃÀ®¯³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›•Œ†‘‹€{ruvgcgvjdVWQDNF@JQB>B<:22A<E<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<@?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­³·¬®£ž£¢¡›aSLJDC?CS°Ò½²¯¦œœœ ¤¡š”“•”‰}xqkebhroq{…Š€upnqtp…³Ã¾ÅÑÐ×ÖÖÒÖÎÔÖ×ÔÓÑÓÔÔÓÏÑÄÐÓÖØÕÖÒËÉÎÑËÆÍÑÊÒÕÖÙÖ×Ó×ØÎÒÊÏÑÌÏÐÌÓÐÀÈÈÊÄÌÌÌÎÏÅÇȶ¿ÊÀÒÍÌÐÇÊÉÀÄÃÈÎÍÐÑÏÍÊÈ͸·»¨Ÿ¥«§Ÿ˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„}xsvpc`erb]R\IJGAEIJ>;A8=5586;86:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÁűµ¨¡¤¥ ¢¡YI@ADAFQv²¯¦š”—Ÿœš  ž›œš•‰wica__`_^__]alusppolrqu’ÄÈÇÔÖ×××ÓÖÐÕÔÚÔÔÎÏÕÔÔÑÑÌÑÎÓ×ÖÓÕÐÏÒÓÑÉÓÑÈÐØ×ØÑØÒ×ÙÔÕÌÏÏÊÍÒËÎÑÀÆÃÈÆÏÎÑÑÒÈÌÍÀËÌÆÓÏÌÏÈÅËÇÇÉÌÊÔÔÑÕÏÒÌÓ¹ű¥¨µ®§›¨«¥²¨°³­¬““Žˆ‹Žƒ‹„Ž™“™‚…Œ|zqstmacim_VP_JJCFCRM@<>43:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><?@=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯­ªª«¥®·¨«·ØÔÕÙÙÑÎп¼Ìɶ¾®¦ª¨¡£«eC8=>DX‚ª¨Ÿ—•—™šœŸ˜œœ’}qecb__a_^a`_``_`emppnkorwwœÌÁÓÕÓØØÖÙÑÒÒ×ÏÓÎËÒÍÕÔÑÊÏÍÓÖÒÑÖÍÏÕÕÑÅÑÔËÐÔÕÖÎÓÑØ××ØËÈÎÄÉÏÌÊÌÀÊÀÉÊÎÎÐËÐÎÎÌÏÏÈÌÐÐËÎËÃÊÇÉÍËÌÒÓÍÓÒÑÐÐʽȹ°®»¹µ«¶°­¨¸­³¾»±š ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…‰zvoqokadnpaW\ZIFFDMXE;@=33<<87855;>@=9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ¤§Ÿ¸¶µµ¬¤¬®¾´°ÀØÒ×ÚÜÖÎÍÊÃÒÏÁÁ±©¬­©¤±zHFB;WŽ¡›•“–›žžžœ“–—”ˆk^^^adb``aa``a^__^\bmroostvvy¤¿ÌÕÑÖÔÓØÖÎÎÓËÎÎÅÎÊÒÒÏÇÎÍÎÔÌÎÒÍË×ÖÐÌÑÔËÌÐÒÓÊÎÑÕÒÕÕÊÀÊÂÅÍÂÈÊÃÌÄÆÉËËÏËÎÍÐÎÓÌÆÉÏÍÈÇËÅÇÁÆÊÌÍÐÒÇÐÏÎÎÌÐÅÇÁ¸¹½Ãýø²²¾±»Ãõª˜¥¡˜–’••’‹”š‘””•‚‰†yqrkmg``qhYXhVMGLIPQB;C>;68:8::57==@;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÄÂÁ¿»µ²±ÇøÊÕÖÙÚÛØÌÌÏÈÖÕĵ¯´¨Ÿ­—xlpqy›Œ—•“‘‘•–•‹|eabb`]^aca``_`aa`_][]grrprsqmry¥ÇÓÏËÐÐÓÔÊÅÉÉÆÆ¿ÃÅÏÎÇÅÇÍÊÒÈËÎÍÆÑÒÐÎÌÔÊÇËÎÏÇÇÏÒËÐÏƺĿÆʽÂÇÉÎÅÃÇÀÇÍÈÄÌËÌÏÈÄÄÐÈÆÂÆÈÄ¿ÁÇÌËÌÏÂËÌÉÇËÐÄÅÇ»ÇÃÈÉÂÏÁ½¼¿°ÁÉƹ½ª°²§¥¢œ˜›£™—™‘•˜‰‚xotdk`^fqa[W`GHHGIMTG?J=64355==48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ¼¹ÌÌÆÐÕÕØÚÛØÐÉÏÏÑÓÈ·»»­£¶~hƒ…¤«”Ž–…ƒƒƒ}„„~s_[^^^`^`cdc_]]^_``_[Z\`lrqookloo}¹ÑÈÉÊÏËÍĺÀû»ºº¾ÉÆÂÃÀÃÈÊÉÈÊÈÁÅÌÆÈÊÍÉÄÂËÉÁÁËÐÅËÈ¿¹Â»ÆǾÀÆÏËÄÀûÉÇÉ»ÉÇÅÊÀ¾ÂËÆÅľƽ¼ÁÃÅÌÅƼÀÉÃÅÇÒÅÁÉ¿ÊÉÆÈÆÑÃÃÆïÄËÇÃÊ·¿¼º´©¬¤¥˜Ÿ˜¬£¡¦›£ ›•|wstfiZanmZ[XRDLFBGELDFS@54335?<3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ÊÏÑÌÇÂÃÆÍÎÎÌÕÏÕÚØÙÏËÒÍÍÎÈÁµÃ¾±¯¶l_z|¡‘‹’–†z€……vxurp_[[]``bcdded`\\]]_^`[YZ\borokikposÇ½ÊÅËÀÆ°¶º²²³²±Â¼¼¼º¸ÁÁÁľ½¹½¿¹ÄÊÅƽÆÀ¸»ÄÉ¿ÁÉ»·»ºÆÿ¼ÁÎÃƾ¾µÁ½Ã»½Æ»Ãº´¼ÆÄ·¿¶¶¾¿»Ìý¶ºÈ»¿¾ËÃÁÆÂÅÉÇÉÆÐÆÂÌȲÇÉÃÎÌÀÅÿ½²·°²§¨¨¹°¥­°ª­¬”zvwjdg`hocV^YJFJFHKAEBFJ@9:658854;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÅÂÄÈÎÒÊÊÉÆÍÍÎÑÈÐÅÕÔÕ×ÍÊÎÅÉÅÇÁ¹Å½«®¦`dvƒ“‹ˆ‹„x††~„{ttc\\]^``bcbbdeb]\[\^\^]Z[\^hsqmggnpry½ÌÀúÁ¸­°±§ª­¬§¸´¶´³³´»¶½±·°µ¯²»Â¼Áļ¿»µ²º¾À¸È¹´»·Á½¸½ÇÁļµ¯²¶º¿´Å·»µ«¸½¾À½±º¶°·º³Æ¼·¯»¿µ·µÅ¼¾ÃÅÀÄÅÆÇËÅÀÆÆ»ÇËÀÏÉÇÃÆÁ÷ý½¶¹¾Ç¿¬µ»µ·¶Žytxggebkn]V^`FKHHJFBDAEE?<:566633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÍÈÅÈÍÌÐÌÍÈÉÈÊÈÊÄÐÍÒÏÍÅÇÁÆÀ¿º·É¶ª°™[hpŠ…ˆ‰zx~††vw|sh]]]]_`_`da^cec__\[^\]^Z[[]_lpnifknnr|¤ÇÀ¸¸µ°«¬§ž¢©§žª¬³­ª¬ª´­¶±³©®§¬³»º¶Ã¹ºº±«µ¹»´Âº°À±¾¼»¶¼È¹Ã¶­ª¨°²À¶¸½°±§±³´»¼«®µ¦®¶®»²±ª¹°®»®»¸»ÀÀ¾ºÃ¿ÆÃÅÀ¼ÆÁÇ˸ÅÇÅ¿ÇÃúÄÆ»ÆÉÌ˳¹Â½»³‰swvki`blhXXW[ALKMJEAC?FA:9:996854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÅÎÒËÃÅÁÄÐÇÍÁÃÆ¿ÄÄÃÃÊÂÉÊ¿À¼Âº³µµÃ®ª°’[j’‡Ž{x}‰…z{„wn^]\\]_`__dcbcdb`_]Z[ZZ]ZZYZ\enohfhiknr­º°µ®¥¥§§š ¤ šœ¥«®¤¨¢«ª¬«°£¦Ÿª­´¶±½¹¯·°¨®¸´³¼¸´½¯¸¹¶²¼Á²À®¥¨£«±²³¨½ª«¨«¬­µ³¥¨®¡¤¯©²¦¨¨®¥¨·¬±³·ºº»²¼¾¾¾Ä¿µÂÁÇÈ·¾ÀÄ·Äÿ»¿Ä¾ÄÈÌÊ¿¿ÃÀÀ©‡stsji\aocWVXPHYRSKFFE>?@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÐÏÌÃǹ¹ËÁ˾»É¶½Ã¾ºÊ·ÁÃÁ´¶¼¶±¯µ»­¨«’dmˆƒ‡‹€z}~xt~|swe_]\\^_`^_ccab`a_^]\ZXY[[YXZ\_fkfdgehjor…ª¥¬¥žœ¡¤”¤š—‘¡£©££Ÿ¥¦§¦­ œ¤¦¬²°¶·§±­¨ª´«´º±¶¶®¶¹³°ºº±·¥ ¤Ÿ¦±¨«¨¹ª¤¦§¨§²­ §¦Ÿ›¤¦¬ŸŸ§£ ¡±­­¬²´³´°µ¼¶»ÁÀ²»¾ÃÁ±¹¹Â³Á¾Àµ¸¼½¾¼ÂÇÅÃÄ¿ÀÄ ƒxplbf`ko`UY_HNgOTGFKF<=@=:;;826536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;>97776788666;::;9:;<859<:>>@;È´¶½¸ºÀº½¶ ž”¡¦º¶«³³»³ÄÏÉËÃƸ·ÇÀÌ¿¸É·»Å¸³Ä¸³¿À¬µ¼²¬¥¯³­¡£‘ir†…†€|xusomjiipi_`]\\\^__acb```a^\[\\XYXXXVX[^_dcbegggkmoˆ©Ÿ–•š¡–›¢˜•Œž¡¢§œ Ÿ¤¥¢§ž›£› «°­±µ¤©ªª¬¬¤´¸­·°¬³¶¯³µ¯°ªŸžŸ£¢²¥¦©¸­¢¦¦ ¨­«™ Ÿž™Ÿ¥šš£œœž¯©«¨ª«­­°²¸¯¸¹º°¶¼»º«³²¹³½´¶±±¶µ¿¶¾À¾Ã»º½—„zsk_e^ddXTW]IW\KOGJJGA<??@;?<05535:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»·ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÅÏÈÈÀÆ»»ÃÃϾ¹Ç¸·¾·²Â´±»»¬¹º±¢ž©«§˜žm~…†xrmomkb^aff]]^]]]\]_aabccba_\[[ZZYXXWWWXXXZ^bddeffhikr§œ“””š—š¡––›¢¡¨žœ¥§¢¥œ ¡›™¯®®¯²¡¥£®«§¢µ°²²¬©¯³§º³¦¶ ¢Ÿœ£¡­£¢ª¶«££¦ž¥¦£–™—™› š—œœ­¡«§££¦­«²³ªµ°²«³¹´¯ª¯²²³·³®©­®²¸±º¶º½À¸³±”…yuf_f^[YVSZUK[QLIEHKIB=?AA@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½¸½¿¶¾¼¿³¥£˜¥±Âµ¶½­´¸ÁÌÈƿŶÁÀÇηÀĽ³¹¹³¿¶±¹»­²´¯Ÿš¤ª ”šxƒ„xoqtqhechdc\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXWVWadecdeddhjv ›“““––ž–˜“— ¡œ–¡¡©¤ŸŸ©››«§¯°«œ£¤¸ª¡ ®¨¶ª§§­±¤¸°¤· £œ™™ª§¡š¬¹¯¢¡¤œ¢  “”¡”––›˜˜–—œ•Ÿ©ž©¤¢£ªª±­¨´¬ª§­³°¥«®³±°°¯¯§¨§²®±´¯¼´º¸®£”zve_aVYXSRSKM^LPLGHLKE=@>=B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾·½®§§¢ª»À½À¹®´¸ÁÌÇÅÂýŸÈ̲ÁÂÁ®¼»µ»¼µ¹¹°¯°ªœ™¡©”‘Š‹€€|wqilrtphhedfa\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWWV[bcbbcbbcfi•’”‹‘““š˜œ•–œŸœŸ–  §¦¤¦§Ÿ ¦ ª¯¦Ÿ¢£·¨¡¡¢¨³¢¥¨¥°¥±®¬µž¡–•©¡¢”­±±Ÿ££žž˜›“‹¡”‘“˜˜“—˜˜—ž§›§¢¢š¤¥¥«¤¥°§¥£«¬­¦¨®¯¯«¨ªª³¥¦«¯´±®¼¶±¯¯ ’zwrea\[]XNLQHRaMVPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8847763321./2556;:8;7876<;:;;A8x»»±µ½°»±·¬ž¥¦¬·»¼Áź±¹µÄÉÉÀÃÆÅǶÅijÁ¿Å«··½¶½º»µ²«­¨™˜Ÿ£‹‰t‰ˆ~vncafihfgifil`]\[ZZZZ\]\[\^_\ZZ[YYY[WUXWTTVURTRU``_`a_aacdi€’’ˆ“‘’œ”•–¤™ — ¥¢­¦¥¥£¤£ª«¥šŸ¥±ª ¡ž¥«ž¨¢Ÿ®¬©©®­¢¢¢•—¢›œ«©°œŸ¢ŸŸ—˜“Šž‘’“–˜˜“œ¡£¤¡¢• ¢¥¦›£«¥¢¤«¤«®¥®²©¦¥¦¦´¦©¨­³µ´¹º°ª¬žŒrpo`[WVURFPNHZ\PRITKSLEGJD8;;=<9667:9;:976977:;:=<<6;<8>598:88659:;<97?<9578452121..1426:8698598989;9@9{µ´¬´»²°«²­¨§¯¹¹³ÀȺµÀ¯ÅÈ̺ÁÊÌȵɼ±½ÃÉ­±¸Áµ¼À¼´µª¬¦•™››ˆrˆƒ{tiijlgjlmkjle]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURRNQY]\]]^___bdmƒ…Ž™“”’œš¢œ›¡©©«¨¬§©¦¤™¥¯¥•š¥¯© œ™›¡ž¯šœ«´ ¥¦Ÿ£¤¡”“›––’©ª­š ¡¡›”Œ™ŽŒ‘Œ’–•¢ ¤œ£•› £¡—¢¨££¨« «¯¤­·¦£¤¢¬­ª¨«¯³·²½µ³«¯˜…tsh[XYSUREXLQ[XMTNPLQRINJC=??A?=75799<<977:79:;<=>;7;;:=67:;8976989:6:=99577570141-+/434988::8::748=8?9~³­§³·¯¨§¯®›©¨¬·¶«¼Ê»¶¿¬ËÆŸÁÎÏȳĺ·»Âȱ­¸¿·¼½»³µ¦© –—˜–‡zt€vwnmhmmmpggifd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUSSNPQYZZZ]]\^_ae}‹€Š}Š‰’–‘—™¢ › «ª¦¯¬¨±¥©š ­¡•–¥¨§˜šž®—™¨«™Ÿ”¥¡Ÿ’‘’‘“•¨«¥š™™žž–ŽŒ‹“†‰ƒ‹’•‘ ž¡¤™–Ÿ•š¡¢ž”›¥¦¨¨¨ ±°¦±½¨Ÿ£¬´ª®§°µ°¹µÀ±®±«‘~rsbVTVNRJGVPRRLLWMJMORGMKACFDD>A75889;9:7::7<=:;@>:9;9:?759:9876958779;85576761320-*.102877;99;8948;8@8³¬¦±·ª¥¢±«ª§©²°¤¶Æ´¹º³ÊŹºÁËÐʱ¶·¼½Áñ°±·­´´»³´¢£——”ƒ€vkglnqnrkpkdege^ZYZYZZZZZZZ\\]\ZXXXYYWXWUUTRSUSVURNNNRWXYYYY\\]ajy~t‡Œ†‰—‰””˜›˜ž©› «¦¦¬ž¨š¡¦œ“Ÿ£š——…„’›¤•£–––ˆ¢››“‹ŽŠš¥§œ••—›‘’‡”Ž‹Œ€‹’’’ š¡¢–”˜™•¢¦™™¤¦©¦¡ ´²§²¸¡œ¢¶¬©­¤²²¦µ¼µ«¬±£‰ysn]NQQLODNNNPKFNNJJNNQIMJAHLHHC>858889:;69:68;99><8:>9;?8789:886857688974577820301+)-/12876:999984988A7w¶¦¤¶°¥§¤ª¥ ©¦¤³ª¢²Ãµµ²³ÆƶºÃÊÌƳ¬¹½´¸À¯­©°ž¦®º¯­Ÿ™š•”‡{ƒn__frpvqinieghj_XXXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQMMKLSWWVXXXX[]anquoƒ‡‡ƒŽŠ”‘“¡šœ£¢¤™¥—¢œ•ˆ™šŒsƒ~Ž—–†‘š”ŽŽ{™Œ‚‰Š˜ £ž“˜–…Žƒ”~~tŠz‡“›šš’–Ž££Ž‰š ¡¤¤›¢´¯¬°¬Ÿ˜¥¸¦¦±¡°®œ°¼ª©¯ª™ƒwscVMROPMCSNLPMBPQHINRMHJJDKMFKK=749888;;69;7:<9::;79?9>@79:<89764445874312585/0102)(,-02764789::65:87A7x·¡£´©¦¥¨£¦¥¦¦¦³§¥´Á¸°´°ÉÄ·¹ÁÎƽ³¬ºÁ¬­Ã­¨¢¦’¦¶­£ •–’}w~fWV_gfighnciigb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTRMMJHNSSSTUUVY[]jjqk~„{sNXr‚—†œ—‹”‘Ÿ˜•”–•–Š€”‰_;Vo|Œ”ŠŒ’Œ††sŠ…—y{†“”ƒ•Ž‘ƒ†}“xqp†Œ}‰‘—š˜“‹ŠˆŸ˜‡ˆ–žš¡ —§®©­¨¨ž–­³¢¦®™¬«˜¨´£©­£“sn_[NSRWLDTJPMLFNOIELQMKOJIMPFII=7599999:7:;:>>8:==7:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9y· £®¡¦¦ª ¦©§£©¯¨§´Â¹°µ°Ç·³½Ï¿¹¯®µÂ§ªÅª£˜ƒ”œ±¢š˜†”‹‡}su]PLQUYZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MORMKHFHNQQMORTVXZ`lngzsPB?•’‘}ˆ•Œ„Š›Ž–•Š’ˆ†•‡y‰`JQnx‹’„~„‹…n”xuvx„špQˆŠ†|~x”vhw†ˆ~Š‰–‹Ž‘’–Œ„Šˆ•„›‚„’š–ž”¤£¨©¥¤ž›°ª¡¤¤‘¦©–¢ªœ¢¦¨‰vmf^[HQQSMIUMRILKOIHFJNLMTKQPOFIC=769:8:;;8:;8>?99>=8;<6;;478;6775344696/3/.125221/,')+*,4833989:99::::?9w¶œ£§Ÿ¡¯¡§¨¥§¨¯¬ªµ¼¶¸¶³Á»¶¨¹È¸¶¨¨µ¶ª²½¦ž•‰“¨–•Š~Žƒ‚}wpoXMKMMNLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDDINOhYNQSTUZnƒru}ih\T‰”ˆt~†|…Œ“‚’š‹{†€v€xsovqtŽŽz~Š«…y{hv{Žprmx‹’xz€{€vsr’xgu„„„…|•ŠˆŠŠ€„‹€”„|€˜”œ–‘Ÿ©žŸ  ©¥ž˜§¤’  –žŸ¤sha]\JWPRGKXROJLMRJJJLPHLQLRTMEHB<77;99>=:;<98@?::>=7==79937785675252472/2.,//200/-+(().12721987:8775:<;7v®™£¡˜Ÿ´©¯ª¥­«°±ª½´²¼¸¶º´±Ÿ·º²ª¬©¨²°¡š‘”€œŽ‘~v†x|vooiXKHIHGEHHPTTTWWSTUUUVWWWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQQSV^t‚{xfvŒ–˜Ž|gyvx€‰}„˜’q‡|w{ok~­}t‹{†’|ufv|†logs|‰Œ‡€lyq}qmvqhq~ŽpC‹…‚ƒ…~wwzŒ†}Œ{u}Ž’˜‹’š›£–™œšž¡œ–‹¥šŽ—Ž–˜xomfcZXXUQJSUTOPNPVKNKOOJROINPLFD<<79;::?=9<:99??;8;=7<9999266856633611224.,,-..-0-+*''*.1362/876966527995y¦— ž–¡¦°¬®«¨©±¯±«¼¸¬»¾¸³¬§›°§¬›–¥©¤ ˜™…’yˆŽ‹Šuq{mupjmjXKFGEA@CDHLLMQRPQSTTTUVVWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNOQTX]eprlˆ§ªÀ~tyb{xo|y‰z}‹†omŒ’ytyjj€‚q–‘‹~–€I’˜nhx~‚midly…’†ksl|nr|†inps‰„†{~{vott†‚yyp|ŽŒŠ“ƒ–—˜š’–—™—–Œƒ‰ž’‹’†–€ojonoXVXTRQYORTTRXUMNHMJMOKCINGF@:99;99:><9<;::=>:8:<9?868727565541432/024*+**-.+-*(*(',-1250,5567485HA895w™‘›™šŸ¥¬°£­ª¨µ¯®¬´¿«¼Ã¿¥¢š•¤˜ž„‹”¡¡™™‘“‹sŽz€†Œ†totkpldljYNDFC@<>>AFFGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_IMOORWZQY\_§‡ašisye~omz‹‰v‚ˆ†tlš’ts|jjMy…“‰„Žg1v†sl~}ƒtfeu„„…€filukq€|hqq|n“|t~}qpnum‚wyujy‰‚ˆ‰ƒ–’’‹‘””Ž—€yˆ—ˆ†Š†€ˆwkkoheXRZWYY[MPUVYXNIHEJJHGC@GECG=998;9:9<:9;:::@<9:<98>787715234533645031.**+),,++)(+'),,226,,4775478iO8;5n’ˆš‘™–£¨­ž±ž§º¯«²°Â±»Ãǚ–”™‹Ž…z„˜”Œ†q‡‚t‡Œ†yprpoodpf_TFIC?<;9:?@ADCEGILOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOPQVLAIQIb¯² q{xl}lqƒ‚…z„††yr¡•tx€su”‡5q¨Ž¡¡„¢…vp‡|‡|tŒ®‰€hgbjnrmp‚uioXupŽ›’wlz}mrnp€{svnbvƒ†€…ŠŠ‰‘‹‘‹‹ŽƒuxŠŽ€~ƒ€}Ž{sqqm`[]^[YX`_RN[ZXWLHJFJG?CABH?CD=;97=;:;;9:99;:?<88=:8;66651121253474531./,,+)*))***)(*)+/3DM2166643<vR7=7b’’ˆ–‘¤§Ÿ¯•¥´©®±®Á²»ÁŖŒ”€ˆ|n’‰ƒŠ‡†u‚„l•ˆˆ{txxlwnwci^JPG>?6449;;;=>@BEHLLLLNPQRTUVWXZXVUTSPLE<5*K[@-gI94/?’ƒ©®_HLMNPL7CMRSDJ†v€||v~lvˆˆ|~…ƒŒ~u¢™y~†„™„šœa†ªŸ‹ƒzwˆ~‰‰Žs‹—„z]dqtz|wŠmhjbyo…‚znwt„zptyxkni]v†|‡|‡‡ŽŠ’—ƒ…Œ†}q„„}uw{|‰wpstfg`[[^S[g^WPTX[UGJJDKG?F@DC>AA=;97<;;=<::99;;=>79>9985653244004645554-,)+('''&(())((+++/00Uq=23331E~W4=9\ŒxŠ€”Œ‘œŸ¦‘ ª ±¨¯À²»Åº–Ž‘”‡{†vkŒ‘‚}Š„Œxƒ€s „Š}|p€~zgvkRWL@E211366688:<>AEGFGJKMOQQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMORLKT]YRJh„ˆ{‰y|q|Œz}‰‡~—‡v¡™ˆ‡’”¥¬ªH†®¯¯‹€“‹‚‹‚„’©‡€˜˜Š›tm|†‡}Žhghyn…‡‚…q„†Gl€wryvhmk_v}‚ˆ‡„‹y”œ‰‹ˆ‘zu‹v|xmow~€ttrl[^^[ccXge[TOPVYPDLKFNICFCC@@CA=978:::;;:888::?>6;>7595773344236656768;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|}‰…‡‘Ž–—’— ž­¡¦¸¯³½³—’‹˜‹}tp~‰’~}Œ‚’”}†~†¤‡ˆ‚ˆ…x‡ˆ~s„x_cWKB60./23124668:=>?BEGHJMNQSTUTTVUSQOGC?80,#‡[>?84.]–ps£UFIKMNPW`XpY\^i“‡•€„‚…‘“~…ˆ‘š•‚¡¡˜•››¦­“š»±§»Ç苌¡¥”Š‘|qƒžŸ‘œv†…‹‡ihp„t‡„Šq†‚w‡{v…}nvuf”Ž†‰ˆ‡ˆ‡ «¢–‰Ž—z‚ˆyyogkx~{~tle^[[^j]af`ZOKNWRQIPJDNGCJDBADDA<:87=<:<:88778:==8<=68756623444576867<BB?<8:>CQ^e\G2'&,,--.1(?‹[.310Oƒ_4?;nupfwƒ{€ŒŽŠš›¤¡¬¦«¯°—‘‘„¡”„xwŒ”|~’…’•Š€’›Žƒ€ŒŠ‚‰ƒŠ€mpj]B@4--//..02234779;=?BDHINQRSRSSTRPOHDB<87/9D><<63.l“—MPIIKKKNV_cggmu›š’“‹Žšˆ“‹  ’£ª¥£¬“©¶¢¨Á®ǯxº”š|¡ž™„“…‚Ž¢Ÿ“˜’„Š…™‘–lpuŠŒ‚–ŒŽw„qm…Š–‘ƒ…ˆqˆ •†’‰Ž–¤µ©›”¢ƒ‡“ƒ}kjj|‚tb^d`[gk]lk^WKGNRQMLLFIPCDMFACEFB=997=<:;:987767;:6=:785456344566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYo‚ou†qv’†~—–š”žžœ§ ©–“˜žge¤š~„’‘y’ˆ‘’}Š„˜’‚€€‹Œ‰…‡…‰…xx~gMR>/..,/.-/000212467;?CENPRTPPQSQNPIED>;<:CF?><752<?R5HHHLLMNR^oŠ|s} ›§¥¢™¡—¢”œž¨ž¨«Ÿ¨¬©ª¶—«¿«¶ÈÈ·ÉÑϾ› pi«©Ÿ„“’…œ¡š›™§‘‘ˆ•¢››xz~”˜’¡“——”ž{w•’«²ˆ—Ÿ|”ž›Ž’•˜£¢¦¶°‘™¨‡–ˆlss}€}ri`]b`bhd`gf[REJKPOIILFFMCHLFGDBGEA:85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Ppt`m}awŽ}{”ŽŽŠŸ’—ž–›ª˜žªBD}‡‰‡˜x‚ŠŽ|Š†Ž‚€‰‹Š„’…ƒ†‰€†v^bP460-1/,.00//..0015>ABMQRSQRSTRNSLEE@<>=GG@A@8662<9;FHGIJNOQYm…w•Š£§ª´½¸¤­¬¬§¨´«°¶²²­»±³½œ³Ã«ºÉ˷ÿ¸¥¢°³¬­ª£‹–˜…¦¦ £—¦™¢«¨¥ˆ…”¤¡ «¡¤©›°‹•£¦·º› £°’¢¢ž£¡«¯¬²µ¢”¤ªˆ™‰’‰•zz}…hah\ec^dd^fg_ZOCIHSNFHLFJGFFHAKFCFFA;87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLhcWioXz…v“…‡‚›ƒ’Œ’Úȝ–sV—ˆˆœ|†ŒŽŠŠz‡‚‡Žƒ…Œ…†‡’†‚„‰†ˆ‡‡pna@E64<2/110-,+-1.-4?CAMUQRSUUVUN[PGGD<>>FHCEA7;<5C;=FKIGHROPW’ „®£³ª²ÀÇê³Å¶¬³¿³¸¾¶¿´Á¶»º£¸Å¨¶Éǵ¾¹µ¨£´­°±›™’šŸˆ§¯«¥”vŸ¤—¡¬²´™–ª®¨®¶»²º¬¯µ¢±«±µ»·´®´ §¨£§š©¯­²¹·¸§›¶¨Œ¤Ž‘’Ÿ†x‚ƒvZbeWfbbd``f`[TIDDLUQHIJDIGEA@@KDBMG<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AFWQJL[ZQbcWyuq”}„†“u…€Œ{¿»£¼‚´”“›„ˆ’‰ˆy†€Œ’Œ‡…Ž‰Ž†€†ˆ…Š‡‘zxn]V@EN<6:46AB764//6CHCQ[OQUWU\VO^UIKJA@?GKFFD;>@7D7?BJJEFWTP^¤­£±´Ã¶¸ÁÌɶ»Ä½³³À¶¸Áµ¾¯·t±³¥ºÄ¤°Æ¹±³±´¨¤µ¶ª± ¢–›¢’¥°®¦­¬§¤˜ ¬´»¢¨²ºµ¼¿Ì¿ÅŽ½³Â·º¸¾·º·¹¬¬°¦±ª­½°¼»Â¬™º¨“­——ª‰}‚}kWdbYkejfW\cYVSIGFLQGCHIAHD>?BBK@@MD99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FRLALRWSYUZvjp~Ž„€ƒnzsx‡b¹¡™£‰””–’”“–’‡†{†•Š€„Šz|Š‡†}ŠƒŠƒ•}wzueO\dGEL;Qca[^SF?;HPEZcQRYXZgYT``MSPEA?IKHEEA@C<E6B>HGJLSZT]“®¸µº¸È¿º½ÉÌ»¼À»·µ»º¶½´º±Æ`u²¤±šž«½ª¥¨««¤¢²µ «§Ÿ•–Ÿ˜Ÿ®¥§¦¥Ÿ£”£§±´§²³½¶Á¾ÓÉÉÓÇÂÅÌÂÊÃÀ¾½¿»¼·´¯¸·¶Ã¹Å½ÂÈ°ž¹©¡«Ž¤§¶ˆs`cb^Xb`igRX`VQUIEENK@>GD=JA=B@=F>;H@796379>489:57045/26389373426?8@>GKRTSQPOQQPJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKE@IMPRKQ]glkp…slrss‡ÕÀµ™ •˜™‘Ž—‘––Ž†‡}†ƒŒ–‹~ƒ€ƒx{‹ƒ‡|‹yŠ‚—~t}zkepuY]\Pedb`ed][XW\MdmURmm_n_XgdUYUJDBKKHFHHHGAI9D?HKTTV\Z[“¹À¸½·ÆÀ»¹Êʺ¶¹µ¸¹²·µ´®¶¶™du¨œ­p^¢¬œ˜ ¢›¤ž«¥”ŸŸ”Ž–˜—§Ÿ¥Ÿžš™ƒ¤¬¥ª°­¸°½¹ÔÑÎÖÐÉÌÒÌÏÎÊÆ¿¿ÂʽÁ¼ÁÀÄÄÅʾÈ㤻°´¯š«¸»™€{m_a]Y^aZccP[`SPKCAEFE<@E>AHA@D=:E>=J?47535;=468977022/24169775554D3ELM>51/006:477@IOI;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODQ\Yh_o—’”nlouu‡³¬¡ Ÿ‹™œ™Œ•‘›’…ŠŠ~ˆ‡‹‹ˆ|„s{Šƒ…{‰t‰‡•s{ykmu{hreilifjih`fiilZms–­¤¼ˆ‡g[oh]ZZTHKNOJKPKSQHLAJGJO_^bfia—·Ç°¸²»½µ±ÄƵ°¸°¯»«²±§«·«µ§š§šNšŒŽŸ–‘¦˜¥•Š““‰‰‘‘›¡—š•–‡žš§›¬¯¨°§´´ÔÔÔÖÒËÏÔÕÍÓÏÍÅÂÉпÊÉÊÉÑÇÌÍÂÐÒ¸¯Ã¼Ä¹¥¶ºÃ¢ƒpe^^^Y`WYfZQ]WOPBBHEBH;AC>AG??A8;D>@H=46655;:687654/10146278875367C5B8?-0-1349=97,.,1;FK=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYSeVs˜‚hqoyyƒ ªž¥–Œš›—‹•‘šŽ}‰‹…ŠŠŠ‡|„‚pˆ†{‡rƒ‘‹}qxukqx~q{nxslhpmcjmpxiw|~Ë¿Áߧncxnc[a`JPRUNY^P]\NPNTQUT\nmv‚q–­¸¬´¦¯¶ª¬¼À°«´¦¤¸¦«® «´£Ž±­š—˜Œ‘“‘„Ž›¦‘œ‰ƒ‹„Š‰„‹ƒ”•——“œ‘œ˜™™Ÿž«¬¤§¢¬­ÏÒÕÑÍËÒÓÔÐÔÑÎÈÃÔÑÇÍÒÓÓ×ÌÑÑÅÒÖÅÀÎÇǨ¾·Ïžzpf_c]W`S]ZPQTPOH>@FABE<@B>ED>??:==<<JA45465<888664412/03526768533;=<E=@11+/249>5901022-2DN3)/3.32=N238C}_2A†tD:==I>@CFH<VRMN[u†…Šwlwp}~¡žž¡‹Œ˜““Œ‹“–„y…‹Š‡‘‡‚{r~€‡z„u…“ˆovrks||w{swqj€sripqzyrz¾Ëš~Œ²„vr„vhak]CZZ[VecXdjSX]]`d^cxz~‹˜©£¤¡Ÿ ¨¥ª°¸ª¥³£¡­¡£­¡§±Ÿ‰¦š“’‘‰‘ˆ”‰j”¢Œ™„€…~‘ƒƒ“–­‹••šŽ†’‘ž—§°¡ ¡¥¤¨ÈÎÏÈÂËÑÔÑÔÓÎÓÍÆÖÒÌÔØÖÖØÔ×ÕÉÔÚÍÉ××ÑʬÃÃ̌tpda`XTYT\PKGJJJ@;:;DAD<BC>GB>BB;<9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/--;R017/532FD28>nb5=tM99@I<AD?A;PLFKYp€u}hsxr‚‰€•”…‹•‰ŠˆŽ‡xƒ”˜Šˆˆ‹‰~‚xs{}ƒ‡wz‡‘–€ƒnwpmuvx}t…|yl‡vtn}v„ux|µŒ;AŠÅ¥~Œ|ieWICfcecgjdnx[^fhknin€ƒˆ‘‹œ —˜ž££¦±££³Ÿ¡¥ © £±œ†ž’’’ŠŽ‹†ƒ„~œ›Œ‚„…z”~‚©•£Œ‘Š—’‹}—Šš’«³˜šœ¨œ§½Ãƹ¶ÆÍÒÐÒÐÌÒËÉÔÎÐÕÚ××ØÔÙØÍØÛÎÉÙÚÑÖ¾ËÌ´ywpf^[SVR[VFGJIEE=:7:@@B:GD?DCADB;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?1*(.BS39254/7K75<`bA<svV87AH:?C><9QECJTknnpbpqt†|—‘‹~‡’ƒ‰†…‰‚‡|x…––ˆƒ‡…†z„yqz{„†uz…Žy‹p|oozq{qƒ‡€nŽzuw}|‚u~{†‡¯sX©Â¶‘‚pnb=^hrpqpnxvehoruxqzŒ‡Ž“‘›•Ÿ•‡Œ“› ›žªŸ ¬œ¡š˜Ÿ¦žŸ«™‹šŒ‘„}ˆ‡ƒ…‹Ž ™“ˆƒ‡~m™y„˜†ˆ“Œ”Œ†|›ˆ”®ª”•˜Ÿ™§®µ½©­¾ÇËÉÉÌËÐÉÃÒÊÔ×Ø×Ø×ÕÛ×ÓÙÛÕÐÛÚÑÖÈÔ˕{}ji\[PST^HCFIH>A>=7:=?;=G=?AAADA>>:86DB755479.566435542323646553457EBDCEB56<FNSM[nfcnskaV>,4LG865434BF4=W_hLux^8;?F<<B<::D?CGRk_mdbfkv€ˆq‘š€z€~‚‚„ƒ||„˜Ž‡‹~††€w‚yo{{‡‚tz’ž vŽu‚tu}t€„oo’…t|€„zv†{ˆ·Å¤Áɸ‚–›wpeNfczw†¢Šxyv{ƒ{„vm“–”•—ƒ‰Ž–™—–¥œ—Ÿ–ž’’—£™«•‰‘‚Œ…ˆˆ†‘ž›™‰…Œ†—zˆˆŸ—ˆŠ‹‚}¡‰‹¼¡˜“—šœ©¦¥®Ÿ¨¶¿ÀÀ¹ÇÉÍÎÅÍÉÑÖÕÕÙÕ×ÛÔ×ÙÚÛ×ÛÚÚØÎÜƇ}{ikgaTXUUMLDNC;==<8:<>9=@6=?@<?><9867DA6455=80665547745613855564557HH=DJE7925;H>;::7IP]ZRUXK9T>;95327I8=NYMHxxd5=>C==@:6:>>@EQ_Yea][htzyl‰’wvzŠ|~€~|„{~‚‘‰„…z„‡zu}tm|}†~s~’‘žƒ‘|†~xŽ}xŠŠn‚š€t™†}ˆ„{}z¨ŽÃ¡½Œœ£}‰„}‰r‹Š~s¦šœ˜“…{Žˆ„hGq ¤Œ‹’…‰Š’•š“”–Œ‹•Ÿœ” ”‘Š~ŽŽ‹„‰’–šžŸ‰Œ”’‘‚‹¥™ˆ„ƒ†„€¥‡‹‹¸˜‘”–¢§¡ž£¯·ºµ¬ÀÅÊÐÈÇÌÏÓÒÒØÒÕ×À×ØÙÛØÚÚÙÙ×Û¸z{zmkgX`\SPOICLB=<>99::99;=6?>><=9:;;37D@8378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWN<MTHN?96333>C;[X>5YypZ<<A<=>8689?=DRSRX_VXfmmmiŠqsyŠ{z|{‡{|{‹‡~uƒ…yrzsm€~„~w…›¡šž”’€Œˆ˜‡€›’n‡¨…z ‹|‘‚ˆ„›}šŠŒ£¢ ¤® ‹‘‹…Œ“†Wr­‹Ÿ«›ƒ˜›Ž\‚¢‘‚ŒŸ“”Œ†ˆŒ’“Œ”””‹‰‡–›•–‹’“…€‹ˆ’ŠŠ–™¢£†“– Š‰ˆœƒˆ€ƒˆ…¤†Œ³˜’”—¡¡ž™’œ¨²¹¬¦½ÂÇÎÇÆÏÌÐÌÎ×ÐÑÔ®ÖÕØÚØÚÚ×ÖÙٟqvih_^XTWXC@HC>>>:49:;7:;:3;;?=>7;9:1:H>:37=@50677255?65;55858:57735HR7GOK994=EJB>1FCLB98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:;@;BQKKSYPTcbymb~’ƒomx‹xyz|†|{w†„sp…‚zuvvt„ƒ…}~’¦£Ÿ¥¢–Š”—‹Š¨—rŠ±„§’„™“„™Œ¢•Ÿ˜“‰šž£’©¯Ÿ•Žˆ–Œn·…šÄȲ›¡¥›œ˜–²‘d¤ÍǕŽ†‡‰’“”‰…Š‰…–™›”“†”—„‹™ˆª——££ˆ™Ÿ–šˆŽ‡——Š„Žˆ¥‰“©š—“–™¡™Ÿ™“›£³´¦£¼Á¾ÈÅÅÉÈÉÂÊÓÍÍÔ©ÒÑÖÖÖØÚÔÓÚ΃sie`__OJU[BAFC;A=837;<:8=649:<:82?9:2:I:=67BC32:96264>=4;>6949;57944KQ<JQK9A7BGI@64JELF><88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBcFu‚Ž}|m~ˆxz~z‚~vv€‚{ln‹y|xx|„‡‹~‹£³¨£«²¡–§ ¥¤–•®¢ƒ·•’³™¡ ‹¤›¯¢¤˜§–©™­¯¤—••”‹˜š– ÀŽ£É¸«š¢¥­™‘›œ²†…¨¢œ˜…ˆ‰Ž•‹“‡†‡ˆ“˜”Œ‹““†”˜†ƒ‘œt‘™²–—¤¡ˆœ™“Š‹—š‰Š–Ž†}Œ™ŸŠœš™“˜˜Ÿ” •Ÿ›¡²®£¥·¾´ÅÇĽÃÿÆÎÊÉÒ§ÎÍÓÒÐÖØÒÏØ»s{w^bWbXPHJOEBCD5>:76:?;<7=42669774=5<5<L<>;<BA75<;4277?@6??784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=89567=:JFDGN[\YJga;H„‹z{m…†y|„x€…}px}}|osz}{x†‹‰…„’¨»­¨²½¯¥®³³¨£¢°¬Ššµž¢¸¥•¬¤—©­·¦¤£Ÿ™©˜ª¤¯°©š™œ”•‘˜ —™»»­É i¶¸«°•˜Ÿ¢«’—½£^ª²‚‰Š•‡‘|Ž}ƒ†””ˆ‡’–‹•‹—™’š³–•«ž‹›”’’Œ˜›Š’žŒ‰•Ÿ¢•Ž˜š“›˜ž”¡ ”œœ¥¯¨¢¥³¸«ÂÈĵ»½»ÅÈÈÂÑ¡ÆÉÍÍÄÖÖÐËÓ¢q|j^\U`RPFD>=CAB8?874>F<<6<35355453B3::BM:A;AHB;:@<746<B9?@B874::6>=47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPeHb`cpJ@‹Š~€r†‡|‰u‚Š‚~m}}|pw‡w‡{Œ†Œš«ÂÀ°¾Æ»²´Á¼´­«³¶Œ¨²®®½ª›»¤¨­¹·«¦¦¢¡££©¯²±ªœ¤˜›˜—ž¢¥¥’£¹®¨À»¬­²¹¥¤§}ˆ†œ­½°ƒ‹Œ‹ƒƒ‘z‡Žœˆˆ—‹•—”š–œ§š±š‘«Ž™’Ž•–—‘ ‘ˆ•›¤¬”–”œž” ž›˜ ¡”šž¨§¤¡£°²¦ÁÆ𰻶ÅÄþͧÇÃÇüÕÐÍÄʉutd^\a\OKBL@EF>A?B;:4>A==5=6>333242A17@BN>G@CNCA=C=;86CC5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GE?CF\gG`igZ][“ŒŒˆ{‡‹†ƒŒu†Šn~|‚q~z•z’””˜‘“•§´ÆÉÀÂÌÁùȼº¯«¹»—²¶º³À®¥À¤ª°»»ª®«¢¢ž§«®µ°ª› ªœ¢œ•ž°´§‹¢ººµÁ»«¨œ²¤¤¨”„Ž©ÃĤ‚‹Ž‡ˆ„†•”zƒŒ‘‘¡ŒŒ”‘‰˜ —’™”—¦ ®ŒªœŽ•’‘••Ž•‘¡”†—Ÿ ³ž”›” ¡™¤Ÿš œ ”˜ž¦¤¦§¤¯­¥¿Ä®©·µÉþ¶Î²Å¾Ã¼³ÑÊÈÁµvzn^Z]lTNICLJJI@A=CD<5AD;:3=8B332262A05IEM>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBg\Me\fTcj™–‰‹ˆ’†‰y†“r€|~w‡‚z¡–¨šš˜º¾ÈÈÊÂÒÉÊÂͼÁ³­»¾§º¿¾¼Ã·¬Á©¬³»½ª°©¤¥£«®´®¶µ Ÿ®Ÿ¦¢˜£´½©›¨¼À£¶¶¯«’¯¬ª«–†š©¦¥‘‚Œ“¥•‰€uŠ’y…‘žŸ“Ž”‹”£™—›””£ž©Ÿ‘¥šŒ•–ˆ}•’’£š• ¢œµ¦‘Ÿ—¥¤£¥žž¦˜ž•—›¥£©¨¢²¬¨»Àį¥³·ÌÀ¹®Ã³»¾Á¸­ÂÂÁÀ™p{cZX]\MLMIGDCHBBACK:4DH:;4<7E.12352B26SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQF7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>kI_XaZdeVžŽ—Žž’‰Š‰Ÿ’„x…•~ˆŠ€• ™®§£˜Â½ÈÄÈÆÓÍÎÍ˼·°º¼´¼Ê¼ÃÁ¶¶»­³¿¹¼­¯¨ ©§¶­®©²·šž­¢¨¡«·¸©¥¯¾Ä±½¹³§©³³­®–•¥¬§ ‘Ž’±Å§•|‘•}‡‘™ª™˜“““•“¥ž“™“¡£¢œ˜Ÿ™‹ŒžˆZ——’–¥šf˜£Ÿ³¥–£–¬­«§›Ÿ§˜™–™•¡¤¨¦ž¶«©º¼Ãµ¥´¶ËÁ¸ª¶¬³º¸®¨¸º½¸ƒnp\ZVWOGKSMK?AHEDGFG85FM;>7>AJ.32025B55PWN;LFKRLOGGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|hW;=@BFBrFiIRebLF¦”œ–¡—©–Œƒ‡¥’ˆ‡‚œ„ƒ•‘”Žš¢Ÿ¯¾®¡Ç½ÅÄÇÇÎÎÎÒʾ»¶±º»¼¾Î¶Ä½·¸·²²µ³¸²«¦œ««¸ª©§¯°—£®¤§¤¥´À°ª¬³¾Â¹À¹³§¸³·³®•¥­®®¤‹“•¡sÁ™}–™„Ž–š‹±•š™•’“™š¦£• ›–š¨œ›¡ ™‹Œ–`J–œš”š¥—T–°Ÿ¯œŸ¥”¯¯­¥š¡¦”“™™Ž §¢™´©ª³½¼»«°²ÇÀ¸¦««­±±£¡²²´¤rpg^\PRMEPPPQ;HKIFHAC>9KT?A:=EM07544:B34NWO<JKNUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@CAF3>58JKCA=C;4EA:A?>H@5*B52,>c]g:35tde@R7&#3}iX;:BC@=REWRsbWFH«—™Ÿ¡©¯˜—‡‹§–Žˆ’…Ÿˆ„œ—ž ›£¥µÉ´©Æ»ÃÄÈÊÈÇÌÎǾº³¯¹¸ÀÁ͵ȺÀ¹µº±¯¯²´§£›ª´´ª©¦®¬™¤®¥¥©­º¿¨«¶¶¾Á¿¾¸³²Â¯·½«£®´¬¸¥ˆ›—¦›v¾ „˜œŽ“™š‹¯–¡œ›—•› ¡©ž¨ ™šª™¡§ž—‘ƒnv“¢š•¢Ÿ®²£«•©ª˜«®¥¤Ÿ¥©’’™›ˆ”œ¢ž–°§©«º·¾³²®¾¹¶Ÿ£§¨¥§œœ¬©©ehc`SLMGHNJVL=MDMIJACD<QU<AABDO18=77?B75UXN?HNQXRPQTJQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW;:=..SaMVHe^HF¬”œ¡Ÿ»¯˜”ž‹“ª›‘’“‰«‡¢žŒ¤¬”££¶Ç½´ÁºÂÃÈÉÅÂÎÈÁ½¹²¯¹´ÀÂʶƱÀ¼µº«¨­¬¯£¢˜ª´º¦©¦¬ª¨¯§¤««¾»¨¬¼³·½Æ¼¶µ¸À°½¿³©´¶«¾¤¢—‘¢Ÿ¼Ÿ‰™ ™–ž·Ÿ©œ¥£›œ¢š¨¥³¡›¥œ¨ªž™•”š‹—‰¤¢”œ¢Ÿ µ¯¥¥“±«š¬¬Ÿž¤£©’•• ƒžŸœ•©¥¢¡´µºµ­¨µ²³žœ¢¦š—•™ª¡žwb^`^KIGHMQIMEFFBRJHADGAVSDH<AGQ1;B7:BF79\YKALPTUSMWRNUJD@JJNO9C?5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-1:h]FDCœpbGE¨—¤žžÃ­›—¥—™©œ–ššª–•¨¦•­¬™¡ª¶ÄÁ¼¿¸ÁÃÁÈľÍÆ»¾¹²°¸³¿Ãȵ¿¯¼·¹·§¤ª«¬  šªªÄ¢¥¨¬¦ž¬¯¬¢ª¨¾¸¦¬½°·¶Ç¶´¹¸¾°¾Á¶´²´¯¾£–£–“›”­Ÿ¡¢¥££Ÿ¾¥©©¬¡›¦Ÿ½¢˜¤ž¢©«¡–•ž“Ÿ‡…“ž¤ µ¬¥œ–²§™°¨Ÿšªž ™•Ÿ…Ž¡š›’¥¤š˜¬±¶±ª¥©­¬œ™ ¡’Ž•©Ÿ”idZa]PJIKOMHECI@=OH@;GIH[ROK=HNU4BF9>HG5Cb[KCNRUWVQXTRUH@8QQPM:G@4CHQSIC;C>GVKC@O>K<06;GF>;FA56?9:?9;15D0-,0Mv\4KZ5,MnW<-=)#zbQ5CKQ9oRF<KxfcXM¢š£›žÅ¬¡Ÿ¬­Ÿ’£ž–¤ §ª¬—¶°£ª³¶Å½À¶À¼É¾Êȶ¸µ´°³´·Áƶ¾°¸´º¶ §­ª«žŸ¥¤Á¥ ª® ¤©­¯¢¦§½µ¥±»·¶µÃ²³·º¾±ÃÀ¸¸­³´µ¢œ¤•‘“ ­ ˜¡©¨«¢šÃ­©ž¬®››ž™¦ ½¡¤˜«««¦¡™šŸ’ž‰ŽW•ž¦¡ ¸ª§“˜¶£Ÿ³¢ ›¯—Ÿ™”‚ —–¢¤•¦®³«©¢¢¥¥••™‹‘“¤Ÿ‰ce[d`LIKKOFEAFK>=JA99JJN]QQJ=LW\9FI=DMI8Hc\LCLPSYYVWOZ^IA=WQIK?H@5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+w`S6SZkWsHE6=ue\LOžŸ¡˜žÄ§¥¢³¡œ²§“ª¤Ÿ£Ÿ­©¬»°¨¬µ²ÈÃÁó¾ǼÄʽ°°¶®°µ¯¿Åµ¹°°º¶­š©°©©šž¦¡§Â­›¬±œª¢®°©¤§½·¦¶º½¯·Ä­³³Â¿±Æ³º·«´¶­ª¢¥••”£«¡ŸŸ™¨«°®®»²¦ ©©™™—“¢¤¸¡¡¤’®¯¬¤¦Ÿ’¡ž•ž‘”š£Ÿ§´§§Œ˜´œ£°šž›®‘Ÿ”—”š€’¢–Ž ¡“‹¦¬°¥§¢œ ž’’›”…‹’œž€cf[hfKIMKSBC@IG;;F?99NMU^RSJ>O^^=HPBMLI9Nd]LELRTY[SUO\bHA?ZQAHAKB7FELKN>;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<v]^?[U^fr@8<H–weA4Ÿ¤Ÿ›ŸÂ¨£ª±¡£´©–²«¦¢¤²¬®©»²­°´´Æ¿ÄĵÀžÊĵÀȵ«µ¨°¸¬ÀÄ´·®¬¶º¥™«±«©˜Ÿ¦—­»µ›¨°›­Ÿ®´²§ªº³§º²·²¸Àª·²Â¼´Å§¾®­·µ©§¬¡—–‘¥¤¢¢—˜¤¯¸­²µ¶ Ÿ¨¤™”•“£Ÿ·£¤¥•®±²¥©¥¢žššš•˜¨ŸŸ˜¢ž®²¢¦—®™¥¬—šž¥‘›Ž”˜š…–Ÿ”Œœž”‹©©«¢§¡™ž–Œ™†–‰”Ÿydi]ljNPNNT=BANC;:I@77QO]^RVQAW`\BJSHWKH:Ud]NFON[W[RPQX]GAB[PBG>NC9HGHNP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1\cZ33906p[bH05JpiVCWFŒyfC;¤£œ¡¥¿¦¨¯¯¡©µª¹¯«¤ª´·±°¹¶°·¸¸Å½Ãǽ¼ÄÂÇÁ¹ÁÆÁºª¶¥­»­Á÷·ª­²¼£•­°­±–¥¨‘ª¹ª §°ªŸ¯´³ª©¶¶¬»«²²¹·¬¹°Á¹½¾¦Ã«°·®¨ª«¦˜˜ª¡¡ ‘— °®³«°¹š›©Ÿ™–’—¦ ¶©¥¢¢¯±³«±§«Ÿ›  ›ž¥œ¡—£³°›Ÿ”¦š¡©›•¢Ÿ–˜Š•˜“–—“‰›™”Ž©©§ ¤›˜›“‡Ž™‹~–†Ž›kimamnXQQZTACEU@;:IA7:XPd^PWWDY^^MLRO_KJ>Zd^NIQN[UYPKSWZI?DXPDF>N?=IGGQPB=CFBM?:2D?77547?=95E4+75/251.-.,1>*'+=\p=>1.1e[d@1747gY`F(@8l}h\V:‰{cC=¨Ÿœ¡©½¡ª°ª£±¸©¥µ²«¡­µ½¯³¸¼º½·¶ÁÿÉĹÅÃÁÀ¸Å½Á¸¯¶§«·²¼¿¾µ©®²¸Ÿ—¬­¨­—§©Ž§»Ÿ¥­³ž«¢±°³¬ª¶³µ¼­¯±µ¬°µ±À¹Ä¶«¼¯±¸¬¬©¢±¥ž¤¨Ÿ¤—˜Ÿ²ª³©ª³™§›™” ¥¤´®§¢¬¬®±§²¬²©£›Ÿ§¤•¡˜›¨µ©—™‘’Ÿ™Ÿ¡ž¬Ÿ˜˜†•˜‹š“Š–—š—§¦£ –•–”•…{’„Œ–flshpr_GYfVDCNXDZ9HB6>]Rh\NY]G[^]NMRXdJJC\c`PLMNXWXPJVVWL=EUJEDAM?AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,+%2+*5K1.'_^aV151=`V^8)C3YU\gK5ŒzfL@¤š ¤¬·£¬©¥®®¶ª®´¹¦§°¸Å·±·¾Áµ´»Å¾ÌŹÃÁº¿ºÄ¸Á¹³µ¬ªº·»º¾µª­±¶˜˜¨«ª«›¬««½ž«®±£ªŸ±­³®®¶²¹¶©­®±§µ°³º¼É²ªµ´±´¯®¦¡³Ÿš¨¬ ¥••š™±¢­ ¥¯–¡¤™™’¢¥¦²©¡¦±«ªµ¤®°µ¯£˜­§š—ž™™¬¸¢˜“˜œ¡™—”¬Ÿ”“™žœš–Š”’žš¥£¢ ™–’’–{‹…{ŒŠƒ‹’knynu|aF`jZIHZ[={JGE6AbTiZM\aJ[]ZRRSbaLKE`a`PLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`Va.5(C^Q\.*A/JGP[G3cYTKD™—Ÿ¯¨±©¬¥£®®µ©¶´·£¬´·Éº´»º¿¾µ´·ÃÁÍǼĽ·¾¿À·¿½²½®§ºº··Â·¬­±¹•—¦®«§£²ª”¯º¤­²±§§¢±³±²±µ±¸²¨®«²§¸¯µ³ÃŶ©´µ«°­©§¢¶Ÿž¦± ¤”›™”±§›Ÿ©©¢›•—¥¥¤·§¢°³«§±§­°µ¬¤™¡¬¨›œ›”ª¸œ•ŽŽ‹™¢˜—§¢Ÿ–ƒ’–œ˜—–ˆ——š§¤ ’–‘–v„‡{…‚„ŒŒnqxv|]Kel\JOd\?b{GI8GgWe[L^bMXYWTXTi]POHa]_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANIg27'FaLV%-B.=ELQ<3rkKDC‘˜¤­¤­­«¦£°²³ª¶°¶Ÿ«µ¹É¹®Á»Ã·³²µÂÃÏÄÀÁ½´½À¿º¿½³Ä¨ª¹±¶·¿½¯«³³ §°­¥¦°¥ž²µ¬«²°¬©¨´¹¬´³µ¬´¬©«¨¬©¹­±°Ç¾¸¤¹¯©­­¦¨­°¥££®£©œ›š¯™¢£¢£¬Ÿ£ Ÿ¡©¥¥¸¤«´´¤ª«¨¬®¶¯¢£¨ª› ™š’¤´š‰‡‘£ –Ž”ž •“…Ž”“›™–”‡˜’•™§œ Ÿ’‘Ž‘w~Ž…||}‡Š‰qts~}~\Rdn^NZg]FD–[G:NmXa[M`bNVWVWTYg^QRLdZ[TKGOTSNGIVS\N;P^JBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3Ce;6*HdHJ+:I?3CIS,>k>HIš©ª¡¨°¤¨£³´±´µ±±¡¬­½Ëº®Á»Æ±´­´ÂÃÑÄƾÀ²¾Â¼¿¸¼Å¨­·¬³¸¼Á°«²­¡¤§­©¨¤°£«±ª¯«±®®­«³»§·±²©²©ª¦¥£­º¬©±Â¹´¬¹¨¨¨­©§±¥©¤¢®ª¨¢ž›¢¬•¤—ž˜«¡§¨¡¬¥£­¬·±± ©¢Ÿª­°¬ž¦§©™£˜˜ §˜†ƒŽŠ‹Ÿ¡Œ—†ˆ‘• •˜•†–““—¥œœ‹‘Š‡…|w‡…‡usr‰vl_Y`ncQsr\K<„|F?WuX`YOd\NUVUWP\a_SONhXWVKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*35>10485(5/*,.30;),,'%234$,2-860)(1<^K0.IgDF8<B05EKX1@”\@MF•–¬§¡ª²œ©¨°µ¬¸´®ª¤««½É»±¾·Ã¯°­³ÄÄÎÎÿ¿´ÀÃĺÀ´ÉĬ¯·®²ºÀ¿³®®«¥¨ª°©¦¨²¥´­ª°®­±¯³¬³º¤¸´¬¬®§« ¢ž°·«ª­º¶¤µµ¤©§¬¬ª¬¡¨¦¦±²¤¦¥¡¡«–© “š ¦ž£¢ª¤¬¢ž¦±·¬¬¢¥¢š©ª­©œ¡¥¤£˜ š•˜”‚ˆ… ŠŽš‘‹„˜¤œ’‘›Œ“‘‘”£š›š‹Ž‹‹|‡‚‚{u€„~uw‹£‡yk^`ngWf‡dN@g’LDbzWbXReUMVUUTO\]aUKNiWVVIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*49?./463)4+*,+.#4.-+&(+79*&6+<-2,&06XZ.0JgAA<<C+:JO^4D†AIHD–‘¯¤¢ª°—ª¨­µ«¶°«¤«ª©¼ÁÀ¸¹³¼µ¦²¯ÄÉËÑ¿Á»¹ÀÀ¹ÁºÂÄ®±µ²´¼Á¾³²®­«¬¨¶ª¥­°ª¹¯¨°°®±«µª¶µ¦´¶«¬¤©ªœ£³³¨¨¤´´ ¶®¡©¨«¨«§ ª«¨¹¶©ª©©¡©Ÿ­›‘¨¡ £¢¦¢©œ¦´®§¥©¢£—¥¦§ªœ¢££Ÿ™˜Ÿ‘Ž™Ž~‡‡…žžˆ„Š‹Ž‘„†•¢šŽš‘’‘Ž“Ÿ—˜–Šƒt‡xuƒ{x~€ˆprggqx\atˆiO]˜VHmyUdVRcOLUTUQOXZbVHPjTWSGPYUI>IHOQPxMNV=<KD?@A<@CUC9AK=5;E13;97*4:=+-341*8**+*,)*(/*&)%3;,$2)2021%/2Rc02?f=NX?C,?LT_/Ik7RE;•¯Ÿ¥ª­™«¤­®³´®ª¥¯©©»¾»Á±¯¸­¢µ¯ÉÇÈÑÀ¿½º¼Ã½ºÃÁÀ¿¯²³²¶½¼Á²²³«³©¥µ©¤­³³¹¯¢­µ±¯±¹ª¸®ª®¶«ªžª« £¡¶®¨¡ž¯²¡´ªž¨§ª£ª¡¡¬­¨½¯¬®¬¡§§Ÿ«˜¯¢˜¢ ¨§Ÿ§›™©°¨¢Ÿ¬¡ ’¡¢£¦˜š¨¥˜˜˜Š‡•ˆ}†„…¤—†‚‚Œ‡Ž‘……• —‰’‘“‘•—Š…†xs}uxz€{tt{j‚‡£ui^elugˆ‹|RWp^KxsTdSQ_MMSZgNLVYeXGSjRR>BNQaQ:IHLSIqQLS;<I?;<=;@@W<<>H73CB15:93-5::)-31--6)(+-,52#2)',%.;.&1.0-14%,0Mi:38_=ad?F1CP[[+HO;XB4Ž°Ÿ¤¥ª£¥£¬¦´³°©¤°§ª¸¾Á¼°¨¹ª§®°ÉÇÈнÀ¾¹¾¾¼É¼Â¹±°µ²º¼¹À³´»­¹¬£µ§§¬²¶¹²¦§ºµ­´¼¯¼¥­­µ«­œ©¯¤Ÿ¥¬ª§œª²¤³¨šª§ª¤©ž¢¨¨©½«´¯­ž©£ ®›š²¢•¤›¤¥Ÿ¤š™¨ª¥žš©¡›‘š ¤˜–©©‘™™“Š‚…}‚€ˆž‡€~Œ‡‘…€”›”†“¢Œ”‘‹‘›’•‡‰~€rzy~|hw|zupq~i†y„ˆd`hdr…{mgy]^VCX{mTaPRXKKMpt]HZ[gYEVgOC>KNDCA9HGKS?jaIQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11&/>KI1%90%,,09/,,+6'17#-/GjI14X=fbAJ7GS`U*=<F\@*Ž“°™ŸŸ©¥£¡ª¤¶²±¤©±¦­¹Á½µ°£¹­¨¨°ÃÉÉÌÁ·½Àµ·¿ºÈ¶Ãµ´³µ²½¹º½¶­¹¶¿­¢³§ª«¯µ·´ªº»¨±¿²¹ ¯´¶©¬ž­±£œ¥¨©¢œ¤°¦¯ Ÿ«©§¡©œ£¨ ­»§®±®¡ª¢£­žž¬¥—Ÿ› ¢œŸ›™¢ª¢š™££•–“Ÿ¡–›–¦¬‹ž‘‘Œ‚‹€{š”‰}~Œ‡ŒŠ…’˜‘‡”¤Š’’‡š“ˆ|yl}vyxb{zrppsxj‚tj‚gchansŽmbjp`oB]ykV^NPQJILSYVM\^mWDXaO^PHMDF;7HEKO<rhJK9AE;;==;;=J49B<3;G<4?18-78;2(09/,5..=-*L>*49&'.34.0+/4&,:$40AhZ13S=e_DL6KVdN)=3Q]=#’—«˜Ÿ—§£¡Ÿ§£·¯­¢¯¯©«¸Âº³­Ÿ¹¯«¨´ºÇÊÇ¿·Â¾¯´¾·Ä¶Ã²°º²³Àµ»¾¸©¹¸½«¤µ§¨ª°­¹°©™¹¼£®¿´´¡®·µ§¦§°³ Ÿ¥¦§ ¥™ž¬¨©ž ª®§ ¦—¢¨Ÿ°¸Ÿ¤±® ¬¡¬¤›¦¦¨šš›ž£•œš©¦–šž¨‘—’˜“™•¡ªš‰‡}ˆ‚Ž||¡Œ‰yƒ…Š…ˆ“šŽ‰•Ÿ‰‘•‚Œ—}„{sp|qst`yxjopqpjsczlhfdae‡€`[rjqMN€iXZMPLJGPRQHM[_oTDXZRgOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23/:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%53=fd24M?e]FO=RZgH*?0\[5(–›¥˜œ•¬ŸŸ¡¤¡·ª°£´´©©¹Å¶²® ·¬­­°¶ÅÇÀ·¿Â¹°µ¼·¿»¿¯¬¾°³¿±½Ã¹©»º¸§¨¶¨§«°¬³°¦™¼¶¤«ºµ®Ÿ±¸¯©¥§¯²›¡¤ £¤¡–›¯¦¡Ÿ£¨¯¡ ¢“£¤¢¶°¡¦±«Ÿ¬¢®—›ª¤¨ž—š¤“š›š¥©™››¤””—”œŽ“—¢©¡‰Š…z„~„Šz—Š‡z‚ˆ„‰ŒŽ…Ž“˜ŒŽ–™Š–†—‹z€zpqvnpt_xwemllki„nfrikfi]ct`[kviZJ^[XOOKHHRUF29]^mPDXVYeMHIEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<"8R=*113>D5,-'42*;+139cm74GAf[HTDU]hD.<2cV,2•¢¡—”›©œ¤¡¢¡·©® º¸¥¬½Å³°®£µ¯­­¯´Ãü³¿º·°³¹¸º¸º¯®À³´¹°¿Á¸¬½ºµ¥¢³ª§©²«­±¡šÀµ¤§µµ¨ž²¼©¨¥©¯¬™£§œ¤¥”—¡²¥™Ÿ¤¨©œ¢ “¤Ÿ£¸¨¤§®¦¥¡¨’Ÿ¨¡¡ ˜šœ ’š›–Ÿ¡ª›š˜ ”“–™”’£¨¤‰‰†y„{„†}Ž‰Š‡z„‡‰‰‘…•““Œ•”Ž”{‚—Ž‹w~{ltqllsawthhjggo…ghhcfij`jcig[e{c`StT\[SLJGIOS@!*h^jLCVU^`KIGEC.:B<F<6KPD8:D357==895?:;4>8@K=>93)8><:9*6@3.E4(+,?0-N?.+-7,1195,&.5-80576`tA3CDg[KWGU`hB379gO'2ž¢£‘Ž£¦›žž£µ¬§ªº·§¬ÄÁ¶°¬£µ®§®¯·À¿¼²Á¶°®²¶¶¸¶¶­ª½³®²±½¿¸®¼»±¥Ÿ¶«¥¥´©ª®žÁ«¨¥¯²©¬µ»ž©©«±¥˜ž©§¤‘˜¦­¢˜ž¤©¡›¡œ–Ÿ§¶¥¯ª®¡¡¡” ¦Ÿ¡ ™›™œ‘™”¥«¡—–œ”’Œ•—‹˜š© ‘ˆ‰‹ˆy…w‚‚‚ˆ‹‚‰}…ˆ††‘„–•Ž‘‘‘Œ’{ƒ•†s}}fxokjkguskcgddv€beffejjdkrZ_Y]mdaNiX[`VJGIKMRX>9_liHBTS\[IHFEA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A=-5B37=+*,0B*JK./*+3722(57$+7.72685]yN2>HiZLZJVbf@:3BhH%5š£Ÿ‹¬¡˜˜Ÿ–¤³±¢±½¶¡±Æ¼º±±¤·¬ª®©¹¼»»®À²®®®¶®²¸³¨«¹±¯®³¶º¶°¸½­¦žµ«  °¤ª®œ¢À ±¤®°®·®µž­¯­­¢š§©¥ž•š§¥Ÿ™¤¢¨šŸ›”œ¬¯¥º¨®¢¡šš™ž£š¤—ž˜›”™ ’¨•©§š“šš‘‹”™””™©§ŽŠ‰|‚sŠ˜…‡|‰‰……ŠŒŠ’„”œ“‘–Ž€Œ‚p€~fymhkigqrk\hccsafhjnlgjjhn]lltpaUcideZIFLMOXQQVaeU@VSYTFHFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24;6#3*)6.55465Z|]19Kj[M[KXdd@A1JfC'4‘¡š°š“¡™¨²¯Ÿ¸¿¶ ´Â»½¹±¦¶°¨®¥·¸··­»¯¬ª«¶ª³¸­¥³µ²®©°·¶±³µº§©Ÿµ¨ž¨¢©­š§¾˜­£®¯´µ­¬Ÿ±­°©¢œœ£«¨›”œ¦£š©¢¤–šŸœ›£«ª©»Ÿ§¤ ˜™™¡k¡–™œp‚•š£u‘©§ž””žˆ—™€–Š¡x†”Œƒnj~vƒql†‹†}„Œ‡p^cag„˜†l‹”’tw‹„~ƒg†€guheW\hsnNPjcgr„g_dfnmj^_aŠƒ„eNKD9FTg^JGPPTUKHR`oteFZQUPFHFC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,+08>G601.*.*/568,#1'214:175Xl16Ok[N\K[fb>G1Qd=*.‹£™†”°›œ“ ›ª­ª£½Å¯©¸Â¸½¼­§¶°¥«¤·³²³±¹­©¦¬´¦¯µ¢¨¸¶¶¨§¬·³®´­³¢©Ÿ³ªž¡¤œ¦¦˜«º•¦¥¯²¶­®¤©®«¬¥¡Ÿ §§›— ¥¥››§§“ŸŸ˜ž§ª£µ¯£££œ–———£ˆ¡Ž’š‡¡‡“œ ¤¥ªž’‘š‘ˆ„rxŽ…ˆ¡vˆŒi—ˆf}rx¡oˆ‡„~Ž}¡  ™€|‡žt‡Žv›Šl‡ƒlheczkqaS…mcli˜qYjqo‡X^i[kk[ˆqnzr…g†„Z^GN?G_MFRVVQQRWTg^MWIRSOEGG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82).1<I9/01.*/(-4583%&2115>1<8Xƒu25Rk[N\L\g_=K1Wa70(‹¦–ƒœ«™˜Ÿªª§ª¿Ã¯±º½·À¿ª¥·°©­¦³´®¯³·«©¥±­¥´³œ­µ¶´¦§¨³±­²¨®ž« ²¨ £¢š ¡š­³”£¥¥µ¼§¬§«ª¬¨¥¡ ˜ ¦£™™¥£¤˜›£©–”£œ”“¤¥¦¡·££ ¤˜”“—“›ˆ®˜”‰©‹—¡›…±€£¬“™”y‚Ô¨€‡•Á›Çyx±¥·—d€Àœ¿y„„y„|‘Êq—¼œÅzrµ¦»{€l–±«°xhkX±®nei¼’¼nhznrØ~Sjb¶²r•tš¡ªWOWbPVNFT[XQPRŒ\W\P@\DQNDGI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22BE/.32.+/)-/186- /416A1=:Wƒw21Tk\O[M^g\>L1[]41!¦’€§ªŸ—œ¥­²¨±Â½²µÀµ·¾Â«¦³­¬©§®³©¯¶´§§¦´¥§¸®œ³²¶ª¥¤§²®®±¦ªž§¤±£¢Ÿž—šžœ®«”¢Ÿ³º£ª©¢­®¥¡šš¡§Ÿ—›§ Ÿ˜¦§‘œ§š“¡¦¢ °¢ŸŸ£–•’˜’™…¯jjŠª~gƒ•†­dp”™¥”q®¡¤~x»}k¡v±_j´[¥€fœ‘`f‚zfjxk©d¾rg¦Œu±j|±xt’“cmm§n[„ Ehf‡–Euœ`~g|¤§‚Y_‹«i€–xyj§7J¯\XSld[KNW_\WV;N‰OXW/ITTICEF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3..53/+/(.0.:5/'$203B/=;U‚v2-Vj\OYL_gY:M5_Y30¢•‚¬§¥ž£¤ª²·¬´½¾°¶Ä²·ºÂ¦©°«®¨©°®£°º¯£¤®²£©¸¨ž³²°£¥ ª­¯¬¯¦§Ÿ£¢°›¢›—•–šš¬¥–›¡ž³³¢«œ¢­­ ™— ¡¨œ™£Ÿœ™ ¥¤¢š— Ÿªž¦¦ ›Ÿ¡••‘–‘š…µ›µx…©™µ™v†³›·~“––¨”~k¦{‚†ˆ’”’w«gk±[«{‡”t‰q†€ˆ—x‚‚‹˜Œƒ „°vwŸqkkl|‹N¤XHcc™~ch¦`yruS’‡^P©mcq~‡€bœ.Q¡o[Skh`LK[dX\ZB>±yXXA#MhEBEA@A19>88:84;:9<9:A:E::;6:CB8=?KNG:5:AFB@AD<FD;0201;F,0.940,.(/3,>831/2-D1<<S}n3+Xj\OXM_gX7J8aU50•Ÿ•‡³¦¦¡®©§²¬©»¶Â°»Â­¸·Àª¬­­®¦­±©¡¯¼ª¡§´­£«µ¤¦³³§£¢§ª²¨°§¥žŸŸ¯–Ÿ˜”••—¬¡™™¤¨´¯¢©©¨ª›•˜ ¥§šŸœ¢Ÿ› £¤£•›Ÿ—™¢©›¥™œœ¢ —“‘“’œƒÕ“™¹p°Â~ņ|֔›»|š•¤œ¤{Ž‡¤‚¥‚z¬yV¯zˆ~Ÿj¹Z¹v‡„}¦‚“|˜zªy{±nŽ„t¼…o”P¯§ÅŠQ zc`©ctrˆm—ˆ`Sµ´È†€‰|c¤3Bv]PjidP@XgZdaJHNmM[ROYfZCD?E?0=<59;74<;8=:<C:F:;>6:@C;6@OLH<:<DHCBCD<EF81211DC./0483+-).323971#%5*>3==Qwj6*Yi[K]O_fT7G:aQ71%›¢“˜±¨¨¥³ª¥´©¤¼·Á°¹À±µ´»³µ§±°£°²¦Ÿ®¶¨š§¹®£¯± ³´° ¤žŸ§©°©´¨¤›ž«—˜—–—•• ªœ™–§­°©£ž¬¢¨–—œ¡¥¡˜¢¡¡¡š¡¢§›ž¡ž”™›¦ œ§•››Ÿ¡™‘”‘œˆ²nhµq«‡nŽ¦r´sr¶{š—¤‹£‘¡¥~°vƒ‘ÒÑv\®{…¤o›ª¦k‡…}­}—™{±s’y³e–t„žožf”RȋZÂ\Ÿyb_­`vs‡b—ˆ^Yʝo¿uMKµSUÆdTQjcfXAOk`lhPUGI8=VQZWXIC?J<2?;5=<46>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>HI91746@>/.24252-).26,742&60;5:=Pqh9'Wi\BOT_eP5G=aM620¡’¥¯­¤ª¼­¦µ¥§¶»¼²º¿·µ´ºº³¥´´¡±±¢Ÿ¬°¤—¦º®¤±°œ´¸ªŸ¦¡©¤²¨¬©¤™›š¨ž•”˜™’’¢§Ÿ–’¥ª°¦¢–“­Ÿ¥’” ›¤¦Ÿ”š¥¦¡š¢Ÿ­š ž•›¡žœ¥•–™¢Ÿ•˜•‘š…¬{w¨v£Žˆ†©o­Š‚§ƒ˜˜¡‰’šŠ¢“™‰®…‚³\r³R®}ƒ‚¤q×}x…~ž†™™w¯†Š‘œˆx³ašeš‚”l’Z°XKšu˜yf`­_ww‡h˜ˆk]¯w•žxl5yÈ®²_BSo^g`EPm_pmVUM.echRXQ;AD@L:5?91=<16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK97<46:>/04333.2..18*.32%!03767=Pke>&Vg\@>V_cN6GC`I:99Ÿ”Ÿ¸°—´Á­¨³¨©²º·³¸¿¹·²µ¼µ¤·³Ÿ´¬ŸŸ¨¬Ÿ”§µ«¨±±«­´¤›©  ¨¡¶§¦©¢™•¥¡“’›˜’”¢¥š’¦¬¯¦ •™©Ÿ¢Ž‘¢™¨¥ •š¥¨œ¤ž¬¡ ”žš¡˜™œ–—¡ “˜¦ž†©}}¥x¡Žƒªp­‹§†–Ÿ¡‰——ˆ£‚‘ˆ”ª|€‹yo±Z¨‚‚ˆ ytØvˆt¨‚Ž›’£|–Ÿ„{²^œd ~ƒ•l’\«[Z“‘hgªdr{k˜‡s]¬Z‰ ŽkoeOJC¡\[Lt]bfM[a_rs_JV6J›“XHE=GFAM35A8.;>05A78@<6=<F?:<6?=B7.HVJEAH6KIN@IK@EN::@4.;>102144+*05/7,&21($$6671<PeeA&Uf[?2U_bL7FI_C2?8¡™™¿«—´Â®¬­©¦´°·±µ¿¹¹²°·»©º´Ÿ°¤ž¥§§ž“ª°©¯ªµ¬ª¯¡˜¡ ¦¥¤º¢£« –›‘¢ ”“žš”—žŸ‹¨¯¯¦–›¨¦ŸŒ’¤—¨«§”—©§žž £­¤¡ž¡•¡˜Ÿ ’—œ•¡•–Ž«›®mr´r©ŒvŠ¦s´xs³€‘¤£’œ‰¤‡w¸oŒ{‹¢kk¶Z …e——i¡¢§m“r´t“˜²j…’ˆ­ku³af¢o‡’j—\­_M¡|‡‘Rs£mz~o˜‡q\¯V<œweTon.\§OcRkebmZc]`p{cSZQ>>mo3CB@?L9!7@6.;@37C58??3;<CDBJFMIF62JTKEBI6IJP?HNCFP=<E50;;010/75,+,426/#00,,289/9N`eD'UdY>/U^aL5FM^81C8¥š›»¡œ²À®®««§·©¸¯µÀµ¼°¯¹¸«Á¶©© ›¦£¢‘ªª¨¶£²§¯ª —œ§ ¤«¸£­›–™¥¢•Œ¡›˜œŸ‘“”«µ°§™”œ¬ª—Œ“¥™¥­¢‘–ª±¤Ÿž¦«°˜¡£™¢–Ÿ›–œ—¡’œ©œ”ª™‡Ô’š»s°Ã€Ã†~Ֆ›¸xˆ˜Œ˜ŠŒ§ˆz£¶u}wv‚š²`ƒºyÀ|u¸bµŒ‡©}•¬©q{u¼ˆ§ ia¦Ž¯¡~Œt‡ª}¾ns¼t²ƒuxŠnšˆqn¤t½^w}[ay¼kZV[jz^jaegbmxoY[YCA@r@CG+5G"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-7A9§›ž¡¼¢—±Ã°­ªª¬±§¸¯¶Ä±º±®º¯®À±«¤¢ž£¢œ›©¤ª²¤µ¦­¥Ÿ–™ª™¦¬¸œ¢®˜” ¥Ÿ’Œœ£ž—›‘•’¯¹²¬•—£§§“–¤œ¤¬ž‘ ¨«Ÿ›Ÿ¨£³ž£¥Ž§¡”¢šœ˜•£˜° ’”©ž…™µ€‘Œ·•x‚“šµwmknsoy„Ž‰tžÁ»½š{²¨p€t‘¹ƒ|††Œ†{Š‡—|¤»¹½œuz´£tv—ut°u™žf†iµtrpw¶Œ^€z}Šhƒymyc‹¬pu…Z[§jEeZTf`c]cQggpluBMPLD:ZM?J3<0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITBKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7LT_G'SbW8*O^]=+:VV'>;<§ž ¡¿¥–´Â´¬ª¨¬«©»®°Å®´²®·§´¸­©¢¡¥ž ™“«¤­ª¦µ¨§Ÿ›– £«¤½¦ ª—”œ¡š‘¢¨¡“˜“—”²µ·­˜££¢Š’’¦›¥ª›–©¤¥œš¡¨¦¦£©¡‘­ž–£ž———ž°¨”›§¡Žj~iœ¦x‡r}šŽtzd‡{½¾Àºo’‚q•‡asjZ^›ŠacˆŽ•k`€•dmwb•k€š•”e^acqšŠirŒ}…•gj~rtx}}b[wthP\n„}|‹kXlz‚sJJo†pMuMEW]gaLZWgc_O[mujqRODEN;HH=L?2-2A?8/5?C<9;@;=C>RVVWYZ[\\]`aaa`\UG5DFUEJOHFPIIH;8=51:.0;:.0-76=5&"/*2,%;8-7JR_I'S`V4)P_L(3=[O'?2>¨ ¨¡Â£š´¹¶£¬¥®§¨µ²«È«°³«´£¾±²¦ ¢¨£›™™¬¦¯¤¤µ©¥›—•¡š¦­¨½§¨¦•“›•Ÿ™’—¤©¨‘˜œ°²¿¬›§¦¡ˆ“‘©š¨£š›¬Ÿ£™š£§¬¢Ÿ«¢š±›•§ —•Ÿ—±¤—¡¨™œ‘œ¢¤˜¦¢šœšš™•gm}qw’—”‘…‹µª†˜•ŽŠŒ˜—‡”•Š„’”‘‰Ž’”˜”˜—š ¢šœ”¡ž‚z¤†lj||€t‰Šq‚xyvv‹€|Škstƒuev}wkp{m`c]phMXZfj`WZoymmfSOFS9OYMRO(+:KB635=@A9:C><ENSSTVWXYZ\]`bba_^^[TKCSGKNDGPLOI<:;389,2;820)6IRO8")+/2#4;*7FO[J&R^S10T^:+=8\K,<-@³¡³¡¿¡¤±²· ©¥²§¥°µªÈ«¬°¥µ¦À§´ ¤¤œ£•• ª§¬££¶«Ÿ™–•Ÿ–­©¥Àž«¤•’œ——’“¢Ÿž¢§“‘™¨§²Ä¯š«œªž––¨ª›œ ¬˜¡›œ¢¤¯¦¡¥¨Ÿ®˜—§™š žžœ¯ œ¡¦•˜’˜“ ¡•£ž— Ž–“ŠŠŽ–­|•›‚’‚‹ª¨†™—Š„Ÿˆ{„‡†š’ˆ†Š•›—‘˜ž¤–š“‘žŽf¡³¯…Š„vzŠ|vyzofz‘€‰kuyˆsiszuƒ‡‚ktdyf`iecdfkYl{pij\SLPD_TE@??,4@F;45;>A;<?>>HNNOPSUVVXZ\_aca_^^]^]XVJKLBIOMRJ;<:786/2964.(&$-1./)+*7%+<(6CMMD/T]Q05M[17E4\G5<,@´ ¹¯¿¬«®²± ª¦±­¢¬³°Ä°ª«£³®¼£´›Ÿ¦¢¡œ™—§¥©¦¤¥²´ž•”™™°¦­¾ «¢‘š™”‘”¢œ—¨œ„žª«¢³È³Ÿª¤ª––—š§¨šŸ¤«“žž ©¯©¥£«¢®›Ÿ ¡˜¤žœŸ¯£˜ž¨“˜—œ‘¤™˜¨š—e‚’|e~™cylhk{’¤ªješ˜~g†Šeeih{Ž¡kh—‘£wkj‹™£ž™sln{„‡zXe^†‚^l‹‰€v\hsww’€‡‚nx‚x€smy„tw‰ˆŽƒ{i†Y^ktd]s‰ik}qkc^RNWJdXAJ4=F7?FD71<=?AD;;DGHHILNPRRTW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%/*+'6*$;'/AJ[J/7ZO6)EY/DO1YC;?.=¥Ÿº¼¹¯¬³°ª¥¨­­°§­­°¼±©§¤­¯°Ÿ­— £¢™™¦«œ­£¥¨©²­ž•£¢¯¦¶¹¥®£ŽŽš¡™“’š ™™¥•{¥­¢¨³Ä¸¤¢§¯ž”ž¢ž£œ£©©’ž¡ ª°ª«¤ª ª›§Ÿ¨ ¬–¡›¥°¤—›ª•¡ž›’¥—žª˜ž~½ƒ‡r´r„…­hx¹Ä¸q“¢£z¦™™sª‚|ËÀÀ»qŒ¢ˆ‚Ÿ}–˜‰À½‚—ÂÁ|‚|’šÃÀ}k¥²oŒoÊz›w’ƒŽvz€yqz‡qx…“ymw”cf_yd`e‚c^thldbXLVIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^__`_^^^^___]\SMPGUNA??=6468276*&%#)*&.+*)109*#>I[L*#BQ/#F[3PY/UAB;/8–£¹Ã´°°À©¨”£¯©°®­¦³´¯©¥¦¦±«Ÿ«˜š¢Ÿœšª§¢¬£¥¨¤¤´¤¢“¦­«·³§®¢‘‘™¥’Ÿ¡˜›Ÿ‡§¬¤«­ÀÀ± ©¯©—‘ž¡™¢£ª£“ ¡ž­®©¬§££§¡¦¥­©’¤š¨­©›œ©œ¬¡––¥•¡¢—œΔxz¤y”–›_®^Ž§¢ }§–œt«ƒ€¯^cª{§‡… t—“ˆ³c‚«†¡³j…¯t}—ˆ¸aƒ­Y£Ímu{Ú{™p~ˆ’v~e{ˆvvk|ˆo~…‘’~m‚`rlpg`_yd\qhjcf`RTRW]KOC5AHED8>6;@?A;=8@>??BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5578164('$!',&&/(&+360$7;SL+,-K0';\;L-!P@F4.1­ÂÀ¿µ´°¸—‘¤ª¨­´«¥²¬¬«¤«¦°ª §›™¥—œ¢¯Ÿ Ÿ¨§£¥¡Ÿ°¬š•§®­±«¨¬ ”’›Ÿ¤’ž¥˜§£ž®¤«°©Àdz¨©±®–’›¡—Ÿ©ªŸ” Ÿ®°§«©œ§¨¤¢«“¬³—¥¢ª©£¦¥¡° ’™¦™ š””‘— q…Œ—t„¨‡q±|q¬~¡ž¥žwª‚}­œs­~«‡†Ÿv˜’{|—~ªˆ¢Œ‘Œ~«{‰”Ÿ€{­VœÄzo’Á}•muoŒmeve†oawnroŠ‹’ƒm’fpuup`gme_oiingcWS\aYRSC8II@D<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;91478452&# 1' 1' '45-&7=WJ-<'>1)3V@F!G:C1.+°ÔÆƲ´ œ£Ž££¢¬¯¶¯¨±¦¨ª§­««§¢£™¢• ¥ªŸ¡¥ ¨¨¢Ÿ°¬—š–¨§¯¬¨¦©ž—”š£¡‘“ ­›¦£¯¬£¬µªºÎ²­¦­¬–•œ¢˜ž®¬– ™žŸª²©ªª›¬«¤£¬›¯±¢¨«®¥˜¦ª©©±¢’–£¤š”’…¤j¤u‰z©tz²p‚¦Š™Œqˆ š‡¤`aR«„®ƒ›v­¦††Ÿz™—†{f€£‰¤™†‚¤}©‚•‡®^}©U¢’z¢Ÿ€{ïŋr¯³³¹qb©¯ÂthŒ˜mš”pnyxxolfeeqpf|ib]W`iXXULLQLCCAB;C@@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799664,&$" ('"+-"$.!3-&@DWH,G+56*1PKL# A9D4,'ÃÉÖÕ¿¡™«§¡¯¢ž°´°¯©­¢§¦ª««©¤¦ ›¤ž¦§¦£œ«š¢¬¡¤Ÿ¯¢œ›“ª¤µ°¯ ©›–”¦¢š¢¨  ¥œ°¦¤¨²­·É²µª«©•‘œ¢˜Ÿ¥³š ”Ÿ§¬¬¤®š­«££ª¢³®¢ª³±¡š©¨®¯¶¢’–¢§˜›‘|ªlž„‡u«y|°o‚¤‹‰Ÿ––Ÿ”Ò¸´¸É€²_`”©ƒ£ˆ‡ z˜–šxªÉt™¤•¨ª‘“šŒ€›Š™ÆÆxf¡‚¥sŸŽ‚}¯]p´b°uK£†m§G‚“dž’|q—“€q{u~{n[fjrpej_aXdm\^YINLKEDAB>A<B?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75685/)(%&%$&),4ENPPMFKJVF*L0/=-5OTQ;<F2,$§¤ÀƸ­©³­¬¥¢œ²¹¬ª¡¦š¨¥ª«ª§ ¦¥˜ª£Ÿ¯«¦ ¬šž©¥§µŸ¢—“©ª¶²¬œ¥›Ÿ”¥¬‘™›§£ ©¦®¡¤§ª°µÂ²³ª­¨“‰—¤š¡£®¦˜¡•™œ¦¦¬›°®©§ž¬¤·¬ ±¹¯›®§²³³¤”—§¢™ŸŽ‚NxšŸzƒ£}ƒ¤„†¦žœž“„¸{|y¹‚~Ìƶx›¡‹Ÿ~š–—Švž˜Š¥˜¤©°……Ÿ„¬}š”b¥l¤p…}–‚r¬`£sq€š`¼}RUu’¤—{~“’‹u{s…q\mnxrjo[d_hnbd]KLQTAIHFI:9K>B108866877-*5==?BDGILNPTVXYZ[\__^]__\ZZZYUSOH@882.,*.+*'&?QTVWWWYXXWUOUF<E3:P[T6?H,- ‹‡™©«¤«¹ª¯ ›¡¬³³¥Ÿ •¥®­®ª§¦¦š£§¡³®¢©¦² ™©¤”¢µ¢¢•—¢©µ¹£›¢œ¡’¡±˜ž›§¥¡¢¯®¤¨¢¶²Ä±­©­©‘‡œ§œ¢¤œ¥—ž˜™š¦¤©š¯¡¯¥¦˜¯¥¼­¡¶·­µ²¸°³¦—¯ £…ÑµÃ·y‡Ž…‘“¦x”¡wŒ ‘„¥Šqª†„´nrj™£œ•Šž|˜™†‡s¯‚¥›¢Ž¦‹“Š•šmp²\¥s“zœl™{™|m©a£qqŸbs²¸hx”¦˜}Œ”x}y‚mixiyrn€u]ednmfg`J[XX<HG@U3@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^__][ZZXURRQF:2230/++(@QRTUTSTVWWXXWUUVTQOQ[U%!2AH$)%“sŠ­¿¿¼º´ž–§¥­µ¡¢™•£¨§®«¬™¦¢Ÿ¦  µ§¢©§°£”¬£Ž¤­£ššª´´¤¤›§‘”—­ŸŸ§¤§œµš¡ª¤¶«Ã°©«©¡Œ„Žœ¡ ¦£•ššœ˜›™§¥¦˜¬¨®£¥›­¦¾¬”½°¬Ÿ¢°²¹«³¦š¨±£§—z¨}|°wŠ¤¥ˆœm²o ‡­|¡Žƒ¨•˜€¬‰„®…Ÿ”ª¡¡—†Ÿ€™•€{’~«€š—‹«xŸ‘‰“’€y¯]£}¦§d€|—sj¯]¥kp…™]`[Œ m•’¦™‚•Ž˜{{„˜kmc~tn€z`geqnhggCZa[>KT3U8BBC7$$3+''3, /6674359@CFIKMNQSSSVZ]_a``aa^][ZXSPONI8052.*,ATVVVTTUUUUTTUTSTVWWXVUUQHFIJ#((½’šƒ©Æ¶Á³Ÿš¬ ®¸¥£Ž›¤£Ÿ°¯ªŸ¤Ÿ­™ž¹ £« ¯©š®¡«¨¤–‰š®±¬¦Ÿ¦š¬—˜¬¡¡¥¡š¥­˜ ¨¦¶©À¯¥©¤Ÿ‹€›šŸ¦ž’”šš”šš¥¤¤š©¬¬¤¥Ÿª¨¾¤–쪢¡«²¹ª®§ ³®¨©˜v¯~‹œ…‡|º®Š˜e°Œe•­}¡ƒ¦•š¬Š„°…¦™¤¡¡‘… [lj³`­{{‚±mgo™˜Œˆ°[}´\¤ƒkÈ¢dŸ€{¼XvµZ²}R®€z¬X€¡n˜¨›‹—‘˜˜|y~dt~b„xt€|ajgqmfeeOUd\BU_>J(>9=4!",%2. *1/04579:<ACFHJLNPQRTXZ^```ab^_\[XUPNJFC553./@UZXWXWXXWWXWVWWWWXWWXYZZ\\XWWGB;ҟ³²·½º´Â³£›¬¦¥¶¨ ‹š Ÿœ³³©Ÿ£ žµ˜ ´¨ª¬ž¯­ž¬›•¯¨¢Žˆ›Ž¯¬¨§¢¦™®’™¨š¡¤Ÿ™¤£¥™Ÿ£ª²©½¯¥¨žŽ}‹š•  ™‘š›’š—¨Ÿ¡š¨®¨¦¦£¥©»ž Æ¦¤¨¡«´µ¬®¦ž»­¬¬•€©’£¯›€‡¤—˜€¸ÃºƒŽœ“„§–œ‚¬Š‚¯ˆ¦››¥ª‘~սªb£¿½}~£‚ƒ×º¸µ…”“ƒž½¾„k£o«„lœz²°Çƒj«°½¬xw¢¾¼t–Ž§œ›‘˜z‚‘›zc}{dŽgy‚{`lekjbPaZSj\@UaBN*=:4/$%2 $(0496678:>ACFGJKMNNQTW]a\__a^`[\YTQMHC?<A?5=SYXXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ»•³´±¿¹±½²¢®¦¥²¦Œ˜¥¿ª¸²¨¡¿¦§²œž±œº¨Ÿ­¯¦¦””°¬—Œƒ›‘®¥¢¬¡£œªŸ˜‹£’¦ž§œš¡¨¢™ž¡¬­ª¹®¨£›—’{‡™‘¦›“Ž‘˜˜˜“¨š ˜©©¡ª§¡£ª»ž¨Ä¢ ®£ª³´ª°© º§®®šsuª¤·†e‰ pg­Šmow¤™Ÿu®˜”p‹q•¨£›—®¤rmmlf‹xon‚™qzjqig‰–•˜qii„‡gp†d]ˆbjoY]g~w¦_aqŽ‘nfe€“¢˜™™‘˜Ÿ}‡•vf‡xiŽkyydlcflbKdXJlZ:QeER'K:+# ",)-2.5:4579<?ABDEHKLMOQSV]WZ\``a]][TPLHD=:AB7MXZZYYZYXXYXWWVWY]^^]\\\]^]^][[UW^¨•­³©¹¹²³ª©¡®ž£²©˜’¾²Äɾ¶ªžÀ¬¬£¡¨¬ º£¤®¬­¦—®©Œ…•–­ž¦«¡ž££Ÿ‘‹¤’§™¨™–£ª –œ¦¦§¯º¬¬š›“’{„—¥˜‘‘˜”—•¨•Ÿ˜©£›±¦ž¢«¹Ÿ¯À§¤²¥¬°±ª­«§·£­·–Š ¨¥¶‰–¢˜‡©š”’©³™›£« ±–¢  ¢œ ¥¡•«§“’Œ‡“œœ•š“˜‘Ž•…¤š—•‹““‹†„}g‰~t‚vt‡‹q§lz”‘“’Ž•¡–š˜¢ƒˆ•riwq‹xw|zjldcodU`X@j[HcaOZ+F=+'!740.!%2(*699469;>?ABDEJKKMPPQXTVY^`ac]^UQJED>9=@ASX[\ZWXXXXXYXXZ[[\^__`^^^__```_YY`¥–©ª¥µ¶®®¢°£­Ÿ µ±Ž¬Ç½Å»¹«¢¦ž›¦Ÿ±¨£¶§©´§¨‘˜¬¢‹‡‰›§–¬¥ ™§žž’•£—¨š¨™”¦¡£š§™¡µ»¨«˜š{”‹ ”Š•‘•“—¥Ÿšª œ¶£ž§«·§®Á®£¶¦¯¯°¬©©³¸ ®¼™‘¥¤¦¶¢’¦Ÿ©Ÿ’Ÿ£¬¯›¡£°¨¯—£ œ£ªžžœ–«’™¡›”–ª™™™––ž‘‰ •”…’Œ”‹€}f‹…u†uyˆƒsœj…”“‰}Œ–’’—”¢“ž˜¢„‰™‡{r–sz‹r|jod^pja[_YncP`dPZ:GGE>2==8/+&+)&&406668:==?AACIJGJKLMSSSUZ``i`eUPJACB:9EMV[^^[Z\[[[\]]__]^__aabaaa`bbbdb\[c—•¤¨£°³¬®£©¦­ §µª¥´¼¯­­¢£šz¢±¤¥±©—œ¸¦£”™ªœŽ†Š‰œ£®Ÿ¢•§Ÿ¡’—˜›®‹ª–¨™¨Œ˜©Ÿ¹¶¥¦™›ˆy‚“‹š“Š•’”’—¢ž¨žŸ¸£€„¯µ¢¯¯u¤½£² wy ª²º”u¬¤ž‰€ªd\bv Ž¤ž„—}n“³£§­ª£eŸ’sy™–p€˜¨—l¢¨Šeœ¥œ‘—˜–Œ’œ‘†š•ƒ’‡’‰„wjŽ†v†p{†€ai‡Š”’‹Zu•‘hhs{¦š™ey™‡ƒx˜j„‹ƒoy€kqe_vplkh\gebbpS\>NNNSG>@TD91/&4:316678<;>@AAFHBGFIKMTTUY]`hfgWQJ<DG<8UR[`ab`^`_`aa_\]__`aabcdabaaedchd^]f›•¦£¡¯±¬«©¥©®£¦­¤’–«¶°²§›«¦¬—tŒ¯Ÿ¨«§”—¹Ÿ œ¤‘‰ˆ›ž«š¢•§¡Ž—‘ž„u®ˆ¦š©‘—¤‰œº´¨ ™˜‹‰uw“•“Š”‘”Œ“ Ž›¡§™œ²–€Œ›µ³Œ’¼§ ~§¢z¢®¶ŽŽ¦žƒ‹†±©¯ŒŠ–£šy€‹¬†œ¢§©§‡•…˜w¥›z‡›—§‚‚{œ²zŠ† —™”˜–‚‘—–„š™cy‡„Ž‘ŠƒmpŽ‡y€p€…†t†„•‘x–h’t št}™„¢ž‡˜“‹ƒ„™kŽŽ…lx{qqgdxojlj\fkjet\_ITLQ@E5.ZTU7)!09=>643568;:=>>@DI?JEJKGSX[Y[aaifZQH9EK<>aV^bdfd`aa`bb_]`aabbbcfgcba`edcgcaahœ—£Ÿ¦­®«¨¬ ¨±¦¦©¥™”®È¾±¢—§©µž„¬œ§¢ ¾žšŸš |†Ž™˜ˆ¬œ¡–Ÿ ‘“‰†€‘¨‡¢¤”˜ž†Ÿº²§ž›’Ž…pu‰”Š”›Œ’Ÿ’—¡¥–ž«‡Ÿ´‰´š­ŠÊ‡ª®ˆ·…Œ¯‚°®ƒ©¥˜}¨r{wœ§–h•¤y´ŒŸž¦¨’˜Â«ˆ˜¡rž€š¥}—…•±€¡}¡“ ˜—Ž“›Š˜‘‹|…“†•’‰ƒmr…yq†„|„u„–€Åf©‡£kžƒ£›„šŽŽ†Š™qŽ“…hwt|whhuqhhk^dpmgmXgG]RM2D46Nac7&3<EGD:64658;8>==?BM?NIJLCPZ]\Wa^jm\QE=LM@JdX]cfhgbbbbcc`_babccceiicbbbecafcbbi”—¢Ÿ°§©¨¦« ¤¸°©ª¦š” £¤«¤—¥ª·£¯€¡§œ¥ž‰”½™“¡’žy„––‘ˆ«™››™¡…Œw›œŸˆž¤œ–š˜‡£¹®¥šœŒŒ~bm‹“˜Œ‘’Ÿ”¡¡™¡§~¡§‡­ –­žœ‘…€ «®†£©™Œš£u€™”k‚¬uM«x‡œ‘›¨§€©«}ƒ¡{z§iž’kg—†—¶‰ž~n`dYƒ—Œ{dh‹r™}y•l]|–m_Spƒ\_kyƒ`Ye‚}ƒ€—p§ªkƒ£nr¥pŸ… if m[nŠ|fZ`ƒbWPowfmtrkjo^kpmliXiO]XF9A4GD^k4,ICRMN=84859;6@;;>BO>QRLMBJ\]_W^^cv`MD:MOMTb\\ffiibbdbddbab`bdcacikdbddgdbgeach—– ¸ ª¤¦¬‘¡µ¼«®¢™˜ ¢¥¬®¡®µ¢¨’¡ Ÿ¦›šŽ™´™‹ŸŒ•‹u”’Š¦–•˜žž’…†¬¤‡›Š˜©™š›’ˆ¦±§¢–šˆ‰€inˆˆ‹ŽŽŠ‹’Œ’¢Œ”Ÿ œ¡¤“£¡” wœ–§ƒ¡§†©¬„¥xŠ|„š~¢ps”ˆ–{žŒym‡›Œ™›¨š‡{‚¢sv¦fž~w¤_˜z}’s¢n˜·´ºt“‡‚µ¨dÆ¸{p•·‹q€š¤bs¬«`}i³~n|†‚‚‹˜q£lr£tž„€£`™³–q|—Ÿ³ts[ž²ƒjbotvqioXklrrf]i^bKE=D6QAYq3=SG_JR=<395::6D;;@JP?UMNQ@D_^[YX``|dHC8LWUVcaZefkkbbeadc`ab`dd_`cknccddhdbgfchh”–•£¸™«œ“ ¤·µ®­ š¢££¦®œ›±­¬“˜¡™¡¤™š”Ÿ«›‹ˆ’x‹…q€–Š¡’”—}‰¨¡‡˜ŽŠ‘£”œ›‹©¨¥ž—‡…~k{‡~}ƒ‹‘‰” ƒ—ž  ž‹‰wœ˜¢ŒŸr¡‹‡¨ˆ›¥–§ª~­Œ~z ™z£“xt–ˆœ}•Ÿ†›Ž™›¦†¢d¡|ˆ–›lžhšnš™{€‹§}rht«ƒžƒtªh•š]›…v„hªj€¸f\¨pœ`•Œ^§vu‡‰~žhšu†“’—ŽŸnšm§š]¨~x»k~ª[Ž„]³g\nrzxki\qjxyc`fXbAQFO7VCRo5KZZ_OZD@151;;6H?:CHU>YRY]>Db^V`Qac}jEB9N[]YefXfgnmbbe_aa__``ec^bdoq_deekecihgki•œ‰ªµ›§ˆc”›«º²±¬ž¦œœ©Ÿž®›ž°¨¬—¤š¡Ÿ˜––¡¤™†‰jˆ€r{—ˆ‹––„‘”˜zŠ„–¤Š”†‹ž’‰©£ šŒ’Š€€i€†x—Œ{‰ŽŽˆ–š”¢Ÿ ¡“˜rhŸŠŸŒp’Œ©‡˜ž¢§Ÿ§|¯­£¢¸—w£³¢¤€ˆ”y{ªš¢Ž›—ˆ—q¡|…¯µ}kš‘¡x~˜´££«¨„™|›}štªZ]o{–‹xžbL~zz…cy—BLžY¢jr|Žm€ˆ„™u›x†‰±³›“§v‚ns}”o™sk¤]•vHedasq~~nf`liv{debR^W]UW@ZEQhDSW\bX^ID=B8?B:IF8LEXAWR[VDFb\Z`K`m~rEC<U_bZfjVghmobfg^aa\]^ahb_ecvl^egfkdflihki“œ°­™„T^ ¦³¹³³©š¢Œœ«œœ©”¡«¤¡¨Ÿžš™–˜¡–ˆ‡‰w†oy•…›‹|‘“–ˆrˆ’¡œs‘ˆ™•¡›…Ž©œš•‹‹‹|ƒl„…q¡Œx†ˆˆ“˜•|“£ ž£ˆ­†}µ„Žžœ{¥–z©•œŠ œ|§hwm~™t¡sq|ž†™p“ƒ®}¤ƒ¦ž™€£o^¨gu£co¥aœÓ|{™xrsc¢†~£s¤vk³Œ`‚˜‰sª²¨¼wƒm~¾¦©´^œn}q—nr¢r]¤gs¦ah¦m›Ô™}…›pzz—k›|x—sn©¤gaeyp€„kgfdnuwg`cT[fQQbIWJTaWS[ej\eQFCKMJKBKE8O@QNXSYOSQafejRcwywIFEc]eZhjTihjocjg`c`\]]_hbahe|d^dgdkdjmghlh—›°«T\K~©¯±´°³£œ™…™© ¡¤Ž¥¨ ˜©Š™˜˜“™“’ ˜Ž‡†{p}„h}ƒ”šwŽ‰o†’’l—“|‰‘’¤–ƒŽªš“’‹…‰zƒv‡€nŸ†w’†ˆ™¢—{”£¤šŸ‰³¡¢¶‹z¬§¤®¥p¨€š…€›‘{¤€¢™†˜rž„£®¯Š—ŒŒ¤•ƒ­¡”v´µµÉ¡s”ŠŸ`—©my•† ›u¡‡w ~’—‹oLf£’p›‡r¤{ztaƒk~ kqd_œq}t—izi³µ´Æ¦s˜~zkœ›«u„›mux˜išzu˜rPE}´^jvky‡fjhbtupnV^TYiPSiIVMYTV]hknVgWMJBJMKHJOAQKPecjmeussy|nu‰{{TPNl^h[kiRjhilglfce`\]\^ibdik{_]dhcjfoleime¡œˆ¯¦„f?”¡³«¯¯¶¢¢€˜ª¢¢¥Œ¥§¦‚š—–—œ“Žˆƒyjy†eƒŒ— yuŽˆŒi„…’‚Œ…zŒ‹•¦“ƒ—©˜Œ‘‹‰z€}‹yp¡†y•‡‰– •”¥§œ––„fnxœl¢d|q¥w›˜pg¦€–‹{¤zŸ–ƒ—ržvŠ”–¹nŠ¢b}™¡•ˆmriªku mn¦_ši‹h–‡š•u¢€}š`Œ†uoˆbh ež~išuocfˆ‚mr¢Z_[b¡m]‰Œo{~srd¥mw¢dg§i™sŒ™o¢oS‰o _e¨T‹^T˜nmskr‚mpikyskoRYWWgZTmJYO]IXiisjYkVQREV\LXSaUik_wt{}p}|rƒ{sv€„v^QrbgbpgPjhhklnhdg_]^]`kbjivu]\cicjjslfkmcœ¤˜¦zetm‹§®¤©°±¦Ÿ‹€˜«Ÿ¦Œ¢¡›¢¢€–˜“š‹˜ŽŠ{†q€ˆh‹‹|˜›st‰}{d‚‡•Š‰–™‚|ˆ‡–¨‘¢¬‘†Š‚Š~€€Žsi¥„}†”ˆ˜ Žˆ“ª¦‰¦x•›~¥ˆ–Œ²˜ž‚¯—Ÿ¥w”‡y©t¥„šn¤¢Œ’„Œƒ»n}¥¯ƒ†††“•œŸ|¥zr¨• –fž~o«c–Š•’x¨l©¢‰vˆƒwª‘¦‡j‘°kv³Œ©kŠ†mmŸž’•`~«‹ªv~Œ¥žvŸ}„¤• j›ˆw¬gŸ­Œ¶tw¾¤“Yƒ¦«aurtp|uqcj~nhlSW[Vab]kM]R]J^mnv`[qY[`[ftenoqbqt`wz~yryƒs„{{Œ‚€vbxdcmsdRkgholrjfia`^\bkbmlzo\\bibljwmglnb•¥ª€ž¤–©ª¨§®¤™‰ƒ˜«šž¤‰›¥©…ŒšŽ†œ‘…’Œt†zˆ„o„~˜“tt†r’ƒm‹’‡†“}{‚…˜¦Ž¥¦ŽŽ‰…•v‚‡’ol‹©€ƒ‹”Ž‰œŸ‰Œ”ª£ €u”—ˆ~y”®£›q…xŠƒ~{r§Œq}}z—–›„Žx{~~‡”•“Šv˜Ÿ ƒ{}‰kŒ…[yyrzphn~’‰qu”“q†„‚eŒ^‹wus”uoynn‡m„…^vhxŽe€€…©›}t|–j‰ˆpv}†vmmgŒsy{˜x…[kXyinwrqpxxp]l†nigV[`W\fkdVbU_Q_pxxlkvejkkv}qrtsaoubt{xuzƒu€y‹…ƒ}{mldxn^Wnghukxjije\`ZciflqunZ[bkdllynhloa”¸¨¦‹¡¢š¦¤™¥œ«£¡„„˜¬’ž¡‰š¦š©˜ƒ›Š~–“‡ŽŠ‰rƒ|}~…{—Žsrƒp•…{}’‹††…x}€†™¤Ž|§¡‹†…–ƒ†Ž˜wr…©…Ž‘ˆžžˆŒ›¨Ÿ ªƒ‰Ž•š~~‰–­¨’¦woœ‚y‘o~¨…p}•qkp}ŸŒ“ŽŒhm]ƒ‹Œœ›žŽs•‹ˆqtk‚vtYrn†‘}~Œj]jd{…„‰€`ixz›{‚‹‚u…‚gwŠ†kapqv^rŠˆ¦•…eŒƒnw‹„q†zpfge{ƒz–[\jgnv[{ywunss‚f\mŠkkbZZ_ZYlq\_aZ_]ft~ztotckkk|}s{xtdmuhm|~vz|{zz€€~o†Š„{}s~ysiT\qiluougkhd]aXkhlkqrmW[enlgsyohjm`‹‹ª°¡£¡šžž˜ž™¨££~ƒ™­Ÿ•ˆœ¢‘¥•{˜„|’™‰ˆ†‡Šs}€‹v…‹„–Šqo€r˜†„~“„ƒ†Šz€ƒ‹› ‚§¡‡xŽ˜‰•‹‹œ—…ƒz¬‚‘—™”Šž‡ˆ¡«Ÿ¢¢£‹ˆ“›œ£™–ª¡§§ ’›‡•{wŽ„§~’‘’“œ²¦›•ž²“—„¥ŒŒ•›Ÿ‰›‚ˆ‘Šk|Žwxe‚†‹|‰„‡‹ˆˆ€„„w|yt™¡ˆ†‰žŠ„”~}Š€€uos„ƒw††Š¦ƒ…‡ƒŒ}ˆŒŠ‘ƒwl‚„}z™jrhatŠp}zwwovt]^o†hn_^Z]]ThrVc\\blhu||sopdkji€|nyqjpplg{r‚€x}„{m‚Œ†|zx|}zƒyNdvjrmpzekecb`[tfpfrqmU]ltmiyzqgikdŒ‡¹ž–¢¡˜•˜™•™¤¡ž|€š«Žž† œ‹ž–}y”ƒ{Ž™‰†„„†nx€€r‡~‰”„mk~z—‡„ƒ€†„†}‡„Ž›’‡«Ÿ„r‹†“‘‹‘}zª„’˜–œ–‡†›¦Ÿ¢š†‚‘š™˜š¦Ÿ¥–€‰v{‡Ž„¥{|Ž‘†˜ª¡“ªŽ‘€Œ‰“šž‚Ž—~†Žƒox†ruaƒ†u‹˜ƒ‚†…~…„”nyut’¡Š‹…š„„Œsˆ|}rr{‡ƒ{xŠŽƒ’¦…ƒŽ„Š‰Šw†‰ŠŒ}ol~|nhlmg_zh}{vtvu{w\_p}nu`c[]^QgnTe[^bkivz~qlldkjh€lslluoyp…yn‡€v‚€~…vq‚ˆ~{{|{‚Š`i|juhi‚ejc`i\cuhobtmlUcqyepzzrejml‹‰ž·š¡£Ÿ’‘–˜‹šŸŸž{xž§‘œŠ‡¥”‹˜™yzŒ…|‰‘ƒŒ‚‚‚n{xs…}‹‘}kh}‚˜‰ˆŽ|~†„‡}››‘‰¨œ€pŒ‹Œ“‡¡¢Š…Œ|¨‘ˆ’—“–“xŒ£  –™€š˜’Œš£¡£™—‘›~…x€ƒŽ† ~ŒŒ|˜¤ ¡“™¦š‘‰“—›~“’~‡Žtt‚pv`~€†qŠ•|ˆŒqŒ‚…†Žhwqx‹˜‘~—}‡Šr†{|qxzŠ„zyŒ‚•¥“‹…{†‡‡…v‚„‰ˆ{fr|y{qljf_~sh|uvs|s€j^`svpwdcY_^RkiTdY_ahjvyqfkdlhe€km~hoql~x‡zkŒs~tv‚†|z}jrƒnsib‡hlb_qVtomn`xhmWjtvcuz{rbjoy‰ž²’¥¥œŽ˜† ›|v¥¡Ž˜€Œ¢Šˆš–x{†‡~ƒ‰ˆ‚q{tv‚…~Š‘xgc}†—Š‚ŠŒy}€ƒy–•˜–– ›~pŒ‚‘”†¦›‡‰ƒ¦•…“‹–—“’w‘ ¡˜“–y~Ž˜—Ž–š¤˜’”›y…‚w„–~‰Œr—£ž¡“™Ž¢Œ‹ƒ–˜ƒ’–™˜Œ|ˆ€vq}nzd€|Š…p†“‚l‡‚€‰„euo{†’—Œ|“wŠˆ{…|{q~wˆ…y„‰Š—¢•ƒ‹wˆ„ƒ‚w|‚Š†w`yx}txgleaijwstu}q|bcasnurmaZa^[leRcX`ahkvy†qcjcmeh}ƒlhuhlpi€}‚ym†q€„ƒt|ƒŒ€~z‚ƒ~|mv‰ttmeŠljbcuV„iqn`xglbjvpfy|yq_ql†…œ®—¦¨ž—‡†Ÿ“—™}xªœŠ™z—‹Œ˜y{€‹}|ƒ|€‚xtyzt}€„‰‹€d^}‹•‡…‡t}~Š}˜„—”—Œ¤¢˜s‡{”’Š§ŒŽŠ’ ‘ƒ‘”—‘‹˜ š’s’”‰ž¦˜˜•–sŽŠk…—™z‡ˆ‰o—š£“•ŠžŒ†‚’œ’’•‡™ˆ|Š‰yqzkul|~‹~m…’‚”xp‚ƒ}~Šdri{€–—„~sˆƒx†}vw|…€|‚Œ„Œ”¤x„‚t‰‡}€tv‰„oa{uzq}obocd{bnovsxwstau`oluno\\_^^k^P]Xcahmt{ˆk_jfjchwˆnflhjlh}{wnˆs„„}t†‰{ƒ}z„}}Žrz‹xxnl‡jh_irb‡hqoevgnlayik}{xpawm‹€™™ª £¨ŠŠ‘†‹ž‹•˜~w®™—}Ÿ“‘–”ˆw}{Š|{€vx€ptt{o…}€Š|a[~’†€„„sz€‡z’ˆ’‘œ“¥œ•‚}‚}Ž‹’¤‰ŽŠ—š…‘˜“–ŠˆŒ’“‹Œnƒ‘ˆž™¢¡—–‰–nˆ™ƒf…˜Ž“zˆ„Šp•š”¢’’‰‹™Œ‚ž}’’Œ™Ž{Š„‡srukpnu{‹tn†Ž’qu€{ˆ|dplx}™“}„ˆtŠ€s‡yn}€…{…‹ˆ„Œ•¨Œz‡|~‹…x~qp†„chytup|b_pakt^pj{yxlspex]nlsmsXZ__bkZPWXecgqq~‡f]ihgbgqndigdihzwuoŽ…t‚ƒ{u‚ˆ…x…|xƒ…z€‰w‹{zrxƒjk_pht€jromqgole|cn€zwqlwwŠ~¢—¡¨ ¦›‡ŒŠ‚‡“uª•“Ž‡¡Œ•“€t{v…xyrs{…krpzmŠv€‡nq[X~‘ˆ€€€wu€ †‘‹’˜¡•˜xŠ€‰œžŠ†’—–…‰•™–‹‹Šƒm‰‹Š–¡œ˜”…˜‡j„£‚f…Š~‹ƒ‹w“˜‘ž‘‰‰•~˜|‘Žš’|Š€‚nuplmop{…isƒŽ˜Šqw€t‚ˆ‚xfrnu™Ž{ˆ„z“‘yv‡soˆ{…‹zŠ…‚ˆŽ›£‡{ƒu‹xyol„‚^rtrppxZ^p`pj^oj}zpmmjlv`pojqmZXaabnXQTZfgcvo„‚b]kmdbfk’n`ff_gkursp‹€uƒ€xu€‹€y…w‡†wƒ…|‡Œ{vŠjqc|c†|nqltjholvx_qy|tut€‚~¤•š­ž§–…„—”ƒ u‹ ”“†‹›Œ•Ž‹zrxt‚pr…squˆkomumˆvƒ~€mnUQ«•‡‚x€wsƒz‚ ‚’‚““˜œ“šx’{ƒ“¤š“Ž‰•˜’„†—™Œ”‹‰ˆž„Š|s‹…‰ŽˆœšŸš–”“~h…œ‡g… ‡‘„‘‚‰qƒ‘—›ŽŒŒx{’zŽ‹Œ’–Œ|ˆ|€kvjnkll{~az~Ž–‚wz€xƒŒ|ygsls‡•Š~ˆ†{“qyƒovŒz‰‹zˆ}‹ž„|{w‚‹}wqjl‚ƒz`xpnlrtV^obr`_lnyphoffsthpkawe]Vf``rSQN\fe]ypˆ|_\hrbbef’j_hd[gp~pkqtŠ}v|…€tu~Œy{†xˆƒs†…~Œ„{y•xfrjƒ`ˆ}ookz`jntu_t}x†xts…|x ™±œ¥Ž‚Šƒš‡€Œž‹š“…ˆ˜ŽŽ„wtvs€po…spqƒojivnƒn}}musRM‚ßȒ֓|puƒv„ ƒ“w”‘™œ™{”s…Ÿ¡““Š’›“†~––ˆˆ‘Œˆœ~Ž€xz~ˆŒŠœœ›•“zugˆ‘†lˆ¢„‘ˆ—‚…cŒ‘™Ž•Š—‹Š‹qz”ˆ{ŽˆŠ“‘‰y…|~l{erokkyy\€yŽ€{}~†ŽzzhrjsŠ‰‚…„|”Šk}~n‹~‹‡|„y•š™Š|vxƒxsmgq€„mjtohjtnS^odpY_kqwfkjbfxropc_w``Vk_^vPNKagc]zp‰t\\ev`aeeŽcafbXissmjqvŒ}ty†‚uv~‹s€†z‰~r‰‡‘‹ˆ|~˜vesn}eˆ~opk€Zlnyysavz{vrwŠwyŸ‹›®› ‚…wˆ•~}Š‡… ‘…Œ˜„“Ž‡twpyqn„omn~rdexp}mz}jhkc¤šÁÜ®ï¡slv„v…£†’o–‘• •œ’r…‹£—‰Ž•Š–ƒ€•…‰€‘Š‰–~‡{u‰x†„œ›˜™ŽvŠvn…ˆŠ}Š¢ƒ‰œ„…^‹“—ŠŽ‰ŽŠŠ„‰m{–}ˆ…‰‘†v…}}k}dxuinxsXˆz’‡…y~€€…Œ~xeri‰Ž‰‚‚‹–…kum‡„~‚z•“˜uswˆusqguzƒbtmpbivgRaqglU_ntyard_h}prnZcrabWnY\xNMLdgb^ws‰m\\dy^`de…`cc^YjrknkrwŒ~tw„xw{‰qƒ„}~ˆ{t‹‰‡–†Œ~—shuqym‹zntp€Wqzvyqewy†Œhv€‰rœ‡™§œ£’…}pŒ”xy‹„…¡Ž|–€šˆ„{swpsjokim|u^axw{qu{g`d|ëÚµÉÃ܈sltw‹›‰Žj˜–“‰q…‰ „‹•ŠŒ˜“|“ˆƒ‰{‹…vxƒ„s‡‚“›—”—†Œu‡p„‰†˜¡‚“‹žƒ‰aƒ”†‰†‰‡‡j}”€}ƒ„‰Ž‚q†~qwhvriswlZŒ|’ƒ…}ƒ€„Š‚uaskˆŠ~~‘}mkx…Ž…‘ƒ||‘’–ˆnqzŒ†ulqlry`tin]kv`ReqifS`pvt`o`]h‚qsiWghbiXmV[uLKLfg_brs…i[\ey^^dg{`d_]YknfoisxŠ~ss~zvzˆs…ƒ|€‡vwŠ†Ž™Œ‚{“ulwuyx“tnx{|Xz†q€ogxw’‚cv†…qŠ–…™¡š¢Š‡so“‹rwŽœ}Šš‰‰|Ÿ„šxrsnodr~hflwx[_y{{qq€jagaÕ¶Ž¦xnqw|q“‘‡j™Ž‰œ’Œ†{i‡‹™†’‘†‡˜|Š{}ˆ„zt{ƒ{q†€–šŽ“”ˆuƒ…uƒŠ’œ…”ŽŸ~ˆa“‡„ˆ„‰€ƒg}‘€~‚ŒŽ~m‚|‚tkmwtsvukc…~|„„ˆ~o_rp„{ŽŒ|~ˆypƒfy‚Š†‹‚{„}“Ž’ƒnoyŒ~umokl{~chkjYnvZRjribQbrwlbe^Zjƒmsb[g_dl`nU[pNHOge\gnq€l[[cs`\clwde]]Zklbmjtw†qp{}ux†x…‚}€‡uy‰’–|‰†v‰pwy{„“om|w^ƒtmizt”sgs‡|r’‘ƒšŸ› †ˆvv•~mv”—~ˆ‘„ŠŽš}Œšv}vqoljau|fbiuzZ_w|zmqedhgW^qs–¼Ä„vq”‰~s˜Œ†“Œˆtkˆ•€{”‹„›Œ|‹†}|‰Œ”ˆu‰…uv}qu†ž•†•‚‚r‡tƒ{‰—œ–†“œ€ˆe}’‚…ƒ‰‰r‚~g}‹{y‡‹}i€}ƒvfoxxsvslj…ŠŠy‚€„ƒj^qwz}Œ‰…{€~r€hx‚†Š…ƒxƒ|€—ŒŒ}nlz‰}wtoih}we]qcXpsSTnsibNgtxf`]\Xn€osYeb]jm`pOYlRDThaZknm{oZ[^lcZcovdg\]`kjclisvƒqn~{tuƒz„‚|…v~‰–‘xƒŠtˆsyyŽoo|qiyz~mm|v•kjx„tk”…Ÿ˜ š…ˆn}Œvjx˜‚Š‚•˜Šz–ozsqljd`tzh_er{Zar|yfpzaeeŽ±²wJbZ¤ÙЗr{‘‹‘x~•‹…™’†ol†’‘zy’†„™Š|‡xx‰Š„–€oŠ‡qt}{jy…ƒ¥‘„“ƒo~‚v‚x…š˜“‹’”…‡oz’ƒ}ƒƒ‰ƒo‚xh€…xrƒŠ‡|e}~ƒucpr€hxqou˜…‚Š{vx€„yj[p|r€‡„‰}…ˆzˆr€mpƒ†Žƒƒrƒx€™Œ„wmn~„wzehj}r`YwZYrmNXrsf`Jmvta][[Yt}roWg]fjp_oNWiR?Yg_[pjgyq\ZYkeYcpy_h]^elhfliqw‡om}€up{€‚v…‰—Šq‚q{†}zz„”Œujzko~t}or|{”po€xf’Š‚¡˜œ’‚…g‡„phz—‰~…‚™Š|ixrklf_aoym_boy\dlƒzaqv_eeÕ뾋2:>‹Ž€ry…ˆŽv„˜“Žnl…Œu}…‚•ˆ|ƒxnv‡…ƒ—wnˆ„lu{tfy‚ƒ¨ŒƒŒƒ}ntuƒy…›‹‘’Œ‹†~{’‡x€„ƒl€ri~xm|{Šƒxby„qdqh~mtqt›‹€…~su~€s€o[k}tx‰‚Š{†|ˆxypkˆ‚ƒ‰qx–ŠŠ~tmjv€€uu\iixqYW}SZqeL[sre[Jpwo][ZY]t~thYb[genbiLWfQ=^f]]vf_tp[XTodZdpyZh^`gmgilipx}Žlj‚„yn€{}€‚zu‚Œ“…p€‹nw~€{{ˆ“‰h{~kt|r†{sw}Œzx„~|kŒŒƒ›–Œ€l~ki{~ƒ”‚}Šˆkuqghc[bgso_altahp‰zast^cd› n\5Y¯µuj€‰}’†v†˜‡uŒŠwpl…ƒ‡ty‰x‰}“ˆz~rgvˆ~}—op†}hwynezˆ„¥‡‡Š~n~u~€|‹˜†“—ˆ‹„‰|ˆq{}…|i~mj€{zjzv‚‡€r`w~qdrgu‚mu{…•‘|‚owy|t~mWm~vsŠ†w‡u‰yxrmˆ€€„r~|}’ˆˆznmim‚un]hftrR[{N\q\O\rodVKsxjWYYZaq€t`]]`fdhhfNZhNAad[`va\umXWRtaZdnrWj^bhkgmlipw|’li„Š}}p~~{‚zw€€‰‹„r{‡oqwƒ{Šƒj~{nxywŠw}x€‚‡ƒ~zm…Œˆ˜£„ƒ{vŒykm„‰’y}{‚‘€€}Šƒpqpcf^Yg_pp``hpfjoŠuato[adiv{¾œ¦£È¸r…ƒs”}x‡”„t‘ˆrsp„{ƒsu†tˆw”‰yyqcw†y€“ir„ufwvcj|ƒˆž‚€ŽŽ}r~sƒy‘‚w•”‡‚ˆz‰‰kxy~uhzikysizv€ƒ}h`w‡~jjsh{€ivŒ”~z~~q{v{t}aUu|rs‰ƒ‚|‚p†‰wxpo‚‚‹~}x}|u…ƒvhqhlˆ‚rp]hctnKevL^oUTZsmbQOtxaRWX\ap‚s[`\hedcjdP[qIDda\dq^\whUVTw^\enhVl^ajgeoohpw{“niˆ‹y~r{~y‚‚|v}ƒˆ†ƒpvƒrmw‚ƒ~‰‹”p€|xyz‹tƒx‚„y€vo~‰‹›žˆ}†zw‡|ht†‘z|‰†„v€gom_d\XeYmsa`aqllh‰n`siY^dm€w©ÚªÇ†‡²rŠxpu{‡z”Š€utu~w€pq~m…t”†xtl`zyˆŽfqƒogun[m}“€y’’}x{m†u€‹ƒs•ŠŽ‡……{…muvnhwem|vmjwv|abx†zhuuc~zgt†ŽŒ•{t€uq€z|lYUr}otƒ†xkˆ†sxjtƒƒ}z|w{rŠ€|sgsem‹„mt[j_veHnoL[cXWVxmbPStvXPUX^`q„o\`cmdc^nbT]rGCf_]fh^Z{bRV\u[[gkaVk_anfflqhpvxŽtkŽuvx}wƒ{t}ƒˆˆƒoqtqu~†‚‰Š{wx„|}…‡x‡|}~„€{~svyŒŽŸŒ‰z‰wuƒy^~†šy‡ƒt††„w‰{bnl[b[[aVjtc`[hopg‡raqfW]ck|Ê·¹¢kmn‹mr…r}…‹{’…zytyuu{jmuc„v’‚wpg^|y‹‰eqjjqcXm{†œ‰ƒ‚s—”w~{m‡p€‰Š†p–Žˆ…‹ƒzy~qqo}ghrbmxrjlqw}|z]ey€wiuxf‚vgt‡Œ”|r‡in~€ym|]Wp}msŠ|nn‰pvgv~€~u{qzs†{yqeranŒ‚lsXk_x\IolMWV_TU|kaOTurQQTV^bt…h\`kjfbYnaXbpGAh]`f^]V{^OVdpZ[jh]Wg`_rfjhrgpsw†xn•Štzw~yƒ‡€us†…Ž‚pp{wwuy‡…‡Œ†z|u‹~}†„„‡~~}‡|xuyw‘“Ÿ~Œ}‹nu€ydƒˆ—†t’Šo……‚zƒtcnjY_[]]Tgse`YdrrgsbkdW[`ix¾®{Ÿ·nbs‡ht|rzƒ‡{~€xxswo{vejna‡uŽsjb^~xyŠ„fq}hjk[WoxŠ£…q™“q€xtm†r”‡Œ‡ƒˆ…}ytrohyajm`mvkgklywzw[g}|xes}n„teu††•~p‹fkzƒtltb[n{kt|‹zft†}mpgt~w}~r{ky{ywpelam‰~mnVk`wVKklOROiNY|gbNUukMPTU^gvƒf]aphg`Wi]\khJEjZbdWYUyZNWnjY]le\Yec^tfldrgrpt€xp™…v~x|…‡}us‚‡€•‚nsxzzss…‡ˆˆ„y}v}„‰Žƒƒ{~‹ƒ{w|wwš—zŠƒ‡iv~|l„…”€r‚q†‚~‚oflgW][\ZSdpe_XcruivpeebW\\h€por€s‰eeyjtvssƒ…x„zwtunkzpbgkg†t„nf^_|o{‰~hlwfidVWrp§|„|v–s|r{ymzz„v—{‡†‚†ƒ}uprmgu]mh_ludgfizo{rYgvuhp€x‚uaw…‹|”n‹jmzqese`lygrv‰z}auƒvikqtzpyxr|e~~~xvnceam†|mkVjbqTLikPLNpH^{faMUtdJNSWajw~e]gsie_VcWbp]KKkXcbUTUsWMXudZ_k`\Zce_wgmbpisoq~ut™x€x~…„z}v‚ƒ~˜…nrt{ztq……‚€z‹uu‘€}”Ž€…„|~Œ†z~€v{£¦Šyˆ†…lu|{u„‚Œzo…sz…}‚ƒunjheV][[ZScne[Xat{jimh_bW_[i€iko€glahzykttto†‚{€}vunzhjyj_enhw„geXbwi~‡zoioff]UXoh§vz|‘Žxuo~nqtxŽ~w”t…‚…ˆvjrvgho\me^ms_gajxh{m[mƒstjo€~yw`v„„x…sˆqpyqcph[nvdps‡{xar€pgixsqkwvtubƒ{~wupcccm|}kkUibgTKlhPGRlEaxfbMTr]JLTYdkwze_mpid\V_UooWJShXf^XMUlTK[y_[_k]][be`zhlaoounowuz—}wy€‡†zyzƒ}“„qtt~yvt…ˆ}€}ls•{‚Ÿ…‡}€~†‚€Š{v„¬Ÿ€zˆ‡„lr‚yv€‚tn‡o}€tŠ€jpmddX_ZZZUbjg[Z_u‚i^nl\aV\\kert}ij]lwvgtwrn‡|~~zvslzgixf]drgzw’ccTeog‚„wvfhi`WVYhd§n~x€‹Žzpp|fxnyŠzvŽqƒ}~†ndvsdhh]lb]oo[g^ltezi]t€orkq{~uuat…Š{‡‡€wru~taplYprbqq„{udr€l`lzojhzwtpd„tyzuqdadms~jlTi^^ULscQGWbGcvfaKTpXJKWXgkvzdempfcZX]XvfTJ\cXhXYIWeQHbxZ^`l[^\bd^€ij_otxnonvƒ—yr€}ˆ‹†~uv†x†Œ}tuuyzz‚ŒŽ}~„‰jt–{Š}~…y€{~|†ˆsq®Œ|{†~fqˆzt}}vro†m{~mzbpoae^eVYYWcfk`]]s†iYqn[^WZ\l{cqwvmc[msthuvqm…yywnotehte[gtfvv‘z_]Refj‚t}aci\TX^bc¥hytƒ†xlnygwl{ƒytˆr€x{xhevm`fa_j`]tkYe]onbzf[x|knnpwyttdrƒ’‡‚ˆzvoq|rawcZnoapq{seq€d^mvicfxzslmts|sqa^emo}eiThYZUNy`RKZYHbtdaITmSIKZWilr{cllscaYZ[aw\SKc]XiSWHY`NGiuX^am[[_bc]…ihanxylojvxm‚~€’ˆ„vu‰t‹†tqvvw|}~Œ€~“~px–ƒ}™’y€€xy~sˆƒspš¢{{€‰•yduˆysyvksply|p‘r^po`gblTZYWhcmf\\r‰fSrn[YXX`lvdjujj_[mtqmtttk†}€|wooleiqc[krdtvs\WTd`q~q‚\ac]SZ`\c“Ÿerq„ƒtkjylnoyyzq€wryzzdfug^b[ah\^whWb]phaxa[{vjjrowtstip”ƒ†~„vrjp|mevW[jmbpr€zseo~[`oqb^io|lks}rpxkp`[ekm{agTgUXRQw\SPYRHcsb`GVkQHOZUkkk|emoqa[ZXYlpWROfWWiSTFZ\OIrtX_cmcXa`a^Œjcdmyxkoiuy†{kƒ}€…™|‚„y}ˆm†qowz|t‚‚}‹ƒ‚–tx‚“†Ÿ‰ut‚p‡‚uo¢—t{†‹‡{fw‹on|pfxq{lsvsk^tnagekR][Vhbll[\qŒdNon]VXUgithctee]Znunpuuzkˆ}€}ˆwscekna\nmcsx‡kZTVbcw||p…\c_cT[`Yb–•cnpƒ„Šsjgyneruqzkyttnz~u_fsc[^WbdYaufU_`mcaq]]~ohisqspuukl„“‰{…qrfn{oqnSZejeqs€vsblvUbqk[^nd|eku|rrrjm_Ycijx^fTeUVPUnXRWTPHer_aFXjNHWTVmhd|ikwjaW\U[tdSRVhQYfTSHZ[PNxvZ^eliZb`^^nbfkyunnivv~mƒ€~†—{‡‰~k“ˆrgt€{u€ƒ~‰‹“r}Š‘…‡Ÿ†{†Œs€†s}‚un¤Œs‹wxn{`d|qgysymmqvƒgd|lcfghS__Ug`lo\^nŽhMim`UVSofslexde]Yqumr{xsm‰|wœ{zlbelm^`njepy~gZVX`kw{zoƒ^b^gVY`Wcœˆbkq†|wkjvl[upjyiurmn{€rXjn^Y]VbdXeqcT^bibbmZ`~kfksunmwvkh…Œ‰z‡mqfo{lqlbX_hhos€ss^imSepdUbnaybou{ujolj_X`fhu]eVbVSOYfSO]OOHeo]cGZiMI_KXmd_xhn}d`U^T]t[TR_fN]bTSJ\ZQZuu\^emhXba[^Žqcgjwqsmgvsyƒsƒ{ˆ~|ŠˆŽynŠtlssˆ…‡’„•z}Œˆ‘›„€|Œ„rstwqn““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|}~}}~~~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’‘‘‘‘‘‘‘’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’‘’’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ”ÎÚØØØØښ„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDBK’š™™™™œ[ADDDDE9/0000,H…ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ”Ûéççççêœ~‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR455553?“žœœœœŸR155557':ƒ€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}zzz|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹’—˜˜˜˜™™’Œ‡‡‡‡‡‡‰““’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†…………†ŽŽŽŽŽŽˆ†††………„ƒƒƒ‚‚‚„ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z{|{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘‹Ž‘‘‰‡ŽŠ’“‘‹‘‡‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…Ž…‡‡Œ†‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰ˆŒ†…Ž†‹ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰ŒŠŽˆ‹‡‡ŒˆˆŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}}}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹ŒˆŒ††ˆ…‰ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz|||{}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒŒŽŠŠŒŠŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzyz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{z{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†…………………„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰Ž‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{~~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““”””””””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’“““”””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••””•“’’“’“••••–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””“’’“““’’‘’”ˆŒ”“••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’‘’‘’“wŒ“’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’w‰’‘“€uŽ’‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘’yn’ŽtvŒ‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘‘gx’‡uw‹ŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚ai†zhtŠŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽw`kbgdn‹ŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹Š‹‡don[jrl…ƒ„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxz}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzoq{xy{|{xw{xuwttvuuvwpcppdkrqdhklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkiffggghhdeimsprukbcbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__ac_\_]`]^Z]`aclnookZY_[XWSNMKKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{xvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSTPMJMNPRONP^iflnkgcQPSPPNNOMJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTtsuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNOLLUdmfjmkif\SOOPQONNONOPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKKGIOU`hnhklkijhd_WONOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEDR]bfhjnlsojijlkieUJJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:;>>>KV\imlnysjjlf[QJDDEEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@:;><;;;;GJ=FYknwpkiYGDBEEDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnpprttsqrvyy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;:;;99:88;<979;;>=:;F[nm`IA>A@CFDCCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqtsurqtxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<:79::979::78:9:;:78Vd?88<<=@A@=;;><==@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyy{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>><==?@===?C;==>===;EY9;<>=>?@A@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquutusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCDA?=>@A?@;]n@>DE??A<D[===;;=>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVppqssttuyz{{|~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???BFD><<=@=8:;mwH8;:==A<I`<<=<8:;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pprrrtuvz{}}|~~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC?>AAABA@YR<==IMFFvwM788:;>>Ug@;<<::;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvvw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC@CsyI;]ƒy|wV<=?==>EitK:=>?==>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hloppqtuvy||}||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCE@Hrykb‚„ƒƒƒ€}]>@C@A=Is|Y:=AEABBFHC=<@DDA@?>=@A>>>?<>@DGE@>@A?@CFECBCC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{{{}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@Fot}‚‚ƒ}„uLACE@?>Y|€]?CEIJIIMMKECFGGEGEEEDDCA?@>>BFJJGEEGFFJNNKJIGGHKLIGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@EEhs}|„~y…qBDEDCWu†‡‡~XGHJMLNOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHHHGFEFFFDFHGEEHHFHGHFQnnpqrvvy{{{z}}~~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJG`{€w„…ƒ„ŠlAAVt‡‰‡‡‡ˆƒWHLMLMNLIGGGGDGGGGFHFHECDDFEDDHHCCCFIJKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrsvwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLLN[|‚‚ƒƒ…††ˆƒVl„‡†††‡ˆˆ‡|PKLKHGFFDECC@ACCCCFFEB@>>@AA@BD?>?DFHDEGIJIJHHHGIIJJIHFJJJJIJIJJJFILLKJKKfopsrtvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKLLJUƒ„„‚‚…††„‚†…„„†††‡‡†ŠuIIFB??@???<<<>;:<AA@><998<<=;>;9;?AB@ACCB@ABDDBCFHIHHHLMLGIJMMNMJJKKJLMSlpqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHHJJIe…„„„‚ƒ‚ƒƒ„……†ˆˆˆˆˆ‰ŒŽfBB=88::9878896479;<:8567789787688;;;=@;999=<>;;=ACEHJMLLGIHORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@CGIIj†„„~ƒƒƒ‚ƒ„†‰ŠŒŒ‹Š‰Š‹Œ‰T:8656766645773568:876565676778:67889;7578979876:<@GFIFIFEFOSRSSROPPRTepqsttwy{{{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:=ECBf…ƒ€‚ƒƒƒƒƒ…‰‹Š‰‰ŠŠŠŠ‹‰Š‹G676468874578567699766765:9:;:;898987779:98878689;A=>>BA?AKLOQPQOOORWkqrttuwz{{{}}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897;B:=q„€ƒ„„„„„†‰ŠŠˆ‡ˆˆˆŠŠŒŠ‰‰Œz>988;<=>9::<9:;9:;:99;:9===>;;<=:=;9;;<;<<9:<8::;:999<?<=ABDIJMKIKLWorsusvx{{||{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<;89989:::;?>H~„‚‚„………†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>BCEEAA@B>@B@@?==>@?>?@?@==?B?AA?A?=@@@>?A=><;:;99;?=;<==AACABCAXpqtttvz{{|}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::<=:;;==?@BR‚‚‚„…„…„†‰‰ˆˆ†††‡ˆ‰Š‹‹ŠŠŠ‹Š‹^>DGIKJIFGGDFHGEC@@CECB@BCB?@DHECEDEEAFEFDEFD@B?<@>=?@>?>?>?>>:;=<`qrttuwzz{}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>???=A@CCFW„‚ƒ„……††‡‰‰ˆ‡†††‡‰‰Š‹ŒŒŒ‹ŠŠˆVHMLMKNJIKIIJJIECDFGFDCEFDBHIKHGGFGGEKIKIJKJCFCCDBAACBDCCDDCA=;=@hpsttvwzx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€OA>=?DLK@BBA98<>;<;>@?A>BBGGJY„‚ƒ……†‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹‹ŠŒPNPNLNKJLJIIHJFDFHHIEEHFFELLMIJGGHIJNMNLLNKHFGGEECFFFFDEHHFCA?@Llptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?EGG=<@@88<;<=:>@>?@CFIJQ_ƒ…„…††‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒ‹ŠrNRONLLLLJHGEIIDJHGKJHJGGGKLNLLHHIJMQNONMOKIGIJHIDIHHFFGGHGCBACUnpuwwy{xyzz||}~~~~}~}~~~~~€€€€€€€€€€€€€€TDAABGGB?8?@8:<8=>;=A>?ADHJLUqƒ„„„„…†‡ˆˆˆˆˆ‡†ˆˆˆˆ‰‰ŒŒ‹ŒŒ‹‹‹‹‹_RRPMNMKJGEBGJGLJFKNKKJJLMLOPNHIKLOQQPQOOJHJJLJKFGHGEFIFEEBABB\orwxyzzyyzz{{~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<9@>>@BGGAGKLPVy…ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹‹ŒŒŒŒ‹‹|XVRRTROLKJDEFKONOWUQPORSRMSTOMSLPSUVRSQPLJMMMKNGGJFFHJDDEEBDCcpuyyzzz{z{zz|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?==B?BCGVNFNPPTX{†ƒ……„„‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŽ‹‹‹hWUkaERQQPI;;RTR`u]UVTVYYRXXRZfPUWZ]RTWQONRPPPQKLKHHJHEFIIIHIirvyxyyz{{|z{|}|}€~}}}}}}~€€€€€€€€€~~SHJIHGFFE??AAEACGEDELXRMTUVX[|†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ}aŠ‹‹‡l[dU:XXXSQ?@VUY[c`VYbr]]V]ZVEQYZ[Y_TYgRVVXTTVTOOMJLJIILMKOMSosvxyxwzyz{z{|}{~~}~}}}~}~€€€€€€€€€€~~~VJJIHGEDDBA?HMIMPKIKPTSSXZZ\\x…„…………†‡‡‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~‹‰Š‹znpXZ\[RSRVVTZZtƒYU}`\X]^WIV]][[_YHYXY[]XXYWRQMPQMMOSQQURassvwwvxxxz{z|}}}~}~}}}~~€€€€€€€€€€€xy}YNKIIHFBD@A:PQQWXPPOQSTTXXYZ[n‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡ƒŠ~fYY\YTUTWRQWUb–€QerXZW_hP`f[[X\gaGOZhg\[\]]WSNSPPQVVVVYZnrtwvvuxxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZ[RSQORRRUSVTW_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PUXTRTRQQLOLKfy[]TYUV]ZLTZUST^ZXWWWzkX[[\^TQQPINOWVX[Zdprvvttvxyy{{|}}}~}}}~}}~€€€~~zxwvsu{€€tk~~kry^[VUSROKFCDAM^ƒlVRSNOQOQURSRRTcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ymqVIKMNKMKHJDFHEC>TdURPQNKRTQMOYRMNQSUUMQSRPOMLHCIHRTUZ\lquvusswzz{{{}{}}}~}}}~}~}}~~€~{vsw}~~du}iqt_d]][YVPLILIal’tPQSNQRQR[RSRQRVTbs{|€‚}{{€ƒ‚…†‡‚†††„†…†u_]KC?CCCCB?DPBC@C=CIGV@HNLG]iPHFOFDEFIGHCDHGHKGDBAD@NQMRdrtvustuz|z{{{|}}|{~}}}~~€€€||}€€€}vt{mh|gnqfiedb\XSQPURsWe[OONLQSQUYSUQQTROV`klrv{{xytrnstsyx~~ƒ€ƒƒ‚€‚€‚‚kMG?@:;>@@??>jQKaEFHIEB?GLNGMQUIBE?><=<==?=?ACC@?<=B>JMGUnttustvxz|z}{|}}}}|~}}|~~€€zywxwvvx{~€~}{xv|uaxglpjljjf`[QRZ\Y^JJPQNKLQRQTUUWQQWVPX[b]agmmlokg`nrjmlqu{z}{xz||xwxeC@@B=:BCAADB\]O{NONNKLMOOQLKLWMHG@B<977599=;;;8989?<BH?\stuvuvxz|||}||}}~~|~}}}~}xuvz{zwyxuw{|yxuywcqhipmnmmhf^OP^\ZIHPQQOMPQNQRTVXSRYTNYZ[WY]^^_e`]^qvk^`gkwooljonnlfbYHFFHBAGIEEFDMRPaWRWQPSSRU[OOQWPMIDF>:96587979:365795<B=essvwwyz{}}||{|}~~~{~~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZWMLTTSQQUOLRSTWXTTXQLWYZVXXVXY]WXXhsk]Vaskaa_^da_^YTQNNNLIHJKIIFCQPS[WTTNQSYS\eUOSTQNKIHC?A9998978857578599Gnrtxxy{{}~}}|{}|~~~z}~|}~}~~~~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPXVVSTVOOUVXXYSUTLKTVUUUWPTUWTUR]n^RNY_[VY;DVXT[fJLORROMMNNMLJFQPUYSTOJNOUST\VRUSROMLIHHF??=:887659967675Wpptwyz{|}~}~||}|~}}y}}|~~~}||}}~}|rvqxxrvuqqnppopuvtnjddjppqrpnfedc\^RTZVWUTWTRXXYYYRUOIGOPOOMRJOPOPNNOTLMIPOSTU2=XMI@Q=caQSQPNPQPNNMQNTRPRMILJORPRRSTQROLLKLLHCBA=::876;B5566:doruxx{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqptuvcjgeWhtrrqniihpVVTUXUWURWVUZYXWUQSFEAFGGHFJDHJHGEHLHKIFLMPMG/E_R>3?>joaRRQ@GUQPQPQNQOPOLJLLOPNNPQQNPOJLMMKGEEDB;=<<9=G6677Dmptvz{{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknaePSTRSTOWVVYYVQQQO@=;=?ABAC@BDDA@GHGHFFHJMLEGCORC8ENS]fSQSAGUPOQQPMMNMKLKLNOOQMOOMHLLIKKLKGFFED<AA>;@E;<89Spruy{{{}||{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpknqmimcLOOMQSLTUTXWUMLKI<987;?@><=@@B=>EHGCFFIGJJ@FAA@FHEJOHPRb\QPRNSOOPLLOMKMLMON[WKMQOGIHCHJKLJFFFD?BC><BG?B?Adptw{zz{|{zzw{wy~~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHDD=9879?B>;?B@@>ADIECGGIFIEBB?>=CBAGIDMObeQMNNWKLMKLMMMLKNNSdNJLRIIIEAHJLMNJGIFBAB@?EFEHDKnovyyy{{z|zwtxtx||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGLMIMPMPOHJD?A=999:?B?<@BBADEHKFCHIGGHCC?B??@A>DECKNRTLJIMTGIIJLJKLIJLMOPRPKGCLGCBJJLMONIJIGCCCDIJMLIYrmwyxz{{y|vrpurtxyvxjqojllnttmtu{stxronqovsnporpopstyjN`gsjt|ygosqiqhdqHKDGHHGJKIJKDGB=>=:::;AB?=BBCCHGJLJDIIFGGCC;A@B>@@BECIMPHHKGHKDHIKMHJLHIJKJM\RHHDNFADKJMMPMKMJKFGGJMNQNLbmivvw{x{z}qmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoiktgdoFKCFEGEFFGEGBC@=<=9:::AC@>BCDEIGKJLFIIGFFDB;BCC>@CCCEGLNHKNHDHEILNMHILGFGIILNKIHENIBFMLNMOMNNMKIHIORQRNRfffqosxu{z|lhjnekqlsqfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGJDFFECCCE@DB>@?:;;=:=>CA>ACEFJGJHKHGGGFEC@=EEB>BCCCEGHIGMPJFFGKNOKFHJFEDEIJHKIFHPKCIMLPMONOONJJHMRUTROWd`amgproryzgehhdilfqlflmgiklslpvutpnvrosrsutqssutsuvvvyvutwljuumrvqlnlerLGEEGCBABD=BA>A=9:=?:=>@B>@BDGJFJFIHFFGECBAAFFCBCBDEEGGHFLQLIOJJLLIGHEGFDCIIHKJGKRMBNOMPOOOMNOKKKPUWVUTX_^\iaminhrsbefedihfnifmmhkkmriqvusqmvnoqrswsrstuvvvvwvwvvtwujsunutsqrjksMGHFHBB@DD<A@@C<89=>9?<?B@@@DFHEHFFHGFFDCECDIECFEBEGEFGGEJMKHQMJKHHIEFHIFCIJIKMKOSNDQRPQRNPMNPMLMSWVWXVX]Z]d`hbjigk_eefcgggkggkmkmlprhttursnvoqprtxqssuvu‚‘yvvtxuuwxmouorsuqqioyMHGHHBBBFE<?BBD<7:>>:>:@B>??BEFDFDDHFDECDEFGJEEJGCGHFHGECFJJGMJLKHJLFIIKHEKKLMNORTOHSUSPSOQMNQNMPWZVZYVZ]ZXa```^hec`dfhgjihjfhnllnmqpiuuxrrpupppruvpusuvu{~}xvtwvvvxplupmstnprrxNIHGICACHE<@EBD=9:>>=<<AB<?>ABFCECCHECEEFGGGIFGKHCIHGIGFDHKIGKHMKJKLHLKMKJNLONORUVOKUWSQSQRLOQPOTYZY\ZY[^^^`c^\ackb`dghr…hgjfjmnponsrjtuxrsstrnpqvrquruus~yŽ}uuvvvvxrhuqkrtlqvotMIKHJFBEGE<@GCD@:<>@?>?BA<@>AAFCEEDIEFEGEHHFHHIKIEJHHKHFFLIHHJGLLLMLIMKMMMOLPPQUVWOKVVUSSQQLOSRQV[[]^[\^__a`ad]d`ef`ehjcssfjhglprqossnswwquvtsmoruorspurvrtvuuuwvuwtgtrkqrkrvnvJKLJLGBEDE<@FDDC;??A@@@CA?B?ACHCFEFHFIFFDIHGIHJMHHJJILJFJKHIJJGKKMMJJMLNNNPLOPRTXVMNTVTRRQPLNTSRW[^^_]]`_`aa_acebchbdijgv‹ljigmosqpqppryvruutsmmssmqrotutrpswtuuwvuuteqskpqjrvowKMLKMGDCAD<?EEEC=AACBBCDACDAAEGCHGHHGJGDGIGHJFILHIJMKMLGKIHKKNQKRQMSMKNNOPPOTOWXX[NSQW\ZRWPNTUTTXZ_bb_da^`b^`eaacingbihhnxvlhimosrpqrrrvtsusssnksqmprotvrqquvuswywutucmtkopjqtowLNLLLGEA@D>>DEFC@CAEDDFBCEGCCIFCIJJIIKGDKJGHJIIKHJJNLNLILHJLKZfJd\KlSHON_nUks[qpbwcSPbvuhucav`Xnqbdvinzf[lt`lkT_wvijgifglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqrqyLNJJJFC?@B?=DEFDCDCEEDFBFFGDEKEEJMMKLLGGMIGJKHKKIKKNLMMLLILML[sbdp^lmUMNfs]feqlntgpi_aYnnbppbkjjgoqtetno\ougpMJryvkb`keemxlkvmnpsrprqpqrqrrrtrmmsnnoprutqsstuuutwxvutbmukpplrrqzKLIHGED@BB@>CFGBFCEEFEDCHHGDEKHGLMNLMMFJNHJKJILJJJKLMNNMMJMMM[roonpplkMPQlWNibtrpamnu\YlQ\mmZqmkomxxtsip\_rkqjUuyxpc^kfbgppjjopprspqpqqrrqqrrtlmrmnnorutqtrtuutuuzvutenukpolsrryIKGHEEEBBB>@@FGBGDIEEEBFIHHEGKJGMMNLMNGLNILKIJMIJIJKOPONMKNML\hdu]lqWlNPQmUZk^klvaldsSecNmYl\tpkilxjwuhp]^rkhWbcw|oc`ggadityknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtvHMGIDEDCAB=BABFDHGLHECCHKHHFJLLFNLLSRLGLLHNJHHNHJJIHNOMNLJNMJZsppoqqmlOQRnYqkgooqqomt]nXat_nopoqronusttj[]tcwxrjnzhaacfbbjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyxtukoumtontsvsHKHIBEEEA@>DDBGCHIMIFCFJLIGFKMLFOJKWRKGKJJNIHJLIKJIHJMMMMIKKKSkb[i^_icrrZ_Yjo_eeUk_c[aaQ`lh]j\niid[pfdp]Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunwqrvtwrGGFIDEDFA@BFEDGBHJLHFDGKLIEFJOLIPIL[QJEHHKMIHJJJKIHIGKKKLGHKKLLLLJKMNT[\TPTLPONOOVQOOQNOQJINPQdqiTYW\[\UYZ]X]\\cfaaebcf__fkmhmtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyxxuvqruovrtsuusGCEGFFAEC@CHDFGCIKLHFDGKLHDGHPKLOKLWLIEEHIJHIKHLJHFGGIGHIEFLIJKNLIP\W^P\[`^MXYS\\b^MYZMXaRJYaZR_d\aX[ddVVX\YZX\VY\]b^daa_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtOBCELMBDDBEIEGGFKJKHEEJJKFEHHPJMMJMSHGEAHFJIKLILJHFEIFDFGEEJHCJMKLU_Y`X`a[`TXYT^^Z_RY\P^\YN^\^SZ^c^Z]`c`Y_b[`^[TXWY^]cbcacfhekrpoppnow††……†‚{€……††…†…uqprrsvyyzyyxxxwryvxrqxvtvaSJJMIDBBCGHEHGHKIIIDFKKKFFIJNKNLHLNGHF>GGLIKKJLKIGEIDCDDBFJD@JLJO[cY_^a_RTRW_`\]Y^QY\MV_WKQY[PZ_aa]^ca`bbbcceZQYVU\Y]c`__cdbhomnllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxXQKFCGECEHIFGHHFFJGHFHKILDDKJNMLLHJJHJG?GFNJKKMKKKIGGCD@DAHIB?IJHP]aZ[d]_TQRX]\\\_ZKW\LR\YIM^QO\_accccb\dcbdcfXQUTR[WZ`_^^aa_dlkmjjlnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMC@IFCFKJFFFHGFIGFFILJNFDKJLNJLIKJHIFBHIQMKKOMKKIHGED?ECHHAAGFET]Y^X_Y_[]UXXP]]QKJV^X^[]UY`RQ__bb``bb`cbaddbXOQQQ[R[]]]]^__dhgljnnp{{|~{€‚ƒ„………………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKCAGFDGMRHCQJFHHHEFKJMPEFIJKNLLILLIIGDHKQOMMPLMKKHICDAEDHGBAGEDWUE\T^SV_XNTUNZZMJKT`a[_X^^a]NYb\``_bcb]abW__TPNOPXR][[\\^`bffelfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDEFGDIRbPCV^IGGHDFMJPPEIIKKNLKKLKJJGEJMQQNOPMNLNHKADACDFDCAEFBMHBKLPONLFMFGIJHGLKMOPILOPOSOLQSRUZYWYXXdWOSTPPNMOUT[XXZ]\`adecgcklpsrzy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKM]LGGXLGHJHGMLQQILKLKNMUNOKKLGGKPSSNPONONOHKF`ED_LDfcEM[I^[rmOMUmYLCP`UkWgJ]XU^DMQULLSVQRTXWTXUT\UPfZhhdXSkSVVT[\[``aaab`fhfnkhrz|}~„„„„ƒƒƒ}|zr{z{‚€ƒ„„……„…ƒƒ~z{LHEGFHEEKOSIJF`SHJOJIOMRQKMLLORUROOJLNGHMQ[YOPPNOPOIJQQI|YYqsXPmHqnoaVPqqsPCksmqspSo_[nX]V\XUkhU]VcZ`Y[`VVXjtuu__v_Xa[\f[_aaaa^`bgmpl`pwtx‚ƒƒ‚}~€vxzlv~tx~€|~€‚„|€ƒz~wwNIEHMNBDLLFIKEQVLKOIKRXWQNOOMQTNOQPKKNGMPS[ZTQROPPPJHZx]TxehZRTQvgtlpbnfjQrOMwmjrpsrqrpoo€]ezuxqqzq~s}ku}bRh|essosr{|o}yor_``baZ``gknkblfgmw~€ƒ~{xw€tvzir~nt|~wx{~€ƒx|€u|||ssNKF`]GAEMMHJJGJPOMMJNV^YULQSNXZMSSRNKOIQRTYWWQTPPPQKHgxlcxrm[KMUypumubnvPdeJfvqmwo€jfxxiWrQhzmijzz~lxzohoYvvjuup`rg|ilx|o^__ba[^bdgiidgbcdllppstsssyqrxblugry{ssuy~suzn|}yxrnNKStNCCFPPHJKJKPOOOMPZ`ZXKTWPa^RVQYRLOISTUXWWPUPONRJKrouuquqdibWnLqp^FhyWvTLiy}x`y{sna]mocRhqunmypwlvttqlm]t~zkmy|ktl|kpvux^__b^]_ddighfe^abiiijknokqnmjpacfdowxompsy~nqpj{ztsomLL[VHGEGRPILMJKPQPPPQW\XUMUYUfXRRY^SLNITTVWYWOSNNNQHRmHiwK`dvvVXlOnl{sajgvULWkh}lmlx_[pz{^`zscroxqhd|ir{]ULl`vukiu{{m~xk|p]^^b[_bddgeeebZccikkrsrwglihdg`akagsrlgmmr|kmhk{tmmkmOHJKHIHHRPLNOLKRRROSRWRVTPW[VVTTTa`PNMKTSSQUVNNLMOPJHQNPULKKSTSRTPVUQQNQQXYRNPUTXXX[ZURSW[WXWZOSUWXXR]YW]VTPYRWWWWX_[gr^[[Y\]_cZ_ccdfdccbZccffemnmueegcaf_]g`dlhfgkhpzhggkujhgilQIKKLMKJSQMQPOLVUTPTUXUYUQZ]VUTWUYXPOLMVTPNUSNOMLQPKJRQKQMKKORURQQSSIHLNOQRQQQTVRXW\WSSPQUUVSZQOSRXVTYVTYUTRUTTUWXW]Z^a]\ZZ\\`c[]bcdfdddaY`acabhhincad^_c]Zd\bma^fefmsdihkkedcfhPJKLOOLMSPNSQQMXWUTUWWWZUS\`VWVYUXSQPKOWSPNUPNQNKSPMOUSNRNMNQTPTQSTUNKMOQTTRRQVWTYZ[YSURTWWWY[TOTUXUUZUWYURRXVUW[YZ_]UX^\^]\]aa^[bbcgfddbX_ab^`hefda^_]]^ZZ_Z_g`^]]bhkagfhfd`bcaPKMLPQLOTOOSQOQZYXWXZZXYV\jdVXYZWVSTOJNVTPOTPPPNMQQPRXTQQOMOSVNWRTUUONMQSUUTTRTWVZ]\ZVWQRWXV[[WQTVVVVYTXXURRXVVZ]Y]_^V^]^`\\`___ZbbdhgddbYb`a^^fcc`b]\\\\YZ[X[a[^]\_b__bdebd__`\PMNNRQMRROSTQPU\ZZW[[\YZ[dqmhd^[YVUWQLMVSMNROQROLPSRU[USPPLPWWRWSSSXMOPRTXVUUSUYX[^][[VROUVV[[WRTWVWXVTX[TSRZWW\^Z^_`Ua\aa^`b_]`]c`cghdf`Zc`a__ed_`c[Z\[\YZXYW\Y\[`^_[^^a`^b\Y`ZQNONVQPTROUTSPW\]\X^\_W\^jqwy€b\[VVXQMOVSNQQPRTRKQTTY[WUORNSXWTSURRZOPSSV[VVWTVZX]^[[^VSNTUV\\VRTVVXYSTY\USS]XZ]^\```Vb[cb^ac_\bab_cfidf^[d`a`acd_b_YZ^[\[YXYWWZZZa\][]\\Z]`W[[ZPOOOYPUURQWRTP[^_^[`\`U\]ijr}slg\UXWPORZSRQSRTUTKQWV[ZZSOSRVVVTOWRSZRTTTX]WXXSX\X^]YZ]TUNVWW^[XRUUYYYUWY\USV^Y]]`]bb^Y_[eb_dd^^cca^efidf^^da`aabd`b^XZ_[\[XXXXW[Z\`\[[\[XZ[^V^Y]POORZPZTUVVTTT^^`_^b\`U]^bkytl}lZUYUQPS\TUTUTVYWLRZW][]ROUSXWVTPXRSWSVUU[]X[YUZ^X_^Y\YRWRYXY_ZZTUVZYZWXZ\VTZ^\^`a_dc\^]]eaafd^^dc`\gdhedb_da_a`bb_`^WX^Z\\ZYYWV]Z]^ZY[\[WY\]VXW]SOPWYQ]UVYWWUX__aa`c]`T]_beeuzhXYYSVSV\XWWVVW]XOU]Z^]]TRWSWVUSTXRSVTXXX]^X][V]_X__X]VQYTYZZaY\VWX[Z[YYZ[XV]__^cbadd\b\`fadfd_`dbb[fchecfaf__aaaa`_^VU]Y[\[Y[YY][[[XXY[YZZ]_]TY]UNTZVS\TVWYVV\`abcac__V[`da_zuohY\ZUXTW[ZY\ZXY`WPV^\`a\TTXPUWVTVWRSUWZZ\_^Z_\V__Z]^Y^VSYWYZ]bZ^VW[\[\[[Z[YZ__``dbcdebdZbfcgfe^ab`c^bcidcg_g^bbcaa`^_XT[ZZ[[X[XX\[Z[WWYXW\[\`]V]]SPVZVVZUXUXWX]_badad`^YYadb`lfh^\][VWXY\\\_[Y[bVTX^]ac\RVYPWVWWWVTVTX\\^``]`\Wa^[^\[^XVXX[[_`\_XY]\]^_\[]X[`a^`dcdeefbYceeigd^ca`ec]eidei_f^cbcaa`__[XY[YZZXYXW[[Z[WXZTY]\Z`\U^bNSWYVWZX[\XWY^`badada]^Yacb_a``^\\\WW[[]]__\Z]cXZX]`cd_RXYPWWXYYWVWV]]^`a`_b^Ya]]^Y]^YXVW[\`^]_ZZ^]^^a\[[Z\_b^bdcefefbZdfgjgc_c_afeZiicfice^bbca``_]]ZW[YYXXZXWZ[ZYWXVU[]]]``bbxLXW\YW\[\]ZW\]_`bdbba]`Xbcbacab][\[XW[\_]`_][`d\\XZbec`R\ZOXXZ[[ZWZY`]`bb`ac_\b]_][^^YYUX]^_`__\[^^`bc\\W\^`bbcedfdefd\efhjgcab\dg`\iibhifd`baca_`_]][Y\YXWXYXW\[ZWWXOXZ]acffrkJYW]ZZ_\[^\X][^_acbaa]b[bdb`bbb\[[ZWXiq`\`_]\ac_^YYcedaS_ZRYX\]][Z[[c`bbc`bda`c^`\]^_ZXV[_^]aa_^[`abeb_]T\``cddfegeffe^efhigdd`[eg^ahhbhhfc`b`cb___]]\Z[YXXXVZV\ZZVVUMXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡…‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vvvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{{{{{{{{{{{|{{{{{{{{{{||||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vvvvvvvvvvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{{||||||||||{{{{{{{{{{||||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚‚ƒ‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||upooooooy~}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰Š‚E>????=u‰‰‰‰‰‹ŒŒŒŒŒˆ~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}upnoooony€~†“y1333332j‚€€€{­éääääèʉŒŒŒŒƒ:233330sŒŒŒŒŒŒ}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}vuuuuuutvwwwwwwxyyyzyzxopppppprrrrrrrwzyyzzz~ƒƒƒƒƒ„|||||||vuuuuuuz}}}||||}}}}}}}|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚ƒ‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vvvvvvywvvz{x{xwvwzxzzy}zyyxxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{|||||||{{{{{{{{{{{{{{|||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwwx}y}}z|{xwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwww|z}}y|zxxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒ„‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z{xwww|{|{z|{wxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzzx{z}|{}{xxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyxyxzzy{yxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyxyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{|||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}|}}}|||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrsuuttssrrrrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqsttstrqppponnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqrsssssro~{oonnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrrrsurrrps˜{opoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpqqqt•|proˆ vpppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqpqrp”¡ups vppppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqqo‰±‘n~¤ vpppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsqu‹‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqrpƒ³©|¯£wpqqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrrp±§«¨¯¤trqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrsssssssuŸ¢¢³¥›£zssssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz~|~~|vvwwvuxzxxxxxwxx€¥žš¥Ÿ¤£zyzyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~}|{|}Š¢—š—™’{{yxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}}~}~†¦©¤ž ›••}}}€ƒ‚€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€€Š±¨©¢¡¡«£‚~€€~~€~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~€€€Š§®Ÿ¨£ ¡¥©¤Œ|~€~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~€€ˆ–ª®¤›¤¡ ¡¡¡©ªŸŽ€€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹Š‹‹‹‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚ƒ‚†Œš¦£œš ”™¡ žž¡Ÿ’„€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒ‘‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒ„‚ƒŠ’•˜—™˜ˆ››œ˜‰…ƒƒƒ‚ƒƒƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒƒƒ‚€‚ƒŒ–™•‰‘™œ’‹‡…††‡‡††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠˆ‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„ƒƒƒ…„ƒ‚‚„—“–™…‡‡ˆˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ‘‘‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„„ƒ„„‚ƒƒ…‘—‰„„ƒƒ………ƒ„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘’’ŽŽ‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€‚ƒ‚‚‚‚‚‚ˆ‘‚ƒƒ‚€€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„„„„…„…†’“‘ŽŽŽŽ‰ˆ‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~€‚‚€„ƒ€€€€€€‰“€‚ƒƒ€€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“’Ž‰†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚‚ƒ„‚‚„„‚ƒ‰–ˆ„‚„‚‚—‚‚‚„ƒ‚‚ƒƒ‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘Œ‡…ƒƒƒ‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒ€ƒ‚……„„ƒƒƒ‚„Ž˜Šƒ…„„„‚€“›…‚‚‚„ƒƒ‚ƒ„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”’’“ŒŒŠ…„ƒƒƒ‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~Œƒ~}||‹œ€‚‚‚…””‹‚‚ƒƒ‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†””“”’Œˆ„„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~•—‰€}}}}{—‹€ƒ€“Œ‚‚‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“’Š†ƒ„ƒ„‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€€•ŸŠ~~€}‡Š}„…ƒ„‚ƒƒ‚Ž‰…Œ‚‚ƒ‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”“’’‹Œˆ†„…ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„‘¡ŠŒ…}†‰€~………„…‚~}}‚„ƒƒƒƒƒ„ƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„……………„…†…††…………………………††…†††…†††‡†…………ƒ„„„‡“““’’Œ‹ˆ…†……‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…ƒŠ‘ƒ„‹…‚~}‡†ƒ€~~~~ƒ„ƒƒ„„„„„„„„„„„„………„…„†……†…†††…†……†……‡†††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„…††”“’‘‹Š‡†‡†„‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„„„‚‚‰~}~…~€€„…„…†††…………†‡‡††…†……†‡‡‡ˆ‡‡‡†††‡†‡††‡‡‡††…„ƒ„……†„……†††‡‡††††‡‡‡‡ˆˆ‡†‡†‡‡‡‘”“‘‘‹‰ˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒ„„„ƒ€€€„„~~€€€€……†ˆˆˆ‡‡‡‡ˆ‡ˆ‡ˆˆˆ††‡ˆ‰‰‰‰ˆ‡†‡‡ˆ‰ˆ‡‡‡‡‡†‡…„ƒ„…†…………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†…†„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡†…ƒƒ…„„„ƒ€€Œ‰€‚‚€€~{z€†‡ˆŠŠ‰‰‰ˆ‰‰‰‰Š‹Šˆˆˆ‰‰Š‹ŠŠˆˆ‡ˆˆˆ‡ˆˆˆ‡ˆ†‡†„ƒƒ…‡‡‡†……„„ƒ……„……†„„„………†…†…ƒ‰”“ŽŠ†„†…ƒ‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡†„„…„ƒƒ‚€€€„„‚‚‚‚‚‚‚€~}}}}~}|{|ƒ‡‰‹‹ŠŠŠˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰‡††‡‡…†ˆˆ‰ˆ††‡„ƒ‚„ˆˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚‚ƒ‚„ƒ„„Ž“’‹ˆ…„†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒƒƒƒ…‰Š‰‡…‡…„……‚€„„‚ƒ‚‚‚ƒ~}~~~~~~~}~}}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡ˆ‰‡ˆ†ˆ‡†‰‰ƒƒ„ƒ…„„……†ˆˆ†…ƒƒ‚ƒ…‡†‡††„‚‚ƒ„‚ƒ„„‚‚ƒƒ„ƒ„‘’ŽŽ‹‡„††„‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒƒ…‡ˆ‹Š†„†„‚††‚‚„„ƒƒƒƒ‚‚}|}€~~~}|}}|y|ƒ†‡‡„ƒƒƒ„………ƒƒ…„„„„…„…„‚‚‚‚„„‚ƒƒ…†…„‚‚‚ƒƒ…„„„…„„†„ƒ„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰†„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„„……‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€ƒƒƒƒƒ‚‚}}€€}~~}}}}{zz~„„„‚€‚‚~‚ƒ‚‚‚‚ƒƒ€€€‚ƒ‚€€€€€ƒ‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†‹“‘‹ˆ……ƒƒ„‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€€ƒ‚~~~~}‚ƒƒ‚ƒƒƒ‚}}~€€€~}}}}~}|zzz€‚‚~€~}€€€€€€€~}}€~€€€€€€€€‚€€‚‚€‚„ƒ†’ŽŠ‡‡†ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒ‚ƒ„…€€|}}~}}~€€}~}~ƒƒƒ‚‚}}~€€€~}}}|{{{zzzz€€~~}~~€~€€~~~~}|~€~~€€€€€~€~€…’’Ž‹‹‡‰…„ƒ‚‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~}~€€~„ƒ‚€~}~~€€€~}}}|{{|zzyyy{€€€~~~€€~€€‚€|~~~~}|€~€~~€€~~~~~~~}}}}…“’ŽŒ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒ‚‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚‚‚€ƒƒƒ€€~}}~~~~}}}}}|||{zyyyx}€€€€€‚‚€~€~~~~~€€€€€~€~~€}~}}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€€~~€€„†‡†‡‚ƒƒ…ƒƒƒƒ…„„„„„ƒƒƒ„‚‚‚‚‚~}}}~~€}}}}}}}|}{zyyyyy€‚‚‚„ƒ€‚ƒ€‚‚ƒ‚ƒƒ‚€€€ƒ„‚€€€€€‚‚€€€€€€~~||Š“‰‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…ƒ„…„…†††††…†…ƒƒƒ‚‚€}}}}}}~~}}}}}}}}}|{yyyyx|‚ƒ„…‚„ƒ‚‚ƒ…‡‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚‚ƒ„ƒ‚ƒ‚‚‚‚€€€~Ž“Œ‡ˆ†ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€€~}}}~~~€ƒ„‡ˆ„†††…††‡‡†‡‡ˆ‡‡‡†}€€‚~}}}}}}}}}}}}||~~~|{yxwxyy€ƒƒƒ„„„„„——ƒƒ„}~‚‚‚‚„†ˆŒ…ƒ‚‚„‚ƒƒ‚ƒ…„„…ƒ‚ƒƒ‚ƒƒ‚‚‚‚ƒ‚‚‚’‹ˆˆ‡‰‡††„†……„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€~}~~€‚………‡†‡‡†‡‡ˆ†‡‡‡‡†‡…}}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yxy|~‰–„ƒƒ„„”“€~~…‹€€€„†‰…„‚‚……‹ƒƒ……††„ƒ……ƒ„„ƒƒ„ƒ„„„ˆ’Œ‰ˆˆ‰‡‡‡…†…„…„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„ƒ…„~}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|xyz{|€‚ƒ‚ƒ‚€~}~~{ˆ‘||Ž–}‚†Š…ƒƒ„ƒƒ‰~ƒ„……ƒ…†…„……ƒ„……†„„Ž‘ŒŠŠŒ‰ˆ‰‡………ƒƒƒ‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚€‚€~}}||}}|||}||}|}}}|||{‹‘—Œz{|€zzz{|yy}}~€€|{{~~}‚•‘„ˆ}|~‚„||‚„‚€‡ƒ}ƒ‚‚€ƒƒ„„„„„‚„ƒ„…„‘‘Ž‹Œ‹ŽŠ‰‰………ƒƒƒ‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚ƒ…ƒƒ…………ƒƒƒ„‚‚ƒ‚ƒ‚‚€€~~}~}||||||||||||||}|||~~Š‚{z{zxz{{|}{~}~}}}}}|€€}†~}‚~~€‚||€‚€‚€~}{Š‚}€~€€‚€‚€€€€‹”ŒŒŽŽˆˆ‡………„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ……†‡„„€†”ˆ€‚€~~~€|||||||||||||}|||||||y{{{xxy{{z|‚€~|~~~}€‚‚€€€‚‘€€~€~~~€}|}{}}}|}||}€€€~€~~‚”’ŽŠ…††…„„…ƒ‚ƒ‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚‚„†‡††~ˆ•Š~€€€~€~~~|{{|||||||||~}|{||||{|||zzy{|z}…ƒƒ~~€~…‚~€~~€…†‚€~~ƒ†}}~€€€~}}}}~{|}€}~Œ‘ŒŽ‡„††…„„ƒƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}€‚ƒ††……~€€€~~}€€€}}||}~}||}}}}}|~|}|{}||z{z|}}†„ƒ€€}~}~~‹„†~}||~‚}}}}|{}|~„ƒ€~~~~}|~}~€~~„’Œ‹Š†„†„„„ƒƒƒ‚ƒ‚ƒ‚ƒ‚€€}|||}~{{}w~vx~}|}}}~~‚ƒ€z}}|~~€~~~€€€€~~~~~~}~~}|~|~}~|{|||z{z}€€„ƒ‚~|||}||ƒ~Œ~|{{}~}~~}{{{}|{{{{€†„‚„ƒ€~‚‚‚‚‚€‹ŒŒ‹Šˆ„„„ƒƒƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€€€}€~~~~|‚}~}}}{{}}|z||~€‚€€€}|}|||||}|~{~{{{|||}|{{{{||zz}z~‚~‚„„‚‚…†……††‡…„‘ŠŠ‹‡‡…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~€€‚€~~€€~}ƒ||}}|}}}}{|~~~~~|}}|||{~~{|{||||}|}|~|}|{{{|y{|{{}z}~~€€ƒ‡‰‰‰Š‰‹‰…ˆ’Œˆ‰‡……ƒ‚‚ƒ„„ƒ‚‚‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||||||~€€€~~~}€€€€ƒ‚€€€€€€~|z|}}~}}~~Œ†}}~{{ƒƒ}~~}}|}}}}}}|}|}|}}~|~}}}}|{{z|{||{z{{zzz{~~ƒ…ˆ‡ˆŠ‹‹Š‰Œ‘ŽŠˆ†…„‚‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„„€€€€‚~}~~{~’Œ|}Š€Œ~~}}}~~}~}}}|~}|}|}}}~}}~~|{{{||}|{{{{yzzxy{~ƒƒ„‡‰Š‡‰ŽŽŒ‰‰…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{}||~~}}‚€€€‚…ƒ„‚‚‚€€ƒ‚€}~€~|‰‚~ƒ‘„„ƒ~}|‡}}~}}|~|}}|}}~~}~}}}{|}~||{|}zzzyyy{{~~€ƒ‡„ˆŽ‹Š†…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{}}}}}zx‚€‚‚€€€€‚‚‚‚†…„‚ƒ€‚„~€}~~}~€€}~„€~~}~}}Š…}~}~~}}}|~~~}€}}}|}||{|}{{{zzz{{|}~}€ƒ€‰Ž‹Œˆ„……„ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv}€‚‚‚‚‚‚ƒƒƒ‚…†„ƒ€€€ƒ€„~~€}~€~}~~€€€~€}€~€~|}}|~~~~€}‚€|}€€}{}}}|||||{{{|{|||}|Š‹‰ˆ††……„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€‚€€€€ƒ~~€}€}}~~€€‚€€€€}€€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{|~|}|||{|{|}‰‡‡……‡…„…„‚‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz~}yxtt€€‚‚‚‚‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚€~~~€}~€}}}~€€€€€‚~~€€€€€~}}}~|~~}}„€~}}}~}~~}~|{|z|{z€‡ƒ„„…„„„…ƒ‚‚€€‚‚ƒ‚‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xyuu}‚ƒ‚ƒƒƒƒ…„…ƒƒƒ„„ƒƒ„ƒ€€€~}~~~~~~€}}|}}~€€€€‚€€€ƒ‚€€~€~€€€~~~~}}~~……€€ƒ~€~€~}{z{z|{z‚…€ƒ‚‚‚‚‚ƒ€€‚€€‚‚ƒ‚ƒ„ƒ„‚„‚‚‚‚~€~}~~~~}~}}z{|…„{{syz|pwuvwyutz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€€}}}~}~~}~|}}~€€€€€ƒ‚€~€€€€€€€€‚‚‚€ƒ‚ƒ‚€€|{{z|{|‚€‚€€‚‚€~‚‚ƒƒƒ‚„‚„‚‚€~€€}~~}}}~}}{{z€x|vyy{qtxwvxury……‚„„‚„……†„„‚„ƒƒ€€~€€|}}~€}~~}|~~~~€€ƒ‚ƒ€€‚€€€€€€€€€‚ƒ€„€}ƒ„€€‚}z{{|||~€}}}€€~}}~‚‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxyzruyyvwwsu†…ƒ…„‚„„…„„„ƒ‚ƒ€~€~€}}}~€~€~~}|€|~€~€‚ƒ€€ƒ„‚€€€€€ƒ‚€ƒ€~‚ƒ„€€‚‚‚„‚~{{||||}}~}z~}}x~|||~~~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„‚„„…ƒƒƒƒƒ€}~}}}€~~~}}€€~|~~~‚‚ƒ‡…~~€€€€€€€‚‚€€~€‚‚ƒƒ‚ƒƒ…‚}}}|{||yz{z~y{yx~{|{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst†„„†ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€}€€~€}~}~€€|€€~}~~€}€€ƒƒƒ~}~~€€€‚€~~€‚€„‚„„†„€~}||||zyvyyzyvyv~|{{{~}{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…„ƒƒƒƒƒ‚‚ƒ‚ƒ‚~~€}}}|~€€€|€€€€|€~~~}~~‚‚~~~~~~~€}€€€~~~~~€‚‚‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{{{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvpxyrx…………ƒ„„ƒ‚„‚‚€‚€~~~~€~}~|~€€€€€€{€~€€€€}~~}}}~€‚~~~~}}~~~|~€~~~‚~~€€~ƒ‚ƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}|{|z{}zzx{|zz{xtxuqrtpxxqy„………ƒ„ƒ‚ƒƒ‚‚‚€‚€€€}~~€}|~|€€€€€€€|€€~€~~}}|€€€€~~~}|~~|}€~}~€‚~€€~‚„‚‚ƒ……‚‚~}}{{||yw|ywxwwx{{{{|…Š}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzz{zxswuqqsoxwq{…†……ƒ…‚ƒƒ‚‚€€€€~~}|~}€‚€€}~€~€€€}}|}€€€€~}|~}}~~~‚€€~ƒ‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{||{zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚€€}}~€‚‚}~~~€€‚€€~|~|€€€€€~}~~€€‚€€€€€€€„‚‚€~|}~~z}…~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚€€€€€€~}€€‚‚‚€~€€€‚}}~‚€€€€€€€€~~}€~€€€€€€€€€‚€€~}~z“z|}|{}y{zzxyxy{||}|||||||}}}||}|~}~~~}|z||{|}{yzzzyytuuooqpwst}…†ƒƒ‚ƒ‚€€‚‚€‚‚€€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€‚‚€€€}~|†‰||~{{~yz{z{Ž~wwy{|{}||||{}|}}}}|}|~~~~|z|}{|}{yz{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€€‚‚‚€€€€€€}~€}€ƒ‚{~~{|}{z|||‡yxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ‚„„€~‚€€€€‚~€€‚€€€€€€€€€~}€€€€€€€€€€€€€€€€€€~}~}~~{}|}|||xxuxxy{||}|{|||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒ„ƒƒ‚‚‚ƒ€€‚„ƒƒ„ƒ‚‚‚€€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€€‚€€€€€€€€€€€€€€€€€€€€€‚ƒ‚‚€‚‚€€€€‡~~|{}|{}xwvyyz|}||}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚ƒ„„€€ƒ†ƒƒƒ‚„€„ƒ‚‚€€‚‚„‚ƒ‚€€ƒ‚€€€€ƒ€€ƒ‚~‚€€~€€€€€€‚‚‚ƒ‚‚ƒƒƒ‚€€€„}}}|}z}{yvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysruowqwysw{…‚‚‚‚ƒ„‚ƒ„ƒ€€ƒƒ†ƒƒƒ‚‚„„ƒƒ€€‚ƒ‚‚‚~€€€‚‚‚‚‚€€€€‚‚„€~ƒ‚€ƒ‚€€‚ƒ‚€‚ƒ‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ‚€‚€}€|z|{{w|yyy{z}~}||||}~~€€€€„„€}€~{{{z{ztpxrytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚ƒ„†„‚ƒ‚‚„„ƒƒ€ƒ‚‚‚‚‚€‚€€€‚‚‚‚‚€‚‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚‚„ƒƒ„‚„‚ƒ‚‚‚‚ƒƒ„ƒ„ƒ„„„…ƒ„‚ƒ‚‚ƒ€€~||€}|x|yzyz|}|{||}}}||€€€€€‚~€€€€{{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚ƒ†……ƒƒ‚ƒ„‚„…‚‚‚ƒƒ‚‚‚€€~€‚ƒ‚‚‚‚€‚‚„‚‚ƒ€€‚€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒƒƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{}~}y|zzz}||}z||}}|z{~~~€€€€€€€‚€€}}|}}|vrvxxvtvu}‡‡ƒ‚„…ƒƒ„…„€‚……„„ƒ‚ƒ„„„…ƒ‚‚‚ƒƒƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚‚‚ƒ„‚‚€€‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚~ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz|}€}||z|~}}}}~~€€€€~~€€€€~|}}~~}||xvvw„‡ƒ‚ƒ†ƒƒ„†„‚…†…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„‚‚‚‚ƒƒ‚ƒ‚ƒ‚‚„„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒƒ„„„„„…„ƒƒ„…„…„ƒ‚€}‚€}||{||€}}~€~~}~||}}}~~~€}}~€~~}}}~}}~~€|}€‚‚ƒƒ†ƒ„ƒ†„‚ˆ‡…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒƒ‚‚ƒƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒ‚‚ƒƒ‚„ƒƒƒ„ƒƒ„„…„„„…………„ƒƒƒ}„€}}||||~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒƒ…ƒ„ƒ…~‚Š‹……„ƒ‚ƒ…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ…ƒƒ„…„……‡‡†‡…„„…„ƒ~~|~~}€~||~|z|}}}}}~~~€}}|€€~~~~~‚€……„ƒ„„‚„ƒ†€‚……Š‰„„„„……‚‡††„„„„…„…„„ƒ„„‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ…€}uz„…„‚ƒƒ‚ƒ„ƒ„„…ƒ„…†„…†}„y|~ƒ{…ƒ„ƒ€}~}~ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚ƒƒ‚‚†„„„…„ƒ„…ƒ„…„Šˆ………ƒ……„†††ƒ„„………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†spurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚……‚hzrss|€rƒƒƒ}}~~}~‚ƒ|}€}}||||}|||~}~}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ…ƒ†ˆ††…ƒ†††‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vyy†r„ƒpvxqvtturstvi€nrotvnulwm{sn€‡ym}rsvsvmnwlpylu}|~€}€}€€}}|||}|}~}€€€~|~€‚€€€€€€€‚ƒ‚‚„…‡††€‚…ƒƒ…‡†ƒ………†‡‡„ƒ††ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoomw}x†pqzprtfu~n{ysoy€}~€{~|€~€€~~€€€~~~~€~}€}€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„†……††ˆ„„†‡ˆˆ†‡„††‹Š…„†‡‡…ƒ………„‚…………†……†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„rioyxpkyszozwvvp€~~~z~}|}~}€ƒƒ€‚ƒ„€}~~~€~~‚€€‚„‡†ƒƒ†„……†‡†…………††ˆ……†…‡‡…†„††‰ˆ…„‰‹ˆ†„†………ƒ……„†††††…ƒx‹yrˆz{pp…„x…xyks~y{krƒ‡ƒz|mzyyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozks|nv‚~~}}z}{|}}~}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ„†„…………†‡……………‡‡ˆ†„†…††……„……„……†‰Š‡…„†…††…††„†††††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„…†…†„†„ƒ„„†„„ƒƒ„„…„…„…„†ƒ…†……„„…‡†„„…†……}w†ƒ„„ƒ‚}~{|{~{||}~}|~€}€~~~€~~~~}}}~|{|~||‰†…„†††…††…………††‡ˆ†„†…‡†……ƒ„…†…„††††…„†„…††††„‡†‡‡†…‡ˆˆˆˆ†„‡…††ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…ƒ‚……†……ƒ…„„„…„†…„……ƒ††………„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ}€{{|~{||}~||~}€~}€~~€}}|€}~~~~~||}~{|||{{~ˆ‡„„ˆ††…‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡…††……†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ……ˆ…†‡†‡†‡†‡…‡‡†‡……†‡…‡†…‚ƒ…††„„ƒ„„ƒ„†„†…………ƒ††…†…„††…„„……ƒ„‡…ƒ‚ƒ„ƒ„‚~€|{}~{|{~~}||~}~~}~}}~~|}||~~|}€|||}|||~z{{|~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†„…„‡†„…‡ƒ„…„…‡„…††…†„††‡‡††ˆ‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…‡‡…‡†‡†‡…ˆˆ‡‡…††‡…††…„„…†……„„„ƒ„…„†††…†„†…††……††…„ƒ„„ƒƒ‡ƒ„‚„„ƒ‚€€€{{~}|||~}|||}}|}|~}|}}||||}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††„…†…†††…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡…†††‡‡‡…‡†ˆˆ‡‡…‡‡‡…†‡„‚„ƒ„†…‡…„„„„„…†††††…‡……‡…†…†…„ƒ„ƒƒ„‡ƒ€‚ƒƒ‚‚‚€{}}|||~}|}}|~{||{||}}{{{}|{~}{|}}|}}~}|zz{{||ˆ‡‚††††‡††…„…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡ˆˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡…‡‡††‡‡…‡†ˆˆ‡†…‡‡ˆ††‡ƒƒ„„ƒ††‡……„„„…†††††…†‡††‡††„†…ƒƒƒƒ‚ƒ†ƒ~‚‚ƒ€ƒ‚|~||}}|}}|}{{{z{|||{{{~{{}{z{~||||}~}{z|z||‰‡ƒ†…†…††…„„……………„ƒ„†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…‰Š‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……ˆƒ„†…ƒ††‡†…„ƒ……†††††…††‡†‡‡…ƒ……ƒ‚‚„…‚ƒ~‚ƒ~~~||}}{}}|}zz{y{|}{{{{~||||z{}||||~}|{{{{|{‰‡„†„†„††…„…†…„„ƒ„‚€ƒ†ƒ‚z„Œ{€„…‡†††…„‡ˆ‡†‡……‡Š‡„‡…††ˆ†…‡…†‡ˆ††ˆˆ‡‡†‡ˆ†„†††‡……‡ƒ„…„‡††‡…„„ƒ……††‡††…†††…††„ƒ„…‚‚€„ƒƒ‚}~ƒ~€||}}~}{}}|}yzzy{}}zz{{}|}||zz}||}|~~€{{{|~}|ˆ‡…†…‡„†„……………ƒƒƒ€‚…‚€}|{„…††„…„„‡‡†††…„†‰†‚†„†††……‡…‡ˆ‰†…ˆ‡‰‡††‡…„†……‡…„‡ƒ„…„ˆ††‡……„‚……†…††‡„††††…†‚ƒƒ…€€€€ƒƒ€|€~~‚€}€||}~}~{~}||yzzyz}}yz{{|{|{{z{}}|}|~~|{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€ƒ‚~~~€yz}€ƒƒ…‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ……ˆ‡‰‡†………ƒ†„…‡ƒ„†„„…„‡†…†…†„‚……†††††„…††………‚‚ƒƒ~€€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|{{{{|}}}|€~}|||~|{‡……††††„…„…ƒ…‚€€€€~‚‚}~{‚ƒƒ…†…„ƒƒ†ƒƒ„‚€…‡…‚ƒ„…„„††‡‡‡……ˆ†‰‡…„„„‚…ƒ„†‚ƒ…„…†„‡†………†ƒ„…„…†…†„„…„…ƒ…„€€‚ƒ~€ƒ|€~}‚}€~~~~~}}{|{zyzzyz{|yzz{{{|z{{{|}~}}€}}||}€}|†ƒ††††…ƒ„ƒ†‚…€€€~‚}~~€€‚‚‚„„ƒƒ‚„€ƒ‚€„…„‚€‚ƒƒ„……‡††„…‡…‡…†‚ƒ‚‚ƒ‚‚…ƒ…„„†„††‡††…‚„„ƒ„†……ƒ„ƒƒ„‚„„€‚‚}~~~„~{||€}€}~ƒ}~~}}~{~{{zy{zyzz{yzzz{{|z||||~~}|}||}€~€†„……„‡„„ƒ‚†‚ƒ€€~~€}|}~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡†……„ƒƒƒ„……„ƒƒ‚„ƒƒ€€~}}~~|~ƒ~|~||€~‚~‚|~}}|||{{zzzzy{yzzyzzz{|y{}{{~€}~}}}€€€†„„…„…‚„‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„…ƒ‚ƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚€…ƒ~€~|}~}|~ƒ}{~|}€ƒ}}€~}|||}{{zyzyy{yzzyzz{{{z{}||‚€~€€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌËËËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFK=8765999<>9?<C:;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÔÓÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937676=;>:=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<:<<98:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA>;A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËÊÊÊËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÔÔÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9>CE?<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÐÑÐÐÐÐÐÑÑÑÑÑÑÑÍÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø×××××ÕÕÕÕÕÕÕÕÕÕÕÕÕÕØÛÜÝÜÜÜÜÝÜÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÜÜ×ÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILN@99:4;A<7=9AC=@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌ͖„†††††‡‡‡‡‡‡‚²âÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¸ºÑÔÔÔÔÔÔÔÔÔÔÔÔØ®|‚‚‚‚‚‚ƒ‹ŠŠŠŠŠŠŠŠŠŠŠ‹‡½æáââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVM<::77>C>8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÎnPSSSSSTTTTTSL óëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§£££££££££££¢¦ÎÓÒÒÒÒÒÒÒÒÒÒÒّ;DDDDDDCCCDDCFSSSSSSSSSSSSSKªòëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;?C>6:7>?;<B@8<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÌÎqTXWWWXXXXXXWP¡ñééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤¤§ÍÓÒÒÒÒÒÒÒÑÑÑÒٔ@HIIIIIIHHHHGJWWWWWWWWWWWWWO«ñêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;?@@8:;8<<<<>::;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÎx^a````aaaa``Z¤îççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©©¬ÎÓÒÒÒÒÒÒÒÒÑÒÒٙMTTTTTTTTTTUTV`bbbbbbbbbbbb[¯ïééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB>;=:9;:=<;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÇÅÅÅÅÅÅÅÅÅÅÅÅÄËÐÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÎÎÎÏÎÏÎÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÒÕÕÕÕÕÕÕÕÕÔÔÔÕÕÐËËÊÊÊÊÊËËÊËËËËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÔØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<7@A<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÏÏÏÏÏÏÏÏÏÏÏÓÏÏÎÌÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÎÓÔÐÏÎÒÔÏÎÎÓÓÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÔÔÔÔÔÕ×××××××××××ØØ×ØØØØØÙÙÙÙÙÙÙÙÙØ×ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?89:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÎЦ’ÅÑÒ¨ ÐÏѤ¡ÐÎÎÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<=B>BB@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÎÒª¬”γž£§Ö¯Ÿ¡©ÒÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?><7:>9?D>@98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÐɗ™…¥«¡š“Àž˜•œÈÐÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<<96?B?B:647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÏѤ°½š‹›¡œ´˜œ¢°²ÓÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8E@?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÏÏÐÕ¹œ‡–­¹†ž–¯³ªÕÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<==964:99::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÏÏÐњ¢œ –x›„“¤ÕÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:<?>=<9@<<::9?@==<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÐÐÕ§¤¥¬›¨ˆœyŸ©…™¤ÕÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CFCAA8;?<=;<<7558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÐÒÀ¢Ì¶µ¯¦œŠ½­¦˜¯ÖÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF?HHGE@<<>><==<756:969;::;8@?:<<9<>=;;:?9?:;9=>=><;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦ÓÔ¤ ¹À£——¥§–˜›»ÕÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@C;557<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡ÈƦ½•‘¨£«¤›ÐŸ«¤œÑÓÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKL@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ Ôʎ“—¨É·×¼ÕÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<<?GEGKH=657:979:;:<=9>99:8;=>>A>=9<<:=>>:=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÔ¯°³ÐÕÇÃÕÑÕÅÄÕÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?AELLA>775;8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÔÖÖÖÒÒÔÕÓÓÓÔÔÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEJ>>786967899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9699:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EIKAALD??;9889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEHIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDI;AA;<886586987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGJB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<BA<;876797799=?A?<:9@?<>B?:8776=?@@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE>;HF89757875898;>>=;89A>=@?A>7596;>AB??@@AB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCEEC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELBA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<<DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGHNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAD?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€iixsg~‰‰xp‚†{w}~…Š½ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€‚wt|„‚}sp€Šx‚yƒÈÞÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsnupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿¼½¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»º¹¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjcmgb\XQPQKTJB:IQ?A7<94:565455688686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸¸·······¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µ¶¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸¸·¸¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶·····¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨§¨¨§¨©©ª§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸········¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨¨§¨¨§¥¤¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§¦¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©ª««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤££¢¢£¢¡ŸŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž¤¤¡ŸžŸ  œœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=6789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥£¢¡¡¡¡¢£¥§¦¦§¬«§¦ œ›¡¡žš››œ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¦¦§§§§Ÿ›š›¢ š•—–š›š——˜™šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜˜™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥£¢¥¦¦¥¦§¦¦ ›™›¡ –ž¢’˜šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB?DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¤¥¨§¦¢žŸ¡Ÿž©Ÿ”—›˜–—–˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;<;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¦¦¥¥¦§¦¥¤¥¦¦¥£  ¡¡ž§yŽ–š™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡¡¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢¢¢¤¥¤«°£¤¤£¢¡¡œ¢–a‘•™›™›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œŸ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸžŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::78:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸ   ¡¢£ª°«¢£¢¡¡žš¦s_—š™š™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢Ÿ›ž ¡£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œ››œŸžœœœœŸ   ¡¡¡  ¡  ¡­’¨¥¡ žœ›Ÿ]dš›™šœ™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥¤¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¢¢¢¡¡  ¨—¬Ÿžš˜¤ˆXf™œšž›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›š›šš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>99;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤¤¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ ŸžŸ ¡    £¤o›¤œšš¥ybf˜œ›žžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›šš››š˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9<<>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœœœžžžž§y‡¤›šœ xkf“œžœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:<>9?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››››œ››œ¢~€œ™››•ujgŸœžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™™™ššª}‰“œœ›ˆqhhŽŸœœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›œš™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š›››œœœ™˜™™˜¢†‚‚™žœpbhŽŸžžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ››››››œ™˜™™— ››|z›£›€‡keŸžžŸžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ›››››œš˜™™›©œˆgn­ªŒhƒl”Ÿž  žžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_^]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜˜——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜™— ¦ˆt_ež–‚Wr{z›œ››žœœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±³­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=:F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œš››œ›˜™š˜˜™›š›•¢žtRMo•„xIYpw‘”‘Ž’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨©¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‘‹‘‹Œ‘‘§•S9@t‰qgE:Uo‡†‚‹†‰Š‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VQQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹Œ†Š‹‹‰‡„†ƒ€Š¨yNhTt‹weOUC_w~€‚’†„„…ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹Ž‹‰‰…‚‚~~‚ _uŒb§žˆ]†{Qk}…Ž‹†”’‹—”—’˜¡–ž–•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¥›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ‚†‹‡ˆ…„ˆˆŠ…€‚}Œ–c¹Ô½º©·‡t|iY†ŠŽ‹™œ””” ššŸ¢­±­©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPEMISWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‘ŒˆŒ‹‡’‰•‚ÏĜխš°ž_‚qTz‘‰‰””˜•œšž¨®²¯°µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWMO_^\NUUbQDTM;?9<895875795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš™‘ž¡“—›¡š›£¡œnº¤¸Ñ±¨®“l³§Ut”‹˜šŒ”š—œ› ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUJTOOJDPK_bXZQ\T`MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ªª©§¢¥¨©«©©°£t•~±¼³«•‡]–Äloœ¢¡¤ž›š¤§¤©«®¬¥¤¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdWOYKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®««¬¤¡¢¥©§¨ª¯’‹v{§—Žzjm‘zo–£¨§ ¢¡®¬«ª§­®¨¥¤©©ª©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_VZNRNPOSe\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢™œ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨§¦¨©§©©¤¨¦š¤¥£¡¡«”|[i‘~{€roksq{{”¢¢ ¡Ÿ¡¡¨ œž¡¥¡ ¦£¢ž¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOXO^ddlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤ ¢ £§¡¦­§§¢¬§}lS[woqvkgdjfnxž ¡ ž £š–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvxb_\UYQUW[c_s_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?B?:8:>?C@DA:;>=@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¡Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯««¬¨¨«¯©¨ª¨¢ ¡§©®´·¶¹¶®jcOVnkkshbdb[`fov€›£¥¡¡¢˜•ž›ŸŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸŸ¡¦¢›—’šš •|wo}yf[[`_Z\V\hdocmjib^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¢ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£ £ªª©´ÂÆÆÈÇ¿³¦’ub`JOoqmtg`ggX][`glou~‰“œ¤Ÿ¡¡š–ž¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¡™˜¥ ¤§ª©¨ª­¬¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxjb[_^\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>BE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢ «²ÀØáÞÕÆ·ª‘|gb_FRjnqxh`biY[^[\]aba`f|¡½½¨¤˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨¨«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥¡¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxxxc[RYT__amhvlphiibZSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶´º±ª®´±°²´µ¶¿ÉÕÖÇ­˜Ž‚ue`c\AQlhuvmbcdZYZ[XY[YWgµÀ¿¶®³ §ª¬§ª©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš’–””˜“š˜Š‹‡€€|‚xa^YTai`fsotitdidb[LK>:9898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÄÇÃù½¾ÁÈÐÍ­€f]YW\UBJqhmgrga_X[WYWTSbŽ¼Â¸·»°µ¶¨¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`b_^kcbnxuvnm[bRV\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAA;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–••‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±°§¼¼¾ÅÄÆÉÇÅÆ»ÅÁÅÅÁÁÀ½ŽfVUWRHDtkb`ogY[Y][^XcŒºÅ¾¥¥±¶«µ²­³­¨®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|~„ifhaklgnvqruqg^_\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÄ¿ÃÃÆÆÁ±”Çʶ…^VTOGbh€‹ŒVU]`a]bƒ±Á¹®²§«¨¨ª­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|~tklndomiqxnyiia\gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÄÄŵÀ¶µÉÏ£kUUQS_˜©¥QV[^^f•À·¦«³µ­®¥¤£§¤  ¥™ª´±¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyy{vnkihuZfrxsyff^d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÊÆÄÃÄž·½Ãʺ}UTTL­žMTWWh–»´±­¬¸µ²¬©£¡­©¬¦­Ÿ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuuefijh]jonyxcba`^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÎÏÌÃÇÆÈÉÈÈÉÇÅÉÇÈÇ¿ÅÇÃÇ‹XQK†°“IOUh Á½¿¹¼º¼º¼¬­¦©»º¹·¿²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqocagvhiitmyl]d[U`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÌÐÍÇÌÉÂÂÇÂËËÈÇÌÉÍÅÅÄÃÅÇɧtMz²ŠGNx­ÌÍÆÄÁÄÇÁ¼¾´±°°Â¾¾ÁÆ¿¾¸¶Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`kjwlieuntc]bTWUSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<9>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÄÇÈÆÒÉÁÃÿ¿¾ÄËÈÊËɼ¼ÈÇÉÍÈÃÈÉÉÅÅÁÁÀÀÆËÓd}dKƒÉÉËÐŶ¿¿ÀÀº»½µ³³À¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrpfegcjdbjmno^Y]VVNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾƹ»Ãº¸¹¼¾ÁÇÁÆ»¹ÈÈÃÅÄÀÃÁÁÀÄÁ½¼ÁÀÀēPIsÉÎÄÈÐÁ¯½½¸¹»»¾·´±¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfadbacccjbgc[ZZ]YQOE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶·´´µ¿»½¿¹¾ºº´À¸µ·²®º»·À·¼ÊÏÁ»¿À¼»Ä½ºÀÄ¿½¼¸»¿ÅyI ÍÄ¿¿É¿°Á¿º·»¾¹µ·´¸¼´½¸µ´°³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|yˆ}qdabchjggiei^VVTYOSLF8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“““˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´´±°µ·µ»Á¸¾¹¿¼¼·´·¯®·µ¹¿»ÁՎ¼¾»ÃµºÇ·¶¹»¼¸¹µºÄʗM¥ÈÀ¿»Á¾¹Æ½Â¿¼Å¸¶·´¸¶¶»»¹¶´·ºµ´¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒ€xqmeefpjekhXYOKKKRJLHD9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’™”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿¾¼²­¯¬±°·¼·»½ÁĹ··¶µ¹¹º»¿¼ÐÅy­Ë½Ç·¹¸­¶´·¹³µ²»ÅʟP¤É¿¿¾½¼¿ÈÃÅžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~‡|knpgpksfbn`\THKKDJCCG>:;8><7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘Ž˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼»À·ª­¤®°¸»²½¾»Ä¶µ¸µ·¿¾Ä¼ÂÄØ®v„¾ÈÏÂÀ¸®µµ»½·¹±¾ÃǘQ¢Îÿ¾½¼ÇÌÇÇÄǽµµ¶Á½»»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†€qflintnwcgb\cQKUHEECGB<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?>??FD@A?>:7?@CC?@=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼ªª£°¹½¼²¼¾¼Å¸±¸¹¼ÆÉÊÂÇÉљsw±ÑÑÌÊĵº¿ÄȾ¾´¿ÀÍU–ÏƾÁ¼¿ÃÌÊÇÅÆÀ¹½¼Ä¿¿¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtolltlln_c^abNHN?E@?DC;;::;:8;<:9<>::>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´»Åк¾¼Ä¾·¼À¿ÉÏÇÈÊʇuw¨ÌÌËÍÊÆÂÃËÎÁ¼¸½º»]‹ÌÆÄÀÀ¿ÄÀÊÉÃÃÃùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{z‡zmmx|`qc[^__TI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA??ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸´¼·»º­Û¾¶¾À¾¾º¦œª³·ÄÀ¦{y|ŸÄÆËÈÁÃÀÀÉÊÁ¿»º²®zlzÇÆÅÄ¿ÀÁ¿ËÇÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}‚znsxthp]\_\ZQEEDMIAD=H;;59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘—žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯··²µ³·¹¼»¶»»Å¶m¯Î½¶¹À¼ª}nhnmt‚—™uzœ¾¿ÆÀ¹À¼¾ÅĽ½¸±± †{q¼ÈÃü½¿¿Ãþ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸··½¹»±¶²ÈÀ»¶´±°·¬³©°­­´·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|wlu{pni\__YSPAFIGK@ECH<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿš›œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹Àͱu‚´½µµÁ¤†iZ^`NS[\pvz…¤¸·Âº³»·»½¿º»»­®¢ŸŠƒ¯ÅÃþ¼¿»»¸¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ°µ´´½º¾ºº»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰{‚zsvvwnqa_f][UJ=??GF=GCC9:5;99><<::<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Âɦ„w‹¢°µœjfgVY_IIMPTo{‹©°·¾¹²µ²¼¹¼¶¹¾²­°©—”•ÇÇÃÀ½¿¹³®²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtwrl_ca\^OIB?=IDFMD@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·¿Æ¨‡{vŒ¡˜_SCYUHbjUOEJe‘¥¯¯¶ºµ´²¬¼¹¸µ¸Á½¡±°¤£z¿È¿¹ºµ®¥¬³±¦°­¨ Ÿ¥­¶µÂ·¶´¥¨ª¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´¶¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wp|ovrnc]fY]]SONA>JB@KJ@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³²­¶º¯­¼³¸¸¿³yˆnNK@eYBOx“hMC^…±µ³µ²´¯¬»º¸¶¹¿ÅŒµ¿®­n¬¾¸µ²±­­Ÿ¤¦§¤¥œ–™™™Ÿ©®¹¬««Ÿ¥¨¤«®¯§°«¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmuil][jT][PNHDGMBFNF8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹º¶¹»µµ³·¶•Œˆ„{XFAO‡XIJYxŽƒcAU£¹³´²°±­°¹¸¶»·º¾ž°µ®¯~¬°©«­«£¨¡ž—— •’–—˜Ÿ¨®¤£¤ ¢¦¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬ª¯£¤£¡© ›“Ž”’’™–š¤¥ Ÿž§˜•’”™ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wrxhutneUacW]QOMH@IRDMC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯²¼©˜™”hM?SyqOIILhZEU°º±¬³¯®¬­¶¶²´µ®©¥™šœž§¨ž ¨©Ÿ¡§–›——Ž”–—›¤¨  ¢¢¢¥¥££ ž¥ ¤¬¥¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›ª¨««Ÿ¦¢›£œ•Œ“—•–˜Ÿžž›™¦—“’–¢ ¥¢¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦¡ˆxƒ|vzcwln]QiTPNGPMLCPQ@>;>49:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¤¬¨½Áª¥¼fDSœ~PXIKaIWbeeƒ¯µª²´®ª«¯°²³­¥‘—“˜ Ÿ¢ œ£¤Ÿž¨”›–—Œ—‘—“˜¢ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨¨œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£žžžš—š«¦ª±£¥¨ž œ•“‘‘™–•˜—Ÿ˜œ™›£™—”•š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’~|uv}nk{dhVRdMJHGOSNKNH<E@<2?859;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜——–¡¨¬®¶·º¹º··»®¨ ¡© «Æ¿ÊžNAv™nOmJLdfvta]bt’²¯®³µª¦¬«¢›™”‘•–˜˜œŸ¢¢œ¤žš¤———–’‘‘“š—› ¤ªž¡¡ž¦§ª¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¢¥¢š™ž¯¨®²«¥ªª ›˜˜˜•“–š“••š–›——˜¡žœœ–›¡šžš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}wy|eyy`bSU`HIJKSTISQM9?B67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—“’œž¤¨®­¬««¯ª¯©ž—ž¥œ¤ÇƋVSJf£Yf}or[Rkc\gb`m‘´°°¸¬¦¡œš”—š™Ž‘•‘ŒŽ“™¢œ—£™š—˜™”™˜–›Ÿ¥¦© ¦£ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§  £±®²±´ª²®£™œž¡˜››š˜™›”–›–™œ¥¡ š£¡šœ™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ ž ž ¥¡žž¥ ¦™{|vvsh‚le[S[YMQJOOVMSMB7>C78=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’‘œ˜¡ª¢§ ž§¡¥Ÿœ’›¢šŸª£ŒyUiqwuocwvXWb`di[ZWh­®¬¯§Ÿž¢ –“› ›™—’“Ÿœ¡£›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬©¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½¶¾°¬±®­©ª´±°¨«¨³¶¸³¸­²´¤ ¥ ¬¡¡¢¡ š˜–•Ÿ››˜¥¡ ž£¡ ž›œ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚€|xvjwu^m[R`HRUHFUWJCMG=KH8F<77;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“Ÿ™¨®Ÿ§žœ¡žš™’˜ž›¡¡ £o‚p`cWK[RZLLQYRHONH™¬ª©¤ŸŸ™’’”˜˜––•Œˆ‹Ž•œž—ž™¦Ÿ ¨¥±ª§®£«®¶°´²±®¶¸½¿º­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«®±¹¸¼¯³°µÂ¼·¾³³µ¢¬¢©¨²©«¨§¨š™žšª§ ™§ ŸŸ¨¨¥¤žª¢¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰…„~vrmiwmhm\X[CWNJGMGCFM<>L>4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜™ª ±¢·¤°¦Ÿž—˜•™žšœ£žœ‰bW^e`WMQG=?@CD?>BRx©­©ª¥ŸžŸ¢£žšœ›”“•”ž˜”…š š«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶º»ÀĹ½»¬¯§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¹Â¾¸³»ÆĽü·³ª³­ª³´¯³®ª¯£¬¨¶±­£°¦ £°±®°¤¥¯£¡ š¡§¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¥ž¦™›¢¤žŸ›››œ‡†{trkkurqhV\QFUHDJPI?EA4FH95<>7;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž  œœ˜šŸ š Ÿ•|_^e`PFE;B>F<>96N~ª²§££¢ ž¥«¥ž—œ”‘™™•ŒŠ†ˆ†xmˆ ¤¢«¬´¼¶Ã¾¾³»ÁÃÂÅÀ¿ÂÆÆÅÃÈÂÀÅÇÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌÌÌÓǾ¿À¾ÇÆ·ÃÊÉÃÁƾºµº»µ»·°¶²ªº²®»¸¿»º«¸­«ª¸»µ¼®®¹£¦£ž¦¥¢£©¦™›Ÿ™š§ª§ ¡¡¤˜”£–”™‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ„}zqkcioxkeY[FKLEDTLDCE7:?:549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ²²¸§¡¡«ª¡œž¡¡›š}riaWNE>IY|oaA=\Ž®¬ ™››žž™———’ŒŽ–—“ŽŒ‚ƒ‚wrqmp¦­®´¹Å»ÍÇË¿ÂÌÍÍÌÇÉÑÌÌÌÇÉÅÅÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÑÓÍÔÐÓÓÌÊÂÅÆÆÊÈÏÀÉÑÌÇÆÈżÃÁ¾¿¿¶¾³­¿ÀÃÃÇÅÇį¿¹²¸¼Äº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›‹™‰•˜› Ÿ£—žš““‹•…€ytsebgrof^ZZCNLDFPIDC@55589B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>9;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›¢¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¤¨¬­ª £žœž•if\TID@?J…ž¤˜ƒ ²­£žœŸš˜—”’”–‘Œ‡ƒƒˆ‡ƒ€€yqroly¤¶º¹¾ËÁÓÒÓÈÍÎÑÓÑÒÑÐÑÑÍÎÎÐÅÎÔÕØÑ×ÍÆÇÉÌÃÅÊÏÊÓ×Ò×ÒÕÖÓÔÈÌÇÌÍÊÓÍÎÓÍÅÉÊÊÁÇÌÇÉÉƿó³ÈÅËËËÏÇÊ¿¾¿½ÁÆÅÍÌÉÉÀÃÀ®¯³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›•Œ†‹€zruvgcgvjdVWQDNF@JQB>B<:22A<E<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<@?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­³·¬®£ž£¢¡›aSLJDC?CS°Ò½²¯¦œœœ ¤¡š”“•”‰}xpkebhroq{…Š€upnqtp…³Ã¾ÅÑÐ×ÖÖÒÖÎÔÖ×ÔÓÑÓÔÔÓÏÑÃÐÓÖØÕÖÒËÉÎÑËÆÍÑÊÒÕÖÙÖ×Ó×ØÎÒÊÏÑÌÏÐÌÓÐÀÈÇÊÄÌÌÌÎÏÅÇȶ¿ÊÀÒÍÌÏÆÊÈ¿ÄÃÈÎÍÐÑÏÍÊÈ͸·»¨Ÿ¥«§Ÿ˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„|xsvpc`erb]R\IJGAEIJ>;A8=5586;86:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÁűµ¨¡¤¥ ¢¡YI@ADAFQv²¯§š”—Ÿœš  ž›œ™•‰wica__`_^__]alusppolrqu’ÄÈÇÔÖ×××ÓÖÐÕÔÚÔÔÎÏÕÔÔÑÑÌÐÎÔ×ÖÓÕÐÏÒÓÑÉÓÑÈÐØ×ØÑ×Ñ×ÙÔÕÌÏÏÊÍÒËÎÑÀÆÃÈÆÏÎÑÑÒÈÌÍÀËÌÆÓÏÌÎÈÄËÇÇÉÌÊÔÔÑÕÏÒÌÓ¹ű¥¨µ®§›¨«¥²¨°³­¬““Žˆ‹Žƒ‹„Ž™“™‚…Œ|zqstmacim_VP_JJCFCRM@<>43:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><?@=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯­ªª«¥®·¨«·×ÔÕÙÙÑÎп¼Ìɶ¾®¦ª¨¡£«eC8=>DX‚ª¨Ÿ—•—™šœŸ˜œœ’}pecb__a_^a`_``_`emppnkorvwœÌÁÓÕÓØØÖÙÑÒÒ×ÏÓÎËÒÍÕÔÑÊÏÌÓÖÒÑÖÍÏÕÕÑÅÑÔËÐÔÕÖÎÒÐØØ×ØËÈÎÄÉÏÌÊÌÀÊÀÈÊÎÎÐËÐÎÎÌÏÏÈÌÐÐËÎÊÃÊÇÉÍËÌÒÓÍÓÒÑÐÐʽȹ°®»¹µ«¶°­¨¸­³¾»±š ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…ˆzvopokaenpaW\ZIFFDMXE;@=33<<87855;>@=9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ¤§Ÿ¸¶µµ¬¤¬®¾´°ÀØÒ×ÚÜÖÎÍÊÃÒÏÁÁ±©¬­©¤±yHFB;WŽ¡›•“–›žžžœ“–—”ˆk^^^adb``aa``a^__^\bmroostvvy¤¿ÌÕÑÖÔÓØÖÎÎÓËÎÎÅÎÊÒÒÏÇÎÍÎÔÌÎÒÍË×ÖÐÌÑÔËÌÐÒÓÊÎÑÕÒÕÕÊÀÊÂÅÍÂÈÊÃÌÄÆÉÊËÏËÎÍÐÎÓÌÆÉÏÍÈÇËÅÇÁÆÊÌÍÏÑÇÐÏÍÎÌÐÅÇÁ¸¹½Ãýø²²¾±»Ãõª˜¥¡˜–’••’‹”š‘””•‚‰†yqrkmg``qhYXhVMGLIPQB;C>;68:8::57==A;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÄÂÁ¿»µ²±ÇøÊÕÖÙÚÛØÌÌÏÈÖÕĵ¯´¨Ÿ­—xlpqy›Œ—•“‘‘•–•‹|eabb`]^aca``_`aa`_][]grrprsqmry¥ÇÓÏËÐÐÓÔÊÅÉÉÆÆ¿ÃÅÏÎÇÅÇÍÊÒÈËÎÍÆÑÒÐÎÌÔÊÇËÎÏÇÇÏÒËÐÏƺĿÆʽÂÇÉÎÅÃÇÀÇÍÈÄÌËÌÏÈÄÄÐÈÆÂÆÈÄ¿ÁÇÌËËÎÂËÌÉÇËÐÄÅÇ»ÇÃÈÉÂÏÁ½¼¿°ÁÉƹ½ª°²§¥¢œ˜›£™—™‘•˜‰‚xotdk`^fqa[W`GHHGIMTG?J=64355==48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ¼¹ÌÌÆÐÕÕØÚÛØÐÉÏÏÑÓÈ·»»­£¶}hƒ…¤«”Ž–…ƒƒƒ}„„~s_[^^^`^`cdc_]]^_``_[Z\`lrqookloo}¹ÑÈÉÊÏËÍĺÀû»ºº¾ÉÆÂÃÀÃÈÊÉÈÊÈÁÅÌÆÈÊÍÉÄÂËÉÁÁËÐÅËÈ¿¹Â»ÆǾÀÆÏËÄÀûÉÇÉ»ÉÇÅÊÀ¾ÂËÆÅľƽ¼ÁÃÅÌÅżÀÉÃÅÇÒÅÁÉ¿ÊÉÆÈÆÑÃÃÆïÄËÇÃÊ·¿¼º´©¬¤¥˜Ÿ˜¬£¡¦›£ ›•|wstfiZanmZ[XRDLFBGELDFS@54335?<3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ÊÏÑÌÇÂÃÆÍÎÎÌÕÏÕÙØÙÏËÒÍÍÎÈÁµÃ¾±¯µl^z|¡‘‹’–†z€……uxurp_[[]``bcdded`\\]]_^`[YZ\borokikposÇ½ÊÅËÀÆ°¶º²²³²±Â¼¼¼º¸ÁÁÁľ½¹½¿¹ÄÊÅƽÆÀ¸»ÃÉ¿ÁÉ»·»ºÆÿ¼ÁÎÃƾ¾µÁ½Ã»½Æ»Ãº´¼ÆÄ·¿¶¶¾¿»ÌüµºÈº¿¾ËÃÁÆÂÅÉÇÉÆÐÆÂÌȲÇÉÃÎÌÀÅÿ½²·°²§¨¨¹°¥­°ª­¬”zvwjdg`hocV^YJFJFHKAEBFJ@9:658854;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÅÂÄÈÎÒÊÊÉÆÍÍÎÑÈÐÅÕÔÖ×ÍÊÎÅÉÅÇÁ¹Å½«®¥_duƒ“‹ˆ‹„x††~„{ttc\\]^``bcbbdeb]\[\^\^]Z[\^hsqmggnory½ÌÀúÁ¸­°±§ª­¬§¸´¶´³³´»¶½±·°µ¯²»Â¼Áļ¿»µ²º¾À¸È¹´»·Á½¸½ÇÁļµ¯²¶º¿´Å·»µ«¸½¾À½±º¶°·º³Æ¼·¯»¿µ·µÅ¼¾ÃÅÀÄÅÆÇËÅÀÆÆ»ÇËÀÏÉÇÃÆÁ÷ý½¶¹¾Ç¿¬µ»µ·¶Žytxggebkn]V^`FKHHJFBDAEE?<:566633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÍÈÅÈÍÌÐÌÍÈÉÈÊÈÊÄÏÍÒÏÍÅÇÁÆÀ¿º·É¶ª°˜[hoŠ…ˆ‰zx~††vw|sh]]]]_`_`da^cec__\[^\]^Z[[]_lpnifjmnr|¤ÇÀ¸¸µ°«¬§ž¢©§žª¬³­ª¬ª´­¶±³©®§¬³»º¶Ã¹ºº±«µ¹»´Âº°À±¾¼»¶¼È¹Ã¶­ª¨°²À¶¸½°±§±³´»¼«®µ¦®¶®»²±ª¹°®»®»¸»ÀÀ¾ºÃ¿ÆÃÅÀ¼ÆÁÇ˸ÅÇÅ¿ÇÃúÄÆ»ÆÉÌ˳¹Â½»³‰swvki`blhXWW[ALKMJEAC?FA:9:996854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÅÎÒËÃÅÁÄÐÇÍÁÃÆ¿ÄÄÃÃÊÂÉÊ¿À¼Âº³µµÃ®ª°‘[j’‡Ž{x}‰…z{„wn^]\\]_`__dcbcdb`_]Z[ZZ]ZZYZ\enohfhiknr­º°µ®¥¥§§š ¤ šœ¥«­¤¨¢«ª¬«°£¦Ÿª­´¶±½¹¯·°¨®¸´³¼¸´½¯¸¹µ²¼Á²À®¥¨£«±²³¨½ª«¨«¬­µ³¥¨®¡¤¯©²¦¨¨®¥¨·¬±²·ºº»²¼¾¾¾Ä¿µÁÁÇÈ·¾ÀÄ·Äÿ»¿Ä¾ÄÈÌÊ¿¿ÃÀÀ©‡stsji\aocWVXPHYRSKFFE>?@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÐÏÌÃǹ¹ËÁ˾»É¶½Ã¾ºÊ·ÁÃÁ´¶¼¶±¯µ»­¨«’dmˆƒ‡‹€z}~xt~|swe_]\\^_`^_ccab``_^]\ZXY[[YXZ\_fkfdgehjor…ª¥¬¥žœ¡¤”¤š—‘¡£©££Ÿ¥¦§¦­ œ¤¦¬²°¶·§±­¨ª´«´º±¶¶®¶¹²°ºº±·¥ ¤Ÿ¦±¨«¨¹ª¤§§¨§²­ §¦Ÿ›¤¦¬ŸŸ§£ ¡±­­¬²´³´°µ¼¶»ÁÀ²»¾ÃÁ±¹¹Â³Á¾Àµ¸¼½¾¼ÂÇÅÃÄ¿ÀÄ ƒxplbf`ko`UY_HNgOTGFKF<=@=:;;825536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;>97776788666;::;9:;<859<:>>@;È´¶½¸ºÀº½¶ ž”¡¦º¶«³³»³ÄÏÉËÃƸ·ÇÀÌ¿¸É·»Å¸³Ä¸³¿À¬µ¼²¬¥¯³­¡£‘ir†…†€|xusomjiipi_`]\\\^__acb````]\[\\XYXXXVX[^_dcbegggkmoˆ©Ÿ–•š¡–›¢˜•Œž¡¢§œ Ÿ¤¥¢§ž›£› «°­±µ¤©ªª¬¬¤´¸­·°¬³¶¯³µ¯°ªŸžŸ£¢²¥¦©¸­¢¦¦ ¨­«™ Ÿž™Ÿ¥šš£œœž¯©«¨ª«­­°²¸¯¸¹º°¶¼»º«³²¹³½´¶±±¶µ¿¶¾À¾Ã»º½—„zsk_e^ddXTW]IW\KOGJJGA<??@;?<04535:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»·ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÅÏÈÈÀÆ»»ÃÃϾ¹Ç¸·¾·²Â´±»»¬¹º±¢ž©«§˜žm~…†xrmomkb^aff]]^]]]\]_aabccba_\[[ZZYXXWWWXXXZ^bddeffhikr§œ“””š—š¡––›¢¡¨žœ¥§¢¥œ ¡›™¯®®¯²¡¥£®«§¢µ°²²¬©¯³§º³¦¶ ¢Ÿœ£¡­£¢ª¶«££¦ž¥¦£–™—™› š—œœ­¡«§££¦­«²³ªµ°²«³¹´¯ª¯²²³·³®©­®²¸±º¶º½À¸³±”…yuf_f^[YVSZUK[QLIEHKIB=?AA@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½¸½¿¶¾¼¿³¥£˜¥±Âµ¶½­´¸ÁÌÈƿŶÁÀÇηÀĽ³¹¹³¿¶±¹»­²´¯Ÿš¤ª ”šxƒ„xoqtqhechdc\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXWVWadecdeddhjv ›“““––ž–˜“— ¡œ– ¡©¤ŸŸ©››«§¯°«œ£¤¸ª¡ ®¨¶ª§§­±¤¸°¤· £œ™™ª§¡š¬¹¯¢¡¤œ¢  “”¡”––›˜˜–—œ•Ÿ©ž©¤¢£ªª±­¨´¬ª§­³°¥ª®³±°°¯¯§¨§²®±´¯¼´º¸®£”zve_aVYXSRSKM^LPLGHLKE=@>=B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾·½®§§¢ª»À½À¹®´¸ÁÌÇÅÂýŸÈ̲ÁÂÁ®¼»µ»¼µ¹¹°¯°ªœ™¡©”‘Š‹€€|wqilrtphhedfa\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWWV[bcbbcbbcfi•’”‹‘““š˜œ•–œŸœŸ– Ÿ§¦¤¦§Ÿ ¦ ª¯¦Ÿ¢£·¨¡¡¢¨³¢¥¨¥°¥±®¬µž¡–•©¡¢”­±±Ÿ££žž˜›“‹¡”‘“˜˜“—˜˜—ž§›§¢¢š¤¥¥«¤¥°§¥£««­¦¨®¯¯«¨ªª³¥¦«¯´±®¼¶±¯¯ ’zwrea\[]XNLQHRaMVPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8847763321./2556;:8;7876<;:;;A8x»»±µ½°»±·¬ž¥¦¬·»¼Áź±¹µÄÉÉÀÃÆÅǶÅijÁ¿Å«··½¶½º»µ²«­¨™˜Ÿ£‹‰t‰ˆ~vncafihfgifil`]\[ZZZZ\]\[\^_\ZZ[YYZ[WUXWTTVURTRU``_`a_aacdi€’’ˆ“‘’œ”•–¤™ — ¥¢­¦¥¥£¤£ª«¥šŸ¥±ª ¡ž¥«ž¨¢Ÿ®¬©©®­¢¢¢•—¢›œ«©°œŸ¢ŸŸ—™“Šž‘’“–˜˜“œ¡£¤¡¢• ¢¥¥›£«¥¢¤«¤«®¥®²©¦¥¦¦´¦©¨­³µ´¹º°ª¬žŒrpo`[WVURFPNHZ\PRITKSLEGJD8;;=<8667:9;:976977:;:=<<6;<8>598:88659:;<97?<9678452121..1426:8698598989;9@9{µ´¬´»²°«²­¨§¯¹¹³ÀȺµÀ¯ÅÈ̺ÁÊÌȵɼ±½ÃȬ±¸Áµ¼À¼´µª¬¦•™››ˆrˆƒ{tiijlgjlmkjle]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURRNQY]\]]^___bdmƒ…Ž™“”’œš¢œ›¡©©«¨¬§©¦¤™¥¯¥•™¥¯© œ™›¡ž¯™œ«³ ¥¦Ÿ£¤¡”“›––’©ª­š ¡¡›”Œ™ŽŒ‘Œ’–•¢ ¤›£•› £¡˜¢¨££¨« «¯¤­·¦£¤¢¬­ª¨«¯³·²½µ³«¯˜…tsh[XYSUREXLQ[XMTNPLQRINIB=??A?=75799<<977:79:;<=>;7;;:=67:;8976989:6:=99577571141-+/434988::8::748=8?9~³­§³·¯¨¨¯®›©¨¬·¶«¼Ê»¶¿¬ËÆŸÁÎÏȳĺ·»ÂÈ°­¸¿·¼½»³µ¦© –—˜–‡zt€vwnmhmmmpggifd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUSSNPQYZZZ]]\^_ad}‹€Š}Š‰’–‘—™¢ › «ª¦¯¬¨±¥©šŸ­¡•–¥¨§˜šž®—™¨ª™Ÿ”¥¡Ÿ’‘’‘“•¨«¥š™™žž–Œ‹“†‰ƒ‹’•‘ ž¡¤˜•Ÿ•š¡¢ž”›¥¦¨¨¨ ±°¦±½¨Ÿ£¬´ª®§°µ°¹µÀ±®±«‘~rsbVTVNRJGVPRRLLWMJMORGMKACFDD>A75889;9:7::7<=:;@>:9;9:?759:9876958779;85576661320-*.102877;99;8948;8@8³¬¦±·ª¥¢±«ª§©²°¤¶Æ´¹º³ÊŹºÁËÐʱ¶·¼½Áñ¯±·­´´»³´¢£——”ƒ€vkglnqnrkpkdege^ZYZYZZZZZZZ\\]\ZXXXYYWXWUUTRSUSVURNNNRWXYYYY\\]ajy~t‡Œ†‰—‰””˜›˜ž©› «¦¦¬ž¨š ¦œ“Ÿ£š——…„’›¤•£–––ˆ¢››“‹ŽŠš¥§œ••—›‘’‡”Ž‹Œ€‹’’’ š¡¢–”˜˜•¢¦™™¤¦©¦¡ ´²§²¸¡œ¢¶¬©­¤²²¦µ¼µ«¬±£‰ysn]NQQLOCMNNPKFNNJJNNQHMJAHLHHC>858889:;69:68;99><8:>9;?8789:886857688974577820301+)-/12876:999984988A7w¶¦¤¶°¥§¤ª¥ ©¦¤³ª¢²Ãµµ²³ÆƶºÃÊÌƳ¬¹½´¸À¯­©°ž¦®º¯­Ÿ™š•”‡{ƒn__frpvqinieghj_XXXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQMMKLSWWVXXXX[]anquoƒ‡‡ƒŽŠ”‘“¡šœ£¢¤™¥—¢œ•‡™šŒsƒ~Ž—–†‘š”ŽŽ{™Œ‚‰Š˜ £ž“˜–…Ž‚”~~tŠz‡“›šš‘–Ž££Ž‰š ¡¤¤›¢´¯¬°¬Ÿ˜¥¸¦¦±¡°®œ°¼ª©¯ª™ƒwscVMROPMCSNLPMBPQHINRMHJJDKMFKK=749888;;69;7:<9::;79?9>@79:<89764445874312585/0102)(,-02764789::65:87A7x·¡£´©¦¥¨£¦¥¦¦¦³§¥´Á¸°´°ÉÄ·¹ÁÎƽ³¬ºÁ¬­Ã­§¢¦’¦¶­£ •–’}w~fWV_gfighnciigb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTRMMJHNSSSTUUVY[]ijqk~„{sNXr‚—†œ—‹”‘Ÿ˜•”–•–‰€”‰_;Vo|Œ”Š€Œ’Œ††sŠ…—y{†“”ƒ•Ž‘ƒ†}“xqp†Œ}‰‘—š˜“‹ŠˆŸ˜‡ˆ–žš¡ —§®©­¨¨ž–­³¢¦®™¬«˜¨´£©­£“sn_[NSRWLDTJPMLFNOIELQMKOJIMPFII=7599999:7:;:>>8:==7:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9y· £®¡¦¦ª ¦©§£©¯¨§´Â¹°µ°Ç·³½Ï¿¹¯®µÂ§ªÅª¢˜ƒ”œ±¢š˜†”‹‡}su]PLQUYZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MORMKHFHNQQMORTVXZ`lngzsPB?•’‘}ˆ•Œ„Š›Ž–•‰’ˆ†•†y‰`JQnx‹’„}„Š…n”xuvx„špQˆŠ†|~x”vhw†ˆ~Š‰–‹Ž‘’–Œ„Šˆ•„›‚„’š–ž”¤£¨©¥¤ž›°ª¡¤¤‘¦©–¢ªœ¢¦¨‰vmf^[HQQSMIUMSILKOIHFJNLMTKQPOFIC=769:8:;;8:;8>?99>=8;<6;;478;6775344696/3/.125221/,')+*,4833989:99::::?9w¶œ£§Ÿ¡¯¡§¨¥§¨¯¬ªµ¼¶¸¶³Á»¶¨¹È¸¶¨¨µ¶ª²½¦ž•‰“¨–•Š~Žƒ‚}wpoXMKMMNLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDDINOhYNQSTUZnƒru}ih\T‰”ˆt~†|…Œ“‚’š‹{†€v€xsovptŽŽz~Š«„y{hv{Žprmx‹’xz€{€vsr’xgu„„„…|•ŠˆŠŠ€„‹€”„|€˜”œ–‘Ÿ©žŸ  ©¥ž˜§¤’  –žŸ¤sha]\JWPRGKXROJLMRJJJLPHLQLRTMEHA=77;99>=:;<98@?::>=7==79937785675251472/2.,//200/-+(().12721987:8775:<;7v®™£¡˜Ÿ´©¯ª¥­«°±ª½´²¼¸¶º´±Ÿ·º²ª¬©¨²°¡š‘”ŽœŽ‘~v†x|vooiXKHIHGEHHPTTTWWSTUUUVWWWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQQSV^t‚{xfvŒ–˜Ž|gyvx€‰}„˜’q‡|w{ok~­}t‹{†’|ufv|†logs|‰Œ‡€lyq}qmvqhq~ŽpC‹…‚ƒ…~wwzŒ†}Œ{u}Ž’˜‹’š›£–™œšž¡œ–‹¥šŽ—Ž–˜xomfcZXXUQJSUTOPNPVKNKOOJROHNPLFD<<79;::?=9<:99??;8;=7<9999266856633611224.,,-..-0-+*''*.1362/876966527995y¦— ž–¡¦°¬®«¨©±¯±«¼¸¬»¾¸³¬§›°§¬›–œ¥©¤ ˜™…’yˆŽ‹Šuq{mupjmjXKFGEA@CDHLLMQRPQSTTTUVVWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNOQTX]eprlˆ§ªÀ~tyb{xo{y‰z}‹†omŒ’ytyjj€‚q–‘‹~–€I’˜nhx~‚midly…’†ksl|nr|†inps‰„†{~{vott†‚yyp|ŽŒŠ“ƒ–—˜š’–—™—–Œƒ‰ž’‹’†–€ojonoXVXTRQYORTTRXUMNHMJMOKCINGF@:99;99:><9<;::=>:8:<9?868727565541432/024*+**-.+-*(*(',-1250,5567485HA895w™‘›™šŸ¥¬°£­ª¨µ¯®¬´¿«¼Ã¿¥¢š•¤˜ž„‹”¡¡™™‘“‹sŽz€†Œ†totkpldljYNDFC@<>>AFFGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_IMOORWZQY\_§‡ašisye~omz‹‰v‚ˆ†tlš’ts|jjMy…“‰„Žg1v†sl~}ƒtfeu„„…€filukq|hqq|n“|t~}qpnum‚wyujy‰‚ˆ‰ƒ–’’‹‘””Ž—€yˆ—ˆ†Š†€ˆwkkoheXRZWYY[MPUVYXNIHEJJHGB@GECG=998;9:9<:9;:::@<9:<98>787715234533645031.**+),,++)(+'),,226,,4775478iO8;5n’ˆš‘™–£¨­ž±ž§º¯«²°Â±»Ãǚ–”™‹Ž…z„˜”Œ†q‡‚t‡Œ†yprpoodpf_TFIC?<;9:?@ADCEGILOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOPQVLAIQIb¯² q{xl}lqƒ‚…z„††yr¡•tx€su”‡5q¨Ž¡¡„¢…vp‡|‡|tŒ®‰€hgbjnrmp‚uioXupŽ›’wlz}mrnp€{svnbvƒ†€…ŠŠ‰‘‹‘‹‹ŽƒuxŠŽ€~ƒ€}Ž{sqqm`[]^[YX`_RN[ZXWLHJFJG?CABH?CD=;97=;:;;9:99;:?<88=:8;66651121253474531./,,+)*))***)(*)+/3DM2166643<vR7=7b’’ˆ–‘¤§Ÿ¯•¥´©®±®Á²»ÁŖŒ”€ˆ|n’‰ƒŠ‡†u‚„l•ˆˆ{txxlwnwci^JPG>?6449;;;=>@BEHLLLLNPQRTUVWXZXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL7CMRSDJ†v€||v~lvˆˆ|~…ƒŒ~u¢™y~†„™„šœa†ªŸ‹ƒzwˆ~‰‰Žs‹—„z]dqtz|wŠmhjbyo…‚znwt„zptyxkni]v†|‡|‡‡ŽŠ’—ƒ…Œ†}q„„}uw{|‰wpstfg`[[^S[g^WPTX[UGJJDKG?F@DC>AA=;97<;;=<::99;;=>79>9985653244004645554-,)+('''&(())((+++/00Uq=23331E~W4=9\ŒxŠ€”Œ‘œŸ¦‘ ª ±¨¯À±ºÅº–Ž‘”‡{†vkŒ‘‚}Š„Œxƒ€s „Š||p€~zgvkRWL@E211366688:<>AEGFGJKMOQQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMORLKT]YRJh„ˆ{‰y|q|Œz}‰‡~—‡v¡™ˆ‡’”¥¬ªH†®¯¯‹€“‹‚‹‚„’©‡€˜˜Š›tm|†‡}Žhghyn…‡‚…q„†Gl€wryvhmk_v}‚ˆ‡„‹y”œ‰‹ˆ‘zu‹v|xmow~€ttrl[^^[ccXge[TOPVYPDLKFNICFCC@@CA=978:::;;:888::?>6;>7585773344236656768;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|}‰…‡‘Ž–—’— ž¬¡¦¸¯³½³—’‹˜‹}tp~‰’~}Œ‚’”}†~†¤‡ˆ‚ˆ…x‡ˆ~s„x_cWKB60./23124668:=>?BEGHJMNQSTUTTVUSQOGC?80,#‡[>?84.]–ps£UFIKMNPW`XpY\^i“‡•€„‚…‘“~…ˆ‘š•‚¡¡˜•››¦­“š»±§»Ç苌¡¥”Š‘|qƒžŸ‘œv†…‹‡jhoƒt‡„Šq…‚w‡{v…}nvuf”Ž†‰ˆ‡ˆ‡ «¢•‰Ž—z‚ˆzyogkx~{~tle]Z[]j]af`ZOKNWRQIPJDNGCJDBADDA<:87=<:<:88778:==8<=68656623444576867<BB?<8:>CQ^e\G2'&,,--.1(?‹[.310Oƒ_4?;nupfwƒ{€ŒŽŠš›¤¡¬¦«¯°—‘‘„¡”„xwŒ”|~’…’•Š€’›Žƒ€ŒŠ‚‰ƒŠ€mpj]B@4--//..02234778;=?BDHINQRSRSSTRPOHDB<87/9D><<63.l“—MPHIKKKNV_cggmu›š’“‹Žšˆ’‹  ’£ª¥£¬“©¶¢¨Á®ǯxº”š|¡ž™„“…‚Ž¢Ÿ“˜’„Š…™‘–lpu‰Œ‚–ŒŽw„qm…Š–‘ƒ…ˆqˆ •†’‰Ž–¤µ©›”¢ƒ‡“ƒ}kjj|‚tb^d_[gk]lk^WKGNRQMLLFIPCDMFACEFB=997=<:;:987767;:6=:785456344566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYo‚ou†qv’†~—–š”žžœ§ ©–“˜žge¤š~„’‘y’ˆ‘’}Š„˜’‚€€‹Œ‰…‡…‰…xx~gMR>/..,/.-/000212467;?CENPRTPPQSQNPIED>;<:CF?><752<?R5HHHLLMNR^oŠ|s} ›§¥¢™¡—¢”œž§ž¨«Ÿ¨¬©ª¶—«¿«¶ÈÈ·ÉÑϾ› pi«©Ÿ„“’…œ¡š›™§‘‘ˆ•¢››xz~”˜’¡“——”ž{w•’«²ˆ—Ÿ|”›Ž’•˜£¢¦¶¯‘™¨‡–ˆlss}€}ri`]a_agd`gf[REJKPOIILFFMCHLFGDBGEA:85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Ppt`m}awŽ}{”ŽŽŠŸ’—ž–›ª˜žªBD}‡‰‡˜x‚ŠŽ|Š†Ž‚€‰‹Š„’…ƒ†‰€†v^bP460-1/,.00//..0015>ABMQRSQRSTRNSLEE@<>=GG@A@8662<9;FHGIJNOQYm…w•Š£§ª´½¸¤­¬¬§¨´«°¶²²­»±³½œ³Ã«ºÉ˷ÿ¸¥¢°³¬­ª£‹–˜…¦¦ £—¦™¢«¨¤ˆ…”¤¡ «¡¤©›°‹•£¦·º› £°’¢¢ž£¡«¯¬²´¢”¤ªˆ™‰’‰•zz}…hah\eb]dd^fg_ZOCIHSNFHLFJGFFHAKFCFFA;87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLhcWioXz…v“…‡‚›ƒ’Œ’Úȝ–sV—ˆˆœ|†ŒŽŠŠz‡‚‡Žƒ…€‹…†‡’†‚„‰†ˆ‡‡pna@E64<2/110-,+-1.-4?CAMUQRSUUVUN[PGGD<>>FHCE@8;<5C;=FKIGHROPW’ „®£³ª²ÀÇê³Å¶¬³¿³¸¾¶¿´Á¶»º£¸Å¨¶Éǵ¾¹µ¨£´­°±›™’šŸˆ§¯«¥”vŸ¤—¡¬²³˜–ª®¨®¶»²º¬¯µ¢±«±µ»·´®´ §¨£§š©¯­²¹·¸¦›¶¨Œ¤Ž‘’Ÿ†x‚ƒvZbeWfaac``f`[TIDDLUQHIJDIGEA@@KDBMG<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AFWQJL[ZQbcWyuq”}„†“u…€Œ{¿»£¼‚´”“›„ˆ’‰ˆy†€Œ’Œ‡…Ž‰Ž†€†ˆ…Š‡‘zxn]V@EN<6:46AB764//6CHCQ[OQUWU\VO^UIKJA@?GKFFC;>@7D7?BJJEFWTP^¤­£±´Ã¶¸ÁÌɶ»Ä½³³À¶¸Áµ¾¯·t±³¥ºÄ¤°Æ¹±³±´¨¤µ¶ª± ¢–›¢’¥°®¦­¬§¤˜ ¬´»¢¨²ºµ¼¿Ì¿ÅŽ½³Â·º¸¾·º·¹¬¬°¦±ª­½°¼»ÁÁ«™º¨“­——ª‰}‚}kWdbYkejeW\cYVSIGFLQGCHIAHD>?BBK@@MD99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FRLALRWSYUZvjp~Ž„€ƒnzsx‡b¹¡™£‰””–’”“–’‡†{†•Š€„Šz|Š‡†}ŠƒŠƒ•}wzueO\dGEL;Qca[^SF?;HPEZcQRYXZgYT``MSPEA?IJHEEA@C<E6B>HGJLSZT]“®¸µº¸È¿º½ÉÌ»¼À»·µ»º¶½´º±Æ`u²¤±šž«½ª¥¨««¤¢²µ «§Ÿ•–Ÿ˜Ÿ®¥§¦¥Ÿ£”£§±´§²³½¶Á¾ÓÉÉÓÇÂÅÌÂÊÃÀ¾½¿»¼·´¯¸·¶Ã¹Å½Âȯž¹©¡«Ž¤¨¶ˆ€s`cb^Xb`igRX`VQUIEENK@>GD=KA=B@=F>;H@796379>489:57045/26389374426?8@>GKRTSQPOQQPJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKE@IMPRKQ]glkp…slrrs‡ÕÀµ™ •˜™‘Ž—‘––Ž†‡}†ƒŒ–‹~ƒ‚x{‹ƒ‡|‹yŠ‚—~t}zkepuY]\Pedb`ed][XW\MdmURmm_n_XgdUYUJDBKKHFHHHGAI9D?HKTTV\Z[“¸À¸½·ÆÀ»¹Êʺ¶¹µ¸¹²·µ´®¶¶˜du¨œ­p^¢¬œ˜ ¢›¤ž«¥”ŸŸ”Ž–˜—§Ÿ¥Ÿžš™ƒ¤¬¥ª°­¸°½¹ÔÑÎÖÐÉÌÒÌÏÎÊÆ¿¿ÂʽÁ¼ÁÀÄÄÅʾÈ㤻°´¯š«¸»™€{l^a]Y^aZccQ[`SPKCAEFE<@E>AHA@D=:E>=J?47535;=468977022/24169775555D3ELM>51/006:477@IOI;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODQ\Yh_o—’”nlouu‡³¬¡ Ÿ‹™œ™Œ•‘›’…ŠŠ~ˆ‡‹‹ˆ|„s{Šƒ…{‰t‰‡•s{ykmu{hreilifjih`fihlZms–­¤¼ˆ‡g[oh]ZZTHKNOJKPKSQHLAJGJO_^bfia—·Ç°¸²»½µ±ÄƵ°¸°¯»«²±§«·¬Œµ§š§šNšŒŽŸ–‘¦˜¥•Š““‰‰‘‘›¡—š•–‡žš§›¬¯¨°§´´ÔÔÔÖÒËÏÔÕÍÓÏÍÅÂÉпÊÉÊÉÑÇÌÍÂÐÒ¸¯Ã¼Ä¹¥¶ºÃ¢ƒod]]^Y`WYfZQ]WOPBBHEBH;AC>AG??A8;D>@H=46655;:687654/10146278875367C5B8?-0-1349=97,.,1;FK=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYSeVs˜‚hqoyyƒ ªž¥–Œš›—‹•‘šŽ}‰‹…ŠŠŠ‡|„‚pˆ†{‡rƒ‘‹}qxukqx~q{nxslhpmcjmpxiw|~Ë¿Áߧncxnc[a`JPRUNY^P]\NPNTQUT\nmv‚q–­¸¬´¦¯¶ª¬¼À°«´¦¤¸¦«® «´¢Ž±­š—˜Œ‘“‘„Ž›¦‘œ‰ƒ‹„Š‰„‹ƒ”•——“œ‘œ˜™™Ÿž«¬¤§¢¬­ÏÒÕÑÍËÒÓÔÐÔÑÎÈÃÔÑÇÍÒÓÓ×ÌÑÑÅÒÖÅÀÎÇǨ¾·Ïžzof^b]W`S]ZPQTPOH>@FABE<@B>ED>??:==<<JA45465<888664412/03526768533;=<E=@11+/249>5901022-2DN3)/3.32=N238C}_2A†tD:==I>@CFH<VRMN[u†…Šwlwp}~¡žž¡‹Œ˜““Œ‹“–„y…‹Š‡‘‡‚{r~€‡y„u…“ˆovrks||w{swqj€sripqzyrz¾Ëš~Œ²„vr„vhak]CZZ[VecXdjSX]]`d^cwz~‹˜©£¤¡Ÿ ¨¥ª°¸ª¥³£¡­¡£­¡§±Ÿ‰¦š“’‘‰‘ˆ”‰j”¢Œ™„€…~‘ƒƒ“–­‹••šŽ†’‘ž—§°¡ ¡¥¤¨ÈÎÏÈÂËÑÔÑÔÓÎÓÍÆÖÒÌÔØÖÖØÔ×ÕÉÔÚÍÉ××ÑʬÃÃ̌soda`XTYT\PKGJJJ@;:;DAD<BC>GB>BB;<9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/--;R017/532FD28>nb5=tM99@I<AD?A;PLFKYp€u}hsxr‚‰€•”…‹•‰ŠˆŽ‡xƒ”˜Šˆˆ‹‰~‚xs{}ƒ‡wz‡‘–€ƒnwpmuvx}t…|yl‡vtn}v„ux{µŒ;AŠÅ¥~Œ|ieWICfcecgjdnx[^fhknin€ƒˆ‘‹œ —˜ž££¦±££³Ÿ¡¥ © £±œ†ž’’’ŠŽ‹†ƒ„~œ›Œ‚„…z”~‚©•£Œ‘Š—’‹}—Šš’«³˜šœ¨œ§½Ãƹ¶ÆÍÒÐÒÐÌÒËÉÔÎÐÕÚ××ØÔÙØÍØÛÎÉÙÚÑÖ¾ËÌ´ywoe^[SVR[VFGJIEE=:7:@@B:GD?DCADB;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?1*(.BS39254/7K75<`bA<svV87AH:?C><9QECJTknnpbpqt†|—‘‹~‡’ƒ‰†…‰‚‡|x…––ˆŽƒ‡…†z„yqz{„†uz…Žy‹p|oozq{qƒ‡€nŽzuw}|‚u~{†‡¯sX©Â¶‘‚pnb=^hrpqpnxvehoruxqz‹†Ž“‘›•Ÿ•‡‹“› ›žªŸ ¬œ¡š˜Ÿ¦žŸ«™‹šŒ‘„}ˆ‡ƒ…‹Ž ™“ˆƒ‡~m™y„˜†ˆ“Œ”Œ†{›ˆ”®ª”•—Ÿ™§®µ½©­½ÆËÉÉÌËÐÉÃÒÊÔ×Ù×Ø×ÕÛ×ÓÙÛÕÐÛÚÑÖÈÔ˕z|ji\[PST^HCFIH>A>=7:=?;=G=?AAADA>>:86DB755479.566435532323647553457EBDCEB56<FNSM[nfcnskaV>,4LG865434BF4=W_hLux^8;?F<<B<::D?CGRk_mdbfkv€ˆq‘š€z€~‚‚„ƒ||„˜Ž‡‹~††€w‚yn{{‡‚tz’ž vŽu‚tu}t€„oo’…t|€„zv†{‰·Å¤Áɸ‚•›wpeNfczw†¢Šxyv{ƒ{„vm“–”•—ƒ‰Ž–™—–¥œ—Ÿ–ž’’—£™«•‰‘‚Œ…‰ˆ†‘ž›™‰…Œ†—zˆˆŸ—ˆŠ‹‚}¡‰‹¼¡˜“—šœ©¦¥®Ÿ¨¶¿ÀÀ¹ÇÉÍÎÅÍÉÑÖÕÕÙÕ×ÛÔ×ÙÚÛ×ÛÚÚØÎÜƇ|{hjf`TXUUMLDNC;==<8:<>9=@6=?@<?><9867CA6455=80665547745613854564557HH=DJE7925;H>;::7IP]ZRUXK9T>;95327I8=NYMHxxd5=>C==@:6:>>@EQ_Yea][htzyl‰’wvzŠ{~€~|„{~‘‰„…z„‡zu}tm|}†~s~’‘žƒ‘|†~xŽ}xŠŠn‚š€t™†}ˆ„{}z¨ŽÃ ¼Œœ£œ}‰„}‰r‹Š~s¦šœ˜“…{Žˆ„hGq ¤Œ‹’…‰Š’•œš“”–Œ‹•Ÿœ” ”‘Š~ŽŽ‹„‰’–šžŸ‰Œ”’‘‚‹¥™ˆ„ƒ†„€¥‡‹‹¸˜‘”–¢§¡ž£¯¶ºµ¬ÀÅÊÐÈÇÌÏÓÒÒØÒÕ×À×ØÙÛØÚÚÙÙ×Û¸yyymkfW`\SPOICLB=<>99::99;=6?>><=9:;;37D?8378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWN<MTHN?96333>C;[X>5YypZ<<A<=>8589?=DRSRX_VXfmmmiŽŠqryŠ{z|{‡{|{‹‡~uƒ…yrzsm€~„~w…›¡šž”’€Œˆ˜‡€›’n‡¨…z ‹|‘‚ˆ„›}šŠŒ£¢Ÿ£® ‹‘‹…‹“†Wr­‹Ÿ«›ƒ˜›Ž[‚¢‘‚ŒŸ“”Œ†ˆŒ’“Œ”””‹‰‡–›•–‹’“…€‹ˆ’ŠŠ–™¢£†“– Š‰ˆœƒˆƒ‡…¤†Œ³˜’”—¡¡ž™’œ§²¸¬¦½ÂÇÎÇÆÏÌÐÌÎ×ÐÑÔ®ÖÕØÚØÚÚ×ÖÙٟq~uig^]XTWXC@HC>>>:49:;7:;:3;;?=>7;9:1:H>:37=@50677255?65;55858:57735HR7GOK994=EJB>1FCLB98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:;@;BQKKSYPTcbymb~’ƒomw‹xyz|†|{w†„sp…‚zuvvt„ƒ…}~’¦£Ÿ¥¢–Š”—‹Š¨—rŠ±„§’„™“„™Œ¢•Ÿ˜“‰š¢’©¯Ÿ•Žˆ–Œn·…šÄȲ›¡¥›œ˜–‘²‘d¤ÍǕŽ†‡‰’“”‰…Š‰…–™›”“†”—„‹™ˆª——££ˆ™Ÿ–šˆŽ‡——Š„ŽŒ‡¥‰“©š—“–™¡™Ÿ™“›¢³´¥£¼Á¾ÈÅÅÉÈÉÂÊÓÍÍÔ©ÒÑÖÖÖØÚÔÓÚ΃sid_^^OJU[BAFC;A=837;<:8=649:<:82?9:2:I:=67BC32:96264>=4;>6949;57944KQ<JQK9A7BGI@64JELF><88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBcFu‚Ž||l}ˆxz~z‚~vv€‚{ln‹y|xx|„‡‹~‹£³¨£«²¡–§ ¥¤–•®¢ƒ·•’³™¡ ‹¤›¯¢¤˜§–¨™­¯¤—••”‹˜™– ÀŽ£É¸«š¢¥­™‘šœ²†…¨¢œ˜…ˆ‰Ž•‹“‡†‡ˆ“˜”Œ‹““†”˜†ƒ‘œt‘™²–—¤¡ˆœ™“Š‹—š‰Š–Ž†}Œ˜ŸŠœš™“˜˜Ÿ” •Ÿ›¡±®£¤·¾´ÅÇĽÃÿÆÎÊÉÒ§ÎÍÓÒÐÖØÒÏØ»s{w^aVaWPHJOEBCD5>:76:?;<7=42669774=5<5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=89567=:JFDGN[\YJga;H„‹zzm…†y|„x€…}px|}|osz}{x†‹‰…„’¨»­¨²½¯¥®³³¨£¢°¬Šš´ž¢¸¥•¬¤—©­·¦¤£Ÿ™©˜ª£¯°©š™œ”•‘— —™»»­É i¶¸«°”˜ž¢«’—½£^ª²‚‰Š•‡‘|Ž}ƒ†””ˆ‡’–‹•ŠŒ–™’š³–•«ž‹›”’’Œ˜›Š’žŒ‰•Ÿ¢•Ž˜š“›˜ž”¡ ”œœ¥¯¨¢¥³¸«ÂÈĵ»½»ÅÈÇÂÑ¡ÆÉÍÍÄÖÖÐËÓ¢q|j^[U_RPFD>=CAA8?874>F<<6<35355454B3::BM:A;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPeHb`cpJ@‹Š~€r†‡|‰u‚Š‚~m}}|pw‡w‡{Œ†Œš«ÂÀ°¾Æ»²´Á¼´­«³¶Œ¨²®®½ª›»¤¨­¹·«¦¦¢¢££©¯²±ªœ¤˜›˜—ž¢¥¥’£¹®¨À»¬­²¹¥¤§}ˆ†œ­½°ƒ‹‹‹ƒƒ‘z‡Žœˆˆ—‹•—”š–œ§š±š‘«Ž™’Ž•–—‘ ‘ˆ•›¤¬”–”œž” ž›˜ ¡”šž¨§¤¡£°²¦ÁÆ𰺶ÅľͧÇÃÇüÕÐÍÄʉutc][a[NKCL@EF>A?B;:4>A==5=6>333242A17@BN>G@CNCA=C=;86CC5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GE?CF\gG`igZ][“ŒŒˆ{‡‹†ƒŒu†Šn~|‚q~z•z’””˜‘“•§´ÆÉÀÂÌÁùȼº¯«¹»—²¶º³À®¥À¤ª°»»ª®«¢¢ž§«®µ°ª› ªœ¢œ•ž°´§‹¢ººµÁ»«¨œ²¤¤¨”„Ž©ÃĤ‚‹Ž‡ˆ„†•”zƒŒ‘‘¡ŒŒ”‘‰˜Ÿ—“™”—¦ ®ŒªœŽ•’‘••Ž•‘¡”†—Ÿ ³ž”›” ¡™¤Ÿš œ ”˜ž¦¤¦§¤¯­¥¿Ä®©·µÉþ¶Î²Å¾Ã¼³ÑÊÈÁµvzn]Y]kSMICLJJI@A=CD<5AD;:3=8B332262A05IEM>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBg\Me\fTcj™–‰‹ˆ’†‰y†“r€|~w‡‚z¡–¨šš˜º¾ÈÈÊÂÒÉÊÂͼÁ³­»¾§º¿¾¼Ã·¬Á©¬³»½ª°©¤¥£«®´®¶µ Ÿ®Ÿ¦¢˜£´½©›¨¼À£¶¶¯«’¯¬ª«–†š©¦¥‘‚Œ“¥•‰€uŠ’y…‘žŸ“Ž”‹”£™—›””£ž©Ÿ‘¥šŒ•–ˆ}•’’£š• ¢œµ¦‘Ÿ—¥¤£¥žž¦˜ž•—›¥£©¨¢²¬¨»Àį¥³·ÌÀ¹®Ã³»¾Á¸­ÂÂÁÀ™ozcYW\\LLMIGDCHBBACK:4DH:;4<7E.12352B26SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQF7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>kI_XaZdeVžŽ—Žž’‰Š‰Ÿ’„x…•~ˆŠ€• ™®§£˜Â½ÈÄÈÆÓÍÎÍ˼·°º¼´¼Ê¼ÃÁ¶¶»­³¿¹¼­¯¨ ©§¶­®©²·šž­¢¨¡«·¸©¥¯¾Ä±½¸³§©³³­®–•¥¬§ ‘Ž’±Å§•|‘•}‡‘™ª™˜“““•“¥ž“™“¡£¢œ˜Ÿ™‹ŒžˆZ——’–¥šf˜£Ÿ³¥–£–¬­«§›Ÿ§˜™–™•¡¤¨¦ž¶«©º¼Ãµ¥´¶ËÁ¸ª¶¬³º¸®¨¸º½¸ƒno[XUVOFKSMK?AHEDGFG85FM;>7>AJ.32025B55PWN;LFKRLOGGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|hW;=@BFBrFiIRebLF¦”œ–¡—©–Œƒ‡¥’ˆ‡‚œ„ƒ•‘”Žš¢Ÿ¯¾®¡Ç½ÅÄÇÇÎÎÎÒʾ»¶±º»¼¾Î¶Ä½·¸·²²µ³¸²«¦œ««¸ª©§¯°—£®¤§¤¥´À°ª¬³¾Â¹À¸³§¸³·³®•¥­®®¤‹“•¡sÁ™}–™„Ž–š‹±•š™•’“™™¦£• ›–š¨œ›¡ ™‹Œ–`J–œš”š¥—T–°Ÿ¯œŸ¥”¯¯­¥š¡¦”“™™Ž §¢™´©ª³½¼»«°²ÇÀ¹¦««­±±£¡²²´¤rpf][OQLEPPPQ;HKIFHAC>9KT?A:=EM07544:B34NWO<JKNUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@CAF3>58JKCA=C;4EA:A?>H@5*B52,>c]g:35tde@R7&#3}iX;:BC@=REWRsbWFH«—™Ÿ¡©¯˜—‡‹§–Žˆ’…Ÿˆ„œ—ž ›£¥µÉ´©Æ»ÃÄÈÊÈÇÌÎǾº³¯¹¸ÀÁ͵ȺÀ¹µº±¯¯²´§£›ª´´ª©¦®¬™¤®¥¥©­º¿¨«¶¶¾Á¿¾¸³±Â¯·½«£®´¬¸¥ˆ›—¦›v¾ „˜œŽ“™š‹¯–¡œ›—•›Ÿ¡©ž¨ ™šª™¡§ž—‘ƒnv“¢š•¢Ÿ®²£«•©ª˜«®¥¤Ÿ¥©’’™›ˆ”œ¢ž–°§©«º·¾³²­½¹¶Ÿ£§¨¥§œœ¬©©ega_RLMGGNJVL=MDMIJACD<QU<AABDO18=77?B75UXN?HNQXRPQTJQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW;:=..SaMVHe^HF¬”œ¡Ÿ»¯˜”ž‹“ª›‘’“‰«‡¢žŒ¤¬”££¶Ç½´ÁºÂÂÈÉÅÂÎÈÁ½¹²¯¹´ÀÂʶƱÀ¼´º«©­¬¯£¢˜ª´º¦©¦¬ª¨¯§¤««¾»¨¬¼³·½Æ¼·µ¸À°½¿³©´¶«¾¤¢—‘¢Ÿ¼Ÿ‰™ ™–ž·Ÿ©œ¥£›œ¡š¨¥³¡›¥œ¨ªž™•”š‹—‰¤¢”œ¢Ÿ µ¯¥¥“±«š¬¬Ÿž¤£©’•• ƒžŸœ•©¥¢¡´µºµ­¨µ²³žœ¢¦š—•™ª¡žwb^`^KIFHMQIMEFFBRJHADGAVSDH<AGQ1;B7:BF79\YKALPTUSMWRNUJD@JJNO9C?5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-1:h]FDDœobGE¨—¤žžÃ­›—¥—™©œ–ššª–•¨¦•­¬™¡ª¶Ä¼¿·ÁÃÀÇÄ¿ÍÆ»¾¹²°¸³¿Ãȵ¿¯¼¶¹·¦£««¬  šªªÄ¢¥¨¬¦ž¬¯¬¢ª¨¾¸¦¬½°·¶Ç¶´¹¸¾°¾Á¶´²´¯¾£–£–“›”­Ÿ¡¢¥££Ÿ¾¥©¨¬¡›¦Ÿ½¢˜¤ž¢©«¡–•ž“Ÿ‡…“ž¤ µ¬¥œ–²§™°¨Ÿšªž ™•Ÿ…Ž¡š›’¥¤š˜¬±¶±ª¥©­¬œ™ ¡’Ž•©Ÿ”idZa]PJGKOLHECI@=OH@;GIH[ROK=HNU4BF9>HG5Cb[KCNRUWVQXTRUH@8QQPM:G@4CHQSIC;C>GVKC@O>K<06;GF>;FA56?9:?9;15D0-,0Mv\4KZ5,MnW<-=)#zbQ5CKQ9oRF<KxecWL¢š£›žÅ¬¡Ÿ¬­Ÿ’£ž–¤ §ª¬—¶°£ª³¶ÄýÀ¶¿Â¼È¾Êȶ¸µ´°³´·Áƶ¾°¸´¹µŸ¦­ª«žŸ¥¤Á¥ ª® ¤©­¯¢¦§½µ¥±»·¶µÃ²³·º¾±ÃÀ¸¸­³´µ¢œ¤•‘“ ­ ˜¡©¨«¢šÃ­©ž¬®››ž™¦ ½¡¤˜«««¦¡™šŸ’ž‰ŽW•ž¦¡ ¸ª§“˜¶£Ÿ³¢ ›¯—Ÿ™”‚ —–¢¤•¦®²«©¢¢¥¥••™‹‘“¤Ÿ‰ce[d`LIJKNFEAFK>=JA99JJN]QQJ=LW\9FI=DMI8Hc\LCLPSYYVWOZ^IA=WQIK?H@5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+w`S6SZkWsHE6=ue\KNžŸ¡˜žÄ§¥¢³¡œ²§“ª¤Ÿ£Ÿ­©¬»°¨¬µ²ÈÃÁ³ÂĽÆĽÄʽ°°¶®°µ¯¿Åµ¹°°ºµ¬š¨°©©šž¦¡§Â­›¬±œª¢®°©¤§½·¦¶º½¯·Ä­³³Â¿±Æ³º·«´¶­ª¢¥••”£«¡ŸŸ™¨«°®®»²¦ ©©™™—“¢¤¸¡¡¤’®¯¬¤¦Ÿ’¡ž•ž‘”š£Ÿ§´§§Œ˜´œ£°šž›®‘Ÿ”—”š€’¢–Ž ¡“‹¦­°¥§¢œ ž’’›”…‹’œž€cf[hfKILJSBC@IG;;F?99NMU^RSJ>O^^=HPBLLI9Nd]LELRTY[SUO\bHA?ZQAHAKB7FELKN>;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<v]^?[U^fr@8<H–weA4Ÿ¤Ÿ›ŸÂ¨£ª±¡£´©–²«¦¢¤²¬®©»²­°´´Æ¿ÄĶÀľÊĵÀȵ«µ¨°¸¬ÀÄ´·®¬¶º¥™«±«©˜Ÿ¦—­»µ›¨°›­Ÿ®´²§ªº³§º²·²¸Àª·²Â¼´Å§¾®­·µ©§¬¡—–‘¥¤¢¢—˜¤¯¸­²µ¶ Ÿ¨¤™”•“£Ÿ·£¤¥•®±²¥©¥¢žššš•—¨ŸŸ˜¢ž®²¢¦—®™¥¬—šž¥‘›Ž”˜š…–Ÿ”Œœž”‹©©«¢§¡™ž–Œ™†–‰”Ÿydi]ljNPMNT=BANC;:I@77QO]^RVQAW`\BJSHWKH:Ud]NFON[W[RPQX]GAB[PBG>NC9HGHNP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1\cZ33806p[bH05JpiVCWFŒyfC;¤£œ¡¥¿¦¨¯¯¡©µª¹¯«¤ª´·±°¹¶°·¸¸Å½Ãǽ¼ÄÁÇÀ¹ÁÆÁºª¶¥­»­Á÷·ª­²¼¢•­°­±–¥¨‘ª¹ª §°ªŸ¯´³ª©¶¶¬»«²²¹·¬¹°Á¹½¾¦Ã«°·®¨ª«¦˜˜ª¡¡ ‘— °®³«°¹š›©Ÿ™–’—¦ ¶©¥¢¢¯±³«±§«Ÿ›  ›ž¤œ¡—£³°›Ÿ”¦š¡©›•¢Ÿ–˜Š•˜“–—“‰›™”Ž©©§Ÿ¤›˜›“‡Ž™‹~–†Ž›kimamnXQQZTACEU@;:IA7:XPd^PVWDY^^MLRN_KJ>Zd^NIQN[UYPKSWZI?DXPDF>N?=IGGQPB=CFBM?:2D?77547?=95E4+75/251.-.,1>*'+=\p=>1.1e[d@1647gY`F(@8l}h\V:‰{cC=¨Ÿœ¡©½¡ª°ª£±¸©¥µ²«¡­µ½¯³¸¼º½·¶ÁÿÉĹÅÃÀÀ¸Å½Á¸¯¶§«·²¼¿¾µ©®±·Ÿ—«­¨­—§©Ž§»Ÿ¥­³ž«¢±°³¬ª¶³µ¼­¯±µ¬°µ±À¹Ä¶«¼¯±¸¬¬©¢±¥ž¤¨Ÿ¤—˜Ÿ²ª³©ª³™§›™” ¥¤´®§¢¬¬®±§²¬²©£›Ÿ§¤”¡˜›¨µ©—™‘’Ÿ™Ÿ¡ž¬Ÿ˜˜†•˜‹š“Š–—š—¦¦£ –•–”•…{’„Œ–flshpr_GYfVDCNXDZ9HB6>]Rh\NY]G[^]NMRXdJJC\c`PLMNXWXPJVVWL=EUJEDAM?AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,+%2+*5K1.'_^aV150=`V^8)C3YU\gK5ŒzfL@¤š ¤¬·£¬©¥®®¶ª®´¹¦§°¸Å·±·¾Áµ´»Å¾ÌŹÃÁº¿ºÄ¸Á¹³µ¬ªº·»º¾µª­±¶˜˜¨«ª«›¬««½ž«®±£ªŸ±­³®®¶²¹¶©­®±§µ°³º¼É²ªµ´±´¯®¦¡³Ÿš¨¬ ¥••š™±¢­ ¥¯–¡¤™™’¢¥¦²©¡¦±«ªµ¤­°µ¯£˜­§š—ž™™¬¸¢˜“˜œ¡™—”¬Ÿ”“™žœš–Š”’žš¥£¢ ™–’’–{‹…{ŒŠƒ‹’knynu|aF`jZIHZ[={JGE6AbTiZM\aJ[]ZRRSbaLKE`a`PLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`Va.5(C^Q\.*A/JGP[G3cYTKD™—Ÿ¯¨±©¬¥£®®µ©¶´·£¬´·Éº´»º¿¾µ´·ÃÁÍǼĽ·¾¿À·¿½²½®§ºº··Â·¬­±¹•—¦®«§£²ª”¯º¤­²±§§¢±³±²±µ±¸²¨®«²§¸¯µ³ÃŶ©´µ«°­©§¢¶Ÿž¦± ¤”›™”±§›Ÿ©©¢›•—¥¥¤·§¢°³«§±§¬°µ¬¤™¡¬¨›œ›”ª¸œ•ŽŽ‹™¢˜—§¢Ÿ–ƒ’–œ˜—–ˆ——š§¤ ’–‘–v„‡{…‚„ŒŒnqxv|]Kel\JOc\?b{GI8GgWe[L^bMXYWTXTi]POHa]_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANIg27'FaLV%-B.=ELQ<3rkKDC‘˜¤­¤­­«¦£°²³ª¶°¶Ÿ«µ¹É¹®Á»Ã·³²µÂÃÏÄÀÁ½´½À¿º¿½³Ä¨ª¹±¶·¿½¯«³³ §°­¥¦°¥ž²µ¬«²°¬©¨´¹¬´³µ¬´¬©«¨¬©¹­±°Ç¾¸¤¹¯©­­¦¨­°¥££®£©œ›š¯™¢£¢£¬ž£ Ÿ¡©¥¥¸¤«´´¤ª«¨¬®¶¯¢£¨ª› ™š’¤´š‰‡‘£ –Ž”ž •“…Ž”“›™–”‡˜’•™§œ Ÿ’‘Ž‘w~Ž…||}‡Š‰qts~}~\Rdn^NZf]FD–[G:NmXa[M`bNVWVWTYg^QRLdZ[TKGOTSNGIVS\N;P^JBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3Ce;6*HdHJ+:I?3CIS,>k>HIš©ª¡¨°¤¨£³´±´µ±±¡¬­½Ëº®Á»Æ±´­´ÂÃÑÄƾÀ²¾Â¼¿¸¼Å¨­·¬³¸¼Á°«²­¡¤§­©¨¤°£«±ª¯«±®®­«³»§·±²©²©ª¦¥£­º¬©±Â¹´¬¹¨¨¨­©§±¥©¤¢®ª¨¢ž›¢¬•¤—ž˜«¡§¨¡¬¥£­¬·±± ©¢Ÿª­°¬ž¦§©™£˜˜ §˜†ƒŽŠ‹Ÿ¡Œ—†ˆ‘• •˜•†–““—¥œœ‹‘Š‡…|w‡…‡usr‰vl_Y`ncQsr\K<„|F?WuX`YOd\NUVUWP\a_SONhXWVKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*35>10485(5/*,.30;),,'%234$,2-860)(1<^J0.IgDF8<B05EKX1@”\@MF•–¬§¡ª²œ©¨°µ¬¸´®ª¤««½É»±¾·Ã¯°­³ÄÄÎÎÿ¿´ÀÃĺÀ´ÉĬ¯·®²ºÀ¿³®®«¥¨ª°©¦¨²¥´­ª°®­±¯³¬³º¤¸´¬¬®§« ¢ž°·«ª­º¶¤µµ¤©§¬¬ª¬¡¨¦¦±²¤¦¥¡¡«–© “š ¦ž£¢ª¤¬¢ž¦±·¬¬¢¤¢š©ª­©œ¡¥¤£˜ š•˜”‚ˆ… ŠŽš‘‹„˜¤œ’‘›Œ“‘‘”£š›š‹Ž‹‹|‡‚‚{u€„~uw‹£‡yk^`ngWf‡dN@g’LDbzWbXReUMVUUTO\]aUKNiWVVIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*49?./463)4+*,+.#4.-+&(+79*&6+<-2,&06XZ.0JgAA<<C+:JO^4D†AIHD–‘¯¤¢ª°—ª¨­µ«¶°«¤«ª©¼ÁÀ¸¹³¼µ¦²¯ÄÉËÑ¿Á»¹ÀÀ¹ÁºÂÄ®±µ²´¼Á¾³²®­«¬¨¶ª¥­°ª¹¯¨°°®±«µª¶µ¦´¶«¬¤©ªœ£³³¨¨¤´´ ¶®¡©¨«¨«§ ª«¨¹¶©ª©©¡©Ÿ­›‘¨¡ ¤¢¦¢©œ¦´®§¥©¢£—¤¦§©œ¢££Ÿ™˜Ÿ‘Ž™Ž~‡‡…žžˆ„Š‹Ž‘„†•¢šŽš‘’‘Ž“Ÿ—˜–Šƒt‡xuƒ{x~€ˆprggqx\asˆiO]˜VHmyUdVRcOLUTUQOXZbVHPjTWSGPYUI>IHOQPxLNV=<KD?@A<@CUC9AK=5;E13;97*4:=+-341*8**+*,)*(/*&)%3;,$2)2021%/2Rc02?f=NX?C,?LT_/Ik7RE;•¯Ÿ¥ª­™«¤­®³´®ª¥¯©©»¾»Á±¯¸­¢µ¯ÉÇÈÑÀ¿½º¼Ã½ºÃÁÀ¿¯²³²¶½¼Á²²³«³©¥µ¨¤­³³¹¯¢­µ±¯±¹ª¸®ª®¶«ªžª« £¡¶®¨¡ž¯²¡´ªž¨§ª£ª¡¡¬­¨½¯¬®¬¡§§Ÿ«˜¯¢˜¢ ¨§ž§›™©°¨¢Ÿ¬¡ ’¡¢£¦˜š¨¥˜˜˜Š‡•ˆ}†„…¤—†‚‚Œ‡Ž‘……• —ˆ‘“‘•—Š…†xs}uxz€{tt{j‚‡£ui^elugˆ‹|RWp^JxsTdSQ_MMSZgNLVYeXGSjRR>BNQaQ:IHLSIqPLS;<I?;<=;@@W<<>H73CB15:93-5::)-31--6)(+-,52#2)',%.;.&1.0-14%,0Mh:38_=ad?F1CP[[+HO;XB4Ž°Ÿ¤¥ª£¥£¬¦´³°©¤°§ª¸¾Á¼°¨¹ª§®°ÉÆÈнÀ¾¹¾¾¼É¼Â¹±°µ²º¼¹À³´»­¹¬£µ¦§¬²¶¹²¦§ºµ­´¼¯¼¥­­µ«­œ©¯¤Ÿ¥¬ª§œª²¤³¨šª§ª¤©ž¢¨¨©½«´¯­ž©£ ®›š²¢•¤›¤¥Ÿ¤šš¨ª¥žš©¡›‘š ¤˜–©©‘™™“Š‚…}‚€ˆž‡€~Œ‡‘…€”›”…“¢Œ”‘‹‘›’•‡‰~€rzy~|hw|zupq~i†y„ˆd`hdr…{mgy]^VBW{mTaPRXKKMpt]HZ[gYEVgOC>KNDCA9HGKS?jaIQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11&/>KI1%90%,,09/,,+6'17#-/GjI14X=fbAJ7GS`U*=<F\@*Ž“°™ŸŸ©¥£¡ª¥·²±¤©±¦­¹Á½µ°£¹­¨¨°ÃÉÉÌÁ·½Àµ·¿ºÈ¶Ãµ´³µ²½¹º½¶­¹¶¿­¢³¦««¯µ·´ªº»¨±¿²¹ ¯´¶©¬ž­±£œ¥¨©¢œ¤°¦¯ Ÿ«©§¡©œ£¨ ­»§®±®¡ª¢£­žž¬¥—Ÿ› ¢œŸ›™¢ª¢š™££•–“Ÿ¡–›–¦¬‹ž‘‘Œ‚‹€{š”‰}~Œ‡ŒŠ…’˜‘‡”¤‰’’‡š“ˆ|yl}vyxb{zrppsxj‚tj‚gchansŽmbjp`oA]ykV^NPQJILSYVM\^mWDXaO^PHMDF;7HEKO<rhJK9AE;;==;;=J49B<3;G<4?18-78;2(09/,5..=-*L>*49&'.34.0+/4&,:$40AhZ13S=e_DL6KVdN)=3Q]=#’—«˜Ÿ—§£¡Ÿ§£¸¯­¢¯¯©«¸Âº³­Ÿ¹¯«¨´ºÇÊÇ¿·Â¾¯´¾·Ä¶Ã²°º²³Àµ»¾¸©¹¸½«¤µ§¨ª°­¹°©™¹¼£®¿´´¡®·µ§¦§°³ Ÿ¥¦§ ¥™ž¬¨©ž ª®§ ¦—¢¨Ÿ°¸Ÿ¤±® ¬¡¬¤›¦¦¨šš›ž£•œœš©¦–šž¨‘—’˜“™•¡ªš‰‡}ˆ‚Ž||¡Œ‰yƒ…Š…ˆ“šŽ‰•Ÿˆ‘•‚Œ—}„{sp|qst`yxjopqpjsczlhfdae‡€`[rjqMN€iXZMPLJGPRQHM[_oTDXZRgOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23/:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%53=fd24M?e]FO=RZgH*?0\[5(–›¥˜œ•¬ŸŸ¡¤¡·ª°£´´©©¹Å¶²® ·¬­­°µÅÇÀ·¿Â¹°µ¼·¿»¿¯¬¾°³¿±½Ã¹©»º¸§¨µ¨§«°¬³°¦™¼¶¤«ºµ®Ÿ±¸¯©¥§¯²›¡¤ £¤¡–›¯¦¡Ÿ£¨¯¡ ¢“£¤¢¶°¡¦±«Ÿ¬¢®—›ª¤¨ž—š¤“šœš¥©™››¤””—”œŽ“—¢©¡‰Š…z„~„Šz—Š‡z‚ˆ„‰ŒŽ…Ž“˜ŒŽ–™Š–†—‹z€zpqvnpt_xwemllki„nfrikfi]ct`[kuiZJ^[XOOKHHRUF29]^mPDXVYeMHIEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<"8R=*113>D5,-'42*;+139cm74GAf[HTDU]hD.<2cV,2•¢¡—”›©œ¤¡¢¡·©® º¸¥¬½Å³°®£µ¯­­¯´Ãü³¿º·°³¹¸º¸º¯®À³´¹°¿Á¸¬½ºµ¥¢³ª§©²«­±¡šÀµ¤§µµ¨ž²¼©¨¥©¯¬™£§œ¤¥”—¡²¥™Ÿ¤¨©œ¢ “¤Ÿ£¸¨¤§®¦¥¡¨’Ÿ¨¡¡ ˜šœ ’š›–Ÿ¡ª›š˜ ”“–™”’£¨¤‰‰†y„{„†}Ž‰Š‡z„‡‰‰‘…•““Œ•”Ž”{‚—Ž‹w~{ltqllsawthhjggo…ghhcfij`jcig[e{c`StT\[SLJGIOS@!*h^jLCVU^`KIGEC.:B<F<6KPD8:D357==895?:;4>8@K=>93)8><:9*6@3.E4(+,?0-N?.+-7,1195,&.5-80576`tA3CDg[KWGU`hB379gO'2ž¢£‘Ž£¦›žž£µ¬§ªº·§¬ÄÁ¶°¬£µ®§®¯·À¿¼²Á¶°®²¶¶¸¶¶­ª½³®²±½¿¸®¼»±¤Ÿ¶«¥¥´©ª®žÁ«¨¥¯²©¬µ»ž©ª«±¥˜ž©§¤‘˜¦­¢˜ž¤©¡›¢œ–Ÿ§¶¥¯ª®¡¡¡” ¦Ÿ¡ ™›™œ‘˜”¥«¡—–œ”’Œ•—‹˜š© ‘ˆ‰‹ˆy…w‚‚‚ˆ‹‚‰}…ˆ††‘„–•Ž‘‘‘Œ’{ƒ•†s}}fxokjkguskcgddv€beffejjdkrZ_Y]mdaNiX[`VJGIKMRX>9_liHBTS\[IHFFA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A=-5B37=+*,0A*JK./*+3722(57$+7.72685]yN2>HiZLZJVbf@:3BhH%5š£Ÿ‹¬¡˜˜Ÿ–¤³±¢±½¶¡±Æ¼º±±¤·¬ª®©¹¼»º®À²®®®¶®²¸³¨«¹±¯®³¶º¶°¸½­¦žµª  °¤ª¯œ¢À ±¤®°®·®µž­¯­­¢š§©¥ž•š§¥Ÿ™¤¢©šŸ›”œ¬¯¥º¨®¢¡šš™ž£š¤—ž˜›”™ ’¨•©§š“šš‘‹”™””™©§ŽŠ‰|‚sŠ˜…‡|‰‰……ŠŒŠ’„”œ“‘–Ž€Œ‚p€~fymhkigqrk\hccsafhjnlgjjhn]lltpaUcideZIFLMOXQQVaeU@VSYTFHFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24;6#3*)6.55465Z|]19Kj[M[KXdd@A1JfC'4‘¡š°š“¡™¨²¯Ÿ¸¿¶ ´Â»½¹±¦¶°¨®¥·¸··­»¯¬ª«¶ª³¸­¥³µ²®©°·¶±³µº§©Ÿµ¨ž¨¢©­š§¾˜­£®¯´µ­¬Ÿ±­°©¢œœ£«¨›”œ¦£š©¢¤–šŸœ›£«ª©»Ÿ§¤ ˜™™¡k¡–™œp‚•š£u‘©§ž””žˆ—™€–Š¡x†”Œƒnj~vƒql†‹†}„Œ‡p^cag„˜†k‹”’tw‹„~ƒg†€guheW\hsnNPjcgr„g_dfnmj^_aŠƒ„eNKD9FTg^JGPPTUKHR`oteFZQUPFHFC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,+08>G601.*.*/568,#1'214:175Xl16Ok[N\K[fb>G1Qd=*.‹£™†”°›œ“ ›ª­ª£½Å¯©·Â¸½¼­§¶°¥«¤·³±³±¹­©¦¬´¦¯µ¢¨¸¶¶¨§¬·³®´­³¢©Ÿ³ªž¡¤›¦§˜«º•¦¥¯²¶­®¤©®«¬¥¡Ÿ §§›— ¥¥››§§“ŸŸ˜ž§ª£µ¯£££œ–———£ˆ¡Ž’š‡¡‡“œ ¤¥ªž’‘š‘ˆ„rxŽ…ˆ¡vˆŒi—ˆf}rx¡oˆ‡„~Ž}¡  ™€|‡žt‡Žv›Šl‡ƒlheczkqaS…mcli˜qYjqo‡X^i[kk[ˆqnzr…g†„Z^GN?G_MFRVVQQRWTg^MWIRSOEGG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82).1<I9/01.*/(-4583%&2115>1<8Xƒu25Rk[N\L\g_=K1Wa70(‹¦–ƒœ«™˜Ÿªª§ª¿Ã¯±º½·À¿ª¥·°©¬¦³´®®³·«©¥±­¥´³œ­µ¶´¦§¨³±­²¨®ž« ²¨ £¢š¡£š­³”£¥¥µ¼§¬§«ª­¨¥¡ ˜ ¦£™™¥£¤˜œ¤©–”£œ”“¤¥¦¡·££ ¤˜”“—“›ˆ®˜”‰©‹—¡›…±€£¬“™”y‚Ô¨€‡•Á›Çyx±¥·—d€Àœ¿y„„y„|‘Êq—¼œÅzrµ¦»{€l–±«°xhkX±®nei¼’¼nhznrØ~Sjb¶²r•tš¡ªWOWbPVNFT[XQPRŒ\W\P@\DQNDGI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22BE/.32.+/)-/186- /416A1=:Wƒw21Tk\O[M^g\>L1[]41!¦’€§ªŸ—œ¥­²¨±Â½²µÀµ·¾Â«¦³¬¬©§¯³©¯¶´§§¦´¥§¸®œ³²¶ª¥¤§±®®±¦ªž§¤±£¢Ÿž—›Ÿ®«”¢Ÿ³º£ª©¢­®¥¡šš¡§Ÿ—›§ Ÿ˜ž§§‘œ§š“¡¦¢ °¢ŸŸ£–•’˜’™…¯jjŠª~gƒ•†­dpœ“™¥”q®¡¤~x»}k¡v±_j´[¥€fœ‘`f‚zfjxk©d¾rg¦Œu±j|±xt’“cmm§n[„ Ehf‡–Euœ`~g|¤§‚Y_‹«i€–xyj§7J¯\XSld[KNW_\WV;N‰OXW/ITTICEF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3..53/+/(.0.:5/'$203B/=;U‚v2-Vj\OYL_gY:M5_Y30¢•‚¬§¥ž£¤ª²·¬´½¾°¶Ä²·ºÂ¦©°«®©©°®£°º¯£¤®²£¨¸¨ž³²°£¥ ª­¯¬¯¦§Ÿ£¢°›¢›—•—››¬¥–š¡ž³³¢«œ¢­­ ™— ¡¨œ™£Ÿœ™¡¦¤£š— Ÿªž¦¦ ›Ÿ¡••‘–‘š…µ›µx…©™µ™v†³›·~“•–¨”~k¦{‚†ˆ’”’w«gk±[«{‡”t‰q†€ˆ—x‚‚‹˜Œƒ „°vwŸqkkl|‹N¤XHcc™~ch¦`yruS’‡^P©mcq~‡€bœ.Q¡o[Skh`LK[dX\ZB>±yXXA#MhEBEA@A19>88:84;:9<9:A:E::;6:CB8=?KNG:5:AFB@AD<FD;0201;F,0.940,.(/3,>831/2-D1<<S}n3+Xj\OXM_gX7J8aU50•Ÿ•‡³¦¦¡®©§²¬©»¶Â°»Â­¸·Àª¬­­®¦­±©¡¯¼ª¡§´­£«µ¤¦³³§£¢§ª²¨°§¥žŸŸ¯–Ÿ˜”••—¬¡™™¤¨´¯¢©©¨ª›•˜ ¥§šŸœ¢Ÿ› £¤£•›Ÿ—™¢©›¥™œœ¢ —“‘“’œƒÕ“™¹p°Â~ņ|֔›»|™•¤œ¤{Ž‡£‚¥‚z¬yV¯zˆ~Ÿj¹Z¹v‡„}¦‚“|˜zªy{±nŽ„t¼…o”P¯§ÅŠQ zc`©ctrˆm—ˆ`Sµ´È†€‰|c¤3Bv]PjidP@XgZdaJHNmM[ROYfYCD>E?0=<59;74<;8=:<C:F:;>6:@C;6@OLH<:<DHCBCD<EF81211DC./0483+-).323971#%5*>3==Qwj6*Yi[K]O_fT7G:aQ71%›¢“˜±¨¨¥³ª¥´©¤¼·Á°¹À±µ´»³µ§±°£°²¦Ÿ®¶¨š§¹®£¯± ³´° ¤žŸ§©°©´¨¤œžª—˜—–—•• ªœ™–§­°©£ž¬¢¨–—œ¡¥¡˜¢¡¡¡š¡¢¦›ž¡ž”™›¦ œ§•››Ÿ¡™‘”‘œˆ²nhµq«‡nŽ¦r´sr¶{™—£‹£‘¡¥~°vƒ‘ÒÑv\®{…¤o›ª¦k‡…}­}—™{±s’y³e–t„žožf”RȋZÂ\Ÿyb_­`vs‡b—ˆ^Yʝo¿uMKµSUÆdTQjcfXAOk_lhOUGI8=VQZWXHC?J<2?;5=<46>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>HI91746@>/.24252-).26,742&60;5:=Pqh9'Wi\BOT_eP5G=aM620¡’¥¯­¤ª¼­¦µ¥§¶»¼²º¿·µ´ºº³¥´´¡±±¢Ÿ¬°¤—¦º®¤±°œ´¸ªŸ¦¡©¤²¨¬©¤šœš¨ž•”˜˜’’¢§Ÿ–’¥ª°¦¢–“­Ÿ¥’” ›¤¦Ÿ”š¥¦¡š¢Ÿ­š ž•›¡žœ¥•–™¢Ÿ•˜•‘š…¬{w¨v£Žˆ†©o­Š‚§ƒ˜˜¡‰’šŠ¢“™‰®…‚³\r³R®}ƒ‚¤q×}x…~ž†™™w¯†Š‘œˆx³ašeš‚”l’Z°XKšu˜yf`­_ww‡h˜ˆk]¯w•žxl5yÈ®²_BSo^g`EPm_pmVUM.echRXQ;AD@L:5?91=<16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK97<46:>/04333.2..18*.32%!03767=Pke>&Vg\@>V_cN6GC`I:99Ÿ”Ÿ¸°—´Á­¨³¨©²º·³·¿¹·²µ¼µ¤·³Ÿ´¬ŸŸ¨¬Ÿ”§µ«¨±±«­´¤›©  ¨¡¶§¦©¢™•¥¡“’›™’”¢¤š’¦¬¯¦ •™©Ÿ¢Ž‘¢™¨¥ •š¥¨œ¤ž¬¡ ”žš¡˜™œ–—¡ “˜¦ž†©}}¥x¡Žƒªp­‹§†•Ÿ¡ˆ——ˆ£‚‘ˆ”ª|€‹yo±Z¨‚‚ˆ ytØvˆt¨‚Ž›’£|–Ÿ„{²^œd ~ƒ•l’\«[Z“‘hgªdr{k˜‡s]¬Z‰ ŽkoeOJC¡\[Lt]bfM[a_rt_JV6J›“XHE=GFAM35A8.;>05A78@<6=<F?:<6?=B7.HVJEAH6KIN@IK@EN::@4.;>102144+*05/7,&21($$6671<PeeA&Uf[?2U_bL7FI_C2?8¡™™¿«—´Â®¬­©¦´°·±µ¿¹¹²°·»©º´Ÿ°¤¥§§ž“ª°©¯©µ¬ª¯¡˜¡ ¦¥¤º¢£« —›‘¢ ”“žš”—žŸ‹¨¯¯¦–›¨¦ŸŒ’¤—¨«§”—©§žž £­¤¡ž¡•¡˜Ÿ ’—œ•¡•–Ž«›®mr´r©ŒvŠ¦s´xs³€‘¤¢‘œ‰¤‡w¸oŒ{‹¢kk¶Z …e——i¡¢§m“r´t“˜²j…’ˆ­ku³af¢o‡’j—\­_M¡|‡‘Rs£mz~o˜‡q\¯V<œweTon.\§OcRkebmZc]ap{cSZQ>>mo3CB@?L9!7@6.;@37C58??3;<CDBJFMIF62JTKEBI6IJP?HNCFP=<E50;;010/75,+,426/#00,,289/9N`eD'UdY>/U^aL5FM^81C8¥š›»¡œ²À®®««§·©¸¯µÀµ¼°¯¹¸«Á¶©ª ›¦£¢‘ªª¨¶£²§¯ª —œ§ ¤«¸£­›–™¥¢•Œ¡›˜œŸ‘“”«µ°§™”œ¬ª—Œ“¥™¥­¢‘–ª±¤Ÿž¦«°˜¡£™¢–Ÿ›–œ—¡’œ©œ”ª™‡Ô’š»s°Ã€Ã†~Ֆ›¸x‡—Œ˜ŠŒ§ˆz£¶u}wv‚š²`ƒºyÀ|u¸bµŒ‡©}•¬©q{u¼ˆ§ ia¦Ž¯¡~Œt‡ª}¾ns¼t²ƒuxŠnšˆqn¤t½^w}[ay¼kZV[jz^jaegbmwoY[YCA@r@CG+5G"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-7A9§›ž¡¼¢—±Ã°­ªª¬±§¸¯¶Ä±¹±®º¯®À±«¤¢ž£¢œ›©£ª²¤´¦­¥Ÿ–™ª™¦¬¹£®˜” ¥ ’Œœ£ž—›•’¯¹±¬•—£§§“–¤œ¤­ž‘ ¨«Ÿ›Ÿ¨£³ž£¥Ž§¢”¡šœ˜•£˜° ’”©ž…™µ€‘Œ·•x‚“šµwmknsnz„Ž‰tžÁ»½š{²¨p€t‘¸ƒ|††Œ†{Š‡—|¤»¹½œuz³£tv—ut°u™žf†iµtrpw¶Œ^€z}Šhƒymyc‹¬pu…Z[§jEeZTf`c]cQggpltBMPLD:ZM?J3<0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITBKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7LT_G'SbV8*O]]=+:VV'>;<§ž ¡¿¥–´Â´¬ª¨¬«©»®°Å®´²®·§´¸­©¢¡¥ž ™“«¤­©¦µ¨§Ÿ›– £¬¤¾¦¡ª—”œ¢›‘¢¨¡“˜“—”²µ·­˜¤¤¢Š’’¦›¥ª›–©¤¥œš¡¨¦¦£©¡‘­ž–£ž———ž°¨”›§¡Žj~iœ¦x‡r}šŽtzd‡{½¾Àºo’‚q•‡`rjZ^›ŠacˆŽ•k`•cmwb•k€š•”e^`cqšŠhrŒ}…•gj~rtx}}b[wthP\n„}{‹kXlz‚sIJo†pMuMEW]gaLZWgc_O[mujqRODEN;HH=L?2-2A?8/5?C<9;@;=C>RVVWYZ[\\]`aaa`\UG5DFUEJOHFPIIH;8=51:.0;:.0-76=5&"/*2,%;8-7JR_I'S`V4)P^L(3=[O'?2>¨ ¨¡Â£š´¹¶£¬¥®§¨µ²«È«°²«´£¾±²¦ ¢¨£›™™¬¦¯¤¥µ©¥›—•¡š¦­©¾§¨¦•“›• š’—¤©¨‘˜œ°²¿¬›§§¢ˆ“‘©š¨£š›¬Ÿ£™š£§¬¢Ÿ«¢š±›•§ —•Ÿ—±¤—¡¨™œ‘œ¢¤˜¦¢šœšš™•gm}qw’—”‘…‹µª†˜•ŽŠŒ˜—‡”•Š„’”‘‰Ž’”˜”˜—š ¢šœ”¡ž‚z¤†lj||€t‰Šq‚xyvv‹€{Škstƒudw}wkp{m`c]phMXZfj`WZoynmfSOFS9OYMRO(+:KB635=@A9:C><ENSSTVWXYZ\]`bba_^^[TKCSGKNDGPLOI<:;389,2;820)6IRO8")+/2#4;*7FO[J&R^S10T^:+=8\K,<-@³¡³¡¿¡¤±²· ©¥²§¥°µªÈ«¬°¥µ¦À§´ ¤¤œ£•• ª¦­££¶«Ÿ™–•Ÿ–­©¥Áž«£•’œ—ž˜“”¢Ÿž¢§“‘™¨§²Ä¯š«œ«Ÿ––¨ª›œ ¬˜¡›œ¢¤¯¦¡¥¨Ÿ®˜—§™š žžœ¯ œ¡¦•˜’˜“ ¡•£ž— Ž–“ŠŠŽ–­|•›‚’‚‹ª¨†˜–Š„Ÿˆ{„‡…™’ˆ†Š•›——ž£–š“‘žŽf¡³¯…Š„vzŠ|vyzofz‘€‰kuyˆshszuƒ‡‚ktdyf`iecdfkYk{pij\SLPD_TE@??,4@F;45;>A;<?>>HNNOPSUVVXZ\_aca_^^]^]XVJKLBIOMRJ;<:786/2964.(&$-1./)+*7%+<(6CMMD/T]Q05M[17E4\G5<,@´ ¹¯¿¬«®²± ª¦±­¢¬³°Ä°ª«£³®¼£´›Ÿ¦¢¡œ™—§¥©¦¤¥³µž•”™™°¦®¾ «¢‘š™“‘•¡œ—¨œ„žª«¢³È³Ÿª¤«––—š§¨šŸ¤«“žž ©¯©¥£«¢®›Ÿ ¡˜¤žœŸ¯£˜ž¨“˜—œ‘¤™˜¨š—e‚’|e~™cylhk{’¤ªješ˜~g†Šeeih{Ž¡kh—‘¢wkj‹˜£ž™slnz„‡zXe^†‚^l‹‰€v\hsww’€‡‚nx‚x€smy„tw‰ˆŽƒ{i†Y^ktd]s‰ij}qkc^RNWJdXAJ4=F7?FD71<=?AD;;DGHHILNPRRTW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%/*+'6*$;'/AJ[J/7ZO6)EY/DO1YC;?.=¥Ÿº¼¹¯¬³°ª¥¨­­°§­­°¼±©§¤­¯°Ÿ­—Ÿ£¢™™¦«œ­£¥§©²­ž•£¢¯¦¶¹¥®£ŽŽš¡™’’› ™™¥•{¥­¢¨³Ä¸¤¡§¯ž”ž¢ž£œ£©©’ž¡ ª°ª«¤ª ª›¦Ÿ¨ ¬–¡›¥°¤—›ª•¡ž›’¥—žª˜ž~½ƒ‡r´r„…­hx¹Ä¸q“¢£z¦™™sª‚|ËÀÀ»q‹¢ˆ‚Ÿ}•˜ˆÀ½‚–ÂÁ{‚|’šÃÀ}k¥²oŒoÊz›w’ƒŽvz€yqz‡qx…“ymw”cf_yd`e‚c^thldbXLVIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^__`_^^^^___]\SMPGUNA??=6468276*&%#)*&.+*)109*#>I[L*#BP/#F[3PY/UAB;/8–£¹Ã´°¯À©¨”£¯©°®­¦²´¯©¥¦¦±«Ÿ«˜š¢Ÿœšª§¢¬¢¥¨¥¤´¤¢“¦­«¸³§¯¢‘‘™¥’‘ ¡˜›Ÿ‡§¬¤«­ÀÀ±¡©¯©—‘ž¡™¢£ª£“ ¡­®©¬§££§¡¥¥­©’¤š¨­©›œ©œ¬¡––¥•¡¢—œΔxz¤x”–›_®^Ž§¢ |§–›t«‚€¯^cªz§‡… t—“ˆ³c‚«†¡³j„¯t}—ˆ¸aƒ­Y£Ímu{Ú{™p~‡’v~e{ˆvvk|ˆo~…‘’~m‚`rlpg`_yd\qhjcf`RTRW]KOC5AHED8>6;@?A;=8@>??BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5578164('$!',&&/(&+360$7;SL+,-J0';\;L-!P@F4.1­ÂÀ¿µ´°¸—‘¤ª¨­³«¥²¬¬«¤«¦°ª §›™¥—œ¢¯Ÿ Ÿ¨§£¥¡ž°¬›•§®­±ª¨¬ ”’›Ÿ¥“Ÿ¥˜§£ž®¤«°¨ÀƳ¨©±®–’›¡—Ÿ©ªŸ• Ÿœ­¯§«©œ§¨¤¢«“¬³—¥¢ª©£¦¥¡° ’™¦™ š””‘— q…Œ—t„¨‡q±|q¬~¡ž¥žwª‚}­œr­~«‡†Ÿv˜’z|—~ªˆ¢Œ‘Œ~«{‰”Ÿ€{­VœÄzo’Á}•muoŒmeve†oawnroŠ‹’ƒm’fpuup`gme_oiingcWS\aYRSC8II@D<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;91478452&# 1' 1' '45-&7=WJ-<'>1)3V@F!G:C1.+°ÔÆƲ´ £Ž££¢¬¯¶®¨±¦¨ª§­««§¢£™¢• ¥ªŸ¡¥ ¨¨¢Ÿ¯¬˜š–¨§¯¬¨¦©ž—”š£¢‘”¡­›¦£¯¬£¬´ª¹Í²­¦­¬–•œ¢˜ž®¬– ™Ÿ©²©ªª›¬«¤£¬›¯±¢¨«®¥˜¥ª©©±¢’–£¤š”’…¤j¤u‰z©tz²p‚¦Š™Œqˆ š‡¤``R«„®ƒ›v®¦††Ÿz™–†{f€£‰¤™†‚¤}©‚•‡®^}©U¢’z¢Ÿ€{ïŋr¯³³¹qb©¯ÂthŒ˜mš”pnyxxolfeeqpf|ib]W`iXXULLQLCCAB;C@@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799664,&$" ('"+-"$.!3-&@DWH,G+56*1PKL# A9D4,'ÃÉÖÕ¿¡™«§¡¯¢ž°´°¯©­¢§¦ª««©¤¦ ›¤ž¦§¦£œ«š¢¬¡¤Ÿ¯¢›“ª¤µ°¯ ©›–”¦£š¢¨  ¥œ°¦¤¨±­·È²µª«©•‘œ¢˜Ÿ¥³š ”œŸ§¬¬¤®š­ª£¢ª¢³®¢ª³±¡š©¨®¯¶¢’–¢§˜›‘|ªlž„‡u«y|°o‚¤‹‰Ÿ––Ÿ”Ò¸´¸É€²__”©ƒ£ˆ‡ z˜•šxªÉt™¤•¨ª‘“šŒ€›Š™ÆÆxf¡‚¥sŸŽ‚}¯]p´b°uK£†m§G‚“dž’|q—“€q{u~{n[fjrpej_aXdm\^YINLKEDAB>A<B?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75685/)(%&%$&),4ENPPMFKJVF*L0/=-5OTQ;<F2,$§¤ÀƸ­©³­¬¥¢œ²¹¬ª¡¦š¨¥ª«ª§ ¦¥˜ª£Ÿ¯«¦ ¬šž©¥§µŸ¢—“©ª¶²¬œ¥œ •¥¬‘™œ§£ ©¦®¡¤§©°µÂ²³ª­¨“‰—¤š¡£®¦˜¡•˜œ¥¦«›°®¨¦Ÿ¬¤·¬ ±¹¯›®§²³³¤”—§¢™ŸŽ‚NxšŸzƒ£}ƒ¤„†¦žœž“„¸{|y¹‚~Ìƶx›¡‘‹Ÿ~š––Švž˜Š¤˜¤©°……Ÿ„¬}š”b¥l¤p…}–‚r¬`£sq€š`¼}RUu’¤—{~“’‹u{s…q\mnxrjo[d_hnbd]KLQTAIHFI:9K>B108866877-*5==?BDGILNPTVXYZ[\__^]__\ZZZYUSOH@882.,*.+*'&?QTVWWWYXXWUOUF<E3:P[T6?H,- ‹‡™©«¤«¹ª¯ ›¡¬³³¥Ÿ •¥®­®ª§¦¦š£§¡³®¢©¦² ™©¤”£¶¢¢•—¢©µ¹£›¢¢“¡±™žœ§¥¡¢¯®¤¨¢¶²Ä±­©­©‘‡œ§œ¢¤œ¥—ž˜™š¦¤©š¯¢®¥¦˜¯¥¼­¡¶·­µ²¸±³¦—¯ £…ÑµÃ·y‡Ž…‘“¦x”¡wŒ ‘„¥Šqª†„´nrj™£›•Šž|˜™†‡s¯‚¥›¢Ž¦‹“Š•šmp²\¥s“zœl™{™|m©a£qqŸbs²¸hx”¦˜}Œ”x}y‚mixiyrn€u]ednmfg`J[XX<HG@U3@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^__][ZZXURRQF:2230/++(@QRTUTSTVWWXXWUUVTQOQ[U%!2AH$)%“sŠ­¿¿»º´ž–§¤­µ¡¢™•£¨§®«¬™¦¢Ÿ¦  µ§¢©§°£”¬£Ž¤®£ššª´´¤¤œ¨‘”—®  §¤§œµš¡ª¤¶¬Ã°©«©¡Œ„Žœ¡ ¦¢•ššœ˜›™¦¤¦˜¬¨®£¥›­¦¾¬”½°¬Ÿ¢°³¹«´¦š¨±£§—z¨}|°wŠ¤¥ˆœm²o ‡­|¡Žƒ§•˜€¬ˆ…®…Ÿ”© ¡—†Ÿ€™•€{’~«€š–‹ªxŸ‰“’€y¯]£}¦§d€|—sj¯]¥kp…™]`[Œ m•’¦™‚•Ž˜{{„˜kmc~tn€z`geqnhggCZa[>KT3U8BBC7$$3+''3, /6674359@CFIKMNQSSSVZ]_a`aaa]][ZXSPONI8052.*,ATVVVTTUUUUTTUTSTVWWXVUUQHFIJ#((½’šƒ©Æ¶Á³Ÿš¬ ®¸¥£Ž›¤£Ÿ°¯ªŸ¤Ÿ­™ž¹ £« ¯©š®¡«©¤–‰š®±¬¦Ÿ¦š¬—˜¬¡¡¥¡š¥­˜ ¨¦¶©À¯¥©¤Ÿ‹€›šŸ¦ž’”šš”šš¥¤¤š©¬¬¤¥Ÿª¨¾¤–쪢¡«²¹ª®§ ³®¨©˜v¯~‹œ…‡|º®Š˜e°Œe•­}¡ƒ¦•š¬Š„°…¦™¤¡¡‘… [lj³`­{{‚±lgo™˜Œˆ°[}´[¤ƒkÈ¢dŸ€{¼Xv´Z²}R®€z¬X€¡n˜¨›‹—‘˜˜|y~dt~b„xt€|ajgqmfeeOUd\BU_>J(>9=4!",%2. *1/04579:<ACFHJLNPQRTWZ^```ab^_\[XUPNJFC553./@UZXWXWXXWWXWVWWWWXWWXYZZ\\XWWGB;ҟ³²·½º´Â³£›¬¦¥¶¨ ‹š Ÿœ³³©Ÿ£ žµ˜ ´¨ª¬¯­ž¬›•¯¨¢Žˆ›Ž¯¬¨§¢¦™®’™¨š¡¤Ÿ™¤£¥™Ÿ£ª²©½¯¥¨žŽ}‹š•  ™‘š›’š—¨Ÿ¡š¨®¨¦¦£¥©»ž Æ¦¤¨¡«´µ¬®¦ž»­¬¬•€©’£¯Ž›€‡¤—˜€¸ÃºƒŽœ“„§–œ‚¬Š‚¯ˆ¦››¥ª‘~սªb£¿½}~£‚ƒ×º¸µ…”“ƒž½¾ƒk£o«„lœz²°Çƒj«°½¬xw¢¾¼t–Ž§œ›‘˜z‚‘›zc}{dŽgy‚{`lekjbPaZSj\@UaBN*=:4/$%2 $(0496678:>ACFGJKMNNQTW]a\__a^`[\YTQMHC?<A?5=SYXXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ»•³´±¿¹±½²¢®¦¥²¦Œ˜¥¿ª¸²¨¡¿¦§²œž±œ¹¨ž­¯¦¦””°¬—Œƒ›‘®¥¢¬¡£œªŸ˜‹£’¦ž§œš¡¨¢™ž¡¬­ª¹®¨£›—’{‡™‘¦›“Ž‘˜˜˜“¨š ˜©©¡ª§¡£ª»ž¨Ä¢ ®£ª³´ª°© º§®®šsuª¤·†e‰ pg­Šmow¤™Ÿu®˜”p‹q•¨£›—®¤rmmmeŠxon‚™qzjqig‰–•˜qii„‡gp†d]ˆbjoY\g~w¦_aqŽ‘ned€“¢˜™™‘˜Ÿ}‡•vf‡xiŽkyydlcflbKdXJlZ:QeER'K:+# ",)-2.5:4579<?ABDEHKLMOQSV]WZ\``a]][TPLHD=:AB7MXZZYYZYXXYXWWVWY]^^]\\\]^]^][[UW^¨•­³©¹¹²³ª©¡®ž£²©˜’¾²Äɾ¶ªžÀ¬¬£¡¨¬ º£¤®¬­¦—®©Œ…•–­ž¦«¡ž££Ÿ‘‹¤’§™¨™–£ª –œ¦¦§¯º¬¬š›“’{„—¥˜‘‘˜”—•¨•Ÿ˜©£›±¦ž¢«¹Ÿ¯À§¤²¥¬°±ª­«§·£­·–Š ¨¥¶‰–¢˜‡©š”’©³™›£« ±–¢ Ÿ¢œ ¥¡•«§“’Œ‡“œœ•š“˜‘Ž•…¤š—•‹“’Š†„}g‰~t‚vt‡‹q§lz”‘“’Ž•¡–š˜¢ƒˆ•riwq‹xw|zjldcodU`X@j[HcaOZ+F=+'!740.!%2(*699469;>?ABDEJKKMPPQXUVY^`ac\^UQJED>9=@ASX[\YWXXXXXYXXZ[[\^__`^^^__```_YY`¥–©ª¥µ¶®®¢°£­Ÿ µ±Ž¬Ç½Å»¹«¢¦ž›¦Ÿ±¨£¶§©´§¨‘˜¬¢‹‡‰›§–¬¥ ™§žž’•£—¨š¨™”¦¡£š§™¡µ»¨«™š{”‹ ”Š•‘•“—¥Ÿšª œ¶£ž§«·§®Á®£¶¦¯¯°¬©©³¸ ®¼™‘¥¤¦¶¢’¦Ÿ©Ÿ’Ÿ£¬¯›¡£°¨¯—£ œ£©žžœ–«’™¡›”–ª™™™––ž‘‰ •”…’Œ”Š€}f‹…u†uyˆƒsœj…”“‰}Œ–’’—”¢“ž˜¢„‰™‡{r–sz‹r|jod^pja[_YncP`dPZ:GGE>2==8/+&+)&&406668:==?AACIJGJKLMSSSUZ``i`eUPJACB:9EMV[^^[Z\[[[\]]__]^__aabaaa`bbbdb\[c—•¤¨£°³¬®£©¦­ §µª¥´¼¯­­¢£šz¢±¤¥±©—›¸¦£”™ªœŽ†Š‰œ£®Ÿ¢•§Ÿ¡’—˜›®‹ª–¨™¨Œ˜©Ÿ¹¶¥¦˜›ˆy‚“‹š“Š•’”’—¢ž¨žŸ¸£€„¯µ¢¯¯u¤½£² wy ª²º”u¬¤ž‰€ªd\bv Ž¤ž„—}n“³£§­ª£eŸ’sy™–p€˜¨—l¢§Šeœ¥œ‘—˜–Œ’œ‘†š•ƒ’‡Ž’‰„wjŽ†v†p{†€ai‡Š”’‹Zu•‘hhs{¦š™ey™‡ƒx˜j„‹ƒoy€kqe_vplkh\gebbpS\>NNNSG>@TD91/&4:316678<;>@AAFHBGFIKMTTUY]`hfgWQJ<DG<8UR[`ab`^`_`aa_\]__`aabcdabaaedchd^]f›•¦£¡¯±¬«©¥©®£§­¤’–«¶°²§›«¦¬—tŒ¯Ÿ¨ª§“—¹Ÿ œ¤‘‰ˆ›ž«š¢•§¡Ž–‘ž„u®ˆ¦š¨‘—¤‰œº´¨ ™˜‹‰uw“•“Š”‘”Œ“ Ž› ¦™œ²–€Œ›µ³Œ’¼§ ~§¢z¢®¶ŽŽ¦žƒ‹†±©¯ŒŠ–£šy€‹¬†œ¢§©§‡•…˜w¥›z‡›—§‚‚{œ±zŠ† —™”˜–‚‘—–„š™cy‡„Ž‘ŠƒmpŽ‡y€p€…†t†„•‘x–h’t št}™„¢ž‡˜“‹ƒ„™kŽŽ…lx{qqgdxojlj\fkjet\_ITLQ@E5.ZTU7)!09=>643568;:=>>@DI?IEJKGSX[Y[aaifYQH9EK<>aV^bded`aa`bb_]`aabbbcfgcba`edcgcaahœ—£Ÿ¦­®«¨¬ ¨±¦§©¥™”®È¾±¢—§©µž„¬œ§¢ ¾žšŸš |†Ž™˜ˆ¬œ¡–Ÿ ‘“‰†€‘¨‡¢£“—ž†Ÿº²§ž›’Ž…pu‰”Š”›‹’Ÿ’— ¤–ž«‡Ÿ´‰´š­ŠÊ‡ª®ˆ·…Œ¯‚°®ƒ©¥˜}¨r{wœ§–h•¤y´ŒŸž¦¨’˜Â«ˆ˜¡rž€š¥}—…•±€¡}¡“ ˜—Ž“›Š˜‘‹|…“†”’‰ƒmr…yq†„|„u„–€Åf©‡£kžƒ£›„šŽŽ†Š™qŽ“…hwt|whhuqhhk^dpmgmXgG]RM2E46Nac7&3<EGD:64658;8>==?BM?NIJLCPZ]\Wa^jm\QE=LM@JdX]cfhgbbbbcc`_babccceiicbbbecafcbbi”—¢Ÿ°§©¨¦« ¤¸±ª«§š” £¤«¤—¥ª·£¯€¡§œ¥ž‰”½™“¡’žy„––‘ˆ«™››™¡…Œw›œŸˆž¤›•™˜‡£¹®¥šœŒŒ~bm‹“Œ˜Œ‘’Ÿ” ¡™¡§~¡§‡­ –­žœ‘…€ «®†£©™Œš£u€™”k‚¬uM«x‡œ‘›¨§€©«}ƒ¡{z§iž’kg—†—¶‰ž~n`dYƒ—Œ{dh‹r™}y•l]{–m_Spƒ\_kyƒ`Ye‚}ƒ€—p§ªkƒ£nr¥pŸ… if m[nŠ|fZ`ƒbWPowfmtrkjo^kpmliXiO]XF9A4GD^k4,ICRMN=84859;6@;;>BO>QRLMBJ\]_W^^cv`MD:MOMTb\\ffiibbdbddbab`bdcacikdbddgdbgeach—– ¸ ª¤¦¬‘¡µ¼¬®¢™˜ ¢¥¬®¡®µ¢¨’¡ Ÿ¦›™˜´™‹ŸŒ•‹u”’Š¦–•˜žž’…†¬¤‡›Š˜©˜™š’ˆ¦±§¢–šˆ‰€inˆˆ‹ŽŽŠ‹’‹’¢Œ”ž œ¡¤“£¡” wœ–§ƒ¡§†©¬„¥xŠ|„š~¢ps”ˆ–{žŒym‡›Œ™›¨š‡{‚¢sv¦fž~w¤_˜z}’s¢n˜·´ºt“‡‚µ¨dÆ¸{p•·‹q€š¤bs¬«`}i³~n|†‚‚‹˜q£lr£tž„€£`™³–q|—Ÿ³ts[ž²ƒjbotvqioXklrrf]i^bKE=D6QAYq3=SG_JR=<395::6D;;@JP?UMNQ@E_^[YX``|dHC8LWUVcaZefkkbbeadc`ab`dd_`cknccddhdbgfchh”–•£¸™«œ“ ¤·µ®­ ›¢££¦®œ›±­¬“˜¡™¡¤™š”ž«›‹ˆ’x‹…q€–‰¡’”—}‰Ž¨ ‡˜ŽŠ‘£“œ›‹©¨¥ž—‡…~k{‡~}ƒ‹‰” ƒ—ž  ž‹‰wœ˜¢ŒŸr¡‹‡¨ˆ›¥–§ª~­Œ~z ™z£“xt–ˆœ}•Ÿ†›Ž™›¦†¢d¡|ˆ–›lžhšnš™{€‹§}rht«ƒžƒtªh•š]›…v„hªj€¸f\¨pœ`•Œ^§vu‡‰~žhšu†“’—ŽŸnšm§š]¨~x»k~ª[Ž„]³g\nrzxki\qjxyc`fXbAQEO7VCRo5KZZ_OZD@151;;6H?:CHU>YRY]>Db^V`Qac}jEB9N[]YefXfgnmbbe_aa__``ec^bdoq_deekecihgki•œ‰ªµ›§ˆc”›«º²°¬¦œœ©Ÿž®›ž°¨¬—¤š¡Ÿ˜–– £™†‰jˆ€r{—ˆ‹––„‘”˜zŠ„–£Š”†‹ž’‰©£ šŒ’Š€€i€†x—Œ{ˆŽŽˆ–š”¢Ÿ ¡“˜rhŸŠŸŒp’Œ©‡˜ž¢§Ÿ§|¯­£¢¸—w£³¢¤€ˆ”y{ªš¢Ž›—ˆ—q¡|…¯µ}kš‘¡x~˜´££«¨„™|›}štªZ]o{–‹xžbL~zz…cy—BLžY¢jr|Žm€ˆ„™u›x†‰±³›“§v‚ns}”o™sk¤]•vHedasq~~nf`liv{debR^W]UW@ZFQhDSW\bX^ID=B8?B:IF8LEXAWQ[VDFb\Z`K`m~rEC<U_bZfjVghmobfg^aa\]^ahb_ecvl^egfkdflihki“œ°­™„T^ ¦³¹³³©š¢Œœ«œœ©”¢«¤¡¨Ÿžš™•˜¡–ˆ‡‰w†oy•…›‹|‘“–ˆrˆ’¡›s‘‰™• ›…Ž©œš•‹‹Š|ƒl„…q¡Œx…ˆˆ“˜•|“£ ž£ˆ­†}µ„Žžœ{¥–z©•œŠ œ|§hwm~™t¡sq|ž†™p“ƒ®}¤ƒ¦ž™€£o^¨gu¢co¥aœÓ|{™xrsc¢†~£s¤vk³Œ`‚˜‰sª²¨¼wƒm~¾¦©´^œn}q—nr¢r]¤gs¦ah¦m›Ô™}…›pzz—k›|x—sn©¤gaeyp€„kgfdnuwg`cT[fQQbIWJT`WS[ej\eQFCKMJKBKE8O@QNXRYOSQafejRcwywIFEc]eZhiTihjocjg`c`\]]_hbahe|d^dgdkdjmghlh—›°«T\K~©¯±´°³£›™…™©  ¤Ž¥¨ ˜©Š™˜˜“™“’ ˜Ž‡†{p}„h}ƒ”šwŽ‰o†’’l—“|‰‘’¤–ƒŽªš“’‹…‰zƒv‡€nŸ†x€’†‡™¢—{”£¤šŸ‰³¡¢¶‹z¬§¤®¥p¨€š…€›‘{¤€¡™†˜rž„£®¯Š—ŒŒ¤•ƒ­¡”v´µµÉ¡s”ŠŸ`—©my•† ›u¡‡w ~’—‹oLf£’p›‡r¤{ztaƒk~ kqd_œq}t—izi³µ´Æ¦s˜~zkœ›«u„›mux˜išzu˜rPE}´^jvky‡fjhbtupnV^TYiPShIVMYSV]hknVgWMKAIMKHJOAQKPecimeussy|nu‰{{TPNl^h[kiRjhilglfce_\]\^ibdik{_]dhcjfomeile¡œˆ¯¦„f?”¡³«¯¯¶¢¢€˜ª¢¢¥Œ¥§¦‚š—–—œ“Žˆƒyjy†eƒŒ— yuŽˆŒi„…’‚Œ…zŒ‹•¦“ƒ—©˜Œ‘‹‰z€}‹yp¡†y•‡‰– •”¥§œ––„fnxœl¢d|q¥w›˜pg¦€–‹{¤zŸ–ƒ—ržvŠ”–¹nŠ¢b}™¡•ˆmri«ju mn¦_ši‹h–‡š•u¢€}š`Œ†uoˆbh ež~išuocfˆ‚mr¢Z_[b¡m]‰Œo{~srd¥mw¢dg§h™sŒ™o¢oS‰o _e¨T‹^T˜nmskr‚mpikyskoRYWWgZTmIYO]HXiisjYkVQREV\LXSaUik_wtz}p}|rƒ{sv€„v^QrbgbpgPjhhklnhdg_]^]`kbjivu]\cicjjslfkmcœ¤˜¦zetm‹§®¤©°±¦Ÿ‹€˜«Ÿ¦Œ¢¡›¢¢€–˜“š‹˜ŽŠ{†q€ˆh‹‹|˜›st‰}{d‚‡•Š‰–™‚|ˆ‡–¨‘¢¬‘†Š‚Š~€€Žsi¥„}†”ˆ˜ Žˆ“ª¦‰¦x•›~¥ˆ–Œ²˜ž‚¯—Ÿ¥w”‡y©t¤Ž„šn¤¢Œ’„Œƒ»n}¥¯ƒ†††“•œŸ|¥zq¨• –fž~o«c–Š•’x¨l©¢‰vˆƒwª‘¦‡j‘°kv³Œ©kŠ†mmŸž’•`~«‹ªv~Œ¥žvŸ}„¤• j›ˆw¬gŸ­Œ¶tw¾¤“Yƒ¦«aurtp|uqcj~nhlSW[Vab]kM]R]I^nnv`[qY[`Zgtenoqbqt`wz~yryƒs„{{Œ‚€vbxdcmsdRkgholrjfia_^\bkbmlzo\\bibljwmglnb•¥ª€ž¤–©ª¨§®¤™‰ƒ˜«šž¤‰›¥©…ŒšŽ†œ‘…’Œt†zˆ„o„~˜“tt†r’ƒm‹’‡†“}{‚…˜¦Ž¥¦ŽŽ‰…•v‚‡’ol‹©€ƒ‹”Ž‰œŸ‰Œ”ª£ €u”–ˆ~y”®£›q…xŠƒ~{r¦Œq}}z—–›„Žx{~~‡”•“Šv˜Ÿ ƒz}‰kŒ…[yxrzphn~’‰qu”“q†„‚eŒ^‹wus”uoynn‡m„…^vhxŽe€€…©›}t|–j‰ˆpv}†vmmgŒsy{˜x…[kXyinwrqpxxp]l†nigV[`W\ekcUbU_Q_pxxlkvejkkv}qrtsaoubt{xuyƒu€y‹…ƒ}{mldxn^Wnghukxjije\`ZciflqunZ[bkdllynhloa”¸¨¦‹¡¢š¦¤™¥œ«£¡„„˜¬’ž¡‰š¦š©˜ƒ›Š~–“‡ŽŠ‰rƒ|}~…{—Žsrƒp•…{}’‹††…x}€†™¤Ž|§¡‹†…–ƒ†Ž˜wr…©…Ž‘ˆžžˆŒ›¨Ÿ ªƒ‰”š~~‰–­¨’¦woœ‚y‘o}¨…p}•qkp}ŸŒ“ŽŒhm]ƒ‹Œœ›žŽs•‹ˆqtkvt€Xrn†‘}~Œj]jd{…„‰€`ixz›{‚‹‚u…‚gwŠ†kapqv^rŠˆ¦•…eŒƒnw‹„q†zpfge{ƒz–[\jgnv[{ywunss‚f\mŠkkbZZ_ZYlq\_aZ^]ft~ztotckkj{}s{xtdmuhm|~vz|{zz€€~o†Š„{}s~ysiT\qiluougkhd]aXkhlkqrmW[enlgsyohjm`‹‹ª°¡£¡šžž˜ž™¨£¢~ƒ™­Ÿ•ˆœ¢‘¥•{˜„|’™‰ˆ†‡Šs}‹v…‹„–Šqo€r˜†„~“„ƒ†Šz€ƒ‹› ‚§¡‡xŽ˜‰•‹‹œ—…ƒz¬‚‘—™”Šž‡ˆ¡«Ÿ¢¢£‹ˆ“›œ£™–ª¡§¦ ’›‡•{wŽ„§~~’‘’“œ²¦›•ž²“—„¥ŒŒ•›Ÿ‰›‚ˆ‘Šk|wxe‚†‹|‰„‡‹ˆˆ€„„w|yt™¡ˆ†‰žŠ„”~}Š€€uos„ƒw††Š¦ƒ…‡ƒŒ}ˆŒŠ‘ƒwl‚„}z™jrhatŠp}zwwovt]^o†hn_^Z]]ShrUc\\alhu||sopdkji|ny€qjpplg{r‚€x}„{m‚Œ†|zx|}zƒyNdvjrmpzekecb`[tfpfrqmU]ltmiyzqgikdŒ‡¹ž—¢¡˜•˜™”™¤¡ž|€š«Žž† œ‹ž–}y”ƒ{Ž™‰†„„†nx€€r‡~‰”„mk~z—‡„ƒ€†„†}‡„Ž›’‡«Ÿ„r‹†“‘‹‘}{ª„’˜–œ–‡†›¦Ÿ¢š…ƒ‘š™˜š¦Ÿ¥–€‰v{‡Ž„¥{|Ž‘†˜ª¡“ªŽ‘€Œ‰“šž‚Ž—~†Žƒox…rt`ƒ†u‹˜ƒ‚†…~…ƒ”myut’¡Š‹…š„„Œs‰||rr{‡ƒzxŠŽƒ’¦…ƒŽƒŠ‰Šw†‰ŠŒ}ol~|nhlmg_zh}{vtvu{w\_p}nt`c[]^QgnTdZ^bkivz~qlldkjg€€lslltoyo…yn‡€v‚€~…vq‚ˆ~{{|{‚Š`i|juhi‚ejc`i\cuhobtmlUcqyepzzsejml‹‰ž·š¡¤Ÿ’‘–˜‹šŸŸž{xž§‘œŠ‡¥”‹˜™yzŒ…|‰‘ƒŒ‚‚‚n{xs…}‹‘}kh}‚˜‰ˆŽ|}†„‡}››‘‰¨œ€pŒ‹Œ“‡¡¢Š…Œ|¨‘ˆ’—“–“xŒ£  –™€š˜’Œš£¡£™—‘›~…x€ƒŽ† ~ŒŒ|˜¤ ¡“™¦‚š‘‰“—›~“’~‡Žtt‚pv`~€†qŠ•|ˆŒqŒ‚…†Žgwqx‹˜‘~—}‡Šr†{|qxzŠ„zyŒ‚•¥“‹…{…†‡…v‚„‰ˆ{fr|y{qljf_~sh|uvs|s€j^`svpwdcY_^RkiTdY_ahjvyqfkdlhe€km~hoqk}x†zkŒs~tv‚†~|z}jrƒnsib‡hlb_qVtomn`xhmWjtvcuz{rbjoy‰ž²‘¤¥Ž˜† ›|v¥¡Ž˜€Œ¢Šˆš–x{†‡~ƒ‰ˆ‚q{tv‚…~Š‘xgc}†—Š‚ŠŒx}€ƒy–•˜–– ›~pŒ‚‘”†¦›‡‰ƒ¦•…“‹–—“’w‘¡¡—“–y~Ž˜—Ž–š¤˜’”›y…‚w„–~‰Œr—£ž¡“™Ž¢Œ‹ƒ–˜ƒ’•™˜Œ|ˆ€vq}nzd€|Š…p†“‚l‡‚€‰„euo{†’—Œ|“wŠˆ{€…|{q~wˆ…y„‰Š—¢•ƒ‹wˆ„ƒ‚w|‚Š†w`yx}txgleaijwstu}q|bcasntrmaZa^[leRcX`aikvy†qcjcmeh}ƒlhuhloi€|ym†q€„ƒt|ƒŒ€~z‚ƒ~|mv‰ttmeŠljbcuV„iqn`xglbjvpfy|yq_ql†…œ®—¦¨ž—‡†Ÿ“—™}xªœŠ™z—‹Œ˜y{€‹}|ƒ|€‚xtyzt}€„‰‹€d^}‹•‡…‡t}~Š}˜„—”—Œ¤¢˜s‡{”’Š§ŒŽŠ’ ‘ƒ‘”—‘‹˜Ÿš’s’”‰ž¦˜˜•–sŽŠk…—™z‡ˆ‰o—š£“•ŠžŒ†‚’œ’’•‡™ˆ|Š‰yqykul|~‹~m…’‚”xp‚ƒ}~Šdri{€–—„~sˆƒx†}vw|…€|‚Œ„Œ”¤x„‚t‰‡}€tv‰„oa{uzq}obocd{bnovsxwstau`oluno\\_^^k^P]Xcahmt{ˆk_jfjchwˆnflhjlh|zwnˆs„„}t†‰zƒ}z„}}Žrz‹xxnl‡jh_irb‡hqoevgnlayik}{xpawm‹€™™ª £¨žŠŠ‘†Šž‹•˜~w®™—}Ÿ“‘–”ˆw}{Š|{€vx€ptt{o…}€Š|a[~’†€„„sz€‡z’ˆ’‘œ“¥œ•‚}‚}Ž‹’¤‰ŽŠ—š…‘˜“–ŠˆŒ’œ“‹Œnƒ‘ˆž™¢¡—–‰–nˆ™ƒf…˜Ž“zˆ„Šp•š”¢’’‰‹™Œ‚ž}’’Œ™Ž{Š„‡srukpnu{‹tn†Ž’qu€{ˆ|dplx}™“}„ˆtŠ€s‡yn}€…{…‹ˆ„Œ•¨Œz‡|~‹…x~qp†„chytup|b_pakt^pj{yxlspex]nlsmsXZ__bkZPWXecgqq~‡f]ihgbgqndigdih€zwuoŽ…t‚ƒ{u‚ˆ…w…|xƒ…z€‰w‹{zrxƒjk_pht€jromqgole|cn€zwqlwwŠ~¢—¡¨ ¦›‡ŒŠ‡“uª•“Ž‡¡•“€t{v…xyrs{…krpzmŠv€‡nq[X~‘ˆ€€€vu€€ †‘‹’˜¡•˜xŠ€‰œžŠ†’—–…‰•™–‹‹ŒŠƒm‰‹Š–¡œ˜”…˜‡j„£‚f…Š~‹ƒ‹w“˜‘ž‘‰‰•~˜|‘Žš‘|Š€‚nuplmop{…isƒŽ˜Šqw€u‚ˆ‚xfrnu™Ž{ˆ„z“‘yv‡soˆ{…‹zŠ…‚ˆŽ›£‡{ƒu‹xxol„‚^rtrppxZ^p`pj^oj}zpmmjlv`pojqmZXaabnXQSZfgcuo„‚b]kmdbfk’n`ff_gkuqsp‹€uƒ€xu€‹€x…w‡†wƒ…|‡Œ{vŠjqc|c†|nqltjholvx_qy|tut€‚~¤•š­ž¦–…„—”ƒ u‹ ”“†‹›Œ•Ž‹zrxt‚pr…squˆkomumˆvƒ~€mnUQ«•‡‚x€wr‚z‚ ‚’‚““˜œ“šx’{ƒ“¤š“Ž‰•˜’„†—™Œ”‹‰ˆž„Š|r‹…‰ŽˆœšŸš–”“~h…œ‡g… ‡’„‘‚‰qƒ‘—›ŽŒŒx{’zŽ‹Œ‘–Œ|ˆ|€kvjnkll{~az~Ž–‚wz€xƒŒ|ygsls‡•Š~ˆ†{“qyƒovŒz‰‹zˆ}‹ž„|{w‚‹}wqjl‚ƒz`xpnlrtV^obr`_lnyphoffsthpkawe]Vf``rSQN\fe^ypˆ|_\hrbbef’j_hd[gp~pkqtŠ}v|…€tu~Œy{†xˆƒs†…~ƒ{y•xfrjƒ`ˆ}ookz`jntu_t}x†xts…|x ™±œ¥Ž‚Šƒš‡€Œž‹š“Ž…ˆ—ŽŽ„vtvs€po…spqƒojivnƒn}}musRM‚ßȒ֓|puƒvƒŸƒ“w”‘™œ™{”s…Ÿ¡““Š’›“†~––ˆˆ‘Œˆœ~Ž€wzŒ~ˆŒŠœœ›•“zugˆ‘†lˆ¢„‘ˆ—‚…cŒ‘™Ž•Š—‹Š‹qz”ˆ{ŽˆŠ“‘‰y…|~l{erokkyy\€yŽ€{}~†ŽzzhrjsŠ‰…„|”Šk}~n‹~‹‡|„y•š™Š|vxƒxsmgq€„mjtohjtnS^odpY_kqwfkjbfxropc_w``Vk_^vPNKagc]zp‰t\\ev`aeeŽcafbXissmjqvŒ}ty†‚uv~‹s€†z‰~r‰‡‘‹ˆ|~˜vesn}eˆ~opk€Zlnyysavz{vrwŠwyž‹›¯› ‚…wˆ•~}Š‡… ‘…Œ˜„’Ž‡twpyqn„omn~rdexp}mz}jhkc¤šÁÜ®ï¡slv„v„¢…’o–‘• •œ’r…‹£—‰Ž•Š–ƒ€•…‰€‘Š‰–~‡zu‰x†„œ›˜™ŽvŠvn…ˆŠ}Š£„‘‰œ„…^‹“—ŠŽ‰ŽŠŠ„‰m{–}ˆ…‰‘†v…}}k}dxuinxsXˆz’‡…y~€€…Œ~xeri‰Ž‰‚‚‹–…kum‡„~‚z•“˜uswˆusqguzƒbtmpbivgRaqglU_ntyard_h}prnZcrabWnY\xNMLdgb^ws‰m\\dy^`de…`cc^YjrknkrwŒ~tw„xw{‰qƒ„}~ˆ{t‹‰‡–†Œ~~—shuqym‹zntp€Wqzvyqewy†Œhv€‰rœ‡™§œ£’…}pŒ”xy‹„…¡Ž|–šˆ„{rwpsjokim|u^axw{qu{g`d|ëÚµÉÃ܈sltvŠš‰Žj˜–“‰q…‰ „‹•ŠŒ˜“|“ˆƒ‰{‹…vxƒ„r‡‚“›—”—†Œu‡p„‰†˜¡‚“Œž‚‰aƒ”†‰†‰‡‡j}”€}ƒ„‰Ž‚q†~qwhvriswlZŒ|’ƒ…}ƒ€„Š‚uaskˆŠ~~‘}mkx…Ž…‘ƒ||‘’–ˆnqzŒ†ulqlry`tin]kv`ReqifS`pvt`o`]h‚qsiWghbiXmV[uLKLfg_brs…i[\ey^^dg{`d_]YknfoisxŠ~ss~zvzˆs…ƒ|€‡vwŠ†Ž™Œ‚{“ulwuyx“tnx{|Xz†q€ogxw’‚cv†…qŠ–…™¡š¢Š‡so“‹rwŽœ}Šš‰‰|Ÿƒ™xqsnodr~hflwx[_y{{qq€jagaÕ¶Ž¦xnqw|q’‘‡j™Ž‰œ’Œ†{i‡‹™†’‘†‡˜|‰{}ˆ„ztz‚zp†€–šŽ“”ˆuƒ…uƒŠ’œž†•Ÿ~ˆa“‡„ˆ„‰€€ƒg}‘€~‚ŒŽ~m‚|‚tkmwtsvukc…~|„„ˆ~o_rp„{ŽŒ|~ˆypƒfy‚Š†‹‚{„}“Ž’ƒnoyŒ~umokl{~chkjYnvZSiribQbrwlbe^Zjƒmsb[g_dl_nT[pNHOge\gnq€l[[cs`\clwde]]Zklbmjtw†qp|}tx†x…‚}‡uy‰’–|ˆ†v‰pwy{„“om|w^ƒtmizt”sgs‡|r’‘ƒšŸ› †ˆvv•~mv”—~ˆ‘„ŠŽš|Œšv}vqoljau|fbiuzZ_w|zmqedhgW^qs–¼Ä„vq”‰~s˜Œ†“Œˆtkˆ•€{”‹„›Œ|Š†}|‰Œ”ˆu‰…uv}qu†ž•†•‚‚r‡tƒ{‰—œ—†“œ€ˆe}’‚…ƒ‰‰r}g}‹{y‡‹}i€}ƒvfoxxsvslj…ŠŠy‚€„ƒj^qwz}Œ‰…{€~r€hx‚†Š…ƒxƒ|€—ŒŒ}nlz‰}wtoih}we]qcXpsSTnribNgtxf`]\Xn€osYeb]jm`pOYlRDThaZknm{oZ[^lcZcovdg\]`kjclisvƒqn~{tuƒzƒ‚|…v~‰–‘xƒŠtˆryyŽoo|qiyz~mm|v•kjx„tk”…Ÿ˜ š…ˆn}Œvjx˜‚Š‚•˜Šy–ozspljd`tzh_er{Zar|yfpzaeeŽ±²wJbZ¤ÙЗr{‘‹‘x~•‹…™‘†pl†’‘zy’†„™Š|‡xx‰Š„–€oŠ‡qt}ziy…ƒ¥‘„“ƒo~‚v‚x…š˜“Š“”…‡oz’ƒ}ƒƒ‰ƒoxh€…xrƒŠ‡|e}~ƒucpr€hxqou˜…‚Š{vx€„yj[p|r€‡…ˆ}…ˆzˆr€mpƒ†Žƒƒrƒx€˜Œ„wmn~„wzehj}r`YwZYrmNXrsf`Jmvta][[Yt}roWg]fjp_oNWiR?Yg_[pjgyq\ZYkeYcpy_h]^elhfliqw‡om}€upz‚v…‰—Šq‚q{†|zz„”Œujzko~t}or|{”po€xf’Š‚¡˜œ’‚…g‡„phz—‰~…‚™Š|Œixrklf_aoym_boy\dlƒzaqv_eeÕ뾋2:>‹Ž€ry…ˆŽv„—“Žnl…Œu}…•ˆ|ƒxnv‡„‚–wnˆ„lu{tfy‚ƒ§ŒƒŒƒ}ntv‚y…›‹‘’Œ‹†~{’‡x€„ƒl€ri~xm|{Šƒxay„qdqh~mtqt›‹€…~su}€s€o[k}tx‰‚Š{†|ˆxypkˆ‚ƒ‰rx–ŠŠ~tmjv€€uu\iixqYW}SZqeL[rre[Jpwo][ZY]t~thYb[genbiMWfQ=^f]]vf_tp[YUodZdpyZh^`gmgilipx}Žlj‚„yn€{}€‚zu‚Œ“…p€‹nw~€{{ˆ“‰h{~kt{r†{sw}Œzx„~|kŒŒƒ›–Œ€l~ki{~ƒ”‚}Šˆkuqghc[bgso_alsahp‰zast^cd› n\5Y¯µuj€‰}’†v†—†tŒŠwpl…ƒ‡ty‰x‰|“ˆz~rgvˆ~}—op†}hvymeyˆ„¥‡‡Š~m}v€|‹˜†“—ˆ‹„‰|ˆq{}…|i~mj€{zjzv‚‡€r`w~qdrgu‚mu{…•‘|‚owy|t~mWm~vs‹†w‡u‰yxrmˆ€€„r~}}’ˆˆznmim‚un]hftrR[{N\q\O\rodVKsxjWYYZaq€t`]]`fdhhfNZhNAad[`va\umXXStaZdnrWj^bhkgmlipw|’li„Š}}p~~{‚zw€€‰‹„r{‡oqwƒ{Šƒj~{nxyvŠw}x€‚‡ƒ~zm…Œˆ˜£„ƒ{vŒykm„‰’y}{‚‘€€}Šƒpqpcf^Yg_pp``gpfjoŠuato[adiv{¾œ¦£È¸r…ƒs”}x‡”ƒtŒˆrrp„{ƒsu†tˆw”ˆyyqcw†y€’hr„ufwvcj|ƒˆž‚€ŽŽ}q~s„x‘‚w•”‡‚ˆz‰‰kxy~uhzikysizv€ƒ}h`w‡~jjsh{€ivŒ”~z~~q{v{t}aUu|rr‰ƒ‚|‚p†‰wxpo‚‚‹~}x}|u…ƒvhqhlˆ‚rp]hctnKevL^oUTYsmbQOtxaRWX\ap‚s[`\hedcjdP[qIDda\dq^\whUWVw^\enhVl^ajgeoohpw{“niˆ‹y~r{~y‚‚|v}ƒˆ†ƒpvƒrmw‚ƒ~‰‹”p€|xyz‹tƒx‚„y€vo~‰‹›žˆ}†zw‡|ht†‘z|‰†„v€gom_d\XeYmsa`aqllh‰n`siY^dm€w©ÚªÇ†‡²rŠxpu{‡€z“Š€utu~w€oq~m…t”†xtl`zyˆŽeqƒogun[m}“€y’’}wzm†u‹ƒs•ŠŽ‡……{…muvnhwem|vmjvv|abx†zhuuc~zgt†ŽŒ•{t€uq€z|lYUr}otƒ†~xkˆ†sxjtƒƒ}z|x{rŠ€|sgsem‹„mt[j_veHnoL[bWWVxmbPStvXPUX^`q„o\`cmdc^nbT]rGCf_]fh^Z{bRV\u[[gkaVk_anfflqhpvxŽtkŽuvx}wƒ{t}ƒˆˆƒoqtqu~†‚‰Š{wx„|}…‡x‡|}~„€{~svyŒŽŸŒ‰z‰wuƒy^~†šy‡ƒt††„w‰{bnl[b[[aVjtc`[hopg‡raqfW]ck|Ê·¹¢kmn‹mr…r}…Š{’…zytyutzjmuc„v’‚wpg^|y‹‰eqjjqcXl{†œ‰ƒ‚s—”w~{m‡p€‰Š†p–Žˆ…‹ƒzy~qqo}ghrbmxrjlqw}|z]ey€wiuxf‚vgt‡Œ”|r‡in~€ym|]Wp}msŠ{nn‰pvgv~€~u{qzt†{yqeranŒ‚lsXk_x\IolMWV^TU{kaOTurQQTV^bt…h\`kjfbYnaXbpGAh]`f^]V{^OVdpZ[jh]Wg`_rfjhrgpsw†xn•Štzw~yƒ‡€us†…Ž‚pp{wwuy‡…‡Œ†z|u‹~}†„„‡~~}‡|xuyw‘“Ÿ~Œ}‹nu€ydƒˆ—†t’Šo……‚zƒtcnjY_[]]Tgse`YdrrgsbkdW[`ix¾®{Ÿ·nbs‡ht|rzƒ†{}€xxsvo{vejna‡uŽsjb^~xyŠƒfq}hjkZVoxŠ£…q™“q€xtm†r”‡Œ‡ƒˆ…}ytrohyajm`mvkgkkzwzw[g}|xes}n„teu††•~p‹fkzƒtltb[n{kt|‹zft†}mpgt~w}~q{kz{ywpelam‰~mnVk`wVKklOROhNY|gbNUukMPTU^gvƒf]aphg`Wi]\khJEjZbdWYUyZNWnjY]le\Yec^tfldrgrpt€xp™…v~x|…‡}us‚‡€•‚nsxzzss…‡ˆˆ„y}v|„‰Žƒƒ{~‹ƒ{w|ww™—zŠƒ‡iv~|l„…”€r‚q†‚~‚oflgW][\[Sdpe_XcruivpeebW\\h€por€s‰eeyjtvssƒ…x„zwtunjzpbgkg†t„nf^_|o{‰~hlwfidUWrp§|„|v–s|r{ymzz„v—{‡†‚†ƒ}uprmgu]mh_ludgfizo{rYgvugp€x‚uaw…‹|”€n‹jmz€pere`lyfrv‰{}auƒvikqtzpyxr|f~~~xvnceam†|mkVjbqTLikPLNpG^{faMUtdJNSWajw~e]gsie_VcWbp]KKkXcbUTUsWLYvdZ_k`\Zce_wgmbpisoq~ut™w€x~…„z}v‚ƒ~˜…nrt{ztq……‚€z‹uu‘€}”Ž€…„|~Œ†z~€v{£¥Šyˆ†…lu|{u„‚Œzo…sz…}‚ƒunjheV][[ZScne[Xat{jimh_bW_Zi€iko€glahzykttto…z}vunzhjyj_enhw„geXbwi~‡zoioff]UXoh§vz|‘Žxuo~nrtxŽ~w”t…‚…ˆvjrvgho\me^ms_gajxh{m[mƒssio€~yw`v„„x„sˆqpyqcqh[nvdpsˆ{xar€pgixsqkwvtvcƒ{~wupcccm|}kkUibgTKlhPGRlEawfbMTr]JLTYdkwze_mpid\V_UnnWJShXf^XMUlTK\z_[_k]][be`zhlaoounowuz—}wy€‡†zyzƒ}“„qtt~yvt…ˆ}€}ls•{‚Ÿ…‡}€~†‚€Š{v„¬žzˆ‡„lr‚yv€‚tn†o|€tŠ€jpmddX_ZZZUbjg[Z_u‚i^nl\aV\\kert}ij]lwvgtwrn†{~}yvslzgixf]drgzw’ccTeog‚„wvfhi`WVYhd§n~x€‹Žzpp|fxny‹zvŽqƒ}~†ndvsdhh]lb]oo[g^ltezi]t€orkq{~uuat…Šz‡‡€wru~taolYprbqq„{udr€l`lzojhzwtqe„tyzuqdadms~jlTi^^ULscQGWbGcvfaKTpXJKWXgkvzdempfcZX]XvfTJ\cXhXYIWeQHbyZ]`l[^\bd^€ij_otxnonvƒ—yr€}ˆ‹†~uv†x†Œ}suuyzz‚ŒŽ}~„‰jt–{Š}~…y€z~|†ˆsq­Œ{{†~fqˆzt}}vro†l{~mzbpoae^eVYYWcfk`]]s†iYqn[^WZ\l{cqwvmc[msthuvqm…y€ywnotehte[gtfvv‘z_]Refj‚t}aci\TX^bc¥hytƒ†xlnygwl{„ztˆr€x{xhevm`fa_j`]tkYe]onbzf[x|knnpxyttdrƒ’‡‚ˆzvoq|rawcZnoapq|seq€d^mvicfxzsmnts|sqa^emo}eiThYZUNy`RKZYHbtdaITmSIKZWilr{cllscaYZ[av\SKc]XiSWHY`NGjvX_am[[_bc]…ihanxylojvxm‚~€’ˆ„vu‰s‹†sqvvw|}~Œ€~“~px–ƒ}™’y€€xy~sˆƒsp™¡{{€‰•yduˆysyvkspky|p‘r^po`gblTZYWhcmf\\r‰fSrn[YXX`lvdjujj_[mtqmtttk†|€|wonldiqc[krdtvs\WTd`q~q‚\ac]SZ`\c“Ÿerq„ƒtkjylnozzzq€wryzzdfug^b[ah\^whWb]phaxa[{vjirowtstip”ƒ†~„vrjp{mevW[jmbpr€zseo~[`oqb^io|lks}rpxkp`[ekm{agTgUXRQw\SPYRHcsb`GVkQHOZUkkk|emoqa[ZXYlpWROfWWiSTFZ\OHruY`dmcXa`a^Œjcdmyxkoiuy†{kƒ}€…™|‚„y}‡m†qowz|t‚‚}‹ƒ‚–tx‚”…Ÿ‰ut‚p‡‚uo¢—t{†‹‡{fw‹on|pfxqzlsvsk^tnagekR][Vhbll[\qŒdNon]VXUgithctee]Znunpuuzl‡}€|ˆwscekna\nmcsx‡kZTVbcw||p…\c_cT[`Yb–•cnpƒ„Šsjgynerurzkyttnz~u_fsc[^WbdYaufU_`mcaq]]~ohisqspuukl„“ˆ{…qrfn{oqnSZejeqs€vsblvUbqk[^nd|eku|rrrjm_Ycijx^fTeUVPUnXRWTOHer_aFXjNHWTVmhd|ikwjaW\U[tdSRVhQYfTSHZ[PNxw[`fliZb`^^nbfkyunnivv~mƒ€~†—{‡‰~k’ˆrgt€{u€ƒ~‰‹“r}Š‘…‡Ÿ†{†Œs€†s}‚un¤Œs‹wxn{`d|qgzsylmqvƒgd|lcfghS__Ug`lo\^nŽhMim`UVSofslexde]Yqumr{xsm‰{€wœ{zlaelm^`njepy~gZVX`kw{zoƒ^b^gVY`Wcœˆbkq†|wkjvl[vpkyiurmn{€rXjn^Y]VbdXeqcT^bibbmZ`~kfksunmwvkh…‹~ˆz‡mqfo{lqlbX_hhos€ts^imSepdUbnaybou{ujolj_X`fhu]eVbVSOYfSO]OOHeo]cGZiMI_KXmd_xhn}d`U^T]t[TR_fN]bTSJ\ZQZvv]_fmhXba[^Žqcgjwqsmgvsyƒsƒ{ˆ~|Š‡ŽynŠtlssˆ…‡’„•z}Œˆ‘›„€|Œ„rstwqn““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|}~}}~~~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’’’’’’’’’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’’“““’““’’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ‘mfggggg}…„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDEB1/0000.\pnmnnojfggggfo„ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‘g_```_^yƒ‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR4555553Sjgggghc_____^j‚€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}zzz|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‘ŽŒ‡‡ˆ‡‡‡‰““’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†………†…ƒƒƒ„„„„ˆŠŠŠŠ‰Š‰ˆˆˆˆˆˆ‰ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z{|{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘’’’’’’‘‰‡ŽŠ’“‰Ž‘ˆ‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…Œˆ‡‡†‰…ˆŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰‘††………‡ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰ŒŠŽ‡‹„‡„†ˆŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{||}}}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹ŒŒ„Š††ˆƒŠŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz|||{}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒˆ‹Œ‹Ž‰ŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzzz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{z{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†……………„„„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰Ž‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{~~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““”””””””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’“““”””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••””•“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””“’““““’’‘“’†“”“••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’‘Ž‘‘’“…|”“’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’’|„’‘’x““‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘’‚m’‰q‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘„g}’€t~ŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ†hp|t{ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽ]ivme{ŒŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹Š‹ˆgfm^igt†…ƒ„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxz}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzop{xy{|{xw{xuwttvuuvwq`tnaptjehklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkiffggghgcfnm]lupebcbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__ac_\_]`]^Z]fjoqqsteYY_[XWSNMKKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{xvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSTPMJMNPRONQ_cenoonbOQTPPNNOMJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTtsuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNOLMP_hgmnlgaRMNOOPONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKKHFINXfmhlmljhc\WUQOOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEBPZ[]dioikljijikkcRHJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:;>>=L^glknkomiijleTICDEEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@:;><;;<;GKG]mmnxqijhVHAEFDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnpprttsqrvyy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;:;;99:88;<979;;>;:OipzslcI=@@CFDCCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqtsurqtxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<:79::979::78:99::AWtqX?7<<=@A@=;;><==@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyy{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>><==?@===?C;===<>;;W_::<>=>?@A@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquutusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCDA?=>@A?@;]n@>DE??A;FX;==;:=>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVppqssttuyz{{|~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???BFD><<=@=8:;mwH8;:==A;I[:<=<8:;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pprrrtuvz{}}|~~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC?>AAABA@YQ<==ILEFuwM788:;>>P`;;=<::;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC@CsyI;]ƒy|wV<=?==>B]jA;=>?==>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hloppqtuvy|||||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCEAHrykb‚„ƒ‚ƒ€}]>@C@@>FnvM:=AEABBFHC=<@DDA@?>=@A>>>?<>@DGE@>@A?@CFECBCC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{{{}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@Fot}‚‚ƒ~}„uLACE@??W|\?CEIJIIMMKECFGGEGEEEDDCA?@>>BFJJGEEGFFJNNKJIGGHKLIGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@EEhs}|„~y…qBDEDCWu†‡‡~XGHJMLNOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHHHGFEFFFDFHGEEHHFHGHFQnnpqruvy{{{z}}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJG`{€w„…ƒ„ŠlAAVt‡‰‡‡‡ˆƒWHLMLMNLJGGGGDGGGGFHFHECDDFEDDHHCCCFIJKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrsvwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLLN[|‚‚ƒƒ…††ˆƒUl„‡†††‡ˆˆ‡|PKLKHGFFDECC@ACCCCFFEB@>>@AA@BD?>?DFHDEGIJIIGHHGIIJJIHFJJJJIJIJJJFILLJJKKfopsrtvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKLLJUƒ„„‚‚…††ƒ‚†…„„†††‡‡†ŠuIIFB??@???<<<>::<AA@><998<<=;>;9;?AB@ACCB@ABDDBCFHIHHHLMLGIJMMNMJJKKJLMSlpqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHHJJIe…„„„‚ƒ‚ƒƒ„……†‡ˆˆˆˆ‰ŒŽfBB=88::9878896479;<:8567689787688;;;=@;999=<>;;=ACEHJMLLGIHORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@CGIIj†„„~ƒƒƒ‚ƒ„†‰Š‹Œ‹Š‰Š‹Œ‰T:8656766645763468:876565676778:67789;7578979876:<@GFIFIFEFOSRSSROPPRTepqsttwy{{{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:=ECBf…ƒ€‚ƒƒƒƒƒ…‰‹Š‰‰ŠŠŠŠ‹‰ŠŠG676468874578567699766765:9:::;898987779:98878589;A=>>BA?AKLOQPQOOORWkqrttuwz{{{}}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897;B:=q„€ƒ„„„„„†‰ŠŠˆ‡ˆˆˆŠŠŒŠ‰‰Œz>988;<=>9::<9:;9:;:99;:9===>;;<=:=;9;;<;<<99<8::;:999<?<=ABDIJMKIKLWorsusvx{{||{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<;89989:::;?>H~„‚‚„………†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>BCEEAA@B>@B@@>==>@?>?@?@==?B?AA?A?=@@@>?A=><;:;99;?=;<==AACABCAXpqtttvz{{|}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::<=:;;==?@BR‚‚‚„…„…„†‰‰ˆˆ†††‡ˆ‰Š‹‹ŠŠŠ‹Š‹^>DGIKJIFGGDFHGEC@@CECB@BCB?@DHDCECEEAFEFDEFD@B?<@>=?@>?>?>?>>:;=<`qrttuwzz{}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>???=A@CCFW„‚ƒ„……††ˆ‰‰ˆ‡†††‡‰‰Š‹ŒŒŒ‹ŠŠˆVHMLMKNJIKHIJJIECDFGFDCEFDBHIKHGGFGGEKIKIJKJCFCCDBAACBDCCDDCA=;=@hpsttwwyx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLK@BBA98<>;<;>@?A>BBGGJY„‚ƒ……†‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹‹ŠŒPNPNLNKJLJIIHJFDGHHIEEHFFELLMIJGGHIJNMNLLNKHFGGEECFFFFDEHHFCA?@Llptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?EGG=<@@87<;<=:?@>?@CFIJQ_ƒ…„…††‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒ‹ŠrNRONLLLLJHGEIIDJHGKJHJGGGKLNLLHHIJMPNPNMOKIGIJHIDIHHFFGGHGCBACUnpuwwy{xyzz||}~~~~}~}~~~~~€€€€€€€€€€€€€€TDAABGHB?8?@8:<8=>;=A>?ADHJLUqƒ„„„„…†‡ˆˆˆˆˆ‡†ˆˆˆˆ‰‰ŒŒ‹ŒŒ‹‹‹‹‹_RRPMNMKJGEBGJGLJFKNKKJJMMLOPNHIKLOQQPQOOJHJJLJKFGHGEGIFEEBABB\orwxyzyyyzz{{~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<9@>>@BGGAGKLPVy…ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹‹ŒŒŒŒ‹‹|WVRRTROLKJDEFKONOWUQPOQSRMSTOMSLPSUVRSQPLJMMMKNGGJFFHJDDEEBDCcpuyyzzz{z{zz|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?==B?CBFVNFNPPTX{†ƒ……„„‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŽ‹‹‹hWUkaERQQPI;;QSR`u]UVTVYYRXXRZfPUWZ]RTWQONRPPPQKKKHHJHEFIIIHIirvyxyyz{{|z{|}|}€~}}}}}}~€€€€€€€€€~~SHJIHGFFE??AAEACGEDELXRMTUVX[|†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ}aŠ‹‹‡l[dU:XXXSQ?@VUY[c`VYbr]]V]ZVEQYZ[Y_TYgRVVXTTVTOOMJLJIILMKOMSosvxyxwzyz{zz|}{~~}~}}}~}~€€€€€€€€€€~~~VJJIHGEDDBA?HMIMPKIKPTSSXZZ\\x…„…………†‡‡‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~‹‰Š‹znpXZ\[RSRVVTZZtƒYU}`\X]^WIV]][[_YHYXY[]XXYWRQMPQMMOSQQURassvwwvxxxz{z|}}}~}~}}}~~€€€€€€€€€€€xy}YNKIIHFBD@A:PQQWXPPOQSTTXXYZ[n‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡ƒŠ~fYY\YTUTWRQWUb–€QerXZW_hP`f[[X\gaGOZhg\[\]]WSNSPPQVVVVYZnrtwvvuxxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZ[RSQORRRUSVTW_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PUXTRTRQQLOLKfy[]TYUV]ZLTZUST^ZXWWWzkX[[\^TQQPINOWVX[Zdprvvttvxyy{{||}}~}}}~}}~€€€~~zxwvsu{€€tk~~kry^[VUSROKFCDAM^ƒlVRSNOQOQURSRRTcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ymqVIKMNKMKHJDFHEC>TdURQQNKRTQMOYQMNQSUUMQSRPOMLHCIHRTUZ\lquvusswzz{{{}{}}}~}}}~}~€}}~~€~{vsw}~~du}iqt_d]][YVPLILIal’tPQSNQRQR[RSRQRVTbs{|€‚}{{€ƒ‚…†‡‚†††„†…†u_]KC?CCCCB?DPBC@C=CIGV@HNLG]iPHFNFDEFIGHCDHGHKGDBAD@NQMRdrtvustuz|z{{{||}|{~}}}~~€€€||}€€€}vt{mh|gnqfiedb\XSQPURsWe[OONLQSQUYSUQQTROV`klrv{{xytrnstsyx~~ƒ€ƒƒ‚€‚€‚‚kMG?@:;>@@??>jQKaEFHIEB?GLNGMQUIBE?><=<==?=?ACC@?<=B>JMGUnttustvxz|z}{|}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QRZ\Y^JJPQNKLQRQTUUWQQWVPX[b]agmmlokg`nrjmlqu{z}{xz||xwxeC@@B=:BCAADB\]O{NONNKLMOOQLKLWMHG@B<977599=;;;8989?<BH?\stuvuvxz|||}||}}~~|}}}}~}xuvz{zwyxuw{|yxuywcqhipmnmmhf^OP^\ZIHPRQOMPQNQRTVXSRYTNYZ[WY]^^_e`]^qvk^`gkwooljonnlfbYHFGHBAGIEEFDMRPaWRWQPSSRU[OOQWPMIDF>:96587979:365795<B=essvwwyz{}}||{|}~~~{}~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZWMKTTSPQUOLRSTWXTTXQLWYZVXXVXY]WWXhsk]Vaskaa_^da_^YTQNNNLIHJKIIFCQPS[WTTNQSYS\eUOSTQNKIHC?A9988978857578599Gnrtxxy{{}~}}|{}|~~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPXVVSTVOOUVXXYSUTLKTVUUUWPTUWTUR]n^RNY_[VY;DVXT[fJLORROMMNNNLJFQPUYSTOJNOUST\VRUSROMLIHHF?>=:787659967675Wpptwyz{|}~}~||}|~}}y}}|~~~}||}}~}|rvqxxrvuqqnppopuvtnjddjppqrpnfedc\^RTZVWUTWTRXXYYYRUOIGOPOOMRJOPOPNNOTLMIPOSTU2=XMI@Q=caQSQPNPQPNNMQNTRPRMILJORPRRSTQROLLKLLHCBA=::876;B5566:doruxx{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqptuvcjgeWhtrrqniihpVVTUXUWURWVUZYXWUQSFEAFGGHFJDHJIGEHLHKIFLMPMG/E_R>3?>joaRRQ@GUQPQPQNQOPOLJLLOPNNPQQNPOJLMMKGEEDB;=<<9=G6677Dmptvz{{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknaePSTRSTOWVVYYVQQQO@=;=?ABAC@BEDA@GHGHEFHJMKEGCORC8ENS]fSQSAGUPOQQPMMNMKLKLNOOQMOOMHLLIKKLKGFFED<AA>;@E;<89Spruy{z{}||{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLOOMQSLTUTXWUMLKI<987;?@><=A@B=>EHGCFFIGJJ@FAA@FHEJOHPRa\QPRNSOOPLLOMKMLMON[WKMQOGIHCHJKLJFFFD?BC><BG?B?Adptw{zz{|{zzw{wy~~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHDD=9779?B>;?B@@>ADIECGGIFIEBB?>=CBAGIDMObeQMNNWKLMKLMMMLKNNSdNJLRIIIEAHJLMNJGIFBAB@?EFEHDKnovyyy{{z|zwsxtx||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGLMIMPMPOHJD?A=999:?B?<@BBADEGKFCHIGGHCC?B??@A>DECKNRTLJIMTFIIJLJKLIJLMOPRPKGCLGCBJJLMONIJIGCCCDIJMLIYrmwyxz{{y|vrpurtxyvxjqnjllnttmtu{stxronqovsnporpopstyjN`gsjt|ygosqiqhdqHKDGHHGJKIJKDGB=>=:::;AB?=BBCCGFILJDIIFGGCC;A@B>@@BECIMPHHKGHKDHIKMHJLHIJKJM\RHHDNFADKJMMPMKMJKFGGJMNQNLbmivvw{x{z}qmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoiktgdoFKCFEGEFFGEGBC@=<=9:::@C@>BCDEIEIJLFIIGFFDB;BCC>@CCCEGLNHKNHDHEILNMHILGFGIILNKIHENIBFMLNMOMNNMKIHIORQRNRfffqosxu{z|lhjnekqlsqfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGJDFFECCCE@DB>@?:;;=:=>CA>ACEFJFIHKHGGGFEC@=EEB>BDCCEGHIGMPJFFGKNOKFHJFEDEIJHKIFHPKCIMLPMONOPNJJHMRUTROWd`amgproryzgehhdilfqlflmgiklslpvutpnvrosrsutqssutsuvvvyvutwljuumrvqlnlerLGEEGCBABD=BA>A=9:=?:=>@B>@BDGJFJFIHFFGECBAAFFCBCBDEEGGHFLQLIOJJLLIGHEGFDCIIHKJGKRMBNOMPOOOMNOKKKPUWVUTX_^\iaminhrsbefedihfnifmmhkkmriqvusqmvnoqrswsrstuvvvvwvwvvtwujsunutsqrjksMGHFHBB@DD<A@@C<89=>9?<?B@@@DFHEHFFHGFFDCECDIECFEBEGEFGGEJMKHQMJKHHIEFHIFCIJIKMKOSNDQRPQRNPMNPMLMSWVWXVX]Z]d`hbjigk_eefcgggkggkmkmlpqgttursnvoqprtxqssuvu‚‘yvvtxuuwxmouorsuqqioyMHGHHBBBFD<?BBD<7:>>:>:@B>??BEFDFDDHFDECDEFGJEEJGCGHFHGECFJJGMJLKHJLFIIKHEKKLMNORTOHSUSPSOQMNQNMPWZVZYVZ]ZXa```^hec`dfhgjihjfhnllnmqpiuuxrrpupppruvpusuvu{~}xvtwvvvxplupmstnprrxNIHGICACHE<@EBE=8:>>=<<AB<?>ABFCEBCHECEEFGGGIFGKHCIHGIGFDHKIGKHMKJKLHLKMKJNLONORUVOKUWSQSQRLOQPOTYZY\ZY[^^^`c^\ackb`dghr…hgjfjmnponsrjtuxrsstrnpqvrquruus~yŽ}uuvvvvxrhuqkrtlqvotMIKHJFBEGE<@GCD@:<>@?>?BA<@>AAFBEDDIEFEGEHHFHHIKIEJHHKHFFLIHHJGLLLLLIMKMMMOLPPQUVWOKVVUSSQQLOSRPV[[]^[\^__a`ad]d`ef`ehjcssfjhglprqossnswwquvtsmoruorspurvrtvuuuwvuwtgtrkqrkrvnvJKLJLGBEDE<@FDDC;??A@@@CA?B?ACHBFEFHFIFFDIHGIHJMHHJJILJFJKHIJJGKKMMJJMLNNNPLOPRTXVMNTVTRRQPLNTSRW[^^_]]`_`aa_acebchbdijgv‹ljigmosqpqppryvruutsmmssmqrotutrpswtuuwvuuteqskpqjrvowKMLKMGDCAD<?EEEC=AACBBCDACDAAEGCHGGGFJGDGJGGJFILHIJMKMLGKIHKKNQKRQMSMKNNOPPOTOWXX[NSQW\ZRWPNTUTTXZ_bb_da^`b^`eaacingbihhnxvlhimosrpqrrrvtsusssnksqmprotvrqquvuswywutucmtkopjqtowLNLLLGEA@D>>DEFC@CAEDDFBCEGCCHECHIIHIKGDKJGHJIIKHJJNLNLILHJLKZfJd\KlSHON_nUks[qpbwcSPbvuhucav`Xnqbdvinzf[lt`lkT_wvijgifglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqrqyLNJJJFC?@B?=DEFDCDBEEDFBFFGDDJEEJLLJLLGGMIGIKHKKIKKNLMMLLILML[sbdp^lmUMNfs]geqlntgpi_aYnnbppbkjjgoqtetno\ougpMJryvkb`keemxlkvmnpsrprqpqrqrrrtrmmsnnoprutqsstuuutwxvutbmukpplrrqzKLIHGED@BB@>CFGBFCFEFEDCHHGDEKHGLMNKMMFJNHJKJILJJJKLMNNMMJMMM[roonpplkMPQlWNibtrpamnu\YlQ\mmZqmkomxxtsip\_rkqjUuyxpc^kfbgppjjopprspqpqqrrqqrrtlmrmnnorutqtrtuutuuzvutenukpolsrryIKGHEEEBBB>@@FGBGDIEEEBFIHHEGLJGMMNLMNGLMILKIJMIJIJKOPONMKNML\hdu]lqWlNPQmUZk^klvaldsSecNmYl\tpkilxjwuhp]^rkhWbcw|oc`ggadityknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtvHMGIDEECAB<BABFDHGLHECCHKHHFJLLFNKLSRLGLLHNJHHNHJJIHNOMNLJNMJZsppoqqmlOQRnYqkgooqqomt]nXat_nopoqronusttj[]tcwxrjnzhaacfbbjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyxtukoumtonssvsHKHIBEEEA@=CDBGCHIMIFCFJLIGFJMLFOJKWRKGKJJNIHJLIKJIHJMMMMIKKKSkbZi^_icrrZ_Yjo_eeUk_c[aaQ`lh]j\niid[pfdp]Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunwqrvtwrGGFIDEDFA@AEEDGBHJLHFDGKLIEFJOLIPIL[QJEHHKMIHJJJKIHIGKKKLGHKKLLLKIKMNT[\TPTLPONOOVQOOQNOQJINPQdqiTYW\[\UYZ]X]\\cfaaebcf__fkmhmtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyxxuvqruovrtsuusGCEGFFAEC@CHDFGCIKLHFDGKLHDGIPKLOKLWLIEEHIJHIKHLJHFGGIGHIEFLIJKNLIP\W^P\[`^MXYS\\b^MYZMXaRJYaZR_d\aX[ddVVX\YZX\VY\]b^d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtOBCELMBDDBEIEGGFKJKHEEJJKFEHHPJMMJMSHGEAHFJIKKILJHFEIFDFGEEJHCJMKLU_Y`X`a[`TXYT^^Z_RY\P^\YN^\^SZ^c^Z]`c`Y_b[`^[TXWY^]cbcacfhekrpoppnow††……†‚{€……††…†…uqprrsvyyzyyxxxwryvxrqxvtvaSJJMIDBBCGHEHGHKIIIDFKKKFFIJNKNLHLNGHF>GGLIKKJLKIGEIDCDDBFJD@JLJO[cY_^a_RTRW_`\]Y^QY\MV_WKQY[PZ_aa]^ca`bbbcceZQYVU\Y]c`__cdbhomnllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxXQKFCGEBEHIFGHHFFJGHFHKILDDKJMMLKHJJHJF?GFNJKKMKKKIGGCD@DAHIB?IJHP]aZ[d]_TQRX]\\\_ZKW\LR\YIM^QO\_accccb\dcbdcfXQUTR[WZ`_^^aa_dlkmjjlnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMC@IFCFKJFFFHGFIFFFILJNFDKJLNJLIKJHIFBHHQMKKOMKKIHGED?ECHHAAGFET]Y^X_Y_[]UXXP]]QKJV^X^[]UY`RQ__bb``bb`cbaddbXOQQQZR[]]]]^__dhgljnnp{{|~{€‚ƒ„………………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKCAGFDGMRHCQJFHHHEFKJMPEFIJKNLLILLIIGDHKQOMMPLMKKHICDAEDHGBAGEDWUE\T^SV_XNTUNZZMJKT`a[_X^^a]NYb\``_bcb]abW__TPNOOWQ][[\\^`bffelfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDEFGDIRbPCV^IGGHDFMJPPEIIKKNLKKLKJJGEJMQQNOPMNLNHKADACDFDCAEFBMHBKLPONLFMFGIJHGLKMOPILOPOSOLQSRUZYWYXXdWOSTPPNMOTS[XXZ]\`adecgcklpsrzy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKM]LGGXLGHJHGMLQQILKLKNMUNOKKLGGKPSSNPONONOHKF`ED_LDfcEM[I^[rmOMUmYLCP`UkWgJ]WU^DLQULLSVQRTXWTXUT\UPfZhhdXRjSWVT[\[``aaab`fhfnkhrz|}~„„„„ƒƒƒ}|zr{z{‚€ƒ„„……„…ƒƒ~z{LHEGFHEEKOSIJF`SHJOJIOMRQKMLLORUROOJLNGHMQ[YOPPNOPOIJQQI|YYqsXPmHqnoaVPqqsPCksmqspSo_[nX]V\XUkhU]VcZ`Y[`VVXjtuu__v_Xa[\f[_aaaa^`bgmpl`pwtx‚ƒƒ‚}~€vxzlv~tx~€|~€‚„|€ƒz~wwNIEHMNBDLLFIKEQVLKOIKRXWQNOOMQTNOQPKKNGMPS[ZTQROPPPJHZx]TxehZRTQvgtlpbnfjQrOMwmjrpsrqrpoo€]ezuxqqzq~s}ku}bRh|essosr{|o}yor_``baZ``gknkblfgmw~€ƒ~{xw€tvzir~nt|~wx{~€ƒx|€u|||ssNKF`]GAEMMHJJGJPOMMJNV^YULQSNXZMSSRNKOIQRSYWWQTPPPQKHgxlcxrm[KMUypumubnvPdeJfvqmwo€jfxxiWrQhzmijzz}lxzohoYvvjuup`rg|ilx|o^__ba[]bdgiidgbcdllppstsssyqrxblugry{ssuy~suzn|}yxrnNKStNCBEPPHJKJKPOOOMPZ`ZXKTWPa^RVQYRLOISTUXWWPUPONRJKrouuquqdibWnLqp^FhyWvTLiy}x`y{sna]mocRhqunmypwlvttqlm]t~zkmy|ktl|kpvux^__b^]_ddighee^abiiijknokqnmjpacfdowxompsy~nqpj{ztromLL[VHGEGRPILMJKPQPPPQW\XUMUYUfXRRY^SLNITTVWYWOSNNNQHRmHiwK`dvvVXlOnl{sajg~vULWkh}lmlx_[pz{^`zscroxqhe|ir{]ULl`vukiu{{m~xk|p]^^b[_bddgeeebZccikkrsrwglihdg`akagsrlgmmr|kmhk{tmmkmOHJKHIIHQPLNOLKRRROSRWRVTPW[VVTTTa`PNMKTSSQUVNNLMOPJHQNPULKKSTSRTPVUQQNQQXXRNPUTXXX[ZURSW[WXWZOSUWWXR]YW]VTPYRWWWWX^[gr^[[Y\]_cZ_ccdfdccbZccffemnmueegcaf_]g`dlhfgkhpzhggkujhgilQIKLLMKJSQMQPOLVUTPTUXUYUQZ]VUTWUYXPOLMVTPNUSNOMLQPKJRQKQMKKORURQQSSIHLNOQRQQQTVRXW\WSSPQUUVSZQOSRWVTYVTYUTRUTTTWXW]Z^a]\ZZ\\`c[]bcdfdedaY`acabhhincad^_c]Zd\bma^fefmsdihkkedcfhPJKLOOLMSPNSQQMXWUTUWWWZUS\`VWVYUXSQPKOWSPNUPNQNKSPMOUSNRNMNQTPTQSTUNKMOQTTRRQVWTYZ[YSURTWWWY[TOTUXUUZUWYURRXVUW[YZ_]UX^\^]\]aa^[bbcgfddbX_ab^`hefda^_]]^ZZ_Z_g`^]]bhkagfhfd`bcaPKMLPQLOTOOSQOQZYXWXZZXYV\jdVXYZWVSTOJNVTPOTPPPNMQQPRXTQQOMOSVNWRTUUONMQSUUTTRTWVZ]\ZVWQRWXV[[WQTVVVVYTXXURRXVUZ]Y]_^V^]^`\\`___ZbbdhgddbYb`b^^fcc`b]\\\\YZ[X[a[^]\_b__bdebd__`\PMNNRQMRROSTQPU\ZZW[[\YZ[dqmhd^[YVUWQLMVSMNROQROLPSRUZUSPPLPWVQWSSSXMOPRTXVUUSUYX[^][[VROUVV[[WRTWVWXVTX[TSRZWV\^Z^_`Ua\aa^`b_]`]c`cghdf`Zc`a__ed_`c[Z\[\YZXYW\Y\[`^_[^^a`^b\Y`ZQNONVQPTROUTSPW\]\X^\_W\^jqwy€b\[VVXQMOVSNQQPRTRKQTTXZWUORNSXWTSURRZOPSSV[VVWTVZX]^[[^VSNTUV\\VRTVVXYSTY\TSS]XZ]^\```Vb[cb^ac_\bab_cfidf^[d`a`acd_b_YZ^[\[YXYWWZZZa\][]\\Z]`W[[ZPOOOYPUURQWRTP[]^^[`\`U\]ijr}slg\UXWPNRZSRQSRTUTKQWV[ZZSOSRVVVTOWRSZRTTTX]WXXSX\X^]YZ]TUNVWW^[XRUUYYYUWY\TSV^Y]]`]bb^Y_[eb_dd^^cca^efidf^^da`aabd`b^XZ_[\[XXXXW[Z\`\[[\[XZ[^V^Y]POORZPZTUVVTTT^^`_^b\`U]^bkytl}lZUYUQPS\TUTUTVYWLRZW]Z\ROUSXVVTPXRSWSVUU[]X[YUZ^X_^Y\YRWRYXY_ZZTUVZYZWXZ\VTZ^\^`a_dc\^]]eaafd^^dc`\gdhedb_da_a`bb_`^WX^Z\\ZYYWV]Z]^ZY[\[WY\]VXW]SOPWYQ]UVYWWUX__aa`c]`T]_beeuzhXYYSVSV\XWWVVW]XOU]Z^]]TRWSWVTSTXRSVTXXX]^X][V]_X__X]VQYTYZZaY\UVX[Z[YYZZXV]__^cbadd\b\`fadfd_`dbb[fchecfaf__aaaa`_^VU]Y[\[Y[YY][[[XXY[YZZ]_]TY]UNTZVS\TVWYVV\`abcac^_V[`da_zuohY\ZUXTW[ZY\YXY`WPV^\`a\TTXPUWVTVWRSUWZZ\_^Z_\V__Z]^Y^VSYWYZ]bZ^VW[\[\[[YZYZ__``dbcdebdZbfcgfe^ab`c^bcidcg_g^bbcaa`^_XT[ZZ[[X[XX\[Z[WWYXW\[\`]V]]SPVZVVZUXUXWX]_badad`^YYadb`lfh^\][VWXY\\\_[Y[bVTX^]ac\RVYPWVWWWVTVTX\\^``]a\Wa^[^\[^XVXX[[_`\_XY]\]^^\Z\X[`a^`dcdeefbYceehgd^ca`ec]eidei_g^cbcaa`__[XY[YZZXYXW[[Z[WXZTY]\Z`\U^bNRWYVWZX[\XWY^`baeada]^Yacb_a``^\\\WW[[]]__\Z]cXZX]`cd_RXYPWWXYYWVWV]]^`a`_b^Ya]]^Y]^YXVW[\`^]_ZZ^]^^a\[[Z\_b^bdcefefbZdffigc_c_afeZiicfice^bbca``_]]ZW[YYXXZXWZ[ZYWXVU[]]]``bbxLWW\YW\[\]ZW\]_`bdbba]`Xbcbacab][\[XW[\_]`_][`d\\XZbec`R\ZOXXZ[[ZWZY`]`bb`ac_\b]_][^^YYUX]^_`__\Z^^`bc\\W\^`bbcedfdefd\efgifcab\dg`\iibhife`baca_`_]][Y\YXWXYXW\[ZWWXOXZ]acffrkJYW]ZZ_\[^\X][^_acbaa]b[bdb`bbb\[[ZWXiq`\`_]\ac_^YYcedaS_ZRYX\]][Z[[c`bbc`bda`c^`\]^_ZXV[_^]aa_][`abeb_]T\``cddfegeffe^efhhgdd`[eg^ahhbhhfc`b`cb___]]\Z[YXXXVZV\ZZVVUMXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡…‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vuuuuuuuvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{{{{{{{{{{{{{{{zzzzzz{{|||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vutuuuutuvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{{{{{{{{{|{zzzzzzzzzzz{{||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚‚ƒ‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||xÅÔÒÒÒÒԓ{}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰‰‰Œ‹°Á¾¾¾¾½ÊÓÒÒÒÒÖº}~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}xÕçääääç™{~†“y1333332j‚€€€{­éääääèʉŒŒŒŒŒŒŽ»ÎËËÌÌËÛæååååéÇ}~}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}v~ywwwwwwxyyyyyzxooppppprrrrrrrwzyyzzz~ƒƒƒƒƒ„||||||}}}}}}|}€‚‚‚‚‚‚„„„„„„…‚|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚ƒ‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vtttttwtvwz{x{xwvx{xyyy}zyyxxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{{{{{zzzzyyyyyzzzzzzzz{||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwwy||{|{}|xwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwwwy}}}}~}xxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒ„‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z{xwww|z}|}~|xxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzzz~{||{~{xxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyy|zzzy|xxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyyyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{|||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}|||||||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}|}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrsuuttssrrrrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqsttstrppqponnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqrsrstsqsƒqoonnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrrrswssroƒ‘oopoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpqqrq‘„prp—npppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqpqrpˆ¤uo{¤oppppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqqp¯Œm‡§’pqppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsqu‹‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqrq}®¢p¦•qqqqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrrq‚²©¡±’prqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrssssssrs›ª¢³§«•rtsssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz~|~~|vvwwvuxzxxxxxxxw}§ £°Ÿœ¡{yzyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~}||||ˆ¦—›¬ £¢ˆzzyxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}}~}~ˆ ‘ž›•˜~}}}€ƒ‚€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€†¨©¡šž™˜”|€€~~€~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~€‚•°¥¦¡Ÿ¢ª¥‰~}}~~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~€€‚‡¡²ªž¦¡Ÿ ¢¨« ”‹„€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹Š‹‹‹‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚ƒ†‹š©®©£œ¤¡Ÿ¢¡ ¢¤£ž‚€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒŽ‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒ„‚ƒŒ™™šš¡›¢ œš“ˆƒ‚ƒƒ‚ƒƒƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒƒƒ‚€„‹”–™šŒ’›š–Œ††‡‡‡††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠˆ‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„ƒƒƒ…„ƒ‚„˜•ˆŽššŽ‡‡ˆˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ‘‘‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„„ƒ„„‚‚‹–“—Œƒ‚ƒ………ƒ„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘’’ŽŽ‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€‚ƒ‚‚‚‚‚‚“„‚ƒ‚€€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„„„„…„…†’“‘ŽŽŽŽ‰ˆ‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~€‚‚€„ƒ€€€€€ˆ‚ƒƒ€€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“’Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚‚ƒ„‚‚„„‚ƒ‰–ˆ„‚„‚‚€Š’€‚‚„ƒ‚‚ƒƒ‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘Œ‡…ƒƒƒ‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒ€ƒ‚……„„ƒƒƒ‚„Ž˜Šƒ…„„„‚€Ž˜ƒ‚‚‚„ƒƒ‚ƒ„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”“’’ŒŠ…„ƒƒƒ‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~Œƒ~}|}‹œ€‚ƒ‚•š†‚‚‚ƒƒ‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†””’”’Œˆ„„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~•—‰€}}}}{—Œ€ƒ€‹•’Ž€‚‚‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“’Š†ƒ„ƒ„‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€€•ŸŠ~~€}‡Š}„„ƒ„‚ƒƒ‚‰…‚‚ƒ‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†„…ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„‘¡ŠŒ…}†‰€~………„…‚}}}‚„ƒƒƒƒƒ„ƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„……………„…†…††…………………………††…†††…†††‡†…………ƒ„„„‡“““’’ŒŠˆ…†……‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…ƒŠ‘ƒ„‹…‚~}‡†ƒ€~~~~ƒ„ƒƒ„„„„„„„„„„„„………„…„†……†…†††…†……†……‡†††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„„„‚‚‰~}~…~€€„…„…†††…………†‡‡††…†……†‡‡‡ˆ‡‡‡†††‡‡‡††‡‡†††…„ƒ„………„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘”“‘‘‹‰ˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒ„„„ƒ€€€„„~~€€€€……†ˆˆˆ‡‡‡‡ˆ‡ˆ‡ˆˆˆ††‡ˆˆ‰‰‰ˆ‡†‡‡‡‰ˆ†‡‡‡‡†‡…„ƒ„…†…………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†…†„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡†…ƒƒ…„„ƒƒ€€Œ‰€‚‚€€~{z€†‡ˆŠŠ‰‰‰ˆ‰‰‰‰Š‹Šˆˆˆ‰‰Š‹ŠŠˆˆ‡ˆˆˆ‡‡ˆˆ‡ˆ†‡†„ƒƒ…‡‡‡†……„„ƒ……„……†„„„………†…†…ƒ‰”“ŽŠ†„†…ƒ‚‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡†„„…„ƒƒ‚€€€„„‚‚‚‚‚‚‚€~}}}}~~|{|ƒ‡‰‹‹ŠŠŠˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰‡†††‡…†ˆˆ‰ˆ††‡„ƒ‚„ˆˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚ƒ‚„ƒ„ƒŽ“’‹ˆ…„†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„……‚€ƒ„‚ƒ‚‚‚ƒ~}}~~~~~~}~}}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡‡‰†‡†ˆ‡†‰‰ƒƒ„ƒ…„„……†ˆˆ†…ƒ‚‚ƒ…‡†‡††„‚‚ƒ„‚ƒ„„‚‚ƒƒ„ƒƒ‘’ŽŽ‹‡„††„‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…‡ˆ‹Š†„†„‚††‚‚„„ƒƒƒƒ‚‚}|}€~~~}|}}|y|ƒ†††„ƒƒƒ„………ƒƒ…„„„„„„…„‚‚‚‚„„‚ƒƒ…†…„‚‚‚ƒƒ…„„„…„„†„ƒ„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰†„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„„……‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€€ƒƒƒƒƒ‚‚}}€€}~~}}}}{zz~„„„‚€€‚‚~‚ƒ‚‚‚‚ƒƒ€€€‚ƒ‚€€€€€ƒ‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†‹“‘‹ˆ……ƒƒ„‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€ƒ‚~~~~}‚ƒƒ‚ƒ‚ƒ‚}}~€€€~}}}}~}|zzz€‚‚~€~}€~€€€€€€~}}€~€€€€€€€€‚€€‚‚€‚„ƒ†’ŽŠ‡‡†ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒ‚ƒ„…€€|}}~}}~€€}~}~ƒƒƒ‚‚}}~€€€~}}}|{{{zzzz€€~~}~~€~€€~}~~}|~€~~€€€€€~€~€…’’Ž‹‹‡‰…„ƒ‚‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~}~€€~€„ƒ‚€~}~~€€€~}}}|{{|zzyyy{€€€~~~€€~€€‚€|~~~~}|€~€~€€~~~~~~~}}}}…“’ŽŒ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒ‚‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚‚‚€ƒƒƒ€€~}}~~~~}}}}}|||{zyyyx}€€€€€€‚‚€~€~~~~~€€€€€~€~~€}~~}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚ƒƒ…ƒƒƒƒ…„„„„„ƒƒƒ„‚‚‚‚‚~}}}~~€}}}}}}}}}{zyyyyy€‚‚‚„ƒ€‚ƒ€‚€‚ƒ‚ƒƒ‚€€€ƒ„‚€€€€€€‚‚€€€€€€~~||Š“‰‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…ƒ„…„…†…†††…†…ƒƒƒ‚‚€}}}}}}~~}}}}}}}}}|{yyyyx|‚ƒ„…‚„ƒ‚‚ƒ…‡‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚‚ƒ„ƒ‚ƒ‚‚‚‚€€€~Ž“Œ‡ˆ†ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€€~}}}~~~€ƒ„‡ˆ„†††…††‡‡†‡‡ˆ‡‡‡†}€‚~}}}}}}}}}}}}||~~~|{yxwxyy€ƒƒƒ„ƒ„„„——ƒƒ„}~‚‚‚‚ƒ†ˆŒ…ƒ‚‚„‚ƒƒ‚ƒ…„„…ƒ‚ƒƒ‚ƒƒ‚‚‚‚ƒ‚‚‚’‹ˆˆ‡‰‡††„†……„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€~}~~€‚………‡†‡‡†‡‡ˆ††‡‡‡†‡…~}}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yxy|~‰–„ƒƒ„„”“€~~…‹€€€„†‰…„‚‚……‹ƒ‚……††„ƒ……ƒ„„ƒƒ„ƒ…„„ˆ’Œ‰ˆˆ‰‡‡‡…†…„…„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„ƒ…„~}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|xyz{|€‚ƒ‚ƒ‚€~}~~{ˆ‘||Ž–}‚†Š…ƒƒ„ƒƒ‰~ƒ„……ƒ…†…„……ƒ„……†„„Ž‘ŒŠŠŒ‰ˆ‰‡………ƒƒƒ‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚€‚€~}}||}}|||}||}|}}}|||{‹‘—Œz{|zzz{|yy}}~€€|{{~~}‚•‘„ˆ}|~‚„||‚„‚€‡ƒ}‚‚‚€ƒƒ„„„„„‚„ƒ„…„‘‘Ž‹ŒŒŽŠ‰‰………ƒƒƒ‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚ƒ…ƒƒ…………ƒƒƒ„‚‚ƒ‚ƒ‚‚€€~~}~}||||||||||||||}|||~~Š‚{z{zxz{{|}{~}~}}}}}|}†~}‚~~€‚||€‚€‚€~|{Š‚}€~€€‚‚€€€€‹”Œ‹ŽŽŒˆˆ‡……„„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ…„†‡„„€†”ˆ€‚€~~~€|||||||||||||}|||||||y{{{xxy{{z|‚€~|~~~}€‚‚€€€‚‘€€~€~~~€}}}{}}}|}||}€€€~€~~‚”’ŽŠ…††…„„…ƒ‚ƒ‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚‚„†‡††~ˆ•Š~€€~€~~~|{{|||||||||~}|{}|||{|||zzy{|z}…ƒƒ~~€~…‚~€~~€…†‚€~~ƒ†~}~€€€~}}}}~{|}€}~Œ‘ŒŽ‡„††…„„ƒƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}€‚ƒ††……~€€€~~}€€€}}||}~}||}}}}}|~|}|{}||z{z|}|†„ƒ€€}~}~~‹„†~}||~‚}}}}|{}|~„ƒ€~~~~}|~}~~~„’Œ‹Š†„†„„ƒƒƒƒ‚ƒ‚ƒ‚ƒ‚€€}|||}~{{}w~vx~}|}|}~~‚ƒ€z}}|~~€~~~€€€€~~~~~~}~~}|~|~}~|{|||{{z}~€„ƒ‚~|||}||ƒ~Œ~|{{}~}~~}{{{}|{{{{€†„‚„ƒ€~‚‚‚‚‚€‹ŒŒŒ‹Šˆ„„„ƒƒƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€€€}€~~~~|‚}~}}}{{}}|z||~€‚€€€}|}|||||}|~{~{{{|||}|{{{{||zz}z~‚~‚„„‚‚…†……††‡…„‘ŒŠŠ‹‡‡…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~€€‚€~~€€~}ƒ||}}|}}}}{|~~~~~|}}|||{~~{|{||||}|}|~|}|{{{|y{|{{}z}~~€€ƒ‡‰‰‰Š‰Š‰…ˆ’Ž‹ˆ‰‡……ƒ‚‚ƒ„„ƒ‚‚‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€€~~~}€€€€ƒ‚€€€€€€€€~|z|}}~}}~~Œ†}}~{{ƒƒ}~~}}|}}}}}}|}|}|}}~|~}}}}|{{z|{||{z{{zzz{~~ƒ…ˆ‡ˆŠ‹‹Š‰Œ‘Šˆ†…„‚‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„„€€€€‚~}~€~{~’Œ|}Š€Œ~~}}}~~}~}}}|~}|}|}}}~}}~~|{{{||}|{z{{yzyyy{~„ƒ„‡‰Š‡‰Ž‹‰‰…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{}||~~}}‚€€€‚…ƒ„‚‚‚‚€€ƒ‚€}~€~|‰‚~ƒ‘„„ƒ~}|‡}}~}}|~|}}|}}~~}~}}}{|}~||{|}zzyyyy{{~~€ƒ‡„ˆŽ‹Š†…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{}}}}}zx‚€‚‚€€€€‚‚‚‚†…„‚ƒ€‚„~€}~~}~€€}~„€~~}~}}Š…}~}~~}}}|~~~}€}}}|}||{|}{{{zzz{{|}~}€ƒ€‰Ž‹Œ‡„……„ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv}€ƒ‚‚‚‚‚ƒƒƒ‚…†„ƒ€€€ƒ€„~~€}~€~}~~€€~€€}€~€~|}}|~~~~€}‚€|}€€}{}}}|||||{{{|{|||}|Š‹‰ˆ…†……„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€‚€€€€ƒ~~€}€}}~~€€‚€€€€}€€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{|~|}|||{|{|}‰‡†„…‡…„…„‚‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz~}yxtt€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚€~~~~€}~€}}}~€€€€€‚~~€€€€€~}}}~|~~}}„€~}}}~}~~}~|{|z|{z€‡ƒ„„…„„„…ƒ‚‚€€‚‚ƒ‚‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xyuu}‚ƒ‚ƒƒƒƒ…„…ƒƒƒ„„ƒƒ„ƒ€€€~}}~€~~~~€}}|}}~€€€€‚€€€ƒ‚€€~€~€€€~~~~}}~~……€€ƒ~€~€~}{z{z|{z‚…€ƒ‚‚‚‚‚ƒ€€‚€€‚‚ƒ‚ƒ„ƒ„‚„‚‚‚‚~€~}~~~~}~}}z{|…„{{syz|pwuvwyutz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€€}}}~€}~~}~|}}~€€€€€ƒ‚€~€€€€€€€‚‚‚€ƒ‚ƒ‚€€|z|z|{|‚€‚€‚‚€~‚‚ƒƒƒ‚„‚„‚‚€~€€}~~}}}~}}{{z€x|vyy{qtxwvxury……‚„„‚„……†„„‚„ƒƒ€€~€€|}}~€}~~}|~~~~€€ƒƒƒ€€‚€€€€€€€€‚ƒ€„€}ƒ„€€‚}z{{|||~€|}}€€~}}~‚‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxyzruyyvwwsu†…ƒ…„‚„„…„„„ƒ‚ƒ€~€~€}}}~€~€~~}|€|~€~€‚ƒ€€ƒ„‚€€€€€ƒ‚€ƒ€~‚ƒ„€€‚‚‚„‚~{{||||}}~}z~}}x~|||~~~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„‚„„…ƒƒƒƒƒ€}~}}}€~~~}}€€~|~~~‚‚ƒ‡…~~€€€€€€€‚‚€€~€‚‚ƒƒ‚ƒƒ…‚}}}|{||yz{z~y{yx~{|{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst†„„†ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€}€€~€}~}~€€€|€€~}~~€}€€ƒƒƒ~}~~€€€€‚€~~€‚€ƒ‚„„†„€~}||||zyvyyzyvyv~|{{{~}{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…„ƒƒƒƒƒ‚‚ƒ‚ƒ‚~~€}}}|~€€€|€€€€|€~~~}~~‚‚~~}~~~~€}€€€~~~~~€‚‚‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{{{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvpxyrx…………ƒ„„ƒ‚„‚‚€‚€~~~~€~}~|~€€€€€€{€~€€€€}~~}}}~€‚~~~~}}~~~|~€~~~‚~~€€~ƒ‚ƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}|{|z{}zzx{|zz{xtxuqrtpxxqy„………ƒ„ƒ‚ƒƒ‚‚‚€€€€}~~€}|~|€€€€€|€€~€~~~}}|€€€€~~~~}|~~|}€~}~€‚~€€~‚„‚‚ƒ……‚‚~}|{{||yw|ywxwwx{{{{|…Š}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzz{zxswuqqsoxwq{…†……ƒ…‚ƒƒ‚‚€€€€~~}|~}€‚€€}~€~€€~€}}|}€€€€~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{||{zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚€€}}~€‚}~~~€€‚€€~|~|€€€€€~}~~€€‚€€€€€€€„‚‚€~|}~~z}…~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚€‚€€€€€€~}€€‚‚‚€~€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€€‚€€~}~{“z|}|{}y{zzxyxy{||}|||||||}}}||}|~}~~~}|z||{|}{yzzzyytuuooqpwst}…†ƒƒ‚ƒ‚€€‚ƒ‚€‚‚€€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€€‚‚€€€}~~|†‰||~{{~yz{z{Ž~wwy{|{}||||{}|}}}}|}|~~~~|z|}{|}{yz{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€€‚‚‚€€€€€€}~€}€ƒ‚{~~{|}{z|||‡yxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€‚€‚‚‚‚ƒƒ‚€‚€€‚‚‚ƒ‚„„€~‚€€€€‚~€€‚€€€€€€€€€~}€~€€€€€€€€€€€€€€€€~}~}~~{}|}{||wxuxxy{||}|||||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒ„ƒƒ‚‚‚ƒ€€‚„ƒƒ„ƒ‚ƒ‚€€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€€‚€€€€€€€€€€€€€€€€€€€€€€‚ƒ‚‚€‚‚€€€‡~~|{}|{}xwvyyz|}||}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚ƒ„„€€ƒ†ƒƒƒ‚„€„ƒ‚‚€€‚‚„‚ƒ‚€€ƒ‚€€€€ƒ€€ƒ‚~‚€€~€€€€€€€‚‚‚ƒ‚‚ƒƒƒ‚€€€„}}}|}z}{yvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysruowqwysw{…‚‚‚‚ƒ„‚ƒ„ƒ€€ƒƒ†ƒƒƒ‚‚„„ƒƒ€€‚„‚‚‚~€€€‚‚‚‚€€€€‚‚„€~ƒ€ƒ‚€€‚ƒ‚€‚ƒ‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ‚€‚€}€|z|{{w|yyy{z}~}||||}~~€€€€„„€}€~{{{z{ztpxrytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚ƒ„†„‚ƒƒ‚„‚„ƒƒ€ƒ‚‚‚‚‚€‚€€€‚‚‚‚‚€ƒ‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚‚„ƒƒ„‚„‚ƒ‚‚‚‚ƒƒ„ƒ„„„„„…ƒ„‚ƒ‚‚ƒ€€~||€}|x|yzyz|}|{||}}}||€€€€€‚~€€€€{{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚ƒ†……ƒƒ‚ƒ„‚„…‚‚‚ƒƒ‚‚‚€€~€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€ƒ€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒƒƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{~~}y|zzz}||}z||}}|z{~~~€€€€€€€‚€€}}|}}|vrvxxvtvu}‡‡ƒ‚„…ƒƒ„…„€‚……„„ƒ‚ƒ„„„…ƒ‚‚‚ƒƒƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚‚‚ƒ„‚‚€€‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚~ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz|}€}||z|~}|}}~~€€€€~~€€€€~|}}~~}||xvvw„‡ƒ‚ƒ†ƒƒ„†„‚…†…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„ƒ‚‚ƒƒ‚ƒƒ‚‚„„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒƒ„„„„„…„ƒƒ„…„…„ƒ‚€}‚€}||{||€}}~€~~}~|||}}~~~€}}~€~~}}}~}}~~€|}€‚‚ƒƒ†ƒ„ƒ†„‚ˆ‡…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒƒ‚‚ƒƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒ‚‚ƒƒƒ„ƒƒƒ„ƒƒ„„…„„„…………„ƒƒƒ}„€}}||||~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒƒ…ƒ„ƒ…~‚Š‹……„ƒ‚ƒ…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ…ƒƒ„…„……‡‡†‡…„„…„ƒ~~|~~}€~||~|z|}}}}}~~~€}}|€€~~~~~‚€……„ƒ„„‚„ƒ†€‚……Š‰„„„„……‚‡††„„„„…„„„„ƒ„ƒ‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ„€}uyƒ~„„‚ƒƒ‚ƒ„ƒƒ„…ƒ„…†„…†}„y|~ƒ{…ƒ„ƒ€}~}~ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚ƒƒ‚‚†„„„…„ƒ„…ƒ„…„Šˆ………ƒ……„†††ƒ„„………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†spurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚……‚hzrss|€rƒƒƒ}}~~}~‚ƒ‚|}€}}||||}|||~}~}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ…ƒ†ˆ††…ƒ†††‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vyy†r„ƒpvxqvtturstvi€nrotvnulwmzsn€‡ym}rsvsvmnwlpylu}|~€}€}€€}}|||}|}~}€€€~|~€‚€€€€€€€‚ƒ‚‚„…‡††€‚…ƒƒ…‡†ƒ………†‡‡„ƒ††ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoomw}x†pqzprtfu~n{ysoy€}~€{~|€~€€~~€€€~~~€~}€}€€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„†……††ˆ„„†‡ˆˆ†‡„††‹Š…„†‡‡…ƒ………„‚…………†……†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„rioyxpkyszozwvvp€~~~z~}|}~}€ƒƒ€‚ƒ„‚€}~~~€~~‚€€‚„‡†ƒƒ†„„„†‡†…………††ˆ……†…‡‡…†„††‰ˆ…„‰‹ˆ†„†………ƒ……„†††††…ƒx‹yrˆz{pp…„x…xyks~y{krƒ‡ƒz|mzyyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozks|nv‚~~}}z}{|}}~}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ„†„…………†‡……………‡‡ˆ†„†…‡††…„……„……†‰Š‡…„†…††…††„†††††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„…†…†„†„ƒ„„†„„ƒƒ„„…„…„…„†ƒ…†……„„…‡†„„…†……}w†ƒ„„ƒ‚}~{|{~{||}~}|~€}€~~~€~~~~}}}~|{|~||‰†…„†††…††…………††‡ˆ†„†…‡………ƒ„…†…„††††…„†„…††††„‡†‡‡†…‡ˆˆˆˆ†„‡…††ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…ƒ‚……†……ƒ…„„„…„†…„……ƒ††…†…„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ}€{{|~{||}~||~}€~}€~~€}}|€}~~~~~||}~{|||{{~ˆ‡„„ˆ††…‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡…††……†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ……ˆ…†‡†‡†‡†‡…‡‡†‡……†‡…‡†…‚ƒ…††„„ƒ„„ƒ„†„†…………ƒ††…†…„††…„„……ƒ„‡…ƒ‚ƒ„ƒ„‚~€|{}~{|{~~}||~}~~}~}}~~|}||~~|}€|||}|||~z{{|~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†„…„‡†„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…‡‡…‡†‡†‡…ˆˆ‡‡…††‡…††„„„…†……„„„ƒ„…„†††…†„†…††……††…„ƒ„„ƒƒ‡ƒ„‚„„ƒ‚€€€{{~}|||~}|||}}|}|~}|}}||||}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††ƒ…†…†††…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡…†††‡‡‡…‡†ˆˆ‡‡…‡‡‡…†‡„‚„ƒ„†…‡…„„„„„…†††††…‡……‡…†…†…„ƒ„ƒƒ„‡ƒ€‚ƒƒ‚‚‚€{}}|||~}|}}|~{||{||}}{{{}|{~}{|}}|}}~}|zz{{||ˆ‡‚††††‡††…ƒ…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡ˆˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡…‡‡††‡‡…‡†ˆˆ‡†…‡‡ˆ††‡ƒƒ„„ƒ††‡……„„„…†††††…†‡††ˆ††„†…ƒƒƒƒ‚ƒ†ƒ~‚‚ƒ€ƒ‚|~||}}|}}|}{{{z{|||{{{~{{}{z{~||||}~}{z|z||‰‡ƒ†…†…††…„„……………„ƒ„†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…‰Š‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……ˆƒ„†…ƒ††‡†…„ƒ……†††††…††‡†‡‡…ƒ……ƒ‚‚„…‚ƒ~‚ƒ~~~||}}{}}|}zz{y{|}{{{{~||||z{}||||~}|{{{{|{‰‡„†„†„††…„…†…„„ƒ„‚€ƒ†ƒ‚z„Œ{€„…‡†††…„‡ˆ‡†‡……‡Š‡„‡…††ˆ†…‡„†‡ˆ††ˆ‡‡‡†‡ˆ†„†††‡……‡ƒ„…„‡††‡…„„ƒ……††‡††…†††…††„ƒ„…‚‚€„ƒƒ‚}~ƒ~€||}}~}{}}|}yzzy{}}zz{{}|}||zz}||}|~~€{{{|~}|ˆ‡…†…‡„†„……………ƒƒƒ€‚…‚€}|{„…††„…„ƒ‡‡†††…„†‰†‚†„†††……‡…‡ˆ‰†…ˆ‡‰‡††‡…„†……‡…„‡ƒ„…„ˆ††‡……„‚……†…††‡„††††…†‚ƒƒ…€€€€ƒƒ€|€~~‚€}€||}~}~{~}||yzzyz}}yzz{|{|{{z{}}|}|~~|{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€ƒ~~~€yz}€ƒƒ…‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ†…ˆ‡‰‡†………ƒ†„…‡ƒ„†„„…„‡†…†…†„‚……†††††„…††………‚‚ƒ„~€€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|{{{{|}}}|€~}|||~|{‡……††††„…„…ƒ…‚€€€€~‚‚}}{‚ƒƒ…†…„ƒ‚†ƒƒ„‚€…‡…‚ƒƒ„„„††‡‡‡……ˆ†‰‡…„„„‚…ƒ„†‚ƒ…„„†„‡†………†ƒ„…„…†…†„„…„…ƒ…„€€‚ƒ~€ƒ|€}}‚}€~~~~~}}{|{zyzzyz{|yzz{{{|z{{{|}}}}€}}||}€}|†ƒ††††…ƒ„ƒ†‚…€€€~‚|~~€€‚‚‚„„ƒ‚‚„€ƒ‚€„…„‚€‚ƒƒ„……‡††„…‡…‡…†‚ƒ‚‚ƒ‚‚…ƒ…„…†„††‡††…‚„„ƒ„………ƒ„ƒƒ„‚„„€‚‚}~~~„~{||€}€}~ƒ}~~}}~{~{{zy{zyzz{yzzz{{|z||||~~}|}||}€~€†„……„‡„„ƒ‚†‚ƒ€€~~€}‚|}~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡†……ƒƒƒƒ„……„ƒƒ‚„ƒƒ€€~}}~~|~ƒ~|~||€~‚~‚|~}}|||{{zzzzy{yzzyzzz{|y{}{{~€}~}}}€€€†„„…„…‚„‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„…ƒ‚ƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚€…ƒ~€~|}~}|~ƒ}{~|}€ƒ}}€~}|||}{{zyzyy{yzzyzz{{{z{}||‚€~€€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌËËËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFK=8765999<>9?<C:;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937677=;>:=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<:<<98:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA>;A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÕÕÕÕÕÕÕÔÔÔÔÕÕÔÒÓÔÔÔÔÔÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9>CE?<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËÊÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø×××××ÕÕÕÕÕÕÕÕÕÕÕÕÕÕØÛÜÝÜÜÜÜÝÜÛÛÛÜÚÓÒÓÓÓÓÓÔÔÔÔÔÔÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILN@99:4;A<7=9AC>@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÏÐÏÏÏÏÏÏÏÏÏÏÏÏÖÞÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¸ºÑÔÔÔÔÔÔÔÔÔÔÔÔØ®|‚‚‚‚‚‚€ÒÒÒÒÒÒÒÓÓÓÒÓÓÓÜãâââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVM<::77>C>8>:??A=?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÌÐÒÒÒÒÒÒÒÒÒÒÒÒÑÞìëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§£££££££££££¢§ÏÓÒÒÒÒÒÒÒÒÒÒÒّ;DDDDDDCCCDC?\ÓÓÒÒÒÒÒÒÒÒÒÒÒÑàìëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;?C>6:7>?;=B?9<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÌÌÑÒÒÒÒÒÒÒÒÒÒÒÒÑÝêééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤£¨ÏÓÒÒÒÒÒÒÒÒÒÒÒٔ@HIIIIIIHHHHC`ÒÓÒÒÒÒÒÒÒÒÒÒÒÑßëêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;?@@8:;8<;;<?:;;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÍÐÒÒÒÒÒÒÒÒÑÑÑÑÐÜèççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©©¬ÏÓÒÒÒÒÒÒÒÒÒÒÓٙMTTTTTTTTTTUQjÒÓÒÒÒÒÒÒÒÒÒÒÒÒßéééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB>;=:9;:==;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÎÎÎÎÎÎÎÎÍÍÍÍÍÍÎÏÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÎÎÎÎÎÏÎÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÒÔÕÕÕÕÕÕÕÕÔÔÔÔÕÐËËÊÊÊÊÊËËÊËÌÌÌÓÔÔÕÕÕÕÕÕÖÕÖÖÖØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<7@A<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÎÓÔÐÎÎÒÔÏÏÒÔÕÔÐÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕ×××××××××××ØØ×ÖÖÖÖÖ×××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?89:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÎЦ’ÅÑÓ¹ŸÐќ‚„ŠÆÏÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<>B>BC@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÎÒª¬”ͳ—šºº•¸¹¯¡ÒÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?><7:>9?D>@98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÐɗ™…¥¯ ¢§²Ñ’}~¯°ÑÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<<:6?B@B9647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÏѤ°½—¡Ç†šµÕÓ͞žÃÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8E@?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÏÏÐÕ¹˜¤Ú¤™µÔÓÀ  ÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<>=964:99::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÏÏÐњ·Ø¢™µÔÔ¯¢©ÔÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ×××××××××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:<?>=<9@<<::9?@>=<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÐÐÕ§¤ ÒÖ¢™µÔÔ£¡ºÔÑÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJACFDAB8;?<=;<<8558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÐÒÀ¢ÉÔÕ¢š¶ÔΟÉÒÑÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF@HIGE@<<>><=><756:969;::;8@?:<<9<>=;;:?9?:;9=>=><;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦ÓÔ¤ ·ÐÖ£™¶×ß ÒÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;557<:7:;::;9==:::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡ÈƦ½•‘¦Ú¢š´Ù±¤§ÖÒÒÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKL@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ Ôʎ“—¦Ú±ƒÆÖ¹ƒ¿ÕÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<=?GFGKH=657:979:;:<=9>99:8;=>>A>=9<<:=>>:=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÔ¯°³ÑÓÑÃÔÒÒÂÓÒÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=>AELLA=775;8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÔÖÖÖÓÒÒÕÓÓÓÕÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEJ=>786967899;;=?@<<89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9599:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EIKAALD??;9889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEHIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDI;AA;<886486987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGJB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<BA<;877797799=?A?<:9@?<>B?:8776=?@@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98868975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE>;HF89757875898;>>=;89A>=@?A>7596;>AB??@@AB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCEEC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELBA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<<DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH@E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGHNOEHFMII@<D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAC?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€iixsg~‰‰xp‚†{w}~…Š½ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€‚wt|„‚}sp€Šx‚yƒÈÞÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsnupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿¼½¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»º¹¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjcmgb\XQPQKTJB:IQ?A7<94:565455688686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸¸·······¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µ¶¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸¸·¸¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶·····¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨¨¨¨§¨©©©§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸········¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¥¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥£¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§§¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©ª««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¥££¢¢¢¢¡ ŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž£¤¡žžŸ  žœžœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=6789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥¤£¢¡¡¡¢£¥§¦¦§¬¬¨¦ œ›¡¡ž›ššœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¦¦¦§§¦Ÿ›š›¢ š––•š›š——˜™šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜—™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥£¢¥¦¦¥¦§¦¦ ›™›¡Ÿ–““’—šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB@DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥¦§¦¦¢žœŸ ž›“‘”—›˜–—–˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;<;=<::<=<7;>CBDC?=AC@DA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¥¦¥¥¦§¦¤¥¦¦¥¥£  ¡ž©µ“–š™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šžŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡¡¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?B@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢¢¢£¤¤¥¦¤¤¤£¢¡ ­£–“”˜›š›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œ ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸžŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::78:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸ   ¡¢££ª©£¤¢¡¡£Š›™™˜™™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢ ›ž ¡£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œž››œŸžœœœœŸ   ¡¡¡  ¡  ¢¢¬¯¡¡ žœš§s‚žœš™š›™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥¤¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¡¢¢¡¡ ¡¡§¢¤Ÿžœ™š a|Ÿ››š›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›šœšš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>99;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤¤¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ žžŸ      Ÿ§–¥Ÿ›šž“Yy ›››Ÿžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›šš››š˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9<<>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœœœžž¤Ž›žœšš¤†Xt¡›œœžžœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:=>:?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››››œšš™¤š››œ¤y_o¢œœžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›œ›šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™˜˜™š£Ž•™› xiiœžœœœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›š™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š›››œœœ˜˜™™˜¥Š–›œxje”Ÿžžžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ››››››œ™™™˜–¥„‰’”wjd žžŸŸžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ››››››š˜˜˜–ŸŒ€‚Šžž‰thb‹ŸžžŸ Ÿžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_^]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜˜——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜˜˜—žŠyzyœœ„lb^ œ››ž¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±³­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=:F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œš››œ›˜™š˜˜™›šš–‹™“„ww˜ž‡ma]Š—’‘’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨©¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‘‹‘‹Œ‘Ž™›‰rœœ„{tdƒ…‡‹†ŠŠ‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VQQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹Œ†Š‹‹‰‡„†‚€’ˆxZ‡“–ln{s‡}€’†„„…ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹Ž‹‰‰…‚}r˜”tdOu‹Œ`\qsƒ{}|†Ž‹†”’‹—”—’˜¡–ž—•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¥›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ‚†‹‡ˆ…„ˆˆ‰„‚~} ‡_KItƒ|ZJakz„„…ŠŒ‘™””” ššŸ¢­±­©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPEMISWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‘Œˆ‹‹‡’‰žxIBEtxmU>Lds‹‹‰‰Ž””˜•œšž¨®²¯°µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWMO_^\NUUbQDTM;?9<895775795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš™‘ž¡“—›¡šœ¢Ÿ ”aS[JtrcWFESl‘Ž‹˜šŒ”š—œ› ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUKTOOJDPK_bXZQ\T`MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ªª©§¢¥¨©«ª©¯¤„V‚Tt|l\YmU_w–ŸŸ¡¤ž›š¤§¤©«®¬¥¤¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdWOXKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®««¬¤¡¢¥©§§©£tjÀ½P“‡o_{kVn›¡¡¨§ ¢¢®««ª§­®¨¥¤©©ª©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_UZNRNPOSe\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢šœ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨§¦¨©§©©¤¨¦š¤¦¢¡¡›e‡Æ½e©¡“—^qƒ]`—œ™¢¢  Ÿ ¡¨ œž¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]\PUOXO^ddlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤ ¢¡¢§¡¦®¦¦œŸ™_µ¾›Ê¤“©uh¯rW››Ÿž Ÿžž £—š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvxb_[UYQUW[c^s_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?B?:8:>?C@DA:;>=@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯««¬¨¨«¯©¨ª¨¢ ¡§©­±²¯«££¤m‚••¨Æ’¡„F¬X†¡Ÿž¥¤¥ ¤³¥•ž›ŸŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸ ¡¦¢›—’šš •|wo}yf[[`_Z\V\hdocmjib^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¢ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£ £ªª§¸Á¾¹¶·³®¬­¯„}{l­» œš€Wƒgƒ¨¡—ž¥¢™–°¾ ¡š–ž¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¡™˜¥ ¤§ª©¨ª­¬¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxjb[_^\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>BE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢ «²·ÏÞÞØÍɼ·¹º¯‰xdj§£š–Š{hkrvz‡‹……„vo¸©£«¦¥˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨¨«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥¡¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxxxc[RYT__amhvlphiibZSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶´º±ª®´±°²´µ¶»Ã×àØÎƽº¶®šxjPc”„ƒ„zrmhhnkllkf_Zw²´ªµµ®³ §ª¬§ª©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš’–””˜“š˜Š‹‡€€|‚xa^YTai`fsotitdidb[LK>:9898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÄÇÃù½¿ÄÔϹ®©¤ž”€d_J\|npwoihb]_^a`^ZTn·²ª´¼°µ¶¨¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`b_^kcbnxuvnm[bRV\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAA;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–••‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±°§¼¼¾ÅÄÆÉÇÅÆ»ÅÁÅÉÌÆ¡‘Žˆ|hWXISkefnhbe`Y[XZZYUl³¹¢¦±¶«µ²­³­¨®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|~„ifhaklgnvqruqg^_\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÄ¿ÃÃÆÆÀ¯”tmdZVWENgbajd`gfYZYXXTf³¼²¦ª©¨ª­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|~tklndomiqxnyiia\gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÄÄĹ´Çº€YSSWU@Ofdaid`fi[XWXSb©¸³µ¬®¥¤£¨¤ Ÿ¥™ª´±¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyy{wnkihuZfrxsyff]d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÊÆÄÃÄÂIJyQKNO=Qcbemf_dh^YWWdª»ª¸µ³¬©£¡­©¬¦­Ÿ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuuefijh]jonyxcb``^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÎÏÌÃÇÆÈÉÈÈÉÇÅÉÇÈǽ‚OMM@Mg^gkj`ba^\Yd¥Á»º¼º¼¬­¦ª»º¹·À²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqocagvhiitmyl]d[U`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÌÐÍÇÌÉÂÂÇÂËËÈÇÌÉÎÅÈ¿|SNEGo`aalb\]^[]›ÇÂÄÇÁ¼¾´±°°Á¾¾ÁÆ¿¾¸¶Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`kjwlieuntb]bTWUSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<9>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÄÇÈÆÒÉÁÃÿ¿¾ÄËÈÊËɼ¼ÈÇÉÍÈÃÈÉÉÅÅîTMHjc\_n]TZY[’È·¿¿ÀÀº»½µ³³¿¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrpfegcjdbjmno^Y]VVNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾƹ»Ãº¸¹¼¾ÁÇÁÆ»¹ÈÈÃÅÄÀÃÁÁÀÄÁû†TIY^myPPSV†Èï½½¸¹»»¾·´°¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfadbacdcjcgc[ZZ\YQOE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶·´´µ¿»½¿¹¾ºº´À¸µ·²®º»·À·¼ÊÏÁ»¿À¼»Ä½ºÀÄÁº‹WGN•’EKZ~¸Ë¾°Á¿º·»¾ºµ·´¸¼´½¸µ´°³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|yˆ}qdabchjggjfi]VVTYOSLF8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“““˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´´±°µ·µ»Á¸¾¹¿¼¼·´·¯®·µ¹¿»Á֎»¾»Ã¶¹Ç·µ·º¼º¹–nJx‘@Z¶¼Á¾¹Æ¼Â¿¼Å¸¶·´¸¶¶»»¹¶´·ºµ´¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒyqmeefoielhXXNKKKRJLHD9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’™”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿¾¼²­¯¬±°·¼·»½ÁĹ··¶µ¹¹º»¿¼ÐÅx¬Ë½Ç¸¹¸­¶³¶¹³¶´´†|›‰V ¿À¾½¼¿ÈÃÅžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~‡|knpgpksfbm`\TIKJDJCCG>:;8><7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘Ž˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼»À·ª­¤®°¸»²½¾»Ä¶µ¸µ·¿¾Ä¼ÂÄ×­u‚½ÈÏÂÀ¸®µ´º½·¸±¿¿›•—Íÿ¾½¼ÇÌÇÇÄǽµµ¶Á½»»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†€qflintnxcgb\cQKTHEECGB<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?>??FD@A?>:7?@CC?@=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼ªª£°¹½¼²¼¾¼Å¸±¸¹¼ÆÉÊÂÇÉјqu°ÑÑÌÊĵº¿ÃȾ¾´¿Ã¯|iµÌžÁ¼¿ÃÌÊÇÅÆÀ¹¾¼Ä¿¿¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtolltkln_c^`aNIM?E@?DC;;::;:8;<:9<>::>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´»Åк¾¼Ä¾·¼À¿ÉÏÇÈÊÊÁ…st¨ÌÌËÍÊÆÂÃËÎÁ¼¸¼º¹uX¶ÈÆÄÀÀ¿ÄÀÊÊÃÃÃùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{z‡zmmx|`qc[^__TI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA??ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸´¼·»º­Û¾¶¾À¾¾º¦œª³·ÄÀ¥ywzžÄÆËÈÁÃÀÀÉÊÁ¿»º°¶vVµÆÅÅÄ¿ÀÁ¿ËÇÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}‚znsxshp][^]YRFDCMIAD=H;;59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘—žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯··²µ³·¹¼»¶»»Å´m¯Î½¶¹À¼ª}nhnmt‚—˜sy~š¾¿ÇÀ¹À¼¾ÅĽ½¸²¯®nT©ÅÆÃü½¿¿Ãþ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸··½¹»±¶²ÈÀ»¶´±°·¬³©°­­´·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|wlu{pni[__YSPAFHGK@ECH<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿš›œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹ÀÍ°u‚´½µµÁ¤†iZ^`NS[\ptx„£¸·Âº³»·»½¿º»»­¯¬lWœÅÃÃþ¼¿»»¸µÁµ¿ºµ®¯­°½À¹ÏÊÉñ°µ´´½º¾ºº»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰|‚zsvvwnq`_f][TJ=??GF=GCC9:5;99><<::<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹ÂÉ¥„xŒ¢°µœjfgUY_IIMQTny‰¨°·¾¹²µ²¼¹¼¶¹¾±´¨o_ŠÁÃÇÃÀ½¿¹³¯²½º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtwrl_cb\^OIB?=IDFMC@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·¿Æ§‡{v¢—`SCYUHbjUOEJe£®¯¶ºµ´²¬¼¹¸µ¸Áººœlz¼ÂÇ¿¹ºµ®¥¬³±¦°­¨ž  ¥­¶µÂ·¶´¥¨«¨°¶³²º¶»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´·¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wp|ovrnc]gX]]SOMA>JBAJI@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³²­¶º¯­¼³¸¸¿³yˆnNJ@eYBPx€“hLC^ƒ±µ³µ²´¯¬»º¸¶¹¿Ä³Ÿ–‚z¨¼»¸µ²±­­Ÿ¤¦§¤¥–™™šŸ©®¹¬««Ÿ¥¨¤«®¯§°¬¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmuil][jT]\PNHDFLBFNF8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹º¶¹»µµ³¸µ•Œˆ„{XFBQˆXIJYxŽ‚bAU¤¹³´²°±­°¹¸¶»·º¿­±²ªŸ ¹®©«­«£¨¡ž—˜¡•’–—˜Ÿ¨®¤£¤ ¢§¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬ª¯£¤£¡© ›“Ž”’’™–š¤¥ Ÿž§˜•’”™ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wryiutndUacW\QNLH@HQDMC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯²»©˜™”hM@TyqOIIKhZEV±»±¬³¯®¬­¶¶²´µ®©¢ž››ž§§ž ¨©Ÿ¡§–›——”–Ž—›¤¨  ¢¢¡¥¥££ ž¥ ¤¬¥¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›©¨««Ÿ¦¢›£œ•Œ“—•–˜Ÿžž›™¦—“’–¢ ¥¢¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦ ˆxƒ|vzcwln]QhTPNGPMLBPQ@>;>49:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¤¬¨½Áª¥½fDS¡„PXIK`IXaee„¯µª²´®ª«¯°²³­¥‘—“˜ ž¢ œ£¤Ÿ¨”›–—Œ—‘—“˜¢ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨¨œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£žžš—š«¦ª±£¥¨ž œ•“‘‘™–•˜—Ÿ˜œ™›¤™—”–š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’}|€uv}mk{dhVRdMJHGORNJNH<E@<2@859;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜——–¡¨¬®¶·º¹º··»®¨ ¡© «Æ¿ËžNAuœoPnJLcfvua]bs’²¯®³µª¦¬«¢›™”‘•–˜˜œŸ¢¢œ¤žš¤———–’‘‘“š—› ¤ªž¡¡ž¦§ª¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¡¥¢›˜ž¯¨®²«¥ªª ›˜˜˜•“–š“••š–›——˜¡žœœ—›¡šžš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}wx|dyy`bSU`HIJKSTIRQM9?B67<65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—“’œž¤¨®­¬««¯ª¯©ž—ž¥œ¤ÇƋVRKf£Xg}or[Rkc\gbam‘´°°¸¬¦¡œš”—š™Ž‘•‘ŒŽ“™¢œ—£™š—˜™”™˜–›Ÿ¥¦© ¦¤ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«º¨¦«§««©¬¬§  £±®²±´ª²®£™œž¡™››š˜™›”–›–™œ¥¡ š£¡šœ™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ Ÿž ¥¡žž¥ ¦™{|vvsh‚lf[SZZMQJOOULSMB7>B78=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’‘œ˜¡ª¢§ ž§¡¥Ÿœ’›¢šŸª£ŒyUiqwuodwvXWb`di[ZWh­®¬¯§Ÿž¢ –“› ›™—’“Ÿœ¡£›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬©¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½·¿°¬±®­©ª´±°¨«¨²¶¸³¸­²´¤ ¥Ÿ¬¡¡¢¡ š˜––Ÿ››˜¥¡ ž£¡ ž›œ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚|xujwu^m[R`HRUHFUVJCMG=KH8F<77;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“Ÿ™¨®Ÿ§žœ¡žš™’˜ž›¡¡ £o‚p`cWL[SZLLQYRHONH™¬ª©¤ŸŸ™’‘“˜˜––•Œˆ‹Ž•œž—ž™§  ¨¥±ª§®£«®¶°´²±®¶¸½Àº­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«¯±¹·¼¯³°µÂ¼·¾³³µ¢¬¢©¨²©ª¨§¨š™žšª§ ™§ ŸŸ§¨¥¤Ÿª¢¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰…„~vrmivmhm\X\CWNJGMGCFM<>L>4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜™ª ±¢·¤°¦Ÿž—˜•™žšœ£žœ‰bW^e`WMQG=?@CD?>CRx©­©ª¥Ÿžž¢£žšœ›”“•”˜”…š¡›«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶º»ÀĹ½»¬¯§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¹Â¾¸³»ÆĽü·³ª³­ª³µ¯³®ª¯£¬¨¶±­£°¦ £¯±®°¤¥¯£¡ š¡§¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¥ž¦™›¢¤žŸ›››œ‡†{trkktrqhV\QFTIDJPI?EA4FH95<>7;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž  œœ˜šŸ š Ÿ•|_^e`PFE;B>F<>96N~ª³§££¢ ž¥«¥ž—œ”‘™˜”ŒŠ†ˆ†xmˆ ¤¢«¬´¼¶Ã¾¾³»ÁÃÂÅÀ¿ÂÆÆÅÃÈÂÀÅÇÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌÌÌÒǾ¿À¾ÇÆ·ÄÊÉÃÁƾºµº»µ»·°¶²ªº²®»·¿»º«¸­«ª¸»µ¼®®¹£¦£ž¦¥¢£©¦™›Ÿ™š§ª§ ¡¡¤˜”£–”™‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ„}zqkchoxkeZ[FKLEDTMDCE7:?;549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;?>=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ²²¸§¡¡«ª¡œž¡¡›š}riaWNE>IZ|oaA=\Ž®¬ ™››žž™———’ŒŽ––“Ž‹‚ƒ‚wrqmp¦­®´¹Å»ÍÇË¿ÂÌÍÍÌÇÉÑÌÍÌÇÉÅÅÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÑÓÍÓÐÓÓÌÊÂÅÆÆÊÈοÈÑÌÇÅÇżÃÁ¿¿¿¶¾³®¿ÀÃÃÇÄÇÄ®¿¸²¸¼Äº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›Œ™‰•˜› Ÿ£—žš““‹•…€ytsebgrof^ZYCNLDFPIDC@55589B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A?<@?>8;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›¢¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¤¨¬­ª £žœž•if\TID@?J†ž¤˜ƒ ²­£žœŸš˜—”’”–‘Œ‡ƒƒˆ‡ƒ€€yqroly¤¶º¹¾ËÁÓÒÓÈÍÎÑÓÑÒÑÐÑÑÍÎÎÐÅÎÔÕ×Ñ×ÍÆÇÉÌÃÅÊÏÊÓ×Ò×ÒÕÖÓÔÈÌÆÌÍÉÒÍÎÓÍÅÈÊÊÁÇÌÇÉÈƿó³ÈÄËËËÏÇÊ¿¾¿½ÁÇÅÍÌÉÉÀÃÀ®¯³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›•Œ†‘‹€zruvgcgvidVWQDNF@JQB>B<:22A<E<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<A?>9:@A:9>9:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­³·¬®£ž£¢¡›aSLJDC?CT±Ñ½²¯¦œœœ ¤¡š”“•”‰}xpkebhqoq{…Š€upnqtp…³Ã¾ÅÑÐ×ÖÖÒÖÎÔÖ×ÔÓÑÓÔÔÓÏÑÃÐÓÖØÕÖÒËÉÎÑËÆÍÒÊÒÕÖÙÖ×ÓÖØÎÒÊÏÑÌÏÐÌÓпÈÇÊÄÌÌÌÎÏÅÆǶ¿Ê¿ÒÍÌÐÆÉÈÀÄÃÈÎÍÐÑÏÍÊÈ͸·»¨Ÿ¥«§Ÿ˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„|xsvpc`drb]R\IJGAEIJ>;A8=5586;85:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÁűµ¨¡¤¥ ¢¡YI@ADAFQv²¯§š”—Ÿœš  ž›œ™•‰wica__`_^__]blutppolrqu’ÄÈÆÔÖ×××ÓÖÐÕÔÚÔÔÎÏÕÔÔÑÑÌÐÍÓ×ÖÓÕÐÏÒÓÑÉÓÑÈÐ××ØÑ×ÒØÙÔÖÌÏÏÊÍÒËÎÐÀÆÂÈÆÎÎÑÑÒÈËÍÀÊÌÆÓÏÌÎÈÅÊÇÇÈÌÊÔÔÑÕÏÒÌÓ¹ű¥¨µ®§›¨¬¥²¨°³¬¬““ŽˆŠƒ‹„Ž™“™‚…Œ|zqstmacim_VP_JJCFCRM?<>43:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><??=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯­ªª«¥®·¨«·ØÔÕÙÙÑÎп¼Ìɶ¾®¦ª¨¡£«eC8=>DX‚ª¨Ÿ—•—™šœŸ˜œœ’}pecb__a__aa_``_`fnppnkorwwœÌÁÒÕÓØØÖÙÑÒÒ×ÏÓÎËÒÍÕÔÒÊÏÌÓÖÒÑÕÍÏÕÕÑÅÑÔÊÐÔÕÖÎÒÐØØØ×ËÈÎÄÉÏÌÊÌÀÉÀÈÊÍÎÐËÐÍÎËÎÏÈËÐÐËÎÊÂÉÇÉÌËÌÒÓÍÓÒÑÐÐʽȹ°®»¹µ«¶°­¨¸­³¾»±š ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…ˆzvopokadnpaW\ZIFFDMXE;@=33<<87855;>@=9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ¤§Ÿ¸¶µµ¬¥¬®¾´°ÀØÒ×ÚÜÖÎÍÊÃÒÏÁÁ±©¬­©¤±yHFB;WŽ¡›•“–›žžžœ“–—”ˆk^^^adb``````a^__^\bmroostvvy¤¿ÌÕÑÖÔÓØÖÎÎÓËÎÎÅÎÊÒÒÏÇÎÍÍÔÌÎÓÍË×ÖÐÌÑÔËÌÐÒÓÊÎÑÕÒÕÕÊÀÊÂÅÍÂÈÉÃÌÃÅÈÊËÏÊÍÍÐÎÓÌÆÉÏÍÈÇËÅÇÁÆÊÌÍÐÑÇÐÏÎÍÌÐÅÇÁ¸¹½Ã½ù²²¾±»Ãõª˜¥¡˜–’••’‹”š‘””•‚‰†yqrkmg``qhYXhVMGLIPQB;C>;6898::57==A;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?;<;<=8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÄÂÁ¿»µ²±Ç¸ËÕÕÙÚÛØÌÌÏÈÖÕĵ¯´¨Ÿ­—xlpr{‘šŒ—•“‘‘•–•‹|eabb`]^acb`__`aa`_][]grqqrspmry¥ÇÓÏËÐÐÓÔÊÅÉÉÆÇ¿ÃÅÏÎÇÅÇÍÊÒÈËÎÎÆÑÒÐÍÌÔÊÇËÎÏÇÇÏÒËÐÏƺĿÆʽÂÇÉÎÄÂÇÀÇÍÈÄÌÊÌÏÈÄÄÐÈÆÂÆÈÅ¿ÁÇÌÌÌÏÂËÌÉÇËÐÄÅÇ»ÇÃÉÉÂÏÁ½¼¿°ÁÉƹ½ª°²§¥¢œ˜›£™—™‘•˜‰‚xotdk`^fqa[W`GHHGIMTG?J=64355==48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ½¹ÍÌÆÐÕÕÙÚÛØÐÉÏÏÑÓÈ·»»­£¶}hƒ…¤«”Ž–…ƒƒƒ}„„~s_[^^^`^`cdc_\]^_``_[Z\`krrookloo}¹ÑÈÉÊÏËÍĺÀû»»º¾ÉÆÂÃÀÃÈÊÉÈÊÈÁÅÌÆÈËÍÉÄÂÊÉÁÁËÐÅËÈ¿¹Â»ÆǾ¿ÆÏËÿûÉÇÉ»ÈÇÅÊÀ¾ÂËÆÅľƽ¼ÀÃÅÌÅżÀÊÃÅÇÒÅÁÉ¿ÊÉÆÈÆÐÃÃÆïÄËÇÃÊ·¿¼º´©¬¤¥˜Ÿ˜¬£¡¦›£ ›•|wstfiZanmZ[XRDLFBGDLDFS@54335?<3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ÊÏÑÌÇÂÃÆÍÎÎÌÕÏÕÙØÙÏËÒÍÍÎÈÁµÃ¾²¯¶l^y}¢‘‹’–†z€……vxurp_Z[]``bcdded`[\]]_^`[YZ\borokilposÇ½ÊÅËÀÆ°¶º²²³²±Â¼¼¼º¸ÁÁÁľ½¹½¿¹ÄÊÅƽÆÀ¸»ÃÉ¿ÁÉ»·»ºÆÿ¼ÁÍÃƾ¾µÁ½Ã»½Æ¼Ãº´¼ÆÄÂ÷À¶¶¾¿»Ìü¶ºÈº¿¾ËÃÁÆÂÅÉÇÉÆÐÆÂÌȲÇÉÃÎÌÁÅÿ½²·°²§¨¨¹°¥­°ª­¬”zvwjdg`hodV^YJFJEGKAEBFJ@9:648854;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÅÂÄÈÎÒÊÊÊÇÍÍÎÑÈÐÆÕÔÖ×ÍÊÎÅÉÅÇÁ¹Å½¬®¥_du„“‹ˆ‹„x††~„{ttc\\]^``bcbadeb]\[\^\^]Z[\^hsqmggnory½ÌÀúÀ¸­°±§ª­¬§¸´¶´³³´»µ¾±¶°µ¯²¼Â¼ÁļÀ»µ²º¾À¸È¹´»·Á½·¼ÆÁüµ®²µº¿´Å·»µ«¸½¾À½±»¶°¶º³Å¼·¯»¿µ·´Å¼¾ÂÅÀÃÅÆÇËÅÀÆÆ»ÇËÀÏÉÇÃÆÁ÷ý½¶¹¾Ç¿¬µ»µ·¶Žytxggebkn^V^`FKHHJFBDAEE?<:565633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÍÈÅÈÍÌÐÌÍÈÊÈÊÉÊÄÐÍÒÏÍÅÇÁÆÀ¿º¸É¶ª°˜[hoŠ…ˆ‰zx~††vw|sh]]]]_`_`da^cec__\[^\]^Z[[]_lpnhfknnr|¤ÇÀ¸¸µ°«­§ž¢©§žª¬³­ª¬©´®·±³©®¦¬³¼º¶Ã¹ºº±«µ¹»´Âº°À±¾¼»¶¼Ç¹Â·­ª¨°²À¶¸½°±¨±³µ»¼¬®µ¦®¶®»²±ª¹°­»®»¸»ÀÀ¾¹Ã¿ÆÃÅÁ¼ÆÂÈ˸ÅÇÅ¿ÇÃúÄÆ»ÆÉÌ˳¹Ã½»³‰swvkiablhYWW[ALKMJEAC?FA:9:995854::9;<=;:;>8;@<=9:79=9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÅÎÒËÃÅÁÅÏÇÍÁÃÆ¿ÄÄÃÃÊÂÉÊ¿À¼Âº³µµÃ®ª°‘[j’‡Ž{x}‰…z{„€wn^]\\]_`__dcadcb`_]Z[ZZ]ZZZZ\enohfgiknr­º°µ®¥¤§§š ¤ šœ¥«­¤¨¢«ª¬«°£¦Ÿª­µ¶±½¹¯·°¨®¸´´¼¸´½¯¸¹µ²¼À²À¯¥¨£«±²³¨½ª«¨«¬­µ´¦¨®¡¤¯©²¦¨¨®¦¨·­±²·ºº»²¼¾¾¾Ä¿µÂÁÇÈ·¾¿Å·Äÿ»¿Ä¾ÄÈÌÊ¿¿ÄÀÀ©‡stsji]aodWVXPHYRSKFFE>>@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÐÏÌÃȺºËÁʾ»É¶½Ã¾ºÊ·ÁÃÁ´¶¼¶±¯µ»­¨«’dmˆƒ‡‹€z}~xt~|swe_]\\^_`^_ccab``_]]\ZXY[[YXZ\_fkfdgehjor…ª¥¬¥žœ¡¤”¤›—‘¡£©££Ÿ¥¦§¦­ œ¤¦¬²°¶·§±­¨ªµ«´¹±¶¶®¶¹²°ºº±·¥ ¤Ÿ¦±¨«¨¹ª¤¦§¨§²­ §¦Ÿ›¤¦¬žŸ§£ ¡±­­¬²´³´°µ½¶»ÁÀ²º¾ÃÁ±¹¹Â³Á¾Àµ¸¼½¾¼ÂÇÄÃÄ¿ÀÄ ƒxplbf`ko`UY^HNgOTGFKF<=?=:;;825536999;9::<:7<?<<;<88<9;:;78::<98>:?=98<:;=:7776788666;::;9:;<859<:>>@;Èµµ½¸ºÀº½¶ ž”¡¦º¶«³³»³ÄÏÉËÂƸ¶ÇÀÌ¿¸É·»Å¸³Ä¸³¿À¬¶¼²¬¥¯³­¡£‘ir†…†€|xusomjjipi^`]\\\^__acb```a]\[\\XYXXXVX[^_dcbegggkmo‡©Ÿ••š¡–›£˜•ž¡¢§œ Ÿ¤¥¢§ž›£› «°­±µ¤©ªª¬¬¤´¸­·°¬³¶¯³µ¯°ªŸžŸ£¢²¥¦©¸­¢¦¦ ¨¬«™ Ÿž™Ÿ¥š™£›œž°©«§««¬­°²¸¯¸¹º°¶¼»º«³²¹³¾´¶²±¶µ¿¶¾À½Ã»º½—„zsk_e^ddXTW]IW\KPGJJGA<??@;?<04535:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»·ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÆÏÈÈÀÆ»»ÃÃϾºÇ¸¸¿·²Â´±»»¬ºº±¢ž©«§˜žm~…†xrmomkb^bff]]^]]]\]_`abccba_\[[ZZYXXWWWXXXZ^bddeffhikqŒ¨œ“””š—š¡––›¢¡¨žœ¥§¢¥œ ¡›™¯®®¯²¡¥£®«§¢µ°²²¬©¯³§º³¦¶ ¢žœ£¡­£¢ª¶«££¦ž¥¦£–™—™› š—œœ­¢«§¤£¦­«²³ªµ°²«²¹´¯ª¯²²³¸³®©¬®²¸°º¶º½À¸³±”…yuf_f^[YVSZUK[QKIEHKIB=?AA@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½·½¿¶¾¼¿²¥£˜¥±Âµ¶½­´¸ÂÌÈƿŶÁÀÇηÀĽ³¹¹³¿¶±¹»­²´¯Ÿš¤ª ”šxƒ„xoqtqhedhdc\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXWVWadecdeddhjv¡›““”––Ÿ—™”— ž¡œ– ¡©¤ŸŸ©››«§¯°«›£¤¸ª¡ ®¨¶ª§§­±¤¸°¤· ¢›™™ª§¡š¬¹¯¢¡¤œ¢Ÿ “”¡”––›˜—–—œ•Ÿªž©¤¢£ªª°­¨´¬ª§­³°¥«®³±°°®¯§¨¨²­±´°¼´º¸®£”zve_aVYXSRSKM^LOKGGLLE=A><B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾¸¼®§§¢ª»À½À¹®´¸ÁÌÇÅÂýŸÈ̲ÁÂÁ­¼»µ»¼µ¹¹°¯°ªœ™¡©”‘Š‹€€|wqilrtphhedfb\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWWV[bcbbcbcdfi•’”‹‘“”š˜œ•–œ œŸ– Ÿ§¦¤¦§Ÿ ¦ ª¯¦Ÿ¢£·¨¡¡¢¨³¢¥¨¥°¥±®¬µž¡••©¡¢”­±±Ÿ££ž˜›“‹¡”‘“˜˜“——™—ž§œ§¡¢š¤¥¥«¤¥°§¥£««­¦©®¯¯«¨ªª³¦¦¬¯´±®¼µ±¯¯ ’zwsea\[]XNLQGQaMVPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8847763321./2556;:8;7876<;:;;A8x»»±µ½°»±·¬ž¥¦¬¸»¼Áź±¹µÄÉÉÀÃÆÅǶÅij¿ū··½¶½ººµ²«­¨™˜Ÿ£‹‰t‰ˆ~vncafihfgifjm`]\[ZZZZ\]\[\^_\ZY[YYZ[WUXWUTVURTRU``_`a_aabei€’’ˆŽ“’“œ”•–£™ — ¥¢­¦¥¥£¤£œª«¥šŸ¥±ª ¡ž¥ªž¨¢Ÿ®¬©©®­¢¢¢•—¢›œ«©°œŸ¢Ÿž—™“Šž‘’“–˜˜“œ¡£¤¡¢• ¡¤¥›£«¥¢¤ª£«®¥®²©¦¥¦¦´¦©¨­³µ´¹º°ª¬žŒrpp`[WVVRFQNHY[ORITKSLEFID8;;=<8667:9;:976977:;:=<<6;<8>698:88659:;<97?<9578452121..1426:8698598989;9@9{µ´­´»²°«²­¨§¯¹¹³ÀɺµÀ¯ÅÈ̺ÁÊÌȵɼ±¾ÃȬ±¸Áµ¼À»´´ª¬¦•š››ˆrˆƒ{tiiilgjlmkjle]\\[[\ZXZ][[^``\XXZYXWXWTUVUTUURRNQY]\]]^___bdmŽƒ†Ž™“”’œš£œ›¡¨©«¨¬§©¦¤™¥¯¥•™¥¯© œ™› ž¯™œ«³ ¥¦Ÿ£¤¡”“›––’©ª­š ¡ ›”Œ™ŽŒ‘Œ’–•ž¢¡¤›£•› £¡—¢¨££¨« «°¤­·¦£¤¢¬­ª¨«¯³·³¾µ³«¯˜…tsh[XYSUREXLQ[XMTNPLQRINIB=??A?=75799<<977:79:;<=>;7;;:=58:;8976989:6:=99577570141-+/434988::8::748=8?9~³­§³·®©¨¯®›©¨¬·¶¬¼Ê»¶¿¬ËÆŸÁÎÏȳĺ·»ÂÈ°­¸¿·¼½»³µ¦© –—˜–‡zt€vwnmhmmmpggifd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUSSNPQYZZZ]]\^_ad}‹€Š~Š‰’—‘—™¢ › «ª¦¯¬¨°¥©šŸ­ •–¥©§˜šž®—˜¨ª™Ÿ”¥¡Ÿ’‘’‘“•¨«¥š™™žž–Œ‹“†ˆƒ‹’•‘ ž¡¤˜•Ÿ•š¡¢ž”›¥¦¨¨¨ ±°¦±½¨Ÿ£¬´ª®§°µ°¹µÀ±®±«‘~rsbVTVNRJGVPSQLLWMJMORGMKACFDC>A75889;9:7::7<=:;@>:9;9:?759:9876958779;85576761320-*.102877;99;8948;8@8³¬¥±·ª¦£±«ª§©²±¤¶Æ´¹º³ÊŹºÁËÐʱ¶·¼½Áñ¯±·­´´»³´¢£——”ƒ€vkglnqnqjpkdege^ZYZYZZZZZZZ\\]\ZXXXYYWXWUUTRSUSVURNNNRWXYYYY\]]ajytˆŒ†‰—‰”“˜›˜ž©› «¦¦¬ž¨š ¦œ“Ÿ£š——…„’›£•£–––ˆ¢››“‹ŽŠš¤§œ••—›‘’‡”Ž‹‹Ž€‹’’’ š¡¢–”˜˜•¢¦™™¤¦©¦¡ ´²§²·¡œ¢¶¬©­¤²²¦µ¼µ«¬±£‰ysn]NQQLOCMNNPKFNNJJNNQHMJAGKHHC>858889:;69:68;99><8:>9;?8789:886857688974577820301+)-/12876:999984988A7w¶§¤¶°¥§¤ª¥ ¨¦¥³ª¢²Ãµµ²³ÆƶºÃÊÌƳ¬¹½´¸À¯­©°ž¦®º¯®Ÿ™š•”‡{ƒn__frpuqinieghj_XXXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQMMKLSWWVXXXX[]anruoƒ‡ˆ€‘„ŽŠ”‘“ž¡›œ£¢¤™¥—¢œ•‡™šŒsƒ~Ž—–†‘š”ŽŽ{™Œ‚‰Š˜ £ž“˜–…‚”~~s‰Žz‡“›šš‘–Ž££Ž‰š ¡¤¤›¢´¯¬¯­Ÿ˜¥¸¦¦±¡°®œ°¼ª©¯ª™ƒwscVMROPNCSNLPLBPQHINRMHJJDJLFJK=749888;;69;7:<9::;79?9>@79:<89764445874312585/0102)(,-02764789::65:87A7x·¡£´©¦¦¨£¦¥¦¦¦³§¥´Á¸°´°ÉÄ·¹ÁÎƽ³¬ºÁ¬­Ã­§¢¦’¦¶¬£ •–’}w~fWV_gfighncjhgb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTRMMJHNSSSTUUVY[]ikqk~„{sNXr‚—†œ—‹”‘Ÿ˜•”–•–‰€”‰_;Vo|Œ”‰€Œ’Œ††sŠ…—y{†“”ƒ•Ž‘ƒ†}“xqp…Œ}‰‘—š˜“‹‰ˆŸ˜‡ˆ–žš¢ —§®©­¨¨ž—­³¢¦®™¬«˜¨´¢©­£“sn_[NSRWLDTJPLLFNOIELQMKOJILPFII=7599999:7:;:>>8:==7:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9y· £®¡¦¦ª §©§£©°¨§´Â¹°µ°Ç·³½Ï¿¹¯®µÂ§ªÅª£˜ƒ”œ±¢š˜†”‹‡}su]PLQUYZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MORMKHFHNQQMPRTVXZ`lnhztOB?•’‘}ˆ”„Š›Ž–•‰’ˆ†•†y‰`JQnx‹’„}„Š…n”xuvx„špQˆŠ†{~x”vgw†ˆ~Š‰–‹Ž‘’–Œ„‰ˆ•„›‚„’š–Ÿ”¤£¨©¥¤ž›°ª¡¤¤‘¦ª–¢ªœ¢¦¨‰vmf^[HQQSMIUMRILKOIHFJNLMTKQPOFIC<768:8:;;8:;8>?99>=8;<6;;478;7775344696/3/.125221/,')**,4833989:99::::?9w¶œ£§Ÿ¡¯¢§¨¥§¨¯­ªµ¼¶··³Á»¶¨ºÈ¸¶¨¨µ¶ª²½§ž•‰“¨–•Š~Žƒ‚}wpoXMKMMNLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDDINOhYNQSTUZnƒru~ih\T‰”‰t†|…Œ“‚’š‹{†€v€xsovqtŽŽz~Š«„y{hv{Žprmx‹’xz€{€vsr’whu„„„…|•ŠˆŠŠ€„‹€”„|€˜”œ–‘Ÿ©žŸ  ©¥ž˜Œ§¤’  –žŸ¤€sha]]JWPRGKXROJLMRJJJLPHLQLRTMEHA<78;99>=:;<98@?::>=7==79937785675252472/2.,//200/-+(().12721987:8775:<;7v®™£¡˜Ÿ´©¯©¥­¬°±ª½´²»¸¶º´±Ÿ·º²ª¬©¨²°¡š‘”ŽœŽ‘v†x|vooiXKHIHGEHHPTTTWWSTUUUVWWWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQQSV^t‚{xfv–˜Ž}gyvx€‰}„˜’q‡|w{ok~­}t‹{†’|ufv|…logs|‰Œ‡€lyq}qmvqhq~ŽpC‹…‚ƒ…wwzŒ†}Œ{u}Ž’˜‹’š›£–™šž¡œ–Š¤›Žž—Ž–˜womfbZXXUQJSUTOPNPVKNKOOJQOHNPLFD<;79;::?=9<:99??;8<=7<9999266856633621224.,,-..-0-+*''*.1362/876966527995y¦— ž–¡¦°­®«¨©±¯±«¼¸¬»¾¸³¬§›°§¬›–œ¥©¤ —™…’yˆŽ‹Šuq{mupjmjXKFGEA@CDHLLMQRPQSTTTUVVWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNPQTX]eprlˆ§ªÀ~tyb{xo|y‰z}‹†omŒ’ytyjj€‚q–‘‹~–€I’˜nhx~‚midly…’†ksl|nr|†inpsŒ‰„†{~{vott†‚yyp|ŽŒŠ“ƒ–—˜š’–—™—–Œƒ‰ž‘‹’†–€nioooXVXTRQYORTTRXUMNHNJMNKCHMGE@:89;99:><9<;::=>:8:<9?868727565541432/024*+**-.+-*(*(',-1250,5567485HA895w™‘›™šŸ¥­°¢­ª¨µ¯®¬´¿«¼Ã¿¥¢š•¤—ž„‹”¡¡™˜‘“‹sŽz€†Œ†totkpldljYNDFC@<>>AFFGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_IMOORWZQY\_§ˆbšisye~pmz‹‰v‚ˆ†tlš’ts|jjMy…“‰„Žg1v†sl~~ƒtfeu„„…€filukq|hqq|n’|t~}qpnum‚wyujy‰‚ˆ‰ƒ–’’‹‘””Ž—€yˆ—ˆ†Š†€ˆwkkoheXQZWYY[MPUVYXNIHEJJHGB@GDCG=998;9:9<:9;:::@<9:<98>787715234533645031/**+),,++)(+'),,226,,4775478iO8;5n’ˆš‘™–¤¨®Ÿ²ž§º¯«²°Â±»Ãǚ–”™‹Ž†y„˜”Œ†q‡‚t‡Œ†yprpoodpf_TFIC?<;9:?@ADCEGILOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOOQVLAIQIb¯³ q{xl}lqƒ‚…z„††yr¡•tx€su”‡5q¨Ž¡¡„¢…vq‡|‡|tŒ®Ž‰€hgbjnrmpƒuipXupŽ›’wl{}mrnp€{svnbvƒ†€…ŠŠ‰‘‹‘Œ‹ŽƒuxŠŽ€~ƒ€}{rppl`[]^\YX`_RN[ZXWLHJFIG?BABH?CD=;97=;:;;9:99;:?<88=:8;66651121253474531./,,+)*))***)(*)+/3DM2166643<vR7=7b’’ˆ–‘ž¥§Ÿ¯•¥´©®±®Á²»ÁƖŒ”€ˆ}n’‰ƒŠ‡†u‚„l•ˆˆ{txxlwnwci^JPG>@7449;;;=>@BEHLLLLNPQRTUVWXZXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL7CMRSDJ†v€||v~lwˆˆ|~…ƒŒ~u¢™y~†…™„šœa†ªŸ‹ƒŽzw‰~‰ˆŽs‹—„z]drtz|wŠmhjbyo†‚zowt„zptyxkni]v‡}‡|‡‡ŽŠ’—ƒ…Œ†}q„ƒ}uw{|‰wpstfg`[[^T\f^WPTX[UGJKDKG?F@DC>AA=;97<;;=<::99;;=>79>9985653244004645554-,)+('''&(())((+++/00Uq=23331E~W4=9\ŒxŠ€”Œ‘Ÿ¦‘ ª ±¨¯À±ºÅº–Ž‘”‡z…vkŒ‘‚}Š„Œxƒ€s „Š}|p€~zgvkRWL@E211367688:<>AEGFGJKMOQQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMORLKT]YRJh„‰{‰y|q|Œz}‰‡~—‡v¡™ˆ‡’”¥¬ªH†®¯¯‹€“Š‚‹‚„’©‡€˜˜Š›tm}†‡}Žhghyn†‡‚…q„†Gl€wryvhmk_v}ƒˆˆ„‹y”œ‰‹ˆ‘zu‹v|xmow}ttrl[^][ccXge\UPPVYPDLKFNICFCC@@CA=988:::;;:888::?>6;>7595773344236656768;DFLMMLC7+"%'+)+++/00+nu22420L\5=<^„t|~‰…ˆ‘Ž–—’— ¬¡¦¸¯³½³—’‹˜‹}tp‰’~}Œ‚’”}†~†¤‡ˆ‚ˆ…x‡ˆ~s„x_cWKB60./23123668:=>?BEGHJMNQSTUTTVUSQOGC?80,#‡[>?94.]–ps£UFIKMNPW`XpY\^i“‡•€„‚…‘“~…ˆ‘š•‚¡¡˜•››¦­“š»±§»Ç苌¡¥”‰‘|qƒžŸ‘œv……‹ˆihoƒ€u‡„‹q†‚w‡{v…}nvuf€”Ž†‰ˆ‡ˆ‡ «¢–‰Ž˜z‚‰zyogkx~zsle^Z[]j]af`YOKNWRQIPJDNGCJDBADDA<:87=<:<:88778:==8<=68756623444576867<BB?<8:>CQ^e\G2'&,,--.1(?‹[.310Oƒ_4?;nupfxƒ{€ŒŽŠš›¤¡¬¦«¯±—‘‘„¡”„xwŒ”|~’…’•Š€’›Žƒ€ŒŠ‚‰ƒ‰mpj]B@4--//./02234778;=?BDHJNQRSRSSTRPOHDB<87/9D><<63.l“—MPHJKKKNV_cggmu›š’“‹Žšˆ’‹  ’£ª¥£¬“©¶¢¨Áîǯxº”š|¡ž™„“…‚¢Ÿ“˜’„‹…š‘–lpu‰‹‚–Œw„qm…Š–‘ƒ…ˆrˆ •†’‰Ž–¤µ©›•¢ƒ‡“ƒ~€kjk|€‚tb^d_[gk]lk^WKGORQNLLFIPCDMFACEFB=:97=<:;:987767;:6=:785456344566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYp‚pu†qv’†~—–š•žžœ§ ª–“˜žge¤š~„’‘y’ˆ‘’}Š„˜’‘‚€€‹Œ‰††„ˆ…xx~gMR>/..,/.-/000212467;?CENPRTPPQSQNPIED>;<:CF?><752<?R5HHHLLMNR^oŠ|s} œ§¥¢™¡—¢”œž§ž¨«Ÿ¨¬©ª¶—«¿«¶ÈÈ·ÉÑϾ› pi«©Ÿ„“’…œ¡š›™§‘‘‰–¢ššwz~”˜’¡’–˜”ž{w•’«²ˆ—Ÿ}”›Ž’•˜£¢¦¶°‘™¨ˆ–‰lsr|}ri`]a_agd`gf[REJKPOIILFFMCHLFGDBGEA:85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Ppu`n}awŽ}{”ŽŽŠŸ’—ž–›ª˜žªBD}‡‰‡˜x‚ŠŽ|Š†Ž‚€‰‹Š„’…ƒ†‰€†v^bP460-1/,.00//..0015>ABMQRSQRSTRNSLEE@<>=GG@A@8662<9;FHGIJNOQYm…w•Š£§ª´½¸¤®¬¬§¨´«°¶²²­»±³½œ³Ã¬»É˷ÿ¸¥£°²¬­ª£‹–˜…¦¦ £—¦™¢«¨¤ˆ…”¤¡ ª ¤©œ±‹•£§·º› £°’¢¢ž£¡«¯¬²µ¢”¤ªˆ™‰’Š–zz}…hah\eb]dc^fg_ZODIHSNFHLFJGFFHAKFCFFA;87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLicWjoXz…v“…ˆ‚›ƒ’‘Œ’Úȝ–sV—ˆˆœ|†ŒŽŠŠz‡‚‡Žƒ…Œ…†‡’†‚„‰†ˆ‡‡pna@E64<2/110-,+-1.-3?DAMUQRSUUVUN[PGGD<>>FHCD@8;<5C;=FKIGHROPW’ „®£³ª²ÀÇê³Å¶¬³¿³¸¾¶¿´Á¶»º£¸Å¨¶Éǵ¾¹´¨£´­±±›š’šŸ‰§¯«¥”vŸ¤—¡¬²³˜–ª­¨®¶»²º¬¯µ¢±¬±µ»·µ®µ §§£§š©¯­²¹·¸§›¶©Œ¥Ž‘“ †x‚ƒvZbeWfaac_`f`[TIDDLUQHIJDIGEA@@KDBMG<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AFWQJL[ZQbcWyuq”}„†’u…Œ{¿»£¼‚´”“›„ˆ’‰ˆy†€Œ’Œ‡…Ž‰Ž††‰…Š‡‘zxn]V@EN<6:46AB764//6CHCQ\OQUWU\VO^UIKJA@>GKFED;>@7D7?BJJEFWTP^¤­£±´Â¶¸ÁÌɶ»Ä½³³À·¸Áµ¾¯·t±³¥ºÅ¤°Æ¹±³±´¨¤µ¶ª± ¢–š¢’¥°­¦­¬§¤˜ ¬´º¢©²ºµ»¾Ì¿ÅŽ½³Â·º¸¾·º·¹¬¬°¦±ª­½°¼ºÂ¬™º¨”®—˜«‰~‚}kWdbYkejeW[cYVSIGFLQGCHIAHD>?BBK@@MD99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FRLALRWSYUZvjp~Ž„ƒnzsx‡b¹¡™£‰•”–“”“–’‡†{†•Š„Šz|‹‡†}ŠƒŠƒ•}wyueO\dGEL;Qca[^SF?;HPE[cQRYXZgYT``MSPEA?IJHEFA@C<E6B>HGKLSZT^“¯¸µº¸É¿º½ÉÌ»¼À¼·µ»»·½´º±Æ`u²¥±šž«½ª¥¨«ª£¢²µ¡«¨ž•–Ÿ™Ÿ®¥§¦¥Ÿ¤”¢§±´§²³½¶Á¾ÓÉÉÓÇÂÅÌÂÊÃÀ¾½¿»¼·´¯¸·¶Ã¹Å½ÃÈ°ž¹ª¡«Ž¤§¶‰€s`bb^Xb`ifRX`VRUIEENKA>GD=KB=B@=F>;H@796379>489:57045/26389374426?8@>GKRTSQPOQQPJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKE@IMPRKQ]glkp…slrrs‡ÕÀµ™ •™™‘Ž—’––Ž†‡}†ƒŒ–‹ƒ‚x{‹ƒ‡|‹yŠ‚—s}zkepuY]\Peeb`ed][XW\MemURmm_n_XgeUYUJDBKJHFHHHGBI9D?HKTTV\Z[“¹À¸½·ÆÀ»¹Êʺ¶º¶¸¹²·µ´®¶¶™du¨­p^¢¬œ˜ £›¤žª¥” Ÿ”Ž–˜—¨Ÿ¥Ÿžš™ƒ¤¬¥ª°­·°½¹ÔÑÎ×ÐÉÌÒÌÏÎÊÇÀ¿ÂʽÁ¼ÁÀÄÄÅÊ¿È㤻°´¯›«¸¼™€zl^a]Y^aZccQ\`SPKCAEFE<@E>AHA@D=:E>=J?47535;=468977022/24169775555D3ELM>51/006:477@IOI;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODQ\Yh_o—’”nlouu‡³¬¡ Ÿ‹™œ™Œ•‘›’…ŠŠ~ˆ‡‹‹ˆ|„s{Šƒ…{‰t‰†•s{xkmu{hreilifjih`fihlZnt–­¤¼ˆ‡g[oh]ZZTHKNOJKPKSQHLAJFKP_^bfjb˜·Ç°¸³»½µ±ÄƵ°¹°°»«²±§ª·¬µ§›§šOšŒŽŸ–‘¦˜¥•Š““‰‰‘‘ž›¡—š•–†žš§›¬¯¨°¨´´ÔÔÔÖÒËÐÔÕÍÓÏÍÅÂÉоÊÉÊÉÑÇÌÍÃÐÒ¸°Ã¼Ä¹¥¶ºÃ¢ƒpd]]^Y`XYfZQ]WOPBBGDBH;AC>AG??A8;D>@H=46655;:687654/10146278875367C5B8?-0-1349=97,.,1;FK=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYSeVs˜‚hqoyyƒ ªž¥–Œ››—‹•‘šŽ}‰‹…ŠŠŠ‡|„‚pˆ†{‡rƒ‘‹}qxukqx~q{nxslipmcimpxiw|~Ë¿Âߧncwoc[a`JPRUNY^P]\NPNTQUT[nmv‚q–­¸¬³§°¶ª¬¼À°«µ¦¤¸¦«® «´£Ž±­š˜˜Œ‘“‘„Ž›¦‘œ‰ƒ‹„Š‰„‹ƒ“•—–“œ‘œ˜™™Ÿž«¬¤§¢¬­ÏÒÕÑÍÌÒÓÓÐÔÑÎÈÃÔÑÇÍÒÓÓ×ÍÑÑÅÒÖÅÀÎÇÇ辷Ϟzof^c^W`S]ZPQUPNH>@FABE<@B?ED>??:==<<JA45465<888664412/03526768533;=<E=@11+/249>5901022-2DN3)/3.32=N238C}_2A†tD:==I>@CFH<VRMN[u†…Šwlwp}~¡žž¡‹Œ™““Œ‹“–„y…‹Šˆ‘‡‚{r~€‡y„u…’‘‰ovrks||w{swqk€sripqzyrz¾Ëš~Œ²„vr„whaj]CZZ[VecXdjSX]\`d^cwz~‹™©¤¤¡Ÿ ¨¥ª°¸ª¥´£¡­¡£­¡§±Ÿ‰¦š“’‘‰‘ˆ”‰j•¢Œ™„€…}‘ƒƒ“–­‹••šŽ†’‘ž—§°¡ ¡¥¤¨ÈÎÏÈÂËÑÔÑÔÓÎÓÍÆÖÓÌÔØÖÖØÕ×ÕÉÔÚÍÉ××ÑʬÃÃ̌spca`XTZT\PKGJJJ@;:;DAD<BC>HB>BB;<9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/--;R017/532FD28>nb5=tM99@I<AD?A;PLFKYp€u}hsxr‚‰€•”…‹–‰ŠˆŽ‡wƒ”˜Šˆˆ‹‰~‚xs{}ƒˆwz‡‘–€ƒnxpmuvx}t…|ym‡vtn}v„ux|µŒ;A‹Å¥~Œ|ieVICfcecgjdnx[_fhknin€ƒˆ‘‹ž —˜Ÿ£¤¦²£¤³ ¡¥ © ¢±œ†ž’’’‹‹†ƒ„~œ›Œƒ„…z”~‚©•£Œ’Š—’‹}—Š›’«³˜šœ¨œ§½Ãƹ¶ÆÍÒÐÒÐÌÒËÉÔÎÑÕÚ××ØÔÙØÍØÛÎÉÚÚÒÕ¾ËÌ´ywoe^ZSVR[WFGJIEE=:7:@AB:GD@ECADB;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?1*(.BS39254/7K75<`bA<svV87AH:?C><9QECJTknnpbpqt†|—‘‹~‡’ƒ‰†…‰‚‡|x…——‰ƒ‡…‡z„yqz{„†uz…ŽœzŒp|oozq|qƒ‡€nŽzuw}|‚u{†‡°tX©Â¶‘‚pnb=^hrpqpnxveioruxqz‹‡Ž“‘›• •‡Œ“› ›ŸªŸ ­œ¡š™Ÿ¥žŸ«™‹šŒ‘„}ˆ‡ƒ…‹Ž ™“ˆ„‡~m™y„˜†ˆ“Œ”Œ†{›ˆ”®ª”•—Ÿ™§®µ½©­½ÆËÈÉÌËÏÉÃÑÊÔ×Ù×Ø×ÕÛ×ÓÙÛÖÏÛÚÑÖÉÔ˕z|ji\[PST^HCEIH>A==7:=?;=G=?AAADA>>:86DB755479.566435532323647553457EBDCEB56<FNSM[nfcnskaV>,4LG865434BF4=W_hLux^8;?F<<B<::D?CGRk_mdbfkv€ˆq‘š€z€~‚‚„„||„˜Ž‡‹~††€w‚yo{{†uz’ž vŽu‚tu}t€„oo’„t|€…zv†{‰·Æ¥Âɸ‚–›wpeNfczw†¢Šxyv{ƒ{„um“–”•—ƒ‰—š—–¥œ— —Ÿ’’—£™«•‘Š‘‚Œ…‰ˆ†‘žœ™‰†Œ†˜zˆˆŸ—ˆŠŒ‚|¡‰‹¼¡˜“—šœ©¦¥®Ÿ¨¶¿ÀÀ¹ÇÉÍÎÅÍÊÑÖÕÕÙÕ×ÛÔÖÙÚÛ×ÛÚÚØÎÜƇ|zhie`TXVUMLDNC;==<9:<>9=@6=?@<?><9867CA6455=80665547745613854564567HH=DJE7925;H>;::7IP]ZRUXK9T>;95327I8=NYMHxxd5=>C==@:6:>>@EQ_Yea][htzyl‰’wvzŠ{~€~€|…{~‘‰……z„‡{u}tm|}†~s~’‘žƒ‘|†~xŽ}yŠŠn‚š€t˜…}ˆ…{}z©ŽÃ ¼Œœ¤œ}‰„}‰rŒŠ~s¦šœ˜“…{ˆ„hGp ¤Œ‹’…‰‹’•œš’”‘–‹•Ÿ” ”‘Ž‹~ŽŽ‹„‰’–šŸŸ‰Œ”’‘‚‹¥™ˆ„ƒ…„¥‡‹‹¸˜‘”–¢§¡ž£¯¶ºµ¬ÀÅÊÐÈÇÌÏÓÒÒØÒÕ×À×ØÙÛØÚÚÙÙ×Û¸yyymjfW`\TPOHCLB==>99::99;=6?>><=9:;;37D?8378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWN<MTHN?96333>C;[X>5YypZ<<A<=>8589?=DRSRX^UXfmmmiŽŠqryŠ{z|{ˆz|{‹‡‚~uƒ…yszsm€~„}w…›¡š”’€Œˆ˜‡€›’n‡¨…z ‹|‘Ž‚ˆƒœ}š‘ŠŒ£¢Ÿ¤¯ ‹‘‹…‹’†Wr­‹Ÿ«›ƒ˜›Ž[‚¢‘‚ŒŸ“•Œ‡ˆŒ’’Œ”””ŒŠ‡–›•–‘‹’“…€‹ˆ’ŠŠ–™¢¢†“– Š‰ˆœƒˆƒ‡…¤†Œ³˜’”—¡¡ž™’œ§²¸¬¦½ÂÇÎÇÆÏÌÐÌÎ×ÐÑÔ®ÖÕØÚØÚÚ×ÖÙٟq~uhg^]XTWXC@HC>>>:49:;7:;:3;;?<>7;9:1:H>:37=@50677255?65;55858:57735HR7GOK994=EJB>1FCLB98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:;@;BQKKSYPTcbymb~’ƒomw‹xyz}†{{w†„sp…‚zuvvt„ƒ…}’¦£Ÿ¥¢–Š”—‹Š¨—rŠ±Œ„§‘„™“…™Œ¢– ˜“‰›ž¢’©¯ ‘•Žˆ•‹n·…šÄȲ›¡¥›œ˜–²d¤Íǖ†‡‰’Ž“”‰…Š‰…–š›”“†”—ƒ‹™ˆª——££ˆ™Ÿ—›ˆ‡——Š„ŽŒ‡¥‰“©š—“–™¡™Ÿ™“›¢³´¥£¼Á¾ÈÅÅÉÈÉÂÊÓÍÍÔ©ÒÑÖÖÖØÚÔÓÚ΃tid_^^NKTZBAGC;A=837;<:8>649:<:82?9:2:I:=67BC32:96264>=4;>6949;57944KQ<JQK9A7BGI@64JELF><88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBcFu‚Ž||l}ˆxz~z‚~vv€ƒ|lo‹y|xx|„‡‹}Š£³¨£«³¡–§ ¥¤–•®¢ƒ·•’³™¡ Œ¤›¯¢¤˜§–¨™­¯¤—•–”‹˜™– ÀŽ£É¸«›¢¦­™‘šœ²†…¨¢œ˜…ˆ‰Ž•‹“Žˆ†‡ˆ’˜”Œ‹““†”˜†ƒ‘œt‘™²–—¤¡ˆœš”Š‹—š‰Š–Ž†}Œ˜ŸŠœš™“˜˜Ÿ” •Ÿ›¡±®£¤·¾´ÅÇĽÃÿÆÎÊÉÒ§ÎÍÓÒÐÖØÒÏØ»s{w^aVaWQIIOEABE5>:76:?;<7=42669774=5<5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=89567=:JFDGN[\YJg`;H„‹zzm…†z|„x€…€}px|}|osz}{x†‹‰…ƒ’§»­¨²½¯¥®³³¨£¢°¬Šš´£¸¤•¬¤–©­·¦¤£Ÿ™©˜ª£¯°ªš™œ”•‘—Ÿ—™»»­É i¶¸«°”˜ž£«’—½£^ª²‚‰Š”‡‘|ŽŽ}ƒ†”•ˆ‡’–‹•ŠŒ—˜’™³–•ªž‹›”’’Œ™›Š’ž‹‰•Ÿ¢•˜š“œ™ž”¡ ”œœ¥¯¨¢¥³¸«ÂÈĵ»½»ÅÈÇÂÑ¡ÆÉÍÍÄÖÖÐËÔ¢q|j^[T_RPGD><CAB8?874>F<<6<35345453B3::BM:A;AHB;:@<746<B9?@B874:96>=47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPeGb`cpJ@‹Šr†‡}‰u‚Šƒm}}|pw‡wŽ‚†{Œ†Œš«ÂÀ¯½Æ»²´Á¼´­«³¶Œ¨²®®½ª›»¤¨­¹·«¦¦¢¢££©¯²±«œ¤˜›˜—ž¢¥¥’£¹®¨¿»¬­²¹¥£¦}ˆ†œ­½°ƒ‹Œ‹ƒƒ‘z‡Žœˆˆ—‹•—”‘š–§š±š‘«Žš’Ž•–—‘ ‘‰•›£¬”–”œž” ž›˜ ¡•šž§§¤¡¤°²¦ÁÆ𰺶ÅľͧÇÃÇüÕÐÍÄʈtsc][a[NKBL@EF>A?B;:4>A==5<6>333242A17@BN>G@CNCA=C=;86CC5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GE?CF\fF`igZ][“ŒŒˆ{‡‹‡ƒŒu†Šo~|‚q~z•z‘””˜“–§´ÆÉ¿ÂÌÁùȼº¯«¹»—²¶º²À®¥À¤ª¯»»ª­«¢¢ž§«¯µ°ª› ªœ¢œ•ž°´§‹¢º¹µÁ»«¨œ²¤£¨“…©ÃĤ‚‹‡ˆ„†•”zƒŒ‘‘¡ŒŒ”‘‰—Ÿ˜“™”—¦ ®ŒªœŽ–’‘••Ž•‘¡”†—Ÿ ³ž”š” ¡™¤Ÿš › ”˜ž¦¤¦§¤¯­¥ÀÄ®©·µÉþ¶Î²Å¾Ä¼³ÑÉÈÁµuym]Y]kSMICLKKI@A=CD<5AD;:3=8B332262A05IEM>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBf[Me\fTcj™—Š‹ˆ“†‰y†“r€|x‡‚‚z¡–¨™š˜º¾ÇÈÊÂÒÉÊÂͽÁ³¬»¾§º¿½»Ã¸¬Á©¬³»½ª°ª£¥£«®´­¶µ Ÿ®Ÿ¦¢˜£´½©›¨¼Á£¶¶¯«’¯¬ª«–†™©¦¥‘‚Œ“¥•‰uŠ’y…‘žŸ“”‹”£™—›””£ž©Ÿ‘¥šŒ•–ˆ}•’’£›• ¢œµ¦Ÿ–¥¤£¥žž¦˜ž•—›¥£©¨¢²¬¨¼Àį¥³·ÌÀ¹®Ã³»¾Â¸¬ÂÂÁÀ™nzbYX]\LLMJGDCHBBACK:4DH9;4<7E.12352B26SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQF7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>kI_XaZddVžŽ—Žž’‰ŠˆŸ“„x…•~ˆŠ‘€•¡š®¦¤˜Ã¾ÈÃÈÅÓÍÎÍ˻·¯º½´¼Ê¼ÃÁ¶¶¼­³¿¹¼®¯¨ ©§¶­®©²·šž­¢¨¡«·¸©¥¯¾Ã±½¹³§©³³¬­––¤«§ ‘Ž’±Å§•Ž|‘•}‡‘™ª™˜“““•“¥ž“™“¡£¢œ˜Ÿ™‹žˆZ——’–¥šf˜£Ÿ³¥–¢–¬­«§›Ÿ¦—™–™•¡¤¨¦ž¶«©º¼Äµ¥´¶ËÁ¸©¶¬³»¸®¨¸º½¸ƒno[XUVOFKSNK?AHEDHFG95FM;>7>AJ.32025B55OVN;LFKRLOGGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|hW;=@BFBrFiIRebLF¦”œ–¡—©–ƒ‡¥’ˆ‡‚œ„ƒ•‘”Žš¢Ÿ¯¾®¡Ç½ÅÄÇÆÎÎÎÒʾ»¶±º»¼¾Î¶Ä½·¸·²²µ³·³¬¦œ««¸«©§¯°—£¯¤¨¤¥´À°ª¬³¾Â¹À¹³§·³·²®•¤¬®®¤‹“•¡tÁš}–™„Ž–š‹±•š™•’“™™¦£• ›–š¨œ›¡ ™‹–`J–œš”š¥—T–°Ÿ¯œŸ¥”¯¯¬¥š¡¥”“™™Ž §¢™´©ª³¼¼»«°²ÇÀ¹¥««­±±£¡²²´¤qof\[OQLEPPQQ;HKIFHBC>9KT?A:=EM07544:B34NWO<JKNUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@CAF3>58JKCA=C;4EA:A?>H@5*B52,>c]g:35tde@R7&#3}iX;:BC@=QEWRsbWFH«—™ ¢¨¯™—‡‹§–Žˆ’…Ÿˆ„—ž š£¤µÈ´©Æ»ÃÃÈÊÉÇÌÎǾº²®¹¸ÀÁ͵ȺÀ¹µ¹±¯¯²´§£›ª´´«©¦®¬™¤®¥¥©¬º¿¨«¶¶¾Á¿¾¸²²Â°¸¼«£®´¬¸¥ˆ›—¦›v¾ „˜œŽ“™š‹¯–¡œ›—•›Ÿ¡©ž¨ ™š©™¡§ž—‘ƒnv’¢š•¢Ÿ­²£«•©ª˜«®¥¤ ¤¨’’™œˆ”œ¢ž—±§©«º·¾³²­½¹¶ £§¨¥§œœ¬©©Œefa_RLMGGNJVL=MDMIJACD<PU<AABDO18=77?B75UXN?HNQXRPQTJQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW;:=..SaMUHe^HE¬•œ¡Ÿ»®™”žŒ“ª›‘’“‰«‡¢žŒ¤­”££¶Æ½´ÁºÂÂÈÈÅÂÎȽ¹²¯¸´ÀÂʶƱÁ¼´º«¨­¬¯£¢™ª´»¦©¦«ª¨¯§¤«ª½¼¨­¼³·½Æ¼¶µ·À¯½¿³¨´¶«¾¤£—‘¢Ÿ¼Ÿ‰™ ™–ž·Ÿ©œ¥£›œ¡š¨¥³¡›¥œ¨©ž™•”›‹—‰¤¡”œ£ž ´¯¥¥“°«™«¬žž¤£©‘•• ƒžŸœ•©¥¢¡´´ºµ­¨µ²³Ÿœ¢¦š—•™ª¡žwa^`^JIFHMQINEFFBRKIADGAVRDH=AGQ1;B7:BF79\YKALPTUSMWRNUJD@JJNO9C?5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-1:g\FCCœobGE§—¤ŸŸÃ¬œ—¤—™©œ–ššª––¨¦•­­™¡«¶Ä»¾·ÁÃÀÇľÍÇ»¾¹²°¸³¿Ãȵ¿¯¼¶º·¦¤ª«¬  šª«Ä¢¥¨«¦ž«¯«¢©¨¾¸¦­½°·¶Ç¶µ¹¸¾°¾Á¶´²´¯½£—£–“›”®Ÿ¡¢¥££Ÿ¾¥©¨¬¡›¦Ÿ½¢™£ž¢©«¡—•ž“Ÿ‡…’ž¤ µ¬¦œ•²§™°§Ÿšªž ™•Ÿ„Ž¡š›“¥¤š˜¬±¶²ª¥©­¬œ™ ¡’Ž–©Ÿ”idZa]OJHKOMHEDIA=OHA;GIH[ROK=HOU4BF9>HG5Cb[KCNRUWVQXTRUH@8QQPM:G@4CHQSIC;C>GVKC@O>K<06;GF>;FA56?9:?9;15D0-,0Mv\4KZ5,MnW<-=)#zbQ5CKQ9oRF<KxecWL¢š£›žÅ¬¡Ÿ¬œ®Ÿ’£ž–¤ §ª¬—¶°£ª³¶Ä½¿¶À¼È¾Êȶ¸µ´°³´·Áƶ¾°¸´¹µŸ¦¬ª«žŸ¥¤Á¥ ©­ ¤©­¯¢¦§½µ¥±¼·µµÃ²³·¹¾±ÃÀ··­³´µ¢œ¤•‘“ ­ ˜¡¨©«¢šÃ­©ž¬®››ž™¦ ¾¡¤˜«««¦¡™šŸ’ž‰ŽX•ž¥¡ ¸ª§“˜¶£Ÿ³¡ ›¯—žŽ™”‚Ÿ—–Ž¢¤•¦®²«©¢¢¥¥–•™‹‘“¤Ÿ‰ce[d`LIJKOFEAFJ?=JB99JKN]QQI=LW\9FI=DMI8Hc\LCLPSYYVWOZ^IA=WQIK?H@5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+w`S6SZkWsHE6=ue\KNžŸ¡˜žÃ§¥¢³ œ²§“ª¤Ÿ£Ÿ­©¬»°©¬µ²ÇÃÁ³ÂĽÆļÅʼ°°¶®°µ¯¿Åµ¹°°ºµ¬š¨°©©šž¦¡§Â­›¬°œª¢®°©¤§½·¦¶º¼®¶Ã­³³Â¿±Æ³º¶«´µ­ª¢¥••”£«¡žŸš¨«°®¯»²¦ ©©™™—“¢¤¹ ¡¤’®¯¬¥¦Ÿ’¡ž•ž‘Ž•™£Ÿ§´¦§˜´œ£¯šž›®‘ž”—”š€’¡•Ž ¡“‹¦¬°¥§¢œ ž“’›”…‹’œž€cf[heKILJSBC@HG;;F?99NMU^RSJ>O^^=HPBLLI9Nd]LELRTY[SUO\bHA?ZQAHAKB7FELKN>;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<v]^?[U^fr@8<H–weA4Ÿ¤Ÿ› Â¨£ª²¡£µ©–²«¦¢¥²¬®©»²­°µ´Æ¿ÄĵÀžÊĶÀȵ«µ¨°¸¬ÀÄ´·®¬¶¹¥™«²«ª—Ÿ¦—­»µ›¨°›­Ÿ®´±§ªº²§¹³·²¸Àª·²Â¼³Å§¾®­·´©§¬¡—–‘¥¤¢¢—˜¤®¸­±µ¶ Ÿ¨¤™”•“¤ ·¢¤¥–­±²¥ª¦¡žšš›–˜¨ŸŸ˜¢ž¯²¢¦—®™¥¬—™ž¥‘›Ž”˜š…–Ÿ”Œœž”‹©©ª¢§¡™ž–Œ™†–‰”Ÿyei]liNPMNT=CAMC::I@77QO]^RVQAW`\BJSHVKH:Ud]NFON[W[RPQX]GAB[PBG>NC9HGHNP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1[bZ33806p[bH05JpiVCWFŒyfC;¤£¡¦¿¦§¯¯ ©µ«¹¯«¤ª´·±°¹·°·¸¸Å½Ãǽ¼ÄÁÇÀ¹ÁÆÁºª¶¥­»­Á÷¸ª­²»¢•­°­²–¥§‘«¹ª §°ªŸ°´²ª©¶µ¬»¬²²¹·¬¹°Âº½¾¦Âª°·¯©ª«¦˜˜ª¡¡ ‘˜ °®³«°¹š›©Ÿ™–’—¦ ¶©¥¢¢¯±³«±§«Ÿ›  ›ž¥œ¡—£³°šŸ“¥š¡©š•¢Ÿ–˜‰”˜“–—“ˆ›™”Ž©¨§Ÿ£œ˜›“‡Ž™‹~–…›kimamnXQQZUACET@;;HA7:XPd^PVWDY^^MLRN^KJ>Zd^NHPN[UYPKSWZI?DXPDF>N?=IGGQPB=CFBM?:2D?77547?=95E4+75/251.-.,1>*'+=\p=>1.1e[d@1647gY`F(?8l}h[V:‰{cC=¨Ÿœ¡©½¡ª°ª£±¸©¥µ²«¡­µ½¯³¸¼º½·¶Á¿ÉĹÅÃÀÀ¸Ä¾Á¸¯¶¨«·²¼¿¿´©®±·Ÿ—«­¨­—§©§»Ÿ¥­³ž«¢±°³¬©¶³µ¼­¯±µ¬°µ±ÀºÄ¶«¼®±¸«¬©¢±¥ž¤©Ÿ£—™Ÿ²ª³©ª³™§›™” ¦¤´®§¡¬¬­±§²¬²©¤›Ÿ¨¤ž”¡˜›¨µ©—™’’Ÿ™ž¡ž¬Ÿ˜˜†•˜‹šœ“Š–—š—¦¥£ –•–”•…{’ƒŒ—flshpr_GYfVDCNXDZ9HB6>]Qh\NY]G[^]NMRXdJJC\c`PKMNXWXPJVVWL=EUJEDAM?AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,+%2+*5K1.'_^aU150=`V^8)C3YU\gK5ŒzfL@¤š ¤¬·¤¬©¥®®¶©®³¹¦§±¸Æ·±·¾Áµ´ºÅ¾ÌŹÃÀº¿ºÄ¸Á¹²µ¬ªº·ºº¾µª­±¶™˜§«ª«›¬««½ž«®±£ªŸ°­³®®¶±¹¶©­®°§¶°³»¼É²ªµ´±´¯®¦¡³Ÿš¨­ ¥••š™±£­ ¥¯–¡¤™™’¢¥§²©¡¦±«©µ¥®°µ¯£™­§š—ž™™¬¸£˜”‘˜œ¡˜—”¬Ÿ”“™žš–Š”“žš¥£¢ ™–’’–{‹…{Œ‹ƒŒ“knxnu|aF`jYIHZ[={JGE6AbTiZM\aJ[]ZRRRb`LKE_a`PLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`Va.5(C^Q\.*B/JGP[H3cYUKD™— °¨±©¬¥£®®µ©·´¸£¬´·Ê»´»º¿¾´´·ÃÁÍǻý·¾¿À¸¿½±½®§º¹··Â·¬­±¹•—¦®«§£²©”¯º¤­²±§§¢²³°²°´±·²¨®«±¦¸¯µ³ÃŶ©´µ«°­©§¢¶Ÿž¦± ¤”›™”±ž§›Ÿ©©¢›•—¥¥¥·§¢±³«§±§¬°µ¬¤™¡¬¨›œ›”ª¹œ•ŽŽ‹™¢˜—¦¡Ÿ–„’—œ˜––ˆ——›¨¤ ’–‘–v„‡|…‚„Œnqxv|]Kel\KOc\?b{GI8GgWe[L^bMXYWTXTi]POHa^_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANIg27'FaLV%-B.=EMQ<3rkJDC‘™¤­¤­­«§¤°²³ª·°¶Ÿ«µ¹É¹®Á»Â·³²µÂÃÏÄÀÁ¾µ½À¿º¿½³Ä¨ª¹°¶·À½¯¬³³œ §°­¥¦°¥ž²µ¬«²°¬©¨´¹¬´²µ¬³¬©¬¨¬©¹®±°Ç¾¸¥¹¯©­­¦¨­°¥££®£©œœš¯™¢£¢£¬ž£ŸŸ¡ª¦¦¸¥«´´¤©«¨«¯¶®¢£¨ª› šš’¤´š‰ˆ’£ •” ”“…Ž”“›˜–•‡˜’•™§œ Ÿ’‘Ž‘w~Ž…}|}‡ŠŠqtr~}~\Rdo^NZf]FD–[G:NmXa[M`aNVWVWTYg^QRLcZ[TKGOTSNGIVS\N;P^JBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3Cd;6*HdHJ+:I?3BIS,>k=GH›©ª¢©¯¤¨¤³´±´µ±±¡¬­½Ìº®Á¼Ç±´­´ÂÃÑÅƾÀ²¾Á¼¿¸¼Å¨­·¬³¸¼Á°¬²­ ¤§­©¨¤°£ª±ª¯«±®¯­«³»§·±²©²©«¥¥£­º¬ª±Â¹´¬º¨¨¨­©¨±¥©¤¢®ª¨¢ž›¢¬•¤—ž˜«¡§©¡¬¥¢¬«·±± ¨¢Ÿª®°¬ž¦§©™£˜™ §˜†ƒŽŠ‹Ÿ ‹Œ–œ†ˆ‘• –˜•†–““—¥œœŒ‘Šˆ…}w‡…‡tsr‰vl_Y`ncQsr\K<„|F?WuX`YNc\NUVUWP\b^SONgXWVKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*35>10485(5/*,.30;),,'%234$,2-860)(1<^J0.IgDF8<B05EKX1@”[?MF•—¬§¢ª²œ©©°¶¬¸µ®ª¥««½É¼±¾·Ã¯±­³ÄÄÎÎÿ¿´ÀÃĺÀ´ÉĬ¯·®²¹À¿³®®«¥§ª°©§¨±¥´­ª°®­±¯³¬³»¤¸´¬¬®§«Ÿ£ž°·«ª­º¶¤¶µ¤©§¬¬ª­¡¨¦¦±²¤¦¥¡¡«–© ”š ¦ž¤¢ª¤¬¢ž¦±·¬­¢¤¢š¨ª­©œ¡¥¤¤™ ™•˜”‚ˆ… ‹ŽŒ™‹„˜¤œ’‘›Œ“’’”£š›š‹Ž‹‹|‡‚ƒ{t€„‚~txŒ¤‡yk^`ngWf‡dN@g’LDbyWbXReUMVUVTO\]aUKNiWVVIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*49?./463)4+*,+.#4.-+&(+79*&6+<-2,&06WZ.0JgAA<<C+:JO^4D†@HHD—’¯¤£ª°—ª©­µ«¶±«¤«ª©¼ÁÀ¸¹³¼µ¦³¯ÄÉËѾÁ»¹À¿Â¹ÁºÂÄ®±µ²³»Á¾³²®­«¬§¶ª¥­¯«¹¯¨°°®±«µª¶µ§µ¶«¬¤©ªœ£³³¨¨¤´´ ¶®¡©¨«¨¬§ «¬¨¹¶©ª©©¡©Ÿ­›‘¨¡ ¤¢¦¢©œ¦´®§¥©¢£—¤¦¦©œ¢¤£Ÿ™™Ÿ‘Ž™Ž~‡‡…žžˆ…Š‹Ž„†•£šŽ›‘’‘’Ÿ—™–Šƒt‡xuƒ{x~€‰žoqggqx\atˆiO]˜VHmxUdVQbOLUTUQOX[bVHPjTWTGPYUI>IHOQPxLNV=<KD?@A<@CUC9AK=5;E13;97*4:=+-341*8**+*,)*(/*&)%3;,$2)2021&/2Rc02?f=NX?C,>LT_/Ik6QE;•¯ ¥ª­™«¤­¯³´®ª¥¯©©º¾»Á±¯¸®¢¶¯ÉÇÈÑÀ¿½º¼Ã¾ºÃÁÀ¿¯²³²µ½¼Á²²³«³©¥µ¨¤­³³¹¯£­µ±¯±¹ª¸®ª®¶«ªžª«Ÿ£ ¶­©¡Ÿ¯³¡´ªž¨§ª£ª¡¡¬­¨½¯¬®¬¡§§Ÿ«˜¯¢˜¢ ¨§ž§›™ª°¨¢Ÿ¬¡¡’¡¢£¦˜š¨¦——˜Š‡•ˆ}†…„¤—…‚‚Œ‡Ž‘„…”¡—ˆ‘“‘‘•—Š…†xt}uyz€{tt{j‚‡£ui^el‚ugˆ‹|RWp^JxsSdSQ^MMRZgNLVYeXGSiRQ>BNQaQ:IHLSIqPLS;<I?;<=;@@W<<>H73CB15:93-5::)-31--6)(+-,52#2)',%.;.&1.0-14%,0Lh:38_=ad?F1CP[[+HO:WB4Ž±Ÿ¤¦«£¦¤¬¦´³°©£°§ª¸¾À¼°¨¹ª§®°ÉÆÈнÀ¾¹¾¿¼É¼Â¹°°µ²º¼¹À³´»­¹­£µ¦§¬±¶¹²§§ºµ­µ¼¯¼¥­­µ«­œ©¯£Ÿ¥¬«§œžª³¤³¨šª§©¤©£©¨©½¬´¯®©£ ®›š²£–¤›¤¥Ÿ¤šš¨ª¥žš©¡›‘š ¥˜–©©‘˜™“Š‚…}‚€ˆž†~Œ‡‘„€“›”…“¢Œ”‘‹‘›“•‡‰~€rzy~|iw|zupq~i†y„ˆd`hcs…zmgy]^UBWzlTaPRYKKMpt]HZ[gYEVfPC>KNDCA9HGKS?jaIQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11&/>KI1%90%,,09/,,+6'17#-/GjI14X=fbAJ7GS`U*=<F[@*“±™ŸŸ¨¥¤¡«¤·²²¤¨°§¬¸Á½µ°£¹¬¨¨°ÃÉÉÌÁ·½Àµ·¿ºÈ¶Ãµ´³µ²½¹º½¶­¹¶¿­¢³¦««¯µ¸´ªº»¨²¿²º ¯´¶©¬ž­°¢œ¥¨©£žœ¤±¦° Ÿª©§¢ª›£¨ ­¼¨®°®¡«¢£®žž¬¦—Ÿ›¡£œŸ›š£©¢š™££•–“Ÿ¡–›–¦¬‹ž‘‘Œ‚‹€Ž{š”‰|‹†Œ‰…’˜‘‡”£Š’’‡š“ˆ|yl}vyxb{zrppsxj‚tjƒgdhaosŽmbjp`oA\xkU^NPQJILSZWM\^mWDW`O^PHMDF;7HEKO<rhJK9AE;;==;;=J49B<3;G<4?18-78;2(09/,5..=-*L>*49&'.34.0+/4&,:$40AhZ13S=e_DL6KVdO)=3Q\=#’˜«˜Ÿ—§¤¢Ÿ¨¤¸¯®¢¯¯©«¸Âº²­Ÿ¸¯«¨´ºÇÊÇ¿·Â¾°´¾·Ä¶Ã²¯º²³Àµ»¾¸©¹¸¾«¤µ§¨ª°­¹°©™¹¼£®¿´´¡®¸µ§¦§°³ Ÿ¤¦§¡¥™Ÿ­¨©ž ª¯§ ¦—£© °¸Ÿ¤±¯¡«¡¬¤›¦¦©šš›ž£•œœš©¦–šž§‘—’˜“™•¡ªš‰‡}‡~‚||¡Œ‰yƒŒ…ŠŒ…ˆ“šŽ‰•Ÿˆ‘•‚‹—}…{sp|qst`yxjopqpjsczlifdaf†€`[rjqLMiXZMPLJHPRQIM[_oTDXZRgOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23/:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%53=fd24M?e]FO=RZgH*?0\Z5(–œ¥˜œ–­ Ÿ¡¤¡·«°£´´©¨¹Å¶²® ·¬­¬°µÅÇÀ·¿Âº±µ½·¿»¿¯¬¾°´¿²½Ã¹©»»¸§¨µ¨§«°¬³°¦™¼¶¤«»µ®Ÿ±¸°©¥§¯²›¡¤ £¤¡–œ°¦¡Ÿ¢§¯¢ ¢“£¥¢·°¡¦±«Ÿ¬¢®˜œª¤¨ž—š¤“šœš¥©™œ›¤””—”œŽ“—¢©¡‰‹†z„}„ŠyŽ—Š‡z‚ˆ„ˆŒŽ…”™ŒŽ–™Š—~†—‹z€zpqvoot_xwemllji„nfrilfi]ds`[kuiZI}][XOOKHGRUF29]^mPDWVYeMHIEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<"8R=*113>D5,-'42*;+139dm84GAf[HTDU]hD.<2cV,2•¢¡—”›ª¤¡¢ ¸ª® º¸¦¬½Å³°¯£µ°­­¯´Ãü³¿º¸±³¹¸º¸º¯®À³´¹°¿Á¸¬½»µ¦¢³ª§©²«­±¡šÀµ¤§µµ¨ž²¼©¨¦©¯¬™£§œ£¦”˜¡²¥™Ÿ£¨©œ¢ “¤ ¤¸¨¤§®¦ž¥ ¨’Ÿ¨¢¡ ˜› ’š›– ¡ª››˜¡”‘”–™”’£¨¤‰Š†y„{„†}ŠŠ‡z„ˆˆˆ‘…•““Œ•”Ž”{ƒ—Ž‹w~{ltqllsaxthhjggp†ghidfij`jbjg[e{c`SsT\[SLJGIOS@!*h]jLCVU^`KIGEC.:B<F<6KPD8:D357==895?:;4>8@K=>93)8><:9*6@3.E4(+,?0-N?.+-7,1195,&.5-80576`tB3CDg[KWGU`hB379gO'2ž££‘Ž£§›ž£µ­¦ª¹·§¬ÃÁ¶°¬£µ®§®¯·À¿¼±Á¶±®²¶¶¸·¶­ª½´¯²±½¿¸®¼¼±¥Ÿ¶«¥¥´©ª®ŸÁ«¨¥°²©¬µ»ž©ª«±¥˜žª¦¤‘™§­¢˜ž¤©¡›¢— §¶¥¯ª¯¡¡¡” ¦Ÿ¡ ™›™œ’™”¥«¡—–”“•—‹˜š¨ ’ˆŠ‹ˆy…w‚‚‚œˆ‹‚‰|„ˆ†…‘„–•Ž‘‘‘Œ“{ƒ•…s}}fxokjlguskcgddv€beffejjdkqZ^Y]mdaNhWZ`VJGHKMRX>9_liHBTS\[IHFEA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A=-5B37=+*,0A*JK./*+3722(57$+7.72685]yN2>HiZLZJVbf@:3BhH%5›£Ÿ‹¬¡˜˜ –¥´±¡±½·¡±Æ¼º±±¤·¬«®©¹¼»º­¿±¯®®¶¯³¸³¨¬º±¯®´¶º¶¯¹¾­¦žµ«  °¤«¯¢À ±£®°®·®µž­¯¬­¢š§©¥ž•›¨¥Ÿ™¤¢©š ›”œž¬¯¥º¨®¢¡šš™ž£š¤—ž˜›”™ ’¨–ª§š“šš‘‹”™””™©§ŽŽŠ‰|‚s‹˜…‡|‰‰„…ŠŒŠ“„“œ’’‘–Ž€Œƒp€~fymhkjgqrk\hdcsafhjnlgkjhm\lktqaTbhdeZIFLMOXQQVaeT@VSYTFHFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24;6#3*)6.55465Z|]19Kj[M[KXdd@A1JfC'4’¡šŽ°š“¡š©²¯Ÿ¸¿¶ ´Â»½¹±¦¶°¨®¥·¸··¬º®­ª«·ª´¹®¦³µ²®©±·¶±³µº§©Ÿ¶©ž©¢©­š§¾˜­£®¯µµ­¬Ÿ±­¯©¢œœ£«¨›•œ§£š©¢¤–š œ‘œ¤«ª©»Ÿ§¤ ˜™™¡k¡–™œq‚•š£€u’©§ž””žˆ—™€–Š¡x†”Œƒnj~vƒql†‹†}„‹†o^cag„—†k‹”“uw‹„~ƒg†€huifW\hsnNPjdgr„g_dfnmj^`aŠ„…eNKD8FTg^JGPPTUKHSaoteFZQUPFHFC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,+08>G601.*.*/568,#1'214:176Yl16Ok[N\K[fb>G1Qd=+.Œ¤™†•°›œ“¡›ª­ª£½Ä¯©·Â¸½¼­§¶°¥«¤·³±³°¸­ª§¬´¦°µ£¨¸¶µ¨§¬·³®´­³¢ªŸ´«ž¡¤œ¦§˜«º•¦¥¯²·­®¤©®«¬¥¡Ÿœ §§›—¡¥¥››§§“ŸŸ˜ž¨ª£µ¯£££œ–———£ˆ¡Ž’š‡¡‡“ ¥¦ªž’‘š‘ˆ„rxŽ…ˆ¡v‰i—ˆf}rx¡pˆ‡„~|¡  ™€{‡žtˆŽv›Šl‡ƒmheczlqbT†mcli˜qYjqo‡X^i[kk[ˆqnzr†g†„Z^FM?G_MFRVVQQRWUg^MWIRSOEGG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82).1<I9/01.*/(-4583%&2115>1<8Xƒu25Rk[N\L\g_=K1Wa70(‹¦—ƒœ«™™Ÿªª§©¾Ã®²º¼·À¿ª¤·°©¬¦³´®®³¶«©¥±­¥µ´œ®¶¶´¥§©³±­²¨¯Ÿ«¡²© ££š¡£š­³”£¤¥¶¼§¬§«ª¬¨¥¡ ˜ ¦£™™¦£¤˜œ¤©–”£œ”“¤¥¦¡·££ ¤˜”“—“›ˆ®˜”‰©‹—¢›…±€£¬“™”y‚Ô¨€‡•Á›Çyx±¥·—d€Àœ¿y„„y„|‘Êq–¼œÅ{r¶¦»{€l–±«°xhkX±®nei¼’¼nhznrØ~Sjb¶²~r”tš¡ªWOWaOVNFT[XQPRŒ\W\P@\DQNEGI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22BE/.32.+/)-/186- /416A1=:Wƒw21Tk\O[M^g\>L1[]41!¦’¦©Ÿ—œž¥­²¨°Â½²µÀµ·¿Â«¦³¬¬©§¯³©¯¶³¨¨¦µ¦§¸¯œ³²¶ª¥¤¨±®®±¦ªž§¤±¤¡ ž—› ®«”¡Ÿ´º£ª©¢­®¥¢šš¡§Ÿ—›¨ Ÿ˜ž§§‘œ§›”¡¦¢ °¢ŸŸ£–•’˜’™…¯jjŠª~g„•†­dpœ“™¥”q®¡¤~x»}k¡v±_j´[¥€fœ‘`f‚zfjxk©d¾rg¦Œv±j|±xt’“cmm§n[„ Ehg‡–Euœ`~g|¤§‚Y_‹«i€•xyj§7J¯\WSmc[KNW_\WV;N‰OWW/ITSIDEF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3..53/+/(.0.:5/'$203B/=;U‚v2-Vj\OYL_gY:M5_Y31‘¡•ƒ¬§¥ž£¥ª²¸¬´½¾¯¶Ä²·ºÂ¦¨°«®©©°®£±º¯¤¥®³£©¹¨ž³²°£¥ ª­¯¬¯¦§Ÿ£¢°›¢›—•—››¬¥–›¡ž´³¢«œ¢­­ žš— ¢¨™ž¤Ÿœš¡§¤£š— Ÿªž¦¦ ›Ÿ¡••‘–‘š…µ›µx…©™µ™w‡³›·~“•–¨”~k¦{‚†ˆ’”’x«gk±[«{‡”tˆq†€ˆ—xƒ‚‹˜Œƒ „°vwŸqkkl|‹N¤XHcc™~ch¦`yruS’‡^P©mcq~‡€bœ.Q¢o[Skh`LK[dX\ZB>±xWXA#MhECDA@A19>88:84;:9<9:A:E::;6:CB8=?KNG:5:AFB@AD<FD;0201;F,0.940,.(/3,>831/2-D1<<S}n3+Xj\OXM_gX7J8aU50•Ÿ”ˆ³¦¦¡®©§³¬ª»¶Â°»Â­¸·Áª¬­®®¦®²©¡¯¼ª¡§´­¤«µ¤¦²³§£¡¨ª²¨°¨¥žŸŸ¯–Ÿ™”•–˜¬¢š™¤¨´¯¢©©¨ª›ž•˜ ¥§šŸœ¢Ÿ› £¥£•›ž˜š¢ª›¥™œ›¢ –“‘“’œƒÕ“™¹p°Â~Ɔ|֔›»|™•¤œ¤{Ž‡£‚¥‚z¬yV¯zˆ~Ÿj¹Z¹w†ƒ|¦‚“|˜zªy{±nŽ„t¼…o”P¯§ÅŠQ zc`©ctrˆm—ˆ`Sµ´È†€‰|c¤3Bv]PjidP@XgZdaJHMlK[ROYfYCD>E?0<<59;74<;8=:<C:F:;>6:@C;6@OLH<:<DHCBCD<EF81211DC./0483+-).323971#%5*>3==Qwj6*Yi[K]O_fT7G:aQ72%›¡“˜±¨¨¥³ª¥µ¨¤¼·Á°¹À±µ´»³µ§±°£°²¦Ÿ®¶¨›¨¹®£¯± ³´° ¤žŸ¨ª±©´©¤œžª—˜—–—•– ©š–¨­°©£ž¬¢¨–ž—œ¡¥¡˜¢¡¡¡š¢¢§›ž¡ž•™›¦ œ§•››Ÿ¡˜’”‘œˆ²nhµq«‡oŽ¦r´sr¶{™—£‹Žœ¢~‘¡¥~°vƒ‘ÒÑv\®{…¤o›ª¦k‡„|­}—™{±s’y³e–t„žožf”RȋZÂ\Ÿyb_­`vs‡b—ˆ^Yʝo¿uMKµSUÆdTQjdfXAOk_lhOUGI9=VR[XXIC?J<2?;5=<46>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>HI91746A>/.24252-).26,742&60;5:=Pqh9'Wi\BOT_eP5G=aM620¡œ‘¥°­¤ª¼­¦µ¥§¶»¼²º¿·¶´ºº³¥´³¡±±¢Ÿ¬¯¤˜¦º®¤±±œ´¸ªŸ¦¢ª¤²¨¬ª¤šœš¨ž•”˜˜’’¢§Ÿ–’¥«°¦¢–“­Ÿ¥’”¡›¤¦Ÿ”š¥¦¡š£Ÿ­š ž–›¡œ¥•–™¢Ÿ•˜–’š…¬{w¨v£Ž‰‡©o­Š‚§ƒ˜˜¡‰’šŠ¢“™‰®…‚³\r³R®}ƒ‚¤q×}x…}Žž†™šw¯†Š‘œˆx³ašeš‚”l’Z°XKšu˜yf`­_ww‡h˜ˆk^¯w•žxl5yÈ®²_BTo^g`EPm_pmVUM.eciSYQ;BDAL:5?91=<16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK97<46:>/04333.2..18*.32%!03767=Pke>&Vg\@>V_cN6GC`I988Ÿ” ¸°—´Á­¨³¨©²º·³¸¿¹·²µ¼µ¥·³Ÿ´¬ŸŸ¨«Ÿ•§¶«¨±±«­´¤›©  ¨¡¶§¦ª£™ž•¥¡”“›™’”¢¥š’¦¬¯¦ •™©Ÿ¢‘¢™¨¥ •š¥¨œ¤ž­¡ ”ž›¡˜™œ––¢ “˜¦†©}}¥x¡Žƒªp­‹§†•Ÿ¡ˆ——ˆ£‚‘ˆ”ª|€‹yo±Z¨‚‚ˆ ytØv‡s§Ž›’¤|–Ÿ„{²^œd ~ƒ•l’\«[Z“‘hgªdr{k˜‡s]¬Z‰ ŽkoeOJC¡\[Lt]bfM[a_rt_JV6J›“XHE=HFAM35A8.;>05A78@<6=<F?:<6?=B7.HVJEAH6KIN@IK@EN::@4.;>002144+*05/7,&21($$6671<PeeA&Uf[?2U_bL7FI_C1?8¡™™¿«—´Â®«­©¦´°·°µ¿¹¹²°·¼©º´Ÿ°¤ž¥§§ž“ª°©°©µ¬«¯¡˜¡ ¦¥¤º¢£« —›‘¢ •”žš”˜ž ‹¨¯¯¦–›¨¦ŸŒ’¤—¨«§”—©§žŸ £­¤¡ž¡•¡™Ÿ ’—œ•ž¡•–Ž«›®mr´r©ŒvŠ¦s´xs³€‘¤¢‘œ‰¤‡w¸oŒ{‹¢kk¶Z …e——i¡¢§m“r´t“˜²j…’ˆ­ku³af¢o‡’j—\­`M¡|‡‘Rs£mz~o˜‡q\¯V<œweTon.\§OcRkebmZc]`p{cTZQ>>mo3BB@?M9!7@6.;@37C58??3;<CDBJFMIF62JTKEBI6IJP?HNCFP=<E50;<010/75,+,426/#00,,289/9N`eD'UdY>/U^aL5FM^81C8¥š›º¡œ²À®­««§·©¸¯µÀµ¼°¯¹¸«Á¶©ª ›¦¤¡‘ªª¨¶£²¨¯ª —œ§ ¤«¸£­›–™¥£•¡›˜œŸ“”«µ°§™”œ¬ª—Œ“¥™¥­¢‘–ª±£ ž§«°˜¡£™¢—Ÿ›–œ—¡“œªœ”«™‡Ô’š»s°Ã€Ã†~Ֆ›¸x‡—Œ˜ŠŒ§ˆz£¶u}wv‚š²`ƒºyÀ|u¸bµŒ‡©}–¬©q{u¼ˆ§ ia¦Ž¯¡~Œt‡ª}¾ns¼t²ƒux‹nšˆqn¤t½^w}[ay¼kZV[jz^jafgbmwoY[YCA@r?CG+5H"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-6A9§šž¡¼¢—±Ã°­ªª¬±§¸¯¶Å±º±®»°®Á²¬¤¢ž£¡œ›‘©¤ª²¤µ¦­¤Ÿ–šª™¦¬¸£®˜•¡¥ ’Œœ£ž—š•’¯¹±¬•—£§§”‘–¤¤­ ¨«Ÿ›Ÿ©£³ž£¥Ž§¢•¢šœ—•£˜° ’”ªž…™µ€‘Œ·•x‚“šµwmknsny„Ž‰tžÁ»½š{²¨p€t‘¸ƒ|††Œ†{‹†—|¤»¹½œuz´£tv—ut°u™žf†i¶trpw¶Œ^€z}Šhƒynyc‹¬pu…Y[§jEdYSf`c]cQgfqmuBMPMD;ZM>J3<0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITBKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7LT_G'SbV8*O]]=+:VV'>;<§ž  ¿¥–´Ã´¬«§¬«©»®°Æ¯µ³®·§´¸­©¢¡¥ž ™”«¤­ª¦µ¨§Ÿ›– £ž¬¤¾§¡ª—”¢›‘¢¨¡“—“—”²µ·­˜£¤¢‹’‘¦œ¦«›–¨¤¥œš¡¨¦§£©¡‘­ž—¤ž———ž°¨”œ§¢Žj~iœ¦x‡s}štze‡z½¾Àºo’‚q•‡_rjZ^š‰acˆŽ•k`•cmwb•k€š•”e^`cq›ŠirŒ}†•gj~rtx}}b[wthP\n„}{‹kXl{‚sIJo†pNuMEW]f`L[Xgc_O[muiqRPDEN<HI=L?2,2A?8/5?C<9;@;=C>RVVWYZ[\\]`aaa`\UG5DFUEJOHFPIIH;8=51:.0;:.0-76=5&"/*2,%;8-7JR_I'S`V4)P^L(3=[O'?2>¨Ÿ¨¡Á£›´º¶£¬¥®§¨µ±¬È¬¯³«µ£¾±²§ ¢©¢›š™¬¦®¤¥µ©¥›˜•¡›§­©¾¨©¦•”œ• š’—¤©¨‘—œ°²¿¬›§§¢‰“‘©›©¤››« £™š£§¬£Ÿ«¢š°›•§ –•Ÿ—±¤˜¡¨™œ‘œ££™¦¢šœšš™–gm}qw’—”‘…Šµª†˜•ŠŒ˜—‡”•Š„’”‘‰Ž’”˜”˜—š ¢šœ”¡‚z¥†lj||€t‰Šq‚xyvv‹€{Škstƒudw}wkp{m`c]pgMYYfj`WZpznlfSOFS9OZMRO(+:KB635=@A9:C><ENSSTVWXYZ\]`bba_^^[TKCSGKNDGPLOI<:;389,2;820)6IRO8")+/2#4;*7FO[J&R^S10T^:+=8\K,<.@³ ³¢¿¡£±²· ©¥²§¥°µªÉ«¬±¥µ¦À¨´¡¤¥œ£•– ª¦¬££·«Ÿ™––Ÿ—­ª¦ÁŸ¬¤•’œ—ž˜“”¢Ÿž¢¦“‘™¨§²Ä¯š«œªŸ––©ž«œœ ¬˜¡›œ¢¤¯§¢¥¨ž®˜—§™š¡žžœ° œ¢¦•˜“˜“ ¡•£ž— Ž–“ŠŠŽ–­|•›‚’‚‹ª¨†˜–Š„Ÿˆ{„‡…™’ˆ†Š•›——ž£–š“‘~Žf¡³¯…Š„vzŠ|vyzofz‘€‰kuyˆrhszvƒˆ‚ktdyf`jecdfkYk{pij\SLPD_UE@??,4@F;45;>A;<?>>HNNOPSUVVXZ\_aca_^^]^]XVJKLBIOMRJ;<:786/2964.(&$-1./)+*7%+<(6CMMD/T]Q05M[17E4\G5<,@´ ¹¯¾¬«®²² ª¦±­¢¬³°Å°ª¬£³®¼¤´œŸ¥¢¡™—¨¥©¦¤¥³µž•”™™°¦®¾ ¬¢‘žš™“‘•¡œ—¨œ„ž©«¢³È³Ÿª£ª—–—š§¨›ž¤«“žŸ ©¯ª¦£«¢­›Ÿ ¡™¤žœž¯£˜ž¨“˜—œ‘¤™˜¨š—e‚’|e~™cylhkz‘¤«keš˜~g…Šeeih{Ž¡kh—‘£xkj‹˜£ž˜slnz„‡zXe^…‚^l‹Š€v\hsww’€‡‚nx‚x€smy„tw‰ˆŽƒ{i†Y^ktd]s‰ij|qlc^RNWJdXAJ4=F7?FD71<=?AD;;DGHHILNPRRTW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%/*+'6*$;'/AJ[J/7ZO6)EY/DO1YC;?.=¥Ÿº¼¹¯¬³°ª¥¨­­°§®­°½±©§¤­¯°Ÿ­—Ÿ£¡š™§«œ­£¥¨©²®ž•£¢¯¦·¹¥®£ŽŽš¡™’’› ™™¥•{¥¬¢¨´Ä¸¤¡§®Ÿž•ž£ž£œ£ª¨’ž¡ ª°ª«£ª ©›¦Ÿ¨¡¬–¡›¥°¤—œ«•¡ž›’¥—žª˜ž~½ƒ‡r´r„†­hx¹Ä¸q“¢£{¦˜™sª‚|ËÀÀ»q‹¢ˆ‚Ÿ}•˜‰žÀ½‚–ÂÁ{‚{’šÃÀ}j¥±oŒoÊz›w’ƒŽvz€yqz‡qx…“ymw”cf_xd`e‚c^tgmdbXLVIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^__`_^^^^___]\SMPGUNA??=6468276*&%#)*&.+*)109*#>I[L*#BP/#F[3PY/UAB;/8–£¸Ãµ°¯À©¨”£¯©°®­¦²µ¯©¥¦¦°« «˜š¢Ÿœ›ª§¢œ¬£¥¨¥¤´¤¢’¦®«¸³§¯¢‘‘š¥’‘ ¡—›Ÿ‡¦«¤«­ÀÀ° ©¯©—’Ÿ¢™¡£ª£“ ¡­®©¬¦££§¡¥¦ž­©’¤›©­©›ªœ¬¡–—¥–¡£—œΔxz¤y•–›_®^Ž§¢ |§•›t«ƒ€¯^cªz§‡… t—“ˆ³c‚«† Ž³j„®t}—‡¸aƒ­Y£Ínu{Ú{™p~ˆ’v~e{ˆvvk}ˆn~…‘’~m‚`qkpg`_yd\qhjcf`RTRW^KOC5AHED9>6;@?A;=8@>??BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5578164('$!',&&/(&+360$7;SL+,-J0';\;L-!P@F4.1­Â¿¿µ´°·—‘¤ª¨­³«¥²¬¬«¤«§¯ª §›™¤—œ¢¯Ÿ ž¨§£¥¡ž°¬›ž•§®­±ª¨¬ ”’›Ÿ¥“Ÿ¥—§£ž­¤ª°¨ÀƳ¨©±®–’œ¢—Ÿ©ªŸ”¡Ÿœ­¯§«©œ§¨¤¢«’­´—¦¢ª©£¦¥¡° ’š§š š””‘— q…Œ—t„¨‡q±|q¬~¡ž¥žwª‚}­œr­~«‡†Ÿv˜’z|—~ªˆ¢Œ‘Œ~«{‰”Ÿ€{­VœÄzo’Á}•mupŒmeve†oawnroŠ‹’ƒm‘‘eptup`gme`oiinfcWS]aYRSC9JI@D<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;91478452&# 1' 1' '45-&7=WJ-<'>1)3V@F!G:C1.+°ÔÆƲ´Ÿ£Ž££¡¬¯¶®©±§¨ª§­««§¢£™¢• ¦«Ÿ¡¥ ¨¨¢Ÿ°¬˜š–¨§¯¬¨§©ž—”š£¢‘”¡­›¦£¯¬£«´ªºÍ²­¦®¬–”œ¢™Ÿ®¬– ™Ÿ©²©ªª›¬«¤£¬›°±¢¨¬®¥˜¦ª©©±¢’–£¥š”’„¤j¤u‰z©tz²p‚¥‰™Œqˆ š‡¤``R«„®ƒ›v®¦††Ÿz™–†{f€£‰¤™…‚£}©~•‡®_|¨U¢’z¢Ÿ€{ïŌs¯³³¹qb©¯Âth˜mš“pnyxwolfeerpf|ib]W`iXXULMQLCCAB;C@@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799674,&$" ('"+-"$.!3-&@DWH,G+56*1PKL# A9D4,'ÃÉÖÕ¿¡™«§¡¯¢ž°´°¯©­¢§¦ª««©¤¦ ›¥Ÿœ¦§¦£œ¬š¢¬¡¤Ÿ¯¢š’ª¤µ°® ©›–”§¤š¢¨  ¥œ±¦£§±¬¶È²µª¬ª•‘œ¢™ ¥³š ”œŸ§¬«¤®š­ª£¢«¢³®¢ª³±¡š©¨®¯¶£“–£§˜›‘|ªlž„‡u«y|°o‚¤Š‰Ÿ–•Ÿ”Ò¸´¸É€²__”©ƒ¤ˆ‡ y˜•šxªÉt™£•§©“šŒ›ŠšÆÆxe¡‚¥sŸŽ‚}¯^pµc±uK£†m§G‚“dž’|p—“€q{u}{n[fjsqfj_aYdm\^YINMKEDAB>A<B?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75785/)(%&%$&),4ENPPMFKJVF*L0/>-5OTQ;<F2,$§¤ÁƸ­©²­¬¥¢œ²¹¬ª¡¦›¨¥ª«ª§ ¦¥˜ª£Ÿ®«¦ ¬šž©¥§¶Ÿ¢—“¨ª¶²¬›¦œ •¥¬‘™œ§£Ÿ©¦®¡£§©°´Â²³ª­¨“‰—¤š¡£¯¦—¡”˜œ¥¦«›°ž®¨¦Ÿ¬£·­¡²¹¯›®§²³³¤”—§£™ŸŽ‚NxšŸzƒ£}ƒ¤„‡§Ÿœž“„¸{|y¹‚~Ìƶx›¡‘‹Ÿ}š––Švž˜Š¤˜£¨~°……Ÿ„¬}š”a¥l£p…}—ƒr¬`¤sq€š`¼}RUuŽ’¤—|}“’‹uzs…q\moxrj‚oZd_hncd]KMQTBIHFI:9K>B108866877-*5==?BDGILNPTVXYZ[\__^]__\ZZZYUSOH@882.,*.+*'&?QTVWWWYXXWUOUF<E3:P[T6?H,- ‹‡™©«¤«¸«¯ ›¡¬³³¦Ÿ •¦®­®ª§¦¦›£§ ²®¢©¦² ™ª¤”£¶¢¢•—¢©´¸¤œ¢¢“¡±™žœ§¥¡¢¯®¤¨¡¶²Ã±­©­©‘‡œ§œ¢¤œ¥–˜™š¦¤©š¯¢®¥¦˜¯¥¼­¡··­žµ²¸°³¦˜¯¡£ž…ÑµÃ·y‡Ž…‘“¦x”¢wŒ ‘„¥Šqª†„´nrj™£›•ŠŸ|˜™†‡s¯‚¥›¢¦‹“‰•šmp²\¥s“zœl™{™}n©a£qqŸbs²¸hx”¦™~Œ“Œx}yŽ‚mixjysn€t]ddnmfg`J[YX<HG@U3@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^``][ZZXURRQF:2230/++(@QRTUTSTVWWXXWUVVTQOQ[U%!2AH$)%“sŠ­¿¿»ºµž–§¤­µ¡£™•£©§®ª«™¦¢Ÿ¦¡ µ§£©§°£”¬£Ž¤­£ššª´´¤¤œ¨‘”—®  ž¦£œ§œ´š¡ª£¶«Ã°©«©¡Œ„Žœ¡ ¦¢•šš›˜›™¦¤¦˜¬¨®£¥›­§¾¬”½°¬Ÿ¢°²¹«³§š¨±¤§˜z¨}|°wŠ¤¥ˆœm²o¡‡­|¡Žƒ¨•˜€¬ˆ…®…Ÿ”© ¡–†Ÿ€™•€{’~«€š–‹ªx ‰”’€y¯]£|¦§d€|—tk¯]¥kp…™]`[Œ m•’§™ƒ”—Œ{{ƒ—klc~um€z`geqnhghCZa[=KT3U8BBC7$$3+''3, /6674359@CFIKMNQSSSVZ]_a`aaa]][ZXSPONI8052.*,ATVVVTTUUUUTTUTSTVVWXVUUQHFIJ#((½’š„©Æ¶Á´Ÿš¬ ®¸¥£Ž›¤¢Ÿ°¯ªŸ¤Ÿ­™ž¸ £« ¯©š®¡«©¤–‰š®°¬§Ÿ§š¬—˜¬¢¡¥¡š¤œ­˜Ÿ¨¦¶©À¯¥©¤Ÿ‹€Ž›šŸ¦ž’•šš”šš¦¤¤š©¬¬¤¥ ª¨¿¥—쪢¡«²¹ª®§ ³®¨©˜v¯~‹œ…‡|º®Š˜e°Œe•­}¡ƒ¦•š¬Š„°…¥™¤¡¡‘… [lj³`­{{‚±lgo™—Œˆ±[}´[¤ƒkÈ¢eŸ€{»YvµZ²}R¯€z¬X€¡n˜¨›‹—‘——|y~ds~b„xt€|ajgqmfeeOUd\BU_>J(>9=4!",%2. *1/045799<ACFHJLNPPRTWZ^`_`ab^_\[XUPNJFC553./@UZXWXWXXWWXWVWWWWXWWXYZZ[\XWWGB;ҟ³²·½»´Á³£›¬¦¥¶¨ ‹š Ÿœ³³©Ÿ£Ÿµ˜ ³¨ª«ž¯­ž¬›•¯©¢Žˆ›Ž¯¬¨§¢§™®’™¨™¢¥Ÿ™£¢¥™Ÿ£ª²©½¯¥¨žŽ}‹›•  ™’š›‘š˜© ¡™¨®§¦¦£¥©»Ÿ Æ§¥©¡«´µ¬®¦ž»­¬¬•€©’£¯Ž›€‡¤—˜€¸ÃºƒŽœ“„§–œ‚¬Š‚¯ˆ¦››¥ª‘~սªb£¿½}~£‚ƒ×º¸µ…”“ƒž½¾„j£o«„mz²°Çƒj«°½¬xw¢¾¼t–Ž§œ›‘˜z‚‘›zc}{dgy‚{`kekjbPa[Sj\@UaCN*=:4/$%2 $(0496677;>ACFGJKMNNQTW]a\__a^`[\YTQMHC?<A?5=SYXXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ»•³´±¿¹±½²¢®¦¥²¦Œ˜¥¿ª¸±¨¡¿¦¦²œž±œ¹¨ž­¯¥§””°¬—Œƒ›‘®¦£¬¡¤œ©Ÿ˜‹£’¦ž§œš ¨¢˜ž ¬­ª¹®¨£›—’{‡™‘¦›“‘˜˜˜”©š ˜©©¡ª§¡¢«»ž©Å£ ¯£ª³´ª¯© º§®®šsuª¤·†e‰ pg­Šmox¤™Ÿu®™•p‹q•¨£›—®¤rmmmeŠxom‚™qzjqig‰–•˜qii„†gp†d]‰cjoY]g~w¦`bqŽ‘ofd€“¢˜˜™’—Ÿ}‡•vf‡xhŽkyydlcflbKdWJlY:QeER'K:+# #,)-2.5:457:<?ABDEHKLMOQSV]WZ\``a]][TPLHD=:AB7MXZZYYZYXXYXWWVWY]^^]\\\]^]^][[UW^©•­³©¹¹²³ª©¡®ž£²©˜’¾²ÃȾ¶ªžÀ«¬£ §¬Ÿº£¤­¬­¦—®©Œ…•–­ž¦«¡Ÿ££ ‘‹¤’§™¨™–£© –œ¦¦¨¯º¬¬š›“’{„–¥˜‘’˜”Ž˜•¨•Ÿ˜©£›±§ž£¬ºŸ°Á§¤³¦¬°±ª­«§¸£­·–Š ¨¥¶‰–¢˜‡©š”“ª³™›£« ±–¡¡Ÿ¢œ ¤¡•«§“’Œ‡’œœ”š“˜‘Ž•…¤™—•‹“’Š†„}gŠt‚vt‡Œq§m{”‘”’Ž”¡–™—¢ƒˆ•riwp‹xw|zjldcodU`X@i[HcaOZ+F=+'!740.!%2(*699469;>?ABDFJKKMPPQXUVY^`ac\^UQJED>9=@ASX[\YWXXXXXYXXZ[[\^__`^^^__```_YY`¥–©ª¥µ¶®®¢°¤­Ÿ µ±Ž¬Æ½Ä»¸ª¢¥ž›¦ž°¨£¶§©µ¦¨‘˜¬¢‹ˆ‰œ§–¬¥ ™§žž“•£–¨š¨™”¦¡£›¨™¡µ»¨«™š|”‹¡”Š•’•”—¥Ÿšª œ¶£ž¨¬·§®Á®£·§¯¯°¬©©²¸ ®¼™‘¥¤¦¶¢’¦Ÿ©Ÿ’Ÿ£¬¯›¡£°¨¯—£ œ£©žžœ–«’™¡›”–ª™™™––ž‘‰ •”…’Œ”Š€}f‹†u†vyˆƒsœj†””‰}Œ–’’—“¡“—¢„‰™‡zr–szŠr|jod^pja[_YncP`ePZ:GGE>2=>7/+&+)&&406658:==?AACIJGJKLMSSSUZ``i`eUPJACB:9EMV[^^[Z\[[[\]]__]^_`aabaaa`bbbdb\[c—•¤¨£°³¬®£©§­ §µª¥³»¯¬¬¢£šz¢±¤¥°©–›¸¦£“™ªœŽ†Š‰œ£®Ÿ£•§Ÿ ’–˜›®Šª–¨™§Œ™¨Ÿ¹¶¥¦™œ‰y‚“‹š“Š•’”’—¢žž©žŸ¸¤€„¯µ¢°¯u¤¾£² wy ª±»”u¬¤ž‰€ªd\bv Ž¤ž„—~n“³£§­ª£eŸ’sy™—p€˜¨—l¢¨Šeœ¥œ‘—˜–Œ’œ†š•ƒ’†Ž’‰„wjŽ‡v†q|†€€aiˆŠ”’‹Zv•‘hhŽrz¦š™ey™‡‚x˜jƒŠƒoy€kqe_vplkh\febbpS\>NNNSG>@TC:1/&4:316678<;>@ABFHBGFIKMTTUY]`hfgWQJ<DG;8UR[`ab`^`_`aa_\]___aabcdabaaedchd^]f›•¦£¡¯±¬«©¥©®£§­¥’–«¶°²¦šª§«—sŒ°Ÿ¨«§“—¹  œ¤‘ˆˆ›ž«š¢”§¡žŽ—‘ž…u®ˆ¦š¨‘—¤‰œº´¨ ™˜‹‰uw“–“Š”‘”Œ“ Ž› §™œ²–€Œœµ³Œ’¼§ ~§¢z¢®·ŽŽ¦žƒ‹†±©¯ŒŠ–£šy‹¬†œ¢§©§‡•…˜w¥›z‡›—¦‚‚{œ±zŠ… —™”˜•‚‘—–„š™cy‡„Ž‘Šƒmp‡y€q€…†t†„•’x–h’t št}™„¡ž‡˜“Šƒƒ™kŽ…lx{qqgdxojlj[ekjft\_ITLQ@E5.YUU7)!09=>643568;:=>>@DI@JEJKGSXZY[a`hfYQH9EL;>bV^bded`aa`bb_]`aabbbcfgcba`edcgcaahœ—£Ÿ¦®®«¨¬ ¨±¦§ª¥™”®È¾°¡–¦©µž„¬œ§¢ ¾žšŸš }†™—ˆ¬œ¡–Ÿ ‘“ˆ†€‘¨‡¢œ£“—ž†Ÿº²§ž›’Ž…pu‰•Š”›‹’Ÿ’— ¤–ž¬ˆŸ´‰´š­ŠÊ‡ª®ˆ·…Œ¯‚°®ƒ©¥˜|¨r{wœ§–h•¤y´‹Ÿž¦¨’˜Â«ˆ˜¡qž€™¤}—…•±€¡|¡” ˜–€Ž“›Š˜‘‹|…’†”’‰ƒms…zr†„|„u„—€Åf©‡£kžƒ¢›„šŽ…Š™qŽ“…hwt|whhuqghk^dpmgmXhG]RM2E46Nac7&3<DGD964658;8>==>BL?NIJLCPZ]\Wa]jl\QE=KM@JdY]cfhgbbbbcc`_babccceiicbbbecafcbbi”—¢Ÿ°¨©¨¥« ¤¹±ª«¦š” £¤ª£–¥ª·£¯€¡§œ¥ž‰”½š“¡‘y„––‘ˆ«™››™¡…Œv›œŸˆž¤›•™˜‡£¹®¤™œŒŒ~bm‹“Œ˜‹’Ÿ” ¡™¡¨~¡§‡­ –­žœ‘…€ ª®†£©™Œš~¢u€™”k‚¬uM«x‡‘›¨§€©«}ƒ¡{z§iž’kg—†—¶‰ž}n`dYƒ–Œ{dh‹r™}y•l]{–m_Spƒ\_kyƒ`Ye‚}ƒ€—p§ªkƒ£nr¥pŸ„Ÿif m[nŠ|fZ`ƒbWPowfmtrkjo^jpmljXiO]XF9A4GD_k4,ICQMN=84859;6@;;=AO>QRLMBJ\]_W^^bv`MD:MOMTb\\ffiibbdbddbab`cdcacikdbddgdbgeach—– ¹¡ª£¦¬‘¡¶¼¬®£™— ¢¥¬­¡®µ£¨’¡  ¦›™˜´™‹ŸŒ•Œu”’ŒŠ¦–•˜žž’……¬¤‡›Š˜©˜™š’ˆ¦±§¢•šˆ‰€inˆˆ‹ŽŽŠ‹’‹’¢Œ”ž œ¢¥“£¡” wœ–§ƒ¡§†©¬„¥xŠ|„š}¢ps”ˆ–{žŒym‡œŒ™›¨š‡{‚¢sv¦fž~v¤_˜z}’s¢n˜·´ºt’‡‚µ¨dÆ¸{p•·‹q€š¤cs¬«`}j³~n|†‚Ž‚‹˜q£lr£sž„€¤`™³–q|—Ÿ´ts[ž²ƒjbotvrhoXklssf]i^bKE=D5QAZr2=SG_JR=<395::6D;;@IQ?UMNQ@E_^[YX``|dHC8LWUVbaZffkkbbeadc`ab`dd_`cknccddhdbgfchh”–•£¸™«œ“ ¤·µ®­ ›¢œ££¦­œ›±­¬“—¡™¡¤™š”ž«›‹‰’x‹†p€–‰¡’”—}‰Ž¨ ‡˜ŽŠ‘£“œ›Œ©¨¥ž–‡„~k{‡}ƒ‹‰” ƒ—ž  Ÿ‹‰wœ˜¢ŒŸr¡‹‡¨ˆ›¥–§ª~­Œ~z ™z£“xt–ˆœ}– ‡›Ž™›¦†¢d¡|ˆ–›lžh›nš™{€Š§}rht«ƒƒtªh•š]›…v„hªj€¸f\¨pœa•Œ^§vvˆ‰žhšu†“’—ŽŸnšm§š]©~x»k~ª[Ž„]´g\nryxki\qjyyc`fXbAQEO7VCRn4KZZ_NZD@151;;7H?:CHU?YRY]>Db^V`Qac}iEB9N[]XdfXfgnmbbe_ba__``ec^bdoq_deekecihgki•œ‰ªµ›§‰c”›«º²°¬¦œœ¨Ÿž®›ž°¨¬—¤š¡Ÿ˜–– £™†‰jˆ€r{—ˆ‹––„‘”˜zŠ„–£Š”†‹ž’œ‰©£ šŒ‘Š€€i€†y—Œ{ˆŽŽˆ–š“¢Ÿ ¡“˜rhŸŠŸŒp’Œ©‡˜ž¢§Ÿ§|¯­£¢¸—w£³¢¤€ˆ”y{«š¢Ž›—ˆ—q¡|…¯µ}kš‘¡x~˜´££«¨„™|›}™~tªZ]o{–‹xžbL~zz…cy—BLžY¢jq|Žm‰„™u›x†‰±³›“§v‚ns}”o™sk¤]•vHec`sq~nf`liv{debR^W]UW@YFQgDSW[bX^ID=B8?A:IE8LEWAVQ[VDFb\Z`K`m~qEC<U_bZejVghmobfg^aa\]^ahb_ecvl^egfkdflihki“±­™„T^ ¦³¹³³©š¢Œœ«œœ©”¡«¤¢¨Ÿžš™•˜ –ˆ‡‰w…ny•…›‹|‘“–ˆrˆ’¡›s‘‰™• ›…Ž©œš•‹‹Š|„l„…q‚¡Œx…ˆˆ’˜•|“£¡ž¢ˆ®†}µ„Žžœ{¥–z©•œŠ œ|§hwm~™t¡sq|ž†™p“ƒ®}¤ƒ¦žš€£o^¨gu£co¥aœÓ|{™xrsc¢…~£s£uk³Œ`‚˜‰sª²¨¼wƒm~¾¦©´^œn}q—n€s¢r]¤gs¦ah¦m›Ô™}…›pyz—k›{x—sn©¤g`eyp€„kgfdnvwg`cS[fQQbIWIT`WS[ej\eQFCKMJKBJE8P@QNWRYOSQ`feiScwywIFEc^eZhiTihjocjg`c`\]]_hbahe|d^dgdkdjmghlh—›±«T\K~©¯±´°³£›™…™¨  ¤Ž¤¨ ˜©Š™˜˜“™“’ ˜Žˆ†{p}„h}ƒ”šw‘Ž‰o†“’l—“|ˆ‘’¤–ƒŽªš”’‹…‰yƒwˆ€n‚Ÿ‡w€“†ˆ™¢—{”¢¤šŸ‰³¡¢¶‹z¬§¤®¥p¨€š…€›‘{¤€¡™†˜rž„£®¯Š—Œ€Œ¤–ƒ®¡”vµµµÉ¡s”ŠŸ`—©my•† ›u¡‡w ~’—Š€oLf£’p›‡r¤{ytaƒ‚k~ kqd`œr~t—izi³µ´Æ¦s˜~zkœ›«u„›muw˜išzu˜rPE}´^jvkyˆfjhbtupnV^TYiPShIULYSU]hknVgWMKAJMKHJNAQKPecimeussy|nu‰{{TPNl^h[kiRjhilglfce_\]\^ibdik{_]dhcjfomeile¡œˆ¯¦„f?”¡³«¯¯¶¢¢€—©¢¢¥Œ¥§¦‚š—–—œ“Žˆƒyjy†eƒŒ— yu‰Œi„…’ƒŒ…zŒŠ•¦“ƒ—©˜Œ‘‹‰z€}‹yp¡†y•‡‰– –”¥¨œ––„fnxœl¢d|q¥w›˜pg¦€–‹{¤zŸ–ƒ—ržvŠ”–¹nŠ¢b}™¡•ˆmri«ju mn¦_ši‹h–‡š•u¢€}š`Œ†Œtoˆbh ež~išuocfˆ‚mr¢Z_[c¡m]‰Œo{~srd¥mw¢dg§h™sŒ™o¢oS‰o _e¨T‹^T˜nmskr‚mpikyskoRYWWfZSmIXO]IXihsjYkVQREV\LXRaUhj_wtz}p||rƒ{sv€„v^QrbgbpgPjhhklnhdg_]^]`kcjivu]\cicjjslfkmcœ¤˜¦zetm‹§®¤©°±¦Ÿ‹€—«Ÿ¥Œ¢¡š¢¢€–˜“š‹˜ŽŠ{†q€ˆh‹‹|˜›st‰}{d‚‡•Š‰•™‚|ˆ†–¨¢¬‘†Š‚Š~€€Žsh¥„}†”‰˜ Žˆ“ª§‰¦x–›¤ˆ–Œ²˜ž‚¯—Ÿ¥w”‡y©t¤Ž„šn¤¢Œ’„Œƒ»n}¥¯‚†††“–œŸ|¥zq¨• –fž~o«c–Š•’w¨l©¢‰u‡‚w«‘¦‡j‘°kv³Œ©kŠ†mmŸž’•a«‹ªvŒ¥žvŸ}„¤• j›ˆw¬gŸ­¶tw¾¤“Yƒ¦«aurtp|tqcj~nhlSV[Vab]kM]R]I]mmv`[qY\`Zgtenoqcqt`xz~yryƒs„~€{{Œ‚€vbxdcmsdRkgholrjfia_^\bkbml{o\\bibljwmglnb•¥ª€ž¤–©ª¨§®¤™‰ƒ˜«šž¤‰š¥©…ŒšŽ†œ‘…’Œt†zˆ„o„~˜“tt†r’ƒm‹’‡†“|{…˜¦Ž¥¦ŽŽ‰…•v‚‡’ol‹©ƒ‹”Ž‰œŸ‰”«£ €u”–ˆ~y”®£›q…xŠƒ~{r¦Œq}}z—–›„Žx{~~‡”•“Šv˜Ÿ ƒz}‰kŒ…[yxrzphn~’‰qt‚”“q…ƒ‚eŒ^‹wus”uoynn‡m„…^vhxŽe€…Ž©›}t|–j‰ˆo€v}†vmmgŒsy{˜x…[kXyinwrqoxxp]l†njgVZ`W]ekcVaU_Q_pxylkvejkjv|qrtsaoubt{xuzƒv€€€x‹…ƒ}{mldxn^Wnghukxjijd\`ZcjelqunZ[bkdllymhloaŽ”¸¨¦‹¡¢š¦¤™¥œ«¢¡„„˜¬’ž¡‰š¦›©˜ƒ›Š~–“‡ŽŠ‰rƒ|}~…{—Žsr„p•…{}’‹††…x~†™¤Ž|§¡‹†…–ƒ†Ž˜wr…©†Ž’ˆžžˆŒ›¨Ÿ ªƒ‰”š~~‰–­¨’¦wo‘‚y‘o}¨…p}•qkp}ŸŒ“ŽŒhm]ƒ‹Œœ›žŽs•‹ˆqtkvtYrn‡‘}~Œj]jdz…ƒˆ€_ixz›{‚‹‚u†‚gwŠ†kapr‚v_r‹‰¦•…fŒƒnw‹„q†zpfgd{ƒz–[\jgnv[{ywunss‚f\mŠklcYY^[Ylq\_aZ^]ft~{uotckkj{}r{xtdmthm|~vz||zz€€~o†Š„{}s~ysiT\qiluougkhd]aXkhlkqrmW[emlgsyohjm`‹‹©°¡£¡šžž˜ž™¨£¢~ƒ˜­Ÿ•ˆ›¢‘¥•{˜„|’™‰ˆ†‡Šs}€‹v…‹„–Šqo€r˜†„~“„ƒ†Šz€ƒ‹› ‚§¢ˆxŽ˜‰•‹‹—…ƒz­‚‘˜™”Šž‡ˆ¡«Ÿ¢¢£‹‡“›œ£™–ª¡§¦ ’›‡•{wŽ„§~’‘’“œ²¦›•ž²“˜„¥ŒŒ•›Ÿ‰›‚ˆ‘Šk|wxe‚†Š|‰„‡‹ˆˆ€…„w|ytš¡ˆ†‰žŠ„”~}‹ups…ƒw‡‡Š¦‘„…‡ƒŒ}ˆ‹‰‚wl‚„}z™jrhatŠp}zwvovt]^o‡ho`^Z\]ShrUc\\alhu||sopdkji|nyqipplf€{r‚€x}…{m‚Œ†|zx|}zƒyNdvjrmpzdkebb`[tfpfrqmU]ltmiyzqgikeŒ‡¹ž—¢¡˜•™˜”™¤¡ž|š«Žž† œ‹ž–}y”ƒ{Ž™‰†„„†nx€€r‡~‰”„mk~z—‡„ƒ€†„†}†ƒŽ›’‡«ŸƒrŠ†“‘Œ‘}zª„’˜–œ—‡†›¦Ÿ¢š†ƒ‘š™™š¦ ¥–€Šv{‡Ž„¥{|Ž‘†˜ª¡“ªŽ‘€žŒ‰“šž‚Ž—~†Žƒow…qua~‚†u‹˜€ƒ‚†…~…ƒ”mxut’¢ŠŒ…™…„t€‰|}rr{‡„{x‹Ž„’¦†ƒ„ŠŠŠw†ˆŠŒ|ok~|nhlmg^zh}{vtvu{w\`p}nu`c[]^QgnTe[^akivz~qlldkjh€€lslltoyo…ym‡€v‚€~…vq‚ˆ~{{|{‚Š`i{juhi‚ejc`i\duhobtmlUcqyepzzrejmm‹‰ž·š¡¤Ÿ’‘–—‹šŸŸž{xž§‘œŠ‡¥”‹˜™yzŒ…|‰‘ƒŒ‚‚‚n|xs…}‹‘}kh}‚˜‰ˆŽ|~†„‡}››‘ˆ§p‹‹Œ“‡¡¡Š…|¨‘ˆ’—“–“xŒ£ ¡–šš˜’Œš£¡£š—‘›~…x€ƒŽ‡ }Œ|˜¤ ¡“™¦›‘‰“—›}’’~‡Žts‚pv`}†rŠ•|ˆŒqŒ‚…†ŽhwqxŒ˜‘–~‡Šr†||qy{‹„zz‘Œƒ–¥“‹†|††‡…v‚„‰ˆzer|xzqljf^~sh|uvt|s€j^`tvpxdcY_^RkhTeY_ahjvxqfkdlhf€kn~hoqk~x†zkŒs~tv‚†~|z}jrƒnsib‡hlb_qVtomn`xhmWjtvcu{zrbkoy‰ž²‘¤¥Ž˜†¡›|v¥¡Ž˜€Œ¢Šˆš–x{†‡~ƒ‰‰‚q{tv‚…~Š‘xgc}†—Š‚Šx}€Œƒy–•˜–– ›~oŒ‚‘”†¦›‡‰„¦•…“‹–—“’w‘¡¡—”—z~Ž˜—Ž–š¤˜’”›y…‚w„–~‰Œs—£ž¡“™Ž¢ŒŒƒ—˜ƒ’–™~˜|ˆvq}nzd€|Š…p†’‚l‡‚€‰„euo{‡’—Œ|“x‹‰{†|{q~w‰…y„Š‹—¢•‚„Œwˆ„ƒ‚w|‚Š†v`xx}t~xgldaijwstu}q|bcasnusmaZa^[leRcX`aikvy†qbjcmei}ƒlhuhloi€}ym†q€ƒƒt|ƒŒ€~z‚ƒ~|mv‰ttmeŠljbcuV„iqn`xglbjvpfy{yq_rl†…œ®—¦¨ž—‡†Ÿ“—™}xªŠ™z—‹Œ˜y{‹}|ƒ{€ƒxtyzs}€„‰‹€d^}‹•‡…‡u}~Š}˜„—”—Œ¤¡˜r‡{”’Š§ŒŽŠ“ ’ƒ’”—‘‹˜ š’‘s’”‰ž¦——•–sŽŠk…—™z‡ˆ‰o—š£“•ŠŸŒ‡‚’œ“’•†™ˆ|Š‰zqykul{}‹~m…’‚”wp‚ƒ}~Šdri{€–—„~sˆƒx‡~vx€}†€|ƒ„Œ”¤y„‚t‰‡}€tv‰„na{uzq}oaocd{bnovsxwstau_oluno\[_^^k^P]Xcahmt{ˆk_jfjciwˆnflhjlh}{woˆsƒ„}t†‰zƒ}z„}}Žrz‹xxnl‡kh_irb‡hrofvgnlayik}{xpaxm‹€™™ª £¨žŠ‹’†Šž‹•˜}w®™—}Ÿ”‘–”ˆw~{Š|{€vw€ptt{o…}€Š~|a\~’†€„„sz€†z’ˆ’‘œ“¥œ•‚~}Ž‹’¤‰ŽŠ˜š†‘˜“–ŠˆŒ’œ“Œnƒ‘‰ž™¢¡—–‰–‘nˆ™„f…˜Ž”z‰…‹p•š”¢’’‰‹šŒ‚‘ž}’’‹™Ž{Š„‡srukqnt{‹tn…’qt€{ˆ|dplx}™“}„ˆtŠ€sˆyo€}€†|…Œ‰„Œ•¨Œ{ˆ|~‹…x~qp†„chytup|b^p`kt^pj{yxlspex]mlsmsXZ^_bkZPWXecgqq‡f]ihgbgqŽndigdihzwuoŽ…t‚ƒ{uƒ‰…w…|x„…z€Šw‹{{rxƒjk_pht€kromqgole|cn€yvqlwwŠ~¢—¡¨ ¦›‡Œ‹œ‡“œuª•“Ž‡¡–“€t{v…xyrs{…krpzmŠv€‡nq[Y~’ˆ€€€vu€€€ †‹’˜¡”˜xŠ‰œžŠ†’˜–…‰•™–‹‹ŠŽƒm‰‹‘‰œ–¡œ˜•…—ˆi„£‚f…Š‘~‹ƒ‹w“˜‘ž‘‰‰•Ž~˜|‘š’|Š€‚nuplmop{…isƒŽ˜Špwt‚ˆ‚xfrou™Ž|ˆ„z”‘yvˆtp‰{…Œz‹†ƒ‰Ž›£ˆ|„v‚‹xxol„‚^rsrqpxZ^p`pj^oj}zpmmjlv`pojrmZXaabnXQTZfgcup„‚b]kmdbfk“n`ff_gkursp‹€uƒ€xu€‹€x…w‡†wƒ…|†Œ{vŠjqc|c†|oqmtjholvx_qy{tut€‚~¤•š­ž¦–…Œ„—”ƒŸu‹ ”“†‹›Œ•‹zrxt‚pr…tquˆkomumˆvƒ~€mnUQ«•‡‚x€ws‚z‚ ‚’‚““˜œ’šx’{ƒ“¤š“Ž‰•™’„‡—™Œ”‹‰ˆž„Š|s‹…‰ŽˆœšŸš–”€“h…œ‡g… ‡’ƒ‘ƒ‰qƒ‘—›ŽŒŒx{’zŽ‹Œ‘–Œ|ˆ|€kvjnkklzaz~Ž–‚vz€xƒŒ|ygslt‡•‹~ˆ†{“qz„pvŒz‰Œz‰}‚Œž…||w‚Œ}wqjl‚ƒz`xomlrtV^obr`_lnyphoffsthpkawe]Vf``rSQN\fe]ypˆ|_\hrbbef’j_hd[gp~pkptŠ}v|…€tuŒy{†xˆƒs†…~ŒŒ„{y•xfrjƒ`ˆ~ook{`jntu_t}x†xts…|x ™°œ¥‚Šƒšˆ€ŒŸ‹š“Ž…ˆ—ŽŽ„vtws€po…tpqƒpjivnƒn}|musRM‚ßȒ֓|puƒvƒŸ‚“w”‘™œ™{”s…Ÿ¡““Š“›”†~––ˆˆ‘ŒˆœŽ€wzŒ~ˆ‹Šœœ›•“zvg‰’‡lˆ£„’‡—ƒ†cŒ‘™Ž•Š—ŒŠ‹q{”ˆ{ŽˆŠ“‘Šz…|~l{erojkyy\€yŽz}~†ŽzzhsjsŠŽ‰……}•‹k~n€‹~‹‡|„z‚•ššŠ|vxƒysmgq€„mjtohjtnS^odpY_krxfkjbfxropc_w``Vk_^wPNKagc]zq‰t\\ev`aeed`ebXissnkqvŒ}ty†uv~‹s€†{‰~r‰‡‘Šˆ|~˜vesn|e‡~opkZlnyysavz{vswŠwyŸ‹›¯› ‚…wˆ•~}Š‡…Ÿ‘Ž…Œ—„“Ž‡twpyqn„omn~rddxq}my}jhlc¤šÁÜ®ï¡slu„v„¢…’o–• •œ’q†‹£—‰Ž•Š–ƒ€•…‰€‘Š‰–~‡zu‰x†„œ›˜™ŽvŠvn†‰‹}Š£„‘‰……^‹“—Š‰Ž‹‹„Šm|–}ˆ…‰‘†v…}}k}dxuinxsXˆz’††y~€€…‹~xfsj‰Ž‰‚‚€Œ–…kvnˆ‚„~z•“™tsxˆusqguzƒbtmpbjvgR`qglU_ntyarc_h}prn[cr`bWnZ\xNMLdga^vs‰m\\dy^`df…`cb^YjrknkrwŒ~tw„xw{‰qƒ„}~ˆ{t‹‰ˆ–‡Œ~~˜shuqyl‹zntqWqzvyqewy†Œiw€‰rœ‡™§œ£’„}pŒ”xy‹„…¡{–™ˆ„{rwpsjokim|t^`xw{qu{gae|ëÚµÉÃ܈sltwŠšˆi˜–“‰q…‰ „‹•ŠŒ˜”|“ˆƒ‰{‹…‚vxƒ„r‡‚“›–”˜†Œu‡p„‚‰‡˜¡ƒ”ŒŸƒ‰aƒ”‡Š†Š‡‡i}”}ƒ„‰ŽŽ‚q†~qwhvriswlZŒ|’‚†}ƒ€„‰‚uaskˆŠ~’}m‚lx††’ƒ|€}€‘“–ˆoqzŒ†ulqlry`tin]kv`RerifS_pvt`o`]h‚prjWghbiXmV\uMKLeg^brs…i[\ey^^dg{`d_\YknfoisxŠ~ss~zvzˆs…ƒ}€‡vwŠ†Ž˜Œ{“vlwuyx“tnx{}Yz†q€ogxw’‚dv†…qŠ•…™¡š¢Š‡to“‹rwŽœ}Šš‰‰|Ÿƒ™xqsnodr~iflwx[^y{{qq€jagaÕ¶Ž§xoqw|q’Œ‡j™Ž‰œ’Œ†{iˆ‹š‡’‘†‡˜|‰{~‰…zt{‚zp†€–™Ž“”‚‰uƒ†vƒŠ“œŸ†•Ÿ~ˆa€“‡…ˆ„ŠŽ€ƒg}‘€~‚Œ~m‚|‚tkmvtsvukb…~|„~ƒ‡~o_rp…{ŽŒ|~‘ˆzpƒfyƒŠ†‹ƒ|„~€”’„nozŒ~unokl{~chkjYnvZRirjbQbrxlbe]Zjƒmsa[g_dl_nT[pNHOge\gnq€l[[cs`\clwde]]Zllbmjtw†qo||tx†x…‚}€‡uy‰’–|ˆ†v‰pwy{ƒ“om|w^ƒtmizt”sgs‡|r‘‘ƒšŸ› †ˆvv•~mv”—~ˆƒŠš|‹šv}vqoljau|gbiuzZ_x|zmqedhgW^qs—¼Å„vq”‰~r—Œ†“Œˆtk‰–{”‹„›Œ|‹†}|‰Œ”ˆu‰…vv}qu†ž”†•ƒƒqˆtƒ{‰˜œ—†“Ž€ˆe}“‚€†„‰‰r}g}‹{y‡Œ}i€}ƒvfoxxsvslj…ŠŠx‚€ƒ‚j^qxz}Œ‰…{€~rix‚‡‹…„yƒ|˜ŒŒ}nl{‰}wtoih}we]qcXosSSnsiaNftxf`]\Xn€nsYeb]jm`pOYlRDThaZknm{oZ[^mcZbowcf\]`kjclisvƒqn~{tuƒzƒ‚|…v~‰–‘xƒŠtˆryy~oo|qiyz~mm|v•kjx„tl“…Ÿ˜ ™…ˆn}Œvjx˜‚Š‚•—Šy–ozspljd`szi`er{Z`r|ygpzaeeŽ±²wJbZ¤ÚЗr{‘‹x~•‹…™‘†ol†’’zy’†„˜Š|‡xx‰Š„–€oŠ‡qt~ziy…ƒ¥‘„“ƒo~ƒvƒx…›˜“Š’”…‡p{’ƒ}ƒƒ‰ƒoxh€…xrƒ‹‡|e}~ƒvcps€hxpot˜Œ…‚Š{vxƒyj\p}r€‡…ˆ}†‰zˆrnqƒ†Ž„„s„x€™Œ„xnn~„w{ehj}r`YwZYqnNXrsg`Jlvta][[Yt}roWg]fjp_oNWiR?Yf_Zpkgyq[[XkeYcpy_h\^elhfliqw‡ol}€upz€‚v…‰—Šq‚q{†|zy„“Œtjzko~t}or|{”on€xg’Š‚¡™œ’‚†g‡„phz–‰~…‚™Š|Œixrklf_aoxm_boy\dlƒzaqv_eeÔ꾊2:>‹Ž€ry…ˆŽvƒ—~“Žnl…Œv}…‚•‰|ƒxnv†„ƒ—wnˆ„ku{tfy‚ƒ§ŒƒŒ„}ntvƒy…›‹‘’Œ‹†~{’‡x€„ƒl€ri~xm|{Š„xay„qdqh~mtqu›‹€…~sv}€r€o[l~tx‰‚Š{†|ˆxzqlˆƒƒŠry–‹Š~tmkv€€uv]iixqYW|SZqeL[rre[Jpwo\[ZY]t~thYb[genciMWfQ=^f\]ve_tp[YUodYepyZh^_gmgjlipx}Žli‚„yn€{}‚zu‚Œ“…p€‹nw~€{{ˆ“‰h{~jt{r†{sw}Œyx„~|kŒŒƒ›–Œ€lŽ~kiŽ{~ƒ”‚}Šˆkuqghc[bgro_alsahp‰zast^cd› n\5Y¯µuj€‰}’†v†—†t‹Šwpm…ƒ‡uyŠx‰}“ˆzsgvˆ~~˜op†}hvymeyˆ…¥‡‡Š~n~u€|‹™‡‚“˜ˆ‹„‰|‰q{}…|i~mk€{zjzv‚‡€r`w~qdrgu‚mu{…”‘|owy|t~lWo~vs‹†w‡u‰zxrn‰€€…r~}~’ˆ‰znnim‚‚un]hftrR[{N\q\O\rpcVKsxjWYYZaq€t`]]`gdhifNZhNAad[`va\tmXXStaZdnrWj^ahkgmlipw|’kh„‰|}p~~{‚zw€€‰‹„r{‡oqwƒ{Šƒj~{nwyvŠw}x€‚‡ƒ~zm„Œˆ˜£„ƒ{vŒzkm„‰‘y}{‚‘€€~Šƒprpcf^Yg_pp``gpfjoŠuato[adjv{¾œ¦£È¸q…„s”}x†”‚tˆrrp„{ƒtu‡tˆw”ˆyyqcw†z€“ir„ufwvcj|ƒˆž‚€}rs„x‘‚x–”‡‚ˆ{‰‰lxy~uhzikysizv€ƒ}h`w‡}jkth{iv‹”~z~~p{v{s~bUv|rr‰ƒ‚|‚p†‰wxppƒ‚Œ~}y~|uŽ…‚uiqilˆ‚rp^hcsnKeuL^oUTYsnbPOsxaRWX\ap‚s[a\hedcjdP[qIDda\dq^]whUWVw^\enhVk^ajgeooipw{“niˆŒy~s{~x‚‚|v}ƒˆ†ƒpvƒrnw‚ƒ~‰‹“p€|xyzŒtƒx‚„y€vo~‰‹šžˆ}…zw‡|ht†‘z|‰†„v€gom_d\XeYmra`aqlkh‰n`siY^dm€w©Ú©Ç†‡²q‰xpu{‡€z“Š€utu~w€pqm…t”†xul`z‚yˆŽfqƒogun[m}“€y’“}x{m‡u€‹ƒs–Š‘Ž‡……{€…muvnhwem{vmjvv|abx†zhtuc}zgu†ŽŒ•{t€uq€z|lYVs}otƒ†~xkˆ†syktƒƒ}z}x{r‹€|rgtem‹ƒmt[k_ueHnnL[bWWVxmbOStvXPUX^aq„o\`cmdc]nbT]rGCf_]fh]ZzcRV\u[[gkaVj_`nffkqhpvxŽtkŽŒuvx~wƒ{t~ƒˆˆƒoqtqu~†‚‰Š{wx„||…‡x‡|}~…€{~svyŒŽŸ‰zŠvuƒy^~†šŒy‡ƒt…†…w‰zbnl[b[[aVjsc`[gnog‡raqfW]ck|Ê·¹¢jmmŠlq„q|„Š~{’…zytyuu{jmuc„v’‚wpg^}‚y‹‰eqkjqcXl{†œ‰ƒ‚s—”w~{n‡q‰‹‡q–Žˆ…‹ƒ{y~qqo}ghrbnxqjlqx}|z]ey€wiuxf‚vgt‡‹”|r‡io~€xm|]Xq~msŠ{nn‰qvgwv|qzt†|yrfsan‹‚lsXk_w\IokNWV^TU{kaOTurQQTV^bt…h\`kjfbYnaXbpGAh]`f^]U{^OVdpY[jh]Wg`_rfkgrgpsw†xn•Štzx~y‚‡€us€†…Ž‚pp{wwuz‡†‡Œ†z|u‹~}…„„‡~~}‡|xuyw‘“ŸŒ}‹mu€ydƒˆ—†s’Šo……zƒtcnjY_[]]Tgse`YdrrgsbkeWZ`iw¾®{Ÿ·nbs†ht|rzƒ†z}Œxxsvo{vejna‡uŽsjb^~xyŠƒfq}hjkZVoxŠ£…q™“q€xum€‡r”ˆŒ‡ƒˆ…}yurohyajm`mvjgklzwzw[g}|xer}n„teu…Œ†•o‹fkzƒtltb\o|kt|‹zft†}mqhu~x}r|lzzzwpelbm‰~mnVk`wVKjkOROhNY|hbNUujLPTU^fvƒf]aphg`Wi][khJEjZbdWYUyZNWnjY]le\Yec^tfmdqfrpt€wpš„v~x|…‡}us‚ˆ•‚nsxzzss…‡‰ˆ„x€}v}„‰Ž„‚„{~‹ƒ{w|wwš—zŠƒ‡iw~|l„…”€r‚q†‚~‚oflgW][\[Tdpe_XcsuiupdecW\\h€por€s‰dex~itvssƒ…x„ywtunk{pbhkg†t„nf]_}o{‰}hlwfidUWrp§|„|v–s|s{ym{z„v—|‡†‚†ƒ}uprmgu]mh_ludgfizo{rYgwtgp€x‚ubw…Š|”€n‹jmz€pere`lyfrv‰{}auƒvikqtzpyxr}f~xvnceam†|mkVkcqSLikPLNpG^{faMUtcJNSW`jw}e]gsie_VcWap]LKkXcaUTUsWMXudZ_k`\Zce_wfmbpisor~tt™w€x~†„z}v‚„~˜…nrt{ztq……‚€z‹ut‘}”Ž€…„|~Œ†z~€v{£¥Šyˆ†…lu|{u„‚Œzn…sz…}ƒunjheV][[ZSbne[Xat{jhmh_bW_[i€jko€glahyykttto…z}vunzhjyj_enhw„geXbwi~†zoioff]UXoh§vz|Žyuo~oruyŽw”t…‚…ˆujrvgho\me^ms_gajxh{m[mƒssio€~ywaw„„x„sˆqoyqbph[nvdpsˆ{xar€pgjxsqkwvtwcƒ{~wvpdccn|}kkUjcgSKlhPGRlEaxeaMSr]JMTYekwze^mpid]V_UnnWKShXf^XMUlUK\y_[_k]][be`zhlaoounowuz—}w€z€‡†zyzƒ~“„qtt~zwt…ˆ}€}ls•{‚Ÿ…‡}€~†‚€Š{v„¬Ÿzˆ‡„lr‚zv€un‡o|€s‰€jomddX_ZZZUbjg[Z_u‚i^ml\aV\\kfrt}ij]kvvhtwrn†{~}yvrmzhiwf]drgzw’ccTeof‚„wvfhi`WVYhd§n~x€‹Žzpp|fxny‹zvŽqƒ}~†ndvsdhh]lb]oo[g_muezh]t€orkq{~uubt…Šz‡†€wru~taplYprbqq„{udr€lalzojhywtrf…uzzuqdadns~jlTi_^TLscQGWbGbve`KTpXJLXXgkvzdenpfcZX]XveTJ\cXhXYIWeQHbxZ]_l[^\bd^€ij_otymonvƒ—yr€}ˆ‹†}vv†x‡Œ}suuyzz‚ŒŽ}~„‰jt–{Š}~…y€z~|†ˆsq®Œ{{†~frˆzt}}vro†l{~lzbpoae^eVYYWcfk`]]s†iXpm[_W[\l{cpwvlb[mstguvqm…y€ywnoteite[gtfvv‘z_]Rffj‚t}aci\TX^bc¥hyt‚…xmnygwm{„ztˆr€x|xhevm`fa_j`]tkYe]oobze[w|knnpxxttdrƒ’~‡‚ˆzvoq}rawdZnoapq|seq€d^nvicfyztmnus}sqb^fno}eiTiYYTNx_RJZYHbtc`ITmTILZVilr{bllsbaYZ[av[SKd]XiSWHY`NGiuX^am[[_bc]…ihanxylokvxmƒ~€’ˆ„vu‰tŒ†sqvvw|}~Œ€~“~px–ƒ}™’y€€xy~sˆƒsp™¢{z‰•yduˆysxvlto~ly|p‘r^pn`gblTZZWhcme\\r‰fRrm[ZXX`lvdiujj^Zmsqltttk†|~€|wonldiqc[krdtvs[WTd`r~r‚\ac]SZ`\d“Ÿerq…„‘tljylooz{{q€vrzzzdeug^b[ah\^whWb]ohawa[|vjirowtsthp”‚†~„vrjp{lfvW\jmbpr€zseo~[`pqb^ip|llt~rqxkp`\elm{agTgUWRPv[SPZRHcsb`GVkQIPZUkkk|emoq`[ZXYlpWRPfWWhSTFZ\OHruX_cmcXa`a^Œjcdmyxkoiuy†{kƒ}€…™|‚„y}ˆn†qowz|t‚‚|‹ƒ‚–tx‚”…Ÿ‰u€t‚p‡‚uo¢—t{†‹‡{fx‹on{ofxpzlsvsk^tnagekS][Ugbll[\qŒdNom\VXUgithbtee]Znunpuuzl‡||ˆwscekoa\nmcsx‡kZTVccw||p…\c_cT[`Zc–•cnpƒ…Šsjhznervs{kytuoz~u_frc[^WbdYaufU_`mdaq]]~phisqspuukm„“ˆ{…qrfn|oqnSZejeqs€vsblvUbqk[^ne|elu|rrrjm`Ydjjx^fTeUVPUnXQWTPHer_aFWjOHXTVmid|ikwkaW\U[tcSRWiQYfTSHZ[PNxw[_fliZb`^^nbfkyunoivv~mƒ€~‡—{‡Šk“ˆrgt€{u€ƒ}‰‹“r}Š‘…‡Ÿ†{†Œs€†s}‚un¥ŒsŒwxn{`d|qfzsylmqvƒgd|lcfghS__Tg`lo\^nŽhMil`UVSofskexde]Yptmr{xsmˆ{€wœ{zlaelm^`njepy~gZVX`kx{{oƒ^b^gVY`Xdœˆbkq‡}wkjwl[vqkyiurmo{€rXjm_Y]VbdXeqcT^aibblZ`~lfksunmwvkh…Œˆz‡mqeo{lqlbX_hhos€ts^imSepeUbnaybpu{ukolj_Xaghu]eVbVSNYfSO]OOHeo]cGYiMI_KXmd_xhn}d`U^T]t[TR`fN]aTSJ\ZQZuu]_fmhXba[^Žqcgjwqsnhvsyƒs‚ƒ{ˆ~|Š‡ŽznŠtls‚tˆ…‡’„•z}Œˆ‘›„€|Œ„rstwqn““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|}~}}~~~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’’’’’’’’’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’““““““““’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ>.1111/o‡„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDEB1/0000.\pnmnnqI,00//,I…ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ-h†‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR4555553Sjggggk<;ƒ€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}zzz|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‘‰‡ˆˆˆˆ†Œ‡‡ˆ‡‡‡‰’“’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†………†…ƒƒƒ„„„„ˆŠŠŠŠ‰‰†‚‚‚‚‚‚„ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z{|{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘“““““Ž’’‘‰‡ŽŠ’“ŠŽŽ…Š‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…Œˆˆˆ‰Žˆ‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰‘ˆ‰‰‹ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰ŒŠŽ‡Œ‰†ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}|}}~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹ŒŒ„‹Œ‰†ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz|||{}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒˆ‹ŽŒ‹ŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzzz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{{|}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{z{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz{{|}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}||}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†………………„„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{|}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰ŽŠ‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{~~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““”””””””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““”””••••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••”””“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””“’“““’’’’“”’“““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’’’‘’’ƒ““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’’’’’‹Š’’z‘’’‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘‘’ˆw‘’„w‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘‹nŠ‘zuŒŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŠh€vu‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰iwŒuu†ŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡€hmqs……„„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxz}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzop{xy{|{xw{xuwttvuuvwuh`g`dinghklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkiffggghhf_kl`jhigccbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsvyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__ac_\_]`]^Z\ctmeqpe]ZY_[XWSNMLKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{yvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSTPMJMNPROMRhplapukTPQTPPNNOMKMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTtsuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMNTflncosrWNNNOPQONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKKFBEIMahkqqonYLNRVPOOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEAKOGHNahfpokhc^chWHHJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:;>>@T^Y]hminmljjllVFBDEEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@:;><;;<<EYfikojmmjjklWBFFDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnpprtusqrvxy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;:;;99:88;<979;;<NinokmliilU@?CFDCCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqtsurqtxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<:79::979::78:87IiompnkkW<;=@A@=;;><==@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyy{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>><==?@===?C;===<Jgrwsl\?==>?@A@??A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquttusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCDA?=>@A?@;]n@>DE?>G[yrT@<;:=>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVppqssttuyz{{|~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???BFD><<=@=8:;mvH8;:=>@=g\9<=<8:;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pprrrtuvz{}}|~~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC?>AAABA@YQ<==ILEFvvM788:<??SU9;=<::;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC@CsyI;]ƒy|wV<=?=>?BU[:;=>?==>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hloppqtuvy||}||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCEAHrykb‚„ƒ‚ƒ€}]>@C@@?>Zc>;=AEABBFHC=<@DCAA?>=@A>>>?<>@DGE@>@A?@CFECBCC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{{{}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@Fot}‚‚ƒ~}…uLACE@??PrvL?CEIJIIMMKEDFGHFGEEEDDCA?@>>BFJJGEEGFFJNNKJIGGHKLIGGCDDDEDABBC@CDEDDEDEFCBAEeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@EEhs}|„~y…qBDEDCWu‡ˆˆXGHJMLNOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHIHGFEFFFDFHGEEHHFHGHFQnnpqrvvy{{{z}}~~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJG`{€w„…ƒ„ŠlAAUt‡‰‡‡‡ˆƒWHLMLMNLJGGGGDGGGGFHFHECDDFEDDHHCCCGJJKLLLLLLIJKJJIIIHJHHGHIHHGHFFFHJIIIIH]ooqrtvwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLLN[|‚‚ƒƒ…††ˆƒUl…‡†††‡ˆˆ‡|PKLKHGFFDECC@ACCCCFFEB@=>@AA@BD?>?DFHDEGIJIIHHIGIIJJIHFJJJJIJIJJJFILLJJKKfopsrtvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKLLJUƒ„„‚‚…††ƒ‚†…„…†††‡ˆ†ŠuIIFB??@??><<<>::<AA@><998<<=;>;9:?AB@ACCB@ABDDBCFHIHHHLMLGIJMMNMJJKKJLLSlpqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHHJJIe…„„„‚ƒ‚ƒ„„……†‡ˆˆˆ‰‰ŒŽfBB>88::9878896479;<:8567789787688;;;=@;999=<>;;=ACEHJMLLGIHORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@CGIIj†„„~ƒƒƒ‚ƒ„†‰Š‹Œ‹Š‰Š‹Œ‰T:8656766646763568:876565676778:77789;7578979876:<@GFIFIFEFOSRSSROPPRTepqsttwy{|{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:=ECBf…ƒ€ƒƒƒƒƒ…‰ŠŠ‰‰ŠŠŠŠ‹‰‰ŠH6764688745784676:9766765:9:;:;898987779:98878589;A=>>BA?AKLOQPQOOORWkqrttuwy{z{}}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897;B:=q„€ƒ„„„„„†‰ŠŠˆ‡ˆˆ‰ŠŠŒŠ‰‰Œz>988;<=>9:;;89;9:;:99;:9===>;;<=:>;9;;<;<<99<8::;:999<?<<ABDIJMKIKLWorsutvx{{||{}~~}}}}~~€€€€€€€€€€€€€~TFEFILNNLJJMB?:;<:89989:::;?>H~„‚‚„………†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>ACEEAAAB>@B@@>==>@???@?@==?B?AA?A@=@@@>?A=><;:;99;?=;;==AACABCAXpqtttvy{{|}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::<=:;;==?@BR‚‚‚„…„…„†‰‰ˆˆ†††‡ˆ‰Š‹‹‹ŠŠ‹Š‹^>CGIKJIFGGDFHGEB@@CECBABCB?@DHDCEDEEBFEFDEFD@B?<@>=?@>???>?>>:;=<`qqttuwzzz}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>???=A@CDFX…‚ƒ„……††‡‰‰ˆ‡†††‡‰‰Š‹ŒŒŒ‹ŠŠˆWGLMMKNIIKIIJJIECDFGFDCEFDBHIKHGGFGGEKIKIJKJCFCCDB@ACBDCCDDC@=;=@hpsttwwzx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€OA>=?DLK@BBA98<>;<;>@?A?BBGGIY…‚ƒ……†‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹‹ŠŒPMONLNKJLJIIHJFDGHHIEEHFFELLMIJGGHIJNMNLLNKHFGGEECFFFFDEHHFCA?@Llptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?EGG=<@@98<;;=:?@>?@CFIIP_‚ƒ…„…††‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒ‹ŠrNQONLLKLJHGEJIDJHGKJHJGGGKLNLLHHIJMPNPNMOKIGIJHIDIHHFFGGIGCBACUnpuwwy{xyzz||}~~~~}~}~~~~~€€€€€€€€€€€€€€TDAABGHB?8?@9:<8=>;=A>?ADHJLUqƒ„„„……†‡ˆˆˆˆˆ‡†ˆˆˆˆ‰‰ŒŒ‹ŒŒ‹‹‹‹‹_RRPMNMKJGFBGJGLJFKNKJJJMMLOPNHIKLOQQPQOOJHJJMJLFGHGFGHFEEBABB\orwxyzyyyzz{|~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<9@>>@BGGAGKLPVy…ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹‹ŒŒŒŒ‹‹|XVRRTROLKJDEFKONOWUQPOQSRMSTOMRLPSUVRSQPLJMMMKNGGJFFIJDDEEBDCcpuyyzzz{z{z{|~}}~}}}}|}~~€€€€€€€€UFFGHGGHF>@B=?==B?CCFVNFNOPTX{†ƒ……„„‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŽ‹‹‹hWVkaERQQPI;;QSR`u]UVTVYYRYXRZfPUWZ]RTWQPNRQPPQKLKHHJHEFIIIHIirvyyzyz{{|z{|}|}€~}}}}}}~€€€€€€€€€~~SHJIIGFFE??AAEBCGEDELXRMTUVX[|†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ}aŠ‹‹‡l[dU:XXXSQ?@VUY\d`VYbr]]V]ZVEQYZ[Y_TZgRVVXUTVTOOMJLKIILMKOMSosvxyxwzyz{z{|}|~~}~}}}~}~€€€€€€€€€€~~~VJJIHGEDDBA?HMIMPKIKPTSSXZZ\\x…„…………†‡‡‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~Œ‰Š‹ynpXZ[ZRTRVVTZZuƒYU}`\X]_WIV]][[_YIYXY[]XXYWRQMPQMMOSQQURassvwwvxxxz{{|}}}~}~}}}~~€€€€€€€€€€€xy}YNKIIHFBD@A:PQQWXPPOQSTTXXYZ[n‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡ƒŠfYY\YSUTWRQWVc–€QerXZW_gP`f[[X\gaGOZhg\[\]]WSNSPPQVVVVYZnrtwvvuxxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZ[RSQORRRUSVTW_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PUXTRTRQQLOMKfy[]TYUV]ZLTZTST^ZXWWWzkX[[\^TQQPINOWVX[Zdqsvvttvxyy{{|}}}~}}}~}}~€€€~~{xwvsu{€€tk~~kry^[VUTROKFCDAM^ƒlVRSNOQOQURSRRTcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰‰‡†ƒ‡‡‡ymqVIKMNKMKHJDFHEC>TcURQQNKRTQMOYQMNQSUUMQSRPOMLHCIHRTUZ\mruvuttw{zz{{}{}}}~}}}~}~}}~~€~{vsw}~~du}iqt_d]^[YVPLILIal’tPQSNQRQR[RSRQRVTbs{|€‚}{{€ƒ‚…†‡‚†††„†…†u_]KC?CCCCB?DPBC@C>BHGV@HNMG]iQHFOFDEFHGHCDHGHKGDBADAOQMSdstvustvz|z{{{||}|{~}}}~~€€€||}€€€}vt{mh|gnqfiedb\XSQPURsWe[OOOLQSQUYSUQQTROV`klrv{{xytrnstsyx~~ƒ€ƒƒ‚€‚€‚‚lMG>?;;>@@??>jQKaEFHIEB?GLMGMQUIBE??<=<==?=?ACC@?<=B>JMGUnuuustvxz|{}||}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QRZ\Y^JJPQNKLQRQTUTWQQWUPX[b]agmmlokg`nrjmlqu{z}{xz||xwxeC@@B=:BCAADB\]O{NONNKLMOOQLKLWMHG@A<977599=;;;8989?;BH?\stuvuvxz|||}||}}}~|}}}}~}xuvz{zwyxuw{|yxuywcqhipmnmmhf^OP^\ZIHPRQOMPQNQRTVXSRYTNYZ[WY]^^_e`]^qvk^`gkwooljonnlfbYHFFHBAGIEEFDMROaWRWQPSSRU[OOQWPMIDF>:96587979:366795<B=estvxwyz{}}||{|}}~~{}~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZWMLTTSQQUOLRSTWXTTXRLXYZVXXVXY]WXXhsk]Vaskaa_^da_^YUQMONLIHJKIHFCQPS[WTTNQSYS\eUOSTQNKIHC?A9988978857578599Gmqtxxz{{}~}}|{}|~~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPXVVSTVOOTVXXYSVTLKTUUUUWPTUWTUR]n^RNY_[VY;DVXT[fJLPRROMMNNNLJFQPUYSTNJOOUST\VRUSROMLIHHF?>=:787659967675Wppswyz{|}}}}|}}|}}}y}}|~~~}||}}~}|rvqxxrvuqqnppopuvtnjddjppqrpofedc\^RTZVWUTWTRXXYYYRUOIGOPOOMRJOPPPNNOTLMIPOSTU2=XMIAQ=caQSQPNPQPNNMQNTRPRMILKOQPRRSTQROLLKLLHCBA=::876;B4566:doquwx{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqptuvcjgeWhtrrqniihpVVTUXUVURWVUZYXWUQSFFAFGGHFJDHJHGEHLHKIFLMPMG/E_R>3@>joaRRQ@FUQPQPQNQOPOLJLLOPNNPQQNPOJLMMKGEEDB;==<9=G6677Dmptvy{{||}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknaePSTRSTOWWVYYVQQQO@>;=?ABAC@BEDA@GHGHFFHJMKEGCORC8ENS]fSQSAGUPOQQPMMNMKLKLNOOQMOOMHLLIKKLKGFFED<AA>;@E;<89Spruy{{{}||{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpknqmimcLOOMQSLTVTWWULLKI=987;?@><=A@B=>EHGCFFIGJJ@FAA@FHEJOHPRb\QPRNSOOPLLOMKMLMON[WKMQOGIHCIJLLJFFFE?BC><BF?B?Adptw{z{{|{zzw|wy}~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCE=9879?B>;?B@@>ADIECHGIFIEBB?>=CBAGJEMObeQMNNWKLMKLMMMLKNNSdMJLRIIIEAHJLMNJGIFBAB@?EFEHDKnovyyy{{z{zwtxtx||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGLMIMPMPOHKE?B=999:?B?<@BBADEGKFCHIGGHCC?B??@A>DECKNQTLJIMTGIIJLJKLIJLMOPRPKGCLGCBJJLMOMIJIGCCCDHJMLIYrmwyxz{{y|vrpurtyyvxjqnkllnttmtu{stxronqovsnporpopstyjN`gsjt|ygosqiqheqHJCGHHGJKIJKDGB=>=:::;@B?=BBBCHFJLJDIIFGGCC;A@B>@@CDCIMPGIKGHKDHIKMHJLHIJKJM]RHHDNFACKKMMPNKMJKFGGJMNQNLbmivvw{y{z}qmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoijthdoFKDFEGEFFGEGBC@=<=9:::@C@>BCDEIFJJLFHIGFFDB;BCC>@DDCEGLNHKNHDHEILNMHILGFGIILNKJHENIBFMLOMOMNNMKIHIORQRNRfffqosxu{z|lhjnfkpmsqfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGJCEFEBCBE@DB>@?:;;=:=>CA>ACEGJFIHKHGGGFEC@=EEB>BDCCEGHIGMPJFFGKNOKFHIFEDEIJHKIGHPKDIMLPMONOONKJHMRUUROWd`amgproryzgehhdilgqlflmgiklslpvutpnvrosrsutqssutsuvvvyvutwljuumrvqlnlerLHDEGCB@BD=BA>@=::=?;>>@B>ABDGKFIFIHFFGECCAAFFCBCBDEEGGHFLQLIOJJLLIGHEFEDCIIHKJGKRMBNOMPOOONOOKKKOUWVUTX_^\iaminhrsbefedihfnifmmhkkmriqvusqmvnoqrswsrstuvvvvwvwvvtwujsunutsqrjksMGGFHBB@DE<A@@C<89=>9?<?B@@@DFHEHFFHGEEDCECDIFCFEBEGEFGGEJMKHQMJKHHIEFHIFCIJIKMKPSNDQRPQRNOMNPMLMSWVWXVX]Z]d`hbjigk_eefcgggkggkmkmlpqgttursnvoqprtxqssuvu‚‘yvvtxuuwxmouorsuqqiozMHGHHBBBFE<@BBD<7:>=:>:@B>??CEFDFDDHFDECDEEGJEEJGCGHFHGECFJJGMJLKHJLFIIKHEKKLLOORTOISUSQSPQMNQNMPWZVZYVZ]ZXa```^hec`dfhgiihjfhnllnmqpiuuxrrpupppruvpusuvu{~}xvtwvvvxplupmsunprsyNIIGIDACHE<@EBE=8:>>=<<AB=?>ABFCEBCHECEEFGGGIFHKHCIHGIHFDHKIGKHMLJKLHLKMKJNLONPRUVOKUWTQTQRLOQPOTYZZ\ZY\^^^`c^\ackb`dghr…hgjfjmnponsrjtuxrsstrnpqvrquruus~yŽ}uuvvvvxrhuqkrtlqvpuMIKHJFBEGE<@GCD@:<>@?>?BB<@>AAFCEDDIEFEGEHHFHGIKJFJHHKHFFLHHHJGLLLLLIMKMMMOLPPQUVWOKVVUSSRQLORRQV[[]^[\^__a`ad]d`ef`ehjcssfjhglprqossnswwquvtsmoruorspurvrtvuuuwvuwtgtrkqrkrwovJKLJLGBEDE<@FDDC;??A@@@DA?B?ACHBFEFHFIFFDIHGIHJMHHJJILJFJKHIJJGKKMMJJMLNNNPKOPRUXVMNTVTSRQPLNTSRW[^^_]]`_`aa_acebchbdijgv‹lkigmosqpqppryvruutsmmssmqrotutrpswtuuwvuuteqskpqjrvowKMLLMGCCAD<?EEEC=AACBBCEABDAAEGCGHGGFJGCGJGGJFILHIJMKMLGKIHKKNQKRQMSMKNNOPPOTOWXX[NSQW\ZSVPNTUTTXZ_bb_da^`b^`eaacingbihhnxvlhimosrpqrrrvtsusssnksqmprotvrqquvuswywutucmtkopjqtowLNLLLGEA@D>>DEFC@CAEDDFBBEGCCIFCHJJIIKGDKJGHJIIKHJJNLNLILHJLKZfJd\KlSHON_nUks[qpbwcRPavuhucav`Xnqbdvinzf[lt`ljT_wvijgifglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqrqyLNJKJFB?@B?=DEFDCCBEEDFBEFHCDJEEJLMKLLGGMIGIKHKKIKJNLMMLLILML[sbdp^lmUMNfs]geqlntgpi_aYnnbppbkjjgoqtetno\ougpMJryvkb`keemxmkvmnpsrprqpqrqrrrtrmmsnnoprutqsstuuutwxvutbmukpplrrqzKLIIGED@AB?>BFGBFCEDEEDCHHGDEKGGLMNKMMGJNHJKJILKJJKLMNNMMJMMM[roonpplkMPQlWNibtrpamov\YlQ\mmZqmkomxxtsip\_rkqjUuyxpc^kfbgppjiopprspqpqqrrqqrrtlmrmnnorutqtrtuutuuzvutenukpolsrryJKGHEEEBBB=@@FGBGDIEEDBFIHHEGKJGMMNKMNGLMILKIJMIJJJKOPONMKNML\hdu]lqWlNPQmUZk^klvaldtTecNmYl\tpkilxjwuhp]^rkhWbcw|oc`ggadityknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtvIMGIDEECAB<B@BFDGFLHECCHKHHFJLLFNKLSRLGLLHNJHHNHJJIHNOMNLJNMJZsppoqqmlOQRnYqkgooqqomt^nXat_nopoqronusttj[]tcwxrjnzhaacfbbjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyxtukoumtonssvsHKHIBEEEA@>CDBGCHIMIFCFJLIGFJMLFOJKWRKGKJJNIHJLIKJIHJMMMLIKKKSkbZi^_icrrZ_Yjo_eeUk_c[aaQ`lh]j\ojid[pfdp]Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunwqrutwrHHFIDEDFA@AEEDGBHJLHFDGKLIEFJOLIPIL[QJFHHKMIHJIKKIHIGKKLLFHKKLLLKIKLNT[\TPTLPONOOVQOOQNOQJINPQeriTYW\[\UYZ]X]\\cfaaebce__fkmhmtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyxxuvqruovrtsuusHCEGFFAEC?CHDFGDIKLHFDGKLHDGHPKLOKLWLIFEHIJHIKILJHFGGIGHIEFLIJKNLIO\W^P\[`^OXYS\\b^MYZMXaRJYaZS`d\aX[ddVVX\YZX\VY\]b^d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtOBCDLMBCDBEIEGGFKJKHEEJJJGEHHPJMMJMSIHFAHFJIKLILJHFEIGDFGEEJHCJMJKT_Y`X`a[`UXYT^^Z_RY\P^\YN^\^S[^c^Z]`c`Y_b[`^[TXWY^]cbcacfiekrpoppnow††……†‚{€……††…†…uqprrsvyyzyyxxxwryvxrqxvtvaSJJMIECBCGGEHGHKIIIDFKKKFFIJNKNLHLNHHF>GGLIKLJKKIGEIDCDDBGJD@JLJO[cY_^a_RTRW_`\]Y^QY\MV_WKQY[PZ_aa^^ca`bbbcceZQYVU\Z]c`__cebhomnllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxXQKFCGEBEHIFGHHFFJGHFHKILDDKJMMLLHJJHJG?GFNJKKMKKKIGGCD@DAHIB?IJHO]aZ[d]_TQRX]\\\_ZKW\LR\YIN^QO\_acdccb\dcbdcfXQUTR[XZa_^^aa_dlkmjjlnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMC@IFCEKJFFFHGGIFFFILJNEDKJLNJLIKJHIFBHHQMKKOMKKIHGED?ECIHAAGFET]Y^X_Y_[]UXXP]]QKJV^X^[]VY`RQ__aba`bb`cbaddbXOQQQ[S[]]]]^__dhgljnnp{{|~{€‚ƒ„………………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKCAGFDGMRHCQJFHHHEFKJMPEGIJKNLLILKIIGDHKQOMMPLMKKHICDAEDHGBAGECWUE\T^SV_XNTUNZ[MJKT`a[_X^^a]OYb\``_bcb]abW__TPNOPXR][[\\^`bffelfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDEFGDIRbPCV^IGGHDFMJPPEIIKKNLKKMLJJGEJMQQNOPMNLNHKADACDFDCAEFBMHBKLPONLFMFGIJHGLLMOPILOPOSPLQSRUZYWYXXdWOSTPPNMOUT[YY[]\`adecgcklpsszy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKM]LGGXMGHJHGMLQQILKLKNNUNOKKLGGKPTSNPONONOHKF`ED_LDfcEM[I^[rmOMUmYLCP`UlWgJ]WU^DLQULMTVQRTXWTXUT\UPfZhhdXSkSVVU[\[``aaab`fhfnlhrz|}~„„„„ƒƒƒ}|zr{z{‚€ƒ„„……„…ƒƒ~z{LIEFFHEEKOSIKF`THJOJIOMRQKMLLORUROOJLNGHMQ[YOPPNOPOIJQQI|YYrsXPmHqnoaVPqqsPCksmqtpSo_[nX]V\XUkhU]VcZ`Y[`VUWjtuu__v_Xa\\f[_aaaa^`bgmpl`pwtx‚ƒƒ‚}~€vxzlv~tx~€|~€‚„|€ƒz~wwNIEHMNBDLLFJLFRVLKNIKRXWQNOOMQTNOQPKKNGMPS[ZTQROPPPJHZx]TxehYRTQvgtlpbnfjQrOMwmjrpsrqrpoo€]fzuxqqzq~s}ku}bRg|essosr{|o}yor_``baZ``gknkblfgmw~€ƒ~{xw€tvzir~nt|~wx{~€ƒx|€u|||ssNKF`]GAEMMHKKHJPNMMJNV^YULQSNYZMSSRNLOIQRTYWWPTPPPQKHgxlcxrmZKMUypumubnvPdeJfvqmwo€jfxxiWrRi{lijzz}lxzphoXvvjuup€`rg}ilx|o^__ba[]bdgijdgbcdllppstsssyqrxblugry{ssuy~suzn|}yxrnNKStNCBEPPHJKJLQOOOMPZ`ZXKTWPa^RVQYSLOISTUXWWPUPONRJKrouuquqdibWnLqp^FhyWvTKhx}x`y{sna^mocRgqunmypwlvttqlm\t~zkmy|ktm|kpvux^__b^]_ddighee^abiiijknokqnmjpacfdowxompsy~nqpj{ztromLL[VHGEGRPILMKLQQQPPQW\YUMUYUfXRRY^TMNITTVWYWOSNNNQHRmHiwK`dvvVXlOnl{sajgvUKWkh}lmlx`[pz{^`zscroxqhe|ir|]TKl`vukiv|{m~xk|p]^^b[_bddgeeebZccikkrsrwgmihdg`alagsrlgmmr|kmhk{tmmkmOHJKHIIHQPLNOLKSSSOSRWRVTPW[VVTTTa`PNNKTSSQUVNNLMOPJHQNPULKKSTSRTPVUQQNQQXXQNPUTXXX[[URSW[WXWZOSUWWXR]YW]VTOYRWWWXY^[gr^[[Y\]_cZ_ccdfdccbZccfffmnmuffgc`f_]g`dlhfgkhpzhggkujhgilQIKLLMKJSQMQPOLVUTPTUXUYUQZ]VUTWUYXPOLMVTQNUSNOMLQPKJRRKQMKKORURQQSSIHLNOQRQQQTVRXW\WSSPQUVVSZQOSRWVTYVTYUTRUTTTWXW]Z^a]\ZZ\\`c\]bcdfdedaY`acabhhincad^_c]Zd\bma^fefmsdihkkedcfhPJKLOOLMSPNSQQMXWUTUWWWZUS\`VWVYUXTQPKOWSPNUPNQNKSPMOVTNQNMNQTPUQSTUNKMOQTTRRQVWUYZ[YSURTWWWY[TOTUXUUZUWYURRXVUW[YZ_]UY^\^]\]`a^[bbcgfddbX_ab^`hefda^_]]^ZZ_Z_g`^]]bhkagfhfd`bcaPKMLPQLOTOOSQOQZYXWXZZXYV\jdVXYZWVTTPKOVTPOTPPPNMQQPRXTQQOMOSVNWRTUUONMQSUUTTRTXVZ]\ZVWQRWXV[[WQTVVVVYTWXUSRXVUZ]Y]_^V^]^`\\`___ZbbdhgddaYb`b^^fcc`b]\\\\YZ[X[a[^]\_b__bdebd__`\PMNNRQMRROSTQPU\ZZW[[\YZ[dqmhd_[YVVXRLMVSMNROQROLPSRUZUSPPLPWVRWSSSXMOPRTXUUUSUYX[^][[VROUVV[[WRTWVWXVTX[TSRZWV\^Z^_`Ua\aa]`b`]`]cacghdf`Yc`a__ed_`c[Z\[\YZXYW\Y\[`^_[^^a`_b\Y`ZQNONVQPTROUTSPW\]\X^\_W\^jqwy€c\[VVYQNOVSNQQPRTRKQTTYZWUORNSXWTSTRRZOQSSV[VVWTVZX]^\\^VSNTUV\\VRTVVXYSTY\TSS]XZ]^\```Vb[cb^ac_]bab_dfidf^[d`a`ace_b_YZ^[\[YXYWWZZZa\][]\\Z]`W[[ZPOOOYPUURQWRTP[]^^[`\`U\]ijr}slg\UXWQORZSRQTRTUTKQWV[ZZSOSRVVVTOVRSZRTUTX]WXXSX\X^]YZ]TUNVWW_[XRUUYYYUWY[TSV^Y]]`]bb^Y`[eb_dd_^cca]efidf]^da`abcd_b^XZ_[\[XXXXW[Z\`\[[\[XZ[^V^Y]POORZPZTUVVTTT^^`_^b\`U]^bkyum}lZUYUQQS\TUTUTVYWLRZW]Z\ROUSXVVTPXRSWSVUU[]X[YUZ^X_^Y\YRWRYXY_ZZTUVZYZWXY\VTZ^\^`a_dc\^]]eabfd^_dc`\gdhedb_da_a`bb_`^WX^Z\\ZYYWV]Z]^ZY[\[WY\]VXW]SOPWYQ]UVYWWUX_`aa`c]_T]_beev‚{hXYYSVSV\WWWVVW]XPU]Z^]]TSXSWVTSTXRSVTXXX]^X][V]_X__X]VQYTYZZaY\UVX[Z[YYZZXV]^_^cbadd\b\`fadfd_`dbb[fchecfaf__aaaa`_^VU]Y[\[Y[YY][[[XXY[YZZ]_]TY]UNTZVS\TVWYWV\`abcac^_V[`da_zuohY\ZUWUW[ZY\YXY`WPV^\`a\TUXPUWUSWVRSUWZZ\_^Z_\V__Z]^Y^VSYWYZ]bZ^VW[\[\[[YZYY^_``dbceebdZbfcgfe^ab`c^cciddg_g^bbcaa`^_XTZZZ[[X[XX\[Z[WWYXW\[\`]V]]SPVZVVZUXUXWX]_badad`^YYadb`kfh^\][VWXY\\\_[Y[bVTX^]ac\RVYQWVWVWVTVTX]\^``]a\Wa^[^\[^XVXX[[_`\_XY]\]]^\Z\X[_a^`dcdfffbYceehgd^c``ec]fidei_g^cbcaa`__[XY[YZZXYXW[[Z[WXZTY]\Z`\U^bNRWYVWZX[\XWY^`baeada]^Ybcb_a`a^\\\WW[[]]__\Z]cXZX]`cd_RXYPXWXYYWVXV]]^`a`_b^Ya]]^Y]^YXVW[\`^]_ZZ^]^^a\[[Z\`b^bdcefefbZdfgigc_c^afdZiibfice^bbca``_]]ZW[YYXXZXWZ[ZYWXVU[]]]``bbxLWW\YW\[\]ZW\]_`bdbba]`Xbcb`cab][\[XW[\_]`_][`d\\XZcec`R\YOXXZ[ZZWZY`]`bb`ac_\b]_][^^YYUX]^_`__\Z^^`bc\\W\^`bbcedgeefd\efhifcbb\cg`\iibhife`baca_`_]][Y\YXWXYXW\[ZWWXPXZ]acffrkJYW][Z_\[^\X][^_acbaa]b[bdb`ccb\[[ZWXiq`\`_]\ac_^YYdedaS_ZQYX\]\[Z[[c`cbc`bda`c^`\^^_ZXV[_^]aa_][`abeb_]T\``cddfdgfefe^efhhgdd`[fg^ahhchhfc`b`cb___]]\Z[YXXXVZV\ZZVVUMXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡…‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vvvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{{{{{{{{{{{{{{z{{{{{{{||||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vvuvvvvuvvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{{{{{{{{{|{zzzzzz{{{{{||||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚‚ƒ‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||vˆ‹‹‹‹‹‹}}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰‰‰Œ‹°Á¾¾¾¾Á¢ŠŒŒŒŒ‰~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}vŒƒ~~†“y1333332j‚€€€{­éääääèʉŒŒŒŒŒŽ»ÎËËÌÌϪ’‹}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}vxxyxxxxwwwwwwwxyyyyyzwopppppprrrrrrrwzyyzzz~ƒƒƒƒƒ„||||||}}}}}}||€ƒ‚‚‚‚‚€|}}}}}}|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚ƒ‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vvvvuuyvvvz{x{xwvx{xyyz~|yyxxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{{{{{zzzzzyyyyzz|{|||{|||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwwy|{{{y|{xwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwwwy|z{x{zxxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z{xwww|yy{w|yxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚ƒ‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzzz{y{y|xxxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyy|{yyyyxxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyyyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒ„„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd_t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`w|{{{||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbu}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}||}}|||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}|}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrstuttssrrsrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrrqpopqqqstsssrqqpponnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxopprrrrqqppqqqrrssssqqrpoonnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnnnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrqrrsrrrq…soopoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqppqrrz{qqx–qooppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqpqrp~–qoƒœroppppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqqpv¤{nŸvopppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsqu‹‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqqpvªˆo™¡zoqpqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrrpv«•q¢}prqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrssssssstz«¢{ž¢}rtsssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz~|~~|vvwwvuxzxxxxxxxxx”²¥¤«§~{{yzyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~}|||}¦¦¢²¤¨‹z{{zxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}}}}~†¨œ£«šž›~||}€ƒ‚€€}}}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€£“ ­Ÿ¡Ÿ„€€~~~~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~€ŠžŒ”®œ–›‡}~}~~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~€~ƒƒ€~ˆ¥¢™Ÿ›–œ”ƒ…‰…€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’’‹Š‹‹‹‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚ƒ„‹–˜¤®¦¢› §©¡¡ ’€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒŽ‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒ„‚„”©°°¤¢žŸ¡¢£Ÿ’‚ƒ‚ƒƒ‚ƒƒƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒƒƒ‚€‚”ŸŸ™¡ Ÿ“‡‡‡‡‡††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠ‡‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„ƒƒƒ…„‚‚”•—Ÿž¡ž›•ˆ‡‰ˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ‘‘‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„„„„„ˆ“–—šžœ’„ƒ………‚„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘’’ŽŽ‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€‚ƒ‚‚‚‚‚‹•—‹‘œ–„‚€€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„„„„…„…†’“‘ŽŽŽŽ‰ˆ‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~€‚‚€„ƒ€€‡’Š’…ƒƒ€€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“’Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚‚ƒ„‚‚„„‚ƒŠ–ˆ„‚„‚~‚‰Œ‚‚‚‚„ƒ‚‚ƒƒ‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘Œ‡…ƒƒƒ‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒ€ƒ‚……„„ƒƒƒ‚„Ž™‹ƒ…„„„‚€ŠŽ€‚‚‚„ƒƒ‚ƒ„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”“’’ŒŒŠ„„ƒƒƒ‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~€Œƒ~}|}Œœ€‚‚‚ƒ€“‚‚‚‚ƒƒ‚ƒ…ƒƒƒƒƒƒ„„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†””’”’Œˆ„„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~•—‰€}}}}{—Œ€ƒ‚™™„‚‚‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“’Š‡ƒƒƒ„‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€€•ŸŠ~~€}‡Š~„„ƒ„‚ƒƒƒ……‚‚ƒƒ‚ƒƒƒƒƒ‚ƒƒ„‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”“’’‹Œˆ†„…ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„‘¡ŠŒ…}†‰€~……………‚€~}}‚„ƒƒƒƒƒ„ƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„……………„††…††…………………………††…†††…†††‡†…………ƒ„„„‡“““’’Œ‹ˆ…………‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…ƒŠ‘ƒ„‹…‚~}‡†„€~~ƒ„ƒƒ„„„„„„„„„„„„………„…„†……†…†††…†…††……†…††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†………†”“’‘‹Š‡†‡†„‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„„„‚‚‰~}~…‚~€€„…„…†††…………††‡††…†……†‡‡‡ˆ‡‡‡†††‡†‡††††‡††…„ƒ„………„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘”“‘‘‹‰ˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒ„„„„€€€„„~~€€€€……†‡ˆˆ‡‡‡‡ˆ‡ˆ‡ˆˆˆ††‡ˆˆ‰‰‰ˆ‡†‡‡‡‰ˆ†‡†‡‡†‡…„ƒ„…†…………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘Œ‡†…†„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡†…ƒƒ…„„„ƒ€€Œ‰€‚‚€€~{z€†ˆˆŠŠ‰‰‰ˆ‰‰‰‰Š‹Šˆˆˆ‰‰‹‹ŠŠˆ‡‡ˆˆˆ‡‡ˆˆ‡ˆ†‡†„ƒƒ…‡‡‡†……„„ƒ……„……†„„„………†…†…ƒ‰”“ŽŽŠ†„†…ƒ‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡†„„…„ƒƒ‚€€„„‚‚‚‚‚‚‚€~}}}}~}|{|ƒ‡‰‹‹ŠŠŠˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰Š‰‡†††‡…†ˆˆ‰ˆ‡†‡„ƒ‚„ˆˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚‚ƒ‚„ƒ„ƒŽ“’‹ˆ…„†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚ƒƒ…‰Š‰‡…‡…„……‚€ƒ„‚ƒ‚‚‚ƒ~}~~~~~~~}~}}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡‡‰†ˆ†ˆ‡‡‰ˆƒƒ„ƒ…„„……†ˆˆ†…ƒ‚‚ƒ…‡†‡††„‚‚ƒ„‚ƒ„„‚ƒƒ„ƒƒ‘’ŽŽ‹‡„††ƒ‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…‡‰‹Š†„†„‚††‚‚„„ƒƒƒƒ‚‚~}}€~~~~}|}}|y|ƒ††‡„ƒƒƒ„………ƒƒ…„„„„„„…„‚‚‚‚„„‚ƒƒ…†…„‚‚‚‚ƒƒ…ƒ„„…„„†„„„…ƒ‚ƒ‚ƒƒ„…„‡’‘ŒŠ…„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€ƒƒƒƒƒ‚‚}~€€}~~}}}}{zz~„„„‚€‚‚~‚ƒ‚‚‚‚ƒƒ€€€‚ƒ‚€€€€‚‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†‹“‘‹ˆ……ƒƒ„‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€ƒ‚~~~~~‚ƒƒ‚ƒƒƒ‚}}~€€€~}}}}~}|zzz‚‚~€~}€€€€€€~}}€€~€€€€€€€€‚€€‚‚€‚„ƒ†’ŽŠ‡‡†ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒ‚ƒ„…€€|}}~}}~€}~}~ƒƒƒ‚‚}}~€€€~}}}|{{{zzzz€€€~~}~~€~€€~~~~}|~€~~€€€€~€€~€~€…’’Ž‹‹‡‰…„„‚‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~‚„„‚ƒƒ‚ƒƒ€|~}~€€~„ƒ‚€~}~~€€€~}}}|{{|zzyyy{€€€~~~€€~€€‚€|~~~~}|€~~€~€€~€~~~~~~}||}…“’ŽŒ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒ‚‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚‚‚€ƒƒƒ€€}}}~~~~}}}}}|||{zyyyy}€€€€€‚‚€~€~~~~~€€€€€~€~~€}~~}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚ƒƒ…ƒƒƒƒ…„„„„„ƒƒƒ„‚‚‚‚‚~~}}}~~€}}}}}}}}}{zyyyyy€‚‚‚„ƒ‚‚€ƒ‚‚ƒ‚€€€ƒ„‚€€€€€‚‚€€€€€~~||Š“Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒ‚‚‚€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…ƒ„…„…†…†††…†…ƒƒƒ‚‚€}}}}}}~~}}}}}}}}}|{yyyyx|‚ƒ„…‚„ƒ‚‚ƒ…†‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚‚ƒ„ƒ‚ƒ‚‚‚‚€€€~Ž“Œ‡ˆ†ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€€~}}}~~~€ƒ„‡ˆ„†††…††‡‡††‡ˆ‡‡‡†}€€‚~}}}}}}}}}}}}||~~~|{yxwxyy€ƒƒƒŒ„ƒ„„„——ƒƒ„}~‚‚‚ƒ†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ…„„…ƒ‚„ƒ‚ƒƒ‚‚‚‚ƒ‚‚‚’‹ˆ‰‡‰‡††„†……„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€~}~~€‚………‡†‡‡†‡ˆˆ††‡‡‡†‡…}}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yxy}~‰–„ƒƒ„„”“€~~…‹€€€„†‰…„‚‚……‹ƒ‚……††„ƒ……ƒ„„ƒƒ„ƒ„„„ˆ’Œ‰ˆˆ‰‡‡‡…†…„…„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„ƒ…„~}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|xyz{|€‚ƒ‚ƒ‚€~}~~{ˆ‘||Ž–€}~‚†Š…ƒƒ„‚ƒ‰~ƒ„……ƒ…†…„……ƒ„……†„„Ž‘ŒŠŠŒ‰ˆ‰‡………ƒƒƒ‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚€‚€~}}||}}|||}||}|}}}|||{‹‘—Œz{|zzz{|yy}}~€€|{{~~}‚•‘„ˆ}|~ƒ„||‚„‚€‡ƒ}ƒ‚‚ƒƒ„„„„„‚„ƒ„…„‘‘Ž‹ŒŒŽŠ‰‰………ƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚‚ƒ…ƒƒ„………ƒƒƒ„‚‚ƒ‚ƒ‚‚€€~~}~}||||||||||||||}|||~~Š‚{z{zxz{{|}|~}~}}}}||}†~}‚~~~€‚||€‚€‚€~}{Š‚}€~€€‚‚€€€‹”Œ‹ŽŽˆ‡‡……„„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€|zx{€‚ƒ…„ƒ……†‡„…€†”ˆ€‚€~~~€|||||||||||||}|||||||y{{{xxy{zz|‚€~|~~}€‚‚€€€‚‘€€~€~~~€}}}{}}}|}||}€€€~€~~”’ŒŽŠ…††…„„…ƒ‚ƒ‚ƒƒƒƒ‚‚€€€€€€€€€}{z}€€€x~w{€‚‚‚‚„†‡††~ˆ•Š~€€€€~€~~~|{{|||||||||~}|{}|||{|||zzy{|z}…ƒƒ€~~€~…‚~€~~€…†‚€~~ƒ†~|~€€€~}}}}~{|}€}~€Œ‘ŽŽ‡„††…„„ƒƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}~€‚„††……~€€€~~}€€€}}||}~}||}}}}}|~|}|{}||z{z|}}†„ƒ€€}~}~~Œ„†~}||~‚}}}}|{}|~„ƒ€~~~~}|~}~€~~„’ŒŒ‹Š†„†„„„ƒƒƒ‚ƒ‚ƒ‚ƒ‚€€}|||}~{{}w~vx~}|}|}~~‚ƒ€z}}|~€~~~€€€€~~~~~~}~~}|~}~}~|{|||{{z}€€„ƒ‚~|}|}||ƒ~Œ~|{{}~}~~}{{{}|z{{{€†„‚„ƒ€~‚‚‚‚‚€‹ŒŒ‹Šˆ„„„ƒ„„ƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€€€}€~~~~|‚~~}}}{{}}|z||~€‚€€€||}{||||}|~{~{{{|||}|{{{{||zz}z~‚~‚„„‚‚…†…†††‡…„‘ŠŠ‹‡ˆ…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~€‚€~~€€~}ƒ||}}|}}}}{|~~~~~~|||||}|~~{|{||||}|}|~|}|{{{|z{|{{}z}~~€€ƒ‡‰‰‰Š‰Š‰…ˆ‘ŽŒˆ‰‡……ƒ‚‚ƒ„„ƒ‚‚‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€€~~~}€€€€€ƒ‚€€€€€€€€~|z|}}~}}~~Œ†}}~{{ƒƒ}~~}}|}}}|}~|}{}|}}~|~}}}}|{{z|{||{z{{zzz{~~ƒ…ˆ‡‡‹‹‹Š‰Œ‘Šˆ†…„‚‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„ƒ€€€€‚‚~}~€~{~’Œ|}Š€Œ~~}}}~}}~}|||}}|}|}}}~}}~~|{{{||}|{z{{yzyxy{~ƒƒ„‡‰Š‡‰Ž‹‰‰…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{}||~~}}‚€€€‚…ƒ„‚‚‚‚€€ƒ‚€}}€~|‰ƒ~ƒ„„ƒ~}|‡}}~}}|~|}}|}}~~}~}}}{|}~||{|}zzyyyy{{~~€ƒ‡„ˆŽŽŠŠ†…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{}}}}}zx‚€‚‚€€€€‚‚‚‚……„‚ƒ€‚„~€}~~}~€€}~„€~~}~}}Š…}~}~~€}}}|~~~}€}}}|}||{|}{{{zzz{{|}~}€‚€‰Š‹‡………„ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv}€ƒ‚‚‚‚‚ƒƒƒ‚…†„ƒ€€€ƒ€„~~€~~€~}~~€~€~€}€~€~|}||~~~~€}‚€|}€€}{}}}|||||{{{|{|||}|ŠŠˆˆ…†……„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚„ƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€ƒ€€€€ƒ~~€}€}}~~€€‚€€€€}€€€€€~|}}}}~~}‚}€~‚€}~€|~~}}}{|~|}|||z|{|}‰‡‡……‡…„…„‚‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz~}yxtt€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚€~~~€}~€}}}~€€‚€€€‚~~€€€€~}}}~|~~}}„€~}}}~}~~}~|{|z|{z€‡ƒ„„…„„ƒ…ƒ‚‚€€‚‚ƒ‚‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qyx{xyuu}‚ƒ‚ƒƒƒƒ…„…ƒƒƒ„„ƒƒ„ƒ€€€~}}~€~~~~€}}|}}~€€€€‚€€€ƒ‚€€~€~€€€~~~~}}~~……€€ƒ~€~~€~}{z{z|{z‚…€ƒ‚‚‚ƒ‚ƒ€€‚€€‚‚ƒ‚ƒ„ƒ„‚„‚‚‚‚~€~}~~~~}~}}z{|…„{{syz|pwuvwyutz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€€}}}~€}~~}~|}}~€€€€€ƒ‚€~€€€€€€€€‚‚‚€ƒ‚ƒ‚€€|z|z|{|‚€‚€‚‚€~‚‚ƒƒƒ‚„‚„‚‚€~€€}~~}}}~}}{{z€x|vyy{qtxwvxury……‚„„‚„……†„„‚„ƒƒ€€~€€|}}~€}~~}|~~~~€€ƒƒƒ€€‚€€€€€€€‚ƒ€„€}ƒ„€€‚}z{{|||~€}}}€€~}}~‚‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxyzruyyvwwsu†…ƒ……„„…„„„ƒ‚ƒ€~€~€}}}~~€~~}|€|~€~€‚ƒ€€‚ƒ„‚€€€€€‚ƒ‚€ƒ€~‚‚„€€‚‚‚„‚~{{||||}}~}z~}}x~|||~~~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vwvst†„„…„‚„„…ƒƒƒƒƒ€}~}}}€~~~}}€€~~|~~~‚‚ƒ‡…~~€€€€€€‚€€~€‚~‚ƒƒ‚ƒƒ…ƒ}}}|{||yz{z~y{yx~{{{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst†„„†ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€}€€~€}~}~€€|€€~}~~€}€€ƒƒƒ~}~~€€€‚€€}€~€‚‚€ƒ‚„…†„€~}||||zyvyyzyvyv~|{{{~|{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…„ƒƒƒƒƒ‚‚ƒ‚ƒ‚~~€}}}}€€€|€€€€|€~~~}~~‚‚~~}~~~~€}€€€~~}~~€‚‚ƒ‚ƒ„‡„€€~|}||{|uxyxxxyw{|{{{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvpxyrx…………ƒ„„ƒ‚„‚‚€‚€~~~~€~}~|~€€€€€€€{€~€€€€}~~}}}~€‚~~~~}}~~~|€~~~‚~~€€ƒƒƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}|{|z{}zzx{|zz{xtxuqrtpxxqy„…†…ƒ„ƒ‚ƒƒ‚‚‚€€€€}~~€}|~}€€€€€|€€~€~~~}}|€€€€€~~~~}|~~|}€}}~€‚~€€~‚„‚‚ƒ……‚‚~}}{{||zw|ywxwwx{{z{|…Š}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzz{zxswuqqsoxwq{…†„…ƒ…‚ƒƒ‚€€€€~~}|~}€€‚€€}~€~€€~€}}|}€€€€~}|~}}~~~‚€€~ƒ‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{||{zzzzzzxsvupprowvr{…†ƒ…ƒ„‚ƒ‚‚‚‚‚€€}}~€‚‚}~~~€€‚€€~|~|€€€€€~}~~€€‚€€€€€€€„‚‚€~|}~~z}…~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚€€€€€€~}€€‚‚‚€~€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€€‚€€~}~{“z|}|{}y{zzxyxy{||}|||||||}}}||}|~}~~~}|z||{|}{yzzzyytuuooqpwst}…†ƒƒ‚ƒ‚€€‚ƒ‚€‚‚€€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€€‚‚€€€}~~|†‰||~{{~yz{z{Ž~wwy{|{}||||{}|}}}}|}|~~~~|z|}{|}{yz{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€€‚‚‚€€€€€€}~€}€ƒ‚{~~{|}{z|||‡yxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ‚„„€~‚€€€€‚~€€‚€€€€€€€€€~}€€€€€€€€€€€€€€€€~}~}~~{}|}{||wxuxxy{||}|||||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒƒƒƒ‚‚‚ƒ€‚„ƒƒ„ƒ‚ƒ€€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€€‚€€€€€€€€€€€€€€€€€€€€€€‚€‚ƒ‚‚€‚‚€€€‡~~|z}|{}xwvyyz|}||}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚ƒ„„€€ƒ†ƒ„ƒ‚„€„ƒ‚‚€€‚‚„‚‚„‚€€ƒ‚€€€€ƒ~€ƒ‚~‚€€€~€€€€€€‚‚€‚ƒ‚‚ƒƒƒ‚€€€„}}}|}z}{yvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysruowqwysw{…‚‚ƒ‚ƒ„‚ƒ„ƒ€€ƒƒ†ƒƒƒ‚‚„„ƒ‚€€‚„‚‚‚€€‚‚‚‚€€€€‚„€~ƒ€ƒ‚€~€‚ƒ‚€ƒ‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ€‚€}€|z|{{w|yyy{z}~}||||}~~€€€€„„€}€~{{{z{ztpxrytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚ƒ…†„‚ƒƒƒ„‚„ƒƒ€ƒ‚‚‚‚‚€‚€€€‚‚‚‚‚€ƒ‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚‚„ƒƒ„‚„‚ƒ‚‚‚‚ƒƒ„ƒ„„„„„…ƒ„‚ƒ‚‚ƒ€€~||€}|x|yzyz|}|{||}}}||€€€€€‚~€€€€{{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚ƒ†……ƒƒ‚ƒ„‚„…‚‚‚ƒƒ‚‚‚€€~€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€ƒ€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒƒƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{~~}y|zzz}||}z||}}|z{~~~€€€€€€€€€}}|}}|vrvxxvtvu}‡‡ƒ‚„…ƒƒ„…„€‚……„„ƒ‚ƒ„„„…ƒ‚‚‚ƒƒƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚‚‚ƒ„‚‚€€‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚~ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€|€||}zz|~€}||z|~}|}}~~€€€€~~€€€€~|}}~~}|{xvvw„‡ƒ‚ƒ…ƒƒ„†„‚…†…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„ƒ‚‚ƒƒ‚ƒƒ‚‚„„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒƒ„„„„„…„ƒƒ„…„…„ƒ‚€}‚€}||{||€}}~€~~}~|||}}~~~€}}~€~~}}}~}}~~€|}€‚‚ƒƒ†ƒ„ƒ†„‚ˆ‡…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒƒ‚‚ƒƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒ‚‚ƒƒƒ„ƒƒƒ„ƒƒ„„…„„„…………„ƒƒƒ}„€}}||||~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒ„…ƒ„ƒ…~‚Š‹…„„ƒ‚ƒ…‚†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ…ƒƒ„…„……‡‡†‡…„„…„ƒ~~|~~}€~||~|z|}}}}}~~~€}}|€€~~~~~€‚€……„ƒ„„‚„ƒ†€‚……Š‰„„„„……ƒ‡††„„„„…„„„„ƒ„ƒ‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ„€}uyƒ~„„‚ƒƒ‚ƒ„ƒƒ„…ƒ„…†„…†}„y|~ƒ{…ƒ„ƒ€}~}~ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚‚ƒƒ‚‚†„„„…„ƒ„…ƒ„†„Šˆ………ƒ……„†††ƒ„„………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†spurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚……‚hzrss|€rƒƒƒ}}~~}~‚ƒ‚|}€}}||||}|||~}~€}}}€‚€‚‚‚‚‚‚„‡„…„…„‚„††ƒ…ƒ†ˆ††…ƒ†††‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vyy†r„ƒpvxqvtturstvi€nrotvnulwm{sn€‡ym}rsvsvmnwlpylu}|~€}€}€€}}|||}|}~}€€€~|~€‚€€€€€€€‚ƒ‚‚„…‡††€‚…ƒƒ…‡†ƒ………†‡‡„ƒ††ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoomw}x†pqzprtfu~n{ysoy€}~€{~|€~€€~~€€€~~~€~}€}€€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„†……††ˆ„„†‡ˆˆ†‡„††‹Š…„†‡‡…ƒ………„‚…………†……†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„rioyxpkyszozwvvp€~~~z~}|}~}€ƒƒ€‚ƒ„‚€}~~~€~~‚€€„‡†ƒƒ†„„„†‡†…………††ˆ……†…‡‡…†„††‰ˆ…„‰‹ˆ†„†………ƒ……„†††††…ƒx‹yrˆz{pp…„x…xyks~y{krƒ‡ƒz|mzyyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozks|nv‚~~}}z}{|}}~}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡……………‡‡ˆ†„†…‡††…„……„……†‰Š‡…„†…††…††„†††††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„…†…†„†„ƒ„„†„„ƒƒ„„…„…„…„†ƒ†‡……„„…‡†„„…†……}w†ƒ„„‚}~{|{~{||}~}|~~€}€~~~€~~~~}}}~|{|~||‰†…„†††…††…………††‡ˆ†„†…††……ƒ„…†…„††††…„†„…††††„‡†‡‡†…‡ˆˆˆˆ†„‡…††ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…ƒ‚……†……ƒ…„„„…„†…„……ƒ††…†…„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ‚}€{{|~{||}~||~}€}€~~€}}|€}~~~~~||}~{|||{{~ˆ‡„„ˆ†††‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡…††……†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ……ˆ…†‡†‡†‡†‡…‡‡†‡……†‡…‡†…‚ƒ…††„„ƒ„„ƒ„†„†…………ƒ††…†……††…„„……ƒ„‡…ƒ‚ƒ„ƒ„~€€|{}~{|{~~}||~}~~}~}}~~|}||~~|}€|||}|||~z{{|~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†„…„††„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…‡‡…‡†‡†‡…ˆˆ‡‡…††‡…††„„„…†……„„„ƒ„…„†††…†„†…††……††…„ƒ„„ƒƒ‡ƒ„‚„„ƒ‚€€€{{~}|||~}|||}}|}|~}|}}||||}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††ƒ…†…†††…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡…†††‡‡‡…‡†ˆˆ‡‡…‡‡‡…†‡„‚„ƒ„†…‡…„„„„„…†††††…‡……‡…†…†…„ƒ„ƒƒ„‡ƒ€‚ƒƒ‚‚‚€{}~}|||~}|}}|~{||{||}}{{{}|{~}{|}}|}}~}|zz{{||ˆ‡‚††††‡††…ƒ…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡ˆˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡…‡‡††‡‡…‡†ˆˆ‡†…‡†ˆ††‡ƒƒ„„ƒ††‡……„„„…†††††…†‡††ˆ††„†…ƒƒƒƒ‚ƒ†ƒ~‚‚ƒ€ƒ‚|~~||}}|}}|}{{{z{|||{{{~{{}{z{~||||}~}{z|z||‰‡ƒ†…†…††…„„……………„ƒ„†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…‰Š‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……ˆƒ„†…„††‡†…„ƒ……†††††…††‡†‡‡…ƒ……ƒƒ‚„…‚ƒ~ƒ~~}||}}{}}|~zyzy{|}{{{{~||||z{}||||~}|{{{{|{‰‡„†„†„††…„…†…„„ƒ„‚€ƒ†ƒ‚z„Œ{€„…‡†††…„‡ˆ‡†‡……‡‰‡„‡…††ˆ†…‡„†‡ˆ††ˆ‡‡‡†‡ˆ†„†††‡……‡ƒ„…„†††‡…„„ƒ……††‡††…†††…†‡„ƒ„…‚‚€„ƒƒ‚}€~ƒ~€||}}~}{~}|}yyzy{}}zz{{}|}||z{}||}|~~€{{{|~}|ˆ‡…†…‡„†„……………ƒƒƒ€‚…‚€}|{„…††„…„ƒ‡‡†††…„†‰†‚†„†††……‡…‡ˆ‰†…ˆ‡‰‡††‡…„†……‡…„‡ƒ„…„ˆ††‡……„‚……†…††‡„††††…†ƒƒƒ…€€€€ƒƒ€|€~~‚€}€||}~}~{~}||yzzyz}}yzz{|{|{{{{}}|}|~~|{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€€ƒ~~~€yz}€ƒƒ…‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ†…ˆ‡‰‡†………ƒ†„…‡ƒ„†„„…„‡†…†…†„‚……†††††„…††………‚‚ƒ„~€€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|z{{{|}}}|€~}||}~|{‡……††††„…„…ƒ…‚€€€€~‚‚}}{‚ƒƒ…†…„ƒƒ†ƒƒ„‚€…‡…‚ƒƒ„„„††‡ˆ‡……ˆ†‰‡…„„„‚…ƒ„†‚ƒ…„„†„‡†………†ƒ„…„…†…†„ƒ„……ƒ…„ƒƒ~€€ƒ|€}}‚}€~~~~~}}{|{zyzzyz{|yzz{{{|z{{{|}}}}€}}||}€}|†ƒ††††…ƒ„ƒ†‚…€€€~‚|~~€€‚‚‚„…ƒ‚‚„€ƒ‚€„……‚€‚ƒƒ„……‡††„…‡…‡…†‚ƒ‚‚ƒ‚‚…ƒ…„…†„††‡††…‚„„ƒ„………ƒ„ƒƒ„‚„„€‚‚}~~~„~{}|€}€}~ƒ}~~}}~{~{{zy{zyzz{yzzz{{|z{|||~~}|}||}€~€†„……„‡„„ƒ‚†‚ƒ€€~~€}~‚|}~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡†…„ƒƒƒƒ„……„ƒ‚ƒ‚„ƒƒ€€~}}~~|~ƒ~|~||€~‚~‚|~}}|||{{zzzzy{zzzyzzz{|y{}{{~€}~}}}€€€†„„…„…‚„‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„…ƒ‚ƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚€…ƒ~€~|}~}|~ƒ}{}|}€ƒ}}€~}|||}{{zyzyy{yzzyzz{{{z{}||‚€~€€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌËËËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFK=8765999<>9?<C:;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÔÓÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937677=;>:=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<:<<98:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA>;A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÔÔÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9>CE?<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÑÓÓÓÓÓÓÓÓÓÓÓÓÓÎÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø×××××ÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖ××××××××ÖÖÖÖÖ×ÚÚÚÚÚÚÚÚÚÚÚÛÜÜ×ÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILN@99:4;A<7=9AC>@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌ̈́mpppppppppppj§ãÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¸ºÑÔÔÔÔÔÔÔÔÔÔÔÔÕÉ»½½½½½½½½½½½¾´ŠŠŠŠŠŠŠŠŠŠŠŠ‹‡½æáââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVM<::77>C>8>:??A=?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÎN&+++++++++++"ŠôëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§£££££££££££¢§ÏÓÒÒÒÒÒÒÒÒÒÒÒÔ¿¨ªªªªªªªªªªª¬›SRSSSSSSSSSSSKªòëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;?C>6:7>?;=B?9<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÍÎR+11111111111'óééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤£¨ÏÓÒÒÒÒÒÒÒÒÒÒÒÔÁ©«««««««««««®XWWWWWWWWWWWWO«ñêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;?@@8:;8<;;<?:;;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÏ\9===========5“ðççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©©¬ÏÓÒÒÒÒÒÒÒÓÓÓÓÕ­¯¯¯¯¯¯¯¯¯¯¯±¡babbbbbbbbbbb[¯ïééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB>;=:9;:==;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÅÂÃÃÃÃÃÃÃÃÃÃÃÂÉÐÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÎÎÎÎÎÏÎÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÒÔÕÕÕÕÕÕÕÕÔÓÓÓÔÓÒÒÒÒÒÒÒÒÒÒÒÓÓÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÔØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<7@A<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÏÐÐÏÏÏÏÏÏÏÐÔÐÐÎÌÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÎÓÔÐÏÐÔÒÏÏÏÓÒÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÖÕÖÖÖÖÖÖÖÖÖ×ÖÖØØØØØÙÙÙÙÙÙÙÙÙØ×ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?79:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÎЦ’ÅÓȔ§ÒÑǒ«ÑÎÎÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<>B>BC@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÎÒª¬”Éš¬œ°Ñ™¬š²ÒÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?>;7:>9?D>@98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÐɗ™…¦§—ˆœžÄ’†œÎÏÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<<:6?B@B9647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÏѤ°½—¢Àɘ˜Å¼É—™ÆÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8E@?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÏÏÐÕ¹˜¦Ö”–ŸÎђ™ ÎÐÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<>=964:99::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÏÏÐњ»³ŸÃ›Ú­£¿žÕÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:<?>=<9@<<::9?@>=<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÐÐÕ§¤ Ó͊’žÇˈ•žÈÒÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CFCAB8;?<=;<<8558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÐÒÀ¢ÈÕÍÛ¥™³ÐÛ£™µÕÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF@HIGE@<<>><=><756:969;::;8@?:<<9<>=;;:?9?:;9=>=><;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦ÓÔ¤ ¸È§š ­§˜ž»ÕÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;557<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡ÈƦ½•”Œ§¥¨ ¯§¢©ÐÓÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKL@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ Ôʎ“—¨¡’ºÕš’Ž¾ÖÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<=?GFGKH=657:979:;:<=9>99:8;=>>A>=9<<:=>>:=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÔ¯°³ÒÔ¹ÇÕÓÓ¹ÈÕÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?AELLA>775;8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÔÖÖÖÒÒÕÔÓÓÓÖÔÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEJ>>786967899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9699:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EIKAALD??;9889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEHIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDI;AA;<886486987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGJB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<BA<;876797799=?A?<:9@?<>B?:8776=??@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE>;HF89757875898;>>=;89A>=@?A>7596;>AB??@@AB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCEEC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELCA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<<DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGHNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAC?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€iixsg~‰‰xp‚†{w}~…Š½ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€‚wt|„‚}sp€Šx‚yƒÈÞÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsnupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿¼½¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»º¹¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjcmgb\XQPQKTJB:IQ?A7<94:565455688686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸¸·······¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µ¶¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸¸·¸¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶·····¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨§¨¨§¨©©©§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸········¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥£¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§§¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©ª««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¥££¢¢¢¢¡ ŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž£¤¡žžŸ  žœžœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=7789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥¤£¢¡¡¡¢£¥§¦¦§¬¬§¦ œ›¡¡ž›ššœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¦¦¦§§¦Ÿ›š›¢ š––•š›š——˜™šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜—™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥¢¢¥¦¦¥¦§¦¦ ›™›¡Ÿ—’“’—šœš———˜›š™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB@DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥¦§¦¦¢œŸ¡Ÿ—‘‘”—š˜–––˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;<;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¥¦¥¥¦§¦¤¥¦¦¥¥£  ¡¡ ™’–š™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šžŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡ ¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢¢¢£¤¤¥¦¥¤¤£¢¡¡žœ›•“”˜›š›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œ ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸŸŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::78:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸ   ¡¢£££¤¤¤¢¡¡ž›š™˜™™˜™™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢ ›ž ¡£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œž››œŸžœœœœŸ   ¡¡¡  ¡  ¡¢¡¡¡¡Ÿžœ››š››œš™š›™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥¤¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¡¢¢¡   ¡¡ŸŸŸžœ™™¢››œ›š›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›šœšš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>99;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤¤¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ žžŸ   Ÿ ŸŸ    ž›™œ±žš›œ››Ÿžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›ššš›™˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9<<>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœœœžžœ¤¢Ÿœš™£¬žœœœœœžžœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:=>:?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››››œšš››©£›ššœ£‹žœœžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™˜˜™›š¦¢š™›ž—tžœžœœœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›š™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š›››œœœ˜˜™™š™£ž™™›¡Žd›Ÿžžžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ›››››››™™™˜˜˜¡š—šœ£‚\˜ žžžŸŸžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ››››››š˜˜˜˜˜¢•”›œ£xZ¢žžŸ Ÿžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_^]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜˜——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜˜˜——¢‘Ž›¡q[…¥žžœ››žœœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±³­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=:F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œš››œ›˜™š˜˜™›šš–Œ’Žˆ™•œobvž–•’‘’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨©¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‹‘‹Œ‘ŽŠˆ–~‹ŠŽthi‹ˆŒ…‡‹†ŠŠ‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VQQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹‹†Š‹‹‰‡„†‚€‚‰•‰zŠ…vjd‚€‡}€’†„„…ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹Ž‹‰‰…‚}s|Œ„z‹„…sj`†Šy}|†‹†”’‹—”—’˜¡–ž—•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¥›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ‚†‹†ˆ†„ˆˆŠ„‚z{†‡~w‡€‚og[‚‹‚„…Š‹‘™””” ššŸ¢­±­©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPEMISWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‹‡‹‹‡’Š‡†–ˆvl…~hcXŽŽŠ‰‰Ž””˜•œšž¨®²¯°µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWMO_^\NUUbQDTM;?9<895775795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš™ “—š¡šœ¢¡•¡‹sl~˜ˆe`Y‘‘Ž‘Ž‹˜šŒ”š—œ› ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUKTOOJDPK_bXZQ\T`MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ª©©§¢¥¨©¬ª©¯ ¦‘|{‹šrb_‡—”—ŸŸ¡¤ž›š¤§¤©«®¬¥¤¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdWOXKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®«ª¬¤¡¢¥©§§¨¨©œx{–Ž–xpm“—ž¡¡¨§ ¢¢®««ª§­®¨¥¤©©ª©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_UZNRNPOSe\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢šœ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨§¦¨©§©¨¤§¦™¤¦¢¡ ¤¦Šzfaƒ…cps‹–Ÿš™¢¢  Ÿ ¡¨ œž¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]\PUOXO^ddlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤Ÿ¢ ¢¦¡¦­§¦œ¦œzfVN~{yN_jxš›œ™›Ÿž Ÿžž £™–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvxb_[UYQUW[c^s_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?C?:8:>?C@DA:;>=@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯««¬¨¨«¯©¨ª¨¢ ¡¨ª®±³®«¢¡¬’kQJIwtoEQak£Ÿž¤¢¢¡ ¢˜•ž›ŸŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸ ¡¦¢›—’šš •|wo}yf[[`_Z\V\hdocmjib^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¢ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£ ¢ªª§¯·¶µµ¶³®«¯«‚\HCGrifCFXf~Ÿšœ›–¢§¥§©Ÿ£›ž¡š–ž¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¡™˜¥ ¤§ª©¨ª­¬¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxib[_^\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>AE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢ ª²¸½½¼»º¿´®±¼žqPWMDoa_HDO`o•–“š–£«¨¶­¢£¤«¦¥˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨¨«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥¡¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxxxc[RYT__amhvlphiibZSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶´º±ª®´±°±´µ¶¼ÁÈÀ»½Æº¹¸¼aYŽrCl`_NRWZf‘Ÿ–¢¤¨§ º¦ª«µµ®³ §ª¬§ª©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš’–””˜“š˜Š‹‡€€|‚xa^YTai`ftotitdidb[LK>:9898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÄÇÃù½ÃÔÖÇÀ¼»ººˆV{ªNnngQ[d]\ˆ¬¨§¬¢‹”µ¦«´¼°µ¶¨¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`b_^kcbnxuvnm[bRV\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAA;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–••‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±°§¼¼¾ÅÄÆÉÇÅÆ»ÄÂÕàÚʵ¼¼ÀÀ’P‹À¿a}‚y]JipSz³¸¨œ‚o–°£¦±¶«µ²­³­¨®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|~„ifhaklgnuqruqg^_\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÄ¿ÃÂËÛÙʳÁ¼ÀÆ¥U‚¢¢pœ…|EwŽUk«°”zcq«´¦ª©¨ª­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|~tklndomiqxnyiia\gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÄÄÍÏý¸¸¾Å¯ct{k‹·’ˆ™W{]k…raZ·µ¬®¥¤£¨¤ Ÿ¥™ª´±¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyy{wnkiguZfrxsyff]d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÊÆÄÅË«©­²·žpqm\¤¸ˆhgrhhje^Wh¤ºµ³¬©¢¡­©¬¦­Ÿ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuueeijg]jonxwcb``^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÎÏÌÃÇÆÈÉÈÈÉÇÅË˯—™œŽvpc`ªªŒ‹”p`dga]\XU‹»¼º¼¬­¦ª»º¹·À²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqocagvhiitmxl]d[U`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÌÐÍÇÌÉÂÂÇÂËËÈÇÎۆˆƒyg_M`¡™‡Œ‹se`^XWXUg´ÉÀ¼¾´°°°Á¾¾ÁÆ¿¾¸¶Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`jjvlieuntb]bTWUSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<9>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÄÇÈÆÒÉÁÃÿ¿¾ÄËÈÊËɼ¼ÈÇÉÍÈÃÈÊ´~qj]QPB\Œ‚‚}of[XTUUT‰ÂÀÀºº½µ³³¿¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrpfefcjdbjmno^Y]VVNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾƹ»Ãº¸¹¼¾ÁÇÁÆ»¹ÈÈÃÅÄÀÃÂÁ’^RMHKAUvinsohg]XTVS`©À¸¹»»¾·´°¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfadbacccjbgc[ZZ\YQOE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶·´´µ¿»½¿¹¾ºº´À¸µ·²®º»·À·¼ÊÏÁ»¿À¼»Æ¯nIFDH@MdY`gfbhdYSR[Œ¿¿º·»¾¹µ¸´¸¼´½¸µ´°³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|yˆ}qdabchjfgiei^VVTYOSLF8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“““˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´´±°µ·µ»Á¸¾¹¿¼¼·´·¯®·µ¹¿»Â׍º¾ºÃµ¹Ç·œ`A@E;J\SXaa`gh\RS~´Å¼Á¿¼Ä·¶·´¸¶¶»»¸¶´·ºµ´¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒyqmeefoielhXXNKKKRJLHD9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’™”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿¾¼²­¯¬±°·¼·»½ÁĹ··¶µ¹¹º»¿¼ÐÄuªË½Ç¸¹·­·P@A8LXSS]_^eh]Sa¡ÁÈÃÄžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~‡|knpgqksfbm`\TIKJDJCCG>9;8><7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘Ž˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼»À·ª­¤®°¸»²½¾»Ä¶µ¸µ·¿¾Ä¼ÂÄ׬r€½ÈÏÂÀ·­µ­}O?8MURS^`[ab^UŒ¸½ÇËÇÇÄǽµµ¶Á½»»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†€qflintnxcgb\cQKTHEECGB<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?>??FD@A?>:7?@CC?@=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼ªª£°¹½¼²¼¾¼Å¸±¸¹¼ÆÉÊÂÇÉҖnr®ÒÑÌÊĵº¿®‚L<LWOT_`YZ[Vo·½ÀÃÌÊÇÅÆÀ¹¾¼Ä¿¿¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtolltkln_c^`aNIM?E@?DC;;::;:8;<:9<>::>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´»Åк¾¼Ä¾·¼À¿ÉÏÇÈÊÊÁ„pr¦ÌÌËÍÊÆÂÂɾuGG^PRZbVQR\¢Â¿ÅÀÊÉÂÃÃùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{z‡zmmw|`qc[^__TI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA??ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸´¼·»¹­Û¾¶¾À¾¾º¦œª³·ÄÀ¥vtwÄÆËÈÁÃÀ¿É˦lK]RPVfNJYÄÀÀÁ¿ÊÇÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}‚znsxshp][^]YRFDCMIAD=H;;59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘—žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯··²µ³·¹¼»¶»»Å´m¯Î½¶¹À¼ª}nhnmt‚˜—pw|˜¾¿ÆÀ¸¿¼½Äü¨tfXVcpM[Àļ½¿¿Ã¾¾Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸··½¹»±¶²ÈÀ»¶´±°·¬³©°­­´·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|vlu{pni[__YSPAFHGK@ECH<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿš›œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹ÀÍ°u‚´½µµÁ¤†iY^`NS[\orv‚ ¸·Âº³º·º¼¾º½±nft„o™¿Ä½»¾ºº¸µÁµ¿ºµ®¯­°½À¹ÏÊÉñ°µ´´½º¾ºº»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰|‚zsvvwnq`_f][TJ=??GF=GCC9:5;99><<::<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹ÂÉ¥„xŒ¢°µœjfgUY_IIMQTlu‡¦°·¾¹²µ±»¸»µ¹À¯Ÿvyš­½ÃÅÃÀ¼¿¹³®²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtwrl_cb\^OIB?=IDFMC@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·¿Æ§‡{v¡—_SCYUHbjUNDIdŽ¡¬¯¶ºµ³±«»¸¸´¸Á»»‚u›·¼Áƾ¹¹µ­¥¬³±¦°­¨ž Ÿ¥­¶µÂ·¶´¥¨«¨°¶³²º¶»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´·¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wo{ovrnc]gX]]SOMA>JBAJI@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³²­¶º¯­¼³¸¸¿³yˆmMJ@eYBPx“gLB]‚°µ³µ²´¯¬»¹¸¶¹¿Â·u„®µº»¸µ²±­¬Ÿ¤¦§£¥–™™šŸ©®¹¬««Ÿ¥¨¤«®¯§°¬¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmuil][jT]\PNHDFLBFNF8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹º¶¹»µµ³¸µ•Œˆ…{WEBQˆXIJXxa@V¤¹³´³°±­°¹¸¶»·º¾±¬ª¤®­¸®©ª¬«£¨¡——¡•’•—˜Ÿ¨®¤£¤ ¢§¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬ª¯£¤£¡© ›“Ž“’’™–š¤¥ Ÿž§˜•’”™ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wrxhtsndUacW\QNLH@HQDMC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯²»©˜™”gL?TyqNIIKh~XEX³»±¬³¯®¬­¶¶²´µ®¨¢›››œ§§žŸ¨©Ÿ¡§–›——“–Ž—›¤¨  ¢¢¢¥¥££ ž¥ ¤¬¤¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›©¨««Ÿ¦¢›£œ•Œ“—•–˜Ÿžžš™¦—“’–¢ ¥¢¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦ ˆxƒ|vzcwln]QhTPNGPMLBPQ@>;>49:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¤¬¨½Áª¥½fES¡„PWIK_IX‹`ef„¯µª²´®ª«¯°²³­¥œ–’Ž—Ÿž¡ œ£¤Ÿž¨”›–—Œ—‘—“˜¢ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£žžš—š«¦ª±£¥¨ž œ•“‘˜–•˜—Ÿ˜œ™›¤™—”–š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’}|€uv}mk{dhURdMJHGORNJNH<E@<2?859;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜——–¡¨¬®¶·º¹º··»®¨ ¡© ¬Æ¿ËžNAuœnOmJMcfvt`]bs‘²¯®³µª¦¬«¢›™”•–˜—›Ÿ¡¡›¤žš¤———–’‘‘“š—› ¤ªž¡¡ž¦§ª¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¡¥¢›˜ž¯¨®²«¥ªª ›˜˜˜•“–š“••š–›——˜¡žœœ—›¡šžš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}wx|dyy`bSU`HIJKSTIRQM9?B67<65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—“’œž¤¨®­¬««¯ª¯©ž—ž¥œ¥ÇƋVRKf£Xf}or[Qkc\gb`l‘´°°¸¬¦¡œš”—š™•‘‹“™¢œ—£™š—˜™”™˜–›Ÿ¥¦© ¦£ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§  £±®²°´ª²®£™œž¡™››š˜™›”–›–™œ¥¡ š£¡šœ™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ Ÿž ¥¡žž¥ ¦™{|vvsh‚le[SZZMQJOOULSMB7>B78=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’‘œ˜¡ª¢§ ž§¡¥Ÿœ’›¢šŸª£‹xTjqwvodwvXWb`di[[Vg­®¬¯§Ÿž¢ –“› ›˜—‘’Ÿœ¡£›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬¨¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½·¾°¬±®­©ª´±°¨«¨²µ·³¸­²´¤ ¥Ÿ¬¡¡¢  š˜––Ÿ››˜¤¡ ž£¡ žšœ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚|xujwu]mZQ`HRUHFUVJCMG=KH8F<77;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“Ÿ™¨®Ÿ§žœ¡žš™’˜ž›¡¡ £~n‚p`cWL[RZLLQYRHOMGš¬ª©¤ŸŸ™’‘“˜˜–••ŒˆŠŽ•œž–žš¦  ¨¥±ª§®£«®¶°´²±®¶¸½Àº­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«¯±¹·¼¯³°µÁ¼·½³³µ¢¬¢©¨²©«¨§¨š™žšª§ ™§ ŸŸ§§¥¤Ÿª¢¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰…„~vrmivmhm\X\CWNJGMGCFM<>L>4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜™ª ±¢·¤°¦Ÿž—˜•™žšœ£ž›ˆaW^e`WMQF=?@CD?>BQw©­©ª¥Ÿžž¢£žšœ›”“””˜”…š¡›«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶º»ÀĹ½»¬¯§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¹Â¾¸³»ÆĽü·³ª³­ª³µ¯³®ª¯£«§¶²­¢°¦ £¯±®°¤¥¯£¡ š¡§¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¥ž¦™›¢¤žŸ›››œ‡†{trkktrqhV\QFTIDJPI?EA4FH95<>7;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž  œœ˜šŸ š Ÿ•|_^e`PFE;B>F<>96N~ª³§££¡ ž¥«¥ž—œ”‘™˜”ŒŠ†ˆ†xmˆ ¤¢«¬´¼¶Ã¾¾³»ÁÃÂÅÀ¿ÂÆÆÅÃÈÂÀÅÇÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌÌÌÒǾ¿À¾ÇÆ·ÄÊÉÃÁƾºµº»µ»·°µ²ªº²®»·¿»º«¸­«ª¸ºµ¼®®¹£¦£ž¦¥¢£©¦™›Ÿ˜š§ª§ ¡¡¤˜”£–”™‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ„}zqkchoxkeZ[FKLEDSMDBE7:?;549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ²²¸§¡¡«ª¡œž¡¡›š}riaWNE>IZ|oaA=\Ž®¬ ™››žž™———’ŒŽ–—“Ž‹‚ƒ‚wrqmp¦­®´¹Å»ÍÇË¿ÂÌÍÍÌÇÉÑÌÍÌÇÉÅÅÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÑÓÍÓÐÓÓÌÊÂÅÆÆÊÈοÈÑÌÇÅÇżÃÁ¿¿¿¶¾³®¿ÀÃÃÇÄÇÄ®¿¸²¸¼Äº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›Œ™‰•˜› Ÿ£—žš““‹•…€ytsebgrof^ZYCNLDEPIDC@55589B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>8;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›¢¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¤¨¬­ª £žœ•if\TID@?J‡ž¤˜ƒ ²­£žœŸš—–”’”–‘Œ‡ƒƒˆ‡ƒ€€yqroly¤¶º¹¾ËÁÓÒÓÈÍÎÑÓÑÒÑÐÑÑÍÎÎÐÅÎÔÕØÒ×ÍÆÇÉÌÃÅÊÏÊÓ×Ò×ÒÕÖÓÔÈÌÆÌÍÉÒÍÎÓÍÅÈÊÊÁÇÌÇÉÈƿó³ÈÄËËËÏÇÊ¿¾¿½ÁÇÅÍÌÈÉÀÿ­¯³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›•Œ†‘‹€zruvgcgvidVWQDMF@IQB=B<:22A<E<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<A?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­³·¬®£ž£¢¡›aSLJDC?CT±Ñ½²¯¦œœœ ¤¡š”“•”‰}wpkebhqoq{…Š€upnqtp…³Ã¾ÅÑÐ×ÖÖÒÖÎÔÖ×ÔÓÑÓÔÔÓÏÒÃÐÓÖØÕÖÒËÉÎÑËÆÍÒÊÒÕÖÙÖ×Ó×ØÎÒÊÏÑÌÏÐÌÓпÈÇÊÄÌÌÌÎÏÅÆǶ¿Ê¿ÒÍÌÐÆÉÈÀÄÃÈÎÍÐÑÏÍÊÈ͸·»¨Ÿ¥«§Ÿ˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„|xsvpc`drb]R\IJGAEIJ>;A8=5586;85:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÁűµ¨¡¤¥ ¢ YI@ADAFQw²¯§š”—Ÿœš  ž›œ™•‰wic`__`_^__]blutppolrqu’ÄÈÆÔÖ×××ÓÖÐÕÔÚÔÔÎÏÕÔÔÑÑÌÐÍÓ×ÖÓÕÐÏÒÓÑÉÓÑÈÐ××ØÑ×ÒØÙÔÖÌÏÏÊÍÒËÎÐÀÆÂÈÆÎÎÑÑÒÈËÍÀÊÌÆÓÏÌÎÈÅÊÇÇÈÌÊÔÔÑÕÏÒÌÓ¹ű¥¨µ®§›¨¬¥²¨°³¬¬““ŽˆŠƒ‹„Ž™“™‚…Œ|zqstmacim_VP_JJCFCRM?<>43:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><??=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯­ªª«¥®·¨«·×ÔÕÙÙÑÎп¼Ìɶ¾®¦ª¨¡£ªeC8=>DX‚ª¨Ÿ—•—™šœŸ˜œœ’}pecb__a_^a`_``_`fmppnkorwwœÌÁÒÕÓØØÖÙÑÒÒ×ÏÓÎËÒÍÕÔÑÊÏÌÓÖÒÑÖÍÏÕÕÑÅÑÔÊÐÔÕÖÎÒÐØØ××ËÈÎÄÉÏÌÊÌÀÉÀÈÊÍÎÐËÐÍÎÌÎÏÈËÐÐËÎÊÂÉÇÉÌËÌÒÓÍÓÑÑÐÐʽȹ°®»¹µ«¶°­¨¸­³¾»±š ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…ˆzvopokadnpaW\ZIFFDMXE;@=33<<87865;>@=9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ¤§Ÿ¸¶µµ¬¥¬®¾´°ÀØÒ×ÚÜÖÎÍÊÃÒÏÁÀ°©¬­©¤±yHFB;WŽ¡›•“–›žžžœ“–—”ˆk^^^adb```a``a^__^\bmroostvvy¤¿ÌÕÑÖÔÓØÖÎÎÓËÎÎÅÎÊÒÒÏÇÎÍÍÔÌÎÓÍË×ÖÐÌÑÔËÌÐÒÓÊÎÑÕÒÕÕÊÀÊÂÅÌÂÈÉÃÌÃÅÈÊËÏÊÍÍÐÎÓÌÆÉÏÍÈÇËÅÆÁÆÊÌÍÐÑÆÐÎÎÍÌÐÅÇÁ¸¹½Ã½ù²²¾±»Ãõª˜¥¡˜–’••’‹”š‘””•‚‰†yqrkmg``phYXhVMGLIPQB;C>;68:8::57==A;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÄÂÁ¿»µ²±Ç¸ËÕÕÙÚÛØÌÌÏÈÖÕĵ¯´¨Ÿ­—xlpr{‘šŒ—•“‘‘•–•‹|eabb`]^acb`__`aa`_][]grqqrspmry¥ÇÓÏËÐÐÓÔÊÅÉÉÆÆ¿ÃÅÏÎÇÅÇÍÊÒÈËÎÎÆÑÒÐÍÌÔÊÇËÎÏÇÇÏÒËÐÏƺĿÆɽÂÇÉÎÄÂÇÀÇÍÈÄÌÊÌÏÈÄÄÐÈÆÂÆÈÄ¿ÁÇÌÌÌÏÂÊËÉÇËÐÄÅÇ»ÇÃÉÉÂÏÁ½¼¿°ÁÉƹ½ª°²§¥¢œ˜›£™—™‘•˜‰‚wotdk`^fpa[W`GHHGIMTG?J=64355==48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ½¹ÍÌÆÐÕÕÙÚÛØÐÉÏÏÑÓȶ»»­£¶}hƒ…¤«”Ž–…ƒƒƒ}„„~s_[^^^`^`cdc_\]^_``_[Z\akrrookloo}¹ÑÈÉÊÏËÍĺÀû»ºº¾ÉÆÂÃÀÃÈÊÉÈÊÈÁÅÌÆÈËÍÉÄÂÊÉÁÁËÐÅËÈ¿¹Á»ÆǾ¿ÆÏËÿûÉÇÉ»ÈÇÅÊÀ¾ÂËÆÅľƽ¼ÀÃÅÌÅżÀÉÃÅÇÒÅÁÉ¿ÊÉÆÈÆÐÃÃÆïÄËÇÃÊ·¿¼º´©¬¤¥˜Ÿ˜¬£¡¦›£ ›•{wrtfiZanmZ\XRDLFBGDLDFS@54334?<3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ÊÏÑÌÇÂÃÆÍÎÎÌÕÏÕÙØÙÏËÒÍÍÎÈÁµÃ¾±¯¶l^y}¢‘‹’–†z€……vxurp_Z[]``bcdded`[\]]_^`[YZ\borokilposÇ½ÊÅËÀÆ°¶º²²³²±Â¼¼¼º¸ÁÁÁľ½¹½¿¹ÄÊÅƽÆÀ¸»ÃÉ¿ÁÉ»·»»Æÿ¼ÁÍÃƾ¾µÁ½Ã»½Æ»Ãº³¼ÅÄÂ÷¿µ¶¾¿»ÌüµºÈº¿¾ËÃÁÆÂÅÉÇÉÆÐÆÂÌDzÇÉÃÎÌÁÅÿ½²·°²§¨¨¹°¥­°ª­¬”zvwjdg`hocV^YJFJEGKAEBFJ@9:647854;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÅÂÄÈÎÒÊÊÊÇÍÍÎÑÈÐÆÕÔÖ×ÍÊÎÅÉÅÇÁ¹Å½«­¥_du„“‹ˆ‹„x††~„{ttc\\]^``bcaadeb]\[\^\^]Z[\^hsqmggnory½ÌÀúÀ¸­°±§ª­¬§¸´¶´³³´»µ¾±¶°µ¯²¼Â¼ÁļÀ»µ²º¾À¸Ç¹´»¶Á½·¼ÆÁüµ®²µº¿´Ä·»µ«¸½¾À½±º¶°¶º³Å¼¶®»¿µ·´Å¼¾ÂÅÀÃÅÆÇËÅÀÅÆ»ÇËÀÏÉÇÃÆÁ÷ý½¶¹¾Ç¿¬µ»µ·¶Žytxggebkn^V^`FKHHJFBDAEE?<:565633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÍÈÅÈÍÌÐÌÍÈÊÈÊÉÊÄÐÍÒÏÍÅÇÁÆÀ¿º·É¶ª°˜[hoŠ…ˆ‰zx~††ww|sh]]]]_`_`da^cec__\[^\]^Z[[]_lpnhfknnr|¤ÇÀ¸¸µ°«­§ž¢©§žª¬³­ª¬©´®·±³©®¦¬³¼º¶Ã¹ºº±«µ¹»³Âº°À±¾¼¼¶¼Ç¹Â·­ª¨°²À¶¸½°±¨±³µ»¼«®µ¦®¶¯»²°ª¹°­»®»¸»ÀÀ¾¹Ã¿ÆÃÅÁ¼ÆÂÈʸÅÇÅ¿ÇÃúÄÆ»ÆÉÌ˳¹Â½»³‰svvkiablhYWW[ALKMJEAC?FA:9:995754::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÅÎÒËÃÅÁÅÏÇÍÁÃÆ¿ÄÄÃÃÊÂÉÊ¿À¼Âº³´µÃ®©°‘[j’‡Ž{x}‰…z{„€wn^]\\]_`__dcbdcb`_]Z[ZZ]ZZYZ\enohfgiknr­º°µ®¥¤§§š ¤ šœ¥«­¤¨¢«ª¬«°£¦Ÿª­µ¶±½¹¯·°¨®¸´´¼¸´¼¯¸¹µ²¼À²À¯¥¨£«±²³¨½ª«¨«¬­´³¦¨®¡¤¯©²¦§¨®¥¨·­±²·ºº»²¼¾¾¾Ä¿µÂÁÇÈ·¾¿Å·Äÿ»¿Ä¾ÄÈÌÊ¿¿ÃÀÀ©‡strji]aocWVXPHYRSKFFE>>@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÐÏÌÃȺºËÁ˾»É¶½Ã¾ºÊ·ÁÃÁ´¶¼¶±¯µ»­¨«’dmˆƒ‡‹€z}~xt~|swe_]\\^_`^_ccab`a_^]\ZXY[[YXZ\_fkfdgehjor…ª¥¬¥žœ¡¤”¤›—‘¡£©££Ÿ¥¦§¦­ œ¤¦¬²°¶·§±­¨ªµ«´¹±¶¶®¶¹²°ºº±¶¥ ¤Ÿ¦±§«¨¹ª¤§§¨§²­ §¦Ÿ›¤¦¬žŸ§£ ¡±­­¬²´³´°µ½¶»ÁÀ²º¾ÃÁ±¹¹Â³Á¾Àµ¸¼½¾¼ÂÇÄÃÄ¿ÀÄ ƒxplbf_ko`UY^HNgOTGFKF<=?=:;;825536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;=:7776788666;::;9:;<859<:>>@;Èµµ½¸ºÀº½¶ ž”¡¦º¶«³³»³ÄÏÉËÂƸ¶ÇÀÌ¿¸É·»Å¸³Ä¸³¿À¬µ¼²¬¥¯³­¡£’ir†…†€|xusomjjipi^`]\\\^__acb````]\[\\XYXXXVX[^_dcbegggkmo‡©Ÿ••š¡–›¢˜•ž¡¢§œ Ÿ¤¥¢§ž›£› «°­±µ¤©ªª¬¬¤´¸­·°¬³µ®³µ®°ªŸžŸ£¢²¤¦©¸­¢¦¦ ¨¬«™ Ÿž™Ÿ¥š™£œ›ž°©«§««¬­°²¸¯¸¹º°¶¼»º«³²¹³¾´¶²±¶µ¿¶¾À½Ã»º½—„zsk_e^ddXTW]IW\KPGJJGA<??@;?<04535:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»·ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÆÏÈÈÀÆ»»ÃÃϾºÇ¸¸¿·²Â´±»¼«¹º±¢ž©«§˜žm~…†xrmomkb^aff]]^]]]\]_`abccba_\[[ZZYXXWWWXXXZ^bddeffhikqŒ¨œ“””š—š¡––›¢¡¨žœ¥§¢¥œ ¡›™¯®®¯²¡¥£®«§¢µ°²²¬¨¯³§º³¦¶ ¢žœ£¡­£¢ª¶«££¦ž¥¦£–™—™› š—œœ­¢«§¤£¦­«²³ªµ°²«²¹´¯ª¯²²³¸³®©¬®²¸°º¶º½À¸³±”…zuf^e^[YVSZUK[QKIEHKIB=?AA@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½·½¿¶¾¼¿²¥£˜¥±Âµ¶½­´¸ÂÌÈƿŶÁÀÆηÀĽ³¹¹³¿¶±¹»¬²´¯Ÿš¤ª ”šxƒ„xoqtqhechdc\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXWVWadecdeddhjv¡›““”––Ÿ—™”— ž¡œ– ¡©¤ŸŸ©››«§¯°«›£¤¸ª¡ ®¨¶ª§§­±¤¸°¤· ¢›™™ª¦¡š¬¹¯¢¡¤œ¢Ÿ “”¡”––›˜—–—œ•Ÿªž©¤¢£ªª°­¨´«ª§­³°¥«®³±°°®¯§¨¨²­±´°¼´º¸®£”zvd^aVYXSRSKM^LOKGGLLE=A><B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾¸¼®§§¢ª»À½À¹®´¸ÁÌÇÅÂýŸÈ˲ÁÂÁ­¼»µ»¼µ¹¹°¯°ªœ™¡©”‘Š‹€€|wqilrtphhedfb\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWWV[bcbbcbcdfi•’”‹‘“”š˜œ•–œ œŸ– Ÿ§¦¤¦§Ÿ ¦ ª¯¦Ÿ¢£·¨¡¡¢¨³¢¥¨¥°¥°®¬´ž¡••©¡¢”­±±Ÿ££ž˜›“‹¡”‘“˜˜“——™—ž§œ§¡¢š¤¥¥«¤¥°§¥£««­¦©®¯¯«¨ªª³¦¦¬¯´±®¼µ±¯¯ ’zwrea\Z]XNLQGQaMVPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8847763321./2556;:8;7876<;:;;A8x»»±µ½°»±·¬ž¥¦¬¸»¼Áź±¹µÄÉÉÀÃÆÅǶÅIJ¿ū··½¶½ººµ²«­¨™˜Ÿ£‹‰t‰ˆ~vncafihfgifjm`]\[ZZZZ\]\[\^_\ZY[YYZ[WUXWTTVURTRU``_`a_aacei€’’ˆŽ“’“œ”•–£™ — ¥¢­¦¥¥£¤£ª«¥šŸ¥±ª ¡ž¥ªž¨¢ž­¬©©®­¢¢¢•—¢›œ«©°œŸ¢Ÿž—™“Šž‘’“–˜˜“œ¡£¤¡¢• ¡¤¥›£«¥¢¤ª£«®¥®²©¦¥¦¦´¦©¨­³µ´¹º°ª¬žŒrpo`[WVURFQNHY[ORITKSLEFID8;;=<8667:9;:976977:;:=<<6;<8>598:88659:;<97?<9678452121..1426:8698598989;9@9{µ´­´»²°«²­¨§¯¹¹³ÀȺµÀ¯ÅÈ̺ÁÊÌȵɼ±¾ÃȬ±¸Áµ¼À»´´ª¬¦•š›œˆrˆƒ{tiijlgjkmkjle]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURRNQY]\]]^___bdmŽƒ†Ž™“”’œš£œ›¡©©«¨¬§©¦¤™¥¯¥•™¥¯© œ™› ž¯™œ«³ ¥¦Ÿ£¤¡”“›––’©ª­šœŸ¡ ›”Œ™ŽŒ‘Œ’–•ž¢ £›£•› £¡—¡¨££¨« «°¤­·¦£¤¢¬­ª¨«¯³·³¾µ³«¯˜…tsh[XYSUREXLQ[XMTNPLPQINIB=??A?=75799<<977:79:;<=>;7;;:=67:;8976989:6:=99577571141-+/434988::8::748=8?9~³­§³¶®¨¨¯®›©¨¬·¶¬¼Ê»¶¿¬ËÆŸÁÎÏȳĺ·»ÂÈ°­¸¿·¼½»³µ¥© –—˜—‡zt€vwnmhmmmpggifd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUSSNPQYZZZ]]\^_`d}‹€Š~Š‰’—‘—™¢ › «ª¦¯¬¨°¥©šŸ­ •–¤©§˜šž®—˜¨ª™Ÿ”¥¡ž’‘’‘“•§ª¥š™™žž–Œ‹“†ˆƒ‹’•‘ ž¡¤˜•Ÿ•š¡¢ž”›¥¥¨¨¨ ±°¦±½¨Ÿ£¬´ª®§°µ°¹µÀ±®±ª‘~rsbVTUNRJGVPRQLLWMJLNRGMKACFDC>A75889;9:7::7<=:;@>:9;9:?759:9876958779;85576661320-*.102877;99;8948;8@8³¬¥±·ª¥¢±«ª§©²±¤¶Æ´¹º³ÊŹºÁËÐʱ¶·¼½Áñ¯±·­´´»³´¢£œ——”ƒ€vkglnqnqjpkdege^ZYZYZZZZZZZ\\]\ZXXXYYWXWUUTRSUSVURNNNRWXYYYY\\]ajytˆŒ†‰—‰”“˜›˜ž©› «¦¦¬ž¨š ¦œ“Ÿ£š——…„’›£•£–––ˆ¢››“‹ŽŠš¤§œ••—›‘’‡”Ž‹‹Ž€‹’’’ š ¢–”˜˜•¢¦™™¤¦¨¦¡ ´²§²·¡œ¢¶¬©­¤²²¦µ¼µ««±£‰ysn]NQQLOCMNNPKFNNJJMNQHMJAGKHHC>858889:;69:68;99><8:>9;?8789:886857688974577820301+)-/12876:999984988A7w¶¦¤¶°¥§¤ª¥ ¨¦¥³ª¢²Ãµµ²³ÆƶºÃÊÌƳ¬¹½´·À¯­©°ž¦®º¯®Ÿ™š•”‡{ƒn__frpuqinieghj_XXXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQMMKLSWWVXXXX[]anquoƒ‡ˆ€‘„ŽŠ”‘“ž¡›œ£¢¤™¥—¢œ•‡™šŒsƒ~Ž—–†‘š”ŽŽ{™Œ‚‰Š˜Ÿ£ž“˜–…‚”~~s‰Žz‡“œ›šš‘–Ž££Ž‰š ¡£¤›¢´¯¬¯­Ÿ˜¥¸¦¦±¡°®œ°¼ª©¯ª™ƒwscVMROPNCSNLPLBPQHIMRMHJJDJLFJK=749888;;69;7:<9::;79?9>@79:<89764445874312585/0102)(,-02764789::65:87A7x·¡£´©¦¥¨£¦¥¦¦¦³§¥´Á¸°´°ÉÄ·¹ÁÎƽ³¬ºÁ¬­Ã­§¡¦’¦¶¬£ •–’~x~fWV_gfighncjhgb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTRMMJHNSSSTUUVY[]ijqk~„{sNXr‚—†œ—‹”‘Ÿ˜•”–•–‰€”‰_;Vo|Œ”‰€Œ’Œ††sŠ…—y{†““ƒ•Ž‘ƒ†}“xqp…Œ}‰‘—š˜“‹‰ˆŸ˜‡ˆ–žš¡ —§®©­¨¨ž—­³¢¦­™¬«˜¨´¢©­£“~tn_[NSRWLDTJPLLFNOIELQMKOJILPFII=7599999:7:;:>>8:==7:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9y· £®¡¦¦ª §©§£©°¨§´Â¹°µ°Ç·³½Ï¿¹¯®µÂ§ªÅ©£˜ƒ”œ±¢š˜†”‹‡}su]PLQUYZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MORMKHFHNQQMPRTVXZ`lnhztOB?•’‘}ˆ”„Š›Ž–•‰’ˆ†•†y‰`JQnx‹’„}„Š…n~”xuvx„™oQˆŠ†{~x”vgw†ˆ~Š‰–‹Ž‘’–Œƒ‰ˆ•„›‚„’š–ž”¤£¨©¥¤ž›°ª¡¤¤‘¦ª–¢ªœ¢¦¨‰umf^[HQQSMIUMSILKOIHFJNLMTKQPOFIC<769:8:;;8:;8>?99>=8;<6;;478;6775344696/3/.125221/,')+*,4833979:99::::?9w¶œ£§Ÿ¡¯¡§¨¥§¨¯­ªµ¼¶··³Á»¶¨ºÈ¸¶¨¨µ¶ª²½¦ž•‰“¨–•Š~Žƒ‚}xpnXMKMMNLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDDINOhYNQSTUZnƒsu~ih\T‰”‰t†|…Œ“‚’š‹{†€v€xsovptŽŽz~Š«„y{hv{Žprmx‹’xz€{€vsr’whu„„„…{•ŠˆŠŠ€„‹€”„|€˜”œ–‘Ÿ©žŸ  ©¥ž˜Œ§¤’  –žŸ¤€rha]]JWPRHKXROJLMRJJJLPHLQLRTMEHA<78;99>=:;<98@?::>=7==79937785675251472/2.,//200/-+(().12721987:8775:<;7v®™£¡˜œŸ´©¯©¥­¬°±ª½´²»¸¶º´±Ÿ·º²ª¬©¨²°¡š‘”ŽœŽ‘v†x|vooiXKHIHGEHHPTTTWWSTUUUVWWWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQQSV^t‚{xfv–˜Ž}gyvx€‰}„˜’q‡|w{ok~­}t‹{†’|ufv|…logs|‰Œ‡€lyq}qmvqhq~ŽpC‹„‚ƒ…wwzŒ†}Œ{u}Ž’˜‹’š›£–™šž¡œ–Š¤›Žž—Ž–˜womfbZXXUQJSUTOPNPVKNKNOJQOHNPLFD<;79;::?=9<:99??;8<=7<9999266856633611224.,,-..-0-+*''*.1362/876966527995y¦— ž– ¦¯¬®«¨©±¯±«¼¸¬»¾¸³¬§›°§¬›–œ¥©¤ —™…’yˆŽ‹Šuq{mupjmjXKFGEA@CDHLLMQRPQSTTTUVVWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNOQTX]eprlˆ§ªÀ~tyb{xo|y‰z}‹†omŒ’ytyjj€‚q–‘‹~–€I’˜nhx~‚midly…’†ksl|nr|†inpsŒ‰„†{}~{vott…‚yyp|ŽŒŠ“ƒ–—˜š’–—™—–Œƒ‰ž‘‹’†–€nioooXVXTRQYORTTRXULNHMJMNKCHMGE@:89;99:><9<;::=>:8:<9?868727565541432/024*+**-.+-*(*(',-1250,5567485HA895w™‘›™šŸ¥­°£­ª¨µ¯®¬´¿«¼Ã¿¥¢™•¤—ž„‹”¡¡™˜‘“‹sŽz€†Œ†totkpldljYNDFC@<>>AFFGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_IMOORWZQY\_§ˆbšisye~pmz‹‰v‚ˆ†tlš’ts|jjMy…“‰„Žg1v†sl~~ƒtfeu„„…€filukq|hqq|n’|s}|qpnum‚~wyujyˆ‚ˆ‰ƒ–’’‹‘””Ž—€yˆ—ˆ†Š†€ˆwkkoheXQZWYY[MPUVYXNHHEJJHGB@GDCG=998;9:9<:9;:::@<9:<98>787715234533645031.**+),,++)(+'),,226,,4775478iO8;5n’ˆš‘™–£¨®ž²ž§º¯«²°Â±»Ãǚ–”™‹Ž†y„˜”Œ†q‡‚t‡Œ†yprpoodpf_TFIC?<;9:?@ADCEGILOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOOQVLAIQIb¯³ q{xl}lqƒ‚…z„††yr¡•tx€su”‡5q¨Ž¡¡„¢„vq†|‡|tŒ­Ž‰€ggbjnrmpƒuipXupŽ›’wlz}mrnp€{svnbvƒ†€…ŠŠ‰‘‹‘Œ‹ŽƒuxŠŽ€~ƒ€}{rppl`[]^\YX`_RN[ZXWLHIFJG>BABH?CD=;97=;:;;9:99;:?<88=:8;66651121253474531./,,+)*))***)(*)+/3DM2166643<vR7=7b’’ˆ–‘¤§ž¯•¥´©®±®Á²»ÁƖŒ”€ˆ}n’‰ƒŠ‡†u‚„l•ˆˆ{txxlwnwci^JPG>@7449;;;=>@BEHLLLLNPQRTUVWXYXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL7CMRSDJ†v€||v~lwˆˆ|~…ƒŒ~u¢™y~†…™„šœa†ªŸ‹ƒzwˆ~‰ˆŽsŠ—ƒz]drtz|wŠmhjbyo†‚znwt„zptyxkni]v‡|‡|‡‡ŽŠ’—ƒ…Œ†}q„ƒ}uw{|‰wpstfg`[[^T\f^WPTX[UGJKDKG?F@DC>AA=;97<;;=<::99;;=>79>9985653244004645554-,)+('''&(())((+++/00Uq=23331E~W4=9\ŒxŠ€”Œ‘Ÿ¦‘ ª ±¨¯À±ºÅº–Ž‘”‡z…vkŒ‘‚}Š„Œxƒ€s „Š||p€~zgvkRWL@E211367688:<>AEGFGJKMOQQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMORLKT]YRJh„ˆ{‰y|q|Œz}‰‡~—‡v¡™ˆ‡’”¥¬ªH†®¯¯‹€“Š‚‹‚„’©‡€˜˜Š›tm}†‡}Žhghyn†‡‚…q„†Gl€wryvhmk_v}‚ˆ‡„‹y”œ‰‹ˆ‘zu‹v|xmow}ttrl[^][ccXge\UPPVYPDLKFNICFCC@@CA=978:::;;:888::?>6;>7585773344236656768;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|~‰…ˆ‘Ž–—’— ¬¡¦¸¯³¼³—’‹˜‹}tp‰’~}Œ‚’”}†~†¤‡ˆ‚ˆ…x‡ˆ~s„x_cWKB60./23123668:=>?BEGHJLNQSTUTTVUSQOGC?80,#‡[>?84.]–ps£UFIKMNPW`XpY\^i“‡•€„‚…‘“~…ˆ‘š•‚¡¡˜•››¦­“š»±§»Ç苌¡¥”‰‘|qƒžŸ‘œv……‹ˆihoƒ€u‡„‹q…‚w‡{v…}nvuf€”Ž†‰ˆ‡ˆ‡¡«¢–‰Ž˜z‚‰zyogkx~z~sle^Z[]j]af_YOKNWRQIPJDNGCJDBADDA;:87=<:<:88778:==8<=68656623444576867<BB?<8:>CQ^e\G2'&,,--.1(?‹[.310Oƒ_4?;nupfxƒ{€ŒŽŠš›¤¡¬¦«¯°—‘‘„¡”„xwŒ”|~’…’•Š€’›Žƒ€ŒŠ‚‰ƒ‰mpj]B@4--//./02234778;=?BDHJNQRSRSSTRPOHDB<87/9D><<63.l“—MPHIKKKNV_cggmu›š’“‹Žšˆ’‹  ’£ª¥£¬“©¶¢¨Áîǯxº”š|¡ž™„“…‚¡Ÿ“˜’„‹…š‘–lpu‰‹‚–Œw„qm…Š–‘ƒ…ˆrˆ –†’‰Ž–¤µ©›•¢ƒ‡“ƒ}kjk|€‚sb^d_[gk\ll^WKGORQNLLFIPCDMFACEFB=:97=<:;:987767;:6=:785456344566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYp‚pu†qv’†~—–š•žžœ§ ©–“˜žge¤š~„’‘y’ˆ‘’}Š„˜’‘‚€€‹Œ‰††„ˆ…xx~gMR>/..,/.-/000212467;?CENPRTPPQSQNPIED>;<:CF?><752<?R5HHHLLMNR^oŠ|s} œ§¥¢™¡—¢”œž§ž¨«Ÿ¨¬©ª¶—«¾«¶ÈÈ·ÉÑϾ› pi«©Ÿ„“’…œ¡š›™§‘‘‰–¢ššwz~”˜’¡’–˜”ž{w•’«²ˆ—Ÿ}”›Ž’•˜¤¢¦µ°‘™¨ˆ–ˆlsr|}qh_]a_agd`gf[QEJKPOIILFFLCHLFFCBGEA:85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Ppu`n|awŽ}{”ŽŽŠŸ’—ž–›ª˜žªBD}‡‰‡˜x‚ŠŽ|Š†Ž‚€‰‹Š„’…ƒ†‰€†v^bP460-1/,.00//..0015>AAMQRSQRSTRNSLEE@<>=GG@A@8662<9;FHGIJNOQYm…w•Š£§ª´½¸¤®¬¬§¨´«°¶²²­»±³½œ³Ã¬»É˷ÿ¸¥£°²¬­ª£‹–˜…¦¦ £—¦™¢«¨¤ˆ…”¤¡ ª ¤©œ±‹•£§·º› £°’¢£ž£¡«¯¬²µ¢”¤ªˆ™‰’Š•yz}…hah\eb]dc^gf_ZODIHSNFHLFJGEFHAKFCFFA;87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLicWjoXz…v“…ˆ‚›ƒ’‘Œ’Úȝ–sV—ˆˆœ|†ŒŽŠŠz‡‚‡Žƒ…Œ…†‡’†‚„‰†ˆ‡‡pna@E64<2/110-,+-1.-3?CAMUQRSUUVUN[PGGD<>>FHCD@8;<5C;=FKIGHROPW’ „®£³ª²ÀÇê³Å¶¬³¿³¸¾¶¿´Á¶»º£¸Å¨¶Éǵ¾¹´¨£´­±±›š’šŸ‰§¯«¥”vŸ¤—¡¬²³˜–ª­¨®¶»²º¬¯µ¢±¬±µ»·µ®µ §§£¨š©¯­²¹·¸§›¶©Œ¥Ž‘“Ÿ†x‚ƒuZbdVfaac_`f_[TIDDLUQHIJDIGEA@@JDBMF<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AFWQJL[ZQbcWyuq”}„†’u…€Œ{¿»£¼‚´”“›„ˆ’‰ˆy†€Œ’Œ‡…Ž‰Ž†€†‰…Š‡‘zxn]V@EM<6:46AB764//6CHCQ\OQUWU\VO^UIKJA@>GKFED;>@7D7?BJJEFWTP^¤­£±´Â¶¸ÁÌɶ»Ä½³³À··Áµ¾¯·t±³¥ºÅ£°Æ¹±³±´¨¤µ¶ª± ¢–š¢’¥°­¦­«§¤˜ ¬´»¢©²º´»¾Ì¿ÅŽ½³Â·º¸¾·º·¹¬¬°¦°ª­½°½»Â¬™º¨”®—˜«‰}‚}kWcbYjejeW[cYVSIGFLQGCHIAHD>?BBK@@MC99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FRLALRWSYUZvjp~Ž„ƒnzsy‡b¸¡™£‰•“–“”“–’‡†{†•Š„Šz|Š‡†|ŠƒŠƒ•}wyueO\dGEL:Qca[^SF?;HPD[cQRYXZgYT``MSPEA?IJHEFA@C<E6B>HGJLSZT]“¯¸µº¸É¿º½ÉÌ»¼À¼·µ»»¶½´º±Æ`u²¥±šžª½ª¥¨«ª£¢²µ¡«¨ž•–Ÿ™Ÿ®¥§¦¥Ÿ£”¢§±´§²³½¶Á¾ÓÉÉÓÆÂÅÌÂÊÃÀ¾½¿»¼·´¯¸·¶ÃºÆ½ÃÈ°ž¹©¡«Ž¤§¶‰€r`bb^Xa_igRX`VQUIEENKA>GD=KA=B@=F>;H@796379>489:57045/26389374426?8@>GKRTSQPOQQPJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKE@IMPRKQ]glkp…slrrs‡ÕÀµ™ •˜™‘Ž—’––Ž†‡}†ƒŒ–‹ƒƒx{‹ƒ‡{‹yŠ‚—t}zkepuY]\Peeb`ed][XW\MemURmm_n_XgeUYUJDBKKHFHHHGBI9D?HKTTV\Z[’¹À¸½·ÆÀ»¹Êʺ¶º¶¸¹²·µ´®¶¶™du¨œ­p^¡­œ˜ ¢›¤žª¥” Ÿ”Ž–˜—¨Ÿ¥Ÿžššƒ¤¬¥ª°­·°½¹ÔÑÏ×ÏÉÌÒÌÏÎÊÆÀ¿ÂʽÁ¼ÁÀÄÄÅÊ¿È㤻°´¯›«¸¼™zl^a\Y]aZccQ\`SPKCBEFE<@E>AHA@D=:E>=J?47535;=468977022/24169775555D3ELM>51/006:477@IOI;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODQ\Yh_o—’”nlouu‡³¬¡¡Ÿ‹™œ™Œ•‘›’…ŠŠ~ˆ†Œ‹ˆ|„s{Šƒ…{‰t‰†•s{xkmu{hreilifjih`fihlZnt–­¤¼ˆ‡g[oh]ZZTHKNOJKPKSQHLAJFKP_^bfib˜·Ç°¸³»½µ±ÄƵ°¹°°»«²±§ª·¬µ§›§šOšŒŽŸ•‘¦˜¥•Š““‰‰‘‘ž›¡—š•–†žš§›¬¯¨°§³´ÔÔÔÖÒËÐÔÕÍÓÏÍÅÂÉоÊÉÊÉÑÇÌÍÂÐÒ¸°Ã¼Ä¹¥¶ºÃ¢‚od]]^Y`XYeZQ]WOOBBGDBH;AC>AG??A8;D>@H=46655;:687654/10146278875367C5B8?-0-1349=97,.,1;FK=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYSeVs˜‚hqoyyƒ ªž¥—Œ››—‹•‘šŽ}‰‹„ŽŠŠ‹‡{„‚pˆ†{‡rƒ‘‹}qxukqx~q{mxslipmcimpxiw|~Ë¿Âߧncwoc[a`JPRUNY^P]\NPNTQUT[nmv‚q–­¸¬³§°¶ª¬¼À°«µ¦¤¸¦«® «´£Ž±­š˜˜Œ‘“‘„Ž›¦‘œ‰ƒ‹„Š‰„‹ƒ“•—–“›‘œ˜™™Ÿž«¬¤§¢¬­ÏÒÕÑÍÌÒÓÓÐÔÑÎÈÃÔÑÇÍÒÓÓ×ÍÒÑÅÒÖÅÀÎÇǨ¾·Ïžzof^b^W_S]ZOPTPNH>@FABE<@B>ED>??:==<<JA45465<888664412/03526768533;=<E=@11+/249>5901022-2DN3)/3.32=N238C}_2A†tD:==I>@CFH<VRMN[u†…Šwlwp}~¡žž ‹Œ™““Œ‹“–„y…‹Šˆ‘‡‚{r~€‡y„u…’‘‰ovrks||w{swqk€sripqzyrz¾Ëš~Œ²„vr„whaj]CZZ[VecXdjSX]\`d^cwz~‹™©¤¤¡Ÿ ¨¥ª°¸ª¥´£¡­¡£­¡§±Ÿ‰¦š“’‘‰‘ˆ”‰j•¢Œ™„€…}‘ƒƒ“–­‹••šŽ†’‘—§°¡ ¡¥¤¨ÈÎÏÈÂËÑÔÑÔÓÎÓÍÆÖÓÌÔØÖÖØÔ×ÕÉÔÚÍÉ××ÑʬÃÃˌsoc`_XTYS\PKGJJJ@;:;DAD<BC>HB>BB;;9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/--;R017/532FD28>nb5=tM99@I<AD?A;PLFKYp€u}hsxr‚‰€•”…‹–‰ŠˆŽ‡wƒ“™Šˆˆ‹‰~ƒxs{}ƒˆwz‡‘–€ƒnxpmuvx}t…|ym‡vtn}v„ux|µŒ<A‹Å¥~Œ|ieVICfcecgjdnx[_fhknin€ƒˆ‘‹ž —˜Ÿ£¤¦²£¤³ ¡¥ © ¢±œ†ž’’’‹Ž‹†ƒ„~œ›Œƒ„…z”~‚©•£Œ’Š—’‹}—Šš‘«³˜š›§œ§½Ãƹ¶ÆÍÒÐÒÐËÒËÉÔÎÑÕÚ××ØÔÙØÍØÛÎÉÚÚÒÕ¾ËÌ´xwoe]ZRVQZWFGJIEE=:79@AB9GD@ECADB;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?1*(.BS39254/7K75<`bA<svV87AH:?C><9QECJTknnpbpqt†|—‘‹~‡’‚‰†…‰‡|x…––ˆƒ‡…‡z„yqz{„†uz…ŽœzŒp|oozq|qƒ‡€nŽzuw}|‚u{†‡°tX©Â¶‘‚pnb=^hrpqpnxveioruxqz‹‡Ž“‘›• •‡Œ“› ›ŸªŸ ­œ¡š™Ÿ¥žŸ«™‹šŒ‘„}ˆ‡ƒ…‹ŽŸ™“ˆ„‡~m™y„˜†ˆ“Œ”Œ†{›ˆ”®ª”•—Ÿ™§®µ½©­½ÆËÈÉÌËÏÉÃÑÊÔ×Ù×Ø×ÔÛ×ÓÙÛÖÏÛÚÑÖÉÔ˕z{ih\ZPST]HCEIH>A==7:=?;=G=?AAADA>>:86DB755479.566435532323647553457EBDCEB56<FNSM[nfcnskaV>,4LG865434BF4=W_hLux^8;?F<<B<::D?CGRk_mdbfkv€ˆq‘š€z€~‚‚„~ƒ||„˜Ž‡‹~††€w‚yn{{†uz’ž vŽu‚tu}t€„oo’„t|€…zv†{‰·Æ¥Âɸ‚–›wpeNfczw†¢Šxyv{ƒ{„um“–”•—ƒ‰—š—–¥œ— —Ÿ’’—£™«•Š‘‚Œ…‰ˆ†‘žœ™‰…‹†˜zˆˆŸ—ˆŠŒ‚|¡‰‹¼¡˜“—šœ©¦¥®Ÿ¨¶¿ÀÀ¹ÇÉÍÎÅÍÊÑÖÕÕÙÕ×ÛÔ×ÙÚÛ×ÛÚÚØÎÜƇ|zhie`TXVUMLDNC;=<<9:<>9=@6=?@<?><9867CA6455=80665547745613854564567HH=DJE7925;H>;::7IP]ZRUXK9T>;95327I8=NYMHxxd5=>C==@:6:>>@EQ_Yea][htzyl‰’wvzŠ{~€~|…{~‘‰„…z„‡{u}tm|}†~s~’‘žƒ‘|†~xŽ}yŠŠn‚š€t˜…}ˆ…{}z©ŽÃ ¼Œœ£œ}‰„}‰rŒŠ~s¦šœ˜“…{Žˆ„hGp ¤Œ‹’…‰Š‘’•œš’”‘–‹•Ÿ” ”‘‹~ŽŽ‹„‰’–šŸŸ‰Œ”’‘‚‹¥™ˆ„ƒ…„¥‡‹‹¸˜‘”–¢§¡ž£¯¶ºµ¬ÀÅÊÐÈÇÌÏÓÒÒØÒÕ×À×ØÙÛØÚÚÙÙ×Û¸yyymjfW`\TPOHCLB==>99::99;<6?>><=9:;;37D?8378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWN<MTHN?96333>C;[X>5YypZ<<A<=>8589?=DRSRX^UXfmmmiŽŠqryŠ{z|{ˆz|{‹‡‚~uƒ…yszsm€~„}w…›¡›”’€‹ˆ˜‡€›’n‡¨…z ‹|‘Ž‚ˆƒœ}š‘ŠŒ£¢Ÿ¤® ‹‘‹…‹’†Wr­‹Ÿ«›ƒ˜›[‚¢‘‚ŒŸ“•Œ‡ˆŒ’’Œ”””ŒŠ‡–›•–‘‹’“…€‹ˆ’ŠŠ–™¢¢†’– Š‰ˆœƒˆƒ‡…¤†Œ³˜’”—¡¡ž™’œ§²¸¬¦½ÂÇÎÇÆÏÌÐÌÎ×ÐÑÔ®ÖÕØÚØÚÚ×ÖÙٟq~uhg^]XTWXC@HC>>>:49:;7:;:3;;?<>7;9:1:H>:37=@50677255?65;55858:57735HR7GOK994=EJB>1FCLB98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:;@;BQKKSYPTcbxmb~’ƒomw‹xyz|†{{w†„sp…‚zuvvt„ƒ…}’¦£Ÿ¥¢–‰”—‹Š¨—rŠ±Œ„§‘„™“…™Œ¢– ˜“‰›¢’©¯Ÿ‘”Žˆ•‹n·…šÄȲœ¡¥›œ˜–²d¤Íǖ†‡‰’Ž“”‰…Š‰…–š›”“†”—ƒ‹™ˆª——££ˆ™ž—›ˆ‡——Š„ŽŒ‡¥‰“©š—“–™¡™Ÿ™“›¢³´¥£¼À¾ÈÅÅÉÈÉÂÊÓÍÍÔ©ÒÑÖÖÖØÚÔÓÚσs€id_^^NKTZBAGC;A=837;<:8=649:<:82?9:2:I:=67BC32:96264>=4;>6949;57944KQ<JQK9A7BGI@64JELF><88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBcFu‚Ž||l}ˆxz~zƒ~vv€ƒ|ln‹y|xx|„‡‹}Š£³§£ª²¡–§Ÿ¥¤–•®¢ƒ·•’³™¡ Œ¤›¯¢¤˜§–¨™­¯¤—”–”‹˜™– ÀŽ£É¸«š¢¦­˜‘šœ²†…¨¢œ˜…ˆ‰Ž•‹“Žˆ†‡ˆ’˜”Œ‹““†”˜†ƒ‘œt‘™²–—¤¡ˆœš“Š‹—š‰Š–Ž†}Œ˜ŸŠœš™“˜˜Ÿ” •Ÿ›¡±®£¤·½´ÅÇĽÃÿÆÎÊÉÒ§ÎÍÓÒÐÖØÒÏØ»s{w^aVaWQIIOEABE5>:76:?;<7=42669774=5<5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=89567=:JFDGN[\YIf`;H„‹zzm…†z|„x€…€}px|}|orz}{x†‹‰…ƒ’§»­¨²½¯¤­³³¨£¢°¬Šš´£¸¤•¬¤–©­·¦¤£Ÿ™©—©£¯°ªš˜œ”•‘—Ÿ—™»»­É i¶¸«°”˜ž£«’—½£^ª²‚‰Š”‡‘|ŽŽ}ƒ†”•ˆ‡’–‹•ŠŒ—˜’š³–•«ž‹›”’’Œ™›Š’ž‹‰•Ÿ¢•˜š“œ™ž”¡ ”œœ¥¯¨¢¥³·«ÂÈĵº½»ÅÈÇÂÑ¡ÆÉÍÍÄÖÖÐËÔ¢q|i^[T_RPFD><CAA8?874>F<<6<35355454B3::BM:A;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPeGb`bpI@‹Šs†‡}ˆu‚Šƒm}}|pw†w‡{Œ†Œ™ªÂÀ¯½Æ»²´Á¼´­«³¶Œ¨²®®½ª›»¤¨­¹·«¦¦¢¢££©¯²±ªœ¤˜š——ž¢¥¥’£¹®¨¿»¬­²¹¥£¦}ˆ†œ­½°ƒ‹Œ‹ƒƒ‘z‡ŒŽœˆˆ—‹•—”‘š–§š±š‘«Ž™’Ž•–—Ž‘ ‘‰•›£¬”–”œž” ž›˜ ¡•šž§§¤¢¤°²¦ÁÇ𰺶ÅľͧÇÃÇüÕÐÍÄʈtsc]Z`[NKBK@DF>A?B;:4>A==5=6>333242A17@BN>G@CNCA=C=;86CC5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GE?CF\fF`igZ][“ŒŒˆ{‡‹‡ƒŒu†Šo~|‚q~z•z‘””˜“•§´ÆÉ¿ÂÌÁùǼº¯«¹»—²¶º²À®¥À¤ª¯»»ª­«¢¢ž§«¯µ°ª›Ÿª›¡›•ž¯³§‹¢º¹µÁ»«¨œ²¤£¨“…©ÃĤ‚‹‡ˆ„†•”zƒŒ‘Ž‘¡ŒŒ”‘‰—Ÿ˜“™”—¦ ®ŒªœŽ•’‘••Ž•‘¡”†—Ÿ ³ž”š” ¡™¤Ÿš › ”˜ž¦¤¦§¤¯­¥ÀÄ®¨·µÉþ¶Î²Å¾Ä¼³ÑÉÈÁµuym]Y\jSMICLKJJ@A=BD<5AD;:3=8B332262A05IEM>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBf[Me\fTcj™—Š‹ˆ“†‰y†“r€|x‡‚‚y¡–¨šš˜º¾ÇÈÊÂÒÈÊÂͽÁ³¬»¾§º¿½»Ã¸¬Á©¬³»½ª°ª£¥£¬­´­¶µ Ÿ®ž¦¢˜£³¼©›¨¼Á£¶¶¯«’¯¬ª«–†™©¦¥‘‚Œ“¥•‰uŠ’y…‘Ÿ“”‹”£™—›””£ž©Ÿ‘¥šŒ•–ˆ}•’’£›• ¢œµ¦Ÿ–¥¤£¥žž¦˜ž•—›¥£©¨¢²¬¨¼Àį¥³·ÌÀ¹®Ã³»¾Â¸¬ÂÂÁÀ™nzbYW][LKMJGDCIBBACK:4DH9;4<7E.12352B26SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQF7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>kI_XaZddVž—Žž’‰ŠˆŸ“„w…•~ˆŠ•¡š®¦£˜Â½ÈÃÈÅÓÌÎÍ˻·¯º½´¼Ê¼ÃÁ¶¶¼­³¿¹¼®¯¨ ©§¶­®©²·šž­¢¨¡ª··©¤¯¾Ã±½¹³§©³³¬­––¤«§ ‘Ž’±Å§•Ž|‘•}‡‘™ª™˜“““•“¥ž“™“¡£¢œ˜Ÿ™‹žˆZ——’–¥šf˜£Ÿ³¥–¢–¬­«§›Ÿ¦—˜–™•¡¤¨¦ž¶«©º»Äµ¥´¶ËÁ¸©¶¬³»¸®¨¸º½¸ƒno[XUVOFKSNK?AHEDHFG85FM;>7>AJ.32025B55OVN;LFKRLOGGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|hW;=@BFBrFiIRebLF¥”œ–¡—©–ƒ‡¥’ˆ‡‚œ„ƒ•”Žš¢Ÿ¯¾®¡Æ½ÅÄÇÆÎÎÎÒʾ»¶±º»¼¾Î¶Ä½·¸·²²µ³·³¬¦œ««¸ª¨§¯°—£®¤§¤¤´À°ª¬³¾Â¹À¹³§·³·²®•¤¬®®¤‹“•¡tÁš}–™„Ž–š‹±•š™•’“™™¦£• ›–š¨œ›¡ ™‹–`J–œš”š¥—T–°Ÿ¯œŸ¥”¯¯¬¥š¡¥”“™™Ž §¢™´©ª³¼¼»«°²ÇÀ¹¥««­±±£¡²²´¤qof\[OQLEPPPQ;GKHFHBC>9KT?A:=EM07544:B34NWO<JKNUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@CAF3>58JKCA=C;4EA:A?>H@5*B52,>c]g:35tde@R7&#3}iX;:BC@=QEWRsbWFH«—˜ ¢¨¯™—‡‹§–Žˆ’…Ÿˆ„—Žž š£¤µÈ´©ÆºÃÃÈÊÈÇÌÎƾº²®¹¸ÀÁ͵ȺÀ¹µ¹±¯¯²´§£›ª´´ª©¦®¬™¤®¥¥¨¬º¿¨«¶¶¾Á¿¾¸²²Â°¸¼«£®´¬¸¥ˆ›—¦›v¾ „˜œŽ“™š‹¯–¡œ›—•›Ÿ¡©ž¨ ™š©™¡§ž—‘ƒnv’¢š•¢Ÿ­²£«•©ª˜«®¥¤ ¤¨’’™œˆ”œ¢ž—±§©«º¶¾³²­½¹¶ £§¨¥§œœ¬©©Œdfa_RKLGGNJVL=MDMIKACD<PU<AABDO18=77?B75UXN?HNQXRPQTJQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW;:=..SaMUHe^HE«•œ¡Ÿ»®™”žŒ“ª›‘’“‰ª‡¢žŒ¤­”££¶Æ½´ÁºÁÂÇÈÅÂÎÈÁ½¹²¯¹´ÀÂʶƱÁ¼´º«¨­¬¯£¢™ª´»¦©¦«ª¨¯§¤ªª½¼§¬¼³·½Æ¼¶µ·À¯½¿³¨´¶«¾¥¢—‘¢Ÿ¼Ÿ‰™ ™–ž·Ÿ©œ¥£›œ¡š¨¥³¡›¥œ¨©ž™•”›‹—‰Œ¤¡”œ¢ž ´¯¥¥“°«™«¬žž¤£©‘•• ƒžŸœ•©¥¢¡´´ºµ­¨´²²žœ¢¦š—•™ª¡žwa^`^JIFHMQINEFFBRKIADG@VRDH=AGQ1;B7:BF79\YKALPTUSMWRNUJD@JJNO9C?5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-1:g\FCCœobGE§—¤ŸŸÃ¬œ—¤—™©œ–›šª––§¦•­¬™¢«¶Ä»¾·ÁÂÀÇľÍÇ»½¹²°¸³¿Ãȵ¿¯¼¶º·¦¤««¬  šª«Ä¢¥¨«¦ž«¯«¢©¨¾¸¦­½°·¶Ç¶µ¹¸¾°¾Á¶´²´¯½£–£–“›”®Ÿ¡¢¥££Ÿ½¥©©¬¡›¦Ÿ½¢™£ž¢©«¡—•ž“ž‡„“ž¤ µ¬¦œ•²§™°§Ÿšªž ™•Ÿ„Ž¡š›’¥¤š˜¬±¶²ª¥©­¬œ˜ ¡’Ž–©Ÿ”idZa]OJGKOLHEDIA=OHA;GIH[ROK=HOU4BF9>HG5Cb[KCNRUWVQXTRUH@8QQPM:G@4CHQSIC;C>GVKC@O>K<06;GF>;FA56?9:?9;15D0-,0Mv\4KZ5,MnW<-=)#zbQ5CKQ9oRF<KxecWL¢š£›žÅ¬¡Ÿ¬œ®Ÿ’£ž–¤ §©«—¶°£ª²µÄ½¿¶À»È¾Êȶ¸µ´±³´·Áƶ¾°¸´¹µŸ¦¬ª«žŸ¥¤Á¥ ©­ ¤©­¯¢¦§½µ¥±¼·µµÃ²³·¹¾±ÃÀ··­³´µ¢œ¤•‘“ ­ ˜¡¨©«¢šÃ­©ž¬­››ž™¦ ½¡¤˜«««¦¡™šŸ’ž‰ŽW•ž¥¡ ¸ª§“˜¶£Ÿ³¡ ›¯—žŽ™”‚Ÿ—–Ž¢¤•¥®²«©¢¢¥¥–•œ™‹‘“¤Ÿ‰be[d`LIJJOFEAFK>=JB99JKN]QQI=LV\9FI=DMI8Hc\LCLPSYYVWOZ^IA=WQIK?H@5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+w`S6SZkWsHE6=ue\KNžŸ¡˜žÃ§¥¢³ œ²§“«¤ £Ÿ­©¬»°¨¬µ±ÈÃÁ³ÂĽÆüÅʼ°°¶®°µ¯¿Åµ¹°°ºµ¬š¨°©©šž¦¡§Â­›¬°œª¢®°©¤§½·¦¶º¼®¶Ã­³³Â¿±Æ³º¶«´µ­©¡¥••”£«¡žŸš¨«°®¯»²¦ ©©™™—“¢¤¸ ¡¤’®¯¬¥¦Ÿ’¡ž•ž•™£Ÿ§´¦§˜´œ£¯šž›®‘ž”—”š€’¡•ŽŸ¡“‹¦¬°¥¦¢œ ž“’š”…‹’œž€bf[heKILJSBC@HG;;F?99NMU^RSJ>O^^=HPBLLI9Nd]LELRTY[SUO\bHA?ZQAHAKB7FELKN>;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<v]^?[U^fr@8<H–weA4Ÿ¤Ÿ› Â¨£ª²¡£µ©•²«§¢¥²¬®©»²¬°µ´Æ¿ÄĵÀľÊĶÀȵ«µ¨°¸¬ÀÄ´·®¬¶¹¥™«²«ª—Ÿ¦—­»µ›¨°›­Ÿ®´±§ªº²§¹³·²¸Àª·²Â¼³Å§¾®­·´©§«¡––‘¥¤¢¢—˜¤®¸­±µ¶ Ÿ¨¤™”•“£ ·¢¤¥–­±²¥ª¦¡žššš–˜¨ŸŸ˜¢ž¯²¢¦—®™¥¬—™ž¥‘›Ž”˜š…–Ÿ”Œœž”‹©©ª¢§ ™ž–Œ™†–‰”Ÿydi]liNPMNT=CAMC::I@77QO]^RVQAW`\BJSHVKH:Ud]NFON[W[RPQX]GAB[PBG>NC9HGHNP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1[bZ33806p[bH05JpiVCWFŒyfC;¤£¡¦¿¦§¯¯ ©µª¹¯«£ª´·±°¹·¯¶¸·Ä½Ãǽ¼ÃÁÇÀ¹ÁÆÁºª¶¥­»­Á÷¸ª­²»¢•­°­²–¥§‘«¹ª §°ªŸ°´²ª©¶µ¬»¬²²¹·¬¹°Âº½¾¦Âª°·¯©ª«¦˜˜ª¡¡ ‘˜ °¯³«°¹š›©Ÿ™–’—¦ ¶©¥¢¢¯±³«±§«Ÿ›  ›ž¥œ¡—£³°šŸ“¥š¡©š•¢Ÿ–˜‰”˜“–—“ˆ›™”©¨§Ÿ£›—›“‡Ž™‹~–…›kimamnXQQZTACET@;;HA7:XPd^PVWDY^^MLRN^KJ>Zd^NHPN[UYPKSWZI?DXPDF>N?=IGGQPB=CFBM?:2D?77547?=95E4+75/251.-.,1>*'+=\p=>1.1e[d@1647gY`F(?8l}h[V:‰{cC=§Ÿœ¡©½¡ª°ª£±¸©¥´³«¡­µ½¯³¸¼º½¶¶À¿ÉĸÄÂÀÀ¸Ä½Á¸¯¶¨«·²¼¿¿´©®±·Ÿ—«­¨­—§©§»Ÿ¥­³ž«¢±°³¬©¶³µ¼­¯±µ¬°µ±ÀºÄ¶«¼¯±¸«¬©¢±¥ž¤©Ÿ£—™Ÿ²ª³©ª³™§›™” ¦¤´®§¡¬¬­±§²¬²©¤›Ÿ¨£”¡˜›¨µ©—™’’ž™ž¡ž¬Ÿ˜˜†•˜‹šœ“Š–—š—¦¥£ –•—”€”…{’ƒŒ–flrhpr_GYfVDCNXDZ9HB6>]Qh\NY]G[^]NMRXdJJC\b`PKMNXWXPJVVWL=EUJEDAM?AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,+%2+*5K1.'_^aU150=`V^8)C3YU\gK5ŒzfL@¤š ¤¬·¤¬©¥®®¶©¯³¹¦¦°·Å·±¶¾Áµ´ºÅ¾ÌŹÃÀº¿ºÄ¸Á¹²µ¬ªº·ºº¾µª­±¶™˜§«ª«›¬««¼¬®±£ªŸ°­³®®¶±¹¶©­®°§µ¯³»¼É²ªµ´±´¯®¦ ³Ÿš¨­ ¥••š™±£­Ÿ¥¯–¡¤™™’¢¥§²©¡¦±«©µ¥®°µ¯£™­§š—ž™™«¸£—“‘˜œ¡˜—”¬Ÿ”“™š–Š”“žš¥£¢ ™–’“–{‹…{Œ‹ƒ‹’knxnu|aF`jYIHYZ={JGE6AbTiZM\aJ[]ZRRRb`LKE_a`PLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`Va.5(C^Q\.*B/JGP[H3cYUKD™– °¨±©¬¥£®®µ©·´¸£«´·Ê»´»º¿¾´´·ÃÁÍǻý·¾¿À¸¿½±½®§º¹··Â·«­±¹•—¦®«§£²©”¯»¤­²±§§¢²³°²°´±·²¨®«±¦¸¯µ³ÃŶ¨´µ«°­©§¢¶Ÿž¦± ¤”›™”±ž§›Ÿ©©¢›•—¥¥¥·§¢±³«§±§¬°µ¬¤™ ¬¨›œ›”ª¸›”ŽŽ‹˜œ¢˜—¦¡Ÿ–„’–œ˜––ˆ——›¨¤ ’–‘‘—v„‡|…‚„Œnqxv|]Kel\KOc\?b{GI8GgWe[L^bMXYWTXTi]POHa^_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANIg27'FaLV%-B.=EMQ<3rkJDC™¤­¤­­«§¤°²³ª·°¶Ÿ«µ¹É¹®Á»Â·³²µÂÃÏÄÀÁ¾µ½À¿º¿½³Ä¨ª¹°¶·¿½¯«³³œ §°­¥¦°¥ž²µ­«²°¬©¨´¹¬´²µ¬³¬©¬¨¬©¹­±°Ç¾·¤¹¯©­­¥¨­°¥££®£©œœš¯™¢£¢£¬ž£ŸŸ¡ª¦¦¸¥«´´¤©«¨«¯¶®¢£¨ª› ™š’¤´™‰‡‘¢ •” ”“…”’›˜–•‡˜’•™§œ Ÿ’‘Ž‘w~Ž…}|}‡ŠŠqtr~}~\Rdo^NZf]FD–[G:NmXa[M`aNVWVWTYg^QRLcZ[TKGOTSNGIVS\N;P^JBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3Cd;6*HdHJ+:I?3BIS,>k=GH›©ª¡©¯¤¨¤³´±´µ±±¡«­¼Ëº®À»Ç±´­´ÂÃÑÅƾÀ²¾Á¼¿¸¼Å¨­·¬³¸¼À°«²­ ¤§­©¨¤°£ª±ª¯¬°®¯­«³º¦¶°²©²©«¥¥£­º¬ª±Â¹´«¹¨¨¨­©¨±¥©¤¢®ª¨¢ž›¢¬•¤—˜«¡§©¡¬¥¢¬«·±± ¨¢Ÿª®°¬ž¦§¨™£˜˜ §˜†ƒŽŠ‹ž¡‹Œ–œ†‡•Ÿ–˜•†–““—¤œœ‹‘ŽŠ‡…}w‡…‡tsr‰vl_Y`ncQsr\K;„|F?WuX`YNc\MUVUWP\b^SONgXWVKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*35>10485(5/*,.30;),,'%234$,2-860)(1<^J0.IgDF8<B05EKX1@”[?MF•—¬§¢ª²œ©©°¶¬¸µ®ª¥«ª½É»°¾·Â¯±­³ÄÃÎÎÿ¿´ÀÃĺÀ´ÉĬ¯·®²¹À¿³­­«¥§ª°©§¨±¥´­«°®­±¯³¬³º¤¸³¬¬®§«Ÿ£ž°·«ª­º¶¤µµ¤©§¬¬ª­¡¨¦¦±²¤¦¥¡¡«–© “š ¦¤¢ª¤¬¢ž¦±·¬¬¢¤¢š¨ª­©œ¡¥¤£˜ ™•˜“‚ˆ…œ ‹ŽŒ™‹„˜£›’‘›Œ“’’”¢™›š‹‹‹|†ƒ{t€„‚~txŒ¤‡yk^`ngWf‡dN@g’LDbyWbXReUMVUUTO\]aUKNiWVVIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*49?./463)4+*,+.#4.-+&(+79*&6+<-2,&06XZ.0JgAA<<C+:JO^4D†@HHD–’¯¤¢ª°—ª©­µ«¶±«¤«ª©¼ÀÀ¸¹³¼µ¦³¯ÄÉËѾÁ»¹À¿Â¹ÁºÂÄ®±µ²³»Á¾³±®­«¬§¶ª¥­¯«¹¯¨±±®±«µª¶µ§´¶«¬¤©ªœ£³³¨¨¤´´ µ­¡©¨«©¬§ «¬¨¹¶©ª©©¡©Ÿ­›‘¨¡ ¤¢¦¢©œ¦´®§¥©¢£—¤¦§©œ¢¤£Ÿ™˜Ÿ‘Ž™~‡Œ‡„žžˆ…Š‹Ž„†•¢šŽ›‘’‘’Ÿ—™–ŒŠƒt†xuƒ{x~€‰žoqggqx\atˆiO]˜VHmxUdVQbOLUTUQOX[bVHPjTVTGPYUI>IHOQPxLNV=<KD?@A<@CUC9AK=5;E13;97*4:=+-341*8**+*,)*(/*&)%3;,$2)2021%/2Rc02?f=NX?C,>LT_/Ik6QE;•¯ ¥ª­™«¤­¯³´®ª¥¯©©º¾»À±¯¸®¢¶°ÉÇÈÐÀ¿½»¼Ã¾ºÃÁÀ¿¯²³²µ½¼Â²²³«³©¥µ©¥­³³¹¯£®¶±¯±¹ª¸®ª®¶¬ªžª«Ÿ£ ¶­¨¡ž¯³¡´ªž¨§ª£ª¡¡¬­¨½¯¬®¬¡§§Ÿ«˜¯¢˜¡ ¨§ž§›™ª°¨¢Ÿ¬¡¡’¡¢£¦˜š¨¥——˜Š‡•ˆ|†…„¤—…‚‚Œ‡Ž‘„…” —ˆ‘“‘‘œ•—Š…†xt}uxz€zttzi‚‡£ui^el‚ugˆ‹}RWp^JxsSdSQ^MMRZgNLVYeXGSiRQ>BNQaQ:IHLSIqPLS;<I?;<=;@@W<<>H73CB15:93-5::)-31--6)(+-,52#2)',%.;.&1.0-14%,0Mh:38_=ad?F1CP[[+HO:VB4Ž±Ÿ¤¦«£¦¤¬¦´³°©£°§ª¸¾À¼°¨¹ª§®°ÉÆÈÑýÀ¾¹¾¿¼É¼Â¹°°µ²º¼¹Á³´»­¹­£µ¦§¬±¶¹²§§ºµ­µ¼¯¼¥­­µ«­œ©¯£Ÿ¥¬ª§œžª³¤³¨šª§©¤©£©¨©½¬´¯®©£ ®›š²£•¤›¤¥Ÿ¤šš¨ª¥žš©¡›‘š ¤˜–©©‘˜™“Š‚…}‚€ˆž†~Œ‡‘„€“›”…“¢Œ”‘‹‘›“•‡‰~€rzy~|iw}zuqq}h†y„ˆd`hcs…zmgy]^UBWzlTaPRYKKMpt]HZ[gYEVfPC>KNDCA9HGKS?jaIQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11&/>KI1%90%,,09/,,+6'17#-/GjI14X=fbAJ7GS`U*=;EZ?*“°™ŸŸ¨¥¤¡«¤·²²¤¨°§¬¸Á½µ°£¹¬¨¨°ÃÉÉÌÁ·½Àµ·¿ºÈ¶Ãµ´³µ²½¹º¾·­¹¶¿­¢³¦ª«¯µ¸´ªž»»¨²¿²º ¯´¶©«ž­°¢œ¥¨©¢žœ¤±¦° Ÿª©§¢ª›£¨ ­¼¨®°®¡«¢£®žž¬¦—žš¡£œŸ›š£©¢š™££•–“ž¡–›–¦¬‹ž‘‘Œ‚‹€Ž{š”‰|‹†Œ‰…’˜‘‡”£Š’’‡š“ˆ|yl}vyxb{zqppsxitjƒgdhaosŽmbjp`oA\xkU^NPQJILSZWM]^mWDW`O^PHMDF;7HEKO<rhJK9AE;;==;;=J49B<3;G<4?18-78;2(09/,5..=-*L>*49&'.34.0+/4&,:$40AhZ13S=e_DL6KVdO)<2P[=#’˜«˜Ÿ—§¤¢Ÿ¨¤¸¯®¢¯¯©«¸Âº²­Ÿ¸¯«¨´ºÇËÇ¿·Â¾°´¾·Ä¶Ã²¯º²³À¶»¾¸©¹¸¾«¤µ§¨ª°­¹°©šº¼¤®¿´´¡®·µ§¦§°² Ÿ¤¦§ ¥™Ÿ­¨¨ž ª¯§ ¦—£©Ÿ°¸Ÿ¤±¯¡«¡¬¤›¦¦©šš›ž£•œœš©¦–šž§‘—’˜“™•¡ªš‰‡}‡~‚||¡Œ‰yƒŒ…ŠŒ…ˆ“šŽ‰•Ÿˆ‘•‚‹—}…{sp|qst`yxiopqojsczlifdaf†€`[rjqLMiXZMPLJHPRQIN\_oTDXZRgOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23/:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%53=fd24M?e]FO=RZgH*?0ZZ5(–œ¥˜œ–­ Ÿ¡¤¡·«°£´´©¨¹Å¶²® ·¬­¬°µÆÈÀ·¿Âº±µ½·¿»¿¯¬½°´¿²½Ãº©»»¸§¨¶¨§«°¬³°¦š¼·¤«»µ®Ÿ°¸¯©¥¦¯±›¡¤ ££¡–›°¦¡ž¢§¯¢ ¢“£¥¢·°¡¦±«Ÿ¬¢®˜œª¤¨ž—š¤“šœš¥©™œ›¤””—”œŽ“—¢©¡‰Š…z„}„ŠyŽ—Š‡z‚ˆ„ˆŒŽ…”™ŒŽ–™Š—~†—‹z€zpqvoot_xwelllji„nfrilfi]ds`[kuiZI}][XOOKHGRUF29^^mPDWVYeMHIEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<"8R=*113>D5,-'42*;+139cl84GAf[HTDU]hD.<2bV,2•¢¡—”›ª¤¡¢ ·ª® º¸¦¬½Å³°¯£µ°­­¯µÄļ³¿º¸±³¹¸º¸º¯®À³´¸°¿Á¸¬½ºµ¦¢³ª§©²«­±¡›À¶¤§µµ¨ž²¼©¨¦¨¯¬™£§œ£¦”˜¢²¥™ž£¨©œ¢ “¤ ¤¸¨¤§®¦ž¥ ¨’Ÿ¨¢¡ ˜› ’š›– ¡ª››˜¡”‘”–™“’£¨¤ˆŠŽ…y„{„†}ŠŠ‡z„ˆˆˆ‘…•““Œ•”Ž”{ƒ—Ž‹w~{ltqllsaxthijgfo†ghidfij`ibjg[e{c`SsT\[SKJGIOS@!*i^jLCVU^`KIGEC.:B<F<6KPD8:D357==895?:;4>8@K=>93)8><:9*6@3.E4(+,?0-N?.+-7,1195,&.5-80576`tB3CDg[KWGU`hB379fO'2ž££‘Ž£§›ž£µ­¦ª¹·§¬ÃÁ¶°¬£µ®§®¯·ÀÀ¼²Á·±®²·¶¸·¶­ª½³¯²±½¿¸®¼¼±¥Ÿ¶«¥¥³©ª®ŸžÁ«¨¥°²©¬µ»ž©ª«±¥—žª¦¤‘™§­¢˜ž¤©¡œ¢— §¶¦¯ª¯¡¡¡” ¥Ÿ¡ ™›™œ’™”¥«¡—–”“•—‹˜š¨ ’ˆŠŠˆy…w‚‚œˆ‹‚‰|„ˆ†…‘„–•Ž‘‘‘Œ’{ƒ•…s}}fxokjlguskcgedu€beffejjdkqZ^Y]mdaNhWZ`VJGIKMRX>9_liHBTS\[IHFFA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A=-5B37=+*,0A*JK./*+3722(57$+7.72685]yN2>HiZLZJVbf@:3AfH%5›£Ÿ‹¬¡˜˜ –¥³±¡±½·¡±Æ¼º±±¤¶««®©¹½»»®À²¯®­¶¯³¸³¨«¹±¯®´¶º¶°¹¾­¦žµ«  °¤«®£Á ±£®°®·®µž­¯¬­¢™œ§©¤ž•›¨¥Ÿ™¤¢¨š ›”œ¬°¦¹¨®¢¡šš˜£š¤—ž˜›”™ ’¨–ª§š“šš‘‹”™””™©§ŽŽŠ‰{‚sŠ˜…‡|‰‰„…ŠŒŠ“„“œ’’‘–Ž€€Œƒp€~fxmhkjgqrk\hccsafhjnlgkjgm\lktqaTbhdeZIFLMOXQQVadT@VSYTFHFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24;6#3*)6.55465Z|]19Kj[M[KXdd@A1JeC'4’¡šŽ°š“¡™©²¯Ÿ¸¿¶ ´Â»½¹±¦¶°¨®¤·¸··­»¯­ª«·ª´¹®¦³µ²®©±·¶±³µº§©Ÿ¶©ž©¢©¬›¨¿˜­£®¯µµ­­Ÿ±­¯©¢›œ£«¨›•œ§£š©¢¤–š œ›£«ª©»Ÿ§¤ ˜™™ k¡–˜œq‚•š£€u’©§ž””žˆ—™€–Š¡x†”Œƒnj~vƒql†‹†}„‹†o^cag„—†k‹”“uw‹„~ƒ€g†€huifW\hsnNPjcgr„g_dfnlj^`aŠ„…eNKD8FTg^JGPPTUKHSaoteF[QUPFHFC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,+08>G601.*.*/568,#1'214:176Xl16Ok[N\K[fb>G1Qd=+/Œ£™†•°›œ“¡›ª­ª£½Ä¯©·Â¸½¼­§¶°¥«¤¸³²³±¹­ª§¬´¦°µ£¨¸¶µ¨§¬·³®´­³£ªŸ´«ž¡¤œ¦§™¬»•¦¥¯²·­®¥©­«¬¥¡Ÿœ §¦›—¡¥¥››§§“žŸ˜ž§ª£µ¯£££œ–—˜—£ˆ¡Ž’š‡¡‡“ ¥¦ªž’‘š‘ˆƒrxŒŽ…ˆ¡v‰i—ˆf}rx¡oˆ‡„~|¡  ™€{‡žtˆŽv›Šl‡‚mheczlqaT†mcli˜qXjpo‡X^i[kk[ˆqnzr†g†„Z^FM?G_MFRVVQQRWUg^MXJRROEGG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82).1<I9/01.*/(-4583%&2115>1<8Xƒu25Rk[N\L\g_=K1Wa7/(‹¦—ƒœ«™™Ÿªª§©¾Ã®²º¼·À¿ª¤·°©¬¦²µ®¯³¶«©¥±­¥µ³œ­µ¶´¥§©³±­²¨¯Ÿ«¡²© £¢š¡¢›®´•£¤¥¶¼¦­§«ª¬¨¥¡ ˜ ¦£™™¦¢¤˜œ¤©–”£œ”“¤¥¦¡·££ ¤˜”“˜“œˆ®˜”‰©‹—¢›…±€£¬“™”y‚Ô¨‡•Á›Çyx±¥·—d€Àœ¿y„„y„|‘Êq–¼œÅ{r¶¦»{€l–±«°yhkX±®nei¼’¼nhznrØ~Sjb¶²~r”tš¡ªWOWaOVNFT[XQPRŒ\W\P@\DQNEGI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22BE/.32.+/)-/186- /416A1=:Wƒw21Tk\O[M^g\>L1[]41!¥“€¦©Ÿ—œž¥­²¨°Â½²µÀµ·¿Â«¦³¬¬©§¯³©¯¶³¨¨¦µ¦§¸¯œ³²¶ª¥¤¨±®®±¦ªž§¤±¤¡ ž—›Ÿ®¬”¡Ÿ´º¢ª¨¡­®¥¢š™¡§Ÿ—›§ Ÿ˜ž§§‘œ§š”¡¦¢ °¢ŸŸ£–•’˜’™…¯jjŠª~g„•†­dpœ“™¥”q®¡¤~x»}k¡v±_j´[¥€fœ‘`f‚zfjxk©d¾rg¦Œv±j|±xt’”cmm§m[„ Ehg‡–Euœ`}g|¤§‚Y_‹«i€•xyj§7J¯\WSmc[KNW_\WV;N‰OWW/ITSIDEF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3..53/+/(.0.:5/'$203B/=;U‚v2-Vj\OYL_gY:M5_Y31‘¡”‚¬§¥ž£¥ª²·¬´½¾¯¶Ä²·ºÂ¦¨°«®©©°®£±º¯¤¥®³£©¹¨ž³²°£¥ ª­¯¬¯¦§Ÿ£¢°›¢›—•—š›­¥–›¡ž´³¡«›¢­­ ž™– ¡¨œ˜ž¤Ÿœ™¡§¤¢š— Ÿªž¦¦ ›Ÿ¡••‘–‘š…µ›µx…©™µ™w‡³›·~“•–¨”~k¦z‚†ˆ’”’x«gk±[«{‡”tˆq†€ˆ—xƒ‚‹—Œƒ „°vwŸqkkl|‹N¤XHcc™~ch¦`yruS’‡^P©mcq~‡€bœ.Q¢o[Skh`LK[dX\ZB>±xWXA#MhECDA@A19>88:84;:9<9:A:E::;6:CB8=?KNG:5:AFB@AD<FD;0201;F,0.940,.(/3,>831/2-D1<<S}n3+Xj\OXM_gX7J8aU50•Ÿ”ˆ³¦¦¡®©§³¬©º¶Â°»Â­¸·Áª¬­®®¦®²©¡¯¼ª¡§´­¤«µ¤¦²³§£¡¨ª²¨°¨¥žŸŸ¯–Ÿ™”•–˜¬¡š™£¨´®¢©©¨ª›ž•— ¤§šžœ¢Ÿ› £¥£–›ž˜™¢ª›¥šœ›¢ –“‘“’œƒÕ“™¹p°Â~Ɔ|֔›»|™•¤œ¤{Ž‡¤‚¥‚z¬yV¯zˆ~Ÿj¹Z¹w†ƒ|¦‚“|˜zªy{±nŽ„t¼…o”P¯§ÅŠQ zc`ªbsrˆm—ˆ`Sµ´È†€‰|c¤3Bv]PihdP@XgZdaJHMlK[ROYfYCD>E?0<<59;74<;8=:<C:F:;>6:@C;6@OLH<:<DHCBCD<EF81211DC./0483+-).323971#%5*>3==Qwj6*Yi[K]O_fT7G:aQ72%›¢“˜±¨¨¥´ª¥µ¨¤»·Á°¹À±µ´»³µ§±°£°²¦Ÿ®¶¨›¨¹®£¯± ³´° ¤žŸ¨ª±©´©¤œžª—˜—–—•– ©š–§­°¨£Ÿ¬¢¨–ž—›¡¥¡˜¢¡¡¡š¢¢§›ž¡ž•™›¦ ›§•››Ÿ¡˜’”‘œˆ²nhµq«‡oŽ¦r´sr¶{™—£‹Žœ¢~‘ ¥~°vƒ‘ÒÑv\®{…¤o›ª¦k†„|­}—™{±s’y³e–t„žožf”RȋZÂ\Ÿyb_­`vs‡b—ˆ^Yʝo¿uMKµSUÆdSQjcfXAOk_lhOUGI9=VR[WXHC?J<2?;5=<46>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>HI91746A>/.24252-).26,742&60;5:=Pqh9'Wi\BOT_eP5G=aM620¡œ‘¥°­¤ª»­¦µ¥§¶»¼²º¿·¶´ºº³¥´³¡±±¢Ÿ¬¯¤˜¦º®¤±±œ´¸ªŸ¦¡ª¤²¨¬ª¤šœš¨ž•”˜˜’’¢§Ÿ–’¥«¯¦¢–“¬Ÿ¥’” ›¤¦Ÿ”š¥¦¡š£Ÿ­š¡Ÿž–›¡œ¥••™¢Ÿ•˜–’š…¬{w¨v£Ž‰‡©o­Š‚§ƒ˜˜¡‰’šŠ¢“™ˆ®…‚³\r³R®}ƒ‚¤q×}w„}Žž†™™w¯†Š‘œˆx³ašeš‚”l’Z°XKšu˜yf`­^ww‡h˜ˆk^¯w•žxl5yÈ®²_ATo^g`EPl_pmVUM.eciSYQ:AD@L:5?91=<16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK97<46:>/04333.2..18*.32%!03767=Pke>&Vg\@>V_cN6GC`I988Ÿ” ¸°—´Á­¨³¨©²º¸´¸¿¹·²µ¼µ¥·³Ÿ´¬ŸŸ¨«Ÿ•§¶«¨±±«­´¤›©  ¨¡¶§¦ª£™ž•¥¡”“›™’”¢¥š’¦¬®¦¡•š©Ÿ¢‘¢™¨¥ •š¥¨œ¤ž­¡ ”ž› ˜™œ–—¢ “˜¦†©}}¥x¡Žƒªp­‹§†•Ÿ¡ˆ——ˆ£‚‘ˆ”ª|€‹yo±Z¨‚‚ˆ ytØv‡s§Ž›’¤|–Ÿ„{²^œd ~ƒ•l’\«[Z“‘hgªdr{k˜‡s]¬Z‰ ŽkoeOJC¡\ZLt]bfM[a_rt_JV6J›“XHE=HFAL35A8.;>05A78@<6=<F?:<6?=B7.HVJEAH6KIN@IK@EN::@4.;>002144+*05/7,&21($$6671<PeeA&Uf[?2U_bL7FI_C1?8¡™™¿«—´Â®«­©¥´°·±µ¿¹¹²°·¼©º´Ÿ°¤ž¥§§ž“ª°©°©µ¬«¯¡˜¡ ¦¥¤º¢£« —›‘¢ •”žš”˜ž ‹¨¯¯¦—›§¦ŸŒ’¤—§ª§”—©§žŸ £­¤¡ž¡•¡™Ÿ ’—œ•ž¡•–Ž«›®mr´r©ŒvŠ¦s´xs³€‘¤¢‘œ‰¤‡w¸oŒ{‹¢kk¶Z …e——i¡¢§m“r´t“˜²j…’ˆ­ku³af¢o‡’j—\­`M¡|‡‘Rs£mz~o˜‡q\¯V<œweTon.\§ObRkeblZc]`p{cTZQ>>mo3BB@?L9!7@6.;@37C58??3;<CDBJFMIF62JTKEBI6IJP?HNCFP=<E50;<010/75,+,426/#00,,289/9N`eD'UdY>/U^aL5FM^81C8¥š›º¡œ²À®­««§·©¸¯µÀµ¼°¯¹¸«Á¶©ª ›¦¤¡‘ªª¨¶£²¨¯ª —œ§ ¤«¸£­›–™¥£• ›˜œŸ“”«µ¯§™”›¬©—Œ“¥˜¤¬¢‘–ª±£ ž§«±™¡£™¢—Ÿ›–œ—¡“œªœ”«™‡Ô’š»s°Ã€Ã†~Ֆ›¸x‡—Œ˜ŠŒ§ˆz£¶u}wv‚š²`ƒºyÀ|u¸bµŒ‡©}–¬©q{u¼ˆ§ ia¦Ž¯¡~Œt‡«}¾ns¼t²ƒuxŠnšˆqn¤t½^w}[ay¼kZV[jz^jafgbmwoY[YCA@r?CG+5H"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-6A9§šž¡¼¢—±Ã°­ªª¬±§¸¯¶Å±º±®»°®Á±«¤¢ž£¡œ›‘©¤ª²¤µ¦­¤Ÿ–šª™¦¬¸£®˜•¡¥ ’œ£ž—š•’¯¹±¬•—£§§”‘–¤œ£¬ž‘ ¨«ŸœŸ©£³ž£¥Ž§¢•¢šœ—•£˜° ’”©ž…™µ€‘Œ·•x‚“šµwmknsny„Ž‰tžÁ»½š{²¨p€t‘¸ƒ|††Œ†{Š†—|¤»¹½œuz´£tv—ut°u™žf†iµtrpw¶Œ^€z}‰hƒymyc‹¬pu…Y[§jDdYSf`c]cQgfqmuBMPMD;ZM>J3<0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITBKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7LT_G'SbV8*O]]=+:VV'=;<§ž  ¿¥–´Ã´¬«§¬«©»®°Æ¯µ³®·§´¸­©¢¡¥ž ™”«¤­ª¦µ¨§Ÿ›– £ž¬¤½¦¡ª—”¢›’¢¨¢“—“—”²µ¶­˜£¤¢‹’‘¦›¥ª›–¨¤¥œš¡©§§£©¡‘­ž—¤ž———ž°¨”›§¡Žj~iœ¦x‡s}štze‡z½¾Àºo’‚q•‡_rjZ^š‰acˆŽ•k`•cmwb•kš•”e^`cq›ŠirŒ}†•gj~rtx}}b[wthP\n„}{‹kXlz‚sIJo†pNtMEW]f`L[Xfc_O[muiqRODEM<HI=L?2,2A?8/5?C<9;@;=C>RVVWYZ[\\]`aaa`\UG5DFUEJOHFPIIH;8=51:.0;:.0-76=5&"/*2,%;8-7JR_I'S`V4)P^L(3=[O'?2>¨Ÿ¨¡Á£›´º¶£¬¥®§¨µ±¬È¬¯³«µ£¾±²§ ¢©¢›š™¬¦®¤¥µ©¥›˜•¡›§­©¾§©¦•”œ• š“—¥©¨‘—œ°²¿¬›§§¢‰“‘©š¨£››« £š›£§­£Ÿ«¢š°›•§ –•Ÿ—±¤˜¡§˜œ‘œ££™¦¢šœšš™–gm}qw’—”‘…Šµª†˜•ŠŒ˜—‡”•Š„’”‘‰Ž‘“˜”˜—š ¢šœ”¡‚z¥†lj||€t‰Šq‚xyvv‹€|Škstƒudw}wkpzm`c]pgMYYfi`WZpznlfSOFS9OZMRO(+:JB635=@A9:C><ENSSTVWXYZ\]`bba_^^[TKCSGKNDGPLOI<:;389,2;820)6IRO8")+/2#4;*7FO[J&R^S10T^:+=8\K,<-@³ ³¢¿¡£±²· ©¥²§¥°µªÉ«¬±¥µ¦À§´¡¤¥œ£•– ª¦¬££·«Ÿ™––Ÿ—­©¥Áž«¤•’œ—ž˜“”¢Ÿž¢§“‘™¨§²Ã¯š«œªŸ––©ªœœ ¬˜¡›¢¥°§¢¥¨ž®˜—§™š¡žžœ° œ¢¦•˜“˜“ ¡•£ž— Ž–“ŠŠŽ–­|•›‚’‚‹ª¨†˜–Š„Ÿˆ{„‡…™’ˆ†Š•Ž›——ž£–š“‘~Žf¡³¯…Š„vzŠ|vyzofz‘€‰kuyˆrhszvƒ‡‚ktdyf`jecdfkYk{pij\RLPD_UE@??,4@F;45;>A;<?>>HNNOPSUVVXZ\_aca_^^]^]XVJKLBIOMRJ;<:786/2964.(&$-1./)+*7%+<(6CMMD/T]Q05M[17E4\G5<,@´ ¹¯¾¬«®²² ª¦±­¢¬³°Å°ª¬£³®¼¤´œŸ¥¢¡™—¨¥©¦¤¥³µž•”™™°¦­¾ ¬¢‘žš™”‘•¡œ—¨œ„ž©«¢³È³Ÿª£ª—–—š§¨›ž¤«“žŸ ª¯ª¦£«¢­›Ÿ ¡™¤žœž¯£˜Ÿ¨“˜—œ‘¤™˜¨š—e‚’|e~™cylhkz‘¤«keš˜~g…Šeeih{Ž¡kh—‘¢wkj‹˜£ž˜slnz„‡zXe^…‚^lŠ‰€v\hsww’€‡‚nx‚x€smy„tw‰ˆŽƒ{i†Y^ktd]s‰ij|qlc]RNXJdXAJ4=F7?FD71<=?AD;;DGHHILNPRRTW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%/*+'6*$;'/AJ[J/7ZO6)EY/DO1YC;?.=¥Ÿº¼¹¯¬³°ª¥¨­­°§®­°½±©§¤­¯°Ÿ­—Ÿ£¡š™§«œ­£¥¨©²®ž•£¢¯¦·¹¥®£ŽŽš¡™“’› ™˜¤•{¥¬¢¨³Ã·¤¡§®Ÿž•ž£ž£œ£ª¨’ž¡ž ª±ª«£ª ©›¦Ÿ¨¡¬–¡›¥°¤—œª•¡ž›’¥—žª˜ž~½ƒ‡r´r„†­hx¹Ä¸q“¢£{¦˜™sª‚|ËÀÀ»q‹¢‡‚Ÿ}•˜‰žÀ½‚–ÂÁ{‚{’ŒšÃÀ}j¥±oŒ€oÊz›w’ƒŽvzyqz‡qx…“ymv“cf_xd`e‚c^tgmdbXLVIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^__`_^^^^___]\SMPGUNA??=6468276*&%#)*&.+*)109*#>I[L*#BP/#F[3PY/UAB;/8–£¸Ãµ°¯À©¨”£¯©°®­¦²µ¯©¥¦¦°«Ÿ«˜š¢Ÿœ›ª§¢œ¬£¥¨¥¤´¤¢’¦®«¸³§¯¢‘‘š¥’‘ ¡—›Ÿ‡¦«¤«­¿À± ©¯©—’Ÿ¢™¡£ª£“ ¡žž­¯©¬¦££§¡¥¦ž­©’¤›©­©œªœ¬¡–—¥–¡£—œΔxz¤y•–›_®^Ž§¢ |§•›t«ƒ€¯^cªz§‡… t—’ˆ³c‚«† Ž³j„®t}–‡¸aƒ­Y£Ínu{Ú{™p~ˆ’v~e{ˆvvk}ˆn~…‘’~m`qkpg`_yd\qhjcf`RTRW^KOC5AHED8>6;@?A;=8@>??BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5578164('$!',&&/(&+360$7;SL+,-J0';\;L-!P@F4.1­Â¿¿µ´°·—‘¤ª¨­³«¥²¬¬«¤«§¯ª §›™¤—œ¢¯Ÿ ž¨§£¥¡ž°¬›ž•§®­±ª¨¬ ”’›Ÿ¥“Ÿ¥—§£ž­¤ª°¨ÀƳ¨©±®–’œ¢—Ÿ©ªŸ”¡Ÿ®°¨«©œ§§¤¢«’­´—¦¢ª©£§¥¡° ’š§š š””‘— q…Œ—t„¨‡q±|q¬~¡ž¥žwª‚}­œr­~«‡†Ÿv˜’z|—~ªˆ¢Œ‘Œ~«{‰“Ÿ€{­VœÄzo’Á}•mupŒmeve†oawnroŠ‹’ƒm‘‘eptup`gme_oiinfcWS]aYRSC9II@D<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;91478452&# 1' 1' '45-&7=WJ-<'>1)3V@F!G:C1.+°ÔÆƲ´Ÿ£Ž££¡¬¯¶®©±§¨ª§­««§¢£™¢• ¦«Ÿ¡¥ ¨¨¢Ÿ°¬—š–¨§¯¬¨§©ž—•š£¢‘”¡­›¦£¯¬£«´ªºÍ±­¦®«–”œ¢˜Ÿ®¬– ™žŸª³©ªª›«ª¤£¬›°±¢¨¬®¥˜¦ª©©±¢’–£¥š”’„¤j¤u‰z©tz²p‚¥‰™Œqˆ š‡¤``R«„®ƒ›v®¦††Ÿz™–†{f€£‰¤™…‚£}©~”‡®^|©U¢’z¢Ÿ€{ïŌs¯³³¹qb©¯Âth˜mš“pnyxwolfeerpf|ib]W`iXXUMMQLCCAB;C@@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799674,&$" ('"+-"$.!3-&@DWH,G+56*1PKL# A9D4,'ÃÉÖÕ¿¡™«§¡¯¢ž°´°¯©­¢§¦ª««©¤¦ ›¥Ÿœ¦§¦£œ¬š¢¬¡¤Ÿ¯¢š’ª¤µ°® ©›–”¦£š¢¨  ¥œ±¦£§±¬¶È²µª¬©•‘œ¢™ ¥³š ”Ÿ§¬¬¤®š¬ª£¢«¢³®¢ª³±¡šª¨®¯¶£“–£§˜›‘|ªlž„‡u«y|°o‚¤Š‰Ÿ–•Ÿ”Ò¸´¸É€²__”©ƒ¤ˆ‡ y˜•šxªÉt™£•§©“šŒ›‰šÆÆxe¡‚¥sŸŽ‚}¯^pµc±uK£†m§G‚“dž’|p—“€q{u}{n[ejsqfj_aYdm\^YIMLKEDAB>A<B?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75685/)(%&%$&),4ENPPMFKJVF*L0/>-5OTQ;<F2,$§¤ÁƸ­©²­¬¥¢œ²¹¬ª¡¦›¨¥ª«ª§ ¦¥˜ª£Ÿ®«¦ ¬šž©¥§¶Ÿ¢—“¨ª¶²¬›¦œ •¥¬‘™œ§£Ÿ©¦®¡£§©°´Â±³ª­¨“‰—œ¤š¡£¯¦˜¡•™œ¥¦«›°ž­¨§ž¬£·­¡²¹¯›¯§³³³¤”—§£™ŸŽ‚NxšŸzƒ£}ƒ¤„‡§Ÿœž“„¸{|y¹‚~Ìƶx›¡‘‹Ÿ}š––Švž˜Š¤˜£¨~°……ž„¬}™”a¥l£p…}—ƒr¬`¤sq€š`¼}RUuŽ’¤—|}“’‹uzs…q\moxrj‚oZd_hncd]KMQTBIHFI:9K>B108866877-*5==?BDGILNPTVXYZ[\__^]__\ZZZYUSOH@772.,*.+*'&?QTVWWWYXXWUOUF<E3:P[T6?H,- ‹‡™©«¤«¸«¯ ›¡¬³³¦Ÿ •¦®­®ª§¦¦š£§ ²®¢©¦² ™ª¤”£¶¢¢•—¢©´¸¤œ¢¢“¡±™žœ§¥¡¢¯®¤¨¡¶²Ã±®©­©‘‡œ§œ¢¤œ¥—ž™šš¦¤©š¯¢®¥¦˜¯¥¼­¡··­µ²¸°³¦˜¯¡£ž…ÑµÃ·y‡Ž…‘“¦x”¢wŒ ‘„¥Šqª†„´nrj™£›•ŠŸ|˜™†‡s¯‚¥›¢¦‹“‰”›mp²\¥s“zœl™{™}n©a£qqŸbs²¸hx”¦™~Œ“Œx}yŽ‚mixiysn€t]ddnmfg`J[XX<HG@U3@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^``][ZZXURRQF:2230/++(@QRTUTSTVWWXXWUVVTQOQ[U%!2AH$)%“sŠ­¿¿»ºµž–§¤­µ¡£™•£©§®ª«™¦¢Ÿ¦¡ µ§£©§°£”¬£Ž¤­£ššª´´¤¤œ©‘”—­  ž¦£œ§œ´š¡ª£¶«Ã¯©«©¡Œ„Žœ¡ ¦¢•ššœ™›™§¥¦˜¬¨®£¥›®§¾¬”½°¬Ÿ¢°³¹«´§š¨±¤§˜z¨}|°wŠ¤¥ˆœm²o¡‡­|¡Žƒ§•˜€¬ˆ…®…Ÿ”© ¡–†Ÿ€™•€{’~«€š–‹ªx ‰“’€y¯]£|¦§d€|—tk®]¥kp…™]`[Œ m•’§™ƒ”—Œ{{ƒ—klb~tm€z`geqnhghCZa[=KT2U8BBC7$$3+''3, /6674359@CFIKMNQSSSVZ]_a`aaa]][ZXSPONI7052.*,ATVVVTTUUUUTTUTSTVVWXVUUQHFIJ#((½’š„©Æ¶Á´Ÿš¬ ­¸¥£Ž›¤¢Ÿ°¯ªŸ¤Ÿ­™ž¸ £« ¯©š®¡«©¤–‰š®°¬¦Ÿ§š¬—˜¬¢¡¥¡š¤œ­˜Ÿ¨¦¶©À¯¥©£Ÿ‹€Ž›šŸ¦ž’•šš”šš¦¥¤š©¬¬£¤ ª¨¿¤—쪢¡«²¹ª®§ ³®¨©˜v¯~‹œ…‡|º®Š˜e°Œe•­}¡ƒ¦•š¬Š„°…¥™¤¡¡‘… [lj³`­{{‚±lgo™—Œˆ°[}´[¤ƒkÈ¢eŸ€{¼YvµZ²}R¯€z¬X€¡n˜¨›‹—‘——|yŽ~ds~b„xt€|ajgqmfeeOUd\AT_>J(>9=4!",%2. *1/045799<ACFHJLNPPRTWZ^```ab^_\[XUPMJGC553./@UZXWXWXXWWXWVWWWWXWWXYZZ[\XWWGB;ҟ³²·½»´Á³£›¬¦¥¶¨ ‹š Ÿœ³³©Ÿ£Ÿµ˜ ³¨ª«ž¯­ž¬›•¯¨¢Žˆ›Ž¯¬¨§¢§™®’™¨™¢¥Ÿ™£¢¥™Ÿ£©²¨¼¯¥¨žŽ}‹›•  ™’š›‘š˜© ¡™¨®§¥¦£¥©»Ÿ Æ§¥©¡«´µ¬®¦ž»­¬¬•€©’£¯Ž›€‡¤—˜€¸ÃºƒŽœ“„§–œ‚¬Š‚¯ˆ¦››¥ª‘~սªb£¿½}~£‚ƒ×º¸µ…”“ƒž½¾„j£o«„mz²°Çƒj«°½¬xw¢¾¼t–Ž§œ›‘˜z‚‘›zc}{dgy‚{`kekjbPa[Sj\@UaCN*=:4/$%2 $(0496677;>ACFGJKMNNQTW]a\__a^`[\YTQMHC?<A?5=SYXXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ¼•³´±¿¹±½²¢®¦¥²¦Œ˜¥¿ª¸±¨¡¿¦¦²œž±œ¹¨ž­¯¥§””°«—Œƒ›‘®¦£¬¡¤œ©Ÿ˜‹£’¦ž§œš ¨¢˜ž ¬­ª¹®¨£š—’{‡™‘¦›’Ž‘˜˜˜”©š ˜©©¡ª§¡¢«»ž©Å£ ¯£ª³´ª¯© º§®®šsuª¤·†e‰ pg­Šmox¤™Ÿu®™•p‹q•¨£›—®¤rmmmeŠxom‚™q€yiqig‰–•˜qhi„†gp†d]‰cjoY]g~w¦`bqŽ‘oed€“¢˜˜™’—Ÿ}‡Ž•vf‡xhŽkyydlcflbKdWJlY:QeER'K:+# #,)-2.5:457:<?ABDEHKLMOQSV]WZ\``a]][TPLHD=:AB7MXZZYYZYXXYXWWVWY]^^]\\\]^]^][[UW^¨•­³©¹¹²³ª©¡®ž£²©˜’¾²ÃȾ¶ªžÀ«¬£ §¬Ÿº£¤­¬­¦—®©Œ…•–­ž¦ª¡Ÿ££ ‘‹¤’§™¨™–£© –œ¥¦§¯º«¬š›’’{„—¥˜‘‘˜”Ž˜•¨•Ÿ˜©£›±§ž£¬ºŸ°Á§¤³¦¬°±ª­«§¸£­·–Š ¨¥¶‰–¢˜‡©š”“ª³™›£« ±–¡¡Ÿ¢œ ¤¡•«§“’Œ‡’œœ”š“˜Ž•…¤š—•‹’’Š†„}gŠt‚vt‡‹p§m{”‘“’Ž”¡–™—¢ƒˆ”riwp‹xw|zjlddodU`X@i[HcaOZ+F=+'!740.!%2(*699469;>?ABDFJKKMPPQXUVY^`ac\^UQJED>9=@ASX[\YWXXXXXYXXZ[[\^__`^^^__```_YY`¦–©ª¥µ¶®®¢°¤­Ÿ µ±Ž¬Æ½Ä»¸ª¢¥ž›¦ž°¨£¶§©µ¦¨‘˜¬¢‹ˆ‰œ§–¬¤ ™§žž“•£–¨š¨™”¦¡£›¨™¡µº§«˜š|”‹ ”Š”‘•”—¥Ÿšª œ¶£§¬·§®Á®£·§¯¯°¬©©²¸ ®¼™‘¥¤¦¶¢’¦Ÿ©Ÿ’Ÿ£¬¯›¡£°¨¯—£ œ£©žžœ–«’™¡›”–ª™™™––ž‘‰ •”…’Œ”Š€}f‹†u†vyˆƒsœj†””‰}Œ–’’—“¡“—¢„ˆ˜‡zr–szŠr|jod^pj`[_YncP`eP[:GGE>2==7/+&+)&&406658:==?AACIJGJKLMSSSUZ``i`eVPJACB:9EMV[^^[Z\[[[\]]__]^_`aabaaa`bbbdb\[c—•¤¨£°³¬®£©§­ §µª¥³»¯¬¬¢£šz¢±¤¥°©–›¸¦£“™ªœŽ†Š‰œ£®Ÿ£•§Ÿ ’–˜›®Šª–¨™§Œ™¨ž¹¶¤¥˜›‰y‚“‹š“‰•’”’—¢žž©žž¸¤€„¯µ¢°¯u¤¾£² wy ª±»”u¬¤ž‰€ªd\bv Ž¤ž„—~n“³£§­ª£eŸ’sy™—p€˜¨—l¢¨Šeœ¥œ‘—˜•‹‘œ†š•ƒ’†Ž’‰„wjŽ‡v†q|†€€ai‡Š”’‹Zu•hhŽrz¦™™ey™‡‚x˜jƒŠƒoy€kqe_vplkh\febbpS\>MNNSG>@TC:1/&4:316678<;>@ABFHBGFIKMTTUY]`hfgWPJ<DG;8UR[`ab`^`_`aa_\]___aabcdabaaedchd^]f›•¦£¡¯±¬«©¥©®£§­¥’–«¶°²¦šª§«—sŒ°Ÿ¨«§“—¹  œ¤‘ˆˆ›ž¬š¢”§¡žŽ—‘ž„u®ˆ¦š¨‘—¤ˆ›º´§ ™˜‹‰uw“–“Š”‘”Œ“ Ž› §™œ²–€Œœµ³Œ’¼§ ~§¢z¢®·ŽŽ¦žƒ‹†±©¯ŒŠ–£šy‹¬†œ¢§©§‡•…˜w¥›z‡›—¦‚‚{œ±zŠ… —™”˜•‘—–„™™cy‡„Ž‘Šƒmp‡y€q€…†t†„•’x–h’t št}™„¡ž‡˜~’‹ƒƒ™kŽ…lx{qqgdxnjlj[ekjft\_HTLQ@E5.YUU7)!09=>643568;:=>>@DI@JEJKGSX[Y[a`hfYQH9EL;>bV^bded`aa`bb_]`aabbbcfgcba`edcgcaahœ—£Ÿ¦®®«¨¬ ¨±¦§ª¥™”®È¾°¡–¦©µžƒ¬œ§¢ ¾žšŸš }†™—ˆ¬œ¡–Ÿ ‘“ˆ†€‘¨‡¢œ£“—ž†žº²§ž›’Ž…pu‰•Š”›‹’Ÿ’— ¤–ž¬ˆŸ´‰´š­ŠÊ‡ª®ˆ·…Œ¯‚°®ƒ©¥˜|¨r{wœ§–h•¤y´‹Ÿž¦¨’˜Â«ˆ˜¡qž€™¤}—…•±€¡|¡” ˜–€Ž“›Š—‘‹|…’†”’‰ƒms…zr†„|„u„—€Åf©‡£kžƒ¢›ƒš€ŒŽ…Š™pŽ“…hwt|whhuqghk^domgmXhG]RM2E46Nac7&3<DGD964658;8>==>BL?NIJLCPZ]\Wa]jl\QE=KM@JdY]cfhgbbbbcc`_babccceiicbbbecafcbbi”—¢Ÿ°¨©¨¥« ¤¹±ª«¦š” £¤ª£–¥ª·£¯¡§œ¥ž‰”½š“¡‘y„––‘ˆ«™››™¡…Œv›œŸˆž¤›•™˜†¢¹®¤™œŒŒ~bm‹“Œ˜‹’Ÿ” ¡™¡¨~¡§‡­ –­žœ‘…€ ª®†£©™Œš~¢v€™”k‚¬uM«x‡‘›¨§€©«}ƒ¡{z§iž’kg—†—¶‰ž}n`dYƒ–Œ{dhŠr™}y•l]{–m_Spƒ\_kyƒ`Ye‚}ƒ€—p§ªkƒ£nr¥pŸ„ŸieŸl[nŠ|fZ`ƒbWPowfmtrkjo^jpmljXiO]XF9A4GD_k4,ICQMN=84859;6@;;=AO>QRLMBJ\]_W^^bv`MD:MOMTb\\ffiibbdbddbab`cdcacikdbddgdbgeach—– ¹¡ª£¦¬‘¡¶¼¬®£™— ¢¥¬­¡®µ¢¨’¡ Ÿ¦›™˜´™‹ŸŒ•Œu”’ŒŠ¦–•˜žž’……¬¤‡›Š˜¨˜™š‘‡¥±§¢•šˆ‰€inˆˆ‹ŽŽŠ‹’‹’¢Œ”ž œ¢¥“£¡” wœ–§ƒ¡§†©¬„¥xŠ|„š}¢pr“ˆ–{žŒym‡œŒ™›¨š‡{‚¢sv¦fž~v¤_˜z}’s¢n˜·´ºt’‡‚µ¨dÆ¸{p•·‹q€š¤cs¬«`}j³~n|†‚Ž‚‹˜q£lr£sž„€¤`œ˜³–q|—Ÿ´ts[ž²ƒjbotvrhoXklssf]i^bKE=D5QAZr2=SG_JR=<395::6D;;@IQ?UMNQ@E_^[YX``|dHC8LWUVbaZffkkbbeadc`ab`dd_`cknccddhdbgfchh”–•£¸™«œ“ ¤·µ®­ ›¢œ££¦­œ›±­¬“—¡™¡¤™š”ž«›‹‰’x‹†p€–‰¡’”—}‰Ž¨ ‡˜ŽŠ‘¢“›šŒŠ¨¨¥ž–‡„~k{‡}ƒ‹‰” ƒ—ž  Ÿ‹‰wœ˜¢ŒŸr¡‹‡¨ˆ›¥–§ª~­Œ~z ™z£“xt–ˆœ}– ‡›Ž™›¦†¢d¡|ˆ–›lžh›nš™{€Š§}rht«ƒƒtªg”š]›…v„hªj€¸f\¨pœa•Œ^§vvˆ‰žhšu†“’—ŽŸnšm§™]¨~x»k~ª[Ž„]´g\nryxki\qjyyc`fXbAQEN7VCRn4KZZ_NZD@151;;7H?:CHU?YRY]>Db^V`Qac}iEB9N[]XdfXfgnmbbe_aa__``ec^bdoq_deekecihgki•œ‰ªµ›§‰c”›«º²°¬¦œœ¨Ÿž®›ž°¨¬—¤š¡Ÿ˜–– £™†‰jˆ€r{—ˆ‹––„‘”˜zŠ„–£Š”…‹‘œœˆ¨£ ™‹‘Š€€i€†y—Œ{ˆŽŽˆ–š“¢Ÿ ¡“˜rhŸŠŸŒp’Œ©‡˜ž¢§Ÿ§|¯­£¢¸—w£³¢¤€ˆ”y{«š¢Ž›—ˆ—q¡|…¯µ}kš‘¡x~˜´££«¨„™|›}™~tªZ]o{–‹xžbL~zz…cy—BLžY¢jq|Žm‰„™u›x†‰±³›“§vmr}”o™sj¤]•vHec`sq~nf`liv{debR^W]UV@YFQgDSW[bX^ID=B8?A:IE8LEWAVQ[VDFb\Z`K`m~qEC<U_bZejVghmobfg^aa\]^ahb_ecvl^egfkdflihki“±­™„T^ ¦³¹³³©š¢Œœ«œœ©”¡«¤¡¨Ÿžš™•˜ –ˆ‡‰w…ny•…›‹|‘“–ˆrˆ’¡›s‘€ˆ˜”Ÿš„Ž©œš”Š‹Š|ƒl„…q‚¡Œx…ˆˆ’˜•|“£¡ž¢ˆ®†}µ„Žžœ{¥–z©•œŠ œ|§hwm~™t¡sq|ž†™p“ƒ®}¤ƒ¦žš€£o^¨gu£co¥aœÓ|{™xrsc¢…~£s£uk³‹`‚˜‰sª²¨¼wƒm~¾¦©´^œn}q—n€s¢r]¤gs¦ah¦m›Ô™}„šoxz—k›{w—sm©¤g`eyp€„kgfdnvwg`cS[fQQaHWIT`WS[ej\eQFCKMJKBJE8P@QNWRYOSQ`feiScwywIFEc^eZhiTihjocjg`c`\]]_hbahe|d^dgdkdjmghlh—›±«T\K~©¯±´°³£›™…™¨  ¤Ž¤¨ ˜©Š™˜˜“™“’ ˜Žˆ†{p}„h}ƒ”šw‘ŽŽ‰o†“’l—“|ˆ‘‘£•ƒŽªš”’‹…‰yƒvˆ€n‚Ÿ‡w€“†ˆ™¢–z“¢¤šŸ‰³¡¢¶‹z¬§¤®¥p¨€š…€›‘{¤€¡™†˜rž„£®¯Š—ŒŒ¤–ƒ®¡”v´µµÉ¡s”ŠŸ`—©my•† ›u¡‡w ~‘–Š€oLf£’p›‡r¤{ytaƒk~ kqd`œr~t—izi³µ´Æ¦s˜~zkœ›«u„›muw˜išzu˜qPE}´^jvkyˆfjhbtupnV^TYiPShIULYSU]hknVgWMJAJMKHJNAQKPecimeussy|nu‰{{TPNl^h[kiRjhilglfce_\]\^ibdik{_]dhcjfomeile¡œˆ¯¦„f?”¡²«¯¯¶¢¢€—©¢¢¥Œ¥§¦‚š—–—œ“Žˆƒyjy†eƒŒ— yu‰Œi„…’ƒŒ…zŒŠ•¥’ƒ—©—Œ‘‹‰z€}‹yp¡†y•‡‰– •”¥¨œ––„fnxœl¢d|q¥w›˜pg¦€–‹{¤zŸ–ƒ—ržvŠ”–¹nŠ¢b}™¡•ˆmri«ju mn¦_ši‹h–‡š•u¢€}š`‹…Œtoˆbh ež~išuocfˆ‚mr¢Z_[c¡m]‰Œo{~srd¥mw¢dg§h™sŒ™o¢oS‰o _e§T‹^T˜nmskr‚mpikyskoRYWWfZSmIXO]IXihsjYkVQREV\LXRaUhj_wtz}p||rƒ{sv€„v^QrbgbpgPjhhklnhdg_]^]`kcjivu]\cicjjslfkmcœ¤˜¦zetm‹§®¤©°±¦Ÿ‹€—«Ÿ¥Œ¢¡š¢¢€–˜“š‹˜ŽŠ{†q€ˆh‹‹|˜›st‰}{d‚‡•Š‰•™‚|ˆ†–§€¡¬…Š‚Š}€€Žsh¥„}†”ˆ˜ Žˆ“ª§‰¦x–›¤ˆ–Œ²˜ž‚¯—Ÿ¥w”‡y©t¤Ž„šn¤¢Œ’„Œƒ»n}¥¯‚†††“–œ |¥zq¨• –fž~o«c–Š•’w¨l©¢‰u‡‚w«‘¦‡j‘°kv³Œ©kŠ†mmŸž’•a«‹ªvŒ¥žvŸ}„¤• j›ˆw¬gŸ­¶tw¾¤“Yƒ¦«aurtp|tqcj~nhlSV[Vab]kM]R]I]mmv`[qY[`Zgtenoqcqt`xz~yryƒs„~€{{Œ‚€vbxdcmsdRkgholrjfia_^\bkbmlzo\\bibljwmglnb•¥ª€ž¤–©ª¨§®¤™‰ƒ˜«šž¤‰š¥©…ŒšŽ†œ‘…’Œt†zˆ„o„~˜“tt†r’ƒm‹’‡†“|{…—¥¥¦ŽŽ‰…•v‚‡’ol‹©ƒ‹”Ž‰œŸ‰”«£ €u”–ˆ~y”®£›q…xŠƒ~{r¦Œq}}z—–›„Žx{~~‡”•“Šv˜Ÿ ƒz}‰kŒ…[yxrzphn~’‰qt‚”“q…ƒ‚eŒ^‹wus”uoynn‡m„…^vhxŽe€…Ž©›}t|–j‰ˆo€v}†vmmgŒsy{˜x„[kXyinwrqoxxp]l†njgVZ`W]ekcVaU_Q_pxylkvejkjv|qrtsaoubt{xuzƒv€€€x‹…ƒ}{mldxn^Wnghukxjijd\`ZcjelqunZ[bkdllymhloaŽ”¸¨¦‹¡¢š¦¤™¤œ«¢¡„„˜¬’ž¡‰š¦›©˜ƒ›Š~–“‡ŽŠ‰rƒ|}~…{—Žsr„p•…{}’‹††…x~†˜£{§¡‹†…–ƒ†Ž˜wr…©†Ž’œˆžž‡Œ›¨Ÿ ªƒ‰”š~~‰–­¨’¦wo‘‚y‘o}¨…p}•qkp}ŸŒ“ŽŒhm]ƒ‹Œœ›žŽs•‹ˆqtkvtYrn‡‘}~Œj]jdz…ƒˆ€_ixz›{‚‹‚v†‚gwŠ†kapr‚v_r‹‰¦•…fŒƒnw‹„q†zpfgd{ƒz–[\jgnv[{ywunss‚f\mŠklcYY^[Ylq\_aZ^]ft~{uotckkj{}r{xtdmthm|~vz||zz€€~o†Š„{}s~ysiT\qiluougkhd]aXkhlkqrmW[emlgsyohjm`‹‹©°¡£¡šžž˜ž™¨£¢~ƒ˜­Ÿ•ˆ›¢‘¥•{˜„|’™‰ˆ†‡Šs}€‹v…‹„–Šqo€r˜†ƒ~“„ƒ†Šz€ƒ‹›Ÿ‚§¡‡xŽ˜‰•‹‹—…ƒz­‚‘˜™”Šž‡ˆ¡«Ÿ¢¢£‹ˆ“›œ£™–ª¡§¦ ’›‡•{wŽ„§~’‘’“œ±¦›•ž²“˜„¥ŒŒ•›Ÿ‰›‚ˆ‘Šk|wxe‚†Š|‰„‡‹ˆˆ€…„w|ytš¡ˆ†‰žŠ„”~}‹ups…ƒw‡‡Š¦‘„…‡ƒŒ}ˆ‹‰‚wl‚„}z™jrhatŠp}zwvovt]^o‡ho`^Z\]ShrUc\\alhu||sopdkji|nyqipplf{r‚€x}…{m‚Œ…|zx|}zƒyNdvjrmpzdkebb`[tfpfrqmU]ltmiyzqgikeŒ‡¹ž–¢¡˜•™˜”™¤¡ž|š«Žž† œ‹ž–}y”ƒ{Ž™‰†„„†nx€€r‡~‰”„mk~z—†ƒƒ€†„†|†ƒ›’‡ªŸƒrŠ†“‘‹‘}zª„’˜–œ—‡‡›¦Ÿ¢š†ƒ‘š™™š¦ ¥–€Šv{‡Ž„¥{|Ž‘†˜ª¡ž“Ž«Ž‘€žŒˆ“šž‚Ž—~†‚ow…qua~‚†u‹˜ƒ‚†„~…ƒ”mxut’¢ŠŒ…™…„t€‰|}rr{‡„{x‹Ž„’¦†ƒ„ŠŠŠw†ˆ‰Œ|ok~|nhlmg^zh|{vtvu{w\`p}nu`c[]^QgnTe[^akivz~qlldkjg€€ls€kltoyo„ym†€v‚€}„vq‚‡~{{|{‚Š`i{juhi‚ejc`i\duhobtmlUcqyepzzreimm‹‰ž·š¡£Ÿ’‘–—‹šŸŸž{xž¦‘›Š‡¥”‹˜™yzŒ…|‰‘ƒŒ‚‚‚n|xs…}‹‘}kh}—ˆˆŽ|}…„‡|€››‘ˆ§p‹‹Œ“‡¡¡Š…|¨‘ˆ’—“–“xŒ£ ¡–š€š˜’Œš£¡£š—‘›~„x€ƒŽ‡ }Œ|˜¤ ¡“™§›‘‰’—›}’’~†ts‚pv`}†rŠ•|ˆŒqŒ‚…†ŽhwqxŒ˜‘–~‡Šr†|}px{‹„zz‘Œƒ–¥“‹†|††‡…v‚„ˆˆzer|xzqljf^~sh|uvt|s€j^`tvpxdcY_^RkhTeY_ahjvxqfkclhekm}hoqk}x†zk‹s~tv‚†~|z}jrƒnsia‡hlb_qVtomn`xhmWjtvcu{zrbjny‰ž²’¥¥œŽ˜†¡›|v¤ Ž—¢Šˆš–x{†‡~ƒ‰‰‚q{tv‚…~Š‘xgc}†—Š‚Šx}€Œƒy–€•—–• ›~oŒ‚‘”†¦›‡‰„¦•…“‹–—“’w‘¡¡—”—z~Ž˜—Ž–š¤˜’”›y…‚w„–~‰Œs—¢ž¢“™Ž¢ŒŒƒ—˜ƒ’–™~˜|ˆvq}nzd€|Š…p†’‚l‡‚€‰„euo{‡’—Œ|“x‹‰{†|{q~w‰…y„Š‹—¢•‚„Œwˆ„ƒ‚w|‚‰…v`xx}t~xgldaijwstu}q|bcasnusmaZa^[leRcX`aikvy†qbjcmeh}ƒlhthloi€|ym†q€ƒƒt|ƒŒ~z‚ƒ~|mv‰ttmeŠljbcuVƒiqn`xglbjvpfy{yq_rl†…œ®—¦¨ž—‡†Ÿ“—™}xªœŠ™z—‹Œ˜y{€‹}|ƒ{€ƒxtxzs}€„‰‹€d^}‹•‡~…‡t}~‰}—„—“–Œ£¡˜r‡{”’Š§ŒŽŠ“ ’ƒ’”—‘‹˜ š’‘s’”‰ž¦——•–sŽŠk…—™z‡ˆ‰o—š£“•ŠŸŒ‡‚’œ’’•†™ˆ|‰‰yqykul{}‹~m…’‚”wp‚ƒ}~Šdri{€–—„~sˆƒx‡~ux€}†€|ƒŒ„Œ”¤y„‚t‰‡}€tvˆ„na{uzq}oaocd{bnovsxwstau_oluno\[_^^k^P]Xcahmt{ˆk_jejchwˆnflhjlh|{wo‡sƒ„}s†‰z‚}z„}}Žrz‹xxnl‡kh_irb‡hroevgnlayhk}{xpawm‹€™™ª £¨Š‹’†Šž‹•˜}w®˜Œ—}ž”‘–”ˆw~{Š|{€vw€pts{o…}€Š|a\~‘†„„sz€†z‘‡’‘›’¥œ•‚~}Ž‹’¤‰ŽŠ˜š†‘˜“–ŽŠˆŒ’œ“ŒŒnƒ‘‰ž™¢¡—–‰–‘nˆ™„f…˜Ž”z‰…‹p–š”¢’’‰‹šŒ‚‘ž|’’‹™Ž{Š„‡srukqnt{‹tn…’qt€{ˆ|dplx}™“}„ˆtŠ€sˆyo€}€†|…Œˆ„Œ•¨Œ{ˆ|~‹…x~qp€…ƒchytup|b^p`kt^pj{yxkspex]mlsmsXZ^_bkZPWXecgqq‡f]ihgbgqodigdih€zwtnŽ…t‚ƒ{u‚‰…w…|x„…z€‰w‹{{ryƒjk_pht€kromqgole|cn€yvqlwwŠ~¢—¡¨ ¦›‡Œ‹œ‡“œuª”’Ž‡ –“€t{v…wxrs{…krpzmŠv€‡nq[X~‘ˆ€€€vu€€ †Š’œ—¡”˜xŠ‰œžŠ†’˜–…‰•™–‹‹ŠŽƒmˆŠ‘‰œ–¡œ˜•…—ˆj„£‚f…Š‘~‹ƒ‹w“˜’Ÿ’‘‰‰•Ž~˜{‘š’|Š‚nuplmop{…isƒŽ˜Špwt‚ˆ‚xfrou™Ž|ˆ„z”‘yvˆtp‰{…Œz‹†ƒ‰Ž›£ˆ|„v‚‹xxokƒ^rsrqpxZ^p`pj^oi|zpmmjlv`pojrmZXaabnXQTZfgcup„‚b]kmdbfk“m`ff_gkuqrp‹€uƒ€xu€‹€x…w‡†wƒ…{†Œ{vŠ€jqc|c†|oqmtjholvw_qy{tut€‚~¤•š­ž¦–…Œƒ—”ƒŸu‹Ÿ”“†‹šŒ•‹zrxt‚pr…tquˆkomumˆvƒ~€mnUQ«”‡‚x€vr‚y ‚‘“’˜œ’šx’{ƒ“¤š“Ž‰•™’„‡—™Œ”‹‰ˆž„Š|rŠ…‰ŽˆœšŸš–”€“~h…œ‡g… ‡’ƒ‘ƒ‰qƒ‘—›ŽŒx{’zŽ‹Œ‘–Œ|ˆ|€kvjnkklzaz~Ž–‚vz€xƒŒ|ygslt‡•‹~ˆ†{“qz„pvŒz‰Œ{‰}‚Œž…||w‚Œ}wqjl‚y`xomlrtV^obr`_lnypgpffsthpkawe]Vf``rSQN\fe]ypˆ|_\hrbbef’j_hd[gp~pkpsŠ}v|…€tuŒy{†xˆƒs†…~ŒŒ„{y•xgrjƒ`ˆ~ookz`jntt_t}x†xts…|x ™°œ¥‚Šƒšˆ€ŒŸ‹š“Ž…ˆ—ŽŽ„vtvs€po…spqƒpjivnƒn}|musRM‚ßȒ֓|puƒuƒ ‚“w•‘™›™{”s…Ÿ¡“”Š“›”†~––ˆˆ‘ˆœŽ€wzŒ~ˆ‹Šœœš•“zvg‰‘‡lˆ£„’‡—ƒ†cŒ‘™Ž•Š—ŒŠ‹q{”ˆ{ŽˆŠ’‘‰y…{~l{erojkyy\€yŽz}~†Žzyhsjs‹‰……}•‹k~~n€‹~‹‡}„z•ššŠ|vxƒysmfp€ƒmjtohjtnS^odpY_krxfkjbfxropc_x``Vk_^vPNK`gc]zq‰t\\ev`aeed`eaXissmjqvŒ|ty†‚uv~‹s†{‰~r‰‡‘Šˆ|~˜vesn|e‡~opkYlnyysavz{vswŠwyŸ‹›¯› ‚…wˆ•~}Š‡…Ÿ‘Ž…Œ—„“Ž‡twpyqn„omn~rddxq}my}jhlc¤šÁÜ®ï¡skuƒu„¢…’o–• •œ‘q†‹£—‰Ž–‹–ƒ€•…‰€’Š‰–~‡zu‰x†„œ›˜˜ŽvŠvn†‰‹}Š£„‘‰……^‹“—Š‰Ž‹‹„Šm|–}ˆ…‰†v…}}k}dxuinxsXˆz’††y~€€…‹~xesj‰Ž‰‚‚€Œ–…kvnˆ‚„‚z•“™tsx‡usqguzƒbtmpbjvgR`qglU_ntyarc_h}prn[crabWnZ\xMMLdga^vs‰m\\dy^`df…`cb^Yjrknksw‹}tw„xw{‰qƒ„}~ˆ{t‹‰ˆ–‡Œ~~˜shuqyl‹zntp€Wqzvyqewy†Œiw€‰rœ‡™§œ£’„}pŒ”xy‹„…¡{–™ˆ„{rwpsjokim|t^`xw{qu{gae|ëÚµÉÃ܈sltvŠšˆi˜•“‰q…‰ „‹–ŠŒ˜”|“ˆƒ‰{‘‹…‚vxƒƒr‡‚“›–”˜†Œu‡p„‚‰†˜¡ƒ”ŒŸƒ‰aƒ”‡Š†Š‡‡i}”}ƒ„‰Ž‚q†~qwhvriswlZŒ|’‚†}ƒ€„‰‚uaskˆŠ‚~’}m‚lx††‘ƒ}}€’“–ˆoqzŒ†ulqlrx_tin]kv`RerifS_pvt`o`]h‚prjWghciXmV\uLKLeg^brs…i[\ey^^dg{`d_\YknfnitwŠ~ss~zvzˆs…‚|€‡vwŠ†Ž˜Œ{“vlwuyx“tnxz}Xy…q€ogxw’‚dv†…qŠ•…™¡š¢Š‡to“‹rwŽœ}Šš‰‰|Ÿƒ™xqsmodr~iflwx[^y{{qq€jagaÕ¶Ž¦xnqw{p’Œ‡j™Žˆœ’Œ…{iˆ‹š‡’‘†‡˜|‰Ž{~‰…zt{‚zp†€–™Ž“”ˆuƒ†vƒŠ’œŸ†•Ÿ~ˆa€“‡…ˆ„ŠŽ€ƒg}‘€~‚ŒŽ~m‚|‚tkmvtsvukb…~|„„ˆ~o_rp…{Œ‚|~‘ˆzpƒfyƒŠ†‹ƒ|„~€”’„noyŒ~unoklz}chkjYnvZRirjbQbrxlbe]Zjƒmsa[g_dl_nT[pNHOge\gnq€l[[cs`\clwde]]Zllbmjsv‡qo||tx†x…‚}€‡uy‰’–|ˆ†v‰pwy{ƒ“om|w^ƒtmizt”sgs‡|r‘‘ƒšŸ› †ˆvv•~mv”—~ˆƒŠš|‹šv}vqoljau|gbiuzZ_x|zmqedhgW^qr–¼Ä„vq”‰~r—Œ†œ“Œˆsk‰–{”‹„›Œ|‹†}|‰Œ”ˆu‰…vv}qu†ž”†•ƒ‚qˆtƒ{‰˜œ—†“Ž€ˆe}“‚€†„‰‰r}g}‹{y‡‹|i€}ƒvfoxxsvslj…ŠŠx‚€„ƒj^qxz}Œ‰…{€~rix‚‡‹…„xƒ|˜ŒŒ}nm{‰}wtohh}vd\qcXosSSnsiaNftxf`]\Xn€nsYeb]jm`pOYlRDThaZknm{oZ[^mcZbowcf\]`kjclisvƒqn~{tuƒzƒ‚|…v~‰–‘xƒŠtˆryy~oo|qiyz~mm|v•kjx„tl“…Ÿ˜ ™…ˆn}Œvjx˜‚Š‚•—Šy–ozspljd`szh_er{Z`r|ygpzaeeŽ±²wJbZ¤ÙЗq{‘‹x}•‹…™‘†ol†’’zy’†„˜Š|‡xx‰Š„–€oŠ‡qt~ziy…ƒ¥‘„“ƒo~ƒvƒx…›˜“Š’”…‡p{’ƒ}ƒƒ‰ƒoxh€…xrƒŠ‡|e}~ƒvcps€hxpot˜Œ…‚Š{vx€„yj\p}r€‡…‰}†‰zˆrnqƒ†Ž„„s„x€™Œ„xnn~„w{ehj}q`YwZYqnNXrsg`Klvta][[Yt}roWg]fjp_oNWiR?Yf_Zpkgyq[[XkeYcpy_h\^elhflipw‡nl}€upz€‚v…‰—Šq‚q{†|zy„“Œtjzko~t}or|{”on€xg’Š‚¡™œ’‚†g‡„phz–‰~…‚™Š|Œhxrklf_aoxm_boy\dlƒzaqv_eeÔ꾊2:>‹Ž€ry…ˆŽvƒ—~“Žnl…Œv}…‚•‰|ƒxnv‡„ƒ—wnˆ„lu{tfy‚ƒ§Œƒ‹„}ntvƒy…›‹‘’Œ‹†~{’‡x€„ƒl€ri~xm|{‚Š„xay„qdqh~mtqu›‹€…~sv}€s€o[l~txŠ‚‹{†€|ˆxzqlˆƒƒŠry–‹Š~tmkv€€uv]iixpYW|SZqeL[rre[Jpwo\[ZY]t~thYb[genciMWfQ=^f\]vf_tp[YTodYepyZh^_gmgjliow}Žli‚„~yn€{|€‚zu‚Œ“…p€‹nw~€{{ˆ“‰h{}jt{r†{sw}Œyx„}|kŒŒƒ›–Œ€lŽ~kiŽ{~ƒ”‚}Šˆkuqghc[bgro`alsahp‰zast^cd› n\5Y¯µuj€‰}’†v†—†t‹Šwpm…ƒ‡uy‰x‰}“ˆzsgvˆ~~˜op†}hvymeyˆ„¥‡‡‰~n~u€|‹™‡‚“˜ˆ‹„‰|ˆq{}„|i~mk€{zjzv‚‡€r`w~qdrgu‚mu{…”‘|owy|t~lWo~vt‹†w‡u‚‰zxrn‰€Ž€…r~}~’ˆ‰znnim‚‚un]hftrR[{N\q\O\rpcVKsxjWYYZaq€t`]]`gdhifNZhN@ad[`va\tmXWStaZdnrWj^ahkgmlipw|’kh„‰||p~~{‚zw€€‰‹„q{‡oqwƒ{Šƒj~{nwyvŠw}x€‚‡ƒ~~zm„Œˆ˜£„ƒ{vŒzkm„‰‘y}{‚‘€€~Šƒprpcf^Yg_pp``gpfjoŠuato[adjv{¾œ¦£È¸q…„s”}x†”‚tˆrrp„{ƒtu‡tˆw”ˆyyqcw†z€“ir„ufwvcj|ƒˆž‚€}r~s„x‘‚x–”‡‚ˆz‰‰lxyuh{ikysizv€ƒ}h`w‡}jkth{iv‹”~z~~p{v{s~bUv|rsŠ„‚}ƒp†Šwxppƒ‚Œ~}y~|uŽ…‚uiqil‡‚rp^hcsnKeuL^oUTYsnbPOsxaRWX\ap‚s[a\hedcjdP[qIDda\cq^]whUWUw][enhVk^ajgeooipv{“niˆŒy}r{~x‚‚|v}ƒˆ†ƒpvƒrnw‚ƒ~‰‹“p€|xyzŒtƒx‚„z€uo~‰‹šžˆ}…zw‡|ht†‘z|‰†„v€gom_d\XeYmra`aqlkh‰n`siY^dm€w©Ú©Ç†‡²q‰xpu{‡€z“Š€utu~w€pqm„t”†xul`z‚yˆŽfqƒogun[m}€“€y’’}x{m‡u€‹ƒs–Š‘Ž‡……{€…muvnhwem{vmjvv|abx†zhtuc}zgu†ŽŒ•{t€uq€z|lYVs}ot„‡€ykˆ†syktƒƒ}z}x{r‹€|rgtemŠƒmt[k_ueHnnL[bWWVxmbOStvXPUX^aq„o\`cmdc]nbT]rGCf_]fh]ZzcRU\u[[gkaVj_`nffkqhpuxŽtkŽŒuvx~wƒ{t~ƒˆˆƒoqtqu~†‚‰Š{wx„||…‡x‡|}~…€{~svyŒŽŸ‰zŠvuƒy^~†šŒy‡ƒt…†…w‰zbnl[b[[aVjsc`[gnog‡raqfW]ck|Ê·¹¢jmmŠlq„q|„Š~{’…zytyuu{jmuc„u‘‚wpg^}‚y‹‰eqkjqcXl{†œˆ‚‚s—”w~{n‡q‰‹‡q–Žˆ…‹ƒ{y~qqo~ghrbnxqjlqw}|z]ey€wiuxf‚vgt‡‹”|r‡io~€xm|]Xq~ms€‹|no‰qvgwv|qzt†|yrfsan‹‚lsXk_w\IokNWV^TU{kaOTurQQTV^bt…h\`kjfbYnaXbpGAh]`f^]U{^OVdpY[jh]Wg`_rfkgrgprw†xn•Štzw~y‚‡€us€†…Ž‚pp{wwuz‡†‡Œ†z|u‹~}…„„‡~~}‡|xvyw‘“ŸŒ}‹mu€ydƒˆ—†s’Šo……zƒtcnjY_[]]Tgse`YdrrgsbkeWZ`iw¾®{Ÿ·nbs†ht|rzƒ†z}Œxxsvo{vejn`‡uŽsjb^~xyŠƒfq}hjkZVoxŠ¤…q™“q€xum€‡r”ˆŒ‡ƒˆ…}ytrohzajm`mvjgkkywzw[g}|xer}n„teu…Œ†•o‹fkzƒtltb\o|kt{‹{‚fu‡}mqgu~x}r|lzzzwpelbm‰~mnVk`wVKjkOROhNY|hbNUujLPTU^fvƒf]aphg`Wi][khJEkZbdWYUyZNVmjY]le\Yec^tfmdqfrot€wpš…v~w|…‡}us‚ˆ”‚nsxzzss…‡‰ˆ„x€}v|„‰Ž„‚„{~‹ƒ{w|wwš—zŠƒ‡iw~|l„…”€r‚q†‚~‚oflgW][\[Tdpe_XcsuivpeebW\\h€por€s‰dex~itvssƒ…x„ywtunk{qagkg†t„nf]_}o{‰}hlwfidUWrp¦|„|v–s|s{ym{z„v˜|‡†‚†ƒ}uprlgu]mh_ludgfizo{rYgwugp€x‚ubw…Š|”€n‹jmz€pere`lyfrwŠ{~buƒvikqtzpyxr}f~xvnceam†|mkVkcqSLikPLOpG^{faMUtcJNSW`jv}e]gsie_VcWap]LKkXcaUTTsWLXudZ_k`\Zce_wfmbpisnq~tt™w€w~†„z}u‚„~—…nrt{ztq……‚€z‹ut€}”Ž€…„|~Œ†z~€v{£¥Šyˆ…„lu|{u„‚Œzn…sz…}ƒunjheV][ZZSbne[Xat{jhmi_bW_Zi€jko€glahyyktttn…z}vunzhjyj_eniw„geXbwi~‡zoioff]UXoh§vz|Žyuo~oruyŽw”t…‚…ˆujrvgho\me^ms_gaixh{m[m‚rsio€~ywaw„„x„sˆqoyqbph[nwdpsˆ|ybs€pgjxsrkwvtwcƒ{~wvpdccn|}klVjcgSKlhPGRlEaxfaMSq]IMTYekwze^mpid]V_UnnWKShXf^XMUlUJ\y_[_k]]Zbe`zhlaoounowuz˜}w€z€‡†zyzƒ~“„qtt~zvt…ˆ}€}ls”{‚Ÿ…‡}€~†‚€Š{v„¬Ÿzˆ‡„lr‚zv€un‡o|€s‰€jomddX_ZYZUbjg[Z_u‚i^ml\aV\\kfrt}ij]kvvhtwqm†{~}yvrlzhiwf]dshzw’ccTeof‚„wvfhi`WVYhd§n~x€‹Žzpp|fxny‹{vŽq„}~†ndvsdhh]kb]oo[g_luezh]t€orkq{~uubt…Šz‡†€wru~taplYpsbqr…|tdr€lalzojhywtqf…uzzupdadns~jlUj^^TLscQGWbGbvfaKToWJLXXgkvzdenpfcZX]XveTJ\cXhXYHWeQHbxZ]_l[^\ad^ij`otxmonvƒ—yr€}ˆ‹†}vv†x‡Œ}suuxzz‚ŒŽ}~„‰jt–{Š}~…y€z~|†ˆsq®Œ{{†~frˆzt}}vro†l{~lzbpoae^eVYYWcfk_]]s…hYpnZ^WZ\l{cpwvlb[mstguupm…y€ywnoteite[gufvv‘z_]Rffj‚s}aci\TX^bc¥hyt‚…xmnygwm{„zuˆr€x|xhevm`fa_j`]tkYe]oobze[w{knnpxxttdrƒ’~‡‚ˆzvoq}rawdZnpapq‚|sfr€d^nvicfyztmnus|sqb^fno}ejTiYYTNx_RJZYHbtcaITmSILZVilr{bllsbaYZ[av\SKd]XiSWGY`NGiuX^am[[_bb]…hhanxylnjvynƒ~€’ˆ„vt‰tŒ†sqwvw|}~Œ€~“~px–ƒ}™’y€€xy~sˆƒsp™¢{z‰•yduˆysxvlto~ly|p‘r^pn`gblTZYWhcme\\q‰eSrn[ZXX`lvdiujj^Zmsqltstj†|~€|wonldiqc[jrdtvs[VSd`q~q\ac]SZ`\c’Ÿerq…„‘tljylooz{zq€v~rzzzdeug^bZag\^whWb]ohawa[{vjirowtsthp”‚†~„vrjp{lfvW[jmbpszsfo~[`pqb^ip|lks~rqxkp`\elm{ahTgUWRPv[SPZRHcsb`GUjPHOZUkkk|emoq`[ZXYlpWRPfWWiSTFZ\OHruX_cmcXa`a]‹icdmyxkniuy†{kƒ}„™|‚„y}ˆn†qowz|t‚‚|‹ƒ‚–tx‚”…Ÿ‰u€€t‚p‡‚uo¢—t{†‹‡{fx‹on{ofxpzlsvsk^tnagekR][Ugbll[\qŒdOon]VXUgithbtee]Znunpuuzk‡||ˆwscekoa\nmcsx‡kZTVbcw||p…\c_cT[`Yc–•cnpƒ…Šsjhznervs{lztuoz~u_frc[^WbdYaueU_`mdaq]]~phisqspuukm„“ˆ{…qrfn|oqnSZejeqtvsbmvUbqk[^ne|elu|rrrjm`Ydjjx_gTeUVPUnXQWTPHer_aFWiNHXTVmid|ikwkaW\U[tcSRWhQYfTSHZZPNxw[_fliZb`^^nbfkyunohvv~mƒ€~†—{‡Šk“ˆrgt€{u€ƒ}‰‹“r}Š‘…‡Ÿ†{†Œs€†s}‚un¥Œs‹wxnzŒ`d|qfzsylmqvƒgd|lcfghS_^Tg`lo\^nŽhNim`TVSofskexde]Yptmrzxsmˆ{€wœ{zkaelm^`ojepy~gZVX`kw{{oƒ^b^gVY`Wdœˆbkq‡}wkjwl[vqkyiurmo{€rXjm_Y]VbcXeqcS^aibblZ`~lfksunmwvkh…Œˆz‡mqeo{lqlbX_hhotsr^imSepeUbnaybpv{ukolj_Xaghu]eVbVSNYfSO]OOHeo]cGYiMI_KXmd_xhn}d`U^T]t[TR`fN]aTSJ\ZQYuu]_fmhXba[^Žqcgjwqsmhvtyƒs‚ƒzˆ~|Š‡ŽznŠtls‚tˆ…‡’„•z}Œˆ‘›„€|Œ„rstwqn““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|}~}}~~~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’‘‘‘‘‘‘‘’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’‘’’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ”ÎÚØØØØښ„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDEB1/000/,€¤    £€cggggfo„ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ”Ûéççççêœ~‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR4555553~©¤¤¤¤§|\____^j‚€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}zzz|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹’—˜˜˜˜™™’Œ‡‡ˆ‡‡‡‰““’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†………†…ƒƒƒ„„„ƒŒ‹ˆˆˆˆˆˆ‰ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z{|{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘‹Ž‘‘‰‡ŽŠ’“ŠŒŽ‡‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…Œˆ‡Š††‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰‘ˆŠ…Ž†‹ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰ŒŠŽ‡Œ†ŒˆˆŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}|}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹ŒŒ„‰‡†ˆ…‰ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz||||}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒˆŠŠ‹ŠŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzzz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{y{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†……………„„„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰ŽŠ‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{}~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““””””“””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••””•“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””“’“““’’’’“”““““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘‘’“’’““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’’’’‘‘‘‘’““’“’‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘‘‘‘‘’’‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ˆ}ŒŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ{ŒvŠŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽs‡Šs…ŽŒŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡ƒn‚‚pˆ……„„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxz}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzop{xy{|{xw{xuwttvuuvwuqfmjqsoghklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkiffggghhglgifrnhgcbbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__ac_\_]`]^Z^\ef^rl]^ZY_[XWSNMLKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{xvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSTPMJMNPRONPSabYkdTQQQTPPNNOLJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTtsuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMOPYhhbibQOONOPPQONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKKFCFJMcrkgpjUNMLMOOOOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEB@?@BPlsmisq_OKKRLHHJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:;>=BIB<OipmdrtfEJ^TFBDEEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@:;><;;;AYQ>Efmi`pqiRafEEFDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnpprtusqrvyy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;:;;99:88;<979:G[SScjjnqmjhmT>CFDCCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqtsurqtxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<:79::979::78:Mcciljromklc@=@A@=;;><==@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyy{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>><==?@===?C;=>]mopmqnlklO;>??A@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquutusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCDA?=>@A?@;]m?>CKfrqopnjk]<:=>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVppqssttuyz{{|~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???BFD><<=@=8:;mvH8<9KkropnkgG;8:;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pprrrtuvz{}}|~~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC?>AAABA@YQ<==ILEFuvM7898JlrrpmS;<::;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC@CsyI;]ƒy{wV<>?==JfwmR==>?==>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hloppqtuvy|||||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCEAHrykb‚„ƒ‚ƒ€}]>@C@A>EtV;<=@EABBFHC=<@DCAA?>=@A>>>?<>@DGE@>@A?@CFECBCC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{{{}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@Fot}‚‚ƒ~}„uMACE@@ANvjH@CEIIIIMMKECFGHEGEEEDDCA?@>>BFJJGEEGFFJNNKJIGGHKLIGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@EEhs}|„~y…pBDEDCXu†ˆ‰~XGIJLLNOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHIHGFEFFFDFHGEEHHFHGHFQnnpqruvy{{{z}}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJG`{€w„…ƒ„‰lAAVt‡‰‡‡‡ˆƒWHLMLMNLJGGGGDGGGGFHFHECDDFEDDHHCCCGJJKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrsvwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLLN[|‚‚ƒƒ…††ˆƒUl„‡†††‡‡ˆ‡|PKLKHGFFDECC@ACCCCFFEB@>>@AA@BD?>?DFHDEGIJIIHHIGIIJJIHFJJJJIJIJJJFILLJJKKfopsrtvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKLLJUƒ„„‚‚…††ƒ‚†…„„†††‡ˆ†ŠuIIFB??@???<<<>::<AA@><998<<=;>;9;?AB@ACCB@ABDDBCFHIHHHLMLGIJMMNMJJKKJLMSloqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHHJJIe…„„„‚ƒ‚ƒ„„……†‡ˆˆˆ‰‰ŒŽfBB=88::9878896479;<:8567789787688;;;=@;999=<>;;=ACEHJMLLGIHORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@CGIIj†„„~ƒƒƒ‚ƒ„†‰Š‹Œ‹Š‰Š‹Œ‰T;8656766645763468:876565676778:77789;7578979876:<@GFIFIFEFOSRSSROPPRTepqsttwy{{{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:=ECBf…ƒ€‚ƒƒƒƒƒ…‰ŠŠ‰‰ŠŠŠŠ‹‰‰ŠH676468874578467699766765:9:;:;898977779:98878589;A=>>BA?AKLOQPQOOORWkqrttuwy{z{}}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897;B:=q„€ƒ„„„„„†‰ŠŠˆ‡ˆˆˆŠŠŒŠ‰‰Œz>988;<=>9:;<89;9:;:99;:9===>;;<=:>;9;;<;<<99<8::;:999<?<=ABDIJMKIKLWorsutvx{{||{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<;89989:::;?>H~„‚‚„………†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>BCEEAAAB>@B@@>==>@???@?@==?B?AA?A@=@@@>?A=><;:;99;?=;;==AACABCAXpqtttvy{{|}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::<=:;;==?@BR‚‚‚„…„…„†‰‰ˆˆ†††‡ˆ‰Š‹‹ŠŠŠ‹Š‹^>CGIKJIFGGDFHGEB@@CECCABCB?@DHDCEDEEAFEFDEFD@B?<@>=?@>???>?>>:;=<`qrttuwzzz}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>???=A@CDFX…‚ƒ„……††ˆ‰‰ˆ‡†††‡‰‰Š‹ŒŒŒ‹ŠŠˆWGLMMKNJIKHIJJIECDFGFDCEFDBHIKHGGFGGEKIKIJKJCFCCDBAACBDCCDDCA=;=@hpsttwwzx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLK@BBA98<>;<;>@?A?BBGGIY…‚ƒ……†‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹‹ŠŒPMPMKNKJLJIIHJFDGHHIEEHFFELLMIJGGHIJNMNLLNKGFGGEECFFFFDEHHFCA?@Llptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?EGG=<@@98<;<=:?@>?@CFIIP_‚ƒ…„…††‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒ‹ŠrNQOMLLKLJHHEJIDJHGKJHJGGGKLNLLHHIJMPNPNMOKIGIJHIDIHHFFGGIFCBACUnpuwwy{xyzz||}~~~~}~}~~~~~€€€€€€€€€€€€€€TDAABGHB?8?@9:<8=>;=A>?ADHJLUqƒ„„„„…†‡ˆˆˆˆˆ‡†ˆˆˆˆ‰‰ŒŒ‹ŒŒ‹‹‹‹‹_RRPMNMKJGFBGJGLJFKNKKJJMMLOPNHIKLOQQPQOOJHJJLJKFGHGEGHFEEBABB\orwxyzyyyzz{{~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<9@>>@BGGAGKLPVy…ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹‹ŒŒŒŒ‹‹|XVRRTROLKJDEFKONOWUQPOQSRMSTOMSLPSUVRSQPLJMMMKNGGJFFIJDDEEBDCcpuyyzzz{z{z{|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?==B?CBFVNFNPPTX{†ƒ……„„‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŽ‹‹‹hVUkaERQQPI;;QSR`u]UVTVYYRYXRZfPUWZ]RTWQPNRPPPQKKKHHJHEFIIIHIirvyyzyz{{|z{|}|}€~}}}}}}~€€€€€€€€€~~SHJIIGFFE??AAEBCGEDELXRMTUVX[|†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ}aŠ‹‹‡l[dU:XXXSQ?@VUY\d`VYbr]]V]ZVEQYZ[Y_TZgRUVXTTVTOOMJLJIILMKOMSosvxyxwzyz{z{|}|~~}~}}}~}~€€€€€€€€€€~~~VJJIHGEDDBA?HMIMPKIKPTSSXZZ\\x…„…………†‡‡‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~Œ‰Š‹znpXZ[ZRTRVVTZZuƒYU}`\X]_WIV]][[_YIYXY[]XXYWRQMPQMMOSQQURassvwwvxxxz{z|}}}~}~}}}~~€€€€€€€€€€€xy}YNKIIHFBD@A:PQQWXPPOQSTTXXYZ[n‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡ƒŠ~fYY\YSUTWRQWVc–€QerXZW_gP`f[[X\gaGOZhg\[\]]WSNSPPQVVVVYZnrtwvvuxxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZ[RSQORRRUSVTW_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PUXTRTRQQLOMKfyZ]TYUV]ZLTZTST^ZXWWWzkXZ[\^TQQPINOWVXZZdqsvvttvxyy{{||}}~}}}~}}~€€€~~zxwvsu{€€tk~~kry^[VUTROKFCDAM^ƒlVRSNOQOQURSRRTcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ymqVIKMNKMKHJDFHEC>ScURQQNKRTQMOYQMNQSUUMQSRPOMLHCIHRTUZ\mruvutsw{z{{{}{}}}~}}}~}~€}}~~€~{vsw}~~du}iqt_d]^[YVPLILIal’tPQSNQRQR[RSRQRVTbs{|€‚}{{€ƒ‚…†‡‚†††„†…†u_]KC?CCCCB?DPBC@C>BHGV@HNMG]iQHFOFDEFHGHBCHGHKGDBADAOPMSdstvustvz|z{{{||}|{~}}}~~€€€||}€€€}vt{mh|gnqfiedb\XSQPURsWe[OONLQSQUYSUQQTROV`klrv{{xytrnstsyx~~ƒ€ƒƒ‚€‚€‚kLG??;;>@@??>jQKaEFHIEB?GLMGMQUIBE??<=<==?=?ACC@?<=B>JMFUnuuustvxz|z}||}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QRZ\Y^JJPQNKLQRQTUUWQQWVPX[b]agmmlokg`nrjmlqu{z}{xz||xwxdB@@B=:BCAADB\]O{NONNKLMOOQLKLWMHG@B<977599=;;;8989?;BH?\stuvuvxz|||}||}}~~|}}}}~}xuvz{zwyxuw{|yxuywcqhipmnmmhf^OP^\ZIHPRQOMPQNQRTVXSRYTNYZ[WY]^^`e`]^qvk^`gkwooljonnlfbXGFFHBAGIEEFDMRPaWRWQPSSRU[OOQWPMIDF>:96587979:366795<B=essvwwyz{}}||{|}~~~{}~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZWMKTTSQQUOLRSTWXTTXRLWYZVXXVXY]WWXhsk]Vaskaa_^da_^YUPMONLIHJKIHFCQPSZWTTNQSYS\eUOSTQNKIHC?A9988978857578599Gnqtwxz{{}~}}|{}|~~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPXVVSTVOOUVXXYSUTLKTUUUUWPTUWTUR]n^RNY_[VY;DVXT[fJLPRROMMNNNLJFQPUYSTNJOOUST\VRUSROMKIHHF?>=:787659967675Wppswyz{|}~}~||}|~}}y}}|~~~}||}}~}|rvqxxrvuqqnppopuvtnjddjppqrpnfedc\^RTZVWUTWTRXXYYYRUOIGOPOOMRJOPPPNNOTLMIPOSTU2<XMIAQ=caQSQPNPQPNNMQNTRPRMILKORPRRSTQROLLKLLHCBA=::876;B4566:doquwx{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqptuvcjgeWhtrrqniihpVVTUXUWURWVUZYXWUQSFFAFGGHFJDHJHGEHLHKHFLMPMG/E_R>3@>joaRRQ@FUQPQPQNQOPOLJLLOPNNPQQNPOJLMMKGEEDB;=<<9=G6677Dmptvy{{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknaePSTRSTOWVVYYVQQQO@>;=?@BAC@BEDA@GHGHEFHJMKEGCORC8ENS]fSQSAGUPOQQPMMNMKLKLNOOQMOOMHLLIKKLKGFFED<AA>;@E;<89Sprtx{z{}||{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLOOMQSLTUTWWULLKH=987;?@><=A@B=>EHGCFFIGJJ@FAA@FHEJOHPRa\QPRNSOOPLLOMKMLMON[WKMQOGIHCIJLLJFFFD?BC><BF?B?Adpswzz{{|{zzw|wy~~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCE=9879?B>;?B@@>ADIECGGIFIEBB?>=CBAGJEMObeQMNNWKLMKLMMMLKNNSdMJLRIIIEAHJLMNJGIFBAB@?EFEHDKnovyyy{{z|zwsxtx||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGLMIMPMPOHKE?B=999:?B?<@BBADEGKFCIIGGHCC?B??@A>DECKNQTLJIMTFIIJLJKLIJLMOPRPKGCKGCBJJLMOMIJIGCCCDIJMLIYrmwyxz{{y|vrpurtyyvxjqnjllnttmtu{stxronqovsnporpopstyjN`gsjt|ygosqiqheqHKCGHHGJKIJKDGB=>=:::;@B?=BBBCHFJLJDIIFGGCC;A@B>@@CDCIMPGIKGHKDHIKMHJLHIJKJM]RHHDMGADKKMMPNKMJKFGGJMNQNLbmivvw{x{z}qmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoijthdoFKDFEGEFFGEGBC@><=9:::@C@>BCDEIFJJLFIIGFFDB;BCC>@DDCEGLNHKNHDHEILNMHILGFGIILNKJHENIBFMLOMOMNNMKIHIORQRNRfffqosxu{z|lhjnekpmsqfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGJCEFEBCBE@DB>@>:;;=:=>CA>ACEGJFIHKHGGGFEC@=EEB>BDCCEGHIGMPJFFGKNOKFHJFEDEIJHKIFHPKDIMLPMONOONKJHMRUTROWd`amgproryzgehhcilgqlflmgiklslpvutpnvrosrsutqssutsuvvvyvutwljuumrvqlnlerMHDEGCB@BD=BA>A=::=?;>>@B>@BDGKFIFIHFFGECBAAFFCBCBDEEGGHFLQLIOJJLLIGHEFEDCIIHKJGKRMBNOMPOOONOOKKKOUWVUTX_^\iaminhrsbefedihfnifmmhkkmriqvusqmvnoqrswsrstuvvvvwvwvvtwujsunutsqrjksMGGFHBB@DE<A@@C<89=>9?<?B@@@DFHEHFFGFEEDCECDIFCFEBEGEFGGEJMKHQMJKHHIEFHIFCIJIKMKOSNDQRPQRNOMNPMLMSWVWXVX]Z]d`hbjigk_eefcgggkggkmkmlpqgttursnvoqprtxqssuvu‚‘yvvtxuuwxmouorsuqqiozMHGHHBBBFE<?BBD<7:>>:>:@B>??CEFDFDDGEDECDEFGJEEIGCGHFHGECFJJGMJLKHJLFIIKHEKKLLOORTOHSUSQSPQMNQNMPWZVZYVZ]ZXa```^hec`dfhgjihjfhnllnmqpiuuxrrpupppruvpusuvu{~}xvtwvvvxplupmstnprryNIHGIDACHE<@EBE=8:>>=<<AB<?>ABFCEBCIECEEFGGGIFGKHCHHGIGFDHKIGKHMKJKLHLKMKJNLONPRUVOKUWTQTQRLOQPOTYZY\ZY[^^^`c^\ackb`dghr…hgjfjmnponsrjtuxrsstrnpqvrquruus~yŽ}uuvvvvxrhuqkrtlqvpuMIKHJEBEGE<@GCD@:<>@?>?CB<@>AAFCEDDIEFEGEHHFHGIKIFJHHKHFFLHHHJGLLLLLIMKMMMOLPPQUVWOKVVUSSRQLORRPV[[]^[\^__a`ad]d`ef`ehjcssfjhglprqossnswwquvtsmoruorspurvrtvuuuwvuwtgtrkqrkrwovJKLJLGBEDE<@FDDB;??A@@@CA?B?ACHBFEFHFIFFDIHGIHJLHHJJILJFJKHIJJGKKMMJJMLNNNOKOPRUXVMNTVTSRQPLNTSRW[^^_]]`_`aa_acebchbdijgv‹ljigmosqpqppryvruutsmmssmqrotutrpswtuuwvuuteqskpqjrvowKMLLMGCCAD<?EEEC=AACBBCEABDAAEGCGHGGFJGCHIGGJFILHIJMKMLGKIHLKNQKRQMSMKNNOPPOTOWXX[NSQW\ZSVPNTUTTXZ_bb_da^`b^`eaacingbihhnxvlhimosrpqrrrvtsusssnksqmprotvrqquvuswywutucmtkopjqtowLNLLLGEA@D>>DEFC@CAEDDFBBEGCCIFCHJJIIKGDKJGHJIIKHJJNLNLILHJMKZfJd\KlSHON_nUks[qpbwcRPavuhucav`Xnqbdvinzf[lt`ljT_wvijgifglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqrqyLNJKJFC?@B?=DEFDCDBEEEFBEFHCDJEEJLMKLLGGMJGIKHKKIKJNLMMLLILML[sbdp^lmUMNfs]geqlntgpi_aYnnbppbkjjgoqtetno\ougpMJryvkb`keemxmlvlnpsrprqpqrqrrrtrmmsnnoprutqsstuuutwxvutbmukpplrrqzKLIIGED?BB?>BFGBFCEDEEDCHHGDEKGGLMNKMMGJNHJKJILKJJKMMNNMMJMMM[roonpplkMPQlWNibtrpamov\YlQ\mmZqmkomxxtsip\_rkqjUuyxpc^kfbgppjioppsspqpqqrrqqrrtlmrmnnorutqtrtuutuuzvutenukpolsrryJKGHEEEBBB=@@FGBGDIEEDBFIHHEGKJGMMNKMNGLNILKIJMIJJJKOPONMKNML\hdu]lqWlNPQmUZk^klvaldtTecNmYl\tpkilxjwuhp]^rkhWbcw|oc`ggadityknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtvIMGIDEECAB<B@BFDGFLHECCHKHHFJLLFNKLSRLGLMHNJHHNHJJIHNOMNLJNMJZsppoqqmlOQRnYqkgooqqomt^nXat_nnooqronusttj[^tcwxrjnzhaacfbbjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyxtukoumtonssvsHKHIBEEEA@>CDBGCHIMIFCFJLIGFJMLFOJKWRKGKJJNIHJLIKJIHJMMMLIKKKSkbZi^_icrrZ_Yjo_eeUk_c[aaQ`lh]j\ojid[pfdp\Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunwqrutwrHHFIDEDFA@AEEDGBHJLHFDGKLIEFJOLIPIL[QJFHHKMIHJIKKIHIGKKLLFHKKLLLKIKLNT[\TPTLPONOOVQOOQNOQJINPQeriTYW[[\UYZ]X]\\cfaaebce__fkmhmtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyxxuvqruovrtsuusHCEGFFAEC?CHDFGCIKLHFDGKLHDGHPKLOKLWLIEEHIJHIKILJHFGGIGHIEFLIJKNLIO\W^P\[`^OXYS\\b^MYZMXaRJYaZS`d\aX[ddVVX\YZX\VY\]b^d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtOBCDLMBCDBEIEGGFKJKHEEJJJGEHHPJMMJMSIHFAHFJIKLILJHFEIGDFGEEJHCJMJKT_Y`X`a[`UXYT^^Z_RY\P^\YN^\^S[^c^Z]`c`Y_b[`^[TXWY^]cbcacfiekrpoppnow††……†‚{€……††…†…uqprrsvyyzyyxxxwryvxrqxvtvaSJJMIECBCGGEHGHKIIIDFKKKFFIJNKNLHLNHHF>GGLIKKJKKIGEIDCDDBFJD@JLJO[cY_^a_RTRW_`\]Y^QY\MV_WKQY[PZ_aa^^ca`bbbcceZQYVU\Z]c`__cebhomnllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxXQKFCGEBEHIFGHHFFJGHFHKILDDKJNMLKHJJHJG?GFNJKKMKKKIGGCD@DAHIB?IJHO]aZ[d]_TQRX]\\\_ZKW\LR\YIN^QO\_acdccb\dcbdcfXQUTR[XZa_^^aa_dlkmjjlnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMC@IFCEKJFFFHGGIFFFILJNEDKJLNJLIKJHIFBHHQMKKOMKKIHGED?ECHHAAGFET]Y^X_Y_[]UXXP]]QKJV^X^[]VY`RQ__aba`bb`cbaddbXOQQQ[S[]]]]^__dhgljnnp{{|~{€‚ƒ„………………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKCAGFDGMRHCQJFHHHEFKJMPEGHJKNLLILKIIGDHKQOMMPLMKKHICDAEDHGBAGECWUE\T^SV_XNTUNZ[MJKT`a[_X^^a]OYb\``_bcb]abW__TPNOPXR][[\\^`bffelfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDEFGDIRbPCV^IGGHDFMJPPEIIJKNLKKMLJJGDJMQQNNOMNLNHKADACDFDCAEFBMHBKLPONLFMFGIJHGLLMOPILOPOSPLQSRUZYWYXXdWOSTPPNMOUT[YY[]\`adecgcklpsszy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKM]LGGXMGHJHGMLQQILKKKNNUNOKKLGFKPSSNPONONOHKE`ED_LDfcEM[I^[rmOMUmYLCP`UlWgJ]WU^DLQULMTVQRTXWTXUT\UPfZhhdXSkSVVU[\[``aaab`fhfnlhrz|}~„„„„ƒƒƒ}|zr{z{‚€ƒ„„……„…ƒƒ~z{LIEFFHEEKOSIKF`THJOJIOMRQKMLLORUROOJLNGHMQ[YOPPNOPOIJPQI|YYrsXPmHqnoaVPqqsPCksmqtpSo_[nX]V\XUkhU]VcZ`Y[`VUWjtuu__v_Xa\\f[_aaaa^`bgmpl`pwtx‚ƒƒ‚}~€vxzlv~tx~€|~€‚„|€ƒz~wwNIEHMNBDLLFJLFQVLKNIKRXWQNOOMQTNOQPKKNGMPS[ZTQROPPPJHZx]TxehYRTQvgtlpbnfjQrOMwmjrpsrqrpoo€]fzuxqqzq~s}ku}bRg|essosr{|o}yor_``baZ``gknkblfgmw~€ƒ~{xw€tvzir~nt|~wx{~€ƒx|€u|||ssNKF`]GAEMMHKKHJPNMMJNV^YULQSNYZMSSRNLOIQRTYWWPTPPPQKGfxlcxrmZKMUypumubnvPdeJfvqmwo€jfxxiWrRi{lijzz}lxzogoXvvjuup€`rg}ilx|o^__ba[]bdgijdgbcdllppstsssyqrxblugry{ssuy~suzn|}yxrnNKStNCBEPPHJKJLQOOOMPZ`ZXKTWPa^RVQYSLOISTUXWWPUPONRJKrouuquqdibWnLqp^FhyWvTKhx}x`y{sna^mocRgqunmypwlvttqlm\t~zkmy|ktm|kpvux^__b^]_ddighee^abiiijknokqnmjpacfdowxompsy~nqpj{ztromLL[VHGEGRPILMKLQQQPPQW\YUMUYUfXRRY^TMNITTVWYWOSNNNQHRmHiwK`dvvVXlOnl{sajgvUKWkh}lmlx`[pz{^`zscroxqhe|ir|]TKl`vukiv|{m~xk|p]^^b[_bddgeeebZccikkrsrwgmihdg`alagsrlgmmr|kmhk{tmmkmOHJKHIIHQPLNOLKSSSOSRWRVTPW[VVTTTa`PNNKTSSQUVNNLMOPJHQNPULKKSTSRTPVUQQNQQXXQNPUTXXX[[URSW[WXWZOSUWWXR]YW]VTOYRWWWXY^[gr^[[Y\]_cZ_ccdfdccbZccfffmnmuffgc`f_]g`dlhfgkhpzhggkujhgilQIKLLMKJSQMQPOLVUTPTUXUYUQZ]VUTWUYXPOLMVTQNUSNOMLQPKJQRKQMKKORTRQQSSIHLNOQRQQQTVRXW\WSSPQUUVSZQOSRWVTYVTYUTRUTTTWXW]Z^a]\ZZ\\`c\]bcdfdedaY`acabhhincad^_c]Zd\bma^fefmsdihkkedcfhPJKLOOLMSPNSQQMXWUTUWWWZUS\`VWVYUXTQPKOWSPNUPNQNKSPMOUTNQNMNQSPTQSTUNKMOQTTRRQVWUYZ[YSURTWWWY[TOTUXUUZUWYURRXVUW[YZ_]UY^\^]\]`a^[bbcgfddbX_`b]`hefda^_]]^ZZ_Z_g`^]]bhkagfhfd`bcaPKMLPQLOTOOSQOQZYXWXZZXYV\jdVXYZWVTTPKOVTPOTPPPNMQQPRXTQQOMOSVNWRTUUONMQSUUTTRTXVZ]\ZVWQRWXV[[WQTVVVVYTXWTSRXVUZ]Y]_^V^]^`\\`___ZbbdhgddaYb`b^^fcc`b]\\\\YZ[X[a[^]\_b__bdebd__`\PMNNRQMRROSTQPU\ZZW[[\YZ[dqmhd_[YVVXQLMVSMNROQROLPSRUZUSPPLPWVRWSSSXMOPRTXUUUSUYX[^][[VROUVV[[WQTWVWXVTXZTSRZWV\^Z^_`Ua\aa]`b`]`]cacghdf`Yc`a__ed_`c[Z\[\YZXYW\Y\[`^_[^^a`_b\Y`ZQNONVQPTROUTSPW\]\X^\_W\^jqwy€c\[VVXQNOVSNQQPRTRKQTTYZWUORNSXWTSTRRZOQSSV[VVWTVZX]^\\^VSNTUV\\VRTVVXYSTY\TSS]XZ]^\```Vb[cb^ac_]bab_dfidf^[d`a`ace_b_YZ^[\[YXYWWZZZa\][]\\Z]`W[[ZPOOOYPUURQWRTP[]^^[`\`U\]ijr}slg\UXWQORZSRQTRTUTKQWV[YZSOSRVVVTOVRSZRTUTX]WXXSX\X^]YZ]TUNVWW_[XQTUYYYUWY[TSV^Y]]`]bb^Y`[eb_dd_^cca]efidf]^da`abcd_b^XZ_[\[XXXXW[Z\`\[[\[XZ[^V^Y]POORZPZTUVVTTT^^`_^b\`U]^bkyum}lZUYUQQS\TUTUTVYWLRZW][\ROUSXVVTPXRSWSVUU[]X[YUZ^X_^Y\YRWRYXY_ZZSTVZYZVXY\VTZ^\^`a_dc\^]]eabfd^_dc`\gdhedb_da_a`bb_`^WX^Z\\ZYYWV]Z]^ZY[\[WY\]VXW]SOPWYQ]UVYWWUX_`aa`c]_T]^beev‚{hXYYSVSV\WWWVVW]XPU]Z^]]TRXSWVTSTXRSVTXXX]^X][V]_X__X]VQYTYZZaY\UVX[Z[XYYZXV]^_^cbadd\b\`fadfd_`dbb[fchecfaf__aaaa`_^VU]Y[\[Y[YY][[[XXY[YZZ]_]TY]UNTZVS\TVWYWV\`abcac^_V[`da_zuohY\ZUWUW[ZY\YXY`WPV^\`a\TUXPUWUSWVRSUVZZ\_^Z_\V__Z]^Y^VSYWYZ]bZ^VW[\[\[[YZYY^_``dbceebdZbfcgfe^ab`c^cciddg_g^bbcaa`^_XTZZZ[[X[XX\[Z[WWYXW\[\`]V]]SPVZVVZUXUXWX]_badad`^YYadb`kfh^\][VWXY\\\_[Y[bVTX^]ac\RVXQWVWVWVSVTX\\^``]a\Wa^[^\[^XVXX[[_`\_XY]\]]^\Z\X[_a^`dcdfffbYceehgd^c``ec]fidei_g^cbcaa`__[XY[YZZXYXW[[Z[WXZTY]\Z`\U^bNRWYVWZX[\XWY^`baeada]^Yacb_a`a^\\\WW[[]]__\Z]cXZX]`cd_RXYPXWXYYWVXV]]^`a`_b^Ya]]^Y]^YXVW[\`_]_ZZ^]^^a\[[Z\`a^bdcefefbZdfgigc_c^afdZiibfice^bbca``_]]ZW[YYXXZXWZ[ZYWXVU[]]]``bbxLWW\YW\[\]ZW\]_`bdbba]`Xbcb`cab][\[XW[\_]`_][`d\\XZcec`R\YOXXZ[ZYXZY`]`bb`ac_\b]_][^^YYUX]^_`__\Z^^`bc\\X[^`bacedgeefd\efhifcbb\cg`\iibhife`baca_`_]][Y\YXWXYXW\[ZWWXPXZ]acffrkJYW]ZZ_\[^\X][^_acbaa]b[bdb`ccb\[[ZWXiq`\`_]\ac_^YYcedaS_ZQYX\]\[Z[[c`cbc`bda`c^`\^^_ZXV[_^]aa_][`abeb_]T\``cddfdgfefe^efhhgdd`[fg^ahhchhfc`b`cb___]]\Z[YXXXVZV\ZZVVUMXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡…‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vvvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{{{{{{{{{||||{|{zzzzz{{|||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vvvvvvvwwvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{{{{{{{{{|}}|||}|zzzzz{{||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚‚ƒ‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||upooooppz~}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰‰‰ŒF(****"‹ÛÒÒÒÒÖº}~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}upnoooooz€~†“y1333332j‚€€€{­éääääèʉŒŒŒŒŒ”;ïååååéÇ}~}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}vuuuuuuuvwwwwwwxyyyyyzxopppppprrrrrrrwzyyzzz~ƒƒƒƒƒ„||||||}}}}}}}}vssssss}…„„„„…‚|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚‚‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vvvvvvywvvz{x{xwvx{xzyy}zyyxxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{{{{{zzz|}}}}}}{zzzzzz{||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwwy||{}z|{xwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwwwy|{~y|zxxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z{xwww|yy|z|{wxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚ƒ‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzzz{{|{}{xxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyy|{zzy{yxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyxyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{|||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}|||||||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}|}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrstuttssrrsrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqstsssrqqpponnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqqrssssqpqpoonnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrqrrssrrpppoopoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqppqqrrqqqpppooppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqpqqqqqqpurppppppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqqqqzqo‹voppppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsqu‹‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqqqqss˜xpqqpqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrrqp—{v prrqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrssrrrrrstŸ‚{¤‡qttsssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz~|~~|vvwwvuxzxxxxwwwwx§Œˆ¦w|{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~|{{{|}~©’†¥•z{{{yxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}}|||‚«œŠ¢•}}||}€ƒ€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€€€‚€š¯¨§§•€€~~~~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~€…¬¦¥¯¦Ÿ‚~~~~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~€~~~©™¢ª›£€~€€€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹Š‹‹Š‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚ƒƒƒ‚Ÿ¡“Ÿ¤˜Ÿ˜€€„Ž‚€€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒŽ‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒ„ƒ‹‹…˜Šª›š„ˆ›’‚ƒ‚ƒƒ‚ƒƒƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒƒƒ…•›Œ’“®™“žŸŸšˆ‡‡‡‡††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠˆ‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„ƒƒƒ…„‚¥ª¬©£¥™¤¢‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ‘‘‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„„ƒ“¦¨¡œŸš›žŸž–„„……‚„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘’’ŽŽ‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€‚ƒ‚‚„‘—–˜™œžœšŒ€€€€~€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„„„„…„…†’“‘ŽŽŽŽ‰ˆ‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~€‚‚€„ƒƒ’–š—› “„ƒ€€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“’Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚‚ƒ„‚‚„„‚ƒ‰—ˆ„‚…†–™—œŸ›ˆ„ƒ€‚ƒ‚‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘Œ‡…ƒƒƒ‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒ€ƒ‚……„„ƒƒƒ‚„Ž™‹ƒ…„„Š“™•šœ‚‚„ƒƒ‚‚„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”“’’ŒŒŠ…„ƒƒƒ‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~Œƒ~}|}Œœ€‚‚ƒ‡’‘Žƒ‚ƒƒ‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†””’”’Œˆ„„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~•—‰€}}}}{˜Œ€ƒ€‚€„‰ˆ‚‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“’Š‡ƒƒƒ„‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€€•ŸŠ~~€}‡Š~„„ƒ„‚ƒƒƒ‚„ƒ€‚‚ƒƒ‚‚ƒƒƒƒ‚ƒƒ„‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†ƒ…ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„‘¡ŠŒ…}†‰€~………„…‚~~}ƒ„ƒƒƒƒƒ„ƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„……………„…†…††…………………………††…†††…†††‡†…………ƒ„„„‡“““’’ŒŠˆ…………‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…ƒŠ‘ƒ„‹…‚~}‡†ƒ€~~ƒ„ƒƒ„„„„„„„„„„„„………„…„†……†…†††…†……†……†…††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„„„‚‚‰~}~…~€„…„…†††…………††‡††…†……†‡‡‡ˆ‡‡‡†††‡‡‡†††††††…„ƒ„………„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘”“‘‘‹‰ˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒ„„„ƒ€€€„„~~€€€€……†‡ˆˆ‡‡‡‡ˆ‡ˆ‡ˆˆˆ††‡ˆˆ‰‰‰ˆ‡†‡‡‡‰ˆ†‡†‡‡††…„ƒ„…†…………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†…†„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡†…ƒƒ…„„ƒƒ€€Œ‰€‚‚€€~{z€†ˆˆŠŠ‰‰ˆˆ‰‰‰‰Š‹Šˆˆˆ‰‰‹‹ŠŠˆˆ‡ˆˆˆ‡‡ˆˆ‡ˆ†‡†„ƒƒ…‡‡‡†……„„ƒ……„……†„„„………†…†…ƒ‰”“ŽŠ†…†…ƒ‚‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡†„„…„ƒƒ‚€€€„„‚‚‚‚‚‚‚€~}}}}~~|{|ƒ‡‰‹‹ŠŠŠˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰‡†††‡…†ˆˆ‰ˆ‡†‡„ƒ‚„ˆˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚‚ƒ‚„ƒ„ƒŽ“’‹ˆ…„†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„……‚€ƒ„‚ƒ‚‚‚ƒ~}~~~~~~~}~}}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡‡‰†ˆ†ˆ‡†‰‰ƒƒ„ƒ…„„……†ˆ‡†…ƒ‚‚ƒ…‡†‡††ƒ‚‚ƒ„‚ƒƒ„‚‚ƒƒ„ƒƒ‘’ŽŽ‹‡„††„‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…‡ˆ‹Š†„†„‚††‚‚„„ƒƒƒƒ‚‚~}}€~~~~}|}}|y|ƒ††‡„ƒƒƒ„………ƒƒ…„„„„„„…„‚‚‚„„‚ƒƒ…†…„‚‚‚ƒƒ…ƒ„„…„„†ƒ„„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰†„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€‚€ƒƒƒƒƒ‚‚}~€€}~~}}}}{zz~„„„‚€‚‚~‚ƒ‚‚‚‚ƒƒ€€€‚ƒ‚€€€€€‚‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†‹“‘‹ˆ……ƒƒ„‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€€ƒ‚~~~~}€‚ƒƒ‚ƒ‚ƒ‚}}~€€€~}}}}~}|zzz€‚‚~€~}€~€€€€€~}}€~€€€€€€€€‚€€‚‚€‚„ƒ†’ŽŠ‡‡†ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒ‚ƒ„…€€|}}~}}~€€}~}~ƒƒƒ‚‚}}~€€€~}}}|{{{zzzz€€€~~~~}~~€~€€~}~~}|~€~~€€€~€€~€~€…’’Ž‹‹‡‰…„„‚‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~}~€€~€„ƒ‚€~}~~€€€~}}}}{{|zzyyy{€€~~~€€~€€‚€|~~~~}|€~€~~€€~€~~~~~~}||}…“’ŽŒ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒ‚‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚‚‚€ƒƒƒ€€}}}~~~~}}}}}|||{zyyyy}€€€€€€‚‚€~€~~~~~€€€€~€~~€}~~}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚ƒƒ…ƒƒƒƒ…„„„„„ƒƒƒ„‚‚‚‚‚~~}}}~~€}}}}}}}}}{zyyyyy€‚‚‚„ƒ‚ƒ€ƒ‚ƒƒ‚€€€ƒƒ‚€€€€€€‚‚€€€€€€~~||‰“Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…ƒ„…„…†…†††…†…ƒƒƒ‚‚€}}}}}}~~}}}}}}}}}|{yyyyx|‚ƒ„…‚„ƒ‚‚ƒ…†‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…‚ˆ…‚‚ƒ„ƒ‚ƒ‚‚‚‚€€€~Ž“Œ‡ˆ†ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€€~}}}~~~€ƒ„‡ˆ„†††…††‡‡†‡‡ˆ‡‡‡†}€‚~}}}}}}}}}}}}||~~~|{yxwxyy€ƒƒƒŒ„ƒ„„„——ƒƒ„}~‚‚‚‚ƒ†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ…„„…ƒ‚ƒƒ‚ƒƒ‚‚‚‚ƒ‚‚‚’‹ˆ‰‡‰‡††„†……„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€~}~~€‚………‡†‡‡†‡‡ˆ††‡‡‡†‡…~}}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yxy|~‰–„ƒƒ„„”“€~~…‹€€€„†‰…„‚‚……‹ƒ‚……††„ƒ……ƒ„„ƒƒ„ƒ…„„ˆ’Œ‰ˆˆ‰‡‡‡…†…„…„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„ƒ…„~}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|xyz{|€‚ƒ‚ƒ‚€~|~~{ˆ‘||Ž–}‚†Š…ƒƒ„ƒƒ‰~ƒ„……ƒ…†…„……ƒ„……†„„Ž‘ŒŠŠŒ‰ˆ‰‡………ƒƒƒ‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚€‚€~}}||}}|||}||}|}}}|||{‹‘—Œz{|zzz{|yy}}~€€|{{~~}‚•‘„ˆ~|~‚„||‚„‚€‡ƒ}‚‚‚€ƒƒ„„„„„‚„ƒ„…„‘’Ž‹ŒŒŽŠ‰‰………ƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚ƒ…ƒƒ…………ƒƒƒ„‚‚ƒ‚ƒ‚‚€€~~}~}||||||||||||||}|||~~Š‚{z{zxz{{|}{~}~}}}}||€}†~}‚~~~€‚||‚€‚€~|{Š‚}€~€€€‚‚€€€‹”Œ‹ŽŽŒˆ‡‡……„„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ…„†‡„„€†”ˆ€‚€~~~€|||||||||||||}|||||||y{{{xxy{zz|‚€~|~~}€‚€€€‚‘€€~€~~~€}}}{}}}|}||}€€€~€~~‚”’ŒŒŽŠ…††…„„…ƒ‚ƒ‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚„†‡††~ˆ•Š~€€~€~~~|{{|||||||||~}|{}|||{|||zzy{|z}…ƒƒ~~€~…‚~€~~€…†‚€~~ƒ†~|~€€€~}}}}~{|}€}~Œ‘ŽŒŽ‡„††…„„„ƒ‚ƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}€‚ƒ††……~€€€~~}€€€}}||}~}||}}}}}|~|}|{}||z{z|}}†„ƒ€€}~}~~‹„†~}||~‚}}}}€|{}|~„ƒ€~~~~}}~}~€~~„’ŒŒ‹Š†„†„„ƒƒƒƒ‚ƒ‚ƒ‚ƒ‚€€}|||}~{{}w~vx~}|}|}~~‚ƒ€z}}|~€~~~€€€€~~~~~~}~~}|~}~}~|{|||{{z}~€€ƒƒ‚~|}|}||ƒ~Œ~|{{}~}~~}{{{}|z{{{€†„‚„ƒ€~‚‚‚‚‚€‹Œ‹‹‰‡„„„ƒƒƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€~€€}€~~~~|‚~~}}}{{}}|z||~€‚€€||}{||||}|~{~{{{|||}|{{{{||zz}z~‚~‚„„‚‚…†……††‡…„‘Š‰‹‡‡…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~€€‚€~~€€~}ƒ||}}|}}}}{|~~~}~|||||}|~~{|{||||}|}|~|}|{{{|y{|{{}z}~~€€ƒ‡‰‰‰Š‰Š‰…ˆ’ŽŒˆ‰‡……ƒ‚‚ƒ„„ƒ‚‚‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€€~~~}€€€€ƒ‚€€€€€€€€~|z|}}~}}~~Œ†}}~{{ƒƒ}}}}}|}}}|}~|}|}|}}~|~}}}}|{{z|{||{z{{zzz{~~ƒ…ˆ‡ˆŠ‹‹Š‰Œ‘Šˆ†…„‚‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„ƒ€€€€‚~}~€~{~’Œ|}Š€Œ~~}}}~}}~}|||}}|}|}}}~}}~~|{{{||}|{z{{yzyyy{~„ƒ„‡‰Š‡‰Ž‹‰‰…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{}||~~}}‚€€€‚…ƒ„‚‚‚‚€€ƒ‚€}~€~|‰‚~ƒ„„ƒ~}|‡}}~}||~|}}|}}~~}~}}}{|}~||{|}zzyyyy{{~~€ƒ‡„ˆŽŠŠ†…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{}}}}}zx‚€‚‚€€€€€‚‚‚‚†…„‚ƒ€‚„~€}~~}~€€}~„€~~}~}}Š…}~}~~€}}}|~~~}€}}}|}||{|}{{{zzz{{|}~}€ƒ€‰Š‹‡………„ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv}€ƒ‚‚‚‚‚ƒƒƒ‚…†„ƒ€€€ƒ€„~~€~~€~}~~€€~€€}€~€~|}}|~~~~€}‚€|}€€}{}}}|||||{{{|{|||}|ŠŠˆˆ…………„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€‚€€€€ƒ~~€}€}}~~€€‚€€€€}€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{|~|}|||z|{|}‰‡‡……‡………„‚‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz~}yxtt€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚€~~~€}~€}}}~€€‚€€€‚~~€€€€€~}}}~|~~}}„€~}}}~}~~}~|{|z|{z€‡ƒ„„…„„ƒ„ƒ‚‚€€‚‚ƒ‚‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xyuu}‚ƒ‚ƒƒƒƒ…„…ƒƒƒ„„ƒƒ„‚€€€~}}~€~~~~€}}|}}~€€€€‚€€€‚€€~€~€€€~~~~}}~~……€€ƒ~€~€~}{z{z|{z‚…€ƒ‚‚‚ƒ‚ƒ€€‚€€‚‚ƒ‚ƒ„ƒ„‚„‚‚‚‚~€~}~~~~}~}}z{|…„{{syz|pwuvwyutz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€€}}}~€}~~}~|}}~€€€€€ƒ‚€~€€€€€€€€‚‚‚€ƒ‚ƒ‚€€|{{z|{|‚€‚€‚‚€~‚‚ƒƒƒ‚„‚„‚‚€~€€}~~}}}~}}{{z€x|vyy{qtxwvxury……‚„„‚„……†„„‚„ƒƒ€€~€€|}}~€}~~}|~~~~€€ƒƒƒ€€‚€€€€€€€€€‚ƒ€„€}ƒ„€€‚}z{{|||~€|}}€€~}}~‚‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxyzruyyvwwsu†…ƒ……„„…„„„ƒ‚ƒ€~€~€}}}~~€~~}|€|~€~€‚ƒ€€ƒ„‚€€‚€€€‚ƒ‚€ƒ€~‚‚„€€‚‚‚„‚~{{||||}}~}z~}}x~|||~~~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„‚„„…ƒƒƒƒƒ€}~}}}€~~~}}€€~~|~~~‚‚ƒ‡…~~€€€€€€‚€€~€‚~‚‚ƒ‚ƒƒ…‚}}}|{||yz{z~y{yx~{{{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst†„„†ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€}€€~€}~}~€€€~|€€~}~~€}€€ƒƒƒ~}~~~€€€€‚€~~€‚‚€ƒ‚„„†„€~}||||zyvyyzyvyv~|{{{~}{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…„ƒƒƒƒƒ‚‚ƒ‚ƒ‚~~€}}}}€€€|€€€€|€~~~}~~‚‚~~}~~~~€}€€€~~~~~€‚‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{{{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvpxyrx…………ƒ„„ƒ‚„‚‚€‚€~~~~€~}~|~€€€€€€{€~€€€}€~~~}}}~€‚~~~~}}~~~|€~~~‚~~€€ƒƒƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}|{|z{}zzx{|zz{xtxuqrtpxxqy„………ƒ„ƒ‚ƒƒ‚‚‚€€€€}~~€}|~}€€€€€|€€~€~~~}}|€€€€€~~~~}|~~|}€~}~€‚~€€~‚„‚‚ƒ……‚‚~}|{{||yw|ywxwwx{{{{|…Š}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzz{zxswuqqsoxwq{…†„…ƒ…‚ƒƒ‚€€€€~~}|~}€€‚€€}~€~€€}~|}€€€€~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{||{zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚‚€€}}~€‚‚}~~~€€‚€€~|~|€€€€€~}~~€€‚€€€€€€€„‚‚€~|}~~z}…~t|}zzzz|yyzz†…wy|||||}{||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚€€€€€€~}€€‚‚‚€~€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€€‚€€~}~{“z|}|{}y{zzxyxy{||}||{||||}}}||}|~}~~~}|z||{|}{yzzzyytuuooqpwst}…†ƒƒ‚ƒ‚€€‚ƒ‚€‚‚€€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€€‚‚€€€}~~|†‰||~{{~yz{z{Ž~wwy{|{}||||{}|}}}}|}|~~~~|z|}{|}{yz{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€€‚‚‚€€€€€€}~€}€ƒ‚{~~{|}{z|||‡yxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ‚„„€~‚€€€€‚~€€‚€€€€€€€€€~}€€€€€€€€€€€€€€€€~}~}~~{}|}{||wxuxxy{||}|||||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒƒƒƒ‚‚ƒ€‚„ƒƒ„ƒ‚ƒ€€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€€‚€€€€€€€€€€€€€€€€€€€€€€‚€‚ƒ‚‚€‚‚€€€‡~~|z}|{}xwvyyz|}||}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚ƒ„„€€ƒ†ƒ„ƒ‚„€„ƒ‚‚€€‚‚„‚‚„‚€€ƒ‚€€€€ƒ~€ƒ‚~‚€€€~€€€€€€‚‚€‚ƒ‚‚ƒƒƒ‚€€€„}}}|}z}{yvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysruowqwysw{…‚‚ƒ‚ƒ„‚ƒ„ƒ€€‚ƒ†ƒƒƒ‚‚„„ƒ‚€€‚„‚‚‚~€€‚‚‚‚€€€€‚„€~ƒ€ƒ‚€~€‚ƒ‚€ƒ‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ€‚€}€|z|{{w|yyy{z}~}||||}~~€€€€„„€}€~{{{z{ztpxrytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚ƒ„†„‚ƒƒƒ„‚„ƒƒ€ƒ‚‚‚‚‚€‚€€€‚‚‚‚‚€ƒ‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚‚„ƒƒ„‚„‚ƒ‚‚‚‚ƒƒ„ƒ„„„„„…ƒ„‚ƒ‚‚ƒ€€~||€}|x|yzyz|}|{||}}}||€€€€€‚~€€€€{{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚ƒ†……ƒƒ‚ƒ„‚„…‚‚‚ƒƒ‚‚‚€€~€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€ƒ€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒƒƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{~~}y|zzz}||}z||}}|z{~~~€€€€€€€€€}}|}}|vrvxxvtvu}‡‡ƒ‚„…ƒƒ„…„€‚……„„ƒ‚ƒ„„„…ƒ‚‚‚ƒƒƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚‚‚ƒ„‚‚€€‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚~ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz{}€}||z|~}|}}~~€€€€~~€€€€~|}}~~}|{xvvw„‡ƒ‚ƒ…ƒƒ„†„‚…†…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„ƒ‚‚ƒƒ‚ƒƒ‚‚„„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒƒ„„„„„…„ƒƒ„…„…„ƒ‚€}‚€}||{||€}}~€~~}~|||}}~~~€}}~€~~}}}~}}~~€|}€‚‚ƒƒ†ƒ„ƒ†„‚ˆ‡…„ƒƒ„„…„……ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒƒ‚‚ƒƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒ‚‚ƒƒƒ„ƒƒƒ„ƒƒ„„…„„„…………„ƒƒƒ}„€}}||||~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒ„…ƒ„ƒ…~‚Š‹…„„ƒ‚ƒ…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ…ƒƒ„…„……‡‡†‡…„„…„ƒ~~|~~}€~||~|z|}}}}}~~~€}}|€€~~~~~€‚€……„ƒ„„‚„ƒ†€‚……Š‰„„„„……‚‡††„„„„…„„„„ƒ„ƒ‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ„€}uyƒ~„„‚ƒƒ‚ƒ„ƒƒ„…ƒ„…†„…†}„y|~ƒ{…ƒ„ƒ€}~}~ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚‚ƒƒ‚‚†„„„…„ƒ„…ƒ„…ƒŠˆ………ƒ……„†††ƒ„„………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†spurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚……‚hzrss|€rƒƒƒ}}~~}~‚ƒ‚|}€}}||||}|||~}~€}}}€‚€‚‚‚‚‚‚„‡„…„…„‚„††ƒ…ƒ†ˆ††…ƒ†††‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vyy†r„ƒpvxqvtturstvi€nrotvnulwm{sn€‡ym}rsvsvmnwlpylu}|~€}€}€€}}|||}|}~}€€€~|~€‚€€€€€€€‚ƒ‚‚„…‡††€‚…ƒƒ…‡†ƒ………†‡‡„ƒ††ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoomw}x†pqzprtfu~n{ysoy€}~€{~|€~€€~~€€€~~~€~}€}€€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„†……††ˆ„„†‡ˆˆ†‡„††‹Š…„†‡‡…ƒ………„‚…………†……†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„rioyxpkyszozwvvp€~~~z~}|}~}€ƒƒ€‚ƒ„‚€}~~~€~~‚€€„‡†ƒƒ†„„„†‡†…………††ˆ……†…‡‡…†„††‰ˆ…„‰‹ˆ†„†………ƒ……„†††††…ƒx‹yrˆz{pp…„x…xyks~y{krƒ‡ƒz|mzyyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozls|nv‚~~}}z}{|}}~}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡……………‡‡ˆ†„†…‡††…„……„……†‰Š‡…„†…††…††„†††††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„…†…†„†„ƒ„„†„„ƒƒ„„…„…„…„†ƒ†‡……„„…‡†„„…†……}w…ƒ„„‚}~{|{~{||}~}|~~€}€~~~€~~~~}}}~|{|~||‰†…„†††…††…………††‡ˆ†„†…††……ƒ„…†…„††††…„†„…††††„‡†‡‡†…‡ˆˆˆˆ†„‡…††ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…ƒ‚……†……ƒ…„„„…„†…„……ƒ††…†…„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ‚}€{{|~{||}~||~}€}€~~€}}|€}~~~~~||}~{|||{{~ˆ‡„„ˆ†††‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡…††……†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ……ˆ…†‡†‡†‡†ˆ…‡‡†‡……†‡…‡†…‚ƒ…††„„ƒ„„ƒ„†„†…………ƒ††…†……††…„„……ƒ„‡…ƒ‚‚…ƒ„~€€|{}~{|{~~}||~}~~}~}}~~|}||~~|}€|||}|||~z{{|~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†„…„††„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…‡‡…‡†‡†‡…ˆˆ‡‡…††‡…††„„„…†……„„„ƒ„…„†††…†„†…††……††…„ƒ„„ƒƒ‡ƒ„‚„„ƒ‚€€€{{~}|||~}|||}}|}|~}|}}||||}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††ƒ…†…†††…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡…†††‡‡‡…‡†ˆˆ‡‡…‡‡‡…†‡„‚„ƒ„†…‡…„„„„„…††††……‡……‡…†…†…„ƒ„ƒƒ„‡ƒ€‚ƒƒ‚‚‚€{}~}|||~}|}}|~{||{||}}{{{}|{~}{|}}|}}~}|zz{{||ˆ‡‚††††‡††…ƒ…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡ˆˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡…‡‡††‡‡…‡†ˆˆ‡†…‡†ˆ††‡ƒƒ„„ƒ††‡……„„„…†††††…†‡††ˆ††„†…ƒƒƒƒ‚ƒ†ƒ~‚‚ƒ€ƒ‚|~~||}}|}}|}{{{z{|||{{{~{{}{z{~||||}~}{z|z||‰‡ƒ†…†…††…„„……………„ƒ„†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…‰Š‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……ˆƒ„†…„††‡†…„ƒ……†††††…††‡†‡‡…ƒ……ƒƒ‚€ƒ…‚ƒ~ƒ~~}||}}{}}|~zyzy{|}{{{{~||||z{}||||~}|{{{{|{‰‡„†„†„††…„…†…„„ƒ„‚€ƒ†ƒ‚z„Œ{€„…‡†††…„‡ˆ‡†‡……‡‰‡„‡…††ˆ†…‡„†‡ˆ††ˆ‡‡‡†‡ˆ†„†††‡……‡ƒ„…„†††‡…„„ƒ……††‡††…†††…††„ƒ„…‚‚€ƒƒƒ‚}€~ƒ~€||}}~}{~}|}yyzy{}}zz{{}|}||z{}||}|~~€{{{|~}|ˆ‡…†…‡„†„……………ƒƒƒ€‚…‚€}|{„…††„…„ƒ‡‡†††…„†‰†‚†„†††……‡…‡ˆ‰†…ˆ‡‰‡††‡…„†……‡…„‡ƒ„…„ˆ††‡……„‚……†…††‡„††††…†ƒƒƒ…€€€€ƒƒ€|€~~‚€}€||}~}~{~}||yzzyz}}yzz{|{|{{z{}}|}|~~|{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€€ƒ~~~€yz}€ƒƒ…‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ†…ˆ‡‰‡†………ƒ†„…‡ƒ„†„„…„‡†…†…†„‚……†††††„…††………‚‚ƒ„~€€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|z{{{|}}}|€~}||}~|{‡……††††„…„…ƒ…‚€€€€~‚‚}}{‚ƒƒ…†…„ƒƒ†ƒƒ„‚€…‡…‚ƒƒ„„„††‡ˆ‡……ˆ†‰‡…„„„‚…ƒ„†‚ƒ…„„†„‡†………†ƒ„…„…†…†„ƒ„……ƒ…„€€ƒƒ~€€ƒ|€}}‚}€~~~~~}}{|{zyzzyz{|yzz{{{|z{{{|}}}}€}}||}€}|†ƒ††††…ƒ„ƒ†‚…€€€~‚|~~€€‚‚‚„…ƒ‚‚„€ƒ‚€„……‚€‚ƒƒ„……‡††„…‡…‡…†‚ƒ‚‚ƒ‚‚…ƒ…„…†„††‡††…‚„„ƒ„………ƒ„ƒƒ„‚„„€‚‚}~~~„~{||€}€}~ƒ}~~}}~{~{{zy{zyzz{yzzz{{|z{|||~~}|}||}€~€†„……„‡„„ƒ‚†‚ƒ€€~~€}‚|}~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡†…„ƒƒƒƒ„……„ƒ‚ƒ‚„ƒƒ€€~}}~~|~ƒ~|~||€~‚~‚|~}}|||{{zzzzy{zzzyzzz{|y{}{{~€}~}}}€€€†„„…„…‚„‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„…ƒ‚ƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚€…ƒ~€~|}~}|~ƒ}{~|}€ƒ}}€~}|||}{{zyzyy{yzzyzz{{{z{}||‚€~€€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌËËËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFK=8765999<>9?<D:;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937677=;>:=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<:<<98:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA><A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËÊÊÊËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÔÔÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÒÓÔÔÔÔÔÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9>CE?<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÐÑÐÐÐÐÐÑÑÑÑÑÑÑÍÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø×××××ÕÕÕÔÔÔÔÕÕÕÕÕÕÕÖ××××××××ÖÖÖÖÖÖÓÒÓÓÓÓÓÔÔÔÔÔÔÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILO@99:4;A<7=9AC>@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌ͖„†††††‡‡‡‡‡‡‚²âÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¸ºÑÓÓÓÓÓÓÓÓÓÔÔÔÕÉ»½½½½½½½½½½½¼¿ÒÒÒÒÒÒÒÓÓÓÒÓÓÓÜãâââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVN<::77>C>8>:??A=>@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÎnPSSSSSTTTTTSL óëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§£££££££££££¢§ÏÓÒÒÒÒÒÒÒÒÒÒÒÔ¿¨ªªªªªªªªªªª¨°ÒÒÒÒÒÒÒÒÒÒÒÒÒÑàìëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;?C>6:7>?;=B?9<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÌÎqTXWWWXXXXXXWP¡ñééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤£¨ÏÓÒÒÒÒÒÒÒÒÒÒÒÔÁ©«««««««««««ª±ÑÒÒÒÒÒÒÒÒÒÒÒÒÑßëêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;?@@8:;8<;<<?:;;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÎx^a````aaaa``Z¤îççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©©¬ÏÓÒÒÒÒÒÒÒÓÓÓÓÕ­¯¯¯¯¯¯¯¯¯¯¯®¶ÒÒÒÒÒÒÒÒÒÒÒÒÒÒßéééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB>;=:9;:==;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÇÅÅÅÅÅÅÅÅÅÅÅÅÄËÐÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÎÎÎÏÎÏÏÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÒÔÕÕÕÕÕÕÕÕÔÓÓÓÔÓÒÒÒÒÒÒÒÒÒÒÒÓÓÒÕÔÔÕÕÕÕÕÕÖÕÖÖÖØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<8@B<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÏÏÏÏÏÏÏÏÏÏÏÓÏÏÎÌÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÎÓÔÐÎÑÔÔÓÎÎÓÓÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÖÕÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖ×××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?79:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÎЦ’ÅÔ­ƒƒ•ÏÒ¤¡ÐÎÎÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<>B>BC@=:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÎÒª¬•Ã›¼¸™´³Ÿ¡©ÒÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?>;7:>9?D>A98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÐɗ™…¦Ÿ¨Ž€Å˜•œÈÐÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<=:6?B@C:647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÏѤ°½šŒ£‰¬Öº˜¢°²ÓÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8FA?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÏÏÐÕ¹›‹«­›¥²™–¯³ªÕÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<>=964:99::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÏÏÐњ ¥¤œ–§š„“¤ÕÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ×××××××××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:<?>=<9@<<::9?@>=<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÐÐÕ§¤ Õ¤´«Ÿ ©…™¤ÕÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CFCAB8;?<=;<<8558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÐÒÀ¢È×ÊÙÁœ€¼­¦˜¯ÖÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF@HIGE@<<>><=><756:969;::;8@?:<<9<>=;;:?9?:;9=>=><;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦ÓÔ¤ ¹Ã¡ŸŸ™¨–˜›»ÕÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;557<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡ÈƦ½•““¨«¢ŸÃ «¤œÑÓÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKLA>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ Ôʎ“—ª«¬Ø¼ÕÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<=?GFGKH=657:979:;:<=9>99:8;=>>A>=9<<:=>>:=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÔ¯°³ÐÖÀ¿ÖÒÕÅÄÕÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?AELLA>775;8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÔÖÖÖÒÒÕÕÓÓÓÔÔÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEK>>786967899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9699:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EILAALD??;9889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEHIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDJ;AA;<886486987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGJB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<BA<;877797799=?A?<:9@?<>B?:8776=??@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98868975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE>;HF89757875898;>>=;89A>=@?A>7596;>AB??@@AB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCEEC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELCA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<<DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGHNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAC?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€iixsg~‰‰xp‚†{w}~…Š½ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€‚wt|„‚}sp€Šx‚yƒÈÞÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsoupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿¼½¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»º¹¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjcmgb\XQPQKTJB:IQ?A7<94:565455688686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸········¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µ¶¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸¸·¸¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶·····¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨¨¨¨§¨©©©§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸········¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¥¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥£¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§§¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœsknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©ª««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤££¢¢¢¢¡ ŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž£¤¡žžŸ  žœžœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=7789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥¤£¢¡¡¡¢£¥§¦¦§¬¬§¦ œ›¡¡ž›ššœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¥¦¦§§¦Ÿ›š›¢ ™––•š›š——˜™šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜—™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥¢¢¥¦¦¥¦§¦¦ ›™›¡ —““’—šœš———˜›š™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB@DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¦¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥¦§¦¦¢œž¡Ÿ—‘‘”—š˜–—–˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–Ž{jfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;<;=<:;<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¥¦¥¥¦§¦¤¥¦¦¥¥£  ¡¡Ÿ™’–š™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šžŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡ ¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢¢¢£¤¤¥¦¥¤££¡¡¡žœš•“”˜›š›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œ ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸŸŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::88:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸ   ¡¢£££££¤¢¡ ž›™™˜™™™™™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢ ›ž ¡£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?;:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œž››œŸžœœœœŸ   ¡¡¡  ¡  ¡¢¡¡¡¡Ÿžœ›ššš›œš™š›™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥¤¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¡¢¢¡   ¡¡ ŸŸžœš™š›››œ›š›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›šœšš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>98;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤¤¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ žžŸ     Ÿ ¡  Ÿž›š™šš›š›››Ÿžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›ššš›™˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9<<>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœ›œžžŸž›šš›œœ››œœžžœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:=>:?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››š›œššš›œœ›š™œœœžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™˜˜ššš™™™™š›œœœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›š™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š››››œ›˜˜˜™™˜˜™™˜›œœžžžžžžžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ›››››››™˜˜˜˜˜˜˜™™œœœžžžžžŸŸžžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ››››››š˜˜˜˜™™˜š›œœžžž  Ÿžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_^]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜™——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜˜˜——˜˜››œœ¡žžžžœ››œœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±³­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=:F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œšœ›œ›˜™š˜˜™ššš–‹”™™˜•›¦–›œ—•’‘’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨©¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‹‘‹ŒŽŽ‹„Œ–‹ŒŠ‘œ‹Ž‹‡Œ…†‹†ŠŠ‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VQQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹‹†Š‹‹‰†„†‚€‚‰Ž–‚Œ~Ž’Œˆ…€‡}€’†„„†ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹‹‰‰…‚}s}†™›„Œ{ŠŠz}}†ŽŠ†”’‹—”—’˜¡–ž—•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¥›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ‚†‹†ˆ…„ˆˆ‰„‚z|z‰•‘‚…i†…‹Šƒ„…ŠŒ‘™””” ššŸ¢­±­©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPEMISWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~‰‹‡Œ‹Š‡’Š‡†›–‹‘ˆ_†…ˆŒŽ‹ŽŠ‰Ž””˜•œšž¨®²¯¯µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWLO_^\NUUbQDTM;?9<895775795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš™ “—š ™›¢¡•›¬‘“›˜{Y†‰‘‘Ž’Ž‹˜šŒ”š—œ› ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUKTOOJCPK_bXZQ\T`MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ª©¨§¡¥¨¨«ª©¯¡š ¬ŠŽ¡ŸvYƒ™˜”˜  ¡¤ž›š¥§¤©«¯¬¥£¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdWOXKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®¯ªª«¤¡¢¤©§¦©¨¢¦¤…†§£t[s ™˜Ÿ¡¢©§ ¢¢®¬«ª§­¯¨¥¤©©ª©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_UZNRNPORd\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢šœ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨§¥§©§©¨£§¦™œ¤¦¢¡¡¡¡¥œ‚‚¡¢rcf™Ÿž–Ÿ›š¢¢ ¡Ÿ¡¢¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]\PUOWO^ddlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§¬©¤Ÿ¢ ¢¦¡¦®¦¦ŸŸŸ¥’€~qh_¢¡›œšœ ž¡Ÿžž £™–›˜¤¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvxb_\UYQUW[c^s_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?C?:8:>?C@DA:;>=@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯««¬¨¨«°©¨ª¨¡Ÿ §©­°²¯¬£¢¦¡®Š|~¥žoj\„¤¥¢ž žŸ¥¢¢žŸ¢˜•ž›ŸŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸ ¡¦¢›—’šš •|wo}yf[Z`_Z\V\hdncnjib^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¢ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£Ÿ¢ª©§®·¶´´¶³¯¬«®«¹ƒw}²¦liX~¥¢£šœœ—¢¨¥¡Ÿž£›¡š–¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¡™˜¥ ¤§ª©¨ª­¬¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvyjb[_^\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>AE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢œŸª²¸¼¼½»º¿´¯±³µ´¸zrq°¯gfT¥žŸ–•š—¤ª¦¦¡¤£¤«¦¥™¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨¨«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥¡¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxxxc[RYT__amhukqhiiaYSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶´º±ª®´±°±´µµ¼¼¾¼¼¾Æº¸·º½´®wne¬·k`R­¥¥—¤¤§¨¤®¤««µµ¯³ §ª¬§ª©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš’–””˜“š˜Š‹‡€€|‚xa^YTai`fsositdidb[LK>:8898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÃÆÂù½¿ÀÀ½¿Ä½¼º½¾¶©~ui¢¶u`Vœµ®®ªª§¬§§¤¯§ª´¼±´µ¨¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`a^^kcbnwuvnl[bQV\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAA;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–••‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±°§¼¼¾ÅÄÆÉÇÅÆ»ÄÀÅÆÀ¹¯½¼À¾¾·¦‰~}•£„mjª¼¬¯¯´©ª¦ª£­¤§±¶«µ²­³­¨®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|ƒjfhakmfnuqruqg^_\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÅ¿ÃÂÆÅÀ±“¾º¿ÃÉ°–ˆ{†Œ‘‰y€¡¸°Ÿš°®¬¤­°´§ª©¨ª­¬©¦¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|tklndomiqxnyiia\gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿¼»¾Ä¾ÅÈÆÆÄÄĹ´À·´»Å˝‚xfv„†|l|†¦¶ª™¢·°¦°»µ¬®¥¤£¨¤  ¥™ª´±¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyz{vnkiguZfrxsyff]d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÉÅ¿ÃÀËÍÏÊÇÄÃÄÂľ¸½Ê½‰naSb}~iUgp³ª¦´³¬²Àµ³¬©£¡­©¬¦­Ÿ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuuefijh]konxwcb``^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÎÏÏÌÃÇÆÈÉÈÇÊÎÊÉÇÈÇ¿Æˤy^NHTwu^DYby§·À¾¾¹¬¹Áº¼¬­¦ª»º¹·À²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqocagvhjitmxl]d[V`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÌÐÎÇÌÉÂÂÇÁÌÕ×ÍËÊÎÅɼŠkPE?NphX=N\l•ÄÌÆÆ°™ºÄ»¾´°°°Á¾¾ÁÆ¿¾¸¶Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`jjvlieuntb]bTWUSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<9>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÄÇÈÆÒÉÁÃÄ¿¿¾ÄËÈÊËɼ¼ÈÆÉÕÛÕÍÉÉÅɧvZLWEJh]V=IVc{¼ÐÆ°‰¹Â»º½µ³³¿¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrpfefcjdbjmno^Y\VVNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾƹ»Ãº¸¹¼¾ÁÇÁÆ»¹ÈÉÃËÙÓÈÃÂÁÆ¢iLb•jHaVXAMU^i¯Ö½“v…¼º»»¾·´°¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfadbacddjcgc[ZZ\YQOE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶¸´´µ¿»½¿¹¾ºº´À¸µ·²®º»·À·¼ÊÑÁ½ÏÓ¼´¼½½®lF€¾J`WZDT_[_¢Æ£{h“÷»¾¹µ·´¸¼´½¸µ´°³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|yˆ}qc`bchjggifi]VVTYOSLF8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“““˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´µ±°µ·µ»Á¸¾¹¿¼¼·´·¯®·µ¹¿»Â֋º¿ÂÙ¹¡¥¯´¸wIƒ«ŽLhecBUs`W‘Ÿ‚le¨Æ¿¼Å¸¶·´¸¶¶»»¸¶´·ºµ´¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒxqmeefoielhXXNKKKRILHC9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’™”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿¾¼²­¯¬±°·¼·»½ÁĹ··¶µ¹¹º»¿¼ÐÄs©Ë¾Ü͚–¢°Mq~pWxqNVeUxvkcnÁÆžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~‡|knpgpksfbm`\TIKJDJBCG?:;8><7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘Ž˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼¼À·ª­¤®°¸»²½¾»Ä¶µ¸µ·À¾Ä¼ÂÄØ«p¼ÈÔÞ²„…™}UcfVr™‚~nUtcZcba\…ÒÇÇÄǽµµ¶Á½»»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†€rflintnxcgb\cQKTHEECHC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?>??FD@A?>:7?@CC?@=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼ªª£°¹½¼²¼¾¼Å¸±¸¹½ÇÊÊÃÇÉҔlq­ÑÐÛԒv|t^b]N•¥ƒ„‰T]]\YYXaªÒÉÇÅÆÀ¹½¼Ä¿¿¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtolltkln_c^`aNIM?E@?DC;;::;:8;<:9<>::>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´»ÆÓú¾¼Ä¾·¼À¿ÉÐÇÈÊÊÀ‚no£ËËÏà¸sjkg``WU¨¡€ƒ’^XYVQURyÆËÉÃÃÃùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{zˆzmmw{_pc[^__TI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA??ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸´¼¶»¹ªÛþ¶¾À¾¾·¢˜¦¯³ÂÀ£trt™ÄÇÊÖ׆WUQOPE[Ÿ‘yƒ‰gZTONOVœÉËÆÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}‚znsxsgp][^]YREDCMIAE=H;;59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘—žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯··²µ³·¹¼»¶»»Æµl«Í¼µ¹À¼§zlgnjr•–mtw•½¿ÆÁÕ¨UB@>B9Z‰}qi[SLLNv·ÀÁ¾¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸¸¸½¹»±¶²ÈÀ»¶´±°·¬³©°­­´·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y}vlu{pni[__ZSPAFHGK@DCH<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿš›œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹Àαv€²¼µ¶Á¡…iZ__LR[[mnr}¸·Â¸½»sD5594Rrjjspd_WLK\ Àº¹·¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ°µ´´½º¾¹º»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰|‚zsuvwnq`_f][TJ=??FF=FCC9:5;99><<::<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Âʦ„wŠ¡¯´˜hcfUY`JJMPTjs„£¯·¾¹³¶žh7053F]U^db`b]OLv´¿¸²®²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³»·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtwrl_cb[^OHB?=HCFMC@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·¿Æ§ˆ{v¡”^SBYTHblWPFIc‹Ÿª¯¶ºµ´²­”P311APFQWXX``P\˜¹º´­¥¬³°¦°­¨ž Ÿ¥­¶µÂ·¶´¥¨«¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´·¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wo{ourmc]gX\]RNNA>JBAJI@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³²­¶º¯­¼³¸¸¿³yˆŽkNJ@hXBOwƒ–lLBW~°´³µ²´¯®­wL00?E;EVWQX]Q|°²±¬¬ž¤§§£¦–™™šŸ©®¹¬««Ÿ¥¨¤«®®§¯¬¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmtil][jT]\PMHDFLBFNF8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹º¶¹»µµ³¸µ•‰„yVFARˆWJJVvŒ€a?U§¸³´²°±­°¹¤{@->Z{—§¢’sUZ•«¬«£§ ž—˜¡•’•—˜Ÿ¨®¤£¤ ¢§¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬ª¯£¤£¡© ›“Ž“’’™–š¤¥ Ÿž§˜•’”™ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wrxhtsndUacW\QNLH@HQDMC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯²»©˜™•hM@VznOIILfšWEU¯»±¬³¯®¬­µ· fg“©§Ÿš›ž wž§©Ÿ¡§–›——“–Ž—›¤¨  ¢¢¢¥¥££ ž¥ ¤¬¤¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›©¨««Ÿ¦£›£œ•Œ“—•–˜Ÿžžš™¦—“’–¢ ¥¢¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦ ˆxƒ|vzcwln\QhTPNGPMLBOQ@>;>49:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¤¬¨½Áª¦½dEU¢ƒPYIKaJX‰cff¬µª²´®ªª®°­«°§œ–‘–ž  Ÿš£¤Ÿž¨”›–—Œ—‘—“˜¢ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£ž™—š«¦ª±£¥¨ž œ•“‘˜–•˜—Ÿ˜›™›¤™—”–š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’}|€uv}mk{dhUQcMJHGORMJNG<E@<2@859;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜——–¡¨¬®¶·º¹º··»®¨ ¡© ¬ÆÀʚNBwnOoKNbfur`_ft°¯®³µª¦«ª¢œ˜’Œ”•–—šž¢¡›œ¤žš¤———–’‘‘“š—› ¤ªž¡¡ž¦§ª¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¡¤¡›˜ž¯¨®²«¥ªª š˜˜˜•“–š“••š–›——˜¡žœœ—›¡šžš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}wx|dyy`bRU`HIJKSTIRPL9?A67<65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—“’œž¤¨®­¬««¯ª¯©ž—ž¥œ¥ÆƈWRKf¢^i~rvYRkc]ifej‹´°°¸¬¦ ›™”—™˜Ž”Š“˜¢œ—£™š—˜™”™˜–›Ÿ¥¦© ¦£ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§  £±®²°´ª²®¢™œž¡™››š˜™›”–›–™œ¥¡ š£¡šœ™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ Ÿž ¥¡žž¥ ¦™{|vvsh‚le[SZZMQJOOULSLA7>C78=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’‘œ˜¡ª¢§ ž§¡¥Ÿœ’›¢šŸª£yUlruumburXY`_di]`Xb¬®¬¯§Ÿ¡Ÿ–“›Ÿš˜–‘’ž›¡£›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬¨¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½·¾°¬±®­©ª´±°¨«¨²µ·³¸­²´¤ ¥Ÿ¬¡¡¢  š˜–– ››˜¤¡ ž£¡ žšœ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚|xujwu]lZR`HRUHFUVJBLG=KH8F<77;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“Ÿ™¨®Ÿ§žœ¡žš™’˜ž›¡¡ £~on`dWM[RXKKQWQIROC—¬ª©¤Ÿž˜’’“˜—•””‹‡Š”œž—ž™¦Ÿ ¨¥±ª§®£«­¶°´²±®¶¸½Àº­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«¯±¹·¼¯³°µÁ¼·½³³µ¢¬¢©¨²©«¨§¨š™žšª§ ™§ ŸŸ§§¥¤Ÿª¢¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰…„~vrmivmhm\X\CWNJGMGCFM<>L>4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜™ª ±¢·¤°¦Ÿž—˜•™ž›œ£ŸœˆaW_f`VMOE<>?CC>=BQw¨­©ª¥Ÿ¢£Ÿ™››“’”“˜”…š š«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶º»ÀĹ½»¬¯§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¹Â¾¸³»ÆĽü·³©³­ª³µ¯³®ª¯£«§¶±­¢°¦¡£¯±­°¤¥¯£¡ š¡§¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¥ž¦™›¢¤žŸ›››œ‡†{trkktrqhV\QFTHDJPI?EA4FH95;>6;<>=<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž  œœ˜šŸ šŸŸ“{`^e_PEE:D@F<>96N~ª³§££¡ ž¥«¥ž—œ”‘™˜”ŒŠ†ˆ†xmˆ £¢«¬´¼¶Ã¾¾³»ÁÃÂÅÀ¿ÂÆÆÅÃÈÂÀÅÇÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌÌÌÒǾ¿À¾ÇÆ·ÄÊÉÃÁƾº´ººµ»·°µ²ªº²®»·¿»º«¸­«ª¸º´¼®®¹£¦£ž¦¥¢£©¦™›Ÿ˜š§ª§ ¡¡¤˜”£–”™‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ„}zqkchoxkeZ[FKLEDSMDBE7:?;549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ²²¸§¡¡«ª¡œž¡¡œ™{ri`UND>J\}pbA=\Ž®¬ ™››žž™———’ŒŽ–—“Ž‹‚ƒ‚wrqmp¦­®´¹Å»ÍÇË¿ÂÌÎÍÌÇÉÑÌÍÌÇÉÅÅÌÑÒÕÎÓɽÀ¿Ã»ÆÅÈÅÑÓÍÓÐÓÓÌÊÂÅÆÆÊÈοÈÑÌÇÆÇÅÁ¼ÃÁ¿¿¿¶¾³®¿ÀÃÃÇÄÇÄ®¿¸²¸¼Ãº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›Œ™‰•˜› Ÿ£—žš““‹•…€ytsebgrof^ZYCNLDEPIDC@5558:B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>8;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›¢¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¤¨¬­ª £žœž•hd[SHD@?LŠ¡©šƒ ²­£žœŸš—–”’”–‘Œ‡ƒƒˆ‡ƒ€€yqroly¤¶º¹¾ËÁÓÒÓÈÍÎÑÓÑÒÑÐÑÑÍÎÎÐÅÎÔÕØÒ×ÍÆÇÉÌÃÅÊÏÊÓ×Ò×ÒÕÖÓÔÈÌÆÌÍÉÒÍÎÓÍÅÈÊÊÁÆËÇÉÈƿó³ÈÄËËËÏÇÊ¿¾¿½ÁÇÄÌÌÈÉÀÿ­¯³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›•Œ†‘‹€zruvgcgvidVWQDMF@IQB=B<:22A<E<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<A?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­³·¬®£ž£¢¡›bSKIDB?DV³Ò½²°¦œœœ ¤¡š”“•”‰}wpkebhqoq{…Š€upnqtp…³Ã¾ÅÑÐ×ÖÖÒÖÍÔÖ×ÔÓÑÓÔÔÓÏÑÃÐÓÖØÕÖÒËÉÎÑËÆÍÒÊÒÕÖÙÖ×Ó×ØÎÒÊÏÑÌÏÐÍÓпÈÇÊÄÌÌÌÎÏÅÆǶ¿Ê¿ÒÍÌÐÆÉÈÀÄÃÈÎÍÐÑÏÍÊÈ͸·»¨Ÿ¥«§ž˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„|xsvpc`drb]R\IJGAEIJ>;A8=4586;86:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÁűµ¨¡¤¥ ¢ YI@AD@GQy²®§š”—Ÿœš  ž›œ™•‰wic`__`_^__]blutppolrqu’ÄÈÆÔÖ×××ÓÖÐÕÔÚÔÔÎÏÕÔÔÑÑÌÑÍÓ×ÖÓÕÐÏÒÓÑÉÓÑÈÐ××ØÑ×ÒØÙÔÖÌÏÏÊÍÒËÎÐÁÆÃÈÆÎÍÑÑÒÉÌÍÀÊÌÆÓÏÌÎÈÅÊÇÇÈÌÊÔÔÑÕÏÒÌÓ¹ű¥¨µ®§›¨¬¥²¨°³¬¬““ŽˆŠƒ‹„Ž™“™‚…Œ|zqstmacim_VP_JJCFCRM?<>54:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><??=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯­ªª«¦®·¨«·×ÔÕÙÙÑÎп¼Ìɶ¾®¦ª¨¡£«eC8=>EX‚ª¨Ÿ˜•—™šœŸ˜œœ’}pecb__a__a`_``_`fnppnkorwwœÌÁÒÕÓØØÖÙÑÒÒ×ÏÓÎËÒÍÕÔÒÊÏÌÓÖÒÑÖÍÏÕÕÑÅÑÔÊÐÔÕÖÎÒÐØØ××ËÈÎÄÉÏÍÊÌÀÊÀÈÊÍÎÐËÐÎÎÌÎÏÈËÐÐËÎÊÂÉÇÉÌËÌÒÓÍÓÑÑÐÐʽȹ°®»¸µª¶°­¨¸­³¾»±šŸ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…ˆzvopokadnpaW\ZIFFDMXE;@=33<=87855;>@=9<<8;>9<@;@:=8>98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ¤§Ÿ¸¶µµ¬¤¬®¾´°ÀØÒ×ÚÜÖÎÍÊÃÒÏÁÀ°©¬­©¤±zJHC=XŒ¡›•“—›žžžœ“–—”ˆk^^^adb``aa``a^__^\bmroostvvy¤¿ÌÕÑÖÔÓØÖÎÎÔËÎÎÅÎÊÒÒÏÇÎÍÍÔËÎÓÍË×ÖÐÌÑÔËÌÐÒÓÊÎÑÔÒÕÕÊÀÊÂÅÌÂÈÉÃÌÃÅÈÊÊÏÊÍÌÐÎÓÌÆÈÏÌÈÇËÅÆÁÆÊÌÍÐÑÆÐÎÍÍÌÏÅÇÁ¸¹½Ãýù²²¾±»Ãõª˜¥¡™–‘••’‹”š‘”””‚‰†yqrkmg``phYXhVLFLIPPB;C>;67:8::57==A<:<<9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÄÂÁ¿»µ²±Ç¸ËÕÕÙÚÛØÌÌÏÈÖÕĵ¯´¨Ÿ®•xosu‚’™Œ—•“‘‘•–•‹|eabb`]^acb`__`aa`_][]grrqrspmry¥ÇÓÏËÐÏÓÔÊÅÉÉÆÆ¿ÃÆÏÎÇÅÇÍÊÒÈËÎÎÆÑÒÐÍÌÔÊÇËÎÏÈÇÏÒËÑÏƺĿÆɽÂÇÉÎÅÂÈÀÇÍÈÄÌÊÌÏÈÄÄÐÈÆÂÆÈÄ¿ÁÇÌÌÌÏÂÊËÈÇËÐÄÅÇ»ÇÃÈÉÂÏÁ½¼¿°ÁÉƹ½ª±²§¥¢œ˜›£™—™‘•˜‰‚wotdk`^fpa[W`GHHGIMTG?J=64355==48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ¼ºÍÍÆÐÕÕÙÚÛØÐÉÏÏÑÓȶ»»­£¶}hƒ„¥«“–…ƒƒƒ}„„~s`[^^^`^`cdc_\]^_``_[Z\`krrooklop}¹ÑÈÉÊÏËÍĺÀû»ºº¾ÉÆÂÃÀÃÈËÉÈÊÈÁÅÌÆÈËÍÉÄÂÊÉÁÂÌÐÅËÈ¿¹Á»ÆȾ¿ÆÏËÿûÉÇÈ»ÈÆÅÊÀ½ÂËÆÅľƽ¼ÀÃÅÌÅżÀÊÂÅÇÒÅÀÉ¿ÊÉÆÈÆÐÃÃÆïÄËÇÃÊ·¿¼º´©¬¤¥˜Ÿ˜¬£¡¥›£ ›”{wrtfiZanlZ\XRDLFBGDLDFS@54334?=3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ÊÏÑÌÇÂÃÆÍÎÎÌÕÏÕÙØÙÏËÒÍÍÎÈÁµÃ¾±¯µl_z~¤Š’–†z€……vxurp_[[]``bcdded`[\]]_^`[YZ\borokilposÇ½ÉÅÌÀÆ°¶º²²³²±Â¼¼¼º¸ÁÁÁž½¹½¿¹ÄÊÅƽÆÀ¸»ÄÉ¿ÁÉ»·»»Æÿ¼ÁÍÃƾ¾µÁ½Ãº½Æ»Ãº³¼ÅÄ·¿µ¶¾¿»ÌüµºÈº¿¾ËÄÁÆÂÅÉÆÉÆÐÆÂÌDzÇÉÃÎÌÁÅÃÀ½³·°²§¨¨¹°¥­°ª­¬”zvwjdg`hocW^YJFJFHJAEBEI@9:648854;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÅÂÄÈÎÒÊÊÊÇÍÍÎÑÈÐÆÕÔÖ×ÍÊÏÅÉÅÇÁ¹Å½«­¥_eu†“‹ˆ‹„x††~„{ttc\\]^``bcaadeb]\[\^\^]Z[\^hsqmggnpry½ÌÀúÀ¸®°±§ª­¬§¸´·´³³´»µ¾²·°µ¯²¼Â¼ÁļÀ»µ²º¾À¸Ç¹´»¶Á¼¸½ÆÁûµ¯²¶º¿´Ä·»µ«¸½½À½±º¶°¶º³Å¼¶®»¿µ·´Å¼¾ÃÅÀÃÅÆÈËÅÀÆÆ»ÇËÀÏÉÇÃÆÂ÷ý½¶¹¾Ç¿¬µºµ·¶Žytxggebkn^V^`FKHHJFBDAEE?<:565633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÍÈÅÈÍÌÐÌÍÈÊÈÊÉÊÄÐÍÒÏÍÅÇÁÅÀ¿º·É¶ª°™[iqŒ…ˆ‰zx~††ww|sh]]]]_`_`da^cec__\[^\]^Z[[]_lpnhfknnr|¤Ç¿¹¸µ°«­§ž¢©§ž«­³­ª¬©´®·±³©®¦¬³¼º¶Ã¹ºº±«µ¹»´Âº°À±¾¼»¶»Ç¹Â¶­ª¨°²À¶¸½°±¨²³µ»¼«®µ¦®¶¯»²°ª¹°­»®»¸»ÀÀ¾¹Â¿ÇÃÅÀ¼ÆÂÈʸÅÇÅ¿ÇÄúÄÆ»ÆÉÌ˳¹Â½»³‰svvkiablhYXW[ALKMIEAC?FA:9:995854::9;<=;:;>8;@<=9:79>9;<:8;;:>=9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÅÎÒËÃÅÁÅÐÇÍÁÃÆ¿ÄÄÃÃÊÂÉÊ¿À¼Âº³´µÃ®©°‘[j’‡Ž{x}‰…z{„€wn^]\\]_`__dcadcb`_]Z[ZZ]ZZZZ\enohfgiknr­¹°µ®¥¤§§š ¤¡šœ¥¬®¤¨¢«ª­«°£¦Ÿª­µ¶±½¹¯·¯¨®¸´´¼¸´¼¯¸¹µ²¼Á²À®¥©£«±²³¨½ª«¨«­­´³¦¨­¡¤¯©²¦§¨®¦¨·¬±²·ºº¼±¼½¾¾Ä¿µÂÁÇÈ·¿ÀÅ·Äÿ»¿Ä¾ÄÈÌÊ¿¿ÄÀÀ©‡strji]aocWVXPHYRSKFFE>>@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?B;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÐÏÌÃȺºËÁʾ»É¶½Ã¾ºÊ·ÁÃÁ´¶¼¶±¯µ»­¨«“emˆƒ‡‹€{}~xt~|swe_]\\^_`^_ccab`a_]]\ZXY[[YXZ\_fkfdgehjor…©¥«¥ž›¡¥”ž¥›˜‘¡£ª££ ¥¦§¦­ œ¤¦¬²°¶·§°¬¨ª´«´º±¶¶®¶¹²¯ºº±¶¥ ¤Ÿ¦±§«¨¹ª¤§§¨§²­ §¦Ÿ›¤¦¬žŸ§¤ ¡±­­¬²´³´°µ¼¶»ÁÀ²º¾ÃÁ²¹¹Ã³Á½Àµ¸¼½¾¼ÂÇÄÃÄ¿ÀÄ ƒxplbf_ko`UY^HNgOTHEKF<=?=:;;8255369:8;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;=:7776788666;::;9:;<859<:>>@;Èµµ½¸ºÀº½¶ ž•¡¦º¶«³³»³ÄÏÉËÂƸ¶ÇÀÌ¿¸É·»Å¸³Ä¸³¿À¬µ¼²¬¥¯³­¡£’iq†…†€|yusomjjipi^`]\\\^__acb````]\[\\XYXXXVX[^_dcbegggjmo‡¨Ÿ••š¡–œ£™–Ÿ¡£§œ  ¤¥¢§ž›£› «°­±¶£©ªª¬¬¤´¹­·°¬³µ®³µ®°ªŸžŸ£¢²¤¦©¸­¢¦¦ ¨¬«™Ÿ ž™Ÿ¥š™£œ›¯©«§ª¬¬­±²¸¯¸¹»°¶¼¼º«³³¹³¾´¶²±¶µ¿¶¾À½Ã»º½—„zsl_e^ddXTW]IW\KPGIJGA<??@;?<04535:;9:899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»·ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÆÏÈÈÀÆ»»ÃÃϾºÇ¸¸¿·²Â´±»¼«¹º±¢ž©«§—žm~…†xrmomkb^aff]]^]]]\]_`abccba_\[[ZZYXXWWWXXXZ^bddeffhikq§œ“””›˜›¢—–‘œ¢¢¨žœ¥§¢¥œ ¡›™¯®®®² ¦¢®«§¢µ±²²¬¨¯³§º³¦¶ ¢žœ£¡­£¢ªµª¢£¦ž¥¦£–™ž—™› š—œ­¢«§¤¤¦­«³´ªµ°³«²¹´¯ª¯²²³¸³®©¬®²¸°»¶º½À¸³±”…yuf^e^[YVSZUK[QKIEHKIB=?AA@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½·½¿¶¾¼¿³¥£˜¥±Âµ¶½­´¸ÂÌÈƿŶÁÀÆηÀĽ³¹¹³¿¶±¹»¬²´¯Ÿš¤©Ÿ”šxƒ„xoqtqhechdc\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXWVWadecdeddhjv¡›“””—— —™•— ž¡– ¡©¤ŸŸ©››«§¯°«›£¤¸ª¡ ®¨¶ª§§­±¤¸°¤· ¢›™™ª¦¡š¬¸¯¢¡¤œ¢Ÿ “”¡”––›˜—–—œ•Ÿªž©¤¢£ªª°®¨´«ª§­³°¥«®³±°°®¯§¨¨²­±´°¼´º¸®£”yud^aVYXSRTKM^LOKGGLLE=A><B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾¸¼®§¨£ª»À½À¹®´¸ÁÌÇÅÂýŸÈ˲ÁÂÁ­¼»µ»¼µ¹¹°¯°ªœ™¡¨”‘Š‹€€|wqilrtphhedfb\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWWV[bccbcbcdfi–“•‹’””œ™––œ œŸ– Ÿ§¦¤¦§Ÿ ¦ ª¯¦Ÿ¢¤·¨¡¡¢¨´¢¥¨¥°¥±®¬´ž¡••©¡¢”­±±Ÿ¢£ž˜›“‹¡”‘“˜˜“——˜—ž§œ§¡¢š¤¥¥«¤¥°§¥£««­¦©®¯®«¨ªª³¦¦¬¯´±¯¼µ±¯¯ ’zwrea\Z]XNLRHRaMVPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8847763321./2556;:8;7876<;:;;A8x»»±µ½°»±¸¬ž¥§­·»¼Áź±¹µÄÉÉÀÃÆÅǶÅIJ¿ū··½¶½ººµ²«­¨™˜Ÿ£‹‰t‰ˆ~vncafihfgifjm`]\[ZZZZ\]\[\^_\ZY[YYZ[WUXWTTVUSURU``_`a_aabej€““‰Ž”“”•–—¤™ — ¥¢­¦¥¥£¤£œª«¥šŸ¥±ª ¡ž¥«ž¨¢ž­¬©©®­¢¢¢•˜£›œ«©°œ ¢Ÿž—™“Šž‘’“–˜˜”œ¡£¤¡¢• ¢¤¦›£«¥¢¤ª£«®¥®²©¦¥¦¦´¦©¨­³µ´¹º¯ª¬žŒrqo`[WVVRGQOHZ[ORITKSLEFID8;;=<8667:9;:976977:;:=<<6;<8>598:88659:;<97?<9578452121..1426:8698598989;9@9{µ´­´»²°«²­¨§¯¹¹³ÀȺµÀ¯ÅÈ̺ÁÊÌȵɼ±¾ÃȬ±¸Áµ»À»´´ª¬¦•š›œˆ€rˆƒ{tiijlgjkmkjme]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURSOQY]\]^^___bdmŽ„‘‡Žš“•’œ›£œ›¡¨©«¨¬§©¦¤™¥¯¥•™¥¯ª œ™› ž¯™œ«³ ¥¦Ÿ£¤¡”“›––’©ª­šœ ¡ ›”Œ™ŽŒŒ‘–•¢ £œ£•› £¡—¢¨£¢¨« «°¤­·¥£¤¢­­ª¨«¯³·³¾µ³«¯˜…tsh[YYSUREXLQ[XMTNPLPQINIB=??A?=75799<<987:79:;<=>;7;;:=67:;8976989:6:=99577570141-+/434988::8::748=8?9~³­§³¶®¨¨¯®›©¨¬·¶¬¼Ê»¶¿¬ËÆŸÁÎÏȳĺ·»ÂÈ°­¸¿·¼½»³µ¥© –—˜—‡zt€vwnmhmmmpggigd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUSSNPQYZZZ]]\^_`d~Œ‹‹‰’—‘—™¢ › ¬ª¦¯¬¨°¥©šŸ­ •–¤©¨˜šž®—˜¨ª™Ÿ”¥¡ž’‘’‘“•§ª¥š™™žž–Œ‹“†‰ƒ‹’•‘ ž¡¤˜•Ÿ•š¡¢ž”›¥¥§¨¨ ±±¦±¼§Ÿ¢¬µ«®§°µ°¸µÀ±­±«‘~rsbVTUNRJGVPRQLLWMJLNRGMKACFDC>A75889;9:7::7<=:;@>:9;9:?759:9876958779;85576761320-*.102877;99;8948;8@9³¬¥±·ª¥¢±«ª§©²±¤¶Æ´¹º³ÊŹºÁËÐʱ¶¸»½Áñ¯±·­´³»³´¢£œ——”ƒwkglnqnqjpkdege^ZYZYZZZZZZZ\\]\ZXXXYYWXWUUTRSUSVURNNNRWXYYYY\\]aj€zuˆŒ†Š—‰”“˜›™ž©› «¦¦¬ž¨š ¦œ“Ÿ£›——…„’›£•£–––ˆ¢››”‹ŽŠš¤§œ••—›‘’‡”Ž‹‹€Š’’’ š ¢–”˜™•¢¦™™¤¦¨¦¡ ´²§²·¡œ¢·¬ª®¤²²¦µ¼µ¬«±£‰ysm]NQQLOCMNNPKFNNJJMNQHMJAGKHHC=858889:;69:68;99><8:>9;?8789:886857688974577820301+)-/12876:999984988A7w¶¦¤¶°¤§¤ª¥ ¨¦¥³ª¢²Ãµµ²³ÆÆ·ºÃÊÌƳ¬º½´·À¯­©°ž¦­º¯®Ÿ™š•”‡{ƒn__frpuqinieghj_XXXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQMMKLSWWVXXXX[]aosvp„ˆ‚ˆ€‘„ŽŠ”‘”ž¡›œ£¢¤˜¥—¢œ•‡™šŒtƒ~Ž—–†‘š”ŽŽ{™Œ‚‰‰˜Ÿ£ž“˜–…‚”~~tŠŽz‡“›šš’–Ž££Ž‰š ¡£¤›¢´¯¬¯­Ÿ˜¥¸¦¦±¡°®œ°»ª©¯ª™ƒwscVMROPNCSNLQLBPQHIMRMHJJDJLFJJ=749888;;69;7:<9::;79?9>@79:<89764445874312585/0102)(,-12764789::65:87A7x·¡£´¨¦¥¨£¦¥§¦§³§¥´Á¸°´°ÉÄ·¹ÁÎƽ³¬ºÁ«­Ã­§¡¦’¦¶¬£ •–’~x~eWV_gfighncjhgb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTQMMJHNSSSTUUVY[]ilrl…|tNXr‚—†—‹”‘Ÿ˜•”–•–‰€“Š_;Wo|Œ”‰€Œ’Œ††sŠ…—y{†““ƒ•Ž‘ƒ†}“xqp…}‰‘—š™“‹‰ˆŸ˜ˆ‡–žš¡ —§®©­©¨ž–­³¢¦­™¬«˜¨³¢©­£“~rn`[NSRWLDTJPLLFNOIELQMKOJILPFII=7599999:7:;:>>8:==7:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9y· £­¡¦¦ª §©¨£ª°¨§´Á¹°µ°Ç·³½Ï¿¹¯®µÂ§ªÅ©£˜ƒ”›±¢š˜†”‹‡}su]PLRUYZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MORMKHFHNQQMPRTVXZ`moi{‚tQB@•’‘}‰•„Š›Ž–•‰’ˆ†•†y‰`JQnx‹’„}„Š…n~”xuvx„™oQˆŠ†{~x”vgw†ˆ}Š‰•‹‘’—Œ„Šˆ•„šŒ‚„’š–ž”¤£¨©¥¤žš°«¡¤¤‘¦ª–¢ªœ¢¦¨‰umf^[HQQSMIUMSILKOIHFJNLMTKQPOFIC<768:8:;;8:;8>?99>=8;<6;;478;6775344696/3/.125221/,')+*,4833979:99::::?9w¶›£§Ÿ¡¯¡§¨¥§¨°­ª¶¼¶··³Á»¶§ºÈ¸¶¨¨µ¶ª²¼¦ž•‰“¨–•Š~Žƒ‚}xpnXMKMMNKMQW[\ZXZUUVVVWYYXXYYXYYYZXXVVWUSPMJE@@›kssIMJDDDINOhYNQSTUZnƒsv~ji\U‰”‰t†|…Œ“‚’š‹{†€v€xsovqtŽz~Š«…yzhv{Žprmx‹’xz€{€vrr’whu„„„…{•‰ˆŠ‹€„‹Œ€”ƒ|€˜”œ–‘ž©žŸ  ©¥ž˜Œ§¤“¡ –žŸ¤€rha\]JWPRGJXROJLMRJJJLPILQLRTMEHA<78;99>=:;<98@?::>=7==79937785675251472/2.,//200/-+(().1272198798775:<;7v®™£¢˜œŸ´©¯©¥­¬°²ª½´²»¸¶º´±Ÿ·º²ª¬©¨²¯¡š‘”€ŽœŽ‘v†x|vooiXKHIHGEHHPTTTWWSTUUUVWWWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQQSV^t‚{xfw—˜}hyvx€‰}„˜’r‡|w{ok~­|sŠ{†’}tfv|†lohs}‰Œˆ€lyq}qmvqhq~ŽpC‹„‚ƒ…wwz‹…}Œ{u~Ž’˜Š’š›£–™šž¡œ–Š¤›Žž—Ž–˜womebZXXUQJSUTOPNPVKNKNOJQNHOOLFD<;79;::?=9<:99??;8;=7<9999266856633611224.,,-..-0-+*''*.1362/876966527995y¦— ž– ¦¯¬®«¨©±¯±«¼¸¬»¾¹³¬§›°§¬›–œ¥©¤ —™Ž…’yˆŽ‹Šuq|mupjmjXKFGEA@CDILLMQRPQSTTTUVVWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNOQTX]eprlˆ§ªÀ~uyc|xo|yˆz}‹†omŒ’ytxjj€‚q–‘‹~–€I“˜nhw~‚licly…’†ksl|nr{†imps‰„†{}~{vots…‚yyp|ŽŒŠ”ƒ–—˜š’•—™—–Œƒ‰ž‘‹’†–€ojnonXVXTRQYORTTSXUMNHNKMNKCHNGE?:89;99:><9<;::=>:8:<9?868727565541432/024*+**-.+-*(*(',-1250,5567485HA895w™‘›™šŸ¥­°£¬ª¨µ¯®¬´¿«¼Â¿¦¢™•¤—ž„‹”¡¡˜˜‘“‹sŽz€†Œ†totkqldljYNDFC@<>>AFFGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_IMOORWZQY\`§ˆbšitze~pmz‹‰v‚ˆ†tlš‘ts|jkMy…’‰„Žg1v†sl~~ƒtfet~„„…€filukq|hqq|n“Ž|s}|qpnvm‚wyujy‰‚ˆ‰„–’’‹‘””Ž—€yˆ—ˆ†Š†€ˆwkkoheXQZWYY[MPUVYXNIHEJJHGB@FDCG=998;9:9<:9;:::@<9:<98>787715234533645031.**+),,++)(+'),,226,,5775478iO8;5n’ˆš‘™–¤¨®ž²Ÿ§»¯«²°Â±»Ãǚ–”™‹Ž†y„˜”Œ†q‡‚t‡Œ†zprpoodpf_TFIC?<;9:?@ADCEGILOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOOQVLAIQIb¯³ r|xm}lqƒ‚…z„††yr¡•tx€su”‡5q¨Ž¡¡„¢„vp†|‡|sŒ­‰€ggbjnrmpƒuioXupŽ›’wlz}mrnp€zsvnbvƒ~†€…ŠŠ‰‘‹‘Œ‹ŽƒuxŠŽ€~ƒ€}{rppl`[\^\YXa_RN[ZXWLHJFJG>BABG>CD=;97=;:;;9:99;:?<88=:8;66651121253474531./,,+)*))***)(*)+/3DM2166643<vR7=7b’“ˆ–‘¤§ž¯•¥µª®±®Á²»ÁƖŒ”€ˆ}n’‰ƒŠ‡…u‚„l•ˆˆ{txxlwnwci^JPG>@7449;;;=>@BEHLLLLNPQRUUVWXYXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL7CMRSDJ†v€||v~lwˆˆ|~…ƒŒ~v¢™y~†…™…›œa†ªŸ‹ƒzwˆ~‰ˆsŠ—ƒz]drtz|wŠmhjbyo†‚znwt„zptywkni]w‡|‡|‡‡‹’—ƒ…Œ†}q„ƒ}uw{|‰wpsteg_[[^T\g^WQUX[UGJJDLG?F@DC>AA=:97<;;=<::99;;=>79>9985653244004645554-,)+('''&(())((+++/00Uq=23331E~W4=9\ŒxŠ€”Œ’œŸ¦‘ « ±¨¯À±ºÅº–Ž‘”‡z…vkŒ‘‚}Š„ŽŒxƒ€s¡„‹}}p€~zgvkRWL@E211367688:<>AEGFGJKMOPQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMORLKT]YRJi„ˆ{‰y|q|Œz}‰‡~—‡v¡™ˆ‡’”¥¬©H†®¯¯‹€“Š‚‹„’¨‡€˜˜Š›tm|†‡}Žhghxn…‡‚…q„†Gl€wryvhmk_w}ƒ‰ˆ…‹z•›‰‹ˆ‘zu‹v|xmow}ttrl[]][ccXgf\UOPVYPDLKFNICFCCA@CA=988:::;;:888::?>6;>7595773344236656768;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|}‰…ˆ‘–˜’—¡¬¡¦¸¯³¼³—’‹˜‹}tp‰’~}Œ‚’”}†~†¤‡ˆ‚ˆ…x‡ˆ~s„x_cWKB60./23123668:=>?BEGHJLNQSTUTTVUSQOGC?80,#‡[>?84.]–ps£UFIKMNPW`YpZ\^j“‡•€„‚…‘“~…ˆ‘š•‚¡¡˜•›š¥­“š»±§»Ç苌¡¥”‰‘|qƒžŸ‘œv……Šˆihoƒ€tŒ‡„‹q…‚w‡{v…}nvuf€”†‰‰‡ˆ‡¡ª¢–‰Ž˜z‚‰zyogkx~z~rjd^ZZ]j]af`YOKNWRQHPJDNGCJDB@DDA<:87=<:<:88778:==8<=68756623444576867<BB?<8:>CQ^e\G2'&,,--.1(?‹[.320Oƒ_4?;nupfxƒ{€Œ€‘ŽŠš›¤¡¬¦«¯°—‘‘„¡”„xwŒ”|’†’•Š€’›Žƒ€Œ‹‚‰ƒ‰mpj]BA4--//./02234779;=?BDHJNQRSRSTTRPOHDB<87/9D><<63.l“—MPHIKKKNV`cggmušš““‹Žšˆ“‹  ’£ª¥£¬“¨¶¢¨Áîǯxº”š|¡ž™„“…‚¡Ÿ“˜’„‹…™‘–lpu‰‹‚–Œw„qm…Š–‘ƒ…ˆrˆ¡–‡“‰Ž–¥µ©›•¢ƒ‡“ƒ}kjk|€sa]c^Zfk\lk^WKGORQNMLFIPCDMFACEGB>:97=<:;:987767;:6=:785456345566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYp‚pu‡qv’†~—–š•žžœ§ ©–“˜žge¤š~„’‘y€’ˆ’}Š„˜’‘‚€€‹‰…†„ˆ…xx~gMR>/..,/.-/000212457;?CENPRTPQQSQNPIED>;<:CF?><752<?R5HHHLLMNR^oŠ|s} œ¨¥¢™¡—¢•Ÿ¨ž¨« ¨¬©ªµ—«¿«¶ÈÈ·ÉÑϾ› pi«©Ÿ„“’…œ¡š›™§‘‘‰•¢ššxz~”˜’¡’–˜”ž{w•’«³ˆ—Ÿ}”žœŽ“–™¤¢¦¶°‘™¨ˆ–ˆlsr||qh`\`^bgc`hg[REJKPOIJLFFMCHLFFCBGEA:85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Ppu`n}awŽ}{”ŽŽŠŸ’—ž–›ª˜žªBD}‡‰‡˜x‚ŠŽ|Š†Ž‚€‰ŒŠ„’…ƒ†‰€†w_bP460-1/,.00//..0015>AAMQRSPRSURNSLEE@<>=GG@A@8662<9;FHGIJNOQYm†w•‹£§ª´½¸¤®¬¬§¨´«°¶²²­»±³¾œ³Ã¬»É˷ÿ¸¥£°²¬­ª£‹–˜…¦¦ £—¦™¢ª¨¤ˆ…”¤¡ ª¡¤©œ±‹•£§·»› £°“££ž‘¤¢«¯­³µ¢”¤ªˆ™‰’Š•yz~…~g`h\eb]dc_ff_ZODIHSOFHLFJGEFHAKECFGA;87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLicWjpXz…v“…ˆ‚›ƒ’‘Œ’Úȝ–sV—ˆˆœ|†ŒŽŠŠz‡‚‡‘ƒ…€‹…†‡’†‚„‰†ˆ‡‡qna@E64<2/110-,+-1.-3?DAMUQRSUUWUN[PGGE<>>FHCD@8;<5C;=FKIGHROPW“ „®£³ª±ÁÇê³Å¶¬³¿³¸¾¶¿´Á¶»»¤¸Æ¨¶Éǵ¾¹´¨£´­±±›™’šŸ‰¨¯«¥”vŸ¤—¡«±³™–ª­¨®¶»²º¬¯µ¢±¬±µ¼·µ®µ §§£¨š©°­²º¸¸§›¶©Œ¥Ž‘“Ÿ†x‚ƒuYadVeaac`af_[TIDDLUQHIJDIGEA@@JDBMF<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AFWQJL[ZQcdWyuq”}…‡“v…€Œ{¿»£¼‚´”“›„ˆ’‰‰y†€Œ“‡„Ž‰Ž†€†‰…Š‡‘zxn]V@EM<6:46AB764//6CHCQ[OQUWU\VO^UIKJA@>GKFED;>@7D7?BJJEFWTP^¥®£±´Ã¶¸ÁÌɶ»Ä½³³À··Áµ¿°·t±³¦ºÅ¤°Æ¹±³±´¨¤µ¶ª± ¢–›¢’¥°®¦­«§¤˜ ¬³º¢©²º´»¾Ì¿ÅŽ½³Â·º¸¿·º·¹¬¬°¦°ª­¾°½»Â¬™º¨”®——«‰}‚|jWbaWjejeW[dYVSIGFLQGCGIAHD>?BBK@@MC99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FRLALRWTYUZvjp„Ž„nzsy‡b¸¡™¢ˆ•“–“”“–’‡‡{†–Š€„Šz|‹‡†|ŠƒŠƒ•}xzueO\dGEL:Qca[^SF?;HPDZcQQYXZgYT``MSPEA?IJHEFA@C<E6B>HGJLSZT]“¯¸µº¸É¿º½ÉÌ»¼Á¼·µ»»·½´º±Æau²¥±šžª½ª¥¨«ª£¢²µ¡«¨Ÿ•–Ÿ˜Ÿ®¥§¦¥Ÿ£”¢¦±´§²²½¶Á½ÓÉÊÓÆÂÅËÁÊÃÀ¾½¿»¼·´¯¸·¶ÃºÅ½ÃÈ°ž¹ª¢«Ž¥¨¶‰r_ab]Wa_hfRXaVRUIEENKA>GD=KB=B@=F=;H@796379>489:57045/26389374426?8@>GKRTSQPOQQPJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKE@IMPRLQ]gllq…slrrsˆÕÀµ™ •˜™‘Ž—’––Ž†‡}†ƒŒ–Šƒƒx{‹ƒ‡{‹yŠ‚—t}zkepuY]\Peeb`ed][XW\MdmURmm_n_XgeUYUKDAKKHFIHHGBI9D?HKTTV\Z[’¹À¸½·ÆÀ»¹Êʺ·º¶¸¹²·µ´®¶¶™du¨œ­p^¡­œ˜ ¢›¤žª¥” Ÿ”Ž–˜—¨Ÿ¥Ÿžšš„¤¬¥ª°¬·°½¹ÔÑÏ×ÏÉÌÑÌÏÎÊÆÀ¾ÂʽÁ¼ÁÀÄÄÅÊ¿È䤻°´¯›«¹¼šzl]`\Y^aYccQ\`SPKCBEGE<@E>AHA@D=:E>=J?47535;=468977022/24169775555D3ELM>51/006:477@IOI;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODR\Yi_p—’”olouu‡³¬¡¡Ÿ‹™œ™Œ•‘›’…ŠŠ~ˆ†Œ‹‰|„s{Šƒ†{‰t‰†•s{xkmu{hreilifjih`fihlZnt—­¤¼ˆ‡g[oh]ZZTHKNOJKQKTQHLAJGKP_^bfia—·Ç°¸³»½µ±Äǵ°¹°°»«²±§ª·¬¶§›§šOšŒŽ –‘¦˜¥•Š““‰‰‘‘ž›¡—š•–‡žš¦›¬¯¨¯§³´ÔÔÔÖÒËÏÔÕÎÓÏÍÅÂÉпÊÉÊÉÑÇÌÍÂÐÒ¸°Ã¼Ä¹¥¶ºÄ¢‚oc\\^XaXYeZQ]WOOBBHEBI;AC>AG??A8;D>@H=46655;:687654/10146278875367C5B8?-0-1349=97,.,1;FK=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYSeWs˜‚hqoyyƒ ªž¦—Œ››—‹Ž•‘šŽ}‰‹„ŽŠŠ‹‡|„‚p‡†{‡rƒ‘‹~qxukqx~q{mxslipmcinpxiw|~Ë¿Âߧmcxnc[a`JPRUNY^P^]MPNTQUT\nnv‚r—­¸¬³§°¶ª¬¼À±«µ¦¤¸¦«®¡«´£Ž±®š˜˜Œ‘“‘„Ž›§’œ‰ƒ‹„Š‰„‹ƒ“•˜—“›‘œ˜™™žž«¬¤§¡¬­ÏÒÕÑÍÌÒÓÔÐÔÑÎÈÃÔÑÈÍÒÓÓ×ÍÒÑÅÒÖÅÀÎÇÇ辷Оzof]b]W`S][OPTPNH>AFABE<@B>ED>??:==<<JA45465<888664412/03526768533;=<E=@11+/249>5901022-2DN3)/3.32=N238C}_2A†tD:==I>@CFH<VRMO[u†…Šwlwp}~¡žž¡‹™““ŒŒ“–…y…‹Šˆ‘‡‚{r~€‡y„u…’‘‰ovrks|{w|swqk€srhoqzyr{¾Ë›~Œ²ƒvr„vhaj]CZZ[WfdXekSX]]`d^cx{~‹™ª¤¤¡Ÿ ¨¥ª°¸ª¥´£¡­¡£­¢§±Ÿ‰¦š”’‘‰‘Žˆ”‰k•¢™„€…}‘ƒƒ“–­‹••™Ž…’—§°¡ ¡¤¤¨ÈÎÏÈÂËÑÔÑÔÓÎÓÍÆÖÒÌÔØÖÖØÔ×ÕÉÔÚÍÉ××ÑʬÄÃˋsoc`_XTZS\PJGIJJ@;:;EBD<BC>HB>BB;;9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/--;R017/532FD28>nb5=tM99@I<AD?A;PLFKYp€u}hsxr‚‰€•”…‹–‰ŠˆŽ‡x„“™Šˆˆ‹‰~‚xs{}ƒ‡wz‡‘–€ƒnxpmuvx~t…|ym‡vtn}v„uy{¶Œ<A‹Æ¥~|ieVICfcechjdox[_fiknin€ƒ‰‘‹ž —˜Ÿ£¤¦²¤¤³ ¡¥ © ¢±œ†ž’’’‹Ž‹†ƒ„~œ›Œƒ„…z”~‚©•£Œ’Š—’‹}—Šš‘ª³˜š›§œ§½Ãƹ¶ÆÍÒÐÒÐÌÒËÉÔÎÐÕÚ××ØÔÙØÍØÛÎÉÚÚÒÕ¿ËÌ´xvoe]YRVQZVFGJIEE=:79@AB9GD@ECADB;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?1*(.BS39254/7K75<`bA<svV87AH:?C><9QECJTlnopaqqs†|—‘‹~‡’‚‰†…Š‡|x…––ˆƒ‡…‡z„xqz{„†uz…ŽœzŒp|oozq|qƒ‡€nŽzuw}|‚u|‡ˆ°tY©Â¶Œ’‚pnb=^hrpqpnxweioruxrz‹‡Ž”’›• •‡Œ“› ›ŸªŸ ­œ¡š™Ÿ¥žŸ¬™‹šŒ‘‘„}ˆ‡ƒ…‹ŽŸ™“ˆ„‡~m™y„˜†ˆ“ŒŽ”Œ†{›ˆ“®ª”•—ž˜§®µ½©­½ÆËÈÉÌËÏÈÃÑÊÔÖØ×Ø×ÕÛ×ÓÙÛÖÐÛÚÑÖÉÔ˕y{ii[ZPRT^HBEII>A==7:=?;=G=?AAADA>>:86DB755479.566435532323647553457EBDCEB56<FNSM[nfcnskaV>,4LG865434BF4=W_hLux^8;?F<<B<:9D?CGRk_mdbfkv€ˆq‘š€z€~‚‚„~ƒ||„—Ž‡‹~††€w‚yn{{†uz’ž vu‚tu}t€„oo’„t|…zv†{‰·Æ¥ÂÉ·–›wpeNfczw†¢‹xyw{ƒ|„un“–”•˜ƒŠ–š——¥œ— —Ÿ“’—£™«•Š‘‚Œ…‰ˆ…‘žœ™‰…‹†˜z‰ˆŸ—ˆŽŠŒ‚|¡‰‹¼¡˜“—šœ©¦¥®Ÿ¨µ¾ÀÀ¹ÇÉÍÎÅÍÉÑÖÖÕÙÕ×ÛÔ×ÙÚÛ×ÛÚÙØÎÜƆzzhid`TWVUMJDND;=<<9:<>9=@6=?@<?><9867CA6455=80665547745613854564567HH=DJE7925;H>;::7IP]ZRUXK9T>;95327I8=NYMHxxd5=>C==@:6:>>@EQ_Yea][htzyl‰’wvz‹|~€~|…{~‘‰„…z„ˆ{u}tm|}†~s~’‘žƒ’|†~xŽ}yŠŠn‚š€t˜…~‰…|~z©Ã ¼Œœ£œ}‰„}‰sŒŠ~s¦šœ˜”…{‰„hGp ¤Œ‹’…‰‹’•œš’”‘—Œ•Ÿ”¡”‘‹~ŽŽ‹„ˆ’•šŸŸ‰Œ”’ž‘‚‹¥™ˆ„Žƒ†„€¥†Š‹¸˜‘•–¢§¡ž£®¶ºµ«¿ÆÊÐÈÇÌÏÓÒÒØÒÕ×À×ØÙÛØÚÚÙÙ×Ü·xxxljdW`[TPNGCLB==>99::99;=6?>><=9:;;37D@8378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWN<MTHN?96333>C;[X>5YypZ<<A<=>8589?=DRSRX^UXfmmmiŽŠqryŠ{z|{ˆ{|{‹‡‚~uƒ†yszsm€~„}w…›¡›”’€‹ˆ˜‡€œ’n‡¨…z ‹|‘Žƒˆ„œ~š‘Š£¢Ÿ¤® ‹‘‹…‹’†Wr­‹Ÿ«›ƒ˜›Ž[‚¢‘‚ŒŸ“•Œ‡ˆŒ’“Œ”””ŒŠˆ–›•–‘‹’”†€‹ˆ’‰Šœ–™¢¢†’–¡‹Šˆœƒˆ€ƒ‡…¤†Œ³˜’”—¡¡ž™’œž§±¸¬¥¼ÂÇÍÇÆÏÌÐÌÎ×ÏÑÔ®ÖÕØÚØÚÚ×ÖÙڟo|uhg\]XSWXC@ID>>>:49:;7:;:3;;?<>7;9:19G=:37=@50677255?65;55858:57735HR7GOK994=EJB>1FCLB98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:<@;BQKKSYPTcbxmb~’ƒomw‹xyz|†|{w†„sp…‚zuvvt„ƒ…}’¦£Ÿ¥¢–‰”—‹Š¨—rŠ±Œ„§‘„™“…™‹¢– ˜“‰›¡’©¯Ÿ‘”ˆ•‹n·…šÄȲœ¡¥›œ˜–²d¤Íǖ…‡‰’Ž“”‰…ŠŠ†–š›”“†”—„‹™ˆª——££ˆ™ž–›‰‡——Š„Ž‡¥‰“©š—“–™¡™Ÿ™“›£³´¥£¼Á¾ÇÅÅÉÈÉÂÊÓÌÍÔ¨ÒÑÖÖÖØÚÔÓÚ΂rhc_]^NJTZBAGD;A=837;<:8=649:<:82?9:29I:>67BC32:96264>=4;>6949;57944KQ<JQK9A7BGI@64JELF><88ETA7>\86214:;E`XAFathLcZ>5;::5;:>:EMFHRWSRBcFu‚}|m~ˆxz~zƒ~vv€ƒ|ln‹y|xx|„‡‹}Š£³§£ª²¡–§Ÿ¥¤–•®¢ƒ¸•’³™¡ Œ¥›¯£¤˜§–§™­¯¤—”–”‹˜™– ÀŽ¤É¸«›¢¦­˜‘šœ²†…¨¢œ˜…ˆ‰Ž•‹“Žˆ†‡ˆ“˜”Œ‹““†”˜†„‘œt‘™²–—¤¡ˆœ™“Š‹—š‰Š–Ž†}Œ˜ž‰œš™“˜˜ ” •Ÿ›¡±®¢¤·¾´ÅÇĽÃÿÆÍÊÉÒ§ÎÍÓÒÐÖØÓÐØ»ryv\`U_WPHINEBCE6>:76:?;<7=42669774=5<5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=89566=:JFDGN[\YIf`;H„‹zzm…†z|„x€…~px|}|orz}{x†‹‰…ƒ’§»­¨²½¯¥­³³¨£¢°¬Ššµ£¸¤•­¤–©­·¦¤£Ÿ™©˜©£¯°ªš˜œ”•‘—Ÿ—™»»­É i¶¸«°”˜ž£«“—¾£^ª²‚‰Š”‡‘|ŽŽ}ƒ†Ž”•ˆ‡’–‹•‹Œ—˜’™´–•«ž‹›”’’Œ™›Š’ž‹‰• ¡”˜š“œ™ž”¡ ”œ¥¯¨¡¥³¸«ÂÈĵº½»ÅÇÇÂÑ¡ÆÉÍÍÄ×ÖÑËÓ¡pzh]YS^ROFD><CAB8?874>F<<6<35355454B3::BM:A;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPeGb`bpI@‹Š~s†‡}ˆu‚Šƒm}}|pw†w‡{Œ†Œ™ªÂÀ¯½Æ»³´Á¼´­«³¶Œ¨²®®¼ª›»¤¨­¹¸«¦¦¢¡££¨¯²±«œ¤˜›˜—ž¢¥¥‘£¹®¨¿¼¬­²¹¥£§}ˆ†œ­½°ƒ‹Œ‹ƒƒ‘z‡ŒŽœˆ‡—‹•—”‘š–§š±š‘¬Žš’Ž•–—Ž‘ ‘‰•›£¬”–”œž” ž›˜ ¡•šž§§¤¢¤°²¦ÁÇ𰺶ÅľͧÇÃÇüÕÑÍÄʈtsb\Z`[MJBL@EG?A?B;:4>A<=5=6>333241A17@BN>G@CNCA=C=;86CC5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GE?CF\fF`igZ][“ŒŒˆ{‡‹†ƒŒu†Šo~|‚q~z•z‘””˜“•§´ÆÉ¿ÂÌÁùǼº¯«¹»—²¶º²À®¥À¤«¯»¼ª­«¢¢§ª®´°ª›Ÿª›¡›•Ÿ°´§‹¢º¹µÁ»«©œ²¥¤¨”…©ÃĤ‚‹‡ˆ„†•”zƒŒ‘Ž‘¡ŒŒ”‘‰—Ÿ—“™•—¦ ®ŒªœŽ–’‘••Ž•‘¡”†—Ÿ ²ž”š” ¡™¤Ÿš œ ”˜ž¦¤¦§¤¯­¥ÀÄµÉþ¶Î²Ä¾Ä¼³ÑÊȵtym\X\jSMHDLKKJAA=CD<5AD;:3=8B332263A05IEM>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBfZMe\fTcj™—ŠŒˆ’†‰y†”r€|x‡‚‚y¡–¨šš˜º¾ÈÈÊÁÒÉÊÂ̽Á³¬»¾§º¿½¼Ä·¬Á©¬²»½ª°©£¥£¬­³­¶µ Ÿ¯ž¥¢˜£´¼©›¨¼Á£¶¶¯«’¯¬«¬—†™©¦¥‘‚Œ“¥•‰uŠ’y…‘žŸ“”‹”£™—œ•”£ž©Ÿ‘¥šŒ•–ˆ}•’’£›• ¢œµ¦ž—¥¤£¥žž¦˜ž•—›¥£©¨¢²¬¨¼Àį¥³·ÌÀ¹®Ä³»¾Â¸¬ÂÃÂÀ˜myaXW\[KKMJFDDIBBACK:4DH9;4<7E.12352B26SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQF7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>jH_XaZddVž—Žž’‰Š‰Ÿ“„w…•ˆŠ•¡š®¦£˜Â½ÈÃÇÅÓÍÎÍ˻·¯º½´¼Ê¼ÃÁµ¶¼­³¿¹¼®¯¨ ¨§¶­­©±·šž­¢§¡«··©¥¯¾Ã±½¹³§ª´³­®––¤«§ ‘Ž’±Å§•Ž|‘•}‡‘™ª™˜“““•“¥ž“™“¡£¢œ˜Ÿ™‹žˆZ——’–¥™e˜£ž²¥–¢–¬­«§›Ÿ¦—˜–™•¡¤©¦Ÿ¶«©º¼Äµ¥´¶ËÁ¸©¶¬²º¸®¨¸º½¸ƒlnZWTUNFJSNK?BHEDHGG95FM;>7>AJ.32025B55PVN<LFKRLOHGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|hW;=@BFBqFiIRebLF¥”œ–¡—©–ƒ‡¦“ˆ‡‚œ„ƒ•”Žš¢Ÿ¯¾®¡Æ½ÅÄÆÆÎÎÎÒʾ»¶±º»¼¾Î¶Ä½·¹·²²µ³¸³¬¦œ««¸ª¨§¯°—£®¤§¤¤´À°ª¬³¾Â¹À¹³§¸´¸²®•¤¬®®¤‹“•¡tÁš}–™„Ž–š‹±•š™•’“™™¦£•Ÿ›–š¨œœ¡ š‹–`J–œš•š¥–T–°Ÿ¯œŸ¥”¯¯¬¦š¡¦”“™™Ž §¢™´©ª³¼¼»«°²ÇÀ¸¥««­±±£¡²²´¤qnf\ZNPKDPPPQ;GJIGHBC>9KU?A:=EM07544:B34NWO<JKNUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@CAF3>58JKCA=C;4EA:A?>H@5*B52,>c]g:35tde@R7&#3}iX;:BC@=QEWRsbWFHª—™ ¢¨¯™‘—‡‹§–Žˆ’…Ÿ‡„—Žž š£¤µÈ´©ÆºÃÃÇÊÈÈÌÍƾº²®¹¸ÀÁͶȺÁ¹¶º±¯®²´§£›ª³´ª¨¦­¬™¤®¥¤¨¬º¿¨«¶¶¾Á¿¾¸²²Ã±¹½¬£®´¬¸¥ˆ›—¦›v¾ „˜œŽ“™š‹®—¡œ›—•›Ÿ¡©ž¨ ™š©™¢§ž˜‘ƒnv’¢š•¢ž­²£«•¨ª˜«®¥¤Ÿ¥©“’™œˆ•œ¢ž—±¦©«º¶¾³²­½¹¶ £§¨¥§œœ¬©©Œcea_RKMGHNIUL=MDNJKBCD<QU=AABDO18=77?B75UXN?HNQYSPQTJQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW;:=..R`MUHe^HE«”œ¡Ÿ»¯™”žŒ“ª›‘’“‰«‡¢žŒ¤­”££¶Æ½´ÁºÂÂÇÈÅÁÍÈÁ½¹²¯¹´ÀÂʵƱÁ¼µº«¨­¬°£¢™ª´º¦©¦«ª¨¯§£ªª½¼§¬¼³·½Æ¼·µ¸À°½À³¨´¶«¾¥¢—‘¢Ÿ¼Ÿ‰™ ™–ž·Ÿ©œ¥£›œ¡š¨¥³¡›¥œ¨ªž™•”›‹—‰Œ¥¢”¢ž ´¯¥¥“°«™«¬žž¤£©‘•• ƒžŸœ–©¤¢¡´µ»µ­¨µ²³žœ¢¥š—•™ª¡žwa]`]JIFHMQIMEFGBRLIAEG@VRDH=AGQ1;B7:BF79\YKALPTUSMWRNUJD@JJNO9C?5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-1:g\FCCœpbGE§—¤ŸŸÃ¬›—¤—™©œ–›šª––§¦•­­™¡«¶Ä»¾·ÁÂÀÇýÍÇ»½¹²¯¸³¿Ãȵ¿¯¼¶º·¦£ª¬­  šªªÄ¢¥¨«¦ž«¯¬¢©¨¾¸¦­½°·¶Ç¶µ¹¸¿°¾Á¶´²´¯½£–£–“›”®Ÿ¡¢¥££Ÿ½¥©©¬¡›¦Ÿ½¢™£ž¢©«¡–•ž“ž‡„“ž¤ µ¬¦œ•²§™°§Ÿšªž ™•Ÿ„Ž¡š›“¥¤š˜¬±¶²ª¥ª­¬œ˜  ’Ž–©Ÿ”hcZb]NIHKOLHEDIA=PIA<GIH[ROK=HOU4BF9>HG5Cb[KCNRUWVQXTRUH@8QQPM:G@4CHQSIC;C>GVKC@O>K<06;GF>;FA56?9:?9;15D0-,0Mv\4KZ5,MnW<-=)#zbQ5CKQ9oRF<KxecWM¢š£œžÅ¬¡Ÿ¬œ®Ÿ’£ž–¥ §©«—¶°¢ª²µÄ½¿¶À»È½Êȶ¸µ´°³´·Áƶ¾°¸´¹µŸ¦¬ª«ž¥£Á¥ ©­ ¤©­¯¢¦§½µ¥±¼·¶µÃ²³·º¾±ÃÀ··­³´µ¢œ¤•‘“ ­ ˜¡¨©«¢šÃ­©ž¬­››ž™¦ ½¡¤˜««¬¦¡™šŸ’ž‰ŽW–ž¥¡ ¸ª§“˜¶£Ÿ³¡ ›¯—žŽ™”‚Ÿ—–Ž¢¤•¥®²«©¢¢¦¥••œ˜‹‘“¤Ÿ‰be[d`LIJKOFEAFK>=JB99JKN]QQI=LV\9FI=DMI8Hc\LCLPSYYVWOZ^IA=WQIK?H@5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+w`S6SZkWsHE6=ue\KNžŸ¡™žÃ§¥¢³ œ²§“«¤ ¤Ÿ­©¬»°¨¬µ±ÇÃÁ³ÂĽÆüÄʼ¯±¶­°µ¯¿Åµ¹±°ºµ¬š¨°©©š¥¡§Â­›¬°œª¢®°©¤§½·¦¶º¼®¶Ã­³³Â¿±Æ³º¶«´µ­©¡¥••”£«¡žŸš¨«°®¯»²¦ ©©™™˜“¢¤¸ ¡¤’®¯¬¥§Ÿ’¡ž•ž”š¢Ÿ§´¦§˜´œ£¯šž›®‘ž”—”š€’¡–ŽŸ¡“‹¦¬°¥§¢œ¡ž’’š“…‹’œž€bf[hfJILJSBC@IG;;G?99NMU^RSJ>O^]=HPBLLI9Nd]LELRTY[SUO\bHA?ZQAHAKB7FELKN>;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<v]^?[U^fr@8<H–weA4Ÿ¤Ÿ› Ã¨¤ª²¡£µ©•²«§¢¤²¬®©»²¬°µ´Æ¿ÄĵÀĽÈöÀȵ«µ¨°¸¬ÀÄ´·®¬¶¹¥™«±«ª˜Ÿ¦—­»µ›¨°›­Ÿ®´±§ªº²§¹³·²¸Àª·²Â¼³Å§¾®­·´©§«¡––‘¥¤¢¢—˜¤®¸­±µ¶ Ÿ¨¤™••“¤ ·¢¤¥–®²²¦ª¦¡ž›šš–˜¨žž˜¡ž¯²¢¦—®™¥¬—™ž¥‘›Ž“˜š…–Ÿ”Œœž”‹©©ª¢§ ™ž–ŒŽ™‚†–‰”Ÿydi]kjMPNNT=CANC::I@77QO]^RVQAW`\BJSHVKH:Ue]NFON[W[RPQX]GAB[PBG>NC9HGHNP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1[bZ33806p[bH05JpiVCWFŒyfC;¤¤¡¦¿¦¨¯¯ ©µª¹¯«£ª´·±°¹·¯¶¸¸Å½Ãǽ¼ÃÁÆÀ¹ÁÆÁºª¶¤­»­Áø¸ª­²»¢•­°­²–¥§ª¹ª §°ª °´²ª©¶µ¬»¬²²¹·¬¹°Âº½¾¦Âª°·¯©ª«¦˜˜ª¡¡ ‘˜ °¯³«°¹š›© ™–’—¦¡·©¥¢¢¯±´«²¨«Ÿ›  ›ž¥›¡—£³°šŸ“¥š¡©š•¢Ÿ–˜‰”˜“–—“ˆ›™”©¨§Ÿ£›—›“‡Ž™‹~–…›kimalnWPRZTACET@;;IA7:XPd^PVWDY^]MLRN^KJ>Zd^NHPN[UYPKSWZI?DXPDF>N?=IGGQPB=CFBM?:2D?77547?=95E4+75/251.-.,1>*'+=\p=>1.1e[d@1647gY`F(?8l}h[V;‰{cC=§Ÿœ¢©½¡ª°ª£±¸©¥´³«¡­µ½¯³¸¼º½¶¶À¿ÉĸÄ¿À¸Ä¾Á·¯µ¨«·²¼¿¿µ©®±·Ÿ—«­¨­–§¨Ž§»Ÿ¥­³ž«¢±°³¬©¶³µ½­¯±µ¬°µ±ÀºÄ¶«¼¯±¸«¬©¢±¥ž¤©Ÿ£—™Ÿ²ª³©ª³™§›š• ¦¤´®§¡¬¬­±§³­²©£œŸ¨£“ ˜›¨µ©—™’’Ÿ™Ÿ¡ž¬Ÿ˜˜†•˜‹š“Š–—š—¦¥£ –•—””…{’ƒŒ–flrgpr_GYfVDCMXDZ9HB6>]Qh\NY]G[^]NMRXdJJC\b`PKMNXWXPJVVWM=EUJEDAM?AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,+%2+*5K1.'__aU150=`V^8)C3YU\gK5ŒzfL@¤™ ¤¬·¤¬©¥®®¶©¯³¹¦¦°·Å·±·¾Áµ´ºÅ¾ÌŸ¿º¿ºÄ¸Á¹²µ¬ªº·ºº¾´ª®°µ˜˜§«ª«›¬««¼¬®±£ªŸ°­³®®¶±¹·©­®±§µ¯³»¼É²ªµ´±´¯®¦ ³Ÿš¨­ ¥••š™±£­Ÿ¥¯–¡¤™™’¢¥§²©¡¦±«©µ¥¯±µ¯£™­§š—ž™™¬¸£—“˜œ¡˜—”¬Ÿ”“™š–Š“’žš¥¡¡ ™–’“–{‹†{ŒŠƒ‹’knxnv|aFajYIHY[={JGE6AbTiZM\aJ[]ZRRRb`LKE_a`PLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`U`/5(C^Q\.*B/JGP[H3cYUKD™– °¨±©¬¥£®®µ©·´¸£«´·É»´»»¿¾´´·ÃÁÍǻü¶¾¿À¸¿¼±½®§º¹··Á¶«­±¸”—¦®«§£²©”¯»¤­²±§§¢²³°²°´±¸³©®«²§¸¯µ³ÃŶ¨´µ«°­©§¢¶Ÿž¦± ¤”›™”±ž§›Ÿ©©¢›•—¥¥¥·§¢±³«§±¨®°µ¬¤™ ¬¨››œ›”©¸œ”ŽŽ‹™œ¢˜—¦¡Ÿ–„’–œ˜––ˆ–—›§œ£ ’–‘‘—v„‡{…„Œnqwv|]Lel\KNc\?b{GI8GgWe[L^bMXYWTXTi]OOHa^_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANHf27'FaLV%-B.=EMQ<3rkJDC™¥®¤­­«§¤°²³ª·°¶Ÿ«µ¹É¹®Á¼Â·³²µÂÃÏÄ¿Á½´½À¿º¿¼³Ä¨©¹°¶¶¿¼¯¬³²œ §°­¥¦°¥ž²µ­«²°¬©¨´¹¬´²µ­´¬©«¨¬©¹­±°Ç¾·¤¹¯©­­¥¨­°¥££®£©œœš¯™¢£¢£¬ž£ŸŸ¡ª¥¦¹¥«´´¤©«©¬¯¶®¢£¨ª›Ÿ™š’¤´š‰‡‘¢ –”ž ”“…Ž”’›˜–•‡—’•™¦›ŸŸ’‘Ž‘w~Ž…||}‡ŠŠrtr~}~\Sdo^NZf]FD–[H;NmXa[M`aNVWVWTYg^QRLcZ[TKGOTSNGIVS\N;P^IBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3Bc;6*HdHJ+:I?3BIS,>k=HH›ªª¢©¯¤¨£²´±´µ±±¡«­¼Ëº®À»Ç±´­´ÂÃÑÅžÀ²¾Á¼¿·¼Ä§­·¬³¸¼À°«²­ ¤§­©¨¤°£ª±ª¯¬°®¯­«³º¦¶°²©²©«¦¥£­º¬ª±Â¹´«¹¨¨¨­©¨±¥©¤¢®ª¨¢ž›¢¬•¤—ž˜«¡§©¡¬¥£­¬·±± ¨¢ «®°¬Ÿ§¨©™¤˜™ §˜†ƒŽ‰‹Ÿ¡‹Œ–œ†‡• –˜•‡–““—¤œœ‹‘ŽŠˆ†|w‡…‡tsr‰vl_Y`ncQsq\K;„|F>WuX`YNc\MUVUWP\b^SONgXWVKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*35>10485(5/*,.30;),,'%234$,2-860)(1<]J0.IgDF8<B05EKX1@”[?MF•˜­§¢ª²œ©¨¯¶¬¸µ®ª¥«ª½É»°¾¸Ã¯±­³ÄÃÎÎþ¿´ÀÃĺÀ´ÉĬ¯·®²¹À¿´®®«¥§ª°©§¨±¥´­«°®­±¯³¬³º¤¸³¬¬®§« ¢ž°·«ª­º¶¤µµ¤©§¬¬ª­¡¨¦¦±²¤¦¥¡¡«–© “š ¦ž¤¢ª¤¬¢Ÿ§±·¬¬¢¤¢›©ª­©œ¢¥¤¤˜ ™–˜“‚ˆ…œ ŒŠŽŒ™‹„˜¤›’‘›Œ“’‘”¢™›™ŠŽ‹‹|†‚ƒzt€„‚~twŒ¤‡yk^`ngWe‡dN@g’LDbyWbXReUMVUUTO\]aUKNiWVVIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*49?./463)4+*,+.#4.-+&(+79*&6+<-2,&06WZ.0JgAA<<C+:JO^4D†@HHD—’¯¤£ª°—ª¨¬µ«¶±«¤«ª©¼ÀÀ¸¹³¼µ¦³¯ÄÉËÑ¿Á»¹À¿Ã¹ÁºÁÄ®±µ²³»Á¾³±®¬««¨¶ª¥­¯«¹¯¨±±®±«µª¶µ§´¶«¬¤©ª£³³¨¨¤´´ µ­¡©¨«©¬§ «¬¨¹¶©ª©©¡©Ÿ­›‘¨¡ ¤¢¦¢©œ¦´®§¥©¢£˜¤¦¦©œ¢¤£Ÿ™˜Ÿ‘Ž™Ž~‡‹†„žžˆ…‹‹ŽŽ„†•£šŽ›‘’‘’Ÿ—˜–ŒŠƒt†xuƒ{xˆoqggqx\`sˆjO]˜VHmxUdVQbOLUTUPOX[bUHPjTVTGPYUI>IHOQPxLMV=<KD?@A<@CUC9AK=5;E13;97*4:=+-341*8**+*,)*(/*&)%3;,$2)2021%/2Qc02?f=NX?C,>LT_/Jk6PE;•Ž° ¥ª­™«¤¬®³´®ª¥¯©©º¾»À±¯¸®¢¶°ÉÇÈÐÀ¾½»¼Â½ºÃÁÀ¿®²²²µ½¼Â²²³ª³¨¤µ¨¤¬³³¹¯£®¶±¯±¹ª¸®ª®¶¬«žª¬Ÿ£ ¶­¨¡ž¯³¡´ªž¨§ª¤ª¡¡¬­¨½¯¬®¬¡§§Ÿ«˜¯¢˜¢ ¨§ž§›™ª°©£Ÿ¬¢¡“¢¢£¦˜™©¥——˜Š‡•ˆ}†„„¤–…‚‚‹†ŽŽ‘„…” —ˆ‘“‘œ”–Š……xt}uxy€{tszi‚‡£ui^el‚ugˆŒ}RXp^JxsSdSQ^MMRYfNLVYeYFSiRR?BNQaQ:IHLSIqQLS;<I?;<=;@@W<<>H73CB15:93-5::)-31--6)(+-,52#2)',%.;.&1.0-14%,0Lh:48_=ad?F1CP[[+HO:VB4± ¤¦«£¦¤¬¦´³°©£°§ª¸¾À¼°¨¹ª§®°ÉÆÈѽ¿¾¹¾¿¼É¼Â¹°°´±º»¹Á³´»¬¸¬£µ¦¦«±¶¹²§§ºµ­µ¼¯¼¥­­µ«­œ©¯£Ÿ¥¬ª§œžª³¤³¨šª§©¤©£©¨©½¬´¯®©£ ®›š²£•¤›¤¥Ÿ¤šš¨«¥ž›ª¡›’› ¤˜–©©‘˜™“Š‚…}‚€ˆž†}‹†„€“›”…“¢Œ”’‹‘š‘”‡‰~qzy~|iw|zuqq}h†x„‡d`hcr…zmgy]^VBWzmTaPRYKKNqt]HZ[gYEUfPD>KNDCA9HGKS?jaIQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11&/>KH1%90%,,09/,,+6'17#-/GjI14X=fbAJ7GS`U*=;EZ?*“±™ŸŸ¨¥¤¡«¤·²²¤¨°§¬¸Á½µ°£¹¬¨¨°ÃÉÉÌÁ¶½¿µ·¿ºÈ¶Ãµ´³µ±½¸º¾·­¹µ¿­¡³¦©ª¯µ¸´ªž»»¨²¿²º ¯´¶©¬Ÿ®°¢œ¥¨©¢žœ¤±¦¯ Ÿª©¨¢ª›£¨ ­¼¨®°®¡«¢£®žž¬¦—žš¡£œŸ›š£ª¢šš¤¤•–”Ÿ¡–›–¦¬‹ž‘‘Œ‚‹€Ž{š”‰|~‹…ŽŒ‰…’˜‘‡”£‰’’‡™“ˆ|yk}vyxb{zqpqsxisjƒgdhaosŽmbjp`pA\xkV^NPQJJMSYVM]^mWDX`O^PHMDF;7HEKO<rhJK9AE;;==;;=J49B<3;G<4?18-78;2(09/,5..=-*K>*49&'.34.0+/4&,:$40BhY13S=e_DL6KWeO)<3P[=#’˜¬™Ÿ—§¤¢Ÿ¨¤¸¯®¢¯¯©«¸Âº²­Ÿ¸¯«¨´ºÇËÇ¿·Á¾¯´¾·Ä¶Ã±®¹²²Àµ»¾¸©¹·½«¤µ§§©°­¹°©šº¼¤®¿´´¡®·µ§§§°³ Ÿ¤¦§ ¥™ž­§¨ž ©®§ ¦—£©Ÿ°¸Ÿ¤±¯¡«¡¬¤›¦¦©šš›ž£•œœš©¦–›Ÿ¨’˜“˜“™•¡ªš‰‡}‡~‚||¡ŒŒˆyƒŒ„‰Œ„‡“šŽ‰•Ÿ‰‘•‚‹–Œ}„{so}qst`yxiopqojrdzlifdaf†€`[sjrMMiXZMPLJHPRPIN\_oTDXZRgOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23/:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%53=fd24M?e]FO=RZhH*?0ZY5(–¥˜œ–­ Ÿ¡¤¡·«°£´´©¨¹Å¶²® ·¬­¬°µÆÈÀ·¿Á¹°´½·¿»¿¯«½°´¿±½Ãº©»º·§¨¶¨¦ª°¬³°¦š¼·¤«»µ®Ÿ°¸¯©¦§¯±›¡¤ ££¡–œ¯¦¡Ÿ¢§¯¢ ¢“£¥¢·°¡¦±«Ÿ¬¢®˜œª¤¨ž—š¤“šœš¦ª™œœ¤••—•œŽ“—¢©¡‰Š…z„}„ŠyŽ—Š†y‚‡„ˆŒŽ„Œ“™ŒŽ–™Š–~†—‹z€zprwoot_xwdlllji„nfsikfi]ds`[kuiZI}^[XOOKHGRUF29^^mPDXVYeMIIEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<#8R=*113>D5,-'42*;+139cl84GAf[HTDU]hE.<2bU,2–£¡—”›ª¤¡¢ ·ª® º¸¦¬½Å³°¯£µ°­­¯µÄļ³¿º·°³¹¸º¸º®­¿³´¸¯¿Á¸¬½ºµ¦¢³ª¦¨²«­±¡›Àµ¤§µµ¨ž²¼ª¨¦©¯¬™£§œ£¦”˜¢²¤™Ÿ¤¨©œ¢ “¤ ¤¸¨¤§®¦ž¥ ¨’Ÿ¨¢¡ ˜› ’š›– ¡ª››™¡”‘”–™”’£¨¤‰ŠŽ…y„{„†}ŠŠ†y€„ˆˆˆ‘„”““Œ•”Ž”{ƒ—Ž‹w~{ltrllsaxthhjgfo…ghicfij`ibjg[e{c`SsT[[SKJGIOS@!*i^jLCVU^`KIHEC.:B<F<6KPD8:D357==895?:;4>8@K=>93)8><:9*6@3.E4(+,>0-N?.+-7,1195,&.5-80576`tB3CDg[KWGU`hB379eO'2ž££‘Ž£§›ž£µ­¦ª¹·§¬ÃÁ¶°¬£µ®§®¯·ÀÀ¼²Á¶±®²¶¶¸·¶¬©½³¯²±½¿¸®»¼±¥Ÿ¶«¥¤´©«®ŸžÂ«¨¥°²©¬´»ž©ª«±¥˜žª¦¤‘™¦­¢˜ž¤©¡œ¢— §¶¦¯ª¯¡ ¡” ¥Ÿ¡ ™›™œ’™”¥¬¢˜–”“•—‹˜š¨ ‘ˆ‰‹ˆy…w‚‚œˆ‹‚‰|„ˆ†…‘ƒ••Ž‘‘‘’{ƒ•…s}}fxokjlguskcgddu€beffejjdkqZ^Y]mdaNhWZ`VJGIKMRX>9_liHBTS\[IHFEA.<?9A89RG@7:B037=7692:<97:9DM=B<0*<@;A=-5B37=+*,0A*JK./*+3722(57$+7.72685\yN2>HiZLYJVbfA:3AgH%5š£ž‹¬¡˜˜ –¥³±¢±½·¡±Æ»¹±±¤¶««®©¹½»»®À²¯®­¶¯³¸³¨«¹±¯­´¶º¶°¹¾­¦žµ«  °¥«®ž¤Â ²£®°®·­µž­¯¬­¢™œ§©¤ž•›¨¥Ÿ™¥£¨š ›”œ­°¦¹¨®¢ ššž™ž£š¤—ž˜›”š ’¨–ª§š“šš‘‹•™””™©§ŽŠ‰|‚t‚Š˜…‡|‰‰„„ŠŒˆ’„“œ’’‘–Ž€Œ‚p€fynhkjgqrk\hccsafhjnlgkjgm\lluqaTbhdeZIFLMOXQQVaeT@VSYTFHFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24;6#3*)6.55465Z|]19Kj[M[KXdd@A1JeC'4’ šŽŽ°š“¡™©²°Ÿ¸À¶ ´Â»½¹±¦¶°¨®¤·¸··­»¯­ª«·ª´¹®¥³µ±®©±·¶±³µº§©Ÿ¶©ž©£ª­œ©À™­£®¯µµ­­Ÿ±­¯©¢›œ£«¨›•œ§£š©¢¤–š œ›£«ª©»Ÿ¨¤Ÿ—š™ž¡k¢–˜œq‚–›¤€u’©§ž””žˆ—™€–Š¡x†”Œƒnj~wƒql†‹†}„‹†o^c`g„—†k‹”“uw‹„~ƒg†€huifW\hsnNPjcgr„g_dfnlj^``Š„†gOKD8FTg^JGQPUUKHSaoteF[QUPFHFC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,+08>G601.*.*/568,#1'214:176Xl16Ok[N\K[fb>G1Qd=+/Œ£™‡”°›œ“¡›ª­«£½Å¯©·Â¸½½­§¶°¥«¤¸³²³±¹­ª§¬´¦°µ£¨¸¶µ¨§¬·³®´­³£ªŸ´«ž¡¤œ§§™¬»•¦¥¯²·­®¥¨®«¬¥¡Ÿœ §¦›—¡¥¥››§§“žŸ˜ž¨ª£µ¯£££›–—˜—£ˆ¡Ž’š‡¡‡”¡¥¦ªž’‘š‘ˆƒrxŽ…ˆ¡v‰i—ˆf}sx¡oˆ‡„~|¡ Ÿ™€{‡žtˆŽv›Šl‡ƒlheczlqbT†mcli˜qXjpo‡X^i[kk[ˆqnzr†h‡„Z^FM?G_MFRVVQQRWTg^MXJRROEGG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82).1<I9/01.*/(-4583%&2115>1<8Xƒu25Rk[N\L\g_=K1Wa7/(Œ¦—ƒœ«™™Ÿªª§©¿Ã®±º¼·À¿ª¥·°©¬¦²µ®¯³¶«©¥±­¥µ³œ­µ¶´¦§©³±­²¨¯Ÿ«¡²© ££š¢£œ®µ•¤¤¥¶¼¦¬§ªª¬¨¥¡ ˜ ¦£™™¦£¤˜œ¤©–”¢œ”“¤¥¦ ¶££ £˜”’—“›ˆ®˜”‰©‹—¢›…±€£¬“™”y‚Ô¨‡•Á›Çyx±¥·—d€Àœ¿y„„y„|‘Êq–¼œÅ{r¶§ºzl–±«°yhkX±®nei¼’¼nhznrØ~Sjb¶²r”uš¡ªWOWaOVNFT[XQPRŒ\W\P@\DQNEGI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22BE/.32.+/)-/186- /416A1=:Wƒw21Tk\O[M^g\>L1[]41!¦“¦©Ÿ—œž¥­²¨°Â½²µÀµ·¿Â«¦³¬¬©§¯³ª¯¶³¨¨¦µ¦§¸¯³²¶ª¥¤§±®®±¦ªž§¤±¤¡ ž—œ ž¯­•ž¡Ÿ´º¢ª¨¡­®¥¢š™¡§Ÿ—›§ Ÿ˜ž§§‘œ§›”¡¦¢ ¯¢ŸŸ£––’—‘˜…¯jjŠª~g„•‡­dpœ“™¥”q®¡¤~x»}k¡v±_j´[¥€fœ‘`f‚zfjxj©e¾rg¦Œv²j|±xt’“cmm§m[„ Ehg‡–Euœ`}h|¤§‚Y_‹«i€•xzj§7J¯[WSmc[KOX_\WV;NˆOWW/ITSIDEF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3..53/+/(.0.:5/'$203B/=;U‚v2-Vj\OYL_gY:M5_Y31‘¢•‚¬§¥ž£¥ª²·¬´½¾°¶Ä²¸»Â§©°«®©©°®¤°º¯¤¥®³£©¹©ž³²°£¥ ª­¯¬°¦§Ÿ£¢°›¢›—•—šœ­¦—›¡ž´³¡«›¢­­ žš– ¡¨œ˜ž¤ œ™¡§¤£š— Ÿ«Ÿ¦¦ŸšŸ¡–•–™…µ›µx…©™µ™w‡³›·~“•–¨”~k¦z‚†ˆ’”’w«gk±[¬{‡”tˆq†€€ˆ—xƒ‚‹—Œƒ „°vwŸqkkl|‹N¤XHcc™~ch¦`yruS’‡^P©mcq~‡€b.Q¢n[Skh`LK\dX\ZB>°xWXA#MhECDA@A19>88:84;:9<9:A:E::;6:CB8=?KNG:5:AFB@AD<FD;0201;F,0.940,.(/3,>831/2-D1<<S}n3+Xj\OXM_gW7J9aU50•Ÿ”ˆ³¦¦¡®©§³¬©»¶Â°»Â­¸·Áª¬­®®¦®²©¡¯¼ª¡§´­¤«µ¥¦²³§£¢ž¨ª²¨°¨¥žŸŸ¯–Ÿ™••–˜ž­¢šš£¨´®¡©©¨ª›ž•— ¤§šž£Ÿ› £¥£•›Ÿ˜š¢ª›¦™››¢ –’‘““œƒÕ“™¹p°Â~Ɔ|֔›»|™•¤œ¤{Ž‡¤‚¥‚z¬yV¯{‰~Ÿj¹Z¹w†ƒ|¦‚“|˜zªyœ{±mŽ„t¼…o”P¯§ÅŠQ zc`ªbsrˆm—ˆ`Sµ´È†€‰|c¤3Bv]QjhdP@XgZdaJHMlK[SOYfZCD?E?0<<59;74<;8=:<C:F:;>6:@C;6@OLH<:<DHCBCD<EF81211DC./0483+-).323971#%5*>3==Qwj6*Yi[K]O_fT7G:aQ72%›¢“˜±¨¨¥´ª¥´¨¤¼·Á°¹À±¶µ¼³µ§±°£°²¦Ÿ®¶¨›¨¹®£¯± ³´° ¤žŸ¨ª±©´©¤œžª—˜—–—•–¡«›–§­°¨£ž¬¢¨–ž—›¡¥¡˜¡¡¢¡š¢¢§›ž¡ž•™›¦ œ§”›šŸ¡˜’•‘ˆ²nhµq«‡oŽ¦r´sr¶{™—£‹Žœ¢~‘¡¥~°vƒ‘ÒÑv\®|†¤o›ª¦k†„|­}—™{±s“y³e–t„žožf”RȋZÂ\Ÿyb_­`vs‡b—ˆ^Yʝo¿uMKµSUÆdTQjcfXAOk_lhOUGI9=WR[WXHC?J<2?;5=<46>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>HI91746A>/.24252-).26,742&60;5:=Pqh9'Wi\BOT_eP5G=aM620¡œ‘¥°­¤ª»­¦´¥§¶»¼²º¿·¶µºº³¥´´¡±±¢Ÿ¬°¤˜¦º®¤±±´¸ªŸ¦¢ª¥²¨­ª¤šœš¨ž•”˜˜’’£¨ —’¥«¯¦¢–“­Ÿ¥’”¡›¤¦Ÿ”š¦¦¡š£Ÿ­š ž–›¡œ¥”œ•™¢Ÿ•™–’›…¬{w¨v£Ž‰‡©o­Š‚§ƒ˜˜¡‰’šŠ¢“™‰®…‚³\r³R®}ƒ‚¤q×}w„}Ž‡™™w¯†Š‘œˆx³ašeš‚”l’Z°XKšu˜yf`­^ww‡h˜ˆk^¯w•žxl5yÈ®²_ATo^g`EPl_pmVUM.eciSYQ:AD@L:5?91=<16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK97<46:>/04333.2..18*.32%!03767=Pke>&Vg\@>V_cN6GC`I988Ÿ” ¸°—´Á­¨²¨ª²º¸´¸¿¹·²¶¼µ¤·³Ÿ´¬ŸŸ¨«Ÿ•§¶«¨±±«®´¤›©  ¨¡¶§¦ª£™ž•¥¡”“›™’”¢¥š“¦¬®¦ •™©Ÿ¢‘¢™¨¥ •™¥¨œ¤ž­¡ ”ž› ˜™œ•—¢ “˜‘¦†©}}¥x¡Žƒªp­‹§†•Ÿ¡ˆ——ˆ£‚‘ˆ”ª|€‹yo±Z¨‚‚ˆ ytØv‡t§Ž›’¤|–Ÿ„{²^œd ~ƒ•l’\«[Z“‘hgªdr{k˜‡s]¬Z‰ ŽkneOJC¡\ZLt^bfMZa_rt_JV6Jš“YHE=HFAL35A8.;>05A78@<6=<F?:<6?=B7.HVJEAH6KIN@IK@EN::@4.;>002144+*05/7,&21($$6671<PeeA&Uf[?2U_bL7FI_C1?8¡™™¿«—´Â®«­©¥´°¸±µ¿¹º³±·¼©º´Ÿ°¤ž¥§§ž”ª±©°©µ¬«¯¡˜¡ ¦¤¤º¢£« —›‘¢ •”žš”˜ž Œ¨¯¯¦–›¨¦ŸŒ’¤—§ª§”—©§žŸ £­¤¡ž¡•¡™Ÿ ’—œ•ž¡•–«›®mr´r©ŒvŠ¦s´xs³€‘¤¢‘œ‰¤‡w¸oŒ{‹¢kk¶Z …e——i¡¢§m“r´t“˜²j…“ˆ­ku³af¢o‡’j—\­`M¡|‡‘Rs£mz~o˜‡q\¯V<œwfTon.\§ObRkeamYb\ap{cTZQ>>mp3BB@?L9!7@6.;@37C58??3;<CDBJFMIF62JTKEBI6IJP?HNCFP=<E50;<010/75,+,426/#00,,289/9N`eD'UdY>/U^aL5FM^81C8¥š›º¡œ²À®­««§·©¸¯µÀµ¼±¯¹¸ªÀµ©ª ›¦£¡’ªª¨¶£²¨®ª —œ§ ¥«¸£­›–™¥£• ›˜œŸ“”«µ¯§™”œ¬ª—Œ“¥™¤¬¢‘—ª²¤ ž§«°˜¡£™¢— ›–›—¡“œªœ”‘«™‡Ô’š»s°Ã€Ã†~Ֆ›¸x‡—Œ˜ŠŒ§ˆz£¶u}wv‚š²`ƒºyÀ|u¸bµŒ‡©}–¬©q{u¼ˆ§ ia¦Ž¯¡~Œt‡«}¾ns¼t²ƒuxŠnšˆqn¤t½]w}[ay¼kZV[jz^j`dfbmwoY[YCA@r?CG+5H"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-7A9§šž¡¼¢—±Ã°­ªª¬±§¹¯¶Ä±º²®»°®À±¬¤¢ž£¡œ›‘©¤ª²¤µ¦­¤Ÿ–šª™¦¬¸œ¢®˜•¡¥ ’œ£ž˜›•’¯¹±¬•—£§§”‘–¤œ£¬ž‘ ¨«Ÿ›Ÿ¨¢³ž¢¥Ž§¢”¡šœ—–¤˜° ’”ªž…™µ€‘Œ·•x‚“šµwmknsny„Ž‰tžÁ»½š{²¨p€t‘¸ƒ|††‹‡{Š†—|¤»¹½œuz´£tv—ut°u™žf†iµtrpw¶Œ^z}‰hƒymyb‹¬pu…Y[§jDdYSf`c]cPgfqmuBNPLD;ZL>J3<0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITBKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7LT_G'SbV8*O]]=+:VV'=;<§ž  ¿¥–³Ã´¬«§¬«©»®°Æ¯µ³®·§´¸­©¢¡¥ž ™”«¤­ª¦µ¨§Ÿ›– £ž¬¤¾¦¡«—”¢›’¢¨¢“—“—”²µ¶­˜£¤¢‹’‘¦›¥ª›–¨¤¥œš¡¨¥¦£©¡’­Ÿ—£ž—–—ž°©”›§¡Žj~iœ¦x‡s~štze‡z½¾Àºo’‚q•‡_rjZ^š‰acˆŽ•k`•cmœvb”kš•”e^`cq›ŠirŒ}†•gj~rtx}}b[wthP\nƒ|{‹kXlz‚rIJo…pMtMEW]f`L[Xgc^O[muiqQODEM;HI<L?2,2A?8/5?C<9;@;=C>RVVWYZ[\\]`aaa`\UG5DFUEJOHFPIIH;8=51:.0;:.0-76=5&"/*2,%;8-7JR_I'S`V4)P^L(3=[O'?2>¨Ÿ¨¡Á£›´º¶£­¥®§¨µ±¬È¬°³«µ£¾±²§ ¢©¢›š™¬¦®¤¥µ©¥›˜•¡›§­¨¾§©¦•”œ• š“˜¥©§‘‘—œ°²¿¬›§§¢‰“‘©š¨¤››« £™›£¦¬¢Ÿª¢š°›•¦ –•Ÿ—±¥˜¡§˜œ‘œ££™¦¢šœšš™–gm}qw’—”‘…Šµª†˜•ŠŒ˜—‡”•Š„’“‘‰‘“˜”˜—š ¢šœ”¡Ž‚z¥…lj||€t‰Šq‚xyvvŠ€{‰jstƒucw}vkp{m`c]pgMYYej_WZpznmfSOFS9OZNRO(+:JB635=@A9:C><ENSSTVWXYZ\]`bba_^^[TKCSGKNDGPLOI<:;389,2;820)6IRO8")+/2#4;*7FO[J&R^S10T^:+=8\K,<-@³ ³¢¿¢¤±²· ª¥²§¥°µªÉ«­±¥µ¦À§´¡¤¥œ£•– ª¦¬££·«Ÿ™––Ÿ—­©¥Àž«¤•’œ—ž˜“”¢Ÿ¢§“‘™¨§²Ã¯š«œªŸ––©ª›› ­˜¡›œ¢¤¯¦¡¤¨ž­˜—¦™š¡žž° œ¢¦•˜’˜“ ¡•£ž— Ž–“ŠŠŽ–­|•›‚’‚‹ª¨†˜–Š„Ÿˆ{„‡…™‡†‰•Ž›—˜ž¤–š“‘f¡³¯…‰„vzŠ|vyzogy€‰kuyˆrhszvƒˆ‚ktdyf`idbdfjYk{pij\SLPD_UF@??,4@F;45;>A;<?>>HNNOPSUVVXZ\_aca_^^]^]XVJKLBIOMRJ;<:786/2964.(&$-1./)+*7%+<(6CMMD/T]Q05M[17E4\G5<,@´ ¹¯¾¬«®²² ª¦±­¢¬³°Å°ª¬£³®¼¤´œŸ¥¢¡™—¨¥©¦¤¥³µž•”™™°¦®¾ «£‘žš™”‘•¡œ–¨œ„ž©«¢³È³Ÿª£ª—–—š§¨š£«“žŸ ª®©¥£«¡­›Ÿ ¡™¥žœž°¤˜Ÿ¨“˜—œ‘¤™˜¨š—fƒ’|e~™cylhkz‘¤«keš˜~g…Šeeih{Ž¡ŽkhŒ—‘¢wkj‹˜£Ÿ™slnz„Œ‡zXe^…^lŠ‰€v\hsww‘€‡‚nx‚x€smyƒtwˆˆŽƒ{j†Y^ktd]s‰ij|qlc]QMWJdX@J4=F7?FD71<=?AD<<DGHHILNPRRTW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%/*+'6*$;'/AJ[J/7ZO6)EY/DO1YC;?.=¥Ÿº¼¹¯¬³±ª¥¨­®°¦®­°½±©§¤­¯°Ÿ­—Ÿ£¡š™§«œ­£¥¨©²®ž•£¢¯¦¶¹¥®£Žš¡™“’› ™˜¤•{¥¬¢¨³Ã·¤¡§®Ÿž•ž£ž£›¢©©’ž¡ž ª¯ª«£ªŸ¨›¦Ÿ¨¡¬–¡›¥°¤—œª•¡ž›’¥—žª˜ž~¾ƒ‡r´r„†­hx¹Ä¸q“¢£{¦˜™sª‚|ËÀÀ»q‹¢‡‚Ÿ|•˜‰žÀ½‚–žÂÁ{{’šÃÀ}k¥±oŒ€oÊz›w‘ƒŽvzyqz‡qx…Œ“ymw“bf_xd_e‚c^thmdbXLVIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^__`_^^^^___]\SMPGUNA??=6468276*&%#)*&.+*)109*#>I[L*#BP/#F[3PY/UAB;/8–£¸Ãµ°¯À©¨”£¯©°®­¦²µ¯ª¥¦¦°«Ÿ«˜š¢Ÿœ›ª§¢œ¬£¥¨¥¤´¤¢“¦­¬·³§¯¢’‘š¥’‘ ¡—›Ÿœ‡¦«¤«­¿À± ©¯©—’Ÿ¢™¡¢©£“ ¡ž­®¨¬¦£¢§ ¥¥ž­©‘¤›©­ªœªœ¬¡–—¥•¡£—œΔxz¤y•–›_®^Ž§¢ |§•›t«ƒ€¯^cªz§‡… t—’ˆ³c‚«†¡Ž³j„®t}–‡¸a‚­Y£Ínu{Ú{™p~ˆ“v~e{ˆvvk}ˆn~…‘’~m`qkpg`_yd\qhjdf`RTRW^KOC5AHED8>6;@?A;=7@>??BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5578164('$!',&&/(&+360$7;SL+,-J0';\;L-!P@F4.1­ÂÀ¿µ´°·—ž‘¤ª¨­³«¦²¬­¬¤«§°ª §›™¥—œ¢¯Ÿ ž¨§£¦¡ž°¬›ž•§®­±ª¨¬ ”’›Ÿ¥“Ÿ¥—ž¨£ž­¤ª°¨ÀƳ¨©±®–’œ¢—ž¨ªŸ• Ÿœ®¯§ª©›§§¤¡«’¬´–¦¢ª©£§¥¡°¡“š§š š””‘— q…Œ—t„¨‡q±|q¬~¡ž¥žw«‚}­œr­~«‡†Ÿv˜’z|—~ªˆ¢Œ‘‹~«{‰“Ÿ€{­VœÄzo’Á}•mupŒmeve†oawnroŠ‹’ƒm‘dotup`gme_oiinfcWS]aYRSC9II@D<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;91478452&# 1' 1' '45-&7=WJ-<'>1)3V@F!G:C1.+°ÔÆƲ´Ÿ£Ž££¡¬¯¶®¨°§©ª¨®««§¢¤™¢•Ÿ¦«Ÿ¡¥ ¨¨¢Ÿ°¬—š–¨§¯¬¨§©ž—”š£¢’”¡­›¦£¯¬£«´ªºÍ±­¦®«–”œ¢™ž¬¬– ™ž©±©©©›«©£¢¬›¯±¢¨¬®¥˜¦ª©©±¢’—£¥š”’„¤j¤u‰z©tz²p‚¥‰™Œqˆ š‡¤``R¬„®ƒ›v®¦††Ÿz™–†{f€£‰¤™†£}©~”‡®^|©U¢’z¢Ÿ€{ïŌs¯³³¹qb©¯Âth˜mš“omyxwolfeeqpf|ib]W`iXXUMMQLCCAB;C@@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799674,&$" ('"+-"$.!3-&@DWH,G+56*1PKL# A9D4,'ÃÉÖÕÀ¡™«¨¡¯¢ž°´°¯©¬£¨¦ªª«©¤¦ ›¤ž¥§¦£œ¬š¢¬¡¤Ÿ¯¢š’ª¤µ°® ©›–”§£š¢¨Ÿ ¦œ±¦£§±¬¶È²µª¬©•‘œ¢™Ÿ¤³š ”œŸ§««£®š¬©¢¡ª£³­¢ª³±¡šª¨®¯¶£“–£§˜›‘|ªlž„‡u«y|°o‚¤‹‰Ÿ–•Ÿ”Ò¸´¸É€²__”©ƒ¤ˆ‡ y˜•šxªÉt™£•§©’›Œ›‰šÆÆxe¡‚¥sŸŽ‚}¯^pµc±uK£†m§G‚“dž’|p—“p{u}{n[ejrqfj_aYdm\^YIMLKEDAB>A<B?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75685/)(%&%$&),4ENPPMFKJVF*L0/>-5OTQ;<F2,$§¤Áƹ­©²­¬¥¢œ²¹¬ª¡¦›¨¦ª¬©¦ ¦¥˜«£Ÿ®«¦ ¬šž©¥§¶Ÿ¢—“¨ª¶²¬›¦œ •¥­‘™œ¦¢ ª¦®¡£§©°´Â±³ª­¨“‰—œ¤š ¢®¦˜¡•˜œ¥¦«š¯­¨¦ž¬£·¬¡²¹¯›¯§³³³¥”˜§£™ŸŽ‚NxšŸzƒ£}ƒ¤„‡§Ÿœž“„¸{|y¹‚~Ìƶx›¡‘‹Ÿ}š––Švž˜Š¤˜£¨~°…œ…ž„¬}™”a¥l£p…}—ƒr¬`¤sq€š`¼}RUuŽ’¤—{}“’‹uzs…q\mnwrjoZd_hncd]KMQTBIHFI:9K>B108866877-*5==?BDGILNPTVXYZ[\__^]__\ZZZYUSOH@772.,*.+*'&?QTVWWWYXXWUOUF<E3:P[T6?H,- ‹‡™©«¤«¸«¯ œ¡¬³³¦Ÿ •¥®­®ª§¦¦š£§¡²®¢©¦² ™©¤”£¶¢¢•—¢©´¸¤œ¢£“¡±™žœ¦¤¡¢¯®¤¨¡¶²Ã±®©­©‘‡œ§œ¢¢œ¥—ž˜™™¥¤¨š®¡®¥¦—°¥¼­¡··­µ²¸°³§˜ž¯¡£ž…ÑµÃ·y‡Ž…‘“¦x”¢wŒ ’„¥Šqª†„´nrj™£›•ŠŸ|˜™†‡s¯‚¥›¢¦‹“‰”›mp²\¥s“zœl™{™}n©a¢qqŸbs²¸hx”¦˜~Œ“‹x}yŽ‚mixixsnt]ddnmfg`J[XX<HG@U3@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^``][ZZXURRQF:2230/++(@QRTUTSTVWWXXWUVVTQOQ[U%!2AH$)%“sŠ­¿¿»ºµž—¨¤­µ¡£™•£©§®ª«™¥¢Ÿ¥  µ¦¢©§°£”¬£¥­£ššª´´¤¤©’”—®  ¦£œ§œ´š¡ª£¶«Ã¯©«©¡Œ„Žœ¡ ¥¡•ššœ˜š™¦¤¦˜«§­¢¤›­§¾¬•½°¬Ÿ¢°³¹«´§›©±¤§˜z¨}|°wŠ¤¥ˆœm²o¡‡­|¡ƒ¨•˜€¬ˆ…®…Ÿ”© ¡–†Ÿ€™•€{’~«€š–Šªx ‰“’€y¯]£|¦§d€|—tk®]¥kq…™]`[Œ m•’§™‚”—Œ{{ƒ—klb}tm€z`geqnhghCZa[=KT2U8BBC7$$3+''3, /6674359@CFIKMNQSSSVZ]_a`aaa]][ZXSPONI7052.*,ATVVVUTUUUUTTUTSTVVWXVUUQHFIJ#((½’š„©Æ¶Á´Ÿš¬ ®¸¥¤Ž›¤£ ¯¯ªŸ¤Ÿ­™ž¸ £« ¯ªš®¡ª©¤–‰›®°¬§Ÿ§›­˜˜¬¢¡¥¡™¤œ­˜Ÿ¨¦¶©À¯¥©£ž‹€›šŸ¦’•šš”šš¥£¤š¨¬¬£¤Ÿª¨¾¤—쪢¡¬²º«®§ ³®¨©˜v¯~‹œ…‡|º®Š˜e°Œe•­}¡ƒ¦•š¬Š„°…¥™¤¡¡… [lj³`­{{‚€±lgn™—Œˆ°[}´[¤ƒkÈ¢eŸ€{¼YvµZ²}R¯€z¬X€¡m˜¨›‹˜‘––{yŽ~ds~bƒwt€|ajfqmfeeOUd\BT^>I(>9=4!"-%2. *1/045799<ACFHJLNPPRTWZ^`_`ab^_\[XUPNJGC553//@UZXWWWXXWWXWVWWWWXWWXYZZ[\XWWGB;ҟ³²·½»´Â³£›¬¦¥¶¨¡‹š Ÿ³³©ž£ µ˜ ³¨ª«ž¯®Ÿ«›•¯¨¢Žˆ›Ž¯¬©§¢§™®“™¨š¢¥Ÿ™£¢¥™Ÿ£©²¨¼¯¥¨œŽ}‹›•  ™’š›’™—¨ž¡™¨®§¦¦£¥©»Ÿ Æ§¥©¡«´¶­®¦ž»­¬¬•€©’£¯›€‡¤—˜€¸ÃºƒŽ“„§–œ‚¬Š‚¯ˆ¦››¥ª~սªb£¿½}~£‚ƒ×º¸µ…”“ƒž½¾„j£o«„mz²°Çƒj«°½¬xw¢¾»t€–Ž¦œ‘—œy‚‘›zc}{dŒfy‚{`kekjbPb[Sj\@TaBN)=:4/$%2 $(0496677;>ADFGJKMNNQTW]a\__a^`[\YTQMIC?<A?5=SYXXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ¼•³´±¿¹²½²¢®¦¥³¦ž‹˜¥¾©·±¨¡¿¦¦²œž±œ¹¨ž­¯¦§•”°¬—Œƒ›‘®¦£­¡¤œª ˜‹£’§ž§œš ¨¢˜ž ¬­ª¹®¨£š–’{‡™‘¦›’Ž‘˜˜˜“¨™ ˜©©¡ª§¡£«»ž©Å£ ¯£«³µ«¯© º§®®šsuª¤·†e‰ pg­Šmow¤™Ÿu®™•p‹q•¨£›—®¤rmmmeŠxom‚™q€yiqig‰–•˜qhi„†gp†d]‰cjoY]g~w¦`bqŽ‘ofd€’Ž¢˜˜™‘–ž|‡Ž•vf‡xhjy~ydlcflbKeXJlY:QeER'K:+# #,)-2.5:457:<?ABDEHKLMOQSV]WZ\``a]][TPLHD=:AB7MXZZYYZYXXYXWWVWY]^^]\\\]^]^][[UW^¨•­³ªº¹²³ª©¡®ž¤²©˜’½²ÄȾ¶ªžÀ«¬£¡§¬Ÿº£¤­¬­¦Ž–®©Œ…•—­ž¦ª¢Ÿ££ ‘Œ¤’§™¨™–£© –œ¥¦§¯º«¬š›’’{„—¥˜‘‘˜”˜•§”Ÿ˜©£›±§ž£¬ºŸ°Á§¤³¦¬±²«­«§¸£­·–Š¡¨¥¶‰–¢˜‡©š”“ª³™›£« ±–¡¡ ¢œ ¤¡•«¦Œ’’Œ‡’œœ”š“˜•†¤š—•‹“’Š†„~gŠt‚vt‡Œq§m{”‘”“”¡–™—¢‚ˆ”riwp‹wv|zjlddocU`Y@i[HcaOZ+F=+&!740.!%2(*699469;>?ABDFJKKMOPQXTVY^_ac]^UQJED>9=@ASX[\YWXXXXXYXXZZ[\^__`^^^__```_YY`¦–©ª¥µ·®®¢°¤­  µ±Ž«Æ½Äº¸ª¢¥›¦ž±©£¶§©µ§¨‘˜¬¢‹ˆ‰œ¨–¬¤¡™§žž“•£—¨š¨™”¦¡£›¨™¡µº¨«™š|”‹ ”Š”‘•“—¥Ÿšª œ¶£§¬·§¯Á®£·¦¯¯°­©©²¸ ®¼™‘¦£¦¶¢’¦Ÿ©Ÿ’Ÿ£¬¯š¡£±¨¯—£ œ£©žžœ–«œ’™¡›”–ª™™™–•ž‘‰ •”…’ŒŒ”Š€~fŒ†u†vyˆƒsœj†””‘Š}Œ–’’˜“¡“ž—¢„ˆ˜‡zr–szŠq{jnd_pi`[`ZmcP`dP[:GGD=2==7.*&+)&&406658:==?AACHJGJKLMSSSUZ``i`eVPJACB:9EMV[^^[Z\[[[\]]__]^_`aacaaa`bbbdb\[c—•¤¨£°³¬®£©§­ ¨µª¦´»¯¬¬¢£šz¢±¤¥°©–›¹§£”™ªœŽ†Š‰œ£®Ÿ£–¨ ¡’—˜›¯‹ª–¨™§Œ™¨ž¹¶¤¥™›‰y‚“‹š“‰•’”‘–¢Œžž©žŸ¸¤€„¯µ¢°¯t¤¾£² xz ª±»”u¬¤ž‰€ª~d\bv Ž¤ž„—~n“³œ£§®ª£eŸ“sy™—p€˜¨—l¢¨Šeœ¥œ‘—˜–‹‘›‘†š•‚’‡ŽŽ’‰…wk‡v†q|†€€ai‡Š”’‹[v•‘ghŽr{¦™™ey™‡‚x˜j„Š‚nykpe`vokkh\febboS\>NNNRG=@TB91/&4:316678<;>@ABFHBFFIKMTTUY\_hfgWQJ<DG;8UR[`ab`^`_`aa_\]___aabcdabaaedchd^]f›•¦£¡°±¬«©¥¨­£§­¤’•«¶°²¦šª§«—sŒ°Ÿ¨«§“—¹  œ¤‘ˆˆ›ž«š£•§¢žŽ—‘ž…u®ˆ¦š¨‘—¤ˆœº´¨ ™˜‹‰uw“Œ•’‰“‘”Œ“ Ž› §™œ³–€Œœµ³Œ’¼§¡~§¢z¢®·Ž¦žƒ‹…±©¯ŒŠ–£šy‹¬†œ¢§©§‡•…˜w¥›z‡›—¦‚{œ±zŠ… —™”˜–––„™™cy‡„’Šƒmp‡y€q€…†t†„•’x–h“t št}™„¡‡˜~’‹ƒƒ™kŽ…kx{qpgdwnilj[ekjes\^ITLQ@E5.YTU6)!09=>643568;:=>>@DH?IEJKGSXZY[aahfYQH9EL;>bV^bded`aa`bb_]`aabbbcfgcba`edcgcaahœ—£Ÿ¦®®«¨¬ ¨°¦§©¥™”®Ç¾°¡–¦©µžƒ¬œ§¢ ¾ž™Ÿš }†™—ˆ«¢–Ÿ ‘“‰†€‘¨Ž‡¢œ£“—ž†žº²§ž›’Ž…puˆ“‰“›‹‘ž‘—¡¤–ž¬ˆŸ´‰´š­‹Ê‡ª®ˆ·…°‚°®ƒ©¦™|¨r{wœ§–h•¤y´‹Ÿž¦¨’™Â«ˆ˜¡qž€™¤}—…•±€¡|¡” ˜–€Ž“›Š—‘‹|…“†•“‰ƒms‘…zr†„|„t…‚—Åf€©‡£kžƒ¢šƒš€ŒŽ…Š™p“…hwt{vghupggl^colgmXhG]QL2E46M`c7&3<DGD:64658;8>==>BL?NIJLCPZ]\Wb^jl\QE=KM@JdY]cfhgbbbbdc`_babcccdiicbbbecafcbbi”—¢Ÿ°¨©¨¥« ¤¹°ª«¦š” ¤¥«£–¥ª·£¯¡§œ¥ž‰”½š“¡‘y„––‘‡«™››™¡…Œw›œ ‘ˆž¤›•™˜†¢¹®¤™œŒŒbmŠ’ŒŒ˜‹‘žŽ” ¡™¡¨~¡§‡­ –®ž‘† ª®†¤ªšŒš~¢v€™”k‚¬uM«x‡‘›¨§€ª«}ƒ¡{z§iž’kg—†—¶‰ž}n`dYƒ–Œ{dhŠr™}y•l]{—m_Sp„\_lyƒ`Ye‚}„˜q§ªkƒ£nr¥pŸ„ŸjeŸl[nŠ|fZ_ƒbWPovemtqjjo^jomljXiO]XE9A4GC^k4,ICQMN=84859;6@;;>BO>QRLMBJ\]_W^_cv`MD:MOMTb\\ffiibbdbddbab`cdcabikdbddgdbgeach—– ¹¡ª£¦¬’¡¶¼«®¢™— ¢¦­­¡®µ¢¨’¡  ¦œ™Ž˜´™‹žŒ•Œu”’Š¦–•˜žž’…†¬¤‡œ‘Š˜©˜™š’‡¥±§¢•šˆ‰€inˆ‡Š‰‹’‹’¡‹”ž œ¢¥“£¡” wœ–§ƒ¡§†©¬„¥yŠ}„š}¢pr“ˆ–{žŒym‡œŒ™›¨š‡|‚¢sv¦fž~v¤_˜z}’s¢n˜·´ºt’‡‚µ¨dÆ¸{p•·‹q€›¤cs¬«`}j³~n}‡ƒŽ‚‹—q€£ls¤sž„€¤`™³–q|—Ÿ´ts[ž²ƒjbotuqhoXklrsf]i^bKD=D5QAYq3=SG_JR=<395::6D;;@IP?TMNQ@E_^[ZW``|dHC8LWUVbaZffkkbbeadc`ab`dd_`cknccddhdbgfchh”–•£¸™«œ“ ¤¸µ®­ ›¢œ££¦­œ›±­¬“—¡™¡¤™š”ž«›‹‰’x‹†p€–Š “”—}‰Ž¨ ‡˜Š‘¢“›šŒ‹¨¨¥ž–‡„~k{‡~}ƒ‹‰” ‚–ž  Ÿ‹‰wœ˜¢Œ r¢‹ˆ©ˆœ¦–§ª~®Œ}z ™z£“xt–ˆœ}– ‡›Ž™›¦†¢d¡|ˆ–›lžh›nš™{€Š§}rht«ƒƒtªg”š]›…v„hªj€¸f\¨pœa•Œ^§vu‰Šžhšu‡“’˜ŽŸnšm§™]¨~x»k~ª[Ž„]´g\nqzxki[qjxyc`fXbAPEN7VBRn4KZZ_NZC@151;;7H?:CGT?YRY]>Db^V`Qac}iEB9N[]XdfXfgnmbbe_aa__``ec^bdoq_deekecihgki•œ‰ªµ›§‰c”›¬º²°¬¦œœ¨Ÿž®›ž°¨¬—¤š¡Ÿ˜–– £™†‰jˆ€r{—ˆ‹––„‘”˜zŠ„–¤Š”…‹‘œœ‰¨£ ™‹‘Š€€i‡x–‹{ˆŽŽˆ–š”£Ÿ ¢“˜rhŸŠŸŒq’Œ©ˆ™Ÿ£§Ÿ§|°­£¢¸—w£³¢¤€ˆ”y{«š¢Ž›—‰—q¡|…¯µ}kš‘¡x~˜´££«¨„™|›}š~tªZ]o{–‹xžbL~zz…cy—BMŸY¢jq|Žm‰„™u›y‡‰±³›“§unr}”o™sj¤]•vHec`sq~~ne`lhv|debR^W]TV@YEQgDSW[bX^ID=B8?B:IE8LDWAVQ[VDFb\Z`K`m~qEC<U_bZejVghmobff^aa\]^ahb_edvl^egfkdflihki“±­™„T_ §³¹³³©š¢Œœ«œœ©”¡«¤¡¨Ÿžš™•˜ –ˆ‡‰w…ny•…›‹|‘“–ˆr€‰“¡œs‘ˆ˜”Ÿš„Ž©œš”Š‹Š|ƒl„…q ‹x…ˆ‡’™•|“£¡Ÿ£ˆ®†}µ„Žž{¥–z©–Š œ|§hvm~™t¡sq|ž†™p“ƒ®}¤ƒ¦žš£o^¨gu£co¥aœÓ|z™xrsc¢…~£s£uk³‹`‚˜‰sª²¨¼wƒm~¾¦©´^œn}q—os¢r]£gt¦ah¦m›Ô™|„›oxz—k›{w—rm©¤g`eyp€„kgfdmuxg`cT[fQQbIWIT_WS[ej\dPECKMJKBJE8P?PMWSXORR`feiRcwywIFEc]dZhiTihjocjg`c`\]]_hbahe|d^dgdkdjmghlh—›€±«T\K~©¯±´°³£œ™…™¨  £¤¨ ˜©Š™˜˜“™“’ ˜Žˆ†{p}„h}ƒ”šw‘Ž‰o†“’l—”}ˆ‘‘£•ƒŽªš”’‹…‰yƒv‡€n‚Ÿ†x€“†ˆ™¢—z“¢¤š ‰³¡¢¶‹z¬§¤®¥p©€š†œ’|¤€¢™†˜rž„£­®Š—Œ€Œ¤–ƒ®¢•vµµµÉ¡s”ŠŸ`—©my•†Ÿšu¡‡w ~‘–Š€oLf£’pš‡r¤{ytaƒ‚l~ kqd`œrt—i{i³µ´Æ¦s˜~{j››«uƒšltw—išzu˜rPD}³^jvky‡fjgbttqnV^TYhOQhIULYSU]hknVgWMJAJMKHJNAQJPdcimetrs~y{nu‰{{TPOl^h[kiRjhilglgce_\]\^ibdhk{_]dhcjfomeile¡œ‰°§„f?”¡²«¯¯¶¢¢€—©¢¢¥Œ¥§¦‚š—–—œ“Žˆƒyjy†eƒŒ— yuˆŒi„…’ƒŒ…zŒŠ•¥’ƒ—©—Œ‘‹‰z€}‹xp¡‡y•‡‰– –”¥¨œ––„gnxœl¢d|q¥w›˜pg§—Œ{¥zŸ–ƒ—ržv‰”–¹nŠ¢b}™¢•ˆmri«ju mn¦`›i‹h–‡š•u¢€}š`‹…Œtoˆbh ež~išuocfˆ‚nr¢Z_[c¡n]‰Œo{srd¥mw¢dg§h˜s‹˜n¡oSˆo _e§T‹]T˜mmskr‚lphkxskoRXWVfYRmIXO]IXihsjYkVQREV\LXRaThj^wuz|p||rƒ{rv€„v^QrbgbpgPjhhklngdg_]^]`kcjivu]\cicjjslfkmcœ¥™¦zetm‹§®¤©°±¦Ÿ‹€—«ž¥Œ¢¡š¢¢€–˜“š‹˜ŽŠ{‡q€ˆh‹‹|˜›stŠ}|d‚‡•ŠŠ•™‚|ˆ†–§¢¬…Š‚Š}€€sh¦„}†”‰˜ Žˆ’ª§‰¦x–œ~¥‰–Œ²˜ž‚¯—Ÿ¥x•ˆz©t¥„šn¤¢Œ’„Œƒ»n}¥¯‚††‡“–œŸ|¥zq¨• –gž~o«c–Š•’w¨l©¢‰u‡‚w«‘¦ˆk‘°kv³Œ©kŠ†nmŸž’•a«‹ªv€Œ¦ŸwŸ}…¥• iš‡v¬gž­Œ·sw¾¤“Yƒ¦«aurtp|tqbj~nhmSV[Uaa\kM]R]I]mmv`[qY[`Zgsenoqcqt`wz~yryƒs„€{{Œ‚€vbxdcmsdRlgholrifia_^\bkbmlzo\\bibljwmglnb•¦ª€ž¤–©ª¨§®¤™‰ƒ˜«šž¤‰š¥©…ŒšŽ†œ‘…’Œt†zˆ„o„~˜“tt†r’ƒm‹’‡†”|{…—¥¥¦ŽŽ‰…•v‚‡’ol‹©ƒŒ”Ž‰œŸ‰“«£ €u”—ˆ~y”®£›q…y‹„{r¦Œq}}z—–›„Žx{~~‡”•“Šv˜Ÿ ƒz}‰lŒ…[yxqyphn~’‰qt‚”“q…ƒ‚e_‹wus”uoynn‡m„†^wixf‚†Ž©›~t|—j‰ˆo€v}†vmlgŒsy{˜x„[kXyhnwrqoxxo]l†nigVZ`W\ekcVaU_Q_pxylkvejkjv|qrtsaoubs{xuy‚u€€€x‹…ƒ}{mldxn^Wnghukxjijd\`ZcjelpunZ[bkdllymhloaŽ”¹©§‹¡¢š¦¤™¤œ«¢¡„„˜¬’ ‰š¦›©˜ƒ›Š~–“‡ŽŠ‰rƒ|}~…{—Žtrƒp–…{}’‹††…x~†˜£{§¡‹†…–ƒ†Ž—vr…ª†Ž’œˆžžˆŒ›¨  «ƒ‰Ž”š~~‰–­¨“¦wo‘ƒz’o~¨…p}•qkp|ŸŒ“ŽŒhm]ƒ‹Œ››žŽs•‹ˆqtk‚vs€Yrn‡‘}~Œj]jd{…ƒˆ€_ix{›{‚‹‚v†‚hy‹‡kaqrƒw_sŒ‚‰§•†fŒƒnw‹„q†zoegdzƒz–[\jgnv[{xwunss‚f\mŠklbYY^ZXlr\_aZ^]ft~{uotckkj{|r{xtdmtgl{~vz|{zz~o†Š„{}s~ysiT\qiluougkhd]aXkhkjqrmW[enlgsyohjm`‹Œª±¢£¡šžž—ž™¨£¢~ƒ˜­Ÿ”‡›¢‘¥•{˜„|’™‰ˆ†‡Šs}€‹v…‹„–Šqo€r˜†„~’„ƒ†Šz€ƒ‹›Ÿ‚¦¡‡xŽ˜‰•‹‹œ—„ƒz­‚‘˜™”Šž‡ˆ¡« ¢¢£‹ˆ“›œ£™–ª¡§¦ ’›‡–Ž{xŽŽ„§~’‘’“œ±¦›•ž²“˜„¥ŒŒ•›Ÿ‰›‚‰‘Šk|vwe‚†Š{‰„‡‹ˆˆ€…„w|yuš¡ˆ†ŠŸ‹…”~Œ€vpt†„xˆ‡‹¦„…ˆƒŒ}ˆ‹‰vl‚„|y™jrhatŠp}zwvovt]^o†hn_^Z\]ShrVc\\alhu||sopdkji{mxqioplf€{r‚€x}€„zmƒŒ†|zx|}zƒyNdvksmpzdkebb`[tfpfrrmU]ltmiyzqgikeŒˆºŸ–¢¡˜•™˜”™¤ ž{š«Žž…Ÿ‹ž–}y”ƒ{Ž™‰†„„†nx€€rˆ~‰”„mk~z—†„ƒ€†„†|‡ƒ›’‡ªŸƒrŠ†“’Œ‘}{ª„’˜–œ—††›§ ¢š†ƒ‘š™™š¦ ¦–€Šv|‡Ž„¥{|Ž‘†˜ª¡ž“Ž«Ž‘€žŒ‰“šž‚Ž—~†‚ox…qt`‚†u‹—€ƒ‚†„~…ƒ”nxut’¡‹Œ…š…„t€‰||rr{ˆ„{y‹Ž„“§†„‚„ŠŠŠw†ˆ‰‹|ok~€{nhlmg^zh|{vtvu{w\`p}nu`cZ]^QgmSe[^akivz~qlldkjg€ls€lltoxn„yn‡€v‚€}„vq‚ˆ~{{|{‚Š`i{juhi‚djc`i\duhobumlTcqyepzzreimm‹ŠŸ·š¡£Ÿ’‘–—‹šŸŸž{xž¦›Š†¤”‹˜™yz…|‰‘ƒŒ‚‚m|xs…}‹‘}kh}—ˆˆŽ|~†„‡|€››‘ˆ§p‹‹Œ“‡¡¡Š…|¨‘ˆ’—“–“xŒ£¡¡ž–š€š˜“Œ›£¡¤š—‘›~„xƒ‡ €}ŒŒ|˜¤ ¡“™§›‘‰’—›}’’~†ut‚pv`}†rŠ•|ˆ‹rŒ‚…†ŽhwqxŒ˜’—~ˆ‹r†|}px{‹„zz‘ƒ–¦“‹†‘|††‡…v‚„‰ˆzer{yzqljf^~sh|uvt|s€j^`tvpxdcY_^SkhTdY_ahjvxqfkclhe€jm~hnqk}w†zkŒs}tv‚†~|{}jrƒnsia‡hlb_qVtomn`xhmWjtvcu{{rbjny‰Ÿ²’¥¥œŽ˜†œ ›œ|v¤ —Œ¢Šˆš–x{†‡~ƒ‰‰‚€q{tvƒ…~Š‘xgc}†—Š‚Šx}€Œƒy–€•—–– ›~oŒ‚‘”†¦›ˆ‰„¦•…“‹–—“’v‘ž¡¡˜”—z~Ž˜—Ž–›¤˜’”›y…‚w„—~‰Œs—¢ž¢“™Ž¢ŒŒƒ—˜ƒ’–™~˜|ˆvq}nzd€|Š…p†“‚l‡‚€‰„euo|‡’—}“x‹‰{†|{q~w‰…y„Š‹˜¢•„wˆ„ƒ‚w|‚‰†v_xw}t~xgldaijwstu}q|bcasnusmaZa^[kdRbX`aikvy†qcjcmeh|ƒlhthloh|‚ym†q€ƒƒt|ƒŒ~z‚ƒ~|mv‰ttmeŠljacuV„iqn`yglbjvpfy|zq`rl†…œ­—¦¨ž—‡†Ÿ“—˜}xªœŠ™z—œ‹Œ˜y{‹}|ƒ{€‚€xtxzs}€„‰‹€d^}‹•‡…‡t}~Š}—„—“–Œ£¡˜r‡{“’Š§ŒŽŠ“¡’„’”—‘‹˜ š’‘t’”‰ž§˜˜•–sŽŠk…˜™z‡ˆ‰o—š£“•ŠŸŒ‡‚’œ’’•†™ˆ|‰‰zqykul{}‹~n…’‚”wo‚ƒ}~Šdrj{€–—„t‰ƒx‡~ux€}†€|ƒŒ…”¤y…‚t‰‡}€tvˆ„n`{uzq}oaocd{bnovsxwstav_oluno\\_^^j^O]Xcahmt{ˆk_jejchw‡mflhilh€|zwo‡sƒ„}s†‰z‚}z„}}Žrz‹xxnl‡kh_iqc‡hqoewhnlayhk}{xpawm‹™šª ¤¨ŠŠ‘†ŠžŠ•—}w®˜Œ—~ž“‘–”ˆw~{Š}{€vx€pts{o†}€Š|a\~‘†ƒ„sz€†z‘‡’‘›’¥›•‚~|Ž‹’¤‰ŽŠ˜›†‘˜“–Ž‰‰Œ““Œnƒ‘‰ž™¢¡—–Š—‘nˆ™„f†™Ž“z‰…Šp–š”¢’’‰‹šŒ‚‘ž|’’‹™Ž{Š„‡tsukqnt{‹tn…Ž’qt€{‚ˆ|dqly}™”}„ˆt‹€sˆyo€}€†|…Œˆ…•¨{ˆ}~‹…x~qp€…ƒchxtup|b^p`kt^qjzxxkspex]mlsmsYZ^`bjZPWXecgqq‡f]ihgbgqŽodigejh€zwtnŽ…t‚{u‚‰…w…|x„…z€‰w‹{zryƒjk_pht€kromqgole|cn€yvqlwwŠ¢˜¢¨¡¦›‡ŒŠœ†“œuª”’Ž‡ Œ–“€t|v…wxrs{…kroznŠv€‡nq[Y~‘ˆ€€vu€€ †Š’œ—¡”˜xŠ‰žŠ†’˜–…‰•™–Œ‹ŽŠŽƒmˆŠ‘‰œ–¡›˜•†˜ˆi„£‚f…Š‘~‹ƒ‹w“˜’Ÿ’‘‰‰•Ž~—|‘š’}Š‚nvplmop{…isƒŽ—Špwt‚‰‚xfsov™Ž|‰„z”‘yvˆtp‰{…Œz‹†ƒ‰œ£ˆ|„w‚‹xxokƒ]rsqppxZ^p`pj^oi|zpmmjlv`pojrmZXaabnXQSZfgcup„‚b]jmdbfk’m`ff_hjuqrp‹€u‚€xu€‹€x…w‡†wƒ…{†Œ{vŠjqc|b†|oqltjholvw_qy{tut€‚~¤•š­Ÿ§–…ƒ—”ƒŸu‹Ÿ”“†‹›Œ•‹zrxt‚pr…tquˆlolumˆwƒ~€mnUQ«”‡‚x€vr‚y ‚‘“’˜œ’šx’{ƒ“¤š“Ž‰•™“…‡—™Œ”Œ‰ˆž…Š|rŠ…‰ŽˆœšŸ›–”€”h…œ‡g† ˆ’„‘ƒ‰qƒ‘—›ŽŒx{’zŽ‹Œ‘–Œ|ˆ|€kvjnkklzay~Ž•vz€wƒ|ygtlt‡•‹ˆ†{”qz„pvŒz‰Œ{‰}‚Œ‘Ÿ…}|x‚Œ}wqjl‚y_womlrsV^obr`_lnypgpffsthqkawe]Vfa`rSPN\fe]ypˆ|_]hrbbef’i_hd[gp~pkpsŠ}v|…€tuŒy{†€xˆƒs†…~ŒŒ„{y•wfrjƒ`ˆ~ookz`jntt_t}y†xts…|x ™°œ¥Ž‚Šƒšˆ€Œž‹š“„ˆ˜ŽŽ„vtvs€po…spqƒpkivnƒn}|musRN‚ßȒ֓|ot„vƒ ‚“w•‘™›š{”s…Ÿ¡““Š“›”†~–•ˆˆ‘‰œ€ŽxzŒ~ˆŒŠœœ›•“yvgˆ‘‡lˆ£„’‡—ƒ†cŒ‘™Ž•Š—ŒŠ‹q{”ˆ{ŽˆŠ’‘‰y…{~l{erokkyy\€yŽ€z}~†Žzyhsks‹‰‚……}•Œk~~n€‹~‹‡}„z–ššŠ}wxƒysmgp€„mjtohjtnS^odpY_krxfkjbfxrppc_x``Vk_^vONL`gc]yq‰t\\ev`aeed`faXissnkqvŒ|ty†‚uv~‹s†{‰~r‰‡‘Šˆ|~˜vesm|eˆ~opl€Zlnyysavz{vswŠwyŸ‹›®› ‚…wˆ•~}Š‡…Ÿ‘Ž…Œ—„“Ž‡twpyqn„omn~rddxq}mz}jhlc¤šÁÜ®ï¡sku„v…¢…’o–• ”œ’q†‹£—‰Ž•Š–ƒ€•…‰€’ŠŠ—‡{u‰x†„œ›˜™vŠvn†ˆ‹}Š£„‘‰……^‹”—Š‰Ž‹‹„Šm|–}ˆ…‰†v…}}k}dxujnxsXˆz’‡…z~€…‹~xesj‰Ž‰‚‚€Œ–…kvnˆ‚„‚z–“™utxˆusqguzƒbtmobivgR`qglU_ntyarc_h}prn[crabWnZ\wMMLdga^vs‰m\\dy^`df…`cb^YjrknkrvŒ}tw„xw{‰qƒ„}~ˆ{t‹‰ˆ–‡Œ~~˜shuqym‹zntpXqzvyqewy†Œiw€‰rœ‡™§œ£’„|pŒ”xy‹„…¡Ž{•™ˆ„{rwpsjokil|t^`xw{qu{gae|ëÚµÉÃ܈slswŠšˆi˜•“‰q…‰ „‹•ŠŒ˜”|“ˆƒ‰{‘‹†‚vxƒƒr‡‚“›–”˜†Œv‡p„‰‡™¡ƒ”Œžƒ‰aƒ•‡‰†Š‡‡i}”}ƒ„‰Ž‚q†~qwhvriswlZŒ|’‚…|ƒ€„Š‚uatlˆŠ‚~’}m‚lx††‘ƒ}}€’“—‰orz†ulqlrx_sin\kv`RdrifS_pvt`o`]h‚qsjWghciXmV[uLJLeg^brs…i[\ey^^dg{`d_\YkneojswŠ~ss~zvzˆs…‚|€‡vwŠ†Ž˜Œ{“vlvuyx“tnxz}Xy…q€ogyw’‚dv†…qŠ•…™¡›¢Š†so’‹rwŽœ}Šš‰‰|Ÿƒ™xqsnodr~hflww[_y{{qq€iagaÕ¶Ž¦xnqw{p’Œ‡j™Žˆœ’Œ…{iˆ‹š‡’‘†‡˜|‰Ž|~Š…zu{‚zp†€–™Ž“”ˆuƒ†vƒŠ“ž†•Ÿ~ˆa€“‡…ˆ„ŠŽ€ƒg}‘€~‚Œ~m‚|‚tkmvtsvukb…~|„„‡~p_sq…{Œ‚|~‘ˆzpƒfyƒŠ†‹ƒ|„~€”‘“„npzŒunoklz}bhjiXmvZRirjbQbrxlbe]Yjƒmsb\g_dl_nT[oNHOge\gnq€l[\cs`\clwde]]Zllbmjsv‡qo||tx†x…‚}€‡uy‰’–|ˆ†v‰owy{„“pm|w^ƒtmi{s”sgs‡|r‘‘ƒšŸ› †‡vv”~mv”—~ˆ‘ƒŠš|‹šv}vqoljat|gbiuzZ_x|zmqedhhW^qr–¼Ãƒuq”‰~r—Œ†œ“Œˆsk‰–{”‹„›Œ|‹†}|‰Œ”ˆu‰…vw}qu†ž”†•ƒ‚rˆu„{‰˜œ—†“Ž€ˆe}“‚€†„‰‰r}g}‹{y‡‹Ž|i€|ƒvfoxxsvslj…ŠŠx€„ƒk^rxz}Œ‰…{€~rix‚‡‹…„xƒ|—Œ}nm{‰}wuohh}vd\pbWpsSSnsiaNftxf`]\Xn€osYeb]jm`pOYkQDSgaZknm{oZ[^mcZbowcf\]`ljcmjsv‚ƒqn~{tuƒzƒ‚|…v~‰–‘xƒŠtˆrxy~oo|qiyz~mm|v•kjx„tl“Œ†Ÿ˜ ™…ˆn}Œvjx˜‚Šƒ•—‰yŽ–ozspljd`tzh`eqzZar}ygpzaee±²wJbZ¤ÙЖq{‹x}•‹…™‘†ol†’’zy’†„˜Š|‡xx‰Š„–€pŒˆqt}ziy…ƒ¥‘„“ƒo~ƒvƒw…›˜“Š’”…‡p{’ƒ}ƒƒ‰ƒoxh€…xrƒŠ†{e}~„udps€hxpou˜Œ…‚Š{vx€„yk\q}r€‡…‰}†‰zˆrnqƒ†Ž„„s„x€™„xno„w{ehj}q`YwZXqnNWrsg`Klvta][[Yt}roWg]fjq_oNWhQ?Yf_Zpkgyq[[XkeYcpy_h\^emhfliqw‡ol}€upz€‚v…‰—Šq‚q{†|yyƒ“Œujzko~t}or|{”on€xg’Š‚¡™‘‚†g‡ƒohz–Š~€…‚™Š|Œixrklf_aoym_boy\dk‚zaqv_efÔ꾊2:>‹Ž€ry…ˆŽvƒ—~“Žnl…Œv}…‚•‰|ƒxnv‡„ƒ—wo‰…lu{tfy‚ƒ§Œƒ‹„}ntvƒy†œ‹‘’Œ‹†~{’‡x€„ƒl€ri~xm|{Šƒway„qdqh~mtqu›‹€…~ru}€r€o[m~txŠ‚‹{†|ˆxzqlˆƒƒŠry–‹‹tnkw€€uu\iiwpYW|SZqeL[rre[Jpwo\[ZY]t~uhYb[gfnciLWfQ=^f\]ue_tp[YUodYdqyZh^_gmgjkipw}Žli‚„~yn€{|€‚zu‚Œ“…p€‹nx~€z{ˆ’‰h{~kt{r†{sw}Œyx„}|kŒŒƒ›–Œ€lŽ~kh~Ž{~ƒ”‚}Šˆkuqghc[bgro`altahp‰ybst^cd› n\5Y¯µuj€‰}’†v†—†t‹Šwpm…ƒ‡uy‰x‰}“ˆzsgvˆ~~˜oq†~hvymeyˆ„¥‡€‡‰~n~u€}Œ™‡‚“˜ˆ‹„‰|ˆq{}„|i~mk€{zjzv‡r`w~qdrgu‚mt{…”‘|nwy|t~lXovt‹†w‡u‰zxsn‰€Ž€…r~}~“‰‰znnjn‚‚un]gfsqQ[{N\q\O\rpdVKsxjWYYZaq€t`]]`gdhifNYhM@ad[`va\tmXXStaZdorWj^ahkgmlipw|’kh„‰||p~~{‚zw€€‰‹„q{‡oqwƒ{‰ƒj~{nwyvŠw}x€‚‡ƒ~~zm…Œˆ˜£„ƒ{u‹ykl„‰’y}{‚‘€€~Šƒprpcf^Yg_pp``gpfjoŠtato[adjv{¾œ¦£È¸q…„s”}x†”‚tˆrrp„{ƒtu‡tˆw”ˆyyqcw†z€“ir„vfwvcj|ƒˆž‚ŽŽ}r~s„y€‘‚x–”ˆ‚ˆz‰‰lxyuh{ikysizv€‚}h`w‡}jkth{ivŒ”~z~~p{v{s~bVw}rsŠ„‚|‚p†‰wxppƒ‚Œ~}y~|uŽ†ƒviqimˆ‚rp]hcsnJeuL^oVTYsnbQOsxaRXX]bp‚s[a]hedcjdQZpIDda[cp^]whUWVw^\enhVk^ajgeoohpvz’niˆŒy}r{~x‚‚|v}ƒˆ†ƒpvƒrnw‚‚~‰‹“p€|xyzŒuƒx‚„z€uo~‰‹šžˆ}…zw†{gt…Œz|‰†„v€gon_d\XeYmra`aqlkh‰n`siY^dm€w©Ú©Ç†‡²q‰xpu{‡€z“Š€utu~w€pqm„t”†xul`z‚yˆfqƒogvn[m}€“€€x’’}x{m‡u€‹ƒs–Š‘Ž‡……{€…muvnhwem{vmjvw|`bx†zhtuc~zgt…ŽŒ•{tuq€z|lYVt}ot„‡€xkˆ†sxkuƒƒ}z}x{r‹}sgten‹„mt[j_udHnnL[bWWVxmbPStvXPUX^aq„o\`cmec^nbT\rGBf_]fh]ZzcRV\u[[gkaVj_`offkqhpuxtkŽŒuvx~wƒ{t~ƒˆˆƒoqtqu~…‚‰Š{wx„||…‡x‡|}~„€{~svyŒŽŸ‰z‰vtƒy^}…™Œy‡ƒt…†…w‰{bnl[b[[aVjsc`\gnof‡qaqfW]ck|ÊΈ¹¢jmmŠlq„r|„Š~{’…zytyuu{jluc„u‘‚wpg^}‚z‹‰er‚kjqcXl{†œˆ‚s—”w~{n‡qŠ‹‡q–Žˆ…‹ƒ{y~qqo~ghrbnxqjkqw||y\ey€wiuxf‚vgt‡‹”|r†io~€xm|]Xq~ls€‹|nn‰qvhwv|qzt‡|zrfsanŒ‚lsXk_w[InkMVU^TU{kaOTurQQTV^bt…h\`ljfcYnaXbpGAh]`f_]U{^OVdpZ[jh]Wg_^rfkgrgprv…xn•Štzx~y‚‡€us€†…Ž‚pp{xvty†††‹†z|u‹~}…„„‡~~}‡|xvyw’“ŸŒ|‹mv€ycƒ‡—†s’Šo……zƒtcnjY_[]]Tgse`YdrrfsbkeW[`iw¾®{ ·mbs†ht|rzƒ†z}Œxxsvo{vejn`‡uŽsjb^~xy‹„fq~hjkZVoxŠ¤…q™“q€xum€‚‘‡r”ˆŒ‡ƒˆ…}ytrohzajm`mvkgjkywzw[g}|xer}n„teu…Œ†•o‹fkzƒtltb\o{jt{‹{et†}mqgu~x}r|lzzzxpflbnŠ~mnVk`wUJjkOROhNY|hbNUvjLPTU_gvƒf]`qhgaWi][khJEkZbdWYUyZNWnjY]le\Zdb^tfmdqgrot€wp™…v~w|…‡}us‚ˆ”‚nsxzyrr…‡ˆˆ„y}v|„‰Ž„‚„{~‹ƒ{w|wwš—zŠƒ†iw}|lƒ„“€r‚q†‚~oflgW][\[Tdpe_XcsuivpeebW\\h€por€t‰eex~itvssƒ„x„ywtunk{pagkg†t„nf]_}p{‰~imwfidUWrp¦|„|v–s|s{ym{{‘„v˜|‡†ƒ†ƒ}uprlgu]mh_ludgfizo{rYgwugp€w‚ubw…Š|”€n‹jmz€pere`myfrwŠ{~bu‚vikqtzpyxr}f~ywncebn†|mkVjbpSKikOLOpG^{faMUtcJNSWajv~e\gsie`VcWbp]LKkXcaUTUsWLYudZ_ka\[cd_wfmbpisnq~tt™w€w~†…z}u‚„~—…nrt{ztp„…€z‹ut‘€}”Ž€…„}~Œ†{~€v{£¥Šyˆ…„lu|{uƒ‚Œzn…sz„}ƒunjheV][ZZSbne[Xbs{jhmi_bW_Zi€jko€hlahyxktttn…{}vumzhjyj_enhv„geXbwi~‡{oiogf]UXoh§vz|Žyuo~oruxŽw”t…‚…ˆvjrvgho\me^ms_gaixh{m[m‚rsio€~ywaw„„x„sˆqoyqbph\owdqsˆ|xbs€pgjxsrkwvtwcƒ{wvodccn|}klUibfSKmhOGRlEaxfaMSr]IMTYekwze^mpid\V_UnnWKThXf^XMUlTJ\y_[_k]]Zbe`zhlaoounowuz˜}w€z€‡†zyzƒ~“„qtt~zvt…ˆ}€}ls•|ƒŸ…‡}€~†‚€Š{v„¬Ÿzˆ‡„lr‚zv€€un‡o|s‰€jomddX_ZYZUbjg[Z^ui^ml\aV\\kfrt}jj]kvvgtwqm…{}}yvrlzhixf]dshzw’ccTepg‚…wwfhj`WVYhd§n~x€‹Žzpp|fxny‹{vŽq„}~†ndvsdhh]kb]oo[g_luezh]t€orkq{}uubt…Šz‡†€wru~taplYqtbqr…|tdrlalzojhywtqf…uzzupdadns~ilTi^]TKscQGWbGbvfaKToWJLXXglvzdenpfcZW]XveTJ\cXhXYIWeQHbxZ]_l[^\ad^ij`otxmonvƒ˜yr€}ˆ‹†}uv†x‡Œ}suu‚xzz‚ŒŽ}~„‰jt—{‹}~…zz~|†ˆsq®Œ{{†~frˆzt||vro†l{~lzbpoae]eVYYVcfk`]\s…iYpnZ^WZ\l{cpwvlb[mstguupm„x~€ywnnteite[gufvv‘z_]Refj‚‚t}bci\TX^bc¥hyt‚…xmnygwm{„zuˆr€x|xhevm`fa_j`]tkYe]oobze[w{knnpwxstdrƒ’~‡‚ˆzvor}rawd[opbpq‚|sfq€d^nvicfyztmnut}sqb^fno}djShXYTMw_QJZYHbtcaITmSILZWilr{bllsbaYZ[av[SKd]XiSWHY`NGiuX^am[[_bb]…hhanxylnjvynƒ~€’ˆ„vt‰tŒ†sqwvw|}~Œ€~“~px–ƒ}™’y€€xy}tˆƒsp™¢{z‰•yduˆysxulto~ly|p‘r^pn`gblT[ZWhcmf\\qˆeSrn[ZXX`mwdiujj^Zmsqmtstj…|~|wnnldiqc[jrdtvs[WSdar€r‚]bc]SZ`[c“Ÿerq…„‘tljylooz{zq€v~rzzzdfvg^bZag\^whWb^ohawa[{vjirnwssthp”‚†~„vsjp|lfvW\kmbpszsfo~[`oqb_ip|lks~rqxkp`[elmzagSgUWRPv[RPZRHcsb`GUjPHOZVklk|emoq`[ZXYlpWRPfWWiSTFZ\OHruX_cmcXa`a]‹jcdmyxkniuy†{kƒ}„™|‚„y}ˆn†qowz|t‚‚|‹ƒ‚–tx‚”…Ÿ‰u€€sp‡‚uo¢—t{†‹‡{fx‹on{ofxpzlsvrŒk^tnagekR][VgbllZ\qŒdOon]VXUgjuhbtee]Znunquuzk‡||ˆwsddkna\nmcsx‡kZTVbcx}}q…]c_cT[`Yc–•cnpƒ…Šsjhznervs{lztuoz~u_frc[^WbdYaueU_`mdaq]]~phisqspuukm„“ˆ{…qrfn|oqnS[fjfqtvsblvUbqj[_ne|elu|rrsjm`Ydjjw^fTdUVPTmWQWTPHer_aFWiNHXTVnid|ikwkaW\U[tdSRWhQYfTSHZZPMxw[_eliZb`^^nbfkyunohvvmƒ€~†—{ˆŠk“ˆrgt€{u€ƒ}‰‹“r}Š‘…‡Ÿ†{†Œs€†s}ƒvn¥Œs‹wxnzŒ`d|pfzsylmqv‚gd{lcfghS^^Tg`lo[^nhNim`TVSogtlexde]Yptmrzxsmˆ{€vœ{zkaelm^`ojepy~gZVX`kx|{p„_b^gVY`Wdœˆbkq‡}wkjwl[vqkyiurmo{€rXjn_Y]VbcXeqcS^aibblZ`~lfksunmwvkh…Œˆz‡mqfp|lqlcY`hiotsr^ilReqdTbnaybpv{ukpmk_Xaght\eVaVSNXeRO\OOHeo]cGYiMI_KXmd`xhn}d`U^T]t[TR`fN]aTSJ\YPYuv]_fmhXca[^Žpcgjwqsmhvtzƒs‚ƒzˆ~|Š‡ŽznŠtls‚tˆ…‡’„•z}Œˆ‘›„€|Œ„sstxqn““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~~~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’’’’’’’’’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’’“““’““’’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z||}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ‘mfggggg}…„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDEB1/////,€¤    ¥^*///0,H…ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‘g_```_^yƒ‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR4555553~©¤¤¤¤ªV:ƒ€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}z{z|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‘ŽŒ‡‡ˆ‡‡†‰““’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†………†…ƒƒƒ„„„ƒŒˆ‚ƒƒ‚‚‚…ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z{|{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘’’’’’’‘‰‡ŽŠ’“Š‹Š‰‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŽŽŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…Œˆ†…‰‰…ˆŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰‘††‡……‡ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰ŒŠŽ‡Œ‰„†ˆŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}|}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹ŒŒ„Š††ˆƒŠŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz||||}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒˆŠ‰ŠŽ‰ŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzzz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{y{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†………………„„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰ŽŠ‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{}~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““””””“””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••””•“’’’’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””’’“““““’’“”““““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘’’““’““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~~~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’’’’‘‘‘‘’’“’“’‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡ƒŠŠ‡‡‰†……„„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxz}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzop{xy{|{xw{xuwttvtuvwurpqklrpghklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkiffggghhgmejfhehgcbbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__ac_\_]`]^Z^\]^bi`]^ZY_[XWSNMKKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{yvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSTPMJMNPROMPP\W^lWURQQTPPNNOLJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTtsuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMOPP`W]rUOOONOPPQONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKLFDFJKLcT[tVKPMLLNOOOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEBA@@CCGfTUuSJPLIIJHHJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:;>><ED=?Jc[UpKDFHGFGBDDDFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@;;><;;<<HL=>Udb^gOAEEFDFFDFIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnpprtusqrvxy}}}~}~~~€~~€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;:;;99:88;<979;;><Hbmhfl`FC?LCCFDCCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqusurqtxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<:79::979::7==89UlrkjpkN5JX>@A@=;;><==@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqsusurrvyy{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>><==?@===?C@OB<Xnqnlsq[CcU=?@A@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquutusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCDA?=>@A?@;]m?RYJRkokgrrf_jH;>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVppqssttuyz{{|~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???CFD><<=@=8:;nvGAb]\inhcqnklf>9;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pprrrtuvz{}}}~~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC?>AAABA@ZQ<<=KNHHvvM8WjhknjoqnmlV::;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC@CsyH<_€ƒ€z{wV;C`strouqno`A?==>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hloppqtuvy|||||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCE@Hrykeƒ„ƒƒƒ€}]>?GhxurspmlL>EBBBFHC=<@DCAA?>=@A>>>?<>@DGE@>@A?@CFECBCC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqprutwz|{|{}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@Fot~‚‚„~}„uLBCCOlwx{zq_EEIIIIMMKECFGHEGEEEDDCA?@>>BFJJGEEGFFJNNKJIGGHKLIGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@EEhs}|„~y…rCDEECd‚‡‡ˆ…^FIJLLNOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHIHGFEFFFDFHGEEHHFHGHFQnnpqrvvy{{{z}}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJG`{€€x€„…ƒ„‰mAAWu…ˆ‡‡‡‰‚WHLMLMNLJGGGGDGGGGFHFHECDDFEDDHHCCCGJJKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrswwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLLN[|‚‚ƒƒ…††ˆƒUm†ˆ†‡†‡ˆ‰ˆ|PKLKHGFFDECC@ACCCCFFEB@>>@AA@BD?>?DFHDEGIJIIHHIGIIJJIHFJJJJIJIJJJFILLJJKKfopsrtvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKLLJV„„„‚‚†††„‚†………†††‡ˆ†ŠuIIFB??@???<<<>::<AA@><998<<=;>;9;?AB@ACCB@ABDDBCFHIHHHLMKGIJMMNMJJKKJLMSloqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHHJJIf…„„„ƒƒ‚ƒ„„……†‡ˆˆˆˆ‰ŒŽfBB=88::9878896479;<:8567789787688;;;=@;999=<>;;=ACEHJMLLGIHORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@CGIIi†„„~ƒƒƒ‚ƒ„†‰Š‹‹‹Š‰Š‹Œ‰T:8656766645763468:876565676778:77789;7578979876:<@GFIFIFEFOSRSSROPPRTepqsttwy{|{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:=ECBf…ƒ€ƒƒƒƒƒ…‰ŠŠ‰‰ŠŠŠŠ‹‰‰ŠH676468874578467699766765:::::;898987779:98878589;A=>>BA?AKLOQPQOOORWkqrttuwy{z{|}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897;B:=r„€ƒ„„„„„†‰ŠŠˆ‡ˆˆ‰ŠŠŒŠ‰‰Œz>988;<=>9:;<89;9:;:99;:9===?;;<=:>;9;;<;<<9:<8::;:999<?<=ABDIJMKIKLWorsutvx{{{|{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<:89989:::;?>H~„‚‚„………†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>BCEEAAAB>@B@@>=>>@???@?@==?B?AA?A?=@@@>?A=><;:;99;?=;;==AACABCAXpqtttvy{{|}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::<=:;;==?@BRƒ‚‚„…„…„†‰‰ˆˆ†††‡ˆ‰Š‹Œ‹ŠŠ‹Š‹^>DGIKJIFGGDFHGEB@@CECCABCB?@DHECEDEEAFEFDEFD@B?<@>=?@>???>?>>:;=<`qrttvwzyz}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>???=A@CCFX…‚ƒ„…†††ˆ‰‰ˆ‡†††‡‰‰Š‹ŒŒŒ‹ŠŠˆWHLMMKNJIKHIJJIECDFGFDCEFDBHIKHGGFGGEKIKIJKJCFCCDBAACBDCCDDCA=;=@hpsttwwzx{||}}~~~}}}}~~~~}~€€€€€€€€€€€€€€OA>=?DLK@BBA98<>;<;>@?A?BBGGJY…‚ƒ……‡‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹‹ŠŒPMOMKNKJLJIIHJFDGHHIEEHFFELLMIJGGHIJOMNLLNKGGGGEECFFFFDEHHFCA?@Llptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?EGG=<@@88<;<=:?A>@@CFIJQ`‚ƒ…„…††‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒ‹ŠqMQOMLLKLJHGEJHDJHGKJHJGGGKLNLLHHIJMPNPNMOKIGIJHIDIHHFFGGHFCBACUnpuwwy{xyzz||}~~~~}~}~~~~~€€€€€€€€€€€€€€TDAABGGB?8?@8:<8=>;=A>?@DHJLUqƒ„„„„…†‡ˆˆˆˆˆ‡†ˆˆˆˆ‰‰ŒŒ‹ŒŒ‹‹‹‹‹_RRPMNMKJGFBGJGLJFKOLKJJMMLOPNHIKLOQPPQOOJIJJLJLFGHGEGIFEEB@BB\orwxyzyyyzz{|~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<9@>>@BGGAGKLPVy…ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹‹ŒŒŒŒ‹‹|WVRRTROLKJDEFKONOWVQPOQSRMSTOMSLPSUWRSQPLJMMMKNGGJFFHJDDEEBDCcpuyyzzz{z{z{|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?==B?CCFVNFNPPTX{†ƒ……„„‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒ‹‹‹gVUkaERQQPI;;QSR`u]UVTVYYRYXRZfPUWZ]RTWQPNRPPPQKKKHHJHEFIHIHIirvyyzyz{{|z{|}|}~}}}}}}~€€€€€€€€€~~SHJIIGGFE??AAEBCGEDELXRMTUVX[|†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ}aŠ‹‹‡l[dU:XXXSQ?@VUY\d`VYbr^]V]ZVEQYZ[Y_TZgRUVXTTVTOOMJLJIILMKOMSosvxyxwzyz{z{|}|~~}~}}}~}~€€€€€€€€€€~~~VJJIHGFDDBA?HMIMPKIKPTSSXZZ\\x…„…………†‡‡‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~Œ‰Š‹ynpXZ[ZRTRVVTZZuƒYU}a\X]^WIV]][[_YIYXY[]XXYWRQNPQMMOSQQURassvwwvxxxz{{|}}}~}~}}}~~€€€€€€€€€€€xy}YNKIIIFBD@A:PQQWXPPOQSTTXXYZ[n‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡ƒŠfYY\YSUTWRQWVc–€QerXZW_hP`f[[X\gaGOZhg\[\]]WROSPPQVVVVYZnrtwvvtwxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZ[SSQORRRUSVTW_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PUXTRTRQQLOMKfyZ]TYUV]ZLTZTST^ZXWWWzkXZ[\^TQQPINOWVXZZdqsvvttvxyy{{|}}}~}}}~}}~€€€~~zxwvsu{€€tk~~kry^[VUTROKFCDAM^ƒlVRSNOQOQURSRRTcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ymqVIKMNKMKHJDFHEC>ScURQQMKRTQMOYQMNQSUUMQSRPOMLHCIHRTUZ\mruvussw{zz{{}{}}}~}}}~}~}}~~€~{vsw}~~du}iqt_d]^[YVPLILIal’tPQSNQRQR[RSRQRVUbs{|€‚}{{€ƒ‚…†‡‚†††„†…†u_]KC?CCCCB?DPBD@C>BHGV@HNMG]iQHGOFDEFHGHBCHGHKGDAAD@OPMSdstuustuz|z{{{|}}|{~}}}~~€€€||}€€€}vt{mh|gnqfiedb[XSQPURsWe[OONLQSQUYSUQQTSOV`klrv{{xytrnstsyx~~ƒ€ƒƒ‚€‚€‚kLG??;;>@@??>kQKaEFHIEB?GLMGMQUIBE?><=<==?=?ACC?><=B>JMFUnuuustvxz|{}||}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljjf`[QRZ\Y^IJPQNKLQRQTVTWRQWVPX[b]agmmlokh`nrjmlqu{z}{xz||xwxdB@@B=:BCAADB\]O{NOONKLMOOQLKLWNHG@B<977599=;;;8989?;BH?\ttuvuvxz|||}||}}~~|~}}}~}xuvz{zwyxuw{|yxuywcqhipmnmmhf^OP^\ZIGPRQOMPQNQRTVXSRYTNYZ[WY]^^`e`]^qvk^`gkwooljonnlfbXGFFHBAGIEEFDMRPaWRXQPSSRU[OOQWPMJCF>::6487979:366795<B=essvwwyz{}}||{|}~~~{~~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZWMLTTSQQUOLRSTWXTTXQLXYZVXXVXY]WWXhsk]Vaskaa_]da_^YUPMONLIHJKIHFCQPSZWTTNQSYS\eUOSTQNLIHC?A9988978857578599Gnrtxxz{{}~}}|{}|~~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPXVVSTVOOUVXXYSUTLKTUUUUWPTUWTUR]n^RNY_[VY;DVXT[fJLPRROMMNNNLJFQPUYSTNJOOTST\VRUSROMKIHHF??=:787659967665Wpqtwyz{|}~}}|}}|}}}y}}|~~~}||}}~}|rvqxxrvuqqnppopuvtnjddjppqrpofedc\^RTZVWUTWTRXXYYYRUOIGOPOOMRJOPPPNNOTLMIPOSTU2<XMIAQ=caQSQPNPQPNNMQNTRPRMILKOQPRRSTQROLMKLLHCBA=::876;B4566;eprvwx{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqptuvcjgeWhtrrqniihpVVTUXUWURWVUZYXWUQSFFAFGGHFJDHJHGEHLHKHFLMPMG/E_R>3@>joaRRQ@FUQPQPQNQOPOLJLLOPNNPQQNPOJLMMKGEEDB;=<<9=G6676Dnquwz{{||}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknbePSTRSUOWVVYYVQQQO@>;=?@BAC@BEDA@GHGHEFHJNKEGCORC8ENS]fSQSAGUPOQQPMMNMKLKLNOOQMOOMHLLIKKLKHFFED<AA>;@E;<89Tqrty{{{}||{y|zz~~|{utvrvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpknqmimcLOOMQSLTUTWWULLKH=987;?@><=@@B=>EHGDFFIGKJ@FAA@FHEJOHPRa\QPRNSOOPLLOMKMLMON[WKMQOGIHCIJLLJFFFE?BC><BF?B?Adquw{z{{|{zzw|wy~~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCE=9879?B>;?A@@>ADIECHHIGIEBB?>=CBAHJEMObeQMNNWKLMKLMMMLKNNSdMJLRIIIEAHJLMNJGIFBAB@?EFEHDKopwzyy{{z{zwtxux||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGLMIMPMPOHKE?B=999:?B?<@BAADEGKFCIIGGHCC?B??@A>DECKNQTLJIMTGIIJLJKLIJLMOPRPKGCKGCBJJLMOMIJIGCCCDIJMLIZsmxyxz{{y|vrpurtyyvxjqokllnttmtu{stxronqovsnporpopstyjN`gsjt|ygosqjqheqHKDGHHGJKIJKDGB=>=:::;@B?=BBBCHFJLJDIIFGGCC;A@B>@@CDCIMPGIKGHKDHIKMHJLHIJLKM]RIHDMGADKKNMPNKMJKFGGJMNQNLcniwvw{x{z}qmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoijthdoFKDFEGEFFGEGBC@><=9:::@D@>BCDEIFJJLFIIGFFDB;BCC>@DDCEGLNHKNHDHEILNMHILGFGIILNKJHENIBFMLOMOMNNMKHHJORQRNRfgfrosxu{z|lhjnekpmsqfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGJCEFEBCBE@DB>@>:;;=:=>CA>ACEGJFIHKHGGGFEC@=EEB>BCCCEGHIGMPJFFGKNOKFHJFEDEIIHKIFHPKDIMLPMONOONJJIMRUTROWd`amgproryzgehhcilgqlflmgiklslpvutpnvrosrsutqssutsuvvvyvutvlkuumrvqlnlerMGEEGCB@BD<BA>A=::=?;>>@B>@BDGKFIFIHFFGECBAAFFCBCBDEEGGHFLQLIOJJLLIGHEFEDCIHHKJGKRMCNOMQOOONOOKKKOUWVUTX`^\iaminhrsbefedihfnifmmhkkmriqvusqmvnoqrswsrstuvvvvwvwvvtwuksunutsqrjksMGGFHBB@DE<AA@C<89=>9?<?B@@@DFHEHFFGFEEDCECDIECFEBEGEFGGEJMKHQMJKHHIEFHIFCIIJKMKOSNDQRPQRNOMNPMLNSWVWXVX]Z]d`hbjigk_eefcgggkggkmkmlpqgttursnvoqprtxqssuvu‚‘yvvtxuuwxnouorsuqqiozMHGHHBBBFE<@BBD<7:>>:>:@B>??CEFDFDDGEDECDEFGJEEIGCGHFHGECFJJGMJLKHJLFIIKHEKKLMOORTOISUTQSPQMNQNMQWZVZYVZ]ZXa```^hec`dfhgjhhjfhnllnmqpiuuxrrpupppruvpusuvu{~}xvtwvvvxplupmsunprsyNIHGIDACHE<@EBE=8:>>=<<AB=?>ABFCEBCIECEEFGGGIFGKHCHHGIGFDHKIGKHMKJKLHLKMKJNLONPRUVOKUVTQTQRLOQPOTYZZ\ZY[^_^`b^\ackb`dghr…hgifjmnponsqjtuxrsstrnpqvrquruus~yŽ}uuvvvvxrhuqkrtlqvquMIKHJEBEGE<@GCD@:<>@?>?BB<@>AAFCEDDIEFEGEHHFHGIKIFJHHKHFFLHHHJGLLLLLIMKMMMOLPPQUVWOKVVUSSRQLORRQV[[]^[\^__a`ad]d`ef`ehjcssfjhglprqossnswwquvtsmoruorspurvrtvuuuwvuwtgtrkqrkrvovJKLJLGBEDE<@FDDB;??A@@@DA?B?ACHBFEFHFIFFDIIGIHJLHHJJILJFJKHIJJGKKMMJJNLNNNPKOPRUXVMNTVUSRQPLNTSRW[^^_]]`_aaa`bdeachbdijgv‹lkigmosqpqppryvruutsmmssmqrotutrpswtuuwvuuueqskpqjrvowJMLLMGDDAD<?EEEC=AACBBCEBBDAAEGCGHHGFJGCGIGGJFILHIJMKMLGKIHLKNQKRQLSMKNNOPPOTOWXX[NSQW\ZSVPNTUTTXZ_bb_da^`b^`eaabhmgbihhmxvlhimosrpqrrrvtsusssnksqmprotvrqquvuswywutucmtkopjqtowLMLLLGEA@D>>DEFC@CAEDDFCCEGCCIFCHJJIIKGEKJGHJIIKHJJNKNLILHJMKZfJd\KlSHON_nUks[qpbwcRPbvuhucav`Xnqbdvinzf[lt`ljT`wuhjgifglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqrqyKNJKJFC?@B?=DEFDCCBEEEFBFFHCDJEEJMMKLLGGMIGIKHKKIKJNLMMLLILLL[sbdp^lmUMNfs]feqlntgpi_aYnnbppbkjjgoqtetno\ougpMJryvkb`keemymkvlnpsrprqpqrqrrrtrmmsnnoprutqsstuuutwxvutbmukpplrrqzKLIIGED@BB?>CFGBFCEDEEDCHHGDEKGGLMNKMMGJNHJKJILKJJKMMNNMMJMMM[roonpplkMPQlWNibtrpamov\YlQ\mmZqmkomxxtsip\_rkqjUuyxpc^kfbgqpjioppsspqpqqrrqqrrtlmrmnnorutqtrtuutuuzvutenukpolsrryJKGHEEEBBB=@@FGBGDIEEDBFIHHEGKJGMMNKMNGLNILKIJMIKJJKOPONMKNML\hdu]lqWlNPQmUZk^klvaldtTecNmYl\tpkilxjwuhp]^rkhWbcw|oc`ggadjuyknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtvIMGIDEDCAB<BABGDGFLHECCHKHHFJLLFNKLSRLGLLHNJHHNHJJIHNOMNLJNMJZsppoqqmlOQRnYqkgooqqomt^nXat_nnooqronusttj[]tcwxrjnzhaacfbbjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyytukoumtonssvsHKHIBEEEA@>CDBGCHIMIFCFJLIGFKMLFOJKWRKGKJJNIHJLIKJIHJMMMMIKKKSkbZi^_icrrZ_Yjo_eeUk_c[abQ`lh]j\niid[pfdp]Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunvqrutwrHHFIDEDFA@AEEDGBHJLHFDGKLIEFJOLIOIL[QJFHHKMIHJIKKIHIGKKLKFHKKLLLKIKLNT[\TPTLPONOOVQOOQOOQJINPQdqiTYW[[\UYZ]X]\\cfaafbce__fkmhmtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyxxuvqruovrtsuusHDEGFFAEC?CHDFGCIKLHFDGKLHDGHPKLOKLWLIEEHIJHIKHLJHFHGJGHIEFLIJKNLIO\W^P\[`^OXYS\\b^MYZMXaRJYaZS`d\aX[ddVVX\YZX\VY\]b_d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtOBCDLMACDBDIEGGFKJKHEEJJJGEHHPJMMJMSIHFAHFJIKLILJHFEJGDFGEFJHCJMJKT_Y`X`a[`UXYT^^Z_RY\P^\YN^\^S[^c^Z]`c`Y_b[`^[TXXY^]cbbaceiekrpoppnow††……†‚{€……††…†…uqprrsvyyzyyxxxwryvxrqxvtvaSJJMIDBBCFGEGGIKJIIDFKKKFFIJNJNLHLNHHF>GGLIKKJLKIGEIDCCEAFJD@JLJO[cY_^a_RTSW_`\]Y^QY\MV_WKQY[PZ_aa^^ca`bbbcceZQYVU\Y]c`__cebhommllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxXQKGCGEBEGHFGHIFGJGHFHKILDDKKNMLLHJJHJG?GFNKKKMKKKIGGCD@DAHIB?IJHO]aZ[d]_TQSX]\\\_ZKW\LR\YIM^PO\_acdccb\dcbdcfXQUTS[XZa^^^aa_dlkmjjlnv~uz|„………………††…†……††‚zrsuu{…‡‡‡†…„~xpzwvx\RMC@IFCFKIFFGIGGIFFFILJNEDKJLNJLIKJHIGBHHQMKKOLKKIHGED?ECHHAAGFET]Y^X_Y_[]UXXP]]QKJW^X^[]VZ`RQ__bba`bb`cbaddbXOQQR[S[]]]]___dhgljnnp{{|~{€‚ƒ„………………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKBAGFDGMRHCRKFHHHEFKJMPEGIJKNLLILKIIHDHKQOMMPLMKKHICDAEDHGBAGECWUE\T]SV_XNTUNZ[MJKU`a[_X_^a]OYb]``_bcb]abW__TPNPQXR][[\\^`bffelfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDEFGDIRbPDW_IGGHDFMJPPFJIJKNLKKMLJJGEJMQQNNOMNLNHKADACDFDCAEFBMHCLLPOOLFMFGIJHGLLMOPILOPPSPLPTSUZYWYXXdWOSTPPONPUT[XYZ]\`adecgcklpsszy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKM]LGHYMGHJHGNLQQILJKKNNUNOKKLGGKPSSNPONONOHKE`ED_LDfcEM[I_\smOMVmYLCP`UlWgJ]WU^DMQULMTVQSTXWTXUT\UPfZhhdXSkSVVU[\[``abbb`fhfnlhrz|}~„„„ƒƒƒƒ}|zr{z{‚€ƒ„„……„…ƒƒ~z{LIEFFHEEKOSIKF`THJOJIOMRQKLKLORUROOJLNGHMQ[YOPPNOPOIJPQI|YYrsXPmHqnpaVPqqsPBksmqspSo_[nX]V\XUkhU]VcZ`Y[`VUWjtuu_`w`Xa\\f[_aaaa^`bgmpl`pwtx‚ƒƒ‚}~€vxzlv~tx~€|~€‚„|€ƒz~wwNIEHMMBDLLFJLFQVLKOIKRXWQNNNLQTNOQPKLOGMPS[ZTQQOPPPJHZx]TxehYRTQvgtlpbnfjQrOMwmjrpsrqrpop]fzuxqqzq~s}ku}bRg|essoss|}o}yor_``bbZ``gknkblfgmw~€ƒ~{xw€tvzir~nt|~wx{~€ƒx|€u|||ssNKF`]GAEMMHKKHJPOMMJNV^YULQSNXZLSSRNLPIQRTYWWQTPPPQKHfxlcxrmZKMUypumubnvPdeIfvqmwo€jfxxiXsRi{mijzz~lxzogoXvvjuup€`sh|ilx|o___cbZ^cdfijdgbcdllppstsssyqrxblugry{ssuy~suzn|}yxrnNKStNCBEPPHJKJLQOOOMPZ`ZXKTWPa^RVQYSMPISTUXWWOUPONRJKrouuquqdibWnLqp^FhyWvTLhx}x`y{sna^modRgrunmypwlvttqlm\t~zkmy|lum|kpvux^__b^]_edighfe^abiiijknokqnmjpacfdowxompsy~nqpj{ztromLL[VHGEGRPJLMKLQQQPPQW\YUNVYUfXRRY^TMNITTVWYWOSNNNQHRmHiwK`dvvVXlOnl{sajgvUKWkh}lmlx`[pz{^`zscroxqhe|ir{]TKl`vukiu{{m~xk|p]^^b[^bddgeeebZccikkrsrwgmihdg`alagsrkhmmr|kmhk{tmmkmOHJKHIIHRPLNOLKSSSOSRWRVTPWZVVTTTa`QONKTSSQUVNNLMOPJHQNPULKKSTSRTPVUQQNQQXXQNPUTXXX[[URSW[WXWZOSUWWXR]YW]VTOYRWWWXY_[gr^[[Y\]_cZ_ccdfdccbZccfffmnmuffgc`f_]g`dlhfgkhpzhggkujhgilQIKKLMKJSQMQPOLVVTPTUXUYURZ]VUTWUYXPOLMVTQNUSNOMLQOJIQRKQMKKORTRQQSSIHLNOQRQQQTVRXW\WSSQRUUVSZQOSRWVTYVTYUTRUTTTWXW]Z^a]\ZZ\\`c\]bcdgeedaY`acabhhincad^_c]Zd\bma^ffgmsdihkkeddfhPJKLOOLMTPNSQQMXXUTUWWWZVT\`VWVYUXTQPKOWSPNUPNQNKSPLNUTNQNMNQSPTQSTUNKMOQTTRRQVWUYZ[YRURTWWWY[TOTUXUUZUWYURRXVUW[YZ_]UY^\^]\]`a^[bbchfedbX_`b]`hefda^_]]^ZZ_Z_g`^]]chkagfhfd`bcaPKMLPQLOTOOSQOQ[ZXWXZZXXV]jdVXYZWVTTOKOVTPOTPPPNMQQOQXTRQOMOSVNWRTUUONMQSUUTTRTXVZ]\ZVVQRWXV[[WQTVVVVYTXWTSRXVUZ]Y]_^V^]^`\\`___ZbbdhhedaYb`b^^fdc`b]\\\\YZ[X[a[^]]_b__bddbd__`\PMNNRQMRROSTQPU\ZZW[[\YZ[dqmhd_[YVVXRMMVSMNROQROLPSQUZUTPPLPWVRWSSSXMOPRTXUUUSUYX[^][[VROUVV[[WQTWVWXVTXZTSRZWV\^Z__`Ua\aa]`b_\`]cacgide`Yc`a__ee_`c[Z\[\YZYYW\Y\[`^`[^^a`_b\Y`ZQNONVQPTQOUTSPW\\\X^\_W\^jqwy€c\[VVXRNOWSNQQPRTRKQTTYZWUORNSXVTSTRRZOQSSV[VVWTVZX]^\\^VSNTUV\\VRTVVXYSTY\TRR]XZ]^\`a`Wb[cb^ac_\bab_dgjdf^[d`a`ace_b_YZ^[\[YXYWWZZZa\][]\\Z]`W[[ZPOOOYPUURRWRTP[]^][`\`U\]ijr}slg\UYWQOR[SRQTRTUTKQWV[YZSOSRVVUSOVRSZRTUTX]WXXSX\X^]YZ]UUNVWW^[XQTUYYYUWY[TSV^Y]]`]bc_Y`[eb_dd^^cca]egjdf^^da`abcd_b^XZ_[\[XXXXW[Z\`][[\[XZ[^V^Y]POORZPZTUVVSTT^^`^^b\aU]^bkytl}lZUZUQQS\TUTVTVYWLRZV][\ROUSXWVSPXRSWSVUU[]X[YUZ^X_^Y\YRWRYXY_ZZSTVZYZVXY\VUZ^\^`a_dd]^]]eabfd^^dc`\gehedb_da`a`bb_`^WX^Z\\ZYYWV]Z]^ZY[\[WY\]VXW]SOPWYQ]UVYWWUX_`aa`c]`U]^beeuzhXYZTVSV\XWWVVW]XPU\Y^]]TRXRWVTRTXRSVTXXX]^X][U^_X__X]VQYTYZZaY\UVX[ZZXYYZXV]^_^cbaee\b\`fbdfd__dbb[fchecfaf__aaaa`_^VU]Y[\[Y[YY][[[XXY[YZZ]_]TY]UNSZVS\TVWYWV\`abcad__V[`da_zuohY\ZUWUW[ZY\YXY`WPU^[`a\TUXPUWUSVVRSUVZZ\_^Z_\V__Z]^Y^VSYWYZ]bZ^VW[\[\[[YZYY^_``dbceebdZbfcgfe^ab`c^cciddg_g^bbcaa`^_XTZZZ[[X[XX\[Z[WWYXW\[\`]V]]SPVZVVZUXUXWX]_badada^YYadb`lfh^\][VWXY\\\_[Y[bVTW^]ac\RVXQWVWVVVSVTX\\^``]a]Wa^[^\[^XVXX[[_`\_XY]\]^^\Z\X[_a^`dcdfffbYceehgd^c`_ec]fidei_f^cbcaa`__[XY[YZZXYXW[[Z[WXZTY]\Z`\U^bNRWYVWZY[\YWY^`badada]^Yacb_a`a_\\]XW[[]]__\Z]cXZX]`cd_RXYPWVXYYWVWV\]^`a`_b^Ya]]^Y]]YXVW[\`_]_ZZ^]^^a\[[Z[_a^bdcefefbZdfgigc_c^afeZiibfice^bbca``_]]ZW[YYXXZXWZ[ZYWXVU[]]]``bbxLWW\YW]\\]ZW\]_`bdbba]`Xbcb`cab^\\\XW[]_]`_][`d\\XZcec`R\YOXWY[ZYXZY`]`bb`ac_\b]_][^^YYUX]^_`__\Z^^`bc\\X[]`bacedgeefd\efhifcbb\cg`\iibhife`baca_`_]][Y\YXWXYXW\[ZWWXPXZ]acffrkJYW]ZZ_]\^\Y][^_acbaa]b[bdb`ccb]\[ZWXiq`\`_]\ac_^YYcedaS_ZQXW\]\[Z[[c`cbc`bda`c^`\^^_ZXV[_^]aa_][`abeb_]T\_`cddfdgfefe^efhhgdd`[fg^ahhchhfc`b`cb___]]\Z[YXXXVZV\ZZVVUMXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡…ƒƒƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vuuuuuuuvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{{{{{{{{{||||||{{{{{{{||||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vutuuuutuvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{{{{{{{{{|}}}}|||{{{{{||||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||xÅÔÒÒÒÒԓ{}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰‰‰F(+++*%c’ŒŒŽ‰~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}xÕçääääç™{~†“y1333332j‚€€€{­éääääèʉŒŒŒŒŒŒ”;]–‹}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}v~ywwwwwwxyyyyy{xnoooppprrrrrrrwzyyzzz~ƒƒƒƒƒ„||||||}}}}}}}}vssssssy}}}}}}}|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚‚‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vtttttwtvwz{x{xwvx{y{zy}yxxyxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{{{{{zzz|}}}}}}|{{{{{||||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwwy|}~z{}{wwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwwwy}||}~|wxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z|ywww|yy{}~|xxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚ƒ‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzzz{|||~{xxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyy|{{zy|xxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyxyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{{||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}||}}|||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}|}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrstuttssrrsrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqstsssrqqpponnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqqrssssqpqpoonnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrqrrssrrqppoopoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpppqrrqqqpopooppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqpqqqqqqpooppppppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqqqqqpppppppppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsqu‹‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqqqpqqqqpqpqpqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrsrƒƒƒ‚vqrrqqqrqrrqqrrrqqqqqrqqqrrqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrssrrrrrsusstvstsssssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwwvz|~~|vvwwvuxzxxxxwwwvx}ƒz†ˆyy|{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxxxyyyxzzzzzz{{{|}~|{{z{|{’Œ’y{{{zyxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}||{~}|š…š~}||}€ƒ€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€~€‚¢‡“Ÿ…€€~~~~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒˆ†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~~~€€€€ƒ¦‰–¢‡~~~~}~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽŒ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~~~€„¨Œ”£‰~€€~~~€€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’’ŠŠ‹‹Š‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚ƒ‚‚…©‘¢‰~€€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒŽ‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒ„‚……ƒƒ–«£¡ ‡‚‚‚ƒ‚ƒ‚ƒƒ‚ƒƒƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒƒƒ€ƒ„¬©«°¥’‡‡†‰ˆ‡ˆ‡‡††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠ‡‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„ƒƒ‚ƒ…„„‚‚›¨¥ª  ‹†‰“‹ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ‘’‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„‹Š„…¤” ¢—¡•ƒ‘˜†……‚„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘’’ŽŽ‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€‚‚‡—’ƒ™—ŽœŸ—ž™‘’€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„„„„…„…†’“‘ŽŽŽŽ‰ˆ‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~€‚‚€„ƒ“©˜”– ¦—˜ž¡œ‹€€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“’Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚‚ƒ„‚‚„„‚ƒŠ—ˆ‡ž«©Ÿš¡«–™Ÿ™‡‚‚ƒ‚‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘ŽŒ‡…ƒƒƒ‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒ€ƒ‚…†„„ƒƒƒ‚„Ž™‹„ ¢ œŸ£™œœ“„ƒƒ‚‚„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”“’’ŒŒŠ…„„ƒƒ‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~Œƒ~}|}Œœ‡‘’“–œ™›œš“ƒ‚ƒƒ‚‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†””’”’Œˆ„„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~–—‰€}}}}|‚—‹ƒƒ“——œŸ™‰‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“’Š‡ƒƒƒ„‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€€•Ÿ‹~€}‡‹~„„ƒ„‚‰Ž’Ž‰Žœ”ƒƒ‚‚‚ƒƒƒƒ‚ƒƒ„‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†ƒ…ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„‘¡Š€‹…}†‰†………†‡ƒ~~}ƒ‡„„ƒƒƒƒ„ƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„……………„…†…††…………………………††…†††…†††‡†…………ƒ„„„‡“““’’ŒŠˆ…………‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…ƒŠ‘ƒ„‹…ƒ‚~‚‡†„€€€€€„„ƒƒ„„„„„„„„„„„„………„…„†……†…†††…†……‡……†…††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„„„‚‚‰~~…‚€€€€€€€„…„…†††…………††‡††…†……†‡‡‡ˆ‡‡‡†††‡†‡†††††††…„ƒ„……†„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘”“‘‘‹ˆˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒ„„„ƒ€€€……~€€€€€€€€€€……†‡ˆˆ‡‡‡‡ˆ‡ˆ‡ˆˆˆ††‡ˆˆ‰‰‰ˆ‡†‡‡‡‰ˆ†‡†‡‡††…„ƒ„…†…………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†…†„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡†…ƒƒ…„„„ƒ€€ˆ€‚‚€€~{z€†ˆˆŠŠ‰‰ˆˆ‰‰‰‰Š‹Šˆˆˆ‰‰Š‹ŠŠˆˆ‡ˆˆˆ‡‡ˆ‡‡ˆ†‡†„ƒƒ…‡‡‡†……„„„……„……†„„„………†…†…ƒ‰”“ŽŠ†…†…ƒ‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡†„„…„ƒƒ‚€€„„‚‚‚‚‚‚‚€~}}}}~|{|ƒ‡‰‹‹ŠŠŠˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰‡†††‡…†ˆˆ‰ˆ‡†‡„ƒ‚„ˆˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚‚ƒ‚„ƒ„„Ž“’‹ˆ…„†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚ƒƒ…‰Š‰‡…‡…„……‚€ƒ„‚ƒ‚‚‚ƒ~}~~~~~~~}~}}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡‡‰†ˆ†ˆ‡†‰‰ƒƒ„ƒ…„„……†ˆˆ†…ƒ‚‚ƒ…‡†‡††„ƒ‚ƒ„‚ƒ„„‚ƒƒ„ƒƒ‘’ŽŽ‹‡„††„‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…‡ˆ‹Š†„†„‚††‚‚„„ƒƒƒƒ‚‚}|}€~~~~}|}}|y|ƒ†‡‡„ƒ‚ƒƒ„………ƒƒ…„„„„„„…„‚‚ƒ‚„„‚ƒƒ…†…„‚‚‚ƒƒ…ƒ„„…„„†ƒ„„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰†„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€‚ƒƒƒƒƒ‚‚}}€€}~~}}}}{zz~„„„‚€‚‚~‚ƒ€‚‚‚‚ƒ„€€€‚ƒ‚€€€€€‚‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†‹“‘‹ˆ……ƒ‚„‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€€ƒ‚~~~~}€‚ƒƒ‚ƒ‚ƒ‚}}~€€€~}}}}}}|zzz€‚‚~€~}€€€€€€€~}}€~€€€€€€€€‚€€‚‚€‚„ƒ†’ŽŠ‡‡†ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒƒƒ„…€€|}}~}}~€€}~}~ƒƒƒ‚‚}}~€€€~}}}|{{{zzzz€€~~~}~~€~€€€~~~~}|~€~~€€€~€€~€~€…’’Ž‹‹‡‰…„„‚‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~~}~€€~€„ƒ‚€~}~~€€€~}}}|{{|zzyyy{€€~~~~~€€~€€‚€|~~~~}|€~€~~€€~€~~~~~~}||}…“’ŽŒ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒƒ‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚‚‚€ƒƒƒ€€}}}~~~~}}}}}|||{zzyyy}€€€€€€‚‚€~€~~~~€‚€€€€~€€~~€}~~}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒ‚ƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…ƒƒƒƒ…„„„„„ƒƒƒ„‚‚‚‚‚~~}}}~~€}}}}}}}}}{zyyyyy€‚‚‚„ƒ‚‚€ƒ‚‚ƒ‚€€€ƒ„‚€€€€€€‚‚€€€€€€~~||Š“Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…ƒ„…„…†…†††…†…ƒƒƒ‚‚€}}}}}}~~}}}}}}}}}|{yyyyx|‚ƒ„…‚„ƒ‚‚ƒ…†‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚ƒ„ƒ‚ƒ‚‚‚‚€€€~Ž“Œ‡ˆ†ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€€~}}}~~~€ƒ„‡ˆ„†††…††‡‡†‡‡ˆ‡‡‡†}€‚~}}}}}}}}}}}}||~~~|{yxwxyy€‚ƒƒŒ„ƒ„„„——ƒƒ„}~‚‚‚‚ƒ†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ…„„…ƒ‚ƒƒ‚ƒƒ‚‚‚‚ƒƒ‚‚’‹ˆ‰‡‰‡††„†…„„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€~}~~€‚………‡†‡‡†‡‡ˆ††‡‡‡†‡…}}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yxy|~‰–„ƒƒ„„”“€~~…‹€€€„†‰…„‚‚……‹ƒƒ……††„ƒ……ƒ…„ƒƒ„ƒ„„„ˆ’ŽŒ‰ˆˆ‰‡‡‡…†…„…„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„ƒ…„~}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|xyz{|€‚ƒ‚ƒ‚€~}~~{ˆ‘||Ž–}‚†Š…ƒƒ„ƒƒ‰}ƒ„……ƒ…†…„……ƒ„……†„„Ž‘ŒŠŠŒ‰ˆ‰‡………ƒƒƒ‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚€‚€~}}||}}|||}||}|}}}|||{‹‘—Œz{|zzz{|yy}}~€€|{{~~}‚•‘„ˆ~|~‚„||‚„‚€‡ƒ}‚‚‚€ƒƒ„„„„„‚„ƒ„…„’‘Ž‹ŒŒŽŠ‰‰………ƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚‚ƒ…ƒƒ…………ƒƒƒ„‚‚ƒ‚ƒ‚‚€€~~}~}||||||||||||||}|||~~Š‚{z{zxz{{|}{~}~}}}}||}†~}‚~~~€‚||‚€‚€~|{Š‚}€~€€€‚‚€€‹”Œ‹ŽŽˆ‡‡………„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ…„†‡„„€†”ˆ€‚€~~~€|||||||||||||}|||||||y{{{xxy{zz|‚€~|~~}€‚‚€€€‚‘€€~€~~~€}}}{}}}|}||}€€€~€~~”‘ŒŒŽŽŠ…††…„„…ƒƒƒ‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚„†‡††~ˆ•Š~€€~€~~~|{{|||||||||~}|{}|||{|||zzy{|z}…ƒ‚~~€~…‚~€~~€…†‚€~~ƒ†~|~€€€~}}}}~{|}€}~€Œ‘ŒŽ‡„††…„„ƒƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}~€‚ƒ††……~€€€~~}€€€}}||}~}||}}}}}|~|}|{}||z{z|}}†„ƒ€€}~}~~Œ„†~}||~‚}}}}€|{}|~„ƒ€~~~~}}}~€~~~„’ŒŒ‹‰†„†„„„ƒƒƒ‚ƒ‚ƒ‚ƒ‚€€}|||}~{{}w~vx~}|}|}~~‚ƒ€z}}|~€~~~€€€€~~~~~~}~~}|~}~}~|{|||z{z}€€ƒƒ‚~|}|}||ƒ~Œ~|{{}~}~~}{{{}|z{{{€†„‚„ƒ‚€~‚‚‚‚‚€‹Œ‹ŒŠ‡„„„ƒƒƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€~€€}€~~~~|‚~~}}}{{}}|z||~€‚€€€||}|||||}|~{~{{{|||}|{{{{||zz}z~‚~ƒ„‚‚…†……††‡…„‘‹Š‹‡‡…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~€‚€~~€€~~}ƒ||}}|}}}}{|~~~~~~|||||}|~~{|{||||}|}|~|}|{{{|y{|{|}z}~~€€ƒ‡‰‰‰ŠˆŠ‰…ˆ‘ŽŒˆ‰‡……ƒ‚‚ƒ„„ƒ‚‚‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€€~~}€€€€ƒ‚€€€€€€~|z|}}~}}~~Œ†}}~|{ƒ‚}}}|}|}}}|}~|}{}|}}~|~}}}}|{{z|{||{z{{zzz{~~ƒ…ˆ‡ˆŠ‹‹‹‰‘Ž‰ˆ†…„‚‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„ƒ€€€€‚~}~€~{~’Œ|}Š€Œ~~}}}~}}~}|||~}|}|}}}~}}~~|{{{||}|{z{|yzyxy{~ƒƒ„‡‰Šˆ‰Ž‹ˆˆ…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{|||~~}}‚€€€‚…ƒ„‚‚‚€€ƒ‚€}~€~|‰‚~‚„„ƒ~}|‡}}~}}|~|}}|}}~~}~|}}{|}~||{|}zzyyyy{{~~€ƒ‡„ˆŽŠŠ†…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{}}}}}zx‚€‚‚€€€€‚‚‚‚……„‚ƒ€‚„~€}~~}~€€}~„€~~}~}}Š…}~~}~~€}}}|~~~}€}~}|}||{|}{{{zzz{{|}~}€ƒ€‰Š‹‡………„ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv}€ƒ‚‚‚‚‚ƒƒƒ‚…†„ƒ€€€€ƒ€„~~€~~€~}~~€~€€}€€~€~|}}|~~~~€}‚€|}€€}{}}}||{||{{{|{|||}|ŠŠˆˆ…………„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€‚€€€€ƒ~~€}€}}~~€€‚€€€€}€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{|~|}|||z|{|}‰††……‡…„…„‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz~}yxtt€€‚‚‚‚‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚€~~~€}~€}}}~€€€€€‚~~€€€€€~}}}~|~~}}„€~}}}~}~~}~|{|z|{z€‡‚„„…„„ƒ…ƒ‚‚‚€€‚‚ƒ‚‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xyuu}‚ƒ‚ƒƒƒƒ…„…ƒƒƒ„„ƒƒ„‚€€€~}}~€~~~€}}|}}~€€€€‚€€€‚€€~€~€€€~~~~~~~~……€€ƒ~€~€~}{z{z|{z‚„ƒ‚‚‚‚‚„‚€€‚€€‚‚ƒƒ„ƒ„‚„‚‚‚‚~€~}~~~~}~}}z{|…„{{syz|pwuvwyutz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€€}}}~€}~~}~|}}~€€€€€ƒ‚€~€€€€€€€€‚‚‚ƒ€ƒ‚€€|{{z|{|‚€‚€‚‚~€~‚‚ƒƒƒ‚„‚„‚‚€~€€}~~}}}~}}{{z€x|vyy{qtxwvxury……‚„„‚„……†„„‚„ƒƒ€€~€€|}}~€~~~}|~~~~€€ƒƒƒ€€‚€€€€€€€€€‚ƒ€„}ƒ„€€‚}z{{|||~€}}}€€~}}€~‚‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxyzruyyvwwsu†…ƒ……‚„„…„„„‚ƒ‚ƒ€~€~€}}}~~€~~}|€|~€~€‚ƒ€€‚ƒ„‚€€‚€€€‚ƒ‚€ƒ€~‚‚„€€‚‚‚„‚~{{||||}}~}z~}}x~|||~~~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„„„…ƒƒƒƒƒ€}~}}}€~~~}}€€~|~~~‚‚ƒ‡…~~€€€€€€‚‚€€~€‚‚ƒƒ‚ƒƒ…ƒ}}}|{||yz{z~y|yx~{{{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst†„„†ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€}€€~€}~}~€€~|€€~}~~€}€€ƒƒƒ~}~~~€€€€‚€€~€~€‚‚€ƒ‚„…†„€~}||||{yvyyzywyv~|{{{~|{}€}}‚~~}}|}}}}}}}|~|}y{{zy}wxxtuuxrwwtv†„„…„ƒƒƒƒƒ‚‚ƒ‚ƒ‚~~€}}}}€€€|€€€€|€}~~}~~‚‚~~}~~~~€}€€€~~}~~€‚‚ƒ‚ƒ…‡„€€~|}||{|uyyxxxyw{|{{{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvpxyrx…………ƒ„„ƒ‚„‚‚€‚€~~~~€~}~|~€€€€€€{€~€€€}€~~~}}}~€‚~~~~}}~~~|€~~~‚~~€€ƒ‚ƒƒ†„€~|}||{}xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}|{|z{}zzx{|zz{xtxuqrtpxxry„………ƒ„ƒ‚ƒƒ‚‚‚€€€€}~~€}|~}€€€€€|€€~€~~~}}|€€€€€~~~~}|~~|}€~}~€‚~€€~„‚‚ƒ……‚‚~}}{{||yw|ywxwwx{{{{|…Š}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzz{zxswuqqroxwq{…†„…ƒ…‚ƒƒ‚€€€€~~}|~}€€‚€€}~€~€€€}~|}€€€€~~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{||{zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚‚€€}}~€‚‚}~~~€€‚€€~|~|€€€€€~}~~€€‚€€€€€€€„‚‚€~|}~~z}…~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚‚€€€€€€~}€€‚‚‚€~€€€‚}}~‚€€€€€€€€~~}€~€€€€€€€€€‚€€~}~{“z|}|{}y{zzxyxy{||}|||||||}}}||}|~}~~~}|z||{|}{yzzzyysuuooqpwst}…†ƒƒ‚ƒ‚€€‚‚€‚‚€€€€~~€€‚‚€‚‚€€‚~€€}~€€‚€€€€€€€~}~€~}€€€€€€€€€€€‚‚€€€}~|†‰||~{{~yz{z{Ž~xwy{|{}||||{}|}}}}|}|~~~~|z|}{|}{yy{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€€‚‚€€€€€€}~€}€ƒ‚{~~{|}{z|||‡yxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ‚„„€~‚€€€€‚~€€‚€€€€€€€€€~}€€€€€€€€€€€€€‚€€€€€~}~}~~{}|}{||xxvxxy{||}|||||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒƒƒƒ‚‚ƒ€‚„ƒƒ„ƒ‚‚‚€€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€‚€€€€€€€€€€€€€€€€€€€€€€‚€‚‚‚‚€‚€€€‡~~|z}|{}xwvyyz|}||}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚ƒ„„€€ƒ†ƒ„ƒ‚„€„ƒ‚‚€€‚‚„‚„‚€€ƒ‚€€€€ƒ~€ƒ‚~‚€€€~€€€€€€‚‚€€‚ƒ‚‚ƒƒƒ‚€€€„}}}|}z}zyvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysruowqwysw{…‚‚ƒ‚ƒ„‚ƒ„ƒ€€‚ƒ†ƒƒƒ‚‚„„ƒ‚€€‚„‚‚‚~€€‚‚‚€€€€‚„€~ƒ‚~€ƒ‚€~€‚ƒ‚€‚‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ€‚€}€|z|{{w|yyy{z}~}||||}~~€€€€„„€}€~{{{z{ztpxrytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚‚…†„‚ƒƒ‚„‚„ƒƒ€ƒ‚‚‚‚‚€‚€€€‚‚‚‚‚€‚ƒ‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚‚ƒƒƒ„‚„‚ƒ‚‚‚‚ƒƒ„ƒ„„„„„…ƒ„‚ƒ‚‚ƒ€€~||€||x|yzyz|}|{||}}}||€€€€€‚~€€€€{{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚ƒ†……ƒƒ‚ƒ„‚„…‚‚‚ƒƒ‚‚‚€€~€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€‚€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒ„ƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{~~}y|zzz}||~z||}}|z{~~~€€€€€€€€€}}|}}|vrvxxvtvu}‡‡ƒ‚„…ƒƒ„…„€‚……„„ƒ‚ƒ„„„…ƒ‚‚‚ƒƒƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚‚‚ƒ„‚‚€€‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚~ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz{}€}||z|~}|}}~~€€€€~~€€€€~|}}~~}|{xvvw„‡ƒ‚ƒ…ƒƒ„†„‚…†…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„ƒ‚‚ƒƒ‚ƒ‚ƒ‚‚„„ƒƒ‚„‚„ƒƒƒƒ„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒ„„„„„„…„ƒƒ„…„…„ƒ‚€}‚}||{||€}}~€~~}~|||}}~~~€}}~€~~}}}~}}~~€|}€‚‚ƒƒ†ƒ„ƒ†„‚ˆ‡…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒƒ‚‚ƒƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ€‚„„…ƒ‚‚ƒƒƒ„ƒƒƒ„ƒƒ„„…„„„…………„ƒƒƒ}„€}}||||~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒ„…ƒ„ƒ…~‚Š‹…„„ƒ‚ƒ…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ†‚ƒ‚ƒ‚„ƒ‚ƒƒ…ƒƒ„…„……‡‡†‡……„…„ƒ~~|~~}€~||~|z|}}}}}~~~€‚}}|€€~~~~~€‚€……„ƒ„„‚„ƒ†€‚……Š‰„„„„„…‚‡††„…„„…„…„„„„ƒ‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ…€}uyƒ~„„‚ƒƒ‚ƒ„ƒƒ„…ƒ„…†„…†}„y|~ƒ{…ƒ€„ƒ€}}~~~ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚‚ƒƒ‚‚†„„„…„ƒ„…ƒ„…„Šˆ………ƒ……„†††ƒ„…………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†spurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚……‚hzrss|€rƒ~ƒƒ}}~~}~‚ƒ‚|}€}}||||}|||~}~€}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ…ƒ†ˆ††…ƒ†††‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vyy†s„ƒpvxqvtturstvi€nrotvnulwm{sn€‡ym}rsvsvmnwlpylu}}~€}€}€€}}||}}|}~}€€€~|~€‚€€€€€€€‚ƒ‚‚„…ˆ††€‚…ƒƒ„‡†ƒ………†‡‡„ƒ†‡ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoomw}x†pqzprtfu~n{ysoy€}}€{~|€~€€~~€€€~~~€~}€}€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„†……††ˆ„„†‡ˆˆ†‡„††‹‰…„†‡‡…ƒ………„‚…………†……†…†quprsoszy~ƒtˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„qjoyxpkyszozwvvp€~~~z~}|}~}€ƒƒ€‚ƒ„‚€€}~~}~€~~‚€€„‡†ƒƒ†„…„†‡†…………††ˆ……†…‡‡…†„††‰ˆ…„‰‹ˆ†„†………ƒ……„†††††…ƒx‹yrˆz{pp……x…xyks~y{krƒ‡ƒz|m{yyt~€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozls|nw‚~~}}z}{|}}}}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡……………‡‡ˆ†„†…‡††…„……………†‰Š‡…„†…††…††„†††††…†‡‡‡††„†…†‡ˆ‡…‡‡†ƒ‡†……ƒ„††…†„†„ƒ„„†„„ƒƒ„„…„…„…„†ƒ†‡…†„„†‡†„„…†„…}w…„„„‚}~{|{~{||}~}|~}€€}€~~~€~~~~}}}~|{|~||‰†…„†††…††…………††‡ˆ†„†…††……ƒ„…†…„††††…„†„…††††„‡†‡‡†…‡ˆˆˆˆ†„‡…††ˆ†…ˆ‡ˆ…‡††ˆ……††…††…ƒƒ……†……ƒ…„„„…„……„……ƒ††††…„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ‚}€|{|~{||}~||~}€}€~~€}}|€}~~~~~|}}~{|||{{~ˆ‡„„ˆ†††‡†……„††††ˆ‡„††‡†…„ƒƒ„†…„‡…††……†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ……ˆ…†‡†‡†‡†ˆ…‡‡†‡……†‡…‡†…‚ƒ…††„„ƒ„„ƒ„†„……………ƒ††…†……††…„„……ƒ„‡…ƒ‚‚…ƒ„~€€|{}~{|{~~}{|~}~~}~}}~~}}||~~|}€|||}|||~z{{|~ˆ‡‚…ˆ‡‡†‡††„„††‡†ˆ†„……††„…‡ƒ„…„…‡„…††…†„††‡‡††ˆ‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…‡‡…‡†‡†‡…ˆˆ‡‡…††‡…††„„„…†……„„„ƒ„…„†††…†„†…††……††…„ƒ„„ƒƒ‡ƒ„‚„„ƒ€€€{{~}|||~}|||}}|}|~}|}}||||}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††„…†…†…†…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡…‡†…‡†‡…‡†ˆˆ‡‡…‡‡‡††‡„‚„ƒ„†…‡…„„„„„…†††††…‡……‡………‡…„ƒ„ƒƒƒ‡ƒ€‚ƒƒ‚‚‚€{}~}{||~}|}}|~{||{|||}{{{}|{~|{|}}|}}~}|zz{{||ˆ‡‚††††‡††…„…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡ˆˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡†‡‡††‡‡…‡†ˆˆ‡†…‡‡‡††‡ƒƒ„„ƒ††‡……„„„…†††††…†‡††‡††„†…ƒƒƒƒ‚ƒ†ƒ~‚‚ƒ€ƒ‚|~~||}}|}}|}{{{z{|||{{{~{|}{z{~||||}~}{z|z||‰‡ƒ†…†…††…„„……………„ƒ…†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…ˆŠ‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡‡ˆˆ‡…†‡†‡……‡ƒ„†…„††‡†…„ƒ……†††††…††‡†‡‡…ƒ†…ƒƒ‚€ƒ…‚ƒ~ƒ~~~~||}}{}}|}zyzy{|}{{{{~||||z{}||||~}|{{{{|{‰‡„†„†„††…„………„„ƒ„‚€ƒ…‚‚z„Œ{€„…‡†††…„‡ˆ‡†‡……‡Š‡ƒ‡…††ˆ†…‡„†‡‰††ˆˆ‡‡†‡ˆ†„†††‡……‡ƒ„…„†††‡…„„ƒ……††‡††…†††…††„ƒ„…‚‚€ƒƒ‚‚}€~ƒ~€||}}~}{}}|}yyzy{}}zz{{}|}||z{}||}|~~€|{{|~}|ˆ‡…†…‡„†„……………ƒƒƒ€…‚€€}|{„…††„…„ƒ‡‡†††…„†‰†‚†„†††……‡†‡ˆ‰†…ˆ‡ˆ‡††‡…„†……‡…„‡ƒ„…„ˆ††‡……„‚……†…††‡„††††…†ƒƒƒ…€€€ƒƒ€|€~~‚€}€||}~}~{~}||yzzyz}}yzz{|{|{{z{}}|}|~~|{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€€ƒ~~~€yz}€ƒƒ…‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ……ˆ‡‰‡†………ƒ†„…‡ƒ„†„„…„‡†…†…†„‚……†††††„…††……†‚‚ƒ„~€€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|z{{{|}}}|€~}||}~|{‡……††††„…„…ƒ…‚€€€€~€‚‚}~{‚ƒƒ…†…„ƒƒ†ƒƒ„‚€…‡…‚ƒƒ„„„…†‡ˆ‡……ˆ†‰‡…„„„‚…ƒ„†‚ƒ…„…†„‡†………†ƒ„…„…†…†„ƒ„……ƒ……€ƒƒ~€€ƒ{€}}‚~€}~~~~}}{|{zyzzyz{|yzzz{{|z{{{{}~}}€}}||}€}|†ƒ…††††ƒ„ƒ…‚…€€€~‚|~~€€‚‚‚„…ƒ‚‚„€ƒ‚€„……‚€‚ƒƒ„……‡††„…‡…‡…†‚ƒ‚‚ƒ‚‚…ƒ…„…†„††‡††…‚„„ƒ„………ƒ„ƒƒ„‚„„€‚‚~}~~~„~{||€}€}~ƒ|~~}}~{~|{zyzzyzz{yzzz{{|z{|{{~~}|}||}€~€†„……„‡„ƒƒ‚†‚ƒ€€~~€}‚|}~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡†…„ƒƒƒƒ„……„ƒ‚ƒ‚„ƒƒ€€~}}~~|~ƒ~|~||€~‚~‚|~}}|||{{zzzzy{zzzyzzz{|y{}{{~€}~}}}€€€†„„…„…‚„‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„…ƒ‚ƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚€…ƒ~€~|}~}|~ƒ}{~|}€ƒ}}€~}|||}{{zzzyy{yzzyzz{{{z{}||‚€~€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌËËËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFK=8765999<>9?<D:;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937677=;>:=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<:<<98:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA><A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÔÔÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÔÔÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9>CE?<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËÊÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø×××××ÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕØØ××××Ø×××××Ö×ÚÚÚÚÚÚÚÚÚÚÚÛÜÜ×ÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILO@99:4;A<7=9AC>@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÏÐÏÏÏÏÏÏÏÏÏÏÏÏÖÞÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¸ºÑÓÓÓÓÓÓÓÓÓÔÔÔÕÇ·¹¹¸¸¸¸¸¸¸¸¸¹°ŠŠŠŠŠŠŠŠŠŠŠŠ‹‡½æáââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVN<::77>C>8>:??A=>@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÌÐÒÒÒÒÒÒÒÒÒÒÒÒÑÞìëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§£££££££££££¢§ÏÓÒÒÒÒÒÒÒÒÒÒÒÔ½ £££££££££££¥•SRSSSSSSSSSSSKªòëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;?C>6:7>?;=B?9<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÌÌÑÒÒÒÒÒÒÒÒÒÒÒÒÑÝêééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤£¨ÏÓÒÒÒÒÒÒÒÒÒÒÒÕ¾¢¥¥¤¤¤¤¤¤¤¤¤¦—WWWWWWWWWWWWWO«ñêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;?@@8:;8<;<<?:;;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÍÐÒÒÒÒÒÒÒÒÑÑÑÑÐÜèççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©©¬ÏÓÒÒÒÒÒÒÒÓÓÓÓÕÀ¦¨¨©©©©©©©©©«žbabbbbbbbbbbb[¯ïééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB>;=:9;:==;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÎÎÎÎÎÎÎÎÍÍÍÍÍÍÎÏÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÎÎÏÎÎÏÎÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÒÔÕÕÕÕÕÕÕÕÔÓÓÓÔÓÒÒÒÒÒÒÒÒÒÒÒÒÒÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÔØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<8@B<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÎÓÔÐÏÎÐÓÐÎÒÔÕÔÐÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÖÖÖÖÖÖÖÖÖÖÖ××ÖØØØØØÙÙÙÙÙÙÙÙÙØ×ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?79:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÎЦ’ÅÑÒ¹¾Ôœ‚„ŠÆÏÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<>B>BC@=:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÎÒª¬”ÍÁ”°œ±–¸¹¯¡ÒÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?>;7:>9?D>A98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÐɗ™…¥°¦ ‹‘Ó}~¯°ÑÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<=:6?B@C:647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÏѤ°½˜›œ‡ºÔÒ͞žÃÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8FA?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÏÏÐÕ¹š˜Ÿ ÒÓÀ  ÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<>=964:99::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÏÏÐњ ¡¬¯‘¡¹×¯¢©ÔÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:<?>=<9@<<::9?@>=<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÐÐÕ§¤£»žš­›©Ø£¡ºÔÑÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CFCAB8;?<=;<<8558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÐÒÀ¢ËŖ¦Å˜¢ÑžŸÉÒÑÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF@HIGE@<<>><=><756:969;::;8@?:<<9<>=;;:?9?:;9=>=><;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦ÓÔ¤ ¸Ë›œ››­ÇŸ¡ÒÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;557<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡ÈƦ½•‘ª©«¤žÅ´¤¦ÖÒÒÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKLA>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ Ôʎ“—§Ï’§×¹ƒ¿ÕÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<=?GFGKH=657:979:;:<=9>99:8;=>>A>=9<<:=>>:=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÔ¯°³ÐÕ˽ÕÒÑÂÓÒÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?AELLA>775;8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÔÖÖÖÓÒÓÕÓÓÓÕÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEK>>786967899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9699:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EILAALD??;9889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEHIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDJ;AA;<886486987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGJB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<BA<;876797799=?A?<:9@?<>B?:8776=??@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE>;HF89757875898;>>=;89A>=@?A>7596;>AB??@@AB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCEEC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELCA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<<DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGHNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAC?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€iixsg~‰‰xp‚†{w}~…Š½ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€‚wt|„‚}sp€Šx‚yƒÈÞÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsoupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿¼½¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»º¹¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjcmgb\XQPQKTJB:IQ?A7<94:565455688686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸········¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µ¶¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸¸·¸¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶·····¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨¨¨¨§¨©©©§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸········¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥£¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§§¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©ª««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤££¢¢¢¢¡ ŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž£¤¡žžŸ  žœžœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=7789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥¤£¢¡¡¡¢£¥§¦¦§¬¬§¦ œ›¡¡ž›ššœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¥¦¦§§¦Ÿ›š›¢ ™––•š›š——˜™šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜—™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥¢¢¥¦¦¥¦§¦¦ ›™›¡ —““’—šœš———˜›š™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB@DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥¦§¦¦¢œž¡Ÿ—‘‘”—š˜–—–˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;<;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¥¦¥¥¦§¦¤¥¦¦¥¥£  ¡¡Ÿ™’–š™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šžŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡ ¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢¢¢£¤¤¥¦¥¤££¡¡¡žœš•“”˜›š›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œ ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸŸŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::88:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸ   ¡¢£££££¤¢¡ ž›™™˜™™™™™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢ ›ž ¡£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œž››œŸžœœœœŸ   ¡¡¡  ¡  ¡¢¡¡¡¡Ÿžœ›ššš›œš™š›™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥¤¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¡¢¢¡   ¡¡ ŸŸžœš™š›››œ›š›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›šœšš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>98;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤¤¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ žžŸ     Ÿ ¡  Ÿž›š™šš›š›››Ÿžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›ššš›™˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9<<>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœ›œžžŸž›šš›œœ››œœžžœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:=>:?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››š›œššš›œœ›š™œœœžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™˜˜ššš™™™™š›œœœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›š™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š››››œ›˜˜˜™™˜˜™™˜›œœžžžžžžžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ›››››››™˜˜˜˜˜˜˜™™œœœžžžžžŸŸžžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ››››››š˜˜˜˜™™˜š›œœžžž  Ÿžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_^]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜™——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜˜˜——˜™››œœœžžžžœ››œœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±³­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=:F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œšœ›œ›˜™š˜˜™ššš–‹“–™˜•˜˜–›œ—•’‘’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨©¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‹‘‹ŒŽŽ‹……‡‹ŒŒ‡ˆ‹Ž‹‡Œ…†‹†ŠŠ‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VQQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹‹†Š‹‹‰†„†‚€‚‰‘ƒ€ƒŒ†‹‰…€‡}€’†„„†ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹‹‰‰…‚}s}ˆ€~œ„……‰‹Šz}}†ŽŠ†”’‹—”—’˜¡–ž—•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¥›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ‚†‹†ˆ…„ˆˆ‰„‚z||}~’ˆx…‹Šƒ„…ŠŒ‘™””” ššŸ¢­±­©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPEMISWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~‰‹‡Œ‹Š‡’Š‡†‘“‘‘„‡}}ƒˆŒŽ‹ŽŠ‰Ž””˜•œšž¨®²¯¯µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWLO_^\NUUbQDTM;?9<895775795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš˜ “—š ™›¢¡•› ¤£š“ˆˆ‹‰‘‘Ž’Ž‹˜šŒ”š—œ› ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUKTOOJCPK_bXZQ\T`MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ª©¨§¡¥¨¨«ª©¯¡›Ÿ¡££ šž œ”˜”˜  ¡¤ž›š¥§¤©«¯¬¥£¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdWOXKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®¯ªª«¤¡¢¤©§¦©¨£¢››¤¡¥¨£ ˜˜Ÿ¡¢©§ ¢¢®¬«ª§­¯¨¥¤©©©©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_UZNRNPORd\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢šœ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨§¥§©§©¨£§¦™œ¤¦¢¡¡¡¡ ž™™Ÿ ¦¦£¢žž–Ÿ›š¢¢ ¡Ÿ¡¢¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]\PUOWO^ddlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§¬©¤Ÿ¢ ¢¦¡¦®¦¦ŸŸŸ ªž™œ›ª¤¡¤Ÿ¡›œšœ ž¡Ÿžž £™–›˜¤¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvxb_\UYQUW[c^s_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?C?:8:>?C@DA:;>=@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯««¬¨¨«°©¨ª¨¡Ÿ §©­°²¯¬£¢¦¡ª²¡¤¢£«¢¥¤¢¥£ž žŸ¥¢¢žŸ¢˜•ž›ŸŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸ ¡¦¢›—’šš •|wo}yf[Z`_Z\V\hdncnjib^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¢ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£Ÿ¢ª©§®·¶´´¶³¯¬«®«·µ¤²±°›¢§ž¢££›œ—¢¨¥¡Ÿž£›¡š–¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¡™˜¥ ¤§ª©¨ª­¬¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvyjb[_^\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>AE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢œŸª²¸¼¼½»º¿´¯±³µ³¸²ž¶´¹ª¤¢Ÿ —•š—¤ª¦¦¡¤£¤«¦¥™¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨¨«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥¡¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxxxc[RYT__amhukqhiiaYSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶´º±ª®´±°±´µµ¼¼¾¼¼¾Æº¸·º½´°¬“±»¹k¸²ª¦¦Ÿ˜¤¤§¨¤®¤««µµ¯³ §ª¬§ª©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš’–””˜“š˜Š‹‡€€|‚xa^YTai`fsositdidb[LK>:8898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÃÆÂù½¿ÀÀ½¿Ä½¼º½¾³©¥‡®Á·az¾À³¯¯ªª¨­§§¤¯§ª´¼±´µ¨¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`a^^kcbnwuvnl[bQV\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAA;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–••‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±°§¼¼¾ÅÄÆÉÇÅÆ»ÄÀÅÆÀ¹¯½¼À¾¾°¯ž€­¼²^i¶Ãº­¯°µª«¦ª£­¤§±¶«µ²­³­¨®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|ƒjfhakmfnuqruqg^_\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÅ¿ÃÂÆÅÀ±“¾º¿Ãµ»”}ªµ¥^a ¼»± ›±¯¬¤¬®´§ª©¨ª­¬©¦¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|tklndomiqxnyiia\gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿¼»¾Ä¾ÅÈÆÆÄÄø´À·´¼Á¹Á‡{³Å¢aa†¹»¶¬›£·°¦¬´µ¬®¥¤£¨¤  ¥™ª´±¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyz{vnkiguZfrxsyff]d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÉÅ¿ÃÀËÍÏÊÆÄÃÃÁľ¸¾ÁÃÁº}|¿Õ¦dbr±³´ªŸ§´²®«¸µ³¬©£¡­©¬¦­Ÿ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuuefijh]konxwcb``^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÎÏÏÌÃÇÆÈÉÈÈÉÇÅÉÇÈÇ¿ÅÇÄDztv½×¤ecf®´··À¾¾º½º¼º¼¬­¦ª»º¹·À²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqocagvhjitmxl]d[V`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÌÐÎÇÌÉÂÂÇÂËËÈÆÌÊÎÅÆÅÃȪlp²×Ÿcc^µÄÁÈÌÆÄÁÄÇÁ¼¾´°°°Á¾¾ÁÆ¿¾¸¶Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`jjvlieuntb]bTWUSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<9>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÄÇÈÆÒÉÁÃÄ¿¿¾ÄËÈÊËɼ¼ÈÇÉÍÈÃÈÉÉÅÅãeiŸÒš`a^¾ÏÇËÎÄ·¿¿ÀÀ»º½µ³³¿¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrpfefcjdbjmno^Y\VVNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾƹ»Ãº¸¹¼¾ÁÇÁÆ»¹ÈÉÃÅÄÀÃÁÂÁÃÂÃÁœdc‡Çž[^cÄÍÅÈÐÁ®½¾¸¹»»¾·´°¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfadbacddjbgc[ZZ\YQOE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶¸´´µ¿»½¿¹¾ºº´À¸µ·²®º»·À·¼ÊÒÀ»ÀÁ¼»Å½»ÁÄÄ£idx½£[\kÆÅÀÀÉ¿°Á¿»¸»¾¹µ·´¸¼´½¸µ´°³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|yˆ}qc`bchjggiei^VVTYOSLF8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“““˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´µ±°µ·µ»Á¸¾¹¿¼¼·´·¯®·µ¹¿»Áي²Â»ÃµºÇ·¶¹»À¦vrw¦hi€ÆÀ¿»Á¾¹Æ¼ÂÀ¼Å¸¶·´¸¶¶»»¸¶´·ºµ´¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒxqmeefoielhXXNKKKRILHC9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’™”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿¾¼²­¯¬±°·¼·»½ÁĹ··¶µ¹¹º»¿¼ÑÆv Ì½Ç·¹¸®·µ¾±…„‚“•{™ÅÀ¿¾½¼¿ÉÂÇȾƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~‡|knpgpksfbm`\TIKJDJBCG?:;8><7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘Ž˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼¼À·ª­¤®°¸»²½¾»Ä¶µ¸µ·À¾Ä¼ÂÄØ­r{¶ÉÏÂÀ¸¯µ¾¿ Ž„}‡„„™°Â¿¾½¼ÇÆËÊÄǽµµ¶Á½»»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†€rflintnxcgb\cQKTHEECHC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?>??FD@A?>:7?@CC?@=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼ªª£°¹½¼²¼¾¼Å¸±¸º½ÇÊÉÂÈÉҖop©ÒÑÌÊĵ»É¯ˆxpe}y…os€ˆµÄ¾Á¼À¿·ÊÉÅÆÀ¹½¼Ä¿¿¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtolltkln_c^`aNIM?E@?DC;;::;:8;<:9<>::>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´»ÇÒ¹¾¼Ä¾·¼Á¿ÈÏÆÈÊÊÀ„pr¢ÍËËÍÊÆÅÁ•pbYOls{WXhr™¿ÁÀ¿Ä¨¤ÈÄÃÄùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{zˆzmmw{_pc[^__TI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA??ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸´¼¶»¸®Ü¾¶¾À¾½´ž”¢«¯¿¾£vtw¢ÐÉËÈÁÃæx\MFA_opIEXa}ªÅ¿Á²ˆ™ÈÃÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}‚znsxsgp][^]YRFDCMIAE=H;;59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘—žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯··²µ³·¹¼»¶»»È­l±Í½µ¹À¼¤vjglho|‘”nty¢ÑÆÈÁ¸¿½‡bLBA:ThdE:NXh’ÃÀ´ržÈ¾¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸¸¸½¹»±¶²ÈÀ»¶´±°·¬³©°­­´·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y}vlu{pni[_`YSPAFHGK@DCH<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿš›œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹ÀЩrƒ´½¶µ¿ž„hY_^KQZZkor}£Í¾º¹´½´xP@Qe@K\YG9GS\{¼¹œri¬¼µÁµ¿ºµ®¯­°½À¹ÏÊÉñ°µ´´½º¾¹º»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰|‚zsuvwnq`_f][TJ=??FF=FCC9:5;99><<::<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹ÂË ‚v‹¢°³‘f`eUY_KJMOSls„¥Ç»¢£­¸°„E@p–QERQK:JRUlª¡dr¶¯²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³»·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtwrl_ca[^OHB?=HCFMC@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·¿Å¢†yu¢Ž[RAXTGamYSGIc£ªÃƙ„£°¥BG{š_BPQN9SZRa‹i_‰·¥¬³°¦°­¨ž Ÿ¥­¶µÂ·¶´¥¨«¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´·¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wo{ourmc]fX\]RNNA>JBAJI@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³²­¶º¯­¼³¸¸Â°Žx‡ŽhNIAkWBOu…™pMCV}°»Ñ®zv‚¡¦FHhwXBXX[<VcRZoh`_¡³ž¤§§£¦–™™šŸ©®¹¬««Ÿ¥¨¤«®®§¯¬¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmtil][jT]\PMHDFLBFNF8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹º¶¹»µµ³¸³’ŒˆƒwUE@T‰VJJSu‹b@Y©¹²Çϒglƒ„KFSUId‘Ÿ©ž—{QV^\Wr¯§¡ž—˜¡•’•—˜Ÿ¨®¤£¤ ¢§¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬ª¯£¤£¡© ›“Ž“’’™–š¤¥ Ÿž§˜•’”™ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wrxhtsndT`cW\QNLH@HQDMC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯²º§˜™–hL?`€jNIIMgšVGY­º±¯Òºr[adQEPp•©¥žšœžŸTPSS”¯Ÿ§–›——“–Ž—›¤¨  ¢¢¢¥¥££ ž¥ ¤¬¤¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›©¨««Ÿ¦£›£œ•Œ“—•–˜Ÿžžš™¦—“’–¢ ¥¢¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦ ˆxƒ|vzcwln\QhTPNGPMLBOQ@>;>49:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¤¬¨½Á©¦½aB\£}OZIKaK[‰fmsŽ¯µ©¼Ò—UOOPn¢°§œ•‘Ž—ž¢ŽSI\¥¤¨”›–—Œ—‘—“˜¢ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£ž™—š«¦ª±£¥¨ž œ•“‘˜–•˜—Ÿ˜›™›¤™—”–š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’}|€uv}mk{dhUQcMJHGORMJNG<E@<2?859;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜——–¡¨¬®¶·º¹º··»®¨ ¡© «ÅÀɖNBvkQqLPagwp_`k™°°®Æº]>`”¥ž˜’Œ”•——›Ÿ¦‹Pr žš¤———–’‘‘“š—› ¤ªž¡¡ž¦§ª¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¡¤¡›˜ž¯¨®²«¥ªª š˜˜˜•“–š“••š–›——˜¡žœœ—›¡šžš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}wx|dyy`bRU`HIJKSTIRPL9?A67<65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—“’œž¤¨®­¬««¯ª¯©ž—ž¥œ¤ÆƆWRMdŸ^n}uyWQkc^jglxŽ´¯´Â„¡Ÿ™”—™˜”‹Š¡—£™š—˜™”™˜–›Ÿ¥¦© ¦£ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§  £±®²°´ª²®¢™œž¡™››š˜™›”–›–™œ¥¡ š£¡šœ™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ Ÿž ¥¡žž¥ ¦™{|vvsh‚le[SZZMQJOOULSLA7>C78=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’‘œ˜¡ª¢§ ž§¡¥Ÿœ’›¢šŸª£yWsurti_rnXY]^dgYb_h¬®«°¨£Ÿ¢ –“› š˜–‘’ž›¡¥›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬¨¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½·¾°¬±®­©ª´±°¨«¨²µ·³¸­²´¤ ¥Ÿ¬¡¡¢  š˜–– ››˜¤¡ ž£¡ žšœ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚|xujwu]lZR`HRUHFUVJBLG=KH8F<77;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“Ÿ™¨®Ÿ§žœ¡žš™’˜ž›¡¡ ¢~o{i`cWM[RUHJOUPGRSJ™¬ª©¤ŸŸ™’‘“˜˜–•”‹‡Š”œž—ž™¦Ÿ ¨¥±ª§®£«­¶°´²±®¶¸½Àº­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«¯±¹·¼¯³°µÁ¼·½³³µ¢¬¢©¨²©«¨§¨š™žšª§ ™§ ŸŸ§§¥¤Ÿª¢¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰…„~vrmivmhm\X\CWNJGMGCFM<>L>4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜™ª ±¢·¤°¦Ÿž—˜•™žšœ£Ÿœˆ_V_f_ULLD:>>BC>>CSx©­©ª¥ŸžŸ¢£žšœ›“’”“˜”…š š«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶º»ÀĹ½»¬¯§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¹Â¾¸³»ÆĽü·³©³­ª³µ¯³®ª¯£«§¶±­¢°¦¡£¯±­°¤¥¯£¡ š¡§¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¥ž¦™›¢¤žŸ›››œ‡†{trkktrqhV\QFTHDJPI?EA4FH95;>6;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž  œœ˜šŸ šŸŸ“{``f^NDE<JEH<?:6N~ª³§££¡ ž¥«¥ž—œ”‘™˜”ŒŠ†ˆ†xmˆ ¤¢«¬´¼¶Ã¾¾³»ÁÃÂÅÀ¿ÂÆÆÅÃÈÂÀÅÇÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌÌÌÒǾ¿À¾ÇÆ·ÄÊÉÃÁƾº´ººµ»·°µ²ªº²®»·¿»ºª¸­«ª¸º´¼®®¹£¦£ž¦¥¢£©¦™›Ÿ˜š§ª§ ¡¡¤˜”£–”™‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ„}zqkchoxkeZ[FKLEDSMDBE7:?;549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ²²¸§¡¡«ª¡œž¡¡œ™{ri_TLD>K`‚seB=\Ž®¬ ™››žž™———’ŒŽ–—“Ž‹‚ƒ‚wrqmp¦­®´¹Å»ÍÇË¿ÂÌÎÍÌÇÉÑÌÍÌÇÉÅÅÌÑÒÕÎÓɽÀ¿Ã»ÆÅÈÅÑÓÍÓÐÓÓÌÊÂÅÆÆÊÈοÈÑÌÇÆÇÅÁ¼ÃÁ¿¿¿¶¾³®¿ÀÃÃÇÄÇÄ®¿¸²¸¼Ãº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›Œ™‰•˜› Ÿ£—žš““‹•…€ytsebgrof^ZYCNLDEPIDC@55589B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>8;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›¢¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¤¨¬­ª £žœž•hd[SHC@@M§°œƒ ²­£žœŸš—–”’”–‘Œ‡ƒƒˆ‡ƒ€€yqroly¤¶º¹¾ËÁÓÒÓÈÍÎÑÓÑÒÑÐÑÑÍÎÎÐÅÎÔÕØÒ×ÍÆÇÉÌÃÅÊÏÊÓ×Ñ×ÒÕÖÓÔÈÌÆÌÍÉÒÍÎÓÍÅÈÊÊÁÆËÇÉÈƿó³ÈÄËËËÏÆÊ¿¾¿½ÁÇÄÌÌÈÉÀÿ­¯³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›•Œ†‘‹€zruvgcgvidVWQDMF@IQB=B<:22A<E<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<A?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­³·¬®£ž£¢¡›`RKHDC@FX¶Ò¼²¯¦œœœ ¤¡š”“•”‰}wpkebhqoq{…Š€upnqtp…³Ã¾ÅÑÐ×ÖÖÒÖÍÔÖ×ÔÓÑÓÔÔÓÏÑÃÐÓÖØÕÖÒËÉÎÑËÆÍÒÊÒÕÖÙÕ×Ó×ØÎÒÊÏÑÌÏÐÍÓпÈÇÊÄÌÌÌÎÏÅÆǶ¿Ê¿ÒÍÌÏÆÉÈ¿ÄÃÈÎÍÐÑÏÍÊÈ͸·»¨Ÿ¥«§ž˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„|xsvpc`drb]R\IJGAEIJ>;A8=4586;86:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÁűµ¨¡¤¥Ÿ¢¡YI?ACAIS|²­¦™”—Ÿœš  ž›œ™•‰wic`__`_^__]blutppolrqu’ÄÈÆÔÖ×××ÓÖÐÕÔÚÔÔÎÏÕÔÔÑÑÌÑÍÓ×ÖÓÕÐÏÒÓÑÉÓÑÈÐ××ØÑ×ÒØÙÔÖÌÏÏÊÍÒËÎÐÁÆÃÈÆÎÍÑÑÒÉÌÍÀÊÌÆÓÏÌÎÈÄÊÇÇÈÌÊÔÔÑÕÏÒÌÓ¹ű¥¨µ®§›¨¬¥²¨°³¬¬““ŽˆŠƒ‹„Ž™“™‚…Œ|zqstmacim_VP_JJCFCRM?<>54:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><??=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯­ªª«¦®·¨«·×ÔÕÙÙÑÎп¼Ìɶ¾®¦ª¨¡£«gC9=>GZƒ«§Ÿ—•—™šœŸ˜œœ’}pecb__a__a`_``_`fnppnkorwwœÌÁÒÕÓØØÖÙÑÒÒ×ÏÓÎËÒÍÕÔÒÊÏÌÓÖÒÑÖÍÏÕÕÑÅÑÔÊÐÔÕÖÎÒÐØØ××ËÈÎÄÉÏÍÊÌÀÊÀÈÊÍÎÐËÐÎÎÌÎÏÈËÐÐËÎÊÂÉÇÉÌËÌÒÓÍÓÑÑÐÐʽȹ°®»¸µª¶°­¨¸­³¾»±š ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…ˆzvopokadnpaW\ZIFFDMXE;@=33<<87865;>@=9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ¤§Ÿ¸¶µµ¬¤¬®¾´°ÀØÒ×ÚÜÖÎÍÊÃÒÏÁÀ°©¬­©¤°zKJE?Z¡›•“—›žžžœ“–—”ˆk^^^adb```a``a^__^\bmroostvvy¤¾ÌÕÑÖÔÓØÖÎÎÔËÎÎÅÎÊÒÒÏÇÎÍÍÔËÎÓÍË×ÖÐÌÑÔËÌÐÒÓÊÎÑÕÒÕÕÊÀÊÂÅÌÂÈÉÃÌÃÅÈÊÊÏÊÍÌÐÍÓËÆÈÏÌÈÇËÅÆÁÆÊÌÍÐÑÆÐÎÍÍÌÏÅÇÁ¸¹½Ãýù²²¾±»Ãĵª˜¥¢™–‘••’‹”š‘”””‚‰†yqrkmg``phYXhVLFLIPQB;C>;67:8::57==@;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÄÂÁ¿»µ²±Ç¸ËÕÕÙÚÛØÌÌÏÈÖÕĵ¯´¨ ®“xrv{‹•šŒ—•“‘‘•–•‹|eabb`]^acb`__`aa`_][]grrqrspmry¤ÆÓÏËÐÏÓÔÊÅÉÉÆÆ¿ÃÆÏÎÇÅÇÍÊÒÈËÎÎÆÑÒÐÍÌÔÊÇËÎÏÈÇÏÒËÑÏƺĿÆɽÂÇÉÎÅÂÈÀÇÍÈÄÌÊËÏÈÄÄÐÈÆÂÆÈÄ¿ÁÇÌÌÌÏÂÊËÈÇËÐÄÅÇ»ÇÃÈÉÂÏÁ½¼¿°ÁÉƹ½ª°²§¥¢œ˜›£™—™‘•˜‰‚wotdk`^fpa[W`GHHGIMTG?J=64355==48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ¼ºÍÍÆÐÕÕÙÚÛØÐÉÏÏÑÓȶ»»­£¶|fƒƒ§¬“Ž–…ƒƒƒ}„„~s`[^^^`^`cdc_\]^_``_[Z\akrrookloo}¸ÑÈÉÊÏËÍĺÀû»ºº¾ÉÆÂÃÀÃÈËÉÈÊÈÁÅÌÆÈËÍÉÄÂÊÉÁÂÌÐÅËÈ¿¹Á»ÆȾ¿ÆÏËÿûÉÇÈ»ÈÆÅÊÀ½ÂËÆÅľƽ¼ÀÃÅÌÅżÀÊÂÅÇÒÅÀÉ¿ÊÉÆÈÆÐÃÃÆïÄËÇÄÊ·¿¼º´©¬¤¥˜Ÿ˜¬£¡¥›£ ›”{wrtfiZanlZ\XRDLFBGDLDFS@54334?=3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ÊÏÑÌÇÂÃÆÍÎÎÌÕÏÕÙØÙÏËÒÍÍÎÈÁµÃ¾±¯µk_y¦Š’–†z€……vxurp_[[]``bcdded`[\]]_^`[YZ\borokilposÆ¼ÉÅÌÀÆ°¶º²²³²±Â¼¼¼º¸ÁÁÁž½¹½¿¹ÄÊÅƽÆÀ¸»ÄÉ¿ÁÉ»·»»Æÿ¼ÁÍÃƾ¾µÁ½Ãº½Æ»Âº³¼ÅÄ·¿µ¶¾¿»ÌüµºÈº¿¾ËÄÁÆÂÅÉÆÉÆÐÆÂÌDzÇÉÃÎÍÁÅÃÀ½³·°²§¨¨¹°¥­°ª­¬”zvwjdg`hocV^YJFJFHJAEBEI@9:648854;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÅÂÄÈÎÒÊÊÊÇÍÍÎÑÈÐÆÕÔÖ×ÍÊÏÅÉÅÇÁ¹Å½«­¤_et‡“‹ˆ‹„x††~„{ttc\\]^``bcaadeb]\[\^\^]Z[\^hsqmggnory½ÌÀúÀ¸®°±§ª­¬§¸´·´³³´»µ¾²·°µ¯²¼Â¼ÁļÀ»µ²º¾À¸Ç¹´»¶Á¼¸½ÆÁûµ¯²¶º¿´Ä·»´«¸½½À½±º¶°¶º³Å¼¶®»¿µ·´Å¼¾ÃÅÀÃÅÆÈËÅÀÆÆ»ÇËÀÏÊÇÃÆÂ÷ý½¶¹¾Ç¿¬µºµ·¶Žytxggebkn^V^`FKHHJFBDAEE?<:565633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÍÈÅÈÍÌÐÌÍÈÊÈÊÉÊÄÐÍÒÏÍÅÇÁÅÀ¿º·É¶ª°˜[hqŒ…ˆ‰zx~††ww|sh]]]]_`_`da^cec__\[^\]^Z\[]_lpnhfkmnr|¤Ç¿¹¸µ°«­§ž£ª§ž«­³­ª¬©´®·±³©®¦¬³¼º¶Ã¹ºº±«µ¹»´Âº°À±¾¼»¶»Ç¹Â¶­ª¨°²À¶¸½°°§²³µ»¼«®µ¦®¶¯»²°ª¹°­»®»¸»ÀÀ¾¹Â¿ÇÃÅÀ¼ÆÂÈʸÅÇÆ¿ÇÄúÄÆ»ÆÉÌ˳¹Â½»³‰svvkiablhYXW[ALKMIEAC?FA:9:995854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÅÎÒËÃÅÁÅÐÇÍÁÃÆ¿ÄÄÃÃÊÂÉÊ¿À¼Áº³´µÃ®©°‘\j~’‡Ž{x}‰…z{„€wn^]\\]_`__dcadcb`_]Z[ZZ]ZZZZ\enohfgiknq­¹°µ®¦¥¨§š ¥¡šœ¥¬®¤¨¢«ª­«°¤¦Ÿª­µ¶±½¹¯·¯¨®¸´´¼¸´¼¯¸¹µ²¼Á²À®¥©£«±²³¨½ª«¨«­­´³¦¨­¡¤¯©²¦§¨®¦¨·¬±²·ºº¼±¼½¾¾Ä¿µÂÁÇÈ·¿ÀÅ·Äÿ»¿Ä¾ÄÈÌÊ¿¾ÄÀÀ©‡strji]aocWVXPHYRSKFFE>>@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÐÏÌÃȺºËÁʾ»É¶½Ã¾ºÊ·ÁÃÁ´¶¼¶±¯µ»­¨«“elˆƒ‡‹€{}~xt~|swe_]\\^_`^_ccab`a_]]\ZXY[[YXZ\_fkfdgehjor…©¥«¥ œ¢¥”ž¥›˜‘¡£ª££ ¥¦§¦­ œ¤¦­²°¶·§°¬¨ª´«´º±¶¶®¶º²¯ºº±¶¥ ¤ ¦±§«¨¹ª¤§§¨§²­ §¦Ÿ›¤¦¬žŸ§¤ ¡±­­¬²´³´°µ¼¶»ÁÀ²º¾ÃÁ²¹¹Ã³Á½¿µ¸¼½¿¼ÂÇÄÃþÀÄ ƒxplbf_ko`UY^HNgOTGEKF<=?=:;;825536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;=:6676788666;::;9:;<859<:>>@;Èµµ½¸ºÀº½¶ ž•¡¦º¶«³³»³ÄÏÉËÂƸ¶ÇÀÌ¿¸É·»Å¸³Ä¸³¿À¬µ¼²¬¥¯³­¡£’iq†…†€|yusomjjipi^`]\\\^__acb````]\[\\XYXXXVX[^_dcbegggjmo‡© —–›¢–œ£™–Ÿ¡£§œ  ¤¥¢§ž›£› «°­±¶£©ªª¬¬¤´¹­·°¬³µ®³µ®°ªŸžŸ¤¢²¤¦©¸­¢¦¦ ¨¬«™Ÿ ž™Ÿ¥š™£œ›¯©«§ª¬¬­±²¸¯¸¹»°¶¼¼º«³³¹³¾´¶²±¶µ¿¶¾À½ÃÁ»»½—„zsl_e^ddXTW]IW\KPGIJGA<??@;?<04535:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»·ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÆÏÈÈÀÆ»»ÃÃϾºÇ¸¸¿·²Â´±»¼«¹º±¢ž©«§—žm~…†xrmomkb^aff]]^]]]\]_`abccba_\[[ZZYXXWWWXXXZ^bddeffhikq§”••›˜›¢—–‘œ¢¢¨žœ¥§¢¥œ ¡›™®®®®² ¦¢®«§¢µ±²²¬¨¯³§º³¦¶ ¢Ÿœ£¡­£¢ªµª¢£¦ž¥¦£–™ž—™› š—œ­¢«§¤¤¦­«³´ªµ°³«²¹´¯ª¯²²³¸³®©¬®²¸±»¶º½¿·³±”…yuf^e^[YVSZUK[QKIEHKIB=?AA@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½·½¿¶¾¼¿³¥£˜¥±Âµ¶½­´¸ÂÌÈƿŶÁÀÆηÀĽ³¹¹³¿¶±¹»¬²´­žš¤©Ÿ”šxƒ„xoqtqhechdc\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXWVWadecdeddhjv¡œ“••—— —™•— ž¡– ¡©¤ŸŸ©œš«§¯°«›£¤¸ª¡ ®¨¶ª§§­±¤¸°¤· £›™™ª¦¡š¬¸¯¢¡¤œ¢Ÿ “”¡”––›˜—–—œ•Ÿªž©¤¢£ªª°®¨´«ª§­³°¥«®³±°¯®¯¦¨¨²­±´°¼´¹·®£”yud^aVYXSRTKM^LOKGGLLE=A><B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾¸¼®§¨£ª»À½À¹®´¸ÁÌÇÅÂýŸÈ˲ÁÂÁ­¼»µ»¼µ¹¹°¯°©›™¡¨”‘Š‹€€|wqilrtphhedfb\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWWV[bcbbcbcdfi–“–Œ’””›™––œ œŸ– Ÿ§¦¤¦§ŸŸ¦ ª¯¦Ÿ¢¤·¨¡¡¢¨´¢¥¨¥°¥±®¬´ž¡••©¡¢”­±±Ÿ¢£ž˜›“‹¡”‘“˜˜“——˜—ž§œ§¡¢š¤¥¥«¤¥°§¥£««­¦©®¯®«¨ª©³¦¦¬¯´±¯¼µ±¯¯ ’zwrea\Z]XNLRHRaMVPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8847763321./2556;:8;7876<;:;;A8x»»±µ½°»±¸¬ž¥§­·»¼Áź±¹µÄÉÉÀÃÆÅǶÅIJ¿ū··½¶½ººµ²«¬§˜˜Ÿ£‹‰t‰ˆ~vncafihfgifjm`]\[ZZZZ\]\[\^_\ZY[YYZ[WUXWTTVUSURU``_`a_aacej€”“ŠŽ”“”•–—¤™ — ¥¢­¦¥¥££¢œª«¥šŸ¥±ª ¡ž¥«ž¨¢ž­¬©©®­¢¢¢•˜£›œ«©°œ ¢Ÿž—™“Šž‘’“–˜˜”œ¡£¤¡¢• ¢¤¦›£«¥¢¤ª£«®¥®²©¦¥¦¦´¦©¨­³µ´¹º¯©¬žŒrqo`[WVVRGQOHZ[ORJTKSLEFID8;;=<8667:9;:976977:;:=<<6;<8>598:88659:<<97?<9678452121..1426:8698598989;9@9{µ´­´»²°«²­¨§¯¹¹³ÀȺµÀ¯ÅÈ̺ÁÊÌȵɼ±¾ÃȬ±¸Áµ»À»´´ª¬¦•š›œˆ€rˆƒ{tiijlgjkmkjme]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURSOQY]\]]^___bdmŽ„‘‡‘š“•“œ›£œ›¡©©«¨¬§©¦¤™¥¯¥•™¥¯ª œ™› ž¯™œ«³ ¥¦Ÿ£¤¡•“›––’©ª­šœŸ¡ ›”Œ™ŽŒ‘Œ‘–•¢ £œ£•› £¡—¢¨£¢¨« «°¤­·¥£¤¢­­ª¨«¯³·³¾µ²«¯˜…tsh[YYSUREXLQ[XMTNPLPQINIB=??A?=75799<<987:79:;<=>;7;;:=67:;8976989:6:=99576570141-+/434988::8::748=8?9~³­§³¶®¨¨¯®›©¨¬·¶¬¼Ê»¶¿¬ËÆŸÁÎÏȳĺ·»ÂÈ°­¸¿·¼½»³µ¦© –—˜—‡zt€vwnmhmmmpggigd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUSSNPQYZZZ]]\^_`d~Œ‹‹Š’—‘—™¢ › «ª¦¯¬¨°¥©šŸ­ •–¤©¨˜šž®—˜¨ª™Ÿ”¥¡ž’‘’‘“•§ª¥š™™žž–Œ‹“†‰ƒ‹’•‘ ž¡¤˜•Ÿ•š¡¢ž”›¥¥§¨¨ ±±¦±¼§Ÿ£¬µ«®§°µ°¸µÀ±­±«‘~rsbVTUNRJGVPRQLLWMJLNRGMKACFDC>A75889;9:7::7<=:;@>:9;9:?759:9876958779;85576661320-*.102877;99;8948;8@8³¬¥±·ª¥¢±«ª§©²±¤¶Æ´¹º³ÊŹºÁËÐʱ¶¸»½Áñ¯±·­´³»³³¢£œ——”ƒwkglnqnqjpkdege^ZYZYZZZZZZZ\\]\ZXXXYYWXWUUTRSUSVURNNNRWXYYYY\\]aj€zu‰‡Š—‰””˜›™ž©› «¦¦¬ž¨š ¦œ“Ÿ£›——…„’›£•£–––ˆ¢››”‹ŽŠš¤§œ••—›‘’‡”Ž‹‹€Š’’’ š ¢–”˜™•¢¦™™¤¦¨¦¡ ´²§²·¡œ¢·¬ª­¤²²¦µ¼µ¬«±£‰ysm]NQQLOCMNNPKFNNJJNMQHMJAGKHHC=858889:;69:68;99><8:>9;?8789:886857688974577820301+)-/12876:999984988A7w¶¦¤¶°¤§¤ª¥ ¨¦¥³ª¢²Ãµµ²³ÆÆ·ºÃÊÌƳ¬º½´·À¯­©°ž¦­º¯­Ÿ™š•”‡{ƒn__frpuqinieghj_XXXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQMMKLSWWVXXXX[]aosvp„ˆ‚ˆ€‘„‹”‘”ž¡›œ£¢¤™¥—¢œ•‡™šŒsƒ~Ž—–†‘š”ŽŽ{™Œ‚‰‰˜Ÿ£ž“˜–…‚”~~tŠŽz‡“›šš’–Ž££Ž‰š ¡£¤›¢´¯¬¯­Ÿ˜¥¸¦¦±¡°®œ°»ª©¯ª™ƒwscVMROPNCSNLQLBPQHINRMHJJDJLFJJ=749888;;69;7:<9::;79?9>@79:<89764445874312585/0102)(,-12764789::65:87A7x·¡£´¨¦¥¨£¦¥§¦§³§¥´Á¸°´°ÉÄ·¹ÁÎƽ³¬ºÁ«­Ã­§¡¦’¦¶¬£Ÿ•–’~x~eWV_gfighncjhgb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTRMMJHNSSSTUUVY[]ilrl…|tNXrƒ—‡Ž—‹”‘Ÿ˜•”–•–‰€“Š_;Wo|Œ”‰€Œ’Œ††sŠ…—y{†““ƒ•Ž‘ƒ†}“xqp…}‰‘—š™“‹‰ˆŸ˜ˆ‡–žš¡ —§®©­©¨ž–­³¢¦­™¬«˜¨³¢©­£“~rn`[NSRWLDTJPLLFNOIELQMKOJILPFII=7599999:7:;:>>8:==7:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9y· £­¡¦¦ª §©¨£ª°¨§´Á¹°µ°Ç·³½Ï¿¹¯®µÂ§ªÅ©£˜ƒ”›°¢™—†”‹‡}su]PLRUYZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MORMKHFHNQQMPRTVXZ`moi{‚tQB@•’’}‰•„Š›Ž–•‰’ˆ†•†y‰`JQnx‹’„}„Š…n~”xuvx„™oQˆŠ†{~x”vgw†ˆ}Š‰•‹‘’—Œ„Šˆ•„šŒ‚„’š–ž”¤£¨©¥¤žš°«¡¤¤‘¦ª–¢ªœ¢¦¨‰umf^[HQQSMIUMSILKOIHFJNLMTKQPOFIC<769:8:;;8:;8>?99>=8;<6;;478;6775344696/3/.125221/,')+*,4833979:99::::?9w¶›£§Ÿ¡¯¡§¨¥§¨°­ª¶¼¶··³Á»¶§ºÈ¸¶¨¨µ¶ª²¼¦ž•‰“¨–•Š~Žƒ‚}xpnXMKMNOLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDDINOhYNQSTUZnƒtw~ji\U‰”‰t‡|…Œ“‚’š‹{†€v€xsovptŽz~Š«…yzhv{Žprmx‹’xz€{€vrr’whu„„„…{•ŠˆŠ‹€„‹Œ€”ƒ|€˜”œ–‘ž©žŸ  ©¥Ÿ˜Œ§¤“¡ –žŸ¤€rha\]JWPRHJXROJLMRJJJLPHLQLRTMEHA<78;99>=:;<98@?::>=7==79937785675251472/2.,//200/-+(().1272198798775:<;7v®™£¢˜œŸ´©¯©¥­¬°²ª½´²»¸¶º´±Ÿ·º²ª¬©¨²¯¡š‘”ŽœŽ‘v†x|vooiXKHIHGEHHPTTTWWSTUUUVWWWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQQSV^uƒ|xfw—˜}hyvx€‰}„˜’r‡|w{ok~­|sŠ{†’}tfv|†lohs}‰Œˆ€lyq}qmvqhq~ŽpC‹„‚ƒ…wwz‹…}Œ{u~Ž’˜Š’š›£–™šž¡œ–Š¤›Žž—Ž–˜womebZXXUQJSUTOPNPVKNKNOJQNHOOLFD<;79;::?=9<:99??;8;=7<9999266856633611224.,,-..-0-+*''*.1362/876966527995y¦— ž– ¦¯¬®«¨©±¯±«¼¸¬»¾¹³¬§›°§¬›–œ¥©¤ —™Ž…’yˆŽ‹Šuq|mupjmjXKFGEA@CDILLMQRPQSTTTUVVWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNOQTX]eprmˆ§ªÀ~uyc|xo|yˆz}‹†omŒ’ytxjj€‚q–‘‹~–€I“˜nhw~‚licly…’†ksl|nr{†imps‰„†{}~{vots…‚yyp|ŽŒŠ”ƒ–—˜š’•—™—–Œƒ‰ž‘‹’†–€ojnonXVXTRQYORTTSXUMNHNKMNKCHNGE?:89;99:><9<;::=>:8:<9?868727565541432/024*+**-.+-*(*(',-1250,5567485HA895w™‘›™šŸ¥­°£¬ª¨µ¯®¬´¿«¼Â¿¦¢™•¤—ž„‹”¡¡˜˜‘“‹sŽz€†Œ…totkqldljYNEFC@<>>AFFGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_IMOORWZQY\`§ˆbšitzepmz‹‰v‚ˆ†tlš‘ts|jkMy…’‰„Žg1v†sl~~ƒtfet~„„…€filukq|hqq|n“Ž|s}|qpnvm‚wyujy‰‚ˆ‰„–’’‹‘””Ž—€yˆ—ˆ†Š†€ˆwkkoheXQZWYY[MPUVYXNIHEJJHGB@FDCG=998;9:9<:9;:::@<9:<98>787715234533645031.**+),,++)(+'),,226,,5775478iO8;5n’ˆš‘™–¤¨®ž²Ÿ§»¯«²°Â±»Ãǚ–”™‹Ž†y„˜”Œ†q‡‚t‡Œ†zprpoodpf_TFIC?<;9:?@ADCEGILOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOOQVLAIQIb¯³ r|xl}mrƒ‚…z„††yr¡•tx€su”‡5q¨Ž¡¡„¢„vp†|‡|sŒ­‰€ggbjnrmpƒuioXupŽ›’wlz}mrnp€zsvnbvƒ~†€…ŠŠ‰‘‹‘Œ‹ŽƒuxŠŽ€~ƒ€}{rppl`[\^\YXa_RN[ZXWLHJFJG>BABG>CD=;97=;:;;9:99;:?<88=:8;66651121253474531./,,+)*))***)(*)+/3DM2166643<vR7=7b’“ˆ–‘¤§ž¯•¥µª®±®Á²»ÁƖŒ”€ˆ}n’‰ƒŠ‡…u‚„l•ˆˆ{txxlwnwci^IPG>@7449;;;=>@BEHLLLLNPQRUUVWXYXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL7CMRSDJ†v€||v~mwˆˆ|~…ƒŒ~v¢™y~†…™„›œa†ªŸ‹ƒzwˆ~‰ˆsŠ—ƒz]drtz|wŠmhjbyo†‚znwt„zptywkni]w‡|‡|‡‡‹’—ƒ…Œ†}q„ƒ}uw{|‰wpsteg_[[^T\g^WQUX[UGJJDLG?F@DC>AA=:97<;;=<::99;;=>79>9985653244004645554-,)+('''&(())((+++/00Uq=23331E~W4=9\ŒxŠ€”Œ’œŸ¦‘ « ±¨¯À±ºÅº–Ž‘”‡z…vkŒ‘‚}Š„ŽŒxƒ€s¡„‹}}p€~zgvkRWL@E211367688:<>AEGFGJKMOPQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMORLKT]YRJi„ˆ{‰y|r|Œz}‰‡~—‡v¡™ˆ‡’”¥¬©H†®¯¯‹€“Š‚‹„’¨‡€˜˜Š›tm|†‡}Žhghxn…‡‚…q„†Gl€wryvhmk_w}ƒ‰ˆ…‹z•›‰‹ˆ‘zu‹v|xmow}ttrl[]][ccXgf\UOPVYPDLKFNICFCCA@CA=978:::;;:888::?>6;>7585773344236656768;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|}‰…ˆ‘–˜’—¡¬¡¦¸¯³¼³—’‹˜‹}tp‰’~}Œ‚’”}†~†¤‡ˆ‚ˆ…x‡ˆ~s„x_cWKB60./23123668:=>?BEGHJLNQSTUTTVUSQOGC?80,#‡[>?84.]–ps£UFIKMNPW`YpZ\^j“‡•€„‚…‘“~…ˆ‘š•‚¡¡˜•›š¥­“š»±§»Ç苌¡¥”‰‘|qƒžŸ‘œv……Šˆihoƒ€tŒ‡„‹q…‚w‡{v…}nvuf€”†‰‰‡ˆ‡¡ª¢–‰Ž˜z‚‰zyogkx~z~rjd^ZZ]j]af`YOKNWRQHPJDNGCJDB@DDA<:87=<:<:88778:==8<=68656623444576867<BB?<8:>CQ^e\G2'&,,--.1(?‹[.310Oƒ_4?;nupfxƒ{€Œ€‘ŽŠš›¤¡¬¦«¯°—‘‘„¡”„xwŒ”|’†’•Š€’›Žƒ€Œ‹‚‰ƒ‰mpj]BA4--//./02234778;=?BDHJNQRSRSTTRPOHDB<87/9D><<63.l“—MPHIKKKNV`cggmušš““‹Žšˆ“‹  ’£ª¥£¬“¨¶¢¨Áîǯxº”š|¡ž™„“…‚¡Ÿ“˜’„‹…™‘–lpu‰‹‚–Œw„qm…Š–‘ƒ…ˆrˆ¡–‡“‰Ž–¥µ©›•¢ƒ‡“ƒ}kjk|€sa]c^Zfk\lk^WKGOSQNMLFIPCDMFACEGB>:97=<:;:987767;:6=:785456345566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYp‚pu‡qv’†~—–š•žžœ§ ©–“˜žge¤š~„’‘y€’ˆ’}Š„˜’‘‚€€‹‰…†„ˆ…xx~gMR>/..,/.-/000212457;?CENPRTPQQSQNPIED>;<:CF?><752<?R5HHHLLMNR^oŠ|s} œ¨¥¢™¡—¢•Ÿ¨ž¨« ¨¬©ªµ—«¿«¶ÈÈ·ÉÑϾ› pi«©Ÿ„“’…œ¡š›™§‘‘‰•¢ššxz~”˜’¡’–˜”ž{w•’«³ˆ—Ÿ}”žœŽ“–™¤¢¦¶°‘™¨ˆ–ˆlsr||qh`\`^bgc`hg[REJKPOIJLFFMCHLFFCBGEA:85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Ppu`n}awŽ}{”ŽŽŠŸ’—ž–›ª˜žªBD}‡‰‡˜x‚ŠŽ|Š†Ž‚€‰ŒŠ„’…ƒ†‰€†w_bP460-1/,.00//..0015>AAMQRSPRSURNSLEE@<>=GG@A@8662<9;FHGIJNOQYm†w•‹£§ª´½¸¤®¬¬§¨´«°¶²²­»±³¾œ³Ã¬»É˷ÿ¸¥£°²¬­ª£‹–˜…¦¦ £—¦™¢ª¨¤ˆ…”¤¡ ª¡¤©œ±‹•£§·»› £°“££ž‘¤¢«¯­³µ¢”¤ªˆ™‰’Š•yz~…~g`h\eb]dc_ff_ZOCIHTOFHLFJGEFHAKFCFFA:87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLicWjpXz…v“…ˆ‚›ƒ’‘Œ’Úȝ–sV—ˆˆœ|†ŒŽŠŠz‡‚‡‘ƒ…€‹…†‡’†‚„‰†ˆ‡‡qna@E64<2/110-,+-1.-3?DAMUQRSUUWUN[PGGE<>>FHCD@8;<5C;=FKIGHROPW“ „®£³ª±ÁÇê³Å¶¬³¿³¸¾¶¿´Á¶»»¤¸Æ¨¶Éǵ¾¹´¨£´­±±›™’šŸ‰¨¯«¥”vŸ¤—¡«±³™–ª­¨®¶»²º¬¯µ¢±¬±µ¼·µ®µ §§£¨š©°­²º¸¸§›¶©Œ¥Ž‘“Ÿ†x‚ƒuYadVeaac`af_[TJDELUQHIJDIGEA@@KDBMF<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AFWQJL[ZQcdWyuq”}…‡“v…€Œ{¿»£¼‚´”“›„ˆ’‰‰y†€Œ“‡„Ž‰Ž†€†‰…Š‡‘zxn]V@EM<6:46AB764//6CHCQ[OQUWU\VO^UIKJA@>GKFED;>@7D7?BJJEFWTP^¥®£±´Ã¶¸ÁÌɶ»Ä½³³À··Áµ¿°·t±³¦ºÅ¤°Æ¹±³±´¨¤µ¶ª± ¡–›¢’¥°®¦­«§¤˜ ¬³º¢©²º´»¾Ì¿ÅŽ½³Â·º¸¿·º·¹¬¬°¦±ª­¾°½»Â¬™º¨”®——«‰}‚|jWbaWjejeW[dYVTIGGLQGCHIAHD>?BBK@@MC99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FRLALRWTYUZvjp„Ž„nzsy‡b¸¡™£‰•“–“”“–’‡†{†–Š„Šz|Š‡†|ŠƒŠƒ•}xzueO\dGEL:Qca[^SF?;HPDZcQQYXZgYT``MSPEA?IJHEFA@C<E6B>HGJLSZT]“¯¸µº¹É¿º½ÉÌ»¼Á¼·µ»»·½´º±Æau²¥±šžª½ª¥¨«ª£¢²µ¡«¨ž•–Ÿ˜Ÿ®¥§¦¥Ÿ£”¢¦±´§²²½¶Á½ÓÉÊÓÆÂÅËÁÊÃÀ¾½¿»¼·´°¹·¶ÃºÅ½ÃÈ°ž¹ª¢«Ž¥¨¶‰€q_bb]Wa_hfRXaVRUIEENKA>GD=KB=B@=F>;H@796379>489:57045/26389374426?8@>GKRTSQPOQQPJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKE@IMPRLQ]gllq…slrrsˆÕÀµ™ •˜™‘Ž—’––Ž†‡}†ƒŒ–Šƒƒx{‹ƒ‡{‹yŠ‚—t}zkepuY]\Peeb`ed][XW\MdmURmm_n_XgeUYUKDAKKHFIHHGBI9D?HKTTV\Z[’¹À¹½·ÆÀº¸Ê˺·º¶¸¹²·µ´®¶¶™du¨œ­p^¡­œ˜ ¢›¤žª¥” Ÿ”Ž–˜—¨Ÿ¥Ÿžšš„¤¬¥ª°¬·°½¹ÔÑÏ×ÏÉÌÑÌÏÎÊÆÀ¾ÂʽÁ¼ÁÀÄÄÅÊ¿È䤻°´¯›«¹¼šyl]`\Y^aYccQ\`SPKCBEGE<@E>BHB@D=:E>=J?47535;=468977022/24169775555D3ELM>51/006:477@IOI;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODR\Yi_p—’”olouu‡³¬¡¡Ÿ‹™œ™Œ•‘›’…ŠŠ~ˆ‡Œ‹‰|„s{Šƒ…{‰t‰†•s{xkmu{hreilifjih`fihlZnt—­¤¼ˆ‡g[oh]ZZTHKNOJKQKTQHLAJGKP_^bfia—·Ç°¹³»¾µ±Äǵ°¹°°»«²±§ª·¬¶§›§šOšŒŽ –‘¦˜¥•Š““‰‰‘‘ž›¡—š•–‡žš¦›¬¯¨¯§³´ÔÔÔÖÒËÏÔÕÎÓÏÍÅÂÉпÊÉÊÉÒÇÌÍÂÐÒ¸°Ã¼Ä¹¥¶ºÄ¢‚nc\\^XaXYeZQ]WOOBBHEBI;AD>AG??B7;C>@H=46655;:687654/10146278875367C5B8?-0-1349=97,.,1;FK=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYSeWs˜‚hqoyyƒ ªž¦—Œ››—‹Ž•‘šŽ}‰‹…ŽŠŠ‹‡|„‚pˆ†{‡rƒ’‹~qxukqx~q{mxslipmcinpxiw|~Ë¿Âߧmcxnc[a`JPRUNY^P^]MPNTQUT\nnv‚r—­¸¬´§°¶«¬¼À±«µ¦¤¸¦«®¡«´£Ž±®š˜˜Œ‘“‘„Ž›§’œ‰ƒ‹„Š‰„‹ƒ“•˜—“›‘œ˜™™žž«¬¤§¡¬­ÏÒÕÑÍÌÒÓÔÐÔÑÎÈÃÔÑÈÍÒÓÓ×ÍÒÑÅÒÖÅÀÎÇÇ辷Оzne]b]W`S][OPTPNH>AFABE<@B>ED>@?:==<<JA45465<888664412/03526768533;=<E=@11+/249>5901022-2DN3)/3.32=N238C}_2A†tD:==I>@CFH<VRMO[u†…Šwlwp}~¡žž¡‹™““ŒŒ“–…y…‹Šˆ‘‡‚{r~€‡y„u…“‘‰ovrks|{w|swqk€srhoqzyr{¾Ë›~Œ²ƒvr„vhaj]CZZ[WfdXekSX]]`d^cx{~‹™ª¤¤¡ ¡¨¦ª°¸ª¥´£¡­¡£­¢§±Ÿ‰¦š”’‘‰‘Žˆ”‰k•¢™„€…}‘ƒƒ“–­‹••™Ž…’—§°¡ ¡¤¤¨ÈÎÏÈÂËÑÔÑÔÓÎÓÍÆÖÒÌÔØÖÖØÔ×ÕÉÔÚÍÉ××ÑʬÄÃˋsob`_XTZS\PJGIIJ@;:;EBD<BD>HB?BC;;9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/--;R017/532FD28>nb5=tM99@I<AD?A;PLFKYp€u}hsxr‚‰€•”…‹–‰ŠˆŽ‡x„”™Šˆˆ‹‰~‚xs{}ƒ‡wz‡‘–€ƒnxpmuvx~t…|ym‡vtn}v„uy{¶Œ<A‹Æ¥~|ieVICfcechjdox[_fiknin€ƒ‰‘‹ž —˜Ÿ£¤¦²¤¤³ ¡¥ © ¢±œ†ž’’’‹Ž‹†ƒ„~œ›Œƒ„…z”~‚©•£Œ’Š—’‹}—Šš‘ª³˜š›§œ§½Ãƹ¶ÆÍÒÐÒÐÌÒËÉÔÎÐÕÚ××ØÔÙØÍØÛÎÉÚÚÒÕ¿ËÌ´xvnd]YRVQZVFGJJEE=:79@AB:HD@ECADB;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?1*(.BS39254/7K75<`bA<svV87AH:?C><9QECJTlnopaqqs†|—‘‹~‡’‚‰†…Š‡|x…––ˆƒ‡…‡z„yqz{„†uz…ŽzŒp|oozq|qƒ‡nŽzuw}|‚u|‡ˆ°tY©Â¶Œ’‚pnb=^hrpqpnxweioruxr{‹‡Ž”’›• •‡Œ“› ›ŸªŸ ­œ¡š™Ÿ¥žŸ¬™‹šŒ‘‘„}ˆ‡ƒ…‹Ž ™“ˆ„‡~m™y„˜†ˆ“ŒŽ”Œ†{›ˆ“®ª”•—ž˜§®µ½©­½ÆËÈÉÌËÏÈÃÑÊÔÖÙ×Ø×ÔÛ×ÓÙÛÖÏÛÚÑÖÉÔ˕y{hh[YPRT^HCEII>A>=7:=?;>H=?AAADA>>:86DB755479.566435532323647553457EBDCEB56<FNSM[nfcnskaV>,4LG865434BF4=W_hLux^8;?F<<B<:9D?CGRk_mdbfkv€ˆq‘š€z€~‚‚„~ƒ||„—Ž‡‹~††€w‚yn{{‡uz’ž vu‚tu}t€„o‚o’„t|…zv†{‰·Æ¥ÂÉ·–›wpeNfczw†¢‹xyw{ƒ|„vn”–”•˜ƒŠ–š——¦œ— —Ÿ“’—£™«–‘Š‘‚Œ…‰ˆ…‘žœ™‰…‹†˜z‰‰Ÿ—ˆŽŠ‹‚|¡‰‹¼¡˜“—šœ©¦¥®Ÿ¨µ¾ÀÀ¹ÇÉÍÎÅÍÊÑÖÖÕÙÕ×ÛÔ×ÙÚÛ×ÛÚÙØÎÜƆzyghe`TWVUMKDND;<=<9:<>9=@6=?@<?><9867CA6455=80665547745613854564567HH=DJE7925;H>;::7IP]ZRUXK9T>;95327I8=NYMHxxd5=>C==@:6:>>@EQ_Yea][htzyl‰’wvz‹|~€~|…{~‘‰„…z„ˆ{u}tn|}†~t~’‘žƒ’|†~xŽ}yŠŠn‚š€t˜…~‰…|~z©Ã ¼Œœ£œ}‰„}‰sŒŠ~s¦šœ˜”…{‰„hGq¡¤Œ‹’…‰‹’•š“•‘—Œ•Ÿ”¡”’Ž‹~ŽŽ‹„ˆ’–šŸŸ‰Œ”’ž‘‚‹€¦™ˆ„Žƒ†„€¥†Š‹¸˜‘•–¢§¡ž£®¶ºµ«¿ÆÊÐÈÇÌÏÓÒÒØÒÕ×À×ØÙÛØÚÚÙÙ×Ü·xxwkidW`[TPOHDLB==>99::99;=6?>><=9:;;37D@8378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWN<MTHN?96333>C;[X>5YypZ<<A<=>8589?=DRSRX^UXfmmmiŽŠqryŠ{z|{ˆ{|{‹‡‚~uƒ†yszsm~…}w…›¡›”’€‹ˆ˜‡€œ’n‡¨…z ‹|‘Žƒˆ„œ~š‘Š£¢Ÿ¤® ‹‘‹…‹’†Wr­‹Ÿ«›ƒ˜›Ž\‚¢‘‚ŒŸ“•Œ‡ˆŒ’“Œ”””ŒŠˆ–›•–‘‹’”†€‹ˆ’‰Šœ–™££†’–¡‹ŠˆŽœƒˆ€ƒ‡…¤†Œ³˜’”—¡¡ž™’œž§±¸¬¥¼ÂÇÍÇÆÏÌÏÌÎ×ÏÑÔ®ÖÕØÚØÚÚ×ÖÙڟo|tgg\]XSWXC@ID>>>:49:;7:;:3;;?=>7;9:19G=:37=@50677255?65;55858:57735HR7GOK994=EJB>1FCLB98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:<@;BQKKSYPTcbxmb~’ƒomw‹xyz|†|{w†„sp…‚zuvvt„ƒ…}’¦£Ÿ¥¢–‰”—‹Š¨—rŠ²„§‘„™“…™‹¢– ˜“‰›¡’©¯Ÿ‘”ˆ•‹n·…šÄȲœ¡¥›œ˜–‘²‘d¤Íǖ…‡‰’“”Š…ŠŠ†–š›”“†•—„‹™ˆª——¤£ˆ™ž–›‰‡——Š„‡¥‰“©š—“–™¡™Ÿ™“›£³´¥£¼Á¾ÇÅÅÉÈÉÂÊÓÌÍÔ¨ÒÑÖÖÖØÚÔÓÚ΂rhc_]^NJTZBAGD;A=837;<:8=649:<:82?9:29I:>67BC32:96264>=4;>6949;57944KQ<JQK9A7BGI@64JELF><88ETA7>\86214:;E`XAFathLcZ>5;::5;:>:EMFHRWSRBcFu‚}|m~ˆxz~zƒ~vv€ƒ|ln‹y|xx|„‡‹}Š£³§£ª²¡–§Ÿ¥¤–•®¢ƒ¸•’³™¡ Œ¥›¯£¤˜§–§™­¯¤—”–”‹˜™– ÀŽ¤É¸«›¢¦­˜‘›œ²†…¨¢œ˜…ˆ‰Ž•‹“ˆ†‡ˆ“˜”Œ‹““†”˜†„‘œt‘™³–—¥¡ˆœ™“Š‹—š‰Š–Ž†}Œ˜ž‰œš™“˜˜ ” •Ÿ›¡±®¢¤·¾´ÅÇĽÃÿÆÍÊÉÒ§ÎÍÓÒÐÖØÓÐØ»ryv\`U_WPHINEBCE5>:76:?;<7=42669774=5<5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=89566=:JFDGN[\YIf`;H„‹zzn…†z|„x€…~px|}|orz}{x†‹‰†ƒ’§»­¨²½¯¥­³³¨£¢°¬Šš´ž£¸¤•­¤–©­·¦¤£Ÿ™©˜©£¯°ªš˜œ”•‘—Ÿ—™»»­É¡i¶¸«°”˜ž£«“—¾£^ª²‚‰Š”‡‘|ŽŽ}ƒ†Ž”•ˆ‡“—Œ•‹Œ—˜’™´—–«ž‹›”’’Œ™›Š’ž‹‰• ¡”˜š“œ™ž”¡ ”œ¥¯¨¡¥³¸«ÂÈĵº½»ÅÇÈÂÑ¡ÆÉÍÍÄ×ÖÑËÓ¡pzh]YS^ROFD><CAB8?874>F<<6<35345454B3::BM:A;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPeGb`bpI@‹Š~s†‡}ˆu‚Šƒm}}|pw‡w‡{Œ†Œ™ªÂÀ¯½Æ»³´Á¼´­«³¶Œ¨²®®¼ª›»¤¨­¹¸«¦¦¢¡££¨¯²±«œ¤˜›˜—ž¢¥¥’£¹®¨À»¬­²¹¥¤§}ˆ‡œ¬½°ƒŒŒ‹ƒƒ‘z‡ŒŽœˆ‡—‹•—”‘š–§š±š‘¬Žš’Ž”–—Ž‘ ‘‰•›£¬”–”œž” ›˜ ¡•šž§§¤¢¤°²¦ÁÇï°º¶ÅľͧÇÃÇüÕÑÍÄʈtsb\Y_[MJBL@EG?A?B;:4>A<=5=6>333241A17@BN>G@CNCA=C=;86CC5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GE?CF\fF`igZ][“ŒŒˆ{‡‹†ƒŒu†Šo~|‚q~z•z‘””˜“•§´ÆÉ¿ÂÌÁùǼº¯«¹»—²¶º²À®¥À¤«¯»¼ª­«¢¢§ª®´°ª›Ÿª›¡›•Ÿ°´§‹¢ººµÁ»«©œ²¥¤¨”…ŽªÃĤ‚‹‡ˆ„†•”zƒŒ‘Ž‘¡ŒŒ”‘‰—Ÿ—“™•˜¦ ®ŒªœŽ–’‘”•Ž•‘¡”†—Ÿ ²ž”š” ¡™¤Ÿš œ ”™ž¦¤¦§¤¯­¥ÀÄµÉþ¶Î²Ä¾Ä¼³ÑÊȵtym\X\iSLHDLKKJAA=CD<5AD;:3=8B332263A05IEM>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBfZMe\fTcj™—ŠŒˆ’†‰y†”r€|x‡‚‚y¡–¨šš˜º¾ÈÈÊÁÒÉÊÂ̼Á³­»¾§º¿½¼Ä·¬Á©¬²»½ª°©£¥£¬­³­¶µ Ÿ¯ž¥¢˜£´¼©›¨¼Á£¶¶¯«’°­«¬—†šª¦¥‘‚Œ“¥•‰€uŠ’y…’žŸ“”‹”£™—œ•”£ŸªŸ‘¥šŒ•–ˆ|•’’£›• ¢œµ¦ž—¥¤£¥žž¦˜ž•—›¥£©¨¢²¬¨¼Àį¥³·ÌÀ¹®Ä³»¾Â¸¬ÂÃÂÀ˜myaXW\[KKMJFDDIBBACK:4DH9;4<7E.12352B26SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQF7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>jH_XaZddVž—Žž’‰Š‰Ÿ“„w…•ˆŠ•¡š®¦£˜Â½ÈÃÇÅÓÍÎÍË»Á·¯º½´¼Ê¼ÃÁµ¶¼­³¿¹¼®¯¨ ¨§¶­­©±·šž­¢§¡«··©¥¯¾Ã±½¹³§ª´³­®––¥¬¨ ‘Ž’±Å§•Ž|‘•}‡‘˜Ž©™˜“““•“¥ž“™“¡£¢œ˜Ÿ™‹žˆZ–—’–¥™e˜£ž²¥–¢–¬­«§›Ÿ¦—˜—™•¡¤©¦Ÿ¶«©º¼Äµ¥´µËÁ¸©¶¬²º¸®¨¸º½¸ƒlnZWTUNFJSNK?BHEDHGG95FM;>7>AJ.32025B55PVN<LFKRLOHGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|hW;=@BFBqFiIRebLF¥”œ–¡—©–ƒ‡¦“ˆ‡‚œ„ƒ•”Žš¢Ÿ¯¾®¡Æ½ÅÄÆÆÎÎÎÒʾ»µ±º»¼¾Î¶Ä½·¹·²²µ³¸³¬¦œ««¸ª¨§¯°—£®¤§¤¤´À°ª¬´¾Â¹À¹³§¸´¸²®•¥­¯®¥‹“•¡tÁš~—™…Ž–™Š±•š™•’“™™¦£•Ÿ›–š©œ¡ š‹–`J–œš•š¥–T–°Ÿ¯œŸ¥”¯¯¬¦š¡¦”“™™Ž §¢™´©ª³¼¼»«°²ÇÀ¸¥««­±±£¡²²´¤qnf\ZNPKDPPPQ;GJIGHBC>9KU?A:=EM07544:B34NWO<JKNUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@CAF3>58JKCA=C;4EA:A?>H@5*B52,>c]g:35tde@R7&#3}iX;:BC@=QEWRsbWFHª—™ ¢¨¯™‘—‡‹§–Žˆ’…Ÿ‡„—ž š£¤µÈ´©ÆºÃÃÇÊÈÈÌÍƾº³®¹¸ÀÁͶȺÁ¹¶º±¯®²´§£›ª³´ª¨¦­¬™¤®¥¤¨¬º¿¨«¶·¿Á¿¾¸²²Ã±¹½¬£®µ¬¹¦ˆœ˜¦›v¿ …™Ž“™™Š®—¡œ›—•›Ÿ¡©ž¨ ™šªš¢§ž˜‘ƒnv’¢š•¢ž­²£«•¨ª˜«®¥¤Ÿ¥©“’™œˆ•œ¢ž—±¦©«º¶¾³²­¾¹¶ £§¨¥§œœ¬©©Œcea_RKMGHNIUL=MDNJKBCD<QU=AABDO18=77?B75UXN?HNQYSPQTJQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW;:=..R`MUHe^HE«”œ¡Ÿ»¯™”žŒ“ª›‘’“‰«‡¢žŒ¤­”££¶Æ½´ÁºÂÂÇÈÅÂÍȽ¹²¯¹´ÀÂʵƱÁ¼´º«¨­¬°£¢™ª´º¦©¦«ª¨¯§£ªª¾¼§¬¼³·½Æ¼·µ¸À±½À³©µ·«¾¥£—‘¢Ÿ¼Ÿ‰š ™–žŽ·Ÿ©œ¥£›œ¡š¨¥³¡›¦œ¨ªž™•”›‹—‰Œ¥¢”¢ž ´¯¥¥“°«™«¬žž¤£©‘•• ƒžŸœ–©¤¢¡´µ»µ­¨µ²³žœ¢¥š—•™ª¡žwa\_]JHFGMQIMEFGBRLIAEG@VRDH=AGQ1;B7:BF79\YKALPTUSMWRNUJD@JJNO9C?5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-1:g\FCCœpbGE§—¤ŸŸÃ¬›—¤—™©œ–ššª––§¦•­­™¡«¶Ä»¾·ÁÂÀÇľÍÇ»½¹²¯¸³¿Ãȵ¿¯¼¶¹·¦£ª¬­  šªªÄ¡¤¨«¦ž«¯¬¢©¨¿¸¦­½°·¶Ç¶µ¹¸¿±¿Á¶´³´¯¾£—£–“›”­ ‘¡¢¥££Ÿ¾¥©©¬¡›¦Ÿ½¢™£Ÿ¢©«¡–•ž“ž‡…“ž¤ µ¬¦œ•²§™°¨Ÿšªž ™•Ÿ„Ž¡š›“¥¤š˜¬±¶²ª¥ª­¬œ˜  ’Ž–©Ÿ”hcYa]NIGJNKHEDIA=PIA<GIH[ROK=HOU4BF9>HG5Cb[KCNRUWVQXTRUH@8QQPM:G@4CHQSIC;C>GVKC@O>K<06;GF>;FA56?9:?9;15D0-,0Mv\4KZ5,MnW<-=)#zbQ5CKQ9oRF<KxecWL¢š£œžÅ¬¡Ÿ¬œ® “£Ÿ—¥ §©«—¶°¢ª²µÄýÀ¶¿Â»È¾Êȶ¸µ´°³³·Áƶ¾°¸´¹µŸ¦¬ª«ž¥£Á¥ ©­ ¤©­¯¢¦§½¶¦±¼·¶µÃ²³·¹¾²ÃÀ·¸®³µµ£¤•‘“ ­ ™¢©¨«£šÃ­©ž¬­››ž™¦ ½¢¥˜««¬¦¡™šŸ’ž‰ŽW–ž¥¡ ¸ª§“˜¶£Ÿ³¡ ›¯—žŽ™”‚ŽŸ—–Ž¢¤•¦®³«©¢¢¦¥••œ˜‹‘“¤Ÿ‰beZc`LHJJNFEAFK>=JB99JKN]QQI=LV\9FI=DMI8Hc\LCLPSYYVWOZ^IA=WQIK?H@5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+w`S6SZkWsHE6=ue\KNžŸ¡™žÃ§¥¢³ œ²§“ª¤ ¤Ÿ­©¬»°¨¬µ±ÇÄÁ³ÂüÆüÄʽ¯±¶­°´¯¿Åµ¹±°¹µ¬š¨°©©š¥¡§Â¬›¬±œª¢®°©¤§½·¦·º¼®¶Ã­³³Â¿²Æ³º·¬´¶­ª¢¦–•”£¬¢ŸŸš¨«°¯¯¼²¦ ©©™™˜“¢¤¸ ¡¤“¯¯¬¥§Ÿ’¡ž•ž•š¢Ÿ§´¦§˜´œ£¯šž›®‘ž”—”š€’¡–ŽŸ¡“‹¦¬°¥§¢œ¡ž’’š“…‹’œž€bf[geJILJRAC@IG;;G?99NMU^RSJ>O^]=HPBLLI9Nd]LELRTY[SUO\bHA?ZQAHAKB7FELKN>;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<v]^?[U^fr@8<H–weA4Ÿ¤Ÿ› Ã¨¤ª²¡£µ©–²«¦¢¤²¬®©»²¬°µ´Æ¿ÄĵÀĽÉĵÀȵ«µ¨°¸¬ÀÄ´·®¬¶¹¥™«±«ª˜Ÿ¦—­»´›¨°›­Ÿ®´²§ªº³§º³·²¸Àª·²Â¼´Å§¾®­·µª¨¬¡—–‘¦¥¢£˜˜¥¯¸®²µ¶ Ÿ¨¤™••“¤ ·¢¥¦–®²²¦ª¦¡ž›šš–˜¨Ÿ ˜¡ž¯²¢¦—®™¥¬—šž¥‘›Ž“—™…–Ÿ”Œœž”‹©©ª¢§ ™ž–ŒŽ™‚†–‰”Ÿydi]kjMPMNT=CANC::I@77QO]^RVQAW`\BJSHVKH:Ue]NFON[W[RPQX]GAB[PBG>NC9HGHNP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1[bZ33806p[bH05JpiVCWFŒyfC;¤¤¡¦¿¦¨¯¯ ©µª¹¯ª£ª´·±°¹·¯¶¸¸Å½Ãǽ¼ÃÁÆÀ¸ÁÆÁºª¶¤­»­Áø¸ª­±»¢•­°­²–¥§ª¹© §°ª °´²ª©¶µ¬¼¬²²¹·¬¹°Âº½¾¦Ã«°·¯©««¦ž˜˜«¢¢ ‘˜¡±¯³«±º›œ© ™–’—¦¡·©¥£¢¯±´«²¨«Ÿ›  ›ž¥œ¢–£³°šŸ“¥š¡©š•¢Ÿ–˜‰”˜“–—“ˆ›™”©¨§Ÿ£›—›“‡Ž™‹~–…›kimalnWPQZTACET@;;IA7:XPd^PVWDY^]MLRN^KJ>Zd^NHPN[UYPKSWZI?DXPDF>N?=IGGQPB=CFBM?:2D?77547?=95E4+75/251.-.,1>*'+=\p=>1.1e[d@1647gY`F(?8l}h[V;‰{cC=§Ÿœ¢©½¡ª°ª£±¸©¥´²«¡­µ½¯³¸¼º½¶¶À¿ÉĹÄÁÀÀ¸Ä½Á·¯µ¨«·²¼¿¿µ©®±¶ž—«­¨­–§¨Ž§»Ÿ¤­³ž«¢±°³¬©¶´µ½­¯±µ¬°µ±ÀºÄ¶«¼¯±¸«­ª£±¦ž¤ª ¤—™Ÿ³ª³ª«³š§›š• ¦¤´®§¢­­®±§³­²©¤œŸ¨¤ž•¡˜›¨µ©—™’’Ÿ™ž¡ž‘¬Ÿ˜˜…•˜‹š“Š–—š—¦¥£ –•—””…{’ƒŒ–flrgpr_FYfVDCMXDZ9HB6>]Qh\NY]G[^]NMRXdJJC\b`PKMNXWXPJVVWM=EUJEDAM?AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,+%2+*5K1.'__aU150=`V^8)C3YU\gK5ŒzfL@¤™ ¤¬·¤¬©¥®®¶©¯³¹¦¦°·Å·±·¾ÀÁµ´ºÅ¾ÌŹ¿º¿¹Ä¸Á¹²µ¬ªº¶»¹¾µª­±¶™˜§«ª«›¬««½ž¬®±£ªŸ°­³®®¶±¹·©­®±¨µ¯³»¼É²ªµ´±´¯®§¡³ š¨­ ¥••š™²£­ ¦¯–¡¤šš’¢¥§²©¢§²¬ª¶¥¯±µ¯¤™­§š˜Ÿ™™¬¸£—“˜œ¡˜—”¬Ÿ”“™š–Š”“žš¥¢¢ ™•‘“•z‹†{ŒŠƒ‹’knxnv{`EajYIHY[={JGE6AbTi[M\aJ[]ZRRRb`LKE_``PLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`U`/5(C^Q\.*B/JGP[H3cYUKD™– °¨²©­¥£®®µ©·´¸£«´·É»´»»¿¾´´·ÃÀÌȻü¶¾¾À¸¿¼±½®§º¹·¶Ã·«­²¹•—¦®«§£±ª”¯»¤­²²§§¢²³°±±µ±¸³©®«±§¸¯µ´ÃŶ©´µ«°­ª§£¶ŸŸ§² ¤”›™”²ž§œ ª©£ž›–˜¥¥¥·§¢²´¬§±§­°µ¬¥™ ¬¨›œ›”©¸œ”ŽŽ‹™œ¢˜—¦¡Ÿ–ƒ’–œ˜––ˆ——›¨¤ ’•–v„‡{…„Œnqwv|~\Kel\KNc\?b{GI8GgWe[L^bMXYWTXTi]OOHa]_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANHf27'FaLV%-B.=EMQ<3rkJDC™¥®¥­®«§¤°²³ª·°¶Ÿ«µ¹É¹®Á¼Â·³±µÂÃÎÅ¿Á½´½¿¿º¿¼³Ä¨©¹°¶¶À½¯«³³œ §°­¥¦°¥ž²¶­«²°¬©¨´¹¬´²µ­´¬©¬¨¬©¹®±±Ç¿¸¤¹¯©­­¦¨­°¦¤¤®£©œ›š°™¢£¢£¬ž¤ Ÿ¢ª¦¦¹¥¬µµ¤©«©¬¯¶¯£ž£¨ª› šš’¤´š‰‡‘¢ –”ž ”“…Ž“’›˜–•ˆ˜“•™§œ ŸŒ’w~Ž…||}‡ŠŠrtr~}}[Rdo^NZf]FD–[H;NmXa[M`bNVWVWTYg^QRLcZ[TKGOTSNGIVS\N;P^IBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3Bc;6*HdHJ+:I?3BIS,>k=HH›ªª¢ª°¤¨¤³´±´µ±±¡«­¼Ëº®À»Ç±´­´ÂÂÑÅžÀ²¾Á¼¿·¼Ä§¬·¬³¸¼À°«²­ ¤§­©¨¤°£«±ª¯¬°®¯®«³º§¶°²©²©«¥¥¤¯º¬ª±Â¹µ«¹¨¨¨¬ª¨±¥ª¤¢®ª¨¢ž›¢¬•¤˜ž™¬¢§©¢­¦£­¬·±² ©¢ «®°¬žŸ§¨©™¤˜™ §˜†ƒŠ‹Ÿ¡‹Œ–œ†‡• –˜•‡–““—¤œœ‹‘‰~ˆ†|w‡…‡tsr‰vl_Y`ncQsq\K;„|F>WuX`ZOc\NUVUWP\b^SONhXWVKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*35>10485(5/*,.30;),,'%234$,2-860)(1<]J0.IgDF8<B05EKX1@”[?MF•—­§¢ª²œ©©°¶¬¸µ®ª¥«ª½É»°¾·Â¯°¬³ÄÃÎÎþ¿´ÀÂĺÁ´ÉĬ¯·­²¸¿¾³­®«¥§ª°©§¨±¥´®«°®­±°³¬³º¤¸³¬¬®§«Ÿ¢Ÿ±¸«ª­º·¥µµ£©§¬¬ª­¡©§¦±²£¦¥¡¡¬–ª¡”› ¦ž¤¢«¤­£Ÿ§±·­­£¥¢›©ª®©¢¥¤¤˜ ™–˜“‚‰…œ ŒŠŽŒ™‹„˜¤›’‘›Œ“’‘”¢™›šŠŽŠŠ|†‚ƒzt€„‚~twŒ¤‡yk^`ngWe‡dN@g’LDbyWbXReUMVUUTO\]aUKMiWVVIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*49?./463)4+*,+.#4.-+&(+79*&6+<-2,&06WZ.0JgAA<<C+:JO^4D†@HHD—’¯¤£ª°˜«©­µ«¶±«¤«ª©¼ÀÀ¸¹³»µ¥²¯ÄÉËÑ¿Á»¹À¿Â¹ÁºÁÄ®²µ±³»À¾³±®¬««¨¶ª¥­°«¹°©±±¯²­¶ª¶µ§´¶¬¬¤©ªœ£Ÿµ³¨¨¤´´ µ­¡©¨«©«§ ««¨¹¶©ª©©¢© ­›’©¡ ¤¢¦£ªž¦µ®¨¦ª¢£—¥§§ªœ¢¤£Ÿ™˜Ÿ‘Ž™Ž~‡Œ‡„žžˆ…‹‹Ž„†•£šŽ›‘’‘’Ÿ—™–ŒŠƒt†xuƒ{xˆoqggqx\`sˆjO]˜VHmxUdVRcPMUTUPOX[bUHPiTVTGPYUI>IHOQPxLMV=<KD?@A<@CUC9AK=5;E13;97*4:=+-341*8**+*,)*(/*&)%3;,$2)2021%/2Qc02?f=NX?C,>LT_/Jk6PE;•Ž° ¥«­š«¥­®³´¯ª¥¯©©º¾»À±®¸®¡µ¯ÉÇÈÑÀ¾½»¼Â½ºÃÁ¿¿®²²±µ½¼Â±²³ª³¨¤µ©¥­³³¹°£­¶²¯²¹ª¸®ª®µ««žª¬Ÿ£ ¶­¨¡Ÿ¯³¡´ªž¨§ª¤«¡¢¬­¨½¯¬®­¡§¨Ÿ«™¯¡˜¢¡¨§Ÿ¨›™ª°©£Ÿ¬¢¡“¢££§˜š¨¥——™Š‡•ˆ}…„„¤–…‚‚‹‡Ž‘„„” —ˆ‘“‘‘”—Š……xt}uxy€{tszi‚‡¤ui^el‚ugˆŒ}RXp^JxsSdSQ^MMRYfNLVYeYFSiRR?BNQaQ:IHLSIqQLS;<I?;<=;@@W<<>H73CB15:93-5::)-31--6)(+-,52#2)',%.;.&1.0-14%,0Lh:48_=ad?F1CP[[+HO:VB4± ¤¦«£¦¤¬¦´³±ª¤°§ª¸¾À¼¯¦¸ª§®°ÉÆÈÑý¿¾¹¾¿¼É¼Á¸°°´±º»¹Á³´»¬¸¬¢´¦§¬²¶¹³§¦»µ­µ¼¯¼¦­¬µ«­œ©¯¤ ¥¬ª§œžª³¤³¨šª§©¤©ž£©¨©½¬´¯®©¤ ®œ›²£•¤œ¤¥Ÿ¤šš¨«¥ž›ª¡›’›¡¥˜—©©‘˜š“Š‚…~‚ˆž†}Œ‡‘„“›”…“¢Œ”‘‹‘›’•‡ˆ~qzy~|iw|zuqq}h†y…ˆd`hcr…zmgy]^VBWzmTaORXKLNqt]HZ[gYEUfPD>KNDCA9HGKS?jaIQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11&/>KH1%90%,,09/,,+6'17#-/GjI14X=fbAJ7GS`U*=;EZ?*“±™ŸŸ©¥¤¡«¤·²²¥©°§¬¸Á½µ¯¢¹­¨¨°ÃÉÉÌÁ¶½¿µ·¿ºÈ¶Ãµ´³µ±½¸º¾·­¹µ¿­¡³¦ª«°µ¸´ª»¼¨²¿²¹ ¯³µª¬Ÿ®°£œ¥¨©¢žœ¥±¦¯ Ÿª©¨¢ªœ¤© ­¼¨®°®¡«£¤®žž­¦—Ÿ›¡£œŸ›š£ª¢šš¤¤•–”Ÿ¢–›–¦¬‹ž‘‘Œ‚‹€Ž€zš”‰|~‹†ŒŠ„’˜‘‡”£Š’’‡š“‡|yk}vyxb{zqpqsxitkƒgdhaosŽmbjp`pA\xkV^NQQJJMSYVM]^mWDX`O^PHMDF;7HEKO<rhJK9AE;;==;;=J49B<3;G<4?18-78;2(09/,5..=-*K>*49&'.34.0+/4&,:$40BhY13S=e_DL6KWeO)<3P[=#’˜¬™Ÿ—§¤¢Ÿ¨¤¸¯®¢¯¯¨ª¸Â¹²­Ÿ¹¯«¨´ºÇÊÈ¿·Á¾¯´¾·Ä¶Ã±¯º²²Àµ»¾¸©¹·½«¤´§¨ª°®¹±ª™º½¤¯¿´´ ®·µ¦§§°³ ž¤¦§¡¥™ž­§¨ž ©®§¡§—£© °¸Ÿ¤±¯¡¬ ¬¤œ¦§©šš›Ÿ£•œš©¦–›Ÿ¨’˜“˜’™–¡ªš‰Ž‡}ˆ‚Ž|{¡ŒŒˆyƒŒ…ŠŒ…‡’šŽ‰•Ÿˆ‘•‚‹—Œ‘}„{so}qst`yxiopqojsd{lifdaf†€`[sjrMMiXZMPLJHPRQIN\_nSDXZRgOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23/:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%53=fd24M?e]FO=RZhH*?0ZY5(–¥˜œ–­ Ÿ¡¤¡·«°¤´³¨¨¹Äµ±® ·¬®­°µÆÈÀ·¿Á¹°´½·¿»¿¯«½°´¿±½Ãº©»º·§¨µ¨§«°­³±§™¼·¤«»¶¯Ÿ±·°©¥§¯²›¡¤ £¤¡—›¯¦¡Ÿ¢§¯¢ ¢“¤¥¢·°¡¦±«Ÿ¬¢®—œª¥©ž—š¥“›œš¦ª™œœ¤••—•œŽ“—¢©¡‰Š†z„~„ŠyŽ—Š†y‚‡„ˆŒŽ…“˜ŒŽ–™Š—~†—‹z€zprwnot_xwdlllji„nfsikfi]ds`[kuiZI}^[XOOJHHRUF29_^lPDXVYeMIIEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<#8R=*113>D5,-'42*;+139cl84GAf[HTDU]hE.<2bU,2–£¡—”œª¥¡¢ ·ª® º¸¥«½Å²¯®£µ¯¬­¯µÄļ³¿º·°³¹¸º¸»®­À³´¸¯¿Á¸¬½ºµ¦¢³ª§ª³«­²¢šÀ¶¥§´µ©ž²»©§¦©¯¬™¢§œ£¦”˜¢²¤™Ÿ¤¨©œ¢ “¥ ¤¸¨¤§®§ž¥ §’Ÿ©¢¡ ™› ’›œ– ¡«››™¡”‘”–šŽ”’£¨¤ˆŠ†y„|…†}ŠŠ†y€„ˆˆˆ‘…•“’Œ•”Ž”{ƒ˜‹w~{ltrllsaxthhjgfo…ghicfij`ibjg[e{c`SsT[[SLIGIOS@!*i^jLCVU^`KIHEC.:B<F<6KPD8:D357==895?:;4>8@K=>93)8><:9*6@3.E4(+,>0-N?.+-7,1195,&.5-80576`tB3CDg[KWGU`hB379eO'2ž££‘Ž¤§›žž£µ­¦ªº·¦«ÃÁ¶¯¬£µ®§¯¯·ÀÀ¼²Á¶±®²¶¶¸·µ¬©½³¯²±½¿¸®»»±¥ž¶«¥¥´©«® žÂ«¨¥¯³ª¬µ»¨ª«±¥˜žªž¦¤‘™¦­¢˜ž¤©¡œ¢— §µ¦¯ª®¡¡žœ¡• ¦Ÿ¡ ™›™œ’™”¥¬¢˜–ž”“•—Œ˜š© ‘ˆŠ‹‰y…w‚‚œˆ‹‚‰|„ˆ†…‘„–•Ž‘‘‘Œ’{ƒ•Ž†r}}fxokjlguskcgedu€beffejjdkqZ^Y]mdaNhWZ`VJGIKMRX>9`liGBTS\[IIGFA.<?9A89RG@7:B037=7692:<97:9DM=B<0*<@;A=-5B37=+*,0A*JK./*+3722(57$+7.72685\yN2>HiZLYJVbfA:3AfH%5š£ž‹¬¡˜˜ –¥´±¢±½¶ °Æ»¹±±¤·¬ª®©¹½»»­À²¯®­¶¯³·²¦ª¹±¯­´¶º¶°¸½­¦µªŸ °¥«®ž¤Â ²¤®±¯·­µž­¯­®¢™¨ª¥ž•›¨¥Ÿ™¥£¨š ›”œ¬¯¥¹§­¢¡š›ž™ž£š¤—ž˜›”š ’¨–ª§š“›œ’Œ•™””™¨§Š‰|‚t‚Š˜…‡|‰‰„„ŠŒˆ’„“œ’’‘–Ž€Œƒo€fynhkjgqrk\hccsaehjnlgkjgm\lluqaTbhdeZIFLMOXQQVaeT@VSYUFHFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24;6#3*)6.55465Z|]19Kj[M[KXdd@A1JeC'4’ šŽŽ°š“¡š©²°Ÿ¸ÀµŸ³Â»½¹±¦¶¯¨®¥·¸··¬»¯­ª«·ª´¸­¤±µ±®©±·¶±³µº§¨Ÿ¶©œž©£ª­œ©À™­¤®°¶µ­­Ÿ±­°ª¢›œ¤¬¨›•œ§£š©¢¤–š œ›£ª©©»ž¦¤ ˜š™ž¡k¢–˜œq‚–›¤€u’©§ž”•Ÿ‘‰—™€–Š y†”Œƒnj~wƒql†‹†}„‹†o^c`g„—†k‹”“uw‹„~ƒf†€huifW\isnNPjcgr„g_dfnlj^``Š„†gOKD8ETg^JGQPUUKHSaoteF[QUPFHFC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,+08>G601.*.*/568,#1'214:176Xl16Ok[N\K[fb>G1Qd=+/Œ£™‡”°›œ“ ›ª­«£½Å¯¨¶Â¸½½­§¶°¥«¤¸³²³°¹­ª§¬´¦°´¢§·µµ¨§¬·³®´­³¢©Ÿ´«¡¤œ§§™¬»•¦¥¯³¸­®¥¨®«¬¥¡Ÿœ¡§¦›˜¡¦¥››§§“žŸ˜ž¨©¢µ¯£¢£–—˜—£ˆ¡Ž’š‡¡‡”¡¥¦ª’’›’ˆ„rxŽ„ˆ¡vˆi—ˆf}sx¡oˆ‡„~{¡ Ÿ™€{‡žtˆŽv›Šl‡ƒmheczlqbT†mcli˜qXjpo‡X^i[kk[ˆqnzr†h‡„Z^FN>F_MFRVVQQRWTg^LXJRRPEGG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82).1<I9/01.*/(-4583%&2115>1<8Xƒu25Rk[N\L\g_=K1Wa7/(Œ¦—ƒœ«™™Ÿªª§©¿Ã®±º¼·À¿ª¥·°©¬¦²µ®¯³¶«©¥±­¥µ²›¬´¶´¦§©³±­²§¯Ÿª ²© ¤£š¢£œ®µ•¤¥¦¶½§­§ªª¬¨¦¢ ˜ §£™™¦£¤˜œ¤©–”¢œ”“¤¥¦ ¶£¤ £˜•“˜“œˆ®˜”‰©‹—¢›…±€£¬œ“šž•y‚Ô¨‡”Á›Çyx±¥·—d€Àœ¿y„„yƒ|‘Êq–¼œÅ{r¶§ºzl–±«°yhkX±®oei¼’¼nhznrØ~Sjb¶²r”uš¡ªWOWaOVNFT[XQPRŒ\W\P@\DPNEGI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22BE/.32.+/)-/186- /416A1=:Wƒw21Tk\O[M^g\>L1[]41!¦“¦©Ÿ—œž¥­²©°Â½²µÀµ·¿Â«¦´­­©§¯³ª¯¶´¨¨¦µ¦§¸­œ²°µª¥¤§±®®±¦ªž§¤±¤¢¡ž—œ ž¯­•ž¢Ÿ´º£«©¡­®¥¢›š¢¨Ÿ˜›¨ Ÿ˜ž§§‘œ§›”¡¦¢ ¯¢ŸŸ£––“˜’™…¯jjŠª~g„•‡­dpœ”š¦•q®¡¤~w»|k¡v±_j´[¥€fœ‘`fzfjxj©e¾rg¦Œv²j|±xt’“cmm§m[„ Eig‡–Euœ`}g{¤§‚Y_‹«i€•xzj§7J¯[WTlc[KOX_\WV;NˆOWV/HSSJDEF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3..53/+/(.0.:5/'$203B/=;U‚v2-Vj\OYL_gY:M5_Y31‘¢•‚¬§¥ž£¥ª²¸¬´½¾°¶Ä²·ºÂ§©°«¯©©°®¤°º°¤¥®³£©¸¨ž²±°£¥ ª­¯¬°¦§Ÿ£¢°œ£œ˜•—›œ­¦—›¢ž´³¡¬œ¢­­ žš— ¢©œ™ž¤ œ™¡§¤£š— Ÿ«Ÿ¦¦ŸšŸ¡–•‘—‘š…µ›µx…©™µ™w‡³›·~“––©”~k¦z‚…ˆ“”’w«gk±[¬{‡”tˆp†€ˆ—xƒ‚‹—Œƒ „°vwŸqkkl|‹N¤XHcc™~ch¦`yruS’‡^P©mcq~‡€b.Q¡n[Tkg`LK\dX\ZB>°xWXA#LhECDA@A19>88:84;:9<9:A:E::;6:CB8=?KNG:5:AFB@AD<FD;0201;F,0.940,.(/3,>831/2-D1<<S}n3+Xj\OXM_gW7J9aU50•Ÿ”ˆ³¦¦¡®©§³¬©»¶Â°¼Â­¸·Áª¬­®®¦®²©¡¯¼ª¡§´­¤«µ¥¦²²§£¢ž¨ª²¨°¨¥žŸŸ®–Ÿ™••–˜ž­¢šš¤¨µ¯¡©©¨ª›ž•˜ ¥¨šŸœ£Ÿ› £¥£•›Ÿ˜š¢ª›¦š›¢ —“‘““œƒÕ“™¹p°Â~Ɔ|֔›»|™•¤œ¤{Ž‡¤‚¥‚z¬yV¯{‰~Ÿj¹Z¹w‡„}¦‚“|˜zªyœ{±mŽ„t¼…o”P¯§ÅŠQ zc`ªbsr‡m—ˆ`Sµ´È†€‰|c¤3Bv]QjhcP@XfZdaJHMlK[SOYfZCD?E?0<<59;74<;8=:<C:F:;>6:@C;6@OLH<:<DHCBCD<EF81211DC./0483+-).323971#%5*>3==Qwj6*Yi[K\P_fT7G:aQ72%›¢“˜±§¨¥³ª¥´¨¤¼·Á°ºÀ±µµ¼³µ§±°£°²¦Ÿ®¶¨›¨¹®£¯± ³³¯ ¤žŸ§©°¨´©¤œžª—˜—–—•–¡ª›—¨­°©£Ÿ¬¢§–ž—œ¡¥¡˜¡¡¢¡š¢¢§›ž¡ž•™›¦ œ§•œ›Ÿ¡™’•‘ˆ²nhµq«‡oŽ¦r´sr¶{™—£‹Žœ¢~‘ ¥~°vƒ‘ÒÑv\®|†¤o›ª¦k†…}­}—™{±s“Žx³e–t„žožf”RȋZÂ\Ÿyb_­_vs‡b—ˆ^Yʝo¿uMKµSUÆdTQjcfXAOj_liOUGI9=WR[WXHC?J<2?;5=<46>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>HI91746A>/.24252-).26,742&60;5:=Pqh9'Wi\BNT_eP5G=aM62/¡œ‘¥¯¬¤ª»­¦´¥§¶»¼²º¿·¶µºº³¥´´¡±±¢Ÿ¬°¤˜¦º®¤±±´·¨Ÿ¦¢ª¤±§¬©¤šœš¨ž•”˜˜’’£¨ —“¦«°¦¢–“­Ÿ¥’”¡›¤¦ ”š¦¦¡š£Ÿ­š ž–›¡œ¥••š¢Ÿ–™–’›…¬{w¨v£Ž‰‡©o­Š‚§ƒ˜˜¡‰’šŠ¢“™‰®…‚³\r³R®}ƒ‚¤q×}w…†™™w¯†Š‘œ‡w´ašeš‚”l’Z°XKšu˜yf`­^vw‡h˜ˆk^¯w•žxl5yÈ®²_ATo^g`EPl_qmVUM.eciSYQ:AD@L:5?91=<16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK97<46:>/04333.2..18*.32%!03767=Pke>&Vg\@=V_cN6GC`I:88Ÿ” ¸°—´Á­¨²¨©²º¸´¸¿¹·²¶½µ¥¸³Ÿ´¬ŸŸ¨«Ÿ•§¶«¨±²«­´£›©  ¨¡µ¦¦ª£™ž•¥¡”“œ™’•¢¥š“§¬¯¦ •™©Ÿ¢‘¢™¨¦ •™¥¨œ¤ž­¡ ”ž› ˜™œ–—¢ “˜‘¦†©}}¥x¡Žƒªp­‹§†•Ÿ¡ˆ——ˆ£‚‘ˆ”ª|€‹yo±Z¨‚‚ˆ ytØv‡t§Ž›’¤|–Ÿ„{²^œd ~ƒ•l’\«[Z“‘hgªcr{k˜‡r]¬Z‰ ŽkneOJC¡\ZLt^beMZa_rs_JV6Jš“YHE=HFAL35A8.;>05A78@<6=<F?:<6?=B7.HVJEAH6KIN@IK@EN::@4.;>002144+*05/7,&21($$6671<PeeA&Uf[?1U_bL7FI_C1>8¡™™¾«—´Â®«­©¥´°¸±µ¿¹º³±·¼ª»´Ÿ°¤ž¥§§ž”ª±©°ªµ¬«¯¡˜¡ ¦¤£¹¢£« —›‘¢ •”Ÿš”˜Ÿ Œ©°¯¦–›¨¦ŸŒ’¤—¨«§”—©§žŸ £­¤¡ž¡•¡™Ÿ ’—œ•ž¡•–«›®mr´r©ŒvŠ¦s´xs³€‘¤¢‘œ‰¤‡w¸oŒ{‹¢kk¶Z …e——i¡¢§m“r´t“˜²j…“ˆ­ku³af¢o‡’j—\­`M¡|‡‘Rs£ly~o˜‡q\¯V<œwfTon.\§ObRkealYb\`p{cTZQ>>mp3BB@?L9!7@6.;@37C58??3;<CDBJFMIF62JTKEBI6IJP?HNCFP=<E50;<010/75,+,426/#00,,289/9N`eD'UdY>/U_aL5FM^81B8¥š›º¡›²À®­««§·©¸¯´Àµ¼±¯¹¸«Á¶©ª ›¦¤¡’ªª§¶£²¨®ª —œ§ ¥«¹£­›–™¥£•¡›™œŸ“”«¶¯§™”œ¬ª—Œ“¥™¥¬£‘—ª²¤ ž§«°˜¡£™¢— ›–›—¡“œªœ”‘«™‡Ô’š»s°Ã€Ã†~Ֆ›¸x‡—Œ˜ŠŒ§ˆz£¶u}wv‚š²`ƒºyÀ|u¸bµŒ‡©}–¬©q{u¼ˆ§ ia¦Ž¯¡~Œt‡«}¾ns¼t²ƒux€Šnšˆqn¤t½]w}[ay¼kZV[jz^j`dfbmwoY[YCA@r?CG+5H"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-7A9§šž¡¼¢—±Ã°­ªª¬±§¹¯¶Å±º²®»°®Á²¬¤¢ž£¡œ›‘ª¤ª²¤´¦­¤Ÿ–šª™¦¬¸œ¢®˜•¡¥ ’œ£ž˜š–“¯¹±¬•—£¨§”‘–¤œ¤­ž‘ ¨«Ÿ›Ÿ©£³ž¢¥Ž§¢”¡šœ—•¤˜° ’•ªž…™¶€‘Œ·•x‚“›µwnknsny„Ž‰sžÁ»½š{²¨p€t‘¸ƒ|††‹‡{Š†—|¤»¹½œuz´£tv—ut°u™žf†iµtrpw¶Œ^y}‰hƒymyb‹¬pu…Y[§jDdYSf`c]cQgfqluBNPLD;ZL>J3<0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITBKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7LT_G'SbV8*O]]=+:VV'=;<§ž  ¿¥–´Ã´¬«§¬«©»®°Æ¯µ³®·§µ¸­©£¡¥ž ™”¬¤­ª¦µ¨¨Ÿ›– £ž¬¤¾¦¡«—”¢›’¢¨¢“—’˜”²µ¶­˜¤¤¢‹’‘¦›¥«›–¨¤¥œš¡©¦§£©¡’­Ÿ—£ž—–—ž°©”œ§¢Žj~iœ¦x‡s~štze‡z¾¾Àºn’ƒq”†_rjZ^š‰adˆŽ•k`•cmœvb”kš•”e^`cq›ŠirŒ}†•gj~rtx}}b[wthP\nƒ|{‹kXlz‚rIJo…pMtMEW]f`L[Xgc^O[muiqQODEM;HI<L?2,2A?8/5?C<9;@;=C>RVVWYZ[\\]`aaa`\UG5DFUEJOHFPIIH;8=51:.0;:.0-76=5&"/*2,%;8-7JR_I'S`V4)P^L(3=[O'?2>¨Ÿ¨¡Á£›´º¶£­¥®§¨µ±¬È¬°³¬µ£¾±²¦ ¢©¢›š™¬§®¤¤µ©¥›—•¡›§­¨¾§©¦•”œ• š“˜¥©§‘ž˜œ°²¿¬›¦ž§¢‰“‘©š¨¤š›«Ÿ£™›£§­¢Ÿª¢š°›•¦ –•Ÿ—±¥˜¢¨™œ‘œ££™¦¢šœššš–gm}qw‘—”‘…Šµª†˜•ŽŠŒ˜—‡”•Šƒ’“‘‰‘“˜”˜—š ¢šœ”¡Ž‚z¥…lj||€t‰Šq‚xyvvŠ€{‰jstƒucw}vkp{m`c]pgMYYej_WZozmmfSOFS9OZNRO(+:JB635=@A9:C><ENSSTVWXYZ\]`bba_^^[TKCSGKNDGPLOI<:;389,2;820)6IRO8")+/2#4;*7FO[J&R^S10T^:+=8\K,<-@³ ³¢¿¢¤±²· ª¥²§¥°µªÉ«­±¥µ¦À¨´¡ž¤¥œ£•– «¦¬££¶¬ ™––Ÿ—­©¥Àž«¤•’œ—ž˜“”¢Ÿž¢§“‘˜¨§²Ã¯š««ž––©žªœœ ¬˜¡šœ¢¥¯¦¡¤¨ž­˜—¦™š¡žž° ¢¦•˜“˜” ¡•£ž— Ž–”‹ŠŽ–­|•›‚’‚‹ª¨†˜–Š„Ÿˆ{„†…™‡†‰•Ž›—˜ž¤–š“‘f¡³¯…‰„vzŠ|vyzogy€‰kuyˆrhszvƒˆ‚ktdyf`idbdfjYk{pij\SLPD_UF@??,4@F;45;>A;<?>>HNNOPSUVVXZ\_aca_^^]^]XVJKLBIOMRJ;<:786/2964.(&$-1./)+*7%+<(6CMMD/T]Q05M[17E4\G5<,@´ ¹¯¾¬«®²² ª¦±­¢¬³°Å°ª­£³®¼¤´œŸ§£¡™—¨¦©¦¤¦³µž•”™™°¦®¾ «£‘žš™”‘•¡œ—©œ„ž©¬¢³È³Ÿª¤«––—š§¨›Ÿ¤«”žŸ ª®©¥£«¡­›Ÿ ¡™¥žœž°¤™Ÿ¨“˜˜‘¥™˜¨š—fƒ’|e~Ž™cylhkz‘¤«keš˜~g…Šeeihz¡ŽkhŒ—‘¢wkj‹˜£Ÿ™slnz„Œ‡zXe^…^lŠ‰€v\hsww‘€‡‚nx‚x€smyƒtwˆˆŽƒ{j†Y^ktd]s‰ij|qlc]QMWJdX@J4=F7?FD71<=?AD<<DGHHILNPRRTW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%/*+'6*$;'/AJ[J/7ZO6)EY/DO1YC;?.=¥Ÿº¼¹¯¬³±ª¥¨­®°¦®­°½±©¨¤­¯±Ÿ­—Ÿ¤ž¡š™¦«œ¬£¦¨©²®ž•£¢¯¦¶¹¥®£Žš¡™“’› ™™¥–{¥¬¢¨³Ã·¤¢§¯žž•ž£ž£œ£ª¨‘ž¡ž ª¯ª«£ªŸ¨›¦Ÿ¨¡¬–¡›¥°¤˜œª•¡žš“¥—žª˜ž~¾ƒˆr´r„†­hx¹Ä¸q“¢£{¦˜™sª‚|ËÀÀ»q‹¢‡‚Ÿ|•˜‰žÀ½‚–žÂÁ{{’šÃÀ}k¥±oŒ€oÊz›w‘ƒŽvzyqz‡qx…Œ“ymw“bf_xd_e‚c^thmdbXLVIQZHOE2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^__`_^^^^___]\SMPGUNA??=6468276*&%#)*&.+*)109*#>I[L*#BP/#F[3PY/UAB;/8–£¸Ãµ°¯À©¨”£¯©°¯­¦²µ¯ª¦¦¦±«Ÿ«˜›£ œ›ª§¢«¢¥¨¥¤´£¢“¦­¬·³§¯¢’‘š¥’‘ ¡—œŸ‡§«¤«­¿À°¡©¯©—’Ÿ¢™¢£ª£’ ¡ž­®¨¬¦££§¡¥¥ž­©‘¤›©­ªœªœ¬¡–—¥–¡£—œΔyz¤y•–›_®^Ž§¢ |§•›t«ƒ€¯^c©z§‡… t—’ˆ³c‚«†¡Ž³j„®t}–‡¸a‚­Y£Ínu{Ú{™p~ˆ“v~e{‡vvk}ˆn~…‘’~m`qkpg`_yd[phjdf`RTRW^KOC5AHED8>6;@?A;=7@>??BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5578164('$!',&&/(&+360$7;SL+,-J0';\;L-!P@F4.1­ÂÀ¿µ´°¸˜ž‘¤ª¨­´«¦²¬­¬¤«§°ª §›™¥—œ¢¯Ÿ ž¨§£¦¡ž°¬›ž•§®­±ª¨¬ ”’›Ÿ¥“Ÿ¥—ž¨£ž®¤«°¨ÀƳ¨©±®–’œ¢—Ÿ©ªž”¡Ÿœ®¯§ª©›§§¤¢«’¬´–¦¢«ªž£§¦¡° “š§š š””‘— p…Œ—t„¨‡q±|q¬~¡ž¥žw«‚}­œr­~«‡†Ÿv˜’z|—~ªˆ¢Œ‘‹~«{‰“Ÿ€{­VœÄzo’Á}•mupŒmeve†oawnroŠ‹’ƒmeotup`gmd_oiinfcWS\aZQQB9II@D<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;91478452&# 1' 1' '45-&7=WJ-<'>1)3V@F!G:C1.+°ÔÆƲ´Ÿ£Ž££¡­¯¶®¨°§©ª¨®««§¢¤™¢•Ÿ¦«Ÿ¢¥ ¨¨¢Ÿ°¬—š–¨§¯¬¨§©ž—”š£¢’”¡­›¦£¯¬£¬µªºÍ±­§®¬–”œ¢˜Ÿ®¬œ– ™ž©±©©©›«ª¤£¬›¯±¢¨¬®¦™¦«ªª±¢’—£¤š”’„¤j¤u‰z©tz²q‚¥‰™Œqˆ š‡¤``R¬„®ƒ›v®¦††Ÿz˜–†{f€£‰¤™†£}©~”‡®^|©U¢’z¢Ÿ€{ïŌs¯³³¹qb©¯Âth˜mš’pnywwolfdeqpf{hc]W`jXXTKMQLCCAB;C@@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799674,&$" ('"+-"$.!3-&@DWH,G+66*1PKL# A9D4,'ÃÉÖÕÀ¡™«¨¡¯¢ž°µ°¯©¬£¨¦ªª«©¤¦ ›¤ž¥§¦£œ¬š¢¬¡¤Ÿ¯¢š’ª¤µ°® ©›–”§£š¢¨Ÿ ¦œ±¦£§±¬¶È²µª¬©•‘œ¢™ ¥³š¡”œŸ§««£®š¬ª£¢«£³­¢ª³±¡›ª¨¯°¶£“–£§˜›‘|ªlž„‡u«y|°o‚¤‹‰Ÿ–•Ÿ”Ò¸´¸É€²__”©ƒ¤ˆ‡ y˜•šxªÉt™£•§©’›Œ›‰šÆÆxe¡‚¥sŸŽ‚}¯^pµc±uK£†m§G‚“dž’|p—’€pzt|{m[fjrqfj^bYcm\^XHMLKEDAB>A<B?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75685/)(%&%$&),4ENPPMFKJVF*L0/>-5OTQ;<F2,$§¤Áƹ­©³®¬¥¢œ²¹¬ª¡¦›¨¦ª¬©¦ ¦¥˜«£Ÿ®«¥ ¬šž©¥¦µŸ¢—“¨ª¶²¬›¦œ •¥­‘™œ§£ ª§®¢£§ª°´Â²³ª­¨“‰—¥›¡£®¦—¡•™¥¦«š¯­¨§ž¬£·¬¡²¹¯›¯§³´³¤”˜¨¤šŸŽ‚NxšŸzƒ£|‚¤„‡§Ÿœž“„¸{|y¹‚~Ìƶx›¡‘‹Ÿ}™–—Švž˜Š¤˜£¨~°…œ…ž„¬}™”a¥l£p…}—ƒr¬`¤sq€š`¼}RUuŽ’¤—|~’‘Štzs„~p[mnwrjoZd_hncd]KMQTBIHFI:9K>B108866877-*5==?BDGILNPTVXYZ[\__^]__\ZZZYUSOH@772.,*.+*'&?QTVWWWYXXWUOUF<E3:P[T6?H,- ‹‡™©¬¤«¹«¯ œ¡¬³³¦Ÿ •¥®­®ª§¦¦š£§¡²®¢¨¦² ™©¤”¢µ¢£•—¢©´¸¤œ¢£“¡±™žœ§¦¡¢¯®¤¨¢µ²Ã±­ª­ª‘‡œ§£¤œ¥—ž™™š¦¤¨š®¡®¥¦˜°¥¼­¡··­žµ²¹±³§˜ž°¢¤ž…ÑµÃ·y‡Ž…‘“¦x”¢wŒ ’„¥Šqª†„´nrj™£›•ŠŸ{–˜†‡s¯‚¥›¢¦‹“‰”›mp²\¥s“zœl™{™}n©a¢qqŸbs²¸hx”¦˜~ŒŒ“Šw|ymixixsnt]ddnmfh`J[XX<HG@U3@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^``][ZZXURRQF:2230/++(@QRTUTSTVWWXXWUVVTQOQ[U%!2AH$)%“sŠ­¿¿»ºµž—¨¤­µ¡£™•£©§®ª«™¥¢Ÿ¥  µ¦¢¨§°£”«£Ž¤­£ššª´´¤¤©’”—®  ž¦¤œ§œµš ª£µ«Ã°©«©¢Œ„Žœ¢¡¦¢•š›œ™œ™¦¤¦˜«§­£¥›­§¾¬•¾°­Ÿ£°³º¬´§›©±¥§˜z¨}|°wŠ¤¥ˆ›l±o¡‡­|¡ƒ¨•˜€¬ˆ…®…Ÿ”© ¡–†Ÿ€˜•€{’~«€š–Šªx ‰“’€y¯]£|¦§d€|—tk®]¥kq…™]`[Œ m•‘§™ƒ”Œ–‹zz‚–~klb}tmz`geqohghCY`[=KT2U8BBC7$$3+''3, /6674359@CFIKMNQSSSVZ]_a`aaa]][ZXSPONI7052.*,ATVVVTTUUUUTTUTSTVVWXVUUQHFIJ#((½’š„©Æ·Á´Ÿ›­ ®¸¥¤Ž›¤£ ¯¯ªŸ¤Ÿ­™ž¹ ¢ª ¯ªš­¡ª¨¤–‰›®°¬§Ÿ§›­˜˜¬¢¡¥¢š¥œ­˜Ÿ¨¦¶©À¯¥ª¤Ÿ‹€ŽœšŸ¦ž’•šš”››¦¤¤š¨¬¬£¤ ª¨¾¤—쪢¡¬²º«®§ ³¯©ª˜v¯~‹œ…‡}º­Š˜d°Œe•­}¡ƒ¦•š¬Š„°…¥™¤¡¡„ [lj³`­{{‚€±lgn™—Œˆ°[}´[¤ƒkÈ¢eŸ€{¼YvµZ²}R¯€z¬X€¡m˜¨šŠ—‘––{xœ~ds~bƒwt€|ajfqnfeeOUc[BT^>I(>9=4!"-%2. *1/045799<ACFHJLNPPRTWZ^```ab^_\[XUPNJGC553./@UZXWXWXXWWXWVWWWWXWWXYZZ[\XWWGB;ҟ³²·½»´Â³£œ¬¦¥¶¨¡‹š Ÿ³³©ž£ µ˜ ³¨ª«¯®Ÿ«›•¯¨¢Žˆ›Ž¯¬©§¢§™®“™¨š¢ž¥Ÿš££¥™Ÿ£©²¨¼¯¥¨žŽ}‹›•  ™’š›’›˜©Ÿ¡™¨®§¥¦£¥©»Ÿ Æ§¥©¡«´¶­®§Ÿ¼­­¬•©’£¯›€†¤—˜€¸ÃºƒŽ“„§–œ‚¬Š‚¯ˆ¦››¥©~սªb£¿½}~£‚ƒ×º¸µ…”“ƒž½¾„j£o«„mz²°Çƒj«°½­xw¢¾»t€–Ž¦œ›’—z›zc}{dŒfy‚{`kekjbPb[Sj\@TaBN)=:4/$%2 $(0496677;>ACFGJKMNNQTW]a\__a^`[\YTQMIC?<A?5=SYXXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ¼•³´±¿¹²½³¢®¦¥³¦ž‹˜¥¾©·±¨¡¿¦¦²œž±œ¹¨ž­¯¦§•”°¬—Œƒ›‘®¦£¬¡¤œª¡˜‹£’§ž§œš¡¨¢˜ž ¬­ª¹®¨£›—“{‡™‘¦›’Ž‘˜˜™”ªš ˜©©¡ª§¡£«»ž©Å£ ¯£«³µ«°ª »¨¯¯šsuª¤·†e‰Ÿpg­Šmow¤™Ÿu®™•p‹q•¨£›—­£rmmmeŠxom‚™q€yipig‰–•˜qhi„†gp†d]‰cjoY]g~w¦`bqŽ’ofd€’Ž¢˜—™‘–Ÿ}‡Ž•vf‡xhjy~ydlcflbKdXJkY:QeER'K:+# #,)-2.5:457:<?ABDEHKLMOQSV]WZ\``a]][TPLHD=:AB7MXZZYYZYXXYXWWVWY]^^]\\\]^]^][[UW^¨•­³ªº¹²³«©¢®ž¤²©˜’½±ÃȾ¶ªžÀ«¬£¡§¬Ÿº£¤­¬­¦Ž–®©Œ…•—­ž¦ª¢Ÿ££ ‘Œ¤’§™©™–£ª –œ¥¦§¯º«¬š›““{„—¥˜‘‘˜”Ž˜–¨”Ÿ˜©£›±§ž£¬ºŸ°Á§¤³¦¬±²«®¬¨¹¤®¸–Š¡¨¥¶‰–¢—‡©š”“ª³™›£« ±–¡¡ ¢œ ¤¡•ª¦Œ’’Œ‡’œœ”š“˜Ž•†¤™—•‹“’Š†„~gŠt‚vt‡Œq§l{•‘”“” –˜–¡ƒ‡“qiwpŠwv|zjlddocU`X@i[HcaOZ+F=+&!740.!%2(*699469;>?ABDFJKKMOPQXUVY^_ac]^UQJED>9=@ASX[\YWXXXXXYXXZZ[\^__`^^^__```_YY`¥–©ª¥µ·®®¢°¤­Ÿ µ±Ž«Å¼Ä»¸ª¢¥›¦ž±©£¶§©µ§¨‘˜¬¢‹ˆ‰œ§–¬¤¡™§žž“•£—¨š©™”¦¡£›¨™¡µº¨«™š|”‹ ”Š”‘•“—¥Ÿšª œ¶£§¬·§¯Á®£·¦¯¯°­ªª³¹¡¯½™’¦£¦¶¢’¦ž©Ÿ’Ÿ£¬¯š¡£±¨¯—£ œ£©žžœ–«’™¡›”–ª™™™––Ÿ‘‰ •”…’ŒŒ”Š€~fŒ†u†vyˆƒsœj†‘””‘Š}Œ–’’˜“¡“– ƒ‡—‡zr–sy‰q{jnd_pi`[`YmcP`dP[:GGD=2==7.*&+)&&406658:==?AACHJGJKLMSSSUZ``i`eVPJACB:9EMV[^^[Z\[[[\]]__]^_`aabaaa`bbbdb\[c—•¤¨£°³¬®£©§­ ¨µª¤³»¯¬¬¢£šz¢±¤¥°¨–›¸§£”™ªœŽ†Š‰œ£®Ÿ£–¨ ¡’—˜›®‹«–¨™§Œ™¨ž¹¶¤¥™›‰y‚”‹š“‰•’”‘–¢Œžž©žŸ¸¤€„¯µ¢°¯t¤¾£² xz ª²»•v­¤ŸŠ€ª~d\bvŸŽ¤ž„—~n“³œ£§®ª£eŸ“sy™—p€˜¨—l¢¨Šeœ¥œ‘—˜•‹’œ‘†š•‚’‡ŽŽ’‰…wk‡v†q|†€€aiˆ‹•“‹[v•‘ghŽr{¥˜˜dy˜†‚x˜iƒŠ‚nykpe`vokkh[febboS\>NNNRG=@TB91/&4:316678<;>@ABFHBFFIKMTTUY\_hfgWQJ<DG;8UR[`ab`^`_`aa_\]___aabcdabaaedchd^]f›–¦£¡°±¬«©¥¨­£§­¤’–«µ¯²¦šª¦«—sŒ°Ÿ¨ª¦”–¹  œ¤‘ˆˆ›ž«š£•§¢žŽ—‘ž…u®ˆ¦š¨‘—¤ˆœº´¨ ™˜‹‰uw“Œ–“Š”‘”Œ“ Ž› §™œ³–€Œœµ³Œ’¼§¡~§¢z£¯·ŽŽ¦ž„‹…±©¯Œ‰–£šy‹¬†œ¢§©§‡•…˜w¥›z‡›—¦‚{œ±zŠ… —™”˜–‚‘—–„™™cy‡„’Šƒmp‡y€q€…†t†„–’x–h“t št|™ƒ œ†˜~’‰‚ƒ™jŒ…kx{qpgdwnilk[ekjes\^ITLQ@E5.YTU6)!09=>643568;:=>>@DH?IEJKGSXZY[aahfYQH9EL;>bV^bded`aa`bb_]`aabbbcfgcba`edcgcaahœ˜£Ÿ¦®®«¨¬ ¨°¦§©¥™”®Æ½°¡–¦©µžƒ¬œ§¢ ¾ž™Ÿš }…Ž™—ˆ«¢– ¡’“‰†€‘¨Ž‡¢œ£“—ž†žº²§ž›’Ž…pu‰•Š”›‹‘Ÿ’— ¤–ž¬ˆŸ´‰´š­‹Ê‡ª®ˆ·…°ƒ±®ƒ©¦˜|¨r{w›§–h•¤y´‹Ÿž¦¨’™Â«ˆ˜¡qž€™¤}—…•±€¡|¡” ˜–€Ž“›Š—‘‹|…“†•“‰ƒms‘…zr†„|„t…‚—Åf€©‡£kžƒ¡™ƒš€ŒŒƒ‰˜pŽ’…hwt{vghupggl^colgmXgG]QL2E46M`c7&3<DGD:64658;8>==>BL?NIJLCPZ]\Wb^jl\QE=KM@JdY]cfhgbbbbdc`_babcccdiicbbbecafcbbi•—¢Ÿ°¨©¨¥« ¤¹°ª«¦š” £¤ª¤–¥©¶£¯¡§œ¥ž‰”½š“¡‘y„––‘‡«™››š¢…Œw›œ ‘ˆž¤›•™˜†¢¹®¥šœŒŒbm‹“Œ˜‹‘Ÿ” ¡™¡¨~¡§‡­ –®ž‘† «¯†¤ªšŒš~¢v€™“j‚¬uM«x‡‘›¨§€ª«}ƒ¡{z§iž’kg—†—¶‰ž}n`dYƒ–Œ{dhŠr™}y•l]{—m_Sp„\_lyƒ`Ye‚}„˜q§ªkƒ£nr¥pŸƒžieŸl[m‰{eY_ƒbWPovemtrjjo^jomljXiO]WE9A4GC^k4,ICQMN=84859;6@;;>BO>QRLMBJ\]_W^_cv`MD:MOMTb\\ffiibbdbddbab`cdcabikdbddgdbgeach˜– ¹¡ª£¦¬’¡¶¼«®¢™— ¡¥­­¡­µ¢¨’¡  ¦œ™Ž˜´™‹žŒ•‹u”‘Š¦–•˜žŸ’…†¬¤‡œ‘Š˜©˜™š’‡¥±§¢•šˆ‰€inˆ‡‹ŽŽŠ‹’‹’¢Œ”ž œ¢¥“£¡” wœ–§ƒ¡§†©­…¥yŠ}„š}¢pr“‡–{žŒym‡œŒ™›¨š‡|‚¢sv¦fž~v¤_˜z}’s¢n˜·´ºt’‡‚µ¨dÆ¸{p•·‹q€›¤cs¬«`}j³~n}‡ƒŽ‚‹—q€£ls¤sžƒ¤`™³•p|—ž´ts[ž²ƒjbosuqhoXklrsf]i^bKD=D5QAYq3=SG_JR=<395::6D;;@IP?TMNQ@E_^[ZW``|dHC8LWUVbaZffkkbbeadc`ab`dd_`cknccddhdbgfchh”–•£¹™«œ“ ¤¸µ®­ ›¢œ££¦®œ›±­¬“—¡™¡¤™š”ž«›‹‰’x‹…p€–Š “”—}‰Ž¨ ‡˜Š‘¢“›šŒ‹¨¨¥ž–‡„~k{‡}ƒ‹‰” ‚–ž  Ÿ‹‰wœ˜¢Œ r¢‹ˆ©ˆœ¦–¨«®Œ}z ™z£“x€s–ˆœ}– ‡›Ž™›¦†¢d¡|ˆ–›lžh›nš™{€Š§}rht«ƒƒtªg”š]›…v„hªj€¸f\¨pœa•Œ^§vu‰Šžhšu‡“’˜ŽŸnšm§™]¨~w»k~ª[Ž„]´g\nqywki[qjxyc`fXbAPEN7VBRn4KZZ_NZC@151;;7H?:CGT?YRY]>Db^V`Qac}iEB9N[]XdfXfgnmbbe_aa__``ec^bdoq_deekecihgki•œ‰ª¶›¨‰c”›¬º²°¬¦œœ¨Ÿž®›ž°¨«—¤š¡Ÿ˜–– £™†‰jˆ€q{—ˆ‹––„‘”˜zŠ„–¤Š”…‹‘œœ‰¨£ ™‹‘Š€€i†y—Œ{ˆŽŽˆ–š”£Ÿ ¢“˜rhŸŠŸŒq’Œ©ˆ™Ÿ£¨ ¨}°­£¢¸—w£³¢£ˆ”y{«š¢Ž›—‰—q¡|…¯µ}kš‘¡x~˜´££«¨„™|›}š~tªZ]o{–‹xžbL~zz…cy—BMŸY¢jq|Žm‰„™u›y‡‰±³›“§unr|”o™rj¤]•vHec`sp}}ne`lhv|ddaQ^V]TV@YEQgDSW[bX^ID=B8?B:IE8LDWAVQ[VDFb\Z`K`m~qEC<U_bZejVghmobff^aa\]^ahb_edvl^egfkdflihki“€±®™„S_ §³¹³³©š¢Œœ«œœ©”¡«¤¡¨Ÿžš™•˜ –ˆ‡‰w…ny•…š‹|‘“–ˆr€‰“¡œs‘ˆ˜”Ÿš„Ž©œš”Š‹Š|ƒl„…q¡Œx…ˆ‡’™•|“¤¡Ÿ£ˆ®†}µ„Žž{¥–z©‚–Š¡}§hvm~™t¡sq|…™p“ƒ®}¤ƒ¦žš£o^¨gu£co¥aœÒ|z™xrsc¢…~£s£uk³‹`‚˜‰sª²¨¼wƒm~¾¦©´^œn}q—os¢r]£gt¦ah¦m›Ô™|„›oxy—k›zw—rm©¤g`eypƒkgfdmuwg`bS[eQQaIWIT_WS[ej\dPECKMJKBJE8P?PMWSXORR`feiRcwywIFEc]dZhiTihjocjg`c`\]]_hbahe|d^dgdkdjmghlh—›€±«T\K~©¯±´°³£œ˜…™¨  £¤¨ ˜©‰™˜˜“™“’ ˜Žˆ†{p}„h}‚”šw‘Ž‰o†“’l—”}ˆ‘‘£•ƒŽªš”’‹…‰yƒvˆ€n‚Ÿ†w€“†ˆ™¢—z”£¥šŸ‰³¡¢¶‹z¬§¤®¥p©€š…œ’|¤€¢™†˜rž„¢­®‰—Œ€Œ¤–ƒ­¡”vµµµÉ¡s”ŠŸ`–©my•†Ÿšu¡‡w ~‘–Š€oLf£’pš‡r¤{ytaƒ‚l~ kqd`œrt—i{j´µ´Æ¦s˜~{j››«uƒšltw—išzu˜rPD}³^jvkx‡fjgbttqnV^TYhORhIULYSU]hknVgWMJAJMKHJNAQJPdcimetrs~y{nu‰{{TPOl^h[kiRjhilglfce_\]\^ibdhk{_]dhcjfomeile¡œ‰°§„f?”¡²«¯¯µ¢£€—©¢¢¥Œ¥§œ¥‚š—–—œ“Žˆƒyjy†eƒŒ— yuˆŒi„…’ƒŒ…zŒŠ•¥’ƒ—©—Œ‘‹‰z€}‹yp¡†y•‡‰– –•¦©œ––„gnxœl¢d|q¥wœ˜pg§—Œ{¥zŸ–ƒ—ržv‰”–¹nŠ¢b}˜¡•ˆmri«ju mn¦`›hŠh–‡š•u¢€}š`‹…Œtoˆbh ež~išuocfˆ‚nr¢Z_[c¡n]‰Œo{srd¥mw¢dg§h˜s‹˜n¡oSˆo _e§T‹]T˜mmskqmphkxskoRXWVfYSmIXO]HXihsjYkVQREV\LXRaThj^wuz|p||rƒ{rv€„v^QrbgbpgPjhhklngdg_]^]`kcjivu]\cicjjslfkmcœ¥™¦zetm‹§®¤©°±¦Ÿ‹€—«ž¥Œ¢¡š¢¢€–˜“š‹˜ŽŠ{‡q€ˆh‹‹|˜›stŠ}|d‚‡•ŠŠ•™‚|ˆ†–§¢¬…Š‚Š}€€Žsh¦„}†”‰˜ Žˆ“«§‰¦x–œ¥‰–Œ²˜žƒ¯—Ÿ¥x•ˆz©t¥„šn¤¢Œ’„Œƒ¼n|¥¯‚†…†’–œŸ|¥zq¨• –gž}n«c–Š•’w¨l©¢‰u‡‚w«‘¦ˆk‘°kv³Œ©kŠ†nmŸž’•a«‹ªv€Œ¦ŸwŸ}…¥• iš‡v¬gž­Œ·sw¾¤“Yƒ¦«aurso{tqbj~nhmSV[Uaa\kM]R]I^mmv`[qY[`Zgsenoqcqt`wz~yryƒs„€{{Œ‚€vbxdcmsdRlgholrifia_^\bkbmlzo\\bibljwmglnb•¦ª€ž¤–©ª¨§®¤™Šƒ˜«šž¤‰š¥©œ„ŒšŽ†œ‘…’Œt†zˆ„o„~˜“tt†r’ƒm‹’‡†”|{…—¥¥¦ŽŽ‰…•v‚‡’ol‹©ƒ‹”Ž‰œŸ‰”«¤ €u”—‰y”®£›q†y‹„{r¦Œq}}z—–›„Žx{~~ˆ”•“Šv˜Ÿ ƒz}‰lŒ…[yxqyqhn~’‰qt‚”“q…ƒ‚e_‹wus”uoynn‡m„†^wixf‚†Ž©›~t|—j‰ˆo€v}…vmlgŒsy{˜x„[kXyhnwrqowxo]l†nigVZ`W\ekcUaU_R_pxylkvejkjv|qrtsaoubs{xuy‚u€€€x‹…ƒ}{mldxn^Wnghukxjijd\`ZcjelpunZ[bkdllynhloaŽ”¹©§‹¡¢š¦¤™¤œ«£¡„„˜¬’ ‰š¦š¨˜‚›Š~–“‡ŽŠ‰rƒ|}~…{—Žtrƒp–…{}’‹††…x~†˜£{§¡‹†…–ƒ†Ž˜wr…ª†Ž’œˆžžˆŒ›¨  «ƒ‰Ž”›€~‰–­¨“¦xo‘ƒz’o~¨…p}•qkp|Ÿ‹’ŽŒhm]ƒ‹Œ››žŽs•‹ˆqtk‚vs€Yrn‡‘}~Œj]jd{…ƒˆ€_ix{›{‚‹‚v†‚hy‹‡kaqrƒw_sŒ‚‰§•†fŒƒnw‹„q…yoegdzƒz–[\jgnv[{xwtmsr‚f\mŠklbYY^ZXlq[_aZ^]ft~{uotckkj{|r{xtdmtgl{~vz|{zz~o†Š„{}s~ysiT\qiluougkhd]aXkhkjqrmW[enlgszohjm`‹Œª±¡£¡šžž˜ž™¨£¢~ƒ˜­Ÿ”‡›¢¥•{˜„|’™‰ˆ†‡Šs}€‹v…‹„–Šqo€r˜†„~“„ƒ†Šz€ƒ‹›Ÿ‚¦¡‡xŽ˜‰•‹‹—…ƒz­‚‘˜™”Šž‡ˆ¡« ¢¢£‹ˆ“œ£™–ª¡§¦ ’›ˆ—Ž|xŽŽ„§~’‘’“œ±¦›”ž²“˜„¥ŒŒ•›Ÿ‰›‚‰‘Šk|vwe‚†Š{‰„‡‹ˆˆ€…„w|yuš¡ˆ†ŠŸ‹…”~Œ€vpt†„xˆ‡‹¦‘„…ˆƒŒ}ˆ‹ˆvl‚„|y™jrhatŠp}zwvowt]^o†hn_^Z\]ShqUc\\aliu||sopdkji{mxqioplf€{r‚€x}€„zmƒŒ†|zx|}zƒyNdvksmpzdkebb`[tfpfrrmU]ltmhyzqgikeˆºŸ—¢¡˜•™˜”™¤ ž{š«Žž…Ÿœ‹ž–}y”ƒ{Ž™‰†„„†nx€€rˆ~ˆ”„ml~z—†„ƒ€†„†|‡ƒ›’‡ªŸƒrŠ†“’Œ‘}{ª„’˜•œ—††›§ ¢š†ƒ‘šš™š¦ ¦–‘Šw|ˆŽ„¥{|Ž‘†˜©¡“«‘€žŒ‰“šž‚Ž—~†‚ox…qt`‚†u‹—€ƒ‚†„~…ƒ”nyut’¢‹Œ…š…„t€Š||rr{ˆ„{yŒ„“§†„‚„ŠŠŠw†ˆ‰‹|ok~€{mhlmg^yh|{vtuu{w\`p}nu`cZ]^QfmSeZ^akivz~qlldkjg€ls€lltoxn„yn‡€v‚€}„vrƒˆ~{{|{‚Š`i{juhi‚djc`i\duhobunlTcqyepzzseimm‹ŠŸ·›¢¤Ÿ’‘–—‹šŸŸž{xž¦›Š†¤”‹˜™yz…|‰‘ƒŒ‚‚m|xs…}Š‘}kh}—ˆˆŽ|~†„‡|€››‘ˆ§p‹‹Œ“‡¡¡Š…|¨‘ˆ’—“–“xŒ£¡¡ž–š€š˜“Œ›£¡¤š—‘›Ž…y€ƒ‡ €}ŒŒ|—¤  “™¦›‘‰’—›~’’~†ut‚pv`}†rŠ•|ˆ‹rŒ‚…†ŽhwqxŒ˜’—~ˆ‹s‚‡||py{Œ„z{’ƒ–¦“‹†‘|††‡…v‚ƒˆ‡zer{~xzpljf^}sh|uus|r€j^`tvpxdcY_^SkhTdY_agjvxqfkclhe€jm~hnqk}w†zkŒs}tv‚†~|{}jrƒnsia‡hlb_qVtomn`xhmWjtvcu{{rbjny‰Ÿ²’¦¥œŽ˜†œ ›œ|v¤ —Œ¢Šˆš–x{†‡~ƒ‰~ˆ‚€q{tv‚…~Š‘xgc}†—Š‚Šx}€Œƒy–€•—–– ›~oŒ‚‘”†¦›ˆ‰„¦•…’‹–—“’v‘ž¡¡˜”—z~Ž˜—Ž–›¤™“”œz†ƒx…—~‰Œs—¢ž¡“™Ž¢Œ‹ƒ–˜ƒ’–™~˜|ˆvq}nzd|Š…p†“‚l‡‚€‰„euo|‡’—}“x‹‰|€‡|{q~xŠ…y…‘Š‹˜¢•„wˆ„ƒ‚w|‰†v_xw}s}wflda~ijwstt}q|bcasnusmaZa^[kdRbW`ahkvy†qbjcmeh|ƒlhthloh|‚ym†q€ƒƒs|ƒŒ~z‚ƒ~|mvˆttmeŠljacuV„iqn`yglbjvpfy|zq`rl†…œ®—¦¨ž—‡†Ÿ“—˜}xªœŠ˜y—œ‹Œ˜y{‹}|ƒ{€‚€xtyzs}€„‰‹€d^}‹•‡…‡t}~Š}—„—“–Œ£¡˜r‡{“’Š§ŒŽŠ“¡’ƒ‘”—‘‹˜ š’‘t’”‰ž§˜˜•–tŽŽ‹l†˜™z‡ˆ‰o—š£“•ŠŸŒ†’œ’’•†™ˆ|‰‰zqykul{}‹~n…’‚”wo‚ƒ}~Šdrj{€–—„t‰ƒy‡~ux€}‡€|„Ž…Œ”¤y…‚t‰‡}€tv‡ƒn`{uzq|oance{bnovrwwstav_oluno\\_^^j^O]Wcahmt{‰k_jejchw‡mflhilh€|zwo‡sƒ„}s†‰z‚}z„}}ŽrzŠxxnl‡kh_iqc‡hqoewhnlayhk}{xpawm‹™šª £¨ŠŠ‘†ŠžŠ•—}w®˜Œ–}ž“‘–”ˆw~{Š}|€vw€put{o†}€Š|a\~‘†ƒ„sz€†z‘‡’‘›’¥›•‚~|Ž‹’¤‰ŽŠ˜›†‘˜“–Ž‰‰Œ““Œnƒ‘‰ž™¢¡—–Š—‘oˆ™„g†™Ž”z‰…Šp•š”¡’’ˆ‹™Œ‚ž|’’‹™Ž{Š„‡tsukqnu{‹tn…Ž’qt€{‚ˆ|dqly}™”}„ˆt‹tˆyo€~‡|…Š…•¨{ˆ}~‹…x~qp€…ƒchxtvp{b^paku^qjzxxlrpex]mlsmsYZ^`bjZPWWecgqq‡f]ihgbgqŽodigejh€zwtnŽ…t‚{u‚ˆ…w…|x„…z€‰w‹{zryƒjk_pht€kromqgole|cn€yvqlwwŠ¢˜¢¨ ¦›‡ŒŠœ†“œuª”’† Œ–“€t|v…wxrs{…kspznŠv€‡nq[Y~‘ˆ€€vu€€ †Š’œ—¡”˜xŠ‰žŠ†’˜–…‰•™—Œ‹ŽŠŽƒmˆŠ‘‰œ–¡›˜•†˜ˆj…£ƒg†Š‘~‹ƒ‹w“˜‘ž‘ˆ‰•~—|‘š’|Š‚nvplmnp{…isƒŽ—Špwt‚‰‚xfsov™Ž|‰„z”‘zwˆtp‰{†z‹‡„‰œ£ˆ|„w‚‹xxok‚]rsqqqxZ^p`qk^oi|ypmmjlv`pojrmZXaabnXQSZfgcup„‚b]jmdbfk’m`ff_hjuqrp‹€u‚€xu€‹€x…w‡†wƒ…{†Œ{vŠjqc|b†|oqltjholvw_qy{tut€‚~¤•š­ž¦–…Œƒ—”ƒŸu‹Ÿ”“…Š›Œ•‹zrxt‚pr„squˆlpmumˆwƒ~€mnUQ«”‡‚x€vr‚y ‚‘“’˜œ’šx’{ƒ“¤š“Ž‰•™“…‡—™Œ”Œ‰ˆž…Š|rŠ…‰ŽˆœšŸ›–””i†ˆg†¡ˆ’„‘ƒ‰qƒ‘—šŒ‹w{’zŽ‹Œ‘–Œ|ˆ|€kvjnkklz~ay~Ž•vz€wƒ|ygtlt‡•‹ˆ†{”qz„pwŒzŠŒz‰~ƒŒ‘Ÿ…}|x‚Œ}wqjl‚y_womlrsV^obra_lnypgpffsthqkawe]Wfa`rSPN\fe]xpˆ|_\hrbbef’i_hd[gp~pkpsŠ}v|…€tuŒy{†xˆƒs†…~ŒŒƒ{y•wfrjƒ`ˆ~ookz`jntt_t}y†xts…|x ™°œ¥‚Šƒšˆ‹ž‹š“„ˆ˜ŽŽ„vtvs€po…spqƒokivm‚n}|musRN‚ßȒ֓|ot„vƒ ‚“w•‘™›š{”s…Ÿ¡““‰“›”†~–•ˆˆ‘ˆœ€ŽxzŒ~ˆŒŠœœ›•“zŽvh‰’‡lˆ£…’‡—ƒ†cŒ‘™•‰–ŒŠ‹q{”‰zˆŠ’‘‰y…{~l{erokkyy\€y€z}~†Žzyhsks‹Š‚……}•Œk~~n€ŒŒ‡}„{ƒ•ššŠ|wxƒ‘ysmfpƒljtohjtmS^odpY`kqwfkjbfxrppc_x``Vk_^vONK`fc]yq‰t\\ev`aeed`faXissnkqvŒ|ty†‚uv~‹s†{‰~r‰‡Šˆ|~˜vesm|eˆ~opl€Zlnyysavz{vswŠwyŸ‹›®› ‚…wˆ•~|‰œ‡…Ÿ‘Ž…Œ—„“Ž‡twpyqn„omn~rddxp|mz}jhlc¤šÁÜ®ï¡sku„v…¢…’o–• ”œ’q†‹£—‰•Š–ƒ€•…‰€’ŠŠ—‡{u‰x†„œ›˜™wŒvn†‰‹}Š£„‘‰……^‹”—ŠˆŽ‹‹„‰l|–}ˆ…‰†v…}}k}dxujnxsXˆz‘†…z~€…‹~xesjŠŽŠƒ‚Œ–…kvnˆ‘‚…‚{€‘–“™utxˆusqguy‚btmobivgR`qglU_nty`rc_h}prn[crabWnZ\wMMLdfa^vs‰m\\dy^`df…`cb^YjrknkrvŒ}tw„xw{‰qƒ„}~ˆ{t‹‰ˆ•†Œ~~˜shuqym‹zntpXqzvyqewy†Œiw€‰rœ‡˜§œ£’„|pŒ”xy‹„…¡Ž{•™ˆ„{rwpsjokil|t^`xv{pu{gae|ëÚµÉÃ܈slswŠšˆi˜•“‰q…‰ Ž…Š•Š˜”|“ˆƒ‰{‘‹†‚vxƒƒr‡‚“›–”˜†Œwˆp…‚‰‡™¢ƒ”Œžƒ‰aƒ•‡‰†‰‡€‡i}”}ƒ„‰Ž‚q†~qwhvriswlZŒ}’…|ƒ€„Š‚uatlˆ‹‚~’‘}m‚lx††“„}~’“—‰orz†ulqkrx€_sin\kv`RdrifS_pvt`o`]h‚qsjWghciXmW[uLJLeg_brs…i[\ey^^dg{`d_\YkneojswŠ~ss~zvzˆs…‚|€‡vwŠ†˜‚Œ{“vlvuyx“tnxz}Xy…q€ogyw’‚dv†…qŠ–…™¡›¢Š†so’‹rwŽœ}Šš‰‰|Ÿƒ™xqsnodr~hflww[_y{zqq€iagaÕ¶Ž¦xnqw{p’Œ‡j™Žˆœ’Œ…{iˆ‹š‡’‘†‡˜|‰Ž|~Š…zu{‚zp†€–™Ž“”ˆuƒ†vƒ€‹“Ÿ†•Ÿ~ˆa€“‡…ˆ„‰ƒg}~‚‹~m‚|‚tkmvtsvukbŽ…~|„„‡~p_sq…|‚|’‰zpƒfyƒŠ‡Œƒ|„~€”‘“„npzŒunojlz}bhjiXluZRirjbQbrxlae]Zjƒmsb\g_dl_nT[oNHOge\gnq€lZ[cs`\clwde]]Zllbmjsv‡qo||tx†x…‚}€‡uy‰’•|ˆ†v‰owy{„“pm|w^ƒtmi{s”sgs‡|r’‘ƒšŸ› †‡vv”~mv“—~ˆ‘ƒŠš|‹šv}vqoljat|gbiuzZ_w|zmqedhhW^qr–¼Ãƒuq”‰~r—Œ†œ“Œˆsk‰–{”Œ„›Œ|‹†}|‰Œ”ˆu‰…vw}qu†ž”†•ƒ‚rˆu„|‰˜˜‡“Ž€ˆe}“‚€…ƒ‰‰r}g~‹{x~‡‹Ž|i€|ƒvfoxxsvslj…ŠŠx€„ƒk^rxz~Š…{‚€~r€ixƒ‡‹†„xƒ|—Œ}nm{‰}wuohg|vc\pbWorSSnsiaNftxe`]\Xn€osYeb]jm`pOYkQDSgaZknm{oZ[^mcZbowdf\]`ljcmjsv‚ƒqn~{tuƒzƒ‚|…v~‰–xƒŠtˆrxy~oo|qiyz~mm|v•kjx„tl”…ž˜ ™…ˆn}Œvjx˜Ž‚Š‚•—‰yŽ–ozspljd`t{h`eqzZar}ygqzaee±²wJbZ¤ÙЖq{‹x~•‹…™‘†ol†’’zy’†€„˜Š|‡xx‰Š„–€o‹ˆqt}ziy…ƒ¥‘„“ƒo~ƒv„y…›˜“‹’”…‡p{’ƒ}ƒƒ‰ƒnxh€„xr‚Š†{e}~„udps€hxpou˜…‚Š{vx€„yk\q}rˆ…‰}†‰zˆr€nq„‡Ž„…s„x€™„xno„w{ehj}p_YwZXqmNWrsg`Klvt`][[Yt}roWg]fjq_oNWhQ?Yg_[pjgyq[[XkeYcpy_h\^emhfliqw‡ol}€upz~‚v…‰—Šq‚q{†|yyƒ“Œujzko~t}or|{”on€xg’Š‚¡™‘‚†g‡ƒogz•‰~…™Š|Œixrklf_aoym_boy\dk‚zaqv_efÔ꾊2:>‹Ž€ry…ˆŽvƒ—Œ~’Žnl…Œv}…‚•‰|ƒxnv†„ƒ—woˆ…ku{tfy‚ƒ§Œƒ‹„}ntvƒy†œŒ‘’Œ‹†~{’‡x€„ƒl€ri~xm|{Šƒwby„qdqh~mtqu›‹€…~ru}€rp[m~txŠƒ‹{‡€|ˆxzqlˆƒ„‹ry—‹‹tnkw€€uu\ihwpYW|SZpeLZrre[Jpwo\ZZY]t~uhYb[gfnciLWfQ=^f\]ue_toZYTodYdqyZh^_gmgjlipw}Žli‚„~yn€{}‚zu‚“…p€‹nx~€z{ˆ’‰h{}jt{r†{sw}Œyx„}|kŒŒƒ›–Œ€lŽ~kh~ŽŒ{~ƒ”‚}Šˆkuqghc[bgro`altahp‰ybst^cd› n\5Y¯µuj€‰}’†v…–…sŽ‹Šwpm…ƒ‡uy‰x‰}“ˆzsgvˆ~~˜oq†~hvymeyˆ„¥‡€‡‰~n~v€|Œ™‡‚“˜ˆ‹„‰|ˆq{}„|i~mk€{zizv‡r`w~qdrgu‚mt{…”‘|nwy|t~mXovtŒ‚†wˆv‚‰zxsn‰…r~}~“‰‰znnjn‚‚un\gfsqQ[{N\p\O[rpdVKsxjWYYZaq€t`]]`gdhifNYhM@ad[`va\tlWWStaZdorWj^ahkgmlipw|’kh„‰||p~~{€‚zw€€Š‹ƒq{‡oqwƒ{‰ƒj~{nwyvŠw}x€‚‡ƒ~~zm…Œˆ˜£„ƒ{u‹ykl„ˆ‘x}{‘€€~Šƒprpcf^Yg_pp``gpfjoŠtato[adjv{¾œ¦£È¸q…„s”}x†“‚s‘ˆrrp„{ƒtu‡tˆw”ˆyyqcw†z€“ir„vfwvcj|ƒˆž‚ŽŽ}r~s„y€‘‚x–”ˆ‚ˆ{‰‰lyyuh{ikysizv€‚}h`w‡}jkth{ivŒ”~z~~p{v{t~bVw}rsŠ„‚|ƒq†Šwxppƒ‚}y~}vŽ†ƒviqimˆ‚rp]hcsnJeuL^nUTYsnbQOsxaRXX]bp‚s[a]hedcjdQZpIDda[cp^]wgTVVw][enhVk^ajgeoohpvz’niˆŒy}r{~x|v}„ˆ†ƒpvƒrnw‚‚~‰‹“p€{wyzŒuƒx‚„z€uo~‰‹šžˆ}…zw†{gt…Œz{‰†„v€gon_d\XeYmra`aqlkh‰n`siY^dm€w©Ú©Ç†‡²q‰xpu{‡€z“Š€utu~w€pqm„t”†xul`z‚yˆfqƒogvn[m}€“€€x’’}x{m‡u€‹„t–Š‘Ž‡……{…luvmhwem{vmjvw|`bx†zhtuc~zgt…ŽŒ•{tuq€z|mYVt~ou„‡€ylˆ†txkuƒ„}{}x{r‹}sgten‹„mt[j_udHnnL[bWVUxmbPStvXPUX^aq„o\`cmec^nbT\rGBf_]fh]ZzbQU\u[[gkaVj_`nffkqhpuxŽtkŽuvx~wƒ{t~„ˆ‡ƒoqtqu~…‚‰Š{wxƒ||…‡x‡|}~„€{~svyŒŽŸ‰z‰vtƒy^}…™Œy†ƒt…†…w‰{bnl[b[[aVjsc`\gnof‡qaqfW]ck|ÊΈ¹¢jmmŠlq„r|…Š{‘…zytyuu{jluc„u‘‚wpg^}‚z‹‰er‚kjqcXl{†œˆ‚s—”w~{nˆqŠ‹‡q—Žˆ…‹ƒ{y~qqo}fhrbnxqjkqw||y\ey€wiuxf‚vgt‡‹”|r†io~€yn|]Xrmt€‹|‚oo‰qvhwv}qzt‡|zrfsanŒ‚lsXk_w[InkMVU^TU{kaOTurQQTV^bt…h\`ljfcYnaXbpGAh]`f_]U{^OVdpY[jh]Wh`_rfkhrgprw†xn•Štzx~y‚ˆ€us€†…‚pp{xwuy†††‹†z|u‹~}…„„‡~~}‡|xvyw’“ŸŒ|‹mv€ycƒ‡—†s’‹o……zƒtcnjY_[]]Tgse`YdrrfsbkeW[`iw¾®{ ·mbs†ht|rzƒ†{}Œxxsvo{vejn`‡uŽsjb^~xy‹„fq~hjkZVoxŠ¤…q™“q€xu‚m€‚‘‡s•ˆŒ‡„ˆ…}xtrnhy`jm`mvkgjkywzw[g}|xer}n„teu…Œ†•o‹fkzƒumtb\o|ku|Œ|fu‡}mqgu~x~r}lzzzxpflbnŠ~mnVk`wUJjkORNhNY|hbNUvjLPTU_gvƒf]`qhgaWi][khJEkZbdWYUyZNVmjY]le\Zec^tfmdqgrouwp™…v~w|…‡}us‚ˆ•‚nsxzzss…‡ˆˆ„y}v|„‰Ž„‚„{~‹ƒ{w|wwš—zŠƒ†iw}|lƒ„“€r‚q…‚~oflfW][\[Tdqe_XcsuiupeecW\\h€por€t‰eex~itvssƒ…x€„ywtunk{pagkg†t„nf]_}p{‰~imwfidUWrp¦|„|v–s{s|zn{{…v˜|‡†ƒ†ƒ|tprlgu\mh_ltdgfizo{rYgwtgp€w‚ubw…Š|”€n‹jmzqfse`mzgswŠ|~buƒvikqtzpyys}f~ywncfbn†|mkVjbpSKikOLNpG^{faMUtcJNSWajv~e\gsif`VcWbp]LKkXcaUTUsVLXudZ_ka\[ce_wfmbpisnrttšw€w~†…z}u‚„~—…nrt{zuq„…€z‹ut‘€}”Ž€…„}~Œ†{~€v{£¥Šyˆ…„lu|{uƒ‚Œzn…sz„}ƒunjheV][ZZTbnd[Xbs{ihmi`bW_Zi€jko€hlahyxktttn…{}vumzhjyj_enhv„geXbwi~‡{oiogf]UXoh§vz|Žyuo~osuy€w•t…‚…ˆvjrvghn[ld]ls_gaixh{mZm‚rsio€~ywaw„„x„rˆqoyrcqh\owdqsˆ|xbs€pgjxsrlxwuwdƒ{wvoddcn|}klUibfSKmhOGRkEaxgaMSq]IMTYekw{e^mqid]V_UnnWKThXf^XNUlTJ\y_[_k]]Zbe`zhlaoounowuz˜}w€z€‡†zxzƒ~“„qtt~zvt…ˆ}€}ls•|ƒŸ…‡}€~†‚€Š{v„¬Ÿzˆ‡„lr‚zv€€un‡o|s‰€jomddX_ZYZUbjg[Z^ui^nl\bV\\kfrt}ij]kvvgtwqm…{}}yvrlzhixf]dshzw’ccTepg‚…wwfhj`WVYhd§n~x€‹Žzpp|fyozŒ{vŽq„}~†ndvsdhh\kb]oo[g_ludzh]t€orkq{}uubt…Šz‡†wruuaplYqtbqr…|udrlalzojizxurf…uzzupdadns~ilTi^]TKscQGVaGbvfaKToWJLXXglvzdenqfcZW]XveTJ\cXhXYIWeQHbxZ]_l[^\ad^ij`otxmonvƒ˜yr€|ˆ‹†}uv†x‡Œ}tuu‚xzz‚ŒŽ}~„‰jt—{‹}~…zz~|†ˆsq®Œ{{†~frˆzt||vro†l{~lzbpobe]eVYYWdfk`]\s…hXqnZ^WZ\l{cpwvlb[mstguupm„x~€ywnnteite[gufvv‘z_]Refj‚‚t}bci\TX^bc¥hyt‚…xmnygxm|…{uˆr€x|xhevm`f`^j_]skYe]oobze[w{knnpwxstdrƒ’~‡‚ˆzvor}rbxd[opbqq‚|sfq€d^nvidgyztnout}sqb_fno}djShXYTMw_QJYYHbtdaITmSILZWilr{bllscaZZ[av[SKd]XiSWGY`NGiuX^am[[_bb]…hhanxylnjvynƒ~€’ˆ„vt‰tŒ†trwvw|}~Œ€~“~px–ƒ}™’y€€xy}tˆƒsp™¢{z‰•yduˆysxulto~ly|p‘r^po`gblT[ZWhcmf\\qˆeRrn[ZXX`lwdiujj^Zmsqmtstj…|~|wnnldiqc[jrdtvs[WSdar€r‚]bc]SZ`[c“Ÿerq…„‘tljylopz|{q€wrzzzdfvg]bZag[^whWb^ohaw`[{vjirnwssthp”‚†~„vrjp|mfwW\kmbqszsfo~[`oqb_jq}llt~sqxkpa\ellzagSgUWRPv[RPYRIcsb`GUjPHOZVklk|fmoqa\ZXYlpWRPfWWiSTFZ\OHruX_cmcXa`a]‹jcdmyxkniuy†{kƒ}€„™|‚„y}ˆn†qowz|t‚‚|‹ƒ‚–tx‚”…Ÿ‰u€€sp‡‚uo¢—t{†‹‡{fx‹on{ofxpzlsvrŒk^tnagekR][VgbllZ\qŒdOon]VXUgjthbtee]Znunquuyk‡||ˆwsddkna\nmcsx‡kZTVbcx}}q…]c_cT[`Yc–•cnpƒ…Šsjhznesvs|lztuoz~u_frc[^VbdXaueU_`mdaq]]~phisqspuukm„“ˆ{„qrfn}proS[fjfqtwsblvUbqj[_ne|emv|srsjm`Zdjjw^fTdUVPTmWQWSPHer_aFXiNHXTVnid|ikxkbW\U[tdSRWhQYfTSHZZPMxw[_eliZb`^^nbfkyunohvvlƒ€}†—{ˆŠk“ˆrgt€{u€ƒ}ˆŽ‹“r}Š‘…‡Ÿ†{†Œs€†s}ƒvn¥Œs‹wxnzŒ`d|pfzsylmqv‚gd{lcfghS^^Tg`lo[^nhNjm`TVSogtkexde]Yptmrzxsmˆ{€vœ{zkaelm^`ojepy~gZVX`kx|{p„_b^gVY`Wdœˆbkq‡}wkkxl[vqlzivsno{€rXjn_Y]UacWdqcS^aibblZ`~lfksunmwvkh…Œˆz‡mqfp|mrmcY`hiottr^ilReqdTbnbzcqv{ukpmk_Xaght\eVaVSNXeRO\OOHep]cFYiMI_KXmd`xhn~d`U^T]t[TR`fN]aTSJ\YPYuv]_fmhXca[^Žpcgjwqsmhvtzƒsƒzˆ~|Š‡ŽznŠtls‚tˆ…†‘„•z}Œˆ‘›„€|Œ„sstxqn““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~~~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’’’’’’’’’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’““““““““’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z||}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ>.1111/o‡„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDEB1//000/>DDDDDCXhggggfo„ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ-h…‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR4555553.755554Ma____^j‚€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}z{z|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‘‰‡‡ˆˆˆ‡ŽŒ‡‡ˆ‡‡‡‰’“’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†………†…ƒƒƒ„„„„……†…………‡‰ˆˆˆˆˆ‰ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z{|{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘“““““Ž‘’‘‰‡ŽŠ’“‰ŒŽ…Š‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…Œˆ‡‡ˆˆ‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰‘†…†‰ŒŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰ŒŠŽ‡‹‡ˆŒˆŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}|}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹ŒŒ„‹‡†ŒˆŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz||||}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒˆ‹Œ‹ŒŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzzz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{y{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†……………„„„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰ŽŠ‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{}~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““””””“””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••””•“’’’’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””’’“““““’’“”““““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘’’““’““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’‘‘‘‘’’“’“’‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡ƒ‹Šˆ‰‰†……„„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxz}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzop{xy{|{xw{xuwttvtuvwuqrqnprpghklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkiffggghhgmgjghehgcbbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__ac_\_]`]^Z^]YY^ba^^ZY_[XWSNMLKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{xvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSTPMJMNPROMPQQQQRVVRQQTPPNNOLJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTtsuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMOPPRQONMOOONOPPQONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKLFDFJKJNINNLMOMLLNOOOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEBA@@CCESBUPHKOKIIJHHJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:;>><ED=?FYC[V>EEGGGGBDDDFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@;;><;;<<HL==C]D^a>ADDFCFFDFIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnpprtusqrvyy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;:;;99:88;<979;<>=:C`>\kCAB?A@CFDCCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqusurqtxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<:79::979::69:99:Fg@\m?98<<=@A@=;;><==@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyy{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>><==?@===?D;>=>;FiK\m>:<>=??@A@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquutusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCDA?=>@A?@;]pB>DF?MdX]e>==;<>>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVppqssttuyz{{|~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???CFD><<=@=8::nwJ7<9EZc``dI;<=D:;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pprrrtuvz{}}|~~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC?>AAABA@[Q<<=LPIHvwO789Thmghl`A;NQ9;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC@EuyH<a„€z{w\F=AertlmrmOFfO:=>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hloppqtuvy|||||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCEAIsykf„„ƒ‚ƒ€}`XQFbqrqouq``iJ@BBFHC=<@DCAA?>=@A>>>?<>@DGE@>@A?@CFECBCC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{|{}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@Gpt}‚‚ƒ~}„tJSfXaqrtv|tkmcIJIIMMKECFGHEGEEEDDCA?@>>BFJJGEEGFFJNNKJIGGHKLIGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@EEis}|„~y†qBHdmlv†‡‡„tkVIMLNOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHIHGFEFFFDFHGEEHHFHGHFQnnpqrvvy{{{z}}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJG`{€x€„…ƒ„Šm@Os…‡‡‡‡ˆ†gJLMLMNLJGGGGDGGGGFHFHECDDFEDDHHCCCGJJKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrswwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLLN[|‚ƒ„ƒ…‡…‡‚Vl„‡‡‡†‡ˆ‰ˆ|QKLKHGFFDECC@ACCCCFFEB@>>@AA@BD?>?DFHDEGIJIIHHIGIIJJIHFJJJJIJIJJJFILLJJKKfopsrtvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKLLJV‚„„„‚‚††…ƒ‚…………†††‡ˆ†ŠuIIFB??@???<<<>::<AA@><998<<=;>;9;?AB@ACCB@ABDDBCFHIHHHLMLGIJMMNMJJKKJLMSloqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHHJJIf…„„„€ƒƒ‚ƒ„„……†‡ˆˆˆˆ‰‹ŽfBB=88::9878896479;<:8567789787688;;;=@;999=<>;;=ADEHJMLLGIHORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@CGIIj†„„~ƒƒƒ‚ƒ„†‰Š‹‹‹Š‰Š‹Œ‰T;8656766645763468:876565676778:77789;7578979876:<@GFIFIFEFOSRSSROPPRTepqsttwy{|{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:=ECBf…ƒ€ƒƒƒƒƒ…‰ŠŠ‰‰ŠŠŠŠ‹‰‰ŠH676468874578467699766765:9:::;898987779:98868589;A=>>BA?AKLOQPQOOORWkqrttuwy{z{|}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897;B:=r„€ƒ„„„„„†‰ŠŠˆ‡ˆˆ‰ŠŠŒŠ‰‰Œz>:88;<=>9:;<89;9:;:99;:9===?;;;=:>;9;;<;<<9:<8::;:999<?<=ABDIJMKIKLWorsutux{{{|{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<;89989:::;?>H~„‚‚„………†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>BCEEAAAB>@B@@>=>>@???@?@==?B?AA?A?=@@@>?A=><;:;99;?=;;==AACABCAXpqtttvy{{|}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::<=:;;==?@BRƒ‚‚„…„…„†‰‰ˆˆ†††‡ˆ‰Š‹‹‹ŠŠ‹Š‹^>DGIKJIFGGDFHGEBA@CECCABCB?@DHECEDEEAFEFDEFD@B?<@>=?@>???>?>>:;=<`qrttuwzzz}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>???=A@CCFX…‚ƒ„…†††ˆ‰‰ˆ‡†††‡‰‰Š‹ŒŒŒ‹ŠŠˆWHLMMKNJIKHIJJIECDFGFDCEFDBHIKHGGFGGEKIKIJKJCFCCDBAACBDCCDDCA=;=@hpsttwwzx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLK@BBA98<>;<;>@?A?BBGGJY…‚ƒ……‡‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹‹ŠŒPMPMKNKJLJIIHJFDGHHIEEHFFELLMIJGGHIJOMNLLNKGGGGEECFFFFDEHHFCA?@Llptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?EGG=<@@88<;<=:?A>@@CFIJQ`‚ƒ…„…††‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒ‹ŠqMQOMLLKLJHHEJIDJHGKJHJGGGKLNLLHHIJMPNPNMOKIGIJHIDIHHFFGGIGCBACUnpuwwy{xyzz||}~~~~}~}~~~~~€€€€€€€€€€€€€€TDAABGHB?8?@8:<8=>;=A>?@EHJLWrƒ„„„„…†‡ˆˆˆˆˆ‡†ˆˆˆˆ‰‰ŒŒ‹ŒŒŒ‹‹‹‹_RRPMNMKJGFBGJGLJFKOLKJJMMLOPNHIKLOQQQQOOJIJJLJLFGHGEGIFEEB@BB\orwxyzyyyzz{{~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<9@>>@BGGAHKLPWy…ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹‹ŒŒŒŒ‹‹|WVRRTROLKJDEFKONOWVQPOQSRMSTOMSLPSUWRSQPLJMMMKNGGJFFHJDDEEBDCcpuyyzzz{z{z{|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?==B?CBFVNFOPPTY|†ƒ……„„‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒ‹‹‹gVUkaERQQPI;;QSR`u]UVTVYYRYXRZfPUWZ]RTWQPNRPPPQKKKHHJHEFIHIHIirvyyzyz{{|z{|}|}€~}}}}}}~€€€€€€€€€~~SHJIIGGFE??AAEBCGEDELXRMTVVX[|†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ}aŠ‹‹‡l[dU:XXXSQ?@VUY\d`VYbr^]V]ZVEQYZ[Y_TZgRUVXTTVTOOMJLJIILMKOMSosvxyxwzzz{z{|}|~~}~}}}~}~€€€€€€€€€€~~~VJJIHGFDDBA?HMIMPKIKPTSSXZZ\\y…„…………†‡‡‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~Œ‰Š‹znpXZ[ZRTRVVTZZuƒYU}a\X]^WIV]][[_YIYXY[]XXYWRQNPQMMOSQQURassvwwvxxxz{{|}}}~}~}}}~~€€€€€€€€€€€xy}YNKIIIFBD@A:PQQWXPPOQSTTXXYZ[n‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡ƒŠ~fYY\YSUTWRQWVc–€QerXZW_hP`f[[X\gaGOZhg\[\]]WROSPPQVVVVYZnrtwvvtwxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZ[RSQORRRUSVTW_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PUXTRTRQQLOMKfyZ]TYUV]ZLTZTST^ZXWWWzkXZ[\^TQQPINOWVXZZdqsvvttvxyy{{||}}~}}}~}}~€€€~~zxwvsu{€€tk~~kry^[VUTROKFCDAM^ƒlVRSNOQOQURSRRTcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ymqVIKMNKMKHJDFHEC>ScURQQNKRTQMOYQMNQSUUMQSRPOMLHCIHRTUZ\mruvussw{z{{{}{}}}~}}}~}~€}}~~€~{vsw}~~du}iqt_d]^[YVPLILIal’tPQSNQRQR[RSRQRVUbs{|€‚}{{€ƒ‚…†‡‚†††„†…†u_]KC?CCCCB?DPBD@C>BHGV@HNMG]iQHFOFDEFHGHBCHGHKGCBAD@OPMSdstuustuz|z{{{||}|{~}}}~~€€€||}€€€}vt{mh|gnqfiedb[XSQPURsWe[OONLQSQUYSUQQTSOV`klrv{{xytrnstsyx~~ƒ€ƒƒ‚€‚€‚kLG??;;>@@??>kQKaEFHIEB?GLMGMQUIBE?><=<==?=?ACC?><=B>JMFUnuuustvxz|z}||}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QRZ\Y^IJPQNKLQRQTUUWQQWVPX[b]agmmlokh`nrjmlqu{z}{xz||xwxdB@@B=:BCAADB\]O{NOONKLMOOQLKLWMHG@B<977599=;;;8989?;BH?\ttuvuvxz|||}||}}~~|}}}}~}xuvz{zwyxuw{|yxuywcqhipmnmmhf^OP^\ZIGPRQOMPQNQRTVXSRYTNYZ[WY]^^`e`]^qvk^`gkwooljonnlfbXGFFHBAGIEEFDMRPaWRXQPSSRU[OOQWPMJCF>::6487979:366795<B=essvwwyz{}}||{|}~~~{}~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZWMLTTSQQUOLRSTWXTTXQLXYZVXXVXY]WWXhsk]Vaskaa_]da_^YUPMONLHHJKIHFCQPSZWTTNQSYS\eUOSTQNKIHC?A9988978847578599Gnqtwxz{{}~}}|{}|~~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPXVVSTVOOUVXXYSUTLKTUUUUWPTUWTUR]n^RNY_[VY;DVXT[fJLPRROMMNNNLJFPPUYSTNJOOTST\VRUSROMKIHHF??=:787659967665Wppswyz{|}~}~||}|~}}y}}|~~~}||}}~}|rvqxxrvuqqnppopuvtnjddjppqrpnfedc\^RTZVWUTWTRXXYYYRUOIGOPOOMRJOPPPNNOTLMIPOSTU2<XMIAQ=caQSQPNPQPNNMPNTRPRMILKOQPQRSTQROLMKLLHCBA=::876;B4566;epqtwx{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqptuvcjgeWhtrrqniihpVVTUXUWURWVUZYXWUQSFFAFGGHFJDHJHGEHLHKHFLMPMG/E_R>3@>joaRRQ@FUQPQPQNQOPOLJLLOPNNPQQNPOJLMMKGEEDB;=<<9=G6676Dnqtvy{{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknbePSTRSUOWVVYYVQQQO@>;=?@BAC@BEDA@GHGHEFHJNKEGCORC8ENS]fSQSAGUPOQQPMMNLJLKLNOOQMOOMHLLIKKLKGFFED<AA>;@E;<89Tqsuy{{{}||{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLOOMQSLTUTWWULLKH=987;?@><=A@B=>EHGDFFIGJJ@FAA@FHEJOHPRa\QPRNSOOPLLOMKMLMON[WKMQOGIHCIJLLKFFFD?BC><BF?B?Adqux{z{{|{zzw|wy}~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCE=9879?B>;?B@@>ADIECHGIGIEBB?>=CBAGIDMObeQMONWKLMKLMMLLKNNSdMJLRIIIEAHJLMNJGIFBAB@?EFEHDKopwzyy{{z|zwsxtx||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGLMIMPMPOHKE?B=999:?B?<@BBADEGKFDIIGGHCC?B??@A>CECKNQTLJIMTFIIJLJKKIILMOPRPKGCKGCBJJLMOMIJIGCCCDIJMLIZsmxyxz{{y|vrpurtyyvxjqnjllnttmtu{stxronqovsnporpopstyjN`gsjt|ygosqjqheqHKDGHHGJKIJKDGB=>=:::;@B?=BBCCGFJLJEIIFGHCC;A@B>@@CEDIMPGIKGHKDHIKMHJLHHJLKM]RIHDMFADKKNMPNKMJKFGGJMNQNLcnivvw{x{z}qmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoijthdoFKDFEGDEEGEGBC@><=:;::@D@>BCDEIFJJLFIIGFFDB;BCC>@CCCEGLNHKNHDHEILNMHILGEFIILNKJHENHCGMLOMOMNNMLIHJORQRNRfgfrosxu{z|lhjnekpmsqfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGJDFFEBBBE@DB>?>:;;=:=>CA?ACEGJFIILHGGGFEC@=EEB>BDCCEGHIGMPJFFGKNOKFHJFEDEIIHKIFHPKDIMLPMONOONJJIMRUTROWd`amgproryzgehhcilgqlflmgiklslpvutpnvrosrsutqssutsuvvvyvutvlkuumrvqlnlerMGEEGCBABD<BA>A=::=?;>>@B?@BDGKFIGIHFFGECBAAFFCBCBDEDGGHFLQLIOJJLKIGHEFEDCIHHKJGKRMBNOMQOOONOOKKKPUWVUTX`^\iaminhrsbeffdihfnifmmhkkmriqvusqmvnoqrswsrstuvvvvwvwvvtwuksunutsqrjksMGGFHBB@DE<AA@C<89=>9?<?B?@@DFHEHFFGFEEDCECDIFCFEBEGEEFGEJMKHQMJKHHIEFHIECIIJKMKOSNDQRPQRNOMNPMLNSWVWXVX]Z]d`hbjigk_eegcgggkggkmkmlpqgttursnvoqprtxqssuvu‚‘yvvtxuuwxnouorsuqqiozMHGHHBBBFE<@BBD<7:=>:>:@B>??CEFDFDDGECECDEFGJEEIGCGHFHFECFJJGMJLKIJLFIIKHEKKLMNORTOISUTQSPQMNQNMQWZVZYVZ]ZXa```^hec`dehgjihjfhnllnmqpiuuxrrpupppruvpusuvu{~}xvtwvvvxplupmstnprsyNIHGIDACHE<@EBE=8:>>=<<AB<?>ABFCEBCHDCEEFGGGIFGKHCHHGIGFDHKIGKHMKJKLHLKMKIMLONORUVOKUVTQTQRLOQPOTYZY\ZY[^_^`b^\ackb`dghr…hgifjmnponsqjtuxrsstrnpqvrquruus~yŽ}uuvvvvxrhuqkrtlqvquMIKHJEBEGE<@GDD@:<>@?>?CB<@>AAFCEDDHDFDGEHHFHGIKJFJHHKHFFLHHHJGLLLLLIMKMMMOLPPQUVWOKVVUSSRQLOSRQV[[]^[\^__a`ad]d`ef`ehjcssfjhglprqossnswwquvtsmoruorspurvrtvuuuwvuwtgtrkqrkrvovJKLJLGBEDE<@FDDB;??A@@@DA?B?ACHBFEFGEIEFDIIGIHJMHHJJILJFJKHIJJGKKMMJJNLNNNOKOPRUXVMNTVUSRQPLNTSRW[^^_]]`_aaa`bceachbdijgv‹lkigmosqpqppryvruutsmmssmqrotutrpswtuuwvuuteqskpqjrvowJMLLMGDDAD<?EEEC=AACBBCEBBDAAEGCHHHGFJFCGIGGJFILHJJMKMLGKIHLKNQKRQLSMKNNOPPOTOWXX[NSQW\ZSVPNTUTTXZ_bb_da^`b^`eaabgnhbihhmxvlhjmosrpqrrrvtsusssnksqmprotvrqquvuswywutucmtkopjqtowLMLLLGEA@D>>DEFC@CAEDDFCCEGCCIFCHJJIIKFDKJGHJIIKGJJNKNLILHJMKZfJd\KlSHON_nUks[qpbwcRPbvuhucav`Xnqbdvinzf[lt`ljT`wuijgifglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqrqyKNJKJFC?@B?=DEFDCDBEEEFBFFHCDJEEJLMKLMGGMIHIKHKJIKJNLMMLLILML[sbdp^lmUMNfs]geqlntgpi_aYnnbppbkjjgoqtetno\ougpMJryvkb`keemymkvlnpsrprqpqrqrrrtrmmsnnoprutqsstuuutwxvutbmukpplrrqzKLIIGED?BB?=CFGBFCEDEEDCHHGDEKGGLMMKMMGJNHJKJILKJJKMMNNMMJMMM[roonpplkMPQlWNibtrpamov\YlQ\mmZqmkomxxtsip\_rkqjUuyxpc^kfbgqpjioppsspqpqqrrqqrrtlmrmnnorutqtrtuutuuzvutenukpolsrryJKGHEEEBBB=?@FGBGDIEEDBFIHHEGKJGMMNLMNHLMILKHJMIKJJKOPONMKNML\hdu]lqWlNPQmUZk^klvaldtTecNmYl\tpkilxjwuhp]^rkhWbcw|oc`ghadjuyknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtwIMGIDEECAB<BABFDGFLHECCHKHHFJLLFNKLSRLHLLHNJIHNHJJIHNOMNLJNMJZsppoqqmlOQRnYqkgooqqomt^nXat_nopoqronusttj[]tcwxrjnzhaacgbbjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyytukoumtonssvtHKHIBEEEA@>CCBGCHIMIFCFJLIGFJMLFOJKWRKGKJJNIHJLIKJIHJMMMMIKKKSkbZi^_jcrrZ_Yjo_eeUk_c[abQ`lh]j\niid[pfdp]Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunwqrutwrHHFIDEDFA@AEDDGBHJLHFDGKLIEFJOLIOIL[QJFHHKMIHJJKKIHIGKKLKFHKKLLLKIKLNT[\TPTLPONOOVQOOQOOQJINPQdqiTYW[[\UYZ]X]\\cfaafbce__fkmhmtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyxxuvqruovrtsuusHCEGFFAEC?CGCEGCIKLHFDGKLHDGHPKLOKLWLIEEHIJHIKILJHFHGJGHIEFLIIKNLIO\W^O\[`^OXYS\\b^MYZMXaRJYaZS`d\aX[ddVVX\YZX\VY\]b_d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtOBCDLMBCDBDIDGGFKJKHEEJJJGEHHPJMMJMSIHFAGFJIKKILJIFEJGDFGEEJHCJMJKT_Y`X`a[`UXYT^^Z_RY\P^\YN^\^S[^c^Z]`c`Y_b[`^[TXXY^]ccbaceiekrpoppnow††……†‚{€……††…†…uqprrsvyyzyyxxxwryvxrqxvtvaSJJMIECBCFGEGGIJJIIDFKKKFFIJNJNLHLNGHF>GGLIKKJKKIGEIDCCEAFJD@JLJO[cY^^a_RTSW_`\]Y^QY\MV_WKQY[PZ_aa^^ca`bbbcceZQYVU\Y^d`__cebhommllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxXQKGCGEBEGHFGHIFGJGHFHKILDDKKNMLLHJJHJG?GFNJKKMKKKIGGCD@DAHIA?IJHO]aZ[d]_TQSX]\\\_ZKW\LR\YIM^PO\_acdccb\dcbdcfXQUTS[XZa^^^aa_dlkmjjlnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMC@IFCFKIFFGHGGIFFFILJNEDKJLNJLIKJHIGBHHQMKKOMKKIHGED?ECHHAAGFET]Y^X_Y_[]UXXP]]QKJW^X^[]VZ`RQ__bba`bb`cbbddbXOQQR[S[^]]]^__dhgljnnp{{|~{€‚ƒ„………………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKBAGFDGMRHCRKFHHHEFKJMPEGIJKNLLILKIIHDHKQOMMPLMKKHICDAEDHGBAGECWUE\T]SV_XNTUNZ[MJKU`a[_X_^a]OYb]``_bcb]bbW__TPNPQXR]\[\\^`bffelfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDEFGDIRbPDW_IGGHDFMJPPFJIJKNLKKLKJJGEJMQQNNOMNLNHKADACDFDCAEFBMHCLLPOOLFMFGIJHGLLMOPILOPPSPLPTSUZYWYXXdVOSTPPONPUT\YYZ]\`adecgcklpsszy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKM]LGHYMGHJHGNLQQIKKKKNNUNOKKLGGKPSSNPONONOHKE`ED_LDfcEM[I_\smOMVmYLCP`UlWgJ]WU^DLQULMTVQSTXWTXUT\TPfZhhdXSkTWVU[\[``abbb`fhfnlhrz|}~„„„ƒƒƒƒ}|zr{z{‚€ƒ„„……„…ƒƒ~z{LIEFFHEEKOSIKG`THJOJIOMRQKLKLORUROOJLNGHMQ[YOPPNOPOIJPQI|YYrsWPmHqnpaVPqqsPCksmqspSo_[nX]V\XUkhU]VcZ`Y[`VUWjtuu_`w`Xa\\f[_aaaa^`bgmpl`pwtx‚ƒƒ‚}~€vxzlv~tx~€|~€‚„|€ƒz~wwNIEHMMBDLLFJLFRVLKNIKRXWQNNNLQTNOQPKLOGMPS[ZTQROPPPJHZx]TxehYRTQvgtlpbnfjQrOMwmjrpsrqrpop]fzuxqqzq~s}ku}bRg|essoss|}o}yor_``bbZ``gknkblfgmw~€ƒ~{xw€tvzir~nt|~wx{~€ƒx|€u|||ssNKF`]GAEMMHKKHJPNMMJNV^YULQSNXZLSSRNLPIQRTYWWPTPPPQKGfxlcxrmZKLUypumubnvPdeIfvqmwo€jfxxiXsRi{mijzz}lxzogoXvvjuup€`sh|ilx|o^__cbZ]bdgijegbcdllppstsssyqrxblugry{ssuy~suzn|}yxrnNKStNCBEPPHJKJLPOOPMPZ`ZXKTWPa^RVQYSMPISTUXWWPUPONRJKrouuquqdibWnLqp^FhyWvTLhx}x`y{sna^modRgrunmypwlvttqlm\t~zkmy|lum|kpvux^__b^]_edighfe^abiiijknokqnmjpacfdowxompsy~nqpj{ztromLL[VHGEGRPJLMKLQQQQPQW\YUNVYUfXRRY^TMNITTVWYWOSNNNQHRmHiwK`dvvVXlOnl{sajgvUKWkh}lmlx`[pz{^`zscroxqhe|ir{]TKl`vukiu{{m~xk|p]^^b[^bddgeeebZccikkrsrwgmihdg`alagsrkhmmr|kmhk{tmmkmOHJKHIIHRQLNOMLTSSOTRWRVTPWZVVTTTa`QONKTSSQUVNNLMOPJHQNPULKKSTSRTPVUQQNQQXXQNPUTXXX[[URSW[WXWZOSUWWXR]YW]VTOYRWWWXY_[gr^[[Y\]_cZ_ccdfdccbZccfffmnmuffgc`f_]g`dlhfgkhpzhggkujhgilQIKLLMKJSQMQPOLVVTPTUXUYURZ]VUTWUYXPOLMVTQNUSNOMLQPKJQRKQMKKORTRQQSSIHLNOQRQQQTVRXW\WSSQRUUVSZQOSRWUTYVTYUTRUTTTWXW]Z^a]\ZZ\\`c\]bcdgeedaY`acabhhincad^_c]Zd\bma^ffgmsdihkkedcfhPJKLOOLMTPNSQQMXXUTUWWWZVT\`VWVYUXTQPKOWSPNUPNQNKSPMOUTNQNMNQSPTQSTUNKMOQTTRRQVWUYZ[YSURTWWWY[TOTUXUTYUWYURRXVUW[YZ_]UX_]^]\]aa^[bbchfedbX_`b]`hefda^_]]^ZZ_Z_g`^]]bhkagfhfd`bcaPKMLPQLOTOOSQOQ[ZXWXZZXYV]jdVXYZWVTTOKOVTPOTPPPNMQQPRXTRQOMOSUOWRTUUONMQSUUTTRTXVZ]\ZVVQRWXV[[WQTVVUVXTWWTSRXVUZ]Y]_^V^]^`\\``__ZbbdhhedaYb`b^^fdc`b]\\\\YZ[X[a[^]\_b__bddbd__`\PMNNRQMRROSTQPU\ZZW[[\YZ[dqmhd_[YVVXRMMVSMNROQROLPSRUZUTPPLPWVRWSSSXMOPRTXUUUSUYX[^]\[VROUVV[[WQTWUWXVTXZTSQZWV\^Z__`Ua\`a]`b_\`]cacghdf`Yc`a__ee_`c[Z\[\ZZYYW\Y\[`^`[^^a`_b\Y`ZQNONVQPTROUTSPW\\\X^\_W\^jqwy€c\[VVXRNOWSNQQPRTRKQTTYZWUORNSXVTSTRRZOQSSV[VVWTVZX]^\\^VSNTUV\\VRTVVXYSTY\TRR\WZ]^]aa`Wb[cb^ac_\bab_dfidf^[d`a`ace_b_YZ^[\[YXYWWZZZa\][]\\Z]`W[[ZPOOOYPUUSRWRTP[]^][`\`U\]ijr}slg\UYWQOR[SRQTRTUTKQWV[YZSOSRVVUSOVRSZRTUTX\WXXSX\X^]YZ]TUNVWW^[XQTUXYYUWY[TSV]Y]]`]bc^Y`[eb_dd^^cca]efidf]^da`abcd_b^XZ_[\[XXXXW[Z\`][[\[XZ[^V^Y]POORZPZUUVVTTT^^`^^b\aU]^bkytl}lZUZUQQS\TUTUTVYWLRZV][\ROUSXWVSPXRSWSWVU[]X[YUZ^X_^Y\YRWRYXY_ZZSTVZYZVXY\VUZ]\^aa_dd]^]]eabfd^^dc`\gdhedb_da_a`bb_`^WX^Z\\ZYZWV]Z]^ZY[\[WY\]VXW]SOPWYQ]UVYWWUX_`aa`c]`U]^beeuzhXYZTVSV\XWWVVW]XPU\Y^]]TRXRWVTRTXRSVTYXY]^X][U^_X__X]VQYTYZZaY\UVX[ZZXYYZXV]^_^cbaee]b\`fbdfd__dbb[fchecfaf__aaaa`_^VU]Y[\[Y\YY][[[XXY[YZZ]_]TY]UNSZVS\TVWYWV\`abcad__V[`da_zuohY\ZVXUW[ZY\YXY`WPU^[`a\TUXPUVUSVVRSUW[Z\_^Z_\V__Z]^Y^VSYWYZ]bZ^VW[\[\[[Y[YY^_``dbceebdZbfcgfe^ab`c^cciddg_g^bbcaa`^_XTZZZ[[X[XX\[Z[WWYXW\[\`]V]]SPVZVVZUXVXWX]_badada^YYadb`lfh^\][WXXY\\\_[Y[bVTW^]ac\RVXQWVVVVVSVTX\\_``]`]Wa^[^\[^XVXX[[_`\_XY]\]]^\Z\X[_a^`dcdfffbYceehgd^c`_ec]fidei_g^cbcaa`__[XY[YZZXYXW[[Z[WXZTY]\Z`\U^bNRWYVWZY[\YWY^`baeada]^Yacb_a`a_\\]XW[[]]__\Z]cXZX]`cd_RXYPXWXYYWVXV]]^`aa_b^Ya]]^Y]^YXVW[\`_]_YY^]^^a\[ZY\_b_bdcefefbZdfgigc_c^afdZiibfice^bbca``_]]ZW[YYXXZXWZ[ZYWXVU[]]]``bbxLWW\YW]\\]ZW\]_`bdbba]`Xbcb`cab^\\\XW[]_]`_][`d\\XZcec`R\YOXWY[ZYXZY`]`bb`ac_\b]_][^^ZYUX]]_`__[Z^^`bc\\W[]`bacedgeefd\efhifcbb\cg`\iibhife`baca_`_]][Y\YXWXYXW\[ZWWXPXZ]acffrkJYW]ZZ_]\^\Y][^_acbaa]b[bdb`ccb]\[ZWXiq`\`_]\ac_^YYcedaS_ZQYW\]\[Z[[c`cbc`bda`c^`\]^_ZXV[_^]aa_][`abeb_]S\_`cddfdgfefe^efhhgdd`[fg^ahhchhfc`b`cb___]]\Z[YXXXVZV\ZZVVUMXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡…ƒƒƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vvvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{{{{{{{{{{{|{{{{zzzzz{{|||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vvuvvvvuvvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{{{|||{{{|||{{{{{zzzzz{{||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||vˆ‹‹‹‹‹‹}}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰‰‰‹‰‰‰‰‰†³ÖÒÒÒÒÖº}~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}vŒƒ~~†“y1333332j‚€€€{­éääääèʉŒŒŒŒŒŒŒŒŒŒŒˆ¿éååååéÇ}~}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}vxxxxxwxwwwwwwwxyyyyyywopppppprrrrrrrwzyyzzz~ƒƒƒƒƒ„||||||}}}}}}}}||||||{„„„„„…‚|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚‚‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vvvuuuyvvvz{x{xwvx{xyzz~|yyxxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{{{{{zzzz{{{{{{zzzzzzz{||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwwy||}zy|{xwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwwwy}~}y{zxxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z|ywww|z||z|yxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚ƒ‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzzz~{}}z|xxxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyy|zz{yyxxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxxyyyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{{||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}|||||||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}|}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrstuttssrrsrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqstsssrqqpponnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqqrssssqpqpoonnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrqrrssrrqppoopoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpppqrrqqqpopooppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqpqqqqqqpooppppppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqqqqqpppppppppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsqu‹‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqqqpqqqqpqpqpqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrqqqqqrqqqrrqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrssrrrrrstrrsrsssssssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz|~~|vvwwvuxzxxxxwwwvx|yy|zyy|{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~|{{z{|{}|{{{{{{{yxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}||{~|}~~~~~~}||}€ƒ€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€~€€€€€€~~~~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~~~€€€„ƒ~~~~}~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~~~~€~~Œ~…~~~~€€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹Š‹‹Š‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚ƒ‚€€—‚”Œ~€€€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒŽ‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒ„‚„„‚‚†ž†—”€‚‚‚‚ƒ‚ƒƒ‚ƒƒƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒƒƒ€ƒ‚Š¡ˆ™š‡‡††††‡ˆ‡‡††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠˆ‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„ƒƒ‚ƒ…„ƒ‹£Ššœ‰††‡‡‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ‘’‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„„ƒƒ‚€£‰—œˆ„„ƒƒ„……‚„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘’’ŽŽ‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€‚ƒ‚‚‚‚£–™„‚ƒ€~€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„„„„…„…†’“‘ŽŽŽŽ‰ˆ‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~€‚‚€„Ž„€€…Ÿ¦©¨—‚‚ƒ†ƒ€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“’Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚‚ƒ„‚‚„„‚ƒŠ—‰„ƒ„˜­§«¬ Ž‚„„€‚ƒ‚‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘ŽŒ‡…ƒƒƒ‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒ€ƒ‚…†„„ƒƒƒ‚„Ž™……‰¥¡™¥£›ž‰‚”•„ƒ‚„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”“’’ŒŒŠ…„„ƒƒ‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~Œƒ~}|}™“„ˆŸ”Ÿœ”•’žŽ‚ƒ‚‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†””’”’Œˆ„„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~–—‰€}}}~|‚—“¡Œ“’˜š”™¡¡›‡‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“’Š‡ƒƒƒ„‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€€–Ÿ‹~€}‡‹„†•¨¥Ÿ’‘•‰• ™„‚‚ƒƒƒƒ‚ƒƒ„‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†ƒ…ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„’ Š€Œ…}†ˆ€†‰œ¡¢ƒ~~‚–‘‚ƒƒƒ„ƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„……………„…†…††…………………………††…†††…†††‡†…………ƒ„„„‡“““’’ŒŠˆ…………‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…ƒŠ‚„Š…ƒ‚ƒˆ†€€€‚Ž†ƒƒ„„„„„„„„„„„„………„…„†……†…†††…†……‡……†…††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„„„‚‚ˆ€€†‚€€€€€€€€ƒ…„…†††…………††‡††…†……†‡‡‡ˆ‡‡‡†††‡‡‡†††††††…„ƒ„………„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘”“‘‘‹ˆˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒ„„„ƒ€€€……€€€€€€€€€€……†‡ˆˆ‡‡‡‡ˆ‡ˆ‡ˆˆˆ††‡ˆˆ‰‰‰ˆ‡†‡‡‡‰ˆ†‡†‡‡††…„ƒ„…†…………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†…†„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡†…ƒƒ…„„ƒƒ€€Œˆ€‚‚€€~{z€†ˆˆŠŠ‰‰ˆˆ‰‰‰‰Š‹Šˆˆˆ‰‰‹‹ŠŠˆˆ‡ˆˆˆ‡‡ˆˆ‡ˆ†‡†„ƒƒ…‡‡‡†……„„ƒ……„……†„„„………†…†…ƒ‰”“ŽŠ†…†…ƒ‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡†„„…„ƒƒ‚€€€„„‚‚‚‚‚‚‚€~}}}}~|{|ƒ‡‰‹‹ŠŠŠˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰‡†††‡…†ˆˆ‰ˆ‡†‡„ƒ‚„ˆˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚‚ƒ‚„ƒ„„Ž“’‹ˆ…„†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„……‚€ƒ„‚ƒ‚‚‚ƒ~}~~~~~~~}~}}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡‡‰†ˆ†ˆ‡†‰‰ƒƒ„ƒ…„„……†ˆ‡†…ƒ‚‚ƒ…‡†‡††„‚‚ƒ„‚ƒƒ„‚ƒƒ„ƒƒ‘’ŽŽ‹‡„††ƒ‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…‡ˆ‹Š†„†„‚††‚‚„„ƒƒƒƒ‚‚}|}€~~~~}|}}|y|ƒ†‡‡„ƒƒƒ„………ƒƒ…„„„„„„…„‚‚ƒ‚„„‚ƒƒ…†…„‚‚‚ƒƒ…ƒ„„…„„†ƒ„„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰†„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€‚ƒƒƒƒƒ‚‚}}€€}~~}|}}{zz~„„„‚€‚‚~‚ƒ€‚‚‚‚ƒ„€€€ƒ‚€€€€€‚‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†‹“‘‹ˆ……ƒ‚„‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€€ƒ‚~~~~}€‚ƒƒ‚ƒ‚ƒ‚}}~€€€~}}}}~}|zzz€‚‚~€~}€€€€€€~}}€~€€€€€€€€‚€€‚‚€‚„ƒ†’ŽŠ‡‡†ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒƒƒ„…€€|}}~}}~€€}~}~ƒƒ‚‚‚}}~€€€~}}}|{{{zzyz€€€~~~}~~€~€€€~~~~}|~€~~€€€~€€~€~€…’’Ž‹‹‡‰…„„‚‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~~}~€€~€„ƒ‚€~}~~€€€~}}}}{{|zzyyy{€€~~~~€€~€€‚€|~~~~}|€~€~~€€~€~~~~~~}||}…“’ŽŒ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒƒ‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚‚‚€ƒƒƒ€€}}}~~~~}}}}}|||{zyyyy}€€€€€€‚‚€~€~~~~~€€€€~€€~~€}~~}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…ƒƒƒƒ…„„„„„ƒƒƒ„‚‚‚‚‚~~}}}~~€}}}}}}}}}{zzyyyy€‚‚‚„ƒ‚ƒ€ƒ‚ƒƒ‚€€€ƒ„‚€€€€€€‚‚€€€€€€~~||Š“Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…ƒ„…„…†††††…†…ƒƒƒ‚‚€}}}}}}~~}}}}}}}}}|{yyyyx|‚ƒ„…‚„ƒ‚‚ƒ…†‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚ƒ„ƒ‚ƒ‚‚‚‚€€€~Ž“Œ‡ˆ†ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€€~}}}~~~€ƒ„‡ˆ„†††…††‡‡†‡‡ˆ‡‡‡†}€‚~}}}}}}}}}}}}||~~~|{yxwxyy€ƒƒƒŒ„ƒ„„„——ƒƒ„}~‚‚‚‚ƒ†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ…„„…ƒ‚ƒƒ‚ƒƒ‚‚‚‚ƒƒ‚‚’‹ˆ‰‡‰‡††„†…„„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€~}~~€‚………‡†‡‡†‡‡ˆ††‡‡‡†‡…~}}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yxy|~‰–„ƒƒ„„”“€~~…‹€€€„†‰…„‚‚……‹ƒ‚……††„ƒ……ƒ…„ƒƒ„ƒ…„„ˆ’ŽŒ‰ˆˆ‰‡‡‡…†…„…„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„ƒ…„~}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|xyz{|€‚ƒƒ‚€~|~~{ˆ‘||Ž–}‚†Š…ƒƒ„ƒƒ‰~ƒ„……ƒ…†…„……ƒ„……†„„Ž‘ŒŠŠŒ‰ˆ‰‡………ƒƒƒ‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚€‚€~}}||}}|||}||}|}}}|||{‹‘—Œz{|zzz{|yy}}~€€|{{~~}‚•‘„ˆ~|~‚„||‚„‚€‡ƒ}‚‚‚€ƒƒ„„„„„‚„ƒ„…„’’Ž‹ŒŒŽŠ‰‰………ƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚ƒ…ƒƒ…………ƒƒƒ„‚‚ƒ‚ƒ‚‚€€~~}~}||||||||||||||}|||~~Š‚{z{zxz{{|}{~}~}}}}||}†~}‚~~~€‚||‚€‚€~|{Š‚}€~€€€‚‚€€€‹”Œ‹ŽŽˆ‡‡……„„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ…„†‡„„€†”ˆ€‚€~~~€|||||||||||||}|||||||y{{{xxy{zz|‚€~|~~}€‚‚€€€‚‘€€~€~~~€}}}{}}}|}||}€€€~€~~‚”‘ŒŒŽŽŠ…†‡…„„…ƒƒƒ‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚„†‡††~ˆ•Š~€€~€~~~|{{|||||||||~}|{}|||{|||zzy{|z}…ƒ‚~~€~…‚~€~~€…†‚€~~ƒ†~|~€€€~}}}}~{|}€}~€Œ‘ŒŽ‡„††…„„„ƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}€‚ƒ††……~€€€~~}€€€}}||}~}||}}}}}|~|}|{}||z{z|}}†„‚€€}~}~~‹„†~}||~‚}}}}€|{}|~„ƒ€~~~~}}}~€~~~„’ŒŒ‹Š†„†„„ƒƒƒƒ‚ƒ‚ƒ‚ƒ‚€€}|||}~{{}w~vx~}|}|}~~‚ƒ€z}}|~€~€~~€€€€~~~~~~}~~}|~}~}}|{|||z{z}€€ƒƒ‚~|}|}||ƒ~Œ~|{{}~}~~}{{{}|z{{{€†…‚„ƒ‚€~‚‚‚‚‚€ŠŒŒ‹Œ‹ˆ„„„ƒƒƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€~€€}€~~~~|‚~~}}}{{}}|z||~€‚€€€||}|||||}|~{~{{{|||}|{{{{||zz}z~‚~ƒ„‚‚…†……††‡…„‘ŽŒ‹Š‹‡‡…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~€€€‚€~~€€~}ƒ||}}|}}}}{|~~~~~~~|||||}|~~{|{||||}|}|~|}|{{{|y{|{{}z}~€€ƒ‡‰‰‰Š‰Š‰…ˆ‘‹ˆ‰‡……ƒ‚‚ƒ„„ƒ‚‚‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€€~~~}€€€€ƒ‚€€€€€€€€~|z|}}~}}~~Œ†}}~{{ƒ‚}}}}}|}}}|}~|}|}|}}~|~}}}}|{{z|{||{z{{zzz{~~‚…ˆ‡ˆŠ‹‹‹‰‘Ž‰ˆ†…„‚‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„ƒ€€€€‚~}~€~{~’Œ|}Š€Œ~~}}}~}}~}|||}}|}|}}}~}}~~|{{{||}|{z{|yzyxy{~„ƒ„‡‰Šˆ‰Ž‹ˆˆ…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{|||~~}}‚€€€‚…ƒ„‚‚‚‚€€ƒ‚€}~€~|‰‚~ƒ„„ƒ~}|‡}}~}||~|}}|}}~~}~}}}{|}~||{|}zzyyyy{{~~€ƒ‡„ˆŽŠŠ†…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{}}}}}zx‚€‚‚€€€€€‚‚‚‚†…„‚ƒ€‚„~€}~~}~€€}~„€~~}~}}Š…}~}~~€}}||~~~}€}~}|}||{|}{{{zzz{{|}~}€ƒ€‰Š‹‡………„ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv}€ƒ‚‚‚‚‚ƒƒƒ‚…†„ƒ€€€€ƒ€„~~€~~€~}~~€€~€€}€~€~|}}|~~~~€}‚€|}€€}{}}}||{||{{{|{|||}|ŠŠˆˆ…………„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€‚€€€€ƒ~~€}€}}~~€€‚€€€€}€€€€€~|}}}}~~}‚}€~‚€}~€|~~}}}{|~|}|||z|{|}‰††……‡………„‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz~}yxtt€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚€~~~€}~€}}}~€€‚€€€‚~~€€€€€~}}}~|~~}}„€~}}}~}~~}~|{|z|{z€‡‚„„…„„ƒ…ƒ‚‚‚€€‚‚ƒ‚‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xyuu}‚ƒ‚ƒƒƒƒ………ƒƒƒ„„ƒƒ„‚€€€~}}~~~~€}}|}}~€€€€‚€€€‚€€~€~€€€~~~~~~~~……€€ƒ~€~€~}{z{z|{z‚„ƒ‚‚‚ƒ‚„‚€€‚€€‚‚ƒ‚ƒ„ƒ„‚„‚‚‚‚~€~}~~~~}~}}z{|…„{{syz|pwuvwyutz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€€}}}~}~~}~|}}~€€€€€ƒ‚€~€€€€€€€€‚‚‚€ƒ€ƒ‚€€|{{z|{|‚€‚€‚‚€~‚‚ƒƒƒ‚„‚„‚‚€~€€}~~}}}~}}{{z€x|vyy{qtxwvxury……‚„„‚„……†„„‚„ƒƒ€€~€€|}}~€}~~}|~~~~€€ƒƒƒ€€‚€€€€€€€€€‚ƒ€„}ƒ„€€‚}z{{|||~€|}}€€~}}€~‚‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxyzruyyvwwsu†…ƒ……‚„„…„„„‚ƒ‚ƒ€~€~€}}}~~€~~}|€|~€~€‚ƒ€€ƒ„‚€€‚€€€‚ƒ‚€ƒ€~‚‚„€€‚‚‚„‚~{{||||}}~}z~}}x~|||~~~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„‚„„…ƒƒƒ‚ƒƒ€}~}}}€~~~}}€€~~|~~~‚‚ƒ‡…~~€€€€€€‚‚€€~€‚~‚ƒƒ‚ƒƒ…‚}}}|{||yz{z~y{yx~{{{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst†„„†ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€}€€~€}~}~€€€|~€€~}~~€}€€ƒƒƒ~}~~~€€€€‚€~~€‚‚€ƒ‚„„†„€~}||||{yvyyzyvyv~|{{{~|{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…„ƒƒƒƒƒ‚‚ƒ‚ƒ‚~~€}}}}€€€|€€€€|€}~~€}~~‚‚~~}~~~~€}€€€~~~~~€‚‚ƒ‚ƒ„‡„€€~|}||{|uxyxxxyw{|{{{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvpxyrx…………ƒ„„ƒ‚„‚‚€‚€~~~~€~}~|~€€€€€{€~€€€}€~~~}}}~€‚~~~~}}~~~|€~~~‚~~€€ƒƒƒƒ†„€~|}||{}xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}|{|z{}zzx{|zz{xtxuqrtpxxry„………ƒ„ƒ‚ƒƒ‚‚‚€€€€}~~€}|~}€€€|€€~€~~~}}|€€€€€~~~~}|~~|}€~}~€‚~€€~‚„‚‚ƒ……‚‚~}|{{||yw|ywxwwx{{{{|…Š}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzz{zxswuqqroxwq{…†„…ƒ…‚ƒƒ‚€€€€~~€}|~}€€‚€€}~€~€€}~|}€€€€~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{||{zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚‚€€}}~€‚‚}~~~€€‚€€~|~|€€€€€~}~~€€‚€€€€€€€„‚‚€~|}~~z}…~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚€€€€€€~}€€‚‚‚€~€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€‚€€~}~{“z|}|{}y{zzxyxy{||}|||||||}}}||}|~}~~~}|z||{|}{yzzzyysuuooqpwst}…†ƒƒ‚ƒ‚€€‚ƒ‚€‚‚€€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€€‚‚€€€}~|†‰||~{{~yz{z{Ž~wwy{|{}||||{}|}}}}|}|~~~~|z|}{|}{yz{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€€‚‚€€€€€€}~€}€ƒ‚{~~{|}{z|||‡yxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ‚„„€~‚€€€€‚~€€‚€€€€€€€€€~}€€€€€€€€€€€€€€€€€€~}~}~~{}|}{||xxuxxy{||}|||||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒƒƒƒ‚‚ƒ‚„ƒƒ„ƒ‚ƒ€€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€€‚€€€€€€€€€€€€€€€€€€€€€€€‚ƒ‚‚€‚‚€€€‡~~|z}|{}xwvyyz|}||}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚ƒ„„€ƒ†ƒ„ƒ‚„€„ƒ‚‚€€‚‚„‚‚„‚€€ƒ‚€€€€ƒ~€ƒ‚~‚€€€~€€€€€€‚‚€‚ƒ‚‚ƒƒƒ‚€€€„}}}|}z}zyvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysruowqwysw{…‚‚ƒ‚ƒ„‚ƒ„ƒ€€‚ƒ†ƒƒƒ‚‚„„ƒ‚€€‚„‚‚‚~€€‚‚ƒ€€€€‚„€~ƒ€ƒ‚€~€‚ƒ‚€ƒ‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ€‚€}€|z|{{w|yyy{z}~}||||}~~€€€€„„€}€~{{{z{ztpxrytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚‚…†„‚ƒƒƒ„‚„ƒƒ€ƒ‚‚‚‚‚€‚€€€‚‚‚‚‚€ƒ‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚‚„ƒƒ„‚„‚ƒ‚‚‚‚ƒƒ„ƒ„„„„„…ƒ„‚ƒ‚‚ƒ€€~||€||x|yzyz|}|{||}}}||€€€€€‚~€€€€{{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚ƒ†……ƒƒ‚ƒ„„…‚‚‚ƒƒ‚‚‚€€~€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€ƒ€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒƒƒƒ„€‚„ƒ„ƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{~~}y|zzz}||}z||}}|z{~~~€€€€€€€€€}}|}}|vrvxxvtvu}‡‡ƒ‚„…ƒƒ„…„€‚……„„ƒ‚ƒ„„€„…ƒ‚‚‚ƒƒƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚‚‚ƒ„‚‚€€‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚~ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz{}€}||z|~}|}}~~€€€€~~€€€€~|}}~~}|{xvvw„‡ƒ‚ƒ…ƒƒ„†„‚…†…„„ƒƒ„„„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„ƒ‚‚ƒƒ‚ƒƒ‚‚„„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒƒ„„„„„…„ƒƒ„…„…„ƒ‚€}‚€}||{||€}}~€~~}~|||}}~~~€}}~€~~}}}~}}~~€|}€‚‚ƒƒ†ƒ„ƒ†„‚ˆ‡…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒƒ‚‚„ƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ€ƒ„„…ƒ‚‚ƒƒ‚„ƒƒƒ„ƒƒ„„…„„„…………„ƒƒƒ}„€}}||||~~~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒ„…ƒ„ƒ…~‚Š‹…„„ƒ‚ƒ…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ…ƒƒ„…„……‡‡†‡…„„…„ƒ~~|~~}€~||~|z|}}}}}~~~€‚}}|€€~~~~~€‚€……„ƒ„„‚„ƒ†€‚……Š‰„„„„„…‚‡††„„„„…„„„„ƒ„ƒ‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ„€}uyƒ~„„‚ƒƒ‚ƒ„ƒƒ„…ƒ„…†„…†}„y|~ƒ{…ƒ„ƒ€}}~~~ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚‚ƒƒ‚‚†„„„…„ƒ„…ƒ„…„Šˆ………ƒ……„†††ƒ„…………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†spurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚……‚hzrss|€rƒƒƒ}}~~}~‚ƒ‚|}€}}||||}|||~}~€}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ…ƒ†ˆ††…ƒ†††‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vyy†s„ƒpvxqvtturstvi€nrotvnulwm{sn€‡ym}rsvsvmnwlpylu}}~€}€}€€}}||}}|}~}€€€~|~€‚€€€€€€€‚ƒ‚‚„…ˆ††€‚…ƒƒ„‡†ƒ………†‡‡„ƒ†‡ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpu‚rƒ~ozyymonzoomw}x†pqzprtfu~n{ysoy€}}€{}|€~€€~~€€€~~~€~}€}€€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„†……††ˆ„„†‡ˆˆ†‡„††‹Š…„†‡‡…ƒ………„‚…………†……†…†quprsoszy~ƒtˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„rjoyxpkyszozwvvp€~~~z~}|}~}€ƒƒ€‚ƒ„‚€€}~~~€~~‚€€„‡†ƒƒ†„„„†‡†…………‡†ˆ……†…‡‡…†„††‰ˆ…„‰‹ˆ†„†………ƒ……„†††††…ƒx‹yrˆz{pp……x…xyks~y{krƒ‡ƒz|m{zyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozls|nw‚€~~}}z}{|}}~}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡……………‡‡ˆ†„†…‡††…„……„……†‰Š‡…„†…††…††„†††††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„…†…†„†„ƒ„„†„ƒƒƒ„„…„…„…„†ƒ†‡…†„„†‡†„„…†„…}w…ƒ„„‚}~{|{~{||}~}|~}€€}€~~~€~~~~}}}~|{|~||‰†…„†††…††…………††‡ˆ†„†…††……ƒ„…†…„††††…„†„…††††„‡†‡‡†…‡ˆˆˆˆ†„‡…††ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…ƒ‚……†……ƒ…„„„…„……„……ƒ††††…„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ‚}€{{|~{||}~||~}€}€~~€}}|€}~~~~~||}~{|||{{~ˆ‡„„ˆ†††‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡…††……†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ……ˆ…†‡†‡†‡†‡…‡‡†‡……†‡…‡††‚ƒ…††„„ƒ„„ƒ„†„……………ƒ††…†……††…„„……ƒ„‡…ƒ‚‚…ƒ„~€€|{}~{|{~~}||~}~~}~}}~~|}||~~|}€|||}|||~z{{|~ˆ‡‚…ˆ‡‡†‡††„„††‡†ˆ†„…„‡†„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…‡‡…‡†‡†‡…ˆˆ‡‡…††‡…††„„„…†……„„„ƒ„…„†††…†„†…††……††…„ƒ„„ƒƒ‡ƒ„‚„„ƒ€€€{{~}|||~}|||}}|}|~}|}}||||}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††ƒ…†…†††…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡…‡††‡‡‡…‡†ˆˆ‡‡…‡‡‡…†‡„‚„ƒ„†…‡…„„„„„…††††……‡……‡…†…‡…„ƒ„ƒƒ„‡ƒ€‚ƒƒ‚‚‚€{}~}{||~}|}}|~{||{||}}{{{}|{~|{|}}|}}}|zz{{||ˆ‡‚††††‡††…ƒ…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡ˆˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡†ˆ‡††‡‡…‡†ˆˆ‡†…‡†ˆ††‡ƒƒ„„ƒ††‡……„„„…†††††…†‡††ˆ††„†…ƒƒƒƒ‚ƒ†ƒ~‚‚ƒ€ƒ‚|~~||}}|}}|}{{{z{|||{{{~{{}{z{~||||}~}{z|z||‰‡ƒ†…†…††…„„……………„ƒ…†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…ˆŠ‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡‡ˆˆ‡…†‡†‡……‡ƒ„†…„††‡†…„ƒ……†††††…††‡†‡‡…ƒ†…ƒƒ‚€ƒ…‚ƒ~ƒ~~}||}}{}}|~zyzy{|}{{{{~||||z{}||||~}|{{{{|{‰‡„†„†„††…„…†…„„ƒ„‚€ƒ…ƒ‚z„Œ{€„…‡†††…„‡ˆ‡†‡……‡Š‡ƒ‡…††ˆ†…‡„†‡ˆ††ˆ‡‡‡†‡ˆ†„†††‡……‡ƒ„…„†††‡…„„ƒ……††‡††…†††…††„ƒ„…‚‚€ƒƒƒ‚}€~ƒ~€||}}~}{~}|}yyzy{}}zz{{}|}||z{}||}|~~€|{{|~}|ˆ‡…†…‡„†„……………ƒƒƒ€‚…‚€}|{„…††„…„ƒ‡‡†††…„†‰†‚†„†††……‡…‡ˆ‰†…ˆ‡‰‡†‡‡…„†……‡…„‡ƒ„…„ˆ††‡……„‚……†…††‡„††††…†ƒƒƒ…€€€€ƒƒ€|€~~‚€}€||}~}~{~}||yzzyz}}yzz{|{|{{z{}}|}|~~|{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€€ƒ~~~€yz}€ƒƒ…‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ†…ˆ‡‰‡†…†…ƒ†„…‡ƒ„†„„…„‡†…†…†„‚……†††††„…††……†‚‚ƒ„~€€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|z{{{|}}}|€~}||}~|{‡……††††„…„…ƒ…‚€€€€~‚‚}}{‚ƒƒ…†…„ƒƒ†ƒƒ„‚€…‡…‚ƒƒ„„„††‡ˆ‡……ˆ†‰‡…„„„‚…ƒ„†‚ƒ…„„†„‡†………†ƒ„…„…†…†„ƒ„……ƒ……€ƒƒ~€€ƒ|€}}‚}€~~~~~}}{|{zyzzyzz|yzz{{{|z{{{{}~}}€}}||}€}|†ƒ†††††ƒ„ƒ†‚…€€€~€‚|~~€€‚‚‚„…ƒ‚‚„€ƒ‚€„……‚€‚ƒƒ„……‡†…„†‡…‡…†‚ƒ‚‚ƒ‚‚…ƒ…„…†„††‡††…‚„„ƒ„†……ƒ„ƒƒ„ƒ…„€‚‚}~~~„~{||€}€}~ƒ}~~}}~{~{{zy{zyzz{yzzz{{|z{|{{~~}|}||}€~€†„……„‡„ƒƒ‚†‚ƒ€€~~€}‚|}~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡†…„ƒƒƒƒ„†…„ƒ‚ƒ‚„ƒƒ€€~}}~~|~ƒ~|~||€~‚~‚|~}}|||{{zzzzy{zzzyyzz{|y{}{|~€}~}}}€€€†„„…„…‚„‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„…ƒ‚ƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚€…ƒ~€~|}~}|~ƒ}{~|}€ƒ}}€~}|||}{{zzzyy{yzzyzz{{{z{}||‚€~€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌËËËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFK=8765999<>9?<D:;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937677=;>:=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<:<<98:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA><A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÔÔÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÔÔÔÔÔÔÓÒÓÓÓÔÔÔÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9>CE?<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÑÓÓÓÓÓÓÓÓÓÓÓÓÓÎÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø×××××ÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕØØ××××Ø××××××ÖÓÒÒÓÓÔÔÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILO@99:4;A<7=9AC>@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌ̈́mpppppppppppj§ãÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¸ºÑÓÓÓÓÓÓÓÓÓÔÔÔÕÇ·¹¹¸¸¸¸¸¸¸¸¸·½ÓÒÒÓÓÒÒÒÒÒÒÓÓÓÛâáââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVN<::77>C>8>:??A=>@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÎN&+++++++++++"ŠôëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§£££££££££££¢§ÏÓÒÒÒÒÒÒÒÒÒÒÒÔ½ £££££££££££¡«ÒÒÒÓÒÒÒÒÒÒÒÒÒÐßëëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;?C>6:7>?;=B?9<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÍÎR+11111111111'óééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤£¨ÏÓÒÒÒÒÒÒÒÒÒÒÒÕ¾¢¥¥¤¤¤¤¤¤¤¤¤£­ÒÒÒÒÒÒÒÒÒÒÒÓÒÐßëêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;?@@8:;8<;<<?:;;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÏ\9===========5“ðççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©©¬ÏÓÒÒÒÒÒÒÒÓÓÓÓÕÀ¦¨¨©©©©©©©©©¨°ÒÒÒÒÒÒÒÒÒÒÒÓÓÑßêééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB>;=:9;:==;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÅÂÃÃÃÃÃÃÃÃÃÃÃÂÉÐÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÎÎÎÎÎÏÎÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÒÔÕÕÕÕÕÕÕÕÔÓÓÓÔÓÒÒÒÒÒÒÒÒÒÒÒÒÒÓÔÕÖÖÖÖÖÖÖÖÖÖÖÖØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<8@B<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÏÐÐÏÏÏÏÏÏÏÐÔÐÐÎÌÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÎÓÔÐÏÏÓÓÏÏÏÓÒÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖ×××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?79:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÎЦ’ÅÒС–ËÓǒ«ÑÎÎÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<>B>BC@=:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÎÒª¬”Ψ «ŸÏ™¬š²ÒÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?>;7:>9?D?A98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÐɗ™…¦¤Ÿ–¡´•†œÎÏÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<=:6?B@B:647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÏѤ°½šŠ §™´¿É—™ÆÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8FA?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÏÏÐÕ¹™¥žŒ ÄҒ™ ÎÐÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<>=964:99::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÏÏÐњ½›Åɔ٭£¿žÕÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:<?>=<9@<<::9?@>=<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÐÐÕ§¤¢Æ“–£»Íˆ•žÈÒÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CFCAB8;?<=;<<8558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÐÒÀ¢Í²›®³¥ÐÛ£™µÕÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF@HIGE@<<>><=><756:969;::;8@?:<<9<>=;;:?9?:;9=>=><;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦ÓÔ¤ »¬Ÿš¡œœ‘§˜ž»ÕÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;557<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡ÈƦ½•“˜¡©Ÿ¢ž¨¢©ÐÓÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKLA>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ Ôʎ“—ª³¥Ôš’Ž¾ÖÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<=?GFGKH=657:979:;:<=9>99:8;=>>A>=9<<:=>>:=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÔ¯°³ÑÖÀ½ÖÔÓ¹ÈÕÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?AELLA>775;8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÔÖÖÖÒÒÔÕÓÓÓÖÔÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEK>>786967899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9699:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EILAALD??;9889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEHIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDJ;AA;<886486987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGJB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<BA<;876797799=?A?<:9@?<>B?:8776=??@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE>;HF89757875898;>>=;89A>=@?A>7596;>AB??@@AB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCEEC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELCA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<<DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGHNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAC?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€iixsg~‰‰xp‚†{w}~…Š½ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€‚wt|„‚}sp€Šx‚yƒÈÞÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsoupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿¼½¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»º¹¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjcmgb\XQPQKTJB:IQ?A7<94:565455688686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸········¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µ¶¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸¸·¸¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶·····¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨¨¨¨§¨©©©§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸········¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥£¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§§¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©ª««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤££¢¢¢¢¡ ŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž£¤¡žžŸ  žœžœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=7789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥¤£¢¡¡¡¢£¥§¦¦§¬¬§¦ œ›¡¡ž›ššœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¥¦¦§§¦Ÿ›š›¢ ™––•š›š——˜™šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜—™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥¢¢¥¦¦¥¦§¦¦ ›™›¡ —““’—šœš———˜›š™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB@DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥¦§¦¦¢œž¡Ÿ—‘‘”—š˜–—–˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;<;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¥¦¥¥¦§¦¤¥¦¦¥¥£  ¡¡Ÿ™’–š™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šžŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡ ¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢¢¢£¤¤¥¦¥¤££¡¡¡žœš•“”˜›š›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œ ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸŸŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::88:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸ   ¡¢£££££¤¢¡ ž›™™˜™™™™™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢ ›ž ¡£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œž››œŸžœœœœŸ   ¡¡¡  ¡  ¡¢¡¡¡¡Ÿžœ›ššš›œš™š›™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥¤¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¡¢¢¡   ¡¡ ŸŸžœš™š›››œ›š›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›šœšš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>98;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤¤¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ žžŸ     Ÿ ¡  Ÿž›š™šš›š›››Ÿžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›ššš›™˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9<<>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœ›œžžŸž›šš›œœ››œœžžœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:=>:?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››š›œššš›œœ›š™œœœžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™˜˜ššš™™™™š›œœœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›š™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š››››œ›˜˜˜™™˜˜™™˜›œœžžžžžžžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ›››››››™˜˜˜˜˜˜˜™™œœœžžžžžŸŸžžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ››››››š˜˜˜˜™™˜š›œœžžž  Ÿžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_^]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜™——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜˜˜——˜™››œœœžžžžœ››œœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±³­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=:F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œšœ›œ›˜™š˜˜™ššš–‹“–™˜•˜˜–›œ—•’‘’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨©¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‹‘‹ŒŽŽ‹……‡‹ŒŒ‡ˆ‹Ž‹‡Œ…†‹†ŠŠ‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VQQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹‹†Š‹‹‰†„†‚€‚‰‘ƒ€ƒŒ†‹‰…€‡}€’†„„†ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹‹‰‰…‚}s}ˆ€~œ„……‰‹Šz}}†ŽŠ†”’‹—”—’˜¡–ž—•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¥›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ‚†‹†ˆ…„ˆˆ‰„‚z||}~’ˆx…‹Šƒ„…ŠŒ‘™””” ššŸ¢­±­©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPEMISWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~‰‹‡Œ‹Š‡’Š‡†‘“‘‘„‡}}ƒˆŒŽ‹Ž‰‰Ž””˜•œšž¨®²¯¯µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWLO_^\NUUbQDTM;?9<895775795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš˜ “—š ™›¢¡•› ¤£š“ˆˆ‹‰‘‘Ž‘Ž‹˜šŒ”š—œ› ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUKTOOJCPK_bXZQ\T`MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ª©¨§¡¥¨¨«ª©¯¡›Ÿ¡££ šŸ œ”˜”˜  ¡¤ž›š¥§¤©«¯¬¥£¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdWOXKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®¯ªª«¤¡¢¤©§¦©¨£¢œ››¤ ¥¨£ ˜˜Ÿ¡¢©§ ¢¢®¬«ª§­¯¨¥¤©©©©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_UZNRNPORd\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢šœ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨§¥§©§©¨£§¦™œ¤¦¢¡¡¡¡ œ˜™Ÿ ¡¤¤¢žž– ›š¢¢ ¡Ÿ¡¢¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]\PUOWO^ddlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§¬©¤Ÿ¢ ¢¦¡¦®¦¦ŸŸŸŸŸ™šœœ¡ ¡¤Ÿ¡›šœ ž¡Ÿžž £™–›˜¤¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvxb_\UYQUW[c^s_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?C?:8:>?C@DA:;>=@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯««¬¨¨«°©¨ª¨¡Ÿ §©­°²¯¬£¢¦¡©¥ž¤£¢¦ ¥¤¢¥£ž žŸ¥¢¢žŸ¢˜•ž›ŸŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸ ¡¦¢›—’šš •|wo}yf[Z`_Z\V\hdncnjib^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¢ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£Ÿ¢ª©§®·¶´´¶³¯¬«®«¶°©²±­®§¦ž¢££›œ—¢¨¥¡Ÿž£›¡š–¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¡™˜¥ ¤§ª©¨ª­¬¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvyjb[_^\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>AE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢œŸª²¸¼¼½»º¿´¯±³µ´··¯µ´µ²°¨¤¢Ÿ —•š—¤ª¦¦¡¤£¤«¦¥™¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨¨«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥¡¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxxxc[RYT__amhukqhiiaYSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶´º±ª®´±°±´µµ¼¼¾¼¼¾Æº¸·º½´¯µ±±º¸·²³²ª¦¦Ÿ˜¤¤§¨¤®¤««µµ¯³ §ª¬§ª©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš’–””˜“š˜Š‹‡€€|‚xa^YTai`fsositdidb[LK>:8898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÃÆÂù½¿ÀÀ½¿Ä½¼º½¾´§ª˜±À½¸µ¹À³¯¯ªª¨­§§¤¯§ª´¼±´µ¨¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`a^^kcbnwuvnl[bQV\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAA;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–••‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±°§¼¼¾ÅÄÆÉÇÅÆ»ÄÀÅÆÀ¹¯½¼À¾¾³«ªŒ³»¾´µ·Âº­¯°µª«¦ª£­¤§±¶«µ²­³­¨®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|ƒjfhakmfnuqruqg^_\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÅ¿ÃÂÆÅÀ±“¾º¿Ã¶¶º©´³´©«³»»±Ÿ›±¯¬¤¬®´§ª©¨ª­¬©¦¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|tklndomiqxnyiia\gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿¼»¾Ä¾ÅÈÆÆÄÄø´À·´¼Á¹··¿À»®¥®·¼·­œ£·°¦¬´µ¬®¥¤£¨¤  ¥™ª´±¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyz{vnkiguZfrxsyff]d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÉÅ¿ÃÀËÍÏÊÆÄÃÃÁľ¸¾ÁÃÀÄ¿ÁÏÏÎÇ«¯¶´µ« §´³®«¸µ³¬©£¡­©¬¦­Ÿ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuuefijh]jomxwcb``^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÎÏÏÌÃÇÆÈÉÈÈÉÇÅÉÇÈÇ¿ÅÇÄÄÉÌÊÒÏÓμ¸¶´¸¸Á¾¾º½º¼º¼¬­¦ª»º¹·À²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqocagvhjitmxl]d[V`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÌÐÎÇÌÉÂÂÇÂËËÈÆÌÊÎÅÆÅÃÅÊÇÊÐÍÐÌÇÄÀÃÂÉÍÇÅÁÄÇÁ¼¾´°°°Á¾¾ÁÆ¿¾¸¶Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`jjvlieuntb]bTWUSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<9>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÄÇÈÆÒÉÁÃÄ¿¿¾ÄËÈÊËɼ»ÈÆÈÍÈÃÈÉÉÅÅÃÂÀŵÂÉÊȾÅÇÈÍÆËÏÅ·ÀÀÀÀ»º½µ³³¿¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrpfefcjdajmno^Y\VVNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾƹ»Ãº¸¹¼¾ÁÇÁÆ»¹ÇÐÊÄÄÀÃÁÂÁÃÂþ¿¡·ÁÁÁ ºÇÌËÅÈÑ°¾¾¸º»»¾·´°¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfadbacdcjbgc[ZZ\YQOE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶¸´´µ¿»½¿¹¾ºº´À¸µ·²®º»·À·¼ËÔ·»ÀÁ¼»Å½»ÁÄ¿¿’§½Â»z©ÀÉÄÀÀÊÀ±Á¿»·»¾¹µ·´¸¼´½¸µ´°³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|yˆ}qc`bchjgfiei^VVTYOSLF8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“““˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´µ±°µ·µ»Á¸¾¹¿¼¼·´·¯®·µ¹¿»Áޗ~ɼõºÇ·¶¹»½½Š›½Æ¶`•ÀÅÀ¿¼Á¾¸Æ¼Â¿¼Å¸¶·´¸¶¶»»¸¶´·ºµ´¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒxqmeefoiekhXXNKKKRILHC9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’™”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿¾¼²­¯¬±°·¼·»½ÁĹ··¶µ¹¹º»¿¼ÐË}€¸ÄÇ·¹¸®·µ¸½µ€‘½È¬V|ÀÆÀÀ¿½¼¿ÈÃÅžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~‡|knpgpksfam`\TIKJDJBCG?:;8><7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘Ž˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼¼À·ª­¤®°·»²½¾»Ä¶µ¸µ·À¾Ä¼ÂÄÖªtwÆÏÂÀ¸¯µµ»Ãªy‰¿ÉUfµËÿ¿¾½ÇÌÇÇÄǽµµ¶Á½»»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†€rflintnxcgb[cQKTHEECHC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?>??FD@A?>:7?@CC?@=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼ªª£±¹¼½²¼¾¼Å¸±·¹¾ÊÊÈÃÆËΊstŽÌÑÌÊĵºÀÄΗq…ÁǐXZ—ÎÆ¿¼ÀÃÌÊÇÅÆÀ¹½¼Ä¿¿¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtolltkln_b^`bNIM?E@?DC;;::;:8;<:9<>::>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´¼Ï̼º¾¼Ä¾·½¼°¯¿½ÁËɱzuzÆÌËÍÊÆÂÄËӄm‚¿¾†^XzÊÆÄÁÁ¿ÅÀÊÉÃÃÄùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{zˆzmmw{_pc[]__TI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA??ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸´¼¶À¸Ëؽ¾¶¿À¿¯…vo{v„—´™qy{¿ÇËÈÁÃÁÀÉËsi{¹´|aWhÆÆÅÄ¿ÀÁ¿ËÇÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}‚znsxsgp][^]YREDCMIAE=H;;59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘—žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯··²µ³·¹¼»¶»»År|Á̼¶¹Ã­‡g[c^P[_pov|’º¿ÆÀ¹À¼¾ÆÂear­³uaVaÁÇÃü½¿¿Ãþ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸¸¸½¹»±¶²ÈÀ»¶´±°·¬³©°­­´·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y}vlu{pni[_`YSPAFHGK@DCH<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿš›œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹ÅÊtg†µ½¶¶žnjgU_[ILQS^osž¸¸Âº³»·»¾½aZd ´w]TgÂÃÄþ¼¿»º¸¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ°µ´´½º¾¹º»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰|‚zsuvwnq`_f][TJ=??FF=FCC9:5;99><<::<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´µ·ÇÆ|ti…¥¶˜bSE_QMieSLHPqxˆ¡°·¾¹²µ²¼º»gUW˜¼~SPrÁÄÆÄÀ½¿¹³¯±¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³»·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtwrl_ca[^OHB?=HCFMC@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·Ã¹…znnŽ oOIBkRC\{‡‡[FWˆ¦§°¶ºµ´²¬¼ººtUP…·LT‚¿ÁÇÿ¹ºµ­¥­¶±¦°­¨ž Ÿ¥­¶µÂ·¶´¥¨«¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´·¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wo{ourmc]fX\]RNNA>JBAJI@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³²­¶º¯­¼³¸º½‘wr…~WFBWˆQKNa}‡~QCO†º²³µ²´¯¬»ºº„f[xŸ\q—¹»½¸¶²±­« ­®¨£¦–™™šŸ©®¹¬««Ÿ¥¨¤«®®§¯¬¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmtil][jT]\PMHDFLBFNF8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹º¶¹»µµ²¿¡‡ƒ„}fL@UzpLJLN‡«oV?s¾¹³´²°±­°º·«Žƒt…¥©©©­®¸¯ª«­¬£¨¬´§—˜¡•’•—˜Ÿ¨®¤£¤ ¢§¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬ª¯£¤£¡© ›“Ž“’’™–š¤¥ Ÿž§˜•’”™ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wrxhtsndT`cW\QNLH@HQDMC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯µª“›cEVyRWHQaI|ccw®¹²¬³¯®¬­·©•¤©¤Ÿœœ§¨ž ¨¨¡©·±Ÿ–—“–Ž—›¤¨  ¢¢¢¥¥££ ž¥ ¤¬¤¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›©¨««Ÿ¦£›£œ•Œ“—•–˜Ÿžžš™¦—“’–¢ ¥¢¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦ ˆxƒ|vzcwln\QhTPNGPMLBOQ@>;>49:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¤¬ª¹²ž¢µQAzwXkJUcivudjz²´ª²´®ª«©’”«¯§—“˜ ž¡ œ¤¥­§© š–—Œ—‘—“˜¢ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£ž™—š«¦ª±£¥¨ž œ•“‘˜–•˜—Ÿ˜›™›¤™—”–š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’}|€uv}mk{dhUQcMJHGORMJNG<E@<2?859;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜——–¡¨¬®¶·º¹º··»®¨ ¡¨ °Á¹½|OKlª\j~qvS^oa`mh€–±¯®³µª§¡¡£™”•—˜˜œŸ¢¢›Ÿ­ª————–’‘‘“š—› ¤ªž¡¡ž¦§ª¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¡¤¡›˜ž¯¨®²«¥ªª š˜˜˜•“–š“••š–›——˜¡Ÿœœ—›¡šžš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}wx|dyy`bRU`HIJKSTIRPL9?A67<65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—“’œž¤¨®­¬««¯ª¯©ž—ž¥¡ÃÁ€UVfp}vmfzrT_bdjlblp”´°°¸¬¦¡žš•˜š™Ž‘•‘ŒŽŽ”œ£Œv—šš—˜™”™˜–›Ÿ¥¦© ¦£ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§  £±®²°´ª²®¢™œž¡™››š˜™›”–›–™¥¡ š£¡šœ™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ Ÿž ¥¡žž¥ ¦™{|vvsh‚le[SZZMQJNOULSLA7>C78=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’‘œ˜¡ª¢§ ž§¡¥Ÿœ’›¢šž±¥{m†pbeWQ\UWKNUZTO_Yl´³«¯§Ÿž¢ —‘”› ›˜—’“Ÿœ¡¤˜†lu›Ÿ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬¨¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½·¾°¬±®­©ª´±°¨«¨²µ·³¸­²´¤ ¥Ÿ¬¡¡¢  š˜–– ››˜¤¡ ž£¡ žšœ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚|xujwu]lZR`HRUHFUVJBLG=KH8F<77;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“Ÿ™¨®Ÿ§žœ¡žš™’˜ž›¡¡¡¢„dZ_iaVNPF??ADEBGRLO¨¶ª©¤ŸŸ™’’”˜˜–••Œˆ‹Ž•žya†Ÿ™¦Ÿ ¨¥±ª§®£«­¶°´²±®¶¸½Àº­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«¯±¹·¼¯³°µÁ¼·½³³µ¢¬¢©¨²©«¨§¨š™žšª§ ™§ ŸŸ§§¥¤Ÿª¢¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰…„~vrmivmhm\X\CWNJGMGBFM<>L>4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜™ª ±¢·¤°¦Ÿž—˜•™ž›œ£Ÿ™_^f`REE<K<F<B?>@AMz©­©ª¥Ÿžž¢£žŸšœ›”“•”ž˜–}t“¢š«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶º»ÀĹ½»¬¯§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¹Â¾¸³»Æüü·³©³­ª³µ¯³®ª¯£«§¶±­¢°¦¡£¯±­°¤¥¯£¡ š¡§¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¥ž¦™›¢¤žŸ›››œ‡†{trkktrqhV\QFTHDJPI?EA4FH95;>7;<?<<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž  œœ˜šŸ šŸ ‰vjaWND?L_~l_C<35K{ª²§££¡ ž¥«¥ž—œ”‘™˜”ŒŠ†ˆ†xo‚¤¢«¬´¼¶Ã¾¾³»ÁÃÂÅÀ¿ÂÆÆÅÃÈÂÀÅÇÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌÌÌÒǾ¿À¾ÇÆ·ÄÉÉÃÁƾº´ººµ»·°µ²ªº²®»·¿»ºª¸­«ª¸º´¼®®¹£¦£ž¦¥¢£©¦™›Ÿ˜š§ª§ ¡¡¤˜”£–”™‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ„}zqkchoxkeZ[FKLEDSMDBE7:?;549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ²²¸§¡¡«ª¡œž¡¡œ™qj`UIE@ARž¤ŠPG^®¬¡™››žž™———’ŒŽ–—“Ž‹‚ƒ‚wrqmqŽ¦­®´¹Å»ÍÇË¿ÂÌÎÍÌÇÉÑÌÍÌÇÉÅÅÌÑÒÕÎÓɽÀ¿Ã»ÆÅÈÅÑÓÍÓÐÓÓÌÊÂÅÆÆÊÈοÈÑÌÇÅÇÅÁ¼ÃÁ¿¿¿¶¾³®¿ÀÃÃÇÄÇÄ®¿¸²¸¼Ãº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›Œ™‰•˜› Ÿ£—žš““‹•…€ytsebgrof^ZYCNLDEPIDC@55589B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>8;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›¢¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¤¨¬­ª £žœž”eXPLEDAF^¾Ö㓣³®£žœŸš—–”’”–‘Œ‡ƒƒˆ‡ƒ€€yqroly¤¶º¹½ËÁÓÒÓÈÍÎÑÓÑÒÑÐÑÑÍÎÎÐÅÎÔÕØÒ×ÍÆÇÉÌÃÅÊÏÊÓ×Ñ×ÒÕÖÓÔÈÌÆÌÍÉÒÍÎÓÍÅÈÉÊÁÆËÇÉÈƿó³ÈÄËËËÏÆÊ¿¾¿½ÁÇÄÌÌÈÉÀÿ­¯³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›•Œ†‘‹€zruvgcgvidVWQDMF@IQB=B<:22A<E<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<A?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­³·¬®£ž£¢¡›\LCDFDKUxº¸«¯¯¦œœœ ¤¡š”“•”‰}wpkebhqoq{…Š€upnqtp…³Â½ÄÑÐ×ÖÖÒÖÍÔÖ×ÔÓÑÓÔÔÓÏÑÃÐÓÖØÕÖÒËÉÎÑËÆÍÒÊÒÕÖÙÕ×Ó×ØÎÒÊÏÑÌÏÐÍÓпÈÇÊÄÌÌÌÎÏÅÆǶ¿Ê¿ÒÍÌÏÆÉÈ¿ÄÃÈÎÍÐÑÏÍÊÈ͸·»¨Ÿ¥«§ž˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„|xsvpc`drb]R\IJGAEIJ>;A8=4586;86:<@>;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÁűµ¨¡¤¥Ÿ¢£^E;ABIZlš®¬¨›”—Ÿœš  ž›œ™•‰wic`____^__]blutppolrqu’ÄÇÅÔÖ×××ÓÖÐÕÔÚÔÔÎÏÕÔÔÑÑÌÑÍÓ×ÖÓÕÐÏÒÓÑÉÓÑÈÐ××ØÑ×ÒØÙÔÖÌÏÏÊÍÒËÎÐÀÆÃÈÆÎÍÑÑÒÉÌÍÀÊÌÆÓÏÌÎÈÄÊÇÇÈÌÊÔÔÑÕÏÒÌÓ¹ű¥¨µ®§›¨¬¥²¨°³¬¬““ŽˆŠƒ‹„Ž™“™‚…Œ|zqstmacim_VP_JJCFCRM?<>54:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><??=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯­ªª«¦®·¨«·×ÔÕÙÙÑÎп¼Ìɶ¾®¦ª¨¡£°sD@A?Sm°¨Ÿ—•—™šœŸ˜œœ’}pecb__a__a`_``_`fnppnkorwwœËÀÒÕÓØØÖÙÑÒÒ×ÏÓÎËÒÍÕÔÒÊÏÌÓÖÒÑÖÍÏÕÕÑÅÑÔÊÐÔÕÖÎÒÐØØ××ËÈÎÄÉÏÍÊÌÀÉÀÈÊÍÎÐËÐÎÎÌÎÏÈËÐÑËÎÊÂÉÇÉÌËÌÒÓÍÓÑÑÐÐʽȹ°®»¸µª¶°­¨¸­³¾»±š ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…ˆzvopokadnpaW\ZIFFDMXE;@=33<<87865;>@=9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ¤§Ÿ¸¶µµ¬¤¬®¾´°ÀØÒ×ÚÜÖÎÍÊÃÒÏÁÀ°©¬­©¥ªbgbi‡Ÿ›•“–›žžžœ“–—”ˆk^^^adb```a``a^`_^\bmroostvvy¤½ËÕÑÖÔÓØÖÎÎÔËÎÎÅÎÊÒÒÏÇÎÍÍÔËÎÓÍË×ÖÐÌÑÔËÌÐÒÓÊÎÑÕÒÕÕÊÀÊÂÅÌÂÈÉÃÌÃÅÈÊÊÏÊÍÌÐÍÓËÆÈÏÍÈÇËÅÆÁÆÊÌÍÐÑÆÐÎÍÍÌÏÅÇÁ¸¹½Ãýù²²¾±»Ãĵª˜¥¢™–‘••’‹”š‘”””‚‰†yqrkmg``phYXhVLFLIPQB;C>;67:8::57==A<:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÄÂÁ¿»µ²±Ç¸ËÕÕÙÚÛØÌÌÏÈÖÕĵ¯´¨Ÿ­‰s„‡¡Ãª–ŒŒ—•“‘‘•–•‹|eabb`]^acb``_`aa`_][]grrqrspmry¤ÆÓÏËÐÏÓÔÊÅÉÉÆÆ¿ÃÆÏÎÇÅÇÍÊÒÈËÎÎÆÑÒÐÍÌÔÊÇËÎÏÈÇÏÒËÑÏƺĿÆɽÂÇÉÎÅÂÈÀÇÍÈÄÌÊËÏÈÄÄÐÈÆÂÆÈÄ¿ÁÇÌÌÌÏÂÊËÈÇËÐÄÅÇ»ÇÃÈÉÂÏÁ½¼¿°ÁÉƹ½ª°²§¥¢œ˜›£™—™‘•˜‰‚wotdk`^fpa[W`GHHGIMTG?J=64355==48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ¼ºÍÍÆÐÕÕÙÚÛØÐÉÏÏÑÓȶ»»­¤µsc€¶¬Ž–…ƒƒƒ}„„~s`[^^^`^`cdc_]]^_``_[Z\akrrooklop}¸ÑÈÉÊÏËÍĺÀû»ºº¾ÉÆÂÃÀÃÈËÉÈÊÈÁÅÌÆÈËÍÉÄÂÊÉÁÂÌÐÅËÈ¿¹Á»ÆȾ¿ÆÏËÿûÉÇÈ»ÈÆÅÊÀ½ÂËÆÅľƽ¼ÀÃÅÌÅżÀÊÂÅÇÒÅÀÉ¿ÊÉÆÈÆÐÃÃÆïÄËÇÄÊ·¿¼º´©¬¤¥˜Ÿ˜¬£¡¥›£ ›”{wrtfiZanlZ\XRDLFBGDLDFS@54334?=3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ÊÏÑÌÇÂÃÆÍÎÎÌÕÏÕÙØÙÏËÒÍÍÎÈÁµÃ¾±°±eez‹¶‹’–†z€……vxurp_[[]``bcdded`\\]]_^`[YZ\borokilposÆ¼ÉÅÌÀÆ°¶º²²³²±Â¼¼¼º¸ÁÁÁž½¹½¿¹ÄÊÅƽÆÀ¸»ÄÉ¿ÁÉ»·»»Æÿ¼ÁÍÃƾ¾µÁ½Ãº½Æ»Âº³¼ÅÄ·¿µ¶¾¿»ÌüµºÈº¿¾ËÄÁÆÂÅÉÆÉÆÐÆÂÌDzÇÉÃÎÍÁÅÃÀ½³·°²§¨¨¹°¥­°ª­¬”zvwjdg`hocW^YJFJFHJAEBEI@9:648854;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÅÂÄÈÎÒÊÊÊÇÍÍÎÑÈÐÆÕÔÖ×ÍÊÏÅÉÅÇÀ¹Å½«¯ž\ir—”‹ˆŠ„x††~„{ttc\\]^``bcbbeeb]\[\^\^]Z[\^hsqmggnpry½ÌÀúÀ¸®°±§ª­¬§¸´·´³³´»µ¾²·°µ¯²¼Â¼ÁļÀ»µ²º¾À¸Ç¹´»¶Á¼¸½ÆÁûµ¯²¶º¿´Ä·»´«¸½½À½±»¶°¶º³Å¼¶®»¿µ·´Å¼¾ÃÅÀÃÅÆÈËÅÀÆÆ»ÇËÀÏÊÇÃÆÂ÷ý½¶¹¾Ç¿¬µºµ·¶Žytxggebkn^V^`FKHHJFBDAEE?<:565633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÍÈÅÈÍÌÐÌÍÈÊÈÊÉÊÄÐÍÒÏÍÅÇÁÅ¿¾¹·É¶ª±’\mu‘Ž†‰‰zx~††ww|sh]]]]_`_`da_dec__\[^\]^Z\[]_lpnhfkmnr|¤Ç¿¹¸µ°«­§ž£ª§ž«­³­ª¬©´®·±³©®¦¬³¼º¶Ã¹ºº±«µ¹»´Âº°À±¾¼»¶»Ç¹Â¶­ª¨°²À¶¸½°°§²³µ»¼«®µ¦®¶¯»²°ª¹°­»®»¸»ÀÀ¾¹Â¿ÇÃÅÀ¼ÆÂÈʸÅÇÆ¿ÇÄúÄÆ»ÆÉÌ˳¹Â½»³‰svvkiablhYXW[ALKMIEAC?FA:9:995854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÅÎÒËÃÅÁÅÐÇÍÁÃÆ¿ÄÄÃÃÊÂÉʾÀ¼Áº²´´Ã®©°Ž_o€ˆŽ{x}‰…z{„€wn^]\\]_`__dbbccb`_^Z[ZZ]ZZZZ\enohfgiknq­¹°µ®¦¤§§š ¥¡šœ¥«®¤¨¢¬ª­«°¤¦Ÿª­µ¶±½¹¯·¯©®¸´´¼¸´¼¯¸¹µ²¼Á²À®¥©£«±²³¨½ª«¨«­­´³¦¨®¡¤¯©²¦§¨®¦¨·¬±²·ºº¼±¼½¾¾Ä¿µÂÁÇÈ·¿ÀÅ·Äÿ»¿Ä¾ÄÈÌÊ¿¾ÄÀÀ©‡strji]aocWVXPHYRSKFFE>>@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?B;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÐÏÌÃȺºËÁʾ»É¶½Ã¾ºÊ·ÁÃÁ´µ»µ°®´»­§ª‘ii‡„‡‹€{}~xt~|swe_]\\^_`^_ccab`a_^]\ZXY[[YXZ\_fkfdgehjor…©¥«¥ ›¡¥”ž¥›˜‘¡£ª££ ¦¥¨¥­ œ¤¦¬²°¶·§°¬¨ª´«´º±¶¶®¶¹²°ºº±¶¥ ¤ ¦±§«¨¹ª¤§§¨§²­ §¦Ÿ›¤¦¬žŸ§¤ ¡±­­¬²´³´°µ¼¶»ÁÀ²º¾ÃÁ²¹¹Ã³Á½¿µ¸¼½¿¼ÂÇÄÃþÀÄ ƒxplbf_ko`UY^HNgOTGEKF<=?=:;;825536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;=:7676788666;::;9:;<859<:>>@;Èµµ½¸ºÀº½¶ ž•¡¦º¶«³³»³ÄÏÉËÂƸ¶ÇÀÌ¿¸É·»Å¸³Ä¸³¾À«µ»±«¤®³­Ÿ¡gl†††€|yusomjjipi^`]\\\^__acb````]\[\\XYXXXVX[^_dcbegggjmo‡© —•š¡–œ£™–Ÿ¡£§œ  ¤¦¢§ž›¢›Ÿ«°­±¶£©ªª¬¬¤´¹­·°¬³µ®³µ®°ªŸžŸ¤¢²¤¦©¸­¢¦¦ ¨¬«™Ÿ ž™Ÿ¥š™£œ›¯©«§ª¬¬­±²¸¯¸¹»°¶¼¼º«³³¹³¾´¶²±¶µ¿¶¾À½ÃÁ»»½—„zsl_e^ddXTW]IW\KPGIJGA<??@;?<04535:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»·ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÆÏÈÈÀÆ»»ÃÃϾºÇ¸¸¿·²Â´±»»«¸¹°¡ž¨«§–k}††xrmomkb^aff]]^]]]\]_`abccba_\[[ZZYXXWWXXXXZ^bddeffhikq¨“””›˜›¢—–‘œ¢¢¨žœ¥¦¢¥œ  ›™®®®®² ¦¢®«§¢µ±²²¬¨¯²§º³¦¶ ¢Ÿœ£¡­£¢ªµª¢£¦ž¥¦£–™ž—™› š—œ­¢«§¤¤¦­«³´ªµ°³«²¹´¯ª¯²²³¸³®©¬®²¸±»¶º½¿·³±”…yuf^e^[YVSZUK[QKIEHKIB=?AA@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½·½¿¶¾¼¿³¥£˜¥±Âµ¶½­´¸ÂÌÈƿŶÁÀÆηÀĽ³¹¹³¿¶±¸º¬±´®ž™£©Ÿ“™t€„„xoqtqhechdc\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXWVWadecdeddhjv¡œ“••—— —™•— ž¡–¡¡©¤Ÿž¨œš«§¯°«›£¤¸ª¡ ®¨¶ª¦§­°¤¸°¤· £›™™ª¦¡š¬¸¯¢¡¤œ¢Ÿ “”¡”––›˜—–—œ•Ÿªž©¤¢£ªª°®¨´«ª§­³°¥«®³±°¯®¯¦¨¨²­±´°¼´¹·®£”yud^aVYXSRTKM^LOKGGLLE=A><B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾·½®§¨£ª»À½À¹®´¸ÁÌÇÅÂýŸÈ˲ÁÂÁ­¼»µ»¼µ¸¹¯®¯©›˜ ¨”‰ˆ}wqilrtphhedfb\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWWV[bccbcbcdfi–“–Œ’””›™––œ œŸ–¡ ¦¦¤¦§ŸŸ¦ ª¯¦Ÿ¢¤·¨¡¡¢¨´¢¥¨¥°¥±®¬´ž¡••©¡¢”­±±Ÿ¢£ž˜›“‹¡”‘“˜˜“——˜—ž§œ§¡¢š¤¥¥«¤¥°§¥£««­¦©®¯®«¨ª©³¦¦¬¯´±¯¼µ±¯¯ ’zwrea\Z]XNLRHRaMVPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8847763321./2556;:8;7876<;:;;A8x»»±µ½°»±¸¬ž¥§­·»¼Áź±¹µÄÉÉÀÃÆÅǶÅIJ¿ū··½¶½ººµ²«¬§˜—ž£‹ˆs‰ˆwncafihfgifjm`]\[ZZZZ\]\[\^_\ZY[YYZ[WUXWTTVUSURU``_`a_aacej€”“Š‘Ž”“”•–—¤™ —¡¥¡­¦¤¤££¢œª«¥šŸ¥±ª ¡¥«ž¨¡ž­¬©©®­¢¢¢•˜£›œ«©°œ ¢Ÿž—™“Šž‘’“–˜˜”œ¡£¤¡¢• ¢¤¦›£«¥¢¤ª£«®¥®²©¦¥¦¦´¦©¨­³µ´¹º¯©¬žŒrqo`[WVVRGQOHZ[ORJTKSLEFID8;;=<8667:9;:976977:;:=<<6;<8>598:88659:;<97?<9678452121..1426:8698598989;9@9{µ´­´»²°«²­¨§¯¹¹³ÀȺµÀ¯ÅÈ̺ÁÊÌȵɼ±¾ÃȬ±¸Áµ»À»´³©«¦•š›œˆ€rˆƒ{tiijlgjkmkjme]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURSOQY]\]]^___bdmŽ„‘‡‘š“•“œ›£œ›¡©©«¨¬§¨¦¤™¥¯¥•™¥¯ª œ™› ž¯šœ«³ ¥¦Ÿ£¤¡•“›––’©ª­šœŸ¡ ›”Œ™ŽŒ‘Œ‘–•¢ £œ£•› £¡—¢¨£¢¨« «°¤­·¥£¤¢­­ª¨«¯³·³¾µ²«¯˜…tsh[YYSUREXLQ[XMTNPLPQINIB=??A?=75799<<987:79:;<=>;7;;:=67:;8976989:6:=99576571141-+/434988::8::748=8?9~³­§³¶®¨¨¯®›©¨¬·¶¬¼Ê»¶¿¬ËÆŸÁÎÏȳĺ·»ÂÈ°­¸¿·¼½º²´¥© –—˜—‡zt€vwnmhmmmpggigd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUSSNPQYZZZ]]\^_`d~Œ‹Œ‘Š’—‘—™¢ › «ª¦®¬¨°¤©šŸ­ •–¤©¨˜šž®—˜¨ª™Ÿ”¥¡ž’‘’‘“•§ª¥š™™žž–Œ‹“†‰ƒ‹’•‘ ž¡¤˜•Ÿ•š¡¢ž”›¥¥§¨¨ ±±¦±¼§Ÿ£¬µ«®§°µ°¸µÀ±­±«‘~rsbVTUNRJGVPRQLLWMJLNRGMKACFDC>A75889;9:7::7<=:;@>:9;9:?759:9876958779;85576661320-*.102877;99;8948;8@8³¬¥±·ª¥¢±«ª§©²±¤¶Æ´¹º³ÊŹºÁËÐʱ¶¸»½Áñ¯±·­´³º²²¡¢œ——”ƒwkglnqnqjpkdege^ZYZYZZZZZZZ\\]\ZXXXYYWXWUUTRSUSVURNNNRWXYYYY\\]aj€zv‰Ž‡Š—‰””˜›™ž©› ª¦¥¬ž¨š ¦œ“Ÿ£›——…„’›£•£–––ˆ¢››”‹ŽŠš¤§œ••—›‘’‡”Ž‹‹€Š’’’ š ¢–”˜™•¢¦™™¤¦¨¦¡ ´²§²·¡œ¢·¬ª­¤²²¦µ¼µ¬«±£‰ysm]NQQLOCMNNPKFNNJJNMQHMJAGKHHC=858889:;69:68;99><8:>9;?8789:886857688974577820301+)-/12876:999984988A7w¶¦¤¶°¤§¤ª¥ ¨¦¥³ª¢²Ãµµ²³ÆÆ·ºÃÊÌƳ¬º½´·À¯­©°ž¦­º¯¬ž˜™œ”“‡{ƒn__frpuqinieghj_XXXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQMMKLSWWVXXXX[]aosvq…ˆ‚ˆ€‘„‹”‘”ž¡›œ£¢¤™¥—¢œ•‡™šŒsƒ~—–†‘š”ŽŽ{™Œ‚‰‰˜Ÿ£ž“˜–…‚”~~tŠŽz‡“›šš’–Ž££Ž‰š ¡£¤›¢´¯¬¯­Ÿ˜¥¸¦¦±¡°®œ°»ª©¯ª™ƒwscVMROPNCSNLQLBPQHINRMHJJDJLFJJ=749888;;69;7:<9::;79?9>@79:<89764445874312585/0102)(,-12764789::65:87A7x·¡£´¨¦¥¨£¦¥§¦§³§¥´Á¸°´°ÉÄ·¹ÁÎƽ³¬ºÁ«­Ã­§¢¦’¦¶­¢žŽ”•‘Ž~x~eWV_gfighncjhgb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTRMMJHNSSSTUUVY[]ilrm…|tNXrƒ—‡Ž—‹”‘Ÿ˜•”–•–‰€“Š_;Wo|‹”‰€Œ’Œ††sŠ…—y{†““ƒ•Ž‘ƒ†}“xqp…}‰‘—š™“‹‰ˆŸ˜ˆ‡–žš¡ —§®©­©¨ž–­³¢¦­™¬«˜¨³¢©­£“~rn`[NSRWLDTJPLLFNOIELQMKOJILPFII=7599999:7:;:>>8:==7:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9y· £­¡¦¦ª §©¨£ª°¨§´Á¹°µ°Ç·³½Ï¿¹¯®µÂ§ªÅ©£˜ƒ”›°¢™–…“ŽŠ†}su]PLRUYZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MORMKHFHNQQMPRTVXZ`mpi{‚tQB@•’’}‰•„Š›Ž–•‰’ˆ†•†y‰`JQnxŠ‘„}„Š…n~”xuvx„™oQˆŠ†{~x”vgw†ˆ}Š‰•‹‘’—Œ„Šˆ•„šŒ‚„’š–ž”¤£¨©¥¤žš°«¡¤¤‘¦ª–¢ªœ¢¦¨‰umf^[HQQSMIUMSILKOIHFJNLMTKQPOFIC<769:8:;;8:;8>?99>=8;<6;;478;6775344696/3/.125221/,')+*,4833979:99::::?9w¶›£§Ÿ¡¯¡§¨¥§¨°­ª¶¼¶··³Á»¶§ºÈ¸¶¨¨µ¶ª²¼¦ž–Ž‰“¨•”‰}ƒ|wpnXMKMNOLMQW[\ZXZUUVVVWYYXXYYXYYYZXXVVWUSPMJE@@›kssIMKDDDINOhYNQSTUZnƒtw~ji\U‰”‰t‡|…Œ“‚’š‹{†€v€xsovqtz~Š«…yzhv{Žprmx‹’xz€{€vrr’whu„„„…{•ŠˆŠ‹€„‹Œ€”ƒ|€˜”œ–‘ž©žŸ  ©¥Ÿ˜Œ§¤“¡ –žž¤€rha\]JWPRHJXROJLMRJJJLPHLQLRTMEHA<78;99>=:;<98@?::>=7==79937785675251472/2.,//200/-+(().1272198798775:<;7v®™£¢˜œŸ´©¯©¥­¬°²ª½´²»¸¶º´±Ÿ·º²ª¬©¨²¯¡š‘Ž”›~v…w{unniYKHIHGEHHPTTTWWSTUUUVWWWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQQSV^uƒ|xfw—˜}hyvx€‰}„˜’r‡|w{ok~­|sŠ{†’}tfv|†lohs}‰Œˆ€lyq}qmvqhq~ŽpC‹„‚ƒ…wwz‹…}Œ{u}Ž’˜Š’š›£–™šž¡œ–Š¤›Žž—Ž–˜womebZXXUQJSUTOPNPVKNKNOJQNHOOLFD<;79;::?=9<:99??;8;=7<9999266856633611224.,,-..-0-+*''*.1362/876966527995y¦— ž– ¦¯¬®«¨©±¯±«¼¸¬»¾¹³¬§›°§¬›–œ¥©¤ —™…’zˆŠ‰up{mtpiljXKFGEA@CDILLMQRPQSTTTUVVWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNOQTX]eprmˆ§ªÀ~uyc|xo|yˆz}‹†omŒ’ytxjj€‚q–‘‹~–€I“˜nhw~‚licly…’†ksl|nr{†imps‰„†{}~{vots…‚yxp|ŽŒŠ”ƒ–—˜š’•—™—–Œƒ‰ž‘‹’†–ninonXVXTRQYORTTSXUMNHNKMNKCHNGE?:89;99:><9<;::=>:8:<9?868727565541432/024*+**-.+-*(*(',-1250,5567485HA895w™‘›™šŸ¥­°£¬ª¨µ¯®¬´¿«¼Â¿¦¢™•¤—ž„‹”¡¡˜˜‘“‹sŽz€…‹…tntkpldkjYNEFC@<>>AFFGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_IMOORWZQY\`§ˆbšitzepmz‹‰vˆ†tlš‘ts|jkMy…’‰„Žg1v†sl~~ƒtfet~„„…€filukq|hqq|n“Ž|s}|qpnum‚wyujy‰‚ˆ‰„–’’‹‘””Ž—€yˆ—ˆ†Š†€ˆvjjoheXQZWYY[MPUVYXNIHEJJHGB@FDCG=998;9:9<:9;:::@<9:<98>787715234533645031.**+),,++)(+'),,226,,5775478iO8;5n’ˆš‘™–¤¨®ž²Ÿ§»¯«²°Â±»Ãǚ–”™‹Ž†y„˜”Œ†q‡‚t‡Œ…zorpnodpf_TFIC?<;9:?@ADCEGILOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOOQVLAIQIb¯³ r|xl}mrƒ‚…z„††yr¡•tx€su”‡5q¨Ž¡¡„¢„vp†|‡|sŒ­‰€ggbjnrlpƒuioXupŽ›’wl{}mqmp€zsunbvƒ~†€…ŠŠ‰‘‹‘Œ‹ŽƒuxŠŽ€~ƒ€}zqpok`[\^\YXa_RN[ZXWLHJFJG>BABG>CD=;97=;:;;9:99;:?<88=:8;66651121253474531./,,+)*))***)(*)+/3DM2166643<vR7=7b’“ˆ–‘¤§ž¯•¥µª®±®Á²»ÁƖŒ”€ˆ}n’‰ƒŠ‡…u‚„l•ˆ‡{txxlwnwci^IPG>@7449;;;=>@BEHLLLLNPQRUUVWXYXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL7CMRSDJ†v€||v~mwˆˆ|~…ƒŒ~v¢™y~†€„™„›œa†ªŸ‹ƒzwˆ~‰ˆsŠ—ƒz]drtz{wŠmhjbyo†‚znwt„zptywkni]w‡|‡|‡‡‹’—ƒ…Œ†}q„ƒ}uw{|‰vpsteg_[[^T\g^WQUX[UGJJDLG?F@DC>AA=:97<;;=<::99;;=>79>9985653244004645554-,)+('''&(())((+++/00Uq=23331E~W4=9\ŒxŠ€”Œ’œŸ¦‘ « ±¨¯À±ºÅº–Ž‘”‡z…vkŒ‘‚}Š„ŽŒxƒ€s¡„‹}}~p€~zgvkRWL@E211367688:<>AEGFGJKMOPQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMORLKT]YRJi„ˆ{‰y|r|Œz}‰‡~—‡v¡™ˆ‡’”¥¬©H†®¯¯‹€“Š‚‹„’¨‡€˜˜Š›tm|†‡}Žhghxn…‡‚…q„…Gl€wryvhmk_w}ƒˆˆ…‹z•›‰‹ˆ‘zu‹v|xmow}ssrl[]][ccXgf\UOPVYPDLKFNICFCCA@CA=988:::;;:888::?>6;>7585773344236656768;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|}‰…ˆ‘–˜’—¡¬¡¦¸¯³¼³—’‹˜‹}tp‰’~}Œ‚’”}†~†¤‡ˆ‚ˆ…x‡ˆ~s„x_cWKB60./23123668:=>?BEGHJLNQSTUTTVUSQNGC?80,#‡[>?84.]–ps£UFIKMNPW`YpZ\^j“‡•€„‚…‘“~…ˆ‘š•‚¡¡˜•›š¥­“š»±§»Ç苌¡¥”‰‘|qƒžŸ‘œv……Šˆihoƒ€tŒ‡„‹q…‚w‡{v…}nvuf€”†‰‰‡ˆ‡¡ª¢–‰Ž˜z‚‰zyogkx~z~rjd^ZZ]j]af`YOKNWRQHPJDNGCJDB@DDA<:87=<:<:88778:==8<=68656623444576867<BB?<8:>CQ^e\G2'&,,--.1(?‹[.310Oƒ_4?;nupfxƒ{€Œ€‘ŽŠš›¤¡¬¦«¯°—‘‘„¡”„xwŒ”|’†’•Š€’›Žƒ€Œ‹‚‰ƒ‰mpj]BA4--//./02234778;=?BDHJNQRSRSTTRPOHDB<87/9D><<63.l“—MPHIKKKNV`cggmušš““‹Žšˆ“‹  ’£ª¥£¬“¨¶¢¨Áîǯxº”š|¡ž™„“…‚¡Ÿ“˜’„‹…™‘–lpu‰‹‚–Œw„qm…Š–‘ƒ…ˆrˆ¡–‡“‰Ž–¥µ©›•¢ƒ‡“ƒ}kjk|€sa]c^Zfk\lk^WKGOSQNMLFIPCDMFACEGB>:97=<:;:987767;:6=:785456345566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYp‚pu‡qv’†~—–š•žžœ§ ©–“˜žge¤š~„’‘y€’ˆ’}Š„˜’‘‚€€‹‰…†„ˆ…xx~gMR>/..,/.-/000212457;?CENPRTPQQSQNPIED>;<:CF?><752<?R5HHHLLMNR^oŠ|s} œ¨¥¢™¡—¢•Ÿ¨ž¨« ¨¬©ªµ—«¿«¶ÈÈ·ÉÑϾ› pi«©Ÿ„“’…œ¡š›™§‘‘‰•¢ššxz~”˜’¡’–˜”ž{w•’«³ˆ—Ÿ}”œŽ“–™¤¢¦¶°‘™¨ˆ–ˆlsr||qh`\`^bgc`hg[REJKPOIJLFFMCHLFFCBGEA:85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Ppu`n}awŽ}{”ŽŽŠŸ’—ž–›ª˜žªBD}‡‰‡˜x‚ŠŽ|Š†Ž‚€‰ŒŠ„’…ƒ†‰€†w_bP460-1/,.00//..0015>AAMQRSPRSURNSLEE@<>=GG@A@8662<9;FHGIJNOQYm†w•‹£§ª´½¸¤®¬¬§¨´«°¶²²­»±³¾œ³Ã¬»É˷ÿ¸¥£°²¬­ª£‹–˜…¦¦ £—¦™¢ª¨¤ˆ…”¤¡ ª¡¤©œ±‹•£§·»› £°“¢£ž‘¤¢«¯­³µ¢”¤ªˆ™‰’Š•yz~…~g`h\eb]dc_ff_ZOCIHTOFHLFJGEFHAKFCFGA;87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLicWjpXz…v“…ˆ‚›ƒ’‘Œ’Úȝ–sV—ˆˆœ|†ŒŽŠŠz‡‚‡‘ƒ…€‹…†‡’†‚„‰†ˆ‡‡qna@E64<2/110-,+-1.-3?DAMUQRSUUWUN[PGGE<>>FHCD@8;<5C;=FKIGHROPW“ „®£³ª±ÁÇê³Å¶¬³¿³¸¾¶¿´Á¶»»¤¸Æ¨¶Éǵ¾¹´¨£´­±±›™’šŸ‰¨¯«¥”vŸ¤—¡«±³™–ª­¨®¶»²º¬¯µ¢±¬±µ¼·µ®µ §§£¨š©°­²º¸¸§›¶©Œ¥Ž‘“Ÿ†x‚ƒuYadVeaac`af_[TJDELUQHIJDIGEA@@KDBMF<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AFWQJL[ZQcdWyuq”}…‡“v…€Œ{¿»£¼‚´”“›„ˆ’‰‰y†€Œ“‡„Ž‰Ž†€†‰…Š‡‘zxn]V@EM<6:46AB764//6CHCQ[OQUWU\VO^UIKJA@>GKFED;>@7D7?BJJEFWTP^¥®£±´Ã¶¸ÁÌɶ»Ä½³³À··Áµ¿°·t±³¦ºÅ¤°Æ¹±³±´¨¤µ¶ª± ¡–›¢’¥°®¦­«§¤˜ ¬³º¢©²º´»¾Ì¿ÅŽ½³Â·º¸¿·º·¹¬¬°¦±ª­¾°½»Â¬™º¨”®——«‰}‚|jWbaXjejeW[dYVTIGGLQGCHIAHD>?BBK@@MC99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FRLALRWTYUZvjp„Ž„nzsy‡b¸¡™£‰•“–“““–’‡†{†–Š„Šz|‹‡†|ŠƒŠƒ•}xzueO\dGEL:Qca[^SF?;HPDZcQQYXZgYT``MSOEA?IJHEFA@C<E6B>HGJLSZT]“¯¸µº¹É¿º½ÉÌ»¼Á¼·µ»»·½´º±Æau²¥±šžª½ª¥¨«ª£¢²µ¡«¨ž•–Ÿ˜Ÿ®¥§¦¥Ÿ£”¢¦±´§²²½¶Á½ÓÉÊÓÆÂÅËÁÊÃÀ¾½¿»¼·´°¹·¶ÃºÅ½ÃÈ°ž¹ª¢«Ž¥¨¶‰€q_ab]Wa_hfRXaVRUIEENKA>GD=KB=B@=F>;H@796379>489:57045/26389374426?8@>GKRTSQPOQQPJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKE@IMPRLQ]gllq…slrrsˆÕÀµ™ •˜™‘Ž—’––Ž†‡}†ƒŒ–Šƒ€ƒx{‹ƒ‡{‹yŠ‚—t}zkepuY]\Peeb`ed][XW\MdmURmm_n_XgeUYTJDAKKHFIHHGBI9D?HKTTV\Z[’¹À¹½·ÆÀº¸Ê˺·º¶¸¹²¸µ´®¶¶™du¨œ­p^¡­œ˜ ¢›¤ž«¥” Ÿ”Ž–˜—¨Ÿ¥Ÿžšš„¤¬¥ª°¬·°½¹ÔÑÏ×ÏÉÌÑÌÏÎÊÆÀ¿ÂʽÁ¼ÁÀÄÄÅÊ¿È䤻°´¯›«¹¼šyl]_\X]`YccQ\`SPKCBEGE<@E>BHB@D=:E>=J?47535;=468977022/24169775555D3ELM>51/006:477@IOI;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODR\Yi_p—’”olouu‡³¬¡¡Ÿ‹™œ™Œ•‘›’…ŠŠ~ˆ‡Œ‹‰|„s{Šƒ…{‰t‰†•s{xkmu{hreilifjih`fihlZnt—­¤¼ˆ‡g[oh]ZYTHKNOJKQKTQHLAJGKP_^bfia—·Ç°¹³»¾µ±Äǵ°¹°°»«³±§ª·¬¶§›§šOšŒŽ –‘¦˜¥•Š““‰‰‘‘ž›¡—š•–‡žš¦›¬¯¨¯§³´ÔÔÔÖÒËÏÔÕÎÓÏÍÅÂÉпÊÉÊÉÒÇÌÍÂÐÒ¸°Ã¼Ä¹¥¶ºÄ¢‚nc\\]X`WXfZQ]WOOBBHEBI;AD>AG??B7;C>@H=46655;:687654/10146278875367C5B8?-0-1349=97,.,1;FK=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYSeWs˜‚hqoyyƒ ªž¦—››—‹Ž•‘šŽ}‰‹…ŽŠŠ‹‡|„‚pˆ†{‡rƒ’‹~qxukqx~q{mxslipmcinpxiw|~Ë¿Âߧmcxnc[a`JPRUNY^P^]MPNTQUU\nnv‚r—­¸¬´§°¶«¬¼À±«µ¦¥¸§¬®¡«´£Ž±®š˜˜Œ‘“‘„Ž›§’œ‰ƒ‹„Š‰„‹ƒ“•˜—“›‘œ˜™™žž«¬¤§¡¬­ÏÒÕÑÍÌÒÓÔÐÔÑÎÈÃÔÑÈÍÒÓÓ×ÍÒÑÅÒÖÅÀÎÇÇ辷Оzne]b\V`R][OPTPNH>AFABE<@B>ED>@?:==<<JA45465<888664412/03526768533;=<E=@11+/249>5901022-2DN3)/3.32=N238C}_2A†tD:==I>@CFH<VRMO[u†…Šwlwp}~¡žž¡‹™““ŒŒ“–…y…‹Šˆ‘‡‚{r~€‡y„u…“‘‰ovrks|{w|swqk€srhoqzyr{¾Ë›~Œ²ƒvr„vhaj]CZZ[WfdXekSX]]`d^cx{~‹™ª¤¤¡ ¡¨¦ª°¸ª¥´£¡­¢£­¢§±Ÿ‰¦š”’‘‰‘Žˆ”‰k•¢™„€…}‘ƒƒ“–­‹••™Ž…’—§°¡ ¡¤¤¨ÈÎÏÈÂËÑÔÑÔÒÎÓÍÆÖÒÌÔØÖÖØÔ×ÕÉÔÚÍÉ××ÑʬÄÃˋsob`_XTYR\PJGIIJ@;:;EBD<BD>HB?BC;;9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/--;R017/532FD28>nb5=tM99@I<AD?A;PLFKYp€u}hsxr‚‰€•”…‹–‰ŠˆŽ‡x„”™Šˆˆ‹‰~ƒxt{}ƒ‡wz‡‘–€ƒnxpmuvx~t…|ym‡vtn}v„uy{¶<A‹Æ¥~|ieVICfcechjdox[_fiknin€ƒ‰‘‹ž —˜Ÿ£¤¦²¤¤³ ¡¥ž¡© ¢±œ†ž’’’‹Ž‹†ƒ„~œ›Œƒ„…z”~‚©•£Œ’Š—’‹}—Šš‘ª³˜š›§œ§½Ãƹ¶ÆÍÒÐÒÐÌÒËÉÔÎÐÕÚ××ØÔÙØÍØÛÎÉÚÚÒÕ¿ËÌ´xvnd]YRUPZVFGJJEE=:79@AB:HD@ECADB;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?1*(.BS39254/7K75<`bA<svV87AH:?C><9QECJTlnopaqqs†|—‘‹~‡’‚‰†…Š‚‡|x…–—ˆƒ‡…‡z„yqz{„†uz…ŽzŒp|oozq|qƒ‡nŽzuw}|‚u|‡ˆ°tY©Â¶Œ’‚pnb=^hrpqpnxweioruxr{‹‡Ž”’›• •‡Œ“› ›ŸªŸ ­œ¢š™Ÿ¥žŸ¬™‹šŒ‘‘„}ˆ‡ƒ…‹Ž ™“ˆ„‡~m™y„˜†ˆ“ŒŽ”Œ†{›ˆ“®ª”•—ž˜§®µ½©­½ÆËÈÉËËÏÈÃÑÊÔÖØ×Ø×ÔÛ×ÓÙÛÖÏÛÚÑÖÉÔ˕y{hh[YPRS^HCEII>A>=7:=?;>H=?AAAD@>>:86DB755479.566435532323647553457EBDCEB56<FNSM[nfcnskaV>,4LG865434BF4=W_hLux^8;?F<<B<:9D?CGRk_mdbfkv€ˆq‘š€z€~‚‚‚„~„||„—Ž‡‹~††€w‚yn{{‡uz’ž vu‚tu}t€„o‚o’„t|…zv†|‰·Æ¥ÂÉ·–›wpeNfczw†¢‹xyw{ƒ|„vm“–”•˜ƒŠ–š——¦œ— —Ÿ“’—£™«–‘Š‘‚Œ…‰ˆ…‘žœ™‰…‹†˜z‰‰Ÿ—ˆŽŠ‹‚|¡‰‹¼¡˜“—™œ©¦¦®Ÿ¨µ¾ÀÀ¹ÇÉÍÎÅÍÊÑÖÖÕÙÕ×ÛÔ×ÙÚÛ×ÛÚÙØÎÜƆzyghe`TWVUMKDNC;<=<9:<>9=@6=?@<?><9867CA6455=80665547745613854564567HH=DJE7925;H>;::7IP]ZRUXK9T>;95327I8=NYMHxxd5=>C==@:6:>>@EQ_Yea][htzyl‰’wvz‹|~€€}…{~‘‰„…z„ˆ{u}tn|}†~t~’ž‘Ÿƒ’|†~xŽ}yŠŠn‚š€t˜…~‰…|~z©Ã ¼Œœ£œ}‰„}‰sŒŠ~s¦šœ˜”…{‰„hGp ¤Œ‹’…‰‹’•š“•‘—Œ•Ÿ”¡”’Ž‹~ŽŽ‹„ˆ’–šŸŸ‰Œ”’ž‘‚‹€¦™ˆ„Žƒ†„€¥†Š‹¸˜’•–¢§¡ž£®¶ºµ«¿ÆÊÐÈÇÌÏÓÒÒØÒÕ×À×ØÙÛØÚÚÙÙ×Ü·xxwkidW`[TPOHDMB==>99::99;=6?>><=9:;;37D@8378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWN<MTHN?96333>C;[X>5YypZ<<A<=>8589?=DRSRX^UXfmmmi€ŽŠqryŠ{z}|ˆz|{‹‡‚~uƒ†yszsm~…}w…›¡›ž”’€‹ˆ˜‡€œ’n‡¨…z ‹|‘Žƒˆ„œ~š‘Š£¢Ÿ¤® ‹‘‹…‹’†Wr­‹Ÿ«œƒ˜›Ž\‚¢‘‚ŒŸ“•Œ‡ˆŒ’“Œ”””ŒŠˆ–›•–‘‹’”†€‹ˆ’‰Šœ–™££†’–¡‹ŠˆŽœƒˆ€ƒ‡…¤†Œ³˜’”—¡¡Ÿ™’œž§±¸¬¥¼ÂÇÍÇÆÏÌÏÌÎ×ÏÑÔ®ÖÕØÚØÚÚ×ÖÙڟo|tgg\]XSWXC@ID>>>:49:;7:;:3;;?=>7;9:19G=:37=@50677255?65;55858:57735HR7GOK994=EJB>1FCLB98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:<@;BQKKSYPTcbxmb~’ƒnmw‹xyz|†|{w†„sp…‚zuvvt„ƒ…}’¦£Ÿ¥¢–‰”—‹Š¨—rŠ²„§‘„™“…™‹¢– ˜“‰›¡’©¯Ÿ‘•ˆ•‹n·…šÄȲœ¡¥›œ˜–‘²‘d¤Íǖ…‡‰’“”Š…ŠŠ†–š›”“†•—„‹™ˆª——¤£ˆ™ž–›‰ˆ——Š„‡¥‰“©š—“–™¡˜Ÿ™“›£³´¥£¼Á¾ÇÅÅÉÈÉÂÊÓÌÍÔ¨ÒÑÖÖÖØÚÔÓÚ΂rhc_]^NJTZBAGD;A=837;<:8=649:<:82?9:29I:>67BC32:96264>=4;>6949;57944KQ<JQK9A7BGI@64JELF><88ETA7>\86214:;E`XAFathLcZ>5;::5;:>:EMFHRWSRBcFuŽ}|m~ˆxz~zƒ~vv€ƒ|ln‹y|xx|„‡‹}Š£³§£ª³¡–§Ÿ¥¤–•®¢ƒ¸•’³™¡ Œ¥›¯£¤˜§–§™­¯¤—•–”‹˜™– ÀŽ¤É¸«›¢¦­˜‘›²†…¨¢œ˜…ˆ‰Ž•‹“ˆ†‡ˆ“˜”Œ‹““†”˜†„‘œt‘™³–—¥¡ˆœ™“Š‹—š‰Š–Ž†}Œ˜ž‰œš™“˜˜Ÿ” •Ÿ›¡±®¢¤·¾´ÅÇĽÃÿÆÍÊÉÒ§ÎÍÓÒÐÖØÓÐØ»ryv\`U_WPHINEBCE5>:76:?;<7=42669774=5<5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=89566=:JFDGN[\YIf`;H„‹z{n…†z|„x€…~px|}}osz}{x†‹‰†ƒ’§»¬¨²½¯¥­³³¨£¢°¬Šš´ž£¸¤•­¤–©­·¦¤£Ÿ™©˜©£¯°ªš™œ”•‘—Ÿ—™»»­É¡i¶¸«°”˜ž£«“—¾£^ª²‚‰Š”‡‘|ŽŽ}ƒ†Ž”•ˆ‡“—Œ•‹Œ—˜’™´—–«ž‹›”’’Œ™›Š’ž‹‰• ¡”˜š“›˜ž”¡ ”œ¥¯¨¡¥³¸«ÂÈĵº½»ÅÇÈÂÑ¡ÆÉÍÍÄ×ÖÑËÓ¡pzh]YS^ROFD><CAA8?874>F<<6<35355454B3::BM:A;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPeGb`bpI@‹Š~s†‡}ˆu‚Šƒm}}|pw‡w‡{Œ†Œ™ªÂÀ¯½Æ»³´Á¼´­«³·Œ¨²®®¼ª›»¤¨­¹¸«¦¦¢¡££¨¯²±«œ¤˜›˜—ž¢¥¥’£¹®¨À»¬­²¹¥¤§}ˆ‡œ¬½°ƒŒŒ‹ƒƒ‘z‡ŒŽœˆ‡˜‹•—”š–§š±š‘¬Žš’Ž”–—Ž‘ ‘‰•›£¬”–”œž” ›˜ ¡”šž§¦¤¢¤°²¦ÁÇï°º¶ÅľͧÇÃÇüÕÑÍÄʈtsb\Y_[MJBL@EG?A?B;:4>A<=5=6>333241A17@BN>G@CNCA=C=;86CC5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GE?CF\fF`igZ][“ŒŒˆ{‡‹†ƒŒu†Šo~|‚q~z•z‘””˜“•§´ÆÉ¿ÂÌÁùǼº¯«¹»—²¶º²À®¥À¤«¯»¼ª­«¢¢§ª®´°ª›Ÿª›¡›•Ÿ°´§‹¢ººµÁ»«©œ²¥¤¨”…ŽªÃĤ‚‹‡ˆ„†•”zƒŒ‘Ž‘¡ŒŒ”’‰—Ÿ—“™•˜¦ ¯ŒªœŽ–’‘”••‘¡”†—Ÿ ²ž”š” ¡™¤Ÿš œ ”˜ž¦¤¦¦¤¯­¥ÀÄµÉþ¶Î²Ä¾Ä¼³ÑÊȵtym\X\iSLHDLKKJAA=CD<5AD;:3=8B332263A05IEM>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBfZMe\fTcj™—ŠŒˆ’†‰y†”r€|x‡‚‚y¡–¨šš˜º¾ÈÈÊÁÒÉÊÂ̼Á³­»¾§º¿½¼Ä·¬Á©¬²»½ª°©£¥£¬­³­¶µ Ÿ¯ž¥¢˜£´¼©›¨¼Á£¶¶¯«’°­«¬—†šª¦¥‘‚Œ“¥•‰€uŠ’z…‘žŸ“”‹”£™—œ•”£ŸªŸ‘¥šŒ•–ˆ|•’’£›• ¢œµ¦ž—¥¤£¥žž¦˜ž•—›¥£¨§¢²¬¨¼Àį¥³·ÌÀ¹®Ä³»¾Â¸¬ÂÃÂÀ˜myaXW\[KKMJFDDIBBACK:4DH9;4<7E.12352B26SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQF7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>jH_XaZddVž—Žž’‰Š‰Ÿ“„w…•ˆŠ•¡š®¦£˜Â½ÈÃÇÅÓÍÎÍË»Á·¯º¼´¼Ë¼ÃÁµ¶¼­³¿¹¼®¯¨ ¨§¶­­©±·šž­¢§¡«··©¥¯¾Ã±½¹³§ªµ³­®––¥¬¨ ‘Ž’±Å§•Ž|‘•}ˆ‘™ª™˜“““•“¥ž“™“¡£¢œ˜Ÿ™‹žˆZ–—’–¥™e˜£ž²¥–¢–¬¬«§›ž¦—˜—˜•¡¤¨¦Ÿ¶«©º¼Äµ¥´µËÁ¸©¶¬²º¸®¨¸º½¸ƒlnZWTUNFJSNK?AGDDHFG95FM;>7>AJ.32025B55PVN<LFKRLOHGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|hW;=@BFBqFiIRebLF¥”œ–¡—©–ƒ‡¦“ˆ‡‚œ„ƒ•”Žš¢Ÿ¯¾®¡Æ½ÅÄÆÆÎÎÎÒʾ»µ±º»¼¾Ï¶Ä½·¹·²±µ³¸³¬¦œ««¸ª¨§¯°—£¯¤§¤¤´À°ª¬´¾Â¹À¹³§¹µ¸²®•¥­¯®¥‹“•¡tÁš~—™…–šŒ±•š™•““™™¥£•Ÿ›–š©œ¡ š‹–`J–œš•š¥–T–°Ÿ¯œŸ¥”¯®¬¦š ¥”“™™ŽœŸ§¢™´©ª³¼¼»«°²ÇÀ¸¥««­±±£¡²²´¤qnf\ZNPKDPPPQ;GJIGHBD>9KU?A:=EM07544:B34NWO<JKNUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@CAF3>58JKCA=C;4EA:A?>H@5*B52,>c]g:35tde@R7&#3}iX;:BC@=QEWRsbWFHª—™ ¢¨¯™‘—‡‹§–Žˆ’…Ÿ‡„—ž š£¤µÈ´©ÆºÃÃÇÊÈÈÌÍƾº³®¹¸ÁÁͶȺÁ¸µº±¯®²´§£›ª³´ª¨¦­¬™¤®¥¤¨¬º¿¨«¶·¿Á¿¾¸²²Ã±¹½¬£®µ¬º¦ˆœ˜¦›v¿ …™Ž“™š‹¯—¡œ›—•›Ÿ¡©ž¨ ™šªš¢§ž˜‘ƒnv’¢š•¢ž­²£«•¨ª—ª®¥¤Ÿ¥©“’™œˆ”œ¢ž–±¦©«º¶¾³²­¾¹¶ £§¨¥§œœ¬©©Œcea_RKMGHNIUL=LDNJKBCD<QU=AABDO18=77?B75UXN?HNQYSPQTJQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW;:=..R`MUHe^HE«”œ¡Ÿ»¯™”Ÿ‹“ª›‘’“‰«‡¢ŸŒ¤­”££¶Æ½´ÁºÂÂÇÈÅÂÍȽ¹²¯¹´ÁÂʵƱÁ¼´º«¨­¬°£¢™ª´º¦©¦«ª¨¯§£ªª¾¼§¬¼³·½Æ¼·µ¸À±½À³©µ·«¿¥£˜‘¢ ¼Ÿ‰š ™—žž·Ÿ©œ¥£›œ¡š¨¥³¡›¦œ¨ªž™•”›‹—‰Œ¥¢”¢ž ´¯¥¥“°«™«¬žž££©‘•• ƒžžœ•©¤¢¡´´ºµ­¨µ²³žœ¢¥š—•™ª¡žw`\_]JHFGMQIMEFFBRLJAEG@VRDH=AGQ1;B7:BF79\YKALPTUSMWRNUJD@JJNO9C?5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-1:g\FCCœpbGE§—¤ŸŸÃ¬›—¤—™©œ–ššª––¨¦•­­™¡«¶Ä»¾·ÁÂÀÇľÍÇ»½¹²¯¸³¿Ãȵ¿¯¼¶¹·¦£ª¬­  šªªÄ¡¤¨«¦ž«¯¬¢©¨¿¸¦­½°·¶Ç¶µ¹¸¿±¿Á¶´³´¯¾£—¤—”œ”® ‘¡¢¥££Ÿ¾¥©¨¬¡›¦Ÿ½¢™£Ÿ¢©«¡–•ž“ž‡…“ž¤ µ¬¦œ•²§™¯¨Ÿš©ž ™•Ÿ„Ž¡š›“¥¤š˜¬±¶±ª¥ª­¬œ˜  ’Ž–¨ž”hbYa]NIGJNKHEDIA=PIA<GIH[ROK=HOU4BF9>HG5Ca[KCNRUWVQXTRUH@8QQPM:G@4CHQSIC;C>GVKC@O>K<06;GF>;FA56?9:?9;15D0-,0Mv\4KZ5,MnW<-=)#zbQ5CKQ9oRF<KxecWL¢š£œžÅ¬¡Ÿ¬® “£Ÿ—¥ §©«—¶±£ª²µÄýÀ¶¿Â»È¾Êȶ¸µ´°³³·Áƶ¾°¸´¹µŸ¦¬ª«ž¥£Á¥ ©­Ÿ¤©­¯¢¦§½¶¦±¼·¶µÃ²³·¹¾²ÃÀ·¸®³µµ£¥–’”¡® ™¢©¨«£šÃ­©ž¬­››ž™¦ ½¢¥˜««¬¦¡™šŸ’ž‰ŽW–ž¥¡ ¸ª§“˜¶£Ÿ²¡ ›®–žŽ™”‚ŽŸ—•Ž¢¤•¦­²«©¡¢¥¥••œ˜‹‘“¤ž‰adZc`LHJJNFEAFK>=JB99JKN]QQI=LV\9FI=DMI8Hb\LCLPSYYVWOZ^IA=WQIK?H@5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+w`S6SZkWsHE6=ue\KNžŸ¡™žÃ§¥¢³¡œ³§“ª¤ ¤Ÿ­©¬»°¨¬µ±ÇÄÁ³ÂüÆüÄʽ¯±¶­°´¯¿Åµ¹±°¹µ¬š¨°©©š¥¡§Â¬›¬±›ª¢®°©¤§½·¦·º¼®¶Ã­³³Â¿²Æ³º·¬´¶­ª¢¦–••¤¬¢ŸŸš¨«°¯¯¼²¦ ©©™™˜“¢¤¸ ¡¤“¯¯¬¥§Ÿ’¡ž•ž•š¢Ÿ§´¦§˜´œ£¯šž›®ž“—”š€’¡•ŽŸ¡“‹¦¬°¥¦¡œ ž’’š“…‹’œžae[geJILJRAC@IG;;G?99NMU^RSJ>O^]=HPBLLI9Mc]LELRTY[SUO\bHA?ZQAHAKB7FELKN>;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<v]^?[U^fr@8<H–weA4Ÿ¤Ÿ› Ã¨¤ª²¡¤µ©•²¬§¢¤²¬®©»²¬°µ´Æ¿ÄĵÀĽÉĵÀȵ«µ¨°¸¬ÀÄ´·®¬¶¹¥™«±«ª˜Ÿ¦—­»´›¨°›­Ÿ®´²§ªº³§º³·²¸Àª·²Â¼´Å§¾®­·µª¨¬¡——’¦¥¢£˜˜¥¯¸®²µ¶ Ÿ¨¤™••“¤ ·¢¥¦–®²²¦ª¦¡ž›šš–˜¨Ÿ ˜¡ž¯²¢¦—®™¥«—š¤‘›Ž“—™…–Ÿ”Œœž”‹©©ª¢§ ˜”ŒŽ™‚†–‰”Ÿxch]kjMPMNT=CANC::I@77QO]^RVQAW`\BJSHVKH:Td]NFON[W[RPQX]GAB[PBG>NC9HGHNP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1[bZ33806p[bH05JpiVCWFŒyfC;¤¤¡¦¿¦¨¯¯¡©µª¹°«£ª´·±°¹·¯¶¸¸Å½Ãǽ¼ÃÁÆÀ¸ÁÆÁºª¶¤­»­Áø¸ª­±»¢•­°­²–¥§ª¹© §°ª °´²ª©¶µ¬¼¬²²¹·¬¹°Âº½¾¦Ã«°·¯©««§ž˜™«¢¢ ‘˜¡±¯³«±º›œ© ™–’—¦¡·©¥£¢¯±´«²¨«Ÿ›  ›ž¥œ¢–£³°šŸ“¥š ¨š•¡ž•˜‰”˜“–—œ“ˆ›™”Ž©¨§Ÿ£›—š’†Ž™‹~–…›jhlalnWPQZTACET@;;IA7:XPd^PVWDY^]MLRN^KJ>Zd^NHPN[UYPKSWZI?DXPDF>N?=IGGQPB=CFBM?:2D?77547?=95E4+75/251.-.,1>*'+=\p=>1.1e[d@1647gY`F(?8l}h[V;‰{cC=§Ÿœ¢©½¡ª¯«£±¸©¥µ³¬¡­µ½®³¸¼º½¶¶À¿ÉĹÄÁÀÀ¸Ä½Á·¯µ¨«·²¼¿¿´©®±¶ž—«­¨­–§¨Ž§»Ÿ¤­³ž«¢±°³¬©¶´µ½­¯±µ¬°µ±ÀºÄ·«¼¯±¸«­ª£±¦ž¥ª ¤—™Ÿ³ª³ª«³š§›š• ¦¤´®§¢­­®±§³­²©¤œŸ¨¤ž•¡˜›¨µ©—™’’Ÿ™ž ž«ž——…•˜‹™œ“Š–—š—¦¥¢ ••–“€”…{’ƒŒ–elrgpr_FYfVDCMXDZ9HB6>]Qh\NY]G[^]NMRXdJJC\b_PLMNXWXPJVVWM=EUJEDAM?AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,+%2+*5K1.'__aU150=`V^8)C3YU\gK5ŒzfL@¤™ ¤¬·¤¬©¦®®¶©¯´º§¦°·Å·±¶¾ÀÁµ´ºÅ¾ÌŹ¿º¿¹Ä¸Á¹²µ¬ªº¶»¹½´ª­°µ˜˜§«ª«›¬«Ž«½ž«®±£« ±­³®®¶±¹·©­®±¨µ¯³»¼É²ªµ´±´¯®§¡³ š¨­ ¥•–šš²£­ ¦¯–¡¤šš’¢¥§²©¢§²¬ª¶¥¯±µ¯¤™­§š˜Ÿ™™¬¸£—“˜œ¡˜—”«žœ“€“˜œš–‘Š”“žš¥¡¡ ˜•‘“•z‹…{ŒŠƒ‹’knxnu{`EajYIHY[={JGE6AbTi[M\`J[]ZRRRb`LKE_``QLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`U`/5(C^Q\.*B/JGP[H3cYUKD™– °¨²©­¥¤®®µ©·´¸¤«´·É»´ºº¿¾´´·ÃÀÌȻü¶¾¾À¸¿¼±½®§º¹·¶Á¶«­±¸”—¦®«§£±ª”¯»¤¬²²§¨£²³°±±µ±¸³¨®«±§¸¯µ´ÃŶ©´µ«°­ª§£¶ŸŸ§² ¤•›š•²ž§œ ª©£ž›–˜¥¥¥·§¢²´¬§±§®°µ¬¥™ ¬¨›œ›”©¸œ”ŽŽ‹™œ¢—˜¥ ž•ƒ‘•œ˜–•ˆ——›§œ£ ’•–v„‡{…„‹mqwu|~\Kel\KNc\?b{GI8GgWe[M^bMXYWTXTi]OOHa]_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANHf27'FaLV%-B.=EMQ<3rkJDC™¥®¥­®«§¤°²³ª·°¶Ÿ«µ¹É¹®Á¼Â·³±µÂÃÎÅ¿Á½´½¿¿º¿¼³Ä¨©¹°¶¶¿¼¯«³²œ §°­¥¥°¥ž²µ¬«²°¬©¨´¹¬´²µ¬´­©¬¨«©¹­±±Ç¿¸¤¹¯©­­¦¨­°¦¤¤®£©œžœ›°š¢£££‘¬ž¤ Ÿ¢ª¦¦¹¥¬µµ¥ª«¨¬¯¶¯£ž£¨ª› šš’¤´š‰‡‘¢ •”Ÿ“’„Ž’’›˜•”‡˜“•™¦›ŸŸŒ’w~Ž…||}‡Š‰qtr~}}\Sdo^NZf]FD–[H;NmXa[M`bNVWVWTYg^QRLcZ[TKGOTSNGIVS\N;P^IBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3Bc;6*HdHJ+:I?3BIS,>k=HH›ªª¢ª°¤¨¤³´±´µ±±¡«­½Ëº®À»Ç±´­´ÂÂÑÅžÀ²¾Á¼¿·¼Ä§¬·¬³¸»À°«²­ ¤§­©¨¤°£ª±ª¯¬°®®­¬³»§¶°²©²©«¥¥£­º¬ª±Â¹µ«¹¨¨¨¬ª¨±¥ª¤¢®ª¨¢žœ£¬•¤˜ž™¬¢§©¢­¦£­¬¸±²¡©¢ «®°¬žŸ§¨©™¤˜™ §˜†ƒŠ‹Ÿ ‹Œ–›ŽŽ…‡• –—•†–““—¤œœŠ‘‰~ˆ†|w‡…†tsq‰vl_Y`ncQsq\K;„|F>WuXaYNc[NUVUWP\b^SONhXWWKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*35>10485(5/*,.30;),,'%234$,2-860)(1<]J0.IgDF8<B05EKX1@”[>MF”—­§¢ª²œ©©¯¶¬¸µ®ª¥«ª½È»°½·Â¯°¬³ÄÃÎÎþ¿´ÀÂĺÁ´ÉĬ¯·­²¸¿¾³­®«¥§ª°©§¨±¥´®«°®­±¯²­³»¤¸³¬¬®§«Ÿ¢ž°·«ª­º¶¥µµ£©§¬¬ª­¡©§¦±²¤¦¦¡¡¬–ª¡”› ¦ž¤¢«¤­£Ÿ§±·­­£¥¢›©ª®©¢¥¤¤˜ ™–˜“‚‰…œ ŒŠŽŒ™‹ƒŒ—£›’›Œ“’‘”¢™›™ŠŽŠŠ|†‚ƒzt€„‚~tw‹¤ˆyk^`ngWe‡dN@g’LDbyWbXReTMVUUTO\]aUKMiWUWIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*49?./463)4+*,+.#4.-+&(+79*&6+<-2,&06WZ.0JgAA<<C+:JO^4D†@HHD–’¯¤£ª°˜«©­µ«¶±«¥¬ª©¼ÀÀ¸¸³»µ¥²¯ÄÉËÑ¿Á»¹À¿Â¹ÁºÁÄ®²µ±³»À¾³±®¬««¨¶ª¥­¯«¹°¨±±¯±«µª¶µ§´¶¬¬¤©ªœ£ž³³¨¨¤´´ µ­¡©¨«¨«§ ««¨¹¶©ªªª¢© ­›’©¡ ¤¢¦£ªž¦µ®¨¦ª¢£—¥§§ªœ¢¤£Ÿ™˜Ÿ‘Ž™Ž~‡Œ‡„žž‡„ŠŠŽŒ„†•¢šŽŒš‘’‘’Ÿ—˜–‹Šƒt†xuƒ{x~€ˆoqggqx\`sˆjO]˜VHmxUdVRbPMUTUPOX[bUHPiTVSGPYUI>IHOQPxLMV=<KD?@A<@CUC9AK=5;E13;97*4:=+-341*8**+*,)*(/*&)%3;,$2)2021%/2Qc02?f=NX?C,>LT_/Ik7PE;•Ž° ¥ª­™«¥¬®³´¯ª¥¯©¨º¾¼À°®¸®¡µ¯ÉÇÈÑÀ¾½»¼Â½ºÃÁ¿¿®²²±µ¼¼Â±²³ª³¨¤µ©¥­³³¹°£®¶±¯²º«¹®ª®µ«ªž©«Ÿ¢ ¶­¨¡Ÿ¯³¡´ªž¨§ª£ª¡¢¬­¨½®¬®­¡§¨Ÿ«™¯¡˜¢¡¨§Ÿ¨›™ª°©£Ÿ¬¢¡“¢££§˜š¨¥——™Š‡•ˆ}†…„¤–…‚‚‹†Ž„„“ –ˆ‘“‘œ”—‰……xt}uxy€{ttzi†£ui^el‚ugˆ‹|RXp^JxsSdSQ^MMRYfNLVYeYFSiRQ?BNQaQ:IHLSIqQLS;<I?;<=;@@W<<>H73CB15:93-5::)-31--6)(+-,52#2)',%.;.&1.0-14%,0Lh:48_=ad?F1CP[[+HO:VB4± ¤¦«£¦¤¬¦´³±ª¤°§ª¸¾Á»¯§¹ª§®°ÉÆÈѼ¿¾¹¾¿¼É¼Á¸°°´±º»¸À²³»¬¸¬¢´¦§¬²¶¹³§§»µ­¶½°¼¦­¬µ«­œ©¯£Ÿ¥¬ª§œžª³¤³¨šª§©¤©£©§©½ª³¯®©¤ ®œ›²£•¤œ¤¥Ÿ¤šš¨«¥ž›ª¡›’›¡¥˜—©©‘˜š“Š‚…~‚€ˆž†}‹‡Ž„“›“…“¢Œ”’‹‘›’•‡ˆ~qzy~|iw|zuqq}h†x„‡d`hcr…zmgy]^VBWzmTaORXKLNqt]HZ[gYEUfPD>JNDCA9HGKS?jaIQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11&/>KH1%90%,,09/,,+6'17#-/GjI14X=fbAJ7GS`U*=;EZ?*”±™ŸŸ©¥¤¡«¤·²²¥¨±§¬¸Á½µ°£¹­¨¨°ÃÉÉÌÁ¶½¿µ·¿ºÈ¶Ãµ´³µ±½¸º¾¶­¹µ¿­¡³¦ª«°µ¸´«ž¼¼¨²À³º ¯³µª¬ž®°£œ¥¨©¢žœ¥±¦¯ Ÿª©¨¢©›¤¨ ­»§­°®¡«£¤®žž­¦—Ÿ›¡£œŸ›š£ª¢šš¤¤•–”Ÿ¢–›–¦¬‹ž‘‘Œ‚‹€{š•‰|~‹†Ž‹Š„’˜‘‡”£‰’’‡š“‡|yk}vyxb{zqpqsxisjƒgdhaosmbip`pA\xkV^NQQJJMSYVM]^mWDX`O^PHMDF;7HEKO<rhJK9AE;;==;;=J49B<3;G<4?18-78;2(09/,5..=-*K>*49&'.34.0+/4&,:$40BhY13S=e_DL6KWeO*<2P[=#’™¬™Ÿ—§¤¢Ÿ§£¸¯®¢¯¯©«¸Âº³­Ÿ¹¯«¨´ºÇÊÈ¿·Á¾¯´¾·Ä¶Ã±¯º²²Àµ»¾·©¹·½«¤´§¨ª°®¹±ª›»½¤°Àµ´¡®·µ¦§§±³ ž¤¦§¡¥™ž­§¨ž ©®§ ¦—£¨ °¸Ÿ¢±¯¡¬¡¬¤œ¦§©šš›Ÿ£•œš©¦–›Ÿ¨’˜“˜’™–¡ªš‰Ž‡}ˆ‚Ž}|¡ˆyƒŒ…‰ŒŒ…‡’šŽ‰•Ÿ‰‘•‚‹—Œ‘}„{so}qst`yxiopqojrczlifdaf†`[rjrMMiXZMPLJHPRQIN\_nSDXZRgOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23/:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%53=fd24M?e]FO=RZhH*>/ZY5(—¥˜œ–­ Ÿ¡¤¡·«±¤´´©¨¹Äµ²® ·¬®­°µÆÈÀ·¿Á¹°´½·¿»¿¯«½°´¿±½Ã¹©»º·§¨µ¨§«°­³±§š½·¤­¼¶¯Ÿ±·°¨¥§¯±› ¤ £¤¡—›¯¦¡Ÿ¢§¯¢ ¢“¤¤£·°¡¦±«Ÿ¬£¯˜œª¥©ž—š¥“›œš¦ª™œœ¤••—•œŽ“—£©¡‰Š†z„~„Šz—Š†y‚‡„ˆ‹Ž…“˜ŒŽ–™Š–~†—‹z€zprwnot_xwdlllji„merikfi]ds€_ZkuiZI}^[XOOJHHRUF29_^lPDXVYeMIIEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<#8R=*113>D5,-'42*;+139cl84GAf[HTDU]hE.;2bU,2–£¡—”œª¥¡¢ ·ª® º¸¦¬½Å³¯®¢µ¯¬­¯´Ãļ³¿º·°³¹¸º¸»®­À³´¸¯¿Á¸¬¼ºµ¦¢³ª§©³«­²¢œÁ¶¥¨µµ©ž²»ª§¦©¯¬™¢§œ£¦”˜¢²¤™Ÿ¤¨©œ¢ “¥ ¤¹¨¤§®§ž¥¡¨’Ÿ©¢¡ ™› ’›œ– ¡«››™¡”‘”–šŽ”“£¨¤ˆŠ†y„|…†}Š‹†y€„‡ˆ‡‘…•“’Œ•”Ž”{ƒ˜‹w~{ltrllsaxthhjgfo…gghcfij`ibifZe{c`SsT[[SLIGIOS@!*i^jLCVU^`KIHEC.:B<F<6KPD8:D357==895?:;4>8@K=>93)8><:9*6@3.E4(+,>0-N?.+-7,1195,&.5-80576`tB3CDg[KWGU`hB379eO'2ž¤£‘Ž¤§›žž£µ¬§ª¹·§¬ÃÁ¶°¬¢µ®§¯¯·ÀÀ¼²Á¶±®²¶¶¸·¶¬ª½³¯²±½¿·®»»±¥ž¶«¥¥´©«® ŸÂ«¨¥°³ª¬µ»¨ª«±¥˜ªž¦¤‘™¦­¢˜ž¤©¡œ¢— §¶¦¯ª®¡¡ž¡• ¦Ÿ¡ ™›™œ’™”¥¬¢˜—ž”“•—Œ˜š© ‘ˆ‰‹‰y…w‚‚‚‡‹‚‰|„ˆ†„„–•Ž‘‘‘“{ƒ•Ž†r}}fxokjlguskcgdduadffejjcjqY^X^mdaNhWZ`VIGHKMRX>9`liGBTS\[IIGEA.<?9A89RG@7:B037=7692:<97:9DM=B<0*<@;A=-5B37=+*,0A*JK./*+3722(57$+7.72685\yN2>HiZLZJVbfA:3AfH%5›¤ŸŒ­¡™˜ –¤´±¢±½·¡±Æ»¹°±£·¬ª®©¹½»»­À²¯®­¶¯³¸³¨«¹±¯®´¶»¶¯¸½­¦µ« ¡°¥«®ž¤Â ²¤®±¯·­µž­¯­®¢™¨ª¥ž•›¨¥Ÿ™¥£¨š œ”œ­°¦¹¨®£¡ššž™ž£š¤—ž˜›”š ’¨•ª§›“›œ’Œ•™””™¨§Š‰|‚t‚‹˜…‡|‰‰„„ŠŒˆ’„“œ’’‘–Ž€Œƒo€fynhkjgqrk\hcbraehjnlgjifl\lmuqaTbhdeYIFLMOXQQVaeT@VSYUFHFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24;6#3*)6.55465Z|]19Kj[M[KXdd@A1IeC'4“¢šŽŽ°š“¡š©²°Ÿ¸À¶ ´Â»½¹±¥¶¯¨®¥·¸··¬»¯­ª«·ª´¹®¥³µ±®©±¶¶°²µº§¨Ÿ¶©žž©¢ª­œ©À™­¤®°¶µ­­Ÿ±­°ª¢›œ£¬¨›•œ§£š©¢¤–š œ‘›£«ª©»Ÿ¨¤ ˜š™ž¡k¢–˜œq‚–›¤€v‘©§ž••Ÿ‘‰—™€–Š y†”ƒnj~wƒql†‹†}„‹†o^c`g„—†k‹”“uw‹„~ƒf†€huifW\isnNPjcfq„g_dfnli^__‰„†gOKD8ETg^JGPPUUKHSaoteF[QUPFHFC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,+08>G601.*.*/568,#1'214:176Xl16Ok[N\K[fb>G1Pd=+/¤™‡•°›œ“ ›ª®«£½Å¯©·Â¸½¼­¦¶°¥«¤¸³²³°¹­ª§¬´¦°µ£¨¸¶µ¨§¬¶²®´­³¢©Ÿ´«ž¢¤œ§¨š¬»•¦¥¯³¸­®¥¨®«¬¥¡žœ §¦›˜¡¦¥››§§“ž ™ž¨ª£µ°£££–—˜—£ˆ¡Ž’š‡¡‡”¡¥¦ªž’’›’ˆ„rxŽ„ˆ¡vˆi—ˆf}sx¡oˆ‡„~{¡ Ÿ™€{‡žtˆŽv›Šl‡ƒmheczlqbT†mcli˜qXjon†X^i[kj[ˆpmyr†h‡„Z^FN>F^MERVVQQRWTg^LXJRRPEGG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82).1<I9/01.*/(-4583%&2115>1<8Xƒu25Rk[N\L\g_=K1Wa7/(Œ¦—ƒœ¬™™Ÿªª§©¿Ã®±º¼·À¾ª¤·°©¬¦²µ®¯³¶«©¥±­¥µ³œ­µ¶´¦§©³±­²§¯Ÿª ²¨Ÿ¤£š¡£œ®µ•¤¥¦¶½¦¬§ªª¬¨¦¢ ˜ §£™™¦£¤˜œ¤©–”¢œ•“£¥¦ ·¤¤ £˜•“˜“œˆ®˜”‰©‹—¢›…±€¤¬œ“™•y‚Ô¨‡”Á›Çyw±¥·—d€Àœ¿y„„yƒ|‘Êq–¼œÅ{r¶§ºzl–±«°yhkX±®oei¼’¼nhymrØ~Sjc¶²q”uš¡ªWOWaOVNFT[XQPRŒ\W\P@]EQNEGI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22BE/.32.+/)-/186- /416A1=:Wƒw21Tk\O[M^g\>L1\]41!¦“¦©Ÿ—œ¥¬²¨°Â½²µÀµ·¾Â«¦´­­©§¯³ª¯¶´¨¨¦µ¦§¸¯³²¶ª¥¤§±®­±¦ªž§¤±¤¢¡ž—› ž¯­•ž¢Ÿ´º¢ª¨¡­®¥¢›š¢¨Ÿ˜›¨ Ÿ˜ž§§‘œ§›”¡§¢ °£ŸŸ£––“˜’™…¯jjŠª~g„•‡­eqœ”™¥•q®¡¤~w»|k¡v±_j´[¥€fœ‘`fzfjxj©e¾rg¦Œv²j|±xt’“cmm§m[„ Eig‡–Euœ`}g{¤§‚Y_‹«i•xzj§7J¯[WTlc[KNW_\WV;NˆOWV/ITTJDEF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3..53/+/(.0.:5/'$203B/=;U‚v2-Vj\OYL_gY:M5_Y31‘¢•‚¬§¥ž£¤©±·¬³½¾°·Ä²¸ºÂ§©°«¯©©°¯¤°º°¤¥®³£©¹©ž³²°£¥ ª­¯«¯¦§Ÿ£¢°œ£œ˜•—›œ­¦—›¡ž´³¡«›¢­­ ž™— ¢©œ™ž¤ œ™¡§¤£š—¡Ÿ¬Ÿ¦§ ›Ÿ¡–•‘—‘š…µ›µx…©™µ™w‡³›·~“••¨”~k¦z‚…ˆ’”’w«gk±[¬{‡”tˆp†€€ˆ—xƒ‚‹—Œƒ „°vwŸqkkl|‹N¤XHcc™~ch¦`yruS’‡^P©mcq~‡€b.Q¡n[Tkg`LK[dX\ZB>°xWXA#MiECDA@A19>88:84;:9<9:A:E::;6:CB8=?KNG:5:AFB@AD<FD;0201;F,0.940,.(/3,>831/2-D1<<S}n3+Xj\OXM_gX7J9aU50•Ÿ”ˆ³¥¦¡®©§³¬©»¶Â°¼Â­¸·Áª¬­®®¦®²©¡¯¼ª¡§´­¤«µ¥¦²³§£¢ž¨ª²¨°§¥žŸŸ¯–Ÿ™••–˜Ÿ­¢šš¤¨µ¯¡©©¨ª›ž•˜ ¥¨šŸœ£Ÿ› £¥£•›Ÿ˜š£«›¦š›¢ —“’““œƒÕ“™¹p°Â~Ɔ|֔›»|™•¥œ¤{Ž‡¤‚¥‚z¬yV¯{‰~Ÿj¹Z¹w†„}¦‚“|˜zªyŽœ{±mŽ„t¼…o”P¯§ÅŠQ zc`ªbsr‡l—ˆ`Sµ´È†€‰|c¤3Bv]QjhcP@XfZdaJHMlK[SOYfZCD?E?0<<59;74<;8=:<C:F:;>6:@C;6@OLH<:<DHCBCD<EF81211DC./0483+-).323971#%5*>3==Qwj6*Yi[K\P_fT7G:aQ72%›¢“˜±§¨¥³ª¥´¨¤»·Á°ºÀ±µµ¼³µ§±°£°³¦Ÿ®¶¨›¨¹®£¯± ³´° ¤žŸ§©°¨´©¤œžª—˜—–—•–¡«žš—¨­°©£Ÿ¬¢§–ž—œ¡¥¡—¡¡¢¡›¢¢§›ž¡ž•™›¦ œ§•œ›Ÿ¡™’•‘ˆ²nhµq«‡oŽ¦r´sr¶{™˜¤Œœ¢~‘ ¥~°vƒ‘ÒÑv\®|†¤o›ª¦k†…}­}—™{±s“Žx³e–t„žožf”RȋZÂ\Ÿyb_­_vs‡b—ˆ^Yʝo¿uMKµSUÆdTQjcfXAOj_liOUFI9=WR[WXHC?J<2?;5=<46>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>HI91746A>/.24252-).26,742&60;5:=Pqh9'Wi\BNT_eP5G=aM62/¡œ‘¥¯¬¤ª»­¦´¥§¶»¼²º¿·¶µºº³¥´´¡±²£Ÿ¬°¤˜¦º®¤±±´¸ªŸ¦¢ª¤±§¬©¤šœš¨ž•”˜˜’’£¨ —“¦ª±¦¢–“­Ÿ¥’”¡›¤¦Ÿ”š¦¦¡›£Ÿ­š ž–œ¢žœ¥••š¢Ÿ–™–’›…¬{w¨v£Ž‰‡©o­Š‚§ƒ˜™¡‰’šŠ¢“™‰®…‚³\r³R®}ƒ‚¤q×}w…†™™w¯†Š‘œ‡w´ašeš‚”l’Z°XKšu˜yf`­^vw‡g˜ˆk^¯w•žxl5yÈ®²_ATo^g`EPl_qmVUM.eciSYQ:AD@L:5?91=<16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK97<46:>/04333.2..18*.32%!03767=Pke>&Vg\@=V_cN6GC`I:88Ÿ” ¸°—´Á­¨³¨©²º¸³¸¿¹·²¶½µ¥¸³Ÿ´¬Ÿ ¨«Ÿ•§¶«¨±²«®´¤›©  ¨¡µ¦¦ª£™ž•¥¡”“œ™’•¢¥š“§¬¯¦ •™©Ÿ¢‘¢™¨¥Ÿ”™¥¨œ¥ž¬¡ ”Ÿ›ž ˜™œ–—¢ “˜‘¦†©}}¥x¡Žƒªp­‹§†• ¡‰——ˆ£‚‘ˆ”ª|€‹yo±Z¨‚‚ˆ ytØv‡t§Ž›’¤|–Ÿ„{²^œd ~ƒ•l’\«[Z“‘hgªcr{k˜‡q]¬Z‰ ŽkneOJC¡\ZLt^beMZa_rs_JU6Jš“YHE=HFAL35A8.;>05A78@<6=<F?:<6?=B7.HVJEAH6KIN@IK@EN::@4.;>002144+*05/7,&21($$6671<PeeA&Uf[?1U_bL7FI_C1>8¡™™¾«—´Â®«­©¥´°¸±µ¿¹º³±·¼ª»´Ÿ°¤ž¥§§ž”ª±©°ªµ¬«¯¡˜¡ ¦¤£¹¢£« —›‘¢ •”Ÿš”˜Ÿ Œ©°¯¦—›¨¦ŸŒ’¤—¨ª¦“—©§žŸ¡£­¤¡ž¡”¡˜Ÿ ’—œ•ž¡•–«›®mr´r©ŒvŠ¦s´xs³€‘¤¢’œ‰¤‡w¸oŒ{‹¢kk¶Z …e——i¡¢§m“r´t“˜²j…“ˆ­ju³af¢o‡’j—\­`M¡|‡‘Rs£ly~o˜†p\¯V<œwfTon.\§ObRkealYb\`p{cSYQ>>mp3BB@?L9!7@6.;@37C58??3;<CDBJFMIF62JTKEBI6IJP?HNCFP=<E50;<010/75,+,426/#00,,289/9N`eD'UdY>/U_aL5FM^81B8¥š›º¡›²À®­««§·©¸¯´Àµ¼±¯¹¸«Á¶©ª ›¦¤¡’ªª§¶£²¨®ª —œ§ ¥«¹£­›–™¥£•¡›™œŸ‘“”«¶¯§™”œ¬ª—Œ“¥™¥¬¡‘—ª²¤ ž¨«°˜¡£™¢— ›–›—¡“œªœ”‘«™‡Ô’š»s°Ã€Ã†~Ֆ›¸xˆ—Œ˜ŠŒ§ˆz£¶u}wv‚š²`ƒºyÀ|u¸bµŒ‡©}–¬©q{u¼ˆ§ ia¦Ž¯¡~Œt‡«}¾ns¼t²ƒux€Šnšˆqn¤t½]w}[ay¼kZV[jz^j`dfbmwoY[YCA@r?CG+5H"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-7A9§šž¡¼¢—±Ã°­ªª«±§¹¯¶Ä±º²®»°®Á²¬¥¢ž£¡œ›‘ª¤ª²¤´§­¤Ÿ–šª™¦¬¸œ¢®˜•¡¥ ’œ£ž˜š–“¯¹°«•—£¨§”–¤œ¤¬‘ ¨«Ÿ›Ÿ©£³ž¢¥Ž§¢”¡šœ—•¤˜° ’•ªž…™¶€‘Œ¸•x‚“›µwnknsny„Ž‰sžÁ»½š{²¨pt‘¸ƒ|††‹‡{Š†—|¤»¹½œuz´£tv—ut°u™žf†iµtrpw¶Œ^y}‰hƒymyb‹¬pu…Y[§jDdYSf`c]cQgfqluBNPLD;ZL>J3<0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITBKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7LT_G'SbV8*O]]=+:VV'=;<§ž  ¿¥–´Ã´¬«§¬«©»®°Æ¯µ³®·§µ¸­©£¢¦ž ™”¬¤­ª¦µ¨¨Ÿ›– £ž¬¤¾¦¡«—”¢›’¢¨¢“—’˜”²µ¶­˜¤¤¢‹’‘¦›¥«›–¨¤¥œš¡©¦§£©¡’­Ÿ—£ž˜——ž°©”œ§¢Žj~iœ§x‰s~štze‡z¾¾Àºn’ƒq”†_rjZ^š‰ad‡Ž•k`•cmœvb”kš•”e^`cq›ŠirŒ}†•gj~rtx}}b[wthP\nƒ|{‹kXlz‚rIJo…pMtMEW\f`L[Xgc^O[muiqRODEM;HI<L?2,2A?8/5?C<9;@;=C>RVVWYZ[\\]`aaa`\UG5DFUEJOHFPIIH;8=51:.0;:.0-76=5&"/*2,%;8-7JR_I'S`V4)P^L(3=[O'?2>¨Ÿ¨¡Á£›´º¶£­¥®§¨µ±¬È¬°³¬µ£¾±²¦ £©£›š™¬§®¤¤µ©¥›—•¡›§­¨¾§©¦•”œ• š“˜¥©§‘ž˜œ°²¿¬›¦ž§¢‰“‘©š¨¤š›«Ÿ£™›£§­¢Ÿª¢š°›•¦ —•Ÿ—°¥˜¢¨™œ‘œ£¤™§£šœššš–gm}qw‘—”‘…Šµª†˜•ŽŠŒ——‡”•Šƒ’“‘‰‘“˜”˜—š ¢šœ”¡Ž‚z¥…lj||€t‰Šq‚xyvvŠ€{‰jstƒucw}vkp{m`c\pgMYYej_WZozmmfSOFS9OZNRO(+:JB635=@A9:C><ENSSTVWXYZ\]`bba_^^[TKCSGKNDGPLOI<:;389,2;820)6IRO8")+/2#4;*7FO[J&R^S10T^:+=8\K,<-@² ³¢¿¢¤±²· ª¥²§¥°µªÉ«­±¥µ¦À¨´ ž¤¥œ¤–– «¦¬££¶¬ ™–– —­©¥Àž«¤•’œ—ž˜“”¢Ÿž¢§“‘˜¨§²Ã¯š««ž––©žªœœ ¬˜¡šœ¢¥¯¦¡¤¨ž­˜—¦™š¡žžœ° ¢¦•˜“˜” ¢–£ž— Ž–”‹ŠŽ–­|•›‚’‚‹ª¨†˜–Š„ŽŸˆ{„†…™‡†‰•Ž›—˜ž¤–š“‘f¡³¯…‰„vzŠ|vyzogy€‰kuyˆrhszvƒˆ‚ktcyf`idbdfjYk{pij\SLPD_UF@??,4@F;45;>A;<?>>HNNOPSUVVXZ\_aca_^^]^]XVJKLBIOMRJ;<:786/2964.(&$-1./)+*7%+<(6CMMD/T]Q05M[17E4\G5<,@´ ¹¯¾¬«®²² ª¦±­¢¬³°Å°ª­£³®¼¤´œ ¦¢¡™—¨¦©¦¤¦³µž•”™™°¦®¾ «£‘žš™”‘•¡œ—©œ„ž©¬¢³È³Ÿª¤«––—š§¨›Ÿ¤«”žŸ ª®©¥£«¡­›Ÿ ¡™¥žœŸ¯£™Ÿ¨“˜˜‘¥™˜©žš—fƒ’|e~Ž™cylhkz‘¤«keš˜~g…Šeeihz¡ŽkhŒ—‘¢wkj‹˜£Ÿ™slnz„Œ‡zXe^…^lŠ‰€v\hsww‘€‡‚nx‚x€smyƒtwˆˆŽƒ{j…Y^ktd]sˆhj|qlc]QMWJdX@J4=F7?FD71<=?AC;;DGHHILNPRRTW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%/*+'6*$;'/AJ[J/7ZO6)EY/DO1YC;?.=¥Ÿº¼¹¯¬³±ª¥¨­®°¦®­°½±©¨¤­¯±Ÿ­—Ÿ£ž¡š™¦«œ¬£¦¨©²®ž•£¢¯¦¶¹¥®£Žš¡™“’› ™™¥–{¥¬¢¨³Ã·¤¢§¯žž•ž£ž£œ£©¨‘ž¡ž ª¯ª«£ªŸ¨›¦Ÿ¨¡¬–¡›¥°¤˜œª•¡žš“¥˜ž«™ž~¾ƒˆr´r„†­hx¹Ä¸q“¢£{¦˜™sª‚|ËÀÀ»q‹¢‡‚Ÿ|•˜‰žÀ½‚–žÂÁ{{’šÃÀ}k¥±oŒ€oÊz›w‘ƒŽwzyqz‡qx…Œ“ymv’bf_xd_d€b^thmdbXLVIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^__`_^^^^___]\SMPGUNA??=6468276*&%#)*&.+*)109*#>I[L*#BP/#F[3PY/UAB;/8–£¸Ãµ°¯À©¨”£¯©°¯­¦²µ¯ª¦¦¦±«Ÿ«˜š¢ œ›ª§¢«¢¥¨¥¤´£¢“¦­¬·³§¯¢’‘š¥’‘ ¡—œŸ‡§«¤«­¿À°¡©¯©—’Ÿ¢™¢£ª£’ ¡ž­®¨¬¦£¢§ ¥¥ž­©‘¤›©­ªœªœ¬¡–—¥–¡£˜œΔyz¤y•–›_®^Ž§¢ |§•›t«ƒ€¯^c©z§‡… t—’ˆ³c‚«†¡Ž³j„®t}–‡¸a‚­Y£Ínu{Ú{™p~ˆ“ve{ˆvvk}ˆn~…‘’~mŽ`qkpg`_xd[phjdf`RTRW^KOC5AHED8>6;@?A;=8@>??BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5578164('$!',&&/(&+360$7;SL+,-J0';\;L-!P@F4.1­ÂÀ¿µ´°¸˜ž‘¤ª¨­´«¦²¬­¬¤«§°ª §›™¥—œ¢¯Ÿ ž¨§£¥¡Ÿ°¬›ž•§®­±«¨¬ ”’›Ÿ¥“Ÿ¥—ž¨£ž®¤«°¨ÀƳ¨©±®–’œ¢— ©ªž”¡Ÿœ®¯§ª©›§§¤¡«’­´–¦¢«ªž£§¦¡° ’š§š¡›””‘— p…Œ—u„¨‡q±|q¬~¡ž¥žw«‚}­œr­~«‡†Ÿv˜’z|—~ªˆ¢Œ‘‹~«{‰“Ÿ€{­VœÄzo’Á}•mupŒmeve†oawnro‰Š‘ƒmdotup`gmd_oiinfcWS\aZRSC9II@D<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;91478452&# 1' 1' '45-&7=WJ-<'>1)3V@F!G:C1.+°ÔÆƲ´Ÿ£Ž££¡­¯¶®¨°§©ª¨®««§¢¤™¢•Ÿ¦«Ÿ¢¥ ¨¨¢Ÿ°¬—š–¨§¯¬¨§©ž—”š£¢’”¡­›¦£¯¬£¬µªºÍ±­§®¬–”œ¢˜Ÿ®¬œ– ™ž©±©©©›«©£¢¬›¯±¢¨¬®¦™¦«ªª±¢’—£¥›”’…¤j¤u‰z©tz²p‚¥‰™Œqˆ š‡¤``R¬„®ƒ›v®¦††Ÿz˜–†{f€£‰¤™†£}©~”‡®^|©U¢’z¢Ÿ€{ïŌs¯³³¹qb©¯ÂthŒ˜mš’omywwolfdeqpf{hc]W`jXXUMMQLCCAB;C@@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799674,&$" ('"+-"$.!3-&@DWH,G+66*1PKL# A9D4,'ÃÉÖÕÀ¡™«¨¡¯¢ž°µ°¯©¬£¨¦ªª«©¤¦ ›¤ž¥§¦£œ¬š¢«¡¤Ÿ¯¢š’ª¤µ°¯ ©›–”§£š¢¨Ÿ ¦œ±¦£§±¬¶È²µª¬ª•‘œœ¡™Ÿ¥³š¡”œŸ§««£®š¬©¢¡ª£³­¢ª³±¢›ª¨¯°¶£“–¤§˜›‘|ªlž„‡u«y|°o‚¤‹‰Ÿ–•Ÿ”Ò¸´¸É€²__”©ƒ¤ˆ‡ y˜•šxªÉt™£•§©’›Œ›‰šÆÆxe¡‚¥sŸŽ‚}¯^pµc±uK£†m§G‚“dž“|p—’pzt|{m[fjrqfj^bYcm\^YIMLKEDAB>A<B?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75685/)(%&%$&),4ENPPMFKJVF*L0/>-5OTQ;<F2,$§¤Áƹ­©³®¬¥¢œ²¹¬ª¡¦›¨¦ª¬©¦ ¦¥˜«£Ÿ®«¥ ¬šž¨¥¦µŸ¢—“¨ª¶²¬›¥ •¥­‘™œ§£ ª§®¢£§ª°´Â²³ª­¨“‰—œ¤š¡£®¦—¡•˜œ¥¦«š¯­¨¦ž¬£·¬¡²¹¯ž›¯§³´³¥”—§£™ŸŽ‚NxšŸz„£|‚¤„‡§Ÿœž“„¸{|y¹‚~Ìƶx›¡‘‹Ÿ}š–—Švž˜Š¤˜£¨~°…œ…ž„¬}™”a¥l£p…}—ƒr¬`¤sq€š`¼}RUuŽ‘£—|~’‘Štzs„~p[mnwrjoZd_hnbd]KMQTBIHFI:9K>B108866877-*5==?BDGILNPTVXYZ[\__^]__\ZZZYUSOH@772.,*.+*'&?QTVWWWYXXWUOUF<E3:P[T6?H,- ‹‡™©¬¤«¹«¯ œ¡¬³³¦Ÿ •¥®­®ª§¦¦š£§¡²®¢¨¦² ™©¤”¢µ¢£•—¡©´¹¤›££“¡²™žœ§¦¡¢¯®¤¨¢µ²Ã±­ª­ª‘‡œ¦œ£¤œ¥—ž™™™¥¤¨š®¡®¥¦—°¥¼­¡··­žžµ²¹±³§˜¯¡£ž†ÑµÃ·y‡Ž…‘“€¦x”¢wŒ ’„¥Šqª†„´nrj™£›•ŠŸ|˜™†‡s¯‚¥›¢¦‹“‰”›mp²\¥s“zœl™{™}n©a¢qqŸbs²¸hx“¦˜~ŒŒ“Šw|ymixixsnt]ddnmfh`JZXX<HG@U3@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^``][ZZXURRQF:2230/++(@QRTUTSTVWWXXWUVVTQOQ[U%!2AH$)%“sŠ­¿¿»ºµž—¨¤­µ¡£™•£©§®ª«™¥¢Ÿ¥  µ¦¢¨§°£”«£Ž¤­£ššª´´¤¥©’”—®  ž§¤œ§œµš ª£¶«Ã°©«©¢Œ„Žœ¡ ¦¢•š›œ™š™¦¤¦˜«§­¢¥›­§¾¬•¾°­Ÿ£°³º¬´§›¨±¤§˜z¨}|°wŠ¤¥ˆœm²o¡‡­|¡ƒ¨•˜€¬ˆ…®…Ÿ”© ¡–†Ÿ€™•€{’~«€š–Šªx ‰“’€y¯]£|¦§d€|—tk¯]¥kq…™]`[Œ n•‘¦™ƒ”–‹zz‚–klb}tmz`geqohghCY`[=KT2U8BBC7$$3+''3, /6674359@CFIKMNQSSSVZ]_a`aaa^][ZWSPONI7052.*,ATVVVUTUUUUTTUTSTVVWXVUUQHFIJ#((½’š„©Æ·Á´Ÿ›­Ÿ®¸¥¤Ž›¤£ ¯¯ªŸ¤Ÿ­˜ž¹ ¢ª ¯©™­¡ª¨¤–‰›®°¬¦Ÿ§›­˜˜¬¢¡¦¢š¥­˜Ÿ¨¦¶©À¯¥ª¤Ÿ‹€›š ¦ž’•šš”šš¥££™¨««£¤Ÿ©¨¾¤—쪢¡¬²º«®§ ³¯©ª˜v¯~‹œ…‡}º­Š˜e°Œe•­}¡ƒ¦•š¬Š„°…¥™¤¡¡… [lj³`­{{‚€±lgn™—Œˆ°[}´[¤ƒkÈ¢eŸ€{¼YvµZ²}R¯€z¬X€¡m˜¨šŠ—––{xœ}ds}bƒwt€|ajfqnfeeOUc[BT^>I(>9=4!",%2. *1/045799<ACFHJLNPPRTWZ^_``ab^_\[XUPNJGC553./@UZXWXWXXWWXWVWWWWXWWXYZZ[\XWWGB;ҟ³²·½»´Á³£œ­¦¥¶¨¡‹š Ÿ³³©ž£ ´˜ ³¨ª«¯­«›•¯©¢Žˆ›Ž¯¬©§¢§™®“™¨š¢ž¥Ÿ™££¥™ž£©²¨¼¯¥¨žŽ|‹š•¡ ™’š›’™—¨ž ˜¨­§¥¥£¥©»Ÿ Æ§¥©¡«´¶­®§Ÿ¼­­¬•©’£¯›€†¤—˜€¸ÃºƒŽ“…§—œ‚¬Š‚¯ˆ¦›š¥ª~սªb£¿½}~£‚ƒ×º¸µ…”“ƒž½¾„j£o«„mz²°Çƒj«°½­xw¢¾»t€–Ž¦œš‘–œyšyc}zdŒfy‚{`kekjbPb[Sj\@TaBN)=:4/$%2 $(0496677;>ACFGJKMNNQTW]a\__a^`[\YTQMIC?<A?5=SYXXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ¼•³´±¿¹²½³¢®¦¥³¦‹˜¥¾©·±¨¡¿¦¦²›ž±œ¹¨ž­®¥¦•”°¬—Œƒ›‘®¦£¬¡¤œª¡˜‹£’§ž¨œš¡©¢™ž «­©¹®¨£›—“{‡™‘¦›“‘˜˜˜“©™Ÿ˜©¨ ª¦¡£«»ž©Å£ ¯£«³µ«°ª »¨¯¯šsuª¤·†e‰Ÿpg­Šmow¤™Ÿu®™•p‹q•§£›˜®¤rmmmeŠxom‚™q€yiqig‰–•˜qhi„†gp†d]‰cjoY]g~w¦`bqŽ’ofd€’Ž¢˜—˜•ž|‡Ž”uf†whjy~ydlcflbKdXJkY:QeER'K:+# #,)-2.5:457:<?ABDEHKLMOQSV\WZ\``a]][TPLHD=:AB7MXZZYYZYXXYXWWVWY]^^]\\\]^]^][[UW^¨•­³ªº¹²³«©¢®ž£²©˜’½±ÃȾ¶ªžÀ«¬£ §¬Ÿº£¤­¬¬¦Ž–®©Œ…•—­ž¦ª¢Ÿ££ ‘Œ¤’§™©™–£ª –œ¥¥§¯º«¬š›’’{„–¥—‘‘˜”˜•§”ž—¨¢š°¦ž¢¬ºŸ°Á§¤³¦¬±²«­«§¹¤®¸–Š¡¨¥¶‰–¢—‡©š”“ª³™›£« ²–¢¡ ¢œ ¤¡•«¦Œ’’Œ‡’œœ”š“˜•†¤™—•‹“’Š†„~gŠt‚vt‡Œq§l{•‘”“” •˜– ‚‡“ŒphvpŠwv|zjlddocU`X@i[HcaOZ+F=+&!740.!%2(*699469;>?ABDFJKKMPPQWTVY^_ac]^UQJED>9=@ASX[\YWXXXXXYXXZ[[\^__`^^^__```_YY`¥–©ª¥µ·®®¢°¤­Ÿ µ±Ž«Å¼Ä»¸ª¢¥›¥°©£¶§©´¦§‘˜¬¢‹ˆ‰œ§–¬¤¡™§žž“•£—¨š©™”¦¡£š§™¡µº¨«™š|”‹¡”Š•‘•“—¥ž™¨Ÿœ¶£§¬·§¯Á®£·¦¯¯°­©©³¹¡¯½™’¦£¦¶¢’¦ž©Ÿ’Ÿ£¬¯š¡£±¨¯—¤ œ£©žžœ—«œ’™¡›“–ª™™™–•ž‘‰ •”…’ŒŒ”Š€~fŒ†u†vyˆƒsœj†‘””‘Š}Œ–’’˜“¡“– ƒ‡—†yq•ry‰q{jnd_pi`[`YmcP`dP[:GGD=2==7.*&+)&&406658:==?AACHJGJKLMSSSUZ``i`eVPJACB;9EMV[^^[Z\[[[\]]__]^_`aacaaa`bbbdb\[c—•¤¨£°³¬®£©§­ ¨µª¤³»¯¬¬¢£šz¢±¤¥°¨–›¸¦¢”™ªœŽ†Š‰œ£®Ÿ£–¨ ¡’—˜›®‹«–¨š¨Œ˜¨ž¹¶¤¥™›‰y“Œš“Š•‘”‘–¢Œž¨žŸ¸¤„¯µ¢°¯t¤¾£² xzŸ©²»•v­¤ŸŠ€ª~d\bvŸŽ¤ž„—~n“³œ£§®«¢ežŸ“sy™—p€˜¨—l¢§‰eœ¥œ‘—˜–‹‘›‘†š•‚’‡ŽŽ’‰…wk‡v†q|†€€aiˆ‹•“‹[v•‘ghŽr{¥˜˜dy˜†w—iƒŠ‚nykpe`vokkh[febboS[>NNNRG=@TB91/&4:316678<;>@ABFHBFFIKLSTUY\_hfgWQJ<DG;8UR[`ab`^`_`aa_\]___aabcdabaaedchd^]f›–¦£¡°±¬«©¥¨­£§­¤’–«µ¯±¦šª¦«—sŒœ¯Ÿ¨ª¦”–¸  œ£‘ˆˆ›ž«š£•§¢žŽ—‘ž…u®ˆ¦š§‘–£ˆ›º´¨ ™˜‹‰uw“–“Š”‘”Œ“ ŽšŸ¦™œ²–€Œœµ³Œ’¼§¡~§¢z¢®·ŽŽ¦ž„‹…±©¯Œ‰–£šy‹¬†œ¢§©¨‡•†˜v¥›z‡›—¦‚{œ±zŠ… —™”˜–––„™™cy‡„’Šƒmp‡y€q€…†t†„–’x–h“t št}™ƒ œ†˜~‘‰ƒ˜jŒ…kx{qpgdwnilk[ekjes[^ITLQ@E5.YTU6)!09=>643568;:=>>@DH?IEJKGRXZY[aahfYQH9EL;>bV^bded`aa`bb_]`aabbbcfgcba`edcgcaahœ˜£Ÿ¦®®«¨¬ ¨°¦§©¥™”®Æ½°¡–¦¨µžƒœ«œ¦¡Ÿ¾ž™Ÿš }…Ž™—ˆ«¢– ¡’“‰†€‘¨Ž‡¢œ£“–†Ÿ¹²§ž›’Ž…pu‰•Š”›‹‘Ÿ’–Ÿ¤–ž¬ˆŸ´‰´š­ŠÊ‡ª®ˆ·…°ƒ±®ƒ©¦˜|¨r{w›Ž¦–h•¤y´‹Ÿž¦¨’™Â«ˆ˜¡qž€™¤}—…•±€¡|¡” ˜–€Ž“›Š—‘‹|…“†•“‰ƒms‘…zr†„|„t…‚—Åf€©‡£kžƒ¡™‚™€‹Œƒ‰˜pŽ’…hwt{vghupggl^colglXgG]QL2E46M`c7&3<DGD:64658;8>==>BL?NIJLCPZ]\Wb^jl\QE=KM@JdY]cfhgbbbbdc`_babcccdiicbbbecafcbbi•—¢Ÿ°¨©¨¥« ¤¹°ª«¦š” £¤ª£–¤©¶£¯ §œ¥ž‰“¼™“ ‘y„––‘‡«™››š¢…Œw›œ ‘ˆž¤›•˜—†¢¸­¥šœŒŒbm‹“Œ˜‹‘Ÿ“Ÿ¡™¡¨~¡§‡­ –®ž‘† «¯†¤ªšŒš~¢v€™“j«uM«x‡‘›¨§€ª«}ƒ¡{z§iž’kg—†—¶‰ž}n`dYƒ–~Œ{dhŠr™}y•l]{—m_Sp„\_lyƒ`Ye‚}„˜q§ªkƒ£nr¥pŸƒžieŸl[m‰{eY_ƒbWPovemtrjjo^jomliXiO]WE9A4GC^k4,ICQMN=84859;6@;;>BO>QRLMBJ\]_W^_cv`MD:MOMTb\\ffiibbdbddbab`cdcabikdbddgdbgeach˜– ¹¡ª£¦¬’¡¶¼«®¢™— ¡¥­­ œ­µ¢¨’ ŸŸ¦›™Ž˜´™ŠžŒ•‹u”‘Š¦–•˜žŸ’…†¬¤‡œ‘Š˜¨—™š‘‡¥°¦¢•šˆ‰€inˆ‡‹ŽŽŠ‹’‹’¢Œ“ž œ¢¥“£¡” wœ–§ƒ¡§†©­…¥yŠ}„š}¢pr“‡•zŒym‡œŒ™›¨š‡|‚¢sv¦fž~v¤_˜z}’s¢n˜·´ºs’‡µ¨dÆ¸{p•·‹q€›¤cs¬«`}j³~n}‡ƒŽ‚‹—q€£ls¤sžƒ¤_™³•p|—ž´ts[ž²ƒjbosuqhoXklrsf\i^bKD=D5QAYq3=SG_JR=<395::6D;;@IP?TMNQ@E_^[ZW``|dHC8LWUVbaZffkkbbeadc`ab`dd_`cknccddhdbgfchh”–•£¹™«œ“ ¤¸µ®­ ›¢œ££¥®œ›±­¬“— ˜ ¤™š“ž«›‹ˆ‘x‹…p€–Š “”—}‰Ž¨ ‡˜Š‘¢“›šŒ‹¨¨¤ž–‡„~k{‡}ƒ‹‘‰” ‚–  Ÿ‹‰wœ˜¢Œ r¢‹ˆ©ˆœ¦–¨«®Œ}z ™z£“x€s–‡Œœ}– ‡›Ž™›¦†¢d¡|ˆ–›lžh›nš™{€Š§}rhs©‚œ‚sªg”š]›…v„hªj€¸f\¨pœa•Œ^§vu‰Šžhšu‡“’˜ŽŸnšl§™\¨~w»k~ª[Ž„]´g\nqywki[qjxyb_fXbAPEN7VBRn4KZZ_NZC@151;;7H?:CGT?YRY]>Db^V`Qac}iEB9N[]XdfXfgnmbbe_aa__``ec^bdoq_deekecihgki•œ‰ª¶›¨‰c”›¬º²°¬¦œœ¨Ÿž®›°¨«—¢™¡Ÿ˜–– £™†‰Œjˆ€q{—ˆ‹––„‘”˜zŠ„–¤Š”…‹‘œ›‰¨£ ™‹‘Š€€i†y—Œ{ˆŽˆ–š“¢Ÿ ¢“˜rhŸŠŸŒp’Œ©ˆ™Ÿ£¨ ¨}°­£¢¸—w£³¢£ˆ”xz«š¢Ž›—‰—q¡|…¯µ}kš‘¡x~˜´££«¨„™|š|œ™~sªZ]o{–‹xžbL~zz…cy—BMŸY¢jq|Žm‰„™u›y‡‰±³›“§u€mq|”o™rj¤]•vHec`sp}}ne`lhv|cdaQ^V]TV@YEQgDSW[bX^ID=B8?B:IE8LDWAVQ[VDFb\Z`K`m~qEC<U_bZejVghmobff^aa\]^ahb_edvl^egfkdflihki“€±®™„S_ §³¹³³©š¢Œœ«œœ©“¡«¤¡¨žœš™•˜¡–‡†‰w…ny•…š‹|‘“–ˆr€‰“¡œs‘ˆ˜”Ÿš„Ž¨œš”Š‹Š|ƒl……q¡Œx…ˆˆ’™•|’¤¡Ÿ£ˆ®†}µ„Žž{¥–z©‚–Š¡}§hvm~™t¡sq|…˜o“‚®}¤ƒ¦žš£o^¨gu£co¥aœÓ|z™xrsc£…~¢r¢Žuk³‹`‚˜‰sª²¨¼wƒm~¾¦©´^œn}q—os¢r]£gt¦ah¦m›Ô™|ƒ›owy—k›zw—sm©¤g`eypƒkgfdmuxg`bS[eQQbIWIT_WS[ej\dPECKMJKBJE8P?PMWSXORR`feiRcwywIFEc]dZhiTihjocjg`c`\]]_hbahe|d^dgdkdjmghlh—›±«T\K~©¯±´°³£œ˜…˜¨  £¤¨ ˜©‰™—˜“™’’ ˜Ž‡…{p}„h}‚”šw‘Ž‰o†“’l—”}ˆ‘£•ƒŽª™”’Š…‰yƒv‡€n‚Ÿ†w€“†ˆ™¢—y“¢¤šŸ‰³¡¢¶‹z¬§¤®¥p©š…œ’|¤€¢™†˜rž„¢­®‰—‹Œ¤–ƒ®¢”vµ¶µÉ¡s”ŠŸ`—©my•†Ÿšu¡‡w ~‘–Š€oLf£’pš‡r¤{ytaƒ‚l~ kqd`œrt—i{i³µ´Æ¦s˜~{j››«uƒšltw—išzu˜rPD}³^jvkx‡fjgbttqnV^TYhORhIULYRU]hknVgWMJAJMKHJNAQJPdcimetrs~y{nu‰{{TPOl^h[kiRjhilglfce_\]\^ibdhk{_]dhcjfomeile¡œ‰°§„f?”¡²«¯¯µ¢£€—©¢¢¥Œ¥§œ¥‚™—–—›’Žˆ‚yjy†eƒŒ~– yuˆŒi„…’ƒŒ…zŒŠ”¥’ƒ—¨—ŒŠ‰z€}‹xp¡†y•‡‰– –”¥¨œ––„gnxœl¢d|q¥wœ˜pg§—Œ{¥zŸ–ƒ—ržv‰”–¹nŠ¢b}™¢•ˆmri«ju mn¦`›i‹h–‡š•u¢€}š`‹…Œuoˆbh ež~išuocfˆ‚nr¢Z_[c¡n]‰Œo{srd¥mw¢dg§h˜s‹˜n¡oSˆo _e§T‹]T˜mmskqmphkxskoRXWVfYSmIXO]HXihsjYkVQREV\LXRaThj^wuz|p||rƒ{rv€„v^QrbgbpgPjhhklngdg_]^]`kcjivu]\cicjjslfkmcœ¥™¦zetm‹§®¤©°±¦Ÿ‹€—«œž¥Œ¢¡š¢¢€•˜“šŠ—Ž‹{‡q€ˆh‹‹{—šstŠ}{d‚‡•ŠŠ•™‚|ˆ…–¦¡«…‰‚Š}€€sh¦„}†”ˆ˜ Žˆ’ª§‰¦x–œ~¥‰–Œ²˜žƒ¯—Ÿ¥x–ˆz©t¥„šn¤¢Œ’„Œƒ¼n|¥¯‚††‡“–œŸ|¥zq¨• –gž~o«c–Š•’w¨l©¢‰u‡‚w«‘¦ˆk‘°kv³Œ©kŠ†nmŸž’•a«‹ªv€Œ¦ŸwŸ}…¥• iš‡v¬gž­Œ·sw¾¤“Yƒ¦«aurso{tqbj~nhmSV[Uaa\kM\R]I]mmw`[qY[`Zgsenoqcqt`wz~yryƒs„€{{Œ‚€vbxdcmsdRlgholrifia_^\bkbmlzo\\bibljwmglnb•¦ª€ž¤–©ª¨§®£™‰‚—«šž¤‰š¥©œ„ŒšŽ†œ‘…’‹Œt†zˆ„oŒ„}—“tt†r’‚m‹’‡†”|{…—¤¥¥Ž‰„”u‚‡’ol‹©ƒ‹”Ž‰œŸ‰“«£ €u”—ˆ~y”®£›q†yŒ„{r¦Œq}}z—–›„Žx{~~ˆ”•“Šv˜Ÿ ƒz}‰lŒ…[yxqyphn~’‰qt‚”“q…„‚e_‹wus”uoynn‡m„†^wixf‚†Ž©›~t|—j‰ˆp€v|…vmlgŒsy{˜x„[kXyhnwrqowxo]l†nigVZ`W\ekcUaU_Q_pxylkvejkjv|qrtsaoubs{xuy‚u€€€x‹…ƒ}{mldxn^Wnghukxjijd\`ZcjelpunZ[bkdllynhloaŽ”¹©§‹¡¢š¦¤™¤œ«¢ „„—¬’ ‰š¦š¨˜‚›Š~–“‡Ž‰ˆr‚|}~Ž„z—trƒp•…{}“‹††…x~†˜¢Œ{¦ ‹…„•‚†Ž—wr…ª†Ž’œˆžžˆŒ›¨  «ƒ‰Ž”š~~‰–­¨“¦xp‘ƒ{’o~¨…p}•qkp|Ÿ‹’ŽŒhm]ƒ‹Œ››žŽs•‹ˆqtk‚vs€Yrn‡}~Œj]jd{…ƒˆ€_ix{›{‚‹‚v†‚hy‹‡kaqrƒw_sŒ‚‰§•†fŒƒnw‹„p…yoegdzƒz–[\jgnv[{xwtmsr‚f\mŠklbYY^ZXlq[_`Z^]ft~{uotckkj{|r{xtdmtgl{~vz|{zz~o†Š„{}s~ysiT\qiluougkhd]aXkhkjqrmW[enlgszohjm`ŒŒª±¢£¡šžž˜ž™¨¢¡}‚˜­Ÿ”‡›¢¥•{—„|’˜ˆˆ††Šr|€‹v…‹„•Šqo€r˜†„~’„ƒ†Šz€ƒ‹šž‚¦ †xŽ—ˆ•‹‹—„ƒz­‚‘˜™”Šž‡ˆ¡« ¢¢£‹ˆ“›œ£™–ª¡§¦ ’›ˆ—Ž|xŽŽ„§~’‘’“œ±¦›”ž²“˜„¥ŒŒ•›Ÿ‰›‚‰‘Šk|vwe‚…Š|‰„‡‹ˆˆ€…„w|yuš¡ˆ†ŠŸ‹…”~Œ€vpt†„xˆ‡‹¦„…ˆƒŒ|‡Šˆvl‚„|y™jrhatŠp}zwvowt]^o†hn_^Z\]ShqUc[\alhu||sopdkji{mxqioplf€{r‚€x}€„zmƒŒ†|zx|}zƒyNdvksmpzdkebb`[tfpfrrmU]ltmhyzqgikeˆºŸ–¢¡˜•™˜”™¤ ž{™«Žž…ŸœŠž–|x”‚{Ž™‰†„„†mx€€r‡~ˆ“„ml~z—†„ƒ€†„†|‡ƒšœ’†©žƒrŠ…’‘‹‘}{ª„’˜•œ—††›§ ¢š†ƒ‘š™™š¦ ¦–‘Šw|‡Ž„¥{|Ž‘†˜©¡“œªŽ‘€žŒ‰“šž‚Ž—~†‚ox…qt`~‚†u‹—€ƒ‚†„~…ƒ”nyut’¢‹Œ…š„„t€Š||rr{ˆ„{yŒŽ„“§†„„‹ŠŠw…‡‰‹|ok~€{mhlmg^yh|{vtuu{w\`p}nu`cZ]^QfmSeZ]ajivy~qkldkjg€ls€lltoxn„yn‡€v‚€}„vr‚ˆ~{{|{‚Š`i{juhi‚djc`i\duhobunlTcqyepzzseimm‹ŠŸ·š¡£Ÿ’‘–—‹šŸŸž{x¦›Š†¤”‹˜™xz…{‰‘ƒŒ‚‚m|~xs€…}Š|kh}—ˆˆŽ|~†„‡|€š›‘ˆ¦œp‹Š‹’‡ ¡Š…Œ|¨‘ˆ’—“–“xŒ£¡¡ž–š€š˜“Œ›£¡¤š—‘›~Ž…y€ƒ‡ €}ŒŒ|—¤  ’™¦›‘‰’—›~’’~†ut‚pv`}†rŠ•|ˆ‹rŒ‚…†ŽhwqxŒ˜’—~ˆŠs‚‡||py{Œ…z{‘ƒ–¦“‹†‘|†‡‡…u‚ƒˆ‡zer{~xzpljf^}sh|uus|r€j^`tvpxdcY_^RkhTdY_agjvxqfkclhe€jm~hnqk}w†zkŒs}tv‚†~|{}jrƒnsia‡hlb_qVtomn`xhmWjtvcu{{rbjny‰Ÿ²’¥¥œŽ˜†œ ›œ|v¤ —Œ¢Šˆš–x{†‡~ƒ‰~ˆ‚€qztu‚…~‰xgc}†—Š‚Šx}€Œƒy–€•—•Œ–Ÿš}o‹‘“†¦›‡Œ‰„¦•…’‹–—“’v‘ž¡¡˜”—z~Ž˜—Ž–›¤™“”œz…ƒx„—~‰Œs—¢ž¡’˜Ž¢Œ‹ƒ–˜ƒ’–™~˜|ˆvq}nzd|Š…p†“‚l‡‚‰„euo|‡’—}“x‹‰|€‡|{q~xŠ†y…‘Š‹˜¢•„w‰…ƒ‚v{‰†v_xw}s}wflda~ijwstt}q|bcasnusmaZ`^[kdRbW`ahkux†pbjcmeh|ƒlhthloh|‚ym†q€ƒƒs|ƒŒ~z‚ƒ~|mvˆttmeŠljacuV„iqn`yglbjvpfy|zq`rl†…œ­—¦¨ž—‡†Ÿ“—˜}wªœŠ˜y—œ‹‹˜y{€‹}|ƒ{€‚€xtxzs}€ƒˆ‹€d^}‹•‡…‡t}}‰}—„–“–Œ£ —~r‡z“‘Š§ŒŽŠ“ ‘ƒ‘”—‘‹˜ š’‘t’”‰ž§˜—•–tŽŠl†˜™z‡ˆ‰o—š£“•ŠŸŒ†’œ’’•†™ˆ|‰‰zqykul{}‹~n…’‚”wo‚ƒ}~Šdrj{€–—„t‰ƒy‡~ux€}‡}ƒ…”¤x…‚t‰‡}€su€‡ƒn`{uzq|oancd{bnovrwwstav_oluno\[_]^j^O]Wcahmsz‰k_jejchw‡mflhilh€|zwo‡sƒ„}s†‰z‚}z„}}ŽrzŠxxnl‡kh_iqc‡hqoewhnlayhk}{xpawm‹™šª ¤¨ŠŠ‘†ŠžŠ•—}w®˜Œ–}ž“‘–“ˆw}{Š||€vw€ptszo…|€Š~|`\~‘†ƒ„sz†z‘‡‘‘›’¤›”}€{Š’¤‰Š˜šŒ†‘˜“–Ž‰‰Œ““Œnƒ‘‰ž™¢¡—–‰–‘oˆš„g†™Ž“z‰…Šp•š”¡’’ˆ‹™Œ‚ž|’’‹™Ž{Š„‡tsukqnu{‹tn…Ž’qt€{ˆ|dqly}™”}„ˆt‹tˆyo€~‡|…Œ‰…•¨{ˆ}~‹…w~po€…ƒchxtuo{b^p`jt^qjzxxlrpex]mlsmsXZ^_ajZPWWecgqq‡f]ihgbgqŽodigejh€zwtnŽ…t‚{u‚ˆ…w…|x„…z€‰w‹{zryƒjk_pht€kromqgole|cn€yvqlwwŠ¢˜¢¨¡¦›‡ŒŠœ†“œtª”’† Œ–“t{v…wxrs{…kroymŠv€€†nq[Y~‘ˆ€vu€ †Š‘œ— “—w‰~€ŒˆžŠ†’˜–…‰•™—Œ‹ŽŠŽƒmˆŠ‘‰œ–¡›˜•…—ˆj…£ƒg†Š‘~‹ƒ‹w“˜‘ž‘ˆ‰•~—|‘š’|Š‚nvplmnp{…isƒŽ—Špwt‚‰‚xfsov™Ž|‰„z”‘zwˆtp‰{†{‹†„‰œ£ˆ|„w‚‹€xxnj€‚]rsqpoxZ^p`pj^oi|ypmmjlv`pojrmYXaaanXQSZfgcup„‚b]jmdbfk’m`ff_hjuqrp‹€u‚€xu€‹€x…w‡†wƒ…{†Œ{vŠjqc|b†|oqltjholvw_qy{tut€‚~¤•š­Ÿ§–…Œƒ—”ƒŸuŠŸ”’†Š›Œ•‹zrxtpr„squˆlolumˆvƒ}mnUQ«”‡‚x€vr‚y ‘’’—›‘šx‘z‚Œ’¤š“Ž‰•™’„‡—™Œ”Œ‰ˆž…Š|rŠ…‰ŽˆœšŸ›–””i†ˆg†¡ˆ’„‘ƒ‰qƒ‘—šŒ‹w{’zŽ‹Œ‘–Œ|ˆ|€kvjnkklz~ay~Ž•vz€wƒ|ygtlt‡•‹ˆ†{”qz„pwŒzŠ{‰~ƒŒ‘Ÿ…}|x‚Œ}vpik‚y_womkqsV^obqa_lnypgpffsthqkawe]Vfa`rSPN\fe]xpˆ|_\hrbbef’i_hd[gp~pkpsŠ}v|…€tuŒy{†xˆƒs†…~ŒŒƒ{y•wfrj‚`ˆ~ookz`jntt_t}y†xts…|x ™°œ¥‚Šƒšˆ‹žŠ™“Ž„ˆ˜ŽŽ„vtvs€po…spqƒokivm‚n}|mtsRN‚ßȒ֓|pt‚uƒŸ‚“w”˜š˜{“r…Ÿ¡““‰“›”†~–•ˆˆ‘ˆœ€ŽxzŒ~ˆŒ‰œ››•“yvh‰’‡lˆ£…’‡—ƒ†cŒ‘˜Ž•‰–ŒŠ‹q{”‰zˆŠ’‘‰y…{~l{erojkyy[€y€z}~†Žzyhsks‹Š‚……}•Œl~o€ŒŒ‡}„y–ššŠ|wxƒysmfpƒljtohismS^odpY`kqwfkjbfxrppc_x``Vk_]vPNK`fc]yq‰t]\ev`aeed`faXissnkqvŒ|ty†‚uv~‹s†{‰~r‰‡Šˆ|~˜vesm{e‡~opl€Zlnyysavz{vrwŠwyŸ‹›®› ‚…wˆ•~|‰œ‡…ŸŽ…Œ—„“Ž‡uwpyqn„omn~rddxp|mz}jhlc¤šÁÜ®ï¡skuƒu„¢…‘n•”Ÿ“›‘p…‹£—‰•Š–ƒ€•…‰€’ŠŠ—‡{u‰x†„››˜™vŠvn†‰‹}Š£„‘‰……^‹”—ŠŽˆŽ‹‹„‰l|–}ˆ…‰†v…}}k}dwujmxsWˆz‘†…z~€…‹~xesjŠŽŠƒ‚Œ–…k‚unˆ‘‚‘…‚y–“™utxˆusqguy‚btmobhugR`qglU_nty`rc_h}prn[crabWnY\wMMLdfa^vs‰m\\dy^`df…`cb^XjrknkrvŒ}tw„xw{‰qƒ„}~ˆ{t‹‰ˆ•†Œ~~˜shupxl‹zntpXqzvyqewy†Œiv€‰rœ‡˜§œ£’„|pŒ”xy‹„…¡Ž{•™ˆ„{rwpsjokil|t^`xv{pu{g`e|ëÚµÉÃ܈sls€vŠšˆi—Žœ”’ˆp…ˆ Ž…Š•Š˜”|“ˆƒ‰{‘‹†‚vxƒƒr‡‚’›–”˜†Œv‡p…‚‰‡™¢ƒ”Œžƒ‰aƒ•†‰†‰‡€‡i}”}ƒ„‰Ž‚q†~qwhuriswkZŒ}’…|ƒ€„Š‚uatlˆ‹‚~’‘}n‚ly††“„}|’“—‰orz†ulpkrx€_sin\jv`RdrifS_pvt`o`]h‚qsjWghciXmW[uLJLeg_brs…i[\ey^^dg{`d_\YkneojswŠ~ss~zvzˆs…‚|†vwŠ†˜‚Œ{“vlvuxx“tnxz}Xy…q€ogyw’‚dv†…qŠ–…™¡›¢Š†so’‹rwŽœ}Ššˆ‰{Ÿƒ™xqsnodr~hflww[_y{zqqiagaÕ¶Ž¦xnqw{p’Œ‡j˜ˆ›‘‹…{h‡‹™†’‘†‡˜|‰Ž|Œ~Š…zu{‚zp†€•™Ž“”ˆuƒ†vƒ€‹“Ÿ†•Ÿ~ˆa“‡„ˆ„‰ƒg}~‚‹~m‚|‚tkmvtsvukcŽ…~|„„‡~p_sq…|‚|’‰zqƒfz„Š‡Œƒ|…}”‘“„npzŒumnjlz}bhjiXluZRirjbQbrxlae]Zjƒmsb\g_dl_nTZoNHOge\gnqkZ[cs`\clwde]\Zllbmjsv‡qo||tx†x…‚}‡uy‰’•|ˆ†v‰owy{„“pm|w^ƒtmi{s”sgrˆ}r’‘ƒšŸ› †‡vv”~mv“—}‡ƒŠš|‹šv}vqoljat|gbiuzZ_w|zmq~echhW^qr–¼Ãƒuq”ˆ~r–‹†œ“Œ‡rjˆ–€{”Œ„›Œ|‹†}|‰Œ”ˆu‰…vw}qu†ž”†•ƒ‚rˆu„|‰˜˜‡“Ž€ˆf}“‚…ƒ‰‰r}g~‹{x~‡‹Ž|i€|ƒveoxxrvslj…ŠŠx€„ƒk^rxz~Š…{‚€~r€iyƒ‡‹†„y„|€—Œ}nm{‰}wtnhg|vc\pbWorSSnsiaNftxe`]\Xn€osYeb]jm`pOYkQDSgaZknm{nY[^mcZcowdf\]`ljcljsv‚ƒqn~{tuƒ{ƒ‚|…v~‰–xƒŠtˆrxy~oo|qiyz~mm|v•kjw„tl”…ž˜ ™…ˆn}Œvjx˜Ž~Š‚•—ŠyŽ–ozspljd`t{h_eqzZ`r}ygqzaee±²wJbZ¤ÙЖq{Šw}”‹„™‘‹…nk…’’zy’†€„˜Š|‡xx‰Š„–€oŒˆqt}ziy…ƒ¥„“ƒo~ƒv„y…›˜“‹’”…‡p{’‚}‚ƒ‰ƒnxh€…xr‚Š†{e}~„ucprhxpou˜…‚Š{vx€„yk\q}rˆ…‰}†‰zˆrnq„‡Ž„…s„x€™„xno„vzehj}p_YwZXqmNWrsg`Klvt`][[Yt}roWg]fjq_nNWhQ?Yg_[pjgxpZZYkeYcpy_h\^emhfliqw‡ol}€uo‚{~‚v…‰—Šq‚q{†|yyƒ“Œujzlo~t}or|{”onxf’Š‚¡™‘‚†g‡ƒogz•‰~…™Š|Œixrklf_aoxm_box\dk‚zaqv_eeÔ꾊2:>‹Ž€qy…‡Žvƒ–Œ~’Œml…Œv}…‚•‰|ƒxnv†„ƒ—woˆ…ku{tfy‚ƒ§Œƒ‹„}ntvƒy†œŒ‘’Œ‹†~{’†w„ƒl€ri~xm|{Šƒwby„qdqh~mtqu›‹€…~ru}€rp[m~txŠƒ‹{‡€|ˆxzqlˆƒ„‹ry—‹‹tnkv€uu\ihwpYW|SZpeLZrre[Jpwn\ZZY]t~uhYb[gfnciLWfQ=^f\]ue_tpZYTodYdqyZh^_gmgjlipw}Žli‚„~yn€|}‚zu‚“…p€‹nx~€z{ˆ’‰h{}jt{r†{sw}Œyx„}|kŒŒƒ›–Œ€lŽ~kh~ŽŒ{~ƒ”‚}Šˆkuqghc[bgrn`aksahp‰yast^cd› n\5Y¯µti€ˆ|’†v…–…sŽŠ‰wpm…ƒ‡uy‰x‰}“ˆzsgvˆ~~˜oq†~hvymeyˆ„¥‡€‡‰~n~v€|Œ™‡‚“˜ˆ‹„‰|ˆp{}„{h~mk€{zizv‡r`w~qdrgu‚mt{…”‘|nwy|t~mXovtŒ‚†wˆv‚‰zxsn‰…r~}~“‰‰znnjm‚un]gfsqQ[{N\p\O[rpdVKsxiWYYZaq€t`]]`gdhifNYhM@ad[`va]umXWStaZdorWj^ahkgmlipw|’kh„‰||p~~{€‚zw€€Š‹ƒq{‡oqwƒ{‰ƒj~{nwyvŠw}x€‚‡ƒ~~zm…Œˆ˜£„ƒ{u‹ykl„ˆ‘x}{‘€€~Šƒprpcf^Yg_op``gpfjoŠtato[adjv{¾œ¦£È¸q…ƒs“|x†“‚s‘Œ‡rrp„{ƒtu‡tˆw”ˆyyqcw†z€“ir„vfwvcj|ƒˆž‚ŽŽ}r~s„y€‘‚x–”ˆ‚ˆ{ˆ‰kxy~ugzhkysizv€‚}h`w‡}jkth{ivŒ”~z~~p{v{t~bVw}rsŠ„‚|ƒq†Šwxppƒ‚}y~}vŽ†ƒviqil‡‚rp]hcsnJeuL^nUTYsnbQOsx`RXX]bp‚s[a]hedcjdQZpIDda[cp^]whUWUw][enhVk^ajgeoohpvz’niˆŒy}r{~x|v}„ˆ†ƒpvƒrnw‚‚~‰‹“p€{wyzŒtƒx‚„z€uo~‰‹šžˆ}…zw†{gt…Œz{‰†„v€gon_d\XeYmr```plkh‰n`siY^dm€w©Ú©Ç†‡²q‰xoŒu{†Ž€z“‰utu~w€pqm„t”†xul`z‚yˆfqƒogvn[m}€“€€x’’}x{m‡u€‹„t–Š‘Ž‡……{…ltvmgwem{umjvw|`bx†zhtuc~zgt…ŽŒ•{tuq€z|mYVt~ou„‡€ylˆ†txkuƒ„}{}x{s‹}sgtemŠ„mt[j_udHnnL[bWVUxmbPStvWPUX^aq„o\`cmed^nbT\rGBf^]fh^[{bQU\u[[gkaVj_`nffkqhpuxŽtkŽuvx~wƒ{t~„ˆ‡ƒoqtqu~…‚‰Š{wxƒ||…‡x‡|}~„€{~svyŒŽŸ‰z‰vtƒy^}…™Œy†ƒt…†…w‰{bnl[b[[aVjsc`[gnof‡qaqfW]ck|ÊΈ¹¢jmmŠlq„q|„‰~{‘„yytyuu{jluc„u‘‚wpg^}‚z‹‰er‚kjqcXl{†œˆ‚s—”w~{nˆqŠ‹‡q—Žˆ…‹ƒ{y~qqo}fhqbmxqjkqw||y\ey€wiuxf‚vgt‡‹”|r†io~€yn|]Xrmt€‹|‚oo‰qvhww}qzt‡|zrfsanŒ‚lsXk_w[InkMVU^TU{kaOTurPQTV^bt…h\`ljfcYnaXbpGAh\_e_]V{^OVdpY[jh]Wh`_rfkhrgprw†xn•Štzx~y‚ˆ€us€†…‚pp{xwuy†††‹†z|u‹~}…„„‡~~}‡|xvyw’“ŸŒ|‹mv€ycƒ‡—†s’‹o……zƒtcnjY_[]]Tgse`YdqqfsbkeW[`iw¾®{ ·mbs†hs{qy‚…{}Œ~wxsvo{vejn`‡uŽsjb^~xy‹„fq~hjkZVoxŠ¤…q™“q€xu‚m€‚‘‡s•ˆŒˆ„ˆ…}xtrnhy`jm`mvjgjkywzw[g}|xer}n„tdu…Œ†•o‹fkzƒumtb\o|ku|‹|fu‡}mqgu~x~r}kzzzxpflbn‰~mnVk`wUJjkORNhNY|hbNUujLPTU_gvƒf]`qhgaWi][khJEkYacWYUyZNVmjY]le\Zec^tfmdqgrouwp™…v~w|…‡}us‚ˆ•‚nsxzzss…‡ˆˆ„y}v|„‰Ž„‚„{~‹ƒ{w|wwš—zŠ‚†iw}|lƒ„“€r‚q…‚~oflfW][\[Tdpd_WcruiupeecW\\h€por€t‰ddx~ituss‚„x€„yvtunk{pagkg†t„nf]_}p{‰~imwfidUWrp¦|„|v–s{s|zn{{…v˜|‡†ƒ†ƒ|tprlgu\mh_ltdgfizo{rYgwugp€w‚ubw„Š|”€n‹jmzqfse`mzgswŠ|~buƒvikqtzqyys}f~ywncfbn†|mkVjbpSKikOLNpG^{faMUtcJNSWajv~e\gsif`VcWbp]LKkXcaUTUsVLXudZ_ka\[ce_wfmbpisnq~ttšw€w~†…z}u‚„~—…nrt{zuq„…€z‹ut‘€}”Ž€…„}~Œ†{~€v{£¥Šy‰…ƒku|{uƒ‚Œzn…sy„}ƒunjheV][ZZTcne[Xbs{ihmi`bW_Zi€jko€hlahyxjsttm„{}vumzhjyj_enhv„geXbwi~‡{oiogf]UXoh§vz|Žyuo~osuy€w•t…‚…ˆvjrvghn[ld]ls_gaixh{mZm‚rsio€~yw`w„„x„rˆqoyrcqh\owdqsˆ|xbs€pgjxsrlxwuwdƒ{wvoddcn|}klUibfSKmhOGRkEaxgaMSq\IMTYekw{e^mqid]V_UnnWKThWf^XNUlTJ\y_[_k]]Zbe`zhlaooumovuz˜}w€z€‡†zxzƒ~“„qtt~zvt…ˆ}€}ks•|ƒŸ…‡}€~†‚€Š{v„¬Ÿzˆ‡ƒkr‚zv€€un‡o|s‰€jomddX_ZYZUbjg[Z^ui^nl\aV\\kfrt}ij]kvugtwql…{}}yvrlzhixf]dshzw’ccTepg‚…wwfhj`WVYhd§n~x€‹Žzpp|fyozŒ{vŽq„}~†ndvsdhh\kb]oo[g_ludzh]t€orkq{}uuat…Šz‡†wruuaplYqtbqr…|udrlalzojizxurf…uzzupdadns~ilTi^]TKscQGVaGbvfaKToWJLWXgkvzdenqfcZW]XveTJ\cWhXYIWeQHbxZ]_l[^\ad^ij`otxmomvƒ˜yr€|ˆ‹†}uv†x‡Œ}tuu‚xzz‚ŒŽ}~„ˆjs—{‹}~…zz~|†ˆsq®Œ{{‡}erˆzt||vro†l{}lzbpobe]eVYYWdfk`]\s…hXqnZ^WZ\l{cpwvlb[lrsgtupl„y~€ywnnteite[gufvv‘z_]Refj‚‚t}bci\TX^bc¥hyt‚…xmnygxm|…{uˆr€x|xhevm`f`^j_]skYe]oobze[w{knnpwxstdrƒ’~‡‚ˆzvor}rbxd[opaqq‚|sfq€d^nvidgyztnout}sqb_fno}djShXYTMw_QJYYHbtdaITmSILZWilq{bllscaZZ[av[SKd^XiSWGY`NGiuX^am[[_bb]…hhanxylojvymƒ~€’ˆ„vt‰tŒ†trwvw|}~Œ€~“~px–ƒ}™’y€€xy}tˆƒsp™¢{{ˆ”xduˆysxulto~ly|p‘r^po`gblT[ZWhcmf\\qˆeRrn[ZXX`lwdiujj^Zmsqlsssj…|~|wnnldiqc[jrdtvs[WSdar€r‚]bc]SZ`[c“Ÿerq…„‘tljylopz|{q€vrzzzdfvg]bZag[^whWb]ohaw`[{vjirnwssthp”‚†~„vrjp|mfwW\kmbqszsfo~[`oqb_jq}llt~sqxkpa\ellzagSgUWRPv[RPYRIcsb`GUjPHPZUkkk|emoqa\ZXYlpWRPfVWiSTFZ\OHrtX_cmcXa`a]‹jcdmyxkoiuy†{kƒ}€„™|‚„y}ˆn†qowz|t‚‚|‹ƒ‚—tw‚”…Ÿ‰u€€sp‡‚uo¢—t{†‹†{ex‹on{ofxpzlsvrŒk^tnagekR][VgbllZ\qŒdOon]VXUgjthbtee]Ymtmpuuyj‡||ˆwsddkna\nmcsx‡kZTVbcx}}q…]c_cT[`Yc–•cnpƒ…Šsjhznesvs|lztuoz~u_frc[^VbdXaueU_`mdaq]]~phisqspuujm„“ˆ{„qrfn}proS[fjfqtwsblvUbqj[_ne|emv|srsjm`Zdjjw^fTdUVPTmWQWSPHer_aFXiNHWTVmhd|ikxkbW\U[tdSRWhQYfTSHZZPMxw[_eliZb`^^nbfkyunohvvlƒ€}†—{ˆŠk“ˆrgt€{u€ƒ}ˆŽŒ“s|Š‘…‡Ÿ†{†Œs€†s}ƒvn¥Œs‹vwmzŒ`d|pfzsylmqv‚gd{lcfghS^^Tg`lo[^nhNjm`TVSogskexde]Xotlrzwrlˆ{€vœ{zkaelm^`ojepy~gZVX`kx|{p„_b^gVY`Wdœˆbkq‡}wkkxl[vqlziusno{€rXjn_Y]UacWdqcS^aiablZ`~lfksunmwvkh…Œˆz‡mqfp|mrmcYahiottr^ilReqdTbnbzcqv{ukpmk_Xaght\eVaVSNXeRO\OOHep]cFYiMI_KXmd_xhn~d`U^T]t[TR`fN]aTSJ\YPYuv]_fmhXca[^Žpcgjwqsngvtzƒrƒzˆ~|Š‡ŽznŠtls‚tˆ…†‘„•y~Œˆ‘›„€|Œ„sstxqn““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~~~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’‘‘‘‘‘‘‘’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’‘’’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z||}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ”ÎÚØØØØښ„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDEB1////0/>DDDDDE8.//00,H…ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ”Ûéççççêœ~‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR4555553.755556':ƒ€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}z{z|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹’—˜˜˜˜™™’Œ‡‡ˆ‡‡‡‰““’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†………†…ƒƒƒƒƒƒƒ……†…………„ƒ‚‚‚‚‚„ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z{|{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘‹Ž‘‘‰‡ŽŠ’“‰Ž‡‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…Œˆ††‡Œ†‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰‘‡†…Ž†‹ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰ŒŠŽ‡‹‡‡ŒˆˆŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}|}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹ŒŒ„Š††ˆ…‰ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz||||}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒˆ‹ŠŠŒŠŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzzz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{y{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†……………„„„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰ŽŠ‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{}~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““””””“””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••””•“’’’’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””’’“““““’’“”““““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘’’““’““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’‘‘‘‘’’“’“’‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡ƒ‹Šˆ‰‰†……„„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxz}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzop{xy{|{xw{xuwttvtuvwuqrqnprpghklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkiffggghhgmgjghehgcbbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__ac_\_]`]^Z^]YY^ba^^ZY_[XWSNMLKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{xvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSTPMJMNPROMPQQQQQVVQQQTPPNNOLJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTtsuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMOPPRQPNNONONOPPQONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKLFDFJKKKHJLLLOMLLNOOOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEBA@@CCDEACEHKOKIIJHHJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:;>><ED=?EA?@A@DEGGGGBDDDFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@;;><;;<<HL==A@@CD=ADDFCFFDFIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnpprtusqrvyy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;:;;99:88;<979;<>=;<;8:@@AB?A@CFDCCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqusurqtxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<:79::979::69:9:;<?7=;::8<<=@A@=;;><==@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyy{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>=;<=?@===?Q>===<AL;LB9;<>=>?@A@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquutusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCD@=<>@A?A;ZyO=CE>DX<YN;<<;:=>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVppqssttuyz{{|~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???CFD><;=@=9::owY7;:<G^=`\9;<;89;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pqrrrtuvz{}}}~~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC?>AAABAC_I<;Fcg_WwwX7888MbBeh<;<;::;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC@O|tFFu†††‚|wY<=?<SjGgk>;=>?==>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hloppqtuvy|||||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCE@Uvzpv„ƒƒ‚€}Y>@C>SoLdh=;=AEABBFHC=<@DCAA?>=@A>>>?<>@DGE@>@A?@CFECBCC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{|{}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@Ptsƒ€„||…mFBCDBRidsrI@CEHIIIMMKECFGHEGEEEDDCA?@>>BFJJGEEGFFJNNKJIGGHKLIGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@EGls}€y…€}†sFCDDMg}‡ˆˆ~XGHQPLNOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHIHGFEFFFDFHGEEHHFHGHFQnnpqrvvy{{{z}}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJG`z€|‚„†……‹l@@Vw†ˆ‡‡‡ˆ‚XR^NLMNLJGGGGDGGGGFHFHECDDFEDDHHCCCGJJKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrswwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLKN\|ƒ…„„„…†ˆ€Vl…‡†‡†‡ˆˆ‡~iVKKHGFFDECC@ACCCCFFEB@>>@AA@BD?>?DFHDEGIJIIHHIGIIJJIHFJJJJIJIJJJFILLJJKKfopsrtvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKLLJZƒ„„…€…‡†ƒ‚……„…†††‡ˆ†‰{KIFB??@???<<<>::<AA@><998<<=;>;9;?AB@ACCB@ABDDBCFHIHHHLMLGIJMMNMJJKKJLMSloqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHHJJIh…„…„€ƒƒ‚ƒ„„……†‡ˆˆˆ‰‰ŒfBB=88::9878896479;<:8567789787588;;;=@;999=<>;;=ADEHJMLLGIHORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@CGIIi†…„€‚„ƒƒ‚ƒ„†‰Š‹‹‹Š‰Š‹Œ‰T:8656766645763468:876565676778:77789;7578979876:<@GFIFIFEFOSRSSROPPRTepqsttwy{|{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:=ECBh…ƒ‚ƒƒƒƒƒ…‰ŠŠ‰‰ŠŠŠŠ‹‰‰ŠH676468874578467699766765:::::;898987779:98878589;A=>>BA?AKLOQPQOOORWkqrttuwy{{{}}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897;B:>v„‚ƒƒ„„„„†‰ŠŠˆ‡ˆˆ‰ŠŠŒŠ‰‰Œz>:88;<=>9:;<89;9:;:99;:9===?;;;=:>;9;;<;<<9:<8::;:999<?<=ABDIJMKIKLWorsutvx{{{|{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<;89989:::;?=Jƒ‚‚„………†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>BCEEAAAB>@B@@>=>>@???@?@==?B?AA?A?=@@@>?A=><;:;99;?=;;==AACABCAXpqtttvy{{|}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::<=:;;==?@BU„‚‚„…„…„†‰‰ˆˆ†††‡ˆ‰Š‹‹‹ŠŠ‹Š‹^>DGIKJIFGGDFHGEBA@CECCABCB?@DHECEDEEAFEFDEFD@B?<@>=?@>???>?>>:;=<`qrttuwzzz}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>???=A@CCEZ…‚ƒ„…†††ˆ‰‰ˆ‡†††‡‰‰Š‹ŒŒŒ‹ŠŠˆWHLMMKNJIKHIJJIECDFGFDCEFDBHIKHGGFGGEKIKIJKJCFCCDBAACBDCCDDCA=;=@hpsttvwzx{||}}~~~}}}}~~~~}~€€€€€€€€€€€€€€€OA>=?DLK@BBA98<>;<;>@?A?BCGGJ[…‚ƒ……‡‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹‹ŠŒPMOMKNKJLIIIHJFDGHHIEEHFFELLMIJGGHIJOMNLLNKGGGGEECFFFFDEHHFCA?@Llptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?FGG=<@@88<;<=:?A>@@CFIJQ`‚ƒ…„…†‡‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒ‹ŠqMQOMLLKLJHHEJIDJHGKJHJGGGKLNLLHHIJMPNPNMOKIGIJHIDIHHFFGGIGCBACUnpuwwy{xyzz||}~~~~}~}~~~~~€€€€€€€€€€€€€€TDAABGHB?8?@8:<8=>;=A>?@EIKMVrƒ„„„„…†‡ˆˆˆˆˆ‡†ˆˆˆˆ‰‰ŒŒ‹ŒŒŒ‹‹‹‹_RRPMNMKJGFBGJGLJFKOLKJJMMLOPNHIKLOQQQQOOJIJJLJLFGHGEGIFEEB@BB\orwxyzyyyzz{|~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<9@>>@BGGAHLMQWy…ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹‹ŒŒŒŒ‹‹|WVRRTROLKJDEFKONOWVQPOQSRMSTOMSLPSUWRSQPLJMMMKNGGJFFHJDDEEBDCcpuyyzzz{z{z{|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?==B?BCGVNFOQQUY|†ƒ……„„‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒ‹‹‹gVUkaERQQPJ;;QSR`u]UVTVYYRYXRZfPUWZ]RTWQPNRPPPQKKKHHJHEFIHIHIirvyyzyz{{|z{|}|}~}}}}}}~€€€€€€€€€~~SHJIIGGFE??AAEBCGEDELXRMTVVX[|†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ}aŠ‹‹‡l[dU:XXXSP>@VUY\d`VYbr^]V]ZVEQYZ[Y_TZgRUVXTTVTOOMJLJIILMKOMSosvxyxwzzz{z{|}|~~}~}}}~}~€€€€€€€€€€~~~VJJIHGFDDBA?HMIMPKIKPTSSXZZ\\x…„…………†‡‡‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~Œ‰Š‹znpXZ[ZRSRVVTZZuƒYU}a\X]^WIV]][[_YIYXY[]XXYWRQNPQMMOSQQURassvwwvxxxz{{|}}}~}~}}}~~€€€€€€€€€€€xy}YNKIIIFBD@A:PQQWXPPOQSTTXXYZ[n‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡ƒŠ~fYY\YSVTWRQWVc–€QerXZW_hP`f[[X\gaGOZhg\[\]]WROSPPQVVVVYZnrtwvvtwxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZ[RSQORRRUSVTW_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PUXTRTRQQLOMKfyZ]TYUV]ZLTZTST^ZXWWWzkXZ[\^TQQPINOWVXZZdqsvvttvxyy{{||}}~}}}~}}~€€€~~zxwvsu{€€tk~~kry^[VUTROKFCDAM^ƒlVRSNOQOQURSRRTcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ymqVIKMNKMKHJDFHEC>ScURQQNKRTQMOYQMNQSUUMQSRPOMLHCIHRTUZ\mruvussw{z{{{}{}}}~}}}~}~€}}~~€~{vsw}~~du}iqt_d]^[YVPLILIal’tPQSNQRQR[RSRQRVUbs{|€‚}{{€ƒ‚…†‡‚†††„†…†u_]KC?CCCCB?DPBD@C>BHGV@HNMG]iQHFOFDEFHGHBCHGHKGCBAD@OPMSdstuustuz|z{{{||}|{~}}}~~€€€||}€€€}vt{mh|gnqfiedb[XSQPURsWe[OOOLQSQUYSUQQTSOV`klrv{{xytrnstsyx~~ƒ€ƒƒ‚€‚€‚kLG??;;>@@??>kQKaEFHIEB?GLMGMQUIBE?><=<==?=?ACC?><=B>JMFUnuuustvxz|z}||}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QRZ\Y^IJPQNKLQRQTUUWQQWVPX[b]agmmlokh`nrjmlqu{z}{xz||xwxdB@@B=:BCAADB\]O{NOONKLMOOQLKLWMHG@B<977599=;;;8989?;BH?\ttuvuvxz|||}||}}~~|}}}}~}xuvz{zwyxuw{|yxuywcqhipmnmmhf^OP^\ZIGPRQOMPQNQRTVXSRYTNYZ[WY]^^`e`]^qvk^`gkwooljonnlfbXGFFHBAFIEEFDMRPaWRXQPSSRU[OOQWPMJCF>::6486979:366795<B=essvwwyz{}}||{|}~~~{}~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZWMLTTSQQUOLRSTWXTTXQLXYZVXXVXY]WWXhsk]Vaskaa_]da_^YUPMONLHHJKIHFCQPSZWTTNQSYS\eUOSTQNKIHC?A9988978857578599Gnqtxxz{{}~}}|{}|~~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPXVVSTVOOUVXXYSUTLKTUUUUWPTUWTUR]n^RNY_[VY;DVXT[fJLPRROMMNNNLJFPPUYSTNJOOTST\VRUSROMKIHHF??=:787659967665Wppsxyz{|}}}~||}|~}}y}}|~~~}||}}~}|rvqxxrvuqqnppopuvtnjddjppqrpnfedc\^RTZVWUTWTRXXYYYRUOJHOPOOMRJOPPPNNOTLMIPOSTU2<XMIAQ=caQSQPNPQPNNMPNTRPRMILKOQPQRSTQROLMKLLHCBA=::876;B4566;epquxx{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqptuvcjgeWhtrrqniihpVVTUXUWURWVUZYXWUQSFFBFGGHFJDHJHGEHLHKHFLMPMG/E_R>3@>joaRRQ@FUQPQPQNQOPOLJLLOPNNPQQNPOJLMMKGEEDB;=<<9=G6676Dnqtvz{{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknbePSTRSUOWVVYYVQQQO@>;=?@BAC@BEDA@GHGHEFHJNKEGCORC8ENS]fSQSAGUPOQQPMMNLJLKLNOOQMOOMHLLIKKLKHFFED<AA>;@E;<89Tqsuy{{{}||{y|{z~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLOOMQSLTUTWWULLKH=987;?@><=@@B=>EHGDFFIGJJ@FAA@FHEJOHPRa\QPRNSOOPLLOMKMLMON[WKMQOGIHCIJLLJFFFD?BC><BF?B?Adqux{z{{|{zzw|xy}~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCE=9879?B>;?A@@>ADIECHHIGIEBB?>=CAAGIDMObeQMONWKLMKLMMLLKNNSdMJLRIIIEAHJLMNJGIFBAB@?EFEHDKopwzyy{{z|zwsxtx||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGLMIMPMPOHKE?B=999:?B?<@BAADEGKFDIIGGHCC?B??@A>CECKMQTLJIMTFIIJLJKKIILMOPRPKGCKGCBJJLMOMIJIGCCCDIJMLIZsmxyxz{{y|vrpurtyyvxjqojllnttmtu{stxronqovsnporpopstyjN`gsjt|ygosqjqheqHKDGHHGJKIJKDGB=>=:::;@B?=BBCCGFJLJEIIFGHCC;A@B>@@CECIMPGIKFHKDHIKMHJLHHJLKM]RIHDMFADKJNMPNKMJKFGGJMNQNLcnivvw{x{z}qmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoijthdoFKDFEGDEEGEGBC@><=:;::@D@>BCDEIFJJLFIIGFFDB;BCC>?CCCEGLNHKNHDHEILNMHILGEFIILNKJHENHCGMLOMOMNNMLIHJORQRNRfgfrosxu{z|lhjoekpmsqfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGJDFFEBBBE@DB>?>:;;=:=>CA?ACEGJFJILHGGGFEC@=EEB>ACCCEGIIGMPIFFGKNOKFHJFEDEIIHKIFHPKDIMLPMONOONJJIMRUTROWd`amgproryzgehhcilgqlflmgiklslpvutpnvrosrsutqssutsuvvvyvutvlkuumrvqlnlerMGEEGCBABD=BA>A=::=?;>>@B?@BDGKFIGIHFFGECBAAFFCBCBDEDGGHFLQLIOJJLKIGHEFEDCIHHKJGKRMCNOMQOOONOOKKKPUWVUTX`^\iaminhrsbeffdihfnifmmhkkmriqvusqmvnoqrswsrstuvvvvwvwvvtwuksunutsqrjksMGGFHBBADD<AA@C<89=>9?<?B?@@DFHEHFFGFFEDCECDIFCFEBEGEEFGEJMKHQMJKHHIEFHHECIIJKMKOSNDQRPQQNOMNPMLNSWVWXVX]Z]d`hbjigk_eegcgggkggkmkmlpqgttursnvoqprtxqssuvu‚‘yvvtxuuwxnouorsuqqiozMHGHHBBBFE<@BBD<7:=>:>:@B>??CEFDFDDGECEDDEFGJEEIGCGHFHFECFJJGMJLKHJLFIIKHEKKLMNORTOISUTQSPQMNQNMQWZVZYVZ]ZXa```^hec`dehgjihjfhnllnmqpiuuxrrpupppruvpusuvu{~}xvtwvvvxplupmsunorsyNIHGIDACHE<@EBE=8:>>=<<AB<?>ABFCEBBGDCEEFGGGIFGKHCHHGIGFDHKIGKHMKJKLHLKMKIMLONORUVOKUVTQTQRLOQPOTYZY\ZY[^_^`c^\ackb`dghr…hgifjmnponsqjtuxrsstrnpqvrquruus~yŽ}uuvvvvxrhuqkrtlqvquMIKHJEBEGE<@GCD@9<>@?>?CB<@>AAFCEDCHDFDGEHHFHGIKJFJHHKHFFLHHHJGLLLLLIMKMMMOLPPQUVWOKVVUSSRQLORRQV[[]^[\^__a`ad]d`ef`ehjcssfjhglprqossnswwquvtsmoruorspurvrtvuuuwvuwtgtrkqrkrvovJKLJLGBEDE<@FDDB;??A@@@DA?B?ACHBEDFHEIEFDIHFIHJLHHJJILJFJKHIJJGKKMMJJNLNNNPLOPRUXVMNTVUSRQPLNTSRW[^^_]]`_aaa`bdeachbdijgv‹lkigmosqpqppryvruutsmmssmqrotutrpswtuuwvuuteqskpqjrvowJMLLLGDCAD<?EEEC=AACBBCEBBDAAEGCHGHGFJFCGIGGJFILHJJMKMLGKIHLKNQKRQLSMKNNOPPOTOWXX[NSQW\ZSVPNTUTTXZ_bb_da^`b^`eaabgnhbihhmxvlhimosrpqrrrvtsusssnksqmprotvrqquvuswywutucmtkopjqtowLMLKLGEA@D>>DEFC@CAEDDFCCEGCBIFCHJIHIKFDKJGHJIIKGJJNKNLILHJMKZfJd\KlSHON_nUks[qpbwcRPbvuhucav`Xnqbdvinzf[lt`ljT`wuijgifglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqrqyKNJKJFC?@B?=DEFDCDBEEEFBFFHDDJEEJLLJLMGGMIHIKHKJIKJNLMMLLILLL[sbdp^lmUMNfs]geqlntgpi_aYnnbppbkjjgoqtetno\ougpMJryvkb`keemymkvlnpsrprqpqrqrrrtrmmsnnoprutqsstuuutwxvutbmukpplrrqzKLIIGED@BB?=CFGBFCEDEEDCHHGDEKGGLMMKMMGJNHJKJILKJJKMMNNMMJMMM[roonpplkMPQlWNibtrpamov\YlQ\mmZqmkomxxtsip\_rkqjUuyxpc^kfbgqpjioppsspqpqqrrqqrrtlmrmnnorutqtrtuutuuzvutenukpolsrryJKGGEEEBBB=?@FGBGDIEEDBFIHHEGKJGMMNKMNHLMILKHJMIKJJKOPONMKNML\hdu]lqWlNPQmUZk^klvaldtTecNmYl\tpkilxjwuhp]^rkhWbcw|oc`ghadjuyknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtwIMGIDEDCAB<BABFDGFLHECCHKHHFJLLFNKLSRLGLLHNJIHNHJJIHNOMNLJNMJZsppoqqmlOQRnYqkgooqqomt^nXat_nopoqronusttj[]tcwxrjnzhaacgbbjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyytukoumtonssvtHKHIBEEEA@>CCBGCHIMIFCFJLIGFKMLFOJKWRKGKJJNIHJLIKJIHJLMMMIKJKSkbZi^_jcrrZ_Yjo_eeUk_c[abQ`lh]j\niid[pfdp]Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunwqrutwrHHFIDEDFA@AEDDGBHJLHFDGKLIEFJOLIOIL[QJFHHKMIHJJKKIHIGKKLKFHJJLLLKIKLNT[\TPTLPONOOVQOOQOOQJINPQdqiTYW[[\UY[]X]\\cfaafbce__fkmhmtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyxxuvqruovrtsuusHDEGFFAEC?CGCEGCIKLHFDGKLHDGHPKLOKLWLIEEHIJHIKILJHFHGJGHIEFLHIKNLIO\W^O\[`^OXYS\\b^MYZMXaRJYaZS`d\aX[ddVVY\YZX\VY\]b_d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtPBCDLMBCDBDIDGGFKJKHEEJJJFEHHPJLMJMSIHFAGFJIKKJLJIFEJGDFGEEJGCJMJKT_Y`X`a[`UXYT^^Z_RY\P^\YN^\^S[^c^Z]`c`Y_b[`^[TXXY^]ccbaceiekrpoppnow††……†‚{€……††…†…uqprrsvyyzyyxxxwryvxrqxvtvaSJJMIECBCFGEGGIJJIIDFKKKEEHINJNLHLNGHF>GGLIKKJKKIGEIDCCEAFJD@JKIO[cY^^a_RTSW_`\]Y^QY\MV_WKQY[PZ_aa^^ca`bbbcceZQYVU\Y^d`__cebhommllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxXQKGCGEBEGHFGHIFGJGHFHKILDDKKNMLLHJJHJG?GFNKKKMKKKIGGCD@DAHIA?IJGO]aZ[d]_TQSX]\\\_ZKW\LR\YIM^PO\_acdccb\dcbdcfXQUTS[XZa^^^aa_dlkmjjlnv~uz|„………………††…†……††‚zrsuu{…‡‡‡†…„~xpzwvx\RMC@IFCFKIFFGHGGJFFFILJNEDKJLNJLIKJHIGBHHQMKKOMKKIHGED?ECHHAAGFET]Y^X_Y_[]UXXP]]QKJW^X^[]VZ`RQ__bba`bb`cbbddbXOQQR[S[^]]]^__dhgljnnp{{|~{€‚ƒ„………………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKBAGFDGMRHCRKFHHHEFKJMPEGIJKNLLILKIIGDHKQOMMPLMKKHICDAEDHGBAFEDWUE\T]SV_XNTUNZ[MJKU`a[_X_^a]OYb]``_bcb]bbW__TPNPQXR]\[\\^`bffelfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDEFGDIRbPDW_IGGHDFMJPPFJIJKNLKKLKJJGEJMQQNOPMNLNHKADACDFDCADFBMHCLLPOOLFMFGIJHGLLMOPILOPPSPLPTSUZYWYXXdVOSTPPONPUT\YYZ]\`adechcklpsszy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKM]LGHYMGHJHGNLQQIKKKKNNUNOKKLGGKPSSNPONONOHKE`ED_LDfcDM[I_\smOMVmYLCP`UlWgJ]WU^DMQULMTVQSTXWTXUT\TPfZhhdXTkTWVU[\[``abbb`fhfnlhrz|}~„„„„ƒƒƒ}|zr{z{‚€ƒ„„……„…ƒƒ~z{LIEFFHEEKOSIKG`THJOJIOMRQKLKLORUROOJLNGHMQ[YOPPNOPOIJPQI|YYrsWPmHqnpaVPqqsPBksmqspSo_[nX]V\XUkhU]VcZ`Y[`VUWjtuu_`w`Xa\\f[_aaaa^`bgmpl`pwtx‚ƒƒ‚}~€vxzlv~tx~€|~€‚„|€ƒz~wwNIEHMMBDLLFJLFRVLKOIKRXWQNNNLQTNOQPKLOGMPS[ZTQROPPPJHZx]TxehYRTQvgtlpbnfjQrOMwmjrpsrqrpop]ezuxqqzq~s}ku}bRg|essoss|}o}yor_``bbZ``gknkblfgmw~€ƒ~{xw€tvzir~nt|~wx{~€ƒx|€u|||ssNKF`]GAEMMHKJHJPNMMJNV^YULQSNXZLSSRNLPIQRTYWWPTPPPQKGfxlcxrmZJLUypumubnvPdeJfvqmwo€jfxxiXsQhzmijzz~lxzogoXvvjuup€`sh|ilx|o^__cb[]bdgijdgbcdllppstsssyqrxblugry{ssuy~suzn|}yxrnNKStNCBEPPHJKJLPOOPMPZ`ZXKTWPa^RVQYSMPISTVXWWPUPONRJKrouuquqdh`VnLqp^FhyWvTLhx}x`y{sna^modRgrunmypwlvttqlm\t~zkmy|lum|kpvux^__b^]_edighee^bbiiijknokqnmjpacfdowxompsy~nqpj{ztromLL[VHGEGRPJLMKLQQQQPQW\YUNVYUfXRRY^TMNITTWWYWOSNNNQHRmHiwK`dvvUWlOnl{sajgvUKWkh}lmlx`[pz{^`zscroxqhe|ir{]TKl`vukiu{{m~xk|p]^^b[^bddgeeebZccikkrsrwgmihdg`alagsrkhlmr|kmhk{tmmkmOHJKHIIHRPLNOMLTSSOTRWRVTPWZVVTTTa`QONKTTSQUVNNLMOPJHQNPULKKSTSRTPVUQQNQQXXQNPUTXXX[[URSW[WXWZOSUWWXR]YW]VTOYRWWWXY_[gr^[[Z\]_cZ_ccdfdccbZccfffmnmuffgc`f_]g`dlhfgkhozhggkujhgilQIKKLMKJSQMQPOLVVTPTUXUYURZ]VUTWUYXPOLMVTQNUSNOMLQPKJQRKQMKKORTRQQSSIHLNOQRQQQTVRXW\WSSQRUUVSZQOSRWUTYVTYUSRUSTTXYW]Z_a]\ZZ\\`c\]bcdgeddaY`acabhhincad^_c]Zd\bma^ffgmsdihkkedcfhPJKLOOLMTPNSQQMXWUTUWWWZVT\`VWVYUXTQPKOWSPNUPNQNKSPMOUTNQNMNQSPTQSTUNKMOQTTRRQVWUYZ[YSURTWWWY[TOTUXUTYUWYTRRWUUW\Z[_]VY_]^]\]aa^[bbchfedbX_`b]`hefda^_]]^ZZ_Z_g`^]]chkagfhfd`bcaPKMLPQLOTOOSQOQZYXWXZZXYV]jdVXYZWVTTOKOVTPOTPPPNMQQPRXTRQOMOSUOWRTUUONMQSUUTTRTXVZ]\ZVVQRWXV[[WQTVVVVYTWWTRRXVUZ_Z]__W_]^`\\``__ZbbdhhedaYb`b^^fdd`b]\\\\YZ[X[a[^]\_b__bddbd__`\PMNNRQMRROSTQOU\ZZW[[\YZ[dqmhd_[YVVXRMMVSMNROQROLPSRUZUTPPLPWVRWSSSXMOPRTXUUUSUYX[^]\[VROUVV[\WQTWUVXVTXZTSQZWV\^[__`Vb\`a]`b_\`]cacgidf`Yc`a__ee_`c[Z\[\ZZYYW\Y\[`^`[^^a`_b\Y`ZQNONVQPTROUTSPW\\\X^\_W\^jqwy€c\[VVXRNOWSNQQPRTRKQTSYZWUORNSXVTSTRRZOQSSV[VVWTVZX]^\\^VSNTUV\\VRTVVXYSTY\TRR\WZ]^]aa`Wb[cb^ac_\bab_dgidf^[d`a`ace_b_YZ^[\[YXYWWZZZa\][]\\Z]`W[[ZPOOOYPUUSRWRTP[]^][`\`U\]ijr}slg\UYWQOR[SRQTRTUTKRVU[YZSOSRVVUSOVRSZRTUTX\WXXSX\X^]YZ]UUNVWW^[XQTUXXXUWY[TSV]Y]]`]bc^Y`[eb_dd^^cca]efidf^]da`aacd_b^XZ_[\[XXXXW[Z\`][[\[XY[^V^Y]POORZPZUUVVTTT^^`^^b\`U]^bkytl}lZUZUQQS\TUTVTVYWLRZV][\ROUSXWVSPXRSWSVVU[]X[YUZ^X_^Y\YRWRYXY_ZZSTVZYZVXY\VUZ]\^`a_dd]^]]eabfd^^dc`\gdhedb_da_a`bb_`^WX^Z\\ZYZXV]Z]^ZY[\[WY\]VXW]SOPWYQ]UVYWWUX_`aa`c]`U]^beeuzhXYZTVSV\WWWVVW]XPU\Y^]]TRXRWVTRTXRSVTYXY]^X][U^_X__X]VQYTYZZaY\UVX[ZZXYZZXV]^_^cbaee]b\`fbdfd__dbb[fchecfaf__aaaa`_^VU]Y[\[Y\YY][[[XXY[YZZ]_]TY]UNSZVS\TVWYWV\`abcad__V[`da_zuohY\ZVXUW[ZY\YXY`WPU^[`a\TUXPUVUSVVRSUW[Z\_^Z_\V__Z]^Y^VSYWYZ]bZ^VW[\[\[[Y[YY^_``dbceebdZbfcgfe^ab`c^cciddg_g^bbcaa`^_XTZZZ[[X[XX\[Z[WWYXW\[\`]V]]SPVZVVZUXUXWX]_badada^YYadb`lfh^\][WXXY\\\_[Y[bVTW^]ac\RVXQWVVVVVSVTX\\_``]a]Wa^[^\[^XVXX[[_`\_XY]\]^^\Z\X[_a^`dcdfffbYceehgd^c`_ec]fidei_g^cbcaa`__[XY[YZZXYXW[[Z[WXZTY]\Z`\U^bNRWYVWZY[\YWY^`baeada]^Yacb_a`a_\\]XW[[]]__\Z]cXZX]`cd_RXYPXWXYYWVXV]]^`aa_b^Ya]]^Y]^YXVW[\`_]_YY^]^^a\[ZY\_a_bdcefefbZdfgigc_c^afdZiibfice^bbca``_]]ZW[YYXXZXWZ[ZYWXVU[]]]``bbxLWW\YW]\\]ZW\]_`bdbba]`Xbcb`cab^\\\XW[]_]`_][`d\\XZcec`R\YOXWY[ZYXZY`]`bb`ac_\b]_][^^ZYUX]]____[Z^^`bc\\W[]`bacedgeefd\efhifcab\cg`\iibhife`baca_`_]]\Y\YXWXYXW\[ZWWXOXZ]acffrkJYW]ZZ_]\^\X][^_acbaa]b[bdb`ccb]\[ZWXiq`\`_]\ac_^YYcedaS_ZQYW\]\[Z[[c`cbc`bda`c^`\]^_ZXV[_^]aa_][`abeb_]S\_`cddfdgfefe^efhhgdd`[fg^ahhchhfc`b`cb___]][Z[YXXXVZV\ZZVVULXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡…ƒƒƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vvvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{{{{{{{{{{{|{{{{{{{{{{||||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vvvvvvvwwvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{{{{{{{{{|||{{{{z{{{{{{|||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||upooooppz~}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰‰‰ŒŒŒŒŒ‹‰‰‰‰‰‰‹ŒŒŒŒŒˆ~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}upnoooooz€~†“y1333332j‚€€€{­éääääèʉŒŒŒŒŒŒŒŒŒŒŒ‘‹}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}vuuuuuuuvwwwwwwxyyyyyzxooooppprrrrrrrwzyyzzz~ƒƒƒƒƒ„||||||}}}}}}}}||||||||}}}}}}}|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚‚‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vvvvvvyvvvz{x{xwvx{xzzy}yxxyxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{{{{{zzzz{{{{{{{{{{{{{|||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwwy||}}z|{wwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwwwy|}}y|zwxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z|ywww|z||z|{wxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚ƒ‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzzz~|}|{}{xxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyy|{zzy{yxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyxyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{|||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}|||||||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}|}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrstuttssrrsrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqstsssrqqpponnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqqrssssqpqpoonnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrqrrssrrqppoopoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpppqrrqqqpopooppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqpqqqqqqpooppppppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqqqqqpppppppppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsqu‹‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqqqpqqqqpqpqpqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrqqqqqrqqqrrqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrssrrrrrstrrsrsssssssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz|~~|vvwwvuxzxxxxwwwvx|yy|zyy|{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~|{{z{|{}|{{{{{{zyxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}||{~|}~~~~~}|||}€ƒ€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€~€€€€~€~~~~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~~~€€~~~~~}~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~~~~€~~~~~~~~~€€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹Š‹‹Š‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚ƒ‚€€€€€€€€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒŽ‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒ„‚„„‚ƒ‚‡ƒƒ‚€‚‚‚‚ƒ‚ƒƒ‚ƒƒƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒƒƒ€ƒ‚„………††‡††††‡ˆ‡‡††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠˆ‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„ƒƒ‚ƒ…„ƒ‚…‡†‡‡‡††‡‡‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ‘’‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„„ƒƒƒ‚†ƒŒ‡……„ƒƒ„……‚„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘’’ŽŽ‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€‚ƒ‚‚‚ˆ“€’ˆ‚ƒ€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„„„„…„…†’“‘ŽŽŽŽ‰ˆ‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~€‚‚€‚ƒ‘‡€€‹š€•Ž‚‚ƒƒ€€€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“’Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚‚ƒ„‚‚ƒƒ‚ƒ‰™Œƒ‚„œƒ˜’‚‚‚„ƒ‚ƒ‚‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘ŽŒ‡…ƒƒƒ‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒ€ƒƒ……„ƒƒ€ƒšƒ…„‚’œ„—”„‚‚‚„ƒƒ‚‚„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”“’’ŒŒŠ…„„ƒƒ‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~€„‰ƒ€~||{{ŒŽ€‚‚‘›„••„‚‚‚ƒƒ‚‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†””’”’Œˆ„„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~…›”ˆ}}|€•ˆ€ƒ‚œ’˜”‚‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“’Š‡ƒƒƒ„‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€„›ž‰~ƒ}‰‰~‚ƒƒ„‚ˆŸ ¡“‰‚‚„‡‚ƒƒƒƒ‚ƒƒ„‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†ƒ…ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„‚• ˆ‚…~ƒ…††……œŸ†~}}‚ƒ‡–Œƒƒ„ƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„……………„…†…††…………………………††…†††…†††‡†…………ƒ„„„‡“““’’ŒŠˆ…………‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…ƒ‹’‚„†„‰~‚ˆ†…ˆ|~ˆš„„„„„„„„„„„„„………„…„†……†…†††…†……‡……†…††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„„„‚€„~€Š‚~~…žƒ…†††…………††‡††…†……†‡‡‡ˆ‡‡‡†††‡‡‡†††††††…„ƒ„………„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘”“‘‘‹ˆˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒ„„„„€€Œ‡€~~€€€€~ƒ‡…†‡ˆˆ‡‡‡‡ˆ‡ˆ‡ˆˆˆ††‡ˆˆ‰‰‰ˆ‡†‡‡‡‰ˆ†‡†‡‡††…„ƒ„…†…………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†…†„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡†…ƒƒ…„„„ƒ€€ƒ‰…‚€‚‚€€~{y€†ˆˆŠŠ‰‰ˆˆ‰‰‰‰Š‹Šˆˆˆ‰‰‹‹ŠŠˆˆ‡ˆˆˆ‡‡ˆˆ‡ˆ†‡†„ƒƒ…‡‡‡†……„„ƒ……„……†„„„………†…†…ƒ‰”“ŽŠ†…†…ƒ‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡†„„…„ƒƒ‚€‚…„‚‚‚‚‚‚‚€~}}}}~|{|ƒ‡‰‹‹ŠŠŠˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰‡†††‡…†ˆˆ‰ˆ‡‡‡„ƒ‚„ˆˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚‚ƒ‚„ƒ„ƒŽ“’‹ˆ…„†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„……ƒ‚„„ƒƒ‚‚‚ƒ~}~~~~~~}|~}}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡‡‰†ˆ†ˆ‡†‰‰ƒƒ„ƒ…„„……†ˆˆ†…ƒ‚‚ƒ…‡†‡††„ƒ‚ƒ„‚ƒƒ„‚‚ƒƒ„ƒ„‘’‘ŽŽ‹‡…††„‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…‡ˆ‹Š†„†„‚††‚„„ƒƒƒƒ‚‚}|}€~~~}|}}|y|ƒ†‡‡„ƒƒƒ„………ƒƒ…„„„„…„…„‚‚ƒ‚„„‚ƒƒ…†…„‚‚‚ƒƒ…ƒ„„…„„†ƒ„„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰†„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€ƒƒƒƒƒ‚‚}}€€}~~}}}}{zz~„„„‚€‚‚~‚ƒ€‚‚‚‚ƒ„€€€ƒ‚€€€€€‚‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†‹“‘Ž‹ˆ……ƒ‚„‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€€ƒ‚~~~~~€‚ƒƒ‚ƒ‚ƒ‚}}~€€€~}}}}}}|zzz€‚‚~€~}€€€€€€€~}}€~€€€€€€€€‚€€‚‚€‚„ƒ†’ŽŠ‡‡†ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€€‚ƒ„‚‚ƒƒƒ„…€€|}}~}}~€}~}~ƒƒƒ‚‚}}~€€€~}}}|{{{zzyz€€€~~~}~~€~€€~~~~}|~€~~€€€~€€~€~€…’’Ž‹‹‡‰…„„‚‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~~}~€€~€„ƒ‚€~}~~€€€~}}}}{{|zzyyy{€€~~~~€€~€€‚€|~~~~}|€~€~~€€~€~~~~~~}||}…“’ŽŒ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒƒ‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚‚‚€ƒƒƒ€€}}}~~~~}}}}}|||{zyyyy}€€€€€€‚‚€~€~~~~~€€€€~€€~~€}~~}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…ƒƒƒƒ…„„„„„ƒƒƒ„‚‚‚‚‚~~}}}~~€}}}}}}}}}{zzyyyy€‚‚‚„ƒ‚‚€ƒ‚ƒƒ‚€€€ƒ„‚€€€€€€‚‚€€€€€€~~||Š“Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…ƒ„…„…†…†††…†…ƒƒƒ‚‚€}}}}}}~~}}}}}}}}}|{yyyyx|‚ƒ„…‚„ƒ‚‚ƒ…†‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚ƒ„ƒ‚ƒ‚‚‚‚€€€~Ž“Œ‡ˆ†ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€€~}}}~~~€ƒ„‡ˆ„†††…††‡‡†‡‡ˆ‡‡‡†}€‚~}}}}}}}}}}}}||~~~|{yxwxyy€ƒƒƒŒ„ƒ„„„——ƒƒ„}~‚‚‚‚ƒ†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ…„„…ƒ‚ƒƒ‚ƒƒ‚‚‚‚ƒƒ‚‚’‹ˆ‰‡‰‡††„†…„„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€~}~~€‚………‡†‡‡†‡‡ˆ††‡‡‡†‡…}}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yxy|~‰–„ƒƒ„„”“€~~…‹€€€„†‰…„‚‚……‹ƒƒ……††„ƒ……ƒ…„ƒƒ„ƒ…„„ˆ’ŽŒ‰ˆˆ‰‡‡‡…†…„…„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„ƒ…„~}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|xyz{|€‚ƒƒ‚€~|~~{ˆ‘||Ž–}‚†Š…ƒƒ„‚ƒ‰}ƒ„†…ƒ…†…„……ƒ„……†„„Ž‘ŒŠŠŒ‰ˆ‰‡………ƒƒƒ‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚€‚€~}}||}}|||}||}|}}}|||{‹‘—Œz{|zzz{|yy}}~€€|{{~~}‚•‘„ˆ~|~‚„||‚„‚€‡ƒ|‚‚‚€ƒƒ„„„„„‚„ƒ„…„‘‘Ž‹ŒŒŽŠ‰‰………ƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚ƒ…ƒƒ…………ƒƒƒ„‚‚ƒ‚ƒ‚‚€€~~}~}||||||||||||||}|||~~Š‚{z{zxz{{|}{~}~}}}}||}†~}‚~~~€‚||‚€‚€~|{Š‚}€~€€€‚‚€€€‹”Œ‹ŽŽˆ‡ˆ……„„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ…„†‡„„€†”ˆ€‚€~~~€|||||||||||||}|||||||y{{{xxy{zz|‚€~|~~}€‚‚€€€‚‘€€~€~~~€}}}{}}}}}||}€€€~€~~‚”‘ŒŒŽŽŠ…†‡…„„…ƒƒƒ‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚„†‡††~ˆ•Š~€€€~€~~~|{{|||||||||~}|{||||{|||zzy{|z}…ƒ‚~~€~…‚~€~~€…†‚€~~ƒ†~|~€€€~}}}}~{|}€}~€Œ‘ŒŽ‡„††…„„„ƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}€‚ƒ††……~€€€~~}€€€}}||}~}||}}}}}|~|}|{}||z{z|}}†„‚€€}~}~~‹„†~}||~‚}}}}€|{}|~„ƒ€~~~~}}}~€~~~„’ŒŒ‹Š†„†„„ƒƒƒƒ‚ƒ‚ƒ‚ƒ‚€€}|||}~{{}w~vx~}|}|}~~‚ƒ€z}}|~€~€~~€€€€~~~~~~}~~}|~}~}}|{|||z{z}~€ƒƒ‚~|}|}||ƒ~Œ~|{{}~}~~}{{{}|z{{{€†…‚„ƒ‚€~‚‚‚‚‚€‹Œ‹Œ‹ˆ„„„ƒƒƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€~€}€~~~~|‚~~}}}{{}}|z||~€‚€€€||}|||||}|~{~{{{|||}|{{{{||zz}z~‚~ƒ„‚‚…†……††‡…„‘‹Š‹‡‡…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~€€€‚€~~€€~}ƒ||}}|}}}}{|~~~~~~|||||}|~~{|{||||}|}|~|}|{{{|y{|{|}z}~~€€ƒ‡‰‰‰Š‰Š‰…ˆ‘ŽŒˆ‰‡……ƒ‚‚ƒ„„ƒ‚‚‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€€~~~}€€€€ƒƒ€€€€€€~|z|}}~}}~~Œ†}}~{{ƒ‚}}}}}|}}}|}~|}|}|}}~|~}}}}|{{z|{||{z{{zzz{~~ƒ…ˆ‡ˆŠ‹‹‹‰‘Ž‰ˆ†…„‚‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„ƒ€€€€‚~}~€~{~’Œ|}Š€Œ~~}}}~}}~}|||}}|}|}}}~}}~~|{{{||}|{z{|yzyxy{~„ƒ„‡‰Šˆ‰Ž‹ˆˆ…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{|||~~}}‚€€€‚…„„‚‚‚€€ƒ‚€}~€~|‰‚~ƒ„„ƒ~}|‡}}~}||~|}}|}}~~}~}}}{|}~||{|}zzyyyy{{~~€ƒ‡„ˆŽŠŠ†…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{}}}}}zx‚€‚‚€€€€€‚‚‚‚†…„‚ƒ€‚„~€}~~}~€€}~„€~~}~}}Š…}~}~~€}}||~~~}€}~}|}||{|}{{{zzz{{|}~}€ƒ€‰Š‹‡………„ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv}€ƒ‚‚‚‚‚ƒƒƒ‚…†„ƒ€€€€ƒ€„~~€~~€~}~~€€~€~€|€~€~|}}|~~~~€}‚€|}€€}{}}}||{||{{{|{|||}|ŠŠˆˆ…………„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€ƒ€€€ƒ~~€}€}}~~€€‚€€€}€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{|~|}|||z|{|}‰††……‡………„‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz~}yxtt€€‚‚‚ƒ‚ƒ…ƒ„ƒƒƒ„„„„…„€€~€‚€~~~€}~€}}}~€€‚€€€‚~~€€€€€~}}}~|~~}}„€~}}}~}~~}~|{|z|{z€‡‚„„…„„ƒ…ƒ‚‚‚€€‚‚ƒ‚‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xyuu}‚ƒ‚ƒƒƒƒ…„…ƒƒƒ„„ƒƒ„‚€€€~}}~€~~~€}}|}}~€€€€‚€€€‚€€~€~€€€~~~~~~~~……€€ƒ~€~€~}{z{z|{z‚„ƒ‚‚‚ƒ‚„‚€€‚€€‚ƒƒ„ƒ„‚„‚‚‚‚~€~}~~~~}~}}z{|…„{{syz|pwuvwyutz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€€}}}~€}~~}~|}}~€€€€€ƒ‚€~€€€€€€€€‚‚‚ƒ€ƒ‚€€|{{z|{|‚€‚€‚‚~€~‚‚ƒƒƒ‚„‚„‚‚€~€€}~~}}}~}}{{z€x|vyy{qtxwvxury……‚„„‚„……†„„‚„ƒƒ€€~€€|}}~€~~~}|~~~~€€ƒ‚ƒ€€‚€€€€€€€€€‚ƒ€„}ƒ„€€‚}z{{|||}€|}}€€~}}€~‚‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxyzruyyvwwsu†…ƒ……‚„„…„„„‚ƒ‚ƒ€~€~€}}}~~€~~}|€|~€~€‚ƒ€€‚ƒ„‚€€‚€€€‚ƒ‚€ƒ€~‚‚„€€‚‚‚„‚~{{||||}}~}z~}}x~|||~~~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„‚„„…ƒƒ‚ƒƒ€}~}}}€~~~}}€€~~|~~~‚‚ƒ‡…~~€€€€€€‚‚€€~€‚~‚‚ƒ‚ƒƒ…‚}}}|{||yz{z~y|yx~{{{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzswvst†„„†ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€}€€~€}~}~€€€~|~€€~}~~€}€€ƒƒƒ~}~~~€€€€‚€€~€~€‚‚€ƒ‚„…†„€~}||||zyvyyzywyv~|{{{~|{}€}}‚~~}}|}}}}}}}|~|}y{{zy}wxxtuuxrwwtv†„„…„ƒƒƒƒƒ‚‚ƒ‚ƒ‚~~€}}}}€€€|€€€€|€}~~}~~‚‚~~}~~~~€}€€€~~~~~€‚‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{{{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvpxyrx…………ƒ„„ƒ‚„‚‚€‚€~~~~€~}~|~€€€€{€~€€€}€~~~}}}~€‚~~~~}}~~~|€~~~ƒ~~€€ƒ‚ƒƒ†„€~|}||{}xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}|{|z{}zzx{|zz{xtxuqrtpxxry„………ƒ„ƒ‚ƒƒ‚‚‚€€€€}~~€}|~}€€€€|€€~€~~~}}|€€€€€~~~~}|~~|}€}}~€‚~€€~‚„‚‚ƒ……‚‚~}|{{||yw|ywxwwx{{{{|…Š}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzzzzxswuqqrpxwq{…†„…ƒ…‚ƒƒ‚€€€€~~}|~}€€‚€€}~€~€€}~|}€€€€~~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{||{zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚‚€€}}~€‚‚}~~~€€‚€€~|~|€€€€€~}~~€€‚€€€€€€€„‚‚€~|}~~z}…~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚€€€€€€~}€€‚‚‚€~€€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€‚€€~}~{“z|}|{}y{zzxyxy{||}|||||||}}}||}|~}~~~}|z||{|}{yzzzyysuuooqpwst}…†ƒƒ‚ƒ‚€€‚‚€‚‚€€€€~~€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€}~€~}€€€€€€€€€€€€‚‚€€€}~|†‰||~{{~yz{z{Ž~wwy{|{}||||{}|}}}}|}|~~~~|z|}{|}{yz{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€‚‚‚€€€€€€}~€}€ƒ‚{~~{|}{z|||‡yxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxqvv……ƒ„ƒ‚‚€€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ‚„„€~‚€€€€€‚~€€‚€€€€€€€€€~}€€€€€€€€€€€€€€€€€~}~}~~{}|}{||xxuxxy{||}|{|||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒƒƒƒ‚‚ƒ‚„ƒƒ„ƒ€‚‚‚€€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€‚€€€€€€€€€€€€€€€€€€€€€€€‚ƒ‚‚€‚‚€€€‡~~|z}|{}xwvyyz|}||}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚ƒ„„€ƒ†ƒ„ƒ‚„€„ƒ‚‚€€‚‚„‚‚„‚€€ƒ‚€€€€ƒ~€ƒ‚~‚€€€~€€€€€€‚‚€‚ƒ‚‚ƒƒƒ‚€€€„}}}|}{}zyvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysruowqwysw{…‚‚ƒ‚ƒ„‚ƒ„ƒ€€‚ƒ†ƒƒƒ‚‚„„ƒ‚€€‚„‚‚‚~€€‚‚ƒ€€€€‚„€~ƒ‚~€ƒ‚€~€‚ƒ‚€‚‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ€‚€}€|z|{{w|yyy{z}~}||||}~~€€€€„„€}€~{{{z{ztpxrytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚‚…†„‚ƒƒ‚„„„ƒ€ƒ‚‚‚‚‚€‚€€€‚‚‚‚‚€‚ƒ‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚‚ƒƒƒ„‚„‚ƒ‚‚‚‚ƒƒ„ƒ„„„„„…ƒ„‚ƒ‚‚ƒ€€~||€||x|yzyz|}|{||}}}||€€€€€‚~€€€€{{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚ƒ†……ƒƒ‚ƒ„„…‚‚‚ƒƒ‚‚‚€€~€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€‚€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒ„ƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{~~}y|zzz}||~z||}}|z{~~~€€€€€€€€€}}|}}|vrvxxvtvu}‡‡ƒ‚„…ƒƒ„…„€‚……„„ƒ‚ƒ„„€„…ƒ‚‚‚ƒƒƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚‚‚ƒ„‚‚€€‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚~ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz{}€}||z|~}|}}~~€€€€~~€€€€~|}}~~}|{xvvw„‡ƒ‚ƒ…ƒƒ„†„‚…†…„„ƒƒ„„„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„ƒ‚‚ƒƒ‚ƒ‚ƒ‚‚„„ƒƒ‚„‚„ƒƒƒƒ„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒƒ„„„„„…„ƒƒ„…„…„ƒ‚€}‚€}||{||€}}~€~~}~|||}}~~~€}}~€~~}}}~}}~~€|}€‚‚ƒƒ†ƒ„ƒ†„‚ˆ‡…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒƒ‚‚„ƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒ‚‚ƒƒƒ„ƒƒƒ„ƒƒ„„…„„„…………„ƒƒƒ}„€}}||||~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒ„…ƒ„ƒ…~‚Š‹…„„ƒ‚ƒ…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ†‚ƒ‚ƒ‚‚„ƒ‚ƒƒ…ƒƒ……„……‡‡†‡…„„…„ƒ~~|~~}€~||~|z|}}}}}~~~€}}|€€~~~~~€‚€……„ƒ„„‚„ƒ†€‚……Š‰„„„„……‚‡††„……„…„„„„ƒ„ƒ‚ƒƒƒ„„†„…„ƒƒ„„„|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ…€}uz„~„„‚ƒƒ‚ƒ„ƒƒ„…ƒ„…†„…†}„y|~ƒ{…ƒ„ƒ€}}~~~ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚‚ƒƒ‚‚†„„„…„ƒ„…ƒ„…„Šˆ………ƒ……„†††ƒ„…………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†spurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚……‚hzrss|€rƒƒƒ}}~~}~‚ƒ‚|}€}}||||}|||~}~€}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ…ƒ†ˆ††…ƒ††‡‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vyy†s„ƒpvxqvtturstvi€nrotvnulwm{sn€‡ym}rsvsvmnwlpylu}}~€}€}€€}}|||}|}~}€€€~|~€‚€€€€€€€‚ƒ‚‚„…ˆ††€‚…ƒƒ„‡†ƒ………†‡‡„ƒ†‡ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoomw}x†pqzprtfu~n{ysoy€}}€{}|€~€€~~€€€~~~~€~}€}€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„†……††ˆ„„†‡ˆˆ†‡„††‹Š…„†‡‡…ƒ………„‚…………†……†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„qjoyxpkyszozwvvp€~~~z~}|}~}€ƒƒ€‚ƒ„€}~~~€~~‚€€„‡†ƒƒ†„„„†‡†…………‡†ˆ……†…‡‡…†„††‰ˆ…„‰‹ˆ†„†………ƒ……„†††††…ƒx‹yrˆz{pp…„x…xyks~y{krƒ‡ƒz|m{zyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozls|nw‚€~~}}z}{|}}~}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡……………‡‡ˆ†„†…‡††…„……………†‰Š‡…„†…††…††„†††††…†‡‡‡††„†…†‡ˆ‡…‡‡†ƒ‡†……ƒ„…†…†„†„ƒ„„†„„ƒƒ„„…„…„…„†ƒ†‡…†„„…‡†„„…†„…}w…ƒ„„‚}~{|{~{||}~}|~}€€}€~~~€~~~~}}}~|{|~||‰†…„†††…††…………††‡ˆ†„†…††……ƒ„…†…„††††…„†„…††††„‡†‡‡†…‡ˆˆˆˆ†„‡…††ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…ƒ‚……†……ƒ…„„„…„……„……ƒ††††…„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ‚}€{{|~{||}~||~}€}€~~€}}|€}~~~~||}~{|||{{~ˆ‡„„ˆ†††‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡…††……†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ……ˆ…†‡†‡†‡†‡…‡‡†‡……†‡…‡†…‚ƒ…††„„ƒ„„ƒ„†„……………ƒ††…†……††…„„……ƒ„‡…ƒ‚‚…ƒ„~€€|{}~{|{}~}||~}~~}~}}~~}}||~~|}€|||}|||~z{{|~ˆ‡‚…ˆ‡‡†‡††„„††‡†ˆ†„…„††„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…‡‡…‡†‡†‡…ˆˆ‡‡…††‡…††…„„…†……„„„ƒ„…„†††…†„†…††……††…„ƒ„„ƒƒ‡ƒ„‚„„ƒ€€€{{~}|||}}|||}}|}|~}|}}||||}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††„…†…†††…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡…‡††‡‡‡…‡†ˆˆ‡‡…‡‡‡…†‡„‚„ƒ„†…‡…„„„„„…†††††…‡……‡…†…‡…„ƒ„ƒƒ„‡ƒ€‚ƒƒ‚‚‚€{}~}{||~}|}}|~{||{||}}{{{}|{~|{|}}|}}}|zz{{||ˆ‡‚††††‡††…„…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡ˆˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡†ˆ‡††‡‡…‡†ˆˆ‡†…‡†ˆ††‡ƒƒ„„ƒ††‡……„„„…†††††…†‡††ˆ††„†…ƒƒƒƒ‚ƒ†ƒ~‚‚ƒ€ƒ‚|~~||}}|}}|}{{{z{|||{{{~{{}{z{~||||}~}{z|z|}‰‡ƒ†…†…††…„„……………„ƒ…†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…‰Š‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……‡ƒ„†…„††‡†…„ƒ……†††††…††‡†‡‡…ƒ†…ƒƒ‚€ƒ…‚ƒ~ƒ~~~~||}}{}}|}zyzy{|}{{{{~||||z{}||||~}|{{{{|{‰‡„†„†„††…„…†…„„ƒ„‚€ƒ…ƒ‚z„Œ{€„…‡†††…„‡ˆ‡†‡…„‡Š‡ƒ‡…††ˆ†…‡„†‡ˆ††ˆ‡‡‡†‡ˆ†„†††‡……‡ƒ„…„†††‡…„„ƒ……††‡††…††‡…††„ƒ„…‚‚€ƒƒ‚‚}€~ƒ~€||}}~}{~}|}yyzy{}}zz{{}|}||z{}||}|~~€|{{|~}|ˆ‡…†…‡„†„……………ƒƒƒ€‚…‚€€}|{„…††„…„ƒ‡‡†††…„†‰†‚†„†††……‡†‡ˆ‰†…ˆ‡‰‡††‡…„†……‡…„‡ƒ„…„ˆ††‡……„‚……†…††‡„††‡†…†ƒƒƒ…€€€ƒƒ€|€~~‚€}€||}~}~{~}||yzzyz}}yz{{|{|{{z{}}|}|~~|{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€€ƒ~~~€yz}€ƒƒ…‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ……ˆ‡‰‡†…†…ƒ†„…‡ƒ„†„„…„‡†…†…†„‚……†††††„…††……†‚‚ƒƒ~€€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|z{{{|}}}|€~}||}~|{‡……††††„…„…ƒ…‚€€€€~€‚‚}~{‚ƒƒ…†…„ƒƒ†ƒƒ„‚€…‡…‚ƒƒ„„„††‡ˆ‡……ˆ†‰‡…„„„‚…ƒ„†‚ƒ…„„†„‡†………†ƒ„…„…†…†„ƒ„……ƒ……€ƒƒ~€€ƒ|€}}‚}€~~~~~}}{|{zyzzyz{|yzz{{{|z{{{{}~}}€}}||}€}|†ƒ…††††ƒ„ƒ…‚…€€€~€|~~€€‚‚‚„…ƒ‚‚„€ƒ‚€„……‚€‚ƒƒ„……‡†…„†‡…‡…†‚ƒ‚‚ƒ‚‚…ƒ…„…†„††‡††…‚„„ƒ„†……ƒ„ƒƒ„ƒ…„€‚‚}~~~„~{||€}€}~ƒ|~~}}~{~{{zyzzyzz{yzzz{{|z{|{{~~}|}||}€~€†„……„‡„ƒƒ‚†‚ƒ€€~~€}|}~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡†…„ƒƒƒƒ„†…„ƒ‚ƒ‚„ƒƒ€€~}}~~|~ƒ~|~||€~‚~‚|}}|||{{zzzzy{zzzyyzz{|y{}{|~€}~}}}€€€†„„…„…‚„‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„…ƒ‚ƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚€…ƒ~€~|}~}|~ƒ}{~|}€ƒ}}€~}|||}{{zzzyy{yzzyzz{{{z{}||‚€~€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌËËËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFK=8765999<>9?<D:;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÔÓÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937677=;>9=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<9<<98:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA><A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËÊÊÊËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÔÕÔÔÔÕÔÔÔÔÔÔÔÓÓÓÓÔÔÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9>CE?<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÐÑÐÐÐÐÐÑÑÑÑÑÑÑÍÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø×××××ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÛÜÛÛÛÛÜÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÜÜ×ÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILO@99:4;A<7=9AC>@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌ͖„†††††‡‡‡‡‡‡‚²âÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¹´ŒŒŒŒŒŒŒŒŒŒŒŒˆ‚ƒ‹ŠŠŠŠŠŠŠŠŠŠŠ‹‡½æáââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVN<::77>C>8>:??A=?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÎnPSSSSSTTTTTSL óëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§£££££££££££¤œZUVVVVVVVVVVVWNCCCCCDDCCCDDCFSSSSSSSSSSSSSKªòëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;?C>6:7>>;=B?9<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÌÎqTXWWWXXXXXXWP¡ñééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤¥ž_YZZZZZZZZZZZ[SHHHHHHHHHHHHGJWWWWWWWWWWWWWO«ñêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;?@@8:;8<;;<?:;;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÎx^a````aaaa``Z¤îççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©ª£hdeeeeeeeeddee]STTTTTUTTTTUTV`bbbbbbbbbbbb[¯ïééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB>;=:9;:==;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÇÅÅÅÅÅÅÅÅÅÅÅÅÄËÐÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÏÎÎÏÎÏÎÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÑÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌËËËËËËËËËÊËÌËËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÔØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<8@B<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÏÏÏÏÏÏÏÏÏÏÏÓÏÏÎÌÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÐÔÒÏÏÎÒÔÏÎÎÓÓÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××Ö×××××ÖÖÖÖÖÖÖ×××××××××××ØØ×ØØØØØÙÙÙÙÙÙÙÙÙØ×ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?79:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÏʖ¥ÑÏÒ¨ ÐÏѤ¡ÐÎÎÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<>B>BC@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÏϜª¬Ö²ž£§Ö¯Ÿ¡©ÒÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?>;7:>9?D?A98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÐ˔ˆšÈžš“Àž˜•œÈÐÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<<:6?B@B:647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÏѽș›¬š¡œ´˜œ¢°²ÓÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8FA?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÏÏҗ”¢­š–­¹†ž–¯³ªÕÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<>=964:99::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÏÓ³›Ä­˜ –x›„“¤ÕÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:<?>=<9@<<::9?@>=<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÐÑ΍£œ¨ˆœyŸ©…™¤ÕÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CFCAB8;?<=;<<8558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÐÑËÚ¨œ‘¹¯¦œŠ½­¦˜¯ÖÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF@HIGE@<<>><=><756:969;::;8@?:<<9<>=;;:?9?:;9=>=><;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦ÕɎ¥š ¥¦——¥§–˜›»ÕÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;557<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡Ê»¡¦§œÍ «¤›ÐŸ«¤œÑÓÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKL@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÓӞ¶×Ս·×¼ÕÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<=?GFGKH=657:979:;:<=9>99:8;=>>A>=9<<:=>>:=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÒºÄÕÑÔÇÃÕÑÕÅÄÕÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?AELLA>775;8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÒÕÔÒÒÒÔÕÓÓÓÔÔÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEJ>>786967899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9699:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EILAALD??;9889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEHIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDJ;AA;<886486987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGJB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJC<BA<;876797799=?A?<:9@?<>B?:8776=??@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE>;HF89757875898;>>=;89A>=@?A>7596;>AB??@@AB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCEEC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELCA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<<DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGHNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAC?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€iixsg~‰‰xp‚†{w}~…Š½ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€‚wt|„‚}sp€Šx‚yƒÈÞÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsoupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿¼½¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»º¹¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjcmgb\XQPQKTJB:IQ?A7<94:565455688686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸········¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µ¶¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸¸·¸¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶·····¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨¨¨¨§¨©©©§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸········¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥£¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§§¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©ª««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤££¢¢¢¢¡ ŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž£¤¡žžŸ  žœžœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=7789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥¤£¢¡¡¡¢£¥§¦¦§¬¬§¦ œ›¡¡ž›ššœ™˜ššššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¥¦¦§§¦Ÿ›š›¢ ™––•š›š——˜˜šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜—™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥¢¢¥¦¦¥¦§¦¦ ›™›¡ —““’—šœš———˜›š™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB@DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥¦§¦¦¢œž¡Ÿ—‘‘”—š˜–—–˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;<;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¥¦¥¥¦§¦¤¥¦¦¥¥£  ¡¡Ÿ™’–š™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šžŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡ ¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢¢¢£¤¤¥¦¥¤££¡¡¡žœš•“”˜›š›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œ ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸŸŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::88:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸ   ¡¢£££££¤¢¡ ž›™™˜™™™™™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢ ›ž ¡£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œž››œŸžœœœœŸ   ¡¡¡  ¡  ¡¢¡¡¡¡Ÿžœ›ššš›œš™š›™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥¤¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¡¢¢¡   ¡¡ ŸŸžœš™š›››œ›š›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›šœšš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>98;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤¤¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ žžŸ     Ÿ ¡  Ÿž›š™šš›š›››Ÿžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›ššš›™˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9;;>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœ›œžžŸž›šš›œœ››œœžžœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:=>:?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››š›œššš›œœ›š™œœœžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™˜˜ššš™™™™š›œœœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›š™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š››››œ›˜˜˜™™˜˜™™˜›œœžžžžžžžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ›››››››™˜˜˜˜˜˜˜™™œœœžžžžžŸŸžžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ››››››š˜˜˜˜™™˜š›œœžžž  Ÿžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_^]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜™——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜˜˜——˜™››œœœžžžžœ››œœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±³­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=:F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œšœ›œ›˜™š˜˜™ššš–‹“–™˜•˜˜–›œ—•’‘’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨©¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‹‘‹ŒŽŽ‹……‡‹ŒŒ‡ˆ‹Ž‹‡Œ…†‹†ŠŠ‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VQQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹‹†Š‹‹‰†„†‚€‚‰‘ƒ€ƒŒ†‹‰…€‡}€’†„„†ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹‹‰‰…‚}s}ˆ€~œ„……‰‹Šz}}†ŽŠ†”‘‹—”—’˜¡–ž—•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¥›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ†‹†ˆ…„ˆˆ‰„‚z||}~’ˆx…‹Šƒ„…ŠŒ‘™””” ššŸ¢­±­©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPEMISWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~‰‹‡Œ‹Š‡’Š‡†‘“‘‘„‡}}ƒˆŒŽ‹ŽŠ‰Ž””˜‘•›š¨®²¯¯µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWLO_^\NUUbQDTM;?9<895775795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš˜ “—š ™›¢¡•› ¤£š“ˆˆ‹‰‘‘Ž‘Ž‹˜šŒ”š—œœ›Ÿœ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUKTOOJCPK_bXZQ\T`MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ª©¨§¡¥¨¨«ª©¯¡›Ÿ¡££ šŸ œ”˜”˜  ¡¤ž›š¥§¤©«®¬¥£¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdWOXKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®¯ªª«¤¡¢¤©§¦©¨£¢œ››¤ ¥¨£ ˜˜Ÿ¡¢©§ ¢¢®¬«ª§­®¨¥¤©©©©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_UZNRNPORd\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢šœ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨§¥§©§©¨£§¦™œ¤¦¢¡¡¡¡ œ˜™Ÿ ¡¤¤¢žž– ›š¢¢ ¡Ÿ¡¢¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]\PUOWO^ddlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§¬©¤Ÿ¢ ¢¦¡¦®¦¦ŸŸŸŸŸ™šœœ¡ ¡¤Ÿ¡›šœ ž¡Ÿžž £™–š˜¤¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvwb_\UYQUW[c^s_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?C?:8:>?C@DA:;>=@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯ªª¬¨¨«°©¨ª¨¡Ÿ §©­°²¯¬£¢¦¡©¥ž¤£¢¦ ¥¤¢¥£ž žŸ¥¢¢žŸ¢˜•žšžŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸ ¡¦¢›—’šš •|wo}yf[Z`_Z\V\hdncnjib^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¢ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶¯³°«±²±£Ÿ¢ª©§®·¶´´¶³¯¬«®«¶°©²±­®§¦ž¢££›œ—¢¨¥¡Ÿž£›¡š–¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¡™˜¥ ¤§ª©¨ª­¬¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvyjb[_^\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>AE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢œŸª²¸¼¼½»º¿´¯±³µ´··¯µ´µ²°¨¤¢Ÿ —•š—¤ª¦¦¡¤£¤«¦¥™¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨¨«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥¡¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxxxc[RYT__amhukqhiiaYSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶´º±ª®´±°±´µµ¼¼¾¼¼¾Æº¸·º½´¯µ±±º¸·²³²ª¦¦Ÿ˜¤¤§¨¤®¤««µµ¯³ §ª¬§ª©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš’–””˜“š˜Š‹‡€€|‚xa^YTai`fsositdidb[LK>:8898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÃÆÂù½¿ÀÀ½¿Ä½¼º½¾´§ª˜±À½¸µ¹À³¯¯ªª¨­§§¤¯§ª´¼±´µ¨¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`a^^kcbnwuvnl[bQV\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAA;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–••‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±°§¼¼¾ÅÄÆÉÇÅÆ»ÄÀÅÆÀ¹¯½¼À¾¾³«ªŒ³»¾´µ·Âº­¯°µª«¦ª£­¤§±¶«µ²­³­¨®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|ƒjfhakmfnuqruqg^_\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÅ¿ÃÂÆÅÀ±“¾º¿Ã¶¶º©´³´©«³»»±Ÿ›±¯¬¤¬®´§ª©¨ª­¬©¦¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|tklndomiqxnyiia\gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÄÄø´À·´¼Á¹··¿À»®¥®·¼·­œ£·°¦¬´µ¬®¥¤£¨¤  ¥™ª´±¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyz{vnkiguZfrxsyfg]d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÊÆÄÃÃÁľ¸¾ÁÃÀľÁÏÏÎÆ«¯¶´µ« §´³®«¸µ³¬©£¡­©¬¦­Ÿ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuueeijg]jomxwcb``^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÏÏÌÃÇÆÈÉÈÈÉÇÅÉÇÈÇ¿ÅÇÄÄÇÈÊÒÏÒ̼¸¶´¸¸Á¾¾º½º¼º¼¬­¦ª»º¹·À²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqocaguhjitmxl]d[U`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÌÐÍÇÌÉÂÂÇÁËËÈÆÌÊÎÅÆÅÃÆÅÉÍÐÍÏÌÇÄÀÃÂÉÍÇÅÁÄÇÀ»¾´°°°Á¾¾ÁÆ¿¾¸¶Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`jjvlieuntb]bTWUSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<9>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÄÇÈÆÒÉÁÂÿ¿¾ÄËÈÊËɼ¼ÈÈÉÍÈÃÈÉÉÅÅÃÂÁÂÇÇÉÊÇÌÈÇÈÍÆËÏÅ·À¿ÀÀ»º½µ³³¿¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrpfefcjdajmno^Y\VVNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾƹ»Ã¹¸¹¼½ÁÇÁÆ»¸ÎÝÎÃÄÀÃÁÂÁÃÂþ½ÂÀÀÁÂËÃÆÌËÅÈÑ°¾¾¸º»»¾·´°¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfadbacdcjbgc[ZZ\YQOE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶¸´´µ¿»½¿¹¾ºº´À¸µ·²®º»¶À·ÀޞÂ¿Á¼»Å½»ÁÄÀ¾¾¸¼ÁÁ˾½ÉÄÀÀÊÀ±Á¿»¸»¾¹µ·´¸¼´½¸µ´°³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|yˆ}qc`bbgjgfiei^VVTYOSLF8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“““˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´µ±°µ·µ»Á¸¾¹¿¼¼·´·¯®·´·¿ºÐÃ}†Ê¾ÃµºÇ·¶¹»½¹º¶»ÅÅʽ¹ÅÀ¿¼Á¾¸Æ¼Â¿¼Å¸¶·´¸¶¶»»¸¶´·ºµ´¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒ€xqmeefoiekhXXNKKKRILHC9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’™”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿¾¼²­¯¬±°·¼·»½ÁĹ··¶µ¹¹¹¹¿¿×w©ÄÇ·¹¸®·µ¸º´·³»ÅÆËÁ¼ÆÀÀ¿½¼¿ÈÃÅžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~‡|knpgpksfam`\TIKJDJBCG?:;8><7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘Ž˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼¼À·ª­¤®°·»³½¾»Ä¶µ¸·ºÃ¿Å¼ÁÎĀwy”ÆÏÂÀ¸¯µµ¼¾¸º²¾ÄÄÊÅÁÉÿ¿¾½ÇÌÇÇÄǽµµ¶Á½»»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†qflintnxcgb[cQKTHEECHC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?>??FD@A?>:7?@CC?@=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼ªª£°¹¾¾²¼¾¼Ä·²º°£§¹³½ÇÌ¢tyz—ÏÑÌÊĵºÀÄÈ¿¿µ¿Á¿ÆÆ¿ËÆÿ¼ÀÃÌÊÇÅÆÀ¹½¼Ä¿¿¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtolltkln_b^`bNIM?E@?DC;;::;:8;<:9<>9:>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±³ÀÜÛŹ¾¼Ä¾¸ wkoqk€•¸‡s~™ÊÌËÍÊÆÂÄËÍÅ¿¹½¹¹ÀÿÈÆÄÁÁ¿ÅÀÊÉÃÃÄùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{zˆzmmw{_pc[]__TI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA??ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸µ¼¶ÁŠ­Øľ¶À¾}dZgRNX\v|t~‚ŸÃÆËÈÁÃÁÀÉÊÈÁ»»°³½½ÀÅÆÅÄ¿ÀÁ¿ËÇÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}znsxsgp][^]YRFDCMIAE=H;;59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘—žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯··²µ³·¹¼»¶ºÀ·en¦ÉÀ¶·†b`fTd]NNQTht{ˆ¤¾¿ÆÀ¹À¼¾ÅÄÀµº²°­¿¹¿ÃÇÃý½¿¿Ãþ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸¸¸½¹»±¶²ÈÀ»¶´±°·¬³©°­­´·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y}vlu{pni[_`YSPAFHGK@DCH<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿš›œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¸Ëµmgo˜µ¸„YNFfLOtj`OMXtzŽ¬¸·Âº³»·»½Áµž½®°°¶³¹ÁÂÄþ¼¿»º¸¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ¯µ´´½º¾¹º»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰|‚zsuvwnq`_f][TJ=??FF=FCC9:5;99><<::<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¸Í¶yuesœ¢^NGUzLHf~”ƒ[Cu‰™«±·¾¹²µ²¼¹¿ªˆ¼³³·Ÿ¨¸½ÃÆÄÀ½¿¹³¯²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtwrl_ca[^OHB?=HCFMC@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³¶Ç³€yql‹vQEGtMNO_ŠpFR~¦´°¶ºµ´²¬¼¹¾Ÿw¹¼¹·v”½¼ÁÇÿ¹ºµ®¥¬³°¦°­¨ž Ÿ¥­¶µÂ·¶´¥¨«¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´·¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wo{ourmc]fX\]RNNA>JBAJI@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³²­¶º¯­¼³·½¹‚zzydKG{|aMIQe§¥aNJp®»°³µ²´¯¬»¸ÁŒo­Å¸­\v¹¶¼¼¸¶²±­­Ÿ¤§§£¦–™™šŸ©®¹¬««Ÿ¥¨¤«®®§¯¬¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmtil][jT]\PMHDFLBFNF8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹º¶¹»µµ³¿‡‡‹ˆZDv—r[ZI^`R‘qnm Á¸³´²°±­°¹¸¿rg Â²°§¥±®¹®ª«­¬£¨¡ž—˜¡•’•—˜Ÿ¨®¤£¤ ¢§¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬ª¯£¤£¡© ›“Ž“’’™–š¤¥ Ÿž§˜•’”™ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wrxhtsndT`cW\QNLH@HQDMC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯¶©–“¨OJ}³ljq]k^uqccn‡±¹±­³¯®¬­¶·´]ƒ¥«¤žœž¨¨ž ¨©Ÿ¡§–›——“–Ž—›¤¨  ¢¢¢¥¥££ ž¥ ¤¬¤¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›©¨««Ÿ¦¢›£œ•Œ“—•–˜Ÿžžš˜¦—“’–¢ ¥¢¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦ ˆxƒ|vzcwln\QhTPNGPMLBOQ@>;>39:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¤¬©³³¢­•LTr¦st}ŒsNnmeppn“¨¶ª²´®ª«¯°°¡±¦‘˜”˜ Ÿ¢ œ¤¥Ÿž¨”›–—Œ—‘—“˜¢ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£ž™—š«¦ª±£¥¨ž œ•“‘˜–•˜—Ÿ˜›™š£™—”–š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’}|€uv}mk{dhUQcMJHGORMJNG<E@<2?859;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜——–¡¨¬®¶·º¹º··»®¨ ¡¨ ­Á¿¨WZxunqZ_db\Y[ilbfsƒ²¯®³µª¦¬«£ž™”‘–—™™œ ¢¢œ¥ž›¤———–’‘‘“š—› ¤ªž¡¡ž¦§ª¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¡¤¡›˜ž¯¨®²«¥ªª š˜˜˜•“–š“••š–›——˜¡žœœ—›¡šžš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}wx|dyy`bRU`HIJKSTIRPL9?B67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—“’œž¤¨®­¬««¯ª¯©ž—ž¥ž¿·xcr|fgeWZZQJGKOPLUb_›²°°¸¬¦¡œš”—ššŽ‘•‘ŒŽŽ”™¢œ—£™š—˜™”™˜–›Ÿ¥¦© ¦£ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§  £±®²°´ª²®¢™œž¡™››š˜™›”–›–™œ¥¡ š£¡šœ™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ Ÿž ¥¡žž¥ ¦™{|vvsh‚le[SZZMQJNOULSLA7>B78=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’‘œ˜¡ª¢§ ž§¡¥Ÿœ’›¢šž©§‡aXfh\NJFD>@BEBCLVO}±­¬¯§Ÿž¢ –“› ›™—’“Ÿœ¡¤›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬¨¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½·¾°¬±®­©ª´±°¨«¨²µ·³¸­²´¤ ¥Ÿ¬¡¡¢  š˜–– ››˜¤¡ ž£¡ žšœ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚|xuiwu]lZR`HRUHFUVJBLG=KH8F<77;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“Ÿ™¨®Ÿ§žœ¡žš™’˜ž›¡¡ žcefXJBIOfRKAC>@FIH_£ªª©¤ŸŸ™’‘“˜˜––•Œˆ‹Ž•ž—ž™¦Ÿ ¨¥±ª§®£«­¶°´²±®¶¸½Àº­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«¯±¹·¼¯³°µÁ¼·½³³µ¢¬¢©¨²©«¨§¨š™žšª§ ™§ ŸŸ§§¥¤Ÿª¢¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰…„~vrmivmhm\X\CWNJGMGBFM<>L=4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜™ª ±¢·¤°¦Ÿž—˜•™žšœ£ ‹wk_RKCDV‹hF=::98Q…ª­©ª¥ŸžŸ¢£žšœ›”“•”žž˜”†š¡š«¤¬²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶º»ÀĹ½»¬¯§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¹Â¾¸³»Æüü·³©³­ª³µ¯³®ª¯£«§¶±­¢¯¦¡£¯±­°¤¥¯£¡ š¡§¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¥ž¦™›¢¤žŸ›››œ‡…{trkktrqhV\QFTHDJPI?EA4FG95;>7;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž  œœ˜šŸ šŸŸui^TJFDFg³ÄÁ]PIBO{ª²§££¡ ž¥«¥ž—œ”‘™˜”ŒŠ†ˆ†xmˆ ¤¢««³¼¶Ã¾¾³»ÁÃÂÅÀ¿ÂÆÆÅÃÈÂÀÅÇÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌÌÌÒǾ¿À¾ÇÆ·ÄÉÉÃÁƾº´ººµ»·°µ²ªº²®»·¿»ºª·­«ª¸º´¼®®¹£¦£ž¦¥¢£©¦™›Ÿ˜š§ª§ ¡¡¤˜”£–”™‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ„}zqkchoxkeZ[FKLEDSMDBE7:?;549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ²²¸§¡¡«ª¡œž¡¡œ—jWNKIHHS}ÑË´“œŽ‚–¯­¡™››žž™———’ŒŽ–—“Ž‹‚ƒ‚wsqnqŽ¥¬°¹½Å»ÍÇË¿ÂÌÎÍÌÇÉÑÌÍÌÇÉÅÅÌÑÒÕÎÓɽÀ¿Ã»ÆÅÈÅÑÓÍÓÐÓÓÌÊÂÅÆÆÊÈοÈÑÌÇÅÇÅÁ¼ÃÁ¿¿¿¶¾³®¿ÀÃÃÇÄÇÄ®¿¸²¸¼Ãº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›Œ™‰•˜› Ÿ£—žš““‹•…€ytsebgrof^ZYCNLDEPIDC@5558:B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>8;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›¢¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¤¨¬­ª £žœž“\MCFIIYf’º¬ƒ´¹±¬£žœŸš—–”’”–‘Œ‡ƒƒˆ‡ƒ€€yrrplx¦ÁÊÊÅÊÁÓÒÓÈÍÎÑÓÑÒÑÐÑÑÍÎÎÐÅÎÔÕØÒ×ÍÆÇÉÌÃÅÊÏÊÓ×Ñ×ÒÕÖÓÔÈÌÆÌÍÉÒÍÎÓÍÅÈÉÊÁÆËÇÉÉƿó³ÈÄËËËÏÆÊ¿¾¿½ÁÇÄÌÌÈÉÀÿ­¯³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›•Œ†‘‹€zruvgcgvidVWQDMF@IQB=B<:22A<E<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<A?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­³·¬®£ž£¢¡ž^H>DEWf†¬Ÿž¡­«£œœœ ¤¡š”“•”‰}wpkebhqoq{…Š€vpnqsoˆÃÏÍÈÑÐ×ÖÖÒÖÍÔÖ×ÔÓÑÓÔÔÓÏÑÃÐÓÖØÕÖÒËÉÎÑËÆÍÒÊÒÕÖÙÕ×Ó×ØÎÒÊÏÑÌÏÐÌÓпÈÇÊÄÌÌÌÎÏÅÆǶ¿Ê¿ÒÍËÏÆÉÈ¿ÄÃÇÎÍÐÑÏÍÊÈ͸·»¨Ÿ¥«§ž˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„|xsvpc`drb]R\IJGAEIJ>;A8=4586;86:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÁűµ¨¡¤¥ ¡©pGEEHb„¼Äª«ª›”—Ÿœš  ž›œ™•‰wic`__`_^__]blusqpolrqu½ÉÅÔÖ×××ÓÖÏÕÔÚÔÔÎÏÕÔÔÑÑÌÑÍÓ×ÖÓÕÐÏÒÓÑÉÓÑÈÐ××ØÑ×ÒØÙÔÖÌÏÏÊÍÑËÎÐÀÆÃÈÆÎÍÑÑÑÈÌÍÀÊÌÆÓÎÌÎÈÄÊÇÇÈÌÊÔÔÑÕÏÒÌÓÁ¹Å±¥¨µ®§›¨¬¥²¨°³¬¬““ŽˆŠƒ‹„Ž™“™‚…Œ|zqstmacim_VP_JJCFCRM?<>54:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><??=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯­ªª«¦®·¨«·×ÔÕÙÙÑÎп¼Ìɶ¾®¦ª¨¡£¯‚bkjzœÂ¿®¨Ÿ—•—™šœŸ˜œœ’}pecb__a_^a`_``_`fmppnkorww™Ê¿ÒÕÓØØÖÙÑÒÒ×ÏÓÎËÒÍÕÔÒÊÏÌÓÖÒÑÖÍÏÕÕÑÅÑÔÊÐÔÕÖÎÒÐØØ××ËÈÎÄÉÏÍÊÌÀÉÀÈÊÍÎÐËÐÍÎÌÎÏÈËÐÐËÎÊÂÉÇÉÌÊËÒÓÍÓÑÑÐÐʽȹ°®»¸µª¶°­¨¸­³¾»±šŸ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…ˆzvopokadnpaW\ZIFFDMXE;@=33<<87865;>@=9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ¤§Ÿ¸¶µµ¬¤¬®¾´°ÀØÒ×ÚÜÖÎÍÊÃÒÏÁÀ°©¬­©§–{ˆŒ©Íα›š•”–›žžžœ“–—”ˆk^^^adb``aa``a^__^]bmroostuvy¤½ËÕÐÕÓÓØÖÎÎÔËÍÎÅÎÊÒÒÏÇÎÍÍÔËÎÓÍË×ÖÐÌÑÔËÌÐÒÓÊÎÑÕÒÕÕÊÀÊÂÅÌÂÈÉÃÌÃÅÈÊÊÏÊÍÌÐÍÓËÆÈÏÍÈÇËÅÆÁÆÊÌÍÐÑÆÐÎÍÍÌÏÅÇÁ¸¹½Ãýø²²¾±»Ãõª˜¥¢™–‘••’‹”š‘”””‚‰†yqrkmg``phXXhVLFLIPQB;C>;67:8::57==A;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÄÂÁ¿»µ²±Ç¸ËÕÕÙÚÛØÌÌÏÈÖÕĵ¯´¨ ®xeƒƒºÎª”Œ—•“‘‘•–•‹|eabb`]^aca``_`aa`_][]grqqrsqnry£ÅÒÎËÐÏÓÔÊÅÉÉÆÆ¿ÃÆÏÎÇÅÇÍÊÒÈËÎÎÆÑÒÐÍÌÔÊÇËÎÏÈÇÏÒËÑÏƺĿÆɽÂÇÉÎÅÂÈÀÇÍÈÄÌÊËÏÈÄÄÐÈÆÂÆÈÄ¿ÁÇÌÌÌÏÂÊËÈÇËÐÄÅÇ»ÇÃÈÉÂÏÀ½¼¿°ÁÉƹ½ª°²§¥¢œ˜›£™—™‘•˜‰‚wotdk`^fpa[W`GHHGIMTG?J=64355==48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ¼ºÍÍÆÐÕÕÙÚÛØÐÉÏÏÑÓȶ»»­¤°ff|ŒÑ«Ž–†ƒƒƒ}„„~s`[^^^`^`cdc_]]^_``_[Z\akrrookloo}·ÐÇÉÊÎËÍĺÀû»ºº¾ÉÆÂÃÀÃÈËÉÈÊÈÁÅÌÆÈËÍÉÄÂÊÉÁÂÌÐÅËÈ¿¹Á»ÆȾ¿ÆÏËÿûÉÇÈ»ÈÆÅÊÀ½ÂËÆÅľƼ¼ÀÃÅÌÅżÀÊÂÅÇÒÅÀÉ¿ÊÉÆÈÆÐÃÃÆïÄËÇÃÊ·¿¼º´©¬¤¥˜Ÿ˜¬£¡¥›£ ›”{wrtfiZanlZ[XRDLFBGDLDFS@54334?=3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ÊÏÑÌÇÂÃÆÍÎÎÌÕÏÕÙØÙÏËÒÍÍÎÈÁµÃ¾²²¤]js¦¸ŽŠ’—†z€……vxurp_[[]``bcdded`\\]]_^`[YZ\borokikporÅ¼ÉÄË¿ÆÁ°¶º²²³²±Â¼¼¼º¸ÁÁÁž½¹½¿¹ÄÊÅƽÆÀ¸»ÄÉ¿ÁÉ»·»»Æÿ¼ÁÍÃƾ¾µÁ½Ãº½Æ»Âº³¼ÅĶ¿µµ¾¿»ÌüµºÈº¿¾ËÄÁÆÂÅÉÆÉÆÐÆÂÌDzÇÉÃÎÍÀÅÃÀ½³·°²§¨¨¹°¥­°ª­¬”zvwjdg`hocV^YJFJFHJAEBEI@9:648854;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÅÂÄÈÎÒÊÊÊÇÍÍÎÑÈÐÆÕÔÖ×ÍÊÏÅÉÅÇÀ¹Å½«¯’]nv¨’‹ˆ‹…x€††~„{ttc\\]^``bcbbeeb]\[\^\^]Z[\^hsqmggnorxœ¼Ë¿ÂºÀ·®°±§ª­¬§¸µ·´³³´»µ¾²·°µ¯²¼Â¼ÁļÀ»µ²º¾À¸Ç¹´»¶Á¼¸½ÆÁûµ¯²¶º¿´Ä·»´«¸½½À½±º¶°¶º³Å¼¶®»¿µ·´Å¼¾ÃÅÀÃÅÆÈËÅÀÆÆ»ÇË¿ÏÉÇÃÆÂ÷ý½¶¹¾Ç¿¬µºµ·¶Žytxggebkn^V^`FKHHJFBDAEE?<:565633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÍÈÅÈÍÌÐÌÍÈÊÈÊÉÊÄÐÍÒÏÍÅÇÁÅÀ¾¹·É¶ª°ˆ^q—…ˆ‰{x~††vw|sh]]]]_`_`da_cec__\[^\]^Z\[]_kpnifjmnr{¤Æ¾¸·´¯«¬§ž¢ª§ž«­³­ª¬©´®·±²©®¦¬³¼º¶Ã¹ºº±«µ¹»´Âº°À±¾¼»¶»Ç¹Â¶­ª¨°²À¶¸½°°§²³µ»¼«®µ¦®¶¯»²°ª¹°­»®»¸»ÀÀ¾¹Â¿ÇÃÅÀ¼ÆÁÇʸÅÇÅ¿ÇÄúÄÆ»ÆÉÌ˳¹Â½»³‰svvki`blhYWW[ALKMIEAC?FA:9:995854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÅÎÒËÃÅÁÅÐÇÍÁÃÆ¿ÄÄÃÃÊÁÉʾ¿¼Àº²´´Ã®©°Œhl„’‡Ž{x~Š…z{„€wn^]\\]_`__dcbccb`_]Z[ZZ]ZZZZ\dnohghiknq¬¸¯´­¥¤§§š ¥¡šœ¥«®¤¨¢¬ª­ª°¤¦Ÿª­µ¶±½¹¯·¯©®¸´´¼¸´¼¯¸¹µ²»Á²À®¥©£«±²³¨½ª«¨«­­´³¦¨®¡¤¯©²¦§¨®¦¨·¬±²·ºº¼±¼½¾¾Ä¿µÂÁÇÈ·¿ÀÅ·Äÿ»¿Ä¾ÄÈÌÊ¿¾ÄÀÀ©‡strji\aodWVXPHYRSKFFE>>@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÐÏÌÃȺºËÁʾ»É¶½Ã¾ºÉ·ÁÃÁ´µ»µ°®´»­§©i`†„‡‹€{}~xt~|swe_]\\^_`^_ccab`a_^]\ZXY[[YXZ\_fkfegehjor…©¤ª¥ž›¡¥”ž¤›˜‘¡£ª££ ¦¥¨¥­ œ¤¦¬²°¶·§°¬¨ª´«´º±¶¶®¶¹²¯ºº±¶¤ ¤ ¦±§«¨¹ª¤§§¨§²­ §¦Ÿ›¤¦¬žŸ§£ ¡±­­¬²´³´°µ¼¶»ÁÁ²º¾ÃÁ²¹¹Ã³Á½¿µ¸¼½¾¼ÂÇÄÂþÀÄ ƒxqlaf_ko`TY^HNgOTGEKF<=?=:;;825536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;=:7676788666;::;9:;<859<:>>@;Èµµ½¸ºÀº½µ ž•¡¦º¶«³³»³ÄÏÈËÂƸ¶ÇÀÌ¿¸É·»Å¸³Ä¸³¾À«µ»±«¤®²¬ ¡do‡…†€|yusomjjipi^`]\\\^__acb````]\[\\XYXXXVX[^_dcbegggjmo‡œ¨Ÿ••š¡–œ¢™–Ÿ¡£§œ  ¤¦¢§ž›¢›Ÿ«°­±¶£©ªª¬¬¤´¹­·°¬³µ®²µ®°ªŸžŸ¤¢²¤¦©¸­¢¦¦ ¨¬«™Ÿ ž™Ÿ¥š™£œ›¯©«§ª¬¬­±²¸¯¸¹»°¶¼¼º«³³¹³¾´¶²±¶µ¿¶½À½ÃÁ»»½—„zsl_e^ddXTW]IW\KPGIJGA<??@;?<04535:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»·ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÆÏÈÈÀÆ»»ÃÃϾºÇ¸·¾·²Á´±»»«¸¹°¡ž¨ª¦—žf~…†xrmomkb^aff]]^]]]\]_aabccba_\[[ZZYXXWWWXXXZ^bddeffhikqŒ§œ“””›˜›¢—–‘œ¢¢©žœ¥¦¢¥œ  ›™®®®®² ¦¢®«§¢µ±²²¬¨¯²§º³¦µ ¢Ÿœ£¡­£¢ªµª¢£¦ž¥¦£–™ž—™› š—œ­¢«§¤¤¦­«³´ªµ°³«²¹´¯ª¯²²³¸³®©¬®²¸±º¶º½¿·³±”…yuf^e^[YVSZUK[QKIEHKIB=?AA@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½·½¿¶¾¼¿³¥£˜¥±Âµ¶½­´¸ÂÌÈƿŶÁÀÆηÀĽ³¹¹²¿¶±¸º¬±´­ž™£¨Ÿ’š‡nƒ„xoqtqhechdc\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXWVWadecdeddhjv¡›“”•—— —™•— ž¡–¡¡©¤Ÿž¨œš«§¯°«›£¤¸ª¡ ®¨¶ª¦§­°¤¸°¤· ¢œ™™ª¦¡š¬¸¯¢¡¤œ¢Ÿ “”¡”––›˜—–—œ•Ÿªž©¤¢£ªª°®¨´«ª§­³°¥«®³±°¯®¯¦§§²­±´°¼´¹·®£”yud^aVYWSRTKM^LOKGGLLE=A><B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾¸¼®§¨£ª»À½À¹®´¸ÁÌÇÅÂýŸÈ˲ÁÂÁ­¼»´»¼´¸¹¯®¯¨›˜ §“Š€|€|wqilrtphhedfb\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWWV[bcbbcbcdfi–“•‹’””œ™––œ œŸ–¡ ¦¦¤¦§ŸŸ¦ ª¯¦Ÿ¢¤·¨¡¡¢¨´¢¥¨¥°¥±®¬µž ••©¡¢”­±±Ÿ¢£ž˜›“‹¡”‘“˜˜’——˜—ž§œ§¡¢™£¥¥«¤¥°§¥£««­¦©®¯®«¨ª©³¥¦¬¯´±¯¼µ±¯¯ ’zwrea\Z]XNLRGRaMVPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8847763321./2556;:8;7876<;:;;A8x»»±µ½°»±·¬ž¥§­·»¼Áź±¹µÄÉÉÀÃÆÅǶÅIJ¿Ū··½¶½ººµ²«¬¦˜—ž¡‹ˆs…‡~vncafihfgifjm`]\[ZZZZ\]\[\^_\ZY[YYZ[WUXWTTVUSTRU``_`a_aabdj€““‰”“”•–—¤™ —¡¥¡­¦¤¤££¢œª«¥šŸ¥±ª ¡¥«ž¨¡ž­¬©©®­¢¡¢•˜£›œ«©°œ ¢Ÿž—™“Šž‘’“–˜˜“œ¡£¤ ¢• ¢¤¦›£«¥¢¤ª£«®¥®²©¦¥¦¦´¦©¨­³µ´¹º¯©¬žŒrqo`[WVURGQOHY[ORITKSLEFID8;;=<8667:9;:976977:;:=<<6;<8>598:88659:;<97?<9678452121..1426:8698598989;9@9{µ´­´»²¯«±­¨§¯¹¹³ÀȺµÀ¯ÅÈ̺ÁÊÌȵɼ±¾ÃȬ±¸Áµ»À»´³©ª¤”™š›‡qˆƒ{tiijlgjkmkjme]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURSOQY]\]]^^__bdmŽ„‘‡‘š“•“œ›£œ›¡©©«¨¬§¨¦¤™¤¯¥•™¥¯ªŸœ™› ž¯šœ«³ ¥¦Ÿ¢£¡”“›––’©©¬šœŸ¡ š”Œ™ŽŒŒ‘–•¡ £›£•› £¡—¢¨£¢¨« «°¤­·¥£¤¢­­ª¨«¯³·³¾µ²«¯˜…tsh[XYSUREXLQ[XMTNPLPQINIB<??A?=75799<<987:79:;<=>;7;;:=67:;8976989:6:=99577571141-+/434988::8::748=8?9~³­§³¶®¨¨¯®›©¨¬·¶«¼Ê»¶¿¬ËÆŸÁÎÏȳĺ·»ÂÈ°­¸¿·¼½º²´¥¨Ÿ•–—•†yt€vwnmhmmmpggigd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUSSNPQYZZZ]\\^_`d~Œ‹Œ‘Š’—‘—™¢ › «ª¦®¬¨°¤©šŸ­ •–¤¨§—šž®—˜¨ª™Ÿ”¥ ž’’‘“•§ª¥š™™žž•Œ‹“†‰ƒ‹’•‘ ž¡£˜•Ÿ•š¡¢ž”›¥¥§¨¨ ±±¦±¼§Ÿ£¬µ«®§°µ°¸µÀ±­±«‘~rsbVTUNRJGVPRQLLWMJLNRGMKACFDC>@75889;9:7::7<=:;@>:9;9:?759:9876958779;85576661320-*.102877;99;8948;8@8³¬¥±·ª¥¢±«ª§©²±¤¶Æ´¹º³ÊŹºÁËÐʱ¶¸»½Áñ¯±·­´³º²²¡¢›œ––“‚~vkglnqnqjpkdege^ZYZYZZZZZZZ\\]\ZXXXYYWXWUUTRSUSVURNNNRWXYYYY\\]aj€zv‰Ž‡Š—‰””˜›™ž©› ª¦¥¬¨š ¦œ“Ÿ£›——…„’›£•£–––ˆ¢››”‹ŽŠš¤§œ••—›‘‘‡”Ž‹‹€Š’’’ š ¢–”˜™•¢¦™™¤¦¨¦¡ ´²§²·¡œ¢·¬ª­¤²²¦µ¼µ¬«±£‰ysm]NQQLOCMNNPKFNNJJNMQHMJAGLHGC=858889:;69:68;99><8:>9;?8789:886857688974577820301+)-/12876:999984988A7w¶¦¤¶°¤§¤ª¥ ¨¥¥³ª¢²Ãµµ²³ÆÆ·ºÃÊÌƳ¬º½´·À¯­©°ž¦­¹®¬ž˜™œ”’†z‚m__frpuqinieghj_XXXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQMMKLSWWVXXXX[]aosvq…ˆ‚ˆ€‘„‹”‘”ž¡›œ£¢¤™¥—¢œ•‡˜šŒsƒ~—–†‘š”ŽŽ{™œŒ‚‰‰˜Ÿ£ž“˜–…ƒ”~~tŠŽz‡“ššš‘•Ž¢£Ž‰š ¡£¤›¢´¯¬¯­Ÿ˜¥¸¦¦±¡°®œ°»ª©¯ª™ƒwscVMROPNCSNLQLBPQHINRMHJJDJLFKJ=749888;;69;7:<9::;79?9>@79:<89764445874312585/0102)(,-12764789::65:87A7x·¡£´¨¦¥¨£¦¥¦¦¦³§¥´Á¸°´°ÉÄ·¹ÁÎƽ³¬ºÁ«­Ã­§¢¦’¦µ«¢žŽ”•‘Ž}v}eWV_gfighncjhgb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTRMMJHNSSSTUUVY[]ilrm…|tNXrƒ—‡Ž—‹”‘Ÿ˜•”–•–‰€“‰_;Vo|‹”‰€Œ’Œ††sŠ…–y{†““ƒ•Ž‘ƒ†}“xqp…}‰‘—š™“‹‰œˆŸ˜ˆ‡–žš¡ —§®©­©¨ž–­³¢¦­™¬«˜¨³¢©­£“~rn`[NSRWLDTJPLLFNOIELQMKOJIMPFII=7599999:7:;:>>8:==7:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9y· £­¡¦¦ª §¨¨£ª°¨§´Á¹°µ°Ç·³½Ï¿¹¯®µÂ§ªÅ©¢˜ƒ”›¯¡˜–…“ŽŠ†|ru]QLRUYZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MORMKHFHNQQMPRTVXZ`mpi{‚tQB@•’’}‰•„Š›Ž–•‰’ˆ†•†y‰`JQnxŠ‘„}„Š…n~”wuvx„™oQˆŠ†{~x”vgw†ˆ}Š‰•‹‘’—Œ„Šˆ•„šŒ‚„’š–ž”¤£¨©¥¤žš°«¡¤¤‘¦ª–¢ªœ¢¦¨‰umf^[HQQSMIUMSILKOIHFJNLMTKQQOFIC=769:8:;;8:;8>?99>=8;<6;;478;6775344696/3/.125221/,')+*,4833979:99::::?9w¶›£§Ÿ¡¯¡§¨¥§¨¯­ªµ¼¶··³Á»¶§¹È¸¶¨¨µ¶ª²¼¦–Ž‰“¨•”‰}ƒ|wpnXMKMNOLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDDINOhYNQSTUZnƒtw~ji\U‰”‰t‡|…Œ“‚’š‹{†€v€xsnuptz~Š«…yzhv{Žprmx‹’xz€{€vrr’whu„„„…{•ŠˆŠ‹€„‹Œ€”ƒ|€˜”œ–‘ž©žŸ  ©¥Ÿ˜Œ§¤“¡ –žž¤€rha\]JVORGJXROJLMRJJJLPHLQLRTMEHA<78;99>=:;<98@?::>=7==79937785675251472/2.,//200/-+(().1272198798775:<;7v®™£¢˜œŸ´©¯©¥¬«°±ª½´²»¸¶º´±Ÿ·º²ª¬©¨²¯¡š‘”€›~v…w{unnhXKHIHGEHHPTTTWWSTUUUVWWWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQQSV^uƒ|xfw—˜}hyvx€‰}„˜’q‡|w{ok~­|sŠ{†’}tfv|†lohs}‰Œˆ€lyq}qmvqhq~ŽpC‹„‚ƒ…wwz‹…}Œ{u}Ž’˜Š’š›£–™šž¡œ–Š¤›Žž—Ž–˜womebZXXUQJSUTOPNPVKNKNOJQNHOOLFD<;79;::?=9<:99??;8;=7<9999266856633611224.,,-..-0-+*''*.1362/876966527995y¦— ž– ¦¯¬®«¨©±¯±«¼¸¬»¾¹³¬§›°§¬›–œ¥©¤ —™Ž„’yˆŠ‰up{mtpiliWKFGEA@CDILLMQRPQSTTTUVVWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNOQTX]eprmˆ§ªÀ~uyc|xo|yˆz}‹†omŒ’ytxjj€‚q–‘‹~–€I“˜nhw~‚licly…’†ksl|nr{†imps‰„†{}~{vots…‚yxp|ŽŒŠ”ƒ–—˜š’•—™—–Œƒ‰ž‘‹’†–ninonXUXTRQYORTTSXUMNHNKMNKCHNGE?:89;99:><9<;::=>:8:<9?868727565541432/024*+**-.+-*(*(',-1250,5567485HA895w™‘›™šŸ¥­°£¬ª¨µ¯®¬´¿«¼Â¿¦¢™•¤—ž„‹”¡¡˜˜‘“‹sŽz…‹…tntkpldkjXNEFC@<>>AFFGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_IMOORWZQY\`§ˆbšitzepmz‹‰vˆ†tlš‘ts|jkMy…’‰„Žg1v†sl~~ƒtfet~„„…€filukq|hqq|n“|s}|qpnum‚wyujy‰‚ˆ‰„–’’‹‘””Ž—€yˆ—ˆ†Š†€ˆvjjoheXQYWYY[MPUVYXNIHEJJHGB@FDCG=998;9:9<:9;:::@<9:<98>787715234533645031.**+),,++)(+'),,226,,5775478iO8;5n’ˆš‘™–¤¨®ž²Ÿ§»¯«²°Â±»Ãǚ–”™‹Ž†y„˜”Œ†q‡‚s‡Œ…zorpnodpf_TFIC?<;9:?@ADCEGILOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOOQVLAIQIb¯³ r|xl}mrƒ…z„††yr¡•tx€su”‡5q¨Ž¡¡„¢„vp†|‡|sŒ­‰€gfbjnrlpƒuioXupŽ›’wl{}mqmp€zsunbvƒ~†€…ŠŠ‰‘‹‘Œ‹ŽƒuxŠŽ€~ƒ€}zqpok`[\^\YX`_RN[ZXWLHJFJG>BABG>CD=;97=;:;;9:99;:?<88=:8;66651121253474531./,,+)*))***)(*)+/3DM2166643<vR7=7b’“ˆ–‘¤§ž¯•¥µª®±®Á²»ÁƖŒ”€ˆ}n’‰ƒŠ‡…u‚ƒl•ˆ‡{txxlwnwci^IPG>@7449;;;=>@BEHLLLLNPQRUUVWXYXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL7CMRSDJ†v€||v~mwˆˆ|~…ƒŒ~v¢™y~†€„™„›œa†ªŸ‹ƒzwˆ~‰ˆsŠ—ƒz]dqtz{wŠmhjbyo…‚znwt„zptywkni]w‡|‡|‡‡‹’—ƒ…Œ†}q„ƒ}uw{|‰vpsteg_[[]T\g^WQUX[UGJJDLG?F@DC>AA=:97<;;=<::99;;=>79>9985653244004645554-,)+('''&(())((+++/00Uq=23331E~W4=9\ŒxŠ€”Œ’œŸ¦‘ « ±¨¯À±ºÅº–Ž‘“‡z…vkŒ‘‚}Š„ŽŒxƒ€s¡„‹}|~p€~zgvkRWL@E211367688:<>AEGFGJKMOPQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMORLKT]YRJi„ˆ{‰y|q|Œz}‰‡~—‡v¡™ˆ‡’”¥¬©H†®¯¯‹€“Š‚‹„’¨‡€˜˜Šœtm|†‡}Žhghx~n…‡‚…q„…Gl€wryvhmk_w}ƒˆˆ…‹z•›‰‹ˆ‘zu‹v|xmow}ssrl[]][ccXgf\UOPVYPDLKFNICFCCA@CA=977:::;;:888::?>6;>7585773344236656768;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|}‰…ˆ‘–˜’—¡¬¡¦¸¯³¼³—’‹˜‹}tp‰’~}Œ‚’”}†~†¤‡ˆ‚ˆ…x‡ˆ~s„x_cWKB60./23123668:=>?BEGHJLNQSTUTTVUSQOGC?80,#‡[>?84.]–ps£UFIKMNPW`YpZ\^j“‡•€„‚…‘“~…ˆ‘š•‚¡¡˜•›š¥­“™»±§»Ç苌¡¥”‰‘|qƒžŸ‘œv……Šˆihoƒ€tŒ‡„‹q…‚w‡{v…}nvuf€”†‰‰‡ˆ‡¡ª¢–‰Ž˜z‚‰zyogkx~z~rjd^ZZ]j]af`YOKNWRQHPJDNGCJDB@DDA<987=<:<:88778:==8<=68656623444576867<BB?<8:>CQ^e\G2'&,,--.1(?‹[.310Oƒ_4?;nupfxƒ{€Œ€‘ŽŠš›¤¡¬¦«¯°—‘‘ƒ¡”„xwŒ”|’†’•Š€’›Žƒ€Œ‹‚‰ƒ‰mpj]BA4--//./02234778;=?BDHJNQRSRSTTRPOHDB<87/9D><<63.l“—MPHIKKKNV`cggmušš““‹Žšˆ“‹  ’£ª¥£¬“¨¶¢¨Áîǯxº”š|¡ž™„“…‚¡Ÿ“˜’„‹…™‘–lpu‰‹‚–Œw„ql„Š–‘ƒ…ˆrˆ¡–‡“‰Ž–¥µ©›•¢ƒ‡“ƒ}kjk|€sa]c^Zfk\lk^WKGOSQNMLFIPCDMFACEFB>:97=<:;:987767;:6=:785456345566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYp‚pu‡qv’†~—–š•žžœ§ ©–“˜žge¤š~„’‘y€’ˆ’}Š„˜’‘‚€€‹‰…†„ˆ…xx~gMR>/..,/.-/000212457;?CENPRTPQQSQNPIED>;<:CF?><752<?R5HHHLLMNR^oŠ|s} œ¨¥¢™¡—¢•Ÿ¨ž¨« ¨¬©ªµ—«¾«¶ÈÈ·ÉÑϾ› pi«©Ÿ„“’…œ¡š›™§‘‘‰•¢ššxz~”˜’¡’–˜”ž{v•’«²ˆ—Ÿ}”œŽ“–™¤¢¦¶°‘™¨ˆ–ˆlsr||qh`\`^bgc`hg[REJKPOIJLFFMCHLFFCBGD@:85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Ppu`n}awŽ}{”ŽŽŠŸ’—ž–›ª˜žªBD}‡‰‡˜x‚ŠŽ|Š†Ž‚€‰ŒŠ„’…ƒ†‰€†w_bP460-1/,.00//..0015>AAMQRSPRSURNSLEE@<>=GG@A@8662<9;FHGIJNOQYm†w•‹£§ª´½¸¤®¬¬§¨´«°¶²²­»±³¾œ³Ã¬»É˷ÿ¸¥£°²¬­ª£‹–˜…¦¦ ¢—¦™¢ª¨¤ˆ…”¤¡ ª¡¤©œ±‹•£§·»› £°“¢£ž‘¤¢«¯­³µ¢”¤ªˆ™‰’Š•yz~…~g`h\eb]dc_ff_ZOCIHTOFHLFJGEFHAKFCFFA:86=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLicWjpXz…v“…ˆ‚›ƒ’‘Œ’Úȝ–sV—ˆˆœ|†ŒŽŠŠz‡‚‡‘ƒ…€‹…†‡’†‚„‰†ˆ‡‡qna@E64<2/110-,+-1.-3?DAMUQRSUUWUN[PGGD<>>FHCD@8;<5C;=FKIGHROPW“ „®£³ª±ÁÇê³Å¶¬³¿³¸¾¶¿´Á¶»»£·Å¨¶Éǵ¾¹´¨£´­±±›™’šŸ‰§¯«¥”vŸ¤—¡«±³˜–ª­¨®¶»²º¬¯µ¢±«±µ»·´®µ §§£¨š©°­²º¸¸§›¶©Œ¥Ž‘“Ÿ†x‚ƒuYadVeaac`af_[TJDELUQHIJDIGEA@@KDAMF<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AFWQJL[ZQcdWyuq”}„‡“v…€Œ{¿»£¼‚´”“›„ˆ’‰‰y†€Œ“‡„Ž‰Ž†€†‰…Š‡‘zxn]V@EM<6:46AB764//6CHCQ[OQUWU\VO^UIKJA@>GKFED;>@7D7?BJJEFWTP^¥­£±´Ã¶¸ÁÌɶ»Ä½³³À··Áµ¿°·t±³¦ºÅ¤¯Æ¹±³±´¨¤µ¶ª± ¡–›¢’¥°®¦­«§¤˜ ¬³º¢©²º´»¾Ì¿ÅŽ½³Â·º¸¾·º·¹¬¬°¦±ª­¾°½»Â¬™º¨”®——«‰}‚|jWbaXjejeW[dYVTIGGLQGCHIAHD>?BBK@@MC99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FRLALRWTYUZvjp„Ž„nzsy‡b¸¡™£‰•“–“““–’‡†{†–Š„€Šz|‹‡†|ŠƒŠƒ•}xzueO\dGEL:Qca[^SF?;HPDZcQQYXYgYT``MSOEA?IJHEFA@C<E6B>HGJLSZT]“¯¸µº¹É¿º½ÉÌ»¼À¼·µ»»·½´º±Æ`u²¥±šžª½ª¥¨«ª£¢²µ¡«¨ž•–Ÿ˜Ÿ®¥§¦¥Ÿ£”¢¦±´§²²½¶Á½ÓÉÊÓÆÂÅËÁÊÃÀ¾½¿»¼·´°¹·¶ÃºÅ½ÃÈ°ž¹ª¢«Ž¥¨¶‰€q_bb]Wa_hfRXaVRVIEENKA>GD=KB=B@=F>;H@796379>489:57045/26389374426?8@>GKRTSQPOQQPJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKE@IMPRLQ]gllq…slrrsˆÕÀµ™ •˜™‘Ž—’––Ž†‡}†ƒŒ–Šƒ‚xz‹ƒ‡{‹yŠ‚—t}zkepuY]\Peeb`ed][XW\MdmURmm_n_XgeUYTJDAKKHFIHHGBI9D?HKTTV\Z[’¹À¹½·ÆÀº¸Ê˺·¹¶¸¹²·µ´®¶¶˜du¨œ­p^¡­œ˜ ¢›¤ž«¥” Ÿ”Ž–˜—¨Ÿ¥Ÿžšš„¤¬¥ª°¬·°½¹ÔÑÏ×ÏÉÌÑÌÏÎÊÆÀ¿ÂʽÁ¼ÁÀÄÄÅÊ¿È䤻°´¯›«¹¼šyl]_\X]`YccQ\`SPKCAEFD<@E>BHB@D=:E>=J?47535;=468977022/24169775555D3ELM>51/006:477@IOI;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODR\Yi_p—’”olouuˆ³¬¡¡Ÿ‹™œ™Œ•‘›’…ŠŠ~ˆ‡Œ‹‰|ƒs{Šƒ…{‰t‰†•s{xkmu{hreilifjih`fihlZnt—­¤¼ˆ‡g[oh]ZYTHKNOJKQKTQHLAJGKP_^bfia—·Ç°¹³»¾µ±Äǵ¯¹°°»«²±§ª·¬¶§›§šOšŒŽ –‘¦˜¥•Š““‰‰‘‘ž›¡—š•–‡žš¦›¬¯¨¯§³´ÔÔÔÖÒËÏÔÕÎÓÏÍÅÂÉпÊÉÊÉÒÇÌÍÂÐÒ¸°Ã¼Ä¹¥¶ºÄ¢‚nc\\]X`WXfZQ]WOOBBHEBI;AD>AG??B7;C>@H=46655;:687654/10146278875367C5B8?-0-1349=97,.,1;FK=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYSeWs˜‚hqoyyƒ ªž¦—››—‹Ž•‘šŽ}‰‹…ŽŠŠ‹‡|„‚p‡†{‡rƒ’‹~qxukqx~q{mxslipmcinpxiw|~Ë¿Âߧmcxnc[a`JPRUNY^P^]MPNTQUT\nnv‚r—­¸¬´§°¶«¬¼À±«µ¦¥¸§¬®¡«´£Ž±®š˜˜Œ‘“‘„Ž›¦‘œ‰ƒ‹„Š‰„‹ƒ“•˜—“›‘œ˜™™žž«¬¤§¡¬­ÏÒÕÑÍÌÒÓÔÐÔÑÎÈÃÔÑÈÍÒÓÓ×ÍÒÑÅÒÖÅÀÎÇÇ辷Оzne]b\V`R][OPTPNH>AFABE<@B>ED>@?:==<<JA45465<888664412/03526768533;=<E=@11+/249>5901022-2DN3)/3.32=N238C}_2A†tD:==I>@CFH<VRMO[u†…Šwlwp}~¡žž¡‹™““ŒŒ“–…y…‹Šˆ‘‡‚{r~‡y„u…“‘‰ovrks||v|swqk€srhoqzyr{¾Ëš~Œ²ƒvr„vhaj]CZZ[WedXekSX]\`c]cx{~‹™ª¤¤¡ ¡¨¦ª°¸ª¥´£¡­¢£­¢§±Ÿ‰¦š”’‘‰‘Žˆ”‰j•¢™„€…}‘ƒƒ“–­‹••™Ž…’—§°¡ ¡¤¤¨ÈÍÏÈÂËÑÔÑÔÒÎÓÍÆÖÒÌÔØÖÖØÔ×ÕÉÔÚÍÉ××ÑʬÄÃˋsob`_XTYR\PJGIIJ@;:;EAD<BD>HB?BC;;9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/--;R017/532FD28>nb5=tM99@I<AD?A;PLFKYp€u}hsxr‚‰€•”…‹–‰ŠˆŽ‡x„”™Šˆˆ‹‰~ƒxs{}ƒ‡wz‡‘–€ƒnxpmuvx}s…|ym‡vtn}v„uy{µŒ<A‹Æ¥~|ieVICfcechjdox[_fhknin€ƒ‰‘‹ž —˜Ÿ£¤¦²¤¤³ ¡¥ž¡© £±œ†ž’’’‹Ž‹†ƒ„~œ›Œƒ„…z”~‚©•£Œ’Š—’‹}—Šš‘ª³˜š›§œ§½ÃƸ¶ÆÍÒÐÒÐÌÒËÉÔÎÐÕÚ××ØÔÙØÍØÛÎÉÚÚÒÕ¿ËÌ´xvnd]YRUPZVFGJJEE=:79@AB:HD@ECACB;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?1*(.BS39254/7K75<`bA<svV87AH:?C><9QECJTlnopaqqs†|—‘‹~‡’‚‰†…Š‚‡|x…–—ˆƒ‡…‡z„yqz{„†uz…ŽzŒp|oozq{qƒ‡nŽztw||‚u|‡ˆ°tX©Â¶Œ’‚pnb=^hrpqpnxweioruxr{‹‡Ž“’›• •‡Œ“› ›ŸªŸ ­œ¢š™Ÿ¥žŸ¬™‹šŒ‘‘„}ˆ‡ƒ…‹Ž ™“ˆ„‡~m™y„˜†ˆ“Œ”‹†{›ˆ“®ª”•—ž˜¦®µ½©­½ÆËÈÉËËÏÈÃÑÊÔÖÙ×Ø×ÔÛ×ÓÙÛÖÏÛÚÑÖÉÔ˕y{hh[YPRS^HCEII>A>=7:=?;>H=?AAADA>>:86DB755479.566435532323647553457EBDCEB56<FNSM[nfcnskaV>,4LG865434BF4=W_hLux^8;?F<<B<:9D?CGRk_mdbfkv€ˆq‘š€z€~‚‚‚„~„||„—Ž‡‹~††€w‚yn{{‡ty’ž vu‚tu}t€„o‚o’„t|…zv†|‰·Æ¥ÂÉ·–›wpeNfczw†¢‹xyw{ƒ|„vm“–”•˜ƒŠ–š——¦œ— —Ÿ“’—£™«–‘Š‘‚Œ…‰ˆ…‘žœ™‰…‹†—zˆˆŸ—ˆŠ‹‚|¡‰‹¼¡—“—™œ§¥¥®ž¨µ¾ÀÀ¹ÇÉÍÎÅÍÊÑÖÖÕÙÕ×ÛÔ×ÙÚÛ×ÛÚÙØÎÜƆzyghe`TWVUMKDNC;<=<9:<>9=@6=?@<?><9867CA6455=80665547745613854564567HH=DJE7925;H>;::7IP]ZRUXK9T>;95327I8=NYMHxxd5=>C==@:6:>>@EQ_Yea][htzyl‰’wvz‹|~€€}…{~‘‰„…z„ˆ{u}tn|}†~t~’ž‘Ÿƒ’|†~xŽ}yŠŠn‚š€t˜…~‰…|~z©Â ¼Œœ£œ}‰„}‰sŒŠ~s¦šœ˜”…{‰„hGp ¤Œ‹’…‰‹’•š“•‘—Œ•Ÿ”¡”’Ž‹~ŽŽ‹„ˆ’–šŸŸ‰Œ”’ž‘‚‹¥™ˆ„Ž‚†„€¥†Š‹¸˜‘•–¡¦ ž£®¶ºµ«¿ÆÊÐÈÇÌÏÓÒÒØÒÕ×À×ØÙÛØÚÚÙÙ×Ü·xxwkidW`[TPOHDMB==>99::99;=6?>><=9:;;37D@8378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWN<MTHN?96333>C;[X>5YypZ<<A<=>8589?=DRSRX^UXfmmmi€ŽŠqryŠ{z}|ˆz|{‹‡‚~tƒ†yszsm~…}w…›¡›ž”’€‹ˆ˜‡€œ’n‡¨…z ‹|Žƒˆ„œ~š‘Š£¢Ÿ¤® ‹‘‹…‹’†Wr­‹Ÿ«›ƒ˜›Ž\‚¢‘‚ŒŸ“•Œ‡ˆŒ’“Œ”””ŒŠˆ–›•–‘‹’”…€‹ˆ’‰Š–™££†’–¡ŠŠˆŽœƒˆ€ƒ‡…¤†Œ³˜œ’”—¡ ž™’œ§±¸¬¥¼ÂÇÍÇÆÏÌÏÌÎ×ÏÑÔ®ÖÕØÚØÚÚ×ÖÙڟo|tgg\]XSWXC@ID>>>:49:;7:;:3;;?=>7;9:19G=:37=@50677255?65;55858:57735HR7GOK994=EJB>1FCLB98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:<@;BQKKSYPTcbxmb~’ƒnmw‹xy~z|†|{w†„sp…‚zuvvt„‚„}’¦£Ÿ¥¢–‰”—‹Š¨—rŠ²Œ„§‘„™“„™‹¢– ˜“‰›¡’©¯Ÿ‘•ˆ•‹n·…šÄȲœ¡¥›œ˜–‘²‘d¤Íǖ…‡‰’“”Š…ŠŠ†–š›”“†•—„‹™ˆª——¤£ˆ™ž–›ˆ‡——Š„Œ‡¥‰“¨™–“–™¡˜Ÿ™“œ›¢³´¥£¼Á¾ÇÅÅÉÈÉÂÊÓÌÍÔ¨ÒÑÖÖÖØÚÔÓÚ΂rhc_]^NJTZBAGD;A=837;<:8=649:<:82?9929I:>67BC32:96264>=4;>6949;57944KQ<JQK9A7BGI@64JELF><88ETA7>\86214:;E`XAFathLcZ>5;::5;:>:EMFHRWSRBcFuŽ}|m~ˆxz~zƒ~vv€ƒ|ln‹y|xx|„‡Š}Š£³§£ª³¡–§Ÿ¥¤–•®¢ƒ¸•’³™Œ¡ Œ¤›¯£¤˜§–§™­¯¤—•–”‹˜™– ÀŽ¤É¸«›¢¦­˜‘›²†…¨¢œ˜…ˆ‰Ž•‹“ˆ†‡ˆ’˜”Œ‹““†”˜†„‘œt‘™³–—¥¡ˆœ™“ŠŠ—š‰Š–Ž†}Œ˜ž‰œš™“˜˜Ÿ” •ž›¡±®¢¤·¾´ÅÇĽÃÿÆÍÊÉÒ§ÎÍÓÒÐÖØÓÐØ»ryv\`U_WPHINEBCE5>:76:?;<7=42669774=5;5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=89566=:JFDGN[\YIf`;H„‹z{n…†z|„x€…~px|}}osz}{x†‹‰†ƒ’§»¬¨²½¯¥­³³¨£¢°¬Š™µ£¸¤•­¤–©­·¦¤¢Ÿ™©˜©£¯°©š™œ”•‘—Ÿ—™»»­É¡i¶¸«°”˜ž£«“—¾£^ª²‚‰Š”‡‘|ŽŽ}ƒ†Ž”•ˆ‡’—Œ•‹Œ—˜’™´—–«‹›”’’Œ™›Š’ž‹‰• ¡”˜š“›˜ž”¡ ”œ¥¯¨¡¥³¸«ÂÈĵº½»ÅÇÈÂÑ¡ÆÉÍÍÄ×ÖÑËÓ¡pzh]YS^ROFD><CAA8?874>F<<6<35355454B39:BM:A;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPeGb`bpI@‹Š~s†‡}ˆu‚Šƒm}}|pw‡w‡{Œ†Œ™ªÂÀ¯½Æ»³´Á¼´­«³¶Œ§²®®¼ª›»¤¨­¹¸«¦¦¢¡££¨¯²±ªœœ¤˜›˜—ž¢¥¥’£¹®¨À»¬­²¹¥¤§}ˆ‡œ¬½°ƒŒŒ‹ƒƒ‘z‡ŒŽœˆ‡—‹•—”š–§š±š‘¬œŽš’Ž”–—Ž‘ ‘‰•›£¬”–”œž” ›˜ ¡”šž§¦¤¢¤°²¦ÁÇï°º¶ÅľͧÇÃÇüÕÑÍÄʈtsb\Y_[MJBL@EG?A?B;:4>A<=5=6>333242A17@BN>G@CNCA=C=;86CC5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GE?CF\fF`igZ][“ŒŒˆ{‡‹†ƒŒu†Šo~|‚q~z•z‘””˜“•§³ÆÉ¿ÂÌÁùǼº¯«¹»—²¶º²À®¥À¤«¯»¼ª­«¢¢§ª®´°ª›Ÿª›¡›•Ÿ°´§‹¢ººµÁ»«©œ²¥¤¨”…ŽªÃĤ‚‹‡ˆ„†•”zƒŒ‘Ž‘¡ŒŒ”’Žˆ—Ÿ—“™•˜¦ ¯Œªœ•’‘”••‘¡”†—Ÿ ²ž”š” ¡™¤Ÿš œ ”˜ž¦¤¦¦¤¯­¥ÀÄ­¨·µÉþ¶Î²Ä¾Ä¼³ÑÊȵtym\X\iSLHDLKKJAA=CD<5AD;:3=8B332262A05IEM>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBfZMe\fTcj™—ŠŒˆ’†‰y†”r€|x‡‚‚y¡–¨šš˜º½ÈÈÊÁÒÉÊÂ̼Á³­»¾§¹¿½¼Ä·¬Á©¬²»½ª°©£¥£¬­³­¶µ Ÿ®ž¥¢˜£´¼©›¨¼Á£¶¶¯«’°­«¬—†šª¦¥‘‚Œ“¥•‰€uŠ’z…‘žŸ“”‹”£™—œ•”£ŸªŸ‘¥šŒ•–ˆ|•’’£›• ¢œµ¦ž—¥¤£¥žž¦˜ž•—›¥£¨§¢²¬¨¼Àį¥³·ÌÀ¹®Ä³»¾Á¸¬ÂÃÂÀ˜myaXW\[KKMJFDDIBBACK:4DH9;4<7E.12352B26SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQF7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>jH_XaZddVž—Žž’‰Š‰Ÿ“„w…•ˆŠ•¡š®¦£˜Â¾ÈÃÇÅÓÍÎÍË»Á·¯¹¼´¼Ë¼ÃÁµ¶¼­³¿¹¼®¯¨ ¨§¶­­©±·šž­¢§¡«··©¥¯¾Ã±½¹³§ªµ³­®––¥¬¨ ‘Ž’±Å§•Ž}‘•}ˆ‘™ª™˜“““•“¥ž“™“¡£¢œ˜Ÿ™‹ŒžˆZ–—’–¥™e˜£ž²¥–¢–¬¬«§›ž¦—˜—˜•¡¤¨¦Ÿ¶«©º¼Ã´¦³µËÁ¸©¶¬²º¸®¨·º½¸ƒlnZWTUNFJSNK?AGDDHFG95FM;>7>AJ.32025B55PVN<LFKRLOHGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|hW;=@BFBqFiIRebLF¥”œ–¡—©–ƒ‡¦“ˆ‡‚œ„ƒ•”Žš¢Ÿ¯¾®¡Æ¼ÅÄÆÆÎÎÎÒʾ»µ±º»¼¾Ï¶Ä½·¹·²±µ³¸³¬¦œ««¸ª¨§¯°—£¯¤§¤¤´À°ª¬´¾Â¹À¹³§¹µ¸²®•¥­¯®¥‹“•¡tÁš~—™…–šŒ±•š™•““™™¥£•Ÿ›–š©œ¡ š‹–`J–œš•š¥–T–°Ÿ¯œŸ¥”¯®¬¦š ¥”“™™ŽœŸ§¢™´©ª³¼¼»ª°²ÇÀ¸¥««­±±£¡±²´¤qnf\ZNPKDPPPQ;GJIGHBD>9KU?A:=EM07544:B34NWO<JKOUNQJOHHJOB<>MR;>=8:<CR>DHRIBWNI@CAF3>58JKCA=C;4EA:A?>H@5*B52,>c]g:35tde@R7&#3}iX;:BC@=QEWRsbWFHª—™ ¢¨¯™‘—‡‹§–Žˆ’…Ÿ‡„—ž š£¤µÈ´©ÆºÃÃÇÊÈÈÌÍƾº³®¹¸ÁÁ̶ȺÁ¸µº±¯®²´§£›ª³´ª¨¦­¬™¤®¥¤¨¬º¿¨«¶·¿Á¿¾¸²²Ã±¹½¬£®µ¬º¦ˆœ˜¦›v¿ …™Ž“™š‹¯—¡œ›—•›Ÿ¡©ž¨ ššªš¢§ž˜‘ƒnv’¢š•¢ž­²£«•¨ª—ª®¥¤Ÿ¥©“’™œˆ”œ¢ž–±¦©«º¶¾³²®¾¹¶ £§¨¥§œ›¬©©Œcea_RKMGHNIUL=LDNJKBCD<QU=AABDO18=77?B75UXN?HNQYSPQTJQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW;:=..R`MUHe^HE«”œ¡Ÿ»¯™”Ÿ‹“ª›‘’“‰«‡¢ŸŒ¤­”££¶Æ½´ÀºÂÂÇÈÅÂÍȽ¹²¯¹´ÀÂʵƱÁ¼´º«¨­¬°£¢™ª´º¦©¦«ª¨¯§£ªª¾»§¬¼³·½Æ¼·µ¸À±½À³©µ·«¿¥£—‘¢ ¼Ÿ‰š ™—žž·Ÿ©œ¥£›œ¡š¨¥³¡›¦œ¨ªž™•”›‹—‰Œ¥¢”¢ž ´¯¥¥“°«™«¬žž££©‘•• ƒžžœ•©¤¢¡´´ºµ­¨µ²³žœ¢¥š—•™ª¡žw`\_]JHFGMQIMEFFBRLJAEG@VRDH=AGQ1;B7:BF79\YKALPTUSMWRNUJD@JJNO9C?5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-1:g\FCCœpbGD§—¤ŸžÃ¬›—¤—™©œ–ššª••¨¦•­­™¡«¶Ä»¾¶ÁÂÀÇľÍÇ»½¹²¯¸³¿Ãȵ¿¯¼¶¹·¦£ª¬­  šªªÄ¡¤¨«¦ž«¯¬¢©¨¿·¦­½°·¶Ç¶µ¹¸¿±¿Á¶´³´¯¾£—£–”œ”® ‘¡¢¥££Ÿ¾¥©¨¬¡›¦Ÿ½¢˜£Ÿ¢©«¡–•ž“ž‡…“ž¤ µ¬¦œ•²§™¯¨Ÿš©ž ™•Ÿ„Ž¡š›“¥¤š˜¬±¶±ª¥ª­¬œ˜  ’Ž–¨ž”hbYa]NIGJNKHEDIA=PIA<GIH[ROK=HOU4BF9>HG5Ca[KCNRUWVQXTRUH@8QQPM:G@4CHQSIC;C>GVKC@O>K<06;GF>;FA56?9:?9;15D0-,0Mv\4KZ5,MnW<-=)#zbQ5CKQ9oRF<KxebVL¢š£œžÅ¬¡Ÿ¬® “£Ÿ–¥ ¦©«—¶±£ª²µÄý¿µ¿Â»È¾Êȶ¸µ´°³³·Áƶ½°¸´¹µŸ¦¬ª«ž¥£Á¥ ©­Ÿ¤©­¯¢¦§½µ¦±¼·¶µÃ²³·¹¾²ÃÀ·¸®³µµ£¤•’”¡® ™¢©¨«£šÃ­©ž¬­››ž™¦ ½¢¥˜««¬¦¡™™Ÿ’ž‰ŽW–ž¥¡ ¸ª§“˜¶£Ÿ²¡ ›®–žŽ™”‚ŽŸ—•Ž¢¤•¦­²«©¡¢¥¥••œ˜‹‘“¤ž‰adZc`LHJJNFEAFK>=JB99JKN]QQI=LV\9FI=DMI8Hb\LCLPSYYVWOZ^IA=WQIK?H@5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+w`S6SZkWrHE6=ue\KMžŸ¡˜žÃ§¥¢³¡œ²§“ª¤ ¤Ÿ¬©¬»°¨¬µ±ÇÄÁ³ÂüÆüÄʽ¯±¶­°´¯¿Äµ¹°°¹µ¬š¨°©©š¥¡§Â¬›¬±›ª¢®°©¤§½¶¦·º¼®¶Ã­³³Â¿²Æ³º·¬´¶­ª¢¦–••¤¬¢ŸŸš¨«°¯¯¼²¦ ©©™™˜“¢¤¸ ¡¤“¯¯¬¥§Ÿ’¡ž•ž•š¢Ÿ§´¦§˜´œ£¯šž›®ž“—”š€’¡•ŽŸ¡“‹¦¬°¥¦¡œ ž’’š“…‹‘œžae[geJILJRAC@IG;;G?99NMU^RSJ>O^]=HPBLLI9Mc\LELRTY[SUO\bHA?ZQAHAKB7FELKN>;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<v]^?[U^fr@8<H–weA4Ÿ£Ÿ› Ã¨¤ª²¡£´©•²¬§¢¤²«®©»²¬°µ´Æ¿ÄõÀĽÉĵÀȵ«µ¨°¸¬ÀÄ´·®¬¶¹¥™«±«ª˜Ÿ¦—­»´›¨°›­Ÿ®´±§ªº²§º³·²¸Àª·²Â¼´Å§¾®­·µª¨¬¡——’¦¥¢£˜˜¥¯¸®²µ¶ Ÿ¨¤™••“¤ ·¢¥¦–®²²¦ª¦¡ž›šš–˜¨Ÿ ˜¡ž¯²¢¦—®™¥«—š¤‘›Ž“—™…–Ÿ”Œœž”‹©©ª¢§ ˜ž–ŒŽ™…•‰”Ÿxch]kjMPMNT=CANC::I@77QO]^RVQAW`\BJSHVKH:Td\NFON[W[RPQX]GAB[PBG>NC9HGHNP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1[bZ33806p[bH05JphVCWFŒyfC;¤£œ¡¦¿¦¨¯°¡©µª¹°«£ª´¶±°¹·¯¶¸¸Ä½Ãǽ¼ÃÁÆÀ¸ÁÆÁºª¶¤­»­À··ª¬±»¢•­°­²–¥§ª¹© §°ª °´²ª©¶µ¬¼¬²²¹·¬¹°Âº½¾¦Ã«°·¯©««§ž˜™«¢¢ ‘˜¡±¯³«±º›œ© ™–’—¦¡·©¥£¢¯±´«²¨«Ÿ›  ›ž¥œ¢–£³°šŸ“¥š ¨š•¡ž•˜‰”˜“–—œ“ˆ›™”Ž©¨§Ÿ£›—›“‡Ž™‹}‹–…›jhlalnWPQZTACET@;;IA7:XPd^PVWDY^]MLRN^KJ>Zc^NHPN[UYPKSWZI?DXPDF>N?=IGGQPB=CFBM?:2D?77547?=95E4+75/251.-.,1>*'+=\p=>1.1e[d@1647gY`F(?8l}h[V;‰{cC=§Ÿœ¢©½¡ª°«£±¸©¥µ³¬ ¬´½®³¸¼º½¶¶À¿ÈĹÄÁÀÀ¸Ä½Á·¯µ¨«·²¼¾¿´©®±¶ž—«­¨­–§¨Ž§»Ÿ¤­³ž«¢±°³¬©¶´µ½­¯±µ¬°µ±ÀºÄ·«¼¯±¸¬­ª£±¦ž¥ª ¤—™Ÿ³ª³ª«³š§›š• ¦¤´®§¢­­®±§³­²ª¤œŸ¨¤ž•¡˜›¨µ©—™’’Ÿ™ž ž«ž——…•˜‹™œ“Š–—š—¦¥¢ ••—“€”…zŽ’ƒŒ–elrgpq_FYfVDCMXDZ9HB6>]Qh\NY]G[^]NMRXdJJC\b_PLMNXWXPJVVWM=EUJEDAM?AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,+%2+*5K1.'__aU150=`V^8)C3YU\gK5ŒzfL@¤š ¤¬·£¬©¥®®¶©¯´º§¦°·Å·±¶¾ÀÁµ´ºÅ¾ÌŹ¿º¿¹Ä¸Á¹²µ¬ªº¶»¹¾´ª­°µ˜˜§«ª«›¬«Ž«½ž«®±£« ±­³®®¶±¹·©­®±¨µ¯³»¼É²ªµ´±µ°¯§¡³ š¨­ ¥•–›š²£­ ¦¯–¡¤šš’¢¥§²©¢§²¬ª¶¥¯±µ¯¤™­§š˜Ÿ™™¬¸¢—“˜œ¡˜—”«žœ“€“˜œš–‘Š”“žš¥¡¡ ˜•‘“•z‹…{ŒŠƒ‹’knxmu{`EajYIHY[={JGE6AbTi[M\`J[]ZRRRb`LKE_``QLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`U`/5(C^Q\.*B/JGP[H3cYTJD™– °¨±©­¥¤®®µ¨·´¸¤«´·É»´ºº¿¾´´·ÃÀÌȻü¶¾¾À¸¿¼±½®§º¹·¶Á¶«­±¸”—¦®«§¢±ª”¯»¤¬²²§¨£²³°±±µ±¸³¨®«±§¸¯µ´ÃŶ©´µ¬±®ª§£¶ŸŸ§² ¤”œš•²ž§œ ª©£ž›–˜¥¥¥·§¢²´¬§±§®°µ¬¥™ ¬¨›œ›”©¸œ”ŽŽ‹™œ¢—˜¥ ž•ƒ‘•œ˜–•ˆ——›§œ£ ’•–v„‡{…„‹mqwu{~\Kel\KNc\?b{GI8GgWe[M^bMXYWTXTi]OOHa]_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANHf27'FaLV%-B.=EMQ<3rjJCC™¥®¥­®«§¤°²³ª·°¶ «µ¹É¹®Á¼Â·³±µÂÃÎÅ¿Á½´½¿¿º¿¼³Ä¨©¹°¶¶¿¼¯«³²œ §°­¥¥°¥ž²µ¬«²°¬©¨´¹¬´²µ¬´­©¬¨«©¹­±±Ç¿¸¤¹°©­­¦¨­°¦¤¤®£©œžœ›¯š¢£££¬ž¤ Ÿ¢ª¥¦¹¥¬µµ¥ª«¨¬¯¶®£ž£¨ª› šš’¤´šŽ‰‡‘¢ •”Ÿ“’„Ž’’›˜•”‡˜“•™¦›ŸŸŒ’w~Ž…||}‡Š‰qtr~}}\Sdo^NZf]FD–ZG;NmXa[M`bNVWVWTYg^QRLcZ[TKGOTSNGIVS\N;P^IBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3Bc;6*HdHJ+:I?3BIS,>k<GH›ªª¢©°¤¨¤³´±´µ±±¡«­½Ëº®À»Ç±´­´ÂÂÑÅžÀ²¾Á¼¿·¼Ä§¬·¬³¸»À°«²­ ¤§­©¨¤°£ª±ª¯¬°®¯®¬³»§¶°²©²©«¥¥£­º¬ª±Â¹µ«¹¨¨¨­ª¨±¥ª¤¢®ª¨¢žœ£¬•¤˜ž™¬¢§©¢¬¥£­¬¸±² ©¢ «®°¬žŸ§¨©™¤˜™ §˜†ƒŠ‹Ÿ ‹Œ–›ŽŽ…‡• –—•†–““—¤œœŠ‘‰~ˆ†|w‡…†tsqˆul_Y`ncQsq\K;„|F>WuXaYNc[NUVUWP\b^SONhXWWKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*35>10485(5/*,.30;),,'%234$,2-860)(1<]J0.IgDF8<B05EKX1@”Z>LE”—­§¢ª²œ©©¯¶¬¸µ®ª¥«ª½È»°½·Â¯°¬³ÄÃÎÎþ¿´ÀÂĺÁ´ÉĬ¯·­²¸¿¾³­®«¥§ª°©§¨±¥´®«°®­±°³­³»¤¸³¬¬®§«Ÿ¢ž°·«ª­º¶¥µµ£©§¬¬ª­¡©§¦±²£¦¥¡¡¬–ª¡”š ¦ž¤¢«¤¬¢Ÿ§±·­­£¥¢›©ª®©¢¥¤¤˜ ™–˜“‚‚‰…œ ŒŠŽŒ™‹ƒŒ—£›’›Œ“’‘”¢™›™ŠŽŠŠ|†‚ƒzt€„‚~tw‹£‡xj^`ngWe‡dN@g’LDbyWbXReTMVUUTO\]aUKMiWUWIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*49?./463)4+*,+.#4.-+&(+79*&6+<-2,&06WZ.0JgAA<<C+:JO^4D†?HFD–’¯¤£ª°˜«©­µ«¶±«¥«ª©¼ÀÀ¸¸³»µ¥²¯ÄÉËÑ¿Á»¹À¿Â¹ÁºÁÄ®²µ±³»À¾³±®¬««¨¶ª¦­¯«¹°¨±±¯²¬¶ª¶µ§´¶¬¬¤©ªœ£ž³³¨¨¤´´ µ­ ©¨«¨«§ ««¨¹¶©ªª©¢© ¬›’©¡ ¤¢¦£©œ¦µ®¨¦©¢£—¥§§ªœ¢¤£Ÿ™˜Ÿ‘Ž™Ž~‡Œ‡„žž‡„ŠŠŽŒ„†•¢šŽŒš‘’‘’Ÿ—˜–‹Šƒt†xuƒ{x~ˆoqggqx\`sˆjO]˜VHmxUdVRbPMUTUPOX[bUHPiTVSGPYUI>IHOQPxLMV=<KD?@A<@CUC9AK=5;E13;97*4:=+-341*8**+*,)*(/*&)%3;,$2)2021%/2Qb02?f=NX?C,>LT_/Jj6OD;•Ž° ¥«­™«¥¬®³´¯ª¥¯©¨º¾¼À°®¸®¡µ¯ÉÇÈÑÀ¾½»¼Â½ºÃÁ¿¿®²²±µ¼¼Â±²³ª³¨¤µ©¥­³³¹°£®¶±¯²º«¹®ª®µ«ªž©«Ÿ¢ ¶­¨¡Ÿ¯³¡´ªž¨§ª£ª¡¢¬­¨½¯¬®­¡§¨Ÿ«™¯¡˜¢¡¨§Ÿ¨š™ª°©£Ÿ¬¢¡“¢££§˜š¨¥——˜Š‡•ˆ}†…„¤—…‚‚‹†Ž„„“ –ˆ‘“‘œ”—‰……xt}uxy€{tszi†£ui^ekugˆ‹|RXp^JxsSdSQ^MMRYfNLVYeYFSiRQ?BNQaQ:IHLSIqQLS;<I?;<=;@@W<<>H73CB15:93-5::)-31--6)(+-,42#2)',%.;.&1.0-14%,0Lh:38_=ad?F1CP[[+HN9UA4±Ÿ¤¦«£¦¤¬¦´²±ª¤°§ª¸¾Á»¯§¹ª§®°ÉÆÈѼ¿¾¹¾¿¼É¼Á¸°°´±º»¸À²³»¬¸¬¢´¦§¬²¶¹³§§»µ­¶½°¼¦­¬µ«­œ©¯£Ÿ¥¬ª§œžª³¤³¨šª§©¤©£©§©¾«´¯®©¤ ®œ›²£•¤œ¤¥Ÿ¤šš¨«¥ž›ª¡›’›¡¥˜—©©‘˜š“Š‚…~‚€ˆž†}‹‡Ž„“›“…“¢Œ”’‹‘›’•‡ˆ~qzy~|iw|zupp}h…x„‡d`gcr…zmgy]^VBWzmTaORXKLNqt]HZ[gYEUfPD>JNDCA9HGKS?jaIQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11&/>KH0%90%,,09/,,+6'17#-/GjI14X=fbAJ7GS`U*=;DX>*”±™ŸŸ©¥¤¡«¤·²²¥¨±§¬¸Á½µ°£¹­¨¨°ÃÉÉÌÁ¶½¿µ·¿ºÈ¶Ãµ´³µ±½¸º¾¶­¹µ¿­¡³¦ª«°µ¸´«ž¼¼¨²À³º ¯³µª¬ž®°£œ¥¨©¢žœ¥±¦¯ Ÿª©¨¢©›¤¨ ­¼¨®°®¡«£¤®žž­¦—Ÿ›¡£œŸ›š£ª¢šš¤¤•—”Ÿ¢–›–¦¬‹ž‘‘Œ‚Š€€{š•‰|~‹†Ž‹Š„’˜‘‡”£‰’’‡š“‡|yk}vyxb{zqpqrxh€sjƒgdhansŽmbip`pA\xkV^NQQJJMSYVM]^mWDX`O^PHMDF;7HEKO<rhJK9AE;;==;;=J49B<3;G<4?18-78;2(09/,5..=-*K>*49&'.34.0+/4&,:$40BhY13S=e_DL6KWeO*<2OZ="’™¬™Ÿ—§¤¢Ÿ§£¸¯®¢¯°©«¸Âº³­Ÿ¹¯«¨´ºÇÊÈ¿·Á¾¯´¾·Ä¶Ã±¯º²²Àµ»¾·©¹·½«¤´§¨ª°®¹±ª›»½¤°Àµ´¡®·µ¦§§±³ ž¤¦§¡¥™ž­§¨ž ©®§ ¦—£¨ °¸Ÿ£±¯¡¬¡¬¤œ¦¦¨šš›Ÿ£•œš©¦–›Ÿ¨’˜“˜’™–¡ªš‰Ž‡}‡‚Ž||¡ˆyƒŒ…‰ŒŒ…‡’šŽ‰•Ÿ‰‘•‚‹—Œ‘}„{so}qst`yxioppoi~qczliecaf†`[rjrMMiXZMPLJHPRQIN\_nSDXZRgOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23/:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%53=fd24M?e]FO=RZhH*>/YX5(—¥˜œ–¬ Ÿ¡¤¡·«±¤´´ª¨¹Äµ²® ·¬®­°µÆÈÀ·¿Á¹°´½·¿»¿¯«½°´¿±½Ã¹©»º·§¨µ¨§«°­³±§š½·¤­¼¶¯Ÿ±·°¨¥§¯±› ¤ £¤¡—›¯¦¡Ÿ¢§¯¢ ¢“¤¤£·°¡¦±«Ÿ¬£¯˜œª¥©Ÿ—š¥“›œš¦ª™œœ¥–•—•œŽ“—£©¡‰Š†z„~„Šz—Š†y‚‡„ˆ‹Ž…“˜ŒŽ–™Š–~†—‹z€zprwnot_xwdllkihƒmfrikeh\cs€_ZkuiZI}^[XOOJHHRUF29_^lPDXVYeMIIEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<#8R=*113>D5,-'42*;+139cl84GAf[HTDU]hE.;2aT,2–£¡—”œª¥¡¢ ·ª® º¹¦¬½Ä³°®¢µ¯¬­¯´Ãļ³¿º·°³¹¸º¸»®­À³´¸¯¿Á¸¬¼ºµ¦¢³ª§©³«­²¢›Á¶¥¨µµ©ž²»ª§¦©¯¬™¢§œ£¦”˜¢²¤™Ÿ¤¨©œ¢ “¥ ¤¹¨¤§®§ž¥¡¨’Ÿ©¢¡ ™› ’›œ– ¡«››™¡•’•–šŽ”“£¨¤ˆŠ†y„|……}Š‹†y€„‡ˆ‡‘…•“’Œ•”Ž”{ƒ˜‹w~{ltrllsaxthhjgeo„gghcfhj_hbifZe{c`SsT[[SLIGIOS@!*i^jLCVU^`KIHEC.:B<F<6KPD8:D357==895?:;4>8@K=>93)8><:9*6@3.E4(+,>0-N?.+-7,1195,&.5-80576`tB3CDg[KWGU`hB378dN'2ž¤£‘Ž¤¦›žž£µ¬§ª¹·¨¬ÃÀ¶°¬¢µ®§¯¯·ÀÀ¼²Á¶±®²¶¶¸·¶¬ª½³¯²±½¿·®»»±¥ž¶«¥¥´©«® ŸÂ«¨¥°³ª¬µ»¨ª«±¥˜ªž¦¤‘™¦­¢˜ž¤©¡œ¢— §¶¦¯ª®¡¡ž¡• ¦Ÿ¡ ™›™œ’™”¥¬¢˜—ž•”Ž•—Œ˜š© ‘ˆŠ‹‰y…w‚‚‚‡‹‚‰|„ˆ†„„–•Ž‘‘‘’{ƒ•Ž†r}}fxokjlguskcgdctadefeijcjqY^X^mdaNhWZ`VIGHKMRX>9`liGBTS\[IIGFA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A=-5B37=+*,0A*JK./*+3722(57$+7.72685\yN2>HiZLZJVbfA:3AfH%5›¤ŸŒ­¡™˜ –¤´±¢±½·¡±Æ»¹°±£·¬ª®©¹½»»­À²¯®­¶¯³¸³¨«¹±¯®´¶»¶¯¸½­¦µ« ¡°¥«®ž¤Ã ²¤®±¯·­µž­¯­®¢™¨ª¥ž•›¨¥Ÿ™¥£¨š œ”œ­°¦¹¨®£¡šš™ž£š¤—ž˜›”š ’¨–«¨›“œœ’Œ•™””™¨§Š‰|‚t‚Š˜…‡|‰‰„„ŠŒˆ’„“œ’’‘–Ž€Œƒo€fxnhkjgqrk\hcbr`dgjmlgjifl\lmuqaTbhdeYIFLMOXQQVaeT@VSYUFHFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24;6#3*)6.55465Z|]19Kj[M[KXdd@A1IeC'4“¢šŽŽ°š“¡š©²°Ÿ¸À¶ ´Â»½¹±¥¶¯¨®¥·¸··¬»¯­ª«·ª´¹®¥³µ±®©±¶¶°²µº§¨Ÿ¶©žž©¢ª­œ©À˜­¤®°¶µ­­Ÿ±­°ª¢›œ£¬¨›•œ§£š©¢¤–š ‘›£«ª©»Ÿ¨¤ ˜™™ž k¢–˜œq‚–›¤€u’ª§ž••Ÿ‘‰—™€–Š y†”ƒnj~wƒql†‹†}„‹†o^c`g„—†k‹”“uw‹„~ƒf†€huifW\isnNPjcfq„f^dfnli^__‰„†gOKD8ETg^JGPPUUKHSaoteF[QUPFHFC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,+08>G601.*.*/568,#1'214:176Xl16Ok[N\K[fb>G1Pd=+/¤™‡•°›œ“ ›ª®«£½Å¯©·Â¸½¼­¦¶°¥«¤¸³²³°¹­ª§¬´¦°µ£¨¸¶µ¨§¬¶²®´­³¢©Ÿ´«ž¢¤œ§¨š¬¼•¦¥¯³¸­®¥¨®«¬¥¡žœ §¦›˜¡¦¥››§§“ž ˜ž¨ª£µ°£££–—˜—£ˆ¡Ž’š‡¡‡”¡¥§«ž“’›’ˆ„rxŽ„ˆ¡vˆi—ˆf}sx¡oˆ‡„~{¡ Ÿ™€{‡žtˆŽv›Šl‡ƒmheczlqbT†mcli˜qXjon†W^i[kj[ˆpmyr†h‡„Z^FN>F^MERVVQQRWTg^LXJRROEGG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82).1<I9/01.*/(-4583%&2115>1<8Xƒu25Rk[N\L\g_=K1Va7/(Œ¦—ƒœ¬™™Ÿªª§©¿Ã®±º¼·À¾ª¤·°©¬¦²µ®¯³¶«©¥±­¥µ³œ­µ¶´¦§©³±­²§¯Ÿª ²¨Ÿ¤£š¡£œ®µ•¤¥¦¶½¦¬§ªª¬¨¦¢ ˜ §£™™¦£¤˜œ¤©–”¢œ•“£¥¦ ·¤¤ £˜•“˜“œˆ®˜”‰©‹—¢›…±€¤­ž”šž•y‚Ô¨‡”Á›Çyw±¥·—d€Àœ¿y„„yƒ|‘Êq–¼œÅ{r¶§ºzl–±«°yhkX±®oei¼’¼nhymrØ~Rkc¶²q”uš¡ªWOWaOVNFT[XQPRŒ\W\P@]EQNDGI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22BE/.32.+/)-/186- /416A1=:Wƒw21Tk\O[M^g\>L1[]41!¦“¦©Ÿ—œ¥¬²¨°Â½²µÀµ·¾Â«¦´­­©§¯³ª¯¶´¨¨¦µ¦§¸¯³²¶ª¥¤§±®­±¦ªž§¤±¤¢¡ž—› Ÿ¯­•ž¢Ÿ´º¢ª¨¡­®¥¢›š¢¨Ÿ˜›¨ Ÿ˜ž§§‘œ§›”¡§¢ °£ŸŸ£––’˜’™…¯jjŠª~g„•‡­epž”š¦•q®¡¤~w»|k¡v±_j´[¥€fœ‘`fzfjxj©e¾rg¦Œv²j|±xt’“cmm§m[„ Eif‡–Euœ`}g{¤§‚Y_‹«i•xzj§7J¯[WTlc[KNW_\WV;NˆOWV/ITTICEF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3..53/+/(.0.:5/'$203B/=;U‚v2-Vj\OYL_gY:M5_Y31‘¢•‚¬§¥ž£¤©±·¬³½¾°·Ä²·ºÂ§©°«¯©©°¯¤°º°¤¥®³£©¸©ž³²°£¥ ª­¯«¯¦§Ÿ£¢°œ£œ˜•—›œ­¦—›¢ž´³¡«›¢­­ ž™— ¢©œ™ž¤ œ™¡§¤£š—¡Ÿ¬Ÿ¦§ ›Ÿ¡–•‘—‘š…µ›µx…©™µ™w‡³›·”–—©”~k¦z…ˆ’”’w«gk±[¬{‡”tˆp†€€ˆ—xƒ‚‹—Œƒ „°vwŸqkkl|‹N¤XHcc™~ch¦`yruS’‡^P©mcq~‡€b.Q¡n[Tkg`LK\dX\ZB>°xWXA#MiEBDA@A19>88:84;:9<9:A:E::;6:CB8=?KNG:5:AFB@AD<FD;0201;F,0.940,.(/3,>831/2-D1<<S}n3+Xj\OXM_gX7J9aU50•Ÿ”ˆ³¥¦¡®©§³¬©»¶Â°¼Â­¸·Áª¬­®®¦®²©¡¯¼ª¡§´­¤«µ¥¦²³§£¢§ª²¨°§¥žŸŸ¯–Ÿ™••–˜Ÿ­¢šš¤¨µ¯¡©©¨ª›ž•˜ ¥¨™Ÿœ£Ÿœ £¤£–›Ÿ˜š£«›¦š›¢ —“’““œƒÕ“™¹p°Â~Ɔ|֔›»|š–¥œ¤{Ž†£‚¥‚z¬yU¯{‰~Ÿj¹Z¹w†ƒ|¦‚“|˜zªyŽœ{±mŽ„t¼…o”P¯§ÅŠQ zc`ªbsr‡l—ˆ`Sµ´È†€‰|c¤3Bv]QjhcP@XfZdaJHMlK[SOYfZCD?E?0<<59;74<;8=:<C:F:;>6:@C;6@OLH<:<DHCBCD<EF81211DB./0483+-).323971#%5*>3==Qwj6*Yi[K\P_fT7G:aQ72%›¢“˜±§¨¥³ª¥´¨¤»·Á°ºÀ±µµ¼³µ§±°£°³¦Ÿ®¶¨›¨¹®£¯± ³´° ¤žž§©°¨´©¤œž«—™—–—•–¡«žš—¨­°©£Ÿ¬¢§–ž—œ¡¥¡—¡¡¢¡›¢¢§›ž¡ž•™›¦ œ§•œ›Ÿ¡™’•‘ˆ²nhµq«‡oŽ¦r´sr¶{š˜¤Œœ¢~ ¥~°vƒ‘ÒÑu[®|†¤o›ª¦k†„|­}—™{±s“Žx³e–t„žožf”RȋZÂ\Ÿyb_­_vs‡b—ˆ^Yʝo¿uMKµSUÆdTQjcfXAOj_liOUFI9=WR[WXHC?J<2?;5=<46>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>HI91746@>/.24252-).26,742&60;5:=Pqh9'Wi\BNT_eP5G=aM62/¡œ‘¥¯¬¤ª»­¦´¥§¶»¼²º¿·¶µºº³¥´´¡±²£Ÿ¬°¤˜¦º®¤±±´¸ªŸ¦¡ª¤±§¬©¤šœš©ž–•˜˜’’£¨ —“¦ª±¦¢–“­Ÿ¥’”¡›¤¦Ÿ”š¦¦¡›£Ÿ¬š¡Ÿž–œ¢žœ¥••š¢Ÿ–™–’›…¬{w¨v£Ž‰‡©o­Šƒ¨ƒ™™¡‰’šŠ¢’˜‰®…‚³\r³R®~ƒ‚¤q×}w„}Ž‡™™w¯†Š‘œ‡w´ašeš‚”l’Z°XKšu˜yf`­^vw‡g˜ˆk^¯w•žxl5yÈ®²_ATo^g`EPl_qmVUM.eciSYQ:AD@L:5?91=<16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK97<46:>/04333.2..18*.32%!03767=Pke>&Vg\@=V_cN6GC`I:88Ÿ” ¸°—´Á­¨³¨©²º¸³¸¿¹·²¶½µ¥¸³Ÿ´¬Ÿ ¨«Ÿ•§¶«¨±²«®´¤›©  ¨¡µ¦¦ª£™ž•¥¡””œ™’•¢¥š“§¬¯¦ •™©Ÿ¢‘¢™¨¦ •™¥¨œ¤ž¬¡ ”Ÿ›ž ˜™œ–—¢ “˜‘¦†©}}¥x¡Žƒªp­Œ‚§†– ¡Š——ˆ£‚‘‡”ª|€‹yo±Z§ƒ‚ˆ ytØv‡t§Ž›’¤|–Ÿ„{²^œd ~ƒ•l’\«[Z“‘hgªcr{k˜‡q]¬Z‰ ŽkneOJC¡\ZLt^beMZa_rs_JU6Jš“YHE=HFAL35A8.;>05A78@<6=<F?:<6?=B7.HVJEAH6KIN@IK@EN::@4.:>102144+*05/7,&21($$6671<PeeA&Uf[?1U_bL7FI_C1>8¡™™¾«—´Â®«­©¥´°¸±µ¿¹º³±·¼ª»´Ÿ°¤ž¥§§ž”ª±©°ªµ¬«¯¡˜¡ ¦¤£¹¢£« —›‘¢ •”Ÿš”˜ŸŸŒ©°¯¦—›¨¦ŸŒ’¤—¨«§”—©§žŸ¡£¬¤¡ž¡”¡˜Ÿ ’—œ•ž •–«›®mr´r©ŒvŠ¦s´yt³€’¤¢’œ‰¤‡v¸oŒ{‹¢kk¶Y¡†e——i¡¢§m“r´t“˜²j…“ˆ­ku³af¢o‡’j—\­`M¡|‡‘Rs£ly~o˜†p\¯V<œwfTon.\§ObRkealYb\`p{cSYQ>>mp3BB@?L9!7@6.;@37C58??3;<CDBJFMIF62JTKEBI6IJP?HNCFP=<E50;;010/75,+,426/#00,,289/9N`eD'UdY>/U_aL5FM^81B8¥š›º¡›²À®­««§·©¸¯´Àµ¼±¯¹¸«Á¶©ª ›¦¤¡’ªª§¶£²¨®ª —œ§ ¤«¹£­›–™¥£–¡›™œŸ“”«¶¯§™”œ¬ª—Œ“¥™¥¬£‘—ª²£ ž§«°˜¡£™¢— ›–›—¡“œ©œ”‘«™‡Ô’š»s°Ã€Ã†~Ֆœ¸xˆ˜Œ—‰Œ§ˆz£¶u}wv‚š²`ƒºyÀ|u¸bµŒ‡©}–¬©q{u¼ˆ§ ia¦Ž¯¡~Œt‡«}¾ns¼t²ƒux€Šnšˆqn¤t½]w}[ay¼kZV[jz^j`dfbmwoY[YCA@r?CG+5H"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-7A9§šž¡¼¢—±Ã°­©ª«±§¹¯¶Å±º²®»°®Á²¬¥¢ž£¡œ›‘ª¤ª²¤´¦­¤Ÿ–šª™¦¬¸œ¢­˜•¡¥ “œ£ž˜š–“¯¹±«•—£¨§”–¤œ¤­ž‘ ¨«Ÿ›Ÿ©£²ž£¥Ž§¢”¡šœ—•¤˜° ’•ªž…™µ€‘Œ¸•x‚“›µwnlnsny„Ž‰sžÁ»¼š{²¨p€t‘¸ƒ|††‹‡{Š†—|¤»¹½œuz³£tv—ut°u™žf†iµtrpw¶Œ^y}‰gƒymyb‹¬pu…Y[§jDdYSf`c]cQgfqluBNPLD;ZL>J3<0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITBKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7LT_G'SbV8*O]]=+:VV'=;<§ž  ¿¥–´Ã´¬ª§¬«©»®°Å¯µ³®·§µ¸­©£¢¦ž ™”¬¤­ª¦µ¨¨Ÿ›– £ž«¤¾¦¡ª—”¢›’¢¨¢“—’˜”²µ¶­˜¤¤¢‹’‘¦›¥«›–¨¤¥œš¡©¦§£©¡’­Ÿ—£ž———ž°©”œ§¢Žj~iœ§x‰s~štze‡z½¾Àºn’ƒq”†`rjZ^š‰ad‡Ž•k`•cmœvb”kš•”e^`cqš‰hrŒ}†•gj~qtx}}b[wthP\nƒ|{‹jXkz‚rIJo…pMtMEW\f`L[Xgc^O[muiqRODEM;HI<L?2,2A?8/5?C<9;@;=C>RVVWYZ[\\]`aaa`\UG5DFUEJOHFPIIH;8=51:.0;:.0-76=5&"/*2,%;8-7JR_I'S`V4)P^L(3=[O'?2>¨ ¨¡Á£š´º¶¢¬¥®§¨µ±¬È¬°³¬µ£¾±²¦ £©£›š™¬§®¤¤µ©¥›—•¡›§¬¨¾§©¦•”›• ™“˜¥©§‘ž˜°²¿¬›¦ž§¢‰“‘©š¨¤š›«Ÿ£™›£§­¢Ÿª¢š°›•¦ —”Ÿ—°¥˜¢¨™œ‘œ£¤™§£šœššš–hn}qw‘—”‘…Šµª†˜•ŽŠŒ——‡”•Šƒ’“‘‰‘“˜”˜—š ¢š›” Ž‚z¥†ki||€t‰Šq‚xyvvŠ€{Šjstƒucw}vkp{m`c\pgMYYej_WZozmmfSOFS9OZNRO(+:JB635=@A9:C><ENSSTVWXYZ\]`bba_^^[TKCSGKNDGPLOI<:;389,2;820)6IRO8")+/2#4;*7FO[J&R^S10T^:+=8\K,<-@² ³¡¿¢¤±²· ©¥²§¥°µªÉ«­±¥µ¦À¨´ ž¤¥œ¤•– «¦¬££¶¬ ™–– —­©¥Àž«¤•’œ—ž˜“”¢Ÿž¢§“‘˜©§²Ã¯š««ž––©žªœœ ¬˜¡šœ¢¥¯¦¡¤¨ž­˜—¦™š¡žžœ° ¢¦•˜“˜“ ¢–£ž— Ž–”‹ŠŽ—­|•›‚’‚‹ª¨†˜–Š„ŽŸˆ{„†…™‡†‰•Ž›—˜ž£–™“‘f¡³®„‰„vzŠ|vyzogy€‰kuyˆrhszvƒˆ‚ktcyf`idbdfjYk{pij\SLPD_UF@??,4@F;45;>A;<?>>HNNOPSUVVXZ\_aca_^^]^]XVJKLBIOMRJ;<:786/2964.(&$-1./)+*7%+<(6CMMD/T]Q05M[17E4\G5<,@´ ¹¯¾¬«®²² ª¦±­¢¬³°Å°ª­£³®¼¤´œ ¦¢¡™—¨¥©¦¤¦³µž•”™™°¦®¾ «£‘žš™”‘•¡œ—©œ„ž©¬¢´È³Ÿª¤«––—š§¨›Ÿ¤«”žžœŸª®©¥£«¡­›Ÿ ¡˜¥žœŸ¯£™Ÿ¨“˜˜‘¥™˜©žš—fƒ’|e~Žšcylhkz‘¤«keš˜~g…Šeeihz¡ŽkhŒ—‘¢wkj‹˜£Ÿ˜slnz„†yXe]…^lŠ‰€v\hsww‘€‡‚nw‚x€smyƒtwˆˆŽƒ{j…Y^ktd]s‰ij|qlc]QMWJdX@J4=F7?FD71<=?AC;;DGHHILNPRRTW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%/*+'6*$;'/AJ[J/7ZO6)EY/DO1YC;?.=¥Ÿº¼¹¯«³°ª¥¨­®°¦®­°½±©¨¤­¯±Ÿ­—Ÿ£ž¡š™¦«œ¬£¦¨©²®ž•£¢¯¦¶¹¥®£Žš¡™“’› ™™¥–{¥¬¢¨³Ã·¤¢§¯žž•ž£ž£œ£©¨‘ž Ÿª¯ª«£ªŸ¨›¦Ÿ§ ¬–¡›¥°¤˜œª•¡žš“¥˜ž«™ž~¾ƒˆr´r„†­hx¹Ä¸q“¢£{¦˜™sª‚|ËÀÀ»q‹¢‡‚Ÿ|•˜‰žÀ½‚–žÁÁ{{‘ŒšÂ¿}k¥±oŒ€oÊz›w‘ƒŽ€vyyqz‡qx…Œ“ymv’bf_xd_e‚c^thmdbXLVIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^__`_^^^^___]\SMPGUNA??=6468276*&%#)*&.+*)109*#>I[L*#BP/#F[3PY/UAB;/8–£¸Ãµ°¯À©¨”£¯©°¯­¦²µ¯ª¦¦¦±«Ÿ«˜š¢ œ›ª§¢œ«¢¥¨¥¤´£¢’¦­¬·³§¯¢’‘š¥’‘ ¡—œŸ‡§«¤«­¿À°¡©¯©—’Ÿ¢™¢£ª£’ ¡­®¨¬¦£¢§ ¥¥­©‘¤›©­ªœªœ¬¡–—¥–¡£˜œΔyz¤y•–›_®^Ž§¡ |§•›t«ƒ€¯^cªz§‡… t—’ˆ³c‚«†¡Ž³i„®t}–‡¸a‚­Y£Ínu{Ú{™p~ˆ’ue{ˆvvk}ˆn~…‘’~mŽ`qkpg`_yd[phjdf`RTRW^KOC5AHED8>6;@?A;=8@>??BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5578164('$!',&&/(&+360$7;SL+,-J0';\;L-!P@F4.1­Â¿¿µ´°·˜ž‘¤ª¨­´«¦²¬­¬¤«§°ª §›™¥—œ¢¯Ÿ Ÿ¨§£¥¡Ÿ°¬›ž•§®­±«¨¬ ”’›Ÿ¥“Ÿ¥—ž¨£ž®¤ª°¨¿Æ³¨©±®–’œ¢— ©ªž” Ÿœ®¯§ª©›§§¤¡«’­´–¥£ªªž£§¦¡° ’š§š¡›””‘— p…Œ—u…¨‡q°|r¬~¡ž¥žw«‚}­œr­~«‡†Ÿv˜’z|—~ªˆ¢Œ‘‹~«{‰“Ÿ€{­VœÄzo’Á}•mupŒmeve†oawnro‰Š‘ƒmdotup`gmd_oiinfcWS\aZRSC9II@D<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;91478452&# 1' 1' '45-&7=WJ-<'>1)3V@F!G:C1.+¯ÔÆƲ´Ÿ£Ž££¡¬¯¶®¨°§©ª¨®««§¢¤™¢•Ÿ¦ªŸ¢¥Ÿ¨¨¢Ÿ°¬—š–¨§®¬¨§©ž—”š£¢’”¡­›¦£¯¬£¬´©¹Í±­§®¬–”œ¢˜Ÿ®¬œ– ™ž©±©©©›«©£¢¬›¯±¢¨¬®¦™¦«ªª±¢’—£¥›”’…¤j¤u‰z©tz²p‚¥‰™Œpˆ š‡¤``R¬„®‚šv®¦††Ÿz˜–†{f€£‰¤™†£}©~”‡®^|©U¢’z¢Ÿ€{ïŌs¯³³¹qb©¯ÂthŒ˜mš’omywwolfdeqpf{hc]W_iXXUMMQLCCAB;C@@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799674,&$" ('"+-"$.!3-&@DWH,G+66*1PKL# A9D4,'ÂÉÕÕÀ¡™«¨¡¯¢ž°µ°¯©¬£¨¦ªª«©¤¦ ›¤ž¥§¦£œ¬š¢«¡¤Ÿ¯¢š’ª¤µ°¯ ©›–”§£š¢¨Ÿ ¦œ±¦£¨±¬¶È²µª¬©•‘œ¢™Ÿ¥³œš ”œŸ§««£®š¬©¢¡ª£³­¢ª³±¡›ª¨¯°¶£“–¤§˜›‘|ªlž„‡u«y|°o‚¤‹‰Ÿ–•ž”Ò¸´¸É€²^_”©ƒ¤ˆ‡ y˜•šxªÉt™£•§©’›Œ›‰šÆÆxe¡‚¥sŸŽ‚}¯^oµc±uK£†m§G‚“dž“|p—’pzt|{m[fjrqfj^bXcm\^YIMLKEDAB>A<B?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75685/)(%&%$&),4ENPPMFKJVF*L0/>-5OTQ;<F2,$§¤Àƹ­¨²®¬¥¢œ²¹¬ª¡¦›¨¦ª¬©¦ ¦¥˜«£Ÿ®«¥ ¬šž¨¥¦µž¢—“¨ª¶²¬›¥œ •¥­‘™œ§£ ª§®¢£§©°´Â±²ª­¨“‰˜¤š¡£®¥—¡•˜œ¥¦«š¯­¨¦ž¬£·¬¡±¹¯›¯§³´³¤”˜¨¤šŸŽ‚NxšŸz„£|‚¤„†¦žœž“„¸{|y¹‚~ÌŶxš¡‘‹Ÿ}š–—Švž˜Š¤˜£¨~°…œ…ž„¬}™”a¥l£p…}—ƒr¬`¤sq€š`¼}RUuŽ‘£—|~’‘Štzs„~p[mnwrjoZd_hnbd]KMQTBIHFI:9K>B108866877-*5==?BDGILNPTVXYZ[\__^]__\ZZZYUSOH@772.,*.+*'&?QTVWWWYXXWUOUF<E3:P[T6?H,- ‹‡™©¬¤«¹«¯ œ¡¬³³¦Ÿ •¥®­®ª§¦¦š£§¡²®¢¨¦² ™©¤”¢µ¢£•—¡©´¹¤›££“¡²™žœ§¦¡¢¯®¤¨¡µ±Ã±­ª­©‘‡‘œ¦œ£¤œ¥—ž˜™™¥¤¨š®¡®¥¦—°¥¼­¡··­µ²¹±³§˜ž°¢¤ž†ÑµÃ·y‡Ž…‘“€¦x”¢wŒ ’„¥Šqª†„´nrj™£›•ŠŸ|˜™†‡s¯‚¥›¢¦‹“‰”›mp²\¥s“zœl™{™}n©a¢qqŸbs²¸hx“¦˜~ŒŒ“Šw|ymixixsnt]ddnmeh`JZXX<HG@U3@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^``][ZZXURRQF:2230/++(@QRTUTSTVWWXXWUVVTQOQ[U%!2AH$)%’sŠ­¿¿»ºµž—¨¤­µ¡£™•£©§®ª«™¥¢Ÿ¥  µ¦¢¨§°£”«£Ž¤­£ššª´´¤¥©‘”—®  ž§¤œ§œµš ª£µ«Â°©«©¡Œ„›¡ ¦¢•™šœ˜š™¦¤¦˜«§­¢¥›­§¾¬•½°¬Ÿ£°³º¬´§›©²¥¨˜z¨}|°wŠ¤¥ˆœm²o¡‡­|¡Žƒ§•˜€¬ˆ…®…Ÿ”¨ ¡–†Ÿ€™•€{’~«€š–Šªx ‰“’€y¯]£|¦§d€|—tk®]¥kq…™]`[Œ n•‘¦™ƒ”–‹zz‚–klb}tmz`geqogghCY`[=KT2U8BBC7$$3+''3, /6674359@CFIKMNQSSSVZ]_a`aaa]][ZXSPONI7052.*,ATVVVTTUUUUTTUTSTVVWXVUUQHFIJ#((¼’š„©Æ·Á´Ÿ›­Ÿ®¸¥¤Ž›¤£ ¯¯ªŸ¤Ÿ­˜ž¹ ¢ª ¯©™­¡ª©¤–‰š®°¬¦Ÿ§›­˜˜¬¢¡¦¢š¥­˜Ÿ¨¥¶¨¿¯¥©¤ž‹€Ž›š ¦ž’”šš“šš¥££™¨««£¤Ÿ©¨¾¤—쪣¡¬²º«®§ ³¯©ª˜v¯~‹œ…‡}º­Š˜d°Œe•­} ƒ¦•š¬Š„°…¥™¤¡¡… [lj³`­{{‚€±lgn™—Œˆ°[}´[¤ƒkÈ¢eŸ€{¼YvµZ²}R¯€z¬X€¡m˜¨šŠ—––{xœ}ds}bƒwt€|ajfqmfeeOUc[BT^>I(>9=4!",%2. *1/045799<ACFHJLNPPRTWZ^```ab^_\[XUPMJGC553./@UZXWXWXXWWXWVWWWWXWWXYZZ[\XWWGB;ҟ³²·½»´Á³£œ­¦¥¶¨¡‹š Ÿ³³©ž£ ´— ³¨ª«¯­«›•®¨¢Žˆ›Ž¯«¨¦¢§™®“™¨š¡ž¥Ÿ™££¥™ž£©²¨¼¯¤¨žŽ|‹š•¡ ™’š›‘™—¨ž ˜¨­§¥¥£¥©»Ÿ Æ§¥©¡«´¶­®§Ÿ¼®­¬•©’£¯Ž›€†¤—˜€€¸ÃºƒŽ“…§—œ‚¬Š‚¯ˆ¦›š¥ª~սªb£¿½|~£‚ƒ×º¸µ…”“ƒž½¾„j£o«„mz²°Çƒj«°½­xw¢¾»t€–Ž¦œš‘–œyšyc}zdŒfy‚{`kekjbPb[Sj\@TaBN)=:4/$%2 $(0496677;>ACFGJKMNNQTW]a\__a^`[\YTQMIC?<A?5=SYXXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ¼•³´±¿¹²½³¢®¦¥³¦‹˜¥¾©·±¨¡¿¦¦±›ž±œ¹¨ž­®¥¦•”¯¬—Œƒš‘®¦£¬¡¤œª¡˜‹£’¦ž¨œš¡©¢™ž «­©¹­¨£›—“{‡™‘¦›“‘˜˜Ž˜“©™Ÿ˜©¨ ª¦¡£«»ž©Å£ ¯£«³µ«°ª »¨¯¯šsuª¤·†e‰Ÿpg¬Šmow¤™Ÿu®™•p‹q•§£›˜®¤rmmmeŠwnm‚™q€yiqig‰••˜qhi„†gp†d]‰cjoY]g~w¦`bqŽ’ofd€’Ž¢˜—˜•ž|‡Ž”uf†whjy~ydlcflbKdXJkY:QeER'K:+# #,)-2.5:457:<?ABDEHKLMOQSV\WZ\``a]][TPLHD=:AB7MXZZYYZYXXYXWWVWY]^^]\\\]^]^][[UW^¨•­³ªº¹²³«©¢®ž£²©˜’½±ÃȾ¶ªžÀ¬¬£ §¬Ÿº£¤­¬¬¦Ž–­©Œ…•–¬ž¥ª¡Ÿ££ ‘Œ¤’§™©™–£ª –œ¥¥§¯º«¬š›’’{„–¥—‘‘˜“˜•§”ž—¨¢š°¦ž¢¬ºŸ°Á¨¤³¦¬±²«®¬¨¹£®¸–Š¡¨¥¶‰–¢—†©š”“ª³™›£« ²–¢¡ ¢œ ¤¡•«¦Œ’’Œ‡’œœ”™“˜•†¤™—•‹“’Š†„~gŠt‚vt‡Œq§l{•‘”“” •˜– ‚‡“ŒphvpŠwv|zjlddocU`X@i[HcaOZ+F=+&!740.!%2(*699469;>?ABDFJKKMPPQWTVY^_ac]^UQJED>9=@ASX[\YWXXXXXYXXZ[[\^__`^^^__```_YY`¥–©ª¥µ·®®¢°¤­Ÿ µ±Ž«Å¼Ä»¸ª¢¥›¥°©£¶§©´¦§‘˜¬¢‹ˆ‰Žœ§–«¤¡™§žž“•£—¨›©™”¦¡£š§™¡µº¨ª˜š|”‹¡”Š”‘•“—¥ž™¨Ÿœ¶£§¬·¨®Á®£·§¯¯°­ªª³¹¡¯½™’¦£¦¶¢’¦ž©Ÿ’Ÿ£¬¯š¡£±¨¯—¤ œ£©žžœ—«œ’™¡›“–ª™˜˜–•ž‘ˆ •”…’ŒŒ”Š€~fŒ†u†vyˆƒsœj†‘””‘Š}Œ–’’˜“¡“– ƒ‡—†yq•ry‰q{jnd_pi`[`YmcP`dP[:GGD=2==7.*&+)&&406658:==?AACHJGJKLMSSSUZ``i`eVPJACB;9EMV[^^[Z\[[[\]]__]^_`aabaaa`bbbdb\[c—•¤§£°³¬®£©§­ ¨µª¤³»¯¬¬¢£šz¢±¤¥°¨–›¸¦¢”˜©œŽ†Š‰›¢®ž£•§Ÿ¡’—˜›®‹«–¨š¨Œ˜¨ž¹¶¤¥˜›‰y“Œš“Š”‘“‘–¢Œž¨žŸ¸¤„¯µ¢¯¯u¤¾£² xz «²»•w­¤ŸŠ€ª~d\bvŸŽ¤ƒ—~n“³œ£§®«¢ežŸ’sy™—p€˜¨—l¢§‰eœ¥œ‘—˜–‹‘›‘…š•‚’‡ŽŽ’‰…wk‡v†q|†€€aiˆ‹•“‹[v•‘ghŽr{¥˜˜dy˜†w—iƒŠ‚nykpe`vokkh[febboS[>NNNRG=@TB91/&4:316678<;>@ABFHBGFIKLSTUY\_hfgWQJ<DG;8UR[`ab`^`_`aa_\]___aabcdabaaedchd^]f›–¦£¡°±¬«©¥¨­£§­¤’–«µ¯±¦šª¦«—s‹œ¯Ÿ¨ª¦”–¸  œ£‘~ˆˆ›«š£•§¢žŽ—‘ž…u®ˆ¦š§‘–£ˆ›º´§ ™˜‹‰tv“–“Š”‘”Œ“ ŽšŸ¦™œ²–€Œœµ³Œ’¼§¡~§¢z£¯·ŽŽ§Ÿ„‹…±©¯Œ‰–¢šy‹¬†œ¢§©¨‡•†˜v¥›z‡›—¦‚{œ±zŠ… —™”˜–––„™™cy‡„’Šƒmp‡y€q€…†t†„–’x–h“t št|™ƒ œ†˜~‘‰ƒ˜jŒ…kx{qpgdwnilk[ekjes[^ITLQ@E5.YTU6)!09=>643568;:=>>@DH?IEJKGRXZY[aahfYQH9EL;>bV^bded`aa`bb_]`aabbbcfgcba`edcgcaahœ˜£Ÿ¦®­«¨¬ ¨°¦§©¥™”®Æ½°¡–¦¨µžƒœ«œ¦¡Ÿ¾ž™Ÿš }…Ž™—ˆ«¢–Ÿ ‘“‰†€‘¨Ž‡¢œ£“–†Ÿ¹²§š’Ž…pu‰•Š”›‹‘Ÿ’–Ÿ¤–ž¬ˆŸ´‰´š­ŠÊ‡ª®ˆ·…°ƒ±®ƒ©¦˜|¨r{w›Ž¦–h•¤y´‹Ÿž¦¨’™Â«ˆ˜¡qž€™¤}—…•±€¡|¡” ˜–€Ž“›Š—‘‹|…“†•“‰ƒms‘…zr†„|„t…‚—Åf€©‡¢kžƒ¡™‚™€‹Œƒ‰˜pŽ’…hwt{vghupggl^colglXgG]QL2E46M`c7&3<DGD:64658;8>==>BL?NIJLCPZ]\Wb^jl\QE=KM@JdY]cfhgbbbbdc`_babcccdiicbbbecafcbbi•—¢Ÿ°¨©¨¥« ¤¹°ª«¦š” £¤ª£–¤©¶£¯ §œ¥ž‰“¼™“ ‘y„––‘‡«™››™¡…Œw›œ ‘ˆž¤›•˜—†¢¸­¥™›ŒŒbm‹“ŒŒ—‹‘Ÿ“Ÿ¡™¡¨~¡§‡­ –®ž‘† «¯†¤ªšŒš~¢v€™“j«uM«x‡‘›¨§€ª«}ƒ¡{z§iž’kg—†—¶‰ž}n`dYƒ–~Œ{dhŠr™}y•l]{—m_Sp„\_lyƒ`Ye‚}„˜q§ªkƒ£nr¥pŸƒžieŸl[m‰{eY_ƒbWPovemtrjjo^jomliXiO]WE9A4GC^k4,ICQMN=84859;6@;;>BO>QRLMBJ\]_W^_cv`MD:MOMTb\\ffiibbdbddbab`cdcabikdbddgdbgeach˜– ¹¡ª£¦¬’¡¶¼«®¢™— ¡¥­­ œ­µ¢¨’ ŸŸ¦›™Ž˜´™ŠžŒ•‹u”‘Š¦–•˜žž’…†¬¤‡œ‘Š˜¨—™š‘‡¥°¦¢•šˆ‰€hnˆ‡‹ŽŽ‰‹’‹’¢Œ“ž œ¢¥“£¡” wœ–§ƒ¡§†©­…¥yŠ}„š}¢pr“‡•zŒym‡œŒ™›¨š‡œ{‚¢sv¦fž~v¤_˜z}’s¢n˜·´ºs’‡µ¨dÆ¸{p•·‹q€›¤cs¬«`}j³~n}‡ƒŽ‚‹—q€£ls¤sžƒ¤_™³•p|—ž´ts[ž²ƒjbosuqhoXklrsf\i^bKD=D5QAYq3=SG_JR=<395::6D;;@IP?TMNQ@E_^[ZW``|dHC8LWUVbaZffkkbbeadc`ab`dd_`cknccddhdbgfchh”–•£¸™«œ“ ¤¸µ®­ ›¢œ££¥®œ›±­¬“— ˜ ¤™š“ž«›‹ˆ‘x‹…p€–Š “”—}‰Ž¨ ‡˜Š‘¢“›šŒ‹¨¨¤ž–‡„~kz†}ƒ‹‘‰” ‚–  Ÿ‹‰wœ˜¢Œ r¢‹ˆ©ˆœ¦–¨«®Œ}z ™z£“x€s–‡Œœ}– ‡›Ž™›¦†¢d¡|ˆ–›lžh›nš™{€Š§}rhs©‚œ‚sªg”š]›…v„hªj€¸f\¨pœa•Œ^§vu‰Šžhšu‡“’˜ŽŸnšl§™\¨~w»k~ª[Ž„]´g\nqywki[qjxyb_fXbAPEN7VBRn4KZZ_NZC@151;;7H?:CGT?YRY]>Db^V`Qac}iEB9N[]XdfXfgnmbbe_aa__``ec^bdoq_deekecihgki•œ‰ª¶›¨‰c”›¬º²°¬¦œœ¨Ÿž®›°¨«—¢™¡Ÿ˜–– £™†‰Œjˆ€q{—ˆ‹––„‘”˜zŠ„–£Š”…‹‘œ›‰¨£ ™‹‘Š€€i†y—Œ{ˆŽŽ‡–š“¢Ÿ ¢“˜rhŸŠŸŒp’Œ©ˆ™Ÿ£¨ ¨}°­£¢¸—v£³¢£ˆ”xz«š¢Ž›—ˆ—q¡|…¯µ}kš‘¡x~˜´££«¨„™|š|œ™~sªZ]o{–‹xžbL~zz…cy—BMŸY¢jq|Žm‰„™u›y‡‰±³›“§u€mq|”o™rj¤]•vHec`sp}}ne`lhv|cdaQ^V]TV@YEQgDSW[bX^ID=B8?B:IE8LDWAVQ[VDFb\Z`K`m~qEC<U_bZejVghmobff^aa\]^ahb_edvl^egfldflhhki“€±®™„S_ §³¹³³©š¢Œœ«œœ©“¡«¤¡¨žœš™•˜¡–‡†‰w…ny•…š‹|‘“–ˆr€‰“ œs‘ˆ˜”Ÿš„Ž¨œš”Š‹Š|ƒl……q¡Œx…ˆ‡’™•|’¤¡Ÿ£ˆ®†}µ„Žž{¥–y©‚–Š¡}§hvm~™s sq|…˜o“‚®}¤ƒ¦žš£o^¨gu£co¥aœÓ|z™xrsc¢…~¢r¢Žuk³‹`‚˜‰sª²¨¼wƒm~¾¦©´^œn}q—os¢r]£gt¦ah¦m›Ô™|ƒ›owy—k›zw—sm©¤g`eypƒkgfdmuxg`bS[eQQaIWIT_WS[ej\dPECKMJKBJE8P?PMWSXORR`feiRcwywIFEc]dZgiTihjocjg`c`\]]_hbahe|d^dgdkdjmghlh—›°«T\K~©¯±´°³£œ˜…˜¨  £¤¨ ˜©‰™—˜“™’’ ˜Ž‡…{p}„h}‚”šw‘Ž‰o†“’l—”}ˆ‘£•ƒŽª™”’Š…‰yƒv‡€n‚Ÿ†w€’†ˆ™¢—y“¢¤šŸ‰³¡¢¶‹z¬§¤®¥p©š…œ’|¤€¢™†˜rž„¢­®‰—‹Œ¤–ƒ®¢”v´µµÉ¡s”Š€Ÿ`—©my•†Ÿšu¡‡w ~‘–Š€oLf£’pš‡r¤{ytaƒ‚l~ kqd`œrt—i{i³µ´Æ¦s˜~{j››«uƒšltw—išzt˜qPD}³^jvkx‡fjgbttqnV^TYhORhIULYRU\gknVgWMJAJMKHJNAQJPdcimetrs~y{nu‰{{TPOm]h[kiRjhilglfce_\]\^ibdhk{_]dhcjfomeile¡œ‰¯§„f?”¡²«¯¯µ¢£€—©¢¢¥Œ¥§œ¥‚™—–—›’Žˆ‚yjy†eƒŒ~– yuˆŒi„…’ƒŒ…zŒŠ”¥’ƒ—¨—ŒŠ‰z€}‹xp¡†y•‡‰– –”¥¨œ––„gnxœl¢d|q¥wœ—pg§—Œ{¥zŸ–ƒ—ržv‰”–¹nŠ¢b}™¢•ˆmri«ju ln¦`›i‹h–‡š•u¢€}š`‹…Œuoˆbh ež~išuocfˆ‚nr¢Z_[c¡n]‰Œo{srd¥mw¢dg§h˜s‹˜n¡oSˆo _d§T‹]T˜mmskqmphkxskoRXWVfYSmIXO]HXihsjYkVQREV\LXRaThj^wuz|p||rƒ{rv€„v^QsagbpgPjhhklngdg_]^]`kcjivu]\cicjjslfkmcœ¥™¦zetm‹§®¤©°±¦Ÿ‹€—«œž¥Œ¢¡š¢¢€•˜“šŠ—Ž‹{‡q€ˆh‹‹{—šstŠ}{d‚‡•ŠŠ•™‚|ˆ…–¦¡«…‰‚Š}€€sh¥„}†”ˆ˜ Žˆ’ª§‰¦x–œ~¥‰–Œ²˜žƒ¯—Ÿ¥x–ˆz©t¥„šn¤¢Œ’„Œƒ¼n|¥¯‚††‡“–œŸ|¥zq¨” –gž~o«c–Š•’w¨l©¢‰u‡‚w«‘¦ˆk‘°kv³Œ©kŠ†nmŸž’•a«‹ªv€Œ¦ŸwŸ}…¥• iš‡v¬gž­Œ·sw¾¤“Yƒ¦«aurso{tqbj~nhmSV[Uaa\kM\R]I]mmv`[qY[`Zgsenoqcqt`wz~yryƒs„€{{Œ‚€vbxdcnsdRlgholrifia_^\bkbmlzo\\bibljwmglnb•¦ª€ž¤–©ª¨§®£™‰‚—«šž¤‰š¥©œ„ŒšŽ†œ‘…’‹Œt†zˆ„oŒ„}—“tt†r’‚m‹’‡†”|{…—¤¥¥Ž‰„”u‚‡’ol‹©€ƒ‹”Ž‰œŸ‰“«£ €u”–ˆ~y”®£›q†xŒ„{r¦Œq}}z—–›„Žx{~~ˆ”•“Šv˜Ÿ ƒz}‰kŒ…[yxqyphn~’‰qt““q…„‚eŒ_‹wus”uoynn‡m„…^wixf‚†Ž©›~t|—j‰ˆp€v|…vmlfŒsy{˜x„[jXyhnwrqowxo]l†nigVZ`W\ekcUaU_Q_pwyljvejkjv|qrtsaoubs{xuy‚u€€€x‹…ƒ}{mldyn^Wnghukxjijd\`ZcjelpunZ[bkdllynhloaŽ”¹©§‹¡¢š¦¤™¤œ«¢ „„—¬’ ‰š¦š¨˜‚›Š~–“‡Ž‰ˆr‚|}~Ž„z—trƒp•…{}“‹††…x~†˜¢Œ{¦ ‹…„•‚†Ž—wr…ª†Ž’œˆžžˆŒ›¨  «ƒ‰”š~~‰–­¨“¦xp‘ƒ{’o~¨…p}•qkp|Ÿ‹’ŽŒhm]ƒ‹Œ››žŽs•‹ˆqtk‚vs€Yrn‡}~‹i]id{…ƒˆ€_ix{›{‚‹‚v†‚hy‹‡kaqrƒw_sŒ‚‰§•†fŒƒnw‹„p…yoefcyƒz–[\ifnv[{xwtmsr‚f\mŠklbYY^ZXlq[_`Z^]ft}{tosckkj{|r{xtdmtgl{~vz|{zz~o†Š„{}s~ysiT\qiluougkhd]aXkhkjqrmW[enlgszohjm`ŒŒª±¢£¡šžž˜ž™¨¢¡}‚˜­Ÿ”‡›¢¥•{—„|’˜ˆˆ††Šr|€‹v…‹„•Šqo€r˜†„~’„ƒ†Šz€ƒ‹šž‚¦ †xŽ—ˆ•‹‹—„ƒz­‚‘˜™”Šž‡ˆ¡« ¢¢£‹ˆ’›œ£™–ª¡§¦ ’›ˆ—Ž|xŽŽ„§~’‘’“œ±¦›”ž²“˜„¥ŒŒ•›Ÿ‰›‚ˆ‘‰k|vwe‚…Š|‰„‡‹ˆˆ€…„w|yuš¡ˆ†ŠŸ‹…”~Œ€vpt†„xˆ‡‹¦„…ˆƒŒ|‡Šˆvkƒ|y™jrh`sŠp}zwvowt]^o†hn_^Z\]ShqUc[\alhu{|rnpdkji{mxqioplf€{r‚€x}€„zmƒŒ†|zx|~zƒxNdvksmpzdkebb`[tfpfrrmU]ltmhyzqgikeˆºŸ–¢¡˜•™˜”™¤ ž{™«Žž…ŸœŠž–|x”‚{Ž™‰†„„†mx€€r‡~ˆ“„mk~z—†„ƒ€†„†|‡ƒšœ’†©žƒrŠ…’‘‹‘}{ªƒ’—•œ—††›§ ¢š†ƒ‘š™™š¦ ¦–‘Šw|‡Ž„¥{|Ž‘†˜©¡“œªŽ‘€žŒ‰“šž‚Ž—~†‚ox…qt`~‚†u‹—€ƒ‚†„~…ƒ”myut’¢‹Œ…š„„t€Š||rr{ˆ„{yŒŽ„“§†„„‹ŠŠw…‡‰‹|nk}€{mhlmg^yh|{vtuu{w\`p}nu`cZ]^QfmSeZ]ajivz~pkldkjg€ls€lltoxn„yn‡€v‚€}„vrƒˆ~{{|{‚Š`i{juhi‚djc`i\duhobunlTcqyepzzseimm‹ŠŸ·š¡£Ÿ’‘–—‹šŸŸž{x¦›Š†¤”‹˜™xz…{‰‘ƒŒ‚‚m|~xs€…}Š|kh}—ˆˆŽ|~†„‡|€š›‘ˆ¦œp‹Š‹’‡ ¡Š…Œ|¨‘ˆ’—“–“xŒ£¡¡ž–š€š˜“Œ›£¡¤š—‘›~Ž…y€ƒ‡ €}ŒŒ|—¤  ’™¦›‘‰’—›~’’~†ut‚pv`}†rŠ•|ˆ‹rŒ‚…†ŽhwqxŒ˜’—~ˆŠs‚‡||py{Œ…z{‘ƒ–¦“‹†‘|†‡‡…u‚ƒˆ‡zer{xzpljf^}sh|uus|r€j^`tvpxdcY_^RkhTdY_agjvxqfkclhe€jm~hnqk}w†zk‹s}tv‚†~|{}jrƒnsia‡hlb_qVtomn`xhmWjtvcu{{rbjny‰Ÿ²’¥¥œŽ˜†œ ›œ|v¤ —Œ¢Šˆš–x{†‡~ƒ‰~ˆ‚€qztu‚…~‰xgc}†—Š‚Šx}€Œƒy–€•—•Œ–Ÿš}o‹‘“†¦›‡Œ‰„¦•…’‹–—“’v‘ž¡¡˜”—z~Ž˜—Ž–›¤™“”œz†ƒx„—~‰Œs—¢ž¡’˜Ž¢Œ‹ƒ–˜ƒ’–™~˜|ˆvq}mzd|Š…p†“‚l‡‚‰„euo|‡’—}“x‹‰|€‡|{q~xŠ†y…‘Š‹˜¢•„w‰…ƒ‚v{‰†v_xw}s}wflda~ijwstt}q|bcasnusmaZ`^[kdRbW`ahkux†pbjcmeh|ƒlhthloh|‚xm†q€ƒƒs|ƒŒ~z‚ƒ~|mvˆttmeŠljacuV„iqn`yglbjvpfy|zq`rl†…œ­—¦¨ž—‡†Ÿ“—˜}wªœŠ˜y—œ‹‹˜y{€‹}|ƒ{€‚€xtxzs}€ƒˆ‹€d^}‹•‡…‡t}}‰}—„–“–Œ£ —~r‡z“‘Š§ŒŽŠ“ ‘ƒ‘”—‘‹˜ š’‘t’”‰ž§˜—•–tŽŽŠl†˜™z‡ˆ‰o—š£“•ŠŸŒ†’œ’’•†™ˆ|‰‰zqykul{}‹~n…’‚”wo‚ƒ}~Šdrj{€–—„t‰ƒy‡~ux€}‡}ƒ…”¤x…‚t‰‡}€su€‡ƒn`{uzq|oancd{bnovrwwstav_oluno\[_]^j^O]Wcahmsz‰k_iejchw‡mflhilh€|zwn‡sƒ„}s†‰z‚}z„}|ŽrzŠxxnl‡kh_iqc‡hqoewhnlayhk}{xpawm‹™šª ¤¨ŠŠ‘†ŠžŠ•—}w®˜Œ–}ž“‘–“ˆw}{Š||€vw€ptszo…|€Š~|`\~‘†ƒ„sz†z‘‡‘‘›’¤›”}€{Š’¤‰Š˜šŒ†‘˜“–Ž‰‰Œ““ŒnƒŽ‘‰ž™¢¡—–‰–‘oˆš„g†™Ž“z‰…Šp•š”¡’’ˆ‹™Œ‚ž|’’‹™Ž{Š„‡tsukqnu{‹tn…Ž’qt€{ˆ|dqly}™”}„ˆt‹tˆyo€~‡|…Œ‰…•¨{ˆ}~‹…w~po€…ƒchxtuo{b^p`jt^qjzxxlrpex]mlsmsXZ^_ajZPWWecgqq‡f]ihgbgqŽodigejh€zwtnŽ…t‚{u‚ˆ…w…|x„…z€‰w‹{zryƒjk_pht€kromqgole|cn€yvqlwwŠ¢˜¢¨¡¦›‡ŒŠœ†“œtª”’† Œ–“t{v…wxrs{…kroymŠv€€†nq[Y~‘ˆ€vu€ †Š‘œ— “—w‰~€ŒˆžŠ†’˜–…‰•™—Œ‹ŽŠŽƒmˆŠ‘Šœ–¡›˜•…—ˆj…£ƒg†Š‘~‹ƒ‹w“˜‘ž‘ˆ‰•~—|‘š’|Š‚nvolmnp{…isƒŽ—Špwt‚‰‚xfsov™Ž|‰„z”‘zwˆtp‰{†{‹†„‰œ£ˆ|„w‚‹€xxnj€‚]rsqpoxZ^p`pj^oi|ypmmjlv`pokrmYXaaanXQSZfgcup„‚b]jmdbfk’m`ff_hjuqrp‹€u‚€xu€‹€x…w‡†wƒ„{†Œ{vŠjqc|b†|oqltjholvw_qy{tut€‚~¤•š­Ÿ§–…Œƒ—”ƒŸuŠŸ”’†Š›Œ•‹yrxtpr„squˆlolumˆvƒ}mnUQ«”‡‚x€vr‚y ‘’’—›‘šx‘z‚Œ’¤š“Ž‰•™’„‡—™Œ”Œ‰ˆž…Š|rŠ…‰Žˆœ™Ÿ›–””i†ˆg†¡ˆ’„‘ƒ‰qƒ‘—šŒ‹w{’zŽ‹Œ‘–Œ|ˆ|€kvjnkklz~ay~Ž•vz€wƒ|xgtlt‡•‹ˆ†{”qz„pwŒzŠ{‰~ƒŒ‘Ÿ…}|x‚Œ}vpik‚y_womkqsV]obq`_lnypgpffsthqlawe]Vfa`rSPN\fe]xpˆ|^\hrbbef’i_hd[gp~pkpsŠ}v|…€tuŒy{†xˆ‚s†„~ŒŒƒ{y•wfrjƒ`ˆ~ookz`jntt_t}y†xts…|x ™°œ¥‚Šƒšˆ‹žŠ™“Ž„ˆ˜ŽŽŽ„vtvs€po…spqƒokivm‚n}|mtsRN‚ßȒ֓|pt‚uƒŸ‚“w”˜š˜{“r…Ÿ¡““‰’›”†~–•ˆˆ‘ˆœ€ŽxzŒ~ˆŒ‰œ››•“yvh‰’‡lˆ£…’‡—ƒ†cŒ‘˜Ž”‰–ŒŠ‹q{”‰zˆŠ’‘‰y…{~l{erojkyy[€y€z}~†Žzyhsks‹Š‚……}•Œl~o€ŒŒ‡}„z‚•ššŠ|wxƒysmfpƒljtohismS^odpY_kqwfkjbfxrppc_w``Vk_]vONK`fc]yq‰t\[ev`aeeŽcafaXissnkqvŒ|ty†uv~‹s†{‰~r‰‡Šˆ|~˜vesm|eˆ~npk€Zlnyysavz{vrwŠwyŸ‹›®› ‚…wˆ•~|‰œ‡…ŸŽ…Œ—„“Ž‡twpyqn„omn~rddxp|mz}jhlc¤šÁÜ®ï¡skuƒu„¢…‘n•”Ÿ“›‘p…‹£—‰•Š–ƒ€•…‰€’ŠŠ—‡{u‰w†„›š˜™ŽvŠvn†‰‹}Š£„‘‰……^‹”—ŠŽˆŽ‹Š„‰l|–}ˆ…‰†v…}}k}dwujmxsWˆz‘†…z~€…‹~xesjŠŽŠƒ‚Œ–…k‚unˆ‘‚‘…‚z€‘–“™utxˆusqguy‚btmobhugR`qgkU_nty`rc_h}prn[crabWnY\wMMLdfa^vsŠm[\dx^`de…_cb^XjrknkrvŒ}sw„xw{‰qƒ„}~ˆ{t‹ˆˆ•†Œ~~˜shuqym‹zntpXqzvyqewy†Œiv€‰rœ‡˜§œ£’„|pŒ”xy‹„…¡Ž{•™‡„{rwpsjokil|t^`xv{pu{g`e|ëÚµÉÃ܈sls€vŠšˆi—Žœ”’ˆp…ˆ Ž…Š•Š˜”|“ˆƒ‰{‘‹†‚vxƒƒr‡‚’›–”˜†Œv‡p…‚‰‡™¢ƒ”Œžƒ‰aƒ•†‰†‰‡€‡i}”}ƒ„‰Ž‚q†~qwhuriswkZŒ}’…|ƒ€„Š‚uatlˆ‹‚~’‘}n‚ly††“„}}€’“—‰orz†ulpkrx€_sin\jv`RdqhfS_pvt`o`]h‚qsjWghciXmW[uLJLeg_brs…h[\ey^^dg{`d_\YkneojswŠ~sr~zvzˆs…‚|†vwŠ†˜‚Œ{“vlvuyx“tnxz}Xy…q€ogyw’‚dv†…qŠ–…™¡›¢Š†so’‹rwŽœ}Ššˆ‰{Ÿƒ™xqsnodr~hflww[_y{zqqiagaÕ¶Ž¦xnqw{p’Œ‡j˜ˆ›‘‹…{h‡‹™†’‘†‡˜|‰|Œ~Š…zu{‚{p†€•™Ž’”ˆuƒ†vƒ€‹“Ÿ†•Ÿ~ˆa“‡„ˆ„‰ƒg}~‚‹~m‚|‚tkmvtsvukcŽ…~|„„‡~p_sq„|‚|’‰zqƒfzƒŠ‡Œƒ|…~€”‘“„npzŒumnjlz}bhjiXluZRiribQbrxlae]Zjƒmsb[g_el_nTZoNHOge\gnq€lZ[cr_\ckwde]\Zllcmjsv‡qo||tx†x…‚}‡uy‰’•|ˆ†v‰owy{„“pm{w^ƒtmi{s”sgrˆ}r’‘ƒšŸ› †‡vv”~mv“—}‡ƒŠš|‹šv}vqoljat|gbiuzZ_w|zmq~echhW^qr–¼Ãƒuq”ˆ~r–‹†œ“Œ‡rjˆ–€{”Œ„›Œ|Š†}|‰Œ”ˆu‰…vw}qu†ž”…”ƒ‚rˆu„|‰˜˜‡“Ž€ˆf}“‚…ƒ‰‰r}g~‹{x~‡‹Ž|i€|ƒveoxxrvslj…ŠŠx€„ƒk^rxz}Š…{‚€~r€iyƒ‡‹†„y„|˜Œ}nm{‰}wtnhg|vc\pbWorSSnshaNftxe`]\Xn€osYea^jn`pOYkQDSgaZknm|nZ[^lbZcovcf\]`licljsv‚ƒqn~{tuƒ{ƒ‚|…v~‰–xƒŠtˆrxy~oo|qiyz~mm|v•kjw„tl”…ž˜ ™…ˆn}Œvjx˜Ž~Š‚•—ŠyŽ–ozspljd`t{h_eqzZ`r}ygqzaee±²wJbZ¤ÙЖq{Šw}”‹„™‘‹…nk…’’zy’†€„˜Š|‡xx‰Š„–€oŒˆqt}zix…ƒ¥„“Œƒo~ƒv„y…›˜“‹’”…‡p{’‚}‚ƒ‰ƒnxh€…xr‚Š†{e}~„ucprhxpou˜…‚Š{vx€„yk\q}rˆ…‰}†‰zˆrnq„‡Ž„…s„y™Ž„xno„vzehj}p_YwZXqmNWrsg`Klvt`][[Yt}roWg]fjq_nNWhQ?Yg_[pjgyqZZYkeYcpy_h\^emhfliqw‡ol}€uo‚{~‚v…ˆ—Šq‚q{†|yyƒ“Œujzko~t}or|{”onxf’Š‚¡™‘‚†g‡ƒogz•‰~…™Š|Œixrklf_aoxm_box\dk‚zaqv_eeÔ꾊2:>‹Ž€qy…‡Žvƒ–Œ~’Œml…Œv}…•‰|ƒxnv‡„ƒ—woˆ…ku{tey‚ƒ§‹ƒŽ‹„}ntvƒy†œŒ‘’Œ‹†~{’†w„ƒl€ri~xm|{Šƒwby„qdqh~mtqtšŠ€…~ru}€rp[m~txŠƒ‹{‡€|ˆxzqlˆƒ„‹ry—‹‹tnkw€€uu\ihwpYW|SZpeLZrre[Jpwn\ZZY]t~uhYb[genciLWfQ=^f\]ue_tpZYTodYdqyZh^_gmgjlipw}Žli‚„~yn€|}‚zu‚Œ“…p€‹nx~€z{ˆ’‰h{}jt{r†{sw}Œyx„}|kŒŒƒ›–Œ€lŽ~kh~ŽŒ{~ƒ”‚}Šˆkuqghc[bgrn`aksahp‰yast^cd› n\5Y¯µti€ˆ|’†v…–…sŽ‹‰vpl…ƒ‡uy‰x‰|’ˆzsgv‰~~˜oq†~hvymeyˆ„¤†€‡‰~n~v€|Œ™‡‚“˜ˆ‹„‰|ˆp{}„{h~mk€{zizv‡r`w~qdrfu‚mt{…”‘|nwy|t~mXovtŒ‚†wˆv‚‰zxsn‰…r~}~“‰‰znnjn‚‚un]gfsqQ[{N\p\O[rpdUKsxiWYYZaq€t`]]`gdhifNYhM@ad[`va]umXWStaZdorWj^ahkgmlipw|’kh„‰||p~~{€‚zw€Š‹ƒq{‡oqwƒ{‰ƒj~{nwyvŠw}x€‚‡ƒ~~zm…Œˆ˜£„ƒ{u‹ykl„ˆ‘x}{‘€€~Šƒprpcf^Yg_op``gpfjoŠtato[adjv{¾œ¦£È¸q…ƒs“|x†“‚s‘Œˆrroƒ{ƒtu‡tˆw“ˆyyqcw‡z€“ir„vfwucj|ƒ‡ŽŽ}r~s„y€‘‚x–”ˆ‚ˆ{ˆ‰kxy~ugzhkysizv€‚}h`w‡}jktg{ivŒ”~z~~p{v{t~bVw}rsŠ„‚|ƒq†Šwxppƒ‚}y~}vŽ†ƒviqimˆ‚rp]hcsnJeuL^nUTYsnbQOsx`RXX]bp‚s[a]hedcjdQZpIDda[cp^]whUWUw][enhVk^ajgeoohpvz’niˆŒy}r{~x|v}„ˆ†ƒpvƒrnw‚‚~‰‹“p€{wyzŒtƒx‚„z€uo~‰‹šžˆ}…zw†{gt…Œz{‰†„v€gon_d\XeYmr```plkh‰n`siY^dm€w©Ú©Ç†‡²q‰xoŒu{†Ž€z“‰€utt~w€pqm„t”†xtk`z‚yˆfqƒogvm[m}€“€y’’}x{m‡u€‹„t–Š‘Ž‡……{…ltvmgwem{umjvw|`bx†zhtub}zgt…ŽŒ•{tuq€z|mYVt~ou„‡€ylˆ†txkuƒ„}{}x{s‹}sgten‹„ms[j_udHnnL[bWVUxmbPRtvWPUX^aq„o\`cmdc^nbT\rGBf_]fh^[{bQU\u[[gkaVj_`nffkqhpuxŽtkŽŒu~vx~wƒ{s~„ˆ‡ƒoqtqu~…‚‰Š{wxƒ||…‡x‡|}~„€{~svy‹ŽŸ‰z‰vtƒy^}…™Œy†ƒt…†…w‰{bnl[b[[aVjsc`[gnof‡qaqfW]ck|ÊΈ¹¢jmmŠlq„q|„‰~{‘…zysyuu{jluc„u‘‚wof^}‚z‹‰er‚kjqcXl{…›ˆ‚s—”w~{nˆqŠ‹‡q—Žˆ…‹ƒ{y~qqo}fhqbmxqjkqw||y\ey€wiuxfvgt‡‹”|q†io~€yn|]Xrmt€‹|‚oo‰qvhww}qzt‡|zrfsanŒ‚lrXk_w[InkMVU^TU{kaOTurPQTV^bt…h\`ljfcYnaXbpGAh]`f_]V{^OVdpY[jh]Wh`_rfkhrgprw†xn•Štzx~y‚ˆ€ur‡…‚pp{xwuy†††‹†z|u‹~}…„„‡~~}‡|xvyw‘“ŸŒ|‹mv€ycƒ‡—†s’‹o……y‚tcnjY_[]]Tgse`YdqqfsbkeW[`iw¾®{ ·mbs†hs{qy‚…{}Œwxrvo{vejn`‡uŽsjb^~xy‹„fq~hjkZVox‰£„q™“q€xu‚m€‚‘‡s•ˆŒˆ„ˆ„}xtrnhy`jm`mvjgjkywzw[g}|xer}m„teu…Œ†•o‹fkzƒumtb\o|ku|‹|fu‡}mqgu~x~r}kzz{xpflbn‰~mmVk`wUJjkORNhNY|hbNUujLPTU_gvƒf]`qhgaWi][khJEkZbdWYUyZNVmjY]le\Zec^tfmdqgrouwp™…v~w|…‡}us‚‰•‚nsxzzss…‡ˆˆ„y}v|„‰Ž„‚„{~‹ƒ{w|wwš—zŠƒ†iw}|lƒ„“€r‚q…‚~oflfW][\[Tdpd_WcruiupeecW\\hpor€t‰ddx~ituss‚„x€„yvsunkzpagkg†tƒnf]_}p{‰~imwfidUVro¦|„{v–s{s|zn{{…v˜|‡†ƒ†ƒ|tprlgu\mh_ltdgfizo{rYgwugp€wubw„Š|”€n‹imzqfse`mzgswŠ|~buƒvikqtzqyys}f~xwncfbn†|mkVjbpSKikOLNpG^{faMUtcJNSWajv~e\gsif`VcWbp]LKkXcaUTUsVLXudZ_ka\[ce_wfmbpisnrttšw€w~†„z}u‚„~—…nrt{zuq„…€z‹ut|”Ž€…„}~Œ†{~€v{£¥Šyˆ…„lu|{uƒ‚Œzn…sy„}ƒunjheV][ZZSbnd[Xbs{ihmi`bW_Zi€jko€gkahyxjsttm„{}vum{hjyj_enhv„geXbwi~‡{oiogf]UXoh¨wz|Žyuo~osuy€w•t…‚…‡ujrvghn[ld]lr_gaixh{mZm‚rsio€~yw`w„„x„r‡qoyrcqh\owdqsˆ|xbs€pgjxsrlxwuwdƒ{wvoddcn|}klUibfSKmhOGRkEaxgaMSq\IMTYekw{e^mqid]V_UnnWKThWf^XNUlTJ\y_[_k]]Zbe`zhlaoounpwuz˜}w€z€‡†zxzƒ~“„qtt~zvt…ˆ}€}ks•€{‚Ÿ…‡}€~†‚€Š{v„¬Ÿzˆ‡„lr‚zv€€un‡o|s‰€jomddX_ZYZUbjg\Z^ui^nl\aV\\kfqt}ii]kvugtwql…{}}yvrlzhixf]dshzw’ccTepg‚…wwfhj`WVYgc§n~w€‹Žzpp|fyozŒ{vŽq„}~†ndusdhh\kb]oo[g_ludzh]t€orkq{}uuat…Šz‡†wruuaplYqtbqr…|udrlalzojizxurf…uzzupdadns~ilTi^]TKscQGVaGbvfaKToWJLWXgkvzdenqfcZW]XveTJ\cWhXYIWeQHbxZ]_l[^\ad^ij`otxmpnvƒ˜yr€|ˆ‹†~uu†y‡‹}tuu‚xzz‚ŒŽ}~„ˆjs—zŠ}~…zz~|†ˆsq®Œ{{†~frˆzt||vro†l{}lzbpobe]eVYYVcfk`]\s…hXqnZ^WZ\l{cpwvlb[lrsgtupl„y~€ywnnteite[gufvv‘z_]Refj‚‚t}bci\TX]bc¥hxt‚…xmnygxm|…{uˆr€x|xhevl`f`^j_]skYe]oobze[w{knnpwxstdrƒ’~‡‚ˆzuor}rbxd[opaqq‚|sfq€d^nvidgyztnout}sqb_fno}djShXYTMw_QJYYHbtdaITmSILZWilq{bllscaZZ[av[SKd^XiSWGY`NGiuX^am[[_bb]…hhanxylokvymƒ~€’ˆ„€vt‰tŒ†trwvw|}~Œ€~“~px–ƒ|™’y€€xy}tˆƒsp™¢{{ˆ•xduˆysxulto~ly|p‘r^po`gblT[ZWhcmf\\qˆeRrn[ZXX`lwciujj^Zmsqlsssj…|~|wnnldiqc[jrdtvŽs[WSdar€r‚]bc]SZ`[c’Ÿerq…„‘tljylopz|{q€vrzyydeuh]bZag[^whWb]ohaw`[{vjirnwssthp”‚†~ƒurjp|mfwW\kmbqszsfo~[`oqb_jq}llt~sqxkpa\ellzagSgUWRPv[RPYRIcsb`GUjPHPZUkkk|emoqa\ZXYlpWRPfVWiSTFZ\OHrtX_cmcXa`a]‹jcdmyxkoiuy†{kƒ}€„™|‚„y}ˆn†qowz|t‚‚|‹ƒ‚—tw‚”…Ÿ‰u€€sp‡‚uo¢—t{†‹†{ex‹nn{ofxpzlsvrŒk^tnagekR][VgbllZ\qŒdOon]VXUgjtgbtee]Ymtmpuuyj‡||ˆwsddkna\nmcsx‡kZTVbcx}}q…]c_cTZ`Yc–•cnpƒ…Šsjhznesvs|lztuoy~u^frc[^VbdXaueU_`mdaq]]~phisqspuujm„“ˆ{„qrfn}proS[fjfqtwsblvUbqj[_ne|emv|srsjm`Zdjjw^fTdUVPTmWQWSPHer_aFXiNHWTVmhd|ikxkbW\U[tdSRWhQYfTSHZZPMxw[_eliZb`^^nbfkyunohvvlƒ€}†—{ˆ‰~k“ˆrgt€{u€ƒ}ˆŽŒ“s|Š‘…‡Ÿ†{†Œs€†s}ƒvn¥Œs‹vwmzŒ`d|pfzsylmqv‚gd{lcfghS^^Tg`lo[^nhNjm`TVSogskewde]Xotlrzwrlˆ{€vœ{zkaelm^`ojepx~gZVX`kx|{p„_b^gVX_Wdœˆbkq‡}wkkxl[vqlziusno{€rXjn_Y]UacWdqcS^aiablZ`~lfksunmwvkh…Œˆz‡mpfp|mrmcYahiottr^ilReqdTbnbzcqv{ukpmk_Xaght\eVaVSNXeRO\OOHep]cFYiMI_KXmd_xhn~d`U^T]t[TR`fN]aTSJ\YPYuv]_fmhXca[^Žpcgjwqsngvtzƒrƒzˆ~|Š‡ŽynŠtls‚tˆ…†‘„•y~Œˆ‘›„€|Œ„sstwqn““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~~~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’’’’’’’’’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’’“““’““’’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ‘mfggggg}…„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDBN¥¯­­­®°knnnnojfggggfo„ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‘g_```_^yƒ‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR455553A©¶´´´´·|ehggghc_____^j‚€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}z{z|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‘ŽŒ‡‡‡‡‡‡‰““’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†…………†‘‹ŠŠŠŠ‰Š‰ˆˆˆˆˆˆ‰ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z{|{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘’’’’’’‘‰‡ŽŠ’“Š‘Ž‘ˆ‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŒ‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…Ž‡‰‡†‰…ˆŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰†ˆ†………‡ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰Œ‰‰†…‡„†ˆŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}|}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹Œ‹†ˆ††ˆƒŠŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz||||}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒ‰ŽŒ‹Ž‰ŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzzz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{{|}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{y{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†……………„„„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰ŽŠ‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{}~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““””””“””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••””•“’’’’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””’’“““““’’“”““““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘’’““’““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’‘‘‘‘’’“’“’‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡ƒ‹Šˆ‰‰†……„„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxz}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzop{xy{|{xw{xuwttvtuvwuqrqnprpghklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkiffggghhgmgjghehgcbbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__ac_\_]`]^Z^]YY^ba^^ZY_[XWSNMLKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{xvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSTPMJMNPROMPQQQQRVVQQQTPPNNOLJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTtsuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMOPPRQPNNONONOPPQONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKLFDFJKKKHJLLLOMLLNOOOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEBA@@CCDEACEHKOKIIJHHJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AE@>:;>><ED=?EA?@A@DEGGGGBDDDFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@;;><;<<<HL==AA?BC=ADDFCFFDFIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnpprtusqrvyy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;:;;99:88;<98:<<>=;;:8:@@AB?A@CFDCCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqusurqtxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<:79::979::78:9:;;8789;:8<<=@A@=;;><==@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyy{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>><==?@==;Ke@==>=<<<;;:;<>=>?@A@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquutusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCDA?=>@?=?=kxT=CE?>@=;===<;:=>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVpoqssttuyz{{|~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???CFD?<<=@MLFHwuY7<:==@=:<;;<;89;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pprrrtuvz{}}|~~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC?>AAAB@InP;=d‚~uzvS788:<>??<;;<;::;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC?W{yRe„ƒƒƒ„|xR<=?=BFAD?;<=>?==>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hloppqtuvy|||||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCE@Ytw{‚ƒ|€ƒ{L?@C?JR=MG<<=AEABBFHC=<@DCAA?>=@A>>>?<>@DGE@>@A?@CFECBCC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{|{}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA?Rus~€{€„{~†b@CCE>O[LmhI@CEIIIIMMKECFGHEGEEEDDCA?@>>BFJJGEEGFFJNNKJIGGHKLIGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@EFku~y‚„……†}JDFDBc~…ˆ‰~XGHJLLMOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHIHGFEFFFDFHGEEHHFHGHFQnnpqrvvy{{{z}}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJG]x‚ƒ„„††‡jABVt…‡‡‡‡‡‚WILMLMNLJGGGGDGGGGFHFHECDDFEDDHHCCCGJJKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrswwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLLLX„……€ƒ†‡‰}Sm„‡†††‡‡‡‡|PKLKHGFFDECC@ACCCCFFEB@>>@AA@BD?>?DFHDEGIJIIHHIGIIJJIHFJJJJIJIJJJFILLJJKKfopsrtvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKLLJ^„„…„ƒ††„‚†…„„†††‡‡†ŠuIIFB??@???<<<>::<AA@><998<<=;>;9;?AB@ACCB@ABDDBCFHIHHHLMLGIJMMNMJJKKJLMSloqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHHJJIj†……‚€ƒ‚‚ƒ„„……†‡ˆˆˆ‰‰ŒŽfDC=88::9878896479;<:8567789787588;;;=@;999=<>;;=ADEHJMLLGIHORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@CGIIg†…‚€ƒ„ƒ‚‚ƒ„†‰Š‹Œ‹Š‰Š‹Œ‰^?7656766645763468:876565676778:77789;7578979876:<@GFIFIFEFOSRSSROPPRTepqsttwy{{{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:=ECBj„€‚ƒƒƒƒƒ…‰ŠŠ‰‰ŠŠŠŠ‹‰‰Š‚H676468874578467699766765:9:::;898977779:98878589;A=>>BA?AKLOQPQOOORWkqrttuwy{{{|}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897;B9A{„€‚ƒ„„„„„†‰ŠŠˆ‡ˆˆˆŠŠŒŠ‰‰Œz>:88;<=>9:;<89;9:;:99;:9===?;;;=:>;9;;<;<<99<8::;:999<?<=ABDIJMKIKLWorsutvx{{{|{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<;89989:::;?=Pƒ‚‚„…„…†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>ACEEAAAB>@B@@>=>>@???@?@==?B?AA?A?=@@@>?A=><;:;99;?=;;==AACABCAXpqtttvy{{|}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::<=:;;==?@BY…‚‚„…„…„†‰‰ˆˆ†††‡ˆ‰Š‹‹ŠŠŠ‹‰‹^>DGIKJIFGGDFHGEB@@CECCABCB?@DHECEDEEAFEFDEFD@B?<@>=?@>???>?>>:;=<`qrttuwzzz}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>???=A@DDE^†‚ƒ„…†††ˆ‰‰ˆ‡†††‡‰ŠŠ‹ŒŒŒ‹ŠŠˆWHLMMKNJIKHIJJIECDFGFDCEFDBHIKHGGFGGEKIKIJKJCFCCDBAACBDCCDDCA=;=@hpsttwwzx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLK@BBA98<>;<;>@?A?BCHHJ]†‚ƒ……‡‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹‹ŠŒPMPMKNKJLIIIHJFDGHHIEEHFFELLMIJGGHIJOMNLLMKHFGGEECFFFFDEHHFCA?@Llptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?FGG=<@@87<;<=:?@>@@CFJJQc‚ƒ…„…†‡‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒ‹ŠqMQOMLLKLJHHEJIDJHGKJHJGGGKLNLLHHIJMPNPNMOKIGIJHIDIHHFFGGIFCBACUnpuwwy{xyzz||}~~~~}~}~~~~~€€€€€€€€€€€€€€TDAABGHB?8?@8:<8=>;=A>?@EIKMVrƒ„„„„…†‡ˆˆˆˆˆ‡†ˆˆˆˆ‰‰ŒŒ‹ŒŒŒ‹‹‹‹_QQPMNMKJGFBGJGLJFKOLKJJMMLOPNHIKLOQQQQOOJIJJLJLFGHGEGIFEEB@BB\orwxyzyyyzz{{~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<9@>>@BGGAHLMQWy…ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹‹ŒŒŒŒ‹‹|WUQRTROLKJDEFKONOWVQPOQSRMSTOMSLPSUWRSQPLJMMMKNGGJFFHJDDEEBDCcpuyyzzz{z{z{|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?==B?BCGVNFOQQUY|†ƒ……„„‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŽ‹‹‹gVUkaERQQPJ;;QSR`u]UVTVYYRXXRZfPUWZ]RTWQPMRPPPQKKKHHJHEFIHIHIirvyyzyz{{|z{|}|}€~}}}}}}~€€€€€€€€€~~SHJIIGGFE??AAEBCGEDELXRMTVVX[|†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ}aŠ‹‹†l[dU:XXXSP>@VUY[c`VYbr^]V]ZVEQYZ[Y_TYgRUVXTTVTOOMJLJIILMKOMSosvxyxwzzz{zz|}|~~}~}}}~}~€€€€€€€€€€~~~VJJIHGFDDBA?HMIMPKIKPTSSXZZ\\x…„…………†‡‡‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~Œ‰Š‹znpXZ[ZRSRVVTZZtƒYU}a\X]^WIV]][[_YHYXY[]XXYWRQNPQMMOSQQURassvwwvxxxz{{|}}}~}~}}}~~€€€€€€€€€€€xy}YNKIIIFBD@A:PQQWXPPOQSTTXXYZ[n‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡ƒŠ~fYY\XSVTWRQWUb–€QerXZW_hP`f[[X\gaGOZhg\[\]]WROSPPQVVVVYZnrtwvvtwxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZ[RSQORRRUSVTW_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PUXTRTRQQLOLKfyZ]TYUV]ZLTZTST^ZXWWWzkXZ[\^TQQPINOWVXZZdqsvvttvxyy{{||}}~}}}~}}~€€€~~zxwvsu{€€tk~~kry^[VUTROKFCDAM^ƒlVRSNOQOQURSRRTcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ymqVIKMNKMKHJDFHEC>ScURQQNKRTQMOYQMNQSUUMQSRPOMLHCIHRTUZ\mruvussw{z{{{}{}}}~}}}~}~€}}~~€~{vsw}~~du}iqt_d]^[YVPLILIal’tPQSNQRQR[RSRQRUUbs{|€‚}{{€ƒ‚…†‡‚†††„†…†u_]KC?CCCCB?DPBC@C>BHGV@HNMG]iQHFOFDEFHGHBCHGHKGCBAD@OPMSdstuustuz|z{{{||}|{~}}}~~€€€||}€€€}vt{mh|gnqfiedb[XSQPURsWe[OONLQSQUYSUQQTROV`klrv{{xytrnstsyx~~ƒ€ƒƒ‚€‚€‚kLG??;;>@???>kQJaEFHIEB?GLMGMQUIBE?><=<==?=?ACC?><=B>JMFUnuuustvx{|z}||}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QRZ\Y^IJPQNKLQRQTUUWQQWVPX[b]agmmlokh`nrjmlqu{z}{xz||xwxdB@@B=:BCAADB\]O{NOONKLMOOQLKLWMHG@B<977599=;;;8989?;BH?\ttuvuvwy|||}||}}~~|}}}}~}xuvz{zwyxuw{|yxuywcqhipmnmmhf^OP^\ZIGPRQOMPQNQRTVXSRYTNYZ[WY]^^`e`]^qvk^`gkwooljonnlfbXGFFHBAFIEEFDMRPaWRXQPSSRU[OOQWPMJCF>::6486979:366795<B=ettvwwyy{}}||{|}~~~{}~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZWMLTTSQQUOLRSTWXTTXQLXYZVXXVXY]WWXhsk]Vaskaa_]d`_^YUPMONLHHJKIHFCQPSZWTTMQSYS\eUOSTQNKIHC?A9988978847578599Gnruxxz{{}~}}|{}|~~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPXVVSTVOOUVXXYSUTLKTUUUUWPTUWTUR]n^RNY_[VY;DUWT[fJLPRROMMNNNLJFPPUYSTNJOOTST\VRUSROMKIHHF??=:787659967665Wppsxyz{|}~}~||}|~}}y}}|~~~}||}}~}|rvqxxrvuqqnppopuvtnjddjppqrpnfedc\^RTZVWUTWTRXXYYYRUOJHOPOOMRJOPPPNNOTLMIPOSTU2<XMIAQ=caQSQPNPQPNNMPNTRPRMILKOQPQRSTQROLMKLLHCBA=::876;B4566;epquxx{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqptuvcjgeWhtrrqniihpVVTUXUWURWVUZYXWUQSFEBFGGHFJDHJHGEHLHKHFLMPMG/E_R>3@>joaRRQ@FUQPQPQNQOPOLJLLOPNNPQQNPOJLMMKGEEDB;=<<9=G6676Dnqtvz{{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknbePSTRSUOWVVYYVQQQO@>;=?@BAC@BEDA@GHGHEFHJNKEGCORC8ENS]fSQSAGUPOQQPMMNLJLKLNOOQMOOMHLLIKKLKGFFED<AA>;@E;<89Tqsuy{{{}||{y}{z~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLOOMQSLTUTWWULLKH=987;?@><=A@B=>EHGDFFIGJJ@FAA@FHEJOHPRa\QPRNSOOOLLOMKMLMON[WKMQOGIHCIJLLJFFFD?BC><BF?B?Adqux{z{{|{zzw|xy~~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCE=9879?B>;?B@@>ADIECHGIGIEBB?>=CBAGIDMOaeQMONWKLMKLMMLLKNNSdMJLRIIIEAHJLMNJGIFBAB@?EFEHDKopwzyy{{z|zwsxtx||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGLMIMPMPOHKE?B=999:?B?<@BBADEGKFDIIGGHCC?B??@A>CECKMQTLJIMTFIIJLJKKIILMOPRPKGCKGCBJJLMOMIJIGCCCDIJMLIZsmxyxz{{y|vrpurtyyvxjqnjllnttmtu{stxronqovsnporpopstyjN`gsjt|ygosqjqheqHKDGHHGJKIJKDGB=>=:::;@B?=BBCCGFJLJEIIFGGCC;A@B>@@CECIMOGHKFHKDHIKMHJLHHJLJM]RIHDMFADKJNMPNKMJKFGGJMNQNLcnivvw{x{z}qmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoijthdoFKDFEGDEEFEGBC@><=:;::@D@>BCDEIFJJLFIIGFFDB;BCC>?CCCEGLNGKNHDHDILNMHILGEFIILNKJHENHCGMLOMOMNNMLIHJORQRNRfgfrosxu{z|lhjoekpmsqfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGJDFFEBBBE@DB>?>:;;=:=>CA?ACEGJGIILHGGGFEC@=EEB>ACCCEGHIGMPIFFFKNOKFHJFEDDIIHKIFHPKDIMLPMONOONJJIMRUTROWd`amgproryzgehhcilgqlflmgiklslpvutpnvrosrsutqssutsuvvvyvutvlkuumrvqlnlerMGEEGCBABD=BA>A=::=?;>>@B?@BDGJFJGIHFFGECBAAFFCBCBDEDGGHFLQKIOJJLKIGHEFEDCIHHKJGKRMCNOMQOOONOOKKKPUWVUTX`^\iaminhrsbeffdihfnifmmhkkmriqvusqmvnoqrswsrstuvvvvwvwvvtwuksunutsqrjksMGGFHBBADD<AA@C<89=>9?<?B?@@DFHEHFFGFEEDCECDIFCFEBEGEEFGEJMKHQMJKHHIEFHHECIIJKMKOSNDQRPQQNOMNPMLNSWVWXVX]Z]d`hbjigk_eegcgggkggkmkmlpqgttursnvoqprtxqssuvu‚‘yvvtxuuwxnouorsuqqiozMHGHHBBBFE<@BBD<7:=>:>:@B>??CEFDFDDGECECDEFGJEEIGCGHFHFECFJJGMJLKIJLFIIKHEKKLMNORTOISUTQSPQMNQNMQWZVZYVZ]ZXa```^hec`dehgjihjfhnllnmqpiuuxrrpupppruvpusuvu{~}xvtwvvvxplupmstnprsyNHHGIDACHE<@EBE=8:>>=<<AB<?>ABFCEBBGDCEEFGGGIFGKHCHHGIGFDHKIGKHMKJKLHLKMKINLONORUVOKUVTQTQRLOQPOTYZY\ZY[^_^`b]\ackb`dghr…hgifjmnponsqjtuxrsstrnpqvrquruus~yŽ}uuvvvvxrhuqkrtlqvquMIKHJEBEGE<@GCD@9<>@?>?CB<@>AAFCEDCHDFDGEHHFHGIKJFJHHKHFFLHHHJGLLLLLIMKNMMOLPPQUVWOKVVUSSRQLORRQV[[]^[\^__a`ad]d`ef`ehjcssfjhglprqossnswwquvtsmoruorspurvrtvuuuwvuwtgtrkqrkrvovJKLILGBEDE<@FDDB;??A@@@DA?B?ACHBEDFGEIEFDIHFIHJLHHJJILJFJKHIJJGKKMMJJMLNNNPKOPRUXVMNTVUSRQPLNTSRW[^^_]]`_aaa`bceachbdijgv‹lkigmosqpqppryvruutsmmssmqrotutrpswtuuwvuuteqskpqjrvowJMLLLGDCAD<?EEEC=AACBBCEBBDAAEGCHGHGEJFCGIGGJFILHJJMKMLGKIHLKNQKRQLSMKNNOPPOTOWXX[NSQW\ZSVPNTUTTXZ_bb_da^`b^`eaabgnhbihhmxvlhimosrpqrrrvtsusssnksqmprotvrqquvuswywutucmtkopjqtowLMLKLGEA@D>>DEFC@CAEDDFCCEGCBIFCHJJHIKFDKJGHJIIKGJJNKNLILHJMKZfJd\KlSHON_nUks[qpbwcRPbvuhucav`Xnqbdvinzf[lt`ljT`wuijgifglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqrqyKNJKJFC?@B?=DEFDCDBEEEFBFFHCDJEEJLLJLMGGMIHIKHKJIKJNLMMLLILML[sbdp^lmUMNfs]geqlntgpi_aYnnbppbkjjgoqtetno\ougpMJryvkb`keemymkvlnpsrprqpqrqrrrtrmmsnnoprutqsstuuutwxvutbmukpplrrqzKLIIGED?BB?=CFGBFCEDEEDCHHGDEKGGLMMKMMGJNHJKJILJJJKLMNNMMJMMM[roonpplkMPQlWNibtrpamov\YlQ\mmZqmkomxxtsip\_rkqjUuyxpc^kfbgqpjioppsspqpqqrrqqrrtlmrmnnorutqtrtuutuuzvutenukpolsrryJKGGEEEBBB=?@FGBGDIEEDBFIHHEGKJGMMNLMNHLMILKHJMIKJJJOPONMKNML\hdu]lqWlNPQmUZk^klvaldtTecNmYl\tpkilxjwuhp]^rkhWbcw|oc`ghadjuyknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtwIMGIDEECAB<BABFDGFLHECCHKHHFJLLFMKLSRLGMLHNJIHNHJJIHNOMNLJMMJZsppoqqmlOQRnYqkgooqqomt^nXat_nopoqronusttj[]tcwxrjnzhaacgbbjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyytukoumtonssvtHKHIBEEEA@>CCBGCHIMIFCFJLIGFJMLFOJKWRKGKJJNIHJLIKJIHJLMMMIKJKSkbZi^_jcrrZ_Yjo_eeUk_c[abQ`lh]j\niid[pfdp]Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunwqrutwrHHFIDEDFA@AEDDGBHJLHFDGKLIEFJOLIOIL[QJFHHKMIHJJKKIHIGKKKKFHJJLLLKIKLNT[\TPTLPONOOVQOOQOOQJINPQdqiTYW[[\UY[]X]\\cfaafbce__fkmhmtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyxxuvqruovrtsuusHCEGFFAEC?CGCEGCIKLHFDGKLHDGHPKLOKLWLIEEHIJHIKILJHFHGJGGIEFLHIKNLIO\W^O\[`^OXYS\\b^MYZMXaRJYaZS`d\aX[ddVVX\YZX\VY\]b_d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtOBCDLMBCDBDIDGGFKJKHEEJJJGEHHPJLMJMSIHEAHFJIKKILJIFEJGDFGEEJGCJMJKT_Y`X`a[`UXYT^^Z_RY\P^\YN^\^S[^c^Z]`c`Y_b[`^[TXXY^]ccbaceiekrpoppnow††……†‚{€……††…†…uqprrsvyyzyyxxxwryvxrqxvtvaSJJMIECBCFGEGGIJJIIDFKKKFEHINJNLHLNGHF>GGLIKKJKKIGEIDCCEAFJD@JKIO[cY^^a_RTSW_`\]Y^QY\MV_WKQY[PZ_aa]^ca`bbbcceZQYVU\Y^d`__cebhommllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxXQJFDGEBEGHFGHIFGJGHFHKILDDKJNMLLHJJHJG?GFNJKKMKKKIGGCD@DAHIA?IJGO]aZ[d]_TQRX]\\\_ZKW\LR\YIM^PO\_accccb\dcbdcfXQUTS[XZa^^^aa_dlkmjjlnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMC@IFCEKIFFGHGGIFFFILJNEDKJLNJLIKJHIGBHHQMKKOLKKIHGED?EBHHAAGFDT]Y^X_Y_[]UXXP]]QKJW^X^[]VZ`RQ__bb``bb`cbbddbXOQQR[S[^]]]^__dhgljnnp{{|~{€‚ƒ„………………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKBAGFDGMRHCRKFHHHEFKJMPEGIJKNLLILKIIGDHKQOMLPLMKKHICDAECHGBAFEBVUE\T]SV_XNTUNZ[MJKU`a[_X_^a]OYb]``_bcb]bbW__TPNPQXR]\[\\^`bffelfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDEFGDIRbPDW_IGGHDFMJPPEJIJKNLKKLKJJGEJMQQNOPMNLNHKADACDFDCADFALHCLLPOOLFMFGIJHGLLMOPILOPPSPLPTSUZYWYXXdVOSTPPONPUT\YYZ]\`adechcklpsszy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKM]LGHYMGHJHGNLQQIKJKKNNUNOKKLGGKPSSNPONNNOHKE`ED_LDfcDM[H^\smOMVmYLCP`UlWgJ]WU^DLQULMTVQSTXWTXUT\TPfZhhdXSkTWVU[\[``abbb`fhfnlhrz|}~„„„„ƒƒƒ}|zr{z{‚€ƒ„„……„…ƒƒ~z{LIEFFHEEKOSIKG`THJOJIOMRQKLKLORUROOJLNGHMQ[YOPPNOPOIJPQI|YYrsWPmHqnpaVPqqsPCksmqspSo_[nX]V\XUkhU]VcZ`Y[`VUWjtuu_`w`Xa\\f[_aaaa^`bgmpl`pwtx‚ƒƒ‚}~€vxzlv~tx~€|~€‚„|€ƒz~wwNIEHMMBDLLFJLFRVLKOIKRXWQNNNLQTNOQPKLOGMPS[ZTQROPPPJHZx]TxehYRTQvgtlpbnfjQrOMwmjrpsrqrpop]ezuxqqzq~s}ku}bRg|essoss|}o}yor_``bbZ``gknkblfgmw~€ƒ~{xw€tvzir~nt|~wx{~€ƒx|€u|||ssNKF`]GAEMMHKJHJPNMMJNV^YULQSNYYLSSRNLPIQRTYWWQTPPPQKGfxlcxrmZJLUypumubnvPdeJfvqmwo€jfxxiWsQhzmijzz}lxzogoXvvjuup€`sh|ilx|o^__cb[]bdgijdgbcdllppstsssyqrxblugry{ssuy~suzn|}yxrnMJStNCBEPPHJKJLPOOPMPZ`ZXKTWPa^RVQYSMPISTVXWWPUPONRJKrouuquqdh`VnLqp^FhyWvTKhx}x`y{sna^modRgrunmypwlvttqlm\t~zkmy|lum|kpvux^__b^]_edighee^bbiiijknokqnmjpacfdowxompsy~nqpj{ztromKK[VHGEGRPJLMKLQQQQPQW\YUNVYUfXRRY^TMNITTWWYWOSNNNQHRmHiwK`dvvUWlOnl{sajgvUKWkh}lmlx`[pz{^`zscroxqhe|ir{]TKl`vukiu{{m~xk|p]^^b[^bddgeeebZccikkrsrwgmihdg`alagsrkhlmr|kmhk{tmmkmOHJKHIIHRPLNOMLTSSOTRWRVTPWZVVTTTa`QONKTTSQUVNNLMOPJHQNPULKKSTSRTPVUQQNQQXXQNPUTXXX[[URSW[WXWZOSUWWXR]YW]VTOYRWWWXY_[gr^[[Y\]_cZ_ccdfdccbZccfffmnmuffgc`f_]g`dlhfgkhozhggkujhgilQIKLLMKJSQMQPOLVVTPTUXUYURZ]VUTWUYXPOLMVTQNUSNOMLQPKJQRKQMKKORTRQQSSIHLNOQRQQQTVRXW\WSSQQUUVSZQOSRWUTYVTYUSRUSTTWXW]Z^a]\ZZ\\`c\]bcdgeddaY`acabhhincad^_c]Zd\bma^ffgmsdihkkedcfhPJKLOOLMTPNSQQMXWUTUWWWZVT\`VWVYUXTQPKOWSPNUPNQNKSPMOUTNQNMNQSPTQSTUNKMOQTTRRQVWUYZ[YSURTWWWY[TOTUXUTYUWYTRRWUUW[YZ_]UX_]^]\]aa^[bbchfedbX_`b]`hefda^_]]^ZZ_Z_g`^]]chkagfhfd`bcaPKMLPQLOTOOSQOQZYXWXZZXYV]jdVXYZWVTTOKOVTPOTPPPNMQQPRXTQQOMOSUOWRTUUONMQSUUTTRTXVZ]\ZVVQRWXV[[WQTVVUVXTWWTRRXVUZ]Y]_^V^]^`\\``__ZbbdhhedaYb`b^^fdc`b]\\\\YZ[X[a[^]\_b__bddbd__`\PMNNRQMRROSTQPU\ZZW[[\YZ[dqmhd_[YVVXRMMVSMNROQROLPSRUZUTPPLPWVRWSSSXMOPRTXUUUSUYX[^]\[VROUVV[\WQTWUWXUSXZTSQZWV\^Z__`Ua\`a]`b_\`]cacghdf`Yc`a__ee_`c[Z\[\ZZYYW\Y\[`^`[^^a`_b\Y`ZQNONVQPTROUTSPW\\\X^\_W\^jqwy€c\[VVXRNOWSNQQPRTRKQTSXZWUORNSXVTSTRRZOQSSV[VVWTVZX]^\\^VSNTUV\\VRTVVXYRSY\TRR\WZ]^]aa`Wb[cb^ac_\bab_dfidf^[d`a`ace_b_YZ^[\[YXYWWZZZa\][]\\Z]`W[[ZPOOOYPUUSRWRTP[]^][`\`U\]ijr}slg\UYWQOR[SRQTRTUTKRVU[YZSOSRVVUSOVRSZRTUTX\WXXSX\X^]YZ]TUNVWW^[XQTUXXXTVX[TSV]Y]]`]bc^Y`[eb_dd^^cca]efidf]^da`aacd_b^XZ_[\[XXXXW[Z\`][[\[XZ[^V^Y]POORZPZUUVVTTT^^`^^b\`U]^bkytl}lZUZUQQS\TTTUTVYWLRZV][\ROUSXWVSPXRSWSVVU[]X[YUZ^X_^Y\YRWRYXY_ZZSTVZYZVWY\VUZ]\^aa_dd]^]]eabfd^^dc`\gdhedb_da_a`bb_`^WX^Z\\ZYZWV]Z]^ZY[\[WY\]VXW]SOPWYQ]UVYWWUX_`aa`c]`U]^beeuzhXYZTVSV\XWWVVW]XPU\Y^]]TRXRWVTRTXRSVTYXY]^X][U^_X__X]VQYTYZZaY\UVX[ZZXYYZXV]^_^cbaee]b\`fbdfd__dbb[fchecfaf__aaaa`_^VU]Y[\[Y\YY][[[XXY[YZZ]_]TY]UNSZVS\TVWYWV\`abcad__V[`da_zuohY\ZVXUW[ZY[YXY`WPU^[`a\TUXPUVUSVVRSUW[Z\_^Z_\V__Z]^Y^VSYWYZ]bZ^VW[\[\[[Y[YY^_``dbceebdZbfcgfe^ab`c^cciddg_g^bbcaa`^_XTZZZ[[X[XX\[Z[WWYXW\[\`]V]]SPVZVVZUXVXWX]_badada^YYadb`lfh^\][WXXY\\\_[Y[bVTW^]ac\RVXQWVVVVVTVTX\\_``]`]Wa^[^\[^XVXX[Z_`\_XY]\]]^\Z\X[_a^`dcdfffbYceehgd^c`_ec]fidei_g^cbcaa`__[XY[YZZXYXW[[Z[WXZTY]\Z`\U^bMRWYVWZX[\YWY^`baeada]^Yacb_a`a_\\]XW[[]]__\Z]cXZX]`cd_RXYPXWXXXWVXV]]^`aa_b^Ya]]^Y]^YXVW[[`_]_YY^]^^a\[ZY\_b_bdcefefbZdfgigc_c^afdZiibfice^bbca``_]]ZW[YYXXZXWZ[ZYWXVU[]]]``bbxKWW\YW\\\]ZW\]_`bdbba]`Xbcb`cab^\\\XW[]_]`_][`d\\XZcec`R\YOXWY[ZYXZY`]`bb`ac_\b]_][^^ZYUX]]_`__[Z^^`bc\\W[]`bacedgeefd\efhifcab\cg`\iibhife`baca_`_]]\Y\YXWXYXW\[ZWWXOXZ]acffrkJYW]ZZ_\\^[X][^_acbaa]b[bda_ccb]\[ZWXiq`\`_]\ac_^YYcedaS_ZQYW\]\[Z[[c`cbc`bda`c^`\]^_ZXV[_]\aa_][`abeb_]S\_`cddfdgfefe^efhhgdd`[fg^ahhchhfc`b`cb___]][Z[YXXXVZV\ZZVVULXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡…‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vuuuuuuuvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{{{{{zzz{{{{{{{zzzzzz{{|||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vutuuuutuvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{{{{{{{zzz{zzzzzzzzzzz{{||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||xÅÔÒÒÒÒԓ{}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰ˆ±µ´´´³³»¾¾¾¾¾½ÊÓÒÒÒÒÖº}~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}xÕçääääç™{~†“y1333332j‚€€€{­éääääèʉŒŒŒŒ‹‘»À¿ÀÀ¿¿ÉÌÌÌÌÌËÛæååååéÇ}~}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}v~ywwwwwwxyyyzzzxooppppprrrrrrrwzyyzzz~ƒƒƒƒƒ„||||||}€€€‚‚‚‚‚‚„„„„„„…‚|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚‚‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vtttttwtvwz{x{xwvx{wzzy}zyyxxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{zzzzzyzyyyyyyzzzzzzzz{||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwwy|{|}{}|xwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwww||}}}~}xxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z|ywwwz|}{}~|xxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚ƒ‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzzz}|||{~{xxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyy{xzzy|xxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyyyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{|||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}|||||||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}|}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrstuttssrrsrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqstsssrqqpponnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqqrssssqpqpoonnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrqrrssrrqppoopoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpppqrrqqqpopooppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqpqqqqqqpooppppppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqqqqqpppppppppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsqu‹‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqqqpqqqqpqpqpqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrqqqqqrqqqrrqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrssrrrrrstrrsrsssssssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz|~~|vvwwvuxzxxxxwwwvx|yy|zyy|{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~|{{z{|{}|{{{{{{{yxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}||{~|}~~~~~}}||}€ƒ€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€~€€€€~€~~~~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~~~€€€~~~~~}~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~~~~€~~~~~~~~€€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹Š‹‹Š‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚ƒ‚€€€€€€€€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒŽ‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒ„‚„„‚‚‚‡ƒƒ‚€‚‚‚‚ƒ‚ƒƒ‚ƒƒƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒƒƒ€ƒ‚…………††‡†…††‡ˆ‡‡††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠˆ‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„ƒƒ‚ƒ…„‚‚„…‡‡‡‡††‡‡‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ‘’‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„ƒƒƒƒ‚ƒ„…„„……„ƒƒ„……‚„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘’’ŽŽ‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€‚‡‚‚‚‚‚‚‚ƒ€€€~€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„„„„…„…†’“‘ŽŽŽŽ‰ˆ‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~€‚‚†šˆ€€€€€‚€‚ƒƒ€€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“’Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚ƒ„‚‚‚…ŽŒƒ‚„‚€‚‚‚‚„ƒ€‚ƒ‚‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘ŽŒ‡…ƒƒƒ‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒ€ƒ‚†…„ƒ~}|€“ƒ…„ƒ‡…€‚ƒ‚‚„ƒƒ‚„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”“’’ŒŒŠ…„„ƒƒ‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~€…”‹…~|}}~{Ÿ‹‚‹‹†„‚‚‚‚ƒƒ‚‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†””’”’Œˆ„„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~~†ž—‡}€~‹…€‘„ƒ’“‹€‚‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“’Š‡ƒƒƒ„‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€„œ ˆŒ‚}†…}‚„ƒ„‚”˜‚‰ˆ€‚‚ƒƒ‚‚ƒƒƒƒ‚ƒƒ„‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†ƒ…ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„”Ÿ…„ˆ„‡€~~………„…Ž…}}}‚„ƒƒƒƒƒ„ƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„……………„…†…††…………………………††…†††…†††‡†…………ƒ„„„‡“““’’ŒŠˆ…………‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…ƒˆ‚‚…~}‚‡†ƒ€~~ƒ„ƒƒ„„„„„„„„„„„„………„…„†……†…†††…†……‡……†…††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„ƒƒ‚€€€‰„~}…€€~€€„…„…†††…………††‡††…†……†‡‡‡ˆ‡‡‡†††‡‡‡†††††††…„ƒ„………„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘“’‘‘‹ˆˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒ„„„ƒ€€ƒ†ƒ€~~€€€€€€……†ˆˆˆ‡‡‡‡ˆ‡ˆ‡ˆˆˆ††‡ˆˆ‰‰‰ˆ‡†‡‡‡‰ˆ†‡†‡‡††…„ƒ„…†…………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†…†„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡†…ƒƒ…„„„ƒ€€…„‚ƒ‚‚€~{z‹Œ‰ŠŠ‰‰ˆˆ‰‰‰‰Š‹Šˆˆˆ‰‰‹‹ŠŠˆˆ‡ˆˆˆ‡‡ˆˆ‡ˆ†‡†„ƒƒ…‡‡‡†……„„ƒ……„……†„„„………†…†…ƒ‰”“ŽŠ†…†…ƒ‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡†„„…„ƒƒ‚€„…„‚‚‚‚‚‚‚€~}}}}~|z|Œ‰‹‹ŠŠŠˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰‡†††‡…†ˆˆ‰ˆ‡†‡„ƒ‚„ˆˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚‚ƒ‚„ƒ„ƒŽ“’‹ˆ…„†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„……ƒƒ…„ƒ„ƒ‚‚‚ƒ~}~~~~~~}}~}}~ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡‡‰†ˆ†ˆ‡†‰‰ƒƒ„ƒ…„„……†ˆ‡†…ƒ‚‚ƒ…‡†‡††ƒ‚‚ƒ„‚ƒƒ„‚‚ƒƒ„ƒƒ‘’‘ŽŽ‹‡„††„‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…‡ˆ‹Š†„†„‚†…€„ƒƒƒƒƒ‚‚}|}€~~~}|}}|y|ƒ††‡„ƒƒƒ„………ƒƒ…„„„„„„…„‚‚ƒ„„‚ƒƒ…†…„‚‚‚ƒƒ…ƒ„„…„„†ƒ„„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰†„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€‚ƒƒƒƒƒ‚‚}}€€}~~}}}}{zz~„„„‚€‚‚~‚ƒ€‚‚‚‚ƒ„€€€ƒ‚€€€€€‚‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†‹“‘Ž‹ˆ……ƒ‚„‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€€ƒ‚~~~~~€ƒƒƒ‚ƒ‚ƒ‚}}~€€€~}}}}~}|zzz‚‚~€~}€~€€€€€€~}}€~€€€€€€€€‚€€‚‚€‚„ƒ†’ŽŠ‡‡†ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒ‚ƒ„…€€|}}~}}~€€}~}~€ƒƒƒ‚‚}}~€€€~}}}|{{{zzyz€€€~~~~}~~€~€€~}~~}|~€~~€€€~€€~€~€…’’Ž‹‹‡‰…„„‚‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~}~€€~€„ƒ‚€~}~~€€€~}}}}{{|zzyyy{€€~~~~€€~€€‚€|~~~~}|€~€~~€€~€~~~~~~}||}…“’ŽŒ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒƒ‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚‚‚€ƒƒƒ€€}}}~~~~}}}}}|||{zyyyy}€€€€€€€‚‚€~€~~~~~€€€€~€€~~€}~}}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…ƒƒƒƒ…„„„„„ƒƒƒ„‚‚‚‚‚~~}}}~~€}}}}}}}}}{zzyyyy€‚‚‚„ƒ€‚ƒ€ƒ‚ƒƒ‚€€€ƒ„‚€€€€€€‚‚€€€€€€~~||Š“Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…ƒ„…„…†…†††…†…ƒƒƒ‚‚€}}}}}}~~}}}}}}}}}|{yyyyx|‚ƒ„…‚„ƒ‚‚ƒ…†‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚ƒ„ƒ‚ƒ‚‚‚‚€€€~Ž“Œ‡ˆ†ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€€~}}}~~~€ƒ„‡ˆ„†††…††‡‡†‡‡ˆ‡‡‡†}€‚~}}}}}}}}}}}}||~~~|{yxwxyy€ƒƒƒ„ƒ„„„——ƒƒ„}~‚‚‚‚ƒ†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ…„„…ƒ‚ƒƒ‚ƒƒ‚‚‚‚ƒƒ‚‚’‹ˆ‰‡‰‡††„†…„„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€~}~~€‚………‡†‡‡†‡‡ˆ††‡‡‡†‡…~}}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yxy|~‰–„ƒƒ„„”“€~~…‹€€€„†‰…„‚‚……‹ƒ‚……††„ƒ……ƒ…„ƒƒ„ƒ…„„ˆ’ŽŒ‰ˆˆ‰‡‡‡…†…„…„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„ƒ…„~}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|xyz{|€‚ƒ€ƒ‚€~|~~{ˆ‘||Ž–}‚†Š…ƒƒ„ƒƒ‰~ƒ„……ƒ…†…„……ƒ„……†„„Ž‘ŒŠŠŒ‰ˆ‰‡………ƒƒƒ‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚€‚€~}}||}}|||}||}|}}}|||{‹‘—Œz{|zzz{|yy}}~€€|{{~~}‚•‘„ˆ~|~‚„||‚„‚€‡ƒ}‚‚‚€ƒƒ„„„„„‚„ƒ„…„‘‘Ž‹ŒŒŽŠ‰‰………ƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚ƒ…ƒƒ…………ƒƒƒ„‚‚ƒ‚ƒ‚‚€€~~}~}||||||||||||||}|||~~Š‚{z{zxz{{|}{~}~}}}}||}†~}‚~~~€‚||‚€‚€~|{Š‚}€~€€€‚‚€€€‹”Œ‹Žˆ‡‡……„„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ…„†‡„„€†”ˆ€‚€~~~€|||||||||||||}|||||||y{{{xxy{zz|€~|~~}€‚‚€€€‚‘€€~€~~~€}}}{}}}|}||}€€€~€~~‚”‘ŒŒŽŽŠ…††…„„…ƒƒ‚‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚„†‡††~ˆ•Š~€€~€~~~|{{|||||||||~}|{}|||{|||zzy{|z}…ƒ‚~~€~…‚~€~~€…†‚€~~ƒ†~|~€€€~}}}}~{|}€}~€Œ‘ŒŽ‡„††…„„„ƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}€‚ƒ††……~€€€~~}€€€}}||}~}||}}}}}|~|}|{}||z{z|}|†„‚€€}~}~~‹„†~}||~‚}}}}€|{}|~„ƒ€~~~~}}}~€~~~„’ŒŒ‹Š†„†„„ƒƒƒƒ‚‚‚ƒ‚ƒ‚€€}|||}~{{}w~vx~}|}|}~~‚ƒ€z}}|~€~€~~€€€€~~~~~~}~~}|~}~}}|{|||z{z}~€ƒƒ‚~|}|}||ƒ~Œ~|{{}~}~~}{{{}|z{{{€†…‚„ƒ‚€~‚‚‚‚‚€ŠŒŒ‹Œ‹ˆ„„„ƒƒƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€~€€}€~~~~|‚~~}}}z|}}|z||~€‚€€€||}|||||}|~{~{{{|||}|{{{{||zz}z~‚~ƒ„‚‚…†……††‡…„‘ŽŒ‹Š‹‡‡…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~€€€‚€~~€€~}ƒ||}}|}}}}{|~~~~~~||||||{~~{|{||||}|}|~|}|{{{|y{|{{}z}~~€€ƒ‡‰‰‰Š‰Š‰…ˆ‘‹ˆ‰‡……ƒ‚‚ƒ„„ƒ‚‚‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€€~~~}€€€€ƒ‚€€€€€€€€~|z|}}~}}~~Œ†}}~{{ƒ‚}}}}}|}}}}}~|}|}|}}~|~}}}}|{{z|{||{z{{zzz{~~‚…ˆ‡ˆŠ‹‹‹‰‘Ž‰ˆ†…„‚‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„„€€€€‚~}~€~{~’Œ|}Š€Œ~~}}}~}}~}|||}}|}|}}}~}}~~|{{{||}|{z{|yzyxy{~„ƒ„‡‰Šˆ‰Ž‹ˆˆ…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{|||~~}}‚€€€‚…ƒ„‚‚‚‚€€ƒ‚€}~€~|‰‚~ƒ„„ƒ~}|‡}}~}||~|}}|}}~~}~}}}{|}~||{|}zzyyyy{{~~€ƒ‡„ˆŽŠŠ†…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{}}}}}zx‚€‚‚€€€€€‚‚‚‚†…„‚ƒ€‚„~€}~~}~€€}~„€~~}~}}Š…}~}~~€}}||~~~}€}~}|}||{|}{{{zzz{{|}~}€ƒ€‰Š‹‡………„ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv}€ƒ‚‚‚‚‚ƒƒƒ‚…†„ƒ€€€€‚€„~~€~~€~}~~€€~€|€~€~|}}|~~~~€}‚€|}€€}{}}}||{||{{{|{|||}|ŠŠˆˆ…………„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚‚‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€ƒ€€€€ƒ~~€}€}}~~€€‚€€€}€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{|~|}|||z|{|}‰††……‡………„‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz~}yxtt€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚~~~€}~€}}}~€€‚€€€‚~~€€€€€~}}}~|~~}}„€~}}}~}~~}~|{|z|{z€‡‚„„…„„ƒ…ƒ‚‚‚€€‚‚ƒ‚‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xyuu}‚ƒ‚ƒƒƒƒ…„…ƒƒƒ„„ƒƒ„‚€€€~}}~€~~~€}}|}}~€€€€‚€€€‚€€~€~€€€~~~~~~~~……€€ƒ~€~€~}{z{z|{z‚„ƒ‚‚‚ƒ‚„‚€€‚€€‚ƒ‚ƒ„ƒ„‚„‚‚‚‚~€~}~~~~}~}}z{|…„{{syz|pwuvwyutz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€€}}}~€}~~}~|}}~€€€€€ƒ‚€~€€€€€€€€‚‚‚€ƒ€ƒ‚€€|{{z|{|‚€‚€‚‚€~‚‚ƒƒƒ‚„‚„‚‚€~€€}~~}}}~}}{{z€x|vyy{qtxwvxury……‚„„‚„……†„„‚„ƒƒ€€~€€|}}~€}~~}|~~~~€€ƒƒƒ€€‚€€€€€€€€€‚ƒ€„}ƒ„€€‚}z{{|||~€|}}€€~}}€~‚‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxyzruyyvwwsu†…ƒ……‚„„…„„„‚ƒ‚ƒ€~€~€}}}~~€~~}|€|~€~€‚ƒ€€‚ƒ„‚€€‚€€€‚ƒ‚€ƒ€~‚‚„€€‚‚‚„‚~{{||||}}~}z~}}x~|||~~~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„‚„„…ƒƒ‚ƒƒ€}~}}}€~~~}}€€~~|~~~‚‚ƒ‡…~~€€€€€€‚‚€€~€‚~‚‚ƒ‚ƒƒ…‚}}}|{||yz{z~y{yx~{{{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst†„„…ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€}€€~€}~}~€€€~|~€€~}~~€}€€ƒƒƒ~}~~~€€€€‚€~€~€‚‚€ƒ‚„„†„€~}||||zyvyyzyvyv~|{{{~}{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…„ƒƒƒƒƒ‚‚ƒ‚ƒ‚~~€}}}}€€€|€€€€|€}~~}~~‚‚~~}~~~~€}€€€~~}~~€‚‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{{{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvpxyrx…………ƒ„„ƒ‚„‚‚€‚€~~~~€~}~|~€€€€{€~€€€}€~~~}}}~€‚~~~~}}~~~|€~~~ƒ~~€€ƒ‚ƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}|{|z{}zzx{|zz{xtxuqrtpxxry„………ƒ„ƒ‚ƒƒ‚‚‚€€€€}~~€}|~}€€€€|€€~€~~~}}|€€€€€~~~~}|~~|}€~}~€‚~€€~‚„‚‚ƒ……‚‚~}|{{||yw|ywxwwx{{{{|…Š}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzz{zxswuqqrpxwq{…†„…ƒ…‚ƒƒ‚€€€€~~}|~}€€‚€€}~€~€€}~|}€€€€~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{||{zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚‚€€}}~€‚‚}~~~€€‚€€~|~|€€€€€~}~~€€‚€€€€€€€„‚‚€~|}~~z}…~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚€€€€€€~}€€‚‚€~€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€€‚€€~}~{“z|}|{}y{zzxyxy{||}|||||||}}}||}|~}~~~}|z||{|}{yzzzyysuuooqpwst}…†ƒƒ‚ƒ‚€€‚ƒ‚€‚‚€€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€€‚‚€€€}~~|†‰||~{{~yz{z{Ž~wwy{|{}||||{}|}}}}|}|~~~~|z|}{|}{yz{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€€‚‚‚€€€€€€}~€}€ƒ‚{~~{|}{z|||‡yxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ‚„„€~‚€€€€‚~€€‚€€€€€€€€€~}€€€€€€€€€€€€€€€€€~}~}~~{}|}{||wxuxxy{||}|||||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒƒƒƒ‚‚ƒ‚„ƒƒ„ƒ€‚ƒ€€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€€‚€€€€€€€€€€€€€€€€€€€€€€€‚ƒ‚‚€‚‚€€€‡~~|z}|{}xwvyyz|}||}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚ƒ„„€ƒ†ƒ„ƒ‚„€„ƒ‚‚€€‚‚„‚‚„‚€€ƒ‚€€€€ƒ~€ƒ‚~‚€€€~€€€€€€‚‚€‚‚ƒ‚‚ƒƒƒ‚€€€„}}}|}z}zyvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysruowqwysw{…‚‚ƒ‚ƒ„‚ƒ„ƒ€€‚ƒ†ƒƒƒ‚‚„„ƒ‚€€‚„‚‚‚~€€‚‚ƒ€€€€‚„€~ƒ€ƒ‚€~€‚ƒ‚€ƒ‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ€‚€}€|z|{{w|yyy{z}~}||||}~~€€€€„„€}€~{{{z{ztpxrytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚‚…†„‚ƒƒƒ„„„€ƒ€ƒ‚‚‚‚‚€‚€€€‚‚‚‚‚€ƒ‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚‚„ƒƒ„‚„‚ƒ‚‚‚‚ƒƒ„ƒ„„„„„…ƒ„‚ƒ‚‚ƒ€€~||€||x|yzyz|}|{||}}}||€€€€€‚~€€€€{{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚ƒ†……ƒƒ‚ƒ„„…‚‚‚ƒƒ‚‚‚€€~€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€ƒ€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒƒƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{~~}y|zzz}||}z||}}|z{~~~€€€€€€€€€}}|}}|vrvxxvtvu}‡‡ƒ‚„…ƒƒ„…„€‚……„„ƒ‚ƒ„„€ƒ…ƒ‚‚‚ƒƒƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚‚‚ƒ„‚‚€€‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚~ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz{}€}||z|~}|}}~~€€€€~~€€€€~|}}~~}|{xvvw„‡ƒ‚ƒ…ƒƒ„†„‚…†…„„ƒƒ„„„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„ƒ‚‚ƒƒ‚ƒƒ‚‚„„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒƒ„„„„„…„ƒƒ„…„…„ƒ‚€}‚€}||{||€}}~€~~}~|||}}~~~€}}~€~~}}}~}}~~€|}€‚‚ƒƒ†ƒ„ƒ†„‚ˆ‡…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒƒ‚‚„ƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒ‚‚ƒƒƒ„ƒƒƒ„ƒƒ„„…„„„…………„ƒƒƒ}„€}}||||~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒ„…ƒ„ƒ…~‚Š‹…„„ƒ‚ƒ…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ…ƒƒ„…„……‡‡†‡…„„…„ƒ~~|~~}€~||~|z|}}}}}~~~€}}|€€~~~~~€‚€……„ƒ„„‚„ƒ†€‚……Š‰„„„„……‚‡††„„„„…„„„„ƒ„ƒ‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ„€}uyƒ~„„‚ƒƒ‚ƒ„ƒƒ„…ƒ„…†„…†}„y|~ƒ{…ƒ„ƒ€}}~~~ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚‚ƒƒ‚‚†„„„…„ƒ„…ƒ„…ƒŠˆ………ƒ……„†††ƒ„„………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†spurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚…„‚hzrss|€rƒƒƒ}}~~}~‚ƒ‚|}€}}||||}|||~}~€}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ…ƒ†ˆ††…ƒ††‡‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vyy†r„ƒpvxqvtturstvi€nrotvnulwm{sn€‡zm}rsvsvmnwlpylu}}~€}€}€€}}|||}|}~}€€€~|~€‚€€€€€€€‚ƒ‚‚„…ˆ††€‚…ƒƒ„‡†ƒ………†‡‡„ƒ†‡ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoomw}x†pqzprtfu~n{ysoy€}}€{}|€~€€~~€€€~~~€~}€}€€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„†……††ˆ„„†‡ˆˆ†‡„††‹Š…„†‡‡…ƒ………„‚……„…†……†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„qjoyxpkyszozwvvp€~~~z~}|}~}€ƒƒ€‚ƒ„‚€€}~~~€~~‚€€„‡†ƒƒ†„„„†‡†…………‡†ˆ……†…‡‡…†„††‰ˆ…„‰‹ˆ†„†………ƒ……„†††††…ƒx‹yrˆz{pp…„x…xyks~y{krƒ‡ƒz|mzyyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozls|nw‚€~~}}z}{|}}~}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡……………‡‡ˆ†„†…‡††…„……„……†‰Š‡…„†…††…††„†††††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„…†…†„†„ƒ„„†„„ƒƒ„„…„…„…„†ƒ†‡…†„„…‡†„„…†„…}w…ƒ„„‚}~{|{~{||}~}|~}€€}€~~~€~~~~}}}~|{|~||‰†…„†††…††…………††‡ˆ†„†…††……ƒ„…†…„††††…„†„…††††„‡†‡‡†…‡ˆˆˆˆ†„‡…††ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…ƒ‚……†……ƒ…„„„…„……„……ƒ††††…„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ‚}€{{|~{||}~||~}€}€~~€}}|€}~~~~~||}~{|||{{~ˆ‡„„ˆ†††‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡…††……†„…††‡‡…‡†‰ˆ††‡‡ˆ‰ˆ……ˆ…†‡†‡†‡†‡…‡‡†‡……†‡…‡†…‚ƒ…††„„ƒ„„ƒ„†„……………ƒ††…†……††…„„……ƒ„‡…ƒ‚‚…ƒ„~€€|{}~{|{}~}||~}~~}~}}~~|}||~~|}€|||}|||~z{{|~ˆ‡‚…ˆ‡‡†‡††„„††‡†ˆ†„…„††„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…‡‡…‡†‡†‡…ˆˆ‡‡…††‡…††„„„…†……„„„ƒ„…„†††…†„†…††……††…„ƒ„„ƒƒ‡ƒ„‚„„ƒ€€€{{~}|||}}|||}}|}|~}|}}||||}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††ƒ…†…†††…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡…‡††‡‡‡…‡†ˆˆ‡‡…‡‡‡…†‡„‚„ƒ„†…‡…„„„„„…††††……‡……‡…†…‡…„ƒ„ƒƒ„‡ƒ€‚ƒƒ‚‚‚€{}~}{||~}|}}|~{||{|||}{{{}|{~|{|}}|}}~}|zz{{||ˆ‡‚††††‡††…ƒ…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡ˆˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡†ˆ‡††‡‡…‡†ˆˆ‡†…‡†ˆ††‡ƒƒ„„ƒ††‡……„„„…†††††…†‡††ˆ††„†…ƒƒƒƒ‚ƒ†ƒ~‚‚ƒ€ƒ‚|~~||}}|}}|}{{{z{|||{{{~{{}{z{~||||}~}{z|z|}‰‡ƒ†…†…††…„„……………„ƒ…†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…‰Š‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……‡ƒ„†…„††‡†…„ƒ……†††††…††‡†‡‡…ƒ†…ƒƒ‚€ƒ…‚ƒ~ƒ~~}||}}{}}|~zyzy{|}{{{{~||||z{}||||~}€|{{{{|{‰‡„†„†„††…„…†…„„ƒ„‚€ƒ…ƒ‚z„Œ{€„…‡†††…„‡ˆ‡†‡……‡‰‡„‡…††ˆ†…‡„†‡ˆ††ˆ‡‡‡†‡ˆ†„†††‡……‡ƒ„…„†††‡…„„ƒ……††‡††…†††…††„ƒ„…‚‚€ƒƒƒ‚}€~ƒ~€||}}~}{~}|}yyzy{}}zz{{}|}||z{}||}|~~€|{{|~}|ˆ‡…†…‡„†„……………ƒƒƒ€‚…‚€}|{„…††„…„ƒ‡‡†††…„†‰†‚†„†††……‡…‡ˆ‰†…ˆ‡‰‡††‡…„†……‡…„‡ƒ„…„ˆ††‡……„‚……†…††‡„††††…†ƒƒƒ…€€€€ƒƒ€|€~~‚€}€||}~}~{~}||yzzyz}}yzz{|{|{{z{}}|}|~~|{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€€ƒ~~~€yz}€ƒƒ…‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ†…ˆ‡‰‡†…†…ƒ†„…‡ƒ„†„„…„‡†…†…†„‚……†††††„…††………‚‚ƒ„~€€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|z{{{|}}}|€~}||}~|{‡……††††„…„…ƒ…‚€€€€~‚‚}}{‚ƒƒ…†…„ƒƒ†ƒƒ„‚€…‡…‚ƒƒ„„„††‡ˆ‡……ˆ†‰‡…„„„‚…ƒ„†‚ƒ…„„†„‡†………†ƒ„…„…†…†„ƒ„……ƒ……€ƒƒ~€€ƒ|€}}‚}€~~~~~}}{|{zyzzyzz|yzz{{{|z{{{{}~}}€}}||}€}|†ƒ†††††ƒ„ƒ†‚…€€€~€‚|~~€€‚‚‚„…ƒ‚‚„€ƒ‚€„……‚€‚ƒƒ„……‡†…„†‡…‡…†‚ƒ‚‚ƒ‚‚…ƒ…„…†„††‡††…‚„„ƒ„†……ƒ„ƒƒ„ƒ…„€‚‚}~~~„~{||€}€}~ƒ}~~}}~{~{{zy{zyzz{yzzz{{|z{|{{~~}|}||}€~€†„……„‡„ƒƒ‚†‚ƒ€€~~€}‚|}~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡†…„ƒƒƒƒ„†…„ƒ‚ƒ‚„ƒƒ€€~}}~~|~ƒ~|~||€~‚~‚|~}}|||{{zzzzy{zzzyyzz{|y{}{|~€}~}}}€€€†„„…„…‚„‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„…ƒ‚ƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚€…ƒ~€~|}~}|~ƒ}{~|}€ƒ}}€~}|||}{{zzzyy{yzzyzz{{{z{}||‚€~€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌËËËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFK=8765999<>9?<D:;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937677=;>9=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<9<<98:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA><A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÔÕÔÔÔÕÔÔÔÔÔÔÓÒÓÔÔÔÔÔÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9?CE@<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËÊÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø×××××ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÛÜÛÛÛÛÜÛÛÛÛÚÓÒÓÓÓÓÓÔÔÔÔÔÔÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILO@99:4;A<7=9AC>@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÏÐÏÏÏÏÏÏÏÏÏÏÏÏÖÞÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¹´ŒŒŒŒŒŒŒŒŒŒŒŒˆ‚ÓÒÒÒÒÒÒÓÓÓÒÓÓÒÝãâââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVN<::77>C?8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÌÐÒÒÒÒÒÒÒÒÒÒÒÒÑÞìëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§£££££££££££¤œZUVVVVVVVVVVVWNCCCCCDDCCCDD@\ÒÓÒÒÒÒÒÒÒÒÒÒÒÐàìëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;?C>6:7>>;=B?8<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÌÌÑÒÒÒÒÒÒÒÒÒÒÒÒÑÝêééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤¥ž_YZZZZZZZZZZZ[SHHHHHHHHHHHHD`ÑÓÒÒÒÒÒÒÒÒÒÒÒÐßëêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;?@@8:;8<;;<?:;;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÍÐÒÒÒÒÒÒÒÒÑÑÑÑÐÜèççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©ª£hdeeeeeeeeddee]STTTTTUTTTTUQkÒÓÒÒÒÒÒÒÒÒÒÒÒÒÞéééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB>;=:9;:==;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÎÎÎÎÎÎÎÎÍÍÍÍÍÍÎÏÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÏÎÎÎÎÏÎÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÑÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌËËËËËËËËËÊËÌËÍÔÔÔÕÕÕÕÕÕÖÕÖÖÖØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<8@B<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÐÔÒÏÏÏÑÓÏÏÒÔÕÔÐÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××Ö×××××ÖÖÖÖÖÖÖ×××××××××××ØØ×ÖÖÖÖÖ×××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?79:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÏʖ¥ÑÏÒ¸ŸÑќ‚„ŠÆÏÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<>B>BC@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÏϜª­Õ²—˜¸º•¸¹¯¡ÒÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?>;7:>9?D?A98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÐ˔ˆšÌ£¨±Ñ’}~¯°ÒÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<<:6?B@B:647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÏѽș™Âň›¶ÕÓ͞žÃÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8FA?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÏÏҗ”ŸË×¥›µÔÓÀ  ÐÏÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<>=964:99::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÏÓ³›Ä˜ÔÕ¢šµÔÔ¯¢©ÔÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:=?>=<9@<<::9?@>=<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÐÑ΍žÂ×¢™µÔÓ£¡ºÔÑÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CFCAB8;?<=;<<8558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÐÑËÚ¨™¯Ú¢š¶ÔΟÉÒÑÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF@HIGE@<<>><=><756:969;::;8@?:<<9<>=;;:?9?:;9=>=><;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦ÕɎ¥šž´Ù£šµ×ß¡ÒÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;557<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡Ê»¡¦§œË×¢›´Ù²¤¦ÖÒÒÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKL@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÓӞ¶ÖÕ²„ÆÖ¹ƒ¿ÕÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<=?GFHKH=657:979:;:<=9>99:8;=>>A>=9<<:=>>:=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÒºÄÕÒÒÑÄÕÑÑÂÓÒÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??>>AELLA>775;8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÒÕÔÒÒÒÓÕÓÓÓÕÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEK>>786967899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9699:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EILAALD??;9889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEHIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDJ;AA;<886486987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGJB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<BA<;876797799=?A?<:9@?<>B?:8776=??@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE>;HF89757875898;>>=;89A>=@?A>7596;>AB??@@BB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCEEC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELCA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<=9;<;DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGHNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAC?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8:87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€iixsg~‰‰xp‚†{w}~…Š½ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9768579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€‚wt|„‚}sp€Šx‚yƒÈÞÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsoupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿¼½¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»º¹¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjcmgb\XQPQKTJB:IQ?A7<94:565455688686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸········¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µ¶¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸¸·¸¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶·····¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨¨¨¨§¨©©©§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸········¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥£¤¢¡¡¡¡ŸŸŸŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§§¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©ª««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤££¢¢¢¢  ŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž£¤¡žžŸ  žœœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=7789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥¤£¢¡¡¡¢£¥§¦¦§¬¬§¦ œ›¡¡ž›ššœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¥¦¦§§¦Ÿ›š›¢ ™––•š›™——˜˜šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜—™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥¢¢¥¦¦¥¦§¦¦ ›™›¡ —““’—šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB@DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥¦§¦¦¢œž¡Ÿ—‘‘”—›˜–––˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;;;=<:;<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¥¦¥¥¦§¦¤¥¦¦¥¥£  ¡¡Ÿ™’–š™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šžŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡ ¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢¢¢£¤¤¥¦¥¤££¡¡¡žœš•“”˜›š›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œ ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸŸŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::88:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸ   ¡¢££££££¢¡ ž›™™˜™™™š™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢ ›ž ¡£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?;:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ ¡¢¤£¢£¤¢­§W^]TW_nkšš›œž››œŸžœœœœŸ   ¡¡¡  ¡  ¡¢¡¡¢¡Ÿžœšššš›œš™š›™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥¤¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¡¢¢¡   ¡¡ ŸŸžœš™š›››œ›š›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›šœšš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;A>>?=>98;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤¤¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ žžŸ     Ÿ ¡  Ÿž›š™šš›š›››Ÿžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›ššš›™˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9;;>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœ›œžžŸžœšš›œœ››œœžžœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:=>:?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››š›œššš›œœ›™™œœœžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™˜˜ššš™™™˜š›œœœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›š™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š››››œ›˜˜˜™™˜˜™™™›œœžžžžžžžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ›››››››™˜˜˜˜˜˜˜™™œœœžžžžžŸŸžžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ››››››š˜˜˜˜™™˜š›œœžžžž  Ÿžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_]]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜™——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜˜™——˜™››œœœžžžžœ››œœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±³­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=:F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œšœ›œ›˜™š˜˜™ššš–‹“–™˜•˜˜–›œ—•’‘’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨©¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‹‘‹ŒŽŽ‹……‡‹ŒŒ‡ˆ‹Ž‹‡Œ…†‹†ŠŠ‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VPQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹‹†Š‹‹‰†„†‚€‚‰‘ƒ€ƒŒ†‹‰…€‡}€’†„„†ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹‹‰‰…‚}s}ˆ€~œ„……‰‹Šz}}†ŽŠ†”‘‹—”—’˜¡–ž—•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¥›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ†‹†ˆ…„ˆˆ‰„‚z||}~’ˆx…‹Šƒ„…ŠŒ‘™””” ššŸ¢­±­©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPFMHSWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‹‡Œ‹Š‡’Š‡†‘“‘‘„‡}}ƒˆŒŽ‹ŽŠ‰Ž””˜‘•œš¨®²¯¯µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWLO_^\NUUbQDTM;?9<895775795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš˜ “—š ™›£ •› ¤£š“ˆˆ‹‰‘‘Ž‘Ž‹˜šŒ”š—œœ›Ÿœ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUKTOOJCPK_bXZQ\T`MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ª©¨§¡¥¨¨«©©¯¡›Ÿ¡££ šŸ œ”˜”˜  ¡¤ž›š¤§¤©«®¬¥£¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdVOXKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®ªª«¤¡¢¤©§§©¨£¢œ››¤ ¥¨£ ˜™Ÿ¡¢©§ ¢¢®¬«ª§­®¨¥¤©©ª©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_UZNRNPORd\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢šœ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨¦¥§©§©¨£§¦™œ¤¦¢¡ ¡¡ œ˜™Ÿ ¡¤¤¢žž– ›š¢¢ ¡Ÿ ¢¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOWO^ddlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§¬©¤Ÿ¢ ¢¦¡¦®¦¦ŸŸŸŸŸ™šœœ¡ ¡¤Ÿ¡›šœ ž¡Ÿžž £™–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvwa_\UYQUV[c^s_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?C?:8:>?C@DA:;><@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯ªª­¨¨«°©¨ª¨¡Ÿ §©­°²¯¬£¢¦¡©¥ž¤£¢¦ ¥¤¢¥£ž žŸ¥¢¢žŸ¢˜•žšžŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸ ¡¦¢›—’šš •|wo}yf[[`_Z\V\hdocniib^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9><B??ADB9:€ž¤§¢ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶¯³°«±²±¢Ÿ¢ª©§®·¶´´¶³¯¬«®«¶°©²±­®§¦ž¢££›œ—¢¨¤¡Ÿž£›ž¡š–¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¢š˜¥ ¤§ª©¨ª­¬¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxib[_^\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>AE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢œŸª²¸¼¼½»º¿´¯±³µ´··¯µ´µ²°¨¤¢Ÿ —•š—¤ª¦¦¡¤£¤«¥¥˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨¨«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥¡¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxyxc[RYT__amhukpgiibYSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶´º±ª®´±°±´µ¶¼¼¾¼¼¾Æº¸·º½´¯µ±±º¸·²³²ª¦¦Ÿ˜¤¤§¨¤®¤««µµ®³ §ª¬§ª©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš’–””˜“š˜Š‹‡€€|‚xa^YSah`fsositdidb[LK>:8898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÃÆÂù½¿ÀÀ½¿Ä½¼º½¾´§ª˜±À½¸µ¹À³¯¯ªª¨­§§¤¯§ª´¼±´µ¨¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`a^^jbbnwuvnl[bQU\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAB;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–••‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±°§¼¼¾ÅÄÆÉÇÅÆ»ÄÀÅÆÀ¹¯½¼À¾¾³«ªŒ³»¾´µ·Âº­¯°µª«¦ª£­¤§±¶«µ²­³­¨®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|ƒjfhaklfnuqruqf^_\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCCDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÅ¿ÃÂÆÅÀ±“¾º¿Ã¶¶º©´³´©«³»»±Ÿ›±¯¬¤¬®´§ª©¨ª­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|tkkndomhqxoyjia\gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÃÄø´À·´¼Á¹··¿À»®¥®·¼·­œ£·°¦­´µ¬®¥¥£¨¤  ¥™ª³±¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyz{vnkiguZfrwsyfg]d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÊÆÄÃÃÁľ¸¾ÁÃÀľÁÏÏÎÆ«¯¶´µ« §´³®«¸µ³«©£¢­©¬¦­Ÿ¬µ³¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuueeijg]jomxwcb``^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÏÏÌÃÇÆÈÉÈÈÉÇÅÉÇÈÇ¿ÅÇÄÄÇÈÊÒÏÒ̼¸¶´¸¸Á¾¾º½º¼º¼¬­§ª»º¹·À²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqobagugiitmxl]d[U`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÍÐÎÇÌÉÂÁÇÁËËÈÆÌÊÍÅÆÅÃÆÅÉÍÐÍÏÌÇÄÀÃÂÉÍÇÅÁÄÇÁ»¾´±°°Á¾¿ÁÆ¿¾¸·Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`jjvlieuotb]bTWTSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<9>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÅÇÈÆÒÉÁÂÿ¿¾ÄËÈÊËɼºÕÖÉÌÈÃÈÉÉÅÅÃÂÁÂÇÇÉÊÇÌÈÇÈÍÆËÏÅ·ÀÀÀÀ»º½µ³³¿¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrpfegdjeajmno^Y\VVNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾƹ»Ã¹¸¹¼½ÁÇÁƹÊʜÁÆÃÀÄÁÂÁÄÁþ½ÂÀÀÁÂËÃÆÌËÅÈÑ°¾½¸º»¼¾·´°¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·½Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfadbabccjbgc[ZZ\YQNE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶¸´´µ¿»½À¹¾ºº´À¸µ·²®º»¶À¹Ú›~¼Â¾À¼»Ä¾»ÁÄÀ¾¾¸¼ÁÁ˾½ÉÄÀÀÊÀ±Á¿»¸»¾ºµ·´¸¼´½¸µ´°³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ¾ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ §¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|yˆ}qc`bbgjgfiei]VVTYOSKE8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“’’˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´µ±°µ·µ»Á¸¾¹¿¼¼·´·¯®·µ¸½Éʃ„¥ÇºÃµºÇ¸¶¹»½¹º¶»ÅÅʽ¹ÅÀ¿¼Á¾¸Æ½ÁÀ¼Å¸¶·´¸¶¶»»¸¶´·ºµ´¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¡¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒ€xqmeefoiekhXXNKKKRILHC9=8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<97>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’š”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿¾¼²­¯¬±°·¼·»½ÁĹ··¹·º»º»¿Ñ©{‰º¿Ç·¹¸­·µ¸º´¸³»ÅÆËÁ¼ÆÀÀ¿½¼¿ÉÃÄžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ˜ž¤œ–œ£œž¡œ¦–~‡|knpgpksebm_\THKJDJBCG?9;8><7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘ŽŽ˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼¼À·ª­¤¯°¶¹²½¾»Ä¶··¦˜§¦§¶ÄȌy~…¹ÉÏÂÀ¸®µµ¼¾¸º²¾ÄÄÊÅÁÊÿ¿¾½ÇÌÇÇÄǽµµ¶Á½º»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†qflintnxcgb[cQKTHEECGC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?>??FD@A?>:7?@CC?@=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼ªª£°ºÑÓ´»¾¼Åº´ŽnhpckyŸ¬{{‚…»ÑÑÌÊĵºÀÃÈ¿¾µ¿Á¿ÆÆ¿ËÆÿÁ¼ÀÃÌÊÇÅÆÀ¹½¼Ä¿À¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtolltkln_b^`aNHM?E@?DC<;::;:8;<:9<>9:>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED<AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±³Ä²ÆÙ¼½»Ç­ŽxcbjNRZ`~y…‰¼ÊÌËÍÊÆÂÄËμ¹½¹¹ÀÿÈÆÄÁÁ¿ÅÀÊÉÃÃÄùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{zˆzmmw{_pc[]_^SI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA??ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸µ¼¸½iw½Î¿¸¯oYbdSlgSQQ[s}„»ÃÇËÈÁÃÁÀÉÊÂÀ»º°´»½ÀÅÆÅÅ¿À¿ËÇÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²²¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¤žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}znsxsgp][^\YQEDCMIAE=G::59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘–žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯·¶²µ³·¹¼»¶»ÁÀti}«¾¶pVJVjIZwsTPf|…š¼½¿ÆÀ¹À¼¾ÅĽ½¹²°®¸·¿ÃÇÃü½¿¿Ãþ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸¸¸½¹»±¶²ÈÀ»¶´±°·¬³©°­­´·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y}vluzpni[__YSPAEHGK@DCH<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BCBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿš›œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹É¿zwi©—VOJwtMQlyƒ{PT‚‰¡·¸·Âº³»·»¾À»»¼®¯®³²¹ÁÂÄþ¼¿»º¸¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ¯µ´´½º¾¹º»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬£¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰|‚zsvvwnq`_f]ZTJ<??FF=FCC9:5;99><<::<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¸ÈÀƒ~sq“lOH\‰hOOO®}]Kx¤¨±²·¾¹²µ²¼¹¼¶º¾²´´´°¸¾ÃÆÄÀ½¿¹³¯²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtvql_ca[]OHA>=HCFMC@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·Ä»Œƒ{x~aI`Œj^QO^®Ž^PN{¶¶°¶ºµ´²¬¼¹¸µ¸Áº¸³±¬·¼ÁÇÿ¹ºµ®¥¬³°¦°­¨ž Ÿ¥­¶µÂ·¶´¥¨«¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´·¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wo{ourmc]fX\]RNMA>IBAJI@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³²­¶º¯­¼³¸ºÁ›Œ…‰~SMˆžxjZVl^u‡noz¥¼¶±´µ²´¯¬»º¸¶ºÀö®®ª²¶¼½¹¶²±­­Ÿ¤§§£¦–™™šŸ©®¹¬««Ÿ¥¨¤«®®§¯¬¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmuik][jT]\OMHDFLBFNF8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹º¶¹»µµ³¼ª–šLUŠ½d{‚‰gb{jbmv ¾¸²´³°±­°¹¸¶¾¸»¿²²²®±®¹¯ª«­¬£¨¡žž—˜¡•’•—˜Ÿ¨®¤£¤ ¢§¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬ª¯£¤£¡© ›“Ž“’’™–š¤¥ Ÿž§˜•’”™ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wrxhtsndT`cW\QNLH@HQDMC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯²°¤š¤L`~yly}cajktym‚¤·²­³¯®¬®¶¶³¼µ¯ª¤ž›œœž¨¨ž ¨©Ÿ¡§–›——“–Ž—›¤¨  ¢¢¢¥¥££ ž¥ ¤¬¤¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›©¨««Ÿ¦¢›£œ•Œ“—•–˜Ÿžžš˜¦—“’–¢ ¥£¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦ ˆxƒ|vybwln\QhTPNGPMLBOQ@>;>39:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¤¬©´¿³³oa…oiiWc]^STYca\q{¢¶ª²´®ª«¯°²µ­¥ž’˜”˜ Ÿ¢ œ¤¥Ÿž¨”›–—Œ—‘—“˜¢ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£ž™—š«¦ª±£¥¨ž œ•“‘˜–•˜—Ÿ˜›™š£™—”–š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’}|€uu}mk{dhUQcMJHGORMJNG<E@=2?759;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜——–¡¨¬®¶·º¹º··»®¨ ¡¨¡¦ÃÐUunfofW[QHEGILKNae{³¯¯³µª¦¬«¢œ™”Ž‘–—™™œ ¢¢œ¥žš¤———–’‘‘“š—› ¤ªž¡¡ž¦§ª¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¡¤¡›˜ž¯¨®²«¥ªª š˜˜˜•“–š“••š–›——˜¡žœœ—›¡šžš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}vx|dyy`bRU`IIJKSTIRPL9?B67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—“’œž¤¨®­¬««¯ª¯©ž—ž¥ž»²ƒ}a_maTHFQKIDIGEJUY\¥²°°¸¬¦¡œš”—ššŽ‘•‘ŒŽŽ”™¢œ—£™š—˜™”™˜–›Ÿ¥¦© ¦£ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§  £±®²±´ª²¯¢™œž¡™››š˜™›”–›–™œ¥¡ š£¡š™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ Ÿž ¥¡žž¥ ¦™{|uvsh‚le[SZYMQJNOULSLA7>B68=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’‘œ˜¡ª¢§ ž§¡¥Ÿœ’›¢›ž£§¡gh_TGIV}~hSGCBFLPSŠ±®¬¯§Ÿž¢ —‘“› œ™—’“Ÿœ¡¤›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬¨¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½·¾°¬±®­©ª´±°¨«¨²µ·³¸­²´¤ ¥Ÿ¬¡¡¢  š˜–– ››˜¤¡ ž£¡ žšœ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚|xuiwu]lZR`HRUHFUVJBLG=KH8E<67;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“Ÿ™¨®Ÿ§žœ¡žš™’˜ž›¡¡¡wj[QJFLq § lNEB@?BTƒ «ª©¤ŸŸ™’’“˜˜––•Œˆ‹Ž•ž–žš¦  ¨¥±ª§®£«­¶°´²±®¶¸½Àº­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«¯±¹·¼¯³°µÁ¼·½³³µ¢¬¢©¨²©«¨§¨š™žšª§ ™§ ŸŸ§¨¥¤Ÿª¡¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰…„~vqmivmhm\X[BWNJGMGBFM<>L=4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜™ª ±¢·¤°¦Ÿž—˜•™žšœ¤ yg\RMKJRÙÙÀudVIDS‘¬¨­©ª¥Ÿžž¡¢Ÿšœœ”“•”žž˜”…š¡›«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶º»ÀĹ½»¬¯§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¹Â¾¸³»Æüü·³©³­ª³´¯³®ª¯£«§¶±­¢°¦¡£¯±­°¤¥¯£¡ š¡§¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¥ž¦™›¢¤žŸ›››œ‡…{trkkurphW[QETHDJPI?EA4FH95;=6;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž  œœ˜šŸŸš žnVNLNMVg¡Ð» —¸¦‰˜®¸®§££¡ ž¥«¥ž—œ”‘™˜”ŒŠ†ˆ†ymˆ ¤¢«¬´¼¶Ã¾¾³»ÁÃÂÅÀ¿ÂÆÆÅÃÈÂÀÅÇÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌÌÌÒǾ¿ÀþÇÆ·ÃÉÉÂÁƾº´ºº´»·°µ²ªº²®»·¿»ºª·­«ª¸º´¼®®¹£¦£ž¦¥¢£©¦™›Ÿ˜š§ª§ ¡¡¤˜”£–”™‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ„}zqkchoxjdZ[FKLEDSLDBE7:?;549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ²²¸§¡¡«ª¡œž¡¢œ•`NFJLVk~§¸ª†ŒÔÖÆ¿·¨Ÿšœ›žž™———’ŒŽ——“Ž‹‚ƒ‚wsqnp¦­®´¹Å»ÍÇË¿ÂÌÎÍÌÇÉÑÌÍÌÇÉÅÅÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÑÔÍÓÐÓÓÌÊÂÆÆÇÊÈοÈÑÌÇÅÇÅÁ¼ÃÁ¾¿¾µ¾³®¿¿ÂÃÇÄÇÄ®¿¸²¸¼ÃÁÁº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›Œ™‰•˜› Ÿ£—žš““‹•…€ytsebgrof^ZYCNLCEPIDC@5558:B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>8;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›¢¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¤¨¬­ª £Ÿœž”\JBHLhy©¸¡±Ë»¯©¢žœŸš˜–”’”–‘Œ‡„ƒˆ‡ƒ€€yrroly¤¶º¹¾ËÁÓÒÓÈÍÎÑÓÑÒÑÐÑÑÍÎÎÐÅÎÔÕØÒ×ÍÆÇÉÌÃÅÊÏÊÓ×Ñ×ÒÕÖÓÓÈÌÇÌÍÉÒÍÎÓÍÅÈÉÊÁÆËÇÈÉƿó³ÈÄËÊËÏÆÊ¿¾¿½ÁÇÄÌÌÈɿÿ­¯³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›•Œ†‘‹€zruvgcgvidVWQDMF@IQB=B<:22@<D<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<A?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­³·¬®£ž£¢ ¢lJJLUu¢ÍÒ»¡¤³ª£œœœ ¤ š””•”‰|wpkebhqoq{…Š€vpnqtp…³Â¾ÅÑÐÖÖÖÒÖÍÔÖ×ÔÓÑÓÔÔÓÏÒÃÐÓÖØÕÖÒËÉÎÑËÆÍÒÊÒÖÖÙÕ×ÓÖØÎÒÊÏÑÌÎÐÌÒÏ¿ÈÇÊÃÌÌÌÎÏÅÆǶ¿Ê¿ÑÍËÏÆÉÈ¿ÃÃÈÎÌÏÐÏÍÊÇ͸·»¨Ÿ¥«§ž˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„|xsvpc`drb]R\IJGAEHI>;A8=4585;86:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÁűµ¨¡¤¥ ¡¬erv³ÑÛѽ¯©™•˜ œš  ž›œ™•‰wic`____^_`^blusqpolrqu’ÄÇÆÔÕÖ××ÓÖÏÕÔÚÔÔÎÏÕÔÔÑÑÌÐÍÓ×ÖÓÕÐÏÒÓÑÉÓÑÈÐØ×ØÑØÒ×ÙÕÖÌÏÏÊÍÒËÎÐÀÆÂÇÅÎÍÑÑÑÈÌÍÀÊÌÅÓÎËÎÈÄÊÇÆÈÌÊÓÓÑÕÏÒÌÓÁ¹Å±¥¨µ®§›¨¬¥²¨°³¬¬““ŽˆŠƒ‹„Ž™“™‚…Œ|zqstmacim^VP_JJCFCRM?<>54:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><??=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯­ªª«¦®·¨«·×ÔÕÙÙÑÎп¼Ìɶ¾®¦ª¨¡¥¡‚Š’´ÒÒÕ­¦ —–˜š›œŸ˜œ“}qecc__a__a`_``_`fnppnkorwwœÌÁÒÕÓØØÖÙÑÒÒ×ÏÓÎËÒÍÕÔÒÊÏÌÓÖÒÑÖÍÏÕÕÑÅÑÔÊÐÔÕÖÎÒÐØØØ×ËÈÎÄÉÏÌÊÌÀÉ¿ÇÉÍÎÏËÐÍÎÌÎÏÈËÐÐÊÎÊÂÉÇÉÌÊËÑÒÌÓÑÑÏÐʽȹ°®»¸µª¶°­¨¸­³¿»±šŸ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…ˆzvopokadnpaW\ZIFFDMWE;@=33<=87865;>@=9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ¤§Ÿ¸¶µµ¬¤¬®¾´°ÀØÒ×ÚÜÖÎÍÊÃÒÏÁÀ°©¬­©§lˆ‡ÀÕÌ°››–”—›žžŸœ”–˜”ˆk^^^adb``aa``a^__^]bmroortvvy¤¾ËÕÑÖÔÓØÖÎÎÔËÍÎÅÎÊÒÒÏÇÎÍÍÔÌÎÓÍË×ÖÐÌÑÔËÌÐÒÓÊÎÑÕÒÕÕÊ¿ÉÁÅÌÂÈÉÂÌÃÅÈÊÊÏÊÍÌÐÍÓËÆÈÏÍÈÇËÅÆÁÅÊÌÍÏÑÆÐÎÍÍÌÏÅÇÁ¸¹½Ãýù³²¾±»Ãĵª˜¥¢™–‘••’‹”š‘”””‚‰…ypqkmg``phXXhVLFLIPPB;C>;67:89:57==@;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÄÂÁ¿»µ²±Ç¸ËÕÕÙÚÛØÌÌÏÈÖÕĵ¯´¨ ¬jh~“ÖЪ•Ž˜–‘“’‘–––‹|eabb`]^acb`_``aa`_][]grqqrsqmry¤ÆÓÏËÐÏÔÕÉÅÉÉÆÆ¿ÃÆÏÎÇÅÇÍÊÒÈËÎÍÆÑÒÐÎÌÔÊÇËÎÏÇÇÏÒËÑÏźĿÆɽÂÇÉÎÅÂÈÀÇÍÈÄÌÊËÏÈÄÄÐÈÆÂÆÈľÀÇÌËËÎÂËËÈÇËÐÄÅÈ»ÇÃÉÈÂÏÁ½¼¿°ÁÉǹ½ª°²§¥¢œ˜›£™—™‘•˜‰‚wotdk`^fpa[W`GHHGIMTG?J=64355=<48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ¼ºÍÍÆÐÕÕÙÚÛØÐÉÏÏÑÓȶ»»­¥¥_mwªÔªŽŽ—‡„„„‚~……s`[^^^`^`cdc_]]^_``_[Z\`krrookloo}¸ÑÈÉÊÏËÍĺÀû»ºº¾ÉÆÂÃÀÃÈÊÉÈÊÈÁÅÌÆÈËÍÉÄÂËÉÁÂÌÐÅÌÈ¿¹Á»ÆǾ¿ÆÏËÿûÉÇÈ»ÈÆÅÊÀ½ÂËÆÅľƼ¼ÀÃÅÌÅÅ»ÀÊÂÅÇÒÅÁÉ¿ÊÉÆÈÆÐÃÃÆïÄËÇÃÊ·¿¼º´©¬¤¥˜Ÿ˜¬£¡¥›£ ›”{vstfiZanlZ[XRDLFBGDLDFS@54334?<3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ÊÏÑÌÇÂÃÆÍÎÎÌÕÏÕÙØÙÏËÒÍÍÎÈÁµÃ¾²²•^pw¸´‹“—‡{…†€vxurp_[[]``bcdded`\\]]_^`[YZ\borokilposÆ¼ÉÅÌÀƱ¶º²²³²±Â¼¼¼º¸ÁÁž½¹½¿¹ÄÊÅƽÆÀ¸»ÄÉ¿ÂÉ»·»ºÅÿ¼ÁÍÃƽ½µÁ½Ãº½Æ»Âº³¼ÅÄÁ¶¿¶µ½¿»ÌüµºÈº¿¾ËÄÁÆÂÆÉÆÈÆÐÆÂÌDzÇÉÃÎÍÁÅÃÀ½³·°²§¨¨¹°¥­°ª­¬”yvwjdg`hocV^YJFJFHJAEBEI@9:648853;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÅÂÄÈÎÑÊÊÊÇÍÍÎÑÈÐÆÕÔÖ×ÍÊÏÅÉÅÇÁ¹Å½«¯†`sƒ°’Œ‰‹…y‡‡€~„|ttc[\]^``bcbbeeb]][\^\^]Z[]]hsqmggnpry½ÌÀúÁ¸®°°§ª­¬§¸µ·´³³´¼¶½±·°µ¯²»Â¼Áļ¿ºµ³º¾À¸Ç¹´»¶Á¼¸½ÆÁûµ®²¶º¿´Ä·»µ«¸½½À½±º¶¯¶º³Å¼·®»¿µ·´Å¼¾ÃÅÀÃÅÆÈËÅÀÆÆ»ÈË¿ÏÊÇÃÆÂ÷ý½¶¹¾Ç¿¬µºµ·¶Žytxfgebkn^V^`FKHHJFBDAEE?<:565633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÍÈÅÈÍÌÐÌÍÈÊÈÊÉÊÄÐÍÒÏÍÅÇÁÅÀ¾º¸Éµ©±†hs“žŒ†‰Š{y~††wx‚}ti^]]]_`_`da_dec__\[^\]^Z[[]_lpmhfjmnr|¤Ç¿¸¸µ°«¬§ž¢ª§ž«­³­ª¬©´¯·°²©®¦¬²¼º¶Ã¹ºº±«µ¹»´Âº°À±¾¼»¶»Ç¹Â¶­ª¨°²À¶¸½°°§²³µ»¼«®µ¥®µ®»²°©¹°­»®»¸»ÀÀ½¹Â¿ÇÃÅÁ¼ÆÂÈ˸ÅÇÅ¿ÆÃúÄÆ»ÆÉÌ˳¹Â¼»³ˆsvvkiablhYWW[ALKMIEAC?FA:9:995854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÅÎÒËÃÅÁÅÏÇÎÁÃÆ¿ÄÄÃÃÊÁÉʾ¿¼Àº²´´Ã®©¯‰kc‰“ˆŽ|x~Š…z{„wn^]\]]_`__dbaccb`_][[ZZ]ZZZZ\enohfgiknr­¹°µ®¦¥§§š ¥¡šœ¥«®¤¨¢¬ª¬ª°£¦Ÿª­µ¶±½¹¯·¯©®¸´´¼¸´¼¯¸¹µ²»Á²À®¥©¢«±²³¨½ª«¨«¬­´³¦¨­¡¤¯©²¦§¨®¦¨·¬±²·ºº»²¼½¾¾Ä¿µÂÁÇÈ·¿ÀÅ·Ä¿»¿Ä¾ÄÈÌÊ¿¾ÄÀÀ©‡strji]aodWVXPHYRSKFFE>>@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÐÏÌÃȺºËÁ˾»É¶½Ã¾ºÉ·ÁÃÁ´µ»µ°®´»­¨¨Šcg‹„ˆ‹€{~€~xt|swe_]\\^_`^_ccab``_]]\ZXZ[[YXZ\_fkfegeikor…ª¥¬¥ œ¢¥”ž¤›˜’¡£ª¤¢Ÿ¦¥¨¥­ œ¥¦¬²¯¶·§°«¨ª´«´º±¶µ®¶¹²¯ºº±¶¤ ¤Ÿ¦±§«¨¹ª¤¦§¨§²­ §¦Ÿ›¤¦¬žŸ§£ ¡±­­¬²´³´°µ¼¶»ÁÁ²º¾ÃÁ²¹¹Ã³À½¿µ¸»½¾¼ÂÇÄÂþÀÄ ƒxpkaf_ko`TY^HNgOTHEJF<=?=:;;825536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;=:7676788666;::;9:;<859<:>>@;È´µ½¸ºÀº½µ ž•¡¦º¶«³³»³ÄÏÈËÂƸ·ÇÁÌ¿¸É·»Å¸³Ä¸³¾À«µ»±«¤®²¬ ¢a{‡††|yutomkjjqi^`]\\\^__acb````]\[\\XYXXXVX[^_dcbegggjmoˆ© —–›¡–›¢˜–ž¡£§›Ÿ ¤¦¢¨ž›¢›Ÿ«°¬±¶£©ªª¬¬¤´¹­·°¬³µ®²µ®°ªŸŸ¤¢²¤¦©¸­¢¦¦Ÿ¨¬«™Ÿ ž™Ÿ¥š™£œ›¯©«§ª¬¬­±²¸¯¸¹»°¶»»º«³³º³½´¶±±µ´¿¶½À½ÃÁ»»½—ƒ{sk_e^ddXTW]IW\KPGIIFA<??@;?<04536:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»·ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÆÏÈÈÀÆ»»ÄÃϾ¹Ç¸·¾·²Á´±»»«¸¹°¡ž¨ª¦—ž‰eƒ…†xrnpnkb^bff]]^]]]\]_`abccba_\[[ZZYXXWWXXXXZ^bdeeffhikr§”••›˜›¢––‘œ¢¢¨›¥¦¢¦œ  ›™®®­®² ¥¢®«§¢µ±²²¬¨¯²§º³¦µ ¢ž›£¡­£¢ªµª¢£¦¦¦£–™ž—™› š—œ­¡«§¤¤¦­«³´ªµ°³«²¹´¯ª¯²²³·³®©¬®²¸°º¶º½¿·³±”…yue^e^[YVSZUK[QKIEHKIB=?AA@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½·½¿¶¾¼¿²¥¤˜¥±Âµ¶½­´¸ÂÌÈƿŶÁ¿ÇηÀĽ³¹¹²¿¶±¸º¬±´­ž™£¨Ÿ’š}h€ƒ„xoqtqifdhec\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXWVWadecdeddhjv¢œ””•—— —™•˜ ž¡œ–¡¢©¤ŸŸ©œš«§¯°ª›£¤¸ª¡ ®¨¶ª¦§­°¤¸°¤· ¢›™™ª¦¡š¬¸°¢¡¤œ¢ŸŸ“”¡”––›˜—–—œ•Ÿªžª¤¢£ªª°®¨´«ª§­²°¥«®³±°°®¯¦§§²®±´°¼´¹·®£”yud^aVYWSRTKM^LOKGGLLE<@><B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾¸½®§¨£ª»À½À¹®´¸ÁÌÇÅÂýŷÈ̲ÁÂÁ­¼»´»¼´¸¹¯®¯¨›˜ §“Št{€|wqilrtpihedfb\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWWV[bcbbcbcdfj–“•Œ’””›™––œ œ –¡ §¦¤¦§ŸŸ¦ ª¯¦Ÿ¢¤·¨¡¡¢¨´¢¥¨¥°¥°­«´ž ••©¡¢”­±±Ÿ¢£ž˜›“‹¡”‘“˜˜’——˜—ž§œ§¡¢™£¥¥«¤¥°§¥£««­¦©®¯®«¨ª©³¥¦¬¯´±¯¼µ±¯® ’zvrda\Z]XNLRHRaMVPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8847863321./2556;:8;7876<;:;;A8x»»±µ½°»±¸¬ž¥§­·»¼Áź±¹µÄÉÉÀÃÆÆǶÆij¿Ū··½¶½ººµ²«¬¦˜—ž¢‹ˆr}ˆ~vncbfihfhjgjm`]\[ZZZZ\]\[\^_\ZY[YYY[WUXWUTVUSTRU``_`a_`acdi”“‰‘”“””•—¤™ —¡¦¢­¦¤¤££¢œª«¥™Ÿ¥±ª ¡¥«§¡ž­¬©©­¬¡¢¢•˜£›œ«©°›Ÿ¢Ÿž—™“‰ž‘’“–˜˜“œ¡£¤ ¢• ¢¤¦›£«¥¢¤ª¤«®¥®²©¦¥¦¦´¦©¨­³µ´¹º¯©¬ž‹rpo`[WVURGPOHZ[ORITKSLEFIC8;;=<8667:9;:976977:;:=<<6;<8>598:88659:;<97?<9678452121.-1426:8698598989;9@9{µ´­´»²°«²­¨§¯¹¹³ÀȺµÀ¯ÅÈ̺ÁÊÌȵɽ±¾Äɬ±¸Áµ»À»´³¨©¤”™š›ˆ~p‡ƒ{tiiilgjkmkjme]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURSOQY]\]^^___bdmŽ„‘‡‘™“•“œ›£œ›¡©©«¨¬§¨¦¤™¥®¤”™¥¯©Ÿ›™› ž®™œ«³ ¥¦Ÿ¢£¡•“›––’©ª­šœ ¡ š”Œ™ŽŒ‘Œ‘–•¡ £œ›£•› £¡—¢¨£¢¨« «¯£­·¥££¢¬­ª¨«¯³·³¾µ³«¯˜„tsh[XXSUQEXLQ[XMTNPLPQINIB<??A?<65799<<987:79:;<=>;7;;:=67:;8976989:6:=99577571140-+/434988::8::748=8?9~³­¨³¶®©§¯®›©¨«·¶¬»Ê»¶¿¬ËÆŸÁÎÏȳĻ·»Ãȱ­¸¿·¼½º²³£§ž”–—•†xs€vwnmhmnmpggigd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUSSNPQYZZZ]]\^_`d~‹ŒŠ’—‘—™¢ › «ª¦®¬¨¯¤©šŸ¬ •–¤¨§—šž®–˜¨ª™Ÿ”¥ ž’’‘“•§«¥š™™žž•Œ‹“†‰ƒ‹’•‘ ž¡£—•Ÿ•š¡¢ž”›¥¥§¨¨ ±°¦±¼§Ÿ£¬´«®§°µ°¹µÀ±­±«}rsbVSVNRIFVPRQLLWMJLNRGMJACFDC>@65889;9:7::7<=:;@>:9;9:?759:9876958779;85576661320-*.102877;99;8948;8@8³¬¦±·ª¦¢°«ª§©²±¥¶Æ´¹º³ÊŹºÁËÐ˱¶¸¼¾Áñ°²·­´³º²±¡¡š›—–’‚~vkglnqnqjpkdege^ZYZYZZZZZZZ\\]\ZXXXYYWXWUUTRSUSVURNNNRWXYYYX\\]aj€zv‰‡Š—‰””˜›™ž©› ª¦¥«¨š¡¥›“Ÿ£›——…„’›£”£–––ˆ¢››“‹ŽŠš¤§œ••—›‘‘‡”Ž‹‹€Š’’’ šŸ¢•”˜™•¢¦™™¤¦¨¦¡Ÿ´²¨²·¡œ¢·¬ª­¤²²¦µ¼µ¬«±£‰xsm]NQQLOCMNNPKFNNJJNMQIMJAGLHGC=858889:;69:68;99><8:>9;?8789:886857688974577820301*)-/12876:999984988A7w¶§¤¶±¥§£©¥ ¨¥¥³ª¢²Ãµµ²³ÆÆ·ºÃÊÌƳ¬º½´·À¯­©°ž¦­¹®«˜™œ”’…zm__frpvqinieghj_XXXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQMMKLSWWVXXYX[]aosvq…ˆ‚ˆ€‘„‹”‘”ž¡›œ£¡£˜¥—¢œ•‡˜šŒsƒ~—–†‘™”ŽŽ{™œŒ‚‰Š˜Ÿ£ž“˜–…‚”~~tŠŽz‡“š™š‘•Ž¢£Ž‰š ¡¤¤›¢´¯¬¯¬Ÿ˜¥¸¦¦±¡±®œ°¼ª©¯ª™‚wscVMROPMCSNLQMBPQHINRMHJJCJLFKK<749888;;69;7:<9::;79?9>@79:<89764445874312585/0102)(,-12764789::65:87A7x·¡£´©¦¥¨£¦¥¦¦¦³§¦´Á¸°´°ÉÄ·¹ÁΞ³¬ºÁ«­Ã­¨¢¦’¦µ«¡œŽ”•‘Ž|v}eWV_gfighncjhgb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTRMMJHNSSSTUUWY[]ilrm…|tNXrƒ—†Ž—‹”Ÿ˜•”–•–‰€“‰_;Wo|‹”‰€Œ‘Œ††sŠ…–yz…””ƒ•Ž‘ƒ†}“xqp…}‰‘—š˜“Š‰œˆŸ˜ˆ‡–žš¡ —§¯©­¨¨Ÿ–­³¢¦®™¬«˜¨´¢©­£“}rn`[NSRVLDTJPMLFNOIELQMKOJIMOFII<7599999:7:;:>>8:==7:?8>?589;79675333760.-/344110//((++-3854779<:79;86A9y· £­¡¦¦ª §©¨£ª°¨§´Á¹±µ°Ç·³½Ï¿¹¯®µÂ§ªÅ©£˜ƒ”›® ˜•…“ŽŠ†{rt\QLRUYZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MORMKHFHNQQMPRTVXZ`mpi{‚tPB@•‘‘}‰”„Š›–•‰’ˆ†•†yˆ`JQnxŠ‘„}„Š…n~”wuuw„™pQˆŠ†{~x”vhw†ˆ}Š‰•‹‘’–‹„Šˆ•„šŒ‚„’›–ž”¤£¨©¥¤ž›°ª¡¤¤‘¦ª–¢ªœ¢¦¨‰tmg^[HQQRMIUMSILKOIHFJNLMTKQPOFIC<768:8:;;8:;8>?99>=8;<6;;478;7775344696/3/.125221/,')+*,4833979:99::::?9w¶›£§Ÿ¢¯¡§¨¥§¨¯¬ªµ¼¶¸·³Á»¶§¹È¸¶¨¨µ¶ª²¼¦ž•Ž‰“§•”‰}ƒ|vomXMKMNOLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDDINOhYNQSTUZnƒtw~ji]U‰”‰t‡|…Œ“’™‹{†€vxsnuptŽz~Š«…yzhv{Žprmx‹’xz€{vrr’wgu„„„„{•‰ˆŠŒ‹€„‹Œ€”ƒ|˜•œ•‘Ÿ©žŸ  ©¥Ÿ˜§¤“¡Ÿ–žž¤€rha\]JVORGJXROJLMRJJJLPILQLRTLEHA<77;99>=:;<98@?::>=7==79937785675251472/2.,//200/-+(().1272198798775:<;7v®™£¢˜œŸ´©¯©¥¬«°±ª½´²»¸¶º´±Ÿ·º²ª¬©¨²¯¡š‘”€›~v…w{uonhXKHHHGEHHPTTTWWSTUUUVWWWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQQSV^uƒ|xfw—˜}hyvx€‰}„˜’q‡|w{ok~­}s‹{†’}tfv|†lohs|‰Œˆ€lyq}pmuqiq€~ŽpC‹„‚ƒ…wwz‹…}Œ{u~Ž’˜Š’š›£–™šž¢–‹¥›ž—Ž–˜womebZXWTQJSUTOPNPVKNKNOJQNHNOKEC<;79;::?=9<:99??;8<=7<9999266856633511224.,,-..-0-+*''*.1362/876966527995y¦— ž– ¦¯¬®«¨©±¯±«¼¸¬»¾¹³¬§›°§¬›–œ¥©¤ —™Ž„’yˆŠ‰up{mtpiliWKFGEA@CDILLMQRPQSTTTUVWWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNPQTX^eprmˆ§ªÀ~uyc|xo|yˆz}‹†omŒ’ytxjj€‚q–‘‹~–€I“˜nhw~‚licly…’†ksl|nr{†imps‰„†z}~{vots…‚yxp|ŽŒŠ”ƒ–—˜š’•—™—ž—Œƒ‰Ÿ‘‹’†–ninonXUWTRQYORTTSXUMNHNKMNKCHNGE?;99;99:><9<;::=>:8:<9?868727565541432/024*+**-.+-*(*(',-1250,5567485HA895w™‘›™šŸ¥­°¢¬ª¨µ¯®¬´¿«¼Â¿¦¢™•¤—„‹”¡¡˜˜‘“‹sŽz…‹…tntkpldkjXNEFC@<>>AFFGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_IMOORWZQY\`§ˆbšitzepmz‹‰vˆ†tlš’ts|jkMy…’‰„Žg1v†sl~~ƒtfet~„„…€filukq€|gqq{n“{s}|qpnum‚xyujy‰‚ˆŠ„–“’‹‘””—Ž€yˆ—ˆ†Š†€ˆvjjoheXQZWYY[MPUVYXNIHEJJHGBAFDCG=998;9:9<:9;:::@<9:<98>787715234533645031.**+),,++)(+'),,226,,5775478iO8;5n’ˆš‘™–¤¨®ž²Ÿ§»¯«²°Â±»Ãǚ–”™‹…y„˜”Œ†q‡‚s‡Œ…zorpnodpf_TFIC?<;9:?@ADDEGILOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOOQVLAIQIb¯³ r|xl}mrƒ…z„††yr¡•txsu”‡5q¨Ž¡¡„¢…vp†|‡|sŒ­‰€gfbjnrmpƒuioXupŽš’wl{}mqmp€zsvncv„~†€…‘Š‹‰‘‹‘Œ‹ƒux‹€~ƒ€~zqpok`[\^[YX`_RN[ZXWLHJFJG?CABG>CD=;97=;:;;9:99;:?<88=:8;66651121253474531./,,+)*))+**)(*)+/3DM2166643<vR7=7b’“ˆ–‘ž¤§ž¯•¥µª®±®Á²»ÁƖŒ”€ˆ}n’‰ƒŠ‡…u‚ƒl•ˆ‡{txxlwnwci^IPG>@7449;;<=>@BEHLLLLNPQRUUVWXYXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL7CMRSDJ†v€||v~mwˆˆ|~…ƒŒ~v¢™y~†…™„›œa†ªŸ‹ƒŽzwˆ~‰ˆsŠ—„z]dqtz{wŠlgjbyo…‚znwt„zptzwkni^w‡}‡|ˆ‡€‹’—ƒ…‡}q„„}uw{|‰vpsteg_[[]S[f^WQUX[UGJJDLG?F@DC>AA=:97<;;=<::99;;=>79>9985653244004645554-,)+('''&(())((+++/00Uq=23331E~W4=9\ŒxŠ€”Œ’Ÿ¦‘ « ±¨¯À±ºÅº–Ž‘”‡z…vkŒ‘‚}Š„ŽŒxƒ€s¡„‹}}~p€~zgvkRWL@E211367688:<>AEGFGJKMOPQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMORLKT]YRJi„ˆ{‰y|q|Œz}‰‡~—‡v¡™ˆ‡’”¥¬©H†®¯¯‹€“Š‚‹„‘¨‡€˜˜Šœsm|†‡}Žhghx~n…‡‚…q„…Gk€wryvhmk_w}ƒ‰ˆ…Œz•ž›‰‹ˆ‘zu‹v|xmow~ssrl[]][ccXfe\UPPVYPDLKFNICFCCA@CA=988:::;;:888::?>6;>7585773344236656768;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|~Š…ˆ‘–˜’—¡¬¡¦¸¯³¼³—’‹˜‹}tp‰’~}Œ‚’”}†~†¤‡ˆ‚ˆ…x‡ˆ~s„x_cWKB60./23133668:=?@BEGHJLNQTTUTTVUSQOGC?80,#‡[>?84.]–ps£UFIKMNPW`YpZ\^j“‡•„‚…‘“~…ˆ‘š•‚ ¡—•›š¥­“š»±§»Ç芌¡¥”‰‘{qƒžŸ‘œv……Šˆihoƒ€u‡„‹q†‚w‡€{v…}nvug€”†‰ˆˆˆ‡¡«¡–‰Ž˜z‚‰zzogkx~z~rjd^ZZ]j\af_YOKNWRQHPJDNGCJDB@DDA<:87=<:<:88778:==8<=68656623445576867<BB?<8:>CQ^e\G2'&,,--.1(?‹[.310Oƒ_4?;nupfxƒ{€Œ€‘‹š›¤¡¬¦«¯°—‘‘„¡”„xwŒ”|’†’•Š€’›Žƒ€Œ‹‚‰ƒ‰mpj]BA4--//./02234779;=?BEHJNQRSRSTTRPOHDB<87/9D><<63.l“—MPHJLKKNV`cggmu›š““‹Žšˆ“‹  ’£ª¥£¬“¨¶¢¨Áîǯxº”š|¡ž™„“…‚Ž¡Ÿ”™’„Š…˜‘–lpu‰‹‚–Œv„ql…Š–’ƒ…ˆr‰¡–‡“‰–¥µ©›•¢ƒ‡“„}kjk|€sa]c^Zfk\kk^WKGOSQNMLFIPCDMFACEGB>997=<:;:987767;:6=:785456345566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYp‚pu‡qv’†~˜–š•ŸŸœ§ ª–“˜žge¤š~„’‘y€’ˆ’}Š…™’‘‚€€‹‰…†„ˆ…xx~gMR>/..,/.-/000212557;?CENPRTPQQSQNPIED>;<:CF?><752<?R5HHHLLMNR^oŠ|s} ›¨¦¢™¡—¢•Ÿ¨ž©«Ÿ¨¬©ªµ—«¿«¶ÈÈ·ÉÑϾ› pi«©Ÿ„”’†œ¡šš™§‘‘ˆ•¢ššxz~”˜’¡’——”ž{v•’«³‰— }”žœŽ“–™¤¢¦¶°‘™¨ˆ–Žˆlsr||qh`\`^bgc`gg\QEJKPOIJLFFMCHLFFCBGDA:85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Ppu`n}awŽ}|”ŽŽŠŸ’—ž–œª˜žªBD}‡‰‡˜x‚ŠŽ|Š†Ž‚€‰ŒŠ„’…ƒ†‰€†w_bP460-1/,.00./..0015>AAMQRSPRSURNSLEE@<>=GG@A@8662<9;FHGIJMOQYm†w•‹£§ª´½¸¥®¬¬§¨´«°·²²­»±³¾œ³Ä¬»É˸Ŀ¸¥£°²¬­«¤‹–˜…¦¦ ¢—¦™¢ª¨¤ˆ…”¤¡ ª¡¤©Žœ±‹•£§·»› £°“££ž‘¤¢«¯­³µ¢•¥ªˆ™‰’Š–zz~…~g`h\eb]dc_ff^[OCIHTOFHLFJGEFHAKFCFFA;87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLicWjpXz…v”…ˆ‚œƒ’’Úȝ–sV—ˆˆœ|†ŒŽŠŠzˆ‚‡‘Žƒ…€‹…†‡’†‚„‰†ˆ‡‡qna@E64<2/110-,+-1/-4?DAMUQRSUUWUN[PGGD<>>FHCD@8;<5C;=FKIGHROPW“ „®£³ª²ÁÇë³Æ¶¬³¿³¸¾¶¿´Á¶»»¤¸Æ©¶Éǵ¾¹´¨£´­±±œš’šŸ‰§¯«¤•vŸ¤—¡«±³˜–ª®¨®¶»²º¬¯µ¢±¬±µ¼·µ®µ §¨£¨›©°­²º¸¸§›¶©Œ¤Ž‘“ ‡x‚ƒuYadVeaac`ae_ZUJDELUQHIJDIGEA@@KDAMF<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AEWQJL[ZQcdWzuq‚”}…†“v…~€{¿»£¼‚´”“›„ˆ’‰‰y†€Œ“Œ‡…Ž‰Ž†€†‰…Š‡‘zxn]V@EM<6:46AB7650/6CHCQ\OQUWU\VO^UIKJA@?GKFED;>@7D7?BJJEGWTP^¥­£±´Ã¶¸ÁÌɶ¼Å½³³À·¸Âµ¿°¸t²´¦ºÅ¤°Æ¹±³±´¨¤µ¶ª± ¢–›¢’¥°®¥­¬§¤˜ ¬³º¢©²ºµ»¾Ì¿ÅŽ½³Â·º¸¿·º·¹¬­°¦±ª­¾°½»Â¬™º¨”®˜˜«‰~‚|jWbaXjejeW[cYVTIGGLQGCHIAHD>?BBK@@MC99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m7?FQLALRWTYUZwjp„Ž…nzryˆb¸¡™£‰•“–“““—’‡‡{†•Š€„€Šz|‹‡†|ŠƒŠƒ•}wyueO\dGEL:Qda[^SF?;HPDZcQQYXYgYT``MSOEA?IJHEFA@C=E6B>HGKLSZT]“¯¸µº¹ÉÀ»½ÉÌ»¼À¼·µ¼»·¾µº²Æ`u³¥±šž«½ª¥¨«ª£¢²µ¡«¨ž•–Ÿ˜ ®¥§§¥ž¤”¢§±´§²²¼¶Á½ÓÉÊÓÆÂÅÌÂÊÃÀ¾½¿»¼·´°¹··ÃºÆ½ÃÉ°ž¹ª¢¬¥¨·‰q_aa\Wa_hfRXaVRUIEFNKA>GD=KB=B@=F=;H@796379>489:57045/26389373526?8@>GKRTTRPPQRQJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKE@IMPRLQ]hllq…tmsrsˆÕÀµ™ •˜™‘Ž—’––Ž†‡}†ƒŒ–‹ƒ‚xz‹ƒ‡{‹yŠ‚—t}zkepuY]\Peeb`ed][XW\MdmURmm_n_XgeUYTJDAKJHFHHHHBI9D?HKTTV\Z[’¹À¹½·ÆÀ»¹Ê˺·¹¶¸¹³¸µ´®¶¶™du¨ž­p^¢¬œ˜¡£›¤ž«¥” Ÿ”Ž–˜—¨Ÿ¦ŸŸš™„¤¬¥ª°­·°½¹ÔÑÏ×ÏÉÌÒÌÏÎÊÇÀ¿ÂʽÁ½ÂÀÅÄÆÊ¿È䤻°µ°›¬¹½šyl]_[X]aYccQ[`SQKCAEFD<@E>BHB@C=:E>=J?47535;=468977022/24169775555D3ELM>510006:477@IOJ;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODR\Yi_p—’‘”olouuˆ³¬¡¡Ÿ‹™œ™Œ•‘›’…ŠŠ~ˆ‡Œ‹‰|„s{‰ƒ†|‰t‚Š†•s{xlmu{hreilifjih`fihmZmt—­¤¼ˆ‡g[oh]ZYTHJNPJKQLTQILAJGKP__bfia˜·Ç°¹³»¾¶²Äǵ¯¹°°»¬³±§ª·¬¶§ž›§šO›ŒŽ –‘¦˜¥•Š““‰‰‘‘ž›¡˜›•—‡žš¦›¬¯¨¯§³´ÔÔÕÖÒËÏÓÕÎÓÏÍÅÂÉпÊÉËÉÒÈÍÍÂÐÒ¸°Ä¼Äº¦¶»Ä£‚nc\\]X`WXfZQ]WNPCBHEBI;AD>AH??B7;D>@H=46655;:687654/10146278875367C5B8?-0,1349=97,.,1;FL=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYSeWs˜ƒhqoyyƒ ªž¦—››—‹Ž•‘šŽ}‰‹…ŽŠŠ‹ˆ|„‚p‡†{‡rƒ’‹}qxulqx~q{mxslipmcimpyiw}~Ë¿Âߧmcxnc[a`JPRUNY^P]]NQNTQUT\nnw‚r–®¸¬´§°¶«­½À±«µ¦¥¸§¬®¡¬´£Ž±®š˜˜Œ‘”‘„Ž›¦‘œ‰ƒ‹„Š‰„‹ƒ”•˜—”›‘œ˜™™žž«¬¤§¡¬¬ÎÒÕÑÍÌÒÓÔÐÔÑÎÈÃÔÑÈÍÒÓÓ×ÍÒÑÅÒÖÆÀÎÇÈ鿸Оyne]b\V_R][OPTPNH>AFABE<@B>EE>??:==<<JA45465<888664412/03526768533;=<E=@11+/349?5901022-2EO3)/3.32=N248C}_2A†tD:==I>@CFH<VRMO[u†…Šwmwp}~€¡žž¡‹™““ŒŒ“–„y…‹Šˆ‘‡‚{r~€‚‡z…u…“‘‰ovsls|{v|swqk€srioqzyr{¾Ëš~Œ²ƒvr„vhaj]CZZ[VfdXekTX]\`c]cx{‹™ª¤¤¡ ¡©¦ª±¸ª¥´£¢­¢£­¢§±Ÿ‰¦š”’‘Š’Žˆ‚“‰k•¢™„€…~‘ƒƒ“–­‹••™Ž…’—§°¡ ¡¤¤¨ÇÍÏÈÂËÐÓÑÔÒÎÓÍÆÖÒÌÔØÖÖØÕ×ÕÉÔÚÍÉ×ÖÑÊ­ÄÃ̊rob`_XSYR\PJGIIJ@;:;EAD<BD>HB?BB;;9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/-.;R017/532ED28>nb5=tM99@I<AD?A;PLFKYp€u}hsyr‚‰•”…‹–‰ŠˆŽ‡w„”™‹ˆˆ‹‰~ƒxs{}ƒ‡w€{‡‘—ƒnwpmuvx}s…|ym‡vto}v„uy{µŒ<A‹Æ¥~|ieVICecfchjdoy[_fhknin€ƒ‰‘‹ž —˜Ÿ££¦²¤¤³ ¢¥ž¡© ¢±œ†ž’’’‹Ž‹†ƒ„~œ›Œƒ„…z”~‚©•£Œ’Š˜’‹}—Šš‘«³˜š›§œ§½ÃƸ¶ÆÍÒÐÒÐÌÒËÉÔÎÐÕÚ××ØÔÙØÍØÛÎÉÚÚÒÖ¿ÌÌ´wvnd]YRUPYVFGJJEE=:79@AB:HD@ECADA;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?1*(.BT29254/7K75<`bA<svV87AH:?C><9QECJTlnopaqqs†|—‘‹~‡’ƒ‰†…Š‚‡|x…–—ˆƒ‡†‡z„yqz{„†uz…ŽzŒp|opzr|qƒ‡nŽztw}|‚u|‡ˆ°tX©Â¶Œ’‚pnb=^hrpqpnxw‚eioruxr{‹‡Ž”’›– –‡Œ“› ›ŸªŸ ­œ¢š™Ÿ¥žŸ¬™‹šŒ‘’…}ˆ‡ƒ„‹Ž ™“ˆ„‡~m™y„˜†ˆ“Œ•Œ†{›ˆ“®ª”•—ž˜¦®¶½¨­½ÆËÈÉËËÐÉÃÑÊÔÖØ×Ø×ÕÛ×ÓÙÛÖÏÛÚÑÖÈÕ˕y{hh[YPSS]HCEII>A>=7:=?;>H=@AAADA>>:86DB755479.566435542323647553457EBDCEB56<FNSM[nfcnskaV>,4LG865433BF4=W_hLux^8;?F<<B<99D?CGRk_mdbfkv€ˆq‘›€y€Ž~ƒ‚‚…„||„—Ž‡‹~†‡€w‚yn{{†tz’ž¡vu‚tu}t€„o‚o’„t|…zv†{‰·Æ¤Âɸ–›wpeNfczw†¢‹yyw{ƒ|„vm”–”•—ƒ‰–š——¦œ˜ —Ÿ“’—£š«–‘‘‹’ƒŒ…‰ˆ…‘žœ™‰…Œ†—{ˆˆŸ—‰Š‹‚|¡‰‹¼¡—“—™œ¨¦¥®ž§µ¾ÀÀ¹ÇÉÍÎÅÍÊÑÖÕÔÙÕ×ÛÔÖÙÚÛ×ÛÚÙØÎÛƆzyfhd_TWVUMKDMC;==<9:<>9>A6>?@=?><9867CA6455=80665547745613854564567HH=DJE7925;H>;::7IP]ZRUXK9T>;95327I8=NYMHxxd5=>C==@:6:>>@EQ_Yea][htzyl‰’wvzŠ|~€€}…z~‚‘‰„…z…ˆ{u}tn|}†~t’ž‘Ÿƒ’|†~xŽ}xŠŠn‚š€t˜…~‰…|~z©Ã ¼Œœ¤œ}‰„}‰sŒŠ~s¦šœ™”…{‰„hGq¡¤Œ‹’…ˆ‹‘’•š“•‘—Œ•Ÿ”¡”’ŽŽ‹~Ž‹„ˆ’–šŸŸ‰Œ”’ž‘‚‹¦™ˆ…Ž‚†„€¥†ŠŒ¸˜‘”–¡§ ž£®¶ºµ«¿ÅÊÐÈÇÌÏÓÒÒØÒÕ×À×ØÙÛØÚÚÙÙ×Ü·xxwjidV`[SONHDLB==>99::99<=6@>><=9:;;37D@8378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWN<MTHN?96333>C;[X>5YypZ<<A<=>8589?=DRSRX^UXfmmmiŠqrxŠ{{}|ˆz|{‹‡‚~uƒ†yszsm~„}w†›¡›ž”’€‹ˆ˜‡€œ’n‡¨…z ‹|Žƒˆ„œ~š‘Š£¢ ¤¯ ‹‘‹…‹’†Wr­‹Ÿ¬œƒ˜›Ž\ƒ¢‘‚ŒŸ“•Œ†ˆŒ’“Œ”•”ŒŠˆ–›•–‘‹’”†€‹‰’‰Š–™££†“–¡‹ŠˆŽœƒˆ€ƒ‡…¤†Œ³˜œ’”—¡¡ž™’›§±¸¬¥¼ÁÇÍÇÆÏÌÏÌÏ×ÏÑÔ®ÖÕØÚÙÚÚ×ÖÙڟo|tgf\]XSVWC@ID>?>:49:;7:;:3;<?=>7;9:1:G=:27=@50677255?65;55858:57735HR7GOK994=EJB>1FCLA98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:<@;BQKKSYPTcbxlb~’ƒnmw‹xy~z}†|{v†„€sp…‚{vvut„ƒ…}~’¦£ž¦¢–‰”–‹Š¨—rŠ²Œ„§‘„™“„™Œ¢– ™“‰š¢’©¯Ÿ‘•Žˆ•‹n·„šÄȲ¢¥›œ˜–‘²c¤ÍȕŽ†‡‰’Ž“”Š…ŠŠ†–š›”“‡•˜„€‹™ˆª——¤£ˆ™ž–›‰‡——‹…Œ†¥‰“¨™–“–˜¡˜Ÿ™“›¢²´¥£¼Á¾ÇÅÅÉÈÉÂÊÓÌÍÔ¨ÒÑÖÖÖØÚÔÓÚ΂rhb^]]NITYABGD;A=837;<:8=649:<:82?9929I:>67BC32:96264>=4;>6949;57944KQ<JQK9A7BGI@64JELF><88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBcFvŽ}|m~ˆxz~z‚‚ƒ~vv€‚|ln‹z|xx|„‡Š~Š£³§£ª³¡–§Ÿ¥£–•®¢ƒ¸•’³™Œ¡¡Œ¤›¯£¤˜§–§™¬¯¤—•–•‹˜™– ÀŽ£É¹«›£¦­˜‘›²……¨¢œ˜…‰‰Ž•‹“ˆ†‡‰“˜•Œ‹”“‡”˜†„‘œt‘™³–—¥¡ˆœš“Š‘Š—›‰Š–Ž†}Œ˜ž‰œš™“˜—Ÿ” •ž› ±®¢¤·¾´ÅÇĽÃÿÆÍÊÉÒ¦ÎÍÓÒÐÖØÓÐØ»ryv]`U_VOHJNDBCE5>:77:?;<7=42669774=5;5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:IENED:6A@BS>9DO323565=v\<R\tiZM]S<=88567=:JFDGN[\YJf`;H„‹z{n…†z|„x…~px|~}orz}|x†‹‰†„’§»¬¨²½¯¤­³³¨£¢°¬Šš´£¸¤•­¤—©­·¦¤£Ÿ™©—©£¯°©š™œ”•‘— ˜š»»®Ê¡j¶¸«°”˜Ÿ£«“—¾£^ª²‚‰Š”‡‘|ŽŽ}ƒ†Ž”•ˆ‡“—Œ•‹Œ—˜’™´—–«‹œ”’’Œ™›Š‘ž‹‰•Ÿ¡”˜š“›˜ž”¡ ”œœ¥¯¨¡¤³¸«ÂÈĵº½»ÅÇÇÂÑ ÆÉÍÍÄ×ÖÑËÔ¡pzh\ZS^QOEC><CAB8?875>F<<5<35345454B39:BM:B;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAE@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPdGb`bpJ@‹Šs†‡}‚ˆuƒŠ‚m}}|pw‡w‡{Œ†Œ™ªÂÀ¯½Æ»³´Á¼´­«³¶‹§²­®¼ª›»¤¨­¹¸«¦¦¢¡££¨¯²±ªœœ¤˜š——ž¢¥¥’¤º®©À¼­­²¹¥¤§}ˆ‡œ¬½°ƒŒŒ‹ƒƒ‘zˆŽœˆ‡—‹•—”š–§š±š‘¬œŽš’Ž•‘–—Ž‘ ‘‰”›£¬”–”œ’Ÿ›˜ ¡”šž§¦¤¢¤°²¦ÁÆï°º¶ÅľͦÇÃÇüÕÑÍÄʈtsb\Y_[MJBL@EG>A?B;:4>A<=5=6>333241A17@BN>G@CNCA=C=;86CB5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GE?CF\eG`igZ]\“ŒŒˆ{‡‹†ƒŒu†‘Šo~{q~z•z’””˜“•§³ÆÉ¿ÂÌÁùǼº¯«¹º—²¶º²À®¥À¤«¯»¼ª­«¢¢§ª®´°ª›Ÿª›¡›•Ÿ°´§‹£ºº¶Á¼¬¨œ²¥¤¨”…ŽªÃĤ‚‹‡ˆ„†•”zƒ‘‘¡ŒŒ”’Žˆ—Ÿ—“™•˜¦ ¯Œªœ•’‘”•Ž•‘¡”†—Ÿ ²ž”š”  ˜¤Ÿš › ”˜ž¦¤¦¦¤¯­¥ÀÄ®¨·µÉþ¶Î²Ä¾Ä¼³ÑÊȵuym\X\iSLHDLKKJAA=CD<5AD;:3=8B332263A05IEM>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBfZNe\fTcj™—ŠŒˆ’†‰y†”r€|x‡‚‚y¡–¨šš˜º½ÇÈÉÁÒÉÊÂͼÁ³­»¾§º¿½¼Ä·¬Á©¬³»¾ª°©£¥£¬­³­¶µ Ÿ®ž¥¢˜£´¼©›¨½Á£··°«’°­«¬—†šª¦¥‘‚Œ“¥•‰vŠ’z…’žŸ“”‹”£™—œ•”£ŸªŸ‘¥šŒ•–ˆ|•’’£š• ¢œµ¦ž—¥£¢¥ž¦˜ž•—›¥£¨§¢²¬¨¼Àį¥³·ÌÀ¹®Ä³»¾Á¸¬ÂÃÂÀ™myaXW\[KKMJFDDIBBADL:4DH9;4<7E.12352B26SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQG7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>jH_XaZddVžŽ—Žž’‰Š‰ “„x…•ˆŠ–¡™®¦£˜Â¾ÇÃÇÅÓÍÎÍ˼·°¹¼³¼Ë¼ÃÁµ¶»­³¿¹¼®¯¨ ¨§¶­­©±·šž­¢§¡«··©¥°¿Ä±¾¹³§ªµ³­®––¥¬¨ ‘Ž’±Å§•Ž}‘•}ˆ‘™ª™˜“““•“¥ž“™“¡£¢œ˜Ÿ™‹ŒžˆZ–—’–¥™e˜£ž²¥–¢–¬¬ª§›ž¦—˜—˜•¡¤¨¦Ÿ¶«©º¼Ãµ¦³µËÁ¸©¶¬²º¸®¨·º½¸‚lnZWTUNFJSNK?AGDDHGG95FM;>7=@J.32025B55PVN<LFKRLOHGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|gV;=@BFBqFiIRebLF¥”œ–¡—©–‘ƒ‡¦“ˆ‚‡‚œ„ƒ•”Žš¢Ÿ¯¾®¡Æ¼ÅÄÆÆÎÎÎÒʾ»¶±º»»¾Ï¶Ä½·¸·²±µ³¸³«¦œ««¸ª¨§¯°—£¯¤§¤¤µÀ°ª¬´¿ÃºÀº³§¹µ¸²®•¥­¯¯¥‹“•¡tÁš~—™…–šŒ±•šš•““™™¥£•Ÿ›–š©œ¡ š‹–`J–œš•š¥–T–°Ÿ¯œŸ¥”¯®¬¥š ¥”“™™ŽœŸ§¢™´©ª³¼¼¼ª°²ÇÀ¸¥««­±±£¡±²´¤pnf\ZNPKDPPPQ;GJIGHCC>:KU?A:=EM07544:B34NWO<JKNUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@BAF3>58JKCA=C;4EA:A?>H@5*B52,>c]g:35tde@R7&#3}hW;:BC@=QEWSsbWFHª—™ ¢¨¯™‘—‡‹§–Ž‰“…Ÿ‡„—ž š£¤µÈ´©ÆºÂÃÇÉÈÈÌÍƾ»³®¹¸ÀÁͶȺÁ¸µº°¯¯³´¦£›ª³´ª¨¦­¬™¤®¥¤§¬º¿¨«µ·¿Á¿¾¹³²Ä±¹½¬£®µ¬º¦ˆœ˜¦›v¿ …™Ž“™š‹¯—¡œœ—•›Ÿ¡©ž¨ ššªš¢§ž˜‘ƒnv’¢š•¢ž®²¢«•¨ª—ª®¥¤Ÿ¥¨’’™œˆ”œ¢ž–±¦©«º¶¾³²®¾¹¶ £§¨¥§œ›¬©©Œbea_RKMGHNIUL=LDNJKBCD<QU=AABDO18=77?B75UXN?HNQYSPQUKQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW;:=..R`MUHe^HE«”œ¡Ÿ»¯™”Ÿ‹“ª›‘’“‰«‡¢ŸŒ¤­”££¶Æ½´ÁºÂÂÇÈÅÂÍÈÁ½¹²¯¹´ÀÂʵűÁ¼´ºª¨­­°¢¢™ª´»¦©¦«ª¨¯§£ªª¾»§­¼´·½Ç¼·µ¸Á±½À³©µ·«¿¥£˜‘¢ ¼Ÿ‰š ™—žž·Ÿ©œ¥£›œ¡š¨¥³¡›¦œ¨ªž™–”›‹—‰Œ¥¢”¢ž ´¯¥¥“°«™««ž¤£¨‘•• ƒžžœ•©¤¢¡´´ºµ­¨µ²³žœ¢¥š—•˜ª¡žw`\_]JHFGMQIMEFFBRLJBEG@VRDH=AGQ1;B7:BF79\YKALPTUSMWRNUJD@JJNO9C?5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-1:g\FCCœpbGE§—¤ŸžÃ­›—¤—™©œ–ššª–•§¦•­­™¡«¶Ä»¾·ÁÂÀÇľÍÆ»½¹²¯¸³¿Âȵ¿¯»¶¸¶¦¤ª¬­  šªªÄ¢¥¨«¦ž«¯¬¢©¨¿·¦­½°·¶Ç¶µ¸¸¿±¿Á¶´³´¯¾£—£–”œ”® ‘¢¢¥££Ÿ¾¥©¨« ›¦Ÿ½¢˜£Ÿ¢©«¡—•ž“ž‡…“ž¤¡µ¬¥œ•²§™¯§Ÿš©ž ™•Ÿ„ š›“¥¤š˜«±µ±ª¥ª­¬œ˜  ’Ž–¨ž”hbYa]OIGJNLHEDIA=PIA<GIH[ROK=HOU4BF9>HG5Ca[KCNRUWVQXTRUH@8QQPM:G@4CHQSIC<C>GVKC@O>K<06;GF>;FA56?9:?9;15D0-,/Mv\4KZ5,MnW<-=)#zbQ5CKQ:nRF<KxebWL¢š£œžÅ¬¡Ÿ¬® “£Ÿ–¥ ¦©«—¶±£ª²µÄĽ¿¶¿Â»È¾Êȶ¸µµ°³³·Áƶ¾°¸´¸µŸ¦¬ª¬ž¥£Á¥ ª­Ÿ¤©­¯¢¦§½µ¥±¼¸¶¶Ã²³·¹¾²ÃÀ·¸®³µµ£¥•’”¡® ™¢©¨«£šÃ­©ž¬­››ž™¦¡½¢¥˜««¬¦¡™™Ÿ’Ÿ‰W–Ÿ¦¡ ¸ª§“˜¶£Ÿ²¡ ›®–žŽ™”‚ŽŸ—•Ž¢¤•¦®²«©¡¢¥¥••˜‹‘“¤ž‰adYc`LHJJNFEAFK>=JB99JKN]QQI=LV\9FI=DMI8Hb\LCLPSYYVWOZ^IA=WQIK?H@5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+w`S6SZkWrHE6=ue\KNžŸ¡˜žÃ¨¥¢³¡œ²¨“«¤ ¤Ÿ­©¬»°¨¬µ±ÈÅÁ³ÂüÆüÄʼ¯°¶­°´¯¿Ä´¹±°¹´¬™¨°©©š¥¡§Â­›¬±›ª¢®°©¤§½¶¦·»½¯·Ã¬³³Â¿²Æ³º·¬´¶­ª¢¦––•¤¬¢ŸŸš¨«°¯¯¼²¦ ©¨™™˜“¢¤¸ ¡¤“¯¯¬¥§Ÿ’¡ž•ž•š£Ÿ§³¦¦˜´œ£®šž›®ž“—”š€‘¡–ŽŸ¡“‹¦¬°¥¦¡œ ž’’š“…‹’œžae[geJILJRBC@IG;;G?99OMU^RSJ>O^]=HPBLLI9Mc\LELRTY[SUO\bHA?ZQAHAKB7FELKN>;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<v]^?[T^eq@8;H–weA4Ÿ£Ÿ› Ã¨¤ª²¡£´ª•³¬§¢¤²¬®©»²¬°µ´ÆÀÄõÀĽÉĵÀÈÁ´«µ¨¯¸¬¿Ä´·®¬¶¹¥™«±«ª˜Ÿ¦—­»´›¨°›­Ÿ®´±§ª¹²§º³·²¹Àª·²Â¼´Å§¾¯­·µª¨¬¡——’¦¥¢£˜˜¥¯¸®²µ¶ Ÿ©¤™••“¤ ·£¤¦–®²²§«¦¡ž›š›–˜¨Ÿ ˜¢ž¯²¢¦—®™¥«—™ž¤‘›“—š…•ž”Œœž”‹©©ª¡§ ˜ž•ŒŽ™…•‰”Ÿxch]kjMPMNT=CANC::I@77RO]^RVQAW`\BJSHVKH:Td\NFON[W[RPQX]GAB[PBG>NC9HGHOP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1[bZ33806p[bH05IphVCWFŒyfC;¤£œ¡¦¿¦¨¯°¡©µ«¹°«£ª´¶±°¹·¯¶¸¸Å¾Ãǽ¼ÄÁÆÀ¸ÀÆÀº©¶¤¬»¬À··©¬±º¢•­°­²–¥§ª¹© §°ª °´²ª©¶¶­»¬³³º·¬¹°Âº½¾¦Ã«°·¯©««§ž˜™«¢¢ ‘˜¡±¯³«±º›œ© ™–’—¦¡·©¥£¢°±´«²¨«Ÿ›  ›ž¥¢—£³°šŸ“¥š ¨š”¢ž•˜‰”˜“––œ“ˆ›™”Ž©¨¦Ÿ¢›—›“‡Ž™‹}Œ–…›jhlalnWPQZTACET@;;IA7:XPd^PVWDY^]MLRN^KJ>Zc^NHPN[UYPKTWZI?DXPDF?N@=IGGQPB=DFBM?:1D?77547?=95E4+75/251.-.,1=*'+=\p=>1.1e[d@1647gY`F(?8l}h[V;‰{cC=§Ÿœ¡©½¡ª¯«£±¸©¥µ³¬ ­µ½®³¸¼º½¶¶ÀÿÈĹÄÁÀÀ¸Ä½À·¯µ§«·±»¾¿´©®±¶ž—«­¨­–§¨Ž§»Ÿ¤­³ž«¢±°³¬©¶´µ½­¯±µ¬°µ±ÀºÅ·«¼¯±¸¬­ª£±¦Ÿ¥ª ¤—™ ³ª³ª«³š§›š•Ž ¦¤´®§¢­­®±§³­²ª¤œŸ¨¤ž•¡™›¨µ©—™’’Ÿ™ž ž«ž—˜…•—‹™›“Š–—š—¦¤¢ –•—“€”…{Ž’ƒŒ–elrgpq_FYfVDCMXDZ9HB6>]Qh\NY]G[^]NMRXdJJC\b_PLMNXWXPJVVWL=EUJEDAM@AFHHQPA;GDFK=87B=68719><65D0+80/05/*,/-*=,,%2+*5K1/'__aU150=`V^8)C3YT\gK6ŒzfL@¤š¡¤¬¶¤­©¥¯®¶ª¯µº§¦°·Å·±·¿ÀÁµ´ºÅ¾ÌŹ¿º¿¹Ã·À¸±´«©º¶º¹¾´ª­±µ˜˜§¬ª«›¬«Ž«½ž«®±£« ±­³®®¶²¹·ª­®±¨µ¯³»½Ê²ª¶µ±´¯®§¡³ ›¨­ ¥•–›š²£­ ¦¯—¡¤šš’¢¥§²©¢§²¬ª¶¥®±µ¯¤™­§š˜Ÿ™™¬¸£—“˜œ¡˜—”«Ÿœ““˜œš•‰”“žš¤¡¡ ˜–‘“•z‹…{ŒŠƒ‹’knxmu{`EajYIHYZ={JFD6AbTi[M\`J[]ZRRRb`LKE_``QLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`U`/5(C_Q\.*B/JGP[H3cYTKD™— ±¨±ª­¦¤¯®µ©·´¹¤«´·Éº´º»¿¾´´·ÃÀÌȻü¶½¿¿·¾»°¼­§º¸·¶Â¶«­±·”—¦®«§£±ª”¯»¤¬²²§¨£²³°±±µ±¸³©®«±§¸¯µ´ÃŶ©µ¶¬°­©§£¶Ÿ §± ¤”œš•±ž§œ ªŽ©£ž›–˜¥¥¥·§¢²´¬§²§­°µ¬¥™ ¬¨›œ›”ª¸œ”ŽŽ‹™œ¢—˜¥¡ž•ƒ‘•œ˜–”‡——š¦›£ ’–•v„‡{…„‹mqwu{~\Kel\KNc\>b{GI8GgWf[L^bMXYWTXTi]OOHa]_PJHQVURKIWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANHf27'GbLV%-B.=ELQ<3rkJCC‘™¥®¥­®«§¥±²³ª·±· «µ¹È¸®Á¼Ã·³±µÂÂÎÅ¿Á½´½¿¿º¾»±Ã§©¸°¶¶¿¼¯«³²œŸ§±­¦¥°¥ž²µ¬«²°¬©¨´¹¬´²µ¬´­ª¬¨«©¸­±°Ç¿¸¥¹°©­­¥¨­°¦¤¤¯¤©œžœ›¯™££¢£‘¬ž¤ Ÿ¢ª¥¦¹¥¬µµ¥ª«¨¬¯¶®££©ª› šš’¤´š‰Ž‡‘¢ •” ”’…Ž’’›˜•“†—“•™¦šžŸŒ’‘Žw~…||}‡Š‰qtr~}}\Sdo^NYf\FD–[G;NmXb[M`bNVWVWTYg^QRLcZ[TKGOTSNGIWS\N;P^IBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3Bc;6*HeHJ+:I?3BIS,>k<GHœª«¢©±¤©¥³´±´µ²²¡«­½Ëº®À»Ç±´­´ÂÂÑÅžÀ²½À¼¿·¼Ä§¬·¬³¸¼À°«±­ £§­ª¨¤°£ª±ª¯¬°®¯®¬³»§¶°²©²©«¥¥£­º¬ª±Â¹µ¬º¨©¨­ª¨±¥ª¤£®ª¨¢Ÿœ£¬•¥ž˜ž™¬¡§©¢¬¥£­¬¸±² ©¢ «¯°¬žŸ§¨©™¤˜™ §˜†„Š‹ž ‹Œ•›Ž…‡• –˜•†–““—¤›œœ‹’‰~~‡…|w‡…†tsqˆuk_Y`ncQsq\K;„|F>WtX`ZNc[NUVUWP\b^SONhXWWKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*35>10485(5/*,.30;),,'%234$,2-860)(1<]J0.JgDF8<B05EKX1@”Z>LE•˜­¨¡ª³œªª°¶­¸µ®«¥ªª½È»±½·Â¯°¬³ÄÃÎÎþ¿´ÀÂúÀ³ÈĬ®·­²¸À¾³­®«¤§ª°©§¨±¥´®«°®­±°³­³»¤¸³¬¬®§« ¢ž°·ªª­º¶¥¶µ£ª§¬¬ª­¡©§¦²²¤¦¦¡¡¬–ª¡•š ¦ž¤¢«¤¬¢Ÿ§±·­­£¥¢›ª«®©¢¥¤¤˜ ™–˜“‚ƒ‰… ŒŠŽ‹˜ŠƒŒ—£›’›Œ“’‘”¢™›™ŠŽ‹Š|†€ƒzt€„‚~twŒ¤ˆxj^`ngWe‡cN?g“LEbyWbXReTMVUUTO\]aUKMiWUWIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*49?./463)4+*,+.#4.-+&(+79*&6+<-2,&06WZ.0JgAA<<C+:JO^4D†>HFD—’°¥£ª±˜«ª­µ«¶±«¥¬ª©¼ÀÀ¸¸³»µ¥²¯ÄÉËÑ¿Á»¹¿¿Á¹ÁºÁÄ®±µ±³ºÀ¾³±®­««¨¶ª¦®¯«¹°¨±±¯²¬¶ª¶µ§´¶¬¬¤©«œ£ž´²¨¨¤´´ ¶­ ©¨«©«§ «¬©¹¶©ªªª¢© ¬œ’©¡ ¤¢¦£©œ¦µ®¨¦©¢£˜¥¦§ªœ¢¤£Ÿ™˜Ÿ‘Ž™Ž‡‡…žž‡„ŠŠŒŒ„†”¢šŽŒš‘’‘’Ÿ–˜–‹Šƒt†xuƒ{xˆoqggqx\`sˆjO^™VHmxUdVQbPMUTUQOX[bUHPiTVSGPYUI>IHOQPxLMV=<KD?@A<@CUC9AK=5;E13;97*4:=+-341*8**+*,))(/*&)%3;,$2)2021%/2Qb02?f=NX>C,>LT_/Jj6OD;•Ž° ¥«®š¬¥­®³´¯«¥¯©¨º¾¼À°®¸­¡¶¯ÉÇÈÑÀ¾½º¼Â½ºÃÁ¿¿®²²±µ¼¼Â±±³«³¨¤µ©¥­³³¹°£®¶±¯²º«¹®ª®¶¬ªž©¬Ÿ¢ ¶­¨¡Ÿ¯³¡´ªž¨§ª£«¡¢¬­¨½¯¬®­¡§¨Ÿ«™¯¡˜¢¡¨§Ÿ¨š™ª±©£Ÿ­¢¡“¢££§˜š©¥˜—™Š‡•ˆ}†…„¤—…‚‚‹†Ž„„“ –ˆ‘“‘œ”—‰……xt}uxy€{tszi†£ui^ekugˆŒ}SXp^JxsSdSQ^MMRYfNLVYeYFSiRQ?BNQaQ:IHLSIqQLS;<I?;<=;@@W<<?H73CB15:93-5::)-31--6)(+-,42#2)',%.;.&1.0-14%,0Lh:48_=ad?F1CP[[+HN9UA4±Ÿ¤¦¬¤§¤¬¦´²±ª¤°§ª¸¾Á»¯§¹ª¦®°ÉÇÈÑü¿¾¸¾¿¼É¼Á¸°°µ±º»¸À²³»­¸­¢´¦§¬²¶¹³§§»µ­¶½°¼¦­¬µ«­œ©¯£Ÿ¥¬«§œžª³¤³¨šª§©¤©ž£©§©¾«´¯®©¤ ®œ›²£•¤œ¤¥Ÿ¤šš¨«¥ž›ª¡›’›¡¥˜—©¨’˜š“Š‚…~‚€ˆž†}‹‡Ž„“›“…“¢Œ”’‹‘š‘•‡ˆ~qzy~|ix|zupp}h…x„ˆdahcr…zmgy]^VBWzmTaPRXKKNqu]HZ[gYEUfPD>JNDCA9HGKS?jaJQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11&/>KH0%90%,,09/,,+6'17#-/GjI14X=fcBJ7GS`U*=;DX?*”±™Ÿ ©¥¤¡«¤·²²¦©±§¬¸Á½µ°£¹¬¨¨±ÃÉÉÍÁ¶½¿µ·¿¹È¶Ãµ´³µ±½¸º¾¶­¹¶¿­¡³¦ª«°µ¸µ«ž¼¼¨²À³º ¯³µª¬Ÿ®°£œ¥¨©£žœ¥±¦¯ Ÿª©¨¢ªœ¤¨ ­¼¨®°®¡«£¤®žž­¦—Ÿ›¡£œŸ›š¢ª£šš¤¤•—”Ÿ¢–›—¦«‹ž‘‘Œ‚Š€€{š•‰|~‹†ŽŒŠ„’˜‘‡”£‰’’‡™“€ˆ|yk}vyxc{zqpqrxh€tjƒgdhansŽmbip`pA\xlU^OQQJJMTYWM]^mWDX`O^PHMDF;7HEKO<rhKK9AE;;==;;=J49B<3;G<4?18-78;2(09/,5..=-*K>*49&'.34.0+/4&,:$40BhY13S=e_DL6KWeO*<3OY=#’™¬™Ÿ˜§¤¢Ÿ§£¸¯®£¯°©«¸Âº³­Ÿ¸¯«¨´»ÈËÈ¿·Â¾¯´½·Ä·Ã±¯º²³Àµ»¾·©¹¸½«¤´§¨ª°®¹±ª›»½¤°Àµ´¡®·µ¦§§±³ ž¤¦§¡¥™ž­§¨ž ©®§ §˜¤¨ °¸Ÿ£±¯¡¬¡¬¤œ¦§©šš›Ÿ£•œš©¦—›Ÿ¨’˜“˜ž“™–¡©š‰Ž‡}‡‚Ž||¡ˆyƒŒ„‰ŒŒ…ˆ’šŽ‰•Ÿ‰‘•‚‹–Œ‘|„{so}qst`yxioqpoi~qczliec`f†`[rjrMM~hXZMPLJHPRPIN\_nTDX[RgOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23/:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%53=fd24M?e]FO=RZhH*>/YX5(—¥˜–­  ¡¤¡·«±¤³´ª¨¹Äµ²® ·¬®­°µÆÈÁ·¿Á¹°´¼·¿»¿¯«½°´¿±½Ã¹©»º·§¨µ¨§«°­³±§š½·¤­¼¶¯Ÿ±·°¨¥§°²› ¤ ¤¤¡—œ¯¦¡Ÿ¢§¯¢ ¢“¤¤£·°¡¦±«Ÿ¬£¯˜œª¥©ž—š¥“›œš¦«šœœ¥–•—•Ž”—£¨¡‰Š†z…~„‹z—Š†y‚‡„ˆ‹Ž…“˜ŒŽ–™Š–~†—‹y€zprwoot_ywdllkihƒmerjkeh\cs€_ZkuiZI}][XOOJHHRUF29_^lPDXVYeMIIEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<#8R=*113>D5,-'42+;+139cl84GAf[HTDU]hE.;2`T,2–£¡—•œ©¥¡¢ ·ª¯ º¹¦¬½Ä³°®¢µ¯¬®¯´ÄĽ³¿º·°³¹¸º¸»®®À³´¸¯¿Á¸¬½ºµ¦¢³ª§©³«®²¢›Á¶¥¨µµ©ž²»ª§¦©°¬™¢§œ¤¦”˜¢²¤™Ÿ¤¨©œ¢ “¥ ¤¹¨¤§®§ž¥¡¨’Ÿ©¢¡ ™› ’šœ– ¢«››™¡•’•–š”“£§¤ˆŠ†y„|……}Š‹†y€„‡ˆˆ‘…•“’Œ•”Ž”{ƒ—ŽŠw~{ltrlltbxuhhjgeo„ghhdfij`hbifZe{c`SsT[[SLIGIOS@!*i^jLCVU^`KIHEC.:B<F<6KPD8:D357==895?:;4>8@L=>93)8><:9*6@3.E4(+,>0-N?.+-7,1195,&.5-80576`tB3CDg[KWGU`hB378cN'2ž¤£’Ž¤¦œžž£µ­§ªº·¨¬ÃÀ¶°¬¢µ­§¯¯¸ÀÀ½±Á·±®²·¶¸·¶¬ª½³¯²±½¿·®»»±¥Ÿ¶«¥¥´©«® ŸÂ«¨¥°³ª¬´º¨ª«±¥˜ªž¦¤‘™¦­¢˜ž¤©¡œ¢— §¶¦¯ª®¡¡ž¡• ¦Ÿ¢ ™›™œ’™”¥ž­£˜—ž•”Ž•˜Œ˜š¨ ‘ˆ‰Šˆy…w‚‚‚‡‹‚‰|„ˆ†…„–•Ž‘‘‘’{ƒ•†s~}fxokklhuskcgdctbdefeijciqY^X]mdaNhWZ`VIGHKMRX?9`liGBUS\[IIGEA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A=-5B37=+*,0A*JK./*+3722(57$+7.72685\yN2>HiZLYJVbfA;3AfH%5›¤ ‘Œ­¡™˜ –¥´±¢±¾·¡±Æ»¹°±£¶««®©¹½¼»­À²¯®­¶¯³¸³¨«¸±®®´¶»¶¯¸½­¦µ« ¡±¥«¯Ÿ¤Ã ²¤®±¯·­µ­¯­®£™œ§ª¥ž•›¨¥Ÿ™¥¢§œš œ”œ­°¦¹¨®£¢ššž™ž£š¤—ž˜›”š¡’¨•¬©›”›œ’Œ•™Ž””™©§Š‰{‚t‚Š˜…‡|‰‰„„ŠŒˆ’…“œ’’‘–Ž€‚ofynhkjgqrk\hdbr€`dgjmlgjifl\lmuqaTbhceYIFLMOXQPUaeT@VSYUFHFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24:6#3*)6.55465Z|]19Kj[M[KXdd@A1IeC'4“¢›Ž°š“¡š©²°Ÿ¸À¶ ´Â»½¹±¥¶¯©®¥·¹·¸¬»¯­ª«·ª´¹®¥²µ±®©±¶¶°²µº§¨Ÿ¶©žžª¢ª­œ©À˜­¤®°¶µ¬¬ž±­°ª¢›œ£¬¨›•œ§£š©¢£•š ‘›£«ª©»Ÿ§¤ ˜ššž¡k¢–˜œq‚–œ¤€v‘«¨ž••Ÿ‘‰—™€—‹ y†“Œƒmi~wƒql†‹†}„‹†o^c`g„—†k‹”’uw‹„~ƒf‡€huifW\isnNPjdfq„f^dfnli^__‰„†hOKD8ETg^JGPPUUKGS`oteE[QUPFHFC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,+08>G601.*.*/668,#1'214:176Xl16Ok[N\K[fb>G1Pd=+/¤™‡•°›œ“ ›ª­«£½Å¯©·Â¸½¼­§¶°¦«¤¸´²³°¹­ª§¬´¦°µ£¨¸¶µ¨§¬¶²®´­³¢©Ÿ´«ž¢¤œ§¨š¬¼•¦¥¯³¸­­¤¨®«¬¥¡žœ ¨§›˜¡¦¥››§§’Ÿ ™‘ž¨ª£µ°£££–˜˜—£ˆ¡’š‡¡‡”ž¡¥§«ž“’›’ˆ„rxŒŽ„ˆ¡vˆŒi—ˆf}sx¡oˆ‡„~{¡ Ÿ™{ˆžtˆŽv›Šl‡ƒmheczlqbT†mcmi˜qXjpn†W^i[kj[ˆpmyr†h‡„Z^FN>F^MERVWQQRWTg^LYKRROEGG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82).1<I9/01.*/(-4583%&2115>1<8Xƒu25Rk[N\L\g_=K1Va7/(Œ¦—„œ¬™™Ÿ«ª¨ª¿Ã®±º¼·À¾ª¤·±ª¬¦³µ®¯³¶«©¥±­¥µ³œ­µ¶´¥§¨³±­²§¯Ÿª ²¨Ÿ¤£š¢¤œ®µ•¤¥¦¶½¦¬§©ª¬¨¦¢ ™Ÿ¦£™™¦£¤˜œ¤©–“¢œ•“£¥¦¡·¤¤ ¤˜•“˜”œˆ®˜”‰©‹—£œ…±€¤­ž”šž•y‚Ô¨‡”Á›Çyx±¥·—d€Àœ¿y„„yƒ|‘Êq–¼œÅ{r¶§º{l–±«°yhkX±®oei¼’¼nhzmrØ~Sjc¶²q”uš¡ªWOWaOVNFT[XQPS‹\W[P@\EQNDGI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22BE/.32.+/)-/186- /416A1=:Wƒw21Tk\O[M^g\>L1[]41!Ž¦“¦©Ÿ—œ¥­²©±Â½²µÀµ·¾Â«¦´­­©¨¯´ª¯¶´¨§¦µ¦§¸¯³±µª¥¤§±®­±¦ªž§¤±¤¢¡Ÿ—œ Ÿ¯­•ž¢Ÿ´º¢©¨ ­®¥¢›š¡¨Ÿ˜›¨ Ÿ˜ž§§‘œ§›”¡§£ °£Ÿ £––’˜’™…°kjŠª~g„–‡­eqž•š¦•q®¡¤~w»|k¡v±_j´[¥€fœ‘`fzfjxj©e¾rg¦Œv±j|±xt’“cmm§n[„ Eig‡–Euœ`~g{£§‚Y_‹«i•xzj§7J¯[WTlc[KNW_\WV;NˆOWV/ITSICEF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3..53/+/(.0.:6/'$203B/=;U‚v2-Vj\OYL_gY:M5_Y31’¢•‚¬§¥ž£¤ª±·­´½¾°·Ä²¸ºÂ§©°¬¯©©±¯¤°º°¤¥®³£©¸©ž³²°£¥ ª­¯«¯¦§Ÿ£¢°œ£œ˜•˜›­¦—›¢ž´³¡ª›¡­­ žš— ¢©œ™ž¤ œ™¡§¤£›˜¡Ÿ¬Ÿ¦¦ › ¡–•‘–‘š†µ›µx…©™µ™w‡³›·“–—©”~k¦z…ˆ’”’w«gj±[¬{‡”tˆp†€ˆ—xƒ‚‹—Œƒ …°vwŸqkjl|‹N¤XHcc™~ch¦`yruS’†^P©mcq~‡€b.Q¢n[Tkg`LK\dX\ZB>°xWXA#MhEBDA@A19>88:84;:9<9:A:E::;6:CB8=?KNH:5:AFB@AD<FD;0201;F,0.940,.(/3,>831/2-D1<<S}n3+Xj\OXM_gX7J9aU50–Ÿ”ˆ³¦¦¡®©§³¬ª»¶Â°¼Â­¸·Áª¬­®¯¦®²©¡¯¼ª¡§µ­£«µ¥¦²³§£¢§ª²¨°§¥ž Ÿ¯–Ÿ™•–—˜Ÿ­¢šš¤¨µ¯¡©©¨©›ž•˜ ¥¨šŸ£Ÿœ ¢¥£•›ž˜š£«›¦™››¢ —“‘““ƒÕ“™¹p°Â~Ɔ|֔›»|š–¥›Œ¤z‡£‚¥‚z¬yU¯{‰~Ÿj¹Z¹w†ƒ}¦‚“|˜zªy{±nŽ„t»…o”O¯§ÅŠQ zc`ªbsr‡l—‡_Sµ´È†€‰|c¤3Bv]QjhdP@XfZdaJHMlKZSOYfZCC?E?0<<59;74<;8=:<C:F:;>6:@C;6@OLH<9;DHCBCD<EF81211DB./0483+-).323971#%5*>3==Qwj6*Yi[K\P_fT7G:aQ82%œ¡“˜±¨¨¥³ª¥´¨¥¼·Á°ºÀ±µµ¼³¶§±±£±³¦Ÿ®¶¨›¨º®¢¯± ³´° ¤žž§©°¨´©¥œž«—™———–—¡ªš—¨­°©£ŸŽ¬¢§–ž—œ¡¥¡˜¢¡¢¡š¢¢§›ž ž•™›¦ œ§”›šŸ¡™’•‘ˆ²nhµq«ˆpŽ¦r´sr¶{š˜¤›¢~ ¥~°vƒ‘ÒÑu[®|†¤o›ª¦k†…}­}—™{±s“Žx³e–t…žnžf”RȋZÂ\Ÿyb_­`ws‡b—ˆ^Yʝo¿uMKµSUÆdTQjcfXAOj_liPUFI9=WR[WXHC?J<2?;5=<46>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>II:1746@>/.24252-).26,742&60;5:=Pqh9'Wi\BNT_eP5G=aM62/¢‘¤¯¬¤ª»­¦´¥¨¶»¼²»¿·¶´»»³¥µ´¢²²£Ÿ¬°¤˜¦º®¤±°œ´¸ª ¦¡ª¤±§¬ª¥šš©ž–•˜™““¢§ —“¦ª±¦¡–’¬Ÿ¥’”¡›¤¦Ÿ•›¦§¡š£Ÿ­š žž–œ¢žœ¥”œ•š¢Ÿ•˜–’›…¬{w¨v£Š‡©o­Šƒ¨ƒ™™¢Š’™‹¢~’˜‰®…‚³\r³R®~ƒ‚¤q×}w„~†™šw¯†Š‘œ‡w´ašeš‚•l’Z°XKšu˜yf`­^ww‡g˜ˆj]¯w•žxl5yÈ®²_ATo^h`EPl_pmVUM/eciSYQ;AD@L:5?91=<16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK97<46:>/04333.2..18*.32%!03767=Pke>&Vg\@=V_cN6GC`I:88Ÿ” ¸°˜´Á­¨²§ª²º¸´¸¿º¸³¶½µ¥¸´ ´¬Ÿ ¨«Ÿ•§¶¬¨°±«­´¤›©  ¨¡µ¦¦ª£™ž•¥¡””œ™“–£¥›“§¬¯¦ •˜©Ÿ¢‘¢™¨¦ •š¦©ž¤ž¬  ”Ÿ›ž ˜™œ–—¢ ”˜‘§†©}}¥y¡ƒªp­Œ‚§†– ¡Š——ˆ£ˆ”ª|€‹yo±Z¨ƒ‚ˆ ytØv‡t§Ž›’¤|–Ÿ„{²^œd }‚”l’\«[Z“‘hgªds{k˜‡q]¬Z‰ ŽkneOJC¡\ZLt^cfMZa_st_JU5Jš’YHE=HFAL35A8.;>05A78@<6=<F?:<6?=B7.HVJE@H6KIN@IK@EN::@4.:>102154+*05/7,&21($$6671<PeeA&Uf[?1U_bL7FI_C1>8¡œ™™¾¬˜´Â®«­©¦´°¸±µ¿ºº³±·¼ª»µ ±¤ž¥§§ž“ª±©¯ªµ¬«¯¡˜¡ ¦¤£¹¢£«¡—œ‘¢ •”Ÿš”™  Œ©°¯¦—š§¦Ÿ’¤—¨«§”—ª¨ŸŸ £­£ ¡•¡˜Ÿ ’—œ•ž¡•—«›®mr´t©ŒwŠ¦s´yt³€’¤£’œŒ‰¤‡Žv¸oŒ{‹¢kk¶Z¡†e——i ¢§m”r´t“˜²j†’ˆ­ku³af¢n†’j—\­`M¡|‡‘Rs£ly~n˜†o\¯V<œwfTon.\§ObRkebmYb\`q|cSYP>>mo3BB@?L9!7@6.;@37C58??3;<CDBJFMIF62JTKEBJ6IJP?HOCFP=<E50;;010/75,+,426/#00,,289/9N`eD'UdY>/U_aL5FM^81B8¥š›»¢œ²À®­««§·©¸¯µÀµ¼±¯¹¸«Á·ªª ›¦¤¡’«ª§µ£²¨®ª —œ¨ ¤«¹£­œ–™¥£–¡œ™Ÿ‘“•«¶¯§™”›¬©—Œ“¥™¥¬£‘—«²¤ ž¨«°™¡¢™¢— ›–›—¡“©œ”‘«™‡Ô’š»t±Ä€Ã†}Ֆœ¸xˆ‘—Œ—‰Œ§‡y£¶u}wv‚š²`ƒºyÀ|u¸bµŒ‡©}–¬©q{u¼ˆ§ ia¦Ž¯¡~Œt‡«}¾ns¼t²ƒux€Šnšˆpm¤t½]w}[ay¼kZV[jz^i`dfbmxoY[YCA@r?CF+5H"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.97-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-7A9¦™ž¢¼¢—±Ã°­©ª¬±§¸¯¶Ä±»²®»°®Á²¬¥¢ž£¡œ›‘ª¤ª²¤µ§­¤Ÿ–šª™¦¬¸œ¢®™•¡¥ “œ£ž˜žš–’¯¹°«•—£¨§”‘–¥œ¤­ž‘ ¨«Ÿœ ©¤³ž¢¤Ž§¢”¡šœ—•¤˜° ’•ªž…™µ€‘‘¸•x‚“›µwnlnsny„Ž‰sžÁ»¼š{²¨p€t‘¹ƒ|††‹‡{Š†—|¤»¹½œuz³£tv—ut°u˜žf†i¶trpw¶Œ^z}‰gƒymyb‹¬pu…Y[§jEdZTf`c]bQggqmuBMPLD;ZL?J3<0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITAKNGEOF?G<7>7070/9:.,/-*8/%&2(4$(>7/7KT_G'SbV8*O]]=+;VV'=;<¦ ¡¿¥–´Ã´¬ª§¬«©»®°Æ¯µ´¯¸§µ¸­©£¢¦ž ™”¬¤­ª¦µ¨¨Ÿ›– £ž¬¤¾¦¡ª˜•œ‘¢›’¡¨¢“—’˜”²µ¶­˜¤¤¢‹’’¦›¥«›–¨¤¥œ›¢©¦¦£¨ ‘­ž–¢ž———ž°©”œ§¢Žj~iœ§x‰s~šŽuze‡{½¾Àºn’ƒq”†_rjZ^š‰ad‡Ž•k`€•cmœvb”kš•”e^`cq›ŠhrŒ}†•gj~qty}|b[wthP\nƒ|{‹jXly‚rIJo…pMtMEW]faL[Xgc^O[muiqRODEN;HI<M?2,2A?8/5?C<9;@;=C>RVVWYZ[[\]`aaa`\UG5DFUEKOHFPIIH;8=51:.0;:.0-76=5&"/*2,%;8-7IR_I'S`V4)P^L(3>[O'?2>¨Ÿ¨¡Á£š´º¶£¬¥®§¨µ²¬È¬°³¬µ£¾±²¦ £©£›š™¬§®¤¤µª¥›˜•¢›¦­¨¾§©¦–”›• š“˜¥©§‘ž˜œ°²¿¬›¦ž§¢‰“‘ªš¨¤š›«Ÿ£™›£§­¢Ÿª¡™°›”¦ —”Ÿ—°¥™¢¨™œ‘žœ£¤™§£šœš›š–‚hn|qv‘—”‘„‰´©†˜•ŽŠŒ——‡”•Šƒ’“‘‰‘”™“˜—š ¢››” Ž‚z¤…kj||€t‰Šq‚xyvvŠ€{Šjstƒudw}vkp{m`c\phMYYej_WYozmmfSOFS9OZNRO(+;JB635=@A9:C><ENSSTVWXZZ\]`bba_^^[TKCSGKNDGPLOI<:;389,2;820)6IRO8")+/2#4;*7FO[J'R^S10T^:+=8]K,<-@² ³¡¿¢¤±²· ©¥²§¥°µªÉ«­±¦µ¦À¨´ ž¤¥œ¤•– «¦¬££·¬ ™–– —­ª¥Àž«¤–’œ—ž˜“”¢Ÿž¢§’‘™¨§²Ã¯š««ž––©žªœœ ¬˜¡›¢¥¯¦¢¤§ž­˜–¦™š¡žžœ° ¢§–˜“™” ¢–£Ÿ— Ž–”‹ŠŽ—­{•›‚’‰©¨…˜–Š„ŽŸˆ{„†…™‡†‰•Ž›—˜ž£–š“‘~f¢³®…‰„vzŠ}vyzogy€‰kuyˆrhtzvƒˆ‚ktcyf`idcdfjXk{pij\RLPD_UF@?>,4@F;45;>A;<?>>HNNOPSUVVXZ\_aca_^]]^]XVJKLBIOMRJ;<:786/2964.(&$-1./)+*7%+<(6CMLD/T]Q05M[17E4\G5<,@´ ¹¯¾­«®²² ª¦²­¢¬³°Å°ª¬£³¯½¤´œ ¦¢¡™—¨¥¨¦¤¦³µž•”ž™™¯¦®¾ «£‘‘žš™”‘•¡œ—©…ž©¬¢³È´ ª¤«––˜š§¨›Ÿ¤«”žŸž ª®©¥¢ª¡­›žŸ¡˜¥žœŸ¯¤™Ÿ¨“˜—’¥š˜©žš—fƒ’|e~Žšcxlhkz£«keš˜~g…Šeeihz¡ŽkhŒ—‘¢wkj‹˜£Ÿ˜slnz„†yXe]…^kŠŠv[hsww‘€‡‚nx‚x€smy„twˆˆƒ{j…X^ktd]sˆij|qlc]QNWIdX@J3=F7?FD71<=?AC;;DGHHILNPRRTW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%/*+'6*$;'/AI[I/7ZO6)EY/DO1YC;?.=¥Ÿº¼¹¯«³°«¥¨­®°¦®®°½±©¨¤­°±Ÿ­—Ÿ£ž¡š™¦ª›¬£¦¨©³®ž•£¢¯¦¶¹¥®£Žš¡™“’š ™™¥–{¥¬¢¨³Ã¸¤¢§¯žž•ž£ž£œ£©¨‘ž¡ž ª¯ª«¢©Ÿ¨›¥ž§ ¬–¡›¥°¤˜œ«–¡ž›“¥˜ž«™ž~¾ƒˆr´r…ž†­hx¹Ä¸q’¡£{¦˜™sª‚|ËÀÀ»q‹¢‡ƒŸ|•˜ˆžÀ½‚–žÁÁ{z‘ŒšÂ¿}k¥±oŒoÊz›w‘ƒŽ€vyyqz‡qx…Œ“ymv’bf_xc_eb^thmdbXLVIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^__`_^^^^___]\SMPGUNA??=6468276*&%#)*&.+*)109*#>H[L*#CP/#F[3PY/UAB;/8–£¸Ãµ°¯À©©”£¯©°¯­¦²µ¯«¦¦¦±«Ÿ«˜š¢ œ›ª§¢œ«¢¥¨¤¤´¤£“¦®¬·³§¯¢’‘š¥’‘ ¡—œŸ‡¦«¤«­¿À°¡©¯©—’Ÿ¢™¢£ª£’ ¡ž­®©¬¥£¢¦ ¤¥­©‘¤›©­ªœªœ¬¢–—¥–¡£˜œΔyz¥‚y•–›_®^Ž§€¡¡}§–›t«ƒ€¯^d©z§‡… t—’ˆ³c‚«†¡Ž³i„®t|–‡¸a‚­Y£Ínu{Û{™p~ˆ’ue{‡vvk}ˆn~…‘’~mŽ`qkpf`_xd[phjcf`RTRW]JOC5AHED8>6;@?A;=8@>>?BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5578164('$!',&&/(&+360$7;SL+--J0';\:L-!P@F4.1­ÂÀÀµ´°·˜ž‘¤ª¨­´«¦²¬¬¬¤¬¦°ª §›š¦˜œ¢°Ÿ¡Ÿ¨§£¦¡ž°¬›ž–¦®­±«¨¬ ”’›Ÿ¥“Ÿ¥—ž¨£ž®¤«°¨¿Æ³¨©±®–’œ¢— ©ªŸ” žœ­¯§ª©›§¦£¡«’­´–¦¢«ªž£§¦¡°¡’š§š¡›””‘— p…Œ—u…¨‡q±|q¬~¡Ÿ‚¥žw«‚}­œr­~«‡†Ÿv˜’z|—~ªˆ¢Œ‘‹~«{ˆ“ €z­VœÄzo’Á}•mupŒmfve†oawnro‰Š‘ƒmeotvo`fmd_oiinfcWS\aZRRC8II@C<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^]\^_a_^^][ZRC>;91478452&# 1' 1' '45-&7>WJ-='>1)3V@F!G:C1.+¯ÔÆDz´Ÿ£Ž££¡¬®¶¯©°§©ª¨®««§¢£™¢•Ÿ¦«Ÿ¢¥Ÿ¨¨¢Ÿ°¬—›–¨§¯­¨§©ž—”š£¢’”¡­›¦£®¬£¬µ©¹Í²­¦®¬–”œ¢˜Ÿ®¬–Ÿ™Ÿ©±©©©›«©£¢«›¯±¢¨¬®¦™¦«ªª±£“—£¥›”’…¤j¤u‰z©tz²p‚¥‰™Œpˆ š‡¤_`R«„®‚›v®§††Ÿz˜–…{f€£‰¤™†£}©~€”‡®^|¨U¢’z¢Ÿ€{ïŌs¯³³¹qb©¯ÂthŒ˜mš’onyxwnlfedqpf{hc]W_iXXTLLQLCCAB;CA@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799674,&$" ('"+-"$.!3-&@DWH,G+66*1PKL# A9D4,'ÂÉÕÖÀ¡™«¨¡¯¢ž°µ°¯©¬£¨¦ª««©¤¦ ›¥Ÿ¥§¦£œ¬š¢«¡¤Ÿ¯¢›“ª¤¶°® ©›–”§£š¢¨Ÿ ¦œ°¦£¨±¬¶È²µª¬ª•‘œ¢™Ÿ¥³š “œŸ§««£®š¬¨¢¡ª¢³­¢ª³±¡›ª¨¯¯¶£“—¤§˜›‘|ªlž„‡u«y|°o‚¤‹‰Ÿ–•Ÿ•Ò¸´¸É€²^_”©ƒ¤‡‡ z˜•™xªÉt™£•§©’›Œ~›‰šÆÆwe¡‚¥sŸŽ‚}¯^oµc±uK£†m§G‚“dž“|p—’~p{u}zm\fjrqfj^bXcm\^YIMMKEDAB>A<B?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75785/)(%&%$&),5FNOPMFLJVF*L0/>-4OTQ;<F2,$¨¤Áƹ­¨²®¬¥¢œ²¹¬ª¡¦›¨¦ª¬©§ ¦¥˜ª£Ÿ®«¦ ¬šŸ©¥¦µž¢—“§ªµ²¬›¦œ •¥­‘™œ§£ ª§®¡£§©°´Â²³ª­¨“‰˜¤š¡£®¤–¡•˜œ¥¦«š¯­¨¦ž¬£·¬¡²¹¯›¯§³´³¥•˜¨¤šŸŽ‚NxšŸz„£|‚¤„‡§Ÿœž“„¸||y¹‚~ÌŶx›¡‹Ÿ~š–—Švž˜Š¤˜£¨~°…œ„ž„¬}™”a¥l£p…}—ƒr¬`¤sq€š`¼}RUuŽ‘£—|~’‘‰uzs„~p\mnwrjoZd_hnbd]KLQTAHGFI:9K>B108856877-*5==?BDGILNPTVXYZ[\__^]__\ZZZYUSOH@772.,*.+*'&?QTVWWWYXXWUOUF<E2:P[T6?H,- Œ‡™©¬¤«¹«¯ œ¡¬³´¦Ÿ •¥®®®©¦¦¦š£§¡²®¡©¦² ™¨¤”¢µ¢£•—¡©´¹¤›£ž£“¡²™žœ§¦¡¢¯­¤¨¢µ±Ã±­ª­©‘‡‘œ¦œ£¤œ¤–ž˜™™¥¤¨š®¡­¥¦˜¯¥¼­¢··­žžµ²¹²³§™ž°¢¤ž†ÑµÃ·y‡Ž…‘“€¦x”¢wŒ ’„¥‚‹q«†„´nrj™£œ•‰Ÿ|˜™†‡s¯‚¥›¢¦‹“‰”›mp²\¥s“zœl™{™}n©a¢qqŸbs²¸hx“¦˜~ŒŒ’‹x}ymiwixsnt]ddnmeh`JZWX<GG@U3@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^``]Z[ZXURRQF:2230/++(@QRTUTSTVWWXXWUVVTQOQ[U%!2AH$)%’sŒŠ®¿¿»»µž—¨¤­¶¡¢™•£©§®©«™¥¡Ÿ¥  µ§¢©§°£”«£Ž¤­£šš©³´¤¦©’”—®  ž§¤œ§œµš ª£¶«Â°©«ª¡Œ„Ž›¡ ¦¢•˜™œ˜š˜¦¤¦˜«§­¢¥›­§¾¬•¾°­Ÿ£°³º¬´§›©²¥¨˜z¨}|°wŠ¤¥ˆœm²o¡‡­|¡ƒ¨–™€¬‰„®…Ÿ”© ¢–…Ÿ€™•€{’~«€š–Šªx ‰“’€y¯]£|¦§d€|—tk®]¥kq…™]`[Œ n•‘¦™ƒ”–‹zz‚–~km~b}tnz`geqogghCY`[=JS2U8BBC7$$3+''3, /667436:@CFIKMNQSSSVZ]_a`aaa]][ZXSPONI7052.*,ATVVVUTUUUUTTUTSTWWWXVUUQHFIJ#((¼’š„©ÆöÁ´Ÿ›­ ®¸¥¤Ž›¤£ ¯¯ªŸ£ž­˜ž¹ ¢« ¯ª™­¡ª©¤–‰š®°¬¦Ÿ§›¬˜˜¬¢¡¦¢š¥œ­˜Ÿ¨¦¶¨¿¯¥©¤žŒ€Ž›š ¦ž’”™š“šš¥¤£™¨««£¤Ÿ©¨¾¤—쪣¢¬³º¬¯§¡´°©ª™v¯~‹œ…‡}º®Š˜e°Œe•­}¡ƒ§•š¬Š„°…¥™¤¡¢„ [lj³`­{{‚€±lgn™—Œˆ±[}´[¤ƒkÈ¢eŸ€{¼YvµZ²}R¯€z¬X€¡m˜¨šŠ—•–{xœ}ds}bƒwt€|ajfpmfeeOUc[AT^>I(>9=4!"-%2. *1/04579:<ACFHJLNPPRTWZ^`_`ab^_\[XUPMJGC553./@UYXWXWXXWWXWVWWWWXWWXYZZ[\XWWGB;ҟ³²·½»´Á³£œ­¦¥¶¨¡‹™ Ÿ³³©ž¢Ÿ´˜ ³¨ª«ž°®«›•®©¢Žˆ›Ž¯¬¨¦¢§™®“™¨š¡ž¥Ÿš££¥™ž¢©²¨¼¯¤¨ž|‹›•¡ ™’š›‘™—¨ž¡˜¨­§¥¥£¥©»Ÿ Æ§¥©¢«´¶­®§ ½®­­–©’£¯Ž›€†¤—˜€¸ÃºƒŽœ“…§—œ‚¬Š‚¯ˆ¦›š¥ª‘~սªb£¿½|~£‚ƒ×º¸µ…”“ƒž½¾„j£o«„nz²°Çƒj«°½­xw¢¾»t€–Ž¦œš•œyšyb|zdŒfy‚{`kekjbPb[Sj\@TaBN)=:4/$%2 $(0496678;>ACFGJKMNNQTW]a\__a^`[\YTQMIC?<A?5=SYYXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ¼•´´±¿¹²½³¢®¦¥³¦Œ˜¥¿ª·±¨¡¿¦¦±›ž±œ¹¨ž­®¥¦•”¯¬—Œƒš‘¯¦£¬¡¤œª¡˜‹£’¦ž§œš¡¨¢™ž «­©¹­¨£›—“{‡™‘¦›“‘˜˜Ž˜“©™Ÿ˜©¨ ª¦¡£«»ž©Å£ ¯£«³µ«°ª¡¼¨°°štuª¤·†e‰Ÿpg­Šmow¤™Ÿu®™•pŒq•§£›˜®¤rmmmeŠwnm‚™q€yiqig‰–•˜qhi…†gp†d^‰cjoY]g~w¦`bqŽ’ofd€’Ž¢˜—˜•ž|‡Ž”ue†whjy~ydlcflbKdXJkY:PeER'K:+# #,)-2.5:457:<?ABDEHKLMOQSV\WZ\``a]][TPLHD=:AB7MXYZYYZYXXYXWWVWY]^^]\\\]^]^][[UW^¨”­³ªº¹²³ª©¢®ž¤²©˜’½±ÃȾ¶ªžÀ«¬£ ¦«Ÿº£¤­¬¬¦Ž–­ªŒ…•—­Ÿ¥ª¡Ÿ££ ‘Œ¤’§™©™–£ª –œ¥¥§¯º«¬š›’’{„—¥—‘‘˜“˜•§”ž—¨¢š°¦ž¢¬ºŸ°Â¨¤³¦¬±²«®¬¨¹¤¯¸–Š¡¨¥¶‰–¢˜‡©š”“ª³™›£¬ ²–¢ ž ¢œ ¤¡•«¦Œ’“Œ‡’œœ”™“˜Ž•†¤š—•‹“’Š†„~g‹t‚vtˆŒq§m|•‘”“” •—– ‚‡“ŒphvpŠwv|zjlddocU`Y@iZGb`OZ+F=+&!740.!%2(*799469;>?ABDFJKKMOPQWTVY^_ac]^UQJED>9=@ASX[\YWXXXXXYXXZ[[\^__`^^^__```_YY`¥–©ª¥µ¸¯®¢°¤­Ÿ µ±‘Ž«Å¼Ä»¸ª¢¥›¦°¨£¶§©´¦§‘˜¬£‹ˆ‰œ§–«¤¡™§žž“•£—¨›©™”¦¡¤š§™¡µº¨ª˜š|”Œ¡”Š”‘•“—¥ž™¨Ÿœ¶£§¬·§®Â®£·¦¯¯°­ªª´º¢¯½™’¦£¦¶£’¦ž©Ÿ’Ÿ£¬¯š¡£±¨¯—¤ œ¤ªžœ—«œ’™¡›“–ª™˜˜––ž‘ˆ •”…’ŒŒ”‹~fŒ†u†vyˆƒsœj‡‘””‘Š}Œ–’’˜“¡’œ– ƒ‡—†yq•ry‰q{jnd_pi`[`YmbP`cP[:GGD=2==7.*&+)&&406658:==?AACHJGJKLMSSSUZ``i`eVPJACB;9EMV\^^[Z\[[[\]]_^]^_`aabaaa`bbbdb\[c˜•¤§£°³¬®£©§­ ¨µªœ¥³»¯¬¬¡¢™z¢°¤¥±©–›¸¦¢”™©œŽ†Š‰›¢®ž£–§Ÿ¡’—˜›®‹«–¨™¨Œ˜¨ž¹¶¤¥˜›‰y“Œš“Š”‘“‘–¢Œž¨žŸ¸¤„¯µ¢°¯t¤¾£² xz «³¼•v®¤ŸŠ€ª~d\bvŸŽ¤ž„—~n“³œ£¨®«¢ež “sy™–p€˜¨—l¢§‰eœ¥›—˜–‹‘›‘…š•‚’‡ŽŽ’‰…xk‡v†q|†€aiˆ‹•“‹[v•‘ghŽrz¤˜˜dy˜†w—iƒŠ‚nykpe_vokkh[fcbboS[>NNNRG=@TB91/&4:316678<;>@ABFHBGFIKLSTUY\_hfgWQJ<DG;8UR[`ab`^`_`aa_\]___aabcdabaaedchd^]fœ•¦£¡°±¬«©¥¨­£§­¤’–«µ¯±¦šª¦«—s‹œ¯Ÿ¨ª§“–¸  œ¤‘~ˆˆšž«š£”§¢žŽ—‘ž…u®ˆ¦š¨‘–£ˆ›º´§ ™˜‹‰tv“•“Š””Œ“ ŽšŸ¦™œ²–€Œœµ´Œ’½§¡~§¢z£¯¸ŽŽ§Ÿ„‹…±©¯Œ‰–£šy‹¬†œ¢§ª¨‡•†˜w¥›z‡›—¦‚{œ±zŠ…Ÿ—™”˜–––„™šcy‡„Ž’‹ƒnqˆyq€††t‡…–’x–h“t št|™ƒŸœ†˜~‘‰‚˜jŒ„kx{qpgdwnilk[ejier[^ITLQ@E5-YTT6)!09=>643568;:=>>@DI@IEJKGRXZY[aahfZQH9EL;>bV^bded`aa`bb_]`aabbbcfgcba`edcgcaah˜£Ÿ¦®®«¨¬ ¨°§§ª¥™”®Æ½° •¥¨µžƒœ«œ¦¡Ÿ¾ž™Ÿš }…Ž™—ˆ«¢•Ÿ ‘“‰†€‘¨Ž‡¢œ£“–†Ÿ¹²§š’Ž…puˆ“Š”›‹‘Ÿ’–Ÿ¤–ž¬ˆŸ´‰´š®‹Êˆ«®‰·…°ƒ±¯„©§˜|¨r{w›Ž¦–h•¤y´‹Ÿž¦¨’™Â«ˆ˜¡qž€š¤}—…•±¡| “Ÿ˜—€Ž“›‰˜’‹|…“†•“‰ƒms‘†€{r†…}…t…‚—Åf€©‡¢jžƒ ˜™Š‹ƒˆ˜oŒ’„gwt{vghupggl^cnlflXhG\QL2E46M`c6&4<DGD:64658;8>==>BL?NIJLCPZ]\Wb^jl\QE=KM@JdY]cfhgbbbbdc`_babcccdiicbbbecafcbbi•—¢Ÿ°¨©¨¥« ¤¹±ª«¦š” £¤ª¢•£©¶£¯ §œ¥ž‰“¼™“ ‘y„––‘‡«™›š™¡…Œw›œ ‘ˆž¤›•˜—†¢¸­¥™›ŒŒbmŠ’ŒŒ—‹‘Ÿ“Ÿ¡™¡¨~¡§‡­ž –®Ÿ‘† «¯‡¤ªšŒš~£v€˜“k«uM«x‡‘›¨§ª«}ƒ¡{z§iž’kg—†—¶ˆž}m`cXƒ—Œ{dg‹s™}y–l]|—n_Sq„\`lyƒ`Ye‚}„˜q§ªkƒ£nr¥pŸƒžhdŸlZlˆzeY_‚~aWPoventrjjo^jolkhWiO]WE9A4GC^k4+ICQMN=84859;6@;;>BO>QRLMBJ\]_W^_bv`MD:MOMTb\\ffiibbdbddbab`cdcabikdbddgdbgeach˜– ¹¡ª£¦¬’¡¶¼«®¢™— ¡¥¬¬Ÿœ­µ£¨’ ŸŸ¦›™Ž˜´™‹žŒ•‹u”‘Š¦–•—žž’…†¬¤‡œ‘Š˜¨—™š‘‡¥°¦¢•šˆ‰hnˆ‡ŠŽŽ‰‹’‹’¢Œ“ž œ¢¥“£¡” wœ–§ƒ¡§€†ª®…¥y‹}„š}¢ps“‡–{žŒym‡›Œ™›¨š‡|‚¢sv¦fž~w¤_˜z|’s¢n˜·´ºt’‡€¶¨dÆ¸{p•·Œq€›¤cs¬«`}j³~n}‡ƒŽ‚‹—q€£ls¤sžƒ¤^™³–o{—ž³tr[ž²‚ibotuqhoXklrre\i^bKD=D5QAYq2<RF_JR=<395::6D;;@IP?TMNQ@D_^[ZX``|dHC8LWUVbaZffkkbbeadc`ab`dd_`cknccddhdbgfchh”–•£¹™¬œ“ ¤¸µ®­ ›¢œ££¤¬›š±­¬“— ˜ ¤™š“ž«›‹ˆ’x‹…p€–Š “”—}‰Ž¨¡‡˜Š‘¢“›šŒ‹¨¨¤ž–†ƒ}jz†}Œ‚‹‰” ‚–  Ÿ‹‰wœ˜¢Œ r¢‹ˆ©ˆœ§‘—¨«®Œ}z ™z£“x€s—ˆŒœ}–Ÿ†›™›¦†£d¡|‰–›lžhšnš™zŠ§}rgsªƒ‚sªg”š]›…v„hªj¸f\©pœa•Œ^§vu‰Šžhšu‡“’˜Žžn™k¦™\¨~w»j}©ZŽ„]³g\nqywki[qixyc_eWbAPEN7VBRm4JZZ_NZC@151;;7H?:CGT?YRY]>Db^V`Qad}iEB9N[]XdfXfgnmbbe_aa__``ec^bdoq_deekecihgki•œ‰ª¶›¨‰c”›¬º²°¬¦œœ§Ÿ­š°¨«—¢™¡Ÿ˜–– £™†‰iˆ€q{—ˆ‹––„’•˜zŠ„–£‰”…‹‘œ›‰¨£ ™‹‰i†y–‹zˆŽ‡–š“¢Ÿ ¢“˜rhŸŠ Œp’Œ‚©ˆ™Ÿ£© ¨}°­¤¢¸—v£³¢£ˆ”xz«š~¢Ž›—ˆ—r¡|…¯µ}kš‘¡x~˜´££«¨„˜{š|œ™~sªZ]o{—‹xžbM{{…cz—BMŸY¢jr|Žm‰„™u›y‡‰±³š’¦tmq|”o™ri£]•vHec`sp}~ne`lhv|dc`Q^V]TV@YEQgDRW[bX^ID=B8@B:IE8LDWAVQ[VDFb\Z`K`m~rEC<U_bZejVghlnbff^aa\]^ahb_edvl^egfkdflhhki“±®™„S_ §³¹³³©š¢‹›©œ›¨’¡«¤¡¨žœš™•˜¡–‡‡‰w…ny•…š‹}‘’–ˆr€‰’ œr‘€ˆ˜”Ÿš„Ž¨œš”ŠŠ‰{ƒk„…q ‹w…ˆ‡’™•|’¤¡Ÿ£ˆ®†}µ„ž{¦–z©‚–‹¡ž~§hwm~™s sq|…˜o“‚®}£ƒ¦žš£p^©gu£co¥aœÓ|z™xrsc¢…~¢r¢Žuk³‹`‚˜Šsª²¨¼wƒm¿¦ª´^œo~q—os¢r]£gt¦ah¦m›Ó˜{ƒ›nwy—k›zv—rl©¥g_eyp„kgfdmvxh_aR[eQQbIWIT_WS[ej\dPFCKLJKBJE8P?PMWSXORR`feiRdxywIFEc]dYhjTihjocjg`c`\]]_hbahe|d^dgdkdjmghlh˜›°¬T\K~©¯²µ°³£œ˜…˜§  £¤¨ ˜©‰™—˜“™“’ —ˆ…{p}„h}‚“šw‘Ž‰p†“’l—“|ˆ‘£•ƒŽªš”’Š…‰yƒuˆ€n‚Ÿ†w’†ˆ™¢—y“¢¤šŸ‰³¡¢¶‹z¬§¤®¥p©€š…œ’}¤€¢™†˜rž„¢¬®‰—‹€Œ¤–ƒ®¢”vµ¶µÉ¡s”Š€Ÿaž—©my•‡Ÿšu¡‡w }–ŠoLf¢’pšˆs¤{ytaƒ‚l~ lrd`œrt—i{i³µ´Æ¦s˜~{j››«u‚šmtw—išyt˜qPE|³^jujx‡fjgbttqnV^TYhPRhIULXRV\gknVgWMJAJMJHJNAQJPecimetrs~y{nu‰{{TPOm]h[kiRjhilglgce_\]\^ibdhk{_]dgcjfomeime¢œ‰¯§…f?”¡³«¯¯µ¢¢€—¨¢¢¤Œ¥§œ¥‚™—–—›’ˆƒyjy†eƒŒ~— yuˆŒi„…’ƒŒ…zŒŠ”¥’‚—©—Œ‘‹€‰y|‹yp¡†y€•‡‰– –”¥¨œ––„gnxœl¢d|q¥wœ˜pg§—Œ{¥z –ƒ—rŸv€‰”–¹nŠ¢b}™¢•ˆnri«ju ln¦`›i‹h–‡š•u¢€}š_‹…Œuoˆbh¡eži›uocfˆ‚nr¢Z_[d¡n^‰Œo{srd¥nx¢dg§h˜s‹˜n¡oSˆo ^d§T‹]S˜mmrjqmphkxskpRXWWfYSmIXO\HXihsjYkVQREV\LXRaUhj^wuz|p||rƒ{rv€„v^QsagbpgPjhhklngdg_]^]`kbjivu]\chcjjslfkmc¥˜¦zetm‹§®¥ª°±¦Ÿ‹€–ªœž¥Œ¢¡š¢¢€•˜“š‹—Š{†q€ˆh‹‹|—šstŠ}{eƒ‡•ŠŠ•™‚|ˆ…–¦¢«…ŠŠ}Žsi¥„|…“ˆ˜ Žˆ’ª§ž‰¦x–œ~¥‰–Œ²˜žƒ¯—Ÿ¥x–ˆz©t¥„šn¥¢Œ’„Œƒ¼n|¥¯‚†…†”—œ |¥zq¨” –gž~o¬c–Š•’w¨l©¢‰v‡‚w«‘¦ˆk‘°kv³Œ©kŠ†nmŸž’•a«‹ªv€§ŸwŸ}…¤• iš‡v¬gž­Œ¶sw¾Œ¤“Yƒ¦«auqso{tqbj~nhlSV[Uaa\kM\R]I]mmv`[qY[`Zgsenorcqt`w{~yryƒs„€{{Œ‚€vbxdcnsdRlgholrifia_^\bkbllzo\\bibljwmglnb•¦ªœ€ž¤–©ªž¨§®£™‰‚—ª™ž¤‰š¥©„‹š…œ‘…’‹t…zˆƒo„}–“tt†r’‚mŒ’‡†”}{„—¤¥¥€‰„”u‚‡’ol‹©€ƒ‹”Ž‰œŸ‰“«¤ €u•—ˆ~y”®£›q†xŒ…€{r§Œq}}z—–›„Žx{~}ˆ”•“Šv˜ž ƒz}‰lŒ…[yyryqhn~’‰qt”“q…ƒe_€Œwus”uoyon‡m„†_wixŽf‚†Žªœ~t}—j‰ˆo€v|…vmlgŒsx{—w„[jXxhmwqpowxo]l†nigVZ`W\ekcUaU^Q_pwyljvejjju|qrtsaoubs{xuy‚u€€€x‹…ƒ}{mldyn^Wnghukxjijd\`ZcjelpunZ[bkdllymhloaŽ•º©§‹¡¢š¦¤™¤«¢ ƒƒ—«‘ ‰š¦š¨˜‚›‹~–”‡Ž‰ˆr‚|}~„z—Žtrƒp•…{}’‹††…x~€†˜¢Œ{§¡‹…„•‚†Ž—wr…ª†Ž’œˆžžˆŒ›¨  «ƒ‰Ž•š~~‰–­¨’§xpž‘ƒ{“o~©…p}•qjo|Ÿ‹’ŽŒhm]ƒ‹Œ›šžŽs•‹ˆqtk‚vs€Yrn‡}~‹i]icz…ƒˆ€_ix{›|ƒŒƒv†‚hy‹‡kaqsƒw`sŒ‚‰§•†fƒnv‹ƒp…yoefcy‚z•Z\ifnv[zywtmsr‚f\mŠklbYY^ZYlq[_`Y^]ft}{tosckki{|q{xtdmthl|~uy|{zz~o†Š„{}s~ysiT\qiluougkhd]aXkhkjqrmW[enlgszohjm`ŒŒ«±¢£¡šŸž˜ž™©£¡}ƒ—«ŒŸ”‡›¢¥•{—„|’™ˆ‰††Šr}€‹v…‹„–Šqo€r˜†„~’„ƒ†Šz€ƒŠšž‚¦ ‡x—ˆ•‹‹œ—…ƒz­‚‘˜™”Šž‡ˆ¡« ¢¢£Œˆ“›œ£™–ª¡§¦ ’›ˆ—|yŽ„¨~’‘’“œ°¥š”²“˜„¦ŒŒ”šŸ‰›‚‰‘Šk|Žvwe‚†Š|‰„‡‹‡ˆ€„ƒw|zuš¢‰‡‹ž‹…”~Œvqt†…€xˆ‡Š‘¦‘„†ŽˆƒŒ|‡Šˆvkƒ{y™irh`sŠp}zvuowt]^o‡hn__Z\]ShqUc[[alhu{|rnpdkjh{mxqioplf{r€x€}€„zmƒŒ†|zx|~zƒxNdvksmpzdkebb`[tfpfrqlU]ltmhyzqgikeˆºŸ–¢¡˜•™˜”˜¤ {€™ªž…ŸœŠž–|y”‚{Ž™‰†ƒ„†mx€r€‡~ˆ“„mk~z—†„ƒ~€†„†}‡ƒŒšœ’‡ªž‚qŠ…’‘‹œ‘}{ª„’—•Žœ–††›§ ¢š†ƒ’š™™š¦ ¦—‘Šw}ˆŽ…¥{|‘†˜ª¡“œ«‘€žŒˆ’™ž‚Ž—~†‚ox…qt`ƒ†u‹—€ƒ‚†„~…ƒ”nyut“¢‹…š„„t€Š}|rs{ˆ„{yŒŽ„“§†„‚ƒŠ‰‰v…‡‰‹{nk}{mhklg^y~g|{vsuu{w\`p}nu`c[\^QfmSeZ]akivz~qkldkjg€€ls€lltoxn„yn†€v‚€}„vq‚ˆ~{{|{‚Š`i{juhi‚djc`i[cuhobumlTbqyepzzsejmm‹ŠŸ¸š¡£Ÿ’’–—‹šŸž{xž¥›‰†¤”‹˜™yz…|‰‘ƒŒ‚‚m|xr€…}Š|kh}—ˆˆŽ|~†„‡|€š›‘ˆ§œp‹Š‹’† ¡Š…Œ|¨’ˆ’—“–’w£¡¡ž–šš™“Œ›£¡¤š—‘›Ž„y€„‡¡€~Œ|—¤  ’™¦›‘‰’—›~’’~†ut‚pv`}€†rŠ•|ˆ‹rŒ‚…†ŽhwqxŒ˜’—~ˆŠs‚‡||qyzŒ…z{’ƒ–¦“‹†‘|…†‡„u‚ƒˆ‡ydr{~xypljf^}rh|uus|r€j^`tvpxdcY^^RkhTdX^agjvxqfkclhe€€jm~hnqk}w†yk‹r}tv‚†~|{}jrƒnsia‡hlb_qUtomn`xhmWjtvcu{{rbjoz‰Ÿ²’¥¥œŽ˜† šœ|v¤ –Œ¢Šˆš–x{†‡~ƒ‰~ˆ‚€p{tu‚…~‰xgc}†—Š‚Šx}€Œƒy–€•—•Œ– š}o‹“†¥›‡Œ‰ƒ¦–…’Š•—’‘v‘ž¡¡˜”˜zŽ˜—Ž–›¤ž™“”œz…ƒx…—ž~ŠŽŒs—¢ž¡’˜Ž¢Œ‹ƒ–˜ƒ’–™~˜|ˆvq}mzd€|Š…p†“‚l‡‚‰„euo|‡’—}“x‹‰|€‡||rxŠ‡y…‘Š‹˜¢•‚„Œwˆ„‚v{‰…t^xw|s}wfkd`~ijvstt}q|ccasnusmaY`^[ldRbW_`hkuy†pbjcmeh|ƒlhthloh|‚xm†q€‚‚t|ƒŒ~z‚ƒ~|mvˆttmeŠljacuVƒiqn`yglbjvpfy|zq`rl††®—¦¨ž—‡† “—˜}w©œŠ˜y—œ‹‹˜y|€‹}|ƒ{€‚€xsxzs}€„ˆ‹€d^}‹•‡~„‡t}~Š}˜„–“–Œ£¡—~r‡{“‘Š¦ŒŽŠ’ ‘ƒ‘”—‘Š˜ š’’t€’”‰ž§˜˜•—tŽŠl†˜™z‡ˆ‰o—š£“•ŠŸŒ†’œ’’•†™ˆ|‰‰zqyjul{~‹~n…’‚”wo‚ƒ}~Šdrj{€–—„t‰ƒy‡~vx€}†}„Ž…Œ”¤y…ƒt‰‡}su€‡ƒm`zuyp{oanbd{anovrwwstbv`oluno][^]^j^O]Wbahmsz‰k_iejchwˆmflhjmh€|zwn‡s€ƒ„}t†‰z‚}z„}|ŽrzŠxxnl‡kh_irc‡hqoewhnlazhk}{xpawm‹™šª ¤¨ŠŠ‘†ŠžŠ•—}v­˜Œ–}ž“‘–“ˆw~{Š|{€vw€ptszo…}€Š~|`\~‘†ƒ„sz€†z‘‡‘‘›’¤›”}€|Š’¤ˆŠ—š…‘˜“•Ž‰‰Œ““Œn„‘‰ž™¢¡—–‰—’o‰™„g†š”z‰…Šp–š”¡’’ˆ‹™Œ‚ž|’’‹™Ž{Š„‡tsukqnu|‹tn…Ž’qt€{ˆ|dqly}™”}„ˆt‹tˆyn}€‡}…Š…•¨{ˆ}~‹…w}po€…ƒchwstnzb^o`jt^pjzxxlrpey]mlsmsXZ^_ajZPWXdcgqq‡f]ihgbgqŽodigejh€zwtnŽ…s€‚{u‚ˆ…w…|x„…z€‰w‹{zryƒjk_phtkqnmqgole{bn€yvqlwwŠ£˜¢¨¡¦›‡ŒŠ†“œt€©”‘Œ† Œ•“t{v…xxrs{…kroym‰v€€†nq[Y~‘ˆ€€€vu€ †Š‘œ— “—w‰~€Œˆœ‰†’—•„ˆ”™–‹‹ŽŠŽ„n‰‹‘Šœ–¡›˜•…˜ˆk…£ƒg†Š‘‹„‹w“˜‘ž‘ˆ‰•~—|‘š’|Š‚nvokmop{…isƒŽ—Špwt‚‰‚xfsov™Ž|‰„z”‘zwˆtpˆ{†Œ{‹‡„‰œ£ˆ|„w‚‹€xxnj€‚]rrpoowZ^p`oj^oi|ypmmjmv`pokrmYXaabnXQSYefcup„‚b]jmdbfk’m`ff_hkurrp‹€t‚€xv€‹€x…w‡†wƒ„{†Œ{vŠjqc|b†|opltjholvw_qy{tut€‚¥•š­Ÿ§–…ƒ—•ƒŸuŠŸ“’…ŠšŒ•‹zrxt‚pr…squˆlomumˆwƒ}mnUQ«”‡‚x€vr‚y‚ ‘“’—›‘šx‘z‚Œ’¤š“Žˆ•˜’„†–™Œ“‹‰ˆž…Š|s‹…‰ˆœ™Ÿ›–”€”i†œˆh‡¡ˆ’„‘ƒ‰qƒ‘—šŒ‹w{’zŽ‹Œ‘–Œ|ˆ|€kvjmkklz~ay~Ž•vz€wƒ|ygtlt‡•‹ˆ†{”qz„pwŒzŠŒ{‰~ƒŒ‘Ÿ…|}x‚‹}vpik‚y_wnlkqrU]nbq`_mnypgpfgsuhpkawe]Vf``rSPN\fe]xpˆ|_]hrbbef’j_hd[gp~pkqsŠ}v|…€tuŒy{†xˆ‚s†„~ŒŒ„{y•wfrjƒ`‡~ookz`jntt_t}y†xts…|x ™°œ¥‚Šƒšˆ€‹žŠ™“Ž„ˆ—Ž„vtvs€po…spqƒojivm‚n}|musRN‚ßɒ֓|pt‚uƒ ‚’w”˜›˜{“r…Ÿ¡““Š’›”†~–•ˆˆ‘ˆœ€ŽxzŒ~ˆŒŠœ››•“ywh‰’‡l‰¤…“ˆ—ƒ†cŒ‘˜Ž”Š–ŒŠ‹q{”‰zˆŠ’‘‰y…{~l{erojkyy[€yŽ€z}~†Žzzhsks‹Š‚……}•Œl~o€ŒŒˆ}„z‚–š›‹|wxƒysmfpƒlitnghsmS^ndpY_kqwfkjbfxsopc_w``Vk_^vPNL`fc]yq‰t\[ev`aeeŽcafaXissnkqv‹|tz†uv~‹s†zˆ~r‰‡‘Šˆ|~˜vesn|e‡~npk€Zlnyys`vz{vrwŠwyŸ‹›®› ‚…wˆ•}‰œ‡…Ÿ‘Ž…Œ—„“Ž‡uwpyqn„omn~rddxp|mz}jhlc¤šÁÜ®ï¡skuƒu„¡…‘n•”Ÿ”›‘p…‹£—‰Ž•Š–ƒ€•…‰€’ŠŠ—‡{u‰x†„›š˜™Žv‹wo‡‰‹}‹¤…’‰……^‹”—ŠŽ‰Ž‹Š„‰l|–}ˆ…‰†v…}}k}dwujmxsWˆz‘†…z~€…Œ~yesjŠŽŠƒ‚Œ–…k‚unˆ‘‚‘…‚z€‘–”™ttxˆutqguy‚btmoahufR`pgkU_nty`rc_h}qrmZbrabWnY\wMMLcfa^vsŠm[\dy^`df„_cc^Xjrknkrw‹}sw„xw{‰qƒ„}~ˆ{t‹‰ˆ–†Œ~~˜shuqym‹zntpXqzvyqdwy†Œiv€‰rœ‡˜§œ£’„}pŒ”xy‹„…¡Ž|•Œšˆ„{rwpsjokil|t^`xv{pu{g`e|ëÚµÉÃ܈sls€v‰šˆi—Žœ”’ˆp…ˆ Ž„‹•Š˜”|“ˆƒ‰{‘‹†‚vxƒ„r‡‚’›–”˜†Œv‡q…‚‰‡™¢ƒ”Œžƒ‰aƒ•Ž†‰†‰‡€‡i}”}ƒ„‰Ž‚q†~qwhuriswkZŒ}’…|ƒ€„Š‚vbtlˆ‹‚~’‘}n‚ly††“„}}€’“‘—‰nrzŒ†ulqkrx€_tin\ju`RdqhfS_pvt`o`]h‚qriWghciXmW[uLJLef^brs…h[\ey^^dgzad_\YkneojtwŠ~ss~zvzˆs…ƒ|‡vwŠ†˜‚{“vlwuyy“tnxz}Xy…q€ogxw’‚dv†…qŠ–…™¡›¢Š†so’‹rwŽœ}Ššˆ‰{Ÿƒ™xqsnodr~hflww[_y{zqqiagaÕ¶Ž¦xnqw{p’Œ‡j˜ˆ›‘‹†{h‡‹™†’‘†‡˜|Š|Œ~Š…zu{‚zq†€•™Ž“”‚‰u„‡w„€‹“Ÿ†–Ÿ~ˆa“‡„ˆ„‰ƒg}~‚‹~m‚|‚tkmvtsvukcŽ…~|„„ˆp_sq…|‚|’‰zqƒfzƒŠ‡Œƒ|…~€•‘“„npyŒumnjkz}bhjiXkuZRiribPbrxlae]Zjƒmsb[g_dl_nTZoNHOfd\gnq€lZ[cr_\clwde]\Zllbmisv†qn||tx†x…‚|€‡uy‰’–|‰†v‰oxy{„“pm{w^ƒtmizs”sgrˆ}r’‘ƒšŸ› †‡vv”mv“—}‡ƒŠ™|‹šv}vqoljat|gbiuzZ_x|zmq~echhW^qr–¼Ãƒuq”ˆ~r–‹†›’Œ‡rjˆ–€{”Œ„›Œ|Š†}|‰Œ”ˆuŠ†vv}qu†ž”…”ƒƒr€ˆu…|‰˜˜‡”Ž€ˆf}“‚…ƒ‰‰r}g~‹{x~‡‹Ž|i€|ƒveoxxsvslj…ŠŠx€„ƒk^rxz~Š…{‚€~r€iyƒ‡‹†„y„|˜Œ}nm{‰}wtnhg|vc\qbWnrSSnshaMftxe`]\Xn€osYea^jm`pOYkQDSg`Zknm|nZ[^lcZbowdg\]`ljckisvƒpm~|tuƒ{ƒ‚|‚…v~‰–‘xƒŠtˆryx~oo|qiyz~ml|v•kjw„tl”…ž˜ ™…ˆn}Œvjx˜Ž~Š‚•—‰yŽ–ozspljd`t{h_eqzZar}ygqzaee±²wJbZ¤ÙЖq{Šw}”‹„™‘Œ…nk…’’zy’†„˜Š|‡xx‰Š„–€pŒˆqt}ziy…ƒ¥„“ƒoƒw„y…›™”‹“”…‡p{’‚}‚ƒ‰ƒnxh€„xrƒŠ†{e}~„ucprhxpou˜†‚Š{vx€„yk\q}rˆ…‰}†‰zˆrnq„‡Ž„…s„y™„xno~„€wzehj|p_YwZXplNWqsg`Jlvt`][[Yt}roWg]fjq_nNWhQ?Yf^ZokgyqZZYkeYcqy_h\^emhekhqw‡nk~€uo‚{€~ƒv…‰—Šq‚q{†|yy„“Œujzlo~t}or{{”onxf“Šƒ¡™œ’‚†g‡ƒohz•ˆ}„˜‰|Œixrklf_aoxm_box\dlƒzaqv_eeÔ꾊2:>‹Ž€qy…‡Žvƒ–Œ~’Œml…Œ‹u}…‚•‰|ƒxnv‡„ƒ—woˆ…ku{tfy‚ƒ§‹‚‹„}n€uwƒy†œŒ‘’Œ‹†~{’†w„ƒlrh€~xm|{Šƒway„qdqh~mtqt›‹€…~ru}€sp[m~txŠƒ‹{‡€|ˆxzqlˆƒ„‹r‚z€—‹‹tnkw€€uu\ihwpXV{SYodLZrre[Ipwn\ZZY]u~thYb[genciLWfQ=^e\]ue_tpZYTodYdqyZh^`gmgilipw}Žli‚„~yn€||‚zu‚“…p€‹nx~€{{ˆ’‰h{~kt{r†{sw}Œyx„}|kŒ„›–Œ€lŽ~kh~Œz~ƒ”~}Šˆkuqghc[bgrn`aksahp‰zbst^cd› n\5Y¯µti€ˆ|’†v…–…s‹‰vpm…‚†ty‰x‰|’ˆzsgv‰~~˜oq†~hvymeyˆ„¤‡€‡‰~n~v€|Œ™‡‚“˜‰‹„‰|ˆp{}„{h~lj€{zizv‡r`w~qdrfu‚mu{„”‘|nwy|tmXovtŒ‚†wˆv‚‰zxsn‰…s}“‰‰znnjn‚‚un]gfsqQZzMZo\N[rpdUKsxiWYYZaq€t`]]`fdhifNYhM@ad[`ua\tmXWStaZdorWj^bhkgmlipw|’li„‰||p~~{‚zw€Š‹ƒq{‡oqwƒ{‰ƒj~{nwywŠw}x€‚‡ƒ~~zm…Œˆ˜£„ƒ{u‹ykl„ˆx}{‘~Šƒprpcf^Yg_op``gpfjo‰tato[adjv{¾œ¦£È¸q…ƒs“|x†“‚sŒˆrrp„{‚su‡tˆw“ˆyyqcw‡z€“ir„vfwvcj|ƒ‡žŽ}rt…y€‘‚x–”ˆ‚ˆ{ˆ‰kxy~ugzhlysizv€‚}h`w‡}jktg{€iv€‹”~z~~p{v{t~bVw}rsŠ„‚|ƒq†Šwxppƒ‚}y~}vŽ†ƒviqimˆ‚rp]hcsnJduK]nUSYsnbQOsx`RXX\ao‚s[a\heecjdQZpIDcaZcp^]whUVUw^[enhVk^ajgeoohpvz’niˆŒy}r{~y‚|v}ƒˆ†ƒpwƒrnv‚ƒ}‰‹“p€|xyzŒtƒx‚„z€uo~Š‹›žˆ}…zw†{gt…‹z~{ˆ…„v€gon_d\XeYmr```plkh‰n`siY^dm€w©Ú©Ç†‡²q‰xoŒu{†Ž€z“‰€utu~woqm„t”†xtk`z‚yˆfqƒogvn[m}”€y‘’}y{m‡v€‹„t–Š‘Ž‡……{…ltvmgvem{umjvw|`bx…yhtub}{gt†ŽŒ•{tuq€z|mYVt~ou„‡€ylˆ†txkuƒ„}{}y{s‹}sgten‹„ms[j_udHnnLZaWVUxmbPRtvWPUX^aq„o\`cmdd^nbT\rGBf_]fh]ZzbQU\u[[gkaVj_`nffkqhpuxŽtkŽŒuvx}wƒ{s}ƒˆ‡ƒoqtqu~…‰Š{wxƒ||†‡x‡|}~„€{~svyŒŽ ‰z‰vtƒy^}…˜Œy†ƒt…†„w‰{bnl[b[[aVjsc`[gnof‡qaqfW\ck|Ê·¹¡jmmŠlq„q|ƒ‰~{‘…zysyuu{jluc„u‘‚wof^}‚z‹‰er‚kjqcXl{†›ˆ‚s—”w|mˆqŠ‹‡q—Žˆ…‹ƒ{y~qqp}fhqbmxqjkqw||y\dy€wiuxfvgt‡‹”|q†io~€yn|]Xrmt€‹|‚oo‰qvhwv}r{u‡|zrfsanŒ‚lrXk_w[InkMUT^TU{kaOTurPQTV^bt…i\`kjfcYnaXbpGAh\`f_]U{]OUdpZ[jh]Wh`_rfkhrgprw†xn•Štzx~xƒ‡ur†…‚pp{xwuz†…†Œ…z|u‹~}†„„‡~~}‡|xvyx‘“ Œ}‹mv€ycƒ†–…s‘Šo……zƒtcnjY_[]]Tgse`YdqrfsbkeW[`ix¾®{ ·mbs†hs{qy‚…{}Œwxrvo{vejn`‡uŽsjb^~xy‹„fq~hjkZVowŠ£„q™“qyt‚m€‚‘‡s•ˆŒˆ„‰…}xtrnhy`jm`mvjgjkywzw[g}|xer}m„teu…Œ…•o‹fkzƒumtb\o|ku|‹|fu‡}mqgu~x~r}l{{zxpflbn‰~mmVk`wUJjkOQNhMY|hbNUujLPTU^fuƒf]`phgaWi][khJEkZadWYUyYNVmjY]le\Zec^tfmdqgrouxp™…v~w|…‡}us‚ˆ€•‚nsxzzss…†ˆˆƒx}v|„ŠŽ„‚„{~‹ƒ{w|wwš—zŠ‚†iw}|lƒ„“r‚p…‚~oflgW][\[Tdpd_WbruiupeebW\\hpor€s‰ddx~ituss‚„x€„yvsunkzpagkg†tƒnf]_}p{‰~imwfidUVro¦|„{v–t|s|zm{{…v˜|‡†‚†ƒ|tprlgt\lh^ltdgfizo{rYg€vugp€wubw„Š|”€n‹jmzqfse`mzgswŠ|~buƒvikqtzpzys~f~ywndfbn†|mkVjbpSKhjOKNpG^{faMUtcJNSWajv~e\gsie`VcWbp]LKkXcbUUUsVLXudZ_ka\Zce_wfmbpisnrutšw€w~……z|u‚„~—…nrt|ztq„…€y‹ut‘|•Ž€…„}~Œ†{~€v{£¥Šyˆ†„ku|zuƒ‚‹yn…sy„}ƒunjheV][ZZSbnd[Xas{ihmi`bW_[j€iko€gkahyxjsttn„z}uunzhjyj_enhv„geXbwi~‡{oiogf]UXogŽ¨wz|Žyuo~oruy€w•t…‚…‡ujrvghn[ld]ms_gajxh{mZm‚rsio€~yw`w„„w„rˆqoy€rcqi\owdqtˆ|xbs€pgjxsrlxwuxdƒ{xvpdccn|}klUibfSKkgOGRkEaxgaMSq\JMTYekw{e^mqid]V`UnnWKShWf^XNUlTJ\y_[_k]][ce`zhlaoounoxuz˜}w€z€‡†zyzƒ~“„qttyvt…ˆ}€|ks•€{‚Ÿ…~‡}€†‚€Š{v„¬Ÿzˆˆƒkryu€€sn†n|s‰€jomddX_ZYZUbjg[Z^u‚i^ml\aV\\leqt}ii]kvvgtwrm…{}}yurlyhixf]dshzw’ccTepg‚…wwfhj`WVYgc§n~w€‹Žzpp|fxoz|vŽq„}~†ndvsdhh\kb]oo[g_mudzh]t€orkq{}uuat…Šz‡‡€wruuapmYqtbqr…|udrlalzoji{yvrf…v{zuqeaems~ilTi^]TKrbPFVaGbvgaKToWJLWXgkvzdenqfcZW]YveUJ\cWhXYIWeQHbxZ]_l[^\ad^ij`otxnonvƒ—yr€|ˆ‹†~uu†y‡Œ}suu‚yzz‚ŒŽ}~„‰is–zŠ}~…zz|†ˆsq®Œ{{‡}eq‡ys||uqn…l{~lzbpobe]eVYYVcfk`]\s…hXpnZ^WZ\l{bpvvlb[lssguupl„y~€ywnnteite[gufvv‘z_]Rffkƒ‚t}bci\TX]bc¥hxt‚…xmnygwm|…{uˆr€x|xhevm`f`^j_]skYe]oobze[w{knnowxstdrƒ’~‡‚ˆzvor}sbxd[opaqq‚|sfq€d^nvidgy{uno‚ut}sqb_fno}djShXYTMw_QJYXHbudaITmSJLZWilq{bllscaYY[av[SLc]XiSWHYaNGiuX^am[[_bb]…hhanxylojvxm‚~€’ˆ„vt‰tŒ†sqwu‚w|}~Œ€~“~pw•ƒ|™’y€€xy~tˆƒsp™¢{z‰”xduˆxsxuksn~ly|p‘r^po`gblT[ZWhcmf\\q‰eSrn[ZXX`lvciujj^Zmsqlsssj…|~|vnnldiqc[jrdtvŽs[WSear€r‚]bc]SZ`[c‘žerq…„‘tljzmop{||q€wrzyydeuh]bZ`g[^vhWb]phaw`[{vjirnwsrthp”‚†~„vrjp}mfwW\kmbqszsfo~[`oqb_jq~llu~sqxkpa\ellzagSgUWRPu[QOYRIctb`GUjPIPZUkkk|emoqa[ZXYlpWSOfWWiSTFZ\OHruX_cmcX``a]‹jcdmyxkoiuy†{kƒ}„™|‚„y}ˆn†qowz}t‚‚|‹ƒ‚—tw‚“…Ÿ‰u€€s‚q‡‚uo¢—t{†‹†{ewŠnn{ofwpzlsvrŒk^tnagekR][UgallZ\pŒdOon]VXUgjtgbtee]Yntnpuuyk‡||ˆvsddkna\nmcsx‡kZTVcdx}}q…\c_cTZ`Yc••cnpƒ…Šsjh{ofsws|lztuoy~u^frc[^VadYateU_`mdaq]]~phisqsptujm„“ˆ{…qrfn}proT[fjfqtwsblvUbqj[_of}fmw}sssjm`Zdjjw^fTdUVPTmWQVSPHds_aFXiNHWTVmhd|ikxkbW\U[tdSRWhQYfTSHZZPMxw[_eliYb`^^nbfkyunohvvlƒ}†—{ˆŠ~k“ˆrgt€{u€ƒ}ˆŽ‹“r|Š‘…‡Ÿ†{†Œs†s}ƒvn¥Œs‹vwmzŒ`d|pfxrylmqv‚gd{lcfghS_^Ug_lo[^nhNim`TVSogslfwde]Xptlrzwrmˆ{vœzykaelm^`ojepx~gZVX`lx|{pƒ_b^gVX_Wd›ˆbkq‡}wkkym\wqlzivsno{€rXjn_Y]UbcXdqbS^ahbblZ`~lfksunmwvkh…‹~ˆzˆmqep}mrmcYahiottr^ilReqdTbnbzcqw{vkpmk_Xaght\eVaVSNXeRO\OOHep]cFYiMI_KXmd_xhn~d`T^T]u\TS`fN]aTSJ\YPYuv]_fmhXca[^Žpcgjwqsngvtzƒr‚yˆ~|ŠˆŽznŠtls‚tˆ…†‘„•y~Œ‡‘›„€|Œ„r€stwqn““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~~~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’’’’’’’’’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’““““““““’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ>.1111/o‡„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDBN¥¯­­­®°knnnnqJ,00//,I…ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ-h…‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR455553A©¶´´´´·|ehgggk=;ƒ€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}z{z|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‘‰‡‡ˆˆˆ‡ŽŒ‡‡‡‡†‡‰’“’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†…………†‘‹ŠŠŠŠ‰Š†ƒƒƒ‚‚‚„ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z{|{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘“““““Ž‘’‘‰‡ŽŠ’“Š‘ŽŽŽ…Š‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŒ‹‹ŒŒŒŒŽŽŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…Ž‡Š‰‰Žˆ‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰†‹‰‰‹ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰Œ‰‰ˆŒ‰‡ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}|}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹Œ‹†‰Œˆ†ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz||||}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒ‰‹‹ŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzzz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{y{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz||||}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||~~~}}~~€€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†………………„„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰ŽŠ‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{}~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““”””””””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““”””••••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••””•“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””’’“““““’’“”““““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘’’““’““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~~~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’‘‘‘‘’’“’“’‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{}|}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡ƒ‹Šˆ‰‰†……„„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHIGGHGGLNIgsuxy}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzop{xy{|{xw{xuwttvtuvwuqrqnprpghklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkigfggghhgmgjghehgccbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsvyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__`c_\_]`]^Z^]YY^ba^^ZY_\XWSNMKKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{xvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSSPMJMNPROMPQQQQQVVQQQTPPNNOLJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTttuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMOPPRQPNNONONOOPQONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKLFDFJKKJHJLLLOMLLNOOOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEBA@@CCDEACEHKOKIIJHGJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AE@>:;>><ED=?EA?@A@DEGGGGBDDEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@;;><;;<<HL==AA?BC=ADDFCFFDGIHC?@?@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnpprttsqrvyy}}}~}~~~€~~€€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;:;;99:88;=;78;<>=;;:8:@@AB?A?CFDBCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqtsusqtxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<:79::97::@?8:9:;;8789;:8<;=@A@=;;><==@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyy{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>><==??>==ji>===<<<<;<:;<>=>??A@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLKIIIIKGMmpquutusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AB?=?BDD?>=>>@@<JxsL=CE??@=;===<;:=>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVpoqssttuyz{{|~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???CFEJ?<;RomgexsH8<9==@=:<;;<;89;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIGHHHJIJKJJNLII_pqrrrtuvz{}}|~~~~~~~~€€€€€€€€€€€€€€€vMNNMNNLLNPNL>A<<=?>BC??AAAB@Mzc=W…††‚yrF888:;=??<;;<;::;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHJJJLJFFgpoqqtvuw{|}}|~~}}}~~~€~~€€€€€€€€€€€€€€€{NIKKLLLEILNM<?<<=>@@AA;BCBC?Vw{g}ƒ‚ƒ~‚~vG==?>=>CD?;<=>?==>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hlopoqtuvy|||||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABECE@Wut}‚ƒy…rD@@C@@?@@>=<=AEABBFHC=<@DCAA?>=@A>>>?<>@DGE@>@A?@CFECBCC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{{|}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@Ntr~}x‚…ƒ†_=CCE@??Na_J@CEIIIIMMKECFGHEGEEEDDCA?@>>BFJJGEEGFFJNNKJIGGHKMJGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@EEfw€„…‡†ˆ„KCEDCWu†‰Š~XGHJLLNOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHFHIHGFEFFFDFHGEEHHFHGHFQnnpqrvvy{{{z}}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJGXs„……ƒ…ˆˆe?AVt‡‰‡‡†‡‚WILMLMMLJGGGGDGGGGFHFHECDDFEDDHHCCCGJJKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrswwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLLJX‚…†„‚†ˆŠ|Tl…‡†††‡‡‡‡|PKLKHGFFDECC@ACCCCFFEB@>>@AA@BD?>?DFHDEGIKIIGHIGIIJJIHFJJJJIJIJJJFILLJJKKfopsstvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKLLJc†††ƒƒ‚„„ƒƒ……„„…††‡‡†ŠuIIFB??@???<<<>::<AA@><998<<=;>;9;?ABAACCC@ABDDBCFHIHHHLMLGIJMMNMJJKKJLMSloqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHHJJJl‡†„ƒ†€‚ƒƒ„……†‡ˆˆˆ‰‰ŒŽfBB=88::9878896479;<:8567789787689;;<>@;999==><<=ADEHJMLLGIHORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@CGIIh†ƒ€ƒ„„„ƒƒ„†‰Š‹‹‹Š‰Š‹Œ‰T:8656766645763468:876565676778:77789;7589989876:<@GFIFIFEFOSRSSROPPRTepqsttwy{{{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:=ECEr…€€‚ƒƒ„ƒƒ…‰ŠŠ‰‰ŠŠŠŠ‹‰‰ŠH676468874578467699766765:9:::<898977779:98878589;A=>>BA?AKLOQPQOOPRWkqrttuwy{{{|}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897;B9F€„€ƒ„…„„„„†‰ŠŠˆ‡‡ˆ‰ŠŠŒŠ‰‰Œz>988;<=>9:;<89;9:;:99;:9===?;;;=:>;9;;<;<;9:<8::;:999<?<=ABDIJMKJKLWorsutvx{{{|{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<;89989:::;?=T…ƒ‚ƒ…†……†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>BCEEAAAB>@B@@?=>>@?>?@?@==?B?AA?A?=@@@??A=><;:;:9;?=;;==AACABCAXqqtttvy{{|}{}~~}}}~~~~~~€€€€€€€€€€~REBAGJNOLIGK:8:;9::<=:;;==?@B]‡ƒƒ…†……„†‰‰ˆˆ†††‡ˆ‰Š‹‹ŠŠŠ‹Š‹^>DGIKJIFGGDFHGEC@@CECB@BCB?@DHECEDEEAFEFEFFD@B?=@>=?@>???>?>>:;=<`qrttuwzz{}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>???=A@DDEa‡ƒƒ……†††ˆ‰‰ˆ‡†††‡‰ŠŠ‹ŒŒŒ‹ŠŠˆWHLMMKNJIKHIJJIECDFGFDCEFDBHIKHGGFGGEKIKIJKJCFCCDBAACBDCCDDCA=;=@hpsttwwzx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLK@BBA98<>;<;>@?A?BCHHJ_…‚ƒ……‡‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹‹ŠŒPMPMKNKJLIIIHJFDGHHIEEHFFELLMIJGGHIJOMNLLMKHFGGEECFFFFDEHHFCA?@Llptuvxyyy|||}}~~~}}}}~~~~~€€€€€€€€€€€€QA?>?FGG=<@@88<;<=:?@>@@CFJJPgƒƒ…„…†‡‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒ‹ŠqMQOMLLKLJHGEJHDJHGKJHJGGGKLNLLHHIJMPNPNMOKIGIJHIDIHHFFGGIFCBACUnquvwy{xyzz||}~~~~}~}~~~~~€€€€€€€€€€€€€€TDAABGGB?8?@8:<8=>;=A>?@EIKMVsƒƒ„„……†‡ˆˆˆˆˆ‡†ˆˆˆˆˆ‰ŒŒ‹ŒŒ‹‹‹‹‹^QQPMNMKJGFCGJGLJFKOLKJJMMLOPNHIKLOQPPQOOJIJJLJLFGHGFGIFEEB@BB\orwxyzyyyzz{|~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<9@>>@BGGAHLMQWy…ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹‹ŒŒŒŒ‹‹|WURRTROLKJEEFKONOWVQPOQSRMSTOMSLPSUWRSQPLKMMMKNGGJFFHJDDEEBDCcpuyyzzz{z{z{|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?==B?BCFVNFOQQUY|†ƒ……„„‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŽ‹‹‹gVVkaERQQPJ;:QSR`u]UVTVYYRXXRZfPUWZ]RTWQPNRPPPQKLKGHIHEFIHIHIjrvyyzyz{{|z{|}|}€~}}}}}}~€€€€€€€€€€~~THJIIGGFE??AAEBCGEDELXRMTVVX[|†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ}aŠ‹‹‡l[dU:XXXSP>@VUY\d`VYbr^]V]ZVEQYZ[Y_TYgRUVXUTVTOOMJLJIILMKOMSosvxyxwyyz{z{|}|~~}~}}}~}~€€€€€€€€€€~~~VJJIHGFDDBA?HMIMPKIKPTSSXZZ\\x…„…………†‡‡‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~Œ‰Š‹ynpXZ[ZRSRVVTZZuƒYU}a\X]^WIV]][[_YHYXY\]YXYWRQMPQMMOSQQURassvwwvxxxz{{|}}}~}~}}}~~€€€€€€€€€€€€xy}YNKIIIFBD@A:PQQWXPPOQSTTXXYZ[n‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡ƒŠ~fYY\XSVTWRQWVc–€QerXZW_hP`fZ[X\hbGOZig\[\]]WSNSPPQVVVVYZnrtwvvtwxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZ[RSQORRRUSVTW_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PVXTRTRQQLOMKfyZ]TYUV]ZLTZUST^ZXWWWzkXZ\\^SPPPINOWVXZZdqsvvttvxyy{{||}}~}}}~}}~€€€~~zxwvsu{€€tk~~kqy^[VUSROKFCDAM^ƒlVRSNOQOQURSRRTcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ymqVIKNNKMKHJDFHEC>ScURPQMKRTRMOYQMNQSUUMQSRPNLLHCIHRTUZ\mrvvussw{zz{{}{}}}~}}}~}~€€€}}~~€~{vsw}~~du}iqt_d]^[YVQLILIal’tPQSNQRQR[RSRQRUUbs{|€‚}{{€ƒ‚…†‡‚†††„†…†u_]KC>CCCCB?DPBD@C>BHGV@HNMG]iPHFOFDEFHGHBCHGHJGCBAD@OPMRdsuvustuz|z{{{||}|{~}}}~~€€€||}€€€}vt{mh|gnqfieeb\XSQPURsWe[OONLQSQUYSUQQTROV`klrv{{xytrnstsyx~~ƒ€ƒƒ‚€‚€‚kLG>>:;>@@??>kPKaEFHIEB?GLNGMQUIBE?><=<==?=?ACB?><=B>JMFUnuuustvx{|z}||}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljjf`[QRZ\Y^IJPQNKLQRQTVTWQQWVPX[b]agmmlokh`nrjmlqu{z}zxz||xwxdB@@A=:BCAADB[\O{NOONKLMOOQLKLWMHG@A<977599=;;;8989?;AH?\tuuvuvwy|||}||}}}~|~}}}~}xuwz{zwyxuw{|yxuywcqhipmnmmhf^OP^\ZIGPRQOMPQNQRTVXSRYTNYZ[WY]^^`e`]^qvk^`gkwooljonnlfbYGFFHBAFIEEFDLQOaWRXQPSSRU[OOQVPMJCF>:96486979:366796<B=ftuvwwyy{}}||{|}}~~{~~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZWMLTTSQQUOLRSTWXTTXRLXYZVXXVXY]WWXhsk]Vaskaa_]d`_^YUPMONLIHJKIHFCPOSZWTTMQSYS\eUOSTRNKIHC?A9988978847578589Gnsuxxz{{}~}}|{}|~~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPXVVSTVOOUVXXYSUTLKTUUUUWPTUWTUR]n^RNY_[VY;DUWT[fJLPRROMMNNNLJFPPUYSTNJNOUST\VRUSRNMLIHHF??=:787659967665Wqqtwyz{|}}}~|}}|~}}y}}|~~~}||}}~}|rvqxxruuqqnppopuvtnjddjppqrpofedc\^RTZVWUTWTRXXYYYRUOJHOPOOMRJOPPPNNOTLMIPOSTU2<XMIAQ=c`QSQPNPQPNNMPNTRPRMILKOQPQRSTQROLMKLLHCBA=:9876;B4566;eprvxy{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqptuvcjgeWhtrrqniihpVVTUXUWURWVUZYXWUQSFEBFGGHFJDHJHGEHLHKIGLMPMG/E_R>3@>joaRRQ@FTQPQPQNQOPOLJLLOPNNPQQNQOJLMMKGEEDB;==<9=G6677Dnquwz|{||}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknbePSTRSUOWVVYYVQQQO@>;=?@BAC@BEDA@GHGHFFHJMLEGCORC8ENS]gSQSAGUPOQQPMMNLJLKLNOOQMONMIMLIKLLKGFFED<AA>;@E;<89Tqruy{{{}||{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpknqmimcLONMQSLTUTWWULLKH=987;?A?<=A@B=>EHGDFFIGKJ@FAA@FHEJOHQRa\QPRNSOOOLLOMKMLMON[WKMQOHJHCIKMLJFFFE?BC><BF?B?Adqux{z{{|{zzw|wy}~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCE=9879?B>;>A@@>ADIECHGIGIEBB?><CAAGIDMOaeQMONWKLMKLMMLLKNNSdMJLRIIIEAHKMMNKGIFBAB@?EFEHDKopwzyy{{z{zwtxux||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGLMIMPMPOHKE?B=999:?B?<ABBADDGKFDIIGGHCC?B??@A>CECKNQTLJIMTFIIJLJKKIILMOPRPKGCKGCBJJLMONIJIGCCCDIJMLIZsmxyxz{{y|vrpurtyyvxjqokllnttmsu{stxronqovsnporpopstyjN`gsjt|ygosqjqheqHKCFHHGJKIJKDGB=>=:::;AB?=BCCCHFJLJEIIFGGCC;A@B>@@CECIMPGHKFHKDHIKMHJLHHJLKM]RIHDMFBEKKNMPNKMJKFGGJMNQNLcniwvw{x{z}qmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoijthdoFKCFEGDEEFEGBC@><=:;::@D@>BCEEIFJJLFIIGFFCB;BCC>?CCCEGLNHKNHDHEIMNMGILGEFIILNKJHENHCGMLNMPMNNMLIHJORQRNRfgfrosxu{z|lhjoekpmsqfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGICEFEBCBE@DB>?>:;;=:=?CA?ACFGJGIILHGGGFEC@=EEB>ACCCEGHIGMPIFFGKNOKFHIFEDDIIHKIGHPKDJMLPNPNOONJJIMRUTROWdaamgprosyzgehhcilgqlflmgiklslpvutpnvrosrsutqssutsuvvvyvutvlkuumrvqlnlerMGEEGCBABD=BA>A=::=?:>?@B?@BEGJFJGIHFFGECBAAFFCBBBDEDGGHFLQLIOJJLKIGHEFEDCIHHKJHKRMCOONQPPONOOLKKPUWVUSX`^]iaminhrsbeffdihfnifmmhkkmriqvusqmvnoqrswsrstuvvvvwvwvvtwuksunutsqrkksMFFEHBBADD<AA@C<89=>:?<?B?@@DFHEHFFGFEEDCECDIFCFEBEGEEFGEJMKHQMJKHHIEFIHECIIJKMKPSNDQSQQROPMNPMLNSWVWXVX^[]d`hbjigk_eegcgggkggkmkmlpqgttursnvoqprtxqssuvu‚‘yvvtxuuwxnouorsuqqipzMHGGHBBBFE<@CBD<7:=>;>:@B>??CEFDFDDGECECDEFGJEEIGCGHFHFECFJJGMJLKIJLFIHKHEKKLMNOSTOISUTQTPQMNQNMQWZVZYVZ^ZXa```^hec`dehgjhhjfhnllnmqpiuuxrrpupppruvpusuvu{~}xvtwvvvxplupmsunossyNIHGIDACHE<@ECE=8:>>>==AB=?>ABFCEBCGDCEEFGGGIFHJHCHHGIGFDHKIGKHMKJKLHLJMKINLONORUVOKUVTQTQRLOQPOTYZY\ZY\__^`c]\ackb`dghr…hgifjmnponsqjtuxrsstrnpqvrquruus~yŽ}uuvvvvxrhuqkrtlqwquMIKHJEBEGE<@GDD@9<>@@??BB<@>AAFCEDCHDFDGEHHFHGIKJFJHHKHFFLHHHJGLLLLLIMKMNMOLPPQUVWOKVVUSSRQLORRQV[[]^[\^`_a`bd]d`ef`ehjcssfjhglprqossnswwquvtsmoruorspurvrtvuuuwvuwtgtrkqrkrwovJKLJLGBEDE<@FDDB;??AAA@DA@B?ACHBEDFGEIEFDIHFIHJLHHJJILJFJKHIJJGKKMMJJMLNONOLOPRUXVMNTVUSRQPLNTSRW[^^_]]``aaa`bdebcibdijgv‹lkigmosqpqpprywruutsmmssmqrotutspsvtuuwvuuueqskpqjrvowJMLLMGDCAD<?EEEC=AACBACEACDAAEGCHGHGEJFCGJGGJFILHIJMJMLGKIHLKNQKRQLSMKNNOPPPTOWXX[NSQW\ZSVPNTUTTXZ_bb_da_`b_`eaacinhbihhmxvlhimosrpqrrrvtsusssnksqmprotvrrquvuswywutucmtkopjqtpwLMLKLGDA@D>>DEFC@CAEDDFCBEGCBIFCHJJHIKFDKJGHIIIKGJJOKNLILHJMKZfJd\KlRHON_nUls[qpbwcRPbvuhucav`Xnqbdvinzf\lt`ljT_wvijgifglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqsqyKNJKJFB?@B?=DEFDCCBEEEFBFFGCDJEEJLLJLMGGMJHJJHKJIKJNLMMLLILML[sbdp^llUMNfs]geqlntgpi_aYnnbppbkjjgoqtetno\pugpMJryvkb`keemxmkvlnpsrprqpqrqrrrtrmmsnnoprutqsstuuutwxvttbmukpplrrqzKLIIGED@AB?=BFGBFCEDEEDCHHGDEKGGLMMJMMFJNHIKJILJJJKMMNNMMKNMM[roonpplkNPQlWNibtrpamov\YlQ\mmZqmkomxxtsip\`slqjUuyxpc^kfbgppjioppsspqpqqrrqqrrtlmrmmnorutqtrtuutuuzvutenukpolsrryJKGHEEEBBB=?@FGBGDIEEDBFIHHEGKJGMMNKMNHLNILKIJMIKIJKOPONMLNML\hdu]lqWlNOQmUZk^klvaldtTecNmYl\tpkilxjwuhp]_skhWbcw|oc`ghadityknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtwIMGIDEDCAB<B@BFDGFLHECCHKHHFJLLFMKLRRLGMMHNJIHNHJJIHNOMNLJNMJZsppoqqmlOQRnYqkgooqqomt^nXat_nopoqronusttj[]tcwxrjnzhaacgbbjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyytukoumtonssvtHKHIBEEEA@>CCBGCHIMIFCFJLIGFJMLFNJKWRKGKJJNIHJLIKJIHJLMMMIKKKSkbZi^_jcrrZ_Yjo_eeUk_c[abQ`mh]j\niid[pfdp]Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunvqrutwsHHFIDEDFA@AEDDGBHJLHFDGKLIEFJOLIOIL[QJFHHKMIHJJKKIHIGKKKKFHJJLLLKIKLNT[\TPTMPONOOVQOOQOOQJJOPQdqiTYW[[\UY[]X]\\cfaafbce__fkmhmtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyxxuvqruovrtsuusGCEGFFAEC?CGDEGCIKLHFDGKLHDGIPKLOKLWMIEEHIJHIKILJHFHGJGGIEFLHIKNLIO\W^O\[`^OXYS\\b^MYZMXaRKYaZS`d]bX[ddVVX\YZX\VY\^c_d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtOBCDLMACDBDIEGGFKJKHEEJJJFEHHPJLMJMSIHEAHFJIKKILJIFEJHEFGEEJGCJMJKT_Y`X`a[`UXYT^^Z_RY\P^\YN_\^S[^c_Z]`c`Y_b[`^[TXXZ_^dbbaceiekrpoppnow††……†‚{€……††…†…uqprrsvyyzyyxxxwryvxrqxvtvaSJJMIDBBCFGEGGIJJIIDFKKKEFHINJNLHLNGHF>GGLIKKJKKIGEIEDDEAFJD@JKIO[cY^^a_RTSW_`\]Y^QY\MV_WKQY[Q[_aa]^ca`bbbcceZRYVU\[^c`__cebhommllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxXQJFCGEBEGHFGHIFGJGHFHKILDCKKNMLLHJJHJG?GFNJKKLKKKIGHDD@DAHIA?IJGO]aZ[d]_TQRW]\\\_ZKW\LR\YIM^PP]_accccb\dcbdcfXQUTS\X[a_^^aa_dlkmjjlnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMB@IFCFKIFFFHGGJFFFILJNECKJLNJLIKJHIGBHHQMKKOLKKIHGED?DBHHAAGFDT]Y^X_Y_[]UXXP]]QKJW^X^[]VZ`RQ__bb``bb`cbbddbXOQQR[S\^]]]___dhgljnnp{{|~{€‚ƒ„………………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKBAGFDGMRHCQJFHHHEFKJMPEGIJKNLLILKIIGDHKQOMLPLMKKHICE@DCHGBAFEBVUE\T^SV_XNTUNZ[MJKU`a[_X_^a]OYb\``_bcb]bbW__TPOPQXR]\[\^_`affelfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDFFGDIRcPDV^IGGHDFMJPPFJIJKNLKKLKJJGEJMQQNOPMNLNHKAD@BCFDCADEALHCLLPOOLFMFGIJHGLLMOQILOPPSPLQSRUZYWYXXdVOSTPPONPUT\YYZ^^aaefchdklpsszy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKM^LGGXMHHJHGNLQQILKKKNNUNOKKLGGKPSSNPONONOHKE`DC_LDfcDM[H^\smOMVmYLCP`UlWgJ]XV^DLQULMTVQRTXWTXUT\TPfZhhdYTkTWVU[\\``abbb`fhfnlhrz|}~„„„ƒƒƒƒ}|zr{z{‚€ƒ„„……„…ƒƒ~z{LIEFFHEEKOTIKGaTHJOJIOMRQKMKLORUROOJLNGHMQ[YOPPNOPOIJPQI|YYrsXPmHqnoaVPqqsPBksmqspSo_[nX]V\XUkhU]VcZ`YZ_VUWjtuu_av_Xb\\f[_aaab^`bgmpl`pwtx‚ƒ„‚}~€vxzlv~tx~€|~€‚„|€ƒz~wwNIEHMMBDLLGILFRVLKOIKRXWQNOOLQTNOQPKLOGMPRZZTQQOPPPJHZx]TxdhYRTQvgtlpbnfkQrOMwmjrpsrqrpop€]ezuxqqzq~s}ku}bRh|essoss|}o~yor```bbZa`gknkblfgmw~€ƒ~{xw€tvzir~nt|~wx{~€ƒx|u|||ssNKF`]GAEMMHKKHJPOMMJNV^YULQSNYYLSSRNLPIQRTYWWPTPPPQKGfxlcxqmZJLUypumubnvPdeIfvqmwo€jfxxiWrQhzmijzz}lxzpgoXvvjvup€ash}ilx|o___cb[^cdgijdgbcdllppstsssyqrxblugry{ssuy~svzn|}yxrnNJStNDBEPPIKKJLPOOOMPZ`ZXKTWPa^RVQYSMPISTUXWWPUPONRJKrouuquqdhaVnLqp^FhyWvTLhx}x`y{sna^modRgrunmypwlvstqlm\s~zkmy|lum|kpvux^__b^]_edighee^bbiiijknokqnmjpacfdowxompsy~nqpj{ztromKK[VHGEGRPJLMKLQQPPPQW\YUNVYUfXRRY^TMNITTVWYWOSNNNQHRmHiwK`dvvUWlOnl{sajgvUKWkh}lmlx`[pz{^`zscroxqhd|ir{]TKl_vukiu{{m~xk|p]^^b[^bdegeeebZccikkrsrwgmihdg`alagsrkhmmr|kmhk{tmmkmOGJKHJHHRQLNPMLTSROSSWRVTPWZVVTTTa`QONKTSSQUVNNLMOPJHQNPULKKSTSRTPVUQQNQQXXQOPUTXXX[[USSW[WXWZOSUWWXQ]XV]USOXRWWWXZ`[gr^[\[]]_cZ_ccefdccbYccfffmnmuffgc`f_]g`dlhfgkhpzhggkujhgilQIKKLMKJTRMQQPLVVTPTUXUYURZ]VUTWUYXPOLNWTQNUSNPMLQPKJQRKQMKKORTRQQSSIHMNOQRQQQTVRXW\WSSQRUUVSZQNSRXUTYVTYUSRUSTUXYW^Z_a]\[Z\\`c\]bcdgeddaY`acabihincad^_c]Zd\bma^ffgmsdihkkeddfhPJKLOOLMTQOTQQMXWUTUWWWZVT\`VWVYUXTQPKOXSPNUPNQNKSPMOUTNQNMNQSPTQSTUNKMOQTTRRQVWUYZ[YSURTWWWY[TOTUXUTYUWYTRRWUUW\Y[`^VY_]^]\]aa^[bbchfedbX``b]`hefda^_]]^ZZ_Z_g`^]]chkagfhfd`bcaPKMLPQLOTPPSQOQZYXWXZZXXV]jdVXYZWVTTOKOVTPOTPPQNMQQPRXTRQOMOSUNWRTUUONNQSUUTTRTXVZ]\ZVVQRWXV[[WQTVVUVYTWWTRRXVUZ_Z^`_V^]^`\\``__ZbbdhhedbYb`b^_fdd`b]\\\\YZ[X[a[^]\_b__bddbd__`\PMNNRQMRSPSTQOU\ZZW[[\YZ[dqmhd_[YVVXRMMVSMNROQROLPSRUZUTPPLPWVQWSSSXMOPRTXUUUSUYX[^][[VROUWV[\WQTWUWXVTXZTSQYWV\^[__`Ua\`a]`b_\`]cacgidf`Zc`a__ee_`c[Z\[\YZYYW\Y\[`^_[^^a`_b\Y`ZQNONVQPUSPUTSPW\\\X^\_W\^jqwy€c\[VVXRNOWSNQQPRTRLQTSYZWUORNSXVTSTRRZOQSSV[VVWTVZX]^\\^VSNTVV\\VRTVVXYSTY\TRR\XZ]^]aa`Wb[cb^ac_\bab_dgidf^[d`a`ace_b_YZ^[\[YXYWWZZZa\][]\\Z]`W[[ZPOOOYPUUSRWRTP[]^][`\`U\]ijr}slg\UYWQOR[SRQTRTUTKRVU[YZSOSRVVUSOVRSZRTUTX\WXXSX\X^]Y[^UUNVWW^[XQUUXXXUWY[TSV]Y]]a^cc^Y`[eb_dd^^cca]efidf^^da`abcd_b^XZ_[\[XXXXW[Z\`][[\[XY[^V^Y]POORZPZUUWVSTT^^`^^b\`U]^bkytl}lZUZUQQS\TUTUTVYWLRZV][\ROUSXVVSPXRSWSWVV[]X[YUZ^X_^Y\ZRWRYXY_ZYSTVZYZVXY\VUZ]\^`a_ed]^]]eabfd^_dc`\gdhedb_da_a`bb_`^WX^Z\\ZYZXV]Z]^[Z[\[WY\]VXW]SOPWYQ]UVYWWUX_`aa`c]`U]^beeuzhXYZTVSV\WWWVVW]XPU\Y^]]TSXRXVSRTXRSVSYXX]^X][U^_X__X\VRYTYZZ`X[TVX[ZZXYZZXV]^_^cbaee]b\`fbdfd_`dbb[fchecfaf__aaaa`_^VU]Z[\[Y\YY][[[XXY[YZZ]_]TY]UNTZVS\TVWYWV\`abcad__V[`da_zuohY\ZVXUW[ZY\YXY`WPU^[`a\TUXPUVUSVVRSUW[Z\_^Z_\V__Z]^Y^VSYWYZ]bY]UV[\[\[[Y[YY^_``dbceebdZbfcgfe^ac`c^cciddg_g^bbcaa`^_XTZZZ[[X[XX\[Z[WWZXW\[\`]V]]SPVZVVZUYUXWX]_badada^YYadb`lfh^\][WXXY\\\_[Y[bVTW^]ac\SVYPVVVVVVTVTX\\_``]`]W`^[^\[^XVXX[[__[^WX]\]^^\Z\X[_a^`dcdfffbYceehgd^ca`ec]fidei_f^cbcaa`__[XY[YZZXYXW[[Z[WXZTY]\Z`\U^bMRWYVWZY[\YWY^`badada]^Yacb_a`a_\\]XW[[]]__\Z]cXYX]`cd_RXYPXWXXXWVWV]]^`aa_b^Ya]]^Y]^YXVW[\`_]_YY^]^^a][ZY\_a_bddefggbZdfgigc_c^afeZhicfice^bbca``_]]ZW[YYXXZYWZ[ZYWXVU[]]]``bbxKWW\XW]\\]ZW\]_`bdbba]`Xbcb`cab^\\\XW[]_]`_][`d\\XZcecaR\YOXWY[ZYXZY`]`bb`ac_\b]_][_^ZYUX]]_`__[Z^^`bc\[W[]`bbcedgfegd\efhifcab\cg`\iibhife`baca_`_]]\Y\YXWXYYW\[ZWWXOXZ]acffrkJYW]ZZ_]\^\X]\^_acbaa]b[bda_ccb]\[ZWXjq`\`_]\ac_^YYcedaT_ZQYW\]\[Z[[c`cbc`bda`c^`\^^_ZXV[_]\aa_][`abeb_]S\_`cddfegfefe^efhhgdd`[fg^ahhbhhfc`b`cb___]][Z[YXXXVZV\ZZVVULXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡…‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vvvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{{{{{zzz{{{{{{z{{{{{{{||||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vvuvvvvuvvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{{{{{{{zzz{zzzz{z{{{{{||||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||vˆ‹‹‹‹‹‹}}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰ˆ±µ´´´³³»¾¾¾¾¾Á¡ŠŒŒŒŒ‰~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}vŒƒ~~†“y1333332j‚€€€{­éääääèʉŒŒŒŒ‹‘»À¿ÀÀ¿¿ÉÌÌÌÌÌϪ’‹}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„ƒ‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}vxxxxxxxwwwwwwwxyyyzzzwopppppprrrrrrrwzyyzzz~ƒƒƒƒƒ„||||||}€€€‚ƒƒƒƒƒ|||}}}}|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚‚‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vvvuuuyvvvz{x{xwvx{wzyz~|yyxxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{zzzzzyzyyyyzzz{|{{||{|||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwwy|z|{y|{xwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwww|{y{x|zxxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z|ywwwz{y{w|yxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚ƒ‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzzz}{y|x|xxxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyy{xyyyyxxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyyyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒƒ‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{{||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}||}}|||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}|}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrrqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrstuttssrrsrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqstsssrqqppnnnmmmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqqrssssqpqpoonnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrqrrssrrqppoopoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpppqrrqqqpopooppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqpqqqqqqpooppppppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqqqqqpppppppppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsquŒ‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqqqpqqqqpqpqpqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrqqqqqrqqqrrqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrssrrrrrstrrsrsssssssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~€~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz|~~|vvwwvuxzxxxxwwwvx|yy|zyy|{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~|{{z{|{}|{{{{{{zyxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|~}{|}}}|||~|}~~~~~}}||}ƒ€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š††ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€€€€€€‚€€~~~~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~~€€€€~~~~}~~~~€‚‚ƒ‚‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽŒ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~~~~€~~~~}~~~~~€€€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’’‹Š‹‹‹‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚ƒ‚€€€€€€€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒŽ‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒ„‚„„‚ƒ‚‡ƒ‚‚€‚‚‚‚ƒ‚‚ƒ‚ƒ‚ƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒƒƒ€ƒ‚„………††‡†…††‡‡‡†††‡‡†…„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠˆ‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„ƒƒ‚ƒ…„‚‚„…‡‡‡‡††‡‡‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ’‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„ƒƒƒƒƒ„…„„……„ƒ‚„……‚„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘’’ŽŽ‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€†‚‚‚‚‚‚‚‚ƒ€€€€€€€€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„„„„…„…†’“‘ŽŽŽŽ‰ˆ‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~€‚‚‚‚›…€€€€~€‚€‚ƒƒ€€€€€€€‚ƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“‘Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€‚ƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚‚ƒ„‚€…–›ˆ„‚„‚€‚‚‚‚„‚‚ƒ‚‚‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘‘ŽŒ‡…„ƒƒ‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒ„„ƒ€‚ƒŠˆ†€}}}{—œ‰ƒ…„„„‚€‚ƒ‚‚„„ƒ‚‚„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†……„„…„„„ƒ„ƒƒ„‘”“’’ŒŒŠ…„„ƒƒ‚‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~€†™†}~~~‡~œ…‚€‚‚€‚‚‚‚‚‚ƒƒ‚‚‚ƒ…ƒƒƒƒƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……„……„ƒƒƒƒ„ƒ‚†””’”’‹‡„„ƒƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~~~†ž†€‰€‡€Œ‚ƒ€€‚„ƒ‚‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚‚ƒ‚ƒ‚‹”“’“‘Š†ƒƒƒ„‚‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€ƒš¡ˆ…‰ƒƒ€}„ƒ„ƒƒƒƒ‚€€€‚‚ƒƒ‚‚ƒƒƒƒ‚ƒƒ„‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„„ƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†„…ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„„‚‚„‡~~}}„……„…„}}}‚„ƒƒƒƒƒ„ƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„……………„…†…††…………………………††…†††…†††‡†…………ƒ„„„‡““’‘’ŒŠˆ…………‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…ƒ†Œ‚€€…€}}{‚‡†ƒ€~~~ƒ„ƒƒ„„„„„„„„„„„„………„…„†……†…†††…†……‡……†…††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„ƒƒ‚€„„}}€†€€~€„…„…†††…………††‡††…†……†‡‡‡ˆ‡‡‡†††‡‡‡††††‡††…„ƒ„……†„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘“’‘‹ˆˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒ„„„ƒ€€…„ƒƒ€€€€€€€……†‡ˆˆ‡‡‡‡ˆ‡ˆ‡ˆˆˆ††‡ˆˆ‰‰‰ˆ‡†‡‡‡‰ˆ†‡†‡‡††…„ƒ„…†…………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†…†„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡†…ƒƒ…„„ƒ€ƒ…ƒ‚‚‚‚‚€€~{z€†ˆˆŠŠ‰‰ˆˆ‰‰‰‰Š‹Šˆˆˆ‰‰‹‹ŠŠˆˆ‡ˆˆˆ‡‡ˆˆ‡ˆ†‡†„ƒƒ…‡‡‡†……„„ƒ……„……†„„„………†…†…ƒ‰”“‘ŽŠ†…†…ƒ‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡†„„…„ƒƒƒ‚ƒ„„„‚‚‚‚‚‚‚€~|}}}~|{|ƒ‡‰‹‹ŠŠŠˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰‡†††‡…†ˆˆ‰ˆ‡†‡„ƒ‚„ˆˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚‚ƒ‚„ƒ„ƒŽ“’‹ˆ…„†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„…„ƒƒ…ƒƒ„ƒ‚‚‚ƒ~}}~~~~~}|~}}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡‡‰‡ˆ†ˆ‡†‰ˆƒƒ„ƒ…„„……†ˆ‡†…ƒ‚‚ƒ…‡†‡††ƒ‚‚ƒ„‚ƒƒ…‚ƒƒ„ƒ„‘’‘ŽŽ‹‡„††„‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…‡ˆ‹Š†„†„‚†…€‚„ƒƒƒƒƒ‚‚}|}€~~~}|}}|z|„†‡†„ƒƒƒ„………ƒƒ…„„„„„„…„‚‚ƒ‚„„‚ƒƒ…†…„‚‚‚ƒƒ…ƒ„„…„„†ƒƒ„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰†„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€€€ƒƒƒƒƒ‚‚}}€€}~~}|}}zzz~ƒ„„‚€‚‚~‚ƒ€‚‚‚‚ƒ„€€€ƒ‚€€€€€‚‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†‹“‘Ž‹ˆ……ƒ‚„‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€€ƒ‚~~~~~€‚ƒƒ‚ƒƒƒ‚}}~~€€€~}}}}~}|zzz‚‚€~€~}€€€€€€~}}€~€€€€€€€€‚€€‚‚€‚„ƒ†’ŽŠ‡‡†ƒƒ‚‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒ‚ƒ„…€€|}}~}~~€€}~}~€ƒƒƒ‚‚}}~€€€~}}}|{{{zzzz€€~~~~}~~€~€€~}~~}|~€~~€€€~€€~€€…’’Ž‹‹‡‰…„ƒ‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~~}~€€~€„ƒ‚€~}~~€€€~}}}|{{|zzyyy{~~}~~€€~€€‚€|~~~~}|€~€~~€€~€~~~~~}||}…“’ŽŒ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒƒ‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚‚‚€ƒƒƒ€€}}}~~~~}}}}}|||{zzyyy}€€€€€€‚‚€~€~~~~~€‚€€€€~€~~€}~}}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…ƒƒƒƒ…„„„„„ƒƒƒ„‚‚‚‚‚€~~}}}~~€}}}}}}}}}{zyyyyy€‚‚‚„ƒ€‚ƒ€ƒ‚‚ƒ‚€€€ƒ„‚€€€€€€‚‚€€€€€€~~}|Š“Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…ƒ„…„…†…†††…†…ƒƒƒ‚‚€}}}}}}~~}}}}}}}}}|{yyyyx|‚ƒ„…‚„ƒ‚‚ƒ…†‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚ƒ„ƒ‚ƒ‚‚‚‚€€€€~Ž“Œ‡ˆ†ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€~}}}~~~€ƒ„‡ˆ„†††…††‡‡†‡‡ˆ‡‡‡†}€‚~}}}}}}}}}}}}||~~~|{yxwxyy€‚ƒƒ„ƒ„„„——ƒƒ„}~‚‚‚‚ƒ†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ…„„…ƒ‚ƒƒ‚ƒƒ‚‚‚‚ƒƒ‚‚’‹ˆ‰‡‰‡††„†…„„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€~}~~€‚………‡†‡‡†‡‡ˆ††‡‡‡†‡…}}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yxy|~‰–„ƒƒ„„”“€~~…‹€€€„†‰…„‚‚……‹ƒƒ……††„ƒ……ƒ…„ƒƒ„ƒ„„„ˆ’ŽŒ‰ˆˆ‰‡‡‡…†…„…„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„ƒ…„~}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|xyz{|€‚ƒ€ƒ‚€~|~~{ˆ‘||Ž–}‚†Š…ƒƒ„ƒƒ‰~ƒ„……ƒ…†…„……ƒ„……†„„Ž‘ŒŠŠŒ‰ˆ‰‡………ƒƒ‚‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚€‚€~}}||}}|||}||}|}}}|||{‹‘—Œz{|zzz{|yy}}~€€|{{~~}‚•‘„ˆ~|~‚„||‚„‚€‡ƒ}‚‚‚€ƒƒ„„„„„‚„ƒ„…‚„‘‘Ž‹ŒŒŽŠ‰‰………ƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚‚ƒ…ƒƒ„………ƒƒƒ„‚‚ƒ‚ƒ‚‚€€~~}~}||||||||||||||}|||~~Š‚{z{zxz{{|}{~}~}}}}||€}†~}‚~~~€‚||‚€‚€~|{Š‚}€~€€‚‚€€‹“Œ‹Žˆ‡‡……„„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ……†‡„„€†”ˆ€‚€~~~€|||||||||||||}|||||||y{{{xxy{zz|€~|~~}€‚‚€€€‚‘€€~€~~~€}}}{}}}}}||}€€€~€~~“‘ŒŒŽŽŠ…††…„„…ƒƒ‚‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚„†‡††~ˆ•Š~€€€€~€~~~|{{|||||||||~}|{||||{|||zzy{|z}…ƒ‚~~€~…‚~€~~€…†‚€~~ƒ†~|~€€€~}}}}~{|}€}~€Œ‘ŽŒŽ‡„††…„„„ƒƒƒ‚ƒƒƒƒ‚€€€€{z{y€wz}~€‚ƒ††……~€€€~~}€€€€}}||}~}||}}}}}|~|}|{}||z{z|}}†„‚€€}~}~~‹„†~}||~‚}}}}|{}|~„ƒ€~~~~}}}~€~~~„’ŒŒ‹Š†„…„„„ƒƒƒ‚‚‚ƒ‚ƒ‚€}|||}~{{}w~vx~}|}|}~~‚ƒ€z}}|~€~€~~€€€€~~~~~~}~~}|~}~}}|{|||z{z}~€ƒƒ‚~|}|}||€ƒ}Œ~|{{}~}~~}{{{}|z{{{€†„‚„ƒ‚€~‚‚‚‚‚€ŠŒŒ‹Œ‹ˆ„„„ƒƒƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€~€€€}€~~~~|‚~~}}}{{}}|z||~€‚€€€||}|||||}{}{~{{{|||}|{{{{||zz}z~‚~ƒ„‚‚…†……‡†‡†„‘ŽŒ‹Š‹‡‡…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~€€‚€~~€€~}ƒ||}}|}}}}{|~~~~~~~||||||{~~z|{||||}|}|~|}|{{{|y{|{{}z}~~€€ƒ‡‰‰‰‹‰‹‰…ˆ‘‹ˆ‰‡……ƒ‚‚ƒ„„ƒ‚‚‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||||||€€€~~}€€€€ƒ‚€€€€€€~|z|}}~}}~~Œ†}}~{{ƒ‚}~~}}|}}}}}~{}|}|}}~|~}}}}|{{z|{||{z{{zzz{~~ƒ…ˆ‡ˆŠ‹‹‹‰‘Ž‰ˆ†…„‚‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„„€€€€‚~}~€~{~‘Œ|}Š€Œ~~}}}~}}~}|||}}|}|}}}~}}~~|{{{||}|{z{|yzyxy{~ƒƒ„‡‰Šˆ‰Ž‹ˆˆ…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{|||~~}}€€€‚…ƒ„‚‚‚‚€€ƒ‚€}~€~|ˆ‚~‚„„ƒ~}|‡}}~}||~|}}|}}~~}~|}}{|}~||{|}zzyyyy{{~~€ƒ‡„ˆŽŠŠ†…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~~z{y}}zzz}q~‚z{|}}}}zx‚€‚‚€€€€‚‚‚‚……„‚ƒ€‚„~€}~~}€€}~„€~~}~}}Š…}~~}~~€}}||~~~}€}~}|}||{|}{{{zzz{{|}~~€ƒ€‰Š‹‡………„ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv~€‚‚‚‚‚‚ƒƒƒ‚…†„ƒ€€€€ƒ€ƒ~~€~~€~}~~€€~€~|€~€~|}}|~~~~€}‚€|}€€}{}}}||{||{{{|{|||}|ŠŠˆˆ…………„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€ƒ€€€€ƒ~~€}€}}~~€€‚€€€}€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{|~|}|||z|{|~‰††……‡…„…„‚‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz~}yxut€€‚‚‚‚‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚~~~€}~€}}}~€€€€€‚~~€€€€€~}}}}|~~}}„€~}}}~}~~}~|{|z|{z€‡‚„„…„„ƒ…ƒ‚‚‚€€‚‚ƒ‚‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xyuu}‚ƒ‚ƒƒƒƒ…„…ƒƒƒ„„ƒƒ„‚€€€~}}~~~~€}}|}}~€€€€‚€€€‚€€~€~€€€~~~~~~~~……€€ƒ~€~~€~}{z{z|{z‚„ƒ‚‚‚ƒ‚„‚€€‚€€‚ƒ‚ƒ„ƒ„‚„‚‚‚‚~€~}~~~~}~}}z{|…„{{syz|pwuvwyutz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€€}}}~}~~}~|}}~€€€€€ƒ‚€~€€€€€€€€‚‚‚ƒ€ƒ‚€€|{{z|{|‚€‚€‚‚~€~‚‚ƒƒƒ‚ƒ‚„‚€‚€~€€}~~}}}~}}{{z€x|vyy{qtxwvxury……‚„„‚„………„„‚„ƒƒ€€~€€|}}~€}~~}|~~~~€€ƒƒƒ€€‚€€€€€€€€€‚ƒ€„}ƒ„€€‚}z{{|||~€}}}€€~}}€~‚‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxyzruyyvwwsu†…ƒ……‚„„…„„„‚ƒ‚ƒ€~€~€}}}~~€~~}|€|~€~€‚ƒ€€‚ƒ„‚€€€€€ƒ‚€ƒ€~‚‚„€€‚‚‚„‚~{{||||}}~}z~}}x~|||~~~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„„„…ƒƒ‚ƒƒ€}~}}}€~~~}}€€~~|~~~‚‚ƒ‡…~~€€€€€€‚‚€€~€‚‚‚ƒ‚ƒƒ…‚}}}|{||yz{z~y{yx~{{{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzswvst†„„…ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€|€€~€}~}~€€€~|~€€~}~~€}€€ƒƒƒ~}~~~€€€€‚€€~€~€‚€„‚„…†„€~}||||zyvyyzyvyv~|{{{~|{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…„ƒƒƒƒƒ‚‚ƒ‚ƒ‚~~€}}}}€€€|€€€€|€}~~}~~‚‚~~}~~~~€}€€€~~}~~€‚‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{{{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ||z{{{z{wvxursvpxyrx…………ƒ„ƒ‚‚„‚‚€‚€~~~~€~}~|€€€€{€~€€€€}€~~~}}}~€‚~~~~}}~~~|€~~~ƒ~~€€ƒ‚ƒƒ†„€~|}||{|xx{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}|{|z{}zzx{|zz{xtxuqrtpxxry„………ƒ„ƒ‚ƒƒ‚‚‚€€€€}~~€}|~}€€€€€|€€~€~~~}}|€€€€€~~~~}|~~|}€}}~€‚~€€~„‚‚ƒ……‚‚~}|{{||yw|ywxwwx{{{{|…Š}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzzzzxswuqqrpxwq{…†„…ƒ…‚ƒƒ‚€€€€~~}|~}€€‚€€}~€~€€~~|}€€€€~~}|~}}}~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{|||zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚‚€€}}~€‚‚}~~~€€€‚€€€~}~|€€€€€~}~~€€‚€€€€€€€„‚‚€~|}~~z}…~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}{|}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚‚€€€€€€~}€€‚‚‚€~€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€‚€€~}~{“z|}|{}y{zzxyxy{||}|||||||}}}||}|}}~~~}|z||{}}{yzzzyysuuooqpwst}…†ƒƒ‚ƒ‚€€‚‚€‚‚€€€€~~€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€‚‚€€€}~~|†‰||~{{~yz{z{Ž~wwy{|{}||||{}|}}}}|}|~~~~|z|}{}}{yz{zyxstunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€ƒ‚€€€€€€}~€}€ƒ‚{~~{{}{z|{{‡yxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ‚„„€~‚€€€€‚~€€‚€€€€€€€€€~}€€€€€€€€€€€€€€€€€€~}~}~~{}|}|||wxuxxy{||}|||||}~~}}~€€€|}||}{z{yz|xzsrunwqqzqvw……ƒ„ƒƒ‚‚ƒ€‚„ƒƒ„ƒ‚‚€€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€‚€€€€€€€€€€€€€€€€€€€€€€€‚ƒ‚‚€‚‚€€€‡~~|z}|{}xwvyyz|}||}{|}}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚ƒ„„€€ƒ†ƒ„ƒ‚„€„ƒ‚‚€€‚‚„‚‚„‚€€ƒ‚€€€€ƒ~€ƒ‚~‚€€€~€€€€€€‚‚€‚‚ƒ‚‚ƒƒƒ‚€€€„}}}{}z}zyvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysruowqwysw{…‚‚ƒ‚ƒ„‚ƒ„ƒ€€‚ƒ†ƒƒƒ‚‚„„ƒ‚€€‚ƒ‚‚‚~€€‚‚‚‚€€€€‚‚„€~ƒ‚~€ƒ‚€~€‚ƒ‚€ƒ‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ€‚€}€|z|{{w|yyy{z}~}||||}~~€€€€„„€}€~{{{z{ztpxrytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚‚…†„‚ƒƒƒ„„„€ƒ€ƒ‚‚‚‚‚€‚€€€‚‚‚‚‚€ƒ‚‚ƒ€~ƒ‚„„ƒ‚‚ƒ‚‚„ƒƒ„‚„‚ƒ‚‚‚‚ƒƒ„ƒ„„„…„…ƒ„‚ƒ‚‚ƒ€€~||€||x|yzyz|}|{||}}}||€€€€€‚~€€€€{{|zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚ƒ†……ƒƒ‚ƒ„„…‚‚‚ƒƒ‚‚‚€€~€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€‚€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒƒƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{~~}y|zzz}}|}z||}}|z{~~~€€€€€€€€}}||}|vrvxyvtvu}‡‡ƒ‚„…ƒƒ„…„€‚……„„ƒ‚ƒ„„€ƒ…ƒ‚‚‚ƒƒƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚‚‚ƒ„‚‚€€‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒ„ƒ„ƒ€‚ƒ‚„ƒ‚‚~ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€|€||}zz{}€~||z|~}}}}~~€€€€~~€€€€~|}}~~}|{xvvw„‡ƒ‚ƒ…ƒƒ„†„‚…†…„„ƒƒ„„„……‚‚ƒƒ„‚ƒ‚ƒ‚ƒ~€€‚‚ƒ‚ƒƒƒ„‚‚‚‚ƒƒ‚ƒ‚ƒ‚‚„„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒƒ„„„„„…„ƒƒ„…„…„ƒ‚€}‚€}||{||€}}~€~~}~||}}}~~~€}}~€~~}}}~}}~~€|}€‚‚ƒƒ†ƒ„ƒ†„‚ˆ‡…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒƒ‚‚ƒƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ€‚„„…ƒ‚‚ƒƒƒ„ƒƒƒ„ƒƒ„„…„„„…………„ƒƒƒ}„€}}||||~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒ„…ƒ„ƒ…€~‚Š‹…„„ƒ‚ƒ…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ†‚ƒ‚ƒ‚„ƒ‚ƒƒ…ƒƒ……„……‡‡†‡…„„…„ƒ~~|~~}€~||~|z|}}}}}~~~€‚}}|€€~~~~~€‚€……„ƒ„„‚„ƒ†€‚……Š‰„„„„„…ƒ‡††„„„„…„…„„ƒ„ƒ‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ…}uyƒ€~„„‚ƒƒ‚ƒ„ƒƒ„…ƒ„…†„…†}„y|~ƒ{…ƒ„ƒ}~~~~ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚‚ƒƒ‚‚†„„ƒ…„ƒ„…ƒ„…„Šˆ………ƒ……„†††ƒ„…………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†tpurstƒv{}u‚ƒ€‚vy…€ƒ€„…„‚……‚hzrss|€s„~ƒƒ}}~~}~‚ƒ‚|}€}}||||}|||~}~€}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ…ƒ†ˆ††…ƒ††‡‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vyy…r„ƒpvxqvtturstvi€nrotvnulwm{sn€‡ym}rsvsvmmxlpylu}}~€}€}€€}}||}}|}~}€€€~|~€‚€€€€€€€‚ƒ‚‚„…ˆ††€‚…ƒƒ„‡†ƒ………†‡‡„ƒ†‡ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoomw}x†pqzprtfu~n{ysoy€}}€|}|€~€€~~€€€~~~€~}€}€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„†……††ˆ„„†‡ˆˆ†‡„††‹‰…„†‡‡…„………„‚…………†……†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„qjoyxpkyszozwvvp€~~~z~}|}~}€ƒƒ€‚ƒ„€}~~}€~~‚€€„‡†ƒƒ†„……†‡†…………‡†ˆ……†…‡‡…†„††‰ˆ…„‰Šˆ†„††……ƒ……„†††††…ƒx‹yrˆz{pp…„x…xyks~y{krƒ‡ƒz|m{yyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozls|nw‚€~~}}z}{|}}}}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡…………†‡‡ˆ†„†…‡††…„……„……†‰Š‡…„†…††…††„†††††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„††…†„†„ƒ„„†„„ƒƒ„„…„…„…„†ƒ†‡…†„„…‡†„„…†„…}w…ƒ„„‚}~{|{~{||}~}|~}€€}€~~~€~~~~}}}~|{|~||‰†…„†††…‡†…………††‡ˆ†„†…††……ƒ„…†…„††††……†„…††††„‡†‡‡†…‡ˆˆˆˆ†„‡…††ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…ƒ‚……†……ƒ…ƒ„„…„……„……ƒ††††…„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ‚}€{{|~{||}~||~}€}€~~€}}|€}~~~~|}}~{|||{{~ˆ‡„„ˆ†††‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡……†……†„…††‡‡…‡†‰ˆ††‡‡ˆ‰ˆ……ˆ…†‡†‡†‡†‡…‡‡†‡……†‡…‡†…‚ƒ…††„„ƒ„„ƒ„†„………†…ƒ††…†……††…„„……ƒ„‡…ƒ‚‚…ƒ„~€€|{}~{|{}~}{|~}~~}~}}~~|}||~~|}€|||}|||~z{{|~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†„…„††„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…†‡…‡†‡†‡…ˆˆ‡‡…††‡…††…„„…†……„„„ƒ„…„†††…†„†…†‡……††…„ƒ„„ƒ„‡ƒ„‚„„ƒ€€€{{~}|||}}|||}}|}|~}|}}}|||}|~}{|}|}|}|||zz||}ˆ‡‚†ˆ‡†‡†††„…†…†…†…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡…‡†…‡‡‡…‡†ˆˆ‡‡…‡‡‡…†‡„‚„ƒ„†…‡…„„„„„…†††††…‡……‡………‡…„ƒ„ƒƒƒ‡ƒ€‚ƒƒ‚‚‚€{}~}{||~}|}}|}{||||||}{{{}|{~}{|}}|}}~}|zz{{||ˆ‡‚††††‡††…„…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡‰ˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡†ˆ‡††‡‡…‡†ˆˆ‡†…‡‡‡††‡ƒƒ„„ƒ††‡……„„„…†††††…†‡††‡††„†…ƒ„ƒƒ‚ƒ†ƒ~‚‚ƒ€ƒ‚|~~||}}|}}|}z{{z{|||{{{~{{}|{{~||||}~}{z|z|}‰‡ƒ†…†…††…„„……………„ƒ…†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…ˆŠ‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……‡ƒ„†„„††‡†…„ƒ……†††††…††‡†‡‡…ƒ†…ƒ‚‚‚€ƒ…‚ƒ~ƒ~~}~||}}{}}|~zyzy{|}{{{{~||||z{}||||~}€|{{{{|{‰‡„†„†„††…„………„„ƒ„‚€ƒ…‚‚z„Œ{€„…‡†††…„‡ˆ‡†‡……‡‰‡„‡…††ˆ†…‡„†‡ˆ††ˆˆ‡‡†‡ˆ†„†††‡……‡ƒ„…„†††‡…„„ƒ……††‡††…†††…††„ƒ„…‚‚€ƒƒ‚‚}€~ƒ~€||}}~}{~}|}yyzy{}}zz{{}|}||z{}||}|~~€|{{|~}|ˆ‡…†…‡„†„……………ƒƒƒ€‚…‚€€}|{„……†„…„ƒ‡‡†††…„†‰†‚†„†††……‡†‡ˆ‰†…ˆ‡ˆ‡††‡…„†……‡…„‡ƒ„…„ˆ††‡……„‚……†…††‡„††‡†…†ƒƒƒ…€€€€ƒƒ€|€~~‚€}€||}~}~{~}||yzzyz}}yz{{|{|{{z{}}|}|~~{{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€€ƒ~~~€yz}€ƒƒ…‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ……ˆ‡‰‡†…†…ƒ†„…‡ƒ„†„„…„‡†…†…†„‚……†††††„…††……†‚‚ƒ„~€€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|z{{{|}}}|€~}||}~|{‡……††††„…„…ƒ…‚€€€€~€‚‚}~{‚ƒƒ…†…„ƒƒ†ƒƒ„‚€…‡…‚ƒ„…„„††‡ˆ‡……ˆ†‰‡…„„„‚…ƒ„†‚ƒ…„…†„‡†………†ƒ„…„…†…†„ƒ„„…ƒ……€ƒƒ~€€ƒ|€}}‚~€~~~~~}}{|{zyzzyzz|yzzz{{|z{{{|}~}}€}}||}€}|†ƒ†††††ƒ„ƒ…‚…€€~€|~~€€‚‚‚„…ƒ‚‚„€ƒ‚€„…„‚€‚ƒƒ„……‡†……†‡…‡††‚ƒ‚‚ƒ‚‚…ƒ…„…†„††‡††…‚„„ƒ„†……ƒ„ƒƒ„ƒ…„€‚‚~~~~~„~{||€}€}}ƒ|~~}}~{~|{zy{zyzz{yzzz{{|z{||{~~}|}||}€~€†„……„‡„ƒƒ‚†‚ƒ€€~~€}|}~~‚„ƒ‚‚‚€‚€€‚…„‚€€ƒƒ……‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡†…„ƒƒƒƒ„†…„‚ƒ‚ƒ‚„ƒƒ€€~}}~~|~ƒ~|~||€~‚}‚|}}|||{{zzzzy{zzzyyzz{|y{}{{~€}~}}}€€€†„„…„…‚„‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„…ƒ‚ƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚€…ƒ~€~|}~}|~ƒ}{}|}€ƒ}}€~}|||}{{zzzyy{yzzyzz{{{z{}||‚€~€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌËËËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFK=8765999<>9?<D:;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937677=;>9=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<9<<98:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA><A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÔÔÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9?CE@<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÑÓÓÓÓÓÓÓÓÓÓÓÓÓÎÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø×××××ÛÛÛÛÛÛÛÛÛÛÛÛÛÛØÖ×××××××ÖÖÖÖÖ×ÚÚÚÚÚÚÚÚÚÚÚÛÜÜ×ÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILO@99:4;A<7=9AC>@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌ̈́mpppppppppppj§ãÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¹´ŒŒŒŒŒŒŒŒŒŒŒŒ‰¢¿¼½½½½½½½½½½¾´ŠŠŠŠŠŠŠŠŠŠŠŠ‹‡½æáââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVN<::77>C?8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÎN&+++++++++++"ŠôëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§£££££££££££¤œZUVVVVVVVVVVVR|®ªªªªªªªªªªª¬›SRSSSSSSSSSSSKªòëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;?C>6:7>>;=B?8<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÍÎR+11111111111'óééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤¥ž_YZZZZZZZZZZZV€¯«««««««««««®XWWWWWWWWWWWWO«ñêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;?@@8:;8<;;<?:;;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÏ\9===========5“ðççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©ª£hdeeeeeeeeddda†²¯¯¯¯¯¯¯¯¯¯¯±¡babbbbbbbbbbb[¯ïééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB>;=:9;:==;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÅÂÃÃÃÃÃÃÃÃÃÃÃÂÉÐÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÏÎÎÎÎÏÎÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÑÍÌÌÌÌÌÌÌÌÌÌÌÌËÏÓÓÒÒÒÒÒÒÒÒÒÓÓÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÔØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<8@B<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÏÐÐÏÏÏÏÏÏÏÐÔÐÐÎÌÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÐÔÒÏÏÐÔÒÏÏÏÓÒÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××Ö×××××ÖÖÖÖÖÖÕÕÖÕÖÖÖÖÖÖÖÖ×ÖÖØØØØØÙÙÙÙÙÙÙÙÙØ×ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?79:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÏʖ¥ÑÑȔ§ÒÑǒ«ÑÎÎÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<>B>BC@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÏϜª­Ñ™¬œ°Ñ™¬š²ÒÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?>;7:>9?D?A98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÐ˔ˆšÄ”ˆœžÄ’†œÎÏÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<<:6?B@B:647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÏѽș™Â¿É˜˜Å¼É—™ÆÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8FA?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÏÏҗ”ŸÌҔ–ŸÎђ™ ÎÐÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<>=964:99::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÏÓ³›Ä˜Ù¯ŸÂ›Ú­£¿ÕÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:=?>=<9@<<::9?@>=<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÐÑ΍žÃ΋“žÇˈ•žÈÒÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CFCAB8;?<=;<<8558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÐÑËÚ¨™¯ÏÛ¥™³ÐÛ¢™µÕÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF@HIGE@<<>><=><756:979;::;8@?:<<9<>=;;:?9?:;9=>=><;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦ÕɎ¥š «‘§™ ­¨˜ž»ÕÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;547<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡Ê»¡¦§Ÿ±¤¤¨ ¯§¢©œÐÓÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKL@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÓӞ¶Öœ‘ŽºÕš‘Ž¾ÖÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<=?GFHKH=657:979:;:<=9>99:8;=>>A>=9<<:=>>:=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÒºÄÕÓÓ¹ÇÖÓÓ¸ÈÕÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?AELLA>775;8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÒÕÔÒÒÒÕÔÓÓÓÖÔÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEK>>786967899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9699:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EILAALD??;9889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEHIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDJ;AA;<886486987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGJB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<BA<;876797799=?A?<:9@?<>B?:8776=??@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE>;HF89757875898;>>=;89A>=@?A>7596;>AB??@@BB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCEEC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELCA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<;DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGHNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAC?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€iixsg~‰‰xp‚†{w}~…Š½ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€‚wt|„‚}sp€Šx‚yƒÈÞÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsoupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿¼½¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»º¹¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjcmgb\XQPQKTJB:IQ?A7<94:565455688686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸········¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µ¶¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸¸·¸¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶·····¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨¨¨¨§¨©©©§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸········¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥£¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§§¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©ª««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤££¢¢¢¢  ŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž£¤¡žžŸ  žœœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=7789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥¤£¢¡¡¡¢£¥§¦¦§¬¬§¦ œ›¡¡ž›ššœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¥¦¦§§¦Ÿ›š›¢ ™––•š›™——˜˜šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜—™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥¢¢¥¦¦¥¦§¦¦ ›™›¡ —““’—šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB@DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥¦§¦¦¢œž¡Ÿ—‘‘”—›˜–––˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;;;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¥¦¥¥¦§¦¤¥¦¦¥¥£  ¡¡Ÿ™’–š™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šžŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡ ¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢¢¢£¤¤¥¦¥¤££¡¡¡žœš•“”˜›š›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œ ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸŸŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::88:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸ   ¡¢££££££¢¡ ž›™™˜™™™š™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢ ›ž ¡£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œž››œŸžœœœœŸ   ¡¡¡  ¡  ¡¢¡¡¢¡Ÿžœšššš›œš™š›™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥¤¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¡¢¢¡   ¡¡ ŸŸžœš™š›››œ›š›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›šœšš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>98;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤¤¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ žžŸ     Ÿ ¡  Ÿž›š™šš›š›››Ÿžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›ššš›™˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9;;>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœ›œžžŸžœšš›œœ››œœžžœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:=>:?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››š›œššš›œœ›™™œœœžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™˜˜ššš™™™˜š›œœœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›š™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š››››œ›˜˜˜™™˜˜™™™›œœžžžžžžžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ›››››››™˜˜˜˜˜˜˜™™œœœžžžžžŸŸžžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ››››››š˜˜˜˜™™˜š›œœžžžž  Ÿžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_]]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜™——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜˜˜——˜™››œœœžžžžœ››œœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±³­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=9F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œšœ›œ›˜™š˜˜™ššš–‹“–™˜•˜˜–›œ—•’‘’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨©¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‹‘‹ŒŽŽ‹……‡‹ŒŒ‡ˆ‹Ž‹‡Œ…†‹†ŠŠ‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VPQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹‹†Š‹‹‰†„†‚€‚‰‘ƒ€ƒŒ†‹‰…€‡}€’†„„†ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹‹‰‰…‚}s}ˆ€~œ„……‰‹Šz}}†ŽŠ†”‘‹—”—’˜¡–ž—•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¥›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ†‹†ˆ…„ˆˆ‰„‚z||}~’ˆx…‹Šƒ„…ŠŒ‘™””” ššŸ¢­±­©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPFMHSWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‹‡Œ‹Š‡’Š‡†‘“‘‘„‡}}ƒˆŒŽ‹ŽŠ‰Ž””˜‘•›š¨®²¯¯µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWLO_^\NUUbQDTM;?9<895775795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš˜ “—š ™›£ •› ¤£š“ˆˆ‹‰‘‘Ž‘Ž‹˜šŒ”š—œœ›Ÿœ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUKTOOJCPK_bXZQ\T`MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ª©¨§¡¥¨¨«©©¯¡›Ÿ¡££ šŸ œ”˜”˜  ¡¤ž›š¤§¤©«®¬¥£¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdVOXKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®ªª«¤¡¢¤©§§©¨£¢œ››¤ ¥¨£ ˜™Ÿ¡¢©§ ¢¢®¬«ª§­®¨¥¤©©©©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_UZNRNPORd\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢šœ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨¦¥§©§©¨£§¦™œ¤¦¢¡ ¡¡ œ˜™Ÿ ¡¤¤¢žž– ›š¢¢ ¡Ÿ ¢¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOWO^ddlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§¬©¤Ÿ¢ ¢¦¡¦®¦¦ŸŸŸŸŸ™šœœ¡ ¡¤Ÿ¡›šœ ž¡Ÿžž £™–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvwa_\UYQUV[c^s_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?C?:8:>?C@DA:;><@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯ªª¬¨¨«°©¨ª¨¡Ÿ §©­°²¯¬£¢¦¡©¥ž¤£¢¦ ¥¤¢¥£ž žŸ¥¢¢žŸ¢˜•žšžŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸ ¡¦¢›—’šš •|wo}yf[[`_Z\V\hdocniib^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¢ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶¯³°«±²±£Ÿ¢ª©§®·¶´´¶³¯¬«®«¶°©²±­®§¦ž¢££›œ—¢¨¥¡Ÿž£›ž¡š–¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¢™˜¥ ¤§ª©¨ª­¬¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxib[_^\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>AE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢œŸª²¸¼¼½»º¿´¯±³µ´··¯µ´µ²°¨¤¢Ÿ —•š—¤ª¦¦¡¤£¤«¥¥˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨¨«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥¡¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxyxc[RYT__amhukpgiibYSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶´º±ª®´±°±´µ¶¼¼¾¼¼¾Æº¸·º½´¯µ±±º¸·²³²ª¦¦Ÿ˜¤¤§¨¤®¤««µµ®³ §ª¬§ª©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš’–””˜“š˜Š‹‡€€|‚xa^YSah`fsositdidb[LK>:8898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÃÆÂù½¿ÀÀ½¿Ä½¼º½¾´§ª˜±À½¸µ¹À³¯¯ªª¨­§§¤¯§ª´¼±´µ¨¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`a^^jbbnwuvnl[bQU\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAB;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–••‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±°§¼¼¾ÅÄÆÉÇÅÆ»ÄÀÅÆÀ¹¯½¼À¾¾³«ªŒ³»¾´µ·Âº­¯°µª«¦ª£­¤§±¶«µ²­³­¨®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|ƒjfhaklfnuqruqf^_\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÅ¿ÃÂÆÅÀ±“¾º¿Ã¶¶º©´³´©«³»»±Ÿ›±¯¬¤¬®´§ª©¨ª­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|tkkndomhqxoyjia\gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÃÄø´À·´¼Á¹··¿À»®¥®·¼·­œ£·°¦­´µ¬®¥¥£¨¤  ¥™ª³²¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyz{vnkiguZfrwsyfg]d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÊÆÄÃÃÁľ¸¾ÁÃÀľÁÏÏÎÆ«¯¶´µ« §´³®«¸µ³«©£¢­©¬¦­Ÿ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuueeijg]jomxwcb``^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÏÏÌÃÇÆÈÉÈÈÉÇÅÉÇÈÇ¿ÅÇÄÄÇÈÊÒÏÒ̼¸¶´¸¸Á¾¾º½º¼º¼¬­§ª»º¹·À²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqobagugiitmxl]d[U`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÍÐÎÇÌÉÂÁÎÃÊÊÈÆÌÊÍÅÆÅÃÆÅÉÍÐÍÏÌÇÄÀÃÂÉÍÇÅÁÄÇÁ»¾´±°°Á¾¿ÁÆ¿¾¸·Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`jjvlieuotb]bTWTSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<:>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÅÇÈÆÒÉÁÂÿ¿¾ÄËÈÊËɺÎÓÈÈÍÈÃÈÉÉÅÅÃÂÁÂÇÇÉÊÇÌÈÇÈÍÆËÏÅ·ÀÀÀÀ»º½µ³³¿¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrpfegdjeajmno^Y\VVNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾƹ»Ã¹¸¹»¾ÁÇÁÅÃӉ©ÏÄÄÁÄÁÂÁÄÁþ½ÂÀÀÁÂËÃÆÌËÅÈÑ°¾½¸º»¼¾·´°¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·½Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfadbabccjbgc[ZZ\YQNE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶¸´´µ¿»½À¹¾ºº´À¸µ·³®º»¶¾Ì¶„žÒ¼¿Á¼»Ä¾»ÁÄÀ¾¾¸¼ÁÁ˾½ÉÄÀÀÊÀ±Á¿»¸»¾ºµ·´¸¼´½¸µ´°³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ¾ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ §¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|yˆ}qc`bbgjgfiei]VVTYOSKE8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“’’˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´µ±°µ·µ»Á¸¾¹¿¼¼·´·°®·µ¸¿Ï›ŠµÁºÃµºÇ¸¶¹»½¹º¶»ÅÅʽ¹ÅÀ¿¼Á¾¸Æ½ÁÀ¼Å¸¶·´¸¶¶»»¸¶´·ºµ´¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¡¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒ€xpmeefoiekhXXNKKKRILHC9=8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’š”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿¾¼²­¯¬±°·¼·»½ÁĹ·¸´­¸²¶½Åҁ€ŸÄ¾Ç·¹¸­·µ¸º´¸³»ÅÆËÁ¼ÆÀÀ¿½¼¿ÉÃÄžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~‡|knpgpksebm_\THKJDJBCG?9;8><7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??==97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘ŽŽ˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼¼À·ª­¤¯±¶º±½¾»Ä¶·œ~w‚t„“Á¬{‚œÉÆÏÂÀ¸®µµ¼¾¸º²¾ÄÄÊÅÁÉÿ¿¾½ÇÌÇÇÄǽµµ¶Á½º»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†qelintnxcgb[cQKTHEECGC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?>??FD@A?>:7?@CC?A=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼««£°»ÔÚ»º¾¼Æ²wcldP[a}z…†™ËÎÑÌÊĵºÀÃÈ¿¾µ¿Á¿ÆÆ¿ËÆÿÁ¼ÀÃÌÊÇÅÆÀ¹½¼Ä¿À¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtolltkln_b^`aNHM?E@?DC;;::;:8;<:9<>9:>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED<AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±³Ä¢²Û¿¼½º}do``s[TUXl|†ˆ›ÈÈÌËÍÊÆÂÄËμ¹½¹¹ÀÿÈÆÄÁÁ¿ÅÀÊÉÃÃÄùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{zˆzmmw{_pc[]_^SI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA??ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸µ¼·Áoo°ÍÁ´zZJdcKp~n`QYx‚‹ ÅÂÇËÈÁÃÁÀÉÊÂÀ»º°´»½ÀÅÆÅÅ¿À¿ËÇÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²²¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}zmsxsgp][^\YQEDCMIAE=G::59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘–žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯·¶²µ³·¹¼»¶»¿Ç}ov¤¿›UROƒgO\|ƒlFk‚¬Ã½¿ÆÀ¹À¼¾ÅĽ½¹²°®¸·¿ÃÇÃļ½¿¿Ãþ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸¸¸½¹»±¶²ÈÀ»¶´±°·¬³©°­­´·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|vluzpni[__YSPAEHGK@DCH<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿš›œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹ÇȂn¥sQLb•_QQUŽ–vNe‹œ®¸¸¸Âº³»·»¾À»»¼®¯®³²¹ÁÂÄþ¼¿»º¸¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ¯µ´´½º¾¹º»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰|‚zsvvwnq`_f]ZTJ<??FF=FCC9:5;99><<::<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¸ÇȊƒxtaLbŠq\OVd°ºwVP~¯°²±·¾¹²µ²¼¹¼¶º¾²´´´°¸¾ÃÆÄÀ½¿¹³¯²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtvql_ca[]OHA>=HCFMC@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·ÃшyVQŽ”kmVepg”~qm^‡¼³°¶ºµ´²¬¼¹¸µ¸Áº¸³±¬·¼ÁÇÿ¹ºµ®¥¬³°¦°­¨ž Ÿ¥­¶µÂ·¶´¥¨«¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´·¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wo{ourmc]fX\]RNMA>IBAJI@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³²­¶º¯­¼³¸¹Ã¢‰~J^˜ÃtŠ]v|ijtŠ´»µ±´µ²´¯¬»º¸¶¹Àö®®ª²¶¼½¹¶²±­­Ÿ¤§§£¦–™™šŸ©®¹¬««Ÿ¥¨¤«®®§¯¬¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmuik][jT]\OMHDFLBFNF8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹º¶¹»µµ²»¯”–Lb”vp€zcjls~zsžº¹²´³°±­°¹¸¶¼¸»¿²²²®±®¹¯ª«­¬£¨¡ž—˜¡•’•—˜Ÿ¨®¤£¤ ¢§¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬ª¯£¤£¡© ›“Ž“’’™–š¤¥ Ÿž§˜•’”™ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wrxhtsndT`cW\QNLH@HQDMC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯²´¦ªŽWonj\h_]VY^gci€—¸²­³¯®¬®¶¶²´µ¯ª¤ž›œœž¨¨ž ¨©Ÿ¡§–›——“–Ž—›¤¨  ¢¢¢¥¥££ ž¥ ¤¬¤¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›©¨««Ÿ¦¢›£œ•Œ“—•–˜Ÿžžš˜¦—“’–¢ ¥£¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦ ˆxƒ|vybwln\QhTPNGPMLBOQ@>;>39:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¥¬©±À·¯hxxkshY^PJHJLQOZkn¢¶ª²´®ª«¯°²³®¥ž’˜”˜ Ÿ¢ œ¤¥Ÿž¨”›–—Œ—‘—“˜¢ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£ž™—š«¦ª±£¥¨ž œ•“‘˜–•˜—Ÿ˜›™š£™—”–š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’}|€uu}mk{dhUQcMJHGORMJNG<E@=2?759;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜——–¡¨¬®¶·º¹º··»®¨ ¡¨¡¥ÄÎ`ecrcTLF]IPFMKKS^]|¶¯¯³µª§¬«¢œ™”Ž‘–—˜™œ ¢¢œ¥žš¤———–’‘‘“š—› ¤ªž¡¡ž¦§ª¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¡¤¡›˜ž¯¨®²«¥ªª š˜˜˜•“–š“••š–›——˜¡žœœ—›¡šžš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}vx|dyy`bRU`IIJKSTIRPL9?B67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—“’œž¤¨®­¬««¯ª¯©ž—Ÿ¥ž¹±…zgjcVHP^Ž{lSKGGNTTd«²°°¸¬¦¡œš”—ššŽ‘•‘ŒŽŽ”™¢œ—£™š—˜™”™˜–›Ÿ¥¦© ¦£ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§  £±®²±´ª²¯¢™œž¡™››š˜™›”–›–™œ¥¡ š£¡š™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ Ÿž ¥¡žž¥ ¦™{|uvsh‚le[SZYMQJNOULSLA7>B68=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’‘œ˜¡ª¢§ ž§¡¥Ÿœ’œ¢›ž£§š}l]TLIUƒª±ŸhPFCCGM^”°­¬¯§Ÿž¢ —‘“› œ™—’“Ÿœ¡¤›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬¨¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½·¾°¬±®­©ª´±°¨«¨²µ·³¸­²´¤ ¥Ÿ¬¡¡¢  š˜–– ››˜¤¡ ž¤¡ žšœ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚|xuiwu]lZR`HRUHFUVJBLG=KH8E<67;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“Ÿ™¨®Ÿ§žœ¡žš™’™ž›¡¡¡†n`UPNO\«àÚºubSHBM‹™š«ª©¤ŸŸ™’’“˜˜––•Œˆ‹Ž•ž–žš¦  ¨¥±ª§®£«­¶°´²±®¶¸½Àº­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«¯±¹·¼¯³°µÁ¼·½³³µ¢¬¢©¨²©«¨§¨š™žšª§ ™§ ŸŸ§¨¥¤Ÿª¡¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰…„~vqmivmhm\X[BWNJGMGBFM<>L=4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜™ª ±¢·¤°¦Ÿž—˜•™žšœ¤ tYRORR]u¸Òº ©¹ž„y‰®Ä£¨­©ª¥Ÿžž¡¢Ÿšœœ”“•”žž˜”…š¡›«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶º»ÀĹ½»¬¯§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¹Â¾¸³»Æüü·³©³­ª³´¯³®ª¯£«§¶±­¢°¦¡£¯±­°¤¥¯£¡ š¡§¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¥ž¦™›¢¤žŸ›››œ‡…{tqkkurphW[QETHDJPI?EA4FH95;=6;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž  œœ˜šŸŸš œfPINP]u²½©‡¢ÜÖÎÔÙÈ´®§££¡ ž¥«¥ž—œ”‘™˜”ŒŠ†ˆ†ymˆ ¤¢«¬´¼¶Ã¾¾³»ÁÃÂÅÀ¿ÂÆÆÅÃÈÂÀÅÇÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌÌÌÒǾ¿ÀþÇÆ·ÃÉÉÂÁƾº´ºº´»·°µ²ªº²®»·¿»ºª·­«ª¸º´¼®®¹£¦£ž¦¥¢£©¦™›Ÿ˜š§ª§ ¡¡¤˜”£–”™‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ„}zqkdhoxjdZ[FKLEDSLDBE7:?;549978>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ²²¸§¡¡«ª¡œž¡¢œ”]KELSu…³¶¤’‰ÅãÜÑĵ¦Ÿ™œ›žž™———’ŒŽ——“Ž‹‚ƒ‚wsqnp¦­®´¹Å»ÍÇË¿ÂÌÎÍÌÇÉÑÌÍÌÇÉÅÅÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÑÔÍÓÐÓÓÌÊÂÆÆÇÊÈοÈÑÌÇÅÇÅÁ¼ÃÁ¾¿¾µ¾³®¿¿ÂÃÇÄÇÄ®¿¸²¸¼ÃÁÁº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›Œ™‰•˜› Ÿ£—žš““‹•…€ytsebgrof^ZYCNLCEPIDC@5558:B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>8;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›¢¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¤¨¬­ª £Ÿœž–cJIM\~ªÑж ³Ó̺¯¨¢ŸŸš˜–”’”–‘Œ‡„ƒˆ‡ƒ€€yrroly¤¶º¹¾ËÁÓÒÓÈÍÎÑÓÑÒÑÐÑÑÍÎÎÐÅÎÔÕØÒ×ÍÆÇÉÌÃÅÊÏÊÓ×Ñ×ÒÕÖÓÓÈÌÇÌÍÉÒÍÎÓÍÅÈÉÊÁÆËÇÈÉƿó³ÈÄËÊËÏÆÊ¿¾¿½ÁÇÄÌÌÈɿÿ­¯³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›•Œ†‘‹€zruvgcgvidVWQDMF@IQB=B<:22@<D<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<A?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­³·¬®£ž£¢ ¥w]ghƒ°ÒÚÚÖʺ²ª£ž¡¥ š””•”‰|wpkebhqoq{…Š€vpnqtp…³Â¾ÅÑÐ×ÖÖÒÖÍÔÖ×ÔÓÑÓÔÔÓÏÑÃÐÓÖØÕÖÒËÉÎÑËÆÍÒÊÒÖÖÙÕ×ÓÖØÎÒÊÏÑÌÎÐÌÒÏ¿ÈÇÊÃÌÌÌÎÏÅÆǶ¿Ê¿ÑÍËÏÆÉÈ¿ÃÃÈÎÌÏÐÏÍÊÇ͸·»¨Ÿ¥«§ž˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„|xsvpc`erb]R\IJGAEHI>;A8=4585;86:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÁűµ¨¡¤¥ ¡ª‰’¯ÎÔÙÚϼ¯¨›–˜ œ›¡¢Ÿ›œ™•‰wic`____^_`^blusqpolrqu’ÄÇÆÔÕ×××ÓÖÏÕÔÚÔÔÎÏÕÔÔÑÑÌÐÍÓ×ÖÓÕÐÏÒÓÑÉÓÑÈÐØ×ØÑØÒ×ÙÕÖÌÏÏÊÍÒËÎÐÀÆÂÇÅÎÍÑÑÑÈÌÍÀÊÌÅÓÎËÎÈÄÊÇÆÈÌÊÓÓÑÕÏÒÌÓÁ¹Å±¥¨µ®§›¨¬¥²¨°³¬¬““ŽˆŠƒ‹„Ž™“™‚…Œ|zqstmacim_VP_JJCFCRM?<>54:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><??=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯­ªª«¦®·¨«·×ÔÕÙÙÑÎп¼Ìɶ¾®¦ª¨¡¦•{“’ÅÖÒÕ­¦¡˜•—™š ž™œ’}qecc__a__a`_``_`fnppnkorwwœÌÁÒÕÓØØÖÙÑÒÒ×ÏÓÎËÒÍÕÔÒÊÏÌÓÖÒÑÖÍÏÕÕÑÅÑÔÊÐÔÕÖÎÒÐØØØ×ËÈÎÄÉÏÌÊÌÀÉ¿ÇÉÍÎÏËÐÍÎÌÎÏÈËÐÐÊÎÊÂÉÇÉÌÊËÑÒÌÓÑÑÏÐʽȹ°®»¸µª¶°­¨¸­³¿»±šŸ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…ˆzvopokadnpaW\ZIFFDMWE;@=33<=87855;>@=9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ¤§Ÿ¸¶µµ¬¤¬®¾´°ÀØÒ×ÚÜÖÎÍÊÃÒÏÁÀ°©¬­©¦vi”ÓÖÍ°œ›–•—›žžŸ”–˜”ˆk^^^adb``aa``a^__^]bmroostvvy¤¾ËÕÑÖÔÓØÖÎÎÔËÍÎÅÎÊÒÒÏÇÎÍÍÔÌÎÓÍË×ÖÐÌÑÔËÌÐÒÓÊÎÑÕÒÕÕÊÀÉÁÅÌÂÈÉÂÌÃÅÈÊÊÏÊÍÌÐÍÓËÆÈÏÍÈÇËÅÆÁÅÊËÌÏÑÆÐÎÍÍÌÏÅÇÁ¸¹½Ãýù³²¾±»Ãĵª˜¥¢™–‘••’‹”š‘”””‚‰…ypqkmg``phXXhVLFLIPPB;C>;67:89:57==A;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÄÂÁ¿»µ²±Ç¸ËÕÕÙÚÛØÌÌÏÈÖÕĵ¯´¨¡¨do|¨ÙЪ•Ž˜–‘“’‘–––‹|eabb`]^acb`_``aa`_][]grqqrsqmry¤ÆÓÏËÐÏÔÕÉÅÉÉÆÆ¿ÃÆÏÎÇÅÇÍÊÒÈËÎÍÆÑÒÐÎÌÔÊÇËÎÏÇÇÏÒËÐÏźĿÆɽÂÇÉÎÅÂÈÀÇÍÈÄÌÊËÏÈÄÄÐÈÆÂÆÈľÀÇËËËÎÂËËÈÇËÐÄÅÈ»ÇÃÉÈÂÏÁ½¼¿°ÁÉǹ½ª°²§¥¢œ˜›£™—™‘•˜‰‚wotdk`^fpa[W`GHHGIMTG?J=64355=<48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ¼ºÍÍÆÐÕÕÙÚÛØÐÉÏÏÑÓȶ»»­¦œ^owºÐ«ŽŽ—‡„„„‚~……s`[^^^`^`cdc_]]^_``_[Z\akrrookloo}¸ÑÈÉÊÏËÍĺÀû»ºº¾ÉÆÂÃÀÃÈÊÉÈÊÈÁÅÌÆÈËÍÉÄÂËÉÁÂÌÐÅËÈ¿¹Á»ÆǾ¿ÆÏËÿûÉÇÈ»ÈÆÅÊÀ½ÂËÆÅľƼ¼ÀÃÄËÅÅ»ÀÊÂÅÇÒÅÁÉ¿ÊÉÆÈÆÐÃÃÆïÄËÇÃÊ·¿¼º´©¬¤¥˜Ÿ˜¬£¡¥›£ ›”{vstfiZanlZ[XRDLFBGDLDFS@54334?<3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ÊÏÑÌÇÂÃÆÍÎÎÌÕÏÕÙØÙÏËÒÍÍÎÈÀ´Ã¾²²`r¿°‹“—‡{…†€vxurp_[[]``bcdded`\\]]_^`[YZ\borokilposÆ¼ÉÅÌÀƱ¶º²²³²±Â¼¼¼º¸ÁÁž½¹½¿¹ÄÊÅƽÆÀ¸»ÄÉ¿ÂÉ»·»ºÅÿ¼ÁÍÃƽ½µÁ½Ãº½Æ»Âº³¼ÅÄÁ¶¿¶µ½¿ºËüµºÈº¿¾ËÄÁÆÂÆÉÆÈÆÐÆÂÌDzÇÉÃÎÍÁÅÃÀ½³·°²§¨¨¹°¥­°ª­¬”yvwjdg`hocV^YJFJFHJAEBEI@9:648853;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÅÂÄÈÎÑÊÊÊÇÍÍÎÑÈÐÆÕÔÖ×ÍÊÏÅÉÅÇÀ¸Å½«¯~duµ’Œ‰‹…y‡‡€~„|ttc[\]^``bcabeeb]][\^\^]Z[]]hsqmggnpry½ÌÀúÁ¸®°°§ª­¬§¸µ·´³³´¼¶½±·°µ¯²»Â¼Áļ¿ºµ³º¾À¸Ç¹´»¶Á¼¸½ÆÁûµ®²¶º¿´Ä·»µ«¸½½À½±º¶¯¶º³Å¼·®»¿µ·´Å¼¾ÃÅÀÃÅÆÈËÅÀÆÆ»ÈË¿ÏÊÇÃÆÂ÷ý½¶¹¾Ç¿¬µºµ·¶Žytxfgebkn^V^`FKHHJFBDAEE?<:565633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÍÈÅÈÍÌÐÌÍÈÊÈÊÉÊÄÐÍÒÏÍÅÇÁÅÀ¾¸·Éµ©°‚mq—š†‰Š{y~††wx‚}ti^]]]_`_`da^dec__\[^\]^Z[[]_lpnhfjnnr|¤Ç¿¸¸µ°«¬§ž¢ª§ž«­³­©¬©´¯·°²©®¦¬²¼º¶Ã¹ºº±«µ¹»´Âº°À±¾¼»¶»Ç¹Â¶­ª¨°²À¶¸½°°§²³µ»¼«®µ¥®µ¯»²°©¹°­»®»¸»ÀÀ½¹Â¿ÇÃÅÁ¼ÆÂÈ˸ÅÇÅ¿ÆÃúÄÆ»ÆÉÌ˳¹Â¼»³ˆsvvkiablhYWW[ALKMIEAC?FA:9:995854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÅÎÒËÃÅÁÅÏÇÍÁÃÆ¿ÄÄÃÃÊÁÉʾ¿¼Àº²³´Ã®©®†hdŠ’ˆŽ|x~Š…z{„wn^]\]]_`__dcbccb`_][[ZZ]ZZZZ\dnohfgiknr­¹°µ®¦¥§§š ¥¡šœ¥«®¤¨¢¬ª¬ª°£¦Ÿª­µ¶±½¹¯·¯©®¸´´¼¸´¼¯·¹µ²»Á²À®¥©¢«±²³¨½ª«¨«¬­´³¦¨®¡¤¯©²¦§¨®¦¨·¬±²·ºº»²¼½¾¾Ä¿µÂÁÇÈ·¿ÀÅ·Ä¿»¿Ä¾ÄÈÌÊ¿¾ÄÀÀ©‡strji]aodWVXPHYRSKFFE>>@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÐÏÌÃȺºËÁ˾»É¶½Ã¾ºÉ·ÁÃÁ´µ»µ°®´»­¨§‡_qŽƒˆ‹€{~€~xt|swe_]\\^_`^_ccab``_]]\ZXZ[[YXZ\_fkfegeikor…ª¥¬¥ œ¢¥”ž¥›˜‘¡£ª¤¢Ÿ¦¥¨¥­ œ¥¦¬²¯¶·§°«¨ª´«´º±¶µ®¶¹±¯ºº±¶¤ ¤Ÿ¦±§«¨¹ª¤§¨¨§²­ §¦Ÿ›¤¦¬žŸ§£ ¡±­­¬²´³´°µ¼¶»ÁÁ²º¾ÃÁ²¹¹Ã³À½¿µ¸»½¾¼ÂÇÄÂþÀÄ ƒxpkaf_ko`TY^HNgOTGEJF<=?=:;;825536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;=:7676788666;::;9:;<859<:>>@;È´µ½¸ºÀº½µ ž•¡¦º¶«³³»³ÄÏÈËÂƸ·ÇÁÌ¿¸É·»Å¸³Ä¸³¾À«µ»±«¤®²¬Ÿ¢Ša‚‡††|yutomkjjqi^`]\\\^__acb````]\[\\XYXXXVX[^_dcbegggjmoˆ© —–›¢–œ£™–Ÿ¡£§›Ÿ ¤¦¢¨ž›¢›Ÿ«°¬±¶£©ªª¬¬¤´¹­·°¬³µ®²µ®°ªŸŸ¤¢²¤¦©¸­¢¦¦Ÿ¨¬«™Ÿ ž™Ÿ¥š™£œ›¯©«§ª¬¬­±²¸¯¸¹»°¶¼¼º«³³º³½´¶±±µ´¿¶½À½ÃÁ»»½—ƒ{sk_e^ddXTW]IW\KPGIIFA<??@;?<04536:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»·ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÆÏÈÈÀÆ»»ÄÃϾ¹Ç¸·¾·²Á´±»»«¸¹°¡¨ª¦–‚e‚…†xrnpnkb^bff]]^]]]\]_`abccba_\[[ZZYXXWWXXXXZ^bddeffhikr§”••›˜›¢—–‘œ¢¢¨›¥¦¢¦œ  ›˜®®­®² ¥¢®«§¢µ±²²¬¨¯²§º³¦µ ¢ž›£¡­£¢ªµª¢£¦¦¦£–™ž—™› š—œ­¡«§¤¤¦­«³´ªµ°³«²¹´¯ª¯²²³·³®©¬®²¸°º¶º½¿·³±”…yue^e^[YVSZUK[QKIEHKIB=?AA@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½·½¿¶¾¼¿²¥£˜¥±Âµ¶½­´¸ÂÌÈƿŶÁ¿ÇηÀĽ³¹¹²¿¶±¸º¬±´­˜£¨ž’šwiƒ„xoqtqifdhec\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXWVWadecdeddhjv¢œ””•—— —™•— ž¡œ–¡¢©¤ŸŸ©œš«§¯°ª›£¤¸ª¡ ®¨¶ª¦§­°¤·°¤· ¢›™™ª¦¡š¬¸°¢¡¤œ¢ŸŸ“”¡”––›˜—–—œ•Ÿªžª¤¢£ªª°®¨´«ª§­³°¥«®³±°°®¯¦§§²®±´°¼´¹·®£”yud^aVYWSRTKM^LOKGGLLE<@><B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾¸½®§¨£ª»À½À¹®´¸ÁÌÇÅÂýŷÈ̲ÁÂÁ­¼»´»¼´¸¹¯¯¯§›˜Ÿ§’Špz€|wqilrtpihedfb\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWWV[bcbbcbcdfj–“•Œ’””›™––œ œ –¡ §¦¤¦§ŸŸ¦ ª¯¦Ÿ¢¤·¨¡¡¢¨´¢¥¨¥°¥°­«´ž ••©¡¢”­±±Ÿ¢£ž˜›“‹¡”‘“˜˜’——˜—ž§œ§¡¢™£¥¥«¤¥°§¥£««­¦©®¯®«¨ª©³¥¦¬¯´±¯¼µ±¯® ’zvrda\Z]XNLRHRaMVPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8847863321./2556;:8;7876<;:;;A8x»»±µ½°»±¸¬ž¥§­·»¼Áź±¹µÄÉÉÀÃÆÆǶÆij¿Ū··½¶½ººµ²««¥˜—¡Š‡q|ˆ~vncafihfhjgjm`]\[ZZZZ\]\[\^_\ZY[YYZ[WUXWUTVUSTRU``_`a_`acdi”“‰Ž”“”•–—¤™ —¡¦¢­¦¤¤££¢œª«¥™Ÿ¥±ª  ¥«§¢ž­¬©©­¬¡¢¢•˜£›œ«©°›Ÿ¢Ÿž—™“Šž‘’“–˜˜“œ¡£¤ ¢• ¢¤¦›£«¥¢¤ª¤«®¥®²©¦¥¦¦´¦©¨­³µ´¹º¯©¬ž‹rpo`[WVURGQOHZ[ORJTKSLEFIC8;;=<8667:9;:976977:;:=<<6;<8>598:88659:<<97?<9678452121..1426:8698598989;9@9{µ´­´»²°«²­¨§¯¹¹³ÀȺµÀ¯ÅÈ̺ÁÊÌȵɽ±¾Äɬ±¸Áµ»À»´³¨©¤”˜™š‡~p‡ƒ{tiijlgjkmkjme]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURSOQY]\]]^^__bdmŽ„‘‡‘š“•“œ›£œ›¡©©«¨¬§¨¥¤™¥®¤”™¥¯©Ÿ›™› ž®™›«³ ¥¦Ÿ¢£¡•“›––’©ª­šœŸ¡ š”Œ™ŽŒ‘Œ’–•ž¡ £œ›£•›¡£¡—¢¨£¢¨« «¯£­·¥££¢¬­ª¨«¯³·³¾µ³«¯˜„tsh[XXRUQEXLQ[XMTNPLPQINIB<??A?<65799<<987:79:;<=>;7;;:=67:;8976989:6:=99577571141-+/434988::8::748=8?9~³­¨³¶®©§¯®›©¨¬·¶¬¼Ê»¶¿¬ËÆŸÁÎÏȳĻ·»Ãȱ­¸¿·¼½º²³£§ž”•–”…xs€vwnmhmnmpggigd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUSSNPQYZZZ]\\^_`d~‹ŒŠ’—‘—™¢ › «ª¦®¬¨¯¤¨šŸ¬ •–¤¨§—šž®–˜¨ª™Ÿ”¥ ž’’‘“•§«¥š™™žž•Œ‹“†ˆƒ‹‘•‘ ž¡£—•Ÿ•š¡¢ž”›¥¥§¨¨ ±°¦±¼§Ÿ£¬´«®§°µ°¹µÀ±­±«}rsbVSVNRIFVPRQLLWMJLNRGMJACFDC>@65889;9:7::7<=:;@>:9;9:?759:9876958779;85576661320-*.102877;99;8948;8@8³¬¦±·ª¦¢°«ª§©²±¥¶Æ´¹º³ÊŹºÁËÐ˱¶¸¼¾Áñ°²·­´³º²±¡¡š›–•’~vkglnqnqjpkdege^ZYZYZZZZZZZ\\]\ZXXXYYWXWUUTRSUSVURNNNRWXYYYY\\]aj€zv‰‡Š—‰””˜›™ž©› ª¦¥«¨™¡¥›“Ÿ£›——…„’›£”£–––ˆ¢››“‹ŽŠš¤§œ••—›‘‘‡”Ž‹‹Š’’’ šŸ¢•“˜˜•¢¦™™¤¦¨¦¡Ÿ´²¨²·¡œ¢·¬ª­¤²²¦µ¼µ¬«±£‰xsm]NQQLOCMNNPKFNNJJNMQIMJAGLHGC=858889:;69:68;99><8:>9;?8789:886857688974577820301+)-/12876:999984988A7w¶§¤¶±¥§£©¥ ¨¥¤³ª¢²Ãµµ²³ÆÆ·ºÃÊÌƳ¬º½´·À¯­©°ž¦­¹®«˜™›”’…zm__frpvqinieghj_XXXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQMMKLSWWVXXYX[]aosvq…ˆ‚ˆ€‘„‹”‘”ž¡›œ£¡£˜¥—¢œ•‡˜šŒsƒ~—–†‘™”ŽŽ{™œŒ‚‰Š˜Ÿ£ž“˜–…‚”~~t‰Žy‡“š™š‘•Ž¢£Ž‰š ¡¤¤›¢´¯¬¯¬Ÿ˜¥¸¦¦±¡±®œ°¼ª©¯ª™‚wscVMROPMCSNLQMBPQHINRMHJJCJLFKK<749888;;69;7:<9::;79?9>@79:<89764445874312585/0102)(,-12764789::65:87A7x·¡£´©¦¥¨£¦¥¦¦¦³§¦´Á¸°´°ÉÄ·¹ÁΞ³¬ºÁ«­Ã­¨¢¦’¦µ«¡œŽ”•‘Ž|v}eWV_gfighncjhgb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTRMMJHNSSSTUUWY[]ilrm…|tNXrƒ—†Ž—‹”Ÿ˜•”–•–‰€“‰_;Wo|‹”‰€Œ‘Œ††sŠ…–yz…””ƒ•Ž‘ƒ†}“xqo…}‰‘—š˜“Š‰œ‡Ÿ˜‡ˆ–žš¡ —§¯©­¨¨Ÿ–­³¢¦®™¬«˜¨´¢©­£“}rn`[NSRVLDTJPMLFNOIELQMKOJIMOFII<7599999:7:;:>>8:==7:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9y· £­¡¦¦ª §©§£©°¨§´Á¹±µ°Ç·³½Ï¿¹¯®µÂ§ªÅ©£˜ƒ”›® ˜•…“ŽŠ†{rt\QLRUYZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MORMKHFHNQQMPRTVXZ`mpi{‚tPB@•‘‘}‰”„Š›–•‰’ˆ†•†yˆ`JQnxŠ‘„}„Š…n~”wuuw„™pQˆŠ†{~x”vhw†ˆ~Šˆ•Š‘’–‹„Šˆ”„šŒ‚„’›–ž”¤£¨©¥¤ž›°ª¡¤¤‘¦ª–¢ªœ¢¦¨‰tmg^[HQQRMIUMSILKOIHFJNLMTKQPOFIC<769:8:;;8:;8>?99>=8;<6;;478;6775344696/3/.125221/,')+*,4833979:99::::?9w¶›£§Ÿ¢¯¡§¨¥§¨¯­ªµ¼¶¸·³Á»¶§¹È¸¶¨¨µ¶ª²¼¦ž•Ž‰“§•”‰}ƒ|vomXMKMNOLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDDINOhYNQSTUZnƒtw~ji]U‰”‰t‡|…Œ“’™‹{†€vxsnuptŽz~Š«…yzhv{Žprmx‹’xz€{vrr’wgu„„„„{•‰ˆŠŒ‹€„‹Œ”ƒ|˜•œ•‘Ÿ©žŸ  ©¥Ÿ˜§¤“¡Ÿ–žž¤€sh`\\JVORGJXROJLMRJJJLPILQLRTLEHA<77;99>=:;<98@?::>=7==79937785675251472/2.,//200/-+(().1272198798775:<;7v®™£¢˜œŸ´©¯©¥­¬°±ª½´²»¸¶º´±Ÿ·º²ª¬©¨²¯¡š‘”€›~v…w{uonhXKHHHGEHHPTTTWWSTUUUVWWWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQQSV^uƒ|xfw—˜}hyvx€‰}„˜’q‡|w{ok~­}s‹{†’}tfv|†lohs|‰Œˆ€lyq}pmuqiq€~ŽpC‹„‚ƒ…wwz‹…~Œ{u~Ž’˜Š’š›£–™šž¢–‹¥›ž—Ž–˜womebZWWTQJSUTOPNPVKNKNOJQNHNOKEC<;79;::?=9<:99??;8<=7<9999266856633611224.,,-..-0-+*''*.1362/876966527995y¦— ž– ¦¯¬®«¨©°¯±«¼¸¬»¾¹³¬§›°§¬›–œ¥©¤ —™Ž„’yˆŠ‰up{mtpiliWKFGEA@CDILLMQRPQSTTTUVVWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNPQTX]eprmˆ§ªÀ~uyc|xo|yˆz}‹†omŒ’ytxjj€‚q–‘‹~–€I“˜nhw~‚licly…’†ksl|nr{†imps‰„†z}~{vots…‚yxp|ŽŒŠ”ƒ–—˜š’•—™—ž—Œƒ‰Ÿ‘‹’†–~ninnnWUWTRQYORTTSXUMNHNKMNKCHNGE?;99;99:><9<;::=>:8:<9?868727565541432/024*+**-.+-*(*(',-1250,5567485HA895w™‘›™šŸ¥­°¢¬ª¨µ¯®¬´¿«¼Â¿¦¢™•¤—„‹”¡¡˜˜‘“‹sŽz…‹…tntkpldkjXNEFC@<>>AFFGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_IMOORWZQY\`§ˆbšitzepmz‹‰vˆ†tlš’ts|jkMy…’‰„Žg1v†sl~~ƒtfet~„„…€filukq€|gqq{n“{s}|qpnum‚xyujy‰‚ˆŠ„–“’‹‘””—Ž€yˆ—ˆ†Š†€ˆvjjohdWQZWYY[MPUVYXNIHEJJHGBAFDCG=998;9:9<:9;:::@<9:<98>787715234533645031.**+),,++)(+'),,226,,5775478iO8;5n’ˆš‘™–¤¨®ž²Ÿ¦º¯«²°Â±»Ãǚ–”™‹…y„˜”Œ†q‡‚s‡Œ…zorpnodpf_TFIC?<;9:?@ADDEGILOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOOQVLAIQIb¯³ r|xl}mrƒ…z„††yr¡•txsu”‡5q¨Ž¡¡„¢…vp†|‡|sŒ­‰€gfbjnrmpƒuioXupŽš’wl{}mqmp€zsvncv„~†€…‘Š‹‰‘‹‘Œ‹ƒux‹€~ƒ€~{rpol`[\][YX`_RN[ZXWLHJFJG?CABG>CD=;97=;:;;9:99;:?<88=:8;66651121253474531./,,+)*))***)(*)+/3DM2166643<vR7=7b’“ˆ–‘ž¤§ž¯•¥µª®±®Á²»ÁƖŒ”€ˆ}n’‰ƒŠ‡…u‚ƒl•ˆ‡{txxlwnwci^IPG>@7449;;<=>@BEHLLLLNPQRUUVWXYXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL7CMRSDJ†v€||v~mwˆˆ|~…ƒŒ~v¢™y~†…™„›œa†ªŸ‹ƒŽzwˆ~‰ˆsŠ—„z]dqtz{wŠlgjbyo…‚znwt„zptzwkni^w‡}‡|ˆ‡€‹’—ƒ…‡}q„„}uw{|‰vprsfg_[[]S[f^WQUX[UGJJDLG?F@DC>AA=:97<;;=<::99;;=>79>9985653244004645554-,)+('''&(())((+++/00Uq=23331E~W4=9\ŒxŠ€”Œ’Ÿ¦‘ « ±¨¯À±ºÅº–Ž‘”‡z…vkŒ‘‚}Š„ŽŒxƒ€s¡„‹}}~p€~zgvkRWL@E211367688:<>AEGFGJKMOPQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMORLKT]YRJi„ˆ{‰y|q|Œz}‰‡~—‡v¡™ˆ‡’”¥¬©H†®¯¯‹€“Š‚‹„‘¨‡€˜˜Šœsm|†‡}Žhghx~n…‡‚…q„…Gk€wryvhmk_w}ƒ‰ˆ…Œz•ž›‰‹ˆ‘zu‹v|xmow~ssqk[^][ccXfe\UPPVYPDLKFNICFCCA@CA=988:::;;:888::?>6;>7585773344236656768;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|~Š…ˆ‘–˜’—¡¬¡¦¸¯³¼³—’‹˜‹}tp‰’~}Œ‚’”}†~†¤‡ˆ‚ˆ…x‡ˆ~s„x_cWKB60./23123668:=?@BEGHJLNQSTUTTVUSQOGC?80,#‡[>?84.]–ps£UFIKMNPW`YpZ\^j“‡•„‚…‘“~…ˆ‘š•‚ ¡—•›š¥­“š»±§»Ç芌¡¥”‰‘{r„žŸ‘œv……Šˆjhoƒ€u‡„‹q†‚w‡€{v…}nvug€”†‰ˆˆˆ‡¡«¡–‰Ž˜{‚‰zzogkx~y~rjd^[[]i\af_YOKNWRQIPJDNGCJDB@DDA<:87=<:<:88778:==8<=68656623445576867<BB?<8:>CQ^e\G2'&,,--.1(?‹[.310Oƒ_4?;nupfxƒ{€Œ€‘‹š›¤¡¬¦«¯°—‘‘„¡”„xwŒ”|’†’•Š€’›Žƒ€Œ‹‚‰ƒ‰mpj]BA4--//./02234779;=?BEHJNQRSRSTTRPOHDB<87/9D><<63.l“—MPHJLKKNV`cggmu›š““‹Žšˆ“‹  ’£ª¥£¬“¨¶¢¨Áîǯxº”š|¡ž™„“…‚¢Ÿ”™’„Š…˜‘–lpu‰‹‚–Œv„ql…Š–’ƒ…ˆr‰¡–‡“‰–¥µ©›•¢ƒ‡“„}kjk|€sa]c_Zfj\kk^WKGOSQNMLFIPCDMFACEGB>:97=<:;:987767;:6=:785456345566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYp‚pu‡qv’†~˜–š•ŸŸœ§ ª–“˜žge¤š~„’‘y€’ˆ’}Š…™’‘‚€€‹‰…†„ˆ…xx~gMR>/..,/.-/000212557;?CENPRTPQRSQNPIED>;<:CF?><752<?R5HHHLLMNR^oŠ|s} ›¨¦¢™¡—¢•Ÿ¨ž©«Ÿ¨¬©ªµ—«¿«¶ÈÈ·ÉÑϾ› pi«©Ÿ„”’…œ¡šš™§‘‘ˆ•¢ššwz~”˜’¡’——”ž{v•’«³‰— }”žœŽ“–™¤¢¦¶°‘™¨ˆ—Žˆlss|~zqh`\a_afc`gg\QEJKPOIJLFFMCHLFFCBGDA:85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Ppu`n}awŽ}|”ŽŽŠŸ’—ž–œª˜žªBD}‡‰‡˜x‚ŠŽ|Š†Ž‚€‰ŒŠ„’…‚†‰€†w_bP460-1/,.00./..0015>AAMQRSPRSUSNSLEE@<>=GG@A@8662<9;FHGIJMOQYm†w•‹£§ª´½¸¥®¬¬¨©´«°·²²­»±³¾œ³Ä¬»É˸Ŀ¸¥£°²¬­«¤‹–˜…¦¦ ¢—¦™¢ª¨¤‡…“¤¡ ª¡¤©Žœ±‹•£§·»› £°“££ž‘¤¢«¯­³µ¢•¥«ˆš‰’Š–z{~„}f`h\eb]cc^ff^[OCIHTOFHLFJGEFHAKFCFFA:87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLicWjpXz…v”…ˆ‚œƒ’’Úȝ–sV—ˆˆœ|†ŒŽŠŠzˆ‚‡‘Žƒ…€‹…†‡’†‚„‰†ˆ‡‡qna@E64<2/110-,+-1/-4?DAMUQRSUUWUN[PGGD<>>FHCD@8;<5C;=FKIGHROPW“ „®£³ª²ÁÇë³Æ¶­´¿³¸¾¶¿´Á¶»»¤¸Æ©¶Éǵ¾¹´¨£´­±±œš’šŸ‰§¯«¤•vŸ¤—¡«±³˜–ª­¨®¶»²º¬¯µ¢±¬±µ¼·µ®µ §¨£¨›©°­²º¸¸§›·©¥Ž‘“ ‡y‚tXadVea`b_`e_ZUJDELUQHJJDIGEA@@KDAMF<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AEWQJL[ZQcdWzuq‚”}…†“v…~€{¿»£¼‚´”“›„ˆ’‰‰y†€Œ“Œ‡…Ž‰Ž†€†‰…Š‡‘zxn]V@EM<6:46AB7650/6CHCQ\OQUWU\WP_UIKJA@?GKFED;>@7D7?BJJEGWTP^¥­£±´Ã¶¸ÁÌɶ¼Å½´´À·¸Âµ¿°¸t²´¦ºÅ¤°Æ¹±³±´¨¤µ¶ª± ¢–›¢’¥±®¥­¬§¤˜ ¬³º¢©²ºµ»¾Ì¿ÅŽ½³Â·º¸¿·º·¹¬­°¦±ª­¾°½»Â¬™º¨”®˜˜«‰~zjWbaXjdhdVZcYVTIGGLQGCHIAHD>?BBK@@MC99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FQLALRWTYUZwjp„Ž…nzryˆb¸¡™£‰•“–“““—’‡‡{†•Š€„€‰z|‹‡†|ŠƒŠƒ•}wyueO\dGEL:Qda[^SF?;HPDZcQQYXYgZT``MSOEA?IJHEFA@C=E6B>HGKLSZT]“¯¸µº¹ÉÀ»½ÉÌ»½À»·µ¼»·¾µº²Æ`u³¥±šž«½ª¥¨«ª£¢²µ¡«§ž•–Ÿ˜ ®¥§§¥ž¤”¢§±´§²²¼¶Á½ÓÉÊÓÆÂÅÌÂÊÃÀ¾½¿»¼·´°¹··ÃºÆ½ÃÉ°ž¹ª¢¬¥¨·‰~q_aa\Wa_hfRXaVRUIEENKA>GD=KB=B@=F>;H@796379>489:57045/26389374526?8@>GKRTTRPPQRQJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKE@IMPRLQ]hllq…tmsrsˆÕÀµ™ •˜™‘Ž—‘––Ž†‡}†ƒŒ–‹ƒ‚xz‹ƒ‡{‹yŠ‚—t}zkepuY]\Peeb`ed][XW\MdmURmm^o_XgeUYTJDAKKHFHHHHBI9D?HKTTV\Z[’¹À¹½·ÆÀ»¹Ê˺¶º¶¸¹³¸µ´®¶¶™du¨ž­p^¢¬œ˜¡£›¤ž«¥”ŸŸ”Ž–˜—¨Ÿ¦ŸŸš™„¤¬¥ª°­·°½¹ÔÑÏ×ÏÉÌÒÌÏÎÊÇÀ¿ÂʽÁ½ÂÀÅÄÆÊ¿È䤻°µ°›¬¹½šyl]`[X]aZcbQ[`SQKCAEFD<@E>BHB@C=:E>=J?47535;=468977022/24169775555D3ELM>510006:477@IOJ;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODR\Yi_p—’‘”olouuˆ³¬¡¡Ÿ‹™œ™ŒŒ•‘›’…ŠŠ~ˆ‡Œ‹‰|„s{‰ƒ†|‰t‚Š†•s{xlmu{hreilifjih`fihmZmt—­¤¼ˆ‡g[oh]ZYTHJNPJKQLTQILAJGKP__bfia˜·Ç°¹³»¾¶²ÄǶ°¹±°»¬³±§ª·¬¶§ž›§šO›ŒŽ –‘¦˜¥•Š““‰‰‘‘ž›¡˜›•—‡žš¦›¬¯¨¯§³´ÔÔÕÖÒËÏÓÕÎÓÏÍÅÂÉпÊÉËÉÒÈÍÍÂÐÒ¸°Ä¼Äº¦¶»Ä£‚nc\\]X`WZfZP\WNPCBHEBI;AD>AH??B7;D>@H=46655;:687654/10146278875367C5B8?-0,1349=97,.,1;FL=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYSeWs˜ƒhqoyyƒ ªž¦—››—‹•‘šŽ}‰‹…ŽŠŠ‹ˆ|„‚p‡†{‡rƒ’‹}qxulqx~q{mxslh€pmcimpyiw}~Ë¿Âߧmcxnc[a`JPRUNY^P]]NQNTQUT\nnw‚r–®¸¬´§°¶«­½À±«µ¦¥¸§¬®¡¬´£Ž±®š˜˜Œ‘”‘„Ž›¦‘œ‰ƒ‹„Š‰„‹ƒ”•˜—”›‘œ˜™™žž«¬¤§¡¬¬ÎÒÕÑÍÌÒÓÔÐÔÑÎÈÃÔÑÈÍÒÓÓ×ÍÒÑÅÒÖÆÀÎÇÈ鿸Оyne]b\V_R][NOSPNH>AFABE<@B>EE>??:===<JA45465<888664412/03526768533;=<E=@11+/349?5901022-2EO3)/3.32=N248C}_2A†tD:==I>@CFH<VRMO[u†…Šwmwp}~€¡žž¡‹™““Œ‹“–„y…‹Šˆ‘‡‚{r~€‚‡z…u…“‘‰ovsls|{v|swqj€rrioqzyr{¾Ëš~Œ±ƒvr„vhaj]CZZ[VfdXekTX]\`c]cx{‹™ª¤¤¡ ¡©¦ª±¹ª¦´£¢­¢£­¢§±Ÿ‰¦š”’‘Š’Žˆ‚“‰k•¢˜„…~‘ƒƒ“–­‹••™Ž…’—§°¡ ¡¤¤¨ÇÍÏÈÂËÐÓÑÔÒÎÓÍÆÖÒÌÔØÖÖØÕ×ÕÉÔÚÍÉ×ÖÑÊ­ÄÃ̊rob`_XSYR[OJGIIJ@;:;EAD<BD>HB?BB;;9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/-.;R017/532ED28>nb5=tM99@I<AD?A;PLFKYp€u}hsyr‚‰•”…‹–‰ŠˆŽ‡w„”™‹ˆˆ‹‰~ƒxs{}ƒ‡w€{‡‘—ƒnwpmuvx}s…|yl‡vto}v„uy{µŒ<AŠÆ¥~|ieVICecfchjdoy[_fhknin€ƒ‰‘‹ž —˜Ÿ££¦²¤¤³ ¢¥ž¡© ¢±œ†ž’’’‹Ž‹†ƒ„~œ›Œ‚„…z”~‚©•£Œ’Š˜’‹}—Šš‘«³˜š›§œ§½ÃƸ¶ÆÍÒÐÒÐÌÒËÉÔÎÐÕÚ××ØÔÙØÍØÛÎÉÚÚÒÖ¿ÌÌ´wvnd]YRUPYVEFJIEE=:79@AB:HD@ECADA;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?1*(.BT29254/7K75<`bA<svV87AH:?C><9QECJTlnopaqqs†|—‘‹~‡’‚‰†…Š‚‡|x…–—ˆƒ‡†‡z„yqz{„†uz…ŽzŒp|opzr|qƒ‡€nŽzuw}|‚u|‡ˆ°tX©Â¶Œ’pnb=^hrpqpnxw‚eioruxr{‹‡Ž”’›– –‡Œ“› ›ŸªŸ¡­œ¢š™Ÿ¥žŸ¬™‹šŒ‘’…}ˆ‡ƒ…‹Ž ™“ˆ„‡~m™y„˜†ˆ“Œ•Œ†{›ˆ“®ª”•—ž˜¦®¶½¨­½ÆËÈÉËËÏÉÃÑÊÔÖØ×Ø×ÔÛ×ÓÙÛÖÏÛÚÑÖÈÕ˕yzhh[YPSS]HBEII>A>=7:=?;>H=@AAADA>?:87DB755479.566435542323647553457EBDCEB56<FNSM[nfcnskaV>,4LG865433BF4=W_hLux^8;?F<<B<99D?CGRk_mdbfkv€ˆq‘›€y€Ž~ƒ‚‚…„||„—Ž‡‹~†‡€w‚yn{{†tz’ž¡vu‚tu}t€„oo’„t|…zv†{‰·Æ¤Âɸ–›xpeNfczw†¢‹yyw{ƒ|„vm”–”•—ƒ‰–š——¦œ˜ —Ÿ“’—£™«–‘‘‹’ƒŒ…‰ˆ…‘žœ™‰…‹†—{ˆˆŸ—‰Š‹‚|¡‰‹¼¡˜“—™œ¨¦¥®ž§µ¾ÀÀ¹ÇÉÍÎÅÍÊÑÖÕÔÙÕ×ÛÔ×ÙÚÛ×ÛÚÙØÎÛƆzyfhd_TWVUMKDMC;==<9:<>9>A6>?@<?><9867CA6455=80665547745613854564567HH=DJE7925;H>;::7IP]ZRUXK9T>;95327I8=NYMHxxd5=>C=<@:6:>>@EQ_Yea][htzyl‰’wvzŠ|~€€}…z~‚‘‰„…z…ˆ{u}tn|}†~t’ž‘Ÿƒ’|†~xŽ}xŠŠn‚š€t˜…~‰…|~z©Ã ¼Œœ£œ}‰„}‰sŒŠ~s¦šœ™”…{‰„hGq¡¤Œ‹’…ˆ‹‘’•š“•‘—Œ•Ÿ”¡”’ŽŽ‹~Ž‹„‰’–šŸŸ‰Œ”’ž‘‚‹¦™ˆ…Ž‚†„€¥†ŠŒ¸˜‘”–¡§ ž£®¶ºµ«¿ÅÊÐÈÇÌÏÓÒÒØÒÕ×À×ØÙÛØÚÚÙÙ×Ü·xywjidV`[SONHDLB==>99::99<=6@>><=9:;;37D@8378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWN<MTHN?96333>C;[X>5YypZ<<A<=>8589?=DRSRX^UXfmmmiŠqrxŠ{{}|ˆz|{‹‡‚~uƒ†yszsm~„}w†›¡›ž”’€‹ˆ˜‡€œ’n‡¨…z ‹|Žƒˆ„œ~š‘Š£¢ ¤¯Ÿ‹‘‹…‹’†Wr­‹Ÿ¬œƒ˜›Ž\ƒ¢‘‚ŒŸ“•Œ†ˆŒ’“Œ”•”ŒŠˆ–›•–‘‹’”†€‹‰’ŠŠ–™££†“–¡‹ŠˆŽœƒˆ€ƒ‡…¤†Œ³˜œ’”—¡¡ž™’›§±¸¬¥¼ÁÇÍÇÆÏÌÏÌÏ×ÏÑÔ®ÖÕØÚÙÚÚ×ÖÙڞo|tgf\]XSVWC@ID>?>:49:;7:;:3;;?=>7;9:1:G=:27=@50677255?65;55858:57735HR7GOK994=EJB>1FCLA98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:<@;BQKKSYPTcbxmb~’ƒnmw‹xy~z}†|{v†„€sp…‚{vvut„ƒ…}~’¦£ž¦¢–‰”–‹Š¨—rŠ²ƒ¦‘„™“„™Œ¢– ™“‰š¢’©¯Ÿ‘”Žˆ•‹n·„šÄȲ¢¥›œ˜–‘²c¤ÍȕŽ†‡‰’Ž“”Š…ŠŠ†–š›”“‡•˜„€‹™ˆª——¤£ˆ™ž–›‰‡——‹…Œ†¥‰“¨™—“–˜¡˜Ÿ™“›¢²´¥£¼Á¾ÇÅÅÉÈÉÂÊÓÌÍÔ¨ÒÑÖÖÖØÚÔÓÚ΂rhb^]]NITYABGD;A=837;<:8=649:<:82?9929I:>67BC32:96264>=4;>6949;57944KQ<JQK9A7BGI@64JELF><88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBcFvŽ}|m~ˆxz~z‚‚ƒ~vv€‚|ln‹z|xx|„‡Š~Š£³§£ª³¡–§Ÿ¥£–•®¢ƒ¸•’²™Œ¡¡Œ¤›¯£¤˜§–§™¬¯¤—”–•‹˜™– ÀŽ£É¹«›£¦­˜‘›²……¨¢œ˜…‰‰Ž•‹“ˆ†‡‰“˜•Œ‹”“‡”˜†„‘œt‘˜²–—¥¡ˆœš“Š‘Š—›‰Š–Ž†}Œ˜ž‰œš™“˜—Ÿ” •ž› ±®¢¤·¾´ÅÇĽÃÿÆÍÊÉÒ¦ÎÍÓÒÐÖØÓÐØ»ryv]`U_VOHJNDBCE5>:77:?;<7=42669774=5;5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:IENED:6A@BS>9DO323565=v\<R\tiZM]S<=88567=:JFDGN[\YIf`;H„‹z{n…†z|„x…~px|~}orz}|x†‹‰†„’§»¬¨²½¯¤­³³¨£¢°¬Šš´¢¸¤•­¤—©­·¦¤£Ÿ™©—©£¯°ª™˜œ”•‘— ˜š»»®Ê¡j¶¸«°”˜Ÿ£«“—¾£^ª²‚‰Š”‡‘|ŽŽ}ƒ†Ž”•ˆ‡“—Œ•‹Œ—˜’œ™´—•«‹œ”’Ž’Œ™›Š‘ž‹‰•Ÿ¡”˜™œ’›˜ž”¡ ”œœ¥¯¨¡¤³¸«ÂÈĵº½»ÅÇÇÂÑ ÆÉÍÍÄ×ÖÑËÔ¡pzh\ZS^QOED><CAA8?875?F<<5<35345454B39:BM:B;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPdGb`bpJ@‹Šs†‡}‚ˆuƒŠ‚m}}|pw‡w‡{Œ†Œ™ªÂÀ¯½Æ»³´Á¼´­«³¶Œ§²­­½ª›»¤¨­¹¸«¦¦¡¢££¨¯²±ªœ¤˜›——ž¢¦¥’¤º®©À¼­­²¹¥¤§~ˆ†œ­½°ƒŒŒ‹ƒƒ‘zˆŽœˆ‡—‹•—”š—¨š±š‘¬œŽš’Ž•‘–—Ž‘ ‘‰”›£¬”–”œ“ ›˜ ¡”šž§¦¤¢¤°³§ÁÆï°º¶ÅľͦÇÄÇüÕÑÍÄʈtra[Y_[MJBL@FG>A?B;:4>A<=5=6>333241A17@BN>G@CNCA=C=;86CB5BIB:878;5B>79VKDWOF8=4K@C>4EJHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GE?CF\eG`igZ]\“ŒŒˆ{‡‹†ƒŒu†‘Šo~{q~z•z’””˜“•§³ÆÉ¿ÂÌÁùǼº¯«¹»—²·º²À®¥À¤«¯»¼ª­«££ž§ª®´°ª› ª›¡›•Ÿ°´§‹£ºº¶Á¼¬¨œ²¥¤¨”…ŽªÄĤ‚‹‡ˆ„†•”zƒ‘‘¡ŒŒ”’Žˆ—Ÿ—“™•˜¦ ®ŒªœŽ–’‘•••‘¡”†—Ÿ ²ž”š”Ÿ¡˜¤Ÿš › ”˜ž¥£¦¦¤¯®¥¿Ä®¨·µÉþ¶Î²Ä¿Ä¼³ÑÉȵtxl\X[iRLHDLKKJAA=CD<5AD;:3=8B332263A05IEM>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBfZNe\fTcj™—ŠŒˆ’†‰y†”r€|x‡‚z¡–¨šš˜º½ÇÈÉÁÒÉÊÂͼÁ³­»¾§ºÀ¾¼Ä·¬Á©¬³»¾ª°©¤¥£¬­³­¶µ Ÿ®ž¥¢˜£³½©›¨½Á£··°«’°­«¬—‡šª§¥‘‚Œ“¥•‰vŠ’z…’žŸ“”‹”£™—œ••£ž©Ÿ‘¥šŒ•–ˆ|•’’£š• ¢œµ¦ž—¤£¢¥ž¦˜ž•—›¤£¨§¢²¬¨¼Àį¥³·ÌÀ¹®Ä³»¾Â¸­ÂÃÂÀ™myaXW[[KKMJFDDIBBADL:4DH9;4<7E.12352B26SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQG7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>jH_XaZddVžŽ—Žž’‰Š‰ “„x…•ˆŠ€–¡™®¦£˜Â¾ÇÃÇÅÓÍÎÍ˼·°¹¼´¼Ë¼ÃÁµ¶»­³¿¹¼®¯¨ ¨§¶­­©²·šž¬¢§¡«·¸©¤°¿Ä±¾¹³§ªµ³­®—–¥¬¨ ‘Ž’±Å§•Ž}‘•}ˆ‘™ª™˜“““•“¥ž“™”¡£¢œ˜Ÿ˜‹ŒžˆZ–—’–¤™e˜£ž²¥–¢–¬¬ª§›ž¦—˜–˜• £¨¥Ÿ¶«©¹¼Ãµ¦³µËÀ¸ª¶¬²º¸®¨¸º½¸‚knZWTTNFJSNK?BHDDHGG95FM;>7=@J.32025B55PVN<LFKRLOHGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|gV;=@BFBqFiIRebLF¥”œ–¡—©–‘ƒ‡¦“ˆ‚‡‚œ„ƒ•“Žš¢Ÿ¯¾®¡Æ¼ÅÄÆÆÎÎÎÒʾ»¶±º»¼¿Ï¶Ä½¸¸·²±µ³¸³«¦œ««¸ª¨§¯°—£®¤§¤¤µÀ°«¬´¿ÃºÀº³§¹µ¸²®•¥­¯¯¥‹“•¡tÁš~—™…–šŒ±•šš•““™™¥£•Ÿ›–š©œ¡ ™ŠŒ–`J–œš•š¥–T–°Ÿ¯œŸ¥”¯®«¥š ¥”“˜˜ŽœŸ¦¢™´©ª³¼¼¼ª°²ÇÀ¸¥««­±±£¡²²´¤pmf\ZNPKEPPPQ;HJIGICC>:KU?A:=EM07544:B34NWO<JKNUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@BAF3>58JKCA=C;4EA:A?>H@5*B52,>c]g:35tde@R7&#3}hW;:BC@=QEWSsbWFHª—™ ¢¨¯™‘—‡‹§–Ž‰“…Ÿ‡„—Ž¡š£¤µÈ´©ÆºÂÃÇÊÈÈÌÍƾ»³®¹¸ÁÁ͵ǺÁ¸µº°¯¯³´¦£›ª´´ª¨¦®¬š¤­¥¤§¬º¿¨«¶·¾Á¿¾¹³²Ä±¹½¬£®µ¬º¦ˆœ˜¦›v¿ …™Ž“™š‹¯—¡œœ—•›Ÿ¡©ž¨ ššª™¡§ž˜‘ƒnv’¢š•¢ž®²¢«•¨ª—ª­££Ÿ¥¨’’™œˆ”œ¢ž—±§©«º¶¾³²­¾¹· £§¨¥§œœ­©©Œbe`_QKMGHNIUL=MDNJKBCD<QU=AABDO18=77?B75UXN?HNQYSPQUKQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW;:=..R`MUHe^HE«•œ¡Ÿ»¯™”Ÿ‹“«›‘’“‰«‡¢ŸŒ¤­”££¶Æ½´ÁºÂÂÇÈÅÂÍÈÁ½¹²¯¹´ÀÂʵűÁ¼´ºª¨­­°¢£˜ª´»¦©¦«ª¨¯§£ªª¾¼§­¼´¸½Ç¼·µ·Á±½À³©µ·«¿¥£˜‘¢ ¼Ÿ‰š ™—žž·Ÿ©œ¥£›œ¡š¨¥³¡›ž¦œ¨ªž™•”›‹—‰Œ¥¢”¢ž ´¯¥¥“°«™««¤£¨‘•• ƒžž›•©¤¡¡´´ºµ­¨µ²³žœ¢¥š—•™ª¡žw`\_]JHFGMQIMEFGBRLJBEG@VRDH=AGQ1;B7:BF79\YKALPTUSMWRNUJD@JJNO9C?5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-1:g\FCCœpbGE§—¤ŸžÃ­›—¥˜™©œ–ššª–•§¦•­­™¡«¶Ä»¾·ÁÂÀÇľÍÆ»½¹²¯¸³¿Âȵ¿¯»¶¸¶¦¤ª«­  š«ªÄ¢¥¨«¦ž«¯¬¢©¨¿·¦­¾±¸¶Ç¶µ¹¸¿²¿Á·µ³´¯¾£—£–”œ”® ‘¢¢¥££Ÿ½¤©¨« ›¦Ÿ½¢˜£Ÿ¢©«¡—•ž“ž‡…“ž¤¡µ¬¦œ–²§™¯§Ÿš©ž ™•Ÿ„ š›“¥¤š˜«±µ±ª¥ª­¬œ˜  ’Ž–¨ž”hbYa]OIGJNLHEDIA=PIA<GIH[ROK=HOU4BF9>HG5Ca[KCNRUWVQXTRUH@8QQPM:G@4CHQSIC<C>GVKC@O>K<06;GF>;FA56?9:?9;15D0-,/Mv\4KZ5,MnW<-=)#zbQ5CKQ:nRF<KxebWL¢š£œžÅ¬¡Ÿ¬ž® “£Ÿ–¥ ¦©«—·±£ª³µÄĽ¿¶¿Â»È¾Êȶ¸µµ°³³·Áƶ¾°¸´¸µŸ¦¬ª¬ž¥¤Á¥ ª­Ÿ¤©­¯¢¦§½µ¥±¼¹·¶Ã²³·¹¿²ÄÀ¸¸®³µµ£¥•’”¡® ™¢©¨«£šÂ­©ž¬­››ž™¦¡½¢¥˜««¬¦¡™™Ÿ’Ÿ‰W–Ÿ¦¡ ¸ª§“˜µ£Ÿ²¡ ›®–žŽ™”‚ŽŸ—•Ž¢¤•¦®²«©¡¢¥¥••˜‹‘“¤ž‰adYc`LHJJNFEAFK>=JB99JKN]QQI=LV\9FI=DMI8Hb\LCLPSYYVWOZ^IA=WQIK?H@5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+w`S6SZkWrHE6=ue\KNžŸ¡™žÃ¨¥¢´¢œ²¨“«¤ ¤Ÿ­©¬¼±¨¬µ±ÈÅÁ³ÂüÆüÄʼ¯°¶­°´¯¿Ä´¹±°¹´¬™¨°©©š¥¡§Â­›¬±›ª¢®°©¤§½¶¦·»½¯·Ã­³²ÂÀ²Ç³º·¬´¶­ª¢¦––•¤¬¢ŸŸš¨«°¯¯»²¦ ©¨™™˜“¢¤¸ ¡¤“¯¯¬¥§Ÿ’¡ž•ž•š£Ÿ§³¦¦˜´›£®šž›­ž“—”š€’¡–ŽŸ¡“‹¦¬°¥¦¡œ ž’’š“…‹’œžae[geJILJRBC@IG;;G?99OMU^RSJ>O^]=HPBLLI9Mc\LELRTY[SUO\bHA?ZQAHAKB7FELKN>;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<v]^?[T^eq@8;H–weA4Ÿ£Ÿœ Ã¨¤ª²¡£´ª•³¬§¢¤²¬®©»²¬°´´ÆÀÄõÀĽÉĵÀÈÁ´«µ¨¯¸¬¿Ä´·®¬¶¹¥™«±«ª—Ÿ¦—­»´›¨°›­Ÿ®´²§ª¹²§º³·²¹Àª·±Ã½´Æ§¾¯­·µª¨¬¡——’¦¥¢£˜˜¥¯¸®²µ¶ Ÿ¨¤™••“¤ ·£¤¦–®²²§«¦¡ž›š›–˜¨Ÿ ˜¢ž¯²¢¦—®™¥«—™ž¤‘›“—š…–Ÿ”Œœž”‹©©ª¡§ ™ž•ŒŽ™…•‰”Ÿxch]kjMPMNT=CANC::I@77RO]^RVQAW`\BJSHVKH:Td\NFON[W[RPQX]GAB[PBG>NC9HGHOP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1[bZ33806p[bH05IphVCWFŒyfC;¤£¡¦¿¦¨¯¯¡©´«¹°«£ª´¶±°¹·°·¸¸Ä½Ãǽ¼ÄÁÆÀ¸ÀÆÀº©¶¤¬»¬À··©¬±º¢•­°­²–¥§‘ª¹© §°ª ¯´³ª©¶¶­»¬³³º·¬¸°Ãº¾¿¦Ã«°·¯©««§ž˜™«¢¢ ‘˜¡±¯³«°¹šœ© ™–’—¦¡·©¥£¢°±´«²¨«Ÿ›  ›ž¥¢—£³°šŸ“¥š ¨š”¢ž•˜‰”˜“–—”ˆ›™”Ž¨¨¦Ÿ£›—›“‡Ž™‹}Œ–…›jhlalnWPQZTACET@;;IA7:XPd^PVWDY^]MLRN^KJ>Zc^NHPN[UYPKTWZI?DXPDF?N@=IGGQPB=DFBM?:1D?77547?=95E4+75/251.-.,1=*'+=\p=>1.1e[d@1647gY`F(?8l}h[V;‰{cC=§Ÿœ¢©½¡«°«£±¸©¥µ³¬ ­µ¼®³¸¼º½¶¶À¿ÈĹÄÁÀÀ¸Ä½À·¯¶§«·±»¾¿´©®±¶ž—«­¨­—§¨Ž§»Ÿ¤­³ž«¢±°³¬©¶´µ½­¯±µ¬°´±ÁºÅ·«¼¯±¸¬­ª£±¦Ÿ¥ª ¤—™ ³ª³ªª³š§›š•Ž ¦¤´®§¢¬­®±§³­²ª¤œŸ¨¤ž•¡™›¨µ©—™’’Ÿ™ž ž«ž——…•—‹™œ”Š–—š—¦¥¢ –•—“€”…{Ž’ƒŒ–elrgpq_FYfVDCMXDZ9HB6>]Qh\NY]G[^]NMRXdJJC\b_PLMNXWXPJVVWL=EUJEDAM@AFHHQPA;GDFK=87B=68719><65D0+80/05/*,/-*=,,%2+*5K1/'__aU150=`V^8)C3YT\gK6ŒzfL@¤š ¤¬¶¤­©¥¯®¶ª¯µº§¦°·Å·±·¾Á´´ºÅ¾ÌŹÂÀ¹¾¹Ã·À¹²µ¬ªº¶º¹¾´ª­±µ˜˜§¬ª«›««Ž«½«®±£« °­³®®¶²¹·ª®®²¨µ¯³»½Ê²ª¶µ±´¯®§¡³ ›¨­ ¥•–›š²£­ ¦¯—¡¤šš’Ž£¥§³©¡¦²¬ª¶¥®±µ¯¤™­§š˜Ÿ™™¬¸£—“˜œ¡˜—”«Ÿ›’€“˜Œœ™–‘Š”“žš¥¢¡ ˜–‘“•z‹…{ŒŠƒ‹’knxmu{`EajYIHYZ={JFD6AbTi[M\`J\]ZRSRbaLKE_``QLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`U`/5(C_Q\.*B/JGP[H3cYTKD™— ±¨±ª­¦¤¯®µ©·´¹¤¬³·Êº´ºº¿¾´³·ÃÀÌȼü¶½¿¿·¿¼±½®§º¸·¶Â¶«­±·”—¦®«§£°ª”¯»¤¬±²§¨£±´°±±µ±¸³©®«²§·¯µ´ÃŶ©µ¶¬°­©§£¶Ÿ §± ¤”œš•±ž§œ ªŽ©£ž›–˜¦¦¥¸§¢±´¬§²§­°¶¬¤™ ¬¨›œ›”ª¸œ”ŽŽ‹™œ¢—˜¥¡”‚’–œœ˜–•ˆ——š§œ£ ’–•v„‡{…„Œ‹mqwu{~\Kel\KNc\>b{GI8GgWf[L^bMXYWTXTi]OOHa]_PJHQVURKIWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANHf27'GbLV%-B.=ELQ<3rkJCC‘™¥®¥­®«§¥±²³ª·±· «µ¹É¸®Á»Â·²±µÂÂÎÅÀÁ½´¼¿¿º¿¼²Ä¨©¸°¶¶¿¼®«³²œŸ§±­¦¥¯¥²µ¬«±±­©¨´º¬´²µ¬´­ª¬¨¬©¸­±°Ç¿¸¥¹°©­­¥¨­°¦¤¤¯¤©œžœ›¯™££¢£‘¬ž£  ¢ª¦¦¹¥¬µµ¤ª«¨¬¯¶®££©ª› šš’¤´š‰‡‘¢ •” “‘„Ž“’š˜•”‡—“•™§›ŸžŒ’‘Žw~…}||‡Š‰qtr~}}\Sdo^NYf\FD–[G;NmXb[M`bNVWVWTXg^QRLcZ[TKGOTSNGIWS\N;P^IBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3Bc;6*HeHJ+:I?3BIS,>k<GHœª«¢©±¤©¥³´±´µ²²¡«­¼Ìº®À»Ç±´¬´ÂÂÑÅƾÀ²½À¼¿·¼Ä§¬·¬³¸»À°«±­ £§­ª¨¤°£ª±ª¯¬°¯°¯«³»§¶±²©²©«¦¥£­º¬ª±Â¹µ¬º¨©¨­ª¨±¥ª¤£®ª¨¢Ÿœ£¬•¥ž˜ž™¬¢§©¢¬¦£­¬¸±² ©¢ «¯±¬Ÿ§¨©™£˜™ §˜†„Š‹ž ‹Œ–œŽ†‡”Ÿ–˜•†–““—¤›œœ‹’‰~~‡…|w~‡…†tsqˆuk_Y`ncQsq\K;„|F>WtX`ZNc[NUVUWQ\b^SONhXWWKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*35>10485(5/*,.30;),,'%234$,2-860)(1<]J0.JgDF8<B05EKX1@”Z>LE•˜­¨¡ª³œªª°¶­¸µ®«¥ªª½É¼±½·Â¯±¬³ÄÃÎÎþ¿³ÀÂúÀ³ÈĬ®·­²¸À¾³­®«¤§ª°©§¨±¦´®ª°®­±°´­´»¤¸³¬¬®§« ¢ž¯·ªª­º¶¥¶µ£ª§¬¬ª­¡©§¦²²¤¦¦¡¡¬–ª¡•š ¦ž¤¢ª¥­¢Ÿ§±·­®£¥¢›ª«­©œ¡¥¤¤˜ š–˜“‚ƒ‰…œ ŒŠŽŒ™Ž‹ƒŒ—£›’›Œ“’‘”¢™›™ŠŽ‹Š|†€ƒzt€ƒ~twŒ£ˆxj^`ngWe‡cN?g“LEbyWbXReTMVUUTO\]aUKMiWUWIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*49?./463)4+*,+.#4.-+&(+79*&6+<-2,&06WZ.0JgAA<<C+:JO^4D†>HFD—’°¥£ª±˜«ª­µ«¶±«¥¬ª©¼ÀÀ¸¸³»µ¥²°ÄÉËÑ¿Á»¸¿¿Á¹ÁºÁÄ®±µ±³ºÀ¾³±®­««¨¶ª¦®¯ª¹°¨±±¯²­¶ª·¶§´·¬¬¤©«œ£ž³³¨¨¤´´ ¶­ ©¨«©«§ «¬©¹¶©ªªª¢© ¬œ’©¡ ¤¢¦£ªžœ§µ®¨¦ª¢£˜¥¦§ªœ¢¤£Ÿ™™ ‘Ž™Ž‡Œ‡…žž‡„ŠŠŽƒ†”¢šŽŒš‘’‘’Ÿ–˜–‹Šƒt†ytƒzxˆoqggqx\`sˆkO^™VHmxUdVQbPMUTUPOX[bUHPiTVSGPYUI>IHOQPxLMV=<KD?@A<@CUC9AK=5;E13;97*4:=+-341*8**+*,))(/*&)%3;,$2)2021%/2Qb02?f=NX>C,>LT_/Jj6OD;–Ž°¡¦«®š¬¥­®³´¯«¥°ª©º¾»À°®¸­¡¶¯ÉÇÈÑÀ¾¼º¼Â½ºÃÁ¿¿®²²±µ¼»Â±±³«³¨¤µ©¥­³²¹°£®·²¯²¹«¹¯©­¶¬ªž©¬Ÿ¢ µ­¨¡Ÿ¯²¢´ªž¨§ª£«¡¢¬­¨½¯¬®­¢¨¨ ¬™¯¡˜¢ ¨§ž¨›™ª°©£Ÿ­¢¡“¢££§˜š©¥˜—™Š‡•ˆ}†„ƒ£—…‚‚‹†Ž‘„„“ –‡œ“‘œ”—Š†…xt|uxy€{tszi†£ui^ekufˆ‹}RXp]JxsSdSQ^MMRYfNLVYdXFSiRQ?BNQaQ:IHLSIqQLS;<I?;<=;@@W<<?H73CB15:93-5::)-31--6)(+-,42#2)',%.;.&1.0-14%,/Kg:48_=ad?F1CP[[+HN9UA4‘² ¤¦¬¤§¤¬¦´²±ª¤±¨ª¸¾Á»¯§¹ª¦®°ÉÇÈÑü¿¾¸¾¿¼É¼Á¸°°µ±º»¸À²³»­¸­¢´§§¬²¶¹³¨¨¼µ­µ¼°½¦¬¬µ«­œ©¯£Ÿ¤«ª§œžª²¤³¨šª§©¤©ž£©§©½«´¯®©¤ ®œ›²£•¤œ¥¥Ÿ¤›š©«¥ž›ª¡›’›¡¥˜—©¨’˜š“Š‚…~‚‡†~Œ‡Ž„“›“…“¡Œ”’‹‘š‘•†‰~r{y}|hw|zupp}h…x„ˆdahcr…ylfx]]UAVzmTaPRXKKNqu]HZ[gYEUfPD>JNDCA9HGKS?jaJQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11&/>KH0%90%,,09/,,+6'17#-/FjI14X=fcBJ7GS`U*=;DX?*”±™Ÿ ©¥¤¡«¤·²²¦©±§¬¸Á½µ°£¹¬¨¨±ÃÉÉÍÁ¶½¿µ·¿¹È¶Ãµ´²µ±½¸º¾¶­¹¶¿­¡³§ª«°µ¸µ«Ÿ½¼©²¿³» ¯³µ©¬Ÿ®°£œ¤¨ª¢žœ¤°¦° Ÿ«©¨¢ªœ¤¨ ­»§®°® «£¤®žž­¦—Ÿ›¡£œŸœš£ª£šš¤¤•—”Ÿ¢–›—¦«‹ž‘‘Œ‚Š€€{™”‰|‹†ŽŒŠ„’˜‘†”£‰’’‡™“€ˆ|yl}vxxc{zqpqrxh€tjƒgdhanslaio_o?[xlU^OQQJJMTYWM]^lWDX`O^PHMDF;7HEKO<rhKK9AE;;==;;=J49B<3;G<4?18-78;2(09/,5..=-*K>*49&'.34.0+/4&,:$40AhY13S=e_DL6KWeO*<3OY=#“™¬™Ÿ˜§¤¢Ÿ§£¸¯®£¯°ª«¸Âº³­Ÿ¸¯«¨´»ÈËÈ¿·Â¾¯´½·Ä·Ã±¯º²³Àµ»¾·©¹¸½«¤´¨©ª°®¹±ª›»½¤°¿µµ¡®¶µ¦§§±³ ž¤¦§¡¥™Ÿ¬¨©ž ª¯§¡§˜¤¨ °¸Ÿ¤±¯ «¡¬¤œ¦§©ššœŸ£•šž©¦—›Ÿ¨’˜“˜ž“™–¡©š‰Ž‡}‡‚Ž}| ŒŒˆxƒ‹…‰ŒŒ…ˆ’šŽ‰•žˆ”‚‹–Œ‘|…{sp}qst`yxioqpoi~qczliec`f…~_ZsjqKL~hXZMPLJHPRPIN\_nSDX[RgOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23/:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%52<fd24M?e]FO=RZhH*>/YX5(—¦™–­  ¡¤¡·«±¤³´ª¨¹Åµ²® ·¬®­°µÆÈÁ·¿Á¹°´¼·¿»¿¯«½°´¿±½Ã¹©»º·§¨µ¨¨«°­³°§š¾·¥­¼µ¯ž°·°¨¥§°²› ¤ ¤¤¡—œ¯¦¡ž¢§¯¢ ¢“¤¤£·°¡¦±«ž¬£¯˜œª¥©ž˜›ž¥“›š¦ªšœœ¥–•—•Ž”—£¨¡‰Š†z…~„ŠzŽ—Š†x‡„ˆ‹Ž…“˜Ž–˜ŠŽ•~†—‹y€{prwoot_ywdllkihƒmerjkeh\cs_ZlviZH}][XOOJHHRUF29^^lPDXVYeMIIEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<#8R=*113>D5,-'42+;+139cl84GAf[HTDU]hE.;2`T,2–£¡—•œ©¥¡¢ ·ª¯ º¹¦¬½Å³°®¢µ¯¬®¯´ÄĽ³¿º·°³¹¸º¸º®®À³´¸¯¿Á¸¬½ºµ¦¢³«¨©³«®²£œÂ¶¦©¶´©ž²»©¦¦©°¬™¢§œ¤¦”˜¡²¥™ž¤©©œ¢ “¥ ¤¹¨¤§®§¥¡¨“Ÿ©¢¡ ™› ’›œ— ¢«››™¡•’•–š”“£§¤ˆŠ†y„|……|œ‰Š†x€ƒ‡ˆˆ‘…•“’Œ•”“{ƒ—ŽŠw~{ltrllsaxuhhjgeo„ghhdfij`hbifZezcaRsT[[SLIGIOS@!)i^jLCVU^`KIHEC.:B<F<6KPD8:D357==895?:;4>8@L=>93)8><:9*6@3.E4(+,>0-N?.+-7,1195,&.5-80576`tB3CDg[KWGU`hB378cN'2ž¤£’Ž¤¦œžž£µ­§ªº·¨¬ÃÁ·°¬¢´­§¯¯·ÀÀ½±Á·±®²·¶¸·¶¬ª½³¯²±½À·®¼¼±¥Ÿ¶¬¦¥´©«® ŸÃ¬©¦°³«¬´º¨ª«±¥˜ªž§¥‘™¦­¢™ž¤©¡›¢— §¶¥¯ª®¡¡ž¡• ¦Ÿ¢ ™œšœ’šž•¦ž­£˜—ž•”Ž”˜Œ˜š¨ ‘ˆ‰Šˆy…w‚‚‚œ‡‹‚‰{~„ˆ†…„–•‘‘‘Œ’{ƒ•†s~}fxokjlguskcgdctbdefeijcipY^X]ldaMhWZ`VIGHKMRX>9_liGBUS\[IIGFA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A<-5B37=+*,0A*JK./*+3722(57$+7.72685\yN2>HiZLZJVbfA;3AeH%5›¤ ‘Œ® ™˜ –¥´±¢±¾·¡±Æ¼¹°±£¶««®©¹½¼»­À²¯®­¶¯³¸³¨«¹²¯­´¶»¶¯¸½­¦žµ« ¡±¥«¯Ÿ¥Ã ²£®±¯·­µ­¯¬®£™œ§ª¥Ÿ•›¨¥Ÿ™¥£©š œ”›­°¦¹¨®£¢ššž™ž£š¤—ž˜›”š¡’¨•¬©›”œœ’Œ•™Ž””™©§Š‰{‚t‚Š˜…‡|‰ˆ„„ŠŒˆ’…“œ’’‘–Ž€‚ofymhkjgqrk\hdbr€`dgjmlgjhfl\lmuqaTbhceYIFLMOXQPUaeT@VSYUFHFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24:6#3*)6.55465Z|]19Kj[M[KXdd@A1IeC'4“¢›Ž±›“¡š©²°Ÿ¸À¶¡´Â¼½¹±¥¶¯©®¥·¹·¸¬»¯­ª«·ª´¹®¥³¶²¯©±¶¶±²µº¨©Ÿ¶©žŸª¢ª­œªÁ™®¤®°¶µ¬¬ž±­¯ª£›œ£¬¨œ•œ§£š©£¥–š ‘›£«ª©»Ÿ§¤ ˜ššž¡k¢–˜œq‚–œ¤€v‘«¨ž–– ‘‰—™€—‹ y†“Œƒmi~wƒpl†Š†}„‹†o^c`g„—†k‹”’uw‹„~ƒf‡€huifW\isnNPjdfqƒf^dfnli^^_‰…‡hOKD8ETg^JGPPUUKGS`oteE[QUPFHFC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,+08>G701.*.*/668,#1'214:276Xl16Ok[N\K[fb>G1Pd=+/¤™‡•±›œ“ ›ª­«£½Å¯©·Ã¸½¼­§¶°¦«¤¸´²³±¹­ª§­´¦°µ£¨¸·¶©§¬¶³®´­³¢©Ÿ´«ž¢¤œ§¨š­¼•§¥¯³·­­¤¨®ª«¦¡žœ ¨§œ—¡¦¥››§§“Ÿ ™ž§ª£µ°£££–˜˜—£ˆ¡’š‡¡‡”ž¡¥§«ž““œ“‰„rxŒŽ„ˆ¡vˆŒi—ˆf}sx oˆ‡„~|¡ Ÿ™{ˆžtˆŽv›Šl‡ƒmheczlqbT†mcmi˜qXjpn†W^i[kj[ˆpmyr‡i‡„Z^FN>F^MERVWQQRWTg^LYKRRPEGG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82).1<I9/01.*/(-4583%&2115>1<8Xƒu25Rk[N\L\g_=K1Va7/(Œ¦—„œ«œ™™Ÿ«ª¨ª¿Ã¯²º½·À¾ª¤·¯ª¬¦³µ®¯³¶«©¥±­¥µ³œ­µ·µ¦§¨³±­²¨¯Ÿª¡³© ¤¤š¢¤¯¶•¤¦¦¶¼¦¬§©ª¬§¦¢ ™Ÿ¦£™™¦£¤˜œ¤©–”¢œ”“¢¥¦¡·¤¤ ¤˜•“˜”œˆ®˜”‰©‹—£œ…±€¤­ž”šž•y‚Ô¨‡”Á›Çyx±¥·—d€Àœ¿y„„yƒ|‘Êq–¼œÅ{r¶§º{l–±«°yhkX±®oei¼’¼nhzmrØ~Sjc¶²€q”uš¡ªWOWaOVNFT[XQPS‹\W[P@\EQNDGI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22BE/.32.+/)-/186- /416A1=:Wƒw21Tk\O[M^g\>L1[]41!Ž¦“¦©ž—¥­²©±Â½²µÀµ·¾Â«¦³¬¬©¨¯´ª¯¶³¨§¦µ¦§¸®³²¶«¦¤§²®­±¦ªž§¤²¤¢¢Ÿ—œ Ÿ°­•ž£Ÿ´¹¢©¨¡­®¤¢ž›š¡¨Ÿ˜›¨¡Ÿ˜ž§§‘œ§›”¡¦¢ °£Ÿ £––’˜’™…°kjŠª~g„–‡­eqž•š¦•q®¡¤~w»|k¡v±_j´[¥€eœ‘`fzfjxj©e¾rg¦Œv±j|±xt’“cmm§n[„ Eig‡–Euœ`~g{£§‚Y_‹«i€”xzj§7J¯[WTlc[KNW_\WV;NˆOWV/ITSJCEF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3..53/+/(.0.:6/'$203B/=;U‚v2-Vj\OYL_gY:M5_Y31’¢•‚¬¦¥Ÿ£¤ª±·­´½¾°·Å²¸ºÂ§©¯«®©©±®¤°º°¤¤®³£©¹©ž³³±¤¥ ª­°¬¯¦¨Ÿ£¢±¤˜•˜›®§—›¡Ÿ´²¡ª›¡­­ žš— ¢©™ž¤¡œ™¡§¤£š— Ÿ«ž¦§ › ¡–•‘–‘š†µ›µx…©™µ™w‡³›·“–—©•~k¦z…ˆ’”’w«gj±[¬{Ž‡”t‰p†€ˆ—xƒ‚‹—Œƒ …°vwŸqkjl|‹N¤XHcc™~ch¦`yruR“†^P©mcq}†€b.Q¢n[Tkg`LK\dX\ZB>°xWXA#MhFCDA@A19>88:84;:9<9:A:E::;6:CB8=?KNH:5:AFB@AD<FD;0201;F,0.840,.(/3,>831/2-D1<<S}n3+Xj\OXM_gX7J9aU50–Ÿ”ˆ³¦¦¢®©§³¬ª»¶Â°¼Â­¸·Áª¬­®®¦®²©¡¯¼ª¡§µ­£«µ¤¥³³§£¢§ª²¨°¨¥ž Ÿ¯–Ÿ™•–—˜Ÿ®£šš¤¨´®¡©©¨©›ž•˜ ¥©šŸ£Ÿœ ¢¥£•›ž˜š¢ªœ¥š››¢ —“‘““ƒÕ“™¹p°Â~Ɔ|֔›»|š–¥›Œ¤z‡£‚¥‚z¬yU¯{‰~Ÿj¹Z¹w†ƒ}¦‚“|˜zªy{±nŽ„t»…o”O¯§ÅŠQ zc`ªbsr‡l—‡_Sµ´È†€‰|c¤3Bv]QjhdP@XfZdaJHMlKZSOYfZCC?E?0<<59;74<;8=:<C:F:;>6:@C;6@OLH<9;DHCBCD<EF81211DB./0483+-).323971#%5*>3==Qwj6*Yi[K\P_fT7G:aQ82%œ¡“˜±¨¨¥³ª¥´¨¥¼·Á°ºÀ±µµ¼³¶§±±£±³¦Ÿ¯¶¨›¨º®¢¯± ³´° ¤žž§©°©´©¥œž«—™———–—¢«žš—¨­°¨£ŸŽ¬¢§–ž—œ¡¦¢˜¢¡¢¡š¢¢§›ž ž•™š¦ œ§•››Ÿ¡™’•‘ˆ²nhµq«ˆpŽ¦r´sr¶{š˜¤›¢~ ¥~°vƒ‘ÒÑu[®|†¤o›ª¦k†…}­}—™{±s“Žx³e–t…žnžf”RȋZÂ\Ÿyb_­`ws†b—ˆ^Yʝo¿uMKµSUÆdTQjcfXAOj_liPUFI9=WR[WXHC?J<2?;5=<46>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>II:1746@>/.24252-).26,742&60;5:=Pqh9'Wi\BNT_eP5G=aM62/¢‘¤¯¬¤ª»­¦´¥¨¶»¼²»¿·¶´»»³¥µ´¢²²£ ¬°¤˜¦º®¤±°œ´¸© ¦¡ª¥²¨¬ª¥šš©ž–•˜™““£© —“¦«°¥¢–’¬Ÿ¥’”¡œ¥§ •›¦§¡š£Ÿ­š žž–›¢žœ¥”œ–š¢Ÿ•˜–’›…¬{w¨v£Š‡©o­Šƒ¨ƒ™™¢Š’™‹¢~’˜‰®…‚³\r³R®~ƒ‚¤q×}w„~†™šw¯†Š‘œ‡w´ašeš‚•l’Z°XKšu˜yf`­^ww‡g˜ˆj]¯w•žxl5yÈ®²_BTo^h`EPl_pmVUM/eciSYQ;AD@L:5?91=<16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK97<46:>/04333.2..18*.32%!03767=Pke>&Vg\@=V_cN6GC`I:88Ÿ” ¸°˜´Á­¨²§ª²º¸´¸¿º¸³¶½µ¥¸´ µ­Ÿ ©«Ÿ•§¶¬¨°±«­´¤›©  ¨¢µ§¦ª£™ž•¥¡””œ™“–£¦›“§¬¯¥¡•˜©Ÿ¢‘¢š©¦¡•š¦©ž¤ž¬  ”ž›ž ˜˜›–—¢ ”˜‘§†©}}¥y¡ƒªp­Œ‚§†– ¡Š——ˆ£‡”ª|€‹yo±Z¨ƒ‚ˆ ytØv‡t§Ž›’¤|–Ÿ„{²^œd }‚”l’\«[Z“‘hgªds{k˜‡q]¬Z‰ ŽkneOJC¡\ZMt]cfMZa_st_JU5Jš’YHE=HFAL35A8.;>05A78@<6=<F?:<6?=B7.HVJE@H6KIN@IK@EN::@4.;>002154+*05/7,&21($$6671<PeeA&Uf[?1U_bL7FI_C1>8¡œ™™¾¬˜´Â®«­©¦´°¸±µ¿ºº³±·¼ª»µ ±¥ž¥§§ž“ª±©¯ªµ¬ª®¡˜¡ ¦¤¤º¢£«¡—œ‘¢ •”Ÿš”™Ÿ Œ©°¯¦—š§¦Ÿ’¤˜¨«¨”—ª¨ŸŸ £­£ ¡”¡˜Ÿ ’œ—œ•ž¡•—«›®mr´t©ŒwŠ¦s´yt³€’¤£’œŒ‰¤‡Žv¸oŒ{‹¢kk¶Z¡†e——i ¢§m”r´t“˜²j†’ˆ­ku³af¢n†’j—\­`M¡|‡‘Rs£ly~n˜†o\¯V<œwfTon.[§ObSkebmYb\`q|cSYP>>mo3BB@?L9!7@6.;@37C58??3;<CDBJFMIF62JTKEBJ6IJP?HOCFP=<E50;<000/75,+,426/#00,,289/9N`eD'UdY>/U_aL5FM^81B9¤š›»¢œ²À®­««§·©¸¯µÀµ¼±¯¹¸«Á·ª«¡œ§¤¢’«ª§µ£²¨®ª¡—œ¨ ¤«¹£­œ–™¥£–¡œ™Ÿ‘“•«¶¯§™”›¬©—Œ“¦š¥­£‘—«²£ ž¨«°™ ¢˜¢—Ÿ›–›—¡“©œ”‘«™‡Ô’š»t±Ä€Ã†}Ֆœ¸xˆ‘—Œ—‰Œ§‡y£¶u}wv‚š²`ƒºyÀ|u¸bµŒ‡©}–¬©q{u¼ˆ§ ia¦Ž¯¡~Œt‡«}¾ns¼t²ƒux€Šnšˆpm¤t½]w}[ay¼j[V[iy^i`dfbmxoY[YCA@r?CF+5H"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.97-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-7@9§šž¢¼¢—±Ã°­©ª¬±§¸¯¶Ä±»²®»°®Á²¬¥£ž¤¡œ›‘ª¤ª²¤µ§­¤Ÿ–šª™¦¬¹£®™•¡¥ “œ£ž˜žš–’¯¹°«•—£¨§”‘–¥¤­ž‘ ¨« œ ©¤²ž£¥Ž¦¢•¡™œ—•¤˜° ’•ªž…™µ€‘‘¸•x‚“›µwnlnsny„Ž‰sžÁ»¼š{²¨p€t‘¹ƒ|††‹‡{Š†—|¤»¹½œuz³£tv—ut°u˜žf†i¶trpw¶Œ^€z}‰gƒymyb‹¬pu…X[§jDeZTf`c]bQgfqmuBMPLD;ZL>J3<0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITAKNGEOF?G<7>7070/9:.,/-*8/%&2(4$(>7/7KT_G'SbV8*O]]=+;VV'=;<§ž¡¡¿¥–³Ã´¬ª§¬«©»®°Æ¯µ´¯¸§µ¸­©£¢¦Ÿ ™”¬¤­ª¦µ¨¨Ÿ›– £ž¬¤¾¦¡ª˜•œ‘¢›’¡¨¢“—’˜”²µ¶­˜ž¤¤¢‹’’¦œ¥«œ–©¥¦›¢©¦¦£©¡’­Ÿ—£ž——˜žž°©”œ§¢Žj~iœ§x‰s~šŽuze‡{½¾Àºn’ƒq”†_rjZ^š‰ad‡Ž•k`€•cmœvb”kš•”e^`cq›ŠhrŒ}†•gj~qty}|b[wthP\n„}{‹jXly‚rIJo…pMtMEW]faL[Xgc^O[mvjrRODEN;HI<M?2,2A?8/5?C<9;@;=C>RVVWYZ[[\]`aaa`\UG5DFUEKOHFPIIH;8=51:.0;:.0-76=5&"/*2,%;8-7IR_I'S`V4)P^L(3>[O'?2>¨ ¨¡Á£š´º¶£¬¥®§¨µ²¬È¬°³¬µ£¾±²¦ £©£›š™¬§®¤¥µª¥›˜•¢›¦­©¿¨©¦–”›• š“˜¥©§‘ž˜œ°²¿¬›§ž§¢‰“‘ª›¨¤››¬ £š›£§¬¢Ÿª¢š°›•¦Ÿ–”Ÿ—°¥™¢¨™œ‘žœ£¤™§£šœš›š–‚hn|qv‘—”‘„‰´©†˜•ŽŠŒ——‡”•Šƒ’“‘‰‘”™“˜—š ¢››” Ž‚z¤…kj||€t‰Šq‚xyvvŠ€{‰jstƒudw}vkpzm`c\phMYYej_WYpznnfSOFS9OZNRO(+:JB635=@A9:C><ENSSTVWXZZ\]`bba_^^[TKCSGKNDGPLOI<:;389,2;820)6IRO8")+/2#4;*7FO[J'R^S10T^:+=8]K,<-@² ³¡¿¢¤±²· ©¥²§¥°µªÉ«­±¦µ¦À¨´ ž¥¥œ¤–• «§¬££·¬ ™–– —­ª¦ÁŸ¬¤–’œ—ž˜“”¢Ÿž¢§’‘™¨§²Ã¯š««ž––©ž«œ ­˜¡›¢¥¯¦¡¤¨Ÿ­˜—¦šš žžœ° ¢§–˜“™” ¢–£Ÿ— Ž–”‹ŠŽ—­{•›‚’‰©¨…˜–Š„ŽŸˆ{„†…™‡†‰•Ž›—˜ž£–š“‘~f¢³®…‰„vzŠ}vyzogy€‰kuyˆrhtyuƒˆ‚ktcyf`idcdfjXk{pjj\RLPD_UF@??,4@F;45;>A;<?>>HNNOPSUVVXZ\_aca_^]]^]XVJKLBIOMRJ;<:786/2964.(&$-1..)+*7%+<(6CMLD/T]Q05M[17E4\G5<,@³ ¹¯¾­«®²² ª¦²­¢¬³°Å°ª¬£³¯½¤´œ §¢¡™—¨¦©¦¤¦³µž•”ž™™¯¦®¾ «£‘‘žš™”‘•¡œ—©…ž©¬¢³È´ ª¤«––˜š§ž©œ ¤«”žŸž ª®©¦£«¢­›Ÿ ¡š¥žœŸ¯¤™Ÿ¨“˜—’¥š˜©žš—fƒ’|e~Žšcxlhkz£«keš˜~g…Šeeihz¡ŽkhŒ—‘¢wkj‹˜£Ÿ˜slnz„†yXe]…^kŠŠv[hsww‘€‡‚nx‚x€smy„svˆ‰ƒ{j…X^ktd]sˆik|qlc]QNWIdX@J4>F7?FD71<=?AC;;DGHHILNPRRTW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%.++'6*$;'/AI[I/7ZO6)EY/DO1YC;?.=¥Ÿº¼¹¯«³°«¥¨­®°¦®®°½±©¨¤­°±Ÿ­— ¤ž¡š™¦«œ¬£¦¨©³®ž•£¢¯¦¶¹¥®£Žš¡™“’š ™™¥–{¥¬¢¨³Ã¸¥¢§¯Ÿž•ž£Ÿ¤œ¤ª¨’ž¡ž ª¯ª«£ª ¨›¦Ÿ¨¡¬•¡›¥°¤˜œ«–¡ž›“¥˜ž«™ž~¾ƒˆr´r…ž†­hx¹Ä¸q’¡£{¦˜™sª‚|ËÀÀ»q‹¢‡ƒŸ|•˜ˆžÀ½‚–žÁÁ{z‘ŒšÂ¿}k¥±oŒoÊz›x‘ƒŽ€vyyqz‡ow…Œ“ymv’bf_xc_eb^thmdbXLVIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^__`_^^^^___^\SMPGUNA??=6468276*&%#)*&.+*)109*#>H[L*#CP/#F[3PY/UAB;/8–£¸Ãµ°¯À©©”£¯©°¯­¦²µ¯«¦¦¦±«Ÿ«˜›¢ œ›ª§¢«¢¥©¥¤´¤£“¦®¬¸´§¯¢’‘™¥’‘ ¡—œŸ‡¦«¤«­¿À±¡ª¯ª—’Ÿž¢™¢¤ª£“ ¡ž­®©¬¦££¦ ¥¥®©‘¤›©­ªœªœ¬¢–˜¥–¡£˜œΔyz¥‚y•–›_­^Ž§€¡ |§•›t«ƒ€¯^d©z§‡… t—’ˆ³c‚«†¡Ž³j„®t|–‡¸a‚­Y£Ínu{Û{™q~ˆ’ue{‡vvk}ˆn}…’~mŽ`qkpf`_xd[qhjcf`RTRW]JOC5AHED8>6;@?A;=8@>>?BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5578164('$!',&&/(&+360$7;SL+--J0';\:L-!P@F4.1­ÂÀÀµ´°·˜ž‘¤ª©­´ª¥²¬¬¬¤¬¦°ª §›š¦˜œ¢°Ÿ Ÿ¨§£¦¡Ÿ°¬›ž–¦®­±«¨¬ ”’› ¥“ž¥—ž¨£ž®¤«°¨¿Æ³¨©±®–“¢— ©ªŸ•¡ž®¯§ª©›§¦£¡«’­³–¦£«ªž£§¦¡°¡’š§š¡›””‘— p…Œ—u„¨‡q°|r¬~¡Ÿ¥žw«‚}­œr­~«‡†Ÿv˜’z|—~ªˆ¢Œ‘‹~«{ˆ“ €z­VœÄzo’Á}•mupŒmfve†oawnro‰Š‘ƒm‘eosuo`fmd_niinfcWT\aZRRC8II@D<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;91478452&# 1' 1''45-&7>WJ-='>1)3V@F!G:C1.+¯ÔÆDz´Ÿ£Ž££¢­®¶®¨±§©ª¨®««§¢£™¢•Ÿ¦«Ÿ¢¥Ÿ¨¨¢Ÿž°¬˜›–¨§¯­¨§©ž—•š¤¢’”¡­›¦£®¬£¬µ©¹Í²­¦®¬—•œ¢™Ÿ®¬–¡™žŸ©±©©©›«©£¢«›¯±¢¨¬®¦™¦«ªª±£“—£¥š”’…¤j¤u‰z©tz²q‚¥‰™Œpˆ š‡¤_`R«„®‚›u®‚§††Ÿz˜–…{f€£‰¤™†£}©~€”‡®^|¨U¢’z¢Ÿ€{ïŌs¯³³¹qb©¯ÂthŒ˜mš’onxwwnlfedqpf{ic\W_iXXTLLQLCCAB;CA@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^aa`_^]\][SIB6799674,&$" ('"+-"$.!3-&@DWH,G+66*1PKL# A9D4,'ÂÉÕÖÀ¡™«¨¡¯¢Ÿ°µ°®©¬£¨¦ª««©¤¦ ›¥Ÿ¥§¦£œ¬š¢«¡¤Ÿ¯¢ž›“ª¤¶°® ©›–•§¤‘›¡¨Ÿ ¦œ°¦£¨±¬¶È²µª¬ª•’¢™Ÿ¥³š¡”œŸ¦««£®š¬¨¢¡ª¢³­¢ª³²¢›ª¨¯¯¶£“–¤§˜›‘|ªlž„‡u«y|°n‚¤‹‰ –•Ÿ•Ò¸´¸É€²^_”©ƒ¤‡‡ z˜•™xªÉs™£•¨©’›Œ~›‰šÆÆwe¡‚¥sŸŽ‚}¯^oµc±uK£†m§G‚“dž’{p—’~pzt|zm\fjrqfi^aXcm\^YIMMKEDAB>A<B?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75785/)(%&%$&),5FNPPMFLJVF*L0/>-4OTQ;<F2,$¨¤Áƹ­¨²®¬¥¢²¹¬ª¡¥›¨¦ª¬©§ ¦¥˜ª£Ÿ®«¦ ¬šŸ©¥§µŸ¢—“¨«¶²¬›¦œ –‘¦­‘™œ§£ ª§®¡¢¦©°´Â²³ª­¨”‰˜¥›¢£¯¥—¡•™œ¥¥«š¯­¨¦ž¬£·¬¡±¹°›¯§³´³¥•˜¨¤› Ž‚NxšŸz„£|‚¤„†¦žœž“„¸||y¹‚~ÌŶxš ‹Ÿ~š–—Šuž—Š¤™¤¨~°…œ„ž„¬}™”a¥l£p…}—ƒr¬`¤sq€š`¼}RUuŽ‘£–{}’‘‰uyr„~p[lnwrjnZc_hnbd]KLQTAHGFI:9K>B108856877-*5==?BDGILNPTVXYZ[\__^]__\ZZZYUSOH@772.,*.+*'&?QTVWWWYXXWUOUF<E2:P[T6?H,- Œ‡™©¬¤«¹«¯ ›¡¬³´¦Ÿ •¥®®®©¦¦¦š£§¡²®¡©¦² ™¨¤”¢µ¢£•—¡©µ¹¤›£ž£“¢±™žœ§¦¡¢¯®œ£§¢µ±Ã±­ª­ª‘‡‘œ§£¤¥—ž˜™™¥£¨š®¡­¥¦˜¯¥¼­¢··®žµ²¹²³§™ž°¢¤ž†ÑµÃ·y‡Ž…‘“€¦x”¢wŒ ’„¥‚‹q«†„´nri™£œ•‰Ÿ|˜™†‡r®‚¥›¢¦‹“‰”›mp²\¥s“zœl™{™}n©a¢qqŸbs²¸hx“¦˜}‹Œ’‹x|xlhwixsnt\ddnmeh`JZWX<GG@U3@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^``]Z[ZXURRQF:2230/++(@QRTUTSTVWWXXWUVVTQOQ[U%!2AH$)%’sŒŠ®¿¿»»µž—¨¤­¶¡¢™•£©§®©«™¥¡Ÿ¥  µ§¢©§°£”«£Ž¤­£ššª´´¤¦©’•—®  ž§¤œ§œµ™Ÿ©£¶«Â°©«©¢„œ¢¡¦£–™šœ˜›˜¥¤¦˜«§­¢¥›­§¾¬•¾°­Ÿ£°³º¬´§›©²¥¨˜z¨}|°wŠ¤¥ˆœm²o¡‡­|¡ƒ¨–™€¬‰„®…Ÿ”¨ ¢–…Ÿ€™•€{’}«€š–Šªx ‰“’€y¯]£|¦§d€|—tk®]¥kq…™]`[Œ n•‘§™‚”–‹zy–jl~b}tny`feqohghCY`[=JS2U8BBC7$$3+''3, /667436:@CFIKMNQSSSVZ]_a`aaa^][ZXSPONI7052.*,ATVVVUTUUUUTTUTSTWWWXVUUQHFIJ#((¼’š„©ÆöÁ´Ÿ›­ ®¸¥¤Ž›¤£ ¯¯ªŸ£ž­˜ž¹ ¢« ¯ªš­¡ª©¤–‰š®±¬¦Ÿ¨›­˜˜­¢¡ž¥¢š¥œ­˜Ÿ¨¦¶¨¿¯¥©¤ŸŒ€Ž›š ¦ž’”™š”šš¥££™¨««£¤Ÿ©¨¾¤—쪣¢¬³º¬¯§¡´°©«™v¯~‹œ…‡}º­Š˜d°Œe•­} ƒ¦•š¬Š„°…¥™¤¡¢„ [lj³`­{{‚±lgn™—Œˆ±[}´[¤ƒkÈ¢eŸ{¼YvµZ²}R¯€z¬X€¡m—Ž¨šŠ—•–zxœ}ds}aƒxs€|aifpmfeeOUc[AT^=I(>9=4!",%2. *1/04579:<ACFHJLNPPRTWZ^```ab^_\[XUPMJGC553./@UYXWXWWXWWXWVWWWWXWWXYZZ[\XWWGB;ҟ³²·½»´Á³£œ­¦¥¶¨¡‹™ Ÿ³³©ž¢Ÿ´˜ ³¨ª«ž°­ž«›•®©¢Žˆ›Ž¯¬¨¦£¨™®“™©š¡ž¥Ÿš££¥™Ÿ¢©²¨¼¯¥¨ž|‹›•¡ ™‘š›‘™—¨ž¡˜¨­§¥¥£¥©»Ÿ Æ§¥©¢«´¶­®§ ½®­­–©’£¯Ž›€†¤—˜€¸ÃºƒŽœ“…§—œ‚¬Š‚¯ˆ¦›š¥ª‘~սªb£¿½|~£‚ƒ×º¸µ…”“ƒž½¾„j£o«„nz²±Çƒj«°½­xw¢¾»t€•¦œš•œyšyb}zcŒgx{`kekjbPb[Sj\@TaBM)<:4/$%2 $(0496678;>ACFGJKMNNQTW]a\__a^`[\YTQMIC?<A?5=SYYXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ¼•´´±¿¹²½³¢®¦¥³¦Œ˜¥¿ª·±¨¡¿¦¦±›ž±œ¹¨ž­¯¥§•”¯¬—Œƒš‘¯¦£¬¡¥œª¡˜‹£’¦ž§œš¡¨¢™ž «­©¹®¨¤›—“{‡™‘¦›“‘˜˜˜“©™Ÿ˜©¨ ª¦¡£«»ž©Å£ ¯£«³µ«°ª¡¼¨°°štuª¤·†e‰Ÿpg¬Šmow¤™Ÿu®™•pŒq•§£›˜®¤rmmmeŠwnm‚™q€yiqig‰–•˜qhi…†gp†d^‰cjpY]g~w¦`bqŽ’ofd€’Ž¢——˜•ž|‡Ž”ue†whŒjx~ydlcflbKdXJkY:PeEQ'K9+# #,)-2.5:457:<?ABDEHKLMOQSV\WZ\`_a]][TPLHD=:AB7MXYZYYZYXXYXWWVWY]^^]\\\]^]^][[UW^¨”­³ªº¹²³ª©¢®ž¤²©˜’½±ÃȽµ©žÀ«¬£ ¦«Ÿº£¤­¬¬¦Ž–­ªŒ…•—­Ÿ¥ª¢Ÿ££ ‘Œ¥“§™¨™–£ª –œ¥¥§¯º«¬š›“’{„—¥—‘˜”˜•§”ž—¨¢š°¦ž¢­º ±Â¨¤´¦¬±²«®¬¨¹¤¯¸–Š¡¨¥¶‰–¢˜†©š”“ª³™›¢« ²–¢ ž ¢œ ¤¡•«¦Œ’“Œ‡’œœ”™“˜Ž•†¤š—•‹“’Š†„~g‹€tƒvtˆŒq§m|•‘”“Ž” •—• ‚‡“ŒphvoŠwv|zilddocU`Y@iZGb`NY*E=+&"740.!%2(*799469;>?ABDFJKKMPPQWUVY^_ac]^UQJED>9=@ASX[\YWXXXXXYXXZ[[\^__`^^^__```_YY`¥–©ª¥µ¸¯®¢°¤­Ÿ µ±‘Ž«Å¼Äº·ª¡¥›¦°¨£¶§©´¦§‘˜¬£‹ˆ‰œ§–¬¤¡š§žž“•£—©š¨™”§¡¤š§™¡µº¨«˜š|”Œ¡”Š”‘•“—¥ž™¨Ÿœ¶£§­¸¨°Â®£¸§¯¯°­ªª´º¢¯½™’¦£¦¶£’¦ž©Ÿ’Ÿ£¬¯š¡¢°¨¯—¤ œ¤ªžœ—«œ’™¡›“–ª™˜˜––ž‘ˆ •”…’ŒŒ”‹~fŒ‡u‡vyˆƒsœj‡‘””‘Š}Œ–’’˜“¡’œ• ƒ†—†yq•rx‰q{~jnd_pi`[`YmbP`dPZ:GFE=3==7.*&+)&&406658:==?AACHJGJKLMSSSUZ``i`eVPJACB;9EMV\^^[Z\[[[\]]_^]^_`aabaaa`bbbdb\[c˜•¤§£°³¬®£©§­ ¨µªœ¥³º®««¡¢™z¢°¤¥±©–›¸¦£”™©œŽ†Š‰›¢®ž¤–¨ ¡’—™›®‹ª–¨™¨Œ˜¨ž¹¶¤¥˜›‰y“Œš“Š•‘”’–¢Œž¨žŸ¸¤„°¶£±°t¤¿¤² xz «³¼•v®¤ŸŠ€ª~d\bvŸŽ¤ƒ—~n“³œ£§­«¢ež “sy™–p€˜¨—l¢§‰eœ¥›—˜–‹‘›‘…š•‚’‡ŽŽ’‰…xk‡v‡q|†€aiˆ‹•“‹[v•‘ghŽrz¤˜˜ex˜†w—iƒ‰‚nykpe_uokkh\fcbboR[>MNNRG=@TB91/&4:316678<;>@ABFHBGFIKLTUUY\_hfgWQJ<DG;8UR[`ab`^`_`aa_\]___aabcdabaaedchd^]fœ•¦£¡°±¬«©¥©­£§­¤’–«µ¯±¥šª¦«—s‹œ¯Ÿ¨«§“–¸  œ£‘~ˆˆšž«š£•§¢žŽ—’ž…u­ˆ¦š¨‘–£ˆ›º´¨ ™˜‹‰uv“Ž–“Š“‘”Œ“ ŽšŸ¦™œ²–€Œœµžµ’½¨¡~§¢z£¯¸ŽŽ§Ÿ„‹…±©¯Œ‰–¢šy‹¬†œ¢§©¨‡•†˜w¥›z‡›—¦‚{œ±zŠ…Ÿ—™”˜–––„™šcy‡„Ž’‹ƒnqˆzq€††t‡…–’x–h“t št|™ƒŸ›†˜~‘‰‚˜jŒ„jx{qpgdwnilj[ejier[^HSLQ@E5-YTT6)!09=>643568;:=>>@DI@IEJKGRXZX[aahfYQH9EL;>bV^bded`aa`bb_]`aabbbcfgcba`edcgcaah˜£Ÿ¦®®«¨¬ ¨°§§ª¥™”®Æ½°¡–§¨µžƒœ«œ§¢ ¾ž™Ÿš }…Ž™—ˆ«¢• ¡’”‰†€‘§†¢œ£“–†Ÿ¹²§š“…puŠ•Š”›‹‘Ÿ‘–Ÿ¤–ž¬ˆŸ´‰´š®‹Ê‡«®‰·…°ƒ±¯„©§˜|¨r{w›Ž¦–h•¤y´‹Ÿž¦¨’™Â«ˆ˜¡qž€š¤}—…•±¡| “Ÿ˜—€Ž“›‰˜’‹|…“†•“‰ƒms‘†€{r†…}…t…‚—Åf€©‡¢jž‚Ÿ˜™€Š‹ƒˆ˜o’„gwt{vghupggk^bnlflXhG\QL2E46M`c6&4<DGD:64658;8>==>BL?NIJLCPZ]\Wb^jl\QE=KM@JdY]cfhgbbbbcc`_babcccdiicbbbecafcbbi•—¢Ÿ°¨©¨¥« ¤¹±ª«¦š” £¤ª¢–¥©¶£¯ §œ¥ž‰”½™“ ‘yƒ––‘‡«™›šš¡…Œw›œŸˆž¤›•˜—†¢¸­¥™›bm‹“ŒŒ—‹‘Ÿ“Ÿ¡™¡¨~¡§‡­ž –®Ÿ‘† «¯‡¤ªšŒš~£v€˜“k«uM«x‡‘›¨§ª«}ƒ¡{z§iž’kg—†—¶ˆž}m`cXƒ—Œ{dg‹s™}y–l]|—n_Sq„\`lyƒ`Ye‚}„˜q§ªkƒ£nr¥pŸƒgdŸlZlˆzeY_‚~aWPoventrjjo^jolkhWiO]WE9A4GC^k4+ICQMN=84859;6@;;>BO>QRLMBJ\]_W^_bv`MD:MOMTb\\ffiibbdbddbab`cdcabikdbddgdbgeach˜– ¹¡ª£¦¬’¢¶¼«®¢™— ¡¥¬¬ ®µ£¨‘ Ÿ ¦œ™Ž˜´™‹žŒ•‹u”‘Š¦–•—žž~“…†¬¤‡›Š˜¨—™š‘‡¥°¦¢•™ˆ‰€inˆ‡‹ŽŽ‰‹’‹’¢Œ“ž œ¢¥“£¡” wœ–§ƒ¡§€†ª®…¥y‹}„š}¢ps“‡–{žŒym‡›Œ™›¨š‡|‚¢sv¦fž~w¤_˜z|’s¢n˜·´ºt’‡€¶¨dÆ¸{p•·Œq€›¤cs¬«`}j³~n}‡ƒŽ‚‹—q€£ls¤sžƒ~£^™³–o{—ž³tr[ž²‚ibotuqhnYklsre\i^bKD=D5QAYq2<RF_JS=<395::6D;;@IP?TMNQ@E_^[ZX``|dHC8LWUVbaZffkkbbeadc`ab`dd_`cknccddhdbgfchh”–•£¹™¬œ“ Ž¥¸µ®­ ›¢œ££¥­›š±­¬“— ˜ ¤šš”ž«›‹ˆ’x‹…p€–Š “”œ–}‘‰Ž¨¡‡˜Š‘¢“›šŒ‹¨¨¤ž–‡„~k{†~}ƒ‹‰” ‚–  Ÿ‹‰wœ˜¢Œ r¢‹ˆ©ˆœ§‘—¨«®Œ}z ™z£“x€s—ˆŒœ}–Ÿ†›™›¦†£d¡|‰–›lžhšnš™zŠ§}rgsªƒ‚sªg”š]›…v„hªj¸f\©pœa•Œ^§vu‰Šžhšu‡“’˜Žžn™k¦™\¨~w»j}©ZŽ„]³g\nqywjh[pjyyb_fXbAPEN7VBRm4JZZ_NZD@151;;7H?:CGT?YRY]>Db]V`Qad}iEB9N[]XdfXfgnmbbe_aa__``ec^bdoq_deekdcihgki•œ‰ª¶›¨‰c•œ¬º²°¬¦œœ§Ÿž®š°¨«—¢™¡Ÿ™–– £™†‰iˆ€q{—ˆ‹––„’•—ŽyŠ„–£‰”…‹‘œ›‰¨£ š‹‘Š€€i†x–Œ{ˆŽ‡–š“¢Ÿ ¢“˜rhŸŠ Œp’Œ‚©ˆ™Ÿ£© ¨}°­¤¢¸—v£³¢£ˆ”xz«š~¢Ž›—ˆ—r¡|…¯µ}kš‘¡x~˜´££«¨„˜{š|œ™~sªZ]o{—‹xžbM{{…cz—BMŸY¢jr|Žm‰„™u›y‡‰±³š’¦tmq|”o™ri£]•vHec`sp}}md_kiw|ddaR^V]TV@YEQgDRW[bX_ID=B8@B:IE8LDWAVQ[VDFa\Z`K`m~rEC<U_bZejVghlnbff^aa\]^ahb_edvl^egfldelhhki“±®™„S_¡§´º³³©š¢‹›©œœ©“¡«¤¡¨žœš™•˜¡–‡‡‰w…ny•…š‹}‘“•‡r€‰’ œr‘€ˆ˜”Ÿš„Ž¨œš•Š‹Š|ƒl……q¡Œx…ˆ‡’™•|’¤ Ÿ£ˆ®†}µ„ž{¦–z©‚–‹¡ž}§hwm~™s sq|…˜o“‚®}£ƒ¦žš£p^©gu£co¥aœÓ|z™xrsc¢…~¢r¢Žuk³‹`‚˜Šsª²¨¼wƒm¿¦ª´^›o~q—os¢r]£gt¦ah¦m›Ó˜{ƒ›nwy—k›zv—rl©¥g_eyp„jffcnvxh`cS[eQQbIWIT_WS[ej\eQECKLJKBJD8P?PMWSXORQ`eeiRdxywIFEc]dYhjTihjocjg`c`\]]_hbahe|d^dgdkdjmghlh˜›°¬T\K~©°²µ°³£œ˜…˜¦  £¤¨ ˜©‰™—˜“™“’ —Ž‡…{p}„h}ƒ“šw‘Ž‰p†“’l—“|ˆ‘£•ƒŽªš”’Š…‰yƒv‡€nŸ†w€’†ˆ™¢—y“¢¤šŸ‰³¡¢¶‹z¬§¤®¥p©€š…œ’}¤€¢™†˜rž„¢¬®‰—‹€Œ¤–ƒ®¢”vµ¶µÉ¡s”Š€Ÿaž—©my•‡Ÿšu¡‡w }–ŠoLf¢’pšˆs¤{ytaƒ‚l~ lrd`œrt—i{i³µ´Æ¦s˜~{j››«u‚šmtw—išyt˜qPE|³^jvkx‡fjgbtuqnV^TYhPRhIULXRV]gknVgWMJAJMJHJNAQJPecimetrs~x{nu‰{{TPOm]h[kiRjhilglfce_\\\^ibdhk{_]dgcjfoleile¢œ‰¯§…f?”¡³«¯¯µ¢¢€—¨¢¢¤Œ¥§œ¥‚™—–—›’Žˆƒyjy†eƒŒ~– yuˆŒi„…’ƒŒ…zŒŠ”¥’ƒ—©—Œ‘‹€‰z€}Šxp¡†y•‡‰– –”¥¨œ––„gnxœl¢d|q¥wœ˜pg§—Œ{¥z –ƒ—rŸv€‰”–¹nŠ¢b}™¢•ˆnri«ju ln¦`›i‹h–‡š•u¢€}š_‹…Œuoˆbh¡eži›updfˆ‚nr¢Z_[d¡n^‰Œo{srd¥nx¢dg§h˜s‹˜n¡oSˆo ^d§T‹]S˜mmskqmphkxskoRXWWfYSmIXO\HXihsjYkVQREV\LXRaUhj^wuz|p||r‚{rv€„v^QsagbpgPjhhklngdg_]^]`kbjivu]\chcjjslfkmc¥˜¦zetm‹§®¥ª°±¦Ÿ‹€–ªœž¥Œ¢¡š¢¢€•˜“š‹—ŽŠ{‡q€ˆh‹‹|—šstŠ}{eƒ‡•ŠŠ•™‚|ˆ…–¦¢¬…ŠŠ}€€si¥„}†”ˆ˜ Žˆ’ª§ž‰¦x–œ~¥‰–Œ²˜žƒ¯—Ÿ¥x–ˆz©t¥„šn¥¢Œ’„Œƒ¼n|¥¯‚†…†“–œ |¥zq¨” –gž~o¬c–Š•’w¨l©¢‰v‡‚w«‘¦ˆk‘°kv³Œ©l‹†nmŸž’•a«‹ªv€§ŸwŸ}…¤• iš‡v¬gž­Œ¶sw¾Œ¤“Yƒ¦«aurso{tqbj~nhlSV[Uaa]kM]R]I]lmv`[qY[`Zgsenorcqt`w{~yryƒsƒ~{{Œ‚€vbxdcnsdRlgholrifia_^\bkbllzo\\bibljwmglnb•¦ªœ€ž¤–©ªž¨§®£™‰‚—ª™ž¤‰š¥©„‹š…œ‘…’Œt†zˆƒo„}–“tt†r’‚mŒ’‡†”}{„—¤¥¥Ž‰„”u‚‡’olŠ¨€‚‹”Ž‰œŸ‰“«£ €u•—ˆ~y”®£›q†xŒ…€{r§Œq}}z—–›„Žx{~}ˆ”•“Šv™Ÿ ƒz}‰lŒ…[yyryqhn~’‰qt”“q…ƒe_€Œwus”uozon‡m„†_wixŽf‚†Žªœ~t}—j‰ˆo€v|…vmlgŒsx{—w„[jXxhmwrqowxo]l†nigVZ`W\dkdUaU^Q_pwykjvejjju|qrtsaoubs{xuy‚u€€x‹…ƒ}{mldyn^Wnghukxjiid\`ZcjelpunZ[bkdllymhloaŽ•¹¨¦‹¡¢š¦¤™¤«¢ ƒƒ—«‘ ‰š¦š¨˜‚›‹~–”‡Ž‰ˆr‚|}~„z—Žtrƒp•…{}’‹††…x~€†˜¢Œ{§¡‹…„•‚†Ž—wr„©…’œˆžžˆŒ›¨  «ƒ‰Ž•š~~‰–­¨’§xpž‘ƒ{“o~©…p}•qjo|Ÿ‹’ŽŒhm]ƒ‹Œœ›žŽs•‹ˆqtk‚vs€Yrn†}~‹i]icz…ƒˆ€_ix{›|ƒŒƒv†ƒiy‹‡kaqsƒw`sŒ‚‰§•†fƒnv‹ƒp…yoefcy‚z•Z\ifnv[zywtmsr‚f\mŠklbYY^ZYkq[^`Y^]fs}{sosckki{|q{wtdmthl|~uy|{zy€o†Š„{}s~ysiT\qiluougkgd]aXkhkjqrmW[enlgszohjm`ŒŒª°¡£¡šŸž˜ž™©£¡}ƒ—«ŒŸ”‡›¢¥•{—„|’™ˆˆ††Šr}€‹v…‹„–Šqo€r˜†„~’„ƒ†Šz€ƒŠšž‚¦ ‡xŽ—ˆ•‹‹—„ƒz¬—™”Šž‡ˆ¡« ¢¢£Œˆ“›œ£™–ª¡§¦ ’›ˆ—|yŽ„¨~’‘’“œ°¥š”²“˜„¦ŒŒ•›Ÿ‰›‚‰‘Šk|Žvwe‚†Š|‰„‡‹‡ˆ€„ƒw|zuš¢‰‡‹Ÿ‹†•~Œ€vqt†…€xˆ‡Š‘¦‘„†ŽˆƒŒ|‡Š‰vkƒ{y™irh`sŠp}zwvowt]^o‡hn__Z\]SgqUc[[alht{|rnpdkjh{mxqioplf{r€w€}„zm‚Œ†|zx|~zƒxNdvksmpzdkebb`[tfpfrqlU]ltmhyzqgikeˆºŸ–¢¡˜•™˜”˜¤ {™ªž…ŸœŠž–|y”‚{Ž™‰†„„†mx€r€‡~ˆ“„mk~y—†„ƒ~€†„†}‡ƒšœ’‡ªžƒrŠ…’’‹‘}z©ƒ’—•Žœ–††›§ ¢š†ƒ’š™™š¦ ¦—’‹w}ˆŽ…¥{|‘†˜ª¡“œªŽ’€žŒ‰“šž‚Ž—~‡Ž‚ox…qt`ƒ†t‹—€ƒ‚†„~…„”nyuu“¢‹†›……Žt€Š}}rs{‰„{yŒŽ„“§†„‚ƒŠŠŠv…‡ˆ‹|nk}{mhklg^y~g|{vtuu{w\`p}nu`cZ\^QfmSeZ]akivy~pkldkig€€ls€lltoxn„yn†€v‚€}…vq‚ˆ~{z|{‚Š`i{kuhi‚djc`i[cuhobumlTbqyepzzrejmm‹ŠŸ¸š¡¤Ÿ“’–—‹šŸžzw¥›‰†¤”‹˜™yz…|‰‘ƒŒ‚‚m{xr€…}Š|kh|€—ˆˆŽ|~†„‡|š›‘ˆ§œp‹Š‹’‡ ¡Š…Œ|§‘‡’—“–’w£¡¡ž–šš™“Œ›£¡¤š—‘›Ž…y€„‡¡€~Œ|—¤  ’™¦‚›‘‰’—›~’’~‡Žut‚pv`}€…qŠ•|ˆŒr~‚……ŽhxryŒ™’€˜~ˆ‹r‚‡|}qz|Œ…z{’ƒ–¥“‹†‘|…†‡…u‚ƒˆˆzeqzyzpljf^}rh|uus|r€j^`tvpxdcY^^RkhTdX^agjvxqfkclhe€jm~hoqk}w†zk‹r}tv‚†~|z}jrƒnsia‡hlb_qUtomn`xhmWjtvbuz{qbjoz‰Ÿ²’¥¥Ž˜† šœ|u£ –Œ¢Šˆš–x{†‡~ƒ‰~ˆ‚€p{tu‚…~‰xgc|…—Š‚Šx}€Œƒy–€•—•Œ– š}o‹“†¦›‡Œ‰ƒ¥•„’Š•—’‘v‘ž¡¡˜”˜zŽ˜—Ž–›¤ž™“”œz†ƒx…—ž~ŠŽŒs—¢ž¡’˜Ž¢ŒŒƒ–˜ƒ’–™~˜|ˆvq}mzd€|Š…p†“‚l‡‚‰„euo|‡“˜}”xŒ‰|€‡}|r€yŠ‡y…‘Š‹˜¢–‚„Œwˆ„ƒ‚v{‰…u`ww}t}wfkd`~ijvstt}q|ccasnusmaY`^[ldRbW_`hkuy†pcjcmfh|ƒlhthloh|‚xm†q€‚‚t|ƒŒ~z‚ƒ~|mu‰ttmeŠljacuVƒiqn`xflbjvpfy{yq`rl†…®˜¦¨žŽ—‡† “—˜|w©œŠ˜y—œ‹‹˜y|€‹}|ƒ{€‚€xsxzs}€„ˆ‹€d^|Š•‡~„‡t}~Š}˜„–“–Œ£¡—~r‡{“‘Š§ŒŽŠ’ ‘ƒ‘”—‘Š˜ š’’t€’”‰ž§˜˜•—tŽŠl†˜™z‡ˆ‰o—š£“•ŠŸŒ†‚’œ’’•†™ˆ{Š‰zqyjul{~‹~m…‘‚”wp‚ƒ}~‹€drj|—˜…Žt‘‰ƒy‡~vx~‡}„Ž…”¤y…ƒt‰‡}€st€‡ƒmaztzq|oancd{anovrwwstbv`oluno][^]^j^O]Wbahmsz‰k_jejchwˆmflhjmh€|zwn‡s€ƒ„}t†‰z‚}z„}}Žry‹yxnl‡kh_irc‡hqofvgmlazhj|zxpawm‹™šª ¤©ŠŠ‘†ŠžŠ•—}v­˜Œ–}ž“‘–“ˆw~{Š|{€vw€ptszo…}€Š~|`\~‘†ƒ„sz€†z‘‡‘‘›’¤›”}€|Š’¤‰Š—š…‘˜“•Ž‰‰Œ““Œn„‘‰ž™¢¡—–‰—’oŠš…g†š”z‰…Šp–š”¡’’ˆ‹™Œ‚€‘ž|’’‹™Ž{Š„‡tsukqnu|‹tn†‘qt€{‚ˆ|eqmy~š”}…‰t‘‹t‰yo~‡}…Š…–¨{ˆ}~‹…w}po€…ƒchwsupzb^pajt^pjzxxlrpey]mlsmsXZ^_ajZPWXdcgqq‡f]ihfbgqŽndigejh€zwtnŽ…s€‚{u‚ˆ…x„|wƒ…z€‰w‹|{ryƒjk_phtkqnmqgole{bmyvqlwwŠ£˜¢¨¡§›‡ŒŠ†“œt€©”‘Œ† Œ•“t{v…xxrs{…kroym‰v€€†nq[Y~‘ˆ€€€vu€ †Š‘œ— “—w‰~€ŒˆœžŠ†’—•„ˆ”™–‹‹ŽŠŽ„n‰‹‘Šœ–¡›˜•…˜ˆk†¤ƒg†Š‘‹„‹w“˜‘ž‘ˆ‰•Ž~—|‘š’|Š‚ovokmop{…isƒŽ—Šqw€t‚ˆ‚yftov‚š|‰…z•’zw‰tp‰|‡{‹‡„‰œ£ˆ|„w‚‹€xxnj€‚€]rrqppxZ^qaoj^oi|ypmmjmv`pokrmYXaabnXQSYefcup„‚b]kmdbfk’m`gf_hkurrp‹€t‚€xv€‹€y…w‡†vƒ…|‡Œ€{vŠjqc|b†|opltjholvw_q~y{tut€‚¥•š­Ÿ§–…ƒ—•ƒŸuŠŸ“’…ŠšŒ•‹zrxt‚pr…squˆlomumˆwƒ}mnUQ«”‡‚x€vr‚y‚ ‘“’—›‘šx‘zƒŒ’¤š“Ž‰•˜’„†–™Œ“‹‰ˆž…Š|s‹…ˆˆœ™Ÿ›–”€”i†ˆh‡¡ˆ’„‘ƒ‰qƒ‘—šŒ‹w{’zŽ‹Œ‘–Œ|ˆ|€kvjmkklz~ay~Ž•vzwƒŒ|ygtlt‡–Œˆ†{”‘qz…px{‹{‰~ƒ‘žž…|}x‚‹}vpik‚x_womkqrU^pbq`_mnypgpfgsuhpkawe]Ve``rSPN\ed]xpˆ|_\hrbbef’j_hd[gp~pkqsŠ}v|…€tuŒy{…€xˆƒs†…~ŒŒƒ{y•wfrjƒ`‡~ookz`jmtt_t}x†xts…|y¡š±œ¦ŽƒŠƒšˆ€‹žŠ™“Ž„ˆ—ŽŽ„vtvs€po…spqƒojivm‚n}|musRN‚ßɒ֓|ptƒuƒŸ‚’w”˜›˜{“r†Ÿ¡““Š’›”†~–•ˆˆ‘ˆœ€ŽxzŒ~ˆŒŠœ››•“ywhŠ’ˆl‰¤…’ˆ—ƒ†cŒ‘˜Ž”Š–ŒŠ‹q{”‰{ŽˆŠ’‘‰y…{~l{erojkyy[€yŽ€z~~†ŽzzhsksŠ‰……}–Œl~oˆ~„{ƒ–š›‹|wxƒysmfpƒlhtoghslS^oepY_kqxfkjbfxsopc_w``Vk_^vPNL`fc]yq‰t\[ev`aeeŽcafaXissnkqv‹|tz†uv~‹s†{‰r‰‡‘Šˆ|~˜uesn|eˆopl€Zlnyys`vz{vrwŠwyŸŒ›¯› ‚…wˆ•}‰œ‡…Ÿ‘Ž…Œ—„“Ž‡uwpyqn„omn~rddxp|mz}jhlc¤šÁÜ®ï¡skuƒu„¡…‘n•”Ÿ”›‘q†‹£—‰Ž•Š–ƒ€•…‰€’ŠŠ—‡{u‰x†„›š˜™Žv‹wo‡ŠŒ~‹¤…’‰……^‹”—ŠŽ‰Ž‹Š„‰l{—‚}ˆ…‰†v…}}k}cxuimxsWˆz‘†…z~€…Œ~yesj‰Ž‰‚ƒ€Œ—†l‚vn‰‘ƒ‘…‚z€‘–”™ttxˆutqguy‚asloahufR`qgkU^msy`rc_h}qrmZbrabWnZ\wMMLcfa^vsŠm[\dy^`df„_cc^Xjrknkrw‹}sw„ww|ˆqƒ„}~ˆ{t‹ˆˆ–†Œ~~—rguqymŒ{otpXqzvyqdwy†Œiv€‰r€ˆ™¨œ£’„}pŒ”xy‹„…¡Ž|•Œ™‡„{swpsjokil|t^`xv{pu{g`e|ëÚµÉÃ܈sls€v‰šˆi—Žœ”’ˆq†‰ Ž„‹•Š˜”|“ˆƒ‰{‘‹†‚vxƒ„r‡‚’›–”˜†Œv‡q†ƒŠ‡š¢ƒ”Œžƒ‰aƒ•Ž†‰†‰‡€‡i}”}ƒ„‰Ž‚q†~qwgvriswkZŒ}’…|€ƒ€„Š‚vbtlˆŠ‚~€“‘}n‚ly‡‡“„}~’”‘—‰nrzŒ†ulqkrx€_rhn\ju`QerifS_ovt_o`]h‚qriWghciXmW[uLJLef^brs…h[\ey^^dgzad_\YknenjtwŠ~ss~zvz‡s…ƒ|‡wvŠ†˜‚‚{’tkwuyy“uoxz}Xy…q€ogxw’‚dv†…qŠ–…™¡›¢Š†so’‹rwŽœ}Ššˆ‰{Ÿƒ™yrsnodr~iflww[_y{zqqiagaÕ¶Ž¦xnqw{q’Œ‡j˜ˆ›‘‹†zhˆ‹™†’‘†‡˜|Š|Œ~Š…zu{‚zq†€•™Ž“”‚‰u„‡w„€‹“Ÿ†–Ÿ~ˆa“‡„ˆ„‰‚f}‘€~‚‹~m‚|‚tkmvtsvukcŽ…~|„„ˆp_sq…|‚|’‰zqƒf{„‹‡„|…~•‘“„npyŒumnjkz}bgiiXkuZRiribPbrxlae]Zjƒmsb[g_dl_nTZoNHOfd\gnq€lZ[cr_\clwde]\Zlkbmjsv†qo||tx…x…‚|€ˆuy‰’–|‰†v‰oxy{„“on|w^ƒtmizs”sgrˆ}r’‘„šŸ› †‡vv”mv“—}‡ƒŠ™|‹šv~wqoljat|gbiuzZ_x|zmq~echhW^qr–¼Ä„vq”ˆ~r–‹†›’Œ‡rj‰–€{”Œ„›Œ|Š†}|‰Œ”ˆuŠ†vv}qu†ž”…”ƒƒr€ˆu…|Š™˜‡”Ž€ˆf}“‚…ƒ‰‰r}f~‹{y~‡‹Ž|i€|ƒvfoxxsvslj…ŠŠx‚€…ƒk^rxz}Š†|‚~riy„ˆŒ†…y„}˜Œ}nm{‰}wtnhg|vc[pbWnrSSnshaMftxe`]\Xn€osYea^jm`pOYkQDSg`Zknm|nZ[^lcZbowdg\]`liclisvƒqn~|tuƒzƒ‚|‚…v~ˆ–‘xƒŠtˆryx~on|qiyz~ml{u•kjw„tl”Ž†ž˜ ™…ˆn}Œvjx˜Ž~Š‚•—‰yŽ–ozspljd`szh`eqzZar}ygqzaee±²wJbZ¤ÙЖr{Šw}”‹„™‘Œ…nl†“‘zy’†„˜Š|‡xx‰Š„–€pŒˆqt}ziy…ƒ¥„“ƒoƒw„y†œ™”‹“•…‡p{’‚}‚ƒ‰ƒnwh€…xrƒŠ†{e}~„ucprhxpou˜†‚Š|vx€„yk\q~rˆ…‰~†‰{‰rnq…‡……s„z‚™„xno~„€wzehj|p_XvZXplNWqsg`Jlvt`][[Yt}roWg]fjp`oNWhQ?Yf^ZokgyqZZYkeYcqy_h\^emhekiqw‡ol~€uo‚{€~ƒv…ˆ—Šq‚q{†|yy„“Œujzlo~t}or{{”onxf“‹ƒ¡™œ’‚†g‡ƒphz•ˆ}~„˜‰|Œixrklf_anxm_box\dlƒzaqv_eeÔ꾊2:>‹Ž€qx…ˆŽvƒ–Œ~’Œml…Œv}…‚•ˆ|‚xnv‡„ƒ—woˆ…ku{tfy‚ƒ§‹‚‹„}n€tv„z‡‘Œ’“ŒŠ†~{’†w„ƒlrh€~xm|{Šƒwby„qdqh~mtqt›‹€…~su}€sp[muy‹ƒ‹{‡€|ˆxzql‰„„‹r‚z€—‹‹tnkw€€uu\ihwpXV{SZpdL[rre[Ipxo\ZZY]u~thYb[genciLWfQ=^e\]ue_tpZYTodYdqyZh^`gmgilipw}Žli‚„~yn€||‚zu‚€“…p€‹nw~€{{ˆ’‰h{~jt{r†{sw}Œyx„}|kŒ„›–Œ€lŽ~kh~Œz~ƒ”~}Šˆkuqghc[bgrn`alsahp‰zbst^cd› n\5Y¯µti€ˆ|’†u…–…sŠ‰vpl…ƒ‡uy‰x‰|“‡z~sgv‰~~˜oq†~hvymeyˆ„¤‡€‡‰~n~u}Œ™ˆ‚”’™ˆŠ„‰|ˆp{}„{h~lj€{zizv‚‡€r`w~qdrfu‚mu{„”‘|nwy|tmXo€wuŒ‚†xˆv‚‰zxsnŠ†s}“‰ˆznnjn‚‚un]gesqQZzN\o\O\spdUKsxiWYYZaq€t`]]`fdhifNZhN@ad[`ua\tmXWStaZdorWj^bhkgmlipw|’li„‰||p~~{‚zw€Š‹ƒq{‡oqw„{‰ƒj~{nwywŠw}x€‚‡ƒ~~zm…Œˆ˜£„ƒ{vŒykl„ˆx}{‘~Šƒprpcf^Yg_op``gpfjo‰tato[adjv{¾œ¦£È¸q…ƒr’|x†“‚s‘Œ‡rroƒ{ƒtu‡tˆw“ˆyyqcw‡z€“ir„vfwucj|ƒ‡žŽ}rs„y€’‘ƒx–Ž•Ž‡‚ˆ{ˆˆkxy~ugzhlysizv€ƒ}h`w‡}jktg{€iv€‹”~z}~p{v{t~bVw~ssŠ„‚}ƒq‡Šwxqp„‚~y~}vŽ†ƒviqimˆ‚rp]hbrnJduL^nUTZsnbQOsx`RXX\ao‚s[a\heeckdQ[pIDcaZcp^]whUVUw^[enhVk^ajgeoohpvz’niˆŒx}r{~y‚|v}ƒˆ†ƒpwƒrnwƒ‚}‰‹“p€|xyzŒtƒx‚„z€uo~Š‹›žˆ}…zw‡{gt…‹z~{ˆ…„v€gon_d\XeYmr```plkh‰n`siY^dm€w©Ú©Ç†‡²q‰woŒu{†Ž€z“‰utt~w€pqm„t”…xtk`z‚yˆfqƒogvn[m}€”y’“~y{l‡v‘Œ„t–Š‘†……{„luvmgvem{umjwv|`bx…yhtub}{gt†Ž•{t€uqz|mYVt~pu…‡yl‰†tylu€ƒ„~{}y{s‹|sgten‹„ms[j_udHnnLZaWVVxmbPRtvWPUX^aq„o\`cmdd^obT]rGBf_]fh]ZzbQU\u[[gkaVj_`nefkqhpuxŽtkŽu~vx}wƒ{s}ƒˆ‡ƒoqtqu…‰Š{wxƒ||†‡x‡|}~„€{~svyŒŽ ‰z‰vuƒy^}…˜Œy†ƒt…†„w‰{bnm\b[[aVjsc`[gnof‡qaqfW\ck|Ê·¹¡jmmŠlq„q|„‰~{‘…yysyuu{jluc„u’vof^}‚z‹‰er‚kjqcXmz†›ˆ‚‚t˜•x|mˆq‚ŠŒˆr˜Ž‡„‹ƒ{x}qqp}fhqbmxqjkqx}|z\dy€wiuxfvgt‡‹Ž•|q‡jn}yn|]Xrmt‹|‚ooŠqvhw€w}q{u‡|zrfsanŒ‚lrXk_w[InkMUT^TU{kaOTurPQTV^bt…i\`kjfcYnaXbpGAh\`f_]U{]OUdpZ[jh]Wh`_rejhrgprw†xn•Štzw~xƒ‡ur†…‚pp{xwuz†…†Œ…z|u‹~}†„„‡~~}‡|xvyx‘“ Œ}‹mv€ycƒ†–…s‘Šo……zƒtcnkZ_[]]Tgse`YdrrfsbkeW[`ix¾®{ ·mbs†hs{qy‚…{}Œwxrvo{vejn`‡uŽ€rib^xy‹„fq~hjkZVowŠ£„r›”ryt‚n‚’ˆt•ˆŒ‡ƒˆ…}xtrnhy`jm`mvjgjkywzw[g}|xer}m„teu…†–o‹fjzƒumtb\o|ku}Œ|fu‡}nqhux~s}l{{zxpflbn‰~mmVk`wUJjkOQNhMY|hbNUujLPTU^fuƒf]`phgaWi][khJDjZadWYUyYNVmjY]le\Zec^teldqgrouxp™…v~w|…‡}us‚ˆ€•‚nsy{zss…†ˆˆƒx}v|„ŠŽ„‚„{~‹ƒ{w|wwš—zŠ‚†iw}|lƒ„“€r‚p…‚~oflgX][\[Tdpd_WbruiuoeebW\\hpor€s‰ddx~itusr‚„x€„ywtunkzqbgkg†tƒmf^_}p{‰~imwfidUWro§|„|v—‘t|s|zn|{‘…w™}‡…‚†ƒ}tprlgt\lh^ltdgfizo{rYg€vtgp€wubw…Š|”€n‹jmzqfse`mzgsxŠ|~bvƒvjkqt{qzyt}f~ywndfbn†|mkVjbpSKijOKNpG^{faMUtcJNSWajv~e\gsie`VcWbp]LKkXcbUUUsVLXudZ_ka\Zce_wfmbpisnrttšw€w†„z|u‚„~—…nrt|ztq„…€y‹ut‘|•Ž€…„}~Œ†{~€v{£¥Šyˆ†„ku|{uƒ‚Œzo…sy„}ƒunjheV][ZZSbnd[Xarzihlh_bW_[j€iko€gk`hyxjsttn„z}uunzhjyj_enhvƒfeXbwi~‡{oiogf]UXoh©wz|ŽyuppruyŽx•u†‚…‡ujrvghn[ld]ms_gajxh{mZm‚rsjo€~ywaw„„w„rˆqoyrcqi\pxdqtˆ|xbs€pgjxsrlxwuxdƒ{xvpdccn|}klUibfSKlhOGRkEaxgaMSq\JMTYekw{e^mqid]V`VnnWKShWf^XNUlTJ\y_[_k]][ce`zhlaoounoxuz˜}w€z€€‡…zyzƒ~“„qttyvt„ˆ}€|ks•€{‚Ÿ…~‡}€†‚€Š{v„¬Ÿzˆˆƒkr‚zvun†n|s‰€jomddX_ZYZUbjg[Z^ti^mk\aV\\leqt}ii\kvvgtwrm…{}}yurlyhixf]dshzw’€bbTepg‚…wwfhj`WVYgc¨o~w€‹Žzpq~hxoyŒ{wr„}~†ndvsdhh\kb]oo[g_mudzh]t€oqkq{}uuat…Šz‡‡€wruuapmZrtbqr…|uer€lalzoji{yvrf…v{zuqeaems~ilTi^]TKscPGVaGbvgaKToWJLWXgkvzdenqfcZW]YveUJ\cWhXYIWeQHbxZ]_l[^\ad^ij`otxnonvƒ—yr€|ˆ‹…}uu†y‡Œ}suu‚yzz‚‹Ž}~„‰is–zŠ}~…zz|†ˆsq®Œ{{‡}erˆzt}|vro…l{~lzbpobe]eVYYVcfk`]\r„hXomZ^WZ\l{bpwvmbZlssguupl„y~€ywnnteite[gufvv‘y^]Rffkƒ‚t}bci\TX]bc¥hxt‚…xmozhxm{„{u‰s€x|xhevm`f`^j_]skYe]oobze[w{knnowxstdrƒ’~‡‚ˆzvor}sbxd[oqbqq‚|sgr€d^nvidgy{uno‚ut}sqb_fno}djShXYTMw_QJYXHbudaITmSJLZWilq{bllscaYY[av[SLc]XiSWHYaNGiuX^am[[_bb]…hhanxylojvxm‚~€’‡ƒvt‰tŒ†sqwu‚w|}~Œ€~“~pw•ƒ|™’y€€xy~tˆƒsp™¢{z‰”xduˆysxulto~ly|p‘r^po`gblT[ZWhcmf\\q‰eSqmZZXX`lvciuji^Ymsqlsssj…|~|vnnldiqc[jrdtvŽs[WSear€r‚]bc]SZ`[c’Ÿerq…„‘tlkzmop{||qwrzyydeuh]bZ`g[^vhWb]phaw`[{viirnwsrthp”‚†~„vrjp}mfwW\knbqszsgo~[`oqb_jq~llu~sqxkpa\ellzagSgUWRPu[RPYRHctb`GUjPIPZUkkk|emoqa[ZXYlpWSOfWWiSTFZ\OHruX_cmcX``a]‹jcdmyxkoiuy†{kƒ}„™|‚„y}ˆn†qowz}t‚‚|ŠŽ‚‚—tw‚“…Ÿ‰u€€s‚q‡‚uo¢—t{†‹†{ex‹on{ofxpzlsvrŒk^tnagekR][UgallZ\pŒdOnm\VXUgjtgbtee]Yntnpuuyk‡||ˆvsddkna\nmcsx‡kZTVcdx}}q…\c_cTZ`Yc••cnpƒ…Šsjh{ofsws|lztuoy~u^frc[^VadYateU_`mdaq]]~ohisqsptujm„’ˆ{…qrfn}proT[fkfqtwsclvUbqj[_of}fmw}sssjm`Zdjjw^fTdUVPTmWQWSPHds_aFXiNHWTVmhd|ikxkbW\U[tdSRWhQYfTSHZZPMxw[_eliYb`^^nbflyunohvvlƒ}†—{‡Š~k“ˆrgt€{u€‚|ˆŽ‹“r|Š‘…‡Ÿ†{†Œs†s}ƒvn¥Œs‹vwmzŒ`e|pfzsylmqv‚gd{lcfghS_^Ug_lo[^nhNil_TVSogslfxdd\Xptlrzwrmˆ{vœzykaelm^`ojepx~gZVX`lx|{pƒ_b^gVX_Wd›ˆbkq‡}wkkxm\wql{jvsno{€rXjn_Y]UbcXdqbS^ahbblZ`}kfksunmwvkh…‹~ˆzˆmqep}mrmcYaiiotts_ilSeqdTbnbzcqw{vkpmk_Xaght\eVaVSNXeRO\OOHep]cFYiMI_KXmd_xhn~d`T^T]u\TS`fN]aTSJ\YPYuv]_fmhXca[^Žpcgjwqsngvtzƒr‚y‡~|‰‡ŽznŠtls‚t‡„†‘„•y~Œ‡‘›„€|Œ„r€stwqn““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~~~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’‘‘‘‘‘‘‘’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’‘’’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ”ÎÚØØØØښ„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDBN¥¯­­­­®¤Ÿ    £€cggggfo„ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ”Ûéççççêœ~‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR455553A©¶´´´´µ¨£¤¤¤¤§|\____^j‚€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}z{z|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹’—˜˜™™™™’Œ‡‡‡‡‡‡‰““’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†…………†‘‹ˆˆˆˆˆˆ‰ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z{|{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘‹Ž‘‘‰‡ŽŠ’“Š‘ŒŽ‡‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…Ž‡ŠŠ††‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰†‹‹†Ž†‹ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰Œ‰‰ˆ†Œ‰‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}|}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹Œ‹†ˆ‡†ˆ†‰ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz||||}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒ‰Š‹Œ‰ŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzzz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{y{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†……………„„„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰ŽŠ‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{}~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““””””“””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••””•“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””’’“““““’’“”““““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘’’““’““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’‘‘‘‘’’“’“’‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡ƒ‹Šˆ‰‰†……„„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxy}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzop{xy{|{xw{xuwttvtuvwuqrqnprpghklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkigfggghhgmgjghehgccbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__`c_\_]`]^Z^]YY^ba^^ZY_\XWSNMLKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{xvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSSPMJMNPROMPQQQQRVVQQQTPPNNOLJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTttuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMOPPRQPNNONONOOPQONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKLFDFJKKKHJLLLOMLLNOOOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEBA@@CCDEACEHKOKIIJHGJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AE@>:;>><ED=?EA?@A@DEGGGGBDDEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@;;><;;<<HL==AA?BC=ADDFBFFDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnpprttsqrvyy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;:;;99:88;<:68;<>=;;:8:@@AB?A?CFDBCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqtsusqtxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<:79::989:N?8:9:;;8789;:8<;=@A@=;;><==@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyy{}~~~~}~~€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>><==>>=;Fy_;===<<<<;;:;<>=>??A@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLKIIHIKGMmpquutusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CDD?>==@IHCXyoC>CE??@=;===<;:=>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVpoqssttuyz{{|~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???CFEN@:@e~~xrwo>9<9==@=:<;;<;89;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pprrrtuvz{}}}~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPNL>A<<=?>BC??AAAB@M{f@k‡„„ƒ‚zp?988:;=??<;;<;::;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC?Uuyq‚‚|„€rB==?==>CD?;<=>?==>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hloppqtuvy|||||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCE@Uut|ƒƒ|……hAA@C@@?@@>=<=AEABBFHC=<@DCAA?>=@A>>>?<>@DGE@>@A?@CFECBCC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{{|}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@Lss}ƒ…††‡_>CCE@??Na_J@CEIIIIMMKECFGHEGEEEDDCA?@>>BFJJGEEGFFJNNKJIGGHKMJGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@EEfwƒ„…†‡‡‰„KDEDCWu†‰Š~XGHJLLMOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHIHGFEFFFDFHGEEHHFHGHFQnnpqrvvy{{{z}}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJGXt‚„†„‚…ˆˆc@BUt‡‰‡‡†‡‚WILMLMNLJGGGGDGGGGFHFHECDDFEDDHHCCCGJJKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrswwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLLJ[„†‡ƒƒ†ˆ‰}Wl„‡†††‡‡‡‡|PKLKHGFFDECC@ACCCCFFEB@>>@AA@BD?>?DFHDEGIKIIGHIGIIJJIHFJJJJIJIJJJFILLJJKKfopsrtvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKLLIe‡‡†ƒ…€‚ƒ„……„„…††‡‡†ŠuIIFB??@???<<<>::<AA@><998<<=;>;9;?ABAACCC@ABDDBCFHIHHHLMLGIJMMNMJJKKJLMSloqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHHJJJl‡†ƒ€ƒ„€ƒƒƒ„……†‡ˆˆˆ‰‰ŒŽfBB=88::9878896479;<:8567789787689;;<>@;999==><<=ADEHJMLLGIHORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@CGIIi…€~€‚„„„ƒƒ„†‰Š‹Œ‹Š‰Š‹Œ‰T;8656766645763468:876565676778:77789;7589989876:<@GFIFIFEFOSRSSROPPRTepqsttwy{{{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:=ECEv…€ƒƒƒƒƒƒ…‰ŠŠ‰‰ŠŠŠŠ‹‰‰ŠH676468874578467699766765:9:::<898977779:98878589;A=>>BA?AKLOQPQOOORWkrrttuwy{{{|}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897;B9H‚ƒ€ƒ„…„„„„†‰ŠŠˆ‡ˆˆˆŠŠŒŠ‰‰Œz>:88;<=>9:;<89;9:;:99;:9===?;;;=:>;9;;<;<<9;<8::;:999<?<=ABDIJMKJKLWorsutvx{{{|{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<;89989:::;?<W†ƒ‚ƒ…†……†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>BCEEAAAB>@B@@?=>>@?>?@?@==?B?AA?A?=@@@??A=><;:;:9;?=;;==AACABCAXqqtttvy{{|}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::<=:;;==?@B`‡ƒƒ…†……„†‰‰ˆˆ†††‡ˆ‰Š‹‹ŠŠŠ‹Š‹^>DGIKJIFGGDFHGEC@@CECB@BCB?@DHECEDEEAFEFEFFD@B?=@>=?@>???>?>>:;=<`qrttuwzzz}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>???=A@DDEcˆƒƒ……†††ˆ‰‰ˆ‡†††‡‰ŠŠ‹ŒŒŒ‹ŠŠˆWHLMMKNJIKHIJJIECDFGFDCEFDBHIKHGGFGGEKIKIJKJCFCCDBAACBDCCDDCA=;=@hpsttwwzx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLK@BBA98<>;<;>@?A?BCHHJ`†‚ƒ……‡‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹‹ŠŒPMPMKNKJLIIIHJFDGHHIEEHFFELLMIJGGHIJOMNLLMKHFGGEECFFFFDEHHFCA?@Llptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?FGG=<@@87<;<=:?@>@@CFJJPhƒƒ…„…†‡‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒ‹ŠqMQOMLLKLJHGEJIDJHGKJHJGGGKLNLLHHIJMPNPNMOKIGIJHIDIHHFFGGIFCBACUnquvwy{xyzz||}~~~~}~}~~~~~€€€€€€€€€€€€€TDAABGHB?8?@8:<8=>;=A>?@EIKMVsƒ„„„„…†‡ˆˆˆˆˆ‡†ˆˆˆˆ‰‰ŒŒ‹ŒŒŒ‹‹‹‹^QQPMNMKJGFCGJGLJGKOLKJJMMLOPNHIKLOQQPQOOJIJJLJLFGHGFGIFEEB@BB\orwxyzyyyzz{{~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<9@>>@BGGAHLMQWy…ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹‹ŒŒŒŒ‹‹|WURRTROLKJEEFKONOWVQPOQSRMSTOMSLPSUWRSQPLKMMMKNGGJFFHJDDEEBDCcpuyyzzz{z{z{|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?==B?BCFVNFOQQUY|†ƒ……„„‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŽ‹‹‹gVVkaERQQPJ;:QSR`u]UVTVYYRXXRZfPUWZ]RTWQPNRPPPQKKKGHIHEFIHIHIjrvyyzyz{{|z{|}|}€~}}}}}}~€€€€€€€€€€~~THJIIGGFE??AAEBCGEDELXRMTVVX[|†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ}aŠ‹‹‡l[dU:XXXSP>@VUY\d`VYbr^]V]ZVEQYZ[Y_TYgRUVXUTVTOOMJLJIILMKOMSosvxyxwzzz{z{|}|~~}~}}}~}~€€€€€€€€€€~~~VJJIHGFDDBA?HMIMPKIKPTSSXZZ\\x…„…………†‡‡‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~Œ‰Š‹znpXZ[ZRSRVVTZZuƒYU}a\X]^WIV]][[_YHYXY\]YXYWRQMPQMMOSQQURassvwwvxxxz{{|}}}~}~}}}~~€€€€€€€€€€€€xy}YNKIIIFBD@A:PQQWXPPOQSTTXXYZ[n‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡ƒŠ~fYY\XSVTWRQWVc–€QerXZW_hP`fZ[X\hbGOZig\[\]]WSNSPPQVVVVYZnrtwvvtwxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZ[RSQORRRUSVTW_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PVXTRTRQQLOMKfyZ]TYUV]ZLTZUST^ZXWWWzkXZ\\^SPPPINOWVXZZdqsvvttvxyy{{||}}~}}}~}}~€€€~~zxwvsu{€€tk~~kry^[VUSROKFCDAM^ƒlVRSNOQOQURSRRTcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ymqVIKNNKMKHJDFHEC>ScURQQNKRTRMOYQMNQSUUMQSRPNLLHCIHRTUZ\mrvvussw{z{{{}{}}}~}}}~}~€}}~~€~{vsw}~~du}iqt_d]^[YVQLILIal’tPQSNQRQR[RSRQRUUbs{|€‚}{{€ƒ‚…†‡‚†††„†…†u_]KC>CCCCB?DPBD@C>BHGV@HNMG]iPHFOFDEFHGHBCHGHJGCBAD@OPMRdsuvustuz|z{{{||}|{~}}}~~€€€||}€€€}vt{mh|gnqfieeb\XSQPURsWe[OONLQSQUYSUQQTROV`klrv{{xytrnstsyx~~ƒ€ƒƒ‚€‚€‚kLG>>:;>@???>kQKaEFHIEB?GLNGMQUIBE?><=<==?=?ACB?><=B>JMFUnuuustvx{|z}||}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QQZ\Y^IJPQNKLQRQTUUWQQWVPX[b]agmmlokh`nrjmlqu{z}zxz||xwxdB@@A=:BCAADB\]O{NOONKLMOOQMKLWMHG@B<977599=;;;8989?;AH?\tuuvuvwy|||}||}}~~|}}}}~}xuwz{zwyxuw{|yxuywcqhipmnmmhf^OP^\ZIGPRQOMPQNQRTVXSRYTNYZ[WY]^^`e`]^qvk^`gkwooljonnlfbYGFFHBAFIEEFDMRPaWRXQPSSRU[OOQVPMJCF>::6486979:366796<B=ftuvwwyy{}}||{|}~~~{}~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZWMLTTSQQUOLRSTWXTTXQLXYZVXXVXY]WWXhsk]V`tkaa_]d`_^YUPMONLIGJKIHFCQPSZWTTMQSYS\eUOSTRNKIHC?A9988978847578588Gnsuxxz{{}~}}|{}|~~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPXVVSTVOOUVXXYSUTLKTUUUUWPTUWTUR]n^RNY`[VY;DUWT[fJLPRROMMNNNLJFPPUYSTNJOOUST\VRUSRNMLIHHF??=:787659967665Wqqtwyz{|}~}~||}|~}}y}}|~~~}||}}~}|rvqxxruuqqnppopuvtnjddjppqrpnfedc\^RTZVWUTWTRXXYYYRUOJGOPOOMRJOPPPNNOTLMIPPSTU2<XMIAQ=c`QSQPNPQPNNMPNTRPRLILKOQPQRSTQROLMKLLHCBA=:9876;B4566;eprvxy{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqptuvcjgeWhtrrqniihpVVTUXUWURWVUZYXWUQSFEBFGGHFJDHJHGEHLHKIGLMPMG/E_R>3@>joaRRQ@FTQPQPQNQOPOLJLLOPNNPQQNQOJLMMKGEEDB;=<<9=G6676Dnquwz|{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknbePSTRSUOWVVYYVQQQO@>;=?@BAC@BEDA@GHGHFFHJMLDGCORC8ENS]gSQSAGUPOQQPMMNMKLKLNOOQMOOMIMLILKLKGFFED<AA>;@E;<89Tqsuy{{{}||{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLONMQSLTUTWWULLKH=987;?A?==A@B=>EHGDFFIGKJ@FAA@FHEJOHQRa\QPRNSOOOLLOMKMLMON[VKMQOHJHCIJLLKFFFD?BC><BF?B?Adqtw{z{{|{zzw|wy~~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCE=9879?B?;?A@@>ADIECHGIGIEBB?><CBAGIDMOaeQMONWKLMKLMMMLKNNSdMJLRIIIEAHJLMNKGIFBAB@?EFEHDKopwzyy{{z|zwsxtx||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGLMIMPMPPHKE?B=999:?B?<ABBADDGKFDIIGGHCC?B??@A>CECKNQTLJIMTFIIJLJKLIILMOPRPKGCLGCCJJLMONIJIGCCCDIJMLIZsmxyxz{{y|vrpurtyyvxjqnjllnttmsu{stxronqovsnporpopstyjN`gsjt|ygosqjqheqHKCFHHGJKIJLDGB=>=:::;AB?=BBCCHFJLJEIIFGGCC;A@B>@@CECIMPGHKFHKDHIKMHJLHHJLKM]RIHDNGBEKKNMPNKMJKFGGJMNQNLcniwvw{x{z}qmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoijthdoFKCFEGDEEFEGCC@><=:;::@D@>BCEEIFJJLFIIGFFDB;BCC>@CCCEGLNHKNHDHEILNMGILGEFIILNKJHEOICGMLNMPMNNMLIHIORQRNRfgfrosxu{z|lhjoekpmsqfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGICEFEBCBE@DB>?>:;;=:=?CA?ACFGJGIILHGGGFEC@=EEB>ADCCEGHIGMPIFFGKNOKFHJFEDDIIHKIGHPKDJMLPNONOONJJHMRUTROWdaamgprosyzgehhcilgqlflmgiklslpvutpnvrosrsutqssutsuvvvyvutvlkuumrvqlnlerMGEEGCBABD=BA>A=::=?:>>@B?@BEGJFJGIGFFFEDBAAFFCBBBDEDGGHFLQLIOJJLKIGHEFEDCIHHKJHKRMCOONQPOONOOKKKPUWVUTX`^]iaminhrsbeffdihfnifmmhkkmriqvusqmvnoqrswsrstuvvvvwvwvvtwuksunutsqrkksMFFEHBBADD<AA@C<89=>:?=?B?@@DFHEHFFGFFEDCECDIFCFEBEGEEFGEJMKHQMJKHHIEFIHECIIJKMKPSNDQSQQRNOMNPMLNSWVWXVX^[]d`hbjigk_eegcgggkggkmkmlpqgttursnvoqprtxqssuvu‚‘yvvtxuuwxnouorsuqqipzMGGGHBBBFE<@CBD<7:=>;>:@B>??CEFDFDDGECECDEFFJEEIGCGHFHFECFJJGMJLKIJLFIHKHEKKLMNORTOISUTQTPQMNQNMQWZVZYVZ^ZXa```_hec`dehgjihjfhnllnmqpiuuxrrpupppruvpusuvu{~}xvtwvvvwplupmsunorsyMHHGIDACHE<@ECE=8:>><<<AB<?>ABFCEBBHDCDEFFGGIFGKHCHHGIGFDHKIGKHMKJKLHLJMKINLONORUVOKUVTQTQRLOQPOTYZY\ZY\__^`c^\ackb`dghr…hgifjmnponsqjtuxrsstrnpqvrquruus~yŽ}uuvvvvxriuqkrtlqwquKIKHJEBEGE<@GDD@9<>@?>?CB<@>AAFCEDCHDFDGFHHFHHIKJEJHHKHFFLHHHJGLLLLLIMKMNMOLPPQUVWOJVVUSSRQLORRQV[[]^[\^`_a`bd]d`ef`ehjcssfjhglprqossnswwquvtsmoruorspurvrtvuuuwvuwtgtrkqrkrwovIJLILGBEDE<@FDDB;??A@@@DA@B?ACHBEDFHEIEFEIHFIHJLHHJJILJFJKHIJJGKKMMJJMLNONOLOPRUXVMNTVUSRQPMNTSRW[^^_]]``aaa`bdebchbdijgv‹lkigmosqpqpprywruutsmmssmqrotutspsvtuuwvuuteqskpqjrvowJMLKMGDCAD<?EEEC=AACBBCFBCDAAEGCHGHGFJFCGJGGJFILHIJMKMLGKIHLKNQKRQLSMKNNOPPPTOWXX[NSQW\ZSVPNTUTTXZ_bb_da_`b_`eaacinhbihhmxvlhimosrpqrrrvtsusssnksqmprotvrrquvuswywutucmtkopjqtpwLMLLLGDA@D>>DEFC@CAEDDFCCEGCBIEBHJJHIKFDKJGHIIIKGJJOKNLILHJMKZfJd\KlRHON_nUls[qpbwcRPbvuhucav`Xnqbdvinzf\lt`ljT_wvijgifglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqsqyKNJKJFB?@B?=DEFDCDBEEDGBFFGCDJDEJLLJLMGGMJHJJHKJIKJNLMMLLILML[sbdp^llUMNfs]geqlntgpi_aYnnbppbkjjgoqtetno\pugpMJryvkb`keemxmkvlnpsrprqpqrqrrrtrmmsnnoprutqsstuuutwxvutbmukpplrrqzKLIIGED?BB?=BFGBFCEDEEDCHHGDEKGGLMMJMLFJNHIKJILJJJKMMNMMMKNMM[roonpplkMPQlWNibtrpamov\YlQ\mmZqmkomxxtsip\`slqjUuyxpc^kfbgppjioppsspqpqqrrqqrrtlmrmmnorutqtrtuutuuzvutenukpolsrryJKGHEEEBBB=??FGBGDIEEDBFIHHEGKJGMMNKMNGLNILKIJMIKJJKOPNNMLNML\hdu]lqWlNOQmUZk^klvaldtTecNmYl\tpkilxjwuhp]_skhWbcw|oc`ghadityknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtwIMGIDEECAB<B@BFDGFLHECCHKHHFJLLFMKLRRLGMMHNJIHNHJJIHNONNLJNMJZsppoqqmlOQRnYqkgooqqomt^nXat_nopoqronusttj[]tcwxrjnzhaacgbbjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyytukoumtonssvtHKHIBEEEA@>CCBGCHIMIFCFJLIGFJMLFOJKWRKGKJJNIHJLIKJIHJLMMLIKKKSkbZi^_jcrrZ_Yjo_eeUk_c[abQ`lh]j\niid[pfdp]Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunwqrutwsHHFIDEDFA@AEDDGBHJLHFDGKLIEFJOLIOIL[QJFHHKMIHJIKKIHJGKKKKGHJJLLLKIKLNT[\TPTMPONOOVQOOQOOQJJOPQdqiTYW[[\UY[]X]\\cfaafbce__fkmhmtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyyxuvqruovrtsuusGCEGFFAEC?CGDEGCIKLHFDGKLHDGIPKLOKLWMIEEHIJHIKHLJHFHHJGGIEFLHIKNLIO\W^O\[`^OXYS\\b^MYZMXaRKYaZS`d]bX[ddVVX\YZX\VY\^c_d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstxyyxyxwxtqxrxsqrurtOBCDLMBCDBDIEGGFKJKHEEJJJGEHHPJLMJMSIHEAHFJIKKILJHFEJHEFGEEJGCJMJKT_Y`X`a[`UXYT^^Z_RY\P^\YN_\^S[^c_Z]`c`Y_b[`^[TXXZ_^dbbaceiekrpoppnow††……†‚{€……††…†…uqprrsvyyzyyxxxvryvxrqxvtvaSJJMIECBCFGEGGIJJIIDFKKKEFHINJNLHLNGHF>GGLIKKJKKIGEIEDDEAFJD@JKIO[cY^^a_RTSW_`\]Y^QY\MV_WKQY[Q[_aa]^ca`bbbcceZRYVU\[^c`__cebhommllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxXQJFCGEBEGHFGHIFGJGHFHKILDCKJNMLLHJJHJG?GFNJKKMKKKIGHDD@DAHIA?IJGO]aZ[d]_TQRX]\\\_ZKW\LR\YIM^PP]_accccb\dcbdcfXQUTS\X[a_^_aa_dlkmjjlnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMB@IFCFKIFFGHGGJFFFILJNECKJLNJLIKJHIGBHHQMKKOMKKIHGED?EBHHAAGFDT]Y^X_Y_[]UXXP]]QKJW^X^[]VZ`RQ__bb``bb`cbbddbXOQQR[S\^]^^___dhgljnnp{{|~{€‚ƒ„………………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKBAGFDGMRHCRKFHHHEFKJMPEGIIKNLLILKIIGDHKQOMLPLMKKHICEAECHGBAFEBVUE\T^SV_XNTUNZ[MJKU`a[_X_^a]OYb\``_bcb]bbW__TPOPQXR]\\]^_`affelfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDFFGDIRcPDW_IGGHDFMJPPFJIJKNLKKLKJJGEJMQQNOPMNLNHKADACDFDCADEALHCLLPOOLFMFGIJHGLLMOQILOPPSPLQSRUZYWYXXdVOSTPPONPUT\YY[^^aaefchckmqsszy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKM^LGHYMGHJHGNLQQILJKKNNUNOKKLGGKPSSNPONONOHKE`ED_LDfcDM[H^\smOMVmYLCP`UlWgJ]XV^DLQULMTVQRTXWTXUT\TPfZhhdYTkTWVU[\\``abbb`gignlhrz|}~„„„„ƒƒƒ}}zr{z{‚€ƒ„„……„…ƒƒ~z{LIEFFHEEKOTIKG`TGJOJIOMRQKMKLORUROOJLNGHMQ[YOPPNOPOIJPQI|YYrsXPmHqnoaVPqqsPCksmqspSo_[nX]V\XUkhU]VcZ`YZ_VUWjtuu_av_Xb\\f[_aaab^`bgmpl`pwtx‚ƒ„‚}~€vxzlv~tx~€|~€‚„|€ƒz~wwNIEHMMBDLLGILFRVLKOIKRXWQNOOMQTNOQPKLOGMPS[ZTQROPPPJHZx]TxdhYRTQvgtlpbnfkQrOMwmjrpsrqrpop€]ezuxqqzq~s}ku}bRh|essoss|}o~yor```baZa`gknkblfgmw~€ƒ~{xw€tvzir~nt|~wx{~€ƒx|u|||ssNKF`]GAEMMHKKHJPOMMJNV^YULQSNYYLSSRNLPIQRTYWWQTPPPQKGfxlcxqmZJLUypumubnvPdeJfvqmwo€jfxxiWrQhzmijzz}lxzpgoXvvjvup€ash}ilx|o___cb[^bdgijdgbcdllppstsssyqrxblugry{ssuy~svzn|}yxrnNJStNCBEPPIKKJLPOOOMPZ`ZXKTWPa^RVQYSMPISTUXWWPUPONRJKrouuquqdhaVnLqp^FhyWvTKhx}x`y{sna^modRgrunmypwlvstqlm\s~zkmy|lum|kpvux^__b^]_edighee^bbiiijknokqnmjpacfdowxompsynqpj{ztromKK[VHGEGRPJLMKLQQPPPQW\YUNVYUfXRRY^TMNITTVWYWOSNNNQHRmHiwK`dvvUWlOnl{sajgvUKWkh}lmlx`[pz{^`zscroxqhd|ir{]TKl_vukiu{{m~xk|p]^^b[^bdegeeebZccikkrsrwgmihdg`alagsrkhlmr|kmhk{tmmkmOGJKHJHHRQLNPMLTSROSSWRVTPWZVVTTTa`QONKTSSQVVONLMOPJHQNPULKKSTSRTPVUQQNQQXXQNPUTXXX[[USSW[WXWZPSUWWXQ]XV]USOXRWWWXZ`[gr^[\[]^_cZ_cdefdccbYccfffmnmuffgc`f_]g`dlhfgkhpzhggkujhgilQIKKLMKJTRMQQPLVUTPTUXUYURZ]VUTWUYXPOLNWTQNUSNPMLQPKJQRKQMKKORTRQQSSIHMNOQRQQQTVRXW\WSSPQUUVTZQNSRWUTYVTYUSRUSTUXYW^Z_a]\[Z\\`c\]bcdgeddaY`acabihincad^_c]Zd\bma^ffgmsdihkkedcfhPJKKNOLMTQOTQQMXWUTUWWWZVT\`VWVYUXTQPKOXSPNUPMRNKSPMOUTNQNMNQSPTQSTUNKMOQTTRRQVWUYZ[YSURTWWWY[SOSUWUTYUWYTRRWUUW\YZ`]VY_]^]\]aa^[bbchfedbX``b]`hefda^_]]^ZZ_Z_g`^]]bhkagfhfd`bcaPKMLPQLOTPPSQOQZYXWXZZXYV]jdVXYZWVTTOKOVTPOTPPQNMQQPRXTRQOMOSUNWRTUUONNQSUUTTRTXVZ]\ZVVQRWXV[[VPSVUUVXTWWTRRXVUZ_Z^`^V^]^`\\``__ZbbdhhedbYb`b^_fdc`b]\\\\YZ[X[a[^]\_b__bddbd__`\PMNNRQMRSPSTQOU\ZZW[[\YZ[dqmhd_[YVVXRMMVSMNROQROLPSRUZUTPPLPWVQWSSSXMOPRTXUUUSUYX[^]\[VROUVV[[WQSWUVXUSXZTSQYWV\^[__`Ua\`a^`b_\`]cacgide`Zc`a__ee_`c[Z\[\ZZYYW\Y\[`^_[^^a`_b\Y`ZQNONVQPUSPUTSPW\\\X^\_W\^jqwy€c\[VVXRNOWSNQQPRTRLQTSYZWUORNSXVTSTRRZOQSSV[VVWTVZX]^\\^VSNTVV\\VQTVVXYRSY\TRR\XZ]^]aa`Wb[cb^ac_\bab_dgidf^[d`a`ace_b_YZ^[\[YXYWWZZZa\][]\\Z]`W[[ZPOOOYPUUSRWRTPZ]^][`\`U\]ijr}slh\UYWQOR[SRQTRTUTKRVU[YZSOSRVVUSOVRSZRTUTX\WXXSX\X^]Y[^TUNVWW^[XQTUXXXTVX[TSV]Y]]a^cc^Y`[eb_dd^^cca]efidf]^da`abcd_b^XZ_[\[XXXXW[Z\`][\\[XZ[^V^Y]POORZPZUUWVTTT^^`^^b\`U]^bkytl}lZUZUQQS\TTTUTVYWLRZV][\ROUSXVVSPXRSWSWVV[]X[YUZ^W_^Y\ZRWRYXY_ZYSTVZYZVWY\VTZ]\^`a`ed]^]]eabfd^_dc`\gdhedb_da_a`bb_`^WX^Z\\ZYZWV]Z]^[Z[\[WY\]VXW]SOPWYQ]UVYWWUX_`aa`c]`U]^beeuzhXYZTVSV\XWWVVW]XPU\Y^]]TSXRXVSRTXRSVTXXX]^X][U^_X__X\VRYUYZZaY\UWWZZZXYZZXV]^_^cbbee]b\`fbefd_`dbb[fchecfaf__aaaa`_^VU]Z[\[Y\YY][[[XXY[YZZ]_]TY]UNTZVT\TVWYWV\`abcad__V[`da_zuohZ\ZVXUW[ZY[ZXY`WPU^[`a\TUXPUVUSVVRSUWZZ\_^Z_\V__Z]^Y^VSYXYZ]bZ^VWZ[[[Z[Y[YY^_``dcdeebdZbfcgfe^ac`c^cciddg_g^bbcaa`^_XTZZZ[[X[XX\[Z[WWZXW\[\`]V]]SPVZWVZUXUXWX]_badada^YYadb`lfh^\][WXXY\\\_[Y[bVTW^]ac\SVXPVVVVVVSVTX\\_``]a]W`^[^\[^XVXX[[_`\_XX]\]]^\Z\X[_a^`dcdfffbYceehgd^ca`ec]fideh_g^cbcaa`__[XY[YZZXYXW[[Z[WXZTY]\Z`\U^bMRWYVWZY[\YWY^`baeada]^Ybcb_a`a_\\]XW[[]]__\Z]cXYX]`cd_RXYPXWXXXWVWV]]^`aa_b^Ya]]^Y]^YXVW[\`_]_YY^]^^a][ZY\_b_bddefggbZdfgigc_c^afdZhicfice^bbca``_]]ZW[YYXXZYWZ[ZYWXVU[]]]``bbxKWW\YW]\\]ZW\]_`bdbba]`Xcdb`cac^\\\XW[]_]`_][`d\\XZcecaR\YOXWY[ZYWZZ`]`bb`ac_\b]_][_^YYUX]]_`__[Z^^`bc\[W[]`bbcedgfegd\efhifcab\cg`\iibhife`baca_`_]]\Y\YXWXYYW\[ZWWXPXZ]acffrkJYW]ZZ_]\^\Y]\^_acbaa]b[bda_cbb]\[ZWXjq`\`_]\ac_^YYcedaT_ZQYW\]\[Z[[c`cbc`bda`c^`\^__ZXV[_]\aa_][`abeb_]S\_`cddfegfefe^efhhgdd`[fg^ahhbhhfc`b`cb___]][Z[YXXXVZV\ZZVVULXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡…‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vvvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{{{{{zzz{||||{|{zzzzz{{|||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vvvvvvvwwvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{{{{{{{zz{}}}}|}|zzzzz{{||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||upooooppz~}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰ˆ±µ´´´´¸Q&+++*"‹ÛÒÒÒÒÖº}~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}upnoooooz€~†“y1333332j‚€€€{­éääääèʉŒŒŒŒ‹‘»À¿ÀÀ¿ÄIŽïååååéÇ}~}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„ƒ‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}vuuuuuuuvwwwwwwxyyyyyzxopppppprrrrrrrwzyyzzz~ƒƒƒƒƒ„||||||}€€wssssss}…„„„„…‚|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚‚‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vvvvvvyvvvz{x{xwvx{xzyy}zyyxxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{zzzzzyz|}}}}}}{zzzzzz{||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwwy|z{}z|{xwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwww|{z}y|zxxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z|ywwwz{y|z{zwxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚ƒ‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzzz}||}{}{xxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyy{x{zy{xxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyxyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{{||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}|||||||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}|}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrstuttssrrsrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqstsssrqqppnnnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqqrssssqpqpoonnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrqrrssrrqppoopoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpppqrrqqqpopooppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqpqqqqqqpooppppppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqqqqqpppppppppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsquŒ‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqqqpqqqqpqpqpqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrqqqqqrqqqrrqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrssrrrrrstrrsrsssssssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz|~~|vvwwvuxzxxxxwwwvx|yy|zyy|{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~|{{z{|{}|{{{{{{zyxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}|||~|}~~~~~}}||}ƒ€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€€€€‚€€~~~~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~~€€€~~~~}~~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~~~~€~~~~~~~~~€€€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹Š‹‹Š‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚ƒ‚€€€€€€€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒŽ‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒ„‚„„‚ƒ‚‡ƒ‚‚€‚‚‚‚ƒ‚‚ƒ‚ƒ‚ƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒƒƒ€‚ƒ‚…………††‡†…††‡‡‡†††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠˆ‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„ƒƒ‚ƒ„„‚‚„…‡‡‡‡††‡‡‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ’‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚…„ƒƒƒƒ„…„„……„ƒ‚„……‚„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘’’ŽŽ‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€€Œ‚‚‚‚‚‚ƒ€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„…„„…„…†’“‘ŽŽŽŽ‰ˆ‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~€‚‚€ƒ––ƒ€€€€~€‚€‚ƒƒ€€€€€€€€‚ƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“’Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€‚ƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚„„‚}}|‡š˜†„‚„‚€‚‚‚‚„‚‚ƒ‚‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘ŽŒ‡…ƒƒƒ‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒ„…ƒƒƒ‹ˆ…~||}~™š†„…„„„‚€‚ƒ‚‚„„ƒ‚‚„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ……„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”“’’ŒŒŠ…„ƒƒƒ‚‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~€†š‘†|‚‚Š~šƒ‚‚‚€‚‚‚‚‚ƒƒ‚‚ƒ…ƒƒƒƒƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……„……„ƒƒ„ƒ„ƒ‚†””’”’‹‡„„ƒƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~~…ž…ƒ‹€€…€‰ƒ‚„ƒ‚‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“‘Š†ƒƒƒ„‚‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€‚™¡‡„…ˆ‡~„ƒ„‚ƒƒƒ‚€€€‚‚‚‚‚‚ƒƒƒƒ‚ƒƒ„‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†„…ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„‚œƒ€€~~}}„……„…‚}}}‚„ƒƒƒƒƒ„ƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„……………„…†…††…………………………††…†††…†††‡†…………ƒ„„„‡““’‘’ŒŠˆ…………‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…ƒ†‹€ƒ‹}}|ƒ‡†ƒ€~~~ƒ„ƒƒ„„„„„„„„„„„„………„…„†……†…†††…†……‡……†…††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„ƒƒ‚…‡„~…~€„…„…†††…………††‡††…†……†‡‡‡ˆ‡‡‡†††‡‡‡†††††††…„ƒ„………„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘“’‘‹ˆˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒ„„„ƒ€‚…‚‚„‚€€€€€……†‡ˆˆ‡‡‡‡ˆ‡ˆ‡ˆˆˆ††‡ˆˆ‰‰‰ˆ‡†‡‡‡‰ˆ†‡†‡‡††…„ƒ„…†…………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†…†„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡†…ƒƒ…„„ƒ€„„ƒ‚‚€€~{z€†ˆˆŠŠ‰‰ˆˆ‰‰‰‰Š‹Šˆˆˆ‰‰‹‹ŠŠˆˆ‡ˆˆˆ‡‡ˆˆ‡ˆ†‡†„ƒƒ…‡‡‡†……„„ƒ……„……†„„„………†…†…ƒ‰”“‘ŽŠ†…†…ƒ‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡†„„…„ƒƒ‚ƒ„ƒƒ‚‚‚‚‚‚‚€~|}}}~|{|ƒ‡‰‹‹ŠŠŠˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰‡†††‡…†ˆˆ‰ˆ‡†‡„ƒ‚„ˆˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚‚ƒ‚„ƒ„ƒŽ“’‹ˆ…„†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„…„‚„ƒƒƒƒ‚‚‚ƒ~}}~~~~~}}~}}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡‡‰†ˆ†ˆ‡†‰ˆƒƒ„ƒ…„„……†ˆ‡†…ƒ‚‚ƒ…‡†‡††ƒ‚‚ƒ„‚ƒƒ„‚‚ƒƒ„ƒ„‘’‘ŽŽ‹‡„††„‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…‡ˆ‹Š†„†„‚†…€‚„ƒƒƒƒƒ‚‚}|}€~~~}|}}|z|„†‡†„ƒƒƒ„………ƒƒ…„„„„„„…„‚‚ƒ„„‚ƒƒ…†…„‚‚‚ƒƒ…ƒ„„…„„†ƒ„„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰†„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€‚€€‚ƒƒƒƒƒ‚‚}}€€}~~}}}}zzz~ƒ„„‚€‚‚~‚ƒ€‚‚‚‚ƒ„€€€ƒ‚€€€€€‚‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†‹“‘Ž‹ˆ……ƒ‚„‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€€ƒ‚~~~~}€‚ƒƒ‚ƒ‚ƒ‚}}~~€€€~}}}}~}|zzz‚‚€~€~}€€€€€€€~}}€~€€€€€€€€‚€€‚‚€‚„ƒ†’ŽŠ‡‡†ƒƒ‚‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒ‚ƒ„…€€|}}~}~~€€}~}~‚ƒƒ‚‚}}~€€€~}}}|{{{zzyz€€~~~~|~~€~€€~}~~}|~€~~€€€~€€~€€…’’Ž‹‹‡‰…„ƒ‚‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~~}~€€~€„ƒ‚€~}~~€€€~}}}}{{|zzyyy{~~~}~~€€~€€‚€|~~~~}|€~€~~€€~€~~~~~}||}…“’ŽŒ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒƒ‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚‚‚€ƒƒƒ€€}}}~~~~}}}}}|||{zyyyy}€€€€€€‚‚€~€~~~~~€€€€~€€~~€}~}}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…ƒƒƒƒ…„„„„„ƒƒƒ„‚‚‚‚‚~~}}}~~€}}}}}}}}}{zzyyyy€‚‚‚„ƒ€‚ƒ€ƒ‚ƒƒ‚€€€ƒ„‚€€€€€€‚‚€€€€€€~~}|Š“Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…ƒ„…„…†…†††…†…ƒƒƒ‚‚€}}}}}}~~}}}}}}}}}|{yyyyx|‚ƒ„…‚„ƒ‚‚ƒ…†‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚‚„ƒ‚ƒ‚‚‚‚€€€~Ž“Œ‡ˆ†ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€€~}}}~~~€ƒ„‡ˆ„†††…††‡‡†‡‡ˆ‡‡‡†}€‚~}}}}}}}}}}}}||~~~|{yxwxyy€ƒƒƒ„ƒ„„„——ƒƒ„}~‚‚‚‚ƒ†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ…„„…ƒ‚ƒƒ‚ƒƒ‚‚‚‚ƒƒ‚‚’‹ˆ‰‡‰‡††„†…„„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€~}~~€‚………‡†‡‡†‡‡ˆ††‡‡‡†‡…~}}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yxy|~‰–„ƒƒ„„”“€~~…‹€€€„†‰…„‚‚……‹ƒ‚……††„ƒ……ƒ…„ƒƒ„ƒ…„„ˆ’ŽŒ‰ˆˆ‰‡‡‡…†…„…„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„ƒ…„~}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|xyz{|€‚ƒ€ƒ‚€~|~~{ˆ‘||Ž–}‚†Š…ƒƒ„ƒƒ‰~ƒ„……ƒ…†…„……ƒ„……†„„Ž‘ŒŠŠŒ‰ˆ‰‡………ƒƒ‚‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚€‚€~}}||}}|||}||}|}}}|||{‹‘—Œz{|zzz{|yy}}~€€|{{~~}‚•‘„ˆ~|~‚„||‚„‚€‡ƒ}‚‚‚€ƒƒ„„„„„‚„ƒ„…‚„‘‘Ž‹ŒŒŽŠ‰‰………ƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚ƒ…ƒƒ…………ƒƒƒ„‚‚ƒ‚ƒ‚‚€€~~}~}||||||||||||||}|||~~Š‚{z{zxz{{|}{~}~}}}}||}†~}‚~~~€‚||‚€‚€~|{Š‚}€~€€‚‚€€‹“Œ‹Žˆ‡‡……„„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ……†‡„„€†”ˆ€‚€~~~€|||||||||||||}|||||||y{{{xxy{zz|€~|~~}€‚‚€€€‚‘€€~€~~~€}}}{}}}|}||}€€€~€~~‚”‘ŒŒŽŠ…††…„„…ƒƒ‚‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚„†‡††~ˆ•Š~€€~€~~~|{{|||||||||~}|{}|||{|||zzy{|z}…ƒ‚~~€~…‚~€~~€…†‚€~~ƒ†~|~€€€~}}}}~{|}€}~€Œ‘ŒŽ‡„††…„„„ƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}~€‚ƒ††……~€€€~~}€€€€}}||}~}||}}}}}|~|}|{}||z{z|}}†„‚€€}~}~~‹„†~}||~‚}}}}€|{}|~„ƒ€~~~~}}}~€~~~„’ŒŒ‹Š†„…„„ƒƒƒƒ‚‚‚ƒ‚ƒ‚€}|||}~{{}w~vx~}|}|}~~‚ƒ€z}}|~€~€~~€€€€~~~~~~}~~}|~}~}}|{|||z{z}~€ƒƒ‚~|}|}||ƒ~Œ~|{{}~}~~}{{{}|z{{{€†„‚„ƒ‚€~‚‚‚‚‚€ŠŒŒ‹‹Šˆ„„„ƒƒƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€~€€€}€~~~~|‚~~}}}{{}}|z||~€‚€€€||}|||||}|~{~{{{|||}|{{{{||zz}z~‚~ƒ„‚‚…†……‡†‡†„‘ŽŒ‹Š‹‡ˆ…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~€€‚€~~€€~}ƒ||}}|}}}}{|~~~~~~~||||||{~~{|{||||}|}|~|}|{{{|y{|{{}{}~~€€ƒ‡‰‰‰‹‰‹‰…ˆ‘‹ˆ‰‡……ƒ‚‚ƒ„„ƒ‚‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€€~~~}€€€€ƒ‚€€€€€€€€~|z|}}~}}~~Œ†}}~{{ƒ‚}~~}}|}}}}}~|}|}|}}~|~}}}}|{{z|{||{z{{zzz{~~‚…ˆ‡ˆŠ‹‹‹‰‘Ž‰ˆ†…„‚‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„„€€€€‚~}~€~{~‘Œ|}Š€Œ~~}}}~}}~}|||}}|}|}}}~}}~~|{{{||}|{z{|yzyxy{~„ƒ„‡‰Šˆ‰Ž‹ˆˆ…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{|||~~}}€€€‚…ƒ„‚‚‚‚€€ƒ‚€}~€~|~ˆ‚~ƒ„„ƒ~}|‡}}~}||~|}}|}}~~}~}}}{|}~||{|}zzyyyy{{~~€ƒ‡„ˆŽŠŠ†…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{|}}}}zx‚€‚‚€€€€€‚‚‚‚†…„‚ƒ€‚„~€}~~}~€€}~„€~~}~}}Š…}~}~~€}}}|~~~}€}~}|}||{|}{{{zzz{{|}~}€ƒ€‰Š‹‡………„ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv~€ƒ‚‚‚‚‚ƒƒƒ‚…†„ƒ€€€€‚€ƒ~~€~~€~}~~€€~€|€~€~|}}|~~~~€}‚€|}€€}{}}}||{||{{{|{|||}|ŠŠˆˆ…………„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€ƒ€€€€ƒ~~€}€}}~~€€‚€€€}€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{|~|}|||z|{|~‰††……‡…„…„‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz~}yxut€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚~~~€}~€}}}~€€‚€€€‚~~€€€€€~}}}~|~~}}„€~}}}~}~~}~|{|z|{z€‡‚„„…„„ƒ…ƒ‚‚‚€€‚‚ƒ‚‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xyuu}‚ƒ‚ƒƒƒƒ…„…„ƒƒ„„ƒƒ„‚€€€~}}~€~~~€}}|}}~€€€€‚€€€‚€€~€~€€€~~~~~~~~……€€ƒ~€~€~}{z{z|{z‚„ƒ‚‚‚ƒ‚„‚€€‚€€‚ƒ‚ƒ„ƒ„‚„‚‚‚‚~€~}~~~~}~}}z{|…„{{syz|pwuvwyutz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€€}}}~€}~~}~|}}~€€€€€ƒ‚€~€€€€€€€€‚‚‚€ƒ€ƒ‚€€|{{z|{|‚€‚€‚‚€~‚‚ƒƒƒ‚„‚„‚€‚€~€€}~~}}}~}}{{z€x|vyy{qtxwvxury……‚„„‚„……†„„‚„ƒƒ€€~€€|}}~€}~~}|~~~~€€ƒƒƒ€€‚€€€€€€€€€‚ƒ€„}ƒ„€€‚}z{{|||~€|}}€€~}}€~‚‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxyzruyyvwwsu†…ƒ……‚„„…„„„‚ƒ‚ƒ€~€~€}}}~~€~~}|€|~€~€‚ƒ€€‚ƒ„‚€€‚€€€‚ƒ‚€ƒ€~‚‚„€€‚‚‚„‚~{{||||}}~}z~}}x~|||~~~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„‚„„…ƒƒ‚ƒƒ€}~}}}€~~~}}€€~|~~~‚‚ƒ‡…~~€€€€€€‚‚€€~€‚~‚‚ƒ‚ƒƒ…‚}}}|{||yz{z~y{yx~{{{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst†„„…ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€|€€~€}~}~€€€~|~€€~}~~€}€€ƒƒƒ~}~~~€€€€‚€~~€‚‚€„‚„„†„€~}||||zyvyyzyvyv~|{{{~}{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…„ƒƒƒƒƒ‚‚ƒ‚ƒ‚~€}}}}€€€€|€€€€|€}~~}~~€‚‚~~}~~~~€}€€€~~~~~€‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{z{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvpxyrx…………ƒ„ƒ‚‚„‚‚€‚€~~~~€~}~|€€€€|€~€€€€}€~~}}}~€‚~~~~}}~~~|€~~~‚~~€€ƒ‚ƒƒ†„€~|}||{|xx{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}|{|z{}zzx{|zz{xtxuqrtpxxry„………ƒ„ƒ‚ƒƒ‚‚‚€€€€}~~€}|~}€€€€€|€€~€~~~}}|€€€€€~~~~}|~~|}€~}~€‚~€€~„‚‚ƒ……‚‚~~|{{||yw|ywxwwx{{z{|…Š}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzz{zxswuqqrpxwq{…†„…ƒ…‚ƒƒ‚€€€€~~}|~}€€‚€€}~€~€€}~|}€€€€~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{|||zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚‚€€}}~€‚‚}~~~€€€‚€€€~}~|€€€€€~}~~€€‚€€€€€€€„‚‚€~|}~~z}…~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚€€€€€€~}€€‚‚€~€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€€‚€€~}~{“z|}|{}y{zzxyxy{||}|||||||}}}||}|~}~~~}|z||{|}{yzzzyysuuooqpwst}…†ƒƒ‚ƒ‚€€‚ƒ‚€‚‚€€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€€‚‚€€€}~~|†‰||~{{~yz{z{Ž~wwy{|{}||||{}|}}}}|}|~~~~|z|}{}}{yz{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€€‚‚‚€€€€€€}~€}€ƒ‚{~~{|}{z|{{‡yxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ‚„„€~‚€€€€‚~€€‚€€€€€€€€€~}€€€€€€€€€€€€€€€€€~}~}~~{}|}{||wxuxxy{||}|||||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒƒƒƒ‚‚ƒ€‚„ƒƒ„ƒ€‚ƒ€€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€€‚€€€€€€€€€€€€€€€€€€€€€€€‚ƒ‚‚€‚‚€€€‡~~|z}|{}xwvyyz|}||}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚ƒ„„€€ƒ†ƒ„ƒ‚„€„ƒ‚‚€€‚‚„‚‚„‚€€ƒ‚€€€€ƒ~€ƒ‚~‚€€€~€€€€€€‚‚€‚‚ƒ‚‚ƒƒƒ‚€€€„}}}|}z}zyvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysruowqwysw{…‚‚ƒ‚ƒ„‚ƒ„ƒ€€‚ƒ†ƒƒƒ‚‚„„ƒ‚€€‚„‚‚‚~€€‚‚‚‚€€€€‚„€~ƒ€ƒ‚€~€‚ƒ‚€ƒ‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ‚€‚€}€|z|{{w|yyy{z}~}||||}~~€€€€„„€}€~{{{z{ztpxrytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚‚…†„‚ƒƒƒ„„„€ƒ€ƒ‚‚‚‚‚€‚€€€‚‚‚‚‚€ƒ‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚‚„ƒƒ„‚„‚ƒ‚‚‚‚ƒƒ„ƒ„„„…„…ƒ„‚ƒ‚‚ƒ€€~||€||x|yzyz|}|{||}}}||€€€€€‚~€€€€{{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚ƒ†……ƒƒ‚ƒ„„…‚‚‚ƒƒ‚‚‚€€~€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€ƒ€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒƒƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{~~}y|zzz}}|}z||}}|z{~~~€€€€€€€€}}||}|vrvxxvtvu}‡‡ƒ‚„…ƒƒ„…„€‚……„„ƒ‚ƒ„„€„…ƒ‚‚‚ƒƒƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚‚‚ƒ„‚‚€€‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚~ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz{}€}||z|~}}}}~~€€€€~~€€€€~|}}~~}|{xvvw„‡ƒ‚ƒ…ƒƒ„†„‚…†…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„ƒ‚‚‚ƒƒ‚ƒƒ‚‚„„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒƒ„„„„„…„ƒƒ„…„…„ƒ‚€}‚}||{||€}}~€~~}~||}}}~~~€}}~€~~}}}~}}~~|}€‚‚ƒƒ†ƒ„ƒ†„‚ˆ‡…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒƒ‚‚„ƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒ‚‚ƒƒ‚„ƒƒƒ„ƒ„„„…„„„…………„ƒƒƒ}„€}}||||~~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒ„…ƒ„ƒ…~‚Š‹…„„ƒ‚ƒ…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ…ƒƒ……„……‡‡†‡…„„…„ƒ~~|~~}€~||~|z|}}}}}~~~€}}|€€~~~~~€‚€……„ƒ„„‚„ƒ†€‚……Š‰„„ƒ„……ƒ‡††„…„„…„…„„ƒ„ƒ‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ„}uyƒ€~„„‚ƒƒ‚ƒ„ƒƒ„…ƒ„…†„…†}„y|~ƒ{…ƒ„ƒ€}}~}~ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚‚ƒƒ‚‚†„„ƒ…„ƒ„…ƒ„…„Šˆ………ƒ……„†††ƒ„…………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†tpurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚……‚hzrss|€s‚ƒƒƒ}}~~}~‚ƒ‚|}€}}||||}|||~}~€}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ…ƒ†ˆ††…ƒ††‡‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vyy…r„ƒpvxqvtturstvi€nrotvnulwm{sn€‡ym}rsvsvmmxlpylu}}~€}€}€€}}|||}|}~}€€€~|~€‚€€€€€€€‚ƒ‚ƒ„…ˆ††€‚…ƒƒ„‡†ƒ………†‡‡„ƒ†‡ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoomw}x†pqzprtfu~n{ysoy€}}€|}|€~€€~~€€€~~~€~}€}€€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„†……††ˆ„„†‡ˆˆ†‡„††‹Š…„†‡‡…ƒ………„‚†††…†……†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„qjoyxpkyszozwvvp€~~~z~}}}~}€ƒƒ€‚ƒ„‚€€}~~~€~~‚€€„‡†ƒƒ†„„…†‡†…………‡†ˆ……†…‡‡…†„††‰ˆ…„‰Šˆ†„††……ƒ…†…†††††…ƒx‹yrˆz{pp…„x…xyks~y{krƒ‡ƒz|m{yyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozls|nw‚€~~}}{}{|}}~}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡…………†‡‡ˆ†„†…‡††…„……„……†‰Š‡……†…††…††„†††††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„…†…†„†„ƒ„„†„„ƒƒ„„…„…„…„†ƒ†‡…†„„…‡†„„…†„…}w…ƒ„„‚}~{|{~{||}~}|~}€€}€~~~€~~~~}}}~|{|~||‰†…„†††…‡†…………††‡ˆ†„†…††……ƒ„…†…„††††……†„…††††„‡†‡‡†…‡ˆˆˆˆ†„‡…††ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…ƒ‚……†……ƒ…„„„…„……„……ƒ††††…„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ‚}€{{|}{||}~||~}€}€~~€}}|€}~~~~~||}~{|||{{~ˆ‡„„ˆ†††‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡…††……†„…††‡‡…‡†‰ˆ††‡‡ˆ‰ˆ……ˆ…†‡†‡†‡†‡…‡‡†‡……†‡…‡†…‚ƒ…††„„ƒ„„ƒ„†„……………ƒ††…†……††…„„……ƒ„‡…ƒ‚‚…ƒ„~€€|{}~{|{}~}||~}~~}~}}~~|}||~~|}€|||}|||~z{{|~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†„…„††„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…‡‡…‡†‡†‡…ˆˆ‡‡…††‡…††…„„…†……„„„ƒ„……†††…†„†…†‡……††…„ƒ„„ƒƒ‡ƒ„‚„„ƒ€€€{{~}|||}}|||}}|}|~}|}}||||}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††ƒ…†…†††…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡…‡††‡‡‡…‡†ˆˆ‡‡…‡‡‡…†‡„‚„ƒ„†…‡…„„„„„…†††††…‡……‡…†…‡…„ƒ„ƒƒ„‡ƒ€‚ƒƒ‚‚‚€{}~}{||~}|}}|}{||||||}{{{}|{~}{|}}|}}~}|zz{{||ˆ‡‚††††‡††…ƒ…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡‰ˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡†ˆ‡††‡‡…‡†ˆˆ‡†…‡†ˆ††‡ƒƒ„„ƒ††‡……„„„…†††††…†‡††‡††„†…ƒ„ƒƒ‚ƒ†ƒ~‚‚ƒ€ƒ‚|~~||}}|}}|}z{{z{|||{{{~{{}|{{~||||}~}{z|z|}‰‡ƒ†…†…††…„„……………„ƒ…†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…‰Š‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……‡ƒ„†…„††‡†…„ƒ……†††††…††‡†‡‡…ƒ†…ƒ‚‚‚€ƒ…‚ƒ~ƒ~~}||}}{}}|~zyzy{|}{{{{~||||z{}||||~}€|{{{{|{‰‡„†„†„††…„…†…„„ƒ„‚€ƒ…ƒ‚z„Œ{€„…‡†††…„‡ˆ‡†‡……‡‰‡„‡…††ˆ†…‡„†‡ˆ††ˆ‡‡‡†‡ˆ†„†††‡……‡ƒ„…„†††‡…„„ƒ……††‡††…†††…††„ƒ„…‚‚€ƒƒƒ‚}€~ƒ~€||}}~}{~}|}yyzy{}}zz{{}|}||z{}||}|~~€|{{|~}|ˆ‡…†…‡„†„……………ƒƒƒ€‚…‚€}|{„…††„…„ƒ‡‡†††…„†‰†‚†„†††……‡…‡ˆ‰†…ˆ‡‰‡††‡…„†……‡…„‡ƒ„…„ˆ††‡……„‚……†…‡†‡„††††…†ƒƒƒ…€€€€ƒƒ€|€~~‚€}€||}~}~{~}||yzzyz}}yzz{|{|{{z{}}|}|~~|{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€€ƒ~~~€yz}€ƒƒ„‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ†…ˆ‡‰‡†…†…ƒ†„…‡ƒ„†„„…„‡†…†…†„‚……†††††„…††……†‚‚ƒ„~€€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|z{{{|}}}|€~}||}~|{‡……††††„…„…ƒ…‚€€€€~‚‚}}{‚ƒƒ…†…„ƒƒ†ƒƒ„‚€…‡…‚ƒƒ…„„††‡ˆ‡……ˆ†‰‡…„„„‚…ƒ„†‚ƒ…„„†„‡†………†ƒ„…„…†…†„ƒ„……ƒ……€ƒƒ~€€ƒ|€}}‚}€~~~~~}}{|{zyzzyzz|yzz{{{|z{{{{}~}}€}}||}€}|†ƒ†††††ƒ„ƒ†‚…€€€~€‚|~~€€‚‚„…ƒ‚‚„€ƒ‚€„…„‚€‚ƒƒ„……‡†…„†‡…‡††‚ƒ‚‚ƒ‚‚…ƒ…„…†„††‡††…‚„„ƒ„†……ƒ„ƒƒ„ƒ…„€‚‚}~~~„~{||€}€}}ƒ}~~}}~{~{{zy{zyzz{yzzz{{|z{|{{~~}|}||}€~€†„……„‡„ƒƒ‚†‚ƒ€€~~€}‚|}~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡†…„ƒƒƒƒ„……„ƒ‚ƒ‚„ƒƒ€€~}}~~|~ƒ~|~||€~‚}‚|~}}|||{{zzzzy{zzzyyzz{|y{}{|~€}~}}}€€€†„„…„…‚„‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„…ƒ‚ƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚€…ƒ~€~|}~}|~ƒ}{~|}€ƒ}}€~}|||}{{zzzyy{yzzyzz{{{z{}||‚€~€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌËËËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFK=8765999<>9?<D:;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937677=;>9=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<9<<98:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA><A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËÊÊÊËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÒÓÔÔÔÔÔÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9?CE@<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÐÑÐÐÐÐÐÑÑÑÑÑÑÑÍÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø×××××ÛÛÛÛÛÛÛÛÛÛÛÛÛÛØÖ×××××××ÖÖÖÖÖÖÓÒÓÓÓÓÓÔÔÔÔÔÔÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILO@99:4;A<7=9AC>@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌ͖„†††††‡‡‡‡‡‡‚²âÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¹´ŒŒŒŒŒŒŒŒŒŒŒŒ‰¢¿¼½½½½½½½½½½¼¿ÒÒÒÒÒÒÒÓÓÓÒÓÓÓÜãâââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVN<::77>C?8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÎnPSSSSSTTTTTSL óëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§£££££££££££¤œZUVVVVVVVVVVVR|®ªªªªªªªªªªª¨°ÒÒÒÒÒÒÒÒÒÒÒÒÒÑàìëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;?C>6:7>>;=B?9<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÌÎqTXWWWXXXXXXWP¡ñééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤¥ž_YZZZZZZZZZZZV€¯«««««««««««ª±ÑÒÒÒÒÒÒÒÒÒÒÒÒÑßëêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;?@@8:;8<;;<?:;;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÎx^a````aaaa``Z¤îççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©ª£hdeeeeeeeeddda†²¯¯¯¯¯¯¯¯¯¯¯®¶ÒÒÒÓÒÒÒÒÒÒÒÒÒÒßéééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB>;=:9;:==;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÇÅÅÅÅÅÅÅÅÅÅÅÅÄËÐÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÏÎÏÎÎÏÏÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÑÍÌÌÌÌÌÌÌÌÌÌÌÌËÏÓÓÒÒÒÒÒÒÒÒÒÓÓÒÔÔÔÕÕÕÕÕÕÖÕÖÖÖØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<8@B<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÏÏÏÏÏÏÏÏÏÏÏÓÏÏÎÌÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÐÔÒÏÎÑÕÔÓÎÎÓÓÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××Ö×××××ÖÖÖÖÖÖÕÕÖÕÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖ×××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?79:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÏʖ¥ÑÓ­ƒƒ•ÏÒ¤¡ÐÎÎÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<>B>BC@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÏϜª­Ëšº¸™µ³Ÿ¡©ÒÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?>;7:>9?D?A98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÐ˔ˆšž¼¢Œ€Åž˜•œÈÐÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<<:6?B@B:647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÏѽș›¬ ˆ¬Öº™¡°²ÓÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8FA?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÏÏҗ”¢±¨­›¦²™–¯³ªÕÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<>=964:99::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÏÓ³›ÄšÁ¢•§š„“¤ÕÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:=?>=<9@<<::9?@>=<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÐÑ΍žÄ§´«Ÿ ©…™¤ÕÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CFCAB8;?<=;<<8558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÐÑËÚ¨™°ÎÚÁœ€¼­¦˜¯ÖÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF@HIGE@<<>><=><756:979;::;8@?:<<9<>=;;:?9?:;9=>=><;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦ÕɎ¥š §‘¡Ÿ ™¨–˜›»ÕÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;547<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡Ê»¡¦§ž·¤«£žÃ «¤œÑÓÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKL@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÓӞ¶Ù§¬Ø¼ÕÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<=?GFHKH=657:979:;:<=9>99:8;=>>A>=9<<:=>>:=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÒºÄÕÒÕ¿¿ÖÒÕÅÄÕÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?AELLA>775;8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÒÕÔÒÒÒÔÕÓÓÓÔÔÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEK>>786967899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9699:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EILAALD??;9889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEHIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDJ;AA;<886486987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGIB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<BA<;876797799=?A?<:9@?<>B?:8776=??@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE>;HF89757875898;>>=;89A>=@?A>7596;>AB??@@BB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCEEC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELCA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<;DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGHNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAC?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€iixsg~‰‰xp‚†{w}~…Š½ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€‚wt|„‚}sp€Šx‚yƒÈÞÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsoupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿¼½¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»º¹¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjcmgb\XQPQKTJB:IQ?A7<94:565455688686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸········¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µ¶¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸¸·¸¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶·····¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨¨¨¨§¨©©©§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸········¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥£¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§§¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©ª««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤££¢¢¢¢  ŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž£¤¡žžŸ  žœœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=7789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥¤£¢¡¡¡¢£¥§¦¦§¬¬§¦ œ›¡¡ž›ššœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¥¦¦§§¦Ÿ›š›¢ ™––•š›™——˜˜šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜—™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥¢¢¥¦¦¥¦§¦¦ ›™›¡ —““’—šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB@DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥¦§¦¦¢œž¡Ÿ—‘‘”—›˜–––˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;;;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¥¦¥¥¦§¦¤¥¦¦¥¥£  ¡¡Ÿ™’–š™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šžŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡ ¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢¢¢£¤¤¥¦¥¤££¡¡¡žœš•“”˜›š›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œ ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸŸŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::88:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸ   ¡¢££££££¢¡ ž›™™˜™™™š™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢ ›ž ¡£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œž››œŸžœœœœŸ   ¡¡¡  ¡  ¡¢¡¡¢¡Ÿžœšššš›œš™š›™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥¤¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¡¢¢¡   ¡¡ ŸŸžœš™š›››œ›š›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›šœšš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>98;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤¤¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ žžŸ     Ÿ ¡  Ÿž›š™šš›š›››Ÿžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›ššš›™˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9;;>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœ›œžžŸžœšš›œœ››œœžžœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:=>:?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››š›œššš›œœ›™™œœœžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™˜˜ššš™™™˜š›œœœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›š™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š››››œ›˜˜˜™™˜˜™™™›œœžžžžžžžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ›››››››™˜˜˜˜˜˜˜™™œœœžžžžžŸŸžžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ››››››š˜˜˜˜™™˜š›œœžžžž  Ÿžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_]]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜™——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜˜˜——˜™››œœœžžžžœ››œœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±³­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=9F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œšœ›œ›˜™š˜˜™ššš–‹“–™˜•˜˜–›œ—•’‘’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨©¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‹‘‹ŒŽŽ‹……‡‹ŒŒ‡ˆ‹Ž‹‡Œ…†‹†ŠŠ‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VPQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹‹†Š‹‹‰†„†‚€‚‰‘ƒ€ƒŒ†‹‰…€‡}€’†„„†ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹‹‰‰…‚}s}ˆ€~œ„……‰‹Šz}}†ŽŠ†”‘‹—”—’˜¡–ž—•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¥›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXO[\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ†‹†ˆ…„ˆˆ‰„‚z||}~’ˆx…‹Šƒ„…ŠŒ‘™””” ššŸ¢­±­©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPFMHSWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‹‡Œ‹Š‡’Š‡†‘“‘‘„‡}}ƒˆŒŽ‹ŽŠ‰Ž””˜‘•›š¨®²¯¯µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWLO_^\NUUbQDTM;?9<895775795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš˜ “—š ™›£ •› ¤£š“ˆˆ‹‰‘‘Ž‘Ž‹˜šŒ”š—œœ›Ÿœ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUKTOOJCPK_bXZQ\T`MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ª©¨§¡¥¨¨«©©¯¡›Ÿ¡££ šŸ œ”˜”˜  ¡¤ž›š¤§¤©«®¬¥£¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdVOXKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®ªª«¤¡¢¤©§§©¨£¢œ››¤ ¥¨£ ˜™Ÿ¡¢©§ ¢¢®¬«ª§­®¨¥¤©©©©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_UZNRNPORd\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢šœ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨¦¥§©§©¨£§¦™œ¤¦¢¡ ¡¡ œ˜™Ÿ ¡¤¤¢žž– ›š¢¢ ¡Ÿ ¢¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOWO^ddlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§¬©¤Ÿ¢ ¢¦¡¦®¦¦ŸŸŸŸŸ™šœœ¡ ¡¤Ÿ¡›šœ ž¡Ÿžž £™–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvwa_\UYQUV[c^s_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?C?:8:>?C@DA:;><@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯ªª¬¨¨«°©¨ª¨¡Ÿ §©­°²¯¬£¢¦¡©¥ž¤£¢¦ ¥¤¢¥£ž žŸ¥¢¢žŸ¢˜•žšžŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸ ¡¦¢›—’šš •|wo}yf[[`_Z\V\hdocniib^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¢ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶¯³°«±²±£Ÿ¢ª©§®·¶´´¶³¯¬«®«¶°©²±­®§¦ž¢££›œ—¢¨¥¡Ÿž£›ž¡š–¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¢™˜¥ ¤§ª©¨ª­¬¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxib[_^\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>AE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢œŸª²¸¼¼½»º¿´¯±³µ´··¯µ´µ²°¨¤¢Ÿ —•š—¤ª¦¦¡¤£¤«¥¥˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨¨«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥¡¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxyxc[RYT__amhukpgiibYSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶´º±ª®´±°±´µ¶¼¼¾¼¼¾Æº¸·º½´¯µ±±º¸·²³²ª¦¦Ÿ˜¤¤§¨¤®¤««µµ®³ §ª¬§ª©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš’–””˜“š˜Š‹‡€€|‚xa^YSah`fsositdidb[LK>:8898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÃÆÂù½¿ÀÀ½¿Ä½¼º½¾´§ª˜±À½¸µ¹À³¯¯ªª¨­§§¤¯§ª´¼±´µ¨¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`a^^jbbnwuvnl[bQU\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAB;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–••‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±°§¼¼¾ÅÄÆÉÇÅÆ»ÄÀÅÆÀ¹¯½¼À¾¾³«ªŒ³»¾´µ·Âº­¯°µª«¦ª£­¤§±¶«µ²­³­¨®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|ƒjfhaklfnuqruqf^_\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCCDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÅ¿ÃÂÆÅÀ±“¾º¿Ã¶¶º©´³´©«³»»±Ÿ›±¯¬¤¬®´§ª©¨ª­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|tkkndomhqxoyjia\gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÃÄø´À·´¼Á¹··¿À»®¥®·¼·­œ£·°¦­´µ¬®¥¥£¨¤  ¥™ª³²¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyz{vnkiguZfrwsyfg]d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÊÆÄÃÃÁľ¸¾ÁÃÀľÁÏÏÎÆ«¯¶´µ« §´³®«¸µ³«©£¢­©¬¦­Ÿ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuueeijg]jomxwcb``^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÏÏÌÃÇÆÈÈÈÈÉÇÅÉÇÈÇ¿ÅÇÄÄÇÈÊÓÏÒ̼¸¶´¸¸Á¾¾º½º¼º¼¬­§ª»º¹·À²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqobagugiitmxl]d[U`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÍÐÎÇÌÉÂÂÉÁÊÊÈÆÌÊÍÅÆÅÃÆÅÉÍÐÍÏÌÇÄÀÃÂÉÍÇÅÁÄÇÁ»¾´±°°Á¾¿ÁÆ¿¾¸·Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`jjvlieuotb]bTWTSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<:>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÅÇÈÆÒÉÁÂÿ¿¾ÄËÈÊËǽÔÓÇÈÍÈÃÈÉÉÅÅÃÂÁÂÇÇÉÊÇÌÈÇÈÍÆËÏÅ·ÀÀÀÀ»º½µ³³¿¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrpfegdjeajmno^Y\VVNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾƹ»Ã¹¸¹»½ÁÇÁÄÍ¿ËÆÅÄÁÄÁÂÁÄÁþ½ÂÀÀÁÂËÃÆÌËÅÈÑ°¾½¸º»¼¾·´°¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·½Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfadbabccjbgc[ZZ\YQNE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶¸´´µ¿»½À¹¾ºº´À¸µ¸³®º»¶¿ÑŸˆÀλ¿Á¼»Ä¾»ÁÄÀ¾¾¸¼ÁÁ˾½ÉÄÀÀÊÀ±Á¿»¸»¾ºµ·´¸¼´½¸µ´°³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ¾ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|yˆ}qc`bbgjgfiei]VVTYOSKE8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA@C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”““’˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´µ±°µ·µ»Á¸¾¹¿¼¼·´·°­·¶¸Äˌ…›È½»ÃµºÇ¸¶¹»½¹º¶»ÅÅʽ¹ÅÀ¿¼Á¾¸Æ½ÁÀ¼Å¸¶·´¸¶¶»»¸¶´·ºµ´¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¡¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒ€xpmeefoiekhXXNKKKRILHC9=8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’š”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿¾¼²­¯¬±°·¼·»½ÁĹ·¹¸°º´¹¼Éºƒ…†µÄ¾Ç·¹¸­·µ¸º´¸³»ÅÆËÁ¼ÆÀÀ¿½¼¿ÉÃÄžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~‡|knpgpksebm_\THKJDJBCG?9;8><7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘ŽŽ˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼¼À·ª­¤®°·¹±½¾»Ä¶¸¥‡€‹{ŽœÅ£|ƒ…±ËÆÏÂÀ¸®µµ¼¾¸º²¾ÄÄÊÅÁÉÿ¿¾½ÇÌÇÇÄǽµµ¶Á½º»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†qelintnxcgb[cQKTHEECGC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?>??FD@A?>:7?@CC?A=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼««£°¸ÉÓ¶º¾¼Æ´¢xereU`f‡}‡‡ªÎÎÑÌÊĵºÀÃÈ¿¾µ¿Á¿ÆÆ¿ËÆÿÁ¼ÀÃÌÊÇÅÆÀ¹½¼Ä¿À¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtolltkln_b^`aNHM?E@?DC;;::;:8;<:9<>9:>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED<AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±³¿ËÈÛ¾½½¼jv`gv^WV\s€‰‹¨ÌÈÌËÍÊÆÂÄËμ¹½¹¹ÀÿÈÆÄÁÁ¿ÅÀÊÉÃÃÄùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{zˆzmmw{_pc[]_^SI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA??ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸µ¼µÆqÁÓÀ´}[LoaP|ubV`~†‘©ÆÂÇËÈÁÃÁÀÉÊÂÀ»º°´»½ÀÅÆÅÅ¿À¿ËÇÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²²¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}zmsxsgp][^\YQEDCMIAE=G::59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘–žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯·¶²µ³·¹¼»¶»»Ò—rƒµÂ›XTVbRd€„…mIr†—´Â½¿ÆÀ¹À¼¾ÅĽ½¹²°®¸·¿ÃÇÃļ½¿¿Ãþ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸¸¸½¹»±¶²ÈÀ»¶´±°·¬³©°­­´·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|vluzpni[_`YSPAEHGK@DCH<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG>CB?<E”ž   œ—š˜˜•™™Ÿš›œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹Âטr‹®vROl™ZRUZš”wLnŽ¢´¸¸¸Âº³»·»¾À»»¼®¯®³²¹ÁÂÄþ¼¿»º¸¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ¯µ´´½º¾¹º»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰|‚zsvvwnq`_f]ZTJ<??FF=FCC9:5;99><<::<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Ã՝‰}x•`Nju]Q]lºµuTW¸µ²±·¾¹²µ²¼¹¼¶º¾²´´´°¸¾ÃÆÄÀ½¿¹³¯²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtvql_ca[]OHA>=HCFMC@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·Àʟ‰}€XX’gq`wrz—wnk_‹½³°¶ºµ´²¬¼¹¸µ¸Áº¸³±¬·¼ÁÇÿ¹ºµ®¥¬³°¦°­¨ž Ÿ¥­¶µÂ·¶´¥¨«¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´·¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wo{ourmc]fX\]RNMA>IBAJI@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³²­¶º¯­¼³¸¹Å«•‰ŒxLf Ã}†›]yluy‰±ºµ±´µ²´¯¬»º¸¶¹Àö®®ª²¶¼½¹¶²±­­Ÿ¤§§£¦–™™šŸ©®¹¬««Ÿ¥¨¤«®®§¯¬¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmuik][jT]\OMHDFLBFNF8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹º¶¹»µµ³»·–“ ŠMh’“voyrhikvwx¥¼¸²´³°±­°¹¸¶¼¸»¿²²²®±®¹¯ª«­¬£¨¡ž—˜¡•’•—˜Ÿ¨®¤£¤ ¢§¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬ª¯£¤£¡© ›“Ž“’’™–š¤¥ Ÿž§˜•’”™ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wrxhtsndT`cW\QNLH@HQDMC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯²·¦¨“X€psmdk_YWX[b_l›¹²­³¯®¬®¶¶²´µ¯ª¤ž›œœž¨¨ž ¨©Ÿ¡§–›——“–Ž—›¤¨  ¢¢¢¥¥££ ž¥ ¤¬¤¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›©¨««Ÿ¦¢›£œ•Œ“—•–˜Ÿžžš˜¦—“’–¢ ¥£¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦ ˆxƒ|vybwln\QhTPNGPMLBOQ@>;>39:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¥¬©°À±³|xvrteWVOIIKNOO\kp¦µª²´®ª«¯°²³®¥ž’˜”˜ Ÿ¢ œ¤¥Ÿž¨”›–—Œ—‘—“˜¢ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£ž™—š«¦ª±£¥¨ž œ•“‘˜–•˜—Ÿ˜›™š£™—”–š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’}|€uu}mk{dhUQcMJHGORNJNG<E@=2?759;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜——–¡¨¬®¶·º¹º··»®¨ ¡©¡¦ÇĦafir`ROJpUVJOJLT^]·¯¯³µª§¬«¢œ™”Ž‘–—™™œ ¢¢œ¥žš¤———–’‘‘“š—› ¤ªž¡¡ž¦§ª¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¡¤¡›˜ž¯¨®²«¥ªª š˜˜˜•“–š“••š–›——˜¡žœœ—›¡šžš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}vx|dyy`bRU`IIJKSTIRPL9?B67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—“’œž¤¨®­¬««¯ª¯©ž—ž¥žœ»¼}oijaTJWpœ‹zYLFGNTTh®²°°¸¬¦¡œš”—ššŽ‘•‘ŒŽŽ”™¢œ—£™š—˜™”™˜–›Ÿ¥¦© ¦£ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§  £±®²±´ª²¯¢™œž¡™››š˜™›”–›–™œ¥¡ š£¡š™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ Ÿž ¥¡žž¥ ¦™{|uvsh‚le[SZYMQJOOULSLA7>B68=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’‘œ˜¡ª¢§ ž§¡¥Ÿœ’œ¢›ž©«–}k]TMM\ÄË©oYLECGMa˜°­¬¯§Ÿž¢ —‘“› œ™—’“Ÿœ¡¤›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬¨¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½·¾°¬±®­©ª´±°¨«¨²µ·³¸­²´¤ ¥Ÿ¬¡¡¢  š˜–– ››˜¤¡ ž¤¡ žšœ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚|xuiwu]lZR`HRUHFUVJBLG=KH8E<67;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“Ÿ™¨®Ÿ§žœ¡žš™’™ž›¡¡£Šo_URQUiÀãÒ´‡oYJET‘˜«ª©¤ŸŸ™’’“˜˜––•Œˆ‹Ž•ž–žš¦  ¨¥±ª§®£«­¶°´²±®¶¸½Àº­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«¯±¹·¼¯³°µÁ¼·½³³µ¢¬¢©¨²©«¨§¨š™žšª§ ™§ ŸŸ§¨¥¤Ÿª¡¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰…„~vqmivmhm\X[BWNJGMGCFM<>L=4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜™ª ±¢·¤°¦Ÿž—˜•™žšœ£¢wYRQTVhƒÀ̳˜±È°”Š˜¹Å¢©­©ª¥Ÿžž¡¢Ÿšœœ”“•”žž˜”…š¡›«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶º»ÀĹ½»¬¯§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¹Â¾¸³»Æüü·³©³­ª³´¯³®ª¯£«§¶±­¢°¦¡£¯±­°¤¥¯£¡ š¡§¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¥ž¦™›¢¤žŸ›››œ‡…{tqkkurphW[QETHDJPH?EA4FH95;=6;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž  œœ˜šŸŸš¡hPKPQiœµº§‡³àÛÖÛÚÈ´®§££¡ ž¥«¥ž—œ”‘™˜”ŒŠ†ˆ†ymˆ ¤¢«¬´¼¶Ã¾¾³»ÁÃÂÅÀ¿ÂÆÆÅÃÈÂÀÅÈÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌÌÌÒǾ¿ÀþÇÆ·ÃÉÉÂÁƾº´ºº´»·°µ²ªº²®»·¿»ºª·­«ª¸º´¼®®¹£¦£ž¦¥¢£©¦™›Ÿ˜š§ª§ ¡¡¤˜”£–”™‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ„}zqkdhoxjdZ[FKLEDSLDBE7:?;549978>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ²²¸§¡¡«ª¡œž¡¢œ•]LGNX~“À¸¤˜ÕäÛÑÄ´¦Ÿšœ›žž™———’ŒŽ——“Ž‹‚ƒ‚wsqnp¦­®´¹Å»ÍÇË¿ÂÌÎÍÌÇÉÑÌÍÌÇÉÅÆÌÑÒÕÎÓɽÀ¿Ã»ÆÅÈÅÒÔÍÓÐÓÓÌÊÂÆÆÇÊÈοÈÑÌÇÅÇÅÁ¼ÃÁ¾¿¾µ¾³®¿¿ÂÃÇÄÇÄ®¿¸²¸¼ÃÁÁº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›Œ™‰•˜› Ÿ£—žš““‹•…€ytsebgrof^ZYCNLCEPIDC@5558:B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>8;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›¢¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¤¨¬­ª £Ÿœž–aJJNfŠº×Ó¿¯ÀÔ˹®¨¢ŸŸš˜–”’”–‘Œ‡„ƒˆ‡ƒ€€yrroly¤¶º¹¾ËÁÓÒÓÈÍÎÑÓÑÒÑÐÑÑÍÎÎÐÅÎÔÖØÒ×ÍÆÇÉÌÃÅÊÏÊÓ×Ñ×ÒÕÖÓÓÈÌÇÌÍÉÒÍÎÓÍÅÈÉÊÁÆËÇÈÉƿó³ÈÄËÊËÏÆÊ¿¾¿½ÁÇÄÌÌÈɿÿ­¯³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›•Œ†‘‹€zruvgcgvidVWQDMF@IQB=B<:22@<D<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<A?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­³·¬®£ž£¢ ¤u]gm¼ØÜÚÖ˺²ª£¡¥ š””•”‰|wpkebhqoq{…Š€vpnqtp…³Â¾ÅÑÐÖÖÖÒÖÍÔÖ×ÔÓÑÓÔÔÓÏÑÃÐÓÖØÕÖÒËÉÎÑËÆÍÒÊÒÖÖÙÕ×ÓÖØÎÒÊÏÑÌÎÐÌÒÏ¿ÈÇÊÃÌÌÌÎÏÅÆǶ¿Ê¿ÑÍËÏÆÉÈ¿ÃÃÈÎÌÏÐÏÍÊÇ͸·»¨Ÿ¥«§ž˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„|xsvpc`erb]R\IJGAEHI>;A8=4585;86:<@>;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÁűµ¨¡¤¥Ÿ£¬Š“³ÒÕÚÚϼ®¨›•˜ œ›¡¢Ÿ›œ™•‰wic`____^_`^blusqpolrqu’ÄÇÆÔÕ×××ÓÖÏÕÔÚÔÔÎÏÕÔÔÑÑÌÑÍÔ×ÖÓÕÐÏÒÓÑÉÓÑÈÐØ×ØÑØÒ×ÙÕÖÌÏÏÊÍÒËÎÐÀÆÂÇÅÎÍÑÑÑÈÌÍÀÊÌÅÓÎËÎÈÄÊÇÆÈÌÊÓÓÑÕÏÒÌÓÁ¹Å±¥¨µ®§›¨¬¥²¨°³¬¬““ŽˆŠƒ‹„Ž™“™‚…Œ|zqstmacim_VP_JJCFCRM?<>54:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><??=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯­ªª«¦®·¨«·×ÔÕÙÙÑÎп¼Ìɶ¾®¦ª¨¡¥œ€”–ÇØÓÖ­¦¡˜•—™› ž™“}qecc__a__a`_``_`fnppnkorwwœÌÁÒÕÓØØÖÙÑÒÒ×ÏÓÎËÒÍÕÔÒÊÏÌÓÖÒÑÖÍÏÕÕÑÆÑÔÊÑÔÕÖÎÒÐØØØ×ËÈÎÄÉÏÌÊÌÀÉ¿ÇÉÍÎÏËÐÍÎÌÎÏÈËÐÐÊÎÊÂÉÇÉÌÊËÑÒÌÓÑÑÏÐʽȹ°®»¸µª¶°­¨¸­³¿»±šŸ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…ˆzvopokadnpaW\ZIFFDMWE;@=33<=87855;>@=9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ¤§Ÿ¸¶µµ¬¤¬®¾´°ÀØÒ×ÚÜÖÎÍÊÃÒÏÁÀ°©¬­©§l”ÓÖÍ°››–•—›žžŸ”–˜”ˆk^^^adb``aa``a^__^]bmroostvvy¤¾ËÕÑÖÔÓØÖÎÎÔËÍÎÅÎÊÒÒÏÇÎÍÍÔÌÎÓÍË×ÖÐÌÑÔËÌÐÒÓÊÎÑÕÒÕÕÊÀÉÁÅÌÂÈÉÂÌÃÅÈÊÊÏÊÍÌÐÍÓËÆÈÏÍÈÇËÅÆÁÅÊÌÍÏÑÆÐÎÍÍÌÏÅÇÁ¸¹½Ãýù³²¾±»Ãĵª˜¥¢™–‘••’‹”š‘”””‚‰…ypqkmg``phXXhVLFLIPPB;C>;67:89:57==A;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÄÂÁ¿»µ²±Ç¸ËÕÕÙÚÛØÌÌÏÈÖÕĵ¯´¨ ªho}§ÙЪ•Ž˜–‘“’‘–––‹|eabb`]^acb`_``aa`_][]grqqrsqmry¤ÆÓÏËÐÏÔÕÉÅÉÉÆÆ¿ÃÆÏÎÇÅÇÍÊÒÈËÎÍÆÑÒÐÎÌÔÊÇËÎÏÇÇÏÒËÐÏźĿÆɽÂÇÉÎÅÂÈÀÇÍÈÄÌÊËÏÈÄÄÐÈÆÂÆÈľÀÇÌÌËÎÂËËÈÇËÐÄÅÈ»ÇÃÉÈÂÏÁ½¼¿°ÁÉǹ½ª°²§¥¢œ˜›£™—™‘•˜‰‚wotdk`^fpa[W`GHHGIMTG?J=64355=<48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ¼ºÍÍÆÐÕÕÙÚÛØÐÉÏÏÑÓȶ»»­¥¢_ox¹Ð«ŽŽ—‡„„„‚~……s`[^^^`^`cdc_]]^_``_[Z\akrrookloo}¸ÑÈÉÊÏËÍĺÀû»ºº¾ÉÆÂÃÀÃÈÊÉÈÊÈÁÅÌÆÈËÍÉÄÂËÉÁÂÌÐÅËÈ¿¹Á»ÆǾ¿ÆÏËÿûÉÇÈ»ÈÆÅÊÀ½ÂËÆÅľƼ¼ÀÃÅÌÅÅ»ÀÊÂÅÇÒÅÁÉ¿ÊÉÆÈÆÐÃÃÆïÄËÇÃÊ·¿¼º´©¬¤¥˜Ÿ˜¬£¡¥›£ ›”{vstfiZanlZ[XRDLFBGDLDFS@54334?<3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ÊÏÑÌÇÂÃÆÍÎÎÌÕÏÕÙØÙÏËÒÍÍÎÈÁµÃ¾²²‘_r€¾°‹“—‡{…†€vxurp_[[]``bcdded`\\]]_^`[YZ\borokilposÆ¼ÉÅÌÀƱ¶º²²³²±Â¼¼¼º¸ÁÁž½¹½¿¹ÄÊÅƽÆÀ¸»ÄÉ¿ÂÉ»·»ºÅÿ¼ÁÍÃƽ½µÁ½Ãº½Æ»Âº³¼ÅÄÁ¶¿¶µ½¿»ÌüµºÈº¿¾ËÄÁÆÂÆÉÆÈÆÐÆÂÌDzÇÉÃÎÍÁÅÃÀ½³·°²§¨¨¹°¥­°ª­¬”yvwjdg`hocV^YJFJFHJAEBEI@9:648853;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÅÂÄÈÎÑÊÊÊÇÍÍÎÑÈÐÆÕÔÖ×ÍÊÏÅÉÅÇÁ¹Å½«¯ƒcuµ’Œ‰‹…y‡‡€~„|ttc[\]^``bcabeeb]][\^\^]Z[]]hsqmggnpry½ÌÀúÁ¸®°°§ª­¬§¸µ·´³³´¼¶½±·°µ¯²»Â¼Áļ¿ºµ³º¾À¸Ç¹´»¶Á¼¸½ÆÁûµ®²¶º¿´Ä·»µ«¸½½À½±º¶¯¶º³Å¼·®»¿µ·´Å¼¾ÃÅÀÃÅÆÈËÅÀÆÆ»ÈË¿ÏÊÇÃÆÂ÷ý½¶¹¾Ç¿¬µºµ·¶Žytxfgebkn^V^`FKHHJFBDAEE?<:565633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÍÈÅÈÍÌÐÌÍÈÊÈÊÉÊÄÏÍÒÏÍÅÇÁÅÀ¾º¸É¶ª°kr™œ†‰Š{y~††wx‚}ti^]]]_`_`da^cec__\[^\]^Z[[]_lpnhfjnnr|¤Ç¿¸¸µ°«¬§ž¢ª§ž«­³­©¬©´¯·°²©®¦¬²¼º¶Ã¹ºº±«µ¹»´Âº°À±¾¼»¶»Ç¹Â¶­ª¨°±À¶¸½°°§²³µ»¼«®µ¥®µ®»²°©¹°­»®»¸»ÀÀ½¹Â¿ÇÃÅÁ¼ÆÂÈ˸ÅÇÅ¿ÆÃúÄÆ»ÆÉÌ˳¹Â¼»³ˆsvvkiablhYWW[ALKMIEAC?FA:9:995854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÅÎÒËÃÅÁÅÏÇÍÁÃÆ¿ÄÄÃÃÊÂÉʾ¿¼Àº²´´Ã®©®†kdŠ’ˆŽ|x~Š…z{„wn^]\]]_`__dcbccb`_^[[ZZ]ZZZZ\dnohggiknr­¹°µ®¦¥§§š ¥¡šœ¥«®¤¨¢¬ª¬ª¯£¦Ÿª­µ¶±½¹¯·¯©®¸´´¼¸´¼¯·¹µ²»Á²À®¥©¢«±²´¨½ª«¨«¬­´³¦¨®¡¤¯©²¦§¨®¦¨·¬±²·ºº»²¼½¾¾Ä¿µÂÁÇÈ·¿ÀÄ·Ä¿»¿Ä¾ÄÈÌÊ¿¾ÄÀÀ©‡strji]aodWVXPHYRSKFFE>>@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÐÏÌÃȺºËÁ˾»É¶½Ã¾ºÊ·ÁÃÁ´µ»µ°®´»­¨§ˆ`mƒˆ‹€{~€~xt|swe_]\\^_`^_ccab``_^]\ZXZ[[YXZ\_fkfegeikor…ª¥¬¥ œ¢¥”ž¥›˜‘¡£ª¤¢Ÿ¥¥§¥­ œ¥¦¬²¯¶·§°«¨ª´«´º±¶µ®¶¹±¯ºº±¶¤ ¤Ÿ¦±¨«¨¹ª¤§¨¨§²­ §¦Ÿ›¤¦¬žŸ§¤  ±­­¬²´²´°µ¼¶»ÁÁ²º¾ÃÁ²¹¹Ã³À½¿µ¸»½¾¼ÂÇÄÂþÀÄ ƒxpkaf_ko`TY^HNgOTGEJF<=?=:;;825536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;=:7676788666;::;9:;<859<:>>@;Èµµ½¸ºÀº½µ ž•¡¦º¶«³³»³ÄÏÉËÂƸ·ÇÁÌ¿¸É·»Å¸³Ä¸´¾À«µ»±«¤®²¬Ÿ¡‹a€‡††|yutomkjjqi^`]\\\^__acb````]\[\\XYXXXVX[^_dcbegggjmoˆ© —–›¢–œ£™–ž¡£§›ŸŸ£¥¢¨ž›¢›Ÿ«°¬±¶£©ªª¬¬¤´¹­·°¬³µ®²µ®°ªŸŸ¤¢²¥¦©¸­¢¦¦Ÿ¨¬«™Ÿ ž™Ÿ¥šš£œ›¯©«§ª«¬­±²¸¯¸¹»°¶¼¼º«³³¹³½´¶±±µ´¿¶½À½ÃÁ»»½—ƒ{sk_e^ddXTW]IW\KPGIIFA<??@;?<04535:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»·ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÆÏÈÈÀÆ»»ÄÃϾ¹Ç¸·¾·²Á´±»»«¸¹°¡¨ª¦–…f‚…†xrnpnkb^bff]]^]]]\]_aabccba_\[[ZZYXXWWXXXXZ^bddeffhikr§”••›˜›¢—–‘œ£¢¨›¥¦¢¦œ  ›˜®®­®² ¥¢®¬§¢µ±²²¬¨¯²§º³¦µ ¢ž›£¢­£¢ªµª¢£¦¦¦£–™ž—™š š—žœœ›¬¡«§£¤¦­«³´ªµ°³«²¹´¯©¯²²³·³®©¬®²¸°º¶º½¿·³±”…yue^e^[YVSZUK[QKIEHKIB=?AA@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½·½¿¶¾¼¿²¥£˜¥±Âµ¶½­´¸ÂÌÈÆÀŶÁ¿ÇηÀĽ³¹¹²¿¶±¸º¬±´­˜£¨ž‘šziƒ„xoqtqifdiec\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXWVWadecdeddhjv¢œ””•—— —™•˜¡ž¡œ–¡¢©¤ŸŸ©œš«§¯°ª›£¤¸ª¡ ®¨¶ª¦§­°¤·°¤· ¢›™™ª¦¡š¬¸°¢¡¤œ¢ŸŸ“”¡”•–›˜—–—œ•Ÿ©©£¡£ªª°®¨´«ª§­³°¥«®²±°°®¯¦§§²®±´°¼´¹·®£”yud^aVYWSRTKM^LOKGGLLE<@><B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾¸½®§¨£ª»À½À¹®´¸ÁÌÇÅÂýŷÈ̲ÁÂÁ®¼»µ»¼µ¸¹¯¯¯§›˜Ÿ§’Šrz€|wqilrtpihedfb\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWWV[bccbcbcdfj–“•Œ’””›™——œ œ –¡ ¦¥¤¦§ŸŸ¦ ª¯¦Ÿ¢¤·¨¡¡¢¨´¢¥¨¥°¥°­«´ž ••ª¡¢”­±±Ÿ¢£ž˜›“‹¡”‘“˜˜“——˜—¦›§¡¢™£¥¥«¤¥°§¥£««­¦¨®¯®«¨ª©³¥¦¬¯´±¯¼µ±¯® ’zvrda\Z]XNLRHRaMVPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8847863321./2556;:8;7876<;:;;A8x»»±µ½°»±¸¬ž¥§­·»¼Áź±¹µÄÉÉÀÃÆÆǶÆij¿ū··½¶½»ºµ²««¥˜—¡Š‡q{‡~vncafihfgjgjm`]\[ZZZZ\]\[\^_\ZY[ZYZ[WUXWTTVUSTRU``_`a_`acdi”“‰‘”“”•–—¤™ —œ ¥¢­¦¤¤££¢œª«¥™Ÿ¥±ª ¡¥«§¢ž­¬©©­¬¡¢¢•˜£›œ«©°›Ÿ¢Ÿž—™“Šž‘’“–˜˜“œ¡¢¤ ¡• ¢¤¦›£«¥¢¤ª¤«®¥­²©¦¥¦¦´¦©¨­³µ´¹º¯©¬ž‹rpo`[WVURGQOHZ[ORJTKSLEFIC8;;=<8667:9;:976977:;:=<<6;<8>598:88659:;<97?<9678452121..1426:8698598989;9@9{µ´­´»²°«²­¨§¯¹¹³ÀȺµÀ¯ÅÈ̺ÁÊÌȵɽ±¾Äɬ±¸Áµ»À»´³¨©¤”˜™š‡~p‡ƒ{tiijlgjkmkjme]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURSOQY]\]]^___bdmŽ„‘‡‘š“•“œ›£œ› ¨©«¨¬§¨¥¤™¥®¤”™¥¯©Ÿ›™› ž®™›«³ ¥¦Ÿ¢£¡•“›––’©ª­šœŸ¡ š”Œ™Ž‹Œ’–•ž¡ £œ›£•›¡£¡—¢¨£¢¨« «¯£­·¥££¢¬­ª¨«¯³·³¾µ³«¯˜„tsh[XXRUQEXLQ[XMTNPLPQINIB<??A?<65799<<987:79:;<=>;7;;:=67:;8976989:6:=99577571141-+/434988::8::748=8?9~³­¨³¶®©§¯®›©¨¬·¶¬¼Ê»¶¿¬ËÆŸÁÎÏȳĻ·»Ãȱ­¸¿·¼½º²³£§ž”•–”…xs€vwnmhmnmpggigd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUSSNPQYZZZ]]\^_`d~‹ŒŠ’—‘—™¢ › ¬ª¦®¬¨¯¤¨šŸ¬ •–¤¨§—šž®–˜¨ª™Ÿ”¥ ž’’‘“•§«¥š™™žž•Œ‹“†ˆƒ‹‘•‘ ž¡£—•Ÿ•š¡¢ž”›¥¥§¨¨ ±°¦±¼§Ÿ£¬´«®§°µ°¹µÀ±­±«}rsbVSVNRIFVPRQLLWMJLNRGMJACFDC>@65889;9:7::7<=:;@>:9;9:?759:9876958779;85576661320-*.102877;99;8948;8@8³¬¦±·ª¦¢°«ª§©²±¥¶Æ´¹º³ÊŹºÁËÐ˱¶¸¼¾Áñ°²·­´³º²±¡¡š›–•’~vkglnqnqjpkdege^ZYZYZZZZZZZ\\]\ZXXXYYWXWUUTRSUSVURNNNRWXYYYY\\]aj€zv‰‡Š—‰””˜›™ž©› ª¦¥«¨™¡¥›“Ÿ£›——…„’›£”£–––ˆ¢››“‹ŽŠš¤§œ••—›‘‘‡”Ž‹‹Š’’’ šŸ¢•“˜˜•¢¦™™¤¦¨¦¡Ÿ´²¨²·¡œ¢·¬ª­¤²²¦µ¼¶¬«±£‰xsm]NQQLOCMNNPKFNNJJNMQIMJAGLHGC=858889:;69:68;99><8:>9;?8789:886857688974577820301+)-/12876:999984988A7w¶§¤¶±¥§£©¥ ¨¥¤³ª¢²Ãµµ²³ÆÆ·ºÃÊÌƳ¬º½´·À¯­©°ž¦­¹®«˜™›”’…zm__frpvqinieghj_XXXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQMMKLSWWVXXYX[]aosvq…ˆ‚ˆ€‘„‹”‘”ž¡›œ£¡£˜¥—¢œ•‡˜šŒsƒ~—–†‘™”ŽŽ{™œŒ‚‰Š˜Ÿ£ž“˜–…‚”~~t‰Žy‡“š™š‘•Ž¢£Ž‰š ¡¤¤›¢´¯¬¯¬Ÿ˜¥¸¦¦±¡±®œ°¼ª©¯ª™‚wscVMROPMCSNLQMBPQHINRMHJJCJLFKK<749888;;69;7:<9::;79?9>@79:<89764445874312585/0102)(,-12764789::65:87A7x·¡£´©¦¥¨£¦¥¦¦¦³§¦´Á¸°´°ÉÄ·¹ÁΞ³¬ºÁ«­Ã­¨¢¦’¦µ«¡œŽ”•‘Ž|v}eWV_gfighncjhgb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTRMMJHNSSSTUUWY[]ilrm…|tNXrƒ—†Ž—‹”Ÿ˜•”–•–‰€“‰_;Wo|‹”‰€Œ‘Œ††sŠ…–yz…””ƒ•Ž‘ƒ†}“xqo…}‰‘—š˜“Š‰œ‡Ÿ˜‡ˆ–žš¡ —§¯©­¨¨Ÿ–­³¢¦®™¬«˜¨´¢©­£“}rn`[NSRVLDTJPMLFNOIELQMKOJIMOFII<7599999:7:;:>>8:==7:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9y· £­¡¦¦ª §©§£©°¨§´Á¹±µ°Ç·³½Ï¿¹¯®µÂ§ªÅ©£˜ƒ”›® ˜•„“ŽŠ†{rt\QLRUYZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MORMKHFHNQQMPRTVXZ`mpi{‚tPB@•‘‘}‰”„Š›–•‰’ˆ†•†yˆ`JQnxŠ‘„}„Š…n~”wuuw„™pQˆŠ†{~x”vhw†ˆ~Šˆ•Š‘’–‹„Šˆ”„šŒ‚„’›–ž”¤£¨©¥¤ž›°ª¡¤¤‘¦ª–¢ªœ¢¦¨‰tmg^[HQQRMIUMSILKOIHFJNLMTKQPOFIC<768:8:;;8:;8>?99>=8;<6;;478;6775344696/3/.125221/,')+*,4833979:99::::?9w¶›£§Ÿ¢¯¡§¨¥§¨¯­ªµ¼¶¸·³Á»¶§¹È¸¶¨¨µ¶ª²¼¦ž•Ž‰“§•”‰}ƒ|vomXMKMNOLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDDINOhYNQSTUZnƒtw~ji]U‰”‰t‡|…Œ“’™‹{†€vxsnuptŽz~Š«…yzhv{Žprmx‹’xz€{vrr’wgu„„„„{•‰ˆŠŒ‹€„‹Œ”ƒ|˜•œ•‘Ÿ©žŸ  ©¥Ÿ˜§¤“¡Ÿ–žž¤€rh`\\JVORGJXROJLMRJJJLPILQLRTLEHA<77;99>=:;<98@?::>=7==79947795676252572/2.,//200/-+(().1272198798775:<;7v®™£¢˜œŸ´©¯©¥­¬°±ª½´²»¸¶º´±Ÿ·º²ª¬©¨²¯¡š‘Ž”Ž›~v…x{uonhXKHHHGEHHPTTTWWSTUUUVWWWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQQSV^uƒ}ygw—˜}hyvx€‰}„˜’q‡|w{ok~­}s‹{†’}tfv|†lohs|‰Œˆ€lyq}pmuqiq€~ŽpC‹„‚ƒ…wwz‹…~Œ{u~Ž’˜Š’š›£–™šž¢–Š¥›ž—Ž–˜vnmebZWWTQJSUTOPNPVKNKNOJQNHNOKEC<;79;::?=9<:99??;8<=7<9999266856633621224.,,-..-0-+*''*.1362/876966527995y¦— ž– ¦¯¬®«¨©°¯±«¼¸¬»¾¹³¬§›°§¬›–œ¥©¤ —™„’zˆŠŠvq}ntpiliWKFGEA@CDILLMQRPQSUTTUVWWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNPQTX^eprmˆ§ªÀ~uyc|xo|yˆz}‹†omŒ’ytxjj€‚q–‘‹~–€I“˜nhw~‚licly…’†ksl|nr{†imps‰„†z}~{vots…‚yxp|ŽŒŠ”ƒ–—˜š“–—™—ž—Œƒ‰Ÿ‘‹’†–~mhmnnWUWTRQYORTTSXUMNHNKMNKCHNGE?;99;99:><9<;::=>:8:<9?868727575541442/024*+**-.+-*(*(',-1250,5567485HA895w™‘›™šŸ¥­°¢¬ª¨µ¯®¬´¿«¼Â¿¦¢™•¤—„‹”¡¡˜˜‘“‹sŽz€…‹†uoulpldkjXNEFC@<>>AFFGKKKMPRRRTUTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_IMOORWZRY\`§ˆbšitzepmz‹‰vˆ†tlš’ts|jkMy…’‰„Žg1v†sl~~ƒtfet~„„…€filukq€|gqq{n“{s}|qpnum‚xyujy‰‚ˆŠ„–“’‹‘””—Ž€yˆ—ˆ†Š†€‡vjjngdWQZWYY[MPUVYXNIHEJJHGBAFDCG=998;9:9<:9;:::@<9:<98>787715244533645031.**+),,++)(+'),,226,,5775478iO8;5n’ˆš‘™–¤¨®ž²Ÿ¦º¯«²°Â±»Ãǚ–”™‹…y„˜”Œ†q‡‚t‡Œ…ypsqnodpf_TFIC?<;9:?@ADDEGJLOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOOQVLAIQIb¯³ r|xl}mrƒ…z„††yr¡•txsu”‡5q¨Ž¡¡„¢…vp†|‡|sŒ­‰€gfbjnrmpƒuioXupŽš’wl{}mqmp€zsvncv„~†€…‘Š‹‰‘‹‘Œ‹ƒux‹€~ƒ€~zqpok_Z\][YX`_RN[ZXWLHJFJG?CABG>CD=;97=;:;;9:99;:?<88=:8;66651121353475531./,,+)*))***)(*)+/3DM2166643<vR7=7b’“ˆ–‘ž¤§ž¯•¥µª®±®Á²»ÁƖŒ”€ˆ}n’‰ƒŠ‡…u‚„l•ˆ‡{uxxlwnwci^IPG>@7449;;<=>@BEHLLLLNPQRUUVWXYXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL7CMRSDJ†v€||v~mwˆˆ|~…ƒŒ~v¢™y~†…™„›œa†ªŸ‹ƒŽzwˆ~‰ˆsŠ—„z]dqtz{wŠlgjbyo…‚znwt„zptzwkni^w‡}‡|ˆ‡€‹’—ƒ…‡}q„„|uw{}‰uorsef_[[]S[f^WQUX[UGJKEKG?F@DC>AA=:97<;;=<::99;;=>79>9986754244004645654-,)+('''&(())((+++/00Ur=23331E~W4=9\ŒxŠ€”Œ’Ÿ¦‘ « ±¨¯À±ºÅº–Ž‘”‡z…vkŒ‘‚}Š„ŽŒxƒs¡„‹}}p€~zgvkRWL@E211367688:<>BEGFGJKMOPQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMORLKT]YRJi„ˆ{‰y|q|Œz}‰‡~—‡v¡™ˆ‡’”¥¬©H†®¯¯‹€“Š‚‹„‘¨‡€˜˜Šœsm|†‡}Žhghx~n…‡‚…q„…Gk€wryvhmk_w}ƒ‰ˆ…Œz•ž›Š‹ˆ‘zu‹v|wmow~srqjZ]\[ccXfe\UPPVYPDLKFNICFCCA@CA=988:::;;:888::?>6;>7585773344236656768;DFLMMLC7+"&'+)++,/00+nu22420L\5=<^„t|~Š…ˆ‘–˜’—¡¬¡¦¸¯³¼³—’‹˜‹}tp‰’~}Œ‚’”}†~†¤‡ˆ‚ˆ…x‡ˆ~s„x_cVKB60./23133668:=?@BEGHJLNQSTUTTVUSQOGC?80,#‡[>?84.]–ps£UFIKMNPW`YpZ\^j“‡•„‚…‘“~…‰‘š•‚ ¡—•›š¥­“š»±§»Ç芌¡¥”‰‘{r„žŸ‘œv……Šˆjhoƒ€u‡„‹q†‚w‡€{v…}nvug€”†‰ˆˆˆ‡¡«¡–ŠŽ˜{‚‰zzogkx~x}qjc]ZZ]i\af_YOKNWRQIPJDNGCKDC@DDA<:87=<:<:88778:==8<=68656623445576867<BB?<8:>CQ^e\G2'&,,--.1(?‹[.310Oƒ_4?;nupfxƒ{€Œ€‘‹››¤œ¡¬¦«¯°—‘‘„¡”„xwŒ”|’†’•Š€’›Žƒ€‹‹‚‰ƒ‰lpj]BA4--//./02234779;=?BDHJOQRSRSTTRPOHDB<87/9D><<63.l“—MPHJLKKNV`cggmu›š““‹Žšˆ“‹  ’£ª¥£¬“¨¶¢¨Áîǯxº”š|¡ž™„“…‚¢Ÿ”™’„Š…˜‘–lpu‰‹‚–Œv„ql…Š–’ƒ…ˆr‰¡–‡“‰–¥µ©›•¢ƒ‡“„}kjk|€€ra\b^Yfj\kk^WKGOSQNMLFIPCDNFBCEGB>:97=<:;:987767;:6=:785456345566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYp‚pu‡qv’†~˜–š”ŸŸœ§ ª–“˜žge¤š~„’‘y€’ˆ’}Š…˜’‘‚€€‹‰…†„ˆ…xxgMR>/..,/.-/000212557;?CFNPRTPQRSQNPIED>;<:CF?><752<?R5HHHLLMNR^oŠ|s} ›¨¦¢™¡—¢•œŸ¨ž©«Ÿ¨¬©ªµ—«¿«¶ÈÈ·ÉÑϾ› pi«©Ÿ„”’…œ¡šš™§‘‘ˆ•¢ššwz~”˜’¡’——”ž{v•’«³‰— }”žœŽ“–™¤¢¦¶°‘™¨ˆ—Žˆlss|~zpg`[_^afc`gg\QEJKPOIJLFFMCHLFFCBGDA:85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Ppu`n}awŽ}|”ŽŽŠŸ’—ž–œª˜žªBD}‡‰‡˜x‚ŠŽŒ{Š†Ž‚€‰ŒŠ„’…‚†ˆ€‡w_bP460-1/,.00./..0015>AAMQRSPRSUSNSLEE@<>=GG@A@8662<9;FHGIIMOQYm†w•‹£§ª´½¸¥®¬¬§¨´¬°·²²­»±³¾œ³Ä¬»É˸Ŀ¸¥£°²¬­«¤‹–˜…¦¦ ¢—¦™¢ª¨¤‡…“¤¡ ª¡¤©Žœ±‹•£§·»› £°“££ž‘¤¢«¯­³µ¢•¥«ˆš‰’Š–z{~„}f_g[da]cc^ff^[OCIHTOFHLFJGEFHAKFCFFA;87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLicWjpXz…v”…ˆ‚›ƒ’’Úȝ–sV—ˆˆœ|†ŒŽŠ‰zˆ‚‡‘Žƒ…€‹…†‡’†‚„‰†‡‡‡qna@E64<2/110-,+-1/-4?DAMUQRSUUWUN[PGGD<>>FHCD@8;<5C;=FKIGHROPW“ „®£³ª²ÁÇë³Æ¶¬³À³¹¾¶¿´Á¶»»¤¸Æ©¶ÉǶ¾¹´¨£´­±±œš’šŸ‰§¯«¤•vŸ¤—¡«±³˜–ª­¨®¶»²º¬¯µ¢±¬±µ¼·µ®µ §¨£¨›©°­²º¸¸§›·©¥Ž‘“ ‡y‚tX`cUea`b_`e_ZUJDELUQHJJDIGEA@@KDAMF<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AEWQJL[ZQcdWzuq‚”}…†“v…~€{¿»£¼‚´”“›„ˆ’‰‰y†€Œ“Œ‡…Ž‰Ž†€†ˆ…Š‡‘zxn]V@EM<6:46AB7650/6CHCQ[OQUWU\WP_UIKJA@?GKFED;>@7D7?BJJEGWTP^¥­£±´Ã¶¸ÁÌɶ¼Å½³³À·¸Âµ¿°¸t²´¦ºÅ¤°Æ¹±³±´¨¤µ¶ª± ¢–›¢’¥±®¦­¬§¤˜ ¬³º¢©²ºµ»¾Ì¿ÅŽ½³Â·º¸¿·º·¹¬­°¦±ª­¾°½»Â¬™º¨”®˜˜«‰~ziVa`WidhdVZcYVTIGGLQGCHIAHD>?BBK@@MC99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FQLALRWTYUZwjp„Ž…nzryˆb¸¡™£‰•“–“““—’‡‡{†•Š€„€‰z|‹‡†|Š‚Šƒ•}wyueO\dGEL:Qda[^SF?;HPDZdQQYXYgZT``MSOEA?IJHEFA@C=E6B>HGKLSZT]“¯¸µº¹ÉÀ»½ÉÌ»½À¼·µ¼»·¾µº²Æ`u³¥±šž«½ª¥¨«ª£¢²µ¡«§ž•–Ÿ™Ÿ®¥§§¥ž¤”¢§°³§²²¼¶Á½ÓÉÊÓÆÂÅÌÂÊÃÀ¾½¿¼¼·´°¹··ÃºÆ½ÃÉ°ž¹ª¢¬¥¨·‰~q^aa\Va^geRXaVRUIEENKA>GD=KB=B@=F>;H@796379>489:57045/26389374526?8@>GKRTTRPPQRQJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKE@IMPRLQ]hllq…slsrsˆÕÀµ™ •˜™‘Ž—‘––Ž†‡}†ƒŒ–‹ƒ‚xz‹ƒ‡{‹yŠ‚—t}zkepuY]\Peeb`ed][XW\MdmURmm^o_XgeUYTJDAKKHFHHHHBI9D?HKTTV\Z[’¹À¹½·ÆÀ»¹Ê˺¶º¶¸¹³¸µ´®¶¶™du¨ž­p^¢¬œ˜¡£›¤ž«¥”ŸŸ”Ž–˜—¨Ÿ¥ŸŸš™ƒ¤¬¤ª°­·°½¹ÔÑÏ×ÏÉÌÒÌÏÎÊÇÀ¿ÂʽÁ½ÂÀÅÄÆÊ¿ÈÏ´¤»°µ°›¬¹½š~xk\_\Y]aYbbQ[`SQKCBEFE<@E>BHB@C=:E>=J?47535;=468977022/24169775555D3ELM>510006:477@IOJ;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODR\Yi_p—’‘”nlouuˆ³¬¡¡Ÿ‹™œ™ŒŒ•‘›’…ŠŠ~ˆ‡Œ‹‰|„s{‰ƒ†|‰t‚Š†•s{xlmu{hreilifjih`fihmZmt—­¤¼ˆ‡g[oh]ZYTHJNPJKQLTQILAJGKP__bfia˜·Ç°¹³»¾¶²ÄǶ°¹±°»¬³±§ª·¬¶§ž›§šO›ŒŽ –‘¦˜¥•Š““‰‰’ž›¡˜›•–‡ž™¦›¬¯¨¯§³´ÔÔÕÖÒËÏÓÕÎÓÏÍÅÂÊпÊÉËÉÒÈÍÍÂÐÒ¸°Ä¼Äº¦¶»Ä¢mb[\]X`WYeYP\WNQCBHEBH;AD>AH??B7;D>@H=46655;:687654/10146278875367C5B8?-0,1349=97,.,1;FL=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYSeWs˜ƒhqoyyƒ ªž¦—››—‹•‘šŽ}‰‹…ŽŠŠ‹ˆ|„‚p‡†{‡rƒ’‹}qxulqx~q{mxslh€pmcimpyiw}~Ë¿Âߧmcxnc[a`JPRUNY^P]]NQNTQUT\nnw‚r–®¸¬´§°¶«­½À±«µ¦¥¸§¬®¡¬´£Ž±®š˜˜Œ‘”‘„Ž›¦‘œ‰ƒ‹„Š‰„‹ƒ”•˜—”›‘œ—™™žž«¬¤§¡¬¬ÎÒÕÑÍÌÒÓÔÐÔÑÎÈÃÔÑÈÍÒÓÓ×ÍÒÑÅÒÖÆÀÎÇÈ鿸Нxmd\a\V_R]ZNOSPNH>AFBBE<@B?EE>??:===<JA45465<888664412/03526768533;=<E=@11+/349?5901022-2EO3)/3.32=N248C}_2A†tD:==I>@CFH<VRMO[u†…Šwmwp}~€¡žž¡‹™““Œ‹“–„y…‹Šˆ‘‡‚{r~€‚‡z…u…“‘‰ovsls|{v|swqj€rrioqzyr{¾Ëš~Œ±ƒvr„vhaj]CZZ[VfdXekTX]\`c]cx{‹™ª¤¤¡ ¡©¦ª±¹ª¦´£¢­¢£­¢§±Ÿ‰¦š”’‘Š’Žˆ‚“‰k•¢˜„…~‘ƒƒ“–¬‹••™Ž…’—§°¡  ¤¤¨ÇÍÏÈÂËÐÓÑÔÒÎÓÍÆÖÓÍÔØÖÖØÕ×ÕÉÔÚÍÉ×ÖÑÊ­ÄÃˉqnb__WSYR[OJGIIJ@;:;EBD<BD>HB?BB;;9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/-.;R017/532ED28>nb5=tM99@I<AD?A;PLFKYp€u}hsyr‚‰•”…‹–‰ŠˆŽ‡w„”™‹ˆˆ‹‰~ƒxs{}ƒ‡w€{‡‘—ƒnwpmuvx}s…|yl‡vto}v„uy{µŒ<AŠÆ¥~|ieVICecfchjdoy[_fhknin€ƒ‰‘‹Ÿ —˜Ÿ££¦²¤¤³ ¢¥ž¡© ¢±œ†ž’’’‹Ž‹†ƒ„~œ›Œ‚„…z”~‚©•£Œ’Š˜’‹}—Šš‘«³˜š›§œ§½ÃƸ¶ÆÍÒÐÒÐÌÒËÉÔÏÑÕÚ××ØÔÙØÍØÛÎÉÚÚÒÖ¿ÌÌ´vumc\YRUPYVEFJIEE=:7:@AC:GE@ECADA;?;;7DC75655;0689443341014558754449@>DBC<33.6FTWOQJAJF?1*(.BT29254/7K75<`bA<svV87AH:?C><9QECJTlnopaqqs†|—‘‹~‡’‚‰†…Š‚‡|x…–—ˆƒ‡†‡z„yqz{„†uz…ŽzŒp|opzr|qƒ‡€nŽzuw}|‚u|‡ˆ°tX©Â¶Œ’pnb=^hrpqpnxw‚eioruxr{‹‡Ž”’›– –‡Œ“› ›ŸªŸ¡­œ¢š™Ÿ¥žŸ¬™‹šŒ‘’…}ˆ‡ƒ…‹Ž ™“ˆƒ‡~m™y„˜†ˆ“ŒŽ•Œ†{›ˆ“®«”•—ž˜¦®¶½¨­½ÆËÈÉËËÏÉÄÒÊÔÖØ×Ø×ÔÛ×ÓÙÛÖÐÛÚÑÖÈÕ̕xzhgZYORS]HBEII>A>=7:=?;>H=@AAADA>>:87DB755479.566435542323646553457EBDCEB56<FNSM[nfcnsk`V>,4LG865433BF4=W_hLux^8;?F<<B<:9D?CGRk_mdbfkv€ˆq‘›€y€Ž~ƒ‚‚…„||„—Ž‡‹~†‡€w‚yn{{†tz’ž¡vu‚tu}t€„oo’„t|…zv†{‰·Æ¤ÂÉ·•›xpeNec‚zw†¢‹yyw{ƒ|„vm”–”•—ƒ‰–š——¦œ˜ —Ÿ“’—£š«–‘‘‹’ƒŒ…‰ˆ…‘žœ™‰…‹†—{ˆˆŸ—‰Š‹‚|¡ˆ‹¼¡˜“—™œ¨¦¥®ž§µ¾ÀÀ¹ÇÉÍÎÅÍÊÑÖÕÔÙÕ×ÛÔ×ÙÚÛ×ÛÚÙØÎÛƅyxehc_SVVUMKDMC;==<9:<>9>A6>?@<?><9867CA6455=80665547745613855564557HH=DJE7925;H>;::7HP\ZRUXK9T>;95327I8=NYMHxxd5=>C=<@:6:>>@EQ_Yea][htzyl‰’wvzŠ|~€€}…z~‚‘‰„…z…ˆ{u}tn|}†~t’‘Ÿƒ’|†}xŽ}xŠŠn‚š€t˜…~‰…|~z©Ã »Œœ£œ}‰„}‰rŒŠ~s¦šœ™”…{‰„hGq¡¤Œ‹’…ˆ‹‘’•š“•‘—Œ•Ÿ”¡”’ŽŽ‹~Ž‹„ˆ’–šŸŸ‰‹”‘‘‚‹¦™ˆ…Ž‚†„€¤†Š‹¸˜‘”–¡§ ž£®¶ºµ«¿ÅÊÐÈÇÌÏÓÒÒØÒÕ×À×ØÙÛØÚÚÙÙ×Ü·wwviidV_ZSONHDLB==>99;:99<=6@>><=9:;;37D@8378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWN<MTHN?96333>C;[X>5YypZ<<A<=>8589?=DRSRX^UXfmmmiŠqrxŠ{{}|ˆz|{‹‡‚~uƒ†yszsm~„}w†› šž”’€‹‡˜‡€œ’n‡¨…z ‹|Žƒˆ„œ~š‘Š£¢Ÿ£®Ÿ‹‘‹…‹’†Wr­‹Ÿ¬œƒ˜›Ž\ƒ¢‘‚ŒŸ“•Œ†ˆŒ’“Œ”•”ŒŠˆ–›•–‘‹’”†€‹‰’ŠŠ–™££†“• ‹ŠˆŽœƒˆ€ƒ‡…¤…‹³˜œ’”—¡¡ž™’›§±¸¬¥¼ÁÇÍÇÆÏÌÏÌÏ×ÏÑÔ®ÖÕØÚÙÚÚ×ÖÙٞn{sfe[\WRVWC@ID>?>:49:;7:;:3;;?=>7;9:1:G=:27=@50677255?65;55858:57735HR7GOK994=EJB>1FCLA98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:<@;BQKKSYPTcbxmb~’ƒnmw‹xy~z}†|{v†„€sp…‚{vvut„ƒ…}~’¦£ž¥¢–‰”–‹Š¨—rŠ²ƒ¦‘„™“„™Œ¢– ™“‰š¡’¨¯Ÿ‘”ŽŽˆ•‹n·„šÄȲ¢¥›œ˜–‘²c¤ÍȕŽ†‡‰’Ž“”Š…ŠŠ†–š›”“‡•˜„€‹™ˆª——¤£ˆ™ž•›‰‡——‹…Œ†¤ˆ“¨™—“–˜¡˜Ÿ™“›¢²´¥£¼Á¾ÇÅÅÉÈÉÂÊÓÌÍÔ¨ÒÑÖÖÖØÚÔÓÚ΁q~gb]]\NITYABGD;A=837;<:8=649:<:82?9929I:>67BC32:96264>=4;>6949;57944KQ<JQK9A7BGI@64JELF>;88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBcFvŽ}|m~ˆxz~z‚‚ƒ~vv€‚|ln‹z|xx|„‡Š~Š£³§£ª³¡–§Ÿ¥£–•®¢ƒ¸•’²™Œ¡¡Œ¤›¯£¤˜§–§™¬¯¤—”–•‹˜™– ÀŽ£É¹«›£¦­˜‘›²……¨¢œ˜…‰‰Ž•‹“ˆ†‡‰“˜•Œ‹”“†”˜†„‘œt‘˜²–—¥¡ˆœš“Š‘Š—›‰Š–Ž†}Œ˜ž‰œš™“˜—Ÿ” •ž› ±®¢¤·¾´ÅÇĽÃÿÆÍÊÉÒ¦ÎÍÓÒÐÖØÓÐغqxu\_T_UOHJNDBCE5>:77:?;<7=42669774=5;5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=88567=:JFDGN[\YJf`;H„‹z{n…†z|„x…~px|~}orz}|x†‹‰†„’§»¬¨²½¯¤­²³¨£¢°¬Šš´¢¸¤•­¤—©­·¦¤£Ÿ™©—©£¯°©™˜œ”•‘— ˜š»»®Ê¡j¶¸«°”™ž£«“—½£^ª²‚‰Š”‡‘|ŽŽ}ƒ†Ž””ˆ‡“–Œ•‹Œ—˜’œ™´—–«‹œ”’‘’Œ™›Š‘ž‹‰•Ÿ¡”˜™œ’›˜ž”¡ ”œœ¥¯¨¡¤³¸«ÂÈĵº½»ÅÇÇÂÑ ÆÉÍÍÄ×ÖÑËÔ¡oyg[YS^POEC><CAB8?875?F<<5<35355454B39:BM:B;AHB;:@<746<B9?@B874:96>=47TKCUQJ7<:IAE@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPdGb`bpJ@‹Šs†‡}‚ˆuƒŠ‚m}}|pw‡w‡{Œ†Œ™ªÂÀ¯½Æ»³³À¼´­«³¶‹§²­­½ª›»¤¨­¹¸«¦¦¡¢££¨¯²±ªœ¤˜›——ž¢¦¥’¤º®©À¼­­²¹¦¤§~ˆ†œ­½°ƒŒŒ‹ƒƒ‘zˆœˆ‡—‹•—”‘š—¨š±š‘¬œŽš’Ž•‘–—Ž‘ ‘‰”›£¬”–”œ“ ›˜ ¡”šž§¦¤¢¤°³§ÁÆï°º¶ÅÄ¿ͦÇÄÇüÕÑÍÄʇrr`ZY^ZLJBL@FG>A?B;:4>A<=5=6>333242A17@BN>G@CNCA=C=;86CB5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GE?CF\eG`igZ]\“ŒŒˆ{‡‹†ƒŒu†‘Šo~{q~z•z’””˜“•§³ÆÉ¿ÂÌÁùǼº¯«¹º—²¶º²À®¥À¤«¯»¼ª­«££ž§ª®´°ª› ª›¡›•Ÿ°´§‹£ºº¶Á¼¬¨œ³¥¤©”…Ž©ÄĤ‚‹‡ˆ„†•”zƒ‘‘¡ŒŒ”’ˆ— ˜“™•˜¦ ®ŒªœŽ–’‘•••‘¡”†—Ÿ ²ž”š”Ÿ¡˜¤Ÿš › ”˜ž¥£¦¦¤¯®¥¿Ä®¨·µÉþ¶Ï²Ä¿Ä¼³ÑÉȵswk[W[iQLHDLJKJAA=CD<5AD;:3=8B332262A05IEM>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBfZNe\fTcj™—ŠŒˆ’†‰y†”r€|x‡‚z¡–¨šš˜º½ÇÈÉÁÒÉÊÂͼÁ³­»¾§º¿¾¼Ä·¬Á©¬³»¾ª°©¤¥£«­³­¶µ Ÿ®ž¥¢˜£³½©›¨½Á£··°«“±­«¬—‡š©§¥‘‚Œ“¥•‰vŠ’z…’žŸ“”‹”£™—œ••£ž©Ÿ‘¥šŒ•–ˆ|•’’£š• ¢œµ¥ž—¤£¢¥ž¦˜ž•—›¤£¨§¢²¬¨¼À沈·ÌÀ¹¯Ä³»¿Â¸­ÂÃÂÀ˜lx`WVZZJKMJFDDHBBADL:4DH9;4<7E.12352B26SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQG7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>jH_XaZddVžŽ—Žž’‰Š‰ “„x…•ˆŠ€–¡™®¦£˜Â¾ÇÃÇÅÓÍÎÍ˻·°¹¼³¼Ë¼ÃÁµ¶»­³¿¹¼®¯¨ ¨§¶­­©²·šž¬¢§¡«·¸©¤°¿Ä±¾¹³§ªµ´®®—–¥¬¨ ‘Ž’±Å§•Ž}‘•}ˆ‘™ª™˜“““•“¥ž“™”¡£¢œ˜Ÿ˜‹ŒžˆZ–—’–¤™e˜£ž²¤–¡–¬¬ª§›ž¦—˜–˜• £¨¥Ÿ¶«©¹»Ã´¥³µËÀ¸ª¶¬²»¸®¨¸º½¸‚kmYVTTMEJSNK?BHEDHGG95FM;>7=@J.32025B55PVN<LFKRLOHGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|gV;=@BFBqFiIRebLF¥”œ–¡—©–‘ƒ‡¦“ˆ‚‡‚œ„ƒ•“Žš¢Ÿ¯¾®¡Æ¼ÅÄÆÆÎÎÎÒʾ»¶±º»»¾Ï¶Ä½¸¸·²±µ³¸³«¦œ««¹ª¨§¯¯—£®¤§¤¤µÀ°«¬´¿ÃºÀº³§¹µ¸³¯•¥­®®¥‹“•¡tÁš~—™…–šŒ±•›š•““š™¥£• ›–š©œ¡ ™ŠŒ–`J–œš•š¥–T–°Ÿ®œŸ¤”¯®«¥š ¥”“˜˜ŽœŸ¦¢™´©ª³¼»»ª°²Ç¿¹¦¬¬­±±£¡²²´¤ole[YNOKEOPPQ;HJHGICC>:KU?A:=EM07544:B34NWO<JKNUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@BAF3>58JKCA=C;4EA:A?>H@5*B52,>c]g:35tde@R7&#3}hW;:BC@=QEWSsbWFHª—™ ¢¨¯™‘—‡‹§–Ž‰“…Ÿ‡„—Ž¡š£¤µÈ´©ÆºÂÃÇÊÈÇÌÍƾ»³®¹¸ÀÁ̵ǺÁ¸µº°¯¯³´¦£›ª´´©¨¦­¬š¤­¥¤¨¬º¿¨«¶·¾Á¿¾¹³²Ä²¹½¬£®µ¬¹¦ˆœ˜¦›v¿ …™Ž“™š‹¯—¡œœ—•›Ÿ¡©Ÿ¨ ™šª™¡§ž˜‘ƒnv’¢š•¢ž®²¢ª”¨ª—ª­££Ÿ¥¨’’™œˆ”œ¢ž—±§©«º¶½³²­¾¹· £§¨¥§œœ­©©Œbd_^QJLFHNIUL=MDNJKBCD<QU=AABDO18=77?B75UXN?HNQYSPQUKQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW;:=..R`MUHe^HE«•œ¡Ÿ»¯™”Ÿ‹“«›‘’“‰«‡¢ŸŒ£­”££¶Æ½´ÁºÂÂÇÈÅÂÍÈÁ½¹²¯¹´ÀÂʵűÁ¼´ºª¨­¬°¢£˜ª´»¥©¦¬ª¨¯§£ªª¾¼§­¼´¸½Ç¼·µ·Á±¾À´©µ·«¿¥£˜‘¢ ¼Ÿ‰š ™—žž·Ÿ©œ¥£›œ¡š¨¥³¡›ž¦œ¨ªž™•”›‹—‰Œ¥¢”¢ž ´¯¥¤“¯«™««¤£¨‘•• ƒžž›•©¤¡¡´´ºµ­¨µ²³žœ£¥š—•™ª¡žv^[_]JHFGMQIMEFGBRLJBEG@VRDH=AGQ1;B7:BF79\YKALPTUSMWRNUJD@JJNO9C?5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*BdT49-1:g\FCCœpbGE§—¤ŸžÃ­›—¥˜™©œ–ššª–•§¦•­­™¡«¶Ä»¾·ÁÂÀÇľÍÆ»½¹²¯¸³¿Âȵ¿¯»¶¸¶¦¤ª«­  š«ªÄ¢¥¨«¦ž«¯¬¡¨¨¿·¦­¾±¸¶Ç¶µ¹¸¿²¿Á·´³´¯¾£—£–”œ”® ‘¢¢¥££Ÿ½¤©¨« ›¦Ÿ½¢˜£Ÿ¢©«¡—•ž“ž‡…“ž¤¡µ¬¥›•±§™¯§Ÿš©ž ˜”žƒ š›“¥¤š˜«±µ±ª¥ª­¬œ˜  ’Ž–¨ž”gbX`]NHGJNKHEDIA>PH@<GIH[ROK=HOU4BF9>HG5Ca[KCNRUWVQXTRUH@8QQPM:G@4CHQSIC;C>GVKC@O>K<06;GF>;FA56?9:?9;15D0-,/Mv\4KZ5,MnW<-=)#zbQ5CKQ:nRF<KxebWL¢š£œžÅ¬¡Ÿ¬ž® “£Ÿ–¥ ¦©«—¶±£ª³µÄĽ¿¶¿Â»È¾Êȶ¸µµ°³³·Áƶ¾°¸´¸µŸ¦¬ª«ž¥¤Á¥ ª­Ÿ¤©¬¯¢¦§½µ¥±¼¹·¶Ã²³·¹¿²ÄÀ¸¸®³µµ£¥•’”¡® ™¢©¨«£šÂ­©ž¬­››ž™¦¡½¢¥˜««¬¦¡™™Ÿ’Ÿ‰W–Ÿ¦¡ ¸ª¦“˜µ£Ÿ²¡ ›®–žŽ˜”ŽŸ—•Ž¢¤•¦®²«©¡¢¥¥••˜‹‘“¤ž‰`dYc`KHJJNFEAFJ>=JB99JKN]QQI=LV\9FI=DMI8Hb\LCLPSYYVWOZ^IA=WQIK?H@5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+w`S6SZkWrHE6=ue\KNžŸ¡™žÃ¨¥¢´¢œ²¨“«¤ ¤Ÿ­©¬»°¨¬µ±ÈÅÁ³ÂüÆüÄʼ¯°¶­°´¯¿Ä´¹±°¹´¬™¨°©©š¥¡§Â­›¬±œ©£­°©¤§½¶¦·»½¯·Ã­³²ÂÀ²Ç³º·¬´¶®ª¢¦–••¤¬¢ŸŸš¨«°¯¯»²¦ ©¨™™˜“¢¤¸ ¡¤“¯¯¬¥§Ÿ’¡ž•ž•š£Ÿ§³¦¦Œ˜³›£®šž›­ž“–“™‘¡–Ÿ¡“‹¦¬°¥¦¡œ ž’’š“…‹’œž`eZgeJILJRBC@IG;;G?99OMU^RSJ>O^]=HPBLLI9Mc\LELRTY[SUO\bHA?ZQAHAKB7FELKN>;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<v]^?[T^eq@8;H–weA4Ÿ£Ÿœ Ã¨¤ª²¡£´ª•³¬§¢¤²¬®©»²¬°´´ÆÀÄõÀĽÉĵÀÈÁ´«µ¨¯¸¬¿Ä´·®¬¶¹¥™«±«ª—Ÿ¦—­»´›¨°›­Ÿ­´²§ª¹²¨º³·²¹Àª·±Ã½´Æ§¾¯­·µ©¨¬¡——’¦¥¢£˜˜¥¯¸®²µ¶ Ÿ¨¤™••“¤ ·£¤¦–¯²²§«¦¡ž›š›–˜¨Ÿ ˜¢ž¯²¢¦Œ—®˜¤«—™ž¤‘›“–™„•ž”Œœž”‹©©ª¡§ ™ž•ŒŽ™…•‰”Ÿxch\jjMPMNT=CANC::I?77RO]^RVQAW`\BJSHVKH:Td\NFON[W[RPQX]GAB[PBG>NC9HGHOP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1[bZ33806p[bH05IphVCWFŒyfC;¤£¡¦¿¦¨¯¯¡©´«¹°«£ª´¶±°¹·°·¸¸Ä½Ãǽ¼ÄÁÆÀ¸ÀÆÀº©¶¤¬»¬À··©¬±º¢•­°­²–¥§‘ª¹© §°ª ¯´³ª©¶¶­»¬³³º·¬¸°Ãº¾¿¦Ã«°·®©««¦ž˜™«¢¢ ‘˜¡±¯³«°¹šœ© ™–’—¦¡·©¥££°±´«²¨«Ÿ›  ›ž¥¢—£³°šŸ“¥š ©š”¢ž•˜‰“—’•–œ“ˆ›™”Ž¨¨¦Ÿ£›—›“‡Ž™‹}Œ–…›jhl`lnWPQZTACET@;;HA7:XPd^PVWDY^]MLRN^KJ>Zc^NHPN[UYPKTWZI?DXPDF?N@=IGGQPB=DFBM?:1D?77547?=95E4+75/251.-.,1=*'+=\p=>1.1e[d@1647gY`F(?8l}h[V;‰{cC=§Ÿœ¢©½¡«°ª£±¸ª¥µ³¬ ­µ¼®³¸¼º½¶¶À¿ÈĹÄÁÀÀ¸Ä½À·¯¶§«·±»¾¿´¨®±¶ž—«­¨­—§¨Ž§»Ÿ¤­³ž«¢°°³«©¶´µ½­¯±µ¬°´±ÁºÅ·«¼¯±¸¬­ª£±¦ž¥© ¤—™ ³ª³ªª³š§›š•Ž ¦¤´®§¢­­®±§³­²ª¤œŸ¨£ž•¡™›¨µ©—™‘’ž™ž ž«ž——…”—Šœ˜›“Š–—š—¦¥¢ –•—“€”…{Ž’ƒŒ–elrgoq^FYfVDCMXDZ9HB6>]Qh\NY]G[^]NMRXdJJC\b_PLMNXWXPJVVWL=EUJEDAM@AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,,%2+*5K1/'__aU150=`V^8)C3YT\gK6ŒzfL@¤š ¤¬¶¤­©¥®®¶ª¯µº§¦°·Å·±·¾Á´´ºÅ¾ÌŹÂÀ¹¾¹Ã·À¹²´«©º¶º¹½´©­°µ˜˜§¬ª«›««Ž«½«®±£« °­³®­¶²¹·ª®®²¨µ¯³»½Ê²ª¶µ±´¯®§¡³ ›¨­ ¥•–›š²£­ ¦¯—¡¤šš’Ž£¥§³©¡¦²¬ª¶¥®±µ¯¤™­§š˜Ÿ™™«·¢—“Ž—œ¡—–“«ž›’’—Œœš–‰”’ž™¥¢¡ ˜–‘“•z‹…{ŒŠƒ‹’jmxmu{`EajYIHYZ={JFD6AbTi[M\`J\]ZRSRbaLKE_``QLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`U`/5(C_Q\.*B/JGP[H3cYTKD™— ±¨±ª­¦¤¯®µ©·´¹¤¬³·Êº´ºº¿¾´³·ÃÀÌȼü¶½¿¿·¿¼±½­§º¸·¶Á¶ª¬±·”—¦®«§£°ª”¯»¤¬±²§¨£±´°±°µ±¸³©®«²§·¯µ´ÃŶ©µ¶¬°­©¨£¶  §± ¤”œš•±ž§œ ªŽ©£ž›–˜¦¦¥¸§¢±´¬§²§­°¶¬¤™ ¬¨›œ›”©¸œ”ŽŽŠ˜œ¢——¥ ”‚‘•œœ˜–”‡–—š§œ£ ’–•v„‡{…„Œ‹mpwu{~\Kel\KNc\>b{GI8GgWf\M^bMXYWTXTi]OOHa]_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANHf27'GbLV%-B.=ELQ<3rkJCC‘™¥®¥­®«§¤°²³ª·±· «µ¹É¸®Á»Â·²±µÂÂÎÅÀÁ½´¼¿¿º¾¼²Ä§©¸°¶¶¿¼®ª³²œŸ§±­¦¥¯¥²µ¬«±±­©¨´º¬³²µ¬´­ª¬¨¬©¸­±°Ç¿¸¥º°©­­¥¨­°¦¤¤¯¤©œžœ›¯™££¢£‘¬ž£  ¢ª¦¦¹¥¬µµ¤ª«¨¬¯¶®££¨ª› šš’¤³™Ž‰‡¢ ”“œŸ“‘„’’š™•“‡—’•™§›ŸžŒ’‘Žw~…}||‡‰ˆpsq~}}\Sdo^NYf\FD–[G;NmXb[L_bNVWVWTXg^QRLcZ[TKGOTSNGIVS\N;P^IBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3Bc;6*HeHJ+:I?3BIS,>k<GHœª«¢©±¤©¥³´²´µ²²¡«­¼Ìº®À»Ç±´¬´ÂÂÑÅƾÀ²½À¼¿·»Ä§¬·¬³¸»¿¯ª±­ £§­ª¨¤°£ª±ª¯¬°¯°¯«³»§¶°²©²©«¦¥£­º¬ª±Â¹µ¬º¨¨¨­ª¨±¥©¤£®ª¨¢Ÿœ£¬•¥ž˜ž™¬¢§©¢¬¦£­¬¸±² ©¢ «¯±¬Ÿ§§©™£˜™ §˜†„ŽŠ‹žŸŽ‹Œ•›Ž…†”Ÿœ•—”†–““—¤›œœ‹’‰~~‡…|w~‡…†trqˆuk_Y`ncQsq\K;„|F>WtX`ZNc\NUVUWQ\b^SONhXWWKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*35>10485(5/*,.30;),,'%234$,2-860)(1<]J0.JgDF8<B05EKX1@”Z>LE•˜­¨¡ª³œªª°µ­¸µ®«¥ªª½É¼±¾·Â¯±¬³ÄÃÎÎþ¿³ÀÂúÀ³Èë®·­²¸¿¾²­­«¤§ª°©§¨±¦´®ª°®­±°´­´»¤·²«¬®§« ¢ž¯·ªª­º¶¥¶µ£ª§¬¬ª­¡©§¦²²¤¦¦¡¡¬–ª¡•š ¦ž¤¢ª¥­¢Ÿ§±·­®£¥¢›ª«­©œ¡¥¤¤˜ š•˜œ“‚ˆ…œŸ‹Š‹˜Š‚‹—£š‘š‹“’‘“¢™›™ŠŽ‹Š|†€ƒzt€„}sv‹£ˆxj^`ngWe‡cN?g“LEbyWbXReTMVUUTO\]aUKMiWUWIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*49?./463)4+*,+.#4.-+&(+79*&6+<-2,&06WZ.0JgAA<<C+:JO^4D†>HFD—’°¥£ª±˜«ª­¶«¶±«¥¬ª©¼ÀÀ¸¸³»µ¥²°ÄÉËÑ¿Á»¸¿¿Á¹Á¹ÀÄ­±µ±³º¿½²°®­«ª¨¶ª¦®¯ª¹¯¨±±¯²­¶ª··¦³µ«¬¤©«œ£ž³³¨¨¤´´ ¶­ ª¨«©¬§ «¬©¹¶©ªªª¢© ¬œ’©¡ ¤£¦£ªžœ§µ®¨¦ª¢£˜¥¦§ªœ¢¤£Ÿ™˜ŸŽ˜~‡Œ†„ž†ƒŠ‰Œ‚…”¢™Œ™‘‘’Ÿ–˜–‹Šƒt†ytƒzw~€‡oqggqx\`sˆkO^™VHmxUdVRbOMUTUPOX[bUHPiTVSGPYUI>IHOQPxLMV=<KD?@A<@CUC9AK=5;E13;97*4:=+-341*8**+*,))(/*&)%3;,$2)2021%/2Qb02?f=NX>C,>LT_/Jj6OD;–Ž°¡¦«®š¬¥­¯³µ¯«¥°ª©º¾¼À±®¸­¡¶¯ÉÇÈÑÀ¾¼º¼Â½ºÃÀ¾¿®±²±µ¼ºÁ±±²«³¨¤µ©¥­³²¹°£­¶±°³º«¹¯©­µ«ªž©¬Ÿ¢ µ­¨¡Ÿ¯²¢´ªž¨§ª¤ª¡¢¬­¨½¯¬®­¢¨¨ ¬™°¡˜¢ §§ž¨›™ª°©£Ÿ­¢¡“¢££§˜š©¥˜—™ŽŠ‡”ˆ}†„„¤–„‚Š†Œƒƒ“ –‡œ’‘œ”—Š†…xt|uxy€{tszh€†£ui^ekugˆ‹}SXp^JxsSdSQ^MMRYfNLVYdXFSiRQ?BNQaQ:IHLSIqQLS;<I?;<=;@@W<<?H73CB15:93-5::)-31--6)(+-,42#2)',%.;.&1.0-14%,0Lg:48_=ad?F1CP[[*HM9UA4‘² ¤¦¬¤§¤¬§´²±ª¤±¨ª¸¾Á¼¯¨¹ª¦®°ÉÇÉÑü¿¾¸¾¿¼É»À¸°¯´±º»·À²³»¬¸¬¢´§§¬²¶¹³§¨¼µ®¶½°½¦¬¬µ«­œ©¯£Ÿ¤«ª§œžª²¤³¨šª§ª¤©£©§©½«´¯®©¤ ®œ›³£•¤œ¥¥Ÿ¤›š©«¥ž›ª¡›’œ¡¥˜—©¨’˜š“Š‚…~‚ˆž…~}‹†„’š“…“¡Œ“‘‹‘š‘•†‰~r{y}|hw|zupp}h…x„ˆdahcr…zmfx]^VBWzmTaPRXKKNqu]HZ[gYEUfPD>JNDCA9HGKS?jaJQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11&/>KH0%90%,,09/,,+6'17#-0GjI14X=fcBJ7GS`U*=:DX?*”±™Ÿ ©¥¥¡«¥·²²¦©±§¬¸Á½µ°£¹¬¨¨±ÃÉÉÍÁ¶½¿µ·¿¹È¶Ãµ³±µ±½·¹½µ­¹µ¾­¡³§ª«°µ¸´«Ÿ½¼©³À³» ¯³µ©«ž­°£œ¤¨ª£žœ¥°¦° Ÿ«©¨¢ª›¤¨ ­»§®°® «£¤®žž­¦—Ÿ›¡£œŸœš£ª£šš¤¤–—”Ÿ¢–›—¦«‹ž‘‘Œ‚Š€€€{š•ˆ{~‹…Ž‹Šƒ‘—†”£‰‘‘‡™“€ˆ|yl}vxxc{zqpqrxh€tjƒgdhansŽmaip`pA\xlU^OQQJJMTYWM]^lWDX`O^PHMDF;7HEKO<rhKK9AE;;==;;=J49B<3;G<4?18-78;2(09/,5..=-*K>*49&'.34.0+/4&,:$41BhY13S=e_DL6KWeO);2OY=#“™¬™Ÿ˜§¤£Ÿ¨¤¸¯®£¯°ª«¸Âº³®Ÿ¸¯«¨´»ÈËÈ¿·Â¾¯´½·Ä¶Ã±®¹±³À´º½·©¹¸½«¤´¨©ª°®¹±ª›»½¤°Àµµ¡®¶µ¦¦§±³ ž¤¦§¡¥™Ÿ¬¨©ž ª¯§¡¦˜£¨ °¸Ÿ£±® «¡¬¤œ¦§©šš›Ÿ£•šž©¦—› ¨’™“™ž“™–¡©š‰Ž†}‡‚Ž}|¡Œˆx‚‹„‰‹‹…‡’™Ž‰•žˆ•‚‹—Œ‘|…{sp}qst`yxioqpoi~qczliec`f†_ZskrLL~hXZMPLJHPRPIN\_nSDX[RgOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23/:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%53=fd24M?e]FO=RZgH*>/YX5(—¦™–­  ¡¤¡·«±¤³´ª¨¹Å¶³® ·¬®­°µÆÈÁ·¿Á¹°´¼·¿»¾¯«½¯´¿°¼Â¸©»º·§¨µ¨¨«°¬³°§š¾·¥­¼¶°ž°·°¨¥§¯±› ¤ ¤¤¡—œ¯¦¡ž¢§¯¢ ¢“¤¤£·°¡¦±ªž¬£¯˜œª¥©ž˜šž¥“›š¦ªšœœ¥–•—•Ž”—£¨¡‰‹„z…~„ŠzŽ—Š†x†ƒˆ‹…“—ŒŽ–˜Š–~†—‹y€{prwoot_ywdllkihƒmerjkeh\cs_ZlviZH}][XOOJHHRUF2:_^lPDXVYeMIIEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<#8R=*113>D5,-'42+;+139cl84GAf[HTDU]hE.;1`T,2–£¡—•œ©¥¡£¡·ª¯ º¹¦¬½Å³°¯£µ¯¬®¯´ÄĽ³¿º·°³¹¸º¸º®­¿³´¸¯¿Á¸¬½º´¦¢³«¨©³«®±£œÁ¶¦©¶µªž²»©¦¦¨°¬™¢§œ¤¦”˜¡²¥™ž¤©©œ¢ “¥Ÿ¤¹¨¤§­¦ž¥¡¨“Ÿ©¡¡ ™› ’›œ— ¢«››™¡•’•–š”“£§¤ˆŠŽ…y„|……|œ‰Š†x€ƒ‡‡‡‘…•’’Œ•”Ž”{ƒ—ŽŠw~{ltrllsaxuhhjgeo„ghhdfij_hbifZezcaRsT[[SLIGIOS@!+j^jLCVU^`KIHEC.:B<F<6KPD8:D357==895?:;4>8@L=>93)8><:9*6@3.E4(+,>0-N?.+-7,1195,&.5-80576`tB3CDg[KWGU`hB378cN'2ž¤£’Ž¤¦œžžž¤µ¬§ªº·¨¬ÃÁ·°¬¢´­§¯¯·ÀÀ½±Á·±®±¶¶¸·µ¬ª¼³¯²±½À·®¼¼±¥Ÿ¶¬¦¥´©«®  Ã«©¦°³«¬´º¨ªª±¦˜ªž§¥‘™¦­¢™ž¤ª¡›¢— œ§¶¥¯ª® ¡¡• ¦Ÿ¡ ™›šœ’šž•¦ž­£˜—ž•”Ž”˜Œ˜š§Ÿ‘ˆ‰Šˆx…w‚‚‚œ‡‹‚‰{~„‡†„„••‘‘‘’{ƒ•†s~}fxokjlguskcgdctadefeijcipY^X]ldaMhWZ`VIGHKMRX?9`liGBUS\[IHFFA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A<-5B37=++,0A*JK./*+3722(57$+7.72685]yN2>HiZLZJVbfA:3AeH%5›¤ ‘Œ® ™˜ –¥´±¢±¾·¡±Æ¼¹°±£¶««®©¹½¼»­À²¯®­¶¯³¸³§«¹°®®´¶»¶¯¸½­¦žµ« ¡°¥«¯Ÿ¥Ã¡³¥¯±¯·­µ­¯¬®£™œ§ª¥Ÿ•›¨¥ ™¥£©š œ”›¬°¥¹§­¢¡ššž™ž£š¥–ž˜›”š¡’¨•¬©›”œœ’Œ•™Ž””˜¨¦Š‰{‚t‚Š˜…‡|‰ˆ„„‰Œˆ’„”œ’’‘–Ž€‚ofymhkjgqrk\hcar`dgjmlgjhfl\lmuqaTbhceYIFLMOXQPUaeT@VSYTFGFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24:6#3*)6.55465Z|]19Kj[M[KXdd@A1IdB'4“¢›Ž±›“¡š©²°Ÿ¸À¶¡´Â¼½¹±¦¶¯©®¥·¹·¸¬»¯­ª«·ª´¸­¥³µ±®©±¶¶±²µº¨©Ÿ¶©žŸª¢ª­œªÁ™®¥¯°¶µ¬¬ž±­¯ª£›œ£¬¨œ•œ§¤š©£¥–š ‘›£«ª©ºŸ¦¤ ˜ššž¡k¢•˜œq‚–œ¤€v‘«¨ž–– ‘‰—™€—‹Ÿx…“Œƒmi~wƒpl†Š†}„Š†o]d`g„—†k‹”’uw‹„~ƒf‡€huifW\itnNPjdfq‚f^dfnli^^_‰…‡hOKD8ETg^JGPPUUKGS`oteE[QUPFGFC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,,08>G701.*.*/668,#1'214:276Xl16Ok[N\K[fb>G1Pb<+/¤™‡•±›œ“ ›ª­«£½Å¯©·Ã¸½¼­§¶°¦«¤¸´²³±¹­ª§¬´¦°µ£§·¶µ¨§¬¶³®´­³¢©Ÿ´«ž¢¥œ§¨š®½•§¦¯³·­­¤¨®ª«¦¡žœ ¨§œ—¡¦¦œœ§§ž“Ÿ ™ž§ª£´¯£¢£œ–˜˜—£ˆ¡’š‡¡‡”ž¡¥§«ž““œ“‰„rxŒŽƒ‡ vˆŒi—ˆf}sx oˆ‡ƒ~Œ|¡ Ÿ™{ˆžtˆŽv›Šl‡ƒmheczlqbT†mcmi˜qXjpn†W^i[kj[ˆpmyr‡i‡„Z^FN>F^MFRVWQQRWTg^LYKRRPEGG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82*/1<I9/01.*/(-4583%&2115>1<8Xƒu25Rk[N\L\g_=K1V`7/(Œ¦—„¬™™Ÿ«ª¨ª¿Ã¯²º½·À¾ª¤·±ª¬¦³µ®¯³¶«©¥±­¥µ³œ¬µ¶´¥§¨³±­²¨¯Ÿª¡³©Ÿ¤£š¢£¯¶•¤¦¦¶¼¦¬§©ª¬§¦¢ ™ §¤™™¦£¤™œ¤ª—”¢œ”“¢¥¦ ¶¤£ £˜•“˜”œˆ®˜”‰©‹—£œ…±€¤­ž”šž•y‚Ô¨‡”À›Çyx±¥·—d€Àœ¿y„„yƒ|‘Êq–¼œÅ{r¶§º{l–±«°xhkX±®oei¼’¼nhzmqØ~Sjc¶²€q”uš¡ªWOWaOVNFT[XQPS‹\W[P@\EQNDFI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22BE/.32.+/)-/186- /416A1=:Wƒw21Tk\O[M^g\>L1[\41!Ž¦“§ªŸ—¥­²©±Â½²µÀµ·¾Â«¦´­­©¨¯´ª¯¶³¨§¦µ¥§¸®œ²±µª¥¤§²®­±¦ªž§¤²¤¡¡Ÿ—œ  °­•ž£Ÿ´¹¢©¨¡­®¤¢ž›š¢© ˜›¨¡Ÿ˜ž¨§‘œ§›”¡¦¢ °£žŸ£––’˜’™…°kjŠª~g„–‡­eqž•š¦•q®¡¤~wº|k¡v±_j´[¥€eœ‘`fzfjxj©e¾rg¦Œv±j|±xt’“cmm§m[„ Eig‡–Euœ`}f{£§‚Y_‹«i€”xzj§7J¯[WTlcZKOW_\WV;NˆOWV/ITSJCEF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3..53/+/(.0.:6/'$203B/=;U‚v2-Vj\OYL_gY:M5_Y31’¢•‚­§¥Ÿ£¤ª±·­´½¾°·Å²¸ºÂ§©°¬¯©©±®¤°º°¤¤®³£©¹©ž³³°£¥ ª­°¬¯¦§Ÿ£¢±œ£œ˜•˜œ®§—›¡Ÿ´²¡ª›¡­­ žš— ¢ª™ž¤¡œš¡§¤£š— Ÿ«Ÿ¥¦ šŸ¡••‘–‘š…µ›µx…©™µ™w‡³›·“–—©•~k¦z…‡’”’w«gj±[¬{Ž‡”tˆpŽ†€ˆ—xƒ‚‹—Œƒ …°vwŸqkjl|‹N¤XHcc™~ch¦`yruR“†^P©mcq}†€b.Q¢n[Tkg`LK\dX\ZB>°xWXA#MhFCDA@A19>88:84;:9<9:A:E::;6:CB8=?KNH:5:AFB@AD<FD;0201;F,0.840,.(/2,>831/2-D1<<S}n3+Xj\OXM_gW7J9aU50–Ÿ”ˆ³¦¦¢®©§³¬ª»¶Â°¼Â­¸·Áª¬­®¯¦®²©¡¯¼ª¡§µ­£«µ¤¦³³§£¢§ª²¨°§¥ž Ÿ°— š•–—˜Ÿ®£šš¤¨´®¡©©¨©›ž•˜ ¥©šŸ£Ÿœ £¥£•›ž˜š¢ªœ¥š››¢ –“‘““ƒÕ“™¹p°Â~Ɔ|֔›»|š–¥›Œ¤z‡£‚¥‚z¬yU¯{‰~Ÿj¹Z¹w†ƒ}¦‚“|˜zªy{±nŽ„t»…o”O¯§ÅŠQ zc`ªbsr‡l—‡_Sµ´È†€‰|c¤3Bv]QjhdP@XfZdaJHMlKZSOYfZCC?E?0<<59;74<;8=:<C:F:;>6:@C;6@OLH<9;DHCBCD<EF81211DB./0483+-(.323971#%5*>3==Qwj6*Yi[K\P_fT7G:aQ82%œ¡“˜±¨¨¥³ª¥´¨¥¼·Á°ºÀ±µµ¼³¶§±±£±³¦Ÿ¯¶¨›¨º®¢¯± ³´° ¤žž§©°©´©¥œž«˜™˜——–—¢«žš—¨­°¨£ŸŽ¬¢§–ž—œ¡¦¢˜¢¡¢¡š¢¢§›ž ž•™š¦ œ§•››Ÿ ˜’•‘ˆ²nhµq«ˆpŽ¦r´sr¶{š˜¤›¢~ ¥~°vƒ‘ÒÑu[®|†¤o›ª¦k†…}­}—™{±s“Žx³e–t…žnžf”RȋZÂ\Ÿyb_­`ws†b—ˆ^Yʝo¿uMKµSUÆdTQjceXAOj_liPUFI9=WR[WXHC?J<2?;5=<46>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>II:1746@>/.24252-).26,742&60;5:=Pqh9'Wi\BNT_eP5G=aM62/¢‘¤¯¬¤ª»­¦´¥¨¶»¼²»¿·¶´»»³¥µ´¢²²£ ¬¯¤˜¦º®¤±°œ´¸© ¦¡ª¥²¨¬ª¥šš©Ÿ–•˜™““£© —“¦«°¥¢–’¬Ÿ¥’”¡œ¥§ •›¦§¡š£Ÿ­š žž–›¢žœ¥”œ•™¢ž•˜–’›…¬{w¨v£‹‡©o­Šƒ¨ƒ™™¢Š’™‹¢~’˜‰®…‚³\r³R®~ƒ‚¤q×}w„~†™šw¯†Š‘œ‡w´ašeš‚•l’Z°XKšu˜yf`­^ww‡g˜ˆj]¯w•žxl5yÈ®²_BTo^g`EOk_pmVUM/eciSYQ;AD@L:5?91=<16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK96<46:>/04333.2..18*.32%!03767=Pke>&Vg\@=V_cN6GC`I:88Ÿ” ¸°˜´Á­¨²§ª²º¸´¸¿º¸³¶½µ¥¸´ µ­Ÿ ©«Ÿ•§¶¬¨°±«­´¤›©  ¨¢µ§¦ª£™ž•¥¢””œ™“–£¦›“§¬¯¥¡•˜©Ÿ¢‘¢š©¦¡•š¦©ž¤ž¬  ”ž›ž ˜˜›•—¡ ”˜‘§†©}}¥y¡ƒªp­Œ‚§†– ¡Š——ˆ£‡”ª|€‹yo±Z¨ƒ‚ˆ ytØv‡t§Ž›’¤|–Ÿ„{²^œd }‚”l’\«[Z“‘hgªds{k˜‡q]¬Z‰ ŽkneOJC¡\ZMt]bfMZa_st_JU5Jš’YHE=HFAL35A8.;>05A78@<6=<F?:<6?=B7.HVJE@H6KIN@IK@EN::@4.;>002154+*05/7,&21($$6671<PeeA&Uf[?1U_bL7FI_C1>8¡œ™™¾¬˜´Â®«­©¦´°¸±µ¿ºº³±·¼ª»µ ±¥ž¥§§ž“ª±©¯ªµ¬ª®¡˜¡ ¦¤¤º¢£«¡—›‘¢ •”Ÿš”™Ÿ Œ©°¯¦—š§¦Ÿ’¤˜¨«¨”—ª¨ŸŸ £­£ ¡”¡˜Ÿ ’œ—œ•¡•—«›®mr´t©ŒwŠ¦s´yt³€’¤£’œŒ‰¤‡Žv¸oŒ{‹¢kk¶Z¡†e——i ¢§m”r´t“˜²j†’ˆ­ku³af¢n†’j—\­`M¡|‡‘Rs£ly~n˜†o\¯V<œwfTon.[§ObSkeblZb\`q|cSYP>>mo3BB@?L9!7@6.;@37C58??3;<CDBJFMIF62JTKEBJ6IJP?HOCFP=<E50;<000/75,+,426/#00,,289/9N`eD'UdY>/U_aL5FM^81B9¥š›»¢œ²À®­««§·©¸¯µÀµ¼±¯¹¸«Á·ª«¡œ§¤¢’«ª§µ£²¨®ª¡—œ¨ ¤«¹£­œ–™¥£–¡œ™Ÿ‘“•«¶¯§™”›¬©—Œ“¦š¥­¤’—«²¤ ž¨«°™¡¢˜¢— ›–›—¡“œ©œ”‘«™‡Ô’š»t±Ä€Ã†}Ֆœ¸xˆ‘—Œ—‰Œ§‡y£¶u}wv‚š²`ƒºyÀ|u¸bµŒ‡©}–¬©q{u¼ˆ§ ia¦Ž¯¡~Œt‡«}¾ns¼t²ƒux€Šnšˆpm¤t½]w}[ay¼jZV[iy^i`dfbmxoY[YCA@r?CF+5H"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-7@9¦™ž¢¼¢—±Ã°­©ª¬±§¸¯¶Ä±»³®»°®Á²¬¥£ž¤¡œ›ª¤ª²¤µ§­¤Ÿ–šª™¦¬¹£®™•¡¦ “œ£ž˜žš–’¯¹°«•—£§§”‘–¥¤­ž‘ ¨« œŸ©¤²ž¢¤Ž¦¡”¡™œ—–¤˜° ’•ªž…™µ€‘‘¸•x‚“›µwnlnsny„Ž‰sžÁ»¼™z²¨p€t‘¹ƒ|††‹‡{Š†—|¤»¹½œuy³£tv—ut°u˜žf†i¶trpw¶Œ^€z}‰gƒymyb‹¬pu…X[§jDdZTf_c]bPgfqmuBMPLD;ZL>J3<0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITAKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7LT_G'SbV8*O]]=+;VV'=;<¦ ¡¿¦–³Ã´¬ª§¬«©»®°Æ¯µ´¯¸§µ¸­ª£¢¦Ÿ ™“¬¤­ª¦µ¨¨Ÿ›– £ž¬¤¾¦¡ª˜•œ‘¢›’¡¨¢“ž—’˜”²µ¶­˜¤¤¢‹’’¦œ¥«œ–©¥¦›¢©§¦£¨ ‘¬ž—£ž——˜ž°©”œ§¢Žj~iœ§x‰s~šŽuze‡{½¾Àºn’ƒq”†_rjZ]š‰ad‡Ž•k`€•cm›vb”kš•”e^`cq›‰hrŒ}†”fj~qty}|b[wthP\n„}{‹jXly‚rIJo…pMtMEW\faL[Wfc^OZmvjrRODEN;HI<M?2,2A?8/5?C<9;@;=C>RVVWYZ[[\]`aaa`\UG5DFUEJOHFPIIH;8=51:.0;:.0-76=5&"/*2,%;8-7IR_I'S`V4)P^L(3>[O'?2>¨Ÿ¨¡Á£š´º¶£¬¥®§¨µ²¬È¬°´¬µ£¾±²§ £©£›š™¬§®¤¥µª¥›˜•¢›¦­©¿¨©¦–”›• š“˜¥©¨‘ž˜œ°²¿¬›§§¡‰“‘ª›©¤œ›¬ £š›£§¬¢Ÿª¡™¯š•¦Ÿ–”Ÿ—°¥™¢¨™œ‘žœ£¤™§£šœš›š–‚hn|qv‘—”‘„‰´©…˜•ŽŠŒ˜—‡”•Šƒ’’‰‘”™“˜—š ¡š›” Ž‚z¤…li||€t‰Šq‚xyvvŠ€{‰jstƒudw}vkpzm`c[ohMXXej_WYpzonfSOFS9OZNRO(+:JB635=@A9:C><ENSSTVWXZZ\]`bba_^^[TKCSGKNDGPLOI<:;389,2;820)6IRO8")+/2#4;*7FO[J'R^S10T^:+=8]K,<-@² ³¡¿¢¤±²· ©¥³§¥°µªÉ«­±¦µ¦À¨´¡ž¥¥œ¤–• «§¬££·¬ ™–– —­ª¦ÁŸ¬¤–’œ—ž˜“”¢Ÿž£§’‘™¨§²Ã¯™««ž––©ž«œž ­˜¡›¢¥¯¦¡¤§ž¬˜—¦™š¡žžœ° ¢§–˜“™” ¢–£Ÿ— Ž–”‹Š–­{•›‚’‰©¨…€˜–Š„ŽŸˆ{„†…™‡†‰•Ž›—˜ž£–™’~e¡³®…‰„vzŠ}vyzogy€‰kuyˆrhtzvƒˆ‚ktcxf_hdcdfjXk{qjj\RLPD_UF@??,4@F;45;>A;<?>>HNNOPSUVVXZ\_aca_^]]^]XVJKLBIOMRJ;<:786/2964.(&$-1..)+*7%+<(6CMLD/T]Q05M[17E4\G5<,@´ ¹¯¾­«®²² ª¦²­¢¬³°Å°ª¬£³¯½¤´œ §¢¡™—¨¦©¦¤¦³µž•”ž™™¯¦®¾ «£‘‘žš™”‘•¡œ—©…ž©¬¢³È´Ÿ©¤ª––˜š§ž©œ ¤«”žŸž ª®©¥¢ª¡¬›Ÿ  ˜¥žœžœ¯¤™Ÿ¨“˜—’¥š˜©žš—fƒ’|e~Žšcxlhkz£«kd™˜~g…Šeeihz¡ŽkgŒ—‘¢wkj‹˜¢Ÿ˜slnz„…yXe]…^kŠŠv[hsww‘€‡‚nx‚x€smy„twˆ‰ƒ{h„X]jsd]sˆij|qlc]QNWIdX@J4>F7?FD71<=?AC;;DGHHILNPRRTW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%.++'6*$;'/AI[I/7ZO6)EY/DO1YC;?.=¥Ÿº¼¹¯«³°«¥¨­®°§®®°½±©¨¤­°± ­— ¤ž¡š™¦«œ¬£¦¨©³®ž•£¢¯¦¶¹¥®£Žš¡™“’š ™™¦–{¥¬¢¨³Ã¸¥¢§¯Ÿž•ž£Ÿ¤œ¤ª¨’ž¡ž ª¯©ª¢©Ÿ§›¦Ÿ§ ¬•¡›¥°¤˜œ«–¡ž›“¥˜ž«™ž~¾ƒˆr´r…ž†­hx¹Ä¸q’¡£{¦˜™sª‚|ËÀÀ»q‹¢‡ƒž|•˜ˆžÀ½‚–œÁÁ{z‘ŒšÂ¿}k¥±oŒoÊz›x‘ƒŽ€vyyqz‡px…Œ“ylu‘be^xd_eb^thmdbXLVIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^__`_^^^^___]\SMPGUNA??=6468276*&%#)*&.+*)109*#>H[L*#CP/#F[3PY/UAB;/8–£¸Ãµ°¯À©©”£¯©°¯­¦²µ¯«¦¦¦±« «˜›¢ œ›ª§¢«¢¥©¥¤´¤£“¦®¬¸´§¯¢’‘™¥’‘ ¡˜œ ‡¦«¤«­¿À±¡ª®ª–’Ÿ¢™¢¤ª£“ ¡ž¬®©«¥£¢¥ ¤¥œ­©‘¤›¨®ªœªœ¬¢–—¥–¡£˜œΔyz¥‚z•–›_­^Ž§€¡ |§•›t«ƒ€¯^d©z§‡…Ÿt—’ˆ³c‚«† ²j„®t|–‡¸a‚­Y£Ínu{Û{™q~ˆ’ue{ˆvvk}ˆn~…’~l€_pjof`_xd\qhjcf`RTRW]JOC5AHED8>6;@?A;=8@>??BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5577164('$!',&&/(&+360$7;SL+-.J0';\:L-!P@F4.1­ÂÀÀµ´°·˜ž‘¤ª©­´«¦²¬­¬¤¬¦°ª §›š¦˜œ¢°Ÿ Ÿ¨§£¦¡Ÿ°¬›ž–¦®­±«¨¬ ”’›Ÿ¥“ž¥—¨£ž®¤«°¨¿Æ³¨©±®–“œœ¢— ©ªŸ•¡ž®¯§ª¨›¦¦£ ª’­³–¦£«ªž£§¦¡°¡’š§š¡›””‘— p…Œ—u„¨‡q°|r¬~¡Ÿ¥žw«‚}­œr­~«‡†Ÿv˜’z|—~ªˆ¡‹‘‹œ~«{ˆ’Ž €z­VœÄzo’Á}•mupŒmfve†oawnrnˆŠ‘ƒmŽdnsuo`fmd_niinfcWT\aZRRC8II@D<><@EDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;91478452&# 1' 1''45-&7>WJ-<(=1)3V@F!G:C1.+¯ÔÆDz´Ÿ£Ž££¢­®¶¯©°§©ª¨®««§¢£™¢•Ÿ¦«Ÿ¢¥Ÿ¨¨¢Ÿž°­˜›–¨§¯­¨§©ž—•š¤¢’”¡­›§£®¬£¬µ©¹Í²­¦®¬—•›œ¢™Ÿ®¬–¡™žŸ©±©©¨šª¨£¡«›¯±¢¨¬®¦™¦«ªª±£“—£¥š”’…¤j¤u‰z©tz²q‚¥‰˜Œpˆ š‡¤_`R«„®‚›u®‚§††Ÿz˜–…{f€£‰¤˜†£}©~€”†®^|¨U¢’z¢Ÿ€{ïŌs¯³³¹qb©¯ÂuhŒ‹—l™‘nmxwwnlfedqpf{ic\W_iXXTLLQLCCAB;C@@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799664,&$" ('"+-"$.!3-&@DWH,G+56*1PKL# A9D4,'ÂÉÕÖÀ¡™«¨¡¯¢Ÿ°µ°¯©¬£¨¦ª««©¤¦ ›¥Ÿ¥§¦£œ¬š¢«¡¤Ÿ¯£ž›“ª¤¶°® ©›—•§¤‘›¢¨Ÿ ¦œ°¦£¨±¬¶È²µª¬ª•‘œ¢™Ÿ¥³š¡”œŸ¦««¢­™«¨¡¡©¢³­¢ª³²¢›ª¨¯¯¶£“–¤§˜›‘|ªlž„‡u«y|°n‚¤‹ˆŸ–•Ÿ•Ò·´¸É€²^_”©ƒ¤‡‡ z˜•™xªÉs™£”§©’›Œ~š‰šÆÆwe¡‚¥sŸŽ‚}¯^oµc±uK£†m§G‚“cŽ’{p–‘}ozt|zm\fjrqfi^aXcm\^YIMMKEDAB>A<B?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75785/)(%&%$&),5FNOPMFLJVF*L0/>-4OTQ;<F2,$¨¤Áƹ­¨²®¬¥¢²¹¬ª¡¦›¨¦ª¬©§ ¦¥˜ª£Ÿ®«¦ ¬šŸ©¥§µŸ¢—“¨«¶²¬›¦œ •¦­‘˜›¦¢ ª§®¡£§©°´Â²³ª­¨”‰—¥›¢£¯¥—¡•™œ¥¥«š®œ¬§¥ž«£·¬¡±¹°›¯§³´³¥•˜¨¤› Ž‚NxšŸz„£|‚¤„†¦žœž“„¸{|y¹‚~ÌŶxš ‹Ÿ~š–—Šuž—Š¤˜£¨~°…œ„žƒ¬}™”a¥l£p…}—ƒr¬`¤sq€š`¼}RUu‘£–{}‘ˆszr„~p[lnwrjnZc_hnbd]KLQTAHHFI:9K>B108856877-*5==?BDGILNPTVXYZ[\__^]__\ZZZYUSOH@772.,*.+*'&?QTVWWWYXXWUOUF<E2:P[T6?H,- Œ‡™©¬¤«¹«¯ ›¡¬³´¦Ÿ •¥®®®©¦¦¦š£§¡²®¡©¦² ™¨¤”¢µ¢£•—¡©µ¹¤›££“¢±™›¦¤¡¢¯­¤¨¢µ±Ã±­ª­ª‘‡‘œ§£¤¥—ž˜™™¥£¨™­¡¬¤¥—¯¥¼­¢··®žµ²¹²³§™ž°¢¤ž†ÑµÃ·y‡Ž…‘“€¦x”¢wŒ ’„¥‚‹q«†„´nri™£œ•‰Ÿ|˜™†‡r®‚¥›¢¦‹“‰”šmp²\¥s“zœl™{™}n©a¢qqŸbs²¸hx“¥˜}‹‹‘Šw|xlhwixsnt\ddnmeh`JZWX<GG@T3@F><*(63.013)&4:;<=?@CEIKNPRTVWWY]__^^``]Z[ZXURRQF:2230/++(@QRTUTSTVWWXXWUUVTQOQ[U%!2AH$)%’sŒŠ®¿¿»»µž—¨¤­¶¡£™•£©§®©«™¥¡Ÿ¥  µ§¢©§°£”«£Ž¤­£ššª´´¤¦œ©’”—® Ÿ¥£œ§œµš ª£¶«Â°©«©¢„œ¢¡¦£–™šœ˜›˜¥¤¦˜ª¦¬¡¤›¬§¾¬•¾°­Ÿ£°³º¬´§›©²¥¨˜z¨}|°wŠ€¤¥ˆœm²o ‡­|¡ƒ¨–™€¬‰„®…Ÿ”¨ ¢–…Ÿ€™•€{’}«€š–Šªx ˆ“’€y¯]£|¦§d€|—tk¯]¥kq…™]`[Œ n•‘¦™‚“‹•Šyy‚–jl~b}tny`feqohghCY`[=JT2T8BBC7$$3+''3, /667436:@CFIKMNQSSSVZ]_a`aaa^][ZXSPONI7052.*,ATVVVTTUUUUTTUTSSVWWXVUUQHFIJ#((¼’š„©ÆöÁ´Ÿ›­ ®¸¥¤Ž›¤£ ¯®©Ÿ£ž­˜ž¹ ¢« ¯ªš­¡ª©¤–‰š®°¬¦Ÿ¨›­˜˜­¢¡ž¥¡š¥œ­˜Ÿ¨¦¶¨¿¯¥©¤ŸŒ€Ž›› ¦ž’”™š”šš¤££™¨««¢£ž©¨¾¤—쪣¢¬³º¬¯§¡´°©«™v¯~Šœ…‡|º­‰˜d°Œe•­} ƒ§–š¬Š„°…¥™¤¡¢„ [lj³`­{{‚±lgn™—‹ˆ±[}´[¤ƒkÈ¢eŸ{¼YvµZ²}R¯€z¬X€¡m—Ž¨š‰–”•yw›}cr}aƒxs€|aifpmfeeOUc[AT^=I(>9=4!",%2. *1/04579:<ACFHJLNPPRTWZ^```ab^_\[XUPMJGC553./@UYXWXWWXWWXWVWWWWXWWXYZZ[\XWWGB;ҟ³²·½»´Á³£œ­¦¥¶©¡‹™ Ÿ³²¨ž¢Ÿ´˜ ³¨ª«ž°­ž¬›•®©¢Žˆ›Ž¯­¨¦£¨™®“š©š¡ž¥Ÿ™££¥™ž¢©²¨»¯¥¨ž|‹›–¡ š‘š›‘™—§ž¡˜¨­¦¤¤¢¤©»ž Æ§¥©¢«´¶­®§ ½®­­–©’£®Ž›€†¤—˜€¸ÃºƒŽœ“„§—œ‚¬Š‚¯ˆ¦›š¥ª‘~սªb£¿½|~£‚ƒ×º¸µ…“’‚ž½¾„j£o«„nœz²±Çƒj«°½­xw¢¾»t€•¦›Ž™•›x€™yb|zcŒgx{`kekjbPb[Sj\@TaBM)<:4/$%2 $(0496678;>ADFGJKMNNQTW]a\__a^`[\YTQMIC><A?5=SYYXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ¼•´´±¿¹²½³¢®¦¦³¦žŒ˜¥¿ª·°§ ¿¦¦±›ž±œ¹¨ž­¯¥§•”¯¬—Œƒš‘¯¦£¬¡¥œª ˜‹£’¦ž§œš¡¨¢™ž «­©¹®¨¤›—“{‡™’¦›“‘˜˜˜“¨™Ÿ˜©¨Ÿ©¦¡¢ª»ž©Å£ ¯£«³µ«°ª¡¼¨°°štuª¤·…e‰Ÿog¬Šmow¤™Ÿu¯™•pŒq•§£›˜®¤rmmmeŠwnm‚™q€yipig‰••—qhi…†gp†d^‰cjpY]g~w¦`bqŽ’ofd€’Ž¢—–—”{†“te†whŒjx~ydlcflbKdXJkY:PeEQ'K9+# #,)-2.5:457:<?ABDEHKLMOQSV\WZ\`_a]][TPLHD=:AB7MXYZYYZYXXYXWWVWY]^^]\\\]^]^][[UW^¨”­³ªº¹²³ª©¢®Ÿ¤³ª˜’½±ÃȽµ©žÀ«¬£ ¦«Ÿº£¤­¬¬¦Ž–­ªŒ…•—­Ÿ¥ª¢Ÿ¤¤ ‘Œ¥“§™¨™–£ª –œ¥¦§¯¹«¬š›“’{„—¦˜Ž‘˜”—•§”ž—¨¢š¯¦¢¬¹Ÿ°Á¨¤³¦¬±²«®¬¨¹¤¯¸–Š¡¨¥¶œ‰–¡—†©š”“ª³™›£¬¡³—¢ ž ¢œ ¤¡•«¦Œ’“Œ‡’œœ”™“˜Ž•…€¤š—•‹“’Š†„}g‹€tƒvt‡Œq§m|•‘”“Ž“ •–•Ÿ†“‹pgŽvoŠwv|zilddocU`Y@iZGb`NY*E=+&"740.!%2(*799469;>?ABDFJKKMPPQWUVY^_ac]^UQJEC>9=@ASX[\YWXXXXXYXXZ[[\^__`^^^__```_YY`¥–©ª¥µ¸¯®¢°¤­ ¡¶±Ž«Ä»Äº·ª¡¥›¦°¨£¶§©´¦§‘˜¬£‹ˆ‰œ§–¬¤¡š§žŸ“•£—©š¨™”§¡¤š§™¡µº¨«˜š|”Œ¡”Š”‘•“—¥ž™¨Ÿ›µ£¦«·¨®Â®£·¦¯¯°­ªª´º¢¯½™’¦£¦µ¢‘¦ž©Ÿ’Ÿ£¬¯š¡£±©°˜¤¡œ¤ªžœ—«œ’™¡›“–ª™˜˜––ž‘ˆ ””…’ŒŒ”‹€~fŒ‡u‡vyˆƒsœj‡‘””‘Š}Œ–’’˜’ ‘›•Ÿ‚†—…xq”rx‰q{~jnd_pi`[`YmbP`dPZ:GFE=3==7.*&+)&&406658:==?AACHJGJKLMSSSUZ``i`eVPJACB;9EMV\^^[Z\[[[\]]_^]^_`aabaaa`bbbdb\[c˜•¤§£°³¬®£©§­ ¨µª‘œ£²º®««¡¢™z¢°¤¥±©–›¸¦£”™©œŽ†Š‰›¢®ž¤–¨ ¡’—™œ®‹ª–¨™¨Œ˜¨ž¹¶¤¥˜›‰y”Œ›“Š•‘”‘–¡Œž¨žž·£ƒ¯µ¢°¯t¤¾£² xz «³¼•v®¤ŸŠ€ª~d[avŸŽ¤ƒ—~n“³œ£¨®«£ež “sy™–p€˜¨—l¢§‰eœ¥›—˜–‹‘›…š”‚’‡ŽŽ’‰…wk‡v‡q|†€aiˆ‹•“‹[v•‘ghqz£—–dx˜†€v—hƒ‰‚nykpe_vokkh\fcbboR[>MNNRG=@TB91.&4:316678<;>@ABFHBGFIKLTUUY\_hfgWQJ<DG<9VR[`ab`^`_`aa_\]___aabcdabaaedchd^]fœ–¦£¡°±¬«©¥©­£§­¥’–ª´®±¥™©¦«–s‹œ¯Ÿ¨«§“–¸  œ¤‘~ˆˆšž«š¤•§¢žŽ—’ž…u®‰¦š¨‘–£ˆ›º´¨ ™˜‹‰uv“Ž–“Š“‘”Œ’ŸšŸ¦™›²–€Œ›µ´Œ’½§¡~§¢z£¯¸ŽŽ§Ÿ„‹…°©¯Œ‰–¢™y‹¬†œ¢¨ª¨ˆ•†˜w¥›z‡›—¦‚{œ±zŠ…Ÿ—™”˜–––„™šby‡„Ž’‹ƒnqˆzq€††t‡…–’x–h“t št|™ƒž›…˜~‘‰‚—iŒ„jx{qpgdwmilj[ejier[^HSLQ@E5-YTT6)!09=>643568;:=>>?DI@IEJKGRXZX[aahfYQH9DK<>bV^bded`aa`bb_]`aabbbcfgcba`edcgcaah˜£Ÿ¦®®«¨¬ ¨°§§ª¥™”­Æ¼°¡•¥¨´ƒœ«›§¢ ¾ž™Ÿš }…Ž™—ˆ«£– ¡’”‰†€‘¨Ž‡¢œ£“–†Ÿ¹²§š“…puŠ•Š”›‹‘ž‘–Ÿ£•¬ˆŸ´‰´š®‹Êˆ«®‰·…°ƒ±¯„©§˜|¨r{w›Ž¦–h•¤y´‹Ÿž§©’™Â«ˆ˜¡qž€š¤}—…•±¡| “Ÿ˜—€Ž“›‰˜’‹|…“†•“‰ƒms‘…€{r†…}…t…‚—Åf€©‡¢jž‚Ÿ˜™€Š‹ƒˆ˜o’„gwt{vghupfgk^bnlflXfF\PL2E46M`c6&4<DGD:64658;8>==>BL?NIJLCPZ]\Wb^jl\QE=KM@JdX]cfhgbbbbcc`_babcccdiicbbbecafcbbi•—¢Ÿ°¨©¨¥« ¤¹±ª«¦š”Ÿ¢¤ª¢•£©¶¢¯ ¦œ¥ž‰”½™“ ‘yƒ––‘‡«™œ›š¡…Œw›œ ‘ˆž¤›•˜—†¢¸­¥™›bm‹“ŒŒ—‹‘žŽ“Ÿ ˜¡¨~¡§‡­ –®Ÿ‘† «°‡¤ªšŒš~£v€˜“k«tM«x‡‘›©¨‚ª«}ƒ¡{z§iž’kg—†—¶ˆž}m`cXƒ—Œ{dg‹s™}y–l]|—n_Sq…\`lyƒ`Ye‚}„˜q§ªkƒ£nr¥pŸƒgdŸlZlˆzeY_‚~aWPovemtqjjo^jolkhWhN]WE9A4GC^k4+ICQMN=84859;6@;;>BO>QRLMBJ\]_W^_bv`MD:MOMTb\[ffiibbdaddbab`bdcabikdbddgdbgeach˜– ¹¡ª£¦¬’¢¶¼«®¢™—Ÿ¡¥¬¬Ÿœ­´¢§‘ ŸŸ¦œ™Ž˜´™‹žŒ•‹u”‘Š¦––˜žž“…†¬¤‡œ‘Š˜¨—™š‘‡¥°¦¢•™ˆ‰€inˆ‡‹ŽŽ‰‹’‹‘¡Œ“žŸ›¢¥“£¡” wœ–§ƒ¡§€†ª®…¥y‹}„š}¢ps“‡–{žŒym‡›Œ™›©›‡|‚¢sv¦fž~w¤_˜z|’s¢n˜·´ºt’‡€¶¨dÆ¸{p•·Œq€›¤ct¬«`}j³~n}‡ƒŽ‚‹—q€£ls¤sžƒ~£^™³–o{—ž³tr[ž²‚ibosuqhoYklrre\h]bKD=D5QAYq2<RF_JS=<395::6D;;@IP?TMNQ@E_^[ZX``|dIC8LWUVbaZefkkbbeadc`ab`cc_`cknccddhdbgfchh”–•£¹™¬œ“ Ž¥¸µ®­ š¢œ££¤¬›š±¬«’— ˜ ¤šš”ž«›‹ˆ’x‹…p€–Š “”—}‘‰Ž¨¡‡˜Š’£“›šŒ‹¨¨¤ž–‡„~k{†~}ƒ‹‰“Ÿ‚—ž  Ÿ‹‰wœ˜¢Œ r¢‹ˆ©ˆœ§‘—¨¬®Œ}z ™z£“x€s—ˆŒœ}–Ÿ†›™›¦†£d¡|‰–›lžhšnš™zŠ§}rgsªƒ‚sªg”š]›…v„hªj¸f\©pœa•Œ^§vu‰Šžhšu‡“’˜Žžn™k¦™\¨~w»j}©ZŽ„]³g\mqxwki[pixxb^eWbAPDO7VBRm4JZZ_NZD@151;;7H?:CHU?XRY]>Db]V`Qad}iEB9N[^YdfXfgnmbbe_aa__``ec^bdoq_deekdcihgki•œ‰ª¶›¨‰c•œ¬º²°¬¦››§Ÿ­š°§«—¢™¡Ÿ™–– £™†‰iˆ€q{—ˆ‹––„’•˜zŠ„–£‰•†‹‘œ›‰¨£ š‹‘Š€€i†x–Œ{ˆŽ‡Ž•š~”£Ÿ ¢“˜rhŸŠ Œp’Œ‚©ˆ™Ÿ£©¡¨}°­¤¢¸—v£³¢£ˆ”xz«š~¢Ž›—ˆ—r¡|…¯µ}kš‘¡x~˜´££«¨„˜{š|œ™~sªZ]o{—‹xžbM{{…cz˜BMŸY¢jr|Žm‰„™u›y‡‰±³š’¦tmq|”o™ri£]•vHec`sp|}ne`khv{bc`Q^V\TV@YEQgDRW[bX_ID=B8@B:IE8LEXAVQ[VDFa\Z`K`m~rEC<U_bZejVghlnbff^aa\]^`hb_ecvl^egfldelhhki“±®™„S_¡§´º³³©š¢‹›©œ›¨’¡«£ §Žžœš™•˜¡–‡‡‰w…ny•…š‹}‘’–ˆr€‰’ œr‘ˆ˜”Ÿš„Ž¨œš•Š‹Š|„l„…q¡Œx…ˆ‡’˜”|“¤ ž£ˆ®†}µ„ž{¦–z©‚–‹¡ž}§hwm~™s sq|…˜o“‚®}£ƒ¦žš£p^©gu£co¥aœÓ|z™xrsc¢…~¢r¢Žuk³‹`‚˜Šsª²¨¼wƒm¿¦ª´^›o~q—os¢r]£gt¦ah¦m›Ó˜z‚›nwy—k›zv—rl©¥g_dyp~„kgfcmvwf_aR[eQQbIWIT_WS[ej\eQECKLJKBJD8P@QNWSXORQ`eeiRdxywIFEc]eZhjSihjocjg`b_\]]_hbahe{d^dgdkdjlfhlh˜›°¬T\K~©°²µ°³£œ˜…˜¦  ¢¤¨Ÿ—¨‰™—˜“™“’ —ˆ…{p}„h}ƒ“šw‘Ž‰p†’’l—“|ˆ‘£•ƒŽªš”’Š…‰y„v‡€nŸ†w€’†ˆ™¡–y“¢£š ‰³¡¢¶‹z¬§¤®¥p©€š…œ’}¤€¢™†˜rž„¢¬®‰—‹€Œ¤–ƒ®¢”vµ¶µÉ¡t”Š€Ÿaž—©mx–†Ÿšu¡‡w }–ŠoLf¢’pšˆs¤{ytaƒ‚l~ lrd`œrt—i{i³µ´Æ¦s˜~{j›š«t‚šmsw—išyt˜qPE|³^jujx‡fjgbttpmU]SYhPRhIULXRV]gknVgWMJAJMJHJNAQJPecimetrs~x{nu‰{{TPOm]h[kiRjhilglfce_\\\^ibdhk{_]dgcjfnmeile¢œ‰¯§…f?”¢³«¯¯µ¢¢€—¨¢¡£‹¤¦œ¥š—–—›’ˆƒyjy†eƒŒ~– yuˆŒi„…’ƒŒ…zŒŠ”¥’‚—©—Œ‘‹€‰z€}‹yp¡†y€”‡‰–Ÿ””¥§œ––„gnxœl¢d|q¥wœ˜pg§—Œ{¥z –ƒ—rŸv€‰”–¹nŠ¢b}™¢•ˆnriªku ln¦`›i‹h–‡š•u¢€}š_‹…Œuoˆbh¡eži›updfˆ‚nr¢Z_[d¡n^‰Œo{srd¥nx¢dg§h˜r‹˜n¡oRˆo ^d§T‹]S˜mmrjqlphkxskoQWVVfYSmIXO\HXihsjYkVQREV\LXRaUhj^wuz|p||r‚{rv€„v^QsagbpgPjhhklngdg_]]]`jbjivu]\chcjirlfkmc¥˜¦zetm‹§®¥ª°±¦Ÿ‹€–ªœž¤Œ¡¡š¡¡€•˜“š‹—Š{†q€ˆh‹‹|—šstŠ}{eƒ‡•ŠŠ•™‚|ˆ…–¦¢«…ŠŠ}€€Žsi¥„}…“ˆ˜Ÿ‡’ª¦ž‰¦x–œ~¥‰–Œ²˜žƒ¯—Ÿ¥x–ˆz©t¥„šn¥¢Œ’„Œƒ¼n|¥¯‚†…†“–œ }¦zq¨” –gž~o«b–Š•’w¨l©¢‰v‡‚w«‘¦ˆk‘°kv³Œ©l‹†nmŸž’•a~«‹ªv€§ŸwŸ}…¤• iš‡u«fž­Œ¶sw¾Œ¤“Yƒ¦«auqso{tpbj~nhlRUZU`a]kM]R]I]lmv`[qY[`Zgsenorcqt`w{~yryƒsƒ~{{Œ‚€vbxdcnsdRlgholrifia_^\ajbllzo\\bibmiwmglnb•¦ªœ€ž¤–©ªž¨§®£™‰‚—ª™£‰š¥œ¨„‹š…œ‘…’‹t…zˆƒo„}–“tt†r’‚m‹’‡†“}{„—¤¥¥€‰„”uƒ‡’olŠ¨€‚‹“ˆœž‰Œ“ª£ €u•—ˆ~y”®£›q†xŒ…€{r§Œq}}z—–›„Žx{~}ˆ”•“Šv™Ÿ¡„{}‰kŒ…[yyryphn}‘‰qt”“q…ƒe_€Œwus”uozon‡m„†_whxŽf‚†Žªœ~t}—j‰ˆou|„umlfŒsx{—w„[jXxhmwqpowwo]l†migVY_W\dkdUaU^Q_pwykjwejjju|qqtsaoubs{xuy‚u€€x‹…ƒ}{mldyn^Wnghukxjiid\`ZcielpunZ[bkdkkymhloaŽ•º©§‹¡¢š¦¤™¤«¢ ƒƒ—«‘ ‰š¦š¨˜‚›‹~–”‡Ž‰ˆr‚|}~„z—Žtrƒp•…{}’‹††…x~€†˜¢Œ{§¡‹…„•‚†Ž—wr„©…’œˆžž‡‹š§  «ƒ‰Ž•š~~‰–­¨’§xpž‘ƒ{“o~©…p}•qjo|Ÿ‹’ŽŒhm]ƒ‹Œœ›Ÿs•‹ˆqtk‚vsYrn†}~‹i]icz…ƒˆ€_ix{›|ƒŒƒv†ƒiy‹‡kaqsƒw`sŒ‚‰§•†fƒnv‹ƒo„Œxndfcy‚z•Z\ifnv[zywtmsr‚f\mŠkkbYY]ZXkq[^`Y^]fs}{sotcjji{|qzwtdmthl|~uy|{zy€o†Š„{}s~ysiT\qilvpugkgd]aYjhkjqrmW[enlgsynhjm`ŒŒ«±¢£¡šŸž˜ž™©£¡}ƒ—«ŒŸ”‡›¢¤”{—„|’™ˆ‰††Šr}€‹v…‹„–Šqo€r˜†„~’ƒ„†Šz€ƒŠšž‚¦ ‡x—ˆ•‹‹œ—…ƒz¬—™“‰ž‡ˆ¡ªŸ¢¢£Œˆ“›œ£™–ª¡§¦ ’›ˆ—|yŽ„¨~’‘’“œ°¥š”Ž²“˜„¦ŒŒ•› ‰›‚‰‘Šk|Žvwe‚†Š|‰„‡‹‡ˆ€„ƒw|zuš¢‰‡‹Ÿ‹†•~Œ€vqt†…€xˆ‡Š‘¦‘„†ŽˆƒŒ|†Š‡Ž€ukƒ{y™irh`sŠp}zvuowt\^o‡hn_^Z[\SgqUc[[alht{|rnpcjih{mx~qhoplf{r€w€}„{m‚Œ†|zx|~zƒxNdvjsnp{ekebb`[sfpfrqlU]ltmiyzpgikeˆºŸ–¢¡˜•™˜”˜¤ {™ª…ŸœŠž–|x”‚{Ž™‰†ƒ„†mx€r€‡~ˆ“„ml~z—†„ƒ~€†„†}‡ƒŒšœ’‡ªž‚qŠ…’‘‹œ‘}z©ƒ’—•Ž›–††›¦ ¢š†ƒ’™™˜š¦Ÿ¦—’‹w}ˆŽ…¥{|‘†˜©¡œ“œªŽ’€ž‰“šŸƒ—‡Ž‚ox…qt`~ƒ…t‹—€ƒŽ‚†„~…„”nyuu“¢‹†›……Žt€Š}}rs{‰„{yŒŽ„“§†„‚ƒŠ‰‰u„‡ˆŠ{nj}{mhklg^y~g|{vsuuzv\`p}mt`bZ\^QfmSeZ]akivy~pklckjg€€kr€lktoxn„yn†€v‚€}…vr‚ˆ~{z|{‚Š`i{kuhiƒejc`i[cuhobumlTbqydpzzrejmm‹ŠŸ¸š¡¤Ÿ“’–—‹šŸžzw¥›‰†¤”‹˜™yy…|‰‘ƒŒ‚‚m|xr€…}Š}kh}—ˆˆŽ|~†„‡|€šš‘ˆ§œp‹Š‹’† ¡Š…Œ|§‘‡’—“–’w£ ¡–š™˜“Œš¢¡£š—‘›Ž…y€„‡¡€~Œ|—¤  ’™¦›‘‰“˜›~’’~‡Žut‚pv`}€…qŠ•|‡‹qŒ~‚……ŽhxryŒ™’€˜~ˆ‹r‚‡|}qz|Œ…{{’ƒ–¥“‹†‘|…†‡„u‚†‡ydqz~xypljf^}rh|uus|sj^`svpwdcY^^RjhTdX^agjvxqfkclhe€jm~hopj}w…zk‹r}tv‚†~|z}jrƒnsiaˆilb_qUtomn`xhmWjtvbuz{qbkoz‰Ÿ³’¥¥Ž˜† šœ|u£ –Œ¢Šˆš–x{†‡~ƒ‰~ˆ‚€p{tu‚…~‰xgc}†—Š‚Šx}€Œƒy–€”–•–Ÿš}o‹“†¥›‡Œ‰ƒ¥•„’Š•—’‘v‘¡¡˜”˜zŽ˜–Ž–šœ¤ž™“”›z†ƒx…—ž~ŠŽŒs—¢ ’˜Ž¢ŒŒƒ—˜ƒ“–š˜|ˆvq}mzd€|Š…p†’‚k‡‚‰„euo|‡“˜}”xŒ‰|€‡}|r€yŠ‡y…‘Š‹˜¢–‚„Œwˆ„‚vz€ˆ„t_ww|s}wfkd`~ijvsst}p{cc`smurmaY`^[ldRbW_`hkuy†pcjclfh|ƒkhthloh|ym†q€‚‚t|ƒŒ~z‚ƒ~|mu‰ttmeŠljacuVƒiqn`xflbjvpfy{yq`rl†…®˜¦¨žŽ—‡†Ÿ“—˜|w©œŠ˜y—œ‹‹˜x{€‹}|ƒ{€‚€xsxzs}€„ˆŠ€d^}‹•‡~„‡t}~Š}˜„–“–Œ¢ —~r‡{“‘Š¦ŒŽŠ’ ‘ƒ‘”—‘Š˜ š’’t€‘“‰œž¦˜˜•—tŽŠl†˜™z‡ˆ‰o—™¢“”ŠŒŸŒ†‚’œ“’•‡™ˆ{‰‰zqyjul{}‹}m…‘‚“woƒ}~‹€drj|—˜…Žt‘‰ƒy‡~vx~‡}„Ž…”¤y…ƒt‰‡}rt†‚l`ztyp{oanbd{anovrwwssav_nkuno][^]^j]O]Wbahmsz‰k_jejchw‡mflhjlg€|zwo‡s€ƒ„}t†‰z‚}z„}}Žry‹yxnl‡kh_irc‡hqofvgmlazhj|zxpawm‹™šª ¤©ŠŠ‘†ŠžŠ•—}v­˜Œ–}ž“‘–“ˆw}{Š|{€vw€ptszo…}€‰}{a\~‘†ƒ„sz€†z‘‡‘‘œ’¤›”}€|Š’¤ˆŠ—š…‘˜“•Ž‰‰Œ““Œn„Ž‘ˆž™¡ —–‰–’oŠš…g†š”z‰…Šp–š“¡’’ˆ‹™Œ‚€‘ž}’“Œ™{‰„‡tsukqnu{Štn†‘qt€{‚ˆ|eqmy~š”}…‰t‘‹t‰yo~‡}…Š…–¨{ˆ}~‹…w}pn„‚bgwstnzb^o`jt^pjzxxlrpex]mlsmsXZ^_ajZOWXdcgqq‡f]ihfbgqndigeih€zwuoŽ…s€‚{u‚ˆ…x„|wƒ…z€‰w‹|{ryƒjk_phtkqnmqgole{bmyvqlwwŠ£˜¢¨¡§›‡ŒŠœ†“œt€ª”‘Œ† Œ•“t{v„wxrs{…kroym‰v€€†mp[Y~‘ˆ€€€vu€ †Š‘œ— “—w‰~€Œˆœ‰†’—–„ˆ”™–‹‹ŽŠŽ„n‰‹‘Šœ– ›˜•…˜ˆk†¤ƒg†Š‘‹„‹w“˜‘‘ˆ‰•Ž~˜|‘š’}Š‚ovokmopz…isƒŽ—‰pw€t‚ˆ‚yftovš|‰…z•’zw‰tpŠ|‡{‹‡„‰œ£ˆ|„w‚‹€xxni\qrqoowZ^p`oj^oi|zpmmjmv`pojqmYXaabmWQSYefcup„‚b]kmdbfk’m`ff_gkuqrp‹€t‚€xv€‹€y…w‡†vƒ…|‡Œ€{vŠjqc|c†|opltjholvw_q~y{tut‚¥•š­Ÿ§–…ƒ—•ƒžuŠŸ“’…ŠšŒ•‹zrwt‚pr…squˆlomumˆwƒ}lmUQ«”‡‚x€vr‚y‚ ‘“’˜›‘šx‘z‚Œ’¤š“Žˆ•˜’ƒ†–™Œ“‹‰ˆž…Š}s‹…ˆˆœ™ž›–”€”i†ˆh‡¡ˆ’„‘ƒ‰qƒ‘—ŽšŽŒ‹w{’{ŽŒ‘–|ˆ|€kvjmkklz~ay}Ž•vzwƒŒ|ygulu‡–Œˆ†{”‘qz…px{‹{‰~ƒ‘žž…|}x‚‹}vphk€w^vomkprU]nbq`_mnypgpfgsuhpkawe]Ve``rSPN[fe]xpˆ|_\hrbbef‘i_hd[gp~okqsŠ}v}…€tuŒy{…€xˆƒs†…~ŒŒƒ{y•xfrjƒ`‡~ookz`intt_t}x†xtr…|y¡š±œ¦ŽƒŠƒšˆ€‹ž~Š™’Ž„ˆ—ŽŽ„vtvs€po…spqƒojivm‚n}|musRN‚ßɒ֓|ptƒuƒ ‚’w”˜›˜{“r…Ÿ¡““Š’›“…~–•ˆˆ‘ˆœ€ŽxzŒ~ˆŒ‰››œš•“ywhŠ’ˆl‰¤…“ˆ—ƒ†cŒ‘˜Ž”‰–‹Š‹q{”‰{ˆŠ“‘Šz…{~l{erojkyy[€y€z}~†Žzzhtkt‹Š‚†…}–Œl~oˆ~„zƒ–š›‹|wxƒxrlep‚khtoghslS^ndpY_kqxfkjbfxsopc_w``Vk_^vPNL`fc]yqŠt\[ev`aeeŽcafaXissnkqv‹|ty†uv~‹s†z‰r‰‡‘Šˆ|~˜vesn|eˆopl€Zlnyys`vz{vrwŠwyŸŒ›¯› ‚…wˆ•}‰œ†„ŸŽ…Œ—„“Ž‡uwpyqn„omn~rddxp|mz}jhlc¤šÁÜ®ï¡skuƒu„¡…‘n•”Ÿ”›‘p…‹£—‰Ž•Š•‚€•…‰€’ŠŠ—‡{u‰x†„›š—™Žv‹woˆŠŒ~‹¤…’‰……^‹”—ŠŽˆŽ‹Š„‰l{—‚}ˆ…‰‘†v…}}k}cxuimxsWˆz‘†„y~€…Œ~yftj€ŠŠƒƒ€Œ—†l‚vn‰‘ƒ‘…‚z€‘–”™ttx‡uspftyasloahufR`pgkU^msy`rc_h}qrmZbrabWnZ\wMMLcfa^vsŠm[\dy^`df„_cc^Xjrknkrw‹}sw„xw|ˆqƒ„}~ˆ{t‹ˆˆ•†Œ~~—shuqylŒ{ntpXqzvyqdwy†Œiv€‰r€ˆ™¨œ£’„}pŒ”xy‹„„ Ž|•Œ™‡„{swpsjokil|t^`xv{pu{g`e|ëÚµÉÃ܈sls€v‰šˆi—Žœ”’ˆp…ˆ Ž„‹•ŠŒ˜“|’ˆƒ‰{‘‹†‚vxƒ„r‡‚’›–“˜†Œv‡q†ƒŠ‡š¢ƒ”Œžƒ‰aƒ•Ž†‰…‰Œ‡€‡i}”}ƒ„‰ŽŽ‚q†~qwgvriswkZŒ}’„|ƒ€„Š‚vbtl‰‚‹‚“‘}n‚ly‡‡“„}~’”‘—‰nrzŒ†ulpjqw^shn\ju`RdqhfS_ovt_o`]h‚qriWghciXmW[uLJLef^brs…h[\ey^^dgzad_\YknenjtwŠ~ss~zvz‡s…ƒ|‡wvŠ…˜‚{“vlwuyy“unxz}Xy†q€ogxw’‚dv†…qŠ–…™¡›¢Š†so’‹rwŽœ}‰™ˆ‰{Ÿƒ™yrsnodr~iflww[_xzzqqiagaÕ¶Ž¦xnqw{q’Œ‡j˜ˆ›‘‹†{h‡‹™†’‘†‡—|Œ€€‰|Œ~Š…zu{‚zq…€”˜Ž’“‰u„‡w„€‹”Ÿ†–Ÿ~ˆa“‡„‡ƒ‰‚f}‘€~‚Œm‚|‚tkmvtsvukcŽ„~|„„ˆp`sq†|‚|’‰zqƒf{„‹‡„|…~•‘“„npyŒ~umnijy|agiiXkuZRiribPbrxlae]Zjƒmsb[g_dl_nTZoNHOfd\gnq€kZ[cr_\clwde]\Zlkbmjsv†qo||tx…x…‚|€ˆuy‰’•|ˆ†vˆpxy{„“om{w^ƒtmizs”sgrˆ}r’‘„šŸ› †‡vv”mv“—}‡ƒŠ™|‹šv~wqoljat|gbiuzZ_x|ymq~echhW^qr–¼Ä„vq”ˆ~r–‹†›’Œ‡rjˆ–€{”Œ„›Œ|Š†|{‰Œ”ˆuŠ†vv}qu…“…”ƒƒr€ˆu…|Š™˜‡”Ž€ˆf}“‚…ƒ‰‰q}f~‹{y~‡‹Ž}i€|ƒvfoxxsvslj…Š‰x€…ƒk_ry{~Š†|‚~riy„ˆŒ†…y„}˜Œ}nm{‰}wtngf{ub[pbWnrSSnshaMftxe`]\Xn€osYea^jm`pOYkQDSg`Zknm|nZ[^lcZbowdg\]`liclisvƒqn~|tuƒzƒ‚|‚…v~ˆ–xƒŠtˆryx~oo{qiyz~ml{u•kjw„tl”Ž†ž˜ ™…ˆn}Œvjx˜Ž~Š‚•—‰yŽ–ozspljd`szh`eqzZar}ygqzaee±²wJbZ¤ÙЖr{Šw~”Š„™‘Œ…nk…’‘zy’†€„˜Š|‡xx‰Š„–€pŒˆqt}ziy…ƒ¤„“Œƒ~oƒw„y†œ™•‹“”…‡p{’‚}‚ƒˆƒnwh€…xrƒŠ‡|e}~„ucprhxpou˜Œ…‚Š|vx€„yk\q~sˆ…‰~†‰{‰rnq…‡……s„z‚™„xno~„vzdgi{o^XvZXplNWqsg`Jlvt`][[Yt}roWg]fjp`oNWhQ?Yf^ZojgzqZZYkeYcqy_h\^emhekiqw‡ol~€uo‚{€ƒv…ˆ—Šq‚q{†|yy„“Œujzlo~u}or{{”onxf“‹ƒ¡™œ’‚†g‡ƒpgz•ˆ}~„˜‰|Œixrklf_anxm_box\dlƒzaqv_eeÔ꾊2:>‹Ž€qx…ˆŽvƒ–Œ~’Œml…Œv}…•ˆ|‚xnv‡„ƒ—woˆ…lu{tfy‚ƒ¦‹‚‹ƒ}n€uw„z‡‘Œ‘’“Œ‹†~{’†w„Œƒkrh€~xm||‚Š„wby„qdqh~mtqt›‹€~…~su}€so[mux‹ƒ‹{‡€|ˆxzql‰„„‹r‚z€—‹‹tmkw€€uu\hgvoXV{RYodLZrre[Ipxo\ZZY]u~thYb[genciLWfQ=^e\]ue`upZYTodYdqyZh^`gmgilipw}Žli‚„~yn€||‚zu‚“…p€‹nw~€{{ˆ’‰h{}jt{r†{sw}Œyx„}|kŒ„›–Œ€l~kh~Œz~ƒ”~}Šˆkuqghc[bgrn`aksahp‰zbst^cd› n\5Y¯µti€ˆ|’†u…–…sŠ‰vpl…ƒ‡uy‰x‰|“‡z~sgv‰~~˜pq†~hvymeyˆ„¤†€‡‰~n~v€}Œšˆ‚”‘˜‰‹„‰|ˆp{}„{h~lj€{zizv‡€r`w~qdrfu‚mu{„”‘|nwy|tmXp€wuŒ‚†xˆv‚‰zxsnŠ†s}“‰ˆznmjn‚‚un]gdrpQZzMZo\N[rpdUKsxiWYYZaq€t`]]`fdhifNZhN@ad[`ua]umXWStaZdorWj]ahkgmlipw|’li„‰||p~~{‚zw€Š‹ƒq{‡oqw„{‰ƒj~{mwxvŠw}x€‚‡ƒ~~zm…Œˆ˜£„ƒ{u‹ykl„ˆx}{‘~Šƒprqcf^Yg_op``gpfjo‰tato[adjv{¾œ¦£È¸q…ƒr’|x†“‚s‘Œ‡rroƒ{ƒtu‡tˆw“ˆyyqcw‡z€“ir„vgwucj|‚‡Ž}rt…z€’‘ƒy–Ž•ˆ‚ˆ{ˆˆkxy~ugzhlysizv€ƒ}h`w‡}jjsg{€iv€‹”~z}~p{v{t~bVw}rsŠ„‚}ƒq‡Šwxqp„‚~y~}vŽ†ƒviqimˆ‚rp]gaqmJeuK]nUSYsnbQOsx`RXX\ao‚s[a\heeckdQ[pIDcaZcp^]xhUVUw^[enhVk^ajgeoohpvz’niˆŒx}r{~y‚|v}ƒˆ†ƒpwƒrnwƒ‚}‰‹“p€{xyzŒtƒx‚„z€uo~Š‹›žˆ}…zw†{gt…‹z~{ˆ…„v€gon_d\XeYmr```plkh‰n`siY^dm€w©Ú©Ç†‡²q‰woŒu{†Ž€z“‰utu~w€pqm„t”†xuk`z‚y‰fq„pgvn[m|€“€y‘’}y{mˆw’Œ„t–Š‘Ž‡……{„luvmgvem{umjwv|`bx…yhtub}{gt†ŽŒ•{t€uqz|mYVtpu…‡yl‰†tylu€ƒ„~{}y{s‹|sgten‹„ms[j^tdGmmLZaWVUxmbPRtvWPUX^aq„o\`cmdd^obT]rGBf_]fh][{bQU\u[ZgkaVj_`nefkqhpuxŽtkŽu~vx}wƒ{s}ƒˆ‡ƒoqtqu…‰Š{wxƒ{|…‡x‡|}~„€{~svyŒŽ ‰z‰vtƒy^}…˜Œy†ƒt…†„w‰{bnm\b[[aVjsc`[gnof‡qaqfW\ck|Ê·¹¡jmmŠlq„q|„‰~{‘…yysyuu|jluc„u’‚wof^}‚z‹‰fr‚kjqcXmz…›ˆs—”w|n‰r‚‹Œˆr˜Ž‘‰…‹ƒ{x}qqp}fhqbmxqjkqx}|z\dy€wiuxe‚vgt‡‹”|q‡jn}yn|]Xrnt‹|‚ooŠqvhw€w}q{u‡|zrfsanŒ‚lrXj]v[HmjMUT^TU{kaOTurPQTV^bt…i\`kjfcYnaXbpGAh\`f^]V{]OUdpZ[jh]Wh`_rejhrgprw†xn•Štzw~xƒ‡ur†…‚pp{xwuz†…†Œ…z|t‹~}†„„‡~~}‡|xvyx‘“ Œ}‹mu€ycƒ†–…s‘Šo……zƒtcnjY_[]]Tgse`YdqrfsbkeW[`ix¾®{ ·mbs†hs{qy‚…{}Œwxrvo{vejn`‡uŽsjb^xy‹„gq~hkkZVow‰£„q™“q€yuƒnƒ’ˆs•ˆˆ„‰…}xtrnhy`jm`mvjgjkywzw[g}|xer}m„teu…Œ…•o‹fjzƒumtb\p}lu}Œ|fu‡}nqhux~s}l{{zxqflbn‰~mnVj_vUJijOQNhMY|hbNUujLPTU^fuƒf]`phgaWi][khJDjZadWYUyYNVmjY]le\Yec^teldqgrouxp™…v~w|…‡}us‚ˆ€•‚nsy{zss…†ˆˆƒx}u~|„ŠŽ„‚„{~‹ƒ{w|wwš—zŠ‚†iv}|lƒ„’r‚p…‚~oflgW][\[Tdpd_WbruiupeebW\\hpor€s‰ddx~itusr‚„x€„ywtumkzqbgkg†tƒnf]_}p{‰~imxfidUWro¦|ƒ{v–t|s}{n||‘…w™|ˆ†ƒ†ƒ}tprlgt\lh^ltdgfizo{rYg€vtgp€wubw…Š|”€n‹jmzqfsean{gsxŠ|~bvƒvjkqu{qzzt}f~ywndfbn…|mjViaoRJhjOKNpG^{faMUtcJNSWajv~e\gsie`VcWbp]LKkXcaUTUsVLXudZ_ka\Zce_wfmbpisnrutšw€w†„z|u‚„~—…nrt|ztq„…€z‹ut|•Ž€…„}~Œ†{~€v{£¥Šyˆ†„ku|zuƒ‹yo…sy„}ƒunjheV][ZZSbnd[Xas{ihmi`bW_[j€iko€gk`hyxjsttn„z}uunzhjyj_enhv„geXbwi~‡{oipgf]UXogŽ¨wz|Žyuppsvz€x•u†ƒ€…ˆvjrvghn[ld]ms_gajxh{mZm‚rsjo€~ywaw„„w„rˆqoyqcph\pxdqtˆ|xcs€pgjytrlxwvxdƒ{xvpdccn||kkUhaeSJkgOGRkEaxgaMSq\JMTYekw{e_mqid]V`VnnWKShWe^XNUlTJ\y_[_k]][ce`zhkaoounoxuz˜}w€z€€‡…zyzƒ~“„qttyvt„ˆ}€|ks•€{‚Ÿ…~‡}€†‚€Š{v„¬Ÿzˆˆƒkryu€tn†n|s‰€jomddX_ZYZUbjg[Z^u‚i^ml\aV\\leqt}ii\kvugtwrm…{}}yurlyhixf]eshzw’ccTepg‚…wwgij`WVYgc§n~w€‹Žzpq}hzoz|wr„}†ndusdhh\kb]oo[g_mudzh]t€oqkq{}uuat…Šz‡‡€wruuapmZrtbqr…|uer€lal{oji{yvrf…v{zuqdaems~ilTh^\TKrbPFVaGbvgaKToWJLWXgkvzdenqfcZW]YveUJ\cWgXYIWeQHbxZ]_l[^\ad^ij_ntxnonvƒ—yr€|ˆ‹…}uu†y‡Œ}suu‚yzz‚‹Ž}~„‰is–zŠ}~…zz|†ˆsq®Œ{{‡}eq‡ys|{uro…l{~lzbpobe]eVYYVcfk`]\s…hXpnZ^WZ\l{bpwvmbZlssgtupl„y~€ywnnteite[hufvv‘z_]Rffkƒ‚t}bci\TX]bc¥hxt‚…xmozhxn|…{u‰s€x|xhevm`f`^j_]skYe]oobze[w{knnowxstdrƒ’~‡‚ˆzvor}sbwd[oqbqq‚|sgr€e^nvidgy{uno‚ut}sqb_fno}diSgXXTMw_QJYXHbudaITmSJLZWilr{bllscaYY[av[SLc]XiSWHYaNGiuX^am[[_bb]…hganxylojvxm‚~€’‡ƒvt‰tŒ†sqwu‚w|}~Œ€~“~pw•ƒ|™’y€€xy~tˆƒsp™¢{z‰”xduˆxswulto~ly|p‘r^po`gblT[ZWhcmf\\q‰eSrn[ZXX`lvciuji^Ymsqlsssj…|~|vnnldiqc[krdtvŽs[WSear€r‚]bc^SZ`[c‘žerq…„‘tlkzmop{||qwszzzdeuh]bZ`g[^vhWb]phaw`[{viirnwsrthp”‚†~„vrjp}mfwW\knbqszsgo~[`pqa_jq~llu~sqxkpa\ellzagSfTWQOu[QOYRHctb`FUjPIPZUkkk|emoqa[ZXYlpWSOfWWhSTFZ\OHrtX_cmcX``a]‹jcdmyxkoiuy†{kƒ}„™|‚„y}ˆn†qowz}t‚‚|ŠŽ‚‚—tw‚“…Ÿ‰u€€s‚q‡‚uo¢—t{†‹†{ewŠnnznfxpzksvrŒk^tnagekR][UgallZ\pŒdOon]VXUgjtgbtee]Yntmpuuyk‡||ˆvsddkna\nmcsx‡kZTVcdx}}q…\c_cTZ`Yc••cnpƒ…Šsjh{ofsws|lztuoz~u^frc[^VadYateU_`mdaq]]~ohisqsptujm„’ˆ{…qrfn}proS[fkfqtwsclvUbrkZ_of}fmw}sssjm`Zdjjw^fTdTUPTmWQVSPHds_aEXiNHWTVmhd|ikxkbW\U[tdSRWhQYeTSHZZPMxvZ_eliYb`^^naflyunohvvlƒ}†—{‡Š~k“ˆrgt€{u€‚|ˆŽ‹“r|Š‘…‡Ÿ†{†Œs†s}ƒvn¥Œs‹vwmzŒ`d{pfzsxlmqv‚gd{lcfghS_^Ug_lo[^nhNim`TVSogslfxdd\Xptlqzxrmˆ{vœzykaelm^`ojeqx~gZVX`lx|{pƒ_b^gWX_Wd›ˆbkq‡}wkkxm\wql{jvsno{€rXjn_Y]UbcXdqbS^ahbblZ`}kfksunmwvkh…‹~ˆzˆmqep}mrmcYaiiotts_ilSeqdUbnbzcqw{vkpmj_Xaght\eUaURNXeRO\OOHep]cFYiMI_KXmd_xhn~d`T^T]u\TS`fN]aTSJ\YPYuu]_emhXca[^Žqbgjwqsngvtzƒr‚y‡~|‰‡ŽznŠtls‚t‡„†‘„•y~Œ‡‘›„€|Œ„r€stwqn““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~~~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’’’’’’’’’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’’“““’““’’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ‘mfggggg}…„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDBN¥¯­­­­®¤Ÿ    ¥^*///0,H…ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‘g_```_^yƒ‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR455553A©¶´´´´µ¨£¤¤¤¤ªV:ƒ€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}z{z|}{|~}~}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‘ŽŒ‡‡‡‡‡‡‰““’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†…………†‘ˆ‚ƒƒ‚‚‚…ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z{|{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘’’’’’’‘‰‡ŽŠ’“Š‹‹‰‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŽŽŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…Ž‡ˆ…‰‹†ˆŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰†Š†‡‡…‡ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰Œ‰‰ˆŽˆ„†ˆŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}|}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹Œ‹†‡‡…ˆƒŠŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz||||}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒ‰ŠŠŽ‰ŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzzz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{y{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†……………„„„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰ŽŠ‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{}~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““””””“””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••””•“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””’’“““““’’“”““““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘’’““’““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’‘‘‘‘’’“’“’‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡ƒ‹Šˆ‰‰†……„„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxy}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzop{xy{|{xw{xuwttvtuvwuqrqnprpghklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkigfggghhgmgjghehgccbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__`c_\_]`]^Z^]YY^ba^^ZY_\XWSNMLKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{xvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSSPMJMNPROMPQQQQRVVQQQTPPNNOLJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTttuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMOPPRQPNNONONOOPQONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKLFDFJKKKHJLLLOMLLNOOOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEBA@@CCDEACEHKOKIIJHGJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AE@>:;>><ED=?EA?@A@DEGGGGBDDEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@;;><;<<<HL==AA?BC=ADDFBFFDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnpprttsqrvyy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;:;;99:88;=:7:<<>=;;:8:@@AB?A?CFDBCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqususqtxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<:79::989;K;9:9:;;8789;:8<;=@A@=;;><==@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyy{}~~~~}~~€€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>><==>>=:MzR:===<<<<;;:;<>=>??A@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLKIIHIKGMmpquutusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCDA?>=@HG@^zi=>CE??@=;===<;:=>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJKKLKIKJJHVpoqssttuyz{{|~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???CEDH?;@c|{usxl99<9==@=:<;;<;89;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pqrrrtuvz{}}}~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPNL>A<<=?>BC??AAAB@Esb?k…„„„yl;988:;=??<;;<;::;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHJJJLJFFgpoqqtvuw{|}}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC?Mtzm€€ƒ{ƒ~p@==?>=>CD?<<=>?==>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hmoppqtuvy|||||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCE@Nsu€~{ƒƒ|„„hAA@C@@?@@>=<=AEABBFHC=<@DCAA?>=@A>>>?<>@DGE@>@A?@CFECBCC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{{|}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@Irs~}„………†]>CCE@??Na_J@CEIIIIMMKECFGHEGEEEDDCA?@>>BFJJGEEGFFJNNKJIGGHKMJGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@EDfv€„………‡‡‰‚JDEDCWu†‰Š~XGHJLLMOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHIHGFEFFFDFHGEEHHFHGHFQnnpqrvvy{{{z}}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJGYy‚…‡„†‰‰Œa@BUt‡‰‡‡†‡‚WILMLMNLJGGGGDGGGGFHFHECDDFEDDHHCCCGJJKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrswwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLLL`„‡ˆƒƒ‡ˆ‰{Wl„‡†††‡‡‡‡|PKLKHGFFDECC@ACCCCFFEB@>>@AA@BD?>?DFHDEGIKIIGHIGIIJJIHFJJJJIJIJJJFILLJJKKfopsrtvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKLLId‡‡…ƒ…€ƒ„†…„„…††‡‡†ŠuIIFB??@???<<<>::<AA@><998<<=;>;9;?ABAACCC@ABDDBCFHIHHHLMLGIJMMNMJJKKJLMSloqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHHJJJl‡†‚ƒƒƒƒƒ„……†‡ˆˆˆ‰‰ŒŽfBB=88::9878896479;<:8567789787689;;<>@;999==><<=ADEHJMLLGIHORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@CGIIi…€~€‚„„„ƒƒ„†‰Š‹Œ‹Š‰Š‹Œ‰T;8656766645763468:876565676778:77789;7589989876:<@GFIFIFEFOSRSSROPPRTepqsttwy{{{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:=ECEu…€ƒƒƒƒƒƒ…‰ŠŠ‰‰ŠŠŠŠ‹‰‰ŠH676468874578467699766765:9:::<898977779:98878589;A=>>BA?AKLOQPQOOORWkrrttuwy{{{|}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897;B9Gƒ€ƒ„…„„„„†‰ŠŠˆ‡ˆˆˆŠŠŒŠ‰‰Œz>:88;<=>9:;<89;9:;:99;:9===?;;;=:>;9;;<;<<9;<8::;:999<?<=ABDIJMKJLLWorsutvx{{{|{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<;89989:::;?<V†ƒ‚ƒ…†……†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>BCEEAAAB>@B@@?=>>@?>?@?@==?B?AA?A?=@@@??A=><;:;:9;?=;;==AACABCAXqqtttvy{{|}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::<=:;;==?@B`‡ƒƒ…†……„†‰‰ˆˆ†††‡ˆ‰Š‹‹ŠŠŠ‹Š‹^>DGIKJIFGGDFHGEC@@CECB@BCB?@DHECEDEEAFEFEFFD@B?=@>=?@>???>?>>:;=<`qrttuwzzz}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>???=A@DDEdˆƒƒ……†††ˆ‰‰ˆ‡†††‡‰ŠŠ‹ŒŒŒ‹ŠŠˆWHLMMKNJIKHIJJIECDFGFDCEFDBHIKHGGFGGEKIKIJKJCFCCDBAACBDCCDDCA=;=@hpsttwwzx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLK@BBA98<>;<;>@@A?BCHHJ`†‚ƒ……‡‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹‹ŠŒPMPMKNKJLIIIHJFDGHHIEEHFFELLMIJGGHIJOMNLLNKHFGGEECFFFFDEHHFCA?@Llptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?FGG=<@@98<;<=:?@>@@CFJJPhƒƒ…„…†‡‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒ‹ŠqMQOMLLKLJHGEJIDJHGLJHJGGGKLNLLHHIJMPNPNMOKIGIJHIDIHHFFGGIFCBACUnquvwy{xyzz||}~~~~}~}~~~~~€€€€€€€€€€€€€TDAABGHB?8?@9:<8=>;=A>?@EIKMVsƒƒ„„……†‡ˆˆˆˆˆ‡†ˆˆˆˆ‰‰ŒŒ‹ŒŒŒ‹‹‹‹^QQPMNMKJGFCGJGLJGKOLKJJMMLOPNHIKLOQQPQOOJIJJLJLFGHGFGIFEEB@BB\orwxyzyyyzz{{~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<9@>>@BGGAHLMQWy…ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹‹ŒŒŒŒ‹‹|WURRTROLKJEEFKONOWVQPOQSRMSTOMSLPSUWRSQPLKMMMKNGGJFFHJDDEEBDCcpuyyzzz{z{z{|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?==B?BCFVNFOQQUY|†ƒ……„„‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŽ‹‹‹gVVkaERQQPJ;:QSR`u]UVTVYYRXXRZfPUWZ]RTWQPNRPPPQKKKGHIHEFIHIHIjrvyyzyz{{|z{|}|}~}}}}}}~€€€€€€€€€€~~THJIIGGFE??AAEBCGEDELXRMTVVX[|†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ}aŠ‹‹‡l[dU:XXXSP>@VUY\d`VYbr^]V]ZVEQYZ[Y_TYgRUVXUTVTOOMJLJIILMKOMTptvxyxwzzz{z{|}|~~}~}}}~}~€€€€€€€€€€~~~VJJIHGFDDBA?HMIMPKIKPTSSXZZ\\x…„…………†‡‡‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~Œ‰Š‹znpXZ[ZRSRVVTZZuƒYU}a\X]^WIV]][[_YHYXY\]YXYWRQMPQMMOSQQURbtsvwwvxxxz{{|}}}~}~}}}~~€€€€€€€€€€€€xy}YNKIIIFBD@A:PQQWXPPOQSTTXXYZ[n‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡ƒŠ~fYY\XSVTWRQWVc–€QerXZW_hP`fZ[X\hbGOZig\[\]]WSNSPPQVVVVYZostwvvtwxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZ[RSQORRRUSVTW_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PVXTRTRQQLOMKfyZ]TYUV]ZLTZUST^ZXWWWzkXZ\\^SPPPINOWVXZZdqtvvttvxyy{{||}}~}}}~}}~€€€~~zxwvsu{€€tk~~kry^[VUSROKFCDAM^ƒlVRSNOQOQURSRRTcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ymqVIKNNKMKHJDFHEC>ScURQQNKRTRMOYQMNQSUUMQSRPNLLHCIHRTUZ\mrvvussw{z{{{}{}}}~}}}~}~€€}}~~€~{vsw}~~du}iqt_d]^[YUQLILIal’tPQSNQRQR[RSRQRUUbs{|€‚}{{€ƒ‚…†‡‚†††„†…†u_]KC>CCCCB?DPBD@C>BHGV@HNMG]iPHFOFDEFHGHBCHGHJGCBAD@OPMRdsuvustuz|z{{{||}|{~}}}~~€€€||}€€€}vt{mh|gnqfieeb\XSQPURsWe[OONLQSQUYSUQQTROV`klrv{{xytrnstsyx~~ƒ€ƒƒ‚€‚€‚kLG>>:;>@@??>kQKaEFHIEB?GLMGMQUIBE?><=<==?=?ACB?><=B>JMFUnuuustvx{|z}||}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QQZ\Y^IJPQNKLQRQTUUWQQWVPX[b]agmmlokh`nrjmlqu{z}zxz||xwxdB@@A=:BCAADB\]O{NOONKLMOOQLKLWNHG@B<977599=;;;8989?;AG>\tuuvuvwy|||}||}}~~|}}}}~}xuwz{zwyxuw{|yxuywcqhipmnmmhf^OP^\ZIGPRQOMPQNQRTVXSRYTNYZ[WY]^^`e`]^qvk^`gkwooljonnlfbYGFFHBAFIEEFDMRPaWRXQPSSRU[OOQVPMICF>::6486979:366796<B=ftuvwwyy{}}||{|}~~~{}~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZWMLTTSQQUOLRSTWXTTXRLXYZVXXVXY]WWXhsk]V`tkaa_]d`_^YUPMONLIGJKIHFCQPSZWTTMQSYS\eUOSTQNLIHC?A9988978847578588Gnruxxz{{}~}}|{}|~~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPXVVSTVOOUVXXYSUTLKTUUUUWPTUWTUR]n^RNY`[VY;DUWT[fJLPRROMMNNNLJFPPUYSTNJOOTST\VRUSRNMLIHHF??=:787659967665Wqqtwyz{|}~}~|}}|~}}y}}|~~~}||}}~}|rvqxxruuqqnppopuvtnjddjppqrpnfedc\^RTZVWUTWTRXXYYYRUOJGPPOOMRJOPPPNNOTLMIPPSTU2<XMIAQ=c`QSQPNPQPNNMPNTRPRLILKOQPQRSTQROLMKLLHCBA=:9876;B4566;eprvxy{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqpuuvcjgeWhtrrqniihpVVTUXUWURWVUZYXWUQSFEAFGGHFJDHJHGEHLHKIGLMPMG/E_R>3@>joaRRQ@FTQPQPQNQOPOLJLLOPNNPQQNQOJLMMKGEEDB;=<<9=G6677Dnquwz|{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknbePSTRSUOWVVYYVQQQO@>;=?@BAC@BEDA@GHGHFFHJMLDGCORC8ENS]gSQSAGUPOQQPMMNLJLKLNOOQMOOMIMLILKLKGFFED<AA>;@E;<89Tqsux{{{|||{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLONMQSLTUTWWULLKH=987;?A?<=A@B=>EHGDFFIGKJ@FAA@FHEJOHQRa\QPRNSOOPLLOLJMLMON[VKMQOHJHCIJLLKFFFD?BC><BF?B?Adqtwzz{{|{zzw|wy~~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCE=9879?B>;>A@@>ADIECHGIGIEBB?><CBAGIDMOaeQMONWKLNKLMLLLKNNSdMJLRIIIEAHJLMNKGIFBAB@?EFEHDKopwzyy{{z|zwsxtx||yznqrmnorrvrsx|xvvmpmsoutlpprooorvvrVVnqgly„jmqrnnjhoHJCGLMIMPMPOGKE?B=999:?B?<ABBADDGKFDIIGGHCC?B??@A>CECKNQTLJIMTFIIJLJJKIILMOPRPKGCLGCCJJLMOMIJIGCCCDIJMLIZsmxyxz{{y|vrpurtyyvxjqnjllnttmsu{stxronqnvsnporpopstyjN`gsjt|ygosqjqheqHKCFHHGJKIJLDGB=>=:::;AB?=BBCCHFJLJEIIFGGCC;A@B>@@CECIMOGHKFHKDHIKMHJLHHJLKM]RIHDNGBEKKNMPNKMJKFGGJMNQNLcniwvw{x{z}qmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoijthdoFKCFEGDEEFEGCC@><=:;::@D@>BCEEIFJJLFIIGFFCB;BCC>@CCCEGLNHKNHDHEIMNMGILGEFIILNKJHEOICGMMNMPNOOMLIHIORQRNRfgfrosxu{z|lhjoekpmsqfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGICEFEBCBE@DB>?>:;;=;=?CA?ACFGJGJILHGGGFEC@=EEB>ADCCEGHIGMPIFFGKNOKFHJFEDDIIHKIFHPKDJMLPNONOPNJJHMRUTROWdaamgprosyzgehhcilgqlflmgiklslpvutpnvrosrsutqssutsuvvvyvutvlkuumrvqlnlerMGEEGCBABD=BA>A=::=?;>>@B?@BEGJFIGIGFFFEDBAAFFCBBBDEDGGHFLQLIOJJLKIGHEFEDCIHHKJGKRMCOONQPOONOOKKKPUWVUSX`^]iaminhrsbeffdihfnifmmhkkmriqvusqmvnoqrswsrstuvvvvwvwvvtwuksunutsqrkksMFFEHBBADD<AA@C<89=>:?=?B?@@DFHEHFFGFFECCECDIFCFEBEGEEFGEJMKHQMJKHHIEFIHECIIJKMKPSNDQSQQRNOMNPMLNSWVWXVX^[]d`hbjigk_defcgggkggkmkmlpqgttursnvoqprtxqssuvu‚‘yvvtxuuwxnouorsuqqipzMGGGHBBBFE<@CBD<7:=>;>:@B>??CEFDFDDGECECDEFFJEEIGCGHFHFECFJJGMJLKHJLFIHKHEKKLMNORTOISUTQTPQMNQNMQWZVZYVZ^ZXa```_hec`deggjihjfhnllomqpiuuxrrpupppruvpusuvu{~}xvtwvvvwplupmsunorsyMHHGIDACHE<@ECE=8:>><<<AB=?>ABFCEBBHCCDEFFGGIFGKHCHHGIGFDHKIGKHMKJKLHLJMKINLONORUVOKUVTQTQRLOQPOTYZY\ZY\__^`c^\ackb`dghr…hgifjmnponsqjtuxrsstrnpqvrquruus~yŽ}uuvvvvxriuqkrtlqwquKIKHJEBEGE<@GDD@9<>@?>?CB<@>AAFCEECHDFDGFHHFHHIKJEJHHKHFFLHHHJHLLLLLIMKMNMOLPPQUVWOJVVUSSRQLORRQV[[]^[\^`_a`bd]d`ef`ehjcssfjhglprqossnswwpuvtsmoruorspurvrtvuuuwvuwtgtrkqrkrwovIJLILGBEDE<@FDDB;??A@@@DA@B?ACHBEEFGEIEFEIHFIHJLHHJJILJFJKHIJJGKKMMJJMLNONOLOPRUXVMNTVUSRQPMNTSRW[^^_]]``aaa`bdebchbdijgv‹lkigmosqpqpprywruutsmmssmqrotutspsvtuuwvuuteqskpqjrvowJMLKMGDCAD<?EEEC=AACBBCEACDAAEGCHGHGFJFCGJGGJFILHIJMKMLGKIHLKNQKRQLSMKNNOPPPTOWXX[NSQW\ZSVPNTUTTXZ_bb_da_`b_`eaacinhbihhmxvlhimosrpqrrrvtsusssnksqmprotvrrquvuswywutucmtkopjqtpwLMLLLGDA@D>>DEFC@CAEDDFCCEGCBIEBHJIHHKFDKJGHIIIKGJJOKNLILHJMKZfJd\KlRHON_nUls[qpbwcRPbvuhucav`Xnqbdvinzf\lt`ljT_wvijgifglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqsqyKNJKJFB?@B?=DEFDCDBEEDFBFFGCDJDEJLLJLMGGMJHJJHKJIKJNLMMLLILML[sbdp^llUMNfs]geqlntgpi_aYnnbppbkjjgoqtetno\pugpMJryvkb`keemxmkvlnpsrprqpqrqrrrtrmmsnnoprutqsstuuutwxvutbmukpplrrqzKLIIGED?BB?=BFGBFCEDEEDCHHGDEKGGLMMJMLFJNHIKJILJJJKMMNMMMKNMM[roonpplkMPQlWNibtrpamov\YlQ\mmZqmkomxxtsip\`slqjUuyxpc^kfbgppjioppsspqpqqrrqqrrtlmrmmnorutqtrtuutuuzvutenukpolsrryJKGHEEEBBB=??FGBGDIEEDBFIHHEGKJGMMNKMNGLNILKIJMIKJJKOPNNMLNML\hdu]lqWlNOQmUZk^klvaldtTecNmYl\tpkilxjwuhp]_skhWbcw|oc`ggadityknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtwIMGIDEECAB<B@BFDGFKGECCHKHHFJLLFNKLRRLGMMHNJIHNHJJIHNONNLJNMJZsppoqqmlOQRnYqkgooqqomt^nXat_nopoqronusttj[]tcwxrjnzhaacfbbjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyytukoumtonssvtHKHIBEEEA@>CCBGCHIMIFCFJLIGFJMLFOJKWRKGKJJNIHJLIKJIHJLMMLIKKKSkbZi^_jcrrZ_Yjo_eeUk_c[abQ`mh\j\niid[pfdp]Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunwqrutwsHHFIDEDFA@AEDDGBHJLGFDGKLIEFJOLIOIL[QJFHHKMIHJIKKIHJGKKKKGHJJLLLKIKLNT[\TPTMPONOOVQOOQOOQJJNPQdqiTYW[[\UY[]X]\\cfaafbce__fkmhmtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyyxuvqruovrtsuusGCEGFFAEC?CGDEGCIKLHFDGKLHDGIPKLOKLWMIEEHIJHIKHLJHFHHJGGIEFLHIKNLIO\W^O\[`^OXYS\\b^MYZMXaRKYaZS`d]bX[ddVVX\YZX\VY\^c_d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstxyyxyxwxtqxrxsqrurtOBCDLMBCDBDIEGGFKJKHEEJJJGEHHPJLMJMSIHEAHFJIKKILJHFEJHEFGEEJGCJMJKT_Y`X`a[`UXYT^^Z_RY\P^\YN_\^S[^c_Z]`c`Y_b[`^[TXXZ_^dbbaceiekrpoppnow‡†……†‚{€……††…†…uqprrsvyyzyyxxxwryvxrqxvtvaSJJMIECBCFGEGGIJJIIDFKKKEFHINJNLHLNGHF>GGLIKKJKKIGEIEDDEAFJD@JKIO[cY^^a_RTSW_`\]Y^QY\MV_WKQY[Q[_aa]^ca`bbbcceZRYVU\[^c`__cebhommllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxXQJFCGEBEGHFGHIFGJGHFHKILDCKJMMLLHJJHJG?GFNJKKMKKKIGHDD@DAHIA?HIGO]aZ[d]_TQRX]\\\_ZKW\LR\YIM^PP]_accccb\dcbdcfXQUTS\X[a_^_aa_dlkmjjlnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMB@IFCFKIFFGHGGJFFFILJNECKJLNJLIKJHIGBHHQMKKOMKKIHGED?EBHHAAFEDT]Y^X_Y_[]UXXP]]QKJW^X^[]VZ`RQ__bb``bb`cbbddbXOQRR[S\^]^^___dhgljnnp{{|~{€‚ƒ„………………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡ˆ‡…ƒ€|x\SKBAGFDGMRHCRKFHHHEFKJMPEGIIKNLLILKIIGDHKQOMLPLLKKHICEAECHGBAFEBVUE\T]SV_XNTUNZ[MJKU`a[_X_^a]OYb\``_bcb]bbW__TPOPQXR]\\]^_`affelfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDFFGDIRcPDW_IGGHDFMJPPFJIJKNLKKLKJJGEJMQQNOOMNLNHKADACDFDCADEALHCLLPOOLFMFGIJHGLLMOQILOPPSPLQSRUZYWYXXdVOSTPPONPUT\YY[^^aaefchckmqsszy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKM^LGHYMHHJHGNLQQILJKKNNUNOKKLGGKPSSOPONONOHKE`ED_LDfcDM[H^\smOMVmYLCP_UlWgJ]XV^DLQULMTVQRTXWTXUT\TPfZhhdYTkTWVU[\\``abbb`fignlhrz|}~„„„ƒƒƒƒ}}zr{z{‚€ƒ„„……„…ƒƒ~z{LIEFFHEEKOTIKG`THJOJIOMRQKMKLORUROOJLNGHMQ[YOPPNOPPJKPQI|YYrsXPmHqnoaVPqqsPCksmqspSo_[nX]V\XUkhU]VcZ`YZ_VUWjtuu_av_Xb\\f[_aaab^`bgmpl`pwtx‚ƒƒ‚}~€vxzlv~tx~€|~€‚„|€ƒz~wwNIEHMMBDLLGILFRVLKOIKRXWQNOOMQTNOQPKLOGMPS[ZTQROPPPKHZx]TxdhYRTQvgtlpbnfkQrOMwmjrpsrqrpop€]ezuxqqzq~s}ku}bRh|essoss|}o~yor_``baZa`gknkblfgmw~€ƒ~{xw€tvzir~nt|~wx{~€ƒx|u|||ssNKF`]GAEMMHKKHJPOMMJNV^YULQSNYYLSSRNLPIQRTYWWPTPPPQKGfxlcxqmZJLUypumubnvPdeJfvqmwo€jfxxiWrQhzmijzz}lxzpgoXvvjvup€ash}ilx|o___cb[^bdgijdgbcdllppstsssyqrxbltgry{ssuy~suzn|}yxrnNJStNCBEPPIKKJLQOOOMPZ`ZXKTWPa^RVQYSMPISTUXWWPUPONRJLrouuquqdhaVnLqp^FhyWvTKhx}x`y{sna^modRgrunmypwlvstqlm\s~zkmy|lum|kpvux^__b^]_edighee^bbiiijknokqnmjpacfdowxompsynqpj{ztromKK[VHGEGRPJLMKLQQPPPQW\YUNVYUfXRRY^TMNITTVWYWOSNNNQHRmHiwK`dvvUWlOnl{sajgvUKWkh}lmlx`[pz{^`zscroxqhd|ir{]TKl_vukiu{{m~xk|p]^^b[^bdegeeebZccikkrsrwgmihdg`alagsrkhlmr|kmhk{tmmkmOGJKHJHHRQLNPMLSSROSSWRVTPWZVVTTTa`QONKTSSQVVONLMOPJHQNPULKKSTSRTPVUQQNQQXXQNPUTXXX[[USSW[WXWZPSUWWXQ]XV]USOXRWWWXZ`[gr^[\[]^_cZ_ccefdccbYccfffmnmuffgc`f_]g`dlhfgkhpzhggkujhgilQIKKLMKJTRMQQPLVVTPTUXUYURZ]VUTWUYXPOLNWTQNUSNPMLQPKJQQKQMKKORTRQQSSIHMNOQRQQQTVRXW\WSSPRUUVTZQNSRWUTYVTYUSRUSTUXYW^Z_a]\[Z\\`c\]bcdgeddaY`acabihincad^_c]Zd\bma^ffgmsdihkkedcfhPJKKNOLMTQOTQQMXWUTUWWWZVT\`VWVYUXTQPKOXSPNUPMRNKSPMNUTNQNMNQSPTQSTUNKMOQTTRRQVWUYZ[YSURTWWWY[SOSUWUTYUWYTRRWUUW\YZ`]VY_]^]\]`a^[bbchfedbX``b]`hefda^_]]^ZZ_Z_g`^]]chkagfhfd`bcaPKMLPQLOTPPSQOQZYXWXZZXXV]jdVXYZWVTTPKOVTPOTPPQNMQQORXTRQOMOSUNWRTUUONNQSUUTTRTXVZ]\ZVVQRWXV[[VPSVUUVXTWWTRRXVUZ_Z^`^V^]^`]\``__ZbbdhhedbYb`b^^fdc`b]\\\\YZ[X[a[^]]_b__bddbd__`\PMNNRQMRSPSTQOU\ZZW[[\YZ[dqmhd_[YVVXRMMVSMNROQROLPSRUZUTPPLPWVQWRSSXMOPRTXUUUSUYX[^]\[VROUWV[[WPSWUVXUSXZTSQYWV\^[__`Ua\`a^`b_\`]cachief`Zc`a__ee_`c[Z\[\ZZYYW\Y\[`^_[^^a`_b\Y`ZQNONVQPUSPUTSPW\\\X^\_W\^jqwy€c\[VVXRNOWSNQQPRTRLQTSYZWUORNSXVTRTRRZOQSSV[VVWTVZX]^\\^VSNTVV\\VQTVVXYRSY\TRR\XZ]^]aa`Wb[cb^ac_\bab_dgidh^\d`a`ace_b_YZ^[\[YXYWWZ[Za\][]\\Z]`W[[ZPOOOYPUUSRWRTPZ]^][`\`U\]ijr}slh\UYWQOR[SRQTRTUTKRVU[YZSOSRVVUSNVRSZRTUTX\WXXSX\X^]Y[^TUNVWW^[XQTUXXXTVX[TSV]Y]]a^cc^Y`[eb_dd^^cca]efieg^]da`abcd_b^XZ_[\[XXXXW[Z\`][[\[XZ[^V^Y]POORZPZUUWVTTT^^`^^b\`U]^bkytl}lZUZUQQS\TTTUTVYWLRZV][\ROUSXVVSPWRSWSWUV[]X[YUZ^W_^Y\ZRWRYXY_ZZSTVZYZVWY\VTZ]\^`a`ed]^]]eabfd^_dc`\gdheeb_da_a`bb_`^WX^Z\\ZYZWV]Z]^[Z[\[WY\]VXW]SOPWYP]UVYWWUX_`aa`c]`U]^beeuzhXYZTVSV\XWWVVW]XPU\Y^]]TSXRXVSRTXRSVTXXX]^X][U^_X__X\VRYUYZZaX\UWWZZZXYZZXV]^_^cbbee]b\`fbefd_`dbb[fchecfaf__aaaa`_^VU]Z[\[Y\YY][[[XXY[YZZ]_]TY]UNTZVT\TVWYWV\`abcad__V[`da_zuohZ\ZVXUW[ZY[YXY`WPU^[`a\TUXPUVUSVVRSUWZZ\_^Z_\V__Z]^Y^VSYXYZ]bY^VWZ[[[Z[Y[YY^_``dcdeebdZafcgfe^ac`c^cciddg_g^bbcaa`^_XTZZZ[[X[XX\[Z[WWZXW\[\`]V]]SPVZWVZUYUXWX^`badada^YYadb`lfh^\][WXXY\\\_[Y[bVTW^]ac\SVYPVVVVVVSVTX]\_``]a]W`^[^\[^XVXX[[_`[^XX]\]]^\Z\X[_a^`dcdfffbYceehgd^ca`ec]fideh_f^cbcaa`__[XY[YZZXYXW[[Z[WXZTY]\Z`\U^bMRWYVWZY[\YWY^`badada]^Yacb_a`a_\\]XW[[]]__\Z]cXYX]`dd_RXYPXVXXXWVWV]^^`aa_b^Ya]]^Y]^YXVW[\`_]_YY^]^^a][ZY\_b_bddefggbZeggigc_c^afdZhicfice^bbca``_]]ZW[YYXXZYWZ[ZYWXVU[]]]``bbxKWW\XW]\\]ZW\]_`bdbba]`Xbcb`cac^\]\XW[]_]`_][`d\\XZbecaR\YOXWY[ZYWZY`^abb`ac_\b]_][_^YYUX]]_`__[Z^^`bc\[W[]`bbcedgfegd\fhhifcab\cg`\iibhife`baca_`_]]\Y\YXWXYYW\[ZWWXPXZ]acffrkJYW]ZZ_]\^\X]\^_acbaa]b[bda_cbb]\[ZWXjq`\`_]\ac_^YYcedaT_ZQYW\]\[Z[[dacbc`bda`c^`\^__ZXV[_]\aa_][`abeb_]S\_`cddfegfefe_fgihgdd`[fg^ahhbhhfc`b`cb___]][Z[YXXXVZV\ZZVVULXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡…‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vuuuuuuuvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{{{{{zzz{||||||{{{{{{{||||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vutuuuutuvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{{{{{{{zz{}}}}|||{{{{{||||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||xÅÔÒÒÒÒԓ{}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰ˆ±µ´´´´¸Q&+++*%b’ŒŒŽ‰~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}xÕçääääç™{~†“y1333332j‚€€€{­éääääèʉŒŒŒŒ‹‘»À¿ÀÀ¿ÄI]–‹}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„ƒ‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}v~ywwwwwwxyyyzz{xnoooppprrrrrrrwzyyzzz~ƒƒƒƒƒ„||||||}€€wrssssry}}}~~}}|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚‚‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vtttttwtvwz{x{xwvx{x{zy}yxxyxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{zzzzzyz|}}}}}}|{{{{{||||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwwy|{}z{}{wwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwww||||}~|wxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z|ywwwz|z{}~|xxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚ƒ‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzzz}||||~{xxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyy{xzzy|xxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyxyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{|||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}|||||||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}|}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrstuttssrrsrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqstsssrqqppnnnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqqrssssqpqpoonnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrqrrssrrqppoopoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpppqrrqqqpopooppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqpqqqqqqpooppppppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqqqqqpppppppppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsquŒ‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqqqpqqqqpqpqpqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrqqqqqrqqqrrqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrssrrrrrstrrsrsssssssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz|~~|vvwwvuxzxxxxwwwvx|yy|zyy|{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~|{{z{|{}|{{{{{{zyxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}|||~|}~~~~~}}||}ƒ€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€€€€‚€€~~~~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~~€€€~~~~}~~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~~~~€~~~~~~~~~€€€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹Š‹‹Š‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚ƒ‚€€€€€€€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒŽ‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒ„‚„„‚ƒ‚‡ƒ‚‚€‚‚‚‚ƒ‚‚ƒ‚ƒ‚ƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒƒƒ€‚ƒ‚……†…††‡††††‡‡‡†††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠˆ‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„ƒƒ‚ƒ„„‚‚„…ˆ‡‡‡††ˆ‡‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ’‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚ƒ„„ƒƒƒƒ„…„„……„ƒƒ„……‚„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘’’ŽŽ‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚‚ˆ‚‚‚‚‚‚ƒ€€€€€€€€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„…„„…„…†’“‘ŽŽŽŽ‰ˆ‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~€‚ƒ‚€„™‘‚€€€€~€‚€‚ƒƒ€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“’Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€‚ƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚‚ƒ„‚~}}ˆ›•…„‚„‚€‚‚‚‚„ƒ‚ƒ‚‚‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘ŽŒ‡…ƒƒƒ‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒ„…ƒƒ‚‰ˆ…~||}~š˜„„…„„„‚€‚ƒ‚‚„„ƒ‚‚„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ……„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”“’’ŒŠ…„„ƒƒ‚‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€€ƒ—‘†}~‚‰~’˜‚‚‚‚‚€‚‚‚‚‚‚ƒƒ‚‚‚ƒ…ƒƒƒƒƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†””“”’‹‡„„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€ƒ›ž…„Š€„‚‰‚ƒ‚„ƒ‚‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“‘Š†ƒƒƒ„‚‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€˜¢‡…„‰†~~~ƒƒ„‚ƒƒƒ‚€€€‚‚‚ƒ‚‚ƒƒƒƒ‚ƒƒ„‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†„…ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„„€€}}}}………„…‚}}}‚„ƒƒƒƒƒ„ƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„……………„…†…††…………………………††…†††…†††‡†…………ƒ„„„‡““’‘’ŒŠˆ…………‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…ƒ†Ž‚€…Œ}}}ƒ‡†ƒ€~~~ƒ„ƒƒ„„„„„„„„„„„„………„…„†……†…†††…†……‡……†…††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„ƒƒ€††ƒ€†~€„…„…†††…………††‡††…†……†‡‡‡ˆ‡‡‡†††‡‡‡†††††††…„ƒ„………„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘“’‘‹ˆˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒ„„„ƒ€ƒ†ƒ‚ƒ‚€€€€€……†‡ˆˆ‡‡‡‡ˆ‡ˆ‡ˆˆˆ††‡ˆˆ‰‰‰ˆ‡†‡‡‡‰ˆ†‡†‡‡††…„ƒ„…†…………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†…†„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡†…ƒƒ…„„„‚€…„ƒ‚‚‚€€~{z€†ˆˆŠŠ‰‰ˆˆ‰‰‰‰Š‹Šˆˆˆ‰Š‹‹ŠŠˆˆ‡ˆˆˆ‡‡ˆˆ‡ˆ†‡†„ƒƒ…‡‡‡†……„„ƒ……„……†„„„………†…†…ƒ‰”“‘ŽŠ†…†…ƒ‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡†„„…„ƒƒƒ‚ƒ„ƒƒ‚‚‚‚‚‚‚€~|}}}~|{|ƒ‡‰‹‹ŠŠŠˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰‡†††‡…†ˆˆ‰ˆ‡†‡„ƒ‚„ˆˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚‚ƒ‚„ƒ„ƒŽ“’‹ˆ…„†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„…„‚‚„ƒƒƒƒ‚‚‚ƒ~}}~~~~~}}~}}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡‡‰†ˆ†ˆ‡†‰ˆƒƒ„ƒ…„„……†ˆ‡†…ƒ‚‚ƒ…‡†‡††ƒ‚‚ƒ„‚ƒƒ„‚‚ƒƒ„ƒ„‘’‘ŽŽ‹‡„††„‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…‡ˆ‹Š†„†„‚†…€‚„ƒƒƒƒƒ‚‚}|}€~~~}|}}|z|„†‡†„ƒƒƒ„………ƒƒ…„„„„„„…„‚‚ƒ„„‚ƒƒ…†…„‚‚‚ƒƒ…ƒ„„…„„†ƒ„„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰†„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€€€‚ƒƒƒƒƒ‚‚}}€€}~~}}}}zzz~ƒ„„‚€‚‚~‚ƒ€‚‚‚‚ƒ„€€€ƒ‚€€€€€‚‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†‹“‘Ž‹ˆ……ƒ‚„‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€€ƒ‚~~~~}€‚ƒƒ‚ƒƒƒ‚}}~~€€€~}}}}~}|zzz‚‚€~€~}€€€€€€€~}}€~€€€€€€€‚€€‚‚€‚„ƒ†’ŽŠ‡‡†ƒƒ‚‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒ‚ƒ„…€€|}}~}~~€}~}~€‚ƒƒ‚‚}}~€€€~}}}|{{{zzyz€€~~~~|~~€~€€~}~~}|~€~~€€€~€€~€€…’’Ž‹‹‡‰…„ƒ‚‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~~}~€€~€„ƒ‚€~}~~€€€~}}}}{{|zzyyy{~~~}~~€€~€€‚€|~~~~}|€~€~~€€~€~~~~~}||}…“’ŽŒ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒƒ‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚‚‚€ƒƒƒ€€}}}~~~~}}}}}|||{zyyyy}€€€€€€‚‚€~€~~~~~€€€€€~€€~~€}~}}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…ƒƒƒƒ…„„„„„ƒƒƒ„‚‚‚‚‚~~}}}~~€}}}}}}}}}{zzyyyy€‚‚‚„ƒ€‚‚€ƒ‚ƒƒ‚€€€ƒ„‚€€€€€‚‚€€€€€€~~}|Š“Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…ƒ„…„…†…†††…†…ƒƒƒ‚‚€}}}}}}~~}}}}}}}}}|{yyyyx|‚ƒ„…‚„ƒ‚‚ƒ…†‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚‚„ƒ‚ƒ‚‚‚‚€€€~Ž“Œ‡ˆ†ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€€~}}}~~~€ƒ„‡ˆ„†††…††‡‡†‡‡ˆ‡‡‡†}€‚~}}}}}}}}}}}}||~~~|{yxwxyy€ƒƒƒ„ƒ„„„——ƒƒ„}~‚‚‚‚ƒ†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ…„„…ƒ‚ƒƒ‚ƒƒ‚‚‚‚ƒƒ‚‚’‹ˆ‰‡‰‡††„†…„„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€~}~~€‚………‡†‡‡†‡‡ˆ†‡‡‡‡†‡…~}}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yxy|~‰–„ƒƒ„„”“€~~…‹€€€„†‰…„‚‚……‹ƒ‚……††„ƒ……ƒ…„ƒƒ„ƒ„„„ˆ’ŽŒ‰ˆˆ‰‡‡‡…†…„…„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„ƒ…„~}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|xyz{|€‚ƒ€ƒ‚€~|~~{ˆ‘||Ž–}‚†Š…ƒƒ„ƒƒ‰~ƒ„……ƒ…†…„……ƒ„……†„„Ž‘ŒŠŠŒ‰ˆ‰‡…†…ƒƒ‚‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚€‚€~}}||}}|||}||}|}}}|||{‹‘—Œz{|zzz{|yy}}~€€|{{~~}‚•‘„ˆ~|~‚„||‚„‚€‡ƒ}‚‚‚€ƒƒ„„„„„‚„ƒ„…‚„‘‘Ž‹ŒŒŽŠ‰‰………ƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚ƒ…ƒƒ…………ƒƒƒ„‚‚ƒ‚ƒ‚‚€€~~}~}||||||||||||||}|||~~Š‚{z{zxz{{|}{~}~}}}}||}†~}‚~~~€‚||‚€‚€~|{Š‚}€~€€‚‚€€‹“Œ‹Žˆ‡‡……„„ƒ‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ…„†‡„„€†”ˆ€‚€~~~€|||||||||||||}|||||||y{{{xxy{zz|€~|~~}€‚‚€€€‚‘€€~€~~~€}}}{}}}|}||}€€€~€~~‚“‘ŒŒŽŠ…††…„„…ƒƒ‚‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚ƒ†‡††~ˆ•Š~€€~€~~~|{{|||||||||~}|{}|||{|||zzy{|z}…ƒ‚~~€~…‚~€~~€…†‚€~~ƒ†~|~€€€~}}}}~{|}€}~€Œ‘‹Ž‡„††…„„„ƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}~€‚ƒ††……~€€€~~}€€€€}}||}~}|}}}}}}|~|}|{}||z{z|}}†„‚€€}~}~~‹„†~}||~‚}}}}|{}|~„ƒ€~~~~}}}~€~~~„’ŒŒ‹Ž‹Š†„…„„„ƒƒƒ‚‚‚ƒ‚ƒ‚€}|||}~{{}w~vx~}|}|}~~‚ƒ€z}}|~€~€~~€€€€~~~~~~}~~}|~}~}}|{|||z{z}~€ƒƒ‚~|}|}||ƒ~Œ~|{{}~}~~}{{{}|z{{{€†„‚„ƒ‚€~‚‚‚‚‚€ŠŒŒ‹‹Šˆ„„„ƒ„ƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€~€€€}€~~~~|‚~~}}}{{}}|z||~€‚€€€||}|||||}|~{~{{{|||}|{{{{||zz}z~‚~ƒ„‚ƒ…†……††‡†„‘ŽŒ‹Š‹‡ˆ…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~€€‚€~~€€~}ƒ||}}|}}}}{|~~~~~~~||||||{~~{|{||||}|}|~|}||{{|y{|{{}{}~~€€ƒ‡‰‰‰Šˆ‹‰…ˆ‘Ž‹ˆ‰‡……ƒ‚‚ƒ„„ƒ‚‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€€~~~}€€€€ƒ‚€€€€€€€€~|z|}}~}}~~Œ†}}~{{ƒ‚}~~}}|}}}}}~|}{}|}}~|~}}}}|{{z|{||{z{{zzz{~~ƒ…ˆ‡ˆŠ‹‹‹‰ŒŽ‰ˆ†…„‚‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„„€€€€‚~}~€~{~‘Œ|}Š€Œ~~}}}~}}~}|||~}|}|}}}~}}~~|{{{||}|{z{|yzyxy{~„ƒ„‡‰Šˆ‰‹ˆˆ…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€~{zy{}}x|zr}{{|||~~}}€€€‚…ƒ„‚‚‚‚€€ƒ‚€}~€~|ˆ‚~ƒ„„ƒ~}|‡}}~}||~|}}|}}~~}~}}}{|}~||{|}zzyyyy{{~~€ƒ‡„ˆŒŠŠ†…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{|}}}}zx‚€‚‚€€€€€‚‚‚‚……„‚ƒ€‚„~€}~~}~€€}~„€~~}~}}Š…}~}~~€}}}|~~~}€}~}|}||{|}{{{zzz{{|}~~€ƒ€‰Š‹‡………„ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv~€ƒ‚‚‚‚‚ƒƒƒ‚…†„‚€€€€ƒ€ƒ~~€€}~€~}~~€€~€~|€~€~|}}|~~~~€}‚€|}€€}{}}}||{||{{{|{|||}|‰Šˆˆ…………„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€ƒ€€€€ƒ~~€€}€}}~~€€‚€€€}€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{|~|}|||{|{|}‰…†……‡…„…„‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz~}yxut€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚~~~€}~€}}}~€€‚€€€‚~~€€€€€~}}}}|~~}}„€~}}}~}~~}~|{|z|{z€†‚„„…„„ƒ…ƒ‚‚‚€€‚‚ƒ‚‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xyuu}‚ƒ‚ƒƒƒƒ…„…ƒƒƒ„„ƒƒ„‚€€€~}}~~~~€}}|}}~€€€€‚€€€‚€€~€~€€€~~~~~~~~……€€ƒ~€~~€~}{z{z|{z‚„ƒ‚‚‚‚‚ƒ€€‚€€‚ƒ‚ƒ„ƒ„‚„‚‚‚‚~€~}~~~~}~}}z{|…„{{syz|pwuvwyutz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€€}}}~}~~}~|}}~€€€€€ƒ‚€~€€€€€€€€‚‚‚ƒ€ƒ‚€€|{{z|{|€‚€‚‚~€~‚‚ƒƒƒ‚„‚„‚€‚€~€€}~~}}}~}}{{z€x|vyy{qtxwvxury……‚„„‚„……†„„‚„ƒƒ€€~€€|}}~€~~~}|~~~~€€ƒƒƒ€‚€€€€€€€€€‚ƒ€„€}ƒ„€€‚}z{{|||}€|}}€€~}}€~‚‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxyzruyyvwwsu†…ƒ……„„…„„„‚ƒ‚ƒ€~€~€}}}~~€~~}|€|~€~€‚ƒ€€‚ƒ„‚€€‚€€€‚ƒ‚€ƒ€~‚‚„€€‚‚‚„‚~{{||||}}~}z~}}x~|||~~~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„„„…ƒƒ‚ƒƒ€}~}}}€~~~}}€€~|~~~‚‚ƒ‡…~~€€€€€€‚‚€€~€‚~‚‚ƒ‚ƒƒ…‚}}}|{||yz{z~y{yx~{{{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst†„„…ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€|€€~€}~}~€€€~|~€€€~}~~€}€€ƒƒƒ~}~~~€€€€‚€€~~€‚‚€„‚„„†„€~}||||zyvyyzyvyv~|{{{~}{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…„ƒƒƒƒƒ‚‚ƒ‚ƒ‚~€}}}}€€€|€€€€|€}~~}~~€‚‚~~}~~~~€}€€€~~~~~€‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{z{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvpxyrx…………ƒ„ƒ‚‚„‚‚€‚€~~~~€~}~|~€€€€{€~€€€}€~~}}}~€€~~~~}}~~~|€~~~‚~~€€ƒ‚ƒƒ†„€~|}||{|xx{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}|{|z{}zzx{|zz{xtxuqrtpxxry„………ƒ„ƒ‚ƒƒ‚‚‚€€€€}~~€}|~}€€€€|€€~€~~~}}|€€€€€~~~~}|~~|}€~}~€‚~€€~„‚‚ƒ……‚‚~~|{{||yw|ywxwwx{{z{|…Š}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzz{zxswuqqrpxwq{…†„…ƒ…‚ƒƒ‚€€€€~~}|~}€€‚€€}~€~€€}~|}€€€€~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{|||zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚‚€€}}~€‚}~~~€€€‚€€€~}~|€€€€€~}~~€€‚€€€€€„‚‚€~|}~~z}…~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚€€€€€€~}€€‚‚€~€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€€‚€€~}~{“z|}|{}y{zzxyxy{||}|||||||}}}||}|~}~~~}|z||{|}{yzzzyysuuooqpwst}…†ƒƒ‚ƒ‚€€‚ƒ‚€‚‚€€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€€‚‚€€€}~~|†‰||~{{~yz{z{Ž~wwy{|{}||||{}|}}}}|}|~~~~|z|}{}}{yz{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€€‚‚‚€€€€€€}~€}€ƒ‚{~~{|}{z|{{‡yxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ‚„„€~‚€€€€‚~€€‚€€€€€€€€€~}€€€€€€€€€€€€€€€€€~}~}~~{}|}{||wxuxxy{||}|||||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒƒƒƒ‚‚ƒ€‚„ƒƒ„ƒ€‚ƒ€€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€€‚€~€€€€€€€€€€€€€€€€€€€€€€‚ƒ‚‚€‚‚€€€‡~~|z}|{}xwvyyz|}||}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚ƒ„„€€ƒ†ƒ„ƒ‚„€„ƒ‚‚€€‚‚„‚‚„‚€€ƒ‚€€€€ƒ~€ƒ‚~‚€€€~€€€€€€‚‚€‚‚ƒ‚‚ƒƒƒ‚€€€„}}}|}z}zyvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysruowqwysw{…‚‚ƒ‚ƒ„‚ƒ„ƒ€€‚ƒ†ƒƒƒ‚‚„„ƒ‚€€‚„‚‚‚~€€‚‚‚‚€€€€‚„€~ƒ€ƒ‚€~€‚ƒ‚€ƒ‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ€‚€}€|z|{{w|yyy{z}~}||||}~~€€€€„„€}€~{{{z{ztpxrytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚‚…†„‚ƒƒƒ„„„€ƒ€ƒ‚‚‚‚‚€‚€€€‚‚‚‚‚€ƒ‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚‚„ƒƒ„‚„‚ƒ‚‚‚‚ƒƒ„ƒ„„„„„…ƒ„‚ƒ‚‚ƒ€€~||€||x|yzyz|}|{||}}}||€€€€€‚~€€€€{{|zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚ƒ†……ƒƒ‚ƒ„„…‚‚‚ƒƒ‚‚‚€€~€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€ƒ€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒƒƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{~~}y|zzz}}|~z||}}|z{~~~€€€€€€€€}}||}|vrvxxvtvu}‡‡ƒ‚„…ƒƒ„…„€‚……„„ƒ‚ƒ„„€„…ƒ‚‚‚ƒƒƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚‚‚ƒ„‚‚€€‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒ„ƒ„ƒ€‚ƒ‚„ƒ‚‚~ƒ‚‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz{}€}||z|~}|}}~~€€€€~~€€€€~|}}~~}|{xvvw„‡ƒ‚ƒ…ƒƒ„†„‚…†…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„‚‚‚‚ƒƒ‚ƒ‚ƒ‚‚„„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒƒ„„„„„…„ƒƒ„…„…„ƒ‚€}‚€}||{||€}}~€~~}~|}}}}~~~€}}~€~~}}}~}}~~€|}€‚‚ƒƒ†ƒ„ƒ†„‚ˆ‡…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒƒ‚‚„ƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒ‚‚ƒƒƒ„ƒƒƒ„ƒ„„„…„„„…………„ƒƒƒ}„€}}||||~~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒ„…ƒ„ƒ…~‚Š‹…„„ƒ‚ƒ…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ†‚ƒ‚ƒ‚„ƒ‚ƒƒ…ƒƒ……„……‡‡†‡…„„…„€ƒ~~|~~}€~||~|z|}}}}}~~~€}}|€€~~~~~€‚€……„ƒ„„‚„ƒ†€‚……Š‰„„ƒ„……ƒ‡††„„…„…„„„„ƒ„ƒ‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ…}uyƒ€~„„‚ƒƒ‚ƒ„ƒƒ„…ƒ„…†„…†}„y|~ƒ{…‚„ƒ€}}~}~ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚‚ƒƒ‚‚†„„ƒ…„ƒ„…ƒ„…„Šˆ………ƒ……„†††ƒ„…………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†tpurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚……‚hzrss|€s‚ƒƒƒ}}~~}~‚ƒ‚|}€}}||||}|||~}~€}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ…ƒ†ˆ††…ƒ††‡‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vyy…r„ƒpvxqvtturstvi€nrotvnulwm{sn€‡ym}rsvsvmmxlpylu}}~€}€}€€}}||}}|}~}€€€~|~€‚€€€€€€€‚ƒ‚ƒ„…ˆ††€‚…ƒƒ„‡†ƒ………†‡‡„ƒ†‡ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoomw}x†pqzprtfu~n{ysoy€}}€|}|€~€€~~€€€~~~€~}€}€€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„†……††ˆ„„†‡ˆˆ†‡„††‹Š…„†‡‡…„………„‚†††…†……†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„qjoyxpkyszozwvvp€~~~z~}}}~}€ƒƒ€‚ƒ„‚€€}~~}€~~‚€€‚„‡†ƒƒ†„……†‡†…………††ˆ……†…‡‡…†„††‰ˆ…„‰Šˆ†„††……ƒ…†…†††††…ƒx‹yrˆz{pp…„x…xyks~y{krƒ‡ƒz|m{yyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozls|nw‚€~~}}{}{|}}~}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡…………†‡‡ˆ†„†…‡††…„……„……†‰Š‡†„†…††…††„†††††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„…†…†„†„ƒ„„†„„ƒƒ„„…„…„…„†ƒ†‡…†„„…‡†„„…†„…}w…ƒ„„‚}~{|{~{||}~}|~}€€}€~~~€~~~~}}}~|{|~||‰†…„†††…‡†…………††‡ˆ†„†…††……ƒ„…†…„††††…„†„…††††„‡†‡‡†…‡ˆˆˆˆ†„‡…††ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…ƒ‚……†……ƒ…„„„…„……„……ƒ††††…„†‡†„„…†‚„„‚„ƒƒ…ƒƒ‚}€{{|~{||}~||~}€}~€~~€}}|€}~~~~||}~{|||{{~ˆ‡„„ˆ†††‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡……†……†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ……ˆ…†‡†‡†‡†‡…‡‡†‡……†‡…‡†…‚ƒ…††„„ƒ„„ƒ„†„……………ƒ††…†……††…„ƒ……‚„‡…ƒ‚‚…ƒ„~€€|{}~{|{}~}||~}~~|~}}~~|}||~~|}€}||}|||~z{{|~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†„…„††„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…‡‡…‡†‡†‡…ˆˆ‡‡…††‡…††…„„…†……„„„ƒ„……†††…†„†…†‡……††…„ƒ„ƒ‚ƒ‡ƒ„‚„„ƒ€€€{{~~|||}}|||}}|}|~}|}}||||}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††„…†…†…†…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡…‡††‡‡‡…‡†ˆˆ‡‡…‡‡‡…†‡„‚„ƒ„†…‡…„„„„„…†††††…‡††ˆ…†…‡…„ƒ„ƒƒƒ‡ƒ€‚ƒƒ‚‚‚€{}~}{||~}|}}|}{||||||}{{{}|{~|{|}}|}}~}|zz{{||ˆ‡‚††††‡††…„…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡‰ˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡†ˆ‡††‡‡…‡†ˆˆ‡†…‡†ˆ††‡ƒƒ„„ƒ††‡……„„„…†††††…†‡‡‡ˆ††„†…ƒ„ƒƒƒƒ†ƒ~‚‚ƒ€ƒ‚|~~||}}|}}|}z{{z{|||{{{~{{}{{{~||||}~}{z|z|}‰‡ƒ†…†…††…„„……………„ƒ…†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…ˆŠ‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……‡ƒ„†…„††‡†…„ƒ……†††††…††‡‡‡‡…ƒ†…‚‚‚€ƒ…‚ƒ~ƒ~~}||}}{}}|~zyzy{|}{{{{~||||z{}||||~}|{{{{|{‰‡„†„†„††…„…†…„„ƒ„‚€ƒ…‚‚z„Œ{€„…‡†††…„‡ˆ‡†‡……‡‰‡„‡…††ˆ†…‡„†‡ˆ††ˆˆ‡‡†‡ˆ†„†††‡……‡ƒ„…„†††‡…„„ƒ……††‡††…††‡†††„ƒ„…‚‚€ƒƒƒ‚}€~ƒ~€||}}~}{~}|}yyzy{}}zz{{}|}||z{}||}|~~€|{{|~}|ˆ‡…†…†„†„……………ƒƒƒ€‚…‚€}|{„…††„…„ƒ‡‡†††…„†‰†‚†„†††……‡…‡ˆ‰†…ˆ‡ˆ‡††‡…„†……‡…„‡ƒ„…„ˆ††‡……„‚……†…‡†‡„†††……†ƒƒƒ…€€€€ƒƒ€|€~~‚€}€||}~}~{~}||yzzyz}}yz{{|{|{{z{}}|}|~~|{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€€ƒ~~~€yz}€ƒƒ„‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ……ˆ‡‰‡†…†…ƒ†„…‡ƒ„†„„…„‡†…†…†„‚……†††††„…††……†‚‚ƒƒ~€€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|z{{{|}}}|€~}||}~|{‡……††††„…„…ƒ…‚€€€€~€‚‚}~{‚ƒƒ…†…„ƒ‚†ƒƒ„‚€…‡…‚ƒ„…„„††‡ˆ‡……ˆ†‰‡…„„„‚…ƒ„†‚ƒ…„…†„‡†………†ƒ„…„…†…†„ƒ„……ƒ……€ƒƒ~€€ƒ{€}}‚}€~~~~~}}{|{zyzzyz{|yzz{{{|z{{{{}~}}€}}||}€}|†ƒ†††††ƒ„ƒ…‚…€€€~€|~~€€‚‚„…ƒ‚‚„€ƒ‚€„……‚€‚ƒƒ„……‡†…„†‡…‡……‚ƒ‚‚ƒ‚‚…ƒ…„…†„††‡††…‚„„ƒ„†……ƒ„ƒƒ„ƒ…„€‚‚}~~~„~{||€}€}}ƒ|~~}}~{~{{zyzzyzz{yzzz{{|z{|{{~~}|}||}€~€†„……„‡„ƒƒ‚†‚ƒ€€~~€}‚|}~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡†…„ƒƒƒƒ„……„ƒ‚ƒ‚„ƒƒ€€~}}~~|~ƒ~|~||€~‚}‚|}}|||{{zzzzy{zzzyyzz{|y{}{|~€}~}}}€€€†„„…„…‚„‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„…ƒ‚ƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚€…ƒ~€~|}~}|~ƒ}{~|}€ƒ}}€~}|||}{{zzzyy{yzzyzz{{{z{}||‚€~€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌËËËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFK=8765999<>9?<D:;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÔÓÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937677=;>9=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<9<<98:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA><A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÔÔÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9?CE@<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËÊÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø×××××ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÙ×××××××Ø×Ö××Ö×ÚÚÚÚÚÚÚÚÚÚÚÛÜÜ×ÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILO@99:4;A<7=9AC>@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÏÐÏÏÏÏÏÏÏÏÏÏÏÏÖÞÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¹´ŒŒŒŒŒŒŒŒŒŒŒŒŠ º¸¸¸¸¸¸¸¸¸¸¸¹°ŠŠŠŠŠŠŠŠŠŠŠŠ‹‡½æáââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVN<::77>C?8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÌÐÒÒÒÒÒÒÒÒÒÒÒÒÑÞìëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§£££££££££££¤œZUVVVVVVVVVVVRy§£££££££££££¥•SRSSSSSSSSSSSKªòëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;?C>6:7>>;=B?9<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÌÌÑÒÒÒÒÒÒÒÒÒÒÒÒÑÝêééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤¥ž_YZZZZZZZZZZZW|¨¤¤¤¤¤¤¤¤¤¤¤¦—WWWWWWWWWWWWWO«ñêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;?@@8:;8<;;<?:;;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÍÐÒÒÒÒÒÒÒÒÑÑÑÑÐÜèççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©ª£hdeeeeeeeedddaƒ¬©©©©©©©©©©©«œbabbbbbbbbbbb[¯ïééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB>;=:9;:==;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÎÎÎÎÎÎÎÎÍÍÍÍÍÍÎÏÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÏÎÏÎÎÏÎÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÑÍÌÌÌÌÌÌÌÌÌÌÌÌËÎÒÒÒÒÒÒÒÒÒÒÒÒÒÐÍÍÍÍÍÍÍÍÍÍÍÍÍÍÔØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<8@B<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÐÔÒÏÏÎÐÓÐÎÒÔÕÔÐÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××Ö×××××ÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÖÖ××ÖØØØØØÙÙÙÙÙÙÙÙÙØ×ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?79:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÏʖ¥ÑÏÒ¹¾Ôœ‚„ŠÆÏÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<>B>BC@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÏϜª¬ÕÀ”°œ±–¸¹¯¡ÒÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?>;7:>9?D?A98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÐ˔ˆšœÎ£ ‹‘Ó}~¯°ÒÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<<:6?B@B:647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÏѽș™»š‡ºÔÒ͞žÃÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8FA?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÏÏҗ” ¾™Ÿ ÒÓÀ  ÐÏÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<>=964:99::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÏÓ³›Ä›¾©¯‘¡¹×¯¢©ÔÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:=?>=<9@<<::9?@>=<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÐÑ΍¡¬ š­›©Ø£¡ºÔÑÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CFCAB8;?<=;<<8558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÐÑËÚ¨› š¦Å˜¢ÑžŸÉÒÑÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF@HIGE@<<>><=><756:979;::;8@?:<<9<>=;;:?9?:;9=>==;;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦ÕɎ¥šŸ¯žœ››­ÇŸ¡ÒÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;547<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡Ê»¡¦§œÏ¦«¤žÅ´¤¦ÖÒÒÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKL@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÓӞ¶Ö˒§×¹ƒ¿ÕÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<=?GFHKH=657:979:;:<=9>99:8;=>>A>=9<<:=>>:=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÒºÄÕÑÔ˽ÕÒÑÂÓÒÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?AELLA>775;8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÒÕÔÒÒÒÓÕÓÓÓÕÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEK>>786967899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9699:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EILAALD??;9889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEGIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDJ;AA;<886486987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGIB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<BA<;876797799=?A?<:9@?<>B?:8776=??@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE>;HF89757875898;>>=;89A>=@?A>7596;>AB??@@BB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCEEC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELCA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<;DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGGNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAC?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€iixsg~‰‰xp‚†{w}~…Š½ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€‚wt|„‚}sp€Šx‚yƒÈÞÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsoupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿¼½¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»º¹¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjcmgb\XQPQKTJB:IQ?A7<94:565455688686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸········¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µ¶¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>F@BC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸¸·¸¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶·····¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨¨¨¨§¨©©©§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸········¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥£¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§§¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©ª««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤££¢¢¢¢  ŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž£¤¡žžŸ  žœœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=7789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥¤£¢¡¡¡¢£¥§¦¦§¬¬§¦ œ›¡¡ž›ššœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¥¦¦§§¦Ÿ›š›¢ ™––•š›™——˜˜šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜—™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥¢¢¥¦¦¥¦§¦¦ ›™›¡ —““’—šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB@DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥¦§¦¦¢œž¡Ÿ—‘‘”—›˜–––˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;;;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¥¦¥¥¦§¦¤¥¦¦¥¥£  ¡¡Ÿ™’–š™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šžŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡ ¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢¢¢£¤¤¥¦¥¤££¡¡¡žœš•“”˜›š›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œ ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸŸŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::88:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸ   ¡¢££££££¢¡ ž›™™˜™™™š™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢ ›ž ¡£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œž››œŸžœœœœŸ   ¡¡¡  ¡  ¡¢¡¡¢¡Ÿžœšššš›œš™š›™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥£¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¡¢¢¡   ¡¡ ŸŸžœš™š›››œ›š›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›šœšš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>98;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤£¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ žžŸ     Ÿ ¡  Ÿž›š™šš›š›››Ÿžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›ššš›™˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9;;>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœ›œžžŸžœšš›œœ››œœžžœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:=>:?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››š›œššš›œœ›™™œœœžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™˜˜ššš™™™˜š›œœœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›š™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š››››œ›˜˜˜™™˜˜™™™›œœžžžžžžžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ›››››››™˜˜˜˜˜˜˜™™œœœžžžžžŸŸžžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ››››››š˜˜˜˜™™˜š›œœžžž  Ÿžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_]]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜™——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜˜˜——˜™››œœœžžžžœ››œœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±³­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=9F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œšœ›œ›˜™š˜˜™ššš–‹“–™˜•˜˜–›œ—•’‘’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨©¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‹‘‹ŒŽŽ‹……‡‹ŒŒ‡ˆ‹Ž‹‡Œ…†‹†ŠŠ‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VPQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹‹†Š‹‹‰†„†‚€‚‰‘ƒ€ƒŒ†‹‰…€‡}€’†„„†ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹‹‰‰…‚}s}ˆ€~œ„……‰‹Šz}}†ŽŠ†”‘‹—”—’˜¡–ž—•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¥›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXO[\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ†‹†ˆ…„ˆˆ‰„‚z||}~’ˆx…‹Šƒ„…ŠŒ‘™””” ššŸ¢­±­©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPFMHSWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‹‡Œ‹Š‡’Š‡†‘“‘‘„‡}}ƒˆŒŽ‹ŽŠ‰Ž””˜‘•›š¨®²¯¯µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWLO_^\NUUbQDTM;?9<895775795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš˜ “—š ™›£ •› ¤£š“ˆˆ‹‰‘‘Ž‘Ž‹˜šŒ”š—œœ›Ÿœ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUKTOOJCPK_bXZQ\T`MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ª©¨§¡¥¨¨«©©¯¡›Ÿ¡££ šŸ œ”˜”˜  ¡¤ž›š¤§¤©«®¬¥£¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdVOXKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®ªª«¤¡¢¤©§§©¨£¢œ››¤ ¥¨£ ˜™Ÿ¡¢©§ ¢¢®¬«ª§­®¨¥¤©©©©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_UZNRNPORd\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢šœ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨¦¥§¨¦©¨£§¦™œ¤¦¢¡ ¡¡ œ˜™Ÿ ¡¤¤¢žž– ›š¢¢ ¡Ÿ ¢¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOWO^ddlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤Ÿ¢ ¢¦¡¦®¦¦ŸŸŸŸŸ™šœœ¡ ¡¤Ÿ¡›šœ ž¡Ÿžž £™–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvwa_\UYQUV[c^r_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?C?:8:>?C@DA:;><@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯ªª¬¨¨«°©¨©¨¡Ÿ §©­°²¯¬£¢¦¡©¥ž¤£¢¦ ¥¤¢¥£ž žŸ¥¢¢žŸ¢˜•žšžŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸ ¡¦¢›—’šš •|wo}yf[[`_Z\V\hdocniib^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¢ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶¯³°«±²±£Ÿ¢ª©§®·¶´´¶³¯¬«®«¶°©²±­®§¦ž¢££›œ—¢¨¥¡Ÿž£›ž¡š–¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¢™˜¥ ¤§ª©¨ª­¬¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxib[_^\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>AE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢œŸª²¸¼¼½»º¿´¯±³µ´··¯µ´µ²°¨¤¢Ÿ —•š—¤ª¦¦¡¤£¤«¥¥˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨¨«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥¡¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxxxc[RYT__amhukpgiibYSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶´º±ª®´±°±´µ¶¼¼¾¼¼¾Æº¸·º½´¯µ±±º¸·²³²ª¦¦Ÿ˜¤¤§¨¤®¤««µµ®³ §ª¬§ª©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš’–””˜“š˜Š‹‡€€|‚xa^YSah`fsositdidb[LK>:8898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÃÆÂù½¿ÀÀ½¿Ä½¼º½¾´§ª˜±À½¸µ¹À³¯¯ªª¨­§§¤¯§ª´¼±´µ¨¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`a^^jbbnwuvnl[bQU\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAB;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–•–‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±°§¼¼¾ÅÄÆÉÇÅÆ»ÄÀÅÆÀ¹¯½¼À¾¾³«ªŒ³»¾´µ·Âº­¯°µª«¦ª£­¤§±¶«µ²­³­¨®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|ƒjfhaklfnuqruqf^_\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÅ¿ÃÂÆÅÀ±“¾º¿Ã¶¶º©´³´©«³»»±Ÿ›±¯¬¤¬®´§ª©¨ª­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|tkkndomhqxnyjia\gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÃÄø´À·´¼Á¹··¿À»®¥®·¼·­œ£·°¦­´µ¬®¥¥£¨¤  ¥™ª³²¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyz{vnkiguZfrwsxfg]d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÊÆÄÃÃÁľ¸¾ÁÃÀľÁÏÏÎÆ«¯¶´µ« §´³®«¸µ³«©£¢­©¬¦­Ÿ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuueeijg]jomxwcb``^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÏÏÌÃÇÆÈÉÈÈÉÇÅÉÇÈÇ¿ÅÇÄÄÇÈÊÒÏÒ̼¸¶´¸¸Á¾¾º½º¼º¼¬­§ª»º¹·À²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqobagugiitmxl]d[U`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÍÐÎÇÌÉÂÁÇÁÊÊÈÆÌÊÍÅÆÅÃÆÅÉÍÐÍÏÌÇÄÀÃÂÉÍÇÅÁÄÇÁ»¾´±°°Á¾¿ÁÆ¿¾¸·Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`jjvlieuosb]bTWTSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<:>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÅÇÈÆÒÉÁÂÿ¿¾ÄËÈÊËÈ»ºÈÇÉÍÈÃÈÉÉÅÅÃÂÁÂÇÇÉÊÇÌÈÇÈÍÆËÏÅ·ÀÀÀÀ»º½µ³³¿¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrpfegdjeajmno^Y\VVNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾƹ»Ã¹¸¹»½ÁÇÁÄÈÆÇÉÃÅÄÀÄÁÂÁÄÁþ½ÂÀÀÁÂËÃÆÌËÅÈÑ°¾½¸º»¼¾·´°¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfadbabccjbfcZZZ\YQNE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶¸´´µ¿»½À¹¾ºº´À¸µ·²®º¼¶ÇԹ˾Á»¿Á¼»Ä¾»ÁÄÀ¾¾¸¼ÁÁ˾½ÉÄÀÀÊÀ±Á¿»¸»¾¹µ·´¸¼´½¸µ´°³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|yˆ}qc`bbgjgfiei]VVTYOSKE8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“’’˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´µ±°µ·µ»Á¸¾¹¿¼¼·´·¯®·µ·ÓÀ˜Ô»¿¼»ÃµºÇ¸¶¹»½¹º¶»ÅÅʽ¹ÅÀ¿¼Á¾¸Æ½ÁÀ¼Å¸¶·´¸¶¶»»¸¶´·ºµ´¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒ€xpmeefoiekhXXNKKKRILHC9=8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’š”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿½¼²­¯¬±°·¼·»½ÁĹ··¶µ¹¹¹ºÒ´Œ¸Ã¾Ƿ¹¸­·µ¸º´¸³»ÅÆËÁ»ÆÀÀ¿½¼¿ÉÃÄžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~‡|knpgpksebm_\THKJDJBCG?9;8><7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘ŽŽ˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼¼À·ª­¤¯°¸»²½¾»Ä¶µ¸¶¸ÀÀŻͨ„•ÂËÉÆÏÂÀ¸®µµ¼¾¸º²¾ÄÄÊÅÁÉÿ¿¾½ÇÌÇÇÄǽµµ¶Á½º»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†qelintnxcgb[cQKTHEECGC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?>??FD@A?>:7?@CC?A=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼««£±¹½¾²º¾¼Å¸±¸¸¶Ã¹¿Ãğ„‹¹ÊÌÎÑÌÊĵºÀÃÈ¿¾µ¿Á¿ÆÆ¿ËÆÿÁ¼ÀÃÌÊÇÅÆÀ¹½¼Ä¿À¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtolltkln_b^`aNHM?E@?DC<;::;:8;<:9<>9:>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´¼Â½ÍĽ»Ä¿¹±•ŠŽzˆ•­—…Œ®ÆÉÈÌËÍÊÆÂÄËμ¹½¹¹ÀÿÈÆÄÁÁ¿ÅÀÊÉÃÃÄùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{zˆzmmw{_pc[]_^SI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA??ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸µ¼¶º¼ÆÈÛµ¿¼°ŒjqqXbfx‰Š¨ÁÆÂÇËÈÁÃÁÀÉÊÂÀ»º°´»½ÀÅÆÅÅ¿À¿ËÇÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}zmsxsgp][^\YQEDCMIAE=G::59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘–žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯·¶²µ³·¹¼»¶»¼½ºÒ²Áɶ´’tyhb~i[Z\pŠ©»Á½¾ÆÀ¹À¼¾ÅĽ½¹²°®¸·¿ÃÇÃļ½¿¿Ãþ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸¸¸½¹»±¶²ÈÀ»¶´±°·¬³©°­­³·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|vluzpni[_`YSPAEHGK@DCH<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿš›œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹ÁÀ·Ð¶¦Æ¶ŽgRnnOs‹w^Y~’±¹·¸·Âº³»·»¾À»»¼®¯®³²¹ÁÂÄþ¼¿»º¸¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ¯µ´´½º¾¹º»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰|‚zsvvwnq`_e]ZTJ<??FF=FCC9:5;99><<::<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Ã¿¶É´–±¡gXU‹pS]z‚‡€Mh˜µ¶²²·¾¹²µ²¼¹¼¶º¾²´´´°¸¾ÃÆÄÀ½¿¹³¯²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtvql^b`[]OHA>=HCFMC@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·À½»Æ²“ž…XSgœfRWW’©~XZ§Ã¹³°¶ºµ´²¬¼¹¸µ¸Áº¸³±¬·¼ÁÇÿ¹ºµ®¥¬³°¦°­¨ž Ÿ¥­¶µÂ·¶´¥¨«¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´·¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wo{ourmc\fX\]RNMA>IBAJI@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³²­¶º¯­¼³¸º·»Ï¹˜“rReŽ|fTbm¥½†cSvž»¶±´µ²´¯¬»º¸¶¹Àö®®ª²¶¼½¹¶²±­­Ÿ¤§§£¦–™™šŸ©®¹¬««Ÿ¥¨¤«®®§¯¬¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmuik][jT]\OMHDFLBFNF8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹º¶¹»µµ³µ¹Ç¾ ’dR‹™rzy‹r‚’upum¢Á¸³´³°±­°¹¸¶¼¸»¿²²²®±®¹¯ª«­¬£¨¡ž—˜¡•’•—˜Ÿ¨®¤£¤ ¢§¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬«¯£¤£¡© ›“Ž“’’™–š¤¥ Ÿž§˜•’”™ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wrxhtsndT`cW\QNLH@HQDMC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯²²À¾¬œV^”Ä•˜’fuuv€~}¯¿¸±¬³¯®¬®¶¶²´µ¯ª¤ž›œœž¨¨ž ¨©Ÿ¡§–›——“–Ž—›¤¨  ¢¢¢¥¥££ ž¥ ¤¬¤¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›©¨ª«Ÿ¦¢›£œ•Œ“—•–˜Ÿžžš˜¦—“’–¢ ¥£¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦ ˆxƒ|vybwln\QhTPNGOMLBOQ@>;>39:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¥¬ª§½Éµ¤Vd…“~itlgcfkuqp®³³ª²´®ª«¯°²³®¥ž’˜”˜ Ÿ¢ œ¤¥Ÿž¨”›–—Œ—‘—“˜¢ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£ž™—š«¥©±£¥¨ž œ•“‘˜–•˜—Ÿ˜›™š£™—”–š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’}|€uu}mk{dhUQcMJHGNRNJNG<E@=2?759;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜——–¡¨¬®¶·º¹º··»®¨ ¡©¢Ÿ´ÏÀ¬]xuxtdiYPOSRWW`w†©µ®¯³µª¦¬«¢œ™”Ž‘–—™™œ ¢¢œ¥žš¤———–’‘‘“š—› ¤ªž¡¡ž¦§ª¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¡¤¡›˜ž¯¨®²«¥ªª š˜˜˜•“–š“••š–›——˜¡žœœ—›¡šžš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}vx|dyy`bRU`IIJKSTIRPL9?B67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—“’œž¤¨®­¬««¯ª¯©ž—ž¥žž©Í͙ozvtcSMTHPIPMLUdgˆµ°°°¸¬¦¡œš”—ššŽ‘•‘ŒŽŽ”™¢œ—£™š—˜™”™˜–›Ÿ¥¦© ¦£ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§  £±®²°´©±¯¢™œž¡™››š˜™›”–›–™œ¥¡ š£¡šœ™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ Ÿž ¥¡žž¥ ¦™{|uvsh‚le[SZYMQJNNTLSLA7>B68=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’‘œ˜¡ª¢§ ž§¡¥Ÿœ’œ¢›ž¤Ê°hjksbRSU…ujSOJJQVYc§¯­¬¯§Ÿž¢ —‘“› œ™—’“Ÿœ¡¤›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬¨¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½·¾°¬±®­©ª´±°¨«¨²µ·³¸¬²´¤ ¥Ÿ¬¡¡¢  š˜–– ››˜¤¡ ž£¡ žšœ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚|xuiwu]lZR`HRUHFUVJBLG=KH8E<67;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“Ÿ™¨®Ÿ§žœ¡žš™’™ž›¡¡¬˜xnk`TLXzª° lRHEGLQV«ªª©¤ŸŸ™’’“˜˜––•Œˆ‹Ž•ž–žš¦  ¨¥±ª§®£«­¶°´²±®¶¸½Àº­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«¯±¹·¼¯³°µÁ¼¶½³³µ¢¬¢©¨²©«¨§¨š™žšª§Ÿ™§ ŸŸ§¨¥¤Ÿª¡¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰…„~vqmivmhm\X[BWNJGMGBFM<>L=4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜™ª ±¢·¤°¦Ÿž—˜•™žšœ¤ Ÿˆm`UPQ[¢ÝàÍp[KD@Da–°­©ª¥Ÿžž¡¢Ÿšœœ”“•”žž˜”…š¡›«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶ººÀĹ½»¬¯§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¹Â¾¸³»Æüû·³©³­ª³´¯³®ª®£«§¶²¬¢°¦¡£¯±­°¤¥¯£¡ š¡§¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¥ž¦™›¢¤žŸ›››œ‡…{tqkkurphW[QETHDIOH>EA4FH95;=6;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž  œœ˜šŸ šŸŸ”sbWSTYm³ÜÆ°«¬ŒmU[¬°¦££¡ ž¥«¥ž—œ”‘™˜”ŒŠ†ˆ†ymˆ ¤¢«¬´¼¶Ã¾¾³»ÁÃÂÅÀ¿ÂÆÆÅÃÈÂÀÅÈÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌÌÌÒǾ¿À¾ÇÆ·ÃÉÉÂÁƾº´ºº´»·°µ²ªº²®»·¿ººª·­«ª¸º´¼®®¹£¦£ž¦¥¢£©¦™›Ÿ˜š§ª§ ¡¡¤˜”£–”™‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ„}yqkdhoxjdZ[FKLEDSLDBE7:?;549978>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ²²¸§¡¡«ª¡œž¡¡›‰_SQUYn‡µÅ³”žØʬ£°¬ ™œ›žž™———’ŒŽ——“Ž‹‚ƒ‚wsqnp¦­®´¹Å»ÍÇË¿ÂÌÎÍÌÇÉÑÌÍÌÇÉÅÆÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÒÓÍÓÐÓÓÌÊÂÅÆÆÊÈοÈÑÌÇÅÇÅÁ¼ÃÁ¾¿¾µ¾³­¿¿ÂÃÇÄÇÄ®¾¸²¸¼ÃÁÁº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›Œ™‰•˜› Ÿ£—žš““‹•…€xtsebgrof^ZYCNLCEPIDC@5558:B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>8;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›¢¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¤¨¬­ª £Ÿœ›|SJORgƒ¢¶²¥‰­Ì»±¬£žœŸš˜–”’”–‘Œ‡„ƒˆ‡ƒ€€yrroly¤¶º¹¾ËÁÓÒÓÈÍÎÑÓÑÒÑÐÑÑÍÎÎÐÅÎÔÕØÒ×ÍÆÇÉÌÃÅÊÏÊÒ×Ñ×ÒÔÖÓÓÈÌÇÌÍÉÒÍÎÓÍÅÈÉÊÁÆËÇÈÉƿó³ÈÄËÊËÎÅÊ¿¾¿½ÁÇÄÌÌÈɿÿ­¯³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›•Œ†‘‹€zrtvhcgvidVWQDMF@IQB=B<:22@<D<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<@?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­³·¬®£ž£¢¡¥qNEMUw“ÅÊ®œ£±©¢œœ ¤ š””•”‰|wpkebhqoq{…Š€vpnqtp…³Â¾ÅÑÐ×ÖÖÒÖÍÔÖ×ÔÓÑÓÔÔÓÏÑÃÐÓÖØÕÖÒËÉÎÑËÆÍÑÉÒÕÖÙÕ×ÓÖØÎÒÉÏÑÌÎÐÌÒÏ¿ÈÇÊÃÌÌÌÎÏÅÆǶ¿Ê¿ÑÍËÏÅÉÈ¿ÃÃÈÎÌÏÐÏÍÊÇ͸·»¨Ÿ¥«§ž˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„|xsvoc`erb]R\IJGAEHI>;A8=4585;86:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÁűµ¨¡¤¥Ÿ¡¬xMIN^„·ÛÕ¸­ªš”—Ÿ›› ¡Ÿ›œ™•‰wic`____^_`^blusqpolrqu’ÄÇÆÔÕÖ××ÓÖÏÕÔÚÔÔÎÏÕÔÔÑÑÌÐÎÓ×ÖÓÕÐÏÒÓÑÉÓÑÇÐØ×ØÑØÒ×ÙÕÖÌÏÏÉÍÒËÎÐÀÆÂÇÅÎÍÑÑÑÈËÍÀÊÌÅÓÎÌÎÈÄÉÆÆÈÌÊÓÓÑÕÏÒÌÓÁ¹Å±¥¨µ®§š¨¬¥²¨°³¬¬““ŽˆŠƒ‹„Ž™“™‚…Œ|zqstmacim_VP_JJCFCRM?<>54:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><??=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯­ªª«¦®·¨«·×ÔÕÙÙÑÎп¼Ìɶ¾®¦ª¨¢£³‹[em‰·×Ư¦Ÿ—•—™š œ™œ“}qecc__a__a`_``_`fmppnkorww›ÌÀÒÕÓØØÖÙÑÒÒ×ÏÓÎËÒÍÕÔÒÊÏÌÓÖÒÑÖÍÏÕÕÑÆÑÔÊÐÔÕÖÎÒÐØØØ×ËÈÎÄÉÏÌÊÌÀÉ¿ÇÉÍÎÏËÐÍÎËÎÎÇËÐÐÊÎÊÂÉÆÉÌÊËÑÒÌÓÑÑÏÐʽȹ°®»¸µª¶°­¨¸­³¿»±šŸ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…ˆzuopnkadnpaW\ZIFFDMWE;@=33<=87855;>@=9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ¤§Ÿ¸¶µµ¬¤¬®¾´°ÀØÒ×ÚÜÖÎÍÊÃÒÏÁÀ°©¬­©£³›xŠ§ÎÔ³››•“—›žžžœ”–˜•ˆk^^^adb``aa``a^__^]bmroostvvy¤¾ËÕÑÖÔÓØÖÎÎÔËÍÎÅÎÊÒÒÏÆÎÍÍÔÌÎÓÍÊ×ÕÐÌÑÔËÌÐÑÓÊÎÑÕÒÕÕÊ¿ÉÁÅÌÂÈÉÂÌÃÅÈÊÊÏÊÍÌÐÍÓËÆÈÏÌÈÇËÄÆÁÅÊÌÍÏÑÆÐÎÍÍÌÏÅÇÀ¸¹½Ãýù³²¾±»Ãĵª˜¥¢™–‘••’‹”š‘”””‚‰…yprkmg``phXXhVLFLIPPB;C>;67:89:57==A;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÄÂÁ¿»µ²±Ç¸ËÕÕÙÚÛØÌÌÏÈÖÕĵ¯´¨ «£ˆ’¸Ô¬”˜•”’‘–––‹|eabb`]^acb`_``aa`_][]grqqrsqmry¤ÆÓÏËÐÏÔÕÉÅÉÉÆÆ¿ÃÆÏÎÇÅÇÍÊÒÈËÎÍÆÑÒÏÎÌÔÊÇËÎÏÇÇÏÒËÐÏźĿÆɽÂÇÉÎÅÂÈÀÇÍÈÄÌÊËÏÈÄÄÐÈÆÂÆÈľÀÇÌÌËÎÂËËÈÇÌÐÄÅÇ»ÇÃÉÈÂÏÁ½¼¿°ÁÉǹ½ª°²§¥¢œ˜›£™—™‘•˜‰‚wotdk`^fpa[W`GHHGIMTG?J=64355=<48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ¼ºÍÍÆÐÕÕÙÚÛØÐÉÏÏÑÓȶ»»­£µ’h€ˆÄ®Ž—†ƒ„„‚~……s`[^^^`^`cdc_]]^_``_[Z\akrrookloo}¸ÑÈÉÊÏËÍĺÀû»ºº¾ÉÆÂÃÀÃÈÊÉÈÊÈÁÅÌÆÈËÍÉÄÂËÉÁÂËÐÄËÈ¿¹Á»ÆǾ¿ÆÏËÿûÉÇÈ»ÈÆÅÊÀ½ÂËÆÅľż¼ÀÃÅÌÅÅ»ÀÊÂÅÇÒÄÀÈ¿ÊÉÆÈÆÐÃÃÆïÄËÇÃÊ·¿¼º´©¬¤¥˜Ÿ˜¬£¡¥›£ ›”{vstfiZanlZ[XRDLFBGDLDFS@54334?<3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ÊÏÑÌÇÂÃÆÍÎÎÌÕÏÕÙØÙÏËÒÍÍÎÈÁµÃ¾±¯¹‚b~¶Š’—‡z€…†€vxurp_[[]``bcdded`\\]]_^`[YZ\borokilposÆ¼ÉÅÌÀÆ°¶º²²³²±Â¼¼¼º¸ÁÁÁľ½¹½¿¹ÄÊÅƽÆÀ¸»ÄÉ¿ÂÉ»·»ºÅÿ¼ÁÍÃƽ½µÁ½Ãº½Æ»Âº³¼ÅÄÁ¶¿µµ½¿»ÌüµºÈº¿¾ËÃÁÅÂÆÉÆÈÆÐÆÂÌDzÇÉÃÎÍÁÅÃÀ½³·°²§¨¨¹°¥­°ª­¬”yvwjdg`hocV^YJFJFHJAEBEI@9:648853;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÅÂÄÈÎÑÊÊÊÇÍÍÎÑÈÐÆÕÔÖ×ÍÊÏÅÉÅÇÁ¹Å½«¬®oev“‹ˆŠ…y€††€~„|ttc[\]^``bcabeeb]][\^\^]Z[]]hsqmggnpry½ÌÀúÁ¸®°°§ª­¬§¸µ·´³³´º´½±·°µ¯²»Â¼Áļ¿ºµ³º¾À¸Ç¹´»¶Á¼¸½ÆÁûµ®²¶º¿´Ä·»µ«¸½½¿½±º¶¯¶º³Å¼·®»¿µ·´Å¼¾ÃÅÀÃÅÆÈËÅÀÆÆ»ÇË¿ÏÊÇÃÆÂ÷ý½¶¹¾Ç¿¬µºµ·¶Žytxfgebkn^V^`FKHHJFBDAEE?<:565633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÍÈÅÈÍÌÐÌÍÈÊÈÊÉÊÄÏÍÒÏÍÅÇÁÅÀ¾¹¸É¶ª¯£eiuŒ†ˆ‰{x~††wx‚}ti^]]]_`_`da^cec__\[^\]^Z[[]_lpnhfjnnr|¤Ç¿¸¸µ°«¬§ž¢ª§ž«­³­©«©´®¶°²©®¦¬²¼º¶Ã¹ºº±«µ¹»´Âº°À±¾¼»¶»Ç¹Â¶­ª¨°±À¶¸½¯°§²³´»¼«­µ¦®µ¯»²°©¹°­»®»¸»À¿½¹Â¿ÇÃÅÁ¼ÆÁÇ˸ÅÇÅ¿ÆÃúÄÆ»ÆÉÌ˳¹Â¼»³ˆsvvkiablhYWW[ALKMIEAC?FA:9:995854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÅÎÒËÃÅÁÅÏÇÍÁÃÆ¿ÄÄÃÃÊÁÉʾÀ¼Áº²´µÄ¯ª¯›al‘ˆŽ{x~Š†z{„wn^]\]]_`^_dcbccb`_][[ZZ]ZZZZ\dnohfgiknr­¹°µ®¦¥§§š ¤ šœ¥«®£§¢«ª¬ª°£¦Ÿª­µ¶±½¹¯·¯©®·´´¼¸´¼¯·¹µ²»Á²À®¥©¢«±²³¨½ª«¨«¬­´³¦¨­¡¤¯©²¦§¨®¥¨·¬±²·ºº»²¼½¿¾Ä¿µÂÀÇÈ·¿ÀÄ·Ä¿»¿Ä¾ÄÈÌÊ¿¾ÃÀÀ©‡strji]aodWVXPHYRSKFFE>>@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÐÏÌÃȺºËÁ˾»É¶½Ã¾¹Ê·ÁÃÁ´¶¼¶±¯µ¼®¨©—eoˆƒˆ‹€{~€~xt|swe_]\\^_`^_ccab``_^]\ZXZ[[YXZ\_fkfegeikor…ª¥¬¥ œ¢¥”ž¤›˜’¡£ª¤¢Ÿ¥¥§¥­ ›¤¦¬²¯¶·§°«¨ª´ª´º±¶µ®¶¹±¯ºº±¶¤ ¤Ÿ¦±§«¨¹ª¤§¨¨§²­ §¦Ÿ›¤¦¬žŸ§¤  ±­­¬²´²´°µ¼¶»ÁÁ²º¾ÃÁ²¹¹Ã³À½¿µ¸»½¾¼ÂÇÄÂþÀÄ ƒxpkaf_ko`TY^HNgOTGEJF<=?=:;;825536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;=:7676788666;::;9:;<859<:>>@;Èµµ½¸ºÀº½µ ž•¡¦º¶«³³»³ÄÏÉËÂƸ·ÇÁÌ¿¸É·»Å¸³Ä·³¿À¬¶¼²¬¥¯´­ ¢”lx…††|yusomkjiqi^`]\\\^__acb````]\[\\XYXXXVX[^_dcbegggjmoˆ© —–›¡–›¢˜–ž¡£§›ŸŸ£¥¢¨ž›¢›Ÿ«°¬±¶£©ª©¬¬¤´¹­·°¬³µ®²µ®°ªŸŸ¤¢²¤¦©¸­¢¦¦Ÿ¨¬ª™Ÿ ž™Ÿ¥šš£œ›¯©«§ª«¬­°²¸¯¸¹»°¶»»º«³³¹³½´¶±±µ´¿¶½À½ÃÁ»»½—ƒ{sk_e^ddXTW]IW\KPGIIFA<??@;?<04535:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»·ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÆÏÈÈÀÆ»»ÄÃϾ¹Ç¸·¾·²Á´±»»¬ºº±¢ž©«§—q…†xrnpnkb^bff\]^]]]\]_`abccba_\[[ZZYXXWWWXXXZ^bdeeffhikr§”••›˜›¢––‘œ¢¢¨›¥¦¢¦œ  š˜®®­®² ¥¢­«§¡µ±²²¬¨¯²§º³¦µ ¢ž›£¢­£¢©µª¢£¦¦¦£–˜ž—™š š—œœ›¬¡«§£¤¦­«³³ª´°²ª²¹´¯©¯²²³·³®©¬®²¸°º¶¹½¿·³±”…yue^e^[YVSZUK[QKIEHKIB=?AA@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½·½¿¶¾¼¿²¥£˜¥±Âµ¶½­´¸ÂÌÈÆÀŶÁ¿ÇηÀĽ³¹¹²¿¶±¸º­²µ¯Ÿš£ª¡’™yƒ„xoqtqhfdhec\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXWVWadecdeddhjv¢œ””•—— —™•˜ ž¡œ–¡¢©¤Ÿž©œšš«§¯°ª›£¤¸© Ÿ®¨¶ª¦§­°¤·°¤· ¢›™™ª¦ š¬¸°¢¡¤œ¢ŸŸ“•¡”•–›˜—–—œ•Ÿ©©£¡£ªª°­¨´«ª¦­²°¥ª®²±°¯®¯¦§§²®±´¯¼´¹·®£”yud^aVYWSRTKM^LOKGGLLE<@><B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾¸½®§§£ª»À½À¹®´¸ÁÌÇÅÂýŷÈ̲ÁÂÁ­¼»µ»¼µ¹¹°°±ªœ™¡©•‰Œ€|wqilrtphhedfb\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWWV[bcbbcbcdfj–“•Œ’””›™––œ œ –¡ ¦¥¤¦§ŸœŸ¦ ª¯¦Ÿ¢¤·¨¡¡¢¨´¢¥¨¥°¥°­«´ž ••ª¡¡”­±±Ÿ¢£ž˜›“‹¡”‘“˜˜’——˜—¦›§¡¢™£¥¥«¤¥°§¥£««­¦¨®¯®«¨ª©³¥¦¬¯´±®¼µ±¯® ’zvrda\Z]XNLRHRaMVPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8846863321./2556;:8;7876<;:;;A8x»»±µ½°»±¸¬ž¥§­·»¼Áź±¹µÄÉÉÀÃÆÆǶÆij¿ū··½¶½»»¶³­­¨™˜Ÿ£‹ˆs‰ˆ~vncafihfhjgjm`]\[ZZZZ\]\[\^_\ZY[YYZ[WUXWTTVURTRU``_`a_`acdi”“‰‘”“””•—¤™ —œ ¥¡­¦¤¤££¢œª«¥™Ÿ¥±ª  ¥«§¢ž­¬©©­¬¡¢¢•˜£›œ«©°›Ÿ¢Ÿž—™“Šž‘’“–˜˜“œ¡¢¤ ¡• ¡¤¦›£«¥¢¤ª¤«®¥­²©¦¥¦¦´¦©¨­³µ´¹º¯©¬ž‹rpo`[WVURGQOHZ[ORITKSLEFIC8;;=<8667:9;:976977:;:=<<6;<8>598:88659:;<97?<9678452121..1426:8698598989;9@9{µ´­´»²°«²­¨§¯¹¹³ÀȺµÀ¯ÅÈ̺ÁÊÌȵɼ±½Äɬ±¸Âµ¼Á¼´µ«¬¦•™››‡rˆƒ{tiijlgjkmkjme]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURSOQY]\]]^^__bdmŽ„‘‡‘™“•“œ›£œ› ¨©«¨¬§¨¥£˜¤®¤”™¥¯©Ÿ›™› ž®™›«³ ¥¦Ÿ¢£¡•“›––’©©­šœŸ¡ š”Œ™ŽŒŒ’–•ž¡ £œ›£•›¡£¡—¡¨£¢¨« «¯£­·¥££¢¬­ª¨«¯²·²½µ³«¯˜„ssh[XXRUQEXLQ[XMTNPLPQINIB<??A?<65799<<987:79:;<=>;7;;:=67:;8976989:6:=99577571141-+/434988::8::748=8?9~³­¨³¶®©§¯®›©¨¬·¶¬¼Ê»¶¿¬ËÆŸÁÎÏȳĺ·»Ãȱ¬¸¿·¼¾»´·§ª ––˜•…yt€vwnmhmnmpggigd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUSSNPQYZZZ]\\^_`d~‹ŒŠ’—‘—™¢ › «ª¦®¬¨¯£¨šŸ¬¡•–¤¨§—šž®–˜¨ª™Ÿ”¥ ž’’‘“•§ª¥š™™žž•Œ‹“†ˆƒ‹‘•‘ ž¡£—•Ÿ•š¡¢ž”›¥¥§¨¨ ±°¦±¼§Ÿ£¬´«®§°µ°¹µÀ±­±«}qrbVSVNRIFVPRQLLWMJLNRGMJACFDC>@65889;9:7::7<=:;@>:9;9:?759:9876958779;85576661320-*.102877;99;8948;8@8³¬¦±·ª¦¢°«ª§©²±¥¶Æ´¹º³ÊŹºÁËÐ˱¶·¼¾Áñ°²¸­´´»´¶¥¤œ—–’~vkglnqnqjpkdege^ZYZYZZZZZZZ\\]\ZXXXYYWXWUUTRSUSVURNNNRWXYYYY\\]aj€zv‰‡Š—‰””˜›™ž©› ª¦¥«§™ ¥›“Ÿ£›——…„’›£”£–––ˆ¢››“‹ŽŠš¤§œ••—œ‘‘‡”Ž‹‹Š’’’ šŸ¢•“˜˜•¢¦™Œ™¤¦¨¦¡Ÿ´²¨²·¡œ¢·¬ª­¤²²¥µ¼µ««±£‰xrm]NQQLOCMNNPKFNNJJNMQIMJAGLHGC=858889:;69:68;99><8:>9;?8789:886857688974577820301+)-/12876:999984988A7w¶§¤¶±¥§£©¥ ¨¥¤³ª¢²Ãµµ²³ÆÆ·ºÃÊÌƳ¬¹½´·À¯­©±ž¦®º°°¡››•“†z‚m__frpvqinieghj_XXXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQMMKLSWWVXXYX[]aosvq…ˆ‚ˆ€‘„‹”‘”ž¡›œ£¡£˜¥–¢›•‡˜šŒsƒ~—–†‘™”ŽŽ{™œŒ‚‰Š˜Ÿ¢ž“˜–…‚”~~t‰Žy‡“š™š‘•Ž¢£Ž‰š ¡££›¢´¯¬¯¬Ÿ˜¥¸¦¦±¡±®œ°»ª©¯ª™‚vrbUMROPMCSNLQMBPQHINRMHJJCJLFKK<749888;;69;7:<9::;79?9>@79:<89764445874312585/0102)(,-11764789::65:87A7x·¡£´©¦¥¨£¦¥¦¦¦³§¦´Á¸¯´°ÉÄ·¹ÁΞ³¬ºÁ«­Ã­¨¢§’¦·®¥¢–—“}w}eWV_gfighncjhgb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTRMMJHNSSSTUUWY[]ilrm…|tNXrƒ—†œ—‹”Ÿ˜•”–”Ž–‰€“‰_;Wo|‹”‰€Œ‘Œ††sŠ…–yz…””ƒ–Ž‘ƒ†}“xqo…}‰‘—š˜“Š‰œ‡Ÿ˜‡ˆ–žš¡ —§¯©­¨¨Ÿ–­³¢¦®™¬«˜§´¢©­£“~rm_[NSRVLDTJPMLFNOIELQMKOJIMOFII<7599999:7:;:>>8:==6:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9y· £­¡¦¦ª §©§£©°¨§´Á¹°µ°Ç·³½Ï¿¹¯®µÂ§ªÅ©£™ƒ”œ±¤šˆ”Œ‡|su]QLRUYZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MORMKHFHNQQMPRTVXZ`mpi{‚tPB@•‘‘}‰”„Š›–•‰’ˆ…•†yˆ`JQnxŠ‘„}„Š…n~”wuuw„™pQˆŠ†{~x”vhw†ˆ~Šˆ•Š‘’–‹„Šˆ”„šŒ‚„’š–žœ”¤£¨©¥¤ž›°ª¡¤¤‘¦ª–¡©œ¢¦¨‰ule^[HQQRMIUMSILKOIHFJNLMTKQPOFIC<769:8:;;8:;8>?99>=8;<6;;478;6775344696/3/.125221/,')+*,4833979:99::::?9w¶›¢§Ÿ¢¯¡§¨¥§¨¯­ªµ¼¶¸·³Á»¶§¹È¸¶¨¨µ¶ª²¼¦ž–ŽŠ”©—˜Ž„„}wqnXMKMNOLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDDINOhYNQSTUZnƒtw~ji]U‰”‰t‡|…Œ“’™‹{†€vxsnuptŽz~Š«…yzhv{Žprmx‹’xz€{€vrr’wgu„„„„{•‰ˆŠŒ‹€„‹Œ”ƒ{˜•œ•‘Ÿ©žŸ  ©¥Ÿ˜§¤“ Ÿ–žž¤€rh`\\JVORGJXROJLMRJJJLPHLQLRTLEHA<77;99>=:;<98@?::>=7==79937795675252572/2.,//200/-+(().1272198798775:<;7v®˜£¡˜œŸ´©¯©¥­¬°±ª½´²»¸¶º´±Ÿ·º²ª¬©¨²¯¡š‘Ž”Žœ”xˆz}wppiXKHHHGEHHPTTTWWSTUUUVWWWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQQSV^uƒ}ygw—˜}hyvx€‰}„˜’r‡|w{ok~­}s‹{†’}tfv|†lohs|‰Œˆ€lyq}pmuqiq€~ŽpC‹„‚ƒ…wwz‹…}Œ{u~Ž’˜Š’š›£–™šž¢–Š¥›ž—Ž–˜vnmebZWWTQJSUTOPNPVKNKNOJQNHNOKEC<;79;::?=9<:99??;8<=7<9999266856633621224.,,-..-0-+*''*.1362/876966527995y¦— Ÿ– ¦¯¬®«¨©°¯±«¼¸¬»¾¹³¬§›°§¬›–œ¥©¤ —™…’z‰ŒxrovqlnkXKFGEA@CDILLMQRPQSUTTUVVWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNOQTX^eprmˆ§ªÀ~uyc|xo|yˆz}‹†omŒ’ytxjj€‚q–‘‹~–€I“˜nhw~‚licly…’†ksl|nr{†imps‰„†z}~{vots…‚yxp|ŽŒŠ”ƒ–—˜š“•–™—ž—Œƒ‰Ÿ‘‹’†–~mhmnnWUWTRQYORTTSXUMNHNJMNJCHNGE?:89;99:><9<;::=>:8:;9?868727575541442/024*+**-.+-*(*(',-1250,5567485HA895w™‘›™šž¥­°¢¬ª¨µ¯®¬´¿ª»Â¿¦¢™•¤—„‹”¡¡˜˜‘“‹sŽz€†ˆvpvmqmflkYNEFC@<>>AFFGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_IMOORWZRY\`§ˆbšitzepmz‹‰vˆ†tlš‘ts|jkMy…’‰„Žg1v†sl~~ƒtfet~„„…€filukq€|gqq{n“{s}|qpnum‚~wyujy‰‚ˆ‰ƒ–“’‹‘””—Ž€yˆ—ˆ†Š†€‡vjjngdWQZWYY[MPUVYXNIHEJJHFBAFDCG=998;9:9<:9;:::@<9:<98>787715244533645031.**+),,++)(+'),,226,+5775478iO8;5n’ˆš‘™–¤¨®ž²Ÿ¦º¯«²°Â±»Ãǚ–Ž”™‹…y„˜”Œ†q‡‚t‡ˆ{qsqopfqg_TFIC?<;9:?@ADDEGJLOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOOQVLAIQIb¯³ r|xl}mrƒ…z„††yr •sx€su”‡5q¨Ž¡¡„¢…vp†|‡|sŒ­‰€gfbjnrmpƒuioXupŽš’wl{}mqmp€zsuncvƒ~†€…‘Š‹‰‘‹‘Œ‹ƒux‹€~ƒ€~zqpok_Z\][YX`^RN[ZXWLHJEJG?CABG>CD=;97=;:;;9:99;:?<88=:8;66651121353475531./,,+)*))***)(*)+/3DM2166643<vR7=7b’’‡–‘ž¤§ž¯•¥µª®±®Á²»ÁƖŒ”€ˆ}n’‰ƒŠ‡…u‚„l•ˆ‰|uxxmwnwdi^IPG>@7448;;<=>@BEHLLLMNPQRUUVWXYXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL7CMRSDJ†v€||v~mwˆˆ|~…ƒŒ~v¢™y~†…™„›œa†ªŸ‹ƒŽzwˆ~‰ˆsŠ—„z]dqtz{wŠlgjbyo…‚znwt„zpszwkni^w‡}‡|ˆ‡€‹’—ƒ…‡}q„„|uw{}‰uorsef_[[]S[f^WQUX[UGJJDKG?F@DC>AA=:97<;;=<::99;;=>79>9986754244004645654-,)+('''&(())((+++/00Uq<23331E~W4=9\ŒxŠ”Œ’Ÿ¦‘ « ±¨¯À±ºÅº–Ž‘”‡z…vkŒ‘‚}Š„ŽŒxƒ€s¡„‹}}p~zhvkRWL@E211267688:<>BEGFGJKMOPQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMORLKT]YRJi„ˆ{‰y|q|Œz}‰‡~—‡v¡™ˆ‡’”¥¬©H†®¯¯‹€“Š‚‹„‘¨‡€˜˜Šœsm|†‡}Žhghx~n…‡‚…q„…Gk€wqyvhmk_v}ƒ‰ˆ…Œz•ž›Š‹ˆ‘zu‹v|wmow~srqjZ]\[ccXfe[UOPVYPDLKFNICFCCA@CA=978:::;;:888::?>6;>7585773344236656768;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|~Š…ˆ‘–—’—¡¬¡¦¸¯³¼³—’‹˜‹}tp‰’~}Œ‚’”}†~†¤‡ˆ‚ˆ…x‡‰~s„x_cVKB60./23123668:=??BEGHJLNQSTUTTVUSQOGC?80,#‡[>?84.]–ps£UFIKMNPW`YpZ\^j“‡•„‚…‘“~…‰‘š•‚ ¡—•›š¥­“š»±§»Ç芌¡¥”‰‘{r„žŸ‘œv……Šˆjhoƒ€u†„‹q†‚w‡€{v…}nvug€”†‰ˆˆˆ‡¡«¡–‰Ž˜{‰zzogkx~x}qjc]ZZ]i\af_YOKNWRQIPJDNGCKDCADCA<:87=<:<:88778:==8<=68656623445576867<BB?<8:>CQ^e\G2'&,,--.1(?Œ[.310Oƒ_4?;nupfxƒ{€Œ€‹šš¤œ¡¬¦«¯°—‘‘„¡”„xwŒ”|’†’•Š€’›Žƒ€‹‹‚‰ƒŠlpj]BA4--//./02234779;=?BDHJOQRSRSTTRPOHDB<87/9D><<63.l“—MPHIKKKNV`cggmu›š““‹Žšˆ“‹  ’£ª¥£¬“¨¶¢¨Áîǯxº”š|¡ž™„“…‚¢Ÿ”™’„Š…˜‘–lpu‰‹–Œv„ql…Š–’ƒ…ˆr‰¡–‡“‰–¥µ©›•¢ƒ‡“„}kjk|€€ra\b^Yfj\kk^WKGOSQNMLFIPCDNFBCEGB>997=<:;:987767;:6=:785456345566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYp‚pu‡qv’†~—–š”ŸŸœ§ ª–“˜žge¤š~„’‘y€’ˆ’}Š…˜’‘‚€€‹‰…‡„ˆ…xxgMR>/..,/.-/000212457;?CFNPRTPQRSQNPIED>;<:CF?><752<?R5HHHLLMNR^oŠ|s} ›¨¦¢™¡—¢•œŸ¨ž©«Ÿ¨¬©ªµ—«¿«¶ÈÈ·ÉÑϾ› pi«©Ÿ„”’†œ¡šš™§‘‘ˆ•¢ššwz~”—‘¡’——”ž{v•’«³‰— }”žœŽ“–™¤¢¦¶°‘™¨ˆ—Žˆlss|~zpg`[_^afc`gg\QEJKPOIJLFFMCHLFFCBGD@:85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Ppu`n}awŽ}|”ŽŽŠŸ’—ž–œª˜žªBD}‡‰‡˜x‚ŠŽŒ{Š†Žƒ€‰‹Š„’…ƒ†ˆ€‡w_bP460-1/,.00./..0015>AAMQRSPRSUSNSLEE@<>=GG@A@8662<9;FHGIIMOQYm†w•‹£§ª´½¸¥®¬¬§¨´¬°·²²­»±³¾œ³Ä¬»É˸Ŀ¸¥£°²¬­«¤‹–˜…¦¦ ¢—¦™¢ª¨¤‡…“£¡ ª ¤©Žœ±‹•£§·»› £°“££ž‘¤¢«¯­³µ¢•¥ªˆš‰’Š•z{~„}f_g[da]cc^ff^[OCIHTOFHLFJGEFHAKFCFFA:87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLicWjpXz„v”…ˆ‚›ƒ’’Úȝ–sV—ˆˆœ|†ŒŽŠ‰zˆ‚‡‘Žƒ…€‹…†‡’†‚„‰†‡‡‡qna@E64<2/110-,+-1/-4?DAMUQRSUUWUN[PGGD<>>FHCD@8;<5C;=FKIGHROPW“ „®£³ª²ÁÇë³Å¶¬³À³¹¾¶¿´Á¶»»¤¸Æ©¶ÉǶ¾¹´¨£´­±±œš’šŸ‰§¯ª¤•vŸ¤—¡«±³˜–ª­¨®µ»²º¬¯µ¢±¬±µ¼·µ®µ §¨£¨›©°­²º¸¸§›·©¥Ž‘“ ‡y‚tX`cUea`b_`e_ZUJDELUQHJJDIGEA@@KDAMF<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AEWQJL[ZQcdWzuq‚”}…†“v…~€{¿»£¼‚´”“›„ˆ’‰‰y†€Œ“Œ‡…Ž‰Ž††ˆ…Š‡‘zxn]V@EM<6:46AB764//6CHCQ[OQUWU\WP_UIKJA@?GKFED;>@7D7?BJJEGWTP^¥­£±´Ã¶¸ÁÌɶ»Ä½³³À·¸Âµ¿°¸t²´¦ºÅ¤°Æ¹±³±´¨¤µ¶ª± ¢–›¢’¥±­¥­¬§¤˜ ¬³º¢©²ºµ»¾Ì¿ÅŽ½³Â·º¸¿·º·¹¬­°¦±ª­¾°½»Â¬™º¨”®˜˜ª‰~{jVa`WidhdVZcYVTIGGLQGCHIAHD>?BBK@@LC99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FQLALRWTYUZwjp„Ž…nzryˆb¸¡™£‰•“–“““—’‡‡{†•Š€„€‰z|‹‡†|Š‚Šƒ•}wyueO\dGEL:Qda[^SF>;HPDZdQQYXYgZT``MSOEA?IJHEFA@C=E6B>HGKLSZT]“¯¸µº¹ÉÀ»½ÉÌ»½À»·µ¼»·¾µº²Æ`u³¥±šž«½ª¥¨«ª£¢²µ¡«§ž•–ž˜Ÿ®¥§§¥ž¤”¢§°³§²²¼¶Á½ÓÉÊÓÆÂÅÌÂÊÃÀ¾½¿»¼·´°¹··ÃºÆ½ÃÉ°ž¹ª¢¬¥¨·‰~q^a`\Va^geRXaVRUIEENKA>GD=KB=B@=F>;H@796379>489:57045/26389374526?8@>GKRTSQPOQRQJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKE@IMPRLQ]hllq…slsrsˆÕÀµ™ •˜™‘Ž—‘––Ž†‡}†ƒŒ–‹ƒ‚xz‹ƒ‡{‹yŠ‚—t}zkepuY]\Peeb`ed][XW\MdmURmm^o_XgeUYTJDAKKHFHHHHBI9D?HKTTV\Z[’¹À¹½·ÆÀ»¹Ê˺¶º¶¸¹³¸µ´®¶¶™du¨ž­p^¢¬œ˜¡¢›¤ž«¥”ŸŸ”–˜—¨Ÿ¥Ÿžš™ƒ¤¬¤ª°­·°½¹ÔÐÏ×ÏÉÌÒÌÏÎÊÇ¿¿ÂʽÁ½ÂÀÅÄÅÊ¿ÈÏ´¤»°µ°›¬¹½š~xk\_[X]`YbbQ[`SQKCBEFE<@E>BHB@C=:E>=J?47535;=468977022/24169775555D3ELM>51/006:477@IOJ;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODR\Yi_p—’‘”nlouuˆ³¬¡¡Ÿ‹™œ™ŒŒ•‘›’…ŠŠ~ˆ‡Œ‹‰|„s{‰ƒ†|‰t‚Š†•s{xlmu{hreilifjih`fihmZmt—­¤¼ˆ‡g[oh]ZYTHJNPJKQLTQILAJGKP__bfia˜·Ç°¹³»¾¶²ÄǶ°¹±°»¬³±§ª·¬¶§ž›§šN›ŒŽ –‘¦˜¥•Š““‰‰’ž›¡˜›”–‡ž™¦›¬¯¨¯§³´ÔÔÔÖÑËÏÓÕÎÓÏÌÅÂÊпÊÉËÉÒÈÍÍÂÐÒ¸°Ä¼Äº¦¶»Ä¢mb[[]W_WYeYP\WNQCBHEBH;AD>AH??B7;D>@H=46655;:687654/10146278875367C5B8?-0,1348=97,.,1;FL=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYSeWs˜ƒhqoyyƒ ªž¦—››—‹•‘šŽ}‰‹…ŽŠŠ‹ˆ|„‚p‡†{‡rƒ’‹}qxulqx~q{mxslh€pmcimpyiw}~Ë¿Âߧmcxnc[a`JPRUNY^P]]NQNTQUT\nnw‚r–®¸¬´§°¶«­½À±«µ¦¥¸§¬®¡¬´£Ž±®š˜˜Œ‘”‘„Ž›¦‘œ‰ƒ‹„Š‰„‹ƒ”•˜—”›œ—™™žž«¬¤§¡¬¬ÎÒÕÑÍÌÒÓÔÐÔÑÎÈÃÔÑÈÎÒÓÓ×ÍÒÑÅÒÖÆÀÎÇÈ鿸Нxmd\a\U^Q]ZNOSPNH>AFBBE<@B?EE>??:===<JA45465<888664412/03526768533;=<E=@11+/349>5901022-2EO3)/3.32=N248C}_2A†tD:==I>@CFH<VRMO[u†…Šwmwp}~€¡žž¡‹™““Œ‹“–„y…‹Šˆ‘‡‚{r~€‚‡z…u…“‘‰ovsls||v|swqj€rrioqzyr{¾Ëš~Œ±ƒvr„vhaj]CZZ[VfdXekTX]\`c]cx{‹™ª¤¤¡ ¡©¦ª±¹ª¦´£¢­¢£­¢§±Ÿ‰¦š”’‘Š’Žˆ‚“‰k•¢˜„…~‘ƒƒ“–¬‹••™Ž…’—§°¡  ¤¤¨ÈÍÏÇÁËÐÓÑÔÓÎÓÍÆÖÓÍÔØÖÖØÕ×ÕÉÔÚÍÉ×ÖÑÊ­ÄÃˉqnb__WRXR[OJGIIJ@;:;EBD<BD>HB?BB;;9<:GB46544<5687543250/2546745544<>=E?A62/-15;=081/254/-.;R017/532ED28>nb5=tM99@I<AD?A;PLFKYp€u}hsyr‚‰•”…‹–‰ŠˆŽ‡w„”™‹ˆˆ‹‰~ƒxs{}ƒ‡w€{‡‘—ƒnwpmuvx}s…|yl‡vto}v„uy{µŒ<AŠÆ¥~|ieVICecfchjdoy[_fhknin€ƒ‰‘‹Ÿ —˜Ÿ££¦²¤¤³ ¢¥ž¡© ¢±œ†ž’’’‹Ž‹†ƒ„~œ›Œ‚„…z”~‚©•£Œ’Š—’‹}—Šš‘«³˜š›§œ§½ÃƸ¶ÆÍÒÐÒÐËÒËÉÔÏÑÕÚ××ØÔÙØÍØÛÎÉÚÚÒÖ¿ÌÌ´vumc\YRUPYUEFJIEE=:79@AC:GE@ECADA;?;;7DC75655;0689443341014558744449@>DBC<33.6FTVOQJAJF?1*(.BT29254/7K75<`bA<svV87AH:?C><9QECJTlnopaqqs†|—‘‹~‡’‚‰†…Š‚‡|x…–—ˆƒ‡†‡z„yqz{„†uz…ŽzŒp|opzq|qƒ‡€nŽzuw}|‚u|‡ˆ°tX©Â¶Œ’pnb=^hrpqpnxw‚eioruxr{‹‡Ž”’›– –‡Œ“› ›ŸªŸ¡­œ¢š™Ÿ¥žŸ¬™‹šŒ‘’…}ˆ‡ƒ…‹Ž ™“ˆƒ‡~m™y„˜†ˆ“ŒŽ”Œ…{›ˆ“®ª”•—ž˜¦®µ¼¨­½ÆËÈÉËËÏÈÄÒÊÔÖØ×Ø×ÔÛ×ÓÙÛÖÏÛÚÑÖÈÕ̕xzhgZYORS]HBEII>A>=7:=?;>H=@AAADA>>:87DB755479.566435532323647553457EBDCEB56<FNSM[nfcnsk`V>,4LG865433BF4=W_hLux^8;?F<<B<:9D?CGRk_mdbfkv€ˆq‘›€y€Ž~ƒ‚‚…„||„—Ž‡‹~†‡€w‚yn{{†tz’ž¡vu‚tu}t€„oo’„t|…zv†{‰·Æ¤ÂÉ·•›xpeNec‚zw†¢‹yyw{ƒ|„vm”–”•—ƒ‰–š——¦œ˜ —Ÿ“’—£™«–‘‘‹’ƒŒ…ˆˆ…‘žœ™‰…‹…—{ˆˆŸ—‰Š‹‚|¡ˆ‹¼¡˜“—™œ¨¦¥®ž§µ¾ÀÀ¹ÇÉÍÎÅÍÊÑÖÕÔÙÕ×ÛÔ×ÙÚÛ×ÛÚÙØÎÛƅyxehc_RVVUMKDMC;==<9:<>9>A6>?@<?><9867CA6455=80665547745613854564557HH=DJE7925;H>;::7HP\ZRUXK9T>;95327I8=NYMHxxd5=>C=<@:6:>>@EQ_Yea][htzyl‰’wvzŠ|~€€}…z~‚‘‰„…z…ˆ{u}tn|}†~t’‘Ÿƒ’|†}xŽ}yŠŠn‚š€t˜…~‰…|~z©Ã »Œœ£œ}‰„}‰rŒŠ~s¦šœ™”…{‰„hGq¡¤Œ‹’…ˆ‹‘“•š“•‘—Œ•Ÿ”¡”’ŽŽ‹~Ž‹„ˆ’–šŸŸ‰Œ”‘‚‹¦™ˆ…Ž‚†„€¤†Š‹¸˜‘”–¡§ ž£®¶ºµ«¿ÅÊÐÈÇÌÏÓÒÒØÒÕ×À×ØÙÛØÚÚÙÙ×Ü·wwviidV_ZSONHDLB==>99::99<=6@>><=9:;;37D@8378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWN<MTHN?96333>C;[X>5YypZ<<A<=>8589?=DRSRX^UXfmmmi€ŽŠqrxŠ{{}|ˆz|{‹‡‚~uƒ†yszsm~„}w†› šž”’€‹‡˜‡€œ’n‡¨…z ‹|Žƒˆ„œ~š‘Š£¢Ÿ£®Ÿ‹‘‹…‹’†Wr­‹Ÿ¬œƒ˜›Ž[ƒ¢‘‚ŒŸ“•Œ†ˆŒ’“Œ”•”ŒŠˆ–›•–‘‹’”†€‹‰’ŠŠ–™£¢†“• ‹ŠˆŽœƒˆ€ƒ‡…¤…‹³˜œ’”—¡¡ž™’›§±¸¬¥¼ÁÇÍÇÆÏÌÏÌÏ×ÏÑÔ®ÖÕØÚÙÚÚ×ÖÙٞn{sfe[\WRVWC@ID>?>:48:;7:;:3;;?=>7;9:1:G=:27=@50677255?65;55858:57735HR7GOK994=EJB>1FCLA98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:<@;BQKKSYPTcbxlb~’ƒnmw‹xy~z}†|{v†„€sp…‚{vvut„ƒ…}~’¦£ž¥¢–‰”–‹Š¨—rŠ²ƒ¦‘„™“„™Œ¢– ™“‰š¡’¨¯Ÿ‘”ŽŽˆ•‹n·„šÄȲ¢¥›œ˜–‘²c¤ÍȕŽ†‡‰’“”Š…ŠŠ†–š›”“‡•˜„€‹™ˆª——¤£ˆ™ž–›‰‡——‹…Œ†¤ˆ“¨™—“–˜¡˜Ÿ™“›¢²´¥£¼Á¾ÇÅÅÉÈÉÂÊÓÌÍÔ¨ÒÑÖÖÖØÚÔÓÚ΁q~gb]]\NITYABGD;A=837;<:8=649:<:82?9929I:>67BC32:96264>=4;>6949;57944KQ<JQK9A7BGI@64JELF>;88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBcFv}|m~ˆxz~z‚‚ƒ~vv€‚|ln‹z|xx|„‡Š~Š£³§£ª³¡–§Ÿ¥£–•®¡ƒ¸•’²™Œ¡¡Œ¤›¯£¤˜§–§™¬¯¤—”–•‹˜™– ÀŽ£É¹«›£¦­˜‘›²……¨¢œ˜…‰‰Ž•Œ‹“ˆ†‡‰“˜•Œ‹”“†”˜†„‘œt‘˜²–—¤¡ˆœš“Š‘Š—›‰Š–Ž†}Œ˜ž‰œš™“˜—Ÿ” •ž› ±®¢¤·¾´ÅÇĽÃÿÆÍÊÉÒ¦ÎÍÓÒÐÖØÓÐغqxu\_T_UOHJNDBCE5>:77:?;<7=42669774=5;5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=88567=:JFDGN[\YJf`;H„‹z{n…†z|„x…~px|~}orz}|x†‹‰†„’§»¬¨²½¯¤­²³¨£¢°¬Ššµ¢¸¤•­¤—©­·¦¤£Ÿ™©—©£¯°©™˜œ”•‘— ˜š»»®Ê¡j¶¸«°”˜ž£«“—½£^ª²‚‰Š”‡‘|ŽŽ}ƒ†Ž””ˆ‡“–Œ•‹Œ—˜’œ™´—–«‹œ”’Ž‘’Œ™›Š‘ž‹‰•Ÿ¡”˜™œ’›˜ž”¡ ”œœ¥¯¨¡¤³¸«ÂÈĵº½»ÅÇÇÂÑ ÆÉÍÍÄ×ÖÑËÔ¡oyg[YS^PNEC><CAA8?875?F<<5<35355454B39:BM:B;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPdGb`bpJ@‹Šs†‡}‚ˆuƒŠ‚m}}|pw‡w‡{Œ†Œ™ªÂÀ¯½Æ»³³À¼³¬«³¶‹§²­­½ª›»¤¨­¹¸«¦¦¡¢££¨¯²±ªœ¤˜›——ž¢¦¥’¤º®©À¼­­²¹¦¤¨~ˆ†œ­½°‚ŒŒ‹ƒƒ‘z‡œˆ‡—‹•—”‘š—¨š±š‘¬œŽš’Ž•–—Ž‘ ‘‰”›£¬”–”œ“ ›˜ ¡”šž§¦¤¢¤°³§ÁÆï°º¶ÅÄ¿ͦÇÄÇüÕÑÍÄʇrr`ZY^ZLJBK@FG>A?B;:4>A<=5=6>333242A17@BN>G@CNCA=C=;86CC5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GE?CF\eG`igZ]\“ŒŒˆ{‡‹†ƒŒu†‘Šo~{q~z•z’””˜“•§³ÆÉ¿ÂÌÁùǼº¯«¹º—²¶º²À®¥À¤«¯»¼ª­«££ž§ª®´°ª› ª›¡›•Ÿ°´§‹£ºº¶Á¼¬¨œ²¥¤¨”…Ž©ÄĤ‚‹‡ˆ„†•”zƒ‘‘¡ŒŒ”‘Ž‰—Ÿ˜“™•˜¦ ®ŒªœŽ–’‘••Ž•‘¡”†—Ÿ ²ž”š”Ÿ¡˜¤Ÿš › ”˜ž¥£¦¦¤¯®¥¿Ä®¨·µÉþ¶Ï²Ä¿Ä¼³ÑÉȵswk[W[iQLHCLJKJAA=CD<5AD;:3=8B332262A05IEM>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBfZNe\fTcj™—ŠŒˆ’†‰y†”r€{x‡‚z¡–¨šš˜º½ÇÈÉÁÒÉÊÂ̼Á²­»¾§º¿¾¼Ä·¬Á©¬³»¾ª°©¤¥£«­³­¶µ Ÿ®ž¥¢˜£³½©›¨½Á£··°«“±¬«¬—‡š©§¥‘‚Œ“¥•‰vŠ‘z…’žŸ“”‹”£™—œ••£ž©Ÿ‘¥šŒ•–ˆ|•’’£š• ¢œµ¥ž—¤£¢¥ž¦˜ž•—›¤£¨§¢²¬¨¼À沈·ÌÀ¹¯Ä³»¾Â¸­ÂÃÂÀ˜lx`WVZZJKMJFDDHBBADL:4DH9;4<7E.12352B26SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQG7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>jH_XaZddVžŽ—Žž’‰Š‰ “„x…•ˆŠ€–¡™®¦£˜Â¾ÇÃÇÅÓÍÎÍË»Á·°¹¼³¼Ë¼ÃÁµ¶»­³¿¹¼®¯¨ ¨§¶­­©²·šž¬¢§¡«·¸©¤°¿Ä±¾¹³§ªµ³­®—–¥¬¨ ‘Ž’±Å§•Ž}‘”}ˆ‘™ª™˜““’•“¥“™”¡£¢œ˜Ÿ˜‹ŒžˆZ–—’–¤™e˜£ž²¤–¡–¬¬ª§›ž¦—˜–˜• £¨¥Ÿ¶«©¹»Ã´¥³µËÀ¸ª¶¬²º¸®¨·º½¸‚kmYVTTMEJSNK?AHEDHGG95FM;>7=@J.32025B55PVN<LFKRLOHGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|gV;=@BFBqFiIRebLF¥”œ–¡—©–‘ƒ‡¦“ˆ‚‡‚œƒƒ•“Žš¢Ÿ¯¾®¡Æ¼ÅÄÆÆÎÎÎÒʾ»¶±º»»¾Ï¶Ä½¸¸·²±µ³¸³«¦œ««¹ª¨§¯¯—£®¤§¤¤µÀ°«¬´¿ÃºÀº³§¹µ¸³¯–¥­®®¥‹“•¡tÁš}–™…–šŒ±•›š•’“™™¥£•Ÿ›–š©œ¡ ™ŠŒ–`J–œš•š¥–T–°Ÿ®œŸ¤”¯®«¥š ¥”“˜˜ŽœŸ¦¢™´©ª³¼»»ª°²Ç¿¹¦¬«­±±£¡±²´¤ole[YNOKEOPPQ;GJHGICC>:KU?A:=EM07544:B34NWO<JKOUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@BAF3>58JKCA=C;4EA:A?>H@5*B52,>c]g:35tde@R7&#3}hW;:BC@=QEWSsbWFHª—™ ¢¨¯™‘—‡‹§–Ž‰’…Ÿ‡„—Ž¡š£¤µÈ´©ÆºÂÃÇÊÈÇÌÍƾ»³®¹¸ÀÁ̵ǺÁ¸µº°¯¯³´¦£›ª´´©©¦­¬š¤­¥¤¨¬º¿¨«¶·¾Á¿¾¹³²Ä²¹½¬£®µ¬¹¦ˆ›˜¦›v¿Ÿ„™Ž“™š‹¯—¡œ›–•›Ÿ¡©Ÿ§ ™šª™¡§ž˜‘ƒnv’¢š•¢ž®²¢ª”¨ª—ª­££Ÿ¥¨’’™œˆ”œ¢ž—±§©«º¶½³²­¾¹· £§¨¥§œ›¬©©Œbd_^QJLFHNIUL=MDNJKBCD<QU=AABDO18=77?B75UXN?HNQYSPQUKQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW;:=..R`MUHe^HE«•œ¡Ÿº¯™”Ÿ‹“«›‘’“‰«‡¢ŸŒ£­”££¶Æ½´ÁºÂÁÆÈÅÂÍÈÁ½¹²¯¸´ÀÂʵűÁ¼´ºª¨­¬°¢£˜ª´»¥¨¦«ª¨¯§£ªª¾¼§­¼´¸½Ç¼·µ·Á±¾À´©µ·«¿¥¢˜‘¢ ¼Ÿ‰š ™—žž·Ÿ©œ¥¢›œ¡š¨¥³¡›¥œ¨ªž™•”›Š–‰Œ¤¢”¢ž ´¯¥¤“¯«™«ª¤£¨‘••Ÿƒžž›•©¤¡¡´´ºµ­¨µ²³žœ¢¥š—•˜ª¡žv^[_]JHEFMQIMEFGBRLJBEG@VRDH=AGQ1;B7:BF79\YKALPTUSMWRNUJD@JJNO9C?5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-1:g\FCCœpbGE§—¤ŸžÃ­›—¥˜™©œ–ššª–•§¦•­­™¡«¶Ä»¾·ÀÂÀÇľÍÆ»½¹²¯¸³¿Âȵ¿¯»¶¸¶¦¤ª«­  š«ªÄ¢¤¨«¦ž«¯¬¡¨¨¿·¦­¾±¸¶Ç¶µ¹¸¿²¿Á·´³´¯¾£—£–”œ”® ‘¢¢¥££Ÿ½¤©¨« ›¦Ÿ½¢˜£ž¢©«¡–•ž“ž‡„“ž¤ µ¬¥›•±§™®¦ž™©Ÿ˜”žƒ š›“¥¤š˜«±µ±ª¥ª­¬œ˜  ’Ž–¨ž”gbX`]NHGJNKHEDIA>PH@<GIH[ROK=HOU4BF9>HG5Ca[KCNRUWVQXTRUH@8QQPM:G@4CHQSIC;C>GVKC@O>K<06;GF>;FA56?9:?9;15D0-,/Mv\4KZ5,MnW<-=)#zbQ5CKQ:nRF<KxebVL¢š£œžÅ¬¡Ÿ¬ž® “£Ÿ–¥Ÿ¦©«—¶±£ª³µÄĽ¿¶¿Â»È¾Êȶ¸µµ°³³·Áƶ¾°¸´¸µŸ¦¬ª«ž¥¤Á¤Ÿ©­Ÿ¤©¬¯¢¦§½µ¥±¼¹·¶Ã²³·¹¿²ÄÀ¸¸®³µµ£¥•’”¡® ™¢©¨«£šÂ­©ž¬­››ž™¦¡½¡¤˜««¬¦¡™šŸ’ž‰ŽW–Ÿ¦¡ ¸ª¦“˜µ£Ÿ± Ÿš®–žŽ˜”ŽŸ—•Ž¢¤•¦®²«©¡¢¥¥••˜‹‘“¤ž‰`dYc`KHJJNEEAFJ>=JB99JKN]QQI=LV\9FI=DMI8Hb\LCLPSYYVWOZ^IA=WQIK?H?5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+w`S6SZkWrHE6=ue\KNžŸ¡™žÃ¨¥¢´¢œ²¨“«¤ £Ÿ­©¬»°¨¬µ±ÈÅÁ³ÂüÆüÄʼ¯°¶­°´¯¿Ä´¹±°¹´¬™¨°©©š¥¡§Â¬›¬°œ©£­°©¤§½¶¦·»½¯·Ã­³²ÂÀ²Ç³º·¬´¶®ª¢¦–••¤¬¢ŸŸš¨«°¯¯»²¦ ©¨™™˜“¢¤¸ ¡¤“¯¯¬¥§ž’¡ž”ž•š¢ž§³¦¦Œ˜³›£®š›­ž“•“™‘¡–Ÿ¡“‹¦¬°¥¦¡œ ž’’š“…‹’œž`eZgeJILJRBC@IG;;G?99OMU^RSJ>O^]=HPBLLI9Mc\LELRTY[SUO\bHA?ZQAHAKB7FELKM?;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<v]^?[T^eq@8;H–weA4Ÿ£Ÿœ Ã¨¤ª²¡£´ª•³¬§¢¤²¬®©»²¬°´´ÆÀÄõ¿Ä½ÉĵÀÈÁ´«µ¨¯¸¬¿Ã³·®¬¶¹¥™«±«ª—Ÿ¦—­»´›§°›­Ÿ­´²§ª¹²¨º³·²¹Àª·±Ã½´Æ§¾¯­·µ©¨«¡——’¦¥¢¢˜˜¥¯¸®²µ¶ Ÿ¨¤™••“¤ ·¢¤¥–¯±²§ª¦¡ž›šš–—¨ŸŸ˜¡ž¯²¢¦Œ—®˜¤ª—™ž¤š“—™„•ž”Œœž”‹©©ª¡§ ™ž•ŒŽ™…•‰”Ÿxch\jjMPMNT=CANC::I?77RO]^RVQAW`\BJSHVKH:Td\NFON[W[RPQX]GAB[PBG>NC9HGHOP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1[bZ33806p[bH05IphVCWFŒyfC;¤£¡¦¿¦¨¯¯¡©´«¹°«£ª´¶±°¹·°·¸¸Ä½Ãǽ¼ÄÁÆÀ¸ÀÆÀº©¶¤¬»¬À··©¬±º¢•­°­²–¥§‘ª¹© ¦°ª ¯´³ª©¶¶­»¬³³º·¬¸°Ãº¾¿¦Ã«°·®©««§ž˜™«¢¢ ‘˜¡±¯³«°¹šœ© ™–’—¦¡·©¥£¢°±´«²¨«Ÿ›  ›¥œ¡—£³°šŸ“¥šŸ¨š”¢”—‰“—’•–œ“ˆ›™”Ž¨¨¦Ÿ£›—›“‡Ž™‹}Œ–…›jhl`lnWPQZTACET@;;HA7:XPd^PVWDY^]MLRN^KJ>Zc^NHPN[UYPKTWZI?DXPDF?N@=IGGQPB=DFBM?:1D?77547?=95E4+75/251.-.,1=*'+=\p=>1.0dZd@1647gY`F(?8l}h[V;‰{cC=§Ÿœ¢©½¡«°«£±¸ª¥µ³¬ ­µ¼®³¸¼º½¶¶À¿ÈĹÄÁ¿¿¸Ä½À·¯¶§«·±»¾¿´¨®±¶ž—«­¨­—§¨Ž§»Ÿ¤¬³ž«¢°°³«©µ´µ½­¯±µ¬°´±ÁºÅ·«¼¯±¸¬­ª£±¦ž¤©Ÿ¤—™Ÿ³ª³ªª³š§›š•Ž ¦¤´®§¡¬­®±§³­±ª¤œŸ¨£ž•¡™›¨µ©—™‘’ž™Ÿª–—„”—Šœ˜›“Š–—š—¦¥¢ –•—“€”…{Ž’ƒŒ–elrgoq^FYfVDCMXDZ9HB6>]Qh\NY]G[^]NMRXdJJC\b_PLMNXWXPJVVWL=EUJEDAM@AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,,%2+*5K1/'__aU150=`V^8)C3YT\gK6ŒzfL@¤š ¤¬¶¤­©¥®®¶ª¯µº§¦°·Å·±¶¾Á´´ºÅ¾ÌŹÂÀ¹¾¹Ã·À¹²´«©º¶º¹½´©­°µ˜˜§«ª«›««Ž«½«®±£« °­³®­¶²¹·ª®®²¨µ¯³»½Ê²ª¶µ±´¯®§¡³ ›¨­ ¥••šš²£­ ¦¯—¡¤šš’Ž¢¥§²©¡¦²¬ª¶¥®±µ¯¤™­§š˜Ÿ™™«·¢—“Ž—œ¡—–“«žš’’—Œœ™•‰”’ž™¥¢¡ ˜–‘“•z‹…{ŒŠƒ‹’jmxmu{aE`jYIHYZ={JFD6AbTi[M\`J[]ZRSRbaLKE_``QLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`U`/5(C_Q\.*B/JGP[H3cYTKD™— ±¨±ª­¦¤¯®µ©·´¹¤¬³·Êº´ºº¿¾´³·ÃÀÌȼü¶½¿¿·¿¼±½­§º¸·¶Á¶ª¬±·”—¦®«§£°ª”¯»¤¬±²§¨£±´°±°µ±¸²©®«²§·¯µ´ÃŶ©µ¶¬°­©¨£¶  §± ¤”›™•±ž§œ ªŽ©£ž›–˜¦¥¥·§¢±´¬§²§­°¶¬¤™ ¬¨›œ›”©¸œ”ŽŽŠ˜œ¢——¥Ÿ”‚‘•œ›—•”‡–—š§œ£ ’–•v„‡{…„Œ‹mpwt{~\Kel\KNc\>b{GI8GgWf\M^bMXYWTXTi]OOHa]_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANHf27'GbLV%-B.=ELQ<3rkJCC™¥®¥­®«§¤°²³ª·±· «µ¹É¸®À»Ã·²±µÂÂÎÅÀÁ½´¼¿¿º¾¼²Ä§©¸°¶¶¿¼®ª³²œ §°­¦¥¯¥²µ¬«±±­©¨´º¬´²µ¬´¬ª¬¨¬©¸­±°Ç¿¸¥º°©­­¥¨­°¦¤¤¯£©œžœ›¯™££¢£‘¬ž£  ¢ª¥¦¹¥¬µµ¤ª«¨¬¯¶®££¨ª› šš’¤³™Ž‰‡¢ ”“œŸ“‘„’’š˜”“‡—’•™§›ŸžŒ’‘Žv~…}||‡‰ˆpsq}|}\Sdn^NYf\FD–[G;NmXb[L_bNVWVWTXg^QRLcZ[TKGOTSNGIVS\N;P^IBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3Bc;6*HeHJ+:I?3BIS,>k<GHœª«¢©±¤©¥³´²´µ²²¡«­½Ìº®À»Ç±´¬´ÂÂÑÅƾÀ²½À¼¿·»Ä§¬·¬³¸»¿¯ª±­ £§­ª¨¤°£ª±ª¯¬°¯°¯«³»¦¶±²©²©«¦¥£­º¬ª±Â¹µ¬º¨¨¨­ª¨±¥©¤¢®ª¨¢Ÿœ£¬•¥ž˜ž™¬¢§©¢¬¦£­¬¸±² ©¢ «¯±¬Ÿ§§©™£˜™ §˜†„ŽŠ‹žŸŽ‹Œ•›Ž…†”Ÿœ•—”†–““—¤›œœ‹’‰~~‡…|w~‡…†trqˆuk_Y`ncQsq\K;„|F>WtX`ZNc\NUVUWQ\b^SONhXWWKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*35>10485(5/*,.30;),,'%234$,2-860)(1<]J0.JgDF8<B05EKX1@”Z>LE•˜­¨¡ª³œªª°µ­¸µ®«¥ªª½É¼±½·Â¯±¬³ÄÃÎÎþ¿³ÀÂúÀ³Èë®·­²¸¿¾²­­«¤§©°©§¨±¦´®ª°®­±°´­´»¤¸³¬¬®§« ¢ž¯·ªª­º¶¥¶µ£ª§¬«ª­¡¨¦¦±²¤¦¦¡¡¬–ª¡•š ¦ž¤¢ª¥­¢Ÿ§±·­®£¥¢›ª«­©œ¡¥¤¤˜ š•˜œ“‚ˆ…œŸ‹Š‹˜Š‚‹—£š‘š‹“’‘“¢™›™ŠŽ‹Š|†€ƒzt€„}sv‹£‡xj^`nfWe‡cN?g“LEbyWbXReTMVUUTO\]aUKMiWUWIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*49?./463)4+*,+.#4.-+&(+79*&6+<-2,&06WZ.0JgAA<<C+:JO^4D†>HFD—’°¥£ª±˜«ª­¶«¶±«¥¬ª©¼ÀÀ¸¸³»µ¥²°ÄÉËÑ¿Á»¸¿¿Á¹Á¹ÀÄ­±µ±³º¿½²°®­««¨¶ª¦­¯ª¹¯¨±±¯²­¶ª··¦´·«¬¤©ªœ£ž³³¨¨¤´´ ¶­ ª¨«¨«§ ««¨¹¶©ªªª¢© ¬œ’©¡ ¤£¦£ªžœ§µ®¨¦ª¢£˜¥¦§ªœ¢¤£Ÿ™˜ŸŽ˜~‡Œ†„ž†ƒŠ‰Œ‚…”¢™Œ™‘‘’Ÿ–˜–‹Šƒt†ytƒzw~€‡oqggpx\`sˆkO^™VHmxUdVRbOMUTUPOX[bUHPiTVSGPYUI>IHOQPxLMV=<KD?@A<@CUC9AK=5;E13;97*4:=+-341*8**+*,))(/*&)%3;,$2)2021%/2Qb02?f=NX?C,>LT_/Jj6OD;–Ž°¡¦«®š¬¥­¯³µ¯«¥°ª©º¾¼À°®¸­¡¶¯ÉÇÈÐÀ¾¼º¼Â½ºÃÀ¾¿®±²±µ¼ºÁ±±²«³¨¤µ©¥­³³¹°£­¶±°³º«¹¯©­¶¬ªž©¬Ÿ¢ µ­§¡Ÿ¯²¢´ªž¨§ª£ª¡¢¬­¨½¯¬®­¢¨¨ ¬™°¡˜¢ §§ž¨›™ª°©£Ÿ­¢¡“¢¢£§˜š©¥˜—™ŽŠ‡”‡}†„„¤–„‚Š†Œƒƒ“ –‡œ“‘œ”—ŽŠ†…xt|uxy€ztsyh†£ui^ektgˆ‹}SXp^JxsSdSQ^MMRYfNLVYdXFSiRQ?BNQaQ:IHLSIqQLS;<I?;<=;@@W<<?H73CB15:93-5::)-31--6)(+-,42#2)',%.;.&1.0-14%,0Lg:38_=ad?F1CP[[*HM9UA4‘² ¤¦¬¤§¤¬§´²±ª¤±¨ª¸¾Á¼¯§¹ª¦®°ÉÇÈÑü¿¾¸¾¿¼É»À¸°¯´±º»·À²³»¬¸¬¢´§§¬²¶¹³§¨¼µ®¶½°½¦¬¬µ«­œ©¯£Ÿ¤«ª§œžª²¤³¨šª§©£©£©§©½«´¯®©¤ ®œ›³£•¤œ¥¥Ÿ¤›š©«¥ž›ª¡›’›¡¤˜—©¨’˜š“Š‚…~Ž‚ˆž…~}‹†„’š“…“¡Œ”’‹‘š‘•†‰~€r{y}|hw|ztpp|g„x„ˆdagcq…zmfx]^VBWzmTaPRXKKNqu]HZ[gYEUfPD>JNDCA9HGKS?jbJQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11&/>KH0%90%,,09/,,+6'17#-0GjI14X=fcAJ7GS`U*=:DW>*”±™Ÿ ©¥¥¡«¥·²²¦©±§¬¸Á½µ°£¹­¨¨±ÃÉÉÍÁ¶½¿µ·¿¹È¶Ãµ³±µ±½·¹½µ­¹µ¾­¡³§ª«°µ¸´«Ÿ½¼©³À³» ¯³µ©«ž­°£œ¤¨ª£žœ¤°¦° Ÿ«©§¢ª›¤¨ ­»§®°® «£¤®žž­¦—Ÿ›¡£œŸœš£ª£šš¤¤––”Ÿ¡–›—¦«‹ž‘‘‹‚Š€Ž€{š•ˆ{~‹…Ž‹Šƒ‘—†”£‰’’‡™“€ˆ|yl}vxxc{{qpprwgsjƒgdg`msŽmaip`pA\xlU^OQQJJMTYWM]^lWDX`O^PHMDF;7HEKO<rhKK9AE;;==;;=J49B<3;G<4?18-78;2(09/,5..=-*K>*49&'.34.0+/3&,:$41BhY13S=e_DL6KVdO);2OX=#“™¬™Ÿ˜§¤£Ÿ¨¤¸¯®£¯°ª«¸Âº³­Ÿ¸¯«¨´ºÈËÈ¿·Â¾¯´½·Ä¶Ã±®¹±³À´º½·©¹¸½«¤´¨©ª°®¹±ª›»½¤°Àµµ¡®¶µ¦¦§±³ ž¤¦§¡¥™ž¬¨©ž ª®§ ¦˜£¨Ÿ°¸Ÿ£±® «¡¬¤œ¦§©šš›Ÿ£•šž©¦—› ¨’˜“˜ž“™–¡©™‰Ž†}‡~‚Ž}|¡Œˆx‚‹„‰‹‹…‡’™Ž‰•žˆ‘•‚‹—Œ‘|…{sp}qst`yxinppnh}qczliec_e…_ZskrLL~hXZMPLJHPRPIN\_nSDWZRgOHLEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23/:;83&2<0,85B*)-C*,4;NN@;73-.+-6**<%53=fd24M?e]FO=RZgH*>/XW5(—¦™–­  ¡¤¡·«±¤³´ª¨¹Äµ³®Ÿ·¬®­°µÆÈÀ·¿Á¹°´¼·¿»¾¯«½¯´¿°¼Â¸©»º·§¨µ¨¨«°¬³°§š¾·¥­¼¶°ž°·°¨¥§¯±› ¤ ¤¤¡–›¯¦¡ž¢§¯¡ ¢“¤¤¢·¯¡¦±ªž¬£¯˜œª¥©ž˜šž¥“›š¦ªšœœ¥–•—”œŽ“—£¨¡ˆ‹…z„~„ŠzŽ—Š†x†ƒˆ‹…“—ŒŽ–˜Š–~†—‹y€zprwoot_ywdllkih‚merjkdh[bs_ZlviZH}][XOOJHHRUF2:_^lPCWVYeMHJEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<#8R=*113>D5,-'42+;+139cl84GAf[HTCT]hE.;1_S,2–£¡—•œ©¥¡£¡·ª¯ º¹¦¬½Ä³°¯¢´¯¬®¯´Äļ³¿º·°³¹¸º¸º®­¿³´¸¯¿Á¸¬½º´¦¢³«¨©³«®±£œÁ¶¦©¶µªž²»©¦¦¨°¬™¢§œ¤¦”˜¡²¥™ž¤©©œ¢ “¥Ÿ¤¹¨¤§­¦ž¥¡¨“Ÿ©¡¡ ™› ’›œ— ¢«››™¡•’”–š““£§¤ˆŠŽ…y„|„…|œ‰Š†x€ƒ‡‡‡‘…•’’Œ•”Ž”{ƒ—ŽŠw~{ltrllsaxuhgigen„ghhdfhj_gbifZezcaRsT[[SLIGIOS@!+j^jLCVU^`KHGEC.:B<F<6KPD8:D357==895?:;4>8@K=>93)8><:9*6@3.E4(+,>0-N?.+-7,1195,&.5-80576`tB3CDg[KWGU`hB378bN'2ž¤£’Ž¤¦œžžž¤µ¬§ªº·¨¬ÃÀ·°¬¢´­§¯¯·ÀÀ½±Á·±®±¶¶¸·µ¬ª¼³¯²±½À·®»»±¥Ÿ¶¬¦¥´©«®  Ã«©¦°³«¬´º¨ªª±¦˜ªž§¤‘™¦­¢™¤ª¡›¢— œ§¶¥¯ª® ¡¡• ¦Ÿ¡ ™›šœ’šž•¦ž­£˜—ž•””—Œ˜š§Ÿ‘ˆŠŠ‡x…w‚‚‚œ‡‹‚‰{~„‡†„„••‘‘‘’{ƒ•†s~}fxokjlguskbgdctbdefeijchpY^X]ldaMhWZ`VIGHKMRX?9`liGBUS\[HHFEA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A=-5B37=+*,0A*JK./*+3722(57$+7.72685\yN2>HiZLZJVbfA:3@dG%5›¤ ‘Œ® ™˜ –¥´±¢±¾·¡±Æ»¹°±¢¶««®©¸½¼»­À²¯®­¶¯³¸³§«¹°®®´¶»¶¯¸½¬¦žµ« ¡°¥«¯Ÿ¥Ã¡³¥¯±¯·­µ­¯¬®£™œ§ª¥Ÿ•›¨¥Ÿ™¤£©œšŸœ”›¬°¥¹§­¢¡ššž™ž£š¥–ž˜›”š¡’¨•¬©›”œœ’Œ•™Ž””˜¨¦Š‰Ž{‚t‚Š˜…‡|‰ˆ„„‰Œˆ’„”œ’’‘–Ž€‚ofymhkjgqrk\hdbr`dgjmlgjhfl\lmuqaTbhceYIFLMOXQPUaeT@VSYTFGFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24:6#3*)6.55465Z|]19Kj[M[KXdd@A1IdB'4“¢›Ž±›“¡š©²¯Ÿ¸À¶ ´Á»½¹±¥¶¯©®¥·¹·¸¬»¯­ª«·ª´¸­¥³µ±®©±¶¶±²µº§©Ÿ¶©žŸª¢ª­œªÁ™®¥¯°¶µ¬¬ž±­¯ª£›œ£¬¨œ•œ§¤š©£¥•š ‘›£«ª©ºŸ¦¤ ˜ššž¡k¢•˜œq‚–œ¤€v‘«¨ž–– ‘‰—™€—‹Ÿx…“Œƒmi~wƒpl†Š†}„Š†o]d`g„—†k‹”’uw‹„~ƒf‡€huifW\itnNPjdfq‚f^dfnli^]_‰…‡hOKD8ETg^JGPPUUKGS`oteE[QUPFGFC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,,08>G701.*.*/668,#1'214:276Xl16Ok[N\K[fb>G1Ob<+/¤™‡•±›œ“ ›ª­«£½Å¯©·Â¸½½­§¶°¦«¤·´²³±¹­ª§¬´¦°µ£§·¶µ¨§¬¶³®´­³¢©Ÿ´«ž¢¥œ§¨š®½•§¦¯³·­­¤¨®ª«¦¡žœ ¨§œ—¡¦¦œ›§§’ž ™ž§ª£´¯£¢£œ–˜˜—£ˆ¡’š‡¡‡”ž¡¥§«ž““œ“ˆ„rxŒŽƒ‡ vˆŒi—ˆf}sx oˆ‡ƒ~Œ|¡ Ÿ™{ˆžtˆŽv›Šl‡ƒmheczlqbT†mcmi˜qXjpn†W^i[kj[ˆpmyr‡i‡„Z^FN>F^MFRVWQQRWTg^LYKRRPEGG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82*/1<I9/01.*/(-4583%&2115>1<8Xƒu25Rk[N\L\g_=K1V`7/(Œ¦—„¬™™Ÿ«ª¨ª¿Ã¯²¹¼·À¿ª¤·±ª¬¦³µ®¯³¶«©¥±­¥µ³œ¬µ¶´¥§¨³±­²¨¯žª¡³©Ÿ¤£š¢£¯¶•¤¦¦¶¼¦¬§©ª¬§¦¢ ™ §¤™™¦£¤™œ¤©–“¢œ”“¢¥¦ ¶¤£ £˜•“˜”œˆ®˜”‰©‹—£œ…±€¤­ž”šž•y‚Ô¨‡”À›Çyx±¥·—d€Àœ¿y„„yƒ|‘Êq–¼œÅ{r¶§º{l—±«°xhkX±®oei¼’¼nhzmqØ~Sjc¶²~€q”uš¡ªWOWaOVNFT[XQPS‹\W[P@\EQNDFI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22BE/.32.+/)-/186- /416A1=:Wƒw21Tk\O[M^g\>L1[\41!Ž¥“§ªŸ—¥­²©±Â½²µ¿µ·¾Â«¦´­­©¨¯´ª¯¶³¨§¦µ¥§¸®œ²±µª¥¤§²®­±¦ªž§¤²¤¡¡Ÿ—œ  °­•ž£Ÿ´¹¢©¨¡­®¤¢ž›š¢© ˜›¨¡Ÿ˜ž§§‘œ§›”¡¦¢ °£žŸ£––’˜’™…°kjŠª~g„–‡­eqž•š¦•q®¡¤~wº|k¡v±_j´[¥€eœ‘`fzfjxj©e¾rg¦Œv±j|±xt’“cmm§m[„ Eig‡–Euœ`}f{£§‚Y_‹«i€”xzj§7J¯[WTlcZKOW_\WV;NˆOWV/ITSJCEF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3..53/+/(.0.:6/'$203B/=;U‚v2-Vj\OYL_gY:M5_Y31’¡•‚¬§¥Ÿ£¤ª±·­´½¾°·Å²¸ºÂ§¨°¬¯©©±®¤°º¯¤¤®³£©¹©ž³³°£¥ ª­°¬¯¦¨Ÿ£¢±œ£œ˜•˜œ®§—›¡Ÿ´²¡ª›¡­­ žš— ¢ª™ž¤¡œš¡§¤£š— Ÿ«Ÿ¥¦ šŸ¡••‘–‘š…µ›µx…©™µ™w‡³›·“–—©•~k¦z…‡’”’w«gj±[¬{Ž‡”tˆpŽ†€ˆ—xƒ‚‹—Œƒ …°vwŸqkjl|‹N¤XHcc™~ch¦`yruR“†^P©mcq}†€b.Q¢n[Tkg`LK\dX\ZB>°xWXA#MhFCDA@A19>88:84;:9<9:A:E::;6:CB8=?KNH:5:AFB@AD<FD;0201;F,0.840,.(/3,>831/2-D1<<S}n3+Xj\OXM_fW7J9aU50–Ÿ”ˆ³¦¦¢®©§³¬ª»¶Â°¼Â­¸·Áª¬­®¯¦®²©¡¯»ª¡§µ­£«µ¤¦³³§£¡§ª²¨°¨¥ž Ÿ°— š••—™Ÿ®£šš¤¨´®¡©©¨©›ž•˜ ¥©šŸ£Ÿœ ¢¥£•›ž˜š¢ªœ¥š››¢ –“‘““ƒÕ“™¹p°Â~Ɔ|֔›»|š–¥›Œ¤z†¢¥‚z¬yU¯{‰~Ÿj¹Z¹w†ƒ}¦‚“|˜zªy{±mŽ„t»…o”O¯§ÅŠQ zc`ªbsr†l—‡_Sµ´È†€‰|c¤3Bv]QihdP@XfZdaJHMlKZSOYfZCC?E?0<<59;74<;8=:<C:F:;>6:@C;6@OLH<9;DHCBCD<EF81211DB./0483+-).323971#%5*>3==Qwj6*Yi[K\P_fT7G:aP72%œ¡“˜±¨¨¥³ª¥´¨¥¼·Á°ºÀ±µµ¼³¶§±±£±³¦Ÿ¯¶¨›¨º®¢¯± ³´° £žž§©°©´©¥œž«˜™˜——–—¢«žš—¨­°¨£ŸŽ¬¢§–ž—œ¡¦¢˜¢¡¢¡š¢¢§›ž ž•™š¦ œ§•››Ÿ ˜’•‘ˆ²nhµq«ˆpŽ¦r´sr¶{š˜¤›¢~Ÿ¤~°vƒ‘ÒÑu[®|…¤o›ª¦k†…}­}—™{±s“Žx³e–t…žnžf”RȋZÂ\Ÿyb_­`vs†b—ˆ^Yʝo¿uMKµSUÆdTQjceXAOj_liPUFI9=WR[WXHC?J<2?;5=<46>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>II:1746@>/.24252-).26,742&60;5:=Pqh9'Wi\BNT_eP5G=aM62.¢‘¤¯¬¤ª»­¦´¥¨¶»¼²»¿·¶´»»³¥´´¢²²£ ¬¯¤˜¦º®¤±°œ´¸© ¥¡ª¥±¨¬ª¥šš©Ÿ–•˜™““£© —“¦«°¥¢–’¬Ÿ¥’”¡œ¤§ •›¦§¢š£Ÿ­š žž–›¢žœ¥”œ•™¢ž•˜–’›…¬{w¨v£‹‡©o­Šƒ¨ƒ™™¢Š’™‹¢~’—‡®…‚³\r³R®}‚‚¤q×}w„~†™šw¯†Š‘œ‡w´ašeš‚•l’Z°XKšu˜yf`­^ww‡g˜ˆj]¯w•žxl5yÈ®²_BTo]h`EOk_qmVUM/eciSYQ;AD@L:5?91><16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK96<46:>/04333.2..18*.32%!03767=Pke>&Vg\@=V_cN6GC`I:77Ÿ” ¸°˜³Á­¨²§ª²º¸´¸¿º¸³¶½µ¥¸´ µ­Ÿ ©«Ÿ•§¶¬¨°±«­´¤›©ŸŸ¨¡µ§¦ª£™ž•¥¢””œ™“–£¦›“§¬¯¥¡•˜©Ÿ¢‘¢š©¦¡•š¦©ž¤ž¬  ”ž›ž ˜˜›•—¡ ”˜‘§†©}}¥y¡ƒªp­Œ‚§†– ¡Š——ˆ£‡”ª|€‹yo±Z¨ƒ‚ˆ ytØv‡t§Ž›’¤|–Ÿ„{²^œd }‚”l’\«[Z“‘hgªcr{k˜‡q]¬Z‰ ŽkneOJC¡\ZMt]cfMZa_st_JU5Jš’YHE=HFAL35A8.;>05A78@<6=<F?:<6?=B7.HVJE@H6KIN@IK@EN::@4.;>002154+*05/7,&21($$6671<PeeA&Uf[?1U_bL7FI_C1=7¡œ™™¾¬˜´Â®«­©¦´°¸±µ¿ºº³±·¼©»µ ±¥ž¥§§ž“ª±©¯ªµ¬ª®¡˜¡ ¦¤¤¹¢£«¡—›‘¢ •”ž›”™  Œ©°¯¦—š§¦Ÿ’¤˜¨«¨”—ª¨ŸŸ £­£ ¡”¡˜Ÿ ’œ—œ•¡•—«›®mr´t©ŒwŠ¦s´yt³€’¤£’œŒ‰¤‡Žu¸oŒ{‹¢kk¶Z¡†e——i ¢§m”r´t“˜²j†’ˆ­ku³af¢n†’j—\­`M¡|‡‘Rs£ly~n˜†o\¯V<œwfTon.[§ObRkeblZb\`q|cSYP>>mo3BB@?L9!7@6.;@37C58??3;<CDBJFMIF62JTKEBJ6IJP?HOCFP=<E50;<000/75,+,426/#00,,289/9N`eD'UdY>/U_aL5FM^91A8¥š›»¢œ²À®­««§·©¸¯µÀµ¼±¯¹¸«Á·ª«¡œ§¤¢’«ª§µ£²¨®ª¡—œ¨ ¤«¹£­œ–™¥£–¡›™Ÿ‘“•«¶¯§™”›¬©—Œ“¦š¥­¤’—«³¤ ž¨«°™¡¢˜¢— ›–›—¡“œ©œ”‘«™‡Ô’š»t±Ä€Ã†}Ֆœ¸xˆ‘—Œ—‰Œ§‡y¢¶u}wv‚š²`ƒºyÀ|u¸bµŒ‡©}–¬©q{u¼ˆ§ ia¦Ž¯¡~Œt‡«}¾ns¼t²ƒux€Šmšˆpm¤t½]w}[ay¼jZV[iy^i`dfbmxoY[YCA@r?CF+5H"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-6@9¦™ž¢¼¢—±Â°­©ª¬±§¸¯¶Ä±º²®»°®Á²¬¥£ž¤¡œ›ª¤ª²¤µ§­¤Ÿ–šª™¦¬¹£®™•¡¦ “œ£ž˜žš–’¯¹°«•—£§§”‘–¥¤­ž‘¡¨« œŸ©¤²ž¢¤Ž¦¡”¡™œ—–¤˜° ’•ªž…™µ€‘‘¸•x‚“›µwnlnsny„Ž‰ržÁ»¼™z²¨p€t‘¹ƒ|††‹‡{Š†—|¤»¹½œuy³£tv—ut°u˜žf†i¶trpw¶Œ^y}‰gƒymyb‹¬pu…X[§jDdZTf_c]bPgfqmuBMPLD;ZL?J3<0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITBKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7KT_G'SbW8*O]]=+;VV'=:<¦ ¡¿¥–³Â´¬ª§¬«©»®°Æ¯µ´¯¸§µ¸­ª£¢¦Ÿ ™“¬¥­ª¦µ¨¨Ÿ›– £ž¬¤¾¦¡ª˜•œ‘¢›’¡¨¡“ž—’˜”²µ¶­˜¤¤¢‹’’¦œ¥«œ–©¥¦›¢©§¦£¨ ‘¬ž—£ž——˜ž°©”œ§¢Žj~iœ§x‰s~šŽuze‡{½¾Àºn‘‚q”…_rjZ]š‰ad‡Ž•k`•cm›vb”kš•”e^`cq›‰hrŒ}†”fj~qsy}|b[wthP\nƒ|{ŠjXly‚rIJo…pMtMEW\faL[Wfc^OZmvjrRODEN;HI<M?2,2A?8/5?C<9;@;=C>RVVWYZ[[\]`aaa`\UG5DFUEJOHFPIIH;8=51:.0;:.0-76=5&"/*2,%;8-7IR_I'S_V4)P^L(3>[O'?2>¨Ÿ¨¡Á£š´º¶£¬¥®§¨µ²¬È¬°³¬µ£¾±²¦ £©£›š™¬§®¤¥µª¤›˜•¢›¦­©¿¨©¦–”›• š“˜¥©¨‘ž˜œ°²¿¬›§§¡‰“‘ª›¨¤œ›¬ £š›£§¬¢Ÿª¡™¯š•¦Ÿ–”Ÿ—°¥™¢¨™œ‘žœ£¤™§£šœššš–‚hn|qv—”‘„Š´©…˜•ŽŠŒ˜—‡“•Šƒ’’‰‘”™“˜—š ¡š›” Ž‚z¤…li||€t‰Šq‚xyvvŠ€{‰jstƒudw}vkpzm`c[ohMXXej_WYpzonfSOFS9OZNRO(+;JB635=@A9:C><ENSSTVWXZZ\]`bba_^^[TKCSGKNDGPLOI<:;389,2;820)6IRO8")+/2#4;*7FO[J'R^T10T^:+=8]K,<-@² ³¡¿¢¤±±· ©¥³§¥°µªÉ«­±¦µ¦À¨´¡ž¥¥œ¤–• «§¬££·¬ ™–– —­ª¦ÁŸ¬¤–’œ—ž˜“”¢žž£§’‘™¨§²Ã¯™««ž––©ž«œž ­˜¡›¢¥¯¦¡¤§ž¬˜—¦™š¡žžœ° ¢§–˜“™” ¢–£Ÿ— Ž–”‹ŠŽ–­{”›‚‘Š©¨…€˜–Š„ŽŸˆ{ƒ†…™‡†‰•Ž›—˜ž£–™’~e¡³®„‰„vzŠ}vyzogy€‰kuyˆrhtzvƒˆ‚ktcxf_hdcdfjXk{qjj\RLPD_UF@?>,4@F;45;>A;<?>>HNNOPSUVVXZ\_aca_^]]^]XVJKLBIOMRJ;<:786/2964.(&$-1..)+*7%+<(6CMLD/T\Q05M[17E4\G5<,@´ ¹¯¾­«­±² ª¦²­¢¬³°Å°ª¬£²¯¼¤´œ §¢¡™—¨¦©¦¤¥³µž•”ž™™¯¦®¾ «£‘‘žš™”‘•¡œ—©…ž©¬¢³Ç³Ÿ©¤ª––˜š§ž©œ ¤«”žŸž ª®©¥¢ª¡¬›Ÿ  ˜¥žœžœ¯¤™Ÿ¨“˜—’¥š˜©žš—fƒ’|e~ŽšcxŒlhjz£«kd™˜~g…Šeeihz¡ŽkgŒ—‘¢wkj‹˜¢Ÿ˜slnz„…yXe]…^kŠŠv[hsww‘€‡‚nx‚x€smy„twˆ‰ƒ{h„X]jsd]sˆij|qlc]QNWIdX@J3=F7?FD71<=?AC;;DGHHILNPRRTW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%.++'6*$;'/AI[I.6ZO6)EY/DO1YC;?.=¥Ÿº¼¹¯«³°«¥¨­®°§®®°½±©¨¤­°°Ÿ­— ¤ž¡š™¦«œ¬£¦¨©³®ž•£¢¯¦¶¹¥®£Žš¡™“’š ™™¦–{¥¬¢¨³Ã¸¥¢§¯Ÿž•ž£Ÿ¤œ¤ª¨’ž¡ž ª¯©ª¢©Ÿ§›¦Ÿ§ ¬•¡›¥°¤˜œ«–¡ž›“¥˜ž«™ž~¾ƒˆr´r…†­hw¹Ä¸q’¡£{¦˜™sª‚|ËÀÀ»qŠ¢‡ƒž|•˜ˆžÀ½‚–œÁÁ{z‘ŒšÂ¿}k¥±oŒoÊz›x‘ƒŽ€vyyqz‡px…Œ“ylu‘be^xd_eb^thmdbXLVIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^__`_^^^^___]\SMPGUNA??=6468276*&%#)*&.+*)109*#>H[L*#CP/#F[3PY/UAB;/8–£¸Ã´°¯¿©©”£¯©°¯­¦²¶¯ª¦¦¦±« «˜›¢ œ›ª§¢«¢¥©¥¤´¤£“¦®¬¸´§¯¢’‘™¥’‘Ÿ¡˜› ‡¦«¤«­¿À±¡ª®ª—’Ÿ¢™¢¤ª£“ ¡ž¬®©«¥£¢¥ ¤¥œ­©‘¤›¨®ªœªœ¬¢–—¥–¡£˜œΔyz¥y•–›_­]Ž§€¡ |§•›t«‚€¯^dŒ©z§‡…Ÿt—’ˆ³c‚«† ²j„®t|–‡¸a‚­Y£Ínu{Û{™q~ˆ’ue{ˆvvk}ˆn~…’~l€_pjof`_xd[qhjcf`RTRW]JOC5AHED8>6;@?A;=8@>??BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5578164('$!',&&/(&+360$7;SL+,-J0';\:L-!P@F4.1­ÂÀÀµ´°·˜ž‘¤ª©­´«¦²­­¬¤¬¦°ª §›š¦˜œ¢°Ÿ Ÿ¨§£¦¡Ÿ°¬›ž–¦®­±«¨¬ ”’›Ÿ¥“ž¥—¨£ž®¤«°¨¿Æ³¨©±®–“¢— ©ªŸ•¡ž®¯§ª¨›¦¦£ ª’¬³–¦¢ªªž£§¦¡°¡’š§š¡›””‘— p…Œ—u„¨‡q°|r¬~¡Ÿ¥žw«‚}­œr­~«‡†Ÿv˜’z|—~ªˆ¡‹‘‹œ~«{ˆ’Ž €z­VœÄzo’Á}•mupŒmfve†oawnrnˆŠ‘ƒmŽdnsuo`fmd_niinfcWS\`ZRRC8II@D<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;91478452&# 1' 1''45-&7=WJ-<'=1)3V@F!G;C1-+¯ÔÆDz´Ÿ£Ž££¢­®¶¯©±§©ª¨®««§¢£™¢•Ÿ¦«Ÿ¢¥Ÿ¨¨¢Ÿž°­˜›–¨§¯­¨§©ž—•š¤¢’”¡­›§£®¬£¬µ©¹Í²­¦®¬—•œ¢™Ÿ®¬–¡™žŸ©±©©¨šª¨£¡«›¯±¢¨«®¦™¦«ªª±£“—£¥š”’…¤j¤u‰z©tz²q‚¥‰˜Œp‡ š‡¤_`R«„®‚›u®¦††Ÿz˜–…{f€£‰¤˜†£}©~€”†®^|¨U¢’z£Ÿ€{ïŌs¯³³¹qb©¯ÂuhŒ‹—l™‘nmxwwnlfedqpf{ic]V_iXXTLLQLCCAB;C@@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799664,&$" ('"+-"$.!3-&@DWH,G+56*1PKL# A9D4,'ÂÉÕÖÀ¡™«¨¡¯¢Ÿ°µ°¯©­£¨§ª««©¤¦ ›¥Ÿ¥§¦¤œ¬š¢«¡¤Ÿ¯£ž›“ª¤¶°® ©›—•§¤‘›¡¨Ÿ ¦œ°¦£¨±¬¶È²µª¬ª•’¢™Ÿ¥³š¡”œŸ¦««¢­™«¨¡¡©¢²­¢ª²²¡›ª¨¯¯¶£“–¤§˜›‘|ªlž„‡u«y|°n‚¤‹ˆŸ–•ž•Ò·´¸É€²^_”©ƒ¤ˆ‡ z˜•™xªÉs™£”§©’›Œ~š‰šÆÆwe¡‚¥s‚ Ž‚}¯^oµc±uK£†m§G‚“cŽ’{p–‘}ozt|zm\fjrqfi^aXcm\^YIMMKEDAB>A<B?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75785/)(%&%$&),5FNPPMFLJVF*L0/>-4OTQ;<F2,$¨¤Áƹ­¨²®¬¥¢²¹¬ª¡¦›¨¦«¬©§ ¦¥˜ª£Ÿ®«¦ ¬šŸ©¥§µŸ¢—“¨«¶²¬›¦œ •¦­‘™œ§£ ª§®¡£§©¯´Â²³ª­¨”‰—¥›¢£¯¥—¡•™œ¥¥«š®œ¬§¥ž«£·¬ ±¸°›¯§³´³¥•˜¨¤› Ž‚NxšŸz„£|‚¤„†¦žœž“„¸{|y¹‚~ÌŶxš ‹Ÿ~š–—Šuž—Š¤˜£¨~°…›„ž„¬}™”a¥l£p…}—ƒr¬`¤sq€š`¼}RUtŽ‘£–{}‘ˆszr„~p[lnwrjnZc_hnbd]KLQTAHHFI:9K>B108856877-*5==?BDGILNPTVXYZ[\__^]__\ZZZYUSOH@772.,*.+*'&?QTVWWWYXXWUOUF<E2:P[T6?H,- Œ‡™©¬¤«¹«¯ ›¡¬³´¦Ÿ •¥¯®®©¦¦¦š£§¡²®¡©¦² ™¨¤”¢µ¢£•—¡©µ¹¤›££“¢±™žœ§¥¡¢¯­¤¨¢µ±Ã±­ª­ª‘†‘œ§£¤¥—ž˜™™¥£¨™­¡¬¤¥—®¥»¬¡··®ž¶³¹±³§™ž°¢¤ž†ÑµÃ·y‡Ž…‘“€¦x”¢wŒ ’„¥‚‹q«†„´nri™£œ•‰Ÿ|˜™†‡r®‚¥›¢¦‹“œˆ“šmp²\¥s“zœl™{™}n©a¢qqŸbs²¸hw“¥˜}‹‹‘Šw|xlhwixsnt\ddmmeh`JZWX<GG@T3@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^__]Z[ZXURRQF:2230/++(@QRTUTSTVWWXXWUUVTQOQ[U%!2AH$)%’sŒŠ®¿¿¼»µž—¨¤­¶¡£™•£©§®©«™¥¡Ÿ¥  µ§¢©§°£”«£Ž¤­£ššª´´¤¦œ©’”—®  ž¦¤§œµš ª£µ«Â°©«©¢„œ¢¡¦£–™šœ˜›˜¥¤¦˜ª¦¬¡¤›¬¦½¬”½°­Ÿ£°³º¬´§›©²¥¨˜z¨}|°wŠ¤¥ˆœm²o ‡­|¡ƒ¨–™€¬ˆ„®…Ÿ”¨ ¢–…Ÿ€™•€{’}«€š–ŠªxŸŽˆ“’€y¯]£|¦§d€|—tk®]¥kq…™]`[Œ m”¦™‚“‹•Šyy‚–jl~b}tny_feqngghCY`[=JT2T8BBC7$$3+''3, /667436:@CFIKMNQSSSVZ]_a`aaa^][ZXSPONI7052.*,ATVVVTTUUUUTTUTSSVWWXVUUQHFIJ#((¼’š„©ÆöÁ´Ÿ›­ ®¸¥¤Ž›¤£ ¯®©Ÿ£ž­˜ž¹ ¢« ¯ªš­¡ª©¤–‰š®±¬¦Ÿ¨›­˜˜­¢¡ž¥¡š¥œ­˜Ÿ¨¦¶¨¿¯¥©¤ŸŒ€Ž›› ¦ž’”™š”šš¤££™§ª«¢£ž©¨¾¤—쪣¢«³º¬¯§¡´°©«™v¯~Šœ…‡|º­‰˜d°Œe•­} ƒ§–š¬Š„°…¥™¤¡¢„ [lj³`­{{‚±lgn™—‹ˆ±[}´[¤ƒkÈ¢eŸ{¼YvµZ²}R¯€z¬X€¡m—Ž¨š‰–”•yw›}cr}aƒxs|`ifpmfeeOUc\AT^=I(>9=4!",%2. *1/04579:<ACFHJLNPPRTWZ^````b^_\[XUPMJGC553./@UYXWXWXXWWXWVWWWWXWWXYZZ[\XWWGB;ҟ³²·½»´Á³£œ­¦¥¶©¡‹™ Ÿ³²¨ž¢Ÿ´˜ ³¨ª«ž°­¬›”®©¢Žˆ›Ž¯­¨¦£¨™®“š©š¡ž¥Ÿ™££¥™ž¢©²¨»¯¥¨ž|‹š–¡ š‘š›‘™—§ž ˜§¬¦¤¤¢¤©»ž Æ§¥©¢«´¶­®§ ½®­­–©’£®Ž›€†¤—˜€¸ÃºƒŽœ“„§—œ‚¬Š‚¯ˆ¦›š¥ª‘~սªb£¿½|~£‚ƒ×º¸µ…“’‚ž½¾„j£o«„nœz²±Çƒj«°½­xw¢¾»t€•¦›Ž™•›x€™yb|zcŒgx{`kekjbPb[Si\@TaBM)<:4/$%2 $(0496678;>ACFGJKMNNQTW]a\__a^`[\YTQMIC><A?5=SYYXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ¼•´´±¿¹²½³¢®¦¦³¦žŒ˜¥¿ª·°§ ¿¦¦±›ž±œ¹¨ž­®¥§””¯¬—Œƒš‘¯¦£¬¡¥œª ˜‹£’¦ž§œš¡¨¢™ž «­©¹®¨¤›—“{‡™‘¦›“‘˜˜˜“¨™Ÿ—¨¨Ÿ©¦¡¢ª»ž©Å£ ¯£«³µ«°ª¡¼¨°°štuª¤·…e‰Ÿog¬Šmow¤™Ÿu¯™•pŒq•§£›˜®¤rmmmeŠwnm‚™q€yipig‰••—qhi…†gp†d^‰cjpY]g~w¦`bqŽ’ofd€’Ž¢—–—”{†“te†whŒjx~xdlcflbKdXJkY:PeEQ'K9+# #,)-2.5:457:<?ABDEHKLMOQSV\WZ\`_a]][TPLHD=:AB7MXYZYYZYXXYXWWVWY]^^]\\\]^]^][[UW^¨”­³©º¹²³ª©¢®Ÿ¤³ª˜’½±ÃȽµ©žÀ«¬£ ¦«Ÿº£¤­¬¬¥–­ªŒ…•—­Ÿ¥ª¢Ÿ¤¤ ‘Œ¥“§™¨™–£ª –œ¥¦§¯¹«¬š›“’{„—¦—‘˜”—•§”ž—§¢š¯¦¢¬¹Ÿ°Á¨¤³¦¬±±«®¬¨¹¤¯¸–Š¡¨¥¶œ‰–¡—†©š”“ª³™›£¬¡³—¢ ž ¢œ ¤¡•«¦Œ’“Œ‡’œœ”™“˜Ž•…€¤š—•‹“’Š†„}g‹€tƒvt‡Œq§m|•‘”“Ž“ •–•Ÿ†“‹pgŽvoŠwv|yikddocU`Y@iZGb`NY*E=+&"740.!%2(*799469;>?ABDFJKKMPPQWUVY^_ac]^UQJEC>9=@ASX[\YWXXXXXYXXZ[[\^__`^^^__```_YY`¥–©ª¤µ¸®®¢°¤­ ¡¶±Ž«Ä»Äº·ª¡¥›¦°¨£¶§©´¦§‘—¬£‹ˆ‰œ§–¬¤¡š§žŸ“•£—©š¨™”§¡¤š§™¡µº¨«˜šŒ{”Œ¡”Š”‘•“—¥ž™¨ž›µ£¦«·¨®Â®£·¦¯¯°­ªª´º¢¯½™’¦£¦µ¢‘¦ž©Ÿ’Ÿ£¬¯š¡£±©°˜¤¡œ¤ªžœ—«œ’™¡›“–ª™˜˜––ž‘ˆ ””…’ŒŒ”‹€~fŒ‡u‡vyˆƒsœj‡‘””‘Š}Œ–’’˜’ ‘›•Ÿ‚†—…xq”rx‰q{~ind_pi`[_YmbP`dPZ:GFE=3==7.*&+)&&406658:==?AACHJGJKLMSSSUZ``i`eVPJACB;9EMV[^^[Z\[[[\]]_^]^_`aabaaa`bbbdb\[c˜•¤§£°³¬®£©§­ ¨µª‘œ£²º®««¡¢™z¢°¤¥±©–›¸¦£”™©œŽ†Š‰›¢®ž¤–¨ ¡’—™œ®‹ª–¨™¨Œ˜¨ž¹¶¤¥˜›ˆy“Œ›“Š•‘”‘–¡Œ§ž¸£ƒ¯µ¢°¯t¤¾£² xz «³¼•v®¤ŸŠ€ª~d[avŸŽ¤ƒ—~n“³œ£¨®«£ež “sy™–p€˜¨—l¢§‰eœ¥›—˜–‹‘›…š”‚’‡ŽŽ’‰…wk‡v‡q|†€aiˆ‹•“‹[v•‘ghqz£—–dx˜†€v—hƒ‰‚nx~jpe_uokkh\ecbboR[>MNNRG=@TB91.&4:316678<;>@ABFHBGFIKLTUUY\_hfgWQJ<DG<9VR[`ab`^`_`aa_\]___aabcdabaaedchd^]fœ–¦£¡°±¬«©¥©­£§­¥’–ª´®±¥™©¦«–s‹œ¯Ÿ¨«§“–¸Ÿ œ£‘~ˆˆšž«š¤•§¢žŽ—’ž…u®‰¦š¨‘—£ˆ›º´¨ ™˜‹‰uv“Ž–“Š“‘”Œ’ŸšŸ¦˜›²–€Œ›µ´Œ’½§¡~§¢z£¯¸ŽŽ§Ÿ„‹…°©¯Œ‰–¢™y‹¬†œ¢¨ª¨ˆ•†˜w¥›z‡›—¦‚{œ±zŠ…Ÿ—™”˜–––„™šby‡„’‹ƒnqˆzq€††t‡…–’x–h“t št|™ƒž›…˜~‘‰‚—iŒ„kxzppgdwmilj[djier[^HSLQ@E5-YTT6)!09=>643568;:=>>?DI@IEJKGRXZX[aahfYQH9DK<>bV^bded`aa`bb_]`aabbbcfgcba`edcgcaah˜£Ÿ¦®®«¨¬ ¨°§§ª¥™”­Æ¼°¡•¥¨´ƒœ«›§¢ ¾ž™Ÿš }…Ž™—ˆ«£– ¡’“‰†€‘¨Ž‡¢œ£“—ž†Ÿ¹²§š“…puŠ•Š”›‹‘ž‘–Ÿ£•¬ˆŸ´‰´š®‹Êˆ«®‰·…°ƒ±¯„©§˜|¨r{w›Ž¦–h•¤y´‹Ÿž§©’™Â«ˆ˜¡qž€š¤}—…•±¡| “Ÿ˜—€Ž“›‰˜’‹|…“†•“‰ƒms‘…€{r†…}…t…‚—Åf€©‡¢jž‚Ÿ˜™€Š‹ƒˆ˜o’„gwt{vghupfgk^bnlflXfF\PL2E46M`c6&4<DGD:63658;8>==>BL?NIJKCPZ]\Wb^jl\QE=KM@JdX]cfhgbbbbcc`_babcccdiicbbbecafcbbi•—¢Ÿ°¨©¨¥« ¤¸±ª«¦š”Ÿ¢¤ª¢•£©¶¢¯ ¦œ¥ž‰”½™“ ‘yƒ––‘‡«™œ›š¡…Œw›œ ‘ˆž¤›•™˜†¢¸­¥™›bm‹“ŒŒ—‹‘žŽ“Ÿ ˜¡¨~¡§‡­ –®Ÿ‘† «¯‡¤ªšŒš~¢u€˜“k«tM«x‡‘›©¨‚ª«}ƒ¡{z§iž’kg—†—¶ˆž}m`cXƒ—Œ{dg‹s™}y–k]|—n_Sq…\`lyƒ`Ye‚}„˜q§ªkƒ£nr¥pŸƒgdŸlZlˆzeY_‚~aWPovemtqjjo^jolkhWhN]WE9A4GC^k4+ICQMN=84859;6@;;>BO>QRLMBJ\]_W^_bv`MD:MOMTb\[ffiibbdaddbab`bdcabikdbddgdbgeach˜– ¹¡ª£¦¬’¡¶¼«®¢™—Ÿ¡¥¬¬Ÿœ­´¢§‘ ŸŸ¦œ™Ž˜´™‹žŒ•‹u”‘Š¦––˜žž“…†¬¤‡œ‘Š˜©˜™š’‡¥°¦¢•™ˆ‰€inˆ‡‹ŽŽ‰‹’‹‘¡Œ“žŸ›¢¥“£¡” wœ–§ƒ¡§€†ª®…¥y‹}„š}¢pr’‡–{žŒym‡›Œ™›©›‡|‚¢sv¦fž~w¤_˜z|’s¢n˜·´ºt’‡€¶¨dÆ¸{p•¶Œq€›¤ct¬«`}j³~n}‡ƒŽ‚‹—q€£ls¤sžƒ~£^™³–o{—ž³tr[ž²‚ibosuqhoYklrre\h]bKD=D5QAYq2<RF_JS=<395::6D;;@IP?TMNQ@E_^[ZX``|dIC8LWUVbaZefkkbbeadc`ab`cc_`cknccddhdbgfchh”–•£¹™¬œ“ Ž¥¸µ®­ š¢œ££¤¬›š±¬«’— ˜ ¤šš”ž«›‹ˆ’x‹…p€–Š “”—}‘‰Ž¨¡‡˜Š’£“›šŒ‹¨§¤ž–‡„~k{†~}ƒ‹‰“Ÿ‚–œ  Ÿ‹‰wœ˜¢Œ r¢‹ˆ©ˆœ§‘—¨¬®Œ}z ™y£“x€s—ˆŒœ}–Ÿ†›™›¦†£d¡|‰–›lžhšnš™zŠ§}rgsªƒ‚sªg”š]›…v„hªj¸f\©pœa•Œ^§vu‰Šžhšu‡“’˜Žžn™k¦™\¨~w»j}©ZŽ„]³g\mqxwki[pixxb^eWbAPDO7VBRm4JZZ_NZD@151;;7H?:CHU?XRY]>Db]V`Qad}iEB9N[^YdfXfgnmbbe_aa__``ec^bdoq_deekdcihgki•œ‰ª¶›¨‰c•œ¬º²°¬¦››§Ÿ­š°§«—¢™¡Ÿ™–– £™†‰iˆ€q{—ˆ‹––„’•˜zŠ„–£‰•†‹‘œ›‰¨¢ š‹‘Š€€i†x–Œ{ˆŽ‡Ž•š~“¡ž ¢“˜rhŸŠ Œp’Œ‚©ˆ™Ÿ£©¡¨}°­¤¢¸—v£³¢£ˆ”xz«š~¢Ž›—ˆ—r¡|…¯µ}kš‘¡x~˜´££«¨„˜{š|œ™~sªZ]o{—‹xžbL{{…cz˜BMŸY¢jr|Žm‰„™u›y‡‰±³š’¦tmq|”o™ri£]•vHec`sp|}ne`khv{bc`Q^V\TV@YEQgDRW[bX_ID=B8@B:IE8LEXAVQ[VDFa\Z`K`m~rEC<U^bZejVghlnbff^aa\]^`hb_ecvl^egfldelhhki“±®™„S^¡§´º³³©š¢‹›©œ›¨’¡«£ §Žžœš™•˜¡–‡‡‰w…ny•…š‹}‘“–ˆr€‰’ œr‘ˆ˜”Ÿš„Ž¨œš•Š‹Š|„l„…q¡Œx…ˆ‡’˜”|’£ ž£ˆ®†}µ„ž{¦–z©‚–‹¡ž}§hwm~™s sq|…˜o“‚®}£ƒ¦žš£p^©gu£co¥aœÓ|z™xrsc¢…~¢r¢Žuk³‹`‚˜Šsª²§¼wƒm¿¦ª´^›o~q—os¢r]£gt¦ah¦m›Ó˜z‚›nwy—k›zv—rl©¥g_dyp~„kgfcmvwf_aR[eQQaIWIT_WS[ej[eQECKLJKBJD8P@QNWSXORQ`eeiRdxywIFEc]eZhjSihjocjg`b_\]]_hbahe{d^dgdkdjlfhlh˜›°¬T\K~©¯²µ°³£œ˜…˜¦  ¢¤¨Ÿ—¨‰™—˜“™“’ —ˆ…{p}„h}ƒ“šx‘Ž‰p†’’l—“|‰‘’£•ƒŽªš”’Š…‰y„v‡€nŸ†w€’†ˆ™¡–y“¢£š ‰³¡¢¶‹z¬§¤®¥p©€š…œ’}¤€¢™†˜qž„¢¬®‰—‹€Œ¤–ƒ®¢”vµ¶µÉ¡t”Š€Ÿaž—©mx–†Ÿšu¡‡w }–ŠoLf¢’pšˆs¤{ytaƒ‚l~ lrd`œrt—i{i³µ´Æ¦s˜~{j›š«t‚šmsw—išyt˜qPE|³^jujx‡fjgbttpmU]SYhPRhIULXRV]gknVgWMJAJMJHJNAQJPecimetrs~x{nu‰{{TQOl^h[kiRjhilglfce_\\\^ibdhk{_]dgcjfnmeile¢œ‰¯§…f?”¡³«¯¯µ¢¢€—¨¢¡£‹¤¦œ¥š—–—›’ˆƒyjy†eƒŒ~– yuˆŒi„…’ƒŒ…zŒŠ•¥’‚—©—Œ‘‹€‰z€}‹yp¡†y€”‡‰–Ÿ””¥§œ––„gnxœl¢d|q¥wœ˜pg§—Œ{¥z –ƒ–rŸv€‰”–¹nŠ¢b}™¢•ˆnriªku ln¦`›i‹h–‡š•u¢€}š_‹…Œuoˆbh¡eži›updfˆ‚nr¢Z_[d¡n^‰Œo{srd¥nx¢dg§h˜r‹˜n¡oRˆo ^d§T‹]S˜mmrjqlphkxskoQWVVfYSmIXO\HXihsjYkVQREV\LXRaUhj^wuz|p||r‚{rv€ƒv^QsagbpgPjhhklngdg_]]]`jbjivu]\chcjirlfkmc¥˜¦zetm‹§®¥ª°±¦Ÿ‹€–ªœž¤Œ¡¡š¡¡€•˜“š‹—Š{†q€ˆh‹‹|—šsu‰}{eƒ‡•ŠŠ•™‚|ˆ†–¦¢«…ŠŠ}€€Žsi¥„}…“ˆ˜Ÿ‡’ª¦ž‰¦x–œ~¥‰–Œ²˜žƒ¯—Ÿ¥x–ˆz©t¥„šn¥¢Œ’„Œƒ¼n|¥¯‚†…†“–œ }¦zq¨” –gž~o«b–Š•’w¨l©¢‰v‡‚w«‘¦ˆk‘°kv³Œ©l‹†nmŸž’•a~«‹ªv€§ŸwŸ}…¤• iš‡u«fž­Œ¶sw¾Œ¤“Yƒ¦«auqso{tpbj~nhlRUZU`a]kM]R]I]lmv`[qY[`Zgsenorcqt`wz~yryƒsƒ~{{Œ‚€vbxdcnsdRlgholrifia_^\ajbllzo\\bibmiwmglnb•¦ªœ€ž¤–©ªž¨§®£™‰‚—ª™£‰š¥œ¨„‹š…œ‘…’‹t…zˆƒo„}–“tu†r‘ƒm‹’‡†“}{…—¥¥¥€‰„”uƒ‡’olŠ¨€‚‹”Ž‰œž‰Œ“ª£ €u•—ˆ~y”®£›q†xŒ…€{r§Œq}}z—–›„Žx{~}ˆ”•“Šv™Ÿ¡„{}‰kŒ…[yyryphn}‘‰qt”“q…ƒe_€Œwus”uozon‡m„†_whxŽf‚†Žªœ~t}—j‰ˆou|„umlfŒsx{—w„[jXxhmwqpowwo]l†migVY_W\dkdUaU^Q_pwykjwejjju|qqtsaoubs{xuy‚u€€x‹…‚}{nldyn^Wnghukxjiid\`ZcielpunZ[bkdkkymhloaŽ•º©§‹¡¢š¦¤™¤«¢ ƒƒ—«‘ ‰š¦š¨˜‚›‹~–”‡Ž‰ˆr‚|}~„z—Žts„p•…{}’‹††…x~€†™£Œ{§¡‹…„•‚†Ž—wr„©…’œˆžž‡‹š§  «ƒ‰Ž•š~~‰–­¨’§xpž‘ƒ{“o~©…p}•qjo|Ÿ‹’ŽŒhm]ƒ‹Œœ›ŸŽs•‹ˆqtk‚vsXrn†}~‹i]icz…ƒˆ€_ix{›|ƒŒƒv†ƒiy‹‡kaqsƒw`sŒ‚‰§•†fƒnv‹ƒo„Œxndfcy‚z•Z\ifnv[zywtmsr‚f\mŠkkbYY]ZXkq[^`Y^]fs}{sotcjji{|qzwtdmthl|~uy|{zy€o†Š„{}t~yrhT\qilvpugkgd]aYjhkjqrmW[enlgsynhjm`ŒŒ«±¢£¡šŸž˜ž™©£¡}ƒ—«ŒŸ”‡›¢¤”{—„|’™ˆ‰††Šr}€‹v…‹„–Šro€r˜†„~’ƒ„†Šz€ƒŠ›Ÿ‚¦ ‡x—ˆ•‹‹œ—…ƒz¬—™”Šž‡ˆ¡ªŸ¢¢£Œˆ“›œ£™–ª¡§¦ ’›ˆ—|xŽ„¨~’‘’“œ°¥š”Ž²“˜„¦ŒŒ•› ‰›‚ˆ‘Šk|Žvwe‚†Š|‰„‡‹‡ˆ€„ƒw|zuš¢‰‡‹Ÿ‹†•~Œ€vqt†…€xˆ‡Š‘¦‘„†ŽˆƒŒ|†Š‡Ž€ukƒ{y™irh`sŠp}zvuowt\^o‡hn_^Z[\SgqUc[[alht{|rnpcjih{mx~qhoplf€{r€w€}„{m‚Œ…|zx|}zƒxNdvjsnp{ekebb`[sfpfrqlU]ltmiyzpgikeˆºŸ–¢¡˜•™˜”˜¤ {™ª…ŸœŠ–|x”‚{Ž™‰†ƒ„†mx€r€‡}ˆ“„mk~z—†„ƒ~€†„†}‡ƒ›’‡ªž‚qŠ…’‘‹œ‘}z©ƒ’—•Ž›–††›¦ ¢š†ƒ’™™˜š¦Ÿ¦—’‹w}ˆŽ…¥{|Ž‘†˜©¡œ“œªŽ’€žˆ“šŸƒ—~†Ž‚ox…qt`~ƒ…t‹—€ƒŽ‚†„~…„”nyuu“¢‹†›……Žt€Š}}rs{‰„{yŒŽ„“§†„‚ƒŠ‰‰u„‡ˆŠ{nj}{mhklg^y~g|{vsuuzv\`p}mt`bZ\^QfmSeZ]akiuy~pklckjg€kr€lktnxn„yn†€v‚€}…vq‚‡}{z|{‚‹`i{kuhiƒejc`i[cuhobumlTbqydpzzrejmm‹ŠŸ¸š¡¤Ÿ“’–—‹šŸžzw¥›‰†¤”Š˜™xz…|‰‘ƒŒ‚‚m|xr€…}Š}kh}—ˆˆŽ|~†„‡|€››‘ˆ§œp‹Š‹’† ¡Š…Œ|§‘‡’—“–’w£ ¡–š™˜“Œš¢¡£š—‘›Ž…y€„‡¡€~ŒŒ|—¤  ’™¦›‘‰“˜›~’’~‡Žut‚pv`}€…qŠ•|‡‹qŒ~‚……ŽhxryŒ™’€˜~ˆ‹r‚‡|}qz|Œ…z{’ƒ–¥“‹†‘|…†‡„u‚†‡ydqz~xypljf^}rh{uus|sj^`svpwdcY^^RjhTdX^agjvxqfkclhe€jm}gnpj}w…zk‹r}tv‚†~|z}jrƒnsiaˆilb_qUtomn`xhmWjtvbuz{qbkoz‰Ÿ³’¥¥Ž˜† šœ|u£ –Œ¢Šˆš–x{†‡~ƒ‰~ˆ‚€p{tu‚…~‰xgc}†—Š‚Šx}€Œƒy–€•—•–Ÿš}o‹“†¥›‡Œ‰ƒ¥•„’Š•—’‘v‘¡¡˜”˜zŽ˜–Ž–šœ¤ž™“”›z†ƒx…—ž~ŠŒs—¢ ’˜Ž¢ŒŒƒ—˜ƒ“–š˜|ˆvq}mzd€|Š…p†’‚k‡‚‰„euo|‡“˜}”xŒ‰|€‡}|r€xŠ‡y…‘Š‹˜¢–‚„Œwˆ„‚vz€ˆ„t_ww|s}wfkd`~ijvrst}p{cc`smurmaY`^[ldRbW_`hkuy†pcjclfh|ƒkhthloh|xm†q€‚‚t|ƒŒ~z‚ƒ~|mu‰ttmeŠljacuVƒiqn`xflbjvpfy{yq`rl†…®˜¦¨žŽ—‡†Ÿ“—˜|w©œŠ˜y—œ‹‹˜x{€‹}|ƒ{€‚€xsxzs}€„ˆŠ€d^}‹•‡~„‡t}~Š}˜„–”–Œ¢ —~r‡{“‘Š¦ŒŽŠ’ ‘ƒ‘”—‘Š˜ š’’t€‘“‰œž¦˜˜•—tŽŠl†˜™z‡ˆ‰o—™¢“”ŠŒŸŒ†‚’œ“’•‡™ˆ{‰‰zqyjul{}‹}m…‘‚“woƒ}~‹€drj|—˜…Žt‘‰ƒy‡~vx~‡}„Ž…”¤y…ƒt‰‡}rt†‚l`ztyp{oanbd{annurwwssav_nkuno][^]^j]O]Wbahmsz‰k_jejchw‡melhilg€|zwo‡s€ƒ„}t†‰z‚}z„}}Žry‹yxnl‡kh_iqc‡hqoevgmlazhj|zxpawm‹™šª ¤©ŠŠ‘†ŠžŠ•—}v­˜Œ–}ž“‘–”ˆv}{Š|{€vw€ptszo…}€‰~|a\~‘†ƒ„sz€†z‘‡‘‘›’¤›”}€|Š’¤ˆŠ—š…‘˜“•Ž‰‰Œ““Œn„Ž‘ˆž™¡ —–‰–’oŠš…g†š”z‰…Šp–š“¡’’ˆ‹™Œ‚€‘ž}’“Œ™Ž{‰„‡tsukqnu{Štn†‘qt€{‚ˆ|eqmy~š”}…‰t‘‹t‰yo‡}…Š…–¨{ˆ}~‹…w}pn„‚bgwstnzb^o`jt^pizxxlrpex]mlsmsXZ^_ajZOWXdcgqq‡e]ihfbgqndigdih€zwuoŽ„s€‚{u‚ˆ…x„|wƒ…z€‰w‹|{ryƒjk_phtkqnmqgole{bmyvqlwwŠ¢˜¢¨¡§›‡ŒŠœ†“œt€ª”‘Œ† Œ•“s{v„wxrs{…kroym‰v€€†np[Y~‘ˆ€€€vu€ †Š‘œ— “–w‰~€Œˆœ‰†’—–„ˆ”™–‹‹ŽŠŽ„n‰‹‘Šœ– ›˜•…˜ˆk†¤ƒg†Š‘‹„‹w“˜‘‘ˆ‰•Ž~˜|‘š’}Š‚ovokmopz…isƒŽ—‰pw€t‚ˆ‚yftov‚š|‰…z•’zw‰tpŠ|‡{‹‡„‰œ£ˆ|„w‚‹€xxni\qrqoowZ^p`oj^oi|ypmmjmv`pojqmYXaabmWQSYefcup„‚b]kmdbfk’m`ff_gkuqrp‹€t‚€xv€‹€y…w‡†vƒ…|‡Œ€{vŠjqc|b†|opltjholvw_q~y{tut‚~¥•š­Ÿ§–…ƒ—•ƒžtŠŸ“’…ŠšŒ•Ž‹zrwt‚pr…squˆlomumˆwƒ}mnUQ«”‡‚x€vr‚y‚ ‘“’˜›‘™x‘z‚Œ’¤š“Žˆ•˜’ƒ†–™Œ“‹‰ˆž…Š}s‹…ˆˆœ™ž›–”€”i†ˆh‡¡ˆ’„‘ƒ‰qƒ‘—ŽšŽŒ‹w{’zŽ‹‘–|ˆ|€kvjmkklz~ay}Ž•vzwƒŒ|ygulu‡–Œˆ†{”‘qz…px{‹{‰~ƒ‘žž…|}x‚‹}vphk€w^vomkprU]nbq`_mmypgpfgsuhpkawe]Ve``rSPN[fd]xpˆ|^\hrbbef‘i_gdZhp~okqsŠ}v}…€tuŒy{†€xˆƒs†…~ŒŒƒ{y•xfrjƒ`‡~ookz`imtt_t|x†xsr…|y¡š±œ¦ŽƒŠƒšˆ€‹~Š™’Ž„ˆ—ŽŽ„vsvs€po…spqƒojivm‚n}|mtsRN‚ßɒ֓|ptƒuƒ ‚’w”˜›˜{“r…Ÿ¡““Š’›“…~–•ˆˆ‘ˆœ€ŽxzŒ~ˆŒ‰››œš•“ywhŠ’ˆl‰¤…’ˆ—ƒ†cŒ‘˜Ž”‰–‹Š‹q{”‰{ˆŠ“‘‰z…{~l{erojkyy[€y€z}~†Žzzhtkt‹Š‚†…}–Œl~oˆ~„zƒ–š›‹|wxƒxrlep‚khtoghslS^ndpY_kpxfkjbfxsopc_w``Vk_]vOMK`fc]yqŠt\[eu`aeeŽcafaXissnkqv‹|ty†uv~‹s†{‰r‰‡‘Šˆ|~˜vesn|eˆopk€Yknyys`vz{vrwŠwyŸŒ›¯› ‚…wˆ•~|‰œ‡„ŸŽ…Œ—„“Ž‡uwpyqn„omn~rddxp|mz|jhlc¤šÁÜ®ï¡skuƒu„¡…‘n•”Ÿ”›‘p…‹£—‰Ž•Š•‚€•…‰€’ŠŠ—‡{u‰x†„›š—™Žv‹woˆŠŒ}‹¤…’‰…†^‹”—ŠŽˆŽ‹Š„‰l{—‚}ˆ…‰‘†v…}}k}cxuimxsWˆz‘†„y~€…Œ~yftj€ŠŠƒƒ€Œ—†kvn‰’ƒ‘…‚z€‘–”™ttx‡uspftyasloahufR`pgkU^msy`rc_h}qrmZbrabWnZ\wMMLcfa^vsŠm[\dx^`df„_cc^Xjrknkrw‹}sw„xw|ˆqƒ„}~ˆ{t‹ˆˆ•†Œ~~—shuqylŒ{ntpXpzvyqdwy†Œiv€‰r€ˆ™¨œ£’„}pŒ”xyŠƒ„ Ž|•Œ™‡„{swpsjokil|t^`xv{ptzg`e|ëÚµÉÃ܈sls€vŠšˆi—Žœ”’ˆp…ˆ Ž„‹•ŠŒ˜“|’ˆƒ‰{‘‹†‚vxƒ„r‡‚’›–“˜†Œv‡p†ƒŠ‡š¢ƒ”Œžƒ‰aƒ•Ž†‰…‰Œ‡€‡i}”}ƒ„‰Ž‚q†~qwgvriswkZŒ}’„|ƒ€„Š‚vbtl‰‚‹‚“‘}n‚ly‡‡“…}~’”‘—‰nrzŒ†ulpjqw^shn\ju`RdqhfS_ovt_o`]h‚qriWghciXmW[uLJKef^brs…h[\ey^^dgzad_\YknenjtwŠ~ss~zvz‡s…‚|‡wvŠ…˜‚{“vlwuyy“unxz}Xy†q€ogxw’‚dv†…qŠ–…™¡›¢Š†so’‹rvŽ›}‰™ˆ‰{Ÿƒ™yrsnodr~iflww[_xzzqqiagaÕ¶Ž¦xnqw{q’Œ‡j˜ˆ›‘‹†{h‡‹™†’‘†‡—|Œ€€‰|Œ~Š…zu{‚zq…€”˜Ž’“‰u„‡w„€‹”Ÿ†–Ÿˆa“‡„‡ƒ‰‚f}‘~‚Œ~m‚|‚tkmvtsvukcŽ„~|„„ˆp`sq†|‚|’‰zqƒf{„‹‡„|…~•‘“„npyŒ~umnijy|agiiXkuZRiribPbrxlae]Zjƒmsb[g_dl_nTZoNHNfd\gnq€kZ[cr_\clwde]\Zlkbmjsv†qo||tx…x…‚|€ˆuy‰’•|ˆ†vˆpxy{„“om{w^ƒtmizs”sgrˆ}r’‘„šŸ› †‡vv”mv“—}‡ƒŠ™|‹šv~wqoljat|gbiuzZ_x|ymq~echhW^qr–¼Ä„uq”ˆ~r–‹†›’Œ‡rjˆ–€{”Œ„›Œ|Š†|{‰Œ”ˆuŠ†vv}qu…“…”ƒƒq€ˆu…|Š™˜‡”Ž€ˆf}“‚…ƒ‰‰q}f~‹{y~‡‹}i€|ƒvfoxxsvslj…Š‰x€…ƒk_ry{~Š†|‚~riy„ˆŒ†…y„}˜Œ}nm{‰}wtngf{ub[pbWnrSSnshaMftxe`]\Xn€osYea^jm`pOYkQDSg`Zknm|nY[^lcZbowdf[]`liclisvƒqn~|tuƒzƒ‚|…v~ˆ–xƒŠtˆryx~oo{qixz~ml{u•kjw„tl”Ž†ž˜ ™…ˆn}Œvix˜Ž~€Š‚•—‰yŽ–ozspljd`szh_eqzZ`r}ygqzaee±²wJbZ¤ÙЖr{Šw}”Š„™‘Œ…nk…’‘zy’†€„˜Š|‡xx‰Š„–€pŒˆqt}ziy…ƒ¤„“Œƒ~oƒw„y†œ™•‹“”…ˆp{’‚}‚ƒˆƒnwh€…xrƒŠ‡|e}~„ucprhxpou˜Œ…‚Š|vx€„yk\qsˆ…‰~†‰{‰rnq…‡……s„z‚™„xno~„vzdgi{o^XvZXplNWqsg`Jlvt`][[Yt}roWg]fjp`oNWhQ?Yf^ZojgzqZZYkeYcqy_h\^emhekiqw‡ol~€uo‚{€~‚v…ˆ—Šq‚q{†|yy„“Œujzlo~t}or{{”onxf“‹ƒ¡™œ’‚…g‡ƒpgz–ˆ}~„˜‰|Œixrklf_anxm_box\dlƒzaqv_eeÔ꾊2:>‹Ž€qx…ˆŽvƒ–Œ~’Œml…Œv}…•ˆ|‚xnv‡„ƒ—wnˆ…lu{tfy‚ƒ¦‹‚‹ƒ}n€uw„z‡‘Œ‘’“Œ‹†{’†w„ƒkrh€~xm|{Šƒwby„qdqh~mtqt›‹€~…~su}€so[mux‹ƒ‹{‡€|ˆxzql‰„„‹r‚z€—‹‹tmkw€€uu\hgvoXV{RYodLZrre[Ipxo\ZZY]u~thYb[genciMWfQ=^e\]ue`upZYTodYdqyZh^`gmgjkipw}Žli‚„~yn€||‚zu‚“…p€‹nw~€{{ˆ’‰h{}jt{r†{sw}Œyx„}|kŒ„›–Œ€€l~kh~Œz~ƒ”~}Šˆkuqghb[bgrn`aksahp‰zbst^cd› n\5Y¯µti€ˆ|’†u…–…sŠ‰vpl…ƒ‡uy‰x‰|“‡z~sgv‰~~˜oq†~hvymeyˆ„¤†€‡‰~n~v€}Œšˆ‚”‘˜‰‹„‰|ˆp{}„{h~lj€{zizv‡€r`w~qdrfu‚mu{„”‘|nwy|t~lXp€wuŒ‚†xˆv‚‰zxsnŠ†s}“‰ˆznmjn‚‚un\gdrpQZzMZo\N[rpdUKsxiWYYZaq€t`]]`fdhieNZhN@ad[`ua]umXWStaZdorWj]ahkgmlipw|’li„‰||p~~{‚zw€‰‹ƒq{‡oqw„{‰ƒj~{mwxvŠw}x€‚‡ƒ~~zm…Œˆ˜£„ƒ{u‹ykl„ˆx}{‘~Šƒprqcf^Yf_op``gpfjo‰tato[adjv{¾œ¦£È¸q…ƒr’|x†“‚s‘Œ‡rroƒ{ƒtu‡tˆw“ˆyyqcw‡z€“ir„vgwucj|‚‡Ž}rt…z€’‘ƒy–Ž•ˆ‚ˆ{ˆˆkxy~ugzhlysizv€ƒ}h`w‡}jjsg{€iv€‹”~z}~p{v{t~bVw}rsŠ„‚}ƒq‡Šwxqp„‚~y~}vŽ†ƒviqimˆ‚ro]gaqmJeuK]nUSYsnbQOsx`RXX\ao‚s[a\heeckcP[pIDcaZcp^]whUVUw^[enhVk^ajgeoohpvz’niˆŒx}r{~y‚|v}ƒˆ…ƒpwƒrnwƒ‚}‰‹“p€{xyzŒtƒx‚„z€uo~Š‹›žˆ}…zw†{gt…‹z~{ˆ…ƒv€gon_d\XeYmr```plkh‰n`siY^dm€w©Ú©Ç†‡²q‰woŒu{†Ž€z“‰utu~w€pqm„t”†xuk`z‚yˆfr„pgvn[m|€“€y‘’}y{mˆw’Œ„t–Š‘Ž‡……{„luvmgvem{umjwv|`bx…yhtub}{gt†ŽŒ•{t€uqz|mYVtpu…‡yl‰†tylu€„„~{}y{s‹|sgten‹„msZi^tdGmmLZaWVUxmbPRtvWPUX^aq„o\`cmdd^obT]rGBf_]fh][{bQU\u[ZgkaVj_`nefkqhpuxŽtkŽu~vx}wƒ{s}ƒˆ‡ƒoqtqu…‰Š{wxƒ{|…‡x‡|}~„€{~svyŒŽ ‰z‰vtƒy^}…˜Œy†ƒt…†„w‰{bnm\b[[aVisc`[gnof‡qaqfW\ck|Ê·¹¡jmmŠlq„q|„‰~{‘…yysyuu|jluc„u’‚wof^}‚z‹‰fr‚kjqcXmz…›ˆs—”w|n‰r‚‹Œˆr˜Ž‘‰…‹ƒ{x}qqp}fhqbmxqjkqx}|z\dy€wiuxe‚vgt‡‹”|q‡jn}yn|]Xrnt‹|‚ooŠqvhw€w}q{u‡|zrfsanŒ‚krWj]v[HmjMUT^TU{kaOTurPQTV^bt…i\`kjfcYnaXbpGAh\`f^]V{]OUdpZ[jh]Wh`_rejgrgprw†xn•Štzw~xƒ‡ur†…‚pp{xwuz†…†Œ…z|t‹~}†„„‡~~}‡|xvyx‘“ Œ|‹mu€ycƒ†–…s‘Šo……zƒtcnjY_[]]Tgse`YdqrfsbkeW[`ix¾®{ ·mbs†hs{qy‚…{}Œwxrvo{vejn`‡uŽsjb^xy‹„gq~hjkZVow‰£„q™“q€yuƒnƒ’ˆs•ˆˆ„‰…}xtrnhy`jm`mvjgjkywzvZg}|xer}m„teu…Œ…•o‹fjzƒumub\p}lu}Œ|fu‡}nqhux~s}l{{zxqflbn‰~lmVi_vUJijOQNhMY|hbNUujLPTU^fuƒf]`phgaWi][khJDjZadWYUyYNVmjY]le\Yec^teldqgrouxp™…v~w|…‡}us‚ˆ€•‚nsy{zss…†ˆˆƒx}u~|„ŠŽ„‚„{~‹ƒ{w|wwš—zŠ‚†iv}|lƒ„’r‚p…‚~oflgW][\[Tdpd_WbruiupeebW\\hpor€s‰ddx~isusr‚„x€„ywtumkzqbgkg†tƒnf]_}p{‰~imxfidUWro¦|ƒ{v–t|s}{n||‘†w™|ˆ†ƒ†ƒ}tprlgt\lh^ltdgfizo{rYg€vtgp€wubw…Š|”€n‹jmzqfseanzgsxŠ|~bvƒvjkqu{qzyt}f~ywndfbn…|mjUiaoRJhjOKNpG^{faMUtcJNSWajv~e\gsie`VcWbp]LKkXcaUTUsVLXudZ_ka\Zce_vfmbpisnrutšw€w†„z|u‚„~—…nrt|ztq„…€y‹ut|•Ž€…„}~Œ†{~€v{£¥Šyˆ†„ku|zuƒ‹yo…sy„}ƒunjheV][ZZSbnd[Xas{ihmi`bW_[j€iko€gk`hyxjsstn„z}uunzhjyj_enhv…geXbwi~‡{oipgf]UXogŽ¨wz|Žyuppsvz€x•u†ƒ€…ˆvjrvghn[ld]ms_gajxh{m[m‚rsjo€~ywaw„„w„rˆqoyqcph\pxdqtˆ|ybs€pgjytrlxwvxdƒ{xvpdccn|}kkUhaeSJkgOGQkE`xgaMSq\JMTYekwze_mqid]V`VnnWKShWe^XMUkTJ\y_[_k]][ce`yhkaoounoxuz˜}w€z€€‡…zxyƒ~“„qttyvt„ˆ}€|ks•€{‚Ÿ…~‡}€†‚€Š{v„¬Ÿzˆˆƒkryu€tn†n|s‰€jomddX_ZYZUbjg[Z^u‚i^ml\aV\\leqt}ii\kvugtwrl…{}}yurlyhixf]erhzw“ccTepg‚…wwfhj`WVYgc§n~w€‹Žzpq}hzoz|wr„}†ndusdhh\kb]oo[g_mudzh]t€oqkq{}uuat…Šz‡‡€wruuapmZrtbqr…|ter€lal{oji{yvrf…v{zuqdaems~ilTh^\TKrbPFVaGbvgaKToWJLWXgkvzdenqfcZW]YveUJ\cWgXYHWePHbxZ]_l[^\ac^ij_ntxnonvƒ—yr€|ˆ‹…~uu…x‡Œ}suu‚yzz‚‹Ž}~„‰is–zŠ}~…zz|†ˆsq®Œ{{‡}eq‡ys|{urn†l{~lzbpobe]eVYYVcfk`]\s…hXpnZ^WZ\l{bpwvmbZlssgtupl„y~€ywnnteite[gtfvv’z_]Refkƒ‚t}bci\TX]bc¥hxt‚…xmozhxn|…{u‰s€x|xhevm`f`^j_]skYe]oobze\w{knnowxstdrƒ’~‡‚ˆzvor}sbwd[opbqq|sgr€d^nvidgy{uno‚ut}sqb_fno}diSgXXTMw_QJYXHbudaITmSJLZVilr{bllscaYY[av[SLc]XiSWGY`NGiuX^am[[_bb]…hganxylojvxm‚~€’‡ƒvt‰tŒ†sqwu‚w|}~Œ€~“~pw•ƒ|™’y€€xy~tˆƒsp™¢{z‰”xduˆxswuksn~ly|p‘r^po`gblT[ZWhcmf\\q‰eSrn[ZXX`lvciuji^Ymsqlsssi…|~|vnnldiqc[krdtvŽs[WSear€r‚]bc]SZ`[c‘žerq…„‘tlkzmop{||qwszzzdeuh]bZ`g[^vhWb]phaw`[{viirnwsrthp”‚†~„vrjp}mfwW\knbqszsfo~[`pqa_jq~llu~sqxkpa\ellzagSfTWQOu[QOXQHctb`FUjPIPZUjkk|emnqa[ZXYlpWSOfWWhSTFZ\NHrtX_cmcX``b]‹jcdmyxkoiuy†{kƒ}„™|‚„y|‡m†qowz}t‚‚|ŠŽ‚‚—tw‚“…Ÿ‰u€€s‚q‡‚uo¢—t{†‹†{ewŠnnznfwpzksvrŒk^tnagekR][UgallZ\pŒdOon]VXUgjtgbtee]Yntmpuuxj†||ˆvsddkna\nmcsx‡kZTVcdx}}q…\c_cTZ`Yc••cnpƒ…Šsjh{ofsws|lztuoz~u^frc[^VadYateU_`mdaq]]~ohisqsptujm„’ˆ{…qrfn}proS[fkfqt€vsclvUbrkZ^of}fmw}sssjm`Zdjjw^fTdTUPTmWQVSOGds_aEXiNHWTVmhd|ikwkbW\U[tdSRWhQYeTSHZZPMxvZ_eliYb`^^Žnaflyunohvvlƒ}†—{‡‰~k“ˆrgt€{u€‚|ˆŽ‹“r|Š‘…‡Ÿ†{†Œs†s}ƒvn¥Œs‹vwmzŒ`d{pfyrxlmqv‚gd{lcfghS_^Ug_lo[^nhNim`TVSogslfxdd\Xptlqzxrlˆ{vœzykaelm^`ojeqy~gZVX`lx|{pƒ_b^gWX_Wd›ˆbkq‡}wkkxm\wql{jvsno{€rXjn_Y]UbcXdqbS^ahbblZ`}kfksunmwvkh…‹~ˆzˆmqep}mrmcYaiiotts^ilSeqdUbnbzcqw{vkpmj_Xaght\eUaURNXeRO\OOHdp]cFYiMI_KXmd_xhn}d`T^T]u\TS`fN]aTSJ\YPYuu]_emhXca[^pcgjwqsngvtzƒr‚y‡~|‰‡ŽynŠtls‚t‡„†‘„•y~Œ‡‘›„€|Œ„r€stwqn““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~}~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’’’’’’’’’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’““““““““’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ>.1111/o‡„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDBN¥¯­­­®±a@DDDDCXhggggfo„ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ-h…‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR455553A©¶´´´´¸Y055554Ma____^j‚€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}z{z|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‘‰ˆˆˆˆˆ‡ŽŒ‡‡‡‡‡‡‰’“’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†…………†‘‰…††††…‡‰ˆˆˆˆˆ‰ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z{|{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘“““““Ž‘’‘‰‡ŽŠ’“Š‘ŒŽ…Š‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŒ‹‹ŒŒŒŒŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…Ž‡Šˆˆˆ‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰†Š…†‰ŒŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰Œ‰‰‡‡ˆŒˆŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}|}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹Œ‹†ˆ‡†ŒˆŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz||||}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒ‰ŽŒ‹ŒŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzzz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{y{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†……………„„„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰ŽŠ‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{}~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““””””“””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••””•“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””’’“““““’’“”““““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘’’““’““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’‘‘‘‘’’“’“’‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡ƒ‹Šˆ‰‰†……„„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxy}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzop{xy{|{xw{xuwttvtuvwuqrqnprpghklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkigfggghhgmgjghehgccbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__`c_\_]`]^Z^]YY^ba^^ZY_\XWSNMLKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{xvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSSPMJMNPROMPQQQQRVVQQQTPPNNOLJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTttuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMOPPRQPNNONONOOPQONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKLFDFJKKKHJLLLOMLLNOOOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEBA@@CCDEACEHKOKIIJHGJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AE@>:;>><ED=?EA?@A@DEGGGGBDDEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@;;><;;<<HL==AA?BC=ADDFBFFDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnpprttsqrvyy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;:;;99:88;=979;;>=;;:8:@@AB?A?CFDBCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqususqtxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<:79::9899988:9:;;8789;:8<;=@A@=;;><==@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyy{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>=;==?@><ML9<===<<<<;;:;<>=>??A@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquutusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CDDA>=>@A?>joB=?CE??@=;===<;:=>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVpoqssttuyz{{|~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???CFD@<<=@DDEmyI6:<9==@=:<;;<;89;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pprrrtuvz{}}|~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC??AAABA@AX@>[x|{yyS7:88:;=??<;;<;::;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBCA?FxXc„„„ƒ‚{_;>=?>=>CD?;<=>?==>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hloppqtuvy|||||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCDA?Jtx€‚{ƒh?A@C@@?@@>=<=AEABBFHC=<@DCAA?>=@A>>>?<>@DGE@>@A?@CFECBCC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{{|}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AAA@Ls|€{‚ƒ~……Y>CCE@??Na_J@CEIIIIMMKECFGHEGEEEDDCA?@>>BFJJGEEFFFJNNKJIGGHKMJGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@EEJp}}ƒ…††‡hAEEDCWu†‰Š~XGHJLLMOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHIHGFEFFFDFHGEEHHFHGHFQnnpqrvvy{{{z}}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJHMrƒ„„‚…‡ˆŠUAAUt‡‰‡‡†‡‚WILMLMNLJGGGGDGGGGFHFHECDDFEDDHHCCCFIKKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrswwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLLLg€„†ƒ€„ˆ‰ŒpNm„‡†††‡‡‡‡|PKLKHGFFDECC@ACCCCFFEB@>>@AA@BD?>?DFHDEGIKIIGHIGIIJJIHFJJJJIJIJJJFILLJJKKfopsrtvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKLLJS€…†‚€‚„†‡ƒ€†…„„…††‡‡†ŠuIIFB??@???<<<>::<AA@><998<<=;>;9;?ABAACCC@ABDDBCFHIHHHLMLGIJMMNMJJKKJLMSloqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHHJJJ]……„€‚…€‚‚ƒ„„……†‡ˆˆˆ‰‰ŒŽfBB=88::9878896479;<:8567789787689;;<>@;999==><<=ADEHJMLLGIHORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@CGII`†„~€‚„ƒ‚‚ƒ„†‰Š‹Œ‹Š‰Š‹Œ‰T;8656766645773468:876565676778:77789;7579989876:<@GFIFIFEFOSRSSROPPRTepqsttwy{{{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:=ECB^„€€€‚ƒƒƒƒƒ…‰ŠŠ‰‰ŠŠŠŠ‹‰‰ŠH676468874578467699766765:9:::<898977779:98878589;A=>>BA?AKLOQPQOOOQWkrrttuwy{{{|}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897;B:<j†‚ƒ„„„„„†‰ŠŠˆ‡ˆˆˆŠŠŒŠ‰‰Œz>:88;<=>9::;89;9:;:99;:9===?;;;=:>;9;;<;<<9;<8::;:999<?<=ABDIJMKJKLWorsutvx{{{|{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<;89989:::;?>Ez„‚„………†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>BCEEAA@B>@B@@?=>>@?>?@?@==?B?AA?A?=@@@??A=><;:;:9;?=;;==AACABCAXqqtttvy{{|}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::<=:;;==?@CPƒƒ„…„…„†‰‰ˆˆ†††‡ˆ‰Š‹‹ŠŠŠ‹Š‹^>DGIKJIFGGDFHGEC@@CECB@BCB?@DHECEDEEAFEFEFFD@B><@>=?@>???>?>>:;=<`qrttuwzzz}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>???=A@CDFVƒ‚ƒ……†††ˆ‰‰ˆ‡†††‡‰ŠŠ‹ŒŒŒ‹ŠŠˆWGLMMKNJIKHIJJIECDFGFDCEFDBHIKHGGFGGEKIKIJKJCFCCDBAACBDCCDDCA=;=@hpsttwwzx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLK@BBA98<>;<;>@@A?BBGGJY„‚ƒ……‡‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹‹ŠŒPMPMKNKJLIIIHJFDGHHIEEHFFELLMIJGGHIJNMNLLNKHFGGEECFFFFDEHHFCA?@Llptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?FGG=<@@98<;<=:?@>@@CFIIP`‚ƒ…„…†‡‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒ‹ŠqMQOMLLKLJHGEJIDJHGLJHJGGGKLNLLHHIJMPNPNMOKIGIJHIDIHHFFGGIFCBACUnquvwy{xyzz||}~~~~}~}~~~~~€€€€€€€€€€€€€TDAABGHB?8?@9:<8=>;=A>?ADGJLVrƒ„„„„…†‡ˆˆˆˆˆ‡†ˆˆˆˆ‰‰ŒŒ‹ŒŒŒ‹‹‹‹^QQPMNMKJGFCGJGLJGKOLKJJMMLOPNHIKLOQQPQOOJIJJLJLFGHGFGIFEEB@BB\orwxyzyyyzz{{~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<9@>>@BGGAGKLPWy…ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹‹ŒŒŒŒ‹‹|WURRTROLKJEEFKONOWVQPOQSRMSTOMSLPSUWRSQPLKMMMKNGGJFFHJDDEEBDCcpuyyzzz{z{z{|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?==B?BCFVNFMOPTY|†ƒ……„„‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŽ‹‹‹gVVkaERQQPJ;:QSR`u]UVTVYYRXXRZfPUWZ]RTWQPNRPPPQKKKGHIHEFIHIHIjrvyyzyz{{|z{|}|}€~}}}}}}~€€€€€€€€€~~THJIIGGFE??AAEBCGEDELXRMTUVX[|†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ}aŠ‹‹‡l[dU:XXXSP>@VUY\d`VYbr^]V]ZVEQYZ[Y_TYgRUVXTTVSOOMJLJIILMKOMSosvxyxwzzz{z{|}|~~}~}}}~}~€€€€€€€€€€~~~VJJIHGFDDBA?HMIMPKIKPTSSWZZ\\x…„…………†‡‡‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~Œ‰Š‹znpXZ[ZRSRVVTZZuƒYU}a\X]^WIV]][[_YHYXY\]XXYWRQMPQMMOSQQURassvwwvxxxz{{|}}}~}~}}}~~€€€€€€€€€€€xy}YNKIIIFBD@A:PQQWXPPOQSTTWXXZ[n‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡ƒŠ~fYY\XSVTWRQWVc–€QerXZW_hP`fZ[X\hbGOZig\[\]]WSNSPPQVVVVYZnrtwvvtwxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZ[RSQORRQUSUTW_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PVXTRTRQQLOMKfyZ]TYUV]ZLTZUST^ZXWWWzkXZ\\^SPPPINOWVX[Zdqsvvttvxyy{{||}}~}}}~}}~€€€~~zxwvsu{€€tk~~kry^[VUSROKFCDAM^ƒlVRSNOQOQURSRRTcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ymqVIKNNKMKHJDFHEC>ScURQQNKRTRMOYQMNQSUUMQSRPNLLHCIHRSTZ\mrvvussw{z{{{}{}}}~}}}~}~€}}~~€~{vsw}~~du}iqt_d]^[YUQLILIal’tPQSNQRQR[RSRQRUUbs{|€‚}{{€ƒ‚…†‡‚†††„†…†u_]KC>CCCCB?DPBD@C>BHGV@HNMG]iPHFOFDEFHGHBCHGHJGCBAD@OPMSdsuvustuz|z{{{||}|{~}}}~~€€€||}€€€}vt{mh|gnqfieeb\XSQPURsWe[OONLQSQUYSUQQTROV`klrv{{xyurnstsyx~~ƒ€ƒƒ‚€‚€‚kLG>>:;>@???>kQKaEFHIEB?GLMGMQUIBE?><=<==?=?ACB?><=B>JMFUnuuustvx{|z}||}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QQZ\Y^IJPQNKLQRQTUUWQQWVPX[b]agmmlokh`nrjmlqu{z}zxz||xwxdB@@A=:BCAADB\]O{NOONKLMOOQLKLWMHG@B<977599=;;;8989?;AG>\tuuvuvwy|||}||}}~~|}}}}~}xuwz{zwyxuw{|yxuywcqhipmnmmhf^OP^\ZIGPRQOMPQNQRTVXSRYTNYZ[WY]^^`e`]^qvk^`gkwooljonnlfbYGFFHBAFIEEFDMRPaWRXQPSSRU[OOQVPMICF>::6486979:366796<B=ftuvwwyy{}}||{|}~~~{}~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZWMLTTSQQUOLRSTWXTTXQLXYZVXXVXY]WWXhsk]V`tkaa_]d`_^YUPMONLIGJKIHFCQPSZWTTMQSYS\eUOSTQNKIHC?A9988978847578588Gnruxxz{{}~}}|{}|~~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPXVVSTVOOUVXXYSUTLKTUUUUWPTUWTUR]n^RNY`[VY;DUWT[fJLPRROMMNNNLJFPPUYSTNJNOTST\VRUSRNMLIHHF??=:787659967665Wqqtwyz{|}~}~||}|~}}y}}|~~~}||}}~}|rvqxxruuqqnppopuvtnjddjppqrpnfedc\^RTZVWUTWTRXXYYYRUOJGPPOOMRJOPPPNNOTLMIPPSTU2<XMIAQ=c`QSQPNPQPNNMPNTRPRLILKOQPQRSTQROLMKLLHCBA=:9876;B4566;eprvxy{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqpuuvcjgeWhtrrqniihpVVTUXUWURWVUZYXWUQSFEAFGGHFJDHJHGEHLHKIGLMPMG/E_R>3@>joaRRQ@FTQPQPQNQOPOLJLLOPNNPQQNQOJLMMKGEEDB;=<<9=G6676Dnquwz|{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknbePSTRSUOWVVYYVQQQO@>;=?@BAC@BEDA@GHGHFFHJMLDGCORC8ENS]fRQSAGUPOQQPMMNMKLKLNOOQMOOMIMLILKLKGFFED<AA>;@E;<89Tqsux{z{|||{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLONMQSLTUTWWULLKH=987;?@?<=A@B=>EHGDFFIGKJ@FAA@FHEJOHPQa\QPRNSOOPLLOMKMLMON[VKMQOHJHCIJLLKFFFD?BC><BG?B?Adqtwzz{{|{zzw|wy~~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCE=9879?B>;>A@@>ADIECHGIGIEBB?><CBAGIDMOaePLNNWKLNKLMMMLKNNSdMJLRIIIEAHJLMNKGIFBAB@?EFEHDKopwzyy{{z|zwsxtx||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGLMIMPMPOGKE?B=999:?B?<ABBADDGKFDIIGGHCC?B??@A>CECKNQTKJHMTFIIJLJKLIILMOPRPKGCLGCCJJLMONIJIGCCCDIJMLIZsmxyxz{{y|vrpurtyyvxjqnjllnttmsu{stxronqovsnporpopstyjN`gsjt|ygosqjqheqHKCFHHGJKIJLDGB=>=:::;AB?=BBCCHFJLJEIIFGGCC;A@B>@@CECIMOGHKGHKDHIKMHJLHHJLKM]RIHDNGBEKKNMPNKMJKFGGJMNQNLcniwvw{x{z}qmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoijthdoFKCFEGDEEFEGCC@><=:;::@D@>BCEEIFJJLFIIGFFDB;BCC>@CCCEFKMHKNHDHEILNMGILGEFIILNKJHEOICGMMNMPNOOMLIHIORQRNRfgfrosxu{z|lhjoekpmsqfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGICEFEBCBE@DB>?>:;;=;=?CA?ACFGJGIILHGGGFEC@=DEB>ADCCEGHIGMPIFFGKNOKFHJFEDDIIHKIFHPKDJMLPNONOPNJJHMRUTROWdaamgprosyzgehhcilgqlflmgiklslpvutpnvrosrsutqssutsuvvvyvutvlkuumrvqlnlerMGEEGCBABD=BA>A=::=?;>>@B?@BEGJFJGIGFFFEDBAAFFCBBBDEDGGHFLPLIOJJLKIGHEFEDCIHHKJGKRMCOONQPOONOOKKKPUWVUTX`^]iaminhrsbeffdihfnifmmhkkmriqvusqmvnoqrswsrstuvvvvwvwvvtwuksunutsqrkksMFFEHBBADD<AA@C<89=>:?=?B?@@DFHEHFFGFFECCEBDIFCFEBEGEEFGEIMKHQMJKHHIEFIHECIIJKMKPSNDQSQQRNOMNPMLNSWVWXVX^[]d`hbjigk_defcgggkggkmkmlpqgttursnvoqprtxqssuvu‚‘yvvtxuuwxnouorsuqqipzMGGGHBBBFE<@CBD<7:=>;>:@B>??CEFDFDDGECECDEFFJEEIGCGHFHFECFJJGMJLKIJLFIHKHEKKLMNORTOISUTQTPQMNQNMQWZVZYVZ^ZXa```_hec`deggjihjfhnllomqpiuuxrrpupppruvpusuvu{~}xvtwvvvwplupmsunorsyMHHGIDACHE<@ECE=8:>><<<AB<?>ABFCEBBHCCDEFFGGIFGKHCHHGIGFDHKIGKHMKJKLHLJMKINLONORUVOKUVTQTQRLOQPOTYZY\ZY[__^`c^\ackb`dghr…hgifjmnponsqjtuxrsstrnpqvrquruus~yŽ}uuvvvvxriuqkrtlqwquKIKHJEBEGE<@GDD@9<>@?>?CB<@>AAFCEECHDFDGFHHFHHIKJEJHHKHFFLHHHJHLLLLLIMKMMMOLPPQUVWOJVVUSSRQLORRQVZ[]^[\^``a`ad]d`ef`ehjcssfjhglprqossnswwpuvtsmoruorspurvrtvuuuwvuwtgtrkqrkrwowIJLILGBEDE<@FDDB;??A@@@DA@B?ACHBEEFGEIEFEIHFIHJLHHJJILJFJKHIJJGKKMMJJMLNNNOLOPRUWVMNTVUSRQPMNTSRW[^^_]]``aaa`bdebchbdijgv‹lkigmosqpqpprywruutsmmssmqrotutspsvtuuwvuuteqskpqjrvowJLLKMGDCAD<?EEEC=AACBBCEACDAAEGCHGHGFJFCGJGGJFILHIJMKMLGKIHLKNQKRQLSMKNNOPPPTOWXX[NSQW\ZSVPNTUTTXZ_bb_da_`b_`eaacinhbihhmxvlhimosrpqrrrvtsusssnksqmprotvrrquvuswywutucmtkopjqtpwLMLLLGDA@D>>DEFC@CAEDDFCCEGCBIEBHJIHHKFDKJGHIIIKGJJOKNLILHJMKZfJd\KlRHNN_nUls[qpbwcRPbvuhucav`Xnqbdvinzf\lt`ljT_wvijgifglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqsqyKNJKJFB?@B?=DEFDCDBEEDFBFFGCDJEEJLLJLMGGMJHJJHKJIKJNLMMLLILML[sbdp^llUMNfs]geqlntgpi_aYnmbppbkjjgoqtetno\pugpMJryvkb`keemxmkvlnpsrprqpqrqrrrtrmmsnnoprutqsstuuutwxvutbmukpplrrqzKLIIGED?BB?=BEFBFCEDEEDCHHGDEKGGLMMJMLFJNHIKJIKJJJKMMNMMMKNMM[roonpplkMPQlWNibtrpamov\YlP[mmZqmkomxxtsip\`slqjUuyxpc^kfbgppjioppsspqpqqrrqqrrtlmrmmnorutqtrtuutuuzvutenukpolsrryJKGHEEEBBB=??EGBGDIEEDBFIHHEGKJGMMNKMNGLNILKHIMIKJJKOPNNMLNML\hdu]lqWlNOQmUZk^klvaldtTecNlYl\tpkilxjwuhp]_skhWbcw|oc`ggadityknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtvIMGIDEECAB<B@BFCGFKGECCHKHHFJLLFNKLRRLGMMHNJGHNHJJIHNONNLJNMJZsppoqqmlOQRnYqkgooqqomt^nXat_nopoqronusttj[]tcwxrjnzhaacfbbjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyytukoumtonssvtHKHIBEEEA@>CCAECHIMIFCFJLIGFJMKFOJKWRKGKJJNIHJLIKJIHJLMMLIKKKSkbZi^_jcrrZ_Yjo_eeUk_c[abQ`mh\j\niid[pfdp]Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunwqrutwrHHFIDEDFA@AEDCFBHJLGFCFKLIEFJOLIOIL[QJFHHKMIHJIKKIHJGKKKKGHJJLLLKIKLNT[\TPTMPONOOVQOOQOOQJJNPQdqiTYW[[\UY[]X]\\cfaafbce__fkmhmtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyyxuvqruovrtsuusGCEGFFAEC?CGDEGCIKLHFDGJLHDGIPKLOKLWMIEEHIJHIKHLJHFHHJGGIEFLHIKNLIO\W^O\[`^OXYS\\b^MYZMXaRKYaZS`d]bX[ddVVX\YZX\VY\^c_d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtOBCDLMBCDBDIEGGFKJKHEEJJJGEHHPJLMJMSIHEAHFJIKKILJHFEJHEFGEEJGCJMJKT_Y`X`a[`UXYT^^Z_RY\P^\YN_\^S[^c_Z]`c`Y_b[`^[TXXZ_^dbbaceiekrpoppnow††……†‚{€……††…†…uqprrsvyyzyyxxxwryvxrqxvtvaSJJMIECBCFGEGGIJJIIDFKKKEFHINJNLHLNGHF>GGLIKKJKKIGEIEDDEBFJD@JKIO[cY^^a_RTSW_`\]Y^QY\MV_WKQY[Q[_aa^^ca`bbbcceZRYVU\[^c`__cebhommllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxXQJFCGEBEGHFGHIFGJGHFHKILDCKJMMLLHJJHJG?GFNJKKMKKKIGHDD@DAHIA?HIGO]aZ[d]_TQRX]\\\_ZKW\LR\YIM^PP]_acdccb\dcbdcfXQUTS\X[a_^_aa_dlkmjjlnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMB@IFCFKIFFGHGGJFFFILJNECKJLNJLIKJHIGBHHQMKKOMKKIHGED?EBHHAAFFDT]Y^X_Y_[]UXXP]]QKJW^X^[]VZ`RQ__aba`bb`cbbddbXOQRR[S\^]^^___dhgljnnp{{|~{€‚ƒ„………………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKBAGFDGMRHCRKFHHHEFKJMPEGIIKNLLILKIIGDHKQOMLPLLKKHICEAECHGBAFEBVUE\T]SV_XNTUNZ[MJKU`a[_X_^a]OYb\``_bcb]bbW__TPOPQXR]\\]^_`affelfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDFFGDIRcPDW_IGGHDFMJPPFJIJKNLKKLKJJGEJMQQNOOMNLNHKADACDFDCADEALHCLLPOOLFMFGIJHGLLMOQILOPPSPLQSRUZYWYXXdVOSTPPONPUT\YY[^^aaefchckmqsszy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKM^LGHYMGHJHGNLQQILJKKNNUNOKKLGGKPSSNPONONOHKE`ED_LDfcDM[H^\smOMVmYLCP_UlWgJ]XV^DLQULMTVQRTXWTXUT\TPfZhhdYTkTWVU[\\``abbb`gignlhrz|}~„„„„ƒƒƒ}}zr{z{‚€ƒ„„……„…ƒƒ~z{LIEFFHEEKOTIKG`THJOJIOMRQKMKLORUROOJLMGHMQ[YOPPNOPPJKPQI|YYrsXPmHqnoaVPqqsPCksmqspSo_[nX]V\XUkhU]VcZ`YZ_VUWjtuu_av_Xb\\f[_aaab^`bgmpl`pwtx‚ƒ„‚}~€vxzlv~tx~€|~€‚„|€ƒz~wwNIEHMMBDLLGILFRVLKOIKRXWQNOOMQTNOQPKKNGMPS[ZTQROPPPKHZx]TxdhYRTQvgtlpbnfkQrOMwmjrpsrqrpop€]ezuxqqzq~s}ku}bRh|essoss|}o~yor_``baZa`gknkblfgmw~€ƒ~{xw€tvzir~nt|~wx{~€ƒx|u|||ssNKF`]GAEMMHKKHJPOMMJNV^YULQSNYYLSSRNLPIQRTYWWQTPPPQKGfxlcxqmZJLUypumubnvPdeJfvqmwo€jfxxiWrQhzmijzz}lxzpgoXvvjvup€ash}ilx|o___cb[^bdgijdgbcdllppstsssyqrxbltgry{ssuy~suzn|}yxrnNJRtNCBEPPIKKJLQOOOMPZ`ZXKTWPa^RVQYSMPISTUXWWPUPONRJLrouuquqdhaVnLqp^FhyWvTKhx}x`y{sna^modRgrunmypwlvstqlm\s~zkmy|lum|kpvux^__b^]_edighee^bbiiijknokqnmjpacfdowxompsynqpj{ztromKKZVHGEGRPJLMKLQQPPPQW\YUNVYUfXRRY^TMNITTVWYWOSNNNQHRmHiwK`dvvUWlOnl{sajgvUKWkh}lmlx`[pz{^`zscroxqhd|ir{]TKl_vukiu{{m~xk|p]^^b[^bdegeeebZccikkrsrwgmihdg`alagsrkhlmr|kmhk{tmmkmOGJKHJHHRQLNPMLSSROSSWRVTPWZVVTTTa`QONKTSSQVVONLMOPJHQNPULKKSTRRTPVUQQNQQXXQNPUTXXX[[USSW[WXWZPSUWWXQ]XV]USOXRWWWXZ`[gr^[\[]^_cZ_ccefdccbZccfffmnmuffgc`f_]g`dlhfgkhpzhggkujhgilQIKKLMKJTRMQQPLVUTPTUXUYURZ]VUTWUYXPOLNWTQNUSNPMLQPKJQRKQMKKOQTRQQSSIHMNOQRQQQTVRXW\WSSPQUUVTZQNSRWUTYVTYUSRUSTUXYW^Z_a]\[Z\\`c\]bbdgeddaY`acabhhincad^_c]Zd\bma^ffgmsdihkkedcfhPJKKNOLMTQOTQQMXWUTUWWWZVT\`VWVYUXTQPKOXSPNUPMRNKSPMNUTNQNMNQSPTQSTUNKMOQTTRRQVWUYZ[YSURTWWWY[SOSUWUTYUVYTRRWUUW\YZ`]VY_]^]\]`a^[bbchfedbX``b]`hefda^_]]^ZZ_Z_g`^]]chkagfhfd`bcaPKMLPQLOTPPSQOQZYXWXZZXYV]jdVXYZWVTTOKOVTPOTPPQNMQQORXTRQOMOSUNWRTUUONNQSUUTTRTXVZ]\ZVVQRWXV[\VPSVUUVXTWWTRRXVUZ_Z^`^V^]^`]\``__ZbbdhhedbYb`b^^fdc`b]\\\\YZ[X[a[^]\_b__bddbd__`\PMNNRQMRSPSTQOU\ZZW[[\YZ[dqmhd_[YVVXRMMVSMNROQROLPSRUZUTPPLPWVQWSSSXMOPRTXUUUSUYX[^]\[VROUVV[[WQSWUVXUSXZTSQYWV\^[__`Ua\`a^`b_\`]cacgide`Zc`a__ee_`c[Z\[\ZZYYW\Y\[`^_[^^a`_b\Y`ZQNONVQPUSPUTSPW\\\X^\_W\^jpwyc\[VVXRNOWSNQQPRTRLQTSYZWUORNSWVTRTRRZOQSSV[VVWTVZX]^\\^VSNTVV[[VQTVVXYRSY\TRR\XZ]^]aa`Wb[cb^ac_\bab_dgidf^\d`a`acd_b_YZ^[\[YXYWWZ[Za\][]\\Z]`W[[ZPOOOYPUUSRWRTPZ]^][`\`U\]hjr}rlh\UYWQOR[SRQTRTUTKRVU[YZSOSRVUUSNVRSZRTUTX\WXXSX\X^]Y[^TUNVWW^ZWQTUXXXTVX[TSV]Y]]a^cc^Y`[eb_dd^^cca]efidf]^da`abcd_b^XZ_[\[XXXXW[Z\`][[\[XZ[^V^Y]POORZPZUUWVTTT^^`^^b\`U]^bkytl}lZUZUQQS\TTTUTVYWLRZV][\ROUSXVUSPWRSWSWUV[]X[YUZ^W_^Y\ZRWRYXY_ZYSTVZYZVWY\VTZ]\^`a`ed]^]]eabfd^_dc`\gdhedb_da_a`bb_`^WX^Z\\ZYZWV]Z]^[Z[\[WY\]VXW]SOPWYP]UVYWWUX_`aa`c]`U]^beeuzhXYZTVSV\XWWVVW]XPU\Y^]]TSXRXVSRTXRSVTXXX]^X][U^_X__X\VRYUYZZaX\UWWZZZXYYZXV]^_^cbbee]b\`fbefd_`dbb[fchecfaf__aaaa`_^VU]Y[\[Y\YY][[[XXY[YZZ]_]TY]UNSZVT\TVWYWV\`abcad__V[`da_zuohZ\ZVXUW[ZY[YXY`WPU^[`a\TUXPUVUSVVRSUWZZ\_^Z_\V__Z]^Y^VSYXYZ]bY^VWZ[[[ZZY[YY^_``dcdeebdZbfcgfe^ac`c^cciddg_g^bbcaa`^_XTZZZ[[X[XX\[Z[WWZXW\[\`]V]]SPVZVVZUXUXWX^`badada^YYadb`lfh^\][WXXY\\\_[Y[bVTW^]ac\SVXPVVVVVVSUTX]\_``]`]W`^[^\[^XVXX[[__[_XX]\]]^\Z\X[_a^`dcdfffbYceehgd^ca`ec]fideh_g^cbcaa`__[XY[YZZXYXW[\Z[WXZTY]\Z`\U^bMRWYVWZY[\YWY^`baeada]^Yacb_a`a_\\]XW[[]]__\Z]cXYX]`cd_RXYPXVWXXWVWV]]^`aa_b^Ya]]^Y]^YXVW[\`^\_YZ^]^^a][ZY\_b_bddefggbZdfgigc_c^afdZhicfice^bbca``_]]ZW[YYXXZYWZ[ZYWXVU[]]]``bbxKWW\XW]\\]ZW\]_`bdbba]`Xbcb`cac^\\\XW[]_]`_][`d\\XZcecaR\YOXWY[ZYWZZ`]`bb`ac_\b]_][_^YYUX]]__^_[Z^^`bc\[W[]`bbcedgfegd\efhifcab\cg`\iibhife`baca_`_]]\Y\YXWXYYW\[ZWWXPXZ]acffrkJYW]ZZ_]\^\Y][^_acbaa]b[bda_cbb]\[ZWXjq`\`_]\ac_^YYcedaT_ZQYW\]\[Z[[c`cbc`bda`c^`\^__ZXV[_]\aa_][`abeb^\S\_`cddfegfefe^efhhgdd`[fg^ahhbhhfc`b`cb___]][Z[YXXXVZV\ZZVVULXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡…‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vvvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{{{{{zzz{{{|{{{{zzzzz{{|||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vvuvvvvuvvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{{{{{{{zz{{|{{{{{zzzzz{{||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||vˆ‹‹‹‹‹‹}}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰ˆ±µ´´´³µ•‡‰‰‰‰†³ÖÒÒÒÒÖº}~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}vŒƒ~~†“y1333332j‚€€€{­éääääèʉŒŒŒŒ‹‘»À¿¿¿¿ÁšŠŒŒŒŒˆ¿éååååéÇ}~}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}vxxxxxxxwwwwwwwxyyyzyywopppppprrrrrrrwzyyzzz~ƒƒƒƒƒ„||||||}€€€~||||}|„„„„„…‚|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚‚‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vvvuuuxvvvz{x{xwvx{wyzz~|yyxxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{zzzzzyzz{{{{{{zzzzzzz{||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwwy|{|zy|{xwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwww||}}y{zxxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z|ywwwz|||z|yxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚ƒ‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzzz}||}z|xxxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyy{xz{yyxxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxxyyyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{|||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}|||||||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}|}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚€€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrstuttssrrsrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqstsssrqqppnnnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqqrssssqpqpoonnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrqrrssrrqppoopoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpppqrrqqqpopooppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqpqqqqqqpooppppppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqqqqqpppppppppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsqu‹‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqqqpqqqqpqpqpqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrqqqqqrqqqrrqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrssrrrrrstrrsrsssssssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz|~~|vvwwvuxzxxxxwwwvx|yy|zyy|{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~|{{z{|{}|{{{{{{zyxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}|||~|}~~~~~}}||}ƒ€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€€€€‚€€~~~~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~~€€€~~~~}~~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~~~~€~~~~~~~~~€€€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹Š‹‹Š‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚ƒ‚€€€€€€€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒŽ‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒ„‚„„‚ƒ‚‡ƒ‚‚€‚‚‚‚ƒ‚‚ƒ‚ƒ‚ƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒƒƒ€‚ƒ‚…………††‡†…††‡‡‡†††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠˆ‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„ƒƒ‚ƒ…„‚‚„…‡‡‡‡††‡‡‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ’‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„„ƒƒƒƒ„…„„……„ƒƒ„……‚„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘’’ŽŽ‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚‚„‚‚‚‚‚‚‚ƒ€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„…„„…„…†’“‘ŽŽŽŽ‰ˆ‡„‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~€‚‚ˆ‘‚‚€€€€~€‚€‚ƒƒ€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“’Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚‚‚„‚‚ƒ‚‚‹˜‡…„‚„‚€‚‚‚„ƒ‚ƒ‚‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘ŽŒ‡…ƒƒƒ‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒ€ƒ‚„…„ƒ~|ˆ›‹ƒ„…„„„‚€‚ƒ‚‚„ƒƒ‚‚„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”“’’ŒŒŠ…„„ƒƒ‚‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~€ƒ…~|~™‚‚‚‚€‚‚‚‚‚ƒƒ‚‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†””’”’‹‡„„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~€ƒ–Š}€‚Šƒ‚„ƒ‚‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“‘Š†ƒƒƒ„‚‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€€‚š‚‹‚‚ƒ€„ƒƒ„‚ƒƒƒ‚€€€‚‚‚ƒ‚‚ƒƒƒƒ‚ƒƒ„‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†„…ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„‚‚˜Œ„…‡‡}~€†……„…‚}}}‚„ƒƒƒƒƒ„ƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„„†………„…†…††…………………………††…†††…†††‡†…………ƒ„„„‡““’‘’ŒŠˆ…………‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…„ƒ’ˆ€„~}…‡†ƒ€~~~ƒ„ƒƒ„„„„„„„„„„„„………„…„†……†…†††…†……‡……†…††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„„†ƒ€„Œ‚~}}†~€„…„…†††…………††‡††…†……†‡‡‡ˆ‡‡‡†††‡‡‡†††††††…„ƒ„………„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘“’‘‹ˆˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒ„„ƒƒ‚€…„ƒ‚€~~€€€€……†‡ˆˆ‡‡‡‡ˆ‡ˆ‡ˆˆˆ††‡ˆˆ‰‰‰ˆ‡†‡‡‡ˆˆ†‡†‡‡††…„ƒ„…†…………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†…†„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡†…ƒƒ…„„„ƒ€ƒ…ƒ‚ƒ‚‚€€~{z€†ˆˆŠŠ‰‰ˆˆ‰‰‰‰Š‹Šˆˆˆ‰Š‹‹ŠŠˆˆ‡ˆˆˆ‡‡ˆˆ‡ˆ†‡†„ƒƒ…‡‡‡†……„„ƒ……„……†„„„………†…†…ƒ‰”“‘ŽŠ†…†…ƒ‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡†„„…„ƒƒƒ€…„„‚‚‚‚‚‚‚€~|}}}~|{|ƒ‡‰‹‹ŠŠŠˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰‡†††‡…†ˆˆ‰ˆ‡†‡„ƒ‚„ˆˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚‚ƒ‚„ƒ„ƒŽ“’‹ˆ…„†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„……ƒ‚„„ƒ„ƒ‚‚‚ƒ~}}~~~~~}}~}}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡‡‰†ˆ†ˆ‡‡‰ˆƒƒ„ƒ…„„……†ˆ‡†…ƒ‚‚ƒ…‡†‡††ƒ‚‚ƒ„‚ƒƒ„‚‚ƒƒ„ƒ„‘’‘ŽŽ‹‡„††„‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…‡ˆ‹Š†„†„‚††‚‚ƒƒƒƒƒƒ‚‚}|}€~~~}|}}|z|„†‡†„ƒƒƒ„………ƒƒ…„„„„„„…„‚‚ƒ„„‚ƒƒ…†…„‚‚‚ƒƒ…ƒ„„…„„†ƒ„„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰†„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€‚€€ƒƒƒƒƒ‚‚}}€€}~~}}}}zzz~ƒ„„‚€‚‚~‚ƒ€‚‚‚‚ƒ„€€€ƒ‚€€€€€‚‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†‹“‘Ž‹ˆ……ƒ‚„‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€€ƒ‚~~~~}€‚ƒƒ‚ƒ‚ƒ‚}}~~€€€~}}}}~}|zzz‚‚€~€~}€€€€€€€~}}€~€€€€€€€€‚€‚‚€‚„ƒ†’ŽŠ‡‡†ƒƒ‚‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒ‚ƒ„…€€|}}~}~~€€}~}~ƒƒƒ‚‚}}~€€€~}}}|{{{zzyz€€~~~~~|~~€~€€~}~~}|~€~~€€~€€~€€…’’Ž‹‹‡‰…„ƒ‚‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~~}~€€~€„ƒ‚€~}~~€€€~}}}}{{|zzyyy{~~~}~~€€~€€‚€|~~~~}|€~€~~€€~}€~~~~~}||}…“’ŽŒ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒƒ‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚‚‚€ƒƒƒ€€}}}~~~~}}}}}|||{zyyyy}€€€€€€‚‚€~€~~~~~€€€€~€€~~€}~}}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…ƒƒƒƒ…„„„„„ƒƒƒ„‚‚‚‚‚~~}}}~~€}}}}}}}}}{zzyyyy€‚‚‚„ƒ€‚ƒ€ƒ‚ƒƒ‚€€€ƒ„‚€€€€€€‚‚€€€€€€~~||Š“Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…ƒ„…„…†…†††…†…ƒƒƒ‚‚€}}}}}}~~}}}}}}}}}|{yyyyx|‚ƒ„…‚„ƒ‚‚ƒ…†‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚‚„ƒ‚ƒ‚‚‚‚€€€~Ž“Œ‡ˆ†ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€€~}}}~~~€ƒ„‡ˆ„†††…††‡‡†‡‡ˆ‡‡‡†}€‚~}}}}}}}}}}}}||~~~|{yxwxyy€ƒƒƒ„ƒ„„„——ƒƒ„}~‚‚‚‚ƒ†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ…„„…ƒ‚ƒƒ‚ƒƒ‚‚‚‚ƒƒ‚‚’‹ˆ‰‡‰‡††„†…„„„‚‚‚ƒƒƒƒƒƒ‚€€€€€~€€€€€€~}~~€‚………††‡‡†‡‡ˆ††‡‡‡†‡…~}}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yxy|~‰–„ƒƒ„„”“€~~…‹€€€„†‰…„‚‚……‹ƒ‚……††„ƒ……ƒ„„ƒƒ„ƒ…„„ˆ’ŽŒ‰ˆˆ‰‡‡‡…†…„…„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„ƒ…„~}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|xyz{|€‚ƒ€ƒ‚€~|~~{ˆ‘||Ž–}‚†Š…ƒƒ„ƒƒ‰~ƒ„……ƒ…†…„……ƒ„……†„„Ž‘ŒŠŠŒ‰ˆ‰‡…†…ƒƒ‚‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚€‚€~}}||}}|||}||}|}}}|||{‹‘—Œz{|zzz{|yy}}~€€|{{~~}‚•‘„ˆ~|~‚„||‚„‚€‡ƒ}‚‚‚€ƒƒ„„„„„‚„ƒ„…‚„‘‘Ž‹ŒŒŽŠ‰‰………ƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚ƒ…ƒƒ…………ƒƒƒ„‚‚ƒ‚ƒ‚‚€€~~}~}||||||||||||||}|||~~Š‚{z{zxz{{|}{~}~}}}}||}†~}‚~~~€‚||‚€‚€~|{Š‚}€~€€‚‚€€€€‹“Œ‹Žˆ‡‡……„„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ…„†‡„„€†”ˆ€‚€~~~€|||||||||||||}|||||||y{{{xxy{zz|€~|~~}€‚‚€€€‚‘€€~€~~~€}}}{}}}|}||}€€€~€~~‚”‘ŒŒŽŠ…††…„„…ƒƒ‚‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚ƒ†‡††~ˆ•Š~€€~€~~~|{{|||||||||~}|{}|||{|||zzy{|z}…ƒ‚~~€~…‚~€~~€…†‚€~~ƒ†~|~€€€~}}}}~{|}€}~€Œ‘‹Ž‡„††…„„„ƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}~€‚ƒ††……~€€€~~}€€€€}}||}~}||}}}}}|~|}|{}||z{z|}}†„‚€€}~}~~‹„†~}||~‚}}}}€|{}|~„ƒ€~~~~}}}~€~~~„’Œ‹Ž‹Š†„…„„ƒƒƒƒ‚‚‚ƒ‚ƒ‚€}|||}~{{}w~vx~}|}|}~~‚ƒ€z}}|~€~€~~€€€€~~~~~~}~~}|~}~}}|{|||z{z}~€ƒƒ‚~|}|}||ƒ~Œ~|{{}~}~~}{{{}|z{{{€†„‚„ƒ‚€~‚‚‚‚‚€ŠŒŒ‹‹Šˆ„„„ƒ„ƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€~€€€}€~~~~|‚~~}}}{{}}|z||~€‚€€€||}|||||}|}{~{{{|||}|{{{{||zz}z~‚~ƒ„‚ƒ…†……††‡†„‘ŽŒ‹Š‹‡ˆ…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~€€‚€~~€€~}ƒ||}}|}}}}{|~~~~~~~||||||{~~{|{||||}|}|~|}||{{|y{|{{}{}~~€€ƒ‡‰‰‰‹‰‹‰…ˆ‘‹ˆ‰‡……ƒ‚‚ƒ„„ƒ‚‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€€~~~}€€€€ƒ‚€€€€€€€€~|z|}}~}}~~Œ†}}~{{ƒ‚}~~}}|}}}}}~|}|}|}}~|~}}}}|{{z|{||{z{{zzz{~~‚…ˆ‡ˆŠ‹‹‹‰ŒŽ‰ˆ†…„‚‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„„€€€€‚~}~€~{~‘Œ|}Š€Œ~~}}}~}}~}|||}}|}|}}}~}}~~|{{{||}|{z{|yzyxy{~„ƒ„‡‰Šˆ‰‹ˆˆ…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{|||~~}}€€€‚…ƒ„‚‚‚‚€€ƒ‚€}~€~|~ˆ‚~ƒ„„ƒ~}|‡}}~}||~|}}|}}~~}~}}}{|}~||{|}zzyyyy{{~~€ƒ‡„ˆŒŠŠ†…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{|}}}}zx‚€‚‚€€€€€‚‚‚‚†…„‚ƒ€‚„~€}~~}~€€}~„€~~}~}}Š…}~}~~€}}}|~~~}€}~}|}||{|}{{{zzz{{|}~~€ƒ€‰Š‹‡………„ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv~€ƒ‚‚‚‚‚ƒƒƒ‚…†„‚€€€€‚€ƒ~~€€}~€~}~~€€~€|€~€~|}}|~~~~€}‚€|}€€}{}}}||{||{{{|{|||}|‰Šˆˆ…………„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€ƒ€€€€ƒ~~€€}€}}~~€€‚€€€}€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{|~|}|||{|{|}‰…†……‡…„…„‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz~}yxut€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚~~~€}~€}}}~€€‚€€€‚~~€€€€€~}}}~|~~}}„€~}}}~}~~}~|{|z|{z€†‚„„…„„ƒ…ƒ‚‚‚€€‚‚ƒ‚‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xyuu}‚ƒ‚ƒƒƒƒ…„…„ƒƒ„„ƒƒ„‚€€€~}}~€~~~€}}|}}~€€€€‚€€€‚€€~€~€€€~~~~~~~~……€€ƒ~€~€~}{z{z|{z‚„ƒ‚‚‚ƒ‚ƒ€€‚€€‚ƒ‚ƒ„ƒ„‚„‚‚‚‚~€~}~~~~}~}}z{|…„{{syz|pwuvwyutz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€€}}}~€}~~}~|}}~€€€€€ƒ‚€~€€€€€€€€‚‚‚€ƒ€ƒ‚€€|{{z|{|€‚€‚‚€~‚‚ƒƒƒ‚„‚„‚€‚€~€€}~~}}}~}}{{z€x|vyy{qtxwvxury……‚„„‚„……†„„‚„ƒƒ€€~€€|}}~€}~~}|~~~~€€ƒƒƒ€€‚€€€€€€€€€‚ƒ€„}ƒ„€€‚}z{{|||}€|}}€€~}}€~‚‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxyzruyyvwwsu†…ƒ……„„…„„„‚ƒ‚ƒ€~€~€}}}~~€~~}|€|~€~€‚ƒ€€‚ƒ„‚€€‚€€€‚ƒ‚€ƒ€~‚‚„€€‚‚‚„‚~{{||||}}~}z~}}x~|||~~~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„„„…ƒƒ‚ƒƒ€}~}}}€~~~}}€€~|~~~‚‚ƒ‡…~~€€€€€€‚‚€€~€‚~‚‚ƒ‚ƒƒ…‚}}}|{||yz{z~y{yx~{{{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst†„„…ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€|€€~€}~}~€€€~|~€€€~}~~€}€€ƒƒƒ~}~~~€€€€‚€~~€‚‚€„‚„„†„€~}||||zyvyyzyvyv~|{{{~}{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…„ƒƒƒƒƒ‚‚ƒ‚ƒ‚~€}}}}€€€€|€€€€|€}~~}~~€‚‚~~}~~~~€}€€€~~~~~€‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{z{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvpxyrx…………ƒ„ƒ‚‚„‚‚€‚€~~~~€~}~|~€€€€{€~€€€}€~~}}}~€€~~~~}}~~~|€~~~‚~~€€ƒ‚ƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}|{|z{}zzx{|zz{xtxuqrtpxxqy„………ƒ„ƒ‚ƒƒ‚‚‚€€€€}~~€}|~}€€€€|€€~€}€~~}}|€€€€€~~~~}|~~|}€~}~€‚~€€~„‚‚ƒ……‚‚~~|{{||yw{ywxwwx{{z{|…Š}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzz{zxswuqqrpxwq{…†„…ƒ…‚ƒƒ‚€€€€~~}|~}€€‚€€}~€~€€}~|}€€€€~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{|||zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚‚€€}}~€‚}~~~€€€‚€€€~}~|€€€€€~}~~€€‚€€€€€„‚‚€~|}~~z}…~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚€€€€€€~}€€‚‚€~€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€€‚€€~}~{“z|}|{}y{zzxyxy{||}|||||||}}}||}|~}~~~}|z||{|}{yzzzyysuuooqpwst}…†ƒƒ‚ƒ‚€€‚ƒ‚€‚‚€€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€€‚‚€€€}~~|†‰||~{{~yz{z{Ž~wwy{|{}||||{}|}}}}|}|~~~~|z|}{}}{yz{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€€‚‚‚€€€€€€}~€}€ƒ‚{~~{|}{z|{{‡yxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€€‚€‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ‚„„€~‚€€€€‚~€€‚€€€€€€€€€~}€€€€€€€€€€€€€€€€€~}~}~~{}|}{||wxuxxy{||}|||||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒƒƒƒ‚‚ƒ€‚„ƒƒ„ƒ€‚ƒ€€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€€‚€~€€€€€€€€€€€€€€€€€€€€€€‚ƒ‚‚€‚‚€€€‡~~|z}|{}xwvyyy|}||}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚ƒ„„€€ƒ†ƒ„ƒ‚„€„ƒ‚‚€€‚‚„‚‚„‚€€ƒ‚€€€€ƒ~€ƒ‚~‚€€€~€€€€€€‚‚€‚‚ƒ‚‚ƒƒƒ‚€€€„}}}|}z}zyvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysruowqwysw{…‚‚ƒ‚ƒ„‚ƒ„ƒ€€‚ƒ†ƒƒƒ‚‚„„ƒ‚€€‚„‚‚‚~€€‚‚‚‚€€€€‚„€~ƒ€ƒ‚€~€‚ƒ‚€ƒ‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ€‚€}€|z|{{w|yyy{z}~}||||}~~€€€€„„€}€~{{{z{ztpxrytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚‚…†„‚ƒƒƒ„„„€ƒ€ƒ‚‚‚‚‚€‚€~€€‚‚‚‚‚€ƒ‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚‚„ƒƒ„‚„‚ƒ‚‚‚‚ƒƒ„ƒ„„„„„…ƒ„‚ƒ‚‚ƒ€€~||€||x|yzyz|}|{||}}}||€€€€€‚~€€€€{{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚ƒ†……ƒƒ‚ƒ„„…‚‚‚ƒƒ‚‚‚€€}€€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€ƒ€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒƒƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{~~}y|zzz}}|}z||}}|z{~~~€€€€€€€€€}}||}|vrvxxvtvu}‡‡ƒ‚„…ƒƒ„…„€‚……„„ƒ‚ƒ„„€„…ƒ‚‚‚ƒƒƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚‚‚ƒ„‚‚€€‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚~ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz{}€}||z|~}|}}~~€€€€~~€€€€~|}}~~}|{xvvw„‡ƒ‚ƒ…ƒƒ„†„‚…†…„„ƒƒ„„„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„‚‚‚ƒƒ‚ƒƒ‚‚„„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒƒ„„„„„…„ƒƒ„…„…„ƒ‚€}‚€}||{||€}}~€~~}~|||}}~~~€}}~€~~}}}~}}~~|}€‚‚ƒƒ†ƒ„ƒ†„‚ˆ‡…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒƒ‚‚„ƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒ‚‚ƒƒƒ„ƒƒƒ„ƒ„„„…„„„…………„ƒƒƒ}„€}}||||~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒ„…ƒ„ƒ…~‚Š‹…„„ƒ‚ƒ…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ…ƒƒ……„……‡‡†‡…„„…„€ƒ~~|~}}€~||~|z|}}}}}~~~€}}|€€~~~~~€‚€……„ƒ„„‚„ƒ†€‚……Š‰„„ƒ„……ƒ‡††„„„„…„„„„ƒ„ƒ‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ„}uyƒ€~„„‚ƒƒ‚ƒ„ƒƒ„…ƒ„…†„…†}„y|~ƒ{…‚„ƒ€}}~}}ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚‚ƒƒ‚‚†„„ƒ…„ƒ„…ƒ„…ƒŠˆ………ƒ……„†††ƒ„„………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†tpurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚……‚hzrss|€s‚ƒƒƒ}}~~}~‚ƒ‚|}€}}||||}|||~}~€}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ…ƒ†ˆ††…ƒ††‡‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vyy…r„ƒpvxqvtturstvi€nrotvnulwm{sn€‡ym}rsvsvmmxlpylu}}~€}€}€€}}|||}|}~}€€€~|~€‚€€€€€€€‚ƒ‚ƒ„…ˆ††€‚…ƒƒ„‡†ƒ………†‡‡„ƒ†‡ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoomw}x†pqzprtfu~n{ysoy€}}€|}|€~€€~~€€€~~~~€~}€}€€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„†……††ˆ„„†‡ˆˆ†‡„††‹Š…„†‡‡…ƒ………„‚†††…†……†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„qjoyxpkyszozwvvp€~~~z~}}}~}€ƒƒ€‚ƒ„‚€€}~~~€~~‚€€„‡†ƒƒ†„„…†‡†…………††ˆ……†…‡‡…†„††‰ˆ…„‰Šˆ…„††……ƒ…†…†††††…ƒx‹yrˆz{pp…„x…xyks~y{krƒ‡ƒz|m{yyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozls|nw‚€~~}}{}{|}}~}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡……………‡‡ˆ†„†…‡††…„……„……†‰‰‡†„†…††…††„†††††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„…†…†„†„ƒ„„†„„ƒƒ„„…„…„…„†ƒ†‡…†„„…‡†„„…†„…}w…ƒ„„‚}~{|{~{||}~}|~}€€}€~~~€~~~~}}}~|{|~||‰†…„†††…‡†…………††‡ˆ†„†…††……ƒ„…†…„††††……†„…††††„‡†‡‡†…‡ˆˆˆˆ†„‡…††ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…ƒ‚……†……ƒ…„„„…„……„……ƒ††††…„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ‚}€{{|}{||}~||~}€}€~~€}}|€}~~~~~~||}~{|||{{~ˆ‡„„ˆ†††‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡……†…„†„…††‡‡…‡†‰ˆ††‡‡ˆ‰ˆ……ˆ…†‡†‡†‡†‡…‡‡†‡……†‡…‡†…‚ƒ…††„„ƒ„„ƒ„†„……………ƒ††…†……††…„ƒ……ƒ„‡…ƒ‚‚…ƒ„~€€|{}~{|{}~}||~}~~|~}}~~|}||~~|}€|||}|||~z{{|~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†„…„††„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…‡‡…‡†‡†‡…ˆˆ‡‡…††‡…††…„„…†……„„„ƒ„……†††…†„†…†‡……††…„ƒ„„ƒƒ‡ƒ„‚„„ƒ€€€{{~}|||}}|||}}|}|~}|}}||||}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††ƒ…†…†††…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡…‡††‡‡‡…‡†ˆˆ‡‡…‡‡‡…†‡„‚„ƒ„†…‡…„„„„„…†††††…‡……‡…†…‡…„ƒ„ƒƒ„‡ƒ€‚ƒƒ‚‚‚€{}~}{||~}|}}|}{||||||}{{{}|{~|{|}}|}}}|zz{{||ˆ‡‚††††‡††…ƒ…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡‰ˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡†ˆ‡††‡‡…‡†ˆˆ‡†…‡†ˆ††‡ƒƒ„„ƒ††‡……„„„…†††††…†‡††‡††„†…ƒ„ƒƒ‚ƒ†ƒ~‚‚ƒ€ƒ‚|~~||}}|}}|}z{{z{|||{{{~{{}{{{~||||}~}{z|z|}‰‡ƒ†…†…††…„„……………„ƒ…†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…‰Š‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……‡ƒ„†…„††‡†…„ƒ……†††††…††‡†‡‡…ƒ†…‚‚‚€ƒ…‚ƒ~ƒ~~}||}}{}}|~zyzy{|}{{{{~||||z{}||||~}|{{{{|{‰‡„†„†„††…„…†…„„ƒ„‚€ƒ…ƒ‚z„Œ{€„…‡†††…„‡ˆ‡†‡……‡‰‡„‡…††ˆ†…‡„†‡ˆ††ˆ‡‡‡†‡ˆ†„†††‡……‡ƒ„…„†††‡…„„ƒ……††‡††…†††…††„ƒ„…‚‚€ƒƒƒ‚}€~ƒ~€||}}~}{~}|}yyzy{}}zz{{}|}||z{}||}|~~€|{{|~}|ˆ‡…†…†„†„……………ƒƒƒ€‚…‚€}|{„…††„…„ƒ‡‡†††…„†‰†‚†„†††……‡…‡ˆ‰†…ˆ‡‰‡††‡…„†……‡…„‡ƒ„…„ˆ††‡……„‚……†…‡†‡„††††…†ƒƒƒ…€€€€ƒƒ€|€~~‚€}€||}~}~{~}||yzzyz}}yzz{|{|{{z{}}|}|~~|{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€€ƒ~~~€yz}€ƒƒ„‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ†…ˆ‡‰‡†…†…ƒ†„…‡ƒ„†„„…„‡†…†…†„‚……†††††„…††……†‚‚ƒ„~€€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|z{{{|}}}|€~}||}~|{‡……††††„…„…ƒ…‚€€€€~‚‚}}{‚ƒƒ…†…„ƒ‚†ƒƒ„‚€…‡…‚ƒƒ„„„††‡ˆ‡……ˆ†‰‡…„„„‚…ƒ„†‚ƒ…„„†„‡†………†ƒ„…„…†…†„ƒ„……ƒ……€ƒƒ~€€ƒ|€}}‚}€~~~~~}}{|{zyzzyzz|yzz{{{|z{{{{}~}}€}}||}€}|†ƒ†††††ƒ„ƒ†‚…€€€~€‚|~~€€‚‚„…ƒ‚‚„€ƒ‚€„……‚€‚ƒƒ„……‡†…„†‡…‡……‚ƒ‚‚ƒ‚‚…ƒ…„…†„††‡††…‚„„ƒ„†……ƒ„ƒƒ„ƒ…„€‚‚}~~~„~{||€}€}}ƒ}~~}}~{~{{zy{zyzz{yzzz{{|z{|{{~~}|}||}€~€†„……„‡„ƒƒ‚†‚ƒ€€~~€}‚|}~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡†…„ƒƒƒƒ„……„ƒ‚ƒ‚„ƒƒ€€~}}~~|~ƒ~|~||€~‚}‚|~}}|||{{zzzzy{zzzyyzz{|y{}{|~€}~}}}€€€†„„…„…‚„‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„…ƒ‚ƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚€…ƒ~€~|}~}|~ƒ}{~|}€ƒ}}€~}|||}{{zzzyy{yzzyzz{{{z{}||‚€~€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌËËËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFL=8765999<>9?<D:;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937677=;>9=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<9<<98:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA><A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÒÓÔÔÔÔÔÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9?CE@<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÑÓÓÓÓÓÓÓÓÓÓÓÓÓÎÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø×××××ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÙ×××××××Ø×Ö×××ÖÓÒÓÓÓÓÓÔÔÔÔÔÔÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILO@99:4;A<7=9AC>@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌ̈́mpppppppppppj§ãÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¹´ŒŒŒŒŒŒŒŒŒŒŒŒŠ º¸¸¸¸¸¸¸¸¸¸¸·½ÒÒÒÒÒÒÒÓÓÓÒÓÓÓÜâáââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVN<::87>C?8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÎN&+++++++++++"ŠôëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§£££££££££££¤œZUVVVVVVVVVVVRy§£££££££££££¡«ÒÒÒÒÒÒÒÒÒÒÒÒÒÑßêêëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;?C>6:7>>;=B?9<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÍÎR+11111111111'óééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤¥ž_YZZZZZZZZZZZW|¨¤¤¤¤¤¤¤¤¤¤¤£¬ÒÒÒÒÒÒÒÒÒÒÒÒÒÑÞêêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;?@@8:;8<;;<?:;;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÏ\9===========5“ðççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©ª£hdeeeeeeeedddaƒ¬©©©©©©©©©©©¨°ÒÒÒÓÒÒÒÒÒÒÒÒÒÑÞéééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB>;=:9;:==;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÅÂÃÃÃÃÃÃÃÃÃÃÃÂÉÐÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÏÎÏÏÎÏÎÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÑÍÌÌÌÌÌÌÌÌÌÌÌÌËÎÒÒÒÒÒÒÒÒÒÒÒÒÒÒÔÔÔÕÕÕÕÕÕÖÕÖÖÖØÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<8@B<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÏÐÐÏÏÏÏÏÏÏÐÔÐÐÎÌÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÐÔÒÏÎÏÓÓÏÎÐÔÒÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××Ö×××××ÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÖÖ××ÖÕÖÖÖÖ×××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?79:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÏʖ¥ÑÏÏ¢—ÊÒƒ«ÑÎÎÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<>B>BC@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÏϜª¬×¨ « Î™­š³ÒÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?>;7:>9?D?A98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÐ˔ˆšÂœ•¡³•†ÎÏÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<<:6?B@C:647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÏѽș›«Ÿ§™´Àɗ™ÆÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8FA?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÏÏҗ” Ã¢ Œ Åӑ˜ ÎÐÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<>=964:99::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÏÓ³›Ä˜Ú—Åɔج£¿ÕÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ×××××××××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:=?>=<9@<<::9?@>=<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÐÑ΍ ¶ ”•¡»Íˆ•žÈÒÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CFCAB8;?<=;<<8558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÐÑËÚ¨‹Ÿ¯³¥ÐÛ¢™µÕÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF@HIGE@<<>><=><756:96:;::;8@?:<<9<>=;;:?9?:;9=>==;;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦ÕɎ¥š£¢š¢œœ‘¨˜ž»ÕÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;557<:8:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡Ê»¡¦§¾ž© ¢ž©¢©œÐÓÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKL@>=D<?CF=557;97:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÓӞ¶Ù®Ž‘¥Ôš‘Ž¾ÖÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<=?GFHKH=657:979:;:<=9>99:8;=>>A>=9<<:=>>:=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÒºÄÕÒÕÁ½ÖÓÓ¸ÈÕÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?AELLA>776;8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÒÕÔÒÒÒÔÕÓÓÓÖÔÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEK>>787977899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9699:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EILAALD??;:889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEGIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDJ;AA;<886486987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGIB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<BA<;876797799=?A?<:9@?<>B?:8776=??@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ×ØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE>;HF89757875898;>>=;89A>=@?A>7596;>AB??@@BB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCEFC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELCA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<;DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGGNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAC?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€iixsg~‰‰xp‚†{w}~…Š½ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€‚wt|„‚}sp€Šx‚yƒÈÞÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsoupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿¼½¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»º¹¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjdmgb\XQPQKTJB:IQ?A7<94:565455688686;:9<==;:86688:867>=<=>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸········¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µµ¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸¸·¸¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶·····¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨¨¨¨§¨©©©§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸········¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™˜˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<=::A<6=8378837;@???@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥£¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§§¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜™šš™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©ª««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤££¢¢¢¢  ŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž£¤¡žžŸ  žœœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=7789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥¤£¢¡¡¡¢£¥§¦¦§¬¬§¦ œ›¡¡ž›ššœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¥¦¦§§¦Ÿ›š›¢ ™––•š›™——˜˜šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜—™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥¢¢¥¦¦¥¦§¦¦ ›™›¡ —““’—šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB@DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥¦§¦¦¢œž¡Ÿ—‘‘”—›˜–––˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;;;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¥¦¥¥¦§¦¤¥¦¦¥¥£  ¡¡Ÿ™’–š™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šžŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡ ¡ŸŸœœœœžžš—––•”““’’’‘‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢¢¢£¤¤¥¦¥¤££¡¡¡žœš•“”˜›š›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œ ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸŸŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::88:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸ   ¡¢££££££¢¡ ž›™™˜™™™š™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢ ›ž ¡£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œž››œŸžœœœœŸ   ¡¡¡  ¡  ¡¢¡¡¢¡Ÿžœšššš›œš™š›™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥£¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¡¢¢¡   ¡¡ ŸŸžœš™š›››œ›š›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›šœšš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>98;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤£¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ žžŸ     Ÿ ¡  Ÿž›š™šš›š›››Ÿžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›ššš›™˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9;;>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœ›œžžŸžœšš›œœœœœœœžžœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:=>:?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››š›œššš›œœ›™™œœœžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™˜˜ššš™™™˜šœœœœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›š™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š››››œ›˜˜˜™™˜˜™™™›œœžžžžžžžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ›››››››™˜˜˜˜˜˜˜™™œœœžžžžžŸŸžžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ››››››š˜˜˜˜™™˜š›œœœžžž  Ÿžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_^]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜™——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜˜˜——˜™››œœœžžžžœ››œœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±³­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKIRXY^AF99=9F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œšœ›œ›˜™š˜˜™ššš–‹“–™˜•˜˜–›œ—•’‘’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨©¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‹‘‹ŒŽŽ‹……‡‹ŒŒ‡ˆ‹Ž‹‡Œ…†‹†ŠŠ‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VPQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹‹†Š‹‹‰†„†‚€‚‰‘ƒ€ƒŒ†‹‰…€‡}€’†„„†ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹‹‰‰…‚}s}ˆ€~œ„……‰‹Šz}}†ŽŠ†”‘‹—”—’˜¡–ž—•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¥›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ†‹†ˆ…„ˆˆ‰„‚z||}~’ˆx…‹Šƒ„…ŠŒ‘™””” ššŸ¢­±­©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPEMISWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‹‡Œ‹Š‡’Š‡†‘“‘‘„‡}}ƒˆŒŽ‹ŽŠ‰Ž””˜‘•›š¨®²¯¯µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWLO_^\NUTbQDTM;?9<895775795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš˜ “—š ™›£ •› ¤£š“ˆˆ‹‰‘‘Ž‘Ž‹˜šŒ”š—œœ›Ÿœ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUKTOOJCPK_bXZQ\T`MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ª©¨§¡¥¨¨«©©¯¡›Ÿ¡££ šŸ œ”˜”˜  ¡¤ž›š¤§¤©«®¬¥£¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©©¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdVOXKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®ªª«¤¡¢¥©§§©¨£¢œ››¤ ¥¨£ ˜™Ÿ¡¢©§ ¢¢®¬«ª§­®¨¥¤©©©©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_UZNRNPORd\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢šœ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨¦¥§¨¦©¨£§¦™œ¤¦¢¡ ¡¡ œ˜™Ÿ ¡¤¤¢žž– ›š¢¢ ¡Ÿ ¢¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOWO^ddlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤Ÿ¢ ¢¦¡¦®¦¦ŸŸŸŸŸ™šœœ¡ ¡¤Ÿ¡›šœ ž¡Ÿžž £™–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦¦¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvwa_\UYQUV[c^r_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?C?:8:>?C@DA:;><@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¡¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯ªª¬¨¨«°©¨©¨¡Ÿ §©­°²¯¬£¢¦¡©¥ž¤£¢¦ ¥¤¢¥£ž žŸ¥¢¢žŸ¢˜•žšžŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤ ¥¨¬§¦¥¥££§¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸ ¡¦¢›—’šš •|wp}yf[[`_Z\V\hdocniib^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¢ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶¯³°«±²±£Ÿ¢ª©§®·¶´´¶³¯¬«®«¶°©²±­®§¦ž¢££›œ—¢¨¥¡Ÿž£›ž¡š–¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¢™˜¥ ¤§ª©¨ª­¬¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬£§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxib[_^\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>AE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢œŸª²¸¼¼½»º¿´¯±³µ´··¯µ´µ²°¨¤¢Ÿ —•š—¤ª¦¦¡¤£¤«¥¥˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨©«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥¡¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxxxc[RYT__blhukpgiibYSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶´º±ª®´±°±´µ¶¼½¾¼¼½Æº¸·º½´¯µ±±º¸·²³²ª¦¦Ÿ˜¤¤§¨¤®¤««µµ®³ §ª¬§ª©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¥§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš“–””˜“š˜Š‹‡€€|‚xa^YSah`fsositdidb[LK>:8898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÃÆÃù½¿ÀÀ½¿Ä½¼º½¾´§ª˜±À½¸µ¹À³¯¯ªª¨­§§¤¯§ª´¼±´µ¨¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`a^^jbbnwuvnl[bQU\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAB;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–•–‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±°§¼¼¾ÅÄÆÉÇÅÆ»ÄÁÅÆÀ¹¯½¼À¾¾³«ªŒ³»¾´µ·Âº­¯°µª«¦ª£­¤§±¶«µ²­³­¨®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|ƒjfhaklfnuqruqf^_\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎÌÌÇÁÃÇÇÈÊÅÄÅû¼¼ÁÅÁÅÅ¿ÃÂÆÅÀ±“¾º¿Ã¶¶º©´³´©«³»»±Ÿ›±¯¬¤¬®´§ª©¨ª­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•Œ‡’‹˜˜•šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|tkkndolhqxoyiia\gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABBA=@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆÀÅÇËÈÔËÊÇÆ¿»»¾Ä¾ÅÈÆÆÄÄø´À·´¼Á¹··¿À»®¥®·¼·­œ£·°¦­´µ¬®¥¥£¨¤  ¥™ª³²¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™’‰•‘—•”™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vxz{vnkiguZfrwsxff]d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÉÆÃÃÄÂľ·¾ÁÃÀľÁÏÏÎÆ«¯¶´µ« §´³®«¸µ³«©£¢­©¬¦­Ÿ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuueeijg]jomxwcb``^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÏÏÌÃÇÆÈÈÈÇÉÇÅÉÇÈÇ¿ÅÇÄÄÇÈÊÒÏÒ̼¸¶´¸¸Á¾¾º½º¼º¼¬­§ª»º¹·À²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqobagugiitmxl]d[U`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÍÐÎÇÌÉÂÁÆÁËËÇÆÌÉÍÅÆÅÃÆÅÉÍÐÍÏÌÇÄÀÃÂÉÍÇÅÁÄÇÁ»¾´±°°Á¾¿ÁÆ¿¾¸·Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`jjvlieunsb\bTWTSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<:>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÅÇÈÆÒÉÁÃÄ¿¿¾ÄËÈÊËȼ»ÈÇÉÍÈÃÈÉÉÅÅÃÂÁÂÇÇÉÊÇÌÈÇÈÍÆËÏÅ·ÀÀÀÀ»º½µ³³¿¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrpfegdjebjmnn^X\VUNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾÆÁ¹»Ãº¸¹¼¾ÁÆÁƺ¹ÉÉÃÅÄÀÄÁÂÁÄÁþ½ÂÀÀÁÂËÃÆÌËÅÈÑ°¾½¸º»¼¾·´°¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfadbabccjbfcZYY\YQNE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶·´´µ¿»½¿¹½ºº´¿¸µ·²¯»¼·À·½Â¿Á»¿Á¼»Å¾»ÁÄÀ¾¾¸¼ÁÁ˾½ÉÄÀÀÊÀ±Á¿»¸»¾ºµ·´¸¼´½¸µ´°³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|y‡}qc`bbgjgfiei]VUSYOSKE8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“’’˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´µ±°µ·µ»Á¸¾¸¿¼½·µ·°®¸¶¹¿»À¿·Á¼»Ã¶ºÈ¸¶¹»½¹º¶»ÅÅʽ¹ÅÀ¿¼Á¾¸Æ½ÁÀ¼Å¸¶·´¸¶¶»»¸¶´·ºµ´¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒ€xpmeefoiekhXXNKKKRILHC9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’š”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿½¼²­¯¬±°·¼¶»¼ÀĹ···µº¹º»À¾ÃÀºÄ¾Ǹ¹¸­·µ¸º´¸³»ÅÆËÁ»ÆÀÀ¿½¼¿ÉÃÄžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~†|knpgpksebm_\THKJDJBCG?9;8><7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘ŽŽ˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼¼À·ª­¤®°·»³½¿»Ä·¶¸¶·¿¿Ä¼ÂÒÊÆÇÊÉÆÏÂÁ¸®µµ¼¾¸º²¾ÄÄÊÅÁÉÿ¿¾½ÇÌÇÇÄǽµµ¶Á½º»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†qelintnwcgb\cQKTHEECGC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?=??FD@A?>:7?@CC?A=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼««£°¹½¾³¼¾¼Å¸²¸¹½ÇÉÊÂÍÙÈËÉÈÌÎÑÌÊĵºÀÃÈ¿¾µ¿Á¿ÆÆ¿ËÆÿÁ¼ÀÃÌÊÇÅÆÀ¹½¼Ä¿À¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtolltkln_c^aaNHM?E@?DC<;::;:8;<:9<>9:>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED<AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´¼Ã¼ºº¾¼Ä¿·½¿½ÇÌÆÆ×Ç«ÔÅÄÊÈÌÌÍÊÆÂÃËμ¹½º¹ÀÿÈÆÄÁÁ¿ÅÀÊÉÃÃÄùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{z‡zmmw{_pc[]_^SI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA>>ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸´¼¶º½Á¼»¿¶¿Á¿¼¾ºÀÊÂÆÓÀ”ÂÿÅÂÇËÈÁÃÀÀÉÊÂÀ»»°´»½ÀÅÆÅÅ¿À¿ËÇÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²²¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}‚zmsxsgp][^\YQEDCMIAE=G::59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘–žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯·¶²µ³·¹¼»¶»»½ºÃ»·¼¶¹Áºº¸¸µÄÁÄɹŒ¼¹Á½¿ÇÀ¹À¼¾ÅĽ¾¹²°®¸·¿ÃÇÃĽ½¿¿Ãþ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸¸¸½¹»±¶²ÈÀ»¶´±°·¬³©°­­³·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|vluzpni\_`YSPAEHGK@DCH<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿš›œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹ÁÀ·½¹¸À¶µÀ³µ²²ª®¦·¹¯‹¯¶¸¸¸Âº´»·»¾À»»¼®¯®³²¹ÁÂÄþ¼¿»º¸¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ¯µ´´½º¾¹º»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§¬¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰|‚zsvvwnq`_e]ZUJ<??FF=FCC9:5;99><<::<>>>>88315789>?A?;:?=<;==9;<:;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Ã¿·º¶¶ÑÀ²À·°Œ~wŠŽŸŒŒ¥µ³²·¾¹³µ²¼¹¼¶º¾²´´´°¸¾ÃÆÄÀ½¿¹³¯²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtvrl^b`[]OHA>=HCFMC@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·À½»¼¸¹ÒÌ°¿¬¡€l}m`gizŠŽ¥·³°¶ºµ´²¬¼¹¸µ¸Áº¸³±¬·¼ÁÇÿ¹ºµ®¥¬³°¦°­¨ž Ÿ¥­¶µÂ·¶´¥¨«¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´·¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wo{ournc\fX\]RNMA>IB@JI@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³²­¶º®¬¼²¸¹·»¿¼¾ÕŲ©x~_l‡jc^az‘©½¶±´¶²´¯­»º¸¶¹Àö®®ª²¶¼½¹¶²±­­Ÿ¤§§£¦–™™šŸ©®¹¬««Ÿ¥¨¤«®®§¯¬¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmuik][jT]\OMHDFLBFMF8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹ºµ¹»µµ³µ»¼¿Âͽ €dZ„]V…ŠŒ|a[¯Æ¹´´³°±­°¹¸¶¼¸»¿²²²®±®¹¯ª«­¬£¨¡ž—˜¡•’•—˜Ÿ¨®¤£¤ ¢§¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬«¯£££¡© ›“Ž“’’™–š¤¥ Ÿž§˜•’”˜ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wrxhtsndT`cW\QNLH@HQDMC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;=<<::@=<<;@>B@A?>958;<FBCD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯²²º¸Èų‡cYk–\Wdx‰‹yJ‚·Æ¹²­³°¯¬®¶¶²´µ¯ª¤ž›œœž¨¨ž ¨©Ÿ¡§–›——“–Ž—›¤¨  ¢¢¢¥¥££ ž¥ ¤¬¤¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›©¨ª«ž¥£›£œ•Œ“–•–˜Ÿžžš™¦—“’–¢ ¥£¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦ ˆxƒ|vybwln\QhTPNGOMLBOQ@>;>39:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¥­ª¨µ¯ËǦsW]„WVaf²¥vPh·¾¶³ª²´®ª«¯°²³®¥ž’˜”˜ Ÿ¢ œ¤¥Ÿž¨”›–—Œ—‘—“˜¢ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£ž™—š«¦©±£¥¨ž œ•“‘˜–•˜–Ÿ˜›™›£™—”–š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’}|€uu}mk{dhUQcMIHGNRNJNG;E@=2?759;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@CAD>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜——–¡¨¬®¶·º¹º··»®¨ ¡©¢ ­¨ÂƙbZŠvedzu¯£vf_w›¯´®¯³µª§­¬£œ™”Ž‘–—˜™œ ¢¢œ¥žš¤———–’‘‘“š—› ¤ªž¡¡ž¦§ª¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¡¤¡›˜ž¯¨®²«¥ªª š˜˜˜•“–š“••™–›——˜ žœœ—›¡šžš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}vx|dxy`bRU_HIIKSTIRPL9?B67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—“’œž¤¨®­¬««¯ª¯©ž—Ÿ¥žž¥¤½Ã•Vh›—t‹™‰oŒ~u}yz¢ª³±°°¸­§¡œš”—ššŽ‘•‘ŒŽŽ”™¢œ—£™š—˜™”™˜–›Ÿ¥¦© ¦£ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§  £±®²°´©±¯¢™œž¡™››š˜™›”–›–˜œ¥¡ š£¡š™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ Ÿž ¥¡žž¥ ¦™{|uvsh‚le[SZYMQJNNULRLA7>B68=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’‘œ˜¡ª¢§ ž§¡¥Ÿœ’œ¢›Ÿ¡¡ÂȑQs¥´€„†xipq{ƒx¨©°®®¬°§ Ÿ¢ —‘”› œ™—’“Ÿœ¡¤›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬¨¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½·¾°¬±®­©ª´±°¨«¨²µ·³¸¬±´¤ ¥Ÿ¬¡¡¢  š˜–– ››˜¤¡ ž¤¡Ÿžšœ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚|xuiwu]lZR`HQUHFUVJBLG=KH8E<67;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“Ÿ™¨®Ÿ§žœ¡žžšš’™žœ¢¢ŸÇ͏TvŠŠsoj`[]\^ean ª¨ª¬ª¥ŸŸ™’’“˜˜––•Œˆ‹Ž•ž–žš¦  ¨¥±ª§®£«­¶°´²±®¶¸½Àº­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«¯±¹·¼¯³°µÁ¼·½³³µ¢¬¢©¨²©ª¨§¨š™žšª§Ÿ™¦ ŸŸ§¨¥¤žª¡¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰…„~vqmivmhm\X[BVMJGMGBFM<>L=4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜™ª ±¢·¤°¦Ÿž—˜•™ž›œ£ Æѓa|zyh`WLIKNPOQ\kƒª¯®©ª¦ žž¡¢Ÿšœœ”“•”žž˜”…š¡›«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶ººÀĹ½»¬¯§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¹Â¾¸³»Æüû·³©³­ª³´¯³®ª®£«§¶±¬¢¯¦¡£¯±­°¤¤¯£¡ š¡§¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¥ž¦™›¢¤žŸ›››œ‡…{tqkkurphW[QETHDIOH>EA4EH95;=6;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<<;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž  œœ˜›Ÿ ›Ÿ ÄȇqxvgVRRnWWNMDGa¬®¦££¢ ž¥«¥ž—œ”‘™˜”ŒŠ†ˆ†ymˆ ¤¢«¬´¼¶Ã¾¾³»ÁÃÂÅÀ¿ÂÆÆÅÃÈÂÀÅÈÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌÌÌÒǾ¿ÀþÇÆ·ÃÉÉÂÀƾº´ºº´»·°¶²ªº²®»·¾ººª·­«ª¸º´¼®®¹£¦£ž¦¥¢£©¦™›Ÿ˜š§ª§ ¡¡¤˜”£–”™‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ„}zqkdhoxjeZ[FKLEDSLDBE7:?;549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ³²¸§¡¡«ª¡œž¡¢ž›š³klphUP\|¦•yRMg”®¬ ™œ›žž™———’ŒŽ——“Ž‹‚ƒ‚wsqnp¦­®´¹Å»ÍÇË¿ÂÌÎÍÌÇÉÑÌÍÌÇÉÅÆÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÒÓÍÓÐÓÓÌÊÂÅÆÇÊÈοÈÑÌÇÅÇÅÁ¼ÃÀ¾¾¾µ¾³­¿¿ÂÂÆÄÇÄ®¾¸²¸¼ÄÁÁº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›Œ™‰•˜› Ÿ£—žš““‹•…€ytsebgrof^ZYCNLCEPIDC@5558:B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A?<@?>8;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›¢¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¥¨¬­ª £Ÿœ™¬•rmcWNRh´ÓÓ¤¤³®¤ŸŸš˜–”’”–‘Œ‡„ƒˆ‡ƒ€€yrroly¤¶º¹¾ËÁÓÒÓÈÍÎÑÓÑÒÑÐÑÑÍÎÎÐÅÎÔÕØÒ×ÍÆÇÉÌÃÅÊÏÊÒ×Ñ×ÒÔÖÓÓÈÌÇÍÍÉÒÍÎÓÌÅÇÉÊÁÆËÆÈÈſó³ÈÄËÊÊÎÅÊ¿¾¿½ÁÇÄÌÌÈɿÿ­¯³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›•Œ†‘‹€zruvgcgvidVWQDMF@IQB=B<:22@<D<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<@?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­³·¬®£ž£¢ ¤¬˜zfXSRXwÓ׿²¯§œ ¤ š””•”‰|wpkebhqoq{…Š€vpnqtp…³Â¾ÅÑÐ×ÖÖÒÖÍÔÖ×ÔÓÑÓÔÔÓÏÑÃÐÓÖØÕÖÒËÉÎÑËÆÍÑÉÒÕÖÙÕ×ÓÖØÎÒÊÏÑÌÎÐÌÒÏ¿ÇÆÊÃÌÌËÎÏÅÆǶ¿Ê¿ÑÌËÏÅÉÇ¿ÃÃÈÎÌÏÐÏÍÊÇ͸·»¨Ÿ¥«§ž˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„|xsvpc`erb]R\IJGAEHI>;@8=4585;86:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÁűµ¨¡¤¥ ¢«µgZTUVh“¹®¤š•˜ œš ¡Ÿ›œ™•‰wic`____^_`^blusqpolrqu’ÄÇÆÔÕÖ××ÓÖÏÕÔÚÔÔÎÏÕÔÔÑÑÌÐÎÓ×ÖÓÕÐÏÒÓÑÉÓÑÇÐØ×ØÑØÒ×ÙÕÖÌÏÏÊÍÒËÎÏ¿ÅÂÇÅÎÍÑÐÑÈËÍÀÊÌÅÓÎËÎÈÄÉÆÆÈÌÊÓÓÑÕÏÒÌÓÁ¹Å±¥¨µ®§š¨¬¥²¨°³¬¬““ŽˆŠƒ‹„Ž™“™‚…Œ|zqstmacim_VP_JJCFCQM?<>54:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><??=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯­ªª«¦®·¨«·×ÔÕÙÙÑÎÐÀ¼Ìɶ¾®¦ª¨¡¤±´UPSRe“­¦Ÿ˜–˜š› ™œ“}qecc__a__a`_``_`fmppnkorww›ÌÀÒÕÓØØÖÙÑÒÒ×ÏÓÎËÒÍÕÔÒÊÏÌÓÖÒÑÖÍÏÕÕÑÆÑÔÊÐÔÕÖÎÒÐØØØ×ËÈÍÄÉÏÌÊË¿É¿ÇÉÍÎÏËÐÍÎËÎÎÇËÏÐÊÎÊÂÉÆÉÌÊËÑÒÌÓÑÑÏÏʽȹ°®»¸µª¶°­¨¸­³¿»±šŸ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…ˆzvopokadnpaW\ZIFFDMWE;@<33<=87855;>@=9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6==?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ¤§Ÿ¸¶µµ¬¤¬®¾´°ÀØÒ×ÚÜÖÎÍÊÃÒÏÁÀ±ª¬­ª¥±©mMJNX’ ›•”—œžŸŸ”–˜”‰k^^^adb```a``a^__^]bmroostvvy¤¾ËÕÑÖÔÓØÖÎÎÔËÍÎÅÎÊÒÒÏÆÎÍÍÔÌÎÓÍÊ×ÕÐÌÑÔËÌÐÑÓÊÎÑÕÒÕÕÊÀÊÁÅÌÂÈÉÂÌÃÅÈÊÊÎÊÍÌÐÍÓËÅÈÏÌÈÇÊÄÆÀÅÊËÍÏÑÆÐÎÍÍÌÏÅÇÀ¸¹½Ãýù³²¾±»Ãĵª˜¥¢™–‘••’‹”š‘”””‚‰…xpqkmg``phXXhVLFLIPPB;D>;67:89:57==A;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;776?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÅÂÁ¿»µ²±Ç¸ËÕÕÙÚÛØÌÌÏÈÖÕĵ°µ¨¡«ª­aHDQ‹›Œ˜•”’‘–––‹|ebbb`]^acb`_``aa`_][]grqqrsqmry¤ÆÓÏËÐÏÔÕÉÅÉÉÆÆ¿ÃÆÏÎÇÅÇÍÊÒÈËÎÍÆÑÒÏÎÌÔÊÇËÎÏÇÇÏÒËÐÏźľÆɽÂÇÉÎÄÂÈÀÇÍÇÃËÊËÏÇÃÄÐÈÆÁÅÇľÀÇËËËÎÂÊËÈÇÌÐÄÅÇ»ÇÃÈÈÂÏÁ½¼¿°ÁÉǹ½ª°²§¥¢œ˜›£™—™‘•˜‰‚wntdk`^fpa[W`GHHGIMTG?J=64355=<48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ¼ºÍÍÆÐÕÕÙÚÛØÐÉÏÏÑÓÈ·¼¼®¥³§³dIK‚˜Ž–†ƒ„„‚~……s`\^^^`^`cdc_]]^_``_[Z\`krrookloo}¸ÑÈÉÊÏËÍĺÀû»ºº¾ÉÆÂÃÀÃÈÊÉÈÊÈÁÅÌÆÈËÍÉÄÂËÉÁÂËÐÄËÈ¿¹Á»Åǽ¿ÆÏËÿûÉÆÈ»ÈÆÄÊ¿½ÂËÆÅľż¼¿ÃÄËÅļÀÉÂÅÇÒÄÀÈ¿ÊÉÆÇÆÐÃÃÆïÄËÇÃÊ·¿¼º´©¬¤¥˜Ÿ˜¬£¡¥š£ ›”{vstfiZanlZ[XRDLFBGDLDFS@54334?<3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ËÏÑÌÇÂÃÆÍÎÎÌÕÏÕÙØÙÏËÒÍÍÎÈÁµÄ¿³±·«¹uWy–Œ“—†z€…†€vxurp_Z[]``bcdded`\\]]_^`[YZ\borokilposÆ¼ÉÅÌÀÆ°¶º²²³²±Â¼¼¼º¸ÁÁÁÅ¿½¹½¿¹ÄÊÅƽÆÀ¸»ÄÉ¿ÂÉ»·»ºÅþ¼ÁÍÃƽ½µÁ½Ãº¼Æ»Â¹³¼ÅĶ¿µµ½¿ºËüµºÈº¿½ËÃÁÅÂÅÈÆÈÆÐÆÂÌDzÇÉÃÎÍÁÅÃÀ½²·°²§¨¨¹°¥­°«­¬”yvwjdg`hocV^YJFJFHJAEBEI@9:648853;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÆÃÄÈÎÑÊÊÊÇÍÍÎÑÈÐÆÕÔÖ×ÍÊÏÅÉÅÇÁºÇ¾­®²®°†x‘Š‹…x€††€~„|ttc[\]^``bcabeeb]][\^\^]Z[]]hsqmggnpry½ÌÀúÁ¸®°°§ª­¬§¸µ·´³³´ºµ¾²·°µ¯²»Â¼Áļ¿ºµ³º¾À¸Ç¹´»¶À¼¸½ÆÁûµ®²¶º¾´Ä·»µ«¸½½¿½°º¶¯¶º²Å¼¶®»¿´¶´Å½¾ÂÅÀÃÅÆÈËÅÀÆÆ»ÇË¿ÏÊÇÃÆÂöý½¶¹¾Ç¿¬µºµ·¶Žxtxfgebkn^V^`FKHHJFBDAEE?<:565633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÎÈÅÈÍÌÐÌÍÈÊÈÊÉÊÄÏÍÒÏÍÅÇÁÅÁÀ»¹Ë¸­°±¯—†‰Š{x~††wx‚}ti^]]]_`_`da^dec__\[^\]^Z[[]_lpmhfjmnr|¤Ç¿¸¸µ°«¬§ž¢ª§ž«­³­©«©´­¶±²©®¦¬²¼º¶Ã¹ºº±«µ¹»´Âº°¿±½¼»¶¼Ç¹Â¶­ª¨°±¿µ·¼¯°§²³´»¼«­µ¥®¶®º±°ª¸°­»®»¸»À¿½¹Â¿ÇÃÅÁ¼ÆÁÇ˸ÅÇÅ¿ÆÃùÄÆ»ÆÉÌ˳¹Â¼º²ˆrvvkiablhYXW[ALKMIEAC?FA:9:995854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÅÎÒËÃÅÁÅÏÇÍÁÃÆ¿ÅÅÃÃÊÂÉÊ¿À½Â»´¶¶Å±«°®ª|v“ˆ|x~Š…z{„wo^]\]]_`^_dcbccb`_][[ZZ]ZZZZ\enohfgiknr­¹°µ®¦¥§§š ¤ šœ¥«®£§¢«ª¬ª°£¦Ÿª­´¶±½¹¯·¯¨®·´´¼¸³¼¯¸¹´±¼Á±À®¥¨¢«±²³§¼ª«¨«¬­´³¥¨­¡¤¯©²¥§¨­¥¨·¬°²·ºº»±»½¾¾Ä¿µÂÀÇÈ·¿ÀÄ·Ä¿»¿Ä¾ÄÈÌÊ¿¾ÃÀÀ©†rtrji]aodWVXPHYRSKFFE>>@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÐÏÌÃȺºËÁ˾»Ê·¾Ä¿»Ê¸ÁĶ¸¾·²°¶¾°ªªªnƒƒˆ‹€{~€~xt|swf_]\]^_`^_ccab``_^]\ZXZ[[YXZ\_fkfegeikor…ª¥¬¦ œ¡¥”¤›˜’¡£ª£¢Ÿ¥¥¨¦® ›¤¥«²¯¶·§°¬§ª´ª´º±¶µ®¶¹±¯º¹±·¤Ÿ£Ÿ¦±§«¨¹ª¤§§¨§²­ §¦Ÿ›¤¦¬žŸ§¤  ±­­¬²´²´°µ¼¶»ÁÁ²º¾ÃÁ²¹¹Â³À½¿µ¸»½¾¼ÂÇÄÂÿ¿Ä ƒwpkaf_ko`TY^HNgOTHEJF<=?=:;;825536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;=:7676778666;::;9;;<859<:>>@;Èµµ½¸ºÀº½µ ž•¡¦º¶«³³»³ÄÏÉËÂƸ·ÇÁÌ¿¸Ê¸¼Æ¹´Å¸´À®¸¾´®§±·±££¦t†††|yutomkjjqi^`]\\\^`_acb````]\[\\XYXXXVX[^_dcbegggjmoˆ© —•š¡–›¢˜–ž¡¢¦›ŸŸ£¥¢¨ž›¢›žª°­±µ¢©ª©««¤´¹­·°¬³µ®²µ®°ªŸž£¢²¤¦©¸­¢¦¦Ÿ¨¬ª™Ÿ ž™Ÿ¥šš£œ›¯©«§ª«¬­°²¸¯¸¹»°¶»»º«³³¹³½´¶±±µ´¿¶½À½ÃÁº»½—ƒzrk_e^ddXTW]IW\KPGIIFA<??@;?<04535:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»·ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÆÏÈÈÀÆ»»ÄÃϾ¹È¹¹¿¸³Âµ²½½®¼¼´¤¡«®«™ ŸŠ††xrnpnkb^bff]]^]]]\]_`abccba_\[[ZZYXXWWWXXXZ^bdeeffhikr¨”””›˜›¡––‘œ¡¢¨›¥¦¢¦œ  š˜­®­®² ¥¢­«¦¡´°±±¬¨¯²§º³¦¶¡¢ž›£¡­£¡©µª¢£¦¥¦£–˜ž—™š š—œœ›¬¡«¦£¤¦­«³³ª´°²ª²¹´¯©¯²²³·³®©¬®²¸°º¶¹½¿·²±”…yue^e^[YVSZUK\QLIEHKIB=?AA@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½·½¿¶¾¼¿³¥£˜¥±Âµ¶½­´¸ÂÌÈÆÀÅ·ÂÀÇηÀľ´ºº³À·³º¼¯µ·±¡§­£—˜‹„„xoqtqifdhec\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXWVWadecdeddhjv¢œ”””–—Ÿ—™”˜Ÿž¡œ–¡¡¨£Ÿž©œšš«§¯°«›££·ª Ÿ®¨¶©¦§­°¤·°¤·Ÿ¢›˜˜ª¦¡š¬¸°¢¡¤œ¢  “•¡”•–›˜—–—œ•Ÿ©©£¡£ªª°®¨´«ª¦­²°¥ª®²±°¯®¯¦§§²®±´¯¼´º·®£”yud^aVYWSRTKM^LPKGGLLE<@><B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾¸¼®§§£ª»À½À¹®´¸ÁÌÇÅÂýƸÈ̲Áî½¼¶¼½¶º»³³´¬žœ¤¬—”‘…€}wqilrtpihedfb\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWWV[cccbcbcdfj–“•‹‘”“›™œ––› œŸ• Ÿ¦¥¤¦§ŸœŸ¦ ª¯¦Ÿ¢£¶¨ ¡¢¨´¡¥¨¥°¥°­¬µž •”©¡¢”­±±Ÿ¢£˜›“‹¡”‘“˜˜’——˜—¦›§¡¢™£¥¥«¤¥°§¥£««­¦¨®¯®«¨ª©³¥¦¬¯´±®¼µ±¯¯ ’zvrda\Z]XNLRHRaMWPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8846863321./2556;:8;7876<;:;;A8x»»±µ½°»±·¬ž¥§­·»¼Áź±¹µÄÉÉÀÃÆÆȶÆijÂÀƬ¸¸¾·¾¼½¸¶°°«œ›£¦v‹‡uncbfihfhjgjm`]\[ZZZZ\]\[\^_\ZY[YYZ[WUXWTTVURURU``_`a_`acdi““ˆŽ”’“œ”•–£™ –œ ¥¡­¦¤¤¢£¢œª«¥™ž¥±©  ¥«ž§¡ž­­©©®­¡¡¢”—£›œ«©°›Ÿ¢Ÿž—™“Šž‘’“–˜˜“œ¡¢¤ ¡• ¡¤¦›£«¥¢¤ª¤«®¥­²©¦¥¦¦´¦©¨­³µ´¹º¯ª¬ž‹rpo`[WVVRGPOHZ\ORITKSLEFIC8;;=<8667:9;:976977:;:=<<6;<8>598:88659:;<97?<9678452121..1426:86:8698989;9@9{µ´­´»²¯«±­¨§¯¹¹³ÀȺµÀ¯ÆÉÍ»ÁÊÌȵʽ±¾ÄÊ®²¹Ã·½Â¾··®°©™ž ŸŠ…uˆƒ{tiiilgjlmkjme]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURSOQY]\]^^^__bdmŽ„‘‡‘Ž™“”’œš¢œ› §¨ª¨ª¦¨¥£˜¤®¤”™¥¯©Ÿ›™› ž®™›ª³Ÿ¥¦Ÿ¢£¡”“›––’©©­šœŸ¡ š”Œ™Ž‹Œ’–•ž¡ £œ›¢•› ¢ ˜¢¨£¢¨« «¯¤®·¥£¤¢¬­ª¨«¯²·²½µ³«¯˜„ssh[XXSUQEXLQ[YMUNPLPQINIB<??A?<65799<<987:79:;<=>;7;;:=67:;8976989:6:=99577571141-+/434988::8::748=8?9~³®¨³¶®©§¯­›©¨¬·¶¬»Ê»¶¿¬ÌÇƹÁÎÏȴż·»Äɲ®¹Á¸¾À½¶¹ª®¤šœžš‰wvwnmhmnmphgigd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUTSNPQYZZZ]\\^_`d~‹ŒŠ’—‘—™¢ ›Ÿª©¦®ª§¯£§™Ÿ¬ •–¤¨§—šž®–—§ª™Ÿ”¥¡ž’“’“•§ª¥š™™–ŒŒ”†ˆƒ‹’•‘ ž £—•Ÿ•š ¢“›¥¥§¨¨ ±°¦±¼§ £¬´«®§°µ°¹µÀ±­±«‘}qrbVSVNRIFVPRRLLXMJLNRGMJACFDC>@75889;9:7::7<=:;@>:9;9:?759:9876958779;85576661320-*.102877;99;8948;8@8³­¦±·ª¦¢°«ª§©²±¤¶Æ´¹º³Ëƺ»ÂËÐ˱¸¸¼¾ÁIJ±³¹®¶¶½¶¹§¨¡¢žž˜…†yjglnqnqjpkdfge^ZYZYZZZ[ZZZ\\]\ZXXXYYWXWUUTRSUSVURNNNRWXYYYY\\]aj€zv‰‡Š—‰””—›™¨šŸ©¥¤ª§˜ ¥›’ž¢š—–…„’š£“¢œ–––ˆ¢šš“‹Ž‹š¤§œ••—›’‡”ŽŒ‹Š’’’¡šŸ¢•”˜˜•¢¥™Œ™¤¦¨¦¡Ÿ´²¨²·¡¢·¬ª­¤²²¥µ»µ««±£‰xrm]NQQLOCMNNPKFNNJJNMQIMJAGLHGC=858889:;69:68;99><8:>9;?8789:886857688974577820301+)-/12776:999984988A7w¶§¤¶°¤§£©¥ ©¥¤³ª¢²Ãµµ²³ÆÆ·ºÃÊÌƳ­»¾µ¸Á°®ª²Ÿ¨°½²²¤Ÿ ¥›‹Šp^_frpvqiniehhj_XXXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQMMKLSWWVXXYX[]aosvq…ˆ‚ˆ€‘„ŽŠ”‘“ š›¢¡£˜¤–¡›•‡˜šŒs‚}—–…™”ŽŽ{™ŽœŒ‚Š€‰˜Ÿ¢ž“˜–„Ž‚“~~t‰Žy‡“š™š•Ž¢£Ž‰š ¡££›¢´¯¬¯¬Ÿ™¥¸¦¦±¡±®œ°»ª©¯ª™‚vrbUMROPMCSNLQMBPQHINSMHJJCJLFKK<749888;;69;7:<9::;79?9>@79:<89764445874312585/0102)(,-11764789::65:87A7x·¢£´¨¥¦¨£¦¥¦¦¦³§¥´Á¸¯´°ÉÄ·¹ÁΞ³­»Â¬®Ä®©£¨“Ÿ¨¹°¨¥•œž›–‚}„gWV_gfighncjigb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTQMMJHNSSSTUUWY[]ilrm…|tNXr‚—†œ—‹“Ÿ—•”–”Ž–‰“‰_;Wo{‹”‰€‹’Œ††sŠ„–y‚z…””ƒ–Žƒ†}’xro…}‰‘—™˜“Š‰œ‡ž—‡ˆ–žš¡ —§¯©­¨¨ž—­³¢¦®™¬«˜§´¢©­£“~rm_[NSRVLDTJPMLFNOIFLQMKOJIMPFII<7599999:7:;:>>8:==6:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9y· £­¡¦¦ª §©§¢©°¨§´Á¹°µ°Ç·³½Ï¿¹¯¯¶Ã¨«Æª¤žš„•´¦ŸžŒš—”x{^PLRUYZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MORMKHFHNQQMPRTVXZ`mpi{‚tPBA•‘‘}‰”Œ„Šš••Š’ˆ…•†xˆ`JQnxŠ‘„}„‰…n~”wuuw„™pQˆŠ‡|~x“vhw†ˆ~Šˆ•Š‘–‹„Šˆ”„šŒ„’š–žœ”¤£¨©¥¤ž›°ª¡¤¤‘¦ª–¡©œ¢¦¨‰ule^[HQQRMIUMSILKOIHGKNLMTKQQOFIC<769:8:;;8:;8>?99>=8;<6;;478;6775344696/3/.125221/,')+*,4833979:99::::?9w¶›¢§Ÿ¡®¡§¨¥§¨¯­ª¶¼¶¸·³Â»¶¨ºÈ¸¶¨¨µ¶ª³¾¨Ÿ–€‹•«™šƒ”ŠŠƒ}vtZMKMNOLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDDINOhYNQSTUZnƒtw~ji]U‰”‰t‡|…Œ’’™‹{†€uxsnupty}Šª…yzhv{Žprmx‹Œ’xz€{€vrr’whu„„„„{•‰ˆŠŒŠ€„‹Œ”ƒ{€˜•œ•‘Ÿ©žŸ  ©¥Ÿ˜§¤“ Ÿ–žž¤€rg`\\JVOQGJXROJMMRJJJMPHLQLRTLEHA<77;99>=:;<98@?::>=7==79937795675252572/2.,//200/-+(().1272198798775:<;7v®˜£¡˜œŸ´©¯©¥­¬°±ª½´²»¸¶»µ² ·º²ª¬©¨³°¢›’•ž‘–„{‚|vunZKHHHGEHHPTTTWWSTUUUVWWWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQQSV^uƒ}ygw—˜Ž}gyvx€‰|„˜’r‡|v{ok~­|sŠ{†’}tfv|†lohs|‰Œ‡€lyq}pmuqiq€~ŽpC‹„‚ƒ…wwz‹…}‹zu~Ž’˜Š’š›£–™šž¢–Š¥›ž—Ž–˜vnlebZWWTQJSUTOPNPVKNKNOJQNHNOKEC<;79;::?=9<:99??;8<=7<9999266856633621224.,,-..-0-+*''*.1362/876966527995y¦— Ÿ– ¦¯¬®«¨©°¯±«¼¸¬»¾¹³­¨›°§¬›–œ¥©¥¡˜š†“zŠ‘Žzu‚rzvpqoZKFGEA@CDILLMQRPQSUTTUVWWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNPQTX^eprmˆ§ªÀ~uyb{xn|yˆy|‹…omŒ‘xsxjj€‚r–‘‹}–€I“˜nhw~‚licly…’†ksl|nr{†imps‰„†z}~{vots…‚ywp|ŽŒŠ”ƒ–—˜š“•–™—ž—Œƒ‰Ÿ‘‹’†–~mhmnnWUWTRQYORTTSXUMNHNJMNKCHNGE?:89;99:><9<;::=>:8:;9?868727575541442/024*+**-.+-*(*(',-1250,4567485HA895w™‘›™šž¥­°¢¬ª¨µ¯®¬´¿«¼Â¿¦¢š•¤—„‹”¡¡™™‘”‹tŽz‡ŽŠxsyoupjnn[NEFC@<>>AFFGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_IMOORWZRY\`§ˆbšitze~pmz‹‰vˆ†tlš‘ts{jkMy…’‰„Žg1v†sl~~ƒtfet~„„…€filukq€|gqq{n“{s}|qpnum‚~wytiy‰‚ˆ‰ƒ–“’‹‘””—Ž€yˆ—ˆ†Š†€‡vjjngdWQZWYY[MPUVYXNIHEJJHGBAFDCG=998;9:9<:9;:::@<9:<98>787715244533645031.**+),,++)(+'),,226,+5775478iO8;5n’ˆš‘™–¤¨®ž²Ÿ¦º®«²°Â±»ÃǛ–•™‹…y„˜”Œ†q‡‚tˆŽ‰|surqqhrjaTFIC?<;9:?@ADDEGJLOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOOQVLAIQIb¯³ q|xm}lrƒ…z„††yr •tx€su”‡5q¨Ž¡¡„¢…vp†|‡|sŒ­‰€hfbinrmpƒuioXupŽš’wl{}mqmp€zsvmbv„†€…‘Š‹Š’‹‘Œ‹ƒux‹€~ƒ€~zqpok^Z\][YX`^RN[ZXWLHJEJG?CABG>CD=;97=;:;;9:99;:?<88=:8;66651121353475531./,,+)*))***)(*)+/3DM2166643<vR7=7b’’‡–‘ž¤§ž¯•¥µ©­±®Á²»ÁƗŒ”€ˆ}n’‰ƒŠ‡…u‚„l–‰Š}wyynxpxfj^IPG>@7448;;<=>@BEILLLMNPQSUUVWXYXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL7CMRSDJ†v€||v~mwˆˆ|}…ƒŒ~v¢™y~†…™„›œa†ªŸŠ‚Žzwˆ~‰ˆŽsŠ—ƒ{\dqtz{wŠlgjbyo…‚znwt„zptywkni]w‡}‡|ˆ‡€‹“—ƒ…†}q„„|uw{}‰uorsef_[Z]S[f^WQUX[UGJJDKG?F@DC>AA=:97<;;=<::99;;=>79>9986754244004645654-,)+('''&(())((+++/00Uq<23331E~W4=9\xŠ”Œ’Ÿ¦‘ « ±¨¯À±ºÅº–Ž‘”‡z…vkŒ‘‚}Š„ŽŒxƒ€s¡…Œ~~‚p€~ziwkRWL@E211267688:<?BEGFGJKMOPQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMORLKT]YRJi„ˆ{‰y|q|Œz|‰†~—‡v¡™ˆ‡’”¥¬©H†®¯¯‹€“Š‚‹„‘¨‡€˜˜Šœsl|†‡}Žhghx~n…†‚…q„…Gk€wryvhmk_v}ƒˆˆ…Œz•žœŠ‹ˆ‘{u‹v|wmow~rrqkZ\\[ccXfe[UOPVYPDLKFNICFCCA@CA=978:::;;:888::?>6;>7585773344236656768;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|~Š…ˆ‘–—’—¡¬¡¦¸¯³½³—’‹˜‹}tp‰’~}Œ‚’”}†~†¤‡ˆ‚ˆ…x‡ˆ~s„x_cVKB60./23123668:=??BEGHJLNQSTUTTVUSQOGC?80,#‡[>?94.]–ps£UFIKMNPW`YpZ\^j“‡•„‚…‘“~…‰‘š•‚¡¡—•›š¥­“š»±§»Ç苌¡¥”‰‘{r„žŸ‘œv……Š‡ihoƒ€tŒ†„‹q†‚w‡€{v…}nvug€”†‰ˆ‡ˆ‡¡«¢–‰Ž˜{‚‰zzogkx~x}qjc]ZZ]i\af_YOKNWRQIPKDNGCKDCADCA<:87=<:<:88778:==8<=68656623445576867<BB?<8:>CQ^e\G2'&,,--.1(?Œ[.310Oƒ_4?;nupgxƒ{€Œ€‹šš¤œ¡¬¦«¯°—‘‘„¡”„xwŒ”|’†’•Š€’›Žƒ€‹‹‚‰ƒŠlpj]CA4--//./02234779;=?BDHJOQRSRSTTRPOHDB<87/9D><<63.l“—MPHIKKKNV`cggmu›š““‹Žšˆ“‹  ’£ª¥£¬“¨¶¢¨Áîǯxº”š|¡ž™„“…‚¢Ÿ”™’„Š…˜‘–lpu‰‹•Œv„ql…Š–’ƒ…ˆr‰¡–†“Š–¥µ©›•¢ƒ‡“„~kjk|€€r`\b^Yfj\kk^WKGOSQNMLFIPDDNFBCEGB>997=<:;:987767;:6=:785456345566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<unhYpƒpu‡qv’†~—–š”ŸŸœ§ ª–“˜žge¤š~„’‘y€’ˆ’}Š…˜’‘‚€€‹‰…‡„ˆ…xxgMR>/..,/.-/000212457;?CFNPRTPQRSQNPIED>;<:CF?><752<?R5HHHLLMNR^oŠ|s} ›¨¦¢™¡—¢•œŸ¨ž©«Ÿ¨¬©ªµ—«¿«¶ÈÈ·ÉÑϾ› pi«©Ÿ„”’†œ¡šš™§‘‘ˆ•¢ššwz~”—‘¡’–—”ž{v•’«³‰— }”žœŽ“–™¤¢¦¶°‘™¨ˆ—Žˆlss|~zog_[_^afc`gg\QEJKPOIJLFFMCHLFFCBGD@:85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Pqu`n}bwŽ}|”ŽŽŠŸ’—ž–œª˜žªBD}‡‰‡˜x‚ŠŽŒ{Š†Žƒ€‰‹Š„’…ƒ†ˆ€‡w_bP460-1/,.00./..0015>AAMQRSPRSUSNSLEE@<>=GG@A@8662<9;FHGIIMOQYm†w•‹£§ª´½¸¥®¬¬§¨´¬±·²²­»±³¾œ³Ä¬»É˸Ŀ¸¥£°²¬­«¤‹–˜…¦¦ ¢—¦™¢ª¨¤‡…“£  ª ¤©Žœ±‹•£§·»› £°“££ž‘¤¢«¯­³µ¢•¥«‰šŠ“Š•z{~„}f_g[da]cc^ff^[OCIHTOFHLFKHEFHAKFCFFA:87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLicXjpXz…v”…ˆ‚›ƒ’’Úȝ–sV—ˆˆœ|†ŒŽŠ‰zˆ‚‡‘Žƒ…€‹…†‡’†‚„‰†‡‡‡qna@E64<2/110-,+-1/-4?DAMUQRTUUWUM[PGGD<>>FHCD@8;<5C;=FKIGHROPW“ „®£³ª²ÁÇë³Å¶¬³À³¸¾¶¿´Á¶»»¤¸Æ©¶ÉǶ¾¹´¨£´­±±œš’šŸ‰§¯ª¤•vŸ¤—¡«±³˜–©­¨®µ»²º¬¯µ¢±¬±µ¼·µ®µ §§£¨›©°­²º¸¸§œ·©¥’“ †y‚‚tX`cUea`b_`e_ZUJDELUQIJJDJHEA@@KDAMF<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AEWQJL[ZQcdWzuq‚”}…†“v†~€{¿»£¼‚´”“›„ˆ’‰‰y†€Œ“Œ‡…Ž‰Ž†…ˆ…Š‡‘zyn]V@EM<6:46AB764//6CHCQ[OQUWU\WO_UIKJA@?GKFED;>@7D7?BJJEGWTP^¥­£±´Ã¶¸ÁÌɶ»Ä½³´Á·¸Âµ¿°·t±´¦ºÅ¤°Æ¹±³±´¨¤µ¶ª± ¢–›¢’¥±­¥­¬§¤˜ ¬²º¢¨²¹µ»¾Ì¿ÅŽ½³Â·º¸¿·º·¹­­±¦±ª­¾°½»Â¬™»¨•­˜˜ª‰~‚ziWa`WidhdVZcYVTIGGLQGDIJAHD>?BBK@@LC99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FQLALRWTZVZwjp„Ž…nzsxˆb¸¡š£‰•”–“”“—’‡‡{†•Š€„Šz|‹‡†}Š‚‹„•}xyueO\dGEL:Qda[^SF>;HPDZdQQYXZgZT`aMSOEA?IJHEFA@C=E6B>HGKMSZT^”¯¸µº¹ÉÀ»½ÉÌ»½À»·µ¼»·¾µº²Æ`u²¥±šž«¾ª¥¨«ª£¢²µ¡«§ž•–ž˜Ÿ®¥§¦¥Ÿ¤“¢§°³¨²²¼¶Á½ÓÉÉÓÆÂÅÌÂÊÃÀ¾½¿»¼·´°¹··ÃºÆ¾ÃÉ°žºª¢¬¥¨¶‰~q^a`\Va^geRXaVRUIEENK@>GD=KB=B@=F>;H@796379>489:57045/26389373526?8@>GKRTTRPOQRQJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKE@IMPRLQ]gmlq…smsrsˆÕÀµ™ •™š‘Ž—‘––Ž†‡}†ƒŒ–‹ƒƒx{‹„‡{‹yŠ‚—t}zkepvY]\Peeb`ed][XW\MdmURmn_o_XgeUYTJDAKKHFHHHHBI9D?HKTTV]Z\“¹À¹½·ÆÀ»¹ÊË»·º¶¸¹³¸µµ®¶¶™du©ž­p^¢­œ˜¡¢›¤ž«¥”ŸŸ”–˜—¨Ÿ¥Ÿžš™ƒ¤¬¤ª°­·°¼¸ÔÐÎÖÏÉÌÒÌÏÎÊÇÀ¿ÂʽÁ½ÂÀÅÄÆÊ¿ÉÏ´¤»±µ°›¬¹½š~xj\_[X]`YbbQ[`SQKCBEFE<@E>BHB@C=:E>=J?47535;=468977022/24169775555D3ELM>510006:477@IOJ;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODR\Yi`o—’‘”nlotu‡³¬¡¡Ÿ‹™œ™•‘›’…ŠŠ~ˆ‡ŒŒ‰|ƒs{Šƒ…|Št‚Š†•s{xlmu|iseilifjji`fihmZmt—­¤¼‡‡g[oh]ZYTHJNPJKQLTQHLAJGKP__bgjb—·Ç°¹³»¾¶²ÄǶ°¹±°»¬³±§«·¬¶§žœ§šN›žŽ –‘¦˜¥•Š““ˆ‘‰’ž›¡˜›•–‡ž™¦š¬¯¨¯§³³ÓÔÔÖÑËÏÓÕÎÓÏÌÆÃÊпÊÉËÉÒÈÍÍÃÑÒ¸°Ä½Äº¦·»Ä¢€mb[[\W_WYeYP\WNQCBHEBH;AD>AH??B7;D>@H=46655;:687654/10146278875367C5B8?-0,1349=97,.,1;FL=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYSfWs™ƒhqoyyƒ ªž¦—››˜‹•‘šŽ}‰‹…ŽŠŠ‹ˆ|„‚p‡†{‡rƒ’‹}qxulpxr{nxsli€pmcimpyiw}~Ë¿Âߧmcxod[a`JPRUNY^P]]NPNTQUT\nnwƒr–®¸¬´¨°¶«­½À±«µ¦¥¸§¬® ¬´¤±®›˜˜Œ‘”‘„›¦‘œ‰ƒ‹„Š‰„Šƒ”•˜—”›‘›—™™žž«¬¤§¡¬¬ÎÒÕÑÍÌÒÓÔÐÔÑÎÈÃÔÑÈÎÒÓÓÖÍÒÑÅÒÖÆÀÎÈÈ鿸Нxld\a\U^Q]ZNOSPNH>AFBBE<@B?EE>??:===<JA45465<888664412/03526768533;=<E=@11+/349?5901022-2EO3)/3.32=N248C}_2A†tD:==I>@CFH<VRMO[u‡†‹wmwp}~€¡žž¡‹™““ŒŒ“–…y†‹Šˆ‘‡‚{r~€‚‡z…v…“‘‰ovsls||w|s‚xqk€rrioqzyr{¾Ëš~Œ±ƒvr…whaj]CZZ[WfdXekTX]\`c]cx{‹™ª¤¤¢ ¡©¦ª±¹«¦´£¢­¢£­¡§±Ÿ‰¦›•“‘Š’Žˆ‚”‰k•¢™„†~‘ƒƒ“–¬‹••™Ž…’—§°¢  ¤¤¨ÇÍÏÇÁËÐÓÑÔÒÎÓÍÆÖÓÍÔØÖÖØÕ×ÕÉÔÚÍÉ×ÖÑÊ­ÄÃ̊qmb_^WRXR[OJGIIJ@;:;EBD<BD>HB?BB;;9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/-.;R017/532ED28>nb5=tM99@I<AD?A;PLFKYp€u~isyr‚‰•ž”…‹–‰ŽŠˆŽˆ€xƒ”™‹ˆˆ‹‰~ƒxs{}„‡w€{‡‘—ƒnwpmuvx}t†|yl‡vuo}v„uy{µŒ<AŠÆ¥~|jeWICecfchjdoy[_fhknin€„ˆ‘ŒžŸ ž‘—˜Ÿ££¦²¤¥³ ¢¥ž¡¨Ÿ¢±œ‡Ÿ’’“‘‹Ž‹†ƒ„~œ›Œ‚„…z”~‚ª•£Œ’Š˜’‹}—Šš‘«³—š›§œ§½ÃŹ¶ÅÍÒÐÑÏËÒËÉÔÏÑÕÚ××ØÔÙØÍØÛÎÉÚÚÒÖ¿Ì͵vumc\XQUPYUEFJIEE=:7:@AC:GE@ECADA;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?1*(.BT29254/7K75<`bA<svV87AH:?C><9QECJTlnopbqqs†|—‘‹~‡’‚‰†…Š‚ˆ}y…——ˆƒ‡†‡z„yqz{„†vz†ŽzŒp|opzr{€q„‡€nŽzuw}|‚u|‡‰°tY©Â¶Œ’pnc=^hrpqpnxw‚eioruxr{‹‡Ž“’›– –ˆŒ“› ›ŸªŸ¡­œ¢š™Ÿ¥žŸ¬™ŒšŒ‘’Ž…}ˆ‡ƒ…‹Ž ™“ˆƒ‡~m™y„™†ˆ“Œ•Œ†{›ˆ“®«”•—ž˜¦®µ¼¨­½ÆËÈÉËËÏÉÃÑÊÔÖØ×Ø×ÕÛ×ÓÚÛÖÐÛÚÑÖÉÕ̔wyggZYORS]HBEII>A>=7:=?;>H=@BAADA>?:87DB755479.566435532323647553457EBDCEB56<FNSM[nfcnsk`V>,4LG865433BF4=W_hLux^8;?F<<B<:9D?CGRk_mdbfkv€ˆq‘›€y€Ž~ƒ‚‚„~„|}„˜Ž‡Œ~†‡€w‚yn{{‡‚tz’ž¡vu‚tu}t€„o‚‚o’„t|…zv‡|‰¸Æ¥ÃÉ·•›xpeNec‚zw†¢‹yyw{„|„vm”–”•˜‘ƒ‰–š——¦œ˜ —Ÿ“’—£™«–‘‘‹’ƒŒ…‰ˆ†‘žœ™‰…‹…—{ˆ‰Ÿ—‰Š‹‚|¡ˆ‹¼¡˜“—™œ¨¦¥®ž§µ¾ÀÀ¹ÇÉÍÎÅÍÊÑÖÕÔÙÕ×ÛÔ×ÙÚÛ×ÛÚÙØÎÛDžywehc_SVVUMKDND;==<9:<>9>A6>?@=@><9867CA6455=80665547745613854564557HH=DJE7925;H>;::7HP\ZRUXK9T>;95327I8=NYMHxxd5=>C=<@:6:>>@EQ_Yea][htzyl‰’wvzŠ|~€|…{~‚‘Š…†z…ˆ{u}um}}†~t’ž‘Ÿƒ’|†}x~y‹Šoƒ›€t™†}‰…|~‘{©ŽÃ ¼Œœ£œ}‰„}‰rŒ‹s¦šœ™”…{‘‰„iGq¡¤Œ‹’…ˆ‹‘“•š“•‘—Œ•Ÿ”¡”’ŽŽ‹~Ž‹„ˆ’–šŸŸ‰Œ”‘‚Œ¦™ˆ…Ž‚†„€¤†Š‹¸˜‘”–¡§ ž£®¶ºµ«¿ÅÊÐÈÇÌÏÓÒÒØÒÕ×À×ØÙÛØÚÚÙÙ×Û·wwviidV^ZSONHDLB==>99;:99<=6@>>==9:;;37D@8378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWN<MTHN?96333>C;[X>5YypZ<<A<=>8589?=DRSRX^UXfmmmiŽŠqsxŠ{{}{ˆ{}{‹‡ƒ~u„†ysztm~„}w†›¡›ž”’€‹‡˜‡€œ’nˆ©…z ‹|Žƒˆ„œ~š‘‰£¢Ÿ£®Ÿ‹‘‹…‹’†Wr­‹Ÿ¬œ„˜œŽ\ƒ¢‘‚Ÿ“•Œ‡ˆŒ’“Œ”•”ŒŠˆ–›•–‘‹“”†€‹‰’ŠŠ–™£¢†“• ŠŠˆŽœƒˆ€ƒ‡…¤…‹³˜œ’”—¡¡ž™’›§±¸¬¥¼ÁÇÍÇÆÏÌÏÌÏ×ÏÑÔ®ÖÕØÚÙÚÚ×ÖÙٞn{sfe[\WRUWC@ID??>:49:;7:;:3;<?=>7;9:1:G=:27=@50677255?65;55858:57735HR7GOK994=EJB>1FCLA98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:<@;BQKKSYPTcbxlb~’ƒomw‹xz{}†|{v†…€sp…‚{vwvt„ƒ…}’¦¢Ÿ¦¢–‰”—ŠŠ§—rŠ²„§’„™“„šŒ£– ˜“‰›¡’¨¯Ÿ‘”ŽŽˆ•‹n·„šÄȲ¢¥›˜–‘²d¤ÍȕŽ†‡‰’“”Š…ŠŠ†–š›”“‡•˜„€‹™ˆŽª——¤£ˆ™ž–š‰†——‹…Œ†¥ˆ“¨™—“–˜¡˜Ÿ™“›¢²´¥£¼Á¾ÇÅÅÉÈÉÂÊÓÌÍÔ¨ÒÑÖÖÖØÚÔÓÚ΁q}gb]]\NITYABGD;A=837;<:8=649:<:72?9929I:>67BC32:96264>=4;>6949;57944KQ<JQK9A7BGI@64JELF>;88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBcFv}|m~ˆxz~{‚‚ƒvv€ƒ|mn‹z|xx|„‡Š~‹£³§£ª³¡–§Ÿ¥¤–•®¢ƒ‘¸•‘³šŒ¡¡Œ¤›°£¤˜‘§–§™¬¯¤—”–•‹˜™—¡ÀŽ£É¹«œ£¦­™’›²……¨¢œ˜…‰‰Ž•Œ‹“ˆ†‡‰“˜•Œ‹”“†•˜†„‘œu‘˜²–—¤¡ˆš“ŠŠ—›‰Š–Ž†}Œ˜ž‰œš™“˜—Ÿ” •ž› ±®¢¤·¾´ÅÇĽÃÿÆÍÊÉÒ¦ÎÍÓÒÑÖØÓÐغqxt[_T_UOHJNDBCE5>:77:?<<7=42669774=5;5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=88567=:JFDGN[\YJf`;H„‹zzn…†z|„y†~px|~}orz}|x†‹‰†„’§»¬¨²½¯¤­³³¨£¡°¬Ššµ¢¸¥•­¤—©­¸§¤£Ÿš©—©£¯°©™˜œ”•‘— ˜š»»®Ê¡j¶¸«°”™Ÿ£¬“—½£^ª²ƒŠŠ”‡‘|ŽŽ}ƒ†Ž”•ˆˆ“–Œ–‹Œ—˜“™´—–«‹œ”’Ž‘’Œ˜›Š‘ž‹‰•Ÿ¡”˜™œ’›˜ž”¡ ”œœ¥¯¨¡¤³¸«ÂÈĵº½»ÅÇÇÂÑ ÆÉÍÍÅ×ÖÑËÔ¡oyg[YS]POEC><CAB8?875?G=<6<35345454B39:BM:B;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPdGb`bpJ@‹Šs†‡}‚ˆuƒŠ‚m|}}pw‡wŽ‚‡{Œ†Œ™ªÂÀ¯½Æ»³´À¼´­«³¶Œ¨²­­½«›»¤¨­¹¸«¦¦¢¢¤¢©¯²±ªœ¤˜›˜—ž¢¦¥’¤º¯©À¼­­²¹¦¤¨~ˆ†œ­¼°ƒŒŒ‹ƒƒ‘Žz‡œ‰ˆ—‹•–”‘š—¨š±š‘¬œŽš’Ž•–—Ž‘ ‘‰”›£¬”–”œ“ ›˜ ¡”šž§¦¤¢£°³§ÁÆï°º¶ÅÄ¿ͦÇÄÇüÕÑÍÅʇrq`ZX^ZLJBK@FG>A?B;:4>A==5<6>333241A17@BN>G@CNCA=C=;86CC5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GD?CF\eG`igZ]\“ŒŒˆ{‡Œ‡ƒŒu†‘Šo~{q~{•z’””˜“•§³ÆÉ¿ÂÌÂùǼ»¯«¹»—²·º²À®¥À¤«¯»¼ª­«££ž§«®´°©› ª›¡›–Ÿ°µ§‹£º»¶Á¼¬¨œ²¥¤¨”…Ž©Ä䂋‡ˆ„†•”z„‘‘¢ŒŒ”‘Ž‰—Ÿ˜“™•˜¦ ®ŒªœŽ–’‘•••‘¡”†—Ÿ ²ž”š”Ÿ¡˜¤Ÿš › ”˜ž¥£¦¦¤¯®¥¿Ä¶Éþ¶Ï²Ä¿Ä¼³ÑÉȵswk[VZhQLHCLKKJAA=CD<5AD;;3=8B332263A05IEN>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBeYNe\fTcj™—ŠŒˆ“†‰y†”r€|x‡‚‚zŽ¡–¨šš˜º¾ÇÈÉÁÒÉÊÂͽ³­»¾§º¿½»Ã·¬Á©¬³»¾ª°ª¤¥¤¬®³­¶µ Ÿ®Ÿ¥¢˜£³½©›¨½Á¤··°«“±¬«¬—‡š©§¥‘‚Œ“¥•‰vŠ‘z…’žŸ“”‹”£™–œ””£žªŸ‘¥šŒ•–ˆ|•’’£š• ¢œµ¥ž—¤£¢¥ž¦˜ž–—›¤£©§¢²¬¨¼Àį¥²·ÌÀ¹¯Ä³»¾Â¸­ÂÃÂÀ˜kx`WVZZJKMJFDDHBBADL:4DH9;4<7E.12352B26SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQG7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>jH_XaZddVžŽ—Žž’‰Š‰ “„x…•ˆŠ€–¡™®¦¤˜Â½ÇÃÇÅÓÍÎÍ˼·°¹¼´¼Ë¼ÃÁ¶¶»­³¿¹¼®¯¨ ©¨¶­®©²·šž¬¢§¡ž«·¸ª¥°¿Å±½¹³§ªµ³­®—–¥¬¨ ‘Ž’²Å§•Ž}’•}ˆ’™ª™˜““’•“¥ž’™”¡£¢œ˜Ÿ˜‹ŒžˆZ–—’–¤™e˜£ž³¥–¡–¬¬ª§›ž¦—˜–˜• ¤¨¥Ÿ¶«©¹»Ã´¥³µËÀ¸ª¶¬²º¸®¨¸º½¸‚jmYVSTMEJRNK?AHEDHGG95FM;>8=@J.32025B55PWN<LFKRLOHGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|gV;=@BFBpEiIRebLF¥”œ—¢—©–‘ƒ‡¦“ˆ‚‡‚œƒƒ•”š¢Ÿ¯¾¯¡Æ¼ÅÄÆÆÎÎÎÒʾ»¶±º»¼¿ÏµÃ½¸¸·²±µ³¸³«¦œ«¬¹ª©§¯¯—£®¤§¤¥µÀ°«¬´¿ÃºÀº³§¹µ¸³¯–¥­®®¤‹“•¡tÁš}—™„–šŒ±•›š•’“™™¥£” ›—š©œœ¡ ™Š–œ`J–œš•š¥–T–°Ÿ¯œž¤”¯®«¥š ¥”“™˜Žœ §¢™´©ª³¼»»ª°²Ç¿¹¦¬«­±±£¡±²´¤old[YNOKEOPQQ;GJHGICC>:KU?A:=EM07544:B34NWO<JKOUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@BAF3>58JKCA=C;4EA:A?>H@5*B52,>c]g:35tde@R7&#3}hW;:BC@=QEWSsbWFHª—™ ¢¨¯™‘—‡‹§–Žˆ“…Ÿ‡„—Ž¡›£¤µÈµ©ÆºÂÃÇÊÈÈÌÍƾ»³®¹¸ÁÁ͵ǺÁ¸µº°®¯³´¦¤›ª´µª©¦­¬š¤­¥¤¨¬º¿¨«¶·¾Â¿¾¹³²Ä²¹½¬£®µ¬¹¦ˆ›—¦›v¿Ÿ„™Ž“™š‹®—¡œ›–•›Ÿ¡©ž§Ÿ™šª™¡§ž˜‘ƒnv’¢š•¢ž®²¢ª”¨ª—ª­££Ÿ¥¨’’™œˆ”œ¢–±§©«º¶½³²­¾¹· £§¨¥§œ›¬©©Œad`^QJLFHMIVL=MDNJKBCD<QV=AABDO18=77?B75UXN?HNQYSPQUKQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW;:=.-R`MUHe^HE«•œ¡Ÿ»¯™”Ÿ‹“«›‘’“‰«‡¢ŸŒ¤­”££¶Æ¾´ÀºÂÂÇÈÅÂÍÈÁ½¹²¯¸´ÀÂʵŲÁ¼´ºª¨­­°££˜ª´»¦©¦«ª©®§£ª«¾¼¨­¼´¸¾Ç¼·¶¸Á±¾Á´©µ·«¾¥¢˜’¢ ¼Ÿ‰š ™—žž·Ÿ©œ¥¢›œ¡š¨¥³¡›¦œ¨ªž™•”›‹—‰Œ¤¢”¢ž µ¯¥¤’¯«™«ª¤£¨‘••Ÿƒžž›•©¤¡¡´´ºµ­¨µ²³žœ¢¥š—•˜ª¡žv_[_]JHEFMQHMEFGBRLIBEGAVRDH=AGQ1;B7:BF79\YKALPTUSMWRNUJD@JJNO9C@5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-19g\FCCœpbGE§—¤ŸžÃ­›—¥˜™©œ–››ª–•§¦•­¬™¢«¶Ä¼¾·ÁÂÀÇľÍÆ»½¹²°¸³¿Âȵ¿°¼¶¸¶¦¤«¬­¡¡šªªÅ¢¤©«¦ž¬¯«¢©¨¿·¦­¾±¸¶Ç¶µ¹¸À³¿Â·µ³´¯¾£—£–”œ”® ¡£¥££Ÿ½¤©ž¨« ›¦Ÿ½¢™£Ÿ¢©«¡–•ž“ž‡„“Ÿ¤ žµ¬¥›•±§™®¦ž™©Ÿ˜”ž„ š›“¥¤š˜«±µ±«¥ª­¬œ˜  ’Ž•¨ž”gbX`]NHGJNKHEDIA>PH@<GIH[ROK=HOU4BF9>HG5Ca[KCNRUWVQXTRUI@8RQPM:GA4CHQSIC;C>GVKC@O>K<06;GF>;FA46@9:?9;15D0-,/Mv\4KZ5,MnW<-=)#zbQ5CKQ:nRF<KxebVL¢š£œžÅ¬¡Ÿ¬ž® ’£Ÿ–¥Ÿ¦ª¬—¶±£ª³¶ÄĽ¿µ¿Â»È¾Êȶ¸µ´°³³·ÁŶ¾±¸µ¸µŸ¦¬ª¬ž¥¤Á¤Ÿª­ ¤©­¯¢¦¨½µ¥±¼¹¶¶Ä²´¸º¿³ÄÁ¸¸®³µµ£¥•’”¡® ™¢ž¨¨«£šÂ­©ž¬­››ž™¦¡¾¡¤˜««¬¦¢™šŸ’Ÿ‰ŽW–Ÿ¦¡ ¸ª¦“˜µ£Ÿ± Ÿš®–žŽ˜“ŽŸ—•Ž¢£–¦®²«©¡¢¥¥••˜‹‘’¤ž‰`cYc`KHJJNEEAFJ>=JB99JKN]QQI=LV\9FI=DMI8Hb\LCLPSYYVWOZ^IA=WQIK?H?5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+w`S6SZkWrGE6=ue\KNžŸ¡™žÃ¨¥¢´¢œ²¨“«¥ £Ÿ­©¬»°¨¬¶±ÈÅÁ²ÂýÆüÄʼ¯°¶­°´¯¿Ä´¹±°¹´¬™¨°©ªš¥¡¨Á¬›¬°œª£®±©¤¨½¶¦·»¾¯·Ä­´³ÃÀ³Ç´»·¬´¶­ª¢¦–••¤¬¢ŸŸš¨«°¯¯»²¦ ©¨š™˜“¢¤¹ ¡¤“¯¯¬¥§Ÿ’¡ž•ž•žš¢ž§´¦¦Œ˜³›£®š›­ž“•“™‘¡–Ÿ¡“‹¦¬°¥¦¡œ ž’’š“…‹‘œž`eZgeJILJRBC@IG;;G?99OMU^RSJ>O^]=HPBLLI9Mc\LELRTY[SUO\bHA?ZQAHAKB7FELKM?;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<v]^?[T^eq@8;H–weA4Ÿ£Ÿœ Ã©¤ª²¡£´ª–³¬§¢¤²¬®©»±­°µ´ÆÀÄõÀĽÉĵÀÈÁ´«µ¨¯¸¬¿Ã³·®¬¶¹¥™«²«ª˜Ÿ¦—­»´›§°›­ ®´²§«¹²§º³¸²¹Àª·²Ä¾µÆ¨¿¯­·µ©§¬¡——’¦¥¢¢˜˜¥¯¸®²µ¶ Ÿ¨¤š••“¤ ·¢¤¥–¯±²§ª¦¢Ÿ›š›–—¨Ÿ ˜¡ž¯²¢¦Œ—®˜¤ª—™ž¤š“—™…•ž”Œœ“‹©©ª¡§ ™ž•ŒŽ™…•ˆ”Ÿxbh\jjMPMNT=CANC::I?77RO]^RVQAW`\BJSHVKH:Td\NFON[W[RPQX]GAB[PBG>NC9HGHOP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1[bZ33806p[bH05IphVCWFŒyfC;££¡¦¿§¨¯¯¡©µ«º±«£ª´¶±°¹·°·¸¸Ä½Ãǽ¼ÄÁÆÀ¸ÀÆÀ¹©¶¤¬»¬À··ª¬±º¢•­±­²–¥§‘ª¹©Ÿ¦°« °´³ªª¶¶­»¬³³¹·¬¸°Ã»¾¿¦Ã«°·®©««¦ž˜™«¢¢¡‘—¡±¯³¬°¹šœ© ™–’—¦¡·©¥£¢°±´«³¨¬Ÿ›  ›¥¢—£³°šŸ“¥šŸ¨š”¢”—‰“–’•–œ“ˆš™”Ž¨¨¦Ÿ£›—›“†Ž˜‹}Œ–…Žšjhl`lnWPQZTACET@;;HA7:XPd^PVWEY_]MLRN^KJ>Zc^NHPO\UYPKTWZI?DXPDF?N@=IGGQPB=DFBM?:1D?77547?=95E4+75/251.-.,1=*'+=\p=>1.0dZd@1647gY`F(?8l}g[V;‰{cC=§Ÿ¢©½¢«°«£±¸ª¥¶´¬ ­µ½®³¸»º½¶¶À¿ÈĹÄÂÀÀ¸Ä½Á·¯µ§«·±»¾¿´©®±¶ž—«®¨®—¦¨Ž§»Ÿ¤¬³ž¬¢±°³¬ª¶´µ½®°±µ¬°µ²Á»Å·«½¯±¸¬­ª£±¦ž¥©Ÿ¤˜™Ÿ³ª³«ª³š§›š•Ž ¦¥´®§¡­­®±§´­²ª¤œŸ¨£ž•¢™›¨µ©—™‘’ž™Ÿª–—„”–Š™œ“Š–—š—¦¥¢ –•—“”…{Ž’ƒ‹–elrgoq^FYfVDCMXDZ9HB6>]Qh\NY]G[^]NMRXdJJC\b_PLMNXWXPJVVWL=EUJEDAM@AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,,%2+*5K1/'__`U150=`V^8)C3YT\gK6ŒzfL@¤š¡¤¬¶¤­ª¦¯®·ª¯µº§§±·Å·±·½Áµ´ºÅ¾ÌŹÂÀº¾¹Ä·À¹²´«©º¶»¹¾´©­°µ˜˜§¬ª¬›«««½«®²£«Ÿ°­´®­¶²¹¸ª®¯²¨µ¯´¼½Ê³ª¶µ±´°¯§¡³ ›¨­ ¦––šš²£­ ¥¯—¡¤šš’Ž£¥§³©¡¦³¬©µ¥¯±µ¯¤™­§š˜Ÿš™«·¢—“‘Ž—œ¡—–”«žš’’—Œœ™–‰”’ž™¥¢¡ ˜–‘“•zŠ…{ŒŠƒ‹’jmxmu{aE`jYIHYZ={JFD6AbTi[M\aJ[]ZRRRbaLKE_``QLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`U`/5(C_Q\.*B/JGP[H3cYUKD™—¡±¨±ª­¦¤¯®¶©·´¹¤¬´·É»´ºº¿¿´³·ÃÀÌȼü·½¿¿·¿¼±½­§º¹·¶Â¶ª¬±·”—¦®«¨£°ª”¯º£¬±³§¨£²´±±°µ±¸´ª®«²§·¯¶´Äƶ©¶¶¬°­©§£¶  §±¡¤”œ™•±ž§œ ªŽ¨£žœ–˜¦¦¥¸§¢²µ¬§±§®°¶¬¤™ ¬¨›œžœ”©¸œ”ŽŽŠ˜›¢—˜¥Ÿ”‚‘•œ›—–•ˆ–—š§œ£ ’–•v„‡{…„Œ‹mpwt{~\Kel\KNc\>b{GI8GgWf\L^bMXYWTWTi]OOHa]_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANHf27'GbLV%-B-=ELQ<3rkICC™¥®¥­®«§¥±³´ª·±· «µ¹É¹®À»Â¸³±µÂÂÎÅÀÁ½´½¿¿º¾¼²Ä§©¹°¶¶¿¼®«³²œ §±­¦¥¯¥ž²µ«ª±²­ª©´»­´²µ¬´­ª¬¨­©¹­²±ÈÀ¸¥º°©­­¥¨®°¦¥£¯¤©œžœ›¯™££¢£‘¬ž£  ¢ª¦¦¹¥¬µ¶¥ª«¨­¯¶®££©ª› šš’¤³™Ž‰‡¡ ”Œ”œŸ“‘„’’š˜•“‡—’•™§›ŸžŒ’‘Žv}Ž…|||‡‰ˆpsq}|}\Sdn^NYf\FD–[G;NmXb[L`bNVWVWTYg]QRLcZ[TKGOTSNGIVS\N;P^IBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3Bc;6*HeHJ+;H?3BHS,>k;GHœª«¢©±¤©¥³´±´µ²²¡¬®½Ìº®ÀºÇ±´­´ÂÂÑÅƾÀ²½À¼¿·»Ä§¬·¬³¸»À¯«±­ £§­ª¨¤°¤«²ª¯¬°¯°®«³¼§¶±²©²©«¦¥£­º¬ª±Ãº¶­»©¨¨­ª©³¥©¤£®ª¨¢Ÿ¤¬•¥ž˜ž™¬¢¨ª¢¬¦£­¬¸±²¡©¢ ¬¯±¬Ÿ§¨©™¤™™ §˜†„ŽŠ‹žŸŽŠŒ•›Ž…†”Ÿœ•—”†–““—¤›œœŠ’‰~}‡…|w~‡…†srqˆuk_Y`ncQsq\K;„|F?WtXaZNc[NVVUWQ\b_SONhXWWKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*25>10485(5/*,.30;),,'%234$,2-860)(1<]J0.JgDF8<B05EKX1@•Z>LE•˜­¨¡ª³œªª°¶­¸µ®«¥«ª½É»°½·Â¯±¬³ÄÃÎÏÿ¾³¿ÂúÀ³Èë®·­²¸¿¾²­­«¤§ª°©§¨±¦´¯ª°®­²±´¬´»¤¸³¬¬®§« £ž°·«ª­»·¥·¶¤ª§¬¬«®¡©§¦±²¤§¦¢¢¬–ª¡”› ¦ž¤¢«¥­¢Ÿ§±·­®£¦¢›ª«­©œ¢¥¤¤™ š–˜œ“‚‚ˆ…œŸ‹ŠŽ‹˜Š‚‹—£š‘šŒ“’‘“¢™›šŠŽ‹Š|…€ƒzt€„}sv‹£‡xj^`nfWe‡cN?g“LEbyWbYReTMVUVTO\]aUKMiWVWIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*39?./463)4+*,+.#4.-+&(+79*&6+<-2,&06WZ.0JgAA<<B+:JO^4D†>HFD—’°¥£ª±˜«ª­¶¬¶±«¥¬ª©¼ÀÀ¸¸³»µ¦²¯ÄÉËÑ¿Áº¸¿¿Â¹Á¹ÀÄ­±µ±³º¿½²°®­««§¶ª¦­¯ª¹°¨±²®²­·ª··¦´·«¬¤©ªœ£ž³³¨¨¤´µ ·® ª¨«©¬¨ «¬©¹¶©ª©ª£© ¬œ’ª¡ ¤£¦£ªžœ§µ®¨¦ª££˜¥§§ªœ£¤£ š˜ ‘Ž˜‡Œ‡ƒ†„ŠŠŒƒ…”¢™Œ™‘‘’Ÿ–˜–‹Šƒt†€~xtƒzw~ˆoqggqx\`sˆkO^™VHmxUdVQcOMUTUPOX[bUHPiUVSGPYUI>IHOQPxLMV=<KD?@A<@CUC9AK=5;E13;97*4:=+-331*8**+*,))(/*&)%3;,$2)2021%/2Qb02?f=NX>C,>LT_/Ji5OD;–Ž°¡¦«®š«¥¬°´µ¯«¦°ª©º¾»À°®¹®¡·¯ÉÇÈÐÁ¾½»¼Â½ºÃÀ¾¿®²²±µ¼ºÁ±±²«³¨¤´¨¥­³²¹°£­¶±°²»«º¯©­¶¬ªžª¬Ÿ£ ¶­¨¡Ÿ¯²¢´ªž¨§ª£ª¡¢¬­¨½¯¬®­¢¨¨ ¬™°¢˜¢ §§ž§›™ª±©£ ­¢¡”£££§˜š©¥˜˜˜žŽŠ‡”ˆ}†„ƒ£–„‹†ŽŒƒƒ“ –ˆœ“‘œ”—ŽŠ†…xt|uxy€ztsyh†¤ui^dktgˆŒ}SXp^KxsSeSQ^MMRYfNLVYdXFSiRQ?CNQaQ:IHLSIqQLS;<I?;<=;@@W<<?H73CB15:93-5::)-31.-5)(+-,42#2)',%.;.&1.0-14%,0Lg:48_=ad?F1CP[[+HM9UA4‘² ¤§¬¤§£¬§µ³±«¥±¨ª¸¾À¼¯§¹ª¦¯°ÉÇÈÑü¿¾¹¾¿¼É»Á¸°¯´±º»·À²³»¬¸¬¢´§§¬²¶¹³§¨¼µ®¶¾°½¦¬¬µ«­œ©¯¤ ¥­«§œžª²¤³¨›«§©£©¤©¨©½¬´¯®©¤ ®œ›³£•¤œ¥¥Ÿ¤››©«¦Ÿ›ª¢›“œ¡¥ž˜—©©’˜š”Š‚…~Ž‚‡…~}‹†„“š“…’¡Œ”‘‹‘š‘•†‰~r{z~|hx|zupp|g„x„ˆdagbr…zmgx]]VAWzmTaPRXKLNqu]HZ[gYEUfPD>JNDCA9HGKS?jaJQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11&/>KH0%90%,,09/,,+6'17#-0GjI14X=fcAJ7GS`U*=9DW>*”±™Ÿ ©¦¥ ª¥¸³³¦©±§­¸Á½µ¯¢¸­¨¨°ÂÉÉÌÁ¶½Àµ·¿¹ÈµÃµ³±µ±½·¹½µ­¹¶¿­¡³§««°µ¸µ«Ÿ½¼©³Á´¼ ¯³µª«Ÿ­°£œ¥¨ª£ž›¤°¦° Ÿ«©¨¡©œ¤¨¡­»¨®°® «£¤®žŸ­¦—Ÿ›¡£œ œš¤ª£››¥¥–—•Ÿ¢–›—¦¬Œž‘‘‘‹‚Š€€Ž€{™”Œˆ{~‹…Ž‹Šƒ’˜‘†“¢‰’’‡™“€ˆ|yl~vyxc{{qpprwh€sjƒgeg`mslaio`o@[xkU^OQQJJMTYWM]^lWDX`O^PHMDF;7HEKO<rhKK9AE;;==;;=J49B<3;G<4?18-78;2(09/,4/.=-*K>*49&'.34.0+/4&,:$41BhY13S=e_DL6KVdO*;2NX=#“™¬™ ˜§¤£Ÿ§¤¸°¯¤¯°ª«¸Âº³­Ÿ¸¯«¨´ºÈËÈ¿·Â¾°´½·Ä¶Ã±®¹±³À´º½·©¹¸½«¤´¨©ª°®¹±ª›»½¤°Áµ¶¡®¶µ¦§§±³ ž¤¦§¡¥™Ÿ¬¨©ž ª¯§ ¦˜£© ±¹Ÿ£±® «¡¬¤œ¦§©šš›Ÿ£•›ž©¦—œ ¨’™”˜ž“™–¡ª‘šˆŽ†}‡‚Ž}| ŒŒˆx‚‹„‰‹‹…‡’šˆ•žˆ‘•‚Œ—Œ‘|…{sp}qtt`yxinppnh}qc{miec_e…~_ZskrLL~hXZNPLJHPRPIN\_nSDWZRhOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23/:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%53=fd24M?e]FO=RZgH*>0XV5(—¦™–¬  ¡¤¢¸«²¥´´ª©¹Äµ³­Ÿ·­®­°µÆÈÁ·¿Â¹±´¼¶¿»¾¯«½¯´¿°¼Â¸©»º·§¨µ©¨«°­³°§š¾·¥­¼·²Ÿ°·°¨¥§¯±›¡¤ ¤¤¡—›¯¦¡ž£¨¯¡ ¡“¤¤¢·°¡¦±ªž¬£¯˜œª¥©ž˜šž¥“››ž§«š¥––˜”Ž“—¢¨¢ˆ‹…z„~„‹zŽ—Š†x‡ƒˆ‹…“˜Ž–˜Š—~†—‹yzprwoot_ywdllkih‚merkkehZbs^ZlviZH}][XOOJHHRUF2:_^lPCWVYeLHJEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<#8R=*113>D5,-'42+;+139cl84GBg[HTCT]hE.;1_T,2–£¡—•©ž¦¡£¡¸ª¯¡»¹¦¬½Ä³¯®¢µ¯­­¯´ÄĽ³¿º·±³¹¸º¸º®­¿³´¸¯¿Á¸¬½º´¦¢³«¨ª³«®²£œÁ¶¥©··«ž²»©¦¥¨¯«™¢§œ¥¦”˜¡²¥™ž¤ª©œ¡ ”¥Ÿ¤¹¨¤§­¦ž¥¡¨“Ÿ©¢¡¡™› ’›— ¢«œ›™¡•“•–›Ž““£§¤ˆŠŽ†y„|……|œ‰Š†x€ƒ‡‡‡‘…•“’Œ•“Ž”{‚—ŽŠw~{lurmlsbyuhgigen„gghdfhj_fbifZezc`RsT[[SLIGIOS@!+j^jLCVU^`KHGEC.:B<F<6KPD8:D357==895?:;4>8@L=>93)8><:9*6@3.E4(+,>0-N?.+-7-1195,&.5-80576`tB3CDh[KWGU`hB378bM'2ž¤£’Ž¥¦œžžž¤µ­¨ªº·¨¬ÃÀ·¯¬¡µ®§¯¯·ÁÀ½²Á·±®²¶µ¸·µ¬ª¼³¯²±½À·®¼¼±¥Ÿ¶¬¦¦´©«®¡ Ã¬©§±´¬¬´º¨ª«±¥˜žªž¨¥‘™¦­¢™¤ª¡›¢— §¶¦°ª® ¡¡• ¦Ÿ¢ ™›šœ’šž•¦ž­¢˜—ž•”Ž•˜Œ˜š§ ‡ŠŠˆx…w‚‚‚œ‡‹‚‰{~„ˆ†„„–•‘‘“{ƒ•†r~}gypkjlguskbgdctadefeijchoY^X]ldaMhW[`VIGHKLRX>9`liGBUS][IHFEA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A<-5B37=++,0A*JK./*+3722(57$+7.72785\yN2>HiZLZJVbfA:3@eG%5›¤ ‘Œ® š˜ —¥´²£²¾·¡±Å»¹°±¢¶««¯©¹¾½¼­À²¯®®¶¯³¸²§«¹±®®´¶»¶°¸½­¦žµ« ¡±¥«¯Ÿ¥Ä¡³¥¯²¯·­µ­¯¬®¢™§ª¥Ÿ•›¨¦ ™¤£©œšŸœ•œ­°¦º¨­¢¡ššž™Ÿ¤š¥–ž˜›”š¡’¨–­©›”œ“Œ•™Ž””˜§§Š‰Ž{‚t‚Š˜…‡|‰ˆ„„ŠŒˆ’…“œ“’‘–Ž€ƒofynhkjgqrk\hcbr`dgjmlgjgdl\lmvqaTbhceZIFLMOXQPUaeT@VSYUFGFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24;6#3*)6.55465Z|]1:Kj[M[KXdd@A1IdC'4“¢›±›”¡š©²°Ÿ¹À¶ ´Á»½¹±¥¶¯©®¥·¹¸¹­»¯­ª«·ª´¹­¥²µ±®©±·¶±³µº¨©Ÿ¶©žŸª¢ª­œªÂ™¯¥¯±¶µ¬¬ž±­¯ª¢›¤¬¨œ•œ§¤™©£¥•š ‘œ£«ª©»Ÿ¦¤ ˜ššž¢k¢•˜œqƒ–œ¤€v‘«¨ž––¡‘‰—™€—ŠŸx…“ƒmi~wƒpl†Š†}„Š†o]d`g„—†k‹”’uw‹„ƒfˆ€hvifX]itnNPjdfq‚f^dfnli^]^‰…ˆhOKD8ETg^JHPPUUKHS`oteE[QUPFGFC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,,08>G701.*.*/668,#1'214:276Xl15Ok[N\K[fb>G1Ob<+/¤™‡•±›“ œª­«£½Å¯©·Â¸½½­§¶°¦«¤¸´³´±¹­ª§¬´¦°µ¢§¸¶µ¨§¬¶³®´­³¢©Ÿ´«ž¢¤œ§¨š®½•¨§°´¸­­¤¨®ª«¦¢Ÿœ¡¨§œ—¡¦¦œ›§§’ž ™ž¨ª£µ°£¢£œ–˜˜˜¤‰¡’š‡¡ˆ”ž¡¥§¬ž”““ˆƒrxŽƒ‡ uˆi—ˆf}sx oˆ‡ƒ~Œ|¡ Ÿ™{‡žtˆŽv›Šlˆ‚ƒmied{mrbT†mcmi˜qXjpn†W^i[kj[ˆpmyr‡i‡„Z^FN>F^MERVVQPRWTg^LYKRRPEGG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82*/1<I9/01.*/(-4583%&2115>1<8Xƒt15Rk[N\L\g_=K1U`7/(Œ¦—„¬™™Ÿ«ª¨ª¿Ã¯²¹¼·À¿ª¤·±ª¬¦³µ®¯³¶«©¥±­¥µ³›¬µ¶´¥§¨³±­²¨¯Ÿª¡³© ¤¤š¢¤°·•¥¦§¶½¦¬§©ª¬§¦¢ ™ ¨¤™™¦£¥™œ¥©–“¢œ”“£¦¦ ¶¤£ £˜•“˜“œˆ®˜”‰©‹˜¤œ†±€¤­ž”šŸ•y‚Ô¨‡”À›Æxw±¥·—d€Àœ¿y„„yƒ|‘Êq–¼œÅ{r¶§º{l–±«°yhlX±®oei¼’¼nhzmqØ~Sjc¶²~€q”uš¡ªWOXaOVNFT[XQPS‹\W[P@\EQNDFI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22BE/.32.+/)-/186- /416A1=:Wƒw11Tk\O[M^g\>L1Z\41!Ž¦“§ªŸ—¥­²©±Â½²µ¿µ¸¿Â«¦´­­©¨¯´ª¯¶³¨§¦¶¥§¸¯œ²²µª¥¤§²¯®±¦ªž§¤²¤¢¢Ÿ—œ Ÿ±®•Ÿ£ ´º¢©¨¡­®¥¢›š¢ª ˜›¨¡Ÿ˜¨¨‘œ§š”ž¢§£ °£žŸ£––’˜’™…°kjŠª~g…–‡­eqž•š§–q®¡¤~wº|k¡v±_j´[¥€eœ‘`fzfixj©e¾rg¦Œv±j|±xu’”cmm§n\„ Eig‡–Euœ`}f{£§‚Y_‹«i€’xzj¨8J¯[WTmc[LOX_\WV;NˆOWV/ITSJCEF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3..53/+/(.0.:6/'$203B/=;U‚v2-Vj\OYL_gY:M5^Y31’¢•‚¬§¥Ÿ£¤ª±·­´½¾°·Å²¸ºÂ§¨°¬¯©©±¯¤±º°¤¤¯³£©¹©ž³²°£¥ ª­°¬¯¦¨Ÿ£¢±¤˜•˜›¯¨—œ¢Ÿ´³¡«›¡­­ žš— £ª™ž¤¡œ™¡§¤£›˜¡Ÿ¬Ÿ¥¦ šŸ¡••‘–‘š†µ›µx…©™µ™w‡³›·“–—«•~k¦z…†‘”’w«gj±[¬{Ž‡”tˆpŽ†ˆ—xƒ‚‹—Œƒ …°vwŸqkjl|‹O¥XHcc™~ch¦`yquR“†^P©mcq}†€a/R¢n[Tkg`LK\cX\ZB>°xWXA#MhFCDA@A19>89:84;:9<9:A:E::;6:CB8=?KNH:5:AFBAAD<FD;0202;F,0.840,.(/2,>831/2-D1<<S}n3+Xj\OXM_fW7J8aU50— ”ˆ³¦¦¢®©¨³¬ª»¶Â°¼Â­¸·Áª¬­¯®§®³ª¢¯¼ª¡§µ­£«µ¤¥²³¨£¡§ª²¨°¨¦ž  °– š––—š ¯£›š¤¨µ®¡©©§©š–˜ ¥©›Ÿ£Ÿœ ¢¥£•›ž˜™¢ª›¥šœš¢ –“‘““„Õ“™¹q°ÂƆ|֔œ»|›–¦œŒ¤z†¢¥‚z¬yV¯{‰~Ÿj¹Z¹w†ƒ}¦‚“|˜zªyŽ{±nŽ„t»…n•P¯§ÅŠQ zc`ªbsr†l—‡_Sµ´È…€‰|c¤3Bu]PjhdP@XfZdaJHMkJZSOYfZCC?E?0<<59;74<;8=:<C:F:;>6:@C;6@OLH<:<DHCBCD<EF81211DB./0483+-).323971#%5*>3==Qwj6*Yi[K\P_fT7G:aP72%œ¢“™±¨¨¥³ª¥´§¤¼·Á±ºÀ²¶´¼³¶§²±£±³¦ ¯µ¨›¨º®¢¯± ²´±¡¤žž¨©°©´©¥œžž¬—™™——–˜¢¬ž›—©­°¨£ŸŽ¬¢§–˜œ¡¦¢˜¢¡£¡š¢¢§›ž ž•™š¥ œ§•››Ÿ ˜’•ˆ²nhµq«ˆpŽ¦r´ts¶{›˜¤œ¢~Ÿ¤~°uƒ‘ÒÑu[®|…¤o›ª¦k†…}­}—™{±s“x³e–t…žnžf”RɋZÂ\Ÿyb_­_vs†b—ˆ^Yʝo¿€uMKµSUÆdTQjcfXAOj_liPUFI8=WR[VYIC?J<2?;5=<56>;7><=C;G9;@7;>D;.CRJG>?<IJFCEE>II:1746@>/.24252-).26,742&60;5:=Prh9'Wi\BNT_eP5G=aM62.¢‘¥¯¬¤ª»¬¦µ¥§¶»¼²»¿¸·µ»»´¦µ´¢²²£ ¬¯¤˜¦º®¤±°œ´¸ª ¥¡ª¥²¨¬ª¥š›©Ÿ–•˜™’“£ª¡—“§«°¥¢–’¬Ÿ¥’”¡œ¤§ •›§§¢š£Ÿ­š žž•›¡œ¥••™¢ž•™–’›…¬{w¨v£‹‡©o­Šƒ§„š™¢Š’™‹¢~’—‡®…‚³\r³R®}‚‚¤q×}w„~†™šw¯†Š‘œˆw´ašeš‚•l’[°WKšu˜yf`­^vw‡g˜ˆj]¯w•Ÿxl5yÈ®²_BTo]g`EPl`qmVUM.ebhSYP;BD@L:5?91><16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK97<46:>/04333.2..18*.32%!03767=Pke>&Vg\@=V_cN6GC`I:77 ” ¸°˜³Á¬¨²§ª²º¸´¹¾¹¸³¶½¶¦¸´ µ­  ©«Ÿ•§¶¬¨°±«­´¤›©Ÿ ¨¢µ§¦ª¤™ž•¥¢””œš’–£¦›”§­¯¥¡•˜©Ÿ¢‘¢š©¦¡•š¦©ž¤ž¬  ”ž›ž¡˜™œ–—¡ ”˜‘¦†©}}¥y¡ƒªp­Œ¦†– ¢Š——ˆ£‡”ª{‹yo±Z¨ƒ‚ˆ ytØv‡t§Ž›’¤|–Ÿ„{²^œd }‚”m“\«\[“‘hgªcr{€j˜†q]«Z‰ kneOJC¡\ZMt]bfMZa_rt_JU5Jš’XHE=HFAM35A8.;>05A78@<6=<F?:<6?=B7.HVJE@H6KIN@IK@EN::@4.;>002154+*05/7,&21($$6671<PeeA&Uf[?1U_bL7FI_C1=7¢œšš¿¬˜´Â®«­¨¦´°¸±¶¿¹º³±¸½ª»µ ±¥Ÿ¦§§ž“ª±©¯ªµ­ª¯¡˜¡ ¦¤¤º¢£¬¡—›‘£ ••Ÿ›•™  ŽŒ©°¯¦—š¨¦Ÿ’¤˜¨«¨•˜©¨ŸŸ £­£ ¡” ˜Ÿ ’œ—œ•¡•–«›®nr´t©ŒwŠ¦s´yt´“¥£’œŒ‰¤‡Žu¸oŒ{‹¢kk¶Z¡†e——i ¢§m”r´t“˜²j†’ˆ­ku³af¢n†’k—\­`N¡|‡‘Rs£ly~n˜†p\¯V<œwfTon.[§ObRkeblZb\`p|cSYQ>>mo2BB@?M:!7@6.;@37C58??3;<CDBJFMIF62JTKEBJ6IJP?HOCFP=<E50;;010/75,+,326/#00,,289/9N`eD'UdY>/U_aL5FM^91A8¥š›»¢œ²À®­««§·©¸¯µÁµ½±¯º¹¬Á¶ª«¡§¤¢’«ª§µ£²¨®ª¡—œ¨ ¥«¹£­œ–™¥£–Žž¡œ™žŸ‘“•«¶¯§™”›¬©—Œ”¦š¥­£’—«²¤ ž¨«°™¡¢˜¡— ›–›—¡“œ©”ª™‡Ó“š»t±Ä€Ã†}Ֆ›¸y‰’™Œ—‰Œ§‡y¢¶u}wv‚š²`ƒºyÀ|u¸bµŒ‡©}–¬©q{u¼ˆ§ ia¦Ž¯¢~Œt‡«}¾ns¼t²ƒux€Šmšˆqm¤t½]w}[ay¼jZV[iy^iadfbmyoY[YCA@r?CF+5H"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-6@9¦™ž¢¼¢—±Â°­©ª¬±§¸¯·Å±»²®¼°®Á²¬¥£Ÿ¤¡œ›ª¤ª²¤µ§­¤Ÿ–šª™¦¬¹£®™•¡¦ “œ£ž˜žš–“¯¹°«•—£§§”–¥¤­ž‘ ¨« ›Ÿ©¤²ž¢¤¦¡”¡š›—–¤˜° ’•©Ÿ…™µ€‘‘¸•x‚“›µwnlosny„Ž‰sžÁ»¼™z²¨p€t‘¹ƒ|††‹‡{Š†—|¤»¹½œuy³£tv—ut°u˜žf†i¶trqw¶Œ^y}ˆgƒymyb‹¬pt…X[§jDdYTf_c]cQggqmuBMPMD;ZL?J3<0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITBKNGEOF?G<7>7070/9:.,/-*8/%&2(4$(>7/7KT_G'SaW8*O]]=+;VV'=:<¦ ¡¿¦–³Â´«ª¨¬«©»®±Æ¯µ´®¸§µ¹­©££§Ÿ ˜“¬¤­ª¦µ¨¨Ÿ›– £ž¬¥¾§¡ª˜•œ‘¢›’¡¨¡“ž—’˜”²µ¶¬˜¤¤¢‹’’¦œ¥«œ–©¥¦œ™ ¨§¦£¨ ‘¬ž—£ž—–˜ž°©“œ§¢Žj~iœ§x‰s~›Žuze‡{¾¿Àºn’‚q•…_rjZ]š‰ad‡Ž•k`•cmœvb”k€š•”e^_cq›‰hrŒ|†”fj~qty~}b[xthP\nƒ|{ŠjXlyrIJo…pNsMEW\faL[Wfc^OZmvjrRODEM<HI<M?2,2A?8/5?C<9;@;=C>RVVWYZ[[\]`aaa`\UG5DFUEJOHFPIIH;8=51:.1;:./-76=5&"/*2,%;8-7IR_I'S_V4)P^L(3>[O'?2>¨Ÿ¨¡Á¤š´º¶£¬¦®§¨µ²¬È¬°³¬¶¤¾²³¦ ¤ª£›™™¬§®¤¥µª¤›˜•¢›¦­©¿¨©¦–”›– š“˜¥©§‘ž˜œ°²¾¬›§§¢‰“‘ª›¨¤››¬ ¤šš¢§¬¢Ÿ©¡™¯š•¦Ÿ–”Ÿ—±¥™¢¨™œ‘žœ£¤™§£šššš–‚hn}qv‘—”‘ƒ‰´©…˜•ŽŠŒ˜–‡“•Šƒ““ˆ‘”™“™—š ¡š›”Ÿ›‚z¤…li{}€u‰‹‚r‚xyvvŠ€{‰jstƒudw}vkpzm`c[ogLXYej_WYpzonfSOFR9OZNRO(+;JB635=@A9:C><ENSSTVWXZZ\]`bba_^^[TKCSGKNDGPLOI<:;489,2;820)6IRO8")+/2#4;*7FO[J'R^T10T^:+=8]K,<-@² ³¡¿¢¤±±· ©¦³§¥°µªÉ«­²¦µ¦À¨´¡ž¥¦œ¥•• «§¬££·¬ ™–– —­ª¦ÁŸ¬¤–’œ—ž˜””¢žž£¨’™¨§²Ã¯š«ªž—–©ž«œ ­˜¡›œ¢¥¯¦¡¤§ž¬˜—¦™š¡žžœ°¡¢§•˜“™” ¢–£Ÿ˜¡Ž–”‹Š—­{•›‚‘€‰©¨…€˜–Š„ŽŸˆ{ƒ†…š‘‡†‰•Ž›—Ž˜ž£–™’œ~e¡³®„‰„w{Š}wyzogy€‰kuyˆrisyuƒ‡‚ktcxf_hdcdfjXk{pjk\SLPD_UF@?>,4@F;45;>A;<?>>HNNOPSTVVXZ\_aca_]]]^]XVJKLBIOMRJ;<:786/3964.(&$-1..)+*7%+<(6CMLD/T\Q05M[17E4\G5<,@´ ¹¯¾¬«­±² ª¦²­¢¬³°Æ°«­¤³¯¼¤´œ §¢¡™—¨¦©¦¤¥³µž•”ž™™¯¦®¾ ¬£‘‘žš™”’–¡œ—©…©¬¢´Ç³Ÿ©¤ª––˜š§ž©œ ¤«”žŸž ª®¨¦£«¡¬›Ÿ  ˜¤žœŸœ°¤™Ÿ¨“˜—’¥š˜©Ÿ›—fƒ’|e~šcxŒlhjz£«kd™—~g…Šeeihz¡ŽkhŒ—‘¢wkj‹˜¢Ÿ˜slnz„Œ†yXe]…‚^l‹Š‚v[hsww‘€‡‚nx‚xsmy„swˆˆŽƒ{i…X]jsd]sˆik|qmc]QNWIdX@J3=F7?FD71<=?AC;;DGHHILNORRTW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%.++'6*$;'/AI[I.6ZO6)EY/DO1YB;?.=¥Ÿº¼¹¯«³°«¥¨­®°§®­°½±ª¨¥­°°Ÿ­˜ ¤ž¢šš§¬œ¬£¦¨©³®ž•£¢¯¦¶¹¥®£Žš¡™“’› ˜™¦–{¥¬¢¨³Ã·¥¢§¯Ÿž•ž£Ÿ¤œ¤ª¨’ž¡ž ª¯ªª£ªŸ§›¦Ÿ§ ¬–¡œ¥±¤—œ«–¡ž›“¥—ž«™ž~¾ƒˆr´r…ž…­hw¹Ä¸q’¡£{¦˜˜sª‚|ËÀÀ»qŠ£‡‚ž|–˜ˆžÀ½‚–œÁÀ{z‘ŒšÂ¿}k¥²oŒoÊz›w‘ƒŽ€vyyq{€†px…Œ“ylv‘be^xd_eb^thmdbXLVIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^__a_^^^^___]\SMPGUNA@?=6468266*&%#)*&.+*)109*#>H[L*#CP/#F[3PY/UAB;/8–£¸Ã´°¯¿©©”£¯©°¯­¦²µ¯ª¦§¥±«Ÿ«˜›¢ œ›ª§¢«¢¥©¥¤´¤£“¦®¬¸´§¯¢’‘™¥’‘ ¡—› ‡¦ª¤«­¿¿±¡©®©—’Ÿž¢™¢¤ª£“ ¡ž¬®¨¬¦£¢¥ ¤¥œ­¨‘¤›©­ªœžª­¢–—¥–¡£˜Δyz¥z––›_­]Ž¨€ ¡|§•št«ƒ€¯^dŒ©z¨‡…Ÿt—’ˆ³c‚«† ³j„®t|–‡¸a‚­Y£Ínu{Û{™q~ˆ’ue{ˆvvl}‡n}…‘~l_pjof`_xd\qhjcf`RTSW^JOC5AHED8>6;@?A;=8@>??BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5578164('$!',&&/(&+360$7;SL+,-J0';\:L-!P@F4.1­ÂÀÀµ´°·˜ž‘£ª©­´«¦²­­¬¤¬¦°ª §›š¦˜œ¢¯Ÿ¡Ÿ¨§£¦¡Ÿ°¬›ž–¦®­°«¨¬ ”’›Ÿ¥“ž¥—¨£ž®¤«°¨¿Æ³¨©±®–’žœ¢—¡ªªŸ•¡žœ­®§ª¨›¦¥£¡ª’¬³–¥¢ªªž¤¨¦¡±¢“š§š š””‘— p…Œ˜u„¨‡q°|r¬} Ÿ¥žw«‚}­œr­~«‡†Ÿv˜’{|—~ªˆ¡Œ‘‹œ~«{ˆ’Ž €z­VœÄzo’Á}•mupŒmfwe†oawnrnˆŠ‘ƒmŽdnsuo`fmd_ohjnfcWS\`ZRRC9II@C<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;92478452&# 1' 1''45-&7=WJ-<(=1)3V@F!G;C1-+¯ÔÆDz´Ÿ£Ž£¢¢­®¶¯©±§©«¨®««¦¢£š£–Ÿ¦«Ÿ¢¦ ¨¨¢Ÿž°¬˜›—¨¨¯¬¨§©ž—•š¤¢’”¡­›§£®¬£¬µ©¹Í²­¦®¬–•œ¢™Ÿ®¬–¡™žž©°¨©¨šª¨£¢«›¯±¢¨¬¯¦š§¬ªª²£“—£¥š”‘„¤j¤u‰z©uz²q‚¥‰˜Œp‡Ÿš‡¤_`R«„®‚›u®‚§††Ÿz™—…{f€£‰¤™†£}©”†®^|¨U¢’z£Ÿ€{ïŌs¯´³¹qb©¯ÂuhŒŒ—Žl™‘nmxwwnkfddqpf{ic]V_iXXTLLQLCCAB;CA@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799664,&$" ('"+-"$.!3-&@DWH,G+56*1PKL# A9D4,'ÂÉÕÖÀ¡™«¨¡¯¢Ÿ°µ°¯ª­£¨§ª««©¤¦ ›¥Ÿ¦§¦¤¬š¢«¡¤Ÿ¯¢ž›“ª¤¶°® ©›—•§¤‘›¡¨Ÿ ¦œ°¦£¨±¬¶È²µ©¬ª•‘œ¢™ ¥´š¡”œŸ¦ª«¢­™«§¡¡ª¢³­¢ª³²¢œ«©¯¯·¤”–£§˜›’|ªlž„‡u«y|°n‚¤‹ˆŸ–•ž•Ò·´¸É€²^_”©ƒ¤‡‡ z˜•™xªÉs™£”¨©“šŒ~š‰šÆÆwe¡‚¥sŸŽ‚}¯^oµc±uK£†m§G‚“dŽœ’{p–‘}ozt|zm[ejrqfi^aXcm\^YILLKEDBB=A<B?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75785/)(%&%$&),5FNPPMFLJVF*L0/>-4NTQ;<F2,$¨¤Áƹ­©³®¬¥¢²¹¬ª¡¦›¨¦«¬©¦ ¦¥˜ª£Ÿ®¬¦¡¬šŸ©¥§µ £˜“¨«¶²¬›¦œ –‘¦­‘™œ§£ ª¦®¡£§©°´Â±²ª­¨”‰˜¥›¢¤®¥—¡•™œ¥¥ªš®œ¬¦¥ž¬£·¬ ²¹°žœ¯§³´´¦•˜¨¤› Ž‚NxšŸz„£|‚¤„†¦žœž”„¸{|y¹‚ÌÆöw›¡‹Ÿ~š–—‰vŸ—Š¤˜¤¨~°…œ„ž„¬}™”a¥l£p…}—„r¬`¤rq€š`¼}RUuŽ‘£–{|’ˆszr„}p\lnwrjnZc_hnbd]LLQSAHGFI99K>B108856877-*5==?BDGILNPTWYYZ[\__^]__\ZZZYUSOH@772.,*.+*'&?QTVWWWYXXWUOTF<E2:P[T6?G,- Œ‡™©¬¤«¹«¯ ›¡¬³´¦Ÿ¡•¦¯®®©¦¦¦š£§¡²®¢©§² ™¨¤”¢µ£¤–—¢ªµ¹¤œ££“¢±™žœ¦¥¡¢¯­¤¨¢µ±Ã±­ª­ª‘‡‘œ§£¤œ¥—ž˜™™¥£¨™­¡¬¤¥˜¯¥»¬¡··®žžµ²¹²´¨™ž°¢¤ž†ÑµÃ·y‡Ž…‘“€¦x”¢w‹ ’…¥‚‹q«†…´nri™£œ•‰Ÿ|—™†‡s®‚¥›¢¦‹“œˆ”šmp²\¥s“zœl™{™~n©a¢qqŸbs²¸hw“¤˜}Š‹‘Šw|xlhwixsnt\ddmmeh`JZWX<HF?T3@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^``]ZZZXURRQF:2230/++(@QRTUTSTVWWXXWUUVTQOQ[U%!2AH#)%’rŠ®¿¿¼»µž—¨¤­¶¡¢™•£©§®©«™¥¡Ÿ¥¡ µ§¢©§°£”«£Ž¤­¤Ÿššª´´¤¦œ©’”—®  ž¦¤œ§œµš ª£µ«Â¯©«©¢Œ„œ¢ ¦£•™šœ˜›˜¦£¦˜ª¦¬¡¤›­¦½¬•¾°­Ÿ£°³º¬µ¨œ©²¥©˜z§‘}|°wŠ€¤¥ˆœm²o ‡­{¡ƒ¨•š€¬‰…®… ”¨¡¢—…Ÿ€™•€{’~«€š–‹«x ˆ“’y¯]£|¦§dž€|—tk®]¥kq…™]`[Œ m”¥˜“Œ•Šyy–~jl}b}tmy_fepngghBY_[=JS2T8BBC7$$3+''3, /667436:@CFIKMNQSSSVZ]_a`aaa^][ZWSPONI7052.*,ATVVVTTUUUUTTUTSSVWWXVVUQHFIJ#((¼’š„©ÆöÁ´Ÿš­ ®¸¥£Ž›¤£ ¯®©Ÿ£ž­˜ž¹ ¢« ¯ªš­ ª©¥–‰š®°¬¦ ¨›­˜™­¢¡¥¡™¤œ­˜Ÿ¨¥¶¨¿®¤©£ŸŒ€Ž››Ÿ¦ž’”™š”™™¤££™§ª«¢£ž©¨¾¤—ì«£¢¬³º¬¯¨¢´°ª«™v¯~Šœ…‡|º­‰˜d°Œe•­}¡ƒ§–›­Š„°…¦™¤¡¢„ [lj³`­{{‚€²lgn™—‹ˆ±[}´[¤ƒkÈ¢eŸ{¼YvµZ²}R¯€z¬X€¡m—Ž§š‰–”•zx›|cs|aƒxs|`ifpmfeeOUc\AT^=H(>9=4!!-$2. *1/04579:<ACFHJLNPPRTWZ^```ab^_\[XUPNJGC553./@UYXWXWXXWWXWVWWWWXWWXYZZ[\XWWGB;ҟ³±·½»´Á³£œ­¦¥¶© ‹™ Ÿ³±¨ž¢Ÿ´˜ ³¨ª«ž°­ž«š”®¨¢Žˆ›Ž¯¬©§£¨™¯“š©š¡ž¥ž™£¢¥™Ÿ£©²¨¼¯¥¨žŽ|‹š–¡ ™‘š›‘˜–¨ž ˜§¬¦¤¤¢¤©»ž Æ§¥©¢«´¶­¯¨ ½¯®®—©’£®Ž›€†¤—˜€¸ÃºƒŽ“„§˜‚¬Š‚¯‰¦›š¥ª‘~սªb£¿½|~£‚ƒ×º·µ…“’‚ž½¾„j£o«„nz²±Çƒk«°½¬xw¢¾»t€•¥›Ž™•›x€™yb|zcŒgx{`kekjbPb[Si\@T`BL)<:5/$%2 $(0496678;>ADFGJKMNNQTW]a\__a^`[\YTQMHC><A?5=SYYXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ»•´´±¿º²½³¢®¦¥³¦Œ˜¥¿©¶°§¡¿¦¦±›ž±œ¹¨Ÿ­®¥§”“¯¬—Œƒš‘®¦£¬¢¥œª ˜‹£“¦ž§›š ¨¢™ž ¬¬©¸­§£š—“{‡™’¦›“‘˜˜—“¨™Ÿ—¨¨Ÿ©¦¡¢«»ž©Å£ ¯£«³µ«±«¢½©°°›tvª¤¶…e‰Ÿog¬Šmow¤š u°š–pr–§£›˜®¤rmmleŠxnm‚™q€zipif‰–•˜qhi…†gp†d]ŠcioY]g~x¦`br’ofd€“Ž¡—–—”œ|†Ž”te†wgŒjx~xdlcflbKdXJkY:PdDP'J:+# ",)-2.5:457:<?ABDEHKLMOQSV\WZ\`_a]][TPLHD=:AB7MXYZYYZYXXYXWWVWY]^^]\\\]^]^][[UW^¨•­´ª»º²³ª©¢®ž¤³ª˜’½±ÃȾ´©ž¿«¬£ ¦«Ÿº£¤­¬­¥–­ªŒ…•—­Ÿ¥ª¢Ÿ¤¤ ‘‹¥’§™©™–£ª –œ¥¦§¯¹ª«š›“’{„—Ž¦—Ž‘˜”—”¦“ž—§¢š°¦¢¬¹ °Â¨¤³¦¬±²«¯­©º¥°¹—‹¡©¥¶œ‰–¡—†©š”“ª³™›£¬¡³—£¡ž¡¢œ ¤¡•«¦Œ’“Œ‡’œœ”™“˜Ž•„¤š—•Ž‹“’Š†„~g‹€tƒvt‡Œq§m|•’”“Žœ“ ”–”Ÿ†“‹pgŽvn‰wu|yikddocU`Y@iZGb`NX+E=+&!640/!%2(*799469;>?ABDFJKKMPPQWUVY^_ac]^TQJEC>9=@ASX[\YWXXXXXYXXZZ[\^__`^^^__```_YY`¥–©©¥¶¸®®¢°¥­Ÿ ¶±ŽªÄ»Åº·©¡¥›¥°¨£¶§©µ¦§‘˜¬£‹ˆ‰œ§–¬¤¢š¨žŸ“•£—¨š©™”¦¡¤š§™¡´¹§ª˜šŒ{”Œ¡”Š”‘•’—¤Žž™¨ž›µ£¦¬·¨¯Â®£·¦¯¯°­ª«µ»¢±¾š’¦¤¦µ¢‘¦ž©Ÿ’Ÿ£¬°›¡¤²©°™¥¡¤«žžœ—«œ’™¢›”–ª™˜˜––ž‘‡ •”…’Œ•‹~f‡u‡vyˆ„tœj‡‘••’Š}Œ–’’—’ ‘š”žƒ†–…xq”rx‰~q{~ind_pi`[_YmbP`dOY9GFE=2<=8/*&+)&&406658:==?AACHJGJKLMSSSUZ``i`eVPJACB;9EMV[^^[Z\[[[\]]_^]^_`aabaaa`bbbdb\[c˜•¤§£±´¬®£©§­ ¨µªœ£²»®ª«¡¢™zœ¢°¤¥±©–›¸¦£”˜©œŽ†Š‰›¢®Ÿ¤—¨ ¡’—™›®‹ª–¨™¨Œ˜¨Žž¸¶£¥˜›ˆy“Œ›“Š•‘”‘–¡‹§ž¸£ƒ¯µ¢°¯t¤¾£² xz¡¬³½–w®¥ Š€ª~d[avŸŽ¤ƒ—~n“³œ£¨¯«£eŸ ”tzš–p€˜¨—l~¢¨Še¥›—˜–‹’›„š”ƒ’‡ŽŽ’‰…wkˆv‡q|†€ai‰‹•“Œ[v•‘ghry¢–—ew—†€v—h‚‰‚ny~jpe_vokkh[ecaaoRZ=MMNRF=@TB91/&4:306678<;>@ABFHBGFIKLTUUY]`hggXQI<DG<9VR[`ab`^`_`aa_\]___aabcdabaaedchd^]fœ–¦£¡°±¬«©¥©­£§­¥’–ª´®±¥™©¦ª—s‹œ¯Ÿ¨«§“–¸Ÿ œ¤ž~ˆˆ›ž¬š¤•¨¢žŽ—‘ž…t®ˆ¥š¨‘–£ˆ›¹³§ ™™‹‰uv“–“Š“‘”Œ“Ÿšž¥˜›²–€Œ›µ´Œ’½§¡~§¢z¤°¹ŽŽ§Ÿ„‹…°©¯Œ‰–¢™y‹¬†œ¢¨ª¨ˆ•‡™w¥›z‡›—¦‚{œ²zŠ†Ÿ—™”˜–––„™šcy‡„’‹ƒnqˆzq€††t‡…–’x–h“t št|™‚š…˜}‘‰‚˜iŒŒ„jxzppgdxnilj[diier[]HTLQ@E5-YTT6)!09=>643568;:=>>?DI@IEJKGRXZX[aahfYQH9DK<>bV^bded`aa`bb_]`aabbbcfgcba`edcgcaah˜£Ÿ¦®®«¨¬ ¨°§§ª¥™”­Æ¼¯ •¥¨´ƒœ«›§¢ ¾ž™Ÿš¡|…Ž™—ˆ¬£–¡¡’Ž”‰†€‘¨Ž‡¢œ£“–†ž¹±§š“…pu‰”Š”›‹Ž‘ž‘•ž£•¬ˆŸ´‰´š®‹Êˆ«¯‰·…°ƒ±¯„©§˜|¨r{w›Ž¦–h•¤y´‹Ÿž¦¨“™Â‚«ˆ˜¡qž€š¥}—…•±¡| “Ÿ˜—€Ž“›‰˜’‹|…“†”“‰ƒms’†€{r†„}…u†‚˜Åf€©‡¢jž—€™€Š‹ƒˆ˜o’„gwt{vghupghk^bnlfkXgG\QL2E46Mac7&4<DGD:63658;8>=<>BL?NIJKCPZ]\Wb^jl\QE=KM@JdX]cghgbbbbcc`_babcccdiicbbbecafcbbi•—¢Ÿ°¨©¨¥« ¤¹±ª«§š”Ÿ¢¤ª¢•¤©¶¢¯ ¦œ¥ž‰”¼™“ ‘yƒ––‘ˆ«™œ›š¢…Œw›œŽ ‘ˆž¤›•˜—†¢¸¬¥™›bm‹“ŒŒ—‹‘ŸŽ’ž ™¡¨~¡§‡­ –® ž‘†‚ ¬¯‡¤ªšŒš~¢u€˜“k«tM«x‡’›¨¨‚ª«~„¡{z§iž’lg—†—µˆž}m`cXƒ—Œ{dg‹s™}y–k]|—n_Sq…\`lyƒ`Ye‚~„˜q§ªkƒ£nr¥pŸ‚œgdžlZlˆzeY_‚~aWPovemtqjjn^jolkhWhN]XE9@4GD^k4+ICQMN=84859;6@;;>BO>QRLMBJ[]_W^_bv`ME:MOMTb\[fgiibbdaddbab`bdcabikdbddgdbgeach˜– ¹ ª£¦¬‘¡¶¼«¯¢™—Ÿ¡¥¬«Ÿœ­´¢§‘ ŸŸ¦›™˜´™‹žŒ•‹u”‘ŒŠ¦––˜Ÿž“…†¬£‡œ‘Š˜©˜™š‘‡¥°¦¢•™ˆ‰€inˆ‡‹ŽŽ‰‹Œ‘‹‘¡Œ“Ÿ›¢¥“£¡” wœ–§ƒ¢¨€†ª­…¥y‹}„š}¢pr’‡–{žŒym‡›‹™‘œ©›‡|‚¢sv¦fž~w¤^˜{}’s¢n˜·´ºs’‡€¶¨dÆ¸{p•¶Œq€›¤ct¬«`}j³~n}‡ƒ‚‹—q€£ls¤sž‚}£^œ™³–o{—ž³tr[ž²‚ibosuqhnXklrrd\h]aKD=D5QAZq2<RF_JS=<395::6D;;@IP?TMNQ@E_^[YX``|dIC8LWUVbaZffkkbbeadc`ab`dd_`cknccddhdbgfchh”–•£¹™«œ“ Ž¥¸¶­® š¢œ££¤«›š±¬«’— ˜ ¤™š”ž«›‹ˆ‘x‹…p€–‰¡“”—}‘ŠŽ¨ ‡˜Š’¢“›šŒŠ¨§¤ž–‡„~k{†~}ƒ‹‰Ž“Ÿ‚–œ  Ÿ‹‰wœ˜¢ r¢‹ˆ©ˆœ§‘˜©«®Œ}z ™y£“x€s—ˆŒœ}–Ÿ†›Ž™œ§‡£d¡}‰–›Œlžhšnš™zŠ§}rgsªƒ‚sªg”š]›…v„hªj¸f\©pœa•Œ^§vv‰Š€hšu‡“’˜Žžm™j¦™\¨~w»j}©ZŽ„]³g\nqxwki[pjyxa^dVaAPEO7VBRn4JZY^NZD@151;;7H?:CGU?XRX]>Db]V`Qac}jEB9N[^YdfXfgmmbbe_aa__``ec^bdoq_deekdcihgki•œ‰ª¶›¨‰c•œ¬º²°¬¦››§Ÿ¬™°§«—¢™¡Ÿ™–– £™†‰iˆ€q{—ˆ‹–—„’•˜zŠ„–£œ‰•†‹‘œ›ˆ¨¢ŸšŒ‘Š€€i†y–Œ{ˆŽ‡Ž•š“¡ž ¢“˜rhŸŠ Œp’Œ‚©ˆ™ ¤ª¡¨}°­¤¢¸—v£³¢£ˆ”xzªš~¢žœ˜‰˜r¡}…°µ}kš‘¡x~˜´££«¨„˜{š|œš~sªZ]o{—‹xžbL{{…dz˜BMŸY¢jr|ŽnŠ„™u›y‡‰±³~š’¦t~mq|”o™ri£]•vHec`sp}}nf_khv{bc_P]V\TV@YEQgERV\aX_ID=B8@A:IE8LEXAVQZVDFa\Z`K`m}rEC<U^bZejVhhmobff^a`\]^`hb_ecvl^egfldelhhki”±®™„S_¡§´º³³©š¢‹›©œœ§’ «£ §žœš™•˜¡–‡‡‰w…ny•…š‹}‘“–ˆr€‰’ ›r’ˆ™”Ÿš„Ž¨›™•‹ŠŠ|ƒl„…q¡Œx…ˆ‡‘—”|’£ ž£ˆ®†}µ„ž{¦–z©‚–ž‘‹¢}§hwm~™s sq|…˜o“‚®}£ƒ§Ÿ›¤p^©hu£co¥aœÓ|z™xrsc¢…~¢r¢Žuk³‹`‚˜Šsª²§¼wƒm¿¦ª´^œo~r—os¢r]£gt¦`h¦lšÓ˜z‚›nwy—k›yv—rl©¥g_dypƒkgfcnvwf_aQZePQaHWIT_WS[dj[eQFCKLJKBJD8P@PMXSXORQ`eeiRdxywJFEc]eZhjSihjocjf`c_\]]_hbahe{d^dgdkdjlfhlh˜›°¬T\K~©¯²µ°³£œ˜„—¦  £Œ¤§Ÿ—¨‰™—˜“™“‘ —ˆ…{p}„h}‚“šw‘ŽŽ‰p†“’l˜”|‰‘’£•ƒŽªš“’‹…‰yƒv‡€nž†w€’…‡˜¡–y“¢£š ‰³¡¢¶‹z¬§¤®¥p©€›‘†œ’|¤€¢™†˜qž„¢­®‰—‹€Œ¤–ƒ®¢”vµ¶µÉ¡t”‹‚ža—©my•‡Ÿšu¡‡w }–ŠoLf£’pšˆs¥{ytbƒ‚l~ lrd`œrt—j{i³µ´Æ¦s˜~zj›š«t‚šmsw—i™yt˜qPD}³^jujx‡fkgbttpmV]SXgORhIULXRV]gknVgWMJAJMJHJNAQJPdcimetrs~x{nu‰{{TQNl^h[kiRjhilgmfce_\\\_ibdhk{_]dgcjfnmeile¢œ‰¯§…f?”¡²¬¯¯µ¢¢–§¢¡£‹¤¦œ›¥š—–—›’ˆƒyjy†eƒŒ~–ŸyuˆŒi„…’ƒŒ…zŒŠ•¥’‚—©—Œ‘‹€‰y|‹yp †y”†ˆ–Ÿ””¥§œ––„gnxœl¢d|q¥xœ˜ph§‚˜Œ|¥z –ƒ–rŸv€‰”•¹nŠ¢b}™¢–‰nriªku mo¦`›i‹i–‡š•u¢€}š_‹…Œuoˆbh¡eži›updgˆ‚ns¢Z_[d¡n]‰Œo{srd¥nx¢df§h˜r‹˜n¡oRˆn ^d§T‹]T˜mmrjqmphkxskoQXVUeYSmIXO\HXihsjYkVQREV\LXRaUhj^wuz|p||r‚{sv€ƒv^QsagbpgPjhhklohdg_]]]`jbjivu]\chcjirlfkmc¥™¦zetm‹§®¥ª±±¦Ÿ‹–ªœ¤‹¡¡™¡¡€•˜“š‹—Š{†q€ˆh‹Š|—šst‰}{eƒ‡•Š‰–™‚|ˆ†–¦¢«…ŠŠ}Žsi¥„}…“Œ‡˜Ÿ‡’ª¦ž‰¦x–œ~¥‰–Œ²™ž‘ƒ¯—Ÿ¥y—ˆy©t¥„šn¥¢Œ’„Œƒ¼n}¥¯‚††‡”— }¦zq¨” –gž~o¬c–Š•’w¨l©¢‰v‡‚w«‘¦ˆk‘°kv³Œ©l‹†nnŸž‘•b«‹ªw€§ŸwŸ}…¤• iš‡u«fž­Œ¶sv¾Œ¤“Yƒ¦«auqso{tqbj~nhlSVZU``\jL\R]I^lmv`[qY[`Zgsenoqcqt`wz~yryƒrƒ~{{Œ‚€vbxdcnsdRlghomrifia_^\ajbllzo\\biamiwmglnb•¦ª€ž¤–ªªž¨§®£™ˆ–ª™£‰š¤œ¨„‹š…œ‘…’‹t…zˆƒo„}—“su†r‘ƒm‹’††”}{‚…—¥¥¥€‰„”u‚‡’ol‹¨€‚‹“ˆœž‰Œ“ª£ €t”—ˆ~y”¯¤‚œq†y’Œ„€{r§Œq}}z—–›„x{~~ˆ”•“Šw‘™ ¡„{}‰kŒ…[yysypin~’‰qt”“q…ƒ‚e_€Œxvt”uo{on‰n„†_wixŽf‚‚†Žªœ~t}—j‰ˆou|„umlfŒsw{—w„[jXyhnwqpowxo]l†migVZ_W\dkdUaU^Q_pwykjwejjju|pqtsaoubs{xuzu€y‹…‚}{mldyn^Wnghukxjiid\`ZcielpunZ[bkdkkymhloaŽ•º©§‹¡¢›¦¤™¤«¢ ƒƒ–ª‘ ˆ™¦š¨˜ƒ›‹~–”‡ŽŠˆr‚|}~„z—Žtr„p•…{}’‹††…x~€†˜£Œ{§¡‹…„•‚†Ž—wq„ª…‘œ‡žž‡‹š¨  «ƒ‰Ž•›~Š—­¨“§xqž“ƒ{“o~©…p}•qjo|Ÿ‹’ŽŒhm]ƒŒŒœœŸŽs•‹ˆqtk‚vt€Yrn†}~‹i]icz…ƒˆ€_ix{œ|ƒƒv‡ƒiyŒˆkbqsƒw_r‚‰§•†fƒnw‹ƒo„Œxndfcy‚z•Z\ifnv[zxwtmsr‚f\mŠkkbZY]YXkq[^`Y^]fs}{sotcjji{|rzwtdmthl{~uz|{yy€p†Š„{}s~yrhT\qilvpugkgd]aYjhkjqrmW[enlgryohjm`ŒŒ«±¡£¡šŸž˜ž™©£¡}‚–«Œž”‡š¡¤”{˜„|’™ˆˆ††Šr}€‹v…‹„–Šro€r˜†„~’ƒ„†Šz€„‹šŸ‚¦ ‡x—ˆ•‹‹œ—…ƒz¬—™“‰ž‡ˆ¡«Ÿ¢¢£‹ˆ“›£™–ª¢¨§¡“œ‰˜|yŽ„¨~’‘’“œ±¥š”Ž²“˜„¦ŒŒ–œ ‰‘›‚‰’Šk|Žvwe‚†Š|‰„‡‹‡ˆ€…„w|{u›£‰ˆ‹Ÿ‹†•~‚vqt†…x‰‡Š‘¦‘„†ŽˆƒŒ‹{†‰‡Ž€ukƒ{y™irh`tŠp}zvuowt]]o‡hn__Z[\RgqUc[[alht{|rnpdjih{mx~phoolf€{r€w}„{mƒŒ†|zx|~zƒxNdvjsnq{ekebb`[sfpfrqlU]ltmhxzpgikeˆžºŸ–¢¡˜•™˜”˜¤ {˜©žŒ…ŸœŠ–|x”‚{Ž™‰†ƒ„†mx€r€‡~ˆ“„mk~z—‡„ƒ~€†„†}‡ƒ›‘†©ž‚qŠ…’‘‹œ‘}z©ƒŒ‘—•Ž›–††›¦ ¢š†ƒ’š™˜š¦ ¦žž–’‹w}ˆŽ„¥{|…˜ª œ“œªŽ’€ž‰”šŸƒŽ—~†Ž‚ox†qua~„†t‹—€‚Ž‚†„~…„”nyvu”£ŒŽ†›……Žu€‹}}ss|‰„{yŒ„“§†„‚ƒŠ‰‰u…†‡‰{nj}{mhklg^y~g|{vtuuzw\`p}mt`cZ[^QfmSeZ]ajiuy~pllcjjg€krkjsnxn„yn†€v‚€}…vq‚ˆ~{z|€{‚‹`i{kuhiƒejc`i[cuhobumkTbqyeoyzrejmm‹ŠŸ¸š¡¤Ÿ“‘–—‹šŸž{wœ¥›‰†¤”Š˜™xy…|‰‘ƒŒ‚‚‚l{xr€…}Š|kh}‚—‰ˆŽ|~†„‡|€››‡¦œp‹Š‹’† ¡Š…Œ|§†Ž’—“–’w£ ¡–š™˜“Œš¢¡£š˜‘›~Ž…z„Ž‡ ~ŒŒŽ|—¤  ’™¦›‘‰“—œ~’‘}†€utpv`}€Ž†qŠ•|‡ŠqŒ~‚……Žhxry™’€—~ˆ‹s‚ˆ}}rz|Œ…{z‘ƒ–¥“‹…‘|…†‡…u‚…†ydqz~xyplif^}sh|uus|rj^`tvpwdcX]^RjhTdX^`gjvxqfkclge€jm}gmpj}w†zk‹r}tv‚†|z€}irƒntibˆilb_qUtomn`xhlWjtvbuz{qbkoy‰Ÿ³’¥¥Ž˜† šœ|u£Ÿ—Œ¡Šˆš–x{†‡~ƒ‰~ˆ‚p~ztu‚…~‰wgc}†—‹‚Šx}€ƒy–€•—••Ÿš}o‹“†¥›‡Œ‰ƒ¥“ƒ‘Š–—’‘v‘¡¡˜”˜zŽ—–Ž–šœ¤™“”›z†„y…–}Š‹r—¢ž ’˜Ž¢ŒŒƒ—˜ƒ“–š—Œ{ˆŒ€vq}mzc€|‹…p†“k‡‚‰„fvo}ˆ“™Ž~”xŒ‰}€ˆ}|r€yŠ†z„‘Š‹˜¢–ƒŒwˆ„‚v{€‡ƒt_ww|s}wfkc`~ijvstu}q|ccasnurmaY_]ZkdRbW_`hkuy†pbjclfh|ƒkhthloh|xm†q€‚‚t|ƒŒ€~z‚ƒ~|mu‰ttmeŠljbcuVƒipn`xglajvpfy{yq_ql……®˜§¨žŽ—‡…Ÿ“–˜}v¨›‰˜y–œ‹Œ˜x{€‹}|ƒ{€‚xsxys}€ƒˆŠ€d^}‹•ˆ~…ˆt}~Š~˜„–“–Œ£ —~q‡{“Š¦ŒŽŠ’Ÿ‚”—‘Š˜ š’’t€‘“‰œž¦˜˜Ž•–tŽ‹m†˜™z‡ˆ‰o—š¢“”ŠŒŸŒ†‚’œ“’–‡™ˆ{‰‰yqyjul{‹~m…‘‚“wo‚ƒ}~‹€esj}—˜…Žt‘‰„zˆ~vx~‡}ƒ…”¤y…‚t‰‡}rt…l`ztyp|oanbd{anovswwssav`okuno][^]]j]O]Wbahmsz‰k_iejchwˆmflhilg€|zwo‡s€ƒ„}t†‰zƒ}z„}}Žry‹yxnl‡kh_irc‡hqoevgmlazhk|{xpawm‹™šª¡¤©žŠŠ‘†ŠžŠ•—}v¬—Œ–|ž“‘–”ˆv}{Š|{€vw€otszo…}€‰~|a\~‘†€„„sz€†z‘‡‘‘›’¤š“}€|‰‘£ˆŠ—™Œ…‘˜“•Ž‰‰Œ““Œn„Ž‘ˆž™¡ —–‰—‘oŠš…g†™Ž”z‰…Šp–š“¡’’ˆ‹™Œ‚€‘ž}’“Œš{Š„†ssukqnu|‹tn†‘qt€|‚ˆ|eqmz~›”~…‰t‘‹t‰zo‚ˆ}…ŒŠ…–¨{ˆ}~‹…w~pn~ƒbgwstnzb]o`jt^pjzxxlrpey]mlsmsXZ]_ajZOWWdcfqqˆe]ihgbgqndigdih€zwuoŽ„sƒ{u‚ˆ…x…|wƒ…z€Šw‹{{ryƒjk_phskqnmqgoke{bnyvpkvw‰£˜¢¨¡§›ˆŒŠœ†“œt€©”‘† Œ•“s{v„wxrs{…kroym‰v€†nq[Y~’ˆ€vu€ †Š‘œ— “–w‰~€Œ‡œ‰†’—•ƒˆ”™–‹‹ŽŠŽ„n‰‹‘Šœ– ›˜•†˜ˆk…¤„g‡Š‘~‹„‹w“˜‘‘ˆ‰•Ž~˜|‘Žš’}‹€‚nvokmop{†isƒŽ—Šqw€t‚ˆ‚ygtov‚›}Š…z•’zwŠuqŠ|‡{‹†„‰œ£ˆ|„v‹€xxnj€~\qrqooxZ]o`oj^oi|zpmmjmw`pojqmYX`aamWQSYefbup„‚b]kmdcfk’m`ff_gkuqrp‹€t‚€xv€‹€y†w‡†vƒ…|†Œ€{vŠjqb|b…|opltjhnlvw_q~y{tus‚~¥•š­Ÿ§–…Œƒ~–”ƒžt‰Ÿ“’…ŠšŒ•‹zrwt‚or…squˆlnlumˆwƒ}mnUQ«”‡‚y€vr‚y‚ ‚‘’‘—›‘™wz‚‹‘£š“Žˆ•˜‘ƒ†–™‹“‹ˆˆž…Š|s‹…ˆˆœ™ž›–”€”i†‰h‡ ˆ’„‘ƒ‰qƒ‘—šŒ‹w{’{ŽŒ’—|ˆ|€kvimkllzby}Ž•vzwƒŒ|yhumuˆ–Œ‰†{”‘rz…qxŽ{‹{‰~ƒ‘Ÿž…}}x‹}wphk€€w^womkqrV]naqa_mnypgpfftuhqkawe]Ve``rSPN[ed]xpˆ|^\hqbbef‘i_gd[hp~okqsŠ}v}…tuŒy{†€xˆƒs†…~ŒŒ„|y•xfqjƒ_‡~ookz`imtt_t|x†wss…|y¡š±œ¥Ž‚Š‚™ˆ€‹~Š˜’Ž„ˆ—ŽŽŽ„vtvs€po…spqƒojium‚n}|musRN‚ßɒ֓|otƒuƒŸ‚‘v”˜›˜{“r…Ÿ¡““‰’›“…}••‡Œ‡’‰œŽxzŒˆŒŠ››œš•“ywi‰’ˆm‰¤…“ˆ˜ƒ†cŒ‘˜”‰–‹‰‹pz•‰|Ž‰Š’‘‰z…|~m|erokkyy[€yŽz~~†ŽzzhtluŒŠƒ†…}–Œl~oŒˆ~„{ƒ‘–››‹|wxƒxslep‚kitoghsmS^ndpZ_kqxfkkbgxsoqc_w``Vk_^vOMK`fc]yqŠt\[ev`aeeŽc`fbXirsmkqv‹|ty†‚uv~‹s†{‰r‰‡‘Šˆ}~™vesn}eˆopk€Zknyys`vz{vrwŠwyŸŒ›¯› ‚…xˆ”~|‰œ‡„žŽ…Œ—„“Ž‡twpypn„omn~rcdxp|nz|jhlc¤šÁÜ®ï¡skuƒu„¡„‘n•”Ÿ”š‘p…‹£—‰Ž•Š•ƒ€”„ˆ€’ŠŠ—~‡{u‰x†…Ž›š—™ŽuŠwp‡‰Œ~Œ¥…“Š…†^‹”—‰ŽˆŽ‹Š„‰l|—‚}ˆ…‰‘†v…~~k}cxtimxsWˆz‘‡…y~€…Œ~yftk‹‹„ƒ€Œ—†l‚vn‰‘ƒ‘…‚{‘—“™ttx‡ŒusqftyasmoahufR`pgkU^msy`rc`i}qrnZbrabWnZ\wMMLcfa^vsŠm[\dx^`df„_cc^Yirknkrw‹}sw„xw|ˆqƒ„}}ˆ{t‹ˆˆ•‡Œ˜shuqymŒ{ntp€Wpyvyqdvx†Œiv€Šr€ˆ™§œ£’„|pŒ”xyŠƒ„ŸŽ|•€™‡„{rwpsjokil|t^`xv{ptzg`e|ëÚµÉÃ܈sls€vŠšˆŒi—Žœ”’ˆp…ˆ Ž„Š•ŠŒ—“|’ˆ‚ˆz‘‹†‚€wxƒ„r‡‚“›–“˜†Œu‡q†‚Šˆš£„•Ÿ„‰aƒ•…ˆ†‰Œ‡€‡h}”}ƒ„‰Ž‚q†~rwgvrhswkZŒ}’‚…|€ƒ€„Š‚vbtmŠ‚‘Œƒ“‘}n‚ly‡‡“„}‚~“”‘—‰nrzŒ…tlpjqw^shn\iu_RdqhfS_ovt_o`]h‚qrjWghciXmW[uLJLef^brs…h[\ey^^dgzad_]YknenjtwŠ~sr~zvz‡s…ƒ|‡wvŠ…˜‚‚{“vlwvyx“unxz}Xy…q€ogxv‘‚dv†…qŠ–†™¡›¢Š†so’‹rvŽ›}‰™ˆ‰{Ÿ„™xqtnodr~hflww[_x{zqqiagaÕ¶Ž¦xnqw{q’Œ†j˜ˆ›‘‹†{h‡‹™†’††—{ŒŒ€€‰{~‰…zu{ƒ{q†€•™Ž’“‰u„‡w„€‹“ž ‡–Ÿ~ˆa“‡ƒ‡ƒ‰‚f}‘€~‚Œ~mƒ|‚tkmwusvukcŽ…~|„„ˆp`sr†|Žƒ}’‰zqƒf{„‹‡„|…”‘“„npyŒ~tlnijy|agiiXkuZRiribPbrxlbe^Zjƒnsb[g_dm_nTZoNHNfd\gnq€kZ[cs_\clwde]]Zllbmjsv†qo||tx…x…ƒ|€‡uy‰’•|‰†v‰pxy{„“om{€v^ƒtmizs”sgrˆ}r’‘„šŸ› ††uu”~mv“—}‡ƒŠ™|Œšv~vqoljat|gbiuyZ`w{ymq~echhW^qr–¼Ä„vq”ˆ}q–‹†›’Œ‡rjˆ–€{”Œ„šŒ|Š…|{‰‹”ˆu‰†vw}ru†ž”…”ƒƒr€‰u…|Š™ž™‡•Žœ€ˆf}“‚~„ƒ‰‰r}f~Œ|y‡‹}i€}ƒvfoyxsvslkŽ…ŠŠx‚€…ƒk_ry{~Ž‹†|‚~riy„ˆŒ†…y„}‚˜ŒŒ}nm{‰}vsngf{ub[pbWnqSSnshaNftxe`^]Yo€osYea^jn`pOYkQDSg`Zknm|nY[^mcZbowdg\]`kicljsvƒpm|tuƒzƒ‚|‚…v~ˆ–x„‹tˆryy~oo{€qixz~ml{u•kjx„tl“…Ÿ˜ ™„ˆn}Œvjx˜Ž~€‰‚”—‰y–ozsplid`szh_eqzZ`r|ygqzaee±²wJbZ¤ÙЖq{Šw}“Š„˜‘Œ…nk…’’zy’†„˜Š|†xw‰Š„–€o‹ˆqu~zjy…ƒ¥„’Œƒoƒv„y†›™•Œ”‘”„ˆp{’‚|‚ƒˆƒnwh€„xr€ƒŠ‡|e}~„vcps€hxpou™†ƒŠ|vx€„yk\qs‚‰†Š~†‰{‰rnq…‡……s…z‚™„xno~„vydgi{p^XvZXplNWqsg`Klvt`]\ZYt}soWg]fjq`oNWhR?Yf^ZojgzqZZYkeZcqy_h\^elhekiqw‡nl~€uo‚{€‚~‚v…ˆ—Šq‚q{†|zy„“Œujzko~t}or{z“poxg’‹ƒ¡™œ’‚…f†ƒogy•ˆ}~„˜‰|Œixrkkf_aoym_box\dk‚zaqv_eeÔ꽋2:>‹Žqx…ˆŽv‚•Œ~’Œml…Œ‹u}…•ˆ|‚xnv‡„ƒ—wnˆ…lu{tfy‚ƒ§‹‚Ž‹„}n€uw…z‡‘‘’“Œ‹†{’†wƒŒ‚krh€~xm||Šƒway„qdqh~muqu›‹€…€su~so\nuy‹ƒ‹{‡€|ˆxzql‰„„‹rƒz€–‹Štmkw€€tt\hgvoXV{RYpdLZrre[Ipxo\[[Y]t~thYb[genciMWfQ=^e\]uf`upZYTodYdqyZh]_fmgikipw}Žli‚„~yn€||‚zu‚“„p€‹nw}€{{ˆ’‰h{}js{r†{sw~Œzx„}|kŒ„›–Œ€€l}kh~‹z~~ƒ“‚~}Šˆkuqghb[bgso_aks`hpˆzbst^cd› n\5Z¯µti€ˆ|’†v…•…sŽŠ‰vpl…‚†ty‰x‰|“ˆz~rgu‰~~˜oq†~hvynfy‡„¤‡€†Œ‰~nv€‚~šˆ‚”‘˜‰‹„‰|ˆp{}„{h~lk€{zizv‡€r`w~qdrft‚mu{†•‘|‚owz}u~lYp€wuŒ‚†xˆv‚‰zxsnŠ†s}“ˆ‰znmjn‚tm\gdrpQZzM[o\O\rodUKsxiWYZZaq€t`]]`fdhifNZhM@`c[`va]umXWStaZdorWj^bhkgmlipw|’li„‰||p~~{‚zw€Š‹ƒq{ˆoqwƒ{‰ƒj~{mwxvŠw}x€‚‡ƒ~~zm„Œˆ˜£„ƒzu‹xklƒ‡x}z‘€€~Šƒprqcf^Yf_oo_`gpfjo‰tato[adjv{€¿œ¦¤È¸q…ƒr’|x†’‚s‹‡qroƒz‚su‡tˆw”ˆyypcw‡z€“ir„vgwucj|‚ˆŽ}s€t…z’ƒy–Ž•ˆ‚ˆ{ˆˆkxy~tgzhlysizv€ƒ}h`w‡}jktgz€ivŒ‘”~z~~p|w|t~bVx~ssŠ„‚}ƒq‡Šwxqp„‚~y~}vŽ…ƒviqimˆpo]gaqmJeuK]mUTZsnbQOsx`RXX]ao‚s[a\heeckdQ[pICc`[cp^]xhUVUw^[enhVk^aigennhpvz’niˆŒx}r{~y‚|v}ƒˆ†ƒpw„rmwƒ‚}‰‹“p€{wyzŒtƒx‚„z€uo~Š‹›žˆ}…zw…{gt…Œy~{ˆ…ƒv€gpn_d[XeYmra``plkh‰natiY^dn€w©ÚªÇ†‡²q‰woŒu{†z’‰tst~woqm„t”†xuk`z‚y‰fq„pgvn[m|€“€y‘’}x{nˆw’…t–Š‘Ž‡……{„ltv~mgvem{umjwv|abx…yhuub}{gu†Ž•{t€vq€{}mYWupu…‡yl‰†tylu€„„~{}y{s‹}sgten‹ƒksZi^tdGmmLZaWVVwmbPRtvWPVX^aq„o\`cmdd^ocU^rFBe_]fh][zbQU\u[ZgkaVj_`nefkqhpuxŽtkŽu~vx}wƒ{s}ƒˆ‡ƒor€tqu~…‰Š{wwƒ{|…‡x‡|}~„€{~svyŒŽ ‰z‰vtƒx^}…˜‹x†ƒt…†„w‰{bnm[aZ[aVisc`[gnof‡qaqfW\ck|Ê·¹¡jmmŠlq„q|ƒ‰~z„yxsyuu|jluc„u’‚wof^}‚z‹Šer‚kjqcXmz…›ˆ‚s–“v~|oŠq‚‹ˆr˜Ž‘‰…‹ƒ{x}qqo|fhqbmxqjkqx}|z]ey€wivxf‚wgt‡ŒŽ”{q‡jo~€yn|]Ysnt‹|‚ooŠqvhw€w}q{u‡}zrfsan‹jrWj^v[HmjMVT^SU{kaOTurPQTW^bt…i]`kjfcYnaYdpG@g\`f_\Uz]OUdpZ[jh]Wh`^rfkgqgprw†xn•Štzw~xƒ‡ur†…Žƒpp{xvuz†…†Œ…z|t‹~}†„„‡~~}‡|xvyx‘“ŸŒ|‹muxd‚†•…s‘Šo……zƒtcnjY_Z]]Tgrd`XdqrfsbkeW[`jx¾®{ ¶nbs†hs{qy„z}‹~wwrvo{vejn`‡uŽsjb^xy‹„fqhkkZVow‰£„q™’q€yv„nƒ“‰s•ˆˆ„‰…}xtrnhx`jm`mvjgjkywzvZg}|xer~n„teu…†–~oŒgkzƒumtb]q}lu}Œ{fu‡}nqhux~s}l{{‚{xoelbn‰}kmVi_vUJijOQNhMX{haNUujLPTU_fuƒf^`phgaWi]\lhJDjYadWYTxYNVmjY]kd\Yec^tfldqgrouxp™…v~w|…‡}us‚ˆ€•ƒnsy{zsr…†ˆˆƒx}u~|„ŠŽ„‚„{~‹ƒ{w|wwš—zŠ‚†iv}{lƒ„’qŽp…‚~pflgW]Z\[Sdpd^WbruiupeebW\\ipor€s‰ddx~itutrƒw€ƒyvsumkzqbgkg†tƒnf]_}p{‰imxgjdUWro¦|„{v–t|s}|n||’†w™|ˆ†ƒ†ƒ}tpqlgt\lh^ltdgfizo{rYg€vuhp€x‚vbw…‹|”€nŒjm{‚qfseanzgsxŠ|~bvƒvjkqu{qzzt}f~€ywncfbn†|ljUiboRJhjOKNoG^{faMUtcJNSWajv~e]gsie`VcWcp]LKjXcaUTTsVLXudZ^k`\Zce_vgmbpisnrutšw€w†„z|t‚„~—…nrt|ztq„…€y‹ut|•Ž€…„}~Œ†{~€v{£¥Šyˆ†„ku|zuƒ‹zn„sy„}ƒunjheV][ZZSbmd[Xas{ihmi`bW_[j€ikp€gk`hyxjsttn„€z|uunzhjyj_enhv„geXbwj~‡{oipgf]UXogŽ¨wz|‘Žyuppsvz€x•u†ƒ€…ˆvjqughn[ld]mr_gajxh{m[n‚rtjo€~yxaw…„x…sˆroy€rcqi\qxdrt‰|ybs€pgjytqlxxuxdƒ{ywqddcn|}kkUhaeRJkgOGQkEaxgaMSr]JMTZekvze_mqid]V`VnnWKShWe^XNUlTJ\y_[_k]][ce`yhl`oounoxuz˜}w€z€€‡†zxy‚~“„qttyvt„ˆ‘}€|ks•€{‚Ÿ…~‡}€†‚€Š{v„«Ÿzˆˆƒkryu€tn†n|€sŠ€jomddX_ZYZTajg[Z^t‚i^ml\aV\\leqt}ii\kvugsvrm…{}|xurlygixf]erhzw“ccTepg‚…wwghj`WVYgc§n~w€‹{pq~hzoz|wr„}†ndurdhh\ka\oo\g_mudzh]t€orkq{}uvbt…‹{ˆ‡€xruuapm[rtcqs…}uer€lal{oji{zurf…v{{vqebems~ilTg]\TKrbPFVaGbwgaKToWJLXXgkuzdenqfdZW]XvfUJ\cWgXYIWePHbxZ]_l[^\ac^~ij_ntxnonvƒ—yr€|‰Œ†~uu†y‡Œ}suu‚yzz‚ŒŽ}~„‰is–zŠ}~…zz|†ˆsq­Œ{{‡}eq‡ys|{urn…l{~lzbpobe]eVYYVcfk_]\r…hXpn[^WZ\l{bpwvmbZlssgtupl„x~xwnntdite[gtfvv’y_]Rffjƒ‚t~bci\TX^bc¤hxtƒ†‘xmo{ixn|…{u‰s€x|xhdvl`f`^j_\skYe]oobze[w|knnowxstdsƒ’~‡ƒ‰{vpr~sbxd\ppbqr‚}tgr€e^nvidfy|uno‚ut}trb_fno}diSgXWSMw_QJYXHbudaITmSJMZWilq{bllscbZZ[aw\SLc]XiSWHY`MFiuX^`l[[_bb\„iganxylojvxmƒ~€“ˆ„vsˆtŒ†sqwu‚w|}~Œ€~“~pw•ƒ|™’y€€xz~€tˆƒtp™¢{z‰”xdu‡xsxuksn~kx|p‘r^po`gblT[ZWhcmf\[q‰eSrn[ZXX`lvciuji^Ymsplsssi„|~~{vonldiqc[krdtvŽs[WSear€r‚]bc]SZ`\c‘Ÿeqq…„‘tll{nop{||qwszzzceuh]bZ`g[^vhWb]ohaw`[{vijrnwsruhq‚•ƒ†}ƒvsjq}nfwX]lncrsztgo~[`pqa_jq}llu~sqxkpa\ellzagSfTVQPu[QOXQHctb`FUkPIPZUkkj|emnq`[ZXYlqWSOfWWhSTFY\NHruX_cmcX``a]‹jcdmyxkoiuy†{kƒ}„š|‚„y|‡n†qowz}t‚‚|‹‚‚—tw‚“…Ÿ‰u€t‚q‡‚uo¢—s{†‹†{ewŠnmznfwpzksvrŒk^tnagekR][VgalkZ\pŒdOon]VXUgjtgbtee]Ymtmoutxj†|{‡vsddkna]nmcsx‡kZTVcdx}}q†]c_cTZ`Yb••cnpƒ…Štkh|pfsws|lztuoz~u^erc[^VadXateU_`mdaq]]~phisqsptvkm„“ˆz„qsgo~qsoT\gkfqtwsclvUbrkZ^of}emw}ssskm`Zdjjw^fTdTUPTmWQVSOGds_aEXiOHWTVmhd|ikwjaW]U[tdSRWhQYeTSHZZPMxvZ_eliYb`^^Žnafkyunohvvlƒ€}‡—{€‡‰~k“ˆrgt€{u€‚}ˆŽ‹“r|Š‘…‡Ÿ†{†Œs†s~‚vn¥Œr‹vwmzŒ`d{pfxrxlmqv‚gd{lcfghS_^Ug_ln[^mhNim`TVSogslfxdd\Xoslqzwrl‡{v›zykaelm^`ojeqy~gZVX`lx|{p„_b^gWX_Wd›ˆbkp‡}xlkyn\wql{jvsno{€rXim^Y]UbcWdpcS^ahablZ`~kfksunmwvli…Œ‰y‡mqfq}nsncZaiiot‚ts_ilSeqdUbnbzcqw{vkpmk`Yaght\eUaURNXeRO\OOHdp]cFYiMI_KXmd_xhn}c_T_T]u\TS`fN]aTSJ\YPYtu]_elhXca[^qcgjxqsngvtzƒr‚ƒzˆŽ~|‰‡ynŠtls‚t‡…†’„•y~Œ‡‘›„€|Œ…s€stxro““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~}~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’‘‘‘‘‘‘‘’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’‘’’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ”ÎÚØØØØښ„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDBN¥¯­­­®±a@DDDDE8.////+H…ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ”Ûéççççêœ~‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR455553A©¶´´´´¸Y055557':ƒ€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}z{z|}{}~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹’—˜˜˜˜™š’Œ‡‡‡‡‡‡‰““’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†…………†‘‰………………„ƒƒƒ‚‚‚„ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z{|{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘‹Ž‘‘‰‡ŽŠ’“Š‘‡‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŒ‹‹ŒŒŒŒŽŽŽŽŽŽŽŽŽŽŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}|}}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…Ž‡‰‡‡Œ‡ŠŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰†Š‡†Ž†ŒŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰Œ‰‰‡ˆ‡Œˆ‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}|}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹Œ‹†‡‡†ˆ†‰ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz||||}~~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒ‰ŠŠŒ‰ŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzzz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{y{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰‡‚‡ŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†…………………„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰ŽŠ‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{}~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““””””“””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••””•“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””’’“““““’’“”““““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘’’““’““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’‘‘‘‘’’“’“’‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvy}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡ƒ‹Šˆ‰‰†……„„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxy}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzop{xy{|{xw{xuwttvttvwuqrqnprpghklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkigfgggihgmgjghehgccbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__`c_\_]`]^Z^]YY^ba^^ZY_\XWSNMLKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{yvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSSPMJMNPROMPQQQQRVVQQQTPPNNOLJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTttuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMOPPRQPNNONONOOPQONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKLFDFJKKKHJLLLOMLLNOOOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtttwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEBA@@CCDEACEHKOKIIJHGJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AE@>:<>><ED>?EA?@A@DEGGGGBDDEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrrtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;899;;:@;;><;;<<HL==AA?BC=ADDFBFFDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNMMMNONNMKKNNNMNNLTnpprtusqrvxy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;:;;89:87:<978;;>=;;:8:@@AB?A?CFDBCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqtsusqsxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<979:9988::78:9:;;8789;:8<;=@A@=;;><==@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyy{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>=;<<>?=<=;:<===<<<<;;:;<>=>?@A@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmqquutusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCC@><=?A@?<;>=>CE??@=;===<;:=>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVppqssttuy{{{}~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???CED?=;<@?<;KG88:<9==@=:<;;<;8:;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pqrrrtuvz{}}|~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC??AAABA@=<=;>>97dl;8:88:;=??<;;<;:;;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{|}}|~~}}}~~~€~~€€€€€€€€€€€€€€€{NIKKLLLEILNM<?<<=>@@AA;BCBCA@?@@==FIJkyM<>=?==>CD?;<=>@==>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hloppqtuvy||}|}~~}~~~~~~~~€€€€€€€€€€€€€€}QHKMMMKJKLOQ@?>>AA@@AGABECDB@@C[AQt}}{\?@@C@@?@@>=<=@EABBFHC=<@DCAA?>=@A>>>?<>@DGE@?@A?@CFECBBC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vpoqprutwz|{||}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AAAB@Aoc„…‚ƒ~i?BCE@??Na_J@CEIIIIMMKECFGHEGEEEDDCA?@>>BFJJGDEFFFJNNKJIGGHKLJGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@EFCJv€‚„{€…tDDEDCWu†‰Š~XGIJLLMOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHIHGFEFFFDFHGEEHHFHGHFQnnpqrvvy{{{z}}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJIIQv|€„ƒˆpDCAUt‡‰‡‡†‡‚WILMLMNLJGGGGDGGGGFHFHECCDFEDDHHCCCGJJKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrswwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLKJUx~‚„††‡ƒUNl„‡†††‡‡‡‡|PKLKHGFFDECC@ACCCCFFEB@>>@AA@BD?>?DFHDEGIKIIGHIGIIIJIHFJJJJIJIJJJFILLJJKKfopssuvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKLKJX}ƒ„„ƒ‡‡ˆ}†…„„†††‡‡†ŠuIIFB??@??><<<>::<AA@><998<<=;>;9;?ABAACCC@ABEDBCFHIHHHLMLGIJMMNMJJKKJLMSlortsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHHIIKQv„†„~…ƒƒ„„„……†‡ˆˆˆ‰‰ŒŽfBB=88::9878896479;<:8567789787689;;<>@;999==>;;=ADEHJMLLGIHORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@CGILHq†…~ƒ‚ƒ‚ƒ„†‰Š‹‹‹Š‰Š‹Œ‰T;8656766645773468:876565676778:77789;7689989876:<@GFIFIFEFOSRSSROPPRTepqsttwy{|{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:=ECDK{†„‚ƒƒƒƒƒ…‰ŠŠ‰‰ŠŠŠŠ‹‰‰ŠH676468874578467699766765:::::<898977779:98878589;A=>>BA?AKLOQPQOOOQWkrrttuwz{{{|}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897;B:=M~„‚ƒ„„„„„†‰ŠŠˆ‡ˆˆ‰ŠŠŒŠ‰‰Œz>:88;<=>9::;89;9:;:99;:9===?;;;=:>;9;;<;<;9;<8::;;999<?<<ABDIJMKJKLWorsutvx{{{|{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<;89989::9;??AJ}ƒ‚„………†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>BCEEAA@B>@B@@?=>>@?>?@?@==?B?AA?A?=@@@>?A<><;:;:9;?=;;==AACABCAXqqtttvy{{|}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::<=:;;=<>@DCU‚ƒ„…„…„†‰‰ˆˆ†††‡ˆ‰Š‹‹‹ŠŠ‹Š‹^>DGIKIIFGHDFHGEC@@CECB@BCB?@DHECEDEEAFEFDFFD@B>=@>=?@>???>?>>:;=<`qrttuwzyz}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>???=A?BCGEh„ƒ……†††ˆˆˆˆ‡†††‡‰ŠŠ‹ŒŒŒ‹ŠŠˆWGLLMKNJIKHIJJIECDFGFDCEFDBHIKHGGFGGEKIKIKKJCFCCDBAACBDCCDDCA=;=@hpsttvwzx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLK@BBA98<>;<;>@@A?BBFFKJu„ƒ……‡ˆˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹‹ŠŒPMPMKNKJLIIIHJFDGHHIEEHFFELLMIJGGHIJNMNLLNKHFGGEECFFFFDEHHFCA?@Llptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?FGG=<@@98<;<=:?@>@@CDHHP[„…„…†‡‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒ‹ŠqMQOMLLKLJIGEJHDJHGKJHJGGGKLNLLHHIJMPNONMOKIGIJHIDIHHFFGGIFCBACUnquvwy{xyzz||}~~~~}~}~~~~~€€€€€€€€€€€€€€TDAABGGB?8?@9:<8=>;=A>?ACFHJTqƒ„„„……†‡ˆˆˆˆˆ‡†ˆˆˆˆ‰‰ŒŒ‹ŒŒ‹‹‹‹‹^RRPMNMKJGFCGJGLJGKOLKJJMMLOPNHIKLOQPPQOOJIJJLJLFGHGFGIFEEB@BB\prwxyzyyyzz{|~~~~~}}}}~~~~€€€€€€€€€€€€€€€UECEEGGED;?A;=<9@>>@BGGAFIINTx…ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹‹ŒŒŒŒ‹‹|WVRRTROLKJEEFKONOWVQPOQSRNSTOMSLPSUVRSRPLKMMMKNGGJFFHJDDEEBDCcquyyzzz{z{z{|~}}~}}}}|}~~€€€€€€€€UFEGGGGHF>@B=?==B?BCFVNELNMQV{†„……„„‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŽ‹‹‹gVVkaERQQPJ;;QSR`u]UVTVYYSYXRZfPUWZ]RTWQPNRPPPQKLKGHIHEFIHIHIjsvyyzyz{{|z{|}|}€~}}}}}}~€€€€€€€€€~~THJIIGGFE??A@EBCGEDELXRMSTSVX|†…‡†…†‡ˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ}aŠ‹‹‡l[dU:XXXSP?@VUY\d`VYbr^]W]ZVEQYZ\Y_TYgRUVXTTVSOOMJLJIILMKOMSotvxyxwzyz{z{|}|~~}~}}}~}~€€€€€€€€€€~~~~VJJIHGFDDBA?HMIMPKIKPTSSWYXZYx…„…………†‡ˆ‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~Œ‰Š‹znpXZ[ZRSRWVTZZuƒYU}a\X]^WIV]][[_YHYXY\]XXYWRQMPQMMOSQQURassvwwvxxxz{{|}}}~}~}}}~~€€€€€€€€€€€xy}YNKIIIFBD@A:PQQWXPPOQSTTWXXYZn‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡ƒŠfYY\YSVTWRQWVc–€QerXZW_hP`fZ[X\hbGOZig\[\]]WSNSPPQVVVVYZosuwvvtwxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZ[RSQORRQURUSW_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PVXTRTRQQLOMKfyZ]TYUV]ZLTZTST^ZXWWWzkXZ\\^SPPPINOWVX[Zdqtvvttvxyy{{||}}~}}}~}}~€€€€~~zxwvsu{€€tk~~kry^\VUSROKFCDAM^ƒlVRSNOQOQURSRRTcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰‰‡†ƒ‡‡‡ymqVIKNNKMKHJDFHEC>ScURPQNKRTQMOYQMNQSUUMQSRPNLLHCIHRSTZ]mrvvussw{z{{{}{}}}~}}}~}~€}}~~€~{vsw}~~du}iqt_d]^[YUQLILIal’tPQSNQRQR[RSRQRUUbs{|€‚}{{€ƒ‚…†‡‚†††„†…†u_]KC>CCCCB?DPCC@C>BHGV@HNMG]iQHFOFDEFHGHBCHGHJGDBAC@OPMRdtuvustuz|z{{{||}|{~}}}~~€€€||}€€€}vt{mh|gnqfieeb\XSQPURsWe[OONLQSQUYSUQQTROV`klsvz{xyurnstsyx~~ƒ€ƒ‚‚€‚€‚kLG>>:;>@??>>jPKaEFHIEB?GLMGMQUIBE?><=<==?=?ACB??<=B>JMFUouuvstvx{|z}{|}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QQZ\Y^IJPQNKLQRQTUUWQQWVPX[b]agmmlokh`nrjmlqu{z}zxz||xwxdB@@A=:BCAACA[\O{NOONKLMOOQLKLWMHG@B<977599=;;;8989?;AG>\tuuvuvwy|||}||}}}~|~}}}~}xuwz{zwyxuw{|yxuywcqhipmnmmhf^OP^\ZIGPRQOMPQNQRSVXSRYTNYZ[WY\__`e`]^qwk^`gkwooljonnlfbYGFFHBAFIEEFCLQOaWRXQPSSRU[OOQVPMICF>::6486979:365795<B=fttvwwyy{}}||{|}}~~{~~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZWMKTTSPQUOLRSTWYTTXQLXYYVXXVXY]WWXhsk]V`tkaa_]d`_^YUPMONLIGJKIHFCPOSZWTTMQSYS\eUOSTRNLIHC?A:988978847578589Gnruxxz{{}~}}|{}|~~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPWVVSTVOOUVXXYSUTLKTUUUUWPTUWTUR]n^RNY`[VY;DUWT[fJLPRROMMNNNLJFPPUYSTNJNOTST\VRUSSOMLIHHF??=:787659967665Wqqtwzz{|}~}~|}}|}}}y}}|~~~}||}}~}|rvqxxruuqqnppopuvtnjddjppqrpofedc\^RTZVWTSVTRXXYYYRUOJGPPOOMRJOPPPNNOTLMIPPSTU2<XMIAQ=c`QSQPNPQPNNMPNTRPRLILKOQPQRSTQSOLMKLLHCBA=:9876;B4566;eprvxy{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqpuuvcjgeWhtrrqniihpVVTUXUVURWVUZYXWUQSFEAFGGHFJDHJHGEHLHKIGLMPMG/E_R>3@>joaRRQ@FTQOPPQNQOPOLJLLOPNNPQQNPOJMMMKGEEDB;==<9=G6677Dnquwz{{||}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknbePSTRSUOWVVYYVQQQO@>;=?@BAC@BEDA@GHGHFFHJMLDGCORC8ENS]gSQSAGUPORQPMMNLJLKLNOOQMOOMIMLILKLKGFFED<AA>;@E;<89Tqsuy{{{|||{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpknqmimcLONMQSLTUTWWULLKH=987;?A?==A@B=>EHFDFFIGKJ@FAA@FHEJOHQRa\QPRNSOOPLLOMKMLMON[VKMQOHJHCIJLLKFFFE?CC>=BG?B>Adqtw{z{{|{zzw|wy}~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCE=9879?B?;?A@@>ADIECHGIGIEBB?><CBAGIDMOaePMONWKLNKLMMLLKNNSdMJLRHIJFAIJLMNKGIFBAB@?EFEHDLopwzzy{{z|zwsxtx||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGLLIMPMPOGKE?B=999:?B?<ABBADDGKFDIIGGHCC?B??@A>CECKNQTKJIMTFIIJLJKKIJLMOPRPKGCLHDCJJLMOMIJIGCCCDIJMLIZsmxyxz{{y|vrpurtyyvxjqnjllnttmsu{stxronqovsnporpopstyjN`gsjt|ygosqiqheqHKCFGGGJKIJLDGB=>=:::;AB?=BBCCHFJLJEIIFGGCC;A@B>@@CECIMOGHKFHKDHIKMHJLHIJLJM]RIHDNGBEKKNMPNKMJKFGGJMNQNLcniwvv{x{z}qmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoijthdpFKCFEFDEEFEGCC@><=:;::@D@>BCEEIFJJLFIIGFFCB;BCC>@CCCEGLNHKNHDHEILNMGILGFFIILNKJHEOICGMMNMPNOOMLIHIOSQRNRfgfrosxu{z|lhjoekpmsqfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGICEEDBCBE@DB>?>:;;=;=?CA?ACFGJGJILHGGGFEC@=EEB>ADCCEGIIGMPIFFGKNOKFHIFEDDIIHKIFHPKDJMLPNONOPNJJIMRUUROWdaamgprosyzgehhcilgqlflmgiklsmpvutpnvrosrsutqssutsuvvvyvutvlkuumrvqlnlerMGEEGCAABD<BA>A=::=?;>?@B?@BEGJFIGIGFFFEDCAAFFCBBBDEEGGHFLPLIOJJLKIGHEFEDCIHHKJGKRMCOONQPOONOOKKKPUWVUSX_^]iaminhrsbeffdihfnifmmhkkmriqvusqmvnoqrswsrstuvvvvwvwvvtwuksunutsprkksMFGEGBBADD<AA@C<89=>:?=?B?@@DFHEHFFHFEECCEBCIFCGEAEGEFFGEJMKHQMJKHHIEFHHECIIJKMKPSNDRSQQRNONNPMLNSWVWXVX]Z]d`hbjigk_defcgggkggkmkmlpqgttursnvoqprtxqssuvu‚‘yvvtxuuwxnouorsuqqipzMGGGHBBBFE<@CBD<7:=>;>:@B>??CEFDFDDGECECDEFFJEEIGBGHFGFECFJJGMKLKHJLFIHJHEKKLLNOSTOITUTQTPQMNQNMQWZVZYWZ]ZXa```_hec`deggjhhjfhnllomqpiuuxrrpupppruvpusuvu{~}xvtwvvvwplupmsunossyMHHGIDBCHE<@EBD<8:>><<=BB=?>ABFCEBBHCCDEFFGGIFGJHCIHGIGFDHKIGKIMKJKLHLJMKINLNNORUVOLVVTQTQRLOQPOTYZY\ZZ\__^`c^\ackb`dghr…hgifjnnponsqjtuxrsstrnpqvrqtruus~yŽ}uuvvvvxriuqkrtlqwquKIKHJEBEGE<@GDD@9<>@?>?CB<@>AAFCEDCHDFDFFHHFHGIKJEJHHKHFFLHHHJHMLLLLIMKMNMOLPPQUVWOKVVUSSRQLORRQV[[]^[]^``a`be]d`eg`ehjcssfjhglprqossnswwpuvtsmoruorspurvrtwuuuwvuwsgtrkqrkrwowIJLIKGBEDE<@FDDB;??A@@@DA@B?ACHBEDFGEIEFEIHFIHJLHHJJIKJFJKHIJJGKKMMJJMLMNNOLOPRUWVMNTVUSRQPMNTSRW[^^_]^``aaa`cdebcicdijgv‹lkihmosqpqpprywruutsmmssmqrotutspswtuuwvuuueqskpqjrvpwJMLLMGCCAD<?EEEC=AACBBCEACDAAEGCHGHGFJFDGJGGJFILHIJMJMLGKIHKKNQKRQLSMKNMNPPPTOWXX[NSQW\ZSVPNTUTTXZ_bb_da_`b_`ebacinicihhmxvlhimosrpqrrrvtsusssnksqmprotvrrquvuswywutucmtkopjqtpwLMLLLGEA@D>>DEFC?CAECDFCCEGCBIEBHJIHHKFDKJGHJHIKGJJNKNLILHJMKZfJd\KlRHOM_nUls[qpbwcRPbvuhucav`Xnqbdvinzf\lt`lkU_wvijhhfglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqsqyKNJKJFB?@B?=DEFCCCBEEDFBFFGDDJEEJLLJLMGGMJHJKGKJIJJNLMMLLILML[sbdp^llUMNfs^gfqlntgpi_aYnmbppbkjjgoqtetno\ougpMKryvkbakeelxmkvlnpsrprqpqrqrrrtrmmsnnoprutqsstuuutwxvutbmukpplrrqzKLIIGED?AB?=BEGBFCEDEEDCHHGDEKHGKMMJMLFJNHJKJIKJJJKMMNMMMKNMM[roonpplkNPQlXNibtrpamov\YlP[mmZqmkomxxtsip\`slqjUuyxoc^kfbgppjiopprspqpqqrrqqrrtlmrmmnorutqtrtuutuuzvutenukpolsrryJKGHFEEBAB=??EGBGDIEEDBFIHHEGKJGMMNKMNGLNIMKHIMIKJJKNONNMLNML\hdu]lqWlNPQnUZk^klvaldtTecNlYl\tpkilxjwuhp]_skhWbcw|oc`ghaditykonqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtvIMGIEEDCAB<B@BFCGFKGECCHKHHFJLKFMKLRRLGMMHNJHHNHJJIHNONNLJMMJZsppoqqmlOQSoYqkgooqqomt^nXat_nopoqroousttj[^tcwxrjnzhaacfabjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyytukoumtontsvtHKHJCEEE@@>CCAFCHJMIFCFJLIGFKMLFOJKWRKGKJJNIHJLIKJIHJLMMLIKKKSkbZi^_jcrrZ_Zjo`eeUk_c[abQ`mh\j\niid[pfdp]Z\k[mqcpsldgcdg``knppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunvqrutwrHHFJDEDFA@AEDCGBHJLGFCFKLIEFJOLIOIL[QJFHHKMIHJIKKIHIGKKKKGHJJLLLKIKLNT[]TPUMQPNOOURPOQOOQJJNPQdqiTYW[[\UY[]X]\\cfaafbcf__fkmhmtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuzyxuvqruovrtsuusGCEGFFAEC?CGDEGCIKLHFDGJLHDGIPKLOKLWMIFEHIJHIKHLJHFHHJGGIEFKHIKNLIO\W^O\\`^OXYS\\b^MYZMXaRKYaZS`d]bX[ddVVX\YZX\VY\^c_d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtOBCDLMBCDBDIEGGFKJKHEEJJJFEHHPJLMJMRIHEAHFJIKKILJHFEJHEFGEEJGBJMJKT_Y`X`a[`UXYT^^Z_RY\P^\YN_\^S[^c_Z]`c`Y_b[`^[TYXZ_^dbbacfiekrpoppnnw††……†‚{€……††…†…uqprrsvyyzyyxxxwryvxrqxvtvaSJJMIECBCFGEGGIJJIIDFKKKEFIINJNLHLNGHF>GGLIKKJKKIGEIEDDEBFJD@JKJO[cY^^a_RTSW_`\]Y^QY\MV_WKQY[Q[_aa]^ca`bbbcceZRXVV\[^c`__cebhommllllu…„ƒyu|„………††……††ƒ}wrrtwyyxy~}yuyvvrnzwvxXQJFCGEBEGHFGHIFGJGHFHKILDDJJMMLLHJJHJG?GFNKKKMKKKIGHDD@DAHIA?IJGP]aZ[d]_TQRX]\\\_ZKW\LR\YIM^QQ]_accccb\dcbdcfXQVUS\X[a_^_aa_dlkmjklnv~uz|„………………††…†……††‚zrsuu{…‡‡‡†…„~xpzwvx\RMB@IFCFKIFFGIGGJFFFILJNEDJJLNJLIKJIIGBHHQMKKOLKKIHGED?EBHHAAGFDT]Y^X_X_[]UXXP]]QKJW^X^[]VZaRR__bb``bb`cbbddbXORQS\S\^]^^__`dhgljnnp{{|~{€‚ƒ„………………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKBAGFDGMRHDRKFHHHDFKJMPEGIJKNLLILKIIGDHKQOMLPLLKKHICEAECHGBAFEBVUE\T]SV`XNTUNZ[MJKU`a[_X_^b]OYb\``_bcb]bbW__TPOPQYS^\\]]^`bffelfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDFFGDIRcQDW_IGGHDFMJPPFJIJKNLLKMKJJGEJNQQNOOMNMNHKADACDFDCADEALHCLLPOOMFMFFHJHGLLMOPILOPPSPLQSRUZYWYXXdVOSTPPONQUT\YY[]\aaefchdklqsszy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKM^MGHYMHHJHGMLQQILJKKNMUNOKKLGGKPSSNPONOOOHLF`ED_LDfcDM[H^\smOMVmYLCP_UlWgJ]WU^DLQULMSVQRTXWTXUT\TPfZhhdYTkTXWU[\[``abbb`gignlhrz|}~„„„ƒƒƒƒ}}zr{z{‚€ƒ„„……„…ƒƒ~z{LIEFFHEEKOTJKG`THJOJIOMRQKMKLORUROOJLMGHMQ[YOPPNOPPJKQQI|YYrsWPmHqnoaVPqqtOBksnqtpSo_[nX]V\XUkhU]VcY`YZ_VUWjtuu_av_Yc\\f[_aaab^`bgmpl`pwtx‚ƒ„‚}~€vxzmv~tx~€|~€‚„|€ƒz~wwNIEHMMBDLLGJLFRVLLOHKRXWQNOOLQTNOQPKKNGMPS[ZTQROPPPKHZx]TxdhYRSPvgtlpbnfkRrOLwmjrpsrqrpop€]fzuxqqzq~r}ku}bRh|essoss|}p~yor_``bb[a`hknkblfgmw~€ƒ~{xw€tvzhr~nt|~wx{~€ƒx|u|||ssNKF`]GAEMMHKKHKQOMNJNV^YULQSNYYLSSRNLPIQRTYWWQTPPQRKGgxlcxqmZKLTypumubnvPdeIevqmwo€jfxxiXrRi{mijzz~lxzpgoXvvjvup€ash}ilx|o___cb\_defijdgbcdllppstsssyqrxbltgry{ssuy~suzn|}yxrnNJRtNCBEPPHKLJLQOOOMPZ`ZXKTWPa^RVQYSMPJSTUXWWPUPONSJKrouuquqdhaVnLqp^GhyWvTKhy}x`y{sna^modSgrunmypwlvstqlm\s~zkmy|lum|kpvux^__b^]_edjhhee^bbiiijknokqnmjpacfdowxompsynqpj{ztromLKZVHGEGRPKLNKLQQPPPQW\YUNVYUfXRRY^TMNJTTVWYWOSONNQIRmHiwK`dvuUWlOnl{rajgvUKWkh}lmlx`[pz{_`zscroxqhd|ir{]TKl_vukiu{{m~xk|p]^^b[^bdehfeebZccikkrsrwgmihdg`alagsrkhmmr|kmhk{tmmkmOGJKHJHHRQMOPMLSSROSRWRVTPWZVVTTTa`QONKTSSQVVOOMNOPJHQNPULKKRSRRTPVUQQORRXXQNPUTXXX[[USSW[WXWZPSUWWXQ]XV]USOXRVWWXZ`[gr^[\[]]_cZ_ccegeccbZccgffmnmuffgc`f_]g`dlhfgkhpzhggkujhgilPIKKLMKJTRMRQPLVVTPTUXUZURZ]VUTWUYXPOLNWUQNUSNPNLQPKIQQKQMKKOQTRQQSSIIMNOQRQQQTVRXW\WSSPRUUVTZQNSRWUTYVTYUSRUSTUXXW^Z_a]\[Z]]`c\]bbdgeeebY`acabhhincad^_c]Zd\bma^ffgmsdihkkeddfhQJKKNOLMTQOTQQMXWUTVXWWZVT\`VWVYUXTQPKOXTQNUPNQNKSPMNUSNRNMNQSPTQSTUNLNOQTTRRQVWUYZ[YSURTXWWY[SOSUWUTYUVYTRRWUVX\Y[`]VY_]^]\]`a^[bbchfeebX``b]`hefda^_]]^ZZ_Z_g`^^]chkahfhfd`bdbPKMLPQLOTPPTQOQZYXWYZZXYV]jdVXYZWVTTOKOWUPOTPPQNMQQORXSRQOMOSUNWQTUUONNQSUUTTRTXVZ]\ZVVQRWXV[\VPSVUUVYTWWTRRXVV[_Z^`_V_]^`\\``__ZbbdhheebYb`b^^fdc`b]\\\\YZ[X[a[^]]_b__bddbd__`\PMNNRQMRSPSTQOU\ZZW[[\YZ[dqmhd_[YVVXRMMVSNNRPRROLPSRUZUTPPLPWUQVRSSXMOPQTXUUUSUYX[^]\[VROUVV[[WQSWUVXUSXZTSQYWW]_[__`Vb\`a^`b_\`]cacgiegaZc`a__ee_`c[Z\[\ZZYYW\Y\[`^_[^^a`_c\Y`ZQNONVQPUSPUTSPW\\\Y^\_W\^jpwyc\[VVYRNOWSNQRQSTRLQTSY[WUORNSXVSRTRRZOQSSV[VVVTVZX]^\\^VSNTVV[\VQTVVXYRSY\TRR\XZ]^]aa`Wb[cb^ac_\bab_dgidh^\e`a`acd_b_YZ_[\[YXYWWZ[Za]][]\\Z]`W[[ZPOOOYPUUSRWRTPZ]^]\`\`U\]hjr}rlh\UYWQOR[SRQTSUUTKRVUZZZSOSRUUUSNVRSZRTUTX]WXXSX\X^]Y[^UUNVWW^ZWQUUXXXTVX[TRV]Y]]a^cc_Y`[eb_dd^^cca^efieg^]daaabcd_b^X[_[\[XXXXW[Z[`][[\[XZ[^V^Y]POORZP[UUWVTTT^^`_^b\`U]^bkytl}lZUZVQQT\TTTUUVYWLRZV\Z\RPUSWUUSOWRSWSWVV[]X[YUZ^X_^Y\ZRWRYXY`ZYSUVZYZVWY\UTZ]\^`a`ed]^]]eabfd^_dc`\gdhfeb_da_aabb_`^WX^Z\\ZYZWV]Z]^[Z[\[WY\]VXW]SOPWYP]UVYWWUX_`aa`c]`U]^beev‚{hXYZTVTV\XWWVVW]XOU\Y^]]TSXRWUSRSXRSVTYXX]^X][U^_X__X\VQYUYZZaX\UVWZZZXYYZXV]^_^cbbee]b\`fbefd_`dbb[fbhfcfaf__abaa`_^VU]Y[\[Y\YY][[[XXY[YZZ]_]TY]UNSZWT\UVWYWV\`abcac__V[`da_zuohZ\ZVXVX[ZY\ZXY`VOT][`a\UUYPTVTRVVRSUW[[\_^Z_\V__Z]^Y^VSYXZY]bY^VWZ[[[ZZY[YY__``dcdeebdZbfcgfe^ac`c^cciedg_g^bbcaa`^_XTZZZ[[X\XX\[Z[WWZXW\[\`]V]]SOVZVVZVYUXWX^`badada^YYadb`kfh^\][WWYZ\\\_[Y[bVSW^]ac\SVYPVUUUVVSVTX]]_``]a]W`^[^\[^XVXX[Z__[_XX]\]]][Z\XZ_a^`dcdfffbYcfehgd^ca_ec]fidei_g^cbcaa`__[XY[YZZXZXW[[Z[WXZTY]\Z`\U^bMRWYVWZY[\YWY^`baeada]^Ybcb_a`a_]]]XW[[]]__\Z]cXYX]`cd_RYYPWVWXXWVWV]]^`aa_b^Ya]]^Y]^YXUW[[`^]_YY^]^^`[ZZY[_a_bddefggbZdfgigc_c^`feZhicficf_bbca``_]]ZW[YYXXZYWZ[ZYWXVU[]]]``bbxKWW\YW]\\]ZW\]_`bdbca]`Xbcb`cac^\]\XW[]_]`_][`d\\XZcecaR\YOXVY[ZYWZZ`^abb`ac_\b]_][_^YYTX]]__^_[Z^^`bb\\W[]`bbcedgfegd\efhifcab\cg`\iibhife`baca_`_]]\Y\YXWXYYW\[ZWVXPXZ]acffrkJYW][Z_]\^\Y][^_acbaa]b[bda_cbb]\[ZWXjq`\`_]\ac_^YYcedbT_ZQYW\]\[Z[[c`cbc`bda`c^`\^__ZXV[_]\aa_][`abeb^\S\_`cddfegfefe_ffhhgdd`[fg^ahhbhhfc`b`cb___]][Z[YXXXVZV\ZZVVULXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡…‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vvvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{{{{{zzz{{{|{{{{{{{{{{||||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vvvvvvvwwvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{{{{{{{zz{{|{{{{{{zz{{{|||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||upooooppz~}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰ˆ±µ´´´³µ•‡‰‰‰‰ŠŒŽŽŽ‰~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}upnoooooz€~†“y1333332j‚€€€{­éääääèʉŒŒŒŒ‹‘»À¿¿¿¿ÁšŠŒŒŒŒŒŽ‹}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒƒ„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}vuuuuuuuvwwwwwwxyyyzyzxooooppprrrrrrrwzyyzzz~ƒƒƒƒƒ„||||||}€~||||||}}}}~~}}|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚‚‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vvvvvvywvvz{x{xwvx{wzzz~yxxyxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{zzzzzyzz{{{{{{{{{{{{{|||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwwy|{||z}zwwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwww|{|}y}ywxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z|ywwwz|||z{zwxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚ƒ‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzzz||}|{}{xxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyy{xzzy{yxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyxyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegefgbedebg[be`v||{{||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}||}}|||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚‚‚€€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrstuttssrrsrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqstsssrqqppnnnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqqrssssqpqpoonnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrqrrssrrqppoopoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpppqrrqqqpopooppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqpqqqqqqpooppppppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopopppppppppŠŒˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqqqqqpppppppppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsquŒ‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqqqpqqqqpqpqpqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹‰ƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrqqqqqrqqqrrqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrssrrrrrstrrsrsssssssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz|~~|vvwwvuxzxxxxwwwvx|yy|zyy|{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~|{{z{|{}|{{{{{{zyxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œ‰‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}|||~|}~~~~~}}||}ƒ€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆŒ‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€€€€‚€€~~~~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒˆ†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~~€€€~~~~}~~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽŒ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~~~~€~~~~~~~~~€€€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’’‹Š‹‹‹‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚ƒ‚€€€€€€€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒŽ‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒ„‚„„‚‚‚‡ƒ‚‚€‚‚‚‚ƒ‚‚ƒ‚ƒ‚ƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…ƒ„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒ‚ƒƒ€‚ƒ‚…………††‡†…††‡‡‡†††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒ‚ƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠ‡‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„ƒƒ‚ƒ…ƒ‚‚„…‡‡‡‡††‡‡‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ‘‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚‚ƒ„ƒ‚‚ƒƒƒ‚‚„„ƒƒƒ‚ƒ„…„„……„ƒƒ„……‚„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘“’ŽŽ‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€ƒ‚‚‚‚‚‚‚‚ƒ€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„…„„…„…†’“‘ŽŽŽŽ‰‰‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~~€‚€‚‚‚€€€€~€‚€‚ƒƒ€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“’Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€‚ƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚‚„‚‚ƒ„‚ƒ……†„‚„‚€‚‚‚„ƒ‚ƒ‚‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘ŽŒ‡…ƒƒƒ‚‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒƒ‚ƒ……ƒƒƒ„‚ˆŽƒ…„…„„„‚€‚ƒ‚‚„ƒƒ‚‚„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ……„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”““’ŒŠ…„„ƒƒ‚‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~€ƒ‚€Š™…‚‚‚‚€‚‚ƒ‚‚‚ƒƒ‚‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†””’”’‹‡„„ƒƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~€€€ƒ€~{˜Œ€ƒ€‚„ƒ‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“‘Š†ƒƒƒ„‚‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€€‰ƒ~~‚}•‚ƒ„‚ƒƒƒ‚€€€‚‚‚‚‚‚ƒƒƒƒ‚ƒƒ„‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ…„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†„„ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„‚ƒƒŠ„ƒ’……„„…‚}}}‚„ƒƒƒƒƒ„ƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„……………„…†…††………………„………††…†††…†††‡†…………ƒ„„„‡““’‘’Œ‹ˆ…………‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„„ƒƒƒƒ„…„‚…’‚Š†…‚~‚†‡†ƒ~~~ƒ„ƒƒ„„„„„„„„„„„„………„…„†……†…†††…†……‡……†…††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„ƒ‡’‚†„‡~~……~€„…„…†††…………††‡††…†……†‡‡‡ˆ‡‡‡†††‡‡‡†††‡†††…„ƒ„……†„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘“’‘‹ˆˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒƒ„„„…„ƒ‚‚ƒƒ„ƒ‡‡‚~~~€€€€€……†‡ˆˆ‡‡‡‡ˆ‡ˆ‡ˆˆˆ††‡ˆˆ‰‰‰ˆ‡†‡‡‡ˆˆ†‡†‡‡††…„ƒ„…†…………†††‡‡…†‡†‡†‡‡‡‡‡‡‡‡‡…‡““‘‘‹‡†…†„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡‡…ƒƒ…„ƒ„„„€‹…€€‚€€~{z€†ˆˆŠŠ‰‰ˆˆ‰‰‰‰Š‹Šˆˆˆ‰Š‹‹ŠŠˆˆ‡ˆˆˆ‡‡ˆˆ‡ˆ†‡†„ƒƒ…‡‡‡†……„„ƒ……„……†„„„………†…†…ƒ‰”“‘ŽŠ†…†…ƒ‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡‡„„…„ƒƒ…ƒ€ƒƒ‚‚‚‚‚‚‚€~|}}}~|{|ƒ‡‰‹‹ŠŠŠˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰‡†††‡…†ˆˆ‰ˆ‡†‡„ƒ‚„ˆˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚‚ƒ‚„ƒ„„Ž“’‹ˆ…„†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„………‚€‚ƒƒƒ‚‚‚ƒ~}}~~~~~}}~}}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡‡‰†ˆ†ˆ‡‡‰ˆ„ƒ„ƒ…„„……†ˆˆ†…ƒ‚‚„…‡†‡††„‚‚ƒ„‚ƒƒ„‚ƒƒ„ƒ„‘’‘ŽŽ‹‡…††„‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…‡‰‹Š†„†„‚†‡ƒ„ƒƒƒƒ‚‚}|}€~~~}|}}|z|„†‡†„ƒ‚ƒ„………ƒƒ…„„„„„„…„‚‚ƒ‚„„‚ƒƒ…†…„‚‚‚ƒƒ…ƒ„„…„„†ƒƒ„…ƒ‚ƒ‚ƒƒ„…„‡’‘ŒŠ…„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€‚€ƒ„ƒƒƒ‚‚}}€€}~~}}}}zzz~ƒ„„‚€‚‚~‚ƒ€‚‚‚‚ƒƒ€€€ƒ‚€€€€€‚‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†Œ“‘Ž‹ˆ……ƒ‚„‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€€ƒ‚~~~}~ƒ„ƒ‚ƒƒƒ‚}}~€€€~}}}}~}|zzz‚‚€~€~}€€€€€}}€~€€€€€€‚€€‚‚€‚„ƒ†’ŽŠ‡‡†ƒƒ‚‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒ‚ƒ„…€€|}}~}~~€€}~}~ƒƒƒ‚‚}}~~€€€~}}}|{{{zzzz€€~~~~}~~€~€€€~~~~}|~€~~€€€~€€~€€…’’Ž‹‹‡‰…„ƒ‚‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~~~~€€~€„ƒ‚€~}~~€€€~}}}}{{|zzyyy{~~~}~~€€~€€‚€|~~~~}|€~€~~€€~€~~~~~}||}…“’Œ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒƒ‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚ƒ‚€‚ƒƒ€€}}}~~~~}}}}}|||{zzyyy}€€€€€€‚‚€~€~~~~~€€€€~€€~~€}~}}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…ƒƒƒƒ…„„„„„‚‚ƒ„‚‚‚‚‚~}}}~~€}}}}}}}}|{zyyyyy€‚‚‚„ƒ€‚ƒ€‚€ƒ‚ƒƒ‚€€€ƒ‚„‚€€€€€‚‚€€€€€€~~||Š“Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…ƒ„…„…††††‡………ƒƒƒ‚‚€}}}}}}~~}}}}}}|}}|{yyyyx|‚ƒ„…‚„ƒ‚‚ƒ…†‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚‚„ƒ‚ƒ‚‚‚‚€€€~Ž“Œ‡ˆ†ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€~}}}~~~€ƒ„‡ˆ„†††…††‡‡††‡ˆ‡‡‡†}€‚~}}}}}}}}}}}}||~~~|{yxwxyy€ƒƒƒ„ƒ„„„——ƒƒ„}~‚‚‚‚ƒ†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ……„…ƒ‚ƒƒ‚ƒƒ‚‚‚‚ƒƒ‚‚’‹ˆ‰‡‰‡††„†…„„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€~}~€‚………‡†‡‡†‡‡ˆ†‡‡‡†‡‡†}}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yxy|~‰—„ƒƒ„„”“€~~…‹€€€„†‰…„‚‚……‹ƒ‚……††„ƒ……ƒ„„ƒƒ„ƒ…„„ˆ’Ž‹‰ˆˆ‰‡‡‡…†…„…„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„„…„}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|xyz{|‚ƒ€ƒ‚€~|~~{ˆ‘||Ž–}‚†Š…ƒƒ„ƒƒ‰}ƒ„……ƒ…†…„……ƒ„……†„„Ž‘‹ŠŠŒ‰ˆ‰‡…†…ƒƒ‚‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚‚ƒ}}||}}|||}||}|}}}|||{‹‘—Œz{|zzz{|yy}}~€€|{{~~}‚•‘„ˆ~|~‚„||‚„‚€‡ƒ}ƒ‚‚€ƒƒ„„„„„‚„ƒ„…‚„‘‘Ž‹ŒŒŽŠ‰‰………ƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚ƒ…ƒƒ…………ƒƒƒ„‚‚ƒ‚ƒ‚‚€€~}~}||||||||||||||}|||~~Š‚{z{zxz{{|}{~}~}}}}||}†~}‚~~~€‚||€€~}{Š‚}€~€€‚‚€€€€‹“Œ‹Žˆ‡‡……„„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ…„††„„€†”ˆ€‚€~~~€|||||||||||||}|||||||y{{{xxy{zz|€~|~~}€‚‚€€€‚‘€€~€~~~€}|}{}}}|}||}€€€~€~~“‘ŒŒŽŠ…††…„„…ƒƒ‚‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚„†‡††~ˆ•Š~€€~€~~~|{{|||||||||~}|{||||{|||zzy{|z}…ƒ‚~~€~…‚~€~~€…†‚€~~ƒ†~|~€€€~}}}}~{|}€}~€Œ‘‹Ž‡„††…„„„ƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}~€‚ƒ††……~€€€~~}€€€€}}||}~}||}}}}}|~|}|{}||z{z|}}†„‚€€}~}~~‹„†~}||~‚}}}}€|{}|~„ƒ€~~~~}}}~€~~~„’ŒŒ‹Ž‹Š†„…„„„ƒƒƒ‚‚‚ƒ‚ƒ‚€}|||}~{{}w~vx~}|}|}~~‚ƒ€z}}|~€€~€~~€€€€~~~~~~}~~}|~}~}}|{|||z{z}~€ƒƒ‚~|}|}||ƒ~Œ~|{{}~}~~}{{{}|z{{{€†„‚„ƒ‚€~‚‚‚‚‚€ŠŒŒ‹‹Šˆ„„„ƒ„„ƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€~€€€}€~~~~|‚~~}}}{{}}|z||~€‚€€€||}|||||}|}{~{{{|||}||{{{||zz}z~‚~ƒ„‚‚…†……††‡†‚„‘ŽŒ‹Š‹‡ˆ…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~~€€‚€~~€€~}ƒ||}}|}}}}{|~~~~~~~||||||{~~{|{||||}|}|~|}||{{|y{|{|}z}~~€€ƒ‡‰‰‰Šˆ‹‰…ˆ‘‹ˆ‰‡……ƒ‚‚ƒ„„ƒ‚‚‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€~~~}€€€€ƒ‚€€€€€€€~|z|}}~}}~~Œ†}}~{{ƒ‚}~~}}|}}}}}~|}|}|}}~|~}}}}|{{z|{||{z{{zzz{~~ƒ…ˆ‡ˆŠ‹‹‹‰ŒŽ‰ˆ†…„‚‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~€€€€~~€€€€‚„„€€€€‚~~}~€~{~‘Œ|}Š€Œ~~}}}~}}~}|||}}|}|}}}~}}~~|{{{||}|{z{|yzyxy{~„ƒ„‡‰Šˆ‰‹ˆˆ…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{|||~~}}€€€‚…ƒ„‚‚‚‚€€ƒ‚€}~€~|~ˆ‚~ƒ„„ƒ~}|‡}}~}||~|}}|}}~~}~}}}{|}~||{|}zzyyyy{{~~€ƒ‡„ˆŒŠŠ†…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{|}}}}zx‚€‚‚€€€€€‚‚‚‚†…„‚ƒ€‚„~€}~~}~€€}~„€~~}~}}Š…}~}~~€}}}|~~~}€}~}|}||{|}{{{zzz{{|}~~€ƒ€‰Š‹‡………„ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv~€ƒ‚‚‚‚‚ƒƒƒ‚…†„‚€€€€‚€ƒ~~€€~~€~}~~€€~€|€~€~|}}|~~~~€}‚€|}€€}|}}}||{||{{{|{|||}|‰Šˆˆ…†……„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€ƒ€€€€ƒ~~€€}€}}~~€€‚€€}€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{|~|}|||{|{|~‰…†…†‡…„…„‚‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz}}yxut€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚~~~€}~€}}}~€€€€€‚~~€€€€€~}}}}|~~}}„€~}}}~}~~}~|{|z|{z€‡‚„„…„„„…ƒ‚‚‚€€‚‚ƒ‚‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xytu}‚ƒ‚ƒƒƒƒ…„…„ƒƒ„„ƒƒ„‚€€€~}}~~~~€}}|}}~€€€€‚€€€‚€€~€~€€€~~~~~~~~……€€ƒ~€~~€~}{z{z|{z‚„ƒ‚‚‚‚‚ƒ€€‚€€‚ƒ‚ƒ„ƒ„‚„‚‚‚‚~€~}~~~~}~}}z{|…„{{syz|pwuvwyvtz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€€€}}}~}~~}~|}}~€€€€€ƒ‚€~€€€€€€€€‚‚‚€ƒ€ƒ‚€€|{|z|{|€‚€‚‚~€~‚‚ƒƒƒ‚ƒ‚„‚€‚€~€€}~~}}}~}~{{z€x|vyy{qtxwvxury……‚„„‚„……†„„‚„ƒƒ€€€~€|}}~€~~~}|~~~~€€ƒƒƒ€‚€€€€€€€€€‚ƒ€„}ƒ„€€‚}z{{||}}€|}}€€~}}€~‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxyzruyyvwwsu†…ƒ……‚„„…„„„‚ƒ‚ƒ€~€~€}}}~~€~~}|€|~€~€‚ƒ€€‚ƒ„‚€€€€€‚ƒ‚€ƒ€~‚‚„€€‚‚‚„‚~{{|||}}}~}z~}}x~|||~}~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„„„…ƒƒ‚ƒƒ€}~}}}€~~~}}€€~|~~~‚‚ƒ‡…~~€€€€€€‚‚€€~€‚~‚‚ƒ‚ƒƒ…‚}}}|{||yz{z~y{yx~{{{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzswvst†„„…ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€|€€~€}~}~€€€~|~€€€~}~~€}€€ƒ„ƒ~}~~~€€€‚€~~€‚‚€„‚„…†„€~}||||zyvyyzyvyv~|{{{~|{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…ƒƒƒƒƒƒ‚‚ƒ‚ƒ‚~€}}}}€€€|€€€€}€}~~}~~€‚‚~~}~~~~€}€€€~~~~~€‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{z{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ||z{{{z{wvxursvqxyrx…………ƒ„ƒ‚‚„‚‚€‚€~~~~€~}~|~€€€€|€~€€€€}€~~}}}~€‚~~~~}}~~~|€~~~‚~~€€ƒ‚ƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}}{|z{}zzx{|zz{xtxuqrtpxxqy„………ƒ„ƒ‚ƒƒ‚‚‚€€€€}~~€}|~}€€€€|€€~€}€~}}|€€€€~~~~}|~~|}€~}~€‚~€€~„‚‚ƒ……‚‚~}}{{||yw{ywxwwx{{z{|…Š}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzzzzxswuqqrpxwq{…†„…ƒ…‚ƒƒ‚€€€€~~€}|~}€€‚€€}~€~€€€}~|}€€€€~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{|||zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚‚€€}}~€‚‚}~~~€€€‚€€€~}~|€€€€€~}~~€€‚€€€€€„‚‚€~|}~~z}…~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚€€€€€€~}€€‚‚‚€~€€€‚}}~‚€€€€€€€€~~}€~€€€€€€€€€€‚€€~}~z“z|}|{}y{zzxyxy{||}|||||||}}}||}|~}~~~}|z||{}}{yzzzyysuuooqpwst}…†ƒƒ‚ƒ‚€€‚‚‚€‚€€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€€‚‚€€€}~|†‰||~{{~yz{z{~wwy||{}||||{}|}}}}|}|~~~~|{|}{}}{yz{zyxstunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚‚€~‚‚„ƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€€‚‚‚€€€€€€}~€}€ƒ‚{~~{|}{z||{‡yxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€€€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ‚„„€~‚€€€€€‚~€€‚€€€€€€€€€~}€~€€€€€€€€€€€€‚€€€€€~}~}~~{}|}|||xxuxxy{||}{||||}~~}}~€€€|}||}{z{yz|xzsrunwqqzqvw……ƒƒƒƒ‚‚ƒ€‚…ƒƒ„ƒ€‚ƒ‚€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€€‚€~€€€€€€€€€€€€€€€€€€€€€€€‚‚‚‚€‚€€€‡~~|z}|{}xwvyyz|}}|}{||}}~~€€~}~€€€‚€|~}}~|w{zz{zytqunwpuzrvy……‚ƒ‚ƒƒ‚ƒ„„€€‚†ƒ„ƒ‚„€„ƒ‚‚€€‚‚„‚‚„‚€€ƒ‚€€€€€ƒ~€ƒ‚~‚€€€~€€€€€€‚‚€‚ƒ‚‚ƒƒƒ‚€€€„}}}|}z}€zyvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysruowqwysw{…‚‚ƒ‚ƒ„‚ƒ„ƒ€€‚‚†ƒƒƒ‚‚„„ƒ‚€€‚ƒ‚‚‚~€€‚‚‚‚€€€€‚‚„€~ƒ‚€ƒ‚€~€‚ƒ‚€‚‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ€‚€}€|z|{{w|yyy{z}~}||||}~~€€€„„€}€~{{{z{zspxrytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚‚„†„‚ƒƒ‚„„„ƒ€ƒ‚‚‚‚‚€‚€~€€‚‚‚‚‚€ƒ‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚‚ƒƒƒ„‚„‚ƒ‚‚‚‚ƒƒ„ƒ„„„…„…ƒ„‚ƒ‚‚ƒ€€~||€||x|yzyz|}|{||}}}||€€€€€‚~€€€€z{|zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚ƒ………ƒƒ‚ƒ„„…‚‚‚ƒƒ‚‚‚€€}€€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€‚€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒ„ƒƒ„€‚„ƒ„ƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{~~}y|zzz}}|~z||}}|z{~~~€€€€€€€€€}}||}|vrvxxvtvu}‡‡ƒ‚„…ƒƒ„…„€‚……„„ƒ‚ƒ„„€„…ƒ‚‚‚ƒƒƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚‚‚ƒ„‚‚€€‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚~ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz{}€}||z|~}}}}~~€€€€~~€€€€~|}}~~}|{xvvw„‡ƒ‚ƒ…ƒƒ„†„‚††…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚ƒ~€€‚‚ƒ‚ƒƒƒ„‚‚‚ƒƒ‚ƒƒ‚‚„„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒƒ„„„„„…„ƒƒ„…„…„ƒ‚€}‚€}||{||€}}~€~~}~||}}}~~~€}}~€~~}}}~}}~~|}‚‚ƒƒ†ƒ„ƒ†„ƒˆ‡…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚ƒƒƒ‚‚ƒƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚ƒ„…ƒ‚‚ƒƒ‚„ƒƒƒ„ƒ„„„…„„„…………„ƒƒ„}„€}}||||~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€„„ƒƒ„…ƒ„ƒ…‚Š‹…„„ƒ‚„…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚ƒƒ…‚„„……†„‚€ƒ‡„ƒ„ƒ…„……„„ƒƒ†‚ƒ‚ƒ‚‚„ƒ‚ƒƒ…ƒƒ……„……‡‡†‡…„„…„€ƒ~~|~}}€~||~~|z|}}}}}~~~€}}|€€~~~~~€‚€……„ƒ…„‚„ƒ†€‚……Š‰„„ƒ„……ƒ‡††„„„„…„…„„ƒ„ƒ‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ„}uzƒ„„‚ƒƒ‚ƒ„ƒƒ„…ƒ„…†„…†}„y|~ƒ{…‚„ƒ~~~}}ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚‚ƒƒ‚‚†„„„†„ƒ„…ƒ„…„Šˆ………ƒ……„†††ƒ„„………„……„„…‚‚ƒ„………†„…„ƒƒ……‚h€…j|{qq|s†stt}‚ƒusqƒ†spurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚……‚hzrss|€s‚ƒ~ƒƒ}}~~}~‚ƒ|€}€~}||||}|||~}~€}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ†ƒ†ˆ††…ƒ††‡‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vyy…r„ƒpvxqvtturstvi€nrotvnulwm{sn€ˆym}rsvsvmmxlpylu}}~€}~}€€}}||}}|}~}€€€~|~€‚€€€€€€€‚ƒ‚ƒ„…ˆ††€‚…ƒƒ„‡†ƒ†……†‡‡„ƒ†‡ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwgwznpu‚rƒ~ozyymonzoomw}x†pqzprtfu~n{ysoy€}}|}|~€€~~€€€~~~€~}€}€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„†……††ˆ„„†‡ˆˆ†‡„††‹‰…„†‡‡…„………„‚……„…†……†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„qjoyxpkyszozwvvp€~~~z~}}}~}€ƒƒ€‚ƒ„‚€}~~~€~~‚€€„‡†ƒƒ†„……†‡†…………††ˆ……†…‡‡…†„††‰ˆ…„‰Šˆ…„††……ƒ……„…††††…ƒx‹yrˆz{pp……x…xyks~y{krƒ‡ƒz|m{yyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozls|nw‚€~~}}{}{|}}}}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡…………†‡‡ˆ†„†…‡††…„……………†‰‰‡†„†…††…††„†††††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„††…†„†„ƒ„„†„„ƒƒ„„…„…„…„†ƒ†‡…†„„…‡†„„…†„…}w…ƒ„„‚}~{|{~{||}~}|~~€}€~~~€~~~~}}}~|{|~||‰†…„†††…‡†…………‡†‡ˆ†„†…††……ƒ„…†…„††††……†„…††††…††‡‡†…‡ˆˆˆˆ†„‡…††ˆ†…ˆ‡ˆ…‡††ˆ……††…††…ƒ‚……†……ƒ…ƒ„„…„……„……ƒ†‡††…„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ‚}€{{|~{||}~||~}€}~€~~€}}|€}~~~~~~|}}~{|||{{}ˆ‡„„ˆ†††‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡……†…„†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ……ˆ…†‡†‡†‡†‡…‡‡†‡……†‡…‡†…‚ƒ…††„„ƒ„„ƒ„†„………††ƒ††…†…„††…„„……ƒ…‡…ƒ‚‚…ƒ„~€€|{}~{|{}~}{|~}~~|~}}~~}}||~~|}€|||}|||~z{{}~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†„…„††„…‡ƒ„…„…‡„…††…†„††‡‡††ˆ‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…†‡…‡†‡†‡…ˆˆ‡‡…††‡…††…„„…†……„„„ƒ„……†††…†…†…†‡……††…„ƒ„„ƒ„‡ƒ„‚„„ƒ€€{{~}|||}}|||}}|}|~}|}}||||}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††„…†…†…†…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡…‡††‡‡‡…‡†ˆˆ‡‡…‡‡‡††‡„‚„ƒ„†…†…„„„„„…†††††…‡……‡………‡…„ƒ„ƒƒƒ‡ƒ€‚ƒƒ‚‚‚€{}~}{||~}|}}|}{||||||}{{{}|{~|{|}}|}}~}|zz{{||ˆ‡‚††††‡††…„…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡‰ˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡†‡‡††‡‡…‡†ˆˆ‡†…‡‡ˆ††‡ƒƒ„„ƒ††‡……„„„…†††††…†‡††‡††„†…ƒƒƒƒ‚ƒ†ƒ~‚‚ƒ€ƒ‚|~~||}}|}}|}z{{z{|||{{{~{{}{{{~||||}~}{z|z|}‰‡ƒ†…†…††…„„……………„ƒ…†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…‰Š‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……‡ƒ„†…„††‡†…„ƒ……†††††…††‡†‡‡…ƒ†…ƒƒ‚€ƒ…‚ƒ~ƒ~~~||}}{}}|}zyzy{|}{{{{~||||z{}||||~}|{{{{|{‰‡„†„†„††…„…†…„„ƒ„‚€ƒ…ƒ‚z„Œ{€„…‡†††…„‡ˆ‡†‡……‡Š‡„‡…††ˆ†…‡„†‡‰††ˆˆ‡‡†‡ˆ†„†††‡……‡ƒ„…„†††‡…„„ƒ……‡†‡††…†††…††„ƒ„…‚‚€ƒƒ‚‚}€~ƒ~€||}}~}{~}|}yyzy{}}zz{{}|}||z{}||}|~~€|{{|~}|ˆ‡…†…†„†„……………ƒƒƒ€‚…‚€€}|{„……†„…„ƒ‡ˆ†††…„†‰†‚†„†††……‡…‡ˆˆ†…ˆ‡‰‡††‡…„†……‡…„‡ƒ„…„ˆ††‡……„‚†…†…‡†‡„††††…†ƒƒƒ…€€€ƒƒ€|€~~‚€}€||}~}~{~}||yzzyz}}yz{{|{|{{z{}}|}|~~|{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€€ƒ~~~€yz}€ƒƒ„†…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ†…ˆ‡‰‡†…†…ƒ†„…‡ƒ„†„„…„‡†…†…†„ƒ†…†††††„…††………‚‚ƒƒ~€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|z{{{|}}}|€~}||}~|{‡……††††„…„…ƒ…‚€€€€~‚‚}}{‚ƒƒ…†…„ƒ‚†ƒƒ„‚€…‡…‚ƒƒ…„„††‡ˆ‡……ˆ†‰‡…„„„‚…ƒ„†‚ƒ…„…†„‡†………†ƒ„…„…†…†„ƒ…„…ƒ……ƒƒ~€€ƒ{€}}‚}€}~~}}}}{|{zyzzyzz|yzzz{{|z{{{|}~}}€}}||}€}|†ƒ†††††„…ƒ…‚…€€€~€‚}~~€€‚‚„„ƒ‚‚„€ƒ‚€„……‚€‚ƒƒ„…†ˆ†…„†‡…‡……‚ƒ‚‚ƒ‚‚…ƒ…„…†„††‡††…‚„„ƒ„†……ƒ„ƒƒ„ƒ…„€€‚‚}}~~„~{||€}€}}ƒ|~~}}~{~{{zy{zyzz{yzzz{{|z{||{}~}|}||}€~€†„……„‡„„ƒ‚†‚ƒ€€~~€}|}~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡†…„ƒƒƒƒ„……„ƒ‚ƒ‚„ƒƒ€€~}|~~|~ƒ~|~||€~‚}‚|~}}|||{{zzzzy{zzzyyzz{|y{}{|~€}~}}}€€€†„„…„…‚„‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„…„‚ƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚‚€…ƒ~€~||~}|~ƒ}{}|}€ƒ}}€~}|||}{{zzzyy{yzzyzz{{{z{}||‚€~€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌËËËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFL=8765999<>9?<D:;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937677=;>9=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<9<<98:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA><A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËÊÊÊËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÕÔÕÔÔÔÔÕÔÔÔÔÔÔÔÔÓÓÓÓÔÔÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9?CE@<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÐÑÐÐÐÐÐÑÑÑÑÑÑÑÍÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø××××ØÜÝÝÝÝÝÝÝÝÝÝÝÝÝÜÛÜÛÛÛÛÜÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÜÜ×ÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILO@99:4;A<7=9AC>@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌ͖„†††††‡‡‡‡‡‡‚²âÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¹³xsssssssssssssz‚ƒ‹ŠŠŠŠŠŠŠŠŠŠŠ‹‡½æáââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVN<::77>C?8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÎnPSSSSSTTTTTSL óëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§£££££££££££¥™2)+++++++++++)5ECCCDCCCDCCCCFSSSSSSSSSSSSSKªòëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;?C>6:7>>;=B?9<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÌÎqTXWWWXXXXXXWP¡ñééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤¦›8/00000000000/;IHHHHHHHHHHHGJWWWWWWWWWWWWWO«ñêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;?@@8:;8<;;<?:;;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÎx^a````aaaa``Z¤îççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©« E=>>>>>>>>>>>=HUTTTTUTTTTUUTV`bbbbbbbbbbbb[¯ïééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB>;=:9;:==;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÇÅÅÅÅÅÅÅÅÅÅÅÅÄËÐÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÎÏÎÏÎÏÎÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÑÊÊÊÊÊÊÊÊÉÉÉÉÉÉÊËËËËËËËËËËËÌÌËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÔØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<8@B<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÏÏÏÏÏÏÏÏÏÏÏÓÏÏÎÌÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÎÎÏÑÎÎÒÔÏÎÎÓÓÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖØ××××××Ø×Ö××××Ö×××××××××××ØØ×ØØØØØÙÙÙÙÙÙÙÙÙØ×ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?79:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÎÎÑÁ§ÑÒ¨ ÐÏѤ¡ÐÎÎÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<>B>BC@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÎÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÎÏÏѝÅ´ž£§Ö¯Ÿ¡©ÒÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?>;7:>9?D?A98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÏÏÓº¯ª¸Ÿš“Àž˜•œÈÐÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<<:6?B@C:647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÏÏӟ±¨š¡œ´˜œ¢°²ÓÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8FA?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÏÑÀœ‰žŸ›–­¹†ž–¯³ªÕÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<>=964:99::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÏÔ£¢ ˜› –x›„“¤ÕÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:=?>=<9@<<::9?@>=<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÑğ{š…Ÿ¨ˆœyŸ©…™¤ÕÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CFCAB8;?<=;<<8558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÕ«¯¼ÀÓv´°¦œŠ½­¦˜¯ÖÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF@HIGE@<<>><=><756:96:;::;8@?:<<9<>=;;:?9?:;9=>==;;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦Õɇ… •¦——¥§–˜›»ÕÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;557<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡ÆÓÓ՜˜Â¢«¤›ÐŸ«¤œÑÓÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKL@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÒÑÒר‡ÎƐ·×¼ÕÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<=?GFHKH=657:979:;:<=9>99:8;=>>A>=9<<:=>>:=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÑÒÏÅÔÔÇÃÕÑÕÅÄÕÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?AELLA>775;8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÒÒÓÔÒÒÔÕÓÓÓÔÔÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEK>>786967899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9699:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EILAALD??;:889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEGIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDJ;AA;<886486987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGIB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<BA<;876797799=?A?<:9@?<>B?:8776=??@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE>;HF89757875898;>>=;89A>=@?A>7596;>AB??@@BB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCEFC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELCA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<;DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGGNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAC?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€iixsg~‰‰xp‚†{w}~…Š½ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€‚wt|„‚}sp€Šx‚yƒÈÞÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsoupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿¼½¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»º¹¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjdmgb\XQPQKTJB:IQ?A7<94:565455688686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸········¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µµ¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸¸·¸¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶·····¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨¨¨¨§¨©©©§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸········¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥£¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§§¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©ª««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤££¢¢¢¢  ŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž£¤¡žžŸ  žœœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=7789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥¤£¢¡¡¡¢£¥§¦¦§¬¬§¦ œ›¡¡ž›ššœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¥¦¦§§¦Ÿ›š›¢ ™––•š›™——˜˜šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜—™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥¢¢¥¦¦¥¦§¦¦ ›™›¡ —““’—šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB@DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥¦§¦¦¢œž¡Ÿ—‘‘”—›˜–––˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;;;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¥¦¥¥¦§¦¤¥¦¦¥¥£  ¡¡Ÿ™’–š™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šžŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡ ¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢¢¢£¤¤¥¦¥¤££¡¡¡žœš•“”˜›š›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œ ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸŸŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::88:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸ   ¡¢££££££¢¡ ž›™™˜™™™š™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢ ›ž ¡£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œž››œŸžœœœœŸ   ¡¡¡  ¡  ¡¢¡¡¢¡Ÿžœšššš›œš™š›™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥£¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¡¢¢¡   ¡¡ ŸŸžœš™š›››œ›š›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›šœšš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>98;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤£¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ žžŸ     Ÿ ¡  Ÿž›š™šš›››››Ÿžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›ššš›™˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9;;>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœ›œžžŸžœšš›œœœ›œœžžœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:=>:?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››š›œššš›œœ›™™œœœžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™˜˜ššš™™™˜š›œœœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›š™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š››››œ›˜˜˜™™˜˜™™™›œœžžžžžžžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ›››››››™˜˜˜˜˜˜˜™™œœœžžžžžŸŸžžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ››››››š˜˜˜˜™™˜š›œœžžž  Ÿžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_^]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜™——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜˜˜——˜™››œœœžžžžœ››œœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±³­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=9F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œšœ›œ›˜™š˜˜™ššš–‹“–™˜•˜˜–›œ—•’‘’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨©¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‹‘‹ŒŽŽ‹……‡‹ŒŒ‡ˆ‹Ž‹‡Œ…†‹†ŠŠ‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VPQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹‹†Š‹‹‰†„†‚€‚‰‘ƒ€ƒŒ†‹‰…€‡}€’†„„†ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹‹‰‰…‚}s}ˆ€~œ„……‰‹Šz}}†ŽŠ†”‘‹—”—’˜¡–ž—•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¥›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ†‹†ˆ…„ˆˆ‰„‚z||}~’ˆx…‹Šƒ„…ŠŒ‘™””” ššŸ¢­±­©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPFMHSWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‹‡Œ‹Š‡’Š‡†‘“‘‘„‡}}ƒˆŒŽ‹ŽŠ‰Ž””˜‘•›š¨®²¯¯µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWLO_^\NUTbQDTM;?9<895775795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš˜ “—š ™›£ •› ¤£š“ˆˆ‹‰‘‘Ž‘Ž‹˜šŒ”š—œœ›Ÿœ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUKTOOJCPK_bXZQ\S_MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ª©¨§¡¥¨¨«©©¯¡›Ÿ¡££ šŸ œ”˜”˜  ¡¤ž›š¤§¤©«®¬¥£¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdVOXKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®ªª«¤¡¢¥©§§©¨£¢œ››¤ ¥¨£ ˜™Ÿ¡¢©§ ¢¢®¬«ª§­®¨¥¤©©©©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_UZNRNPORd\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢šœ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨¦¥§¨¦©¨£§¦™œ¤¦¢¡ ¡¡ œ˜™Ÿ ¡¤¤¢žž– ›š¢¢ ¡Ÿ ¢¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOWO^ddlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤Ÿ¢ ¢¦¡¦­¦¦ŸŸŸŸŸ™šœœ¡ ¡¤Ÿ¡›šœ ž¡Ÿžž £™–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvwa_\UYQUV[c^r_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?C?:8:>?C@DA:;><@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯«ª¬¨¨«°©¨©¨¡Ÿ §©­°²¯¬£¢¦¡©¥ž¤£¢¦ ¥¤¢¥£ž žŸ¥¢¢žŸ¢˜•žšžŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸ ¡¦¢›—’šš •|wo}yf[[`_Z\V\hdocnihb^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¢ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£Ÿ¢ª©§®·¶´´¶³¯¬«®«¶°©²±­®§¦ž¢££›œ—¢¨¥¡Ÿž£›ž¡š–¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¢™˜¥ ¤§ª©¨ª­¬¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxib[_^\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>AE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢œŸª²¸¼¼½»º¿´¯±³µ´··¯µ´µ²°¨¤¢Ÿ —•š—¤ª¦¦¡¤£¤«¥¥˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨©«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥ ¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxyxc[RYT__alhukpgiibYSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶³º±ª®´±°±´µ¶¼½¾¼¼½Æº¸·º½´¯µ±±º¸·²³²ª¦¦Ÿ˜¤¤§¨¤®¤««µµ®³ §ª¬§ª©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš“–””˜“š˜Š‹‡€€|‚xa^YSah`fsositdidb[LK>:8898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÃÆÃù½¿ÀÀ½¿Ä½¼º½¾´§ª˜±À½¸µ¹À³¯¯ªª¨­§§¤¯§ª´¼±´µ¨¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`a^^jbbnwuvnl[bQU\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAB;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–•–‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±±§¼¼¾ÅÄÆÉÇÅÆ»ÄÀÅÆÀ¹¯½¼À¾¾³«ªŒ³»¾´µ·Âº­¯°µª«¦ª£­¤§±¶«µ²­³­¨®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|ƒjfhaklfnuqruqf^_\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÅ¿ÃÂÆÅÀ±“¾º¿Ã¶¶º©´³´©«³»»±Ÿ›±¯¬¤¬®´§ª©¨ª­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|tkkndolhqxoyiia\gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÄÄø´À·´¼Á¹··¿À»®¥®·¼·­œ£·°¦­´µ¬®¥¥£¨¤  ¥™ª³²¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyz{vnkiguZfrwsxfg]d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÉÆÃÃÄÂľ¸¾ÁÃÀľÁÏÏÎÆ«¯¶´µ« §´³®«¸µ³«©£¢­©¬¦­Ÿ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuueeijg]jomxwcb``^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÏÏÌÃÇÆÈÈÈÇÉÇÅÉÇÈÇ¿ÅÇÄÄÇÈÊÒÏÒ̼¸¶´¸¸Á¾¾º½º¼º¼¬­§ª»º¹·À²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqobagugiitmxl]d[U`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÍÐÎÇÌÉÂÁÆÁËËÇÆÌÉÍÅÆÆÃÆÅÉÍÐÍÏÌÇÄÀÃÂÉÍÇÅÁÄÇÁ»¾´±°°Á¾¿ÁÆ¿¾¸·Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`jjvlieunsb\bTWTSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<:>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÅÇÈÆÒÉÁÃÄ¿¿¾ÄËÈÊËȼ»ÈÇÉÍÈÃÈÉÉÆÅÃÂÁÂÇÇÉÊÇÌÈÇÈÍÆËÏÅ·ÀÀÀÀ»º½µ³³¿¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrofegdjdajmnn^X\VUNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÂƾÆÁ¹»Ãº¸¹¼¾ÁÆÁƺ¹ÉÉÃÅÄÀÄÁÂÁÄÁþ½ÂÀÀÁÂËÃÆÌËÅÈÑ°¾½¸º»¼¾·´°¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfadbabccjbfcZYY\YQNE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶·´´µ¿»½¿¹½ºº´¿¸µ¸³¯»¼·À·½Â¿Á»¿Á¼»Å¾»ÁÄÀ¾¾¸¼ÁÁ˾½ÉÄÀÀÊÀ±Á¿»¸»¾ºµ·´¸¼´½¸µ´°³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|y‡}qc`bbgjgfiei]VUSYOSKE8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“’’˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´´±°µ·µºÁ¸¾¸¿¼½·µ·°®¸¶¹¿»À¿·Á¼»Ã¶ºÈ¸¶¹»½¹º¶»ÅÅʽ¹ÅÀ¿¼Á¾¸Æ½ÁÀ¼Å¸¶·´¸¶¶»»¸¶´·ºµ´¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒ€xpmedfoiekhXXNKKKRILHC9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’š”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿½¼²­¯¬±°·¼¶»¼ÀĹ···µº¹º»À½ÃÀºÄ¾Ǹ¹¸­·µ¸º´·³»ÅÆËÁ»ÆÀÀ¿½¼¿ÉÃÄžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~†|knpgpksebm_\THKJDJBCG?9;8><7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘ŽŽ˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼¼À·ª­¤®°·»³½¿»Ä·¶¸¶·¿¿Ä¼ÂÅÅÇÇÊÉÆÏÂÁ¸®µµ¼¾¸»²¾ÄÄÊÅÁÉÿ¿¾½ÇÌÇÇÄǽµµ¶Á½º»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†qelintnwcgb\cQKTHEECGC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?=??FD@A?>:7?@CC?A=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼«ª£°¹½¾³¼¾¼Å¸²¸¹½ÇÉÊÃÇÈÆÆÉÈÌÎÑÌÊĵºÀÃÈ¿¿µ¿Á¿ÆÆ¿ËÆÿÁ¼ÀÃÌÊÇÅÆÁ¹½¼Ä¿À¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtolltkln_c^aaNHM?E@?DC<;::;:8;<:9<>9:>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED<AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´¼Ã¼ºº¾¼Ä¿·½¿½ÇÌÆÇÉÆÆ¿ÄÄÊÈÌÌÍÊÆÂÃËμ¹½º¹ÀÿÈÆÄÁÁ¿ÅÀÊÉÃÃÃùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{z‡zmmw{_pc[]_^SI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA>>ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸´¼¶º½Á¼»¿¶¿Á¿¼¿ºÀËÂÇÈÀ¿¼¼¿ÅÂÇËÈÁÃÀÀÉÊÂÀ»»°´»½ÀÅÆÅÅ¿À¿ËÇÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²²¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}‚zmsxsgp][^\YQEDCMIAE=G::59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA=>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘–žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯·¶²µ³·¹¼»¶»»½ºÃ»·½·¹À»º¸¸µÅÁÂû¸³´ºÁ½¿ÇÀ¹À¼¾ÅĽ¾¹²°®¸·¿ÃÇÃĽ½¿¿Ãþ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸¸¸½¹»±¶²ÈÀ»¶´±°·¬³©°­­³·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|vluzpni\_`YSPAEHGK@DCH<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿš›œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹ÁÀ·½¹¸¹¶µ¿³´²¸±»ÁÀøÀ°¯µ¸¸¸Âº´»·»¾À»»¼®¯®³²¹ÁÂÄþ¼¿»º¸¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ¯µ´´½º¾¹º»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§¬¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰|‚zsvvwnq`_e]ZUJ<??FF=FCC9:5;99><<::<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Ã¿·º·¶¶²´À¶²´¸³ºÀÁ¾ØÀ´±´²·¾¹³µ²¼¹¼¶º¾²´´´°¸¾ÃÆÄÀ½¿¹³¯²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtvrl^b`[]OHA>=HCFMC@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·À½»¼¸¶º¶±Àº·¹¸¹»ÁÁÃÐÒ´È´´°¶ºµ´²¬¼¹¸µ¸Áº¸³±¬·¼ÁÇÿ¹ºµ®¥¬³°¦°­¨ž Ÿ¥­¶µÂ·¶´¥¨«¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´·¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wo{ournc\fX\]RNMA>IB@JI@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³²­¶º®¬¼²¸¹·»¿½¹¾À´¿»¼º¸¾Â¼ÂÉÕɗÎÄ´²´¶²´¯­»º¸¶¹Àö®®ª²¶¼½¹¶²±­­Ÿ¤§§£¦–™™šŸ©®¹¬««Ÿ¥¨¤«®®§¯¬¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmuik][jT]\OMHDFLBFMF8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹ºµ¹»µµ³µ»¼À»¾À´¿¹¹º±»Å¼ÁËÍŽ§É¹´´³°±­°¹¸¶¼¸»¿²²²®±®¹¯ª«­¬£¨¡ž—˜¡•’•—˜Ÿ¨®¤£¤ ¢§¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬«¯£££¡© ›“Ž“’’™–š¤¥ Ÿž§˜•’”˜ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wrxhtsndT`cW\QNLH@HQDMC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<;:@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯²²ºº··¸¸»´¯´¬°¯¤œ°¶·‰µº²­³°¯¬®¶¶²´µ¯ª¤ž›œœž¨¨ž ¨©Ÿ¡§–›——“–Ž—›¤¨  ¢¢¢¥¥££ ž¥ ¤¬¤¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›©¨ª«ž¥£›£œ•Œ“—•–˜Ÿžžš™¦—“’–¢ ¥£¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦ ˆxƒ|vybwln\QhTPNGOMLBOQ@>;>39:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¥¬ª¨µ²±¯½Ê²¦¨­•‹vp„ŸŒ…¡·´«²´®ª«¯°²³®¥ž’˜”˜ Ÿ¢ œ¤¥Ÿž¨”›–—Œ—‘—“˜¢ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£ž™—š«¦©±£¥¨ž œ•“‘˜–•˜–Ÿ˜›™›£™—”–š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’}|€uu}mk{dhUQcMIHGNRNJNG;E@=2?759;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜˜—–¡¨¬®¶·º¹º··»®¨ ¡©¡ ­«ª¥½Ô«¢œ€ltacerƒŠ›·µ¯¯³µª§­¬£œ™”Ž‘–—™™œ ¢¢œ¥žš¤———–’‘‘“š—› ¤ªž¡¡ž¦§ª¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¡¤¡›˜ž¯¨®²«¥ªª š˜˜˜•“–š“••™–›——˜ žœœ—›¡šžš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}vx|dxy`bRU_HIIKSTIRPL9?B67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—““œž¤¨®­¬««¯ª¯©ž—ž¥ž¥¦¤ŸÀÏ©’|w^k‘uoe_n ¾´±±°¸­§¡œš”—ššŽ‘•‘ŒŽŽ”™¢œ—£™š—˜™”™˜–›Ÿ¥¦© ¦£ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§  £±®²°´©±¯¢™œž¡™››š˜™›”–›–˜œ¥¡ š£¡š™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ Ÿž ¥¡žž¥ ¦™{|uvsh‚le[SZYMQJNNULRLA7>B68=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’’œ˜¡ª¢§ ž§¡¥Ÿœ’œ¢›Ÿ¡£ŸžÂǙxcaŠ\W‚‹ˆlR‰©Ã³­­¬°§ Ÿ¢ —‘”› œ™—’“Ÿœ¡¤›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬¨¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½·¾°¬±®­©ª´±°¨«¨²µ·³¸¬±´¤ ¥Ÿ¬¡¡¢  š˜–– ››˜¤¡ ž¤¡Ÿžšœ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚|xuiwu]lZR`HQUHFUVJBLG=KH8E<67;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“ž™¨®Ÿ§žœ¡žšš’™žœ¡¢ Ÿ§É¹ˆaZv—ZXam~Nt´Æ³§ª¬ª¥ŸŸ™’’“˜˜––•Œˆ‹Ž•ž–žš¦  ¨¥±ª§®£«­¶°´²±®¶¸½Àº­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«¯±¹·¼¯³°µÁ¼·½³³µ¢¬¢©¨²©«¨§¨š™žšª§Ÿ™¦ ŸŸ§¨¥¤žª¡¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰…„~vqmivmhm\X[BVMJGMGBFM<>L=4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜šª ±¢·¤°¦Ÿž—˜•™ž›œ£Ÿ®ÑªsYdŒ‰X[oi·­vZY º³®®©«¦ žž¡¢Ÿšœœ”“•”žž˜”…š¡›«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶ººÀĹ½»¬¯§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¹Â¾¸³»Æüü·³©³­ª³´¯³®ª®£«§¶±¬¢¯¦¡£¯±­°¤¤¯£¡ š¡§¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¥ž¦™›¢¤žŸ›››œ‡…{tqkkurphW[QETHDIOH>EA4EH95;=6;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž ¡œ˜›Ÿ › Ÿ¬Îž`_ˆ‡wx…‡užrrs”°®§¤¤¢ ž¥«¥ž—œ”‘™˜”ŒŠ†ˆ†ymˆ ¤¢«¬´¼¶Ã¾¾³»ÁÃÂÅÀ¿ÂÆÆÅÃÈÂÀÅÈÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌÌÌÒǾ¿ÀþÇÆ·ÃÉÉÂÀž¹´¹º´»·°µ²ªº±®»·¾ººª·­«ª¸º´¼®®¹£¦£ž¦¥¢£©¦™›Ÿ˜š§ª§ ¡¡¤˜”£–”™‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ„}zqkdhoxjeZ[FKLEDSLDBE7:?;549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;?>=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ³²¸§¡¡«ª¢ž¡¢žœ›ž­É˜VoŸ™y’œkzz¦²ª šœŸžš—˜—’Œ——“Ž‹‚ƒ‚wsqnp¦­®´¹Å»ÍÇË¿ÂÌÎÍÌÇÉÑÌÍÌÇÉÅÆÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÒÓÌÓÐÓÓÌÊÂÅÆÇÊÇοÈÑÌÇÅÆÄÁ»ÃÀ¾¾¾µ½³­¿¿ÂÂÆÄÇÄ®¾¸²¸¼ÄÁÁº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›Œ™‰•˜› Ÿ£—žš““‹•…€ytsebgrof^ZYCNLCEPIDC@5558:B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A?<@?>8;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›¢¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¥¨¬­ª¡£Ÿœš¦·Ì‘Ty ¤z{nfo‘©±¬¤Ÿ ›˜—”“”–‘Œ‡„ƒˆ‡ƒ€€yrroly¤¶º¹¾ËÁÓÒÓÈÍÎÑÓÑÒÑÐÑÑÍÎÎÐÅÎÔÕØÒ×ÍÆÇÉÌÃÅÊÏÊÒ×Ñ×ÒÔÖÓÓÈÌÇÍÍÉÒÌÎÓÌÅÇÉÊÁÅËÆÈÈž²³ÈÄËÊÊÎÅÊ¿¾¿½ÁÇÄÌÌÈɿÿ­¯³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›•Œ†‘‹€zruvgcgvidVWQDMF@IQB=B<:22@<D<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<@?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­´¸¬®£ž¤£Ÿ ¤ªÃΊXz†„nhq®¯¥¡¥¡žš•”–”Š}wpkebhqoq{…Š€vpnqtp…³Â¾ÅÑÐ×ÖÖÒÖÍÔÖ×ÔÓÑÓÔÔÒÏÑÃÐÓÖØÕÖÒËÉÎÑËÆÍÑÉÒÕÖÙÕ×ÓÖØÎÒÊÏÑÌÎÐÌÒÏ¿ÇÆÊÃÌÌËÎÏÅÆǶÀÊ¿ÑÌËÏÅÉÇ¿ÃÂÈÎÌÏÐÏÍÊÈθ·»¨Ÿ¥«§ž˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„|xsvpc`erb]R\IJGAEHI>;@8=4585;86:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÂű¶¨¢¥¦¡¢«µÏϏd{}on”­­œ•˜ œ›¡¢Ÿœš–Šwic`____^_`^blusqpolrqu’ÄÇÆÔÕÖ××ÓÖÏÕÔÚÔÔÎÏÕÔÔÑÑÌÐÎÓ×ÖÓÕÐÏÒÓÑÉÓÑÇÐØ×ØÑØÒ×ÙÕÖÌÏÏÉÍÑËÎÏ¿ÅÂÇÅÎÍÑÐÑÈËÌÀÊËÅÓÎËÎÈÄÉÆÆÈÌÊÓÓÑÕÏÒÌÒÁ¹Å±¥¨µ®§š¨¬¥²¨°³¬¬““ŽˆŠƒ‹„Ž™“™‚…Œ|zqstmacim_VP_JJCFCQM?<>54:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><??=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯­ªª«¦®¸¨«·×ÔÕÙÙÑÎÐÀ¼ÌÉ·¿¯§«©£¤±´Ñnjovq„©¬¡˜–˜š›¡šœž“}qecb__a`_a`_``_`fmppnkorww›ÌÀÒÕÓØØÖÙÑÒÒ×ÏÓÎËÒÍÕÔÒÊÏÌÓÖÒÑÖÍÏÕÕÑÆÑÔÊÐÔÕÖÎÒÐØØØ×ËÈÍÃÈÎÌÊË¿É¿ÇÈÍÎÏËÐÍÎËÎÎÇËÏÐÊÎÊÂÉÆÉÌÊËÑÒÌÓÑÑÏÐʽȹ°®»¸µª¶°­¨¸­³¿»±šŸ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…ˆzvopokadnpaW\ZIFFDMWE;@<33<=87855;>@=9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ¤§Ÿ¸¶µµ¬¥­®¾´°ÀØÒ×ÚÜÖÏÍËÄÓÐÂÁ±ª­®«¥²±Ä¡mln¡œ•“—œžŸŸ”–˜”‰k^^^adb```a``a^__^]bmroostvvy¤¾ËÕÑÖÔÓØÖÎÎÔËÍÎÅÎÊÒÒÏÆÎÍÍÔÌÎÓÍÊ×ÕÐÌÑÔËÌÐÑÓÊÎÑÕÒÕÕÊ¿ÊÁÅÌÂÈÉÂÌÃÅÈÊÊÎÊÍÌÐÍÓËÅÈÏÌÈÇÊÄÆÀÅÊËÍÏÑÆÐÎÍÍÌÏÅÇÀ·¹½Ãýù³²¾±»Ãĵª˜¥¢™–‘••’‹”š‘”””‚‰…xpqkmg``qhYXhVLFLIPPB;D>;67:89:57==A;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?;<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÅÃÁ¿»µ²±Ç¸ËÕÕÙÚÛØÌÍÏÈÖÕÅ÷°µ©¢­¬¸¼¡omŽšŒ—•”’‘–––Œ|ebbb`]^acb`_``aa`_][]grqqrsqmry¤ÆÓÏËÐÏÔÕÉÅÉÉÆÆ¿ÃÆÏÎÇÅÇÍÊÒÈËÎÍÆÑÒÏÎÌÔÊÇËÎÏÇÇÏÒËÐÏźľÆɽÂÇÉÎÄÁÇÀÇÍÇÃËÊËÏÇÃÄÐÈÆÁÅÇľÀÇËËËÎÂÊËÈÇÌÐÄÅÇ»ÇÃÈÈÂÏÁ½¼¿°ÁÉǹ½ª°²§¥¢œ˜›£™—™‘•˜‰‚wntdk`^fqa[W`GHHGIMTG?J=64355=<48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ½ºÍÍÆÐÕÕÙÚÛØÐÊÏÐÒÔÉĸ¼¼®¥¶ª¾º¡w‰–Ž–†ƒ„„‚~……t`\^^^`^`cdc_]]^_``_[Z\akrrookloo}¸ÑÈÉÊÏËÍĺÀû»ºº¾ÉÆÂÃÀÃÇÊÉÈÊÈÁÅÌÆÈËÍÉÄÂËÉÁÂËÐÄËÈ¿¹Á»Åǽ¿ÆÏËÿûÉÆÈ»ÈÆÄÊ¿½ÂËÆÅľż¼¿ÃÄËÅļÀÉÂÅÇÒÄÀÈ¿ÊÉÆÇÆÐÃÃÆïÄËÇÃÊ·¿¼º´©¬¤¥˜Ÿ˜¬£¡¥š£ ›”{vstfiZanmZ[XRDLFBGDLDFS@54334?<3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ËÏÑÌÇÂÃÇÍÎÎÌÕÏÕÙØÙÐÌÓÎÎÐÊöĿ´²º¯¾¶ˆ}•Œ“—†z€…†€vxurq_Z[]``bddded`\\]]_^`[YZ\borokilposÆ¼ÉÅÌÀÆ°¶º²²³²±Â¼¼¼º¸ÀÁÁž½¹½¿¹ÄÊÅƽÆÀ¸»ÄÉ¿ÂÉ»·»ºÅþ¼ÁÍÃƾ¾µÁ½Ãº¼Æ»Â¹³¼ÅĶ¿µµ½¿ºËüµºÈº¿½ËÃÁÅÂÅÈÆÈÆÐÆÂÌDzÇÉÃÎÍÁÅÃÀ½²·°²§¨¨¹°¥­°«­¬”yvwjdg`hocV^YJFJFHJAEBEI@9:648853;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÆÃÄÈÎÒËÊÊÇÍÎÏÒÉÐÆÕÔÖ×ÎÌÐÆËÇÉļȿ®°¶´·¯‚ŒŠ‹…x€††€~„|tud\\]^``bcabeeb]][\^\^]Z[]]hsqmggnpry½ÌÀúÁ¸®°°§ª­¬§¸µ·´²³´ºµ¾±·°µ¯²»Â¼Áļ¿ºµ³º¾À¸Ç¹´»¶À¼¸½ÆÁûµ®²¶º¾´Ä·»µ«¸½½¿½°º¶¯¶º²Å¼¶®»¿´¶´Å½¾ÂÅÀÃÅÆÈËÅÀÆÆ»ÈË¿ÏÊÇÃÆÂöý½¶¹¾Ç¿¬µºµ·¶Žxtxfgebkn^V^`FKHHJFBDAEE?<:565633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÎÈÆÉÎÌÐÌÎÈÊÉËÉÊÄÏÍÒÏÏÆÉÄÉľ»Ìº®²·´²«Œ†‰‰{x~††wx‚}th^]]]_`_`da^dec__\[^\]^Z[[]_lpnhfjnnr|¤Ç¿¸¸µ°«¬§ž¢ª§ž«­³­©«©´­¶°²©®¦¬²¼º¶Ã¹ºº±«µ¹»´Âº°¿±½¼»¶¼Ç¹Â¶­ª¨°±¿µ·¼¯°§²³´»¼«­µ¥®¶®º±°ª¸°­»®»¸»À¿½¹Â¿ÇÃÅÁ¼ÆÁÈ˸ÅÇÅ¿ÆÃùÄÆ»ÆÉÌ˳¹Â¼º²ˆrvvkiablhYXW[ALKMIEAC?FA:9:995854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÆÎÒËÃÆÂÅÐÇÎÂÄÆÀÅÅÃÃÊÂÉËÁ¿ž·¹¹Ç³¯´¶¯­¦‘‰‘|x~Š…z{„wo^]\]]_`^_dcbccb`_][[ZZ]ZZZZ\dnohfgiknr­¹°µ®¦¥§§š ¤ šœ¥«®£§¢«ª¬ª°¤¦Ÿª­µ¶±½¹¯·¯¨®·´´¼¸´¼¯¸¹´±¼Á±À®¥¨¢«±²³§¼ª«¨«¬­´³¥¨­¡¤®©²¥§¨­¥¨·¬°²·ºº»±»½¾¾Ä¿µÁÀÇÈ·¿ÀÄ·Ä¿»¿Ä¾ÄÈÌÊ¿¾ÃÀÀ©†rtrji]aodWVXPHYRSKFFE>>@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÑÐÍÄȺºÌÂÌ¿¼Ê·¾Ä¿»Ë¸ÂÄ÷ºÀºµ³¹Âµ±²³§©“ƒ‰|~€~xt|swf_]\]^_`^_ccab``_]]\ZXZ[[YXZ\_fkfegehkor…ª¥¬¦ œ¡¥”¤›˜’¡£ª£¢Ÿ¥¥§¥¬Ÿ›¤¦¬²¯¶·§°¬§ª´ª´º±¶µ­¶¹±¯º¹±·¤Ÿ¤Ÿ¦±§«¨¹ª¤§¨¨§²­ §¦Ÿ›¤¥¬žŸ§¤Ÿ ±­­¬²´²´°µ¼¶»ÁÁ²º¾ÃÁ²¹¹Â³À½¿µ¸»½¾¼ÂÇÄÂÿ¿Ä ƒwpkaf_ko`TY^HNgOTGEJF<=?=:;;825536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;=:7676788666;::;9:;<859<:>>@;Èµµ½¸ºÀº½µ ž”¡¦º¶«³³»³ÄÐÉËÃǹ¸ÉÂÍÀ¹Ë¸¼Æ¹µÆ¹µÀðºÁ·²«´»¶ª¬®¥›„‡‡}zutomkjjqi^`]\\\^`_acb````]\[\\XYXXXVX[^_dcbegggjmoˆ© —•š¡–›¢˜–ž¡¢¦›ŸŸ£¥¡§ž›¢›Ÿª°­±µ¢©ª©««¤´¹­·°¬²µ®²µ®°ªŸž£¢²¤¦©¸­¢¦¦Ÿ¨¬ª™Ÿ ž™Ÿ¥šš£œ›¯©«§ª«¬­°²¸¯¸¹»°¶»»º«³³¹³½´¶±±µ´¿¶½À½ÃÁº»½—ƒzrk_e^ddXTW]IW\KPGIIFA<??@;?<04535:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»·ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÆÐÈÈÁǼ¼ÅÄÏ¿ºÈ¹¹À¹´Ã¶²½¾°¾¿¸¨¤°´±¡¨©žˆ†‡€xsnpnkb^bff]]^]]]\]_`abccba_\[[ZZYXXWWWXXXZ^bddeffhikr¨”””›˜›¡––‘œ¡¢¨›¥¦¡¥œ  š˜­®­®² ¥¢­«¦¡´°±±¬¨¯²§º³¦¶¡¢ž›£¡­£¡©µª¢£¦¥¦£–˜ž—™šŸš—œœ¬¡«¦£¤¦­«³³ª´°²ª²¹´¯©¯²²³·³®©¬®²¸°º¶¹½¿·²±”…yue^e^[YVSZUK\QLIEHKIB=?AA@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½·½¿¶¾¼¿³¥£˜¥±Âµ¶½­´¸ÂÍÈÇÀÆ·ÁÀÈϸž´»»´À¸´»½±·ºµ¥¡¬³ª §¤”|„„€yprtqifdhec\\[[]]\[^`a^__`^\[Z\ZYXVWWVXXXXVWadecdeddhjv¢œ”””–—Ÿ—™”˜Ÿž¡œ–¡¡¨£Ÿž©œššª¦¯°«›££·ª Ÿ®¨¶©¦§­°£·°¤·Ÿ¢›˜˜ª¦¡š¬¸°¢¡¤œ¢  “•¡”•–›˜—–—œ•Ÿ©©£¡£ªª°®¨´«ª¦­²°¥ª®²±°°®¯¦§§²®±´¯¼´º·®£”yud^aVYWSRTKM^LPKGGLLE<@><B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾¸¼®§§£ª»À½À¹®´¸ÂÍÉÆÃľƸÉ̳Âï½½·½¾·»¼µµ·±¢¡ª³žž–›†€|xrjmrtpihedfb\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWWV[ccbbcbcdfj–“•‹‘”“›™œ––› œŸ• Ÿ¦¥¤¦§žœŸ¥Ÿª¯¦Ÿ¢£¶¨ ¡¢¨´¡¥§¤¯¥°­¬µž •”©¡¢”¬±±ž¢£˜›“‹¡”‘“—˜’——˜–¦›¦¡¢™£¥¥«¤¥°§¥£««­¦¨®¯®«¨ª©³¥¦«¯´±®¼µ±¯¯ ’zvrda\Z]XNLRHRaMWPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8846863321./2556;:8;7876<;:;;A8x»»±µ½°»±·¬ž¤§­·»¼Áź±¹µÅÊËÁÄÇÇÈ·ÆÅ´ÃÀǬ¸¹¿¸¿½¾¹¸²´¯  ª­––‘‡undbgihfhjgjm`]\[ZZZZ\]\[\^_\ZY[YYY[WUXWTTWVSTRU``_`a_`acdi““ˆŽ”’“œ”•–£™ –œ ¥¡­¥¤£¢£¡›ª«¥™ž¥±©  ¥«ž§¡ž¬­©¨®­¢¡¢”—£›œª¨°›Ÿ¢Ÿž—™“Šž‘’“•˜˜“›¡¢œ¤ ¡• ¡¤¦›£«¥¢¤ª¤«®¥­²©¦¥¦¦´¦©¨­³µ´¹º¯ª¬ž‹rpo`[WVVRGQOHZ\ORITKSLEGIC8;;=<8667:9;:976977:;:=<<6;<8>598:88659:<<97?<9678452121..1426:86:8698989;9@9{µ´­´»²¯«±­§§¯¹¹³ÀȺµÀ¯ÆÉÍ»ÂËÌȶʾ²¿ÅÊ®³ºÄ¸¾Ã¿¹¹°´¯ž£¨§”Ž}‹„|uiiilgjlmkjme]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURSOQY]\]]^^__bdmŽ„‘‡‘Ž™“”’œš¢œ› §¨ª¨ª¦¨¥£˜¤®¤”™¥¯©Ÿ›™› ž¯™›ª³Ÿ¥¦Ÿ££¡”“›––’¨©¬šœŸ¡ š”Œ™ŽŒŒ’–•ž¡ £œ›¢•› ¢ ˜¢¨£¢¨« «¯¤®·¥£¤¢¬­ª¨«®²·²½µ³«¯˜„ssh[XXRUREXLQ[YMUNPLPQINIB<??A?<65799<<987:79:;<=>;7;;:=67:;8976989:6:=99577571141-+/434988::8::748=8?9~³®¨³¶®©§¯­›©¨¬·¶¬¼Ê»¶¿¬ÌÇƹÂÏÏǴż¸¼Äʲ®ºÂ¹¿Á¿¸»¬²©Ÿ¢¦¢”Š}wxonhmnmphgigd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUTSNPQYZZZ]\\^_`d~‹ŒŠ’—‘—™¢ ›Ÿª©¦®ª§¯£§™Ÿ¬ •–¤¨§—šž®–—§ª™Ÿœ”¥¡ž’“’“•§ª¤š™™–ŒŒ”†‰ƒ‹’•‘ ž £—•Ÿ•š ¢“›¥¥§¨¨ ±°¦±¼§ £¬´«®§°´°¹µÀ±­±«‘}qrbVTVNRIGVQRRLLXMJLNRGMKACFDC>@75889;9:7::7<=:;@>:9;9:?759:9876958779;85576661320-*.102877;99;8948;8@8³­¦±·ª¦¢°«ª§©²±¤¶Æ´¹º³Ëƺ»ÂËÐʲ¸¹½¿Âų²´º¯··¿¸»ª¬§ª¦¦¡’kgmnrnqjpkdfge^ZYZYZZZ[ZZZ\\]\ZXXXYYWXWUUTRSUSVURNNNRWXYYYY\\]aj€zv‰‡Š—‰””—›™¨šŸ©¥¤ª§˜ ¥›’ž¢š—–…„’š£“¢œ•–•‡¢šš“‹Ž‹š£¦›••—›’‡”ŽŒ‹€Š’’’¡šŸ¢•”˜˜•¢¥™Œ˜¤¦¨¦¡Ÿ´²¨²·¡¢·¬ª­¤²²¦µ»µ««±£‰xrm]NQQLOCMNNPKFNNJJNMQIMJAGLHGC=858889:;69:68;99><8:>9;?8789:886857688974577820301+)-/12776:999984988A7w¶§¤¶°¤§£©¥ ©¥¤³ª¢²Ãµµ²³ÇƸ»ÄÊÍÆ´­»¾¶¹Á±¯«³Ÿ©±¾´µ§£¥¬¦¦•Š—v_`gsqvqiniehhj_XXXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQMMKLSWWVXXYX[]aosvq…ˆ‚ˆ€‘„ŽŠ”‘“ š›¢¡£˜¤–¡›•‡˜šŒs‚}—–…™“ŽŽ{™ŽœŒ‚Š€‰˜Ÿ¢ž“˜–„Ž‚“~~t‰Žz‡“š™š•Ž¢£Ž‰š ¡££›¢´¯¬¯¬Ÿ™¥¸¦¦°¡°®œ°»ª©¯ª™‚vrbUMROPMCSNLQMBPQHINSMHJJCJLFKK<749888;;69;7:<9::;79?9>@79:<89764445874312585/0102)(,-11764789::65:87A7x·¢£´¨¥¦¨£¦¥¦¦¦³§¥´Á¸¯´°ÊŸºÁÏƾ³­»Â­¯Å¯ª¤©“ ©º²ª¨™ ¥¤¡Œ‡’lWW_hgighncjigb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTQMMJHNSSSTUUWY[]ilrm…|tNXr‚—†œ—‹“Ÿ—•”–”Ž–‰“‰_;Wo{‹”‰€‹’Œ…†sŠ„–y‚z…””ƒ–Žƒ†}’xro…~‰‘—™˜“Š‰œ‡ž—‡ˆ–žš¡ —§¯©­¨¨ž—­³¢¦­˜¬«˜§´¢©­£“~rm_[NSRVLDTJPMLFNOIFLQMKOJIMPFII<7599999:7:;:>>8:==6:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9y· £­¡¦¦ª §©§¢©°¨§´Á¹°µ°Èø´¾ÏÀ¹¯¯¶Ã¨¬Ç«¥Ÿš„—žµ¨¡ Ÿœ˜ŒƒˆcQMRVZZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MORMKHFHNQQMPRTVXZ`mpi{‚tPBA•‘‘}‰”Œ„Šš••Š’ˆ…•†xˆ`JQnxŠ‘„}„‰…n~”wuuw„™pQˆŠ‡|~x“vhw†ˆ~Šˆ•Š‘–‹„Šˆ”„šŒ„’›–žœ”¤£¨©¥¤ž›°ª¡¤¤¥ª–¡©œ¢¦¨‰ule^[HQQRMIUMSILKOIHGKNLMTKQQOFIC<769:8:;;8:;8>?99>=8;<6;;478;6775344696/3/.125221/,')+*,4833979:99::::?9w¶›¢§Ÿ¡®¡§¨¥§¨¯­ª¶¼¶¸·³Â¼·¨ºÉ¹¶¨©¶·«³¾¨ ˜Œ–¬›œ’†™’Œ‡€€_MLNNOLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDDINOhYNQSTUZnƒtw~ji]U‰”‰t‡|…Œ’’™‹{†€uxsnupty}Šª…yzhv{Žprmx‹Œ’xz€{€vsr’wgu„„„„{•‰ˆŠŒŠ€„‹Œ”ƒ{€˜•œ•‘Ÿ©žŸ  ©¥Ÿ˜Œ§¤“ Ÿ–žž¤€rg`\\JVORGKXROJMMRJJJMPHLQLRTLEHA<77;99>=:;<98@?::>=7==79937795675252572/2.,//200/-+(().1272198798775:<;7v®˜£¡˜œŸ´©¯©¥­¬°±ª½´²»¸¶»µ² ·»³«ž­ªª´°£œ“–ƒŸ’˜†~’„Šƒ~~x`KIIHGFHHPTTTWWSTUUUVWWWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQQSV^uƒ}ygw—˜Ž}gyvx€‰|„˜’r‡|v{ok~­|sŠ{†’}tfv|†lohs|‰Œ‡€lyq}pmuqiq€~ŽpC‹„‚ƒ…wwz‹…}‹zu~Ž’˜Š’š›£–™šž¢–Š¥›ž—Ž–˜vnlebZWWTQJSUTOPNQVKNKNOJQNHNOKEC<;79;::?=9<:99??;8<=7<9999266856633621224.,,-..-0-+*''*.1362/876966527995y¦— Ÿ– ¦¯¬®«¨©°¯±«¼¸¬»¾¹³­¨›±§­œ–¦ª¥¢™›‘†“{‹’‘|w†v€|xyx`KFGFA@CDILLMQRPQSUTTUVWWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNPQTX]eprmˆ§ªÀ~uyb{xn|yˆy|‹…omŒ‘xsxjj€‚r–‘‹}–€I“˜nhw~‚licly…’†ksl|nr{†imps‰„†z}~{vots…‚ywp|ŽŒŠ”ƒ–—˜š“•–™—ž—Œƒ‰Ÿ‘‹’†–~mhmnnWUWTRQYORUUSXUMNHNJMNKCHNGE?:89;99:><9<;::=>:8:;9?868727575541442/024*+**-.+-*(*(',-1250,5567485HA895w™‘›™šž¥­°¢¬ª¨µ¯®¬´¿«¼Â¿¦¢š•¥˜žŽ…Œ–¢¢™™’•t{‚ˆŽ‹yu{qztptvaOEGD@<>>AFFGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_IMOORWZRY\`§ˆbšitze~pmz‹‰vˆ†tlš‘ts{jkMy…’‰„Žg1v†sl~~ƒtfet~„„…€filukq|gqq{n“{s}|qpnum‚~wytiy‰‚ˆ‰ƒ–“’‹‘””—Ž€yˆ—ˆ†Š†€‡vjjngdWQZWYY[MPUVYYNIHEJJHGBAFDCG=998;9:9<:9;:::@<9:<98>787715244533645031.**+),,++)(+'),,226,+5775478iO8;5n’ˆš‘™–¤¨®ž²Ÿ¦º®«²°Â±»ÃǛ–•™‹†z…‘™•Ž‘‘ˆrˆƒv‰ŽŠ}tusutlvneUFID?<;9:?@ADDEGJLOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOOQVLAIQIb¯³ q|xm}lrƒ…z„††yr •tx€su”‡5q¨Ž¡¡„¢…vp†|‡|sŒ­‰€hfbinrmp‚uioXupŽš’wl{}mqmp€zsvmbv„†€…‘Š‹Š’‹‘Œ‹ƒux‹€~ƒ€~zqpok`[\][YX`_SN[ZYXLHJEJG?CABG>CD=;97=;:;;9:99;:?<88=:8;66651121353475531./,,+)*))***)(*)+/3DM2166643<vR7=7b’’‡–‘ž¤§ž¯•¥µ©­±®Á²»ÁƗŒ”‰}n‚‘’‰„‹ˆ‡vƒ…m–‰‹~xyzpzr{im^JPG>@7448;;<=>@BEILLLMNPQRUUVWXYXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL7CMRSDJ†v€||v~mwˆˆ|}…ƒŒ~v¢™y~†…™„›œa†ªŸŠ‚Žzwˆ~‰ˆŽsŠ—ƒ{\dqtz{wŠlgjbyo…‚znwt„zptywkni]w‡}‡|ˆ‡€‹“—ƒ…†}q„„|uw{}‰uorseg_[Z]S[f^WQUY\VGJJDKG?F@DC>AA=:97<;;=<::99;;=>79>9986754244004645654-,)+('''&(())((+++/00Uq<23331E~W4=9\xŠ”Œ’Ÿ¦‘ « ±¨¯À±ºÅº–Ž‘”ˆz…vk€Œ’ƒ~‹„yƒt¢…Œ~~‚€r‚€|kxkSWL@E211267688:<?BEGFGJKMOPQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMORLKT]YRJi„ˆ{‰y|q|Œz|‰†~—‡v¡™ˆ‡’”¥¬©H†®¯¯‹€“Š‚‹„‘¨‡€˜˜Šœsl|†‡}Žhghx~n…†‚…q„…Gk€wryvhmk_v}ƒˆˆ…Œz•žœŠ‹ˆ‘{u‹v|wmow~rrqk[]\[ccXge\UPPWYPDLKFNICFCCA@CA=978:::;;:888::?>6;>7585773344236656768;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|~Š…ˆ‘–—’—¡¬¡¦¸¯³½³—’‹˜‹}tp‰“}Œƒ“•}†~†¥ˆ‰€ƒˆ†yˆ‹u†x_cVKB60./23123668:=??BEGHJLNQSTUTTVUSQOGC?80,#‡[>?94.]–ps£UFIKMNPW`YpZ\^j“‡•„‚…‘“~…‰‘š•‚¡¡—•›š¥­“š»±§»Ç苌¡¥”‰{rƒŸ‘œ~v……Š‡ihoƒ€tŒ†„‹q†‚w‡€{v…}nvug€”†‰ˆ‡ˆ‡¡«¢–‰Ž˜{‚‰zzogkx~x}qjc]ZZ]i\af_ZOLNXRQIPKDNGCKDCADCA<:87=<:<:88778:==8<=68656623445576867<BB?<8:>CQ^e\G2'&,,--.1(?Œ[.310Oƒ_4?;nupgxƒ{€Œ€‹šš¤œ¡¬¦«¯°—‘‘„¡”„xwŒ”}’†“–Š€’›Ž„‚Œ‹‚ŠŽ„€Šlpj]CA4--//./02234779;=?BDHJOQRSRSTTRPOHDB<87/9D><<63.l“—MPHIKKKNV`cggmu›š““‹Žšˆ“‹  ’£ª¥£¬“¨¶¢¨Áîǯxº”š|Œ¡ž˜„’…‚¡Ÿ“˜’„Š…˜‘–lpu‰‹•Œv„ql…Š–’ƒ…ˆr‰¡–†“Š–¥µ©›•¢ƒ‡“„~kjk|€r`\c^Yfj\lk^XKHOSQNMLFIPDDNFBCEGB>997=<:;:987767;:6=:785456345566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<unhYpƒpu‡qv’†~—–š”ŸŸœ§ ª–“˜žge¤š~„’’z€‘‰‘’}Š…™’‘ƒ€€‹‰†‘‡…ˆ…xxgMR>/..,/.-/000212457;?CFNPRTPQRSQNPIED>;<:CF?><752<?R5HHHLLMNR^oŠ|s} ›¨¦¢™¡—¢•œŸ¨ž©«Ÿ¨¬©ªµ—«¿«¶ÈÈ·ÉÑϾ› pi«©Ÿ„“’…œ¡šš™§‘‘ˆ•¢ššwz~”—‘¡’–—”ž{v•’«³‰— }”žœŽ“–™¤¢¦¶°‘™¨ˆ—Žˆlss|~zog_[`^afc`gg\REKKPOIJLFFMCHLFFCBGD@:85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Pqu`n}bwŽ}|”ŽŽŠŸ’—ž–œª˜žªBD}‡‰‡˜x‚‹Ž{Š†Ž‚ƒ€‰ŒŠ…“…ƒ†ˆ€‡w_bP460-1/,.00./..0015>AAMQRSPRSUSNSLEE@<>=GGAA@8662<9;FHGIIMOQYm†w•‹£§ªµ½¸¥®¬¬§¨´¬±·²²­»±³¾œ³Ä¬»É˸Ŀ¸¥£°²¬­ª£‹–˜…¦¦ ¢—‚¦™¢ª¨¤‡…“£  ª ¤©Žœ±‹•£§·»› £°“££ž‘¤¢«¯­³µ¢•¥«‰šŠ“Š•z{~„}f_g[da]cc^ff_[ODJHTOFHLFKHEFHAKFCFFA:87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLicXjpXz…v”…ˆ‚›ƒ’’Úȝ–sV—ˆˆœ|†Œ‹Šzˆ‚‡‘Žƒ…€‹……ˆ’†‚„‰†‡‡‡qna@E64<2/110-,+-1/-4?DAMUQRTUUWUM[PGGD<>>FHCD@7;<5C;=FKIGHROPW“ „®£³ª²ÁÈÄ«³Å¶¬³À³¸¾¶¿´Á¶»»¤¸Æ©¶ÉǶ¾¹´¨£´­±±›™’šŸˆ§¯ª¤”vŸ¤—¡«±³˜–©­¨®µ»²º¬¯µ¢±¬±µ¼·µ®µ §§£¨›©°­²º¸¸§œ·©¥’“ †y‚tX`cUeaab_`f_[TJDELVQIJJDJHEA@@KDAMF<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AEWQJL[ZQcdWzuq‚”}…†“v†~€{¿»£¼‚´”“›„ˆ“‰‰y‡€Œ“Œ‡…Ž‰†…ˆ…Š‡‘zyn]V@EN<6:46AB764//6CHCQ[OQUWU\WO_UIKJA@?GKFEC;>@7D7?BJJEGWTP^¥­£±´Ã¶¸ÁÌʶ»Ä½³´Á·¸Âµ¿°·t±´¦ºÅ¤°Æ¹±³±´¨¤µ¶ª± ¢–›¢‘¥±­¥­«§¤˜ ¬³º¢¨²¹µ»¾Ì¿ÅŽ½³Â·º¸¿·º·¹­­±¦±ª­¾°½»Â¬™»¨•­˜˜ª‰~{iVa`WididV[cYVTIHGLQGDIJAHD>?BBK@@LC99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FQLALRWTZVZwjp„Ž…nzsxˆb¸¡š£‰•”–“”“—’‡‡{‡•Š€„Šz|‹‡†}Š‚‹„•}xzueO\dGEL:Qda[^SF>;HPDZdQQYXZgZT`aMSOEA?IJHEFA@C=E6B>HGKMSZT^”¯¸µº¹ÉÀ»½ÊÌ»½À»·µ¼»·¾µº²Æ`u²¥±šž«¾ª¥¨«ª¤¢²µ¡«§ž•–ž˜Ÿ®¥§¦¥Ÿ¤“¢§°³¨²²¼¶Á½ÓÉÉÓÆÂÅÌÂÊÃÀ¾½¿»¼·´°¹··ÃºÆ¾ÃÉ°žºª¢¬¥¨¶‰}q^a`\Va^geRXaVRVIEFMK@>HD=KB=B@=F=;H@796379>489:57045/26389374526?8@>GKRTTRPOQRQJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKE@IMPRLQ]gmlq…slsrsˆÕÀµ™ •™š‘Ž—‘––Ž†‡}‡ƒ–‹ƒƒx{‹„‡{‹yŠ‚—t}zlepvY]\Peeb`ed][XW\MdmURmn_o_XgeUYTJDAKKHFHHHHBI9D?HKTTV]Z\“¹À¹½·ÆÁ»¹ÊË»·º¶¸¹³¸µµ®¶¶™du©ž­p^¢­œ˜¡¢›¤ž«¥”ŸŸ”–˜—¨Ÿ¥Ÿžš™ƒ¤¬¤ª°­·°¼¸ÔÐÎÖÏÉÌÒÌÏÎÊÇÀ¿ÂʽÁ½ÂÀÅÄÆÊ¿ÉÏ´¤»±µ°›¬¹½š~xj\_[X]`YbbQ[`SQKCBEFE<@F>BIB@D=:E>=J?47535;=468977022/24169775555D3ELM>510006:477@IOJ;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODR\Yi`o—’‘”nlotu‡³¬¡¡Ÿ‹™œ™•‘›’…ŠŠˆ‡ŒŒ‰|ƒs{Šƒ…|Št‚Š†•s{ylmu|iseilifjji`fihmZmt—­¤¼‡‡g[oh]ZYTHJNPJKQLTQHLAJGKP__bgjb—·Ç°¹³»¾¶±ÄǶ°¹±°»¬³±§«·¬¶§žœ§šN›žŽ –‘§˜¥•Š““ˆ‘‰‘‘›¡˜›•–‡ž™¦š¬¯¨¯§³³ÓÔÔÖÑËÏÓÔÎÓÏÌÆÃÊпÊÉËÉÒÈÍÍÃÑÒ¸¯Ä¼Äº¦·»Ä¢€mb[[\W_WYeYP\WNQCBIECI;AD>AH??A7;D>@I=46655;:687654/10146278875367C5B8?-0,1349=97,.,1;FL=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYSfWs™ƒhqoyyƒ ªž¦—››˜‹•‘šŽ}‰Œ…ŽŠŠ‹ˆ|„‚p‡†{‡rƒ’‹~qyulpxr{nxsli€pmcimpyiw}~Ë¿Âߧmcxod[a`JPRUNY^P]]NPNTQUT\nnwƒr–®¸¬´¨°¶«­½Á±«µ¦¥¸§¬®¡¬´¤±®›˜˜Œ‘”‘„›§‘œ‰ƒ‹„Š‰„Šƒ“•˜—”›‘›˜™™žž«¬¤§¡¬¬ÎÒÕÑÍÌÒÓÓÐÔÑÎÈÃÔÑÈÎÒÓÓÖÍÒÑÅÒÖÆÁÏÈÈ鿸Нxld\a\U^Q]ZOOTPNH>AGBCF<AB?FE>@?:===<JA45465<888664412/03526768533;=<E=@11+/249?5901022-2EO3)/3.32=N248C}_2A†tD:==I>@CFH<VRMO[u‡†‹wmwp}~€¡žž¡‹™““ŒŒ“–…y…Ž‹Šˆ‘‡‚{r~€‚‡z…v…“‘‰€pwsls||w|s‚xqk€rrioqzys{¾Ëš~Œ±ƒvr…whaj]CZZ[WfdXekTX]\`c]cx{‹™ª¤¤¢ ¡¨§ª±¹«¦´£¢­¢£®¢§±Ÿ‰¦›•“‘Š’Žˆ‚”‰k•¢™„†~‘ƒƒ“—­‹••™Ž…’—§°¢  ¤¤¨ÇÍÏÇÁËÐÓÑÔÒÎÓÍÆÖÓÍÔØÖÖØÕ×ÕÉÔÚÍÊØÖÑÊ­ÄÃ̊qmb_^WRXR[PJGJIJ@;:;ECD<CD>HC?CB;;9<9GC46544<5687543250/2546745544<>=E?A62/-16;=081/254/-.;R017/532ED28>nb5=tM99@I<AD?A;PLFKYp€u~isyr‚‰•ž”…‹–‰ŽŠˆŽˆ€xƒ”™‹ˆˆ‹‰~ƒxs{}„‡w€{‡‘—„oxpmuvx}t†|yl‡vun}v„uy{µŒ<AŠÆ¥~|jeWICecfchjdoy[_fhknin€„ˆ‘ŒžŸ ž‘—˜Ÿ¤¤¦²¤¥³ ¢¥ž¡© ¢±œ‡Ÿ’’“‘‹Ž‹†ƒ„~œœŒ‚„…z”~‚ª•£Œ’Š˜’‹}—Šš‘«³˜š›§œ§½ÃŹ¶ÅÍÑÐÑÏËÒËÉÔÏÑÕÚ××ØÔÙØÍØÛÎÉÚÚÒÖ¿Ì͵vumc\XRUPYUFFJIEE=:7:@AB:GE@EDBDA;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?1*(.BT29254/7K75<`bA<svV87AH:?C><9QECJTlnopbqqs†|—‘‹~‡’‚‰†…Šƒˆ}y…——‰ƒ‡†‡z„yqz{„†vz†ŽzŒp}opzr{€q„‡€nŽzuw}|‚u|‡‰°tYªÂ·’pnc=^hrpqpnxw‚eioruxr{‹‡Ž“’›– –ˆŒ“› ›ŸªŸ¡­œ¢ššŸ¦ŸŸ¬™ŒšŒ‘“Ž…}ˆ‡ƒ…‹Ž ™“ˆƒ‡~m™y„™†ˆ“ŒŽ•Œ†{›ˆ“®ª”•—ž˜¦®µ¼¨­½ÆËÈÉËËÏÈÃÑÊÔÖØ×Ø×ÕÛ×ÓÚÛÖÐÚÚÑÖÈÕ̔wygfZYORS]HBEII>A>=8:=?;>H=@BAADA>?:87DB755479.566435532323647553457EBDCEB56<FNSM[nfcnsk`V>,4LG865433BF4=W_hLux^8;?F<<B<:9D?CGRk_mdbfkv€ˆq‘›€y€Ž~ƒ‚‚…„|}„˜Ž‡‹~†‡€w‚yn{{‡‚tz’ž¡vvƒtu}t€„o‚‚o’„u|…zv‡|‰¸Æ¥Ãʸ‚–œxpeNec‚zw†¢‹yyw{„|„vm”–”•˜‘ƒ‰—š——¦œ˜ —Ÿ“’—£™«–‘‘‹Ž’ƒŒ…‰ˆ†‘žœ™‰…‹…—{ˆ‰Ÿ—‰ŽŠ‹‚|¡ˆ‹¼¡˜“—™œ¨¦¥­ž§µ¾À¿¸ÇÉÍÎÅÍÊÑÖÕÔÙÕ×ÛÔ×ÙÚÛ×ÛÚÙØÎÛDžywegc^RVVUMKDND;==<9:<>9>A7>?@=@><9867CA6455=80665547745613854564557HH=DJE7925;H>;::7HP\ZRUXK9T>;95327I8=NYMHxxd5=>C=<@:6:>>@EQ_Yfa][htzyl‰’wvzŠ|~€€}…{~‚‘Š…†z…ˆ{u}um}}†~t’ž‘Ÿƒ’|†}x~y‹Šoƒ›€t™†}‚Š…|~‘{©ŽÃ ½Œœ¤œ~Š„}‰rŒ‹s¦šœ™”…{‘‰„iGq¡¤Œ‹’…ˆ‹‘“•›“”‘—Œ•Ÿ”¡”’ŽŽŒ~Ž‹„ˆ’–šŸŸ‰Œ”‘‚Œ¦™ˆ…Žƒ†„€¤†Š‹¸˜‘”–¢§ £®¶º´«¿ÅÊÐÈÇÌÏÓÒÒØÒÕ×À×ØÙÛØÚÚÙÙ×Û·wwviicU^ZSONHDLB==>99;:99<=6@>>==9:;;37D@8378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWN<MTHN?96333>C;[X>5YypZ<<A<=>8589?=DRSRX^UXfmmmiŽŠqsxŠ{{}€|ˆ{}{‹‡ƒ~u„†ysztm~„}w†›¡›ž”’€Œ‡˜‡€œ’nˆ©…z ‹|‘ƒ‰„œ~š‘‰£¢Ÿ¤¯ ‹‘‹†‹’†Wr­‹Ÿ¬œ„˜œŽ\ƒ¢‘‚Ÿ“•Œ‡ˆŒ’“Œ”••ŒŠˆ–›•–‘‹“”†€‹‰’ŠŠ—™£¢†“• ŠŠˆŽœƒˆ€ƒ‡…¤…‹³˜œ’”—¡¡ž™’›§±¸¬¤¼ÁÇÍÇÆÏÌÏÌÏ×ÏÑÔ®ÖÕØÚÙÚÚ×ÖÙٞn{see[[VRUWC@ID??>:49:;7:;:3<<?=>7;9:1:G=:27=@50677255?65;55858:57735HR7GOK994=EJB>1FCLA98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:<@;BQKKSYPTcbxlb~’ƒomw‹xz{}†|{v†…€sp…‚{vwvt„ƒ…}’¦¢Ÿ¦¢—Š”—ŠŠ§—rŠ²„§’„™”…šŒ£– ˜“‰›ž¢“©° ‘•ŽŽˆ•‹n·„šÄȲ¢¥›˜–‘²d¤ÍȕŽ†‡‰’Ž“”Š…ŠŠ†–š›”“‡•˜„‹™ˆŽª——¤£ˆ™ž–š‰†—˜Š…‚†¥ˆ“©š—“—™¡˜Ÿ™“œš¢²´¥£¼Á¾ÇÅÅÉÈÉÂÊÓÌÍÔ¨ÒÑÖÖÖØÚÔÓÚ΁q}fa\\]NITYABGD;A>837;<:8=64::<:72?9929I:>67BC32:96264>=4;>6949;57944KQ<JQK9A7BGI@64JELF>;88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBc‚Gv}|m~ˆxz~{‚‚ƒvv€ƒ|mn‹z|xx|„‡Š~‹£³§£ª³¢—§Ÿ¥¤–•®¢ƒ‘¸•‘³š¡¡Œ¥›°£¤˜‘§–¨™¬¯¤˜•–•‹˜™—¡ÀŽ£É¹«œ£¦­™’›²……¨¢œ˜…‰‰Ž•‹“ˆ†‡‰“˜•Œ‹”“†•˜†„‘œu‘˜²–—¤¡ˆš“ŠŠ—›‰‹–Ž‡}Œ˜ž‰œš™“˜˜Ÿ” ”ž› ±®¢¤·¾´ÅÇĽÃÿÆÍÊÉÒ¦ÎÍÓÒÑÖØÓÐغqxt[_T_UOHJNDBCE5>:77:?<<7=43669774=5;5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=88567=:JFDGN[\YJf`;H„‹zzn…†z|„y†~px|~}orz~‚|x†‹‰†„’§»¬¨²½¯¥­³³¨£¡°¬Ššµ¢¸¥•­¤—©­¸§¥£Ÿš©—©£¯°ªš™œ”•‘— ˜š»»®Ê¡j¶¸«°”™Ÿ£¬“—½£^ª²ƒŠŠ”‡|ŽŽ}ƒ†Ž”•ˆˆ“–Œ–‹—˜“™´—•«‹œ”’Ž‘’Œ™›Š’ž‹‰•Ÿ¡”˜š’œ˜ž”¡ ”œ¥¯¨¡¥³¸«ÂÈĵº½»ÅÇÇÂÑ ÆÉÍÍÅ×ÖÑËÔ¡oyg[YR]POEC><CAB8?885?G=<6<35345454B39:BM:B;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPdGb`bpJ?‹Šs†‡}‚‰uƒŠ‚m|}}pw‡wŽ‚‡{Œ†Œ™ªÂÀ¯½Æ»³´À¼´­«³¶Œ¨³­­½«›»¤¨­¹¸«§¦¢¢¤¢©¯²±«œ¤˜›˜—ž¢¦¥’¤º¯©À¼­­²¹¥¥¨~ˆ†œ­¼°ƒŒŒ‹ƒŽƒ‘z‡œ‰ˆ—‹•–”‘š—¨š±š‘¬œŽš’Ž•–—Ž‘ ‘‰”›¤¬”–”œ“¡›˜ ¡”šž§¦¤¢¤°³§ÁÆï°º¶ÅÄ¿ͦÇÄÇüÕÑÍÅʇrq`ZX^ZLJBK@FG>A?B;:5>A==5<6>333242A17@BN>G@CNCA=C=;86CC5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GD?CF\eG`igZ]\“ŒŒˆ{‡Œ‡ƒŒu†‘Šo~{q~{•z’””˜“•§³ÆÉ¿ÂÌÂùǼ»¯«¹»˜³·º²À®¥Á¤«°¼½«®«££ž§«®´°ªœ ªœ¡›–Ÿ°µ§‹£º»¶Á¼¬©œ²¥¤©”…Ž©Ä䂋‡ˆ„†•”z„‘‘¢ŒŒ”‘Ž‰—Ÿ˜“™•˜¦ ®ŒªœŽ–’‘•••‘¡”†—Ÿ ²ž”š”Ÿ ˜¤Ÿš › ”˜ž¥£¦¦¤¯®¥ÀÄ¶Éþ¶Ï²Ä¿Ä¼³ÑÉȵswk[VZhQLHCLKKJAA=CD<5AD;;3=8B332262A05IEN>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBeYNe\fTcj™—ŠŒˆ“†‰y‡”r€|x‡‚‚zŽ¡–¨šš˜º¾ÇÈÉÁÒÉÊÂͽ³­¼¾¨º¿½»Ã·¬Â©¬³¼¾ª°ª¤¥¤¬®³­¶µ Ÿ¯Ÿ¥¢˜£³½©›¨½Á¤¶·°¬“±­¬­—‡š©§¥‘‚Œ“¥•‰vŠ‘z…’žŸ“”‹”£™–œ””£žªŸ‘¥šŒ•–ˆ|•’’£š•Ÿ¡œµ¥ž—¥£¢¥ž¦˜ž–—›¤£©§¢²¬¨¼Àį¥²·ÌÀ¹¯Ä³»¾Â¸­ÂÃÂÀ˜kx`WVZZJKMJFDDHCBADL:4DH9;4<7E.12352B25SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQG7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>jH_XaZddVžŽ—Žž’‰ŠŠ “„x…•ˆŠ€–¡™®¦¤˜Â½ÇÃÇÅÓÍÎÍ˼·°¹¼´½Ë¼ÃÁ¶·¼­³Àº¼®¯¨ ©¨¶­®©²·›ž­¢§¡ž«·¸ª¥°¿Å±½¹´¨ªµ´®¯—–¥¬¨ ‘Ž’²Å§•Ž}’•}ˆ’™ª™˜““’•“¥ž’™”¡£¢œ˜Ÿ˜‹ŒžˆZ–—’—¥™e˜£Ÿ³¥–¡–¬¬ª§›ž¦—˜–˜• ¤¨¥Ÿ¶«ªº»Ã´¥³µËÀ¸ª¶¬²º¸®¨¸º½¸‚jmYVSTMEJRNK?AHEDHHH95FM;>8=@J.32025C55OVN<LFKRLOHGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|gV;=@BFBpEiIRebLF¥”œ—¢—©–ƒ‡¦“ˆ‚‡‚œƒƒ•”š¢Ÿ¯¾¯¡Æ¼ÅÄÆÆÎÎÎÒʾ»¶±º»»¾ÏµÃ½¸¹·²±µ³¸³«¦œ«¬¹ª©§¯¯˜£¯¤§¤¥µÀ°«¬´¿ÃºÀº´¨¹µ¹³¯–¥­®®¤‹“•¡tÁš}—™„–šŒ±•›š•’“™™¥£” ›—š©œœ¡ ™Š–œ`J–œš•š¥–U—°Ÿ¯œž¤”¯®¬¥š ¥”“™˜Žœ §¢™´©ª³¼»»ª°²Ç¿¹¦¬«­±±£¡±²´¤old[YNOKEOPQQ;HJIGICC>:KU?A:=EM07544:B44MWO<JKOUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@BAF3>58JKCA=C;4EA:A?>H@5*B52,>c]g:35tde@R7&#3}hW;:BC@=QEWSsbWFHª—™ ¢¨¯™‘˜‡‹¨–Žˆ“…Ÿ‡„—Ž¡›£¤µÈµ©ÆºÂÃÇÊÉÈÌÍƾ»³®¹¹ÁÁ̵ǺÁ¹µº°¯¯³µ§¤›ª´µª©¦­¬š¤®¥¤¨¬º¿¨«¶·¾Â¿¾¹´³Ä²¹½¬£¯µ¬¹¦ˆ›—¦›v¿Ÿ„™Ž“™š‹®—¡œ›–•›Ÿ¡©ž§Ÿ™šª™¡§ž˜‘ƒnv’¢š•¢ž®²¢ª”¨ª—ª®¤¤Ÿ¥¨’’™œˆ”œ¢–±§©«º¶½³²­¾¹· £§¨¥§œ›¬©©Œad`^QJLFHMIVL=MENKLBCD<QV=AABDO18=77?B75UXN?HNQYSPQUKQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW;:=.-R`MUHe^HE«•œ¡Ÿ»¯™”ŸŒ“«›‘’“‰«‡¢ŸŒ¤­”££¶Æ¾´ÀºÂÂÇÈÅÂÍÈÁ¾¹²¯¸´ÀÂʵŲÁ¼´ºª©­­°££˜ª´»¦©¦«ª©¯§£ª«¾¼¨­½´¸¾Ç¼·¶¸Á²¾Á´©µ·«¾¥¢˜’¢Ÿ¼Ÿ‰š ™—žž·Ÿ©œ¥¢›œ¡š¨¥³¡›¦œ¨ªž™•”›‹—‰Œ¤¢”¢ž¡µ¯¥¤“¯«™«ª¤£¨‘••Ÿƒžž›•©¤¡¡´´ºµ­¨µ²³žœ¢¥š—•˜ª¡žv_[_]JHEFMQIMEFGCSLJBEGAVRDH=AGQ1;B7:BF79\YKALPTUSMWRNUJD@JJNO9C@5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-19g\FCCœpbGE§—¤ŸžÃ­›—¥˜š©œ–››ª–•§¦•­¬™¢«¶Ä¼¾·ÁÂÀÇÿÍÆ»½¹²°¸³¿Âȵ¿°¼¶¸¶¦¤«¬­¡¡šªªÅ¢¤©«¦ž¬¯«¢©¨¿¸§­¾±¸¶Ç¶µ¹¸À²¿Â·µ³´¯¾£—£–”›”® ¡£¥££Ÿ½¤©ž¨« ›¦Ÿ½¢™£Ÿ¢©«¡–•ž“ž‡„“Ÿ¤ žµ¬¥›•±§™®¦ž™©Ÿ˜”ž„ š›“¥¤š˜«±µ±«¥ª­¬œ˜  ’Ž•¨ž”gbX`]NHGJNKHEDI@>QIA<GIH[ROK=HOU4BF9>HG5Ca[KCNRUWVQXTRUI@8RQPM:GA4CHQSIC;C>GVKC@O>K<06;GF>;FA46@9:?9;15D0-,/Mv\4KZ5,MnW<-=)#zbQ5CKQ:nRF<KxebVL¢š£œžÅ¬¡Ÿ¬žž® ’£Ÿ–¥Ÿ¦ª¬—¶±£ª³¶ÄĽ¿µ¿Â»È¾Êǵ¸µ´°³³·ÁŶ¾±¸µ¸µŸ¦¬ª¬ž¥¤Á¤Ÿª­ ¤©­¯¢¦¨½µ¥±½¹¶¶Ä²´¸º¿³ÄÁ¸¸®³µµ£¥•‘”¡® ™¢ž¨¨«£šÂ­©ž¬­››ž™¦ ¾¡¤˜««¬¦¢™šŸ’Ÿ‰ŽW–Ÿ¦¡ ¸ª¦“˜µ£Ÿ± Ÿš®–žŽ˜“ŽŸ—•Ž¢£–¦®²«©¡¢¥¥••˜‹‘’¤ž‰`cYc`KHJJNEEAFJ>=JB99JKN]QQI=LV\9FI=DMI8Hb\LCLPSYYVWOZ^IA=WQIK?H?5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+w`S6SZkWrGE6=ue\KNžŸ¡™žÃ¨¥¢´¢²¨“«¥ £Ÿ­©¬»°¨¬¶±ÈÅÁ²ÂýÆüÄɼ¯°¶­°´¯¿Ä´¹±°º´¬™¨°©ªš¥¡¨Á¬›¬°œª£®±©¤¨½¶§·»¾¯·Ä­´³ÃÀ³Ç´»·¬´¶­ª¢¦–•”¤¬¢ŸŸš¨«°¯¯»²¦ ©¨š™˜“¢¤¹ ¡¤“¯¯¬¥§Ÿ’¡ž•ž•žš¢ž§´¦¦Œ˜³›£®š›­ž“•“™‘¡–Ÿ¡“‹¦¬°¥¦¡œ ž’’š“…‹‘œž`eZgeJILJRBC@IG;;G?99OMU^RSJ>O^]=HPBLLI9Mc\LELRTY[SUO\bHA?ZQAHAKB7FELKM?;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<v]^?[T^eq@8;H–weA4Ÿ£ œ Ã©¤ª³¡¤´ª–³¬§¢¤²¬®©»±­°µ´ÆÀÄõÀĽÉĵ¿È´«µ¨¯¸¬¿Ã³·®¬·º¥™«²«ª˜Ÿ¦—­»´›§°›­ ®´²§«¹³¨º´¸²¹Àª·²Ä¾µÆ¨¿¯­·µ©§¬¡——‘¦¥¢¢˜˜¥¯¸®²µ¶ Ÿ¨¤š••“¤ ·¢¤¥–¯±²§ª¦¢Ÿ›š›–—¨Ÿ ˜¡ž¯²¢¦Œ—®˜¤ª—™ž¤š“—™…•ž”Œœ“‹©©ª¡§ ™ž•ŒŽ™…•ˆ”Ÿxbh\jjMPMNT=CANC::I?77RO]^RVQAW`\BJSHVKH:Td\NFON[W[RPQX]GAB[PBG>NC9HGHOP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1[bZ33806p[bH05IphVCWFŒyfC;¤¤¢¦¿§¨¯°¡©µ«º±«£ª´¶±°¹·°·¸¸Ä½Ãǽ¼ÄÁÆÀ¸ÀÅÀº©¶¤¬»¬À··ª¬²»¢•­±­²–¥§‘ª¹©Ÿ¦°« °´³ª©¶¶­¼­³³¹·¬¸°Ã»¾¿¦Ã«°·®©««§ž˜™«¡¢¡‘—¡±¯³¬°¹šœ© ™–’—¦¡·©¥£¢°±´«³¨¬Ÿ›  ›¥¢—£³°šŸ“¥šŸ¨š”¢”—‰“–’•–œ“ˆš™”Ž¨¨¦Ÿ£›—›“†Ž˜‹}Œ–…Žšjhl`lnWPQZTACDT@;;HA7:XPd^PVWEY_]MLRN^KJ>Zc^NHPO\UYPKTWZI?DXPDF?N@=IGGQPB=DFBM?:1D?77547?=95E4+75/251.-.,1=*'+=\p=>1.0dZd@1647gY`F(?8l}g[V;‰{cC=¨Ÿ¢ª½¢«°«£±¸ª¥¶´¬ ­µ½®³¸»º½¶¶À¿ÈĹÄÂÀÀ¸Ä½Á·¯µ§«·±»¾¿´©®±·Ÿ—«®¨®—¦¨Ž§»Ÿ¤¬³ž¬¢±°³¬ª¶´µ¾®°±µ¬°µ²Á»Å·«½¯±¸¬­ª£±¦ž¥ªŸ¤˜™Ÿ³ª³«ª³š§›š•Ž ¦¥´®§¡­­®±§´­²ª¤œŸ¨£ž•¢™›¨µ©—™‘’ž™Ÿª–—„”–Š™œ“Š–—š—¦¥¢ –•—“”…{Ž’‚Œ–elrgoq^FYfVDCMXDZ9HB6>]Qh\NY]G[^]NMRXdJJC\b_PLMNXWXPJVVWL=EUJEDAM@AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,,%2+*5K1/'__`U150=`V^8)C3YT\gK6ŒzfL@¤š¡¤¬¶¥­ª¦¯®·ª¯µ»¨§±·Å·±·½Áµ´ºÅ¾ÌƹÂÀº¾¹Ã·À¹²´«©º¶»¹¾´©­°µ˜˜§¬ª¬›«««¾ž¬®²£«Ÿ°­³®®¶²¹¸ª®¯²¨µ¯´¼½Ê³ª¶µ±´°¯¨¢³ ›¨­ ¦––šš²¢­ ¥¯—¡¤šš’Ž£¦¨³©¡¦³¬ª¶¥¯±µ¯¤™­§š˜Ÿš™«·¢—“‘Ž—œ¡—–”«žš’’—Œœ™–‰”’ž™¥¢¡ ˜–’“•yŠ…{ŒŠƒŠ’jmxmu{aE`jYIHZZ={JFD6AbTi[M\aJ[]ZRRRbaLKE^``QLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`U`/5(C_Q\.*B/JGP[H3cYUKD™—¡±¨±ª­¦¤¯®¶©·µº¤¬´·É»´ºº¿¿´³·ÃÀÌȼü·½¿¿·¿¼±½­§º¹·¶Â¶ª¬±·”—¦®«¨£°ª”¯»¤­±³§¨£²´±²±µ±¸³©®«²§·¯¶´Äƶ©¶¶¬°­ª©¤¶  §±¡¤”œ™•±ž§œ ªŽ©£žœ–˜¦¦¥¸§£²µ¬¨²§®±¶¬¥™ ¬¨›œžœ”©¸œ”ŽŽŠ˜›¢—˜¥ œ”‚‘•›—–•ˆ–—š§œ£ ’–‘•u„‡{…„Œ‹mpwt{~\Kel\KNc\?b{GI8GgWf\L^bMXYWTWTi]OOHa]_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANHf27'GbLV%-B-=ELQ<3rkICC™¥®¥­¯«¨¥±³´«·²· «µ¹É¹®À»Â¸³±µÂÃÎÅÀÁ½´½¿¿º¾¼²Ä§©¹°¶¶¿¼®«³²œ §±­¦¥¯¥ž²µ¬«±²­ª©´»¬µ³µ­´¬ª¬¨­©¹­²±ÈÀ¸¥º°©­­¥©®°¦¥£¯¤©œžœ›¯š££¢£‘¬ž£  ¢ª¦¦¹¤¬µ¶¥«¬¨­¯¶®£ž£©ª› šš’¤³™Ž‰‡¡ ”Œ”œŸ’‘ƒ’’š˜•“‡—’•™§›ŸžŒ’‘v}Ž…|||‡‰ˆpsq}|}\Sdn^NYf\FD–[G;NmXb[L`bNVWVWTYg]QRLcZ[TKGOTSNGIVS\N;P^IBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3Bc;6*HeHJ+;H?3BHS,>k;GHœª«¢ª±¤©¥³´±µµ²²¢«®½Ìº®ÀºÇ±´­´ÂÂÑÅƾÀ²½À¼¿·»Ä§¬·¬³¸»À¯«±­ £§­ª¨¤°¤«²ª¯¬°¯°®«³¼§·±²©³«¬¦¥£­º¬ª±Ãº¶­»©¨¨­ª©³¥©¤£®ª¨¢Ÿ¤­•¥ž˜ž™¬¢¨ª¢­¦¤­«¸²²¡©¢ ¬¯±¬ž §¨©™¤™™ §˜†„ŽŠ‹žŸŽŠŒ•›Ž„†”Ÿœ•—”†–““—¤›œœ‹“‘‰~~‡…|w~‡…†srqˆuk_Y`ncQsq\K;„|F?WtXaZNc[NVVUWQ\b_SONgXWWKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*25>10485(5/*,.30;),,'%234$,2-860)(1<]J0.JgDF8<B05EKX1@•Z>LE•˜­¨¢«³œªª°¶­¹¶¯«¦«ª½É»°½·Â¯±¬³ÄÃÎÏÿ¿´ÀÂúÀ³Èë®·­²¸¿¾²­­«¤§ª°©§¨±¦´¯ª°®­²±´¬´¼¤¸³­¬®¨¬ £ž°·«ª­»·¥·¶¤ª§¬¬«®¡©§¦±²¤§¦¢¢¬—ª¡•› ¦ž¤¢«¥­£Ÿ§±¸®®£¦¢›ª«®©¢¥¤¤™ š–˜œ“‚‚ˆ…œŸ‹ŠŽ‹˜Š‚‹—£š‘šŒ“’‘“¢™›™Š‹‹|†ƒzt€„}sv‹£‡xj^`nfWe‡cN?g“LEbyWbYReTMVUVTO\]aUKMhVVWIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*39?./463)4+*,+.#4.-+&(+79*&6+<-2,&06WZ.0JgAA<<B+:JO^4D†>HFD—’°¥£«±˜«ª­¶¬¶²¬¦¬ª©¼ÀÀ¸¸³»µ¦²¯ÄÉËÒ¿Á»¹À¿Â¹Á¹ÀÄ­±µ±³º¿½²°®­««§¶ª¦­¯ª¹°¨±²®²­·ª··§´·«¬¤ª«œ£ž³³¨¨¤´µ ·® ª¨«©¬¨ «¬©¹¶©ª©ª£ª ­œ’ª¡ ¤¢¦£ªž§´¯¨¦ª¢£˜¥§§ªœ£¤£ š˜ ‘Ž˜‡Œ‡ƒ†„ŠŠ‹‚…”¢šŒ™‘‘’Ÿ–˜–Œ‹„t‡~xtƒzw~ˆoqggqx\asˆkO^™VHmxUdVQcOMUTUPOX[bUHPiTVSGPYUI>IHOQPxLMV=<KD?@A<@CUC9AK=5;E13;:7*4:=+-341*8**+*,))(/*&)%3;,$2)2021%/2Qb02?f=NX>C,>LT_/Ji5OD;–Ž±¡¦«®š¬¥­°´µ¯«¦°ª©º¾»À°®¹®¡·¯ÉÇÈÑÀ¾½»¼Â½ºÃÀ¾¿®²²±µ¼ºÁ±±²«³¨¤´¨¥­³³¹°£®·²°²»«º¯ª®¶¬ªžª¬Ÿ£ ¶­¨¡Ÿ¯³¢µªž¨§ª£ª¡¢¬­¨½¯¬®­¢¨¨ ¬™°¢˜¢ §¨ž§›™ª±ª£ ­¢¡”£££§˜š©¥˜˜˜žŽŠ‡”ˆ}†„„¤–„‹†ŽŒƒƒ“ –ˆœ“‘œ”—ŽŠ††xt|uxy€ztsyh†¤ui^dktgˆŒ}SXp^JxsSeSQ^MMRZfNLVYdXFSiRQ?CNQaQ:IHLSIqQLS;<I?;<=;@@W<<?H73CB15:93-5::)-31--5)(+-,42#2)',%.;.&1.0-14%,0Lg:48_=ad?F1CP[[*HM9UA4²¡¤¦¬¤§¤­§µ³±«¥±¨ª¸¾À¼¯§¹ª¦¯°ÉÇÈÑü¿¾¹¾¿¼É»Á¸°°´±º»·À²³»¬¸¬¢´§§¬²¶¹³¨¨½¶®¶¾°½§­¬µ¬­œ©¯¤ ¥­«§œž«³¥´¨›«§©£©¤©¨©½¬´¯®ª¤ ®œ›³£•¤œ¥¥Ÿ¤››©«¦Ÿ›ª¢›“œ¡¥ž˜—©©’˜š”Š‚…~ƒ€ˆž…~}‹†„“š“…’¡Œ”‘‹‘š‘•†‰~r{z~|hx|zupp|g„x„ˆdagbr…zmgx]]U@WzmTaPRXKLNru]HZ[gYEUfPD>JNDCA9HGKS?jaJQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11'/>KH0%90%,,09/,,+6'17#-0GjI14X=fcAJ7GS`U*=9DW>*”²™  ©¦¥¡«¥¸³³¦©±§­¸Á½µ¯¢¸­¨¨°ÂÉÉÌÁ¶½Àµ·¿¹ÈµÃµ³²µ²¼·¹½µ­¹¶¿­¡³§««°µ¸µ¬Ÿ¾½ª³Á´¼¡¯³µª«Ÿ­°£œ¥¨ª£ž›¥±§° Ÿ«©¨¡©œ¤¨¡­»¨®±® «£¤®žŸ­¦—Ÿ›¡£œ œš¤ª£››¥¤–—•Ÿ¢–›—¦¬Œž‘‘‘‹‚Š€€Ž{š”ˆ{~‹…Ž‹Šƒ’˜‘†“¢‰’’‡™“€ˆ|yl~vyxc{{qpprwh€sjƒgeg`mslaio`o>ZxkU^OQQJIMTYWM]^lWDX`O^PHMDF;7HEKO<rhKK9AE;;==;;=J49B<3;G<4?18-68;2(09/,4/.=-*K>*49&'.34.0+/4&,:$41BhY13S=e_DL6KVdO*;2NX=#“™­š ˜§¤£Ÿ¨¤¸°¯¤¯°ª«¸Âº³­Ÿ¸¯«¨´ºÈËÈ¿·Â¾°´½·Ä¶Ã±®¹²³¿´º½·©¹¸½«¤´¨©ª±®º±«œ¼½¥°Áµ¶¢¯·µ¦§§±³ ž¤¥§¡¥™Ÿ¬¨©ž ª¯§ ¦˜£© ±¹Ÿ£±¯¡¬¡¬¤œ¦§©šš›Ÿ¤•›žª§˜œ ©“™”˜ž“™–¡ª‘šˆŽ†}‡‚Ž}|¡Œˆx‚‹„‰‹‹…‡’šˆ•žˆ‘•‚Œ—Œ‘|…{sp}qtt`yxinppnh}qc{miec_e…~_ZskrKKhXZNPLJHPRPIN\_nSDXZRhOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23.:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%53=fd24M?e]FO=RZgH*>0XV5(—ž§š–¬  ¡¤¢¸«²¥´´ª©¹Äµ³­Ÿ·­®­°µÆÈÁ·¿Â¹±´¼¶¿»¾¯«½°³¾±¼Â¸©»º·§¨µ©¨«±­³±¨›¾·¦­¼·²Ÿ±¸°¨¥§¯±›¡¤ ¤¤¡—œ¯§¡Ÿ£¨¯¡ ¡“¤¤¢·°¡¦±«Ÿ¬£¯˜œª¥©ž—šž¥“››ž§¬›¦—–˜”Ž“—¢¨¢ˆ‹…z„~„‹zŽ–‰†x‡ƒˆ‹…“˜Ž–˜Š—~†—‹yzprwoot_ywdllkih‚merkkehZbs^ZlvjZH}][XOOJHHRUF2:_^lPDXVYeLHJEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<#8R=*113>D5,-'42+;+139cl84GBg[HTCT]hE.;1_T,2–£¢˜•©ž¦¡£¡¸ª¯¡»¹¦¬½Ä³¯®¢µ¯­­¯´ÄĽ³¿º·±³¹¸º¸º®­¿³´¸¯¿Á¸¬½º´¦¢³«¨ª³«®²£Â¶¦©··«Ÿ²»©¦¥¨¯«™¢§œ¥¦”˜¡³¦™ž¥ª©œ¡ ”¥Ÿ¤¹¨¤§­¦ž¥¡¨“Ÿ©¢¡¡™›¡’›— £¬œ›š¢–“•–›Ž““£§¤ˆŠŽ†y„|…†}œ‰Š†x€ƒ‡‡‡‘…•“’Œ•“Ž”{‚—ŽŠw~{lurmlsbyuhgigen„gghdfhj_fbifZf{caRsT[[SLIGIOS@!+j^jLCVU^`KHGEC.:B<F<6KPD8:D357==895?:;4>8@L=>93)8><:9*6@3.E4(+,>0-N?.+-7-1195,&.5-80576`tB3CDh[KWGU`hB378bM'2ž¤¤’Ž¥¦œžžž¤µ­¨ªº·¨¬ÃÀ·¯¬¡µ®§®¯·ÁÀ½²Á·±¯²¶µ¸·µ¬ª¼´¯²±½À·®¼¼±¥Ÿ¶¬¦¦µ©«¯¡ Ä¬ª§±´«¬´ºž¨ª«±¥˜ªž¨¥‘™¦®£˜ž¤ª¡›¢— §¶¦¯ª®¡¡¡• ¦Ÿ¢ ™›šœ’šž•¦ž®£˜—Ÿ–”Ž•˜Œ˜š§ ‡ŠŠˆx…w‚‚‚œ‡‹‚‰{~„ˆ†„„–•‘‘“{ƒ•†r~}gypkjlguskbgdbtbdefeijcgoY^X]mdaMhW[`VIGHKLRX>9`liGBUS\[IHFEA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A<-5B37=+*,0A*JK./*+3722(57$+7.72685\yN2>HiZLZJVbfA:3AdG%5œ¤ ‘Œ® š˜ —¥´²£²¾·¡±Å»¹°±£¶¬«®©¹¾½¼­À²¯¯®¶¯³¹²§«¹±¯®³¶»¶°¹¾¬¥žµ« ¡±¥«¯Ÿ¥Ä¡³¥¯²¯·­µž­¯¬®¢™§ª¥Ÿ•›¨¦ ™¤£©œšŸœ•œ­°¦¹§­¢¡ššž™Ÿ¤š¥–ž˜›”š¡’¨–­©›”œ“Œ•™Ž””˜§§Š‰Ž{t‚‚Š˜…‡|‰ˆ„„ŠŒˆ’…“œ“’‘–Ž€ƒofynhkjgqrk\hcar`dgjnlfjgdl\lmvqaTbhceZIFLMOXQPUaeT@VSYUFGFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24;6#3*)6.55465Z|]1:Kj[M[KXdc@A1IdB'4“¢œ±›”¡š©²°Ÿ¹À¶ ´Á»½¹±¦¶°©®¥·¹¸¹­»¯­««·ª´¹­¥²µ±¯©±·¶±³¶»§©Ÿ¶©Ÿª£ª­ªÂ™¯¥¯±¶µ¬¬ž±­¯ª¢›¤¬¨œ•œ§¤žš©£¥•š ‘œ£«ª©ºŸ¦¤ ˜ššž¢k¢•˜œqƒ–œ¤€v‘«¨ž––¡‘‰—™€—ŠŸx…“ƒmi~w„rl†Š†}„Š†o]d`g„—†k‹”’uw‹„ƒfˆ€hvifX]itnNPjcfq‚f^dfnli^]^‰…ˆhOKD8ETg^JHPPUUKHS`oteE[QUPFGFC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,,08>G701.*.*/668,#1'214:276Xl15Ok[N\K[fb>G1Ob<+/¤š‡•±›“ œª­«£½Å¯©·Â¸½¼­§¶±¦«¤¸´³´±¹®ª§¬´¥°µ¢§¸¶µ¨§¬¶³®´®³¢©Ÿ´«ž¢¥œ§¨›®½•¨§°´¸­®¤¨®ª«¦¢Ÿœ¡¨§œ—¡¦¦œœ§§’ž ™ž¨ª£´¯£¢£œ–˜˜˜¤‰¡’š‡¡ˆ”ž¡¥§¬Ÿ”““ˆƒrxŽƒ‡ uˆi—‰f~sy oˆ‡ƒ~Œ|¡  ™{‡žtˆŽv›Šlˆ‚ƒmied{mrbT†mcmi˜qXipn†W]i[kj[ˆpmyr‡i‡„Z^FN>F^MERVVQPRWTg^LYKRRPEGG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82*/1<I9/01.*/(-4583%&2115>1<8Xƒt15Rk[N\L[g_=K1U`7/(¦—„¬™™Ÿ«ª¨ª¿Ã¯²¹¼·À¿ª¤·±ª¬¦³µ®¯³¶«©¥±­¥µ³›¬µ¶´¦§¨³±­²¨®žª¡³© ¤¤š¢¤°·•¥¦§¶½¦¬§©ª¬§¦¢ ™ ¨¤™™¦£¥™œ¥©–“¢œ”“£¦¦¡¶¤£ £˜•“˜“œˆ®˜”‰©‹˜£œ†±€¤®ž•›Ÿ•y‚Ô¨‡”À›Æxw±¥·–d€Àœ¿y„„yƒ|‘Êq–¼œÅ{r¶§º{l–±«°yhlX±®oei¼’¼nhzmpØ~Skb¶²~€q”uš¡ªWOXaOVNFT[XQPS‹\W[P@\EQNDFI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22BE/.32.+/)-/186- /416A1=:Wƒw11Tk\O[M^g\>L1Z\41!Ž¦“§ªŸ—¥­²©±Â½²µ¿µ¸¿Â«¦´­­©¨¯´ª¯¶´¨¨¦¶¥¨¹¯œ²²¶ª¥¤§²¯®±¦«ž§¤²¤¢¡Ÿ—œ¡ ±®•Ÿ£ ´º¢ª¨¡­®¥¢›š¢ª ˜›¨¡Ÿ˜ž¨§‘œ§š”ž¢§£ °£žŸ£––’˜’™…°kjŠª~g…–‡­eqŸž•š§–q®¡¤~wº|k¡v±_j´[¥€eœ‘`fzf€ixj©e¾rg¦Œv±j|±xu’”cmm§n\„ Eig‡–Euœ`}f{£¦‚Y_‹«i€’xzj¨8J¯[WTmcZLOX_\WV;NˆOWV/ITSJCEF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3..53/+/(.0.:6/'$203B/=;U‚v2-Vj\OYL_gY:M5^Y31’¢•‚¬§¥Ÿ£¤ª±·­´½¾°·Å²¸ºÃ§©°¬¯©©±¯¤±º°¤¥¯³£©¹©ž³²°£¥ ª­°¬¯¦¨Ÿ£¢±œ£˜•˜¯¨—œ¢Ÿ´³¡«›¡­­ žš— £ª™ž¤¡œš¡§¤£›˜¡ ¬Ÿ¦¦ šŸ¡••‘–‘š†µ›µx…©™µ™w‡³›·”——«–~k¦z…†‘”’w«gj±[¬{Ž‡”tˆpŽ†€€ˆ—xƒ‚‹—Œƒ …°vwŸqkjl|‹O¥XHcc™~ch¥_yquR’‡^P©mcq}†€a/R¢n[Tkg`LK\cX\ZB>°xWXA#MhFCDA@A19>88:84;:9<9:A:E::;6:CB8=?KNH:5:AFBAAD<FD;0201;F,0.840,.(/2,>831/2-D1<<S}n3+Xj\OXM_fW7J8aU50— ”ˆ³¦¦¢®©¨³¬ª»¶Â°¼Â­¸·Â«¬­¯®§®³ª¢¯¼«¢§µ­£«¶¥¥²³¨£¡§ª²¨°¨¦ž  °– š––—š ¯£›š¤¨µ®¡©©¨ª›–˜ ¦©›Ÿ£Ÿœ £¥£•›Ÿ˜šž£«›¥šœš¢ –“‘““„Õ“™¹q°ÂƆ|֔œ»|›—§œŒ¤z†¢¥‚z¬yV¯{‰~Ÿj¹Z¹w†ƒ}¦‚“|˜zªyŽ{±nŽ„t»…n•P¯§ÅŠQ zc`ªbsr†l—‡_Sµ´È…€‰|c¤3Bu]PjhdP@XfZdaJHMkJZSOYfZCC?E?0<<59;74<;8=:<C:F:;>6:@C;6@OLH<:<DHCBCD<EF81211DB.00483+-(.323971#%5*>3==Qwj6*Yi[J[P_fT7G:aP72%œ¢“™±¨©¥³ª¥´¨¤¼·Á±ºÀ²¶µ½´¶¨²±£±³¦ ¯¶©›¨º®£°²¡²´±¡¤žž§©±©´©¥œžž¬—™™——–˜¢¬ž›—©­°¨£ŸŽ¬¢¨—˜œ¡§¢˜¢¡£¡›¢¢§›ž ž•™›¦¡œ§•››Ÿ ˜’•ˆ²nhµq«ˆpŽ¦r´ts¶{›™¦œ¢~Ÿ¤~°uƒ‘ÒÑu[®|…¤o›ª¦k†…}­}—™{±s“x³e–t…žnžf”RɋZÂ\Ÿyb_­_vs†b—ˆ^Yʝo¿€uMKµSUÆdTQjcfXAOj_liPUFI8=WR[VYIC?J<2?;5=<56>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>II:1746@>/.24252-).26,742&60;5:=Prh9'Wi\ANT_eP5G=aM62.¢‘¥°­¥ª»­§µ¥§¶»¼²»¿¸·µ»»´¦µ´¢²²£ ¬°¥˜§º®¤²±´¸ª ¥¡ª¤²¨¬ª¥š›©Ÿ–•˜™’“£ª¡—“§«°¥¢–’¬Ÿ¦“”¡œ¥§ •›§§¢š£Ÿ®š¡žž–œ¢žœ¥••™¢ž•™–’›…¬{w¨v£‹‡©o­Šƒ§ƒšš£Š’™‹¢~’—‡®…‚³\r³R®}‚‚¤q×}w„~†™šw¯†Š‘œˆw´ašeš‚•l’[°WKšu˜yf`­^vw‡g˜ˆj]¯w•Ÿxl5yÈ®²_BTo]g`EPl`qmVUM.ebhSYP;BD@L:5?91><16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK97<46:>/03333.2..18*.32%!03767=Pke>&Vg\@=V_cN6GC`I:77 ” ¸±˜³Á­¨²§ª²º¸´¹¾¹¸³¶¾¶¦¸´ µ­  ©¬ •§¶¬¨±²«­´¤›©Ÿ ¨¢µ§¦ª¤™ž•¥¢””œš’–£¦›”§­¯¥¡•˜©Ÿ¢‘¢š©¦¡•š¦©¤ž­¡œ ”Ÿ›ž¡˜™œ–—¡ ”˜‘¦†©}}¥y¡ƒªp­Œ¦†–¡¢Š—–ˆ£‡”ª{‹yo±Z¨ƒ‚ˆ ytØv‡t§Ž›’¤|–Ÿ„{²^œd }‚”m“\«\[“‘hgªcr{€j˜†q]«Z‰ kneOJC¡\ZMt]bfMZa_rt_JU5Jš’XHE=HFAM35A8.;>05A78@<6=<F?:<6?=B7.HVJE@H6KIN@IK@EN::@4.;>002154+*05/7,&21($$6671<PeeA&Uf[?1T_bL7FI_C1=7¢œšš¿¬˜´Â®«­¨¦´°¸±¶¿¹º³±¸¼ª»µ ±¥Ÿ¦§§Ÿ”ª±©°ª¶­ª¯¡˜¡ ¦¤¤º¢£«¡—›‘£ ••Ÿ›•™  ŽŒ©°¯¦—›§¦Ÿ’¤˜¨¬¨•˜©¨žŸ ¤­£¡ž¡Ž•¡˜Ÿ ’œ—œ•¡•–«›®nr´t©ŒwŠ¦s´yt´“¥£“œŒ‰¤‡Žu¸oŒ{‹¢kk¶Z¡†e——i ¢§m”r´t“˜²j†’ˆ­ku³af¢n†’k—\­`N¡|‡‘Rs£ly~n˜†p\¯V<œwfTon.[§ObRkeblZb\`p|cSYQ>>mo2BB@?M:!7@6.;@37C58??3;<CDBJFMIF62JTKEBJ6IJP?HOCFP=<E50;;010/75,+,326/#00,,289/9N`eD'UdY>/U^aL5FM^91A8¥š›»¢œ²À®­««§·©¸¯µÁµ½²°º¸«Á¶ª«¡§¤¢’««§¶£³¨®ª¡—œ¨ ¥«¹£­œ–™¥£–Žž¡›™žŸ‘“•«¶¯§™”›¬©—Œ”¦š¥­£‘—«²¤ ž¨«°™¡¢™¢— ›–›—¡“œ©”ª™‡Ó“š»t±Ä€Ã†}Ֆ›¸y‰‘˜—‰Œ§‡y¢¶u}wv‚š²`ƒºyÀ|u¸bµŒ‡©}–¬©q{u¼ˆ§ ia¦Ž¯¢~Œt‡«}¾ns¼t²ƒux€Šmšˆqm¤t½]w}[ay¼jZV[iy^iadfbmyoY[YCA@r?CF+5H"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-6@9§šŸ¢¼¢˜±Â°­©ª¬±¨¹¯·Å²¼³¯¼°®Á²­¦£Ÿ¤¡œ‘ª¥ª²¤µ§­¤ –šª™¦¬¹£®™•¡¦ “œ£Ÿ™Ÿš–“¯¹°«•—£§§”–¥¤­Ÿ‘ ¨«ŸœŸ©¤²ž¢¤Ž§¢”¡šœ—–¤˜° ’•©Ÿ…™¶€‘’¸•x‚“›µwnlnsoy„Ž‰sžÁ»¼™z²¨p€t‘¹ƒ|††‹‡{Š†—|¤»¹½œuy³£uv—ut°u˜žf†i¶trqw¶Œ^y}ˆgƒymyb‹¬pt…X[§jDdYTf_c]cQffqmuBMPMD;ZL?J3<0 8>;.3=A99?=;<C6BSYZZ[[Z[^`b`]SGGH4DITBKNGEOF?G<7>7070/9:.,/-*8/%&2(4$(>7/7KT_G'SbW8*O]]=+;VV'=:<¦¡¡¿¦–³Â´«ª¨­«ª»¯±Æ°¶´¯¸§µ¹®«¤¢§Ÿ ™”¬¤­ª¦µ¨¨Ÿœ– £ž¬¥¾§¡ª—•œ‘¢›’¡¨¢”ž—’˜”²µ¶­˜¤¤¢‹’’¦œ¥«–©¥¦œ›¢©§¦£¨¡’¬ž—¢ž——˜ž°©“œ§¢k~iœ¨y‰s~›Žuze‡{¾¿Àºn’‚q•…_rjZ]š‰ad‡Ž•k`•cmœvb”k€š•”e^_cq›‰hs|†”fj~qty~}b[xthP\nƒ|{ŠjXlyrIJo…pNsMEW\faL[Wfc^OZmvjrRODEM<HI<M?2,2A?8/5?C<9;@;=C>RVVWYZ[[\]`aaa`\UG5DFUEJOHFPIIH;8=51:.1;:.0-76=5&"/*2,%;8-7IR_I'S_V4)P^L(3>[O'?2>¨Ÿ¨¡Á¤š´º¶£¬¦®§¨µ²¬È­±´­¶¤¾±³§¡¤ª£œšš¬§®¤¥µª¤›˜–¢›¦­©¿¨©¥•”›– š“˜¥©¨’Ÿ˜œ°²¿¬›§§¢‰“‘ª›¨¤œœ¬Ÿ£š›£§¬¢Ÿª¢š®›•¦ –•Ÿ—±¥™¢¨™œ‘žœ£¥š§£šššš–‚hn}qv‘—”‘ƒ‰´©…˜•ŽŠŒ˜—‡“•Šƒ““ˆ‘”™“™—š ¡š›” œŽ‚z¤…li{}€u‰‹‚r‚xyvuŠ€{‰jstƒudw}vkpzm`c[ogLXYej_WYpzonfSOFR9OZNRO(+;JB635=@A9:C><ENSSTVWXZZ\]`bba_^^[TKCSGKNDGPLOI<:;489,2;810)6IRO8")+/2#4;*7FO[J'R^T10T^:+=8]K,<-@² ³¢¿¢¤±±· ©¦³§¥°µªÉ¬®²¦µ¦À¨´¡ž¥¦œ¥–– «§¬££·¬ ™—– —­ª¦ÁŸ¬¤–’œ—ž˜””¢žž£¨’™¨§²Ã°š«ªž—–©ž«œž¡­˜¡›¢¥¯¥¡¤¨ž«˜—¦™š¡žžœ°¡¢§•˜”™”¡£–¤Ÿ˜¡Ž–”‹Š—­{•›‚‘€‰©¨…€˜–Š„ŽŸˆ{ƒ†…š‘‡†‰•Ž›—Ž˜ž£–™’~e¡³®„‰„w{Š}wyzogy€‰kuyˆrisyuƒ‡‚ktcxf_hdcdfjXk{pjk\SLPD_UF@?>,4@F;45;>A;<?>>HNNOPSTVVXZ\_aca_]]]^]XVJKLBIOMRJ;<:786/3964.(&$-1..)+*7%+<(6CMLD/T\Q05M[17E4\G5<,@´ ¹¯¾¬«­±² ª¦²­¢¬³°Æ±¬­¤³¯¼¤´œ §¢¡™—¨¦©¦¤¥³µž••™™¯¦®¾ ¬£’’žš™”’–¡œ—©…©¬¢´Ç³Ÿ©¤ª––˜š§ž©œ ¥«”ŸŸ ª®¨¤£«¡¬›ŸŸ ˜¥žœŸœ°¤™Ÿ¨“˜˜’¥š™©Ÿ›—fƒ’|e~šcxŒlhjz£«kd™—~g…Šeeihz¡ŽkhŒ—‘¢wkj‹˜¢Ÿ˜slnz„Œ†yXe]…‚^l‹Š‚v[hsww‘€‡‚nx‚xsmy„swˆˆŽƒ{i…X]jsd]sˆik|qmc]QNWIdX@J3=F7?FD71<=?AC;;DGHHILNORRTW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%.++'6*$;'/AI[I.6ZO6)EY/DO1YB;?.=¥Ÿº¼¹¯«³°«¥¨­®°§®­°½²«¨¥­°°Ÿ­˜ ¤ž¢šš§¬œ¬£¦¨©³®ž–£¢¯¦¶¹¥®£š¡™“’› ˜™¦–{¥¬¢¨´Ã¸¥¢§¯Ÿž•ž£ž£¤ª¨’Ÿ¡ž ª¯©©£ªž§›¦ž§ ¬–¡œ¥±¤˜œ«–¡Ÿ›“¥˜Ÿ«™ž~¾ƒˆr´r…ž…­hw¹Ä¸q’¡£{¦˜˜sª‚|ËÀÀ»qŠ£‡‚ž|–˜ˆžÀ½‚–œÁÀ{z‘ŒšÂ¿}k¥²oŒoÊz›w‘ƒŽ€vyyq{€†px…Œ“ylv‘be^xd_eb^thmdbXLVIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^__`_^^^^___]\SMPGUNA@?=6468266*&%#)*&.+*)109*#>H[L*#CP/#F[3PY/UAB;/8–£¸Ã´°¯¿©©”£¯©°¯­¦²¶°«¦§¥±« «˜›¢ œ›ª§¢«¢¥©¥¥´¤ž£“¦®¬¸´§¯£’’™¥’‘ ¡—› ‡¦«¤«­¿À±¡©®©—’Ÿž¢™£¤ª£“ ¡ž¬®§«¦£¡¥Ÿ¤¤œ­©‘¤›©­ªœ«­¢—˜¦—¢¤˜Δyz¥z––›_­]Ž¨€ ¡|§•št«‚€¯^dŒ©z¨‡…Ÿt—’ˆ³c‚«† ³j„®s|–‡¸a‚­Y£Ínu{Û{™q~ˆ’ue{ˆvvl}‡n}…‘~l€_pjof`_xd\qhjcf`RTSW^JOC5AHED8>6;@?A;=8@>??BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5478164('$!',&&/(&+360$7;SL+,-J0';[:L-!P@F4.1­ÂÀÀµ´°·˜ž‘£ª©­´«¦²­­¬¤¬¦°ª¡§›š¦˜œ¢¯Ÿ¡Ÿ¨§£¦¡Ÿ°¬›ž–¦®­°«¨¬ ”’›Ÿ¥“Ÿ¥—¨£ž®¤«°¨¿Æ³¨©±®–’žœ¢—¡ªªŸ•¡žœ­®¦©¨›¦¦£ ª’¬³–¥¢ªªž¤§§¢±¢“›§›¡›•”‘— p…Œ˜u„¨‡q°|r¬} Ÿ¥žw«‚}­œr­~«‡†Ÿv˜’{|—~ªˆ¡‹‘‹œ~«zˆ’Ž €z­VœÄzo’Á}•mupŒmfwe†oawnrnˆŠ‘ƒlŽdmsuo`fmd_ohjnfcWS\`ZRRC9II@C<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;92478452&# 1' 1''45-&7=WJ-<(=1)3V@F!G;C1-+¯ÔÆDz´Ÿ£Ž£¢¢­®¶¯©±§©«¨®««¦¢£š£–Ÿ¦«Ÿ¢¦ ¨¨¢Ÿž°¬˜›—¨¨¯¬¨§©ž—•š£¢’”¡­›§£®¬£¬µ©¹Í²­¦®¬–•œ¢™Ÿ®¬–¡™žž©°§©©šª¨£¡«›¯±¢¨¬¯¦™¦«ª«²¤“˜¤¦›•’…¤j¤u‰z©uz²q‚¥‰˜Œp‡Ÿš‡¤_`R«„®‚›u®‚§††Ÿz™—…{f€£‰¤˜†£}©”†®^|¨U¢’z£Ÿ€{ïŌs¯´³¹qb©¯ÂthŒŒ—Žl˜‘nlxxwnkfddqpf{ic\V_iXXTLLQLCCAB;CA@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799664,&$" ('"+-"$.!3-&@DWH,G+56*1PKL# A9D4,'ÂÉÕÖÀ¡™«¨¡¯¢Ÿ°µ°¯©­£¨§ª««©¤¦Ÿ›¥Ÿ¦§¦¤¬š¢«¡¤Ÿ¯¢ž›“ª¤¶°® ©›—•¦£š¢¨Ÿ ¦œ°¦£¨±¬¶È²µ©¬ª•‘œ¢™ ¥´š¡”œŸ¦ªª¢­™ª¨¡¡©¢³­¢ª³²¢œª¨°°·¥”—¤¨™’|ªlž„‡u«y|°n‚¤‹ˆŸ–•ž•Ò·´¸É€²^_”©ƒ¤‡‡ z˜•™xªÉs™£”¨©“šŒ~š‰šÆÆwe¡‚¥sŸŽ‚}¯^oµc±uK£†m§G‚“dŽœ’{o•}nyt|zm[ejrqfj^aXcm\^YILLKEDBB=A<B?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75785/)(%&%$&),5FNPPMFLJVF*L0/>-4NTQ;<F2,$¨¤Áƹ­©³®¬¥¢²¹¬ª¡¦›¨¦«¬©¦ ¦¤˜«£Ÿ®¬¦¡¬šŸ©¥§µ £˜“¨«¶²¬›¦œ –¦­’šœ§£ ª¦­¡£§©°´Â±²ª­¨”‰˜¥›¢¤®¥—¡•™œ¥¥©™®œ¬§¥ž«£·¬ ²¹°žœ¯¨´´´¦–˜©¤›¡‚NxšŸz„£|‚¤„†¦žœž”„¸{|y¹‚ÌÆöw›¡‹Ÿ~š–—‰vŸ—Š¤˜¤¨~°…›„ž„¬}™”a¥l£p…}—„r¬`¤rq€š`¼}RUuŽ‘£–{|‘Ž‡ryrƒ}p\lnwrjoZc_hnbd]LLQSAHGFI99K>B108856877-*5==?BDGILNPTWYYZ[\__^]__\ZZZYUSOH@772.,*.+*'&?QTVWWWYXXWUOTF<E2:P[T6?G,- Œ‡™©¬¤«¹«¯ ›¡¬³´¦Ÿ¡•¦¯®®©¦¥¥š£§¡²®¢©§² ™¨¤”¢µ£¤–—¢ªµ¹¤œ££“¡²™ž›¦¥¡¢®¬œ¤¨¢µ±Ã±­ª­ª‘‡‘œ§£¤œ¥—ž˜™™¥£§˜­¡¬¤¥—®¥»¬¡··®žžµ³¹²´¨™Ÿ±¢¥Ÿ‡ÑµÃ·y‡Ž…‘“€¦x”¢w‹ ’…¥‚‹q«†…´nri™£œ•‰Ÿ|—™†‡s®‚¥›¢¦‹“œˆ”šmp²\¥s“zœl™{™~n©a¢qqŸbs²¸hw“¤˜}Š‹ˆv{xlhwixsn€u]ddmmeh`JZWX<HF?T3@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^``]Z[ZXURRQF:2230/++(@QRTUTSTVWWXXWUUVTQOQ[U%!2AH#)%’rŠ®¿¿¼»µž—¨¤­¶¡¢™•£©§®©«™¥¡ž¦¡ µ§¢©§°£”«£Ž¤­¤ž‘ššª´´¤¦œ©’”—®  ž¦¤œ§œ´™¡ª£µ«Â¯©«©¢Œ„œ¢ ¦£•™šœ˜›˜¦£¥—©¦¬¡¤›¬¦½¬•¾°­Ÿ£°´»¬µ¨ª³¥©™{¨‘}|°wŠ¤¥ˆœm²o ‡­{¡ƒ¨–™€¬‰…®… ”¨¡¢—…Ÿ€™•€{’~«€š–‹ªx ˆ“’y¯]£|¦§dž€|—tk®]¥kq…™]`[Œ m”¥˜“‹“‰xy–~jl}b}tm€z`gepngghBY_[=JS2T8BBC7$$3+''3, /667436:@CFIKMNQSSSVZ]_a`aaa^][ZWSPONI7052.*,ATVVVTTUUUUTTUTSSVWWXVUVQHFIJ#((¼’š„©ÆöÁ´Ÿš­ ®¸¥£Ž›¤£ ¯®©Ÿ£ž­˜ž¹ ¢« ¯ªš­ ª©¥–‰š®°¬¦ ¨›­˜™­¢¡¥¡š¥œ­˜ ¨¥¶¨¿®¤©£Ÿ‹€››Ÿ¦ž’”™™“šš¤££˜§ªª¢£ž©¨¾¤—ì«£¢¬³»¬°¨¢µ±ª¬™v¯~Šœ…‡}º­‰˜d°Œe•­}¡ƒ§–›­Š„°…¦™£¡¢‘… [lj³`­{{‚€²lgn™—‹ˆ±[}´[¤ƒkÈ¢eŸ{¼YvµZ²}R¯€z¬X€¡m—Ž§šŠ–“”yx›|cs|aƒxs€|aifpmfeeOUc\AT^=H(>9=4!!,$2. *1/04579:<ACFHJLNPPRTWZ^```ab^_\[XUPNJGC553./@UYXWXWXXWWXWVWWWWXWWXYZZ[\XWWGB;ҟ³±·½»´Á³£œ­¦¥¶© ‹™ Ÿ³±¨ž¢Ÿ´˜ ³¨ª«ž°­ž«š”®¨¢Žˆ›Ž¯¬©§£¨™¯“š©š¡ž¥Ÿš¤£¥™ž£©²¨¼¯¥¨žŽ|Šš–¡ ™‘™š‘™—¨žŸ—§¬¥¤¤¢¤©»ž Æ§¥©¢¬µ·®¯¨ ½¯®®—©’£®Ž›€†¤—˜€¸ÃºƒŽ“„§˜‚¬Š‚¯‰§œš¥«‘~սªb£¿½|~£‚ƒ×º·µ…“’‚ž½¾„j£o«„nz²±Çƒk«°½¬xw¢¾»t€•¥›™Ž”šw€™yb|zcŒgx{`kekjaPb[Si\@T`BL)<:5/$%2 $(0496678;>ADFGJKMNNQTW]a\__a^`[\YTQMHC><A?5=SYYXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ»•´´±¿º²½³¢®¦¥³¦Œ˜¥¿©¶°§¡¿¦¦±›ž±œ¹¨Ÿ­®¥§”“¯¬—Œƒš‘®¦£¬¢¥œª ˜‹£“¦ž§œš¡¨¢™ž ¬¬©¸­§£š—“{‡˜’¦›“‘˜—Ž˜”¨™ž–¨§ž©¦¡¢«»ž©Å£ ¯£«´µ«±«¢¼©°°›tvª¤¶…e‰Ÿpg¬Šmow¤š u°š–pr–¨£›˜®¤rlmleŠxnm‚™q€zipif‰–•—qhi…†gp†d]ŠcioY]g~x¦`br’ofd€“Ž¡—–—Ž”›{†Ž”te†wgŒjx~xdlcflbKeWJkY:PdDP'J:+# ",)-2.5:457:<?ABDEHKLMOQSV\WZ\`_a]][TPLHD=:AB7MXYZYYZYXXYXWWVWY]^^]\\\]^]^][[UW^¨•­´ª»º²³ª©¢®ž¤³ª˜’½±Ãǽ´©ž¿«¬£ ¦«Ÿº£¤­¬­¥•­ªŒ…•—­Ÿ¥ª¢Ÿ¤¤ ‘‹¥’§™©™–£ª –œ¥¦§¯¹ª«š›“’{ƒ•¦—Ž‘‘—“Œ—•¦“–§¡™°¦¢¬¹ °Â¨¤³¦¬±²«¯­©º¥°¹—‹¡©¥¶‰–¢˜†©š”“ª³™›£¬¡´—£¡ž¡¢¡¤¡•«§Œ’“Œ‡’œœ”™“˜Ž•„¤š—•Ž‹“’Š†„~g‹€tƒvt‡Œq§m|•’”“Žœ“Ÿ”–”ž€†“‹pgŽvn‰wu|yikddocU`X@iZGb`NX+E=+&!640/!%2(*799469;>?ABDFJKKMPPQWUVY^_ac]^TQJEC>9=@ASX[\YWXXXXXYXXZZ[\^__`^^^__```_YY`¥–©©¥¶¸®®¢°¥­Ÿ ¶±ŽªÄ»Ä¹·©¡¥›¥°¨£¶§©µ¦§—¬£‹ˆ‰œ§–¬¤¢š¨žŸ“•£—¨š©™”§¡¤š§™¡´¹§ª˜š{€“Œ¡”Š”‘•Ž’—¤Ž˜§ž›µ£¦¬·¨¯Â®£·§°¯±®ª«µ»¢±¾š’¦¤¦µ¢’¦ž©Ÿ’Ÿ£¬°›¡¤²ª±™¥¡¤ªžžœ—¬’š¢›”–ª™˜˜––ž‘‡ •”…’Œ•‹~f‡u‡vyˆ„tœj‡‘••’Š}Œ–’’—‘ ‘›•ž‚†–…xq”rx‰~q{~ind_pi`[_YmbP`dOY9GFE=2<=8/*&+)&&406658:==?AACHJGJKLMSSSUZ``i`eVPJACB;9EMV[^^[Z\[[[\]]_^]^_`aabaaa`bbbdb\[c˜•¤§£±´¬®£©§­ ¨µªœ£²º­ª«¡¢™zœ¢°¤¥±©–›¸¦£“—©œŽ†Š‰›¢®Ÿ¤—¨ ¡’—™›®‹ª–¨™¨Œ˜¨Žž¸¶£¥˜›‰y€’Œ›“Š•‘“Œ‘–¡‹œœ§ž·£ƒ¯µ¢°¯t¤¾£² x{¡¬³½–w®¥ Š€ª~d\bvŸŽ¤ƒ—~n“³œ£¨¯«¤eŸ ”tzš—q€™©˜l€£¨Šeœ¥›—˜–‹’›„š”ƒ’‡ŽŽ’‰…wkˆv‡q|†€ai‰‹•“Œ[v•‘ghŒqz£—–dw—†€v—h‚‰‚ny~jpe_vokkg\ecaaoRZ=MMNRF=@TB91/&4:306678<;>@ABFHBGFIKLTUUY]`hggXQI<DG<9VR[`ab`^`_`aa_\]___aabcdabaaedchd^]fœ–¦£¡°±¬«©¥©­¤§­¥’–ª´®±¥™©¦ª—s‹¯Ÿ¨«§“–¸  Ž›¤ž~ˆˆšž¬š¤•¨¢žŽ—‘ž…t®‰¦š¨‘–£ˆ›¹³§ ˜™‹‰uv’–“Š“‘“‹“Ÿ™ž¥˜›²–€Œ›µ´Œ’½§¡~§¢{¤°¹‚Ž§Ÿ„‹…±©¯Œ‰–¢™y‹¬†œ¢¨«©ˆ•‡™w¥›z‡œ—§‚{²zŠ†Ÿ—™”˜–––„™šcy‡„’‹ƒnqˆzq€††t‡…–’x–h“t št{™‚žš„˜}‘‰‚˜iŒŒ„jxzppgdwmilj\diier[\HTLQ@E5-YTT6)!09=>643568;:=>>?DI@IEJKGRXZX[aahfYQH9DK<>bV^bded`aa`bb_]`aabbbcfgcba`edcgcaah˜£Ÿ¦®®«¨¬ ¨°§§ª¥™”­Å¼¯ •¥¨´ƒ«œ¦¢ ¾ž™Ÿš¡|…Ž™˜ˆ¬£–¡¡’Ž”‰†€‘¨Ž‡¢œ£“–†ž¹±§š“…pu‰”Š”Ž›‹Ž‘•ž£”¬ˆŸ´‰´š®‹Êˆ«¯‰·…°ƒ²°…©Ž§˜|¨r{w›Ž¦–h•¤y´‹ŸŸ§©“™Â‚«ˆ˜¡qž€š¥}—…•²€¡} “Ÿ˜—€Ž“›‰˜’‹|…“†”“‰ƒms’†€{r†„}…u†‚˜Åf€©‡¢jž—€™€Š‹ƒˆ˜o’„gwt{vghupghk^bnlflXfF\QL2E46Mac7&4<DGD:63658;8>==>BL?NIJKCPZ]\Wb^jl\QE=KM@JdX]cghgbbbbcc`_babcccdiicbbbecafcbbi•—¢Ÿ°¨©¨¥« ¤¹±ª«§š”ž¢¤ª¢•¤©¶¢¯ ¦œ¥ž‰”½™“ ‘yƒ––‘ˆ«™œ›š¢…Œw›œŽ ‘ˆž¤›•˜—†¢¸¬¥™›bm‹“ŒŒ—‹‘ž’ž ˜ ¨~¡§‡­ –® ž‘†‚ ¬±ˆ¤Ž«šŒš~¢u€˜“k«tM«x‡’›©©‚ª«~„¡{z§iž’lg—†˜¶‰ž~n`cXƒ—Œ{dg‹s™}y–k]|—n_Sq…\`lyƒ`Ye‚~„˜q§ªkƒ£nr¥pŸ‚œgdžlZlˆzeY_‚~aWPovemtqjjn^jolkhWgN]XE9@4GD^k4+ICQMN=84859;6@;;>BO>QRLMBJ[]_W^_bv`ME:MOMTb\[fgiibbdaddbab`bdcabjkdbddgdbgeach˜– ¹ ª£¦¬‘¡¶¼«¯¢™–Ÿ ¥««Ÿœ­´¢§‘ ŸŸ¦›™˜´™‹žŒ•‹u”‘Š¦––˜Ÿž“…†¬£‡œ‘Š˜©˜™š‘‡¥°¦¢•™ˆ‰€inˆ‡‹ŽŽ‰‹Œ‘‹‘ ‹’Ÿ›¡¥“£¡” wœ–§ƒ¢¨€†«¯†¥z‹}„š}¢pr’‡–{žŒym‡›‹™‘œ©œ‡|‚¢sv¦fž~w¤^˜{}“s¢n˜·´ºs’‡€¶¨dÆ¸{p•¶Œq€›¤ct¬«`}j³~n}‡ƒ‚‹—q€£ls¤sž‚}£^œ™³–o{—ž³tr[ž²‚ibosuqhnXkkrrd[h]bLD=D5QAZq2<RF_JS=<395::6D;;@IP?TMNQ@E_^[YX``|dIC8LWUVbaZffkkbbeadc`ab`dd_`cknccddhdbgfchh”–•£¹™«œ“ Ž¥¸¶­® š¡›¢£¤«›š±¬«’— ˜ ¤™š”ž«›‹ˆ’x‹…p€–Š¡“”—}‘ŠŽ¨ ‡˜Š’¢“›šŒŠ¨§¤ž–‡„~k{‡~}ƒ‹‰Ž“ž•›Ÿœ Ÿ‹‰wœ˜¢ r¢‹ˆ©ˆœ§‘—©¬€®Œ}z ™y£“x€s—ˆŒœ}–Ÿ†›Ž™œ§‡£d¡}‰–›Œlžhšnš™{€Š§}rgsªƒ‚sªg”š]›…v„hªj¸f\©pœa•Œ^§vv‰Š€hšu‡“’˜Žžm™j¦™\¨~w»j}©ZŽ„]³g\nqxwki[piwxa_fWbBPEO7VBRn4JZY^NZD@151;;7H?:CGU?XRX]>Db]V`Qac}jEB9N[^YdfXfgmmbbe_aa__``ec^bdoq_deekdcihgki•œ‰ª¶›¨‰c•œ¬º²°¬¦›š§Ÿ¬™°§«—¢™¡Ÿ™–– £™†‰iˆ€q{—ˆŒ–—„’”˜zŠ„–£œ‰•†‹‘œ›ˆ¨¢ŸšŒ‘Š€€i†y–Œ{ˆŽ‡Ž•™~’¡ž ¢“˜rhŸŠ Œp’Œ‚©ˆ™ ¤©¢©}°­¤¢¸—v£³¢£ˆ”xz«š~¢žœ˜‰˜r¡}…°µ}kš‘¡x~˜´££«¨„˜{š|œš~sªZ]o{—‹xžbL{{…dz˜BMŸY¢jr|ŽnŠ„™v›y‡‰±³~š’¦t~mq|”o™ri£]•vHec`sp}}nf_khu{bc`Q^W\TV@YEQgERV\aX_ID=B8@A:IE8LEXAVQZVDFa\Z`K`m}rEC<U^bZejVhhmobff^a`\]^`hb_edvl^egfldelhhki”±®™„S_¡§´º³³©š¢‹š©›œ§’ «£ §žœš™•˜¡–‡‡‰w…ny•…š‹}‘“–ˆr€‰’ ›r’ˆ™”Ÿš„Ž¨›™•ŠŠŠ|„l„…q¡Œx…ˆ‡‘—“{‘¢Ÿž£ˆ®†}µ„ž{¦–z©‚–ž‘‹¢ž~§hwm~™s sq|…˜o“‚®}£ƒ§Ÿ›¤p^©hu£co¥aœÓ|z™xrsc¢…~¢r¢Žuk³‹`‚˜Šsª²§¼wƒm¿¦ª´^œo~r—os¢r^¤gt¦`h¦lšÓ˜z‚›nwy—k›yv—rl©¥g_dyp„kgfcmuwf_aR[fPQaHWIT_WS[dj[eQFCKLJKBJE8P@PMXSXORQ`eeiRdxywJFEc]eZhjSihjocjf`c_\]]_hbahe|d^dgdkdjlfhlh˜›°¬T\K~©¯²µ°³£œ˜„—¦  £Œ¤§Ÿ—¨‰™—˜“™“‘ —Žˆ…{p}„h}ƒ“šw‘Ž‰p‡“’l˜”|‰‘’£•ƒŽªš“’Š…‰y„wˆ€nž†w€’…‡˜ –y“¢£š ‰³¡¢¶‹z¬§¤®¥p©€›‘†“}¤€¢™†˜qž„¢­®‰—‹€Œ¤•ƒ¯¢”vµ¶µÉ¢t”‹‚ža—©my•‡Ÿšu¡‡w }–ŠoLf£’pšˆs¥{ytbƒ‚l~ lrd`œrt—k{j´µ´Æ¦s˜~zœjšš«tšmsw—i™yt˜qPD}³^jujx‡fkgbttpmV]SYhORhIULXRV\gknUgWMJAJMJHJNAQJPdcimetrs~x{nu‰{{TQOm^h[kiRjhilgmfce_\\\_ibdhk{_]dgcjfnmeile¢œ‰¯§…f?”¡²¬¯¯µ¢¢–§¢¡£‹¤¦œ›¥š—–—›“Žˆƒyjy†eƒŒ~–ŸyuˆŒ‚i„…’ƒŒ…zŒŠ•¥’‚—©—Œ‘‹€‰z€}‹yp †y”†ˆ•ž•“¥§œ––„gnxœl¢d|q¥xœ˜ph§‚˜|¥z –ƒ–rŸv€‰”•¹nŠ¢b}™¢–‰nsj«ku mo¦`›i‹i–‡š•u¢€}š_‹…Œuoˆbh¡eži›updgˆ‚ns¢Z_[d¡n]‰Œp{trd¥nx¢df§h—r‹˜n¡oRˆn ^d§T‹]T˜mmrjqmphkxskoQXVVfYSmIXO\HXhhsjYkVQREV\LXRaUhj^wuz|p||r‚{sv€ƒv^QsagbqgPkhhklohdg_]]]`jbiivu]\chcjirlfkmc¥™¦zetm‹§®¥ª±±¦Ÿ‹–ªœ¤‹¡¡™¡¡€•˜“š‹—Ž‹{†q€ˆh‹Š|—šst‰}|eƒ‡•Š‰–™‚|ˆ†–¦¢«…ŠŠ}€€Žsi¥„}…“Œ‡—ŸŽ‡’ª¦ž‰¦x–œ~¥‰–Œ²™ž‘ƒ¯—Ÿ¥y—‰z©t¦„šn¥¢Œ’„Œƒ¼n}¥¯‚‡†‡”—¡}¦{r¨” –gž~o¬c–Š•’w¨l©¢‰v‡‚w«‘¦ˆk‘°kv³Œ©l‹†nnŸž‘•b«‹ªw€Ž§ŸwŸ}…¤• iš‡u¬fž­Œ¶sv¾Œ¤“Yƒ¦«auqso{tqbj~nhlSVZVa`\jL\R]I]lmv`[qY[`Zgsenoqcqt`wz~yryƒrƒ~{{Œ‚€vbyddnsdRlggomrifia_^\ajbllzo\\biamiwmglnb•¦ª€ž¤–ªªž¨§®£™ˆ–ª™£‰š¤œ¨„‹š…œ‘…’ŒŒt…zˆƒo„}—“su†r‘ƒn‹’††”}{‚…—¥¥¥€‰„”uƒ‡’ol‹¨€‚‹“ˆ›žˆ‹“ª£ €t”—ˆ~y”¯¤‚œq†y’Œ…€{r§Œq}}z—–›„x{~~ˆ”•“‹w‘™ ¡„{~‰kŒ…[yysypin~’‰qt”“q…ƒ‚e_€Œxvt”uo{on‰n„†_wixŽf‚ƒ†ªœt}—j‰ˆou|„umlfŒsw{—w„[jXyhnwrqowxo]l†migVZ_W\dkdUaU^Q_owykjwejjju|pqtsaoubs{xuzu€y‹…‚}{mldyn^Wnghukxjiid\`ZcielqunZ[bkdkkymhloaŽ•º©§‹¡¢›¦¤™¤«¢ ƒƒ–ª‘ ˆ™¦š¨˜ƒ›‹~–”‡ŽŠ‰Œr‚|}~„z—Žtr„p•†{}’‹††…x~€†˜£Œ{§¡‹…„•‚†Ž˜wq„ª…‘œ‡ž†Šš¨  «ƒ‰Ž•›~Š—­¨“§xqž“ƒ{“p©†p}•qjo|Ÿ‹’Ž‹hn]„ŒŒœœ s•Œˆqtk‚vt€Yrn†}~‹i]icz…ƒˆ€_ix{œ|ƒƒv‡ƒiyŒˆkbqsƒw_r‚Š¨–‡gƒnw‹‚oƒ‹wndfcy‚z•Z\ifnv[zxwtmsr‚f\mŠkkbZY]YXkq[^`Y^]fr}ztotcjji{|rzwtdmthl{~uz|{yy€p†Š„{}s~zrhT\rilvpugkgd]aYjhkjqrmW[enlgryohjm`ŒŒ«±¡£¡šŸž˜ž™©£¡}‚–«Œž”‡š¡¤”{˜„|’™ˆˆ††Šr}€‹v…‹„–Šro€r™‡„~’ƒ„†Šz€„‹šŸ‚¦ ‡x—ˆ•‹‹œ—„ƒz¬—™“‰œ†‡¡«Ÿ¢¢£‹ˆ“›£™–ª¢¨§¡“œ‰˜|y…¨~~’‘’“œ±¥š”±’˜„¦ŒŒ–œ Š‘œƒ‰’Šk|Žvwe‚†Š|‰„‡‹‡ˆ€…„w|{u›£‰ˆ‹Ÿ‹†•~‚vqt†…x‰ˆ‹‘§‘„‡ŽˆƒŒ‹{…‰‡€ukƒ{y™irh`tŠp}zwvovs]]o‡gn__Z[\RgqUc[[alht{|rnpdjih{mx~phoplf€{r€w}„{mƒŒ†|zx|~zƒxNdvjsnq{ekebb`[sfpfrqlU]ltmhxzpgikeˆžºŸ–¢¡˜•™˜”˜¤ {˜©žŒ…ŸœŠ–|x”‚{Ž™‰†ƒ„‡mx€r€‡}‡“„mk~z—‡„ƒ~€†„†}‡ƒ›‘†©ž‚qŠ…’‘‹œ‘}z©ƒ‘—•Žœ–……›¦ ¢š†„“š™™™¦ ¦žž—‚“‹x}ˆ…¦||‘…˜ª œ“œª‘€ž‰”šŸƒ˜‡Žƒpx†qta~„†uŒ˜€‚Ž‚†„~…„•nyvu”£ŒŽ†›……Žu€‹}}ss|‰„{y…“¨‡„‚ƒŠ‰‰u„†‡‰{nj}{mhklg^y~g|{vtuuzw\`p}mu`cZ[^QfmSeZ]akiuz~pkmckig€krkjsnxnƒyn†€v‚€}…vr‚‡~{z|€{‚‹`i{kuhiƒejc`i[cuhobumkTbqyeoyzrejmm‹ŠŸ¸š¡¤Ÿ“‘–—‹šŸž{wœ¥›‰†¤”Š˜™xy…|‰‘ƒŒ‚‚‚l{xr€„|‰|kh}‚—‰ˆŽ|~†„‡|€››‡¦œp‹ŠŒ’† ¡Š…Œ|§‘ˆ’–“–’vŒ£ ¡–š‚‘š™“š¢¢¤›˜‘œ†z…ˆ¡€~Œ|—¤  ’™¦Œœ’Š“—œ~““~‡Žvt‚pv`}€Ž‡rŠ–|‡ŠqŒ~‚…†hxry™“€˜‰Œs‚ˆ}}rz|Œ…{{’Ž„—¦”Œ†‘|…†‡…t‚††ydqz~xypljf^}sh|uus|sj^`tvpwdcX]^RjhTdX^ahjvxqfkclhe€jm}gmpj}w…zk‹r}tv‚Œ†|z€}jrƒntibˆilb_qUtomn`xhlWjtvbuz{qbkoy‰Ÿ³’¥¥Ž˜† šœ|u£Ÿ—Œ¡Šˆš•x{†‡~ƒ‰~ˆ‚p~ztu‚„}ˆwgc}†—‹‚Šx}€ƒy–€•—••Ÿš}o‹“†¥›‡Œ‰ƒ¦•„’Š•—’‘v¡¡˜”˜z€˜——š¤ž™“”œ{‘‡„x†—Žž~‚ŠŽŒs—¢ž ’˜Ž¢Œ‹ƒ˜™„“–š˜|‰wr~n{d€|‹†p†“€k‡ƒ€‰…fvo}ˆ“™Ž~”yŒ‰}€ˆ}|r€yŠ†z…’ŠŒ™£—ƒ„Œwˆ„‚vz€‡„t_ww|s}wfkc`~ijvstu}q|ccasnurmaY_]ZkdRbW_`iluy†pcjclfh|ƒkhthloh|xm†q€‚‚t|ƒŒ€~z‚ƒ~|mu‰ttmeŠljacuVƒipn`xglajvpfy{yq_ql……®˜§¨žŽ—‡…Ÿ“–˜}v¨›‰˜y–œ‹Œ˜x{€‹}|ƒ{€‚xsxys}€ƒˆŠ€d^}‹•ˆ~…ˆt}~Š~˜„–“–Œ£ —~q‡{“‘Š¦ŒŽŠ’ ‘ƒ‘“—Š€Ž— ›’’tŽ’”‰ž§™˜Ž•˜u‹m†™™{‡ˆ‰o—š¢“”ŠžŒ†““’–‡š‰|ŠŠzrzkul{‹~n…’ƒ“wo‚„~~‹€esj}—˜…€Žt‘‰„zˆ~vx~‡}„Ž†•¥‘y…‚t‰‡}rt†‚l`ztyp|oanbd{anovswwssav`oluno][^]]j]O]Wbahmsz‰k_jejchwˆmflhilg€|zwo‡s€ƒ„}t†‰zƒ}z„}}Žry‹yxnl‡kh_jrc‡hqoevgmlazhk|{xpawm‹™šª¡¤©žŠŠ‘†ŠžŠ•—}v¬—Œ–|ž“‘–”ˆv}{Š|{€vw€otszo…}€‰~|a\~‘†€„„sz€†z‘‡‘‘›’¤š“||Š’£ˆŠ—š…‘˜“•Žˆˆ‹’”‘n„‘‰ž™¢¡——‰—’p‹›…g‡š”z‰…Šp–š“¡’’ˆ‹™Œ‚‘ž}’“Œš{Š…‡tsvkqnu|‹tn†‘Ž’qt€|‚‚ˆ|eqmz~›”~…Šu‘‹t‰zo‚ˆ}…Š†Ž–ªŽ{ˆ}~‹…w}pn„‚bgwstnzb^pajt^pjzxxlrpey]mlsmsXZ]_ajZOWWdcfqqˆe]ihgbgqndigeig€zwuoŽ„sƒ|u‚ˆ…x…|wƒ…z€Šw‹{{ryƒjj_qiskqnmqgoke{bnyvpkvw‰£˜¢¨¡§›ˆŒŠœ†“œt€©”‘† Œ•“s{v…wxrs{…kroym‰v€†nq[Y~’ˆ€vu€ †Š‘œ— “–w‰~€Œˆœ‰†’—–…ˆ”˜–‹‹ŒŒ‹‘„n‰‹‘Šœ–¡œ˜–†˜‰l†¥…g‡žŠ‘~Œ„Œw“˜‘‘ˆ‰”~~˜|‘Žš’}‹€ƒovplmop{†isƒŽ˜Špw€u‚‰ƒygsov‚›}Š…{•’zwŠuqŠ|‡{‹‡…Šœ¤‰|„v‹€wxmi\qrqooxZ^paoj^oi|zpmmjmw`pokqmYX`aamWQSYefbup„‚b]kmdcfk’m`ff_gktqrp‹€t‚€yv€‹€y†w‡†vƒ…{‡Œ€{vŠjqc}c…|opltjhnlvw_q~y{tus‚~¥•š­Ÿ§–…Œƒ~–”ƒžt‰Ÿ“’…ŠšŒ•‹zrwt‚pr…squˆlnlumˆwƒ}mnUQ«”‡‚y€vr‚y‚ ‚‘’‘—›‘™wz‚Œ’¤š“Žˆ•˜’ƒ†–˜‹“‹ˆŽˆž…‘‹}s‹…ˆˆœ™Ÿ›–•€”€i‡ž‰h‡¡ˆ’„‘„Šqƒ‘—šŽŒ‹w{“{Ž‹’—|ˆ|kwjnklmzby~Ž–vzwƒ|zhumuˆ–Œ‰‡{”‘rz…qxŽ{‹{‰~„Ž‘ŸŸ†}}x‹}wphk€w^womkqrU^obqa_mnypgpfftuhqlawe]Ve``rSPN[ed\xpˆ|^\iqbbef‘i_gd[go~okqsŠ}v}…€uvŒy{†€xˆƒs†…~ŒŒ„|y•xfqk„`‡~ookz`imtt_t|x†wss…|y¡š±œ¥Ž‚Š‚™ˆ€‹~Š˜’Ž„ˆ—ŽŽŽ„vtvs€po…spqƒojium‚n}|musRN‚ßɒ֓|otƒuƒŸ‚‘v”˜›˜{“r…Ÿ¡““‰’›“…}••‡Œ‡’‰œŽxzŒˆŒŠœ›œ›–”zŽwiŠ“‰m‰¤…“ˆ˜ƒ†cŒ‘˜”‰–‹‰‹pz•‰|Ž‰‹“‘Šz…|m|esoklzy\€yŽ€{}~†Ž{ziuktŒŠƒ††}–lp€Ž‰~„{ƒ‘–››‹}wx‚ysleo~‚kitoghsmS^ndpZ_krygkkbgxsoqd_w`aVk_^vOMK`ec\yqŠt\[eu`aeeŽc`fbXirsmkqv‹|ty†‚vw~‹s†{‰r‰‡‘Šˆ}~™vesn}eˆopk€Zknyys`vz{vrwŠwyŸŒ›¯› ‚…xˆ”~|‰œ‡„žŽ…Œ—„“Ž‡twpypn„omn~rcdxp|nz|jhlc¤šÁÜ®ï¢skuƒu„¡…‘n•”Ÿ”š‘p…‹£—‰Ž•Š•ƒ€”„ˆ€’ŠŠ—~‡{u‰x†…Ž›š—™v‹wpˆŠŒ~Œ¥…“Š…†^‹”—‰ŽˆŽ‹Š„‰l|—‚}ˆ…Š‘†v…~~k}cxtjoxsXˆz‘‡…z€…Œ~zftj‹‹„„€Œ˜†l‚wo‰’ƒ‘…‚{‘—“™‘utx†vsqftxasmoahufR`pgkU^mtzarc`i}qrn[cracWnZ\wMMLcea]vsŠm[\dx^`df„_cc^Yirknkrw‹}sw„xx|‰qƒ„}}ˆ{t‹ˆˆ•‡Œ˜shuqymŒ{ntp€Wpyvyqdvx†Œiv€Šr€ˆ™§œ£’„|pŒ”xyŠƒ„ŸŽ|•€™‡„{rwpsjokil|t^`xv{ptzg`e|ëÚµÉÃ܉sls€vŠšˆi—Žœ”’ˆp…ˆ Ž„Š•ŠŒ—“|’ˆ‚ˆz‘‹†‚€wxƒ„r‡‚“›–”˜†v‡q†ƒŠˆ›£„•Ÿ„‰aƒ•…ˆ†‰Œ‡€‡h}”}‚…‰ŽŽ‚q†~rwgvritwlZŒ}’‚…}€ƒ€„Š‚vbumŠ‚‘Œƒ€“’~nƒmzˆ‘ˆ“…}‚~“”‘—‰orzŒ†ulpjqw^shn\iu_RdqhfS_owu`o`]h‚qrjWgiciXmW[uLJLef^ars…h[\ey^^dgzad_]YknenjtwŠ~sr~{vz‡t…ƒ|‡wvŠ…˜‚‚{“vlwvyx“unxz}Xy…q€ogxv‘‚dv†…qŠ–†™¡›¢Š†so’‹rvŽ›}‰™ˆ‰{Ÿ„™xqtnodr~hflww[_x{zqqiagaÕ¶Ž‘§xnqw{q’‡j˜ˆ›‘‹†{h‡‹™†’††—{ŒŒ€€‰{~‰…zu{ƒ{q†€•™Ž’”‚‰u„ˆx„€Œ•ž ‡– ˆa“‡ƒ‡ƒ‰‚f}‘€~‚Œmƒ|‚tkmwutwvkcŽ„|„…ˆ~p`tr†}Žƒ}€’Šzq„g{…Œˆ„|…•‘“…opy‹tmnijx|agiiXkuZRiribPbrymbe^Zjƒnsb\g_em_nTZoNHNfd\fnr€kZ[cs_\clwde]]Zllbmjsv†€qo|}tx†x…ƒ|€‡uy‰’•|‰†v‰pxy{„“om{€v^ƒtmizs”sgrˆ}r’‘„šŸ› ††uu”~mv“—}‡ƒŠ™|Œšv~vqoljat|gbiuyZ`w{ymq~echhW_rs—¼Ä„vq”ˆ~r–‹†›’Œ‡rjˆ–€{”Œ„šŒ|Š…|{‰‹”ˆu‰†vw}ru†ž”…”ƒƒr€Šv…|Ššž™‡•‰f}“‚~„ƒ‰‰r}f~Œ|y‡‹}i€}ƒvfoyxswslkŽ…ŠŠ€x‚…ƒk_sy{~Ž‹†|‚~s‚iz„‰Œ†…y„}‚™Ž‘Œ~nm{ˆ}vsngf{ub[pbWnqSSnshaNftyf`^]Yo€osYeb]jn`pOYkQDSg`Zjnm|nY[^mcZbowdg\]`kicljsvƒpm|tuƒzƒ‚|…v~ˆ–x„‹tˆryy~oo{€qixz~ml{u•kjx„tl“…Ÿ˜ ™„ˆn}Œvjx—Ž~€‰‚”—‰y–ozsplid`szh_eqzZ`r|ygqzaee±²wKbZ¥ÚЖq{Šx}“Š„˜‘Œ…nk…’‘zy’†„˜Š|†xw‰Š„–€o‹ˆqu~zjy…ƒ¥„“ƒo„w„y‡š•Œ”‘•…ˆp{’‚|‚ƒˆƒnwh€„xr€ƒŠ‡|e}„ucps€iypou™†ƒŠ|vx€…zj\rs‚‰†Š~‡Š{‰r‚nr…ˆ††s„z‚šŽŽ„xno~„vydgi{p^XvZXplNWqsg`Klvua^\ZYt}soWg]fjr`oNWhR?Yf^Zpkhzq[ZYkeZcqy_h\^elhekiqwˆol~€uo‚{€‚‚v…ˆ—Šq‚q{†|zy„“Œujzko~t}or{z“poxg’‹ƒ¡™œ’‚…f†ƒogy•ˆ}~„˜‰|Œixrkkf_`oym_box\dk‚zaqv_eeÔ꽋2:>‹Žqx…ˆŽvƒ–Œ~’Œml…Œu|…•ˆ|‚xnv‡„ƒ—wnˆ…lu{tfy‚ƒ§‹‚Ž‹„~n€uw…zˆž‘‘““Ž‹‡{’†w~ƒŒ‚krh€~xm||Šƒway„‚rdqh~nuqu‚›‹€…€su~so\nuy‹„‹{‡}‰y{rm‰„‘…Œs‚z€—Œ‹tmkw€€tt\hgvoWV{RYpdLZrre[Iqxo\[[Y]t~thYb[gfnciMWfQ=^e\]ue_toZYTodYdqyZh]_fmgikipw}Žmi‚„~yn€||‚zu‚“„p€‹nw}€{{ˆ“‰h{}js{r†{sw~Œzx„}|lŒ„›–Œ€€l}kh~‹z~~ƒ“‚~}Šˆkuqghb[bgso_aks`hpˆzbst^cd› n\5Z¯µti€ˆ|’†u…–†sŽŠ‰vpl…ƒ‡uy‰x‰|“ˆz~rgu‰~~˜oq†~hvynfy‡„¤‡€†Œ‰~nv€‚~šˆƒ•’™Š‹…‰|ˆpz}„{h~lj€{zjzw‚‡€r`vrdrgv‚mu{†•‘|‚owz|umYp€wuŒƒ‡xˆvƒ‰{ytoŠ‘‚†s~”‰‰zonjn‚tn]gdrpPZzM[o\O\rodUKsxiWYYZaq€t`]]`gdhifNZhM@`c[`va\tlXWStaZdorWj^bhkgmlhpw|“lh„Š||p~{‚zw€Š‹ƒq{ˆoqwƒ{Šƒj~{mwxvŠw|x€‚‡ƒ~~zm„Œˆ˜£„ƒzu‹xklƒ‡x}z‘€€~Šƒprqcf^Yf_oo_`gpfjo‰tato[adjv{€¿œ¦¤È¸q…ƒr’|x†“ƒs‹‡qroƒ{ƒtt‡tˆw”ˆyypcw‡z€“ir„vgwucj|‚ˆŽ}s€t…z’ƒz—–ˆ‚ˆ{ˆˆkxy~tgzhkysizv€ƒ}h`w‡~kjth{€ivŒ‘”~z~~p|v|tbVx~ss‹…‚}„q‡Šxyqq„ƒŽ€z~}v†ƒviqimˆqo]gaqmIduK]mUTZsnbQOtxaRXX]ao‚s[a]heedkdQ[pICc`[cp^\vgUVUw^[enhVk^aigennhpwz“miˆŒy}r{~y‚|v}ƒˆ†ƒpw„rmw‚‚~ŠŒ“p€{wyz‹tƒx‚„z€uo~Š‹›žˆ}…zw…{gt…Œy~{ˆ…ƒv€gpn_d\XeYmra``plkh‰natiY^dn€w©ÚªÇ†‡²q‰woŒu{†Ž€z’‰tst~w€pqm„t”†xuk`z‚y‰fq„pgvn[m|€“€y‘“~y|nˆw‚’Œ…u—‹’‡…†{„ltv~mgvdm{umiwv|abx…zhuub}{gu†Ž•{t€vq€{}m€ZWupv…ˆzm‰†tzlv„…|~y|t‹‚~shten‹ƒlsZi^tdGmmKZaWVVwmbPRtvXPVX^aq„o\`cmdd^ocU^rFBe_]fh][zbQU\u[ZgkaVj_`nefkqhpvxŽtkŽu~vx~wƒ{s}ƒˆ‡ƒor€tqu~…‚‰ŽŠ{w€xƒ{|…‡x‡|}~„€{~svyŒŽ ‰z‰vtƒx^}…˜‹x†ƒt…†„w‰zbnm\b[[aVisc`[gnof‡qaqfW]cl|Ê·¹¡jmmŠlq„q|ƒ‰~{‘„yxsyuu{jlvc„u’‚wof^}‚z‹Šer‚kjqcXmz…›ˆ‚s—”x}oŠr„‹Œˆs˜‘‰†‹ƒ{y}ppo|fhqbmxqjkqx}|z]ey€wivxf‚wgt‡ŒŽ”}r‡jo~yn}]Ysnu‹|‚opŠ€qwix€‚€‚w~s{u‡}{sgsan‹krXj^v[GmjLVT^SU{kaOTurPQTW^bt…i]`ljfcYnaYdpG@g\`f^]V{^OUdpZ[jh]Wh`^rfkgqgpsw†xn•Štzx~yƒ‡€ur†…Žƒpp{xvuz†…‡Œ†z|t‹~}†„„‡~~}‡|xvxx‘“ŸŒ|‹muxd‚†•…s‘Šo……zƒtcnjY_[\]Tgrd`XdqrfsbkeW[`jw¾®{ ¶nbs†hs{qy„{~Œ~wwrvo{vejo`‡uŽsjb^xy‹„fqhkkZVow‰£„q™“ryv„o‚ƒ‘ˆt–‰ˆ…‰…}xtqnhx_jl_mvjgjkywzvZg}|xer~n„teu…†–pŒgkz„unub]q}lu}Œ|‚fv‡}nqivy€s~m{|‚{yqflbm‰}lnWj_vUJijNQNhMX{haNUvkLQTU_fuƒf^aqhgbWi]\lhJDjYadWYUyYMVmjY]kd\Yec^tfldqgrpuxp™…v~w|…‡}us‚ˆ€•ƒnsy{zsr…‡‰ˆƒy~u~|„ŠŽ„‚„{~‹ƒ{v{wwš—zŠ‚†iv}{lƒ„’qŽp…‚~pflgX][\[Sdpd^WbruiupeebW\\h€por€s‰ddx~itusrƒw€„yvsunkzqbgkg†tƒnf]_}p{‰imygjdUWro¦|„{v–‘t}s}{o}|‘†xš}ˆ†ƒ†ƒ}uoqlgt\lg^ltdgeizo{rYg€vuhpx‚vbw…‹|”oŒjm{‚qgsfanzgsx‹|~bwƒwjlrv{q{zt~g€ywodfbn…|lkViboRJhjOKNoG^{faMUtcJNSWajv~e]gsif`VcWcp]LKjXcaUTUsVLXudZ^k`\Zce_vgmbpisorut™‚w€w†…z}t‚„~—…nst|ztq„…€z‹vt|•Ž€…„}~Œ†{~€v{£¥Šyˆ†„ku|zuƒ‹zn„sy„}ƒunjheV][ZZSbmd[Xas{ihmi`bW_[j€jkp€gk`hyxjstsmƒ€z|uunzhjyj_enhv„geXbwj~‡{ojpgf]UXogŽ¨wz|‘Žyvqptwzy–u†ƒ€…ˆvjquggn[lc]mr_gajxh{m[n‚rtjo~zwaw…„x…sˆroy€rcqi\qxdrt‰|yct€qhjzurmyxvyd„|ywqddcn|}kkUhaeRJlgOGQkEaxgaMSq]JMTZekvze_mqid]V`VnnWKShWe^XNUlTJ\y_[_k]][ce`yhl`oounpxuz˜}w€z€€‡†zxy‚~“„rutyvt„ˆ‘}€|ks•€{‚Ÿ…~‡}€†‚€Š{v„«Ÿzˆˆƒkryu€tn†n|€sŠ€jomddX_ZYZTajg[Z^t‚i^ml\aW\\lert}ii\kvugsvql„{}|xurlygixf]eshzw“ccTepg‚…wwgij`WVYgc§o~w€‹Ž{qr~hzp{Ž}xr„}†ndurdgg\ja\oo\g_mudzh]t€orkr|~uvbt…‹{ˆ‡€xruuapm[rtcqs…|ues€mam{pkj{yvsf†v{{vqebemr~jlTh]\TKrbPFVaGbwgaKToWJLXXgkuzdenqfdZW]XveTJ\bWgXYIWePHbxZ]_l[^\ac^~ij_ntxmpnvƒ—yr€|‰Œ†~uu†y‡Œ}tvu‚yzz‚ŒŽ}~„‰is–zŠ}~…zz|†ˆsq­Œ{{‡}eq‡ys|{urn…l{~lzbpobe]eVYYWcfk_]\r…hXpn[^XZ\l{cpwvmbZlssgtuolƒx~€xwnntdite[gufvv’y_]Rffjƒ‚t~bdi\TX^bc¤hxtƒ†ynp{iyn|†|vŠsx|xhdvl`f_^i^\skYe]oobze[w|knnoxysudsƒ’~‡ƒ‰{vpr~sbxd\ppbqr‚}tgr€e^nwiehz|uno‚ut}trb_fnn}eiTgXWSMw_QJYXHbudaITmSJMZWilq{bllscbZZ[aw\SLd]XiSWHY`MFiuX^`l[[_bb\„iganxylojvxmƒ~€“ˆ„vsˆtŒ†trwv‚w|}~Œ€~“~pw•ƒ|™’y€€xz~€tˆƒtp™¢{z‰”xdu‡xsxuksn~kx|p‘r^po`gblTZZWhcmf\[q‰eSrn[ZXX`lvciuji^Ymsplsssi„|€|vonldiqc[krduvŽs[WSear€r‚]bc]SZ`\c‘Ÿerq…„‘tll{npq{}}rx€szzzceuh]bY`gZ^vhWb]ohaw`[{vijrnxsruhq‚•ƒ‡~„vsjq}nfwX]lncrsztgo~[`prb`kr~mmusqxkpa\ellzagTfTVQPu[QOXQHctb`FUkPIPZUkkj|emnqb[ZXYlqWRPgWWhSTFY\NHruX_cmcX``a]‹jcdmyxkpiuy†{kƒ}„š|‚„y|‡n†qnwz}t‚‚|‹‚‚—tw‚“…Ÿ‰u€t‚q‡‚uo¢—s{†‹†{ewŠnmznfwpzksvrŒk^tnagekR][UgalkZ\pŒdOon]VXUgithbtee]Ymtmoutxj†||ˆvsddkna\nmcsx‡kZTVcdx}}q†]c_cTZ`Yc••cnpƒ…Štkh|pftxu}mzuvoz~u^erc[]VacXateU_`mdaq]]~phisqtpuvkm„“‰{…qsgo~qsoT\gkfqtwscmvVbrl[_pg~fmw~ssskm`Zdjjw_gTdTUPTmWQVSOGds_aEXiOHWTVmhd|ikwkbW]U[tdSRWiRYfTSHZZPMxvZ_eliYb`^^Žnafkyunoivvlƒ€}‡—{€‡‰~k“ˆrgt€{u€‚}ˆŽ‹“r|Š‘…‡Ÿ†{†Œs†s~‚vn¥Œr‹vwmzŒ`d{pfxrxlmqv‚gd{lcfghS_^Ug_ln[^mhNim`TVSngtkexdd\Xoslqzwrl‡{€wœzykaelm^`ojeqy~gZVX`lx|{p„_b^gVX_Wd›ˆbkq‡}xlkyn\wsm{jvtoo{€rXim^X\UabWdpcS^ahablZ`~kfksvomwwli…Œ‰{ˆmqfq}nsncZaiiot‚ts^imSeqeUcoc{drw|wkpmk`Yaght]eVaURNXeRO\OOHdp]cFYiMI_KXmd_xhn}d`U_T]u\TS`gO]aUSJ\YPYtu]_elhXca[^qcgjxqsnhvtzƒr‚ƒzˆŽ~|‰‡ynŠtls‚t‡…†’„•y~Œ‡‘›„€|Œ…s€stxro““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~}~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’’’’’’’’’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’’“““’““’’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ‘mfggggg}…„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDARÌÚØØØØ܋innnnojfggggfo„ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‘g_```_^yƒ‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR455552FØêççççë‹bgggghc_____^j‚€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}z{z|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‘ŽŒ‡‡‡‡‡‡‰““’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†…………†“”””””•‰ŠŠŠ‰Š‰ˆˆˆˆˆˆ‰ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z{|{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘’’’’’‘’‘‰‡ŽŠ’’“ŽŽ‘ˆ‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽ‹‹‹‹‹ŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}|}}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…‡‰‡†‰…ˆŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰„‡†………‡ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰Œ‰‘‰ƒ……‡„†ˆŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}|}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹ŒŽˆ‡††ˆƒŠŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz||||}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒŽŒ‹Ž‰ŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzzz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{y{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚‡ŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†………………„„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰ŽŠ‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹ŠŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{}~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““””””“””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••””•“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””’’“““““’’“”““““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘’’““’““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’‘‘‘‘’’“’“’‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡ƒ‹Šˆ‰‰†……„„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxy}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzop{xy{|{xw{xuwttvttvwuqrqnprpghklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkigfgggihgmgjghehgccbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__`c_\_]`]^Z^]YY^ba^^ZY_\XWSNMLKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{yvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSSPMJMNPROMPQQQQRVVQQQTPPNNOLJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTttuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMOPPRQPNNONONOOPQONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKLFDFJKKKHJLLLOMLLNOOOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtttwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEBA@@CCDEACEHKOKIIJHGJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:<>><ED=?EA?@A@DEGGGGBDDEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrrtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@:;><;;<<HL==AA?BC=ADDFBFFDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnpprttsqrvxy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;::;89:87:<978;;>=;;:8:@@AB?A?CFDBCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqtsusqsxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<979::989::78:9:;;8789;:8<;=@A@=;;><==@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsusrvyy{}~~~~}~~€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>=;<<>?=<=;:<===<<<<;;:;<>=>??A@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquuuusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?BCC@><=?@??=;>=>CE??@=;===<;:=>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVppqssttuyz{{}~~~~~~€€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???CED?=;<@>:;::97:<9==@=:<;;<;89;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pprrrtuvz{}}|~~~~~~~~€€€€€€€€€€€€€€€vMNNMNNLLNPOL>A<<=?>BC??AAABA@=<=;>=:::<:8:88:;=??<;;<;::;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€{NIKKLLLEILNM<?<<=>@@AA;BCBC@???@=?@?=>A@=>=?==>CD?;<=>@==>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hloppqtuvy||}||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABECDA?@@@?=@@<CcD@@@C@@?@@>=<=@EABBFHC=<@DCAA?>=@A>>>?<>@DGE@>@A?@CFECBBC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{||}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@A@>:>=><<G{[>CCE@??Na_J@CEIIIIMMKECFGHEGEEEDDCA?@>>BFJJGEEFFFJNNKJIGGHKLJGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDFHD@><;>@DED@AFBQenpyqEDDDCWu†‰Š~XGHJLLMOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHIHGFEFFFDFHGEEHHFHGHFQnnpqrvvy{{{z}}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJHIGUea~………€zTAAUt‡‰‡‡†‡‚WILMLMNLJGGGGDGGGGFHFHECDDFEDDHHCCCGJJKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrswwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLKKJ^z€ƒƒ|ƒ~cNl„‡†††‡‡‡‡|PKLKHGFFDECC@ACCCCFFEB@>>@AA@BD?>?DFHDEGIKIIGHIGIIIJIHFJJJJIJIJJJFILLJJKKfopssuvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKKKKKd~ƒ}„‚{€†…„„†††‡‡†ŠuIIFB??@???<<<>::<AA@><998<<=;>;9;?AB@ACCC@ABEDBCFHIHHHLMLGIJMMNMJJKKJLMSloqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHHIHKKf~}‚„ƒ‚„„„……†‡ˆˆˆ‰‰ŒŽfBB=88::9878896479;<:8567789787689;;<>@;999==>;;=ADEHJMLLGIHORQPPNLMMOQ]oprtsuxz|{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@CGHKGj€‚‚‚ƒ‚‚ƒ‚ƒ„†‰Š‹Œ‹Š‰Š‹Œ‰T;8656766655763468:876565677778:77789;7689989876:<@GFIFIFEFOSRSSROPPRTepqsttwy{|{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:=EBDEf‚‚‚ƒƒƒƒ‚…‰ŠŠ‰‰ŠŠŠŠ‹‰‰ŠH676468874578467699766765::;::<898977779:98878588;A=>>BA?AKLOQPQOOOQWkrrttuwz{{{|}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897:A:=CSƒƒ„„„„„†‰ŠŠˆ‡ˆˆˆŠŠŒŠ‰‰Œz>:88;<=>9:;<89;9:;:99;:9===?;;;=:>;9;;<;<;9;<8::;:999<?<=ABDIJMKJKLWorsutvx{{{|{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<:89989999:?>A?Y„ƒ„………†‡‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>BCEEAAAB>@B@@?=>>@?>?@?@==?B?AA?A?=@@@>?A<><;:;:9;?=;;==AACABCAXqqtttvy{{|}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::<=:;;<;=?CB@g…„…„…„†‰‰ˆˆ†††‡ˆ‰Š‹‹ŠŠŠ‹Š‹^>DGIKJIFGGDFHGEC@@CECB@BCB?@DHECEDFEAFEFDFFD@B>=@>=?@>???>?>>:;=<`qrttuwzzz}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>???<@>A@EBN~ƒ„…†††ˆˆˆˆ‡†††‡‰ŠŠ‹ŒŒŒ‹ŠŠˆWGLLMKNJIKHIJJIECDFGFDCEFDBHIKHGGFHGEKIKIKKJCFCCDBAACBDCCDDCA=;=@hpsttwwzx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLK@BBA97<>;<;>@?A>A@DDHCj…‚……‡ˆˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹‹ŠŒPMPMKNKJLIIJHKGEGHHIEEHFFELLMIJGGHIJNMNLLNKHFGGEECFFFFDEHHFCA?@Llptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?FGG=<@@87<;<=:?@>??BCFELW~ƒ„„…†‡‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒ‹ŠqMQOMLLKLJIHFJJEJHGKJHJGGGKLNLLHHIJMPNPNMOKIGIJHIDIHHFFGGIFCBACUnquvwy{xyzz||}~~~~}~}~~~~~€€€€€€€€€€€€€TDAABGHB?8?@8:;8<=;=A=>@BDFGQo„ƒ„„……†‡ˆˆˆˆˆ‡†ˆˆˆˆˆ‰ŒŒ‹ŒŒ‹‹‹‹‹^RRPMNMKJGFCGJGLJGKOLKJJMMLOPNHIKLOQQPQOOJIJJLJLFGHGFGIFEEB@BB\prwxyzyyyzz{|~~~~~}}}}~~~~€€€€€€€€€€€€€€€UECEEGGED;?A;=<9?==@BGF@EGEJQw†ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹‹ŒŒŒŒ‹‹|WVRRTROLKJEEFKONOWVQPOQSRNSTOMSLPSUWRSRPLKMMMKNGGJFFHJDDEEBDCcquyyzzz{z{zz|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?==B>BBFVMDKLINRz†ƒ……„„‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŽ‹‹‹gVVkaERQQPJ;;QSR`u]UVTVYYSYXRZfPUWZ]RTWQPNRPPPQKLKGHIHEFIIIHIjsvyyzyz{{|z{|}|}€~}}}}}}~€€€€€€€€€~~THJIIGGFE??A@EBCFEDELXRLRRPSUz†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ}aŠ‹‹‡l[dU:XXXSP?@VUY\d`VYbr^]W]ZVEQYZ\Y_TYgRUVXTTVSOOMJLJIILMKOMSotvxyxwzzz{z{|}|~~}~}}}~}~€€€€€€€€€€~~~~VJJIHGFDDBA?HMIMPKIKPTSRVXVXWw…„…………†‡ˆ‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~Œ‰Š‹znpXZ[ZRSRWVTZZuƒYU}a\X]^WIV]][[_YHYXY\]XXYWRQMPQMMOSQQURassvwwvxyxz{{|}}}~}~}}}~~€€€€€€€€€€€xy}YNKIIIFBD@A:PQQWXPPOQSTSVWWWYm‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡ƒŠ~fYY\YSVTWRQWVc–€QerXZW_hP`fZ[X\hbGOZig\[\]]WSNSPPQVVVVYZosuwvvtwxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZ[RSQORRQURUSV_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PVXTRTRQQLOMKfyZ]TYUV]ZLTZTST^ZXWWWzkXZ\\^SPPPINOWVX[Zdqtvvttvxyy{{||}}~}}}~}}~€€€€~~zxwvsu{€€tk~~kry^\VUSROKFCDAM^ƒlVRSNOQOQVRSRRTcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ymqVIKNNKMKHJDFHEC>ScURQQNKRTQMOYQMNQSUUMQSRPNLLHCIHRSTZ]mrvvussw{z{{{}{}}}~}}}~}~€}}~~€~{vsw}~~du}iqt_d]^[YUQLILIal’tPQSNQRQR[RSRQRUUbs{|€‚}{{€ƒ‚…†‡‚†††„†…†u_]KC>CCCCB?DPCC@C>BHGV@INMG]iQHFOFDEFHGHBCHGHJGDBAC@OPMRdtuvustuz|z{{{||}|{~}}}~~€€€||}€€€}vt{mh|gnqfieeb\XSQPURsWe[OONLQSQUYSUQQTROV`klsvz{xyurnstsyx~~ƒ€ƒƒ‚€‚€‚kLG>>:;>@??>>kQKaEFHIEB?HMMGMQUJBE?><=<==?=?ACB??<=B>JMFUouuvstvxz|z}{|}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QQZ\Y^IJPQNKLQRQTUUWQQWVPX[b]agmmlokh`nrjmlqu{z}zxz||xwxdB@@A=:BCAACB\]O{NOONKLMOOPLKLWNIG@B<977599=;;;8989?;AG>\tuuvuvwy|||}||}}~~|~}}}~}xuwz{zwyxuw{|yxuywcqhipmnmmhf^OP^\ZIGPRQOMPQNQRSVXSRYTNYZ[WY\__`e`]^qwk^`gkwooljonnlfbYGFFHBAFIEEFCMRPaWRXQPSSRU[OOQVPMICF>:96586979:365795<B=ftuvwwyy{}}||{|}}~~{~~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZWMKTTSPQUOLRSTWXTTXQLWYYVXXVXY]WWXhsk]V`tkaa_]d`_^YUPMONLIGJKIHFCQPSZWTTNQSYS\eUOSTQNKIHC?A9988978847578598Gnruxxz{{}~}}|{}|~~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPWVVSTVOOUVXXYSUTLKSUUUUWPTUWTUR]n^RNY`[VY;DUWT[fJLPRROMMNNNLJFPPUYSTNJNOTST\VRUSSOMLIHHF??=:787659967665Wqqtwzz{|}~}~|}}|~}}y}}|~~~}||}}~}|rvqxxruuqqnppopuvtnjddjppqrpnfedc\^RTZVWTSVTRXXYYYRUOJGOPOOMRJOPPPNNOTLMIPPSTU2<XMIAQ=c`QSQPNPQPNNMPNTRPRLILKOQPQRSTQSOLMKLLHCBA=:9876;B4566;eprvxy{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqpuuvcjgeWhtrrqniihpVVTUXUVURWVUZYXWUQSFEAFGGHFJDHJHGEHLHKIGLMPMG/E_R>3@>joaRRQ@FTQOPPQNQOPOLJLLOPNNPQQNPOJLMMKGEEDB;==<9=G6676Dnquwz|{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknbePSTRSUOWVVYYVQQQO@>;=?@BAC@BEDA@GHGHFFHJMLDGCORC8ENS]gSQSAGUPORQPMMNLJLKLNOOQMOOMHLKIKKLKGFFED<AA>;@E;<89Tqsuy{{{|||{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLONMQSLTUTWWULLKH=987;?A>==A@B=>EHFDFFIGKJ@FAA@FHEJOHQRa\QPRNSOOPLLOMKMLMON[VKMQOGIHDIJLLKFFFD?CC>=BG?B>Adqtw{z{{|{zzw|wy~~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCE=9879?B?;>A@@>ADIECHGIGIEBB?><CBAGIDMOaePMONWKLNKLMMLLKNNSdNJLRIIIEAIJLMNKGIFBAB@?EFEHDLopwzzy{{z|zwsxtx||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGLMIMPMPOGKE?B=999:?B?<ABBADDGKFDIIGGHCC?B??@A>DECKNQTKJIMTFIIJLJKKIJLMOPRPKGCLGCCJJLMONIJIGCCCDIJMLIZsmxyxz{{y|vrpurtyyvxjqnjllnttmsu{stxronqovsnporpopstyjN`gsjt|ygosqiqheqHKCFHHGJKIJLDGB=>=:::;AB?=BBCCHFJLJEIIFGGCC;A@B>@@CECIMOGHKFHKDHIKMHJLHIJLJM]RIHDNGBEKKNMPNKMJKFGGJMNQNLcniwvv{x{z}qmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoijthdpFKCFEGDEEFEGCC@=<=:;::@D@>BCEEIFJJLFIIGFFCB;BCC>@CCCEGLNHKNHDHEILNMGILGFFIILNKJHEOICGMMNMPNOOMLIHIOSQRNRfgfrosxu{z|lhjoekpmsqfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGICEFEBBAE@DB>?>:;;=;=?CA?ACFGJGJILHGGGFEC?=EEB>ACCCEGHIGMPIFFGKNOKFHIFEDDIIHKIFHPKDJMLPNONOPNJJHMRUUROWdaamgprosyzgehhcilgqlflmgiklsmpvutpnvrosrsutqssutsuvvvyvutvlkuumrvqlnlerMGEEGCA@AD<BA>A=::=?;>?@B?@BEGJFJGIGFFFEDCAAFFCBBBDEEGGHFLPLIOJJLKIFHEFEDCIHHKJGKRMCOONQPOONOOKKKPUWVUTY`_]iaminhrsbeffdihfnifmmhkkmriqvusqmvnoqrswsrstuvvvvwvwvvtwuksunutsprkksMFGEGAB@CD<AA@C<89=>:?=?B?@@DFHEHFFHFEECCDBDIFCGEAEGEFFGEJMKHQMJKHHIEFHHECIIJKMKPSNDRSQQRNONNPMLNSWVWXVX^[]d`hbjigk_defcgggkggkmkmlpqgttursnvoqprtxqssuvu‚‘yvvtxuuwxnouorsuqqipzMGGGHBBBEE<@CBD<7:=>;>:@B>??CEFDFDDGECECDEFFJEEIGBGHFGFECFJJGMKLKHJKFIHJHEKKLLNORTOITUTQTPQMNQNMQWZVZYWZ^[Xa```_hec`deggjhhjfhnllomqpiuuxrrpupppruvpusuvu{~}xvtwvvvwplupmsunossyMHHGIDBCHE<@EBD<8:>><<=BB<?>ABFCEBBHCCDEFFGGIFGKHCIHGIGFDHKIGKIMKJKLHLJMKINLNNORUVOLVVTQTRRLOQPOTYZY\ZZ\__^`c^\ackb`dghr…hgjfjnnponsqjtuxrsstrnpqvrquruus~yŽ}uuvvvvxriuqkrtlqwquKIKHJEBEGE<@GDD@9<>@?>?CB<@>AAFCEDCHDFDFFHHFHGIKJEJHHKHFFLHHHJHMLLLLIMKMNMOLPPQUVWOKVVUSSRQLORRQV[[]^[]^``a`be]d`fg`ehjcssfjhglprqossnswwpuvtsmoruorspurvrtwuuuwvuwsgtrkqrkrwowIJLIKGBEDE<@FDDB;??A@@@DA@B?ACHBEDFHEIEFEIHFIHJLHHJJIKJFJKHIJJGKKMMJJMLMNNOLOPRUWVNNTVUSRQPMNTSRW[^^_]^``aaa`cdebdicdijgv‹lkihmosqpqpprywruutsmmssmqrotutspswtuuwvuuueqskpqjrvpwJLLLMGCCAD<?EEEC=AACBBCEACDAAEGCGGGFEJFDGJGGJFILHIJMKMLGKIHKKNQKRQLSMKNMNPPPTOWXX[NSQW\ZSVPNTUTTXZ_bb_da_`b_`fbacinicihhmxvmhimosrpqrrrvtsusssnksqmprotvrrquvuswywutucmtkopjqtpwLMLLLGEA@D>>DEFC?CAECDFCCEGCBHEBHIIHHKFDKJGHJHIKGJJNKNLILHJMKZfJd\KlRHOM_nUls[qpbwcRPbvuhucav`Xnqbdvinzf\lt`lkU_wvijhhfglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqsqyKNJKJFB?@B?=DEFDCCBEEDFBFFGDDKEEJLLJLMGGNJHJKGKJIKKNLMMLLILML[sbdp^llUMNes^gfqlntgpi_aYnmbppbkjjgoqtetno\pugqMKryvkbakeelxmkvlnpsrprqpqrqrrrtrmmsnnoprutqsstuuutwxvttbmukpplrrqzKLIIGED?AB?=BEGBFCEDEEDBHHGDEKHGKMMJMLFJNHJKJIKJJIJLMNMMMKNMM[roonpplkNPQlXMibtrpamov\YlP[mmZqmkomxxtsip\`slqjUuyxoc^kfbgppjiopprspqpqqrrqqrrtlmrmmnorutqtrtuutuuzvutenukpolsrryJKGHEEEBAB=?@EGBGDIEEDBFIHHEGKJGMMNKMNGLNIMKHJMIKIJJNONNMLNML\hdu]lqWlNOQnUZk^klvaldtTecNlYl\tpkilxjwuhp]_skhWbcw|oc`ghaditykonqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtvIMGIEEDCAB<B@BFCGFKGECCHKHHFJLKFMKLRRLGMMHNJIHNHJJHHNONNLJMMJZsppoqqmlOQSoYskgooqqomt^nXat_nopoqroousttj[]tcwxrjnzhaacfabjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyytukoumtonssvtIKHJCEEE@@>CCAFCHIMHFCFJLIGFKMLFOJKWRKGKJJNIIJLIKJIHJLMMLIKKKSkbZi^_jcrrZ_Zko`eeUk_c[abQ`mh\j\niid[pfdp]Z\k[mqcpsldgcdg``knppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunvqrutwrIHFJDEDFA@AEDCGBHJLGFDGKLIEFJNKIOIL[QJFHHKMIHJJKKIHJGKKKKGHJJLLLKIKLNT[]TPUMQPNOOURPOQOOQJJNPQdqiTYW[[\UY[]X]\\cfaafbcf_^fkmhmtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyyxuvqruovrtsuusHCEGFFAEC?CGDEGCIKLHFDGKLHDGHPKLOKLWMIFEHIJHIKHLJIFHHJGGIEFKHIKNLIO\W^O\\`^OXYS\\b^MYZMXaRKYaZS`d]aX[ddVVX\YZX\VY\^c_d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtOBCDLMACDBDIEGGFKJKHEEJJJGEHHPJLMJMRIHEAHFJIKKILJIGEJHEFGEEJGBIMJKT_Y`X`a[`UXYT^^Z_RY\P^\YN_\^S[^c_Z]`c_Y_b[`^[TYXZ_^dbbacfiekrpoppnow††……†‚{€……††…†…uqprrsvyyzyyxxxwryvxrqxvtvaSJJMIDBBCFGEGGIJJIIDFKKKFFIINJNLHLNGHF>GGLIKKJKKIGEIEDDEBFJD?IKHN[cY^^a_RTSW_`\]Y^QY\MV_WKQY[Q[_aa]^ca`bbbcceZRXVV\[^c`__cebhommllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxXQJFCGEBEGHFGHIFGJGHFHKILDDJJMMLLHJJHJG?GFNJKKMKKKIGHDD@DAHIA>HIFO]aZ[d]_TQRX]\\\_ZKW\LR\YIM^QQ]_accccb\dcbdcfXQVUS\X[a_^_aa_dlkmjklnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMB@IFCFKIFFGIGGJFFFILJNEDJJLNJLIKJHIGBHHQMKKOMKKIHHED?EBHHA@FEDT]Y^X_X_[]UXXP]]QKJW^X^[]VZaRR__bb``bb`cbbddbXORRS\S\^]^^__`dhgljnnp{{|~{€‚ƒ„………………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKBAGFDGMRHDRKFHHHDFKIMPEGIJKNLLILKIIGDHKQOMLPLLKKIIDEAECHFA@FEBVUE\T^SV`XNTUNZ[MJKU`a[_X_^b]OYb\``_bcb]bbW__TPOQRYS^\\]^_`bffelfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDFFGDIRcQDW_IGGHDFMJPPFJIJKNLLKMKJJGEINQQNOOMNMNHKADACDFDBADEALHCLLPOOMFMFFHJHGLLMOPILOPPSPLQSRUZYWYXXdVOSTPPONQUT\YY[^^aaefchdklqsszy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKM^MGHYMGHJHGNLQQILJKKNMUNOKKLGGKOSSNPONOOOHKF`ED_LDfcDM[H^\smOMVmYLCP_UlWgJ]WU^DLQULMSVQRTXWTXUT\TPfZhhdYTkTXWU[\\``abbb`gignlhrz|}~„„„ƒƒƒƒ}}zr{z{‚€ƒ„„……„…ƒƒ~z{LIEFFHEEKOTJKG`TGJOJIOMRQKMKLORUROOJLMGHMQ[YOPPNOPPJKQQI|YYrsWPmHqnoaVPqqtOBksnqtpSo_[nX]V\XUkhU]VcY`YZ_VUWituu_av_Yb\\f[_aaab^`bgmpl`pwtx‚ƒƒ‚}~€vxzmv~tx~€|~€‚„|€ƒz~wwNIEHMMBDLLGJLFRVLLOHLRXWQNOOMQTNOQPKKNGMPS[ZTQROPPQKIZx]TxdhYRSPvgtlpbnfkRrNLwmjrpsrqrpop€]fzuxqqzq~r}ku}bRg|essoss|}p~yor_``bb[a`hknkblfgmw~€ƒ~{xw€tvzhr~nt|~wx{~€ƒx|u|||ssNKF`]GAEMMHKKHKQOMNJNW^YULQSNYYLSSRNLOIQRTYWWQTPPQSLHgxlcxqmZKLTypumubnvPdeIevqmwo€jfxxiWrRi{mijzz}lxzpgoXuujvup€ash}ilx|o___cb\_defijdgbcdllppstsssyqrxbltgry{ssuy~svzn|}yxrnNJRtNCBEPPIKLJLQOOOMPZ`ZXKTWPa^RVQYSMPJSTUXWWPUPONSJKrouuquqdhaVnLqp^GhyWvTKhx}x`y{sna^modSgrunmypwlvstqlm\s}zkmy|lum|kpvux^__b^]_edighee^bbiiijknokqnmjpacfdowxompsynqpj{ztromLKZVHGEGRPKLNKLQQPPPQW\YUNVYUfXRRY^TMNJTTVWYWOSOONQIRmHiwK`dvuUWlNnl{rajgvUKWkh}lmlx`[pz{_`zscroxqhd|ir{]TKl_vukiu{{m~xk|p]^^b[^bdegeeebZccikkrsrwgmihdg`alagsrkhmmr|kmhk{tmmkmOGJKHJHHRQMOPMLSSROSRWRVTPWZVVTTTa`QONKTSSQVVOOMNOQJHQNPULKKRSRRROVUQQORRXXQNPUTXXX[[USSW[WXWZPSUWWXQ]XV]USOXRVWWXZ`[gr^[\[]]_cZ_ccefdccbZccgffmnmuffgc`f_]g`dlhfgkhpzhggkujhgilPIKKLMKJTRMRQPLVUTPTUXUZURZ]VUTWUYXPOLNWTPNUSNPNLQPKJQQKQMJKOQTRQQSRIIMNOQRQQQTVRXW\WSSQQUUVTZQNSQWUTYVTYUSRUSTUXYX^Z_a]\[Z]]`c\]bbdgeddaY`acabhhincad^_c]Zd\bma^ffgmsdihkkedcfhQJKKNOLMTQOTQQMXWUTVXWWZVT\`VWVYUXTQPKOXSPNUQNRNLSPMNUSNQNMNQSPTQSTTNLNOQTTRRQVWUYZ[YSURTXWWY[SOSTWUTYUVYTRRWUVX\Z[`]VY_]^]\]`a^[bbchfedbX``b]`hefda^_]]^ZZ_Z_g`^^]chkahfhfd`bdbPKMLPQLOTPPTQOQZYXWYZZXYV]jdVXYZWVTTOKOVTPOTPPQNMQQORXSQQOMOSUNWQTTUONNQTUUTTRTXVZ]\ZVVQRWXV[\VPSUUUVYTWWTRRXVV[_[^`_V_]^`\\``__ZbbdhhedbYb`b^^fdc`b]\\\\YZ[X[a[^]]_b__bddbd__`\PMNNRQMRSPSTQOU\ZZW[[\YZ[dqmhd_[YVVXRMMVSMNROQROMPSRUZUSPPLPWUQVRSSXMOPQTXUUUSUYX[^]\[VROUVU[[VQSVUVXUSXZTSQYWW\_[`_`Vb\`a^`b_\`]cacgief`Zc`a__ee_`c[Z\[\ZZYYW\Y\[`^`[^^a`_c\Y`ZQNONVQPUSPUTSPW\\\Y^\_W\^jpwy€c\[VVYRNOWSNQQPRTRLQTSY[WUORNSXUSRTRRZOQSSV[VVVTVZX]^\\^VSNTVV[[UQSTVXXRSY\TRR\XZ]^]aa`Wb[cb^ac_\bab_dgidg^\e`a`acd_b_YZ_[\[YXYWWZ[Za]][]\\Z]`W[[ZPOOOYPUUSRWRTPZ]^]\`\`U\]hjr}slh\UYWQOR[SRQTRTUTKRVUZZZSOSQUUUSNVRSZRTUTX]WXXSX\X^]YZ]UUNVVW^ZXQTTXXXSVY\TRV]Y]]a^cc_Y`[eb_dd^^cca^efief]^daaabcd_b^X[_[\[XXXXW[Z[`][[\[XZ[^V^Y]POORZP[UUWVTTT^^`_^b\`U]^bkyum}lZUZVQQT\TTTUTVYWLRZV\Z\RPUSWUUSOWRSWSWUV[]X[YUZ^X_^Y\YRWRYXY_YYSUUZYYUWY\UTZ]\^`a`ed]^]]eabfd^_dc`\gdhfdb_da_a`bb_`^WY^Z\\ZYZWV]Z]^[Z[\[WY\]VXW]SOPWYP]UVYWWUX_`aa`c]`U]^beev‚{hXYZTVTV\XWWVVW]XOU\Y^]]TSXRWUSRSXRSVTXXX]^X][U^_X__X\VQYUYZZaX\UWWZZZXYZZWV]^_^cbbee]b\`fbefd_`dba[fchfcfaf__abaa`_^VU]Y[\[Y\YY][[[XXY[YZZ]_]TY]UNSZWT\UVWYWV\`aacac__V[`da_zuohZ\ZVXVX[ZY[YXY`VOT][`a\UUYPTVTRVVRSUW[[\_^Z_\V__Z]^Y^VSYXYZ]bY^VWZ[[[[[YZXY__``dcdeebdZbfcgfe^ab`c^cciedg_g^bbcaa`^_XTZZZ[[X\XX\[Z[WWZXW\[\`]V]]SOVZVVZVYUXWX^`badada^YYadb`kfh^\][WWYZ\\\_[Y[bVSW^]ac\SVYPVUUUVVSUTX]]_``]a]W`^[^\[^XVXX[Z__[_XX\\]]^[Z\WZ_a^`eddfffbYcfehgd^c`_ec]fideh_g^cbcaa`__[XY[YZZXZXW[\Z[WXZTY]\Z`\U^bMRWYVWZY[\YWY^`baeada]^Yacb_a`a_\\]XW[[]]__\Z]cXYX]_cd_RYYPWVWXWWVWV]]^aba_b^Ya]]^Y]^YXUW[[`^\_YY]]^^`\ZZY[_b_bedefggbZdfgigc_c^`feZiicficf_bbca``_]]ZX[YYXXZYWZ[ZYWXVU[]]]``bbxKWW\YW]\\]ZW\]_`bdbca]`Xbcb`cac^\\]XW[]_]`_][`d\\XZbecaR\YOXVYZYYWZZ`^abc`ac_\b]_][_^YYTX]]__^_[Z^^`bb\\W[]`bbcedgfegd\efhifcab\cg`\iichife`baca_`_]]\Y\YXWXYYW\[ZWWXPXZ]acffrkJYW][Z_]\^\Y][^_bcbaa]b[bda_cbb]\[[XXjq`\`_]\ac_^YYcedbT_ZQYW\]\[Z[[c`ccc`bda`c^`\^__ZXV[_]\aa_][`abeb^\S\_`cddfegfefe_ffhhgdd`[fg^ahhbhhfc`b`cb___]][Z[YXXXVZV\ZZVVULXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡…‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vuuuuuuuvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{{{{{{{{{{{{{{{zzzzzz{{|||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vutuuuutuvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{{{|{{{{|{zz{zzzzzzzzz{{||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||xÅÔÒÒÒÒԓ{}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰Š‡sqrrrqo©Á¾¾¾¾¾ÊÓÒÒÒÒÖº}~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}xÕçääääç™{~†“y1333332j‚€€€{­éääääèʉŒŒŒŒŒ‰roooool²ÐÌÌÌÌÌÛæååååéÇ}~}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}v~€ywwwwwwxyyyzyzxooooppprrrrrrrwzyyzzz~ƒƒƒƒƒ„|||||||zzzzyyyƒ‚‚‚‚‚„„„„„„…‚|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚‚‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vtttttwuvwz{x{xwvvxxyyy}yxxyxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{{{{{{{{zyyyyyzzzzzzzz{||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwww|{{|{}{wwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwwy~||}}~|wxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z|yww{~}}|}~|xxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚ƒ‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzzx{|||{~{xxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyywxzzzy|xxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyyyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegefgbedebg[be`v||{{||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}||}}|||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}|}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚€€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrstuttssrrsrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqstsssrqqppnnnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqqrssssqpqpoonnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrqrrssrrqppoopoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpppqrrqqqpopooppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqpqqqqqqpooppppppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqqqqqpppppppppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsquŒ‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqqqpqqqqpqpqpqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrqqqqqrqqqrrqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrssrrrrrstrrsrsssssssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz|~~|vvwwvuxzxxxxwwwvx|yy|zyy|{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~|{{z{|{}|{{{{{{zyxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}|||~|}~~~~~}}||}ƒ€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆŒ‹ˆŠ…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€€€€‚€€~~~~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒˆ†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~~€€€~~~~}~~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~~~€~~~~~~~~~€€€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹Š‹‹‹‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚ƒ‚€€€€€€€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒŽ‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒ„‚„„‚‚‚‡ƒ‚‚€‚‚‚‚ƒ‚‚ƒ‚ƒ‚ƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…ƒ„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒƒƒ€‚ƒ‚…………††‡†…††‡‡‡†††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠ‡‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„„ƒ‚ƒ…ƒ‚‚„…‡‡‡‡††‡‡‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ’‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚‚ƒ„ƒ‚‚ƒƒƒ‚‚„„ƒƒƒ‚ƒ„…„„……„ƒƒ„……‚„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘’’ŽŽ‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€‚‚‚‚‚‚‚‚‚ƒ€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„…„„…„…†’“‘ŽŽŽŽ‰ˆ‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~~€‚€‚‚‚€€€€~€‚€‚ƒƒ€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“‘Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€‚ƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚„‚‚ƒ„‚ƒ„…†„‚„‚€‚‚‚„ƒ‚ƒ‚‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘‘ŽŒ‡…ƒƒƒ‚‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒ€ƒ‚ƒ……ƒƒƒ„ƒ„ƒƒ„„…„„„‚€‚ƒ‚‚„ƒƒ‚‚„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”“’’ŒŠ…„„ƒƒ‚‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~€€‚€€‚‚‚‚‚‚€‚‚‚‚‚ƒƒ‚‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†”“’”’‹‡„„ƒƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~€€€€€€‡‚ƒ€‚„ƒ‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“‘Š†ƒƒƒ„‚‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€€€ƒ‚‚ƒ‚‚’Œ‚ƒ„‚ƒƒƒ‚€€€‚‚‚‚‚‚ƒƒƒƒ‚ƒƒ„‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†ƒ„ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„‚‚††ƒ‚~‘™†…„„…‚}}}~‚„ƒƒƒƒƒ„ƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„„†………„…†…††…………………………††…†††…†††‡†…………ƒ„„„‡““’‘’ŒŠˆ…………‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…ƒ‚ƒ…ˆ‚~}~}…œŒ††ƒ~~~~~ƒ„ƒƒ„„„„„„„„„„„„………„…„†……†…†††…†……‡……†…††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„ƒƒ‰Š€€~…Š“„~€„…„…†††…………††‡††…†……†‡‡‡ˆ‡‡‡†††‡‡‡†††‡†††…„ƒ„……†„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘“’‘‹ˆˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒƒ„ƒ‚ŠŠƒˆ‚ƒ…€„„€€€€……†‡ˆˆ‡‡‡‡ˆ‡ˆ‡ˆˆˆ††‡ˆˆ‰‰‰ˆ‡†‡‡‡ˆˆ†‡†‡‡††…„ƒ„…†…………†††‡‡…†‡†‡†‡‡‡‡‡‡‡‡‡…‡““‘‘‹‡†…†„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡‡…ƒƒ…„ƒƒƒŽ‰††‹ƒ€€‚€€~{z€†ˆˆŠŠ‰‰ˆˆ‰‰‰‰Š‹Šˆˆˆ‰Š‹‹ŠŠˆˆ‡ˆˆˆ‡‡ˆˆ‡ˆ†‡†„ƒƒ…‡‡‡†……„„ƒ……„……†„„„………†…†…ƒ‰”“‘ŽŠ†…†…ƒ‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡‡„„…„ƒƒ„‡‚‚‚‚‚‚‚‚‚€~|}}}~|{|ƒ‡‰‹‹ŠŠŠˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰‡†††‡…†ˆˆ‰ˆ‡†‡„ƒ‚„ˆˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚‚ƒ‚„ƒ„„Ž“’‹ˆ…„†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„………ˆƒ‚‚‚ƒ‚‚‚ƒ~}~~~~~~}|~}}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡‡‰†ˆ†ˆ‡‡‰ˆƒƒ„ƒ…„„……†ˆ‡†…ƒ‚‚ƒ…‡†‡††„‚‚ƒ„‚ƒƒ„‚ƒƒ„ƒ„‘’‘ŽŽ‹‡„††ƒ‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…‡ˆ‹Š†„†„‚†‡‚‚„ƒƒƒƒ‚‚}|}€~~~}|}}|z|„†‡†„ƒ‚ƒ„………ƒƒ…„„„„„„…„‚‚ƒ‚„„‚ƒƒ…†…„‚‚‚ƒƒ…ƒ„„…„„†ƒ„„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰†„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€‚€~„„ƒƒƒ‚‚€}}€€}~~}|}}zzz~ƒ„„‚€‚‚~‚ƒ€‚‚‚‚ƒƒ€€€ƒ‚€€€€€‚‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†Œ“‘Ž‹ˆ……ƒ‚„‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€€ƒ‚~~~~}}€„„‚ƒƒƒ~}~€€€~}}}}~}|zzz‚‚~€~}€€€€€~}}€~€€€€€€€‚€€‚‚€‚„ƒ†’ŽŠ‡‡†ƒƒ‚‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒ‚ƒ„…€€|}}~}~~€€}~}~€ƒƒƒ‚‚}}~~€€€~}}}|{{{zzzz€€€~~~~}~~€~€€~}~~}|~€~~€€€~€€~€€…’’Ž‹‹‡‰…„ƒ‚‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~~~~€€~~~€‚„ƒ‚€~}~~€€€~}}}}{{|zzyyy{€€~}~~€€~€€‚€|~~~~}|€~€~~€€~€~~~~~}||}…“’Œ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒƒ‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚ƒ‚€ƒ„„€€}}}~~~~}}}}}|||{zzyyy}€€€€€€‚‚€~€~~~~~€‚€€€~€€~~€}~}}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…ƒƒƒƒ…„„„„ƒ‚ƒƒƒ‚‚‚‚‚~~}}}~~€}}}}}}}}|{zyyyyy€‚‚‚„ƒ€‚ƒ€‚€ƒ‚ƒƒ‚€€€ƒ„‚€€€€€€‚‚€€€€€€~~||Š“Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…ƒ„…„…†††††……†€ƒƒƒ‚‚€}}}}}}~~}}}}}}}}}|{yyyyx|‚ƒ„…‚„ƒ‚‚ƒ…†‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚‚„ƒ‚ƒ‚‚‚‚€€€~Ž“Œ‡ˆ†ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€€~}}}~~~€ƒ„‡ˆ„†††…††‡‡††‡ˆ‡†‡‡€}€€‚~}}}}}}}}}}}}||~~~|{yxwxyy€ƒƒƒ„ƒ„„„——ƒƒ„}~‚‚‚‚ƒ†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ……„…ƒ‚ƒƒ‚ƒƒ‚‚‚‚ƒƒ‚‚’‹ˆˆ‡‰‡††„†…„„„‚‚‚ƒƒƒƒƒƒ‚€€€€€~€€€€€€~}~~€‚………‡†‡‡†‡‡ˆ††‡‡†‡‡†}}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yxy|~‰—„ƒƒ„„”“€~~…‹€€€„†‰…„‚‚……‹ƒ‚……††„ƒ……ƒ„„ƒƒ„ƒ…„„ˆ’Ž‹‰ˆˆ‰‡‡‡…†…„…„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„„†…}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|xyz{|‚ƒ€ƒ‚€~|~~{ˆ‘||Ž–}‚†Š…ƒƒ„ƒƒ‰~ƒ„……ƒ…†…„……ƒ„……†„„Ž‘‹ŠŠŒ‰ˆ‰‡…†…ƒƒ‚‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚ƒ}}||}}|||}||}|}}}|||{‹‘—Œz{|zzz{|yy}}~€€|{{~~}‚•‘„ˆ~|~‚„||‚„‚€‡ƒ}‚‚‚€ƒƒ„„„„„‚„ƒ„…‚„‘‘Ž‹ŒŒŽŠ‰‰………ƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚ƒ…ƒƒ…………ƒƒƒ„‚‚ƒ‚ƒ‚‚€€~}~}||||||||||||||}|||~~Š‚{z{zxz{{|}{~}~}}}}||}†~}‚~~€‚||€‚€~|{Š‚}€~€€‚‚€€€€‹“Œ‹Žˆ‡‡……„„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ…„††„„€†”ˆ€‚€~~~€|||||||||||||}|||||||y{{{xxy{zz|€~|~~}€‚‚€€€‚‘€€~€~~~€}}}{}}}|}||}€€€~€~~‚”‘ŒŒŽŠ…††…„„…ƒƒ‚‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚„†‡††~ˆ•Š~€€~€~~~|{{|||||||||~}|{}|||{|||zzy{|z}…ƒ‚~~€~…‚~€~~€…†‚€~~ƒ†~|~€€€~}}}}~{|}€}~€Œ‘‹ŽŽ‡„††…„„„ƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}~€‚ƒ††……~€€€~~}€€€€}}||}~}|}}}}}}|~|}|{}||z{z|}}†„‚€€}~}~~‹„†~}||~‚}}}}€|{}|~„ƒ€~~~~}}}~€~~~„’Œ‹Ž‹Š†„…„„ƒƒƒƒ‚‚‚ƒ‚ƒ‚€}|||}~{{}w~vx~}|}|}~~‚ƒ€z}}|~€€~€~~€€€€~~~~~~}~}|~}~}}|{|||z{z}~€ƒƒ‚~|}|}||ƒ~Œ~|{{}~}~~}{{{}{z{{{€†…‚„ƒ‚€~‚‚‚‚‚€ŠŒŒ‹‹Šˆ„„„ƒ„ƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€~€€€}€~~~|‚~~}}}{{}}|z||~€‚€€€||}|||||}|}{~{{{|||}|{{{{}|zz}z~‚~ƒ„‚‚…†……††‡†‚„‘ŽŒ‹Š‹‡ˆ…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~~€€‚€~~€€~}ƒ||}}|}}}}{|~~~~~~~||||||{~~{|{||||}|}|~|}||{{|y{|{{}{}~~€€ƒ‡‰‰‰‹‰‹‰…ˆ‘Ž‹ˆ‰‡……ƒ‚‚ƒ„„ƒƒ‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€~~~}€€€€ƒ‚€€€€€€€~|z|}}~}}~~Œ†}}~{{ƒ‚}~~}}|}}}}}~|}|}|}}~|~}}}}|{{{|{||{z{{zzz{~~‚…ˆ‡ˆŠ‹‹‹‰ŒŽ‰ˆ†…„‚‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„„€€€€‚~}~€~{~‘Œ|}Š€Œ~~}}}~}}~}|||}}|}|}}}~}}~~|{{{||}|{z{|yzyxy{~„ƒ„‡‰Šˆ‰‹ˆˆ…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{|||~~}}€€€‚…ƒ„‚‚‚‚€€ƒ‚€}~€~|~ˆ‚~ƒ„„ƒ~}|‡}}~}||~|}}|}}~~}~}}}{|}~||{|}zzyyyy{{~~€ƒ‡„ˆŒŠŠ†…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{|}}}}zx‚€‚‚€€€€€‚‚‚‚†…„‚ƒ€‚„~€}~~}~€€}~„€~~}~}}Š…}~}~~€}}}|~~~}€}~}|}||{|}{{{zzz{{|}~~€ƒ€‰Š‹‡………„ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv~€ƒ‚‚‚‚‚ƒƒƒ‚…†„‚€€€€‚€ƒ~~€€~~€~}~~€€~€|€~€~|}}|~~~~€}‚€|}€}|}}}||{||{{{|{|||}|‰Šˆˆ…†……„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€ƒ€€€€ƒ~~€€}€}}~~€€‚€€€}€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{|~|}|||{|{|~‰…†…†‡…„…„‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz}}yxut€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚~~~€}~€}}}~€€‚€€€‚~~€€€€€~}}}~|~~}}„€~}}}~}~~}~|{|z|{z€†‚„„…„„ƒ…ƒ‚‚‚€€‚‚ƒ‚‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xytu}‚ƒ‚ƒƒƒƒ…„…„ƒƒ„„ƒƒ„‚€€€~}}~€~~~€}}|}}~€€€€‚€€€‚€€~€~€€€~~~~~~~~……€€ƒ~€~€~}{z{z|{z‚„ƒ‚‚‚ƒ‚„‚€€‚€€‚ƒ‚ƒ„ƒ„‚„‚‚‚‚~€~}~~~~}~}}z{|…„{{syz|pwuvwyvtz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€~€}}}~€}~~}~|}}~€€€€€ƒ‚€~€€€€€€€€‚‚‚€ƒ€ƒ‚€€|{{z|{|€‚€‚‚€~‚‚ƒƒƒ‚„‚„‚€‚€~€€}~~}}}~}}{{z€x|vyy{qtxwvxury……‚„„‚„……†„„‚„ƒƒ‚€€~€€|}}~€}~~}|~~~~€€ƒƒƒ€€‚€€€€€€€€€‚ƒ€„}ƒ„€€‚}z{{||}}€|}}€€~}}€~‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxyzruyyvwwsu†…ƒ……‚„„…„„„‚ƒ‚„€~€~€}}}~~€~~}|€|~€~€‚ƒ€€‚ƒ„‚€€‚€€€‚ƒ‚€ƒ€~‚‚„€€‚‚‚„‚~{{|||}}}~}z~}}x~|||~}~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„‚„„…ƒƒ‚ƒƒ€}~}}}€~~~}}€€~|~~~‚‚ƒ‡…~~€€€€€€‚‚€€~€‚~‚‚ƒ‚ƒƒ…‚}}}|{||yz{z~y{yx~{{{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst†„„…ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€|€€~€}~}~€€€~|~€€€~}~~€}€€ƒ„ƒ~}~~~€€€‚€~~€‚‚€„‚„„†„€~}||||zyvyyzyvyv~|{{{~|{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…ƒƒƒƒƒƒ‚‚ƒ‚ƒ‚~€}}}}€€€€|€€€€|€}~~}~~€‚‚~~}~~~~€}€€€~~~~~€‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{z{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvqxyrx…………ƒ„ƒ‚‚„‚‚€‚€~~~~€~}~|~€€€€{€~€€€}€~~}}}~€‚~~~~}}~~~|€~~~‚~~€€ƒ‚ƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}}{|z{}zzx{|zz{xtxuqrtpxxqy„…†…ƒ„ƒ‚ƒƒ‚‚‚€€€€}~~€}|~}€€€€|€€~€}€~~}}|€€€€~~~~}|~~~|}€~}~€‚~€€~„‚‚ƒ……‚‚~}|{{||yw{ywxwwx{{z{|…Š}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzzzzxswuqqrpxwq{…†……ƒ…‚ƒƒ‚€€€€~~}|~}€€‚€}~€~€€€}~|}€€€€~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{|||zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚‚€€}}~€‚‚}~~~€€€‚€€€~}~|€€€€€~}~~€€‚€€€€€„‚‚€~|}~~z}…~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚‚€€€€€€~}€€‚‚‚€~€€€‚}}~‚€€€€€€€€~~}€~€€€€€€€€€€‚€€~}~z“z|}|{}y{zzxyxy|||}|||||||}}}||}|~}~~~}|z||{|}{yzzzyysuuooqpwst}…†ƒƒ‚ƒ‚€€‚‚€‚‚€€€€~~€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€}~€~}€€€€€€€€€€€€‚‚€€€}~|†‰||~{{~yz{z{~wwy||{}||||{}|}}}}|}|~~~~|z|}{}}{yz{zyxstunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚‚€~‚‚„ƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€€‚‚‚€€€€€€}~€}€ƒ‚{~~{|}{z||{‡yxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€€€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ‚„„€~‚€€€€‚~€€‚€€€€€€€€€~}€€€€€€€€€€€€€€€€€~}~}~~{}|}|||wxuxxy{||}{||||}~~}}~€€€|}||}{z{yz|xzsrunwqqzqvw……ƒ„ƒƒ‚‚ƒ€‚…ƒƒ„ƒ‚‚€€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€€‚€~€€€€€€€€€€€€€€€€€€€€€€€‚ƒ‚‚€‚‚€€€‡~~|z}|{}xwvyyz|}}||{||}}~~€€~}~€€€‚€|~}}~|w{zz{yytqunwpuzqvy……‚ƒ‚ƒƒ‚ƒ„„€€‚†ƒ„ƒ‚„€„ƒ‚‚€€‚‚„‚‚„‚€€ƒ‚€€€€ƒ~€ƒ‚}‚€€€~€€€€€€‚‚€‚ƒ‚‚ƒƒƒ‚€€€„}}}|}z}€zyvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysruowqwysw{…‚‚ƒ‚ƒ„‚ƒ„ƒ€€‚‚†ƒƒƒ‚‚„„ƒ‚€€‚„‚‚‚~€€‚‚‚‚€€€€€‚„€~ƒ€ƒ‚€~€‚ƒ‚€ƒ‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ€‚€}€|z|{{w|yyy{z}~}||||}~~€€€„„€}€~{{zz{ztpxrytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚‚„†„‚ƒƒƒ„„„€ƒ€ƒ‚‚‚‚‚€‚€~€€‚‚‚‚‚€ƒ‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚‚„ƒƒ„‚„‚ƒ‚‚‚‚ƒƒ„ƒ„ƒ„…„…ƒ„‚ƒ‚‚ƒ€€~||€||x|yzyz|}|{||}}}||€€€€€‚~€€€€z{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚ƒ†……ƒƒ‚ƒ„„…‚‚‚ƒƒ‚‚‚€€}€€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€ƒ€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒƒƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{~~}y|zzz}}|}z||}}|z{~~~€€€€€€€€€}}||}|vrvxxvtvu}‡‡ƒ‚„…ƒƒ„…„€‚„…„„ƒ‚ƒ„„€„…ƒ‚‚‚ƒƒƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚‚‚ƒ„‚‚€€‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚~ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz{}€}||z|~}}}}~~€€€€~~€€€€~|}}~~}|{xvvw„‡ƒ‚ƒ…ƒƒ„†„‚…†…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„‚‚‚ƒƒ‚ƒƒ‚‚„„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒ„„„„„„…„ƒƒ„…„…„ƒ‚€}‚€}||{||€}}~€~~}~||}}}~~~€}}~€~~}}}~}}~~€|}€‚‚ƒƒ†ƒ„ƒ†„‚ˆ‡…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚ƒƒƒ‚‚„ƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒ‚‚ƒƒƒ„ƒƒƒ„ƒ„„„…„„„…………„ƒƒ„}„€}}||||~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒ„…ƒ„ƒ…~‚Š‹…„„ƒ‚ƒ…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚ƒƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ†‚ƒ‚ƒ‚„ƒ‚ƒƒ…ƒƒ……„……‡‡†‡…„„…„€ƒ~~|~}}€~||~~|z|}}}}}~~~€}}|€€~~~~~€‚€……„ƒ…„‚„ƒ†€‚……Š‰„„ƒ„……ƒ‡††„„„„…„„„„ƒ„ƒ‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ…}uyƒ€~„„‚ƒƒ‚ƒ„ƒƒ„…ƒ„…†„…†}„y|~ƒ{…‚„ƒ€~~~}}ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚‚ƒƒ‚‚†„„„†„ƒ„…ƒ„…„Šˆ………ƒ……„†††ƒ„„………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†tpurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚……‚hzrss|s‚ƒƒƒ}}~~}~‚ƒ|€}€}}||||}|||~}~€}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ†ƒ†ˆ††…ƒ††‡‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vyy…r„ƒpvxqvtturstvi€nrotvnulwm{sn€ˆym}rsvsvmmxlpylu}}~€}~}€€}}||}}|}~}€€€~|~€‚€€€€€€€‚ƒ‚ƒ„…ˆ††€‚…ƒƒ„‡†ƒ†……†‡‡„ƒ†‡ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoomw}x†pqzprtfu~n{ysoy€}}|}|~€€~~€€€~~~€~}€}€€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„†……††ˆ„„†‡ˆˆ†‡„††‹Š…„†‡‡…ƒ………„‚……„…††…†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„qjoyxpkyszozwvvp€~~~z~}}}~}€ƒƒ€‚ƒ„‚€€}~~~€~~‚€€„‡†ƒƒ†„„…†‡†…………††ˆ……†…‡‡…†„††‰ˆ…„‰Šˆ…„††……ƒ……„…††††…ƒx‹yrˆz{pp…„x…xyks~y{krƒ‡ƒz|m{yyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozls|nw‚€~~}}{}{|}}~}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡……………‡‡ˆ†„†…‡††…„……„……†‰‰‡†„†…††…††„††‡††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„…†…†„†„ƒ„„†„„ƒƒ„„…„…„…„†ƒ†‡…†„„…‡†„„…†„…}w…ƒ„„‚}~{|{~{||}~}|~}€€}€~~~€~~~~}}}~|{|~||‰†…„†††…‡†…………††‡ˆ†„†…††……ƒ„…†…„††††……†„…††††…††‡‡†…‡ˆˆˆˆ†„‡…††ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…ƒ‚……†……ƒ…„„„…„……„……ƒ†‡††…„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ‚}€{{|}{||}~||~}€}~€~~€}}|€}~~~~~||}~{|||{{~ˆ‡„„ˆ†††‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡……†…„†„…††‡‡…‡†‰ˆ††‡‡ˆ‰ˆ……ˆ…†‡†‡†‡†‡…‡‡†‡……†‡…‡†…‚ƒ…††„„ƒ„„ƒ„†„………††ƒ††…†……††…„ƒ……ƒ…‡…ƒ‚‚…ƒ„~€€|{}~{|{}~}||~}~~|~}}~}|}||~~|}€}||}|||~z{{}~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†„…„††„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…‡‡…‡†‡†‡…ˆˆ‡‡…††‡…††…„„…†……„„„ƒ„……†††…†…†…†‡……††…„ƒ„„ƒ„‡ƒ„‚„„ƒ€€€{{~}|||}}|||}}|}|~}|}}|||}}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††ƒ…†…†††…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡…‡††‡‡‡…‡†ˆˆ‡‡…‡‡‡††‡„‚„ƒ„†…‡…„„ƒ„„…†††††…‡……‡…†…‡…„ƒ„ƒƒ„‡ƒ€‚ƒƒ‚‚‚€{}~}{||~}|}}|}{||||||}{{{}|{~|{|}}|}}}|zz{{||ˆ‡‚††††‡††…ƒ…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡‰ˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡†‡‡††‡‡…‡†ˆˆ‡†…‡‡‡††‡ƒƒ„„ƒ††‡……„„„…†††††…†‡††‡††„†…ƒƒƒƒ‚ƒ†ƒ~‚‚ƒ€ƒ‚|~~||}}|}}|}z{{z{|||{{{~{{}{{{~||||}~}{z|z|}‰‡ƒ†…†…††…„„……………„ƒ…†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…‰Š‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……‡ƒ„†…„††‡†……„……†††††…††‡†‡‡…ƒ†…ƒƒ‚€ƒ…‚ƒ~ƒ~~}||}}{}}|~zyzy{|}{{{{~||||z{}||||~}|{{{{|{‰‡„†„†„††…„…†…„„ƒ„‚€ƒ…ƒ‚z„Œ{€„…‡†††…„‡ˆ‡†‡……‡‰‡„‡…††ˆ†…‡„†‡‰††ˆ‡‡‡†‡ˆ†„†††‡……‡ƒ„…„†††‡……„ƒ……‡†‡††…†††…††„ƒ……‚‚€ƒƒƒ‚}€~ƒ~€||}}~}{~}|}yyzy{}}zz{{}|}||z{}||}|~~€|{{|~}|ˆ‡…†…†„†„……………ƒƒƒ€‚…‚€}|{„…††„…„ƒ‡‡†††…„†‰†‚†„†††……‡…‡ˆ‰†…ˆ‡ˆ‡††‡…„†……‡…„‡ƒ„…„ˆ††‡……„‚†…†…‡†‡„††††…†ƒƒƒ…€€€€ƒƒ€|€~~‚€}€||}~}~{~}||yzzyz}}yzz{|{|{{z{}}|}|~~|{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€€ƒ‚~~~€yz}€ƒƒ„‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ†…ˆ‡‰‡†…†…ƒ†„…‡ƒ„†„„…„‡†…†…†„ƒ†…†††††„…††……†‚‚ƒ„~€€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|z{{{|}}}|€~}||}~|{‡……††††„…„…ƒ…‚€€€€~‚‚}~{‚ƒƒ…†…„ƒ‚†ƒƒ„‚€…‡…‚ƒƒ„„„††‡ˆ‡……ˆ†‰‡…ƒ„„‚…ƒ„†‚ƒ…„„†„‡†………†ƒ„…„…†…†„ƒ…„…ƒ……ƒƒ~~€€ƒ|€}}‚}€~~~}}}}{|{zyzzyzz|yzz{{{|z{{{{}~}}}}||}€}|†ƒ†††††„„‚…‚…€€€~€‚}~~€€‚‚„…ƒ‚‚„€ƒ‚€„……‚€‚ƒƒ„…†ˆ†…„†‡…‡……‚ƒ‚‚ƒ‚‚…ƒ…„…†„††‡††…‚„„ƒ„†……ƒ„„ƒ„ƒ…„€€‚‚~}}~~„~{||€}€}}ƒ}~~}}~{~{{zy{zyzz{yzzz{{|z{|{{~~}|}||}€~€†„……„‡„„ƒ‚†‚ƒ€€~~€}|}~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡†…„ƒƒƒƒ„†…„ƒ‚ƒ‚„ƒƒ€€~}|~~|~ƒ~|~||€~‚}‚|~}}|||{{zzzzy{zzzyyzz{|y{}{|~€}~}}}€€€†„„…„…‚„‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„…„‚ƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚‚€…ƒ~€~||~}|~ƒ}{~|}€ƒ}}€~}|||}{{zzzyy{yzzyzz{{{z{}||‚€~€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌËËËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFL=8765999<>9?<D:;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937677=;>9=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<9<<98:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA><A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÕÔÕÔÔÔÔÕÔÔÔÔÔÕÕÔÒÓÔÔÔÔÔÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9?CE@<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËÊÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø××××ØÜÝÝÝÝÝÝÝÝÝÝÝÝÝÜÛÜÛÛÛÛÜÛÛÛÛÛÜÚÓÒÓÓÓÓÓÔÔÔÔÔÔÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILO@99:4;A<7=9AC>@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÏÐÏÏÏÏÏÏÏÏÏÏÏÏÖÞÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¹³xsssssssssssssz‚€ÒÒÒÒÒÒÒÓÓÓÒÓÓÓÜãâââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVN<::87>C?8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÌÐÒÒÒÒÒÒÒÒÒÒÒÒÑÞìëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§£££££££££££¥™2)+++++++++++)5ECCCDCCCDCCC?\ÓÓÒÒÒÒÒÒÒÒÒÒÒÑàìëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;@C>6:7>>;=B?9<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÌÌÑÒÒÒÒÒÒÒÒÒÒÒÒÑÝêééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤¦›8/00000000000/;IHHHHHHHHHHHC`ÒÓÒÒÒÒÒÒÒÒÒÒÒÑßëêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;?@@8:;8<;;<?:;;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÍÐÒÒÒÒÒÒÒÒÑÑÑÑÐÜèççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©« E=>>>>>>>>>>>=HUTTTTUTTTTUUQjÒÓÒÒÒÒÒÒÒÒÒÒÒÒßéééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB?;=:9;:==;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÎÎÎÎÎÎÎÎÍÍÍÍÍÍÎÏÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÎÏÏÎÎÏÎÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÑÊÊÊÊÊÊÊÊÉÉÉÉÉÉÊËËËËËËËËËËËÌÌÌÓÔÔÕÕÕÕÕÕÖÕÖÖÖØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<8@B<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÎÎÏÑÎÎÐÒÎÏÒÔÕÔÐÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖØ××××××Ø×Ö××××Ö×××××××××××ØØ×ÖÖÖÖÖ×××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?79:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÎÎÑÁ§ÑѸ Ðќ‚„ŠÆÏÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<>B>BC@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÏÏÏѝÄ³–˜ºº•¸¹¯¡ÒÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?>;7:>9?D?A98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÏÏÓº¯ª¼Ÿ£¨²Ñ’}~¯°ÒÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<<:6?B@C:647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÏÏӟ±›¿Ç‡š´ÕÓ͞žÃÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8FA?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÏÑÀœ‰š½Ú£˜µÔÓÀ  ÐÏÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<>=964:99::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÏÔ£¢›Àס˜´ÓÓ¯¢©ÔÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:=?>=<9@<<::9?@>=<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÑğ{–«Ø¡˜´ÓÓ£¡ºÔÑÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CFCAB8;?<=;<<8558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÕ«¯¼Àϓӡ™µÔ͞ŸÉÒÑÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF@HIGE@<<>><=><756:96:;::;8@?:<<9<>=;;:?9?:;9=>==;;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦Õɇ…ž¤Ù¢™µ×ß ÒÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;557<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡ÆÓÓ՜˜¿×¡š³Ù²¤¦ÖÒÒÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKL@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÒÑÒר‡ËÖ±ƒÅÖ¹ƒ¿ÕÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<=?GFHKH=657:979:;:<=9>99:8;=>>A>=9<<:=>>:=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÑÒÏÅÔÑÐÃÔÑÒÂÓÒÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?AELLA>775;8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÒÒÓÔÒÒÒÕÓÓÓÕÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEK>>786967899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9699:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EILAALD??;:889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEGIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDJ;AA;<886486987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGIB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<BA<;876797799=?A?<:9@?<>B?:8776=??@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE>;HF89757875898;>>=;89A>=@?A>7596;>AB??@@BB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCEFC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELCA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<;DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGGNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAC?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€ihxsg~‰‰xp‚†{w}~…Š½ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€ƒvt|„‚}sp€Šx‚yƒÈÞÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsoupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿¼½¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»º¹¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjdmgb\XQPQKTJB:IQ?A7<94:565455688686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸········¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®wpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µµ¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@BD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸¸·¸¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶·····¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨¨¨¨§¨©©©§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸········¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥£¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§§¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©ª««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤££¢¢¢¢  ŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž£¤¡žžŸ  žœœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=7789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥¤£¢¡¡¡¢£¥§¦¦§¬¬§¦ œ›¡¡ž›ššœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¥¦¦§§¦Ÿ›š›¢ ™––•š›™——˜˜šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜—™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥¢¢¥¦¦¥¦§¦¦ ›™›¡ —““’—šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB@DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥¦§¦¦¢œž¡Ÿ—‘‘”—›˜–––˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;;;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¥¦¥¥¦§¦¤¥¦¦¥¥£  ¡¡Ÿ™’–š™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šžŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡ ¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢¢¢£¤¤¥¦¥¤££¡¡¡žœš•“”˜›š›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œ ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸŸŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::88:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸ   ¡¢££££££¢¡ ž›™™˜™™™š™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢ ›ž ¡£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œž››œŸžœœœœŸ   ¡¡¡  ¡  ¡¢¡¡¢¡Ÿžœšššš›œš™š›™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥£¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¡¢¢¡   ¡¡ ŸŸžœš™š›››œ›š›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›šœšš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>98;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤£¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ žžŸ     Ÿ ¡  Ÿž›š™šš›››››Ÿžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›ššš›™˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9;;>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœ›œžžŸžœšš›œœœ›œœžžœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:=>:?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››š›œššš›œœ›™™œœœžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™˜˜ššš™™™˜š›œœœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›š™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š››››œ›˜˜˜™™˜˜™™™›œœžžžžžžžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ›››››››™˜˜˜˜˜˜˜™™œœœžžžžžŸŸžžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ››››››š˜˜˜˜™™˜š›œœžžž  Ÿžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_^]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜™——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜˜˜——˜™››œœœžžžžœ››œœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±³­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=9F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œšœ›œ›˜™š˜˜™ššš–‹“–™˜•˜˜–›œ—•’‘’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨©¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‹‘‹ŒŽŽ‹……‡‹ŒŒ‡ˆ‹Ž‹‡Œ…†‹†ŠŠ‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VPQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹‹†Š‹‹‰†„†‚€‚‰‘ƒ€ƒŒ†‹‰…€‡}€’†„„†ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹‹‰‰…‚}s}ˆ€~œ„……‰‹Šz}}†ŽŠ†”‘‹—”—’˜¡–ž—•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¥›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ†‹†ˆ…„ˆˆ‰„‚z||}~’ˆx…‹Šƒ„…ŠŒ‘™””” ššŸ¢­±­©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPFMHSWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‹‡Œ‹Š‡’Š‡†‘“‘‘„‡}}ƒˆŒŽ‹ŽŠ‰Ž””˜‘•›š¨®²¯¯µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWLO_^\NUTbQDTM;?9<895775795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš˜ “—š ™›£ •› ¤£š“ˆˆ‹‰‘‘Ž‘Ž‹˜šŒ”š—œœ›Ÿœ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUKTOOJCPK_bXZQ\S_MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ª©¨§¡¥¨¨«©©¯¡›Ÿ¡££ šŸ œ”˜”˜  ¡¤ž›š¤§¤©«®¬¥£¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdVOXKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®ªª«¤¡¢¥©§§©¨£¢œ››¤ ¥¨£ ˜™Ÿ¡¢©§ ¢¢®¬«ª§­®¨¥¤©©©©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_UZNRNPORd\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢šœ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨¦¥§¨¦©¨£§¦™œ¤¦¢¡ ¡¡ œ˜™Ÿ ¡¤¤¢žž– ›š¢¢ ¡Ÿ ¢¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOWO^ddlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤Ÿ¢ ¢¦¡¦­¦¦ŸŸŸŸŸ™šœœ¡ ¡¤Ÿ¡›šœ ž¡Ÿžž £™–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvwa_\UYQUV[c^r_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?C?:8:>?C@DA:;><@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯«ª¬¨¨«°©¨©¨¡Ÿ §©­°²¯¬£¢¦¡©¥ž¤£¢¦ ¥¤¢¥£ž žŸ¥¢¢žŸ¢˜•žšžŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸ ¡¦¢›—’šš •|wo}yf[[`_Z\V\hdocnihb^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¢ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·®©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£Ÿ¢ª©§®·¶´´¶³¯¬«®«¶°©²±­®§¦ž¢££›œ—¢¨¥¡Ÿž£›ž¡š–¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¢™˜¥ ¤§ª©¨ª­¬¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxib[_^\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>AE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢œŸª²¸¼¼½»º¿´¯±³µ´··¯µ´µ²°¨¤¢Ÿ —•š—¤ª¦¦¡¤£¤«¥¥˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨©«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥ ¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxyxc[RYT__alhukpgiibYSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶³º±ª®´±°±´µ¶¼½¾¼¼½Æº¸·º½´¯µ±±º¸·²³²ª¦¦Ÿ˜¤¤§¨¤®¤««µµ®³ §ª¬§ª©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš“–””˜“š˜Š‹‡€€|‚xa^YSah`fsositdidb[LK>:8898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÃÆÃù½¿ÀÀ½¿Ä½¼º½¾´§ª˜±À½¸µ¹À³¯¯ªª¨­§§¤¯§ª´¼±´µ¨¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`a^^jbbnwuvnl[bQU\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAB;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–•–‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±±§¼¼¾ÅÄÆÉÇÅÆ»ÄÀÅÆÀ¹¯½¼À¾¾³«ªŒ³»¾´µ·Âº­¯°µª«¦ª£­¤§±¶«µ²­³­¨®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|ƒjfhaklfnuqruqf^_\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎÌËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÅ¿ÃÂÆÅÀ±“¾º¿Ã¶¶º©´³´©«³»»±Ÿ›±¯¬¤¬®´§ª©¨ª­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|tkkndolhqxoyiia\gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABB@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÄÄø´À·´¼Á¹··¿À»®¥®·¼·­œ£·°¦­´µ¬®¥¥£¨¤  ¥™ª³²¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyz{vnkiguZfrwsxfg]d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAACB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÉÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÉÆÃÃÄÂľ¸¾ÁÃÀľÁÏÏÎÆ«¯¶´µ« §´³®«¸µ³«©£¢­©¬¦­Ÿ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuueeijh]jomxwcb``^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÏÏÌÃÇÆÈÈÈÇÉÇÅÉÇÈÇ¿ÅÇÄÄÇÈÊÒÏÒ̼¸¶´¸¸Á¾¾º½º¼º¼¬­§ª»º¹·À²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqobagugiitmxl]d[U`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÍÐÎÇÌÉÂÁÆÁËËÇÆÌÉÍÅÆÆÃÆÅÉÍÐÍÏÌÇÄÀÃÂÉÍÇÅÁÄÇÁ»¾´±°°Á¾¿ÁÆ¿¾¸·Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`jjvlietnsb\bTWTSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<:>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÅÇÈÆÒÉÁÃÄ¿¿¾ÄËÈÊËȼ»ÈÇÉÍÈÃÈÉÉÆÅÃÂÁÂÇÇÉÊÇÌÈÇÈÍÆËÏÅ·ÀÀÀÀ»º½µ³³¿¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrofegdjdajmnn^X\VUNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÂƾÆÁ¹»Ãº¸¹¼¾ÁÆÁƺ¹ÉÉÃÅÄÀÄÁÂÁÄÁþ½ÂÀÀÁÂËÃÆÌËÅÈÑ°¾½¸º»¼¾·´°¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfadbabccjbfcZYY\YQNE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶·´´µ¿»½¿¹½ºº´¿¸µ¸³¯»¼·À·½Â¿Á»¿Á¼»Å¾»ÁÄÀ¾¾¹¼ÁÁ˾½ÉÄÀÀÊÀ±Á¿»¸»¾ºµ·³¸¼´½¸µ´°³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|y‡}qc`bbgjffiei]VUSYOSKE8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=96<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“’’˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´´±°µ·µºÁ¸¾¸¿¼½·µ·°®¸¶¹¿»À¿·Á¼»Ã¶ºÈ¸¶¹»½¹º¶»ÅÅʽ¹ÅÀ¿¼Á¾¸Æ½ÁÀ¼Å¸¶·´¸¶¶»»¸¶´·ºµ´¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒ€xpmeefoiekgXXNKKKRILHC9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<97>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’š”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿½¼²­¯¬±°·¼¶»¼ÀĹ···µº¹º»À½ÃÀºÄ¾Ǹ¹¸­·µ¸º´·³»ÅÆËÁ»ÆÀÀ¿½¼¿ÉÃÄžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~†|knpgpksebm_\THKJDJBCG?9;8=<7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘ŽŽ˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼¼À·ª­¤®°·»³½¿»Ä·¶¸¶·¿¿Ä¼ÂÅÅÇÇÊÉÆÏÂÁ¸®µµ¼¾¸»²¾ÄÄÊÅÁÉÿ¿¾½ÇÌÇÇÄǽµµ¶Á½º»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†qelintnwcgb\cQKTHEECGC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?=??FD@A?>:7?@CC?A=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼«ª£°¹½¾³¼¾¼Å¸²¸¹½ÇÉÊÃÇÈÆÆÉÈÌÎÑÌÊĵºÀÃÈ¿¿µ¿À¿ÆÆ¿ËÆÿÁ¼ÀÃÌÊÇÅÆÁ¹½¼Ä¿À¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtolltkln_b^aaNHM?E@?DC;;::;:8;<:9<>9:>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´¼Ã¼ºº¾¼Ä¿·½¿½ÇÌÆÇÉÆÆ¿ÄÄÊÈÌÌÍÊÆÂÃËμ¹½º¹ÀÿÈÆÄÁÁ¿ÅÀÊÉÃÃÃùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{z‡zmmw{_pc[]_^SI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA>>ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸´¼¶º½Á¼»¿¶¿Á¿¼¿ºÀËÂÇÈÀ¿¼¼¿ÅÂÇËÈÁÃÀÀÉÊÂÀ»»°´»½ÀÅÆÅÅ¿À¿ËÇÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²²¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}‚zmsxsgp][^\YQEDCMIAE=G::59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘–žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯·¶²µ³·¹¼»¶»»½ºÃ»·½·¹À»º¸¸µÅÁÂû¹³´ºÁ½¿ÆÀ¹À¼¾ÅĽ¾¹²°®¸·¿ÃÇÃĽ½¿¿Ãþ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸¸¸½¹»±¶²ÈÀ»¶´±°·¬³©°­­³·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|vluzpni\_`YSPAEHGK@DCH<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿš›œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹ÁÀ·½¹¸¹¶µ¿³´²¸±»ÁÀ÷·­°µ¸¸¸Âº´»·»¾À»»¼®¯®³²¹ÁÂÄþ¼¿»º¸¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ¯µ´´½º¾¹º»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§¬¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰|‚zsvvwnq`_e\ZUJ<??FF=FCC9:5;99><<::<>>>>88315789>?A?;:?=<;==9;<:;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Ã¿·º·¶¶²´À¶²´¸³ºÀÁù·³²²´²¸¾¹³µ²¼¹¼¶º¾²´´´°¸¾ÃÆÄÀ½¿¹³¯²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtvrl^b`[]OHA>=HCFMC@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·À½»¼¸¶º¶±Àº·¹¸¹»ÁÁÄû»¶´´°¶ºµ´²¬¼¹¸µ¸Áº¸³±¬·¼ÁÇÿ¹ºµ®¥¬³°¦°­¨ž Ÿ¥­¶µÂ·¶´¥¨«¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´·¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wo{ournc\fX\]RNMA>IB@JI@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³±­¶º®¬¼²¸¹·»¿½¹¾À´¿»¼º¸¾Â¼ÂÊȾÀ¸¸¶²´¶²´¯­»º¸¶¹Àö®®ª²¶¼½¹¶²±­­Ÿ¤§§£¦–™™šŸ©®¹¬««Ÿ¥¨¤«®®§¯¬¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶¯ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmuik][jT]\OMHDFLBFMF8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹½µ²¸´¹ºµ¹»µµ³µ»¼À»¾À´¿¹¹º±ºÃ¼ÂÊÅ¿»¾¿¹´´³°±­°¹¸¶¼¸»¿²²²®±®¹¯ª«­¬£¨¡ž—˜¡•’•—˜Ÿ¨®¤£¤ ¢§¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬«¯£££¡© ›“Ž“’’™–š¤¥ Ÿž§˜•’”˜ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wrxhtsndT`cW\QNLH@HQDMC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;=<<;:@=<<;?>B@A?>958;<FBCD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯²²ºº··µµ¼³¯´«¶º¸ÀÄÁº»¿½·²­³°¯¬®¶¶²´µ¯ª¤ž›œœž¨¨ž ¨©Ÿ¡§–›——“–Ž—›¤¨  ¢¢¢¥¥££ ž¥ ¤¬¤¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›©¨ª«ž¥£›£œ•Œ“—•–˜Ÿžžš™¦—“’–¢ ¥£¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦ ˆxƒ|vybwln\QhTPNGOMLBOQ@>;>49:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;?@A??>949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¥¬ª¨µ²±°®¯²§¦°¤¯®µÁºµ¹Õǵ³´«²´®ª«¯°²³®¥ž’˜”˜ Ÿ¢ œ¤¥Ÿž¨”›–—Œ—‘—“˜¢ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£ž™—š«¦©±£¥¨ž œ•“‘˜–•˜–Ÿ˜›™›£™—”–š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’}|€uu}mk{dhUQcMIHGNRNJNG;E@=2?759;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@CAD>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜˜—–¡¨¬®¶·º¹º··»®¨ ¡©¡ ­«ª¦©¤©¤¥®¥¬¬´¼·¬¹Ù³»­µ¯¯³µª§­¬£œ™”Ž‘–—™™œ ¢¢œ¥žš¤———–’‘‘“š—› ¤ªž¡¡ž¦§ª¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¡¤¡›˜ž¯¨®²«¥ªª š˜˜˜•“–š“••™–›——˜ žœœ—›¡šžš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}vx|dxy`bRU_HIIKSTIRPL9?B67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—““œž¤¨®­¬««¯ª¯©ž—ž¥ž¥¦¤¡¢Ÿ¦ ¢¯«¬­µ²·¦µÔ™Á·²±±°¸­§¡œš”—ššŽ‘•‘ŒŽŽ”™¢œ—£™š—˜™”™˜–›Ÿ¥¦© ¦£ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§  £±®²°´©±¯¢™œž¡™››š˜™›”–›–˜œ¥¡ š£¡š™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ Ÿž ¥¡žž¥ ¦™{|uvsh‚le[SZYMQJNNULRLA7>B68=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’’œ˜¡ª¢§ ž§¡¥Ÿœ’œ¢›Ÿ¡£Ÿ Ÿ¢ ¢¯¯¬°±ª¨ª²É–¦È°®­¬°§ Ÿ¢ —‘”› œ™—’“Ÿœ¡¤›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬¨¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½·¾°¬±®­©ª´±°¨«¨²µ·³¸¬±´¤ ¥Ÿ¬¡¡¢  š˜–– ››˜¤¡ ž¤¡Ÿžšœ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚|xuiwu]lZR`HQUHFUVJBLG=KH8E<67;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“ž™¨®ž§žœ¡žžšš’™žœ¡¢  ¡¤®Ÿ©¬£ž—…{Œ‘±”ˆµ¯¨ª¬ª¥ ž™’’“˜˜––•Œˆ‹Ž•ž–žš¦  ¨¥±ª§®£«­¶°´²±®¶¸½Àº­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«¯±¹·¼¯³°µÁ¼·½³³µ¢¬¢©¨²©«¨§¨š™žšª§Ÿ™¦ ŸŸ§¨¥¤žª¡¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰…„~vqmivmhm\X[BVMJGMGBFM<>L=4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜šª ±¢·£°¦Ÿž—˜•™ž›œ£ŸŸ£¦Î£›¥ ‰vƒsbhk}‡ƒ¡³®®©«§ žž¡¢Ÿšœœ”“•”žž˜”…š¡›«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶ººÀĹ½»¬¯§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¹Â¾¸³»Æüü·³©³­ª³´¯³®ª®£«§¶±¬¢¯¦¡£¯±­°¤¤¯£¡ š¡§¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¥ž¦™›¢¤žŸ›››œ‡…{trkkurphW[QETHDIOH>EA4EH95;=6;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<<;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥žŸ¡œ˜›Ÿ › ŸŸ—¢°Ñ«”ŽˆbqŽlb]`x ±¯§¤¤£ ž¥«¦ž—œ”‘™˜”ŒŠ†ˆ†ymˆ ¤¢«¬´¼¶Ã¾¾³»ÁÃÂÅÀ¿ÂÆÆÅÃÈÂÀÅÈÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌÌÌÒǾ¿ÀþÇÆ·ÃÉÉÂÀž¹´¹º´»·°µ²ªº±®»·¾ººª·­«ª¸º´¼®®¹£¦£ž¦¥¢£©¦™›Ÿ˜š§ª§ ¡¡¤˜”£–”š‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ„}zrkdhoxjeZ[FKLEDSLDBE7:?;549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ³²¸§¡¡«ª¢ž¡¢žœ› ’œºÎ¢†nc‡_W‡ˆœ°ª¡šœŸŸ™—˜˜’Œ——“Ž‹‚ƒ‚wsqnp¦­®´¹Å»ÍÇË¿ÂÌÎÍÌÇÉÑÌÍÌÇÉÅÆÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÒÓÌÓÐÓÓÌÊÂÅÆÇÊÇοÈÑÌÇÅÆÄÁ»ÃÀ¾¾¾µ½³­¿¿ÂÂÆÄÇÄ®¾¸²¸¼ÄÁÁº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›‹™‰•˜› Ÿ£—žš““‹•…€ytsebgrof^ZYCNLCEPIDC@5558:B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>8;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›£¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¥¨¬­ª¡£Ÿœš©“™Æ•k\j—[Tq›°³­¤Ÿ ›˜—”“”–‘Œ‡„ƒˆ‡ƒ€€yrroly¤¶º¹¾ËÁÓÒÓÈÍÎÑÓÑÒÑÐÑÑÍÎÎÐÅÎÔÕØÒ×ÍÆÇÉÌÃÅÊÏÊÒ×Ñ×ÒÔÖÓÓÈÌÇÍÍÉÒÌÎÓÌÅÇÉÊÁÅËÆÈÈž²³ÈÄËÊÊÎÅÊ¿¾¿½ÁÇÄÌÌÈɿÿ­¯³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›•Œ†‘‹€zruvgcgvidVWQDMF@IQB=B<:22@<D<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<@?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­´¸¬®£Ÿ¤£Ÿ ¤¬šŸÏ´Z\}‘k®®¥¡¥¡žš•”–”Š}wpkebhqoq{…Š€vpnqtp…³Â¾ÅÑÐ×ÖÖÒÖÍÔÖ×ÔÓÑÓÔÔÒÏÑÃÐÓÖØÕÖÒËÉÎÑËÆÍÑÉÒÕÖÙÕ×ÓÖØÎÒÊÏÑÌÎÐÌÒÏ¿ÇÆÊÃÌÌËÎÏÅÆǶÀÊ¿ÑÌËÏÅÉÇ¿ÃÂÈÎÌÏÐÏÍÊÈθ·»¨Ÿ¥«§ž˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„|xsvpc`erb]R\IJGAEHI>;@8=4585;86:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÂű¶¨¢¥¦¡¢«µ¥¥Ò¨jZu•£­­œ•˜ œ›¡¢Ÿœš–Šwic`____^_`^blusqpolrqu’ÄÇÆÔÕÖ××ÓÖÏÕÔÚÔÔÎÏÕÔÔÑÑÌÐÎÓ×ÖÓÕÐÏÒÓÑÉÓÑÇÐØ×ØÑØÒ×ÙÕÖÌÏÏÉÍÑËÎÏ¿ÅÂÇÅÎÍÑÐÑÈËÌÀÊËÅÓÎËÎÈÄÉÆÆÈÌÊÓÓÑÕÏÒÌÒÁ¹Å±¥¨µ®§š¨¬¥²¨°³¬¬““Žˆ‹Žƒ‹„Ž™“™‚…Œ|zqstmacim_VP_JJCFCQM?<>54:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><??=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯®ªª«¦®¸¨«·×ÔÕÙÙÑÎÐÀ¼ÌÉ·¿¯§«©£¤±µ±¯Í¡ZdŸ­«¢™–˜š›¡šœž“~recb__a`_a`_``_`fmppnkorww›ÌÀÒÕÓØØÖÙÑÒÒ×ÏÓÎËÒÍÕÔÒÊÏÌÓÖÒÑÖÍÏÕÕÑÆÑÔÊÐÔÕÖÎÒÐØØØ×ËÈÍÃÈÎÌÊË¿É¿ÇÈÍÎÏËÐÍÎËÎÎÇÊÏÐÊÎÊÂÉÆÉÌÊËÑÒÌÓÑÑÏÐʽȹ°®»¸µª¶°­¨¸­³¿»±šŸ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…ˆzvopokadnpaW\ZIFFDMWE;@<33<=87855;>@=9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6==?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ¤§Ÿ¸¶µµ­¥­®¾´°ÀØÒ×ÚÜÖÏÍËÄÓÐÂÁ±ª­®«¥²±¶¾Ì—Z¢œ–“—œžŸŸ”–˜”‰k^^^adb``aa``a^__^]bmroostvvy¤¾ËÕÑÖÔÓØÖÎÎÔËÍÎÅÎÊÒÒÏÆÎÍÍÔÌÎÓÍÊ×ÕÐÌÑÔËÌÐÑÓÊÎÑÕÒÕÕÊÀÊÁÅÌÂÈÉÂÌÃÅÇÊÊÎÊÍÌÐÍÓËÅÈÏÌÈÇÊÄÆÀÅÊËÍÏÑÆÐÎÍÍÌÏÅÇÀ·¸½Ãýù³²¾±»Ãĵª˜¥¢™–‘••’‹”š‘”””‚‰…xpqkmg``qhXXhVLFLIPPB;D>;67:89:57==A;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;776?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÅÃÁ¿»µ²±Ç¸ËÕÖÙÚÛØÌÍÏÈÖÕÅ÷±µª£­¬¸·É͗ˆšŽ˜•”’‘–––Œ|fbbb`]^acb`_``aa`_][]grqqrsqmry¤ÆÓÏËÐÏÔÕÉÅÉÉÆÆ¿ÃÆÏÎÇÅÇÍÊÒÈËÎÍÆÑÒÏÎÌÔÊÇËÎÏÇÇÏÒËÐÏźľÆɽÂÇÉÎÄÁÇÀÇÍÇÃËÊËÏÇÃÃÐÈÆÁÅÇľÀÇËËËÎÂÊËÈÇÌÐÄÅÇ»ÇÃÈÈÂÏÁ½¼¿°ÁÉǹ½ª°²§¥¢œ˜›£™—™‘•˜‰‚wntdk`^fqa[W`GHHGIMTG?J=64355=<48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ½ºÍÍÇÐÕÕÙÚÛØÐÊÏÐÒÔÉĹ½¾¯§·ª½¹ÎÉ¡”ŽŽ—†ƒ„„‚~……t`\^^^`^`cdc_]]^_``_[Z\akrrookloo}¸ÑÈÉÊÏËÍĺÀû»ºº¾ÈÆÂÃÀÃÇÊÉÈÊÈÁÅÌÆÈËÍÉÄÂËÉÁÂËÐÄËÈ¿¹Á»Åǽ¿ÆÏËÿûÉÆÈ»ÈÆÄÊÀ½ÁËÆÅľż¼¿ÃÄËÅļÀÉÂÅÇÒÄÀÈ¿ÊÉÆÇÆÐÃÃÆïÄËÇÃÊ·¿¼º´©¬¤¥˜Ÿ˜¬£¡¥š£ ›”{vstfiZanmZ[XRDLFBGDLDFS@54334?<3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ËÏÑÌÇÂÃÇÍÏÏÌÕÐÖÙØÙÐÌÓÎÏÐÊ÷ÆÀµµ»°¿¶Ò³‘Œ“˜‡z€…†€vxurq_Z[]``bddded`\\]]_^`[YZ\borokilposÆ¼ÉÅÌÀÆ°¶º²²³²±Â¼¼¼º¸ÀÁÁž½¹½¿¹ÄÊÅƽÆÀ¸»ÄÉ¿ÂÉ»·»ºÅþ¼ÁÍÃƾ¾µÁ½Ãº¼Æ»Â¹³¼ÅÄÁ¶¿µµ½¿ºËüµºÈº¿½ËÃÁÅÂÅÈÆÈÆÐÆÂÌDzÇÉÃÎÍÁÅÃÀ½²·°²§¨¨¹°¥­°«­¬”yvwjdg`hocV^YJFJFHJAEBEI@9:648853;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÆÃÄÈÎÒËÊÊÇÍÎÏÒÉÑÆÖÔÖØÎÌÐÇÌÈÊĽÉÁ±´¹¶¹´»“Š‹…y€††€~„|tud\\]^``bcabeeb]][\^\^]Z[]]hsqmggnpry½ÌÀúÁ¸®°°§ª­¬§¸´·´²³´ºµ¾±·°µ¯²»Â¼Áļ¿ºµ³º¾À¸Ç¹´»¶À¼¸½ÆÁûµ®²¶º¾´Ä·»µ«¸½½¿½°º¶¯¶º²Å¼¶®»¿´¶´Å½¾ÃÅÀÃÅÆÈËÅÀÆÆ»ÈË¿ÏÊÇÃÆÂöý½¶¹¾Ç¿¬µºµ·¶Žxtxfgebkn^V^`FKHHJFBDAEE?<:565633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÎÈÆÉÎÌÐÌÎÈËÉËÊËÅÑÎÓÐÏÇÉÅÉÄÿ¼Ï¼²·»¸µ´›Ž‡‰‰{y~††wx‚}th^]]]_`_`da^dec__\[^\]^Z[[]_lpmhfjmnr|¤Ç¿¸¸µ°«¬§ž¢ª§ž«¬³­©«©´­¶°²©®¦¬²¼º¶Ã¹ºº±«µ¹»´Âº°¿±½¼»¶¼Ç¹Â¶­ª¨°±¿µ·¼¯°§±³´»¼«­µ¥®¶®º±°ª¸°­»®»¸»¿¿½¹Â¿ÇÃÅÁ¼ÆÁÈ˸ÅÇÅ¿ÆÃùÄÆ»ÆÉÌ˳¹Â¼º²ˆrvvkiablhYXW[ALKMIEAC?FA:9:995854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÆÎÒÌÃÆÂÅÐÇÎÂÄÇÀÆÆÄÄËÂÊËÁÃÀÆ¿¸ººÉ¶³¹º³±©‘‰|y~Š†z{…wo^]\]]_`^_dcbccb`_][[ZZ]ZZZZ\dnohfgiknr­¹°µ®¦¥§§š ¤ šœ¥«®£§¢«ª¬ª°¤¦Ÿª­µ¶±½¹¯·¯¨®·´´¼¸´¼¯¸¹´±¼Á±À®¥¨¢«±²³§¼ª«¨«¬­´³¥¨­¡¤®©²¥§¨­¥¨·¬°²·¹º»±»½¾¾Ä¿µÁÀÇÈ·¿ÀÄ·Ä¿»¿Ä¾ÄÈÌÊ¿¾ÃÀÀ©†rtrji]aodWVXPHYRSKFFE>>@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÅÑÐÍÄȺºÌÂÌÀ¼Ê¸¿ÅÀ»Ë¹ÂÅĸ»Á»·µ»Ã¶³µ¶©­”ƒ‰|~€~xt|swf_]\]^_`^_ccab``_^]\ZXZ[[YXZ\_fkfegehkor…ª¥¬¦ œ¡¥”¤›˜’¡£ª£¢Ÿ¥¥§¥¬Ÿ›¤¦¬²¯¶·§°¬§ª´ª´º±¶µ­¶¹±¯º¹±·¤Ÿ£Ÿ¦±§«¨¹ª¤§¨¨§²­ §¦Ÿ›¤¥¬žŸ§¤Ÿ ±­­¬²´²´°µ¼¶»ÁÁ²º¾ÃÁ²¹¹Â³À½¿µ¸»½¾¼ÂÇÄÂÿ¿Ä ƒwpkaf_ko`UY^HNgOTGEJF<=?=:;;825536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;=:7676778666;::;9;;<859<:>>@;Èµµ½¸ºÀº½µ ž”¡¦º¶«³³»³ÄÐÉËÃǹ¸ÉÂÍÀ¹Ë¹¼Ç»µÇºµÂı»Ã¹³­¶½¸¬¯±©ž„‡‡‚}zvtomkjjqi^`]\\\^`_acb````]\[\\XYXXXVX[^_dcbegggjmoˆ© —•š¡–›¢˜–ž¡¢¦›ŸŸ£¥¡§ž›¢›Ÿª°­±µ¢©ª©««¤´¹­·°¬²µ®²µ®°ªŸž£¢²¤¦©¸­¢¦¦Ÿ¨¬ª™Ÿ ž™Ÿ¥šš£œ›¯©«§ª«¬­°²¸¯¸¹»°¶»»º«³³¹³½´¶±±µ´¿¶½À½ÃÁº»½—ƒzrk_e^ddXTX]IW\KPGIIFA<??@;?<04535:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»·ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÆÐÈÉÁǼ¼ÅÄÏ¿»ÉººÁº´Ä·³¾¿±¿Á¹ª¦±¶³¤¬­£‰†‡€ysnpnkb^bff]]^]]]\]_`abccba_\[[ZZYXXWWWXXXZ^bddeffhikr¨”””›˜›¡––‘œ¡¢¨›¥¦¡¥œ  š˜­®­®² ¥¢­«¦¡´°±±¬¨¯²§º³¦¶¡¢ž›£¡­£¡©µª¢£¦¥¦£–˜ž—™šŸš—œœ¬¡«¦£¤¦­«³³ª´°²ª²¹´¯©¯²²³·³®©¬®²¸°º¶¹½¿·²±”…yue^e^[YVSZUK[QLIEHKIB=?AA@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½·½¿¶¾¼¿³¥£˜¥±Âµ¶½­´¸ÂÍÈÇÁƸÂÁÈϸÂÆ¿µ¼¼µÁ¹µ¼¾³¸¼·¦£­¶­£«¨–}„…€yprtqifdhec\\[[]]\[^`a^__`^\[Z\ZYXVWWVXXXXVWadecdeddhjv¢œ”””–—Ÿ—™”˜Ÿž¡œ–¡¡¨£Ÿž©œššª¦¯°«›££·ª Ÿ®¨¶©¦§­°£·°¤·Ÿ¢›˜˜ª¦¡š¬¸°¢¡¤œ¢  “•¡”•–›˜—–—œ•Ÿ©©£¡£ªª°®¨´«ª¦­²°¥ª®²±°°®¯¦§§²®±´¯¼´º·®£”yud^aVYWSRTKM^LPKGGLLE<@><B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾¸¼®§§£ª»À½À¹®´¸ÂÍÉÆÃľǹÉÍ´ÃÄ𾾸¾¿¸½½··¹³¤£­·¡¢šŸ‡€}yrjmrtphhedgb\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWWV[ccbbcbcdfj–“•‹‘”“›™œ––› œŸ• Ÿ¦¥¤¦§žœŸ¥Ÿª¯¦Ÿ¢£¶¨ ¡¢¨´¡¥§¤¯¥°­¬µž •”©¡¢”¬±±ž¢£˜›“‹¡”‘“—˜’——˜–¦›¦¡¢™£¥¥«¤¥°§¥£««­¦¨®¯®«¨ª©³¥¦«¯´±®¼µ±¯¯ ’zvrda\Z]XNLRHRaMVPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8846863321./2556;:8;7876<;:;;A8x»»±µ½°»±·¬ž¤§­·»¼Áź±¹µÅÊËÁÄÇÇÈ·ÇÅ´ÄÁÈ®¹ºÀºÀ¾¿»¹´¶²¢£­±™›ƒ”ˆ€wodbgihfhjgjm`]\[ZZZZ\]\[\^_\ZY[YYZ[WUXWTTWVSTRU``_`a_`acdi““ˆŽ”’“œ”•–£™ –œ ¥¡­¥¤£¢£¡›ª«¥™ž¥±©  ¥«ž§¡ž¬­©¨®­¢¡¢”—£›œª¨°›Ÿ¢Ÿž—™“Šž‘’“•˜˜“›¡¢œ¤ ¡• ¡¤¦›£«¥¢¤ª¤«®¥­²©¦¥¦¦´¦©¨­³µ´¹º¯ª¬ž‹rpo`[WVVRGQOHZ\ORITKSLEGIC8;;=<8667:9;:976977:;:=<<6;<8>598:88659:;<97?<9678452121..1426:8698698989;9@9{µ´­´»²¯«±­§§¯¹¹³ÀȺµÀ¯ÆÉÍ»ÂËÍÈ·Ë¿³ÀÆ˯´»Å¹¿ÅÁº»³¶± ¦«©—’Œ„|ujjjlhjlmkjme]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURSOQY]\]^^^__bdmŽ„‘‡‘Ž™“”’œš¢œ› §¨ª¨ª¦¨¥£˜¤®¤”™¥¯©Ÿ›™› ž¯™›ª³Ÿ¥¦Ÿ££¡”“›––’©ª­šœŸ¡ š”Œ™Ž‹Œ’–•ž¡ £œ›¢•› ¢ ˜¢¨£¢¨« «¯¤®·¥£¤¢¬­ª¨«®²·²½µ³«¯˜ƒssh[XXRUREXLQ[YMUNPLPQINIB<??A?<65799<<987:79:;<=>;7;;:=67:;8976989:6:=99577571141-+/434988::8::748=8?9~³®¨³¶®©§¯­›©¨¬·¶¬¼Ê»¶¿¬ÌÇƹÂÏÐȵƽ¹¾Å˳¯»ÃºÀÂÀº¾¯´«¡¥©¦—€wxoninnnphgigd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUTSNPQYZZZ]\\^_`d~‹ŒŠ’—‘—™¢ ›Ÿª©¦®ª§¯£§™Ÿ¬ •–¤¨§—šž®–—§ª™Ÿœ”¥¡ž’“’“•§«¥š™™–ŒŒ”†ˆƒ‹’•‘ ž £—•Ÿ•š ¢“›¥¥§¨¨ ±°¦±¼§ £¬´ª®§°´°¹µÀ±­±«}qrbVTVNRIGVQRRLLXMJLNRGMKACFDC>@75889;9:7::7<=:;@>:9;9:?759:9876958779;85576661321-*.102877;99;8948;8@8³­¦±·ª¦¢°«ª§©²±¤¶Æ´¹º³Ëƺ»ÂËÑ̳¸º¾ÀÄÆ´²µ»°¸¹Áº½­¯©¬¨ª¥•˜‚kgmnroqkpkdfge^ZYZYZZZ[ZZZ\\]\ZXXXYYWXWUUTRSUSVURNNNRWXYYYY\\]aj€zv‰‡Š˜‰””—›™¨šŸ©¥¤ª§˜ ¥›’ž¢š—–…„’š£“¢œ•–•‡¢šš“‹Ž‹š¤§œ••—›’‡”ŽŒ‹€Š’’’¡šŸ¢•”˜˜•¢¥™Œ˜¤¦¨¦¡ ´²§³·¡¢·¬©­¤²²¦µ»µ««±£ˆxql]NQQLOCMNNPKFNNJJNMQIMJAGKHGC=858889:;69:68;99><8:>9;?8789:886857688974577820301*)-/12776:999984988A7w¶§¤¶°¤§£©¥ ©¥¤³ª¢²Ãµµ²³ÇƸ»ÄÊÍǵ¯»¿·ºÃ²±¬´¡ª²À¶·©¦§¯©ª™Ÿy_`gsqvqjniehhj_XXXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQMMKLSWWVXXYX[]aosvq…ˆ‚ˆ€‘ƒŽŠ”‘“ š›¢¡£˜¤–¡›•‡˜šŒs‚}—–…™“ŽŽ{™ŽœŒ‚Š€‰˜Ÿ¢ž“˜–„Ž‚“~~t‰Žz‡“š™š•Ž¢£Ž‰š ¡££›¢´¯¬¯¬Ÿ™¥¸¦¥°¡°®œ°»ª©¯ª™vrbUMROPMCSNLQMBPQHINSMHJJCJLFKK<749888;;69;7:<9::;79?9>@79:<89764445874312585/0102)(,-11764789::65:87A7x·¢£´¨¥¦¨£¦¥¦¦¦³§¥´Á¸¯´°ÊŸºÁÏÆ¿´®¼Ã®°Æ°«¥ª”¡«¼´¬«›£¨§¥‘ŽšoWW`hgihincjigb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTRMMJHNSSSTUUWY[]ilrm…|tNXr‚—†œ—‹“Ÿ—•”–”Ž–‰“‰_;Wo{‹”‰€‹’Œ…†sŠ„–y‚z…””ƒ–Žƒ†}’xro…~‰‘—™˜“Š‰œ‡ž—‡ˆ–žš¡ —§¯©­¨¨ž—­³¢¦­˜¬«˜§´¢©­£’}rm_[NSRVLDTJPMLFNOIFLQMKOJIMPFII<7599999:7:;:>>8:==6:?8>?589;79675333760.-/344110//((++-3854779<:79;86A9y· £­¡¦¦ª §©§¢©°¨§´Á¹°µ°Èø´¾ÏÀº°°·Äª­È¬¥ ›…˜Ÿ·ª££’¡ Ÿœ‘‰fQMRVZZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MORMKHFHNQQMPRTVXZ`mpi{‚tPBA•‘‘}‰”Œ„Šš••Š’ˆ…•†xˆ`JQnxŠ‘„}„‰…n~”wuuw„™pQˆŠ‡|~x“vhw…‡~Šˆ•Š‘–‹„Šˆ”„šŒ„’›–žœ”¤£¨©¥¤ž›°ª¡¤¤¥ª–¡©œ¢¦¨ˆtle^[HQQRMIUMSILKOIHGJNLMTKQQOFHC<769:8:;;8:;8>?99>=8;<6;;478;6775344696/3/.125221/,')**,4833979:99::::?9w¶›¢§Ÿ¡®¡§¨¥§¨¯­ª¶¼¶¸·³Â¼·¨ºÉ¹¶¨©¶·¬´¿© ™‘—®ž•‰›’”‹…†bMLNNOLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDDINOhYNQSTUZnƒtw~ji]U‰”‰t‡|…Œ’’™‹{†€uxsnupty}Šª…yzhv{Žprmx‹Œ’xz€{€vsr’wgu„„„„{•‰ˆŠŒŠ€„‹Œ”ƒ{€˜•œ•‘Ÿ©žŸ  ©¥Ÿ˜Œ§¤“ Ÿ–žž¤rg`\\JVORGKXROJMMRJJJMPHLQLRTMEHA<77;99>=:;<98@?::>=7==79947795675252572/2.,//200/-+(().1372198798775:<;7v®˜£¡˜œŸ´©¯©¥­¬°±ª½´²»¸¶»µ² ·»³«ž­ªª³°£œ“—„’¡”šˆ€”†‹…‚}bKIIHGFHHPTTTWWSTUUUVWWWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQRSV^uƒ}ygw—˜Ž}gyvx€‰|„˜’r‡|v{ok~­|sŠ{†’}tfv|†lohs|‰Œ‡€lyq}pmuqhq€~ŽpCŠ„‚ƒ…wwz‹…}‹zu~Ž’˜Š’š›£–™œšž¢–Š¥›ž—Ž–˜vnlebZWWTQJSUTOPNQVKNKNOJQNHNOKFD<;79;::?=9<:99??;8<=7<9999266856633621224.,,-..-0-+*''*.1362/876966527995y¦—ŸŸ– ¦¯¬®«§©±¯±«¼¸¬»¾¹³­¨›±§­œ–¦ª¥¢™›‘‡”}Œ“’}y‡x‚~{{|bKFGFA@CDILLMQRPQSUTTUVWWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNPQTX^eprmˆ§ªÀ~uyb{xn|yˆy|‹…omŒ‘xsxjj€‚r–‘‹}–€I’˜nhx~‚licly…’†ksl|nr{†hmps‰„…z}~{vots…‚ywp|ŽŒŠ”ƒ–—˜š“•–™—ž—Œƒ‰Ÿ‘‹’†–~mhmnnWUWTRQYORUUSXUMNHNJMNKCHNGE@:89;99:><9<;::=>:8:;9?868727575541442/024*+**-.+-*(*(',-1250,4567485HA895w™‘›™šž¥­°¢¬ª¨µ¯®¬´¿«¼Â¿¦¢š•¥˜žŽ…Œ–¢¢™™’•u}ƒ‰Œzv|r{vrvydOEGD@<>>AFFGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_IMOORWZRY\`§ˆbšitze~pmz‹‰vˆ†tlš‘ts{jkMy…’‰„Žg1v†sl~~ƒtfet~„„…€filukp|gpp{n“Ž{s}|qpnum‚~wytiy‰‚ˆ‰ƒ–“’‹‘””—Ž€yˆ—ˆ†Š†€‡vjjngdWQZWYY[MPUVYYNIHEJJHGBAFDCG=998;9:9<:9;:::@<9:<98>787715244533645031.**+),,++)(+'),,226,+5775478iO8;5n’ˆ™‘š–¤¨®ž²Ÿ¦º®«²°Â±»ÃǛ–•™‹†z…‘™•Ž‘‘ˆsˆ„wŠ‹~uvtvumwqgUFID?<;9:?@ADDEGJLOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOPQVLAIQIb¯³ q|xm}lrƒ…z„††yr •tx€su”‡5q¨Ž¡¡„¢„vp†|‡|sŒ­‰€hfbinrmpƒuioXupŽš’vl{}mqmp€zsvmbv„†€…‘Š‹Š’‹‘Œ‹ƒux‹€~ƒ~zqpok^Z\][YX`_SN[ZYXLHJEJG?CABG>CD=;97=;:;;9:99;:?<88=:8;66651121353475531./,,+)*))***)(*)+/3DM2166643<vR7=7b’’ˆ–‘ž¤§ž¯•¥µ©­±®Á²»ÁƗŒ”‰}n‚‘’‰„‹ˆ‡vƒ…n—ŠŒyz{q{s|jn^JPG>@7448;;<=>@BEILLLMNPQSUUVWXYXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL7CMRSDJ†v€||v~mwˆˆ|}…ƒŒ~v¢™y~†…™„›œa†ªŸŠ‚zvˆ~‰ˆŽsŠ—ƒ{\dqtz{wŠlgiayo…‚znwt„zptywkni]w‡}‡|ˆ‡€‹“—ƒ…‡}q„„|uw{}‰uorsef_[Z]S[f^WQUX\VGJJDKG?F@DC>AA=:97<;;=<::99;;=>79>9986754244004645654-,)+('''&(())((+++/00Uq<23331E~W4=9\xŠ€”Œ’Ÿ¦‘ « ±¨¯À±ºÅº–Ž‘”ˆz…vk€Œ’ƒ~‹„yƒ‚t¢†‚sƒ€|kylSWL@E211267688:<?BEGFGJKMOPQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMORLKT]YRJi„ˆ{‰y|q|Œz|‰†~—‡v¡™ˆ‡’”¥¬©H†®¯¯‹€“Š‚‹„‘¨‡€˜˜Šœsl|†‡}Žhfgx~n…†‚…q„…Gk€wryvhmk_v}ƒˆˆ…Œz•žœŠ‹ˆ‘{u‹v|wmow~rrqjZ\\[ccXge\UPPWYPDLKFNICFCCA@CA=988:::;;:888::?>6;>7585773344236756768;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^…t|~Š…ˆ‘–˜’— ¬¡¦¸¯³½³—’‹˜‹}tp‰“}Œƒ“•}†‡¥ˆ‰ƒˆ†yˆ‹u†y_cVKB60./23123668:=??BEGHJLNQSTUTTVUSQOGC?80,#‡[>?94.]–ps£UFIKMNPW`YpZ\^j“‡•„‚…‘“~…‰‘š•‚¡¡—•›š¥­“š»±§»Ç苌¡¥Ž“‰{rƒŸ‘œ~v……Š‡ihoƒ€tŒ†„‹q†‚w‡€{v…}nvug€”†‰ˆ‡ˆ‡¡«¢–‰Ž˜{‚‰zzogkx}x|qic]ZY]i\af_ZOLNXRQIPKDNGCKDCADDA<:87=<:<:88778:==8<=68656623444576867<BB?<8:>CQ^e\G2'&,,--.1(?Œ[.310Oƒ_4?;nupgxƒ{€Œ€‹šš¤œ¡¬¦«¯°—‘‘„¡”„xw€”}’†“–Š€’›Ž„‚Œ‹‚ŠŽ„€Š€lpj]CA4--//./02234779;=?BDHJOQRSRSTTRPOHDB<87/9D><<63.l“—MPHIKKKNV`cggmu›š““‹Žšˆ“‹  ’£ª¥£¬“¨¶¢¨Áîǯxº”š|Œ¡ž˜„’…‚¡Ÿ“˜’„Š…˜‘–lpu‰‹•Œv„ql…Š–’ƒ…ˆr‰¡–†“Š–¥µ©›•¢ƒ‡“„~kjk|~~q_\b^Yfj\lk^XKHOSQNMLFIPCDNFBCEGB>:97=<:;:987767;:6=:785456345566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<unhYpƒpu‡qv’†~—–š”ŸŸœ§ ª–“˜žge¤š~…“’z€‘‰‘’}Š…™’‘ƒ€€‹‰†‘‡„ˆ…xxgMR>/..,/.-/000212457;?CFNPRTPQRSQNPIED>;<:CF?><852<?R5HHHLLMNR^oŠ|s} ›¨¦¢™¡—¢•œŸ¨ž©«Ÿ¨¬©ªµ—«¿«¶ÈÈ·ÉÑϾ› pi«©Ÿ„“’…œ¡šš™§‘‘ˆ•¢ššwz~”—‘¡’–—”ž{v•’«³‰— }”žœŽ“–™¤¢¦¶°‘™¨ˆ—Žˆlss{}zof^[_^`fc`gg\REKKPOIJLFFMCGMFFCBGDA:85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Pqu`n}bwŽ}|”ŽŽŠŸ’—ž–œª˜žªBD}‡‰‡˜x‚‹Ž{Š†Ž‚ƒ€‰ŒŠ…“…ƒ†ˆ€‡w_bP460-1/,.00./..0015>AAMQRSPRSUSNSLEE@<>=GGAA@8662<9;FHGIIMOQYm†w•‹£§ªµ½¸¥®¬¬§¨´¬±·²²­»±³¾œ³Ä¬»É˸Ŀ¸¥£°²¬­ª£‹–˜…¦¦ ¢—‚¦™¢ª¨¤‡…“£  ª ¤©Žœ±‹•£§·»› £°“££ž‘¤¢«¯­³µ¢•¥ª‰šŠ“Š•z{~ƒ|e_f[d`]bc^ff_[ODJHTOFHLFKHEFHAKFCFFA;87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLicXjpXz…v”…ˆ‚›ƒ’’Úȝ–sV—ˆˆœ|†Œ‹Šzˆ‚‡‘Žƒ…€‹……ˆ’†‚„‰†‡‡‡qna@E64<2/110-,+-1/-4?DAMUQRTUUWUM[PGGD<>>FHCD@7;<5C;=FKIGHROPW“ „®£³ª²ÁÈÄ«³Å¶¬³À³¸¾¶¿´Á¶»»¤¸Æ©¶ÉǶ¾¹´¨£´­°±›™’šŸˆ§¯ª¤”vŸ¤—¡«±³˜–©­¨®µ»²º¬¯µ¢±¬±µ¼·µ®µ §§£¨›©°­²º¸¸§œ·©¥’“ †ysW`bTe``b__e_[TJDELVQIJJDJHEA@@KDBMF<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AEWQJL[ZQcdWzuq‚”}…†“v†€{¿»£¼‚´”“Ž›„ˆ“‰‰y‡€Œ“Œ‡…Ž‰†…ˆ…Š‡‘zyn]V@EN<6:46AB764//6CHCQ[OQUWU\WO_UIKJA@?GKFEC;>@7D7?BJJEGWTP^¥­£±´Ã¶¸ÁÌʶ»Ä½³´Á·¸Âµ¿°·t±´¦ºÅ¤°Æ¹±³±´¨¤µ¶ª± ¢–›¢‘¥±­¥­«§¤˜ ¬³º¢¨²¹µ»¾Ì¿ÅŽ½³Â·º¸¿·º·¹­­±¦±ª­¾°½»Â¬™»¨•­˜˜ª‰~€yiVa_WicidU[cYVTIHGLQGDIJAHD>?BBK@@MD99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FQLALRWTZVZwjp„Ž…nzsxˆb¸¡š£‰•”–“”“—’‡‡{‡•Š€„Šz|‹‡†}Š‚‹„•}xzueO\dGEL:Qda[^SF>;HPDZdQQYXZgZT`aMSOEA?IJHEFA@C=E6B>HGKMSZT^”¯¸µº¹ÉÀ»½ÊÌ»½À»·µ¼¼·¾µº²Æ`u²¥±šž«¾ª¥¨«ª¤¢²µ «¨ž•–ž˜Ÿ®¥§¦¥Ÿ¤“¢§°³¨²²¼¶Á½ÓÉÉÓÆÂÅÌÂÊÃÀ¾½¿»¼·´°¹··ÃºÆ¾ÃÉ°žºª¢¬¥¨¶‰€}p^``\V`]geRXaVRVIEFNK@>HD=KB=B@=F>;H@796379>489:57045/26389373526?8@>GKRTTRPOQRQJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKE@IMPRLQ]gmlq…slsrsˆÕÀµ™ •™š‘Ž—‘––Ž†‡}‡ƒ–‹ƒƒx{‹„‡{‹yŠ‚—t}zlepvY]\Peeb`ed][XW\MdmURmn_o_XgeUYTJDAKKHFHHHHBI9D?HKTTV]Z\“¹À¹½·ÆÀ»¹ÊË»·º¶¸¹³¸µµ®¶¶™du©ž­p^¢­œ˜¡¢›¤ž«¥”ŸŸ”–˜—¨Ÿ¥Ÿžš™ƒ¤¬¤ª°­·°¼¸ÔÐÎÖÏÉÌÒÌÏÎÊÇÀ¿ÂʽÁ½ÂÀÅÄÆÊ¿ÉÏ´¤»±µ°›¬¹½š~xj\_[X]`XabQ[`SQKCBEFE<@F>BIB@D=:E>=J?47535;=468977022/24169775555D3ELM>510006:477@IOJ;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODR\Yi`o—’‘”nlotu‡³¬¡¡Ÿ‹™œ™•‘›’…ŠŠˆ‡ŒŒ‰|ƒs{Šƒ…{Št‚Š†•s{ylmu|iseilifjji`fihmZmt—­¤¼‡‡g[oh]ZYTHJNPJKQLTQHLAJGKP__bgjb—·Ç°¹³»¾¶±ÄǶ°¹±°»¬³±§«·¬¶§žœ§šN›žŽ –‘§˜¥•Š““ˆ‘‰‘‘›¡˜›•–‡ž™¦š¬¯¨¯§³³ÓÔÔÖÑËÏÓÔÎÓÏÌÆÃÊпÊÉËÉÒÈÍÍÃÑÒ¸¯Ä¼Äº¦·»Ä¢€mb[[\X_WXdYO\WNQCBIECI;AD>AH??B8;D>@I=46655;:687654/10146278875367C5B8?-0,1349=97,.,1;FL=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYSfWs™ƒhqoyyƒ ªž¦—››˜‹•‘šŽ}‰Œ…ŽŠŠ‹ˆ|„‚p‡†{‡rƒ’‹~qyulpxr{nxsli€pmcimpyiw}~Ë¿Âߧmcxod[a`JPRUNY^P]]NPNTQUT\nnwƒr–®¸¬´¨°¶«­½Á±«µ¦¥¹§¬®¡¬´¤±®›˜˜Œ‘”‘„›§‘œ‰ƒ‹„Š‰„Šƒ“•˜—”›‘›˜™™žž«¬¤§¡¬¬ÎÒÕÑÍÌÒÓÓÐÔÑÎÈÃÔÑÈÎÒÓÓÖÍÒÑÅÒÖÆÁÏÈÈ鿸Мwmd[`\U^Q]ZOOTPNH>AGBCF<AB?FE>@?:===<JA45465<888664412/03526768533;=<E=@11+/359?5901022-2EO3)/3.32=N248C}_2A†tD:==I>@CFH<VRMO[u‡†‹wmwp}~€¡žž¡‹™““ŒŒ“–…y…Ž‹Šˆ‘‡‚{r~€‚‡z…v…“‘‰€pwsls||w|s‚xqk€rrioqzys{¾Ëš~Œ±ƒvr…whaj]CZZ[WfdXekTX]]`c^cx{‹™ª¤¤¢ ¡¨§ª±¹«¦´£¢®¢¤®¢§±Ÿ‰¦›•“‘Š’Žˆ‚”‰k•¢™„†~‘ƒƒ“—­‹••™Ž…’—§°¢  ¤¤¨ÇÍÏÇÁËÐÓÑÔÒÎÓÍÆÖÓÍÔØÖÖØÕ×ÕÉÔÚÍÊØÖÑÊ­ÄÃ̉qna^]WRXR[OJGJIJ@;:;ECD<CD>HC?CB;;9<9GC46544<5687543250/2546745544<>=E?A62/-16;=081/254/-.;R017/532ED28>nb5=tM99@I<AD?A;PLFKYp€u~isyr‚‰•ž”…‹–‰ŽŠˆŽˆ€xƒ”™‹ˆˆ‹‰~ƒxs{}ƒ‡w€{‡‘—„oxpmuvx}t†|yl‡vun}v„uy{µŒ<AŠÆ¥~|jeWICecfchjdoy[_fhknin€„ˆ‘ŒžŸ ž‘—˜Ÿ¤¤¦²¤¥³ ¢¥ž¡© ¢±œ‡Ÿ’’“‘‹Ž‹†ƒ„~œœŒ‚„…z”~‚ª•£Œ’Š˜’‹}—Šš‘«³˜š›§œ§½ÃŹ¶ÅÍÑÐÑÏËÒËÉÔÏÑÕÚ××ØÔÙØÍØÛÎÉÚÚÒÖ¿ÌÍ´utmc[WQTPXUEFJIEE=:7:@AB:GE@EDBDA;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?1*(.BT29254/7K75<`bA<svV87AH:?C><9QECJTlnopbqqs†|—‘‹~‡’‚‰†…Šƒˆ}y…——‰ƒ‡…‡z„yqz{„†uz†ŽzŒp}opzr{€q„‡€nŽzuw}|‚u|‡‰°tYªÂ·’pnc=^hrpqpnxw‚eioruxr{‹‡Ž“’›– –ˆŒ“› ›ŸªŸ¡­œ¢ššŸ¦ŸŸ¬™ŒšŒ‘“Ž…}ˆ‡ƒ…‹Ž ™“ˆƒ‡~m™y„™†ˆ“ŒŽ•Œ†{›ˆ“®ª”•—ž˜¦®µ¼¨­½ÆËÈÉËËÏÈÃÑÊÔÖØ×Ø×ÕÛ×ÓÙÛÖÏÛÚÑÖÈÕ̓vxgfYXORS\GBEII>A>=8:=?;>H=@BAADA>?:87DB755479.566435532323647553457EBDCEB56<FNSM[nfcnsk`V>,4LG865433BF4=W_hLux^8;?F<<B<:9D?CGRk_mdbfkv€ˆq‘›€y€Ž~ƒ‚‚…„|}„˜Ž‡‹~†‡€w‚yn{{‡‚tz’ž¡vvƒtu}t€„o‚‚o’„u|…zv‡|‰¸Æ¥Ãʸ‚–œxpeNec‚zw†¢‹yyw{ƒ|„vm”–”•˜‘ƒ‰—š——¦œ˜ —Ÿ“’—£™«–‘‘‹Ž’ƒŒ…‰ˆ†‘žœ™‰…‹…—{ˆ‰Ÿ—‰ŽŠ‹‚|¡ˆ‹¼¡˜“—™œ¨¦¥­ž§µ¾À¿¸ÇÉÍÎÅÍÊÑÖÕÔÙÕ×ÛÔ×ÙÚÛ×ÛÚÙØÎÜƅxwegc^SVVTLKDMD;==<9:<>9>A7>?@=@><9867CA6455=80665547745613854564557HH=DJE7925;H>;::7HP\ZRUXK9T>;95327I8=NYMHxxd5=>C=<@:6:>>@EQ_Yfa][htzyl‰’wvzŠ|~€€}…{~‚‘Š…†z…ˆ{u}um}}†~t’ž‘Ÿƒ’|†}x~y‹Šoƒ›€t™†}‚Š…|~‘{©ŽÃ ½Œœ¤œ~Š„}‰rŒ‹s¦šœ™”…{‘‰„iGq¡¤Œ‹’…ˆ‹‘“•›“”‘—Œ•Ÿ”¡”’ŽŽŒ~Ž‹„ˆ’–šŸŸ‰Œ”‘‚Œ¦™ˆ…Žƒ†„€¤†Š‹¸˜‘”–¢§ £®¶º´«¿ÅÊÐÈÇÌÏÓÒÒØÒÕ×À×ØÙÛØÚÚÙÙ×Û·wvuihdU_ZRONHCLC==>99;:99<=6@>>==9::;37D@8378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWN<MTHN?96333>C;[X>5YypZ<<A<=>8589?=DRSRX^UXfmmmiŽŠqsxŠ{{}€|ˆ{}{‹‡ƒ~uƒ†zsztm~„}w†›¡›ž”’€Œ‡˜‡€œ’nˆ©…z ‹|‘ƒ‰„œ~š‘‰£¢Ÿ¤¯ ‹‘‹†‹’†Wr­‹Ÿ¬œƒ˜œŽ\ƒ¢‘‚Ÿ“•Œ‡ˆŒ’“Œ”••ŒŠˆ–›•–‘‹“”†€‹‰’ŠŠ—™£¢†“• ŠŠˆŽœƒˆ€ƒ‡…¤…‹³˜œ’”—¡¡ž™’›§±¸¬¤¼ÁÇÍÇÆÏÌÏÌÏ×ÏÑÔ®ÖÕØÚØÚÚ×ÖÙٝmzree[[VRUVC@ID??>:49:;7:;:3<<?=>7;9:1:G=:27=@50677255?65;55858:57735HR7GOK994=EJB>1FCLA98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:<@;BQKKSYPTcbxlb~’ƒomw‹xz{}†|{v†…€sp…‚{uwvt„ƒ…}’¦¢Ÿ¦¢—Š”—ŠŠ§—rŠ²„§’„™”…šŒ£– ˜“‰›ž¢“©° ‘•ŽŽˆ•‹n·„šÄȲœ¢¥›˜–‘²d¤ÍȕŽ†‡‰’Ž“”Š…ŠŠ†–š›”“‡•˜„‹™ˆŽª——¤£ˆ™ž•š‰†—˜Š…‚†¥ˆ“©š—“—™¡˜Ÿ™“œš¢²´¥£¼Á¾ÇÅÅÉÈÉÂÊÓÌÍÔ¨ÒÑÖÖÖØÚÔÓÚ΀p|e`[\\MISXABGD;A>837;<:8=64::<:72?9929I:>67BC32:96264>=4;>6949;57944KQ<JQK9A7BGI@64JELF>;88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBc‚Gv}|m~ˆxz~{‚‚ƒvv€ƒ|mn‹z|xx|„‡Š~‹£³§£ª³¢—§Ÿ¥¤–•®¢ƒ‘¸•‘³š¡¡Œ¥›°£¤˜‘§–¨™¬¯¤˜•–•‹˜™—¡ÀŽ£É¹«›£¦­™’›²……¨¢œ˜…‰‰Ž•‹“ˆ†‡‰“˜•Œ‹”“†•˜†„‘œu‘˜²–—¤¡ˆš’ŠŠ—›‰‹–Ž‡}Œ˜ž‰œšš“˜˜Ÿ” ”ž› ±®¢¤·¾´ÅÇĽÃÿÆÍÊÉÒ¦ÎÍÓÒÑÖØÓÐغpwsZ^S^TOHIMEBCD5>:77:?<<7=43669774=5;5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=88567=:JFDGN[\YJf`;H„‹zzn…†z|„y†~px|~}orz~‚|x†‹‰†„’§»¬¨²½¯¥­³³¨£¡°¬Ššµ¢¸¥•­¤—©­¸§¥£Ÿš©—©£¯°ªš™œ”•‘— ˜š»»®Ê¡j¶¸«°”™Ÿ£¬“—½£^ª²ƒŠŠ”‡|ŽŽ}ƒ†Ž”•ˆˆ“–Œ–‹—˜“™´—•«‹œ”’Ž‘’Œ™›Š’ž‹‰•Ÿ¡”˜š’œ˜ž”¡ ”œ¥¯¨¡¥³¸«ÂÈĵº½»ÅÇÇÂÑ ÆÉÍÍÄ×ÖÑËÓ nxfZXQ\PNEC><CAB8?885?G=<6<35345454B39:BM:B;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPdGb`bpJ?‹Š~s†‡}‚‰uƒŠ‚m|}}pw‡wŽ‚‡{Œ†Œ™ªÂÀ¯½Æ»³´À¼´­«³¶Œ¨³­­½«›»¤¨­¹¸«§¦¢¢¤¢©¯²±«œ¤˜›˜—ž¢¦¥’¤º¯©À¼­­²¹¥¥¨~ˆ†œ­¼°ƒŒŒ‹ƒŽƒ‘Žz‡œ‰ˆ—‹•–”‘š—¨š±š‘¬œŽš’Ž•–—Ž‘ ‘‰”›¤¬”–”œ“¡›˜Ÿ¡”šž§¦¤¢¤°³§ÁÆï°º¶ÅÄ¿ͦÇÄÇüÖÑÍÄʆrp_YW]YLJAK@FG>A?B;:5>A==5<6>333242A17@BN>G@CNCA=C=;86CC5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GD?CF\eG`igZ]\“Œ‹ˆ{‡Œ‡ƒŒu†‘Šo~{q~{•z’””˜“•§³ÆÉ¿ÂÌÂùǼ»¯«¹»˜³·º²À®¥Á¤«°¼½«®«££ž§«®´°ªœ ªœ¡›–Ÿ°µ§‹£º»¶Á¼¬©œ²¥¤©”…Ž©Ä䂋‡ˆ„†•”z„‘‘¢ŒŒ”’‰—Ÿ˜“™•˜¦ ®ŒªœŽ–’‘•••‘¡”†—Ÿ ²ž”š”Ÿ ˜¤Ÿš › ”˜ž¥£¦¦¤¯®¥ÀÄµÉ¾¶Ï²Ä¿Ä¼³ÑÉÈ´rvjYVYhPLHBLKKJAA=CD<5AD;;3=8B332262A05IEN>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBeYNe\fTcj™—ŠŒˆ“†‰y‡”r€|x‡‚‚zŽ¡–¨šš˜º½ÇÈÉÁÒÉÊÂͽ³­¼¾¨º¿½»Ã·¬Â©¬³¼¾ª°ª¤¥¤¬®³­¶µ Ÿ¯Ÿ¥¢˜£³½©›¨½Á¤¶·°¬“±­¬­—‡š©§¥‘‚Œ“¥•‰vŠ‘z…’žŸ“”Œ•£™–œ””£žªŸ‘¥šŒ•–ˆ|•’’£š•Ÿ¡œµ¥ž—¥£¢¥ž¦˜ž–—›¤£©§¢²¬¨¼Àį¥²·Ì¿¹¯Ä³»¾Â¸­ÂÃÂÀ—jw`VUZYIJLIFDDHCBADL:4DH9;4<7E.12352B25SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQG7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>jH_XaZddVžŽ—Žž’‰ŠŠ “„x…•ˆŠ€–¡™®¦¤˜Â½ÇÃÇÅÓÍÎÍ˼·°¹¼´½Ë¼ÃÁ¶·¼­³Àº¼®¯¨ ©¨¶­®©²·›ž­¢§¡ž«·¸ª¥°¿Å±½¹´¨ªµ´®¯—–¥¬¨ ‘Ž’²Å§•Ž}’•}ˆ’™ª™˜“““–“¥ž’™”¡£¢œ˜Ÿ˜‹ŒžˆZ–—’—¥™e˜£Ÿ³¥–¡–¬¬©§›ž¦—˜–—• ¤¨¥Ÿ¶«ªº»Ã´¥³µËÀ¸ª¶¬²»¹®¨¸º½¸ilXUSSMDJRMK?AHEDHHH95EM;>8=@J.32025C55OVN<LFKRLOHGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|gV;=@BFBpEiIRebLF¥”›—¢—©–ƒ‡¦“ˆ‚‡‚œƒƒ•”š¢Ÿ¯¾¯¡Æ¼ÄÄÆÆÎÎÎÒʾ»¶±º»»¾ÏµÃ½¸¹·²±µ³¸³«¦œ«¬¹ª©§¯¯˜£¯¤§¤¥µÀ°¬¬´¿ÃºÀº´¨¹µ¹³¯–¥­®®¤‹“•¡tÁš}—™„–šŒ±•›š•’“šš¥£” ›—š©œœ¡ ™Š–œ`J–œš•š¥–U—°Ÿ¯œž¤”¯®«¥š ¥”“˜˜œ §¢™´©ª³»»»ª°²Ç¿¹¦¬«­²²£¡²²´¤nkcZXMOJDOOPQ;HKIGICC>:KT?A:=EM07544:B44MWO<JKOUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@BAF3>58JKCA=C;4EA:A?>H@5*B52,>c]g:35tde@R7&#3}hW;:BC@=QEWSsbWFHª—™ ¢¨¯™‘˜‡‹¨–Žˆ“…Ÿ‡„—Ž¡›£¤µÈµ©Æ¹ÂÃÇÊÉÈÌÍƾ»³®¹¹ÁÁ̵ǺÁ¹µº°¯¯³µ§¤›ª´µª©¦­¬š¤®¥¤¨¬º¿¨¬¶·¾Â¿¾¹´³Ä²¹½¬£¯µ¬¹¦ˆ›—¦›v¿Ÿ„™Ž“™š‹®—¡œœ—•› ¡¨ž§Ÿ™šª™¡§ž˜‘ƒnv’¢š•¢ž®²¢ª”¨ª—ª­££Ÿ¤¨‘‘™›‡”œ¢ž–±§©«¹¶½³²®¾¹· £§¨¥¦œœ­©©‹`c^^PIKFGMIVL=MENKLBCD<QV=AABDO18=77?B75TWN?HNQYSPQUKQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW;:=.-R`MUHe^HE«•›¡Ÿ»¯™”ŸŒ“«›‘’“‰«‡¢ŸŒ¤­”££¶Æ¾´ÀºÂÂÇÈÅÂÍÈÁ¾¹²¯¸´ÀÂʵŲÁ¼µºª©­­°££˜ª´»¦©¦«ª©¯§£ª«¾¼¨­½´¸¾Ç¼·¶¸Á²¾Á´©µ·«¾¥¢˜’¢Ÿ¼Ÿ‰š ™—žž·Ÿ©œ¥¢›œ¡š¨¤³¡›¦œ¨©ž™•”›‹—‰Œ¤¢”¢ž¡µ¯¥¤“¯«™«ª££¨””Ÿ‚žž›•©¤¡¡³´ºµ­¨µ²³žœ¢¥š—•™ª¡žu^Z]\IGEFMPHMEGGCSLJBEGAVRDH=AGQ1;B7:BF79\YKALPTUSMWRNUJE@JJNO9C@5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-19f\FCCœpbGE§—¤ŸžÃ­›—¥˜š©œ–››ª–•§¦•­¬™¢«¶Ä¼¾·ÁÂÀÇÿÍÆ»½¹²°¸³¿Âȵ¿°¼·¹·¥¤«¬­¡¡šªªÅ¢¤©«¦ž¬¯«¢©¨¿¸§­¾±¸¶Ç¶µ¹¸À²¿Â·µ³´¯¾£—£–”›”® ¡£¥££Ÿ½¤©ž¨« ›¥Ÿ½¢™£Ÿ¢©«¡–•ž“ž‡„“Ÿ¤ žµ¬¥›•±§™¯¦™ªœŸ˜”ž„ š›’¥¤š˜«±µ±ª¥ª­¬œ˜  ’Ž•¨ž”f`X_\NHGJNKHEDIA>QIA<GIH[ROK=HOU4BF9>HG5Ca[KCNRUWVQXTRUI@8RQPM:GA4CHQSIC;C>GVKC@O>K<06;GF>;FA46@9:?9;15D0-,/Mv\4KZ5,MnW<-=)#zbQ5CKQ:mRF<KxebVL¢š£œžÅ¬¡Ÿ¬žž® ’£Ÿ–¥Ÿ¦ª¬—¶±£ª³¶ÄĽ¿µ¿Â»È¾Êǵ¸µ´°³³·ÁŶ¾±¸µ¸´Ÿ¦¬ª¬ž¥¤Á¤Ÿª­ ¤©­¯¢¦¨½µ¥±½¹¶¶Ä²´¸º¿³ÄÁ¸¸®³µµ£¥•‘”¡® ™¢ž¨¨«£šÂ­©ž¬­››™¦ ½¡¤˜««¬¦¢™šŸ’Ÿ‰ŽW–Ÿ¥¡ ¸ª¦“˜µ£Ÿ± žš®–˜“ŽŸ—•Ž¢£–¦®²«©¡¡¥¥••˜‹‘’¤ž‰_bXb_KHJJNEEAGK>=JB99JJN]QQI=LV\9FI=DMI8Hb\LCLPSYYVWOZ^IA=WQIK?H?5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+w`S6SZkWrGE6=ue\KNžŸ¡™žÃ¨¥¢´¢²¨“«¥ £Ÿ­©¬»°¨¬¶±ÈÅÁ²ÂýÆüÄɼ¯°¶­°´¯¿Ä´¹±°¹´¬™¨°©ªš¥¡¨Á¬›¬°œª£®±©¤¨½¶§·»¾¯·Ä­´³ÃÀ³Ç´»·«³¶­ª¢¦–•”¤¬¢ŸŸš¨«°¯¯»²¦ ©¨™™—“¢¤¸ ¡¤“¯¯¬¥§Ÿ’¡ž•ž•žš¢ž§´¦¦Œ˜³›£®™›¬ž“•“™‘¡•Ÿ¡“‹¦¬¯¥¦¡œ ž’’š“…‹‘œ_dZfdJILJRBC@IH;;G?99OMU^RSJ>O^]=HPBLLI9Mc\LELRTY[SUO\bHA?ZQAHAKB7FELKM?;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<v]^?[T^eq@8;H–weA4Ÿ£ œ Ã©¤«³¡¤´ª–³¬§¢¤²¬®©»±­°µ´ÆÀÄõÀĽÉĵ¿È´«µ¨¯¸¬¿Ã³·®¬¶¹¥˜ª²«ª˜Ÿ¦—­»´›§°›­ ®´²§«¹³¨º´¸²¹Àª·²Ä¾µÆ¨¿¯­¶µ©§¬¡——‘¦¥¢¢˜˜¥¯¸®²µ¶ Ÿ¨¤š••“¤ ·¢¤¥–¯±²§ª¦¢Ÿ›š›–—¨Ÿ ˜¡ž¯²¢¦Œ—®˜¤ª—™ž¤‘šŒ“—™…•ž”Œœ“‹¨©ª¡§ ˜ž•ŒŽ™…•ˆ”žwbg\jiLOMNT=CANC::I?77RO]^RVQAW`\BJSHVKH:Td\NFON[W[RPQX]GAB[PBG>NC9HGHOP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1[bZ33806p[bH05IphVCWFŒyfC;¤£¢¦¿§¨¯°¡©µ«º±«£ª´¶±°¹·°·¸¸Ä½Ãǽ¼ÄÁÆÀ¸ÀÅÀº©¶¤¬»¬À··©¬±º¡”­±­²–¥§‘ª¹©Ÿ¦°« °´³ª©¶¶­¼­³³¹·¬¸°Ã»¾¿¦Ã«°·®©««§ž˜™«¡¢¡‘—¡±¯³¬°¹šœ© ™–’—¦¡¶©¥£¢°±´«³¨¬Ÿ›  ›¥œ¢—£³°šŸ“¥šŸ¨š“¢ž”—ˆ“–’•–œ“ˆš™”Ž¨¨¦Ÿ£›—›“†Ž˜‹}Œ–…™igk`lmWPQZTABET@;;HA7:XPd^PVWEY_]MLRN^KJ>Zc^NHPO\UYPKTWZI?DXPDF?N@=IGGQPB=DFBM?:1D?77547?=95E4+75/251.-.,1=*'+=\p=>1.0dZd@1647gY`F(?8l}g[V;‰{cC=¨Ÿ¢ª½¢«°«£±¸ª¥¶´¬ ­µ½®³¸»º½¶¶À¿ÈĹÄÂÀÀ¸Ä½Á·¯µ§«·±»¾¾´¨®±¶ž–«®¨®—¦¨Ž§»Ÿ¤¬³ž¬¢±°³¬ª¶´µ¾®°±µ¬°µ²Á»Å·«½¯±¸¬­ª£±¦ž¥ªŸ¤˜™Ÿ³ª³«ª³š§›š•Ž ¦¥´®§¡­­®±§´­²ª¤œŸ¨£ž•¡™›¨µ©–™‘’ž™Ÿ«ž–—„”–Š˜œ“‰–—š—¦¥¢ ••—“”…{Ž’‚‹•dkqgoq^FYfVDBMXDZ9HB6>\Qh\NY]G[^]NMRXdJJC\b_PLMNXWXPJVVWL=EUJEDAM@AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,,%2+*5K1/'__`U150=`V^8)C3YT\gK6ŒzfL@¤š¡¤¬¶¥­ª¦¯®·ª¯µ»§¦±·Å·±·½Áµ´ºÄ¾ÌƹÂÀº¾¹Ã·À¹±´«©º¶»¹¾´©­°µ˜˜§¬ª¬›«««¾ž¬®²£«Ÿ°­³®®¶²¹¸ª®®±¨µ¯´¼½Ê³ª¶µ±´°¯§¡³ ›¨­ ¦––šš²¢­ ¥¯—¡¤šš’Ž£¦¨³©¡¦³¬ª¶¥¯±µ¯¤™­§š˜Ÿš™«·¢—“‘Ž—œ¡—–”«žš’’—Œœ™–Š”’ž™¥¢¡ ˜–‘“•yŠ…{ŒŠ‚‰‘jmwmu{aE`kYIHZZ={JFD6AbTi[M\aJ[]ZRRRbaLKE_``QLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`U`/5(C_Q\.*B/JGP[H3cYUKD™—¡±¨±ª­¦¤¯®¶©·µº¤¬´·É»´ºº¿¿´³·ÃÀÌȼü·¾¾¿·¾¼±¼­§º¹·¶Â¶ª¬°·”–§®«¨£°ª”¯»¤­±³§¨£²´±²±µ±¸³©®«²§·¯¶´Äƶ©¶¶¬°­©§£¶  §±¡¤”œ™•±ž§œ ªŽ©¢ž›–˜¦¦¥¸§£²µ¬¨²§®±¶¬¥™ ¬¨›œžœ”©¸œ”ŽŽŠ˜›¢—˜¥ œ”‚‘•›—–•ˆ–˜š§œ£ ’–‘•u„‡{„ƒ‹Šlovt{~\Kem\KNc\?b{GI8GgWe\L^bMXYWTWTi]OOHa]_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANHf27'GbLV%-B-=ELQ<3rkICC™¥®¥­¯«¨¥±³´«·²· «µ¹É¹®À»Â¸³±µÂÃÎÅÀÁ½´½¿¿º¾¼²Ä§©¹°¶¶¿¼®«²±› §±­¦¥¯¥²µ¬«±²­ª©´»¬µ³µ­´¬ª«¨¬©¹­²±ÈÀ¸¥º°©­­¥¨®°¦¥£¯¤©œœ›¯š££¢£‘¬ž£ Ÿ¢ª¦¦¹¤¬µ¶¥«¬¨­¯¶®£ž£©ª› šš’¤³™Ž‰‡¡ ”Œ”œŸ’‘ƒ’’š—•“‡—’•™§›ŸžŒ’‘v}Ž…|{{†‰ˆprq}|}\Sdo^NYf\FD–[G;NmXb[L`bNVVUWTYg]QRLcZZTKGOTSNGIVS\N;P^IBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3Bc;6*HeHJ+;H?3BHS,>k;GHœª«¢ª±¤©¥³´±µµ²²¢«®½Ìº®ÀºÇ±´­´ÂÃÑÅƾÀ³¾Á»¾·»Ä§¬·¬³¸¼À¯«±¬Ÿ£§­ª¨¤°¤ª²ª¯¬°¯°®«³¼§·±²©³©«¥¥£­º¬ª²Ãº¶­»©¨¨­©¨²¥©¤£®ª¨¢žœ£­•¥ž˜ž™¬¢§©¢­¦¤­«¸²²¡©¢ ¬¯±¬ž §¨©™¤™™ ¦—†„ŽŠ‹žŸŽŠŒ•›Ž„†”Ÿœ”—”†–”“—¤›œœŠ’‰~~‡…|w~…„…rqpˆuk_Z`ncQsq\K;„|F?WtXaZNc[NVVUWQ\b_SONgXWVKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*25>10485(5/*,.30;),,'%234$,2-860)(1<]J0.JgDF8<B05EKX1@•Z>LE•˜­¨¢«³œªª°¶­¹¶¯«¦«ª½É»°½·Â¯±¬³ÄÃÎÏÿ¿´ÀÂú¿³Èë®·­²¸¿¾²­­«¤§ª°©§¨±¥´®ª°®­²±´¬´¼¥¸³­¬®§«Ÿ£ž°·«ª­»·¥·¶¤ª§¬«ª­¡©§¦±²¤§¥¡¡¬—ª¡•› ¦ž¤¢ª¤­£Ÿ§±¸®®£¦¢›ª«®©¢¥¤¤™ š–˜œ’‚ˆ…œŸ‹ŠŽ‹˜Š‚‹—£›‘š‹“’‘“£™›šŠŽ‹‹|†ƒzt‚€|ru‹¤‡xj^`nfWe‡cN?g“LEbyWbYReTMVUUTO\]aUKMhVUWIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*39?./463)4+*,+.#4.-+&(+79*&6+<-2,&06WZ.0JgAA<<B+:JO^4D†>HFD—’°¥£«±˜«ª­¶¬¶²¬¦¬ª©¼ÀÀ¸¸³»µ¦²¯ÄÉËÑ¿Á»¹¿¾Á¸Á¹ÀÄ­±µ±³º¿½²°­¬ª«§¶ª¦­¯ª¹°¨±²®²­·ª··§´·«¬¤©ªœ£ž³³¨¨¤´µ ·® ª¨«¨«§ «¬©¹¶©ª©©¢ª ­›’ª¡ ¤¢¦£ªž§´¯¨¦ª¢£˜¥§§ªœ£¤£ š˜ ‘Ž˜~‡Œ‡ƒ†„ŠŠ‹‚…”¢šŒ™’‘“Ÿ–˜–Œ‹ƒt‡~xt‚~yv~€‡oqggqx\asˆkO^™VHmxUdVQcOMUTTPOX[bUHPiTVSGPYUI>IHOQPxLMV=<KD?@A<@CUC9AK=5;E13;:7*4:=+-341*8**+*,))(/*&)%3;,$2)2021%/2Qb02?f=NX>C,>LT_/Ji5OD;–Ž±¡¦«®š¬¥­°´µ°¬¦°ª©º¾»À°®¹®¡·¯ÈÇÈÑÀ¾½»¼Â½ºÃÀ¾¿®²²±µ¼»Á±±²«³¨¤´¨¥­³³¹±£®·²°²»«º¯ª®¶¬ªžª¬Ÿ£ ¶­¨¡Ÿ°³¢µªž¨§ª£ª¡¢¬­¨½¯¬®¬¢¨¨ ¬™°¢˜¢ §§ž§›™ª±ª£ ­¢¡”£££§˜š©¥˜˜˜žŽŠ‡”‡}Œ†„ƒ£–„‹†Œƒƒ“ –ˆœ“‘œ”—Š…†xt|uxyzssyg†¤ui^dk€tgˆŒ}SXp^JxsSeSQ^MMRZfNLVYdXFSiRQ?CNQaQ:IHLSIqQLS;<I?;<=;@@W<<?H73CB15:93-5::)-31--5)(+-,42#2)',%.;.&1.0-14%,0Lg:48_=ad?F1CP[[*HM9UA4²¡¤¦¬¤§¤­§µ³±«¥°§ª¸¾À¼¯§¹ª¦¯°ÉÇÈѼ¿¾¹¾¿¼ÉºÀ¸°¯´±º»·À²³»¬¸¬¢´§§¬²¶¹³¨¨½¶®¶¾°½§­¬µ¬­œ©¯¤ ¥­«§œž«³¥´¨›«§©£©ž¤©¨©½¬´¯­ª¤¡®œ›³£•¤œ¥¥Ÿ¤›š©«¦Ÿ›ª¢›“œ¡¥ž˜—©©’˜š”Š‚…~Ž‚€‡…~}‹‡„“š“…’¡Œ”‘‹‘›’•‡‰~r{z~|hx|ztop{g„x„ˆdagaq„zmgx]]U@WzmTaPRXKLNru]HZ[gYEUfPD>JNDCA9HGKS?jaJQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11'/>KH0%90%,,09/,,+6'17#-0GjI14X=fcAJ7GS`U*=9DW>*”²š  ©¦¥¡«¥¸³³¦ª±§­¸Á½µ¯¢¸­¨¨°ÂÉÉÌÁ¶½Àµ·¿¹ÈµÂµ³²µ²¼·¹½µ­¹¶¿­¡³§««°µ¸µ¬Ÿ¾½ª³Á´¼¡¯³µª«Ÿ­°£œ¥¨ª£ž›¥±§° Ÿ«©¨¡©œ¤¨¡­»¨®°­ «£¤¯ŸŸ­¦—Ÿ›¡£œŸœš¤ª£››¥¤–—•Ÿ¢–›—¦¬Œž‘‘‘‹‚Š€€Ž€{™“ˆ|~‹†‹Šƒ’˜‘†“¢‰’’‡š“€ˆ|yl~vyxc{zqooqvg€sjƒgdg_lrlaio`o>ZxkU^OQQJIMTYWM]^lWDX`O^PHMDF;7HEKO<rhKK9AE;;==;;=J49B<3;G<4?18-68;2(09/,4/.=-*K>*49&'.34.0+/4&,:$41AhY13S=e_DL6KVdO*;2NX=#“™­š ˜§¤£Ÿ¨¤¸°¯£¯°ª«¸Á¹³­Ÿ¸¯«¨´ºÈËÈ¿¶Â¾°´½·Ä¶Ã±®¹²³¿´»¾·©¹¸½«¤´¨©ª±®º±«œ¼½¥°Áµ¶¢¯·µ¦§§±³ ž¤¥§¡¥™Ÿ¬¨©ž ª¯§ ¦˜£© ±¹Ÿ£°¯¡¬¡­¤œ¦§©šš›Ÿ¤•œšž©¦—œ ©“™”˜ž“™–¡ª‘šˆŽ†}‡~‚}| ŒŒˆx‚‹„‰‹‹…‡“šˆ•žˆ‘•‚Œ—Œ‘}…{sp}qtt`yxhnppnh}qc{mieb^d…~_ZrjqKJhXZNPLJHPRPIN\_nSDXZRhOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23.:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%53<fd24M?e]FO=QZgH*>0XV5(—ž§š–¬  ¡¤¢¸«²¥´´ª©¹Ãµ³­Ÿ·­®­°µÆÈÁ·¾Á¹±´¼¶¿»¾¯ª½°³¾±¼Â¹©»º·§¨µ©¨«±­³±¨›¾¸¦­¼·²Ÿ±¸°¨¥§¯±›¡¤ ¤¤ —›¯§¡Ÿ£¨¯¡ ¡”¤¤¢·°¡¦°«Ÿ¬£¯˜œª¥©ž—šž¥“›š¦«š¦—–˜”Ž“—¢¨¢ˆ‹…z„~„ŠzŽ–‰†x‡ƒˆ‹…“˜Ž–˜Š—~†—‹yzprwoot_ywdklkhg‚merkkehYas^ZkuiYG}][XOOJHHRUF2:_^lPDXVYeLHJEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<#8R=*113>D5,-'42+;+139cl84GBg[HTCT]hE.;1_T,2–£¢˜•©ž¥¡£¡¸ª°¡»¹¦¬½Ä³°®¢µ¯­­¯´ÄĽ³¾º·±³¹¸º¸º®­¿³´¸¯¿Á¸¬½º´¦¢³«¨ª³¬®²£Â¶¦©··«Ÿ²»©¦¥¨¯«™¢§œ¥¦”˜¡²¦™ž¥©©œ¡ ”¥Ÿ¤¹¨¤§­¦ž¥¡¨“Ÿ©¢¡¡™›¡’›— ¢«œ›š¢–“•–›Ž““£§¤ˆŠŽ†y„|…†}œŒ‰Š†x€ƒ‡ˆˆ‘…•“’Œ•“Ž”{‚—Ž‹w~{lurmlsbyuhgigem„gghdfhi^fbifZezb`QsT[[SLIGIOS@!+j^jLCVU^`KHGEC.:B<F<6KPD8:D357==895?:;4>8@L=>93)8><:9*6@3.E4(+,>0-N?.+-7-1195,&.5-80576`tB3CDh[KWGU`hB378bM'2ž¤¤’Ž¥¦œžžž¤µ­¨ªº·§¬ÃÀ·¯¬¡µ®§®¯·ÁÀ½±Á·°¯²¶µ¸·µ¬ª¼´¯²±½À·®¼¼±¥Ÿ¶¬¦¦µª«¯¡ Ä¬ª§±´«¬´ºž¨©«±¥˜žªž¨¥’š¦®£˜ž¥ª¡›¢— §¶¦¯ª®¡¡¡• ¦Ÿ¢ ™›šœ’šž•¦ž­¢˜—Ÿ–”Ž•˜Œ˜š§ ‡ŠŠˆx…w‚‚‚œ‡Š‚‰{~„ˆ†„„–•‘‘’{ƒ•Ž†s}gypkjlguskbgdbtadefeiibgoY^X]md`MhW[`VIGHKLRX>9`liGBUS][IHFEA.<?9A89RF@7:B037=7692:<97:9DN=B<0*<@;A<-5B37=+*,0A*JK./*+3722(57$+7.72685\yN2>HiZLZJVbfA:3AdG%5œ¤ ‘Œ® š˜ —¥´²£²¾·¡±Å»¹°±£¶¬«®©¹¾¼»­À²¯¯®¶¯³¹²§«¹±¯®³¶»¶°¹¾¬¥žµ« ¡±¥«¯Ÿ¥Ä¡³¥¯²°·­µž¬®¬®¢™§ª¥Ÿ•œ§¦ ™¤£©œš œ•œž­°¦¹§­¢¡ššž˜ž£š¥–ž˜›”š¡’¨–­©›”œ“Œ•™Ž””˜§§Š‰Ž{t‚‚Š˜…‡|‰ˆ„„ŠŒˆ’…“œ’’‘–Žƒofynhkjgqrk[hcar`dgjnkfjfdl\lmvqaTbhceZIFLMOXQPUaeT@VSYUFGFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24;6#3*)6.55465Z|]1:Kj[M[KXdc@A1IdB'4“¢œŽ±›”¡š©²°Ÿ¹À¶ ´Á»½¹±¦¶°©®¥·¹·¸¬»¯­««·ª´¹­¥²µ±¯©±·¶±³¶»§©Ÿ¶©Ÿª£ª­ªÂ™¯¥¯±¶µ¬¬ž±­¯ª¢›¤¬©œ•œ§¤žš©£¥•š ‘œ£«ª©ºŸ¦¤ ˜šš¡k¢•˜œqƒ–œ¤€v‘«¨ž––¡‘‰—™€—ŠŸx…“ƒmi~w„rl†Š†}„Š†o]d`g„—†k‹”’uw‹„ƒ€fˆ€hvifX]itnNPjcfq‚f^dfnki]]^‰…ˆhOKD8ETg^JHPPUUKHS`oteE[QUPFGFC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,,08>G701.*.*/668,#1'214:276Xl15Ok[N\K[fb>G1Ob<+/¤š‡•±›“ œª­«£½Å¯©·Â¸½¼­§¶±¦«¤¸´²³°¹®ª§¬´¥°µ¢§¸¶µ¨§¬¶³®´®³¢©Ÿ´«ž¢¥œ§¨›®½•¨§°´¸­®¤¨­ª«¦¡Ÿœ¡¨¨œ—¡¦¦œœ§¨’ž ˜Ÿ¨ª£´¯£¢£œ–˜˜—£ˆ¡’š†¡ˆ”ž¡¥§¬ž”““ˆƒrxŒŽƒ‡ uˆi—‰f~sy oˆ‡ƒ~Œ|¡ Ÿ™{‡žtˆŽv›Šl‡‚ƒnied{mrbT†mcmi˜qXipn†W]i[kjZˆpmyr‡i‡„Z^FN>F^MERVVQPRWTg]LYKRRPEGG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82*/1<I9/01.*/(-4583%&2115>1<8Xƒt15Rk[N\L[g_=K1U`7/(¦—„¬™™Ÿ«ª¨ª¿Ã¯²¹¼·À¿ª¤·±ª¬¦³µ®¯³¶«©¥±­¥µ³›¬µ¶´¦§¨³±­²¨®žª¡³© ¤¤š¢¤°·•¥¦§·½¦¬§©ª«§¦¢ ™ ¨¤š™§£¤™œ¥ª–“£œ””¤¦¦¡¶¤£ £˜•“˜“œˆ®˜•‰©‹˜£œ†±€¤­ž”šŸ•y‚Ô¨‡”À›Æxw±¥·–d€Àœ¿y„„yƒ|‘Êq–¼œÅ{r¶§º{l—±«°yhlX±®oei¼’¼nhzmpØ~Skb¶²~€q”uš¡ªWOXaOVNFT[XQPR‹\W[P@\EQNDFI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22BE/.32.+/)-/186- /416A1=:Wƒw11Tk\O[M^g\>L1Z\41!Ž¦“§ªŸ—¥­²©±Â½²µ¿µ¸¿Â«¦´­­©¨¯´ª¯¶´¨¨¦¶¥¨¹¯œ²²¶ª¥¤§²¯®±¦«ž§¤²¤¢¡Ÿ—œ¡ ±®•Ÿ£ ´º¢ª¨ ¬­¤¢›š¢ª ˜›© Ÿ˜ž¨¨‘œ§›”ž¢§£¡°£žŸ£––’˜’™…°kj‹ª~g…–‡­eqž•š§–q®¡¤~wº|k¡v±_j´[¥€eœ‘`fzfixj©e¾rg¦Œv±j|±xu’”cmm§n\„ Eig‡–Euœ`}f{£¦‚Y_‹«i€’xzj¨8J¯[WTmcZLOX_\WV;NˆOVV/ITSJCEF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3..53/+/(.0.:6/'$203B/=;U‚v2-Vj\OYL_gY:M5^Y31’¢•‚­§¥ž£¤ª±·­´½¾°·Å²¸ºÃ§©°¬¯©©±¯¤±º°¤¥¯³£©¹©ž³²°£¥¡ª­°¬¯¦¨Ÿ£¢±œ£˜•˜ž¯¨—œ¢Ÿ´³¡ª›¡¬¬Ÿžš— £ª™ž¥¡œš¡§¤£›˜¡ ¬Ÿ¦¦ šŸ¡••‘–‘š†µ›µy…©™µ™w‡³›·“–—«–~k¦z…†‘”’w«gj±[¬{Ž‡”tˆpŽ†ˆ—xƒ‚‹—Œƒ …°vwŸqkjl|‹O¥XHcc™~ch¥_yquR’‡^P©mcq}†€a/R¢n[Tkg`LK\cX\ZB>°wWXA#MhFCDA@A19>88:84;:9<9:A:E::;6:CB8=?KNH:5:AFB@AD<FD;0201;F,0.840,.(/2,>831/2-D1<<S}n3+Xj\OXM_fW7J8aU50—Ÿ”ˆ³¦¦¡®©¨³¬ª»¶Â°¼Â­¸·Â«¬­¯®§®³ª¢¯¼«¢§µ­£«¶¥¥²³¨£¡§ª²¨°¨¦ž  °– š––—š ¯£›š¤¨µ®¡©©§©›–˜ ¦©›Ÿ£Ÿœ £¥£•›Ÿ˜šž£«›¥šœš¢ –“‘““„Õ“™¹q°ÂƆ|֔œ»|›–¦œŒ¤z†¢¥‚z¬yV¯{‰~Ÿj¹Z¹w†ƒ}¦‚“|˜zªyŽ{±mŽ„t»…n•P¯§ÅŠQ zc`ªbsr†l—‡_Sµ´È…€‰|c¤3Bu]PjhdP@XfYdaJHMkJZSOYfZCC?E?0<<59;74<<8=:<C:F:;>6:@C;6@OLH<:<DHCBCD<EF81211DB.00483+-).323971#%5*>3==Qwj6*Yi\J[P_fT7G:aP72%œ¢“™±¨©¥³ª¥´§¤¼·Á±ºÀ²¶µ½´¶§²±£±³¦ ¯¶©›¨º®£°²¡²´±¡¤žž§©±©´©¥œžž¬—™™——–˜¢¬ž›—©­°¨£ŸŽ¬¢§–˜œ¡¦¢˜¢¡£¡›¢¢§›ž ž•™›¦¡œ¦”››Ÿ ˜’•ˆ²nhµq«ˆpŽ¦r´ts¶{›˜¥œ¢~Ÿ¤~°uƒ‘ÒÑu[®|…¤o›ª¦k†…}­}—™{±s“x³e–t…žnžf”RɋZÂ\Ÿyb_­_vs†b—ˆ^Yʝo¿€uMKµSUÆdTQjceXAOj_liPUFI9=WR[VYHB?J<2?;5=<56>;7><=C;G9;@7;>D;.CRJG>?<IJFCEE>II:1746@>/.24252-).26,742&60;5:=Prh9'Wi\ANT_eP5G=aM62.¢‘¥¯¬¥©º¬¦µ¥§¶»¼²»¿¸·µ»»´¦µ´¢²²£ ¬°¥˜§º®¤²±´¸ª ¥¡ª¤²¨¬ª¥š›©Ÿ–•˜™’“£ª¡˜“§«°¥¢–’¬Ÿ¥’”¡œ¤§ •›§§¢š£Ÿ®š¡žž–œ¢žœ¥”•™¢ž•™–’›…¬{w¨v£‹‡©o­Šƒ§„š™¢Š’™‹¢~‘—‡®…‚³\r³R®}‚‚¤q×}w„~†™šw¯†Š‘œˆw´ašeš‚•l’[°WKšu˜yf`­^vw‡g˜ˆj]¯w•Ÿxl5yÈ®²_BTo]g`EPl_pmVUM.ebhSYP;AD@L:5?91><16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK97<46:>/04333.2..18*.32%!03767=Pke>&Vg\@=V_cN6GC`I:77 ” ¸±˜³Á¬¨²§ª²º¸´¹¾¹¸³¶¾¶¦¸´ µ­  ©¬ •§¶¬¨±±«­´¤›©Ÿ ¨¢µ§¦ª¤™ž•¥¢””œš’–£§›”§­¯¥¡•˜©Ÿ¢‘¢š©¦¡•š¦©¤ž­¡œ ”Ÿ›ž ˜˜œ–—¡ ”˜‘¦†©}}¥y¡ƒªp­Œ¦†– ¢Š—–ˆ£‡”ª{‹yo±Z¨ƒ‚ˆ ytØv‡t§Ž›’¤|–Ÿ„{²^œd }‚”m“\«\[“‘hgªcr{€j˜†q]«Z‰ kneOJC¡\ZMt]bfMZa_rt_JU5Jš’XHE=HFAM35A8.;>05A78@<6=<F?:<6?=B7.HVJE@H6KIN@IK@EN::@4.;>002154+*05/7,&21($$6671<PeeA&Uf[?1T_bL7FI_C1=7¢œšš¿¬˜³Â®«­¨¦´°¸±¶¿¹º³²¸¼ª»µ ±¥Ÿ¦§§Ÿ”ª±©°ª¶­ª¯¡˜¡ ¦¤¤º¢£«¡—›‘£ ••Ÿ›•˜  ŽŒ©°¯¦—›§¦Ÿ’¤˜¨¬¨•˜©¨žŸ ¤­£¡ž¡Ž•¡˜Ÿ ’œ—œ•¡•–«›®nr´t©ŒwŠ¦s´yt´“¥£“œŒ‰¤‡Žu¸oŒ{‹¢kk¶Z¡†e——i ¢§m”r´t“˜²j†’ˆ­ku³af¢n†’k—\­`N¡|‡‘Rs£ly~n˜†p\¯V<œwfTon.[§ObRkeblZb\`p|cSYQ>>mo2BB@?M9!7@6.;@37C58??3;<CDBJFMIF62JTKEBJ6IJP?HOCFP=<E50;;010/75,+,326/#00,,289/9N`eD'UdY>/U^aL5FM^91A8¥š›»¢œ±¿®­««§·©¸¯µÁµ½²°»¸«Á¶ª«¡§¤¢’««§¶£³¨®ª¡—œ¨ ¥«¹£­œ–™¥£–Žž¡œ˜žŸ‘”•«¶¯§™”›¬©—Œ”¦š¥­£‘—«²¤ ž¨«°™¡¢™¢— ›–›—¡“œ©”ª™‡Ó“š»t±Ä€Ã†}Ֆ›¸y‰‘˜—‰Œ§‡y¢¶u}wv‚š²`ƒºyÀ|u¸bµŒ‡©}–¬©q{u¼ˆ§ ia¦Ž¯¢~Œt‡«}¾ns¼t²ƒux€Šmšˆqm¤t½]w}[ay¼jZV[iz^iadfbmyoY[YCA@r?CG*5H"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,<:08LXaF'TcX</T^`K5;L[-6@9§™Ÿ¢¼¢—±Â°­©ª¬±¨¹¯·Å±»³¯¼°®Á²­¦£Ÿ¤¡œ‘ª¥ª²¤µ§­¤ –š«™§¬¹£®™•¡¦ “œ£ž˜žš–“¯¹°«•—£§§”–¥¤­Ÿ‘ ¨«ŸœŸ©¤²ž¢¤Ž§¢”¡šœ—•¤˜° ’•©Ÿ…™¶€‘‘¸•x‚“›µwnlnsoy„Ž‰sžÁ»¼™z²¨p€t‘¹ƒ|††‹‡{Š†—|¤»¹½œuy³£tv—ut°u˜žf†i¶trpw¶Œ^y}ˆgƒymyb‹¬pt…X[§iDdYTf_c]cQffqmuBMPMD;ZL?J3<0 8>;.3=A99?=;<C6BSYZZ[[Z[^`b`]SGGH4DITAKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7KT_G'SbW8*O]]=+;VV'=:<¦¡¡¿¦–³Â´«ª¨­«ª»¯±Æ¯µ´¯¸§µ¹®«¤¢§Ÿ ™”¬¤®ª¦¶¨¨Ÿœ– £¬¤¾§¡ª—•œ‘¢›’¡¨¡“ž—’˜”²µ¶¬˜¤¤¢‹’’¦œ¥«–©¥¦œ›¢©§¦£¨¡’¬ž—¢ž——˜ž°©“œ§¢k~iœ¨y‰s~›Žuze‡{¾¿Àºn’‚q•…_rjZ]š‰ad‡Ž•k`•cmœvb”k€š•”e^_cq›‰hrŒ|†”fj~qty~}b[xthP\nƒ|{ŠjXlyrIJo…pNsMDV\faL[Wfc^OZmvjrRODEM<HI<M?2,2A?8/5?C<9;@;=C>RVVWYZ[[\]`aaa`\UG5DFUEJOHFPIIH;8=51:.1;:./-76=5&"/*2,%;8-7IR_I'S_V4)P^L(3>[O'?2>¨Ÿ¨¡Á¤š´º¶£¬¦®§¨µ²¬È¬°´­¶¤¾±³§¡¤ª£œšš¬§®¤¥µª¤›˜•¢›¦­©¾¨¨¥•”›– š“˜¥©§‘ž˜œ°²¾¬›§§¢‰“‘ª›¨¤œœ¬Ÿ£š›£§¬¢Ÿª¢š®›•¦ –•Ÿ—±¥™¢¨™œ‘žœ£¥š§£šššš–‚hn}qv‘—”‘ƒ‰´©…˜•ŽŠŒ˜–‡“•Šƒ““ˆ‘”™“™—š ¡š›”Ÿ›‚z¤…li{}€u‰‹‚r‚xyvuŠ€{‰jstƒudw}vkpzl_b[ogLXYej_WYpzomfSOFR9OZNRO(+;JB635=@A9:C><ENSSTVWXZZ\]`bba_^^[TKCSGKNDGPLOI<:;489,2;820)6IRO8")+/2#4;*7FO[J'R^T10T^:+=8]K,<-@² ³¢¿¢£±±· ©¦³§¥°µªÉ«­²¦µ¦À¨´¡ž¥¦œ¥–– «§¬£¤·¬ ™—– —­ª¦ÁŸ«¤–’œ—ž˜””¢žž£¨’™¨§²Ã¯š«ªž—–©ž«œž¡­˜¡›¢¥¯¥¡¤¨ž«˜—¦™š¡žžœ°¡¢§•˜”™”¡£–¤Ÿ˜¡Ž–”‹Š—­{•›‚‘€‰©¨…€˜–Š„ŽŸˆ{ƒ†…š‘‡†‰•Ž›—Ž˜ž£–™’œ~e¡³®„‰„w{Š~wyzogy€‰kuyˆrisyuƒ‡jtcxf_hdcdfjXk{qjk\SLPD_UF@??,4@F;45;>A;<?>>HNNOPSTVVXZ\_aca_^]]^]XVJKLBIOMRJ;<:786/3964.(&$-1..)+*7%+<(6CMLD/T\Q05M[17E4\G5<,@³ ¹¯¾¬«­±² ª¦²­¢¬³°Æ°«­¤³¯¼¤´œ §¢¡™—¨¦©¦¤¦³µž••™™°¦®¾ «¢‘‘žš™”’–¡œ—©…©¬¢´Ç³Ÿ©¤ª––˜š§ž©œ ¥«”ŸŸ ª®¨¤£«¡¬›ŸŸ ˜¥žœŸœ°¤™Ÿ¨“˜™’¥š™©Ÿ›—fƒ’|e~šcxŒlhjz£«kd™—~g…Šeeihz¡ŽkhŒ—‘¢wkj‹˜¢Ÿ˜slnz„Œ†yXe]…‚^l‹Š‚v[hsww‘€‡‚nx‚xsmy„swˆˆŽƒ{i…X]jsd]sˆik|qmc]QNWIdX@J4=F7?FD71<=?AC;;DGHHILNORRTW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%.++'6*$;'/AI[I.6ZO6)EY/DO1YB;?.=¥Ÿº¼¹¯¬²°«¥¨­®°§®­°½±ª¨¥­°°Ÿ­˜ ¤ž¢šš§¬œ¬£¦¨©³®ž–££°¦¶¹¥®£š¡™“’› ˜™¦–{¥¬¢¨³Ã·¥¢§¯Ÿž•ž£ž£¤ª¨’Ÿ¡ž ª¯©©£ªž§›¦ž§ ¬–¡œ¥±¤˜œ«–¡Ÿ›“¥˜Ÿ«™ž~¾ƒˆr´r…ž…­hw¹Ä¸q’¡£{¦˜˜sª‚|ËÀÀ»qŠ£‡‚ž|–˜ˆžÀ½‚–œÁÀ{z‘ŒšÂ¿}k¥²oŒoÊz›w‘ƒŽ€vyyq{€†px…Œ“ylu‘be^xd_eb^thmdbXLVIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^__`_^^^^___]\SMPGUNA@?=6468266*&%#)*&.+*)109*#>H[L*#CP/#F[3PY/UAB;/8–¢¸Ã´°¯¿©©”£¯©°¯­¦²µ¯«¦§¥±« «˜›¢ œ›ª§¢«¢¥©¥¥´¤ž£“¦®¬¸´§¯¢’‘™¥’‘ ¡—› ‡¦«¤«­¿¿±¡©®©—’Ÿž¢™£¤ª£“ ¡ž¬®§«¦£¡¥Ÿ¤¤œ­©‘¤›©­ªœ«­¢—˜¦—¢¤˜Δyz¥z––›_­]Ž¨€ ¡|§•št«ƒ€¯^dŒ©z¨‡…Ÿt—’ˆ³c‚«† ³j„®s|–‡¸a‚­Y£Ínu{Û{™q~ˆ’ue{ˆvvl}‡n}…‘}k€_pjof`_xd\qhjcf`RTSW^JOD5AHED8>6;@?A;=8@>>?BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5578164('$!',&&/(&+360$7;SL+,-J0';\:L-!P@F4.1­Á¿¿´´°·˜ž‘£ª©­´«¦²­­¬¤¬¦°ª¡§›š¦˜œ¢¯Ÿ¡Ÿ¨§£¦¡Ÿ°¬›ž–¦®­°«¨¬ ”’›Ÿ¥“Ÿ¤—§£ž®¤«°¨¿Æ³¨©±®–’žœ¢—¡ªªŸ•¡žœ®®¦©¨›¦¦£ ª’¬³–¥¢ªªž¤§§¢±¢“›§›¡›•”‘— p…Œ˜u„¨‡q°|r¬} Ÿ¥žw«‚}­œr­~«‡†Ÿv˜’{|—~ªˆ¡‹‘‹œ}«zˆ’Ž €z­VœÄzo’Á}•mupŒmfwe†oawnrnˆŠ‘ƒlŽdmsuo`fmd_ohjnfcWS\`ZRRC8II@C<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;92478452&# 1' 1''45-&7=WJ-<(=1)3V@F!G;C1-+¯ÓÅƲ³ £Ž£¢¢­®¶¯©±§©«¨®««¦¢£š£–Ÿ¦«Ÿ¢¦ ©¨¢Ÿž°¬˜›—¨¨¯¬¨§©ž—•š£¢’”¡¬š¦£¯¬£¬µ©¹Í²­¦®¬–•œ¢™Ÿ®¬–¡™žžª±§©©šª¨£¡ªš¯±¢¨¬¯¦™¦«ª«²¤“˜¤¦›•’…¤j¤u‰z©uz²q‚¥‰˜Œp‡Ÿš‡¤_`R«„®‚›u®‚§††Ÿz™—…{f€£‰¤˜†£}©~”†®^|¨U¢’z£Ÿ€|ïŌs¯´³¹qb©¯ÂthŒŒ—Žl˜‘nlxxwnkfddqpf{ic\V_iXXTLLQLCCAB;CA@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799664,&$" ('"+-"$.!3-&@DWH,G+56*1PKL# A9D4,'ÂÉÕÕÀ¡™«¨¡¯¢Ÿ°µ°¯©­£¨§ª««©¤¦Ÿ›¥Ÿ¦§¦¤¬š£¬¡¤Ÿ¯¢›“ª¤¶°® ©›œ—•¦£š¢§Ÿ ¦œ±¦£¨±¬¶È²µ©¬ª•‘œ¢™ ¥´š¡”œŸ§«©¢­™ª¨¡¡©¡³­¢ª³²¢œª¨°°·¥”—¤¨™’|ªlž„‡u«y|°n‚¤‹ˆŸ–•ž•Ò·´¸É€²^_”©ƒ¤‡‡ z˜•™xªÉs™£”§¨’šŒ~š‰šÆÆwe¡‚¥sŸŽ‚}¯^oµc±uK£†m§G‚“dŽœ’{o•}nyt|zm[ejrqfj^aXcm\^YILLKEDBB=A<B?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\]\XMB75785/)(%&%$&),5FNPPMFLJVF*L0/>-4NTQ;<F2,$¨¤Àƹ­©²®¬¥¢²¹¬ª¡¦›¨¦«¬©¦ ¦¤˜«£Ÿ®¬¦¡¬šŸ©¥§µŸ¢—“¨«¶²¬›¦œ –¥­’šœ¦¢ ª¦­¡£§©°´Â±²ª­¨”‰˜¥›¢¤¯¦—¡•™œ¥¥©™®œ«¦¤ž«£¶¬ ±¹°žœ¯¨´´´¦–˜©¤›¡‚NxšŸz„£|‚¤„†¦žœž”„¸{|y¹‚ÌÆöw›¡‹Ÿ~š–—‰vŸ—Š¤˜¤§~¯„›ƒž„¬}™”a¥l£p…}—„r¬`¤rq€š`¼}RUuŽ‘£–{|‘Ž‡ryrƒ}p\lnwrj€nZc_hnbd]LLQSAHGFI99K>B108856877-*5==?BDGILNPTWYYZ[\__^]__\ZZZYUSOH@772.,*.+*'&?QTVWWWYXXWUOTF<E2:P[T6?G,- Œ‡™©¬¤«¹«¯ ›¡¬³´¦Ÿ¡•¦¯®®©¦¥¥š£§¡²®¢©§² ™©¤”¢µ¢£•—¢ªµ¹¤œ££“¡²™ž›¦¤ ¢¯­œ¤¨¢µ±Ã±­ª­ª‘‡‘œ§£¤¥—ž˜™™¥£§˜­¡¬¢¤—®¥»¬¡··®žžµ³¹²´¨™Ÿ±¢¥Ÿ‡ÑµÃ·y‡Ž…‘“€¦x”¢w‹ ’…¥‚‹q«†…´nri™£œ•‰Ÿ|—™†‡s®‚¥›¢Œ¦Š“œˆ”šmp²\¥s“zœl™{™~n©a¢qqŸbs²¸hw“¤˜}Š‹ˆv{xlhwixsn~t\ddmmeh`JZWX<HF?T3@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^``]Z[ZXURRQF:2230/++(@QRTUTSTVWWXXWUUVTQOQ[U%!2AH#)%’rŠ­¿¿¼»µž—¨¤­¶¡¢™•£©§®©«™¥¡ž¦¡ µ§¢©§°£”«£Ž¤­£ššª´´¤¦œ©’”—®  ž¦£œ§œµ™¡ª£µ«Â¯©«©¢Œ„œ¢ ¦£–ššœ˜›˜¦£¥—©¦¬ £›¬¦½¬”¾°­Ÿ£°´»¬µ¨ª³¥©™{¨‘}|°wŠ¤¥ˆœm²o ‡­{¡ƒ¨–™€¬‰…®… ”¨¡¢—…Ÿ€™•€{’~«€™–Šªw ˆ“’y¯]£|¦§dž€|—tk®]¥kq…™]`[Œ m”¥˜‚“‹“‰xy–~jl}b}tmy`gepngghBY_[=JS2T8BBC7$$3+''3, /667436:@CFIKMNQSSSVZ]_a`aaa^][ZWSPONI7052.*,ATVVVTTUUUUTTUTSSVWWXVUVQHFIJ#((¼’š„©ÆöÁ´Ÿš­ ®¸¥£Ž›¤£ ¯®©Ÿ£ž­˜ž¹ ¢« ¯ªš®¡‘ª©¥–‰š®°¬¦ ¨›­˜™­¢¡¥¡™¤œ­—Ÿ¨¥¶¨¿®¤©£Ÿ‹€Ž››Ÿ¦ž’”™š”šš¤££˜§ªª¡£ž©¨¾¥—ì«£¢¬³»¬¯¨¢µ±ª¬™v¯~Šœ…‡}º­‰˜d°Œe•­}¡ƒ§–›­Š„°…¦™£¡¢‘… [lj³`­{{‚€±lgm™—‹ˆ±[}´[¤ƒkÈ¢eŸ{¼YvµZ²}R¯€z¬X€¡m—Ž§™‰•“”ywŒ›|cs|aƒxs|aifpmfeeOUc\AT^=H(>9=4!!,$2. *1/04579:<ACFHJLNPPRTWZ^`_`ab__\[XUPNJGC553./@UYXWXWXXWWXWVWWWWXWWXYZZ[\XWWGB;ҟ´±·½»´Á³£œ­¦¥¶© ‹™ Ÿ³±¨ž¢Ÿ´˜ ³¨ª«ž°­ž¬›•®¨¢Žˆ›Ž¯¬¨§£¨™®“š©š¡ž¥ž™£¢¥˜ž¢©²¨¼¯¥¨žŽ|‹›–¡ ™’š›‘™—¨žŸ—§¬¥¤¤¢¤©»ž Æ§¥©¢¬µ·®¯¨¡½¯®®—©’£®Ž›€†¤—˜€¸ÃºƒŽ“„§˜‚¬Š‚¯‰§œš¥«‘~սªb£¿½|~£‚ƒ×º·µ…“’‚ž½¾„j£o«„nz²±Çƒk«°½¬xw¢¾»t€•¥š™Ž”šw™xa|ycŒgx{`kekjaPb[Si\@T`BL)<:5/$%2 $(0496678;>ADFGJKMNNQTW]a\__a^`[\YTQMHC><A?5=SYYXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ»•´´±¿º²½³¢®¦¥³¦Œ˜¥¿©¶°§¡¿¦¦±›ž±œ¹¨Ÿ­®¥§•”¯¬—Œƒš‘®¦£¬¡¥œª ˜Š£“¦ž§›š ¨¢˜ ¬¬©¸­§£š—“{ˆ™’¦›“‘˜˜˜”¨™ž–¨§ž©¦¡¢«»ž©Å£ ¯£«´µ«±«¢½ª°°œtvª¤·…e‰Ÿpg¬Šmow¤š u°š–pr–¨£›˜®¤rlmleŠxnm‚™q€zipif‰–•—qhi…†gp†d]ŠcioY]g~x¦`br’ofd€“Ž¡–•–Ž”›z…“td†wgŒjx~xdlcflbKeWJkY:PdDP'J:+# ",)-2.5:457:<?ABDEHKLMOQSV\WZ\`_a]][TPLHD=:AB7MXYZYYZYXXYXWWVWY]^^]\\\]^]^][[UW^¨•­´©º¹²³ª©¢®ž¤³ª˜’½±Ãǽ´©ž¿«¬£ ¦«Ÿº£¤­¬­¥Ž–­ªŒ…•—­Ÿ¥ª¢Ÿ¤£ ‘‹¥’§™©™–£ª –œ¥¦§¯¹ª«š›“’{„–Ž¦—Ž‘‘˜“—•¦“–§¡™°¦¢¬¹ °Â¨¤³¦¬±²«¯­©º¥°¹—‹¡©¥µœ‰–¢˜†©š”“ª³™›£¬¡´—£¡ž¡¢œ¡¤¡•¬§Œ’“Œ‡’œœ”™“˜Ž•„¤š—•Ž‹“’Š†„~g‹€tƒvt‡Œq§m|•’”“Žœ’Ÿ”•”ž€…’‹pgŽvn‰wu|yikddocU`X@iZGb`NX+E=+&!640/!%2(*799469;>?ABDFJKKMPPQWUVY^_ac]^TQJEC>9=@ASX[\YWXXXXXYXXZ[[\^__`^^^__```_YY`¥–©ª¤µ·®®¢°¤­Ÿ ¶±ŽªÄ»Ä¹·©¡¥›¥°¨£¶§©µ¦§‘˜¬£‹ˆ‰œ§–¬£¡š¨žž“•£—¨š©™”¦¡£š§™¡´¹§ª˜š|”Œ¡”Š•‘•’—¤Ž˜§ž›µ£¦¬·¨¯Â®£·§°¯±®ª«µ»¢±¾™’¦¤¦µ¢’¦ž©Ÿ’Ÿ£¬°›¡¤²ª±™¥¡¤«žžœ—¬ž’š¢›”–ª™˜˜––ž‘‡ •”…’Œ•‹~f‡u‡vyˆ„tœj‡‘••’Š}Œ–’’—‘ ‘š”ž‚†–…xq”rx‰~q{~ind_pi`[_YmbP`dOY9GFE=2<=8/*&+)&&406658:==?AACHJGJKLMSSSUZ``i`eVPJACB;9EMV[^^[Z\[[[\]]_^]^_`aabaaa`bbbdb\[c—•¤§£°³¬®£©§­ ¨µªœ£²º­ª«¡¢™zœ¢°¤¥±©–›¸¦£”˜©œŽ†Š‰›¢®ž¤–¨ ¡’—™›®‹ª–¨™¨Œ˜¨Žž¸¶£¥˜›‰y”Œ›“Š•‘”‘–¡‹œœ§ž¸£ƒ¯µ¢°¯t¤¾£² x{¡¬´½–w®¥ Š€©~d\bvŸŽ¤ƒ—~n”´œ£¨¯¬¤eŸ ”tzš—q€™©˜l€£¨Šeœ¥›—˜–‹’›„š”ƒ’‡ŽŽ’‰…wkˆv‡q|†€ai‰‹•“Œ[v•‘ghŒqy¢––dw—†€v—h‚‰‚ny~jpe_vokkg\ecaaoRZ=MMNRF=@TB91/&4:306678<;>@ABFHBGGIKLTUUY]`hggXQI<DG<9VR[`ab`^`_`aa_\]___aabcdabaaedchd^]fœ–¦£¡°±¬«©¥©­¤§­¤’–ª´®±¥™©¦ª—s‹¯Ÿ¨«§“–¸  œ¤ž~ˆˆšž«š¤•§¢žŽ—‘ž…t®ˆ¥š¨‘–£ˆ›¹³§ ™™‹‰uv“–“Š“‘”Œ“Ÿ™ž¥˜›²–€Œ›µ´Œ’½§¡~§¢{¤°¹‚Ž§Ÿ„‹…±©¯Œ‰–¢™y‹¬†œ¢¨«©ˆ•‡™w¥›z‡œ—§‚{²zŠ†Ÿ—™”˜–––„™šcy‡„’‹ƒnqˆzq€††t‡…–’x–h“t št{™‚š„˜}‘ˆ‚˜iŒŒ„jxzppgdwmilj\diier[\HTLQ@E5-YTT6)!09=>643568;:=>>?DI@IEJKGRXZX[aahfYQH9DK<>bV^bded`aa`bb_]`aabbbcfgcba`edcgcaah˜£Ÿ¦®®«¨¬ ¨°§§ª¥™”­Å¼¯ •¥§´ƒœ«œ¦¢ ¾ž™Ÿš¡|…Ž™˜ˆ¬£–¡¡’”‰†€‘¨Ž‡¢œ£“–†ž¹±§š“…pu‰”Š”Ž›‹Ž‘•ž£”«‡Ÿ´‰´š®‹Êˆ«¯‰·…°ƒ²°…©Ž§˜|¨r{w›Ž¦–h•¤y´‹ŸŸ§©“™Â‚«ˆ˜¡qž€š¥}—…•²€¡} “Ÿ˜—€Ž“›‰˜’‹|…“†”“‰ƒms’†€{r†„}…u†‚˜Åf€©‡¢jž—€™€Š‹ƒˆ˜o’„gwt{vghupghk^bnlflXfF\QL2E46Mac7&4<DGD:63658;8>==>BL?NIJKCPZ]\Wb^jl\QE=KM@JdX]cghgbbbbcc`_babcccdiicbbbecafcbbi•—¢Ÿ°¨©¨¥« ¤¹±©«¦š”ž¢¤ª¢•¤©µ¢¯ ¦œ¥ž‰”½™“ ‘yƒ––‘ˆ«™œ›š¢…Œw›œŽ ‘ˆž¤›•˜—†¢¸¬¥™›bm‹“ŒŒ—‹‘ž’ž ˜ §~¡§‡­ –® ž‘†‚ ¬±ˆ¤Ž«šŒš~¢u€˜“k«tM«x‡’›©©‚ª«~„¡{z§iž’lg—†˜¶‰ž~n`cXƒ—Œ{dg‹s™}y–k]|—n_Sq…\`lyƒ`Ye‚~„˜q§ªkƒ£nr¥pŸ‚œgdžlZlˆzeY_‚~aWPovemtqjjn^jolkhWgN]XE9@4GD^k4+ICQMN=84859;6@;;>BO>QRLMBJ[]_W^_bv`ME:MOMTb\[fgiibbdaddbab`cdcabjkdbddgdbgeach˜– ¹ ª£¦¬‘¡¶¼«®¢™–Ÿ ¥««Ÿœ­´¡§‘ ŸŸ¦›™˜´™‹žŒ•‹u”‘Š¦––˜Ÿž~“…†¬£‡œ‘Š˜©˜™š‘‡¥°¦¢•™ˆ‰€inˆ‡‹ŽŽ‰‹Œ‘‹‘ ‹’Ÿ›¡¥“£¡” wœ–§ƒ¢¨€†«¯†¥z‹}„š}¢pr’‡–{žŒym‡›‹™‘œ©œ‡|‚¢sv¦fž~w¤^˜{}“s¢n˜·´ºs“‡€¶¨dÆ¸{p•¶Œq€›¤ct¬«`}j³~n}‡ƒ‚‹—q€£ls¤sž‚}£^œ™³–o{—ž³tr[ž²‚ibosuqhnXkkrrd[g]aKD=D5QAZq2<RF_JS=<395::6D;;@IP?TMNQ@E_^[YX``{dIC8LWUVbaZffkkbbeadc`ab`dd_`cknccddhdbgfchh”–•£¹™«œ“ Ž¥¸µ­­ š¡›¢£¤«›š±¬ª’— ˜ ¤™š”ž«›‹ˆ’x‹…p€–Š¡“”—}‘ŠŽ¨ ‡˜Š’¢“›šŒŠ¨§¤ž–‡„~k{‡~}ƒ‹‰Ž“ž•›Ÿœ Ÿ‹‰wœ˜¢ r¢‹ˆ©ˆœ§‘—©¬€®Œ}z ™y£“x€s—ˆŒœ}–Ÿ†›Ž™œ§‡£d¡}‰–›Œlžhšnš™{€Š§}rgsªƒ‚sªg”š]›…v„hªj¸f\©pœa•Œ^§vv‰Š€hšu‡“’˜Žžm™j¦™\¨~w»j}©ZŽ„]³g\nqxwki[piwxa^dVaAPEO7VBRn4JZY^NZD@151;;7H?:CGU?XRX]>Db]V`Qac|iEB9N[^YdfXfgmmbbe_aa__``ec^bdoq_deekdcihgki•œ‰ª¶›¨‰c•œ¬º²°«¥›š§Ÿ¬™°§ª–¢™¡Ÿ™–– £™†‰iˆ€q{—ˆŒ––„’”˜zŠ„–£œ‰•†‹‘œ›ˆ¨¢ŸšŒ‘Š€€i†y–Œ{ˆŽ‡Ž•™~’¡ž ¢“˜rhŸŠ Œp’Œ‚©ˆ™ ¤©¢©}°­¤¢¸—v£³¢£ˆ”xz«š~¢žœ˜‰˜r¡}…°µ}kš‘¡x~˜´££«¨„˜{š|œš~sªZ]o{—‹xžbL{{…dz˜BMŸY¢jr|ŽnŠ„™v›y‡‰±³~š’¦t~mq|”o™ri£]•vHec`sp}}nf_khu{bc_P]V\TV@YEQgERV\aX_ID=B8@A:IE8LEXAVQZVDFa\Z`K`m}qEC<U^bZejVhhmobff^a`\]^`hb_edvl^egfldelhhki”±®™„S_¡§´º³³¨š¢‹š©›œ§’ «£ §Žžœš™•˜¡–‡‡‰w…ny•…š‹}‘“–ˆr€‰’ ›r’ˆ™”Ÿš„Ž¨›™•‹ŠŠ|„l„…q¡Œx…ˆ‡‘—“{‘¢Ÿž£ˆ®†}µ„ž{¦–z©‚–ž‘‹¢ž~§hwm~™s sq|…˜o“‚®}£ƒ§Ÿ›¤p^©hu£co¥aœÓ|z™xrsc¢…~¢r¢Žuk³‹`‚˜Šsª²§¼wƒm¿¦ª´^œo~r—os¢r^¤gt¦`h¦lšÓ˜z‚›nvy—k›yv—rl©¥g_dyp„kgfcmuwf_aQZePQaHWIT_WS[dj[eQFCKLJKBJE8P@PMXSXORQ`eeiRdxywIFEc]eZhjSihjocjf`c_\]]_ibahe|d^dgdkdjlfhlh˜›°¬T\K~©¯²µ°²£œ˜„—¦  £Œ¤§Ÿ—¨‰™—˜“™“‘ —Žˆ…{p}„h}ƒ“šw‘Ž‰p‡“’l˜”|‰‘’£•ƒŽªš“’‹…‰y„wˆ€nž†w€’…‡˜ •y’¢£™ ‰³¡¢¶‹z¬§¤®¥p©€›‘†“}¤€¢™†˜qž„¢­®‰—‹€Œ¤•ƒ¯¢•vµ¶¶É¢t”‹‚žaž—©my•† ›u¡‡w }–ŠoLf£’pšˆs¥{ytbƒ‚l~ lrd`œrt—k{j´µ´Æ¦s˜~zœjšš«tšlsw—i™yt—qPD}³^jujx‡fkgbttpmU\RXgORhIULXRU\gknUgWMJAJMJHJNAQJPdcimetrs~x{nu‰{{TQOm^h[kiRjhilgmfce_\\\_ibdhk{_]dgcjfnmeile¢œˆ¯§…f?”¡³¬¯¯µ¢¢–§¢¡£‹¤¦œ›¥š—–—›“Žˆƒyjy†eƒŒ~–ŸyuˆŒ‚i„…’ƒŒ…zŒŠ•¥’‚—©—Œ‘‹€‰z€}‹yp †y”†ˆ•ž”~“¥§œ––„gnxœl¢d|q¥xœ˜ph§‚˜|¤z –ƒ–rŸv€‰”•¹nŠ¢b}™¢–‰nsj«ku mo¦`›i‹i–‡š•u¢€}š_‹…Œuoˆbh¡eži›updgˆ‚nr¢Z_[c¡n]‰Œp{trd¥nx¢df§h—r‹˜n¡oRˆn ^d§T‹]T˜mmrjqmphkxskoQVUUeYSmIXO\HXhhsjYkVPREV\LXRaUhj^wuz|p||r‚{sv€ƒv^QsagbqgPkhhklohdg_]]]`jbiivu]\chcjirlfkmc¥™¦zetm‹§®¥ª°±¦Ÿ‹–ªœ¤‹¡¡™¡¡€•˜“š‹—Ž‹{†q€ˆh‹Š|—šst‰}|eƒ‡•Š‰–™‚|ˆ…–¦¢«…ŠŠ}€€Žsi¥„}…“Œ‡—Ÿ†‘©¦‰¦x–œ~¥‰–Œ²™ž‘ƒ¯—Ÿ¥y—‰z©t¦„šn¥¢Œ’„Œƒ¼n}¥¯‚‡†‡”—¡}¦{r¨” –gž~o¬c–Š•’w¨l©¢‰v‡‚w«‘¦ˆk‘°kv³Œ©l‹†oo ž‘”a«‹ªwŽ§ŸwŸ}…¤• iš‡u¬fž­Œ¶sv¾Œ£“Yƒ¦«`uqso{upbj~nhlSUYU``\jL\Q\I]lmv`[qX[_Zgsenoqcqt`wz~yryƒrƒ~{{Œ‚€vbyddnsdRlggolrifia_^\ajbllzo\\biamiwmglnb•¦ªœ€ž¤–ªªž¨§®£˜ˆ–ª™£‰š¤œ¨„‹š…œ‘…’ŒŒt…zˆƒo„}—“su†r‘ƒn‹’††”}{‚…—¥¥¥€‰„”uƒ‡’ol‹¨€‚‹“ˆ›žˆ‹’ª¢ €t”—ˆ~y”¯¤œq†y’Œ…€{r§Œq}}z—–›„x{~~ˆ”•“‹w‘™ ¡„{~‰kŒ…[yysypin~’Šrt”“q…ƒ‚e_€Œwvt”uo{oo‰n„†^wixŽf‚ƒ†ªœt}—j‰ˆou|„umlfŒsw{—w„ZjWyhmwrqowxo]l†migVY^W\dkdUaT^Q_owykjwejjju|pqtsaoubs{xuyu€y‹…‚}{mldyn^Wnghukxjiid\`ZcielqunZ[bkdlkymhloaŽ•¹©§‹¡¢›¦¤™¤«¢Ÿƒƒ–ª‘ ˆ™¦š¨˜ƒ›‹~–”‡ŽŠ‰Œr‚|}~„z—Žtr„p•†{}’‹††…x~€†˜£Œ{§¡‹…„•‚†Ž˜wq„ª…‘œ‡ž†Šš¨Ÿ ªƒ‰Ž•›~Š—­¨“§xqž“ƒ{“p©†p}•qjo|Ÿ‹’Ž‹hn]„ŒŒœœ s–Œˆqtk‚vt€Yrn†‘‚~~‹i]icz…ƒˆ€_ix{œ|ƒƒv‡ƒiyŒˆkbqrƒw_r‚Š¨–‡gƒnw‹‚oƒ‹wndfcy‚z•Z[ifmv[zxwtmsr‚f\mŠkkbYX]YXkq[^`Y^]er}zsotcjji{|rzwtdmthl{~uz|{yy€p†Š„{}s~zrhT\rilvpugkgd]aYjhkjqrmW[emlgryohjm`ŒŒª±¡£¡šŸž˜ž™¨¢¡}‚–«Œž”‡š¡¤”{˜„|’™ˆˆ††Šr}€‹v…‹„–Šro€r™‡„~’ƒ„†Šz€„‹šŸ‚¦ ‡x—ˆ•‹‹œ—„ƒz¬—™“‰œ†‡¡ªŸ¡¢£‹ˆ“›£™–ª¢¨§¡“œ‰˜|y…¨~~’‘’“œ±¥š”±’˜„¦ŒŒ–œ Š‘œƒ‰’Šk|Žvwe‚†Š}‰„‡‹‡ˆ€…„w|{u›£‰ˆ‹Ÿ‹†•~‚vqt†…x‰ˆ‹‘§‘„‡ŽˆƒŒ‹{…‰‡ujƒ{y™iqh`sŠp}zwvovs\^o‡gn_^YZ\RgqUc[[alht{|rnpcjih{mx~phoplf€{r€w}„{mƒŒ†|zx|~zƒxNdvjsnq{ekebb`[sfpfrqlU]ltmhxzpgikeˆžºŸ–¢¡˜•™˜”˜¤ z˜©žŒ…ŸœŠ–|x”‚{Ž™‰†ƒ„‡mx€r€‡~ˆ“„ml~z—‡„ƒ~€†„†}‡ƒ›‘†©ž‚qŠ…’‘‹œ‘}z©ƒ‘—•Žœ–……›¦Ÿ¢š†ƒ’š™™™¦ ¦žž—‚“‹x}ˆ…¦||‘…˜ª œ“œª‘€ž‰”› ƒ—‡Žƒpx†qta~„†uŒ˜€ƒ‚†„~…„•nyvu“£ŒŽ†›……Žu€Œ~}rs|‰„{y…“¨‡„‚ƒ‰‰ˆu„††‰zmj}zmhklf^y~g|{vtuuzw\`p}mu`cZ[^QfmSeZ]akiuz~pllcjjg€krkjsnxnƒyn†€v‚€}…vr‚‡~{z|{‚‹`i{kuhiƒejc`i[cuhobumkTbqyeoyzrejmm‹ŠŸ¸š¡¤Ÿ’‘–—‹šŸžzwœ¥›‰†¤”Š˜™xy…|‰‘ƒŒ‚‚‚l{xr€…}Š|kh}‚—‰ˆŽ|~†„‡|€››‡¦œp‹ŠŒ’† ¡Š…Œ|§‡’–“–’vŒ£ ¡–šš™“š¢¢¤›˜‘œ†z…ˆ¡€~Œ|—¤  ’™¦Œœ’Š”˜œ~““~‡Žvt‚pv`}€Ž‡rŠ–|ˆŒqŒ~‚……ixry™“€˜‰Œs‚ˆ}}qz|Œ…{{’Ž„—¦”Œ†‘|„…†„t€……xdqz~xypkjf^}sh|uus|sj^`tvpwdcX]^RjhTdX^ahjvxqfkclge€jm}gmpj}w…zk‹r}tv‚Œ†|z€}jrƒntibˆilb_qUtomn`xhlWjtvctzzqbkoy‰Ÿ³’¥¥œŽ˜†œ š›{u£Ÿ—Œ¡Šˆš•x{†‡~ƒ‰~ˆ‚p~ztu‚…~‰wgc}†—‹‚Šx}€ƒy–€•—••Ÿš}o‹“†¥›‡Œ‰ƒ¦•„’Š•—’‘v¡¡˜”˜zŽ˜——š¤ž™“”œ{‘‡„x†—Žž~‚ŠŽŒs—¢ž ’˜Ž¢Œ‹ƒ˜™„“–š˜|‰wr~n{d€|‹†p†“€‚k‡ƒ€‰…fvo}ˆ“™Ž~”yŒ‰}€ˆ}|r€y‹†z…’ŠŒ™£—ƒ„Œw‡ƒ‚uy†ƒs^ww|s}wfkc`~ijvstu}q|ccasnurmaY_]ZkdRbW_`iluy†pbjclfh|ƒkhthloh|xm†q€‚‚t|ƒŒ€~z‚ƒ~|mu‰ttmeŠljbcuVƒipn`xglajvpex{yp_ql……®˜¦¨ž—‡…Ÿ’–—|v¨›‰˜y–œ‹Œ˜x{€‹}|ƒ{€‚xsxys}€ƒˆŠ€d^}‹•ˆ~…ˆt}~Š~˜„–“–Œ£ —~q‡{“‘Š¦ŒŽŠ’ ‘ƒ‘“—Š€Ž— š’’t€’”‰ž§™˜Ž•˜u‹m†™š{‡ˆ‰o—š¢“•ŠžŒ†“€““–‡š‰|ŠŠzrzkul|‹~n…’ƒ”xo‚„~~‹€esj}—˜…€Žt‘‰„zˆ~vx~‡}„Ž†•¥‘y…‚tˆ†|rs…l_ytxp{nanbd{anovswwssav`oluno][^]]j]O]Wbahmsz‰k_iejchwˆmflhilg€|zwo‡s€ƒ„}t†‰zƒ}z„}|Žry‹yxnl‡kh_irc‡hqoevgmlazhj|{wpawm‹™šª ¤¨ŠŠ‘†ŠŠ”—|v¬—Œ–|ž“‘–”ˆv}{Š|{€vw€otszo…}€‰~|a\~‘†€„„sz€†z‘‡‘‘›’¤š“||Š’£ˆŠ—š…‘˜“•Žˆˆ‹’“Œn„‘‰ž™¢¡——‰—’p‹›…g‡š”{‰…Šp–š”¡’’ˆ‹™Œ‚‘Ÿ}’“Œš{Š…‡tsvkqnv|‹tn†‘Ž’qt€|‚ˆ|eqmz~›”~…Šu‘‹tˆyn€~ˆ}…Š†Ž–ªŽ{ˆ}~Š…w}onƒbgwstnza]o`jt^pjzxxlrpey]mlsmsXZ]_ajZOWWdcfqqˆe]ihgbgqndigeig€zwuoŽ„sƒ|u‚ˆ…x…|wƒ…z€Šw‹{{ryƒjk_phskqnmqgoke{bnywpkvw‰£˜¢¨¡¦›ˆŒŠœ†’›t€©”‘† Œ•“s{v…wxrs{…kroym‰v€†nq[Y~’ˆ€vu€ †Š‘œ— “–w‰~€Œˆœ‰†’—–…ˆ”˜–‹‹ŒŒŠŽ„n‰‹‘Šœ–¡œ˜–†˜‰l†¥…g‡ž‹’Œ„Œw“˜‘‘ˆ‰”~~™|‘Žš’}‹€ƒovplmop{†isƒŽ˜Špw€u‚‰ƒygsov‚›}Š…{•’zw‰tpŠ|‡{‹‡…Šœ¤‰|„vŠwwmj€\qrqoowY]o`oj^oi|zpmmjmw`pokqmYX`aamWQSYefbup„‚b]kmdcfk’m`ff_gktqrp‹€t‚€yv€‹€y†w‡†vƒ…{‡Œ€{vŠjqb|b…|opltjhnlvw_q~x{tus‚~¥•š­Ÿ§–…Œƒ~–”‚ŽžtŠŸ“’…ŠšŒ•‹zrwt‚pr…squˆlnlumˆwƒ}mnUQ«”‡‚y€vr‚y‚ ‚‘’‘—›‘™wz‚Œ’¤š“Žˆ”˜’ƒ†–˜‹“‹ˆŽˆž„Š|s‹…ˆˆœ™Ÿ›–•€”€i‡ž‰h‡¡ˆ“…‘„Šqƒ‘—šŽŒ‹w{“‘{Ž‹’—|ˆ|kwjnklmzby~Ž–vzwƒ}zhumuˆ–Œ‰‡{”‘r{…pw{‹{‰~„Ž‘ŸŸ†}}xŠ|vohk€w^womkprU]naqa_mnypgpffsuhqlawe]Ve``rSPN[ed\xpˆ|^\hqbbef‘i_gd[go~okqsŠ}v}…€uvŒy{†€xˆƒs†…~ŒŒ„|y•xfqjƒ_‡~ookz`imtt_s|x†wss…|y¡š±œ¥Ž‚Š‚™ˆŠœ~Š˜’Ž„ˆ—ŽŽŽ„vtvs€po…spqƒojium‚n}|musRN‚ßɒ֓|otƒuƒŸ‚‘v”˜›˜{“r…Ÿ¡““‰’›“…}••‡Œ‡’‰œŽxzŒˆŒŠœ›œ›–”zŽwiŠ“‰m‰¥†“‰˜ƒ†cŒ‘˜”‰–‹‰‹pz•‰|Ž‰‹“‘Šz…|m|esoklzy\€yŽ€{}~†Ž{ziuktŒŠƒ††}–l€p‚€Ž‰~„{ƒ‘–››Œ}wx‚xrken}kitoghslS^odpZ_lrwfkkbgxsoqd_w`aVk_^uOMK`ec\yqŠt\[ev`aeeŽc`fbXirsmkqv‹|ty†‚vw~‹s†~z‰r‰‡‘Šˆ}~™vesn|e‡npk€Zknxyr`vz{vrvŠvyŸŒ›¯› ‚…xˆ”~{ˆœ†„žŽ…Œ—„“Ž‡twpypn„omn~rcdxp|nz|jhlc¤šÁÜ®ï¢skuƒu„¡„‘n•”Ÿ”š‘p…‹£—‰Ž•Š•ƒ€”„ˆ€’ŠŠ—~‡{u‰x†…Ž›š—™v‹wpˆŠŒ~Œ¥…’Š…†^‹”—‰ŽˆŽ‹Š„‰l|—‚}ˆ†Š‘†v…~~k}cxtjoxsXˆz‘‡…z€…Œ~zftj‹‹„„€Œ˜†l‚wo‰’ƒ‘…‚{‘—”›‘utx†Œurpesw€`sloahufR`pgkU_ntyarc`i}qrn[cracWnZ\wLLLcea]vsŠm[\dx^`df„_cc^Yirknkrw‹}sw„xx|‰qƒ„|}ˆ{t‹‰ˆ•†Œ˜shuqyl‹{ntp€Wpyvyqdvx†Œhv€‰q€ˆ™§œ£’„|pŒ”wx‰œƒ„ŸŽ|•€™‡„{rwpsjokil|t^`xv{ptzg`e|ëÚµÉÃ܉sls€vŠšˆŒi—Žœ”’ˆp…ˆ Ž„Š•ŠŒ—“|’ˆ‚ˆz‘‹†‚€wxƒ„r‡‚“›–”˜†v‡q†ƒŠˆš¤„•Ÿ„‰aƒ•…ˆ†‰Œ‡€‡h}”}‚…‰Ž‚q†rwgvritwlZŒ}’‚…}€ƒ€„Š‚vbumŠ‚‘Œƒ€“’~nƒmzˆ‘ˆ“…}‚~“”‘˜ŠorzŒ…tkoipv~^shn\iu_RdqhfS_pvt`o`]h‚qrjWgiciXmW[tLJLef^ars…h[\ey^^dgzad_]YknenjtwŠ~sr~{vz‡t…ƒ|‡wvŠ…˜‚{“vlwvyx’unwz}Xy…qnfxv‘‚dv†…qŠ–†™¡›¢Š†so’‹rvš|‰™ˆ‰{Ÿ„™xqtnodr~hflww[_x{zqqiagaÕ¶Ž‘¦xnqw{q’Œ†j˜ˆ›‘‹†{h‡‹™†’††—{ŒŒ€€‰{~‰…zu{ƒ{q†€•™Ž’”‚‰u„ˆx…Œ•ž ‡– ˆa“‡ƒ‡ƒ‰‚f}‘€~‚Œmƒ|‚tkmwutwvkcŽ„|„…ˆp`tr†}Žƒ}€’Šzq„g{…Œˆ„|…•’”…opy‹tlmijwzagiiXkuZRiribPbrxlbe^Zjƒnsb\g_em_nTZoNGNfd\fnr€kZ[cs_\clwde]]Zllbmjsv†€qo|}tx†x…ƒ|€ˆvx‰’•{‰†v‰oxy{ƒ’om{€v^ƒsmhzs”sgs‡|r’‘„šŸ› ††uu”~mu’–}‡ƒŠ™|Œšv~vqoljat|gbiuyZ`w{ymq~echhW_rs—¼Ä„vq”ˆ}q–‹†›’Œ‡rjˆ–€{”Œ„šŒ|Š…|{‰‹”ˆu‰†vw}ru†ž”…”ƒƒr€Šv†}‹šžš‡•‰f}“‚~„ƒ‰‰r}f~Œ|y‡‹}i€}ƒvfoyxswslkŽ…ŠŠ€x‚…„k_sy{~Ž‹†|‚~s‚iz„‰Œ†…y„}‚™‘~nm{ˆ}vtnfe{tb[pbWnqSSmrhaNftxf`^]Yo€osYeb]jn`pOYkQDSg`Zjnm|nY[^mcZbowdg\]`kicljsvƒpm|tuƒzƒ‚|…v~ˆ–x„‹tˆryy~oo{€qixz~ml{u•kjx„tk“…Ÿ˜ ™„ˆn}Œviw—Ž~€‰‚”—‰y–ozsplid`szh_eqzZ`r|ygqzaee±²wKbZ¥ÙЖq{Šw}“Š„˜‘Œ…nk…’‘zy’†„˜Š|†xw‰Š„–€o‹ˆqu~zjy…ƒ¥„“ƒo„w…z‡š•Œ”‘•…ˆp{’‚|‚ƒˆƒnwh€„xr€ƒŠ‡|e}~„vcps€iypou™†ƒŠ|vx€…zƒk\rs‚‰†Š~‡Š{‰r‚nr…ˆ††s„z‚šŽ…yno~„vzdfh{o^XvZXplNWqsf`Klwta]\ZYt}soWg]fjr`oNWhR?Xf^Zpkhzq[ZYkeZcqy_h\^elhekiqwˆol~€uo‚{€‚‚v…ˆ—‰q‚q{†|zyƒ“Œujy~ko~t}or{z“po~xg’‹ƒ¡™œ‘‚…f†ƒogy•ˆ}~„˜‰|Œhxrklf_`oym_box\dk‚zaqv_eeÔ꽋2:>‹Žqx…ˆŽv‚•Œ~’Œml…Œu|…•ˆ|‚xnv‡„ƒ—wnˆ…lu{tfy‚ƒ§‹‚Ž‹„~n€vx…{ˆž’‘““Ž‹‡{’†w~ƒŒ‚krh€~xm||‚Šƒway„qdqh~nuqu‚›‹€…€su~so\nuy‹„‹{ˆ}‰xzrm‰„‘…Œs‚z€—Œ‹€umkv€€ut[ggunWV{RYpdKZrre[Ipxo\[[Y]t~thYb[gfodjMWfQ>^e\]ue`upZYTndYdqyZh]_fmgikipw}Žmi‚„~yn€||‚zu‚“„p€‹nw}€{{‡’‰h{}js{r…zsw~~Œzx„}|kŒ„›–Œ€l}kh~‹z~~ƒ“‚~}Šˆkuqghb[bgso_aks`hpˆzbst^cd› n\5Z¯µti€ˆ|’†u…•…sŽŠ‰vpl…ƒ‡uy‰x‰|“ˆz~rgu‰~~˜oq†~hvynfy‡„¤‡€†Œ‰~nw‚~Ž›ˆƒ•’™Š‹…‰|ˆpz}„{h~lj€{zjzw‚‡€r`w~qdrgv‚mu{†•‘|‚owz|umYp€wuƒ‡xˆvƒ‰zxso‹‘‚‡s~”‰Š{onjmtm\fdrpPZzM[o\O[rodUKsxiWYYZaq€t`]]`gdiifNYhM@`c[`ua]ulXWStaZdorWj^bhkgmlhpw|“lh„Š||p~{‚zw€Š‹ƒq{ˆoqwƒ{‰Œƒj~{mwxvŠw|x€‡ƒ~~zm„Œˆ˜£„ƒzu‹xklƒ‡x}z‘€€~Šƒprpcf^Yf_oo_`gpfjo‰tato[adjv{€¿œ¦¤È¸q…ƒr’|x†’‚s‹‡qroƒ{ƒtt‡tˆw”ˆyypcw‡z€“ir„vgwucj|‚ˆŽ}s€u†z“‘„z—–ˆ‚ˆ{ˆˆkxy~tgzhkysizv€ƒ}h`w‡}jjth{€ivŒ‘”~z~~p|v|tbVx~ss‹…‚}„q‡Šwxqq„ƒŽ€z~}v†„wjqil‡qo\faqmIduK]mUSYrnbQOtxaRXX]ao‚s[a]heedkdP[pICc`[cp^]whUVUv][enhVk^aigennhpwz“miˆŒy}r{~y‚|u|ƒˆ†ƒpw„rmw‚‚~‰‹“p€{wyz‹tƒx~‚„z€uo~Š‹›žˆ}…zw…{gt…Œy~{ˆ…ƒvgon_d\XeYmra``plkh‰natiY^dn€w©ÚªÇ†‡²q‰woŒu{†z’‰tst~w€pqm„t”†xuk`z‚y‰fq„pgvn[m|€“€y‘“~y|n‰w‚’…u—‹’‡…†{„ltv~mgvdm{umiwv|abx†zhuub}{gu†Ž•{t€vq€{}m€ZWupv…ˆ€zm‰†tylv„…|~y|t‹‚~thtenŠƒlsYh^sdGmmKZaWVUwmbPRtvXPVX^aq„o\`cmdd^ocT]rFBe_]fg][{bQU\u[[gkaVj_`nefkqhpvxŽtkŽu~vx~wƒ{s}ƒˆ‡ƒor€tqu~…‰Š{w€xƒ{|…‡x‡|}~„€{~svyŒŽ ‰z‰vtƒx^}…˜‹x†ƒt…†„w‰zbnl[b[[aVisc`[gnof‡qaqfW]cl|Ê·¹¡jmmŠlq„q|ƒ‰~z„yxsyuu{jlvc„u’‚wof^}‚z‹Šer‚kjqcXmz…›ˆ‚s—”x}o‰r„‹‰s˜‘‰†‹ƒ{y}ppo|fhqbmxqjkqx}|z]ey€xivxf‚wgt‡ŒŽ”}r‡jo~yo}^Ysnu‹|‚opŠ€qwix€‚€‚x~s{u‡}{sgsan‹kqWi]v[GmjLVT^SU{kaOTurPQTW^bt…i]`ljfcZoaXcpG@g\`e^\V{^NVepY[jh]Wh`^rfkgqgpsw†xn•Štzx~yƒ‡€uq†…Žƒpp{xvuz†…‡Œ†z|t‹~}†„„‡~~}‡|xvxx‘“ŸŒ}‹muxd‚†•…s‘Šo……zƒtcnjY_[\]Tgrd`XdqrfsbkeW[`jw¾®{ ¶nbs†hs{qy„z}‹~wwrvo{vejo`‡uŽsjb^xy‹„fqhkkZVow‰£„q™“ryv„o‚ƒ“‰t–ŠŽˆ…‰…}xtqnhx_jl_mvjgjkywzvZg}|xes~n„teu…†–pŒgkz„unub]q}lu}Œ{‚fv‡}nqivy€s~m{|‚{yqflbm‰}lmUi_vUJijNQNhMX{haNUvkLQTU_fuƒf^`qhgbWi]\khJDjYadVYUyYMVmjY]kd\Yec^tfldqgrpuxp™…v~w|…‡}ur‚ˆ€•ƒnsy{zsr…‡‰ˆƒy~u~|„ŠŽ„‚ƒz~‹ƒ{v{wwš—z‰‚†iv}{lƒ„’qŽp…‚~pflgX][\[Sdpd^WbruiupeebW\\h€por€s‰ddx~itusrƒw€ƒyvsunkzqbgkg†tƒnf]_}p{‰imygjdUWro¦|„{v–‘t}s}{o}|’‡xš}ˆ†ƒ†ƒ}uoqlgt\lg^ltdgeizo{rYhwuhpx‚vbw…‹|”oŒjm{‚qgsfanzgsx‹|~bwƒwjlrv{q{zt~g€ywodfbn…{ljUhboRJhjOKNoG]{faMUtcJNSWajv~e]gsif`VcWbp]LKjXcaUTUsVLXudY^k`\Zce_vgmbpisor~ut™‚w€w†…z|t‚„~—…nrt|ztq„…€z‹vt|•Ž€…„|~Œ†{~€v{£¥Šyˆ…„ku|zuƒ€‹zn„sy„}ƒunjheV][ZZSbmd[Xas{ihmi`bW_[j€jkp€gk`hyxjstsmƒ€z|uunzhjyj_enhv„geXbwj~‡{ojpgf]TXogŽ¨wz|‘Žzvqptwzy–t…ƒ€…ˆvjquggn[lc]mr_gajxh|m[n‚rtjo~zwaw…„x…sˆroy€rcqi\qxdrt‰|yct€qhjzurmyxvyd„|ywqddcn||jjThaeSJkgOGQkE`xfaMSq]JMTZekv{e_mqid]V`VnnWKShWe^XMUlTJ\y_[^k]][ce`yhl`oounpwuz˜}w€z€€‡†zxy‚~“„qttyvt„ˆ‘}€|ks•€{‚Ÿ…~‡}€†‚€Š{v„«Ÿzˆ‡ƒkryu€~€tn†n|€sŠ€jomddX_ZYZTajg[Z^t‚i^ml\aW\\lert}ii\kvugsvql„{}|xurlygixf]esgzw“ccTepg‚…wwgij`WVYgc§n~w€‹Ž{qr~hzp{Ž}xq„}†ndurdgg\ja\oo\g_mudzh]t€orkr|~uvbt…‹{ˆ‡€xruuapm[rtcqs…|ues€mam{pkj{yvsf†v{{vqebems}ikSg]\TKqbPFVaGbvfaKToWJLXXgkuzdenqfdZW]XveTJ\bWgWYHWePHbxZ]_l[^\ac^~ij_ntxmpnvƒ—yr€|‰Œ†~uu†y‡Œ|tuu‚yzz‚ŒŽ}~„‰is–zŠ}~…zz|†ˆsq­Œ{{‡}dq‡ys|zuro…l{~lzbpobe]eVYYWcfk_]\r…hXpn[^XZ\l{cpwvmbZlssgtuolƒx~xwnntdite[gufvv’y_]Rffjƒ‚t~bdi\TW]bc¤hxtƒ†‘ymp{iyn|†|v‰s€x|xhdvl`f_^i^\skYe]oobze[w|knnoxysudsƒ’~‡ƒ‰{wpr~sbxd\ppbqr‚}tgr€e^nwiehz|uno‚ut}trb_fnn|dhSgXWSLv_PJYXHbtcaITmSJMZWilq{bmlscbZZ[aw\SLc]XiSWGY`MFiuX^`l[[_bb\„iganxylojvxmƒ~€“ˆ„vsˆtŒ†trvu‚w|}~Œ€~“~pw•ƒ|™’y€€xz~€tˆƒtp˜ z{‰”xcu‡xswtkto~kx|p‘r^po`gblTZZWhcmf\[q‰eSrn[ZXX`lvciuji^Ymsplsssi„|~~{vonldiqc[krdtvŽs[WSear€r‚]bc]SZ`\c‘Ÿeqq…„‘tll{npq{}}qx€szzzceuh]bY`gZ^vhWb]ohaw`[{vijrnxsruhq‚•ƒ‡~„vsjq}nfwX]lncrsztgo~[`prb`kr~mmusqxkpa\elly`fReTVQOtZQOXQHcsb`FUkPIPZUkkk|emoqb[ZXYlqWRPfWVhSTFZ\NHqtX_cmcX``a]‹jcdmyxkpiuy†{kƒ}„š|‚„y|‡n‡rovz}t‚|‹‚‚—tx“…Ÿ‰u€t‚q‡‚uo¡–s{†‹†zewŠnmznfxpzksvrŒk^tnagekR][UgalkZ\pŒdOon]VXUgithbtee]Ymtmoutxj†|{‡vsddkna\nmcsx‡kZTVcdx}}q†]c_cSZ_Yb••cnpƒ…Štkh|pftxu}lzuvoz~u^erc[]VacXateU_`mdaq]]~phisqtpuvkm„“‰{…qsgp~qsoT\gkfqtwscmvVbrl[_pg~fmw~ssskm`Zdjjv^fScTUPSlVPVSOGdr_aEXiOHWTVmhd|ikxkbW]U[tdSRWhQXeTSHZZPMwvZ_eliYb`^^Žnafkyunoivvlƒ€}‡—{€‡‰~k“ˆrgt€{u‚}ˆŽ‹“r|Š‘…‡Ÿ†{†Œs†s~‚vn¤‹r‹vwlzŒ`d{pfzsxlmqv‚gd{lcfghS_^Ug_ln[^mhNim`TVSngtkexdd\Xoslqzwrl‡{v›zykaelm^`ojepy~gZVX`lx|{p„_b^gVX_Wc›ˆbkp‡}xlkyn\wsm{iutoo{€rXim^X\UabWdpcS^ahablZ`~kfksvomwwli…Œ‰{ˆmrgq}nsndZaiiot‚ts^imSeqeUcoc{drw|wkpmk`Yaght\dU`URNWdRN[OOGdo]bFYiMI_KXmd`xin~d`U_T]u\TS`fN]aUSJ\YPYtu]_elhXca[^qcgjxqsnhvtzƒr‚ƒzˆŽ~|‰‡ynŠuls‚t‡…†’„•y}Œ‡‘›„€|Œ…s€stxro““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~}~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’’’’’’’’’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’““““““““’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ>.1111/o‡„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDARÌÚØØØØ܋innnnqI,00//,I…ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ-h…‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR455552FØêççççë‹bggggl<;ƒ€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}z{z|}{}~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‘‰ˆˆˆˆˆ‡Œ‡‡‡‡ˆ‡‰’“’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†…………†“”””””•‰ŠŠŠ‰Š†‚‚‚‚‚‚„ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|y{z{|{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘“““““Ž’’‘‰‡ŽŠ’’“ŽŽŽŽ…Š‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽ‹‹‹‹‹ŒŒŽŽŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}|}}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…‡Š‰‰Žˆ‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰„Šˆ‰‹ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰Œ‰‘‰‚ˆŒˆ‡ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}|}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹ŒŽˆˆŒˆ†ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz||||}~~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒŽŒ‹‹ŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzzz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{y{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰‡‚‡ŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†…………………„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰ŽŠ‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{}~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““””””“””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••””•“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””’’“““““’’“”““““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘’’““’““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’‘‘‘‘’’“’“’‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvy}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡ƒ‹Šˆ‰‰†……„„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxy}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzop{xy{|{xw{xuwttvttvwuqrqnprpghklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkigfgggihgmgjghehgccbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__`c_\_]`]^Z^]YY^ba^^ZY_\XWSNMLKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{yvwxxz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSSPMJMNPROMPQQQQRVVQQQTPPNNOLJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTttuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMOPPRQPNNONONOOPQONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKLFDFJKKKHJLLLOMLLNOOOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEBA@@CCDEACEHKOKIIJHGJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:<>><ED>?EA?@A@DEGGGGBDDEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrquxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;899;;:@:;><;;<<HL==AA?BC=ADDFBFFDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNMMMNONNMKKNNNMNNLTnpprtusqrwyy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;::;89:87:<978;;>=;;:8:@@AB?A?CFDBCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqtsusqsxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<979::989::78:9:;;8789;:8<;=@A@=;;><==@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyy{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>=;=<>?=<=;:<===<<<<;<:;<>=>?@A@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmqquuuusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCC@><=?@??=;>=>CE??@=;===<;:=>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVppqssttuy{{{}~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???CED?=;<@>:;::97:<9==@=:<;;<;8:;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pqrrrtuvz{}}}~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC??AAABA@=<=;>=:::<:8:88:;=??<;;<;:;;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€{NIKKLLLEILNM<?<<=>@@AA;BCBC@???@=??><>@?===?>=>CD?;<=>@==>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGHEDCFEFFGED@AGGFCFDGHJGC>Hlpppqtuvy||}||~~}~~~~~~~~€€€€€€€€€€€€€€}QHKMMMKJKLOQ@?>>AA@@AGABDCDA?@@@?=@><=??@@@C@@?@@>=<=@EABBFHC=<@DCAA?>=@A>>>?<>@DGE@>@A?@CFECBBC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{||}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@A@>:><?=<:=<@BBE@??Na_J@CEIIIIMMKECFGHEGEEEDDCA?@>>BFJJGDEFFFJNNKJIGGHKLJGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@DED?<ADEC@=HDADDDCWu†‰Š~XGHJLLMOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHFHIHGFEFFFDFHGEEHHFHGHFQnnpqrvvy{{{z}}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCAACFJHIFHHJHFA@_hDBAUt‡‰‡‡†‡‚WILMLMNLJGGGGDGGGGFHFHECDDFEDDHHCCCGJJKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrswwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLKJKLKLHT_hq{WNl„‡†††‡‡‡‡|PKLKHGFFDECC@ACCCCFFEB@>>@AA@BD?>?DFHDEGIKIIGHIGIIJJIHFJJJJIJIJJJFILLJJKKfopssuvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKKKKLL`Xg„†„~y†…„„†††‡‡†ŠuIIFB??@???<<<>::<AA@><998<<=;>;9;?ABAACCC@ABEDBCFHIHHHLMLGIJMMNMJJKKJLMSloqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHGIHKLOmyƒ„ƒ€„„„……†‡ˆˆˆ‰‰ŒŽfBB=88::9878896479;<:8567789787689;;<>@;999==>;;=ADEHJMLLGIHORQPPNLMMOQ]oprtsuxz|{||~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@BFHKHPu‚€‚‚‚ƒƒƒ„†‰Š‹‹‹Š‰Š‹Œ‰T;8656766645763468:876565677778:77789;7689989876:<@GFIFIFEFOSRSSROPPRTepqsttwy{|{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:<DBDEMv‚ƒƒ‚ƒ…‰ŠŠ‰‰ŠŠŠŠ‹‰‰ŠH676468874578467699766765:::::<898977779::8878588;A=>>BA?AKLOQPQOOPQWkrrttuwz{{{}}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897:A9<DNx‚‚ƒƒ„„„†‰ŠŠˆ‡‡ˆ‰ŠŠŒŠ‰‰Œz>:88;<=>9:;<89;9:;:99;:9===?;;;=:>;9;;<;<<:;<8::;:999<?<=ABDIJMKJKLWorsutvx{{{|{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<:89989999:>=@@O‚ƒ„„††‡‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>BCEEAAAB>@B@@?=>>@?>?@?@==?B?AA?A?=@@@>?A<><;:;:9;?=;;==AACABCAXqqtttvy{{|}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::<<:;;<;=>AA?bƒƒ…„…„†‰‰ˆ‡†††‡ˆ‰Š‹‹ŠŠŠ‹Š‹^>DGIKJIFGGDFHGEC@@CECB@BCB?@DHECEDFEAFEFDFFD@B>=@>=?@>???>?>>:;=<`qrttuwzzz}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>>??<@>A@DAMƒ„…†††ˆ‰ˆˆ‡†††‡‰ŠŠ‹ŒŒŒ‹ŠŠˆWGLLMKNJIKHIJJIECDFGFDCEFDBHIKHGGFHGEKIKIKKJCFCCDBAACBDCCDDCA=;=@hpsttvwzx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLK@BBA97<>;<:=??A=@@DCGBj…‚……‡‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹‹ŠŒPMPMKNKJLIIJHKGEGHHIEEHFFELLMIJGGHIJNMNLLNKHFGGEECFFFFDEHHFCA?@Llptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?FGG=<@@87<;;<9>@>??ABEDKV~ƒ„„…†‡‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒ‹ŠqMQOMLLKLJIHFJJEJHGKJHJGGGKLNLLHHIJMPNPNMOKIGIJHIDIHHFFGGIFCBACUnquvwy{xyzz||}~~~~}~}~~~~~€€€€€€€€€€€€€€TDAABGGB?8?@8:;8<=;=A=>?ADEFNn„ƒ„„……†‡ˆˆˆˆˆ‡†ˆˆˆˆˆ‰ŒŒ‹ŒŒ‹‹‹‹‹^RRPMNMKJGFCGJGLJGKOLKJJMMLOPNHIKLOQQPQOOJIJJLJLFGHGEGIFEEB@BB\prwxyzyyyzz{{~~~~~}}}}~~~~€€€€€€€€€€€€€€€UECEEGGED;?A;=<9?=>@BGF?DFDHMu†ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹‹ŒŒŒŒ‹‹|WVRRTROLKJEEFKONOWVQPOQSRNSTOMSLPSUWRSRPLKMMMKNGGJFFHJDDEEBDCcquyyzzz{z{z{|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?==B>BCFVMCJKHLOy†ƒ……„„‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŽ‹‹‹gVVkaERQQPJ;;QSR`u]UVTVYYSYXRZfPUWZ]RTWQPNRPPPQKKKGHIHEFIIIHIjsvyyzyz{{|z{|}|}~}}}}}}~€€€€€€€€€~~THJIIGGFE??A@EBCFEDELXRLQQPRSz†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ}aŠ‹‹†l[dU:XXXSP?@VUY\d`VYbr^]W]ZVEQYZ\Y_TYgRUVXTTVSOOMJLJIILMKOMSotvxyxwzzz{z{|}|~~}~}}}~}~€€€€€€€€€€~~~~VJJIHGFDDBA?HMIMPKIKPTSRVWVWVv…„…………†‡ˆ‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~Œ‰Š‹ynpXZ[ZRSRWVTZZuƒYU}a\X]^WIV]][[_YHYXY\]XXYWRQMPQMMOSQQURassvwwvxyxz{{|}}}~}~}}}~~€€€€€€€€€€€xy}YMKJIIFBD@A:PQQWXPPOQSTSWWWXXm‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡ƒŠ~fYY\YSVTWRQWVc–€QerXZW_hP`fZ[X\hbGOZig\[\]]WSNSPPQVVVVYZosuwvvtwxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SOOMKJEC?@;PPZZ[SSQORRQURUSV_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PVXTRTRQQLOMKfyZ]TYUV]ZLTZTST^ZXWWWzkXZ\\^SPPPINOWVX[Zdqtvvttvxyy{{||}}~}~}~}}~€€€€~~zxwvsu{€€tk~~kry^\VUSROKFCDAM^ƒlVRSNOQOQVRSRRTcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ymqVIKNNKMKHJDFHEC>ScURPQNKRTQMOYQMNQSUUMQSRPNLLHCIHRSTZ]mrvvussw{z{{{}{}}}~}}}~}~€}}~~€~{vsw}~~du}iqt_d]^[YUQLILIal’tPQSNQRQR[RSRQRUUbs{|€‚}{{€ƒ‚…†‡‚†††„†…†u_]KC>CCCCB?DPCD@C>BHGV@INMG]iQHFOFDEFHGHBCHGHJGDBAC@NPMRdtuvustuz|z{{{|}}|{~}}}~~€€€||}€€€}vt{mh|gnqfieeb\XSQPURsWe[OONLQSQUYSUQQTROV`klsvz{xyurnstsyx~~ƒ€ƒ‚‚€‚€‚kLG>>:;>@??>>jPJaEFHIEB?HMMGMQUJBE?><=<==?=?ACB??<=B>JMFUouvvstvx{|{}{|}}}}|~}}|~~€{ywxwvvx{~€~}{xv|uaxglpjljif`[QQZ\Y^IJPQNKLQRQTVTWQQWVPX[b]agmmlokh`nrjmlqu{z}zxz||xwxdB@@A=:BCBACA[\N{NOONKLMOOPLKLWNIG@B<977599=;;;8989?;AG>\tuvvuvwy|||}|||}~~|}}}}~}xuwz{zwyxuw{|yxuywcqhipmnmmhf^OP^\ZIGPRQOMPQNQRSVXSRYTNYZ[WY\__`e`]^qwk^`gkwooljonnlfbYGFFHBAFIEEFCLQOaWRXQPSSRU[OOQVPMICF>:96586979:365795<B=ftuwxwyy{}}||{|}}~~{}~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZWMKTTSPQUOLRSTWXTTXQLWYYVXXVXY]WWXhsk]V`tkaa_]d`_^YUPMONLIGJKIHFCPOSZWTTNQSYS\eUOSTQNKIHC?A9988978847578598Gnruxyz{{}~}}|{}|}~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPWVVSTVOOUVWXYSUTLKSUUUUWPTUWTUR]n^RNY`[VY;DUWT[fJLPRROMMNNNLJFPPUYSTNJNOTST\VRUSSOMLIHHF??=:787659967665Wqqtxyz{|}~}~||}|~}}y}}|~~~}||}}~}|rvqxxruuqqnppopuvtnjddjppqrpnfedc\^RTZVWTSVTRXXYYYRUOJGOPOOMRJOPPPNNOTLMIPPSTU2<XMIAQ=c`QSQPNPQPNNMPNTRPRLILKOQPQRSTQSOLMKLLHCBA=:9876;B4566;eprvxy{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqpuuvcjgeWhtrrqniihpVVTUXUVURWVUZYXWUQSFEAFGGHFJDHJHGEHLHKIGLMPMG/E_R>3@>joaRRQ@FTQOPPQNQOPOLJLLOPNNPQQNPOJMMMKGEEDB;==<9=G6677Dnquwz|{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknbePSTRSUOWVVYYVQQQO@>;=?@BAC@BEDA@GHGHFFHJMLDGCORC8ENS]gSQSAGUPORQPMMNLJLKLNOOQMOOMHLKIKKLKGFFED<AA>;@E;<89Tqsuy{{{|||{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLONMQSLTUTWWULLKH=987;?A>==A@B=>EHFDFFIGJJ@FAA@FHEJOHQRa\QPRNSOOPLLOMKMLMON[VKMQOGIHDIJLLKFFFD?CC>=BG?B>Adqtw{z{{|{zzw|wy~~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCE=9879?B?;>A@@>ADIECHGIGIEBB?><CBAGIDMOaePMONWKLNKLMMLLKNNSdNJLRIIIEAHJLMNKGIFBBB@?EFEHDLopwzzy{{z|zwsxtx||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGLMIMPMPOGKE?B=999:?B?<ABAADDGKFDIIGGHCC?B??@A>CECKNQTKJIMTFIIJLJKKIJLMOPRPKGCLGCCJJLMOMIJIGCCCDIJMLIZsnxyxz{{y|vrpurtyyvxjqojllnttmsu{stxronqovsnporpopstyjN`gsjt|ygosqiqheqHKCFHHGJKIJLDGB=>=:::;AB?=BBCCHFJLJEIIFGGCC;A@B>@@CECIMOGHKFHKDHIKMHJLHIJLJM]RIHDNGBEKKNMPNKMJKFGGJMNQNLcnjwvv{x{z}qmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoijthdpFKCFEGDEEFEGCC@=<=:;::@D@>BCEEIFJJLFIIGFFCB;BCC>@CCCDGLNHKNHDHEILNMGILGFFIILNKJHEOICGMMNMPNOOMLIHIOSQRNRfgfrosxu{z|lhjoekpmsqfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGICEFEBBAE@DB>?>:;;=;=?CA?ACFGJGJILHGGGFEC?=EEB>ACCCDGIIGMPIFFGKNOKFHIFEDDIIHKIFHPKDJMLPNONOPNJJHMRUUROWdaamgqrosyzgehhcilgqlflmgiklsmpvutpnvrosrsutqssutsuvvvyvutvlkuumrvqlnlerMGEEGCA@AD<BA>A=::=?;>?@B?@BEGJFJGIGFFFEDCAAFFCBBBDEEGGHFLPLIOJJLKIFHEFEDCIHHKJGKRMCOONQPOONOOKKKPUWVUSY`_]ianinhrsbeffdihfnifmmhkkmriqvusqmvnoqrswsrstuvvvvwvwvvtwuksunutsprkksMFGEGAB@CD<AA@C<8:=>:?=?B?@@DFHEHFFHFEECCDBDIFCGEAEGEFFGEJMKHQMJKHHIEFHHECIIJKMKPSNDRSQQRNONNPMLNSWVWXVX^Z]d`hbjigk_defcgggkggkmkmlpqgttursnvoqprtxqssuvu‚‘yvvtxuuwxnouorsuqqipzMGGGHBBBEE<@CBD<7:=>:>:@B>??CEFDFDDGECECDEFFJEEIGBGHFGFECFJJGMKLKHJKFIHJHEKKLLNORTOITUTQTPQMNQNMQWZVZYWZ^ZXa```_hec`deggjhhjfhnllomqpiuuxrrpupppruvpusuvu{~}xvtwvvvwplupmsunossyMHHGIDACHE<@EBD<8:>>=<<BB<@>ABFCEBBHCCDEFFGGIFGKHCIHGIGFDHKIGKIMKJKLHLJMKINLNNORUVOLVVTQTRRLOQPOTYZY\ZZ\__^`c^\ackb`dghr…hgjfjnnponsqjtuxrsstrnpqvrquruus~yŽ}uuvvvvxriuqkrtlqwquKIKHJEBDGE<@GDD@9<>@?>?CB<@>BAFCEDCHDFDFFHHFHGIKJEJHHKHFFLHHHJHMLLLLIMKMNMOLPPQUVWOKVVUSSRQLORRQV[[]^[]^``a`ae]d`fg`ehjcssfjhglprqossnswwpuvtsmoruorspurvrtwuuuwvuwsgtrkqrkrwowIJKIKGBDDE<@FDDB;??A@@@DA@B?ACHBEDFHEIEFEIHFIHJLHHJJIKJFJKHIJJGKKMLJJMLMNNOLOPRUWVMNTVUSRQPMNTSRW[^^_\^``aaa`cdebdicdijgv‹lkihmosqpqpprywruutsmmssmqsotutspswtuuwvuuueqskpqjrvpwJLKKLGCCAD<?EEEC=AACBBCEACDAAEGCGGHFEIFCGJGGJFILHIJMKMLGKIHKKNQKRQLSMKNMNPPPTOWXX[NSQW\ZSVPNTUTTXZ_bb_da_`b_`fbacinicihhmxvmhimosrpqrrrvtsusssnksqmprotvrrquvuswywutucmtkopjqtpwLMLLLGEA@D>>DEFC?CAECDFCCEGCBHEBHIIHHKFDKJGHJHIKGJJNKNKILHJMKZfJd\KlRHOM_nUls[qpbwcRPbvuhucav`Xnqbdvinzf\lt`lkU_wvijhhfglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqsqyKNJKJFB?@B?=DEFDCCBEEDFBFFGDDKDDJLLJLMGGNIHJKGKJIKKNLMLLLILLL[sbdp^llUMNer]gfqlntgpi_aYnmbppbkjjgoqtetno\ougqMKryvkbakeelxmkvlnpsrprqpqrqrrrtrmmsnnoprutqsstuuutwxvutbmukpplrrqzKLIIGED?AB?=BEGBFCEDEEDBHHGDEKHGKMMJMLFJNHJKJIKJJIJLMNMMMKNMM[roonpplkNPQlXNibtrpamov\YlP[mmZqmkomxxtsip\`slqjUuyxoc^kfbgppjioppsspqppqrrqqrrtlmrmmnorutqtrtuutuuzvutenukpolsrryJKGHFEEBAB=??EGBGDIEEDBFIHHEGKJGMMNKMNGLNIMKHJMIKIJJNONNMLNML\hdu]lqWlNOQnUZk^klvaldtTecNlYl\tpkilxjwuhp]_skhWbcw|oc`ghacityknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtvIMGIEEDCAB<B@BFCGFKGECCHKHHFJLKFMKLRRLGMMHNJIHNHJJHHNONNLJMMJZsppoqqmlOQSoYskgooqqomt^nXat_nopoqroousttj[]tcwxrjnzhaacfabjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyytukoumtonssvtHKHJCEEE@@>CCAFCHIMHFCFJLIGFKMLFOJKWRKGKJJNIIJLIKJIHKMMMLIKKKSkbZi^_jcrrZ_Zko`eeUk_c[abQ`mh\j\niidZoedp]Z\k[mqcpsldgcdg``knppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunwqrutwrHHFIDEDFA@AEDCGBHJLGFDGKLIEFJNKIOIL[QJFHHKMIHJJKKIHJGLKKKGHJJLLLKIKLNT[]TPUMQPNOOURPOQOOQJJNPQdqiTYV[[\UY[]X]\\cfaafbcf_^fkmhmtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyyxuvqruovrtsuusGCEGFFAEC?CGDEGCIKLHFDGKLHDGHPKLOKLWMIFEHIJHIKHLJIFHHJGGIEFKHIKNLIO\W^O\\`^OXYS\\b^MYZMXaRKYaZS`d]bX[ddVVX\YZX\VY\^c_daa_ehkgmttqqtpqr†††…†………†††„}rkiorssstxyyxyxwxtqxrxsqrurtOBCDLMBCDBDIEGGFKJKHEFJJJFEHHPJLMJMRIHEAHFJIKKILJIGEJHEFGEEJGBIMJKT_Y`X`a[`UXYT^^Z_RY\P^\YN_\^S[^c_Z]`c_Y_b[`^[TYXZ_^dbbacfiekrpoppnow††……†‚{€……††…†…uqprrsvyyzyyxxxvryvxrqxvtvaSJJMIDBBCFGEGGIJJIIDGKJKFFIINJNLHLNGHF>GGLIKKJKKIGEIEDDEBFJD?IKHN[cY^^a_RTSW_`\]Y^QY\MV_WKQY[Q[_aa]^ca`bbbcceZRXVV\[^c`__cebhommllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxXQJFCGEBEGHFGHIFGJGHFHKIKDDJJMMLLHJJHJG?GFNJKKMKKKIGHED@DAHIA>HIFO]aZ[d]_TQRX]\\\_ZKW\LR\YIM^QQ]_accccb\dcbdcfXQVUS\X[a_^_aa_dlkmjklnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMB@IFCFKIFFGIGGJFFFILJNEDJJLNJLIKJHIGBHHQMKKOMKKIHHED?EBHHA@FECT]Y^X_X_[]UXXP]]QKJV^X^[]VZaRR__bb``bb`cbbddbXORRS\S\^]^^__`dhgljnnp{{|~{€‚ƒ„………………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKBAGFDGMRHDRKFHHHDFKIMPEGIJKNLLILKIIGDHKQOMLPLLKKIICEAECHFAAFDAVUE\T^SV`XNTUNZ[MJKT`a[_X_^b]OYb\``_bcb]bbW__TPOQRYS^\\]^_`bffelfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDFFGDIRcQDW_IGGHDFMJPPFIIJKNLLKMKJJGEINQQNOOMNMNHKADACDFDBACD@LHBLLPOOMFMFFHIHGLLMOPILOPPSPLQSRUZYWYXXdVOSTPPONQUT\YY[^^aaefchdklqsszy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKM^MGHYMGHJHGNLQQIKJKKNMUNOKKLGGKOSSOPONOOOHKF`ED_LDfcCL[H^[smOMVmYLCP_TlWgJ]WU^DMQULMSVQRTXWTXUT\TPfZhhdYTkTXWU[\\``abbb`gignlhrz|}~„„„„ƒƒƒ}}zr{z{‚€ƒ„„……„…ƒƒ~z{KIEFFHEEKOTJKG`TGJOJIOMRQKMKLORUROOJLMGHMQ[YOPPNOPPJKQQI|YYrsWPmHqnoaVPqqtOBksnqtpSo_[nX]V\XUkhU]VcY`YZ_VUWituu_av_Yb\\f[_aaab^`bgmpl`pwtx‚ƒ„‚}~€vxzmv~tx~€|~€‚„|€ƒz~wwMIEHMMBDLLGJLFRVLLOHLRXWQNOOLQTNOQPKKNGMPS[ZTQROPPQKIZx]TxdhYRSPvgtlpbnfkRrNLwmjrpsrqrpop€]fzuxqqzq~r}ku}bRg|essoss|}p~yor_``bb[a`hknkblfgmw~€ƒ~{xw€tvzhr~nt|~wx{~€ƒx|u|||ssNKF`]GAEMMHKKHJQOMNJNW^YULQSNYYLSSRNLOIQRTYWWQTPPQSLHgxlcxqmZKLTypumubnvPdeIevqmwo€jfxxiXrRi{mijzz}lxzpgoXuujvup€ash}ilx|o___cb\_defijdgbcdllppstsssyqrxbltgry{sruy~svzn|}yxrnMJRtNCBEPPIKLJLQOOOMPZ`ZXKTWPa^RVQYSMPJSTUXWWPUPONSJKrouuquqdhaVnLqp^GhyWvTKhx}x`y{sna^modSgrunmypwlvstqlm\s}zkmy|lum|kpvux^__b^]_edighee^bbiiijknokqnmjpacfdowxompsynqpj{ztromKKZVHGEGRPKLNKLQQPPPQW\YUNVYUfXRRY^TMNJTTVWYWOSOONQIRmHiwK`dvuUWlNnl{rajgvUKWkh}lmlx`[pz{_`zscroxqhd|ir{]TKl_vukiu{{m~xk|p]^^b[^bdegeeebZccikkrsrwgmihdg`alagsrlhmmr|kmhk{tmmkmOGJKHJHHRQMOPMLSSROSRWRVTPWZVVTTTa`QONKTSSQVVOOMNOQJHQNPULKKRSRRROVUQQORRXXQNPUTXXX[[USSW[WXW[ORTWWXQ]XV]USOXRVWWXZ`[gr^[[[]]_cZ_ccefdccbZccgffmnmuffgc`f_]g`dlhfgkhpzhggkujhgilPIKKLMKJTRMRQPLVUTPTUXUZURZ]VUTWUYXPOLNWTPNUSNPNLQPKJQQKQMJKOQTRQQSRIIMNOQRQQQTVRXW\WSSQQUUVTZQNSQWUTYVTYUSRUSTUXYX^Z_a]\[Z]]`c\]bcdgeddaY`acabhhincad^_c]Zd\bma^ffgmsdihkkeddfhQJKKNOLMTQOTQQMXWUTVXWWZVT\`VWVYUXTQPKOXSPNUQNRNLSPMNUSNQNMNQSPTQSTTNLNOQTTRRQVWUYZ[YSURTXWWY[SOSTWUTYUVYTRRWUVX\Z[`]VY_]^]\]`a^[bbchfedbX``b]`hefda^_]]^ZZ_Z_g`^^]chkahfhfd`bdbPKMLPQLOTPPTQOQZYXWYZZXYV]jdVXYZWVTTOKOVTPOTPPQNMQQORXSQQOMOSUNWQTTUONNQTUUTTRTXVZ]\ZVVQRWXV[\VPSUUUVXTWWTRRXVV[_[^`_V_]^`\\``__ZbbdhhedbYb`b^^fdc`b]\\\\YZ[X[a[^]]_b__bddbd__`\PMNNRQMRSPSTQOU\ZZW[[\YZ[dqmhd_[YVVXRMMVSMNROQROMPSRUZUSPPLPWUQVRSSXMOPQTXUUUSUYX[^]\[VROUVU[[VQSVUVXTSXZTSQYWW]_[`_`Vb\`a]`b_\`]cachief`Zc`a__ee_`c[Z\[\ZZYYW\Z\[`^`[^^a`_c\Y`ZQNONVQPUSPUTSPW\\\Y^\_W\^jpwy€c\[VVYRNOWSNQQPRTRLQTSY[WUORNSXUSRTRRZOQSSV[UVVTVZX]^\\^VSNTVV[[UQSTVXXRSY\TRR\XZ]^]aa`Wb[cb^ac_\bab_dgidg^\e`a`acd_b_YZ_[\[XXYWWZZZa\][]\\Z]`W[[ZPOOOYPUUSRWRTPZ]^]\`\`U\]hjr}slh\UYWQOR[SRQTRTUTKRVUZZZSOSQUUUSNUQRZRTUTX]WXXSX\X^]YZ]UUNVVW^ZXQUTXXXSVY\TRV]Y]]a^cc_Y`[eb_dd^^cca^efief]^daaabcd_b^X[_[\[XXXXW[Z[`][[\[XZ[^V^Y]POORZP[UUWVTTT^^`_^b\`U]^bkyum}lZUZVQQT\TTTUTVYWLRZV\Z\RPUSWUUSOWQSWSWUV[]X[YUZ^X_^Y\YRWRYXY_YYSUUZYYUWY\UTZ]\^`a`ed]^]]eabfd^_dc`\gdhfdb_da_a`bb_`^WY^Z\\ZYYWV]Z]^[Z[\[WY\]VXW]SOPWYP]UVYWWUX_`aa`c]`U]^beev‚{hXYZTVTV\XWWVVW]XOU\Y^]]TSXRWUSRSXRSVTXXX]^X][U^_X__X\VQYUYZZaX\UVWZZZXYZZWV]^_^cbbee]b\`fbefd_`dba[fbhfcfaf__abaa`_^VU]Y[\[Y\YY][[[XXY[YZZ]_]TY]UNSZWT\UVWYWV\`aacac__V[`da_zuohZ\ZVXVX[ZY[YXY`VOT][`a\UUYPTVTRVVRTUW[[\_^Z_\V__Z]^Y^VSYXYZ]aY^VWZ[Z[[[YZXY__``dcdeebdZbfcgfe^ab`c^cciedg_g^bbcaa`^_XTZZZ[[X\XX\[Z[WWZXW\[\`]V]]SOVZVVZVYUXWX^`badada^YYadb`kfh^\][WWYZ\\\_[Y[bVSW^]ac\SVYPVUUUVVSVTX]]_``]a]W`^[^\[^XVXX[Z__Z^XX\\]]^[Z\WZ_a^`eddfffbYcfehgd^c`_ec]fideh_g^cbcaa`__[XY[YZZXZXW[[Z[WXZTY]\Z`\U^bMRWYVWZY[\YWY^`baeada]^Yacb_a`a_]]]XW[[]]__\Z]cXYW\`cd_RYYPWVWXWVVWV]]^aba_b^Ya]]^Y]^YXUW[[`^\_YY]]^^`\ZZY[_a_bedefggbZdfgigc_c^`feZiicficf_bbca``_]]ZX[YYXXZYWZ[ZYWXVU[]]]``bbxKWW\YW]\\]ZW\]_`bdbca]`Xbcb`cac^\]\XW[]_]`_][`d\\WZbecaR\YOXVY[YYWZZ`^abc`ac_\b]_][_^YYTX]]__^_[Z^^`bb\\W[]`bbcedgfegd]efhifcab\cg`\iichife`baca_`_]]\Y\YXWXYYW\[ZWVXPXZ]acffrkJYW][Z_]\^\Y][^_bcbaa]b[bda_cbb]\[ZWXjq`\`_]\ac_]XYcedbT_ZQYW\]\[Y[[c`ccc`bda`c^`\^__ZXV[_]\aa_][`abeb^\S\_`cddfegfefe_ffhhgdd`[fg^ahhbhhfc`b`cb___]][Z[YXXXVZV\ZZVVULXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡…‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vvvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{{{{{{{{{{{{{z{{{{{{{{||||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vvuvvvvuvvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{{{|{{{{|{zz{zzzz{{{{{||||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||vˆ‹‹‹‹‹‹}}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰Š‡sqrrrqo©Á¾¾¾¾Á¢ŠŒŒŒŒ‰~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}vŒƒ~~†“y1333332j‚€€€{­éääääèʉŒŒŒŒŒ‰roooool²ÐÌÌÌÌЪ’‹}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒƒ„ƒ‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}vxxxxxxxwwwwwwwxyyyzzzwopppppprrrrrrrwzyyzzz~ƒƒƒƒƒ„|||||||zzzzzyyƒ‚‚‚‚ƒ€||}}}}}|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚‚‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vvvuuuxvvvz{x{xwvvxyxyz~|yyxxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{{{{{{{{zyyyyyz{{{{||{|||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwww|{{|y|{xwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwwy~{y{x|zxxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z|yww{~{y{w|yxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚ƒ‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzzx{{y|x|xxxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyywxzyyyyxxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyyyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegefgbedebg[be`v||{|||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}|}}}|||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚€€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrstuttssrrsrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqstsssrqqppnnnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqqrssssqpqpoonnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrqrrssrrqppoopoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpppqrrqqqpopooppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqpqqqqqqpooppppppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopopppppppppŠŒˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqqqqqpppppppppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsquŒ‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqqqpqqqqpqpqpqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹‰ƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrqqqqqrqqqrrqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrssrrrrrstrrsrsssssssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz|~~|vvwwvuxzxxxxwwwvx|yy|zyy|{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†ŠŒˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~|{{z{|{}|{{{{{{zyxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}|||~|}~~~~~}}||}ƒ€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€€€€‚€€~~~~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒˆ†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~~€€€~~~~}~~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~~~~€~~~~~~~~~€€€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒƒ‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹Š‹‹‹‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚ƒ‚€€€€€€€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒŽ‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒ„‚„„‚‚‚‡ƒ‚‚€‚‚‚‚ƒ‚‚ƒ‚ƒ‚ƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…ƒ„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒ‚ƒƒ€‚ƒ‚…………††‡†…††‡‡‡†††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒ„ƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠ‡‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„„ƒ‚ƒ…ƒ‚‚„…‡‡‡‡††‡‡‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ’‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒ‚‚„„ƒƒƒ‚‚„…„„……„ƒƒ„……‚„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘“’ŽŽ‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚‚‚‚‚‚‚‚‚‚‚ƒ€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„…„„…„…†’“‘ŽŽŽŽ‰ˆ‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~~€‚€‚‚‚€€€€~€‚€‚ƒƒ€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“’Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€‚ƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚„‚‚ƒ„‚ƒ„…†„‚„‚€‚‚‚„ƒ‚ƒ‚‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘ŽŒ‡…ƒƒƒ‚‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒ‚ƒ‚ƒ……ƒƒƒ„ƒ„ƒƒ„„…„„„‚€‚ƒ‚‚„ƒƒ‚‚„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ……„„ƒƒ‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”““’ŒŒŠ…„„ƒƒ‚‚ƒ‚‚‚‚‚ƒ‚‚€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~€€‚€€€‚‚‚‚‚‚€‚‚‚‚‚‚ƒƒ‚‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†””’”’‹‡„„ƒƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~€€€€€€ƒ€‚„ƒ‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“‘Š†ƒƒƒ„‚‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€€€ƒ‚‚ƒ‚‚‚ƒƒƒ„‚ƒƒƒ‚€€€‚‚‚‚‚‚ƒƒƒƒ‚ƒƒ„‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„„ƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†ƒ„ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„…„‚‚‚ƒ‚‚„‚‚†…ƒ…ƒƒ„„…†…„„…‚}}}~‚„ƒƒƒƒƒ„ƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„„…………„…†…††…………………………††…†††…†††‡†…………ƒ„„„‡““’‘’ŒŠˆ…………‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…ƒ‚ƒ„……†…††‡‡‡†ƒ~~~~~ƒ„ƒƒ„„„„„„„„„„„„………„…„†……†…†††…†……‡……†…††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„ƒƒƒ………„ƒ‡™Œ…~€„…„…†††…………††‡††…†……†‡‡‡ˆ‡‡‡†††‡‡‡†††‡†††…„ƒ„……†„……††‡‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘“’‘‹ˆˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒƒ„ƒƒ‚…†‚€~~~‰€€€……†‡ˆˆ‡‡‡‡ˆ‡ˆ‡ˆˆˆ††‡ˆˆ‰‰‰ˆ‡†‡‡‡ˆˆ†‡†‡‡††…„ƒ„…†…………†††‡‡…†‡†‡†‡‡‡‡‡‡‡‡‡…‡““‘‘‹‡†…†„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡‡…ƒƒ…„ƒƒƒƒŠ†€…€€‚€€~{z€†ˆˆŠŠ‰‰ˆˆ‰‰‰‰Š‹Šˆˆˆ‰Š‹‹ŠŠˆˆ‡ˆˆˆ‡‡ˆˆ‡ˆ†‡†„ƒƒ…‡‡‡†……„„ƒ……„……†„„„………†…†…ƒ‰”“Ž‘ŽŠ†…†…ƒ‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡‡„„…„ƒƒ…„‚…ƒ‚‚‚‚‚‚‚€~|}}}~|{|ƒ‡‰‹‹ŠŠŠˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰‡†††‡…†ˆˆ‰ˆ‡†‡„ƒ‚„ˆˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚‚ƒ‚„ƒ„ƒŽ“’‹ˆ…„†ƒ‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„……„…‘ƒ„ƒƒ‚‚‚ƒ~}~~~~~~}|~}}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡‡‰†ˆ†ˆ‡‡‰ˆ„ƒ„ƒ…„„……†ˆ‡†…ƒ‚‚„…‡†‡††ƒ‚‚ƒ„‚ƒ„„‚‚ƒƒ„ƒ„‘’‘ŽŽ‹‡…††„‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…†ˆ‹Š†„†„‚††ƒ„ƒƒƒƒ‚‚}|}€~~~}|}}|z|„†‡†„ƒƒƒ„………ƒƒ…„„„„„„…„‚‚ƒ‚„„‚ƒƒ…†…„‚‚‚ƒƒ…ƒ„„…„„†ƒƒ„…ƒ‚ƒ‚ƒƒ„…„ˆ’‘Œ‰†„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€}€†ƒƒƒƒ‚‚€}}€€}~~}}}}zzz~ƒ„„‚€‚‚~‚ƒ€‚‚‚‚ƒƒ€€€ƒ‚€€€€€‚‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†Œ“‘Ž‹ˆ……ƒ‚„‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€ƒ‚~~~||€ƒƒ‚ƒƒƒ~}~€€€~}}}}~}|zzz‚‚~€~}€€€€€~}}€~€€€€€€€‚€€‚‚€‚„ƒ†’ŽŠ‡‡†ƒƒ‚‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒ‚ƒ„…€€|}}~}~~€€}~}~ƒƒƒ‚‚}}~€€€~}}}|{{{zzzz€€€~~~|~~€~€€~~~~}|~€~~€€€~€€~€€…’’Ž‹‹‡‰…„ƒ‚‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~~~~€€~~~€‚„ƒ‚€~}~~€€€~}}}}{{|zzyyy{€€~}~~€€~€€‚€|~~~~}|€~€~~€€~€~~~~~}||}…“’Œ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒƒ‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚ƒ‚ƒ„„€€~}}~~~~}}}}}|||{zzyyy}€€€€€€‚‚€~€~~~~~€‚€€€€~€€~~€}~}}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…ƒƒƒƒ…„„„„ƒ‚ƒƒ‚‚‚‚‚~}}}~~€}}}}}}}}|{zyyyyy€‚‚‚„ƒ€‚ƒ€‚€ƒ‚ƒƒ‚€€€ƒ„‚€€€€€‚‚€€€€€€~~||Š“Š‰ˆˆˆ‰ˆ††…„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…ƒ„…„…†††††………€€ƒƒƒ‚‚€}}}}}}~~}}}}}}}}}|{yyyyx|‚ƒ„…‚„ƒ‚‚ƒ…†‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚‚„ƒ‚ƒ‚‚‚‚€€€€~Ž“Œ‡ˆ†ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€€~}}}~~~€ƒ„‡ˆ„†††…††‡‡††‡ˆ‡†‡†}€€‚~}}}}}}}}}}}}||~~~|{yxwxyy€ƒƒƒ„ƒ„„„——ƒƒ„}~‚‚‚‚„†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ……„…ƒ‚ƒƒ‚ƒƒ‚‚‚‚ƒƒ‚‚’‹ˆˆ‡‰‡††„†…„„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€~}~€‚………‡†‡‡†‡ˆˆ††‡‡†‡‡‡|}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yxy|~‰—„ƒƒ„„”“€~~…‹€€€„†‰…„‚‚……‹ƒ‚……††„ƒ……ƒ„„ƒƒ„ƒ…„„ˆ’Ž‹‰ˆˆ‰‡‡‡…†…„…„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„„†…€}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|xyz{|‚ƒ€ƒ‚€~|~~{ˆ‘||Ž–}‚†Š…ƒƒ„ƒƒ‰}ƒ„……ƒ…†…„……ƒ„……†„„Ž‘‹ŠŠŒ‰ˆ‰‡…†…ƒƒ‚‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„„…„†„ƒ„ƒ‚ƒ}}||}}|||}||}|}}}|||{‹‘—Œz{|zzz{|yy}}~€€|{{~~}‚•‘„ˆ~|~‚„||‚„‚€‡ƒ}ƒ‚‚€ƒƒ„„„„„‚„ƒ„…‚„‘‘Ž‹ŒŒŽŠ‰‰………ƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚‚ƒ…ƒƒ„………ƒƒƒ„‚‚ƒ‚ƒ‚‚€€~}~}||||||||||||||}|||~~Š‚{z{zxz{{|}{~}~}}}}||}†~}‚~~€‚||€‚€~}{Š‚}€~€€‚‚€€€€‹“‹‹Žˆ‡‡……„„ƒ‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ……††„„€†”ˆ€‚€~~~€|||||||||||||}|||||||y{{{xxy{zz|€~|~~}€‚‚€€€‚‘€€~€~~~€}|}{}}}|}||}€€€~€~~“‘ŒŒŒŠ…††…„„…ƒƒƒ‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚„†‡††~ˆ•Š~€€~€~~~|{{|||||||||~}|{}|||{|||zzy{|z}…ƒ‚~~€~…‚~€~~€…†‚€~~ƒ†~|~€€€~}}}}~{|}€}~‹‹ŒŽ‡„††…„„ƒƒƒƒ‚ƒƒƒƒ‚€€€€{z{y€wz}~€‚ƒ††……~€€€~~}€€€€}}||}~}|}}}}}}|~|}|{}||z{z|}}†„‚€€}~}~~Œ„†~}||~‚}}}}€|{}|~„ƒ€~~~~}}}~€~~~„‘ŒŒ‹Ž‹Š†„†„„ƒƒƒƒ‚ƒ‚ƒ‚ƒ‚€}|||}~{{}w~vx~}|}|}~~‚ƒ€z}}|~€€~€~~€€€€~~~~~~}~}|~}~}}|{|||z{z}~€ƒƒ‚~|}|}||ƒ~Œ~|{{}~}~~}{{{}{z{{{€†…‚„ƒ‚€~‚‚‚‚‚€‹ŒŒ‹Œ‹Šˆ„„„ƒ„ƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€~€€€}€~~~|‚~~}}}{{}}|z||~€‚€€€||}|||||}|}{~{{{|||}|{{{{}|zz}z~‚~ƒ„‚‚…†……††‡†‚„‘ŽŒ‹ŠŠ‡ˆ…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~~€€‚€~~€€~}ƒ||}}|}}}}{|~~~~~~~||||||{~~{|{||||}|}|~|}||{{|y{|{{}{}~~€€ƒ‡‰‰‰‹‰‹‰…ˆ‘‹ˆ‰‡……ƒ‚‚ƒ„„ƒƒ‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€~~~}€€€€ƒ‚€€€€€€€~|z|}}~}}~~Œ†}}~{{ƒ‚}~~}}|}}}}}~|}|}|}}~|~}}}}|{{{|{||{z{{zzz{~~‚…ˆ‡ˆŠ‹‹‹‰ŒŒ‰ˆ†…„‚‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„„€€€€‚~}~€~{~‘Œ|}Š€Œ~~}}}~}}~}|||}}|}|}}}~}}~~|{{{||}|{z{|yzyxy{~ƒƒ„‡‰Šˆ‰ŒŠˆˆ…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{|||~~}}€€€‚…ƒ„‚‚‚‚€€ƒ‚€}~€~|ˆ‚~‚„„ƒ~}|‡}}~}||~|}}|}}~~}~}}}{|}~||{|}zzyyyy{{~~€ƒ‡„ˆŒ‰‰†…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{|}}}}zx‚€‚‚€€€€€‚‚‚‚†…„‚ƒ€‚„~€}~~}~€€}~„€~~}~}}Š…}~}~~€}}}|~~~}€}~}|}||{|}{{{zzz{{|}~~€ƒ€‰Œ‰‹‡………„ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv~€ƒ‚‚‚‚‚ƒƒƒ‚…†„‚€€€€‚€ƒ~~€€~~€~}~~€€~€|€~€~|}}|~~~~€}‚€|}€}||}}||{||{{{|{|||}|‰‰‡ˆ…†……„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€ƒ€€€€ƒ~~€€}€}}~~€€‚€€€}€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{|~|}|||{|{|~‰…†„…‡…„…„‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz}}yxut€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„„„„€€~€‚~~~€}~€}}}~€€‚€€€‚~~€€€€€~}}}~|~~}}„€~}}}~}~~}~|{|z|{z€†‚„„…„„ƒ…ƒ‚‚‚€€‚‚ƒ‚‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xytu}‚ƒ‚ƒƒƒƒ…„…ƒƒƒ„„ƒƒ„‚€€€~}}~~~~€}}|}}~€€€€‚€€€‚€€~€~€€~~~~~~~~……€€ƒ~€~~€~}{z{z|{z‚„€ƒ‚‚‚ƒ‚„‚€€‚€€‚ƒƒ„ƒ„‚„‚‚‚‚~€~}~~~~}~}}z{|…„{{syz|pwuvwyvtz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€~€}}}~}~~}~|}}~€€€€€ƒ‚€~€€€€€€€€‚‚‚„€ƒ‚€€|{{z|{|€€‚‚€~‚‚ƒƒƒ‚„‚„‚€‚€~€€}~~}}}~}}{{z€x|vyy{qtxwvxury……‚„„‚„………„„‚„ƒƒ‚€€~€~€|}}~€}~~}|~~~~€€ƒƒƒ€€‚€€€€€€€€€‚ƒ€„€}ƒ„€€‚}z{{||}}€|}}€€~}}€~‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxyzruyyvwwsu†…ƒ……‚„„…„„„‚ƒ‚ƒ€~€~€}}}~~€~~}|€|~€~€‚ƒ€€‚ƒ„‚€€‚€€€‚ƒ‚ƒ€~‚‚„€€‚‚‚„‚~{{|||}}}~}z~}}x~|||~}~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„‚„„…ƒƒ‚ƒƒ€}~}}}€~~~}}€€~|~~~‚‚ƒ‡…~~€€€€€€‚‚€€~€‚~‚‚ƒ‚ƒƒ…‚}}}|{||yz{z~y{yx~{{{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzswvst†„„…ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€|€€~€}~}~€€€~|~€€€~}~~€}€€ƒ„ƒ~}~~~€€€‚€~~€‚‚€„‚„„†„€~}||||zyvyyzyvyv~|{{{~|{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…ƒƒƒƒƒƒ‚‚ƒ‚ƒ‚~~€}}}}€€€€|€€€€|€}~~}~~‚‚~~}~~~~€}€€€~~~~~€‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{z{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvqxyrx…………ƒ„ƒ‚‚ƒ‚‚€‚€~~~~€~}~|~€€€€|€~€€€€}€~~}}}~€‚~~~~}}~~~|€~~~‚~~€€ƒ‚ƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}}{|z{}zzx{|zz{xtxuqrtpxxqy„…†…ƒ„ƒ‚ƒƒ‚‚‚€€€€}~~€}|~}€€€€|€€~€}€~}}|€€€€~~~~}|~~|}€~}~€‚~€€~„‚‚ƒ……‚‚~}}{{||yw{ywxwwx{{z{|…Š}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzz{zxswuqqrpxwq{…†……ƒ…‚ƒƒ‚€€€€~~€}|~}€€‚€}~€~€€€}~|}€€€€~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{|||zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚‚€€}}~€‚‚}~~~€€€‚€€€~|~|€€€€€~}~~€€‚€€€€€„‚‚€~|}~~z}…~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚€€€€€~}€€‚‚‚‚€~€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€€‚€€~}~z“z|}|{}y{zzxyxy{||}|||||||}}}||}|}}~~~}|z||{}}{yzzzyysuuooqpwst}…†ƒƒ‚ƒ‚€€‚‚‚€‚‚€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€~}~€~}€€€€€€€€€€€€‚‚€€€}~~|†‰||~{{~yz{z{~wwy{|{}||||{}|}}}}|}|~~~~|{|}{}}{yy{zyxstunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚‚€~‚‚„ƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€€‚‚€€€€€€}~€}€ƒ‚{~~{|}{z|||‡yxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€€€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ„„€~‚€€€€€‚~€€‚€€€€€€€€€~}€€€€€€€€€€€€€€€€€~}~}~~{}|}{||wxuxxy{||}{||||}~~}}~€€€|}||}{z{yz|xzsrunwqqzqvw……ƒ„ƒƒ‚‚ƒ€‚…ƒƒ„ƒ‚‚€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€€‚€~€€€€€€€€€€€€€€€€€€€€€€€‚ƒ‚‚‚‚€€€‡~~|z}|{}~xwvyyz|}}|}{|}}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚ƒ„„€€‚†ƒ„ƒ‚„€„ƒ‚‚€€‚‚„‚‚„‚€€ƒ‚€€€€ƒ~€ƒ‚}‚€€€~€€€€€€‚‚€‚ƒ‚‚ƒƒƒ‚€€€„}}}|}z}€zyvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysruowqwysw{…‚‚ƒ‚ƒ„‚ƒ„ƒ€€‚‚†ƒƒƒ‚‚„„ƒ‚€€‚„‚‚‚~€€‚‚‚‚€€€€‚„€~ƒ€ƒ‚€~€‚ƒ‚€‚‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ€‚€}€|z|{{w|yyy{z}~}||||}~~€€€„„€}€~{{{z{ztpxrytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚‚„†„‚ƒƒƒ„„„€ƒ€ƒ‚‚‚‚‚€‚€~€€‚‚‚‚‚€‚ƒ‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚‚ƒƒƒ„‚„‚ƒ‚‚‚‚ƒƒ„ƒ„„„…„…ƒ„‚ƒ‚‚ƒ€€~||€||x|yzyz|}|{||}}}||€€€€€‚~€€€€{{|zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚ƒ†……ƒƒ‚ƒ„„…‚‚‚ƒƒ‚‚‚€€}€€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€ƒ€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒ„ƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{~~}y|zzz}}|}z||}}|z{~~~€€€€€€€€€}}||}|vrvxxvtvu}‡‡ƒ‚„…ƒƒ„…„€‚„…„„ƒ‚ƒ„„€„…ƒ‚‚‚ƒƒƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚‚‚ƒ„‚‚€€‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒ„ƒ„ƒ€‚ƒ‚„ƒ‚‚~ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz{}€}||z|~}}}}~~€€€€~~€€€€~|}}~~}|{xvvwƒ‡ƒ‚ƒ…ƒƒ„†„‚…†…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚ƒ~€€‚‚ƒ‚ƒƒƒ„‚‚‚ƒƒ‚ƒ‚ƒ‚‚„„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒ„„„„„„…„ƒƒ„…„…„ƒ‚€}‚€}||{||€}}~€~~}~||}}}~~~€}}~€~~}}}~}}~~€|}‚‚ƒƒ†ƒ„ƒ†„‚ˆ‡…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚ƒƒƒ‚‚ƒƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ€‚„„…ƒ‚‚ƒƒ‚„ƒƒƒ„ƒ„„„…„„„…………„ƒƒƒ}„€}}||||~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€„„ƒƒ„…ƒ„ƒ…~‚Š‹…„„ƒ‚ƒ…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚ƒƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ…ƒƒ……„……‡‡†‡…„„…„€ƒ~~|~}}€~||~~|z|}}}}}~~~€}}|€€~~~~~€‚€……„ƒ…„‚„ƒ†€‚……Š‰„„ƒ„……ƒ‡††„„„„…„„„„ƒ„ƒ‚ƒƒƒ„„†„…„ƒƒ„„„|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ…}uzƒ€~„„‚ƒƒ‚ƒ„ƒƒ„…ƒ„…†„…†}„y|~ƒ{…‚„ƒ€~~~}}ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚‚ƒƒ‚‚†„„„†„ƒ„…ƒ„…„Šˆ………ƒ……„†††ƒ„„………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†tpurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚……‚hzrss|€s‚ƒƒƒ}}~~}~‚ƒ|€}€}}||||}|||~}~€}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ†ƒ†ˆ††…ƒ††‡‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vyy…r„ƒpvxqvtturstvi€nrotvnulwm{sn€ˆym}rsvsvmmxlpylu}}~€}~}€€}}|||}|}~}€€€~|~€‚€€€€€€€‚ƒ‚ƒ„…ˆ††€‚…ƒƒ„‡†ƒ†……†‡‡„ƒ†‡ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpu‚rƒ~ozyymonzoomw}x†pqzprtfu~n{ysoy€}}|}|~€€~~€€€~~~€~}€}€€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„†……††ˆ„„†‡ˆˆ†‡„††‹‰…„†‡‡…ƒ………„‚……„…†……†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„qjoyxpkyszozwvvp€~~~z~}}}~}€ƒƒ€‚ƒ„‚€€}~~~€~~‚€€„‡†ƒƒ†„„…†‡†…………††ˆ……†…‡‡…†„††‰ˆ…„‰Šˆ…„††……ƒ……„…††††…ƒx‹yrˆz{pp…„x…xyks~y{krƒ‡ƒz|m{yyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozls|nw‚€~~}}{}{|}}~}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡……………‡‡ˆ†„†…‡††…„……………†‰‰‡†„†…††…††„††‡††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„…†…†„†„ƒ„„†„ƒƒƒ„„…„…„…„†ƒ†‡…†„„…‡†„„…†„…}w…ƒ„„‚}~{|{~{||}~}|~}€€}€~~~€~~~~}}}~|{|~||‰†…„†††…‡†…………††‡ˆ†„†…††……ƒ„…†…„††††……†„…††††…††‡‡†…‡ˆˆˆˆ†„‡…††ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…ƒ‚……†……ƒ…ƒ„„…„……„……ƒ†‡††…„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ‚}€{{|}{||}~||~}€}~€~~€}}|€}~~~~~~||}~{|||{{}ˆ‡„„ˆ†††‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡……†…„†„…††‡‡…‡†‰ˆ††‡‡ˆ‰ˆ……ˆ…†‡†‡†‡†‡…‡‡†‡……†‡…‡†…‚ƒ…††„„ƒ„„ƒ„†„………††ƒ††…†……††…„„……‚…‡…ƒ‚‚…ƒ„~€€|{}~{|{}~}||~}~~|~}}~}|}||~~|}€|||}|||~z{{}~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†„…„††„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…‡‡…‡†‡†‡…ˆˆ‡‡…††‡…††…„„…†……„„„ƒ„……†††…†„†…†‡……††…„ƒ„ƒ‚„‡ƒ„‚„„ƒ€€€{{~}|||}}|||}}|}|~}|}}|||}}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††ƒ…†…†††…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡…‡††‡‡‡…‡†ˆˆ‡‡…‡‡ˆ††‡„‚„ƒ„†…‡…„„„„„…†††††…‡……‡…†…‡…„ƒ„ƒƒƒ‡ƒ€‚ƒƒ‚‚‚€{}~}{||~}|}}|}{||||||}{{{}|{~|{|}}|}}~}|zz{{||ˆ‡‚††††‡††…ƒ…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡‰ˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡†ˆ‡††‡‡…‡†ˆˆ‡†…‡‡‡††‡ƒƒ„„ƒ††‡……„„„…†††††…†‡††‡††„†…ƒƒƒƒ‚ƒ†ƒ~‚‚ƒ€ƒ‚|~~||}}|}}|}z{{z{|||{{{~{{}{{{~||||}~}{z|z|}‰‡ƒ†…†…††…„„……………„ƒ…†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…‰Š‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……‡ƒ„†…„††‡†……„……†††††…††‡†‡‡…ƒ†…ƒƒ‚€ƒ…‚ƒ~ƒ~~~~||}}{}}|~zyzy{|}{{{{~||||z{}||||~}|{{{{|{‰‡„†„†„††…„…†…„„ƒ„‚€ƒ…ƒ‚z„Œ{€„…‡†††…„‡ˆ‡†‡……‡‰‡„‡…††ˆ†…‡„†‡‰††ˆˆ‡‡†‡ˆ†„‡††‡……‡ƒ„…„‡††‡……„ƒ……‡†‡††…†††…††„ƒ……‚‚€ƒƒƒ‚}€~ƒ~€||}}~}{~}|}yyzy{}}zz{{}|}||z{}||}|~~€|{{|~}|ˆ‡…†…†„†„……………ƒƒƒ€‚…‚€}|{„……†„…„ƒ‡‡†††…„†‰†‚†„†††……‡…‡ˆ‰†…ˆ‡‰‡††‡…„†……‡…„‡ƒ„…„ˆ††‡……„‚†…†…‡†‡„††††…†ƒƒƒ…€€€€ƒƒ€|€~~‚€}€||}~}~{~}||yzzyz}}yzz{|{|{{z{}}|}|~~|{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€€ƒ~~~€yz}€ƒƒ„†…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ†…ˆ‡‰‡†…†…ƒ†„…‡ƒ„†„„…„‡†…†…†„ƒ†…†††††„…††……†‚‚‚„~€€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|z{{{|}}}|€~}||}~|{‡……††††„…„…ƒ…‚€€€€~€‚‚}~{‚ƒƒ…†…„ƒ‚†ƒƒ„‚€…‡…‚ƒ„…„„††‡ˆ‡……ˆ†‰‡…ƒ„„‚…ƒ„†‚ƒ…„„†„‡†………†ƒ„…„…†…†„ƒ…„…ƒ……ƒƒ~~€€ƒ{€}}‚}€~~~}~}}{|{zyzzyzz|yzz{{{|z{{{|}~}}}}||}€}|†ƒ††††…ƒ„‚…‚…€€€~€|~~€€‚‚„…ƒ‚‚„€ƒ‚€„……‚€‚ƒƒ„…†ˆ†…„†‡…‡……‚ƒ‚‚ƒ‚‚…ƒ…„…†„††‡††…‚„„ƒ„†……ƒ„„ƒ„ƒ…„€€‚‚~}}~~„~{||€}€}}ƒ|~~}}~{~{{zy{zyzz{yzzz{{|z{||{}~}|}||}€~€†„……„‡„ƒƒ‚†‚ƒ€€~~€}‚|}~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡…„„††ƒ…ƒ…‚‚‚ƒ‚„„„……†‡‡†…„ƒƒƒƒ„†…„ƒ‚ƒ‚„ƒƒ€€~}|~~|~ƒ~|~||€~‚}‚|~}}|||{{zzzzy{zzzyyzz{|y{}{|~€}~}}}€€€†„„…„…‚ƒ‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„…„‚ƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚‚€…ƒ~€~||~}|~ƒ}{~|}€ƒ}}€~}|||}{{zzzyy{yzzyzz{{{z{}||‚€~€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌËËËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFL=8765999<>9?<D9;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÔÓÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937677=;>9=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<9<<98:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA><A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÔÔÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9?CE@<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÑÓÓÓÓÓÓÓÓÓÓÓÓÓÎÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø×××××ÜÝÝÝÝÝÝÝÝÝÝÝÝÝÚÖ×××××××ÖÖÖÖÖ×ÚÚÚÚÚÚÚÚÚÚÚÛÜÜ×ÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILO@99:4;A<7=9AC>@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌ̈́mpppppppppppj§ãÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¹´{ssssssssssssp”À¼½½½½½½½½½½¾´ŠŠŠŠŠŠŠŠŠŠŠŠ‹‡½æáââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVN<::77>C>8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÎN&+++++++++++"ŠôëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§£££££££££££¥š4)+++++++++++$d°©ªªªªªªªªªª¬›SRSSSSSSSSSSSKªòëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;@C>6:7>>;=B?9<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÍÎR+11111111111'óééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤¦ž=.00000000000*h²«««««««««««®XWWWWWWWWWWWWO«ñêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;>@@8:;8<;;<?:;;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÏ\9===========5“ðççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©«£K<>>>>>>>>>>>9q´¯¯¯¯¯¯¯¯¯¯¯±¡babbbbbbbbbbb[¯ïééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB?;=:9;:==;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÅÂÃÃÃÃÃÃÃÃÃÃÃÂÉÐÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÎÏÎÎÎÏÏÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÑÊÉÊÊÊÊÊÊÉÉÉÉÉÉÍÓÓÒÒÒÒÒÒÒÒÒÓÓÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÔØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<8@B<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÏÐÐÏÏÏÏÏÏÏÐÔÐÐÎÌÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÎÎÏÑÎÐÔÒÏÎÐÔÒÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖØ××××××Ø×Ö××××ÖÕÖÕÖÖÖÖÖÖÖÖ×ÖÖØØØØØÙÙÙÙÙÙÙÙÙØ×ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?79:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÎÎÑÁ§ÓȔ¨ÒÐƓ«ÒÎÎÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<>B>BC@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÏÏÏѝÀœ«›°Ð™­™³ÒÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?>;7:>9?D>A98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÏÏÓº¯«µ•‡œžÅ“†ÎÏÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<<:6?B@C:647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÏÏӟ±›¿¾È˜™Æ½É–™ÆÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8FA?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÏÑÀœ‰š½Ó”–ŸÎё˜ ÎÐÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<>=964:99::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÏÔ£¢›Ä²ŸÂ›Ú­£¿ÕÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:=?>=<9@<<::9?@>=<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÑğ{–­Ð‹“žÇˈ•žÈÒÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CFCAB8;?<=;<<8558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÕ«¯¼ÀϔÊÛ¥™³ÐÛ¢™µÕÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF@HIGE@<<>><=><756:969;::;8@?:<<9<>=;;:?9?:;9=>==;;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦Õɇ… ›‘§™ ­¨˜ž»ÕÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;547<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡ÆÓÓ՜›¥¦¤¨ ¯§¢©œÐÓÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKL@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÒÑÒרˆÌ‘ŽºÕš‘Ž¾ÖÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<=?GFHKH=657:979:;:<=9>99:8;=>>A>=9<<:=>>:=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÑÒÏÅÔÓ¹ÇÖÓÓ¸ÈÕÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?AELLA>775;8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÒÒÓÔÒÒÕÔÓÓÓÖÔÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEJ>>786967899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9699:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EILAALD??;:889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEGIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDJ;AA;<886486987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGIB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<BA<;876797799=?A?<:9@?<>B?:8776=??@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE>;HF89757875898;>>=;89A>=@?A>7596;>AB??@@BB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCEFC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELCA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<;DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGGNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAC?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€ihxsg~‰‰xp‚†{w}~…Š½ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€ƒvt|„‚}sp€Šx‚yƒÈÞÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsoupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿¼½¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»º¹¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjdmgb\XQPQKTJB:IQ?A7<94:565455688686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸········¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®xpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µµ¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸¸·¸¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶·····¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨¨¨¨§¨©©©§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸········¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥£¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§§¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©ª««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤££¢¢¢¢  ŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž£¤¡žžŸ  žœœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=7789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥¤£¢¡¡¡¢£¥§¦¦§¬¬§¦ œ›¡¡ž›ššœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¥¦¦§§¦Ÿ›š›¢ ™––•š›™——˜˜šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜—™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥¢¢¥¦¦¥¦§¦¦ ›™›¡ —““’—šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB@DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥¦§¦¦¢œž¡Ÿ—‘‘”—›˜–––˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;;;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¥¦¥¥¦§¦¤¥¦¦¥¥£  ¡¡Ÿ™’–š™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šžŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡ ¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢¢¢£¤¤¥¦¥¤££¡¡¡žœš•“”˜›š›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œ ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸŸŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::88:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸ   ¡¢££££££¢¡ ž›™™˜™™™š™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢ ›ž ¡£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œž››œŸžœœœœŸ   ¡¡¡  ¡  ¡¢¡¡¢¡Ÿžœšššš›œš™š›™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥£¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¡¢¢¡   ¡¡ ŸŸžœš™š›››œ›š›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›šœšš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>98;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤£¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ žžŸ     Ÿ ¡  Ÿž›š™šš›››››Ÿžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›ššš›™˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9;;>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœ›œžžŸžœšš›œœœ›œœžžœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:=>:?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››š›œššš›œœ›™™œœœžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™˜˜ššš™™™˜š›œœœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›š™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š››››œ›˜˜˜™™˜˜™™™›œœžžžžžžžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ›››››››™˜˜˜˜˜˜˜™™œœœžžžžžŸŸžžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ››››››š˜˜˜˜™™˜š›œœžžž  Ÿžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_]]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜™——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››œ›››˜˜˜——˜™››œœœžžžžœ››œœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±³­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=9F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œšœ›œ›˜™š˜˜™ššš–‹“–™˜•˜˜–›œ—•’‘’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨©¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‹‘‹ŒŽŽ‹……‡‹ŒŒ‡ˆ‹Ž‹‡Œ…†‹†ŠŠ‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VPQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹‹†Š‹‹‰†„†‚€‚‰‘ƒ€ƒŒ†‹‰…€‡}€’†„„†ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹‹‰‰…‚}s}ˆ€~œ„……‰‹Šz}}†ŽŠ†”‘‹—”—’˜¡–ž—•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¥›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ†‹†ˆ…„ˆˆ‰„‚z||}~’ˆx…‹Šƒ„…ŠŒ‘™””” ššŸ¢­±­©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPFMHSWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‹‡Œ‹Š‡’Š‡†‘“‘‘„‡}}ƒˆŒŽ‹ŽŠ‰Ž””˜‘•›š¨®²¯¯µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWLO_^\NUTbQDTM;?9<895775795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš˜ “—š ™›£ •› ¤£š“ˆˆ‹‰‘‘Ž‘Ž‹˜šŒ”š—œœ›Ÿœ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUKTOOJCPK_bXZQ\S_MHQIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ª©¨§¡¥¨¨«©©¯¡›Ÿ¡££ šŸ œ”˜”˜  ¡¤ž›š¤§¤©«®¬¥£¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdVOXKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®ªª«¤¡¢¥©§§©¨£¢œ››¤ ¥¨£ ˜™Ÿ¡¢©§ ¢¢®¬«ª§­®¨¥¤©©©©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_UZNRNPORd\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢šœ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨¦¥§¨¦©¨£§¦™œ¤¥¢¡ ¡¡ œ˜™Ÿ ¡¤¤¢žž– ›š¢¢ ¡Ÿ ¢¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOWO^ddlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤Ÿ¢ ¢¦¡¦­¦¦ŸŸŸŸŸ™šœœ¡ ¡¤Ÿ¡›šœ ž¡Ÿžž £™–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvwa_\UYQUV[c^r_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?C?:8:>?C@DA:;><@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯«ª¬¨¨«°©¨©¨¡Ÿ §©­°²¯¬£¢¦¡©¥ž¤£¢¦ ¥¤¢¥£ž žŸ¥¢¢žŸ¢˜•žšžŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸ ¡¦¢›—’šš •|wo}yf[[`_Z\V\hdocnihb^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¢ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£Ÿ¢ª©§®·¶´´¶³¯¬«®«¶°©²±­®§¦ž¢££›œ—¢¨¥¡Ÿž£›ž¡š–¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¢™˜¥ ¤§ª©¨ª­¬¥©¤¥©§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxib[_^\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>AE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢œŸª²¸¼¼½»º¿´¯±³µ´··¯µ´µ²°¨¤¢Ÿ —•š—¤ª¦¦¡¤£¤«¥¥˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨©«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥ ¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxyxc[RYT__alhukpgiibYSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶³º±ª®´±°±´´¶¼¼¾¼¼½Æº¸·º½´¯µ±±º¸·²³²ª¦¦Ÿ˜¤¤§¨¤®¤««µµ®³ §ª¬§ª©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš“–””˜“š˜Š‹‡€€|‚xa^YSah`fsositdidb[LK>:8898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÃÆÃù½¿ÀÀ½¿Ä½¼º½¾´§ª˜±À½¸µ¹À³¯¯ªª¨­§§¤¯§ª´¼±´µ¨¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`a^^jbbnwuvnl[bQU\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAB;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–•–‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±±§¼¼¾ÅÄÆÉÇÅÆ»ÄÀÅÆÀ¹¯½¼À¾¾³«ªŒ³»¾´µ·Âº­¯°µª«¦ª£­¤§±¶«µ²­³­¨®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|ƒjfhaklfnuqruqf^_\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÅ¿ÃÂÆÅÀ±“¾º¿Ã¶¶º©´³´©«³»»±Ÿ›±¯¬¤¬®´§ª©¨ª­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|tkkndolhqxoyiia\gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÄÄø´À·´¼Á¹··¿À»®¥®·¼·­œ£·°¦­´µ¬®¥¥£¨¤  ¥™ª³²¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyz{vnkhguZfrwsxfg]d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÉÆÃÃÄÂľ¸¾ÁÃÀľÁÏÏÎÆ«¯¶´µ« §´³®«¸µ³«©£¢­©¬¦­Ÿ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuueeijh]jomxwcb``^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÏÏÌÃÇÆÈÈÈÇÉÇÅÉÇÈÇ¿ÅÇÄÄÇÈÊÒÏÒ̼¸¶´¸¸Á¾¾º½º¼º¼¬­¦©»º¹·À²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqobagugiitmxl]d[U`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÍÐÎÇÌÉÂÁÆÁËËÇÆÌÉÍÅÆÆÃÆÅÉÍÐÍÏÌÇÄÀÃÂÉÍÇÅÁÄÇÁ»¾´±°°Á¾¿ÁÆ¿¾¸·Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`jjvlietnsb\bTWTSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<:>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÅÇÈÆÒÉÁÃÄ¿¿¾ÄËÈÊËȼ»ÈÇÉÍÈÃÈÉÉÆÅÃÂÁÂÇÇÉÊÇÌÈÇÈÍÆËÏÅ·ÀÀÀÀ»»½µ³³¿¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrofegcjdajmnn^X\VUNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÂƾÆÁ¹»Ãº¸¹¼¾ÁÆÁƺ¹ÉÉÃÅÄÀÄÁÂÁÄÁþ½ÂÀÀÁÂËÃÆÌËÅÈÑ°¾½¸º»¼¾·´°¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfadbabccjbfcZYY\YQNE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶·´´µ¿»½¿¹½ºº´¿¸µ·³¯»¼·À·½Â¿Á»¿Á¼»Å¾»ÁÄÀ¾¾¸¼ÁÁ˾½ÉÄÀÀÊÀ±Á¿»¸»¾¹µ·´¸¼´½¸µ´°³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|y‡}qc`bbgjffiei]VUSYOSKE8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“’’˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´´±°µ·µºÁ¸¾¸¿¼½·µ·°®¸¶¹¿»À¿·Á¼»Ã¶ºÈ¸¶¹»½¹º¶»ÅÅʽ¹ÅÀ¿¼Á¾¸Æ½ÁÀ¼Å¸¶·´¸¶¶»»¸¶´·ºµ´¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒ€xpmeefoiekgXXNKKKRILHC9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’š”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿½¼²­¯¬±°·¼¶»¼ÀĹ···µº¹º»À½ÃÀºÄ¾Ǹ¹¸­·µ¸º´·³»ÅÆËÁ»ÆÀÀ¿½¼¿ÉÃÄžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~†|knpgpksebm_\THKJDJBCG?9;8=<7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘ŽŽ˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼¼À·ª­¤®°·»³½¿»Ä·¶¸¶·¿¿Ä¼ÂÅÅÇÇÊÉÆÏÂÁ¸®µµ¼¾¸»²¾ÄÄÊÅÁÉÿ¿¾½ÇÌÇÇÄǽµµ¶Á½º»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†qelintnwcgb\cQKTHEECGC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?=??FD@A?>:7?@CC?A=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼«ª£°¹½¾³¼¾¼Å¸²¸¹½ÇÉÊÃÇÈÆÆÉÈÌÎÑÌÊĵºÀÃÈ¿¿µ¿À¿ÆÆ¿ËÆÿÁ¼ÀÃÌÊÇÅÆÁ¹½¼Ä¿À¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtolltkln_b^aaNHM?E@?DC;;::;:8;<:9<>9:>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´¼Ã¼ºº¾¼Ä¿·½¿½ÇÌÆÇÉÆÆ¿ÄÄÊÈÌÌÍÊÆÂÃËμ¹½º¹ÀÿÈÆÄÁÁ¿ÅÀÊÉÃÃÃùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{z‡zmmw{_pc[]_^SI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA>>ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸´¼¶º½Á¼»¿¶¿Á¿¼¿ºÀËÂÇÈÀ¿¼¼¿ÅÂÇËÈÁÃÀÀÉÊÂÀ»»°´»½ÀÅÆÅÅ¿À¿ËÇÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}‚zmsxsgp][^\YQEDCMIAE=G::59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘–žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯·¶²µ³·¹¼»¶»»½ºÃ»·½·¹À»º¸¸µÅÁÂû¹³´ºÁ½¿ÆÀ¹À¼¾ÅĽ¾¹²°®¸·¿ÃÇÃĽ½¿¿Ãþ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸¸¸½¹»±¶²ÈÀ»¶´±°·¬³©°­­³·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|vluzpni\_`YSPAEHGK@DCH<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿš›œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹ÁÀ·½¹¸¹¶µ¿³´²¸±»ÁÀ÷·­°µ¸¸¸Âº´»·»¾À»»¼®¯®³²¹ÁÂÄþ¼¿»º¸¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ¯µ´´½º¾¹º»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰|‚zsvvwnq`_e\ZUJ<??FF=FCC9:5;99><<::<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Ã¿·º·¶¶²´À¶²´¸³ºÀÁù·³²²´²¸¾¹³µ²¼¹¼¶º¾²´´´°¸¾ÃÆÄÀ½¿¹³¯²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtvrl^b`[]OHA>=HCFMC@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·À½»¼¸¶º¶±Àº·¹¸¹»ÁÁÄû»¶´´°¶ºµ´²¬¼¹¸µ¸Áº¸³±¬·¼ÁÇÿ¹ºµ®¥¬³°¦°­¨ž Ÿ¥­¶µÂ·¶´¥¨«¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´·¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wo{ournc\fX\]RNMA>IB@JI@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³±­¶º®¬¼²¸¹·»¿½¹¾À´¿»¼º¸¾Â¼ÂÊȾÀ¸¸¶²´¶²´¯­»º¸¶¹Àö®®ª²¶¼½¹¶²±­­Ÿ¤§§£¦–™™šŸ©®¹¬««Ÿ¥¨¤«®®§¯¬¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmuik][jT]\OMHDFLBFMF8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹ºµ¹»µµ³µ»¼À»¾À´¿¹¹º±ºÃ¼ÂÊÅ¿»¿¿¹´´³°±­°¹¸¶¼¸»¿²²²®±®¹¯ª«­¬£¨¡ž—˜¡•’•—˜Ÿ¨®¤£¤ ¢§¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬«¯£££¡© ›“Ž“’’™–š¤¥ Ÿž§˜•’”˜ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wrxhtsndT`cW\QNLH@HQDMC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®¬¯²²ºº··µµ¼³¯´«¶º¸ÀÄÁ»µ¼½·²­³°¯¬®¶¶²´µ¯ª¤ž›œœž¨¨ž ¨©Ÿ¡§–›——“–Ž—›¤¨  ¢¢¢¥¥££ ž¥ ¤¬¤¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›©¨ª«ž¥£›£œ•Œ“—•–˜Ÿžžš™¦—“’–¢ ¥£¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦ ˆxƒ|vybwln\QhTPNGOMLBOQ@>;>49:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¥¬ª¨µ²±°®¯²§¦°¤¯®µÁºµ·²·¶³´«²´®ª«¯°²³®¥ž’˜”˜ Ÿ¢ œ¤¥Ÿž¨”›–—Œ—‘—“˜¢ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£ž™—š«¦©±£¥¨ž œ•“‘˜–•˜–Ÿ˜›™›£™—”–š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’}|€uu}mk{dhUQcMIHGNRNJNG;E@=2?759;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜˜—–¡¨¬®¶·º¹º··»®¨ ¡©¡ ­«ª¦©¤©¤¥®¥¬¬´¼·­³±¯±®µ¯¯³µª§­¬£›™”Ž‘–—™™œ ¢¢œ¥žš¤———–’‘‘“š—› ¤ªž¡¡ž¦§ª¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¡¤¡›˜ž¯¨®²«¥ªª š˜˜˜•“–š“••™–›——˜ žœœ—›¡šžš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}vx|dxy`bRU_HIIKSTIRPL9>B67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—““œž¤¨®­¬««¯ª¯©ž—ž¥ž¥¦¤¡¢Ÿ¦ ¢¯«¬­µ²¶¦¯³«©ª´±±°¸­§¡œš”—ššŽ‘•‘ŒŽŽ”™¢œ—£™š—˜™”™˜–›Ÿ¥¦© ¦£ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§  £±®²°´©±¯¢™œž¡™››š˜™›”–›–˜œ¤¡ š£¡š™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ Ÿž ¥¡žž¥ ¦™{|uvsh‚le[SZYMQJNNULRLA7=B78=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=>758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’’œ˜¡ª¢§ ž§¡¥Ÿœ’œ¢›Ÿ¡£Ÿ  £ ¢¯¯¬¯±¬¶¨®±°¨¦±®­¬°§Ÿž¢ —‘”› œ™—’“Ÿœ¡¤›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬¨¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½·¾°¬±®­©ª´±°¨«¨²µ·³¸¬±´¤ ¥Ÿ¬¡¡¢  š˜–– ››˜¤¡ ž¤¡Ÿžšœ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚|xuiwu]lZR`HQUHFUVJBLG=KH8E<67;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›“ž™¨®ž§žœ¡žšš’™žœ¡¢  ¢ ŸžŸ©«§¬©ª´¬«¬ÊÀ¤«¨ª¬ª¥ ž™’’“˜˜––•Œˆ‹Ž•ž–žš¦  ¨¥±ª§®£«­¶°´²±®¶¸½Àº­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«¯±¹·¼¯³°µÁ¼·½³³µ¢¬¢©¨²©«¨§¨š™žšª§Ÿ™¦ ŸŸ§¨¥¤žª¡¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰…„~vqmivmhm\X[BVMJGMGBFM<>L=4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜šª ±¢·£°¦Ÿž—˜•™ž›œ£ŸŸ¤ž›œ¥¢¤£¢ª°¬¦¨Ô´¥¬¯®©«§Ÿžž¡¢žšœœ”“•”ž˜”…š¡›«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶ººÀĹ½»¬¯§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¹Â¾¸³»Æüü·³©³­ª³´¯³®ª®£«§¶±¬¢¯¥ £¯±­°¤¤¯£¡ š¡§¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¥ž¦™›¢¤žŸ›››œ‡…{trkkurphW[QETHDIOH>EA4EH95;=6;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž ¡œ˜›Ÿ › ŸŸ—¤•››Ÿ›žœŸ¥¦¥ £È´²®§¤¤£ ž¥«¥ž—œ”‘™˜”ŒŠ†ˆ†ymˆ ¤¢«¬´¼¶Ã¾¾³»ÁÃÂÅÀ¿ÂÆÆÅÃÈÂÀÅÈÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌÌÌÒǾ¿ÀþÇÆ·ÃÉÉÂÀž¹´¹º´»·°µ²ªº±®»·¾ººª·­«ª¸º´¼®®¹£¦£ž¦¥¢£©¦™›Ÿ˜š§ª§ ¡¡¤˜”£–”š‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ„}zrkdhoxjdZ[FKLEDSLDBE7:?;549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”•–š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ³²¸§¡¡«ª¢ž¡¢žœ› ’ Ÿ’™Ÿ™’š˜Ÿ™‰¢±³¨ šœŸžš—˜—’Œ–—“Ž‹‚ƒ‚wsqnp¦­®´¹Å»ÍÇË¿ÂÌÎÍÌÇÉÑÌÍÌÇÉÅÆÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÒÓÌÓÐÓÓÌÊÂÅÆÇÊÇοÈÑÌÇÅÆÄÁ»ÃÀ¾¾¾µ½³­¿¿ÂÂÆÄÇÄ®¾¸²¸¼ÄÁÁº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›‹™‰•˜› Ÿ£—žš““‹•…€ytsebgrof^ZYCNLCEPIDC@5558:B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>8;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›£¬Ÿ®¦¥±ªÅÆÌÎÍ¿°Á¨¥¨¬­ª¡£Ÿœš©“š š¾£’Ž–Œ‚‹š©°ª£Ÿ ›˜—”“”–‘Œ‡„ƒˆ‡ƒ€€yrroly¤¶º¹¾ËÁÓÒÓÈÍÎÑÓÑÒÑÐÑÑÍÎÎÐÅÎÔÕØÒ×ÍÆÇÉÌÃÅÊÏÊÒ×Ñ×ÒÔÕÓÓÈÌÇÍÍÉÒÌÎÓÌÅÇÉÊÁÅËÆÈÈž²³ÈÄËÊÊÎÅÊ¿¾¿¼ÁÇÄÌÌÈɿÿ­¯³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›•Œ†‘‹zruvgcgvidVWQDMF@IQB=B<:22@<D<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<@?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­´¸¬®£Ÿ¤£Ÿ ¤¬›–§¯Ë¬Œ‘‹™¯¯¦¡¥¡ž›•”–”Š}wpkebhqoq{…Š€vpnqtp…³Â¾ÅÑÐ×ÖÖÒÖÍÔÖ×ÔÓÑÓÔÔÒÏÑÃÐÓÖØÕÖÒËÉÎÑËÆÍÑÉÒÕÖÙÕ×ÓÖØÎÒÊÏÑÌÎÐÌÒÏ¿ÇÆÊÃÌÌËÎÏÅÆǶÀÊ¿ÑÌËÏÅÉÇ¿ÃÃÈÎÌÏÐÏÍÊÈθ·»¨Ÿ¥«§ž˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„|xsvpc`erb]R\IJFAEHI>;@8=4585;86:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢š©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´µÂű¶¨¢¥¦¡¢«µ§š¯ÄÆ¥†† ¯¬œ•˜ œ›¡¢Ÿœš•Šwic`____^_`^blusqpolrqu’ÄÇÆÔÕÖ××ÓÖÏÕÔÚÔÔÎÏÕÔÔÑÑÌÐÎÓ×ÖÓÕÐÏÒÓÑÉÓÑÇÐØ×ØÑØÒ×ÙÕÖÌÏÏÉÍÑËÎÏ¿ÅÂÇÅÎÍÑÐÑÈËÌÀÊËÅÓÎËÎÈÄÉÆÆÈÌÊÓÓÑÕÏÒÌÒÁ¹Å±¥¨µ®§š¨¬¥²¨°³¬¬““Žˆ‹Žƒ‹„Ž™“™‚…Œ{zqstmacim_VP_JJBFCQM?<>54:=52855<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><??=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯®ªª«¦®¸¨«·×ÔÕÙÙÑÎÐÀ¼ÌÉ·¿¯§«©£¤±µ²£·Ë»›”ª«¡˜–˜š› ž™œž“~qecb__a__a`_``_`fmppnkorww›ÌÀÒÕÓØØÖÙÑÒÒ×ÏÓÎËÒÍÕÔÒÊÏÌÓÖÒÑÖÍÏÕÕÑÆÑÔÊÐÔÕÖÎÒÐØØØ×ËÈÍÃÈÎÌÊË¿É¿ÇÈÍÎÏËÐÍÎËÎÎÇÊÏÐÊÎÊÂÉÆÉÌÊËÑÒÌÓÑÑÏÐʽȹ°®»¸µª¶°­¨¸­³¿»±šŸ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…ˆyvopnkadnpaW\ZIFFDMWE;@<33<=87855;>@=9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ¤§ž¸¶µµ­¥­®¾´°ÀØÒ×ÚÜÖÏÍËÄÓÐÂÁ±ª­®«¥²±¸ª»Î¯£žœ–“—œžŸŸ”—˜”‰k^^^adb``aa``a^__^]bmroostvvy¤¾ËÕÑÖÔÓØÖÎÎÔËÍÎÅÎÊÒÒÏÆÎÍÍÔÌÎÓÍÊ×ÕÐÌÑÔËÌÐÑÓÊÎÑÕÒÕÕÊÀÉÁÅÌÂÈÉÂÌÃÅÈÊÊÎÊÍÌÐÍÓËÅÈÏÌÈÇÊÄÆÀÅÊËÍÏÑÆÐÎÍÍÌÏÅÇÀ·¸½Ãýù³²¾±»Ãĵª˜¥¢™–‘••’‹”š‘”””‚‰…xpqkmg``qhXXhVLFLIPPB;D>;67:89:57==A;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÅÃÁ¿»µ²±Ç¸ËÕÖÙÚÛØÌÍÏÈÖÕÅ÷±µª£­¬¸¹¯¿Ê¡—Ž˜•“’‘–––Œ|fbbb`]^acb`_``aa`_][]grqqrsqmry¤ÆÓÏËÐÏÔÕÉÅÉÉÆÆ¿ÃÆÏÎÇÅÇÍÊÒÈËÎÍÆÑÒÏÎÌÔÊÇËÎÏÇÇÏÒËÐÏźľÆɽÂÇÉÎÄÁÇÀÇÍÇÃËÊËÏÇÃÃÐÈÆÁÅÇľÀÇËËËÎÂÊËÈÇÌÐÄÅÇ»ÇÃÈÈÂÏÁ½¼¿°ÁÉǹ½ª°²§¥¢œ˜›£™—™‘•˜‰‚wntdk`^fqa[W`GHHGIMTG?J=64355=<48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥²±¬ÉÍÊÈľ½ºÍÍÇÐÕÕÙÚÛØÐÊÏÐÒÔÉĹ½¾¯§·ª½¸·Ã¬’ŽŽ—†ƒ„„‚~……t`\^^^`^`cdc_]]^_``_[Z\akrrookloo}¸ÑÈÉÊÏËÍĺÀû»ºº¾ÈÆÂÃÀÃÇÊÉÈÊÈÁÅÌÆÈËÍÉÄÂËÉÁÂËÐÄËÈ¿¹Á»Åǽ¿ÆÏËÿûÉÆÈ»ÈÆÄÊÀ½ÁËÆÅľż¼¿ÃÄËÅļÀÉÂÅÇÒÄÀÈ¿ÊÉÆÇÆÐÃÃÆïÄËÇÃÊ·¿¼º´©¬¤¥˜Ÿ˜¬£¡¥š£ ›”{vstfiZanmZ[XQDLFBGDLDFS@54334?<3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ËÏÑÌÇÂÃÇÍÏÏÌÕÐÖÙØÙÐÌÓÎÏÐÊ÷ÆÀµµ»°¿¶¸°‘Œ“˜‡z€…†€vxurq_Z[]``bddded`\\]]_^`[YZ\borokilposÆ¼ÉÅÌÀÆ°¶º²²³²±Â¼¼¼º¸ÀÁÁž½¹½¿¹ÄÊÅƽÆÀ¸»ÄÉ¿ÂÉ»·»ºÅþ¼ÁÍÃƾ¾µÁ½Ãº¼Æ»Â¹³¼ÅÄÁ¶¿µµ½¿ºËüµºÈº¿½ËÃÁÅÂÅÈÆÈÆÐÆÂÌDzÇÉÃÎÍÁÅÃÀ½²·°²§¨¨¹°¥­°«­¬”yvwjdg`hocV^YJEJFHJAEBEI@9:648853;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÆÂÄÈÎÒËÊÊÇÍÎÏÒÉÑÆÖÔÖØÎÌÐÇÌÈÊĽÉÁ±´¹¶¹´®‘Š‹…y€††€~„|tud\\]^``bcabeeb]][\^\^]Z[]]hsqmggnpry½ÌÀúÁ¸®°°§ª­¬§¸´·´²³´ºµ½±·°µ¯²»Â¼Áļ¿ºµ³º¾À¸Ç¹´»¶À¼¸½ÆÁûµ®²¶º¾´Ä·»µ«¸½½¿½°º¶¯¶º²Å¼¶®»¿´¶´Å½¾ÃÅÀÃÅÆÈËÅÀÆÆ»ÈË¿ÏÊÇÃÆÂöý½¶¹¾Ç¿¬µºµ·¶Žxtxfgebkn^V^`FKHHJFBDAEE?<:565633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÎÈÆÉÎÌÐÌÎÈËÉËÊËÅÑÎÓÐÏÇÉÅÉÄÿ¼Ï¼²·»¸¶µ›Ž‡‰‰{y~††wx‚}th^]]]_`_`da^cec__\[^\]^Z[[]_lpnhfjnnr|¤Ç¿¸¸µ°«¬§ž¢ª§ž«¬³­©«©´­¶°²©®¦¬²¼º¶Ã¹ºº±«µ¹»´Âº°¿±½¼»¶¼Ç¹Â¶­ª¨°±¿µ·¼¯°§±³´»¼«­µ¥®¶®º±°ª¸°­»®»¸»¿¿½¹Â¿ÇÃÅÁ¼ÆÁÈ˸ÅÇÅ¿ÆÃùÄÆ»ÆÉÌ˳¹Â¼º²ˆrvvkiablhYWW[ALKLIEAC?FA:9:995854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÆÎÒËÃÆÂÅÐÇÎÂÄÇÀÆÆÄÄËÂÊËÂÃÀÆ¿¹»ºÉ¶³º»´³ª‘‰|y~Š†z{…wo^]\]]_`^_dcbccb`_][[ZZ]ZZZZ\dnohfgiknr­¹°µ®¦¥§§š ¤ šœ¥«®£§¢«ª¬ª°¤¦Ÿª­µ¶±½¹¯·¯¨®·´´¼¸´¼¯¸¹´±¼Á±À®¥¨¢«±²³§¼ª«¨«¬­´³¥¨­¡¤®©²¥§¨­¥¨·¬°²·¹º»±»½¾¾Ä¿µÁÀÇÈ·¿ÀÄ·Ä¿»¿Ä¾ÄÈÌÊ¿¾ÃÀÀ©†rtrji]aodWVXPHYRSKFFE>>@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·ºÄ°¶°›™•œ˜ª©°±³µ½¯ÅÑÐÍÄȺºÌÂÌÀ¼Ê¸¿ÅÀ»Ë¹ÂÅĹ»Â¼¸¶¼Ä·´·¹¬°•ƒ‰|~€~xt|swf_]\]^_`^_ccab``_^]\ZXZ[[YXZ\_fkfegehkor…ª¥¬¦ œ¡¥”¤›˜’¡£ª£¢Ÿ¥¥§¥¬Ÿ›¤¦¬²¯¶·§°¬§ª´ª´º±¶µ­¶¹±¯º¹±·¤Ÿ¤Ÿ¦±§«¨¹ª¤§¨¨§²­ §¦Ÿ›¤¥¬žŸ§¤Ÿ ±­­¬²´²´°µ¼¶»ÁÁ²º¾ÃÁ²¹ºÂ³À½¿µ¸»½¾¼ÂÇÄÂÿ¿Ä ƒwpkaf_ko`UY^HNgOTGEJF<=@=:;;825536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;=:7676788666;::;9:;<859<:>>@;Èµµ½¸ºÁ»½µ ž”¡¦º¶«³³»³ÄÐÉËÃǹ¸ÉÂÍÀ¹Ë¹¼Ç»µÇºµÂű¼Äºµ®·¾º¯±´­¡„‡‡‚}zvtomkjjqi^`]\\\^`_acb````]\[\\XYXXXVX[^_dcbegggjmoˆ© —•š¡–›¢˜–ž¡¢¦›ŸŸ£¥¡§ž›¢›Ÿª°­±µ¢©ª©««¤´¹­·°¬²µ®²µ®°ªŸž£¢²¤¦©¸­¢¦¦Ÿ¨¬ª™Ÿ ž™Ÿ¥šš£œ›¯©«§ª«¬­°²¸¯¸¹»°¶»»º«²²¹²½´¶±±µ´¿¶½À½ÃÁº»½—ƒzrk_e^ddXTX]IW\KPGIIFA<??@;?<04535:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»·ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÆÐÈÉÁǼ¼ÅÄÏ¿»ÉººÁº´Ä·³ÀÀ²À»«¨³¸µ¦¯°¦Š†ˆ€ysnpnkb^bff\]^]]]\]_`abccba_\[[ZZYXXWWWXXXZ^bddeffhikr¨”””›˜›¡––‘œ¡¢¨›¥¦¡¥œ  š˜­®­®² ¥¢­«¦¡´°±±¬¨¯²§º³¦¶¡¢ž›£¡­£¡©µª¢£¦¥¦£–˜ž—™šŸš—œœœ¬¡«¦£¤¦­«³³ª´°²ª²¹´¯©¯²²²·³®©¬®²¸°º¶¹½¿·²±”…yue^e^[YVSZUK[QLIEHKIB=?AA@A:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½·½¿¶¾¼¿²¥£˜¥±Âµ¶½­´¸ÂÍÈÇÁƸÂÁÈϸÂÆ¿µ¼¼¶Â¹µ½¿´¹½¹¨¤¯¹¯¥¯¬™}„…€yprtqhedhec\\[[]]\[^`a^__`^\[Z\ZYXVWWVXXXXVWadecdeddhjv¢œ”””–—Ÿ—™”˜Ÿž¡œ–¡¡¨£Ÿž©œššª¦¯°«›££·ª Ÿ®¨¶©¦§­°£·°¤·Ÿ¢›˜˜ª¦¡š¬¸°¢¡¤œ¢  “•¡”•–›˜—–—œ•Ÿ©©£¡£ªª°®¨´«ª¦­²°¥ª®²±¯°®¯¦§§²®±´¯¼´º·®£”yud^aVYWSRTKM^LPKGGLLE<@><B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾¸½®§§£ª»À½À¹®´¸ÂÍÉÆÃľǹÉÍ´ÃÄ𾿸¿À¹¾¿¸¸»µ¥¥®¹¤¦Ÿ¢ˆ€}yrjmrtphhedgb\\ZYZ\\\]^]\[\^\[\Y[[ZXVWWVWXWWWU[ccbbcbcdfj–“•‹‘”“›™œ––› œŸ• Ÿ¦¥¤¦§žœŸ¥Ÿª¯¦Ÿ¢£¶¨ ¡¢¨´¡¥§¤¯¥°­¬µž •”©¡¢”¬±±ž¢£˜›“‹¡”‘“—˜’——˜–¦›¦¡¢™£¥¥«¤¥°§¥£««­¦¨®¯®«¨ª©³¥¦«¯´±®¼µ±¯¯ ’zvrda\Z]XNLRHRaMVPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8846863321./2556;:8;7876<;:;;A8x»»±µ½°»±¸¬ž¤§­·»¼Áź±¹µÅÊËÁÄÇÇÈ·ÇÅ´ÄÁÈ®¹ºÁ»Á¿À¼º¶¸´¤¥¯³›Ÿ‡—ˆ€wodbgiifgigjm`]\[ZZZZ\]\[\^_\ZY[YYZ[WUXWTTWVSTRU``_`a_`acdi““ˆŽ”’“œ”•–£™ –œ ¥¡­¥¤£¢£¡›ª«¥™ž¥±©  ¥«ž§¡ž¬­©¨®­¢¡¢”—£›œ«¨°›Ÿ¢Ÿž—™“Šž‘’“•˜˜“›¡¢œ¤ ¡• ¡¤¦›£«¥¢¤ª¤«®¥­±©¦¥¦¦´¦©¨­³µ´¹º¯ª¬ž‹rpo`[WVUQFQOHZ\ORITKSLEGIC8;;=<8667:9;:976977:;:=<<6;<8>598:88659:;<97?<9678452121..1426:8698598989;9@9{µ´­´»²°¬²­§§¯¹¹³ÀȺµÀ¯ÆÉÍ»ÂËÍÈ·Ë¿³ÀÆ˯´¼ÆºÀż½µ¸³£¨®¬š–„ƒ|ujjjlhjlmkjme]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURSOQY]\]]^^__bdmŽ„‘†‘Ž™“”’œš¢œ› §¨ª¨ª¦¨¥£˜¤®¤”™¥¯©Ÿ›™› ž¯™›ª³Ÿ¥¦Ÿ££¡”“›––’¨ª­šœŸ¡ š”Œ™Ž‹Œ’Œ–”ž¡ £œ›¢•› ¢ ˜¢¨£¢¨« «¯¤­·¥£¤¢¬­ª¨«®²·²½µ³«¯˜ƒssh[XXRUREXLQ[YMUNPLPQINIB<??A?<65799<<987:79:;<=>;7;;:=67:;8976989:6:=99577571141-+/434988::8::748=8?9~³®¨³¶®©¨¯­›©¨¬·¶¬¼Ê»¶¿¬ÌÇƹÂÏÐȵƽ¹¾ÅË´¯»Ã»Áü¿±¶­¤¨¬©›“ƒwxoninnnphgigd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUTSNPQYZZZ]\\^_`d~‹~ŒŠ’—‘—™¢ ›Ÿª©¦®ª§¯£§™Ÿ¬ •–¤¨§—šž®–—§ª™Ÿœ”¥¡ž’“’“•§«¥š™™–ŒŒ”†ˆƒ‹’” ž £—•Ÿ•š ¢“›¥¥§¨¨ ±°¦°¼§Ÿ£¬´ª®§°´°¹µÀ±­±«}qrbVTVNRIGVQRRLLXMJLNRGMKACFDC>@75889;9:7::7<=:;@>:9;9:?759:9876958779;85576661320-*.102877;99;8948;8@8³­¦±·ª¦¢°«ª§©²±¤¶Æ´¹º³Ëƺ»ÂËÑ̳¸º¾ÀÄƵ³¶¼±¹ºÂ¼¿¯±«®«­¨™ž…kgmnroqkpkdfge^ZYZYZZZ[ZZZ\\]\ZXXXYYWXWUUTRSUSVURNNNRWXYYYY\\]aj€zv‰‡Š˜‰””—›™¨šŸ©¥¤ª§˜ ¥›’ž¢š—–…„’š£“¢œ•–•‡¢šš“‹Ž‹™¤¨œ••—›’‡”ŽŒ‹€Š’’‘¡šŸ¢•”˜˜•¢¥™Œ˜¤¦¨¦¡ ´²§²·¡¢·¬©­¤²²¦µ»µ««±£ˆxql]NPQLOCMNNPKFNNJJNMQIMJAGKHGC=858889:;69:68;99><8:>9;?8789:886857688974577820301+)-/12776:999984988A7w¶§¤¶°¤§£©¥ ©¥¤³ª¢²Ãµµ²³ÇƸ»ÄÊÍǵ¯»¿·ºÃ²±­µ¡«´Á¸¹¬¨©±¬¬œ“£{^`gsqvqjniehhj_XXXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQMMKLSWWVXXYX[]aosvq…ˆ‚ˆ€‘ƒŽŠ”‘“ š›¢¡£˜¤–¡›•‡˜šŒs‚}—–…™“ŽŽ{™ŽœŒ‚ŠŠ˜Ÿ¢ž“˜–„Ž‚“~~t‰Žz†’š™š•Ž¢£Ž‰š ¡££›¢´¯¬¯¬Ÿ™¥¸¦¥°¡°®œ°»ª©¯ª™vrbUMROPMCSNLQMBPQHINSMHJJCJLFKJ<749888;;69;7:<9::;79?9>@79:<89764445874312585/0102)(,-11764789::65:87A7w·¢£´¨¥¦¨£¦¥¦¦¦³§¥´Á¸¯´°ÊŸºÁÏÆ¿´®¼Ã®°Æ°¬¦ª”¢¬½¶®®¥ªª¨“‘žpWW`hgihincjigb\XWXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTRMMJHNSSSTUUWY[]ilrm…|tNXr‚—†œ—‹“Ÿ—•”–”Ž–‰“‰_;Wo{‹”‰€‹’Œ…†sŠ„–y‚z…“”ƒ–Žƒ†}’xro…~‰€—™˜“Š‰œ‡ž—‡ˆ–žš¡ —§¯©­¨§ž—­³¢¦­˜¬«˜§´¢©­£’}rm_[NSRVLDTJPMLFNOIELQMKOJIMPFII<7599999:7:;:>>8:==6:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9y· £­¡¦¦ª §©§¢©°¨§´Á¹°µ°Èø´¾ÏÀº°°·Ä©­È¬¦¡œ…™ ¸«¥¦”£¢¡Ÿ”Œ“gQMRVZZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MORMKHFHNQQMPRTVXZ`moi{‚tPBA•‘‘}‰”Œ„Šš••Š’ˆ…•†xˆ`JQnxŠ‘„}„‰…n~”wuuw„™pQˆŠ‡|~x“vhw…ˆ~Šˆ•Š‘–‹„Šˆ”„šŒ„’›–žœ”¤£¨©¥£ž›°ª¡¤¤¥ª–¡©œ¢¦¨ˆtle^[HQQRMIUMSILKOIHFKNLMTKQQOFHB<769:8:;;8:;8>?99>=8;<6;;478;6775344696/3/.125221/,')+*,4833979:99::::?9w¶›¢§Ÿ¡®¡§¨¥§¨¯­ª¶¼¶¸·³Â¼·¨ºÉ¹¶¨©¶·¬µ¿ª¡š‘‚Ž˜¯ž —‹”–’ˆŠcMLNNOLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDDINOhYNQSTUZnƒtw~ji]U‰”‰t‡|…Œ’’™‹{†€uxsnupty}Šª…yzhv{ŽprmxŠŒ’xz€{€vsr’wgu„„„„z•‰ˆŠŒŠ€„‹Œ”ƒ{€˜•œ•‘Ÿ©žŸ  ©¥Ÿ˜Œ§¤“ Ÿ–žž¤qg`\\JVORGKXROJMMRJJJMPHLQLRTMEHA<77;99>=:;<98@?::>=7==79937795675252572/2.,//200/-+(().1272198798775:<;7v®˜£¡˜œŸ´©¯©¥­¬°±ª½´²»¸¶»µ² ·»³«ž­ª«´²¤•‘—„’¢•›Š•‡ˆ„…dKIIHGFHHPTTTWWSTUUUVWWWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQRSV^uƒ}ygw—˜Ž}gyvx€‰|„˜’r‡|v{ok~­|sŠ{†’}tfv|…lohs|‰Œ‡€lyq}pmuqhq€}ŽpCŠ„‚ƒ…~wwz‹…}‹zu~Ž’˜Š’š›£–™šž¢–Š¥›ž—Ž–˜vmlebZWWTQJSUTOPNQVKNKNOJQNHNOKFD<;79;::?=9<:99??;8<=7<9999266856633621224.,,-..-0-+*''*.1362/876966527995y¦—ŸŸ– ¦¯¬®«¨©±¯±«¼¸¬»¾¹³­¨›±§­œ–§«¦£šœ’‡”}”‘“zˆxƒ€}~dJFGFA@CDILLMQRPQSUTTUVWWWXWXYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNPQTX^eprmˆ§ªÀ~uyb{xn|yˆy|‹…omŒ‘xsxjj€‚r–‘‹}–€I’˜nhx~licly…’†ksl|nr{†hmp~sˆ„…z}~{vots…‚ywp|ŽŒŠ“ƒ–—˜š“•–™—ž—Œƒ‰Ÿ‘Š’†–~mhmnnWUWTRQYORUUSXUMNHNJMNKCHNGE@:89;99:><9<;::=>:8:;9?868727575541442/024*+**-.+-*(*(',-1250,5567485HA895w™‘›™šž¥­°¢¬ª¨µ¯®¬´¿«¼Â¿¦¢š•¥˜žŽ…Œ–¢£™š“–Žu}„ŠŽ|w}s|wtw{fNEGD@<>>AFFGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jsC™o;<95<€‚†_IMOORWZRY\`§ˆbšitze~pmz‹‰vˆ†tlš‘ts{jkMy…’‰„Žg1v†sl~}ƒtfet~„ƒ…€filukp|gpp{n’Ž{s}|qpnum‚~wytiy‰‚ˆ‰ƒ–“’‹‘””—Ž€yˆ—ˆ†‰†€‡uiingdWQZWYY[MPUVYYNIHEJJHGBAFDCG=998;9:9<:9;:::@<9:<98>787715244533645031.**+),,++)(+'),,226,+5775478iO8;5n’ˆ™‘š–¤¨®ž²Ÿ¦º®«²°Â±»ÃǛ–•™‹†z…‘™•‘’‰sˆ„wŠŒvwuwvoxsiTFID?<;9:?@ADDEGJLOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOPQVLAIQIb¯³ q|xm}lrƒ…z„††yr •tx€su”‡5q¨Ž¡¡„¢„vp†|†|sŒ­ˆ€hfbinrmpƒuioXuoŽš’vl{|mqmpzsvmbv„†€…‘Š‹Š’‹‘Œ‹ƒux‹€~ƒ~yponj^Z\][YX`_SN[ZYXLHJEJG?CABG>CD=;97=;:;;9:99;:?<88=:8;66651121353475531./,,+)*))***)(*)+/3DM2166643<vR7=7b’’ˆ–‘¤§ž¯•¥µ©­±®Á²»ÁƗŒ”‰}n‚‘’‰„‹ˆ‡vƒ…n—ŠŒyz{q{t|ko^JPG>@7448;;<=>@BEILLLMNPQRUUVWXYXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL7CMRSDJ†v€||v~mwˆˆ|}…ƒŒ~v¢™y~†„™„›œa†ªŸŠ‚zvˆ~‰ˆsŠ—ƒ{\dqtz{wŠlgiaxo…‚znwt„zpsywkni]w‡}‡|ˆ‡€‹“—ƒ…‡}q„„|uw{}‰unqref_[Z]S[f^WQUX\VGJKDLG?F@DC>AA=:97<;;=<::99;;=>79>9986754244004645654-,)+('''&(())((+++/00Uq<23331E~W4=9\ŒxŠ€”Œ‘Ÿ¦‘ « ±¨¯À±ºÅº–Ž‘”ˆz…vk€Œ’ƒ~‹„Žyƒ‚t¢†‚sƒ}lzlSWL@E211267688:<?BEGFGJKMOPQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMORLKT]YRJi„ˆ{‰y|q|Œz|‰†~—‡v¡™ˆ‡’”¥¬©H†®¯¯‹€“Š‚‹„‘¨‡€˜˜Šœsl|†‡}Žhggx~n…†‚…q„…Gk€wqyvhmk_v}ƒˆˆ…Œz•žœŠ‹ˆ‘{u‹v|wmow~rqpjZ\\[ccXge\UPPWYPDLLFOICFCCA@CA=978:::;;:888::?>6;>7585773344236656768;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|~Š…ˆ‘–˜’— ¬¡¦¸¯³½³—’‹˜‹}tp‰“}Œƒ“•}†‡¥ˆ‰ƒˆ†yˆ‹u†y_cVKB60./23123668:=??BEGHJLNQSTUTTVUSQOGC?80,#‡[>?84.]–ps£UFIKMNPW`YpZ\^j“‡•„‚…‘“~…‰‘š•‚¡¡—•›š¥­“š»±§»Ç苌¡¥Ž“‰{rƒŸ‘œ~v……Š‡ihoƒ€tŒ†„‹q†‚w‡€{v…}nvug€”†‰ˆ‡ˆ‡¡«¢–‰Ž˜{‚‰zzogkx}x|qic]ZY]i\`f_ZOLNXRQIPKDNGCKDCADDA<:87=<:<:88778:==8<=68656623444576867<BB?<8:>CQ^e\G2'&,,--.1(?Œ[.310Oƒ_4?;nupgxƒ{€Œ€‹šš¤œ¡¬¦«¯°—‘‘„¡”„xw€Œ”}’†“–Š€’›Ž„‚Œ‹‚ŠŽ„€Š€lpj]CA4--//./02234779;=?BDHJOQRSRSTTRPOHDB<87/9D><<63.l“—MPHIKKKNV`cggmu›š““‹Žšˆ“‹  ’£ª¥£¬“¨¶¢¨Áîǯxº”š|Œ¡ž˜„’…‚¡Ÿ“˜’„Š…˜‘–lpu‰‹•Œv„ql…Š–’ƒ…ˆr‰¡–†“Š–¥µ©›•¢ƒ‡“„~kjk|~~€q_\b^Yfj\kk^XKHOSQNMLFIPDDNFBCEGB>997=<:;:987767;:6=:785456345566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYpƒpu‡qv‘†~—–š”ŸŸœ§ ª–“˜žge¤š~…“‘y€‘‰‘’}Š…™’‘ƒ€€‹‰†‘‡„ˆ…xxgMR>/..,/.-/000212457;?CFNPRTPQRSQNPIED>;<:CF?><752<?R5HHHLLMNR^oŠ|s} ›¨¦¢™¡—¢•œŸ¨ž©«Ÿ¨¬©ªµ—«¿«¶ÈÈ·ÉÑϾ› pi«©Ÿ„“’…œ¡šš™§‘‘ˆ•¢ššwz~”—‘¡’–—”ž{v•’«³‰— }”žœŽ“–™¤¢¦¶°‘™¨ˆ—Žˆlss{}zof^[_^`fc`gf\REKKPOIJLFFMCGMFFCBGDA:85<<899975658>75=84745754536958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f2A@ia^Pqu`n}awŽ}|”ŽŽŠŸ’—ž–œª˜žªBD}‡‰‡˜x‚‹Ž{Š†Ž‚ƒ€‰ŒŠ…“…ƒ†ˆ€‡w_bP460-1/,.00./..0015>AAMQRSPRSUSNSLEE@<>=FGAA@8662<9;FHGIIMOQYm†w•‹£§ªµ½¸¥®¬¬§¨´¬±·²²­»±³¾œ³Ä¬»É˸Ŀ¸¥£°²¬­ª£‹–˜…¦¦ ¢—‚¦™¢ª¨¤‡…“£  ª ¤©Žœ±‹•£§·»› £°“££ž‘¤¢«¯­³µ¢•¥ª‰šŠ“Š•z{~ƒ|e_f[d`]bc^ff_[ODJHTOFHLFKGEFHAKFCFFA:87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLicXjpXz…v”…ˆ‚›ƒ’“Úȝ–sV—ˆˆœ|†ŒŠŠzˆ‚‡‘Žƒ…€‹……ˆ’†‚„‰†‡‡‡qna@E64<2/110-,+-1/-4?DAMUQRTUUWUM[PGGD<>>FHCD@7;<5C;=FKIGHROPW“ „®£³ª²ÁÈÄ«³Å¶¬³À³¸¾¶¿´Á¶»»¤¸Æ©¶ÉǶ¾¹´¨£´­°±›™’šŸˆ§¯ª¤”vŸ¤—¡«±³˜–©­¨®µ»²º¬¯µ¢±¬±µ¼·µ®µ §§£¨›©°­²º¸¸§œ·©¥’“ †ysW`bTe``b__e_[TIDELVQIJJDJHEA@@KDBMF<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AEWQJL[ZQbdWzuq”}„†“v†~€Œ{¿»£¼‚´”“Ž›„ˆ“‰‰y‡€Œ“Œ‡…Ž‰†…ˆ…Š‡‘zyn]V@EN<6:46AB764//6CHCQ[OQUWU\WO_UIKJA@?GKFEC;>@7D7?BJJEGWTP^¥­£±´Ã¶¸ÁÌʶ»Ä½³´Á·¸Âµ¿°·t±´¦ºÅ¤°Æ¹±³±´¨¤µ¶ª± ¢–›¢‘¥±­¥­«§¤˜ ¬³º¢¨²¹µ»¾Ì¿ÅŽ½³Â·º¸¿·º·¹­­±¦±ª­¾°½»Â¬™»¨•­˜˜ª‰~€ziVa_WicidU[cYVTIHGLQGDIJAHD>?BBK@@MD99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FQLALRWTYVZwjp„Ž…nzrx‡b¸¡š£‰•”–“”“—’‡‡{‡•Š€„Šz|‹‡†}Š‚‹„•}xzueO\dGEL:Qda[^SF>;HPDZdQQYXZgZT`aMSOEA?IJHEFA@C=E6B>HGKMSZT^”¯¸µº¹ÉÀ»½ÊÌ»½À»¸µ¼¼·¾µº²Æ`u²¥±šž«¾ª¥¨«ª¤¢²µ «¨ž•–ž˜Ÿ®¥§¦¥Ÿ¤“¢§°³¨²²¼¶Á½ÓÉÉÓÆÂÅÌÂÊÃÀ¾½¿»¼·´°¹··ÃºÆ¾ÃÉ°žºª¢¬¥¨¶‰€}o]`_\U`]heRXaVRVIEFMK@>HD=KB=B@=F>;H@796379>489:57045/26389374526?8@>GKRTTRPOQRQJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKE@IMPRLQ]gmlq…slsrsˆÕÀµ™ •™š‘Ž—‘––Ž†‡}‡ƒ–‹ƒƒx{‹„‡{‹yŠ‚—t}zlepvY]\Peeb`ed][XW\MdmURmn_o_XgeUYTJDAKKHFHHHHBI9D?HKTTV]Z\“¹À¹½·ÆÀ»¹ÊË»·º¶¸¹³¸µµ®¶¶™du©ž­p^¢­œ˜¡¢›¤ž«¥”ŸŸ”–˜—¨Ÿ¥Ÿžš™ƒ¤¬¤ª°­·°¼¸ÔÐÎÖÏÉÌÒÌÏÎÊÇÀ¿ÂʽÁ½ÂÀÅÄÆÊ¿ÉÏ´¤»±µ°›¬¹½š}wi[^ZX[_XabQ[`SQKCBEFE<@F>BIB@D=:E>=J?47535;=468977022/24169775555D3ELM>510006:477@IOJ;-&**(-./,@M+/54m‰I0H‰t?>BD@CDFKODR\Yi`o—’‘”nlotu‡³¬¡¡Ÿ‹™œ™•‘›’…ŠŠˆ‡ŒŒ‰|ƒs{Šƒ…{Št‚Š†•s{ylmu|iseilifjii`fihmZmt—­¤¼‡‡g[oh]ZYTHJNPJKQLTQHLAJGKP__bgjb—·Ç°¹³»¾¶±ÄǶ°¹±°»¬³±§«·¬¶§žœ§šNšžŽ –‘§˜¥•Š““ˆ‘‰‘‘›¡˜›•–‡ž™¦š¬¯¨¯§³³ÓÔÔÖÑËÏÓÔÎÓÏÌÆÃÊпÊÉËÉÒÈÍÍÃÑÒ¸¯Ä¼Äº¦·»Ä¢laZ[\W_WXdYO\WNQCBIECI;AD>AH??B8;D>@I=46655;:687654/10146278875367C5B8?-0,1348=97,.,1;FL=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYSfWs™ƒhqoyyƒ ªž¦—››˜‹•‘šŽ}‰Œ…ŽŠŠ‹ˆ|„‚p‡†{‡rƒ‘‹~qyulpxr{nxsli€pmcimpyiw}~Ë¿Âߧmcxod[a`JPRUNY^P]]NPNTQUT\nnwƒr–®¸¬´¨°¶«­½Á±«µ¦¥¹§¬®¡¬´¤±®›˜˜Œ‘”‘„›§‘œ‰ƒ‹„Š‰„Šƒ“•˜—”›‘›˜™™žž«¬¤§¡¬¬ÎÒÕÑÍÌÒÓÓÐÔÑÎÈÃÔÑÈÎÒÓÓÖÍÒÑÅÒÖÆÁÏÈÈ鿸Мwlc[`[U^Q\ZOOTPNH>AGBCF<AB?FE>@?:===<JA45465<888664412/03526768533;=<E=@11+/349?5901022-2EO3)/3.32=N248C}_2A†tD:==I>@CFH<VRMO[u‡†‹wmwp}~€¡žž¡‹™““ŒŒ“–…y…Ž‹Šˆ‘‡‚{r~€‚‡z…v…“‘‰€pwsls||w|s‚xqk€rrioqzys{¾Ëš~Œ±ƒvr…whaj]CZZ[WfdXekTX]]`c^cx{‹™ª¤¤¢ ¡¨§ª±¹«¦´£¢®¢¤®¢§±Ÿ‰¦›•“‘Š’ˆ‚”‰k•¢™„†~‘ƒƒ“—­‹••™Ž…’—§°¢  ¤¤¨ÇÍÏÇÁËÐÓÑÔÒÎÓÍÆÖÓÌÔØÖÖØÕ×ÕÉÔÚÍÊØÖÑÊ­ÄÃ̉pm`^]VRWQ[OJGJIJ@;:;ECD<CD>HC?CB;;9<9GC46544<5687543250/2546745544<>=E?A62/-16;=081/254/-.;R017/532ED28>nb5=tM99@I<AD?A;PLFKYp€u~isyr‚‰•ž”…‹–‰ŽŠˆŽˆ€xƒ”™‹ˆˆ‹‰~ƒxs{}ƒ‡w€{‡‘—„oxpmuvx}t†|yl‡vun}v„uy{µŒ<AŠÆ¥~|jeWICecfchjdoy[_fhknin€„ˆ‘ŒžŸ ž‘—˜Ÿ¤¤¦²¤¥³ ¢¥ž¡© ¢±œ‡Ÿ’’“‘‹Ž‹†ƒ„~œœŒ‚„…z”~‚ª•£Œ’Š˜’‹}—Šš‘«³˜š›§œ§½ÃŹ¶ÅÍÑÐÑÏËÒËÉÔÎÑÕÚ××ØÔÙØÍØÛÎÉÚÚÒÖ¿ÌÍ´utlb[XQSPXUEFJIEE=:7:@AB:GE@EDBDA;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?1*(.BT29254/7K75<`bA<svV87AH:?C><9QECJTlnopbqqs†|—‘‹~‡’‚‰†…Šƒˆ}y…——‰ƒ‡†‡z„yqz{„†uz†ŽzŒp}opzr{€q„‡€nŽzuw}|‚u|‡‰°tYªÂ·’pnc=^hrpqpnxw‚eioruxr{‹‡Ž“’›– –ˆŒ“› ›ŸªŸ¡¬œ¢ššŸ¦ŸŸ¬™ŒšŒ‘’Ž…}ˆ‡ƒ…‹Ž ™“ˆƒ‡~m™y„™†ˆ“ŒŽ•Œ†{›ˆ“®ª”•—ž˜¦®µ¼¨­½ÆËÈÉËËÏÉÃÒÊÔÖØ×Ø×ÔÛ×ÓÙÛÖÏÛÚÑÖÈÕ̓vxfeYXNQR\GBEII>A>=8:=?;>H=@BAADA>?:87DB755479.566435532323647553457EBDCEB56<FNSM[nfcnsk`V>,4LG865433BF4=W_hLux^8;?F<<B<:9D?CGRk_mdbfkv€ˆq‘›€y€Ž~ƒ‚‚…„|}„˜Ž‡‹~†‡€w‚yn{{†‚tz’ž¡vvƒtu}t€„o‚‚o’„u|…zv‡|‰¸Æ¥Ãʸ‚–œxpeNec‚zw†¢‹yyw{ƒ|„vm”–”•˜‘ƒ‰—š——¦œ˜ —Ÿ“’—£™«–‘‘‹Ž’ƒŒ…‰ˆ†‘žœ™‰…‹…—{ˆ‰Ÿ—‰Š‹‚|¡ˆ‹¼¡˜“—™œ¨¥¥­ž§µ¾À¿¸ÇÉÍÎÅÍÊÑÖÕÔÙÕ×ÛÔ×ÙÚÛ×ÛÚÙØÎÜƅxvdfb]RVUTLKDMD;==<9:<>9>A7>?@=@><9867CA6455=80665547745613854564557HH=DJE7925;H>;::7HP\ZRUXK9T>;95327I8=NYMHxxd5=>C=<@:6:>>@EQ_Yfa][htzyl‰’wvzŠ|~€€}…{~‚‘Š…†z…ˆ{u}um}}†~t’‘Ÿƒ’|†}x~y‹Šoƒ›€t™†}‚Š…|~‘{©ŽÃ ½Œ›¤œ~Š„}‰rŒ‹s¦šœ™”…{‘‰„iGq¡¤Œ‹’…ˆ‹‘“•›“”‘—Œ•Ÿ”¡”’ŽŽŒ~Ž‹„ˆ’–šŸŸ‰Œ”‘‚Œ¦™ˆ…Žƒ…„€¤†Š‹¸˜‘”–¡¦ £®¶º´«¿ÅÊÐÈÇÌÏÓÒÒØÒÕ×À×ØÙÛØÚÚÙÙ×Û·wvuhgcT^YRONHCLC==>99;:99<=6@>>==9::;37D@8378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWN<MTHN?96333>C;[X>5YypZ<<A<=>8589?<DRSRX^UXfmmmiŽŠqsxŠ{{}€|ˆ{}{‹‡ƒ~uƒ†zsztm~„}w†›¡›ž”’€Œ‡˜‡€œ’nˆ©…z ‹|‘Žƒ‰„œ~š‘‰£¢Ÿ¤¯ ‹‘‹†‹’†Wr­‹Ÿ¬œƒ˜œŽ[ƒ¢‘‚Ÿ“•Œ†ˆŒ’“Œ”••ŒŠˆ–›•–‘‹“”†€‹‰’ŠŠ—™£¢†“• ŠŠˆŽœƒˆ€ƒ‡…¤…‹³˜œ’”—¡¡ž™’›§±¸¬¤¼ÁÇÍÇÆÏÌÏÌÏ×ÏÑÔ®ÖÕØÚØÚÚ×ÖÙٝmzrddZZVQUVC@ID??>:49:;7:;:3<<?=>7;9:1:G=:27=@50677255?65;55858:57735HR7GOK994=EJB>1FCLA98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:;@;BQKKSYPTcbxlb~’ƒomw‹xz{}†|{v†…€sp…‚{uwvt„ƒ…}’¦¢Ÿ¦¢—Š”—ŠŠ§—rŠ²„§’„™”…šŒ£– ˜“‰›ž¢“©° ‘•ŽŽˆ•‹n·„šÄȲœ¢¥›˜–‘±d¤ÍȕŽ†‡‰’Ž“”Š…ŠŠ†–š›”“‡•˜„‹™ˆŽª——¤¢ˆ™ž•š‰†—˜Š…†¥ˆ“¨š—“—™¡˜Ÿ™“œš¢²´¥£¼Á¾ÇÅÅÉÈÉÂÊÓÌÍÔ¨ÒÑÖÖÖØÚÔÓÚ΀p|e`[\\MISXABGD;A>837;<:8=64::<:72?9929I:>67BC32:96264>=4;>6949;57944KQ<JQK9A7BGI@64JELF>;88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBc‚Gv}|m~ˆxz~{‚‚ƒvv€ƒ|mn‹z|xx|„‡Š~‹£³§£ª³¢—§Ÿ¥¤–•®¢ƒ‘¸•‘³šŒ¡¡Œ¥›°£¤˜‘§–¨™¬¯¤˜•–•‹˜™—¡ÀŽ£É¹«›£¦­™’›²……¨¢œ˜…‰‰Ž•‹“ˆ†‡‰“˜•Œ‹”“†•˜†„‘œu‘˜²––¤¡‡š’ŠŠ—›‰‹–Ž‡}Œ˜ž‰œš™“˜—Ÿ“ ”ž› ±®¢¤·¾´ÅÇĽÃÿÆÍÊÉÒ¦ÎÍÓÒÑÖØÓÐغpwsZ^S^TOHIMEBCD5>:77:?<<7=43669774=5;5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=88567=:JFDGN[\YJf`;H„‹zzn…†z|„y†~px|~}orz~‚|x†‹‰†„’§»¬¨²½¯¥­³³¨£¡°¬Ššµ¢¸¥•­¤—©­¸§¥£Ÿš©—©£®°ªš™œ”•‘—Ÿ—š»»®Ê¡j¶¸«°”™Ÿ£¬“—½£^ª²ƒŠŠ”‡|ŽŽ}ƒ†Ž”•ˆˆ’–Œ•‹–˜“™´—•«Šœ”’Ž‘’Œ™›Š’ž‹‰•Ÿ¡”˜š’œ˜ž”¡ ”œ¥¯¨¡¥³¸«ÂÈĵº½»ÅÇÇÂÑ ÆÉÍÍÅ×ÖÑËÓ nxfZXQ\PNEC><CAB8?885?G=<6<35345454B39:BM:B;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPdGb`bpJ?‹Š~s†‡}‚‰uƒŠ‚m|}}pw‡wŽ‚‡{Œ†Œ™ªÂÀ¯½Æ»³´À¼´­«³¶Œ¨³­­½«›»¤¨­¹¸«§¦¢¢¤¢©¯²±«œ¤˜›˜—ž¢¦¥’¤º¯©À¼­­²¹¥¤¨~ˆ†œ­¼°ƒŒŒ‹ƒŽƒ‘z‡œ‰ˆ—‹•–”‘š—¨š±š‘¬œŽš’Ž•–—Ž‘ ‘‰”›¤¬”–”œ“¡›˜Ÿ¡”šž§¦¤¢¤°³§ÁÆï°º¶ÅÄ¿ͦÇÄÇüÖÑÍÄʆrp_YW]YLJAK@FG>A?B;:5>A==5<6>333242A17@BN>G@CNCA=C=;86CC5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GD?CF\eG`igZ]\“Œ‹ˆ{‡Œ‡ƒŒu†‘Šo~{q~{•z’””˜“•§³ÆÉ¿ÂÌÂùǼ»¯«¹»˜³·º²À®¥Á¤«°¼½«®«££ž§«®´°ªœ ªœ¡›–Ÿ°µ§‹£ºº¶Á¼¬©œ²¥¤¨”…Ž©Ä䂋‡ˆ„†•”zƒ‘‘¢ŒŒ”’Ž‰—Ÿ˜“™•˜¦ ®ŒªœŽ–’‘•••‘¡”†—Ÿ ²ž”š”Ÿ ˜¤Ÿš › ”˜ž¥£¦¦¤¯®¥ÀÄµÉ¾¶Ï²Ä¿Ä¼³ÑÊÈ´rvjYVYhPLHBLKKJAA=CD<5AD;;3=8B332262A05IEN>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBeYNe\fTcj™—ŠŒˆ“†‰y‡”r€|x‡‚‚zŽ¡–¨šš˜º½ÇÈÉÁÒÉÊÂͽ³­¼¾¨º¿½»Ã·¬Â©¬³¼¾ª°ª¤¥¤¬®³­¶µ Ÿ¯Ÿ¥¢˜£³½©›¨½Á¤¶·°¬“±­¬­—‡š©§¥‘‚Œ“¥•‰vŠ‘y…’žŸ“”Œ”£™–œ””£žªŸ‘¥šŒ•–ˆ|•’’¢š•Ÿ¡œµ¥ž—¥£¢¥ž¦˜ž–—›¤£©§¢²¬¨¼Àį¥²·Ì¿¹¯Ä³»¾Á¸¬ÂÃÂÀ—jw`VUZYIJLIFDDHCBADL:4DH9;4<7E.12352B25SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQG7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>jH_XaZddVžŽ—Žž’‰ŠŠ “„x…•ˆŠ€–¡™®¦¤˜Â½ÇÃÇÅÓÍÎÍ˼·°¹¼´½Ë¼ÃÁ¶·¼­³¿º¼®¯¨ ©¨¶­®©²·›ž­¢§¡ž«·¸ª¥¯¿Å±½¹´¨ªµ´®¯—–¥¬¨ ‘Ž’²Å§•Ž}’•}‡‘™ª™˜““’–“¥ž’™”¡£¢œ˜Ÿ˜‹ŒžˆZ–—’—¤™e˜£Ÿ³¥–¡–¬¬©§›ž¦—˜–—• ¤¨¥Ÿ¶«ªº»Ã´¥³µËÀ¸ª¶¬²»¹®¨¸º½¸ilXUSSMDJRMK?AHEDHHH95EM;>8=@J.32025C55OVN<LFKRLOHGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|gV;=@BFBpEiIRebLF¥”›—¢—©–ƒ‡¦“ˆ‚‡‚œƒƒ•”š¢Ÿ¯¾¯¡Æ¼ÄÄÆÆÎÎÎÒʾ»¶±º»»¾ÏµÃ½¸¹·²±µ³¸³«¦œ«¬¹ª©¨¯¯˜£¯¤§¤¥µÀ°¬¬´¾ÃºÀº´¨¹µ¹³¯–¥­®®¤‹“•¡tÁš}—™„Ž–šŒ±•›š•’’šš¥£” ›—š©œœ¡ ™Š–œ`J–œš•š¥–U—°Ÿ¯œž¤”¯®«¥š ¥”“˜˜œ §¢™´©ª³»»»ª°²Ç¿¹¦««­²²£¡²²´¤nkcZXMOJDOOPQ;HKIGICC>:KT?A:=EM07544:B44MWO<JKOUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@BAF3>58JKCA=C;4EA:A?>H@5*B52,>c]g:35tde@R7&#3}hW;:BC@=QEWSsbWFHª—™ ¢¨¯™‘˜‡‹¨–Žˆ“…Ÿ‡„—Ž¡›£¤µÈµ©Æ¹ÂÃÇÊÉÈÌÍƾº³®¹¹ÁÁ̵ǺÁ¹µº°¯¯³µ§¤›ª´µª©¦­¬š¤®¥¤¨¬º¿¨¬¶·¾Â¿¾¹´³Ä²¹½¬£¯µ¬¹¦ˆ›—¦›v¿Ÿ„™Ž“™š‹®—¡œœ—”š ¡¨ž§Ÿ™šª™¡§ž˜‘ƒnv’£š•¢®²¢ª”¨ª—ª­££Ÿ¤¨‘‘™›‡”œ¢ž–±§©«¹¶½³²®¾¹· £§¨¥¦œ›­©©‹`c^^PIKFGMIVL=MENKLBCD<QV=AABDO18=77?B75TWN?HNQYSPQUKQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW;:=.-R`MUHe^HE«•›¡Ÿ»¯™”ŸŒ“«›‘’“‰«†¢ŸŒ¤­”££¶Æ¾´ÀºÂÂÇÈÅÂÍÈÁ¾¹²¯¸´ÁÂʵŲÁ¼µºª©­­°££˜ª´»¦©¦«ª©¯§£ª«¾¼¨­½´¸¾Ç¼·¶¸Á²¾Á´©µ·«¾¥¢—’¢Ÿ¼Ÿ‰š ™—žž·Ÿ©œ¥¢›œ¡š¨¤³¡›¦œ¨©ž™•”›‹—‰Œ¤¡”¢ µ¯¥¤“¯«™«ª££¨””Ÿ‚žž›•©¤¡¡³´ºµ­¨µ²³žœ¢¥š—”™ª¡žu^Z]\IGEFLPHMEGGCSLJBEGAVRDH=AGQ1;B7:BF79\YKALPTUSMWRNUJE@JJNO9C@5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-19f\FCCœpbGE§—¤ŸžÃ­›—¥˜š©œ–››ª–•§¦•­¬™¢«¶Ä¼¾·ÁÂÀÇÿÍÆ»½¹²°¸³¿Ãȵ¿°¼·¹·¥¤«¬­¡¡šªªÅ¢¤©«¦ž¬¯«¢©¨¿¸§­¾±¸¶Ç¶µ¹¸À²¿Â·µ³´¯¾£—£–”›”® ¡£¥££Ÿ½¤©ž¨« ›¥Ÿ½¢™£Ÿ¢©«¡–•ž“ž‡„“Ÿ¤ žµ¬¥›•±§™¯¦™ªœŸ˜”ž„ š›’¥¤š˜«±µ±ª¥ª­¬œ˜  ’Ž•¨ž”f`X_\NHGJMKHEDIA>QIA<GIH[ROK=HOU4BF9>HG5CaZKCNRUWVQXTRUI@8RQPM:GA4CHQSIC;C>GVKC@O>K<06;GF>;FA46@9:?9;15D0-,/Mv\4KZ5,MnW<-=)#zbQ5CKQ:mRF<KxeaVK¢š£œžÅ¬¡Ÿ¬žž® ’£Ÿ–¥Ÿ¦ª¬—¶±£ª³¶ÄĽ¿µ¿Â»È¾Êǵ¸µ´°³´·ÁŶ¾±¸µ¸´Ÿ¦¬ª¬ž¥¤Á¤Ÿª­ ¤©­¯¢¦¨½µ¥±½¹¶¶Ä²´¸º¿³ÄÁ¸¸®³µµ£¥•‘”¡® ™¢ž¨¨«£šÂ¬©ž¬­››™¦ ½¡¤˜««¬¦¢™šŸ’Ÿ‰ŽW–Ÿ¥¡ ¸ª¦“˜µ£Ÿ± žš®–˜“ŽŸ—•Ž¢£–¦®²«©¡¡¥¥••˜‹‘’¤ž‰_bXb_KHJJNEEAGK>=JB99JJN]QQI=LV\9FI=DMI8Hb[LCLPSYYVWOZ^IA=WQIK?H?5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+w`S6SZkWrGE6=ue\KNžŸ¡™žÃ¨¥¢´¢²§“«¥ £Ÿ­©¬»°¨¬¶±ÈÅÁ²ÂýÆüÄɼ¯°¶­°´¯¾Ä´¹±°¹´¬™¨°©ªš¥¡¨Á¬›¬°œª£®±©¤¨½¶§·»¾¯·Ä­´³ÃÀ³Ç´»·«³¶­ª¢¦–•”¤¬¢ŸŸš¨«°¯¯»²¦ ©¨™™—“¢¤¸ ¡£“¯¯¬¥§Ÿ’¡ž•ž•žš¢ž§³¦¦Œ˜³›£®™›¬ž“•“™‘¡•Ÿ¡“‹¦¬¯¥¦¡œ ž’’š“…‹‘œ_dZfdJIKJRBC@IH;;G?99OMU^RSJ>O^]=HPBLLI9Nc\LELRTY[SUO\bHA?ZQAHAKB7FELKM?;BHDNB=;N@A3/97CB97F;+6<46<35-/4@1+'VtSeO?104b[M23>0<v]^?[T^eq@8;H–weA4Ÿ£ œ Ã©¤ª³¡¤´ª–³¬§¢¤²¬®©»±­°µ´ÆÀÄõÀĽÉĵ¿ÈÁ´«µ¨°¸¬¿Ã³·®¬¶¹¥˜ª²«ª˜Ÿ¦—­»´›§°›­ ®´²§«¹³¨º´¸²¹Àª·²Ä¾µÆ¨¿¯­¶µ©§¬¡——‘¦¥¢¢˜˜¥¯¸®²µ¶ Ÿ¨¤š••“¤ ·¢¤¥–¯±²§ª¦¢žšš›–—¨Ÿ ˜¡ž®²¢¦Œ—®˜¤ª—™ž¤‘šŒ“—™…•ž”Œœ“‹¨©ª¡§ ˜ž•ŒŽ™…•ˆ”žwbg\jiMOMNT=CANC::I?77RO]^RVQAW`\BJSHVKH:Td\NFON[W[RPQX]GAB[PBG>NC9HGHOP??CIBLB<2IA94177B>;7E7+6914802-/.<6-#Bqgsk23/1[bZ33806p[bH05IphVCWFŒyfC;¤£¢¦¿§¨¯°¡©µ«º±«£ª´¶±°¹·°·¸¸Ä½Ãǽ¼ÄÁÆÀ¸ÀÅÀ¹©¶¤¬»­À··©¬±º¡”­±­²–¥§‘ª¹©Ÿ¦°« °´³ª©¶¶­¼­³³¹·¬¹°Ã»¾¿¦Ã«°·®©««§ž˜™«¡¢¡‘—¡±¯³¬°¹šœ© ™–’—¦¡¶©¥£¢°±´¬³¨¬Ÿ›  ›¥œ¢—£³°šŸ“¥šŸ¨š“¢ž”—ˆ“–’•–œ“ˆš™”Ž¨¨¦Ÿ£›—›“†Ž˜‹}Œ–…™igk`lmWPQZUABET@;;HA7:XPd^PVWEY_]MLRN^KJ>Zc^NHPO\UYPKTWZI?DXPDF?N@=IGGQPB=DFBM?:1D?77547?=95E4+75/251.-.,1=*'+=\p=>1.0dZd@1647gY`F(?8l}g[V;‰{cC=¨Ÿ¢ª½¢«°«£±¸ª¥¶´¬ ­µ½®³¸»º½¶¶À¿ÈĹÄÂÀÀ¸Ä½Á·¯µ§«·±¼¾¾´¨®±¶ž–«­¨®—¦¨Ž§»Ÿ¤¬³ž¬¢±°³¬ª¶´µ¾®°±µ¬°´²Á»Å·«½¯±¸¬­ª£±¦ž¥ªŸ¤˜™Ÿ³ª³«ª³š§›š•Ž ¦¥´®§¡­­®±§´­²ª¤œŸ¨£ž•¡™›¨µ©–™‘‘™Ÿ«ž–—„”–Š˜œ“‰–—š—¦¥¢ ••—“”…{Ž’‚‹•dkqgoq^FYfVDBMXDZ9HB6>\Qh\NY]G[^]NMRXdJJC\b_PLMNXWXPJVVWL=EUJEDAM@AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,,%2+*5K1/'__`U150=`V^8)C3YT\gK6ŒzfL@¤š¡¤¬¶¥­ª¦¯®·ª¯µ»§¦±·Å·±·½Áµ´ºÄ¾ÌƹÂÀ¹¾¹Ã·À¹±´¬©º¶º¹¾´©­°µ˜˜§«ª¬›«««¾ž¬®²£«Ÿ°­³®®¶²¹¸ª®®±¨µ¯´¼½Ê³ª¶µ±´¯®§¡³ ›¨­ ¦––šš²¢­ ¥¯—¡¤šš’Ž£¦¨³©¡¦³¬ª¶¥¯±µ¯¤™­§š˜Ÿš™«·¢—“‘Ž—œ¡—–”«žš’’—Œœ™–‰”’ž™¥¢¡ ˜–‘“•yŠ…{ŒŠ‚‰‘jmwmu{`E`kYIHZZ={JFD6AbTi[M\aJ[]ZRRRbaLKE_``QLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T`U`/5(C_Q\.+B/JGP[H3cYUKD™—¡±¨±ª­¦¤¯®¶©·µº¤¬´·É»´ºº¿¿´³·ÃÀÌȼü¶½¿¿·¾¼±¼­¦º¹·¶Â¶ª¬°·”–§®«¨£°ª”¯»¤­±³§¨£²´±²±µ±¸³©®«²§·¯¶´Äƶ©¶¶¬°­©§£¶  §±¡¤”œ™•±ž§œ ªŽ©¢ž›–˜¦¦¥¸§£²µ¬¨²§®±¶¬¥™ ¬¨›œžœ”©¸œ”ŽŽŠ˜›¢—˜¥ œ”‚”œ›—–•ˆ–˜š§œ£ ’–‘•u„‡{„ƒ‹Šlovt{~\Kem\JNc\?b{GI8GgWe\L^bMXYWTWTi]OOHa]_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANHf27'GbLV%-B-=ELQ<3rkICC™¥®¥­¯«¨¥±³´«·²· «µ¹É¹®À»Â¸³±µÂÃÎÅÀÁ½´½¿¿º¾¼²Ä§©¹¯¶¶¿¼®ª²±› §±­¦¥¯¥²µ¬«±²­ª©´»¬µ³µ­´¬ª«¨¬©¹­²±ÈÀ¸¥º°©¬¬¥¨®°¦¥£¯¤©œœ›¯š££¢£‘¬ž£ Ÿ¢ª¦¦¹¤¬µ¶¥«¬¨­¯¶®£ž£©ª› šš’¤³™Ž‰‡¡ ”Œ”œŸ’‘ƒ’’œš—•“‡—’•™§›ŸžŒ’‘v}Ž…|{{†‰ˆprq}||\Sdn^NYf\FD–[G;NmXb[L`bNVVUWTYg]QRLcZZTKGOTSNGIVS\N;P^IBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/,1()+,-*&5*/&0)38:1&*3Bc:6*HeHJ+:H?3BHS,>k;GHœª«¢ª±¤©¥³´±µµ²²¢«®½Ìº®ÀºÇ±´­´ÂÃÑÅƾÀ²¾Á»¾·»Ä§¬·«²·»¿¯«±¬Ÿ£§­ª¨¤°¤ª²ª¯¬°¯°®«³¼§·±²©³©«¥¥£­º¬ª²Ãº¶­»©©§¬©¨²¥©¤£®ª¨¢žœ£­•¥ž˜ž™¬¢§©¢­¦¤­«¸²²¡©¢ ¬¯±¬ž §¨©™¤™™ ¦—†„ŽŠ‹žŸŽŠŒ•›Ž„†”Ÿœ”—”†–”“—¤›œœŠ’‰~~‡…|w~…„…rqpˆuk_Z`nbQsq\K;„|E?WtXaZNc[NVVUWQ\b_SONgXWVKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*25>10485(5/*,.30;),,'%234$,2-860)(1<]J0.JgDF8<B05EKX1@•Z>LE•˜­¨¢«³œªª°¶­¹¶¯«¦«ª½É»°½·Â¯±¬³ÄÃÎÏþ¿´ÀÂú¿³Èë®·­²¸¾¾²¬­«¤§ª°©§¨±¥´®ª°®­²±´¬´¼¤·³¬¬®§«Ÿ£ž°·«ª­»·¥·¶¤©§««ª­¡©§¦±²¤§¥¡¡¬—ª¡•› ¦ž¤¢«¤­£Ÿ§±¸®®£¦¢›ª«®©¢¥¤¤™ š–˜œ’‚ˆ…œŸ‹ŠŽ‹˜Š‚‹—£›‘š‹“’‘“£™›šŠŽ‹‹|†ƒzt‚€|ru‹¤‡xj^`nfWe‡cN?g“LEbyWbYReTMVUUTO\]aUKMhVUWIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*39?./463)4+*,+.#4.-+&(+79*&6+<-2,&06WZ.0JgAA<<B+:JO^4D†>HFD—’°¥£«±˜«ª­¶¬¶²¬¦¬ª©¼ÀÀ¸¸³»µ¦²¯ÄÉËÑ¿À»¹¿¾Á¸Á¹ÀÄ­±µ±³º¿½²°­¬ª«§¶ª¦­¯ª¹°¨±²®²­·ª··§´·«¬¤©ªœ£ž³³¨¨¤´µ ·® ª¨ª¨«§ «¬©¹¶©ª©©¢ª ­œ’ª¡ ¤¢¦£ªž§´¯¨¦ª¢£˜¥§§ªœ£¤£ š˜ ‘Ž˜~‡Œ‡ƒ†ƒŠŠ‹‚…”¢šŒ™‘‘“Ÿ–˜–Œ‹ƒt‡~xt‚~yv~€‡oqggpw\asˆkO^™VHmxUdVQcOMUTTPOX[bUHPiTVSGPYUI>IHOQPxLMV=<KD?@A<@CUC9AK=5;E13;:7*4:=+-341*8**+*,))(/*&)%3;,$2)2021%/2Qb02?f=NX>C,>LT_/Ji5OD;–Ž±¡¦«®š¬¥­°´µ°¬¦°ª©º¾»À°®¹®¡·¯ÈÇÈÑÀ¾½»¼Â½ºÃÀ¾¿®²²±µ¼ºÁ±±²«³¨¤µ¨¥­³³¹±£®·²°²»«º¯ª®¶¬ªžª¬Ÿ£ ¶­¨¡Ÿ°³¢µªž¨§©£ª¡¢¬­¨½¯¬®¬¢¨¨Ÿ¬™°¡˜¢ §§ž§›™ª±ª£ ­¢¡”£££§˜š©¥˜˜˜žŽŠ‡”‡}Œ†„ƒ£–„€‹†‹ƒƒ“ –ˆœ“‘œ”—Š…†xt|uxyzssyg†¤ui^dj€tgˆŒ}SXp^JwsSdTQ^MMRZfNLVYdXFSiRQ?CNQaQ:IHLSIqQLS;<I?;<=;@@W<<?H73CB15:93-5::)-31--5)(+-,42#2)',%.;.&1.0-14%,0Lg:48_=ad?F1CP[[*HM9UA4²¡¤¦¬¤§¤­§µ³±«¥°§ª¸¾À¼¯§¹ª¦¯°ÉÇÈѼ¿¾¹¾¿¼ÉºÀ¸°¯´±º»·À²³º¬¸¬¢´§§¬²¶¹³¨¨½¶®¶¾°½§­¬µ¬­œ©¯¤ ¥­«§œž«³¥´¨šª§©£©ž¤©¨©½¬´¯­ª¤ ®œ›³£•¤œ¥¥Ÿ¤›š©«¦Ÿ›ª¢›“œ¡¥ž˜—©©’˜š”Š‚…~Ž‚€‡…~}‹‡„“š“…’¡Œ”‘‹‘›’•‡‰~r{z~|hx|ztop{g„x„ˆdagaq„zmgx]]U@VzlTbPQXKLNru]HZ[gYEUfPD>JNDCA9HGKS?jbJQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11'/>KH0%90%,,09/,,+6'17#-0GjI14X=fcAJ7GS`U*=9DW>*”²š  ©¦¥¡«¥¸³³¦ª±§­¸Á½µ¯¢¸­¨¨°ÂÉÉÌÁ¶½Àµ·¿¹ÈµÂµ³²µ²¼·¹½µ­¹µ¿­ ³§««°µ¸µ¬Ÿ¾½ª³Á´¼¡¯³µª«Ÿ­°£œ¥¨ª£ž›¥±§° Ÿ«©§¡©œ¤¨¡­»¨®°­ «£¤¯žŸ­¦—Ÿ›¡£œŸœš¤ª£››¥¤–—•Ÿ¢–›—¦¬Œž‘‘‘‹‚Š€€Ž€{™“ˆ{~‹†‹Šƒ’˜‘†“¢‰’’‡š“€ˆ|yl~vyxc{zqooqvg€sjƒgdg_lrlaio`o>ZxkU^OPQJIMTYWM]^lWDX`O^PHMDF;7HEKO<rhKK9AE;;==;;=J49B<3;G<4?18-68;2(09/,4/.=-*K>*49&'.34.0+/4&,:$41AhY13S=e_DL6KVdO*;2NX=#“™­š ˜§¤£Ÿ¨¤¸°¯£¯°ª«¸Á¹³­Ÿ¸¯«¨´ºÈËÈ¿¶Â¾°´½·Ä¶Ã±®¹²³¿´º½·¨¹·½ª£´¨©ª±®º±ªœ¼½¥°Áµ¶¢¯·µ¦§§±³ ž¤¥§¡¥™Ÿ¬¨©ž ª®¦ ¦˜£© ±¹Ÿ£°¯¡¬¡­¤œ¦¦©šš›Ÿ¤•œšž©¦—œ ©“™”˜ž“™–¡ª‘šˆŽ†}‡~‚}| ŒŒˆx‚‹„‰‹‹…‡“šˆ•žˆ‘•‚Œ—Œ‘}…{sp}qtt`yxhnppnh}qc{mieb^d…~_ZrjqKJ~hXZNPLJHPRPIO\_nSDXZRhOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23.:;83&2<0,85B*)-C*,4;NN@;73-.+-7**<%53<fd24M?e]FO=QZgH*>/XV5(—ž§š–¬  ¡¤¢¸«²¥´´ª©¹Ãµ³­Ÿ·­®­°µÆÈÁ·¾Á¹±´¼¶¿»¾¯ª½°³¾°¼Â¹¨»º·¦§µ¨¨«±­³±¨›¾·¦­¼·²Ÿ±¸°¨¥§¯±›¡¤ ¤¤ —›¯§¡Ÿ£¨¯¡Ÿ¢”¤¤¢·°¡¦°«Ÿ¬£¯˜œª¤¨ž—šž¥“›š¦«š¦—–˜”Ž“—¢¨¢ˆ‹…z„~„ŠzŽ–‰†x‡ƒ‡‹…“˜Ž–˜Š—~†—‹yzprwoot_ywdklkhg‚merkkehYas^ZkuiYG|][XONJHHRUF2:^^lPDXVYeLHJEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<#8R=*113>D5,-'42+;+139cl84GBg[HTCT]hE.;1^S,2–£¢˜•©ž¦¡£¡¸ª°¡»¹¦¬½Ä³°®¢µ¯­­¯´ÄĽ³¾º·±³¹¸º¸º®­¿³´¸¯¿Á·¬½º´¥¢³«¨ª³¬®²£Â¶¦©··«Ÿ²»©¦¥¨¯«™£§œ¥¦”˜¡³¦™ž¥©©›¡ ”¥Ÿ¤¹¨¤§­¦ž¥¡¨“Ÿ©¡¡¡™›¡’›— ¢«œ›š¢–“•–›Ž““£§¤ˆŠŽ†y„|…†}œŒ‰Š†x€ƒ‡ˆ‡‘…•“’Œ•“Ž”{‚—Ž‹w~{lurmlsbyuhgigem„gghdfhi^fbifZezb`QsT[[SKIGIOS@!+i^jLCVU^`KHGEC.:B<F<6KPD8:D357==895?:;4>8@L=>93)8><:9*6@3.E4(+,>0-N?.+-7-1195,&.5-80576`tB3CDh[KWGU`hB377aM'2ž¤¤’Ž¥¦œžžž¤µ­¨ªº·§¬ÃÀ·¯¬¡µ®§®¯·ÁÀ½±Á·°¯²¶µ¸·µ¬ª¼´¯²°½À·®¼¼±¤Ÿ¶¬¦¦µ©«¯¡ Ä¬ª§±´«¬´ºž¨©«±¥˜ªž¨¥’š¦®£˜¤ª¡›¢— §¶¦¯©­¡¡ž¡• ¦Ÿ¢ ™›šœ’šž•¦ž­¢˜—Ÿ–”Ž•˜Œ˜š§ ‡ŠŠˆx…w‚‚‚œ‡Š‚‰{~„ˆ†„„–•‘‘’{ƒ•Ž†s}gypkjlguskbgdbtadefeiibgoY^X]lc`MgWZ`VIGHKLRX>9`liGBUS\[IHFEA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A<-5B37=++,0A*JK./*+3722(57$+7.72685\yN2>HiZLZJVbfA:3@cF%5œ¤ ‘Œ® š˜ —¥´²£²¾·¡±Å»¹°±£¶¬«®©¹¾¼»­À²¯¯®¶¯³¹²§«¹±¯®³¶»¶°¹¾¬¥žµ« ¡±¥«¯Ÿ¥Å¡³¥¯²°·­µž¬®¬®¢™§ª¥Ÿ•œ§¦ ™¤£©œš œ•œž­°¦¹§®¢¡ššž˜ž£š¥–ž˜›”š¡’¨–­©›”œ“Œ•™Ž””˜§§Š‰Ž{t‚‚Š˜…‡|‰ˆ„„ŠŒˆ’…“œ’’‘–Žƒofynhkjgqrk[hcar`dgjnkfjfdl\lmvq`SbhceZIFLMOXQPUaeT@VSYUFGFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24:5#3*)6.55465Z|]1:Kj[M[KXdc@A1HcB'4“¢œŽ±›”¡š©²°Ÿ¹À¶ ³Á»½¹±¦¶°©®¥·¹·¸¬»¯­««·ª´¹­¥²µ±¯©±¶¶±³¶»§©Ÿ¶©Ÿª£ª­«Ã™¯¥¯±¶µ¬¬ž±­¯ª¢›¤¬©œ•œ§¤™©£¥•š ‘œ£«ª©ºž§¤ —šš¡k¢•˜œqƒ–œ¤€v‘«¨ž––¡‘‰—™€—ŠŸx…“ƒmi~w„rl†Š†}„Š†o]d`g„—†k‹”’uw‹„ƒ€fˆ€hvifX]itnNPjcfq‚f^dfnki]]^‰…ˆhOKC7DTg]JHPPUUKHS`oteE[QUPFGFC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,,08>G701.*.*/668,#1'214:276Xl15Ok[N\K[fb>G1Oa<+/¤š‡•±›“ œª­«£½Å¯©·Â¸½¼­§¶±¦«¤¸´²³°¹®ª§¬´¥°µ¢§¸¶µ¨§¬¶³®´®³¢©Ÿ´«ž¢¥œ§¨›¯¾•¨§°´¸­®¤¨­ª«¦¡Ÿœ¡¨¨œ—¡¦¦œ›§¨’ž ˜Ÿ¨ª£´¯£¢£œ–˜˜—£ˆ¡’š†¡ˆ”ž¡¥§¬ž”““ˆƒrxŒŽƒ‡ uˆi—‰f~sy oˆ‡ƒ~Œ|¡ Ÿ™{‡žtˆŽv›Šl‡‚ƒnied{mrbT†mcmi˜qXipn†W]i[kjZˆpmyr‡h‡„Y^FM>F^MERVVQPRWTg]LYKRROEGG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82*/1<I9/01.*/(-4583%&2115>1<8Xƒt15Rk[N\L[g_=K1U_70(¦—„¬™™Ÿ«ª¨ª¿Ã®²º¼·À¿ª¤·±ª¬¦³µ®¯³¶«©¥±­¥µ³›¬µ¶´¦§¨³±­²¨®žª¡³© ¤¤š¢¤°·•¥¦§·½¦¬§©ª«§¦¢ ™ ¨¤š™§£¤™œ¥ª–“£œ””¤¦¦¡¶¤£ ¤˜•“˜“œˆ®˜•‰©‹˜£œ†±€¤­ž”šŸ•y‚Ô¨‡”À›Æxw±¥·–d€Àœ¿y„„yƒ|‘Êq–¼œÅ{r¶§º{l—±«°yhlX±®oei¼’¼nhzmpØ~Skb¶²~€q”uš¡ªVNWaOVNFT[XQPR‹\W[P@\EQNDFI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22BE/.32.+/)-/186- /416A1=:Wƒw11Tk\O[M^g\>L1Z\41!Ž¦“§ªŸ—¥­²©±Â½²µ¿µ¸¿Â«¦´­­©¨¯´ª¯¶´¨¨¦¶¥¨¹¯œ²²¶ª¥¤§²¯­±¦«ž§¤²¤¢¡Ÿ—œ¡ ±®•Ÿ£ ´º¢ª¨ ¬­¤¢›š¢ª ˜›© Ÿ˜¨¨‘œ§›”ž¢§£¡°£žŸ£––’˜’™…°kj‹ª~g…–‡­eqž•š§–q®¡¤~wº|k¡v±_j´[¥€eœ`fzfixj©e¾rg¦Œv±j|±xu’”cmm§n\„ Eig‡–Euœ`}f{£¦‚Y_‹«i€’xzj¨8J¯[WSlcZLOX_\WV;NˆOVV/ITSJCEF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3..53/+/(.0.:6/'$203B/=;U‚v2-Vj\OYL_gY:M5^X31’¢•‚­§¥ž£¤ª±·­´½¾°¶Å²¸ºÃ§©°¬¯©©±¯¤±º°¤¥¯³£©¹©ž³²°£¥¡ª­°¬¯¦¨Ÿ£¢±œ£˜•˜ž°¨—œ¢ ´³¡ª›¡¬¬Ÿžš— £ª™ž¥¡š¡§¤£›˜¡ ¬Ÿ¥¦ š ¡••‘–‘š†µ›µy…©™µ™w‡³›·“–—«–~k¦z…†‘”’w«gj±[¬{Ž‡”tˆpŽ†€ˆ—xƒ‚‹—Œƒ …°vwŸqkjl|‹O¥XHcc™~ch¥_yquR’‡^P©mcq}†€a/R¢n[Skg_LK\cX\ZB>°wWXA#MhFBDA@A19>88:84;:9<9:A:E::;6:CB8=?KNH:5:AFB@AD<FD;0201;F,0.840,.(/3,>831/2-D1<<S}n3+Xj\OXM_fW7J9aU50–Ÿ”ˆ³¦¦¡®©¨³¬ª»¶Â°¼Â­¸·Â«¬­¯®§®³ª¢¯¼«¢§µ­£«¶¥¥²³¨£¡§ª²¨°¨¦ž  °– š––—š ¯£›š¤¨µ®¡¨©§©›–˜ ¦©›Ÿ£Ÿœ £¥£•›Ÿ˜šž£«›¥šœš¢ –“‘““„Õ“™¹q°ÂƆ|֔œ»|›–¦œŒ¤z†¢¥‚z¬yU¯{‰~Ÿj¹Z¹w…ƒ}¦‚“|˜zªyŽ{±mŽ„t»…n•P¯§ÅŠQ zc`ªbsr†l—‡_Sµ´È…€‰|c¤3Bu]PjhdP@XfYdaJHMkJZSOYfZCC?E?0<<59;74<;8=:<C:F:;>6:@C;6@OLH<:<DHCBCD<EF81211DB./0483+-).323971#%5*>3==Qwj6*Yi[J[P_fT7G:aP72%œ¢’˜±¨©¥³ª¥´§¤¼·Á±ºÀ²¶µ½´¶§²±£±³¦ ¯¶©›¨º®£°²¡²´±¡¤žž§©±©´©¥œžž¬—™™——–˜¢¬ž›—©­°¨£žŽ¬¢§–˜œ¡¦¢˜¢¡£¡›¢¢§›ž ž•™›¦¡œ¦”››Ÿ ˜’•ˆ²nhµq«ˆpŽ¦r´ts¶{›˜¥œ¢~Ÿ¤~°uƒ‘ÒÑu[®|…¤n›ª¦k†…}­}—™{±s“x³e–t…žnžf”RɋZÂ\Ÿyb_­_vs†b—ˆ^Yʝo¿€uMKµSUÆdTQjceXAOj_liPUFI9=WR[VYHB?J<2?;5=<56>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>II:1746@>/.24252-).26,742&60;5:=Pqh9'Wi\ANT_eP5G=aM62.¢‘¥¯¬¥©º¬¦µ¥§¶»¼²»¿¸·µ»»´¦µ´¢²²£ ¬°¥˜§º®¤²±´¸ª ¥¡ª¤²¨¬ª¤š›©Ÿ–•˜™’“£ª¡˜“§«°¥¡–’¬Ÿ¥’”¡œ¤§ •›§§¢š£Ÿ®š¡žž–œ¢žœ¥”•™¢ž•™–’›…¬{w¨v£‹‡©o­Šƒ§„š™¢Š’™‹¢~‘—‡®…‚³\r³R®}‚‚£~q×}w„~†™šw¯†Š‘œˆw´ašeš‚•l’[°WKšu˜yf`­^vw‡g˜ˆj]¯w•Ÿxl5yÈ®²_BTo]g`EPl_pmVUM.ebhSYP;AD@L:5?91><16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK97<46:>/04333.2..18*.32%!03767=Pke>&Vg\@=V_cN6GC`I:77 “ ¸±˜³Á¬¨²§ª²º¸´¹¾¹¸³¶¾¶¦¸´ µ­  ©¬ •§¶¬¨±±«­´¤›©Ÿ ¨¢µ§¦ª£™ž•¥¢””œš’–£¦›”§­¯¥ ”˜©Ÿ¢‘¢š©¦¡•š¦©¤ž­¡œ ”Ÿ›ž ˜˜œ–—¡ ”˜‘¦†©}}¥y¡ƒªp­Œ¦†– ¢Š—–ˆ£‡”ª{€‹yo±Z¨ƒ‚ˆ xtØv‡t§Ž›’¤|•Ÿ„{²^œd }‚”m“\«\[“‘hgªcr{€j˜†q]«Z‰ kneOJC¡\ZMt]bfMZa_rt_JU5Jš’XHE=HFAM35A8.;>05A78@<6=<F?:<6?=B7.HVJE@H6KIN@IK@EN::@4.;>002154+*05/7,&21($$6671<OedA&Uf[?1T_bL7FI_C1=7¢œ™™¿¬˜³Â®«­¨¦´°¸±¶¿¹º³²¸¼ª»µ ±¥Ÿ¦§§Ÿ”ª±©°ª¶­ª¯¡˜¡ ¦¤¤º¢£«¡—›‘£ ••Ÿ›•˜  Ž‹©°¯¦–š§¦Ÿ’¤˜¨¬¨•˜©¨žŸ ¤­£¡ž¡Ž•¡˜Ÿ ’œ—œ•¡•–«›®nr´t©ŒwŠ¦s´yt´“¥£“œŒ‰¤‡Žu¸n‹{‹¢kk¶Z¡†e——h ¢§m”r´t“˜²j…’ˆ­ju´af¢n†’k—\­`N¡|‡‘Rs£ly~n˜†p\¯V<œwfTon.[§ObRkeblZb\`p|cSYQ>>mo2BB@?M9!7@6.;@37C58??3;<CDBJFMIF62JTKEBJ6IJP?HOCFP=<E50;;010/75,+,326/#00,,289/9N`eD'UdY>/U^aL5FM^91A8¥šœº¢œ±¿®­««§·©¸¯µÁµ½²°»¸«Á¶ª«¡§¤¢’««§¶£³¨®ª¡—œ¨ ¥«¹£­œ–™¥£–Žž¡œ˜žŸ‘“•«¶¯¦™“›¬©—Œ”¦š¥­£‘—«²¤ ž¨«°™¡¢™¢— ›–›—¡“œ©”ª™‡Ó“š»t±Ä€Ã†~Ֆ›¸y‰‘˜—‰Œ§‡y¢¶t}wv‚š²`ƒºyÀ|u¸bµŒ‡©}–¬©q{u¼ˆ§ ia¦Ž¯¢~Œt‡«}¾ns¼t²ƒux€Šmšˆqm¤t½]w}[ay¼jZV[iz^iadfbmyoY[YCA@r?CG+5H"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,;:08LXaF'TcX</T^`K5;L[-6@9§™Ÿ¢¼¢—±Â¯­©ª¬±¨¹¯·Å±»³¯¼°®Á²­¦£Ÿ¤¡œ‘ª¥ª²¤µ§­¤ –š«™§¬¹£­™•¡¦ “œ£ž˜žš–’¯¹°«•—£§§”–¥¤­Ÿ‘ ¨«ŸœŸ©¤²ž¢¤Ž§¢”¡š›—•¤˜° ’•©Ÿ…™¶€‘‘¸•x‚“›µwnlnsoy„Ž‰ržÁ»¼™z²¨p€t‘¹ƒ{††Š†{Š†—|¤»¹½œuy³£tv—ut°u˜žf†i¶trpw¶Œ^y}ˆgƒymyb‹¬pt…X[§iDdYTf_c]cQffqmuBMOLD;ZL?J3<0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITBKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7KT_G'SbW8*O]]=+;VV'=:<¦¡¡¿¦–³Â³«ª¨¬«ª»¯±Æ¯µ´¯¸§µ¹®«¤¢§Ÿ ™”¬¤®ª¦¶¨¨Ÿœ– £¬¤¾§¡ª—•œ‘¢›’¡¨¡“ž—’˜”²µ¶¬˜ž£¤¢‹’’¦œ¥«–©¥¦œš¡©§¦£¨¡’¬ž—¢ž—–˜ž°©“œ§¢k~iœ¨yˆs~›Žuze‡{¾¿Àºn’‚q”…_rjZ]š‰ad‡Ž•k`”cm›vb”k€š•”e^_bqš‰hrŒ|†”fj~qty~}b[xthP\nƒ|{ŠjXlyrIJo…pNsMDV\faL[Wfc^OZmvjrRODEM<HI<L>2,2A?8/5?C<9;@;=C>RVVWYZ[[\]`aaa`\UG5DFUEJOHFPIIH;8=51:.1;:./-76=5&"/*2,%;8-7IR_I'S_V4)P^L(3>[O'?2>¨Ÿ¨¡Á¤š´¹¶£¬¦®§¨µ²¬È¬°´­¶¤¾±³§¡¤ª£œšš¬§®¤¥µª¤›˜•¢›¦­©¾¨¨¥•”›– š“˜¥©§‘ž˜œ°²¾¬›§§¢‰“‘ª›¨¤œœ¬Ÿ£š›£§¬¡Ÿª¢š®›•¦ –”Ÿ—±¥™¢¨™œ‘žœ£¥š§£šššš–‚hn}qv‘—“ƒ‰´©…˜•ŽŠŒ˜–‡“•‰ƒ““ˆ‘”™“™—š ¡š›”Ÿ›‚z¤…li{}€u‰‹‚r‚xyvuŠ€{‰jstƒudw}vkpzl_b[ogLXYej_WYpzomfSOFR9OZNRO(+;JB635=@A9:C><ENSSTVWXZZ\]`bba_^^[TKCSGKNDGPLOI<:;489,2;820)6IRO8")+/2#4;*7FO[J'R^T10T^:+=8]K,<-@² ³¢¿¢£±±· ©¦³§¥°µªÉ«­²¦µ¦À¨´¡ž¥¦œ¥–– «§­£¤·¬ ™—– —­ª¦ÁŸ«¤–’œ—ž˜””¢žž£¨’™¨§²Ã¯™«œªž—–©ž«œž¡­˜¡›¢¥¯¥¡¤¨ž«˜—¦™š¡žžœ°¡¢§•˜”™”¡£–¤Ÿ˜¡Ž–”‹ŠŽ—­{•›‚‘€‰©¨…€˜–Š„ŽŸˆ{ƒ……š‘†…‰•Ž›—Ž˜ž£–™’œ~e¡³®„‰„w{Š~wyzogy€‰kuyˆrisyuƒ‡jtcxf_hdcdfjXk{qjk\SLPD_UF@??,4@F;45;>A;<?>>HNNOPSTVVXZ\_aca_^]]^]XVJKLBIOMRJ;<:786/3964.(&$-1..)+*7%+<(6CMLD/T\Q05M[17E4\G5<,@³ ¹¯¾¬«­±² ª¦²­¢¬³°Æ°«­¤³¯¼¤´œ §¢¡™—¨¦©¦¤¦³µž”•™™°¦®¾ «¢‘‘žš™”’–¡œ—©…©¬¢´Ç³Ÿ©¤ª––˜š§ž©œ ¥«”ŸŸ ª®¨¤£«¡¬›ŸŸ ˜¤žœŸœ°¤™Ÿ¨“˜™’¥š™©Ÿ›—fƒ’|e~šcxŒlhjz£«kd™—~g…Šeeihz¡ŽjgŒ—‘¢wkj‹˜¢ž˜rknz„Œ†yXe]…‚^l‹Š‚v[hsww‘€‡‚nx‚xsmy„swˆˆŽƒ{i…X]jsd]sˆik|qmc]QNWIdX@J3=F7?FD71<=?AC;;DGHHILNORRTW[^`aa`]]]]^_]ZUODHOKSN=>==6535554*&&%,*%.++'6*$;'/AI[I.6ZO6)EY/DO1YB;?.=¥Ÿº¼¹¯¬²°«¥¨­®°§®­°½±ª¨¥­°°Ÿ­˜ ¤ž¢šš§¬œ¬£¦¨©³®ž–££°¦¶¹¥®£š¡™“’› ˜™¦–{¥¬¢¨³Ã·¥¢§¯Ÿž•ž£ž£¤ª¨’Ÿ¡ž ª¯©©£ªž§›¦ž§ ¬–¡œ¥±¤˜œ«–¡Ÿ›“¥˜Ÿ«™ž~¾ƒˆr´r…ž…­hw¹Ä¸q’¡£{¦˜˜sª‚|ËÀÀ»qŠ£‡‚ž|–˜ˆžÀ½‚–ŒœÁÀ{z‘ŒšÂ¿}k¥²oŒoÊz›w‘ƒŽ€vyyq{€†px…Œ“ylu‘be^xc^eb^thmdbXLVIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^__`_^^^^___]\SMPGUNA@?=6468266*&%#)*&.+*)109*#>H[L*#CP/#F[3PY/UAB;/8–¢¸Ã´°¯¿©©”£¯©°¯­¦²µ¯ª¦§¥±« «˜›¢ œ›ª§¢«¢¥¨¥¥´¤ž£“¦®¬¸´§¯¢’‘™¥’‘ ¡—› ‡¦ª¤«­¿¿±¡©®©—’Ÿž¢™£¤ª£“ ¡ž¬®§«¦£¡¥Ÿ¤¤œ­¨‘¤›©­ªœ«­¢—˜¦—¢¤˜Δyz¥z––›_­]Ž¨€ ¡|§•št«‚€¯^dŒ©z¨‡…Ÿt—’ˆ³c‚«† ³j„®s|–‡¸a‚­Y£Ínu{Û{™q~ˆ’ue{ˆvvl}‡n}…‘}k€_pjof`_xd[qhjcf`RTSW^JOC5AHED8>6;@?A;=8@>??BDDFIJLNPROS\^__^]]_``__]ZWOUJ=?><5578164('$!',&&/(&+360$7;SL+,-J0';\:L-!P@F4.1­Á¿¿´´°·˜ž‘£ª©­´«¦²­¬¬¤¬¦°ª¡§›š¦˜œ¢¯Ÿ¡Ÿ¨§£¥¡Ÿ°¬›ž–¦®­°«¨¬ ”’›Ÿ¥“Ÿ¤—§£ž­£«°¨¿Æ³¨©±®–’žœ¢—¡ªªŸ•¡žœ®®¦©¨›¥¥£¡ª’¬³–¥¢ªªž¤§§¢±¢“›§›¡›•”‘— p…Œ˜u„¨‡q°|r¬} Ÿ¥žw«‚}­œr­~«‡†Ÿv˜’{|—~ªˆ¡‹‘‹œ}«zˆ’Ÿz­VœÄzo’Á}•mupŒmfwe†oawnrnˆŠ‘ƒlŽdmsuo`fmd_ohjnfcWS\`ZRRC8II@C<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;91478452&# 1' 1''45-&7=WJ-<(=1)3V@F!G;C1-+¯ÓÅƲ³ £Ž£¢¢­®¶¯©±§¨ª¨®««¦¢£š£•Ÿ¦«Ÿ¢¦ ©¨£Ÿž°­˜›–¨§¯¬¨§©ž—•š£¢’”¡¬š¦£¯¬£¬µ©¹Í²­¦®¬–•œ¢™Ÿ®¬–¡™žžª±§©©š©§£¡ªš¯±¢¨¬¯¦™¦«ª«²¤“˜¤¦›•’…¤j¤u‰z©uz²q‚¥‰˜Œp‡Ÿš‡¤_`R«„®‚›u®‚§††Ÿz™—…{f€£‰¤˜†£}©~”†®^{¨U¢’z£Ÿ€|ïŌs¯´³¹qb©¯ÂthŒŒ—Žl˜‘nlxxwnkfddqpf{ic\V_iXXTLLQLCCAB;CA@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799664,&$" ('"+-"$.!3-&@DWH,G+56*1PKL# A9D4,'ÂÉÕÕÀ¡™«¨¡¯¢Ÿ°µ°¯©­£¨§ª««©¤¦Ÿ›¥Ÿ¦§¦¤¬š¢¬¡£Ÿ¯£ž›“ª¤¶°® ©›œ—•¦£š¢§Ÿ ¦›±¦£¨±¬¶È²µ©¬ª•‘œ¢™ ¥´š¡”œŸ§«©¢­™ª§¡¡©¡³­¢ª³²¢œª¨°°·¥”—¤¨™’|ªlž„‡u«y|°n‚¤‹ˆŸ–•ž•Ò·´¸É€²^_”©ƒ¤‡‡ z˜•™xªÉs™£”§¨’šŒ~š‰šÆÆwe¡‚¥sŸŽ‚}¯^oµc±uK£†m§G‚“dŽœ’{o•}nyt|zm[ejrqfj^aXcm\^YILLKEDBB=A<B?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75785/)(%&%$&),5FNPPMFLJVF*L0/>-4NTQ;<F2,$¨¤Àƹ­©²®¬¥¢²¹¬ª¡¦›¨¦ª¬©¦ ¦¤˜«£Ÿ®«¦¡¬šž©¥¦µŸ¢—“¨«¶²¬›¦œ –¥­’šœ¦¢ ª¦­¡¢§©°´Â±²ª­¨”‰˜¥›¢¤¯¦—¡•™œ¥¥©™®œ¬¦¥«£¶¬ ±¹°žœ¯¨´´´¦–˜©¤›¡‚NxšŸz„£|‚¤„†¦žœž”„¸{|y¹‚ÌÆöw›¡‹Ÿ~š–—‰vŸ—Š¤˜¤§~¯„›ƒž„¬}™”a¥l£p…}—„r¬`¤rq€š`¼}RUuŽ‘£–{|‘Ž‡ryrƒ}p\lnwrj€nZc_hnbd]LLQSAHGFI99K>B108856877-*5==?BDGILNPTWYYZ[\__^]__\ZZZYUSOH@772.,*.+*'&?QTVWWWYXXWUOTF<E2:P[T6?G,- Œ‡™©¬¤«¹«¯ ›¡¬³´¦Ÿ¡•¥¯®®©¦¥¥š£§ ²®¢©§² ™©¤”£µ££•—¢ªµ¹¤œ££“¡²™ž›¦¤ ¢¯­œ£¨¢µ±Ã±­ª­ª‘‡‘œ§£¤¥—ž˜™™¥£§˜­¡¬£¥—®¥»¬¡··®žžµ³¹²´¨™Ÿ±¢¥Ÿ‡ÑµÃ·y‡Ž…‘“€¦x”¢w‹ ’…¥‚‹q«†…´nri™£œ•‰Ÿ|—™†‡s®‚¥›¢Œ¦Š“œˆ”šmp²\¥s“zœl™{™~n©a¢qqŸbs²¸hw“¤˜}Š‹ˆv{xlhwixsn~t\ddmmeh`JZWX<HF?T3@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^``]Z[ZXURRQF:2230/++(@QRTUTSTVWWXXWUUVTQOQ[U%!2AH#)%’rŠ­¿¿¼»µž—¨¤­¶¡£™•£©§®©«™¥¡ž¦¡ µ§¢©§°£”«£¤­£ššª´´¤¦œ©’”—®  ž¦£œ§œµ™ ª£µ«Â¯©«©¢Œ„œ¢ ¦£–ššœ˜›˜¦£¥—©¦¬¡¤›¬¦½¬”¾°­Ÿ£°´»¬µ¨ª³¥©™{¨‘}|°wŠ¤¥ˆœm²o ‡­{¡ƒ¨–™€¬‰…®… ”¨¡¢—…Ÿ€™•€{’~«€™–Šªw ˆ“’y¯]£|¦§dž€|—tk®]¥kq…™]`[Œ m”¥˜‚“‹“‰xy–~jl}b}tmy_gepogghBY_[=JS2T8BBC7$$3+''3, /667436:@CFIKMNQSSSVZ]_a`aaa^][ZXSPONI7052.*,ATVVVTTUUUUTTUTSSVWWXVUVQHFIJ#((¼’š„©ÆöÁ´Ÿš­ ®¸¥£Žš¤£ ¯®©Ÿ£ž­˜ž¹ ¢« ¯ªš®¡‘ª©¥–‰š®°¬¦ ¨›­˜™­¢¡¥¡™¤œ­—Ÿ¨¥¶¨¿®¤©£Ÿ‹€Ž››Ÿ¦ž’”™š”šš¤££˜§ªª¡¢ž©¨½¤—ì«£¢¬³»¬¯¨¢µ±ª¬™v¯~Šœ…‡}º­‰˜d°Œe•­}¡ƒ§–›¬Š„°…¦™£¡¢‘… [lj³`­{z‚€±lgm™—‹ˆ±Z}´[¤ƒkÈ¢eŸ{¼YvµZ²}R¯€z¬X€¡m—Ž§™‰•“”ywŒ›|cs|aƒxs|`ifpmfeeOUc\AT^=H(>9=4!!,$2. *1/04579:<ACFHJLNPPRTWZ^```ab^_\[XUPMJGC553./@UYXWXWXXWWXWVWWWWXWWXYZZ[\XWWGB;ҟ´±·½»´Á³£œ­¦¥¶© ‹™ Ÿ³±¨ž¢Ÿ´˜ ³¨ª«ž°­ž¬›•®¨¢Žˆ›Ž¯¬¨§£¨™®“š©š¡ž¥ž™£¢¥˜ž¢©²¨¼¯¥¨žŽ|‹›–¡ ™’š›‘™—¨žŸ—§¬¥£¤¢¤©ºž Æ§¥©¡¬µ·®¯¨¡½¯®®—©’£®Ž›€†¤—˜€€¸ÃºƒŽ“„§˜‚¬Š‚¯‰§œš¥«‘~սªb¤¿½}~£‚ƒ×º·µ…“’‚ž½¾„j£o«„nz²±Çƒk«°½¬xw¢¾»t€•¥š™Ž”šw™xa|ycŒgx{`kejibPb[Si\@T`BL)<:5/$%2 $(0496678;>ADFGJKMNNQTW]a\__a^`[\YTQMHC><A?5=SYYXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ»•´´±¿º²½³¢®¦¥³¦Œ˜¥¿©¶°§¡¿¦¦±›ž±œ¹¨Ÿ­®¥§•”¯¬—Œƒš‘®¦£¬¡¥œª ˜Š£“¦ž§›š ¨¢˜ ¬¬©¸­§£š—“{ˆ™’¦›“‘˜˜˜”¨™ž–¨§ž©¦¡¢«ºž©Å£¡°¤«´µ«±«¢½ª°°œtvª¤·…e‰Ÿpg¬Šnow¤š u°š–pr–¨£›˜®¤rlmleŠxnm‚™q€zipif‰••—qhi…†gp†d]ŠcioY]g~x¦`br’ofd€“Ž¡–•–Ž”›z…“td†wgŒjx~xdlcelbKeWJkY:PdDP'J:+# ",)-2.5:457:<?ABDEHKLMOQSV\WZ\`_a]][TPLHD=:AB7MXYZYYZYXXYXWWVWY]^^]\\\]^]^][[UW^¨•­´©º¹²³ª©¢®ž¤³ª˜’½±Ãǽ´©ž¿«¬£ ¦«Ÿº£¤­¬­¥Ž–­ªŒ…•—­Ÿ¥ª¢Ÿ¤£ ‘‹¥’§™©™–£ª –œ¥¦§¯¹ª«š›“’{„–Ž¦—Ž‘‘˜”—•¦“–§¢™¯¦¢¬¹Ÿ°Â¨¤´¦¬±²«¯­©º¥°¹—‹¡©¥µœ‰–¢˜†©š”’ª³™›£¬¡´—£¡ž¡¢œ¡¤¡•¬§Œ’“Œ‡’œœ”™“˜Ž•„¤š—•‹’’Š†„~g‹€tƒvt‡Œq§m|•’”“Žœ’Ÿ”•”ž€…’‹pgŽvn‰wu|yikddocU`X@iZGb`NX+E=+&!640/!%2(*799469;>?ABDFJKKMPPQWUVY^_ac]^TQJEC>9=@ASX[\YWXXXXXYXXZ[[\^__`^^^__```_YY`¥–©ª¤µ·®®¢°¤­Ÿ ¶±ŽªÄ»Ä¹·©¡¥›¥°¨£¶§©µ¦§‘˜¬£‹ˆ‰œ§–¬£¡š¨žž“•£—¨š©™”¦¡£š§™¡´¹§ª˜š|”Œ¡”Š•‘•’—¤Ž˜§ž›µ£¦«·¨¯Â¯¤¸§°¯±®ª«µ»¢±¾™’¦¤¦µ¢’¦ž¨ŸŒ‘Ÿ£¬°š¡¤²ª±™¥¡¤«žžœ—¬ž’š¢›”–ª™˜˜––ž‘‡ •”…’Œ•‹~f‡u‡vyˆ„tœj‡‘••’‰}Œ–’’—‘ ‘š”ž‚†–…xq”rx‰~q{~ind^pi`[_YmbP`dOY9GFE=2<=8/*&+)&&406658:==?AACHJGJKLMSSSUZ``i`eVPJACB;9EMV[^^[Z\[[[\]]_^]^_`aabaaa`bbbdb\[c—•¤§£°³¬®£©§­ ¨µªœ£²º­ª«¡¢™zœ¢°¤¥±©–›¸¦£”˜©œŽ†Š‰›¢®ž¤–¨ ¡’—™›®‹ª–¨™¨Œ˜¨Žž¸¶£¥˜›‰y”Œ›“Š•‘“‘–¡‹œœ§ž·£ƒ¯µ¢°°t¤¿¤² x{¡¬´½–w®¥ Š€©~d\bvŸŽ£ƒ–~n”´œ£¨¯¬¤eŸ ”tzš—p€™©˜l€£¨Šeœ¥œ—˜–‹’›„š”ƒ’‡ŽŽ’‰…wkˆv‡q|†€ai‰‹•“Œ[v•‘ghŒqy¢––dw—†€v—h‚‰‚ny~jpe_uokkg\ecaaoRZ=MMNRF=@TB91/&4:306678<;>@ABFHBGFIKLTUUY]`hggXQI<DG<9VR[`ab`^`_`aa_\]___aabcdabaaedchd^]fœ–¦£¡°±¬«©¥©­¤§­¤’–ª´®±¥™©¦ª—s‹¯Ÿ¨«§“–¸Ÿ œ¤ž~ˆˆšž«š¤•§¢žŽ—‘ž…t®ˆ¥š¨‘–£ˆ›¹³§ ™™‹‰uw“–“Š“‘”Œ“Ÿ™ž¥˜›²–€Œ›µ´’½§¡~§¢{¤°¹‚Ž§Ÿ„‹…±©¯Œ‰–¢™y€‹¬†œ¢¨«©ˆ•‡™w¥›z‡œ—§‚{²zŠ† —™”˜–––„™šcy‡„’‹ƒnqˆzq€††t‡…–’x–h“t št{™‚š„˜}‘ˆ‚˜iŒŒ„jxzppgdxmilj\diier[\HTLQ@E5-YTT6)!09=>643568;:=>>?DI@IEJKGRXZX[aahfYQH9EL;>bV^bded`aa`bb_]`aabbbcfgcba`edcgcaah˜£Ÿ¦®®«¨¬ ¨°§§ª¥™”­Å¼¯ •¥§´ƒœ«œ¦¢ ¾ž™Ÿš¡|…Ž™˜ˆ¬£–¡¡’”‰†€‘¨Ž‡¢œ£“–†ž¹±§š“…pu‰”Š”Ž›‹Ž‘•ž£”«‡Ÿ´‰´š®‹Êˆ«¯‰·…°ƒ²°…©Ž§˜|¨r{w›Ž¥–g”¤y´ŒŸŸ§©“™Â‚«ˆ˜¡qž€š¥}—…•²€¡} “Ÿ˜—€Ž“›‰˜’‹|…“†”“‰ƒms’†€{r†„}…u†‚˜Åf€©‡¢jž—€™€ŠŒƒˆ˜o’„gwt{vghupghk^bnlflXfF\QL2E46M`c7&4<DGD:63658;8>==>BL?NIJKCPZ]\Wb^jl\QE=KM@JdX]cfhgbbbbcc`_babcccdiicbbbecafcbbi•—¢Ÿ°¨©¨¥« ¤¹±©«¦š”ž¢¤ª¢•¤©µ¢¯ ¦œ¥ž‰”¼™“ ‘yƒ––‘ˆ«™œ›š¢…Œw›œŽ ‘ˆž¤›•˜—†¢¸¬¥™›bm‹“ŒŒ—‹‘ž’ž ˜ §~¡§‡­ –® ž‘†‚ ¬±ˆ¤Ž«šŒš~¢u€˜“kªtLªx‡’›©©‚ª«~„¡{z§iž’lg—†˜¶‰ž~n`cXƒ—Œ{dg‹s™}y–k]|—n_Sq…\`lyƒ`Ye‚~„˜q§ªkƒ£nr¥pŸ‚œgdžlZlˆzeY_‚~aWPovemtqjjn^jolkhWgN]XE9@4GD^k4+ICQMN=84859;6@;;>BO>QRLMBJ[]_W^_bv`ME:MOMTb\[ffiibbdaddbab`bdcabjkdbddgdbgeach˜– ¹ ª£¦¬‘¡¶¼«®¢™–Ÿ ¥««Ÿœ­´¡§‘ ŸŸ¦›™˜´™‹žŒ•‹u”‘Š¦––˜Ÿž~“…†¬£‡œ‘Š˜©˜™š‘‡¥°¦¢•™ˆ‰€inˆ‡‹ŽŽ‰‹Œ‘‹‘ ‹’Ÿ›¡¥“£¡” wœ–§ƒ¢¨€†«¯†¥z‹}„š}¢pr’‡–{Œym‡›‹™‘œ©œ‡|‚¢sv¦fž~w¤^˜{}“s¢n˜·´ºs’ˆ€¶¨dÆ¸{p•¶Œq€›¤ct¬«`}j³~n}‡ƒ‚‹—q€£ls¤sž‚}£^œ™³–o{—ž³tr[ž²‚ibosuqhnXkkrrd[g]aKD=D5QAZp2<RF_JS=<395::6D;;@IP?TMNQ@E_^[YX``{dIC8LWUVbaZffkkbbeadc`ab`dc_`cknccddhdbgfchh”–•£¹™«œ“ Ž¥¸µ­­ š¡›¢£¤«›š±¬ª’— ˜ ¤™š”ž«›‹ˆ‘x‹…p€–Š¡“”—}‘ŠŽ¨ ‡˜Š’¢“›šŒŠ¨§¤ž–‡„~k{‡~}ƒ‹‰Ž“ž•›Ÿœ Ÿ‹‰wœ˜¢ r¢‹ˆ©ˆœ§‘—©¬€®Œ}z ™y£“x€s—ˆ‹œ}•Ÿ†›Ž™œ§‡£d¡}‰–›Œlžhšnš™{€Š§}rgsªƒ‚sªg”š]›…v„hªj¸f\©pœa•Œ^§vv‰Š€hšu‡“’˜Žžm™j¦™\¨~w»j}©ZŽ„]³g[nqxwki[piwxa^dVaAPEO7VBRm4JZY^NZD@151;;7H?:CGU?XRX]>Db]V`Qad|iEB9N[^YdfXfgnmbbe_aa__``ec^bdnq`deekdcihgki•œ‰ª¶›¨‰c•œ¬º²°«¥›š§Ÿ¬™°§ª–¢™¡Ÿ™–– £™†‰iˆ€q{—ˆŒ––„’”˜zŠ„–£œ‰•†‹‘œ›ˆ¨¢ŸšŒ‘Š€€i†y–Œ{ˆŽ‡Ž•™~’¡ž ¢“˜rhŸŠ Œp’Œ‚©ˆ™ ¤©¢©}°­¤¢¸—v£³¢£ˆ”xœzª™¢žœ˜‰˜r¡}…°µ}kš‘¡x~˜´££«¨„˜{š|œš~sªZ]o{—‹xžbL{{…dz˜BMŸY¢jr|ŽnŠ„™v›y‡‰±³~š’¦t~mq|”o™ri£]•vHec`sp|}nf_khu{bc_P]V\TV@YEQgERV\aX_ID=B8@A:IE8LEXAVQZVDFa\Z`K`m}qEC<U^bZejVghmobff^a`\]^`hb_edvl^egfldelhhki”±®™„S_¡§´º³³¨š¢‹š©›œ§’ «£ §Žžœš™•˜¡–‡‡‰w…ny•…š‹}‘“–ˆr€‰’ ›r’ˆ™”Ÿš„Ž¨›™•‹ŠŠ|„l„…q¡Œx…ˆ‡‘—“{‘¢Ÿž£ˆ®†}µ„ž{¦–z©‚–ž‘‹¢ž~§hwm~™s sq|†™o’‚­|£ƒ§Ÿ›¤p^©hu£co¥aœÓ|z™xrsc¢…~¢r¢Žuk³‹`‚˜Šsª²§¼wƒm¿¦ª´^œo~r—os¢r^¤gt¦`h¦lšÓ˜z‚›nvy—k›yv—rl©¥g_dyp„kgfcmuwf_aQZePQaHWIT_WS[dj[eQECKLJKBJE8P@PMXSXORQ`eeiRdxywIFEc]eZhjSihjocjf`c_\]]_hbahe|d^dgdkdjlfhlh˜›°¬T\K~©¯²µ°²£œ˜„—¦  £Œ¤§Ÿ—¨‰™—˜“™“‘ —Žˆ…{p}„h}ƒ“šw‘Ž‰p‡“’l˜”|‰‘’£•ƒŽ©š“’‹…‰yƒvˆ€nž†w€’…‡˜ •y’¢£™ ‰³¡¢¶‹z¬§¤®¥p©€›‘†“}¤€¢™†˜qž„¢­®‰—‹Œ¤•ƒ¯¢•vµ¶µÉ¢t”‹‚žaž—©my•† ›u¡‡w }–ŠoLf£’pšˆs¥{ytbƒ‚l~ lrd`œrt—k{j´µ´Æ¦s˜~zœjšš«tšlsw—i™yt—qPD}³^iujx‡fkgbstpmU\RXgORhIULXRU\gknUgWMJAJMJHJNAQJPdcimetrs~x{nu‰z{TQOm^h[kiRjhilgmfce_\\\_ibdhk{_]dgcjfnmeile¢œˆ¯§…f?”¡³¬¯¯µ¢¢–§¢¡£‹¤¦œ›¥š—–—›“Žˆƒyjy†eƒŒ~–ŸyuˆŒ‚i„…’ƒŒ…zŒŠ•¥’‚—¨—Œ‘‹€‰z€}‹yp †y”†ˆ•ž”~“¥§œ––„gnxœl¢d|q¥xœ˜ph§‚˜|¤z –ƒ–rŸv€‰”•¹mŠ¢b}™¢–‰nsj«ku mo¦`›i‹i–‡š•u¢€}š_‹…Œuoˆbh¡eži›updgˆ‚nr¢Z_[c¡n]‰Œp{trd¥nx¢df§h—r‹˜n¡oRˆn ^d§T‹]T˜mmrjqmphkxskoQVUUeYSmIXO\HXhhsjYkVPREV\LXRaUhj^wuz|p||r‚{sv€ƒv^QsafbqgPkhhklohdg_]]]`jbiivu]\chcjirlfkmc¥™¦zetm‹§®¥ª°±¦Ÿ‹–ªœ¤‹¡¡™¡¡€•˜“š‹—Ž‹{†q€ˆh‹Š|—šst‰}|e‚‡•Š‰–™‚|ˆ…–¦¡«…ŠŠ}€€Žsi¥„}…“Œ‡—Ÿ†‘©¦‰¦x–œ~¥‰–Œ²™ž‘ƒ¯—Ÿ¥y—‰z©t¦„šn¥¢Œ’„Œƒ¼m|¥¯‚‡†‡”—¡}¦{r¨” –gž~o¬c–Š•’w¨l©¢‰v‡‚w«‘¦ˆk‘°kv³Œ©l‹†oo ž‘”a«‹ªwŽ§ŸwŸ}…¤• iš‡u¬fž­Œ¶sv¾Œ£“Yƒ¦«`uqso{upbj~nglSUYU``\jL\Q\I]lmv`[qX[_Zgsenoqcqt`wz~yryƒrƒ~{{Œ‚€vbydcnsdRlggolrifia_^\ajbllzo\\biamiwmglnb•¦ªœ€ž¤–ªªž¨§®£˜ˆ–ª™£‰š¤œ¨„‹š…œ‘…’ŒŒt…zˆƒo„}—“su†r‘ƒn‹’††”}{‚…—¥¥¥€‰„”u‚‡’ol‹¨€‚‹“ˆ›žˆ‹’ª¢ €t”—ˆ~y”¯¤œq†y’Œ…€{r§Œq}}z—–›„x{}}ˆ”•“‹w‘™ ¡„{~‰kŒ…[yysypin~’Šrt”“q…ƒ‚e_€Œwvt”uo{oo‰n„†^wixŽf‚ƒ†ªœt}—j‰ˆou|„umlfŒsw{—w„ZjWyhmwrqowxo]l†migVY^W\dkdUaT^Q_owykjwejjju|pqtsaoubs{xuyu€€y‹…‚}{mldyn^Wnghukxjiid\`ZcielqunZ[bkdlkymhloaŽ•¹©§‹¡¢›¦¤™¤«¢Ÿƒƒ–ª‘ ˆ™¦š¨˜‚›‹~–”‡ŽŠ‰Œr‚|}~„z—Žtr„p•†{}’‹††…x~€†˜£Œ{§ ‹…„•‚†Ž˜wq„ª…‘œ‡ž†Šš¨Ÿ ªƒ‰Ž•›~Š—­¨“§xqž“ƒ{“p©†p}•qjo|Ÿ‹‘Ž‹hn]„ŒŒœœ s–Œˆqtk‚vt€Yrn†‘‚~~‹i]icz…ƒˆ€_ix{œ|ƒƒv‡ƒiyŒˆkbqrƒw_r‚Š¨–‡gƒnw‹‚oƒ‹wndfcy‚z•Z[ifmv[zxwtmsr‚f\mŠkkbYX]YXkq[^`Y^]er}zsotcjji{|rzwtdmthl{~uz|{yy€~o…‰„{}s~yrhT\rilvpugkgd]aYjhkjqrmW[emlgryohjm`ŒŒª±¡£¡šŸž˜ž™¨¢¡}‚–«Œž”‡š¡¤”{˜„|’™ˆˆ††Šr}€‹v…‹„–Šro€r˜‡ƒ~’ƒ„†Šz€ƒ‹šŸ‚¦ †x—ˆ•‹‹œ—„ƒz¬—™“‰œ†‡¡ªŸ¡¢£‹ˆ“›£™–ª¢¨§¡“œ‰˜|y…¨~~’‘’“œ±¥š”±’˜„¦ŒŒ–œ Š‘œƒ‰’Šk|Žvwe‚†Š}‰„‡‹‡ˆ€…„w|{u›£‰ˆ‹Ÿ‹†•~‚vqt†…x‰ˆ‹‘§‘„‡ŽˆƒŒ‹{…‰‡ujƒ{y™iqh`sŠp}zwvovs\^o‡gn_^YZ\RgqUc[[alht{|rnpcjih{mx~phoplf€{r€w}„{mƒŒ†|zx|~zƒxNdvjsnq{ekebb`[sfpfrqlU]ltmhxzpgikeˆžºŸ–¢¡˜•™˜”˜¤ z˜©žŒ…ŸœŠ–|x”‚{Ž™‰†ƒ„‡mx€r€‡~ˆ“„mk~z—‡„ƒ~€†„†}‡ƒ›‘†©ž‚rŠ…’‘‹œ‘}z©ƒ‘—•Žœ–……›¦Ÿ¢š†ƒ’š™™™¦ ¦žž—‚“‹x}ˆ…¦||‘…˜© œ“œŽ©‘€ž‰”› ƒ—‡Žƒpx†qta~„†uŒ˜€ƒ‚†„~…„•nyvu“£Œ†›……ŽuŒ~}rs|‰„{y…“¨‡„‚ƒ‰‰ˆu„††‰zmj}zmhklf^y~g|{vtuuzw\`p}mt`cZ[^QfmSeZ]ajhuz~pllcjjg€krkjsnxnƒyn†€v‚€}…vr‚‡~{z|{‚‹`i{kuhiƒejc`i[cuhobumkTbqyeoyzrejmm‹ŠŸ¸š¡¤Ÿ’‘–—‹šŸžzwœ¥›‰†¤”Š˜™xy…|‰‘ƒŒ‚‚‚l{xr€…}Š|kh}‚—‰ˆŽ|~†„‡|€››‡¦œo‹ŠŒ’† ¡Š…Œ|§‡’–“–’vŒ£ ¡–šš™“š¢¢¤›˜‘œ†z…ˆ¡€~Œ|—¤  ’™¦Œ›’‰”˜œ~““~‡Žvt‚pv`}€Ž‡rŠ–|ˆŒqŒ~‚……ixry™“€˜‰Œsƒ‰}}qz|Œ…{{’Ž„—¦”Œ†‘|„…†„t€……xdqz~xypkjf^}sg|uvs|sj^`tvpwdcX]^RjhTeX^`givxqfkclge€jm}gmpj}w…zk‹r}tv‚Œ†|z€}jrƒntibˆilb_qUtomn`xhlWjtvctzzqbkoy‰Ÿ³’¥¥œŽ˜†œ š›{u£Ÿ—Œ¡Šˆš•x{†‡~ƒ‰~ˆ‚p~ztu‚…~‰wgc}†—‹‚Šx}€ƒy–€•—••Ÿš}o‹“†¥›‡Œ‰ƒ¦•„’Š•—’‘v¡¡˜”˜zŽ˜——š¤ž™“”œ{‘‡„x†—Žž~‚ŠŽŒs—¢ ’˜¡Œ‹ƒ—˜ƒ“–š˜|‰wr~n{d€|‹†p†“€‚k‡ƒ€‰…fvo}ˆ“™~”yŒ‰}‰}|r€y‹†z…’‹Œ™£—ƒ„Œw‡ƒ‚uz†ƒs^ww|s}wfkc`~ijvssu}q|ccasnurmaY_]ZkdRbW_`hkty†pbjclfh|‚khthloh|yl…q€‚‚t|ƒŒ€~z‚ƒ~|mu‰ttmeŠljbcuVƒipn`xglajvpex{yp_ql……®˜¦¨ž—‡…Ÿ’–—|v¨›‰˜y–œ‹Œ˜x{€‹}|ƒ{€‚xsxys}€ƒˆŠ€d^}‹•ˆ~…‡t}~Š~—„–“–Œ£ —~q‡{“‘Š¦ŒŽŠ’ ‘ƒ‘“—Š€Ž— š’’t€’”‰ž§™˜Ž•˜u‹m†™š{‡ˆ‰o—™¡“•ŠŒžŒ†“œ““–‡š‰|ŠŠzrzkul|‹~n…’ƒ”xo‚„~~‹€esj}—˜…€Žt‘‰„yˆ~vx~‡}„Ž†•¥‘y…‚tˆ†|qs~…l_ytxp{nanbd{amovrwwssav`oluno][^]]j]O\Wbahmsz‰k_iejchw‡mflhilg€|zwnˆs€ƒ„}t†Šzƒ}z„}|Žry‹yxnl‡kh_irc‡hqoevgmlazhj|{wpawm‹™šª ¤¨ŠŠ‘†ŠŠ”—|v¬—Œ–|ž“‘–”ˆv}{Š|{€vw€otszo…}€‰~|a\~‘†„„sz€†z‘†‘‘›’¤š“||Š’£ˆŠ—š…‘˜“•Žˆˆ‹’“Œn„‘‰ž™¢¡——‰—’p‹›…g‡š”{‰…Šp–š“ ‘‘ˆŠ™Œ‚’Ÿ}’“Œš{Š…‡tsvkqnv|‹tn†‘Ž’qt€|‚ˆ|eqmz~›”~…Šu‘‹‚u‰zoˆ}…Š†Ž–ªŽ{ˆ}~Š…w}om~ƒbgwstnza]o`jt^pjzyxlrpey]mlsmsXZ]_ajZOWWdcfqq‡e]ihgbgqndigeig€zwunŽ…sƒ|u‚ˆ…x…|wƒ…z€Šw‹{{ryƒjk_phskqnmqgoke{bnywpkvw‰£˜¢¨¡¦›ˆŒŠœ†’›t€©”‘† Œ•“s{v…wxrs{…kroym‰v€†nq[Y~’ˆ€vu€ †Š‘œ— “–w‰~€Œˆœ‰†’—–…ˆ”˜–‹‹ŒŒŠŽ„n‰‹‘Šœ–¡œ˜–†˜‰l†¥…g‡ž‹’Œ„Œw“˜‘ˆ‰”~~™|‘Žš’}‹€ƒovplmop{†isƒŽ˜Špw€u‚‰ƒygsov‚›}Š…{•’{wŠuq‹|†{‹‡…Šœ¥‰|„vŠwwli~€\qrqoowY]o`oj^oj|zpmmjmw`pokqmYX`aamWPSYefbuo„‚a]kmdbfk’m`ff_gktqro‹€t‚€yv€‹€y†w‡†vƒ…{‡Œ€{vŠjqb|b…|opltjhnlvw_q~x{tus‚~¥•š­Ÿ§–…Œƒ~–”‚ŽžtŠŸ“’…ŠšŒ•‹zrwt‚pr…squˆlnlumˆwƒ}mnUQ«”‡‚x€vr‚y‚ ‚‘’‘—›‘˜w‘z‚Œ’¤š“Žˆ”˜’ƒ†–˜‹“‹ˆŽˆž„Š}s‹…ˆˆœ™Ÿ›–•€”€i‡ž‰h‡¡ˆ“…‘„Šqƒ‘—šŒ‹w{“‘{Ž‹’–|ˆ|kwjnklmzby~Ž–vzwƒ}zhumuˆ—Œ€‰‡{”‘r{†qxŽ{‹{‰~„Ž‘ŸŸ†}}xŠ|vohj€w^womkprU]naqa_lnypgpffsuhqlawe]Ve``qSPN[ed\xpˆ{^\hqbbee‘i_gd[go~okqsŠ}v|…€uvŒy{†€xˆƒs†…~ŒŒ„|y•xfqjƒ_‡~ookz`imtt_s|x†wss…|y¡š±œ¥Ž‚Š‚™ˆŠœ~Š˜’Ž„ˆ—ŽŽŽ„vtvs€po…spqƒojium‚n}|musRN‚ßɒ֓|otƒuƒŸ‚‘v”˜›˜{“r…Ÿ¡““‰’›“…}••‡Œ‡’‰œŽxzŒˆŒŠœ›œ›–”zŽwiŠ“‰m‰¥†“‰˜ƒ†cŒ‘˜”‰•‹Œ‰‹pz•‰|Ž‰‹“‘Šz…|m|esoklzy\€yŽ€{}~†Ž{ziuktŒŠƒ††}–l€p€Ž‰~„{ƒ‘–››Œ}wx‚xrken}jitnghslS^odpZ_lrwfkkbgxsoqc_w`aUk_^uOMK`ec\yqŠt\[eu`aedŽc`fbXirsmkqv‹|ty†‚vw~‹s†~z‰r‰‡‘Šˆ}~™vesn|e‡npk€Zknxyr`vz{vrvŠvyŸŒ›¯› ‚…xˆ”~{ˆœ†„žŽ…Œ—„“Ž‡twpypn„omn~rcdxp|nz|jhlc¤šÁÜ®ï¢skuƒu„¡„‘n•”Ÿ“š‘p…‹£—‰Ž•Š•ƒ€”„ˆ€’ŠŠ—~‡{u‰x†…Ž›š—™v‹wpˆŠŒ~Œ¥…’Š…†^‹”—‰ŽˆŠŠ„‰l|—‚}ˆ†Š‘†v…~~k}cxtjoxsXˆz‘‡…z€…Œ~zftj‹‹„„€Œ˜†l‚wo‰’ƒ‘…‚{‘—”›‘utx†Œurpesw€`smoahufR`pgkU_ntyarc`i}qrn[cracVnZ\wLLLcea]vsŠm[\dx^`de„_cc^Yirknkrw‹}sw„xx|‰qƒ„|}ˆ{t‹ˆˆ•†Œ˜shuqyl‹{ntp€Wpyvyqdvx†Œhv€‰q€ˆ™§œ£’„|pŒ”wx‰œƒ„ŸŽ|•Œ™‡„{rwpsjokil|t^`xv{ptzg`e|ëÚµÉÃ܉sls€vŠšˆŒi—Žœ“‘ˆp…ˆ Ž„Š•ŠŒ—“|’ˆ‚ˆz‘‹†‚€wxƒ„r‡‚“›–”˜†v‡q†ƒŠˆš¤„•Ÿ„‰aƒ•…ˆ…ˆŒ†€‡h}”}‚…‰Ž‚q†rwgvritwlZŒ}’‚…}€ƒ€„Š‚vbumŠ‚‘Œƒ€“’~nƒmzˆ‘ˆ“…}‚~“”‘˜ŠorzŒ…tkoipv~]shn\iu_RdqhfS_pvt`o`\h‚qrjWgiciXmW[tLJLef^ars…i[\ey^^dgz`d_]YknenjtwŠ~sr~{vzˆt…ƒ|‡vvŠ…˜‚{“vlwvyx’unwz}Xy…qnfxv‘‚dv†…qŠ–†™¡›¢Š†so’‹rvš|‰™ˆ‰{Ÿƒ™xqtnodr~hflww[_x{zqqiagaÕ¶Ž‘¦xnqw{q’Œ†j˜ˆ›Š…{h‡‹™†’††—{ŒŒ€€‰{~‰…zu{ƒ{q†€•™Ž’”‚‰u„ˆx…Œ•ž ‡– ˆa“‡ƒ‡ƒˆŒ‚f}‘€~‚Œmƒ|‚tkmwutwvkcŽ„|„…ˆp`tr†}Žƒ}€’Šzq„g{…Œˆ„|…•’”…opy‹tlmijwzagjiXkuZRiribPbrxlbe^Zjƒnsb\g_em_nTZoNGNfd\fnr€kZ[cs_\ckvde]]Zllbmjsv†€qo|}tx†x…ƒ|€ˆvx‰’•{‰†v‰oxy{ƒ’om{€v^ƒsmhzs”sgs‡|r’‘„šŸ› ††uu”~mu’–}‡ƒŠ™|Œšv~vqoljat|gbiuyZ`w{ymq~echhW_rs—¼Ä„vq”ˆ}q–‹†›’‹‡rjˆ–€{”Œ„šŒ|Š…|{‰‹”ˆu‰†vw}ru†ž”…”ƒƒr€Šv†}‹šžš‡•‰f}“‚~„‚ˆ‰q}f~Œ|y‡‹}i€}ƒvfoyxswslkŽ…ŠŠ€x‚…„k_sy{~Ž‹†|‚~s‚iz„‰Œ†…y„}‚™‘~nm{ˆ}vtnfe{tb[pbWnqSSmrhaNftxf`^\Yo€osYeb]jn`pOYkQDSg`Zjnm|nY[]mcZbpvdg\]`kicljsvƒpm|tuƒzƒ‚|…v~ˆ–x„‹tˆryy~oo{€qixz~ml{u•kjx„tk“…Ÿ˜ ™„ˆn}Œviw—Ž~€‰‚”—‰y•ozsplid`szh_eqzZ`r|ygqzaee±²wKbZ¥ÙЖq{Šw}“Š„˜‹…nk…’‘zy’†„˜Š|†xw‰Š„–€o‹ˆqu~zjy…ƒ¥„“ƒo„w…z‡š•Œ”‘•…ˆp{’‚|‚‚ˆƒn€wh€„xr€ƒŠ‡|e}~„vcps€ixpou™†ƒŠ|vx€…zƒk\rs‚‰‡Š~‡Š{‰r‚nr…ˆ††s„z‚šŽ…yno~„vzdfh{o^XvZWplNWqsf`Klwta][ZYt}soWg]fjr`oNWhR?Xf^Zpkhzq[ZXkeZcpy_h\^elhekiqwˆol~€uo‚z‚‚v„ˆ—‰q‚q{†|zyƒ“Œujy~ko~t}or{z“po~xg’‹ƒ¡™œ‘‚…f†ƒogy•ˆ}~„˜‰|Œhxrklf_`oym_box\dk‚zaqv_eeÔ꽋2:>‹Žqx…‡u‚•Œ~‘Œ‹ml…ŒŒu|…•ˆ|‚xnv‡„ƒ—wnˆ…lu{tfy‚ƒ§‹‚Ž‹„~n€vx…{ˆž’‘““Ž‹‡{’†w~ƒŒ‚krh€~xm||‚Šƒway„qdqh~nuqu‚›‹€…€su~so\nuy‹„‹{‡}ˆy{rm‰„‘…Œs‚z€—ŒŒ€umkv€€ut[ggunWV{RYpdKZrre[Ipxo\[[Y]t~thYb[gfodjMWfQ>]e\]ue`upZYTndYdqyZh]_fmgikipw}Žmi‚„~yn€||‚zu“„p€‹nw}€{{‡’‰hz}js{r…zsw~~Œzx„}|kŒ„›–Œ€l}kh~‹z~~ƒ“‚~}Šˆkuqghb[bgso_aks`hpˆzbst^cd› n\5Z¯µti€ˆ|’†u…•…sŽŠ‰vpl…ƒ‡uy‰x‰|“‡y~rgu‰~~˜oq†~hvynfy‡„¤‡€†Œ‰~nw‚~Ž›ˆƒ•’™Š‹…‰|ˆpz}„{h~lj€{zjzw‚‡€r`w~qdrgv‚mu{†•‘|‚owz|umYp€wuƒ‡xˆvƒ‰{yto‹‘‚†s~”‰Š{onjmtm\fdrpPZzM[o\O[rodUKsxiWYYZap€t`]]`gdiifNYhM@`c[`ua]ulXWStaZdorWj^bhkgmlhpw|“lh„Š||p~{‚zw€Š‹ƒq{ˆoqwƒ{‰Œƒj}{mwxvŠw|x€‡ƒ~~zm„Œˆ˜£„ƒzu‹xklƒ‡x}z‘~Šƒprpcf^Yf_oo_`gpfjo‰tato[adjv{€¿œ¦¤È¸q…ƒr’|w†’‚s‹‡qroƒ{ƒtt‡tˆw”ˆyypcw‡z€“ir„vgwucj|‚ˆŽ}s€u†z“‘„z—–ˆ‚‰{ˆˆkxy~tgzhkysizv€ƒ}h`w‡}jjth{€ivŒ‘”~z~~p|v|tbVx~ss‹…‚}„q‡‰xyqq„ƒŽ€z~}v†„wjqil‡qo\faqmIduK]mUSYrnbQOtxaRXX]ap‚s[a]heedkdP[pICc`[cp^]whUVUv][enhVk^aigennhpwz“miˆŒy}r{~y‚|u|ƒˆ†ƒpw„rmw‚‚~‰‹“p€{wyz‹tƒx~‚„z€uo~Š‹›žˆ}…zw…{gt…Œy~{ˆ…ƒvgon_d\XeYmra``plkh‰natiY^dn€w©ÚªÇ†‡²q‰woŒtz…z’‰tst~w€pqm„t”…xuk`z‚y‰fq„pgvn[m|€“€y‘“~y|n‰w‚’…u—‹’‡……{„ltv~mgvdm{umiwv|abx†zhuub}{gu†Ž•{t€vq€{}m€ZWupv…ˆ€zm‰†tzlv„…|~y|t‹‚~thtenŠƒlsYh^sdGmmKZaWVUwmbPRtvXPVX^aq„o\`cmdd^ocT]rFBe_]fg][{bQU\u[[gkaVj_`nefkqhpvxŽtkŽu~vx~vƒ{s}ƒˆ‡ƒor€tqu~…‰Š{wwƒ{|…‡x‡|}~„€{~svyŒŽ ‰z‰vtƒx^}…˜‹x†ƒt…†„w‰zbnl[b[[aVisc`[gnof‡qaqfW]cl|Ê·¹¡jmmŠlqƒq{ƒ‰~z„yxsyuu{jlvc„u’‚vof^}‚z‹Šer‚kjqcXmz…›ˆ‚s—”x}o‰r„‹‰s˜‘‰†‹ƒ{y}ppo|fhqbmxqjkqx}|z]ey€xivxf‚wgt‡ŒŽ”}r‡jo~yo}^Ysnu‹|‚opŠ€qwix€‚€‚w~s{u‡}{sgsan‹kqWi]v[GmjLVT^SU{kaOTurPQTW^bt…i]`ljfcZoaXcpG@g\`e^\V{^NVepY[jh]Wh`^rfkgqgpsw†xn•Štzx~y‚‡€uq†…Žƒpp{xvuz†…‡Œ…z|t‹~}†„„‡~~}‡|xvxx‘“ŸŒ}‹muxd‚†•…s‘Šo……zƒtcnjY_[\]Tgrd`XdqrfsbkeW[`jw¾®{ ¶nbs†hs{qx„z}‹~wwrvo{vejo`‡uŽ€sjb^xy‹„fqhkkZVow‰£„q™“ryv„o‚ƒ“‰t–ŠŽˆ…‰…}xtqnhx_jl_mvjgjkywzvZg}|xes~n„teu…†–pŒgkz„unub]q}lu}Œ{‚fv‡}nqivy€s~m{|‚{xqflbm‰}lmUi_vUJijNQNhMX{haNUvkLQTU_fuƒf^`qhgbWi]\khJDjYadVYUyYMVmjY]kd\Yec^tfldqgrpuxp™…v~w|…‡}ur‚ˆ€•ƒnsy{zsr…‡‰ˆƒy}u~|„ŠŽ„‚ƒz~‹ƒ{v{wwš—z‰‚†iv}{lƒ„’qŽp…‚~pflgX][\[Sdpd^WbruiupeebW\\h€por€s‰ddx~itusrƒw€ƒxvsunkzqbgkg†tƒnf]_}p{‰imygjdUWro¦|„{v–‘t}s}{o}|’‡xš}ˆ‡ƒ†ƒ}uoqlgt\lg^ltdgeizo{rYgwuhpx‚vbw…‹|”oŒjm{‚qgsfanzgsx‹|~bwƒwjlrv{q{zt~g€ywodfbm…{ljUhboRJhjOKNoG]{faMUtcJNSWajv~e]gsif`VcWbp]LKjXcaUTUsVLXudY^k`\Zce_vgmbpisor~ut™‚w€w†…z|t‚„~—…nrt|ztq„…€z‹ut|•Ž€…„|}Œ†{~€v{£¥Šyˆ…„ku|zuƒ€‹zn„sy„|ƒunjheV][ZZSbmd[Xas{ihmi`bW_[j€jko€gk`hyxjstsmƒ€z|utmzhjyj_enhv„heXbwj~‡{ojpgf]TXogŽ¨wz|Žzvqptwzy–u†ƒ€…ˆvjquggn[lc]mr_gajxh{m[n‚rtjo~zwaw…„x…sˆroy€rcqi\qxdrt‰|yct€qhjzurmyxvyd„|ywqddcn||jjThaeSJkgOGQkE`xfaMSr]JMTZekvze^mqid]V`VnnWKShWe^XMUlTJ\y_[^k]][ce`yhl`oounpwuz˜}vy€€‡†zxy‚~“„qttyvt„ˆ‘}€|ks•€{‚Ÿ…~‡}€~†‚€Š{v„«Ÿzˆ‡ƒkryu€~€tn†n|sŠ€jomddX_ZYZTajg[Z^t‚i^ml\aW\\lert}ii\kvugsvql„{}|xurlygixf]esgzw“ccTepg‚…wwgij`WVYgc§n~w€‹Ž{qr~hzp{Ž}xr„~†ndurdgg\ja\oo\g_mudzh]t€orkr|~uvbt…‹{ˆ‡€xruuapm[rtcqs…|ues€mam{pkj{yvsf†v{{vqebemr}ikSg]\TKqbPFVaGbvfaKToWJLXXgkuzdenqfdZW]XveTJ\bWgWYHWePHbxZ]_l[^\ac^~ij_ntxmpnvƒ—yr€|‰Œ†~uu†y‡Œ|tuu‚yzz‚ŒŽ}~„‰is–zŠ}~…zz|†ˆsq­Œ{{‡}dq‡ys|zurn…l{~lzbpobe]eVYYWcfk_]\r…hXpn[^XZ\l{cpwulbYlssgtuolƒx~xvmntdite[gufvv’y_]Rffjƒ‚t~bdi\TW]bc¤hxtƒ†‘ymp{iyn|†|vŠsy|xhdvl`f_^i^\skYe]oobze[w|knnoxysudsƒ’~‡ƒ‰{wor~sbxd\ppbqr‚}tgr€e^nwiehz|uno‚ut}trb_fnn|dhSgXWSLv_PJYXHbtcaITmSJMZWilq{bmlscbZZ[aw\SLc]XiSWGY`MFiuX^`l[[_bb\„iganxylojvxmƒ~“ˆ„vsˆtŒ†trvu‚w|}~Œ€~“~pw•ƒ|™’y€€xz~€tˆƒtp˜ z{‰”xcu‡xswtksn~kx|p‘r^po`gblTZZWhcmf\[q‰eSrn[ZXX`lvciuji^Ymsplsssi„|~~{vnnldiqc[krdtvŽs[WSear€r‚]bc]SZ`\c‘Ÿeqq…„‘tll{npq{}}sw€szzzdeuh]bY`gZ^vhWb]ohaw`[{vijrnxsruhq‚•ƒ‡~„vsjq}nfwX]lncrsztgo~[`prb`kr~mmusqxkpa\elly`fReTVQOtZQOXQHcsb`FUjPIPZUkkk|fnoqb[ZXYlqWRPfWVhSTFZ\NHqtX_cmcX``a]‹jcdmyxkpiuy†{kƒ}„š|‚„y|‡n‡rovz}t‚|‹‚‚—tx“…Ÿ‰u€t‚q‡‚uo¡–s{†‹†zewŠnmznfwpzksvrŒk^tnagekR][UgalkZ\pŒdOon]VXUgithbted\Xmtmoutxj†|{‡vscdkna\nmcsx‡kZTVcdx}}q†]c_cSZ_Yb••cnpƒ…Štkh|pftxu}mzuvpzv_erc[]VacXateU_`mdaq]]~phisqtpuvkm„“‰{…qsgp~qsoT\gkfqtwscmvVbrl[_pg~fmw~ssskm`Zdjiv^fScTUPSlVPVSOGdr_aEXiNHWTVmhd|ikxkbW]U[tdSRWhQXeTSHZZPMwvZ_eliYb`^^Žnafkyunoivvlƒ}‡—{€‡‰~k“ˆrgt€{u‚}ˆŽ‹“r|Š‘…‡Ÿ†{†Œs†s}‚vn¤‹r‹vwlzŒ`d{pfxrxlmqv‚gd{lcfghS_^Ug_ln[^mhNim`TVSngtkexdd\Xoslqzwrl‡{v›zxkaelm^`ojepy~gZVX`lx|{p„_b^gVX_Wc›ˆbkp‡}xlkyn\wsm{jvtop|€sXim^X\UabWdpcS^ahablZ`~kfksvomwwli…Œ‰{ˆmrgq}nsndZaiiot‚ts^imSeqeUcoc{drw|wkpmk`Yafgt\dU`URNWdRN[OOGdo]bFYiMI_KXmd`xin~d`U_T]u\TS`fN]aUSJ\YPYtu]_elhXca[^qcgjxqsnhvtzƒr‚‚zˆŽ~|‰‡ynŠuls‚t‡…†’„•y}Œ‡‘›„€|Œ…s€stxro““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~}~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’‘‘‘‘‘‘‘’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’‘’’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ”ÎÚØØØØښ„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDARÌÚØØØØÚ°    £€cggggfo„ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ”Ûéççççêœ~‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR455552FØêçççç鶠£¤¤¤§|\____^j‚€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}z{z|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹’—˜˜˜˜™™’Œ‡‡‡‡‡‡‰’“’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†…………†’””””””‹ˆˆˆˆˆˆ‰ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|yzz{|{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘‹Ž‘‘‰‡ŽŠ’’“ŽŒŽŽ‡‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽ‹Š‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…‡‰‹†Œ†‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰„Š‹†Ž…ŒŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰Œ‰‘‰‚‡†Œ‰‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}|}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹ŒŽˆ†‡†ˆ†‰ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz||||}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒŽŒŠ‹Œ‰ŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzzz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{y{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†……………„„„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰ŽŠ‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{}~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““””””“””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••””•“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””’’“““““’’“”““““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘’’““’““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’‘‘‘‘’’“’“’‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡ƒ‹Šˆ‰‰†……„„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxy}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzop{xy{|{xw{xuwttvutvwuqrqnprpghklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkigfggghhgmgjghehgccbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__`c_\_]`]^Z^]YY^ba^^ZY_\XWSNMLKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{xvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSSPMJMNPROMPQQQQRVVQQQTPPNNOLJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTttuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMOPPRQPNNONONOOPQONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKLFDFJKKKHJLLLOMLLNOOOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEBA@@CCDEACEHKOKIIJHGJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:<>><ED=?EA?@A@DEGGGGBDDEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@;;><;;<<HL==AA?BC=ADDFBFFDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnpprttsqrvyy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;::;89:87:<978;;>=;;:8:@@AB?A?CFDBCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqususqsxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<979::988::78:9:;;8789;:8<;=@A@=;;><==@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyy{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>=;<<>?=<=;:<===<<<<;;:;<>=>??A@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquuuusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCC@><=?@??=;>=>CE??@=;===<;:=>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVpoqssttuyz{{}~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???CED?=;<@>:;::97:<9==@=:<;;<;89;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pprrrtuvz{}}}~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC??AAABA@=<=;>=:::<:8988:;=??<;;<;::;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC@???@=?@><>@?===?==>CD?;<=>@==>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hloppqtuvy||}||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCDA?@@@?=@><=??@@@C@@?@@>=<=@EABBFHC=<@DCAA?>=@A>>>?<>@DGE@>@A?@CFECBCC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{||}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@A@>:><?=<:>=?BBE@??Na_J@CEIIIIMMKECFGHEGEEEDDCA?@>>BFJJGEEFFFJNNKJIGGHKLJGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@DED?<ACDB?>A?ADEDCWu†‰Š~XGHJLLMOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHIHGFEFFFDFHGEEHHFHGHFQnnpqrvvy{{{z}}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJHIGHHIGGCDECDCAUt‡‰‡‡†‡‚WILMLMNLJGGGGDGGGGFHFHECDDFEDDHHCCCGJJKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrswwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLKJKLJKIHFEGNGOl„‡†††‡‡‡‡|PKLKHGFFDECC@ACCCCFFEB@>>@AA@BD?>?DFHDEGIKIIGHIGIIJJIHFJJJJIJIJJJFILLJJKKfopsstvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKKKKKNLKMLHIOpp€†…„„…††‡‡†ŠuIIFB??@???<<<>::<AA@><998<<=;>;9;?ABAACCC@ABEDBCFHIHHHLMLGIJMMNMJJKKJLMSloqtsswyz{{|}}~~}}}}}~~~~€~€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHGIIKLOQTOXlsz…„„……†‡ˆˆˆ‰‰ŒŽfBB=88::9878896479;<:8567789787689;;<>@;999==>;;=ADEHJMLLGIHORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@BFHKHKTpe|ƒ„ƒ‚‚ƒ„†‰Š‹‹‹Š‰Š‹Œ‰T;8656766645763468:876565677778:77789;7689989876:<@GFIFIFEFOSRSSROPPRTepqsttvy{|{|}~~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:<DBDFD]|‚‚‚‚‚‚…‰ŠŠ‰‰ŠŠŠŠ‹‰‰ŠH676468874578467699766765::;::<898977779::8878588;A=>>BA?AKLOQPQOOOQWkrrttuwy{{{|}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897:A9<D?fƒ‚ƒƒ„„„†‰ŠŠˆ‡ˆˆˆŠŠŒŠ‰‰Œz>:88;<=>9:;<89;9:;:99;:9===?;;;=:>;9;;<;<<:;<8::;:999<?<=ABDIJMKJKLWorsutvx{{{|{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<:89989999:>=?@Dwƒƒ„„††‡‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>ACEEAAAB>@B@@?=>>@?>?@?@==?B?AA?A?=@@@>?A<><;:;:9;?=;;==AACABCAXqqtttvy{{|}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::<<:;;<;=>A@>b…ƒ„ƒ…„†‰‰ˆ‡†††‡ˆ‰Š‹‹ŠŠŠ‹Š‹^>DFIKJIFGGDFHGEC@@CECB@BCB?@DHECEDFEAFEFDFFD@B>=@>=?@>???>?>>:;=<`qrttuwzzz}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:>:<;>>>?;?=@?C?K~ƒ„…†††ˆ‰ˆˆ‡†††‡‰ŠŠ‹ŒŒŒ‹ŠŠˆWGLLMKNJIKHIJJIECDFGFDCEFDBHIKHGGFHGEKIKIKKJCFCCDBAACBDCCDDCA=;=@hpsttwwzx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLK@BBA97<>;<:=?>@<??CBE@h„‚……‡‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹‹ŠŒPMPMKNKJLIIJHKGEGHHIEEHFFELLMIJGGHIJNMNLLNKHFGGEECFFFFDEHHFCA?@Llptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?FGG=<@@87<;;<9=?=>>@ADCIT~ƒ…„…††‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒ‹ŠqMQOMLLKLJIHFJJEJHGKJHJGGGKLNLLHHIJMPNPNMOKIGIJHIDIHHFFGGIFCBACUnquvwy{xxzz||}~~~~}~}~~~~~€€€€€€€€€€€€€TDAABGHB?8?@8:;8<=:=?<=>@BDEMm„ƒ„„„…†‡ˆˆˆˆˆ‡†ˆˆˆˆˆ‰ŒŒ‹ŒŒŒ‹‹‹‹^RRPMNMKJGFCGJGLJGKOLKJJMMLOPNHIKLOQQPQOOJIJJLJLFGHGEGIFEEB@BB\prwxyzyyyzz{{~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<9?==?AEE>CECGLu†ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹‹ŒŒŒŒ‹‹|WVRRTROLKJEEFKONOWVQPOQSRNSTOMSLPSUWRSRPLJMMMKNGGJFFHJDDEEBDCcquyyzzz{z{zz|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?==B>AAEULBIJGKMy†ƒ……„…‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŽ‹‹‹gVVkaERQQPJ;;QSR`u]UVTVYYSYXRZfPUWZ]RTWQPNRPPPQKKKGHIHEFIIIHIjsvyyzyz{{|z{|}|}€~}}}}}}~€€€€€€€€€~~THJIIGGFE??A@EBCFEDDKWQKPPOPQy†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ}aŠ‹‹‡l[dU:XXXSP?@VUY\d`VYbr^]W]ZVEQYZ\Y_TYgRUVXTTVSOOMJLJIILMKOMSotvxyxwzzz{z{|}|~~}~}}}~}~€€€€€€€€€€~~~~VJJIHGFDDBA?HMIMPKIJOSRQUVVVTu…„…………†‡ˆ‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~Œ‰Š‹znpXZ[ZRSRWVTZZuƒYU}a\X]^WIV]][[_YHYXY\]XXYWRQMPQMMOSQQURassvwwvxyxz{{|}}}~}~}}}~~€€€€€€€€€€€xy}YMKJIIFBD@A:PQQWXPPOQSSRVWWWWl‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡ƒŠ~fYY\YSVTWRQWVc–€QerXZW_hP`fZ[X\hbGOZig\[\]]WSNSPPQVVVVYZosuwvvtwxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SOOMKJEC?@;PPZZZRSQORRQURUSV^ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PVXTRTRQQLOMKfyZ]TYUV]ZLTZTST^ZXWWWzkXZ\\^SPPPINOWVX[Zdqtvvttvxyy{{||}}~}}}~}}~€€€€~~zxwvsu{€€tk~~kry^[VUSROKFCDAM^ƒlVRSNOQOQVRSRRTcdv€‚‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ymqVIKNNKMKHJDFHEC>ScURQQNKRTQMOYQMNQSUUMQSRPNLLHCIHRSTZ]mrvvussw{z{{{}{}}}~}}}~}~€}}~~€~{vsw}~~du}iqt_d]^[YUQLILIal’tPQSNQRPS[RSRQRUUbs{|€‚}{{€ƒ‚…†‡‚†††„†…†u_]KC>CCCCB?DPCD@C>BHGV@INMG]iQHFOFDEFHGHBCHGHJGDBAC@NPMRdtuvustuz|z{{{||}|{~}}}~~€€€||}€€€}vt{mh|gnqfieeb\XSQPURsWe[OONLQRPUYSUQQTROV`klsvz{xyurnstsyx~~ƒ€ƒƒ‚€‚€‚kLG>>:;>@??>>jPJaEFHIEB?HMMGMQUJBE?><=<==?=?ACB??<=B>JMFUouvvstvxz|z}{|}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QQZ\Y^IJPQNKLQRQTUUWQQWVPX[b]agmmlokh`nrimlqu{z}zxz||xwxdB@@A=:BCAACA[\N{NOONKLMOOPLKLWNIG@B<977599=;;;8989?;AG>\tuvvuvwy|||}||||~}|}}}}~}xuwz{zvyxuw{|yxuywcqhipmnmmhf^OP^\ZIGPRQOMPQNQRSVXSRYTNYZ[WY\_^_e`]^qwk^`gkwooljonnlfbYGFFHBAFHEEFCLQOaWRXQPSSRU[OOQVPMICF>:96586979:365795<B=ftuwxwyy{}}||{|}}~~{}~}}~~~~{wuy}|yx||||twvwvuwknihqnooojk`UW^ZWMKTTSPQUOLRSTWXTTXQLWYYVXXVXY]WXXhsk]V`tkaa_]d`_^YUPMOMLIGJKIHFCPOSZWTTNQSYS\eUOSTQNKIHC?A9988978847578598Gnruxyz{{}~}}|{}|}~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPWVVSTVOOUVWXYSUTLKSUUUUWPTUWTUR]n^RNY`[VY;DUWT[fJLPRROMMNMMLJFPPUYSTNJNOTST\VRUSSOMLIHHF??=:787659967665Wqqtwyz{|}~}~||}|~}}y}}|~~~}||}}~}|rvqxxruuqqnppopuvtnjddjppqrpnfedc\^RTZVWTSVTRXXYYYRUOJGOPOOMRJOPOONNOTLMIPPSTU2<XMIAQ=c`QSQPNPPONNMPNTRPRLILKOQPQRSTQSOLMKLLHCBA=:9876;B4566;eprvxy{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqpuuvcjgeWhtrrqniihpVVTUXUVURWVUZYXWUQSFEAFGGHFJDHJHGEHLHKIGLMPMG/E_R>3@>joaRRQ@GTQOPPQNQOPOLJLLOPNMPQQNPOJLMMKGEEDB;==<9=G6676Dnquwz|{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknbePSTRSUOWVVYYVQQQO@>;=?@BAC@BEDA@GHGHFFHJMLDGCORC8ENS]gSQSAGUPPRQPMMNLJLKLNOPQLNNMHLKIKKLKGFFED<AA>;@E;<89Tqsuy{{{|||{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLONMQSLTUTWWULLKH=987;?A>==A@B=>EHFDFFIGJJ@FAA@FHEJOHQRa\QPRNSOOOLLOMKMLMON[VJMQOGIHDIJLLKFFFD?CC>=BG?B>Adqtw{z{{|{zzw|wy~~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCE=9879?B?;>A@@>ADIECHGIGIEBB?><CBAGIDMOaePMONWKLNKKMMLLKNNSdMJLRIIIEAHJLMNKGIFBBB@?EFEHDLopwzzy{{z|zwsxtx||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGLLIMPMPOGKE?B=999:?B?<ABAADDGKFDIIGGHCC?B??@A=CECKNQTKJIMTFIIJLJKKIJLMOPRPKGCLGCCJJLMONIJIGCCCDIJMLIZsnxyxz{{y|vrpurtyyvxjqnjllnttmsu{stxronqovsnporpopstyjN`gsjt|ygosqiqheqHKCFGGGJKIJLDGB=>=:::;AB?=BBCCHFJLJEIIFGGCC;A@B>@?BECIMOGHKFHKDHIKMHJLHIJLJM]RIHDNGBEKKNMPNKMJKFGGJMNQNLcnjwvv{x{z}qmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoijthdpFKCFEFDEEFEGCC@=<=:;::@DA?BCEEIFJJLFIIGFFDB;BCC>?BCCDGLNHKNHDHDILNMGILGFFIILNKJHEOICGMMNMPNOOMLIHIOSQRNRfgfrosxu{z|lhjoekpmsqfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhme_pGICEEEBBAE@DB>?>:;;=;=?CB?ACFGJGJILHGGGFEC?=EEB>ACBCEGHIGMPIFFFKNOKFHIFEDDIIHKIFHPKDJMLPNONOPNJJHMRUUROWdaamgqrosyzgehhcilgqlflmgiklsmpvutpnvrosrsutqssutsuvvvyvutvlkuumrvqlnlerMGDEGCA@AD<BA>A=::=?;>?@B?@BEGJFJGIGFFFDCBAAFFCBBBDEEGGHFLPLIOJJLKIFHEFEDCIHHKJGKRMCOONQPOONOOKKKPUWVUTY`_]ianinhrsbeffdihfnifmmhkkmriqvusqmvnoqrswsrstuvvvvwvwvvtwuksunutsprkksMFGEGAB@CD<AA@C<8:=>:?=?B?@@DFHEHFFHFEECCEBDIFCGEAEGEFFGEJMKHQMJKHHIEFHHECIIJKMKPSNDRSQQRNONNPMLNSWVWXVX^Z]d`hbjigk_defcgggkggkmkmlpqgttursnvoqprtxqssuvu‚‘yvvtxuuwxnouorsuqqipzMGGGHBBBEE<@CBD<7:=>:>:@B>??CEFDFDDGECECDEFFJEEIGBGHFGFECFJJGMKLKHJKFIHJHEKKLLNORTOITUTQTPQMNQNMQWZVZYWZ^ZXa```_hec`deggjihjfhnllomqpiuuxrrpupppruvpusuvu{~}xvtwvvvwplupmsunossyMHHGIDACHE<@EBD<8:>>=<<BB<@>ABFCEBBGCCDEFFGGIFGKHCIHGIGFDHKIGKHMKJKLHLJMKINLNNORUVOLVVTQTRRLOQPOTYZY\ZZ\__^`c^\ackb`dghr…hgjfjnnponsqjtuxrsstrnpqvrquruus~yŽ}uuvvvvxriuqkrtlqwquKHKHJEBDGE<@GDD@9<>@?>?CB<@>AAFCEDCHDFDFFHHFHGIKJEJHHJHFFLHHHJGLLLLLIMKMNMOLPPQUVWOKVVUSSRQLORRQV[[]^[]^``a`ae]d`fg`ehjcssfjhglprqossnswwpuvtsmoruorspurvrtvuuuwvuwtgtrkqrkrwowIJKIKGBDDE<@FDDB;??A@@@DA@B?ACHBEDFGEIEFEIHFIHJLHHJJIKJFJKHIJJGKKMLJJMLMNNOLOPRUWVMNTVUSRQPMNTSRW[^^_\^``aaa`cdebdicdijgv‹lkigmosqpqpprywruutsmmssmqrotutspswtuuwvuuteqskpqjrvpwJLKKLGCCAD<?EEEC=AACBBCEACDAAEGCGGGFEIFCGJGGJFILHIJMKMLGKIHKKNQKRQLSMKNMNPPPTOWXX[NSQW\ZSVPNTUTTXZ_bb_da_`b_`fbacinhcihhmxvlhimosrpqrrrvtsusssnksqmprotvrrquvuswywutucmtkopjqtpwLMLLLGEA@D>>DEFC?CAECDFCCEGCBIEBHIIGHJFDKJGHJHIKGJJNKNKILHJMKZfJd\KlRHOM_nUls[qpbwcRPbvuhucav`Xnqbdvinzf\lt`lkU_wvijhhfglmjmojmnsrprrqrsrssrtrnltonpqquuqqstvvuuywutt`ktkppkqsqyKNJKJFB?@B?=DEFDCCBEEDFBFFGCDKDDJLKIKLGGNJHJKGKJIJJNLMLLLIMLL[sbdp^llUMNer]geqlntgpi_aYnmbppbkjjgoqtetno\pugqMKryvkaakeelxmkvlnpsrprqpqrqrrrtrmmsnnoprutqsstuuutwxvutbmukpplrrqzKLIIGED?AB?=BEGBFCEDEEDBHHGDEKGGKMMJMLFJNHJKJIKJJIJLMNMMMKNMM[roonpplkMPQlXNibtrpamov\YlP[mmZqmkomxxtsip\`slqjUuyxoc^kfbgppjioppsspqpqqrrqqrrtlmrmmnorutqtrtuutuuzvutenukpolsrryIKGHFEEBAB=??EGBGDIEEDBFIHHEGKJGMMNKMNGLNIMKHJMIKIJJNONNMLNML\hdu]lqWlNOQnUZk^klvaldtTecNlYl\tpkilxjwuhp]_skhWbcw|oc`ghacityknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtvHMGIEEDCAB<B@BFCGFKGECCHKHHFILKFMKLRRLGMMHNJIHNHJJHHNONNLJMMJZsppoqqmlOQSoYskgooqqomt^nXat_nopoqroousttj[]tcwxrjnzhaacfabjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyytukoumtonssvtIKHJCEEE@@>CCAFCHIMHFCFJLIGFJMLFOJKWRKGKJJNIIJLIKJIHKMMMLIKKKSkbZi^_jcrrZ_Yko`eeUk_c[abQ`mh\j\niidZoedp]Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunwqrutwrIHFIDEDFA@AEDCGBHJLGFDGKLIEFJNKIOIL[QJFHHKMIHJJKKIHJGLKKKGHJJLLLKIKLNT[]TPUMQPNOOURPOQOOQJJOPQdqiTYV[[\UY[]X]\\cfaafbcf_^fkmhmtxrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyyxuvqruovrtsuusHCEGFFAEC?CGDEGCIKLHFDGKLHDGHPKLOKLWMIFEHIJHIKHLJIFHHJGGIEFKHIKNLIO\W^O\\`^OXYS\\b^MYZMXaRKYaZS`d]bX[ddVVX\YZX\VY\^c_d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtOBCDLMBCDBDIEGGFKJKHEFJJJFDHHPJLMJMRIHEAHFJIKKILJIGEJHEFGEEJGBIMJKT_Y`X`a[`UXYT^^Z_RY\P^\YN_\^S[^c_Z]`c_Y_b[`^[TYXZ_^dbbaceiekrpoppnow††……†‚{€……††…†…uqprrsvyyzyyxxxwryvxrqxvtvaSJJMIECBCFGEGGIJJIIDGKJJDEIINJNLHLNGHF>GGLIKKJKKIGEIECDEBFJD?IKHN[cY^^a_RTSW_`\]Y^QY\MV_WKQY[Q[_aa]^ca`babcceZRXVV\[^c`__cebhommllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxXQJFCGEBEGHFGHIFGJGHFHKIKDDJJMMLLHJJHJG?GFNJKKMKKKIGHDD@DAHIA>HIFO]aZ[d]_TQRX]\\\_ZKW\LR\YIM^QQ]_accccb\dbadcfXQVUS\X[a_^_aa_dlkmjklnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMB@IFCFKIFFGIGGJFFFILJNEDJJLNJLIKJHIGBHHQMKKOMKKIHHED?EBHHA@FECT]Y^X_X_[]UXXP]]QKJV^X^[]VZaRR__bb``bb`cbaddbXORRS\S\^]^^__`dhgljnnp{{|~{€‚ƒ„………………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKBAGFDGMRHDRKFHHHDFKIMPEGIJKNLLILKIIGDHKQOMLPLLKKIIDEAECHFAAFDAVUE\T^SV`XNTUNZ[MJKT`a[_X_^b]OYb\``_bcb]bbW__TPOQRYS^\\]^_`affelfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDFFGDIRcQDW_IGGHDFMJPPFIIJKNLLKMKJJGEINQQNOOMNMNHKADACDFDBACD@LHBLLPOOMFMFFHIHGLLMOPILOPPSPLQSRUZYWYXXdVOSTPPONQUT\YY[^^aaefchdklqsszy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKM^MGHYMGHJHGMLQQIKJKKNMUNOKKLGGKOSSNPONOOOHKF`ED_LDfcCL[H^[smONVmYLCP_TlWgJ]WU^DLQULMSVQRTXWTXUT\TPfZhhdYTkTXWU[\\``abbb`gignlhrz|}~„„„„ƒƒƒ}}zr{z{‚€ƒ„„……„…ƒƒ~z{KIEFFHEEKOTJKG`THJOJIOMRQKMKLORUROOJLMGHMQ[YOPPNOPPIKQQI|YYrsWPmHqnoaVRrqtOBksnqtpSo_[nX]V\XUkhU]VcY`YZ_VUWituu_av`Yb\\f[_aaab^`bgmpl`pwtx‚ƒ„‚}~€vxzmv~tx~€|~€‚„|€ƒz~wwMIEHMMBDLLGJLFRVLLOHKRXWQNOOMQTNOQPKKNGMPS[ZTQROPPQKIZx]TxdhYRSPvgtlpbngkQrOLwmjrpsrqrpop€]fzuxqqzq~r}ku}bRg|essoss|}o~yor_``bb[a`hknkblfgmw~€ƒ~{xw€tvzhr~nt|~wx{~€ƒx|u|||ssNKF`]GAEMMHKKHJQOMNJNV^YULQSNYYLSSRNLOIQRTYWWQTPPQSLHgxlcxqmZKLTypumubowQddIevqmwo€jfxxiWrRi{mijzz}lxzpgoXuujvup€ash|ilx|o___cb\_defijdgbcdllppstsssyqrxbltgry{sruy~svzn|}yxrnMJRtNCBEPPIKLJLQOOOMPZ`ZXKTWPa^RVQYSMPJSTUXWWPUPONSJKrouuquqdhaVnLqp^GhyWvTKhx}x`y{sna^modSgrunmypwlvstqlm\s}zkmy|lum|kpvux^__b^]_edighee^bbiiijknokqnmjpacfdowxompsynqpj{ztromKKZVHGEGRPKLNKLQQPPPQW\YUNVYUfXRRY^TMNJTTVWYWOSOONQIRmHiwK`dvuUWlNnl{rajguTKWkh}lmlx`[pz{_`zscroxqhd|ir{]TKl_vukiu{{m~xk|p]^^b[^bdegeeebZccikkrsrwgmihdg`alagsrlhmmr|kmhk{tmmkmOGJKHJHHRQMOPMLSSROSRWRVTPWZVVTTTa`QONKTSSQVVOOMNOQJHQNPULKKRSRRROVUQQORRXXPNPUTXXX[[USSW[WXW[ORTWWXQ]XV]USOXRVWWXZ`[gr^[[[]]_cZ_ccefdccbZccgffmnmuffgc`f_]g`dlhfgkhpzhggkujhgilPIKKLMKJTRMRQPLVUTPTUXUZURZ]VUTWUYXPOLNWTPNUSNPNLQPKJQQKQMJKOQTRPQSRIIMNOQRPPQTVRXW\WSSQQUUVTZQNRQWUTYVTYUSQUSTUXYX^Z_a]\ZZ]]`c\]bbdgeddaY`acabhhincad^_c]Zd\bma^ffgmsdihkkedcfhQJKKNOLMTQOTQQMXWUTVXWWZVT\`VWUYUXTQPKOXSPNUQNRNLSPMNUSNQNMNQSPTPRTTNLNOQTTQQQVWUYZ[YSURTXWWY[SORTWUTYUVYUQQWUVX\Z[`]VY_]^]\]`a^[bbchfedbX``b]`hefda^_]]^ZZ_Z_g`^^]chkahfhfd`bdbPKMLPQLOTPPTQOQZYXWYZZXYV]jdVXYZWVTTOKOVTPOTPPQNMQQORXSQQOMOSUNWQTTUONNQTUURRRTXVZ]\ZVVQRWXV[\VPSUUUVXSWWTRQXVV[_[^`_V_]^`\\``__ZbbdhhedbYb`b^^fdc`b]\\\\YZ[X[a[^]\_b__bddbd__`\PMNNRQMRSPSTQOU\ZZW[[\YZ[dqmhd_[YVVXRMMVSMNROQROMPSRUZUSPPLPWUQVRSRXMOPQTXUTTSUYX[^]\[VROUVU[[VQSVUVXTSXZTSQYWW]_[`_`Vb\`a]`b_\`]c`cgief`Zc`a__ee_`c[Z\[\ZZYYW\Z\[`^`[^^a`_c\Y`ZQNONVQPUSPUTSPW\\\Y^\_W\^jpwy€c\[VVYRNOWSNQQPRTRLQTSY[WUORNSXUSRTRRZOQSSV[VVVTVZX]^\\^VSNTVV[[UQTTVXXRSY\TRR\XZ]^]aa`Wb[cb^ac_\bab_dgidg^\e`a`acd_b_YZ_[\[XXYWWZZZa\][]\\Z]`W[[ZPOOOYPUUSRWRTPZ]^]\`\`U\]hjr}slh\UYWQOR[SRQTRTUTKRVUZZZSOSQUUUSNUQRZRTUTX]WXXSX\X^]YZ]TUNVVW^ZXQTTXXXSVY\TRV]Y]]a^cc_Y`[eb_dd^^cca^efief]^daaabcd_b^X[_[\[XXXXW[Z[`][[\[XZ[^V^Y]POORZP[UUWVTTT^^`_^b\`U]^bkyum}lZUZVQQT\TTTUTVYWLRZV\Z\RPUSWUUSOWQSWSWUV[]X[YUZ^X_^Y\YRWRYXY_YYRTUZYYUWY\UTZ]\^`a`ed]^]]eabfd^_dc`\gdhfdb_da_a`bb_`^WY^Z\\ZYYWV]Z]^[Z[\[WY\]VXW]SOPWYP]UVYWWUX_`aa`c]`U]^beev‚{hXYZTVTV\XWWVVW]XOU\Y^]]TSXRWUSRSWQSVTXXX]^X][U^_X__X\VQYUYZZaX[TVWZZZXYYZWV]^_^cbbee]b\`fbefd_`dba[fchfcfaf__abaa`_^VU]Y[\[Y\YY][[[XXY[YZZ]_]TY]UNSZWT\UVWYWV\`aacac__V[`da_zuohZ\ZVXVX[ZY[YXY`VOT][`a\UUYPTVTRVUQSUW[[\_^Z_\V__Z]^Y^VSYXYZ]aY]UVZ[Z[ZZYZXY__``dcdeebdZbfcgfe^ab`c^cciedg_g^bbcaa`^_XTZZZ[[X\XX\[Z[WWZXW\[\`]V]]SOVZVVZVYUXWX^`badada^YYadb`kfh^\][WWYZ\\\_[Y[bVSW^]ac\SVYPVUUUVUSUTX]]_``]a]W`^[^\[^XVXX[Z__Z^WX\\]]][Z\WZ_a^`eddfffbYcfehgd^c`_ec]fideh_g^cbcaa`__[XY[YZZXZXW[\Z[WXZTY]\Z`\U^bMRWYVWZY[\YWY^`baeada]^Yacb_a`a_]]]XW[[]]__\Z]cXYW\`cd_RYYPWVWXWVVWV]]^aba_b^Ya]]^Y]^YXUW[[`^\_YY]]^^`\ZZY[_b_bedefggbZdfgigc_c^`feZiicficf_bbca``_]]ZX[YYXXZYWZ[ZYWXVU[]]]``bbxKWW\YW]\\]ZW\]_`bdbca]`Xbcb`cac^\]\XW[]_]`_][`d\\WZbecaR\YOXVY[YYWZZ`^abc`ac_\b]_][_^YYTX]]__^_[Z^^`bb\\W[]`bbcedgfegd]efhifcab\cg`\iichife`baca_`_]]\Y\YXWXYYW\[ZWWXPXZ]acffrkJYW][Z_]\^\Y][^_bcbaa]b[bda_cbb]\[ZWXiq`\`_]\ac_]XYcedbT_ZQYW\]\[Y[[c`ccc`bda`c^`\^__ZXV[_]\aa_][`abeb^\S\_`cddfegfefe_ffhhgdd`[fg^ahhbhhfc`b`cb___]][Z[YXXXVZV\ZZVVULXW\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡…‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vvvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{{{{{{{{{||||{|{zzzzz{{|||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vvvvvvvwwvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{{{|{{{{{|}}}}|}|zzzzz{{||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||upooooppz~}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰Š‡sqrrrrt>(+++*"‹ÛÒÒÒÒÖº}~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}upnoooooz€~†“y1333332j‚€€€{­éääääèʉŒŒŒŒŒ‰rooooor2ŽïååååéÇ}~}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}vuuuuuuuvwwwwwwxyyyyyzxopppppprrrrrrrwzyyzzz~ƒƒƒƒƒ„|||||||zzzzzzzussssss}…„„„„…‚|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚‚‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vvvvvvywvvz{x{xwvvxyzyz~yyyxxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{{{{{{{{|}}}}}}{zzzzzz{||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwww|{z|z}{xwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwwy~{y}y}zxxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z|yww{~|y|z{zwxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚ƒ‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzzx{||}{}{xxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyywxz{zy{xxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyxyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{|||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}|||||||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}|}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚€€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrstuttssrrsrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqstsssrqqppnnnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqqrssssqpqpoonnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrqrrssrrqppoopoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpppqrrqqqpopooppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqpqqqqqqpooppppppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqqqqqpppppppppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsquŒ‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqqqpqqqqpqpqpqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrqqqqqrqqqrrqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrssrrrrrstrrsrsssssssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz|~~|vvwwvuxzxxxxwwwvx|yy|zyy|{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~|{{z{|{}|{{{{{{zyxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}|||~|}~~~~~}}||}ƒ€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€€€€‚€€~~~~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~~€€€~~~~}~~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~~}~€~~~~~~~~~€€€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹Š‹‹Š‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚‚€€€€€€€€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒŽ‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒƒ‚„„‚ƒ‚‡ƒ‚‚€‚‚‚‚ƒ‚‚ƒ‚ƒ‚ƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒ‚ƒ€‚ƒ‚…………††‡†…††‡‡‡†††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠˆ‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„„ƒ‚ƒ…ƒ‚‚„…‡‡‡‡††‡‡‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ’‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„„ƒƒƒƒ„…„„……„ƒƒ„……‚„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘’’ŽŽ‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€‚‚‚‚‚‚‚‚‚ƒ€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„…„„…„…†’“‘ŽŽŽŽ‰ˆ‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~~€‚€‚‚‚€€€€~€‚€‚ƒƒ€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“’Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚„‚‚ƒ„‚ƒ„…†„‚„‚€‚‚‚„ƒ‚ƒ‚‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘ŽŒ‡…ƒƒƒ‚‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒ€ƒ‚ƒ……ƒƒƒ„ƒ„ƒƒ„„…„„„‚€‚ƒ‚‚„ƒƒ‚‚„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”““’ŒŒŠ…„„ƒƒ‚‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~€€‚€€‚‚‚‚‚‚€‚‚‚‚‚ƒƒ‚‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†”“’”’‹‡„„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~€€€€€€ƒ€‚„ƒ‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“‘Š†ƒƒƒ„‚‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€€€ƒ‚‚ƒ‚‚‚ƒƒƒ„‚ƒƒƒ‚€€€‚‚‚ƒ‚‚ƒƒƒƒ‚ƒƒ„‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†ƒ„ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„„„‚‚‚ƒ‚‚„‚‚†…ƒ…ƒƒ„„„……„„…‚}}}~‚„ƒƒƒƒƒ„ƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„„†………„…†…††…………………………††…†††…†††‡†…………ƒ„„„‡““’‘’ŒŠˆ…………‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒƒƒƒƒ„…ƒ‚ƒ„……†…††……‡‡†ƒ€~~~~~ƒ„ƒƒ„„„„„„„„„„„„………„…„†……†…†††…†……‡……†…††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„ƒƒƒ…………‡‡†‡‡…~€„…„…†††…………††‡††…†……†‡‡‡ˆ‡‡‡†††‡‡‡†††‡†††…„ƒ„………„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘“’‘‹ˆˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒƒ„ƒƒ‚„…„…‡‡…‡ƒ€€€€……†‡ˆˆ‡‡‡‡ˆ‡ˆ‡ˆˆˆ††‡ˆˆ‰‰‰ˆ‡†‡‡‡ˆˆ†‡†‡‡††…„ƒ„…†…………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†…†„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡‡…ƒƒ…„ƒƒƒ‚…„ƒ„‚‚€€~{z€†ˆˆŠŠ‰‰ˆˆ‰‰‰‰Š‹Šˆˆˆ‰Š‹‹ŠŠˆˆ‡ˆˆˆ‡‡ˆˆ‡ˆ†‡†„ƒƒ…‡‡‡†……„„ƒ……„……†„„„………†…†…ƒ‰”“Ž‘ŽŠ†…†…ƒ‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡†„„…„ƒƒ…ƒˆˆƒ‚‚‚‚‚€~|}}}~|{|ƒ‡‰‹‹ŠŠŠˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰‡†††‡…†ˆˆ‰ˆ‡†‡„ƒ‚„ˆˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚‚ƒ‚„ƒ„ƒŽ“’‹ˆ…„†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„……„ƒŠ‚‚‚‚‚‚ƒ~}~~~~~~}}~}}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡‡‰†ˆ†ˆ‡‡‰ˆƒƒ„ƒ…„„……†ˆ‡†…ƒ‚‚ƒ…‡†‡††ƒ‚‚ƒ„‚ƒƒ„‚‚ƒƒ„ƒ„‘’‘ŽŽ‹‡„††„‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…†ˆ‹Š†„†„‚††‚€‡†ƒƒƒƒ‚‚}|}€~~~}|}}|z|„†‡†„ƒƒƒ„………ƒƒ…„„„„„„…„‚‚ƒ„„‚ƒƒ…†…„‚‚‚ƒƒ…ƒ„„…„„†ƒ„„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰†„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………‡‡‡‡†€…ƒƒ„…„‡ˆ…‚€€}~ƒƒƒƒƒ‚‚€}}€€}~~}}}}zzz~ƒ„„‚€‚‚~‚ƒ€‚‚‚‚ƒƒ€€€ƒ‚€€€€€‚‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†Œ“‘Ž‹ˆ……ƒ‚„‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€ƒ‚~~~||ƒƒ‚ƒ‚ƒ}}~€€€~}}}}~}|zzz‚‚~€~}€€€€€~}}€~€€€€€€€‚€€‚‚€‚„ƒ†’ŽŠ‡‡†ƒƒ‚‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒ‚ƒ„…€€|}}~}~~€€~}~}|}~‚ƒƒ‚‚}}~€€€~}}}|{{{zzyz€€€~~~~|~~€~€€~}~~}|~€~~€€€~€€~€€…’’Ž‹‹‡‰…„ƒ‚‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~~~~€€~€~}„ƒ‚€~}~~€€€~}}}}{{|zzyyy{€€~}~~€€~€€‚€|~~~~}|€~€~~€€~€~~~~~}||}…“’Œ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒƒ‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚ƒ~€‚ƒƒ€€}}}~~~~}}}}}|||{zyyyy}€€€€€€‚‚€~€~~~~~€‚€€€~€€~~€}~}}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…ƒƒƒƒ…„„„„ƒƒƒƒ‚‚‚‚‚~~}}}~~€}}}}}}}}|{zzyyyy€‚‚‚„ƒ€‚ƒ€‚€ƒ‚ƒƒ‚€€€ƒ„‚€€€€€€‚‚€€€€€€~~||Š“Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…ƒ„…„…†††††……†€ƒƒƒ‚‚€}}}}}}~~}}}}}}}}}|{yyyyx|‚ƒ„…‚„ƒ‚‚ƒ…†‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚‚„ƒ‚ƒ‚‚‚‚€€€~Ž“Œ‡ˆ†ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€€~}}}~~~€ƒ„‡ˆ„†††…††‡‡††‡‡‡†‡‡}€€‚~}}}}}}}}}}}}||~~~|{yxwxyy€ƒƒƒ„ƒ„„„——ƒƒ„}~‚‚‚‚ƒ†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ……„…ƒ‚ƒƒ‚ƒƒ‚‚‚‚ƒƒ‚‚’‹ˆˆ‡‰‡††„†…„„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€~}~~€‚………‡†‡‡†‡‡ˆ††‡‡†‡ˆ‡|}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yxy|~‰—„ƒƒ„„”“€~~…‹€€€„†‰…„‚‚……‹ƒ‚……††„ƒ……ƒ„„ƒƒ„ƒ…„„ˆ’Ž‹‰ˆˆ‰‡‡‡…†…„…„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„„†…€}|||}}||}}}}}}}}}}||‘•–ƒ{z„”|xyz{|‚ƒ€ƒ‚€~|~~{ˆ‘||Ž–}‚†Š…ƒƒ„ƒƒ‰~ƒ„……ƒ…†…„……ƒ„……†„„Ž‘‹ŠŠŒ‰ˆ‰‡…†…ƒƒ‚‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚‚ƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚ƒ}}||}}|||}||}|}}}|||{‹‘—Œz{|zzz{|yy}}~€€|{{~~}‚•‘„ˆ~|~‚„||‚„‚€‡ƒ}‚‚‚€ƒƒ„„„„„‚„ƒ„…‚„‘‘Ž‹ŒŒŽŠ‰‰………ƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚ƒ…ƒƒ…………ƒƒƒ„‚ƒƒ‚ƒ‚‚€€~}~}||||||||||||||}|||~~Š‚{z{zxz{{|}{~}~}}}}||}†~}‚~~€‚||€‚€~|{Š‚}€~€€‚‚€€€€‹“‹‹ˆ‡‡……„„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ…„††„„€†”ˆ€‚€~~~€|||||||||||||}|||||||y{{{xxy{zz|€~|~~}€‚‚€€€‚‘€€~€~~~€}}}{}}}|}||}€€€~€~~“‘ŒŒŠ…††…„„…ƒƒƒ‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚„†‡††~ˆ•Š~€€€~€~~~|{{|||||||||~}|{}|||{|||zzy{|z}…ƒ‚~~€~…‚~€~~€…†‚€~~ƒ†~|~€€€~}}}}~{|}€}~‹ŒŒŽ‡„††…„„„ƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}~€‚ƒ††……~€€~€~~}€€€€}}||}~}|}}}}}}|~|}|{}||z{z|}}†„‚€€}~}~~‹„†~}||~‚}}}}€|{}|~„ƒ€~~~~}}}~€~~~„‘Œ‹‹Ž‹Š†„…„„ƒƒƒƒ‚ƒ‚ƒ‚ƒ‚€}|||}~{{}w~vx~}|}|}~~‚ƒ€z}}|~€€~€~~€€€€~~~~~~}~}|~}~}}|{|||z{z}~€ƒƒ‚~|}|}||ƒ~Œ~|{{}~}~~}{{{}{z{{{€†…‚„ƒ‚€~‚‚‚‚‚€‹ŒŠŠŒ‹Šˆ„„„ƒ„ƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€~€€€}€~~~|‚~~}}}{{}}|z||~€‚€€€||}|||||}|}{~{{{|||}|{{{{}|zz}z~‚~ƒ„‚‚…†……††‡†‚„‘ŽŒŠˆŠ‡ˆ…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~~€€‚€~~€€~}ƒ||}}|}}}}{|~~~~~~~|||||||~~{|{||||}|}|~|}||{{|y{|{{}{}~~€€ƒ‡‰‰‰‹‰‹‰…ˆ‘‹ˆˆ†……ƒ‚‚ƒ„„ƒƒ‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€~~~}€€€€ƒ‚€€€€€€€€~|z|}}~}}~~Œ†}}~{{ƒ‚}}}}}|}}}}}~|}|}|}}~|~}}}}|{{{|{||{z{{zzz{~~‚…ˆ‡ˆŠ‹‹‹‰ŒŒ‰ˆ†…„‚‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„„€€€€‚~}~€~{~‘Œ|}Š€Œ~~}}}~}}~}|||}}|}|}}}~}}~~|{{{||}|{z{|yzyxy{~„ƒ„‡‰Šˆ‰ŒŠˆˆ…„„‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{|||~~}}‚€€€‚…ƒ„‚‚‚‚€€ƒ‚€}~€~|~ˆ‚~ƒ„„ƒ~}|‡}}~}||~|}}|}}}~}~}}}{|}~||{|}zzyyyy{{~~€ƒ‡„ˆŒ‰‰†…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{|}}}}zx‚€‚‚€€€€€‚‚‚‚†…„‚ƒ€‚„~€}~~}~€€}~„€~~}~}}Š…}~}~~€}}}|}~~}€}~}|}||{|}{{{zzz{{|}~}€ƒ€‰Œ‰‹‡………„ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv}€ƒ‚‚‚‚‚ƒƒƒ‚…†„‚€€€€‚€ƒ~~€€}~€~}~~€€~€|€~€~|}}|~~~~€}‚€|}€}||}}||{||{{{|{|||}|‰‰‡ˆ…†……„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚‚‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€ƒ€€€€ƒ~~€€}€}}~~€€‚€€€}€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{|~|}|||z|{|~‰…†„…‡…„…„‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz}}yxtt€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚~~~€}~€}}}~€€‚€€€‚~~€€€€€~}}}~|~~}}„€~}}}~}~~}~|{|z|{z€†‚„„…„„ƒ…ƒ‚‚‚€€‚‚ƒ‚‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xytu}‚ƒ‚ƒƒƒƒ…„…„ƒƒ„„ƒƒ„‚€€€~}}~€~~~€}}|}}~€€€€‚€€€‚€€~€~€€€~~~~~~~~……€€ƒ~€~€~}{z{z|{z‚„€‚‚‚‚ƒ‚„‚€€‚€€‚ƒ‚ƒ„ƒ„‚„‚‚‚‚~€~}~~~~}~}}z{|…„{{syz|pwuvwyvtz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€~€}}}~€}~~}~|}}~€€€€€ƒ‚€~€€€€€€€€‚‚‚„€ƒ‚€€|{{z|{|€€‚‚€~‚‚ƒƒƒ‚„‚„‚€‚€~€€}~~}}}~}}{{z€x|vyy{qtxwvxury……‚„„‚„……†„„‚„ƒƒ‚€€~€~|}}~€}~~}|~~~~€€ƒƒƒ€€‚€€€€€€€€€‚ƒ€„}ƒ„€€‚}z{{||}}€|}}€€~}}€~‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxyzruyyvwwsu†…ƒ……‚„„…„„„‚ƒ‚ƒ€~€~€}}}~~€~~}|€|~€~€‚ƒ€€‚ƒ„‚€€‚€€€‚ƒ‚ƒ€~‚‚„€€‚‚‚„‚~{{|||}}}~}z~}}x~|||~}~€€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„‚„„…ƒƒ‚ƒƒ€}~}}}€~~~}}€€~|~~~‚‚ƒ‡…~~€€€€€€‚‚€€~€‚~‚‚ƒ‚ƒƒ…‚}}}|{||yz{z~y{yx~{{{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst†„„…ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€|€€~€}~}~€€€~|~€€€~}~~€}€€ƒ„ƒ~}~~~€€€‚€~~€‚‚€„‚„„†„€~}||||zyvyyzyvyv~|{{{~|{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…ƒƒƒƒƒƒ‚‚ƒ‚ƒ‚~~€}}}}€€€€|€€€€|€}~~}~~‚‚~~}~~~~€}€€€~~~~~€‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{z{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvqwyrx…………ƒ„ƒ‚‚ƒ‚‚€‚€~~~~€~}~|~€€€€{€~€€€}€~~}}}~€‚€~~~~}}~~~|€~~~‚~~€€ƒ‚ƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}}{|z{}zzx{|zz{xtxuqrtpxxqy„…†…ƒ„ƒ‚ƒƒ‚‚‚€€€€}~~€}|~}€€€|€€~€}€~~}}|€€€€~~~~}|~~~|}€~}~€‚~€€~„‚‚ƒ……‚‚~~|{{||yw{ywxwwx{{z{|…Š}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzz{zxswuqqrpxwq{…†……ƒ…‚ƒƒ‚€€€€~~}|~}€€‚€}~€~€€€}~|}€€€€~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{|||zzzzzzxsvupprowvr{…†„…ƒ„‚ƒ‚‚‚‚‚€€}}~€‚‚}~~~€€€‚€€€~|~|€€€€€~}~~€€‚€€€€€„‚‚€~|}~~z}…~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚€€€€€€~}€€‚‚‚€~€€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€€‚€€~}~{“z|}|{}y{zzxyxy{||}|||||||}}}||}|~}~~~}|z||{|}{yzzzyysuuooqpwst}…†ƒƒ‚ƒ‚€€‚‚‚€‚‚€€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€€‚‚€€€}~~|†‰||~{{~yz{z{~wwy{|{}||||{}|}}}}|}|~~~~|z|}{}}{yz{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚‚€~‚‚„ƒ€‚€€€€}€€€€€€~€€€~}~€~~€€€€€€€‚‚‚€€€€€€}~€}€ƒ‚{~~{|}{z||{‡yxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€€€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ„„€~‚€€€€‚~€€‚€€€€€€€€€~}€€€€€€€€€€€€‚€€€€€~}~}~~{}|}{||wxuxxy{||}|||||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒƒƒƒ‚‚ƒ€‚…ƒƒ„ƒ€‚ƒ€€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€€‚€~€€€€€€€€€€€€€€€€€€€€€€‚ƒ‚‚€‚‚€€€‡~~|z}|{}~xwvyyy|}||}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚ƒ„„€€‚†ƒ„ƒ‚„€„ƒ‚‚€€‚‚„‚‚„‚€€ƒ‚€€€€ƒ~€ƒ‚}‚€€€~€€€€€€‚‚€‚ƒ‚‚ƒƒƒ‚€€€„}}}|}z}€zyvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysruowqwysw{…‚‚ƒ‚ƒ„‚ƒ„ƒ€€‚‚†ƒƒƒ‚‚„„ƒ‚€€‚„‚‚‚~€€‚‚‚‚€€€€€‚„€~ƒ€ƒ‚€~€‚ƒ‚€ƒ‚ƒ‚ƒ‚‚„€ƒ‚„ƒ‚„„ƒƒ„ƒƒ€‚€}€|z|{{w|yyy{z}~}||||}~~€€€„„€}€~{{{z{ztpxrytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚‚„†„‚ƒƒƒ„„„€ƒ€ƒ‚‚‚‚‚€‚€~€€‚‚‚‚‚€ƒ‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚‚„ƒƒ„‚„‚ƒ‚‚‚‚ƒƒ„ƒ„„„„„…ƒ„‚ƒ‚‚ƒ€€~||€||x|yzyz|}|{||}}}||€€€€€‚~€€€€{{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚ƒ†„„ƒƒ‚ƒ„„…‚‚‚ƒƒ‚‚‚€€}€€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€ƒ€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒƒƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{~~}y|zzz}}|}z||}}|z{~~~€€€€€€€€€}}||}|vrvxxvtvu}‡‡ƒ‚„…ƒƒ„…„€‚„…„„ƒ‚ƒ„„€„…ƒ‚‚‚ƒƒƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚‚‚ƒ„‚‚€€‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚~ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz{}€}||z|~}|}}~~€€€€~~€€€€~|}}~~}|{xvvwƒ‡ƒ‚ƒ…ƒƒ„†„‚…†…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„‚‚‚ƒƒ‚ƒƒ‚‚„„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒ„„„„„„…„ƒƒ„…„…„ƒ‚€}‚€}||{||€}}~€~~}~|||}}~~~€}}~€~~}}}~}}~~€|}€‚‚ƒƒ†ƒ„ƒ†„‚ˆ‡…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒƒ‚‚„ƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒ‚‚ƒƒƒ„ƒƒƒ„ƒ„„„…„„„…………„ƒƒƒ}„€}}||||~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒ„…ƒ„ƒ…~‚Š‹…„„ƒ‚ƒ…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ…ƒƒ……„……‡‡†‡…„„…„€ƒ~~|~}}€~||~~|z|}}}}}~~~€}}|€€~~~~~€‚€……„ƒ…„‚„ƒ†€‚……‹‰„„ƒ„……ƒ‡††„„„„…„„„„ƒ„ƒ‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ„}uyƒ€~„„‚ƒƒ‚ƒ„ƒƒ„…ƒ„…†„…†}„y|~ƒ{…‚„ƒ€~~~}}ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚‚ƒƒ‚‚†„„„†„ƒ„…ƒ„…ƒŠˆ………ƒ……„†††ƒ„„………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚„usqƒ†tpurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚……‚hzrss|s‚ƒƒƒ}}~~}~‚ƒ|€}€}}||||}|||~}~€}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ†ƒ†ˆ††…ƒ††‡‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vzy…r„ƒpvxqvtturstvi€nrotvnulwm{sn€ˆym}rsvsvmmxlpylu}}~€}~}€€}}|||}|}~}€€€~|~€‚€€€€€€€‚ƒ‚ƒ„…ˆ††€‚…ƒƒ„‡†ƒ†……†‡‡„ƒ†‡ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoomw}x†pqzprtfu~n{ysoy€}}|}|~€€~~€€€~~~€~}€}€€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„†……††ˆ„„†‡ˆˆ†‡„††‹Š…„†‡‡…ƒ………„‚……„…††…†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„qjoyxpkyszozwvvp€~~~z~}}}~}€ƒƒ€‚ƒ„‚€€}~~~€~~‚€€„‡†ƒƒ†„„…†‡†…………††ˆ……†…‡‡…†„††‰ˆ…„‰Šˆ…„††……ƒ……„…††††…ƒx‹yrˆz{pp…„x…xyks~y{krƒ‡ƒz|m{yyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozls|nw‚€~~}}{}{|}}~}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡……………‡‡ˆ†„†…‡††…„……„……†‰‰‡†„†…††…††„††‡††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„…†…†„†„ƒ„„†„„ƒƒ„„…„…„…„†ƒ†‡…†„„…‡†„„…†„…}w…ƒ„„‚}~{|{~{||}~}|~}€€}€~~~€~~~~}}}~|{|~||‰†…„†††…‡†…………††‡ˆ†„†…††……ƒ„…†…„††††……†„…††††…††‡‡†…‡ˆˆˆˆ†„‡…††ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…ƒ‚……†……ƒ…„„„…„……„……ƒ†‡††…„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ‚}€{{|}{||}~||~}€}~€~~€}}|€}~~~~~||}~{|||{{~ˆ‡„„ˆ†††‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡……†…„†„…††‡‡…‡†‰ˆ††‡‡ˆ‰ˆ……ˆ…†‡†‡†‡†‡…‡‡†‡……†‡…‡†…‚ƒ…††„„ƒ„„ƒ„†„………††ƒ††…†……††…„ƒ……‚…‡…ƒ‚‚…ƒ„~€€|{}~{|{}~}||~}~~|~}}~}|}||~~|}€}||}|||~z{{}~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†„…„††„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…‡‡…‡†‡†‡…ˆˆ‡‡…††‡…††…„„…†……„„„ƒ„……†††…†…†…†‡……††…„ƒ„ƒ‚„‡ƒ„‚„„ƒ€€€{{~}|||}}|||}}|}|~}|}}|||}}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††ƒ…†…†††…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡…‡††‡‡‡…‡†ˆˆ‡‡…‡‡‡…†‡„‚„ƒ„†…‡…„„„„„…†††††…‡……‡…†…‡…„ƒ„ƒƒƒ‡ƒ€‚ƒƒ‚‚‚€{}~}{||~}|}}|}{||||||}{{{}|{~|{|}}|}}}|zz{{||ˆ‡‚††††‡††…ƒ…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡‰ˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡†ˆ‡††‡‡…‡†ˆˆ‡†…‡†ˆ††‡ƒƒ„„ƒ††‡……„„„…†††††…†‡††‡††„†…ƒƒƒ‚‚ƒ†ƒ~‚‚ƒ€ƒ‚|~~||}}|}}|}z{{z{|||{{{~{{}{{{~||||}~}{z|z|}‰‡ƒ†…†…††…„„……………„ƒ…†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…‰Š‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……‡ƒ„†…„††‡†……ƒ……†††††…††‡†‡‡…ƒ†…ƒƒ‚€ƒ…‚ƒ~ƒ~~}||}}{}}|~zyzy{|}{{{{~||||z{}||||~}|{{{{|{‰‡„†„†„††…„…†…„„ƒ„‚€ƒ…ƒ‚z„Œ{€„…‡†††…„‡ˆ‡†‡……‡‰‡„‡…††ˆ†…‡„†‡‰††ˆ‡‡‡†‡ˆ†„†††‡……‡ƒ„…„†††‡……„ƒ……‡…‡††…†††…††„ƒ……‚‚€ƒƒƒ‚}€~ƒ~€||}}~}{~}|}yyzy{}}zz{{}|}||z{}||}|~~€|{{|~}|ˆ‡…†…†„†„……………ƒƒƒ€‚…‚€}|{„…††„…„ƒ‡‡†††…„†‰†‚†„†††……‡…‡ˆ‰†…ˆ‡‰‡††‡…„†……‡…„‡ƒ„…„ˆ††‡……„‚†…†…‡†‡„††††…†ƒƒƒ…€€€€ƒƒ€|€~~‚€}€||}~}~{~}||yzzyz}}yzz{|{|{{z{}}|}|~~~|{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€€ƒ~~~€yz}€ƒƒ„‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ†…ˆ‡‰‡†…†…ƒ†„…‡ƒ„†„„…„‡†…†…†„ƒ†…††…††„…††……†‚‚ƒ„~€€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|z{{{|}}}|~}||}~|{‡……††††„…„…ƒ…‚€€€€~‚‚}}{‚ƒƒ…†…„ƒ‚†ƒƒ„‚€…‡…‚ƒƒ„„„††‡ˆ‡……ˆ†‰‡…ƒ„„‚…ƒ„†‚ƒ…„„†„‡†………†ƒ„…„…†…†„ƒ…„…ƒ……ƒƒ~~€€ƒ|€}}‚}€~~~}}}}{|{zyzzyzz|yzz{{{|z{{{{}~}}€}}||}€}|†ƒ††††…ƒ„‚…‚…€€€~€‚|~~€€‚‚„…ƒ‚‚„€ƒ‚€„……‚€‚ƒƒ„…†ˆ†…„†‡…‡……‚ƒ‚‚ƒ‚‚…ƒ…„…†„††‡††…‚„„ƒ„†……ƒ„„ƒ„ƒ…„€€‚‚~}}~~„~{||€}€}}ƒ}~~}}~{~{{zy{zyzz{yzzz{{|z{|{{~~}|}||}€~€†„……„‡„ƒƒ‚†‚ƒ€€~~€}‚|}~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡…„„††„…ƒ…‚‚‚ƒ‚„„„……†‡‡†…„ƒƒƒƒ„†…„ƒ‚ƒ‚„ƒƒ€€~}|~~|~ƒ~|~||€~‚}‚|~}}|||{{zzzzy{zzzyyzz{|y{}{|~€}~}}}€€€†„„…„…‚ƒ‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„…„‚ƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚‚€…ƒ~€~||~}|~ƒ}{~|}€ƒ}}€~}|||}{{zzzyy{yzzyzz{{{z{}||‚€~€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌËËËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFL=8765999<>9?<D:;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937677=;>9=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<9<<98:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA><A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËÊÊÊËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÒÓÔÔÔÔÔÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9?CE@<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÐÑÐÐÐÐÐÑÑÑÑÑÑÑÍÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø××××ØÜÝÝÝÝÝÝÝÝÝÝÝÝÝÚÖ×××××××ÖÖÖÖÖÖÓÒÓÓÓÓÓÔÔÔÔÔÔÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILO@99:4;A<7=9AC>@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌ͖„†††††‡‡‡‡‡‡‚²âÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¹³xssssssssssssp”À¼½½½½½½½½½½¼¿ÒÒÒÒÒÒÒÓÓÓÒÓÓÓÜãâââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVN<::77>C>8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÎnPSSSSSTTTTTSL óëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§£££££££££££¥™2)+++++++++++$d°©ªªªªªªªªªª¨°ÒÒÒÒÒÒÒÒÒÒÒÒÒÑàìëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;@C>6:7>>;=B?9<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÌÎqTXWWWXXXXXXWP¡ñééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤¦›8/00000000000*h²«««««««««««ª±ÑÒÒÒÒÒÒÒÒÒÒÒÒÑßëêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;>@@8:;8<;;<?:;;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÎx^a````aaaa``Z¤îççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©« E=>>>>>>>>>>>9q´¯¯¯¯¯¯¯¯¯¯¯®¶ÒÒÒÓÒÒÒÒÒÒÒÒÒÒßéééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB?;=:9;:==;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÇÅÅÅÅÅÅÅÅÅÅÅÅÄËÐÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÎÎÎÏÎÏÏÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÑÊÊÊÊÊÊÊÊÉÉÉÉÉÉÍÓÓÒÒÒÒÒÒÒÒÒÓÒÒÕÔÔÕÕÕÕÕÕÖÕÖÖÖØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<8@B<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÏÏÏÏÏÏÏÏÏÏÏÓÏÏÎÌÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÎÎÏÑÎÑÔÔÓÎÎÓÓÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖØ××××××Ø×Ö××××ÖÕÖÕÖÖÖÖÖÖÕÖÖÖÖÕÕÖÖÖ×××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?79:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÎÎÑÁ§Ô­ƒƒ•ÏÒ¤¡ÐÎÎÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<>B>BC@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÎÏÏѝ¹œ¼¸™µ³Ÿ¡©ÒÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?>;7:>9?D>A98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÏÏÓº¯¬¬¦Ž€ÆŸ˜•œÈÐÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<=:6?B@C:647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÏÏӟ±ž¨¡‰¬Öº˜¡°²ÓÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8FA?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÏÑÀœ‰¤ª¬›¥²™–¯³ªÕÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<>=964:99::97;?@;<=@<<A><=;=<?<:<B@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÏÔ£¢ž­¤œ•¨š…“¤ÕÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:=?>=<9@<<;:9?@>=<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÑğ{–­§³«ŸŸ©…™¤ÕÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CFCAB8;?<=;<<8558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÕ«¯¼ÀϔÈÙÁœ€¼­¦˜¯ÖÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF@HIGE@<<>><=><756:969;::;8@?:<<9<>=;;:?9?;;9=>==;;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦Õɇ… — ŸŸ˜¨–˜›»ÕÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;547<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡ÆÓÓ՜›¬¥«¢ŸÃ «¤œÑÓÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKL@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÒÑÒר‡Ï©ŽŽ­Ø»ÕÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<=?GFHKH=657:979:;:<=9>99:8;=>>A>=9<<:=>>:=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÑÒÏÅÔÔ¿¿ÕÒÕÅÄÕÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?AELLA>775;8899:;<><>8::9;>?@=>>:5::<=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÒÒÓÔÒÒÔÕÓÓÓÔÔÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEJ>>786977899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9699:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9848<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EILAALD??;:889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEGIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDJ;AA;<886486987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGIB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<BA<;876797799=?A?<:9@?<>B?;8776=??@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE>;HF89757875898;>>=;89A>=@?A>7596;>AB??@@BB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCEFC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELCA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>;<9;;:==<<8;<;DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGGNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAC?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668784;?<?=9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778777646748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€ihxsg~‰‰xp‚†{w}~…Š½ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€ƒvt|„‚}sp€Šx‚yƒÈÞÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868556747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsoupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿¼½¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»ºº¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjdmgb\XQPQKTJB:IQ?A7<94:565455688686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸········¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®xpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µµ¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸¸·¸¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶·····¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨¨¨¨§¨©©©§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸········¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥£¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§§¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©ª««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤££¢¢¢¢  ŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž£¤¡žžŸ  žœœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=7789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥¤£¢¡¡¡¢£¥§¦¦§¬¬§¦ œ›¡¡ž›ššœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¥¦¦§§¦Ÿ›š›¢ ™––•š›™——˜˜šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜—™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥¢¢¥¦¦¥¦§¦¦ ›™›¡ —““’—šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB@DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥¦§¦¦¢œž¡Ÿ—‘‘”—›˜–––˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;;;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¥¦¥¥¦§¦¤¥¦¦¥¥£  ¡¡Ÿ™’–š™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šžŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡ ¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢¢¢£¤¤¥¦¥¤££¡¡¡žœš•“”˜›š›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œ ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸŸŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::88:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸ   ¡¢££££££¢¡ ž›™™˜™™™š™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢ ›ž ¡£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œž››œŸžœœœœŸ   ¡¡¡  ¡  ¡¢¡¡¢¡Ÿžœšššš›œš™š›™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥£¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¡¢¢¡   ¡¡ ŸŸžœš™š›››œ›š›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›šœšš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>98;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤£¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ žžŸ     Ÿ ¡  Ÿž›š™šš›››››Ÿžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›ššš›™˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9;;>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœ›œžžŸžœšš›œœœ›œœžžœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:=>:?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››š›œššš›œœ›™™œœœžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™˜˜ššš™™™˜š›œœœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›š™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š››››œ›˜˜˜™™˜˜™™™›œœžžžžžžžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ›››››››™˜˜˜˜˜˜˜™™œœœžžžžžŸŸžžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ››››››š˜˜˜˜™™˜š›œœžžž  Ÿžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_]]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜™——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœšš›››››˜˜˜——˜™››œœœžžžžœ››œœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±³­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=9F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œšœ›œ›˜™š˜˜™ššš–‹“–™˜•˜˜–›œ—•’‘’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨©¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‹‘‹ŒŽŽ‹……‡‹ŒŒ‡ˆ‹Ž‹‡Œ…†‹†ŠŠ‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VPQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹‹†Š‹‹‰†„†‚€‚‰‘ƒ€ƒŒ†‹‰…€‡}€’†„„†ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹‹‰‰…‚}s}ˆ€~œ„……‰‹Šz}}†ŽŠ†”‘‹—”—’˜¡–ž—•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¥›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ†‹†ˆ…„ˆˆ‰„‚z||}~’ˆx…‹Šƒ„…ŠŒ‘™””” ššŸ¢­±­©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPFMHSWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‹‡Œ‹Š‡’Š‡†‘“‘‘„‡}}ƒˆŒŽ‹ŽŠ‰Ž””˜‘•›š¨®²¯¯µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWLO_^\NUTbQDTM;?9<895775795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš˜ “—š ™›£ •› ¤£š“ˆˆ‹‰‘‘Ž‘Ž‹˜šŒ”š—œœ›Ÿœ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUKTOOJCPK_bXZQ\S_MHRIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ª©¨§¡¥¨¨«©©¯¡›Ÿ¡££ šŸ œ”˜”˜  ¡¤ž›š¤§¤©«®¬¥£¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdVOXKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®ªª«¤¡¢¥©§§©¨£¢œ››¤ ¥¨£ ˜™Ÿ¡¢©§ ¢¢®¬«ª§­®¨¥¤©©©©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_UZNRNPORd\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢šœ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨¦¥§¨¦©¨£§¦™œ¤¥¢¡ ¡¡ œ˜™Ÿ ¡¤¤¢žž– ›š¢¢ ¡Ÿ ¢¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOWO^ddlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤Ÿ¢ ¢¦¡¦­¦¦ŸŸŸŸŸ™šœœ¡ ¡¤Ÿ¡›šœ ž¡Ÿžž £™–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvwa_\UYQUV[c^r_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?C?:8:>?C@DA:;><@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯«ª¬¨¨«°©¨©¨¡Ÿ §©­°²¯¬£¢¦¡©¥ž¤£¢¦ ¥¤¢¥£ž žŸ¥¢¢žŸ¢˜•žšžŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸ ¡¦¢›—’šš •|wo}yf[[`_Z\V\hdocnihb^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¢ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£Ÿ¢ª©§®·¶´´¶³¯¬«®«¶°©²±­®§¦ž¢££›œ—¢¨¥¡Ÿž£›ž¡š–¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¢™˜¥ ¤§ª©¨ª­¬¥©¤¥©§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxib[_^\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>AE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢œŸª²¸¼¼½»º¿´¯±³µ´··¯µ´µ²°¨¤¢Ÿ —•š—¤ª¦¦¡¤£¤«¥¥˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨©«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥ ¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxyxc[RYT__alhukpgiibYSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶³º±ª®´±°±´´¶¼¼¾¼¼½Æº¸·º½´¯µ±±º¸·²³²ª¦¦Ÿ˜¤¤§¨¤®¤««µµ®³ §ª¬§ª©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš“–””˜“š˜Š‹‡€€|‚xa^YSah`fsositdidb[LK>:8898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÃÆÃù½¿ÀÀ½¿Ä½¼º½¾´§ª˜±À½¸µ¹À³¯¯ªª¨­§§¤¯§ª´¼±´µ¨¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`a^^jbbnwuvnl[bQU\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAB;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–•–‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±±§¼¼¾ÅÄÆÉÇÅÆ»ÄÀÅÆÀ¹¯½¼À¾¾³«ªŒ³»¾´µ·Âº­¯°µª«¦ª£­¤§±¶«µ²­³­¨®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|ƒjfhaklfnuqruqf^_\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎÌËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÅ¿ÃÂÆÅÀ±“¾º¿Ã¶¶º©´³´©«³»»±Ÿ›±¯¬¤¬®´§ª©¨ª­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|tkkndolhqxoyiia\gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÄÄø´À·´¼Á¹··¿À»®¥®·¼·­œ£·°¦­´µ¬®¥¥£¨¤  ¥™ª³²¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyz{vnkhguZfrwsxfg]d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÉÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÉÆÃÃÄÂľ¸¾ÁÃÀľÁÏÏÎÆ«¯¶´µ« §´³®«¸µ³«©£¢­©¬¦­Ÿ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuueeijh]jomxwcb``^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÏÏÌÃÇÆÈÈÈÇÉÇÅÉÇÈÇ¿ÅÇÄÄÇÈÊÒÏÒ̼¸¶´¸¸Á¾¾º½º¼º¼¬­¦©»º¹·À²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqobagugiitmxl]d[U`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÍÐÎÇÌÉÂÁÆÁËËÇÆÌÉÍÅÆÆÃÆÅÉÍÐÍÏÌÇÄÀÃÂÉÍÇÅÁÄÇÁ»¾´±°°Á¾¿ÁÆ¿¾¸·Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`jjvlietnsb\bTWTSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<:>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÅÇÈÆÒÉÁÃÄ¿¿¾ÄËÈÊËȼ»ÈÇÉÍÈÃÈÉÉÆÅÃÂÁÂÇÇÉÊÇÌÈÇÈÍÆËÏÅ·ÀÀÀÀ»»½µ³³¿¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrofegcjdajmnn^X\VUNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÂƾÆÁ¹»Ãº¸¹¼¾ÁÆÁƺ¹ÉÉÃÅÄÀÄÁÂÁÄÁþ½ÂÀÀÁÂËÃÆÌËÅÈÑ°¾½¸º»¼¾·´°¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfadbabccjbfcZYY\YQNE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶·´´µ¿»½¿¹½ºº´¿¸µ·³¯»¼·À·½Â¿Á»¿Á¼»Å¾»ÁÄÀ¾¾¸¼ÁÁ˾½ÉÄÀÀÊÀ±Á¿»¸»¾¹µ·´¸¼´½¸µ´°³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|y‡}qc`bbgjffiei]VUSYOSKE8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“’’˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´´±°µ·µºÁ¸¾¸¿¼½·µ·°®¸¶¹¿»À¿·Á¼»Ã¶ºÈ¸¶¹»½¹º¶»ÅÅʽ¹ÅÀ¿¼Á¾¸Æ½ÁÀ¼Å¸¶·´¸¶¶»»¸¶´·ºµ´¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒ€xpmeefoiekgXXNKKKRILHC9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’š”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿½¼²­¯¬±°·¼¶»¼ÀĹ···µº¹º»À½ÃÀºÄ¾Ǹ¹¸­·µ¸º´·³»ÅÆËÁ»ÆÀÀ¿½¼¿ÉÃÄžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~†|knpgpksebm_\THKJDJBCG?9;8=<7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘ŽŽ˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼¼À·ª­¤®°·»³½¿»Ä·¶¸¶·¿¿Ä¼ÂÅÅÇÇÊÉÆÏÂÁ¸®µµ¼¾¸»²¾ÄÄÊÅÁÉÿ¿¾½ÇÌÇÇÄǽµµ¶Á½º»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†qelintnwcgb\cQKTHEECGC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?=??FD@A?>:7?@CC?A=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼«ª£°¹½¾³¼¾¼Å¸²¸¹½ÇÉÊÃÇÈÆÆÉÈÌÎÑÌÊŵºÀÃÈ¿¿µ¿À¿ÆÆ¿ËÆÿÁ¼ÀÃÌÊÇÅÆÁ¹½¼Ä¿À¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtolltkln_b^aaNHM?E@?DC;;::;:8;<:9<>9:>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´¼Ã¼ºº¾¼Ä¿·½¿½ÇÌÆÇÉÆÆ¿ÄÄÊÈÌÌÍËÆÂÃËμ¹½º¹ÀÿÈÆÄÁÁ¿ÅÀÊÉÃÃÃùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{z‡zmmw{_pc[]_^SI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA>>ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸´¼¶º½Á¼»¿¶¿Á¿¼¿ºÀËÂÇÈÀ¿¼¼¿ÅÂÇËÈÁÃÀÀÉÊÂÀ»»°´»½ÀÅÆÅÅ¿À¿ËÇÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}‚zmsxsgp][^]YQEDCMIAE=G::59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘–žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯·¶²µ³·¹¼»¶»»½ºÃ»·½·¹À»º¸¸µÅÁÃû¹³´ºÁ½¿ÇÀ¹À¼¾ÅĽ¾¹²°®¸·¿ÃÇÃĽ½¿¿Ãþ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸¸¸½¹»±¶²ÈÀ»¶´±°·¬³©°­­³·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|vluzpni\__YSPAEIGK@DCH<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿš›œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹ÁÀ·½¹¸¹¶µ¿³´²¸±»ÁÀ÷·­°µ¸¸¸Âº´»·»¾À»»¼®¯®³²¹ÁÂÄþ¼¿»º¸¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ¯µ´´½º¾¹º»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰|‚zsvvwnq`_e\ZUJ<??FF=FCC9:5;99><<::<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Ã¿·º·¶¶²´À¶²´¸³ºÀÁù·²²²´²·¾º³µ²¼º¼¶º¾²´´´°¸¾ÃÆÄÀ½¿¹³¯²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtvrl^b`[]OHA?=HCFMD@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·À½»¼¸¶º¶±Àº·¹¸¹»ÁÁÄû»¶´´°¶º¶´²¬¼¹¸µ¸Áº¸³±¬·¼ÁÇÿ¹ºµ®¥¬³°¦°­¨ž Ÿ¥­¶µÂ·¶´¥¨«¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´·¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wo{ournc\fX\]RNMA?JB@JI@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³±­¶º®¬¼²¸¹·»¿½¹¾À´¿»¼º¸¾Â¼ÂÊǾÀ¸¹¶²´¶³´¯¬»º¸¶¹Àö®®ª²¶¼½¹¶²±­­Ÿ¤§§£¦–™™šŸ©®¹¬««Ÿ¥¨¤«®®§¯¬¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmuik][jT]\OMHDFLBFMF8665:6:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹½µ²¸´¹ºµ¹»µµ³µ»¼À»¾À´¿¹¹º±ºÃ¼ÂÊÅ¿»¿¿¹´´³±±®°¹¹¶¼¸»¿²²²®±®¹¯ª«­¬£¨¡ž—˜¡•’•—˜Ÿ¨®¤£¤ ¢§¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬«¯£££¡© ›“Ž“’’™–š¤¥ Ÿž§˜•’”˜ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­«©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wrxhtsndT`cW\QNLH@HQDMC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼·ÀÁ¾¼¼¼¹®­¯²²ºº··µµ¼´¯´«¶º¸ÀÄÁ»¶¼½¸²­³°¯¬®·¶³´µ¯ª¤ž›œœž¨¨Ÿ ¨©Ÿ¡§–›——“–Ž—›¤¨  ¢¢¢¥¥££ ž¥ ¤¬¤¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›©¨ª«ž¥¢›£œ•Œ“–•–˜Ÿžžš™¦—“’–¢ ¥£¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦ ˆxƒ|vybwln\QhTPNGOLLBOQ@>;>39:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¥¬ª¨µ²±°®¯²§¦°¤¯®µÁºµ·²·¶²´«²´®ª«¯°²³®¥ž’˜”™ Ÿ¢ œ¤¥Ÿž¨”›–—Œ—‘—“˜¢ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£ž™—š«¦ª±£¥§ž œ•“‘˜–•˜—Ÿ˜›™›£™—”–š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’}|€uu}mk{dhUQcMIHGNRNJNG;D@=2?859;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜˜—–¡¨¬®¶·º¹º··»®¨ ¡©¡ ­«ª¦©¤©£¤®¥¬¬´¼·¬²±¯±­µ¯¯³µª§­¬£œ™”Ž’–—™™œ £¢›¥žš¤———–’‘‘“š—› ¤ªž¡¡ž¦§ª¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¡¤¡›˜ž¯©®²«¥ªª š˜˜˜•“–š“••™–š——˜ žœœ—›¡šžš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}vx|dxy`bRU_HIIKSTIRPL8>B67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—““œž£¨®­¬««¯ª¯©Ÿ—ž¥žž¥¦¤ ¢Ÿ¦ ¢®«¬­µ²¶¦¯´«©ª´±°°¸­§¡œš”˜šš‘Ž‘•‘ŒŽ”™¢œ—£™š—˜™”™˜–›Ÿ¥¦© ¦£ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§  £±®²±´©±¯¢™œž¡™››š˜™›”•›–™œ¥¡ š£¡š™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ Ÿž ¥¡žž¥ ¦™{|uvsh‚le[SZYMQJNNULRLA7>B78=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=?758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’’œ˜¡ª¢§ ž§¡¥Ÿœ’œ¢›Ÿ¡£ž Ÿ£ ¢¯¯¬¯±¬¶§­±­¦¦°®­¬°¨ Ÿ¢ —‘”œ¡œ™˜’“Ÿ¢¤›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬¨¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½·¾°¬±®­©ª´±°¨«¨²µ·³¸¬±´£ ¥ ¬¡¡¢  š˜–•Ÿ››˜¤¡ ž¤¡ žšœ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚|xuiwu]lZR`HQUHFUVJBMG=JH8E<67;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›Ž“ž™¨®ž§žœ¡žšš’™žœ¢¢  ¢ŸŸžŸ©¬§¬©ª´««­«¥¥«¨ª¬ª¥ ž™’’”˜™—––Œˆ‹Ž•ž–žš¦  ¨¥±ª§®£«­¶°´²±®¶¸½Àº­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«¯±¹·¼¯³°µÁ¼·½³³µ¡«¢©¨²©ª¨§¨š™šª§Ÿ™§ ŸŸ§¨¥¤žª¢¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰…„~vqmivmhm\X[BVMJGMGBFM<>L=4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜šª ±¢·£°¦ ž—˜–™ž›œ¤ŸŸ¤šœ¥¢¤£¢ª¯¬§©£ ¡¬®®ª«§ žž¢£žŸžšœœ”“•”žž˜”†žš¡›«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶ººÀĹ½»¬¯§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¹Â¾¸´»Æļ»·³©²­ª³´¯³®ª®£«§¶±¬¢¯¥ £¯±­°¤¤¯£¡ š¡§¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¥ž¦™›¢¤žŸ›››œ‡†{trkkurphW[QETHDIOH>EA3EH95;=6;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž ¡œ˜›Ÿ › ŸŸ—¥•››Ÿšžœž¥¦§  «±®§¤¤£ ž¥«¥ž—œ”‘™˜”ŒŠ†ˆ†ymˆ ¤¢«¬´¼¶Ã¾¾³»ÁÃÂÅÀ¿ÂÆÆÅÃÈÂÀÅÈÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌÌÌÒǾ¿À½ÇÆ·ÃÉÈÂÀž¹´¹ºµ»·°µ²ªº±®»·¾ººª·­«ª¸º´¼®®¹£¦£ž§¥¢£©¦š›Ÿ˜š§ª§ ¡¡¤˜”£–”š‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ„}zrkdhoxjeZ[FJLDDSLDBD7:?;549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”••š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ³²¸§¡¡«ª¢ž¡¢žœ› ’ŸŸ–Ÿ™’š–›™£¡¯³©¡šŸŸš—˜—’Œ–—“Ž‹‚ƒ‚wsqnp¦­®´¹Å»ÍÇË¿ÂÌÎÍÌÈÉÑÌÍÌÇÉÅÆÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÒÓÌÓÐÓÓÌÊÂÅÆÆÊÇοÉÐËÆÄÆÄÁ»ÃÁ¾¾¾µ½³­¿¿ÂÃÆÄÇÄ®¿¸²¸¼ÄÁÁº¼¼µ®§§®¨ ¢©¥š– š™¨«©£¤¤ž—›‹™‰•˜› Ÿ£—žš““‹•…€ytsebgrof^ZYCNLCEPIDB@55589B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>8;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›£¬žŸ®¦¥±ªÅÆÌÎÍ¿°Â©¥¨­­ª¡£Ÿœš©“™¡Ž “”’—™¤±±«¤  ›™—”“”–‘Œ‡„ƒˆ‡ƒ€€yrroly¤¶º¹¾ËÁÓÒÓÈÍÎÑÓÑÒÑÐÑÑÍÎÎÐÅÎÔÕ×Ò×ÍÆÇÉÌÃÅÊÏÊÓ×Ñ×ÒÔÕÓÓÈÌÇÍÍÉÒÌÎÓÍÄÇÉÊÁÅËÆÈÈž³³ÈÄËÊÊÎÅÊ¿¾¿¼ÁÇÄÌÌÈÉÀÿ­°³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›•Œ†‘‹zruugcgvidVWQDMF@IQB=B<:23@<D<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<@?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­´¸¬®£ž¤£Ÿ ¤¬›–©–Œ–Œ—¦°®¥ž¡¥¡ž›•”–”Š}wpkebhqoq{…Š€vpnqtp…³Â¾ÅÑÐ×ÖÖÒÖÍÔÖ×ÔÓÑÓÔÔÓÏÒÃÐÓÖ×ÕÖÒËÉÎÑËÆÍÒÊÒÕÖÙÕ×ÓÖØÎÒÉÎÑÌÎÐÌÒÏ¿ÇÆÊÃÌÌËÎÏÅÆǶÀÊ¿ÒÍËÏÅÉÈ¿ÃÃÈÎÌÏÐÏÌÊÈθ·»¨Ÿ¥«§Ÿ˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„|wsvoc`erb]R\IJFAEHI>;@8=4585:76:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢›©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´¶ÂŲ¶©¢¥¦¡¢«µ§š± ˜Œ¦­«œ•˜¡›¡¢Ÿœ›•Šwic`____^_`^blusqpolrqu’ÄÇÆÔÕÖ××ÓÖÏÕÔÚÔÔÏÏÕÔÔÑÒÌÑÎÓ×ÖÓÕÐÏÒÓÑÉÓÑÈÐØ×ØÑ×Ò×ÙÕÖÌÎÏÉÍÑËÎÏ¿ÅÂÇÅÎÍÑÐÑÈËÌÀÊËÅÔÎËÎÈÄÉÆÆÈÌÊÓÓÑÕÏÒÌÒÁ¹Å²¥¨µ®§š¨¬¥²¨°³¬¬““Žˆ‹Žƒ‹„Ž™“™‚…Œ{zqstmacim_VP_JJBFCQM?<>44:=52755<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><??=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡© ¯®ªª¬ž¦®¸¨«·ØÔÕÙÙÑÎÐÀ¼ÌÉ·À¯§«©£¤±¶³£¶ª¬Ã§©©¡˜–˜š›¡žšž”~recb__a`_a`_``_`fmppnkorww›ÌÀÒÕÓØØÖÙÑÒÒ×ÏÓÎËÓÍÕÔÒÊÏÌÓÖÒÑÖÍÏÕÕÑÆÑÔÊÑÔÕÖÎÒÐØØØ×ËÈÍÃÉÎÌÉË¿È¿ÈÉÍÎÏËÐÍÎËÎÏÇËÏÐÊÎÊÂÉÆÉÌÊËÑÒÌÓÒÑÏÐʽȹ°­»¸µª¶°­¨¸­³¿»±šŸ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…ˆyvopnkadnpaW\ZIFFDLWE;@<33<=86855;>@=9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6==?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ£§ž¸¶µµ­¥­®¾´±ÀÙÒ×ÚÜ×ÏÍËÄÓв«­®¬¦³²¹«²¼Æ¢¡œ–”—›žŸŸ”–—•‰l^^^adb``aa``a^__^]bmroostvvy¤¾ËÕÑÖÔÓØÖÎÎÔËÍÎÅÎÊÒÒÏÆÎÍÍÔÌÎÓÍÊ×ÕÐÌÑÔËÌÐÑÓÊÎÑÕÒÕÕÊÀÊÁÅÌÂÈÉÂÌÃÅÈÊÊÎÊÍÌÐÍÓËÅÈÏÌÈÇÊÄÇÀÅÉËÍÐÑÆÐÎÍÍÌÏÅÇÀ·¹½Ãýù²³¾±¼Äĵª˜¥¢™–‘•–’‹”š‘”””‚‰…xpqknh``qhYXhVMGLIPPB;D>;67:89:57==A;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;776?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÅÃÁ¿»µ²±ÇùËÕÖÙÚÛØÍÍÐÉÖÖÅĸ²¶ª¤®¬¹¹±²Ä¬–˜–“’‘–––Œ|ebbb`]^acb`_``aa`_][]grqqrsqmry¤ÆÓÏËÐÏÔÕÉÅÉÉÆÆ¿ÃÆÏÎÇÅÇÍÊÑÈËÎÍÆÑÒÏÎÌÔÊÇËÎÏÇÇÏÒËÐÏƺľÆɽÂÇÉÎÄÂÇÀÇÍÇÃËÊËÏÇÃÃÏÈÆÁÅÈþÀÇËËÌÎÂÊËÈÇËÐÄÅÇ»ÇÃÈÈÂÏÀ½¼¿±ÁÊǺ½ª±²§¥¢˜š¤™—™‘•˜‰‚wntdl`^fqa[W`GHHGIMTG?J=64355=<48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥³±¬ÉÍÊÈľ½ºÍÍÇÐÕÖÙÚÛØÐÊÐÐÒÔÊź¾¾°¨·«¾¹¸³¥‘ŽŽ–†ƒ„„‚~……t`[^^^`^`cdc_]]^_``_[Z\akrrookloo}¸ÑÈÉÊÏËÍĺÀû»ºº¾ÈÆÂÃÀÃÇÊÉÈÊÇÁÅÌÆÈËÍÉÄÂËÉÂÂËÐÄËÈ¿¹Á»Åǽ¿ÆÏËÿûÉÆÈ»ÈÆÄÊÀ½ÁËÆÅľż¼¿ÃÄËÅżÀÉÂÅÇÒÅÀÈ¿ÊÊÆÈÆÐÃÃÆïÄËÇÄÊ·¿¼º´©¬¥¥˜Ÿ˜¬£¡¥š£ ›”{vstfj[anmZ[XQDLFBGDLDFS@54334?<3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ËÏÑÌÇÂÃÇÍÏÏÍÖÐÖÙØÙÐÍÔÎÏÐËĸÆÁ¶µ¼±À¶º­‘Œ“—‡{€…†€vxurp_Z[]`abcdded`\\]]_^`[YZ\borokilposÆ¼ÉÅÌÀƱ¶º²²³²±Â¼¼»¹¸ÀÁÁž½¹½¿¹ÄÊÅƽÆÀ¸»ÄÉ¿ÂÉ»·»ºÅþ¼ÁÍÂƾ¾µÁ½Ãº¼Æ»Â¹³¼Åö¿µµ¾¿ºËüµºÈº¿½ËÄÁÅÂÆÈÆÈÆÐÆÂÌȲÇÊÃÎÍÁÅÃÀ½³·°³¨¨¨¹±¥­°«­¬”yvwjeh`hocV^YJEJFHKAFBEI@9:648853;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÆÂÄÈÎÒËÊÊÇÍÎÏÒÉÑÇÖÕÖØÎÌÐÈÍÈÊžÊÁ²µº·º¶¯‘Š‹…y€††€~„|tud\\]^``bcbbeeb]][\^\^]Z[]]hsqmggnpry½ÌÀúÁ¸®°°§ª­¬§¸´·´³²³ºµ½±·°µ¯²»Â¼Áļ¿»µ³»¾À¸Ç¹´»¶À¼¸½ÆÁüµ®²¶º¾´Å·»µ«¸¼½À½°º¶¯¶º²Å¼¶¯»¿´¶´Å½¾ÃÅÀÃÅÆÈËÆÀÆÆ»ÈË¿ÏÊÇÃÆÂ÷þ½¶¹¾Ç¿¬µºµ·¶Žxtxggebkn^V^`FKHHJFBCAEE?<:565633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÎÈÆÉÎÌÐÍÎÉËÉËÊËÆÑÏÓÑÏÈÊÆÊÆÄÀ½Ï½³¸½¹·¶›Ž‡‰‰{y~††wx‚}th^]]]_`_`da^cec__\[^\]^Z[[]_lpnhfjnnr|¤Ç¿¸¸µ°«¬§ž¢ª§ž«¬³­©«©³­¶°²©®¦¬²¼º¶Ã¹ºº±«µ¹»´Âº°¿±½½»¶¼È¹Ã·­ª¨°²À¶¸¼¯°§±³´»¼«­µ¦®¶®º±°ª¹¯­»®»¸»¿¿½¹Â¿ÇÃÅÁ¼ÆÁÈ˸ÅÇÅ¿ÇÄúÄÆ»ÆÉÌ˳¹Â¼º²ˆrvvkiablhYXW[ALKMIEAC?FA:9:995854::9;<=;:;>8;@<=9:79>9;<:8;;:>=9A=?@?<>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÆÎÒÌÄÆÁÅÐÈÏÃÄÇÁÆÆÅÅÌÃÊÌÂÄÁÇÀº¼»Ê·´»½µµ«‘‰|y~Š…z{„wn^]]]]_`__dbbccb`_^[[ZZ]ZZYZ]enohfgiknr­¹°µ®¦¥§§š ¤ šœ¥«®£§¢«ª¬ª°£¦Ÿª­µ¶±½¹¯·¯¨®¸´´¼¸³¼¯¸¹µ²¼Á²Á®¥©¢«±²³¨¼ª«¨«¬­´´¦¨®¡¤¯©²¥§¨®¥¨·¬°²·¹º»±¼½¾¾Ä¿µÁÁÇÈ·¿ÀÅ·Ä¿»¿ÄþÄÈÌÊ¿¾ÃÀÀ©†rtrji]aodWVXPHZRSKFFE>?@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·ºÄ°¶°›™•œ˜ª©°±³µ½¯ÆÑÐÍÄÈ»»ÌÃÌÀ½Ê¸¿ÅÀ¼ÌºÃÆź¼Ã½¹·½Å¸µ¸»®²•ƒ‰{~€~xt|swf_]\\^_`^_ccab``_^]\ZXY[[YXZ\_fkfegehkor…ª¥¬¦ œ¡¥”ž¤›—‘¡£ª£¢Ÿ¥¥§¥¬ ›¤¦¬²¯¶·§°¬§ª´«´¹°¶´­¶¹²°º¹±·¤Ÿ£Ÿ¦±§«¨¹ª¤§§¨§²­ §¦Ÿ›¤¦¬žŸ§¤Ÿ ±­­¬²´²´°µ¼¶»ÁÁ²º¾ÃÁ²¹ºÂ³À½¿µ¸»½¾¼ÂÇÄÂÿ¿Ä ƒwpkaf_ko`UY_HNhOTHEJF<=@=:;;825536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;=:7676778666;::;9:;<859<:>>@;Èµ¶½¸ºÁ»¾µ ž•ž¡¦º¶«³³»³ÅÐÉÌÃǹ¸ÉÂÎÁºË¹½È»·Ç»¶ÃƳ½Å»¶¯¸¿»°²¶°¢„‡‡‚}yvtomkjjqi_`]\\]_`_acb````]\[\\XYXXXVX[]^dcbegggjmoˆ© —•š¡–›¢˜•ž¡¢¦›ŸŸ£¥¡§ž›¢›Ÿª°­±µ¢©ª©«¬¤µ¸­·¯¬³µ®³µ®°ªŸž£¢²¤¦©¸­¢¦¦Ÿ¨¬«™Ÿ ž™Ÿ¥š™£œ›¯©«§ª«¬­°²¸¯¸¹»°¶»»º«²²¹²½´¶±±µ´¿µ½À½ÃÁº»½—ƒzrk_e^ddXTX^IW]KPGIJFA<??@;?<04535:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»·ÁÁÁ´¤¤™›¤¦À²¯¶¬´·ÆÐÉÉÁǼ¼ÅÅÐÀ¼ÊººÂ»µÅ¸µÀÁ³Áû¬©´¹·§°³©‹†ˆ€ysnpnkb^bff]]^]]]\]_`abccba_\[[Z[YXWWWWXXX[^bddeffhikr¨”””›˜›¡––œ¡¡¨›¥¦¡¥œ  š˜­®­®² ¥¢­«§¡µ°±±¬¨¯³§º³¦¶¡¢ž›£¡­£¡©µª¢£¦¥¦£–˜ž—™šŸ™—œœ›¬¡«¦£¤¦­«³³ª´°²ª²¹´¯©¯²²²·³®©¬®±·°º¶¹½¿·²±”…yue_e^[YVSZUK[QLIEHKIB=?AA@@:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½¸½¿¶¾½¿³¥£˜¥±Âµ¶½­´¸ÃÍÉÈÁƸÂÁÈйÃÇÀ¶¼½¶Ãº¶¿Àµº¾º©¦°º°§±¯›}……€ypqtqhfdiec\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXXVWadecdeddhjv¢œ”””–—Ÿ—™”˜Ÿž¡œ–¡¡¨£Ÿž©›šª¦¯°«›££·ª Ÿ®¨¶©¦§­°¤·°¤· ¢›˜˜ª¦¡š¬¸°¢¡¤œ¡Ÿ “•¡”––›˜—–—œ”Ÿ©©£¡£ªª°®¨´«ª¦­²°¥ª®²±¯°®¯¦§§²®±´¯¼´¹·®£”yud^aVYWSRTKM^LPKGGLKE<@><B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾¸¼®ž§§£ª»À½À¹®´¸ÂÍÈÇÄžǺÊ͵ÄÅű¿¿¹ÀÁ¹¿À¹¹¼·§¦°»¥¨ ¤‰~xrjlrtpihedgb\\ZYZ\\\]^]\[\^\[\Y[\ZXVWWVWXWWWU[ccbbcbcdfj–“•‹‘”“›™œ––› œŸ• Ÿ¦¥¤¦§ŸœŸ¤Ÿª¯¦Ÿ¢£¶¨ ¡¢¨³¡¥§¤¯¥±­¬µž •”©¡¢”¬±±ž¢¢ž˜›“‹¡”‘“—˜’——˜–¦›¦¡¢™£¥¥«¤¥°§¥£««­¥¨®¯®«¨ª©³¥¦«¯´±®¼µ±¯¯ ’zvrda\[]XNLQGRaMWPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8846863321./2556;:8;7876<;:;;A8x»»±µ½°»²·¬ž¤§­·»¼Áź±¹µÅÊËÁÄÇÇɸÈƵÅÂɯº¼Â»ÂÀÁ½»·¹µ¥¦±µ¡‰˜ˆ€wodbgihfhjgjm`]\[ZZYZ\]\[\^_\ZY[YYZ[WUXWTTWUSTRU``_`a_`acdi”“‰‘Ž”’“œ”•–£™ –œ ¥¡­¥¤¤¢£¡›ªª¥™ž¥±©  œ¤ª§¡ž¬­©¨®­¢¡¢”—£›œ«©°›Ÿ¢žž—˜“Šž’’“•˜˜’›¡¢œ¤ ¡• ¡¤¦›£«¥¢¤ª£«®¤®±©¦¥¦¦´¦©¨­³µ´¹º¯ª¬ž‹rpo`[WVUQFQOHZ\ORJTKSLEGIC8;;=<8667:9;:976977:;:=<<7;<8>598:88659:;<97?<9678452121..1426:86:8598989;9@9{µ´­´»²°¬²­§§¯¹¹³ÀȺµÀ¯ÆÉλÂËÍÉ·Ë¿´ÀÇÌ°¶½Ç»ÁÇý¾¶¹´¤ª¯®œ™‡Žƒ|uijjmhjlnkkme]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURSOQY]\]^^___bdmŽ„‘†‘™“”’œš¢œ› §¨ª¨ª¦¨¥£˜¤®¤”™¥¯©Ÿ›˜› ž®™›ª³Ÿ¥¦Ÿ££¡”“›––’¨ª­šœ ¡ š”Œ™Ž‹Œ’Œ–”ž¡ £œ›¢•› ¢ ˜¢¨£¢¨« «¯¤­·¥££¢¬­ª¨«¯³¸²½µ³«¯˜„ssh[YYRURFYLP\YMTNPLPRINIB<??A?<65799<<987:79:;<=>;7;;:=57:;8976989:6:=99577571141-+/434988::8::748=8?9~³®¨³¶®©¨¯­›©¨¬·¶¬¼Ê»¶¿¬ÌÇƹÂÏÐɵƾº¾Æ˵±½Ä¼ÂÄýÀ²¸®¥ª®ª—†wxoninnnqggigd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUTSNPQYZZZ]]\^_`d~‹‹Š’—‘—™¢ ›Ÿª©¦­ª§¯£§™Ÿ¬ •–¤¨§—šž®–—§ª™Ÿ”¥¡ž’’’“•§«¥š™š–ŒŒ”†ˆƒ‹’” ž £—•Ÿ•š ¢ž“›¥¥§¨¨ ±°¦°¼§ £¬´«®§°´°¹µÀ±­±«}qrbVTUNRIGVQSRLLXMJLNRGMKACFDC>@75889;9:7::7<=:;@>:9;9:?759:9876958779;85576661320-*.102877;99;8948;8@8³­¦±·ª¦¢°«ª§©²±¤¶Æ´¹º³Ëƺ¼ÃËÑ̳¹º¾ÀÄǶ´·½²º»Ã½Á°³­°­¯ª›¢ˆkhnoroqkpkdfge^ZYZYZZZ[ZZZ\\]\ZXXXYYWXWUUTRSUSVURNNNRWXYYYY\\]aj€zu‰Ž‡‰˜‰””—›™¨›Ÿª¥¤ª§˜ ¥›’ž¢š—–…„’š£“¢œ•–•‡¢šš“‹Ž‹™¤§œ••—›’‡”ŽŒ‹€Š’’‘¡šŸ¡•”˜˜•¢¥™Œ™¤¦¨¦¡ ´²§²·¡¢·¬ª­¤²²¦µ¼µ««±£ˆxrm]NPQLOCMNNPKFNNJJNMQIMJAGKHHC>858889:;69:68;99><8:>9;?8789:886857688974577820301+)-/12776:999984988A7w¶§¤¶°¤§¤©¥ ©¥¤³ª¢²Ãµµ²³ÇǸ»ÄÊÍǵ¯¼¿¸¼Ä³³®¶¢¬´Ã¹º­©«³®®ž–§}^`gsqvqjnifhhj_XYXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQNMKLSWWVXXYX[]aosvq…ˆ‚‡€‘ƒŽŠ”‘“ šœ¢¡£˜¤–¡›•‡˜šŒs‚}—–…™“ŽŽ{™ŽœŒ‚Š€Š˜Ÿ¢ž“˜–„Ž‚“~~t‰Žz†’š™š•Ž¢£Ž‰š ¡¤£›¢´¯¬¯¬Ÿ˜¥¹¦¥°¡°®œ°»ª©¯ª™vrcVMROPMCSNLQMCPPHINSMHJJDJLFKK=749888;;69;7:<9::;79?9>@79:<89764445874312485/0102)(,-12764789::65:87A7w·¢£´¨¥¥¨£¦¥¦¦¦³§¥´Á¸¯´°ÊƹºÂÏÇ¿µ¯½Ã¯±Ç²­§«•¤®¿·°¯Ÿ¦¬¬ª•”¢rWV_hgihincjhgb\XXXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTQMMJHNSSSTUUWY[]ilrm…|tNXr‚—†œ—‹“Ÿ—•”–”Ž–‰“‰_;Wo{‹”‰‹‘Œ…†sŠ„–y‚z…“”ƒ•Ž‘ƒ†}“xro…~‰€—™˜“Š‰œˆž—‡ˆ–žš¡ —§¯©­©¨Ÿ—­´¢¦­˜¬«˜§´¢©­£’}rm_[NSRVLDTJPMLFOOIELQMKPJIMPFIH=7599999:7:;:>>8:==6:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9x· £®¡¦¦ª §©§¢©°¨§´Áº±µ°Éù´¿ÏÀº±±¸Ä«®É®§£†š¢¹¬¦§•¥¤£ –Ž–iQMRVZZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MORMKHFHNQQMPRTVXZ`moi{‚tPB@•‘‘}‰”Œ„Š›–•Š’ˆ†•†xˆ`JQnxŠ’„|„Œ‰„n~”wuvx„™pQˆŠ‡|~x”vhw…ˆ~Šˆ•Š’–‹„Šˆ”„šŒ„’›–žœ”¤£¨©¥£ž›°«¡¤¤¦ª–¡ªœ¢¦¨ˆtle^[HQQRMIUMSILLPIHFKNLMTKQQOFIC<769:8:;;8:;8>?99>=7;<6;;478;6775344696/3/.115221/,')+*,4833979:99::::?9v¶œ£§Ÿ¡®¡§¨¥§¨¯­ª¶¼¶¸·³Â¼·¨ºÉ¹·©ª·¸­¶Àª¢›’ƒ™±Ÿ¡™ŒŸ–˜”‘ŠŒeMLNNOLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDDINOhYNQSTUZnƒtw~ji]U‰”‰t†{…Œ’’™‹{†€uxsnuptŽy}Šª…yzhv{ŽprmxŠŒ’xz€{€vsr’wgu„„„„z•‰ˆŠŒ‹€„‹Œ”ƒ{€˜•œ•‘Ÿ©žŸ ž ©¥Ÿ˜Œ§¤“  –ž¤qg`\\JVOQGKXROJMMRJJJMPHLQLRTMEHA<77;99>=:;<98@?::>=7==79937795675252572/2.,./200/-+(().1272198798775:<<7v®˜£¡˜œž³©¯©¥¬¬°±ª½´²¼¸¶ºµ² ·»³«Ÿ­«¬µ³¥–’˜†“£–œ‹‚—‰‰††ƒfJIJIGFHHPTTTWWSTUUUVWWWXXXXXYXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQRSV^uƒ}ygw—˜Ž}gyvx‰|„˜’r‡|v{ok~­|sŠ{†’}tfv|…lohs|‰Œ‡€lyq}pmuqhq€}ŽpCŠ„‚ƒ…~wwz‹…}‹zu~Ž’˜Š’š›£–™›ž¢–Š¤›—Ž–˜vmlebZXXTQJSUTOPNQVKNKNOJQOIOOKFD<;79;::?=9<:99??;8<=7<9999266856633621224.,,-..-0-+*''*.1362/876966527995y¦—Ÿž– ¦¯¬®«¨©±¯±¬¼¸¬»¾¹³­¨›±¨­œ—ž§¬§¤›“ˆ–~Ž•‘•€|Šz…€eJGHFB@CDILLMQRPQSUTTUVWWWXWYYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNPQTX^eprmˆ§ªÀ~uyb{xo|yˆy|‹…omŒ‘xsxjj‚r–‘‹}•€J’˜nhw~licly…’†ksl|nr{†hmp~sˆƒ…z}~{vott…‚ywp|ŽŒŠ“ƒ–—˜š“–—™—ž—Œƒ‰Ÿ‘Š’Œ†–~mhmnnWUWTQQZOSUUTXUMNHMJMNKCINGE@:89;99:><9<;::=>:8:;9?868727575541442/024*+**-.+-*(*(',-1250,5567485HA895w™‘›™šž¤­¯¢¬ª¨µ¯®¬´¿«¼Â¿¦£š•¥˜žŽ…Œ–¢¤›š“—v‘~…‹‘|x~t}xuw|fOEGD@<>>AFGGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jrA™o;<95<€‚†_IMOORWZRY\`§ˆbšitze~pmz‹ˆuˆ†tlš‘ts{jkŽLy„’‰„Žg1v†sl~}ƒtfet~„„…€filukp|gpp{n’Ž{s}|qpnum‚~wytiy‰‚ˆ‰ƒ–“’‹‘”•—Ž€yˆ—ˆ†‰†‡uiingdWQYWXY[MPUVZYNIIEJJHGBAFDCG=998;9:9<:9;:::@<9:<98>787715244533645031.**+),,++)(+'),,226,+5775478iO8;5n’ˆ™‘š–¤¨­ž²Ÿ¦º®«²°Ã²»ÃǛ—”™‹Ž†z…‘š–’Ž’‰tŠ„w‹ŒvwvywoxsiUFID?<;9:?@ADDEGJLOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOPQVLAIQIb¯³ q|xm}mqƒ…y„††yr •tx€su”‡5q¨Ž¡¡„¢„vp†|‡|sŒ­ˆ€hfbinrmpƒuioXuoŽš‘vlz|mqmpzsumbv„†€…‘Š‹Š’‹‘Œ‹ƒux‹€~‚€}yponj^Z\][YX`_SN[[YXLHJFJG?CABG?CD=;97=;:;;9:99;:?<88=:8;66651121353475531./,,+)*))***)(*)+/3DM2166643<vR7=7b’’ˆ–‘¤§ž¯•¥µ©­±®Á³»ÁƗŒ”‰}n‚‘“Š„‹ˆˆv„…o˜ŠŒy{{r|t|ko^JPG>@7458;;<=>@BEILLLMNPQRUUVWXYXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL7CMRSDJ†v€||v~lvˆˆ|}…ƒŒ~v¢™y~†€„™…›œa†ªŸŠ‚zv‰~‰ˆŽsŠ—ƒ{\dqtz{wŠlgiaxo…‚znws„zpsywkni]w‡}‡|ˆ‡€‹“—ƒ††}q„„|uw{}ˆtnqref^[Z]S[f^WQUY]VGKKELG?F@DC?AA=:97<;;=<::99;;=>79>9986754244004645654-,)+('''&(())((+++/00Uq<23331E~W4=9\Œw‰”Œ‘Ÿ¦‘ « ±©¯À²»Æº–‘”ˆz†vk€Œ’ƒ~‹…Žy„‚u¢†‚€sƒ}lylSXLAE311266688:<?BEGFGJKMOPQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMORLKT]YRKi„ˆ{‰y{q|Œ{|‰†~—‡v¡™ˆ‡’”¥¬©H‡­°¯Š€€“Š‚‹‚„‘©‡€˜˜Šœsl|†‡}Žhggx~n…†…q„†Gk€wqyvhmk_w}ƒˆˆ…Œz•žœŠ‹‰‘{u‹v|wmow~~rqpj[\\[cbXge\UPQXZQDLLGOIDFCCA@CA=988:::;;:888::?>6;>7595773344236756768;DFLMMLC7+"&'+)+++/00+nu22420L\5=<^„t|~Š…‡‘–˜’—¡¬¡¦¸¯³½´—’‹˜‹}tpŠ“~ƒ”•}†‡¥ˆ‰ƒˆ†y‰‹€u†y_cWLC60./23123668:=??BEGHJLNQTTUTTVUSQOGC?80,#‡[>?94.]–ps£UFIKMNPW`YpZ\_j“‡•€„‚…‘“~…‰‘š–‚ ¡˜•›š¥­“™»±§»Ç犌¡¥Ž“‰|r„žŸ‘~v……‹‡ihoƒ€tŒ†„‹q†‚w‡{v…}nvug•†‰ˆˆ‰ˆ¢«£–‰Ž˜€{‚‰zzogkx}x|qic]ZY]i\af_ZOLNXSQIQKDNGCKDCADDA<:87=<:<:88778:==8<=68756623445576867<BB?<8:>CQ^e\G2'&,,--.1(?Œ[.310Oƒ_4?;nvpgxƒ{€Œ€‹›š¤œ¡¬¦«¯°—’‘„¡”„xw€”}’†“–~Š’œŽ„‚Œ‹‚ŠŽ„€‹€mpj^CA4--////02234779;=?BDHJOQRSRSTTRPOHDB<87/9C><<63.l“—MPHIKKKNV`cggnu›š““‹Žšˆ“‹ ¡’£©¥£¬“¨¶¢¨Áîȯxº”š|Œ¡ž˜„“…‚¡Ÿ“™’„Š…˜‘–lpu‰‹•Œv„ql…Š–’ƒ…ˆr‰¡—‡“‰—¥¶©›•¢ƒ‡“„~kjk}~~q_[b^Yfj\lk_XKHOSQNMLFIQDDNFBCEGB>997=<:;:987767;:6=:785456345566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYpƒpu‡qv‘†~—–š”ŸŸ›§ ª–“˜žhf¤š~…“’z’‰’’}‹…™’‘ƒ€‹‰†‘‡„ˆ…xxhNR>//.,/.-/000212457;?CFNPRTPQRSQNPIED>;<:CF?><852<?R5HHHLLMNR^oŠ|s‚} ›§¦¢™¡—¢•œŸ¨ž©«Ÿ¨¬©ªµ—«¿«¶ÈÉ·ÉÑϾ› pi«©Ÿ„“’…œ¡ššš§‘‘ˆ•¢ššwz~”—‘¡’–—”ž{v•’«³‰— }•žœŽ“–š¤£§¶°’š¨ˆ—Žˆlss|}znf^[_^agd`gg\REKKQOIJMFFMCHMFFCBGDA:85<<899975658>75=84745754546958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f3A@ib^Pqu`n}awŽ}|”ŽŽŠŸ’—ž–œª˜žªBD}‡‰ˆ˜y‚‹Ž|Š†‚ƒ€‰Œ‰…“…ƒ†‰€‡w_bP460-1/,.00./..0015>AAMQRSPRSUSNSLEE@<>=FH@A@8662<9;FHGIIMOQYm†w•‹£§ªµ½¸¥®¬¬¨©µ¬±·²²­»±³¾œ³Ä¬»É˸Ŀ·¥£°²¬­ª£‹–˜…¦¦ ¢˜‚¦™¢ª¨¤‡…“£  ª ¤©Žœ±‹•£§·»œ¡£°“££ž‘¤¢«°­³µ¢•¦ª‰šŠ“Š•z{~ƒ|e^fZc`]bc^fg_[ODJHTOFILFKGFFHAKFCFFA;87=<88:974658<54<76:54644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLicXjpXz…v”…ˆ‚›ƒ’‘Œ’Úȝ–sV—ˆˆœ|†Œ‹Š{ˆƒ‡‘ƒ…Œ†…ˆ’†‚„‰†‡‡‡qna@E64<3/110-,+-1/-4?DANVQRTUUWUM\QGGD<>>FHCD@8;<5C;=FKIGHROPW“ „®£³ª²ÁÇÄ«³Å¶­´À³¸¾¶¿´Á¶»»¤¸Æ©¶ÉǶ¾¹´¨£´­°±›™’šŸ‰§¯ª¤•wŸ¤—¡«±³˜–©­¨®µ»²º¬¯µ¢±¬²µ¼¸´®µ ¨¨£¨›©°­³º¸¸¨œ¸©¥’“ ‡ysX_bUd``b__f`[UJDELVQIJKEJHEA@@KDBMF<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AEWQJL\ZQbdWzuq•}„†“v†~€{¿»£¼‚´”“Ž›„ˆ“Š‰z‡Œ“‡…Ž€Š†€†ˆ…Š‡‘zyn]W@EN<6:46AB764//6CHCQ\OQUWU]WP_UIKJA@?GKFFD;>@7D7?BJJEGWTP^¤®¤²´Ã¶¸ÁÌʶ»Ä½³´Á·¸Âµ¿°¸t±´¦ºÅ¤°Æ¹±³²´¨¤¶¶ª± ¢–›¢’¥±­¥­¬§¤˜ ¬³º¢¨²¹µ»¾Ì¿ÅŽ½³Â·º·¿¸º¸º­­±¦±ª®¾°½¼Ã왻¨•®˜™«‰~€zhU`_VhcidV[cYVTIHGLQGDIJAID>?BBK@@MD99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FRLALRWTYVZwjp„Ž…o{rxˆb¹¡™£‰•”–“””Ž—’‡‡{‡‚Ž–Š„Š{|‹ˆ†|Š‚‹„•}xzufO\dGEL:Qd`[^SF?;HPDZcQQYYZgZT`aMSOEA?IJHEFA@C=E6B?HGKMSZT^”¯¸µ»¹ÉÀ»½Êͼ½Á¼¸¶¼¼·¾µº³Æau²¥±šž«¾ª¥¨«ª¤¢²µ «¨ž•–ž˜Ÿ®¥§§¥Ÿ¤“¢§°³¨²²¼¶Á½ÓÉÉÓÆÂÅÌÂÊÄÀ¾¾À¼¼¸´°¹··ÃºÆ¾ÄÉ°žº«¢¬¥©·‰€|o]__]U_]heSYaVRVIEFNKA>HE=KB=B@=F>;H@796379>489:57045/26389374526?8@>GKRTTRPOQRQJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKE@JMPRLQ]hmlq†slrrtˆÕÀµš •™™‘Ž—’––Ž†ˆ}‡ƒ–‹ƒ€ƒy{‹„‡{‹yŠ‚—t}zkepvY]\Peeb`ed][XX\MdmURmn_o_XgeUYUKDBKKHFHHHHBI9D@HKTTV]Z\“¹À¹¾¸ÆÁ»¹ÊË»·º¶¹¹´¸µµ®¶·™du©ž­p^¢­œ˜¡¢›¤ž«¥”ŸŸ”Ž–˜—¨ž¦ŸŸš™ƒ¤¬¤ª±­·°¼¸ÔÐÎÖÏÉÌÒÌÏÎÊÇÀ¿ÂʾÁ½ÂÀÅÄÆÊÀÉÏ´¤¼±µ°œ¬¹½š}vi[^ZX[^XbbQ[`SQKCBFGE<@F?BIB@D=:E>=J?47535;=468977022/24169775555D3ELM>510006:477@IOJ;.&**(-.0,@M+/54m‰I0H‰t?>BD@CDGKODR\Zi`o—’‘”nlotu‡³¬¡¡Ÿ‹™œ™•‘›’…ŠŠˆ‡ŒŒ‰|„s{Šƒ…{ŠtŠ‡•t{ylmu|iseilhfjii`fiimZmt—­¤½ˆ‡g[oh^ZYTHKOPJKQLTQHLAJGKP__bgjb—·Ç°º´»¾¶±ÅǶ°¹±±»­³±¨«¸­¶¨žœ§šNšžŒ –‘§˜¥•Š““‰‘‰‘’›¡˜›•–‡ž™¦š¬°¨¯§³³ÓÔÔÖÑËÏÓÔÎÓÏÌÆÃÊпÊÉËÉÒÈÍÎÃÐÒ¸°Ä½Äº¦·»Ä¢laZ[\W^VXdYO\WNQCBIECI<AD>BH?@B8;D>@I=56655;:687654/10146278875367C5B8?-0,1348=97,.,1;FL=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYSfWs‘™ƒhroyyƒ¡ªž¦—Œ››˜‹Ž•‘šŽ}‰‹…ŽŠŠ‹ˆ|„‚p‡†{‡rƒ’‹~qyulpxr{nxsli€pmcinpyiw}~Ë¿Ãߧncxod[a`KPRUNY_P^]NQNTQUT\nnwƒr–®¸¬µ¨°¶«­½Á²«µ¦¥¹¨¬¯¡¬´¤±®›˜˜Œ‘”‘„›§‘œ‰ƒ‹„Š‰„‹ƒ”•——”›œ˜™™žž«¬¤§¢¬¬ÎÒÕÑÍÌÒÓÓÐÔÑÎÈÃÔÑÈÎÒÓÓ×ÍÒÑÅÒÖÆÁÏÈÈ鿸Мwlc[`[U^Q\ZOOTPNH>AGBCF=AB?FE>@?:===<JB45465<888664412/03526768533;=<E=@11+/349?5901022-2EO3)/3.32=N248C}_2A†tD:==I>@CFH<VRMO[u‡†‹wlwp}~€ žž¡Œ™“”‹Œ“–…y…Ž‹Šˆ‘‡‚{r~€‚‡z…v…“‘‰€owsls}|w|s‚xqk€rriprzys{¾Ëš²„vr…wiaj]CZZ[WfdXekTX]]`c^cx{‹™ª¤¤¢ ¡©¦ª±¹«¦´£¢®¢¤®¢§±Ÿ‰¦›•“‘Š’ˆ‚”‰k•¢™„†~‘ƒƒ“—¬‹•Ž•šŽ†’‘—§°¢ ¡¥¤¨ÈÍÏÇÂËÐÓÑÔÒÎÓÍÆÖÓÍÔØÖÖØÕ×ÕÊÔÚÍÊØÖÑË­ÄÃ̉pm`^]VRWRZOJGJIJ@;:;EBD=CD>HC?CB;<9<:GC46544<5687543250/2546745544<>=E?A62/-16;=081/254/-.;R017/532ED28>nb5=tM99@I<AD?A;PLFKYp€u~isyr‚Š€•ž”…‹–‰Š‰Žˆ€x„”™‹ˆˆ‹‰~ƒxs|}„‡w€{‡‘—„oxqmuvx}t†|yl‡vun}v…vy{µŒ<A‹Æ¥~}jeWICecfchjdoy[_fhknin„‰‘ŒžŸ ž‘—™ £¤¦²¤¥³ ¢¥Ÿ¡©¡¢±œ‡Ÿ’’“‘‹Ž‹‡„„~œœŒ‚„…z”ƒª–£Œ’‹˜“‹}—Šš‘ª³˜›œ§œ¦½ÃŹ¶ÅÍÑÐÒÐËÒËÉÔÏÑÕÚ××ØÔÙØÍØÛÎÉÚÚÒÖ¿ÌÍ´utlb[WQSPXUEFJIEE=:7:@BC:HE@EDBDA;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?2*(.BT29254/7K75<`bA<svV87AH:?C><9QECJTlnopbqqt†}—‘žŒ~‡’ƒ‰†…Š‚ˆ}x…——‰ƒ‡†‡z„yq{{…†uz†ŽŽzp}ppz€r{r„‡€nŽzuw}}‚u|‡‰°tYªÂ·’‚qnc=^hrpqpnxw‚eiorvxr{Œ‡“’›– –ˆŒ“œŸ›Ÿ« ¡¬œ¢šš ¦ŸŸ¬™Œš‘“Ž…}ˆˆƒ…‹Ž ™“ˆƒ‡~l™y„™‡ˆ“ŒŽ•Œ†{›ˆ“®«”•—Ÿ˜¦®µ¼©­½ÆËÈÉËËÏÉÄÒÊÔ×Ø×Ø×ÔÛ×ÓÙÛÖÏÛÚÒÖÉÕ̓uxfeXWNQR\GBEII>A>=8:>@<>H=@BAAEA>?:87DB755479.566435532323647553458EBDCEB56<FNSM[nfcnsk`V>,4LG865433BF4=W_hLux^8;?F<<B<:9D?CGRk_mdbflv€ˆq‘›€y€Ž~ƒ‚…„|}„˜Ž‡‹~†‡wƒyn{{‡‚tz’žŽ¡vvƒtu~t€„o‚o’…u|…zv‡|‰¸Æ¥Ãʸ‚–œxpfNec‚{w†¢‹yzw{„€|„um”–•–˜‘ƒ‰—š——¦˜ –Ÿ“’—£žš«–‘‘‹Ž“ƒŒ…‰‰†‘žœ™‰…‹†—{ˆ‰Ÿ—‰ŽŠ‹‚|¡‰‹¼¡˜“—šœ¨¦¥­ž§µ¾À¿¸ÆÉÍÎÅÍÊÑÖÕÔÙÕ×ÛÔ×ÙÚÛ×ÛÚÙØÎÛƃvvdfa]RUUTMKDMD;=<<9:<?9=A7>?@=?>=9867CA6455=80665547745613854564567HH=DJE7925;H>;9:7HP\ZRUXK9T>;95327I8=NYMHxxd5=>C=<@:6:>>@EQ_Yfa]\itzyl‰’wvzŠ|~€€~…{~‚‘Š…†z…ˆ|v~um}}‡~t’ž‘Ÿƒ’|‡~x~y‹Šoƒ›t™†}‚Š…|~‘{©Ã ½Œ›¤œ~Š„}‰sŒ‹s¦šœ˜”…{‘‰„iGq¡¤žŒŒ‘’…ˆ‹’•›“”‘—Œ•Ÿ”¡•’ŽŽ‘ŒŽ‹„‰“–šŸŸ‰Œ”’‘ƒŒ¦™ˆ…Žƒ†„€¥†Š‹¸˜‘•–¡¦ £®¶º´«ÀÆÊÐÈÇÍÏÓÒÒØÒÕ×À×ØÙÛØÚÚÙÙ×Û¶vutgfbT]YROOHCLC==>99;:99<=6@>?==9::;37D@8378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWO<MTHN?96333>C;[X>5YypZ<<A<=>8589?<DRSRX_VXfmmmiŽŠqsxŠ{{€||ˆ{}|‹‡ƒ~u„†zszsm~…~w†›¡›ž”’€Œˆ˜‡€œ’nˆ©…{ Œ|‘Žƒ‰„œ~›‘Š£¢Ÿ‘¤¯ ‹‘‹†‹“†Wr­‹Ÿ«›ƒ™œŽ[ƒ¢‘‚Ÿ“”Œ†ˆŒ’’Œ”••ŒŠˆ–›•—’Œ“”†€‹‰“ŽŠŠ—™£¢†“– ‹Š‰Žƒˆ€ƒ‡…¥…‹³˜œ’”—¡ ž™’›§±¸¬¤½ÂÇÍÈÆÏÌÐÌÎ×ÏÑÔ®ÖÕØÚØÚÚ×ÖÙڝlyqccZZVQUWC@ID??>:49:;7:;:3<<?=>7;9:1:G=:27=@50677255?65;55858:57735HR7GOK994=EJB>1FCLA98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:;@;BQKKSYPTcbxlb~‘ƒomw‹xz{}‡||w†…€sp…‚{uwvt…ƒ…}’¦¢Ÿ¦¢—Š”—‹Š¨—rŠ²„¨’„™”…šŒ£– ˜“‰›ž¢“©° ‘•‘ŽŽˆ–Œo·„šÄȲœ¢¦œœ˜–‘±d¤ÍǕŽ†‡‰’“•Š…ŠŠ†–™›”“‡–˜„€‹™ˆŽª——¤¢ˆ™ž–š‰‡˜˜Š…‡¥ˆ“¨š—”–˜¡˜Ÿ™“œš¢²´¥£¼Á¾ÇÆÅÉÈÉÂÊÓÌÍÔ¨ÒÑÖÖÖØÚÔÓÚÎo{d`[\[MISYBAGD;B>837<<:8>64::<:72?:929I:>67BC32:96264>=4;>6949;57944KQ<JQK9A7BGI@64JELF>;88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBc‚GvŽ}|m~ˆxz~{‚‚ƒwvƒ|mn‹{}xx|…‡Š~‹¢³§£«³¢—§Ÿ¥¤–•®¢ƒ‘¸•’³šŒ¢¡Œ¥›°£¤˜‘§–¨™¬¯¤˜•–•‹˜š—¡ÀŽ£É¸«œ£¦­˜’›²…†¨¢œ˜…‰‰Ž•Œ‹“ˆ†‡‰“˜•Œ‹”“‡•™†„‘œu‘˜³–—¥¡‡š“‹Š—›‰‹–Ž†}Œ˜ž‰œ›š“˜—Ÿ“ ”ž› ±®¢¤·¾´ÅÇĽÃÃÀÆÍÊÉÓ¦ÎÌÓÒÑÖØÓÐغovrY^S^TNHIMEBCD5>:77:?<<7=42669774>5;5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=88567=:JFDGMZ\YJf`;H„‹zzn…†z|„x†~px|~}orz~‚|x†‹‰†„’¦»­¨²½°¥­³³¨£¡°¬Ššµ£¸¥•­¥—©­¸§¤£Ÿš©˜ª¤®°ªš™œ”•‘— ˜š»»®Ê¡j·¸«°”™Ÿ£¬“—¾£^ª²ƒŠŠ”‡|ŽŽ}ƒ†Ž”•ˆˆ“–Œ–‹–˜“™´—–«Šœ”’Ž‘’Œ™›Š’ž‹‰–Ÿ¡”˜š’œ˜ž”¡ ”œ¥¯¨¡¥³¸¬ÂÈĶº½¼ÅÇÇÂÑ ÆÉÍÍÅ×ÖÑËӟmweYWP\PNEC><CAB8@885?G==6<35345454B49:BM:B;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPdHb`bpJ@‹Š~€s†‡}‚ˆuƒŠ‚n}|}pw‡wŽ‚‡|Œ†Œ™ªÂÀ¯½Æ»³´À½´­«³¶Œ¨³­­½«›»¥¨­º¸«§¦¢¢¤£©¯²±«œ¤™›˜—Ÿ¢¦¦’¤º¯©À¼­®²¹¥¤¨~ˆ†œ­½°‚‹Œ‹ƒŽƒ‘zˆœ‰ˆ—‹•–”‘š—¨š±š‘¬œŽš’Ž•–˜’¡‘‰”›¤¬”–”œ“¡›˜Ÿ¡”šž§¦¤¢¤°³§ÁÆï°º·ÅÄÿͦÇÄÇĽÖÐÍÄʅqp_YW\XLJAKAFG?A@C;:4>A==5=6>343241A17@BN>G@CNCA=C=;86CC5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUO79GD?CF\eF`igZ]\“ŒŒ‰{‡Œ‡ƒŒu‡‘Šo~{‚q~{•z’””˜“–§³ÆÉ¿ÂÌÂùǽ»¯«¹»˜³·º²À®¥Á¤«°¼½ª®«££ž§«®´°ªœ ªœ¡œ–Ÿ°µ¨Œ£ºº¶Á¼¬©³¥¤¨”…Ž©Ä䂋‡ˆ„†•”yƒ‘‘¡ŒŒ”’Ž‰—Ÿ˜“™•˜¦ ¯Œ«œ–’‘••Ž•’¡”†—Ÿ ²ž”™“  ˜¤Ÿš › ”˜ž¥¤¦¦¤¯®¦ÀÄ¶Éþ¶Ï²Ä¿Ä¼³ÑÊÈ´rvjZUYgPLHBLKLJAA>DD<5AE;;3=8B332263A05IEN>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBeZMe\fTbk™–ŠŒˆ“†‰y‡”r€{x‡‚‚z¡–¨šš™º½ÇÈÉÁÒÉÊÂͽ³­¼¾¨»À½»Ã·¬Á©¬³¼¾ª°ª¤¥¤¬®³­¶µ Ÿ¯Ÿ¥¢˜£³½©›¨½Á¤¶¸°¬”²¬¬¬—‡š©¦¥‘‚Œ“¥–ŠuŠ’y…Ž’ž ““Œ”£™–œ••£žªŸ‘¥šŒ•–ˆ|–“’£š•Ÿ¡œµ¥ž–¥£¢¥ž¦˜ž•—›¤£©§¢²¬¨¼À拾·Ì¿¹¯Ä³»¾Á¸¬ÂÃÂÀ—jw_VUYXJJLIFDDHCCADL:4DI:;4<8E.12352B25SHN<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQG7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>iH_XbZccVžœŽ—Žž’‰ŠŠ “„x…–ˆŠ‘€–¡™®§¤˜Â½ÇÃÇÅÓÍÎÍ˼·°º¼´½Ë¼ÃÁ¶·¼­³¿º½®¯¨ ©¨¶­®©²·›ž­£¨¡ž«·¸ª¥°¿Å²¾º´¨«¶´®®—–¥¬¨Ÿ‘’²Å§–Ž|’•|‡’™ª™˜““’•“¤“™”¡£¢œ˜Ÿ˜‹ŒžˆZ–—’—¤™e˜£Ÿ²¥•¡–««©§›Ÿ¦—˜–˜•¡¤¨¥Ÿ¶«ªº»Ã´¥´µËÀ¸ª¶«²»¸®¨¸º½¸€hkXUSSMEIRMK?AHEEHHH95EM;>8=@J.32025C55OVN<LFKRLOHGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|gV;>@BFBpEjIReaLF¥”œ—¢—©–Œ‘ƒˆ¦“ˆ‚‡‚œ„ƒ•”š¢Ÿ¯¾¯¡Ç¼ÄÄÇÆÎÎÎÒʾ»¶±º»¼¾ÏµÃ½¸¹·³±µ³¸³«§œ«¬¹ª©§¯¯˜£¯¥§¤¥µÀ±¬¬´¿ÃºÀº´¨º¶¹´¯–¥­®®¤‹“”¡tš}—™„Ž—™Œ±•›š•’’™™¥£• ›—š©›¡ ™Š–œ`J–œš•š¥–U—° ¯œŸ¤”®®«¥š ¥”“˜˜œ §¢š´©ª³»»»ª±²ÇÀ¹¦¬«­²²£¡²²´¤mkcZWMOJDOOPR;GKIGICC>:KU?A:=EM07534:B44MWO<JKOUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@BAF3>58JKCA=C;4EA:A?>H@5*B52,>c]g:35tde@R7&#3}hW;:BC@=QEWSsbWFHª–™ ¢¨°™‘—‡‹¨–Žˆ“… ˆ„—¡›£¥µÉµ©ÆºÂÃÈÊÉÈÌÍÆ¿»³®¹¹ÁÁ̵ǺÁ¹µº°¯¯³µ§¤›ª´µª©¦­¬š¤®¥¤¨¬»¿¨¬¶·¿Á¿¾¹´³Ä²¹¾­£¯µ¬¹¦ˆ›—¦›v¿Ÿ„™Ž“ššŒ®—¡œœ—”› ¡¨ž¨Ÿ™šªš¡§ž˜‘ƒnv’¢š•¢‘®²£ª”¨ª—ª­££Ÿ¤¨‘‘™œ‡”¢ž–±§©«¹¶½²²®¾¹¶ £§¨¥¦œ›­©©‹`c_^OJKFGMJVL=MENKLBCD<QV=AABDO18=77?B75UXO?HNQYSPQUKQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW;:=.-R`MUH~e^HE«•›¡Ÿ»¯™•ŸŒ“«œ‘’“‰«†¡žŒ£­”£¤¶Æ¾´ÀºÂÂÇÉÅÂÎȾ¹²¯¹µÁÂʵŲÁ¼µºª¨­­°££˜ª´»¦©¦«ª©¯§£ª«½¼¨­½µ¸¾Ç¼·¶¸Á²¾Á´ªµ·«¾¥£˜’¢ ½Ÿ‰š ™—žž·Ÿ©œ¥¢›œ¡š¨¤³ ›¦œ¨ªž˜•”›‹—‰Œ¤¢”¢ µ¯¥¤“¯«™ªª££¨””Ÿ‚žžœ•©¤¡¡³´º´­¨µ²³žœ£¥š—•˜ª¡žu]Z^\IGEFMQIMEGGBSLJBEGAVSCH=AGQ1;B7:BF79\YKALPTUSMWRNUJE@JJNO9C@5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*BdT49-19f\FCCpbGE§—¤ŸžÃ­œ—¥˜šªœ–››ª–•§¦•­¬˜¢«¶Ä¼¾·ÁÂÀÇÄ¿ÍÆ»½¹²°¹³¿Ãȵ¿°¼¶¹¶¦¤«¬­¡¡šª«Å¢¤©«¦ž¬¯«¢©©¾¸§­¿²¸·Ç¶µ¹¸À³À¸µ³´¯¾£—£—”œ”®Ÿ¢£¥££Ÿ½¤©ž¨¬¡›¥ž½¡™£Ÿ¢©¬¡—•ž“ž‡„“Ÿ¤ žµ¬¥œ•±§™®¦™©Ÿ˜”žƒŽ š›’¥¤š˜«±µ±ª¥ª®¬›˜  ’•¨ž”e_W`\NHGJNLHEDIA>QIA<GIH\ROK=HOU4BF9>HG5Ca[KBNRUWVQXTRUI@8RQPM:GA4CHQSIC;C>GVKC@O>K<06;GF>;FA46@9:?9;15D0-,/Mv\4KZ5,MnW<-=)#zbQ5CKQ9mRF<KxeaVK¢š£œžÅ¬¡ž¬Ÿž® “£Ÿ–¤ ¦©¬˜¶±¢ª³¶ÅĽ¿µ¿Â»È¿Êǵ¸µ´±³´·ÁŶ¾±¸µ¹´Ÿ§¬ª¬žž¥¤Á¥Ÿª® ¥©­¯¢¦¨½µ¦±½¹·¶Ä³´¸º¿´ÄÁ¹¹®³µµ£¥•’”¡® ™¢ž¨¨«£šÂ¬©ž¬®››ž™¦ ½¡¤˜«¬¬¦¢ššŸ“ž‰ŽW–Ÿ¥¡ ¸ª¦“˜µ£ž± Ÿš®–˜“œŽŸ—•Ž¢¤–¦­²ª©¢¢¥¥••˜‹‘’¤ž‰_bXb_KHJJNFEAGK?=JB99JJN]QQI=LV\9FI=DMI8Hb\LCLPSYYVWOZ^IA=WQIK?H?5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+w`S6SZkWrGE6=ue\KMžŸ¡™žÄ¨¥¢´¢³¨“«¥ £Ÿ¬©¬»°¨¬¶±ÇÅÁ²ÂýÆĽÄɼ¯°¶­°´¯¿Ä´¹±°¹´¬™¨±©ªš¥¡§Â­›¬±œª£®±©¤¨½¶§·»¾¯·Ä­´³ÃÀ´Ç´»¸¬´¶­ª¢¦–••¤¬¢Ÿ ›§«°¯¯»²¦ ©©™™˜“¢£¸ ¡£’¯°¬¥§Ÿ’¡ž•ž•žš¢ž§³¦¦Œ˜³›¢­š›¬“•’™‘¡–Ÿ¡”‹¦«¯¤¦¢œ ž‘‘š“…‹‘›_dZfdJHLJSBC@IH;;F?99OMU^RSJ>O^]=HPBLLI9Mc\LELRTY[SUO\bHA?ZQAHAKB7FELKM?;BHDNB=;N@A3/97CB97F;+6<46<25-/4@1+'VtSeO?104b[M23>0<v]^?[T^eq@8;H–weA4Ÿ£ œ Ã©¤ª³¢¤µª–³­§¡¤²¬®©»²­±µ´ÆÀÄõÀľÉĵ¿È´«µ¨°¹¬¿Ä³·®¬¶¹¥˜ª²«ª˜Ÿ¦—­»´›¨°›­ ®´²§«¹³¨º´¹³¹Àª·²Ä¾µÇ¨¿¯®¶µ©§¬¡˜—’¦¥¢¢˜˜¥¯¸®²µ¶ Ÿ¨¤š••”¤ ·¢¥¥–¯²²§ª¦¢žšš›–˜¨Ÿ ˜¡ž®²¢¦—®˜¤«–™ž£šŒ’–˜…•ž”Œœ”‹¨©ª¡§¡˜ž•‹Ž™…”ˆ“žwbg\jiMONNT>CANC;:I?77RO]_RVQAW`\BJSHVKH:Td\NFON[W[RPQX]GAB[PBG>NC9HGHOP??CIBLB<2IA94177B>;7E7+6914801-/.<6-#Bqgsk23/1[bZ33806p[bH05IohUCWFŒyfC;¤£¢¦¿§§¯±¡©¶«žº±¬£«´¶±°¹·°·¸¸Ä½Ãǽ½ÄÂÆÀ¸ÀÅÀº©¶¤¬»­Á··©¬±º¢”­±­²–¤§‘ª¹ªŸ¦±« °´³ª©¶¶­½­´³¹¸­¹±Ã»¿¿¦Ä«±·¯©««§Ÿ˜™«¡¢¡‘˜¢±¯³¬°¹šœ© š—“˜§ ¶©¦£¢±±´¬³¨¬Ÿ›  ›ž¥œ¢—£³°šŸ“¥šŸ¨™”¢”—ˆ“–’•–œ“ˆš™”Ž©¨¦Ÿ£œ—›’…Ž™‹}‹•„™igk`lmWPQ[UABET@<;IA7:XPd^PWWEY_^MLRN^KJ>Zc^NHPO\UYPKTWZI?DXPDF?N@=IGGQPB=DFBM?:1D?77547?=95E4+75/261--.,1=*'+=\p=>1.0dZd@1647gY`F(?8l}g[V;‰{cC=¨Ÿ¢ª½¢ª°¬¤²¸ª¦¶µ¬ ­µ½¯³¸»º¾·¶À¿ÈĹÅÂÀ¿¸Ä½Á·¯µ§«·²¼¾¾´¨®±¶ž–«®¨®—¦¨Ž§»Ÿ¥¬³Ÿ¬¢±°³¬ª¶´µ¾®°±µ¬°´³Á»Æ·¬½°±¸¬­ª£²¦ž¥ªŸ¤—‘š ³ª³«ª³š§œš•Ž¡¦¤´®¨¡­®®±¨´­²ª¤œŸ¨¤ž•¢™›¨µ©–™’’™Ÿ«–—„”–Š˜œ“Š–—š—¦¥£Ÿ–•—’”…{’‚‹•dkqgoq^FYfVDBMXDZ9HB6>\Qh\OY]G[^]OMRXdJJC\b_PKMNXWXPJVVWL=EUJEDAM@AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,,%2+*5K1/'__`U150=`V^8)C3YU\gK6ŒzfL@¤š¡¥­·¥­ª¦¯®·ª¯µ»§¦±·Å·±¶½ÁµµºÄ¾ÌƹÃÀ¹¾¹Ã¸À¹²´«©º¶º¹¾´ª­°µ˜˜§¬ª¬›«««¾ž¬®²£« ±­³®®¶²¹¸ª®¯±¨µ¯µ¼½Ê³ª·µ±´¯®§¡´ ›¨­ ¦––šš²¢­ ¦¯—¡¤šš“Ž£¥¨³©¡¦³¬«¶¥¯²µ¯¤™¬§š˜Ÿš™«·£—“‘Ž—œ¡—–”ªš‘’—Œœ™–Š”“ž™¥¢¢ ˜–’“•z‹…{ŒŠ‚Š‘jmwmu{aE`kYIHZZ={JFD6AbTi[M\aK\]ZRRRb`LKE_``QLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T_T_/5(C_Q\.+B/JGP[G3cYTKD™—¡±©²ª­¦¤¯®¶©·µº¤¬´·É»´»º¿¿´³·ÃÀÌȼü¶½¿¿·¿¼±½­§º¹·¶Â¶«¬±·”–§®«¨£°ª”¯»¤­±³§¨£²´±²±µ±¸´©¯¬²§·¯·´ÄÆ·©¶¶¬°­©¨£¶  §±¡¤”œ™•±ž§œ ªŽ©£ž›–˜¦¦¥¸§£²µ¬¨²§®±¶¬¥™ ¬¨›œžœ”©¸œ”ŽŽŠ˜›¢—˜¥ œ“‚”œ›—–•ˆ–˜š§œ¤ ’–‘•v„‡{„ƒ‹Šlovt{~\Kem\JNd\?b{GI8GgWe\L^cMXYWUWTi]OOH`]_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANGf27'GbLV%-B.=ELQ<3rkICC‘š¥¯¥®¯«¨¥±³´«·²¸¡«µ¹É¹­Á»Â¸³±µÂÂÎÅÀÁ½´½¿¿º¾¼²Ä§©¹°¶¶¿¼®«³±œ §±­¦¦¯¥²µ­«±²¬©¨µ»¬µ³µ­´­ª¬¨¬©¹®²±ÈÀ¹¥º°©¬¬¥¨®±¦¥£¯¤©œœ›¯š££££‘­Ÿ¤  ¢«¦§¹¤¬µ¶¥«¬©­°¶®¢ž£©ª› ››’¤´™Ž‰‡¡ ”Œ”œŸ’ƒ’’œš—•“‡—“•™§›ŸžŒ’‘v}…|{|†‰ˆprq}|}\Sdn^NYg\FD–[G;NmXb[L`bNVWVWTXg]QRLcY[TKGOTSNGIVS\N;P^IBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/+1()+,-*&5*/&0)38:1&*3Bc:6*HeHJ+:H>3BHS,>k;GHœª«¢ª±¥©¥³µ²µ¶²²¡«®½Ìº­ÀºÇ±´­´ÂÃÒÅƾÀ²¾À»¾·»Ä§¬·¬²·¼À¯«±¬ £§­ª¨¤°£ª²ª°¬°¯°®«³¼§·±²©³ª«¥¥£­º­ª²Ãº¶­»©©§¬©¨²¦ª¤£®ª¨¢žœ£­•¥ž˜ž™¬¢§©¢­¦¤­«¸²²¡ª¢ ¬¯±¬ž §§©™£™™ ¦—†„ŽŠ‹ž ŽŠŒ•šŽ„…”Ÿœ”—”†–”“—¤œœœŠ’‰~‡…|v~…„…rqpˆuk_Y`nbQsq\K;„|F?WtXaZNd[NVVUWQ\a^SONgXWVKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*25>10485(5/*,.30;),,'%234$,2-860)(1;\J0.JgDF8;B05EKX1@•Y=LE•˜­¨¢«³œªª°·­¸¶¯«¦««½É¼°½¶Â¯±¬³ÄÃÎÏþ¿´ÀÂú¿³Èë®·­²¸¾¾²­­«¤§ª°¨§¨±¥´®«±¯­²±´¬´¼¤¸³­¬¯¨«Ÿ£ž°·«ª­»·¥·¶¤©§««ª®¡©§¦±²¤§¥¡¡¬—ª¡•› ¦ž¥¢«¤­£Ÿ§±¸®®£¦£›ª«®©¢¥¤¤˜Ÿ›–˜œ’‚ˆ…œŸ‹ŠŽ‹˜Ž‰‚‹—¢›‘š‹“’‘“£™›šŠŽ‹‹}†ƒzs‚€|ru‹¤‡xk^`nfWe‡cN?g“LEbyWbYReTMVUVTO\]aUKNhVVWIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*39?./463)4+*,+.#4.-+&(+79*&6+<-2,&06VZ.0JgAA<<B+:JO^4D†=GFD—“±¦£¬±˜«ª­¶¬¶²¬¦¬ª©¼ÀÀ·¸²»µ¦²¯ÄÉËÑ¿À»¹¿¾Á¹Á¹ÀÄ­±µ±³ºÀ¾²°®¬ª«¨¶ª¦®¯ª¹°¨²²¯³­·ª··§´·«¬¥©ªœ¤ž´³©¨¤´µ ·® ª¨ª¨«§ «¬©¹µ©ª©©¢ª ­œ“ª¡ ¥¢¦£ªŸ§´¯¨¦ª££˜¥§§ªœ¢¤£ ™˜ ‘Ž˜~‡Œ‡ƒ†ƒŠŠŽŽ‹‚…”¢šŒ™’‘“Ÿ—™–ŒŠƒt†xt‚~yv~€‡orggpw\asˆkO^™VHmxUdVQcOMVTUPOX[bUHOiTVSGPYUI>IHOQPxLMV=<KD?@A<@CUC9AK=5;E13;:7*4:=+-341*8**+*,))(/*&)%3;,$2)2021&/2Qb02?f=NX>C,>LT_/Ji5OD<–Ž±¢¦«¯š¬¥­°´µ°¬¦°ª¨º¾»À°®¹®¡¶°ÈÇÈÑÀ¾½»»Á½ºÂÀ¾¿®²²±µ¼»Â±±³«³©¤µ¨¥­³³¹±£®¸²°²»«º°ª®¶«ªŸª¬Ÿ£ ¶­©¡Ÿ°³¢µªž¨§©£ª¡¢¬­¨½¯¬®­¢¨¨ ¬™°¡˜¢ §§ž¨›™ª±ª£ ®¢¡”£££¨˜š¨¥˜—˜žŠ‡•ˆ}†„„£–„‹†‹ƒƒ“Ÿ–ˆ‘œ“‘œ”—Š††wt|uxyyssyg†¤vi_ek€tgˆŒ}SXo^JxsSdTQ^MMRZfNLVYdXGRhRQ?BNQaQ:IHLSIqQLS;<I?;<=;@@W<<?H73CB15:93-5::)-31--5)(+-,42#2)',%.;.&1.0-14%,0Lg:48_=ad?F1CP[[*HM9U@4‘³¡¥§¬¤§¤­§µ³²«¥±§ª¸¾À¼¯§¹ª¦¯±ÉÇÈÑü¿¾¸½¾¼ÈºÁ¸°¯´±º»¸À²²º¬¸¬¢´§§¬²¶¹³¨¨½¶®¶¾°½§®¬µ¬­œ©¯£ ¥­«¨œž«³¥´¨›ª§©£©ž£©¨©½¬´°®ª¤¡®œ›³£–¤œ¥¥Ÿ¥œ›©«¦Ÿœ«¢œ“œ¢¥ž˜—¨©’˜š”Š‚…~ƒ€ˆ…~}‹‡ƒ“š“…“¢Œ”‘‹‘›’•‡‰~r{z~|hx|ytop{g„x„‰dagar„zmgx]^T?W{mTbPQXKLNru]HZ[gYEUePD>JODCA9HGKS?jbJQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11'/>KH0%90%,,09/,,+6'17#-0GjI14X=fcBJ7GS`U*=9DW=*•²š  ª¦¥¡«¥¸³³¦©±¦¬¸Á½µ¯¢¸­¨¨°ÂÉÉÌÁ¶½À´·¿ºÈµÂµ³²µ²¼·¹½µ­¹µ¿­ ³§««°µ¸µ¬Ÿ¾½ª³Á´¼¡¯³µª¬Ÿ­°£œ¦©ª¤ž›¥±§° Ÿ«©§¡©œ¤¨¡­¼¨®±®¡«£¤¯ŸŸ­¦—Ÿ›¡£œŸœš¤«£œ›¥¥–—• £—›—¥¬Œž‘‘‘‹‚Š€€Ž€{™”ˆ{}‹†‹‰„’˜†”£‰’’‡š“‰}yk~vyxc|zpooqvg€sj„heg_lslaio`o=ZykU^OPQJIMTZWM]^lWDW_O^PHMDF;7HEKO<rhKK9AE;;==;;=J49B<3;G<4?18-68;2(09/,4/.=-*K>)49&'.34.0+/4&,:$41AhY13S>e_DL6KVdO*;1NW=#”™­š¡˜¨¥£Ÿ¨¤¸°¯¤¯°©«¸Á¹³­Ÿ¹¯«¨´ºÈËÈ¿¶Â¾¯´½·Ä¶Ã²®¹²³¿´º½·¨¹¸½ª£´¨©ª±®º±ªœ¼½¥°Áµ¶¢¯¶µ§¦§°³Ÿž¤¦¨¢¥™Ÿ¬¨©ž «®¦ ¦˜£¨ ±¹Ÿ£±¯¡¬¡­¤œ§¦©šš›Ÿ¤•›žª§—œ¡ª“™”™Ÿ“™–¡©‘š‰Ž†|‡~‚}| Œˆx‚‹„‰‹‹…‡“š‰•žˆ‘•‚Œ—‘}…|sp}qtt`zxhmopnh}qc{mieb]e…~_ZsjqJIiXZNPLJHPRQIO\_nSDXZRhOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23.:;83&2<0,85B*)-B*,4;NN@;73-.+-7**<%53<fd24M?e]FO=QZgH*>/WU5(—ž§š—­¡¡¡¤¢¸ª±¥´´©¨¹Äµ³­Ÿ·­®­°´ÆÈÀ¶¾Á¹°´¼¶¾»¾¯«½°³¾°¼Ã¹¨»º·§§µ¨¨«±­³±¨œ¿¸¦­¼·²Ÿ±·°¨¥§¯±›¡¤ ¥¥ —›°§¡Ÿ£¨¯¡Ÿ¡”¤¤¢·°¡¦±«Ÿ¬£¯˜œª¤©Ÿ—šž¥“››ž§«šœž¦—–˜–žŽ“—¢¨¢‰‹†z„~„ŠzŽ–‰†x‡ƒ‡‹…“˜–™Š—~†˜Œzzprwoot_ywdkkkhg‚merkkdhXas^ZluiYE}][XOOKHHRUG2:^^lPDWUYeMHJEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<#8R=*113>D5,-'42+;+139cl84HBg[HTCT]hE.;1^Q,2–¤£˜–ªž¦¡£¡¸©®¡»¸¥¬½Ä³°®¢µ¯­­¯´ÄĽ³¾º·°³¹¸º¸º®­¿³´¸¯¿Á·«½º´¥¢³«¨ª³¬®²£Ã·¦©··«Ÿ³»ª§¦¨¯«™¢§œ¤§”˜¡³¦šž¥©©œ¡ ”¥Ÿ¤¹©¤§­¦ž¥¡¨“Ÿ©¡¡¡™›¡’›—¡£¬œœš¢–“•–›Ž““£§¤ˆŠŽ†y„|…†}œ‰Š†x€ƒ‡ˆ‡‘…•“’Œ‘•”ŽŽ”{‚—‹w|lurmlsbythfigem„gghdfhi^ebifYezb`PsT[[SKIGIOS@!+i^jLCVU^`KHGEC.:B<F<6KPD8:D357==895?:;4>8@L=>93)8><:9*6@3.E4(+,>0-N?.+-7-1195,&.5-80576`tB3CDh[KWGU`hB377aL'2Ÿ¤¥“¥§œžžž¤µ­§ªº·§¬ÃÀ·¯¬¢µ®§®¯·ÁÀ½±Á·°®²¶µ¹¸µ¬ª¼´¯²±½À·®¼¼±¤Ÿ¶¬¦¦µª«¯¡ Å¬ª§±µ¬¬´ºž¨©«±¥˜ªž¨¥’š¦®£™ž¤ª¡›¡œ˜ §¶¦¯ª®¡¡ž¡• ¦Ÿ¢ ™œšœ“šž•¦Ÿ®£˜—Ÿ–•Ž•˜Œ˜š¨ ‡ŠŠˆx…w‚‚‚œ‡Š‚ˆ{„ˆ†„„–•‘‘Œ“{ƒ•Ž†s}gypkklguskagdbsadefeiibfoZ^X]lcaMgW[`VIGHKMRX?9`liGBUS\[IHFEA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A<-5B37=++,/A*JK./*+3722(57$+7.72685\yN2>HiZLZJVbfA:3@bF%5¤¡’Œ® š™ —¥´²£²¾·¡±Æ»º°°£¶¬«®©¹¾½»­À²¯¯®¶®³¹³§«¹±¯®³¶»¶¯¹¾¬¦žµ« ¡±¥«° ¦Å¡³¦°³°·­µž¬®¬®¢™§ª¦Ÿ•œ§¦ ™¥£©œšŸœ•ž­°¦¹§®¢¡ššž™Ÿ£š¥—Ÿ˜œ•š¡“©—­¨›”ž”•šŽ•”˜§§Š‰Ž{t‚‚‹˜…†|‰ˆ„„ŠŒˆ’…“œ’‘‘—ƒp‚gynhkjgqrk[hcar`dgknkfjfdl\mmvqaSbhceZIGLMOYQPVaeT@VRZTFGFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.4<;K6/.+,-24:5#3*)6.55465Z|]1:Kj[M[KXdc@A1HbB'4”£œ±›”¡›©³°Ÿ¹À¶¡´Â»½¹±¦¶°©®¥¸º¸¸¬»°­««·ªµ¹­¥²µ±¯©±¶¶±³¶»§© ¶©Ÿª£ª®«Ä™¯¦°±·µ¬¬ž±­¯ª¢›¤¬©œ•œ§¤ž™ª£¥•š ’œ£«ª©ºž§¤ —ššž¡k£–™qƒ—œ¥v’¬¨ž•—¢’Š˜™€—ŠŸx…“ƒmi~w„rl†Š†}„Š†o]d`g„—†k‹”’ux‹„ƒ€gˆ€hvifX]itnNPjcfq‚f^dfoki]\^‰…ˆhOKC8ETg]JHPPUVLHSapteF[QUPFGFC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,,08>G701.*.*/668,#1'214:276Xl15Ok[N\K[fb>G1Na<+/Ž¤šˆ•±›“ œ«®«£½Å¯©·Â¸¾¼­§¶±¦«¤¸´³³°¹®ª§¬´¥±µ¢§¸¶µ¨§­¶³®´®´¢©Ÿ´«ž£¥§¨›°¿•¨§±´¹­®¤¨­ª«¦¡Ÿœ¡¨¨œ—¡¦¦œœ§¨“ž ™‘Ÿ¨ª£´¯£¢£œ–˜™—£ˆ¡’šˆ¡ˆ•Ÿ¢¥€¨­Ÿ””ž”‰„rxŒŽƒˆ uˆi—‰f~sy o‡‡ƒ~Œ|¡ Ÿ™{‡žtˆŽv›Šl‡‚ƒnied{mrbT†mcmi˜qXipn†W]i[kjZˆpmyr‡h‡„Y^FM>F^MERVVQPRWTg^LZLRRPEFG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82*/1<I:/01.*/(-4583%&2115>1<8Xƒt15Rk[N\L[g_=K1T^7/(§˜„¬™™Ÿ«ª¨ª¿Ã¯²º¼¸Á¿ª¤·±ª¬¦´µ®¯³¶«©¥±­¥¶³›¬µ¶´¦§¨³±­²¨®ž«¡³© ¤¥›¢¥ž±¸•¦§§·¾¦¬§©ª«§¦¢ ™¡¨¤š™§£¥™œ¥ª–“£œ•”¤¦¦¡¶¤£ ¤˜•”˜”œˆ®˜•ŠªŒ˜£†±¥®ž•› —z‚Ô¨‡”À›Æxw±¥·–d€Àœ¿y„„yƒ|‘Êq–¼œÅ{r¶§º{l—±«±yhlX±®oei¼’¼nhzmpØ~Skb¶²~€q”uš¡ªVNXaOVNFU\XQPR‹\W[P@\DPNCFI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22BE/.32.+/)-/186- /416A1=:Wƒw11Tk\O[M^g\>L1Z[41!§”§ªŸ—ž¥­²©±Â½²µÀµ¸¿Â«¦´­­©¨°µª°¶´¨¨¦µ¥¨¹¯œ²²¶ª¥¤§²¯®±¦«ž§¤²¤¢¡ —œ¢ ²¯–Ÿ¤¡µº¢ª¨ ¬­¤¢›š£ª ˜›©¡Ÿ˜ž¨¨‘œ§›”ž¢§£¡°£žŸ£–—“˜’™…¯kj‹Žªh…–‡­fqŸž–›¨—q®¡¤~wº|l¡v±_j´[¥€eœ`fzfixj©e¾rg¦Œv±j|±xu‘”cmm§n\„ Eig‡–Euœ`}f{£¦‚Y_‹«h‘xzj¨8J¯[XTmcZLOX_\WV;NˆPWV/ISSJCEF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3/.53/+/(.0.:6/'$203B/=;U‚v2-Vj\OYL_gY:M5^X31’¢•ƒ­§¥Ÿ£¥«²¸­´½¾°·Å²¸»Ã§©°¬°©ª±¯¤±º°¥¥¯³£ª¹©ž³²°£¥¡ª­°¬¯¦¨Ÿ£¢±œ£™–™ž°©˜œ¢ µ³¡ª›¡¬¬Ÿžš— £ª™ž¥¡š¡¨¤£›˜¡ ¬Ÿ¥¦ š ¡–•‘—‘š†µ›µy†ªš¶™w‡³›·”—˜¬—k¦z…‡‘”’w«gj±[¬{Ž‡”tˆpŽ†€ˆ—xƒ‚Š—Œƒ …°vwŸqkkm|‹O¥XHcc™~ch¥_yquR’‡^P©ncq|†€a/R¢n[Tkg`LK\dX\ZB>°wWXA#MiFBDA@A19>88:84;:9<9:A:E::;6:CB8=?KNH:5:AFBAAD<FD;0201;F-0.840,.(/3,>831/2-D1<<S}n3+Xj\OXM_fW7J9aT50— ”‰³¦¦¡®©¨³¬ª»¶Â°¼Ã­¹·Â«­­¯¯§¯³ª¢¯¼«¢¨µ­£¬¶¥¥²³¨£¢§ª³©°¨¦ž  °– š––—› °£›š¤¨µ¯¡¨©§ª›–˜ ¦©šŸ£ œ £¥¤–›ž˜šž£«›¥šœš¢ –“‘““„Õ“™¹q±ÂƇ}֔œ»}œ—¨’¤{†¢¥‚z¬yV¯{‰~Ÿj¹Z¹w…„}¦‚”|™zªyŽ{±mŽ„t»†o•P¯§ÅŠQ zc`ªbsr‡l—‡_Rµ´È…‰|c¤3Bu\PjhdP@XfYdaJHMkJ[SOYfZCC?E?0<<59<74<;8=:<C:F:;>6:@C;6@OLH<:<DHCBCD<EF81211DB./0483+-).323971#%5*>3==Qwj6*Yi[J[P_fT7H:aP72%œ£“™±¨©¥³ª¥´§¤¼·Á°ºÀ²·µ½´¶¨²±¤²³¦ ¯¶©›¨º®£°²¡²´±¡¤žž¨©±©´©¥œžž¬—™™˜˜–™¢¬ž›—©®±©£žŽ¬¢§–˜œ¡§¢˜¢¡¢¡›¢£¨œŸ¡ž•™›§¡œ¦”››Ÿ ˜’•ˆ²nhµq«ˆpŽ§s´ut¶{œ™¦Ž£~ž£~°uƒ‘ÒÒu\®|…¤n›ª¦j†…}­}˜™{±s“y³e–t…žnŸf”RɋZÂ\Ÿyb_­_vs†b—ˆ^YʝoÀ€tMKµSUÆdUQjceXAOj_liPUFI9=WR[VYHB?J<2?;5=<56>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>II:1746@>/.24252-).26,742&60;5:=Pqh9'Wi\ANT_eP5G=aM62.£ž‘¥¯­¥©º¬¦µ¥§¶»¼²»¿¸·µ¼¼´¦µµ£²²£ ¬°¥˜§º®¤²±´¸ª ¥¡ª¥²¨¬ª¥š›©Ÿ–•™™“”¤ª¡˜“§«±¦¡–’¬Ÿ¥’”¡œ¥§ •›¦§¢›£ ®š¡žž–œ£Ÿœ¥”•™¢ž•™–’›…¬|x¨v£‹‡©p®‹„¨„šš£‹“š‹¢}’—‡®„‚³\r²S¯}‚‚£~q×}w„~†™šw¯†Š‘œˆw´ašeš‚•l’[°WKšu˜yf`­^vw‡g˜ˆj]¯w•Ÿxl5yÈ®³_CTo^g`EPl_pmVUM.echRYP;AD@L:5?91><16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK97<46:>/04333.2..18*.32%!03767=Pke>&Vg\@=V_cN6GB`I:77 ”Ÿ·±™³Á¬¨²§ª²º¸´¹¾¹¸³·¾¶¦¹µ¡µ­  ©¬ •§¶¬¨±±«­´¤›©  ¨¢µ§¦ª¤™ž•¥¢””œ™’•¤§›”§­°¥ ”˜©Ÿ¢‘¢š©¦¡•š¦©ž¤Ÿ­¡ Ž•ŸœŸ ˜˜œ–—¡ ”˜‘¦‡©~¦y¡„ªp­‚§†—¡¢Š˜—ˆ£†”ªz‹yp±Z¨ƒ‚ˆ xtØv‡t§Ž›’¤|•Ÿ„{²^œd }‚•n“\«\[“‘hgªcr{€j˜†q^«Z‰ kneOJC¡\ZMt]bfMZa_rt_JU6Jš‘XHE=GEAL35A8.;>05A78@<6=<F?:<6?=B7.HVJE@H6KIN@IK@EN::@4.;>002154+*05/7,&21($$6671<OedA&Uf[?1T_bL7FH_C1=7¢™˜¾­˜³Â®«­¨¦´°¸±µ¿¹º³²¹¼ª»¶¡²¥Ÿ¦§§Ÿ”ª±©°ª¶­ª¯¡˜¢ ¦¤¤º££¬¡—›‘£ ••žš”˜¡¡ŽŒ©°°¦–š§¦Ÿ’¤˜¨¬¨•˜©¨ŸŸ ¤®£¡ž¡Ž•¡™Ÿ ’œ—œ•¡•–«›®nr´t©Œw‹¦t´zu´‚”¦¤”‰¤‡Žu¸n‹{‹¢kk¶Z¡†e——h ¢§m”r´s“™³j…’ˆ­ju´af¢n†’k—\­`N¡|‡‘Rs£ly~n˜†p\¯V<œwfTon.[§ObRkeblZb\`p|cSZQ>?lo2BB@>M:!7@6.;@37C58??3;<CDBJFMIF62JTKEBJ6IJP?HOCFP=<E50;;010/75,+,326/#00,,289/9N`eD'UdY>/U^aL5FM^81A8¥š›œº£œ±¿®­««§·©¸¯µÁµ½²±»¸«Â·ª¬¡§¤¢’««§¶£³¨®ª¡—¨ ¥«¸£­œ–™¥£–Ž ›˜ž ‘“•«¶°¦™“›¬©—Œ”¦š¥­£‘—«²¤ ž¨¬°™¡£™¢— ›–›—¡“œ©”ª™‡Ô”š»u±Ä€Ä‡~֗œ¸yŠ’™Ž˜ŠŒ§‡y¢¶u}wv‚š²aƒºyÀ|u¸bµŒ‡©}–‚¬©q{u¼ˆ§ ia¦Ž¯¡~Œt‡«}¾ns¼t²ƒuxŠmšˆqm¤t½]w}[ay¼jZV[iy^iadfbmyoX[YCA@q?CG+4H"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,;:08LXaF'TcX</T^`K5<L\-6@9§šŸ¡»£˜±Ã¯­©ª¬±¨¹¯·Å±»³¯¼°®Á²­¦£Ÿ¤¢œœ‘ª¥ª²¤µ§­¤Ÿ–š«™§­¸£®™•¡¦ “Ž£ž˜Ÿš‘–“¯¹°«•—£§§”–¥¤­Ÿ‘ ¨«Ÿ›Ÿ©¤²ž£¥Ž§¢•¢šœ—•¤™° ’•ªŸ…™¶€’’¸–xƒ“›¶wnlotoy„Ž‰ržÁ»¼™z²¨p€t‘¹ƒ|††Š‡{Š†—}¤»¹½œuy³£tv—ut°u˜žf†i¶trqw¶Œ^y}‰gƒymyb‹¬pu…X[§iDdYTf_c]cQgfqmuBMOLD;ZL?J3<0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITBKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7KT_G'SbW8*O]]=+;VV'=:<¦¡¡¿§–³Â³«ª¨¬«ª»¯±Æ¯µ´°¸§µ¹®«¤¢§Ÿ ™”¬¤®ª¦¶¨¨Ÿœ–¡¤ž¬¥¾§¡ª—•œ‘¢›’¢¨¢“ž—’˜”²µ¶¬˜ž£¤¢‹“’¦œ¦«–©¥¦œ™ ¨§§£©¡’¬ž—¢ž—–˜ž°©”œ§¢kjœ©y‰t›v{f‡{¾¿Àºo’ƒq”…_rjZ]š‰ad‡Ž•k`”cmœvb”k€š•”e^`cqš‰hrŒ|†”fj~qty~}b[xthP\nƒ|{ŠjXlyrIJo…pNsMDV\f`LZWfc_OZmvjrRODEM<HI<L>2,2A?8/5?C<9;@;=C>RVVWYZ[[\]`aaa`\UG5CFUEJOHFPIIH;8=51:.1;:./-76=5&"/*2,%;8-7IR_I'S_V4)P^L(3>\O'?2>¨Ÿ¨¡Â¤š´¹¶£¬¦®§¨µ²¬È¬°´­¶¤¾±³§¡¤ª£œšš¬§®¤¥µª¤›˜•¢œ§­©¾¨©¥•”›– š“™¦©¨‘Ÿ˜œ°²¾¬›§§¢‰“’©›¨¤œœ¬Ÿ£šš¢§¬¢Ÿª¢š®›•¦ —•Ÿ˜±¥™¢¨™’Ÿ¤¦›¨¤›šœ›‘—‚hn}rw‘—”„‰´ª…˜•ŽŠŒ˜–‡”•‰ƒ““‰‘”™“™—šŸ¡š›”Ÿ›‚z¤…li{‘}€u‰‹‚r‚xyvuŠ€{‰js‚tƒudw}vkpzl_b[ogMXYfj_WYpzomfSOFR9PZNRO(+:KB635=@A9:C><ENSSTVWXZZ\]`bba_^^[TKCSGKNDGPLOI<:;489,2;820)6IRO8")+/2#4;*7FO[J'R^T10T^:+=8]K,<-@² ³¢¿¢£±±· ©¦³§¥°µªÉ«­²¦µ¦À¨´¡ž¥¦œ¥–– «§­£¤·¬ ™—– ˜­ª¦ÁŸ¬¤–’œ—Ÿ˜”•¢Ÿž£¨“‘™¨¨²Ã¯™«œªž––©ž«œž¡­˜¡›œ¡¥¯¦¡¤¨ž¬™—¦™š¡žž°¡¢§–™”š”¡£—¤ ™¡Ž—•‹‹Ž˜®|•›‚‘‰©¨†€—–Š„ŽŸˆ{„‘†…š‘‡†Š•Ž›—Ž˜ž£–™’œe¡³®„‰„w{Š~wyzogy€‰kuyˆrityuƒ‡jtcwe_hdcdfjXk{qjk\SLPD_UF@??,4@F;45;>A;<?>>HNNOPSTVVXZ\_aca_^^]^]XVJKLBIOMRJ;<:786/3964.(&$-1..)+*7%+<(6CMLD/T\Q05M[17E4\G5<,@³ ¹¯¿­«­±² ª¦²­¢¬³°Æ°«­¤³¯¼¤´œ ¨£¡ž™—¨¦©¦¤¦³µž••žšš°¦®¾¡¬¢‘‘žšš”’–¢œ—©…ª¬£´Ç³Ÿ©¤ª––˜š§ž©œ ¥«”ŸŸœŸª®¨¥£«¡¬›ŸŸ¡˜¤žœŸ°¤™Ÿ©”™™ž“¦›™ªŸœ—f„“}e›cyŒlhjz£«kd™—~g…Šeeihz¢ŽkhŒ—‘¢wkj‹™¢Ÿ˜slnz„Œ†yXe]…‚^l‹Š‚w\gsww‘€‡‚ox‚xsmy„swˆˆŽƒ{i…X]jsd]sˆik|qmc]QNWIdX@J3=F7?FD71<=?AC;;DGHHILNORRTW[^`aa`]]]]]_]ZUODHOKSN=>==6535554*&&%,*%.++'6*$;'/AI[J.6ZO6)EY/DO1YB;?.=¥Ÿº½º¯¬³°«¥¨­®°¦®®°½±ª¨¥®°°Ÿ­˜ ¤ž¢šš§¬œ¬£¦¨©³®ž–¤£°¦¶¹¥®£š¢š“’› ™™¦–{¥¬¢¨´Ã·¥¢§¯Ÿ•ž£ž£¤ª¨’Ÿ Ÿª¯©ª£ªž§›¦ž§ ¬–¡œ¥±¤—¬–¢Ÿ›”¦™ ¬™Ÿ~½„‰s´s…Ÿ†­hw¹Ä¸q’¡£{¦˜˜sª‚|ËÀÀºq‹£‡ƒž}–˜ˆžÀ½‚–œÁÁ|z‘ŒšÂÀ}k¥²ooÊz›w‘ƒŽ€wy€yq{€†px…‹“ylu‘be^wc_e€b^thmdbXKVIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^__a_^^^^___]\SMPGUNA@?=6468266*&%#)*&.+*)109*#>I[L*#CP/#F[3PY/UAB;/8–¢¹Ã´°¯¿©©”£¯©°¯­¦²¶¯ª¦§¦±« «˜›£ œ›ª§¢«¢¥¨¥¥´¤ž£“¦®¬¸´§¯¢’‘™¦“‘ ¡˜› žˆ¦«¤«­¿¿±¡©¯©–’Ÿž¢™£¤ª£“ ¡œ¬®¨«¦£¢¥Ÿ¤¥œ­©‘¤›©®ªœž«®£—˜¦—¢¤˜Δz{¥‚z–—›_­]Ž¨€¡¡}§•›t«ƒ€¯^dŒª{¨‡… t—“ˆ³c‚«† ³j„¯t|–‡¸a‚®Y£Ínv{Û{™q~ˆ’ue{ˆvvl~‡n}…‘}k€Œ_pjof`_xd[qhjcf`RTSW^JOC5AHED8>5;@?A;=8@>??BDDFIJLNPROS\^__^]]_``__][WOUJ=?><5578164('$!',&&/(&+360$7;SL+,-J0';\:L-!P@F4.1¬ÁÀ¿´´°·˜ž‘£ª©­µ¬¦²­¬¬¤¬¦°ª¡§œš¦˜œ¢¯Ÿ¡Ÿ¨§£¦¡Ÿ°¬›ž–¦®­°«¨¬ ”’›Ÿ¥“Ÿ¥—¨£ž­£ª°¨¿Å³¨©±®–“žœ¢—¡ªªŸ•¡žœ›­®¦©¨›¦¦£ ª’¬³–¥¢ªªž¤§§¢²¢“›§›¡›•”‘— q†Œ˜v…¨‡q±|q¬}  ¥žx«‚~­r­¬‡†Ÿv˜’{|—~ªˆ¡‹‘‹œ}«zˆ’Ÿz­VœÄ{p“Á}•mupŒmfwe†oawnrnˆŠƒlŽdmsuo`fmd_oijnfcWS\`ZRRC9II@C<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;91478452&# 1' 1''45-&7=WJ-<(=1)3V@F!G;C1-+¯ÓÆDz³Ÿ££¢¢­¯·¯©±§¨ª¨®««§¢¤š£–Ÿ¦« ¢¦ ¨¨£Ÿž°­˜›–¨§¯¬¨§©ž—•š¤¢’”¡­š§£¯¬¢¬µ©¹Ì±­¦®«–•œ¢™Ÿ®¬–¡™©±§©¨›ª¨£¡ª›¯±¢¨«®¦š§«««³¤“˜¤¦›•’…¤j¤uŠz©u{²q‚¥Š˜Œpˆ ›‡¤_aR«…€®ƒœu®‚¨††Ÿz™—†{f€£Š¤˜†£}©”†®^{¨U¢’z£Ÿ€|İŌs¯´³¹rb©¯ÂuhŒ‹—Žl˜nlxxwnkfddqqf{ic\V_iXXTLLQLCCAB;C@@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799664,&$" ''!+-"$.!3-&@DWH,G+56*1PKL# A9D4,'ÂÉÕÖÀ¡™«¨¡¯¢Ÿ°µ°°©­£¨§ª««¨¤¦ ›¥Ÿ¦§¦¤¬š¢¬¡£Ÿ¯£ž›“ª¤µ°® ©›œ–•§¤‘›¢¨Ÿ ¦œ°¥¢¨±¬¶Ç±µ©¬©•‘¢™ ¥´š¡”›ž§«©¢­š«¨¡¡©¢³­¢ª³²¢œ«©°°¸¥”—¤¨™’|ªlž„ˆv«y|°n‚¤‹‰Ÿ–•ž–Ò¸´¸É‚²_a”©ƒ¥ˆ‡ z˜–šyªÉtš£”§¨’šŒ~š‰šÆÆwe¡‚¥sŸŽ‚}¯^oµc±uK£†m§Gƒ“dŽœ‘{o•}nyt|zm[ejrqf€j^aXcm\^YILLJEDBA=A<A?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75785/)(%&%$&),5FNPPMFLJVF*L0/>-4NTQ;<F2,$¨¤Àƹ­©²®­¥¢³¹¬«¡¦›¨¦ª¬©¦ ¦¥˜ª£Ÿ®¬¦¡­šŸ©¥§µ £˜”¨«¶²¬›¦œ –¦­’šœ§£ ª§®¡£§©°³Á±²©­¨”‰˜¥›¢¤¯¦—¡•—›¥¥©™®œ«¦¤ž«£¶¬¡±¹°žœ°¨´´µ¦–™©¤›¡‚Nxš‚€Ÿz„£|‚¤„†¦ŸœŸ”„¸||z¹‚ÌÆöw›¢‘‹Ÿ~™——ŠvŸ—Š¤˜¤§~¯…›ƒž„¬}™”a¥l£p…}–„r¬`¤sq€ša¼}RUuŽ‘¢–{|‘Ž‡ryrƒ}p\lnwrj€nZc_hnbd]LLQSAHGFH::K>B108856877-*5==?BDGILNPTWYYZ[\__^]__\ZZZYUSOH@772.,*.+*'&?QTVWWWYXXWUOTF<E2:P[T6?G,- Œ‡™©¬¤«¹«¯ ›¢¬³µ¦Ÿ¡•¥¯®®¨§ž¥¥š¤§¡²®¢©§³ š©¤”£µ££•—¡©µ¹¤œ££“¢²™ž›¦¥¡¢¯­œ¤¨¢µ±Â°­ª­ª‘‡‘œ§£¤¥—ž˜˜˜¥£§˜­¡¬¢¤—¯¥»¬¢·¶®žž¶³º³µ©šŸ±¢¥Ÿ‡ÑµÃ·z‡Ž…‘“€¦x”¢wŒ¡’…¥ƒ‹r«‡†´nri™¤•ŠŸ}—™‡‡s®‚¥›¢Œ¦Š“œˆ”šmp²\¥s“zœl™{™~n©a¢rr~Ÿbs²¸hw“¤—}Š‹ˆv{xlhwixsn~t\ddmmeh`JZWX<HF?S3@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^``]Z[ZXURRQF:2230/++(@QRTUTSTVWWXXWUUVTQOQ[U%!2AH#)%’rŠ®¿¿¼»µž—¨¤®¶¢£™•£©§­©ª™¥¢Ÿ¦¡ µ§¢©§±¤”«£¤­¤ššª´´¤¦œ©’”—¯  ž¦£œ§œµ™ ª£µªÂ¯©«©¢Œ„œ¢¡¦£–ššœ˜š—¥£¥—©§¬ £›¬¦½¬•¾°­Ÿ£±´»­¶©«´¥©™{¨‘}|°x‹€¤¥ˆœm²o¡‡­|¢ƒ¨—š¬‰†­… ”¨ £—…Ÿ™–{’~«™–Šªw ˆ“’y¯]£|¦§dž€|—tk®]¥lr…™]`[Œ m”¥˜‚“‹“‰xy–~jl}b}tmy_gepngghBY_Z=JS2S8AAC7$$3+''3, /667436:@CFIKMNQSSSVZ]_a`aaa^][ZXSPONI8152.*,ATVVVTTUUUUTTUTSSVWWXVVUQHFIJ#((¼’›„©ÆöÁ´Ÿš­ ®¹¦£Žš££ ¯®©Ÿ£ž­™ž¹ £« ¯ªš®¡‘ª©¥–‰š­°¬§ ¨›­˜™­¢¡¥¡™¤œ­—Ÿ¨¥¶¨¾®¤©£ŸŒ€Ž›› ¦ž’”™š“™™¥£¢˜§ªª¡£ž©¨½¤—í«£¢¬³»­°©£µ±ª¬™v¯~Šœ…‡}º­‰˜d°Œe–­}¡ƒ§—œ‚­‹…°†§š¤¢¢‘… \lk‚³`­{{‚€±lfn™—‹ˆ±Z}´\¤ƒkÈ¢fŸ{»YvµZ²}S¯z¬X€¡m—Ž§™ˆ•Ž“”ywŒ›}cs|bƒxt€|ajfpmfeeOUc\AT^=H(>9=4!!,$2. *1/04579:<ACFHJLNPPRTWZ^```ab^_\[XUPMJGC553./@UYXWXWXXWWXWVWWWWXWWXYZZ[\XWWGB;ҟ³±·½»´Á³£œ­¦¥·© ‹™ Ÿ²±¨ž¢Ÿµ˜ ³¨ª«ž°­ž¬œ•®¨¢Žˆ›Ž¯¬©§£¨™®“š©š¡ž¥ž™£¢¥˜ž¢¨±¨»®¤¨ž}‹›–¡ ™‘š›’™—¨žŸ—§¬¥¤¤¢¤©ºŸ Æ§¦©¡¬µ·®°©¡¾°®®—©’£®Ž›€†¤—˜€€¸ÃºƒŽ“„¨™ƒ¬‹ƒ¯Š¨œ›¦«‘~սªb¤¿½}£‚ƒ×º·µ„”’‚ž½¾„j£o«„nz²±Çƒk«°½­yx¢¾»t€•¥š™Ž”šw™yb|zdŒgy{`kekjaPb[Si\@T`BL)<:4/$%2 $(0496678;>ADFGJKMNNQTW]a\__a^`[\YTQMHC><A?5=SYYXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ»•´´±¿º²½³¢®§¦³¦Œ—¥¿©¶¯§¡¿¦¦²›ž±¹¨Ÿ­¯¥§•”¯¬—Œƒš‘®¦£¬¡¥œª ˜Š£“¦ž§›š ¨¢˜ «¬©¸¬§£š—“{ˆ™’¦›“‘˜˜—“¨˜ž–¨§ž¨¦¡¢«ºž©Å£¡°¤«´µ«²¬£¾ª°°œtvª¤·…e‰Ÿpg¬Šnnw¥š v±›—q‘Žr—©¤›˜¯¤rlmmf‹xonƒ™q€zipig‰–•—qhi…†gp†d]ŠcioZ]g~x¦`br’pfd€’Ž¡–•—Ž“›z…“td†whŒjx~ydlcflbKeWJkY:PdDP'J9+# ",)-2.5:457:<?ABDEHKLMOQSV\WZ\`_a]][TPLHD=:AB7MXYZYYZYXXYXWWVWY]^^]\\\]^]^][[UW^¨•­´©º¹²³ª©¢®Ÿ¤³ª™’½±ÃǼ´©ž¿«¬£ §« º£¤­¬¬¦Ž–­ªŒ…•—­Ÿ¦ª¢Ÿ¤£ ‘‹¥’§™©™–£© –œ¥¥¦®¹ª¬™š“’{„—Ž¦—Ž‘‘˜”—”¦“–§¢™¯¦¢¬¹ °Â¨¥´§¬±²«¯®ª¼¦°¹—‹¡©¥µœ‰–¢˜†©›”’ª´™›£¬¢´˜¤¢Ÿ¢£¢¥¢–¬§Œ’“‡“•™“˜Ž•„¤š—•Ž‹“’Š†„~gŒtƒwt‡Œq§m}–“””ŽŽœ’ž”•“ž€…“‹phvoŠwv|yiledocUaX@iZGb`NX+E=+&!640/!%2(*799469;>?ABDFJKKMPPQWUVY^_ac]^TQJEC>9=@ASX[\YWXXXXXYXXZ[[\^__`^^^__```_YY`¥–©ª¤µ·®®¢°¥­ ¡·±‘ŽªÄ¼Ã¹¶©¡¤›¥°¨¤·§©´¥§‘˜¬£‹ˆ‰œ§–­¤¡š¨žž“•£—¨š©™”¦ £š§˜ ´¹§ª˜š|•Œ¡”‹•‘•’—¤Ž˜§ž›µ£¦«·¨¯Â¯¤¸§°¯±®«¬¶¼£±¾™’¦¤¦µ¢’¦ž©Ÿ’Ÿ¢­±š¡¤²«²š¦¢ž¥«ŸŸž—­ž“š¢œ”—«™˜˜––ž‘‡ ž””…“Œ•‹fˆuˆwz‰„tœjˆ’–•’‰}Œ–‘‘—‘Ÿš“‚†—…xq”ry‰q{~jnd_pi`\_YmbP`dOX9FFE=2<=8/*&+)&&406658:==?AACHJGJKLMSSSUZ``i`eVPJACB;9EMV[^^[Z\[[[\]]_^]^_`aabaaa`bbbdb\[c˜–¤¨£°³¬®£©§­ ¨µª›£²¹­ª«¡¢™zœ¢±¤¦±©–›¸¥¢”˜©œŽ†Š‰›¢¯ž¤–¨ ¡’—™›®‹ª–¨˜§Œ˜¨Ž¸µ£¥˜›‰y‚”Œ›“Š•‘“‘–¡‹œœ§ž·£ƒ¯µ£°°u¤¿¤² xz¢­µ¾—w®¥ Š€©~d\bvŸŽ¤žƒ–~m”´œ£¨¯¬¥f ¡”tz›˜p™ª™l€£©Šeœ¥œ‘—˜–‹’›„›”ƒ“‡ŽŽ’‰…xkˆv‡q|†ai‰Œ•“Œ[v•‘ghqy¡–•dx˜…€v—hƒ‰‚nyjpe_vokkg\ecaaoRY=MMNRF=@TB91/&4:306678<;>@ABFHBGGIKLTUUY]`hfgXQI<DG<9UR[`ab`^`_`aa_\]___aabcdabaaedchd^]fœ–¦£¡°±¬«ª¥©®¤§­¥’–ª´®°¥™©¥ª—s‹¯Ÿ¨«§”–¹Ÿ œ¤ž‘~ˆˆšž¬š¤•§¢žŽ—‘ž…u®ˆ¥š¨‘–£ˆ›¹³§ ˜˜‹‰uw“–“Š“‘”Œ“Ÿ™ž¥˜›²–€Œ›µ´’½§¡~§£{¥±ºƒŽ§Ÿ„‹…±©¯Œ‰–¢šy€‹¬†œž£©«©‰–‡™w¦œ{ˆœ˜§ƒ{³{Š† ˜™•˜–––ƒ™šbyˆ‘„Ž’‹„nqˆz‚q†€‡t‡…—“x–h“t št{™‚œš„˜~‘ˆ‚˜iŒŒ„kx{qpgdxnilj\diier[\HSLQ@E5-YTT6)!09=>643568;:=>>?DI@IEJKGRXZX[aaifYQH9DL<>bV^bded`aa`bb_]`aabbbcfgcba`edcgcaah˜¤Ÿ¦®®«¨­ ©±§§©¥™”­Å¼¯ ”¥§´ƒœ«œ¦¢ ¾ž™Ÿš¡‘}†˜—ˆ¬£–¡¡’”‰†€‘¨Ž‡¢œ£“–†ž¹±§š“…pu‰”Š”Ž›‹Ž‘•ž£”«‡Ÿ´‰´š®‹Êˆ«¯Š·…°„³±…©Ž§˜|¨r{wœŽ¦–h•¤y´Œ  ¨ª“™Â‚€«‰™¡rž€›¥}—…•³¡}¡“Ÿ˜—€Ž”œ‰˜’‹|…“†•“Š„nt’†€{s‡„}…u†ƒ˜Åf€©‡¢jž—€™€Š‹ƒˆ˜o’„gwt{vghupghk^cnlflXeF]QL2E46M`c7&3<EGD:63658;8>==>BL?NIJLCPZ]\Wb^jl\QE=KM@IdX]cfhgbbbbcc`_babcccdiicbbbecafcbbi•—£ °©©¨¦¬ ¥¹±©«¦š”ž¢¤©¡”£©µ¢¯ ¦œ¥ž‰”½š“ ’yƒ–•‘ˆ«™œ›š¢…Œw›œŽ ‘ˆž£›–˜—†¢¸¬¥™›bm‹“ŒŒ—‹‘ž’ž ˜ §~¡§‡­ –® ž‘‡‚ ­±ˆ¤Ž«šŒš~¢v€™”k«uM«x‡’œª©‚ª«~„¡|{§jž€“lg—†˜·‰ž~n`cXƒ—Œ{dg‹s™}y—l]|—n`Sq…\`mz„`Ye‚~…™q¨«kƒ£nr¥pŸ‚œgdžlZlˆzeY_‚~aWPovemtqjjo^jolkhWgN]XE9@4GD^k4+ICQMN=84859;6@;;>BO>QRKMBJ[]_W^_cu`ME:MNMTb\[ffiibbdaddbab`bdcabjkdbddgdbgeach˜—ž ¹¡ª¤¦¬’¢¶½«®¢™–Ÿ ¥««Ÿœ­´¡§‘ ŸŸ¦›™Ž™´™‹žŒ•‹u”‘Š¦––˜Ÿž~“…†¬¤‡œ‘Š˜¨˜™™‘‡¥¯¦¢•™ˆ‰€inˆ‡‹ŽŽ‰‹‘‹‘ ‹’Ÿ›¡¥“£¡” wœ–§ƒ£©€†¬¯‡¥z‹}„š}¢ps“‡•{žŒym‡œŒš’ªœ‡}ƒ¢tw¦gž~w¥^˜{}“s¢n˜·´ºs’ˆ€¶¨dÆ¸|p•¶Œq€›£ct¬«a~j³~n~ˆƒƒŒ˜q€£ls¤sž‚~£^œ™³–o{—ž³tr[ž²‚ibosuqioXkkrrd[g]aLD=D5QAZp2<RG_JR=<395::6C<;@IP?TNNQ@E_^[YX``{dIC8LWUVcaZffkkbbeadc`ab`dc_`cknccddhdbgfchh”–•£¹™«œ“ Ž¥¸µ­­ š¡›¢£¤¬šš±¬«’— ˜ ¤™š”ž¬›‹‰‘x‹…q€–Š¡“”—}‘‰Ž¨ ‡˜Š’¢“›šŒŠ¨§¤ž–‡„~k{‡~}ƒ‹‰Ž“ž•›Ÿœ Ÿ‹‰wœ˜¢ r¡Œ‰©‰¨‘˜ª­€®Œ}z ™y£“x€s—ˆŒœ}•Ÿ‡œŽš§ˆ£d¡~Š–›mžh›Žoš™{€Š§}rhtªƒ‚sªg”š]›…v…hªj¸f\©pœa•Œ_§vwŠŠ€hšu‡“’˜Žžm™j¦™\¨~w»j}©ZŽ„]³g[nqxwki[piwxa^eVaBPEO7VBRn4JZZ^NZD@151;;7H?:CHU?YSX]>Db]V`Qac|iEB9N[]XdfXffnmbbe_aa__``ec^bdoq`deekdcihgki–‰ª¶œ¨‰c•œ¬»²°«¥›š§Ÿ¬™°§ª–¢™¡Ÿ™–– £™†‰iˆ€r{—‡Œ––„’”˜zŠ„–¤‰•†‹‘œ›ˆ¨¡ŸšŒ‘Š€€i†y–Œ{ˆŽˆŽ•™~’¡ž ¢“˜rhŸŠ Œp’Œ‚©‰š¡¥ª£ª~°­¤¢¸—v£³¢£ˆ”xzª™¢ž˜‰˜r¡}‡°µ}lš‘¡x~™µ££«¨„™|š|œš~sªZ]o{—‹xžbM{{…dz˜BMŸY¢js|Žo‚Š„™v›y‡‰±³~š’¦t~mq|”o™ri£]•vHec`sp|}nf_lhu{bc_P]V\TV@YEQgERV\aX^ID=B8?A:HE8LEXAWRZVEFa\Z`K`m}qEC<U^bZejVghmobff^a`\]^`hb_edvl^egfldelhhki”±®š„S^¡§´º³³¨š¢‹š©››§’ «£ §žœš™•˜¡–‡‡‰w…ny•„›‹}‘“–ˆr€‰’¡›r’ˆ˜”Ÿš„Ž¨›™•‹ŠŠ|ƒl„…q¡Œx…ˆ‡‘—“{‘¢Ÿž£ˆ®†}µ„ž{¦–z©‚—ž‘Œ£ ~§hwm~™s sq|…˜o“‚­|£„§Ÿ›‚¤p^©hv£dp¦aœÓ|{™xrsc¢†~¢r¢uk³‹`‚˜Štª²¨¼wƒn¿¦ª´^œor—p‚s¢r^¤gt¦`h¦lšÓ˜z‚›nvy—k›yv—rl©¥g_dypƒlhfdmuwf_aRZePQaHWIT_WS[dj[dPECKLJKAJD8P@PMXSXOSQ`eeiSdxywIFEc]eZhiSihjocjf`c_\]]_hbahe|d^dgdkdjlfhlh˜›±¬T]K~©¯²µ°²£œ˜„—¦  ¢Œ¤§Ÿ—©‰™—˜“™“’ —Ž‡†{p}„h|ƒ“š‚w‘ŽŠp€†“’l˜”|ˆ‘’£•ƒŽ©š“’Š…‰y„vˆ€nŸ†w€’…‡˜ •y’¢£™ ‰³¡¢¶‹z¬§¤®¥p©€›‘†ž”}¤¢š†˜qž„¢­®‰—‹Œ¤•ƒ¯£•wµ¶¶É¢s”‹‚Ÿ`ž—©my–‡ ›u¡‡w ~–‹oLf£’q›ˆs¥{zubƒ‚m~ lrd`œst—k{j´¶´Æ¦s˜~zœjšš«tšlsw—i™yt—qPD}³^jvkx‡fkfbstpmU\RXgORhIULXRU\gknUgWMJAJMKHKNAQJPdcjmeuss~x{nu‰z{UQOm^h\kiRjhilgmgce_\\\_ibdhk{_]dgcjfnleime¢‰°¨…e@”¡³¬¯¯µ¢¢–§¢¡£‹¤¦œ›¦‚š—–—›’Žˆƒyky†eƒŒ—ŸyuˆŒ‚j……’„‹…zŒŠ•¥’‚—¨—Œ‘‹€‰z€}‹yp †y”†ˆ•ž”~“¥§œ––„gnxœl¢d|r¥xœ˜ph§‚™Ž}¥{¡—ƒ–rŸv€‰”•¹mŠ¢b}™£—‰nsk«ku mo¦`›i‹i–‡›•u¢~š`‹†uoˆbh¡fžj›updgˆ‚or¢[_[d¡n^‰Œq|€trd¥nx¢df§h—r‹—m¡oRˆn ^d§T‹]T˜mmrkqmphkxskoQVUUeYSmIXO\HXhhsjYkVQREV\MXSaUhj^wu{|p}|r‚{swŽ€„w^QsagbpgPkhhklohdg_]]]`jbjivu]\chcjirlfkmc¥™¦zetm‹§®¥ª°±¦Ÿ‹–ªœ¤‹¡¡š¡¡€•˜“š‹—ŽŠ|†q€ˆh‹Š|—šsu‰}|eƒ‡•Š‰•š‚|ˆ†–¦€¡«…ŠŠ}€€Žsi¥„}…“Œ‡—Ÿ†‘©¦‰¦x–œ~¥‰–Œ²™ž‘„¯—Ÿ¥y˜‰{©u§„šn¥¢Œ’„Œƒ¼m|¥¯‚‡†‡•—¢~¦{r¨” –hŸ~o¬c–Š–“x¨mª£‰uˆ‚w«‘¦ˆk’±lw³Œ©l‹†oo ž’•b«Œªw€Ž§ŸwŸ}…¤• hš‡u«fž­Œ¶sv¾Œ£“Yƒ¦«aurto{upbj~nglSUYU``\kL\R\I]lmv`[qX[_Zgsenoqcqt`wz~yryƒrƒ~{{‚€wbydcnsdRlggomrigia_^\ajbll{o\\bibmiwmglnb–¦«€ž¤–©ªž¨§®£™ˆ–©™£‰š¤œ¨„‹š…œ‘…’ŒŒt…zˆƒo…~—“su†r‘ƒn‹’‡†”}{‚…—¤¥¥€‰„”u‚‡“ol‹¨€‚‹“ˆ›žˆ‹’ª¢ €t”—ˆ~y”¯¤‚œq†y’†€{r¨q}}z—–›„x{}}ˆ”•“‹w‘™¡¢…|‰kŒ…\zyszqio~“Šq€t‚”“q†„‚e_Œxwt”upzoo‰o…†_wixŽg‚ƒ†ªœt}—j‰ˆo~u|ƒumlfŒsx{—w„ZjWyinwrqowxo]k…migVY^V\dkdUaU^Q_owykjwejjju|pqtsaoubs{xuy‚u€€y‹…‚~|n€mdyn^Wngiukxjiid\`ZcielqunZ[bkdlkymhloaŽ•º©§‹¡¢›¦¤™¤«¢ ƒƒ–ª‘ ‰™¦š¨˜ƒ›‹~–”‡ŽŠ‰Œr‚|Ž|~„{—Žtr„p•†|}’‹†††y~€†˜£Œ{§ Š…„•ƒ†Ž˜wq„ª…‘œ‡ž†Šš¨Ÿ ªƒ‰Ž•›~Š—­¨“¨‘xqŸ“„|”pª‡p}•qjo|Ÿ‹‘Ž‹hn]„œ s—Œˆqtkƒvt€Yro‡‘‚~Œj]id{…„ˆ€`ix{œ|ƒƒv‚‡„izŒ‰lbqsƒw_sƒŠ‘¨–‡gƒnw‹‚oƒ‹wmdecy‚z•Z[ifmv[{ywtmsrƒf\mŠkkbYX]YXkq[^`Y^]er~{sotcjji{|rzwtdmthl{uz}{yy€p†‰„{}s~zrhT\rilvpugkgd]aYjhkjqrmW[emlgryohjm`ŒŒ«±¡£¡šŸž˜ž™¨£¡}‚–«ŒŸ”‡š¡¤•{˜„|’™‰ˆ††Šr}€‹v…‹‚„–Šro€r˜‡„~“ƒƒ†Š‚z€„ŠšŸ‚¦ †xŽ—ˆ•‹‹œ—„ƒz¬—™“‰œ†‡¡ªŸ¡¢£‹ˆ“›£™–«¢¨§¡“œ‰™}z†©’‘’“œ±¥š”±’˜„¦–¡Š‘ƒ‰’Šl}Žwwfƒ†‘‹|‰ž…‡‹ˆˆ…„‘w|{u›¤Šˆ‹ Œ‡–€ƒwqu†…y‰ˆ‹‘§‘„‡ŽˆƒŒ‹z…‰‡uj€ƒ|y™iqh`sŠp}{wvowt]^o‡gn_^YZ\RgqUc[[alht{|rnpcjih{mx~phoplf€{r‚€w}„{mƒŒ†|zy|}zƒxNdvjsnq{ekebb`[sfpfrqlU]ltmhxzpgikeˆžºŸ–£¡˜•™˜”˜¤ {˜©Œ…ŸœŠ–|x”‚{Ž™‰†ƒ„‡mx€r€‡~ˆ“„mk~z—‡„ƒ~€†„‡|‡ƒ›‘†©žƒrŠ†’’‹œ‘|{©ƒ‘—•Ž›–……›¦Ÿ¢š†ƒ’š™™™¦¡¦žž—‚“Œx}‰…§|}‘…˜© œ“œŽ©’€ž‰”› „˜ˆ„py†rua„‡vŒ˜ƒ‚†„~†„•nzvu”¤ŒŽ†›††uŒ~~ss|‰…{y…”¨‡„‚ƒ‰‰ˆtƒ††‰zmj|{mhklg^y~g||vtvuzw\`p}mt`cZ[]PfmSeZ]ajhuz~pllcjjg€krkjtnwn„yn†€v‚€}…wrƒ‡~|{|€{‚‹`i{kvhiƒejc`i\cugobumkTbqyeoyzrejmm‹ŠŸ¸š¡¤Ÿ“’–—‹šŸžœzwœ¥›‰†¤“Š˜™yy…|‰‘ƒŒ‚‚‚l{xr€…}Š|kh}‚—‰ˆŽ|~†„‡}€››ˆ¦œp‹‹Œ’† ¡Š…Œ|§‡Ž‘–’•’wŒ£ ¡–šš™“š£¢¤›˜’œ€‡{…ˆ¢~|—¤  ’™¥Œœ‘‰”˜œ““ˆ‚vu‚qwa~Ž‡sŠ–}ˆŒqŒ~‚…†hxryš“‘€˜‰Œsƒ‰}}rz|Œ…{{’Ž„—¦”†‘|„…†„t€……xdqz~xypkjf^}sg|uvs|rj^`tvpwdcX]^RjhTeX^`givxqfkclgejm}gnpj}w…zk‹r~uv‚†|z€}jrƒntibˆilb_qVtoln`xhlWjtvctzzqbkoy‰Ÿ³’¥¦Ž˜†œ š›|u£Ÿ—Œ¡Šˆš–w{†‡~ƒ‰~ˆ‚p~ztu‚…~‰wgc}†—Š‚Šx}€ƒy–€•—••Ÿš}o‹‘“…¥›‡Œ‰ƒ¦•„‘Š•—’‘v‘¡¡˜”˜zŽ˜——š¥žš”•{’ˆ…y‡—ŽŸ‚ŠŽs—¢ ’˜Ž¡ŒŒƒ—˜ƒ“–š™Ž}ŠŽ‚wr~n{d€|‹†q‡“€‘‚k‡ƒ€Š…fvo}ˆ”šŽ~”y‹}‚‰~|r€y‹†z…’‹Œ™£—ƒ„Œw‡ƒ‚uz†ƒs^ww|s}wfkc`~ijvssu}q|ccasnurmaY_]ZkdRbW_`hkty†qbjclfh|‚khthloh|yl…q€ƒƒt|ƒ€~z‚ƒ~|mu‰ttmfŠljbcuVƒipm`yglajvpex{yp_ql……¯˜§©žŽ—‡…Ÿ“•—|w¨›‰˜y–œ‹Œ™x{€‹}|ƒ{€‚xsxys}€ƒˆŠ€d^}‹•ˆ~…‡t}Š~˜„–“–Œ£ —~r‡{“‘Š¦ŒŽŠ’ ‘ƒ“—Š˜ š’’t€Ž’”Šž§™˜Ž•˜u‘‹m‡™›{ˆ‰‰o—™¢“•ŠŒ‹†“““–ˆšŠ|‹Š‚zrzkvm|Œn…“ƒ”xo‚„~~‹esj}‚˜˜…€Žt’Š…z‰wy~‡}„Ž†•¥‘y…‚tˆ†|qs~…l`ztyp{nanbd{amovrwwssav`oluno\Z^]]j]O\Wbahmsz‰k_iejchw‡mflhilg€|zwnˆs€ƒ„}t†‰zƒ}z„}|Žry‹yxnl‡kh_irb‡hqofvgmlazhj|{wpawm‹™š«¡¤©žŠ‹‘†‰žŠ”–|v¬—Œ–|ž“‘–”ˆv}{Š|{€vw€otszo…}€‰~|a\~‘†„„sz€†z‘‡‘‘›’¤›“}|Š’£‰Š–šŒ…—’•Ž‰ˆŒ’“Œn„Ž‘‰ž™¢¡˜—Š—“p‹›†gˆš”zŠ…‘‹p–š“¡‘’‡‰˜Œ‚’Ÿ}’“Œ™|‹†ˆtsvkqov}‹uo†‘Ž“rt€|‚‚‰}eqmz›•~…‰t’Œ‚uŠ{p‚‚ˆ}…Š†Ž–ªŽ{ˆ}~Š…w}om~ƒbgwstnza^o`jt^pjzyxlrpey]mlsmsXZ]_ajZOWWdcfqq‡e]ihgbgqnchheig€zwuoŽ…sƒ|u‚‰…x…|x„†z€‰w‹{{syƒjk_phtkqomqgoke{bnzwpkww‰£™£¨¡§›ˆŒŠ†’št€©”‘† Œ•“€s{v…wxrs{…kroym‰v€†nq[Y~’ˆ€vu †Š‘œ— “–w‰~€ŒˆœŠ†’—–…ˆ”˜Ž–Œ‹ŽŒŠŽ‘„nŠ‹‘Šœ–¡œ™–†™‰l‡¥…hˆžŠ’Œ„Œx“˜‘‘‡ˆ”~™|‘Žš’}‹„pvplnoq|‡jsƒ™Šqx€u‚‰ƒzgsov‚›}‰…z•“{xŠuq‹|‡Ž{‹‡…Šœ¥‰|„wŠwwli~€\qrqoowY^o`oj^oj|zpmmjmw`pokqmYX`aamWPSYefbuo„‚b]kmdcfk’m`ff_gjurro‹€t‚€yv€‹€y…~w‡†vƒ…{‡Œ€{wŠjqb|b…|oplujhnlvw_q~y{tus‚~¥–›­Ÿ§–…Œƒ~—•ƒŽtŠŸ“’…ŠšŒ•ŽŒzrwt‚pr…squˆlnltl‡vƒ}mnUQ«”‡‚x€vrƒy‚ ‚‘’‘—›‘™w‘z‚Œ’¤š“Žˆ”˜’„…–˜‹“‹‰Ž‡„‘‹}s‹…ˆˆœ™Ÿ›—••€jˆŸ‰hˆ¡ˆ“…’„Šqƒ‘—š‹ŠŽw{“‘{Ž‹’—|‰}lwjollm{bz~–wzxƒ}zhumuˆ—Œ€‰†|•‘r{†qxŽ{‹Ž{‰~„Ž‘ŸŸ†}}xŠ|vogj€w^womkprU]naqa_lnypgpfgtuhqlawe]Ue``qRPN[ed]xoˆ{^\hqbbee‘i_he[go}okqsŠ}v}…€uvŒy{†€x‡ƒs†…~ŒŒ„|z•xgqjƒ`‡~ook{`imtt_t|x†xss…|y¡š±¦Ž‚Š‚™‰Šœ~Š˜’Ž„ˆ—ŽŽŽ„wtvs€po…spqƒojium‚n}|musRN‚ßɒ֓|ptƒuƒŸ‚‘v”˜›˜{“r…Ÿ¡““‰’›“…}••‡Œ‡’ˆœŽx{ŒˆŒŠœœœ›–”zŽxi‹”ŠnŠ¥†”‰—ƒ†cŒ‘˜”‰–‹Œ‰‹pz•‰|Ž‰‹”’Šz†}m|espkm{z\yŽ{~€†{ziuktŒŠƒ‡†~—m€p‚Ž€Ž‰~„{ƒ‘–››Œ}wx‚xrlen}jitoghslS]odpZ_lrwfkkcgxsopc_w`aUk_^uONK`fb\xpŠt\[ev`addŽc`fbXissmkqv‹|ty†‚vw~‹s†z‰q‰‡‘Šˆ}~™vesn|e‡nok€Zknyyr`vz{vrvŠvzŸŒœ¯› ‚…xˆ”~{ˆœ‡„žŽ…Œ—„“Ž‡uwpypn„omn~rcdxp|nz|jhlb¤šÁÜ®ï¢sluƒu„¡„‘n•”Ÿ“š€‘p…‹£—‰Ž•Š•ƒ€”…ˆ€’ŠŠ—~‡{v‰x†…Ž››—™v‹xp‰‹¦†“‹…†^‹”—‰ŽˆŠŠ„‰l|—‚}ˆ†Š’†v†~~l}dxujoztXˆz‘‡†z€†zftk‹‹„„˜†mƒwo‰“ƒ’…‚{‘—”›‘utx‡Œtrpesw€`smoahtfR`pgkU_ntyasc`i}qrn[cracVnZ\wMMLcfa]vsŠm[\dx^`df„_cc^Xirknkrw‹}sw„xx|‰qƒ„}}ˆ{t‹ˆˆ•†Œ˜shuqyl‹{ntp€Wpyvyqdvy†Œhv€‰q€ˆ™¨œ¢’„|pŒ”wx‰œƒ„ŸŽ|•Œšˆ„|swpsjokil|t^`xv{ptzg`e|ëÚµÉÃ܉slt€vŠšˆŒi—Ž›“‘ˆp…ˆ Ž…‹•ŠŒ—“|’ˆ‚ˆz‘‹†‚€wxƒ„r‡‚“›–”˜†vˆ€r‡„‹‰œ¤…–ŽŸ„‰aƒ•…ˆ…ˆŒ†€‡h}”}‚…ŠŽ‚r‡€rwhvritxmZŒ}’‚†}€ƒ„‹ƒvbumŠ‚‘Œƒ€€“’~oƒmzˆ‘ˆ”…}‚~“”‘˜ŠorzŒ…tkoipv~]shn\it_QdqhfS_pvt`p`]h‚qrjWgiciWmW[tLJLef^ars…i[\ey^^dgz`d_]YknenjtwŠ~sr{vzˆt…ƒ|‡vvŠ…˜‚{“vlwvyy“unwz}Xy…q€ngxv‘‚dv†…qŠ–†š¡›¡Š†so’‹qvš}‰™ˆ‰{Ÿƒ™‚yqtnodr~hflww[_xzzqqiagaÕ¶Ž‘¦xnqw{q’Œ†j˜ˆšŠ…zh‡‹™†’‘††—{ŒŒ€€‰{~‰…zu{ƒ|q†€•™Ž“”‚‰v„ˆx…‚•Ÿ¡ˆ—‘ ˆa“‡ƒ‡ƒˆŒ‚f}‘€~ƒŒ‘mƒ}ƒulmwutwvlcŽ…|„€…‰€q`tr†}Žƒ}€’Šzr…g{…Œˆ…|…•’”…opy‹tlmiiwzagjiXktYRhribPbrxlbe^Zjƒnsb\g_em_oTZoNHNfd\fnr€kZ[cs_\ckvde]]Zllbmjsv†€qo|}tx†x…ƒ|€ˆvx‰’•{‰†v‰oxy{ƒ’om{€v^ƒtmhzs”sgs‡|r’’„šŸ›Ÿ†‡uu”~mu’–}‡ƒŠ™|Œšv~vqoljat|gbiuzZ`w{ymq~edhhW_rs—¼Ä„vq”ˆ}q–‹†›’‹‡rjˆ–€{•Œ„šŒ|Š…|{‰‹”ˆu‰†vw~ru†ž”…”„„rŠw‡~‹›Ÿšˆ•‰f}“‚~„‚ˆ‰q}f~Œ|y‡Œ}i~„vgpyxswtlkŽ…ŠŠ€y‚…„l_sy{~Ž‹†|‚s‚jz…‰‡…y„}‚™Ž‘~nm{‰}vtnfe{tb[pbWnqSSmrhaNftxf`^]Yo€osYeb]jn`pOYkQDSg`Zjnm|nY[]mcZbpvcf\]`kicljsvƒpm~|€tuƒzƒ‚|…v~ˆ–x„Štˆryy~oo{€qixz~ml{u•kjx„tk“†Ÿ™ ™„ˆn}Œviw—Ž~Š‚”—‰y•oztqlid`szh_eqzZar|ygqy`ee±²wKbZ¥ÙЖq{Šw}“Š„˜‹…nk…’‘zy’‡„˜Š|†xw‰Š„–€o‹ˆqu~{jy…ƒ¥„“„p€„x†{ˆ›–•‘•…ˆp{’‚|‚ˆƒn€wh€„xr€ƒŠˆ|e~„vdqs€iyqou™†ƒ‹}wy…zƒk\rs‚‰‡Š~‡Š{‰s‚or…ˆ††s…z‚šŽ…yno~„vzdfh{o^XvZXpkNWqrf`Klwta^\[Zu}roWg]fjq`oNWhR?Xf^Zokgzq[ZXkeZcpy^g\^elgekiqwˆol~€uo‚{€‚‚v…ˆ—‰q‚q{†|zy„“Œujy~ko~t}or{z“on~xg’‹ƒ¡™œ‘‚…f†ƒogy•ˆ}~„‚˜‰|Žixskkf_aoym_box\dk‚zaqv_eeÔ꽋2:>‹Žqx…‡u‚–Œ~’Œ~ml…ŒŒu|…•ˆ|‚xnv‡„ƒ—wnˆ…lu{ufy‚ƒ§‹‚‹„~nvy†|ˆŸ’‘“”Ž‹‡{’†w~ƒŒ‚krh€~xm||‚‹ƒxbz…‚rdri~nuqu‚›‹€…€sv~s‚p\nuy‹„‹{ˆ~‰y{rm‰„‘…Œsƒz€—ŒŒ€unkv€€us[ggunWV{RYodLZrre[Ipxo\[[Y]t~thYb[geodjMWfQ=]e\]ue`upZYUncYdqyZh]_gmgikipw}Žmi‚„~yn€|}‚yt“„p‹nw~€{{ˆ’‰hz}js{r…zsv}~Œzx„}|kŒ„›ž–Œ€l}kh~‹z~~ƒ“‚~}Šˆkvrghb[bgso_aks`hpˆybst^cd› n\5Z¯µti€ˆ|’†u…•…sŽŠ‰vol…ƒ‡uy‰x‰|“‡y~rgu‰~~˜oq†~hvynfy‡„¤‡€‡Š~o€w‚ƒŽ›ˆƒ•’™Š‹…‰|ˆpz}„{h~lj€{zjzw‚ˆr`w~rdrgv‚mu{†•‘|‚owz|umYp€wuƒ‡xˆvƒ‰{yto‹‘‚†s€~”‰Š{onjmtm\fdrpPZzM[n[O[rodUKsxiWYYZap€t`]]agdiifNYhM@`c[`ua]ulXWStaZdorWj^bhjgmlhpw|“lh„Š||p~~{€zvŠ‹ƒq|‡oqwƒ{‰Œƒj}{mwxvŠv|x‚‡ƒ~}zm…Œˆ™£„ƒ{u‹xkl„‡x~{‚‘€€~‹ƒpsqcf^Yf_oo_`gpfjnˆtato[adjv{€¿œ¦¤È¸q„‚r’|w†’‚s‹‡rroƒ{ƒtt‡tˆw”ˆyypcw‡z€“ir„vgwucj|‚ˆ€Ž~s€u‡{‚“‘„z—–ˆ‚‰{ˆˆkxy~tgzhkysizv€ƒ}h`xˆ}kkth|€ivŒ‘”~zq|v|tbVx~ss‹…‚}„q‡Šxyqq„ƒŽ€z~w†„wjqil‡qo\faqmIduK]lTSYrnbQOtxaRXX]ap‚s[a\ieedkdP[pIDc`[cp^]whUWVv][enhVk^aigennhpvz“miˆx}r{~y‚{u|ƒˆ†ƒpw„rmw‚‚~‰‹“p€{wyzŒt‚x~‚„y€uo~Š‹›žˆ}…zw…{gt…‹y~{ˆ†„v€gpn_d\XeYmra``plkhˆnatiY^dn€w©Ú©Ç†‡²qˆwoŒt{…z’‰tst~w€pqm„t”…xuk`z‚y‰fq„pgvn[m}€“€y‘“~y|nŠw‚“…u—‹’‡……{„ltv~lgvdm{vmiww|abx†ziuuc~{gu†Ž•{twq€{}n€ZWupv…ˆ€zm‰†tzlv„…|~z}t‹~thten‹ƒlsYh^sdGmmKZ`WVUwmbPRtvXPVX^aq„o\`cmed^ocT\rGBf_]fg][{bQV\t[[gkaVj_`nefkpgpvxŽtkŽu~vx~w„{s}ƒˆ‡ƒor€tqu~…‚‰Š{wxƒ{|†‡w‡|}~„€{~ruyŒ Œ‰y‰utƒx^}…—‹x†ƒs…†„w‰{bnm\b[[aVisc`[gnpf‡qaqfW]ck|Ê·¹¡jmmŠlqƒq|ƒ‰~z„yxsyuu{jlvc„u’‚vof^}‚z‹Šer‚kjqcXmz…›ˆ‚s—”x}oŠr„‹‰s˜‘‰†‹ƒ{y}ppo|fhqbmxqjkqx}}z]ez€xjvxfƒwgt‡ŒŽ”}rˆjo~yo}]Ysnu‹|‚opŠ€qwix€‚€‚x~s|u‡}{sgsan‹kqWi]v[GmjLVU]SU{kaOTurPQTW^bt…i]`ljfcZoaXbpHAg\`e^\V{^NUepY[jh]Wh`^rekgpgqsw†xn•‹tzx~yƒˆur†…Žƒpp{xwvy††‡Œ†z|t‹~}†„ƒ‡~~~}‡|xuxx‘“ŸŒ|Šmuxdƒ†•…s‘Šo……zƒtdnjY_[\]Tgrd`Ydqrg€rbkeW[`jw¾®{ ¶nas…hs{qx„z}‹~wwrvo{vejoa‡uŽ€sjb^xy‹„fqhkkZVow‰£…q™“rzw„o‚ƒ“‰t–ŠŽˆ…‰…}xtqnhy_jl`mvjgjkywzvZg}|yfs~m…teu…†–pŒgk{„unub]q}lu}Œ{‚gv‡~nqivy€s~m{|‚{yqflbn‰}lmVi_vUJijNQNgLX{haNUukLQTU_fuƒf^`qhgbWj]\khJDjYadVYUyYMVmjY]kd\Yec^temdpfrpuxq™†v~w|…‡}us‚ˆ€•‚nsy{zss…‡‰‰ƒx}u~|„Šƒ„{~‹ƒ{v{wwš˜z‰‚†iv}{lƒƒ’rŽp…‚‚pglgX][\[Sdpd^WbrujuoeebW\\hpor€s‰ddy}isusrƒw€ƒxvrunkzqbgkg†tƒnf]_}p{‰imygjdUWro¦|„{v–‘u}t~|o}|’‡xš}ˆ‡ƒ†ƒ}uoqlgt\lg^ltdgeizo{rYhwuhpx‚vbw…‹|”oŒkm{‚qgtfanzgsx‹|~cw„wjlrv{q{ztg€ywodfbn…{ljUhaoRJhjOKNoG]zfaMUtdJOSWajv~e]gsif`VdWbp]LKjXcaUTUsVLXudY^k`\Zce_vgmboitor~ttš‚w€w€†„z}u‚„~—…nrt|zuq„…€z‹ut|•€…„}}Œ†z}€v{£¥Šyˆ…„ku|zuƒ‹zn„sy„}‚ƒvojieV][ZZSbmd[Xas{jhmi`bW_[j€jko€gk`hyxjrssmƒ€z|utmzhjyj_enhv„heXbwj~‡{ojpgf]TXogŽ¨wz|Žzvq€qtwzy–u†ƒ€…ˆvjquggn[lc]mr_gajxh{l[nƒstjp~zwaw……y†tˆroy€rcqi]qxert‰|yct€qhjzurmyxvyd„|ywqddcn||jjThaeSJkgOGQjE`wfaMSr]JMTZekvze^mqid]VaUnnWKShWf^XMUlTJ\y_[^k]]Zce`yhl`oovnpwuz˜~wy€€‡†zyzƒ~“„qttyvt…ˆ‘}€|ks•{‚Ÿ†~‡}€~†‚€Š{v„«Ÿz‡‡ƒkryu€~tn†n|€sŠ€jpnddX_ZYZTajg[Z_u‚i^ml\aW\\lert}ii\kvugsvql„{}|xurlygixf]eshzw“ccTeph‚…xxgijaWVYgc§n~w€‹Ž{qrizp{Ž}xr„~†ndurdgg\ja\oo\g_mtezh]t€orkr|~uvbt…‹|‰ˆ€xruuapm[rtcqs…|ues€mam{pkj{yvsf†v{{vqebemr}ikSg^\TKqbPFU`GbvfaKToXJMXXgkuzdenqfdZW^XweTJ\bWhXYHWePHbxZ]_lZ^\ac^~ij_ntxmpnvƒ—zr€|‰Œ†}uu†y‡Œ|tuu‚yzz‚ŒŽ}~„‰is–zŠ~~…zz|†ˆsq­Œ{{†}dq‡ys|zuro†l{~lzcpobe]eVYYWcfk_]]s…hXqn[^XZ\l{cpwulbYlssgtuolƒx~xvmntdite[gufvv’y_]Rffkƒ‚t~bdj\TW]bc¤hxtƒ†‘ynq|izn|†|vŠsy|xhdvl`f_^i^\skYe]oobze\w|knnpxytudsƒ’ˆ„‰{wor~sbxd\qqbqr‚}tgr€e^nwiehz|uno‚ut}trb_fnn|dhSgXXTMv_PJYWHbtcaITmSJMZWilq{bmlscbZZ[aw\SLc]XiSWGY`MGiuX^`l[[_bb\„iganxymojvymƒ€“ˆ„vtˆtŒ†trvu‚w|}~Œ€~“~pw–ƒ|™“y€€xz~€tˆƒtp™¡zz‰”wcu‡xswtkto~kx|p‘s^pn`gblTZZWhcmf[\q‰eSrn[ZXX`lvciuji^Ymsplsssi„|~~{vnnldiqc[krduvŽs[WSear€r‚]bc]SZ`\c‘Ÿeqq…„’ull{opq{}}sw€szzzdeuh]bY`gZ^vhWb]phawa[|vijroxtsuhq‚•ƒ‡…vsjq}nfwX]lncrtztgp~[`prb`kr~mmusrxkqa\elmz`fReTWQPu[QOXQHcsa`GVkQIPZUkkk|fnoqb[ZXYlqWRPfWVhSTFZ\NHqtX_clbX``a]‹jcdmyxlpiuy‡{kƒ}„š|ƒ„y|‡n‡rovz}t‚‚|‹ƒ‚—tx‚”…Ÿ‰u€t‚q‡‚uo¡–s{†‹†zewŠnmznfxpzksvsk^unagekR][UgalkZ\qŒdOon]VXUgjthbted\Xmtmoutxj†|{‡vscdkna\nmcsx‡kZTVcdx}}q†]d_cTZ_Yb••cnpƒ…Štki|pftxu}mzuvpzv_erc[]VacXateU_`mdaq]]~phitqtquvkm„“‰|†qsgp~qsoT\gkfruwtcmvVbrl[_pg~fmw~stsknaZdjjw^eScTUPTlVPVRPGdr_aFXiOIXTVmhd|ikxkbW]U[tdSRWhQXfTSHZZPMwvZ_ekiYa`^^Žnafkyunoivv€lƒ€}‡˜{€‡‰~k“ˆrgt€{u€ƒ}‰‹“r|Š‘…‡Ÿ‡{†Œt†s}‚vn¤‹r‹vwlzŒ`d{pfysxlmqwƒgd|mcfghS_^Ug_ln[^nhNim`TVSngtkexdd\Xoslqzwrl‡{v›zykaelm^`ojeqy~gZVX`lx|{p„_c_gVX_Wc›ˆbkp‡}xllzn\wsm{jvtop|€sXim^X\UabWdpcS^biablZa~lfltvomwwli…Œ‰|‰mrgq}nsnc[aiipt‚ts^imSeqeUcoc{drw|wlpmk`Yafgt\dU`URNWdRO[NOHdo\bGYiMJ_KXmd`xin~d`U_T]u\TS`fN]aUSJ\YPYtu]_ekhXba[^qcgjxqsnhvtz„r‚ƒzˆŽ~|‰‡ynŠuls‚tˆ…‡‘„•y}Œ‡‘›…€|Œ…s€stxro““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~}~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’’’’’’’’’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’’“““’““’’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ‘mfggggg}…„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDARÌÚØØØØÚ°    ¥^*///0,H…ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‘g_```_^yƒ‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR455552FØêçççç鶠£¤¤¤ªV:ƒ€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}z{z|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‘ŽŒ‡‡‡‡‡†‰““’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ…†…………†“””””””ˆ‚ƒƒ‚‚‚…ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|yzz{|{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘’’’’’‘’‘‰‡ŽŠ’’“‹Š‰‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽ‹Š‹‹‹ŒŒŒŒŒŒŒŒŒŽŽŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…‡ˆ…‰Š†ˆŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰„‰††‡…‡ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰Œ‰‘‰‚‡Žˆ„…ˆŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}|}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹ŒŽˆ†‡†ˆ„ŠŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz||||}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒŽŒŠŠŽŠŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzzz{}|{{}~~~~~~~€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{y{}|{~~~}~~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}}~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}}}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†…………………„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰ŽŠ‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}~€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††……………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx|{{}~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““””””“””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••””•“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””’’“““““’’“”““““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘’’““’““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’‘‘‘‘’’“’“’‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡ƒ‹Šˆ‰‰†……„„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxy}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzop{xy{|{xw{xuwttvutvwuqrqnprpghklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkigfgggihgmgjghehgccbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__`c_\_]`]^Z^]YY^ba^^ZY_\XWSNMLKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{xvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSSPMJMNPROMPQQQQRVVQQQTPPNNOLJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTttuxzzxvvwwz{|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMOPPRQPNNONONOOPQONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKLFDFJKKKHJLLLOMLLNOOOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEBA@@CCDEACEHKOKIIJHGJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:<>><ED=?EA?@A@DEGGGGBDDEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;899;;:@;;><;;<<HL==AA?BC=ADDFBFFDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnpprttsqrvyy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;::;89:87:<978;;>=;;:8:@@AB?A?CFDBCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqususqsxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<979::988::78:9:;;8789;:8<;=@A@=;;><==@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyy{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>=;<<>?=<=;:<===<<<<;;:;<>=>??A@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquuuusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCC@><=?@??=;>=>CE??@=;===<;:=>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVpoqssttuy{{{}~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???CED?=;<@>:;::97:<9==@=:<;;<;89;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pprrrtuvz{}}}~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC??AAABA@=<=;>=:::<:8988:;=??<;;<;::;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFEHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvvw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC@???@=?@><>@?===?>=>CD?;<=>@==>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hloppqtuvy||}||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABECDA?@@@?=@><=??@@@C@@?@@>=<=@EABBFHC=<@DCAA?>=@A>>>?<>@DGE@>@A?@CFECBBC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{||}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@A@>;><?=<:>=?BBE@?@Na_J@CEIIIIMMKECFGHEGEEEDDCA?@>>BFJJGEEFFFJNMKJIGGHKLJGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@DED?<ACDB?=A?ADEECWu†‰Š~XGIJLLNOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHIHGFEFFFDFHGEEHHFHGHFQnopqrvvy{{{z}}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJHIGHHIGGBDFDDCAVt‡‰‡‡†ˆ‚WILMLMMLJGGGGDGGGGFHFHECDDFEDDHHCCCGJJKLLLKLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrtwwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLKJKMJKIHFFGFEPl„‡†††‡‡ˆ‡|PKLKHGFFDECC@ACCCCFFEB@>>@AA@BD???DFHDEGIKIIGHIGIIJJIHFJJJJIJIJJJFILLJJKKfopsstvxy{{{||}}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKKKKKMLKMMIFJVl†…„…†††‡ˆ†ŠuIIFB??@???<<<>::<AA@><998<<=;>;9;?ABAACCC@ABEDACFHIHHHKMLGIJMMNMJJKKJLMSloqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHGIIKLONNQNQ^r…ƒ„……†‡ˆˆˆ‰‰ŒŽfBB>88::9878896479;<:8567789787689;;<>A;999==>;;=ACEHJMLLGIHORQPPNLMMOQ]oprtsuxz{{||~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56;<C@BFHKHLKOUg{„„ƒ‚ƒ„†‰Š‹‹‹Š‰Š‹Œ‰T;8656766655763468:876565677778:7778:;7689989876:<@GFIFIFEFOSRSSROPPRTepqsttwy{|{|}~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:<DBDFFEfzƒ„‚‚ƒ‚…‰ŠŠ‰‰ŠŠŠŠ‹‰‰ŠH676468874578467799766765:::::<89899877::98878589;A=>>BA?AKLOQPQOOPQWkrrttuwz{{{}}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897:A9<D@Qƒƒƒ„„„†‰ŠŠˆ‡ˆˆˆŠŠŒŠ‰‰Œz>:88;<=>9:;<89;9:;:99;:9===?;;;=:><:<;<;<;9:<8::;:999<?<=ABDIJMKJKLWortutvx{{{|{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<:89989999:>=?@Dvƒƒ„„…†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>BCEEAAAB>@CA@?=>>@?>?@?@==?B?AA?A?=@A@??A<><;:;:9;?=;;==AACABCAXpqtttvy{{|}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::<<:;;<;=>A@>b…ƒ„ƒ…„†‰‰ˆ‡†††‡ˆ‰Š‹‹‹ŠŠ‹Š‹^>DGIKJIFGGDFHGEC@@CECB@BCB?@DHECEDFEAFEFDFFD@B?=@>=?@>???>?>>:;=<`qrttuwzzz}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:=:<;>>>?;?=@?C?J~ƒ„…†††ˆ‰ˆˆ‡†††‡‰ŠŠ‹ŒŒŒ‹ŠŠ‡WGLLMKNIIKHIJJIECDFGFDCEFDBHILGGGFHGEKJLIKKJCFCCDBAACBDCCDDCA=<>@hpsttvwzx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLK@BBA97<>;<:>?>@=??BBE?h„‚……‡‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹‹ŠŒPMPMKNKJLIIJHKFDGHHIEEHFFELLMIJGGHIJNMOMLNKHFGGEECFFFFDEHHFCA?@Lmptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?FGG=<@@87<:;<:>?=>>@ADCIS~ƒ„„…††‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒ‹ŠqMQOMLLLLJIHFJIDJHGKJHJGGGKMNLLHHIJMPNONMOKIGIJHIDIHHFFGGIGCBACUoqvvxz{xxzz||~~~~~}~}~~~~~€€€€€€€€€€€€€TDAABGHB?8?@8:;7<=:<?<=>@BDDMm„ƒ„„……†‡ˆˆˆˆˆ‡†ˆˆˆˆˆ‰ŒŒ‹ŒŒŒ‹‹‹‹^RRPMNMKJGGCHJGLJFKOLKJJMMLOPNHIKLOQQPQOOJIJJLJLFGHGFGIFEEB@BB\prwxyzyyyzz{{~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;@A;=<8?==>@EE>CECGKu†ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹‹ŒŒŒŒ‹‹|WVRRTROLKJEFFKONOWVQPOQSRNSTOMSLPSUWRSRPLJMMMKNGGJFFIJDDEEBDCcquyyzzz{z{z{|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?=<A?AAEULBIJGJLy†ƒ……„…‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŽ‹‹‹gVVkaERQQPJ;;QSR`u]UVTVYYSYXRZfPUWZ]RTWQPNRPPPQKLKGHJHEFIIIHIjsvyyzyz{{|z{|}|}~}}}}}}~€€€€€€€€€~~THJIIGGFE??A@EACFDCDKVPKPPNPPy†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ}aŠ‹‹†l[dU:XXXSP?@VUY\d`VYbr^]W]ZVEQYZ\Y_TYgRUVXTTVSOOMJLJIILMKOMSotvxyxwzzz{z{|}|~~}~}}}~}~€€€€€€€€€€~~~~VJJIHGFDDBA?HLIMPKIJOSRQUVUVTu…„…………†‡ˆ‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~Œ‰Š‹znpXZ[ZRSRWVTZZuƒYU}a\X]^WIV^^[[_YHYXY\]XXYWRQMPQMMOSQQURassvwwvxyxz{{|}}}~}~}}}~~€€€€€€€€€€€xy}YNKJIIFBD@A:OQQWXPPPQRSRVWWWWl‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡ƒŠ~fYY\YSVTWRQWVc–€QerXZW_hP`fZZX\hbGOZig][\]]WRNSPPQVVVVYZosuwvvtwxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZZRSQOQRQURUSV^ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PVXTRTRQQLOMKfyZ]TYUV]ZLTZUST^ZXWWWzkXZ\\^TQQPINOWVX[Zdqtvvttvxyy{{|}}}~}~}~}}~€€€~~zxwvsu{€€tk~~kry^[VUSROKFCDAM^ƒlVRSNOQOQVRSRRTcdv€ƒ‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ymqVIKNNKMKHJDFHEC>ScURPQNKRURMOYQMNQSUUMQSRPOMLHCIGRSTZ]mrvvuttw{z{{{}{}}}~}}}~}~€}}~~€~{vsw}~~du}iqt`d]^[YUQLILIal’tPQSNQRPS[RSRQRUUbs{|~€‚}{{€ƒ‚…†‡‚†††„†…†u_]KC>BBCCB?DPCD@C>BHGV@INMG]iQHFOFDEFHGHBCHGHKGDBAC@NPMRdtuvustvz|z{{{||}|{~}}}~~€€€||}€€€}vt{mh|gnqfieeb\XSQPURsWe[OONLQRPUYSUQQTROV`klsvz{xyurnstsyx~~ƒ€ƒƒ‚‚€‚kLG>>::>@??>>jPJaEFHIEB?HMMGMQUJBE?><=<==?=?ACC@?<=B>IMFUouuvstvx{|z}{|}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QQZ\Y^IJOPNKLQRQTUUWQQWVPX[b]agmmlokh`nrimlqu{z}{xz||xwxdB@@A<:BCAACA[\N{NOONKLMOOPLKLWOIGAA<977599=;;;8989?;AG>\tuvwuvwy|||}|||}~}|}}}}~}xuwz{zwyxuw{|yxuywcqhipmnmmhf^OO^\ZIGOQQOMPQNQRSVXSRYTNYZ[WY\_^_e`]^qwk^`gkwooljonnlfbYGFFHBAFHEEFCLQOaWRXQPSSRU[OOQWPMJDF>:96586979:365795<B=ftuwxwyy{}}||{|}}~~{}~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZWMKSTSPQUOLRSTWXSTXQLXYYVXXVXY]WXXhsk]V`tkaa_]d`_^YUPMOMLIGJKIHFCPOSZWTTNQSYS\eUOSTQNKIHC?A9998978847578599Gnruyyz{{}}}}|{}|}~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPWVVSTVOOUVWXYSUTLKSUUUUWPTUWTUR]n^RNY`[VY;DUWT[fJLPRROMMNMMLJFPPUYSTOJNOUST\VRUSSOMLIHHF??=:787659967565Wqqtxzz{|}}}~||}|~}}y}}|~~~}||}}~}|rvqxxruuqqnppopuvtnjddjppqrpnfedc\^RTZVWTSVTRXXYYYRUOJGOPOOMRJOPOONNOTLMIPPSTU2<XMIAQ=c`QSQPNPPONNMPNTRPRLILKOQPQRSTQSOLMKLLHCBA=:9876;B4566;eprvxy{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqpuuvcjgeWhtrrqniihpVVTUXUVURWVUZYXWUQSFFAFGGHFJDHJHGEHLHKIGLMPMG/E_R>4@>joaRRQ@GTQOPPQNQOPOLJLLOPNNPQQNPOJLMMKGEEDB;==<9=G6676Dnquwz|{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknbePSTRSUOWVVYYVQQQO@>;=?@BAC@BEDA@GHGHFFHJMLDGCORC8DMS]gSQSAGUPOQQPMMNLJLKLNOOQLNNMIMLIKKLKGFFED<AA>;@E;<89Trsuy{{{|||{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLONMQSLTUTWWULLKH=987;?A>==A@B=>EHFDFFIGJJ@FAA@FGDIOHQRa\QPROSNOOLLOMKMLMON[VKMQOHJHCIJLLKFFFE?BC>=BG?B?@druw{z{{|{zzw|wy~~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCE=9879?B?;>A@@>ADIECHGIGIEBB?><CA@GIDMObePMOMWKLNKKMMLLKNNSdMJLRIIIEBIJLMNJGIGBAB@?EFEHDLopvzyy{{z{zwtxtx||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGLLIMPMPOHKE?B=999:?B?<ABAADDGKFDIIGGHCC?B??@@=CEDLMQTLJIMTFIIJLIJKIJLMOPRPKGCLGCCKJLNONIJIGCCCDIJMLIZsnxyxz{{y|vrpurtyyvxjqojllnttmsu{stxronqovsnporpopstyjN`gsjt|ygosqiqheqHKCFGHGJKIJLDGB=>=:::;AB?=BBCCHEJLJEIIFGGCD;A@B>@?BEDIMOGHJGHKDHIKMHJLHIJLJM]RIHDNGBELKNNQNLMJKFGGJMNRNMcnjwvw{y{z}qmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoijthepFKCFEFDEEFEGCC@=<=:;:;ADA?BCEEIFJJLFIIGFFCB;BCC>?CCCDFLNHJNHDHDILNMHILGFFIILNKJHEOICGNMPNPNOOMKIHIOSQRNSggfrosxv{z|lhjoekpmsqfmlhikltmputwqoxtotsrvspqrtsrtuuwvXVuukotrkovlhmf_pGJCEEDBBAE@DB>?>:;;=;=?DB?ACFGKFJILHGGGFEC?=DEB>ACBCEGHIGMPIFFFKNOKFHIFEDEIIHKIFHPKDJMMQNONOPNJJIMRUURPXeaamgqroryzgehhcilfqlflmgiklsmpvutpnvrosrsutqssutsuvvvyvutvlkuumrvqlnlerMGEEFBA@AD<BA>A=::=?;>?AB?@BEGKFJGIGFFFEDCAAFFCBBBDEEGGHFLPLIOJJLKIFHEFEDCIHHKJGKRMCOONQOOONOOKKKPUWVVTY`_]ianjnhrsbeffdihfnifmmhkkmriqvusqmvnoqrswsrstuuvvvwvwvvtwuksunutsprkksMGGEGAA@CD<AA@C<8:=>:?=@B@@@DFHEHFFHFEEDCDBDIFCGEAEGEFFGEJMKHQMJKHHIEFHHECIIJKMKPSNDRSQQRNONOPMLNSWVWYVX^Z]d`hcjigk_defchhgkggkmkmlpqgttursnvoqprtxqssuvu‚‘yvvtxuuwxnouorsuqqipzMGGGHAABEE<@CBD<7:=>;>;AB>??CEFDFDDGECECDFFFJEEIGBGHFGFECFJJGMKLKHJKFIHJHEKKLLNORTOITUTQTPQMNQNMQWZVZYWZ^ZXa```^hec`deggjhhjghnllomqpiuuxrrpupppruvpusuvu{~}xvtwvvvwplupmsunossyMHHGIDACGE<@EBD<8:>>><<BB=@>ABFCEBBGCCDEFGGGIFGKHCIHGIGFDHKIGKHMKJKLHLJMKINLNNORUVOLVVTQTRRLOQPOUYZY\ZZ\__^`c^\bdlc`dghr…hgjfjnnponsqjtuxrsstrnpqvrquruus~yŽ}uuvvvvxriuqkrtlqwquKIKHJEBDGE=AGDD@9<>@?>?CB<@>AAFCEDCHDFDFFHHFHGIKJEJHHJHFFLHHHJGLLLLLIMKMNMOLPPQUVWOKVVUSSRQLORRQV[[]^[]^``a`be^d`fh`ehjdssfjhflprqossnswwpuvtsmoruorspurvrtvuuuwvuwtgtrkqrkrwpwIJKIKGBEDE<AFDDB;??A@@ADA@B>ACHBEDFGEIEFEIHFIHJLHHJJIKJFJKHIJIGKKMLJJMKMNNOLOPRUWVMNTVUSRQPMNTSRW[^^_]^``aab`cdebdicdijgv‹lkigmosqpqpprywruutsmmssmqrotuuspswtuuwvuuteqskpqjrvpwJLKKLGCCAE<?EEEC=AACBBCEBCDAAEGCGFHFEIFCGJGGJFILHIJMJLKGKIHKKNQKRQLSMJNMNPPPTOWXX[NSQW\ZSVPNTUTTXZ_bb_da^ac^`fbacinhcihhmxvmhinosrpqrrrvtsusssnksqmprotvsqquvuswywutucmtkopjqtpwLMLLLGEA@D>=DEFC?CAEDDFCBEGCCIEBHJIGHJFDKJGHJIIKGJJOKMKILHJMKZfJd\KlRGNN_nUls[qpbwcRPbvuhucavaXnqbdvinzf\lu`lkU`xvijhhfglmjmojmosrprrqrsrssrtrnltonpqquurqstvvuuywutt`ktkppkqsqyKNJKJFB?@B?<DEFDCCCEEDFBFFGDDJDDJLKIKLGGNIHJKGKJIKJNLLLLLIMLL[sbdp^llULNer]geqlntgpi_aYnmbppbkjjgoqtetnn\pvgqNKryvkaakeelxmkvlnosrprqpqrqrrrtrmmsnnoprutqsstuuutwxvutbmukpplrrqzKLIIGED?AA?=BEFBECEDEEDBHHGDEKHGKMMILLFJNHJKJIKJJJKMMNMMMKNMM[rponpplkMPQlXNibtrpamov\YlP[mmZqmkomxxtsip]`slqjUuyxoc^kfbgppjioppsspqpqqrrqqrrtlmrmmnorutqtrtuutuuzvutenukpolsrryJKGHFEEBAB=??EGBGDIEEDBFIHHDGKJGMLNJLMGLNIMKHJMIJJJJNONNMLNML\hdu]lqWlNOQmUZk^klvaldtTecNlYl\tpkilxjwuhp]_skhWbcw|oc`ghacityknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtvIMGIEEDCAB<B@BFCGFKGECCHKHHFILKFMKKQQLHMMHNJIHNGJJHHNOMNLJMMJZtppoqqmlOQRnYskgooqqomt^nXat_nopoqroousttj[^tcwxrjnzhaacfabjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyytukoumtonssvtIKHJCEEE@@>CCAFCHIMHFCFJLIGFKMLFOJKWRKGKJJNIIJLIKJIIKMMMLIKKKSkbZi^_jcrrZ_Yko`eeUk_d[abQ`mh\j\niidZoedp]Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunwqrutwrIHFIDEDFA@AEDCGBHJLGFDGKLIEFJOLIOJL[QJFHHKMIHJJKKIHJGLKKKGHJJLLLKIKLNT[]TPUMQPNOOURPPQOOQJJNPQdqiTYV[[\UY[]X]\\cfaafbcf_^fkmhmtxrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyyxuvqruovrtsuusHCEGFFAEC?CGDEGCIKLHFDGKLHDGIQKLOKLWMIFEHIJHIKHLJIFHHJHHHEFLHIKNLIO\W^O\\`^OXYS\\b^MYZMXaRKYaZS`d\bX[ddVVX\YZX\VY\^c_d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtOBCDLMBCDBDIEGGFKJKHEEJJJFEHHPJLMJMRIHEAHFJIKKILJIGEJHEFGDEJGBIMJKT_Y`X`a[`UXYT^^Z_RY\P^\YN_\^S[^d_Z]`c_Y_b[`^[UYXZ_^dbbaceiekrpoppnow††……†‚{€……††…†…uqprrsuyyzyyxxxwryvxrqxvtvaSJJMIECBCFGEGGIJJIIDFKJJEFIINJNLHLNGHF>GGLIKKJKKIGEIEDDEAEID?IKHN[cY^^a_RTSW_`\]Y^QY\MV_WKQY[Q[_ba]^ca`bbbcceZRYVW][^c`__cebhommllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxXQJFDGEBEGHFGHIFGJGHFHKIKDDJJMMLLHJJHJG?GFNJKKMKKKIGHDD@D@GHA>HIFO]aZ[d]_TQRX]\\\_ZKW\LR\YIM^QQ]_bccccb\dcbdceXRWUT]Y[a_^_aa_dlkmjklnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMC@IFCFKIFGGIGGJFFFILJNECJJLNJLIKJIIGBHHQMKKOMKKIHHED?EBHHA@FECT]Y^X_Y_[]UXXP]]QKJV^X^[]VZaRR__bb``bb`cbbddbXPRRS\T\]^^^__`dhgljnnp{{|~{€‚ƒ„………………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKBAGFDGMRHDRKFHHHDFKIMPEGIJKNLLILKJIGDHKQOMLPLLKKIJDEAECHFAAFDAVUE\T^SV_XNTUNZ[MJKT`a[_X_^b]OXb\``_bcb]bbW__TQPQRYS^\\]^_`bffelfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDFFGDIScQEW_IGGHDFMJPPFIIJKNLLKMKJJGEINQQNOOMNMNHLBDACCFDBACD@LHBLLPONLFMFFHIHGLLMOPILOPPSPLQTRUZXWYWXdVOSTPQOOQUT\YY[^^aaefchdlmqsszy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKM^MHHYMGHJHGMLQQIKJKKNMUNOKKLGGKPTSNPONOOOHKF`ED^LDfcCL[H^[smOMVmYLCP_TlWgJ]WU^DLQULMSVQRTXVTXUT\TPfZhheZTkTXWU[\\``abbb`gignlhrz|}~„„„ƒƒƒƒ}}zr{z{‚€ƒ„„……„…ƒƒ~z{LIEFFHEEKOTJKG`TGJOJIOMRQKMKLORUROPJLNGHMQ[YOPPNOPPJKQQI|YYrsWPmHqnoaVPqqtOBksnqtpSo_[nX]V\XUkhU]VcY`YZ_VUWituu_av_Yb\\f[_aaab^`cgmpl`pwtx‚ƒ„‚}~€vxzmv~tx}€|~€‚„|€ƒz~wwNIEHMMBDLLGJLFRVLKOHLRXWQNOOMQTNOQPKLOGMPS[ZTQROPPQKIZx]TxdhXQSPvgtlpbnfkRrOLwmjrpsrqrpop€]fzuxqqzq~r}ku}aRh|essoss|}p~xor_``bb[aahknkblfgmw~€ƒ~{xw€tvzhr~nt|~wx{~€ƒx|u|||ssNKF`]GAEMMHKKHJQOMNJNV^YULQSNYYLSSRNLPIQRTYWWQTPPQSLHgxlcxqmZJLTypumubnvPddIevqmwo€jfxxiXrRi{mijzz}lxzpgnXuujvup€ash}ilx|o___cb\^defijegbcdllppstsssyqrxbltgry{ssuy~svzn|}yxrnMJRtNCBEPQIKLJLQOOOMPZ`ZXKTWPa^RVQYSMPJSTUXWWOUPONSJKrouuquqchaVnLqp^GhyWvTKhx}x`y{sna]modSgrunmypwlvstqlm\s}zkmy|lun|lqvux^__b^]_eeighfe^bbiiijknokqnmjpacfdowxompsynqpj{ztromKKZVHGEGRQKMNLLQQPPPQW\YUNVYUfXRRY^TMNJTTVWYWOSOONQIRmHiwK`dvuUWlNnl{rajguTKWkh}lmlx_Zpz{_`zscroxqhd|ir{]TKl_vuljv|{m~yk|p]^^b[^bdegffec[ccikkrsrwgmihdg`alagsrlhmmr|kmhk{tmmkmOGJKHJHHRQMOPMLSSROSSXRWTPWZVVTTTa`QONKTSSQVVOOMNOQJHQNPULKKRSRRROVUQQORRXXQNPUTXXX[[UQRW[WXW[ORTWWXQ]XV]USOXRWWXYZ`\gr_[[Z]]_cZ_ccegdddcZdbgffmnmuffgc`f^^g`dlhfgkhpzhggkujhgilPIKKLMKJTRNRQPLVVTPTUXUZVR[]VUTWUYXOOLNWTPNUSNPNLQPKJRQKQMJJOQTRPQSRIIMOPQRQQQTUQXW\WSRQQUUVTZQNRRWUSYVTYUSQUSUUYYX^Z_a]\[Z]]`c\]bcdfdeebY`acabhhjncad^_c]Zc\bma^ffgmsdihkkedcfhQJKKNOLMTQOTQQMXWUTVXWWZVT\`VWVYUXTQPKOXSPNUPNQNLSPMNUSNQNMNQSPTPRTTNLNORTTRRQVVSXZ[YSURTXWWY[SOSTWUTYUVYUQQWUVX\Z\`]WY_]^]\]`a^[bbcgfeebX``b]`hegea^_]]^ZZ_Z_g`^^]chkahfhfd`bdbPKMLPQLOTPPTQOQZYXWYZZXXV]jdVXYZWVTTOKOVTPOTPPQNMQQOQXTQQOMOSUNWQTTUONNQTUUTTRTWUZ]\ZVVQRWXV[\VPSUUUVXSWWTRQXVV[_[_`_V_]^`\\``__ZbcdhgeebYb`b^^fdc`b]\\\\YZ[X[a[^]]_b__bddbd__`\PMNNRQMRSPSTQOU\ZZW[[\YZ[dqmhd_[YVVXRMNWSMMROQROMPSQUZUTPPLPWUQVRTSXMOPRUXUUUSUXW[^]\[VROUVV[[VQSVUVXTSWZSSQYWW]_[`_`Vb\`a]`b_\`]cacgief`Zc`a__ee_`c[Z\[\ZZYYW\Z\[`^`[^^a`_c\Y`ZQNONVQPUSPUTSPW\\\Y^\_W\^jpwy€c\[VVYRNPWSNQQPRTRLQTSY[WUORNSXVSRTRRZOQSSV[UVVTWZX]^\\^VSNTVV[[UQTTVWXRSX[SRR\XZ]^]aa`Wb[cb^ac_\bab_dgieg]\e`a`acd_b_YZ_[\[YXYWWZZZa\][]\\Z]`W[[ZPOOOYPUUSRWRTP[]^]\`\`V\]hjr}slh\UYWQOR[SRQTRTUTKRVUZZZSOSQUUUSNUQRZRTUTX]WXXSX\X^]YZ]TUNVVW^ZXQTUXXXSVX[SRV]Y]]a^cc_Y`[eb_dd^^cca^efief^^daaabcd_b^X[_[\[XXXXW[Z[`][[\[XZ[^V^Y]POORZPZUVWVTTT^^`_^b\`U]^bkyum}lZUZVQQT\TTTUTVYWLRZV\Z\RPUSWUUSOWQSWSWUV[^X[YUZ^X_^Y\YRWRYXX_YYRTUZYYUWY[UTZ]]^ab`ed]^]]eabfd^_dc`\gehfdb`ea_aabb_`^WY^Z\\ZYYWV]Z]^[Z[\[WY\]VXW]SOPWYP]UVYWWUX_`aa`c]`U]^beev‚{hXYZTVTV\WWWVVW]XOU\Y^]]TSXSWUSRSWQSVTXXX^^X][U^_X__X\VQYUYZZaX[TVWZZZXYYZWV]_`_dcbee^b\`fbdfd_`dba[fchfdfaf__abaa`_^VU]Y[\[Y\YY][[[XXY[YZZ]_]TY]UNTZVT\UWWYWV\`aacac__V[`da_zuohZ\ZVXVX[ZY[YXY`VOT][`a\UUYPTVTRVUQSUW[[]__Z_\V__Z]^Y^VSYXYY\aY]UVZ[Z[ZZYZXY__``dcdeecdZbfcgfe^ab`c]bciedh_g^bbcaa`^_XTZZZ[[X\XX\[Z[WWZXW\[\`]V]]SOVZVVZVYVXWX^`badada^YYadb`kfh^\][WWYZ\\\_[Y[bVSW^]ac\SVYPVUUUVUSVTX]]_``]a]W`^[^\[^XVXX[Z__Z^WX\\]]][Z\WZ_a^`eddffgcYcfehgd^c`_ec]fidei_g^cbcaa`__[XY[YZYXZXW[[Z[WXZTZ]\[`\U^bMRWYVWZY[\YWY^`baeada]^Yacb_a`a_\]]XW[[]]__\Z]cXYX]`cd_RXYPWVWXWVVWV]]^aba_b^Ya]]^Y]^YXUW[[`^\_YY^]^^`\ZZY[_b_bedefghcZefgigc_c^`feZiicficf_bbca``_]]ZX[YYXXZYWZ[ZYWYVU[]]]``bbxKWW\YW]\\]ZW\]_`bdbca]`Xbcb`cac^\]\XW[]_]`_][`d\\XZbecaR\YOXVY[YYWZZ`^abc`ac_\b]_][_^YYTX]]__^_[Z^^`bb\\W[]`bbcedgffge]eghifcab\cg`\iichife`baca_`_]]\Y\YXWXYYW\[ZWWXPXZ]acffrkJYW][Z_]\^\Y][^_bcbaa]b[bdb`cbb]\[ZWXiq`\`_]\ac_^YYcedbT_ZQYW\]\[Y[[c`ccc`bda`c^`\^__ZXV[_]\aa_][`abeb^\S\_`cddfeggfff`fghhgdd`[fg^ahhcihfc`b`cb___]][Z[YXXXVZV\ZZVVULXX\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡…‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vuuuuuuuvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{{{{{{{{{||||||{{{{{{{||||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vutuuuutuvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{{{|{{{{{|}}}}|||{{{{{||||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||xÅÔÒÒÒÒԓ{}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰Š‡sqrrrrt>(+++*%b’ŒŒŽ‰~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}xÕçääääç™{~†“y1333332j‚€€€{­éääääèʉŒŒŒŒŒ‰rooooor2]–‹}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}v~€ywwwwwwxyyyyy{xnoopppprrrrrrrwzyyzzz~ƒƒƒƒƒ„|||||||zzzzzzzusssssry}}}~~}}|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚‚‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vtttttwuvwz{x{xwvvxy{zy}yyyxxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{{{{{{{{|}}}}}}|{{{{{||||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwww||}z{}{xwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwwy~||}|}|xxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z|yww{~|x{}||xxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚ƒ‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzzx{|||{}{xxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyywxzzzx{xxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyxyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{|||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}|}}}|||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹ŠŠ‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„…‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰…„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚€€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrstuttssrrsrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqstsssrqqppnnnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqqrssssqpqpoonnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrqrrssrrqppoopoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpppqrrqqqpopooppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqpqqqqqqpooppppppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqqqqqpppppppppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsquŒ‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqqqpqqqqpqpqpqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrqqqqqrqqqrrqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrssrrrrrstrrsrsssssssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz|~~|vvwwvuxzxxxxwwwvx|yy|zyy|{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~|{{z{|{}|{{{{{{zyxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}|||~|}~~~~~}}||}ƒ€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š††ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€€€€‚€€~~~~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~~€€€~~~~}~~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~~~~€~~~~~~~~~€€€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹ŠŠ‹‹‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚‚‚€€€€€€€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒŽ‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒƒ‚„„‚ƒ‚‡ƒ‚‚€‚‚‚‚ƒ‚‚ƒ‚ƒ‚ƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒ‚ƒ€‚ƒ‚…………††‡†…††‡‡‡†††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠˆ‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚‚ƒƒƒ„„ƒ‚ƒ…ƒ‚‚„…‡‡‡‡††‡‡‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ’‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„„ƒƒƒƒ„…„„……„ƒƒ„……‚„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘’’ŽŽ‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€‚‚‚‚‚‚‚‚‚ƒ€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„…„„…„…†’“‘ŽŽŽŽ‰‰‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~€‚€‚‚‚€€€€~€‚€‚ƒƒ€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“’Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚„‚‚ƒ„‚ƒ„…†„‚„‚€‚‚‚„ƒ‚ƒ‚‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘ŽŒ‡…ƒƒƒ‚‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒƒ‚ƒ……ƒƒƒ„ƒ„ƒƒ„„…„„„‚€‚ƒ‚ƒ„ƒƒ‚‚„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”““’ŒŒŠ…„„ƒƒ‚‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€€€‚€€‚‚‚‚‚‚€‚‚‚‚‚‚ƒƒ‚‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†”“’”’‹‡„„ƒƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€€€€€€€ƒ€‚„ƒ‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“‘Š†ƒƒƒ„‚‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€€ƒ‚‚ƒ‚‚‚ƒƒƒ„‚ƒƒƒ‚€€€‚‚‚‚‚‚ƒƒƒƒ‚ƒƒ„‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†ƒ„ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„…„‚‚‚ƒƒ‚„‚‚†…„…„ƒ„„„†…„„…‚}}}~‚„ƒƒƒƒƒƒƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„……………„††…††…………………………††…†††…†††‡†…………ƒ„„„‡““’‘’Œ‹ˆ…†……‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒ„ƒƒƒ„…ƒ‚ƒ„……†…††…†‡‡†ƒ~~~~~ƒ„ƒƒ„„„„„„„„„„„„………„…„†……†…†††…†……‡……†…††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„ƒƒƒ…………‡‡……‡…~€€„…„…†††…………††‡††…†……†‡‡‡ˆ‡‡‡†††‡‡‡††††‡††…„ƒ„……†„……††‡‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘“’‘‹ˆˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒƒ„ƒƒ‚ƒ…„…‡‡…„‚€€€€……†‡ˆˆ‡‡‡‡ˆ‡ˆ‡ˆ‰ˆ††‡ˆˆ‰‰‰ˆ‡†‡‡‡ˆˆ†‡†‡‡††…„ƒ„…††………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†…†„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡‡…ƒƒ…„ƒƒƒ‚ƒ…„„…„€‚€€~{z€†ˆˆŠŠ‰‰ˆˆ‰‰‰‰Š‹Šˆˆˆ‰Š‹‹ŠŠˆˆ‡ˆˆˆ‡‡ˆˆ‡ˆ†‡†„ƒƒ…‡‡‡†……„„„……„……†„„„………†…†…ƒ‰”“Ž‘ŽŠ†…†…ƒ‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡‡„„…„ƒƒ„„……ƒƒ‚‚‚‚‚‚€~|}}}~|{|ƒ‡‰‹‹ŠŠŠˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰‡†††‡…†ˆˆ‰ˆ‡†‡„ƒ‚„ˆˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚‚ƒ‚„ƒ„ƒŽ“’‹ˆ…„†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒƒ‚ƒ…‰Š‰‡…‡…„……„„††ƒ‚‚‚‚‚ƒ~}~~~~~~}}~}}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡ˆ‰‡ˆ†ˆ‡‡‰ˆ„ƒ„ƒ…„„……‡ˆˆ†…ƒ‚‚ƒ…‡†‡††ƒ‚‚ƒ„‚ƒ„„‚‚ƒƒ„ƒ„‘’‘ŽŽ‹‡„††ƒ‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚‚„„ƒ‚…†ˆ‹Š†…†„‚††‚€ƒƒƒƒƒƒ‚‚}|}€~~~}|}}|z|„†‡†„ƒ‚ƒ„………ƒƒ…„„„„…„…„‚‚ƒ‚„„‚ƒƒ…†…„‚‚‚ƒƒ…ƒ„„…„„†ƒ„„…ƒ‚ƒ‚ƒƒ„…„‡’‘‰†„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………‡‡‡‡†€…ƒƒ„…„‡ˆ…ƒ€€~}‚ƒƒƒƒ‚‚€}}€€}~~}}}}zzz~ƒ„„‚€‚‚~‚ƒ€‚‚‚‚ƒƒ€€€‚‚‚€€€€‚‚„ƒƒ…„‚‚„ƒ‚‚‚„ƒ……†Œ“‘Ž‹ˆ……ƒ‚„‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€ƒ‚~~~||ƒƒ‚ƒ‚ƒ}}~€€€~}}}}~}|zzz‚‚€~€~}€€€€€€‚~}}€~€€€€€€‚€€‚‚‚€‚„ƒ†’ŽŠ‡‡†ƒƒ‚‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒƒƒ„…€|}}~}}~€€~}~~|}~‚ƒƒ‚‚}}~~€€€~}}}|{{{zzyz€€~~~~|~~€~€€€~~~~}|~€~~€€€~€€~€€…’’Ž‹‹‡‰…„ƒ‚‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~~~~€€€€~}„ƒ‚€~}~~€€€~}}}}{{|zzyyy{~~}~€€~€€‚€|~~~~}|€~~€~~€€~€~~~~~}||}…“’Œ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒƒ‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚‚ƒ„…ƒ„€€€€€‚‚ƒ~€‚ƒƒ€€}}}~~~~}}}}}|||{zyyyy}€€€€€€‚‚€~€~~~~€‚€€€~€€~~€}~}}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…ƒƒƒƒ…„„„„ƒƒƒƒ‚‚‚‚~~}}}~~€}}}}}}}}|{zzyyyy€‚‚‚„ƒ€‚ƒ€‚€ƒ‚‚ƒ‚€€€ƒ„‚€€€€€€‚‚€€€€€€~~||Š“Š‰ˆˆˆ‰ˆ††…„‚‚‚‚ƒƒƒƒƒ‚ƒ‚‚‚€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…ƒ„…„…†††††……†€ƒƒƒ‚‚€}}}}}}~~}}}}}}}}}|{yyyyx|‚ƒ„…‚„ƒ‚‚ƒ…†‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚‚„ƒ‚ƒ‚‚‚‚€€€€~Ž“Œ‡ˆ‡ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€€~}}}~~~€ƒ„‡ˆ„†††…††‡‡†‡‡‡‡†‡‡}€€‚~}}}}}}}}}}}}||~~~|{yxwxyy€‚ƒƒ„ƒ„„„——ƒƒ„}~‚‚‚‚„†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ……„…ƒ‚ƒƒ‚ƒƒ‚‚‚‚ƒƒ‚‚’‹ˆ‰‡‰‡††„†…„„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€~}~€‚………††‡‡†‡‡ˆ†‡‡‡†‡‡‡|}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yxy|~‰—„ƒƒ„„”“€~~„‹€€€„†‰…„‚‚……‹ƒ‚……††„ƒ……ƒ„„ƒƒ„ƒ…„„ˆ’Ž‹‰ˆˆ‰‡‡‡…†…„…„‚‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„„†…||||}}||}}}}}}}}}}||‘•–ƒ{z„”|xyz{|‚ƒ€ƒ‚€~|~~{ˆ‘||Ž–}‚†Š…ƒƒ„ƒƒ‰}ƒ„……ƒ…†…„……ƒ„……†„„Ž‘ŒŠŠŒ‰‰‰‡…†…ƒƒ‚‚‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚ƒƒƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚‚ƒ}}||}}|||}||}|}}}|||{‹‘—Œz{|zzz{|yy}}~€€|{{~~}‚•‘„ˆ~|~‚„||‚„‚€‡ƒ}‚€‚‚€ƒƒ„„„„„‚„ƒ„…‚„‘‘Ž‹ŒŒŽŠ‰‰………ƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚‚ƒ…ƒ„…………ƒƒƒ„‚ƒƒ‚ƒ‚‚€€~~}||||||||||||||}|||~~Š‚{z{zxz{{|}{~}~}}}}||€}†~}‚~~€‚||€‚€~}{Š‚}€~€€‚‚€€€‹“Œ‹Žˆ‡ˆ†…„„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€|zx{€‚ƒ…„ƒ…„††„„€†”ˆ€€~~~€|||||||||||||}|||||||y{{{xxy{zz|€~|~~}€‚‚€€€‚‘€€~€~~~€}}}{}}}|}||}€€€~€~~‚”‘‹ŒŠ…††…„„…ƒƒ‚‚ƒƒƒƒ‚‚€€€€€€€€}{z}€€€x~w{€‚‚‚‚„†‡††~ˆ•Š~€€€~€~~~|{{|||||||||~}|{}|||{|||zzy{|z}…ƒ‚~~€~…‚~€~~€…†‚€~~ƒ†~}~€€€~}}}}~{|}€}~€Œ‘‹Ž‡„††…„„„ƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}~€‚ƒ††……~€€€~~~€€€€}|||}~}|}}}}}}|~|}|{}||z{z|}}†„‚€€}~}~~‹„†~}||~‚}}}}|{}|~„ƒ€~~~~}}}~€~~~„’ŒŒ‹Ž‹Š†„†„„„ƒƒƒ‚ƒ‚ƒ‚ƒ‚€}|||}~{{}w~vx~}|}|}~~‚ƒ€z}}|~€€~€~~€€€€~~~~~~}~}|~}~}}|{|||z|z}~€„ƒ‚~|}|}||ƒ~Œ~|{{}~}~~}{{{}{z{{{€†„‚„ƒ‚€~‚‚‚‚‚€ŠŒŠŠŒ‹Šˆ„„„ƒ„ƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€€€€}€~~~|‚~~}}}{{}}|z||~€‚€€€||}|||||}|}{~{{{|||}|{{{{}|zz}z~‚ƒ„‚‚…†……††‡…‚„‘ŽŒŠ‰Š‡ˆ…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~~€€‚€~~€€~}ƒ||}}|}}}}{|~~~~~~~|||||||~~{|{||||}|}|~|}||{{|y{|{{}{}~~€€ƒ‡‰‰‰Š‰Š‰…ˆ‘‹ˆˆ†……ƒ‚‚ƒ„„ƒƒ‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€~~~}€€€€ƒ‚€€€€€€€~|z|}}~}}~~Œ†}}~{{ƒ‚}}}}}|}|}}}~|}|}|}}~|~}}}}|{{{|{||{z{{zzz{~~ƒ…ˆ‡ˆŠ‹‹Š‰ŒŒ‰ˆ†…„ƒ‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„„€€€€‚~}~€~{~‘Œ|}Š€Œ~~}}}~}}~}|||}}|}|}}}~}}~~|{{{||}|{z{|yzyxy{~„ƒ„‡‰Šˆ‰ŒŠˆˆ…„„ƒ‚‚‚‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{|||~~}}€€€‚…ƒ„‚‚‚‚€€ƒ‚€}~€~|~ˆ‚~ƒ„„ƒ~}|‡}}~}||~|}}|}}}~}~}}}{|}~||{|}zzyyzy{{~~€ƒ‡„ˆŒ‰‰†…„„ƒ‚‚‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{|}}}}zx‚€‚‚€€€€€‚‚‚‚†…„‚ƒ€‚„~€}~~}~€€}~„€~~}~}}Š…}~}~~€}}}|~~~}€}~}|}||{|}{{{zzz{{|}~}€ƒ€‰Œ‰Š‡………„ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv~€ƒ‚‚‚‚‚ƒƒƒ‚…†„‚€€€€‚€„~~€€~~€~}~~€€~€€}~€~€~|}}|~~~~€}‚€|}€}||}}||{||{{{|{|||}|‰‰‡‡…†……„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€ƒ€€€€ƒ~~€€}€}}~~€€‚€€€}€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{|~|}|||{|{|~‰…†„…‡…„…„‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz}}yxtt€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚~~~€}~€}}}~€€‚€€€‚~~€€€€€~}}}~}~~}}„€~}€}}}~~}~|{|z|{z€…‚„„…„„„…ƒ‚‚‚€€‚‚ƒ‚‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xytu}‚ƒ‚ƒƒƒƒ…„…„ƒƒ„„ƒƒ„‚€€€~}}~€~~~€}}|}}~€€€€‚€€€ƒ€€~€~€€€~~~~~~~~……€€ƒ~€~€€~}{z{z|{z‚ƒ€‚‚‚‚ƒ‚ƒ‚€€‚€€‚ƒƒ„ƒ„‚„‚‚‚‚~€~}~~~~}~}}z{|…„{{sy{|pwuvwyvtz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€~€}}}~€}~~}~|}}~€€€€€ƒƒ€~€€€€€€€€‚‚‚„€ƒ€€|{|z|{|€€‚‚€~‚‚ƒƒƒ‚„‚„‚€‚€~€€}~~}}}~}~{{z€x|vyz|qtxwvxury……‚„„‚„……†„„‚„ƒƒ‚€€~€€|}}~€}~~}|~~~~€€ƒƒƒ€€‚€€€€€€€€‚ƒ€„€}ƒ„€€‚}z{{||}}€|~}€€~}}€~‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxzzruyyvwwsu†…ƒ……‚„„…„„„‚ƒ‚ƒ€~€~€}}}~~€~~}|€|~€~€‚ƒ€€‚ƒ„‚€€‚€€€‚ƒ‚ƒ€~‚‚„€€‚‚‚„‚~{{|||}}}~}z~}~y~|||~}~€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„‚„„…ƒƒ‚ƒƒ€}~}}}€~~~}}€€~|~~~‚‚ƒ‡…~~€€€€€€‚‚€€~€‚‚‚ƒ‚ƒƒ…‚}}}|{||yz{z~y|yx~{{{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst†„„…ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€|€€~€}~}~€€€~|~€€€~}~~€}€€ƒ„ƒ~}~~~€€€‚€~€~€‚‚€„‚„„†„€~}||||zyvyyzyvyv~|{{{~}{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„……ƒƒƒƒƒƒ‚‚ƒ‚ƒ‚€~€}}}}€€€€|€€€€|€~~~}~~‚‚‚~~}~~~~€}€€~~~~~€‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{{{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ||z{{{z{wvxursvqwyrx…………ƒ„„‚‚ƒ‚‚€ƒ€€~~~~€~}~|~€€€€{€~€€€€}€~~}}}~€~~~~}}~~~|~€~~~‚~~€€ƒ‚ƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}}{|z{}zzx{|zz{xtxuqrtpxxqy„………ƒ„ƒ‚ƒƒ‚‚‚€€€€}~~€}|~}€€‚€|€€~€}€~}}|€€€€€~~~}|~~~|}€~}~€‚~€€~„‚‚ƒ……‚‚~}}{{||yw{ywxwwx{{z{|…Š}{zwz|}}||}}}~}}~~}}||}~~}}||{zz|{{zyzz{zxswuqqspxwq{…‡……ƒ…‚ƒƒ‚€€€€~~}|~}€€‚€}~€~€€€~~|}€€€€~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{|||zzzzzzxsvupprowvr{…‡„…ƒ„‚ƒ‚‚‚‚‚€€}}~€‚}~~~€€‚€€€~}~|€€€€€~}~~€€‚€€€€€„‚‚€~|}~~z}…~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqpwts|…†ƒ„‚ƒ‚‚‚‚‚‚‚€€€€€€~}€€‚‚‚‚€~€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€€‚€€~}~{“z|}|{}y{zzxyxy{||}|||||||}}}||}|~}~~~}|z||{|}{yzzzyysuuooqpwst}…†ƒƒ‚ƒ‚€€‚‚‚€‚‚€€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€}~€~}€€€€€€€€€€€€‚‚€€€}~|†‰||~{{~yz{z{~wwy{|{}||||{}|}}}}|}|~~~~|z|}{}}{yy{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚‚€~‚‚„ƒ€‚€€€€}€€€€€€~€€€~}€~~€€€€€€€‚‚‚€€€€€€}~€}€ƒ‚{~~{{}{z||{‡yxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxqvv……ƒ„ƒ‚‚€€€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ‚„„€~‚€€€€€‚~€€‚€€€€€€€€€~}€€€€€€€€€€€‚€€€€€~}~}~~{}|}{||wxuxxy{||}|||||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒƒƒƒ‚‚ƒ€‚…ƒƒ„ƒ€‚‚€€‚ƒ‚€‚‚„ƒ€~‚ƒ€€€€€€€€‚€‚€~€€€€€€€€€€€€€€€€€€€€€€‚ƒ‚‚€‚‚€€€‡~~|z}|{}~xwvyyz|}||}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚ƒ„„€€‚†ƒƒƒ‚„€„ƒ‚‚€€‚‚„‚‚„‚€€ƒ‚€€€€€ƒ~€ƒ‚}‚€€€~€€€€€€‚‚€‚ƒ‚‚ƒƒƒ‚€€€„}}}{}z}€zyvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysruowqwysw{…‚‚ƒ‚ƒ„‚ƒ„ƒ€€‚‚†ƒƒƒ‚‚„„ƒ‚€€‚ƒ‚‚‚~€€‚‚‚‚€€€€‚„€~ƒ€ƒ‚€~€‚ƒ‚€‚‚ƒ‚ƒ‚‚„€ƒ‚„ƒƒ„„ƒƒ„ƒƒ‚€‚€}€|z|{{w|yyy{z}~}||||}~~€€€„„€}€~{{{z{ztpxrytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚‚„†„‚ƒƒ‚„„„€ƒ€ƒ‚‚‚‚‚€‚€~€€‚‚‚‚‚€ƒ‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚ƒƒƒ„‚„‚ƒ‚‚‚‚ƒƒ„ƒ„„„„„…ƒ„‚ƒ‚‚ƒ€€~||€||x|yzyz|}|{||}}}||€€€€€‚~€€€€z{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚‚………ƒƒ‚ƒ„„…‚‚‚ƒƒ‚‚‚€€}€€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€ƒ€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒ„ƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{~~}y|zzz}||~z||}}|z{~~~€€€€€€€€€}}||}|vrvxxvtvu}‡‡ƒ‚„…ƒƒ„…„€‚„…„„ƒ‚ƒ„„€„…ƒ‚‚‚ƒƒ‚ƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚‚‚ƒ„‚‚€€‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒ„ƒ„ƒ€‚ƒ‚„ƒ‚‚~ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz{}}||z|~}|}}~~€€€€~~€€€€~|}}~~}|{xvvw„‡ƒ‚ƒ…ƒƒ„†„‚…†…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„‚‚‚ƒƒ‚ƒƒ‚‚„„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒ„„„„„„…„ƒƒ„…„…„ƒ‚‚€}‚}||{||€}}~€~~}~|||}}~~~€}}~€~~}}}~}}~~|}€‚‚ƒƒ†ƒ„ƒ†„‚ˆ‡…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚ƒƒƒ‚‚„ƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒ‚‚ƒƒ‚„ƒƒƒ„ƒ„„„…„„„…………„ƒƒ„}„}}||||~~~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒ„…ƒ„ƒ…~‚Š‹…„„ƒ‚„…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ…ƒƒ……„……‡‡†‡…………„‚„~~|~}}€~||~~|z|}}}}}~~~€}}|€€~~~~~€‚€……„ƒ…„‚„ƒ†€‚……Š‰„„ƒ„……ƒ‡††„„„„…„„„„ƒ„ƒ‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ…}uzƒ€~„„‚ƒƒ‚ƒ„ƒƒ„…ƒ„…†„…†}„y|~„{…ƒ„ƒ€~~~}}ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚‚ƒƒ‚‚†„„„†„ƒ„…ƒ„…„Šˆ………ƒ……„†††ƒ„„………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†tpurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚……‚hzrss|€sƒƒƒ}}~~}~‚ƒ|}€}}||||}|||~}~€}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ…ƒ†ˆ††…ƒ††‡‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vyy…r„ƒpvxqvtturstvi€nrotvnulwm{sn€ˆym}rsvsvmmxlpylu}}~€}~}€€}}||}}|}~}€€€~|~€‚€€€€€€€‚ƒ‚ƒ„…ˆ††€‚…ƒƒ„‡†ƒ………†‡‡„ƒ†‡ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpu‚rƒ~ozyymonzoomw}x†pqzprtfu~n{ysoy€}}|}|~€€~~€€€~~~€~}€}€€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„†……††ˆ„„†‡‡ˆ†‡„††‹Š…„†‡‡…„………„‚…………††…†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„qjoyxpkyszozwvvp€~~~z~}}}~}€ƒƒ€‚ƒ„‚€€}~~~€~~‚€€‚„‡†ƒƒ†„……†‡†…………††ˆ……†…‡‡…†„††‰ˆ…„‰Šˆ…„††……ƒ……„…††††…ƒx‹yrˆz{pp…„x…xyks~y{krƒ‡ƒz|m{yyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozls|nw‚~~}}{}{|}}}}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡…………†‡‡ˆ†„†…†††…„……„……†‰‰‡†„†…††…††„††‡††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„††…†„†„ƒ„„†„ƒƒƒ„„…„…„…„†ƒ†‡…†„„…‡†„„…†„…}w…ƒ„„ƒ‚}~{|{~{||}~}|~}€}€~~~€~~~~}}}~|{|~||‰†…„†††…††…………‡†‡ˆ†„†…††……ƒ„…†…„††††……†„…††††„††‡‡†…‡ˆˆˆˆ†„‡…††ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…ƒ‚……†……ƒ…„„„…„……„……„†‡††…„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ‚}€{{|~{||}~||~}€~}~€~~€}}|€}~~~~||}~{|||{{~€ˆ‡„„ˆ†††‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡……†……†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ…„ˆ…†‡†‡†ˆ†‡…‡‡†‡……†‡…‡†…‚ƒ…††„„ƒ„„ƒ„†„………††„††…†……††……ƒ……‚…‡…ƒ‚‚…ƒ„~€€|{}~{|{}~}{|~}~~|~}}~~}}||~~|}€}||}|||~z{{}~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†„…„††„…‡ƒ„…„…‡„…††…†„††‡‡††ˆ‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…‡‡…‡†‡†‡…ˆˆ‡‡…††‡…††…„„…†……„„„ƒ„……†††…†„†…†‡……††…„ƒ„ƒ‚„‡ƒ„‚„„ƒ€€€{{~}|||}}|||}}|}|~}|}}|||}}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††„…†…†…†…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡…‡††‡‡‡…‡†ˆˆ‡‡…‡‡‡…†‡„‚„ƒ„†…‡……„ƒ„„…††††††‡††ˆ…†††…„‚ƒ‚ƒƒ‡ƒ€‚ƒƒ‚‚‚€{}~}{||~}|}}|}{||||||}{{{}|{~|{|}}|}}~}|zz{{||ˆ‡‚††††‡††…ƒ…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡‰ˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡†ˆ‡††‡‡…‡†ˆˆ‡†…‡‡‡††‡ƒƒ„„ƒ††‡……„„„…†††††…‡‡‡‡ˆ††„†…ƒ‚‚‚‚ƒ†ƒ~‚‚ƒ€ƒ‚|~~||}}|}}|}z{{z{|||{{{~{{}{{{~||||}~}{z|z|}‰‡ƒ†…†…††…„„……………„ƒ…†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…ˆŠ‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……‡ƒ„†…„††‡†……„……††††‡…††‡‡‡‡…„†…ƒ€ƒ…‚ƒ~ƒ~~~~||}}{}}|}zz{y{|}{{{{~||||z{}||||~}|{{{{|{‰‡„†„†„††…„…†…„„ƒ„‚€ƒ…‚‚z„Œ{€„…‡†††…„‡ˆ‡†‡……‡‰‡„‡…†‡ˆ†…‡„†‡‰††ˆ‡‡‡†‡ˆ†„†††‡†…‡ƒ„…„†††ˆ……„ƒ……‡…‡†‡…††‡†††„ƒ„…‚€€€ƒƒƒ‚}€~ƒ~||}}~}{~}|}yzzy{}}zz{{}|}||z{}||}|~~€|{{|~}|ˆ‡…†…†„†………………ƒƒƒ€…‚€€}|{„…††„…„ƒ‡‡†††…„†‰†‚†„†††……‡†‡ˆˆ†…ˆ‡‰‡††‡…„†……‡…„‡ƒ„…„ˆ††‡……„‚†…†…‡†‡„†††……†ƒƒƒ…€€€„€ƒ€|€~~‚€}€||}~}~{~}||yzzyz}}yz{{|{|{{z{}}|}|~~~{{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€€ƒ~~~€yz}€ƒƒ„‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ†…ˆ‡‰‡†…†…ƒ†„…‡ƒ„†„„…„‡†…†…†„ƒ†…†††††„…††……†‚‚ƒ„~€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|z{{{|}}}|~}||}~|{ˆ……††††„…„…ƒ…‚€€€€~‚‚}}{‚ƒƒ…†…„ƒ‚†ƒƒ„‚€…‡…‚ƒ„…„„††‡ˆ‡……ˆ†‰‡…ƒ„„‚…ƒ„†‚„…„…†„‡†………†ƒ„…„…†…†„ƒ„……ƒ……ƒƒ~€ƒ{€}}‚}€}~~}}}}{|{zyzzyzz|yzz{{{}z{{{{}~}}€}}||}€}|†ƒ†††††ƒ„‚…‚…€€€~€‚|~~€€‚‚„…ƒ‚‚„€ƒ‚€„……‚€‚ƒƒ„…†ˆ†…„†‡…‡……‚ƒ‚‚ƒ‚‚…ƒ…„…†„††‡††…‚„„ƒ„†……ƒ„„ƒ„ƒ…„€€‚‚}}~~€ƒ~{||€}€}}ƒ|~~}}~{~{{zy{zyzz{yzzz{{|z{|{{~~}|}||}€~€†„……„‡„ƒƒ‚†‚ƒ€€~~€}‚|}~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡…„„††„…ƒ…‚‚‚ƒ‚„„„……†‡‡†…„ƒƒƒƒ„†…„ƒ‚ƒ‚„ƒƒ€€~}|~~|ƒ}|~||€~‚}‚|~}}}||{{zzzzy{zzzzzzz{|y{}{|~€}~}}}€€€†„„…„…‚ƒ‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„†„‚ƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„„…‚‚‚ƒ…„‚‚€…ƒ~€~||~}|~ƒ}{~|}€ƒ}}€~}|||}{{zzzyy{yzzyzz{{{z{}||‚€~€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌËËËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFL=8765999<>9?<D:;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937677=;>9=:::88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<9<<98:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA><A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÔÔÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9?CE@<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËÊÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø××××ØÜÝÝÝÝÝÝÝÝÝÝÝÝÞÛ×Ø×Ø×××Ø×Ö××Ö×ÚÚÚÚÚÚÚÚÚÚÚÛÜÜ×ÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILO@99:4;A<7=9AC>@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÏÐÏÏÏÏÏÏÏÏÏÏÏÏÖÞÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¹³xssssssssssssp’»¸¸¸¸¸¸¸¸¸¸¸¹°ŠŠŠŠŠŠŠŠŠŠŠŠ‹‡½æáââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVN<::77>C>8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÌÐÒÒÒÒÒÒÒÒÒÒÒÒÑÞìëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§£££££££££££¥™2)++++++++++*%a©¤¤£££££££££¥•SRSSSSSSSSSSSKªòëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;@C>6:7>>;=B?9<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÌÌÑÒÒÒÒÒÒÒÒÒÒÒÒÑÝêééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤¦›8/00000000000+eª¥¥¥¤¤¤¤¤¤¤¤¦—WWWWWWWWWWWWWO«ñêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;>@@8:;8<;;<?:;;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÍÐÒÒÒÒÒÒÒÒÑÑÑÑÐÜèççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©« E=>>>>>>>>>>>9n¯©©©©©©©©©©©«œbabbbbbbbbbbb[¯ïééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB?;=:9;:==;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÎÎÎÎÎÎÎÎÍÍÍÍÍÍÎÏÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÎÎÏÎÎÏÎÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÑÊÊÊÊÊÊÊÊÉÉÉÉÉÉÌÒÑÑÒÒÒÒÒÒÒÒÒÒÐÍÍÍÍÍÍÍÍÍÍÍÍÍÍÔØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<8@B<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÎÎÏÑÎÎÐÓÐÎÒÔÕÔÐÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖØ××××××Ø×Ö××××ÖÖÖÖÖÖÖÖÖÖÖÖ××ÖØØØØØÙÙÙÙÙÙÙÙÙØ×ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?79:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÎÎÑÁ§ÑÒ¹¾Ôœ‚„ŠÆÏÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<>B>BC@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÎÏÏѝÃ”°œ±–¸¹¯¡ÒÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?>;7:>9?D>A98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÏÏÓº¯ª¾¤ ‹‘Ó}~¯°ÒÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<<:6?B@C:647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÏÏӟ±›¸›‡ºÔÒ͞žÃÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8FA?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÏÑÀœ‰›°›Ÿ ÒÓÀ  ÐÏÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<>=964:99::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÏÔ£¢žª«¯‘¡¹×¯¢©ÔÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:=?>=<9@<<::9?@>=<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÑğ{™–¢š­›©Ø£¡ºÔÑÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CFCAB8;?<=;<<8558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÕ«¯¼Àх•¦Å˜¢ÑžŸÉÒÑÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF@HIGE@<<>><=><756:969;::;8@?:<<9<>=;;:?9?;;9=>==;;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦Õɇ…Ÿ Ÿœ››­ÇŸ¡ÒÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;547<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡ÆÓÓ՜˜Ã§«¤žÅ´¤¦ÖÒÒÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKL@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÒÑÒר‡Í͒§×¹ƒ¿ÕÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<=?GFHKH=657:979:;:<=9>99:8;=>>A>=9<<:=>>:=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÑÒÏÅÔÔ˽ÕÒÑÂÓÒÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?AELLA>775;8899:;<><>8::9;>?@=>>:5::<=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÒÒÓÔÒÒÓÕÓÓÓÕÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEJ>>786977899;;=?@<=89;;;?><<95:=>;99:<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9599:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9848<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EILAALD??;:889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEGIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDJ;AA;<886486987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGIB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<BA<;876797799=?A?<:9@?<>B?;8776=??@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE>;HF89757875898;>>=;89A>=@?A>7596;>AB??@@BB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCEFC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELCA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<;DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGGNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAC?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995687673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785667784;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€ihxsg~‰‰xp‚†{w}~…Š½ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€ƒvt|„‚}sp€Šx‚yƒÈÞÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsoupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964777:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿¼½¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»ºº¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjdmgb\XQPQKTJB:IQ?A7<94:565455688686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸········¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®xpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µµ¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸¸·¸¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶·····¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨¨¨¨§¨©©©§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸········¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥£¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§§¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©ª««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤££¢¢¢¢  ŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž£¤¡žžŸ  žœœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=7789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥¤£¢¡¡¡¢£¥§¦¦§¬¬§¦ œ›¡¡ž›ššœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¥¦¦§§¦Ÿ›š›¢ ™––•š›™——˜˜šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜—™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥¢¢¥¦¦¥¦§¦¦ ›™›¡ —““’—šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB@DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥¦§¦¦¢œž¡Ÿ—‘‘”—›˜–––˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;;;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¥¦¥¥¦§¦¤¥¦¦¥¥£  ¡¡Ÿ™’–š™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šžŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡ ¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢¢¢£¤¤¥¦¥¤££¡¡¡žœš•“”˜›š›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œ ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸŸŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::88:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸ   ¡¢££££££¢¡ ž›™™˜™™™š™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢ ›ž ¡£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œž››œŸžœœœœŸ   ¡¡¡  ¡  ¡¢¡¡¢¡Ÿžœšššš›œš™š›™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥£¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¡¢¢¡   ¡¡ ŸŸžœš™š›››œ›š›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›šœšš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>98;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤£¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ žžŸ     Ÿ ¡  Ÿž›š™šš›››››Ÿžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›ššš›™˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9;;>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœ›œžžŸžœšš›œœœ›œœžžœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:=>:?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››š›œššš›œœ›™™œœœžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™˜˜ššš™™™˜š›œœœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›š™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š››››œ›˜˜˜™™˜˜™™™›œœžžžžžžžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ›››››››™˜˜˜˜˜˜˜™™œœœžžžžžŸŸžžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ››››››š˜˜˜˜™™˜š›œœžžž  Ÿžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_]]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜™——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœšš›››››˜˜˜——˜™››œœœžžžžœ››œœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±³­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=9F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œšœ›œ›˜™š˜˜™ššš–‹“–™˜•˜˜–›œ—•’‘’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨©¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‹‘‹ŒŽŽ‹……‡‹ŒŒ‡ˆ‹Ž‹‡Œ…†‹†ŠŠ‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VPQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹‹†Š‹‹‰†„†‚€‚‰‘ƒ€ƒŒ†‹‰…€‡}€’†„„†ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹‹‰‰…‚}s}ˆ€~œ„……‰‹Šz}}†ŽŠ†”‘‹—”—’˜¡–ž—•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¥›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ†‹†ˆ…„ˆˆ‰„‚z||}~’ˆx…‹Šƒ„…ŠŒ‘™””” ššŸ¢­±­©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPFMHSWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‹‡Œ‹Š‡’Š‡†‘“‘‘„‡}}ƒˆŒŽ‹ŽŠ‰Ž””˜‘•›š¨®²¯¯µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWLO_^\NUTbQDTM;?9<895775795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš˜ “—š ™›£ •› ¤£š“ˆˆ‹‰‘‘Ž‘Ž‹˜šŒ”š—œœ›Ÿœ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUKTOOJCPK_bXZQ\S_MHQIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ª©¨§¡¥¨¨«©©¯¡›Ÿ¡££ šŸ œ”˜”˜  ¡¤ž›š¤§¤©«®¬¥£¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdVOXKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®ªª«¤¡¢¥©§§©¨£¢œ››¤ ¥¨£ ˜™Ÿ¡¢©§ ¢¢®¬«ª§­®¨¥¤©©©©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_UZNRNPORd\ec[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢šœ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨¦¥§¨¦©¨£§¦™œ¤¥¢¡ ¡¡ œ˜™Ÿ ¡¤¤¢žž– ›š¢¢ ¡Ÿ ¢¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOWO^ddlhbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤Ÿ¢ ¢¦¡¦­¦¦ŸŸŸŸŸ™šœœ¡ ¡¤Ÿ¡›šœ ž¡Ÿžž £™–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvwa_\UYQUV[c^r_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?C?:8:>?C@DA:;><@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯«ª¬¨¨«°©¨©¨¡Ÿ §©­°²¯¬£¢¦¡©¥ž¤£¢¦ ¥¤¢¥£ž žŸ¥¢¢žŸ¢˜•žšžŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸ ¡¦¢›—’šš •|wo}yf[[`_Z\V\hdocnihb^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¢ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£Ÿ¢ª©§®·¶´´¶³¯¬«®«¶°©²±­®§¦ž¢££›œ—¢¨¥¡Ÿž£›ž¡š–¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¢™˜¥ ¤§ª©¨ª­¬¥©¤¥©§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxib[_^\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>AE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢œŸª²¸¼¼½»º¿´¯±³µ´··¯µ´µ²°¨¤¢Ÿ —•š—¤ª¦¦¡¤£¤«¥¥˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨©«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥ ¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxyxc[RYT__alhukpgiibYSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶³º±ª®´±°±´´¶¼¼¾¼¼½Æº¸·º½´¯µ±±º¸·²³²ª¦¦Ÿ˜¤¤§¨¤®¤««µµ®³ §ª¬§ª©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš“–””˜“š˜Š‹‡€€|‚xa^YSah`fsositdidb[LK>:8898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÃÆÃù½¿ÀÀ½¿Ä½¼º½¾´§ª˜±À½¸µ¹À³¯¯ªª¨­§§¤¯§ª´¼±´µ¨¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`a^^jbbnwuvnl[bQU\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAB;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–•–‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±±§¼¼¾ÅÄÆÉÇÅÆ»ÄÀÅÆÀ¹¯½¼À¾¾³«ªŒ³»¾´µ·Âº­¯°µª«¦ª£­¤§±¶«µ²­³­¨®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|ƒjfhaklfnuqruqf^_\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÅ¿ÃÂÆÅÀ±“¾º¿Ã¶¶º©´³´©«³»»±Ÿ›±¯¬¤¬®´§ª©¨ª­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|tkkndolhqxoyiia\gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÄÄø´À·´¼Á¹··¿À»®¥®·¼·­œ£·°¦­´µ¬®¥¥£¨¤  ¥™ª³²¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyz{vnkhguZfrwsxfg]d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÉÆÃÃÄÂľ¸¾ÁÃÀľÁÏÏÎÆ«¯¶´µ« §´³®«¸µ³«©£¢­©¬¦­Ÿ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuueeijh]jomxwcb``^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÏÏÌÃÇÆÈÈÈÇÉÇÅÉÇÈÇ¿ÅÇÄÄÇÈÊÒÏÒ̼¸¶´¸¸Á¾¾º½º¼º¼¬­¦©»º¹·À²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqobagugiitmxl]d[U`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÍÐÎÇÌÉÂÁÆÁËËÇÆÌÉÍÅÆÆÃÆÅÉÍÐÍÏÌÇÄÀÃÂÉÍÇÅÁÄÇÁ»¾´±°°Á¾¿ÁÆ¿¾¸·Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`jjvlietnsb\bTWTSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<:>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÅÇÈÆÒÉÁÃÄ¿¿¾ÄËÈÊËȼ»ÈÇÉÍÈÃÈÉÉÆÅÃÂÁÂÇÇÉÊÇÌÈÇÈÍÆËÏÅ·ÀÀÀÀ»»½µ³³¿¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrofegcjdajmnn^X\VUNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾÆÁ¹»Ãº¸¹¼¾ÁÆÁƺ¹ÉÉÃÅÄÀÄÁÂÁÄÁþ½ÂÀÀÁÂËÃÆÌËÅÈÑ°¾½¸º»¼¾·´°¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfadbabccjbfcZYY\YQNE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶·´´µ¿º½À¹½ºº´¿¸µ·³¯»¼·À·½Â¿Á»¿Á¼»Å¾»ÁÄÀ¾¾¸¼ÁÁ˾½ÉÄÀÀÊÀ±Á¿»¸»¾¹µ·´¸¼´½¸µ´°³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|y‡}qc`bbgjffiei]VUSYOSKE8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“’’˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´´±°µ·µºÁ¸¾¸¿¼½·µ·°®¸¶¹¿»À¿·Á¼»Ã¶ºÈ¸¶¹»½¹º¶»ÅÅʽ¹ÅÀ¿¼Á¾¸Æ½ÁÀ¼Å¸¶·´¸¶¶»»¸¶´·ºµ´¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒ€xpmeefoiekgXXNKKKRILHC9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’š”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿½¼²­¯¬±°·¼¶»¼ÀĹ···µº¹º»À½ÃÀºÄ¾Ǹ¹¸­·µ¸º´·³»ÅÆËÁ»ÆÀÀ¿½¼¿ÉÃÄžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~†|knpgpksebm_\THKJDJBCG?9;8=<7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘ŽŽ˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼¼À·ª­¤®°·»³½¿»Ä·¶¸¶·¿¿Ä¼ÂÅÅÇÇÊÉÆÏÂÁ¸®µµ¼¾¸»²¾ÄÄÊÅÁÉÿ¿¾½ÇÌÇÇÄǽµµ¶Á½º»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†qelintnwcga\cQKTHEECGC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?=??FD@A?>:7?@CC?A=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼«ª£°¹½¾³¼¾¼Å¸²¸¹½ÇÉÊÃÇÈÆÆÉÈÌÎÑÌÊĵºÀÃÈ¿¿µ¿À¿ÆÆ¿ËÆÿÁ¼ÀÃÌÊÇÅÆÁ¹½¼Ä¿À¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtolltkln_b^`aNHM?E@?DC;;::;:8;<:9<>9:>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´¼Ã¼ºº¾¼Ä¿·½¿½ÇÌÆÇÉÆÆ¿ÄÄÊÈÌÌÍËÆÂÃËμ¹½º¹ÀÿÈÆÄÁÁ¿ÅÀÊÉÃÃÃùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{z‡zmmw{_pc[]_^SI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA>>ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸´¼¶º½Á¼»¿¶¿Á¿¼¿ºÀËÂÇÈÀ¿¼¼¿ÅÂÇËÈÁÃÀÀÉÊÂÀ»»°´»½ÀÅÆÅÅ¿À¿ËÇÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}‚zmsxsgp][^\YQEDCMIAD=G::59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘–žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯·¶²µ³·¹¼»¶»»½ºÃ»·½·¹À»º¸¸µÅÁÃû¹³´ºÁ½¿ÇÀ¹À¼¾ÅĽ¾¹²°®¸·¿ÃÇÃĽ½¿¿Ãþ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸¸¸½¹»±¶²ÈÀ»¶´±°·¬³©°­­³·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|vluzpni\__YSPAEHGK@DCH<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿš›œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹ÁÀ·½¹¸¹¶µ¿³´²¸±»ÁÀ÷·­°µ¸¸¸Âº´»·»¾À»»¼®¯®³²¹ÁÂÄþ¼¿»º¸¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ¯µ´´½º¾¹º»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰|‚zsvvwnq`_e][TJ<>?FF=FCC9:5;99><<::<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Ã¿·º·¶¶²´À¶²´¸³ºÀÁù¸³²²´²·¾º³µ²¼º¼¶º¾²´´´°¸¾ÃÆÄÀ½¿¹³¯²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtvrl^b`[]NHA?=HCFMD@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·À½»¼¸¶º¶±Àº·¹¸¹»ÁÁÄÄ»»¶´´°¶º¶´²¬¼¹¸µ¸Áº¸³±¬·¼ÁÇÿ¹ºµ®¥¬³°¦°­¨ž Ÿ¥­¶µÂ·¶´¥¨«¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´·¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wo{ournc\fX\]RNMA>JB@JI@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³±­¶º®¬¼²¸¹·»¿½¹¾À´¿»¼º¸¾Â¼ÂÊȾÀ¸¹¶²´¶³´¯¬»º¸¶¹Àö®®ª²¶¼½¹¶²±­­Ÿ¤§§£¦–™™šŸ©®¹¬««Ÿ¥¨¤«®®§¯¬¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmuik][jT]\OMHDFLAFMF8665:6:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹½µ²¸´¹ºµ¹»µµ³µ»¼À»¾À´¿¹¹º±ºÃ¼ÂÊÅ¿»¿¿¹´´³±±®°¹¹¶¼¸»¿²²²®±®¹¯ª«­¬£¨¡ž—˜¡•’•—˜Ÿ¨®¤£¤ ¢§¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬«¯£££¡© ›“Ž“’’™–š¤¥ Ÿž§˜•’”˜ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wrxhtsndT`cW\QNLH?HQDMC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®­¯²²ºº··µµ¼´¯´«¶º¸ÀÄÁ»µ¼½¸²­³°¯¬®¶¶²´´¯ª¤ž›œœž¨¨Ÿ ¨©Ÿ¡§–›——“–Ž—›¤¨  ¢¢¢¥¥££ ž¥ ¤¬¤¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›©¨ª«ž¥¢›£œ•Œ“—•–˜Ÿžžš™¦—“’–¢ ¥£¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦ ˆxƒ|vybwln\QhTPNGOMLBOQ@>;>39:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¥¬ª¨µ²±°®¯²§¦¯£¯®µÁºµ·²·¶²´«²´®ª«¯°²³­¥ž’˜”™ Ÿ¢ œ¤¥Ÿž¨”›–—Œ—‘—“˜¢ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£ž™—š«¦©°£¥§ž œ•“‘˜–•˜—Ÿ˜›™›£™—”•š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’}|€uu}mk{dhUQcMIHGNRNJNG;D@=2?859;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜˜—–¡¨¬®¶·º¹º··»®¨ ¡©¡ ­«ª¦©¤©£¤®¥¬¬´¼·¬²±¯±­µ¯¯³µª§­¬£œ™”Ž‘–—™™œ £¢›¥žš¤———–’‘‘“š—› ¤ªž¡¡ž¦§ª¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¡¤¡›˜ž¯¨®²«¥ªª š˜˜˜•“–š“••™–›——˜ žœœ—›¡šžš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}vx|dxy`bRU_HIIKSTIRPL8>B67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—““œž£¨®­¬««¯ª¯©Ÿ—ž¥žž¥¦¤ ¢Ÿ¦ ¢®«¬­µ²¶¦¯´«©ª´±°°¸­§¡œš”˜›š‘Ž‘•‘ŒŽ”™¢œ—£™š—˜™”™˜–›Ÿ¥¦© ¦£ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§  £±­±±´©±¯¢™œž¡™››š˜™›”–›–˜œ¥¡ š£¡š™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ Ÿž ¥¡žž¥ ¦™{|uvsh‚le[SZYMQJNNULRLA7>B78=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=?758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’’œ˜¡ª¢§ ž§¡¥Ÿœ’œ¢›Ÿ¡£ž Ÿ£ ¢¯®¬¯±¬¶§­±­¦¦°®­¬°§ Ÿ¢ —‘”œ¡œ™—’“Ÿ¢¤›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬¨¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½·¾°¬±®­©ª´±°¨«¨²µ·³·¬±´£ ¥ ¬¡¡¢  š˜––Ÿ››˜¤¡ ž¤¡ žšœ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚|xuiwu]lZR`HQUHFUVJBMG=JH8E<67;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›Ž“ž™¨®ž§žœ¡žš™’™žœ¢¢  ¢ŸŸžŸ©«§¬©ª´««­«¥¥«¨ª¬ª¥Ÿž™’’”˜™–––Œˆ‹Ž•ž–žš¦  ¨¥±ª§®£«­¶°´²±®¶¸½Àº­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«¯±¹·¼¯³°µÁ¼·½³³µ¡«¢©¨²©«¨§¨š™žšª¦Ÿ™§ ŸŸ§¨¥¤žª¢¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰…„~vqmivmhm\X[BVMJGMGBFM<>L=4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜šª ±¢·£°¦ ž—˜–™ž›œ¤ŸŸ¤šœ¤¢¤£¢ª¯¬§©£ ¡¬®®ª«¦ žž¡£žžž›œ”“•”žž˜”†žš¡›«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶ººÀĹ½»¬¯§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¹Â¾¸´»Åü»·³©²­ª³´¯³®ª®£«§¶±¬¢¯¥ £¯±­°¤¤¯£¡ š¡§¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¥ž¦™›¢¤žŸ›››œ‡…{trkkurphW[QETHDIOH>EA3EH95;=6;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž ¡œ˜›Ÿ › ŸŸ—¥•››Ÿšžœž¥¦§  «±®§¤¤£ ž¥«¥ž—œ”‘™˜”ŒŠ†ˆ†ymˆ ¤¢«¬´¼¶Ã¾¾³»ÁÃÂÅÀ¿ÂÆÆÅÃÈÂÀÅÈÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌÌÌÒǾ¿À½ÇÆ·ÃÉÈÂÀž¹´¹ºµ»·°µ²ªº²®»¶¾ººª·­«ª¸º´¼®­¸£¥¢ž§¥¢£©¦™›Ÿ˜š§ª§ ¡¡¤˜”£–”š‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ„}zrkdhoxjeZ[FJLDDSLDBD7:?;549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”••š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ³²¸§¡¡«ª¢ž¡¢žœ› ’ŸŸ–Ÿ™’š–›™£¡¯³©¡šŸŸš—˜—’Œ–—“Ž‹‚ƒ‚wsqnp¦­®´¹Å»ÍÇË¿ÂÌÎÍÌÈÉÑÌÍÌÇÉÅÆÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÒÓÌÓÐÓÓÌÊÂÅÆÆÊÇοÉÐËÆÄÆÄÁ»ÃÁ¾¾¾µ½³­¿¿ÂÃÆÄÇÄ®¾¸²¸¼ÄÁÁº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›‹™‰•˜› Ÿ£—žš““‹•…€ytsebgrof^ZYCNLCEPIDB@55589B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>8;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›£¬žŸ®¦¥±ªÅÆÌÎÍ¿°Â©¥¨­­ª¡£Ÿœš©“™¡Ž “”’—™¤±±«¤  ›™—”“”–‘Œ‡„ƒˆ‡ƒ€€yrroly¤¶º¹¾ËÁÓÒÓÈÍÎÑÓÑÒÑÐÑÑÍÎÎÐÅÎÔÕØÒ×ÍÆÇÉÌÃÅÊÏÊÓ×Ñ×ÒÔÕÓÓÈÌÇÍÍÉÒÌÎÓÍÄÇÉÊÁÅËÆÈÈž³³ÇÄËÊÊÎÅÊ¿¾¿¼ÁÇÄÌÌÈɿÿ­°³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›•Œ†‘‹zruugcgvidVWQDMF@IQB=B<:23@<D<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<@?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­´¸¬®£Ÿ¤£Ÿ ¤¬›–©–—Œ—¦°®¥ž¡¥¡ž›•”–”Š}wpkebhqoq{…Š€vpnqtp…³Â¾ÅÑÐ×ÖÖÒÖÍÔÖ×ÔÓÑÓÔÔÓÏÒÃÐÓÖ×ÕÖÒËÉÎÑËÆÍÒÊÒÕÖÙÕ×ÓÖØÎÒÉÎÑÌÎÐÌÒÏ¿ÇÆÊÃÌÌËÎÏÅÆǶ¿É¿ÒÍËÏÅÉÈ¿ÃÂÈÎÌÏÐÏÌÊÇ͸·»¨Ÿ¥«§Ÿ˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„|wsvoc`erb]R\IJFAEHI>;@8=4585:76:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢›©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´¶ÂƲ¶©¢¥¦¡¢«µ§š±¡•”Œ¦­«œ•˜¡›¡¢Ÿœ›•Šwic`____^_`^blusqpolrqu’ÄÇÆÔÕÖ××ÓÖÏÕÔÚÔÔÏÏÕÔÔÑÒÌÑÎÓ×ÖÓÕÐÏÒÓÑÉÓÑÈÐØ×ØÑ×Ò×ÙÕÖÌÎÏÉÍÑËÎÏ¿ÅÂÇÅÎÍÑÐÑÈËÌÀÊËÅÓÎËÎÈÄÉÆÆÈÌÊÓÓÑÕÏÒÌÒÁ¹Å±¥¨µ®§š¨¬¥²¨°³¬¬““Žˆ‹Žƒ‹„Ž™“™‚…Œ{zqstmacim_VP_JJBFCQM?<>44:=52755<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><??=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡© ¯®ªª¬ž¦®¸¨«·ØÔÕÙÙÑÎÐÀ¼ÌÉ·À¯§«©£¤±¶³£¶©¨¨¡ª©¡˜–˜š›¡žšž”~recb__a`_a`_``_`fmppnkorww›ÌÀÒÕÓØØÖÙÑÒÒ×ÏÓÎËÓÍÕÔÒÊÏÌÓÖÒÑÖÍÏÕÕÑÆÑÔÊÑÔÕÖÎÒÐØØØ×ËÈÍÃÉÎÌÉË¿È¿ÈÉÍÍÏËÐÍÎËÎÏÇËÏÐÊÎÊÂÉÆÉÌÊËÑÒÌÓÑÐÏÏʽȹ°­»¸µª¶°­¨¸­³¿»±šŸ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…ˆyvopnkadnpaW\ZIFFDLWE;@<33<=86855;>@=9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›ž£§ž¸¶µµ­¥­®¾´±ÀÙÒ×ÚÜÖÏÍËÃÓв«­®¬¦³±¸«²Î¹«Ÿœ–”—›žŸŸ”–—•‰l^^^adb```a``a^__^]bmroostvvy¤¾ËÕÑÖÔÓØÖÎÎÔËÍÎÅÎÊÒÒÏÆÎÍÍÔÌÎÓÍÊ×ÕÐÌÑÔËÌÐÑÓÊÎÑÕÒÕÕÊÀÊÁÅÌÂÈÉÂÌÃÅÈÊÊÎÊÌÌÏÍÓËÅÈÏÌÈÇÊÄÆÀÅÉËÍÐÑÆÐÎÍÍÌÏÅÇÀ·¹½Ãýù²³¾±¼Äĵª˜¥¡™–‘••’‹”›‘”””‚‰…xpqknh``qhYXhVMGLIPPB;D>;67:89:56==A;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÅÃÁ¿»µ²±ÇùËÕÖÙÚÛØÌÌÏÉÖÖÅĸ²¶ª¤®¬¹¹°¶Õ¡•Ž˜–“’‘–––Œ|ebbb`]^acb`_``aa`_][]grqqrsqmry¤ÆÓÏËÐÏÔÕÉÅÉÉÆÆ¿ÃÆÏÎÇÅÇÍÊÒÈËÎÍÆÑÒÏÎÌÔÊÇËÎÏÇÇÏÒËÐÏźľÆɽÂÆÈÎÄÂÇÀÇÍÇÃËÉËÏÇÃÃÏÈÆÁÆÇþÀÇËËÌÎÂÊËÈÇËÐÄÅÇ»ÇÃÈÈÂÏÀ½¼¿°ÁÊǺ½ª±²§¥¢œ˜›¤™—™‘•˜‰‚wntdl`^fqa[W`GHHGIMTG?J=64355=<48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥³±¬ÉÍÊÈľ½ºÍÍÆÐÕÕÙÚÛØÐÊÐÐÒÔÊź¾¾°¨·«¾º·Á®‘ŽŽ–†ƒ„„‚~……t`[^^^`^`cdc_]]^_``_[Z\akrrookloo}¸ÑÈÉÊÏËÍĺÀû»ºº¾ÈÆÂÃÀÃÇÊÉÈÊÈÁÅÌÆÈËÍÉÄÂËÉÂÂËÐÄËÈ¿¹Á»Åǽ¿ÆÏÊÿûÉÆȺÇÆÄÊÀ½ÁËÆÅýż¼¿ÃÄËÅżÀÉÂÅÇÒÅÀÈ¿ÊÊÆÈÆÐÃÃÆïÄËÇÄÊ·¿¼º´©¬¥¥˜Ÿ˜¬£¡¥š£ ›”{vstfj[anmZ[XQDLFBGDLDFS@54334?<3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ÊÏÑÌÇÂÃÇÍÏÎÍÕÐÖÙØÙÐÍÔÎÏÐËĸÆÁ¶µ¼±À·º°‘Œ“—‡{€…†€vxurp_Z[]`abcdded`\\]]_^`[YZ\borokilposÆ¼ÉÅÌÀƱ¶º²²³²±Â¼¼»¹¸ÀÁÁž½¹½¿¹ÄÊÅƽÆÀ¸»ÄÉ¿ÂÉ»·»ºÅþ¼ÁÍÂƾ¾µÀ½Ãº¼Æ»Â¹³¼Åö¿µµ¾¿ºËüµºÈº¿½ËÃÁÅÂÆÈÆÈÆÐÆÂÌȲÇÊÃÎÍÁÅ¿½²·°³§¨¨¹±¥­°«­¬”yvwjeh`hocV^YJEJFHKAFBEI@9:648853;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÆÂÄÈÎÒËÊÊÇÍÎÏÒÉÑÆÖÕÖØÎÌÐÈÍÈÊžÊÁ²µº·»¶°‘Š‹…y€††€~„|tud\\]^``bcbbeeb]][\^\^]Z[]]hsqmggnpry½ÌÀúÁ¸®°°§ª­¬§¸´·´³²³ºµ½±·°µ¯²»Â¼Áļ¿»µ²º¾À¸Ç¹´»¶À¼·½ÆÀüµ®²¶º¾³Ä·»µ«¸¼½À½°ºµ¯¶º²Å¼¶¯»¿´¶´Å¼¾ÃÅÀÃÅÆÈËÆÀÆÆ»ÈË¿ÏÊÇÃÆÁ÷þ½¶¹¾Æ¿¬µºµ·¶Žxtxggebkn^V^`FKHHJFBCAEE?<:565633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÎÈÆÉÎÌÐÍÎÉËÉÌÊËÆÑÏÓÑÏÈËÆÊÆÄÀ½Ï½³¹½¹¸·œŽ‡‰‰{y~††wx‚}th^]]]_`_`da^cec__\[^\]^Z[[]_lpnhfjnnr|¤Ç¿¹¸µ°¬¬§ž¢ª§ž«¬³­©«©³®¶°²©®¦¬²¼º¶Ã¹ºº±ªµ¹»´Âº°¿±½½»µ»Ç¹Â·­ª¨°±Àµ¸¼¯°§±³´»¼«­µ¥®¶®º±°ª¹¯­»®»¸»¿¿½¹Â¿ÇÃÅÁ¼ÆÁÈ˸ÅÇÅ¿ÇÃúÄÆ»ÅÉÌ˳¹Â¼º²ˆrvvkiablhYXW[ALKMIEAC?FA:9:995854::9;<=;:;>8;@<=9:79>9;<:8;;:>=9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÆÏÒÌÄÆÁÅÐÈÏÂÄÇÁÆÆÅÅÌÄËÌÂÄÁÈÁº¼»Ê·´¼½¶µ«‘‰|y~Š…z{„wn^]]]]_`__dcbccb`_^[[ZZ]ZZYZ]enohfgiknr­¹°µ®¦¥§§š ¤ šœ¥«®£§¢«ª¬ª°£¦Ÿª­µ¶±½¹¯¸¯¨®¸´´¼¸³¼¯·¹µ±»Á±Á®¥¨¢¬±²³§¼ª«¨«¬­´´¦¨®¡¤¯©²¥§¨®¥¨·¬°²·¹º»±¼½¾¾Ä¿µÁÁÇÈ·¿ÀÅ·Ä¿»¿ÄþÄÈÌÊ¿¾ÃÀÀ©†rtrji]aodWVXPHZRSKFFE>?@9789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·ºÄ°¶°›™•œ˜ª©°±³µ½¯ÆÑÐÍÄÈ»»ÌÃÌÀ¼Ê¹ÀÆÀ¼ÌºÃÇź½Ä¾º·½Æ¹¶¹»®²•ƒ‰{~€~xt|swf_]\\^_`^_ccab``_^]\ZXZ[[YXZ\_fkfegehkor…ª¥¬¦ œ¡¥”ž¤›—‘¡£ª£¢Ÿ¥¥§¥¬ ›¤¦¬²¯¶·§°¬§ª´«´¹°¶´¬¶¸±°º¹±·¤Ÿ£Ÿ§±§«¨¹ª¤¦§¨§²­ §¦Ÿ›¤¦¬žŸ§¤Ÿ ±­­¬²´²´°µ¼¶»ÁÁ²º¾ÃÁ²¹ºÂ³À½¿µ¸»½¾¼ÂÇÄÂÿ¿Ä ƒwpkae_ko`UY_HNhOTGEJF<=?=:;;825536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;=:7776788666;::;9:;<859<:>>@;Èµ¶½¸ºÁ»¾µ ž•ž¡¦º¶«³³»³ÅÐÉÌÃǹ¸ÉÂÎÁºË¹½È»·È»·ÄƳ¾Å¼·°¹À»±³·°¢„‡‡‚}yvtomkjjqi_`]\\]_`_acb````]\[\\XYXXXVX[]^dcbegggjmoˆ© —•š¡–›¢˜•ž¡¢¦›ŸŸ£¥¡§ž›¢›Ÿª°­±µ¢©ª©«¬¤µ¸­·¯¬²´®²µ®°ªŸž£¢²¤¥©¸­¡¦¦Ÿ¨¬«™Ÿ ž™Ÿ¥š™£œ›¯©«§ª«¬­°²¸¯¸¹»°¶»»º«²²¹²½´¶±±µ´¿¶½À½ÃÁº»½—ƒzrk_e^ddXTX^IW]KPGIJFA<??@;?<04535:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»·ÁÁÁ´¤¤™›¤¦À²¯¶¬´·ÆÐÉÉÁǼ¼ÅÅÐÀ¼Ê»»Á»¶Å¸µÁÁ³Âļ­ªµº·¨±³©‹†ˆ€ysnpnkb^bff]]^]]]\]_`abccba_\[[Z[YXXWWWXXX[^bddeffhikr¨”””›˜›¡––œ¡¡¨›¥¦¡¥œ  š˜­®­®² ¥¢­«§¡µ°±±¬§®²§º³¦¶¡¢žš£¢­¢¡©µª¢£¦¥¦£–˜ž—™šŸ™—œœ›¬¡«¦£¤¦­«³³ª´°²ª²¹´¯©¯²²²·³®©¬®²¸°º¶¹½¿·²±”…yue^e^[YVSZUK[QLIEHKIB=?AA@@:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½¸½¿¶¾½¿³¥£˜¥±Âµ¶½­´¸ÃÍÉÈÁƸÂÁÈкÃÆÀ¶¼½¶Ãº¶¿Áµ»¿»ª¦±»±¨²¯›}……€ypqtqhfdiec\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXXVWadecdeddhjv¢œ”””–—Ÿ—™”˜Ÿž¡œ–¡¡¨£Ÿž¨œ›šª¦¯°«›££·ª Ÿ®¨¶©¦¦¬°£·°¤· ¢›˜˜ª¦¡›¬¸¯¢¡¤œ¡Ÿ “•¡”––›˜—–—œ”Ÿ©©£¡£ªª°®¨´«ª¦­²°¥ª®²±¯°®¯¦§§²®±´¯¼´¹·®£”yud^aVYWSRTKM^LPKGGLKE<@><B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾¸¼®ž§§£ª»À½À¹®´¸ÂÍÈÇÄžǺÊ͵ÄÅű¿À¹ÀÁºÀÀ¹º½·¨¨±»¦©¢¥‰~xrjlrtpihedgb\\ZYZ\\\]^]\[\^\[\Y[\ZXVWWVWXWWWU[ccbbcbcdfj–“•‹‘”“›™œ––› œŸ• Ÿ¦¥¤¦§ŸœŸ¤Ÿª¯¦Ÿ¢£¶¨ ¡¢¨³¡¥§¤¯¥°­¬µž •”©¡¡”¬±°ž¢¢ž˜›“‹¡”‘“—˜’——˜–¦›¦¡¢™£¥¥«¤¥°§¥£««­¥¨®¯®«¨ª©³¥¦«¯´±®¼µ±¯¯ ’zvrda\Z]XNLQGRaMVPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8846863321./2556;:8;7876<;:;;A8x»»±µ½°»²·¬ž¤§­·»¼Áź±¹µÅÊËÁÄÇÇɸÈƵÅÂɯº¼Â¼ÃÀÁ½¼·º¶¦§²¶ž¢Š™ˆ€wodbgihfhjgjm`]\[ZZYZ\]\[\^_\ZY[YYZ[WUXWTTWUSTRU``_`a_`acdi”“‰‘Ž”’“œ”•–£™ –œ ¥¡­¥¤¤¢£¡›ªª¥™ž¥±©  ¤ª§¡ž¬¬©¨­­¢¡¡”—£›œ«©°›Ÿ¢žž—˜“Šž’’“•˜˜’›¡¢œ¤ ¡• ¡¤¦›£«¥¢¤ª£«®¤®±©¦¥¦¦´¦©¨­³µ´¹º¯ª¬ž‹rpo`[WVUQFQOHZ\ORITKSLEGIC8;;=<8667:9;:976977:;:=<<7;<8>598:88659:;<97?<9578452121..1426:8698598989;9@9{µ´­´»²°¬²­§§¯¹¹³ÀȺµÀ¯ÆÉλÂËÍÉ·Ë¿´ÀÇÌ°¶½È»ÂÇĽ¿·ºµ¥«°®š‡Žƒ|uijjmhjlnkkme]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURSOQY]\]^^^__bdmŽ„‘†‘™“”’œš¢œ› §¨ª¨ª¦¨¤£˜¤®¤”™¥¯©Ÿ›˜š ž®™›ª³Ÿ¥¦Ÿ££¡”“›–•’¨©­šœ ¡ š”Œ™Ž‹Œ’Œ–”¡ £œ›¢•› ¢ —¢¨£¢¨« «¯¤­·¥££¢¬­©¨«¯³¸²½µ³«¯˜ƒrrh[XYSUREYLP\YMTNPLPRINIB<??A?=65799<<987:79:;<=>;7;;:=67:;8976989:6:=99577570141-+/434988::8::748=8?9~³®¨³¶®©¨¯­›©¨¬·¶¬¼Ê»¶¿¬ÌÇƹÂÏÐɵƾº¾Æ˵±½Å½ÃÆĽÁ³¹¯¦«¯«ž—†wxoninnnqggigd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUTSNPQYZZZ]\\^_`d~‹‹Š’—‘—™¢ ›Ÿª©¦­ª§¯¢§™Ÿ¬ •–¤¨§—Ž™®–—§ª™Ÿ”¥¡ž’’’’•§ª¤™™š–Œ‹”†ˆƒ‹’” ž £—•Ÿ•š ¢ž“›¥¥§¨¨ ±°¦°¼§ £¬´«­§°´°¹µÀ±­±«}prbVTUNRIGVQSRLLXMJLNRGMKACFDC>@75889;9:7::7<=:;@>:9;9:?759:9876958779;85576761321-*.102877;99;8948;8@8³­¦±·ª¦¢°«ª§©²±¤¶Æ´¹º³Ëƺ¼ÃËÑ̳¹º¾ÀÄǶ´·½³»¼Ä¾Â±´®±®±¬œ¢ˆkhnoroqkpkdfge^ZYZYZZZ[ZZZ\\]\ZXXXYYWXWUUTRSUSVURNNNRWXYYYY\\]aj€zu‰Ž‡‰˜‰””—›™¨›Ÿª¥¤ªœ§˜ ¥›’ž¢š—–„ƒ‘š£“¢œ•–•‡¢šš“‹ŽŠ™£§œ••—›’‡”ŽŒ‹€Š’’‘¡šŸ¡•“˜˜•¢¥™Œ™¤¦¨¦¡ ´²§²·¡¢·¬ª­¤²²¦µ¼µ««±£ˆxrm]NPQLOCNNNPKFNNJJNMQIMJAGKHHC>858889:;69:68;99><8:>9;?8789:886857688974577820301*)-/12776:999984988A7w¶§¤¶°¤§¤©¥ ©¥¤³ª¢²Ãµµ²³ÇǸ»ÄÊÍǵ¯¼¿¸¼Ä³³®¶¢­µÄº»¯ª¬´¯¯ —¨}^`gsqvqjnifhhj_XYXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQNMKLSWWVXXYX[]aosvq…ˆ‚‡€‘ƒŽŠ”‘“ Žšœ¢¡£˜¤–¡›•‡˜šŒs‚}––…™“ŽŽ{™ŽœŒ‚Š‰˜Ÿ¢ž“˜–„Ž‚“~~t‰Žz†’š™š•Ž¢£Ž‰š ¡¤£›¢´¯¬¯¬Ÿ˜¥¹¦¥°¡°®œ°»ª©¯ª™vrbVLQOPMCSNLQMCPPHINSMHJJDJLEJK=749888;;69;7:<9::;79?9>@79:<89764445874312485/0102)(,-12764789::65:87A7w·¢£´¨¥¥¨£¦¥¦¦¦³§¥´À¸°´°ÊƹºÂÏÇ¿µ¯½Ã¯±Ç²­§¬•¤®¿¸±°Ÿ§­­«–•¢rWV_hgihincjhgb\XXXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTRMMJHNSSSTUUWY[]ilrm…|tNXr‚—†œ—Š“Ÿ—•”–”Ž–‰“‰_;Wo{‹“‰‹‘Œ…†sŠ„–y‚z…“”ƒ•Ž‚†}’xqo…~‰€—™˜“Šˆœˆž—‡ˆ–žš¡ —§¯¨­©¨Ÿ—­´¢¦­˜¬«˜§´¢©­£’}qm_ZNSQVLDTJPMLFOOIELQMKPJIMPFIH=7599999:7:;:>>8:==6:?8>?589;79675333760.-/344110//((++-3854779<:79;86A9x· £®¡¦¦ª §©§¢©°¨§´Á¹±µ°Éù´¿ÏÀº±±¸Ä«®É®§£ž†›¢º­§¨–¦¥¤¡—–iQMRVZZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MORMKHFHNQQMPRTVXZ`moi{‚tPB@•‘‘}‰”Œ„Š›–•Š’ˆ†•†yˆ`JQnxŠ‘„|„Œ‰„n~”wuvx„™pQˆŠ†{~x”vgw…ˆ~Šˆ•Š’–‹ƒ‰‡”„šŒ„’›–žœ”¤£§©¥£ž›°«¡¤¤¦ª–¡ªœ¢¦¨ˆtke][HQQSLIUMSILLPIHFKNLMTKQQOFIC<769:8:;;8:;8>?99>=7;<6;;478;7775344696/3/.125221/,')**,4833979:99::::?9v¶œ£§Ÿ¡®¡§¨¥§¨¯¬ª¶¼¶¸¶³Â¼·¨ºÉ¹·©ª·¸­¶Àª¢›“ƒ™²Ÿ¢š –™”‘‹ŒeMLNNOLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDDINOhYNQSTUZnƒtw~ji]U‰”‰t†{…Œ’’™‹{†uxsnupty}‰ª…yzhv{ŽprmxŠŒ’xz€{€vsr’wgu„„„„z•‰ˆŠŒ‹€„ŠŒ”ƒ{€˜”›•‘Ÿ¨žŸ ž ©¥Ÿ˜Œ§¤“  –ž¤qg`\\JVOQGKXROJMMRJJJMPHLQLRTMEHA<77;99>=:;<98@?::>=7==79947795675252572/2.,//200/-+(().1272198798775:<<7v®˜£¡˜œž³©¯©¥¬¬°±ª½´²¼¸¶ºµ² ·»³«Ÿ­«¬µ³¥ž–’˜†”¤–Œƒ—‰‰††ƒfJIJIGFHHPTTTWWSTUUUVWWWXXXXXYXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQRSV^uƒ}ygw—˜Ž}gyvx‰|„˜’r‡|v{ok~­|sŠ{†’€}tfv|…lohs|‰Œ‡€lyq}pmuqhq€}ŽpCŠ„‚ƒ…~wwz‹…}‹zu~Ž’˜Š’š›£—™›ž¢–Š¤›—Ž–˜ŽumkeaYWXTQJRUTOPNQVKNKNOJQOIOOKFD<;79;::?=9<:99??;8<=7<9999266856633621224.,,-..-0-+*''*.1362/876966527995y¦—Ÿž– ¦¯¬®«§©°¯±¬¼¸¬»¾¹³­¨›±¨­œ—ž§¬§¤›“ˆ–~Ž•’•€|Šz…€eJGHFB@CDILLMQRPQSUTTUVWWWXWYYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNPQTX^eprmˆ§ªÀ~uyb{xo|yˆy|‹…omŒ‘xsxjj‚r–‘‹}–I’˜nhw~licly…’†ksl|nr{†hmp~sˆƒ…z}~{vott…‚ywp|ŽŒŠ“ƒ–—˜š“–—™—ž—Œƒ‰Ÿ‘Š’Œ†–}lhmnmWUWTQQYOSUUTXUMNHMJMNKCINGE@:89;99:><9<;::=>:8:;9?868727575541442/024*+**-.+-*(*(',-1250,5567485HA895w™‘›™šž¤­¯¢­ª¨µ¯®¬´¿«¼Â¿¦£š•¥˜žŽ…Œ–¢¤›š”—v‘~…‹|x~t}xuw|fOEGD@<>>AFGGKKKMPSRRTTTTVVWWXYZYYZWVTSPLE1@š3 jrA™o;<95<€‚†_IMOORWZRY\`§ˆbšitze~pmz‹ˆuˆ†tl™‘ts{jkŽLy„’‰„Žg1v†sl~}ƒtfet~„„…€filukp|gpp{n’Ž{s}|qpnum‚~wytiy‰‚ˆ‰ƒ–“’‹‘”•—Ž€yˆ—ˆ†‰†‡uiingcWQYWXY[MPUVZYNIIEJJHGBAFDCG=998;9:9<:9;:::@<9:<98>787715244533645031.**+),,++)(+'),,226,+5775478iO8;5n’ˆ™‘š–¤¨­ž²ž¦º®«²°Â²»ÃǛ—”™‹Ž†z…‘š–’Ž’‰tŠ„w‹ŒvwuxvoxsiUFID?<;9:?@ADDEGJLOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOPQVLAIQIb¯³ q|xm}mqƒ…y„††yr ”tx€su”‡5q¨Ž¡¡„¢„vp†|‡|sŒ­ˆ€hfbinrmpƒuioXuoŽš‘vlz|mqmpzsumbv„†€…‘Š‹Š’‹‘Œ‹ƒux‹€~‚€}xpnnj^Z[][YX`_SN[[YXLHJFJG?CABG?CD=;97=;:;;9:99;:?<88=:8;66651121353475531./,,+)*))***)(*)+/3DM2166643<vR7=7b’’ˆ–‘¤§ž¯•¥´¨­±®Á³ºÁƗŒ”‰}n‚‘“Š„‹ˆˆv„…o˜ŠŒy{{q{t|ko^JPG>@7458;;<=>@BEHLLLMNPQRUUVWXYXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL7CMRSDJ†v€||v~lvˆˆ|}…ƒŒ~v¢™y~†€„™…›œa†ªŸ‹‚zv‰~‰ˆŽsŠ—ƒ{\dqtz{wŠlgiaxo…‚znws„zpsywkni]w‡}‡|ˆ‡€‹“—ƒ††}q„„|uw{}ˆtmqrde^ZZ]S[f^XQUY]VGKKELG?F@DC?AA=:97<;;=<::99;;=>79>9986754244004645654-,)+('''&(())((+++/00Uq<23331E~W4=9\Œw‰”Œ‘Ÿ¦‘ ªŸ°©¯À±»Æº–‘”ˆz†vk€Œ’ƒ~‹…y„‚u¢†~~‚€sƒ}lylSXLAE311266688:<?BEGFGJKMOPQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMORLKT]YRJi„ˆ{‰y{q|Œ{|‰†~—‡v¡™ˆ‡’”¥¬©H†­¯¯Š€€“Š‚‹‚„‘¨‡€˜˜Šœsl|†‡}Žhggx~n…†…q„†Gk€wqyvhmk_w}ƒˆˆ…Œz•žœŠ‹‰‘{u‹v|wmow~}qqpjZ[[ZcbWge\UPQXZQDLLGOICFCCA@CA=988:::;;:888::?>6;>7585773344236656768;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|~Š…‡‘–˜’— ¬¡¦¸¯³½´—’‹˜‹}tpŠ“~ƒ”•}†‡¥‡‰€ƒˆ†y‰‹€u…y_cVLC60./22123668:=??BEGHJLNQSTUTTVUSQOGC?80,#‡[>?84.]–ps£UFIKMNPW`YpZ\^j“‡•€„‚…‘“~…‰‘š–‚ ¡˜•›š¥­“™»±§»Ç犌¡¥Ž“‰{rƒžŸ‘œ~v……‹‡ihoƒ€tŒ†„‹q†‚w‡{v…}nvug”†‰ˆˆ‰ˆ¢«£–‰Ž˜€{‚‰zzogkx}w|qic\YY\h\af_ZOLNXSQIPKDNGCJDCADDA<:87=<:<:88778:==8<=68656623445576867<BB?<8:>CQ^e\G2'&,,--.1(?Œ[.310Oƒ_4?;nvpgxƒ{€Œ€‹šš¤œ¡¬¦«¯°—’‘„¡”„xw€”}’†“–~Š’›Ž„‚Œ‹‚ŠŽ„€Š€mpj^CA4--////02234779;=?BDHJOQRSRSTTRPOHDB<87/9C><<63.l“—MPHIKKKNV`cggmu›š““‹Žšˆ“‹ ¡’£©¥£¬“¨¶¢§Á®ȯxº”š|Œ¡ž˜„“…‚¡ž“™’„Š…˜‘–lpu‰‹•Œv„ql…Š–’ƒ…ˆr‰¡—‡“‰—¥¶©›•¢ƒ‡“„~kjl}~}q_[b^Yfj\lk_XKHOSQNMLFIQDDNFBCEGB>997=<:;:987767;:6=:785456345566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYpƒpu‡qv‘†~—–š”ŸŸ›§ ª–“˜žhf¤š~…“’z’‰’’}‹…™’‘ƒ‹Ž‰†‘‡„ˆ…xxhNR>//.,/.-/000212457;?CFNPRTPQQSQNPIED>;<:CF?><752<?R5HHHLLMNR^oŠ|s} ›§¦¢™¡—¢•œŸ¨ž©«Ÿ¨¬©ªµ—«¿«¶ÈÉ·ÈÑϾ› pi«©Ÿ„“’…œ šš™§‘‘ˆ•¢ššwz~”—‘¡’–—”ž{v•’«³‰— }•žœŽ“–š¤£§¶°‘™¨ˆ—Žˆlss{|ynf^[_^agc_gg\REKKQOIJMFFMCHLFFCBGDA:85<<899975658>75=84745754546958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f3A@ib^Pqu`n}awŽ}|”ŽŽŠŸ’—ž–œª˜žªBD}‡‰ˆ˜y‚‹Ž|Š†Žƒ€‰Œ‰…“…‚†‰€‡w_bP460-1/,.00./..0015>AAMQRSPRSUSNSLEE@<>=FH@A@8662<9;FHGIIMOQYm†w•‹£§ªµ½¸¥®¬¬¨©µ¬±·²²­»±³¾œ³Ä¬»É˸ÿ·¥£°²¬­ª£‹–˜…¥¦ ¢˜‚¦™¢ª¨¤‡…“£  ª ¤©Žœ±‹•£§·»œ¡£°“££ž‘¤¢«°­³µ¢•¦ª‰šŠ“Š•z{~ƒ{e^fZc`]bb^fg_[ODJHTOFHLFKGFFHAKFCFFA:87=<88:974658<54<76:54644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLicWjpXz…v”…ˆ‚›ƒ’‘Œ’Úȝ–sV—ˆˆœ|†Œ‹Š{ˆƒ‡‘Žƒ…Œ†…ˆ’†‚„‰†‡‡‡qna@E64<3/110-,+-1/-4?DANVQRTUUWUM\QGGD<>>FHCD@8;<5C;=FKIGHROPW“ „®£³ª²ÁÇÄ«³Å¶­´À³¸¾¶¿´Á¶»»¤¸Æ©¶ÉǶ¾¹´¨£´­°±›™’šŸ‰§¯ª¤•wŸ¤—¡«±³˜–©­¨®µ»²º¬¯µ¢±¬²µ¼¸´®µ ¨¨£¨›©°­³º¸¸¨œ¸©¥’“ ‡y€rW_bUd``a^_f`[UJDELVQIJJEJHEA@@KDBMF<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AEWQJL\ZQcdWzuq•}„†“v†~€{¿»£¼‚´”“Ž›„ˆ“Š‰z‡Œ“‡…Ž€Š†€†ˆ…Š‡‘zyn]W@EN<6:46AB764//6CHCQ\OQUWU]WO_UIKJA@?GKFFD;>@7D7?BJJEGWTP^¤­¤²´Ã¶¸ÁÌʶ»Ä½³´Á·¸Âµ¿°¸t±´¦ºÅ¤°Æ¹±³²´¨¤¶¶ª± ¢–›¢’¥±­¥­¬§¤˜ ¬³º¢¨²¹µ»¾Ì¿ÅŽ½³Â·º·¿¸º¸º­­±¦±ª®¾°½¼Ã왻¨•®˜™«‰~€yhUa_VhchdV[cYVTJHGLQGDIJAID>?BBK@@MD99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FRLALRWTYVZwjp„Ž…o{rxˆb¹¡™£‰•”–“””Ž—’‡‡{‡Ž–Š„Šz|‹ˆ†|Š‚‹„•}xzufO\dGEL:Qd`[^SF?;HPDZcQQYYZgZS`aMSOEA?IJHEFA@C=E6B?HGKMSZT^”¯¸µ»¹ÉÀ»½Êͼ¼Á¼¸¶¼»·¾µº³Æau²¥±šž«¾ª¥¨«ª¤¢²µ «§ž•–ž˜Ÿ®¥§§¥Ÿ¤“¢§°³¨²²¼¶Á½ÓÉÉÓÆÂÅÌÂÊÄÀ¾¾¿¼¼¸´°¹··ÃºÆ¾ÄÉ°žº«¢¬¥©·‰€|n]_^\U_]heSXaVSVIEFNKA>HD=KB=B@=F>;H@796379>489:57045/26389374526?8@>GKRTTRPOQRQJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKE@JMPRLQ]hmlq†slrrtˆÕÀµš •™™‘Ž—’––Ž†ˆ}‡ƒ–Š~‚ƒy{‹„‡{‹yŠ‚—t}zkepvY]\Peeb`ed][XX\MdmURmn_o_XgeUYTKDBKJHFHHHHBI9D@HKTTV]Z\“¹À¹¾¸ÆÁ»¹ÊË»¶º¶¸¹´¸µµ®¶·™du©ž­p^¢­œ˜¡¢›¤ž«¥”ŸŸ”Ž–˜—¨ž¦ŸŸš™ƒ£¬¤ª±­·°¼¸ÔÐÎÖÏÉÌÒÌÏÎÊÇÀ¿ÂʽÁ½ÂÀÅÄÆÊÀÉÏ´¤¼±µ°œ¬¹½š}vi[]YW[_XbbQ[aTRLCBFGE<@F?BIB@D=:E>=J?47535;=468977022/24169775555D3ELM>510006:477@IOJ;.&**(-.0,@M+/54m‰I0H‰t?>BD@CDGKODR\Zi`o—’‘”nlotu‡³¬¡¡Ÿ‹™œ™•‘›’…ŠŠˆ‡Œ‹‰|„s{Šƒ…{ŠtŠ‡•t{ylmu|iseilhfjii`fiimZmt—­¤½ˆ‡g[oh]ZYTHKOPJKPKTQHLAJFKP__bgjb—·Ç°º´»¾¶±ÅǶ°¹±±»­³±¨«¸­¶¨žœ§šNšžŒ –‘§˜¥•Š““ˆ‘‰‘’›¡˜›•–‡ž™¦š¬°¨¯§³³ÓÔÔÖÑËÏÓÔÎÓÏÌÆÃÊпÊÉËÉÒÈÍÎÃÐÒ¸°Ä½Äº¦·»Ä¢laZ[[V^VXdYO\XOQCBIECI<AD>BH?@B8;D>@I=56655;:687654/10146278875367C5B8?-0,1348=97,.,1;FL=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYSfWs‘™ƒhroyyƒ¡ªž¦—Œ››˜‹Ž•‘šŽ}‰‹…ŽŠŠ‹ˆ|„‚p‡†{‡rƒ’‹~qyulpxr{nxsli€pmcinpyiw}~Ë¿Ãߧncxnd[a`KPRUNY^P^]NQNTQUT\nnwƒr–®¸¬µ¨°¶«­½Á²«µ¦¥¹§¬¯¡¬´¤±®›˜˜Œ‘”‘„›§‘œ‰ƒ‹„Š‰„‹ƒ”•——”›œ˜™™žž«¬¤§¢¬¬ÎÒÕÑÍÌÒÓÓÐÔÑÎÈÃÔÑÈÎÒÓÓ×ÍÒÑÅÒÖÆÁÏÈÈ鿸Мwlc[`[T^Q\ZOOSPOI>AGBCF=AB?FE>@?:===<JB45465<888664412/03526768533;=<E=@11+/349?5901022-2EO3)/3.32=N248C}_2A†tD:==I>@CFH<VRMO[u‡†‹wlwp}~€ žž¡Œ™“”‹Œ“–…y…Ž‹Šˆ‘‡‚{r~€‚‡z…v…“‘‰€owsls}|w|s‚xqk€rriprzyr{¾Ëš²„vr…wiai]DZZ[WfdXekTX]]`c^cx{‹™ª¤¤¢ ¡©¦ª±¹«¦´£¢®¢¤®¢§±Ÿ‰¦›•“‘Š’ˆ‚”‰k•¢™„†~‘ƒƒ“—¬‹•Ž•šŽ…’—§°¢ ¡¥¤¨ÈÍÏÇÂËÐÓÑÔÒÎÓÍÆÖÓÍÔØÖÖØÕ×ÕÊÔÚÍÊØÖÑË­ÄÃˈpm`^]VRWRZOJGJJJ@;:;EBD=CD>HC?CB;<9<:GC46544<5687543250/2546745544<>=E?A62/-16;=081/254/-.;R017/532ED28>nb5=tM99@I<AD?A;PLFKYp€u~isyr‚Š€•ž”…‹–‰Š‰Žˆ€x„”™‹ˆˆ‹‰~ƒxs|}„‡w€{‡‘—„oxqmuvx}t†|yl‡vun}v…uy{µŒ<A‹Æ¥~}jeWICecfchjdoy[_fhknin„‰‘ŒžŸ ž‘—™ £¤¦²¤¥² ¢¥Ÿ¢©¡¢±œ‡Ÿ’’“‘‹Ž‹‡„„~œœŒ‚„…z”‚ª–£Œ’‹˜“‹}—Šš‘ª³˜›œ§œ¦½ÃŹ¶ÅÍÑÐÒÐËÒËÉÔÎÑÕÚ××ØÔÙØÍØÛÎÉÚÚÒÖ¿ÌÍ´uslb[WQSPXUEFJIFF=:7:@BC:HE@EDBDA;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?2*(.BT29254/7K75<`bA<svV87AH:?C><9QECJTlnopbqqt†}—‘ž‹~‡’‚‰†…Š‚ˆ}x…——‰ƒ‡†‡z„yq{{…†uz†ŽŽzp}ppz€r{r„‡€nŽzuw}}‚u|‡‰°tYªÂ·’pnc=^hrqqpnww‚eiorvxr{Œ‡“’›– –ˆŒ“œŸ›Ÿ« ¡¬œ¢šš ¦ŸŸ¬™Œš‘“Ž…}ˆˆƒ…‹Ž ™“ˆƒ‡~l™y„™‡ˆ“ŒŽ•Œ†{›ˆ“Ž­ª”•—Ÿ˜¦®µ¼¨­½ÆËÈÉËËÏÉÄÒÊÔ×Ø×Ø×ÔÛ×ÓÙÛÖÏÛÚÒÖÉÕ̓uwfeXWNQR\GBEII>B>=8:>@<>H=@BABEA>?:87DB755479.566435532323647553458EBDCEB56<FNSM[nfcnsk`V>,4LG865433BF4=W_hLux^8;?F<<B<:9D?CGRk_mdbflv€ˆq‘›€y€Ž~‚‚…„|}„˜Ž‡‹~†‡wƒyn{{‡‚tz’žŽ¡vvƒtu~t€„o‚o’…u|…zv‡|‰¸Æ¥Ãʸ‚–œxpfNec‚{‚w…¡‹yzw{„€|„um”–•–˜‘ƒ‰—š——¦˜ —Ÿ“’—£žš«–‘‘‹“ƒŒ…‰‰†‘žœ™ˆ…‹…—zˆ‰Ÿ—‰ŽŠ‹‚|¡‰‹¼ ˜“—šœ¨¦¥­ž§µ¾À¿¸ÆÉÍÎÅÍÊÑÖÕÔÙÕ×ÛÔ×ÙÚÛ×ÛÚÙØÎÛƃvvdfa]RUUTMKDMD;=<<9:<?9=A7>?@=@>=9867CA6455=80665547745613854564567HH=DJE7925;H>;9:7HP\ZRUXK9T>;95327I8=NYMHxxd5=>C=<@:6:>>@EQ_Yfa]\itzyl‰’wvz‹|~€€~…{~‚‘Š…†z…ˆ|v~um|}‡~t’‘Ÿƒ’|‡~x~y‹Šoƒ›t™†}‚Š…|~‘{©Ã ½Œ›¤œ~Š„}‰sŒ‹s¦šœ˜”…{‘‰„iGq¡¤žŒŒ‘’…ˆ‹’•›“”‘—Œ•Ÿ”¡•“ŽŽŒŽ‹„‰“–™ŸŸˆŒ”‘‚Œ¦™ˆ…Žƒ†„€¥†Š‹¸—‘”–¡¦ £®¶º´«ÀÆÊÐÈÇÍÏÓÒÒØÒÕ×À×ØÙÛØÚÚÙÙ×Û¶vutgfbT]YROOHCLC==>99;:99<=6@>>==9::;37D@8378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWO<MTHN?96333>C;[X>5YypZ<<A<=>8589?<DRSRX_VXfmmmiŽŠqsyŠ{{€||ˆ{}|‹‡ƒ~u„†zszsm~…~w†›¡›ž”’€Œˆ˜‡€œ’nˆ©…{ Œ|‘Žƒ‰„œ~›‘Š£¢Ÿ‘¤¯ ‹‘‹†‹“†Wr­‹Ÿ«›ƒ™œŽ[ƒ¢‘‚Ÿ“”Œ†ˆŒ’’Œ”••ŒŠˆ–›•–’Œ“”†€‹‰“ŽŠŠ—˜£¢†“• ‹Š‰Žƒˆ€ƒ‡…¥…‹²˜œ’”—¡ ž™’›§±¸¬¤½ÂÇÍÈÆÏÌÐÌÎ×ÏÑÔ®ÖÕØÚØÚÚ×ÖÙڝlyqccZZVQUWC@ID??>:49:;7:;:3<<?=>7;9:1:G=:27=@50677255?65;55858:57735HR7GOK994=EJB>1FCLA98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:;@;BQKKSYPTcbxlb~‘ƒonx‹xz{}‡||w†…€sp…‚{uwvt…ƒ…}’¦¢Ÿ¦¢—Š”—‹Š¨—rŠ²„¨’„™”…šŒ£– ˜“‰›ž¢“©° ‘•‘ŽŽˆ–Œo·„šÄȲœ¢¦œœ˜–‘±d¤ÍǕŽ†‡‰’“•Š…ŠŠ†–™›”“‡•˜„€‹™ˆŽª——¤£ˆ™ž–šˆ‡—˜Š…‡¥ˆ“¨™—“–˜¡˜Ÿ™“œš¢²´¥£¼Á¾ÇÆÅÉÈÉÂÊÓÌÍÔ¨ÒÑÖÖÖØÚÔÓÚÎo{d`[\[MISYBAGD;B>837<<:8>64::<:72?:929I:>67BC32:96264>=4;>6949;57944KQ<JQK9A7BGI@64JELF>;88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBc‚GvŽ}|m~ˆxz~{‚‚ƒwvƒ|mn‹{}xx|„‡Š~‹¢³§£«³¢—§Ÿ¥¤–•®¢ƒ‘¸•’³šŒ¢¡Œ¥›°£¤˜‘§–¨™¬¯¤˜•–•‹˜š—¡ÀŽ£É¸«œ£¦­˜’›²…†¨¢œ˜…‰‰Ž•Œ‹“ˆ†‡‰“˜•Œ‹”“‡”˜†„‘œu‘™²•–¤¡‡œ™’‹Š—›‰‹–Ž†}Œ˜ž‰œšš“˜—Ÿ“ ”ž› ±®¢¤·¾´ÅÇĽÃÃÀÆÍÊÉÓ¦ÎÌÓÒÑÖØÓÐغovrY^S^TNHIMEBCD5>:77:?<<7=42669774>5;5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=88567=:JFDGMZ\YJf`;H„‹zzn…†z|„x†~px|~}orz~‚|x†‹‰†„’¦»¬¨±½°¥­³³¨£¢°¬Ššµ£¸¥•­¥—©­¸§¤£Ÿš©˜ª¤®°ªš™œ”•‘— ˜š»»®Ê¡j¶¸«°”™Ÿ£¬“—¾£^ª²ƒŠŠ”‡|ŽŽ}ƒ†Ž”•ˆˆ“–Œ•‹–˜“™´–•«Šœ”’Ž‘’Œ˜›Š’ž‹‰–Ÿ¡”˜™’›˜ž”¡ ”œ¥¯¨¡¥³¸¬ÂÈĶº½¼ÅÇÇÂÑ ÆÉÍÍÅ×ÖÑËӟmweYWP\PNEC><CAB8@885?G==6<35345454B49:BM:B;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPdHb`bpJ@‹Š~€s†‡}‚ˆuƒŠ‚n}|}pw‡wŽ‚‡|Œ†Œ™©ÂÀ¯½Æ»³´À½´­«³¶Œ¨²­­½«›»¥¨­¹¸«¦¦¢¢¤£©¯²±ªœ¤™›˜—Ÿ¢¦¥’¤º¯©À¼­®²¹¥¤¨~ˆ†œ­½°‚‹Œ‹ƒŽƒ‘zˆœ‰ˆ—‹•–”‘š—¨š±š‘¬œŽš’Ž•–˜’¡‘‰”›¤¬”–“œ“ ›˜Ÿ¡”šž§¦¤¢£°²¦ÁÆï°º·ÅÄÿͦÇÄÇĽÖÐÍÄʅpo^YW\XLJAKAFG?A@C;:4>A==5=6>343241A17@BN>G@CNCA=C=;86CC5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUN79GD?CF\eF`igZ]\“ŒŒ‰{‡Œ‡ƒŒu‡‘Šo~{‚q~{•z’””˜“–§³ÆÉ¿ÂÌÂùǽ»¯«¹»˜³·º²À®¥Á¤«¯¼½ª®«££ž§«®µ°ªœ «œ¡œ–Ÿ¯µ§‹£ºº¶Á¼¬©³¥¤¨”…Ž©Ä䂋‡ˆ„†•”yƒ‘‘¡ŒŒ”’Ž‰—Ÿ˜“™•˜¦ ¯œŒ«œ–’‘••Ž•’¡”†—Ÿ ²ž”™“Ÿ ˜¤žšŸ› ”˜ž¥¤¦¦¤¯­¥ÀÄ¶Éþ¶Ï²Ä¿Ä¼³ÑÊÈ´quiYUYgPLHBLKLJAA>DD<5AE;;3=8B332263A05IEN>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBeZMe\fTbk™–ŠŒˆ“†‰y‡”r€{x‡‚‚z¡–¨™š™º½ÇÈÉÁÒÉËÂͽ³­¼¾¨º¿½»Ã·¬Á©¬³¼¾ª°ª¤¥¤¬®³­¶µ¡Ÿ¯Ÿ¥¢˜£³½ª›¨½Á¤¶¸¯¬”²¬¬¬—‡š©¦¥‘‚Œ“¥–ŠuŠ’y…Ž’ž ““Œ”£™–œ••£žªž‘¥šŒ•–ˆ|–“’£š•Ÿ¡œµ¥ž–¤£¡¥¦˜•—š¤£©§¢²¬¨»À拾·Ì¿¹¯Ä³»¾Á¸¬ÂÃÂÀ—jv^UTYXJJLIFDDHCCADL:4DI:;4<8E.12352B26SHO<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQG7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>iH_XbZccVžœŽ—Žž’‰ŠŠ “„x…–ˆŠ‘€–¡™®§¤˜Â½ÇÃÇÅÓÎÎÍ˼·°º¼´½Ë¼ÃÁ¶·¼­³¿º½®¯¨ ©¨¶­®©²·šž­£§¡«·¸ª¥°¿Ä²½¹´¨«¶´®®—–¥¬¨Ÿ‘’²Å§–Ž|’•|‡’™ª™˜““’•“¤“™”¡£¢œ˜Ÿ˜‹ŒžˆZ–—’—¤™e˜£Ÿ²¥•¡•««©¦›ž¦–˜–˜” ¤¨¥Ÿ¶«©¹»Ã´¥´µËÀ¸ª¶«²»¸®¨¸º½¸€hkWTRSMEIRMK?AHEEHHH95EM;>8=@J.32025C55OVN<LFKRLOHGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|gV;>@BFBpEjIReaLF¥”œ—¢—©–Œ‘ƒˆ¦“ˆ‚‡‚œ„ƒ•”š¢ž¯¾¯¡Æ¼ÄÄÇÆÏÏÎÒÊ¿»¶±º»»¾ÏµÃ½¸¹·³±µ³¸³«§œ«¬¹ª©§¯°˜£¯¥§£¥µÀ°¬¬´¿ÃºÀº´§º¶¹´¯–¥­®®¤‹“”¡tš}—™„Ž—™Œ±•›š•’’™™¥£• ›—š©›  ™Š–œ`J–œš•š¥–U—° ¯œŸ¤”®­ª¤š ¥““˜˜œ §¢š´¨ª³»»»ª±²ÇÀ¹¦¬«­²²£¡²²´¤mjbYWMOJDOOPR;GKIGICC>:KU?A:=EM07534:B44MWO;JKOUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@BAF3>58JKCA=C;4EA:A?>H@5*B52,>c]g:35tde@R7&#3}hW;:BC@=QEWSsbWFHª–™ ¢¨¯™‘—‡‹¨–Žˆ“… ˆ„—¡š£¤µÉµ©Å¹ÂÃÈÊÉÈÍÍÆ¿»³®¹¹ÁÁ̵ǺÁ¹µº°¯¯³µ§¤›ª´µª©¦­¬š¤®¥¤¨¬»¿¨¬¶·¿Á¿¾¹³²Ä²¹¾­£¯µ¬¹¦ˆ›—¦›v¿Ÿ„™Ž“ššŒ®—¡œœ—”› ¡¨ž¨Ÿššªš¡§ž˜‘ƒnv’¢š•¢‘®²£ª”¨ª—©­£¢ž¤§‘‘™œ‡”¢ž–±¦©«¹¶½²²®¾¹¶ £§¨¥¦œ›­©©‹`b^]NJKFGMJVL=MENKLBCD<QV=AABDO18=77?B75UXO?HNQYSPQUKQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW;:=.-R`MUH~e^HE«•›¢Ÿ»¯™”ŸŒ“«›‘’“‰«†¡žŒ£­”££¶Æ¾´À¹ÂÂÇÉÅÂÎȾ¹²¯¹µÁÂʵƲ¼µºª¨­­°££˜ª´»¦©¦«ª©¯§£ª«½»¨­½µ¸¾Ç¼·¶¸Â²¾Á´ªµ·«¾¥£˜’¢ ¼Ÿ‰š ™—Ÿž·Ÿ©œ¥¢›œ¡š¨¤³ ›¦œ¨ªž˜•”›‹–‰Œ¤¡”¢ µ¯¥¤’¯«™ªªœœ£¢¨””Ÿ‚žžœ•©¤¡¡³´º´­¨µ²³žœ£¥š—•˜ª¡žu]Z][HGEFLQIMEGGBSLJBEGAVSCH=AGQ1;B7:BF79\YKALPTUSMWRNUJE@JJNO9C@5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-19f\FCCpbGE§—£ŸžÃ­œ—¥˜šªœ–ššª–•§¦•­¬˜¢«¶Ãü¾¶ÁÂÀÇÄ¿ÍÆ»½¹²°¹³¿Ãȵ¿°¼·¹¶¦¤«¬­¡¡™ªªÄ¢¤©¬¦ž¬¯«¢©©¾¸§­¿²¸·Ç¶µ¹¸À³À¸µ³´¯¾£—£—”œ”®Ÿ¢£¥££ ½¤©ž¨«¡›¥ž½¡™£Ÿ¢©¬¡—•ž“ž‡„“Ÿ¤ žµ¬¥›•°¦™¯¥œ™¨œžŒ˜”žƒŽ š›’¥¤š—«±µ±ª¥ª®¬›˜  ’•¨ž”e_W_[MHGJNLHEDIA>QIA<GIH\ROK=HOU4BF9>HG5Ca[KBNRUWVQXTRUI@8RQPM:GA4CHQSIC;C>GVKC@O>K<06;GF>;FA56?9:?9;15D0-,/Mv\4KZ5,MnW<-=)#zbQ5CKQ9mRF<KxeaVK¢š£œžÅ¬¡ž¬Ÿž® ’£Ÿ–¤ ¦©¬˜¶±¢ª³¶ÅĽ¿µÀ»È¿Êǵ¸µ´±³´·ÁŶ¾±¸µ¹´Ÿ§¬ª¬žž¥¤Á¥Ÿª­ ¤©­¯¡¦¨½µ¦±½¹·¶Ä²´¸º¿´ÄÁ¹¹®³µµ£¥•’”¡® ™¢ž©¨¬£šÂ¬©ž¬®››ž™¦ ½¡¤˜«¬¬¦¢ššŸ’ž‰ŽW–Ÿ¥¡ ¸ª§“˜´¢ž±Ÿž™®•˜“œŽŸ—•Ž¡£•¥­²ª©¢¢¥¥••˜‹‘’¤ž‰_bXb_KGJJNFEAGK?=JB99JJN]QQI=LV\9FI=DMI8Hb\LCLPSYYVWOZ^IA=WQIK?H?5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+w`S6SZkWrGE6=ue\KMžž¡™ŸÄ¨¥¢´¢³§“«¥ £Ÿ¬©¬»°¨¬¶±ÇÅÁ²ÃýÆĽÄɼ¯°¶­°´¯¿Ä´¹±°º´¬™¨±©ªš¥¡§Â­›¬±›ª£®°©¥©¼¶§·»¾¯·Ä­³³ÃÀ´Ç´»¸¬´¶­ª¢¦–••¤¬¢Ÿ ›§ª°¯¯»²¦ ©©™™˜“¢£¸ ¡£’¯°¬¥§Ÿ’¡ž•ž•ž›¢ž§³¦¦Œ—²›¢­™œš¬’•’™‘¡–Ÿ “‹¦«¯¤¦¢œ ž‘‘š“…‹‘›_cYfdIHLJSBC@IH;;F?99OMU^RSJ>O^]=HPBLLI9Mc\LELRTY[SUO\bHA?ZQAHAKB7FELKM?;BHDNB=;N@A3/97CB97F;+6<46<25-/4@1+'VtSeO?104b[M23>0<v]^?[T^eq@8;H–weA4ž£Ÿœ Ã©¤ª³¢¤µª–³¬§¡¤²¬®©»²­±µ´ÆÀÄ´ÀľÉĵ¿È´«µ¨°¹¬¿Ä³·®­¶¸¥˜ª²«ª˜Ÿ¦—­»´›¨°š¬ ­´²¨«¹²¨º´¹³¸Àª·²Ä½µÇ¨¿¯®¶µ©§¬¡˜—’¦¥¢¢˜˜¥®¸®²µ¶ Ÿ¨¤š••”¤ ·¢¥¥–¯²²§ª¦¢žšš›•—¨Ÿ ˜¡ž®²¢¦Œ—­˜¤«–˜¢šŒ’–˜…•ž”Œ›“Š¨©ª¡§¡˜ž•‹Ž™…”ˆ“žwbg[jiLONNT>CANC;:I?77RO]_RVQAW`\BJSHVKH:Td\NFON[W[RPQX]GAB[PBG>NC9HGHOP??CIBLB<2IA94177B>;7E7+6914801-/.<6-#Bqgsk23/1[bZ33806p[bH05IohUCWFŒyfC;££¡¦¿§§¯±¡©¶«žº±¬£«´¶±°¹·°·¸¸Ä½Ãǽ½ÄÂÆÀ¸ÀÅÀº©¶¤¬»­Á··ª­²º¢”­±­²–¤§‘ª¹ªŸ¦°œ« ¯´³«©¶¶­¼­´³¹·¬¸±Ã»¿¿¦Ä«±·¯¨««§ž˜™«¡¢¡‘˜¡±¯³¬°¹šœ© š—“˜§ ¶©¦£¢±±´¬³¨¬Ÿœ  ›ž¥œ¢—£³°šŸ“¤™Ÿ¨™“¡“–ˆ“–’•–œ“ˆš˜”Ž©¨¦Ÿ£œ—›’…Ž™‹}‹•„™igk`lmWPQ[UABET@<;IA7:XPd^PWWEY_^MLRN^KJ>Zc^NHPO\UYPKTWZI?DXPDF?N@=IGGQPB=DFBM?:1D?77547?=95E4+75/251--.,1=*'+=\p=>1.0dZd@1647gY`F(?8l}g[V;‰{cC=§Ÿ¢©½¢ª°¬¤²¸ª¦¶´¬ ­µ½¯³¸»º¾·¶À¿ÉĹÄÂÀ¿¸Ä½Á·¯µ§«·²¼¾¿´©®±¶ž–«®¨®—¦¨Ž§»Ÿ¥¬³ž«¢±°³¬©¶´µ¾®±²µ¬°´³Á»Æ·¬½°±¸¬¬ª£²¦ž¥ª ¤—‘šŸ³ª³««³š§œš•Ž¡¦¤´®¨¡­®®±¨´­²ª¤œŸ¨¤ž•¢™›¨µ©–™’’™Ÿªœ•–„”–Š˜œ“Š––š–¦¥£Ÿ–•—’”…{’‚‹•dkqfoq^FYgVDBMXDZ9HB6>\Qh\OY]G[^]OMRXdJJC\b_PLMNXWXPJVVWL=EUJEDAM@AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,,%2+*5K1/'__`U150=`V^8)C3YU\gK6ŒzfL@¤š¡¥­·¥¬ª¦¯®·ª¯µ»§¦±·Å·±¶½ÁõµºÄ¾ÌƹÃÀ¹¾¹Ã¸À¹²´«©º¶º¹¾´ª­°µ—˜§¬©¬›««Ž«¾ž¬®²£« ±­³®®¶²¹¸ª®®±¨µ¯µ¼½Ê³ª·µ±´¯®¦¡´ ›¨­ ¦––›š²¢­ ¦¯—¡¤šš“Ž£¥¨³ª¡¦³­ª¶¥¯²µ¯¤™¬§š˜Ÿš™«·£—“Ž—œ —–“ªžš‘’—Œ›˜•Š”’ž™¤¢¢ ˜–’“•z‹…{ŒŠ‚Š‘jmwmu{aFakYIHZZ={JFD6AbTi[M\aK\]ZRRRb`LKE_``QLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T_T_/5(C_Q\.+B/JGP[G3cYTKD™—¡±©²ª¬¦¤¯®¶©·µº¤¬´·É»´»º¿¿´³·ÃÀÌȼü¶½¾¿·¿¼±¼­§º¹·¶Â¶«¬±·”–¦®«¨£°©”¯»¤­±³§¨£²´±²±µ±¸´©¯¬²§·¯·´ÄÆ·©¶¶¬°­©§£¶  §±¡¤•œš•±ž§œ ªŽ©£ž›–˜¦¦¥¸¨£²µ¬¨²§®±µ¬¥™ ¬¨›œžœ”©¸œ”ŽŽŠ—›¢——¤ œ“‚”œ›—–•ˆ–—š§œ¤ ‘–‘•v„‡{„ƒ‹Šlovt{~\Lfm\JNd\?b{GI8GgWf\L^bMXYWUWTi]OOH`]_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANGf27'GbLV%-B.=ELQ<3rkICC‘™¥¯¥®¯«¨¥±³´«·²¸¡«µ¹É¹­Á»Â¸³±µÂÂÎÅÀÁ½´½¿¿º¾¼²Ã§©¹°¶¶¿¼®«²±› §±­¦¦¯¥²µ­«±²¬©¨µ»¬µ³µ­´­ª¬¨¬©¹®²±ÈÀ¹¥º°©¬¬¥¨®±¦¥£¯¤©œž›¯š££££‘­Ÿ£  ¢«¦§¹¥¬µ·¥«¬©­°¶®¢ž£©ª› ››’¤´™ŽŠ‡¡ ”Œ”œŸ’ƒ’’œš—•”‡—’•™¦›ŸžŒ’‘v}…|{|†ˆˆprq}|}\Sdo^NYg\FD–[G;NmXb[L`bNVWVWTXg]QRLcY[TKGOTSNGIVS\N;P^IBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/+1()+,-*&5*/&0)38:1&*3Bc:6*HeHJ+:H>3BHS,>k;GHœª«¢ª±¤©¥³µ²µ¶²²¡«®½Ìº­ÀºÇ±´­´ÁÃÑÅƾÀ²¾À»¾·»Ä¦¬·¬²·¼À¯«±¬Ÿ£§­©¨¤°£ª²ª°¬°¯°®«³¼§·±²©³ª«¥¥£­º­ª²Ãº¶­»©©§¬©§±¥ª¤£®ª¨¢Ÿœ£­•¥ž˜ž™¬¢§©¢­¦¤­¬¸²²¢ª¢ ¬¯±¬ž §§©™£™™ ¦—†„ŽŠ‹ž ŽŠŒ•šŽ„…”Ÿœ”—•†–““—¤›œœŠ’‰~‡…|v~…ƒ…rqpˆuk_Z`nbQsq\K;„|F?XuX`ZNd[NVVUWQ\a^SONgXWVKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*25>10485(5/*,.30;),,'%234$,2-860)(1;\J0.JgDF8;B05EKX1@•Y=LE•˜­¨¢«³œªª°·­¸¶¯«¦««½É¼°½¶Â¯±«³ÃÃÎÏþ¿´ÀÂú¿³Çê®·­²¸¾¾²­­ª¤§ª°¨§¨±¥´®«±¯­²±´¬´¼¤¸³­¬¯¨«Ÿ£ž°·«ª­»·¥·¶¤©§««ª­¡©§¦±²¤§¥¡¡¬—ª¡•› ¦ž¥¢«¤­£Ÿ§±¸®®¤¦£›ª«®©¢¥¤¤˜Ÿ›–˜œ’‚‰„œŸ‹ŠŽ‹˜Ž‰‚‹—¢››‹“’‘“¢™›™ŠŽ‹‹}†ƒzs‚€|ru‹¤‡xk_`nfWe‡cN?g“LEbyWbXReTMVUVTO\]aUKNhVVVIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*39?./463)4+*,+.#4.-+&(+79*&6+<-2,&06VZ.0JgAA<<B+:JO^4D†=GFD—“°¦£«±˜«ª­¶¬¶²¬¦¬ª©¼ÀÀ·¸²»µ¥²¯ÃÉËÑ¿À»¹¿¾Á¹Á¹ÀĬ±µ±³ºÀ¾²±®¬ª«¨¶©¦®¯ª¹°¨²²¯³­·ª··§´·«¬¥©ªœ£ž³³©¨¤´µ ·® ª¨ª¨«§ «¬©¹µªª©©¢ª ­œ“ª¡ ¥¢¦£ªŸ§´¯©§«££˜¥§§ªœ¢¤£ ™˜ ‘Ž˜~‡‡„†ƒ‰‰ŽŽ‹‚…”¢šš‘‘’Ÿ—˜–ŒŠƒt†xt‚~yv}€‡orgfpw\asˆkO^™VHnyUdVQcOMVTUPOX[bUHOiTVSGPYUI>IHOQPxLMV=<KD?@A<@CUC9AK=5;E13;:7*4:=+-341*8**+*,))(/*&)%3;,$2)2021%/2Qb02?f=NX>C,>LT_/Ji5OD<–Ž±¢¦«¯š¬¦­°´µ°¬¦°ª¨º¾»À°­¹®¡¶¯ÈÇÈÑÀ¾½»»Á½ºÂÀ¾¿®²²²µ¼»Â±±³ª³©¤´¨¥­³³¹°£®¸²°²»«º°ª®¶¬ªŸª¬Ÿ£ ¶­©¡Ÿ°³¢µªž¨§©£ª¡¢¬­¨½¯¬®­¢¨¨ ¬™°¡˜¢ §§ž¨›™ª±ª£ ®¢¡”£££§˜š¨¥˜—˜žŠ‡”ˆ}†„„£–„‹†‹ƒƒ“Ÿ–ˆ‘œ“‘‘œ”—Š††wt|uxyysrxf†¤vi_dj€tgˆŒ}SXo^JxsSdSQ^MMRZfNLVYdXGRhRQ?BNQaQ:IHLSIqQLS;<I?;<=;@@W<<?H73CB15:93-5::)-31--5)(+-,42#2)',%.;.&1.0-14%,0Lg:48_=ad?F1CP[[*HM9U@4‘³¡¥§­¤§¤­§µ³²«¥±§ª¸¾À»¯§¹ª¦¯±ÉÇÈÑü¿¾¸½¾¼ÈºÁ¸°¯´±º»¸À²²º¬¸¬¢´§§¬²·º³¨¨½¶®¶¾°½§®¬µ¬­œ©¯£ ¥­«¨œž«³¥´¨›ª§©£¨£©¨©½¬´°®ª¤ ®œ›³£–¤œ¥¥Ÿ¥œ›©«¦Ÿœ«¢œ“œ¢¥ž˜—¨©’˜š”Š‚…~ƒ€ˆ…~}‹‡ƒ“š“…“¡Œ•‘‹‘›’•‡‰~r{z~|hx|ytoo{f„x„‰dagar„zmgx]^T?W{mTbPQXKLNru]HZ[gYEUePD>JODCA9HGKS?jbJQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11'/>KH0%90%,,09/,,+6'17#-0GjI14X=fbAJ7GS`U*=9DW=*•²š  ª¦¥¡¬¥¸³³¦©±¦¬¸Á½µ¯¢¸­¨¨°ÂÉÉÌÁ¶½À´·¿ºÈµÂµ³²µ²½¸¹½µ­¹µ¾­ ³§««°¶¸µ¬Ÿ¾½ª³Á´¼¡¯³µª¬Ÿ­°£œ¦©ª¤ž›¥±§° Ÿ«©§¡©œ¤¨¡­¼¨®±®¡«£¤®žŸ­¦—Ÿ›¡£œŸœš¤«£œ›¥¥–—• £—›—¥¬Œž‘‘‘‹‚Š€€Ž€{™”Œˆ{}‹†‹‰„’˜†”£‰“’‡‘š“ˆ}yk~vyxc|zpooqvgsi„heg_lslaio`o=ZykU^NPQJIMTZWM]^lWDW_O^PHMDF;7HEKO<rhKK9AE;;==;;=J49B<3;G<4?18-68;2(09/,4/.=-*K>)49&'.34.0+/4&,:$41AhY14S=e_DL6KVdO*;1NW=#”™­š¡˜¨¥¤ ¨¤¸°¯¤¯°©«¸Á¹²­Ÿ¹¯«¨´ºÈËÈ¿¶Â¾¯´½·Ä¶Ã²®¹²³À´º½·¨¹¸½ª£´¨©ª±¯¹±«œ¼½¥°Áµ¶¢¯¶µ§¦§°³Ÿž¤¦¨¢¥™Ÿ¬¨©ž ª®¦ ¦˜£¨ ±¹Ÿ£±¯¡¬¡¬¤œ§¦©šš›Ÿ¤•›žª§—œ¡ª“™”™Ÿ“™–¡©‘š‰Ž†|‡~‚}| Œˆx‚‹„‰‹‹…‡“šŽ‰•žˆ‘•‚‹–‘|…|sp}qtt`zxhmoomh}qb{mieb]e…~_ZsjqJIiXZMPLJHPRQIO\_nSDXZRhOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23.:;83&2<0,85B*)-B*,4;NN@;73-.+-7**<%53<fd24M?e]FO=QZgH*>/WU5(—ž§š—­¡¡¡¥¢¸«²¥´´©¨¹Äµ²­Ÿ·­®­°´ÆÈÀ¶¾Á¹°´¼¶¾»¾¯«½°´¿°¼Ã¹¨»º·§§µ¨¨«±­´±¨œ¿¸¦­¼·²Ÿ±·°¨¥§¯±›¡¤ ¥¥ —›°§¡Ÿ£¨¯¡Ÿ¡“¤¤¢·°¡¦±«Ÿ¬£¯˜œª¤©Ÿ—šž¥“››ž§«šœž¦—–˜–žŽ“—¢¨¢‰‹†z„~„Šz–‰†x‡ƒ‡‹…“˜–™Š—~†—Œyzprwoot_ywdkkjgg‚lerkkdhXas^ZluiYE}][XOOKHHRUG2:^^lPDWUYeMHJEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<#8R=*113>D5,-'42+;+139cl84HBf[HTCT]hE.;1^Q,2–¤£˜–ªž¦¡£¡¸ª°¡»¸¥¬½Ä²¯®¢µ¯­­¯´ÄĽ³¾º·°³¹¸º¸º®­¿³´¹®¿Á·«½º´¥¢³«¨ª³¬®²¤Ã·¦©··«Ÿ²¼ª§¦¨¯«™£§œ¥¦”˜¡³¦šž¥©©œ¡Ÿ”¥Ÿ¤¹©¤§­¦ž¥¡¨“Ÿ©¡¡¡™›¡’›—¡£¬œœ›£–“•–›Ž““£§¤ˆŠŽ†y„|…†}œ‰Š†x€ƒ‡ˆ‡‘…•“’Œ‘•”Ž”{ƒ—Šw|lurmlsbythfifcm„fghdfhi^ebifZezb`PsT[[SKIGIOS@!+i^jLCVU^`KHGEC.:B<F<6KPD8:D357==895?:;4>8@L=>93)8><:9*6@3.E4(+,>0-N?.+-7-1195,&.5-80576`tB3CDh[KWGU`hB377aL'2Ÿ¤¥“¦§œŸžž¤¶­¨ªº·§¬ÃÀ¶¯¬¢µ®§®¯·ÁÀ½±Á·°®²¶µ¹¸µ¬ª¼´¯²±½À·®¼¼±¤Ÿ¶¬¦¦µª«¯¡ Å¬ª§±µ¬¬µºž¨©«±¥˜ªž§¥’™¥®£™ž¤ª¡›¡œ˜ §¶¦¯©®¡¡¡• ¦Ÿ¢ ™œšœ“šž•¦Ÿ®£˜˜Ÿ–•Ž•˜Œ˜š§ ‡ŠŠˆx…w‚‚‚œ‡Š‚‰{~…ˆ†„„–•‘‘’{ƒ•Ž…s}gypkklguskagcbsacefeiibeoY^X\lcaLgW[`VIGHKMRX>9`liGBUS\[IHFEA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A<-5B37=+*,/A*JK./*+3722(57$+7.72685\yN2>HiZLZJVbfA:3@bF%5¤¡’®¡š™ —¥´²£²¾·¡±Æ»¹°°£¶¬«®©¹¾½»­À²¯¯®¶®³¹²§«¹±¯®³¶»¶¯¹¾¬¦žµ« ¡²¥«°Ÿ¦Å¡³¦°³°·®µž­®¬®¢™§ª¥ž•›§¦ ™¥£©œšŸœ•ž­°¦¸§®¢¡ššž˜ž£š¥—Ÿ˜œ•š¡“©—­©œ•ž”•šŽ•”˜§§ŒŠ‰Ž{t‚‚‹˜…†|‰ˆ„…ŠŒˆ’…“œ’‘‘—Ž‚o‚gynhkjgqrk[hcar`dgjnkeiecl\lluqaSbhceZIGLMOYQPUaeT@VRZTFGFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.4<;K6/.+,-24:5#3*)6.55465Z|]1:Kj[M[KXdc@A1HbB'4”£œ±œ”¡›©³°Ÿ¹À¶ ´Â»½¹±¦¶°©®¥¸º¸¸¬»°­««·ªµ¹­¤²µ±¯©±¶¶±³¶»§© ¶©Ÿª£ª®¬Ä™¯¦°±·¶­¬ž±­¯ª¢›¤¬©›•œ§¤ž™ª£¥•š ’œ£«ª¨¹ž§¤ —šš¡k£–™qƒ—œ¥v’¬©Ÿ–—¢’Š˜™€—ŠŸŽx…’ƒmi~w„ql†Š†}„Š†o]d`g„—†k‹”’ux‹„ƒfˆ€hvifX]itnNPjcfqƒf]dfnkh][]‰…‡hOKC8ETg^JHPPUVKHRapteF[QUPFGFC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,,08>G701.*.*/668,#1'214:276Xl15Ok[N[K[fb>G1Na<+/Ž¤šˆ–²›”¡œª®«£½Å¯©·Â¸¾¼­§¶±¦«¤¸´³³°¹®ª§¬´¥±µ¢§¸¶µ¨§­¶³®´®´¢©Ÿ´«ž£¥§¨›°¿•¨§±´¹­®¤¨­ª«¦¡Ÿœ¡¨§›˜¡¥¦œœ§¨“ž ™‘Ÿ¨ª£³¯£¢£œ–˜˜—£ˆ¡’šˆ¡ˆ•Ÿ¢¥€¨­Ÿ””ž”‰„rxŒŽƒˆ u‡i—‰f~sx o‡‡„~Œ|¡ Ÿ™{‡žtˆŽv›Šl‡‚ƒmhdd{mrbT†mcmi˜qXipn†W]hZkjZˆplyr‡h‡„Y^FM>F^MERVVQPRWTg^LZLRRPEFG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82*/1<I:/01.*/(-4583%&2115>1<8Xƒt15Rk[N[L[g_=K1T^7/(§˜„¬ššŸ«ª¨ª¿Ã¯²º¼·Á¿ª¤·±ª¬¦´µ®¯³¶«©¥±­¥¶³›¬µ¶´¦§¨³±­²¨®ž«¡³© ¤¥›¢¥ž±¸•¦§§·¾¦¬§©ª«§¦¢ ™¡¨£™™§£¥™œ¥ª–“£œ•”¤¦¦¡¶¤£ ¤˜•“˜“œˆ®˜•ŠªŒ™£†±¥®Ÿ•›¡—z‚Ô¨‡”À›Æxw±¥·–d€Àœ¿y„„yƒ|‘Êq–¼œÅ{r¶§º{l—±«±yhlX±®oei¼’¼nhzmqØ}Rkb¶²}p”uš¡ªVNXaOVNFU\XPPS‹[W[P@\DPNCFI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22BE/.32.+/)-/186- /416A1=:Wƒw11Tk\O[M]g\>L1Z[41!§”¨ªŸ˜ž¥­²©±Â½²µÀµ¸¿Â«¦´­­©¨°µª°¶´¨¨¦µ¥¨¹®œ²²¶ª¥¤§²¯®±¦«ž§¤²¤¢¡ —œ¢ ²¯–Ÿ¤¡µº£ª¨¡­­¤¢›š£© ˜œ© Ÿ˜ž¨¨‘œ§›”ž¢§£¡°£žŸ£––’˜’™…¯kj‹Žªh…–‡­fqŸž•›©—q®¡¤~wº|k v±_j´[¥€eœ`fzfixj©e¾rg¦Œv±j|±xu‘”cmm§n\„ Eig‡–Euœ`}f{£¦X_‹«h}xzj¨8J¯[XTmcZKOX_\VV;N‡PWV/ISSJCEF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3/.53/+/(.0.:6/'$203B/=;U‚v2-Vj\OYL_gY:M5^X31’¢•ƒ­§¦Ÿ£¤«²¸­´½¾°·Å²¸»Ã§©°¬°©ª±¯¤±º°¥¥¯³£ª¹©²²°£¥¡ª­°¬¯¦¨Ÿ£¢±œ£™–™ž°©˜œ¢ µ³¡«›¡­¬Ÿžš— £©™ž¥ š¡¨¤£›—¡ ¬Ÿ¥¦ š ¡–•‘–‘š†µ›µy†©š¶™w‡³›·”—˜¬—k¦z…†‘”’w«gj±[¬{Ž‡”t‰p†€ˆ—xƒ‚Š—Œƒ …°vwŸqkkm|‹O¥XHcc™~ch¥_yquR’†]P©ncp{…€a/R¢n[Tkg`LK\dX\ZB>°wWXA#MiFBDA@A19>88:84;:9<9:A:E::;6:CB8=?KNH:5:AFBAAD<FD;0201;F,0.840,.(/3,>831/2-D1<<S}n3+Xj\OXM_fW7J9aT50— ”‰³¦¦¡®©¨³¬ª»¶Â°¼Ã­¹·Â«­­¯¯§¯³ª¢¯¼«¢¨¶­¤¬µ¤¥²³¨£¢§ª³©°¨¦ž  °– š––—› °¤œ›¤¨µ¯¡¨©§ª›–˜ ¦©›Ÿ£ œ £¥¤–›Ÿ˜šž£«›¥šœš¢ —“’““„Õ“™¹q±ÂƇ}֔œ»}œ—¨’¤{†¢¥‚y«yV¯{‰~Ÿj¹Z¹w…„}¦‚”|™zªyŽ{±mŽ„t»†o•P¯§ÅŠQ zc`ªbsr‡k–‡^Rµ´È…~ˆ|c¤3Bv]QjhdP@XfYdaJGLjJZSOYfZCC?E?0<<59<74<;8=:<C:F:;>6:@C;6@OLH<:<DHCBCD<EF81211DB./0483+-).323971#%5*>3==Qwj6*Yi[J[P_fT7H:aP72%œ£“™±¨©¥³ª¥´§¤¼·Á°ºÀ²·µ½´¶¨²±¤²³¦ ¯¶©›¨º®¤°±¡²´±¡¤žž¨©±©´©¥œžž¬—™™˜˜–˜£®Ÿœ—¨®±©£žŽ¬¢§–˜œ¡§¢˜¢¡¢¡›¢£¨œŸ¡ž•™›§¡œ¦”››Ÿ¡˜’•ˆ²nhµr¬ˆpŽ§s´ut¶{œ™¦Ž£~ž£~°u‚ÒÒu\®|…¤n›ª¦j†…}­}˜™{±s“y³e–t…žnŸf”RɋZÂ\Ÿyb_­_vs†a–ˆ]YʝoÀ€tMKµSUÆdVRjceXAOj_liPUFH9=WR[VYHB?J<2?;5=<56>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>II:1746@>/.24252-).26,742&60;5:=Pqh9'Wi\ANT_eP5G=aM62.£ž‘¥¯­¥©º¬¦µ¥§¶»¼²»¿¸·µ¼¼´¦µµ£²²£ ¬°¥˜§»®¥²±´¸ª ¥¡ª¥²¨¬ª¥š›©Ÿ–•™™“”¤«¢˜“§«±¦¡–’¬Ÿ¥’”¡œ¥§ •›¦§¢›£ ®š¡žž–œ£Ÿœ¥”•™£Ÿ–™–“›…¬|x¨w£‹‡©p®‹„¨„šš£‹“š‹¢}’—‡®„³\r²S¯}‚‚£~q×}w„~†™šw¯†Š‘œˆw´ašeš‚•l’[°WKšu˜yf`­^vw‡g—ˆj]¯w•Ÿwl5yÈ®³`DUo^g`EPl_pmVUM.echRYP;AD@L:5?91><16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK97<46:>/04333.2..18*.32%!03767=Pke>&Vg\@=V_cN6GB`I:77 ” ·±™³Á­¨²§ª²º¸´¹¾¹¸³·¾¶¦¹µ¡µ­  ©¬ •¨¶¬¨±²«­´¤›©  ¨¢µ§¦ª¤™ž•¥¢””š’–¤¨œ”§­°¥ ”˜©Ÿ¢‘¢š©¦¡•š¦©ž¤Ÿ­¡ Ž”ŸœŸ ˜˜œ–—¢ ”˜‘§ž‡©~¦y¡„ªp­‚§†—¡¢Š˜—ˆ£†”ªz‹yp±Z¨ƒ‚ˆ xtØv‡t§Ž›’¤|•Ÿ„{²^œd }‚•n“\«\[“‘hgªcr{€j˜†q]«Z‰ kndOJC¡\[Mt]bfMZa_rt_JU5Jš‘XHE=HFAM35A8.;>05A78@<6=<F?:<6?=B7.HVJE@H6KIN@IK@EN::@4.;>002154+*05/7,&21($$6671<OedA&Uf[?1T_bL7FH_C1=7¢šš¾­˜³Á®«­¨¦´°¸±µ¿¹º³²¹¼ª»¶¡²¥Ÿ¦§§Ÿ“«²©°ª¶­ª¯¡˜¢ ¦¤¤º££¬¡—›‘£ ••Ÿ›•™¡¡‘ŽŒ©°°¦–š§¦Ÿ’¤˜¨¬¨•˜©¨ŸŸ ¤®£¡ž¡Ž•¡™Ÿ ’œ—œ–ž¡–—¬œ®nr´t©Œw‹¦t´zu´‚”¦¤“‰¤‡Žu¸n‹{‹¢kk¶Z¡†e——h ¢§m”r´s“™³j…’ˆ­ju´af¢n†’k—\­`N¡|‡‘Rs£ly~n˜†o\¯V<œweTon.[§ObRkeblYb\`p|cSYQ>?lo2BB@?M:!7@6.;@37C58??3;<CDBJFMIF62JTKEBJ6IJP?HOCFP=<E50;;010/75,+,326/#00,,289/9N`eD'UdY>/U^aL5FM^81A8¥šœžº£œ±¿®­««§·©¸¯µÁµ½²±»¸«Â·ª¬¡§¤¢’««¨¶£³¨®ª¡—¨ ¥«¸£­œ–™¥£–Žž¡œ™žŸ‘“•«¶°¦™“›¬©—Œ”¦š¥­£‘—«²¤ ž¨¬°™¡£™¡— ›–›—¡”©”«™‡Ô”š»u±Ä€Ä‡~֗œ¸yŠ’™Ž˜ŠŒ§‡y¢¶u}wv‚š²aƒºyÀ|u¸bµŒ‡©}–‚¬©q{u¼ˆ§ ia¦Ž¯¡~Œt‡«}¾ns¼t²ƒuxŠmšˆpm¤t½]w}[ay¼jZV[iy^i`dfbmyoX[YCA@q?CG+5H"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,;:08LXaF'TcX</T^`K5<L[-6@9§šŸ¢¼£—°Ã¯­©ª¬±¨¹¯·Å±»³¯¼°®Á²­¦£Ÿ¤¢œœ‘ª¥ª²¤µ§­¤Ÿ–š«™§­¸£®™•¡¦ “Ž¤Ÿ™Ÿš–“¯¹±«•—£§§”–¥¤­Ÿ‘ ¨«ŸœŸ©¤²ž¢¥Ž¦¡•¡šœ—•¤™° ’•ªŸ…™¶€’’¸–xƒ“›¶wnlotoy„Ž‰ržÀ»¼š{²¨p€t‘¹ƒ|††Š‡{Š†—}¤»¹½œuy³£tv—ut°u˜žf†i¶trqw¶Œ^y}‰gƒylyb‹¬pt…~X[§iDdYTf_c]cQgfqmuBMOLD;ZL?J3<0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITBKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7KT_G'SbW8*O]]=+;VV'=:<¦¡¡¿¦•²Â³«ª¨¬«ª»¯±Æ¯µ´°¸§µ¹®«¤¢§Ÿ ™”¬¤®ª¦¶¨¨Ÿœ–¡¤ž¬¥¾§¡ª—•œ‘¢›’¢¨¢“ž—’˜”²µ¶¬˜ž£¤¢‹“’¦œ¦«–©¥¦œ›¡©§§£©¡‘¬ž—¢ž—–˜ž°©”œ§¢kjœ©y‰t›v{f‡{¾¿Àºo’ƒq”…_rjZ^›‰ac‡Ž•k`”cmœvb”k€š•”e^`cqš‰hrŒ|†”fj~ptx~}b[xthP\n„||ŠjXlyrIJo…pNrMDV\f`LZWfc_OZmvjrRODEM<HI<L>2,2A?8/5?C<9;@;=C>RVVWYZ[[\]`aaa`\UG5CFUEJOHFPIIH;8=51:.1;:./-76=5&"/*2,%;8-7IR_I'S_V4)P^L(3>\O'?2>¨Ÿ¨¡Á¤™´¹¶£¬¦®§¨µ²¬È¬°´­¶¤¾±³§¡¤ª£œšš¬§®¤¥µª¤›˜•¢œ§­©¾¨©¥•”›– š“™¦©¨‘Ÿ˜œ°²¾¬›§§¢‰“’©›¨¤œœ¬Ÿ£šœ£§­¢Ÿª¢š®›”¦ —•Ÿ˜±¥™¢¨™’Ÿ¤¦›¨¤›šœ›‘—‚hn}rw‘—”„‰´ª…˜•ŠŒ˜–‡”•‰ƒ““‰‘”™“™—šŸ¡š›”Ÿ›‚z¤…li{}€u‰‹‚r‚xyvvŠ€|‰js‚tƒudw}vkoyl_b[ogMXYfj_WYpzomfSOFR9PZNRO(+:KB635=@A9:C><ENSSTVWXZZ\]`bba_^^[TKCSGKNDGPLOI<:;489,2;820)6IRO8")+/2#4;*7FO[J'R^T10T^:+=8]K,<-@² ³¢¿¢£°±· ©¦³§¥°µªÉ«­²¦µ¦À¨´¡ž¥¦œ¥–– «§­£¤·¬ ™—– ˜­ª¦ÁŸ¬¤–’œ—Ÿ˜”•¢Ÿž£¨“˜¨¨²Ã¯™«œªž––©ž«œž¡­˜¡›¢¥¯¦¡¤¨ž¬˜–¥™š¡žž°¡¢§–™”š”¡£—¤ ™¡Ž—•‹‹Ž˜®|•›‚‘‰©¨…€˜–‹„ŽŸˆ{„‘†…š‘‡†Š•Ž›—Ž˜ž£–™’œe¡³®„‰„w{Š~wyzogy‘‰kuyˆrhsyuƒ†jtbxe_hdcdfjXk{qjk\SLPD_UF@??,4@F;45;>A;<?>>HNNOPSTVVXZ\_aca_^^]^]XVJKLBIOMRJ;<:786/3964.(&$-1..)+*7%+<(6CMLD/T\Q05M[17E4\G5<,@³ ¹¯¾­ª­±² ª¦²­¢¬³°Å°«­¤³¯¼¤´œ ¨£¡ž™—¨¦©¦¤¦³µž••žšš°¦®¾¡¬¢‘‘žšš”’–¢œ—©„©«£´Ç³Ÿ©¤ª––˜š§ž©œ ¥«”ŸŸŸª®¨¥£«¡«šžŸ¡˜¤žœŸ°¤™Ÿ©”™™ž“¦›™ªŸœ—f„“}e›cyŒlhjz£«ješ˜~h…Šeeihz¢ŽkhŒ—‘¢wkj‹™¢Ÿ˜slnz„Œ†yXe]…^l‹Š‚w\gsww’€ˆ‚ox‚xsmy„svˆ‡‚zh„X]jsd]sˆik|qmc]QNWIdX@J3=F7?FD71<=?AC;;DGHHILNORRTW[^`aa`]]]]]_]ZUODHOKSN=>==6535554*&&%,*%.++'6*$;'/AI[J.6ZO6)EY/DO1YB;?.=¤žº½¹¯«³°«¥¨­®°¦®®°½±ª¨¥®°°Ÿ­˜ ¤ž¢šš§¬œ¬£¦¨©³®ž–¤£°¦¶¹¥®£š¢š“’› ™™¦–{¤«¢¨´Ã·¥¡§¯Ÿ•ž£ž£¤ª¨’Ÿ¡ž ª¯©ª£ªž¦›¥ž§ ¬–¡œ¥±¤—¬–¢Ÿ›”¦™ ¬™Ÿ~½„‰s´s…Ÿ†­hw¹Ä¸q’¡£z¦˜™tª|ËÀÀºq‹£‡ƒž}–˜ˆžÀ½‚–œÁÁ|z‘ŒšÂÀ}j¥²ooÊz›x’„€wy€yq{€†pw…‹’xlu‘be^wc_e€b^thmdbXKVIQZHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^__a_^^^^___]\SMPGUNA@?=6468266*&%#)*&.+*)109*#>I[L*#CP/#F[3PY/UAB;/8•¢¹Ã´¯¯¿©©”£¯©°¯­¦²¶¯ª¦§¦±« «˜›£ œ›ª§¢«¢¥¨¥¥´¤ž£“¦®­¸´§¯¢’‘™¦“‘ ¡˜› žˆ¦«¤«­¿¿±¡©¯©–’Ÿž¢™£¤ª£“ ¡ž¬®¨«¥£¡¤Ÿ¤¥œ­©‘¤›©®ªœž«®£—˜¦—¢¤˜Δz{¥‚z–—›_­]Ž¨€¡¡|§•›u«ƒ€¯^dŒª{¨‡… t—“ˆ³c‚«† ³j„¯t|–‡¸a‚­Y£Ínv{Û{™q~ˆ“ve{ˆvvl~‡m}…}k€Œ_pjof`_xd[qhjdf`RTSW^JOC5AHED8>5;@?A;=8@>??BDDFIJLNPROS\^__^]]_``__][WOUJ=?><5578164('$!',&&/(&+360$7;SL+,-J0';[:L-!P@F4.1¬ÁÀ¿´´°·˜ž‘£ª©­µ¬¦²­¬¬¤¬¦°ª¡§œš¦˜œ¢¯Ÿ¡Ÿ¨§£¦¡Ÿ°¬›ž–¦®­±«¨¬ ”’›Ÿ¥“Ÿ¥—¨£ž­£ª°¨¿Å³¨©±®–“žœ¢—¡ªªŸ•¡žœ­®¦©¨›¥¥£¡ª’¬³–¥¢ªªž¤§§¢²¢“›§œ¡œ–•‘—¡r…Œ˜v…¨‡q±|q¬}  ¥žx«‚~­r­¬‡†Ÿv˜’{|—~ªˆ¢Œ‘‹œ}«zˆ’Ÿz­VœÄ{p“Á}•mupŒmfwe†oawnrnˆ‰Žƒlcmsuo`fmd_oijnfcWS\`ZRRC9II@C<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;91478452&# 1' 1''45-&7=WJ-<(=1)3V@F!G;C1-+¯ÓÆDz³Ÿ££¢¢­¯·¯©±§¨ª¨®««§¢¤š£•Ÿ¦« ¢¦ ¨¨£Ÿž°­˜›–¨§¯­¨§©ž—•š¤¢’”¡­š§£¯¬¢¬µ©¹Ì±­¦®«–•œ¢™Ÿ®¬–¡™žž©±§¨¨›ª§£¢ªš¯±¢¨«®¦š§«««³¤“˜¤§œ–“…¤k¤uŠz©u{²q‚¥Š˜Œpˆ ›‡¤_aR«…€®ƒœu®‚¨††Ÿz™—†{f€£Š¤˜†£}©”†®^{¨U¢’z£Ÿ€|İŌs¯´³¹rb©¯Âuh‹‹–€k—mkxxwnkfddqqf{ic\V_iXXTLLQLCCAB;C@@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799664,&$" ''!+-"$.!3-&@DWH,G+56*1PKL# A9D4,'ÂÉÕÖÀ¡™«¨¡¯¢Ÿ°´°°©­£¨§ª««¨¤¦ ›¥Ÿ¦§¦¤¬š¢¬¡£Ÿ¯£ž›“ª¤µ°¯¡©›œ–•§¤‘›¢¨Ÿ ¦œ°¥¢¨±¬¶Ç±µ©¬©•‘¢™ ¥³š¡”œž§ªª¢­š«§ ¡©¢²¬¡ª³²¢œ«©°°¸¥”—¥©š“}ªmŸ„ˆv«y|°n‚¤‹‰Ÿ–•ž–Ò¸´¸É‚²_a”©ƒ¥ˆ‡ z˜–šyªÉtš£”¨©’šŒ~š‰šÆÆwe¡‚¥sŸŽ‚}¯^oµc±uK£†m§Gƒ“dŽ›‘{o”|myt|zm[ejrqf€i^aXcm\^YILLJEDBA=A<A?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75785/)(%&%$&),5FNPPMFLJVF*L0/>-4NTQ;<F2,$¨¤Àƹ­©²®­¥¢³¹¬«¡¦›¨¦ª¬©¦ ¦¥˜«£Ÿ¯¬¦¡­šŸ©¥§µ £˜”¨«¶³¬›¦œ –¦­’šœ§£ ª§®¡£§©°³Á±²©­¨”‰˜¥›¢¤¯¦—¢•˜œ¥¥©™®œ¬¦¥«£¶¬¡±¹°žœ°¨´´µ¦–™©¥œ¡ƒžNwš‚€Ÿz„£|‚¤„†¦ŸœŸ”„¸||z¹‚ÌÆöw›¢‘‹Ÿ~™——ŠvŸ—Š¤˜¤¨~¯…›ƒž„¬}™”a¥l£p…}–„r¬`¤sq€ša¼}RUu‘¡•z|Ž‡ryr„~o[lnwrjnZc_hnbd]LLQSAHGFH::K>B108856877-*5==?BDGILNPTWYYZ[\__^]__\ZZZYUSOH@772.,*.+*'&?QTVWWWYXXWUOTF<E2:P[T6?G,- Œ‡™©¬¤«¹«¯ ›¢¬³µ¦Ÿ¡•¦¯®®¨§ž¥¥š¤§¡³®¢©§³ š©¤”£µ££•—¡©µ¹¤œ££“¢²™ž›¦¥¡¢¯­œ¤¨¢µ±Â°­ª­ª‘‡‘œ§£¤œ¥—ž˜˜™¥£§˜­¡¬£¤—®¥»¬¢·¶®žž¶³º³µ©šŸ±£¦ ˆÒµÃ·z‡Ž…‘“€¦x”¢wŒ¡’…¥ƒ‹r«‡†´nri™¤•‰Ÿ}—™‡‡s®‚¥›£¦Š“œˆ”šmp²\¥s“zœl™{™~n©a¢rr~Ÿbs²¸hwŽ’¤—|‰Šˆu{xlhwixsnt\ddmmfh`JZWX<HF?S3@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^``]Z[ZXURRQF:2230/++(@QRTUTSTVWWXXWUUVTQOQ[U%!2AH#)%’rŠ®¿¿¼»µž—¨¤®¶¢¢™•£ª§­©ª™¥¢Ÿ¦¡ µ§¢©§±¤”«£¤­¤ššª´´¤¥œ©’”—¯  ž¦£œ§œµ™ ª£µªÂ¯©«©¢Œ„œ¢¡¦£•ššœ˜š˜¦£¥—©§« ¤›¬¦¼¬•½°­Ÿ£±´»­¶©«´¦ªš|¨‘}|°x‹€¤¥ˆœm²o¡‡­|¢ƒ¨—š¬‰†­… ”¨ £—…Ÿ™–{’~«™–‹«w ˆ“’y¯]£|¦§dž€|—tk®]¥lr…™]`[Œ m”¤—’Š“ˆwy–~jl~b}tmy_gepohghBY_Z=JS2S8AAC7$$3+''3, /667436:@CFIKMNQSSSVZ]_a`aaa^][ZXSPONI8152.*,ATVVVTTUUUUTTUTSSVWWXVUVQHFIJ#((¼’›„©Æ÷Á´Ÿš­ ®¹¦£Žš£¤ ¯®©Ÿ£ž­˜ž¹ ¢« ¯ªš®¡‘ª©¥–Š›®±¬§ ¨›­˜™­¢¡ž¥¡™¤œ­—Ÿ¨¥¶¨¾®¤©£ŸŒ€Ž›› ¦ž’”™›”™™¥£¢˜§ªª¡¢ž¨¨¼¤—í«£¢­´¼­°©£µ±ª­šw¯~‘‹œ…‡}º­‰˜d°Œe–®}¡„§—œ‚­‹…°†§š¤¢¢‘… \lk‚³`­|{‚€²lfn™—‹ˆ±Z}´[¤ƒkÈ¢fŸ{»YvµZ²}S¯z¬X€¡m—¦™ˆ•Ž’“xwŒ›|cs|bƒwt€|ajfpmfeeOUc\AT]=H(>9=4!!,$2. *1/04579:<ACFHJLNPPRTWZ^```ab^_\[XUPMJGC553./@UYXWXWXXWWXWVWWWWXWWXYZZ[\XWWGB;ҟ³±·¾»´Á³£œ­¦¥·© ‹™ Ÿ²±¨ž¢Ÿµ˜ ³¨ª«ž°­ž¬œ•®¨¢Ž‰›Ž¯¬©§£¨™®“š©š¡¤ž™£¢¥˜ž¢¨±¨»®¤¨ž}‹›–¡ ™‘šœ‘™—¨žŸ—§¬¤£¤¢¤©ºž Æ§¦©¡¬¶·®°©¡¾°¯¯—‚ª’£¯Ž›€†¤—˜€€¸Ãº„“…¨™ƒ¬‹ƒ¯Š¨œ›¦«‘~սªb¤¿½}£‚ƒ×º·µ„”’‚ž½¾„j£o«„nz²±Çƒk«°½¬yx¢¾»t€•Œ¤š™Ž“™w™yb|ydŒfx{`kekjbPb[Si\@T`BL)<:4/$%2 $(0496678;>ADFGJKMNNQTW]a\__a^`[\YTQMHC><A?5=SYYXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ»•´´±Àº²½³¢®§¦³¦Œ—¥¿©¶¯§¡¿¦¦±›ž±œ¹¨Ÿ­¯¥§•”¯¬—Œƒš‘®¦£¬¡¥œª ˜Š£“¦§›š ¨¢˜ «¬©¸¬§£š—“{ˆ™’¦›“˜™Ž—“¨˜ž–¨§ž¨¦ ¢ªºž©Å£¡°¤¬´¶¬²¬£¾«±±œuvª¥·…e‰Ÿpg¬Šnnw¥› ‚v±›—q‘Žr—©¤›˜¯¤rlmmf‹xomƒ™q€zipig‰–•—qhi…†gq†d]ŠcioZ]g~x¦`br’pfd€’ –•—Ž“šz…“td†wgŒjx~ydlcflbKeWJkY:PdDP'J9+# ",)-2.5:457:<?ABDEHKLMOQSV\WZ\`_a]][TPLHD=:AB7MXYZYYZYXXYXWWVWY]^^]\\\]^]^][[UW^¨•­´©ºº²´ª©¢®Ÿ¤³ª™’½±ÃǼ´©ž¿«¬£ §« º£¤­¬­¦Ž–­ªŒ…•—­Ÿ¦ª¢Ÿ¤£ ‘‹¥’¦™©™–£© –œ¥¥¦®¹ª¬™š“’{„—Ž¦—Ž‘—”—”¦“–§¢™¯¥¢«¹Ÿ°Á¨¥´§­±³¬¯®ª¼§±º˜Œ¢©¦¶œ‰–¢˜†©›”’ª´šœ¤­¢´˜¤¢Ÿ¢£¢¥¢–¬§Œ’“‡“•™“˜Ž•„¤š—•Ž‹“’Š‡„~gŒtƒwt‡Œq§m}–“””Ž›’ž”•“€…’‹phvo‰wv|yiledodUaX@iZGb_MX+E=+&!640/ %2(*799469;>?ABDFJKKMPPQWUVY^_ac]^TQJEC>9=@ASX[\YWXXXXXYXXZ[[\^__`^^^__```_YY`¥–©ª¤µ·¯®¢°¥­ ¡·±‘ŽªÄ¼Ã¹¶©¡¤›¥°¨¤·§©µ§¨‘˜¬£‹ˆ‰œ§–­¤¡š¨žž“•¤—¨š©™”¦ £š§˜ ´¹§ª˜š|•Œ¡”‹•‘•’—¤Ž˜§žš´£œ¦«·¨¯Â¯¤¸§°°²®«¬¶¼£²¿š“§¤¦µ¢’¦ž©Ÿ’Ÿ¢­±›¢¤³«²š¦¢ž¥«ŸŸž—­ž“š¢œ”—«™˜˜––ž‘‡ ž””…“Œ•Œfˆuˆwz‰„tœjˆ’–•’‰}Œ–‘–‘Ÿš“†–…xq”ry‰q{~jnd_pi`\_YmbP`bOX9FFE=2<=8/*&+)&&406658:==?AACHJGJKLMSSSUZ``i`eVPJACB;9EMV[^^[Z\[[[\]]_^]^_`aabaaa`bbbdb\[c˜–¤¨£°³¬®£©§­ ¨µª›£²¹­ª«¡¢™zœ¡°¤¦±¨–›¸¦£”˜©œŽ†Š‰›¢¯ž¤–¨ ¡’—™œ®‹ª–¨˜§Œ˜¨Ž¸µ£¥˜›‰y‚”Œ›“Š•‘“‘–¡‹œœ§·¢ƒ®µ¢°°u¤¿¤³¡y{¢­µ¾—x¯¦¡Š€ªd\bvŸŽ¤žƒ–~m”µ¤©°¬¥f ¡”tz›˜p™ª™l¤©Šeœ¥œ‘—˜–‹’›„›”ƒ“‡ŽŽ’Š…xkˆv‡q|†ai‰Œ•“Œ[v•‘ggŽŒry¡–•dx—…€v—h‚‰‚nyjpe_vokkg\ecaamQY=MMNRF=@TB91/&4:306678<;>@ABFHBGGIKLTUUY]`hfgXQI<DG<9UR[`ab`^`_`aa_\]___aabcdabaaedchd^]fœ–¦£¡°±¬«ª¥©®¤§­¥’–ª´®°¥™©¥ª—s‹œ¯ ¨«§“–¹  œ¤ž‘~ˆˆšž¬š¤•§¢žŽ—’ž…u®ˆ¥š¨‘–£ˆ›¹³§ ˜˜‹‰uw“–“Š“”Œ’Ÿ™ž¥˜›±•€Œ›µ´Œ’½¨¢~§£{¥±ºƒŽ¨Ÿ„Œ†±©¯Œ‰–¢šy€‹¬†ž£©«©‰–‡™w¦œ{ˆœ˜§ƒ{³{Š† ˜™”˜–––ƒ™šbyˆ‘„’‹„nqˆz‚q†€‡t‡…—“x–h“t šs{™‚œ™„˜~‘ˆ‚˜iŒŒ„jx{qpgexnilj\diieqZ\GSLQ@E5-YTT6)!09=>643568;:=>>?DI@IEJKGRXZX[aaifYQH9DL<>bV^bded`aa`bb_]`aabbbcfgcba`edcgcaah˜¤Ÿ¦®®«¨­ ©±§§ª¥™”­Å¼¯ ”¥§´ƒœ¬œ§¢ ¾ž™Ÿš¡‘}†˜—ˆ¬£–¡¡’”‰†€‘¨Ž‡¢œ£“–†ž¹±§š’Ž…pu‰•Š”Ž›‹•ž£”«‡Ÿ´‰´š®‹Êˆ«¯Š·…°„³±…©Ž©™|¨r{wœŽ¦–h•¤y´Œ¡ ¨ª“™Â‚€«‰™¡rž€›¥}—…•³¡}¡“Ÿ˜˜€Ž”œ‰˜’‹|…”†•“Š„nt’†€{s‡„}…u†ƒ˜Åf€©‡¢jž—€™€Š‹ƒˆ˜o’„gwt{vghupghk^bnlflWdF]QL2E46M`c7&3<EGD:63658;8>==>BL?NIJLCPZ]\Wb^jl\QE=KM@IdX]cfhgbbbbcc__babcccdiicbbbecafcbbi•—£ °©©¨¦¬ ¥¹±ª«¦š”ž¢¤©¡”£©µ¢¯ §¥ž‰”½š“ ’yƒ–•‘ˆ«™œ›š¢…Œv››Ž ‘ˆž£›–˜—†¢¸¬¥™›ŒŒbm‹“‹Œ—‹Žž’ž ˜ §~¡§‡­ –® ž‘‡‚ ­±ˆ¤Ž¬›Œš~¢v€™”k«uM«x‡“œª©‚ª«~„¡|{§jž€“lg—†˜·‰ž~n`cXƒ—{dg‹s™}y—l\|—n`Sq…\`mz„`Ye‚~…™q¨«kƒ£nr¥pŸ‚œgdžlZlˆzeY_‚~aWPoventqjjo]iolkhWfM]XE9A4GC^k4+ICQMN=84859;6@;;>BO>QRKMBJ[]_W^_cu`ME:MNMTb\[ffiibbdbddbab`bdcabjkdbddgdbgeach˜—ž ¹¡ª¤¦¬’¢¶½«¯¢™–Ÿ ¥««Ÿœ­´¡§‘ Ÿ §œ™Ž™´™‹žŒ•‹u”‘Š¦––˜Ÿž~“……¬£‡œ‘Š˜¨˜™™‘‡¥¯¦¢•™‡‰€inˆˆ‹ŽŽ‰Š‘‹Ž‘ ‹’Ÿš¡¥“£¡” wœ–§ƒ£©€†¬°‡¥zŒ~„š}¢ps“‡•{žŒym‡œ‹š’œªœ‡}ƒ¢tw¦gž~w¥^˜{}“s¢n˜·´ºs“ˆ€¶¨dÆ¸|q•¶Œq€›£ct¬«a~j³~n~ˆƒƒŒ˜q€£ls¤sž‚~£^œ™³–o{—ž³tr[ž²‚ibptuqhoXjkrre[f\aLD=D5QAYp2<RG_JR=<395::6C<;@IP?TNNQ@E_^[YX``{dIC8LWUVcaZffkkbbeadc`ab`dc_`cknccddhdbgfchh”–•£¹™«œ“ Ž¥¸¶­­ š¡›¢£¤¬šš±¬«’— ™¡¤™š”ž¬›‹‰‘x‹…q€–Š¡“”—}‘‰Ž¨ †˜Š’¢“›šŒŠ¨§¤ž–‡„~k{‡}ƒ‹‰Ž“ž•›Ÿ› Ÿ‹‰wœ˜¢ r¡Œ‰©‰¨‘˜ª­€®Œ~z ™y£“x€s—ˆŒœ}•Ÿ‡›Žš¨ˆ£d¡~Š–›mžh›Žoš™{€Š§}rhtªƒžƒsªg”š]›…v„hªj¸f\©pœa•Œ_§vwŠŠ€hšu‡“’˜žm™j¦™\¨~w»j}©ZŽ„]³g\nqxwki[piwxa^dVaBPEO7VBRm4JZZ^NZD@151;;7H?:CHU?YSX]>Db]V`Qac|iEB9N[]XdfXffnmbbe_aa__``ec^bdoq_deekdcihgki–‰ª¶œ¨‰c•œ¬»²°¬¥›š§Ÿ¬™°§ª—£š¢Ÿ™–– £™†‰iˆ€r{—‡Œ––„’”˜zŠ„–¤œ‰•†‹‘œ›ˆ¨¡Ÿš‹Š€€i†y—Œ{ˆŽ‡Ž•™~’¡ž ¡“˜rhŸŠ Œp’Œ‚©‰š¡¥ª£ª~°­¤¢¸—v£³¢£ˆ”xzª™¢Ÿ™‰˜r¡}‡°µ}lš‘¡x~™µ££«¨„™|š|œštªZ]o{—ŒxžbM{{…dz˜BMŸY¢js|Žo‚Š„™v›y‡‰±³~š’¦t~mq|”o™ri£]•vHec`sp}}ne_kgu{bc_P]V\TV@YEPfDRV\aX^ID=B8?A:HE8LEXAWRZVEFa\Z`K`m}qEC<U^bZejVghmobff^a`\]^`hb_edvl^egfldelhhki”±®š„S_¡§´º³³©š¢‹š©››§’ «£ §žš™•˜¡–‡‡‰w…ny•„›‹}‘“–ˆr€‰’¡›r’ˆ˜”Ÿš„Ž¨›™•ŠŠŠ|ƒl„…q‚¡Œx„Œˆ‡‘—“{‘¢Ÿž£ˆ®†}µ„ž{¦–z©‚—ž‘Œ£ §hxn~™s sq|…˜o“‚­|£„§Ÿ›ƒ¤p^©hv£dp¦aœÓ|{™xrsc¢†~¢r£vk³‹`‚˜Štª²¨¼wƒn¿¦ª´^œor—p‚s¢r^¤gt¦`h¦lšÓ˜z‚›nvy—k›yv—rl©¥g_dyq„lhfcmuwf_aQZePQaHVIT_WS[dj[dPECKLJKAJD8P@PMXSXOSQ`eeiSdxywIFEc]eZhiSihjncjf`c_\]]_hbahe|d^dgdkdjlfhlh˜›±¬T]Kª°²µ°³¢œ˜„—¦  ¢Œ¤§Ÿ—©‰™˜˜”™“’ —‡…{p}„h|ƒ“š‚w‘ŽŠp€†“’l˜”|ˆ‘’£•ƒ©™“’Š„‰yƒvˆ€nŸ†w€’…‡˜ •y‘¡¢™Ÿ‰³¡¢¶‹z¬§¤®¥p©€›‘†ž”}¤¢š†˜qž„¢­®‰—‹Œ¤•ƒ¯£•wµ¶¶É¢s”ŒƒŸ`ž—©my–‡ ›u¡‡w ~–‹oMf£’qšˆs¥{zubƒ‚m~ lrd`œst—k{j´¶´Æ¦s˜~zœjšš«tšlsw—i™yt—qPD}³^jukx†fkfbstpmU[RXgORgIULXRU\gknUgWMJAJMKGJNAQJPdcjmeuss~x{nu‰z{UQOm^h\kiRjhilgmgce_\\\_ibdhk{_]dgcjfnmeile¢‰°¨…e@”¢²¬¯¯µ¡¢–§¡¡£‹¤¦œ›¦‚™——Ž—›’‡ƒyky†eƒŒ–ŸyuˆŒ‚j……’„‹…zŒŠ•¥’‚—¨–‹‘‹€‰z€}‹yp …y”†ˆ•ž”~’£¦›•–ƒgnxœl¢d|r¥xœ˜ph§‚™Ž}¥{¡—ƒ–rŸv€‰”•¹mŠ¢b}™£—‰nsk«ku no¦`›i‹i–‡›•u¢~š`‹†uoˆbh¡fžj›updgˆ‚or¢[_[d¡n^ˆŒq|€trd¥nx¢df§h—r‹—m¡oRˆn ^d§T‹]T˜mmrkqmphkwsjoQVUUeYSlIXO\HXhhrjYkVPREV\MXSaUhj^wu{|p}|r‚{swŽ€„w^QsagbpgPkhhklohdg_]]]`jbjivu]\chcjirlfkmc¥™¦zetm‹§®¥©°±¦ŸŠ–©œ£‹¡¡š¡¡€•™”Žš‹—‰{†q€ˆh‹Š|—šst‰}|eƒ‡•Š‰•š‚|ˆ†–¦€¡ª…ŠŠ}€€Žsi¥„}…“Œ‡—Ÿ†¨¥œ‰¦x–›~¥‰–Œ²™ž‘„¯—Ÿ¥y˜‰{©u§„šn¥¢Œ’„Œƒ¼m|¥¯‚‡†‡•—¢~¦{r¨•¡–hŸ~o¬c–Š–“x¨mª£‰uˆ‚w«‘¦ˆk’±lw³Œ©l‹†oo ž’•b«Œªw€Ž§ŸwŸ}…¤• hš‡u«fž­Œ¶sv¾Œ£“Yƒ¦«aurto{upbj}ngmSTXT``\kL\R\I]lmv_[qX[_Zgsemoqcqt`wz~yryƒrƒ~{{‚€wbydcnsdRlggomrifia_^\ajbll{o\\bibmiwmglnb–¦«€ž¤–ªªž¨§­£™ˆ–©™¢‰š¤œ¨„Œš†œ‘…’ŒŒt…zˆƒo…}–’st†r‘ƒn‹’‡†”}{‚…—¤¥¤€Ž‰„”u‚‡“nl‹¨€‚‹“ˆšˆ‹’ª¢ €t”—ˆ~y”¯¤‚œq†y’†€{r¨r}}z—–›„x{}}ˆ”•“‹w‘™¡¢…{ŠlŒ†\zyszqio~“Šq€t‚”“q†„‚e_Œxvs”upzoo‰o…†_wixŽf‚ƒ†ªœt}–j‰ˆo~u|ƒumlfŒsx{—w„ZjWyinwrqowxo]k…nigVY^V\djcU`U^Q_owykjwejjju|pqtsaoubs{xuy‚u€€y‹…‚~|n€mdyn^Wnghukxjiid\`ZcielqunZ[bkdlkymhloaŽ•º©§‹¡¢›§¤™¤«¢ ƒƒ–ªŸˆ™¦š¨˜ƒœ‹~–”‡ŽŠ‰Œr‚|Ž|~„z–Žtrƒp•†|}’‹†††y~€†˜£Œ{¦ŸŠ…„•ƒ†Ž˜wq„ª…‘œ‡œ†Šš¨Ÿ ªƒ‰•›~Š—­¨“¨‘xqŸ“„|”pª‡q~•qjo|Ÿ‹‘Ž‹hn]„œ s—Œ‰rulƒvt€Yro‡‘‚~Œj]id{…„ˆ€`ix{œ|„ƒv‚‡„izŒ‰lbqsƒw_sƒŠ‘¨–‡gŽƒnw‹‚oƒ‹wmdecy‚z•Z[ifmv[{ywtnsrƒf\m‰kkbYX\YXjqZ^`Y^]er}ztotcjji{|rzvtdmthl{uz}{yy€p†‰„{}s~zrhT\rilvpugkgd]aYjhkjqrmW[emlgryohjm`ŒŒ«±¡£¡šŸŸ˜ž™¨¢¡}‚–«ŒŸ“†š¡¤•{˜…|’™‰ˆ††Šr|€‹v…‹‚„•‰ro€s˜†„~“ƒƒ†Š‚z€„ŠšŸ¥Ÿ†wŽ—ˆ•‹‹œ—„ƒz¬—™“‰œ›†‡¡ªŸ¡¢£‹ˆ“›£™–«¢¨§¡“œ‰™~z†©€“‘’“œ±¥š”±’˜„¦–¡Š‘„‰“‹l}Žwwfƒ†‘‹}‰ž…‡‹ˆˆ…„‘w|zu›¤Š‡‹ Œ‡–€ƒwqu†„x‰ˆ‹‘§‘„‡Ž‡ƒŒ‹z…‰‡uj€ƒ|y™iqh`sŠp}{wvowt]^o†gn_^YZ\SgpUc[[alhs{{rnpcjih{mx~phpplf€{r‚€w}„{mƒŒ†|zy|}zƒxNdvjsnq{dkebb`[sfpfrqlU]ltmhxzpgikeˆžºŸ–£¡˜•™˜”˜¤ z~—©Œ…ŸœŠ–|x”ƒ{Ž™‰†ƒ„†mx€r€‡~ˆ’ƒmk~z—‡„ƒ~€†„‡|‡ƒ›‘†©ž‚rŠ†’’‹œ‘|{©ƒ‘—•Žš•†…›¦Ÿ¢š†ƒ’š™™™¦¡¦žž—‚“Œx}‰†§|}‘†˜© œ“œŽ©’€žŠ”› „˜€ˆ„qy†rua„‡vŒ™ƒ‚†…†„•ozvu”¤Œ†›††uŒ~~ss|‰…{y…”¨‡…‚‰‰ˆtƒ††‰ymj|{mhklf^yh||vtvtzw\`p}nt`cZ[^QflSdZ]ajhuy~pllcjjg€krkktnwn„yn†€v‚€}…wrƒ‡~|{|€{‚‹`i{kuhjƒdjc`i\cugobumkTbqyeoyzrejmm‹ŠŸ¸š¡¤Ÿ“’–—‹šŸžœzwœ¤›‰†¤“Š˜™xyŒ…{‰‘ƒŒ‚‚‚l{xr€…}Š|kh}‚—‰ˆŽ|~…„‡|€››ˆ¦›p‹‹Œ’† ¡Š…Œ|§‡Ž‘–’”‘wŒ£ ¡–šš™“š£¢¤›˜’œ€‡{…‰¡~|—¤  ’™¥Œœ’Š”™““ˆ‚vu‚qwa~Ž‡sŠ–}ˆŒqŒ~‚…†jyrzŽš“‘€˜‰Œsƒ‰}}rz|†|{“Ž„—¦”†|„…†„t€……xdpz~xypkjf^}sh|uus|rj^`tvpwdcX]^RjhTeX^`givxqfkclge€jm}gmpj}w…zk‹r~uv‚†|z€}jrƒntibˆhlb_qVtolm`xhlWjsvctzzqbkoy‰Ÿ³’¥¦Ž˜†œ š›{u£ž—Œ¡Šˆš–wz…‡~ƒ‰~ˆ‚p~ztu‚…~‰wgc}†—Š‚Šx}€ƒy–€•—••Ÿš}o‹‘“…¥›‡Œ‰ƒ¦•„‘Š•–‘u‘¡¡˜”—yŽ˜——š¥žš”•{’ˆ…y‡˜Ÿ‚ŠŽŒs—¢ ’˜Ž¡ŒŒƒ˜˜„”—›™Ž}ŠŽ‚xr~n{d€|‹†q‡“€‘‚k‡ƒ€Š…gwp}ˆ”šŽ~”y‹}‚‰~|r€y‹†z…’‹Œ™£—ƒ„Œw‡ƒ‚uz†ƒs^vw|s}vfkc`~jkvssu}p{ccasnurmaY_]ZkdRbW_`hkty†qbjclfh|‚khthloh|yl…q€ƒƒt|ƒ€~z‚ƒ~|mu‰ttmfŠljbcuVƒipm`yglajvqex{yp_ql……¯˜§©žŽ—‡…Ÿ“•—|v¨š‰˜y–œ‹Œ™x{€‹}|ƒ{€‚xsxys}€ƒˆŠ€d^}‹”‡…‡t}~Š~˜„–“–Œ£ —~r‡{“‘Š¦ŒŽŠ’ ‘ƒ“—Š€˜ š’‘t€Ž’”Šž§™˜Ž•—u‘‹m‡š‘›|ˆ‰‰o—™¢“•ŠŒ‹†“€”“–‡™‰|‹Š‚{qzkvm|Œn…“ƒ”xo‚„~~‹ftj}‚˜˜…€Žu’Š…z‰wy~‡}„†•¥‘y…‚tˆ†|qs~…k`ytyp|nanbd{bnovsxwrsav`oluno\Z^]]j]O\Wbahmsz‰k_iejchw‡mflhilg€|zwnˆs€ƒ„}t†‰zƒ}z„}|Žry‹xxml‡kh_irb‡hqofvgmlazhj|{wpawmŠ™š«¡¤©žŠ‹‘†‰žŠ”–|v¬—Œ–|ž“‘–”ˆv~{Š|{€vw€otszo…}€‰~|a\~’†„„rz€†z‘‡‘‘›’¤›“}|Š’£‰Š–šŒ…—’•ˆˆŒ’“Œn„‘‰ž™¢¡˜—Š—“p‹›†gˆ›•{Š…Šp–š“¡‘’ˆŠ˜Œ‚’Ÿ~““‹™|‹†ˆtsukqov}‹uo†‘Ž“rt€|‚‚‰}ernz›•~…Šu’Œ‚uŠ{p‚‚‡}†‹…Ž–ªŽ{ˆ}~Š„w}nm~ƒafwstnza^o`jt^ojzyylrpey]mlsmsXZ]_ajZOWWdcfqq‡e]ihgbgqnchheig€zwuoŽ…sƒ|u‚‰…x…|x„†z€‰w‹{zryƒjk_phtkqomqgoke{bnzwpkww‰£™£¨¡§›ˆŒŠ†’št¨“‘† Œ•“€s|v…xxrs{…kroym‰v€†nq[Y~’ˆ€vu †Š‘œ— “–w‰~€ŒˆœŠ†’—–…ˆ”˜Ž–‹ŠŽŒŠŽ‘„m‰‹‘Šœ–¡œ™–†™‰l‡¥…gˆŸ‹“€„Œx“˜‘‘‰‰”~™}’Žš’}‹„pvplnoq|‡jsƒ˜Šqx€u‚‰ƒzgtpw‚›}Š…{•“{xŠur‹|‡Ž{‹‡…Šœ¥‰|„wŠwwli~€[qrqoovY^o`oj^oj|zqnmjmw`pokqmYX`aamWPSYefbuo„‚b]kmdcek’m`ff_gjurro‹€t‚€yv€‹€y…~w‡†vƒ…{‡‹{vŠjqb|b…|oplujhnlwx_q~y{sus‚~¥–›­Ÿ§—…Œƒ~–•ƒŽt‰ž“’…ŠšŒ•ŽŒzrxt‚pr…squˆlnltl‡vƒ}mnUQ«”‡‚x€vrƒy‚ ‚’‘—›‘™w‘z‚Œ’¤š“Žˆ”˜’„…–˜‹“‹‰Ž‡„‘‹}r‹…ˆˆœ™Ÿ›—••€jˆŸ‰hˆ¢‰”…’„Šqƒ‘—šŒ‹w{“‘{Œ’—Œ|‰}lwjoklm{bz~—wzxƒ}zhumv‰—Œ€‰‡|•‘r{†qxŽ{‹Ž{‰„Ž‘ŸŸ†}}xŠ|vogj€w]vnmkprU]naqa_lnyphpfgsuhqlawe]Ue``qSPN[ed]xoˆ{^\hqbbee‘i_he[go}okqsŠ}v}…€uvŒy{†€x‡ƒs†…~ŒŒ„|y•xgqjƒ`‡~ook{`imt€t_t|x†wss…|y¡š±œ¦ƒŠ‚™‰Šœ~Š˜’Ž„ˆ—ŽŽŽ„wtvs€po…spqƒojium‚n}|musRN‚ßɒ֓|ptƒuƒŸ‚‘v”˜›™{“r…Ÿ¡““‰’›“…}••‡Œ‡’ˆœŽx{ŒˆŒŠœœœ›–”zŽxi‹”ŠnŠ¥†”‰˜„†cŒ‘˜”‰–‹Œ‰‹pz•‰|‰‹“’Šz†}m|espkm{z\z{~€†{ziuktŒŠƒ‡†~—Œm€p‚Ž€Ž‰~…{„‘–››Œ}wx‚xrken}jgsnghslS]odpZ_lrwflkbgxsppd_w`aUk_^tOMK_fc\xpŠt\[ev`addŽc`fbXissmkqv‹|ty†‚vw~‹s†z‰q‰‡Šˆ|~™vesn|e‡npk€Zknyzr`vz{vrvŠvzŸŒœ¯› ‘ƒ…xˆ•~{ˆœ†„žŽ…Œ—„“Ž‡uwpypn„omn~rcdwp|nz|jhlb¤šÁÜ®ï¢sluƒu„¡„‘n•”Ÿ”›€‘p…‹£—‰Ž•Š•ƒ€”…ˆ€’ŠŠ—~‡{v‰x†…Ž››—™v‹xp‰‹¦†“‹ž††^‹”—‰ŽˆŠŠ„‰l|—‚~Š‡Š‘†v†~~l}dxujoztXˆ{’‡†z€†zftj‹‹„„˜†mƒwo‰“ƒ’†„{‚’—”š‘utx‡Œtrpesw€`rloahtfR`pgkU_ntyarc`i~qrn[cracVnZ\wLLKcfa]vsŠm[\dx^`df„_cc^Xirknkrw‹}sw„xx|‰qƒ„|}ˆ{t‹ˆ‡•…Œ˜shuqyl‹{ntp€Wpyvyqdvy†Œhv€‰q€ˆ™¨œ£“…}qŒ“xx‰œƒ„ŸŒŽ|•Œšˆ„|swpsjokil|t^`wv{ptzg`e|ëÚµÉÃ܉slt€vŠšˆŒi—Žœ•’ˆp…ˆ Ž…‹•ŠŒ—“|’‡‚ˆz‘‹†‚€wxƒ„r‡‚“›–”˜†vˆ€r‡„‹‰œ¤…–Ž „Šaƒ•…ˆ…ˆŒ†€‡h}”}„…ŠŽ‚r‡€rwhvritxmZ}“ƒ†}€ƒ„‹ƒvbumŠ‚‘Œ„€€“’~oƒmzˆ‘ˆ”…}‚‚“”’˜‰orzŒ…tkoipv]qgn\it_QdqhfS_pvt`p`]hƒqsjWgiciWmW[tLJKef^ars…i[\ey^^dgz`d_]YknenjtwŠ~sr{vzˆs…ƒ|‡vvŠ…˜‚{“vlwvyy“unwz}Xy…q€ngxv‘‚dv†…qŠ–†š¡›¡Š†so’‹qvš|‰™ˆ‰{Ÿƒ™‚yqtnodr~hflvv[_x{zqqiagaÕ¶Ž‘¦xnqw{q’Œ†j˜ˆš‹…zh‡‹™†’‘††—Œ{ŒŒ€€‰{~‰…zu{ƒ|q†€•™Ž“”‚‰v„ˆx…‚•Ÿ¡ˆ—‘¡€‰a”‡„‡ƒˆŒ‚f}‘€~„Œ~mƒ}ƒulmwutwvlcŽ‚€…|„€…‰p`tr†}Žƒ}’Šzr…g{…Œˆ…|…€•‘“…opy‹~tlmiiwzagjiXktYRhribPbrxlbe^Zj„ntb\g_em_oTZnMGNfd\fnr€kZ[cs_\ckvde]]Zllbmjsv†€qo|}tx†x…ƒ|€‡ux‰’•{‰†v‰oxy{ƒ’om{€v^ƒtlhzs”sgs‡|r’’„šŸ›Ÿ†‡uu“~mu’–}‡ƒŠ™|Œšv~vqoljat|gbisyZ`w{ymq~edhhW_rs—¼Ä„vq”ˆ}q–‹†›’‹‡rjˆ–€{•Œ„š‹{Š†|{‰‹”ˆu‰†vw~ru†ž”…”„„rŠw‡~‹›Ÿšˆ•ž‰f~“‚…‚ˆ‰q}f~Œ|y€€ˆŒ}i~„vgpyxswtlkŽ†‹‚Š€y‚…„l_sy{~Ž‹‡|‚s‚jz…‰‡…y…~‚™Ž‘~nm{‰}vtnfe{tb[pbWnqSSmrhaNftxf`^]YoosZeb]jn`pOYjQDSf`Zjnm|nY[]mcZbpvcf\]`kicljsvƒpm~|tuƒzƒ‚|…v~ˆ–x„Štˆryy~oo{€qixz~ml{u•kjx„tk“†Ÿ™ ™„ˆn}‹uiw—Ž~Š‚”—‰y•oztqkid`szh`epyZ`r|ygqyaee±²wKbZ¥ÙЖq{Šw}“Š„˜‹…nk…’’zy’‡„˜‰{†ww‰Š„–€p‹ˆqu~{jy…ƒ¥„“„p€„x†{ˆ›–•’–†ˆq{“ƒ}‚‚ˆ‚m€wh€„xr€ƒŠˆ|e~„vdqs€iyqou™Ž†ƒ‹}wy…zƒk\rs‚‰‡Š~‡Š{‰s‚or…ˆ††s…{‚šŽ…yno~„vzdfh{o^XvZXpkNWqrf`Klwta^\[Zu~spXg]fjr`oNWgR?Xf^Zokgzq[ZXkeYcpy^g\^elgekiqwˆol~€uo‚{‚‚v„‰—‰q‚q{†|zy„“Œujy~ko~t|or{z“on~xg’‹ƒ¡™œ‘‚…f†ƒogy•ˆ}~„‚˜‰|Žixskkf_aoym_box\dk‚yaqv_eeÔ꽋2:>‹Žqx…‡u‚–Œ~’‹~mk„ŒŒu|…”ˆ|‚wnv‡„ƒ—woˆ…lu{ufy‚ƒ§‹‚‹„~nvy…|‰Ÿ’Ž’“”ŽŒ‡{’†w~ƒŒ‚jrh€~xn|}‚‹„wbz…‚rdri~nuru‚œŒ€…€tv~€s‚o\nuy‹„‹|ˆ~‰y{rmŠ…‘…Œsƒz€—Œ‹€unkv€€ut[ggunWV{RYodLZrre[Ipxo\[[Y]t~thYb[gfodjMWfQ=]e\]ue`upZYTncYdpxYh]_gmgikipw}Žmi‚„yn€|}zu‚€“„p‹nw~€{{ˆ’‰hz}js{r…zsv}~Œyx„}|kŒ„›ž–Œ€l}kh~‹z}~ƒ“‚~}Šˆkvrghb[bgso_aks`hpˆybst^cd› n\5Z¯µti€ˆ|‘†u…•…sŽŠ‰vol„‚†ty‰x‰|’‡y~rgv‰~~˜oq‡ivynfy‡„¤‡€‡Š~o€w‚ƒ›‰„–“™ŠŒ…‰|ˆpz}„{h~lj€{zj{w‚ˆr`w~rdrgvƒnu{†–’‚}‚owz|umYp€wuƒ‡xˆvƒ‰{yto‹‚‘‚†s€~”‰Š|onimtm\fdrpPZzM[n[O[rodUKsxiWYYZap€t`]]agdiifNYhM@`c[`ua]ulXWStaZdnqVj^bhjgmlhpw|“lh„Š}}p~~{€zwŠ‹ƒq|‡oqwƒ{‰Œƒj}{mwxvŠv|x‚†ƒ~}zm…Œˆ™£„ƒ{u‹xkl„‡x}z‚‘€€~‹ƒpsqcf^Yf_oo_`gpfjnˆtato[adjv{€¿œ¦¤È¸q„‚r’{w…’‚s‹‡rroƒ{ƒtt‡tˆw“ˆyypcw‡z€“ir„vgwucj|‚ˆ€Ž~s€u‡{‚”’…z˜–ˆ‚‰{ˆˆkxy~tgzhkytizw€ƒ}h`xˆ}kkth|jvŒ‘•{~q|v|tbVx~st‹…ƒ}„q‡Šxyqq…„Ž€z~w†„wjqil‡qo\faqmIduK]lTSYrnbQOtxaRXX]ap‚s[a\ieedkdP[pIDc`[cp^]whUWVv][emgUk^aigennhpvz“miˆy}r{~y‚|v}ƒˆ†ƒpw„rmw‚‚~‰‹“p€{wxz€Œt‚x~‚„y€uo~Š‹›žˆ}…zw…{gt…‹y~{ˆ†„v€gpn_d\XeYmra``plkhˆnatiY_dn€w©Ú©Ç†‡²qˆwoŒtz…y’‰tst}woqm…t“…xtk`z‚y‰fr„pgun[m}€“€x‘“~y|nŠxƒ“Ž†v˜Œ“ˆ††{„ltv~lgvdm{vmjww|abx†ziuuc~|gu‡–|uwq€{}n€ZWupv…ˆzm‰†tzlv„…|~z}tŒ‚~thtenŠƒlsYh^sdGmmKZ`WVUwmbPRtvXPVX^aq„o\`cmed^ocT\rGBf_]fg][{bQV\t[[gkaUj_`nefkqhpvxŽtkŽuvx~w„{t}ƒˆ‡ƒor€tqu~…‚‰Š{wxƒ{|…‡w‡|}~„€{~ruyŒ Œ‰y‰utƒx^}…—‹x†ƒs…†„w‰{bnm\b[[aVisc`[gnpf‡qaqfW]ck|Ê·¹¡jmmŠlqƒq{ƒ‰~z„yxsxut{jlvc„u‘‚vof_}‚z‹Šer‚kjqcXmz…›ˆ‚s—”x}oŠs…ŒŽ‰t™’‰†‹ƒ|y}ppo|fhqbmxqjlqx}}z]ez€xjvxfƒwguˆŒŽ•}rˆjo~yo}]YsnuŒ|‚opŠ€qwix‚‚x~s|u‡}{sgsan‹kqWi]v[GmjLVU]SU{kaOTurPQTW^bt…i]`ljfcZoaXbpHAg\`e^\V{^NUepY[jh]Wh`^rejhrhpsw†xn•‹tzx~yƒˆur†…Ž‚pp{xwvy††‡Œ†z|t‹}}†„ƒ‡~~~}‡|xuxx‘“ŸŒ|Šmu€xdƒ†•…s‘Šo……zƒtdnjY_[\]Tgrd`Ydqrg€rbkeW[`jx¾®{Ÿ·nas…hszqx„z}‹~wwrvo{vejoa‡uŽ€sjb^~xy‹„fqhkkZVow‰£…q™“rzw„oƒ„”Šu—ŠŽ‰…‰…}xtqnhx_jl`mvjgjlywzvZg}|yfs~m…teu††–€pŒgk{„unub]q}lu}Œ|‚gv‡~nqivy€t~m{|‚{yqflbn‰}lmVi_vUJijNQNgLX{haNUukLQTU_fuƒf^`qhgbWj]\khJDjYadVYUyYMVmjY]kd\Yec^temdqgrpuxq™†v~w|…‡}us‚ˆ€•‚nsy{zss…‡‰‰ƒx}u~|„Šƒ„{~‹ƒ{v{wwš˜z‰‚†iv|{lƒƒ’rŽp…‚‚pglgX][\[Sdpd^WbrujuoeecW\[hpor€s‰ddy}isusrƒw€ƒxvrunkzqagkg†sƒmf]_}p{‰imxgjdUWro¦|„{v–‘t}t~|o~}“‡xš}‰‡ƒ‡ƒ}upqlgt\lg^ltdgeizo{rYhwuhpx‚vbw†‹|•oŒkm{‚qgtfanzgsx‹|bw„wjlru|r{{th€€ywodfbm…{ljUhaoRJhjOKNoG]zfaMUtdJOSWajv~f]gsif`VdWbp\LKjWcaUTUsVLXudY^k`\Zce_vgmbpitor~tt™‚w€x€†„z}u‚„—…nrt|zuq„…€z‹us|•€…„}}Œ†z}€v{£¥Šyˆ…„kt{zu‚€‹zn„sy„}‚ƒvojieV][ZZSbnd[Xas{jhmi`bX_Ziiko€gl`hyxjrssmƒ€z|utmzhjyj_enhv„geXbwj~‡{ojpgf]TXogŽ§wz|Žyvq€qux{‘z—v‡ƒ€…ˆvjruggn[lc]mr_gajxh{l[nƒstjp~zxaw†…y…t‰rpzsdri]qxert‰|yct€qgjyusmyxvye„|ywqddcm{|jjTgaeSJkgOGQjE`wfaMSr]JMTZekw|f^mqid]VaUnnVJSgWf^XMUlTJ[x^[^k]]Zce`yhlaoovnpwuz˜~wy€€‡†zyzƒ~“„qttyvt…ˆ‘}€|kr•€{‚Ÿ…~‡}€~†‚€Š{v„«žz‡‡ƒkryu€~€tn†n|€sŠ€jpnddX_ZYZTbjg[Z_u‚i^ml\aW\\kert}ii\kvugsvql„{}|xurlygixf]dshzw’ccTeph‚…xxgijaWVYgcŽ§o~w€‹Ž{qri{q|Ž}xs…~†ndurdgg\ja\oo\g_mtezh]t€orkq|~uvbu†Œ{ˆˆ€ysu€vbqn[rtcqs…|ues€mam{pkj|zvsg‡v{zvqebdmr}ikSg]\TKqbPFU`GbvfaKSoXJMXXgku{eenqfdZW^XweTJ\bWhXYHWePHawZ]_lZ^\ac^~ij`otxmpnvƒ—zr€€|‰Œ†}uu†x‡Œ|tuu‚yzz‚ŒŽ}~„‰is–zŠ~~…zz|†ˆsq­Œ{{†}eq‡ys|zuro†l{~lzcpobe]eVYYWcfk_]]s…hXqn[^XZ\l{bpwulaYlssgtuolƒx~xvmntdite[gufvv‘z_]Rffkƒ‚t~bdj\TW]bc¥hxtƒ†‘ynq|jzo}‡}vŠt‚y|xhdvl`f_^i^\skYe]oobze\w|knnpxytues„“ˆƒ‰|wpstcxe\qqbqr‚}tgr€e_nwjehz}uopƒvt}trb_fmn|dhSgWXSMv_PJYWHbtcaITmSJMZWilq|cmlscbZZ[aw\SKc]XiSWGY`MGitX^`l[[_bb\„ihanxymojvymƒ~€“ˆ„vt‰tŒ†trvv‚x}}~Œ€~“~pw•ƒ|˜’y€€xz~€tˆƒtp™¡zz‰”wct†xswtktn~kx|p‘s^pn`gblTZZWhcmf[\q‰eSrn[ZXW`lvciuji^Ymspksssi„|~~{vnnldiqc[jrdtvŽs[WSear€r‚]bc]SZ`\c‘Ÿeqq…„’ull{opr|~}s‚x€szzzdeug]bY`gZ^vhWb]phawa[|vijroxtsuiq‚–„‡…wtkq~ogxX]lncrtztgp~\`prb`krmnvsrxkqa\ellz`fReSVQOu[QOXQHcsa`GVjPIPZUkkk|enoqb[ZXYlqWRPfVVhSTFZ\NHqtX_clbX``a]‹jcdmzxlpiuy‡{kƒ}„š|ƒ„y|‡m‡rovz|t‚‚|‹ƒ‚—tx“…ž‰u€t‚q‡‚uo¡–sz†‹†zdv‰nmznfxpzksvsk^unagekR][UgalkZ\qŒdOon]VXUgishbted\Xmtloutxj†|{‡vscdkna\nmcsx‡kZTVcdx}}q†]d_cTZ_Yb••cnpƒ…Štki|pguxu}m{uvpzv_frc[]VacXateU_`mdaq]]~phitqtquwkm…”‚‰|†rsgp~rtpT\gkfruwtcmvVcrl[_pg~fnx~ttsknaZdijw^eScTUPSlVPVRPGdr_aFXiNIXTVmhd|ikxkbW]U[tdSRWhQXfTSHZZPMwvZ_ekiYa`^^Žnbfkyunoivv€lƒ€}‡˜{€‡‰~k“ˆrgt€{u€ƒ}‰‹“r|Š‘…‡Ÿ†{†Œs†s}‚vn¤‹r€‹vwly‹`d{pfysxlmqwƒgd|mcfghS_^Ug_ln[^nhNim`TVSogskexdd\Xoslqzwrl‡{v›zykaelm^`ojepx~gZVX`lx|{p„_c_gVX_Wc›ˆbkp‡}xllzn]xsn|kvtop|€sXjn^X\UabWdpcS^biablZa~lfltvomwwli†Œ€Š{‰nrfr~ntnd[aiiptts^imSeqeVcod|dsx}wlpmk`Yafgt\dU`URNWdRO[NOHdo\bGYiMJ_KXmd`xin~d`U_T]u\SR`fN]aUSJ\YPYtu]_ekhXba[^qcgjxqsnhvtz„r‚ƒzˆŽ~|‰‡ynŠuls‚tˆ…‡‘„•y}ŒŽ‡‘›„€|Œ…sstxro““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~}~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’’’’’’’’’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’““““““““’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ>.1111/o‡„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDARÌÚØØØØÝm=DDDDCXhggggfo„ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ-h…‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR455552FØêççççíg.55554Ma____^j‚€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}z{z|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‘‰ˆˆˆˆˆ‡Œ‡‡‡‡‡‡‰’“’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ………………†“”””””•Š………………‡‰ˆˆˆˆˆ‰ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|yzz{|{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘“““““Ž’’‘‰‡ŽŠ’’“ŽŒŽ…Š‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽ‹Š‹‹‹Œ‹ŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…‡‰ˆˆˆ‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰„ˆ…†‰ŒŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰Œ‰‘‰ƒ†‡ˆŒˆŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}|}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹ŒŽˆ‡ˆ†ŒˆŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz||||}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒŽŒ‹ŒŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzzz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{y{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†………………„„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰ŽŠ‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†…†…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{}~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““””””“””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••””•“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””’’“““““’’“”““““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘’’““’““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’‘‘‘‘’’“’“’‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡ƒ‹Šˆ‰‰†……„„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxy}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzop{xy{|{xw{xuwttvutvwuqrqnprpghklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkigfgggihgmgjghehgccbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__`c_\_]`]^Z^]YY^ba^^ZY_\XWSNMLKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{xvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSSPMJMNPROMPQQQQRVVQQQTPPNNOLJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTttuxzzxvvwwz{|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMOPPRQPNNONONOOPQONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKLFDFJKKKHJLLLOMLLNOOOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEBA@@CCDEACEHKOKIIJHGJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:<>><ED=?EA?@A@DEGGGGBDDEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@;;><;;<<HL==AA?BC=ADDFBFFDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnpprttsqrvyy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;::;89:87:<978;;>=;;:8:@@AB?A?CFDBCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqususqsxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<979::988::78:9:;;8789;:8<;=@A@=;;><==@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyy{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>=;<<>?=<=;:<===<<<<;;:;<>=>??A@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquuuusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCC@><=?@??=;>=>CE??@=;===<;:=>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVpoqssttuy{{{|~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???CED?=;<@>:;::97:<9==@=:<;;<;89;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pprrrtuvz{}}}~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC??AAABA@=<=;>=:::<:8988:;=??<;;<;::;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC@???@=?@><>@?===?>=>CD?;<=>@==>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hloppqtuvy||}||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABECDA?@@@?=@><=??@@@C@@?@@>=<=@EABBFHC=<@DCAA?>=@A>>>?<>@DGE@>@A?@CFECBCC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{||}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@A@>;><?=<:>=?BBE@?@Na_J@CEIIIIMMKECFGHEGEEEDDCA?@>>BFJJGEEFFFJNNKJIGGHKLJGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|{{|~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@DED?<ACDB?>A?ADEDCWu†‰Š~XGIJLLNOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHIHGFEFFFDFHGEEHHFHGHFQnopqrvvy{{{z}}~~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJHIGHHIGFBDFDDCAUt‡‰‡‡†ˆ‚WILMLMMLJGGGGDGGGGFHFHECDDFEDDHHCCCGJJKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrtwwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLKJKMJKHHFFGFEPl„‡†††‡‡ˆ‡|PKLKHGFFDECC@ACCCCFFEB@>>@AA@BD???DFHDEGIKIIGHIGIIIJIHFJJJJIJIJJJFILLJJKKfopsstvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKKKKKMLKMLIFJVl†…„„†††‡ˆ†ŠuIIFB??@???<<<>::<AA@><998<<=;>;9;?ABAACCC@ABEDBCFHIHHHLMLGIJMMNMJJKKJLMSloqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHGIIKLONNQNQ^r…ƒ„……†‡ˆˆˆ‰‰ŒŽfBB=88::9878896479;<:8567789787689;;<>A;999==>;;=ADEHJMLLGIHORQPPNLMMOQ]oprtsuxz{{||~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56;<C@BFHKHLKMTg{„„ƒ‚ƒ„†‰Š‹‹‹Š‰Š‹Œ‰T;8656766645763468:876565677778:7778:;7689989876:<@GFIFIFEFOSRSSROPPRTepqsttwy{|{|}~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:<DBDFEJbx„„‚‚ƒ‚…‰ŠŠ‰‰ŠŠŠŠ‹‰‰ŠH676468874578467799766765::;::<89899877:::8878589;A=>>BA?AKLOQPQOOPQWkrrttuwz{{{}}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897:A9<D?]„ƒƒƒ„„„†‰ŠŠˆ‡ˆˆˆŠŠŒŠ‰‰Œz>:88;<=>9:;<89;9:;:99;:9===?;;;=:><:<;<;<;9:<8::;:999<?<=ABDIJLKJKLWortutvx{{{|{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<:89989999:>=??Dw‚ƒ„„…†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>BCEEBAAB>@CA@?=>>@?>?@?@==?B?AA?A?=@A@??A<><;:;:9;?=;;==AACABCAXpqtttvy{{|}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::;<:::<;=>@?=a…‚„ƒ…„†‰‰ˆ‡†††‡ˆ‰Š‹‹ŠŠŠ‹Š‹^>DGIKJJFGGDFHGEC@@CECB@BCB?@DHECEDEEAFEFDFFD@B>=@>=?@>???>?>>:;=<`qrttuwzzz}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:=:<:==>>;><?>B?J~ƒ„…†††ˆ‰ˆˆ‡†††‡‰ŠŠ‹ŒŒŒ‹ŠŠ‡WGLLMKNIIKHIJJIECDFGFDCEFDBHIKGHGFGGEKJLIKKJCFCCDBAACBDCCDDCA=<>@hpsttvwzx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€OA>=?DLK@BBA97;>;<:=?>?<?>BAD>h„‚……‡‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹‹ŠŒPMPMKNKJLIIJHKFDGHHIEEHFFELLMIJGGHIJNMOMLNKHGGGEECFFFFDEHHFCA?@Lmptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?FGG=<@@87<:;<:=?<==?@CBHS~ƒ„„…††‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒ‹ŠqMQOMLLLLJHHFJIDJHGKJHJGGGKLNLLHHIJMPNONMOKIGIJHIDIHHFFGGIGCBACUoquvxz{xxzz||}~~~~}~}~~~~~€€€€€€€€€€€€€TDAABGHB?8?@8:;7<=:<?<<=?BCCLm„ƒ„„……†‡ˆˆˆˆˆ‡†ˆˆˆˆˆ‰ŒŒ‹ŒŒŒ‹‹‹‹^RRPMNMKJGFCHJGLJGKOLKJJMMLOPNHIKLOQQPQOOJIJJLJLFGHGFGIFEEB@BB\prwxyzyyyzz{{~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<8?==>@ED=BDCFJu†ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹‹ŒŒŒŒ‹‹|WVRRTROLKJEFFKONOWVQPOQSRNSTOMSLPSUWRSRPLJMMMKNGGJFFIJDDEEBDCcquyyzzz{z{z{|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?=<A?AADTKBHIFIKx†ƒ……„…‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŽ‹‹‹gVVkaERQQPJ;;QSR`u]UVTVYYSYXRZfPUWZ]RTWQPNRPPPQKKKGHJHEFIIIHIjsvyyzyz{{|z{|}|}~}}}}}}~€€€€€€€€€~~THJIIGGFE??A@EACFDCDKVPJOONPPy†…‡†…†‡ˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ}aŠ‹‹‡l[dU:XXXSP?@VUY\d`VYbr^]W]ZVEQY[\Y_TYgRUVXTTVSOOMKLJIILMKOMSotvxyxwyyz{z{|}|~~}~}}}~}~€€€€€€€€€€~~~~VJJIHGFDDBA?HLIMPKIJOSQPTVUVTu…„…………†‡ˆ‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~Œ‰Š‹znpXZ[ZRSRWVTZZuƒYU}a\X]^WIV^^[[_YHYXY\]XXYWRQMPQMMOSQQURassvwwvxyxz{{|}}}~}~}}}~~€€€€€€€€€€€xy}YNKJIIFBD@A:OQQWXPPPQRSRVWWWWl‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡ƒŠ~fYY\YSVTWRQWVc–€QerXZW_hP`fZZX\hbGOZig\[\]]WRNSPPQVVVVYZosuwvvtwxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZZRSQOQRQURUSV^ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PVXTRTRQQLOMKfyZ]TYUV]ZLTZUST^ZXWWWzkXZ\\^TQQPINOWVX[Zdqtvvttvxyy{{||}}~}}}~}}~€€€€~~zxwvsu{€€tk~~kqy^[VUSROKFCDAM^ƒlVRSOOQOQVQSRRTcdv€ƒ‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ymqVIKNNKMKHJDFHEC>ScURQQNKRURMOYQMNQSUUMQSRPOMLHCIGRSTZ]mrvvuttw{zz{{}{}}}~}}}~}~€}}~~€~{vsw}~~du}iqt`d]^[YUQLILIal’tPQSMQRPS[RSRQRUUbs{|~€‚}{{€ƒ‚…†‡‚†††„†…†u_]KC>BBCCA?DPCD@C>BHGV@INMG]iQHFOFDEFHGHBCHGHKGDBAC@NPMRdtuvustvy|z{{{|}}|{~}}}~~€€€||}€€€}vt{mh|gnqfheeb\XSQPURsWe[OONLQRPUYSUQQTROV`klsvz{xyurnstsyx~~ƒ€ƒƒ‚‚€‚kLG>>::>@?>>>jPJaEFHIEB?HMMGMQUJBE?><=<==?=?ACC@?<=B>IMFUouuvstvxz|z}{|}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QQZ\Y^IJOPNKLQRQTUUWQQWVPX[b]agmmlokh`nrimlqu{z}{xz||xwxdB@@A<:BCAACA[\N{NOONKLMOOPLKLWNHGAA<977599=;;;8989?;AG>\tuuwuvwy|||}||||~}|}}}}~}xuwz{zwyxuw{|yxuywcqhipmnmmhf^OO^\ZIGOQQOMPQNQRSVXSRYTNYZ[WY\_^_e`]^qwk^`gkwooljonnlfbYGFFHBAFHEEFCLQOaWRXQPSSRU[OOQWPMJDF>:96587979:365795<B=ftuwxwyy{}}||{|}}~~{}~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZWMKSTSPQUOLRSTWXSTXQLXYYVXXVXY]WXXhsk]V`tkaa_]d`_^YUPMOMLIGJKIHFCPOSZWTTNQSYS\eUOSTQNKIHC?A9988978847578599Gnruyyz{{}}}}|{}|}~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPWVVSTVOOUVWXYSUTLKSUUUUWPTUWTUR]n^RNY`[VY;DUWT[fJLPRROMMNMMLJFPPUYSTOJNOUST\VRUSSOMLIHHF?>=:787659967565Wqqtxzz{|}}}~||}|~}}y}}|~~~}||}}~}|rvqxxruuqqnppopuvtnjddjppqrpnfedc\^RTZVWTSVTRXXYYYRUOIGOPOOMRJOPOONNOTLMIPPSTU2<XMIAQ=c`QSQPNPPONNMPNTRPRLILKORPQRSTQSOLMKLLHCBA=:9876;B4566;eprvxy{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqpuuvcjgeWhtrrqniihpVVTUXUVURWVUZYXWUQSFFAFGGHFJDHJHGEHLHKIGLMPMG/E_R=3@>joaRRQ@GTQOPPQNQOPOLJLLOPNMPQQNPOJLMMKGEECB;==<9=G6676Dnquwz|{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknbePSTRSUOWVVYYVQQQO@>;=?@BAC@BEDA@GHGHFFHJMLDGCORB8DMS]gSQSAGUPOQQPMMNLJLKLNOOQLNNMIMLIKKLKGFFED<AA>;@E;<89Trsuy{{{|||{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLONMQSLTUTWWULLKH=987;?A>==A@B=>EHFDFFIGJJ@FAA@EGDIOHQRa\QPROSNOOLLOMKMLMON[VKMQOHJHCIJLLKFFFE?BC>=BG?B?@druw{z{{|{zzw|wy~~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCE=9879?B?;>A@@>ADIECHGIGIEBB?><BA@GIDMObePMOMWKLNKKMMLLKNNSdMJLRIIIEBIJLMNJGIFBBB@?EFEHDLopvzyy{{z|zwtxtx||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGLLIMPMPOHKE?B=999:?B?<ABAADDGKFDIIGGHCC?B>??@>CEDLMQTLJIMTFIIJLIJKIJLMOPRPKGCKGCCKJLNONIJIGCCCDIJMLIZsnxyxz{{y|vrpurtyyvxjqnjllnttmsu{stxronqovsnporpopstyjN`gsjt|ygosqiqheqHJCFGHGJKIJLDGB<>=:::;AB?=BBCCHEJLJEIIFGHCC;A@B>@?BEDIMOGHJGHKDHIKMHJLHIJLJM]RHIDNGBELKNNQNLMJKFGGJMNRNMcnjwvw{y{z}qmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoijthepFJCFEFDEEFEGCC@=<=:;:;ADA?BCEEIFJJLFIIGFFDB:ACC>?CCCDGKMHJNHDHDILNMHILGFFIILNKIHEOICGNMPNPNOOMKIHIOSQRNSggfrosxv{z|lhjoekpmsqfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhmf_pGJCEEDBBAE@DB>?>;;;=;=?DB?ACFGJFJILHGGGFEC?=DEB>ACBCEGHIGMPIFFFKNOKFHIFECDIIHKIGHPKDJMMQNONOPNJJIMRUURPXeaamfproryzgehhcilfqlflmgiklsmpvutpnvrosrsutqssutsuvvvyvutvlkuumrvqlnlerMGEDFBA@AD<BA>A=::=?;>?AB?@BEGJFJGIGFFFEDCAAEFCBBBDEEGGHFLPLIOJJLKIFHEFECCHHHKJGKRMCOONQOOONOOKKKPUWVVTY`_]i`mjnhrsbeffdhhfnifmmhkkmriqvusqmvnoqrswsrstuvvvvwvwvvtwuksunutsprkksMGGEGAA@CD<AA@C<8:=>:?=@B@@@DFHEHFFHFEEDCDBDIFCGEAEGEFFGEJMKHQMJKHHIEFHHECIIJKMKPSNDRSQQRNOMOPMLNSWVWYVX^Z]d`hcjigk_defchggkggkmkmlpqgttursnvoqprtxqssuvu‚‘yvvtxuuwxnouorsuqqipzMGGGHAABEE<@CBD<7:=>;>;AB>??CEFDFDDGECECDFFFJEEIGBGHFGFECFJJGMKLKHJKFIHJHEKKLLNORTOHTUTQTPQMNQNMQWZVZYWZ^ZXa```^hec`deggjhhjghnllomqpiuuxrrpupppruvpusuvu{~}xvtwvvvwplupmsunossyMHHGIDACGE<@EBD<8:>>><<BC=@>ABFCECCGDCDEFGGGIFGKHCIHGIGFDHKIGKHMKJKLHKJMKINLNNORUVOLVVTQTRRLOQPOTYZY\ZZ\__]`c^\bdlc`dghr…hgjfjnnponsqjtuxrsstrnpqvrquruus~yŽ}uuvvvvxriuqkrtlqwquKIKHJFBDGE=AGDD@9<>@?>?CB<@>AAFCEDCHDFDFFHHFHGIKJEJHHJHFFLHHHJGLLLLLIMJMNMOLPPQUVWOKVVUSSRQLORRQV[[]^[]^``a`be^d`fh`ehjdssfjhglprqossnswwpuvtsmoruorspurvrtvuuuwvuwtgtrkqrkrwpwIJLIKGBEDE<AFDDB;??A@@ADA@B>ACHBEDFGEIEFEIHFIHJLHHJJIKJFJKHIJJGKKMLJILKMNNOLOPRUWVMNTVUSRQPMNTSRW[^^_]^``aab`cdebdicdijgv‹lkigmosqpqpprywruutsmmssmqrotuuspswtuuwvuuteqskpqjrvpwJLKKLGCCAE<?EEEC=AACBBCEACDAAEGCGGHFEIFCGJGGJEILHIJMKMLGKIHKKNQKRQLSMJMMNPPPTOWXX[NSQW\ZSVPNTUTTXZ_bb_da^ac^`fbacinhcihhmxvmhinosrpqrrrvtsusssnksqmprotvsqquvuswywutucmtkopjqtpwLMLLLGDA@D>=DEFC?CAEDDFCBEGCCIEBHJIGHJFDKJGHJHIKGJJNKNLILHJMKZfJd\KlRGNM_nUls[qpbwcRPbvuhucavaXnqbdvinzf\lu`lkU_wvijhhfglmjmojmosrprrqrsrssrtrnltonpqquurqstvvuuywutt`ktkppkqsqyKNJKJFB?@B?<DEFDCCCEEDFBEFGDDJDDJLKIKLGGNJHJKGKJIKJNLMMLLIMLL[sbdp^llULNer]geqlntgpi_aYnmbppbkjjgoqtetnn\pvgpNKqyvkaakeelxmkvlnosrprqpqrqrrrtrmmsnnoprutqsstuuutwxvutbmukpplrrqzKLIIGED?AA?=BEFBECEDEEDCHHGDEKHGKMMJLLFJNHJKJIKJJIKMMNMMMKNMM[rponpplkMPQlXNibtrpamov\YlP[mmZqmkomxxtsip]`slqjUuyxoc^kfbgppjioppsspqpqqrrqqrrtlmrmmnorutqtrtuutuuzvutenukpolsrryJKGGFEEBAB=??EGBGDIEEDBFIHHDGKJGMLNJLMGLNIMKHJMIJJJJNONNMLNML\hdu]lqWlNOQmUZk^klvaldtTecNlYl\tpkilxjwuhp]_skhWbcw|oc`ghacityknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtvIMGIEEDCAB<B@BFCGFKGECCHKHHFILKFMKKRRLHMMHNJIHNGJJHHNOMNLJNMJZtppoqqmlOQRnYskgooqqomt^nXat_nopoqroousttj[^tcwxrjnzhaacfabjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyytukoumtonssvtIKHJCEEE@@>CCAFCHIMHFCFJLIGFKMLFOJKWRKGKJJNIIJLIKJIIKLMMLIKKKSkbYi^_jcrrZ_Yjo_eeUk_d[abQ`mh\j\niid[oedp]Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunwqrutwrHHFIDEDFA@AEDCGBHJLGFDGKLIEFJOLIOJL[QJFHHKMIHJJKKIHJGKKKKGHKJLKLJIKLNT[]TPUMQONOOURPPQOOQJJNPQdqiTYV[[\UY[]X]\\cfaafbcf_^fkmhmtxrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyyxuvqruovrtsuusGCEGFFAEC?CGDEGCIKLHFDGKLHDGIPKLOKLWMIFEHIJHIKHLJIFHHJHHHEFLHHJNKHO\W^O\\`^OXYS\\b^MYZMXaRKYaZS`d\aX[ddVVX\YZX\VY\^c_d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtOBCDLMACDBDIEGGFKJKHEEJJJFDGHPJLMJMRIHEAHFJIKKILJIGEJHEFGEEJGBIMIJT_Y`X`a[`UXYT^^Z_RY\P^\YN_\^S[^d^Z]`c_Y_b[`^[UYXZ_^dcbaceiekrpoppnow††……†‚{€……††…†…uqprrsuyzzyyxxxwryvxrqxvtvaSJJMIECBCFGEGGIJJIIDFKJJEEHINJNLHLNGHF>GGLIKKJKKIGEIFCDEBFJD?IKIN[cY^^a_RTSW_`\]Y^QY\MV_WKQY[Q[_ba]^ca`bbbcceZRYVW][^d`__cebhommllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxXQJFDGEBEGHFGHIFGJGHFHKIKDCKJMMLLHJJHJG?GFNJKKMKKKIGIEE@DAHIA>HIFO]aZ[d]_TQRX]\\\_[KW\LR\YIM^QQ]_bccccb\dcbdceXRVUT]Y[a_^_aa_dlkmjklnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMC@IFCFKIFGGIGGJFFFILJNECKJLNJLIKJIIGBHHQMKKOMKKIHHFE?EBHHA@FECT]Y^X_Y_[]UXXP]]QKJV^X^[]VZaRR__bb``bb_cbbddbXPRRS\T\]]^^__`dhgljnnp{{|~{€‚ƒ„………………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKBAGFDGMRHDRKFHHHDFKIMPEGIJKNLLILKJIGDHKQOMLPMLKKIJDEAECHFAAFDAVUE\T^SV_XNTUNZ[MJKT`a[_X_^b]OXb\``_bca]bbW__TQPQRYS^\[]^_`affelfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDFFGDIScQEW_IGGHDFMJPPFIIJKNLLKMKJJGEINQQNOPMNMNHLBDACCFDCACD@LHCLLPONLFMFFHIHGLLMOPILOPPSPLQTRUZXWYWWcVOSTPQOOQUT\YY[^^aaefchdlmqsszy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKM^MHHYMGHJHGMLQQIKJKKNMUNOKKLGGKPTSNPPNOOOHKF`ED^LDfcCL[H^\smOMVmYLCO_TlWgJ]WU^DLQULMSVQRTXVTXTT\TPfZhheZTkTXWU[\\``abbb`gignlhrz|}~„„„„ƒƒƒ}}zr{z{‚€ƒ„„……„…ƒƒ~z{LIEFFHEEKOTJKG`THJOJIOMRQKMKLORUROPJLNGHMQ[YOPPNOPPJKQQI|YYrsWPmGqnoaVPqqtOBjsnqtpSo_[nX]V\XUkhU]VcY`YZ^UUWituu_av_Yb\\f[_aaab^`cgmol`pwtx‚ƒ„‚}~€vxzmv~tx}€|~€‚„|€ƒz~wwNIEHMMBDLLGJLFRVLKOHLRXWQNOOMQTNOQPKLOGMPS[ZTQROPPPKIZx]TxdhXRSPvftlpbnfkRrNLwmjrpsrqrpop€]ezuxqqzq~r}ku}aRh|essoss|}p~xor```bb[aahlnkblfgmw~€ƒ~{xw€tvzhr~nt|~wx{~€ƒx|u|||ssNKF`]GAEMMHKKHJQOMNJNV^YULQSNYYLSRRNLPIQRTYWWQTPPQRKHgxlcxqmZJLTypumubnvPddHevqmwo€jfxxiWrQhzmijzz}lxzphnXuujvup€ash}ilx|o___cb\_degjjegbcdllppstsssyqrxbltgry{ssuy~svzn|}yxrnMJRtNCBEPQHKLJLQOOOMPZ`ZXKTWPa^RVQYSMPJSTUXWWPUPONSJKrouuquqchaVnLqp^GhyWvTKhx}w`y{sna]modSgrunmypwlvstqlm\s~zkmy|lun|lqvux^__b_]_eeighfe^bbiiijknokqnmjpacfdowxompsynqpj{ztromKKZVHGEGRQKMNLLQQPPPQW\YUNVYUfXRRY^TMNJTTVWYWOSOONQIRmHiwK`dvuUWlNnl{rajguTKWkg|lmlx_Zpz{_`zscroxqhd|ir{]TKk_vuljv|{m~yk|p]^^b[_bdegffec[ccikkrsrwgmihdg`alagsrlglmr|kmhk{tmmkmOGJKHJHHRQMOPMLSSROSRXRWTPWZVVTTTa`QONKTSSQVVOOMNOQJHQMOULKKRSRRROVUQQORRXXPNPUTWXX[[UQRW[WXW[ORTWWXQ]XV\UTOXRWWXYZ`\gr_[[Z]]_cZ_ccegdddcZdbgffmnmuffgc`f^^g`dlhfgkhpzhggkujhgilPIKKLMKJTRNRQPLVUTPTUXUZVR[]VUTWUYXOOLNWTPNUSNPNLQPKIQQKQMJJOQTRPQSRIIMOPQRPPPTURXW\WSRPQUUUSZQNRQWUSYVTXTSQTSUUYYX^Z_a]\ZZ\\`c\^bbdgeeebY`acabhhjncad^_c]Zc\bma^ffgmsdihkkedcfhQJKKNOLMTQOTQQMXWUTVXWWZVS\`VWVYUXTQPKOXSPNUPNQNLSPMNUSNQNMNQSPTPRTTNLNORTTQQQUWUYZ[ZSURTXWVY\SOSTWUTYUVXTRQWUVX\Z\`]WY_]^]\]`a^[bcchgfebX``b]`hegea^_]]^ZZ_Z_g`^^]chkahfhfd`bdbPKMLPQLOTPPTQOQZYXWYZZXYV]jdVXYZWVSTOKOVTPOTPPQNMRQOQXTQQOMORTNWQTTUONNQTUURRRTXVZ]\ZVVQRWXU[[VPSUUUVXSWWTRQXVV[_[_`_V_]^`\\``__ZbceiheebYb`b^^fdc`b]\\\\YZ[X[a[^]]_b__bddbd__`\PMNNRQMRSPSTQOV\ZZW[[\YZ[dqmhd_[YVVXRMNWSMMROQROMPSRUZUTPPLPWUQVRSRXMOPRUXUTTSTYX[^]\[VROUVU[[VQSVTVXTSXZSRQYWW]_[`_`Vb\`a]`b_\`]cachief`Zc`a__ee_`c[Z\[\ZZYYW\Z\[`^`[^^a`_c\Y`ZQNONVQPUSPUTSPW\\\Y^\_W\^jpwy€c\[VVYRNPWSNQQPRTRLQTSY[WUORNSXVSRTRRZOQSSV[VVVSVZX]^\\^VSNTVV[[UQTTUWXRSY\TRR\XZ]^]aa`Wb[cb^ac_\bab_dgieg]\e`a`acd_b_YZ_[\[XXYWWZZZa\][]\\Z]`W[[ZPOOOYPUUSRWRTP[]^]\`\`U\\hjr}slh\UYWQOR[SRQTRTUTKRVUZZZSOSQUUUSNUQRZRTUTX]WXXSX\X^]YZ]UUNVVW^ZXQTTWXXSVY\TRV]Y]]a^cc_Y`[eb_dd^^cca^efief^^daaabcd_b^X[_[\[XXXXW[Z[`][[\[XZ[^V^Y]POORZPZUVWVTTT^^`_^b\`U]^bkyum}lZUZVQQT\TTTUTVYWLRZV\Z\RPUSWUUSOWQSXSWUV[^X[YUZ^X_^Y\YRWRYXY_YYRTUYYYUWY\UTZ]]^ab`ed]^]]eabfd^_dc`\gehfdb`ea_aabb_`^WY^Z\\ZYYWV]Z]^[Z[\[WY\]VXW]SOPWYP]UVYWWUX_`aa`c]`U]^beev‚{hXYZTVTV\XWWVVW]XOU\Y^]]TSXSWUTRSWQSVTXXX^^X][U]_X__X\VQYTYZZaX[TVWZZZXYYZWV]_`_dcbee^b\`fbdfd_`dba[fchfdfaf__abaa`_^VU]Y[\[Y\YY][[[XXY[YZZ]_]TY]UNTZVT\UWWYWV\`aacac__V[`da_zuohZ\ZVXVX[ZY[YXY`VOT][`a\UUYPTVURVUQSUW[[\__Z_\V__Y]^Y^VSYWYY\aY]UVZ[Z[ZZYZXY__``dcdeecdZbfcgfe^ab`c]bciedh_g^bbcaa`^_XTZZZ[[X\XX\[Z[WWZXW\[\`]V]]SOVZVVZVYVXWX^`badada^YYadb`kfh^\][WWYZ\\\_[Y[bVSW^]ac\SVYPVUUUVUSUTX]]_``]a]Wa^[^\[^XVXW[Z__Z^WX\\\]][Z\WZ_a^`dddffgcYcfehgd^c`_ec]fidei_g^cbcaa`__[XY[YZYXZXW[[Z[WXZTZ]\[`\U^bMRWYVWZY[\YWY^`baeada]^Yacb_a`a_]]]XW[[]]__\Z]cXYX]`cd_RXYPWUWXWVVWV]]^aba_b^Ya]]^Y\^YXUV[[`^\_YY^]^^`\ZZY[_b_bedefghcZefgigc_c^`feZiicficf_bbca``_]]ZX[YYXXZYWZ[ZYWYVU[]]]``bbxKWW\YW]\\]ZW\]_`bdbca]`Xbcb`cac^\]\XW[]_]`_][`d\\XZbecaR\YOXVY[YYWZZ`^abc`ac_\b]_][^^YYTX]\__^_[Z^^`bb\\W[]`bbcedgffge]eghifcab\cg`\iichife`baca_`_]]\Y\YXWXYYW\[ZWWXPXZ]acffrkJYW][Z_]\^\Y][^_bcbaa]b[bdb`cbb]\[ZWXiq`\`_]\ac_^YYcedbT_ZQYW\]\[Y[[c`ccc`bda`c^`\^^_ZXV[^\\aa_][`abfb^\S\_`cddfeggfff`fghhgdd`[fg^ahhcihfc`b`cb___]][Z[YXXXVZW\[ZVVULXX\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡…‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vvvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{{{{{{{{{{{|{{{{zzzzz{{|||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vvuvvvvuvvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{{{|{{{{|{||{{{{{zzzzz{{||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||vˆ‹‹‹‹‹‹}}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰Š‡sqrrrrqƒŠ‰‰‰‰†³ÖÒÒÒÒÖº}~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}vŒƒ~~†“y1333332j‚€€€{­éääääèʉŒŒŒŒŒ‰rooooon…ŒŒŒŒˆ¿éååååéÇ}~}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}vxxxxxxxwwwwwwwxyyyzyywopppppprrrrrrrwzyyzzz~ƒƒƒƒƒ„|||||||zzzzzyz{}||||{„„„„„…‚|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚‚‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vvvuuuxvvvz{x{xwvvxyyzz~|yyxxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{{{{{{{{{{{{{{{zzzzzzz{||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwww||}zy|{xwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwwy~|}}y{zxxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z|yww{~|||z|yxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚ƒ‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzzx{||}z|xxxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyywxzz{yyxxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxxyyyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{{||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}||}}|||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}|}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹ŠŠ‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡ƒ…‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹‡‰ˆ‰…„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚€€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrstuttssrrsrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqstsssrqqppnnnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqqrssssqpqpoonnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrqrrssrrqppoopoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpppqrrqqqpopooppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqpqqqqqqpooppppppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqqqqqpppppppppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsquŒ‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqqqpqqqqpqpqpqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrqqqqqrqqqrrqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrssrrrrrstrrsrsssssssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz|~~|vvwwvuxzxxxxwwwvx|yy|zyy|{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~|{{z{|{}|{{{{{{zyxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}|||~|}~~~~~}}||}ƒ€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š††ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€€€€‚€€~~~~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š†…ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~~€€€~~~~}~~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~~~~€~~~~~~~~~€€€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹ŠŠ‹‹‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚‚‚€€€€€€€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒŽ‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒƒ‚„„‚ƒ‚‡ƒ‚‚€‚‚‚‚ƒ‚‚ƒ‚ƒ‚ƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒ‚ƒ€‚ƒ‚…………††‡†…††‡‡‡†††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠˆ‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„„ƒ‚ƒ…ƒ‚‚„…‡‡‡‡††‡‡‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ’‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„„ƒƒƒƒ„…„„……„ƒƒ„……‚„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘’’ŽŽ‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€‚‚‚‚‚‚‚‚‚ƒ€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„…„„…„…†’“‘ŽŽŽŽ‰ˆ‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~~€‚€‚‚‚€€€€~€‚€‚ƒƒ€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“’Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚„‚‚ƒ„‚ƒ„…†„‚„‚€‚‚‚„ƒ‚ƒ‚‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘ŽŒ‡…ƒƒƒ‚‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒƒ‚ƒ……ƒƒƒ„ƒ„ƒƒ„„…„„„‚€‚ƒ‚ƒ„ƒƒ‚‚„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”““’ŒŒŠ…„„ƒƒ‚‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~€€‚€€‚‚‚‚‚‚€‚‚‚‚‚‚ƒƒ‚‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†”“’”’‹‡„„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~~€€€€€€ƒ€‚„ƒ‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“‘Š†ƒƒƒ„‚‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€€€ƒ‚‚ƒ‚‚‚ƒƒƒ„‚ƒƒƒ‚€€€‚‚‚‚‚‚ƒƒƒƒ‚ƒƒ„‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†ƒ„ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„……‚‚ƒ‚‚„‚‚†…ƒ…ƒƒ„„„†…„„…‚}}}~‚„ƒƒƒƒƒƒƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„„…………„††…††…………„……………††…†††…†††‡†…………ƒ„„„‡““’‘’Œ‹ˆ…………‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒ„ƒƒƒ„…ƒ‚ƒ„……†…††…†‡‡†ƒ~~~~~ƒ„ƒƒ„„„„„„„„„„„„………„…„†……†…†††…†……‡……†…††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„ƒƒƒ…………‡‡……‡…~€€„…„…†††…………††‡††…†……†‡‡‡ˆ‡‡‡†††‡‡‡††††‡††…„ƒ„………„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘“’‘‹ˆˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒƒ„„„…„ƒ‚‚ƒƒ„ƒƒ‚ƒ…„…‡‡…„‚€€€……†‡ˆˆ‡‡‡‡ˆ‡ˆ‡ˆˆˆ††‡ˆˆ‰‰‰ˆ‡†‡‡‡ˆˆ†‡†‡‡††…„ƒ„…††………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†…†„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡‡…ƒƒ…„ƒƒƒ‚„„„„…„€‚€€~{z€†ˆˆŠŠ‰‰ˆˆ‰‰‰‰Š‹Šˆˆˆ‰Š‹‹ŠŠˆˆ‡ˆˆˆ‡‡ˆˆ‡ˆ†‡†„ƒƒ…‡‡‡†……„„„……„……†„„„………†…†…ƒ‰”“Ž‘ŽŠ†…†…ƒ‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡‡„„…„ƒƒ…ƒ…ƒƒƒ‚‚‚‚‚‚€~|}}}~|{|ƒ‡‰‹‹ŠŠŠˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰‡†††‡…†ˆˆ‰ˆ‡†‡„ƒ‚„ˆˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚‚ƒ‚„ƒ„ƒŽ“’‹ˆ…„†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„……„ƒ†…ƒ‚‚‚‚‚ƒ~}~~~~~~}}~}}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡‡‰†ˆ†ˆ‡‡‰ˆ„ƒ„ƒ…„„……†ˆ‡†…ƒ‚‚ƒ…‡†‡††ƒ‚‚ƒ„‚ƒ„„‚ƒƒ„ƒ„‘’‘Ž‹‡„††ƒ‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚‚„„ƒ‚…†ˆ‹Š†„†„‚††‚€…„ƒƒƒƒ‚‚}|}€~~~}|}}|z|„†‡†„ƒƒƒ„………ƒƒ…„„„„„„…„‚‚ƒ‚„„‚ƒƒ…†…„‚‚‚ƒƒ…ƒ„„…„„†ƒ„„…ƒ‚ƒ‚ƒƒ„…„‡’‘‰†„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………‡‡‡‡†€…ƒƒ„…„‡ˆ…ƒ€€~}‚ƒƒƒƒ‚‚€}}€€}~~}|}}zzz~ƒ„„‚€‚‚~‚ƒ€‚‚‚‚ƒƒ€€€ƒ‚€€€€‚‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†Œ“‘Ž‹ˆ……ƒ‚„‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€ƒ‚~~~||ƒƒ‚ƒ‚ƒ}}~€€€~}}}}~}|zzz‚‚€~€~}€€€€€~}}€~€€€€€€‚€€‚‚‚€‚„ƒ†’ŽŠ‡‡†ƒƒ‚‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒƒƒ„…€|}}~}}~€€~}~}{}~‚ƒƒ‚‚}}~€€€~}}}|{{{zzyz€€~~~~}~~€~€€~}~~}|~€~~€€€~€€~€€…’’Ž‹‹‡‰…„ƒ‚‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~~~~€€~€}}„ƒ‚€~}~~€€€~}}}|{{|zzyyy{~~}~€€~€€‚€|~~~~}|€~~€~~€€~€~~~~~}||}…“’Œ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒƒ‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚‚ƒ„„ƒ„€€€€€‚‚ƒ€€‚ƒƒ€€}}}~~~~}}}}}|||{zyyyy}€€€€€€‚‚€~€~~~~€‚€€€~€€~~€}~}}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…ƒƒƒƒ…„„„„ƒƒƒƒ‚‚‚‚~~}}}~~€}}}}}}}}|{zzyyyy€‚‚‚„ƒ€ƒ€‚€ƒ‚ƒƒ‚€€€ƒ„‚€€€€€€‚‚€€€€€€~~||Š“Š‰ˆˆˆ‰ˆ††…„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…ƒ„…„…†††††……†€ƒƒƒ‚‚€}}}}}}~~}}}}}}}}}|{yyyyx|‚ƒ„…‚„ƒ‚‚ƒ…†‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚‚„ƒ‚ƒ‚‚‚‚€€€~Ž“Œ‡ˆ‡ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€€~}}}~~~€ƒ„‡ˆ„†††…††‡‡†‡‡‡‡†‡‡}€€‚~}}}}}}}}}}}}||~~~|{yxwxyy€ƒƒƒ„ƒ„„„——ƒƒ„}~‚‚‚‚ƒ†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ……„…ƒ‚ƒƒ‚ƒƒ‚‚‚‚ƒƒ‚‚’‹ˆˆ‡ˆ‡††„†…„„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€~}~~€‚………††‡‡†‡‡ˆ†‡‡‡†‡‡‡|}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yxy|~‰—„ƒƒ„„”“€~~„‹€€€„†‰…„‚‚……‹ƒƒ……††„ƒ……ƒ„„ƒƒ„ƒ„„„ˆ’Ž‹‰ˆˆ‰‡‡‡…†…„…„‚‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„„†…||||}}||}}}}}}}}}}||‘•–ƒ{z„”|xyz{|‚ƒ€ƒ‚€~|~~{ˆ‘||Ž–}‚†Š…ƒƒ„ƒƒ‰~ƒ„……ƒ…†…„……ƒ„……†„„Ž‘‹ŠŠŒ‰‰‰‡…†…ƒƒ‚‚‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚ƒ„ƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚ƒ}}||}}|||}||}|}}}|||{‹‘—Œz{|zzz{|yy}}~€€|{{~~}‚•‘„ˆ~|~‚„||‚„‚€‡ƒ}‚‚‚€ƒƒ„„„„„‚„ƒ„…‚„‘‘‹ŒŒŽŠ‰‰………ƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚‚ƒ…ƒƒ…………ƒƒƒ„‚ƒƒ‚ƒ‚‚€€€~~~}||||||||||||||}|||~~Š‚{z{zxz{{|}{~}~}}}}||}†~}‚~~€‚||€‚€~}{Š‚}€~€€‚‚€€€€‹“‹‹Žˆ‡‡……„„ƒ‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ…„††„„€†”ˆ€€~~~€|||||||||||||}|||||||y{{{xxy{zz|€~|~~}€‚‚€€€‚‘€€~€~~~€}|}{}}}}}||}€€€~€~~”‘‹ŒŠ…††…„„…ƒƒ‚‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚ƒ†‡††~ˆ•Š~€€~€~~~|{{|||||||||~}|{||||{|||zzy{|z}…ƒ‚~~€~…‚~€~~€…†‚€~~ƒ†~}~€€€~}}}}~{{}€}~€Œ‘‹Œ‡„††…„„„ƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}~€‚ƒ††……~€€€~~~€€€€}}||}~}|}}}}}}|~|}|{}||z{z|}}†„‚€€}~}~~‹„†~}||~‚}}}}€|{}|~„ƒ€~~~~}}~}~€~~~„’Œ‹‹Ž‹Š†„…„„ƒƒƒƒ‚ƒ‚ƒ‚ƒ‚€}|||}~{{}w~vx~}|}|}~~‚ƒ€z}}|~€€~€~~€€€€~~~~~~}~~}|~}~}}|{|||z{z}~€„ƒ‚~|}|}||ƒ~Œ~|{{}~}~~}{{{}|z{{{€†„‚„ƒ‚€~‚‚‚‚€ŠŒŠŠŒ‹Šˆ„„„ƒ„ƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€€€€}€~~~|‚~~}}}{{}}|z||~€‚€€€||}|||||}|}{~{{{|||}|{{{{||zz}z~‚ƒ„‚‚…†……††‡…‚„‘ŽŒŠ‰Š‡ˆ…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~~€€‚€~~€€~}ƒ||}}|}}}}{|~~~~~~~|||||||~~{|{||||}|}|~|}||{{|y{|{{}{}~~€€ƒ‡‰‰‰Š‰Š‰…ˆ‘‹ˆˆ†……ƒ‚‚ƒ„„ƒƒ‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€~~~}€€€€ƒ‚€€€€€€€€~|z|}}~}}~~Œ†}}~{{ƒ‚}}}}}|}|}}}~|}|}|}}~|~}}}}|{{z|{||{z{{zzz{~~‚…ˆ‡ˆŠ‹‹Š‰ŒŒ‰ˆ†…„ƒ‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„„€€€€‚~}~€~{~‘Œ|}Š€Œ~~}}}~}}~}|||}}|}|}}}~}}~~|{{{||}|{z{|yzyxy{~„ƒ„‡‰Šˆ‰ŒŠˆˆ…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{|||~~}}€€€‚…ƒ„‚‚‚‚€€ƒ‚€}~€~|~ˆ‚~ƒ„„ƒ~}|‡}}~}||~|}}|}}}~}~}}}{|}~||{|}zzyyzy{{~~€ƒ‡„ˆŒ‰‰†…„„ƒ‚‚‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{|}}}}zx‚€‚‚€€€€€‚‚‚‚†…„‚ƒ€‚„~€}~~}~€€}~„€~~}~}}Š…}~}~~€}}}|~~~}€}~}|}||{|}{{{zzz{{|}~}€ƒ€‰Œ‰Š‡………„ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv~€ƒ‚‚‚‚‚ƒƒƒ‚…†„‚€€€€‚€„~~€€}~€~}~~€€~€€}~€~€~|}}|~~~~€}‚€|}€}||}}||{||{{{|{|||}|‰‰‡‡…†……„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€ƒ€€€€ƒ~~€€}€}}~~€€‚€€€}€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{|~|}|||{|{|~‰…†„…‡…„…„‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz}}yxtt€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚~~~€}~€}}}~€€‚€€€‚}~€€€€€~}}}~}~~}}„€~}€}}}~~}~|{|z|{z€…‚ƒ„…„„„…ƒ‚‚‚€€‚‚ƒ‚‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xytu}‚ƒ‚ƒƒƒƒ…„…„ƒƒ„„ƒƒ„‚€€€~}}~€~~~€}}|}}~€€€€‚€€€ƒ€~€~€€€~~~~~~~~……€€€ƒ~€~€€~}{z{z|{z‚ƒ‚‚‚‚ƒ‚ƒ‚€€‚€€‚ƒ‚ƒ„ƒ„‚„‚‚‚‚~€~}~~~~}~}}z{|…„{{sy{|pwuvwyvtz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€~€}}}~€}~~}~|}}~€€€€€ƒ‚€~€€€€€€€€‚‚‚„€ƒ€€|{{z|{|€€‚‚€~‚‚ƒƒƒ‚„‚„‚€‚€~€€}~~}}}~}}{{z€x|vyz|qtxwvxury……‚„„‚„……†„„‚„ƒƒ‚€€~€€|}}~€}~~}|~~~~€€ƒƒƒ€€‚€€€€€€€€‚ƒ€„}ƒ„€€‚}z{{||}}€|~}€€~}}€~‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxzzruyyvwwsu†…ƒ……‚„„…„„„‚ƒ‚ƒ€~€~€}}}~~€~~}|€|~€~€‚ƒ€€‚ƒ„‚€€€€€‚ƒ‚ƒ€~‚‚„€€‚‚‚„~{{|||}}}~}z~}~y~|||~}~€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„‚„„…ƒƒ‚ƒƒ€}~}}}€~~~}}€€~|~~~‚‚ƒ‡…~~€€€€€€‚‚€€~€‚~‚‚ƒ‚ƒƒ…‚}}}|{||yz{z~y|yx~{{{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst†„„…ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€|€€~€}~}~€€€~|~€€€~}~~€}€€ƒ„ƒ~}~~~€€€‚€~~€‚‚€„‚„„†„€~}||||zyvyyzyvyv~|{{{~|{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„……ƒƒƒƒƒƒ‚‚ƒ‚ƒ‚€~€}}}}€€€€|€€€€|€~~~}~~€‚‚~~}~~~~€}€€~~~~~€‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{z{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvqwyrx…………ƒ„„‚‚ƒ‚‚€ƒ€€~~~~€~}~|~€€€€{€~€€€}€~~}}}~€~~~~}}}~~|~€~~~‚~~€€ƒ‚ƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}}{|z{}zzx{|zz{xtxuqrtpxxqy„………ƒ„ƒ‚ƒƒ‚‚‚€€€€}~~€}|~}€€‚€|€€~€}€~~}}|€€€€€~~~~}|~~~|}€~}~€‚~€€~ƒ‚‚ƒ……‚‚~~|{{||yw{ywxwwx{{z{|…Š}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzz{zxswuqqspxwq{…†……ƒ…‚ƒƒ‚€€€€~~}|~}€€‚€}~€~€€€~~|}€€€€~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{|||zzzzzzxsvupprowvr{…‡„…ƒ„‚ƒ‚‚‚‚‚€€}}~€‚}~~~€€‚€€€~}~|€€€€€~}~~€€‚€€€€€„‚‚€~|}~~z}„~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚€€€€€€~}€€‚‚‚€~€€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€€‚€€~}~{’Œz|}|{}y{zzxyxy{||}|||||||}}}||}|~}~~~}|z||{|}{yzzzyysuuooqpwst}…†ƒƒ‚ƒ‚€€‚‚‚€‚‚€€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€€‚‚€€€}~~|†‰||~{{~yz{z{~wwy{|{}||||{}|}}}}|}|~~~~|z|}{}}{yz{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}€~~€€€€€€€‚‚‚€€€€€€}~€}€ƒ‚{~~{|}{z||{‡yxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€€€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ„„€~‚€€€€‚~€€‚€€€€€€€€€~}€€€€€€€€€€€‚€€€€€~}~}~~{}|}{||wxuxxy{||}|||||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒƒƒƒ‚ƒƒ€‚…ƒƒ„ƒ€‚ƒ€€‚ƒ‚€‚‚…ƒ€~‚ƒ€€€€€€€€‚€€€~€€€€€€€€€€€€€€€€€€€€€€‚‚‚‚€‚‚€€€‡~~|z}|{}~xwvyyy|}||}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚ƒ„„€€‚†ƒƒƒ‚„€„ƒ‚‚€€‚‚„‚‚„‚€€ƒ‚€€€€€ƒ~€ƒ‚}‚€€€~€€€€€€‚‚€‚ƒ‚‚ƒƒƒ‚€€€„}}}|}z}€zyvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysruowqwysw{…‚‚ƒ‚ƒ„‚ƒ„ƒ€€‚ƒ†ƒƒƒ‚‚„„ƒ‚€€‚ƒ‚‚‚~€€‚‚ƒ€€€€‚„€~ƒ€ƒ‚€~€‚ƒ‚€ƒ‚ƒ‚ƒ‚‚„€ƒ‚„ƒƒ„„ƒƒ„ƒƒ€‚€}€|z|{{w|yyy{z}~}||||}~~€€€„„€}€~{{{z{ztpxrytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚‚„†„‚ƒƒƒ„„„€ƒ€ƒ‚‚‚‚‚€‚€~€€‚‚‚‚‚€ƒ‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚‚„ƒƒ„‚„‚ƒ‚‚‚‚ƒƒ„ƒ„„„„„…ƒ„‚ƒ‚‚ƒ€€~||€||x|yzyz|}|{||}}}||€€€€€‚~€€€€{{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚‚…„„ƒƒ‚ƒ„„…‚‚‚ƒƒ‚‚‚€€}€€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€ƒ€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒƒƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{~~}y|zzz}||}z||}}|z{~~~€€€€€€€€€}}||}|vrvxxvtvt}‡‡ƒ‚„…ƒƒ„…„€‚„…„„ƒ‚ƒ„„€„…ƒ‚‚‚ƒƒ‚ƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚‚‚ƒ„‚‚€€‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚~ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz{}}||z|~}|}}~~€€€€~~€€€€~|}}~~}|{xvuv„‡ƒ‚ƒ…ƒƒ„†„‚…†…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„‚‚‚ƒƒ‚ƒƒ‚‚„„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒ„„„„„„…„ƒƒ„…„…„ƒ‚€}‚€}||{||€}}~€~~}~|||}}~~~€}}~€~~}}}~}}~~€||€‚‚ƒƒ†ƒ„ƒ†„‚ˆ‡…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒƒ‚‚„ƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒ‚‚ƒƒƒ„ƒƒƒ„ƒ„„„…„„„…………„ƒƒƒ}„}}||||~}~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒ„…ƒ„ƒ…~‚Š‹…„„ƒ‚ƒ…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ…ƒƒ……„……‡‡†‡……„…„ƒ~~|~}}€~||~~|z|}}}}}~~~€}}|€€~~~~~€‚€……„ƒ…„‚„ƒ†€‚……‹‰„„ƒ„……ƒ‡††„„„„…„„„„ƒ„ƒ‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ„}uyƒ€~„„‚ƒƒ‚ƒ„ƒƒ„…ƒ„…†„…†}„y|~ƒ{…ƒ€„ƒ€~~~}}ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚‚ƒƒ‚‚†„„„†„ƒ„…ƒ„…ƒŠˆ………ƒ……„†††ƒ„„………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†tpurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚……‚hzrss|s‚ƒƒƒ}}~~}~‚ƒ|}€}}||||}|||~}~€}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ…ƒ†ˆ††…ƒ††‡‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vyy…r„ƒpvxqvtturstvi€nrotvnulwm{sn€ˆym}rsvsvmmxlpylu}}~€}€}€€}}|||}|}~}€€€~|~€‚€€€€€€€‚ƒ‚ƒ„…ˆ††€‚…ƒƒ„‡†ƒ………†‡‡„ƒ†‡ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoomw}x†pqzprtfu~n{ysoy€}}|}|~€€~~€€€~~~€~}€}€€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„†……††ˆ„„†‡‡ˆ†‡„††‹Š…„†‡‡…ƒ………„‚…………††…†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„qjoyxpkyszozwvvp€~~~z~}}}~}€ƒƒ€‚ƒ„‚€€}~~~€~~‚€€„‡†ƒƒ†„„…†‡†…………††ˆ……†…‡‡…†„††‰ˆ…„‰Šˆ…„††……ƒ……„…††††…ƒx‹yrˆz{pp…„x…xyks~y{krƒ‡ƒz|m{yyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozls|nw‚€~~}}{}{|}}~}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡……………‡‡ˆ†„†…‡††…„……„……†‰‰‡†„†…††…††„††‡††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„…†…†„†„ƒ„„†„„ƒƒ„„…„…„…„†ƒ†‡…†„„…‡†„„…†„…}w…ƒ„„‚‚}~{|{~{||}~}|~}€€}€~~~€~~~~}}}~|{|~||‰†…„†††…‡†…………††‡ˆ†„†…††……ƒ„…†…„††††……†„…††††…††‡‡†…‡ˆˆˆˆ†„‡…††ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…ƒ‚……†……ƒ…„„„…„……„……„†‡††…„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ‚}€{{|}{||}~||~}}~€~~€}}|€}~~~~~||}~{|||{{~ˆ‡„„ˆ†††‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡……†……†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ…„ˆ…†‡†‡†ˆ†‡…‡‡†‡……†‡…‡†…‚ƒ…††„„ƒ„„ƒ„†„………††„††…†…„††…„ƒ……‚…‡…ƒ‚‚…ƒ„~€€|{}~{|{}~}||~}~~|~}}~~}}||~~|}€}||}|||~z{{}~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†„…„††„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…‡‡…‡†‡†‡…ˆˆ‡‡…††‡…††…„„…†……„„„ƒ„……†††…†„†…†‡……††…„ƒ„ƒ‚„‡ƒ„‚„„ƒ€€€{{~}|||}}|||}}|}|~}|}}|||}}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††ƒ…†…†††…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡…‡††‡‡‡…‡†ˆˆ‡‡…‡‡‡…†‡„‚„ƒ„†…‡……„ƒ„„…††††††‡……‡…†††…„ƒ„ƒƒƒ‡ƒ€‚ƒƒ‚‚‚€{}~}{||~}|}}|}{||||||}{{{}|{~|{|}}|}}}|zz{{||ˆ‡‚††††‡††…ƒ…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡‰ˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡†ˆ‡††‡‡…‡†ˆˆ‡†…‡†‡††‡ƒƒ„„ƒ††‡……„„„…†††††…†‡††‡††„†…ƒƒƒ‚‚ƒ†ƒ~‚‚ƒ€ƒƒ|~~||}}|}}|}z{{z{|||{{{~{{}{{{~||||}~}{z|z|}‰‡ƒ†…†…††…„„……………„ƒ…†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…‰Š‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……‡ƒ„†…„††‡†……ƒ……††††‡…‡†‡†‡‡…„†…ƒƒ‚€ƒ…‚ƒ~ƒ~~~||}}{}}|}zz{y{|}{{{{~||||z{}||||~}|{{{{|{‰‡„†„†„††…„…†…„„ƒ„‚€ƒ…ƒ‚z„Œ{€„…‡†††…„‡ˆ‡†‡……‡‰‡„‡…‡‡ˆ†…‡„†‡‰††ˆ‡‡‡†‡ˆ†„†††‡†…‡ƒ„…„†††‡……„ƒ……‡…‡†‡…†††…††„ƒ……‚‚€ƒƒƒ‚}€~ƒ~||}}~}{~}|}yzzy{}}zz{{}|}||z{}||}|~~€|{{|~}|ˆ‡…†…†„†………………ƒƒƒ€‚…‚€€}|{„…††„…„ƒ‡‡†††…„†‰†‚†„†††……‡…‡ˆ‰†…ˆ‡‰‡††‡…„†……†…„‡ƒ„…„ˆ††‡……„‚†…†…‡†‡„††††…†ƒƒƒ…€€€€„€ƒ€|€~~‚€}€||}~}~{~}||yzzyz}}yzz{|{|{{z{}}|}|~~~|{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€€ƒ~~~€yz}€ƒƒ„‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ†…ˆ‡‰‡†…†…ƒ†„…‡ƒ„†„„…„‡†…†…†„ƒ†…†††††„…††……†‚‚ƒ„~€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|z{{{|}}}|~}||}~|{ˆ……††††„…„…ƒ…‚€€€€~‚‚}}{‚ƒƒ…†…„ƒ‚†ƒƒ„‚€…‡…‚ƒƒ„„„††‡ˆ‡……ˆ†‰‡…ƒ„„‚…ƒ„†‚ƒ…„„†„‡†………†ƒ„…„…†…†„ƒ…„…ƒ……ƒƒ~€ƒ|€}}‚}€~~~}}}}{|{zyzzyzz|yzz{{{}z{{{{}~}}€}}||}€}|†ƒ†††††ƒ„‚…‚…€€€~€‚|~~€€‚‚‚„…ƒ‚‚„€ƒ‚€„……‚€‚ƒƒ„…†ˆ††……‡…‡……‚ƒ‚‚ƒ‚‚…ƒ…„…†„††‡††…‚„„ƒ„†……ƒ„„ƒ„ƒ…„€€‚‚}}~~€ƒ~{||€}€}}ƒ|~~}}~{~{{zy{zyzz{yzzz{{|z{|{{~~}|}||}€~€†„……„‡„ƒƒ‚†‚ƒ€€~~€}‚|}~~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡…„„††„…ƒ…‚‚‚ƒ‚„„„……†‡‡†…„ƒƒƒƒ„†…„ƒ‚ƒ‚„ƒƒ€€~}|~~|ƒ}|~||€~‚}‚|~}}}||{{zzzzy{zzzzzzz{|y{}{|€}~}}}€€€†„„…„…‚ƒ‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„†„‚ƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„……‚‚‚ƒ…„‚‚€…ƒ~€~||~}|~ƒ}{~|}€ƒ}}€~}|||}{{zzzyy{yzzyzz{{{z{}||‚€~€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌËËËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFL=8765999<>9?<D:;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937677=;>9=::;88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<9<<98:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA><A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÒÓÔÔÔÔÔÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9?CE@<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÑÓÓÓÓÓÓÓÓÓÓÓÓÓÎÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚØÖ×××××××Ø××××ØÜÝÝÝÝÝÝÝÝÝÝÝÝÞÛ×Ø×Ø×××Ø×Ö×××ÖÓÒÓÓÓÓÓÔÔÔÔÔÔÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILO@99:4;A<7=9AC>@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌ̈́mpppppppppppj§ãÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‡¦º¸¸¸¸¸¸¸¸¸¸¸¹³xssssssssssssp’»¸¸¸¸¸¸¸¸¸¸¸·½ÒÒÒÒÒÒÒÓÓÓÒÓÓÓÜâáââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVN<::77>C>8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÎN&+++++++++++"ŠôëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSOƒ§£££££££££££¥™2)++++++++++*%a©¤¤£££££££££¡«ÒÒÒÒÒÒÒÒÒÒÒÒÒÑßêêëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;@C>6:7>>;=B?9<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÍÎR+11111111111'óééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWS…¨¤¤¤¤¤¤¤¤¤¤¤¦›8/00000000000+eª¥¥¥¤¤¤¤¤¤¤¤£¬ÒÒÒÒÒÒÒÒÒÒÒÒÒÑÞêêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;>@@8:;8<;;<?:;;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÏ\9===========5“ðççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbb^Œ¬©©©©©©©©©©©« E=>>>>>>>>>>>9n¯©©©©©©©©©©©¨°ÒÒÒÓÒÒÒÒÒÒÒÒÒÑÞéééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB?;=:9;:==;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÅÂÃÃÃÃÃÃÃÃÃÃÃÂÉÐÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÎÎÎÏÎÏÏÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÏÑÑÒÒÒÒÒÒÒÒÒÒÒÑÊÊÊÊÊÊÊÊÉÉÉÉÉÉÌÒÑÑÒÒÒÒÒÒÒÒÒÒÒÔÔÔÕÕÕÕÕÕÖÕÖÖÖØÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<8@B<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÏÐÐÏÏÏÏÏÏÏÐÔÐÐÎÌÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÎÎÏÑÎÏÓÓÏÎÐÔÒÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖØ××××××Ø×Ö××××ÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÕÖÖÖÖ×××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?79:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÎÎÑÁ§ÒÏ¡–ËÑƓ«ÒÎÎÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<>B>BC@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÎÏÏѝÅª «ŸÎ™­™³ÒÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?>;7:>9?D>A98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÏÏÓº¯«±Ÿ•¡´•‡ÎÏÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<<:6?B@C:647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÏÏӟ±ž§Ÿ§™´¿É–™ÆÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8FA?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏÏÑÀœ‰›µ¤ ‹ŸÃґ˜ ÎÐÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<>=964:99::97;?@;<=@<<A><=;=<?<:<B@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÏÔ£¢›Å™Åɔج£¿ÕÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:=?>=<9@<<;:9?@=<==@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÑğ{—Ÿ¢••¡»Íˆ•žÈÒÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CFCAB8;?<=;<<8558968;:9<:>?<==9<?>=::>9<;;8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÕ«¯¼ÀÓy›°³¥ÐÛ¢™µÕÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF@HIGE@<<>><=><756:969;::;8@?:<<9<>=;;:?9?;;9=>==;;=<@CB?>>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦Õɇ…¢‚£›¢œ‘¨˜ž»ÕÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;547<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡ÆÓÓ՜š² © ¢ž©¢©œÐÓÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKL@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ACB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÒÑÒרˆÏ°‘¥Ôš‘Ž¾ÖÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<=?GFHKH=657:979:;:<=9>99:8;=>>A>=9<<9=>>:=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÑÒÏÅÔÕÀ½ÖÔÓ¸ÈÕÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?AELLA>775;8899:;<><>8::9;>?@=>>:5::<=?:;9:<=BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÒÒÓÔÒÒÔÕÓÓÓÖÔÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEJ>>786977899;;=?@<=89;;;?><<95:<>;:8:;???BBA>A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9599:7<=;>@==79:;9>;9966;=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<59:<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EILAALD??;:889386869>=>?=:6:;>;==:968:=;@@<@?=>?B><><<BEGIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDJ;AA;<886486987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGIB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<BA<;876797799=?A?<:9@?<?B?:8776=??@=@@??==;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98867975698==A>:89>=<?@?<5676<>?><@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE>;HF89757875898;>>=;89A>=@?A>7596;>AA??@@BB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCEFC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@C@CC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:;<>;==;><:;89:89AABA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B;9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELCA>8:9:77966:5;>@;=;?=;?=:99:<9;ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6;DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<<DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875776858@>@;<9<;<>::;9:;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGGNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAC?@;<89996866684;><=;96::9:958:89:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995687673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86776668784;?;>=9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778777656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€ihxsg~‰‰xp‚†{w}~…Š½ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778679645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€ƒvt|„‚}sp€Šx‚yƒÈÞÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9867556747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsoupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664766=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:863656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87863767:66659>?:<?;?9;:7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==<?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757878789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687789:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495666788:<;=>:;::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYEDKPN<9886553956676879>:=>:<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643954775679=:=>;=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿¼½¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573146498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730473785766:=?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»ºº¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA8<;6:56534658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjdmgb\XQPQKTJB:IQ?A7<94:565455588686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸········¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®xpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µµ¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269664737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸¸·¸¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶·····¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨¨¨¨§¨©©©§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸········¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥£¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§§¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©ª««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤££¢¢¢¢  ŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž£¤¡žžŸ  žœœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=7789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥¤£¢¡¡¡¢£¥§¦¦§¬¬§¦ œ›¡¡ž›ššœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¥¦¦§§¦Ÿ›š›¢ ™––•š›™——˜˜šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜—™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥¢¢¥¦¦¥¦§¦¦ ›™›¡ —““’—šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB@DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥¦§¦¦¢œž¡Ÿ—‘‘”—›˜–––˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;;;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¥¦¥¥¦§¦¤¥¦¦¥¥£  ¡¡Ÿ™’–š™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šžŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡ ¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢¢¢£¤¤¥¦¥¤££¡¡¡žœš•“”˜›š›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œ ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸŸŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::88:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸ   ¡¢££££££¢¡ ž›™™˜™™™š™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢ ›ž ¡£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œž››œŸžœœœœŸ   ¡¡¡  ¡  ¡¢¡¡¢¡Ÿžœšššš›œš™š›™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥£¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¡¢¢¡   ¡¡ ŸŸžœš™š›››œ›š›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›šœšš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>98;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤£¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ žžž     Ÿ ¡  Ÿž›š™šš›››››Ÿžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›ššš›™˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™——––—–—–—‰xvg]_WTEE99;<Y>@8B?9;;>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœœœœžžŸžœšš›œœœ›œœžžœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––———•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:=>:?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››š›œššš›œœ›™™œœœžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—’””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™˜˜ššš™™™˜š›œœœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›š™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š››››œ›˜˜˜™™˜˜™™™›œœžžžžžžžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ›››››››™˜˜˜˜˜˜˜™™œœœžžžžžŸŸžžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœš›››››™˜˜˜˜™™˜š›œœžžž  Ÿžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾¸¶´³°¶µ¾ªptr\f_]]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜™——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœšš›››š›˜˜˜——˜™››œœœžžžžœ››œœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±³­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾³¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=9F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œšœ›œ›˜™š˜˜™ššš–‹“–™˜•˜˜–›œ—•’‘’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨©¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‹‘‹ŒŽ‹……‡‹ŒŒ‡ˆ‹Ž‹‡Œ…†‹†ŠŠ‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VPQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹‹†Š‹‹‰†„†‚€‚‰‘ƒ€ƒŒ†‹‰…€‡}€’†„„†ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹‹‰‰…‚}s}ˆ€~œ„……‰‹Šz}}†ŽŠ†”‘‹—”—’˜¡–ž—•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¥›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ†‹‡ˆ…„ˆˆ‰„‚z||}~’ˆx…‹Šƒ„…ŠŒ‘™””” ššŸ¢­±­©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPFMHSWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‹‡Œ‹Š‡’Š‡†‘“‘‘„‡}}ƒˆŒŽ‹ŽŠ‰Ž””˜‘•›š¨®²¯¯µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWLO_^\NUTbQDTM;?:<895775795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš˜ “—š ™›£ •› ¤£š“ˆˆ‹‰‘‘Ž‘Ž‹˜šŒ”š—œœ›Ÿœ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUKTOOJCPK_bXZQ\S_MHQIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ª©¨§¡¥¨¨«©©¯¡›Ÿ¡££ šŸ œ”˜”˜  ¡¤ž›š¤§¤©«®¬¥£¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdVOXKKJKSTpbYdW_[\RZPLC<8::698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®ªª«¤¡¢¥©§§©¨£¢œ››¤ ¥¨£ ˜™Ÿ¡¢©§ ¢¢®¬«ª§­®¨¥¤©©©©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_UZNRNPORd\dc[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢šœ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨¦¥§¨¦©¨£§¦™œ¤¥¢¡ ¡¡ œ˜™Ÿ ¡¤¤¢žž– ›š¢¢ ¡Ÿ ¢¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOWO^ddlgbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤Ÿ¢ ¢¦¡¦­¦¦ŸŸŸŸŸ™šœœ¡ ¡¤Ÿ¡›šœ ž¡Ÿžž £™–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvwa_\UYQUV[c^r_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?C?:8:>?C@DA:;><@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯«ª¬¨¨«°©¨©¨¡Ÿ §©­°²¯¬£¢¦¡©¥ž¤£¢¦ ¥¤¢¥£ž žŸ¥¢¢žŸ¢˜•žšžŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸ ¡¦¢›—’šš •|wo}yf[[`_Z\V\hdocnihb^PQ@?;:8:8<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¢ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£Ÿ¢ª©§®·¶´´¶³¯¬«®«¶°©²±­®§¦ž¢££›œ—¢¨¥¡Ÿž£›ž¡š–¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¢™˜¥ ¤§ª©¨ª­¬¥©¤¥©§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxib[_^\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>AE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢œŸª²¸¼¼½»º¿´¯±³µ´··¯µ´µ²°¨¤¢Ÿ —•š—¤ª¦¦¡¤£¤«¥¥˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨©«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥ ¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxyxc[RYT__alhukpgiibYSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶³º±ª®´±°±´´¶¼¼¾¼¼½Æº¸·º½´¯µ±±º¸·²³²ª¦¦Ÿ˜¤¤§¨¤®¤««µµ®³ §ª¬§ª©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš“–””˜“š˜Š‹‡€€|‚xa^YSah`fsositdidb[LK>:8898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÃÆÃù½¿ÀÀ½¿Ä½¼º½¾´§ª˜±À½¸µ¹À³¯¯ªª¨­§§¤¯§ª´¼±´µ¨¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`a^^jbbnwuvnl[bQU\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAB;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–•–‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±±§¼¼¾ÅÄÆÉÇÅÆ»ÄÀÅÆÀ¹¯½¼À¾¾³«ªŒ³»¾´µ·Âº­¯°µª«¦ª£­¤§±¶«µ²­³­¨®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|ƒjfhaklfnuqruqf^_\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎÌÌÇÁÃÇÇÈÊÅÄÅû¼¼ÁÅÁÅÅ¿ÃÂÆÅÀ±“¾º¿Ã¶¶º©´³´©«³»»±Ÿ›±¯¬¤¬®´§ª©¨ª­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|tkkndolhqxoyiia\gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄËÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÄÄø´À·´¼Á¹··¿À»®¥®·¼·­œ£·°¦­´µ¬®¥¥£¨¤  ¥™ª³²¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyz{vnkhguZfrwsxff]d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÅÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÉÆÃÃÄÂľ¸¾ÁÃÀľÁÏÏÎÆ«¯¶´µ« §´³®«¸µ³«©£¢­©¬¦­Ÿ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuueeijh]jomxwbb``^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÏÏÌÃÇÆÈÈÈÇÉÇÅÉÇÈÇ¿ÅÇÄÄÇÈÊÒÏÒ̼¸¶´¸¸Á¾¾º½º¼º¼¬­¦©»º¹·À²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqobagugihtmxl]d[U`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÍÐÎÇÌÉÂÁÆÁËËÇÆÌÉÍÅÆÆÃÆÅÉÍÐÍÏÌÇÄÀÃÂÉÍÇÅÁÄÇÁ»¾´±°°Á¾¿ÁÆ¿¾¸·Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`jjvlidtnsb\bTWTSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<:>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÅÇÈÆÒÉÁÃÄ¿¿¾ÄËÈÊËȼ»ÈÇÉÍÈÃÈÉÉÆÅÃÂÁÂÇÇÉÊÇÌÈÇÈÍÆËÏÅ·ÀÀÀÀ»»½µ³³¿¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrofegcjdajmnn^X\VUNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾÆÁ¹»Ãº¸¹¼¾ÁÆÁƺ¹ÉÉÃÅÄÀÄÁÂÁÄÁþ½ÂÀÀÁÂËÃÆÌËÅÈÑ°¾½¸º»¼¾·´°¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfaebabccjbfcZYY\YQNE=;8:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶·´´µ¿º½¿¹½ºº´¿¸µ·³¯»¼·À·½Â¿Á»¿Á¼»Å¾»ÁÄÀ¾¾¸¼ÁÁ˾½ÉÄÀÁÊ¿±Â¿»¸»¾¹µ·´¸¼´½¸µ´°³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|y‡}qc`bbgjffiei]VUSYOSKE8?6::779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“’’˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´´±°µ·µºÁ¸¾¸¿¼½·µ·°®¸¶¹¿»À¿·Á»»Ã¶ºÈ¸¶¹»½¹º¶»ÅÅʽ¹ÅÀ¿¼Á¾¸Æ½ÁÀ¼Å¸¶·´¸¶¶»»¸¶´·ºµ´¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒ€xpmeefoiekgXXNKKKRILHC9>8=;6:;:67<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’š”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿½¼²­¯¬±°·¼¶»¼ÀĹ···µº¹º»À½ÃÀºÄ¾Ǹ¹¸­·µ¸º´·³»ÅÆËÁ»ÆÀÀ¿½¼¿ÉÃÄžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~†|knpgpksebm_\THKJDJBCG?9;8=<7;;:78;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘ŽŽ˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼¼À·ª­¤®°·»³½¿»Ä·¶¸¶·¿¿Ä¼ÂÅÅÇÇÊÉÆÏÂÁ¸®µµ¼¾¸»²¾ÄÄÊÅÁÉÿ¿¾½ÇÌÇÇÄǽµµ¶Á½º»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†qelintnwcga\cQKTHEECGC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?=??FD@A?>:7?@CC?A=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼«ª£°¹½¾³¼¾¼Å¸²¸¹½ÇÉÊÃÇÈÆÆÉÈÌÎÑÌÊĵºÀÃÈ¿¿µ¿À¿ÆÆ¿ËÆÿÁ¼ÀÃÌÊÇÅÆÁ¹½¼Ä¿À¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtolltkln_b^`aNHM?E@?DC;;::;:8;<:9<>9:>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´¼Ã¼ºº¾¼Ä¿·½¿½ÇÌÆÇÉÆÆ¿ÄÄÊÈÌÌÍËÆÂÃËμ¹¾º¹ÀÿÈÆÄÁÁ¿ÅÀÊÉÃÃÃùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{z‡zmmw{_pc[]_^SI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA>>ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µ»¶¹Ä¸´¼¶º½Á¼»¾¶¿Á¿¼¿ºÀËÂÇÈÀ¿¼¼ÀÅÂÇËÈÁÃÀÀÉËÂÀ»»°´¼½ÀÅÆÅÅ¿À¿ËÇÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}‚zmsxsgp]Z^\YQEDCMIAD=G::59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘–žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯·¶²µ³·¹¼»¶»»½ºÃ»·½·¹À»º¸¸µÅÁÃû¹³´ºÁ½¿ÇÀ¹À¼¾ÅĽ¾¹²°®¸·¿ÃÇÃĽ½¿¿Ãþ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸¸¸½¹»±¶²ÈÀ»¶´±°·¬³©°­­³·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¦¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|vluzpni[__YSPAEHGK@DCH<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿš›œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯²´´´¶¸¹ÁÀ·½¹¸¹¶µ¿³´²¸±»ÁÀ÷·­°µ¸¸¸Âº´»·»¾À»»¼®¯®³²¹ÁÂÄþ¼¿»º¸¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ¯µ´´½º¾¹º»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰|‚zsvvwnq`_e][TJ<>?FF=FCC9:5;99><<::<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Ã¿·º·¶¶²´À¶²´¸³ºÀÁù·²²²´²·¾º³µ²¼º¼¶º¾²´´´°¸¾ÃÆÄÀ½¿¹³¯²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtvrl^b`[]NHA?=HCFMD?775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·À½»¼¸¶º¶±Àº·¹¸¹»ÁÁÄû»¶´´°¶º¶´²¬¼¹¸µ¸Áº¸³±¬·¼ÁÇÿ¹ºµ®¥¬³±¦°­¨ž Ÿ¥­¶µÂ·¶´¥¨«¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´·¶±¨¦ž ™¥¦¤¬§«¬¶ª¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wo{ournc\fX\]RNMA>JB@JI@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³±­¶º®¬¼²¸¹·»¿½¹¾À´¿»¼º¸¾Â¼ÂÊǾÀ¸¹¶²´¶³´¯¬»º¸¶¹Àö®®ª²¶¼½¹¶²±­­Ÿ¤§§£¦–™™šŸ©®¹¬««Ÿ¥¨¤«®®§¯¬¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmuik][jT]\OMHDFLAFMF8665:5:=8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹ºµ¹»µµ³µ»¼À»¾À´¿¹¹º±ºÃ¼ÂÊž»¿¿¹´´³±±®°¹¹¶¼¸»¿²²²®±®¹¯ª«­¬£¨¡ž—˜¡•’•—˜Ÿ¨®¤£¤ ¢§¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬«¯£££¡© ›“Ž“’’™–š¤¥ Ÿž§˜•’”˜ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wrxhtsndT`cW\QNLH?HQDMC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®­¯²²ºº··µµ¼´¯´«¶º¸ÀÄÁ»¶¼½¸²­³°¯¬®·¶²´´¯ª¤žœœœž¨¨Ÿ ¨©Ÿ¡§–›——“–Ž—›¤¨  ¢¢¢¥¥££ ž¥ ¤¬¤¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›ª¨ª«ž¥£›£œ•Œ“–•–˜Ÿžžš™¦—“’–¢ ¥£¦¤§ ¢¤£¡¡¬«¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦ ˆxƒ|vybwln\QhTPNGOMLBOQ@>;>39:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¥¬ª¨µ²±°®¯²§¦¯£¯®µÁºµ·²·¶²´«²´®ª«¯°²³­¥ž’˜”™ Ÿ¢ œ¤¥Ÿž¨”›–—Œ—‘—“˜¢ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£ž™—š«¦©°£¥§ž œ•“‘‘˜–•˜–Ÿ˜›™›£™—”•š §¨¥ ££¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’}|€uu}mk{dhUQcMIHGNRNJNG;D@=2?749;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜˜—–¡¨¬®¶·º¹º··»®¨ ¡©¡ ­«ª¦©¤©£¤®¥¬¬´¼·¬²±¯±­µ¯¯³µª§­¬£œ™”Ž‘–—™™œ £¢›¥žš¤———–’‘‘“š—› ¤ªž¡¡ž¦§ª¢Ÿ §ŸŸ¤§¨ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¡¤¡›˜ž¯¨®²«¥ªª š˜˜˜•“–š“••™–š——˜ žœœ—›¡šžš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}vx|dxz`bRU_HIIKSTIRPL8>B67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—““œž£¨®­¬««¯ª¯©Ÿ—ž¥žž¥¦¤ ¢Ÿ¦ ¢®«¬­µ²¶¦¯´«©ª´±°°¸­§¡œš”˜›š‘Ž‘•‘ŒŽ”™¢œ—£™š—˜™”™˜–›Ÿ¥¦© ¦£ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§  £±­±±´©±¯¢™œž¡˜››š˜™›”•š–˜œ¥¡ š£¡š™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¤¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ Ÿž ¥¡žž¥ ¦™{|uvsh‚le\SZYMQJNNULRLA7>B78=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=?758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’’œ˜¡ª¢§ ž§¡¥Ÿœ’œ¢›Ÿ¡£ž Ÿ£ ¢¯®¬¯±¬¶§­±­¦¦°®­¬°§ Ÿ¢ —‘”œ¡œ™˜’“Ÿ¢¤›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬¨¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½·¾°¬±®­©ª´±°¨«¨²µ·³·¬±´£ ¥ ¬¡¡¢  š˜–•Ÿ››˜¤¡ ž¤¡ žšœ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚|xuiwu]mZR`HQUHFUVJBMG=JH8E<67;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›Ž“ž™¨®ž§žœ¡žš™’™žœ¢¢  ¢ŸŸžŸ©«§¬©ª´««­«¥¥«¨ª¬ª¥Ÿž™’’”˜™–––Œˆ‹Ž•ž–žš¦  ¨¥±ª§®£«­¶°´²±®¶¸½Àº­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«¯±¹·¼¯³°µÁ¼·½³³µ¡«¢©¨²©«¨§¨š™šª¦Ÿ™§ ŸŸ§¨¥¤žª¢¢ž›Ÿ¨ ¥§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢˜œ›¤Ÿ › œ£‰…„~vqmiwmhm\X[BVMJGMGBFM<>L=4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DADABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜šª ±¢·£°¦ ž—˜–™ž›œ¤ŸŸ¤šœ¤¢¤£¢ª¯¬§©£ ¡¬®®ª«¦ žž¡£žžž›œ”“•”žž˜”†š¡›«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶ººÀĹ½»¬¯§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¹Â¾¸´»Åü»·³©²­ª³µ¯³®ª®£«§¶±¬¢¯¥ £¯±­°¤¤¯£¡ š¡§¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜£¢¡¤ž¦™›¢¤žŸ›››œ‡…{tqkkurphW\QETHDIOH>EA3EH95;=6;<?<<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C?ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž ¡œ˜›Ÿ › ŸŸ—¥•››ŸšžœŸ¥¦§  «±®§¤¤£ ž¥«¥ž—œ”‘™˜”ŒŠ†ˆ†ymˆ ¤¢«¬´¼¶Ã¾¾³»ÁÃÂÅÀ¿ÂÆÆÅÃÈÁÀÅÈÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌÌÌÒǾ¿À½ÇÆ·ÃÉÈÂÀž¹´¹ºµº·°µ²ªº±®»¶¾»ºª·­«ª¸º´¼®­¸¢¥¢ž§¥¢£©¦š›Ÿ˜š§ª§ ¡¡¤˜”£–”™‘œŸ¤ž¨ŸžŸ¢˜™”˜”ˆ„}zrkdioxjeZ[FJLDDSLDBD7:?;549979=><<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:=A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”••š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ³²¸§¡¡«ª¢ž¡¢žœ› ’ŸŸ–Ÿ™’š–›™£¡¯³©¡šŸŸš—˜—’Œ–—“Ž‹‚ƒ‚wsqnp¦­®´¹Å»ÍÇË¿ÂÌÎÍÌÈÉÑÌÍÌÇÉÅÆÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÒÓÌÓÐÓÓÌÊÂÅÆÆÊÇοÉÐËÆÄÆÄÁ»ÃÀ¾¾¾µ½³­¾¿ÂÃÆÄÇÄ®¾¸²¸¼ÄÁÁº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›‹™‰•˜› Ÿ£—žš““‹•…€ytsebgrof^ZYCNLCEPIDB@55589B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>8;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›£¬žŸ®¦¥±ªÅÆÌÎÍ¿°Â©¥¨­­ª¡£Ÿœš©“™¡Ž “”’—™¤±±«¤  ›™—”“”–‘Œ‡„ƒˆ‡ƒ€€yrroly¤¶º¹¾ËÁÓÒÓÈÍÎÑÓÑÒÑÐÑÑÍÎÎÐÅÎÔÕØÒ×ÍÆÇÉÌÃÅÊÏÊÓ×Ñ×ÒÔÕÓÓÈÌÇÍÍÉÒÌÎÓÍÄÇÉÊÁÅËÆÈÈž³³ÇÄËÊÊÎÅÊ¿¾¿¼ÁÇÄÌÌÈɿÿ­°³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›•Œ†‘‹zruugbgvidVWQDMF@IQB=B<:23@<D<79<B=<=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<@?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­´¸¬®£Ÿ¤£Ÿ ¤¬›–©–—Œ—¦°®¥ž¡¥¡ž›•”–”Š|wpkebhqoq{…Š€vpnqtp…³Â¾ÅÑÑ×ÖÖÒÖÍÔÖ×ÔÓÑÓÔÔÒÏÑÃÐÓÖ×ÕÖÒËÉÎÑËÆÍÒÊÒÕÖÙÕ×ÓÖØÎÒÉÎÑÌÏÐÌÒÏ¿ÇÆÊÃÌÌËÎÏÅÆǶ¿É¿ÒÌËÏÅÉÈ¿ÃÂÈÎÌÏÐÏÌÊÇ͸·»¨Ÿ¥«§Ÿ˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„|wsvoc`erb]R\IJFAEHI>;@8=4585:76:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢›©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´¶ÂƲ¶©¢¥¦¡¢«µ§š±¡–•Œ¦­«œ•˜¡›¡¢Ÿœ›•Šwica____^_`^blusqpolrqu’ÄÇÆÔÕÖ××ÓÖÏÕÔÚÔÔÏÏÕÔÔÑÑÌÑÎÓ×ÖÓÕÐÏÒÓÑÉÓÑÈÐØ×ØÑ×Ò×ÙÕÖÌÎÏÉÍÑËÎÏ¿ÅÂÇÅÎÍÐÐÑÈËÌÀÊËÅÓÎËÎÈÄÉÆÆÈÌÊÓÓÑÕÏÒÌÒÁ¹Å±¥¨µ®§š¨¬¥²¨°³¬¬““Žˆ‹Žƒ‹„Ž™“™‚…Œ{zqstmacim_VP_JJBFCQM?<>44:=52755<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><??=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯®ªª¬ž¦®¸¨«·ØÔÕÙÙÑÎÐÀ¼ÌÉ·À¯§«©£¤±¶³¤¶ªŸ¡ª©¡˜–˜š›¡žšž”~recb__a__a`_``_`fmppnkorww›ÌÀÒÕÓØØÖÙÑÒÒ×ÏÓÎËÓÍÕÔÑÊÏÌÓÖÒÑÖÍÐÕÕÑÆÑÔÊÑÔÕÖÎÒÐØØØ×ËÈÍÃÈÎÌÉË¿È¿ÈÉÍÍÏÊÐÍÎËÎÎÇÊÏÐÊÎÊÂÉÆÉÌÊÌÑÒÌÓÑÐÏÏʽȹ°­»¸µª¶°­¨¸­³¿»±šŸ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…ˆyvopnkbenpaW\ZIFFDLWE;@<34<=86855;>@<9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6==?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ¤§ž¸¶µµ­¥­®¾´±ÀÙÒ×ÚÜÖÏÍËÃÓв«­®¬¦³±¸«±¶©£Ÿœ–”—›žŸŸ”–—•‰l^^^adb``aa``a^__^]bmroostvvy¤¾ËÕÑÖÔÓØÖÎÎÔËÍÎÅÎÊÒÒÏÆÎÍÍÔÌÎÓÍÊ×ÕÐÌÑÓËÌÐÑÓÊÎÑÕÒÕÕÊÀÉÁÅÌÂÈÉÂÌÂÅÈÉÊÎÊÌÌÏÍÓËÅÇÏÌÇÇÊÄÆÀÅÉËÍÐÑÆÏÎÍÍÌÏÅÇÀ·¹½Ãýù²³¾±¼Äĵª˜¥¡™–‘••’‹”š‘”””‚‰…xpqknh``qhXXhVMGLIPPB;D>;67:89:57==@;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;776?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÅÃÁ¿»µ²±ÇùËÕÖÙÚÛØÍÌÏÉÖÖÅĸ²¶ª¤®­¸»ÁÅÉ¡—Ž˜–“’‘–––Œ|ebbb`]^acb`_``aa`_][]grqqrsqmry¤ÆÓÏËÐÏÔÕÉÅÉÉÆÆ¿ÃÆÏÎÇÅÇÍÊÑÈËÎÍÆÑÒÏÎÌÔÊÇËÎÏÇÇÏÒËÐÏźľÆɼÂÆÈÎÄÂÇÀÆÍÇÃËÉËÏÇÃÃÏÈÆÁÆÇþÀÇËËËÎÂÊËÈÇËÏÄÅÇ»ÇÃÈÈÂÏÀ½¼¿°ÁÊǺ½ª±²§¥¢œ˜›¤™—™‘•˜‰‚wntdl`^fqa[W`GHHGIMTG?J=64355=<48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥³±¬ÉÍÊÈľ½ºÍÍÆÐÕÕÙÚÛØÐÊÐÐÒÔÊź¾¾°¨·ªÅÝÖDZ‘ŽŽ–†ƒ„„‚~……t`[^^^`^`cdc_]]^_``_[Z\`krrookloo}¸ÑÈÉÊÏËÍĺÀû»ºº¾ÈÆÂÃÀÃÇÊÉÈÊÇÁÅÌÆÈËÍÉÄÂËÉÂÂËÐÄËÈ¿¹ÁºÅǽ¿ÆÏÊÿúÉÇȺÇÆÄÊÀ½ÁËÆÅýż¼¿ÃÄËÄļ¿ÉÂÅÇÑÅÀÈ¿ÊÊÆÈÆÐÃÃÆïÄËÇÄÊ·¿¼º´©¬¥¥˜Ÿ˜¬£¡¥š£ ›”{vstfj[anmZ[XQDLFBGDLDFS@54334?<3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ÊÏÑÌÇÂÃÇÍÏÎÍÕÐÖÙØÙÐÍÔÎÏÐËĸÆÁ¶µ¼¯ØÃu}’Œ“—‡{€…†€vxurp_Z[]`abcdded`\\]]_^`[YZ\borokilposÆ¼ÉÅÌÀƱ¶º²²³²±Â¼¼»¹¸ÀÁÁž½¹½¿¹ÄÊÅƽÆÀ¸»ÄÉ¿ÂÉ»·ººÅ¾¼ÁÍÂƾ½µÀ½Ãº¼Æ»Â¹³¼Åö¿µµ¾¿ºËüµºÈº¿½ËÃÁÅÂÆÈÆÈÆÐÆÂÌȲÇÊÃÎÍÁÅ¿½²·°³§¨¨¹±¥­°«­¬”yvwjeh`hocV^YJEJFHKAFBEI@9:648853;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÆÂÄÈÎÒËÊÊÇÍÎÏÒÉÑÆÖÕÖØÎÌÐÈÍÈÊžÊÁ²µººÓpVŽŽŠ‹…y€††€~„|tud\\]^``bcbbeeb]][\^\^]Z[]]hsqmggnpry½ÌÀúÁ¸®°°§ª­¬§¸´·´³²³ºµ½±·°µ¯²»Â¼Áļ¿»µ²º¾À¸Ç¸´»µÀ¼·½ÆÀû´®²¶º¾³Ä·»µ«¸¼½À½°ºµ¯¶º²Å¼¶®»¿´¶´Å¼¾ÃÅÀÃÅÆÈËÆÀÆÆ»ÈË¿ÏÊÇÃÆÁ÷þ½¶¹¾Æ¿¬µºµ·¶Žxtxggebkn^V^`FKHHJFBCAEE?<:565633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÎÈÆÉÎÌÐÍÎÉËÉÌÊËÆÑÏÓÑÏÈËÆÊÆÄÀ½Ï½³¹½½¹X’†‰‰{y~††wx‚}th^]]]_`_`da^cec__\[^\]^Z[[]_lpmhfjmnr|¤Ç¿¹¸µ°¬¬§ž¢ª§ž«¬³­©«©³­¶°²©®¦¬²¼º¶Ã¹ºº±ªµ¹»´Âº°¿°½¼»µ»Ç¹Â¶­ª¨°±Àµ¸¼¯°§±³´»¼«­µ¥®¶®º±°ª¹¯­»®»¸»¿¿½¹Â¿ÇÃÅÁ¼ÆÁÈ˸ÅÇÅ¿ÇÃúÄÆ»ÅÉÌ˳¹Â¼º²ˆrvvkiablhYXW[ALKMIEAC?FA:9:995854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?<>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÆÏÒÌÄÆÁÅÐÈÏÂÄÇÁÆÆÅÅÌÄËÌÂÄÁÈÁº¼»Ê·´¼½·­w“‰|y~Š…z{„wn^]]]]_`__dcbccb`_^[[ZZ]ZZZZ]dnohfgiknr­¹°µ®¦¥§§š ¤ šœ¥«®£§¢«©¬ª°£¦Ÿª­µ¶±½¹¯¸¯¨®¸´´¼¸³¼®·¹´±»Á±Á®¥©¢¬±²³§¼ª«¨«¬­´´¦¨®¡¤®©²¥§¨®¥¨·¬°²·¹º»±¼½¾¾Ä¿µÁÁÇÈ·¿ÀÅ·Ä¿»¿ÄþÄÈÌÊ¿¾ÃÀÀ©†rtrji]aodWVXPHZRSKFFE>?@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·ºÄ°¶°›™•œ˜ª©°±³µ½¯ÆÑÐÍÄÈ»»ÌÃÌÀ¼Ê¹ÀÆÀ¼ÌºÃÇź½Ä¾º·½Æ¹¶¹»¯²’„‰{~€~xt|swf_]\\^_`^_ccab``_^]\ZXY[[YXZ\_fkfegehkor…ª¥¬¦ œ¡¥”ž¤›—‘¡£ª£¢Ÿ¥¥§¤¬Ÿ›¤¦¬²¯¶·§°¬§ª´«´¹°¶´¬¶¸±¯º¹±·¤Ÿ£Ÿ§±§«¨¹ª¤¦§¨§²­ §¦ž›¤¦¬žŸ§¤Ÿ ±­­¬²´²´°µ¼¶»ÁÁ²º¾ÃÁ²¹ºÂ³À½¿µ¸»½¾¼ÂÇÄÂþ¿Ã ƒwpkae_ko`UY_HNhOTHEJF<=?=:;;825536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;=:7676778666;::;9:;<859<:>>@;Èµ¶½¸ºÁ»¾µ ž•ž¡¦º¶«³³»³ÅÐÉÌÃǹ¸ÉÂÎÁºË¹½È»·È»·ÄƳ¾Å¼·°¹À»±³·°£…‡‡‚}yvtomkjjqi_`]\\]_`_acb````]\[\\XYXXXVX[]^dcbegggjmoˆ© —•š¡–›¢˜•ž¡¢¦›ŸŸ£¥¡§žš¢›Ÿª°­±µ¢©ª©«¬¤µ¸­·¯¬²´®²´®°ªŸž£¢²¤¥©¸­¡¦¦Ÿ¨¬«™Ÿ ž™Ÿ¥š™£œ›¯©«§ª«¬­°²¸¯¸¹»°¶»»º«²²¹²½´¶±±µ´¿µ½À½ÃÁºº½—ƒzrk_e^ddXTX^IW]KPGIJFA<??@;?<04536:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»·ÁÁÁ´¤¤™›¤¦À²¯¶¬´·ÆÐÉÉÁǼ¼ÅÅÐÀ¼Ê»»Á»¶Å¸µÁÁ³Âļ­ªµº·¨±³©‹†ˆ€ysnpnkb^bff]]^]]]\]_`abccba_\[[Z[YXWWWWXXX[^bddeffhikr¨”””›˜›¡––œ¡¡¨›œ¥¦¡¤›Ÿ š˜­®­®² ¥¢­«§¡µ°±±¬§®²§¹³¦µ¡¢žš£¢­¢¡©µª¢£¦¥¦£–˜ž—˜šŸ™—œœ›¬¡«¦£¤¦­«³³ª´°²ª²¹´¯©¯²²²·³­©¬®±·°º¶¹½¿¶²±”…yue^e^[YVSZUK[QLIEHKIB=?AA@@:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½¸½¿¶¾½¿³¥£˜¥±Âµ¶½­´¸ÃÍÉÈÁƸÂÁÈкÃÆÀ¶¼½¶Ãº¶¿Áµ»¿»ª¦±»±¨²¯›}……€ypqtqhfdiec\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXXVWadecdeddhjv¢œ”””–—Ÿ—™”˜Ÿž¡œ–¡¡¨£Ÿ¨œššª¦¯°«›££·ª Ÿ®¨¶©¦¦¬°£·°£¶ ¢›˜˜ª¦¡›¬¸¯¢¡¤œ¡Ÿ “•¡”––›˜—–—œ”Ÿ©©£¡£ªª°®¨´«ª¦­²°¥ª®²±¯°®®§§§²®±´¯¼´¹¶®£”yud^aVYWSRTKM^LPKGGLKE<@><B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾¸¼®ž§§£ª»À½À¹®´¸ÂÍÈÇÄžǺÊ͵ÄÅű¿À¹ÀÁºÀÀ¹º½·¨¨±»¦©¢¥‰~xrjlrtpihedgb\\ZYZ\\\]^]\[\^\[\Y[\ZXVWWVWXWWWU[ccbbcbcdfj–“•‹‘”“›™œ––› œŸ• Ÿ¦¥¤¥¦žœŸ¤Ÿª¯¦Ÿ¢£¶¨ ¡¢¨³¡¥§¤¯¥°¬«´ž •”©¡¡”¬±°ž¢¢ž˜›“‹¡”‘“—˜’——˜–¦›¦¡¢™£¥¥«¤¥°§¥£««­¥¨®¯®«¨ªª³¥¦«¯´±®¼µ±¯¯ ’zvrda\Z]XNLQGRaMVPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8846863321./2556;:8;7876<;:;;A8x»»±µ½°»²·¬ž¤§­·»¼Áź±¹µÅÊËÁÄÇÇɸÈƵÅÂɯº¼Â¼ÃÀÁ½¼·º¶¦§²¶ž¢Š™‡€wodbgihfhjgjm`]\[ZZYZ\]\[\^_\ZY[YYZ[WUXWTTWUSTRU``_`a_`acdi”“‰‘Ž”’“œ”•–£™ –œ ¥¡­¥££¢£¡›ªª¥™ž¥±©  ¤ª§¡ž¬¬©¨­¬¢¡¡”—£›œ«©°›Ÿ¢žž—˜“Šž’’“•˜˜’›¡¢œ¤ ¡• ¡¤¦›£«¥¢¤ª£«®¤®±©¦¥¦¦´¦©¨­³µ´¹º¯ª¬ž‹rpo`[WVUQFQOHZ\ORITKSLEGIC8;;=<8667:9;:976977:;:=<<7;<8>598:88659:;<97?<9678452121..1426:86:859898:;9@9{µ´­´»²°¬²­§§¯¹¹³ÀȺµÀ¯ÆÉλÂËÍÉ·Ë¿´ÀÇÌ°¶½È»ÂÇĽ¿·ºµ¥«°®š‡Žƒ|uijjmhjlnkkme]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURSOQY]\]^^___bdmŽ„‘†‘™“”’œš¢œ› §¨ª§ª¥¨¤£˜¤®¤”™¥¯©Ÿ›˜š ž®™›ª³Ÿ¥¦ž¢£ ”“›–•’¨©­šœ ¡ š”Œ™Ž‹Œ’Œ–”¡ £œ›¢•› ¢ —¢¨£¢¨« «¯¤­·¥££¢¬­©¨«¯³¸²½µ³«¯˜ƒrrh[XYSUREYLP\YMTOPLPRINIB<??A?=65799<<987:79:;<=>;7;;:=67:;8976989:6:=99577571141-+/434988::8::748=8?9~³®¨³¶®©¨¯­›©¨¬·¶¬¼Ê»¶¿¬ÌÇƹÂÏÐɵƾº¾Æ˵±½Å½ÃÆĽÁ³¹¯¦«¯«ž—†wxoninnnqggigd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUTSNPQYZZZ]\\^_`d~‹‹Š’—‘—™¢ ›Ÿª©¦­ª¦¯¢§™Ÿ¬ •–¤¨§—Ž™®–—§ª™Ÿ“¥ ‘’’’•§ª¤™™š–Œ‹”†ˆƒ‹’” ž £—•Ÿ•š ¢“›¥¥§¨¨ ±°¦°¼§ £¬´«­§°´°¹µÀ±­±«}prbVTUNRIGVQSRLLXMJLNRGMKACFDC>@75889;9:7::7<=:;@>:9;9:?759:9876958779;85576661320-*.102877;99;8948;8@8³­¦±·ª¦¢°«ª§©²±¤¶Æ´¹º³Ëƺ¼ÃËÑ̳¹º¾ÀÄǶ´·½³»¼Ä¾Â±´®±®±¬œ¢ˆkhnoroqkpkdfge^ZYZYZZZ[ZZZ\\]\ZXXXYYWXWUUTRSUSVURNNNRWXYYYY\\]aj€zu‰Ž‡‰˜‰””—›™¨›Ÿª¤¤ªœ§˜ ¥›’ž¢š—–„ƒ‘š£“¢œ••–‡¡šš“‹ŽŠ™£§œ••—›’‡”ŽŒ‹€Š’’‘¡šŸ¡•“˜˜•¢¥˜Œ™¤¦¨¦¡ ´²§²·¡¢·¬ª­¤²²¦µ¼µ¬«±£ˆxrm]NPQLOCNNNPKFNNKJNMQIMJAGKHHC>858889:;69:68;99><8:>9;?8789:886857688974577820301+)-/12776:999984988A7w¶§¤¶°¤§¤©¥ ©¥¤³ª¢²Ãµµ²³ÇǸ»ÄÊÍǵ¯¼¿¸¼Ä³³®¶¢­µÄº»¯ª¬´¯¯ —¨}^`gsqvqjnifhhj_XYXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQNMKLSWWVXXYX[]aosvq…ˆ‚‡€‘ƒŽŠ”‘“ Žš›¢ £˜¤–¡›•‡˜šŒs‚}––…™“Žz˜ŽœŒ‚Š‰˜Ÿ¢ž“˜–„Ž‚“~~t‰Žz†’š™š•Ž¢£Ž‰š ¡¤£›¢´¯¬¯¬Ÿ˜¥¹¦¥°¡°®œ°»ª©¯ª™vrbVLQOPMCSNLQMCPPHINSMHJJDJLEJK=749888;;69;7:<9::;79?9>@79:<89764445874312485/0102)(,-12764789::65:87A7w·¢£´¨¥¥¨£¦¥¦¦¦³§¥´À¸°´°ÊƹºÂÏÇ¿µ¯½Ã¯±Ç²­§¬•¤®¿¸±°Ÿ§­­«–•¢rWV_hgihincjhgb\XXXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTQMMJHNSSSTUUWY[]ilrm…|tNXr‚—†œ—Š“ž—œ•”–”Ž–‰“‰_;Wo{‹“‰‹‘Œ…†rŠ„–y‚z…“”ƒ•Ž‚†}’xqo…~‰€—™˜“Šˆœˆž—‡‡–žš¡ —§¯¨­©¨Ÿ—­´¢¦­˜¬«˜§´¢©­£’}qm_ZNSQVLDTJPMLFOOJFLQMKPJIMPFIH=7599999:7:;:>>8:==6:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9x· £®¡¦¦ª §©§¢©°¨§´Á¹±µ°Éù´¿ÏÀº±±¸Ä«®É®§£ž†›¢º­§¨–¦¥¤¡—–iQMRVZZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MORMKHFHNQQMPRTVXZ`moi{‚tPB@•‘‘}‰”Œ„ŠšŒ–•Š’ˆ†•†yˆ`JQnxŠ‘„|„Œ‰„n~”wuvx„™pQˆŠ†{~x”vgw…ˆ~Šˆ•Š’–‹ƒ‰‡”„šŒ„’›–žœ”¤£§©¥£ž›°«¡¤¤¦ª–¡ªœ¢¦¨ˆtke][HQQSLIUMSILLPIHFKOLMTKQQOFIC<769:8:;;8:;8>?99>=7;<6;;478;6775344696/3/.115221/,')+*,4833979:99::::?9v¶œ£§Ÿ¡®¡§¨¥§¨¯¬ª¶¼¶¸¶³Â¼·¨ºÉ¹·©ª·¸­¶Àª¢›“ƒ™²Ÿ¢š –™”ŠŒdMLNNOLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDDINOhYNQSTUZnƒtw~ji]U‰”‰t†{…Œ’’™‹{†uxsnupty}‰ª…yzhv{Žprmx€ŠŒ’xz€{€vsr’wgu„„„„z•‰ˆŠŒ‹€„ŠŒ”ƒ{€˜”›•‘Ÿ¨žŸ ž ©¥Ÿ˜Œ§¤“  –ž¤qg`\\JVOQGKXROJLMRJJJMPHLQLRTMEHA<78;99>=:;<98@?::>=7==79937795675252572/2.,./200/-+(().1262198798776:<<7v®˜£¡˜œž³©¯©¥¬¬°±ª½´²¼¸¶ºµ² ·»³«Ÿ­«¬µ³¥ž–’˜†”¤–Œƒ—‰‰……‚dKIJIGFHHPTTTWWSTUUUVWWWXXXXXXXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQRSV^uƒ}ygw—˜Ž}gyvx‰|„˜’r‡|v{ok~­|sŠ{†’€}tfv|…lohs|‰Œ‡€lyq}pmuqhq€}ŽpCŠ„‚ƒ…~wwz‹…}‹zu~Ž’˜Š’š›£—™›ž¢–Š¤›—Ž–˜ŽumkeaYWXTQJRUTOPNQVKNKNOJQOIOOKFD<;79;::?=9<:99??;8<=7<9999266856633621224.,,-..-0-+*''*.1362/876966527995y¦—Ÿž– ¦¯¬®«§©°¯±¬¼¸¬»¾¹³­¨›±¨­œ—ž§¬§¤›“ˆ–~Ž•’•€|Šz…€~~bJGHFB@CDILLMQRPQSUTTUVWWWXWYYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNPQTX^eprmˆ§ªÀ~uyb{xo|yˆy|‹…omŒ‘xsxjj‚r–‘‹}–I’˜nhw~licly…’†ksl|nr{†hmp~sˆƒ…z}~{vott…‚ywp|ŽŒŠ“ƒ–—˜š“–—™—ž—Œƒ‰Ÿ‘Š’Œ†–}lhmnmWUWTQQYOSUTTXUMNHMJMNKCINGE@:89;99:><9<;::=>:8:;9?868727575541442/024*+**-.+-*(*(',-1250,5567485HA895w™‘›™šž¤­¯¢­ª¨µ¯®¬´¿«¼Â¿¦£š•¥˜žŽ…Œ–¢¤›š”—v‘~…‹|x~t}xtwydOEGD@<>>AFGGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jrA™o;<95<€‚†_IMOORWZRY\`§ˆbšitze~pmz‹ˆuˆ†tl™‘ts{jkŽLy„’‰„Žg1v†sl~}ƒtfet~„„…€filukp|gpp{n’Ž{s}|qpnum‚~wytiy‰‚ˆ‰ƒ–“’‹‘”•—Ž€yˆ—ˆ†‰†‡uiingcWQYWXY[MPUVZYNIIEJJHGBAFDCG=998;9:9<:9;:::@<9:<98>787715244533645031.**+),,++)(+'),,226-+5775478iO8;5n’ˆ™‘š–¤¨­ž²ž¦º®«²°Â²»ÃǛ—”™‹Ž†z…‘š–’Ž’‰tŠ„w‹ŒvwuxvoxrhUFID?<;9:?@ADDEGJLOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOPQVLAIQIb¯³ q|xm}mqƒ…y„††yr ”tx€su”‡5q¨Ž¡¡„¢„vp†|‡|sŒ­ˆ€hfbinrmpƒuioXuoŽš‘vlz|mqmpzsumbv„†€…‘Š‹‰‘‹‘Œ‹ƒux‹€~‚€}xpnnj^Z[][YX`_SN[ZYXLHJFJG?CABG?CD=;97=;:;;9:99;:?<88=:8;66651121353475531./,,+)*))***)(*)+/3DM2166643<vR7=7b’’ˆ–‘¤§ž¯•¥´¨­±®Á³ºÁƗŒ”‰}n‚‘“Š„‹ˆˆv„…o˜ŠŒy{{q{t|ko_JPG>@7458;;<=>@BEILLLMNPQRUUVWXYXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL7CMRSDJ†v€||v~lvˆˆ|}…ƒŒ~v¢™y~†€„™…›œa†ªŸ‹‚zv‰~‰ˆŽsŠ—ƒ{\dqtz{wŠlgiaxo…‚znws„zpsywkni]w‡}‡|ˆ‡€‹“—ƒ††}q„„|uw{}ˆtmqrde^ZZ]S[f^XQUY\VGKKELG?F@DC?AA=:97<;;=<::99;;=>79>9986754244004645654-,)+('''&(())((+++/00Uq<23331E~W4=9\Œw‰”Œ‘Ÿ¦‘ ªŸ°©¯À±»Æº–‘”ˆz†vk€Œ’ƒ~‹…y„‚u¢†~~‚€sƒ}kzlSXLAE311266688:<?BEGFGJKMOPQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMORLKT]YRJi„‰{‰y{q|Œ{|‰†~—‡v¡™ˆ‡’”¥¬©H†­¯¯Š€€“Š‚‹‚„‘¨‡€˜˜Šœsl|†‡}Žhggx~n…†…q„†Gk€wqyvhmk_w}ƒˆˆ…Œz•žœŠ‹‰‘{u‹v|wmow~}qqpjZ[[ZcbWge\UPQXZQDLLGOICFCCA@CA=988:::;;:888::?>6;>7595773344236756768;DFLMMLC7+"&'+)++,/00+nu22420L\5=<^„t|~Š…‡‘–˜’— ¬¡¦¸¯³½´—’‹˜‹}tpŠ“~ƒ”•}†‡¥‡‰€ƒˆ†y‰‹€u…y_cVLC60./22123668:=??BEGHJLNQSTUTTVUSQOGC?80,#‡[>?84.]–ps£UFIKMNPW`YpZ\^j“‡•€„‚…‘“~…‰‘š–‚ ¡˜•›š¥­“™»±§»Ç犌¡¥Ž“‰{rƒžŸ‘œ~v……‹‡ihoƒ€tŒ†„‹q†‚w‡{v…}nvug”†‰ˆˆ‰ˆ¢«£–‰Ž˜€{‚‰zzogkx}w|qic\YY\h\af_ZOLNXSQIPKDNGCJDCADDA<:87=<:<:88778:==8<=68756623445576867<BB?<8:>CQ^e\G2'&,,--.1(?Œ[.310Oƒ_4?;nvpgxƒ{€Œ€‹šš¤œ¡¬¦«¯°—’‘„¡”„xw€”}’†“–~Š’›Ž„‚Œ‹‚ŠŽ„€Š€mpj^CA4--////02234779;=?BDHJOQRSRSSTRPOHDB<87/9C><<63.l“—MPHIKKKNV`cggmu›š““‹Žšˆ“‹ ¡’£©¥£¬“¨¶¢§Á®ȯxº”š|Œ¡ž˜„“…‚¡ž“™’„Š…˜–lpu‰‹•Œv„ql…Š–’ƒ…ˆr‰¡—‡“‰—¥¶©›•¢ƒ‡“„~kjl}~}q_[b^Yfj\lk_XKHPSQNMLFIQDDNFBCEGB>:97=<:;:987767;:6=:785456345566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYpƒpu‡qv‘†~—–š”ŸŸ›§ ª–“˜žhf¤š~…“’z’‰’’}‹…™’‘ƒ‹Ž‰†‘‡„ˆ…xxhNR>//.,/.-/000212457;?CFNPRTPQQSQNPIED>;<:CF?><752<?R5HHHLLMNR^oŠ|s} ›§¦¢™¡—¢•œŸ¨ž©«Ÿ¨¬©ªµ—«¿«¶ÈÉ·ÈÑϾ› pi«©Ÿ„“’…œ šš™§‘‘ˆ•¡™šwz~”—‘¡’–—”ž{v•’«³‰— }•žœŽ“–š¤£§¶°‘™¨ˆ—Žˆlss{|ynf^[_^agc_gg\REKKQOIJMFFMCHLFFCBGDA:85<<899975658>75=84745754546958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f3A@ib^Pqu`n}awŽ}|”ŽŽŠŸ’—ž–œª˜žªBD}‡‰ˆ˜y‚‹Ž|Š†Žƒ€‰Œ‰…“…‚†‰€‡w_bP460-1/,.00./..0015>AAMQRSPRSUSNSLEE@<>=FH@A@8662<9;FHGIIMOQYm†w•‹£§ªµ½¸¥®¬¬¨©µ¬±·²²­»±³¾œ³Ä¬»É˸ÿ·¥£°²¬­ª£‹–˜…¥¦ ¢˜‚¦™¢ª§¤‡…“£  ª ¤©Žœ±‹•£§·»œ¡£°“££ž‘¤¢«°­³µ¢•¦ª‰šŠ“Š•z{~ƒ{e^fZc`]bb^fg_[ODIHTOFHLFKGFFHAKFCFFA;87=<88:974658<54<76:54644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLicWjpXz…v”…ˆ‚›ƒ’‘Œ’Úȝ–sV—ˆˆœ|†Œ‹Š{ˆƒ‡‘Žƒ…Œ†…ˆ’†‚„‰†‡‡‡qna@E64<3/110-,+-1/-4?DANVQRSUUWUM\QGGD<>>FHCD@8;<5C;=FKIGHROPW“ „®£³ª²ÁÇÄ«³Å¶­´À³¸¾¶¿´Á¶»»¤¸Æ©¶ÉǶ¾¹´¨£´­°±›™’šŸ‰§¯ª¤•wŸ¤—¡«±³˜–©­¨®µ»²º¬¯µ¢±¬²µ¼¸´®µ ¨¨£¨›©°­³º¸¸¨œ¸©¥’“ ‡y€rW_bUd``a^_f`[UJDELVQIJJEJHEA@@KDBMF<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AEWQJL\ZQcdWzuq•}„†“v†~€{¿»£¼‚´”“Ž›„ˆ“Š‰z‡Œ“‡…Ž€Š†€†ˆ…Š‡‘zyn]W@EN<6:46AB764//6CHCQ\OQUXU\WO_UIKJA@?GKFFD;>@7D7?BJJEGWTP^¤­¤²´Ã¶¸ÁÌʶ»Ä½³´Á·¸Âµ¿°¸t±´¦ºÅ¤°Æ¹±³²´¨¤¶¶ª± ¢–›¢’¥±­¥­¬§¤˜ ¬³º¢¨²¹µ»¾Ì¿ÅŽ½³Â·º·¿¸º¸º­­±¦±ª®¾°½¼Ã왻¨•®˜™«‰~€yhUa_VhchdV[cYVTJGGLRGDIJAID>?BBL@@MD99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FRLALRWTYVZwjp„Ž…o{rxˆb¹¡™£‰•”–“””Ž—’‡‡{‡Ž–Š„Šz|‹ˆ†|Š‚‹„•}xzufO\dGEL:Qd`[^SF?;HPDZcQQYYZgZS`aMSOEA?IJHEFA@C=E6B?HGKMSZT^”¯¸µ»¹ÉÀ»½Êͼ¼Á¼¸¶¼»·¾µº³Æau²¥±šž«¾ª¥¨«ª¤¢²µ «§ž•–ž˜Ÿ®¥§§¥Ÿ¤“¢§°³¨²²¼¶Á½ÓÉÉÓÆÂÅÌÂÊÄÀ¾¾¿¼¼¸´°¹··ÃºÆ¾ÄÉ°žº«¢¬¥©·‰€|n\^^\U_]gfSYaVRVIEFNKA>HD=KB=B@=F>;H@796379>489:57045/26389374526?8@>GKRTTRPOQRQJA9/,,,*+((,-,/P>(.48€}<2Kˆq9>CKE@JMPRLQ]hmlq†slrrtˆÕÀµš •™™‘Ž—’––Ž†ˆ}‡ƒ–Š~‚ƒy{‹„‡{‹yŠ‚—t}zlepvY]\Peeb`ed][XX\MdmURmn_o_XgeUYTKDBKKHFHHHHBI9D@HKTTV]Z\“¹À¹¾¸ÆÁ»¹ÊË»¶º¶¸¹´¸µµ®¶·™du©ž­p^¢­œ˜¡¢›¤ž«¥”ŸŸ”Ž–˜—¨ž¦ŸŸš™ƒ£¬¤ª±­·°¼¸ÔÐÎÖÏÉÌÒÌÏÎÊÇÀ¿ÂʽÁ½ÂÀÅÄÆÊÀÉÏ´¤¼±µ°œ¬¹½š}vi[\YW[_XabQ\aTRLCBFGE<@F>BIB@D=:E>=J?47535;=468977022/24169775555D3ELM>510006:477@IOJ;.&**(-.0,@M+/54m‰I0H‰t?>BD@CDGKODR\Zi`o—’‘”nlotu‡³¬¡¡Ÿ‹™œ™•‘›’…ŠŠˆ‡Œ‹‰|„s{Šƒ…{ŠtŠ‡•t{ylmu|iseilhfjih`fiimZmt—­¤½ˆ‡g[oh]ZYTHKOPJKPKTQHLAJFKP__bgjb—·Ç°º´»¾¶±ÅǶ°¹±±»­³±¨«¸­¶¨žœ§šNšžŒ –‘§˜¥•Š““ˆ‘‰‘’›¡˜›•–‡ž™¦š¬°¨¯§³³ÓÔÔÖÑËÏÓÔÎÓÏÌÆÃÊпÊÉËÉÒÈÍÎÃÐÒ¸°Ä½Äº¦·»Ä¢kaZZ[V^VYcYP]XORCBIECI;AD>BH?@B8;D>@I=56655;:687654/10146278875367C5B8?-0,1348=97,.,1;FL=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYSfWs‘™ƒhroyyƒ¡ªž¦—Œ››˜‹Ž•‘šŽ}‰‹…ŽŠŠ‹ˆ|„‚p‡†{‡rƒ’‹~qyulpxr{nxsli€pmcinpyiw}~Ë¿Ãߧncxnd[a`KPRUNY^P^]NQNTQUT\nnwƒr–®¸¬µ¨°¶«­½Á²«µ¦¥¹§¬¯¡¬´¤±®›˜˜Œ‘”‘„›§‘œ‰ƒ‹„Š‰„‹ƒ”•——”›œ˜™™žž«¬¤§¢¬¬ÎÒÕÑÍÌÒÓÓÐÔÑÎÈÃÔÑÈÎÒÓÓ×ÍÒÑÅÒÖÆÁÏÈÈ鿸МvkbZ_[T^Q\YOPTPNI>AGBCF=AB?FE>@?:==<<JB45465<888664412/03526768533;=<E=@11+/349?5901022-2EO3)/3.32=N248C}_2A†tD:==I>@CFH<VRMO[u‡†‹wlwp}~€ žž¡Œ™“”‹Œ“–…y…Ž‹Šˆ‘‡‚{r~€‚‡z…v…“‘‰€owsls}|w|s‚xqk€rriprzyr{¾Ëš²„vr…wiai]DZZ[WfdXekTX]]`c^cx{‹™ª¤¤¢ ¡©¦ª±¹«¦´£¢®¢¤®¢§±Ÿ‰¦›•“‘Š’ˆ‚”‰k•¢™„†~‘ƒƒ“—¬‹•Ž•šŽ…’—§°¢ ¡¥¤¨ÈÍÏÇÂËÐÓÑÔÒÎÓÍÆÖÓÍÔØÖÖØÕ×ÕÊÔÚÍÊØÖÑË­ÄÃˈol_\\VRWRZOJGIJJ@;:;EBD=CD>HC?CB;<9<:GC46544<5687543250/2546745544<>=E?A62/-16;=081/254/-.;R017/532ED28>nb5=tM99@I<AD?A;PLFKYp€u~isyr‚Š€•ž”…‹–‰Š‰Žˆ€x„”™‹ˆˆ‹‰~ƒxs|}„‡w€{‡‘—„oxqmuvx}t†|yl‡vtn}v…uy{µŒ<A‹Æ¥~}jeWICecfchjdoy[_fhknin„‰‘ŒžŸ ž‘—™ £¤¦²¤¥² ¢¥Ÿ¢©¡¢±œ‡Ÿ’’“‘‹‹‡„„~œœŒ‚„…z”‚ª–£Œ’‹˜“‹}—Šš‘ª³˜›œ§œ¦½ÃŹ¶ÅÍÑÐÒÐËÒËÉÔÎÑÕÚ××ØÔÙØÍØÛÎÉÚÚÒÖ¿ÌÍ´uskaZWPSPXUEGJIFE=:7:@BC:HE@EDBDA;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?2*(.BT29254/7K75<`bA<svV87AH:?C><9QECJTlnopbqqt†}—‘ž‹~‡’‚‰†…Š‚ˆ}x…——‰ƒ‡†‡z„yq{{…†uz†ŽŽzp}ppz€r{r„‡€nŽzuw}}‚u|‡‰°tYªÂ·’pnc=^hrpqpnww‚eiorvxr{Œ‡“’›– –ˆŒ“œŸ›Ÿ« ¡¬œ¢šš ¦ŸŸ¬™Œš‘“Ž…}ˆ‡ƒ…‹Ž ™“ˆƒ‡~l™y„™‡ˆ“ŒŽ•Œ†{›ˆ“Ž­ª”•—Ÿ˜¦®µ¼¨­½ÇËÈÉËËÏÉÄÒÊÔ×Ø×Ø×ÔÛ×ÓÙÛÖÏÛÚÒÖÉÕ̓uwedXWNQR[GCFIH>B>=8:>@<>H=@BAAEA>?:87DB755479.566435532323647553458EBDCEB56<FNSM[nfcnsk`V>,4LG865433BF4=W_hLux^8;?F<<B<:9D?CGRk_mdbflv€ˆq‘›€y€Ž~‚‚…„|}„˜Ž‡Œ†‡wƒyn{{‡‚tz’žŽ¡vvƒtu~t€„o‚o’…u|…zv‡|‰¸Æ¥Ãʸ‚–œxpfNec‚z‚w…¡‹yzw{„€|„um”–•–˜‘ƒ‰—š——¦˜ —Ÿ“’—£žš«–‘‘‹“ƒŒ…‰‰†‘žœ™ˆ…‹…—zˆ‰Ÿ—‰ŽŠ‹‚|¡‰‹¼ ˜“—šœ¨¦¥­ž§µ¿¿¿¸ÆÉÍÎÅÍÊÑÖÕÔÙÕ×ÛÔ×ÙÚÛ×ÛÚÙØÎÛƃvvdfa]RUTTMKDMC;=<<9:<?9=A7>?@=?>=9867CA6455=80665547745613854564567HH=DJE7925;H>;9:7HP\ZRUXK9T>;95327I8=NYMHxxd5=>C=<@:6:>>@EQ_Yfa]\itzyl‰’wvz‹|~€€~…{~‚‘Š…†{…ˆ|u~um|}‡~t’‘Ÿƒ’|‡~x~y‹Šoƒ›t™†}‚Š…|~‘{©Ã ½Œ›¤œ~Š…}‰sŒ‹s¦šœ˜”…{‘‰„iGq¡¤žŒŒ‘’…ˆ‹’•›“”‘—Œ•Ÿ”¡•“ŽŽŒŽ‹„‰’–™ŸŸˆŒ”‘‚Œ¦™ˆ…Žƒ†„€¥†Š‹¸—‘”–¡¦ £®¶¹´«ÀÆÊÐÈÇÍÏÓÒÒØÒÕ×À×ØÙÛØÚÚÙÙ×Û¶vutgfbT]YRNNHCLC==>99;:99<=6@>?==9::;37D@8378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWO<MTHN?96333>C;[X>5YypZ<<A<=>8589?<DRSRX_VXfmmmiŽŠqsyŠ{{€||ˆ{}|‹‡ƒ~u„†zszsm~…~w†›¡›ž”’€Œˆ˜‡€œ’nˆ©…{ Œ|‘Žƒ‰„œ~›‘Š£¢Ÿ‘¤¯ ‹‘‹…‹“†Wr­‹Ÿ«›ƒ™œŽ[ƒ¢‘‚Ÿ“”Œ†ˆŒ’’Œ”••ŒŠˆ–›•–’Œ“”†€Œ‰’ŽŠŠ—˜£¢†“• ‹Š‰Žƒˆ€ƒ‡…¥…‹²˜œ’”—¡ ž™’›§²¸¬¥½ÂÇÍÈÆÏÌÐÌÎ×ÏÑÔ®ÖÕØÚØÚÚ×ÖÙڝlyqccZZUQUVC@IC??>:48:;7:;:3<<?=>7;9:1:G=:27=@50677255?65;55858:57735HR7GOK994=EJB>1FCLA98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:;@;BQKKSYPTcbxlb~‘ƒonx‹xz{}‡||w†…€sp…‚{uwvt…ƒ…}’¦¢Ÿ¦¢—Š”—‹Š¨—rŠ²„¨’„™”…šŒ£– ˜“‰›ž¢“©° ‘•‘ŽŽˆ–Œo·„šÄȲœ¢¦œœ˜–‘±d¤ÍǕŽ†‡‰’“•Š…ŠŠ†–™›”“‡•˜„€‹™ˆŽ«——¤£ˆ™ž–šˆ‡—˜Š…‡¥ˆ“¨™—“–˜¡˜Ÿ™“œš¢²´¥£¼Á¾ÇÆÅÉÈÉÂÊÓÌÍÔ¨ÒÑÖÖÖØÚÔÓÚÎo{d`[[[MHSYBAGD;B>837;<:9>64::<:72?:929I:>67BC32:96264>=4;>6949;57944KQ<JQK9A7BGI@64JELF>;88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBc‚GvŽ}|m~ˆxz~{‚‚ƒwvƒ|mo‹{}xx|„‡Š~‹¢³§£«³¢—§Ÿ¥¤–•®¢ƒ‘¸•’³šŒ¡¡Œ¥›°£¤˜‘§–¨™¬¯¤˜•–•‹˜š—¡ÀŽ£É¸«œ£¦­˜’›²…†¨¢œ˜…‰‰Ž•Œ‹“ˆ†‡‰“˜•Œ‹”“‡”˜†„‘œu‘™²•–¤¡‡œ™’‹Š—›‰‹–Ž†}Œ˜ž‰œšš“˜—Ÿ“ ”ž› ±®¢£·¾´ÅÇĽÃÃÀÆÍÊÉÓ¦ÎÌÓÒÑÖØÓÐغovrY^S]TNGIMDACD5>:77:?<<7=42669774>5;5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=88567=:JFDGMZ\YJf`;H„‹zzn…†z|„x†~px|~}osz~‚|x†‹‰†„’¦»¬¨±½°¥­³³¨£¢°¬Ššµ£¸¥•­¥—©­¸§¤£Ÿš©˜ª¤®°ªš™”–‘— ˜š»»®Ê¡j¶¸«°”™Ÿ£¬“—¾£^ª²ƒŠŠ”‡|ŽŽ}ƒ†Ž”•ˆˆ“–Œ•‹–˜“™´–•«Šœ”‘Ž‘’Œ˜›Š’ž‹‰–Ÿ¡”˜™’›˜ž”¡ ”œ¥¯¨¡¤³¸¬ÂÈĶº½¼ÅÇÇÂÑ ÆÉÍÍÅ×ÖÑËӟmweYWP[ONEC><BAB8@885?G=<5<35345454B49:BM:B;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPdHb`bpJ@‹Š~€s†‡}‚ˆuƒŠ‚n}|}pw‡wŽ‚‡|Œ†Œ™©ÂÀ¯½Æ»³´À½´­«³¶Œ¨²®­¾«›»¥§­¹¸«¦¦¢¢¤£©¯²±ªœ¥™›˜—Ÿ¢¦¥’¤º¯©À¼­®²¹¥¤¨~ˆ†œ­½°‚‹Œ‹ƒŽƒ‘zˆœ‰ˆ—‹•–”‘š—¨š±š‘¬œŽš’Ž•–—‘ ‘‰”›¤¬”–“œ“ ›˜Ÿ¡”šž§¦¤¢£°²¦ÁÆï°º·ÅÄÿͦÇÄÇĽÖÐÍÄʅpo^YW\XLJAKAFG?A@C;:4>A==5=6>333242A17@BN>G@CNCA=C=;86CC5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUN79GD?CF\eF`igZ]\“ŒŒ‰{‡Œ‡ƒŒu‡‘Šo~{‚q~{•z’””˜“–§³ÆÉ¿ÁÌÂùǽ»¯«¹»˜³·º²Á®¥À¤«¯¼½ª®«££ž§«®µ°ªœ «œ¡œ–Ÿ¯µ§‹£ºº¶Á¼¬©³¥¤¨”…Ž©Ä䂋‡ˆ„†•”yƒ‘‘¡ŒŒ”’Ž‰—Ÿ˜“™•—¦ ¯œŒ«œ–‘‘••Ž‘•’ ”†—Ÿ ²ž”™“Ÿ ˜¤žšŸ› ”˜ž¥¤¦¦¤¯­¥ÀÄ¶Éþ¶Ï²Ä¿Ä¼³ÑÊÈ´quiYUYgQLHBLKLJAA>DD<5AE;;3=8B332262A05IEN>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBeZMe\fTbk™–ŠŒˆ“†‰y‡”r€{x‡‚‚z¡–¨™š™º½ÇÈÉÁÒÉËÂ̽³­¼¾¨ºÀ¾»Ä·¬Á©¬³¼¾ª°ª¤¥¤¬®³­¶µ¡Ÿ¯Ÿ¥¢˜£³½ª›¨½Á¤¶¸¯¬”²¬¬¬—‡š©¦¥‘‚Œ“¥–ŠuŠ’y…Ž’ž ““Œ”£™–œ•”£žªž‘¥šŒ•–ˆ|•“’£š•Ÿ¢œµ¥ž–¤£¡¥¦˜•—š¤£©§¢²¬¨»À拾·Ì¿¹¯Ä³»¾Á¸¬ÂÃÂÀ—jv^UTYXJJLIFDDHCCADL:4DI:;4<8E.12242B26SHO<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQG7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>iH_XbZccVžœŽ—Žž’‰ŠŠ “„x…–~ˆŠ‘€–¡™®§¤˜Â½ÇÃÇÅÓÎÎÍ˼·°º¼´½Ë¼Ã¶·¼­³¿º½®¯¨ ©¨¶­®©²·šž­£§¡«·¸ª¥°¿Ä²½¹´¨«¶´®®—–¥¬¨Ÿ‘’²Å§–Ž|’•|‡’™ª™˜““’•“¤“™“¡£¢œ˜Ÿ˜‹ŒŽˆZ——’—¤™e˜¢Ÿ³¥•¡•««©¦›ž¦–˜–˜” ¤¨¥Ÿ¶«©¹»Ã´¥´µËÀ¸ª¶«²»¸®¨¸º½¸€hkWTRSMEIRMK?AHEEIHH95EM;>8=@J.32025C55OVN<LFKRLOHGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|gV;>@BFBpEjIReaLF¥”œ—¢—©–Œ‘ƒˆ¦“ˆ‚‡‚œ„ƒ•”š¢ž¯¾¯¡Æ¼ÄÄÆÆÎÏÎÒÊ¿»¶±º»»¾Ï¶Ä½¸¹·³±µ³¸³«§œ«¬¹ª©§¯°˜£¯¥§£¥µÀ°¬¬´¿ÃºÀº´§º¶¹´¯–¥­¯®¤‹“”¡tš}—™„Ž—™Œ±•›š•’’™™¥£• ›—š©›  ™Š•œ`J–œš”š¥–T–¯Ÿ¯œŸ¤”®­ª¤š ¥““˜˜œ §¢š´¨ª³»»»ª±²ÇÀ¹¦¬«­²²£¡²²´¤mjbYWMOJDOOPR;GKIGICC>:KU?A:=EM07544:B44MWO;JKOUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@BAF3>58JKCA=C;4EA:A?>H@5*B52,>c]g:35tde@R7&#3}hW;:BC@=QEWSsbWFHª–™ ¢¨¯™‘—‡‹¨–Žˆ“… ‡„—¡š£¤µÉµ©Å¹ÂÃÈÊÉÈÍÍÆ¿»³®¹¹ÁÁ̵ǺÁ¹µº°¯¯³µ§¤›ª´´ª©¦­¬š¤®¥¤¨¬»¿¨¬¶·¿Á¿¾¹³²Ä²¹¾­£¯µ¬¹¦ˆ›—¦›v¿Ÿ„™Ž“ššŒ®—¡œœ—”› ¡¨ž¨Ÿ™šªš¡§ž˜‘ƒnv’¢š•¢‘®²£ª”¨ª—©­£¢ž¤§‘‘™œ‡”¢ž–±¦©«¹¶½²²®¾¹¶ £§¨¥¦œ›­©©‹`b^]NJKFGMJVL=MENKLBCD<QV=AABDO18=76?B75UXO?HNQYSPQUKQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW;:=.-R`MUH~e^HE«•›¢Ÿ»¯™” Œ“«›‘’“‰«†¡žŒ£­”££¶Æ¾´À¹ÂÂÇÉÅÂÍȾ¹²¯¹´ÀÂʵƲ¼µºª¨­­°££˜ª´»¦©¦«ª©¯§£ª«½»¨­½µ¸¾Ç¼·¶¸Â²¾Áµªµ·«¾¥£˜’¢ ¼Ÿ‰š ™—Ÿž·Ÿ©œ¥¢›œ¡š¨¤³ ›¦œ¨ªž˜•”›‹–‰Œ¤¡”¢ ´¯¥¤’¯«™ªªœœ£¢¨””Ÿ‚žž›•©¤¡¡³´º´­¨µ²³žœ£¥š—•˜ª¡žu]Z][HGEFLQIMEGGBSLJBEGAVSCH=AGQ1;B7:BF79\YKALPTUSMWRNUJE@JJNO9C@5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*BdT49-19f\FCCpbGE§—£ŸžÃ­œ—¥˜šªœ–ššª–•§¦•­¬˜¢«¶Ãü¾¶ÁÂÀÇÄ¿ÍÆ»½¹²°¹³¿Âǵ¿°¼·¹¶¦¤««­ ¡™ªªÄ¢¤©¬¦ž¬¯«¢©©¾¸§­¿²¸·Ç¶µ¹¸À³À¸µ³´¯¾£—£—”œ”®Ÿ¢£¥££ ½¥©©«¡›¥ž½¡™£Ÿ¢©¬¡—•ž“ž‡„“Ÿ¤ žµ¬¦œ•°¦™¯¥œ™¨œžŒ˜”žƒŽ ™›’¥¤š—«±µ±ª¥ª®¬›˜  ’•¨ž”e_W_[MHGJNLHEDIA>QIA<GII\ROK=HOU4BF9>HG5Ca[KBNRUWVQXTRUI@8RQPM:GA4CHQSIC;C>GVKC@O>K<06;GF>;FA56?9:?9;15D0-,/Mv\4KZ5,MnW<-=)#zbQ5CKQ9mRF<KxeaVK¢š£œžÅ¬¡ž¬Ÿž® ’£Ÿ–¤ ¦©¬˜¶±¢ª³¶ÅĽ¿µÀ»È¾Êǵ¸µ´±³´·ÁŶ¾±¸µ¹´Ÿ§¬ª¬žž¥¤Á¥Ÿª­ ¤©­¯¡¦¨½µ¦±½¹·¶Ä²´¸º¿´ÄÁ¹¹¯³µµ£¥•’”¡® ™¢ž©¨¬£šÂ¬©ž¬®››ž™¦ ½¡¤˜«¬¬¦¢ššŸ’ž‰ŽW–Ÿ¥¡ ¸ª§“˜´¢ž±Ÿž™®•˜“œŽŸ—•¡£•¥­²ª©¢¢¥¥••˜‹‘’¤ž‰_bXb_KGJJNFEAGK?=JB99JKN^QQI=LV\9FI=DMI8Hb\LCLPSYYVWOZ^IA=WQIK?H?5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+w`S6SZkWrGE6=ue\KMžž¡™ŸÄ¨¥¡´¢³§“«¥ £Ÿ¬©¬»°¨¬¶±ÇÅÁ²ÃýÆļÄɼ¯°¶­°´¯¾Ä´¹±°º´¬™¨±©ªš¥¡§Â­›¬±›ª£®°©¥©¼¶§·»¾¯·Ä­³³ÃÀ´Ç´»¸¬´¶­ª¢¦–••¤¬¢Ÿ ›§ª°¯¯»±¦ ©©š™˜“¢£¸ ¡£’¯°¬¥§Ÿ’¡ž•ž•ž›¢ž§´§¦Œ—²›¢­™œš¬’•’™‘ •ŽŸ “‹¦«¯¤¦¢œ ž‘‘š“…‹‘›_cYfdIHLJSBC@IH;;F?99ONV^RSJ>O^]=HPBLLI9Mc\LELRTY[SUO\bHA?ZQAHAKB7FELKM?;BHDNB=;N@A3/97CB97F;+6<46<25-/4@1+'VtSeO?104b[M23>0<v]^?[T^eq@8;H–weA4ž£Ÿœ Ã©¤ª³¢¤µª–³¬§¡¤²¬®©»²­±µ´ÆÀÄ´ÀľÉĵ¿ÈÁ´«µ¨¯¸¬¿Ã³·®­¶¸¥˜ª²««˜Ÿ¦—­»´›¨°š¬ ­´²¨«¹²¨º´¹³¸Àª·²Ä½µÇ¨¿¯®¶µ©§¬¡˜—’¦¥¢¢˜˜¥®¸®²µ¶ Ÿ©¤š•–”¤ ·¢¥¥–¯²²§ª¦¢žšš›•—¨Ÿ ˜¡ž¯²¢¦Œ—­˜¤«–˜¢šŒ’–˜…•ž“‹›“Š¨©ª¡§¡˜ž•‹Ž™…”ˆ“žwbg[jiLONNT>CANC::I?77RO]_RVQAW`\BJSHVKH:Td\NFON[W[RPQX]GAB[PBG>NC9HGHOP??CIBLB<2IA94177B>;7E7+6914801-/.<6-#Bqgsk23/1[bZ33806p[bH05IohUCWFŒyfC;££¡¦¿§§¯±¢©¶«žº±¬£«´¶±°¹·°·¸¸Ä½Ãǽ½ÄÂÆÀ¸ÀÆÀ¹©¶¤¬»­ÀÁ··ª­²º¢”­±­²–¤§‘ª¹ªŸ¦°œ« ¯´³«©¶¶­¼­´³¹·¬¸±Ã»¿¿¦Ä«±·¯¨««§ž˜™«¡¢¡‘˜¡±¯³¬°¹š›© š—“˜§ ¶©¦£¢±±´¬³¨¬Ÿœ  ›ž¥œ¢—£³¯›Ÿ“¤™Ÿ¨™“¡“–ˆ“–’•–œ’ˆš˜”Ž©¨¦Ÿ£œ—›’…Ž™‹}‹•„™igk`lmWPQ[UABET@;;IA7:XPd^PWWEY_^MLRN^KJ>Yc^NHPO\UYPKTWZI?DXPDF?N@=IGGQPB=DFBM?:1D?77547?=95E4+75/251--.,1=*'+=\p=>1.0dZd@1647gY`F(?8l}g[V;‰{cC=§Ÿ¢©½¢ª°¬¤²¹ª¦¶´¬ ­µ½¯³¸»º¾·¶À¿ÉĹÄÂÀ¿·Ã½À·®µ§«·±»½¾´©®±¶ž–«®§®—¦¨Ž§»Ÿ¥¬³ž«¢±°³¬©¶´µ¾®±²µ¬°´³Á»Æ·¬½°±¸¬¬ª£²¦ž¥ª ¤—‘šŸ³ª³««³š§œš•Ž¡¦¤´®¨¡­®®±¨´­²ª¤œŸ¨¤ž•¢™›¨µ©—™’’™Ÿªœ•–„”–Š˜›“Š––š–¦¥£Ÿ–•—’”…{’‚‹•dkqfoq^FYgVDBMXDZ9HB6>]Qh\OY]G[^]OMRXdJJB\b_PLMNXWXPJVVWL=EUJEDAM@AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,,%2+*5K1/'__`U150=`V^8)C3YU\gK6ŒzfL@¤š¡¥­·¥¬ª¦¯®·ª¯µ»§¦±·Å·±¶½ÁõµºÄ¾ÌƹÃÀ¹¾¹Ã¸À¸²´«©º¶º¹¾´©­°µ—˜§¬©¬›««Ž«¾ž¬®²£« ±®³®­µ²¹¸ª®®±¨µ¯µ»¼Ê³ª·µ±´¯®¦¡´ ›¨­ ¦––›š²£­ ¦¯—¡¤šš“Ž£¥¨³ª¡¦³­ªµ¥¯²µ¯¤™¬§š˜Ÿš™«·£—“Ž—œ —–“ªžš‘’—Œ›˜•Š”’ž™¥¢¢ ˜–’“•z‹…{ŒŠ‚Š‘jmwmu{aFakYIGZZ={JFD6AbTi[M\aK\]ZRRRb`LKE_``QLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T_T_/5(C_Q\.+B/JGP[G3cYTKD™—¡±©²ª¬¦¤¯®¶©·µº¤¬´·É»´»º¿¿´³·ÃÀÌȼü¶½¾¿·¾¼±¼­§º¹·µÂ¶ª­±·”–¦®«¨£°©”¯»¤­±³§¨£²µ±±°µ±¸´©¯¬²§·¯·´ÄÆ·©¶¶¬°­©§£¶  §±¡¤•œš•±ž§œ ªŽ©£ž›–˜¦¦¥¸¨£²µ¬¨±§®±µ¬¥™ ¬¨›œžœ”©¸œ”ŽŽŠ—›¢——¤ œ“‚”œ›—–•ˆ–˜š§œ¤ ‘–‘•v„‡{„ƒ‹Šlovt{~\Lfm\JNc\>b{GI8GgWf\L^bMXYWUWTi]OOH`]_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANGf27'GbLV%-B.=ELQ<3rkICC‘™¥¯¥®¯«¨¥±³´«·²¸¡«µ¹É¹­Á»Â¸³±µÂÂÎÅÀÁ½´½¿¾º¾¼²Ã§©¹°µµ¿¼®¬²±› §±­¦¦¯¥²µ­«±²¬©¨µ»¬´²µ­´­ª¬¨¬©¸­²°ÈÀ¹¥º°©¬¬¥¨®±¦¥£¯¤©œž›°š££££‘­Ÿ¤  ¢«¦§¹¥¬¶¶¥«¬©­°¶®¢ž£©ª› ››’¤´™ŽŠ‡¡ ”Œ”œŸ’ƒ’’œš—•”‡—’•™§›ŸžŒ’‘v}…|{|…ˆˆprq}|}\Sdo^NXf\FD–[G;NmXb[L`bNVWVWTXg]QRLcY[TKGOTSNGIVS\N;P^IBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/+1()+,-*&5*/&0)38:1&*3Bc:6*HeHJ+:H>3BHS,>k;GHœª«¢ª±¤©¥³µ²µ¶²²¡«®½Ìº­ÀºÇ±´­´ÁÃÑÅƾÀ²¾À»¾·»Ä¦¬¶«²·»À¯«±¬Ÿ£§­©¨¤°£ª²ª°¬°¯°®«³½§¶°²©³ª«¥¥£­º­ª²Ãº¶­»©©§¬©§±¥ª¤£®ª¨¢Ÿœ£­•¥ž˜ž™¬¢§©¢­¦¤­«¸³²¢ª¢ ¬¯±¬ž §§©™£™™ ¦—†„ŽŠ‹ž ŽŠŒ•šŽ„…”Ÿœ”—•†–”“—¤›œœŠ’‰~‡…|v~…ƒ…rqpˆuk_Z`nbQrp\K;„|F?XuX`ZNd[NVVUWQ\a^SONgXWVKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*25>10485(5/*,.30;),,'%234$,2-860)(1;\J0.JgDF8;B05EKX1@•Y=LE•˜­¨¢«³œªª°·­¸¶¯«¦««½É¼°½¶Â¯±«³ÃÃÎÏþ¿´ÀÁù¿³Çꮶ­²¸¾¾²­­ª¤§ª°¨§¨±¥´®«±¯®²±´¬´¼¤·³¬¬¯¨«Ÿ£ž°·«ª­º·¥·¶¤ª§«ªª­¡©§¦±²¤§¥¡¡¬—ª¡•› ¦ž¥¢«¤­£Ÿ§±¸®®¤¦£›ª«®©¢¥¤¤˜Ÿ›–˜œ’‚‰„œŸ‹ŠŽ‹˜Ž‰‚‹—¢››Œ“’‘“£™›™ŠŽ‹‹}†ƒzs‚|ru‹¤‡xk_`nfWd†cN?g“LEbyWbXReTMVUVTO\]aUKNhVVVIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*39?./463)4+*,+.#4.-+&(+79*&6+<-2,&06VZ.0JgAA<<B+:JO^4D†=GFD—“°¦£«±˜«ª­¶¬¶²¬¦¬ª©¼ÀÀ·¸²»µ¥²¯ÃÉËÑ¿À»¹¿¾Á¸Á¹ÀĬ±´±³º¿½²°®¬ª«¨¶©¦®¯ª¹°¨²²¯³­·ª¸¸¦´¶«¬¥©ªœ£ž³³©¨¤´´ ·® ª¨ª¨«§ «¬©¹µªª©©¢ª ­›’ª¡ ¥¢¦£ªŸ§´¯©§«££˜¥§§ªœ¢¤£ ™˜ ‘Ž˜~‡‡„†ƒ‰‰ŽŽ‹‚…”¢šš‘’‘“Ÿ—˜–ŒŠƒt†€xt‚~xv}€‡orgfpw\`r‡jO^™VHnyUdVQcOMVTUPOX[bUHOiTVSGPYUI>IHOQPxLMV=<KD?@A<@CUC9AK=5;E13;:7*4:=+-341*8**+*,))(/*&)%3;,$2)2021%/2Qb02?f=NX>C,>LT_/Ji5OD<–Ž±¢¦«¯š¬¥­°´µ°¬¦°ª¨º¾»À°­¹®¡¶¯ÈÇÈÑÀ¾½»»Á½ºÂ¿¾¿­±±±µ¼»Â±±³ª³©¤´¨¥­³³¹°£®¸²°³»¬º°ª®¶¬ªŸª¬Ÿ£ ¶­©¡Ÿ°³¢µªž¨§©£ª¡¢¬­¨½¯¬®­¢¨¨Ÿ¬™°¡˜¢¡¨¨Ÿ¨œ™ª±ª£ ®¢¡”£££§˜š¨¥˜—˜žŠ‡”ˆ}†„„£–„Š†ŽŒƒƒ“Ÿ–ˆ‘œ“‘‘œ”—Š††wt|uxyyrrxf†¤vi_di€tfˆ‹|SXo^JxsSdSQ^MMRZfNMVYdXGRhRQ?BNQaQ:IHLSIqQLS;<I?;<=;@@W<<?H73CB15:93-5::)-31--5)(+-,42#2)',%.;.&1.0-14%,0Lg:48_=ad?F1CP[[*HM9U@4‘³¡¥§­¤§¤­§µ³²«¥±§ª¸¾À»¯§¹ª¦¯±ÉÇÈÑü¿¾¸½¾¼ÈºÀ·¯¯³±¹»¸À²²º¬¸¬¢´§¨¬²¶¹³¨¨½¶®·¾°¾§­¬µ¬­œ©¯£ ¥­«¨œž«³¥´¨š«§©£¨£©¨©¾«´°®ª¤¡¯œ›³£–¤œ¥¦ ¥œ›©«¦Ÿœ«¢œ“œ¢¥ž˜—¨©’˜š”Š‚…~ƒ€ˆ…~}‹‡‘ƒ“š“…“¡Œ”‘‹‘›’•‡‰~r{z~|hx|ysno{f„x„‰dag`r„zlfx]^T?W{mTbPQXKLNru]HZ[gYEUePD>JODCA9HGKS?jbJQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11'/>KH0%90%,,09/,,+6'17#-0GjI14X=fbAJ7GS`U*=9DW=*•²š  ª¦¥¡«¥¸³³¦©±¦¬¸Á½µ¯¢¸­¨¨°ÂÉÉÌÁ¶½À´·¿ºÈµÂ´²²´±¼¸¹½µ­¹µ¾­ ³§««°¶¸µ¬Ÿ¾½ª³Á´¼¡¯³µª¬Ÿ­°£œ¦©ª¤ž›¥°§° Ÿ«©§¡©œ¤¨¡­¼¨®±®¡«£¤¯žŸ­¦—Ÿ›¡¤Ÿœš¤«£œ›¥¥–—• £—›—¥¬Œž‘‘‘‹‚Š€€Ž€{™”Œˆ{}‹†‹‰„’˜†”£‰“’‡‘š“ˆ}yk~vyxc|zpnoqvgsi„heg^lsl`io`o=ZylU^NPQJIMTZWM]^lWDW_O^PHMDF;7HEKO<rhKK9AE;;==;;=J49B<3;G<4?18-68;2(09/,4/.=-*K>)49&'.34.0+/4&,:$41AhY14S=e_DL6KVdO*;1NW=#”™­š¡˜¨¥¤ ¨¤¸°¯¤¯°©«¸Á¹²­Ÿ¹¯«¨´ºÈËÈ¿¶Â¾¯´½·Ä¶Â±­¹±³À´º½·¨¹¸½ª£´¨©ª±®¹±«œ¼½¥°Á¶·¢¯¶µ§¦§°³Ÿž¤¦¨¢¥™Ÿ¬¨©ž «®¦ ¦˜£¨ ±¹Ÿ£±¯¡¬¡­¤œ§¦©šš›Ÿ¥–›žª§—œ¡ª“™”™Ÿ“™–¡©‘š‰Ž†|‡~‚}| Œˆx‚‹„‰‹‹…‡“šŽ‰•žˆ‘•‚‹–‘|…|sp}qtt`zxhmoomh}qb{mieb\d„~^YsjqJIiXZMPLJHPRQIO]_nSDXZRhOHKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23.:;83&2<0,85B*)-B*,4;NN@;73-.+-7**<%53<fd24M?e]FO=QZgH*>/WU5(—ž§š—­¡¡¡¥¡¸«²¥´´©¨¹Äµ²­Ÿ·­®­°´ÆÈÀ¶¾Á¹°´¼¶¾»¾¯ª½°´¿°¼Ã¹¨»º·§§µ©¨¬±­´±¨œ¿¸¦®½·²Ÿ±·°©¥§¯±›¡¤ ¥¥ —›°§¡ž£¨¯¡Ÿ¡“¤¤¢·°¡¦±«Ÿ¬£¯˜œª¤©Ÿ—šž¥”››ž§«šœž¦—–˜–žŽ“—¢¨¢‰‹†z„~„Šz–‰†x‡ƒ‡‹…“˜–™Š—~†—Œyzprwoot_ywdjkjgg‚lerkkdgWar^YkuiYE}^[XOOKHHRUG2:_^mPDWUYeMHJEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<#8R=*113>D5,-'42+;+139cl84HBf[HTCT]hE.;1^Q,2–¤£˜–ªž¦¡£¡¸ª°¡»¸¥¬½Ä²¯®¢µ¯­­¯´ÄĽ³¾º·°³¹¸º¸º­­¿³´¸®¿Á·«½º´¥¢³«¨ª³¬®²¤Ã·¦ª¸·¬Ÿ²¼ª§¥¨¯«™£§œ¥¦”˜¡³¦™ž¥©©œ¡Ÿ”¥Ÿ¤¹¨¤§­¦ž¥¡©“Ÿ©¡¡¡™›ž¡“›—¡£¬œœ›£–“•–›Ž““£§¤ˆŠŽ†y„|…†}œ‰Š†x€ƒ‡ˆ‡‘…”“’Œ‘•”Ž”{ƒ—Šw|lurmlsbytgfifcm„fghdfgh]dbieZezb`PsT[[SKIGIOS@ *j^jLCVU^`KHGEC.:B<F<6KPD8:D357==895?:;4>8@L=>93)8><:9*6@3.E4(+,>0-N?.+-7-1195,&.5-80576`tB3CDh[KWGU`hB377aL'2Ÿ¤¥“¦§œŸžž¤¶­¨ªº·§¬ÃÀ¶¯¬¢µ®§¯¯·ÁÀ½±Á·°®²¶µ¹¸µ¬ª¼³¯²±½À·®¼¼±¤Ÿ¶¬¦¦µª«¯¡ Å¬ª¨²µ¬­µºž¨ª«±¥˜ªž§¥’™¥­£˜¤ª¡›¡œ— §¶¥¯ª­¡¡ž¢• ¦Ÿ¢ ™œ›œ“šž•¦Ÿ®£˜˜Ÿ–•Ž•˜Œ˜š§ ‡ŠŠˆx…w‚‚‚œ‡Š‚ˆ{~…ˆ†„„–•‘‘’{ƒ•Ž…s}gyplklguskagcbsacefehhaenY]X\lcaLgW[`VIGHKMRX>9`liHBUS\[IHFEA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A<-5B37=++,/A*JK./*+3722(57$+7.72685\yN2>HiZLZJVbfA:3@bF%5¤¡’®¡š™ —¥´²£²¾·¡±Æ¼¹°°£¶¬«¯©¹¾½»­À²¯¯®¶®³¹²§«¹±¯®³¶»¶¯¹¾¬¥žµ« ¢²¥«°Ÿ¦Å¡³¦°³°·®µž¬¯¬®¢™§ª¥ž•›§¦ ™¥£©œšŸ›•­°¦¹§®¢¡ššž™Ÿ£š¥—Ÿ˜›•š¡“ª—­©œ•ž”•šŽ•”˜§§ŒŠ‰Ž{t‚‚‹˜…†|ˆˆ„…ŠŒˆ’…”œ’‘‘—Ž‚o‚gynhljgqrk[hcar`dgjnkeiecl\llupaSbhceZIGLMOYQPUaeT@VRZTFGFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.4<;K6/.+,-24:5#3*)6.55465Z|]1:Kj[M[KXdc@A1HbB'4”£œ±œ”¡›©³°Ÿ¸À¶ ´Â»½¹±¦¶°©®¥¸º¸¸¬»°­««·ªµ¹­¤²µ±¯©±¶¶±³¶»§© ¶ªž ª£ª®¬Ä™¯¦°±·¶­¬ž±­¯ª¢›¤¬©›•œ¦¤šª£¥–š œ’œ£«ª©ºž¦¤ —ššž¡k£–™qƒ—œ¥v’¬©Ÿ–—¢’Š˜™€—ŠŸŽx…’ƒmi~w„ql†Š†}„Š†o]d`g„˜†k‹”’ux‹„ƒfˆ€hvifX\itnNPjcfqƒf]dfnkh][]‰…‡hNKC8ETg^JHPPUVKHRapteF[QUPFGFC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,,08>G701.*.*/668,#1'214:276Xl15Ok[N[K[fb>G1Na<+/Ž¤šˆ–²›”¡œª®¬£½Å¯©·Â¸¾¼­§·±¦«¤¸´³³°¹®ª§¬´¥±µ¢§¸¶µ¨§­¶³®´®´¢©Ÿ´«ž£¥§¨›°¿•¨§±´¹­®¤¨­««¥¡Ÿœ¡¨§›˜¡¥¦œœ§¨“ž ™Ÿ¨ª£´¯£¢£œ–˜™—£ˆ¡’šˆ¡ˆ•Ÿ¢¥€¨­Ÿ””ž”‰„rxŒŽƒˆ u‡i—‰f~sx o‡‡„~Œ|¡ Ÿ™|ˆžtˆŽv›Šl‡‚ƒmhdd{mrbT†mcmi˜qXipn†W]hZkjZˆplyr‡h‡„Y^FN>F^MERVVQPRWTg^LZLRRPEFG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82*/1<I:/01.*/(-4583%&2115>1<8Xƒt15Rk[N[L[g_=K1T^7/(§˜„¬ššŸ«ª¨ª¾Ã®²º¼·Á¿ª¤¸±ª¬¦³µ®¯³¶«©¥±­¥¶³›¬µ¶´¦§¨³±­²¨®ž«¡³ª ¥¥›¢¥ž±¸•¦§§·¾¦¬§©ª¬§¥¡Ÿ™¡¨£™™§£¤˜œ¥ª–“£œ”“¤¦¦¡¶¤£Ÿ£˜•”˜”œˆ®˜•ŠªŒ™£†±¥®Ÿ•›¡—z‚Ô¨‡”À›Æxw±¥·–d€Àœ¿y„„yƒ|‘Êq–¼œÅ{r¶§º{l—±«±yhlX±®oei¼’¼nhzmqØ}Rkb¶²}p”uš¡ªVNXaOVNFU\XPPS‹[W[P@\DPNCFI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22BE/.32.+/)-/186- /416A1=:Wƒw11Tk\O[M]g\>L1Z[41!§”¨ªŸ˜ž¥­²ª°Â½²µÀµ¸¿Â«¦´®®©¨°µª¯¶´¨¨¦µ¥¨¹®œ²²¶ª¥¤§²¯®±¦«ž§¥³¥¢¢ —œ¢ ²¯–Ÿ¤¡µº£ª¨¡­­¤¢šš£© ˜œ© Ÿ—ž¨¨‘œ§›”ž¢§£¡°£žŸ£–—“˜’™…¯kj‹Žªh…–‡­fqŸž•›©—q®¡¤~wº|k v±_j´[¥€eœ`fzfixj©e¾rg¦Œv±j|±xu‘”cmm§n\„ Eig‡–Euœ`}f{£¦X_‹«h}xzj¨8J¯[XTmcZKOX_\VV;N‡PWV/ISSJCEF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3/.53/+/(.0.:6/'$203B/=;U‚v2-Vj\OYL_gY:M5^X31’¢•ƒ­§¦Ÿ£¥«²¸­´½¾°·Å²¸»Ã§©°¬°©ª±¯¤°º°¥¥¯³£ª¹©²²°£¥¡ª­°¬¯¦¨ £¢±œ¤ž™–™ž°©˜œ¢ µ³¡«›¡­­Ÿ™—¡£©™ž¥ œ™¡§¤£š—¡ ¬Ÿ¦¦ šŸ¡–•‘—‘š†µ›µy†©š¶™w‡³›·”—˜¬—k¦z…†‘”’w«gj±[¬{Ž‡”t‰pŽ†€ˆ—xƒ‚Š—Œƒ …°vwŸqkkm|‹O¥XHcc™~ch¥_yquR’†]P©ncp{…€a/R¢n[Tkg`LK\dX\ZB>°wWXA#MiFBDA@A19>88:84;:9<9:A:E::;6:CB8=?KNH:5:AFBAAD<FD;0201;F,0.840,.(/3,>831/2-D1<<S}n3+Xj\OXM_fW7J9aT50— ”‰³¦¦¡®©¨³¬ª»¶Â°¼Ã­¹·Â«­­¯¯¨¯³ª¢¯¼«¢¨¶­¤¬µ¤¥²³¨£¢§ª³©°¨¦Ÿ  °— ›––—› °¤œ›¤¨µ¯¡¨©§ª›–˜¡¦©šŸ£ œ £¥£–›ž˜šž£«œ¦šœš¢ –“’”“„Õ“™¹q±ÂƇ}֔œ»}œ—¨’Ž¤{†¢¥‚y«yV¯{‰~Ÿj¹Z¹w†„}¦‚”|™zªyŽ{±mŽ„t»†o•P¯§ÅŠQ zc`ªbsr†k–‡^Rµ´È…~ˆ|c¤3Bu]PjhdP@XfYdaJGLjJZSOYfZCC?E?0<<59<74<;8=:<C:F:;>6:@C;6@OLH<:<DHCBCD<EF81211DB./0483+-).323971#%5*>3==Qwj6*Yi[J[P_fT7H:aP72%œ£“™±¨©¥³ª¥µ¨¤¼·Á°ºÀ²·µ½´¶¨²±¤²³§ ¯¶©›¨º®¤°±¡²´±¡¤žž¨©±©´©¦œžŸ¬˜™™˜˜–˜£®Ÿœ—¨­±©£ž¬¢§•—œ¡¦¡˜¢¡¢¡›¢¢¨œŸ ž”™›§¡œ§•››Ÿ ˜’•ˆ²nhµr¬ˆp§r´ut¶{œ™¦Ž£~ž£~°u‚ÒÒu\®|…¤n›ª¦j†…}­}˜™{±s“y³e–t…žnŸf”RɋZÂ\Ÿyb_­_vs…a–ˆ]YʝoÀ€tMKµSUÆdUQjceXAOj_liPUFH9=WR[VYHB?J<2?;5=<56>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>II:1746@>/.24252-).26,742&60;5:=Pqh9'Wi\ANT_eP5G=aM62.£ž‘¥¯­¥©»­¦µ¥§¶»¼²»¿¸·µ¼¼´¦µµ£³²£ ¬°¥˜§»®¥²±´¸ª ¥¡ª¥²¨¬ª¥š›ªŸ––™™“”¤«¢˜“¦«±¦¡•’«Ÿ¥’”¡œ¥§ •›¦§¢›£Ÿ®š žž–œ£Ÿ¥”•™¢ž•™–“›…¬|x¨w£‹‡ªp®‹„¨„šš£‹“š‹¢}’—‡®„³\r²S¯}‚‚£~q×}w„~†™šw¯†Š‘œˆw´ašeš‚•l’[°WKšu˜yf`­^vv†g—ˆj]¯w•Ÿwl5yÈ®³_CTo^g`EPl_pmVUM.echRYP;AD@L:5?91><16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK97<46:>/04333.2..18*.32%!03767=Pke>&Vg\@=V_cN6GB`I:77 ” ·±™³Á­¨²§ª²º¸´¹¾¹¸³·¾¶¦¹µ¡¶®  ©¬Ÿ•¨¶¬¨±²«­´¤›©  ¨¢µ§¦ª¤šž–¥¢””š’–¤¨œ”§­°¥ ”™¨Ÿ¢‘¢š©¦¡•š¦©ž¤Ÿ­  ”ŸœŸ¡™˜œ–—¡ ”˜‘§ž‡©~¦y¡„ªp­ƒ§†—¡£Š˜—ˆ£†”ªz‹yp±Z¨ƒ‚ˆ xtØv‡t§Ž›’¤|•Ÿ„{²^œd }‚•n“\«\[“‘hgªcr{€j˜†q]«Z‰ kndOJC¡\ZMt]bfMZa_rt_JU5Jš‘XHE=GEAL35A8.;>05A78@<6=<F?:<6?=B7.HVJE@H6KIN@IK@EN::@4.;>002154+*05/7,&21($$6671<OedA&Uf[?1T_bL7FH_C1=7¢šš¾­˜³Á®«¬¨¦´°¸±µ¿¹º³²¹¼ª»¶¡²¥Ÿ¦§§ž“«²©°ª¶­ª¯¡˜¢ ¦¤¤º££¬¡—œ’£ –•Ÿ›•™¡¡‘ŽŒ©°°¦–š§¦Ÿ’¤˜¨«¨•˜©¨ŸŸ ¤­£ ž¡Ž•¡™  ’œ—œ•¡•—¬œ®nr´t©Œw‹¦t´zu´‚”§¤“‰¤‡Žu¸n‹{‹¢kk¶Z¡†e——h ¢§m”r´s“™³j…’ˆ­ju´af¢n†’k—\­`N¡|‡‘Rs£ly~n˜†o\¯V<œweTon.[§ObRkeblYb\`p|cSYQ>?lo2BB@>M:!7@6.;@37C58??3;<CDBJFMIF62JTKEBJ6IJP?HOCFP=<E50;;010/75,+,326/#00,,289/9N`eD'UdY>/U^aL5FM^81A8¥šœžº£œ±À®®««§·©¸¯µÁµ½²±»¸¬Â·ª¬¡§¤¢’««¨¶£³¨®ª¡—¨ ¥«¸£®œ–™¦£—Žž¡œ™žŸ‘“•«¶°¦˜“›¬©–Œ“¦š¥­£‘—«²¤ ž¨¬°˜¡¢™¡— ›–›—¡“œ©”«™‡Ô”š»u±Ä€Ä‡~֗œ¸yŠ’™Ž˜ŠŒ§‡y¢¶u}wv‚š²aƒºyÀ|u¸bµŒ‡©}–‚¬©q{u¼ˆ§ ia¦Ž¯¡~Œt‡«}¾ns¼t²ƒuxŠmšˆpm¤t½]w}[ay¼jZV[iy^i`dfbmyoX[YCA@q?CG+4H"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,;:08LXaF'TcX</T^`K5<L[-6@9§šŸ¢¼£—°Ã¯­ªª¬±¨¹¯·Å±»³¯¼°®Á²­¦£Ÿ¤¢œœ‘«¥ª²¥µ§­¤Ÿ–š«™§­¸£®™•¡¦ “Ž£Ÿ™Ÿš–“¯¹±«•–£§¦”–¥¤­Ÿ‘ ¨«ŸœŸ©¤²¢¤Ž¦¡•¡™›–•¤™° ’•ªŸ…™¶€’’¸–xƒ“›¶wnlotoy„Ž‰ržÀ»¼š{²¨p€t‘¹ƒ|††Š‡{‹†—}¤»¹½œuy³£tv—ut°u˜žf†i¶trqw¶Œ^y}ˆgƒylyb‹¬pt…~X[§iDdYTf_c]cQgfqmuBMOLD;ZL>J3<0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITBKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7KT_G'SbW8*O]]=+;VV'=:<¦¡¡¿¦•²Â³«ª¨¬«ª»¯±Æ¯µ´°¸§µ¹®«¤¢§Ÿ ™”­¥®ª§¶¨¨Ÿœ–¡¤ž¬¥¾§¡ª—•œ‘¢›’¢¨¢“ž—’˜”²µ¶¬˜£¤¢‹“’¦œ¦«–©¥¦œ›¡©§§¢¨ ‘¬ž—¢ž—–˜ž°©”œ§¢kjœ©y‰t›v{fˆ{½¾Àºo’ƒq”…_rjZ^›‰ac‡–l`”cmœvb•k€š•”e^`cqš‰hrŒ|†”fj~ptx~}b[xthP\n„||‹jWlzrIJo…pNrMDV\f`LZWfc_OZmvjrRODDM<HI<L>2,2A?8/5?C<9;@;=C>RVVWYZ[[\]`aaa`\UG5CFUEJOHFPIIH;8=51:.1;:./-76=5&"/*2,%;8-7IR_I'S_V4)P^L(3>\O'?2>¨Ÿ¨¡Á¤™´¹¶£¬¦®§¨µ²¬È¬°´­¶¤¾²³¨¡¤ªž£œšš¬§®¤¥µª¤›˜•¢œ§­©¾¨©¥•”›– š“™¦©¨‘Ÿ˜œ°²¾¬š¦§¢‰“’©›¨¤œœ¬Ÿ£šœ£§­¢Ÿ©¡™®›”¦ —”žŸ˜±¥™¢¨™’Ÿ¤¦›¨¤›šœ›‘—‚hn}rw‘—”„‰´ª…˜•ŠŒ˜—ˆ”•‰ƒ““‰’”™“™—šŸ¡š›”Ÿ›‚z¤…li{}€u‰‹‚r‚xyvvŠ€|‰jstƒudw}vkoyl_b[ogMXYfj_WYpzomfSOFS9PZNRO(+:KB635=@A9:C><ENSSTVWXZZ\]`bba_^^[TKCSGKNDGPLOI<:;489,2;820)6IRO8")+/2#4;*7FO[J'R^T10T^:+=8]K,<-@² ³¢¿¢£°±· ª¦³§¥°µªÉ«­²¦µ¦À©´¡Ÿ¥¦œ¥––¡«§­£¤·¬ ™—– ˜­ª¦ÁŸ¬¤–’œ—Ÿ˜”•£Ÿž£¨“˜¨¨²Ã¯™ªœªž––©ž«œž¡­˜¡›¢¥¯¦¡¤§ž¬˜–¥™™¡žž°¡¢§–™”š”¡£—¤ ™¡Ž—•‹‹Ž˜®|•›‚‘‰©¨…€˜–‹„ŽŸˆ{„‘†…š‘‡†Š•›—Ž˜ž£–™’œe¡³®„‰„w{Š~wyzogy‘‰kuyˆrhsyuƒ†jtbxe_hdcdfjXk{qjk\SLPD_UF@>?,4@F;45;>A;<?>>HNNOPSTVVXZ\_aca_^^]^]XVJKLBIOMRJ;<:786/3964.(&$-1..)+*7%+<(6CMLD/T\Q05M[17E4\G5<,@³ ¹¯¾­ª­±² ª¦²­¢¬³°Å°«­¤³¯¼¤´œ¡¨£¡žš—¨¦©¦¤¦³µž••žšš°¦®¾¡¬¢‘‘žšš”’–¢œ—©„©«£´Ç³Ÿ©£ª––˜š§ž©œ ¥«”ŸŸŸª®¨¤¢« «šžŸ¡˜¤žœŸ°¤™Ÿ©”™™ž“¦›™ªŸœ—f„“}e›cyŒlhjz£«ješ˜~g…‹eeihz¢ŽkhŒ˜‘£xkj‹™£Ÿ˜slnz„Œ†yXe]…^l‹Š‚w\gsww’€ˆ‚ow‚xsmy„svˆ‡‚zh„X]jsd]sˆik|qmc]QNVIdX@I3=F7?FD71<=?AC;;DGHHILNORRTW[^`aa`]]]]]_]ZUODHOKSN=>==6535554*&&%,*%.++'6*$;'/AI[J.6ZO6)EY/DO1YB;?.=¤žº½¹¯«³°«¥¨­®°¦®®°½±ª¨¥®°° ­—¡¤ž¢šš§¬œ­¤¦¨©³®ž–¤£°¦¶¹¥®£š¢š“’› ™™¦–{¤«¢¨´Ã·¥¡¦¯ž•ž£ž£¤ª¨’Ÿ¡ž ª¯ª©¢ªž¦›¥ž§ «–¡œ¥±¤—¬–¢Ÿ›”¦™ ¬™Ÿ~½„‰s´s…Ÿ†­hw¹Ä¸q’¡£z¦˜™t«‚}ËÀÀºq‹£‡ƒž}–˜ˆžÀ½‚–œÁÁ|z‘ŒšÂÀ}j¥²ooÊz›x’„€vy€yq{€†pw…‹’xlu‘be^wc_e€b^thmdbXKUIQYHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^_`a_^^^^___]\SMPGUNA@?=6468266*&%#)*&.+*)109*#>I[L*#CP/#F[3PY/UAB;/8•¢¹Ã´¯¯¿©©”£°©°¯­¦²¶¯ª¦§¦±« «˜›£ œ›ª§¢¬£¥¨¥¥´¤ž£“¦®­¸´§¯¢’‘™¦“‘ ¡˜› žˆ¦«¤«­¿¿± ¨¯©–‘Ÿ¢™£¤ª£“ ¡ž¬®¨ª¥£¡¤Ÿ£¤œ­©‘¤›©®ªœž«®£—˜¦—¢¤˜Δz{¥‚z–—›_­]Ž¨€¡¡|§•›u«ƒ¯^dŒª{¨‡… t—“ˆ³c‚«† ³j„¯t|–‡¸a‚­Y£Ínv{Û{™q~ˆ“ve{ˆuvl~‡m}…}k€Œ_pjof`_xd[qhjdf`RTSW^JOC5AHED8>5;@?A;=8@>??BDDFIJLNPROS\___^]]_``__][WOUJ=?><5578164('$!',&&/(&+360$7;SL+,-J0';\:L-!P@F4.1¬ÁÀ¿´´°·˜ž‘£ª©­µ¬¦²­¬¬¤¬¦°ª¡§œš¦˜œ¢¯Ÿ¡Ÿ¨§£¦¡Ÿ°¬›ž–¦®­±«¨¬ ”’›Ÿ¥“Ÿ¥—¨£ž­£ª°¨¿Å²§©±­–’žœ¢—¡ªªŸ•¡žœ­®¦©¨›¥¥¢ ª’¬³–¥¢ªªž¤§§¢²¢“›§œ¡œ–•‘—¡r†Œ˜v†¨‡q±|q¬}  ¥žx«‚~­r­¬‡†Ÿv˜’{|—~ªˆ¢Œ‘‹œ}«zˆ’Ÿz­VœÄ{p“Á}•mupŒmfwe†oaxnrnˆ‰Žƒlcmsuo`fmd_oijnfcWS\`ZRRC9II@C<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;91478452&# 1' 1''45-&7=WJ-<(=1)3V@F!G;C1-+¯ÓÆDz³Ÿ££¢¢­¯·¯©±§¨ª¨®««§¢¤š£•Ÿ¦« ¢¦ ¨¨£Ÿž°­˜›–¨§¯­¨§©ž—•š¤¢’”¡­š§£¯¬¢¬µ©¹Ì±¬¦­«–”œ¢™Ÿ®¬–¡™žž©±§¨¨›ª§£¡ªš¯±¢¨«®¦š§«««³¤“˜¤§œ–“…¤k¤uŠz©u{²q‚¥Š˜Œpˆ ›‡¤_aR«…€®ƒœu®‚¨††Ÿz™—†{f€£Š¤˜†£}©”†®^{¨U¢’{£Ÿ€|İŌs¯´³¹rb©¯Âuh‹‹–€k—mkxxwnkfddqqf{ic\V_iXXTLLQLCCAB;C@@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799664,&$" ''!+-"$.!3-&@DWH,G+56*1PKL# A9D4,'ÂÉÕÖÀ¡™«¨¡¯¢Ÿ°´°°©­£§§ª««¨¤¦ ›¥Ÿ¦§¦¤¬š¢¬¡£Ÿ¯£ž›“ª¤µ°¯¡©›œ–•§¤‘›¢¨Ÿ ¦œ°¥¢¨±¬¶Ç±´¨«©•‘¢™ ¥³š¡”œž§ªª¢­šª¦ ¡©¢²¬¡ª³²¢œ«©±°¸¥”—¥©š“}ªmŸ„ˆv«y|°n‚¤‹‰Ÿ–•ž–Ò¸´¸É‚²_a”©ƒ¥ˆ‡ z˜–šyªÉtš£”¨©’šŒ~š‰šÆÆwe¡‚¥sŸŽ‚}¯_oµc±uK£†m§Gƒ“dŽ›‘{o”|myt|zm[ejrqf€i^aXcm\^YILLJEDBA=A<A?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75785/)(%&%$&),5FNPPMFLJVF*L0/>-4NTQ;<F2,$¨¤Àƹ­©²®­¦¢³¹¬«¡¥›¨¦ª¬©¦ ¦¥˜«£Ÿ¯¬¦¡­šŸ©¥§µ £˜”¨«¶³¬œ¦œ –¦­’šœ§£ ª§®¡£§©°³Á±²©¬§”‰˜¥›¢¤¯¦—¢•˜œ¥¥©™®œ«¥¤«£¶¬¡±¹°žœ°¨´´µ¦–™©¥œ¡ƒžNwš‚€Ÿz„£|‚¤„†¦ŸœŸ”„¸||z¹‚ÌÆöw›¢‘‹Ÿ~™——ŠvŸ—Š¤˜¤¨~¯…›ƒž„¬}™”a¥l£p…}–„r¬`¤sq€ša¼}RUu‘¡•z|Ž‡ryr„~o[lnwrjnZc_hnbd]LLQSAHGFH::K>B108856877-*5==?BDGILNPTWYYZ[\__^]__\ZZZYUSOH@772.,*.+*'&?QTVWWWYXXWUOTF<E2:P[T6?G,- Œ‡™©¬¤«¹«¯ ›¢¬³µ¦Ÿ¡•¥¯®®¨§ž¥¥š¤§¡³®¢©§³ š©¤”£µ££•—¡©µ¹¤œ££“¢²™ž›¦¥¡¢¯­œ¤¨¢µ±Ã°­©¬©‘†‘œ§£¤œ¥—ž˜˜™¥£§˜­¡«¢¤—®¥»¬¢·¶®žž¶´º³µ¨š ±£¦ ˆÒµÃ·z‡Ž…‘“€¦x”¢wŒ¡’…¥ƒ‹r«‡†´nri™¤•‰Ÿ}—™‡‡s®‚¥›£¦Š“œˆ”šmp²\¥s“zœl™{™~n©a¢rr~Ÿbs²¸hwŽ’¤—|‰Šˆu{xlhwixsnt\ddmmfh`JZWX<HF?S3@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^``]Z[ZXURRQF:2230/++(@QRTUTSTVWWXXWUUVTQOQ[U%!2AH#)%’rŠ®¿¿¼»µž—¨¤®¶¢¢™•£ª§­©ª™¥¢Ÿ¦  µ¦¢©§±¤”«£¤­¤ššª´´¤¥œ©’”—¯  ž¦£œ§œµ™ ª£µªÂ¯¨ª¨¡Œ„œ¢¡¦£•ššœ˜š˜¦£¥—©§« £›¬¦¼¬•½°­Ÿ£±µ»­¶©ž«´¦ªš|¨‘}|°x‹€¤¥ˆœm²o¡‡­|¢ƒ¨—š¬‰†­… ”¨ £—…Ÿ™–{’~«™–‹«w ˆ“’y¯]£|¦§dž€|—uj®]¥lr…™]`[Œ m”¤—’Š“ˆwy–~il~b}tmy_gepogghBY_Z=JS2S8AAC7$$3+''3, /667436:@CFIKMNQSSSVZ]_a`aaa^][ZXSPONI8152.*,ATVVVUTUUUUTTUTSSVWWXVUVQHFIJ#((¼’›„©Æ÷Á´Ÿš­ ®¹¦£Žš£¤ ¯®©Ÿ£ž­˜ž¹ £«¡°ªš®¡‘ª©¥–Šš­±¬§ ¨›­˜™­¢¡ž¥¡™¤œ­—Ÿ¨¥¶¨¾®¤©£ŸŒ€Ž›› ¦ž’”™›”™™¥£¢˜§«ª¡¢ž¨§¼¤—í«£¢­´¼­°©£¶±«­šw¯~‘‹œ…‡|º­‰˜d°Œe–®}¡„§—œ‚­‹…°†§š¤¢¢‘… \lk‚³`­|{‚²lfn™—‹ˆ±Z}´[¤ƒkÈ¢fŸ|»YvµZ²}S¯z¬X€¡m—¦˜ˆ”’“xwŒ›}cs|bƒwt€|ajfomfeeOUc\AT]=H(>9=4!!,$2. *1/04579:<ACFHJLNPPRTWZ^```ab^_\[XUPMJGC553./@UYXWXWWXWWXWVWWWWXWWXYZZ[\XWWGB;ҟ³±·¾»´Á³£œ­¦¥·© ‹™ Ÿ²±¨ž¢Ÿµ˜ ³¨ª«ž°­ž¬œ•®¨¢Ž‰›Ž¯¬©§£¨š®“š©š¡¥Ÿ™£¢¥˜ž¢¨±¨»®¤¨ž}‹›–¡ ™‘šœ‘™—¨žŸ—§­¥£¤¢¤©ºž Æ§¦©¡¬¶·®°©¡¿°°°˜‚ª’£¯Ž›€†¤—˜€€¸Ãº„“…¨™ƒ¬‹ƒ¯Š¨œ›¦«‘~սªb¤¿½}£‚ƒ×º·µ„”’‚ž½¾„j£o«„nz²±Çƒk«±½¬yx¢¾»t€•Œ¤™˜“™w™yb|ydŒfx{`kejjbPb[Si\@T`BL)<:4/$%2 $(0496678;>ADFGJKMNNQTW]a\__a^`[\YTQMHC><A?5=SYYXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ»•´´±À¹²½³¢®§¦³¦Œ—¥¿©¶¯§¡¿¦¦±›ž±œ¹¨Ÿ®¯¥§•”¯¬—Œƒš‘®¦£¬¡¥œª ˜Š£“¦§›š ¨¢˜ «¬©¸¬§£š—“{ˆ™’¦›“˜™Ž—“¨˜ž–¨¨ž¨¦ ¢ªºž©Å£¡°¤¬´¶¬²¬£¿«²²œuvª¥·…eŠ pg¬Šnnw¥› ‚v±›—p‘Žr—©¤›˜¯¤rlmmf‹xomƒ™qzipig‰–•—qhi…†gq†d]ŠcioZ]g~x¦`br“pfd€’ ••—’šz…“td†wgŒjx~ydlcflbJeWJkY:PdDP'J9+# ",)-2.5:457:<?ABDEHKLMOQSV\WZ\`_a]][TPLHD=:AB7MXYZYYZYXXYXWWVWY]^^]\\\]^]^][[UW^¨•­´©º¹²´ª©¢®Ÿ¤³ª™’½±ÃǼ´©ž¿«¬£ §« º£¤®¬­¦Ž–­ªŒ…•–­Ÿ¦ª¢Ÿ¤£ ‘‹¥’¦™©™–£© –œ¥¥¦®¹ª¬™š“’{„—Ž¦—Ž‘—”—”¦“–§¢™¯¥¢«¹Ÿ°Á¨¥´§­±³¬°®ª¼§±»˜Œ¢©¦¶œ‰—£˜†©›”’ª´šœ¤­¢´˜¤£Ÿ¢£ž¢¥¢–¬§Œ’“‡“•™“˜•„¤š—•Ž‹“’Š‡„~gŒtƒwt‡Œq§m}–“””Ž›‘“”“€…’‹phvo‰wv|yiledocUaX@iZGb_MX+E=+&!640/ %2(*799469;>?ABDFJKKMPPQWUVY^_ac]^TQJEC>9=@ASX[\YWXXXXXYXXZ[[\^__`^^^__```_YY`¥–©ª¤µ·¯®¢°¥­  ¶±‘ŽªÄ¼Ã¹¶©¡¤›¥°¨¤·§©µ§¨‘˜¬£‹ˆ‰œ§–­¤¡š¨žŸ“•¤—¨š©™”¦ £š§˜ ´¹§ª˜š|•Œ¡”‹•‘•’—¤Ž˜¨žš´£œ¦«·¨¯Â¯¤¸§°°²¯«¬¶½£²Àš“§¤¦µ¢’§Ÿ©Ÿ’Ÿ¢­±›¢¤³«³š¦£ž¦¬ Ÿž—­ž“š¢œ”—«™˜™—–ž‘‡ ž””†“Œ•Œfˆuˆwz‰„tœjˆ’–•’‰}Œ–‘–ž™’†–…xq”ry‰q{~jod_pi`\_YmbP`bOX9FFE=2<=8/*&+)&&406658:==?AACHJGJKLMSSSUZ``i`eVPJACB;9EMV[^^[Z\[[[\]]_^]^_`aabaaa`bbbdb\[c˜–¤¨£°³¬®£©§­ ¨µª›£²¹­ª«¡¢™zœ¡°¤¦±©—œ¸¦£”˜©œŽ†Š‰›¢¯ž¤–¨ ¡’—™œ®‹«–¨™§Œ˜¨Ž¸µ£¥˜›‰y‚”Œ›“Š•‘“‘–¡‹œ§œ·¢ƒ®µ¢°°u¤¿¤³¡y{¢­µ¿—x°¦¡Š€ªd\bw Ž¤žƒ–~m”µ¤©°¬¥f ¡”tz›˜p™ª™l¤©Šeœ¥œ‘—˜—‹’›„›”ƒ“‡ŽŽ’Š…xkˆv‡q|†ai‰Œ•“Œ[v•‘ggŽŒqy¡••dx—…€v—h‚‰‚nykpe_vokkg\ecaamQY=MMNRF=@TB91/&4:306678<;>@ABFHBGGIKLTUUY]`hfgXQI<DG<9UR[`ab`^__`aa_\]___aabcdabaaedchd^]fœ–¦£¡°±¬«ª¥©®£§­¥’•ª´®°¥™©¥ª—s‹œ¯ ¨«§”—¹  œ¤ž‘~ˆˆšž¬š¤•§¢žŽ—’ž…u®ˆ¦š¨‘–£ˆ›¹³§ ˜˜‹‰uw“–“Š“”Œ“Ÿ™ž¥˜›±•€Œ›µ´Œ’½¨¢~§£{¥±ºƒŽ¨Ÿ„Œ†±©¯ŒŠ–¢šy€‹¬†ž£©«©‰–‡šw¦œ{ˆœ˜§ƒ{³{Š† ˜™”˜–––ƒ™šbyˆ‘„Ž’‹„nqˆz‚q†€‡tˆ…—“x–h“t šs{™‚œ™„˜~‘ˆ‚˜iŒŒ„jx{qpgexnilj\diidqZ\GSKQ@E5-YTT6)!09=>643568;:=>>?DI@IEJKGRXZX[aaifYQH9DL<>bV^bded`aa`bb_]`aabbbcfgcba`edcgcaah˜¤Ÿ¦®®«¨­ ©±§§ª¥™“¬Ä¼¯ ”¥§´ƒœ¬œ§¢ ¾ž™Ÿš¡‘}†˜—ˆ¬£–¡¡’”‰†€‘¨Ž‡¢œ£“–†ž¹±§š’Ž…pu‰•Š”Ž›‹Ž‘ž•ž£”«‡Ÿ´‰´š®‹Êˆ«¯Š·…°„³²†©Ž©™|¨r{wœŽ¦–h•¤y´Œ¡ ¨ª“™Â‚€«‰™¡rž€›¥}—…•³¡}¡“Ÿ˜˜€Ž”œ‰˜’‹|…”†•“Š„nt’†€{s‡„}…u†ƒ˜Åf€©‡¢jž—€™€ŠŒƒˆ˜o’„gwt{vghupghk^bnlfjWdE\PL2E46M`c7&3<EGD:63658;8>==>BL?NIJLCPZ]\Wb^jl\QE=KM@IdX]cfhgbbbbcc__babcccdiicbbbecafcbbi•—£ °©©¨¦¬ ¥¹±ª«¦š”ž¡¤©¡”£©µ¢¯ §¥ž‰”½š“ ’yƒ–•‘ˆ«™œ›š¢…Œv››Ž ‘ˆž£›–˜—†¢¸¬¥™›ŒŒbm‹“‹Œ—‹‘ž’ž ˜ §~¡§‡­ –® ž‘‡‚¡­²ˆ¤Ž¬›Œš~¢v€™”k«uM«x‡“œª©‚ª«~„¡|{§jž€“lg—†˜·‰ž~n`cXƒ—{dg‹s™}y—l\|—n`Sq…\`mz„`Ye‚~…™q¨«kƒ£nr¥oŸ‚œgdžlZlˆzeY_‚~aWPoventqjjo]ioljgWfM\WE9A4GC^k4+ICQMN=84859;6@;;>BO>QRKMBJ[]_W^_cu`ME:MNMTb\[ffiibbdbddbab`bdcabjkdbddgdbgeach˜—ž ¹¡ª¤¦¬’¢¶½«¯¢™–ž ¥««Ÿœ­´¡§‘ Ÿ §œ™Ž™´™‹žŒ•‹u”‘Š¦––˜žŸ~“……¬£‡œ‘Š˜¨˜™™‘‡¥¯¦¢•™‡‰€inˆˆ‹ŽŽ‰Š‘‹‘¡‹’Ÿš¡¥“£¡” wœ–§ƒ£©€†¬°‡¥zŒ~„š}¢ps“‡•{žŒym‡œŒš’œªœ‡}ƒ¢tw¦gž~w¥^˜{}“s¢n˜·´ºs“ˆ€¶¨dÆ¸|q•¶Œq€›£ct¬«a~j³~n~ˆƒƒŒ˜q€£lr£rž‚~£^œ™³–o{—ž³tr[ž²‚ibptuqhoXjkqpd[f\aKD=D5QAYp2<RG_JR=<395::6C<;@IP?TNNQ@E_^[YX``{dIC8LWUVcaZffkkbbeadc`ab`dc_`cknccddhdbgfchh”–•£¹™«œ“ Ž¥¸¶­­ š¡›¢£¤¬šš±¬«’— ™¡¥™š”ž¬›‹‰‘x‹…q€–Š¡“”—}‘ŠŽ¨ †˜Š’¢“›šŒŠ¨§¤ž–‡„~k{‡}ƒ‹‰Ž“Ÿ•›Ÿ› Ÿ‹‰wœ˜¢ r¡Œ‰©‰¨‘˜ª®®Œ~z ™y£“x€s—ˆŒœ}•Ÿ‡›Žš¨ˆ£d¡~Š–›mžh›Žoš™{€Š§}rhtªƒžƒsªg”š]›…v„hªj¸f\©pœa•Œ_§vwŠŠ€hšu‡“’˜~žm™j¦™\¨~w»j}©ZŽ„]³g\nqxwki[piwwa^cVaAPEO7VBRm4JZZ^NZD@151;;7H?:CHU?YSX]>Db]V`Qac|iEB9N[]XdfXffnmbbe_aa__``ec^bdoq_deekdcihgki–‰ª¶œ¨‰c•œ¬»²°¬¥›š§Ÿ¬™°§ª—£š¢ ™–– £™†‰iˆ€r{—‡Œ––„’”˜z‹„–¤œ‰•†‹‘œ›ˆ¨¡Ÿš‹Š€€i†y—Œ{ˆŽ‡Ž•™}’¡ž ¡“˜rhŸŠ Œp’ƒ©‰š¡¥ª£ª~°­¤¢¸—v£³¢£ˆ”xzª™¢Ÿ™‰˜r¡}‡°µ}lš‘¡x~™µ££«¨„™|š|œštªZ]o{—ŒxžbM{{…dz˜BMŸY¢js|Žo‚Š„™v›y‡‰±³~š’¦t~mq|”o™ri£]•vHec`sp}}ne_kguzbb^O]V\TV@YEPfDRV\aX^ID=B8?A:HE8LEXAWRZVEFa\Z`K`m}qEC<U^bZejVghmobff^a`\]^`hb_edvl^egfldelhhli”±®š„S_¡§´º³³©š¢‹š©››§’ «£ §žš™•˜¡–‡‡‰w…ny•„›‹}‘“–ˆr‰’¡›r’ˆ˜”Ÿš„Ž¨›™•ŠŠŠ|ƒl„…q‚¡Œx„Œˆ†‘˜”{‘¢Ÿž£ˆ®†}µ„ž{¦–z©‚—ž‘Œ£ §hxn~™s sq|…˜o“‚­|¤„§Ÿ›ƒ¤p^©hv£dp¦aÓ|{™xrsc¢†~¢r£vk³‹`‚˜Štª²¨¼wƒn¿¦ª´^œor—p‚s¢r^¤gt¦`h¦lšÓ˜z‚›nvy—k›yv—rl©¥g_dyq„lhfcmuvf^`QZePQaHVIT_WS[dj[ePECKLJKAJD8P@PMXSXOSQ`eeiSdxywIFEc]eZhiSihjncjf`c_\]]_hbahe|d^dgdkdjlfhlh˜›±¬T]Kª°²µ°³¢œ˜„—¦  ¢Œ¤§Ÿ–¨‰™˜™”™“’ —Žˆ…{p}„h|ƒ“š‚w‘ŽŠp€†“’l˜”|ˆ‘’£•ƒ©™“’Š„‰yƒvˆ€nŸ†w€‘…‡˜ •y’¡£™Ÿ‰³¡¢¶‹z¬§¤®¥p©€›‘†ž”~¥£š†˜qž„£­¯‰—‹Œ¤•ƒ¯£•wµ¶¶É¢s”ŒƒŸ`ž—©my–‡ ›u¡‡x ~–‹oMf£’qšˆs¥{zubƒ‚m~ lrd`œst—k{j´¶´Æ¦s˜}yœjšš«tšlsw—i™yt—qPD}³^jukx†fkfbstolU[RXgORgIULXRU\gknUgWMJAJMKGJNAQJPdcjmeuss~x{nu‰z{TQNm^h\kiRjhilgmgce_\\\_ibdhk{_]dgcjfnmeile¢‰°¨…e@”¢²¬¯¯µ¡¢–§¡¡£‹¤¦œ›¥‚™——Ž—›“Žˆƒyky†eƒŒ–ŸyuˆŒ‚j……’„‹…zŒŠ•¥’‚—¨–‹‘‹€‰z€}‹yp …y”†ˆ•ž”~“¤¦›•–ƒgnxœl¢d|r¥xœ˜ph§‚™Ž}¥{¡—ƒ–rŸv‰”•¹mŠ¢b}™£—‰nsk«ku no¦`›i‹i–‡›•u¢~š`‹†uoˆbh¡fžj›updgˆ‚or¢[_[d¡n^ˆŒq|€trd¥nx¢cf§g—r‹—m¡oRˆn ^d§T‹]T˜mmrkqmphkwsjnQVUUeYSlIXO\HXhhrjYkVPREV\MXSaUhj^wu{|p}|r‚{swŽ€ƒw^QsagbpgPkhhklohdg_]]]`jbjivu]\chcjirlfkmc¥™¦zetm‹§®¥©°±¥Ÿ‹–©œ£‹¡¡š¡¢€•™“Žš‹—ŽŠ{†q€ˆh‹Š|—šst‰}|eƒ‡•Š‰•š‚|ˆ†–¦€¡ª…ŠŠ}€€Žsi¥„}…’Œ‡—Ÿ†‘©¥‰¦x–›~¥‰–Œ²™ž‘„¯—Ÿ¥y˜Š{©u¨„šn¥¢Œ’„Œƒ¼m|¥¯‚‡†‡•—¢~¦|r¨•¡–hŸ~o¬c–Š–“x¨mª£‰uˆ‚w«‘¦ˆk’±lw³Œ©l‹†oo ž’•b«Œªw€Ž§ŸwŸ}…¤• hš‡u«fž­Œ¶sv¾Œ£“Yƒ¦«aurto{upbj}nglRTXT``\kL\R\I]lmv_[qX[_Zgsemoqcqt`wz~yryƒrƒ~{{‚€vbydcnsdRlggomrifia_^\ajbll{o\\bibmiwmglnb–¦«€ž¤–ªªž¨§­£˜ˆ–©™¢‰š¤œ¨œ„Œš†œ‘…’ŒŒt…zˆƒo…~—“st†r‘ƒn‹’‡†”}{‚…—¤¥¤€Ž‰„”u‚‡“nl‹¨€‚‹“ˆ›žˆ‹’ª¢ €t”—ˆ~x”¯¤‚œq†y“Ž†{s©r}}z—–›„x{}}ˆ”•“‹w‘™¡¢…{ŠlŒ†\zyszqio~“Šq€t‚”“q†„‚e_Œxvs”upzoo‰o…†_wixŽf‚ƒ†ªœt}–i‰ˆo~u|ƒumlfŒsx{—w„ZjWyinwrqowxo]k…nhgVY^V\djcU`U^Q_owykjwejjju|pqtsaoubs{xuy‚u€y‹…‚}{m€mdyn^Wnghukxjiid\`ZcielqunZ[bkdlkymhloaŽ•º©§‹¡¢›§¤™¤«¡Ÿƒƒ–ªŸˆ™¦š¨˜‚œ‹~–”‡ŽŠ‰Œr‚|Ž|~„{—Žtrƒp•†|}’‹†††y~€†˜£Œ{¦ŸŠ…„•ƒ†Ž˜wq„ª…‘œ‡ž†Šš¨  «ƒ‰•›~Š—­¨“¨‘xqŸ“…}”p«‡q~•qjo|Ÿ‹‘Ž‹hn]„œ s—‰rulƒvt€Yro‡‘‚~Œj]id{…„ˆ€`ix{œ|„ƒv‚‡„izŒ‰lbqsƒw_sƒŠ‘¨–‡gŽ‚lvŠ‚nƒ‹wmdecz‚z•Z[ifmv[{ywtnsrƒf\m‰kkbYX\YXjqZ^`Y^]er}ztotcjji{|rzvtdmthl{uz}{yy€p†‰ƒ{}s~zrhT\rilvpugkgd]aYjhkjqrmW[emlgryohjm`ŒŒ«±¡£¡šŸŸ˜ž™¨¡ }‚–«ŒŸ“†š¡‘¤•{˜…|’™‰ˆ††Šr|€‹v…‹‚„–Šro€s˜†„~“ƒƒ†Š‚z€„ŠšŸ¥Ÿ†wŽ—ˆ•‹‹œ—„ƒz¬—˜“‰œ†‡¡ªŸ¢¢£‹ˆ“›£™–«¢¨§¡“œ‰™‘~z†©€“‘’“œ±¥š”±’˜„¦Ž–¡Š‘„‰“‹l}Žwwfƒ†‘‹}‰ž…‡‹ˆˆ…„‘w|{u›¤Š‡‹ Œ‡–€ƒwqu†„x‰ˆ‹‘§‘„‡Ž‡‚‹Šz…‰‡uj€ƒ|y™iqh`sŠp}{wvowt]^o†gn_^YZ\SgpUc[[alht{{rnpcjih{mx~phpplf€{r‚€w}„{mƒŒ…|zy|~zƒxNdvjsnq{dkebb`[sfpfrqlU]ltmhxzpgikeˆžºŸ—£¡˜•™˜”˜¤ œz~—©Œ…ŸœŠ–|y•ƒ{Ž™‰†ƒ„†mx€r€‡~ˆ“„mk~z—‡„ƒ~€†„‡|‡ƒ›’†©ž‚rŠ†’’‹œ‘|{©ƒ‘—•Ž›–……›¦Ÿ¢š†ƒ’š™™™¦¡¦žž—‚“Œx}‰†§|}‘†˜ª¡œ“œŽ©’€ž‰”› „˜€ˆ„qy†rua„‡vŒ™ƒ‚†…†„•nzvu”¤Œ†›††uŒ~~ss|‰…{y…”¨‡„‚‰ˆˆt‚††ˆymj|{mhklf^yh|{vtvu{w\`p}nt`cZ[^QflSdZ]`jhty~pllcjjg€krkktnwn„yn†€v‚€}…wrƒ‡~{{|€{‚‹`i{kuhjƒdjc`i\cugobumlTbqyeoyzrejmm‹ŠŸ¸š¢¤Ÿ“’–—‹šŸžœzwœ¤›‰†¤“Š˜™yz…{Š‘ƒŒ‚‚‚l{xr€…}Š|kh}‚—‰ˆŽ|~…„‡|€››ˆ¦›p‹‹Œ’† ¡Š…Œ|§‡Ž‘–’–’wŒ£ ¡–šš˜“š£¢¤›˜’œ€‡{†‘‰¡~|—¤  ’™¥Œœ’Š”™““ˆ‚vu‚qwa~Ž†sŠ–}ˆŒqŒ~‚…†hxrzŽš“‘€˜‰Œsƒ‰}}rz|†|{“Ž„—¦”†{„…†„s€„…xdpz~xypkjf^~si|uus|s€j^`tvpwdcX]^RihSdX^_giuxqfkclge€jm}gmpj}w…zk‹r~uv‚†|z€}jrƒntibˆhlb_qVtolm`xhlWjtvctzzqbkoy‰Ÿ³’¥¦Ž˜†œ š›{u£ž—Œ¡Šˆš–x|†‡~„Š~ˆ‚p~ztu‚…~‰wgc}†—Š‚Šx}€ƒy–€•—•–Ÿš}o‹‘“…¥›‡Œ‰ƒ¦•„‘Š•—’‘v‘¡¡˜”—yŽ˜—Ž–š¥žš”•{’ˆ…y‡˜Ÿ‚ŠŽŒs—¢ž ’˜Ž¡ŒŒƒ˜˜„”—š™Ž}ŠŽ‚xr~n{d€|‹†q‡“€‘‚k‡ƒ€Š…fvp}ˆ”šŽ~”y‹}‚‰~|r€y‹†z…’‹Œ™£—‚„‹v‡ƒ€tx†‚s^vw|s}vfkd`~jkwssu}q|ccasnurmaY_]ZkcRbW__gjty…pbjclfh|‚khthloh|yl…q€ƒƒt|ƒ€~z‚ƒ~|mu‰ttmfŠljbcuVƒipm`yglajvpex{yp_ql……¯˜§©žŽ—‡…Ÿ“•—|v¨š‰˜y–œ‹Œ™x|‹}}„{€‚xsxys}€ƒˆŠ€d^}‹”‡…‡t}~Š~˜„–“–Œ£ —~r‡{“‘Š¦ŒŽŠ’ ‘ƒ“—‘Š˜ š’‘t€Ž’”‰ž§™˜Ž•—u‘‹mˆš‘›|ˆ‰‰o—š¢’•ŠŒ‹†“€”“–ˆšŠ}‹Š‚{qzkvm|Œn…“ƒ”xo‚„~~‹esj}‚˜˜…€Žu’Š…z‰wy~‡}„†•¥‘y…‚tˆ†{~qr~„k`ytyp|nanbe{bnovsxwstav`oluno\Z^]]i]O\Wb`glrzˆj_iejchw‡mflhilg€|zwnˆs€ƒ„}t†‰zƒ}z„}|Žry‹xxml‡kh_irb‡hqoevgmlazhj|{wpawmŠ™š«¡¥©žŠ‹‘†‰žŠ”–|v¬—Œ–|ž“‘–”ˆv~{Š||€vw€otszo…}€‰~|a\~’†„„rz€†z‘‡‘‘›’¤›“}|Š’£‰Š–šŒ…—’•ˆˆŒ’“Œn„‘‰ž™¢¡˜—Š—“p‹›†g‰›•{Š…Šp–š”¡‘‘ˆŠ˜Œ‚’Ÿ~“”š|‹†ˆtsukqov}Œuo†‘Ž“rt€|‚‚‰}ernz›•~…Šu’Œ‚uŠ{p‚‚‡}†‹…Ž–ªŽ{ˆ}~Š„v|nl}‚€afwstnza^o`kt^pj{yylrpey^nlsmsXZ]_aiZOVWdbgpq‡e]ihgbgqnchheig€zwuoŽ…sƒ|u‚‰…x…|x„†z€‰w‹{zryƒjk_phtkqnmqgoke{bnzwpkww‰£™£¨¡§›ˆŒŠ†’št¨“‘† Œ•“€s|v…xy€rs{…kroym‰v€†nq[Y~’ˆ€vu †Š‘œ— “–w‰~€ŒˆœŠ†’—–…ˆ”˜Ž–‹ŠŽŒŠŽ‘„m‰‹‘Šœ–¡œ™–†™‰l‡¥…gˆŸŒ“€„Œx“˜’‘ˆ‰”~™}’Ž‘Ž›“}‹„pvplnoq|‡jsƒ˜Šqx€u‚‰ƒzgtpw‚›}Š…{•“{xŠur‹|‡Ž{‹‡…Šœ¥‰|„v‰~wwlh}~[qrqoovY^o`pj^oj|zqnmjmw`pokqmYX`aalWPRYeebuo„a]kmdcek’m`ff_gjurro‹€t‚€yv€‹€y…~w‡†vƒ…{‡‹{vŠjqb|b…|oplujhnlvw_q~y{sus‚~¥–›­Ÿ§—…Œƒ~–•ƒŽt‰ž“’†ŠšŒ•ŽŒzrxt‚pr…tquˆlnltl‡vƒ}mnUQ«”‡‚x€vrƒy‚ ‚“’˜›‘™w‘z‚Œ’¤š“Žˆ”˜’„…–˜‹“‹‰Ž‡„‘‹}r‹…ˆˆœ™Ÿ›—••€jˆŸ‰hˆ¢‰”…’„Šqƒ‘—šŒ‹Žw{“‘{ŒŽ“˜|‰}lwjoklm{€bz~—wzxƒ}zhumv‰—Œ€‰‡|•‘r{†qxŽ{‹Ž{‰„Ž‘ŸŸ†}|wŠ|vogi~v]vnmkprU]nbra_mnyphpfgsuhplawe]Ue``pSPN[ed]xoˆ{^\hqbbee‘i_he[go~okqsŠ}v}…€uvŒy{†€x‡ƒs†…~ŒŒ„|y•xgrjƒ`‡~ook{`imtt_t|x†wss…|y¡š±œ¦ƒŠ‚™‰Šœ~Š˜’Ž„ˆ—ŽŽŽ„wtws€pp…spqƒojium‚n}|musRN‚ßɒ֓|ptƒuƒŸ‚‘v”˜›™{“r…Ÿ¡““‰’›“…}••‡Œ‡’ˆœŽx{ŒˆŒŠœœœ›–”zŽxi‹”ŠnŠ¥†”‰˜„†cŒ‘˜”‰–‹Œ‰‹pz•Š|Ž‰‹“’Šz†}m|espkm{z\z{~€†{ziuktŒŠƒ‡†~—Œm€p‚Ž€Ž‰~…{„‘–›œŒ}wx‚Žwrkdn|€igsnghslS]odpZ_lqwgkkbgxsppd`x`aUk_^tOMJ_fb\xp‰t\[eu`addŽc`fbXistnlqv‹|ty†‚vw~‹s†z‰q‰‡Šˆ|~™vesn}e‡npk€Yknyzr`vz{vrvŠvzŸŒœ¯› ‘ƒ…xˆ•~{ˆœ†„žŽ…Œ—„“Ž‡uwpyqo„omn~rcdwp|nz|jhlb¤šÁÜ®ï¢sluƒu„¡„‘n•”Ÿ”›€‘p…‹£—‰Ž•Š•ƒ€”…ˆ€’ŠŠ—~‡{v‰x†…Žœš—™v‹xp‰‹Ž¦†“‹ž††^‹”—‰ŽˆŠŠ„‰l|—ƒ~‰†Š‘†v†~~l}dxujoztXˆ{’‡†z€†zftj‹‹„„˜†mƒwo‰“ƒ’†„{‚’—”š‘utx‡‹trpdrv_rloahtfR`pgkU^nsyarc`i~qrn[cracVnZ\wLLKcfa]vr‰m[\dx^`df„_cc^Xirknkrw‹}sw„xx|‰qƒ„|}ˆ{t‹ˆ‡•…Œ˜shurym‹{ntp€Wpzvyqdvy†Œhv€‰q€ˆ™¨œ£“…}qŒ“xx‰œƒ„ŸŒŽ|–€šˆ„|swpsjoljm|t^`wv{ptzg`e|ëÚµÉÃ܉slt€vŠšˆŒi—Žœ•’ˆp…ˆ Ž…‹•ŠŒ—“|’‡‚ˆz‘‹†‚€wxƒ„r‡‚“›–“˜†vˆ€r‡„Œ‰œ¤…–Ž „Šaƒ•…ˆ…ˆŒ†€‡h}”€~ƒ…ŠŽ‚r‡€rwhvritxmZ}“ƒ†}€ƒ„‹ƒvbumŠ‚‘Œ„€€“’~oƒmzˆ‘ˆ”…}‚‚“”’˜‰nqy‹„tjoiov~]rhm\it_QdqhfS_qvt`p`]hƒqsjXgiciWmW[tLJKef^ars…i[\ey^^dgz`d_]YknenjtwŠ~sr{vzˆs…ƒ|‡vvŠ…˜‚{“vlwvyx“unwz}Xy…q€ngxv‘‚dv†…qŠ–†š¡›¡Š†so’‹qvš|‰™ˆ‰|Ÿ„™‚yrtnodr~iflww[_x{zqqiagaÕ¶Ž‘¦xnqw{q’Œ†j˜ˆš‹…zh‡‹™†’††—{ŒŒ€€‰{~‰…zu{ƒ|q†€•™Ž’”‚‰v„ˆx†ƒ• ¡ˆ—‘¡€‰a”‡„‡ƒˆŒ‚f}‘€€ƒŒ~mƒ}ƒulmwutwvkcŽ‚€…|„€…‰p`tr†}Žƒ}’Šzr…g{…Œˆ…|…€•‘“…nox‹~tlmhiwz`giiXktYRhribPbrxmbe^Zj„ntb\h`em_oTZnMGNfd\fnq€kZ[cs_\ckvde]]Zllbljsv†€qo|}tx†x…ƒ|€‡ux‰’•{‰†v‰oxy{„“om{€v^ƒtlhzs”sgs‡|r’’„šŸ›Ÿ†‡uu“~mu’–}‡ƒŠš|Œšv~vqoljat|gbiuyZ`w{ymq~edhhW_rs—¼Ä„vq”ˆ}q–‹†›’‹‡rjˆ–€{•‹„šŒ|Š…|{‰‹”ˆu‰†vw~ru†ž”…”„ƒrŠw†~Œ›Ÿšˆ•ž‰f~“‚…‚ˆ‰q}f~Œ|y€ˆŒ}i~„vgpyxswtlkŽ†‹‚Š€y‚…„l_sy{~Ž‹‡|‚s‚jz…‰‡…y…~‚™Ž‘~nmzˆ|usmee{sa[pbWnqSSmrhaNguxf`^]YoosZeb^jn`pOYjQDSf`Zjnm|nY[]mcZbpvcf\]`kicljsvƒpm~|tuƒzƒ‚|…v~ˆ–x„Štˆryy~oo{€qixz~ml{u•kjx„tk“†Ÿ™ ™„‡n}‹uiw—Ž~Š‚”—Šy•oztqljd`szh`eqzZ`r|ygqyaee±²wKbZ¥ÙЖq{Šw}“Š„˜‹…nk…’’zy’†„˜Š|†ww‰Š„–€p‹ˆqu~{jy…ƒ¥„“„p€„x†{ˆž›–•’–…ˆp{“‚}‚‚ˆ‚m€wh€…yr€ƒŠˆ|e~„vdqs€iyqpu™Ž†ƒ‹}wy…zƒk\rs‚‰‡Š~‡Š{‰s‚or…ˆ††s…{‚šŽ…ynn}ƒ~uyceh{n^XvZWpkNWqrf`Klwta^\[Zu~spXg^gkr`oNWgR?Xf^Zokgyq[ZXkeYcpy^g\^elgfkiqwˆol~€uo‚{‚‚v„‰—‰q‚q{†|zy„“Œujy~ko~t|or{z“on~xg’‹ƒ¡™œ‘‚…g†ƒogy•ˆ}~„‚˜Š|Žixskkf_aoym_box\dk‚yaqv_eeÔ꽋2:>‹Žqx…‡u‚–Œ~’‹~mk„ŒŒu|…”ˆ|‚wnv‡„ƒ—woˆ…lu{ufy‚ƒ¦‹‚‹„~nvx…|‰Ÿ’Ž’“”ŽŒ‡{’†w~ƒŒ‚jrh€~yn||‚‹„wbz…‚rdri~nvru‚œŒ€…€tv~€s‚o\n€uy‹„‹|ˆ~‰y{rmŠ…‘…Œsƒz€—Œ‹€umjv€ts[ggunWV{RYodLZrre[Iqxo\[[Y]u~thYb[hfodjMWeP=]e\]ue`uoZYTncYcqyZh]`gmgikipw}Žmi‚„yn€|}zu‚€“„p‹nw~€{{ˆ’‰hz}js{r…zsv}~Œyx„}|kŒ„›ž–Œ€l}kh~‹z}~ƒ“‚~}Šˆkvqghb[bgso_aks`hpˆybst^cd› n\5Z¯µti€ˆ|‘†u…•…sŽŠ‰vol„‚†ty‰x‰|’‡y~rgv‰~~˜oq‡ivynfy‡„¤†€‡Š~o€w‚ƒ›‰„–“™ŠŒ…‰|ˆpz}„{h~lj€{zj{w‚ˆr`w~rdrgvƒnu|†–’‚}‚owz|umYqwuƒ‡xˆv„‰{yto‹‚‘‚†s€~”‰Š|onimtm[edqoPZzM[n[O[rodUKsxiWYZZaq€t`]]`gdiifNYgM@`c[`u`]ulXWSt`ZdorWj^bhjgmlhpw|“lh„Š}}p~~{€zwŠ‹ƒq|‡oqwƒ{‰Œƒi}{mwxvŠv|x‚†ƒ~}zm…Œˆ™£„ƒ{u‹xkl„‡x}z‚‘€€~‹ƒprqcf^Yf_oo_`gpfjnˆtato[adjv{€¿œ¦¤È¸q„‚r’{w…’‚s‹‡rroƒ{ƒtt‡tˆw“ˆyypcw‡z€“ir„vgwucj|‚‡€Ž~s€u‡{‚”’…z˜–ˆ‚‰{‰‰kxy~tgzhkytizw€ƒ}h`xˆ}kkth|jv‚Œ‘•{~q|v|tbVx~st‹…ƒ}„q‡Šxyqq…„Ž€z~v†„wjqil‡qo\f`qlIduK]lTSYrnbQOtxaRXX]ap‚s[a\ieedkdP[pICc`[co]]whUWVv][enhVk^ajgennhpvz“miˆy}r{~y‚|v}ƒˆ†ƒpw„rmw‚‚~‰‹“p€{wxz€Œt‚x~‚„y€uo~Š‹›žˆ}…zw…{ht…‹y~{ˆ†„v€gpn_d\XeYmra``plkhˆnatiY_dn€w©Ú©Ç†‡²qˆwoŒtz…y’‰tst}woqm…t“…xtk`z‚y‰fr„pgun[m}€“€x‘“~y|nŠxƒ“Ž†v˜Œ“ˆ††|…ltu~lgvdm{vmjww|abx†ziuuc~|hu‡–|uwq€{}n€ZWupv…ˆzm‰†tzlv‚„…|~z}tŒ‚~thtenŠƒlsZh]sdGmmKZ`WVUwmbPRtvXPVX^ar„o\`cmed^ocT\qFBe^]eg][{bQV\t[Zgk`Vj_`offkqhpvxŽtkŽvvx~w„{t}ƒˆ‡ƒor€tqu~…‚‰Šzvxƒ{|…‡w‡|}~„€{~ruyŒ Œ‰y‰vtƒx^}…—‹x†ƒs…†„w‰zbnm\b[[aVisc`[gnpf‡qaqfW]ck|Ê·¹¡jmmŠlqƒq{ƒ‰~z„yxsxut{jlvc„u‘‚vof_}‚z‹Šer‚kjqcXlz…›ˆ‚s—”x}oŠs„ŒŽ‰t™’‰†‹ƒ{y}qpo|fhqbmxqjlqx}}z]ez€xjvxfƒwhu‰ŒŽ•}rˆjo~yo}]YsnuŒ|‚opŠ€qwix‚‚x~s|u‡}{sgsan‹€kqWi\v[GmjLVU]SU{kaOTurPQTW^ct…i]`ljfcZoaXboGAg\`e]\V{^NUepY[jh]Wg`^rejhrhpsw†xn•‹tzx~yƒˆur†…Ž‚pp{xwvy††‡Œ†y{t‹}}†„ƒ‡~~~}‡|xuxx‘“ŸŒ|Šmu€xdƒ†•…s‘Šo……zƒtdnjY_[\]Tgrd`Ydqrg€rbkeW[`jx¾®{Ÿ·nas…hszqx„z}‹~wwrvo{vejoa‡uŽ€sjb^~xy‹„fqhkkZVowˆ¢€„q™“rzv„oƒ„”Šu—ŠŽ‰…‰…}xtqnhx_jl`mvjgjlywzvZg}|yfs~m…ueu‡†–€pŒgk{„unub]q}lu}Œ|‚gv‡~nqiv€y€t~m{|‚{yqflbn‰}llUi_vUJijNQNgLX{haNUukLQTU_gvƒf^`qhgbWj]\kgJDjYbcVYUyYMVmjY]kd\Yec^temdqgrpuxq™†v~w|…‡}us‚ˆ€•‚nsy{zss…‡‰‰ƒx}u~|„Šƒ„{~‹ƒ{v{wwš˜z‰‚†iv|{lƒƒ’rŽp…‚‚pglgX][\[Sdpd^WbrujuoeecW\[hpor€s‰ddy}isusrƒw€ƒxvrumjzqagkg†sƒmf]_}p{‰imxgjdUWroŒ¦|„{v–‘t}t~|o~}“ˆx›}‰‡„‡ƒ}upqlgt\lg^ltdgeizo{rYhwuhpx‚wbw†‹|•oŒjm{‚qgtfanzhsx‹|cw„wjlru|r{{th€€ywodfbm…{ljUhaoRJhjOKNoG]zfaMUtdJOSWakw~f]gsif`VdWbp\KKjWcaUTUsVLXudY^k`[Zce_vgmbpitor~tt™‚w€x€†„z}u‚„—…nrt|zuq„…€z‹us|•€…„}}Œ†z}€w{£¥Šyˆ…„kt{zu‚€‹zn„sy„}‚ƒvojieV][ZZSbnd[Xas{jhmi`bX_Ziiko€gl`hyxjrssmƒ€z|utmzhjyj_enhv„geXbwj~‡{ojpgf]TXog§v€z|Žzvq€qux{‘z—v‡ƒ€†ˆvjruggn[ld]mr_gajxh{l[nƒstjp~zxaw†…y‘…t‰rpzsdri]qxert‰|yct€qgjyusmyxvye…|ywqddcm{|jjTgaeSJkgOGQjE`wfaMSr]JMUZelx|f_nqid]VaUnnVJSgWe]XMUkTJ[y_[_k]]Zbe`yhlaoovnpwuz˜~wy€€‡†zyzƒ~“ƒqtt~zvt…ˆ‘}€|kr•€{‚Ÿ…~‡}€~†‚€Š{w„«žz‡‡ƒkryu€~€tn†n|€sŠ€jpnddX_ZYZTbjg[Z_u‚i^ml\aW\\kert}ii\kvugsvql„{}|xurlygixf]dshzw’ccTeph‚…xxgijaWVYgcŽ§o~w€‹Ž{qri{q|Ž}xs…~€€†ndurdgg\ja]oo\g_mtezh]t€orkq|~uvbt†Œ{‰ˆysu€vbqn[rtcqs…|ues€mam{pkj|zvtg‡v{zvqebdmr}ikSg]\TKqbPFU`GbvfaKSoXJMXXhkv{eenqfdZW^XweTJ\bWgWYHWdPHbxZ]_lZ^\ac^~ij`otxmpnvƒ—zr€€|‰Œ†}uu†x‡Œ|suuyzz‚ŒŽ}~„‰is–zŠ~~…zz|†‰sq­Œ{{†}dq‡ys|zuro†l{~lzcpobe]eVYYWcfk_]]s…hXqn[^XZ\l{bpwulaYlssgtuolƒx~xvmntdhte[gufvv‘z_]Rffkƒ‚t~bdj\TW]bcŽ¤ixsƒ†‘ynq|jzo}‡}vŠt‚y}y€idvl`f_^i_]tkYe]oobze\w|knnpxytues„“€ˆƒ‰{wpstcxe\qqbqr‚}tgr€e_nwjehz}uopƒvt}trb_fmn|dhSgWXSMv_PJYWHbtcaITmSJMZWjlr|cmmscbZZ[aw\SKc]WhSVFX`MGiuX^`l[[_bb\„ihanxymojvymƒ~€“ˆ„vt‰tŒ†tqvvx}}~Œ€~“~pw•ƒ|˜’y€€xz~€tˆ„tq™¡zz‰”wcu‡xswtktn~kx|p‘s^pn`gblTZZWhcmf[\q‰eSrn[ZXW`lvciuji^Ymspksssi„|~~zvnnldiqc[jrdtvŽs[WSear€r‚]bc]SZ`\c‘Ÿeqq…„’ull{opr|~}s‚xt{z{deug]bY`g[^vhWb]phawa[|vijroxtsuiq‚–„‡…wtkq~ogxX]lncrtztgp~\`prb`ksmnvsqxkqa\ellz`fReSVQOu[QOXQHcsa`GVjPIPZVkkk}fnoqb[ZXYlqWRPfVVhSTEY[NHruX_clbX``a]‹jcdmzxlpiuy‡{kƒ}„š|ƒ„y|‡m‡rnvz|t‚‚|‹ƒ‚—tx“…ž‰u€t‚qˆƒvp¡–sz†‹†zewŠnmznfxpzksvsk^unagekR][UgalkZ\qŒdOon]VXUgishbted\Xmtloutxj†|{‡vscdkna\nmcsx‡kZTVcdx}}q†]d_cTZ_Yb••cmpƒ…Štki|pguxu}m{uvp{v_frc[]VacXaueU_`mdaq]]~phitqtquwkm…”‚‰}‡rsgprtpT\gkfruwtcmvVcrl[_pg~fnx~stsknaZdijw^eScTUPSlVPVRPGdr_aFXiNIXTWnie}ilxkbW]U[tdSRWhQXfTSGYYOMxv[_ekiYa`^^Žnbfkyunoivv€lƒ€}‡˜{€‡‰~k“ˆrft€{u€ƒ}‰‹“r|Š‘…‡Ÿ†{†Œs†s~‚vn¤‹r€‹vwlzŒ`d{pfysxlmqwƒgd|mcfghS_^Ug_ln[^nhNim`TVSogskexdd\Xoslqzwrl‡{v›zykaelm^`ojepx~gZVX`lx|{p„_c_gVX_Wc›ˆbkp‡}xllzn]xsn|kvtop|sXjn^X\UabWdpcS^biablZa~lfltvomwwli†€Š{‰nrfr~ntnd[aiiptts^imSeqeVcod|dsx}wlpmk`Yafgt\dU`URNWdRO[NOHdo\bGYiMJ_KYmd`yin~d`U_T]u\SR`fN\`URI[XPYtu]_ekhXba[^qcgjxqsnhvt{„r‚ƒzˆŽ~|‰‡yn‰tkstˆ…‡‘„•y}ŒŽ‡‘›„€|Œ…sstxro““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~}~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’‘‘‘‘‘‘‘’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’‘’’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ”ÎÚØØØØښ„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffh\CDDDDARÌÚØØØØÝm=DDDDE8.////+H…ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ”Ûéççççêœ~‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____aR455552FØêççççíg.55557':ƒ€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}z{z|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹’—˜˜˜˜™™’Œ‡‡‡‡‡‡‰’“’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰ˆ………………†“””••”•Š………………„ƒƒƒ‚‚‚„ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|yzz{|{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘‹Ž‘‘‰‡ŽŠ’’“ŽŽ‡‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽ‹‹‹‹‹Œ‹ŽŽŽŽŽŽŽŽŽŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…‡ˆ‡‡‹†‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰„ˆ††Ž…ŒŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰Œ‰‘‰ƒ…†‡Œ‰‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}|}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹ŒŽ‰†††ˆ†‰ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz||||}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒŽ‹ŠŒ‰ŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzzz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{y{}|{~~~}~~~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}}~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}}}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†…………………„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰ŽŠ‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}~€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††……………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx|{{}~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““””””“””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••””•“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””’’“““““’’“”““““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘’’““’““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’‘‘‘‘’’“’“’‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡ƒ‹Šˆ‰‰†……„„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxy}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzop{xy{|{xw{xuwttvutvwuqrqnprpghklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkigfgggihgmgjghehgccbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{}~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__`c_\_]`]^Z^]YY^ba^^ZY_\XWSNMLKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{xvwxwz{}~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSSPMJMNPROMPQQQQRVVQQQTPPNNOLJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTttuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMOPPRQPNNONONOOPQONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKLFDFJKKKHJLLLOMLLNOOOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEBA@@CCDEACEHKOKIIJHGJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:<>><ED=?EA?@A@DEGGGGBDDEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;899;;:@;;><;;<<HL==AA?BC=ADDFBFFDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnpprttsqrwyy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;::;89:87:<978;;>=;;:8:@@AB?A?CFDBCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqususqsxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<979::988::78:9:;;8789;:8<;=@A@=;;><==@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyy{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>=;=<>?=<=;:<===<<<<;;:;<>=>??A@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquuuusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCC@><=?@??=;>=>CE??@=;===<;:=>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVpoqssttuyz{{}~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???CED?=;<@>:;::97:<9==@=:<;;<;89;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pprrrtuvz{}}}~~~}~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC?>AAABA@=<=;>=:::<:8988:;=@?<;;<;::;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFEHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC@?>?@=??><>@?===?==>CD?;<=>@==?AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hloppqtuvy||}||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCDA?@@@?=@><=??@@@C@@?@@>=<=@EABBFHC=<@DCAA?>=@A>>>?<>@DGE@>@A?@CFECBBC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{||}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@A@>;><?=<:>=?BBE@??Na_J@CEIIIILMKECFGHEGEEEDDCA?@>>BFJJGEEFFFJNMKJIGGHKLJGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|{{|~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@DED?<ACDB?>A?ADDDCWu†‰Š~XGHJLLNOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHIHGFEFFFDFHGEEHHFHGHFQnopqrvvy{{{z}}~~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJHIGHHIGFBDFDDCAUt‡‰‡‡†ˆ‚WILMLMMLJGGGGDGGGGFHFHECDDFEDDHHCCCGJJKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrtwwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLKJKMJKHHFFGFEPl„‡†††‡‡ˆ‡|PKLKHGFFDECC@ACCCCFFEB@>>@AA@BD???DFHDEGIKIIGHIGIIIJIHFJJJJIJIJJJFILLJJKKfopsstvxy{{{||}~~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKKKKKMLKMLIFJVl†…„„†††‡ˆ†ŠuIIFB??@??><<<>::<AA@><998<<=;>;9;?ABAACCC@ABEDBCFHIHHHLMKGIJMMNMJJKKJLMSlortsswyz{{|}}~~}}}}}~~~~€~€€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHGIHKLONNQNQ^r…ƒ„……†‡ˆˆˆ‰‰ŒŽfBB=88::9878896479;<:8567789787689;;<>A;999==>;;=ACEHJMLLGIHORQPPNLMMOQ]oprtsuxz{{||~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@BFHKHLKNTg{„„ƒ‚ƒ„†‰Š‹‹‹Š‰Š‹Œ‰T;8656766646763468:876565677778:7778:;7689989876:<@GFIFIFEFOSRSSROPORTepqsttwy{|{|}~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:<DBDFCCVx„„‚‚ƒ‚…‰ŠŠ‰‰ŠŠŠŠ‹‰‰ŠH676468874578467799766765::;::<89899877:::8878589;A=>>BA?AKLOQPQOOPQWkrrttuwz{{{}}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897:A9<GR`|„ƒƒ„„„†‰ŠŠˆ‡ˆˆ‰ŠŠŒŠ‰‰Œz>:88;<=>9:;<89;9:;:99;:9===?;;<=:><:<;<;<<::<8::;;999<?<=ABDIJMKJKLWortutvx{{{|{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<:89989999:>=>Ow‚ƒ„„…†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>BCEEBAAB>@CA@?=>>@?>?@?@==?B?AA?A?=@A@??A<><;:;:9;?=;;==AACABCAXpqtttvy{{|}{}~~}}}~~~~~~€€€€€€€€€€~REBAGJNOLIGK:8:;9::;<:::<;=>@>N}‚ƒ„ƒ…„†‰‰ˆ‡†††‡ˆ‰Š‹‹ŠŠŠ‹Š‹^>DGIKJJFGGDFHGECA@CECB@BCB?@DHECEDEEAFEFDFFD@B>=@>=?@>???>?>>:;=<`qrttuwzz{}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:=:<:==>>;><?>B?L~ƒ„…†††ˆ‰ˆˆ‡†††‡‰ŠŠ‹ŒŒŒ‹ŠŠ‡WGLLMKNIIKHIJJIFDDFGFDCEFDBHIKGHGFGGEKJLIKKJCFCCDBAACBDCCDDCA=<>@hpsttvwzx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLK@BBA97;>;<:=?>?<?>BAD>gƒ‚……‡‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹‹ŠŒPMPMKNKJLIIJHKGEGHHIEEHFFELLMIJGGHIJNMOMLNKHFGGEECFFFFDEHHFCA?@Lmptuvxyyy|||}}~~~}}}}~~~~~€€€€€€€€€€€€QA?>?FGG=<@@87<:;<:=?<==?@CBHS~ƒ„„…††‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒ‹ŠqMQOMLLLLJIHFJJEJHGKJHJGGGKLNLLHHIJMPNONLOKIGIJHIDIHHFFGGIGCBACUoquvxz{xxzz||}~~~~}~}~~~~~€€€€€€€€€€€€€TDAABGHB?8?@8:;7<=:<?<<=?BCCLm„ƒ„„……†‡ˆˆˆˆˆ‡†ˆˆˆˆˆ‰ŒŒ‹ŒŒ‹‹‹‹‹^RRPMNMKJGFCHJGLJGKOLKJJLMLOPNHIKLOQPPQOOJIJJLJLFGHGFGIFEEB@BB\prwxyzyyyzz{{~~~~~}}}}~~~~€€€€€€€€€€€€€€€~UECEEGGED;?A;=<8?==>@ED=BDCFJt†ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹‹ŒŒŒŒ‹‹|WVRRTROLKJEFFKONOWVQPOQSRMSTOMSLPSUWRSRPLKMMMKNGGJFFIJDDEEBDCcquyyzzz{z{z{|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?=<A?AADTKBHIFIKx†ƒ……„…‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŽ‹‹‹gVVkaERQQPJ;;QSR`u]UVTVYYRXXRZfPUWZ]RTWQPNRPPPQKKKGHJHEFIIIHIjsvyyzyz{{|z{|}|}~}}}}}}~€€€€€€€€€~~THJIIGGFE??A@EACFDCDKVPJOONPQy†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ}aŠ‹‹‡l[dU:XXXSP?@VUY\d`VYbr^]V]ZVEQYZ\Y_TYgRUVXTTVSOOMKLJIILMKOMSotvxyxwyzz{z{|}|~~}~}}}~}~€€€€€€€€€€~~~~VJJIHGFDDBA?HLIMPKIJOSQPTVUWUv…„…………†‡ˆ‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~Œ‰Š‹znpXZ[ZRSRWVTZZuƒYU}a\X]^WIV^^[[_YHYXY\]XXYWRQMPQMMOSQQURassvwwvxyxz{{|}}}~}~}}}~~€€€€€€€€€€€xy}YNKJIIFBD@A:OQQWXPPPQRSRVWWXXm‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡ƒŠ~fYY\YSVTWRQWVc–€QerXZW_hP`fZZX\hbGOZig][\]]WSNSPPQVVVVYZosuwvvtwxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZZRSQOQRQURUSV_ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PVXTRTRQQLOMKfyZ]TYUV]ZLTZUST^ZXWWWzkXZ\\^SPPPINOWVX[Zdqtvvttvxyy{{||}}~}~}~}}~€€€~~zxwvsu{€€tk~~kqy^[VUSROKFCDAM^ƒlVRSOOQOQVQSRRTcdv€ƒ‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ymqVIKNNKMKHJDFHEC>ScURQQNKRURMOYQMNQSUUMQSRPNLLHCIGRSTZ]mrvvuttw{zz{{}{}}}~}}}~}~€}}~~€~{vsw}~~du}iqt`d]^[YUQLILIal’tPQSMQRPS[RSRQRUUbs{|~€‚}{{€ƒ‚…†‡‚†††„†…†u_]KC>BBCCA?DPCC@C>BHGV@INMG]iQHFOFDEFHGHBCHGHJGDBAC@NPMRdtuvustvy|z{{{||}|{~}}}~~€€€||}€€€}vt{mh|gnqfheeb\XSQPURsWe[OONLQRPUYSUQQTROV`klsvz{xytrnstsyx~~ƒ€ƒƒ‚‚€‚kLG>>::>@?>>>jPKaEFHIEB?HMMGMQUJBE?><=<==?=?ACB??<=B>IMFUouuvttvxz|z}{|}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QQZ\Y^IJOPNKLQRQTUUWQQWVPX[b]agmmlnjh`nrimlqu{z}{xz||xwxdB@@A<:BCAACA[\O{NOONKLMOOPLKLWNHGAA<977599=;;;8989?;AG>\tuvvuvwy|||}|||}~}|}}}}~}xuwz{zwyxuw{|yxuywcqhipmnmmhf^OO^\ZIGOQQOMPQNQRSVXSRYTNYZ[WY\_^_e_]^qwk^`gkwooljonnlfbYGFFHBAFHEEFCLQOaWRXQPSSRU[OOQWPMJDF>:96587979:365795<B=ftuwxwzy{}}||{|}}~~{}~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZWMKSTSPQUOLRSTWXSTXQLXYYVXXVXY]WXXhsk]V`tkaa_]d`_^YUPMOMLIGJKIHFCPOSZWTTNQSYS\eUOSTQNKIHC?A9988978847578599Gnruyyz{{}}}}|{}|}~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPWVVSTVOOUVWXYSUTLKSUUUUWPTUWTUR]n^RNY`[VY;DUWT[fJLPRROMMNMMLJFPPUYSTOJNOUST\VRUSSOMLIHHF?>=:787659967565Wqqtxzz{|}}}~||}|~}}y}}|~~~}||}}~}|rvqxxruuqqnppopuvtnjddjppqrpnfedc\^RTZVWTSVTRXWYYYRUOIGOPOOMRJOPOONNOTLMIPPSTU2<XMIAQ=c`QSQPNPPONNMPNTRPRLILKORPQRSTQSOLMKLLHCBA=:9876;B4566;eprvxy{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqpuuvcjgeWhtrrqniihpVVTUXUVURWVUZYXWVQSFFAFGGHFJDHJHGEHLHKIGLMPMG/E_R=3@>joaRRQ@GTQOPPQNQOPOLJLLOPNMPQQNPOJLMMKGEECB;==<9=G6676Dnquwz{{||}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknbePSTRSUOWVUYYVQQQO@>;=?@BAC@BEDA@GHGHFFHJMLDGCORB8DMS]gSQSAGUPOQQPMMNLJLKLNOOQLNNMIMLIKKLKGFFED<AA>;@E;<89Trsuy{{{|||{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLONMQSLTUTWWULLKH=987;?A>==@@B=>EHFDFFIGJJ@FAA@EGDIOHQRa\QPROSNOOLLOMKMLMON[VKMQOHJHCIJLLKFFFE?BC>=BG?B?@druw{z{{|{zzw|wy}~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCE=9879?B?;>A@@>ADIECHGIGIEBB?><BA@GJEMObePMOMWKLNKKMMLLKNNSdMJLRIIIEBIJLMNJGIFBBB@?EFEHDLopvzyyz{z|zwtxtx||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGLLIMPMPOHKE?B=999:?B?<ABAADDGKFDIIGGHCC?B>??@>CEDLMQTLJIMTFIIJLIJKIJLMOPQPKGCKGCCKJLNONIJIGCCCDIJMLIZsnxyxzz{y|vrpurtyyvxjqnjllnttmsu{stxronqovsnporpopstyjN`gsjt|ygosqiqheqHJCFGHGJKIJLDGB<>=:::;AB?=BBCCHEJLJEIIFGHCC;A@B>@?BDDIMOGHJGHKDHIKMHJLHIJLJM]RHIDNGBELKNNQNKMJKFGGJMNRNMcnjwvw{y{z}qmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoijthepFJCFEFDEEFEGCC@=<=:;:;AD@?BCEEIFJJLFIIGFFDB:ACC>?CCCDGKNHJNHDHEILNMHILGFFIILNKIHEOICGNMPNPNNOMKIHIOSQRNSggfrosxv{z|lhjoekpmsqfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhmf_pGJCEEDBBAE@DB>?>;;;=;=?DB?ACFGKGJILHGGGFEC?=DEB>ACBCEGHIGMPIFFGKNOKFHIFECDIIHKIGHPKDJMMQNONOPNJJIMRUURPXeaamfproryzgehhcilfqlflmgiklsmpvutpnvrosrsutqssutsuvvvyvutvlkuumrvqlnlerMGEDFBA@AD<BA>A=::=?;>?AB?@BEGJFIGIGFFFDCBAAEFCBBBDEEGGHFLPLIOJJLKIFHEFECCHHHKJGKRMCOONQOOONOOKKKPUWVVTY`_]i`minhrsbeffdhhfnifmmhkkmriqvusqmvnoqrswsrstuuvvvwvwvvtwuksunutsprkksMGGEGAA@CD<AA@C<8:=>:?=@B@@@DFHEHFFHFEEDCEBDIFCGEAEGEFFGEJMKHQMJKHHIEFHHECIIJKMKPSNDRSQQRNOMOPMLNSWVWYVX^Z]d`hcjigk_defchggkggkmkmlpqgttursnvoqprtxqssuvu‚‘yvvtxuuwxnouorsuqqipzMGGGHAABEE<@CBD<7:=>;>;AB>??CEFDFDDGECECDFFFJEEIGBGHFGFECFJJGMKLKHJKFIHJHDKKLLNORTOHTUTQTPQMNQNMQWZVZYWZ^ZXa```^hec`deggjhhjghnllomqpiuuxrrpupppruvpusuvu{~}xvtwvvvwplupmsunossyMHHGICACGE<@EBD<8:>>><<BB=@>ABFCECCGDCDDFGGGIFHJHCIHGIGFDHKIFKHMKJKKHKJMKINLNNORUVOLVVTQTRRLOQPOTYZY\ZZ\__]_c^\bdlc`dghr…hgjfjnnponsqjtuxrsstrnpqvrquruus~yŽ}uuvvvvxriuqkrtlqwquKIKHJEBDGE=AGDD@9<>@?>?CB<@>AAGCEDCHDEDFFHHFHGIKJEJHHJHFFLHHHJGLLLLLIMJMNMOLPPQUVWOKVVUSSRQLORRQV[[]^[]^``a`bf]d`fh`ehjdssfjhflprqossnswwpuvtsmoruorspurvrtvuuuwvuwtgtrkqrkrwpwIJLIKGBEDE<AFDDB;??A@@@DA@B>ACHBEDFGEHEFEIHFIHJLHHJJIKJFJKHIJJGKKMLIILKMNNOLOPRUWVMNTVUSRQPMNTSRW[^^_]^``aab`cdeadicdijgv‹lkigmosqpqpprywruutsmmssmqrotuuspswtuuwvuuteqskpqjrvpwJLKKLGCCAE<?EEEC=AACBBCEACDAAEGCHFHFEIFCGJGGJFILHIJMKMLGKIHKKNQKRQLSMJMMNPPPTOWXX[NSQW\ZSVPNTUTTXZ_bb_da^ac^`fcabgnicihhmxvmhinosrpqrrrvtsusssnksqmprotvsqquvuswywutucmtkopjqtpwLMLLLGDA@D>=DEFC?CAEDDFCBEGCCIFBHJIGHJFDKJGHJIIKGJJNKNLILHJMKZfJd\KlRGNM_nUls[qpbwcRPbvuhucavaXnqbdvinzf\lu`lkV`wuhjhhfglmjmojmosrprrqrsrssrtrnltonpqquurqstvvuuywutt`ktkppkqsqyKNJKJFB?@B?<DEFDCCCEEDFBEFGDDKEEJLKIKLGGNIHJKGKJIJJNLMMLLIMLL[sbdp^llULNer]geqlntgpi_aYnmbppbkjjgoqtetnn\pvgpNLryvkaakeelxmkvlnosrprqpqrqrrrtrmmsnnoprutqsstuuutwxvutbmukpplrrqzKLIIGED?AA?=BEFBFCEDEEDCHHGDDKHGKMMJLLFJOHJKJILJJIJMMNMMMKNMM[rponpplkMOPmXNibtrpamov\YlP[mmZqmkomxxtsip]`slqjUuyxoc^kfbgppjioppsspqpqqrrqqrrtlmrmmnorutqtrtuutuuzvutenukpolsrryJKGGEEEBAB=??EGBGDHEEDBFIHHEGKJGMLNJLMGLNIMKHJMIJIJJNONNMLNML\hdu]lqWlMOQnUZk^klvaldtTecNlYl\tpkilxjwuhp]_skhWbcw|oc`ghacityknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtvIMGIEEDCAB<B@BFCGFKGECCHKHHFILKFMKKRRLHMMINJIHNGJJHINOMNLJMMJZtppoqqmlOQRnYskgooqqomt^nXat_nopoqroousttjZ^tcwxrjnzhaacfabjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyytukoumtonssvtIKHJCDDE@@>CCAFCHIMHFCFJLIGFJMLFOJJWRKGKJJNIIJLIKJIIKLMMLIKKKSkbYi^_jcrrZ_Yjo_eeUk_d[abQ`mh\j\niid[oedp]Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunwqrutwrHHFJDECFA@AEDCFBHJLGFDGKLIEFJOLIOJL[QJFHHKMIHJJKKIHIGKKKKGHKJLKLJIKLNT[]TPUMQONOOURPPQOOQJJNPQdqiTYV[[\UYZ]X]\\cfaafbcf_^fkmhmtxrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyyxuvqruovrtsuusGCEGFF@EC?CGDEGCIKLHFDGKLHDGIPKLOKLWMIFEHIJHIKHLJIFHHJHHHEFLHHJNKHO\W^O\\`^OXYS\\b^MYZMXaRKYaZS`d\aX[ddVVX\YZX\VY\^c_d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtOBCDLMBCDBDIEGGFKJKHEEJJJFDGHPJLMJMRIHEAHFJIKKILJIGEJHEFGEEJGBIMIJT_Y`X`a[`UXYT]^Z_RY\P^\YN_\^S[^d^Z]`c_Y_b[`^[UYXZ_^ccbaceiekrpoppnow††……†‚{€……††…†…uqprrsuyyzyyxxxwryvxrqxvtvaSJJMIECBCFGEGGIJJIHDFKJJEEHINJNLHLNGHF>GGLIKKJKKIGEIFCDEBFJD?IKHN[cY^^a_RTSW__\]Y^QY\MV_WKQY[Q[_ba]^ca`bbbcceZRYVW]Z^d`__cebhommllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxXQJFDGEBEGHFGHIFGJGHFHKIKDCKJMMLLHJJHJG?GFNKKKMKKKIGIEE@DAHIA>HIFO]aZ[d]_TQRX]\\\_[KW\LR\YIM^QQ]_bccccb\dcbdceXRWUT]Y[a_^_aa_dlkmjklnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMC@IFCEKIFGGIGGJFFFILJNECKJLNJLIKJIIGBHHQMKKOMKKIHHFE?EBHHA@FECT]Y^X_Y_[]UXXP]]QKJV^X^[]VZaRR__bb``bb_cbbddbXPRRS\T\]]^^___dhgljnnp{{|~{€‚ƒ„………………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKBAGGDFMRHDRKFHHHDFKIMPEGIJKNLLILKJIGDHKQOMLPMLKKIJDEAECHFAAFDAVUE\T^SV_XNTUNZ[MJKT`a[_X_^b]OYb\``_bca]bbW`_TQPQRYS^\[]^_`affelfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDFFHDIScQEW_IGGHDFMJPPFIIJKNLLKMKJJGEINQQNOPMNMNILBDACCFDCACD@LHCLLPONLFMFFHIHGLLMOPILOPPSPLQSRUZXWYWWcVNRTPQPOQUT\YY[^^aaefchdlmqsszy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKN^MHHYMGHJHGMLQQIKJKKNMUNOKKLGGKPTSNPPNOOOHLF`ED^LDfcCL[H^\smOMVmYLCO_TlWgJ]WU^DMQULMSVQRTXVTXTT\TOeZhheZUkTXWU[\\``abbb`gignlhrz|}~„„„ƒƒƒƒ}}zr{z{‚€ƒ„„……„…ƒƒ~z{LIEFFHEEKPTJKG`THJOJIOMRQKMKLORUROPJLNGHMQ[YOPPNPQPJKQQI|YYrsWPmGqnoaVPqqtOBjsnqtpSo_[nX]V\XUkhU]VcY`YZ^UUWituu_av_Yb\\f[_aaab^`cgmol`pwtx‚ƒ„‚}~€vxzmv~tx}€|~€‚„|€ƒz~wwNIEHMMBDLLGJLFRVLKOHLRXWQNOOLQTNOQPKLOGMPS[ZTQROPPPKIZx]TxdhXRSPvftlpbnfkRrNLwmjrpsrqrpoo€]ezuxqqzq~r}ku}aRh|essoss|}p~xor```bb[aahlnkblfgmw~€ƒ~{xw€tvzhr~nt|~wx{~€ƒx|u|||ssNKF`]GAEMMHKKHJQOMNJNV^YULQSNYYLSRRNLPIQRTYWWPTPPQRKHgxlcxqmZJLTypumubnvPddHevqmwo€jfxxiWrQhzmijzz}lxzphnXuujvup€ash}ilx|o___cb\_degjjehbcdllppstsssyqrxbltgry{ssuy~svzn|}yxrnMJRtNCBEPQHKLJLQOOOMPZ`ZXKTWPa^RVQYSMPJSTUXWWPUPONRJKrouuquqch`UnKqp^GhyWvTKhx}w`y{sna]modSgrunmypwlvstqlm\s~zkmy|lun|lqvux^__b_]_edighfe^bbiiijknokqnmjpacfdowxompsynqpj{ztromKKZVHGEGRQKMNLLQQPPPQW\YUNVYUfXRRY^TMNJTTVWYWOSOONQIRmHiwK`dvvTVlNnl{rajguTKVkg|lmlx_Zpz{_`zscroxqhd|ir{]TKk_vuljv|{m~yk|p]^^b[_bdegffec[ccikkrsrwgmihdg`alagsrlglmr|kmhk{tmmkmOGJKHJHHRQMOPLLSSROSRXRWTPWZVVTTTa`QONKTSSQVVOOMNOQJHQMOULKKRSRQROVUQQORRXXPMOUTWXX[[UQRW[WXW[ORTWWXQ]XV\UTOXRWWXYZ`\gr_[[[]]_cZ_ccegdddcZdbgffmnmuffgc`f^]g`dlhfgkhpzhggkujhgilPIKKLMKJTRNRQPLVVTPTUXUZVR[]VUTWUYXOOLNWTPNUSNPNLQPKIQQKQMJJOQTQPQSRJHMOPQRPPPTVRXW\WSRPQUUUSZQNRQWUSYVTXTSQTSUUYYX^Z_a]\[Z\\`c\]bcdgeeebY`acabhhjncad^_c]Zc\bma^ffgmsdihkkedcfhQJKKNOLMTQOTQRMXWUTVXWWZVS\`VWVYUXTQPKOXSPNUPNQNLSPMNUSNQNMNQSPTPRTTNKMORTTQQQUWUYZ[ZSURTXWVY\SOSTWUTYUVXTRQWUVX\Z\`]WY_]^]\]`a^[bbchgfebX``b]`hegea^_]]^ZZ_Z_g`^^]chkahfhfd`bdbPKMLPQLOTPPTQOQZYXWYZZXYV]jdVXYZWVSTOKOVTPOTPPQNMRQOQXTQQOMORTNWQSTUONNQTVURSRTXVZ]\ZVVQRWXU[[VPSUUUVXSWWTRQXVV[_[^`_V_]^`]\`___ZbcehheebYb`b^^fdc`b]\\\\YZ[X[a[^]]_b__bddbd__`\PMNNRQMRSPSUQOV\ZZW[[\YZ[dqmhd_[YVVXRMNWSMMROQROMPSQUZUTPPLPWUQVRSRXMOPRUXUTTSTYX[^]\[VROUVU[[VQSVTVXTSXZSRQYWW]_[```Vb\`a]`b_\`]cachief`Zc`a__ee_`c[Z\[\ZZYYW\Z\[`^`[^^a`_c\Y`ZQNONVQPUSPUTSPW\\\Y^\_W\^jpwy€c\[VVYRNPWSNQQPRTRLQTSY[WUORNSXUSQTQRYOQSSV[UVVSVZX]^\\^VSNTVV[[UQTTUWXRSY\TRR\XZ]^]ba`Wb[cb^ac_\bab_dgieg]\d`a`acd_b_YZ_[\[XXYWWZZZa]][]\\Z]`W[[ZPOOOYPUUSRXSTP[]^]\`\`U\\hjr}slh\UYWQOR[SRQTRTUTKRVUZZZSOSQUUTRNUQRZRTUTX]WXXSX\X^]YZ]UUNVVW^ZXQTTWXXSVY\TRV]Y]]a^cc_Y`[eb_dd^^cca^efief^^daaabcd_b^X[_[\[XXXXW[Z[`][[\[XZ[^V^Y]POORZPZUVWVTTT^^`_^b]`U]^bkyum}lZUZVQQT\TTTUTVYWLRZV\Z\RPUSWUUROWQSWSWUV[^X[YUZ^X_^Y\YRWRYXY_YYRTUYYYUWY\UTZ]]^ab`ed]^]]eabfd^_dc`\gehfdb`ea_aabb_`^WY^Z\\ZYYWV]Z]^[Z[\[WY\]VXW]SOPWYQ]UVYWWUX_`aa`c]`U]^beev‚{hXYZTVTV\XWWVVW]XOU\Y^]]TSXSWUTRSWQSVTXXX^^X][U]_X__X\VQYTYZZaX[TVX[YZXYYZWV]_`_dcbee^b\`fbdfd_`dba[fchfdfaf__abaa`_^VU]Y[\[Y\YY][[[XXY[YZZ]_]TY]UNTZWT\UWWYWV\`aacac__V[`da_zuohZ\ZVXVX[ZY[YXY`VOT][`a\UUYPTVTRVUQSUW[[\__Z_\V__Y]^Y^VSYWYY\bY]UVZ\Z[ZZYZXY__``dcdeecdZbfcgfe^ab`c]bciedh_g^bbcaa`^_XTZZZ[[X\XX\[Z[WWZXW\[\`]V]]SOVZVVZVYVXWX]_badada^YYadb`kfh^\][WWYZ\\\_[Y[bVSW^]ac\SVYPVUUUVUSUTX]]_``]a]Wa^[^\[^XVXW[Z__[^WX\\\]][Z\WZ_a^`eddffgcYcfehgd^c`_ec]fidei_g^cbcaa`__[XY[YZYXZXW[[Z[WXZTZ]\[`\U^bMRWYVWZY[\YWY^`baeada]^Yacb_a`a_]]]XW[[]]__\Z]cXYX]`cd_RXYPWUWXWVVWV]]^aba_b^Ya]]^Y\]YXUV[[`^\_YY^]^^`\ZZY[_b_bedefghcZefgigc_c^`feZiicficf_bbca``_]]ZX[YYXXZYWZ[ZYWYVU[]]]``bbxKWW\YW]\\]ZW\]_`bdbca]`Xbcb`cac^\]\XW[\_]`_][`d\\XZbecaR\YOXVY[YYWZZ`^abc`ac_\b]_][^]YYTX]\__^_[Z^^`bb[[W[]`bbcedgffge]eghifcab\cg`\iichife`baca_`_]]\Y\YXWXYYW\[ZWWXPXZ]acffrkJYW][Z_]\^\Y][^_bcbaa]b[bdb`cbb]\[ZWXjq`\`_]\ac_^YYcedbT_ZQYW\]\[Y[[c`ccc`bda`c^`\^^^ZXU[^\\aa_][`abfb^[S\_`cddfeggfff`fghhgdd`[fg^ahhcihfc`b`cb___]][Z[YXXXVZW\[ZVVULXX\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ‡‰‡…‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vvvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyy{{{{{{{{{{{{{{{{{|{{{{{{{{{{||||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vvvvvvvwwvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyy{{{{{{{{|{{{{|{||{{{{{{zz{{{|||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||upooooppz~}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÖ½†‰‰‰‰Š‡sqrrrrqƒŠ‰‰‰‰ŠŒŽŽŽ‰~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}upnoooooz€~†“y1333332j‚€€€{­éääääèʉŒŒŒŒŒ‰rooooon…ŒŒŒŒŒŽ‹}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}vuuuuuuuvwwwwwwxyyyzyzxopppppprrrrrrrwzyyzzz~ƒƒƒƒƒ„|||||||zzzzyyy{}||||||}}}~~}}|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚‚‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vvvvvvywvvz{x{xwvvxyzzz~yyyxxxxyyyyzzyyyyzzzyxxyyyyy{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwww||}|z}{xwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwwy~|}}y}zxxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z|yww{~}||z{zwxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚ƒ‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{yzzx{}}|{}{xxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyywxzzzz{xxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyxyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{|||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}|}}}|||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹ŠŠ‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„…‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰…„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚€€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrstuttssrrsrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqstsssrqqppnnnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqqrssssqpqpoonnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrqrrssrrqppoopoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpppqrrqqqpopooppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqpqqqqqqpooppppppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqqqqqpppppppppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsquŒ‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqqqpqqqqpqpqpqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtsttttww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrqqqqqrqqqrrqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrssrrrrrstrrsrsssssssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz|~~|vvwwvuxzxxxxwwwvx|yy|zyy|{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~|{{z{|{}|{{{{{{zyxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}|||~|}~~~~~}}||}ƒ€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹ˆŠ††ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€€€€‚€€~~~~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~~€€€~~~~}~~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~~~~€~~~~~~~~~€€€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹ŠŠ‹‹‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚‚‚€€€€€€€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒŽ‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒƒ‚„„‚ƒ‚‡ƒ‚‚€‚‚‚‚ƒ‚‚ƒ‚ƒ‚ƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒ‚ƒ€‚ƒ‚…………††‡†…††‡‡‡†††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠ‡‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„„ƒ‚ƒ…ƒ‚‚„…‡‡‡‡††‡‡‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ‘‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„„ƒƒƒƒ„…„„……„ƒƒ„……‚„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘’’ŽŽ‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€ƒ‚‚‚‚‚‚‚ƒ€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„…„„…„…†’“‘ŽŽŽŽ‰‰‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~~€‚€‚‚€€€€~€‚€‚ƒƒ€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“‘Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚„‚‚ƒ„‚ƒ„……„‚„‚€‚‚‚„ƒ‚ƒ‚‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘‘ŽŒ‡…ƒƒƒ‚‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒ‚€ƒ‚ƒ……ƒƒƒ„ƒ„ƒƒ„„…„„„‚€‚ƒ‚‚„ƒƒ‚‚„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…………………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”“’’ŒŠ…„„ƒƒ‚‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~€€‚€€€‚‚‚‚‚‚€‚‚‚‚‚‚ƒƒ‚‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†”“’”’‹‡„„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~€€€€€€ƒ€‚„ƒ‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“‘Š†ƒƒƒ„‚‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€€€ƒ‚‚ƒ‚‚‚ƒƒƒ„‚ƒƒƒ‚€€€‚‚‚‚‚‚‚ƒƒƒ‚ƒƒ„‚‚‚ƒƒƒ‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†ƒ„ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……„ƒ„…ƒƒ„…„‚‚‚ƒ‚‚„‚‚†…ƒ…ƒƒ„„„†…„„…‚}}}~‚„ƒƒƒƒƒƒƒƒƒ„„„ƒ‚„„„„ƒ„„„ƒ„ƒƒ…†………„……………„††…††…………………………††…†††…†††‡†…………ƒ„„„‡““’‘’Œ‹ˆ…………‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒ„ƒƒƒ„…ƒ‚ƒ„……†…††…†‡‡†ƒ~~~~~ƒ„ƒƒ„„„„„„„„„„„„………„…„†……†…†††…†……‡……††††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„ƒƒƒ…………‡‡……‡…~€„…„…†††…………††‡††…†……†‡‡‡ˆ‡‡‡†††‡‡‡†††‡‡††…„ƒ„……†„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘“’‘‹ˆˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒƒ„ƒƒ‚„…„…‡‡…„‚€€€……†‡ˆˆ‡‡‡‡ˆˆˆ‡ˆˆˆ††‡ˆˆ‰‰‰ˆ‡†‡‡‡ˆˆ†‡†‡‡†‡…„ƒ„…††………†††‡‡…†‡†‡†‡‡‡‡‡‡‡‡‡…‡““‘‘‹‡†…†„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡‡…ƒƒ…„ƒƒƒ‚„„„„…„€‚€€~{z€†ˆˆŠŠ‰‰ˆˆ‰‰‰‰Š‹Šˆˆˆ‰Š‹‹ŠŠˆˆ‡ˆˆˆ‡‡ˆ‡‡ˆ†‡†„ƒƒ…‡‡‡†……„„„……„……†„„„………†…†…ƒ‰”“Ž‘ŽŠ†…†…ƒ‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡‡„„…„ƒƒ…ƒ…„ƒƒ‚‚‚‚‚‚€~|}}}~|{|ƒ‡‰‹‹ŠŠŠˆ‰Š‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰‡†††‡…†ˆˆ‰ˆ‡†‡„ƒ‚„ˆˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚‚ƒ‚„ƒ„ƒŽ“’‹ˆ…„†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„……„„…„ƒ‚‚‚‚‚ƒ~}~~~~~~}|~}}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡ˆ‰‡ˆ†ˆ‡‡‰ˆ„ƒ„ƒ…„„……†ˆ‡†…ƒ‚‚„…‡†‡††„‚‚ƒ„‚ƒ„…‚‚ƒƒ„ƒ„‘’‘Ž‹‡„††ƒ‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…†ˆ‹Š†…†„‚†…„…ƒƒƒƒƒ‚‚}|}€~~~}|}}|z|„†‡†„ƒ‚ƒ„………ƒƒ…„„„„…„…„‚‚ƒ‚„„‚ƒƒ…†…„‚‚‚ƒƒ…ƒ„„…„„†ƒ„„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰†„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………†‡ˆ‡†€…ƒƒ„…„‡ˆ…ƒ€€Œ†ƒƒƒƒ‚‚€}}€€}~~}}}}zzz~ƒ„„‚€‚‚~‚ƒ€‚‚‚‚ƒƒ€€€ƒ‚€€€€‚‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†Œ“‘Ž‹ˆ……ƒ‚„‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€ƒ‚~~~|‡ƒƒ‚ƒ‚ƒ}}~€€€~}}}}~}|zzz‚‚€~€~}€€€€€}}€~€€€€€€‚€€‚‚‚€‚„ƒ†’ŽŠ‡‡†ƒƒ‚‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒ‚ƒ„…€|}}~}}~€€~}~}{}~ƒƒ‚‚}}~~€€€~}}}|{{{zzyz€€~~~~}~~€~€€~}~~}|~€~~€€€~€€~€€…’’Ž‹‹‡‰…„ƒ‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~~~~€€~€}}„ƒ‚€~}~~€€€~}}}}{{|zzyyy{~~}~€€~€€‚€|~~~~}|€~~€~~€€~€~~~~~}||}…’’Œ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒƒ‚ƒƒƒƒƒ€€€€€€€€€~€„ƒ‚‚ƒ„„ƒ„€€€€€‚‚ƒ€€‚ƒƒ€€}}}~~~~}}}}}|||{zzyyy}€€€€€€‚‚€~€~~~~~€‚€€€~€~~€}~}}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…ƒƒƒƒ…„„„„ƒƒƒƒ‚‚‚‚~~}}}~~€}}}}}}}}|{zyyyyy€‚‚‚…ƒ€‚ƒ€‚€ƒ‚ƒƒ‚€€€ƒ„‚€€€€€€‚‚€€€€€€~~||Š“Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒ‚‚‚€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…ƒ„…„…†††††……†€ƒƒƒ‚‚€}}}}}}~~}}}}}}}}}|{yyyyx|‚ƒ„…‚„ƒ‚‚ƒ…†‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚‚„ƒ‚ƒ‚‚‚‚€€€~Ž“Œ‡ˆ‡ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€€~}}}~~~€ƒ„‡ˆ„†††…††‡‡†‡‡‡‡†‡‡}€€‚~}}}}}}}}}}}}||~~~|{yxwxyy€ƒƒƒ„ƒ„„„——ƒƒ„}~‚‚‚‚ƒ†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ……„…ƒ‚ƒƒ‚ƒƒ‚‚‚‚ƒƒ‚‚’‹ˆˆ‡ˆ‡††„†…„„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€~}~€‚………††‡‡†‡‡ˆ†‡‡‡†‡‡‡|}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yxy|~‰–„ƒƒ„„”“€~~„‹€€€„†‰…„‚‚……‹ƒ‚……††„ƒ……ƒ„„ƒƒ„ƒ…„„ˆ’Ž‹‰ˆˆ‰‡‡‡…†…„…„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„„†…||||}}||}}}}}}}}}}||‘•–ƒ{z„”|xyz{|‚ƒ‚€ƒ‚€~|~~{ˆ‘||Ž–}‚†Š…ƒƒ„ƒƒ‰}ƒ„……ƒ…†…„……ƒ„……†„„Ž‘‹ŠŠŒ‰‰‰‡…†…ƒƒ‚‚‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚ƒ„ƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚ƒ}}||}}|||}||}|}}}|||{‹‘—Œz{|zzz{|yy}}~€€|{{~~}‚•‘„ˆ~|~‚„||‚„‚€‡ƒ}‚€‚‚€ƒƒ„„„„„‚„ƒ„…‚„‘‘‹ŒŒŽŠ‰‰………ƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚‚ƒ…ƒƒ…………ƒƒƒ„‚ƒƒ‚ƒ‚‚€€€~~~~}||||||||||||||}|||~~Š‚{z{zxz{{|}{~}~}}}}||}†~}‚~~€‚||€‚€~|{Š‚}€~€€‚‚€€€€‹“‹‹Žˆˆ‡……„„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€|zx{€‚ƒ…„ƒ…„††„„€†”ˆ€€~~~€|||||||||||||}|||||||y{{{xxy{zz|€~|~~}€‚‚€€€‚‘€€~€~~~€}}}{}}}}}||}€€€~€~~‚”‘‹ŒŠ…††…„„…ƒƒƒ‚ƒƒƒƒ‚‚€€€€€€€€}{z}€€€x~w{€‚‚‚‚ƒ†‡††~ˆ•Š~€€~€~~~|{{|||||||||~}|{||||{|||zzy{|z}…ƒ‚~~€~…‚~€~~€…†‚€~~ƒ‡}|~€€€~}}}}~{{}€}~€Œ‘‹Œ‡„††…„„„ƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}~€‚ƒ††……~€€€~~~€€€€}}||}~}|}}}}}}|~|}|{}||z{z|}}†„‚€€}~}~~‹„†~}||~‚}}}}€|{}|~„ƒ€~~~~}}~}~€~~~„’ŒŒ‹ŽŒ‹Š†„†„„ƒƒƒƒ‚ƒ‚ƒ‚ƒ‚€}|||}~{{}w~vx~}|}|}~~‚ƒ€z}}|~€€~€~~€€€€~~~~~~}~~}|~}~}}|{|||z{z}~€„ƒ‚~|}|}||ƒ~Œ~|{{}~}~~}{{{}|z{{{€†„‚„ƒ‚€~‚‚‚‚‚€ŠŒŠŠŒ‹Šˆ„„„ƒ„ƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€€€€}€~~~|‚~~}}}{{}}|z||~€‚€€€||}|||||}|}{~{{{|||}|{{{{||zz}z~‚ƒ„‚‚…†……††‡…‚„‘ŽŒŠ‰Š‡‡…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~~€€‚€~~€€~}ƒ||}}|}}}}{|~~~~}~|||||||~~{|{||||}|}|~|}||{{|y{|{{}{}~~€€ƒ‡‰‰‰Š‰Š‰…ˆ‘‹‡ˆ†……ƒ‚‚ƒ„„ƒƒ‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€~~~}€€€€ƒ‚€€€€€€€€~|z|}}~}}~~Œ†}}~{{ƒ‚}}}}}|}|}}}~|}{}|}}~|~}}}}|{{z|{||{z{{zzz{~~ƒ…ˆ‡ˆŠ‹‹Š‰ŒŒˆˆ†…„ƒ‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„„€€€€‚~}~€~{~‘Œ|}Š€Œ~~}}}~}}~}|||}}|}|}}}~}}~~|{{{||}|{z{|yzyxy{~„ƒ„‡‰Šˆ‰ŒŠˆˆ…„„ƒ‚‚‚‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{|||~~}}€€€‚…ƒ„‚‚‚€€ƒ‚€}~€~|ˆ‚~ƒ„„ƒ~}|‡}}~}||~|}}|}}~~}~}}}{|}~||{|}zzyyzy{{~~€ƒ‡„ˆŒ‰‰†…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{|}}}}zx‚€‚‚€€€€€‚‚‚‚……„‚ƒ€‚„~€}~~}~€€}~„€~~}~}}Š…}~~}~~€}}}|~~~}€}}}|}||{|}{{{zzz{{|}~}€ƒ€‰Œ‰Š‡………„ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv~€ƒ‚‚‚‚‚ƒƒƒ‚…†„‚€€€€‚€„~~€€}~€~}~~€€~€€}~€~€~|}}|~~~~€}‚€|}€}||}}||{||{{{|{|||}|‰‰‡‡…†……„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€ƒ€€€€ƒ~~€€}€}}~~€€‚€€€}€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{|~|}|||{|{|~‰…†„…‡…„…„‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz}}yxtt€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚~~~€}~€}}}~€€‚€€€‚}~€€€€€~}}}~}~~}}„€~}€}}~}~~}~|{|z|{z€…‚ƒ„…„„„…ƒ‚‚‚€€‚‚ƒ‚‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}}~~{{z~‰‡~xry}qzx{xytu}‚ƒ‚ƒƒƒƒ…„…„ƒƒ„„ƒƒ„‚€€€~}}~€~~~€}}|}}~€€€€‚€€€ƒ€~€~€€~~~~~~~~……€€€ƒ~€~€~€~}{z{z|{z‚ƒ‚‚‚‚ƒ‚ƒ‚€€‚€€‚ƒ‚ƒ„ƒ„‚„‚‚‚‚~€~}~~~~}~}}z{|…„{{sy{|pwuvwyvtz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€~€}}}~}~~}~|}}~€€€€€ƒ‚€~€€€€€€€€‚‚‚„€ƒ€€|{{z|{|€€‚‚€~‚‚ƒƒƒ‚„‚„‚€‚€~€€}~~}}}~}}{{z€x|vyz|qtxwvxury……‚„„‚„……†„„‚„ƒƒ‚€€~€€|}}~€}~~}|~~~~€€ƒƒƒ€‚€€€€€€€€‚ƒ€„}ƒ„€€‚}z{{||}}€|~}€€~}}€~‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxzzruyyvwwsu†…ƒ……‚„„…„„„‚ƒ‚ƒ€~€~€}}}~~€~~}|€|~€~€‚ƒ€€‚ƒ„‚€€€€€‚ƒ‚ƒ€~‚‚„€€‚‚‚„~{{|||}}}~}z~}~y~|||~}~€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„‚„„…ƒƒ‚ƒƒ€}~}}}€~~~}}€€~|~~~‚‚ƒ‡…~~€€€€€€‚‚€€~€‚~‚‚ƒ‚ƒƒ…‚}}}|{||yz{z~y|yx~{{{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst†„„…ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€|€€~€}~}~€€€~|~€€€~}~~€}€€ƒ„ƒ~}~~~€€€‚€~~€‚‚€„‚„…†ƒ€~}||||zyvyyzyvyv~|{{{~|{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„……ƒƒƒƒƒƒ‚‚ƒ‚ƒ‚€~€}}}}€€€|€€€€}€~~~}~~‚‚~~}~~~~€}€€~~~~~€‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{z{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvqwyrx…………ƒ„„‚‚ƒ‚‚€ƒ€€~~~~€~}~|~€€€€{€~€€€}€~~}}}~€~~~~}}}~~|~€~~~‚~~€€ƒ‚ƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}}{|z{}zzx{|zz{xtxuqrtpxxqy„………ƒ„ƒ‚ƒƒ‚‚‚€€€}~~€}|~}€€‚€|€€~€}€~~}}|€€€€€~~~~}|~~~|}€~}~€‚~€€~ƒ‚‚ƒ……‚‚~}}{{||yw{ywxwwx{{z{|…Š}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzz{zxswuqqspxwq{…†……ƒ…‚ƒƒ‚€€€€~~}|~}€€‚€}~€~€€€}~|}€€€€~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{|||zzzzzzxsvupprowvr{…‡„…ƒ„‚ƒ‚‚‚‚‚€€}}~€‚}~~~€€‚€€€~}~|€€€€€~}~~€€‚€€€€€„‚‚€~|}~~z}„~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚‚€€€€€€~}€€‚‚‚€~€€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€€‚€€~}~{’Œz|}|{}y{zzxyxy{||}|||||||}}}||}|~}~~~}|z||{|}{yzzzyysuuooqpwst}…†ƒƒ‚ƒ‚€€‚‚‚€‚‚€€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€€‚‚€€€}~|†‰||~{{~yz{z{~wwy{|{}||||{}|}}}}|}|~~~~|z|}{}}{yz{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}€~~€€€€€€€‚‚‚€€€€€€}~€}€ƒ‚{~~{{}{z||{‡yxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€€€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ„„€~‚€€€€€‚~€€‚€€€€€€€€€~}€€€€€€€€€€€‚€€€€€~}~}~~{}|}{||wxuxxy{||}|||||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒƒƒƒ‚‚ƒ€‚…ƒƒ„ƒ‚‚‚€€€‚ƒ‚€‚‚…ƒ€~‚ƒ€€€€€€€€‚€€~€€€€€€€€€€€€€€€€€€€€€€‚‚‚‚€‚‚€€€‡~~|z}|{}~xwvyyy|}||}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚ƒ„„€€‚†ƒ„ƒ‚„€„ƒ‚‚€€‚‚„‚‚„‚€€ƒ‚€€€€ƒ~€ƒ‚}‚€€€~€€€€€€‚‚€‚ƒ‚‚ƒƒƒ‚€€€„}}}{}z}€zyvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysruowqwysw{…‚‚ƒ‚ƒ„‚ƒ„ƒ€€‚ƒ†ƒƒƒ‚‚„„ƒ‚€€‚ƒ‚‚‚~€€‚‚‚‚€€€€€‚„€~ƒ€ƒ‚€~€‚ƒ‚€ƒ‚ƒ‚ƒ‚‚„€ƒ‚„ƒƒ„„ƒƒ„ƒƒ‚€‚€}€|z|{{w|yyy{z}~}||||}~~€€€„„€}€~{{{z{ztpxrytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚‚„†„‚ƒƒƒ„„„€ƒ€ƒ‚‚‚‚‚€‚€~€€‚‚‚‚‚€‚ƒ‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚‚„ƒƒ„‚„‚ƒ‚‚‚‚ƒƒ„ƒ„„„„„…ƒ„‚ƒ‚‚ƒ€€~||€||x|yzyz|}|{||}}}||€€€€€‚~€€€€z{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚‚…„„ƒƒ‚ƒ„„…‚‚‚ƒƒ‚‚‚€€}€€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€ƒ€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒƒƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{~~}y|zzz}||}z||}}|z{~~~€€€€€€€€€}}||}|vrvxxvtvt}‡‡ƒ‚„…ƒƒ„…„€‚„…„„ƒ‚ƒ„„€„…ƒ‚‚‚ƒƒ‚ƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚‚‚ƒ„‚‚€€‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚~ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz{}}||z|~}|}}~~€€€€~~€€€€~|}}~~}|{xvuv„‡ƒ‚ƒ…ƒƒ„†„‚…†…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„‚‚‚‚ƒƒ‚ƒƒ‚‚„„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒ„„„„„„„„ƒƒ„…„„„ƒ‚€}‚€}||{||€}}~€~~}~|||}}~~~€}}~€~~}}}~}}~~€||€‚‚ƒƒ†ƒ„ƒ†„‚ˆ‡…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒƒ‚‚ƒƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ€‚„„…ƒ‚‚ƒƒƒ„ƒƒƒ„ƒ„„„…„„„…………„ƒƒƒ}„€}}||||~}~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒ„…ƒ„ƒ…~‚Š‹…„„ƒ‚ƒ…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…‚„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ…ƒƒ……„……‡‡†‡…„„…„ƒ~}|~}}€~||~~|z|}}}}}~~~€}}|€€~~~~~€‚€……„ƒ…„‚„ƒ†€‚……‹‰„„ƒ„……ƒ‡††„„„„…„…„„ƒ„ƒ‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ„}uzƒ€~„„‚ƒƒ‚ƒ„ƒƒ„…ƒ„…†„…†}„y|~ƒ{…ƒ€„ƒ€}}~}}ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚‚ƒƒ‚‚†„„„†„ƒ„…ƒ„…ƒŠˆ………ƒ……„†††ƒ„„………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†tpurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚……‚hzrss|s‚ƒƒƒ}}~~}~‚ƒ|}€}}||||}|||~}~€}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ…ƒ†ˆ††…ƒ††‡‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vyy…r„ƒpvxqvtturstvi€nrotvnulwm{sn€ˆym}rsvsvmmxlpylu}}~€}€}€€}}||}}|}~}€€€~|~€‚€€€€€€€‚ƒ‚ƒ„…ˆ††€‚…ƒƒ„‡†ƒ………†‡‡„ƒ†‡ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoomw}x†pqzprtfu~n{ysoy€}}|}|~€€~~€€€~~~~€~}€}€€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„†……††ˆ„„†‡‡ˆ†‡„††‹‰…„†‡‡…ƒ………„‚…………†……†…†quprsoszy~ƒtˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„qjoyxpkyszozwvvp€~~~z~}}}~}€ƒƒ€‚ƒ„‚€€}~~~€~~‚€€„‡†ƒƒ†„„…†‡†…………††ˆ……†…‡‡…†„††‰ˆ…„‰Šˆ…„††……ƒ……„…††††…ƒx‹yrˆz{pp……x…xyks~y{krƒ‡ƒz|m{yyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozls|nw‚€~~}}{}{|}}~}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡…………†‡‡ˆ†„†…‡††…„……„……†‰‰‡†„†…††…††„††‡††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„††…†„†„ƒ„„†„„ƒƒ„„…„…„…„†ƒ†‡…†„„…‡†„„…†„…}w…ƒ„„ƒ‚}~{|{~{||}~}|~~€}€~~~€~~~~}}}~|{|~||‰†…„†††…‡†…………‡†‡ˆ†„†…††……ƒ„…†…„††††……†„…††††…††‡‡†…‡ˆˆˆˆ†„‡…††ˆ†…ˆ‡ˆ…‡††ˆ……††…††…ƒ‚……†……ƒ…„„„…„……„……„†‡††…„†‡†„„„…ƒ…„‚„ƒƒ…ƒƒ‚}€{{|~{||}~||~}€}~€~~€}}|€}~~~~~~||}~{|||{{~ˆ‡„„ˆ†††‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡……†……†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ…„ˆ…†‡†‡†ˆ†‡…‡‡†‡……†‡…‡†…‚ƒ…††„„ƒ„„ƒ„†„………††„††…†…„††…„ƒ„„ƒ…‡…ƒ‚‚…ƒ„~€€|{}~{|{}~}||~}~~|~}}~~}}||~~|}€|||}|||~z{{}~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†„…„††„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…‡†…‡†‡†‡…ˆˆ‡‡…††‡…††…„„…†……„„„ƒ„……†††…†„†…†‡……††…„‚„ƒ‚„‡ƒ„‚„„ƒ€€€{{~~|||}}|||}}|}|~}|}}|||}}|~}{|}|}|}|||zz||}ˆ‡‚†ˆ‡†‡†††ƒ…†…†††…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡…‡†…‡‡‡…‡†ˆˆ‡‡…‡‡‡…†‡„‚„ƒ„†…‡……„ƒ„„…††††††‡……‡…†…†…„‚„ƒƒƒ‡ƒ€‚ƒƒ‚‚‚€{}~}{||~}|}}|}{||||||}{{{}|{~|{|}}|}}}|zz{{||ˆ‡‚††††‡††…ƒ…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡‰ˆˆ‡†ˆŠ‡†‡‡†ˆ‰‡…ˆ‡†ˆ‡††‡‡…‡†ˆˆ‡†…‡†‡††‡ƒƒ„„ƒ††‡……„„„…†††††…†‡††‡††„†…ƒƒƒ‚‚ƒ†ƒ~‚‚ƒ€ƒƒ|~~||}}|}}|}z{{z{|||{{{~{{}{{{~||||}~}{z|z|}‰‡ƒ†…†…††…„„……………„ƒ…†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…‰Š‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……‡ƒ„†…„††‡†……ƒ……††††‡…‡†‡†‡‡…„……ƒƒ‚€ƒ…‚ƒ~ƒ~~||}}{}}|}zz{y{|}{{{{~||||z{}||||~}|{{{{|{‰‡„†„†„††…„………„„ƒ„‚€ƒ…ƒ‚z„Œ{€„…‡†††…„‡ˆ‡†‡……‡Š‡„‡…††ˆ†…‡„†‡‰††ˆˆ‡‡†‡ˆ†„†††‡……‡ƒ„…„†††‡……„ƒ……‡…‡†‡…†††…††„ƒ„…‚€ƒƒƒ‚}€~ƒ~€||}}~}{~}|}yzzy{}}zz{{}|}||z{}||}|~~€|{{|~}|ˆ‡…†…‡„†………………ƒƒƒ€‚…‚€€}|{„…††„…„ƒ‡‡†††…„†‰†‚†„†††……‡†‡ˆ‰†…ˆ‡ˆ‡††‡…„†……†…„‡ƒ„…„ˆ††‡……„‚†…†…‡†‡„††††…†ƒƒƒ„€€€ƒ€ƒ€|€~~‚€}€||}~}~{~}||yzzyz}}yzz{|{|{{z{}}|}|~~~|{{}~}|ˆ†…†††………„……„ƒ‚€‚€€€ƒ~~~€yz}€ƒƒ„‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ†…ˆ‡‰‡†…†…ƒ†„…‡ƒ„†„„…„‡†…†…†„ƒ†…†††††„…††……†‚‚ƒƒ~€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|z{{{|}}}|~}||}~|{ˆ……††††„…„…ƒ…‚€€€€~‚‚}}{‚ƒƒ…†…„ƒ‚†ƒƒ„‚€…‡…‚ƒƒ„„„††‡ˆ‡……ˆ†‰‡…ƒ„„‚…ƒ„†‚ƒ…„„†„‡†………†ƒ„…„…†…†„ƒ…„…ƒ……ƒƒ~€ƒ{€}}‚}€}~~}~}}{|{zyzzyzz|yzz{{{}z{{{|}~}}}}||}€}|†ƒ†††††ƒ„‚…‚…€€€~€‚|~~€€‚‚‚„…ƒ‚‚„€ƒ‚€„……‚€‚ƒƒ„…†ˆ††……‡…‡……‚ƒ‚‚ƒ‚‚…ƒ…„…†„††‡††…‚„„ƒ„†……ƒ„„ƒ„ƒ…„€€‚‚}}~~€ƒ~{||€}€}}ƒ|~~}}~{~{{zy{zyzz{yzzz{{|z{||{~~}|}||}€~€†„……„‡„ƒƒ‚†‚ƒ€€~~€}‚|}~~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡…„„††„…ƒ…‚‚‚ƒ‚„„„……†‡‡†…„ƒƒƒƒ„†…„ƒ‚ƒƒ„ƒƒ€€~}|~~|ƒ}|~||€~‚}‚|}}|||{{zzzzy{zzzzzzz{|y{}{|~€}~}}}€€€†„„…„…‚ƒ‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„†„‚ƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„……‚‚‚ƒ…„‚‚€…ƒ~€~||~}|~ƒ}{~|}€ƒ}}€~}|{|}{{zzzyy{yzzyzz{{{z{}||‚€~€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7;<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌËËËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFL=8765999<>9?<D9;<79<=;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÔÓÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937677=;>9=::;88:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<9<<98:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA><A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËÊÊÊËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÕÔÔÔÔÔÔÕÔÔÔÔÔÔÔÓÓÓÓÔÔÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9?CE@<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÐÑÐÐÐÐÐÑÑÑÑÑÑÑÍÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÙÙÚÛÛÛÛÛÛÛÚÛÜÛÛÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÜÜ×ÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILO@99:4;A<7=9AC>@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌ͖„†††††‡‡‡‡‡‡‚²âÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‰’™˜˜˜˜˜˜˜˜˜˜˜˜—Œ‹ŠŠŠŠŠŠŠŠŠŠŠ‹†‚ƒ‹ŠŠŠŠŠŠŠŠŠŠŠ‹‡½æáââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVN<::77>C>8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÎnPSSSSSTTTTTSL óëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSQblkkkkkkkkkkkkiUSSSSSSSSSSSSTKCCDCCDCCDDCCCFSSSSSSSSSSSSSKªòëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;@C>6:7>>;=B?9<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÌÎqTXWWWXXXXXXWP¡ñééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWVepoooooooooooomYWWWWWWWWWWWWXPGHHHHHHHHHHHGJWWWWWWWWWWWWWO«ñêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;>@@8:;8<;;<?:;;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÎx^a````aaaa``Z¤îççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbbaoxwwwwwwwwwwwwucbbbbbbbbbbbbb\STTTUUUUUUUUTV`bbbbbbbbbbbb[¯ïééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB?;=:9;:==;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÇÅÅÅÅÅÅÅÅÅÅÅÅÄËÐÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÏÎÎÏÎÏÎÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÍÎÎÎÎÎÎÎÎÎÎÎÎÎÍÌÌÌÌÌÌÌÌÌÌËËËÌÌËËËËËËÌÌËËÌÌÌËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÔØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<8@B<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÏÏÏÏÏÏÏÏÏÏÏÓÏÏÎÌÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÑÔÔÓÏÎÒÔÏÎÎÓÓÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖ××××××Ö×××××Ö××××××××ÖÖÖÖÖÖÖ×××××××××××ØØ×ØØØØØÙÙÙÙÙÙÙÙÙØ×ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?79:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÑ°‚ƒ“ÍÒ¨ ÐÏѤ¡ÐÎÎÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<>B>BC@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÏɛº¸›°·ž£§Ö¯Ÿ¡©ÒÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?>;7:>9?D>A98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÑ⏉Şš“Àž˜•œÈÐÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<<:6?B@C:647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÑ¿žŠ¨Ó¾˜¡œ´˜œ¢°²ÓÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8FA?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏѺ¤­œ¡´™–­¹†ž–¯³ªÕÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<>=964:99::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÑÀ ž“©› –x›„“¤ÕÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:=?>=<9@<<::9?@>=<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÐÒ¦°®Ÿ€Ÿ¨ˆœyŸ©…™¤ÕÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CFCAB8;?<=;<<8558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÐÑÉ×Ĝ‚¸¯¦œŠ½­¦˜¯ÖÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF@HIGE@<<>><=><756:969;::;8@?:<<9<>=;;:?9?:;9=>==;;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦Õōž Ÿ™§——¥§–˜›»ÕÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;547<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡ÉÁ¡­¡ Á¢«¤›ÐŸ«¤œÑÓÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKL@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÓÕ«©ØՍ·×¼ÕÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<=?GFHKH=657:979:;:<=9>99:8;=>>A>=9<<:=>>:=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÔÁ¾ÕÒÔÇÃÖÒÕÅÄÕÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?AELLA>775;8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÑÔÕÒÒÒÔÕÓÓÓÔÔÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEJ>>786977899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9599:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EILAALD??;:889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEGIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDJ;AA;<886486987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGIB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<BA<;876797799=?A?<:9@?<>B?:8776=??@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE>;HF89757875898;>>=;89A>=@?A>7596;>AB??@@BB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCEFC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELCA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<;DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGGNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAC?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668884;?<?<9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€ihxsg~‰‰xp‚†{w}~…Š½ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€ƒvt|„‚}sp€Šx‚yƒÈÞÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsoupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9<<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹º¹¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676879>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿¼½¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»ºº¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjdmgb\XQPQKTJB:IQ?A7<94:565455688686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸········¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®xpljac`YQMQLRFC9MPE>8;727967443588797;9:==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µµ¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸¸·¸¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶·····¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨¨¨¨§¨©©©§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸········¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥§©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥£¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§§¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©ª««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤££¢¢¢¢  ŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:99=7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž£¤¡žžŸ  žœœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=7789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥¤£¢¡¡¡¢£¥§¦¦§¬¬§¦ œ›¡¡ž›ššœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¥¦¦§§¦Ÿ›š›¢ ™––•š›™——˜˜šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜—™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥¢¢¥¦¦¥¦§¦¦ ›™›¡ —““’—šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AA??AB@DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥¦§¦¦¢œž¡Ÿ—‘‘”—›˜–––˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;;;=<::<=<7;>CBDC?=ACADA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¥¦¥¥¦§¦¤¥¦¦¥¥£  ¡¡Ÿ™’–š™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šžŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡ ¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?C@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢¢¢£¤¤¥¦¥¤££¡¡¡žœš•“”˜›š›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œ ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸŸŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::88:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸ   ¡¢££££££¢¡ ž›™™˜™™™š™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢ ›ž ¡£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œž››œŸžœœœœŸ   ¡¡¡  ¡  ¡¢¡¡¢¡Ÿžœšššš›œš™š›™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::<;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=::9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥£¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¡¢¢¡   ¡¡ ŸŸžœš™š›››œ›š›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›šœšš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>98;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤£¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ žžŸ     Ÿ ¡  Ÿž›š™šš›››››Ÿžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›ššš›™˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9;;>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœ›œžžŸžœšš›œœœ›œœžžœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<??::97;8887489<;<8;;<=:=>:?A=:=<>>@?=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››š›œššš›œœ›™™œœœžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™˜˜ššš™™™˜š›œœœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›š™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:;=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š››››œ›˜˜˜™™˜˜™™™›œœžžžžžžžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ›››››››™˜˜˜˜˜˜˜™™œœœžžžžžŸŸžžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<97:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ››››››š˜˜˜˜™™˜š›œœžžž  Ÿžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_]]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;9799;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜™——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››››››˜˜˜——˜™››œœœžžžžœ››œœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±³­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=9F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œšœ›œ›˜™š˜˜™ššš–‹“–™˜•˜˜–›œ—•’‘’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹““‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨©¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8437:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‹‘‹ŒŽ‹……‡‹ŒŒ‡ˆ‹Ž‹‡Œ…†‹†ŠŠ‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VPQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8@B?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹‹†Š‹‹‰†„†‚€‚‰‘ƒ€ƒŒ†‹‰…€‡}€’†„„†ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹‹‰‰…‚}s}ˆ€~œ„……‰‹Šz}}†ŽŠ†”‘‹—”—’˜¡–ž—•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¥›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ†‹†ˆ…„ˆˆ‰„‚z||}~’ˆx…‹Šƒ„…ŠŒ‘™””” ššŸ¢­±­©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPFMHSWRe^gTPL\QHLRCA997958866;79:;:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‹‡Œ‹Š‡’Š‡†‘“‘‘„‡}}ƒˆŒŽ‹ŽŠ‰Ž””˜‘•›š¨®²¯¯µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWLO_^\NUTbQDTM;?9<895775795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš˜ “—š ™›£ •› ¤£š“ˆˆ‹‰‘‘Ž‘Ž‹˜šŒ”š—œœ›Ÿœ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUKTOOJCPK_bXZQ\S_MHQIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ª©¨§¡¥¨¨«©©¯¡›Ÿ¡££ šŸ œ”˜”˜  ¡¤ž›š¤§¤©«®¬¥£¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdVOXKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®ªª«¤¡¢¥©§§©¨£¢œ››¤ ¥¨£ ˜™Ÿ¡¢©§ ¢¢®¬«ª§­®¨¥¤©©©©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_UZNRNPORd\dc[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢šœ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨¦¥§¨¦©¨£§¦™œ¤¥¢¡ ¡¡ œ˜™Ÿ ¡¤¤¢žž– ›š¢¢ ¡Ÿ ¢¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOWO^ddlgbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤Ÿ¢ ¢¦¡¦­¦¦ŸŸŸŸŸ™šœœ¡ ¡¤Ÿ¡›šœ ž¡Ÿžž £™–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvwa_\UYQUV[c^r_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?C?:8:>?C@DA:;><@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯«ª¬¨¨«°©¨©¨¡Ÿ §©­°²¯¬£¢¦¡©¥ž¤£¢¦ ¥¤¢¥£ž žŸ¥¢¢žŸ¢˜•žšžŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸ ¡¦¢›—’šš •|wo}yf[[`_Z\V\hdocnihb^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¢ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£Ÿ¢ª©§®·¶´´¶³¯¬«®«¶°©²±­®§¦ž¢££›œ—¢¨¥¡Ÿž£›ž¡š–¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¢™˜¥ ¤§ª©¨ª­¬¥©¤¥©§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxib[_^\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9:;<>AE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢œŸª²¸¼¼½»º¿´¯±³µ´··¯µ´µ²°¨¤¢Ÿ —•š—¤ª¦¦¡¤£¤«¥¥˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨©«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥ ¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxyxc[RYT__alhukpgiibYSL@<:;89797556285677:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶³º±ª®´±°±´´¶¼¼¾¼¼½Æº¸·º½´¯µ±±º¸·²³²ª¦¦Ÿ˜¤¤§¨¤®¤««µµ®³ §ª¬§ª©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš“–””˜“š˜Š‹‡€€|‚xa^YSah`fsosiscidb[LK>:8898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÃÆÃù½¿ÀÀ½¿Ä½¼º½¾´§ª˜±À½¸µ¹À³¯¯ªª¨­§§¤¯§ª´¼±´µ¨¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`a^^jbbnwuvnm[bQU\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAB;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–•–‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±±§¼¼¾ÅÄÆÉÇÅÆ»ÄÀÅÆÀ¹¯½¼À¾¾³«ªŒ³»¾´µ·Âº­¯°µª«¦ª£­¤§±¶«µ²­³­¨®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|ƒjfhaklfnuqruqf^_\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCBDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÅ¿ÃÂÆÅÀ±“¾º¿Ã¶¶º©´³´©«³»»±Ÿ›±¯¬¤¬®´§ª©¨ª­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š”‘™—ž¡•˜š’—”•‘”š˜““–’‹‘~z|tkkndolhqxoyiia\gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆ¿ÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÄÄø´À·´¼Á¹··¿À»®¥®·¼·­œ£·°¦­´µ¬®¥¥£¨¤  ¥™ª³²¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸·»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™œ˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyz{vnkhguZfrwsxff]d[RXIF?;78876169744333646;8:<;=<8=><:;<;=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÈÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÉÆÃÃÄÂľ¸¾ÁÃÀľÁÏÏÎÆ«¯¶´µ« §´³®«¸µ³«©£¢­©¬¦­Ÿ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuueeijh]jomxwbb``^XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÏÏÌÃÇÆÈÈÈÇÉÇÅÉÇÈÇ¿ÅÇÄÄÇÈÊÒÏÒ̼¸¶´¸¸Á¾¾º½º¼º¼¬­¦©»º¹·À²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqobagugihtmxl]d[U`YLHC6<9988:53:664413525;:<>;;<=<;<=<;<>=?A?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÅÉÅÍÐÎÇÌÉÂÁÆÁËËÇÆÌÉÍÅÆÆÃÆÅÉÍÐÍÏÌÇÄÀÃÂÉÍÇÅÁÄÇÁ»¾´±°°Á¾¿ÁÆ¿¾¸·Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`jjvlidtnsb\bTWTSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<:>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÅÇÈÆÒÉÁÃÿ¿¾ÄËÈÊËȼ»ÈÇÉÍÈÃÈÉÉÆÅÃÂÁÂÇÇÉÊÇÌÈÇÈÍÆËÏÅ·ÀÀÀÀ»»½µ³³¿¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrofegcjdajmnn^X\VUNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾÆÁ¹»Ãº¸¹¼¾ÁÆÁƺ¹ÉÉÃÅÄÀÄÁÂÁÄÁþ½ÂÀÀÁÂËÃÆÌËÅÈÑ°¾½¸º»¼¾·´°¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfadbabccjbfcZYY\YQNE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶·´´µ¿º½À¹½ºº´¿¸µ·³¯»¼·À·½Â¿Á»¿Á¼»Å¾»ÁÄÀ¾¾¸¼ÁÁ˾½ÉÄÀÀÊÀ±Á¿»¸»¾¹µ·´¸¼´½¸µ´°³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|y‡}qc`bbgjffiei]VUSYOSKE8?6;:779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“’’˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´´±°µ·µºÁ¸¾¸¿¼½·µ·°®¸¶¹¿»À¿·Á¼»Ã¶ºÈ¸¶¹»½¹º¶»ÅÅʽ¹ÅÀ¿¼Á¾¸Æ½ÁÀ¼Å¸¶·´¸¶¶»»¸¶´·ºµ´¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒ€xpmeefoiekgXXNKKKRILHC9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’š”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿½¼²­¯¬±°·¼¶»¼ÀĹ···µº¹º»À½ÃÀºÄ¾Ǹ¹¸­·µ¸º´·³»ÅÆËÁ»ÆÀÀ¿½¼¿ÉÃÄžƸµ²²½¸¸¸¾ºº¹¼ºº´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~†|knpgpksebm_\THKJDJBCG?9;8=<7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘ŽŽ˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼¼À·ª­¤®°·»³½¿»Ä·¶¸¶·¿¿Ä¼ÂÅÅÇÇÊÉÆÏÂÁ¸®µµ¼¾¸»²¾ÄÄÊÅÁÉÿ¿¾½ÇÌÇÇÄǽµµ¶Á½º»¿ÂºÀ¿¼¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†qelintnwcga\cQKTHEECGC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?=??FD@A?>:7?@CC?A=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼«ª£°¹½¾³¼¾¼Å¸²¸¹½ÇÉÊÃÇÈÆÆÉÈÌÎÑÌÊĵºÀÃÈ¿¿µ¿À¿ÆÆ¿ËÆÿÁ¼ÀÃÌÊÇÅÆÁ¹½¼Ä¿À¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtolltkln_b^`aNHM?E@?DC;;::;:8;<:9<>9:>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿®³½´¸Á±°±´¼Ã¼ºº¾¼Ä¿·½¿½ÇÌÆÇÉÆÆ¿ÄÄÊÈÌÌÍËÆÂÃËμ¹½º¹ÀÿÈÆÄÁÁ¿ÅÀÊÉÃÃÃùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{z‡zmmw{_pc[]_^SI>CEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=?>AAA>>ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸´¼¶º½Á¼»¿¶¿Á¿¼¿ºÀËÂÇÈÀ¿¼¼¿ÅÂÇËÈÁÃÀÀÉÊÂÀ»»°´»½ÀÅÆÅÅ¿À¿ËÇÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}‚zmsxsgp]Z^\YQEDCMIAD=G::59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘–žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯·¶²µ³·¹¼»¶»»½ºÃ»·½·¹À»º¸¸µÅÁÃû¹³´ºÁ½¿ÇÀ¹À¼¾ÅĽ¾¹²°®¸·¿ÃÇÃĽ½¿¿Ãþ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸¸¸½¹»±¶²ÈÀ»¶´±°·¬³©°­­³·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|vluzpmh\__YSPAEHGK@DCH<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿš›œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹ÁÀ·½¹¸¹¶µ¿³´²¸±»ÁÀ÷·­°µ¸¸¸Âº´»·»¾À»»¼®¯®³²¹ÁÂÄþ¼¿»º¸¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ¯µ´´½º¾¹º»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰|‚zsvvwmp`^e][TJ<>?FF=FCC9:5;99><<::<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Ã¿·º·¶¶²´À¶²´¸³ºÀÁù·²²²´²·¾º³µ²¼º¼¶º¾²´´´°¸¾ÃÆÄÀ½¿¹³¯²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtvrl^b`[]NHA?=HCFMD?775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••’˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·À½»¼¸¶º¶±Àº·¹¸¹»ÁÁÄû»¶´´°¶º¶´²¬¼¹¸µ¸Áº¸³±¬·¼ÁÇÿ¹ºµ®¥¬³°¦°­¨ž Ÿ¥­¶µÂ·¶´¥¨«¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´·¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wo{ourmc\fX\]RNMA>JB@JI@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³±­¶º®¬¼²¸¹·»¿½¹¾À´¿»¼º¸¾Â¼ÂÊǾÀ¸¹¶²´¶³´¯¬»º¸¶¹Àö®®ª²¶¼½¹¶²±­­Ÿ¤§§£¦–™™šŸ©®¹¬««Ÿ¥¨¤«®®§¯¬¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶°ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmuik]ZjT]\OMHDFLAFMF8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹ºµ¹»µµ³µ»¼À»¾À´¿¹¹º±ºÃ¼ÂÊÅ¿»¿¿¹´´³±±®°¹¹¶¼¸»¿²²²®±®¹¯ª«­¬£¨¡ž—˜¡•’•—˜Ÿ¨®¤£¤ ¢§¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬«¯£££¡© ›“Ž“’’™–š¤¥ Ÿž§˜•’”˜ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wrxhtsndT`cW\QNLH?HQDMC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®­¯²²ºº··µµ¼´¯´«¶º¸ÀÄÁ»µ¼½¸²­³°¯¬®¶¶²´´¯ª¤žœœœž¨¨Ÿ ¨©Ÿ¡§–›——“–Ž—›¤¨  ¢¢¢¥¥££ ž¥ ¤¬¤¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›©¨ª«ž¥£›£œ”ŒŽ“—•–˜Ÿžžš™¦—“’–¢ ¥£¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦ ˆxƒ|vybwln\PhTPNGOMLBOQ@>;>39:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¸´§¥¬ª¨µ²±°®¯²§¦¯£¯®µÁºµ·²·¶²´«²´®ª«¯°²³­¥ž’˜”™ Ÿ¢ œ¤¥Ÿž¨”›–—Œ—‘—“˜¢ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£ž™—š«¦©°£¥§ž œ•“‘˜–•˜—Ÿ˜›™›£™—”•š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’}|€uu}mk{dhUQcMIHGNRNJNG;D@=2?859;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜˜—–¡¨¬®¶·º¹º··»®¨ ¡©¡ ­«ª¦©¤©£¤®¥¬¬´¼·¬²±¯±­µ¯¯³µª§­¬£œ™”Ž‘–—™™œ £¢›¥žš¤———–’‘‘“š—› ¤ªž¡¡ž¦§ª¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¡¤¡›˜ž¯¨®²«¥ªª š˜˜˜•“–š“••™–š——˜ žœœ—›¡šžš£§¥Ÿ¡¢¢£›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}vx|dxz`bRU_HIIKSTIRPL8>B67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—““œž£¨®­¬««¯ª¯©Ÿ—ž¥žž¥¦¤ ¢Ÿ¦ ¢®«¬­µ²¶¦¯´«©ª´±°°¸­§¡œš”˜›š‘Ž‘•‘ŒŽ”™¢œ—£™š—˜™”™˜–›Ÿ¥¦© ¦£ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«¹¨¦«§««©¬¬§  £±­±±´©±¯¢™œž¡˜››š˜™›”•š–˜œ¥¡ š£¡šœ™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ Ÿž ¥¡žž¥ ¦™{|vvsh‚le[SZYMQJNNULRLA7>B78=76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=?758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’’œ˜¡ª¢§ ž§¡¥Ÿœ’œ¢›Ÿ¡£ž Ÿ£ ¢¯®¬¯±¬¶§­±­¦¦°®­¬°§ Ÿ¢ —‘”œ¡œ™˜’“Ÿ¢¤›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬¨¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½·¾°¬±®­©ª´±°§«¨²µ·³·¬±´£ ¥Ÿ«¡¡¢ Ÿš˜–•Ÿ››˜¤¡ ž£¡ žšœ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚|xuiwu]lZR`HQUHFUVJBMG=JH8E<67;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›Ž“ž™¨®ž§žœ¡žš™’™žœ¢¢  ¢ŸŸžŸ©«§¬©ª´««­«¥¥«¨ª¬ª¥Ÿž™’’”˜™–––Œˆ‹Ž•ž–žš¦  ¨¥±ª§®£«­¶°´²±®¶¸½Àº­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«¯±¹·¼¯³°µÁ¼·½³³µ¡«¢©¨±©ª¨§§š™šª¦Ÿ™§ ŸŸ§¨¥¤žª¡¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰…„~vqmiwmhm\X[BVMJGMGBFM<>L=4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜šª ±¢·£°¦ ž—˜–™ž›œ¤ŸŸ¤šœ¤¢¤£¢ª¯¬§©£ ¡¬®®ª«¦ žž¡£žžž›œ”“•”žž˜”†š¡›«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶ººÀĹ½»¬®§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¹Â½¸³»Åü»·³©²­ª³´¯³®©®£«§¶±¬¢¯¥ £¯±­°¤¤¯£¡ š¡§¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¥ž¦™›¢¤žŸ›››œ‡…{trkkurpgW\QETHDIOH>EA3EH95;=6;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž ¡œ˜›Ÿ › ŸŸ—¥•››Ÿšžœž¥¦§  «±®§¤¤£ ž¥«¥ž—œ”‘™˜”ŒŠ†ˆ†ymˆ ¤¢«¬´¼¶Ã¾¾³»ÁÃÂÅÀ¿ÂÆÆÅÃÈÂÀÅÈÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌËÌÒǾ¿À½ÇÆ·ÃÉÈÂÀž¹´¹ºµº·°µ²ªº±®»¶¾»ºª·¬ªª¸º´»®­¸£¥¢ž§¥¢£©¦™›Ÿ˜š§ª§ ¡¡¤˜”£–”š‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ„}zrkdioxjeZ[FJLDDSLDBD7:?;549978>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”••š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ³²¸§¡¡«ª¢ž¡¢žœ› ’ŸŸ–Ÿ™’š–›™£¡¯³©¡šŸŸš—˜—’Œ–—“Ž‹‚ƒ‚wsqnp¦­®´¹Å»ÍÇË¿ÂÌÎÍÌÇÉÑÌÍÌÇÉÅÆÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÑÓÌÓÏÓÓÌÊÂÅÆÆÊÇοÈÐËÆÄÆÄÀ»ÃÀ¾¾¾µ½³­¾¿ÂÃÆÄÇí¾¸²¸¼ÄÁÁº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›‹™‰•˜› Ÿ£—žš““‹•…€ytsebgrof^ZYCNLCEPIDB@55589B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>8;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›£¬žŸ®¦¥±ªÅÆÌÎÍ¿°Â©¥¨­­ª¡£Ÿœš©“™¡Ž “”’—™¤±±«¤  ›™—”“”–‘Œ‡„ƒˆ‡ƒ€€yrroly¤¶º¹¾ËÁÓÒÓÈÍÎÑÓÑÒÑÐÑÑÍÎÎÐÅÎÔÕØÒ×ÍÆÇÉÌÃÅÊÏÊÓ×Ñ×ÒÔÕÓÓÈÌÇÍÍÉÒÌÍÓÍÄÇÉÉÀÆËÆÈÈž³³ÇÄËÊÊÎÅÉ¿½¿¼ÁÇÄÌÌÈɿÿ­°³¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›•Œ†‘‹zruugbgvidVWQDMF@IQB=B<:23@<D<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<@?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ“£˜–Ÿž¤®›Ÿ°«¨¬±ÉÍÔ×ÏƻǬ­´¸¬®£Ÿ¤£Ÿ ¤¬›–©–—Œ—¦°®¥ž¡¥¡ž›•”–”Š}wpkebhqoq{…Š€vpnqtp…³Â¾ÅÑÐ×ÖÖÒÖÍÔÖ×ÔÓÑÒÔÔÒÏÑÃÐÓÖ×ÕÖÒËÉÎÐËÆÍÒÉÒÕÖÙÕ×ÓÖØÎÒÉÎÑÌÎÐËÒÏ¿ÇÆÉÃËËËÎÏÅÆǶ¿É¿ÒÌËÏÅÉÇ¿ÃÂÇÎÌÐÐÏÌÊÇ͸·»¨Ÿ¥«§Ÿ˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„|wsvoc`erb]R\IJFAEHI>;@8=4585:76:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢›©¦¢¦«š£°±©¨µÐÔ×ÚÒÇÆË´¶ÂƲ¶©¢¥¦¡¢«µ§š±¡–•Œ¦­«œ•˜¡›¡¢Ÿœ›•Šwic`____^_`^blusqpolrqu’ÄÇÆÔÕÖ××ÓÖÏÕÔÚÔÔÎÏÕÔÔÑÑÌÑÎÓ×ÖÓÕÐÏÒÓÑÉÓÑÇÐØ×ØÑ×Ò×ÙÕÖÌÎÏÉÌÑËÎпÅÁÇÅÍÌÐÐÑÈËÌÀÊËÅÓÎËÎÈÄÉÆÆÈËÊÓÓÐÕÏÒÌÒÁ¹Å±¥¨µ®§š¨¬¥²¨°³¬¬““Žˆ‹Žƒ‹„Ž™“™‚…Œ{zqstmacim_VP_JJBFCQM?<>44:=52755<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><??=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯®ªª¬ž¦®¸¨«·ØÔÕÙÙÑÎÐÀ¼ÌÉ·À¯§«©£¤±¶³£¶ªŸ¡ª©¡˜–˜š›¡žšž”~recb__a__a`_``_`fmppnkorww›ÌÀÒÕÓØØÖÙÑÒÒ×ÏÓÎËÓÍÕÔÑÊÏÌÓÖÒÑÖÍÐÕÕÑÅÑÔÊÐÔÕÖÎÒÐØØØ×ËÈÍÃÈÎÌÊË¿É¿ÇÈÍÍÏÊÐÍÎËÎÎÇÊÏÐÊÎÊÂÈÆÉÌÊËÑÒÌÓÑÐÏÏʽȹ°­»¸µª¶°­¨¸­³¿»±šŸ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…ˆyvopnkbenpaW\ZIFFDLWE;@<33<=86855;>@=9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><>>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ¤§ž¸¶µµ­¥­®¾´±ÀÙÒ×ÚÜÖÏÍËÃÓв«­®¬¦³±¸«³·©£Ÿœ–”—›žŸŸ”–—•‰l^^^adb``aa``a^__^]bmroostvvy¤¾ËÕÑÖÔÓØÖÎÎÓËÍÎÅÎÊÒÒÏÆÎÍÍÔÌÎÓÍÊ×ÕÐÌÑÓËËÏÑÓÉÎÑÕÒÕÕÊÀÉÁÅÌÂÈÉÂÌÂÅÈÉÊÎÊÌÌÏÍÓËÅÇÏÌÇÇÊÄÆÀÅÉËÍÏÐÆÏÎÍÍÌÏÅÇÀ·¹½Âýù²³¾°»Ãĵ©˜¥¡™–‘••’‹”š‘”””‚‰…xpqkmh``qhXXhVMGLIPPB;D>;67:89:57==A;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÅÃÁ¿»µ²±ÇùËÕÖÙÚÛØÍÌÏÉÖÖÅĸ²¶ª¤®¬¹¹±²À¡—Ž˜–“’‘–––Œ|ebbb`]^acb`_``aa`_][]grqqrsqmry¤ÆÓÏËÐÏÔÕÉÄÉÉÆÆ¿ÃÅÎÎÇÅÇÍÊÑÈËÎÍÆÑÒÏÎÌÔÊÇÊÍÎÇÇÏÒËÐÏźľÆɼÂÆÈÎÄÂÇÀÆÍÇÃËÉËÏÇÃÃÏÈÆÁÆÇþÀÇËËËÎÂÊËÈÇËÏÄÅÇ»ÇÂÈÈÂÏÀ½¼¿°ÁÊǺ½ª°²§¥¢œ˜›¤™—™‘•˜‰‚wntdk`^fqa[W`GHHGIMTG?J=64355=<48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥³±¬ÉÍÊÈľ½ºÍÍÆÐÕÕÙÚÛØÐÊÐÐÒÔÊź¾¾°¨·«¾¹¹³¥’ŽŽ–†ƒ„„‚~……t`[^^^`^`cdc_]]^_``_[Z\akrrookloo}¸ÑÈÉÊÏËÍĺ¿Ã»»º¹¾ÈÆÂÃÀÃÇÊÉÈÊÇÁÅËÆÈËÍÉÄÂÊÉÁÂËÐÄËÈ¿¹ÁºÅǽ¿ÆÏÊÿúÉÇȺÇÆÄÊÀ½ÁËÆÅýż¼¿ÃÄËÄļ¿ÉÂÅÇÑÅÀÈ¿ÊÉÆÇÆÐÃÃÆïÄËÇÄÊ·¿¼º´©¬¥¥˜Ÿ˜¬£¡¥š£ ›”{vrtfiZanmZ[XQDLFBGDLDFS@54334?<3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ÊÏÑÌÇÂÃÇÍÏÎÍÕÐÖÙØÙÐÍÔÎÏÐËĸÆÁ¶µ¼±À·º­‘Œ“—‡{€…†€vxurp_Z[]`abcdded`\\]]_^`[YZ\borokilposÆ¼ÉÅÌÀÆÁ°¶º²²´²±Á¼»»¹¸ÀÁÁž½¹½¿¹ÄÊÅƽÆÀ·»ÄÉ¿ÂÉ»·ººÅ¾¼ÁÍÂƾ½µÀ½Ãº¼Æ»Â¹³¼Åö¿µµ¾¿ºËüµºÈº¿½ËÃÁÅÂÅÈÅÈÅÐÆÂÌDzÆÉÃÎÍÁÅ¿½²·°³§¨¨¹±¥­°«­¬”yvwjeh`hocV^YJEJFHKAFBEI@9:648853;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÆÂÄÈÎÒËÊÊÇÍÎÏÒÉÑÆÖÕÖØÎÌÐÈÍÈÊžÊÁ²µº·»¶°‘Š‹…y€††€~„|tud\\]^``bcbbeeb]][\^\^]Z[]]hsqmggnpry½ÌÀúÀ¸­°°§ª­¬§¸´¶´³²³ºµ½±·°´®²»Â¼Áļ¿ºµ²º¾À¸Ç¸´»µÀ¼·½ÆÀû´®²¶º¾³Ä·»µ«¸¼½À½°ºµ¯¶º²Å¼¶®»¿´¶´Å¼¾ÃÅ¿ÃÄÅÇËÅÀÆÆ»ÇË¿ÏÉÇÃÆÁ÷þ½¶¹¾Æ¿¬µºµ·¶Žxtxfgebkn^V^`FKHHJFBCAEE?<:565633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¥«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÎÈÆÉÎÌÐÍÎÉËÉÌÊËÆÑÏÓÑÏÈËÆÊÆÄÀ½Ï½³¹½¹¸·œŽ‡‰‰{y~††wx‚}th^]]]_`_`da^cec__\[^\]^Z[[]_lpnhfjnnr|¤Ç¿¹¸µ°«¬§ž¢ª§ž«¬³­©«©³­¶°²¨®¦¬²¼º¶Ã¹º¹°«µ¹»´Âº°¿°½¼»µ»Ç¹Â¶­ª¨°±Àµ¸¼¯°§±³´»¼«­µ¥®¶®º±°ª¹¯­»®»¸»¿¿½¹Â¿ÆÂÅÀ¼ÆÁÈ˸ÅÇÅ¿ÇÃúÄÆ»ÅÉÌ˳¹Â¼º²ˆrvvkiablhYWW[ALKMIEAC?FA:9:995854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÆÏÒÌÄÆÁÅÐÈÏÂÄÇÁÆÆÅÅÌÄËÌÂÄÁÈÁº¼»Ê·´¼½¶µ«‘‰|y~Š…z{„wn^]]]]_`__dcbccb`_][[ZZ]ZZZZ]dnohfgiknr­¹°µ®¦¥§§š ¤ šœ¥«­£§¢«©¬ª°£¦Ÿª­µ¶±½¹¯·¯¨®¸´´¼¸³¼®·¹´±»Á±Á®¥©¢¬±²³§¼ª«¨«¬­´´¦¨®¡¤®©²¥§¨®¥¨·¬°²·¹º»±¼½¾¾Ä¿µÁÁÇÈ·¿ÀÅ·Ä¿»¿ÄþÄÈÌÊ¿¾ÃÀÀ©†rtrji]aodWVXPHZRSKFFE>?@9789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·ºÄ°¶°›™•œ˜ª©°±³µ½¯ÆÑÐÍÄÈ»»ÌÃÌÀ¼Ê¹ÀÆÀ¼ÌºÃÇź½Ä¾º·½Æ¹¶¹»®²•ƒ‰{~€~xt|swf_]\\^_`^_ccab``_^]\ZXY[[YXZ\_fkfegehkor…ª¥¬¦ œ¡¥”ž¤›—‘¡£ª£¢Ÿ¥¥§¤¬Ÿ›¤¦¬²¯¶·§°¬§ª´«´¹°¶´¬¶¸±¯º¹±·¤Ÿ£Ÿ§±§«¨¹ª¤¦§¨§²­ §¦ž›¤¦¬žŸ§¤Ÿ ±­­¬²´²³°µ¼¶»ÁÁ²º¾ÃÁ²¹ºÂ³À½¿µ¸»½¾¼ÂÇÄÂþ¿Ã ƒwpkae_ko`UY_HNhOTGEJF<=?=:;;825536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;=:7676788666;::;9:;<859<:>>@;Èµ¶½¸ºÁ»¾µ ž”¡¦º¶«³³»³ÅÐÉÌÃǹ¸ÉÂÎÁºË¹½È»·È»·ÄƳ¾Å¼·°¹À»±³·°¢„‡‡‚}yvtomkjjqi_`]\\]_`_acb````][[[\XYXXXVX[]^dcbegggjmoˆ© —•š¡–›¢˜•ž¡¢¦›ŸŸ£¥¡§žš¢›Ÿª°­±µ¢©ª©«¬¤µ¸­·¯¬²´®²´®°ªŸž£¢²¤¥©¸­¡¦¦Ÿ¨¬«™Ÿ ž™Ÿ¥š™£œ›¯©«§ª«¬­°²¸¯¸¹»°¶»»º«²²¹²½´¶±±µ´¿µ½À½ÃÁºº½—‚zrk_e^ddXTX^IW]KPGIJFA<??@;?<04535:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»·ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÆÐÉÉÁǼ¼ÅÅÐÀ¼Ê»»Á»¶Å¸µÁÁ³Âļ­ªµº·¨±³©‹†ˆ€ysnpnkb^bff]]^]]]\]_`abccba_\[[Z[YXWWWWXXX[^bddeffhikr¨”””›˜›¡––œ¡¡¨›œ¥¦¡¤›Ÿ š˜­®­®² ¥¢­«§¡µ°±±¬§®²§¹³¦µ¡¢žš£¢­¢¡©µª¢£¦¥¦£–˜ž—˜šŸ™—œœ›¬¡«¦£¤¦­«²³ª´°²ª²¹´¯©¯²²²·³­©¬®±·°º¶¹½¿¶²±”„yue^e^[YVSZUK[QLIEHKIB=?AA@@:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½¸½¿¶¾½¿³¥£˜¥±Âµ¶½­´¸ÃÍÉÈÁƸÂÁÈкÃÆÀ¶¼½¶Ãº¶¿Áµ»¿»ª¦±»±¨²¯›}……€ypqtqhfdiec\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXXVWadecdeddhjv¢œ”””–—Ÿ—™”˜Ÿž¡œ–¡¡¨£Ÿ¨œššª¦¯°«›££·ª Ÿ®¨¶©¦¦¬°£·°£¶ ¢›˜˜ª¦¡›¬¸¯¢¡¤œ¡Ÿ “•¡”––›˜—–—œ”Ÿ©©£¡£ªª°­¨´«ª¦­²°¥ª®²±¯°®®§§§²®±´¯¼´¹¶®£”yud^aVYWSRTKM^LPKGGLKE<@><B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾¸¼®§§£ª»À½À¹®´¸ÂÍÈÇÄžǺÊ͵ÄÅű¿À¹ÀÁºÀÀ¹º½·¨¨±»¦©¢¥‰~xrjlrtpihedgb\\ZYZ\\\]^]\[\^\[\Y[\ZXVWWVWXWWWU[ccbbcbcdfj–“•‹‘”“›™œ––› œŸ• Ÿ¦¥¤¥¦žœŸ¤Ÿª¯¦Ÿ¢£¶¨ ¡¢¨³¡¥§¤¯¥°¬«´ž •”©¡¡”¬±°ž¢¢ž˜›“‹¡”‘“—˜’——˜–¦›¦¡¢™£¥¤«¤¥°§¥£««­¥¨®¯®«¨ªª³¥¦«¯´±®¼µ±¯¯ ’zvrda\Z]XNLQGRaMVPOJMOEBD?9=69:764599;9887;89=>;>;<69:7;6;7;;:85:;:;;6<;8846863321./2556;:8;7876<;:;;A8x»»±µ½°»²·¬ž¤§­·»¼Áź±¹µÅÊËÁÄÇÇɸÈƵÅÂɯº¼Â¼ÃÀÁ½¼·º¶¦§²¶ž¢Š™ˆ€wodbgihfhjgjm`]\[ZZYZ\]\[\^_\ZY[YYZ[WUXWTTWUSTRU``_`a_`acdi”“‰‘Ž”’“œ”•–£™ –œ ¥¡­¥££¢£¡›ªª¥™ž¥±©  ¤ª§¡ž¬¬©¨­¬¢¡¡”—£›œ«©°›Ÿ¢žž—˜“Šž’’“•˜˜’›¡¢œ¤ ¡• ¡£¥›£«¥¢¤ª£«®¤­±©¦¥¦¦´¦©¨­³µ´¹º¯ª¬ž‹rpo`[WVUQFQOHZ\ORITKSLEGIC8;;=<8667:9;:976977:;:=<<6;<8>598:88659:;<97?<9678452121..1426:8698598989;9@9{µ´­´»²°¬²­§§¯¹¹³ÀȺµÀ¯ÆÉλÂËÍÉ·Ë¿´ÀÇÌ°¶½È»ÂÇĽ¿·ºµ¥«°®š‡Žƒ|uijjmhjlnkkme]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURSOQY]\]^^^__bdmŽ„‘†‘Ž™“”’œš¢œ› §¨ª§ª¥¨¤£˜¤®¤”™¥¯©Ÿ›˜š ž®™›ª³Ÿ¥¦ž¢£ ”“›–•’¨©­šœ ¡ š”Œ™Ž‹Œ’Œ–”¡ £œ›¢•› ¢ —¢¨£¢¨« «¯¤­·¥££¢¬­©¨«¯³¸²½µ³«¯˜ƒrrh[XYSUREYLP\YMTNPLPRINIB<??A?<65799<<987:79:;<=>;7;;:=67:;8976989:6:=99577571141-+/434988::8::748=8?9~³­¨³¶®©¨¯­›©¨¬·¶¬¼Ê»¶¿¬ÌÇƹÂÏÐɵƾº¾Æ˵±½Å½ÃÆĽÁ³¹¯¦«¯«ž—†wxoninnnqggigd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUTSNPQYZZZ]\\^_`d~‹‹Š’—‘—™¢ ›Ÿª©¦­ª¦¯¢§™Ÿ¬ •–¤¨§—Ž™®–—§ª™Ÿ“¥ ‘’’’•§ª¤™™š–Œ‹”†ˆƒ‹’” ž £—•Ÿ•š ¢“›¥¥§¨¨ ±°¦±¼§Ÿ£¬´«­§°´°¸µÀ±­±«}prbVTUNRIGVQSRLLXMJLNRGMKACFDC>@75889;9:7::7<=:;@>:9;9:?759:9876958779;85576661320-*.102877;99;8948;8@8³¬¦±·ª¦¢°«ª§©²±¤¶Æ´¹º³Ëƺ¼ÃËÑ̳¹º¾ÀÄǶ´·½³»¼Ä¾Â±´®±®±¬œ¢ˆkhnoroqkpkdfge^ZYZYZZZ[ZZZ\\]\ZXXXYYWXWUUTRSUSVURNNNRWXZYYY\\]aj€zv‰Ž‡‰˜‰””—›™¨›Ÿª¤¤ªœ§˜ ¥›’ž¢š—–„ƒ‘š£“¢œ••–‡¡šš“‹ŽŠ™£§œ••—›’‡”ŽŒ‹€Š’’‘¡šŸ¡•“˜˜•¢¥˜Œ™¤¦¨¦¡ ´²§²·¡¢·¬ª­¤²²¦µ¼µ««±£ˆxrm]NPQLOCNNNPKFNNKJNMQHMJAGKHHC=858889:;69:68;99><8:>9;?8789:886857688974577820301+)-/12776:999984988A7w¶§¤¶°¤§¤©¥ ©¥¤³ª¢²Ãµµ²³ÇǸ»ÄÊÍǵ¯¼¿¸¼Ä³³®¶¢­µÄº»¯ª¬´¯¯ —¨}^`gsqvqjnifhhj_XYXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQNMKLSWWVXXYX[]aosvp„ˆ‚‡€‘ƒŽŠ”‘“ Žš›¢ £˜¤–¡›•‡˜šŒs‚}––…™“Žz˜ŽœŒ‚Š‰˜Ÿ¢ž“˜–„Ž‚“~~s‰z†’š™š•Ž¢£Ž‰š ¡¤£›¢´¯¬¯¬Ÿ˜¥¹¦¥°¡°®œ°»ª©¯ª™vrbVLQOPMCSNLQMCPPHINSMHJJDJLEKK<749888;;69;7:<9::;79?9>@79:<89764445874312485/0102)(,-12764789::65:87A7w·¡£´¨¥¥¨£¦¥¦¦¦³§¥´À¸°´°ÊƹºÂÏÇ¿µ¯½Ã¯±Ç²­§¬•¤®¿¸±°Ÿ§­­«–•¢rWV_hgihincjhgb\XXXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTRMMJHNSSSTUUWY[]ilrm…|tNXr‚—†œ—Š“ž—œ•”–”Ž–‰“‰_;Wo{‹“‰‹‘Œ…†rŠ„–y‚z…“”ƒ•Ž‚†}’xqo…Œ}‰€—™˜“Šˆœˆž—‡‡–žš¡ —§¯¨­©¨ž–­´¢¦­˜¬«˜§³¡©­£’}qm_ZNSQVLDTJPMLFOOIELQMKOJIMPFIH=7599999:7:;:>>8:==6:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9x· £®¡¦¦ª §©§¢©°¨§´Á¹±µ°Éù´¿ÏÀº±±¸Ä«®É®§£ž†›¢º­§¨–¦¥¤¡—–iQMRVZZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MORMKHFHNQQMPRTVXZ`moiz‚tPB@•‘‘}‰”Œ„ŠšŒ–•Š’ˆ†•†yˆ`JQnxŠ‘„|„Œ‰„n~”wuvx„™pQˆŠ†{~x”vgw…‡~‰ˆ•Š’–‹ƒ‰‡”„šŒ„’›–žœ”¤£§©¥£ž›±«¡¤¤¦ª–¡©œ¢¦¨ˆtke][HQQSLIUMSILLPIGFKNLMTKQQOFIC<769:8:;;8:;8>?99>=7;<6;;478;6775344696/3/.115221/,')+*,4833979:99::::?9v¶œ¢§Ÿ¡®¡§¨¥§¨¯¬ª¶¼¶¸¶³Â¼·¨ºÉ¹·©ª·¸­¶Àª¢›“ƒ™²Ÿ¢š –™”‘‹ŒeMLNNOLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDDINOhYNQSTUZnƒtw~ji]U‰”‰t†{…Œ’’™‹{†uxsnupty}‰ª…yzhv{Žprmx€ŠŒ’xz€{€vrr’wgu„„„„z•‰ˆŠŒ‹€ƒŠŒ“ƒ{€˜”›•‘Ÿ¨žŸ ž ©¥Ÿ˜Œ§¤“ Ÿ•ž¤qg`\\JVOQGKXROJLMRJJJMPHLQLRTMEHA<78;99>=:;<98@?::>=7==79937795675252572/2.,./200/-+(().1262198798775:<<7v®˜£¡˜œž³©¯©¥¬¬°±ª½´²¼¸¶ºµ² ·»³«Ÿ­«¬µ³¥ž–’˜†”¤–Œƒ—‰‰††ƒfJIJIGFHHPTTTWWSTUUUVWWWXXXXXYXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQRSV^uƒ}ygw—˜Ž}gyvx‰|„˜’r‡|v{ok~­|sŠ{†’€}tfv|…lohs|‰Œ‡€lyq}pmuqhq€}ŽpCŠ„‚ƒ…~wwz‹…}‹zu~Ž’˜Š’š›£—™›ž¢–Š¤›—Ž–˜ŽumkeaYWXTQJRUTOPNQVKNKNOJQOINOKFD<;79;::?=9<:99??;8<=7<9999266856633621224.,,-..-0-+*''*.1362/876966527995y¦—Ÿž– ¦¯¬®«§©°¯±¬¼¸¬»¾¹³­¨›±¨­œ—ž§¬§¤›“ˆ–~Ž•’•€|Šz…€eJGHFB@CDILLMQRPQSUTTUVWWWXWYYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNPQTX^eprmˆ§ªÀ~uyb{xo|yˆy|‹…omŒ‘xsxjj‚r–‘‹}–I’˜nhw~‚licly…’†ksl|nr{†hmp~sˆƒ…z}~{vots…‚ywp|ŽŒŠ“ƒ–—˜š“–—™—ž—Œƒ‰Ÿ‘Š’Œ†–}lhmnmWUWTQQYOSUTTXUMNHMJMNKCINGE?:89;99:><9<;::=>:8:;9?868727575541442/024*+**-.+-*(*(',-1250,5567485HA895w™‘›™šž¤­¯¢­ª¨µ¯®¬´¿«¼Â¿¦£š•¥˜žŽ…Œ–¢¤›š”—v‘~…‹|x~t}xuw|fOEGD@<>>AFGGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jrA™o;<95<€‚†_IMOORWZRY\`§ˆbšitze~pmz‹ˆuˆ†tl™‘ts{jkŽLy„’‰„Žg1v†sl~}ƒtfet~„„…€filukp|gpp{n’Ž{s}|qpnum‚~wytiy‰‚ˆ‰ƒ–“’‹‘”•—Ž€yˆ—ˆ†‰†‡uiingcWQYWXY[MPUVZYNIIEJJHGBAFDCG=998;9:9<:9;:::@<9:<98>787715244533645031.**+),,++)(+'),,226-+5775478iO8;5n’ˆ™‘š–¤¨­ž²ž¦º®«²°Â²»ÃǛ—”™‹Ž†z…‘š–’Ž’‰tŠ„w‹ŒvwuxvoxsiUFID?<;9:?@ADDEGJLOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOPQVLAIQIb¯³ q|xm}mqƒ…y„††yr ”tx€su”‡5q¨Ž¡¡„¢„vp†|†{sŒ­ˆ€hfbimqmoƒuioXuoŽš‘vlz|mqmpzsumbv„†€…‘Š‹‰‘‹‘Œ‹ƒux‹€~‚€}xpnnj^Z[][YX`_SN[ZYXLHJFJG?CABG?CD=;97=;:;;9:99;:?<88=:8;66651121353475531./,,+)*))***)(*)+/3DM2166643<vR7=7b’’ˆ–‘¤§ž¯•¥´¨­±®Á³ºÁƗŒ”‰}n‚‘“Š„‹ˆˆv„…o˜ŠŒy{{q{t|ko^JPG>@7458;;<=>@BEILLLMNPQRUUVWXYXVUTSPLE<5*K[@-gI94/?’ƒ©®_GLMNPL7CMRSDJ†v€||v~lvˆˆ|}…ƒŒ~v¢™y~†€„™…›œa†ªŸ‹‚zv‰~‰‡ŽsŠ—ƒ{\dqtz{wŠlgiayo…‚znws„zpsywkni]w‡}‡|ˆ‡€‹“—ƒ††}q„„|uw{}ˆtmqrde^ZZ]S[f^XQUY\VGKKELG?F@DC?AA=:97<;;=<::99;;=>79>9986754244004645654-,)+('''&(())((+++/00Uq<23331E~W4=9\Œw‰”Œ‘Ÿ¦‘ ªŸ°©¯À±»Æº–‘”ˆz†vk€Œ’ƒ~‹…y„‚u¢†~~‚€sƒ}lylSXLAE311266688:<?BEGFGJKMOPQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMORLKT]YRJi„ˆ{‰y{q|Œ{|‰†~—‡v¡™ˆ‡’”¥¬©H†­¯¯Š€€“Š‚‹‚„‘¨‡€˜˜Šœsl|†‡}Žhggx~m…†…q„†Gk€wqyvhmk_w}ƒˆˆ…Œz•žœŠ‹‰‘{u‹v|wmow~}qqpjZ[[ZcbWge\UPQXZQDLLGOICFCCA@CA=978:::;;:888::?>6;>7585773344236656768;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|~Š…‡‘–˜’— ¬¡¦¸¯³½´—’‹˜‹}tpŠ“~ƒ”•}†‡¥‡‰€ƒˆ†y‰‹€u…y_cVLC60./22123668:=??BEGHJLNQSTUTTVUSQOGC?80,#‡[>?84.]–ps£UFIKMNPW`YpZ\^j“‡•€„‚…‘“~…‰‘š–‚ ¡˜•›š¥­“™»±§»Ç犌¡¥Ž“‰{rƒžŸ‘œ~v……‹‡ihoƒ€tŒ†„‹q†‚w‡{v…}nvug”†‰ˆ‡‰ˆ¡«£–‰Ž˜€{‚‰zzogkx}w|qic\YY\h\af_ZOLNXSQIPKDNGCJDCADDA<:87=<:<:88778:==8<=68656623445576867<BB?<8:>CQ^e\G2'&,,--.1(?Œ[.310Oƒ_4?;nvpgxƒ{€Œ€‹šš¤œ¡¬¦«¯°—’‘„¡”„xw€”}’†“–~Š’›Ž„‚Œ‹‚ŠŽ„€Š€mpj^CA4--////02234779;=?BDHJOQRSRSSTRPOHDB<87/9C><<63.l“—MPHIKKKNV`cggmu›š““‹Žšˆ“‹ ¡’£©¥£¬“¨¶¢§Á®ȯxº”š|Œ¡ž˜„“„‚¡ž“™’„Š…˜–lpu‰‹•Œv„ql…Š–’ƒ…ˆr‰¡—‡“‰—¥¶©›•¢ƒ‡“„~kjl}~}q_[b^Yfj\lk_XKHPSQNMLFIQDDNFBCEGB>:97=<:;:987767;:6=:785456345566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<ungYpƒpu‡qv‘†~—–š”ŸŸ›§ ª–“˜žhf¤š~…“’z’‰’’}‹…™’‘ƒ‹Ž‰†‘‡„ˆ…xxhNR>//.,/.-/000212457;?CFNPRTPQQSQNPIED>;<:CF?><752<?R5HHHLLMNR^oŠ|s} ›§¦¢™¡—¢•œŸ¨ž©«Ÿ¨¬©ªµ—«¿«¶ÈÉ·ÈÑϾ› pi«©ž„“‘…œ šš™§‘‘ˆ•¡™šwz~”˜‘¡’–—”ž{v•’«³‰— }•žœŽ“–š¤£§¶°‘™¨ˆ—Žˆlss{|ynf^[_^agc_gg\REKKQOIJMFFMCHLFFCBGDA:85<<899975658>75=84745754546958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f3A@ib^Pqu`n}awŽ}|”ŽŽŠŸ’—ž–œª˜žªBD}‡‰ˆ˜y‚‹Ž|Š†Žƒ€‰Œ‰…“…‚†‰€‡w_bP460-1/,.00./..0015>AAMQRSPRSUSNSLEE@<>=FH@A@8662<9;FHGIIMOQYm†w•‹£§ªµ½¸¥®¬¬¨©µ¬±·²²­»±³¾œ³Ä¬»É˸ÿ·¥£°²¬­ª£Š–˜…¥¦ ¢˜‚¦™¢ª§¤‡…“£  ª¡¤©Žœ±‹•£§·»œ¡£°“££ž‘¤¢«°®³µ¢•¦ª‰šŠ’Š•z{~ƒ{e^fZc`]bb^fg_[ODIHTOFHLFKGFFHAKFCFFA;87=<88:974658<54<76:44644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLicWjpXz…v”…ˆ‚›ƒ’‘Œ’Úȝ–sV—ˆˆœ|†Œ‹Š{ˆƒ‡‘Žƒ…Œ†…ˆ’†‚„‰†‡‡‡qna@E64<3/110-,+-1/-4?DANVQRSUUWUM\QGGD<>>FHCD@8;<5C;=FKIGHROPW“ „®£³ª²ÁÇÄ«³Å¶­´À³¸¾¶¿´Á¶»»¤¸Æ©¶ÉǶ¾¹´¨£´­°±›™’šŸ‰§¯ª¤•wŸ¤—¡«±³˜–©­¨®µ»²º¬¯µ¢±¬²µ¼¸µ®µ ¨¨£¨›©°­³º¸¸¨œ¸©¥’“ †y€rW_bUd``a^_f`[UJDELVQIJJEJHEA@@KDBMF<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AEWQJL\ZQcdWzuq•}„†“v†~€{¿»£¼‚´”“Ž›„ˆ“Š‰z‡Œ“‡…Ž€Š†€†ˆ…Š‡‘zyn]W@EN<6:46AB764//6CHCQ\OQUXU\WO_UIKJA@>GKFFD;>@7D7?BJJEGWTP^¤­¤²´Ã¶¸ÁÌʶ»Ä½³´Á·¸Âµ¿°¸t±´¦ºÅ¤°Æ¹±³²´¨¤¶¶ª± ¢–›¢’¥±­¥­¬§¤˜ ¬³º¢¨²¹µ»¾Ì¿ÅŽ½³Â·º¸¿¸º¸º­­±¦±ª®¾°½¼Â왻¨•®˜˜«‰~€yhUa_VhchdV[cYVTJGGLRGDIJAID>?BBL@@MD99669:?6:9966246/19599364627;=?6:1./58:9650*(,---,,*((++(ES/*00Jk52P‡m6?FRLALRWTYVZwjp„Ž…o{rxˆb¹¡™£‰•”–“””Ž—’‡‡{‡Ž–Š„Šz|‹ˆ†|Š‚‹„•}xzueO\dGEL:Qd`[^SF?;HPDZcQQYYZgZS`aMSOEA?IJHEFA@C<D6B?HGKMSZT^”¯¸µ»¹ÉÀ»½Êͼ¼Á¼¸¶¼»·¾µº³Æau²¥±šž«¾ª¥¨«ª¤¢²µ «§ž•–ž˜Ÿ®¥§§¥ž£“¢§°³¨±²¼¶Á½ÓÉÉÓÆÂÅÌÂÊÃÁ¾¾¿¼¼¸´°¹··ÃºÆ¾ÄÉ°žº«¢¬¥©·‰€|n\^^\U_]gfSYaVRVIEFNKA>HD=KB=B@=F>;H@796379>489:57045/26389374526?8@>GKRTTRPOQRQJA9/,,,*+((,-+/P>(.48€}<2Kˆq9>CKE@JMPRLQ]hmlq†slrrtˆÕÀµš •™™‘Ž—’––Ž†ˆ}‡ƒ–Š~‚ƒy{‹„‡{‹yŠ‚—t}zkepvY]\Peeb`ed][XX\MdmURmn_o_XgeUYTJDBKKHFHHHHBI9D@HKTTV]Z\“¹À¹¾¸ÆÁ»¹ÊË»¶º¶¸¹´¸µµ®¶·™du©ž­p^¢­œ˜¡¢›¤ž«¥”ŸŸ”Ž–˜—¨ž¦ŸŸš™ƒ£¬¤ª°¬·°¼¸ÔÐÎÖÏÉÌÒÌÏÎÊÇÀÀÂʽÁ½ÂÀÅÄÆÊÀÉÏ´¤¼±µ°œ¬¹½š}vi[\YW[_XabQ\aTRLCBFGE<@F>BIB@D=:E>=J?47535;=468977022/24169775555D3ELM>510006:477@IOJ;.&**(-./,@M+/54m‰I0H‰t?>BD@CDGKODR\Zi`o—’‘”nlotu‡³¬¡¡Ÿ‹™œ™•‘›’…ŠŠˆ‡Œ‹‰|„s{Šƒ…{ŠtŠ‡•t{ylmu|iseilhfjih`fiimZmt—­¤½ˆ‡g[oh]ZYTHKOPJKPLSQHLAJFKP__bgjb—·Ç°º´»¾¶±ÅǶ°¹±±»­³±¨«¸­¶¨žœ§šNšžŒ –‘§˜¥•Š““ˆ‘‰‘’›¡˜›”–‡ž™¦š¬¯¨¯§³³ÔÔÔÖÑËÏÓÔÎÓÏÌÅÂÊпÊÉËÉÒÈÍÎÃÐÒ¸°Ä½Äº¦·»Ä¢kaZZ[V^VYcYP]XORCBIECI;AD>BH?@B8;D>@I=56655;:687654/10146278875367C5B8?-0,1348=97,.,1;FL=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYSfWs‘™ƒhroyyƒ¡ªž¦—Œ››˜‹Ž•‘šŽ}‰‹…ŽŠŠ‹ˆ|„‚p‡†{‡rƒ’‹~qyulpxr{nxsli€pmcinpyiw}~Ë¿Ãߧncxnd[a`JPRUNY^P]]MQNTQUT\nnwƒr–®¸¬µ¨°¶«­½Á²«µ¦¥¹§¬¯¡¬´¤±®›˜˜Œ‘”‘„›§‘œ‰ƒ‹„Š‰„‹ƒ”•——”››˜™™ž«¬¤§¢¬¬ÎÒÕÑÍËÒÓÓÐÔÑÎÈÃÔÑÈÎÒÓÓ×ÍÒÑÅÒÖÆÁÏÈÈ鿸МvkbZ_[T^Q\YOPTPNI>AGBCF=AB?FE>@?:==<<JA45465<888664412/03526768533;=<E=@11+/349?5901022-2EO3)/3.32=N248C}_2A†tD:==I>@CFH<VRMO[u‡†‹wlwp}~€ žž¡Œ™“”‹Œ“–…y…Ž‹Šˆ‘‡‚{r~€‚‡z…v…“‘‰€owsls}|w|s‚xqk€rriprzyr{¾Ëš²„vr…wiai]CZZ[WfdXekTX]]`c^cx{‹™ª¤¤¢ ¡©¦ª±¹«¦´£¢®¢¤®¢§±Ÿ‰¦›•“‘Š’ˆ‚”‰k•¢™„†~‘ƒƒ“—¬‹•Ž•šŽ…’—§°¢  ¥¤¨ÈÍÏÇÂËÑÓÑÔÒÎÓÍÆÖÓÍÔØÖÖØÕ×ÕÊÔÚÍÊØÖÑË­ÄÃˈol_\\VRWRZOJGIJJ@;:;EBD=CD>HC?CB;<9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/-.;R017/532ED28>nb5=tM99@I<AD?A;PLFKYp€u~isyr‚Š€•ž”…‹–‰Š‰Žˆ€x„”™‹ˆˆ‹‰~ƒxs|}„‡w€{‡‘—„oxqmuvx}t†|yl‡vtn}v…uy{µŒ<A‹Æ¥~}jeWICecfchjdoy[_fhkninƒ‰‘ŒžŸ ž‘—™ £¤¦²¤¥² ¢¥Ÿ¢©¡¢±œ‡Ÿ’’“‘‹‹‡„„~œœŒ‚„…z”‚ª–£Œ’‹˜“‹}—Šš‘ª³˜šœ§œ¦½ÃŸ¶ÅÍÑÐÒÐËÒËÉÔÎÑÕÚ××ØÔÙØÍØÛÎÉÚÚÒÖ¿ÌÍ´uskaZWPSPXUEGJIFE=:7:@BC:HE@EDBDA;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?2*(.BT29254/7K75<`bA<svV87AH:?B><9QECJTlnopbqqt†}—‘ž‹~‡’‚‰†…Š‚ˆ}x…——‰ƒ‡†‡z„yq{{…†uz†ŽŽzp}ppz€r{r„‡€nŽzuw}}‚u|‡‰°tYªÂ·’pnc=^hrpqpnww‚eiorvxrz‹‡“’›– –ˆŒ“œŸ›Ÿ« ¡¬œ¢šš ¦ŸŸ¬™Œš‘“Ž…}ˆ‡ƒ…‹Ž ™“ˆƒ‡~l™y„™†ˆ“ŒŽ•Œ†{›ˆ“Ž­ª”•—Ÿ˜¦®µ¼¨­½ÇËÈÉËËÏÉÄÒÊÔ×Ø×Ø×ÔÛ×ÓÙÛÖÏÛÚÒÖÉÕ̓uwedXWNQR[GCFIH>B>=8:>@<>H=@BAAEA>?:87DB755479.566435532323647553458EBDCEB56<FNSM[nfcnsk`V>,4LG865433BF4=W_hLux^8;?F<<A<:9D?CGRk_mdbflv€ˆq‘›€y€Ž~‚‚…„|}„˜Ž‡Œ†‡wƒyn{{‡‚tz’žŽ¡vvƒtu~t€„o‚o’…u|…zv‡|‰¸Æ¥Ãʸ‚–œxpeNec‚z‚w…¡‹yzw{„€|„vm”–•–˜‘ƒ‰—š——¦˜ —Ÿ“’—£žš«–‘‘‹“ƒŒ…‰‰†‘žœ™ˆ…‹…—zˆ‰Ÿ—‰ŽŠ‹‚|¡‰Š»¡˜“—šœ¨¦¥­ž§µ¿¿¿¸ÆÉÍÎÅÍÉÑÕÕÔÙÕ×ÛÔ×ÙÚÛ×ÛÚÙØÎÛƃvvdfa]RUTTMKDMC;=<<9:<?9=A7>?@=?>=9867CA6455=80665547745613854564557HH=DJE7925;H>;9:7HP\ZRUXK9T>;95327I8=NYMHxxd5=>C=<@:6:>>@EQ_Yfa]\itzyl‰’wvz‹|~€€~…{~‚‘Š…†z…ˆ|u~um|}‡~t’‘Ÿƒ’|‡~x~y‹Šoƒ›t™†}‚Š…|~‘{©Ã ½Œ›¤œ}‰…}‰sŒ‹s¦šœ˜”…{‘‰„iGq¡¤žŒŒ‘’…ˆ‹’•›“”‘—Œ•Ÿ”¡•“ŽŽŒŽ‹„‰’–™ŸŸˆŒ”‘‚Œ¦™ˆ…Žƒ†„€¤†Š‹·—‘”–¡¦ £®¶¹´«ÀÆÊÐÈÇÌÏÓÒÒØÒÕ×À×ØÙÛØÚÚÙÙ×Û¶vutgfbT]YRNNHCLC==>99;:99<=6@>?==9::;37D@8378>70688357<37804976755546FP5DNI8938AK=;3C@I<9DWO<MTHN?96333>C;[X>5YypZ<<A<=>8589?<DRSRX_VXfmmmiŽŠqsyŠ{{€||ˆ{}|‹‡‚~uƒ†zszsm~…~w†›¡›ž”’€Œˆ˜‡€œ’nˆ©…{ Œ|‘Žƒ‰„œ~›‘Š£¢Ÿ‘¤¯ ‹‘‹…‹“†Wr­‹Ÿ«›ƒ™œŽ[ƒ¢‘‚Ÿ“”Œ†ˆŒ’’Œ”••ŒŠˆ–›•–’Œ“”†€‹‰’ŽŠŠ—˜£¢†“• ‹Š‰Žœƒˆ€ƒ‡…¤„‹²˜œ’”—¡ ž™’›§²¸¬¥½ÂÇÍÈÆÏËÏÌÎ×ÏÑÔ®ÖÕØÚØÚÚ×ÖÙڝlyqccZZUQUVC@IC??>:48:;7:;:3<<?=>7;9:1:G=:27=@50677255?65;55858:57735HR7GOK994=EJB>1FCLA98:GX@5HWI66223:ECeX?&_yi_z>>9<;98:;@;BQKKSYPTcbxlb~‘ƒonx‹xz{}‡||w†…€sp…‚{uwvt…ƒ…}’¦¢Ÿ¦¢—Š”—‹Š¨—rŠ²„¨’„™”…šŒ£– ˜“‰›ž¢“©° ‘•‘ŽŽˆ–Œo·„šÄȲœ¢¦œœ˜–‘±d¤ÍǕŽ†‡‰’“•Š…ŠŠ†–™›”“‡•˜„€‹™ˆŽ«——¤£ˆ™ž–šˆ‡——Š…‡¥ˆ“¨š—“–˜¡˜Ÿ™“œš¢²´¥£¼Á¾ÇÆÅÈÈÉÂÊÓÌÍÔ¨ÒÑÖÖÖØÚÔÓÚÎo{d`[[[MHSYBAGD;B>837;<:9>64::<:72?:929I:>67BC32:96264>=4;>6949;57944KQ<JQK9A7BGI@64JELF>;88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHRWSRBc‚GvŽ}|m~ˆxz~{‚‚ƒwv€ƒ|mn‹{}xx|„‡Š~‹¢³§£«³¢—§Ÿ¥¤–•®¢ƒ‘¸•’³šŒ¡¡Œ¥›°£¤˜‘§–¨™¬¯¤˜•–•‹˜š—¡ÀŽ£É¸«œ£¦­˜’›²…†¨£œ˜…‰‰Ž•Œ‹“ˆ†‡‰“˜•Œ‹”“‡”˜†„‘œu‘™²•–¤¡‡œ™’‹Š—›‰‹–Ž†}Œ˜ž‰›šš“˜—Ÿ“ ”ž› ±®¢£·¾´ÅÇĽÃÃÀÆÍÊÉÓ¦ÎÌÓÒÑÖØÓÐغovrY^S]TNGIMDACD5>:77:?<<7=42669774>5;5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=88567=:JFDGMZ\YJf`;H„‹zzn…†z|„x†~px|~}osz~‚|x†‹‰†„’¦»¬¨±½°¥­³³¨£¢°¬Ššµ£¸¥•­¥—©­¸§¤£Ÿš©˜ª¤®°ªš™œ”–‘— ˜š»»®Ê¡j¶¸«°”™Ÿ£¬“—¾£^ª²ƒŠŠ”‡|ŽŽ}ƒ†Ž”•ˆˆ“–Œ•‹–˜“™´–•«Šœ”‘Ž‘’Œ™›Š’ž‹‰–Ÿ¡Œ”—™’›˜ž”¡ ”œ¥®¨¡¤³¸¬ÂÈĵº½¼ÅÇÇÂÑ ÆÉÍÍÅ×ÖÑËӟmweYWP[ONEC><BAB8@885?G=<5<35345454B49:BM:B;AHB;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPdHb`bpJ@‹Š~€s†‡}‚ˆuƒŠ‚n}|}pw‡wŽ‚‡|Œ†Œ™©ÂÀ¯½Æ»³´À½´­«³¶Œ¨²®®½«›»¥§­¹¸«¦¦¢¢¤£©¯²±ªœ¤™›˜—Ÿ¢¦¥’¤º¯©À¼­®²¹¥¤¨~ˆ†œ­½°‚‹Œ‹ƒŽƒ‘zˆœ‰ˆ—‹•–”‘š—¨š±š‘¬œŽš’Ž•–—‘ ‘‰”›¤¬”–“œ“ ›˜Ÿ¡”šž§¦¤¢£°²¦ÁÆï°º·ÅÄÿͦÇÄÇĽÖÐÍÄʅpo^YW\XLJAK@EG>A@C;:5>A==5=6>333242A17@BN>G@CNCA=C=;86CC5BIB:878;5B>79VKDWOF8=4K@C>4EKHN>AA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUN79GD?CF\eF`igZ]\“ŒŒ‰{‡Œ‡ƒŒu‡‘Šo~{‚q~{•z’””˜“–§³ÆÉ¿ÁÌÂùǽ»¯«¹»˜³·º²À®¥À¤«¯¼½ª®«££ž§«®µ°ªœ «œ¡œ–Ÿ¯µ§‹£ºº¶Á¼¬©³¥¤¨”…ªÃ䂋‡ˆ„†•”yƒ‘‘¡ŒŒ”’Ž‰—Ÿ˜“™•—¦ ¯œŒ«œ–‘‘••‘•’ ”†—Ÿ ²ž”™“Ÿ ˜¤žšŸ› ”˜ž¥£¦¦¤¯­¥ÀÄ¶Éþ¶Ï²Ä¿Ä¼³ÑÊÈ´quiYUYgQLHBLKKJAB=CD<5AE;;3=8B332262A05IEN>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBeZMe\fTbk™–ŠŒˆ“†‰y‡”r€{x‡‚‚z¡–¨™š™º½ÇÈÉÁÒÉËÂ̽³­¼¾¨ºÀ½»Ä·¬Á©¬³¼¾ª°ª¤¥¤¬®³­¶µ¡Ÿ¯Ÿ¥¢˜£³½ª›¨½Á¤¶¸¯¬”²¬¬¬—†š©¦¥‘‚Œ“¥–ŠuŠ’y…Ž’ž ““Œ”£™–œ•”£žªž‘¥šŒ•–ˆ|•“’£š•Ÿ¢œµ¥ž–¤£¡¥¦˜•—š¤£©§¢²¬¨»À拾·Ì¿¹¯Ä³»¾Á¸¬ÂÃÂÀ—jv^UTYXJJLIFDDHCCADL:4DI:;4<8E.12242B26SHO<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQG7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>iH_XbZccVžœŽ—Žž’‰ŠŠ “„x…–~ˆŠ‘€–¡™®§¤˜Â½ÇÃÇÅÓÎÎÍ˼·°º¼´½Ë»Ã¶·¼­³¿º½®¯¨ ©¨¶­®©²·šž­£§¡«·¸ª¥°¿Ä²½¹´¨«¶´®®—–¥¬¨Ÿ‘’²Å§–Ž|’•|‡’™ª™˜““’•“¤“™“¡£¢œ˜Ÿ˜‹ŒŽˆZ——’—¤™e˜¢Ÿ³¥•¡•««©¦›ž¦–˜–˜”¡£¨¥ž¶«©¹»Ã´¥´µËÀ¸ª¶«²»¸®¨¸º½¸€hkWTRSMEIRLK?AHEEHGG95FM;>7=@J.32025C55OVN<LFKRLOHGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C=4FE:BABG9/:A3603>GD94=tdMG;E+:f|gV;>@BFBpEjIReaLF¥”œ—¢—©–Œ‘ƒˆ¦“ˆ‚‡‚œ„ƒ•”š¢ž¯¾¯¡Æ¼ÄÄÆÆÎÏÎÒʾ»¶±º»»¾ÏµÃ½¸¹·³±µ³¸³«§œ«¬¹ª©§¯°˜£¯¥§£¥µÀ°¬¬´¿ÃºÀº´§º¶¹´¯–¥­®®¤‹“”¡tš}—™„Ž—™Œ±•›š•’’™™¥£• ›—š©›  ™Š•œ`J–œš”š¥–T–¯Ÿ¯œŸ¤”®­ª¤š ¥““˜˜œŸ§¢™´¨ª³»»»ª±²ÇÀ¹¦¬«­²²£¡²²´¤mjbYWMOJDOOPR;HKIGICC>:KU?A:=EM07544:B44MWO;JKOUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@BAF3>58JKCA=C;4EA:A?>H@5*B52,>c]g:35tde@R7&#3}hW;:BC@=QEWSsbWFHª–™ ¢¨¯™‘—‡‹¨–Žˆ“… ‡„—¡š£¤µÉµ©Å¹ÂÃÈÊÈÈÌÍÆ¿»³®¹¹ÁÁ̵ǺÁ¹µº°¯¯³µ§¤›ª´´ª©¦­¬š¤®¥¤¨¬»¿¨¬¶·¿Á¿¾¹³²Ä²¹¾­£¯µ¬¹¦ˆ›—¦›v¿Ÿ„™Ž“ššŒ®—¡œœ—”› ¡¨ž¨Ÿ™šªš¡§ž˜‘ƒnv’¢š•¢‘®²£ª”¨ª—©­£¢ž¤§‘‘™œ‡”¢ž–±¦©«¹¶½²²®¾¹¶ £§¨¥¦œ›­©©‹`b^]NJKFGMJVL=MENKLBCD<QV=AABDO18=76?B75UXO?HNQYSPQUKQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW;:=.-R`MUH~e^HE«•›¢Ÿ»¯™”ŸŒ“«›‘’“‰«†¡žŒ£­”££¶Æ¾´À¹ÂÂÇÉÅÂÍÈÁ¾¹²¯¹´ÀÂɵƲ¼µºª¨­­°££˜ª´»¦©¦«ª©¯§£ª«½»¨­½µ¸¾Ç¼·¶¸Â²¾Áµªµ¶«¾¥£˜’¢ ¼Ÿ‰š ™—Ÿž·Ÿ©œ¥¢›œ¡š¨¤³ ›¦œ¨ªž˜•”›‹–‰Œ¤¡”¢ ´¯¥¤’¯«™ªªœœ£¢¨””Ÿ‚žž›•©¤¡¡³´º´­¨µ²³žœ£¥š—•˜ª¡žu]Z][HGEFLPIMEGGBSLJBEGAWSCH=AGQ1;B7:BF79\YKALPTUSMWRNUJE@JJNO9C@5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-19f\FCCpbGE§—£ŸžÃ­œ—¥˜™©œ–ššª–•§¦•­¬˜¢«¶Ãü¾¶ÁÂÀÇÄ¿ÍÆ»½¹²°¹³¿Âǵ¿°¼·¹¶¦¤««­ ¡™ªªÄ¢¤©«¦ž¬¯«¢©©¾¸§­¿²¸·Ç¶µ¹¸À²À·µ³´¯½£—£—”œ”®Ÿ¢£¥££ ½¥©©«œœ¡›¥ž½¡™£Ÿ¢©«¡—•ž“ž‡„“Ÿ¤ žµ¬¦œ•°¦™¯¥œ™¨œžŒ˜”žƒŽ ™›’¥¤š—«±µ±ª¥ª®¬›˜  ’•¨ž”e_W_[MHGINLHEDIA>QIA<GII\ROK=HOU4BF9>HG5Ca[KBNRUWVQXTRUI@8RQPM:GA4CHQSIC;C>GVKC@O>K<06;GF>;FA56?9:?9;15D0-,/Mv\4KZ5,MnW<-=)#zbQ5CKQ9mRF<KxeaVK¢š£œžÅ¬¡ž¬Ÿ® ’£Ÿ–¤ ¦©¬˜¶±¢ª³¶ÅĽ¿µÀ»È¾Êǵ¸µ´±³´·ÁŶ¾±¸µ¹´Ÿ§¬ª¬žž¥¤Á¥Ÿ©­ ¤©­¯¡¦¨½µ¦±½¹·¶Ä²´¸º¿´ÄÁ¸¹®³µµ£¥•’”¡® ™¢ž©¨¬£šÂ¬©ž¬®››ž™¦ ½¡¤˜««¬¦¡ššŸ’ž‰ŽW–Ÿ¥¡ ¸ª§“˜´¢ž±Ÿž™®•˜“œŽŸ—•¡£•¥­²ª©¢¢¥¥••˜‹‘’¤ž‰_bXb_KGJJNFEAGK?=JB99JKN]QQI=LV\9FI=DMI8Hb\LCLPSYYVWOZ^IA=WQIK?H?5HMXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+w`S6SZkWrGE6=ue\KMžž¡™ŸÄ¨¥¡´¢³§“«¥ £Ÿ¬©¬»°¨¬¶±ÇÅÁ²ÃýÆļÄɼ¯°¶­°´¯¾Ä´¹±°º´¬™¨±©ªš¥¡§Á­›¬±›ª£®°©¥©¼¶§·»¾¯·Ä­³³ÃÀ´Ç´»·¬³¶­ª¢¦–••¤¬¢Ÿ ›§ª°¯¯»±¦ ©¨š™˜“¢£¸ ¡£’°¯¬¥¦Ÿ’¡ž•ž•ž›¢ž§´§¦Œ—²›¢­™œš¬’•’™‘ •ŽŸ “‹¦«¯¤¦¢œ ž‘‘š“…‹‘›_cYfdIHLISAC@IH;;F?99ONV^RSJ>O^]=HPBLLI9Mc\LELRTY[SUO\bHA?ZQAHAKB7FELKM?;BHDNB=;N@A3/97CB97F;+6<46<25-/4@1+'VtSeO?104b[M23>0<v]^?[T^eq@8;H–weA4ž£Ÿœ Ã©¤ª³¢¤µª–³¬§¡¤²¬®©»²­±µ´ÆÀÄ´ÀľÉĵ¿ÈÁ´«µ¨¯¸¬¿Ã³·®­¶¸¥˜ª²««˜Ÿ¦—­»´›¨°š¬ ­´²¨«¹²¨º´¹³¸Àª·²Ä½µÆ¨¿¯­¶µ©§¬¡˜—’¦¥¢¢˜˜¥®¸®²µ¶ Ÿ©¤š”–”¤ ·¢¥¥–¯±²§«¦¢žšš›•—¨Ÿ ˜¡ž¯²¢¦Œ—­˜¤«–˜¢šŒ’–˜…•ž“‹›“Š¨©ª¡§¡˜ž•‹Ž™…”ˆ“žwbg[jiLOMNT=BANC::I?77RO]^RVQAW`\BJSHVKH:Td\NFON[W[RPQX]GAB[PBG>NC9HGHOP??CIBLB<2IA94177B>;7E7+6914801-/.<6-#Bqgsk23/1[bZ33806p[bH05IohUCWFŒyfC;££¡¦¿§§¯±¢©µ«žº±¬£«´¶±°¹·°·¸¸Ä½Ãǽ½ÄÂÆÀ¸ÀÆÀ¹©¶¤¬»­ÀÁ··ª­²º¢”­±­²–¤§‘ª¹ªŸ¦°œ« ¯´³«©¶¶­¼­´³¹·¬¸±Ã»¿¿¦Ã«°¶®¨««§ž˜™«¡¢¡‘˜¡±¯³¬°¹š›©Ÿš—“˜§ ¶©¦£¢°±´¬³§¬Ÿœ  ›ž¥œ¢—£³¯›Ÿ“¤™Ÿ¨™“¡“–ˆ“–’•–œ’ˆš˜”Ž©¨¦Ÿ£œ—›’…Ž™‹}‹•„™igk`lmWPQ[UABET@;;IA7:XPd^PWWEY_^MLRN^KJ>Yc^NHPO\UYPKTWZI?DXPDF?N@=IGGQPB=DFBM?:1D?77547?=95E4+75/251--.,1=*'+=\p=>1.0dZd@1647gY`F(?8l}g[V;‰{cC=§Ÿ¢©½¢ª°¬¤²¹ª¦¶´¬ ­µ½¯³¸»º¾·¶À¿ÉĹÄÂÀ¿·Ã½À·®µ§«·±»½¾´©®±¶ž–«®§®—¦¨Ž§»Ÿ¤¬³ž«¢±°³¬©¶´µ¾®±²µ¬°´³ÁºÅ·¬½°±·«¬ª£²¦ž¥ª ¤—‘šŸ³ª³««³š§œš•Ž¡¦¤´®¨¡­®®±¨´­²ª¤œŸ¨¤ž•¢™›¨µ©—™’’™Ÿªœ•–„”–Š˜›“Š––š–¦¥£Ÿ–•—’”…{’‚‹•dkqfoq^FYgVDBMXDZ9HB6>]Qh\NZ]G[^]OMRXdJJB\b_PLMNXWXPJVVWL=EUJEDAM@AFHHQPA;FDFK=87B=68719><65D0+80/05/*,/-*=,,%2+*5K1/'__`U150=`V^8)C3YU\gK6ŒzfL@¤š¡¥­·¥¬ª¦¯®·ª¯µ»§¦±·Å·±¶½ÁõµºÄ¾ÌƹÃÀ¹¾¹Ã¸À¸²´«©º¶º¹¾´©­°µ—˜§¬©¬›««Ž«¾ž«­²£« ±®³®­µ²¹¸ª®®±¨µ¯µ»¼Ê³ª·µ±´¯®¦¡´ ›¨­ ¦––›š²£­ ¦¯—¡¤šš“Ž£¥§³ª¡¦³­ªµ¥¯²µ¯¤™¬§š˜Ÿš™«·£—“Ž—œ —–“ªžš‘’—Œ›˜•Š”’ž™¤¢¢ ˜–’“•z‹…{ŒŠ‚Š‘jmwluzaFakYIGZZ={JFD6AbTi[M\aK\]ZRRRb`LKE_``QLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76)(9.$:K5."T_T_/5(C_Q\.+B/JGP[G3cYTKD™—¡±©²ª¬¦¤¯®¶©·µº¤¬´·É»´»º¿¿´³·ÃÀÌȼü¶½¾¿·¾¼±¼­§º¹·µÂ¶ª­±·”–¦®«¨£°©”¯»¤­±³§¨£²µ±±°µ±¸´©¯¬²§·¯·´ÄÆ·©¶¶¬°­©§£¶  §²¡¤•œš•±ž§œ ªŽ©£ž›–˜¦¦¥¸¨£²µ¬¨±§®±µ¬¥™ ¬¨›œžœ”©¸›”ŽŽŠ—›¢——¤ œ“‚”œ›—–•ˆ–—š§œ¤ ‘–‘•v„‡{„ƒ‹Šlovt{~\Lfm\JNc\>b{GI8GgWf\L^bMXYWUWTi]OOH`]_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANGf27'GbLV%-B.=ELQ<3rkICC‘™¥¯¥®¯«¨¥±³´«·²¸¡«µ¹É¹­Á»Â¸³±µÂÂÎÅÀÁ½´½¿¾º¾¼²Ã§©¹°µµ¿¼®¬²±› §±­¦¦¯¥²µ­ª±±¬©¨µ»¬´²µ­´­ª¬¨¬©¸­²°ÈÀ¹¥º°©¬¬¥¨®±¦¥£¯¤©œž›¯š££££‘­ž£  ¢«¦¦¹¥¬¶¶¥«¬©­°¶®¢ž£©ª› ››’£³™ŽŠ‡¡ ”Œ”œŸ’ƒ’’œš—•”‡—’•™§›ŸžŒ’‘v}…|{|…ˆˆprq}|}\Sdo^NXf\FD–[G;NmXb[L`bNVWVWTXg]QRLcY[TKGOTSNGIVS\N;P^IBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/+1()+,-*&5*/&0)38:1&*3Bc:6*HeHJ+:H>3BHS,>k;GHœª«¢ª±¤©¥³µ²µ¶²²¡«®½Ìº­ÀºÇ±´­´ÁÃÑÅƾÀ²¾À»¾·»Ä¦¬¶«²·»À¯«±¬Ÿ£§­©¨¤°£ª²ª°«°¯°®«³½§¶°²©³ª«¥¥£­º­ª²Ãº¶­»©©§¬©§±¥ª¥£®ª¨¢Ÿœ£­•¥ž˜ž™¬¢§©¢­¦¤­«¸³²¢ª¢ ¬¯±¬ž §§©™£™™ ¦—†„ŽŠ‹ž ŽŠŒ•šŽ„…”Ÿœ”—•†–”“—¤›œœŠ’‰~‡…|v~…ƒ„rqpˆuk_Z`nbQrp\K;„|F?XuX`ZNd[NVVUWQ\a^SONgXWVKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*25>10485(5/*,.30;),,'%234$,2-860)(1;\J0.JgDF8;B05EKX1@•Y=LE•˜­¨¢«³œªª°·­¸¶¯«¦««½É¼°½¶Â¯±«³ÃÃÎÏþ¿´ÀÁù¿³Çꮶ­²¸¾¾²­­ª¤§ª°¨§¨±¥´®ª±®®²±´¬´¼¤·³¬¬¯¨«Ÿ£ž°·«ª­º·¥·¶¤ª§«ªª­¡©§§²²¤§¥¡¡¬—ª¡•› ¦ž¥¢«¤­¢Ÿ§±¸®®¤¦£›ª«®©¢¥¤¤˜Ÿ›–˜œ’‚‰„œŸ‹ŠŽ‹˜Ž‰‚‹—¢››Œ“’‘“£™›™ŠŽ‹‹}†ƒzs‚|ru‹¤‡xk_`nfWd†cN?g“LEbyWbXReTMVUVTO\]aUKNhVUVIJHIOBGISQYoAMX@:JGFEG>>EQH8CKE87C72:::*39?./463)4+*,+.#4.-+&(+79*&6+<-2,&06VZ.0JgAA<<B+:JO^4D†=GFD—“°¦£«±˜«ª­¶¬¶²¬¦¬ª©¼ÀÀ·¸²»µ¥²¯ÃÉËÑ¿À»¹¿¾Á¸Á¹ÀĬ±´±³º¿½²°®¬ª«¨¶©¦®¯ª¹°¨²²¯²­·ª¸¸¦³¶«¬¥©ªœ£ž³³©¨¤´´ ·® ª¨ª¨«§ «¬©º¶ªª©©¢ª ­›’ª¡ ¥¢¦£ªŸ§´¯©§«££˜¥§§ªœ¢¤£ ™˜ ‘Ž˜~‡‡„†ƒ‰‰ŽŽ‹‚…”¢šš‘’‘“Ÿ—˜–ŒŠƒt†€xt‚~xv}€‡orgfpw\`r‡jO^™VHmyTdVQcOMVTUPOX[bUHOiTVSGOXUI>IHOQPxLMV=<KD?@A<@CUC9AK=5;E13;:7*4:=+-341*8**+*,))(/*&)%3;,$2)2021%/2Qb02?f=NX>C,>LT_/Ji5OD<–Ž±¢¦«¯š¬¥­°´µ°¬¦°ª¨º¾»À°­¹®¡¶¯ÈÇÈÑÀ¾½»»Á½ºÂ¿¾¿­±±±µ¼»Â±±³ª³©¤´¨¥­³³¹°£®¸²°³»¬º°©­¶«ªŸª¬Ÿ£ ¶­©¡Ÿ°³¢µªž¨§©£ª¡¢­­¨½¯¬®­¢¨¨Ÿ¬™°¡˜¢¡¨¨Ÿ¨›™ª±ª£ ®¢¡”£££§˜š¨¥˜—˜žŠ‡”ˆ}†„„£–„Š…Ž‹ƒƒ“Ÿ–ˆ‘œ“‘œ”—Š††wt|uxyyrrxf†¤vi_di€tfˆ‹|SXo^JxsSdSQ_MMRZfNMVYdXGRhQQ?BNQaQ:IHLSIqQLS;<I?;<=;@@W<<?H73CB15:93-5::)-31--5)(+-,42#2)',%.;.&1.0-14%,0Lg:48_=ad?F1CP[[*HM9U@4‘³¡¥¦­¤§¤­§µ³²«¥±§ª¸¾À»¯§¹ª¦¯±ÉÇÈÑü¿¾¸½¾¼ÈºÀ·¯¯³±¹»¸À²²º¬¸¬¢´§¨¬²¶¹³¨¨½¶®·¾°¾§­¬µ«­œ©¯£ ¥­«¨œž«³¥´¨šª§©£¨£©¨©¾«´°®ª¤¡¯œ›³£–¤œ¥¦ ¥œ›©«¦Ÿœ«¢œ“œ¢¥ž˜—¨©’˜š”Š‚…~ƒ€ˆ…~}‹‡Žƒ“š“…“¡Œ”‘‹‘›’•‡‰~r{z~|hx|ysno{f„x„‰dag`r„zlfx]^T?W{lTaPQYKLNru]HZ[gYEUePD>JNDCA9HGKS?jbJQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11'/>KH0%90%,,09/,,+6'17#-0GjI14X=fbAJ7GS`U*=9DW=*•²š  ª¦¥¡«¥¸³³¦©±¦¬¸Á½µ¯¢¸­¨¨°ÂÉÉÌÁ¶½À´·¿ºÈµÂ´²²´±¼¸¹½µ­¹µ¾­ ³§««°¶¸µ¬Ÿ¿½ª³Á´¼¡¯²µª¬Ÿ­°£œ¦©ª¤ž›¥°§° Ÿ«©§¡©œ¥©¡­¼¨®±®¡«£¤¯žŸ­¦—Ÿš¡¤Ÿœš¤«£œ›¥¥–—• £—›—¥¬Œž‘‘‘‹‚Š€€Ž€{™”Œˆ{~‹…‹‰„’˜†”£‰“’‡‘š“ˆ}yk~vyxc|zpnoqvgsi„heg^lsl`io`o=ZxlU]NPRKIMTZWM]^lWDW_O^PHMDF;7HEKO<rhKK9AE;;==;;=J49B<3;G<4?18-68;2(09/,4/.=-*K>)49&'.34.0+/4&,:$41AhY14S=e_DL6KVdO*;1NW=#”™­š ˜¨¥¤ ¨¤¸°¯¤¯°©«¸Á¹²­Ÿ¹¯«¨´ºÈËÈ¿¶Â¾¯´½·Ä¶Â±­¹±³À´º½·¨¹¸½ª£´¨©ª±®¹±«œ¼½¥°Á¶·¢¯¶µ§¦§°³Ÿž¤¦¨¢¥™Ÿ¬¨©ž ª®¦ ¦˜¤© ±¹Ÿ£±¯¡¬¡­¤œ§¦©šš›Ÿ¥–›žª§—œ¡ª“™”™Ÿ“™–¡©‘š‰Ž†|‡~‚}| Œˆx‚‹„‰‹‹…‡“šŽ‰•žˆ‘•‚‹—‘}…|sp}qtt`zxhmoomh}qb{mieb\d„~^YsjqJI~iXYMPLJHPRQIO]_nSDXZRhNGKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23.:;83&2<0,85B*)-B*,4;NN@;73-.+-7**<%53<fd24M?e]FO=QZgH*>/WU5(—ž§š—®¡¡¡¥¡¸«²¥´´©¨¹Äµ²­Ÿ·­®­°´ÆÈÀ¶¾Á¹°´¼¶¾»¾¯ª½°´¿°¼Ã¹¨»º·§§µ©¨¬±­´±¨›¿·¦®½·²Ÿ±·°©¥§¯±›¡¤ ¥¥ —›°§¡ž£¨¯¡Ÿ¡“¥¥£·°¡¦±«Ÿ¬£¯˜œª¤©Ÿ—šž¥”››ž§«šœž¦—–˜–žŽ“—¢¨¢‰‹†z„~„Šz–‰†x‡ƒ‡‹…“˜–™Š—~†—Œy‚zprwoot_ywdjkjgg‚lerkkdgWar^YkuiYE}^[XOOKHHRUG2:_^mPDWUYeLHJEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<#8R=*113>D5,-'42+;+139cl84HBf[HTCT]hE.;1^Q,2–¤£˜–«ž¦¡£¡¸ª°¡»¸¥¬½Ä²¯®¢µ¯­­¯´ÄĽ³¾º·°³¹¸º¸º­­¿³´¸®¿Á·«½º´¥¢³«¨ª³¬®²£Ã·¦ª¸·¬Ÿ²»ª§¥¨¯«™£§œ¥¦”˜¡³¦™ž¤©©œ¡Ÿ”¦ ¤¹¨¤§­¦ž¥¡©“Ÿ©¡¡¡™›ž¡“›—¡£¬œœ›£–“•–›Ž““£§¤ˆŠŽ†y„|…†}œ‰Š†x€ƒ‡ˆ‡‘…•“’Œ‘•”Ž”{ƒ—Šw|lurmlsbytgfifcm„fghdfgh]dbieZezb`PrT[[RKJGIOS@ *j^jLCVU^`KHGEC.:B<F<6KPD8:D357==895?:;4>8@L=>93)8><:9*6@3.E4(+,>0-N?.+-7-1195,&.5-80576`tB3CDh[KWGU`hB377aL'2Ÿ¤¥“¦§œŸžž¤¶­¨ªº·§«ÃÀ¶¯¬¢µ®§¯¯·ÁÀ½±À¶±®²¶µ¹¸µ¬ª¼³¯²°½À·®¼¼°¤Ÿ¶¬¦¦µª«¯¡¡Å¬©¨²µ¬¬´¹¨ª«±¥˜ªž§¥’™¥­£˜¤ª¡›¡œ˜¡ž§·¦¯ª­¡¡ž¢• ¦Ÿ¢ ™œ›œ”šž•¦Ÿ®£˜˜Ÿ–•Ž•˜Œ˜š§ ‡ŠŠˆx…w‚‚‚œ‡Š‚ˆ{~…ˆ†„ƒ–•‘‘’{ƒ•Ž…s}gyplklguskagcbsacefehhaenY]X\lcaLgWZ`VIGHKMRX>9`liHBUS\[HHFEA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A<-5B37=++,/A*JK./*+3722(57$+7.72685\yN2>HiZLZJVbfA:3@bF%5¤¡’Œ®¡š™ —¥´²£²¾·¡±Å»¹°°£¶¬«®©¹¾½»­À²®¯®¶®³¹²§«¹°¯®´¶»¶¯¹¾¬¦µ« ¡²¥«°Ÿ¦Å¡³¦°²±·­´¬¯¬®¢™§ª¥ž•›§¦ ™¥£¨œšž›•­°¦¹§®¢¡ššž™Ÿ£š¥—Ÿ˜›–›¡“ª—­©œ•ž”•šŽ•”˜§§ŒŠ‰Ž{t‚‚‹˜…†|ˆˆ„…ŠŒˆ’…”œ’‘‘—Ž‚o‚gynikjgqrk[hcaq`dgjnkeiecl\llupaSbhceZIFLMOYQPUaeT@VRZTFGFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24:5#3*)6.55465Z|]1:Kj[M[KXdc@A1HbB'4”£œ±œ•¡›©³°Ÿ¸À¶ ´Á»½¹±¦¶°©®¥¸º¸¸¬»¯¬««·ªµ¹­¤³µ±¯©±¶¶±³¶»§© ¶ªžŸª£ª®¬Ä™¯¦°±·¶¬«ž°­¯ª¢›¤¬©›•œ¦¤šª£¤–š œ’œ£¬«©ºž¦¤ —ššž¡k£–™qƒ˜¥v’¬©Ÿ–—¢’Š˜™€—ŠŸŽx…’ƒmi~w„ql†Š†}„Š†o]d`g„˜†k‹”’ux‹„ƒfˆ€hvifW\itnNPjceqƒf]dfnkh][]‰…‡hNKC8ETg^JHPPUVKHRapteF[QUPFGFC>1;=6=6<3f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,,08>G701.*.*/668,#1'214:276Xl15Ok[N[K[fb>G1Na<+/Ž¤šˆ–²›”¡œª®¬£½Å¯©·Â¸¾¼­§·±¦«¤¸´³³°¹­©§¬´¥±µ¢§¸¶µ¨§­¶³®´®´¢©Ÿ´«ž£¥§¨›°¿•¨§°µ¹­­£¨¬««¥¡Ÿœ¡¨§›˜¡¥¦œœ§¨“žŸ™Ÿ¨«¤´¯£¢£œ–˜™—£ˆ¡’›ˆ¡ˆ•Ÿ¢€¥€¨­Ÿ””ž”‰„rxŒŽƒˆ u‡i—‰f~sx o‡‡„~Œ|¡ Ÿ™|‡ŸtˆŽv›Šl‡‚ƒmhdd{mrbT†mcmi˜qXion†W]hZkjZˆplyr‡h‡„Y^FN>F^MERVVQPRWTg^LZLRRPEFG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82*/1<I:/01.*/(-4583%&2115>1<8Xƒt15Rk[N[L[g_=K1T^7/(§˜„ž¬ššŸ«ª¨ª¾Ã¯²¹¼·Á¿ª¤·±ª¬¦³µ®¯³¶«©¥±­¥¶³›¬µ¶µ¥¦©³±­²¨®žª¡³© ¤¥›¢¥ž±¸•¦§§·½¦¬¦©©¬§¥¡Ÿ™¡¨£™™§£¤˜œ¥ª–”¢œ”“¤¦§¡¶¤£Ÿ£˜•”˜”œˆ®˜•ŠªŒ™£†±¥®Ÿ•›¡—z‚Ô¨‡”À›Æxw±¥·–d€Àœ¿y„„yƒ|‘Êq–¼œÅ{r¶§º{l—±«±yhlX±®nei¼’¼nhymqØ}Rkb¶²}~p”uš¡ªVNWaOVNFU\XPPS‹[W[P@\DPNCFI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22AE/.32.+/)-/186- /416A1=:Wƒw11Tk\O[M]g\>L1Z[41!§”¨ªŸ˜ž¥­²ª°Â½²µÀµ·¿Â«¦´®­©¨°µª¯¶´¨¨¦µ¥¨¹®œ²²¶ª¥¤§²¯®±¦«ž§¥²¥¢¢ —œ¢ ²¯–Ÿ¤¡µº£©¨ ¬­¤¢šš£© ˜œ© Ÿ—ž¨¨‘œ§›”ž¢§£¡°£žŸ£–—“˜’™…¯kjŒŽªh…–‡­fqŸž•›©—q®¡¤~wº|k v±_j´[¥€eœ`fzfixj©e¾rg¦Œv±j|±xu‘”cmm§n\„ Eig‡–Euœ`}f{£¦X_‹«h}xzj¨8J¯[XTlcZKOX_\VV;N‡PWV/ISSJCEF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3/.53/+/(.0.:6/'$203B/=;U‚v2-Vj\OYL_gY:M5^X31’¢•ƒ­§¦Ÿ£¥«²¸­´½¾°·Å²¸ºÃ§©°¬°©ª±¯¤±º°¤¥¯³£ª¹©²²°£¤ ª­°¬¯¦¨Ÿ£¢±œ¤ž™–™ž°©˜œ¢ µ³¡ª›¡­­Ÿ™—¡£©™ž¥ œ™¡¨¤œ¢š—¡ ¬Ÿ¦¦ šŸ¡–•‘—‘š†µ›µy‡©š¶™w‡³›·”—˜¬—k¦z…†‘”’w«gj±[¬{Ž‡”t‰pŽ†€ˆ—xƒ‚Š—Œƒ …°vwŸqkkm|‹O¥XHcc™~ch¥_yquR’†]P©ncpz…€a/R¢n[Tkg`LK\dX\ZB>°wWXA#MiFBDA@A19>88:84;:9<9:A:E::;6:CB8=?KNH:5:AFBAAD<FD;0201;E,0.940,.(/3,>831/2-D1<<S}n3+Xj\OXM_fW7J9aT50— ”‰³¦¦¡®©¨³¬ª»·Â°¼Ã­¹¶Â«¬­¯¯¨¯³ª¢¯¼«¢¨¶­¤¬µ¤¥²³¨£¢§ª³©°¨¦Ÿ  °— ›––—› °¤œ›¤¨µ¯¡¨Ž©§ª›–˜¡¦©šŸ£ œ £¥£–›ž˜šž£«œ¦šœš¢ —“‘““„Õ“™¹q±ÂƇ}֔œ»}œ—¨’¤{†¢¥‚y«yV¯{‰~Ÿj¹Z¹w†„}¦‚”|™zªyŽ{±mŽ„t»†o•P¯§ÅŠQ zc`ªbsr†k–‡^Rµ´È…~ˆ|c¤3Bu]PjhdP@XfYdaJGLjJZSOYfZCC?E?0<<59<74<;8=:<C:F:;>6:@C;6@OLH<9;DHCBCD<EF81211DB.00483+-).323971#%5*>3==Qwj6*Yi[J[P_fT7H:aP72%œ£“™±¨©¥³ª¥µ¨¤¼¸Á°ºÀ²·´½´¶¨²±¤²³§ ¯¶©›¨º®¤°±¡²´±¡¤žž¨©±©´©¦œžŸ¬˜™™˜˜–˜£®Ÿœ—¨­±©£ž¬¢§•—œ¡¦¡˜¢¡¢¡›¢¢¨œŸ ž•™›§¡œ§•›šŸ¡˜’•ˆ²nhµr¬ˆp§r´ut¶{œ™¦Ž£~ž£~°u‚ÒÒu\®|…¤n›ª¦j†…}­}˜™{±s“y³e–t…žnŸf”RɋZÂ\Ÿyb_­_vs…a–ˆ]YʝoÀ€tMKµSUÆdUQjceXAOj_liPUFH9=WR[VYHB?J<2?;5=<56>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>II:1746@>/.24252-).26,742&60;5:=Pqh9'Wi\ANT_eP5G=aM62.£ž‘¥¯­¥©»­¦µ¥¨¶»¼³»¿¸·µ¼¼´¦µµ£³²¤ ¬°¥˜§»®¥²±´¸ª ¥¡ª¥²¨¬ª¥š›ªŸ––™™“”¤«¢˜“¦«±¦¡•’«Ÿ¥’”¡œ¥§ •›¦§¢›£Ÿ®š žž–œ£Ÿ¥”•™£ž•™–“›…¬|x¨w£‹‡ªp®‹…¨„šš£‹“š‹¢}’—‡®„³\r²S¯}‚‚£~q×}w„~†™šw¯†Š‘œˆw´ašeš‚•l’[°WKšu˜yf`­^vv†g—ˆj]¯w•Ÿwl5yÈ®³_CTo^g`EPl_pmVUM.echRYP;AD@L:5?91><16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK97<46:>/04333.2..18*.32%!03767=Pke>&Vg\@=V_cN6GB`I:77 ” ·±™³Á­¨²§ª²º·µ¹¾¹¸³·¾µ¦¹µ¡¶­  ©¬Ÿ•¨¶¬¨±²«­´¤›©  ¨¢µ§¦ª¤šž–¥¡””š’–¤¨œ”§­°¥ ”™¨Ÿ¢‘¢š©¦¡•š¦©ž¤Ÿ­  ”ŸœŸ¡™˜œ•–¢ ”˜‘¦†©~¦y¡„ªp­ƒ§†—¡£Š˜—ˆ£†”ªz‹yp±Z¨ƒ‚ˆ xtØv‡t§Ž›’¤|•Ÿ„{²^œd }‚•n“\«\[“‘hgªcr{€j˜†q]«Z‰ kndOJC¡\ZMt]bfMZa_rt_JU5Jš‘XHE=GEAL35A8.;>05A78@<6=<F?:<6?=B7.HVJE@H6KIN@IK@EN::@4.;>002154+*05/7,&21($$6671<OedA&Uf[?1T_bL7FH_C1=7¢šš¾­˜³Á®«¬¨§µ±¸±µ¿¹º³²¹¼ª»¶¡²¥Ÿ¦§§ž“«²©°ª¶­ª¯¡˜¢ ¦¤¤º££¬¡—œ’£ –•Ÿ›•™¡¡‘ŽŒ©°°¦–š§¦Ÿ’¤˜¨«¨•˜©¨ŸŸ ¤­£ ž¡Ž•¡™  ’œ—›•ž¡–—«œ®nr´t©Œw‹¦t´zu´‚”§¤“‰¤‡Žu¸n‹{‹¢kk¶Z¡†e——h ¢§m”r´s“™³j…’ˆ­ju´af¢n†’k—\­`N¡|‡‘Rs£ly~n˜†o\¯V<œweTon.[§ObRkeblYb\`p|cSYQ>?lo2BB@>M:!7@6.;@37C58??3;<CDBJFMIF62JTKEBJ6IJP?HOCFP=<E50;;010/75,+,326/#00,,289/9N`eD'UdY>/U^aL5FM^81A8¥šœžº£œ±À®®««¨·ª¸¯µÁµ½²±»¸¬Â·ª¬¡œ§¤¢’««¨¶£³¨®ª¡—¨ ¥«¸£®œ–™¦£—Žž¡œ™žŸ‘“•«¶°¦˜“›¬©–Œ“¦š¥­£‘—«²¤ ž¨¬°˜¡¢™¡— ›–›—¡“©”«™‡Ó”š»u±Ä€Ä‡~֗œ¸yŠ’™Ž˜ŠŒ§‡y¢¶u}wv‚š²aƒºyÀ|u¸bµŒ‡©}–‚¬©q{u¼ˆ§ ia¦Ž¯¡}Œt‡«}¾ns¼t²ƒuxŠmšˆpm¤t½]w}[ay¼jZV[iy^i`dfbmxoX[YCA@q?CG+4H"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,;:08LXaF'TcX</T^`K5<L\-6@9§šŸ¢¼£—°Ã¯­ªª­±¨¹¯·Å±»³¯¼°®Á²­¦£Ÿ¤¢œœ‘«¥ª²¥µ§­¤Ÿ–š«™§­¸£®™•¡‘¦ “Ž£Ÿ™Ÿš–“¯¹±«•–£§¦”–¥¤­Ÿ‘ ¨« œŸ©¤²¢¤Ž¦¡•¡™›–•¤™° ’•ªŸ…™¶€’’¸–xƒ“›¶wnlotoy„Ž‰ržÀ»¼š{²¨pt‘¹ƒ|††‹†Œ{Š‡Œ—}¤»¹½œuy³£tu—ut°u˜žf†i¶trqw¶Œ^y}ˆgƒylyb‹¬pt…~X[§iDdYTf_c]cQgfqmuBMOLD;ZL>J3<0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITBKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7KT_G'SbW8*O]]=+;VV'=:<¦¡¡¿¦•²Â³«ª¨¬«ª»¯±Æ¯µ´°¸¨µ¹®«¤¢§Ÿ ™”­¥®ª§¶¨¨Ÿœ–¡¤ž¬¥¾§¡ª—•œ‘¢›’¢¨¢“ž—’˜”²µ¶¬˜£¤¢‹“’¦œ¦«–©¥¦›¡©§§¢¨ ‘¬ž—¢ž—–˜ž°©”œ§¢kjœ©y‰t›v{fˆ{½¾Àºo’ƒq”…_rjZ^›‰ac‡–l`”cmœvb•l€™•”e^`cqš‰hrŒ{†”fj~ptx~}b[xthP\n„||ŠjWlzrIJo…pNrMDV\f`LZWfc_OZmvjrRODDM<HI<L>2,2A?8/5?C<9;@;=C>RVVWYZ[[\]`aaa`\UG5CFUEJOHFPIIH;8=51:.1;:./-76=5&"/*2,%;8-7IR^I'S_V4)P^L(3>\O'?2>¨Ÿ¨¡Á¤™´¹¶£¬¦®§¨µ²¬È¬°´­¶¤¾²³¨¡¤ªž£œšš¬§®¤¥µª¤›˜•¢œ§­©¾¨©¥•”›– š“™¦©¨‘Ÿ˜œ°²¾¬š¦§¢‰“’©›¨¤œœ¬ £šœ£§­¢Ÿ©¡™®›”¦ —”žŸ˜±¥™¢¨™’Ÿ¤¦›¨¤›šœ›‘—‚hn}rw‘—”„‰´ª…˜•ŠŒ˜—ˆ”•‰ƒ““‰’”™“™—šŸ¡š›”Ÿ›y¤…li{}€u‰‹‚r‚xyvvŠ|‰jstƒudw}vkoyl_b[ogMXYfj_WYpzomfSOFS9PZNRO(+:KB635=@A9:C><ENSSTVWXZZ\]`bba_^^[TKCSGKNDGPLOI<:;489,2;820)6IRO8")+/2#4;*7FO[J'R^T10T^:+=8]K,<-@² ³¢¿¢£°±· ª¦³§¦°µªÉ«­²¦µ¦À©´¡Ÿ¥¦œ¥–•¡«§­£¤·¬ ™—– ˜­ª¦ÁŸ¬¤–’œ—Ÿ˜”•£Ÿž£¨“˜¨¨²Ã¯™ªœªž––©ž«œž¡­˜¡›¢¥¯¦¡¤§ž¬˜–¥™™¡žž°¡¢§–™”š”¡£—¤Ÿ™¡Ž˜•‹‹Ž˜®|•›‚‘‰©¨…€˜–‹„ŽŸˆ{„‘……š‘‡†Š•›—Ž˜ž£–™’œ~e¡³®„‰„w{Š~wyzogy‘€ˆjuyˆrhsyuƒ†jtbxe_hdcdfjXk{qjk\SLPD_UF@>?,4@F;45;>A;<?>>HNNOPSTVVXZ\_aca_^^]^]XVJKLBIOMRJ;<:786/3964.(&$-1..)+*7%+<(6CMLD/T\Q05M[17E4\G5<,@³ ¹¯¾­ª­±² ª¦²­£¬³°Å°«­¤³¯¼¤´œ¡¨£¡žš—¨¦©¦¤¦³µŸ••žšš°¦®¾¡¬¢‘‘žšš”’–¢œ—©„©«£´Ç³Ÿ©£ª––˜š§ž©œ ¥¬”ŸŸŸª®¨¤¢« «šžŸ¡˜¤žœŸ°¤™Ÿ©”™™ž“¦›™ªŸœ—f…“}e›cyŒlhjz£«ješ˜~g…‹eeihz¢ŽkhŒ˜‘¢wkj‹™£Ÿ˜skmz„Œ†yXe]…^l‹Š‚w\gsww’€ˆnw‚xsmy„svˆ‡‚zh„X]jsd]sˆij|qmc]QNVIdX@I3=F7?FD71<=?AC;;DGHHILNORRTW[^`aa`]]]]]_]ZUODHOKSN=>==6535554*&&%,*%.++'6*$;'/AI[J.6ZO6)EY/DO1YB;?.=¤žº½¹¯«³°«¥¨­®°§®®°½±ª¨¥®°° ­—¡¤ž¢šš¦¬œ­¤¦¨©³®ž–¤£°¦¶¹¥®£š¢š“’› ™™¦–{¤«¢¨´Ã·¥¡¦¯ž•ž£ž£¤ª©’Ÿ¡ž ª¯ª©¢ªž¦›¥ž§ «–¡œ¥±¤—¬–¢Ÿ›”¦™ ¬™Ÿ~½„‰s´s…Ÿ†­hw¹Ä¸q’¡£z¦˜™t«‚}ËÀÀºq‹£‡ƒž}–˜ˆžÀ½‚–œÁÁ{z‘ŒšÂÀ}j¥²ooÊz›x’„€vy€yq{€†pw…‹’xlu‘be^wc_e€b^thmdbXKUIQYHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^_`a_^^^^___]\SMPGUNA@?=6468266*&%#)*&.+*)109*#>I[L*#CP/#F[3PY/UAB;/8•¢¹Ã´¯¯¿©©”£°ª°¯®¦²µ¯ª¦§¦±« «˜›£ œ›ª§¢¬£¥¨¥¥´¤ž£“¦®­¸´§¯¢’‘™¦“‘ ¡˜› žˆ¦«¤«­¿¿± ¨¯©–‘Ÿ¢™£¤ª£“¡¡ž¬®¨ª¥£¡¤Ÿ£¤œ­©‘¤›©®ªœž«®£—˜¦—¢¤˜žΔz{¥‚z–—›_­]Ž¨€¡¡|§•›u«ƒ¯^dŒª{¨‡… t—“ˆ³c‚«† ³j„¯t|–‡¸a‚­Y£Ínv{Û{™q~ˆ“ve{ˆuvl~‡m}…}k€Œ_pjof`_xd[qhjdf`RTSW^JOC5AHED8>5;@?A;=8@>??BDDFIJLNPROS\___^]]_``__][WOUJ=?><5578164('$!',&&/(&+360$7:SL+,-J0';[:L-!P@F4.1¬ÁÀ¿´´°·˜ž‘£ª©­µ«¦²­¬¬¤¬¦°ª¡§œš¦˜œ¢¯Ÿ¡Ÿ¨§£¦¡Ÿ°¬›ž–¦®­±«¨¬ ”’›Ÿ¥“Ÿ¥—¨£ž­£ª°¨¿Å²§©±­–’žœ¢—¡ªªŸ•¡žœ­®¦©¨›¥¥¢ ª’¬³–¥¢ªªž¤§§¢²¢“›§œ¡œ–•‘—¡r†Œ˜v†¨‡q±|q¬}  ¥žx«‚~­r­¬‡†Ÿv˜’{|—~ªˆ¢Œ‘‹œ}«zˆ’Ÿz­VœÄ{p’Á}•mupŒmfwe†oaxnrnˆ‰Žƒlcmsuo`fmd_oijnfcWS\`ZRRC8II@C<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;91478452&# 1' 1''45-&7=WJ-<(=1)3V@F!G;C1-+¯ÓÆDz³Ÿ££¢¢­¯·¯©±§¨ª¨®««§¢¤š£•Ÿ¦« ¢¦ ¨¨£Ÿž°­˜›–¨§¯­¨§©ž—•š¤¢’”¡­›§£¯¬¢¬µ©¹Ì±¬¦­«–”œ¢™Ÿ®¬–¡™žž©±§¨¨›ª§£¡ªš¯±¢¨«®¦š§«««³¤“˜¤§œ–“…¤k¤uŠz©u{²q‚¥Š˜Œpˆ ›‡¤_aR«…€®ƒœu®‚¨††Ÿz™—†{f€£Š¤˜†£}©”†®^{¨U¢’{£Ÿ€|İŌs¯´³¹rb©¯Âth‹‹–€k—mkxxwnkfddqqf{ic\V_iXXTLLQLCCAB;C@@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^`a`_^]\][SIB6799664,&$" ''!+-"$.!3-&@DWH,G+56*1PKL# A9D4,'ÂÉÕÖÀ¡™«¨¡¯¢Ÿ°´°°©­£§§ª««¨¤¦ ›¥Ÿ¦§¦¤¬š¢¬¡£Ÿ¯£ž›“ª¤µ°¯¡©›œ–•§¤‘›¢¨ŸŸ¦œ°¥¢¨±¬¶Ç±´¨«©•‘¡™ ¥³š¡”œž§ªª¢­šª¦ ¡©¢²¬¡ª³²¢œ«©±°¸¥”—¥ªš“}ªmŸƒˆv«y|°n‚¤‹‰Ÿ–•ž–Ò¸´¸É‚²_a”©ƒ¥ˆ‡ z˜–šyªÉtš£”¨©’šŒ~š‰šÆÆwe¡‚¥sŸŽ‚}¯_oµc±uK£†m§Gƒ“dŽ›‘{o”|myt|zm[ejrqf€i^aXcm\^YILLJEDBA=A<A?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^__^\\\\\XMB75785/)(%&%$&),5FNPPMFLJVF*L0/>-4NTQ;<F2,$¨¤Àƹ­©²®­¦¢œ²¹¬«¡¥›¨¦ª¬©¦ ¦¥˜«£Ÿ¯¬¦¡­šŸ©¥§µ £˜”¨«¶³¬œ¦œ –¦­’šœ§£ ª§®¡£§©°³Á±²©¬§”‰˜¥›¢¤¯¦—¢•˜œ¥¥©™®œ«¥¤«£¶¬¡±¹°žœ°¨´´µ¦–™ª¦œ¡ƒžNwš‚€žz„£|‚¤„†¦ŸœŸ”„¸||z¹‚ÌÆöw›¢‘‹Ÿ~™——ŠvŸ—Š¤˜¤§~¯…›ƒž„¬}™”a¥l£p…}–„r¬`¤sq€ša¼}RUu‘¡•z|Ž‡ryr„~o[lnwrjnZc_hnbd]LLQSAHGFH::K>B108856877-*5==?BDGILNPTWYYZ[\__^]__\ZZZYUSOH@772.,*.+*'&?QTVWWWYXXWUOTF<E2:P[T6?G,- Œ‡™©¬¤«¹«¯ ›¢¬³µ¦Ÿ¡•¥¯®®¨§ž¥¥š¤§¡³®¢©§³ š©¤”£µ££•—¡©µ¹¤œ££“¢²™ž›¦¥ ¢¯­œ¤¨¢µ±Ã°­©¬©‘†‘œ§£¤œ¥—ž˜˜™¥£§˜­¡«¢¤—®¥»¬¢·¶®žž¶´º³µ¨š ±¤¦ ˆÒµÃ·y‡Ž…‘“€¦x”¢wŒ¡’…¥ƒ‹r«‡†´nri™¤•‰Ÿ}—™‡‡s®‚¥›£¦Š“œˆ”šmp²\¥s“zœl™{™~n©a¢rr~ bs²¸hwŽ’¤—|‰Šˆu{xlhwixsnt\ddmmfh`JZWX<HF?S3@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^`_]Z[ZXURRQF:2230/++(@QRTUTSTVWWXXWUUVTQOQ[U%!2AH#)%’rŠ®¿¿¼»µž—¨¤®¶¢¢™•£ª§­©ª™¥¢Ÿ¦  µ¦¢©§±¤”«£¤­¤ššª´´¤¥œ©’”—¯  ž¦£œ§œµ™ ª£µªÂ¯¨ª¨¡Œ„œ¢¡¦£•ššœ˜š˜¦£¥—©§« £›¬¦¼¬•½°­Ÿ£±µ»­¶©«´¦«š|¨‘}|°x‹€¤¥ˆœm²o¡‡­|¢ƒ¨—š¬‰†­… ”¨ £—…Ÿ™–{’~«™–‹«w ˆ“’y¯]£|¦§dž€|—uj®]¥lr…™]`[Œ m”¤—’Š“ˆwy–~il~b}tmy_gepogghBY_Z=JS2S8AAC7$$3+''3, /667436:@CFIKMNQSSSVZ]_a`aaa^][ZXSPONI8152.*,ATVVVTTUUUUTTUTSSVWWXVUVQHFIJ#((¼’›„©Æ÷Á´Ÿš­ ®¹¦£Žš£¤ ¯®©Ÿ£ž­˜ž¹ £«¡°ªš®¡‘ª©¥–Šš­±¬§ ¨›­˜™­¢¡¥¡™¤œ­—Ÿ¨¥¶¨¾®¤©£Ÿ‹Ž›› ¦ž’”™›”™™¥£¢˜§«ª¡¢ž¨§¼¤—í«£¢­´¼­°©£¶±«­šw¯~‘‹œ†‡|º­‰˜d°Œe–®}¡„§—œ‚­‹…°†¨š¤¢¢‘… \lk‚³`­|{‚²lfn™—‹ˆ±Z}´[¤ƒkÈ¢fŸ|»YvµZ²}S¯z¬X€¡m—¦˜ˆ”’“xwŒ›|cs|bƒwt€|aifomfefOUc\AT]=H(>9=4!!,$2. *1/04579:<ACFHJLNPPRTWZ^```ab^_\[XUPMJGC553./@UYXWXWXXWWXWVWWWWXWWXYZZ[\XWWGB;ҟ³±·¾»´Á³£œ­¦¥·© ‹™ Ÿ²±¨ž¢Ÿµ˜ ³¨ª«ž°­ž¬œ•®¨¢Ž‰›Ž¯¬©§£¨š®“š©š¡¥Ÿ™£¢¥˜ž¢¨±¨»®¤¨žŽ|‹š–¡ ™‘šœ‘™—¨žŸ—§­¥£¤¢¤©ºž Æ§¦©¡¬¶·®°©¡¿°°°˜‚ª’£¯Ž›€†¤—˜€€¸Ãº„“…¨™ƒ¬‹ƒ¯Š©š¦«‘~սªb¤¿½}£‚ƒ×º·µ„”’‚ž½¾„j£o«„nz²±Çƒk«±½¬yx¢¾»t€•Œ¤™˜“™w™yb|ydŒfx{`kejjbPb[Si\@T`BL)<:4/$%2 $(0496678;>ADFGJKMNNQTW]a\__a^`[\YTQMHC><A?5=SYYXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ»•´´±À¹²½³¢®§¦³¦Œ—¥¿©¶¯§¡¿¦¦±›ž±œ¹¨Ÿ®¯¥§•”¯¬—Œƒš‘®¦£¬¡¥œª ˜Š£“¦§›š ¨¢˜ «¬©¸¬§£š—’{‡™‘¦›’˜™Ž—“¨˜ž–¨¨ž¨¦ ¢ªºž©Å£¡°¤¬´µ¬²¬£¿«²²œuvª¥·†eŠ pg¬Šnnw¥› ‚v±›—p‘Žr—ª¤›™¯¤rlmmf‹xomƒ™q€zipig‰–•—qhi…†gq†d]ŠcioZ]g~x¦`br’pfd€’ ••—’šz…“td†wgŒjx~ydlcflbJdWIjY:PdDP'J9+# ",)-2.5:457:<?ABDEHKLMOQSV\WZ\`_a]][TPLHD=:AB7MXYZYYZYXXYXWWVWY]^^]\\\]^]^][[UW^¨•­´©º¹²´ª©¢®Ÿ¤³ª™’½±ÃǼ´©ž¿«¬£ §« º£¤®¬­¦Ž–­ªŒ…•–­Ÿ¦ª¢Ÿ¤£ ‘‹¥’¦™©™–£© –œ¥¥¦®¹ª¬™š“’{„—¦—‘—”—”¦“–§¢™¯¥¢«¹Ÿ°Á¨¥´§­±³¬°®ª¼§±»˜Œ¢©¦µœ‰—£˜†©›”’ª´šœ¤­¢´˜¤£Ÿ¢£ž£¥¢—¬§Œ’“‡“•™“˜•„¤š—•Ž‹“’Š‡„~gŒtƒwt‡Œq§m}–“””Ž›‘“”“€…’‹phvo‰wu|yikddocUaX@iZGb_MX+E=+&!640/ %2(*799469;>?ABDFJKKMPPQWUVY^_ac]^TQJEC>9=@ASX[\YWXXXXXYXXZ[[\^__`^^^__```_YY`¥–©ª¤µ·¯®¢°¥­  ¶±‘ŽªÄ¼Ã¹¶©¡¤›¥°¨¤·§©µ§¨‘˜¬£‹ˆ‰œ§–­¤¡š¨žŸ“•¤—¨š©™”¦ £š§˜ ´¹§ª˜šŒ{”Œ¡”Š•‘•’—¤Ž˜¨žš´£œ¦«·¨¯Â¯¤¸§°°²¯«¬¶½£²Àš“§¤¦µ¢’§Ÿ©Ÿ’Ÿ¢­±›¢¤³«³š¦£ž¦¬ Ÿž˜­ž“š¢œ”—«™˜™—–ž‘‡ ž””†“Œ•Œfˆuˆwz‰„tœjˆ’–•’‰}Œ–‘–ž™’†–…xq”ry‰q{~jnd_pi`\_YmbP`bOX9FFE=2<=8/*&+)&&406658:==?AACHJGJKLMSSSUZ``i`eVPJACB;9EMV[^^[Z\[[[\]]_^]^_`aabaaa`bbbdb\[c˜–¤¨£°³¬®£©§­ ¨µª›£²¹­ª«¡¢™zœ¡°¤¦±©—œ¸¦£”˜©œŽ†Š‰›¢¯ž¤–¨ ¡’—™œ®‹«–¨™§Œ˜¨Ž¸µ£¥˜›ˆy‚“Œ›“‰•‘“‘–¡‹œ§œ·¢ƒ®µ¢°°u¤¿¤³ y{¢­µ¿—x°¦¡Š€ªd\bw Ž¤žƒ–~m”µ¤©°¬¥f ¡”tz›™p™ª™l¤©Šeœ¥œ‘—˜—‹’›„›”ƒ“‡ŽŽ’Š…xkˆv‡q|†ai‰Œ•“Œ[v•‘ggŽŒqy¡••dx—…€v—h‚‰‚nykpd_vokkg[ecaamQY=MMNRF=@TB91/&4:306678<;>@ABFHBGFIKLTUUY]`hfgXQI<DG<9UR[`ab`^__`aa_\]___aabcdabaaedchd^]fœ–¦£¡°±¬«ª¥©®£§­¥’•ª´®°¥™©¥ª—s‹œ¯ ¨«§”—¹  œ¤ž‘~ˆˆšž¬š¤•§¢žŽ—’ž…u®ˆ¦š¨‘–£ˆ›¹³§ ˜˜‹‰tv’–“‰“”Œ“Ÿ™ž¥˜›±•€Œ›µ´Œ’½¨¢~§£{¥±ºƒŽ¨Ÿ„Œ†±©¯ŒŠ–¢šy€‹¬†ž£©«©‰–‡šw¥œ{ˆœ˜§ƒ{³{Š† ˜™”˜–––ƒ™šbyˆ‘„’‹„nqˆz‚q†€‡tˆ…—“x–h“t šs{™‚›™„˜~‘ˆ‚˜iŒŒ„jx{qpfexnilj[diidqZ\GSKQ@E5-YTT6)!09=>643568;:=>>?DI@IEJKGRXZX[aaifYQH9DL<>bV^bded`aa`bb_]`aabbbcfgcba`edcgcaah˜¤Ÿ¦®®«¨­ ©±§§ª¥™“¬Ä¼¯ ”¥§´ƒœ«œ§¢ ¾ž™Ÿš¡‘}†˜—ˆ¬£–¡¡’”‰†€‘¨Ž‡¢œ£“–†ž¹±§š’Ž…pu‰•Š”Ž›‹Ž‘ž•ž£”«‡Ÿ´‰´š®‹Êˆ«¯Š·…°„³²†©Ž©™|¨r{wœŽ¦–h•¤y´Œ¡ ¨ª“™Â‚€«‰™¡rž€›¥}—…•³¡}¡“Ÿ˜˜€Ž”œ‰˜’‹|…”†•“Š„nt’†€{s‡„}…u†ƒ˜Åf€©‡¢j—€™€ŠŒƒˆ˜o’„gwt{vghupghk^bnlfjWdE\PL2E46M`c7&3<EGD:63658;8>==>BL?NIJLCPZ]\Wb^jl\QE=KM@IdX]cfhgbbbbcc__babcccdiicbbbecafcbbi•—£ °©©¨¦¬ ¥¹±©«¦š”ž¡¤©¡”£©µ¢¯ ¦¥ž‰”½š“ ’yƒ–•‘ˆ«™œ›š¢…Œv››Ž ‘ˆž£›–˜—†¢¸¬¥™›ŒŒ~bm‹“Œ‹Œ—‹‘ž’ž ˜ §~¡§‡­ –® ž‘‡‚¡­²ˆ¤Ž¬›Œš~¢v€™”k«uM«x‡“œª©‚ª«~„¡|{§jž€“lg—†˜·‰ž~n`cXƒ—{dg‹s™}y—l\|—n`Sq…\`mz„`Ye‚~…™q¨ªkƒ£nr¥oŸ›gdžlZlˆzeY_‚~aWPoventqjjo]ioljgWfM\WE8A4GC^k4+ICQMN=84859;6@;;>BO>QRKMBJ[]_W^^cu`ME:MNMTb\[ffiibbdbddbab`bdcabjkdbddgdbgeach˜—ž ¹¡ª¤¦¬’¢¶½«¯¢™–ž ¥««Ÿœ­´¡§‘ Ÿ §œ™Ž™´™‹žŒ•‹u”‘Š¦––˜žŸ~“……¬£‡œ‘Š˜¨˜™™‘‡¥¯¦¢•™‡‰€inˆˆ‹ŽŽ‰Š‘‹‘¡‹’Ÿš¡¥“£¡” wœ–§ƒ£©€†¬°‡¥zŒ~„š}¢ps“‡•{žŒym‡œ‹š’œªœ‡}ƒ¢tw¦gž~w¥^˜{}“s¢n˜·´ºs“ˆ€¶¨dÆ¸|q•¶Œq€›£ct¬«a~j³~n~ˆƒƒŒ˜q€£lr£rž‚}£^œ™³•o{—ž³tr[ž²‚ibptuqhoXjkqpd[f\aKC=D5QAYp2<RG_JR=<395::6C<;@IP?TNNQ@E_^[YW``{dIC8LWUVcaZffkkbbeadc`ab`cc_`cknccddhdbgfchh”–•£¹™«œ“ Ž¥¸µ­­ š¡›¢£¤¬šš±¬«’— ™¡¥™š”ž¬›‹‰‘x‹…q€–Š¡“”—}‘ŠŽ¨ †˜Š’¢“›šŒŠ¨§¤ž–‡„~k{†}ƒ‹‰Ž“Ÿ•›Ÿ› Ÿ‹‰wœ˜¢ r¡Œ‰©‰¨‘˜ª®®Œ~z ™y£“x€s—ˆŒœ}•Ÿ‡›Žš¨ˆ£d¡~Š–›mžh›Žoš™{€Š§}rhtªƒžƒsªg”š]›…v„hªj¸f\©pœa•Œ_§vwŠŠ€hšu‡“’˜~žl˜j¦™\¨~w»j}©ZŽ„]³g\nqxwki[piwwa^cVaAPEN7VBRm4JZZ^NZD@151;;7H?:CHU?YSX]>Db]V`Qad|iEB9N[]XdfXffnmbbe_aa__``ec^bdoq_deekdcihgki•‰ª¶œ¨‰c•œ¬»²°¬¥›š§Ÿ¬™°§ª—£š¢Ÿ™–– £™†‰iˆ€r{—‡Œ––„’”˜z‹„–¤œ‰•†‹‘œ›ˆ¨¡Ÿš‹Š€€i†y–Œ{ˆŽ‡Ž•™}’¡ž ¡“˜rhŸŠ Œp’‚©‰š¡¥ª¢ª~°­¤¢¸—v£³¢£ˆ”xzª™¢Ÿ™‰˜r¡}‡°µ}lš‘¡x~™µ££«¨„™|š|œštªZ]o{—ŒxžbM{{…dz˜BMŸY¢js|Žo‚Š„™v›y‡‰±³~š’¦s}mp|”o™ri£]•vHec`sp}}ne_kguzbb^O]V\TV@YEPfDRV\aX^ID=B8?B:HE8LEXAWRZVEFa\Z`K`m}qEC<U^bZejVghmobff^a`\]^`hb_ecvl^egfldelhhli”±®š„T_¡§´º³³©š¢‹š©››§’ «£ §žš™•˜¡–‡‡‰w…ny•„›‹}‘“–ˆr‰’¡›r’ˆ˜”Ÿš„Ž¨›™•ŠŠŠ|ƒl„…q‚¡Œw„Œˆ†‘˜”{‘¢Ÿž£ˆ®†}µ„ž{¦–z©‚—ž‘Œ£ §hxn~™s sq|…˜o“‚­|¤„§Ÿ›‚¤p^©hv£dp¦aœÓ|{™xrsc¢†~¢r£vk³‹`‚˜Štª²¨¼wƒn¿¦ª´^œor—p‚s¢r^¤gt¦`h¦l›Ó˜yšnvy—k›yv—rl©¥g_dyq„lhfcmuvf^`QZePQaHVIT_WS[dj[ePECKLJKAJD8P@PMXSXOSQ`eejSdxywIFEc]eZhiSihjncjf`c_\]]_hbahe|d^dgdkdjlfhlh˜›±¬T]Kª°²µ°³¢œ˜„—¦  ¢Œ¤§Ÿ–¨‰™˜™”™“’ —Žˆ…{p}„h|ƒ“š‚w‘ŽŠp€†“’l˜”|ˆ‘’£•ƒ©™“’Š…‰yƒvˆ€nŸ†w€‘…‡˜¡•x’¡£™Ÿ‰³¡¢¶‹z¬§¤®¥p©€›‘†ž”~¥£š†˜qž„¢­¯‰—‹Œ¤•ƒ¯£•wµ¶¶É¢s”ŒƒŸa—©my–‡ ›u¡‡w ~–‹oMf£’qšˆs¥{zubƒ‚m~ lrd`œst—k{j´¶´Æ¦s˜}yœjš™«sšlsw—i™yt—qPD}³^jukx†fkfbstolU[RXgOQgIULXRU\gknUgWMJAIMJGJNAQJPdcjmeuss~x{nt‰z{TQNm^h\kiRjhilgmgce_\\\_ibdhk{_]dgcjfnmeile¢‰°¨…e?”¢²¬¯¯µ¡¢–§¡¡£‹¤¦œ›¥‚™——Ž—›“Žˆƒyky†eƒŒ–ŸyuˆŒ‚j……’„‹…zŒŠ•¥’‚—¨–‹‘‹€ˆz€}‹yp …y”†ˆ•ž”~“¤¦›––ƒgnxœl¢d|r¥xœ˜ph§‚™Ž}¥{¡—ƒ–rŸv‰”•¹mŠ¢b}™£—‰nsk«ku no¦a›i‹i–‡›•u¢~š`‹†uoˆbh¡fžj›updgˆ‚or¢[_[d¡n^ˆŒq|€trd¥nx¢cf§g—q‹—m¡oRˆn ^d§T‹]T˜mmrkqmphkwsjnQVUUeYSlIXN[HWhhrjYkVPREV\MXSaUhj^wu{|p}|r‚{sw€ƒw^QsagbpgPkhhklohdg_]]]`jbjivu]\chcjirlfkmc¥™¦zetm‹§®¥©°±¥Ÿ‹–©œ£‹¡¡š¡¢€•™“Žš‹—ŽŠ{†q€ˆh‹Š|—šst‰}|eƒ‡•Š‰•š‚|ˆ†–¦€¡ª…Š‰}€€Žsi¥ƒ}…’Œ‡—ž‡‘©¥‰¦x–›~¥‰–Œ²™ž‘„¯—Ÿ¥y˜Š{©u¨„šn¥¢Œ’„Œƒ¼m|¥¯‚‡…‡•—ž¢~¦|r¨•¡–hŸ~o¬c–Š–“x¨mª£‰uˆ‚w«‘¦ˆk’±lw³Œ©l‹†oo ž’•b«Œªw€Ž§ŸwŸ}…¤• g™‡u¬fž­Œ¶sv¾Œ£“Yƒ¦«aurto{upbj}nglRTXT``\kL[Q[I]lmv_[qY[_Zgsdmoqcqt`wz~yryƒsƒ~{{Œ‚€vbydcnsdRlggomrifia_^\ajbll{o\\bibmiwmglnb–¦«€ž¤–ªªž¨§­£˜ˆ–©™¢‰š¤œ¨œ„Œš†œ‘…’ŒŒt…zˆƒo…~—“st†r‘ƒn‹’‡†”}{‚…—¤¥¤€Ž‰„”u‚‡“nl‹¨€‚‹“ˆ›žˆ‹’ª¢ €t”—ˆ~x”¯¤‚œq†y“Ž†{s©r}}z—–›„x{}}ˆ”•“‹w‘™¡¢…{ŠlŒ†\zyszqin~“Šq€t‚”“q†„‚e_Œxvs”upzoo‰o…†_wixŽf‚ƒ†ªœt}–i‰ˆo~u{‚tmlfŒsw{—w„ZjWyinwrqowxo]k…nhgVY^V\djcU`T]Q^owykjwdijju|pqtsaoubs{xuy‚u€y‹…‚}{m€mdyn^Wnghukxjiid\`ZcielqunZ[bkdlkymhloaŽ•º©§‹¡¢›§¤™¤«¡Ÿƒƒ–ªŸˆ™¦š¨˜‚œ‹~–”‡ŽŠ‰Œr‚|Ž|~„{—Žtrƒp•†|}’‹†††y~€†˜£Œ{¦ŸŠ…„•‚†Ž˜wq„ª…‘œ‡ž†‹›§Ÿ «ƒ‰•›~Š—­¨“¨‘xqŸ“…}”p«‡q~•qjo|Ÿ‹‘Ž‹hn]„œ s—‰rulƒvt€Yro‡‘‚~Œj]id{…„ˆ€`ix{œ|„ƒv‚‡„izŒ‰lbqsƒw_sƒŠ‘¨–‡gŽ‚lvŠ‚n‚Šwmdecy‚z•Z[ifmv[{ywtnsrƒf\m‰kkbYX\YXjqZ^`Y]]dr}ztotbjji{|qzvtdmthl{uz}{yz€€o†‰ƒ{}s~zrhT\rilvpugkgd]aYjhkjqrmW[emlgryohjm`ŒŒ«±¡£¡šŸŸ˜ž™¨¡ }‚–«ŒŸ“†š¡‘¤•{˜…|’™‰ˆ††Šr|€‹v…‹‚„–Šro€s˜†„~“ƒƒ†Š‚z€„ŠšŸ¥Ÿ†wŽ—ˆ•Š‹œ—„ƒy¬—˜“‰œ†‡¡ªž¢¢£‹ˆ“›£™–«¢¨§¡“œ‰™‘~z†©€“‘’“œ±¥š”±’˜„¦–¡Š‘„‰“‹l}Žwwf‚†‘‹}‰ž…‡‹ˆˆ…„‘w|{u›¤Š‡‹ Œ‡–€ƒwqu†„x‰ˆ‹‘§‘„‡Ž‡‚‹Šzƒˆ†Œuj€ƒ|y™iqh`sŠp}{wvowt]^o†gn_^YZ\SgpUc[[`lgt{{rnocjih{mx~phpplf€{r‚€w}„{mƒŒ…|zy|~zƒxNdvjsnq{dkebb`[sfpfrqlU]ltmhxzpgikeˆžºŸ—¢¡˜•™˜”˜¤ œz~—©Œ…ŸœŠ–|y•ƒ{Ž™‰†ƒ„†mx€r€‡~ˆ“„mk~z—‡„ƒ~€†„‡|‡ƒŒšœ’†©‚rŠ…’‘‹œ‘|z©ƒ‘—•Ž›–……›¦Ÿ¢š†ƒ’š™™™¦¡¦žž—‚“x}‰†§|}‘†˜ª¡œ“œŽ©’€ž‰•› „˜€ˆ„qy†rua„‡vŒ™ƒ‚†…†„•nzvu”¤Œ†›††uŒ~~ss|‰…{y…”¨‡„‚‰ˆˆt‚…†ˆymj|{mhklf^yg|{vtvu{w\`p}nt`cZ[^QflSdZ]`jhty~pllcjjg€krkktnwn„yn†€v‚€}…wq‚‡~{{|€{‚‹`i{kuhjƒdjc`i\cugobumlTbqyeoyzrejmm‹ŠŸ¸š¡¤Ÿ“’–—‹šŸžœzwœ¤›‰†¤“Š˜™yz…{Š‘ƒŒ‚‚‚l{xr€…}Š|kh}‚—‰ˆŽ|~…„‡|€Ž››‡¦›pŠŠ‹’† ¡Š…Œ|§‡Ž‘–’–’wŒ£ ¡–šš˜“š£¢¤›˜’œ€‡{†‘‰¡~|—¤  ’™¥Œœ’Š•™““ˆƒuu‚qwa}Ž†sŠ–}ˆŒqŒ~‚…†hxrzŽš“‘€˜‰Œsƒ‰}}rz|†|{“Ž„—¦”†{„…†„s€„…wdpz~xypkjf^~sh|uus|s€j^`tvpwdcX]^RihSdX^`giuxqfkclge€jm}gmpj}w…zk‹r~uv‚†|z€}jrƒntibˆhlb_qVtolm`xhlWjsvctzzqbkoy‰Ÿ³’¥¦Ž˜†œ š›{u£ž—Œ¡Šˆš–x|†‡~„Š~ˆ‚p~ztu‚…~‰wgc}†—Š‚Šx}€ƒy–€•—•Œ•žš}o‹“…¥›‡Œ‰ƒ¦•„‘Š•—’‘v‘¡¡˜”—yŽ˜—Ž–š¥žš”•{’‰…y‡˜Ÿ‚ŠŽŒs—¢ž ’˜Ž¡ŒŒƒ˜˜„”—š™Ž}ŠŽ‚wr~n{d€|‹†q‡“€‘‚k‡ƒ€Š…fvp}ˆ”šŽ~”y‹}‚‰~|r€y‹†z…’‹Œ™£—‚„‹v‡ƒ€tx†‚s^vw|s}vfkd`~ijwssu}q|ccasnurmaY_]ZkcRbW__gjty…pbjclfh|‚khthloh|xl…q€ƒƒt|ƒŒ€~z‚ƒ~|mu‰ttmfŠljacuVƒipm`yglajvpex{yp_ql……¯˜§©žŽ—‡…Ÿ“•—|v¨š‰˜y–œ‹Œ™x|‹}}„{€‚€xsxys}€ƒˆŠ€d^}‹”‡…‡t}~Š~˜„–“–Œ£ —~q†{“‘Š¦ŒŽŠ’ ‘ƒ“—‘Š˜ š’‘t€Ž’”‰ž§™˜Ž•—u‘‹mˆš‘›|ˆ‰‰o—š¢’•ŠŒ‹†“€””–ˆšŠ}‹Š‚{qzkvm{Œn…“ƒ”xo‚„~~‹esj}‚˜˜…€Žu’Š…z‰wy~‡}„†•¥‘y…‚tˆ†{~qr~„k`ytyp|n`mbe{bnovsxwstav`oluno\Z^]]i]O\Wb`glrzˆk_idjchw‡mflhilg€|zwnˆs€ƒ„}t†‰zƒ}z„}|Žry‹xxml‡kh_iqb‡hqoevgmlazhj|{wpawmŠ™š«¡¤©žŠ‹‘†‰žŠ”–|v¬—Œ–|ž“‘–”ˆv~{Š||€vw€ptszo…}€‰~|a\~’†„„rz€†z‘‡‘‘›‘¤š“}€|Š’£‰Š–šŒ…—’•ˆˆŒ’“Œn„‘‰ž™¢¡˜—Š—“pŒœ†g‰›•{Š…Šp–š”¡‘‘ˆŠ˜Œ‚’Ÿ}“‘”š|‹†ˆtsukqou}‹uo†‘Ž“rt€|‚‚‰}ernz›•~…Šu’Œ‚uŠ{p‚‚‡}†‹…Ž–ªŽ{ˆ}~Š„v|nl}‚€afwstnza^o`kt^pjzyylrpey^nlsmsXZ]_aiZOVWdbepq‡e]ihgbgqnchheig€zwuoŽ…sƒ|u‚‰…x…|x„†z€‰w‹{zryƒkk_ohtkqnmqgoke{amzwpkww‰£™£¨¡¦›ˆŒŠ†’št¨“‘† Œ•“€s|v…xy€rsz†lroym‰v€†nq[Y~’ˆ€vu †Š‘›— ’–w‰~€ŒˆœŠ†’—–…ˆ”˜Ž–‹ŠŽŒŠŽ‘„m‰‹‘Šœ–¡œ™–†™‰l‡¦…gˆŸŒ“€„Œx“˜’‘ˆ‰”~™}’Ž‘Ž›“}‹„pvplnop|†isƒ˜Šqx€u‚‰ƒzgtpw‚›}Š…{•“{xŠur‹|‡Ž{‹‡…Šœ¥‰|„v‰~wwlh}~[qrqoovY^o`pj^oj|zqnmjmw`pokqmYX`aalWPRYeeato„a\kmdcek’m`ff_gjurro‹€t‚€yv€‹€y…~w‡†vƒ…{‡‹{vŠjqc|b…|oplujhnlww_q~y{sus‚~¥•›­Ÿ§–…Œƒ~–•ƒŽt‰ž“’†ŠšŒ•ŽŒzrxt‚pr…tquˆloltl‡vƒ}mnUQ«”‡‚x€vrƒy‚ ‚’’˜›‘˜wz‚Œ’¤š“Žˆ”˜’„…–˜‹“‹‰Ž‡„‘‹}r‹…ˆˆœ™Ÿ›—••€jˆŸŠhˆ¢‰”…’„Šqƒ‘—šŒ‹Žw{“‘{ŒŽ“˜|‰}lwjoklm{€bz~—wzxƒ}zhumv‰—Œ€‰‡|•‘r{†qxŽ{‹Ž{‰„Ž‘ŸŸ†}|wŠ|vogi~v]vnmkprU]nbra_mnyphpfgsuhplawe]Ue``qSPN[ec\woˆ{^\hqbbee‘i_he[go~okqsŠ}v}…€uvŒy{†€x‡ƒs†…~ŒŒ„|y•xfrkƒ`‡~ooj{`imt€t^s|x†wss…|x ›±¦Ž‚Š‚™‰Šœ~Š˜’Ž„‡—ŽŽŽ„wtws€pp…spqƒojium‚n}|musRN‚ßɒ֓|ptƒuƒŸ‚‘v”˜›˜{“r…Ÿ¡““‰’›“…}••‡Œ‡’ˆœŽx{ŒˆŒŠœœœ›–”zŽxi‹”ŠnŠ¥†”‰˜„†cŒ‘˜”‰–‹Œ‰‹pz•Š|‰‹“’Šz‡}m|esokm{z\y{~€†{ziuktŒŠƒ‡†~—Œm€p‚Ž€Ž‰~…{„‘–›œŒ}wx‚Žwrkdn|€igsnghslS]odpZ_lqwgkkbgxsppd`x``Uk_^tOMK_fb[wp‰t\[eu`addŽc`fbXistnkqv‹|ty†‚vw~‹s†z‰q‰‡Šˆ|~™vesn|e‡~nokYknyzr`vz{vrvŠvyŸŒœ¯› ‚…xˆ•~{ˆœ†„žŽ…Œ—„“Ž‡uwoyqoƒomn~rcdwp|nz|jhlb¤šÁÜ®ï¢sluƒu„¡„‘n•”Ÿ“š€‘p…‹£—‰Ž•Š–ƒ€”…ˆ€’ŠŠ—‡{v‰x†…Žœš—™v‹xp‰‹Ž¦‡”‹ž††^‹”—‰ŽˆŠŠ„‰l|—ƒ~‰†Š‘†v‡~~l}dxujoytXˆ{’‡†z€†zgtj‹‹„„˜†mƒwo‰“ƒ’†„{‚’—”š‘utx‡‹trpdrv_rloahtfR`pgkU_nsyarc`i~qrn[crabVnZ\wLLKcf`]ur‰m[\dy^`df„_cc^Xirknkrw‹}sw„xx|‰qƒ„|}ˆ{t‹ˆ‡•…Œ˜shurym‹znsp€Wpzvyqdvy†Œhv€‰q€‡™¨œ¢’„}qŒ“xx‰œƒ„ŸŒŽ|–€šˆ„|svpsjoljm|t^`wv{ptzg`e|ëÚµÉÃ܉slt€vŠšˆŒi—Ž›“‘ˆp…ˆ Ž…‹•ŠŒ—“{’‡‚ˆz‘‹†‚€wxƒ„r‡‚’›–“˜†vˆ€r‡„Œ‰œ¤…–Ž „Šaƒ•…ˆ…ˆŒ†€‡h}”€~ƒ…ŠŽ‚r‡€rwhvritxmZŒ}“ƒ†}€ƒ„‹ƒwbumŠ‚‘Œƒ€€“’~oƒmzˆ‘ˆ”…}‚‚“”’˜‰nqy‹„tjoiov~]rhm\it_QdqhfS_qvt`p`]hƒqrjWgichWmW[tLJKef^aqs…i[\ey^^dgz`d_]YknenjswŠ}sr{vzˆs…ƒ|‡vvŠ…˜‚{“vlwvyx“tnwz}Xy…q€ngxv‘‚dv†…qŠ—†š¡›¡Š†so’‹qvš|‰™ˆ‰|Ÿ„™‚yrsnodr~iflww[_x{zqqiagaÕ¶Ž‘¦xnqw{q’Œ†j˜ˆšŠ…zh‡Š™‡’††—|ŒŒ€€‰{}‰…zu{ƒ|q†€•™Ž’”‚‰v„ˆx†ƒ• ¡ˆ˜‘¡€‰a”‡„‡ƒˆŒ‚f}‘€€ƒŒ~mƒ}ƒulmwutwvkcŽ‚€…|„€…‰p`tr†}Žƒ}’Šzr…g{…Œˆ…|…€•‘“…nox‹~tlmhiwz`giiXktYRhribPbrxmbe^Zj„ntb\h`em_oTZnMGNfd[fmq€kZ[cs_\ckvde]]Zllbljsv†qo|}tx†x…ƒ|€‡ux‰’•{‰†v‰oxy{„’omz€v^ƒtlhzs”sgs‡|r’’„šŸ›Ÿ†‡uu“~mu’–}‡ƒŠš|Œšv~vqoljat|gbiuyZ`w{ymq~edhhW_rs—¼Ä„vq”ˆ}q–‹†›’‹‡rjˆŽ–€{•‹„š‹|Š…|{‰‹”ˆu‰†vw~ru†“…”„ƒrŠw†~Œ›Ÿ›ˆ•ž‰f~“‚…‚ˆ‰q}f~Œ|y€ˆŒ}i~„vgpyxswtlkŽ†‹‚‹€y‚…„l_sy{~Ž‹†|‚s‚jz…‰‡…y…~‚™Ž‘~nmzˆ|usmee{sa[pbWnqSSmrhaNguxf`^]YoosZeb^jn`pOYjQDSf`Yjmm|nY[]mcZbpvcf\]`kicljsvƒqm~|tuƒzƒ‚|…v~ˆ–x„Štˆrxy~ooz€qixz~ml{u•kjx„tk“†Ÿ™ ™„‡n}‹uiw—Ž~Š‚”—Šy•oztqkjd`szh_eqzZ`r|ygqyaee±²wKbZ¥ÙЖq{Šw}“Š„˜‹…nk…’’zy’†„˜Š|†ww‰Š„–€o‹ˆqu~{jy…ƒ¤„“„p€„x†{ˆž›—•’–…ˆp{“‚}‚‚ˆ‚m€vh€…yr€ƒŠˆ|e~…vdqs€iyqpu™Ž†ƒ‹}wy…zƒk\rs‚‰‡Š~‡Š{‰s‚or…ˆ††s…{‚šŽ…ynn}ƒ~uyceh{n^XvZWpkNWqrf`Klwta^\[Zu~spXg]gjr`oNWgR?Xf^ZojgyqZZXkeYcpy^g\^elgfkiqw‡nl~€up‚{‚‚v„‰—‰q‚q{†|zyƒ“Œujy~ko~t|or{z“on~xg’‹‚¡™œ‘‚…g†ƒogy•ˆ}~„‚˜Š|ixskkf_aoym_box\dk‚yaqv_eeÔ꽋2:>‹Žqx…‡u‚–Œ~’‹~mk„ŒŒu|…”ˆ|‚wnv‡„ƒ—wnˆ…lu{ufy‚ƒ¦‹‚‹„~nvx…|‰Ÿ’’“”ŽŒ‡{’†w~ƒŒ‚jqh€~yn||‚‹„wbz…‚rdri~nuru‚œŒ€…€tv~€s‚o\n€uy‹„‹|ˆ~‰y{rmŠ…‘…Œsƒz€—‹‹€umjv€ts[ggunWV{RYodLZrre[Iqxo\[[Y]uuiYb[hfodjMWeP=]e\]ue`toZYTncYcqyZh]`gmgikipw}Žli‚„yn€||zu‚€“„p‹nw~€{{ˆ’‰hz}js{r…zsv}~Œyx„}|kŒƒ›ž–Œ€lŒ}kh~‹z}~ƒ”‚~}Šˆkvqghb[bgro`aks`hpˆybst^cd› n\5Z¯µti€ˆ|‘†u…•…sŽŠ‰vol„‚‡ty‰x‰|’‡y~rgv‰~~˜oq‡ivynfy‡„¤†€‡ŒŠ~o€w‚ƒ€œ‰„–“™ŠŒ…‰|ˆpz}„{h~lj€{zj{w‚ˆr`w~rdrgvƒnu|†–’‚}‚owz|umYp€wuƒ‡xˆvƒ‰{yto‹‚‘‚†s€~”‰Š|onimtm[edqoPZzM[n[O[rodUKsxiWYZZaqua^]`gdiifNYgM@`c[`u`]ulWWSt`ZdorWj^bhjgmlhpw|’kh„Š}|o~~{€zwŠ‹ƒq|‡oqwƒ{‰Œƒi}{mwxvŠv|x‚†ƒ~}zm„Œˆ™£„ƒ{u‹xkl„‡x}z‚‘€€~‹ƒprqcf^Yf_pp_`gpfjnˆtato[adjv{€¿œ¦¤È¸q„‚r’{w…’‚s‹‡rroƒ{ƒst†tˆw“ˆyypcw‡z€“ir„vgwucj|‚‡€Ž~s€u‡{‚•’…{˜–ˆ‚‰{‰‰kxy~tgzhkytizw€ƒ}h`xˆ}kkth|iv‚Œ‘•{~q|v|tbVx~st‹…‚}„q‡Šxyqq…„Ž€z~v†ƒwjqhl‡qo\f`qlIduK]lTSYrnbQOtxaRXX]apƒt\a\ieedkdP[pICc`[co]]xgTWVv][enhVk^ajgennhpvz’miˆŒy}r{~y‚|v}ƒˆ†ƒpw„rmw‚‚~‰‹“p€{wxz€Œt‚x~‚„y€uo~Š‹›žˆ}…zw…{gt…‹y~{ˆ†„v€gpn_d\XeYmsa``plkhˆnatiY_dn€w©Ú©Ç†‡²qˆwoŒtz…y’‰tst}woqm…t“…xtk`z‚y‰fr„pgun[m}€“€x‘“~y|nŠxƒ“†w˜Œ“ˆ†…|…ltv~lgvdm{vmjww|abx†ziuuc~|hu‡–|uwq€{}n€ZWupv…ˆym‰†tzlv‚„…|~z}tŒ‚}thtenŠƒlsZh]sdGmmKZ`WVUwmbPRtvXPVX^`r„o]`cmed^ocT\qFBe^]eg][zbQV\t[Zgk`Vj_`offkqhpvxŽtjŽu~vx}w„{t}ƒˆ‡ƒor€tqu~…‚‰Šzvxƒ{|…‡w‡|}~„€{~ruyŒ Œ‰y‰vt‚x^}…—‹x†ƒs…†„w‰zbnm\b[[aVisc`[gnpf‡qaqfW]ck|Ê·¹¡jmmŠlqƒq{ƒ‰~z„yxsxut{jlvc„u‘‚vof_}‚zŒŠer‚kjqcXlz…›ˆ‚r–”w}oŠs…ŽŠt™’‰†‹ƒ{y}ppo|fhqamxqjlqx}}z]ez€xjvxfƒwhtˆŒŽ•}rˆjo~yo}]Ysnt‹|‚ooŠ€qwix‚‚x~s|u‡}{sgsan‹€kqWi\v[GmjLVU]SU{kaOTurPQTW^cu†i]`ljfcZoaXboGAg\`e]\V{]NUepY[jh]Wg`^rejhrgpsw†xn•‹tzx~yƒˆur†…Ž‚pp{xwvy†…‡Œ†y{t‹}}†„ƒ‡~~~}‡|xuxx‘“ŸŒ|Šmuxdƒ†•…s‘Šo……zƒtdnjY_[\]Tgse`Xcqrg€rbkeW[`jx¾®{Ÿ·nas…hszqx„z}‹~wwrvo{vejoa‡uŽ€sjb^~xy‹„fqhkkZVowˆ¢€„q™“rzv„oƒ„”Šu—ŠŽ‰…‰…}xtqnhx_jl`mvjgjkywzvZg}|yfs~m…ueu††—€pŒgk{„unub]q}lu}Œ{‚gu‡~nqiv€y€t~m{|‚{xqflam‰}llUi_vUJijNQNgLX{haNUukLQTU_gv„g^aqhgbWj]\kgJDjYbcVYUyYMVmjY]kd\Ydb^temdqgrpu€wp™†v~w|…‡}us‚ˆ€•‚nsy{zsr„‡‰ˆƒx}u~|„Šƒ„{~‹ƒ{v{wwš˜z‰‚†iv|{lƒƒ’rŽp…‚‚pglgX][\[Sdpd^WbrujuoeecW\[hpor€s‰ddy}isusrƒw€ƒxvrumjzqagkg†sƒmf]_}p{‰imxgjdUWroŒ¦|„{v–‘t}t~|o~}“ˆx›}‰‡ƒ‡ƒ}upqlgt\lg^ltdgeizo{rYgwuhpx‚wbw†‹|•‚oŒjm{‚qgtfanzhsxŠ{~bv„wjlru|r{{th€€ywodfbm…{ljUhaoRJhjOKNoG]zfaMUtdJOSWakwf]gtif`VdWbp\KKjWcaUTUsVLXudY^k`[Zcd_vgmbpitor~tt™‚w~€x€†„z}u‚„—…nrt|zuq„…€z‹us|•€…„}}Œ†z}€w{£¥Šyˆ…„kt{zu‚€‹zn„sy„}‚ƒvojieV][ZZSbnd[Xas{jhmi`bX_Ziiko€gl`hyxjrssmƒ€z|utmzhjyj_enhv„geXbwj‡{ojpgf]TXog§v€z|Žzvq€qux{’‚z—v†„€†ˆvjruggn[lc]mr_gajxh{l[nƒrtjp~zxaw†…y…t‰rpzrcri]qxertˆ|yct€qgjyusmyyvye…|ywqddcm{|jjTgaeSIkfOGQjE`wfaMSr]JMUYelx|f_nqje]VaUnnVJSgWe]XMUkTJ[y_[_k]]Zbe_yhlaoovnpwuz˜~vy€€‡†zyzƒ~“ƒqtt~zvt„ˆ‘}€|kr•€{‚Ÿ…~‡}€~†‚€Š{w„«žz‡‡ƒkryu€~€tn†n|€sŠ€jpnddX_ZYZTbjg[Z_u‚i^ml\aW\\kert}ii\kvugsvql„{}|xuqlygixf]dshzw’ccTeph‚…xxgijaWVYgcŽ§o~w€‹Ž{qri{q|Ž}xs…~€€†ndurdgg\ja]oo[g^mtezh]t€orkq|~uvbt†Œ{‰ˆysu€vbqn[rtcqs…|ues€mam{pkj|zvtg‡v{{vqebdmr}ikSg]\TKqbPFU`GbvfaKSoXJMXXhkv{eenqgdZW^XweTJ\bWgWYHWdPHbxZ]_lZ^\bc]~ij`otxmpnvƒ—zr€€|‰Œ†}uu†x‡Œ|suuyzzŒŽ|~„‰is–zŠ~~…zz|†‰sq­Œ{{†}dq‡ys|zurn†l{~lzcpobe]eVYYWcfk_]\s…hXqn[^XZ\l{bpwulaYlssgtuolƒx~xvmnsdhte[gufvv‘z_]Rfgkƒ‚t~bdj\TW]bcŽ¤ixsƒ†‘ynq|jzo~ˆ}vŠt‚y}y€idvl`f_^i_]tkYe\oobze\w|knnpxytues„“€ˆƒ‰{wpstcxe\qqbqr‚|tgr€e_nwjehz}uopƒvt}srb_fmn|dhSgWXSMv^PIYWHbtcaITmSJMZWjlr|cmmscbZZ[aw\SKc]WhSVFX`MGiuX^`l[[_ab\„ihanxymojvym‚~€“ˆ„vt‰tŒ†tqvvx}}~Œ~“~pw•ƒ|˜’y€€xz~€tˆ„tq™¡zz‰”wcu‡xswtkto~kx|p‘s^pn`gblTZZWhcmf\\q‰eSrn[ZXW`lvciuji^Ymspksssi„|~~zvnmkdiqc[jrdtvŽs[WSear€r‚]bc]SZ`\c‘Ÿeqq…„’ull{opr|}}s‚xt{zzdeug]bY`g[^vhWb]phawa[|vijroxtsuiq‚–„‡…wtkq~ogxX]lncrs€zsgp~\`prb`ksmnvsqxkpa\ellz`fReSVQOuZQOXQHcsa`GVjPIPZVkkk}fnorb[ZXYlqWRPfVVhSTEY[NHqtX_clbX``a]‹jcdmzxlpiuy‡{kƒ}„š|ƒ„y|‡m‡rnvz|t‚‚|‹‚‚—tx“…ž‰u€t‚qˆƒvp¡–sz†‹†zewŠnmznfxpzksvsk^unagekR][UgalkZ\qŒdOon]VXUgishbted\Xmtloutxj†|{‡vrcdkna\nmcsx‡kZTVcdx}}q†]d_cTZ_Yb••cmpƒ…Štki|pguyu}m{uvp{u_frc[]VacXateU_`mdaq]]~phitqtquwkm…”‚‰}‡rsgprtpT\gkfrt€vscmvVcrl[_pg~fnx~stsjmaZdijw^eScTUPSlVPVRPGdr_aFXiNIXTWnie}ilxlbW]U[tdSRWhQXfTSGYYOMwvZ_ekiYa`^]Žnbfkyunoivv€lƒ€}‡˜{€‡‰~k“ˆrft€{u€ƒ}‰Ž‹“r|Š‘…‡Ÿ†{†Œs†s~‚vn¤‹r€‹vwlzŒ`d{pfysxlmqwƒgd|mcfghS_^Ug_ln[^nhNim`TVSogskexdd\Xoslqzwrl‡{v›zykaelm^`ojepx~gZVX`lx|{p„_c_gVX_Wc›ˆbkp‡}xllzn]xsm|kvtop|sXjn^X\UabWdpcS^biablZa~lfltvomwwli†€Š{‰nrfr~ntnd[aiiptts^imSeqeVcod|dsx}wlpmk`Yafgt\dU`URNWdQO[NOHdo\bGYiMJ_KYmd`yin~e`U_T]u\SR`fN\`URI[XPYtu]_ekhXb`[^qcgjxqsnhvt{„r‚ƒzˆŽ~|‰‡yn‰tkstˆ…‡‘„•y}ŒŽ‡‘›„€|Œ…sstxro““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~}~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~}~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’’’’’’’’’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’’“““’““’’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ‘mfggggg}…„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffc€¾»»»»½³mfgggggmnnnnnojfggggfo„ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‘g_```_^yƒ‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____[~ÈÄÄÄÄÆ»g^_____eggggghc_____^j‚€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}z{z|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‘ŽŒ‡‡‡‡‡‡‰““’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰Œ’‘‘‘‘‘‰ˆ‰‰‰‰‰‰ŠŠŠŠŠŠ‰ˆˆˆˆˆˆ‰ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|yzz{|{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘’’’’’‘’‘‰‡ŽŠ’“ŽˆŽŽ‘ˆ‘‘‘‘ŽŽŽŽŽŽŽŽŒ‹‹‹‹‹‹‹ŽŽŽŽŒŒŒŒŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…‘Š†‡†‰…ˆŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰‘Š„‰†………‡ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰Œ‰…„‡„†ˆŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}|}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹Œ‹…ˆ††ˆƒŠŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz||||}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒ‰Œ‹Ž‰ŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzzz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{y{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}~}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†……………„„„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰ŽŠ‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{}~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““””””“””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••””•“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””’’“““““’’“”““““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}~~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘’’““’““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’‘‘‘‘’’“’“’‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}}~~~}~~€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡ƒ‹Šˆ‰‰†……„„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxy}zxwy||||~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzop{xy{|{xw{xuwttvutvwuqrqnprpghklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkigfggghhgmgjghehgccbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__`c_\_]`]^Z^]YY^ba^^ZY_\XWSNMLKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{xvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSSPMJMNPROMPQQQQRVVQQQTPPNNOLJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTttuxzzxvvwwzz|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMOPPRQPNNONONOOPQONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKLFDFJKKKHJLLLOMLLNOOOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMLORNYpprwxwwtstwz|~}~~~~~~~~~€€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEBA@@CCDEACEHKOKIIJHGJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:<>><ED=?EA?@A@DEGGGGBDDEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??;898;;:@;;><;;<<HL==AA?BC=ADDFBFFDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnpprttsqrvyy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;::;89:87:<978;;>=;;:8:@@AB?A?CFDBCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqususqsxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;;?@AB@=<9<=<979::988::78:9:;;8789;:8<;=@A@=;;><==@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyy{}~~~~}~~€€€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>=;<<>?=<=;:<===<<<<;;:;<>=>??A@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquuuusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?CCC@><=?@??=;>=>CE??@=;===<;:=>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVpoqssttuyz{{}~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???CED?=;<@>:;::97:<9==@=:<;;<;89;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pprrrtuvz{}}}~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC??AAABA@=<=;>=:::<:8988:;=??<;;<;::;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvuw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC@???@=?@><>@?===?==>CD?;<=>@==>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hloppqtuvy||}||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCDA?@@@?=@><=??@@@C@@?@@>=<=@EABBFHC=<@DCAA?>=@A>>>?<>@DGE@>@A?@CFECBCC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz|{||}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@A@>;><?=<:>=?BBE@??Na_J@CEIIIIMMKECFGHEGEEEDDCA?@>>BFJJGEEFFFJNNKJIGGHKLJGGCDDDEDABBC@CDEDDEDEFCBADeopqqtvux{|{{|~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@DED?;ACDB?>A?ADEDCWu†‰Š~XGHJLLMOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHIHGFEFFFDFHGEEHHFHGHFQnnpqrvvy{{{z}}~}}}}}~~}~~€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFJHIGHHIGFBDFDDCAUt‡‰‡‡†ˆ‚WILMLMNLJGGGGDGGGGFHFHECDDFEDDHHCCCGJJKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrswwz{{z{}}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKLKJKMJKHHFFGFEPl„‡†††‡‡ˆ‡|PKLKHGFFDECC@ACCCCFFEB@>>@AA@BD???DFHDEGIKIIGHIGIIJJIHFJJJJIJIJJJFILLJJKKfopsstvxy{{{||}~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKKKKKMLKMLIFJVl†…„„†††‡ˆ†ŠuIIFB??@???<<<>::<AA@><998<<=;>;9;?ABAACCC@ABEDBCFHIHHHLMLGIJMMNMJJKKJLMSloqtsswyz{{|}}~~}}}}}~~~~€~€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHGIIKLONNQNQ^r…ƒ„……†‡ˆˆˆ‰‰ŒŽfBB=88::9878896479;<:8567789787689;;<>A;999==>;;=ADEHJMLLGIHORQPPNLMMOQ]oprtsuxz{{||~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@BFHKHLKNTg{„„ƒ‚ƒ„†‰Š‹‹‹Š‰Š‹Œ‰T;8656766645763468:876565677778:7778:;7689989876:<@GFIFIFEFOSRSSROPPRTepqsttwy{|{|}~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:<DBDFFDVx„„‚‚ƒ‚…‰ŠŠ‰‰ŠŠŠŠ‹‰‰ŠH676468874578467799766765::;::<89899877:::8878589;A=>>BA?AKLOQPQOOOQWkrrttuwz{{{}}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897:A9<D?P}„ƒƒ„„„†‰ŠŠˆ‡ˆˆˆŠŠŒŠ‰‰Œz>:88;<=>9:;<89;9:;:99;:9===?;;;=:><:<;<;<<::<8::;:999<?<=ABDIJMKJKLWorsutvx{{{|{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?:;<:89989999:>=??Cv„ƒ„„…†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>BCEEBAAB>@CA@?=>>@?>?@?@==?B?AA?A?=@A@??A<><;:;:9;?=;;==AACABCAXpqtttvy{{|}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:8:;9::;<:::<;=>@?=a…ƒ„ƒ…„†‰‰ˆ‡†††‡ˆ‰Š‹‹ŠŠŠ‹Š‹^>DGIKJJFGGDFHGEC@@CECB@BCB?@DHECEDEEAFEFDFFD@B>=@>=?@>???>?>>:;=<`qrttuwzzz}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD97:=:<:==>>;><?>B?J~ƒ„…†††ˆ‰ˆˆ‡†††‡‰ŠŠ‹ŒŒŒ‹ŠŠ‡WGLLMKNIIKHIJJIECDFGFDCEFDBHIKGHGFGGEKJLIKKJCFCCDBAACBDCCDDCA=<>@hpsttvwzx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€€OA>=?DLK@BBA97;>;<:=?>?<?>BAD>h„‚……‡‡ˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹‹ŠŒPMPMKNKJLIIJHKFDGHHIEEHFFELLMIJGGHIJNMOMLNKHFGGEECFFFFDEHHFCA?@Lmptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?FGG=<@@87<:;<:=?<==?@CBHS~ƒ„„…††‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒ‹ŠqMQOMLLLLJIHFJIDJHGKJHJGGGKLNLLHHIJMPNONLOKIGIJHIDIHHFFGGIFCBACUopuwxz{xxzz||}~~~~}~}~~~~~€€€€€€€€€€€€€TDAABGHB?8?@8:;7<=:<?<<=?BCCLm„ƒ„„……†‡ˆˆˆˆˆ‡†ˆˆˆˆˆ‰ŒŒ‹ŒŒŒ‹‹‹‹^RRPMNMKJGFCHJGLJGKOLKJJLMLOPNHIKLOQQPQOOJIJJLJLFGHGFGIFEEB@BB\prwxyzyyyzz{{~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<8?==>@ED=BDCFJu†ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹‹ŒŒŒŒ‹‹|WVRRTROLKJEFFKONOWVQPOQSRMSTOMSLPSUWRSRPLJMMMKNGGJFFHJDDEEBDCcquyyzzz{z{zz|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?=<A?AADTKBHIFIKx†ƒ……„…‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŽ‹‹‹gVVkaERQQPJ;;QSR`u]UVTVYYRXXRZfPUWZ]RTWQPNRPPPQKKKGHJHEFIIIHIjsvyyzyz{{|z{|}|}€~}}}}}}~€€€€€€€€€~~THJIIGGFE??A@EACFDCDKVPJOONPPy†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ}aŠ‹‹‡l[dU:XXXSP?@VUY\d`VYbr^]V]ZVEQYZ\Y_TYgRUVXTTVSOOMKLJIILMKOMSotvxyxwyzz{z{|}|~~}~}}}~}~€€€€€€€€€€~~~~VJJIHGFDDBA?HLIMPKIJOSQPTVUVTu…„…………†‡ˆ‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~Œ‰Š‹znpXZ[ZRSRWVTZZuƒYU}a\X]^WIV^^[[_YHYXY\]XXYWRQMPQMMOSQQURassvwwvxyxz{{|}}}~}~}}}~~€€€€€€€€€€€xy}YNKJIIFBD@A:OQQWXPPPQRSRVWWWWl‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡ƒŠ~fYY\YSVTWRQWVc–€QerXZW_hP`fZZX\hbGOZig\[\]]WSNSPPQVVVVYZosuwvvtwxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZZRSQOQRQURUSV^ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PVXTRTRQQLOMKfyZ]TYUV]ZLTZUST^ZXWWWzkXZ\\^SPPPINOWVX[Zdqtvvttvxyy{{||}}~}}}~}}~€€€€~~zxwvsu{€€tk~~kry^[VUSROKFCDAM^ƒlVRSOOQOQVQSRRTcdv€ƒ‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ymqVIKNNKMKHJDFHEC>ScURQQNKRURMOYQMNQSUUMQSRPNLKGCIGRSTZ]mrvvuttw{zz{{}{}}}~}}}~}~€}}~~€~{vsw}~~du}iqt`d]^[YUQLILIal’tPQSMQRPS[RSRQRUUbs{|~€‚}{{€ƒ‚…†‡‚†††„†…†u_]KC>BBCCA?DPCC@C>BHGV@HNMG]iQHFOFDEFHGHBCHGHJGCBAC@NPMRdtuvustvy|z{{{||}|{~}}}~~€€€||}€€€}vt{mh|gnqfheeb\XSQPURsWe[OONLQRPUYSUQQTROV`klsvz{xytrnstsyx~~ƒ€ƒƒ‚€‚€‚kLG>>::>@?>>>jPKaEFHIEB?HLMGMQUJBE?><=<==?=?ACB?><=B>IMFUouuvstvxz|z}{|}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QQZ\Y^IJOPNKLQRQTUUWQQWVPX[b]agmmlnjh`nrimlqu{z}{xz||xwxdB@@A<:BCAACA[\O{NOONKLMOOPLKLWNHGAA<977599=;;;8989?;AG>\tuuvuvwy|||}||||~}|}}}}~}xuwz{zwyxuw{|yxuywcqhipmnmmhf^OO^\ZIGOQQOMPQNQRSVXSRYTNYZ[WY\_^_e_]^qwk^`gkwooljomnlfbYGFFHBAFHEEFCLQOaWRXQPSSRU[OOQWPMIDF>996587979:365795<B=ftuwxwzy{}}||{|}}~~{}~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZWMKSTSPQUOLRSTWXSTXQLXYYVXXVXY]WXXhsk]V`tkaa_]d`_^YUPMOMLIGJKIHFCPOSZWTTNQSYS\eUOSTQNKIHC?A9988978847578599Gnruyyz{{}}}}|{}|}~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPWVVSTVOOUVWXYSUTLKSUUUUWPTUWTUR]n^RNY`[VY;DUWT[fJLPRROMMNMMLJFPPUYSTOJNOUST\VRUSSOMLIHHF?>=:787659967565Wqqtxzz{|}}}~||}|~}}y}}|~~~}||}}~}|rvqxxruuqqnppopuvtnjddjppqrpnfedc\^RTZVWTSVTRXWYYYRUOIGOPOOMRJOPOONNOTLMIPPSTU2<XMIAQ=c`QSQPNPPONNMPNTRPRLILKORPQRSTQSOLMKLLHCBA=:9876;B4566;eprvxy{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqpuuvcjgeWhtrrqniihpVVTUXUVURWVUZYXWVQSFFAFGGHFJDHJHGEHLHKIGLMPMG/E_R=3@>joaRRQ@GTQOPPQNQOPOLJLLOPNMPQQNPOJLMMKGEECB;==<9=G6676Dnquwz{{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknbePSTRSUOWVUYYVQQQO@>;=?@BAC@BEDA@GHGHFFHJMLDGCORB8DMS]gSQSAGUPOQQPMMNLJLKLNOOQLNNMIMLIKKLKGFFED<AA>;@E;<89Trsuy{{{|||{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLONMQSLTUTWWULLKH=987;?A>==A@B=>EHFDFFIGJJ@FAA@EGDIOHQRa\QPROSNOOLLOMKMLMON[VKMQOHJHCIJLLKFFFE?BC>=BG?B?@druw{z{{|{zzw|wy~~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSNKHCE=9879?B?;>A@@>ADIECHGIGIEBB?><BA@GJEMObePMOMWKLNKKMMLLKNNSdMJLRIIIEBIJLMNJGIFBBB@?EFEHDLopvzyy{{z|zwsxtx||yznqrmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGLLIMPMPOGKE?B=999:?B?<ABAADDGKFDIIGGHCC?B>??@=CEDLMQTLJIMTFIIJLIJKIILMOPQPKGCKGCCKJLNONIJIGCCCDIJMLIZsnxyxzz{y|vrpurtyyvxjqnjllnttmsu{stxronqovsnporpopstyjN`gsjt|ygosqiqheqHJCFGHGJKIJLDGB<>=:::;AB?=BBCCHEJLJEIIFGHCC;A@B>@?BDDIMOGHJGHKDHIKMHJLHIJLJM]RHIDNGBELKNNQNKMJKFGGJMNRNMcnjwvw{y{z}qmlskptttuhpmjikktpnttyprytorqowsoqptrprutykNVmulq{vinoijthepFJCFEFDEEFEGCC@=<=:;:;AD@?BCEEIFJJLFIIGFFDB:ACC>?CCCDGKMHJNHDHEILNMHILGFFIILNKIHEOICGNMPNPNNOMKIHIOSQRNSggfrosxv{z|lhjoekpmsqfmlhikltmputwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhmf_pGJCEEDBBAE@DB>?>;;;=;=?DB?ACFGJFJILHGGGFEC?=DEB>ACBCEGHIGMPIFEFKNOKFHIFECDIIHKIGHPKDJMMQNONOPNJJIMRUURPXeaamfproryzgehhcilfqlflmgiklsmpvutpnvrosrsutqssutsuvvvyvutvlkuumrvqlnlerMGEDFBA@AD<BA>A=::=?;>?AB?@BEGJFJGIGFFFDCBAAEFCBBBDEEGGHFLPLHNIJLKIFHEFECCHHHKJGKRMCOONQOOONOOKKKPUWVVTY`_]i`minhrsbeffdhhfnifmmhkkmriqvusqmvnoqrswsrstuvvvvwvwvvtwuksunutsprkksMGGEGAA@CD<AA@C<8:=>:?=@B@@@DFHEHFFHFEEDCEBDIFCGEAEGEFFGEIMKHQLJKHHIEFHHECIIJKMKPSNDRSQQRNOMOPMLNSWVWYVX^Z]d`hcjigk_defchggkggkmkmlpqgttursnvoqprtxqssuvu‚‘yvvtxuuwxnouorsuqqipzMGGGHAABEE<@CBD<7:=>;>;AB>??CEFDFDDGECECDFFFJEEIGBGHFGFECFJJGMJLKHJKFIHJHEKKLLNORTOHTUTQTPQMNQNMQWZVZYWZ^ZXa```^hec`deggjhhjghnllomqpiuuxrrpupppruvpusuvu{~}xvtwvvvwplupmsunossyMHHGHCACGE<@EBD<8:>>><<BB=@>ABFCECCGCCDDFGGGIFGKHCIHGIGFDHKIFKHMKJKKHKJMKINLNNORUVOLVVTQTRRLOQPOTYZY\ZZ\__]_c^\bdlc`dghr…hgjfjnnponsqjtuxrsstrnpqvrquruus~yŽ}uuvvvvxriuqkrtlqwquKIJHJEBDGE=AGDD@9<>@?>?CB<@>AAFCEDCHDEDFFGHFHGIKJEJHHJHFFLHHHJGLKLLLIMJMNMOLPPQUVWOKVVUSSRQLORRQV[[]^[]^``a`bf]d`fg`ehjdssfjhglprqossnswwpuvtsmoruorspurvrtvuuuwvuwtgtrkqrkrwpwIJKIKGBEDE<AFDDB;??A@@@DA@B>ACHBEDFGEHEFEIHFIHJLHHJJIKJFJKHIJJGKJLLIILKMNNOLOPRUWVMNTVUSRQPMNTSRW[^^_]^``aab`cdeadibdijgv‹lkigmosqpqpprywruutsmmssmqrotuuspswtuuwvuuteqskpqjrvpwJLLKLGCCAE<?EEDC=AACBBCEACDAAEGCGGHFEIFCGJGGJFILHIJMKMLGKIHKKNQKRPLSMJMMNPPPTOWXX[NSQW\ZSVPNTUTTXZ_bb_da^ac^`fcabgnhbihhmxvmhinosrpqrrrvtsusssnksqmprotvsqquvuswywutucmtkopjqtpwLMLLLGDA@D>=DEFC?CAEDDFCBEGCBHFBHJIGHJFDKJGHJHIKGJJNKNLILHJMKZfJd[KlRGNM_nUls[qpbwcRPbvuhucavaXnqbdvinzf\lu`lkV`wuhjghfglmjmojmosrprrqrsrssrtrnltonpqquurqstvvuuywutt`ktkppkqsqyKNJKJFB?@B?<DDFDCCBEEDFBEFGDDJEEJLKIKLGGNJHJKGKJIJJNLMMLLIMLL[sbdp^llULNer]geqlntgpi_aYnmbppbkijgoqtetnn\pvgpNLryvkaakeelxmkvlnosrprqpqrqrrrtrmmsnnoprutqsstuuutwxvutbmukpplrrqzKLIIGED?AA?=BEFBECEDEEDCHHGDDKHGKMMJLLFJNHJKJILJJIJMMNMMMKNMM[rponppkjLOPmXNibtrpamov\YlP[mmZqmkomxxtsip]`slqjUuyxoc^kfbgppjioppsspqpqqrrqqrrtlmrmmnorutqtrtuutuuzvutenukpolsrryJKGGEEEBAB=??EGBGDHEEDBFIHHEGKJGMLNJLMGLNIMKHJMIJIJJNONNMLNML\hdu]lqVkMOQnUZk^klvaldtTecNlYl\tpkilxjwuhp]_skhWbcw|oc`ghacityknnqsspqpqprqppprukmqmmmoqstqsrtvvswvzvuthoulsomsrtvIMGIEEDCAB<B@BFCGFKGECCHKHHFILKFMKKRRLHMMINJIHNGJJHINOMNLJMMJZtppoqqlkOQRnYskgooqqomt^nXat_nopoqroousttjZ^tcwxrjnzhaacfabjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyytukoumtonssvtIKHJCDDE@@>CCAFCHIMHFCFJLIGFJMLFOJJWRKGKJJNIIJLIKJIIKLMMLIKKKSkbYi^_jcrrZ_Yjo_eeUk_c[aaQ`mh\j\niid[oedp]Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunwqrutwrHHFJDECFA@AEDCFBHJLGFCFKLIEFJOLIOJL[QJFHHKMIHJJKKIHIGKKKKGHKJLKLJIKLNT[]TPUMQONOOVQOPQNOQJJNPQdqiTYV[[\UYZ]X]\\cfaafbcf_^fkmhmtxrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyyxuvqruovrtsuusGCEGFF@EC>CGDEGCIKLGFDGJLHDGIPKLOKLWMIFEHIJHIKHLJIFHHJHHHEFLIHJNKHO\W^O\\`^OXYS\\b^MXZMXaRKYaZS`d\aX[ddVVX\YZX\VY\^c_d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtOBCDLLACDADIEGGFKJKGEEJJJFDGHPJLMJMRIHEAHFJIKKILJIGEJHEFGEEJGBILIJT_Y`X`a[`UXYT]^Z_RY\P^\YN_\^S[^d^Z]`c_Y_b[`^[UYXZ_^ccbaceiekrpoppnow††……†‚{€……††…†…uqprrsuyzzyyxxxwryvxrqxvtvaSJJMHDCBCFGEGGIJJIHDFKKKEEHINJNLHLNGHF>GGLIKKJKKIGEIFCDEBFJD?IJHNZbY^^a_RTSW__\]Y^QY\MV_WKQY[Q[_ba]^ca`bbbcceZRYVW]Z^d`__cebhommllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxXQJFDGEBEGHFGHIFGJGHFHKIKDCKJMMLLHJJHJG?GFNJKKMKKKIGIEE@DAHIA>HIFO]`Z[d]_TQRX]\\\_[KW\LR\YIM^QQ]_bccccb\dcbdceXRWUT]Y[a_^_aa_dlkmjklnv~uz|„………………††…†…†††‚zrsuu{…‡‡‡†…„~xpzwvx\RMC@IFCEKIFGGIGGJFFFILJNECKJLNJLIKJIIGBHHQMKKOMKKIHHFE?EBHHA@FECS]Y^X_Y_[]UXXO\\QKJV^X^[]VZaRR__bb``bb_cbbddbXPRRS\T\]]^^___dhgljnnp{{|~{€‚ƒ„………………„„…ƒ„„‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKBAGGDFMRHDRKFHHHDFKIMPEGIJKNLLILKJIGDHKQOMLPMLKKIJDEAECHFAAFCAUUE\T^SV_XNTUMYZLJKT`a[_X_^b]OYb\``_bca]baW`_TQPQRYS^\[]]^`bffelfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDFFHDIScQEW_IGGHDFMJPPFIHJKNLLKMKJJGEJNQQNNPMNMNILBDACCFCB@CD@LHCLLPONLFMFFHIGFLKMOPILOPPSPLQSRUZXWYWWcVNRTPQPOQUT\YY[]\aaefchdlmqsszy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKN^MHHYMGHJHGMLQQIKJKKNMUNOKKLGGKPSSNPPNOOOHLF`ED^LDfbCLZH^\smOMVmXKCO_TkVgI]WU^DLQULMSVQRTXVTXTT\TOeZhheZUkTXWU[\[``abbb`gignlhrz|}~„„„„ƒƒƒ}}zr{z{‚€ƒ„„……„…ƒƒ~z{LIEFFHEEKPTJKG`THJOJIOMRQKMKLORUROPJLNGHMQ[YOPPNPQPJKQQI|YYrsWPmGqnoaVPqqtOBjsnqspSo_[nX]V\XUkhU]VcY`YZ^UUWituu_av_Xb\\f[_aaab^`cgmol`pwtx‚ƒ„‚}~€vxzmv~tx}€|~€‚„|€ƒz~wwMIEHMMBDLLGJLFRVLKOHLRXWQNOOMQTNOQPKLOGMPS[ZTQROPPPKIZx]TxdhXRSPvftlpbnfkRrNLwmjrpsrqrpoo€]ezuxqqzq~r}ku}aRh|essoss|}o~xor```bb[aahlnkblfgmw~€ƒ~{xw€tvzhr~nt|~wx{~€ƒx|u|||ssMKF`]GAEMMHKKHJPOMNJNV^YULQSNYYLSRRNLPIQRTYWWQTPPPRKHgxlcxqmZJKTypumubnvPddHevqmwo€jfxxiWrQhzmijzz}lxzphnXuujvup€ash}ilx|o___cb\_degjjegbcdllppstsssyqrxbltgry{ssuy~svzn|}yxrnMIRtNCBEPQHKLJLQOOOMPZ`ZXKTWPa^RVQYSMPJSTUXWWPUPONSJKrouuquqch`VnKqp^GhyWvTKhx}w`y{sna]modSgrunmypwlvstqlm\s~zkmy|lun|lqvux^__b_]_eeighfe^bbiiijknokqnmjpacfdowxompsynqpj{ztromKKZVHGEGRQKMNLLQQPPPQW\YUNVYUfXRRY^TMNJTTVWYWOSOONRIRmHiwK`dvvTVlNnl{rajguTKWkg|lmlx_Zpz{_`zscroxqhd|ir{]TKk_vuljv|{m~yk|p]^^b[_bdegfeec[ccikkrsrwgmihdg`alagsrlglmr|kmhk{tmmkmOGJKHJHHRQMOPLLSSROSRXRWTPWZVVTTTa`QONKTSSQVVOOMNOQJHQMOULKKRSRQROVUQQORRXXPMOUTWXX[[UQRW[WXW[ORTWWXQ]XV\UTOXRWWXYZ`\gr_[[Z]]_cZ_ccegdddcZdbgffmnmuffgc`f^]g`dlhfgkhpzhggkujhgilPIKKLMKJTRNRQPLVUTPTUXUZVR[]VUTWUYXOOLNWTPNUSNPNLQPKIQQKQMJJOQTQPQSRJHMOPQRPPPTURXW\WSRPQUUUSZQNRQWUSYVTXTSQTSUUYYX^Z_a]\ZZ\\`c\^bbdgeeebY`acabhhjncad^_c]Zc\bma^ffgmsdihkkedcfhQJKKNOLMTQOTQRMXWUTVXWWZVS\`VWVYUXTQPKOXSPNUPNQNLSPMNUSNQNMNQSOTPRTTNKMORTTQQQUWUYZ[YRURTXWVY\SOSTWUTYUVXTRQWUVX\Z\`]WY_]^]\]`a^[bcchgfebX``b]`hegea^_]]^ZZ_Z_g`^^]chkahfhfd`bdbPKMLPQLOTPPTQOQZYXWYZZXYV]jdVXYZWVSTOKOVTPOTPPQNMRQOQXTQQOMORTMWQSTUONNQTVURRRTXVZ]\ZVVQRWXU[[VPSUUUVXSWWTRQXVV[_[_`_V_]^`]\`___ZbceiheebYb`b^^fdc`b]\\\\YZ[X[a[^]]_b__bddbd__`\PMNNRQMRSPSUQOV\ZZW[[\YZ[dqmhd_[YVVXRMMWSMMROQROMPSRUZUTPPLPWUPVRSRXMOPRUXUTTSTYX[^]\[VROUVU[ZVQSVTVXTSXZSRQYWW]_[```Vb\`a]`b_\`]cachief`Zc`a__ee_`c[Z\[\ZZYYW\Z\[`^`[^^a`_c\Y`ZQNONVQPUSPUTSPW\\\Y^\_W\^jpwy€c\[VVYRNPWSNQQPRTRLRTSY[WUORNSXUSQTQQYOQSSV[VVVSVZX]^\\^VSNTVV[[UQTTUWXRSY\TRR\XZ]^]ba`Wb[cb^ac_\bab_dgieg]\d`a`acd_b_YZ_[\[XXYWWZZZa]][]\\Z]`W[[ZPOOOYPUUSRXRTP[]^]\`\`U\\hjr}slh\UYWQOR[SRQTRTUTKQVUZZZSOSQUUTRNUQRZRTUTX]WXXSX\X^]YZ]UUNVVW^ZWQTTWXXSVY\TRV]Y]]a^cc_Y`[eb_dd^^cca^efief^^daaabcd_b^X[_[\[XXXXW[Z[`][[\[XZ[^V^Y]POORZPZUVWVTTT^^`_^b\`U]^bkyum}lZUZVQQT\TTTUTVYWLRZV\Z\RPUSWUUROWQSWSWUV[^X[YUZ^X_^Y\YRWRYXY_YYRTUYYYUWY\UTZ]]^ab`ed]^]]eabfd^_dc`\gehfdb`ea_aabb_`^WY^Z\\ZYYWV]Z]^[Z[\[WY\]VXW]SOPWYQ\UVYWWUX_`aa`c]`U]^beev‚{hXYZTVTV\XWWVVW]XOU\Y^]]TSXRVUSQRWQSVTXXX^^X][U]_X__X\VQXTYZZaX[TVX[YZWXYZWV]^`_dcbee^b\`fbdfd_`dba[fchfdfaf__abaa`_^VU]Y[\[Y\YY][[[XXY[YZZ]_]TY]UNTZVT\UWWYWV\`abcac__V[`da_zuohZ\ZVXVX[ZY[YXY`VOT][`a\UUYPTVTRUUQSUW[[\__Z_\V__Y]^Y]VRXWYY\bY]UVZ\Z[ZZYZXY__``dcdeecdZbfcgfe^ab`c]bciedh_g^bbcaa`^_XTZZZ[[X\XX\[Z[WWZXW\[\`]V]]SOVZVVZVYVXWX]_badada^YYadb`kfh^\][WWYZ\\\_[Y[bVSW^]ac\SVYPVUUUUUSUTX]]_``]a]Wa^[^\[^XUXW[Z__[^WX\\\]][Z\WZ_a^`dddffgcYcfehgd^c`_ec]fidei_g^cbcaa`__[XY[YZYXZXW[[Z[WXZTZ]\[`\U^bMRWYVWZY[\YWY^`baeada]^Yacb_a`a_]]]XW[[]]__\Z]cXYX]`cd_RXYPWUWXWVVWV]]^aba_b^Ya]]^Y\]YXUV[[`^\_YY^]^^`\ZZY[_b_bedefghcZefgigc_c^afeZiicficf_bbca``_]]ZW[YYXXZYWZ[ZYWXVU[]]]``baxKWW\YW]\\]ZW\]_`bdbca]`Xbcb`cac^\]\XW[\_]`_][`d\\XZbecaR\YOXVY[YYWYZ`^abc`ac_\b]_][^]YYTX]\__^_[Z^^`bb[[W[]`bbcedgffge]eghifcab[cg`\iichife`baca_`_]]\Y\YXWXYYW\[ZWVXPXZ]acffrkJYW][Z_]\^\X][^_bcbaa]b[bdb`cbb]\[ZWXjq`\`_]\ac_^YYcedbT_ZQYW\]\[Y[[c`ccc`bda`c^`\^^^ZXU[^\\aa_][`abfb^[S\_`cddfeggfff`fghhgdd`[eg^ahhcihfc`b`cb___]][Z[YXXXVZW\[ZVVULXX\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†‰‡…‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vuuuuuuuvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyyz{{zz{zzzzzzzzz{{{{zzzzzzzz{{|||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vutuuuutuvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyyzzz{{zzzzzzzzz{{z{zzzzzzzzz{{||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||xÅÔÒÒÒÒԓ{}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÓÏÄÅÅÅÅÅÇÒÔÔÔÓÓÓľ¾¾¾¾¾ÊÓÒÒÒÒÖº}~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}xÕçääääç™{~†“y1333332j‚€€€{­éääääåàÔÔÔÔÔÔÖãååååäåÒËÌÍÌÍÌÛæååååéÇ}~}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}v~€ywwwwwwxyzzzzzxooopppprrrrrrrwzyyzzz~ƒƒƒƒƒƒƒ‚‚ƒƒƒ‚ƒ„„„„„ƒƒ‚‚‚‚‚‚‚„„„„„„…‚|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚‚‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vtttttwuvwz{x{xwvy|zzzy}yyyxxxxyyyyzzyyyyzzzyxxyyyyyyyyyyyyyyyyyyyyyyyyyzzzzzzzz{||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwvz|y}}{}{xwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwvz~{}}}~|xxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z{xwwxy}}{}~|xxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚ƒ‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{xzzz||||{~{xxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyy{xzzy|xxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyxyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxxyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oyyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{|||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}|||||||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}|}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹Š‹‹‡‡‡„ƒ‚‚‚‚‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„„‚‚‚‚€€‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚€€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrstuttssrrsrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqstsssrqqppnnnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqqrssssqpqpoonnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrqrrssrrqppoopoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpppqrrqqqpopooppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqpqqqqqqpooppppppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqqqqqpppppppppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsquŒ‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqqqpqqqqpqpqpqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrqqqqqrqqqrrqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrssrrrrrstrrsrsssssssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz|~~|vvwwvuxzxxxxwwwvx|yy|zyy|{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~|{{z{|{}|{{{{{{zyxyxxz{zzzyyz||{zz|||zzz{}||~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}|||~|}~~~~~}}||}ƒ€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š…†ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€€€€‚€€~~~~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒ‰†‡‰Œ‹‹Š††ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~~€€€~~~~}~~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Šˆ‰ŠŽ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~~~~€~~~~~~~~~€€€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’“‹ŠŠ‹Š‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚‚‚€€€€€€€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒŽ‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒƒ‚„„‚ƒ‚‡ƒ‚‚€‚‚‚‚ƒ‚‚ƒ‚ƒ‚ƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒ‚ƒ€‚ƒ‚…………††‡†…††‡‡‡†††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠˆ‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚ƒƒ‚‚ƒƒƒ„„ƒ‚ƒ…ƒ‚‚„…‡‡‡‡††‡‡‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ‘‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„„ƒƒƒƒ„…„„……„ƒƒ„……‚„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆ‰‡†…†††‡ˆ‘’’ŽŽ‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€‚‚‚‚‚‚‚‚‚ƒ€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„…„„…„…†’“‘ŽŽŽŽ‰‰‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡ˆ‡…„‚~~€€€~~~€‚€‚‚‚€€€€~€‚€‚ƒƒ€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“’Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚„‚‚ƒ„‚ƒ„……„‚„‚€‚‚‚„ƒ‚ƒ‚‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘ŽŒ‡…ƒƒƒ‚‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒƒƒ…ƒ€ƒ‚ƒ……ƒƒƒ„ƒ„ƒƒ„„…„„„‚€‚ƒ‚‚„ƒƒ‚‚„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”““’ŒŒŠ…„„ƒƒ‚‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~€€‚€€‚‚‚‚‚‚€‚‚‚‚‚‚ƒƒ‚‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†”“’”’‹‡„„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††‡†††…†ƒƒƒƒ€‚‚‚‚€~€€€€€€ƒ€‚„ƒ‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“‘Š†ƒƒƒ„‚‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€€€ƒ‚‚ƒ‚‚‚ƒƒƒ„‚ƒƒƒ‚€€€‚‚‚ƒ‚‚ƒƒƒƒ‚ƒƒ„‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†ƒ„ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„…„‚‚‚ƒ‚‚„‚‚†…ƒ…ƒƒ„„„†…„„…‚}}}~‚„ƒƒƒƒƒ„ƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„„†………„…†…††…………………………††…†††…†††‡†…………ƒ„„„‡““’‘’ŒŠˆ…………‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒ„ƒƒƒ„…ƒ‚ƒ„……†…††…†‡‡†ƒ~~~~~ƒ„ƒƒ„„„„„„„„„„„„………„…„†……†…†††…†……‡……†…††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„ƒƒƒ…………‡‡……‡…~€„…„…†††…………††‡††…†……†‡‡‡ˆ‡‡‡†††‡‡‡†††‡†††…„ƒ„………„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘“’‘‹ˆˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒ‚„„„…„ƒ‚‚ƒƒ„ƒƒ‚ƒ…„…‡‡…„‚€€€……†‡ˆˆ‡‡‡‡ˆ‡ˆ‡ˆˆˆ††‡ˆˆ‰‰‰ˆ‡†‡‡‡ˆˆ†‡†‡‡††…„ƒ„…††………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†…†„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡‡…ƒƒ…„ƒƒƒ‚„„„„…„€‚€€~{z€†ˆˆŠŠ‰‰ˆˆ‰‰‰‰Š‹Šˆˆˆ‰‰‹‹ŠŠˆˆ‡ˆˆˆ‡‡ˆˆ‡ˆ†‡†„ƒƒ…‡‡‡†……„„„……„……†„„„………†…†…ƒ‰”“Ž‘ŽŠ†…†…ƒ‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒ‚ƒ„‰Š‡‡„„…„ƒƒ…ƒ…„ƒƒ‚‚‚‚‚‚€~|}}}~|{|ƒ‡‰‹‹ŠŠŠˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰‡†††‡…†ˆˆ‰ˆ‡†‡„ƒ‚„ˆˆ‡ˆ‡…‚‚ƒƒ‚ƒƒ„‚‚‚ƒ‚„ƒ„ƒŽ“’‹ˆ…„†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚‚ƒ…‰Š‰‡…‡…„……„ƒ…„ƒ‚‚‚‚‚ƒ~}~~~~~~}}~}}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡‡‰†ˆ†ˆ‡‡‰ˆ„ƒ„ƒ…„„……†ˆ‡†…ƒ‚‚ƒ…‡†‡††ƒ‚‚ƒ„‚ƒƒ„‚‚ƒƒƒƒ„‘’‘Ž‹‡„††ƒ‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…†ˆ‹Š†„†„‚††‚€ƒƒƒƒƒƒ‚‚}|}€~~~}|}}|z|„†‡†„ƒƒƒ„………ƒƒ…„„„„„„…„‚‚ƒ„„‚ƒƒ…†…„‚‚‚ƒƒ…ƒ„„…„„†ƒ„„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰†„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………‡‡‡‡†€…ƒƒ„…„‡ˆ…ƒ€€~}‚ƒƒƒƒ‚‚€}}€€}~~}}}}zzz~ƒ„„‚€‚‚~‚ƒ€‚‚‚‚ƒƒ€€€ƒ‚€€€€‚‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†Œ“‘Ž‹ˆ……ƒ‚„‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€ƒ‚~~~||ƒƒ‚ƒ‚ƒ}}~€€€~}}}}~}|zzz‚‚€~€~}€€€€€~}}€~€€€€€€‚€€‚‚€‚„ƒ†’ŽŠ‡‡†ƒƒ‚‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒ‚ƒ„…€|}}~}}~€€~}~}{}~‚ƒƒ‚‚}}~€€€~}}}|{{{zzyz€€~~~~|~~€~€€~}~~}|~€~~€€€~€€~€€…’’Ž‹‹‡‰…„ƒ‚‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~~~~€€~€}}„ƒ‚€~}~~€€€~}}}}{{|zzyyy{~~}~€€~€€‚€|~~~~}|€~~€~~€€~€~~~~~}||}…’’Œ‹Šˆ‰ˆ„„„‚‚‚‚ƒ‚‚ƒƒ‚ƒƒƒƒƒ€€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€€‚‚ƒ€€‚ƒƒ€€}}}~~~~}}}}}|||{zyyyy}€€€€€€‚‚€~€~~~~~€‚€€€~€€~~€}~}}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…ƒƒƒƒ…„„„„ƒƒƒƒ‚‚‚‚~~}}}~~€}}}}}}}}|{zzyyyy€‚‚‚„ƒ€‚ƒ€‚€ƒ‚ƒƒ‚€€€ƒ„‚€€€€€€‚‚€€€€€€~~||Š“Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚…„…ƒ„…„…†††††……†€ƒƒƒ‚‚€}}}}}}~~}}}}}}}}}|{yyyyx|‚ƒ„…‚„ƒ‚‚ƒ…†‚ƒ„ƒ‚‚ƒƒ‚‚‚‚‚…ƒˆ…‚‚‚„ƒ‚ƒ‚‚‚‚€€€~Ž“Œ‡ˆ‡ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€€~}}}~~~€ƒ„‡ˆ„†††…††‡‡†‡‡‡‡†‡‡}€€‚~}}}}}}}}}}}}||~~~|{yxwxyy€ƒƒƒ„ƒ„„„——ƒƒ„}~‚‚‚‚ƒ†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ……„…ƒ‚ƒƒ‚ƒƒ‚‚‚‚ƒƒ‚‚’‹ˆˆ‡ˆ‡††„†…„„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€€~}~~€‚………††‡‡†‡‡ˆ†‡‡‡†‡‡‡|}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yxy|~‰—„ƒƒ„„”“€~~„‹€€€„†‰…„‚‚……‹ƒ‚……††„ƒ……ƒ„„ƒƒ„ƒ…„„ˆ’Ž‹‰ˆˆ‰‡‡‡…†…„…„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„„†…||||}}||}}}}}}}}}}||‘•–ƒ{z„”|xyz{|‚ƒ€ƒ‚€~|~~{ˆ‘||Ž–}‚†Š…ƒƒ„ƒƒ‰~ƒ„……ƒ…†…„……ƒ„……†„„Ž‘‹ŠŠŒ‰‰‰‡…†…ƒƒ‚‚‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚ƒ„ƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚ƒ}}||}}|||}||}|}}}|||{‹‘—Œz{|zzz{|yy}}~€€|{{~~}‚•‘„ˆ~|~‚„||‚„‚€‡ƒ}‚‚‚€ƒƒ„„„„„‚„ƒ„…‚„‘‘‹ŒŒŽŠ‰‰………ƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚ƒ…ƒƒ…………ƒƒƒ„‚ƒƒ‚ƒ‚‚€€€~~~}||||||||||||||}|||~~Š‚{z{zxz{{|}{~}~}}}}||}†~}‚~~€‚||€‚€~|{Š‚}€~€€‚‚€€€€‹“‹‹Žˆ‡‡……„„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ…„††„„€†”ˆ€€~~~€|||||||||||||}|||||||y{{{xxy{zz|€~|~~}€‚‚€€€‚‘€€~€~~~€}}}{}}}|}||}€€€~€~~‚”‘‹ŒŠ…††…„„…ƒƒƒ‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚ƒ†‡††~ˆ•Š~€€~€~~~|{{|||||||||~}|{}|||{|||zzy{|z}…ƒ‚~~€~…‚~€~~€…†‚€~~ƒ‡}|~€€€~}}}}~{{}€}~€Œ‘‹Œ‡„††…„„„ƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}~€‚ƒ††……~€€€~~~€€€€}}||}~}|}}}}}}|~|}|{}||z{z|}}†„‚€€}~}~~‹„†~}||~‚}}}}€|{}|~„ƒ€~~~~}}~}~€~~~„’Œ‹‹ŽŒ‹Š†„†„„ƒƒƒƒ‚ƒ‚ƒ‚ƒ‚€}|||}~{{}w~vx~}|}|}~~‚ƒ€z}}|~€€~€~~€€€€~~~~~~}~~}|~}~}}|{|||z{z}~€ƒƒ‚~|}|}||ƒ~Œ~|{{}~}~~}{{{}{z{{{€†„‚„ƒ‚€~‚‚‚‚‚€ŠŒŠŠŒ‹Šˆ„„„ƒ„ƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€}}~~€€€€}€~~~|‚~~}}}{{}}|z||~€‚€€||}|||||}|}{~{{{|||}|{{{{||zz}z~‚~ƒ„‚‚…†……††‡…‚„‘ŽŒŠ‰Š‡‡…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~~€€‚€~~€€~}ƒ||}}|}}}}{|~~~~}~|||||||~~{|{||||}|}|~|}||{z|y{|{{}{}~~€€ƒ‡‰‰‰Š‰Š‰…ˆ‘‹‡ˆ†……ƒ‚‚ƒ„„ƒƒ‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€~~~}€€€€ƒ‚€€€€€€€€~|z|}}~}}~~Œ†}}~{{ƒ‚}}}}}|}|}}}~|}{}|}}~|~}}}}|{{z|{||{z{{zzz{~~‚…ˆ‡ˆŠ‹‹Š‰ŒŒˆˆ†…„ƒ‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~~€€€€~~€€€€‚„„€€€€‚~}~€~{~‘Œ|}Š€Œ~~}}}~}}~}|||}}|}|}}}~}}~~|{{{||}|{z{|yzyxy{~„ƒ„‡‰Šˆ‰ŒŠˆˆ…„„ƒ‚‚‚‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}x|zr}{{|||~~}}€€€‚…ƒ„‚‚‚‚€€ƒ‚€}~€~|~ˆ‚~ƒ„„ƒ~}|‡}}~}||~|}}|}}}~}~}}}{|}~||{|}zzyyzy{{~~€ƒ‡„ˆŒ‰‰†…„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{|}}}}zx‚€‚‚€€€€€‚‚‚‚†…„ƒ€‚„~€}~~}~€€}~„€~~}~}}Š…}~}~~€}}}|~~~}€}}}|}||{|}{{{zzz{{|}~}€ƒ€‰Œ‰Š‡………„ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv~€ƒ‚‚‚‚‚ƒƒƒ‚…†„‚€€€€‚€„~~€€}~€~}~~€€~€€}~€~€~|}}|~~~~€}‚€|}€}||}}||{||{{{|{|||}|‰‰‡‡…†……„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xvw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€ƒ€€€€ƒ~~€€}€}}~~€€‚€€€}€€€€€~|}}}}~~}ƒ}€~‚€}~€|~~}}}{|~|}|||{|{|~‰…†„…‡…„…„‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz}}yxtt€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚~~~€}~€}}}~€€‚€€€‚}~€€€€€~}}}~}~~}}„€~}€}}~}~~}~|{|z|{z€…‚ƒ„…„„„…ƒ‚‚‚€€‚‚ƒ‚‚ƒ„ƒ„ƒƒ‚‚ƒ€~€~~~~~}~~~{{z~‰‡~xry}qzx{xytu}‚ƒ‚ƒƒƒƒ…„…„ƒƒ„„ƒƒ„‚€€€~}}~€~~~€}}|}}~€€€€‚€€€ƒ€~€~€€€~~~~~}~~……€€€ƒ~€~€~€~}{z{z|{z‚ƒ‚‚‚‚ƒ‚ƒ‚€€‚€€‚ƒ‚ƒ„ƒ„‚„‚‚‚‚~€~}~~~~}~}}z{|…„{{sy{|pwuvwyvtz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€~€}}}~}~~}~|}}~€€€€€ƒ‚€~€€€€€€€€‚‚‚„€ƒ€€|{{z|{|€€‚‚€~‚‚ƒƒƒ‚„‚„‚€‚€~€€}~~}}}~}}{{z€x|vyz|qtxwvxury……‚„„‚„……†„„‚„ƒƒ‚€€~€€|}}~€}~~}|~~~~€€ƒƒƒ€€‚€€€€€€€‚ƒ€„}ƒ„€€‚}z{{||}}€|~}€€~}}€~‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxzzruyyvwwsu†…ƒ……‚„„…„„„‚ƒ‚ƒ€~€~€}}}~~€~~}|€|~€~€‚ƒ€€‚ƒ„‚€€€€€‚ƒ‚ƒ€~‚‚„€€‚‚‚„~{{|||}}}~}z~}~y~|||~}~€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„‚„„…ƒƒ‚ƒƒ€}~}}}€~~~}}€€~|~~~‚‚ƒ‡…~~€€€€€€‚‚€€~€‚~‚‚ƒ‚ƒƒ…‚}}}|{||yz{z~y|yx~{{{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst†„„…ƒ‚ƒ„„ƒ‚‚‚ƒ‚‚€|€€~€}~}~€€€~|~€€€~}~~€}€€ƒ„ƒ~}~~~€€€‚€~~€‚‚€„‚„„†„€~}||||zyvyyzyvyv~|{{{~|{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…ƒƒƒƒƒƒ‚‚ƒ‚ƒ‚€~€}}}}€€€€|€€€€|€~~~}~~‚‚~~}~~~~€}€€~~~~~€‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{z{~…}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvqwyrx…………ƒ„„‚‚ƒ‚‚€ƒ€€~~~~€~}~|~€€€€{€~€€€}€~~}}}~€~~~~}}}~~|~€~~~‚~~€€ƒ‚ƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}}{|z{}zzx{|zz{xtxuqrtpxxqy„………ƒ„ƒ‚ƒƒ‚‚‚€€€€}~~€}|~}€€€|€€~€}€~~}}|€€€€€~~~~}|~~~|}€~}~€‚~€€~ƒ‚‚ƒ……‚‚~~|{{||yw{ywxwwx{{z{|…Š}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzz{zxswuqqspxwq{…†……ƒ…‚ƒƒ‚€€€€~~}|~}€€‚€€}~€~€€€}~|}€€€€~}|~}}~~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{|||zzzzzzxsvupprowvr{…‡„…ƒ„‚ƒ‚‚‚‚‚€€}}~€‚}~~~€€‚€€€~}~|€€€€€~}~~€€‚€€€€€„‚‚€~|}~~z}„~t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚€€€€€€~}€€‚‚‚€~€€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€€‚€€~}~{’Œz|}|{}y{zzxyxy{||}|||||||}}}||}|~}~~~}|z||{|}{yzzzyysuuooqpwst}…†ƒƒ‚ƒ‚€€‚‚€‚€€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€€‚‚€€€}~~|†‰||~{{~yz{z{~wwy{|{}||||{}|}}}}|}|~~~~|z|}{}}{yz{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}€~~€€€€€€€‚‚‚€€€€€€}~€}€ƒ‚{~~{|}{z||{‡yxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€€€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ„„€~‚€€€€‚~€€‚€€€€€€€€€~}€€€€€€€€€€€‚€€€€€~}~}~~{}|}{||wxuxxy{||}|||||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒƒƒƒ‚‚ƒ€‚…ƒƒ„ƒ€‚ƒ€€€‚ƒ‚€‚‚…ƒ€~‚ƒ€€€€€€€€‚€€€~€€€€€€€€€€€€€€€€€€€€€€‚‚‚‚€‚‚€€€‡~~|z}|{}~xwvyyy|}||}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚‚„„€€‚†‚„ƒ‚„€„ƒ‚‚€€‚‚„‚‚„‚€€ƒ‚€€€€ƒ~€ƒ‚}‚€€€~€€€€€€‚‚€‚ƒ‚‚ƒƒƒ‚€€€„}}}|}z}€zyvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysruowqwysw{…‚‚ƒ‚ƒ„‚ƒ„ƒ€€‚ƒ†ƒƒƒ‚‚„„ƒ‚€€‚ƒ‚‚‚~€€‚‚ƒ€€€€€‚„€~ƒ€ƒ‚€~€‚ƒ‚€ƒ‚ƒ‚ƒ‚‚„€ƒ‚„ƒƒ„„ƒƒ„ƒƒ€‚€}€|z|{{w|yyy{z}~}||||}~~€€€„„€}€~{{{z{ztpxrytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚‚„†„‚ƒƒƒ„„„€ƒ€ƒ‚‚‚‚‚€‚€~€€‚‚‚‚‚€ƒ‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚‚„ƒƒ„‚„‚ƒ‚‚‚‚ƒƒ„ƒ„„„„„…ƒ„‚ƒ‚‚ƒ€€~||€||x|yzyz|}|{||}}}||€€€€€‚~€€€€{{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚‚…„„ƒƒ‚ƒ„„…‚‚‚ƒƒ‚‚‚€€}€€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€ƒ€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒƒƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{~~}y|zzz}||}z||}}|z{~~~€€€€€€€€€}}||}|vrvxxvtvt}‡‡ƒ‚„…ƒƒ„…„€‚„…„„ƒ‚ƒ„„€„…ƒ‚‚‚ƒƒ‚ƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚‚‚ƒ„‚‚€€‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚~ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz{}}||z|~}|}}~~€€€€~~€€€€~|}}~~}|{xvuv„‡ƒ‚ƒ…ƒƒ„†„‚…†…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„‚‚‚ƒƒ‚ƒƒ‚„„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒ„„„„„„…„ƒƒ„…„„„ƒ‚€}‚€}||{||€}}~€~~}~|||}}~~~€}}~€~~}}}~}}~~€||€‚‚ƒƒ†ƒ„ƒ†„‚ˆ‡…„ƒƒ„„…………ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒ‚ƒ‚„ƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒ‚‚ƒƒƒ„ƒƒƒ„ƒ„„„…„„„…………„ƒƒƒ}„€}}||||~}~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒ„…ƒ„ƒ…~‚Š‹…„„ƒ‚ƒ…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…„„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ…ƒƒ……„……‡‡†‡…„„…„ƒ~}|~}}€~||~~|z|}}}}}~~~€}}|€€~~~~~€‚€……„ƒ…„‚„ƒ†€‚……‹‰„„ƒ„……ƒ‡††„„„„…„„„„ƒ„ƒ‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ„}uyƒ€~„„‚ƒƒ‚ƒ„ƒƒ„…ƒ„…†„…†}„y|~ƒ{…ƒ€„ƒ€}}~}}ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚‚ƒƒ‚‚†„„„†„ƒ„…ƒ„…ƒŠˆ………ƒ……„†††ƒ„„………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚ƒusqƒ†tpurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚……‚hzrss|s‚ƒƒƒ}}}~}~‚ƒ|}€}}||||}|||~}~€}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ…ƒ†ˆ††…ƒ††‡‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vyy…r„ƒpvxqvtturstvi€nrotvnulwm{sn€ˆym}rsvsvmmxlpylu}~}~€}€~}€€}}|||}|}~}€€€~|~€‚€€€€€€€‚ƒ‚ƒ„…ˆ††€‚…ƒƒ„‡†ƒ………†‡‡„ƒ†‡ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoomw}x†pqzprtfu~n{ysoy€}}|}|~€€~~€€€~~~€~}€}€€€~~€~‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„†……††ˆ„„†‡‡ˆ†‡„††‹Š…„†‡‡…ƒ………„‚…………††…†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„qjoyxpkyszozwvvp€~~~z~}}}~}€ƒƒ€‚ƒ„‚€€}~~~€~~‚€€„‡†ƒƒ†„„…†‡†…………††ˆ……†…‡‡…†„††‰ˆ…„‰Šˆ…„††……ƒ……„…††††…ƒx‹yrˆz{pp…„x…xyks~y{krƒ‡ƒz|m{yyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|upozls|nw‚€~~}}{}{|}}~}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡……………‡‡ˆ†„†…‡††…„……„……†‰‰‡†„†…††…†…„††‡††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„…†…†„†„ƒ„„†„„ƒƒ„„…„…„…„†ƒ†‡…†„„…‡†„„…†„…}w…ƒ„„‚‚}~{|{~{||}~}|~}€€}€~~~€~~~~}}}~|{|~||‰†…„†††…‡†…………††‡ˆ†„†…††……ƒ„…†…„††††……†„…††††…††‡‡†…‡ˆˆˆˆ†„‡…††ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…ƒ‚……†……ƒ…„„„…„……„……„†‡††…„†‡†„„„…ƒ…„‚„ƒƒ…ƒƒ‚}€{{|}{||}~||~}}~€~~€}}|€}~~~~~||}~{|||{{~ˆ‡„„ˆ†††‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡……†……†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ…„ˆ…†‡†‡†ˆ†‡…‡‡†‡……†‡…‡†…‚ƒ…††„„ƒ„„ƒ„†„………††„††…†…„††…„ƒ„„ƒ…‡…ƒ‚‚…ƒ„~€€|{}~{|{}~}||~}~~|~}}~~}}||~~|}€|||}|||~z{{}~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†ƒ„„††„…‡ƒ„…„…‡„…††…†„††‡‡††‡‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…‡‡…‡†‡†‡…ˆˆ‡‡…††‡…††…„„…†……„„„ƒ„……†††…†„†…†‡……††…„‚„ƒ‚„‡ƒ„‚„„ƒ€€€{{~}|||}}|||}}|}|~}|}}|||}}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††ƒ…†…†††…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡…‡††‡‡‡…‡†ˆˆ‡‡…‡‡‡…†‡„‚„ƒ„†…‡……„ƒ„„…††††††‡……‡…†…†…„‚„ƒƒƒ‡ƒ€‚ƒƒ‚‚‚€{}~}{||~}|}}|}{||||||}{{{}|{~|{|}}|}}}|zz{{||ˆ‡‚††††‡††…ƒ…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡‰ˆˆ‡†ˆŠ‡†‡‡†ˆ‰‡…ˆ‡†ˆ‡††‡‡…‡†ˆˆ‡†…‡†‡††‡ƒƒ„„ƒ††‡……„„„…†††††…†‡††‡††„†…ƒƒƒ‚‚ƒ†ƒ~‚‚ƒ€ƒƒ|~~||}}|}}|}z{{z{|||{{{~{{}{{{~||||}~}{z|z|}‰‡ƒ†…†…††…„„……………„ƒ…†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…‰Š‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……‡ƒ„†…„††‡†……ƒ……††††‡…‡†‡†‡‡…„……ƒƒ‚€ƒ…‚ƒ~ƒ~~||}}{}}|}zz{y{|}{{{{~||||z{}||||~}|{{{{|{‰‡„†„†„††…„…†…„„ƒ„‚€ƒ…ƒ‚z„Œ{€„…‡†††…„‡ˆ‡†‡……‡‰‡„‡…‡†ˆ†…‡„†‡‰††ˆ‡‡‡†‡ˆ†„†††‡†…‡ƒ„…„†††‡……„ƒ……‡…‡†‡…†††…††„ƒ„…‚€ƒƒƒ‚}€~ƒ~€||}}~}{~}|}yzzy{}}zz{{}|}||z{}||}|~~€|{{|~}|ˆ‡…†…†„†………………ƒƒƒ€‚…‚€€}|{„…††„…„ƒ‡‡†††…„†‰†‚†„†††……‡…‡ˆ‰†…ˆ‡‰‡††‡…„†……†…„‡ƒ„…„ˆ††‡……„‚†…†…‡†‡„††††…†ƒƒƒ…€€€„€ƒ€|€~~‚€}€||}~}~{~}||yzzyz}}yzz{|{|{{z{}}|}|~~~|{{}~}|‡†…†††………„……„ƒ‚€‚€€€ƒ~~~€yz}€ƒƒ„‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ……ˆ‡‰‡†…†…ƒ†„…‡ƒ„†„„…„‡†…†…†„ƒ†…†††††„…††……†‚‚ƒ„~€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|z{{{|}}}|~}||}~|{‡……††††„…„…ƒ…‚€€€€~‚‚}}{‚ƒƒ…†…„ƒ‚†ƒƒ„‚€…‡…‚ƒƒ„„„††‡ˆ‡……ˆ†‰‡…ƒ„„‚…ƒ„†‚ƒ…„„†„‡†………†ƒ„…„…†…†„ƒ…„…ƒ……ƒƒ~€ƒ|€}}‚}€~~~}}}}{|{zyzzyzz|yzz{{{}z{{{{}~}}€}}||}€}|†ƒ†††††ƒ„‚…‚…€€€~€‚|~~€€‚‚‚„…ƒ‚‚„€ƒ‚€„……‚€‚ƒƒ„…†ˆ†…„…‡…‡……‚ƒ‚ƒ‚‚…ƒ…„…†„††‡††…‚„„ƒ„†……ƒ„„ƒ„ƒ…„€€‚‚}}~~€ƒ~{||€}€}}ƒ|~~}}~{~{{zy{zyzz{yzzz{{|z{|{{~~}|}||}€~€†„……„‡„ƒƒ‚†‚ƒ€€~~€}‚|}~~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡…„„††„…ƒ…‚‚‚ƒ‚„„„……†‡‡†…„ƒƒƒƒ„†…„ƒ‚ƒƒ„ƒƒ€€~}|~~|ƒ}|~||€~‚}‚|~}}|||{{zzzzy{zzzzzzz{|y{}{|~€}~}}}€€€†„„…„…‚ƒ‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„†„‚ƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„……‚‚‚ƒ…„‚‚€…ƒ~€~||~}|~ƒ}{~|}€ƒ~}€~}|{|}{{zzzyy{yzzyzz{{{z{}||‚€~€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7:<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌËËËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFL=8765999<>9?<D:;<8:<>;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937677=;>9=::;89:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<9<<97:9:::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA><A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÕÔÔÔÔÔÔÕÔÔÔÔÔÔÓÒÓÔÔÔÔÔÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9?CE@<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËÊÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÙÙÚÛÛÛÛÛÛÛÚÛÜÛÛÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÚÓÒÓÓÓÓÓÔÔÔÔÔÔÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILO@99:4;A<7=9AC>@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÏÐÏÏÏÏÏÏÏÏÏÏÏÏÖÞÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‰’™˜˜˜˜˜˜˜˜˜˜˜˜—Œ‹ŠŠŠŠŠŠŠŠŠŠŠ‹†‚ÓÒÒÒÒÒÒÓÓÓÒÓÓÒÝãâââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVN<::77>C>8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÌÐÒÒÒÒÒÒÒÒÒÒÒÒÑÞìëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSQblkkkkkkkkkkkkiUSSSSSSSSSSSSTKCCDCCDCCDDCC?]ÒÓÒÒÒÒÒÒÒÒÒÒÒÐàìëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;@C>6:7>?;=B?9<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÌÌÑÒÒÒÒÒÒÒÒÒÒÒÒÑÝêééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWVepoooooooooooomYWWWWWWWWWWWWXPGHHHHHHHHHHHD`ÑÓÒÒÒÒÒÒÒÒÒÒÒÐßëêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;>@@8:;8<;;<?:;;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÍÐÒÒÒÒÒÒÒÒÑÑÑÑÐÜèççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbbaoxwwwwwwwwwwwwucbbbbbbbbbbbbb\STTTUUUUUUUUQkÒÓÒÒÒÒÒÒÒÒÒÒÒÒÞéééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB?;=:9;:==;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÎÎÎÎÎÎÎÎÍÍÍÍÍÍÎÏÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÏÎÎÎÎÏÎÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÍÎÎÎÎÎÎÎÎÎÎÎÎÎÍÌÌÌÌÌÌÌÌÌÌËËËÌÌËËËËËËÌÌËËÌÌËÍÔÔÔÕÕÕÕÕÕÖÕÖÖÖØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<8@B<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÑÔÔÓÏÎÑÒÎÏÒÔÕÔÐÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖ××××××Ö×××××Ö××××××××ÖÖÖÖÖÖÖ×××××××××××ØØ×ÖÖÖÖÖ×××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?79:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÑ°ƒ„“ÎÓ¸žÏќ‚„ŠÆÏÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<>B>BC@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÏɛ»¸¯·—™¹º•¸¹¯¡ÒÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?>;7:>9?D>A98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÑ⏀‰É£¨²Ñ’}~¯±ÒÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<<:6?B@C:647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÑ¿žŠ§ÐÓ†šµÕÓ͞žÄÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8FA?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏѺ¤¬œžÑÖ£˜´ÔÓÀ  ÐÐÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<>=964:99::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÑÀ ž“¥·Ø¢™µÔÕ°¢©ÕÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<9765::6:<;7<@@<::=:=?>=<9@<<::9?@>=<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÐÒ¦¯®›¦Ù¢™µÔÕ¤¡¹ÔÑÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CFCAB8;?<=;<<8558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÐÑÉ×Ę Ù¢š¶ÔΟÉÒÑÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF@HIGE@<<>><=><756:969;::;8@?:<<9<>=;;:?9?;<9=>==;;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦Õōž ¨Ú£šµ×ß¡ÒÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;557<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡ÉÁ¡­¡ ¿Ø¢›´Ù²¤¦ÖÒÒÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKL@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÓÕ«©ÕÖ²„ÆÖ¹ƒ¿ÕÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<=?GFHKH=657:979:;:<=9>99:8;=>>A>=9<<:=>>;=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÔÁ½ÕÒÒÑÄÕÑÑÂÓÒÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?AELL@>775;8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÑÔÕÒÒÒÓÕÓÓÓÕÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEJ>>786977899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9599:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9948<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EILAALD??;:889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEGIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDJ;AA;<886486987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGIB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<BA<;876797799=?A?<:9@?<>B?:8776=??@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE>;HF89757875898;>>=;89A>=@?A>7596;>AB??@@BB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCEFC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELCA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<;DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGGNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAC?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995686673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668784;?<?=9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€ihxsg~‰‰xp‚†{w}~…Š½ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€ƒvt|„‚}sp€Šx‚yƒÈÞÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsoupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8<:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495666788:=;<>:<::==9<<=<==<;=DHDCA<<<<>>@;8<815:AFEW®µµµ¶·¸¸¹¸¸¸¸¸·¸¹ºº¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676889>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿¼½¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498566:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»ºº¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545659756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjdmgb\XQPQKTJB:IQ?A7<94:565455588686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸········¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®xpljac`YQMQLRFC9MPE>8;727967443578797;::==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µµ¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸¸·¸¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶·····¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨¨¨¨§¨©©©§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸········¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥¨©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥£¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§§¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©ª««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤££¢¢¢¢  ŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:9:>7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž£¤¡žžŸ  žœœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=7789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥¤£¢¡¡¡¢£¥§¦¦§¬¬§¦ œ›¡¡ž›ššœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¥¦¦§§¦Ÿ›š›¢ ™––•š›™——˜˜šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜—™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥¢¢¥¦¦¥¦§¦¦ ›™›¡ —““’—šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AB??AB@DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥¦§¦¦¢œž¡Ÿ—‘‘”—›˜–––˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<;;9:765846789=88;:;?;:;<:9:7768;;;=<::<=<7;>CBDC?=AC@DA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¥¦¥¥¦§¦¤¥¦¦¥¥£  ¡¡Ÿ™’–š™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šžŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡ ¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?B@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢¢¢£¤¤¥¦¥¤££¡¡¡žœš•“”˜›š›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œ ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸŸŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::88:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸ   ¡¢££££££¢¡ ž›™™˜™™™š™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢ ›ž ¡£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œž››œŸžœœœœŸ   ¡¡¡  ¡  ¡¢¡¡¢¡Ÿžœšššš›œš™š›™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::;;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=:;9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥£¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¡¢¢¡   ¡¡ ŸŸžœš™š›››œ›š›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›šœšš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>99;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤£¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ žžŸ     Ÿ ¡  Ÿž›š™šš›››››Ÿžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›ššš›™˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9;;>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœ›œžžŸžœšš›œœœ›œœžžœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<>?::97;8887489<;<8;;<=:=>:?A=:=<>>@@=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››š›œššš›œœ›™™œœœžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™˜˜ššš™™™˜š›œœœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›š™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:<=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š››››œ›˜˜˜™™˜˜™™™›œœžžžžžžžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ›››››››™˜˜˜˜˜˜˜™™œœœžžžžžŸŸžžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<:7:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ››››››š˜˜˜˜™™˜š›œœžžž  Ÿžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_]]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;97::;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜™——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››››››˜˜˜——˜™››œœœžžžžœ››œœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹ŽŒ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±³­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=9F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:846<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œšœ›œ›˜™š˜˜™ššš–‹“–™˜•˜˜–›œ—•’‘’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹”“‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨©¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8537:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‹‘‹ŒŽ‹……‡‹ŒŒ‡ˆ‹Ž‹‡Œ…†‹†ŠŠ‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VPQAELOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8AB?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹‹†Š‹‹‰†„†‚€‚‰‘ƒ€ƒŒ†‹‰…€‡}€’†„„†ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹Ž‹‰‰…‚}s}ˆ€~œ„……‰‹Šz}}†ŽŠ†”‘‹—”—’˜¡–ž—•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¥›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ†‹‡ˆ…„ˆˆ‰„€‚z||}~’ˆx…‹Šƒ„…ŠŒ‘™””” ššŸ¢­±­©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPFMHSWRe^gTPL\QHLRCA997958866;79:<:>98;:::<<>=<D>96;;88>95157BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~ŠŒ‡Œ‹‹‡’Š‡†‘“‘‘„‡}}ƒˆŒŽ‹ŽŠ‰Ž””˜‘•›š¨®²¯¯µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWLO_^\NUTbQDTM;?9<895775795:::9;8:<<:=<>>??B=86::9:@;5256AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš˜ “—š ™›£ •› ¤£š“ˆˆ‹‰‘‘Ž’Ž‹˜šŒ”š—œœ›Ÿœ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUKTOOJCPK_bXZQ\S_MHQIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ª©¨§¡¥¨¨«©©¯¡›Ÿ¡££ šŸ œ”˜”˜  ¡¤ž›š¤§¤©«®¬¥£¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdVOXKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®ªª«¤¡¢¥©§§©¨£¢œ››¤ ¥¨£ ˜™Ÿ¡¢©§ ¢¢®¬«ª§­®¨¥¤©©©©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_UZNRNPORd\dc[]Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢šœ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨¦¥§¨¦©¨£§¦™œ¤¥¢¡ ¡¡ œ˜™Ÿ ¡¤¤¢žž– ›š¢¢ ¡Ÿ ¢¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOWO^ddlgbbZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤Ÿ¢ ¢¦¡¦­¦¦ŸŸŸŸŸ™šœœ¡ ¡¤Ÿ¡›šœ ž¡Ÿžž £™–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvwa_\UYQUV[c^r_h_cSQYTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?C?:8:>?C@DA:;><@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯«ª¬¨¨«°©¨©¨¡Ÿ §©­°²¯¬£¢¦¡©¥ž¤£¢¦ ¥¤¢¥£ž žŸ¥¢¢žŸ¢˜•žšžŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸ ¡¦¢›—’šš •|wo}yf[[_^Z\V\hdocnihb^PP@?;:898<;624333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¢ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£Ÿ¢ª©§®·¶´´¶³¯¬«®«¶°©²±­®§¦ž¢££›œ—¢¨¥¡Ÿž£›ž¡š–¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¢™˜¥ ¤§ª©¨ª­«¥©¤¥ª§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜—œœš¡¡š““—˜›wrvxib[_^\bY`dnmkna_d`POA@;;9;8:9614364777:=:<;9==B?>?=<:?9;;<>BE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢œŸª²¸¼¼½»º¿´¯±³µ´··¯µ´µ²°¨¤¢Ÿ —•š—¤ª¦¦¡¤£¤«¥¥˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨©«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥ ¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxyxc[RYT__alhukpgiibYSL@<:;89797556285678:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶³º±ª®´±°±´´¶¼¼¾¼¼½Æº¸·º½´¯µ±±º¸·²³²ª¦¦Ÿ˜¤¤§¨¤®¤««µµ®³ §ª¬§ª©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš“–””˜“š˜Š‹‡€€|‚xa^YTah`fsositcidb[LK>:8898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÃÆÃù½¿ÀÀ½¿Ä½¼º½¾´§ª˜±À½¸µ¹À³¯¯ªª¨­§§¤¯§ª´¼±´µ¨¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`a^^jbbnwuvnm[bQU\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAB;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–•–‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±±§¼¼¾ÅÄÆÉÇÅÆ»ÄÀÅÆÀ¹¯½¼À¾¾³«ªŒ³»¾´µ·Âº­¯°µª«¦ª£­¤§±¶«µ²­³­¨®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|ƒjfhaklfnuqruqf^_\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<;>BDE>>=@CCCDD;:8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿µ³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÅ¿ÃÂÆÅÀ±“¾º¿Ã¶¶º©´³´©«³»»±Ÿ›±¯¬¤¬®´§ª©¨ª­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š“‘™—ž¡•˜š’˜”•‘”š˜““–’‹‘~z|tkkndolhqxoyiia\gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABB@=@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐËÆÆÀÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÃÄø´À·´½Á¹··¿À»®¥®·¼·­œ£·°¦­´µ¬®¥¥£¨¤  ¥™ª³²¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸¸»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™›˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyz{vnkiguZfrwsxff]d[RXIF?;78876169754333646;8:<;=<8=><:;<:=;;>>DAACB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜Š‹ŒŽ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÉÎÉÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÉÆÃÃÄÂĽ¸¾ÁÃÀľÁÏÏÎÆ«¯¶´µ« §´³®«¸µ³«©£¢­©¬¦­Ÿ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuueeijh]jomxwbb``]XWFE8:8:979449766512335;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÏÏÌÃÇÆÈÈÈÇÉÇÅÉÇÈÇ¿ÅÇÄÄÇÈÊÒÏÒ̼¸¶´¸¸Á¾¾º½º¼º¼¬­¦©»º¹·À²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqobagugihtmxl]d[U_YLHD6<9988:53:664413525;:<>;;<=<;<=<;<?=?B?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÍÐÎÇÌÉÂÁÆÁËÊÈÆÌÉÍÅÆÅÃÆÅÉÍÐÍÏÌÇÄÀÃÂÉÍÇÅÁÄÇÁ»¾´±°°Á¾¿ÁÆ¿¾¸·Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`jjvlidtnsb\bTWTSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<:>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÅÇÈÆÒÉÁÃÿ¿¾ÄËÈÊËȼ»ÈÇÉÍÈÃÈÉÉÅÅÃÂÁÂÇÇÉÊÇÌÈÇÈÍÆËÏÅ·ÀÀÀÀ»»½µ³³¿¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrofegcjdajmnn^X\VUNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾÆÁ¹»Ãº¸¹¼¾ÁÆÁƺ¹ÉÉÃÅÄÀÄÁÂÁÄÁþ¾ÂÀÀÁÂËÃÆÌËÅÈÑ°¾½¸º»¼¾·´°¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfadbabccjbfbZYY\XQNE=;9:;77996499:5314527:;:@=?<<977;;::<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶·´´µ¿º½À¹½ºº´¿¸µ·³¯»¼·À·¾Â¿Á»¿À¼»Å¾»ÁÄÀ¾¾¸¼ÁÁ˾½ÉÄÀÀÊÀ±Á¿»¸»¾¹µ·´¸¼´½¸µ´°³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ §¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|y‡}qc`bbgjffiei]UUSYOSKE8?6;:779;65:;<6313417;98?=>;<;76998:<=@?>@==?B><@ACCA?C=:6<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“’’˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´´±°µ·µºÁ¸¾¸¿¼½·µ·°®¸¶¹¿»ÀÀ·Á¼»Ã¶ºÈ¸¶¹»½¹º¶»ÅÅʽ¹ÅÀ¿¼Á¾¸Æ½ÁÀ¼Å¸¶·´¸¶¶»»¸¶´·ºµ´¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¡¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒ€xpmedfoiekgXXNKKJRILHC9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<97>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’š”þÆÁÁ¼¼¸¸º¿¶¼±Â¶´¼±´¶¸³º½¿½¼²­¯¬±°·¼¶¼¼ÀĹ···¶º¹º»À½ÃÀºÄ¾Ǹ¹¸­·µ¸º´·³»ÅÆËÁ»ÆÀÀ¿½¼¿ÉÃÄžƸµ²²½¸¸¸¾ºº¹¼»º´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~†|knpgpksebl_[THKJDJBCG?9;8=<7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??==97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘ŽŽ˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼¼À·ª­¤®°·»³½¿»Ä·¶¸¶·À¿Ä¼ÂÅÅÇÇÊÉÆÏÂÁ¸®¶µ¼¾¸»²¾ÄÄÊÅÁÉÿ¿¾½ÇÌÇÇÄǽµµ¶Á½º»¿Âº¿Á¿½¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†qelintnwcga[bPKTHEECGC<;98=:7:=:89;7<=53650689:<;@=<;><9>99=>;?>C<?>@?=??FD@A?>:7?@CC?A=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¹¯²¼¼°·»¶»¼««£°¹½¾³¼¾¼Å¸²¸¹½ÇÉÊÃÇÈÆÆÉÈÌÎÑÌÊĵºÀÃÈ¿¿µ¿À¿ÆÆ¿ËÆÿÁ¼ÀÃÌÊÇÅÆÁ¹½¼Ä¿À¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtolltkln_b^aaMHM?E@?DC;;::;:8;<:9<>9:>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED<AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿­³½´¸Á±°±´¼Ã¼ºº¾¼Ä¿·½¿½ÇÌÆÇÉÆÆ¿ÄÄÊÈÌÌÍËÆÂÃËμ¹½º¹ÀÿÈÆÄÁÁ¿ÅÀÊÉÃÃÃùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{z‡zmmw{_pc[]_^SI>BEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=@>AAA>>ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µº¶¹Ä¸µ¼¶º½Á¼»¿¶¿Á¿¼¿ºÀËÂÇÈÀ¿¼¼¿ÅÂÇËÈÁÃÀÀÉÊÂÀ»»°´»½ÀÅÆÅÅ¿À¿ËÇÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}‚zmsxsgp]Z^\YQEDCMIAD=G::59;:<<:;;;=?:=54512788;<;B;?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘–žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯·¶²µ³·¹¼»¶»»½ºÃ»·½·¹À»º¸¸µÅÁÃû¹³´ºÁ½¿ÇÀ¹À¼¾ÅĽ¾¹²°®¸·¿ÃÇÃĽ½¿¿Ãþ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸¸¸½¹»±¶²ÈÀ»¶´±°·¬³©°­­³·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¦¢¥ª¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|vluzpmh\__YSPAEHGK@DCH<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ˜š˜˜•™™Ÿ››œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹ÁÀ·½¹¸¹¶µ¿³´²¸±»ÁÀ÷·­°µ¸¸¸Âº´»·»¾À»»¼®¯®³²¹ÁÂÄþ¼¿»º¸¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ¯µ´´½º¾¹º»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰|‚zsvvwmp`^e][TJ<>?FF=FCC9:5;99><<::<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Ã¿·º·¶¶²´À¶²´¸³ºÀÁù·²²²´²·¾º³µ²¼º¼¶º¾²´´´°¸¾ÃÆÄÀ½¿¹³¯²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qtwtvql^b`[]NHA?=HCFMD@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••“˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·À½»¼¸¶º¶±Àº·¹¸¹»ÁÁÄû»¶´´°¶º¶´²¬¼¹¸µ¸Áº¸³±¬·¼ÁÇÿ¹ºµ®¥¬³°¦°­¨ž Ÿ¥­¶µÂ·¶´¥¨«¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅɺ½¾¶±§¤ž¡©±®µ¹¶²±«´·¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{wo|ourmc\fX\]RNMA>JB@JI@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;66:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³±­¶º®¬¼²¸¹·»¿½¹¾À´¿»¼º¸¾Â¼ÂÊǾÀ¸¹¶²´¶³´¯¬»º¸¶¹Àö®®ª²¶¼½¹¶²±­­Ÿ¤§§£¦–™™šŸ©®¹¬««Ÿ¥¨¤«®®§¯¬¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬²®³©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦©ššžš¡§§¦§©¯¶²«´¶¯ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yrvsmtik][jT]\OMHDFLAFMF8665:5:>8;97<=:;=:9236777>;=>::?><<<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹½µ²¸´¹ºµ¹»µµ³µ»¼À»¾À´¿¹¹º±ºÃ¼ÂÊÅ¿»¿¿¹³´³±±®°¹¹¶¼¸»¿²²²®±®¹¯ª«­¬£¨¡ž—˜¡•’•—˜Ÿ¨®¤£¤ ¢§¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬«¯£££¡© ›“Ž“’’™–š¤¥ Ÿž§˜•’”˜ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wrxhtsndT`cW\QNLH?HQDMC=8875:7<>:;<89<;;<;8248978;;<;8;=>;<<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢¤ž Ÿ§ ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼¸ÀÁ¾¼¼¼¹®­¯²²ºº··µµ¼´¯´«¶º¸ÀÄÁ»µ¼½¸²­³°¯¬®·¶²´µ¯ª¤ž›œœž¨¨Ÿ ¨©Ÿ¡§–›——“–Ž—›¤¨  ¢¢¢¥¥££ ž¥ ¤¬¤¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›©¨ª«ž¥£›£œ•Œ“–•–˜Ÿžžš™¦—“’–¢ ¥£¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦ ˆxƒ|vybwln\PhTPNGOLLCOQ@>;>39:5;9=;:9=99<;<<;936996:;?=:8;:><:=;9;=;<<=><@=?<8;@@A???949<7ACBD=@CŽª¤£¢¡¢«¥¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¹µ§¥¬ª¨µ²±°®¯²§¦¯£¯®µÁºµ·²·¶²´«²´®ª«¯°²´®¥ž’˜”™ Ÿ¢ œ¤¥Ÿž¨”›–—Œ—‘—“˜¢ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£ž™—š«¦©°£¥§ž œ•“‘˜–•˜—Ÿ˜›™›£™—”•š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’}|€uu}mk{dhUQcMIHGNRMJMG;D@<2?859;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜˜—–¡¨¬®¶·º¹º··»®¨ ¡©¡ ­«ª¦©¤©£¤®¥¬¬´¼·¬²±¯±­µ¯¯³µª§­¬£œ™”Ž‘–—™™ £¢›¥žš¤———–’‘‘“š—› ¤ªž¡¡ž¦§ª¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¡¤¡›˜ž¯¨®²«¥ªª š˜˜˜•“–š“••™•š——˜ žœœ—›¡›žš£§¥Ÿ¡¢¢£œ›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}vx|dxz`bRU_HIIKSTIRPL9>A67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—““œž£¨®­¬««¯ª¯©Ÿ—ž¥žž¥¦¤ ¢Ÿ¦ ¢®«¬­µ²¶¦¯´«©ª´±°°¸­§¡œžš”˜›š‘Ž‘–‘ŒŽ”™¢œ—£™š—˜™”™˜–›Ÿ¥¦© ¦£ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«º¨¦«§««©¬¬§  £±­±±´©±¯¢™œž¡™››š˜™›”•š–˜œ¤¡ š£¡šœ™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ Ÿž ¥¡žž¥ ¦™{|vvsh‚le\SZYMQJNOTLRLA7>B68<76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=?758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–•™’’œ˜¡ª¢§ ž§¡¤Ÿœ’œ¢›Ÿ¡£ž Ÿ£ ¢¯®¬¯±¬¶§­±­¦¦°®­¬°§ Ÿ¢ —‘”œ¡œ™˜’“Ÿ¡¤›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬¨¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½·¾°¬±®­©ª´±°§«¨²µ·³·¬±´£ ¥ ¬¡¡¢ Ÿš˜–•Ÿ››˜¤¡ ž£¡ ž›œ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚|xuiwu]mZR`HQUHFUVJBMG=JH8E<67;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:>758==?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›Ž“ž™¨®ž§žœ¡žšš’˜žœ¢¢  ¢ŸŸžŸ©«§¬©ª´««­«¥¥ª¨«¬ª¥Ÿž™’’”˜™–––Œˆ‹•ž–žš¦  ¨¥±ª§®£«­¶°´²±®¶¸½Àº­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«¯±¹·¼¯³°µÁ¼·½³³µ¡«¢©¨²©ª¨§§š™ž™©¦ ™§ ŸŸ§¨¥¤žª¡¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰…„~vqmivmhm\X[BVMJGMGBFM<>L=4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?858<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜šª ±¢·£°¦ ž—™–™ž›œ¤ŸŸ¤šœ¤¢¤£¢ª¯¬§©£ ¡¬¯®ª«§ žŸ¢£žŸž›œ””••žž˜”†š¡›«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶ººÀĹ½»¬®§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¹Â½¸³»Åü»·³©²­ª³´¯³®©®£«§¶±¬¢¯¥ £¯±­°¤¤¯£¡ š¡¦¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¤ž¦™›¢¤žŸ›››œ‡†{trkkurphW\QETHDIPH>EA4EH95;=6;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¢œŸ©²«»²¿«¯¬¥ž ¡œ˜›Ÿ › ŸŸ—¥•››ŸšžŸ¥¦§  ¬±¯§¤¤£¡Ÿ¦¬¦Ÿ—œ”‘™™•ŒŠ†ˆ†ymˆ ¤¢«¬´¼¶Ã¾¾³»ÁÃÂÅÀ¿ÂÆÆÅÃÈÂÀÅÈÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌËÌÒǾ¿À½ÇÆ·ÃÉÈÂÀŽ¹³¹º´»·°µ²ªº±®»¶¾ººª·¬ªª¸º´»®­¸£¥¢ž§¥¢£©¦™›Ÿ˜š§ª§ ¡¡¤˜”£–”š‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ„~zrkdioxjeZ[FJLDDSLDBD7:?;549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”••š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ³²¸§¡¡«ª¢ž¡¢žœ› ’ŸŸ–Ÿ™’š–›™£¡¯³©¡›ŸŸš—˜˜“–—“ŽŒ‚ƒ‚wsqnp¦­®´¹Å»ÍÇË¿ÂÌÎÍÌÈÉÑÌÍÌÇÉÅÆÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÒÓÌÓÏÓÓÌÊÂÅÆÆÊÇοÈÐËÆÅÆÄÀ»ÂÀ¾¾¾µ½³­¾¿ÂÃÆÄÆí¾¸²¸¼ÃÁÁº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›‹™‰•˜› Ÿ£—žš““‹•…€ytsebgrof^ZYCNLCEPIDB@55589B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>8;AA;;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›£¬žŸ®¦¥±ªÅÆÌÎÍ¿°Â©¥¨­­ª¡£Ÿœš©“™¡Ž “”’—™¤±±«¤  œ™—•“”—‘Œ‡„ƒˆ‡ƒ€€yrroly¤¶º¹¾ËÁÓÒÓÈÍÎÑÓÑÒÑÐÑÑÍÎÎÐÅÎÔÕ×Ò×ÍÆÇÉÌÃÅÊÏÊÓ×Ñ×ÒÕÕÓÓÈÌÇÍÍÉÒÌÍÓÍÄÇÉÉÀÅËÇÈÈž³³ÇÄËÊÊÎÅÉ¿½¿¼ÁÆÄÌÌÈɿÿ­¯²¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›•Œ†‘‹{ruvgbhwidVWQDMF@IQB=B<:23@<D<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<@?>9:@A:9>8:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ”£˜–Ÿž¤¯› °«¨¬±ÉÍÔ×ÏƻǬ­´¸¬®£Ÿ¤£Ÿ ¤¬›–©–—Œ—¦°®¥ž¡¥¢ž›–•–”Š}wpkebhqoq{…Š€vpnqtp…³Â¾ÅÑÐ×ÖÖÒÖÍÔÖ×ÔÓÑÓÔÔÒÏÑÃÐÓÖ×ÕÖÒËÉÎÐËÆÍÒÊÒÕÖÙÕ×ÓÖØÎÒÉÎÑÌÎÐËÒÏ¿ÇÆÉÂËËËÎÏÅÆǶ¿Ê¿ÒÌËÏÅÉÇ¿ÃÂÈÎÌÏÐÎÌÊÇ͸·»¨Ÿ¦«§Ÿ˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„|xsvpc`erb]R\IJFAEHI>;@8=4585:76:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢›©¦¢¦¬š¤°±©¨µÐÔ×ÚÒÇÆË´¶ÂƲ¶©¢¥¦¡¢«µ§š±¡–•Œ¦­«œ•™¡›¡¢Ÿž›–Šxida____^_`^blusqpolrqu’ÄÇÆÔÕÖ××ÓÖÏÕÔÚÔÔÏÏÕÔÔÑÑÌÑÎÓ×ÖÓÕÐÏÒÓÑÉÓÑÈÐØ×ØÑ×Ò×ÙÕÖÌÎÏÉÌÑËÎпÅÁÆÅÎÌÐÐÑÈËÌÀÊËÅÓÎËÎÇÃÉÆÆÈËÊÔÓÐÔÏÒÌÒÁ¹Å±¥¨µ®§š¨¬¥²¨°³¬¬““Žˆ‹Žƒ‹„Ž™“™‚…Œ{zqstmacim_VP_JJBFCQM?<>44:=52755<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;9<74:><??=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯®«ª«¦®¸¨«·ØÔÕÙÙÑÎÐÀ¼ÌÉ·À¯§«©£¤±¶³£¶ªŸ¡ª©¡˜–˜š›¡žšž”~rfcc__a`_a`_``_`fmppnkorvw›ÌÀÒÕÓØØÖÙÑÒÒ×ÏÓÎËÓÍÕÔÑÊÏÌÓÖÒÑÖÍÐÕÕÑÆÑÔÊÑÔÕÖÎÒÐØØØ×ËÈÎÃÈÎËÊÌ¿É¿ÇÈÍÍÏÊÐÍÎËÎÏÇÊÏÐÊÎÊÁÈÆÉÌÊËÑÒÌÓÑÑÏÏʽǹ°­»¸µª¶°­¨¸­³¿»±šŸ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…ˆyvopokbenpaW\ZIFFDLWE;@<33<=86855;>@=9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><=>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ¤§ž¸¶µµ­¥­®¾µ±ÀÙÓ×ÚÜÖÏÍËÃÓв«­®¬¦³²¹«³·©£Ÿœ–”—œžŸŸž•–˜•Šl__^adb``aa``a^__^]bmroostuvy¤¾ËÕÑÖÔÓØÖÎÎÓËÍÎÅÎÊÒÒÏÆÎÍÍÔÌÎÓÍÊ×ÕÐÌÑÔËÌÏÑÓÊÍÑÕÒÕÕÊÀÉÁÅÌÂÈÉÂÌÂÅÇÊÊÎÊÌÌÐÍÓËÅÇÏÌÇÇÊÄÆÀÅÉËÍÏÐÆÏÎÍÍÌÏÅÇÀ·¹½Âýù²³¾°»ÃĶª˜¥¡™–‘••’‹”š‘”””‚‰…xprkmh``qhXXhVMGLIPPB;D>;67:89:56==A<:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?<<;<<8;A@<:<9;;;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÅÃÁ¿»µ²±ÇùËÕÖÙÚÛØÌÍÏÉÖÖÅĸ²¶ª¤®­¹¹±²À¡—Ž˜–”’‘–—–‘Œ}fbcb`]^acb`_``aa`_][]grqqrsqmry¤ÆÓÏËÐÏÔÕÉÄÉÉÆÆ¿ÃÅÎÎÇÅÇÍÊÑÈËÎÍÆÑÒÏÎÌÔÊÇÊÍÎÇÆÏÒËÐÏźľÆɼÂÆÈÎÄÂÇÀÆÍÇÃËÉËÏÇÃÃÏÈÆÁÆÇÿÀÇËËËÎÂÊËÈÇÌÐÄÅǺÇÃÈÈÂÏÀ½¼¿°ÁÊǺ½ª±²§¥¢œ˜›¤™—™‘•˜‰‚wntdk`^fqa[W`GHHGIMTG?J=64355<<48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79;>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥³±¬ÉÍÊÈľ½ºÍÍÆÐÕÕÙÚÛØÐÊÐÐÒÔÊź¾¾°©·«¿º¹³¥’ŽŽ–†ƒ„„‚~……€t`[^^^`^`cdc_]]^_``_[Z\akrrookloo}¸ÑÈÉÊÏËÍĺ¿Ã»»º¹¾ÈÆÂÃÀÃÇÊÉÈÊÇÁÅËÆÈËÍÉÄÁÉÉÁÁËÐÄËÈ¿¹ÁºÅǽ¿ÅÎÊÿúÉÇȺÇÆÄÊÀ½ÁËÆÅýż¼¿ÃÄËÄÄ»¿ÉÂÅÇÒÅÁȾÊÉÆÇÆÐÃÃÆïÄËÇÄÊ·¿¼º´©¬¥¥˜Ÿ˜¬£¡¥š£ ›”{vrtfiZanmZ[XQDLFBGDLCFR?54334?<3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ËÐÑÌÇÂÃÇÍÏÎÍÕÐÖÙØÙÐÌÔÎÏÐËĸÆÁ¶µ¼±À¶º¬‘Œ“—‡{€…†€vxusq_Z[]`abcdded`\\]]_^`[YZ\borokilposÆ¼ÉÅÌÀÆÁ°¶º²²´²±Á¼»»¹¸ÀÁÁž½¹½¿¹ÄÊÅƽÆÀ·»ÄÉ¿ÂÉ»·ººÅ¾¼ÁÍÂƾ½µÀ½Ãº¼Æ»Â¹³¼Åö¿¶µ¾¿ºË¼µºÈº¿½ËÃÁÅÂÅÈÅÈÅÐÆÂÌDzÆÉÃÎÍÁÅ¿½²·°³§¨¨¹±¥­°«­¬”yvwjeh`hocV^YJEJFHKAEBEI@9:648853;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9;<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÆÂÄÈÎÒËÊÊÇÍÍÏÒÉÑÆÖÕÖØÏÌÐÈÍÈÊŽÊÁ²µº·»¶¯‘ŠŒ…y€††€~„|tud\\]^``bcbbeeb]][\^\^]Z[]]hsqmggnpry½ÌÀúÀ¸­°°§ª­¬§¸´¶´³²³ºµ½±·°´®²»Â¼Áļ¿ºµ²º¾À¸Ç¸³»µÀ¼·½ÆÀûµ®²¶º¾³Ä·ºµ«¸¼½À½°º¶¯¶º²Å¼¶®»¿´¶´Å¼¾ÂÅ¿ÃÄÅÇËÅÀÆÆ»ÇËÀÏÉÇÃÆÁ÷þ¾¶¹¾Æ¿¬µºµ·¶Žxtxfgebkn^V^`FKHHJFBCADE?<:565633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¦«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÎÈÆÉÎÌÐÍÎÉËÉÌÊËÆÑÏÓÑÏÇÊÆÊÅÄÀ¼Ï½³¹½¹¸·›Ž‡‰Š{y~‡†wx}th^]]]_`_`da^cec__\[^\]^Z[[]_lpmhfjnnr|¤Ç¿¹¸µ°«¬§ž¢ª§ž«¬³­©«©³­¶°²¨®¦¬²¼º¶Ã¹º¹°«µ¹»´Â¹¯¿°½¼»µ»Ç¹Â¶­ª¨°±Àµ¸¼¯°§±³´»¼«­µ¥®¶®º±°ª¹¯­»­»¸»¿¿½¹Â¿ÆÂÅÀ¼ÆÁÈ˸ÅÇÅ¿ÇÃúÄÆ»ÅÉÌ˳¹Â¼º²ˆrvvkiablhYWW[ALKMIEAC?FA;9:995854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<:9;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÆÏÒÌÄÆÂÅÐÈÏÃÄÇÁÆÆÅÅÌÃÊÌÃÄÁÇÀº¼»Ê·´»½µµ«‘‰|y~Š†z{„xn^]]]]_`__dcbccb`_^[[ZZ]ZZZZ]dmohggiknr­¹°µ®¦¥§§š ¤ šœ¥«­£§¢«©¬ª°£¦Ÿª­µ¶±½¹¯·¯¨®¸´´»·³¼®·¹´±»Á±Á®¥¨¢«±²³§¼ª«¨«¬­´´¦¨®¡¤¯©²¥§¨®¥¨·¬°²·¹º»±¼½¾¾Ä¿µÁÁÇÈ·¿ÀÅ·ÄÂÀ»¿ÄþÄÈÌÊ¿¾ÃÀÀ©†rsrji]aodWVXPHZRSKFFE>?@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·ºÄ°¶°›™•œ˜ª©°±³µ½¯ÆÑÐÍÄÈ»»ÌÃÌÀ½Ê¹ÀÅÀ¼ÌºÃÇź½Ä¾º·½Å¸¶¸»®±•ƒ‰{~€xt|swf_]]\^_`^_ccab``_^]\ZXY[[YXZ\_fkfegehkor…ª¥¬¦ œ¡¥”ž£›—‘¡£ª£¢Ÿ¥¥§¥­Ÿ›¤¥«²¯¶·§°¬§ª´«´¹°¶´¬¶¸±¯º¹±·¤Ÿ£Ÿ¦±§«§¹ª¤¦§¨§²­ §¦žš¤¦¬žŸ§¤Ÿ ±­­¬±³²³°µ¼¶»ÁÁ²º¾ÃÁ±¹¹Â³À½¿µ¸»½¾¼ÂÆÄÂþ¿Ã ƒwpkae_ko`UY_HNhOTGEJF<=@=:;;8255369:8;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;=:7676778666;::;9;;<859<:>>@;Èµ¶½¸ºÁ»¾µ ž”¡¦º¶«³³»³ÅÐÉÌÃǹ¸ÉÂÎÁºË¹½È»¶Ç»·ÄƳ¾Å¼·°¹¿»°³¶¯¢„‡‡‚}yvtpmkjjqi_`]\\]_`_acb````]\[\\XYXXXVX[]^dcbegggjmoˆ© —•š¡–›¢˜•ž¡¢¦›ŸŸ£¥¡§žš¢›Ÿª°¬±µ¢©ª©«¬¤µ¸­·¯¬²´®³µ®±ªŸž£¢²¤¥©¸­¡¦¦Ÿ¨¬«™Ÿ ž™Ÿ¥š™£œ›¯©«§ª«¬­°²¸®¸¹»°¶»»º«³²¹²½´¶±±µ´¿µ½¿½ÂÁºº½—ƒzrk_e^ddXTX^IW]KPGIJFA<??@;?<04535:;9:899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»·ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÆÐÉÉÁǼ¼ÅÅÐÁ¼Ê»»Á»µÅ¸µÁÁ³Âļ­ªµ¹·§±²©‹†ˆ€ysnpnkc^bff]]^]]]\]_`abccba_\[[Z[YXXWWWXXX[^bddeffhikr¨”””›—›¡––œ¡¡¨›œ¥¦¡¤›Ÿ š˜­­­¯² ¥¢­«§¡µ°±±¬§®²§¹³¦¶¡¢žš£¡­¢¡©µª¢£¦¥¦£–˜ž—˜›Ÿ™—œœ›¬¡«¦¢£¥­«²³ª´°²ª²¹´¯©¯²²²·³­©¬®±·°ºµ¹½¾¶³±”„yue^e^[YVSZUL\QLJEHKIB=?AA@@:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½¸½¿¶¾½¿³¥£˜¥±Âµ¶½­µ¸ÃÍÉÈÁƸÂÁÈкÃÆÀ¶¼½¶Ãº¶¿Áµ»¿»ª¦±º±§±¯š}……€ypqtqhediec\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXXVWadecdeddhjv¢œ””•——Ÿ—™”˜Ÿž¡œ–¡¡¨£Ÿ¨œ›šª¦®°«›££·ª Ÿ®¨¶©¦¦¬°£·°£¶ ¢›˜˜«¦¡›¬¸¯¢¡¤œ¡Ÿ “•¡”––›˜—–—œ”Ÿ©©£¡œ£ªª°­¨´«ª¦­²°¥ª®²±¯°®¯¦§§²®±´¯»³¹·­£”yud^aVYWSRTKM^LPLGHLKE<@><B<;7653498899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼´¹Â±¾¸¼®§§£ª»À½À¹®´¸ÂÍÈÇÄžǺÊ͵ÄÅı¿¿¹ÀÁºÀÀ¹º½·¨¨±»¦¨¡¤‰~xrjlrtpihedgb\\ZYZ\\\]^]\[\^\[\Z[\ZXVWWVWXWWWU[ccbbcbcdfj–“•‹’”“›˜œ––› œŸ• Ÿ¦¥¤¥¦žœŸ¤Ÿª¯¦Ÿ¢£¶¨ ¡¢¨³¡¥§¤¯¥°¬«´ž •”©¡¡”¬±°ž¢£ž˜›“‹¡”‘“—˜’——˜–¦›¦¡¢™¤¤¤«£¥°§¥£««­¥¨®®®«¨©©³¥¦«¯´±®»µ°¯®Ÿ’yvrea\Z]XNLQGRaMVPOJMOEBD?9=69:764599;9887<89=>;>;<69:7;6;7;;:85:;:;;6<;8846863321./2556;:8;7876<;:;;A8x»»±µ½°»²·¬ž¤¦­·»¼Áź±¹¶ÅÊËÁÄÇÇɸÈƵÅÂÈ®º¼Â¼ÂÀÁ½¼·º¶¦§²µž¢Š˜‡€wodbgihfhjgjm`]\[ZZYZ\]\[\^_\ZY[YYY[WUXWTTWUSTRU``_`a_`acdi”“‰‘Ž“’“œ”•–£™ –œ ¥¡­¥££¢£¡›ªª¥™ž¥±©  ¤ª§¡¬¬©¨­­¢¡¢”—¢šœ«©°›Ÿ¢Ÿž—˜“Šž’’’•˜˜“›¡¢œ¤ ¡• ¡£¤š£«¥¢¤ª£«®¥­±©¦¥¦¦µ¦©¨­³µ´¹º¯©¬ž‹rpo`[WVUQFQOHZ\ORJTKSLEGIC8;;=<8666:9;::76977:;:=<=6;<8>598:88659:;<97?<9678452121..1426:869869898:;9@9{µ´­´»²°¬²­§§¯¹¹³¿Èº¶À¯ÆÉμÂËÍÉ·ËÀ´ÀÇÌ°¶½Ç»ÁÇý¿·ºµ¤ª¯®™‡Žƒ|uijjmhjlnkkme]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURSOQY]\]^____bdmŽ„‘†‘Ž™“”’œš¢œ› §¨ª§ª¥¨¤¢˜¤®¤”™¥¯©Ÿ›˜š ž®™›©²Ÿ¤¦Ÿ£¤ ”“›–•‘©©­šœ ¡ š”Œ™Ž‹Œ’Œ–”¡ ¢œ›¢•› ¢ —¡¨£¢¨« «¯¤­·¥¢£¢¬­©¨«¯³¸²½µ³«¯˜ƒrrh[YYSUREYLQ\YMTNPLQRINIB<??A?=65799<<987:79:;<=>;7;;:=67:;8976989:6:=99577571141-+/434988::8::748=8?9~³®¨³¶®¨§¯­›©¨¬·¶¬»Ê»¶¿¬ÌÇƹÂÏÐɵƾº¾Æ̵±½Ä¼ÂÅýÁ³¹¯¥ª¯«ž—†wxoninnnqggigd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUTSNPQYZZZ]\\^_`d~‹‹Š’—‘–™¢ ›Ÿª©¦­ª¦¯¢§™Ÿ¬ ”•¤¨§—Ž™®–—¦©˜žœ“¥¡ž‘’’’•§ª¤™™š–ŽŒ‹”†ˆƒŠ‘”  £—•Ÿ•š ¡’›¥¥§¨¨ ±°¦±¼¦Ÿ£¬´«­§°´°¹µ¿±­±«|prbVTUNRIGVQRRLLXMJLNRGMKACFDC>@75889;9:7::7<=:;@>:9;9:?759::876958779;85576661320-*.102877;99;8948;8@8³­¦±·ª¥¢°«ª§©²°¤¶Æ´¹º³Ëƺ¼ÃËÑ̳¹º¾ÀÅǶ´·¼²º»Ä¾Â±³­°®°¬œ¢ˆkhmoroqkpkdfge^ZYZYZZZ[ZZZ\\]\ZXXXYYWXWUUTRSUSVURNNNRWXYYYY\\]aj€zv‰‡‰˜‰”“˜š˜¨›Ÿª¤¤ªœ§™ ¥›’ž¢š—–„ƒ‘š£“¢œ••–‡¢šš“‹ŽŠ™£§œ••—›’‡”ŽŒ‹€Š‘’‘ ™Ÿ¡•“˜˜”¡¤˜Œ™¤¦¨¦¡ ´²§²· œ¢·¬ª­¤²²¦µ¼µ««±£ˆxrm]NPQLOCNNNPLFNNKJNNQHMJAGKHHC=858889:;69:68;99><8:>9;?8789:886857688974577820301+)-/12776:999984988A7w¶§¤¶°¤§£©¥ ©¥¤³ª¢²Ãµµ²³ÇǸ»ÄÊÍǵ¯¼¿¸¼Ä³³®¶¢¬µÄº»¯ª¬´¯¯ —¨}^`gsqvqjnifhhj_XYXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQNMKLSWWVXXYX[]aosvp„ˆ‚‡€‘ƒŽŠ”“ Žš›¢ £˜¤–¡›•Œ‡˜šŒs‚}Œ––…™“Žz™œŒ‚‰‰˜Ÿ¢ž“˜–„Ž‚“~~t‰Žz†’œš™™•¢¢‰š ¡¤£›¢´¯¬¯¬Ÿ˜¥¹¦¥°¡±®œ°»ª©¯ª™vrbVLQOPMCSNLQMCPPHHMSMHJJDJLEJJ<749888;;69;7:<9::;79?9>@79:<89764445874312585/0102)(,-12764789::65:87A7w·¢£´¨¥¥¨£¦¥¦¥¦³§¥´Á¸°´°ÊƹºÂÏÇ¿µ¯½Ã¯±Ç²­§¬•£­¿¸±° ¨­¬ª–•¢rWV`hgihincjhgb\XXXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTQMMJHNSSSTUUWY[]ilrl…|tNXr‚—†œ—Š“ž—œ•”–”Ž–ˆ“‰_;Wo{Š“‰‹‘Œ…†rŠ„–y‚z…“”ƒ•Ž‚†}’xqo…~‰€—™˜“Šˆœ‡ž—†‡–žš¡ —§¯¨­©¨ž–­´¢¦­™¬«˜§³¡©­£’|qm_ZNSQVLDTJPMMFOOJELQMKOJIMOFIH=7599999:7:;:>>8:==6:?8>?589;79675333760.-/344110//()++-3854779<:79;86A9x· ¢­¡¦¦© §¨§¢©°¨§´Â¹±µ°Éù´¿ÏÀº±±¸Ä«®É®§¢…š¢º­§¨–¦¥£ —–iPNRVZZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MORMKHFHNQQMPRTVXZ`moiz‚tPB@•‘‘}‰”Œ„ŠšŒ–•Š’ˆ†•…xˆ`JQnxŠ‘„|„Œ‰„~n~”wuvx„™pQˆŠ†{~x”vgw…ˆ~Šˆ•Š‘–‹ƒ‰‡”„š‹„’›–žœ”¤£§©¥£ž›±«¡¤¤‘¦ª–¡©œ¢¦¨‡ske][HQQSMIUMSILLPIGFJNLMTKQQOFIC<769:8:;;8:;8>?99>=7;<6;;478;6775344696/3/.115221/,')+*,4833979:99::::?9v¶œ¢¦Ÿ¡®¡§¨¥¦§¯¬ª¶¼¶¸¶³Â¼·¨»É¹·©ª·¸­¶Àª¢›’‚™²Ÿ¢š –˜”‘‹ŒeMLNNOLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDDINOhYNQSTUZnƒtw~ji]U‰”‰t†{…Œ’€‘™‹{†uxsnupty}‰ª„yzhv{Žprmx€ŠŒ’xz€{€vrr’xgu„„„„z•‰ˆŠŒŠ€ƒŠŒ“ƒz€˜”›•‘Ÿ¨žŸŸ ©¥Ÿ˜¨¤“ Ÿ•žž¤qf`\\JVOQGKXROJMMSJJJLPHLQLRTMEHA<78;99>=:;<98@?::>=7==79937795675252572/2.,//200/-+(().1262198798775:<<7v®˜£¡˜œž³©¯©¥¬«°±ª½´²¼¸¶»µ³ ¸»³«Ÿ­«¬µ³¥ž–‘˜†”¤–Œƒ—‰‰††ƒfJIJIGFHHPTTTWWSTUUUVWWWXXXXXYXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQRSV^uƒ}ygw—˜Ž}gy€vx‰|„˜’r‡|v{ok~­|sŠ{†’€}tfv|…lohs|‰Œ‡€lyq}pmurhq€}ŽpCŠ„‚ƒ„wwzŠ„}‹zt~Ž’˜Š’š›£—™šž¢–‹¥›—Ž–˜ŽumkeaYWXTQJSVTOPOQWKNKOOJQOIOOKFD<;79;::?=9<:99??;8<=7<9999266856633621224.,,-..-0-+*''*.1362/876966527995y¦—Ÿž– ¦°¬®«§©°¯±¬¼¸¬»¾¹´®©›±¨­œ—ž§¬§¤›“‡–}Ž•’•€|Šz…€eJGHFB@CDILLMQRPQSUTTUVWWWXXYYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNPQTX^eprmˆ§ªÀ~uyb{wo|yˆy|‹…omŒ‘xsxjj‚r–‘‹}–I’˜nhw~‚licly…’†ksl|nr{…imp~sˆƒ…z}~zvott…ywp|ŽŒŠ“ƒ–—˜š“–—™—ž—Œƒ‰Ÿ’Š’†–}lhmnmWUWTRQYOSUUTYVMNHNKNNKCINGE?:89;99:><9<;::=>:8:;9?868727575541442/024*+**-.+-*(*(',-1250,5567485HA895w™‘›™šž¤­¯¢­ª¨µ¯®¬´¿«¼Â¿¦£š•¥˜ŸŽ…Œ–¢¤››”–v‘}„‹|x~t}xuw|fOEGD@<>>AFGGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jrA™o;<95<€‚†_IMOORWZRY\`§ˆbšitze~omz‹ˆuˆ†tl™‘ts|jkŽLy„’‰„Žg1v†sl~}ƒtfet~„„…€filukp{gpp{n’Ž{s}}qpnum‚~wytjy‰‚ˆ‰ƒ–“’‹‘”•—Ž€yˆ—ˆ†‰†‡uiingcWQYWXY\NPVWZYOIIEJJHGBAFDCG=998;9:9<:9;:::@<9:<98>787715244533645031.**+*,,++)(+'),,226-+5775478iO8;5n’ˆ™‘š–¤¨­ž²ž¦º®«²°Â²»ÃǛ—”™‹Ž†z…‘š–’Ž’Šs‰„w‹ŒvwuxvoxsiUFID?<;9:?@ADDEGJLOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOPQVLAIQIb¯³ q|xm}lqƒ…yƒ††yr ”tx€su”‡5q¨Ž¡¡„¢„vp†{†{sŒ­ˆ€hfbimqmo‚uioXuoŽš‘vl{|mrnpzsumbv„†€…‘Š‹Š’‹‘Œ‹ƒvy‹€~ƒ€}Žxpnnj^Z[][YXa`SO\[YXLHJFJG?CABG>CD=;97=;:;;9:99;:?<88=:8;66651121353475531./,,+)*))***)(*)+/3DM2166643<vR7=7b’’ˆ–‘¤§ž¯•¥´¨­°®Á³ºÁƗŒ”‰}n‚‘“Š„‹‰ˆw„…n˜ŠŒy{{q{t|ko^JPG>@7458;;<=>@BEILLLMNPQRUUVWXYXVUTSPLE<5*K[@-gI94/>’ƒ©®_GLMNPL7CMRSDJ†v€||v~lw‡‡|}…‚Œ~v¢™y~†€„™…›œa†ªŸ‹‚zvˆ~‰‡ŽsŠ—ƒ{\dqtz{wŠmgiayo…‚znws„zqsywkni]w‡}‡|ˆ‡€‹“—ƒ†‡}q…€„|uw{|‡tmqrde^ZZ]S[g^XQVY]WGKKELG?F@DC>AA=;97<;;=<::99;;=>79>9986754244004645654-,)+('''&(())((+++/00Uq<23331E~W4=9\Œw‰”Œ‘Ÿ¦‘ ªŸ°©¯À±»Åº–‘”ˆz†vk€Œ’ƒ~‹…y„‚t¢…ƒsƒ}lylSXLAE311267688:<?BEGFGJKMOPQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMORLKT]YRJi„ˆ{‰y|r|‹z|ˆ†~—‡v¡™ˆ‡’”¥¬©H†­¯¯Š€€“Š‹„‘¨‡€˜˜Šœsl|†‡}Žhggx~m…†…q„…Gk€xqyvhmk_w}ƒˆˆ…Œz•žœŠ‹‰’€{u‹v|xmow~}qqpjZ\[ZccWgf\VPQXZQDLLGOIDFCCA@CA=978:::;;:888::?>6;>7595773344236656768;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|~Š…‡‘–˜’— ¬ §¹¯³½´—’‹˜‹}tqŠ“~ƒ”•}‡†¥‡‰€ƒˆ†y‰Š€u…y_cVLC60./23133668:=??BEGHJLNQTTUTTVUSQOGC?80,#‡[>?84.]–ps£UFIKMNPW`YpZ\^j“‡•€„‚…‘“~…‰‘€š–‚ ¡˜•›š¥­“™»±§»ÈħŠŒ¡¤Ž“‰€{rƒžŸ‘œ~v……‹‡ihoƒ€tŒ†„‹q†‚v‡€{v…}nvug”†‰‰ˆ‰ˆ¢«£–‰˜€{‚Š{zogkx}w|qic\YY\i]ag`ZOLNXSRIQKDNGCKDCADDA<:87=<:<:88778:==8<=68756623445576867<BB?<8:>CQ^e\G2'&,,--.1(?Œ[.310Oƒ_4?;nvpgxƒ{€Œ€‘‹šš¤œ¡¬¦«¯°—’‘„¡”„xw€”}’†“–‹’›Ž„‚ŒŒ‚ŠŽ…€Š€mpj^CA4--////02234779;=?BDHJOQRSRSSTRPOHDB<87/9C><<63.l“—MPHJKLKNV`cggmu›š““‹Žšˆ“‹ ¡’£©¥£¬“¨¶¢§Á®ȯxº”š|Œ¡ž™„’„‚¡ž“™’„Š…˜–lpu‰‹•Œv„ql…Š—’ƒ…ˆr‰¡—‡“Š—¥¶©›–¢ƒ‡“…~€kjk}~}q_[b^Yfj\ll_XKHOSQNNLFIQDDNFBCEGB>:97=<:;:987767;:6=:785456345566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<unhYpƒpu‡qv‘†~—–š”ŸŸ›§ ª–“˜žhf¤š}…“’z’‰’’}‹…™’‘ƒ€‹Ž‰†’ˆ„‰…xxhNR>//.,/.-/000212457;?CFNPRTPQQSQNPIEE>;<:CF?><752<?R5HHHLLMNR^oŠ|s} ›§¦¢™¡—¢•œŸ¨ž©«Ÿ¨¬©ªµ—«¾«¶ÈÉ·ÈÑϾ› piª¨Ÿ„“‘…œ šš™§‘‘ˆ•¡™šwz~”˜‘¡’–—”ž{v•’«³‰— }•žœŽ“–š¤£§¶°ž‘š¨ˆ—Ž‚‰lss{|ynf^[__agc`gg]REKKQOJJMFFMCHMFFCBGDA:85<<899975658>75=84745754546958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f3A@ib_Pqu`n}awŽ}|”ŽŽŠŸ’—ž•œª˜žªBD}‡‰ˆ˜y‚‹Ž|Š†‘‚ƒ‰ŒŠ…“…‚†‰€‡w_bP460-1/,.00./..0015>AAMQRSPRTUSNSLEE@<>=FH@A@8662<9;FHGIJNOQYm†w•‹£§ªµ½¸¥®¬¬¨©µ¬±·²²­»±³¾œ³Ã¬»É˸ÿ·¥£°²¬¬ª£Š–˜…¥¦ ¢˜‚¦™¢ª§¤‡…“£  ª¡¤©Žœ°‹•¤§¸»œ¡£°“££ž‘¤¢¬°­³¶£•¦«‰šŠ“‹•z{~ƒ{e^fZc`]bc^fg`[ODIHTOFHLFKGFGHAKFCFFA;87=<88:974658<54<76:54644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLicWjpXz…v‚“…ˆ‚œƒ’‘Œ’Úȝ–sV—ˆˆœ|†Œ‹Š{‰ƒ‡‘ƒ…Œ†…ˆ’†‚„‰†‡‡‡qna@E64<3/110-,+-1/-4?DANVQRSUUWUM\QGGD<>>FHCDA8;<5C;=FKIGHROPW“ „®£³ª²ÁÇÄ«³Å¶­´À³¸¾¶¿µÁ¶»»¤¸Æ©¶ÉǶ¾¹´¨£´­°°›™’šŸ‰§¯ª¤•wŸ¤—¡«±³˜–©­¨®µ»²º¬¯µ¢±¬²µ¼¸µ®µ §¨£¨›©°®³º¸¹¨œ¸ª¥’” †z€rW_bUd``a__f`\UJDELVRIJKEJHEA@@KDBMF<867;<97:986555711<8895466497>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AEWQJL\ZQcdWzuq”}„†“v†~€{¿»£¼‚´”“Ž›„ˆ“Š‰z‡Œ“ˆ…‚Ž€‰††ˆ…Š‡‘zyo]W@EN<6:46AB764//7CHCQ\OQUXU\WO_UIKJA@>GKFFD;>@7D7?BJJEGWTP^¤­¤²´Ã¶¸ÁÌÊ·¼Ä½³´Á·¸Âµ¿°¸t±´¦ºÅ¤°Æ¹±³²´¨¤¶¶ª° ¢–›¢’¥±­¥­¬§¤˜ ¬³º¢©²¹µ»¾Ì¿ÅŽ½³Â¸º¸¿¸»¸º­­±¦±ª®¾±½¼Ã홻©•®˜™«‰~€yhUa`WicieV[dZWUJGGLRHDIKAID>?BBL@@MD99669:?6:9966246/19599364627;=?6:1./57::650*(,---,,*((++(ES/*00Jk52P‡m6?FRLALRWTYVZwjp„Ž„o{rxˆb¹¡š£‰•”–“””Ž—’‡‡|‡Ž–Š„Šz|‹ˆ†|Š‚‹„•}xzufP\dGEL:Qd`[^SF?;HPE[cQQYYZgZS`aMSOEA?IJHEFA@C<D6B?HGKMTZT^”¯¸µ»¹ÉÀ»½Êͼ½Á¼¸¶¼»·¾µº²Æau²¥±šž«¾ª¥¨«ª¤¢³µ «§ž•–ž˜Ÿ®¥§§¥ž£”¢§°³§²²¼¶Á½ÓÉÉÓÆÂÅÌÂÊÃÁ¾¾¿¼¼¸µ°¹··ÃºÆ¾Äɱžº«¢¬¦©·Š€|o]^^\U`]hfSYbWSWIEFOK@>HD=KB=B@=F>;H@796379>489:57045/26389374526?8@>GKRTTRPPQRQJA9/,,,*+((,-+/P>(.48€}<2Kˆq9>CKE@JMPRLQ]hmlq†slrrsˆÕÀ¶š •™™‘Ž—’––Ž†ˆ}‡ƒ–Šƒ€‚y{‹„‡{‹yŠ‚—t}zlfpvY]\Peeb`ed][XX\NdmURmn_o_XgeUYTJDBKKHFHHHHBI9D@HKTTV]Z[“¹À¹¾¸ÆÁ»¹ÊË»¶º¶¸¹´¸µµ®··™du©ž­p^¢­œ˜¡¢›¤ž«¥”ŸŸ”Ž–˜˜¨ž¦ŸŸš™ƒ£¬¤ª°¬·°¼¸ÔÐÎÖÏÉÌÒÌÏÎÊÇÀÀÂʽÁ½ÁÁÅÄÆÊÀÉÏ´¤¼±µ°œ¬¹½š}wi[]YW[_XabQ\aTRLCBFHF<@F>BIB@D=:E>=J?47535;=468977022/24169775555D3ELM>510006:477@IOJ;.&**(-./,@M+/54m‰I0H‰t?>BD@CDGKODR\Zi`p—“‘”nlotu‡³¬¡¡Ÿ‹™œ™•‘›’…ŠŠ‰‡ŒŒ‰|ƒs{Šƒ…{ŠtŠ‡•t{ylmu|iseilhfjih`fiimZnt—­¤½ˆ‡g[oh]ZYTHKOPJKPLSQHLAJFKP__bgjb˜¸Ç°º´»¾¶±ÅǶ°¹±±»­³²¨¬¸­¶¨žœ§šNšžŒ –‘§˜¥•Š““ˆ‘‰‘’›¡˜›•–‡ž™¦š¬¯¨¯§³³ÔÔÔÖÑËÏÓÔÎÓÏÌÅÂÊпÊÉËÉÒÈÍÎÃÐÒ¸°Ä½Äº¦·»Å¢~laZZ[V^VYdZP]XORCBHFDJ;AD>BH?@B8;D>@I=56655;:687654/10146278875367C5B8?-0,1348=97,.,1;FL=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYSfWs‘™‚hrpyyƒ¡ªž¦—Œ››˜‹Ž•‘šŽ}‰‹†Ž‹‹‹ˆ|…‚p‡‚†{‡rƒ’Œ~qyulqxr{nxsli€pmcinpyix}~Ë¿Ãߧncxnd[a`KPRUNY^P]]MQNTQUT\nnwƒr—®¸¬µ¨°¶«­½Á²«µ¦¥¹§¬¯¢¬´¤±®›˜˜Œ‘”‘„›§’œ‰ƒ‹„Š‰„‹„”•——”›œ˜™™ž«¬¤§¢¬¬ÎÒÕÑÍËÒÓÓÐÔÑÎÈÃÔÑÈÎÒÓÓÖÍÒÑÅÒÖÆÁÏÈÈ鿸МvkbZ_[U^Q\ZPPUQOI>AGBCF=AB?FE>@?:==<<JA45465<888664412/03526768533;=<E=@11+/349?5901022-2EO3)/3.32=N248C}_2A†tD:==I>@CFH<VRMO[u‡†‹wlwp}~€ žž¡Œ™“”‹Œ“–…y…‘ŒŠˆ‘‡ƒ{r~€‚‡z…v…“‘‰€owsls}|w|s‚xqk€rriprzyr{¾Ë›²„vr…wiai]DZZ[WfdXekTX]]ac^cx{Œ‚™ª¤¤¢ ¡©¦ª±¹«¦´£¢®¢¤®£§² ‰¦›•“‘Š’ˆ‚”‰k•£™„†~‘ƒƒ”—­‹•Ž•šŽ…’—§¯¡  ¥¤¨ÈÍÏÇÂËÑÓÑÔÒÎÓÍÆÖÓÍÔØÖÖØÕ×ÕÊÕÚÍÊØÖÑË­ÄÃ̇ok`]\VRWR[PJHJJK@;:;EBD=CD>HC?CB;<9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/-.;R017/532ED28>nb5=tM99@I<AD?A;PLFKYq€v~isyr‚Š€•ž”…‹–‰Š‰Žˆ€x„”™‹‰ˆ‹‰„ys{}ƒ‡w€{‡‘—„oxqnvvx}t†|yl‡vun}v„uy|ž¶<A‹Æ¥~}jeWICecfchjdoy[_fhlninƒ‰’ŒžŸ ž‘—™ £¤¦²¤¥² ¢¥Ÿ¢©¢£²œ‡Ÿ’’“‘‹‹‡„„~œœŒ‚„…z”‚ª–£Œ’‹˜“‹}—Šš‘ª³˜šœ§œ¦½ÃŸ¶ÅÍÑÐÒÐËÒËÉÔÎÑÕÚ××ØÔÙØÍØÛÎÉÚÚÒÖ¿ÌÍ´tskaZWPSPXUEGKJFF>:7:@BC:GE@EDBDA;?;;7DC75655;0689443341014558754449@>DBC<33.6FTWOQJAJF?2*(.BT29254/7K75<`bA<svV87AH:?B><9QECJTlnopbqqt†}—‘ž‹‡’ƒ‰†…Š‚ˆ}x…——‰ƒ‡†‡{…yq{{„†v{†ŽŽžzp}ppz€r{r„‡€nŽzuw}}ƒu€}‡‰°tYªÂ·’pnc=^hrqqpnww‚fiorvyrz‹‡”’›– –ˆŒ“œŸ›Ÿ« ¡¬œ¢šš ¦Ÿ ¬šŒš‘“Ž…}ˆ‡ƒ…‹Ž ™”ˆƒ‡~l™z„™‡ˆ“ŒŽ•Œ†{›ˆ“®«“•—Ÿ˜¦®µ¼¨­½ÇËÈÉËËÏÉÄÒÊÔ×Ø×Ø×ÔÛ×ÓÚÛÖÐÚÚÒÖÉÕ̓uwfeXWNQR\GCFII?B>=8:>@<>I=@BAAEA>?:87DB755479.566435532323647553458EBDCEB56<FNSM[nfcnsk`V>,4LG865433BF4=W_hLux^8;?F<<A<:9D>CGRk_mdbflv€ˆq‘›€y€Ž~ƒ‚…„|}„˜Ž‡Œ†‡wƒyo{{‡‚tz’žŽ¡vvƒtu~t€„o‚o’…u}‚…zw‡|‰¸Æ¥Ãʸ‚–œxpfNec‚z‚w…¡‘‹yyw{„€|„vm”–•–˜‘ƒ‰—š——¦˜ —Ÿ““˜£ž›¬–‘‘‹“ƒŒ…‰‰†‘žœšˆ…Œ†—{ˆ‰Ÿ—‰Ž‹‹‚| ˆŠ¼ ˜“—šœ¨¦¥­ž§µ¿¿¿¸ÇÉÍÎÅÍÉÑÕÕÔÙÕ×ÛÔ×ÙÚÛ×ÛÚÙØÎÛƃvvdfa]RUUTMKDND;===9:<?9>A7>?@=?>=9867CA6455=80665547745613854564557HH=DJE7925;H>;9;7IP\ZRUXK9T>;95327I8=NYMHxxd5=>C=<@:6:>>@EQ_Yfa]\itzyl‰’wvzŠ|~€€~†{~‚‘Š…†z…ˆ|v~un}}‡~t’ž‘ ƒ’|†~x~y‹Šoƒ›t™‡~‚Š…|~‘{©Ã ½Œ›¤œ~Š…}‰sŒ‹€s¦šœ˜”…{‘‰„iGp¡¤žŒŒ‘’…ˆ‹‘“•›“”‘—Œ–Ÿ”¡•“ŽŽ‘Œ~Ž‹„‰’–™ŸŸˆŒ”‘‘ƒŒ¦™ˆ…Žƒ†„€¤…Š‹·—‘”–¡¦ £®¶¹´«ÀÆÊÐÈÇÌÏÓÒÒØÒÕ×À×ØÙÛØÚÚÙÙ×Û·uutgfbT]YRONHDLC>=?99;:::<>6A>?==9:;;37D@8378>70688357<37804976755546FP5DNI8938AK=;3C@I<:DWN<MTHN?96333>C;[X>5YypZ<<A<=>8589?=DRSRX^VXfmmmiŽŠqsxŠ{{€||ˆ{}|‹‡‚~uƒ†zsztm~„~w…›¡›ž”“€Œˆ˜‡€œ’nˆ©…{¡Œ}‘Žƒ‰…›‘Š£¢Ÿ‘¤¯ ‹‘‹…‹“†Wr­‹Ÿ«œƒ™œŽ[‚¢‘‚Ÿ“•Œ‡ˆŒ’’Œ”••ŒŠˆ–œ–—’Œ“”†€Œ‰’ŽŠŠ—˜££†“• ‹Š‰Žœƒ‰€ƒ‡…¤„‹²˜œ’”—¡ ž™’›§²¸¬¥½ÂÇÍÈÆÏËÏÌÎ×ÏÑÔ®ÖÕØÚØÚÚ×ÖÙڝlyqccZZUQUWC@ID???:49:;7:<;4<<?=>7;::1:G=:27=@50677255?65;55858:57735HR7GOK994=EJB>1FCLB98:GX@5HWI66223:ECeX?&_yi_z>>9<;88;<@;BQKKSYPTcbymb~‘ƒonx‹yz{}‡||w†…€sp…‚{uwvt…‚„}’¦¢Ÿ¦¢—Š”—‹Š¨—rŠ³„¨’„™”…š£– ˜“‰›ž¢“©°Ÿ‘•‘ŽŽˆ–Œo·„šÄȲ¢¦œ˜–‘²d¤ÍǕŽ†‡‰’“•Š…ŠŠ†–šœ‘•“‡•˜„€Œ™ˆŽ«——¤£ˆ™ž•š‰‡˜—Š…‡¤ˆ“¨š—“–˜¡˜Ÿ™“œ›¢²´¥£½Á¾ÇÆÅÈÈÉÂÊÓÌÍÔ¨ÒÑÖÖÖØÚÔÓÚÎo{d`[[[LHTZBBHD<B>837<<:9>64::<:72?:929I:>67BC32:96264>=4;>6949;57944KQ<JQK9A7BGI@64JELF>;88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHSWSRBc‚GvŽ}|m~ˆy{~{‚‚ƒww€ƒ|mn‹{}xx|…‡Š~Š¢³§£ª³¢—§ ¥¤–•®¢ƒ‘¸•’³š¢¡Œ¥œ°£¤™‘§–¨™¬¯¤˜•–•‹˜š—¡ÀŽ£É¸«œ£¦®˜’›²…†¨¢œ˜…‰‰Ž•Œ‹“ˆ†‡‰“˜•ŒŒ”“‡”˜†„’œu‘™²–—¥¡‡œ™’‹‘Š—›‰‹—Ž†~Œ˜ž‰›šš“˜—Ÿ” ”ž› ±®¢¤¸¾´ÅÇĽÃÃÀÆÍÊÉÓ¦ÎÍÔÒÐÖØÓÐغovrY^S]UNGINEACE5?;77:?<<7=43669774>5;5<L<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=88467=:JFDGNZ\YJf`;I„‹zzn…†z}„x†~px}~}osz~‚|y†‹‰†„’¦»¬¨±½¯¥­³³©¤¢°¬Ššµ£¹¦•­¥–ª­¸§¤£ š©˜ª¤®°ªš™œ”–‘— ˜š»»®Ê¡j·¸«°•™ž£¬“—¾£^ª²ƒŠŠ”‡‘|ŽŽ}ƒ†Ž”•ˆˆ“–Œ•‹—˜“™´—•«Šœ”‘Ž‘’Œ™›‹“ž‹Š–Ÿ¡Œ”—™’›˜ž”¡ ”œ¥®¨¡¤´¸«ÂÈĵº½¼ÅÇÇÂÑ¡ÆÊÍÍÅ×ÖÑËԟmweYWQ\PNEC?=CBB8@885?G=<6<35345454B49:BM:B;AHC;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPdHb`bpI@‹Š~s†‡}‚ˆuƒŠ‚n}|}pw‡wŽ‚‡|Œ†Œ™©ÁÀ¯½Æ»³´À½µ­«³¶‹¨²®®¾«›»¥¨­¹¹«§¦¢¢¤£ª¯²±ªžœ¤™›˜˜Ÿ£¦¥’¤º¯©À¼­®²¹¥¤¨~ˆ‡œ­½°‚‹Œ‹ƒŽƒ‘zˆœ‰ˆ—Œ•—”‘š—¨›±š‘¬œŽš’Ž”–—‘ ‘‰•›£¬”–”œ’ ›˜Ÿ¡”šž¦¥¤¢£°²¦ÁÆï°º·ÅÄÿͦÇÄÇĽÖÑÍÅʅpo^YW\YLJBKAFH?A@C;:5>A>=5=7>333241A17@BN>G@CNCA=C=;86CC5BIB:878:5B>79VKDWOF8=4K@C>4EKHN>BA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUN79GD?CF\eF`igZ]]“ŒŒ‰{‡Œ‡ƒŒu‡‘Šo~{‚q~z•z’””˜“–§³ÆÉ¿ÁÌÂùǽ»¯«º»˜³·º²À®¥À¤«°»½ª®«££ž§«®µ°ªœ «œ¡œ–Ÿ°µ§Œ£»»¶Á¼¬©³¥¤¨”…ŽªÄ䂋‡ˆ„†•”zƒ‘‘¡ŒŒ”’Ž‰—Ÿ˜“™•—¦ ¯œŒ«œ–‘‘••Ž‘•’ ”‡—Ÿ¡³ž”™“Ÿ —¤žšŸ› ”˜ž¥£¦¦¤¯­¥ÀÄ¶Éþ¶Ï²Ä¿Ä¼³ÑÊÈ´quiYUYgQLHCMKLJAB>DE<5AE<;3=8B332263A05IEN>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBeZMe\eTbj™–ŠŒˆ“†‰y‡”r€{x‡‚‚y¡–¨™š™º½ÇÈÉÁÒÉÊÂͽ³­¼¾¨ºÀ½»Ä·¬Á©¬³¼¿ª°ª¤¥¤¬®³­¶µ¡ °Ÿ¥¢™£´½ªœ©½Â¤¶·¯¬”²¬¬¬—‡šª¦¥‘‚Œ“¥–ŠuŠ’y…Ž’ž ““‹”£™—œ•”£žªž‘¥šŒ•–ˆ|•“’£š• ¢œµ¥ž–¤£¡¥¥˜•—›¤£©§¢²¬¨»À拾·ÌÀ¹¯Ä³»¾Â¹­ÂÃÂÀ—iv^UTYXJJLIFDDIDCBDL:4DI:;4=8F.12242B26SHO<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQG7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>iH_XaZccVžŽ—Žž’‰ŠŠ “„x…•ˆŠ‘€–¡™®§¤˜Â½ÇÃÇÅÓÎÎÍ˼¸°º¼´½Ë»Ã¶·¼­³¿¹½®¯¨ ©¨¶®­©²·›Ÿ­¢§¡ž«·¸ª¥¯¿Å²½º³¨«¶´®®—–¥¬§Ÿ‘’²Å§–Ž|’•|‡’™ª™˜““’•“¥“™“¡£¢œ˜Ÿ˜‹ŒŽˆZ——’—¤™e˜¢Ÿ²¥•¡•ª«©¦šž¦—˜–˜” £¨¥ž¶«©¹»Ã´¥´¶ËÀ¸ª¶«²»¸®¨¸º½·hkWTRSMEJRMK?BHEEIHG96FM;>7>AK.32025C55OVN<LFKRLOHGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C>4FE:BABG9/:A3603>GD94=tdMG;E+:f|gV;>@BFBpEjIReaLF¥”œ—¢—©–Œ‘ƒˆ¦“ˆ‚‡‚œ„ƒ•”š¢ž¯¾¯¡Æ¼ÄÄÆÆÎÎÎÒÊ¿»¶²»»»¾ÏµÄ¾¹¹·³±µ³¸³«§œ«¬¹ª¨§¯°˜¤¯¤§¤¥µÀ±¬¬´¿ÃºÀº´¨º¶¹´¯–¥­¯®¤‹“”¡tš}—š„Ž—™Œ±•›š•’’™™¥£• š–š©›  ™Š•œ`J–œš”š¥–T–¯Ÿ¯œž£”®­ª¤™ ¥““˜˜›Ÿ§¢™´¨ª³»»»ª°²ÈÀ¹¦¬«­²²£¡²²´¤mkcYWMOJDOPPR;HKIHJCD>:KU?A:=EM07544:B44MWO;JKOUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@BAF3>58JKCA=C;5EA:A?>H@5*B52,>c]g:35tde@R7&#3}hW;:BC@=QEWSsbWFHª—™ ¢¨¯™‘—‡‹¨–Žˆ“… ‡„— š£¤µÉµ©Å¹ÂÄÈÊÉÈÌÍÇ¿»³®¹¹ÁÁ̵Ⱥ¹µº°¯¯³µ¦£›ª´µª©¦­¬š¥®¥¤¨¬º¿¨¬¶¸¿ÂÀ¾¹³³Å²¹¾­¤¯µ¬¹¦ˆ›—¦›v¿Ÿ„™žŽ“ššŒ®—¡œ›—”šŸ¡©ž¨Ÿ™šªš¡§ž˜‘ƒnv’¢š•¢‘®²£«”§©—ª¬£¢ž¤§’‘™œ‡”œ¢–±¦©«¹¶½²²®¾¹· £§¨¥¦œ›­©©‹_b^]OJKFGMJVM=NFOKMBDD<QV=AABDO18=76?B75UXO?HNQYSPQUKQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW;:=.-R`MUH~e^HE«•›¢Ÿ»¯™” Œ“«›‘’“‰«†¡žŒ£¬”£¤¶Æ¾´À¹ÂÂÇÉÅÂÍȾ¹²¯ºµÁÂʵƲ¼µºª¨­­°¢£˜ª´»¦©¦«ª©¯§£ª«½»¨­½µ¸¾Ç¼·¶¹Â²¿Áµª¶·¬¾¥£˜’¢ ½Ÿ‰š¡™—Ÿž·Ÿ©œ¦¢›œ¡š¨¤³ ›¦œ¨ªž˜•”›‹–‰Œ¤¡”¢ ´¯¥¥’¯ª™ª©œœ¢¢¨””Ÿ‚žž›•©¤¡¡³´º´­¨¶²³ž£¥›—”˜ª¡žu\Z]\HGEFLPINEGHCSLJBEGAWSCH=AGQ1;B7:BF79\YKALPTUSMWRNUJE@JJNO9D@5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</';*H‘B:SJ0,[oW71<*B€dT49-19f\FCCpbGE§—¤ŸžÃ­œ—¥˜šªœ–ššª–•§¦•­¬™¢«¶Äü¾¶ÁÂÀÇÄ¿ÌÅ»½¹²°¹³¿Âǵ¿°¼·¹¶¦¤««­ ¡™ªªÄ¢¤©«¦ž¬¯«¢©©¾·§­¿²¹·Ç¶µ¹¹À³Àø¶³´°½£—£—”œ”® ¢£¥££ ½¥©©«œœ¡›¥ž½¢™£Ÿ¢©¬¡—Ž–ž“ž‡„“Ÿ¤ žµ¬¦œ•°¦™®¥œ™¨œŸŒ˜”žƒŽ ™›’¥¤š˜«±µ±ª¥ª®¬›˜  ’Ž•¨ž”e_W_[MHGINLHFDIA>QIA<GII\ROK=IOU5BF9>HG5Ca[KBNRUWVQXTRUI@8RQPM:GA4CHQSIC;C>GVKC@O>K<06;GF>;FA55?9:?9;15D0-,/Mv\4KZ5,MnW<-=)#zbQ5CKQ9mQF<KxeaVK¢š£œžÅ¬¡Ÿ¬Ÿž® ’£Ÿ–¤ ¦©¬˜¶±£ª³¶ÅĽ¿µÀ»È¾ÉǶ¸µ´±³´·ÁŶ¾±¸µ¹´Ÿ¦¬ª¬žž¥¤Á¥Ÿ©­ ¤©­¯¢¦¨¼µ¦±½¹·¶Ä²´¸»À´Å¹¹¯³µµ£¥•’”¡® ™¢ž©¨¬£šÂ¬©ž¬®››ž™¦ ½¡¤˜««¬¦¡ššŸ’ž‰ŽW–Ÿ¥¡ ¸ª¦“˜´¢ž°Ÿ™®•˜“œŽŸ—•¡£–¥­±«©¢¢¥¥••˜‹Ž‘’¤žˆ^aXb_KGJJNFEAGK?=JB99JKN]QQI=LW\9FI=DMI8Hb\LCLPSYYVWOZ^IA=WQJL?H?5HLXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+w`S6S[kWqGE6=ue\KMžž¡™ŸÄ¨¦¡´¢³¨“«¥ £Ÿ¬©¬»°¨¬¶±ÇÅÁ²ÃýÆüÄɼ¯°¶­°µ¯¾Ä´¹²°º´¬™¨±©ªš¥¡§Á­›¬±›ª£®°©¤¨¼¶§·»¾°·Ä­³³ÃÀ´È´¼¸¬´¶­ª¢¦–••¤¬¢Ÿ ›§«°¯¯»±¦ ©¨š™˜“¢£¸ ¡£’°°¬¥¦Ÿ“¢ž•ž•ž›¢ž§´§¦Œ—²›¢­™œš¬“•’™‘ •ŽŸ ”‹¥«¯¥¦¢œ ž‘’š“…Š‘›~_dYfdIHLISAC@IH;;F?99ONV^RSJ?P^]=HPBLLI9Nc\LELRTY[SUO\bHA?ZQAHAKB7FELKM?;BHDNB=;N@A3/97CB97F;+6<46<25-/4@1+'VtSeO?104b[M23>0<v]^?[T]ep@8;H–weA4ž£Ÿœ Ã©¤ª³¢¤µª–³¬§¡¤²¬®©»²­±µ´ÆÀÄ´ÀľÉĵ¿ÇÁ´«µ¨°¹¬¿Ã³¸¯­¶¹¥˜ª²««˜Ÿ¦—­»´›¨°š¬ ­´²§«¹²¨º´¹³¹Àª·²Ä¾¶Ç¨À¯®·µ©§¬¡˜—’¦¥¢¢˜™¥¯¸®²µ¶ Ÿ©¤š”–”¤ ·¢¥¥–°²²§«¦¢Ÿšš›•—¨Ÿ ˜¡ž¯²¢¦–­˜¤ª–—¢šŒ’–˜…•ž“‹›“Š¨¨ª¢¦¡˜ž•‹Ž™…”ˆ“žwag[jiLOMNT=CANC::I?77RO]^RVQAW`\BJSHVKH:Ud\NFON[W[RPQX]GAB[PBG>NC9HGHOP??CIBLB<2IA94177B>;7E7+6914801-/.<6-#Bqgsk23/1[bZ33806p[bH04IogUCWFŒyfC;££¡¦¿§¨¯±¢ªµ«žº±¬£«´¶±°¹·°·¸¸Å½Ãǽ½ÄÂÆÀ¸ÀÅÀ¹©¶¤¬»­ÀÁ··ª­²º¢”­±­²–¤§‘ª¹ªŸ¦°œ« ¯´³«©µ¶­¼­´³¹·¬¸±Ã»ÀÀ§Ä«±·¯©««§ž˜™«¡¢¡‘˜¡±¯³¬°¹š›©Ÿš—“˜§ ·©¦£¢±±´¬³¨­ œ  ›ž¥œ¢—£³¯›Ÿ“¤™Ÿ§™“¡“—ˆ“–’•–œ’ˆš˜”Ž¨¨¦Ÿ¢œ—›’…Ž™‹}‹•„™hfk`lmWPQ[UABET@;;IA7:XPd^PWWEY_^NMRN^KJ>Yc^NHPO\UYPKTWZI?DXPDF?N@=IGGQPB=DEBM?:1D?77547?=95E4+75/251--.,1=*'+=\p=>1.0dZd@1647gY`F(?8l}g[V;‰{cC=§Ÿ¢ª½¢ª°¬¤²¹ª¦¶µ¬¡­µ½¯³¸»º¾··À¿ÉĹÄÃÀ¿·Ã¼À¶®µ§«·±»½¾´©®±¶ž–«®§®—¦¨Ž§»Ÿ¤¬³ž«¢±°³¬©µ´µ½®±²µ¬°´³Á»Æ·¬½°±¸¬­ª£²¦ž¥ª ¤—šŸ³ª³««³š§œ›–Ž¡¦¥´®¨¡­®®±¨´­²ª¤œŸ¨¤ž•¢™›¨µ©—™‘‘™Ÿªœ•—„”–Š˜›“Š––š–¦¥£ –•—“”…{’‚‹”djqfoq^FYgVDCMWDZ9HB6>]Qh\NZ]G[^^ONRXdJJB\b_PLMOXWXPJVVWL=EUJEDAM@AFHHQPA;GDFK=87B=68719><65D0+80/05/*,/-*=,,%2+*5K1/'__`U150=`V^8*C3YU\gK6ŒzfL@¤š¡¥­·¥¬ª¦¯®·ª¯¶¼¨§±·Æ·±¶½ÁõµºÄ¾ÌƹÃÀ¹¾¹Ã·À¸²´¬©º¶º¹¾´©­°µ—˜§¬©¬›««Ž«¾«­±£« ±­³®­µ²¸¸ª®¯±¨µ¯µ»¼Ê³ª·¶±´¯®¦¡´ ›©­ ¦––›š²£®¡¦¯—¡¤šš“Ž£¦¨³ª¢§³­«¶¥¯±µ¯£™¬§š—Ÿ›™«·¢—“Ž˜œ¡—–“ªš’‘—Œ›˜–Š”’ž™¤¢¢ ˜–’“•z‹…{ŒŠ‚Š‘jmwlt{aFakYIGZZ={JFD6AbTi[M\bK\][RSRb`LKE_``QLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76((9.$:K5."U_T_/5(C_Q\.*A/JGP[G3cYUKD™—¡²©²ª¬¦¤¯®¶ª¸¶º¥¬´·Ê»´»º¿¿µ³·ÃÀÌȼüµ½¿¿·¾¼±¼­§º¹·µÂ¶ª­°·”–§®«©£°©”¯º¤¬±³§¨£²´±²°´±·³©¯¬²§·¯·´ÄÆ·©¶·¬±­©§£¶  ¨²¡¥•œš•²ž¨œ ªŽ©£ž›–˜¦¦¥¸¨£²µ¬¨²¨®±µ«¤™ «¨›œžœ”©¸œ”ŽŽŠ—›¢——¤Ÿ›”‚•œ›—–•ˆ–—š§œ¤ ‘–‘•v„‡{„ƒ‹Šlovt{~\Lfm\KNc\>b{GI8GgWf\L^cMYYWUXTi]OOH`]_PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANGe27'GbLV%-A.=ELQ<3rkICC‘™¥¯¥­¯«¨¥±³´«¸²¸¡¬µ¹É¹­Á»Â¸³±µÂÂÎÅ¿Á½³¼¿¾º¾¼²Ã¨©¹°µµ¿¼®«²±› §±­¦¦¯¥²µ­ª±±¬©¨µ»­´²´­³­ª¬¨¬©¸­²°ÈÁ¹¥º±©­­¥¨®±¦¥¤¯¤©œž›°š££££‘­Ÿ¤  ¢«¦§º¥¬¶¶¦«¬©­°µ®£ž£¨ª› ››’£³™‰†¡Ÿ”Œ”›ž‘‘ƒ’’œš—•”‡—’•™§œ žŒ“‘Žw}Ž…|{|…ˆˆprq}||\Sdo^NXf\FD–[G;NmXb\M`bNVWVWTXg]QRLcY[TKGOTSNGIVS\N;P^IBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/+1()+,-*&5*/&0)38:1&*3Bc:6*HeHJ+:G>3BHS,>k;GHœª¬¢ª±¤©¥´µ²µ¶²²¢¬®½Ìº­ÀºÇ±´­´ÁÃÑÅƾÀ²¾À»¾·»Ä§¬¶¬²·¼À¯«±¬Ÿ£§­©©¥°£ª²ª°«¯®°®«³¼§¶°²©²©«¥¥£­º­ª²Ãº¶­»©©¨¬©§±¥ª¥£¯ª¨¢Ÿœ£­•¥ž˜ž™¬¢§©¢­¦¤®¬¸³²¢ª£ «¯°¬Ÿ¦§©™¤™™Ÿ¦˜‡„Ž‰‹ ŽŠŒ•š„…”Ÿœ”—•†–”“—¤œœ‹’‘Ž‰~~‡…|v~…ƒ„rqp‡tl_ZanbQrp\K<…|F?XuXaZNd\NVVUWQ\a^SONgXVVKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*25>10485(5/*,.30;),,'%234$,2-860)(1;\J0.JgDF8<B/4EKX2@•Y=LE–˜­©¢«³œªª±·­¹·¯¬¦««½É¼°½¶Â¯±¬³ÃÃÎÏþ¿³ÀÁù¿³Ç믷­²¸¿¾±¬­«¤§ª°¨¨©±¥´®ª±®­±±´¬´¼¤·³¬¬®¨« £ž°·«ª­º·¥·¶¤ª§¬«ª­¡©§§²²¤§¦¡¡¬—ª¡•› ¦ž¥¢ª¤­£ §±¸®®¤¦£›ª¬­©œ¡¤£¤˜ ›–—œ“‚ƒˆ…› ‹ŠŽ‹—Ž‰‚‹—£››Œ“’‘“£š›šŠ‹‹|†ƒzs‚|ru‹¤‡xk_`meWd†cN?g“LEbyWbYReUNVUVTO\]aUKNhVUVIJHIOBGISQYoANX@:JGFEG>>EQH8CKE87C72:::*39?./463)4+*,+.#4.-+&(+79*&6+<-2,&06VZ.0JgAA<<B+:JO^4D‡=GFD—“°¦£«±˜«ª®¶¬·³¬¦¬ª©¼ÀÀ·¸²¼µ¦²°ÃÉËÑ¿Àº¸¿¾Á¹Á¹ÀĬ±´±³ºÀ¾²°®¬««¨¶ª§®¯ª¹°¨²±®²­·ª¸¸¦´¶«¬¤©ª¤ž³³©¨¤´´ ·® ª¨ª¨«§ «¬©º¶ª«ªª¢ª ­›’ª¡ ¥¢¦£ªŸ¨µ¯©¦«£¤™¥¨§©›¢££Ÿ™™ ˜~‡Œ‡ƒ†ƒ‰‰ŒŽ‹‚…•¢šš’‘“Ÿ—™–Œ‹ƒu‡€xt‚~xv}€‡oqgfow\`r‡jO^™VHnyUeWQcPMVTUPOXZbUHOiTVSGOXUI>IHOQPxLNW=<KD?@A<@CUC9AK=5;E13;:7*4:=+-341*8**+*,))(/*&)%3;,$2)2021%/1Pb02?f=NX>C,>LT_0Ji5OD<—±¢¦¬¯š¬¦­°´µ°¬¦°ª©º¾»À°­¹®¡¶°ÉÇÈÑÀ¾¼º»Á½ºÂ¿¾¿­±±±µ¼»Á±±³ª³©¤´©¦®³³¹±£®¸²°³»¬»°©­¶¬ªžª«Ÿ£ ¶®©¡Ÿ°³¢¶ªž¨§ª£ª¡¢­­¨½¯¬®­¢¨¨ ¬™°¡˜¢¡§¨Ÿ¨›š«±ª£ ®¢¡”¢¤£§˜š¨¥˜—˜žŠ‡”ˆ}†„„£–„Š…Ž‹ƒƒ“Ÿ–ˆ‘œ“‘œ”—Š††xt‚|uxyyrrxf†¤vi_di€tfˆ‹|RXp_JxsSdTQ_MMSZfNLVYdXGRhRQ?BNQaQ:IHLSIqQLS;<I?;<=;@@W<<?H73CB15:93-5::)-31--5)(+-,42#2)',%.;.&1.0-14%,0Kg:48_=ad?F1CP[[*HL9U@4’³¡¥§­¤§¤­§µ³²«¥±§ª¸¾À»¯§¹ª¦¯±ÉÇÈÑü¿¾¸½¾¼ÈºÀ·¯¯³±¹»¸À³²º¬¸¬¢´§¨­³·º³¨¨¾¶¯·¾°¿§­¬µ«­œ©¯£ ¥­¬¨œž«³¥´¨šª§©£¨£©¨©¾«´°®ª¤¡¯œ›³£–¤œ¥¦ ¥››ª¬¦ œ«¢œ“œ¢¦˜—¨©’˜š”Š‚…~ƒ€ˆ…~}‹‡ƒ“š“…“¡Œ”‘‹‘›’•‡‰€r{z~|ix|ysno{f„w…Šdag_r„zlfx]^T?W{lTaPQYLLNru]HZ[gYEUeOC>JNDCA9HGKS?jaIQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11'/>KH0%90%,,09/,,+6'17#-0GjI14X=fbAJ7GS`U*=9CV=*•²š ¡ª¦¥¢«¥¸³´¦ª±¦¬¸Á½µ¯¢¹­¨¨°ÂÊÉÌÁ¶½À´·¿ºÈ´Â´²±´±¼¸¹½µ­¸µ¾¬¡³§«¬±¶¸µ¬Ÿ¿½ª³Â´½¡¯²µª¬Ÿ­°£œ¦©ª¤ž›¥±§° Ÿ«©§¡©œ¥©¡­¼¨®±®¡«£¤¯ŸŸ­¦˜Ÿ›¡¤ ›¤«£››¥¥–—• £—›–¥¬Œž‘‘‘‹‚Š€€Ž{™”Œˆ{~‹†‹‰„’˜†”£‰“’‡‘š‘“€‰}yl~vyxc|zpnoqvgrj„geg]lsl`hp`o=[xlU]NPRKJMTZWM\^lWDW_O^OHMDF;7HEKO<rhKK9AE;;=>;;=J49B<3;G<4?18-68;2(09/,4/.=-*K>)49&'.34.0+/4&,:$41AhY14S=e_DL6KVdO*;1NW=#”š­š ˜¨¤¤ ¨¤¸°¯¤¯°©«¸Á¹²­Ÿ¹¯«¨´ºÈËȾ¶Â¾¯´½·Ä¶Â±­¸±³À´»½·¨¹·½ª£´¨©«²¯º±«œ½¾¦°Á¶·¢®¶µ§¦§°³ ž¥¦¨¢¥™Ÿ­¨ªž ª®¦ ¦˜¤© ±¹Ÿ£±¯¡¬¡­¥œ§§©šš›Ÿ¥–›Ÿ«§—¡ª“š”™Ÿ”™–¡©‘š‰Ž†|‡~‚}| Œˆx‚‹„‰‹‹…‡“šŽ‰•žˆ‘•‚‹—Ž‘}…|sp~rtt`zxhmoomh}qc{miea\d„~^YsjrIH~iXYMPLKHPRQIO\_nSDXZRgNGKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23.:;83&2<0,85B*)-B*,4;NN@;73-.+-7**<%53<fd24M?e]FO=QZgH*=/WT5(—Ÿ§š—®¡¡¡¥¡·«²¦´´ª¨¹Ä´²­ ·­®­°µÆÈÀ¶¾Á¹°´¼·¾»½¯ª½°´¿°½Ã¹©»º·§§µ©¨¬²­´±¨œ¿¸¦®½¸³Ÿ±·°©¥§¯±›¡¤¡¥¥ —›¯¦¡ž£¨¯¡Ÿ¡“¥¥£·°¡¦±«Ÿ¬£¯˜œª¥©Ÿ—šž¦”››ž¨¬šŸ¦——˜–žŽ“—¢¨¢‰‹†z„~„‹z—‰†x‡ƒ‡‹…“˜–™Š—~†—yzprwppt_ywdjkjgg‚lerjkdgWar^YkuiXE}^[XOOKHHRUG29^^mPDWUYeLHJEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<#8R=*113>D5,-'42+;+139cl84HBf[HTCT]hE.:1]Q,2—¤£˜–«ž¦¡£¡¸ª°¡»¸¥¬½Ä²¯®¢µ°¬­¯µÄĽ³¾º·°³¹¸º¸º®­¿³´¸¯¿Á¸«½º´¥¢³«©«´­®³¤žÄ·§ª¸·¬Ÿ²»ª§¥¨¯«™£§œ¤¦”˜¡²¥™ž¤©©œ¡Ÿ”¦ ¤¹¨¤§­¦ž¥¡¨“ ©¡¡¡™›ž¡“œ—¡£¬œœ›£–“––œŽ”“£§¤‰ŠŽ†y„|…†}‰Š†x€ƒ‡ˆˆ‘…”“’Œ‘•”Ž”{ƒ—‹w|musmmtbythfifcm„fghdfgh]dbieZezb`PrT[[RKJHIOS@ *i^jLCVU^`KHGEC.:B<F<6KPD8:D357==895?:;4>8@L=>93)8><:9*6@3.E4(+,>0-O?.+-7-1195,&.5-80576`tB3CDh[KWGU`hB377`L'2Ÿ¤¥“¦§œŸžž¤¶­¨ªº·§¬ÃÀ¶¯¬¢µ®§¯¯·ÁÀ½±Á·±®²¶µ¹¸µ¬ª¼³¯²±½À·®¼¼°¥Ÿ¶¬¦§µª«¯¡¡Å¬ª¨²µ­¬´¹¨ª«±¥˜ªŸ§¥’™¥­¢˜¤ª¡›¡œ˜¡ž§·¦¯ª­¡¡ž¢•¡¦Ÿ¢ ™œš”›ž•¦Ÿ®£™˜Ÿ–••™Œ˜š§ ‡ŠŠˆx…w‚‚‚‡Š‚ˆ{…ˆ†…„–•‘‘’{ƒ•…s~gyplklgusjafcasadefdhhaenY]X\lcaMgWZ`VIHIKMRX>9`liHBUS\ZIGFEA.<?9A89RG@7:B037=7693:<97:9DM=B<0*<@;A<-5B37=++,/A*JK./*+3722(57$+7.72685\yN2>HiZLZJVbfA:3@aE%5¥¡’®¡š™ —¥´²£²¾·¡±Å»¹°±£·««®©¹¾½»­À²®¯®¶¯³¹²§«¹°¯®´¶»¶¯¹¾­¦žµ« ¡²¦«° ¦Å¡³¦°²±·­´¬¯¬®¢™¨«¦Ÿ•›§¦ ™¥£©šŸ›•­±¦º¨®¢¡š›ž™Ÿ¤š¥—Ÿ˜›–š¡”ª—­©œ•ž”•šŽ•”˜§§ŒŠ‰Ž{t‚‚‹˜…†|ˆˆ„…ŠŒˆ“…”œ“’‘—Žƒo‚gyniljgqrkZhcaq`dgjnkeiecl\lluqbSbiceZIGLMOYQPUaeT@VRZUFGFE@/<=7?6<FNa8:?249@37828?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24:5#3*)6.55465Z|]1:Lj[M[KXdc@A1G`A'4”£œ±œ•¡›©³°Ÿ¸À¶ ´Á»½¹±¦¶°©®¥¸º¸¸­»°­««·ªµ¹­¤³µ±¯©±¶¶±³¶»§© ¶ªžŸ«£ª®¬Ä™¯¦°±·¶¬«ž°­¯ª¢›¤­©›•§¤šª£¥–š œ’œ£¬«©»ž¦¤ —ššž¡k£–™qƒ˜¥€v’¬©Ÿ–—¢’Š˜™€—ŠŸŽx…’‚li~w„ql†Š†}„‹†o]dag„˜†l‹”’uy‹„ƒfˆhvjfX\itnMOibepƒf]dfnkh][\‰„ˆhOKD8FTg^JHQPUVKHRapteF[QUPFGFC>1;=6=6<4f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,,08>G701.*.*/668,#1'214:286Xl15Ok\N[K[fb>G1N_;+.¤›ˆ–±›”¡œª®¬£½Å¯©·Â¸¾¼­§·±¦«¤¸´³´°¹®©§¬´¦±µ¢§¸¶µ¨§­¶³®´®´¢ªŸ´«ž£¦§©œ°¿•¨§°µ¹­­£¨¬««¥¡Ÿœ¡¨¨›˜¢¦¦œœ§¨“žŸ™Ÿ¨«¤µ°£¢£œ–˜™˜£ˆ¡’š‡¡ˆ•Ÿ¢€¥€¨­Ÿ””ž”‰„rxŽƒˆ u‡Œi–ˆf~sx o‡‡„~Œ|¡  ™€|‡ŸtˆŽv›Šk‡‚ƒnied{mrbT†mdmi˜qXiom†W]hZkjZˆpkyr‡h‡„Y^FN>F^MFRVVQPRWTg^MZLRRPEFG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82*/1<I:/01.*/(-4583%&2115>1<8Xƒt15Rk[O[L[g_=K1T]7/(Ž§˜„ž¬ššŸ«ª¨ª¾Ã¯²¹¼·Á¿ª¤·±ª¬¦´µ®¯³·«©¥²­¥¶³›¬µ¶µ¥¦©³±­²¨¯žª¡²© ¥¥œ¢¥ž±¸•¦§§·½¦¬¦©©¬§¥¡Ÿ™¡¨¤š™§£¤˜œ¥ª—”¢œ”“¤¦§¡·¥£Ÿ£˜•”˜”ˆ®˜•ŠªŒ™¤†±¥®Ÿ•›¡—z‚Ô¨€‡”À›Æxw±¥·—d€Àœ¿y„„yƒ|‘Êq–¼œÅ{r¶§º{‚l—±«±yilX±®ofj¼“¼ngymqØ~Rkb¶²}~p•uš¡ªVNWaOVNGV\XPPS‹\W[PA\DPNCFI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22AE/.32.+/)-/186- /416A1=:Wƒw11Tk\O[M]g\>L1YZ41!§”¨ªŸ˜ž¥­²ª°Â½²µÀµ·¿Â«¦´®­©¨°µª°¶´¨¨¦¶¦¨¹®œ²²¶ª¥¤§²¯®±§«ž§¥²¥¢¢ ˜œ¢¡²¯–Ÿ¤¡µº£©¨ ¬­¤¢šš£© ˜›© Ÿ—ž¨¨‘§›”ž¢§£¡°£žŸ£–—“˜’™…¯kjŒŽªh…–‡­fqŸž•›©—q®¡¤wº|k v±_j´[¥€eœ`fzfixkªe¾sg¦Œv±j|±xu’”cmm§n\„ Eigˆ–Euœ_}f{£§‚Y_‹«h|Œw{j¨8J¯[XTlcZKOY`\VV;NˆPWV0ISSJCEF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3/.53/+/(.0.:6/'$203B/=;U‚v2-Vj\OYL_gY:N5]W31’£–ƒ­§¦Ÿ£¥«²¸­´½¾°·Å²¸ºÃ§©°¬°©ª±¯¤±»±¥¥¯³£ª¹©²²°£¤ ª­°¬¯§¨ ££±œ¤ž™—™žŸ°©˜œ¢ µ³¡ª›¡­­Ÿš—¡£©™ž¥ œ™¡§¤¢š—¡ ¬Ÿ¦¦ šŸ¡–•‘—‘›†µ›µy‡©š¶™xˆ´›·”—˜¬—k¦{…†‘”’w«gj±[¬{Ž‡”t‰pŽ†ˆ‘—xƒƒ‹—Œƒ …°vwŸrkkm|‹O¥XHdd™~ch¦_xqtR’†]P©ncpz…€a/S¢n[Tkg`LK]dX\ZB>°wWXA#MiEBDA@A19>88:84;:9<9:A:E::;6:CB8=?KNH:5:AFBAAD<FD;0201;E,0.940,.(/3,>831/2-D1<<S}n3+Xj\OXM_fW7J9`T50— •‰´¦§¡­©¨³¬ª»·Â°¼Ã­¹¶Â«­­¯¯¨¯³ª¢°¼«¢¨¶­£¬µ¤¥²³¨£¢¨«³©°¨¦Ÿ  °— ›—–—›¡±¥œ›¤¨¶¯¡¨Ž©§ª›–˜ ¦©›Ÿ¤ œ £¥£–›ž˜šž£«œ¦šœš¢ —“‘”“„Õ“™¹q±ÂƇ}֔œ»}œ—¨’¤{†¡€¥‚y«yV¯{‰~Ÿj¹Z¹w‡„}¦ƒ”|™{©yŽ{±mŽ„u¼†o•P¯§ÅŠQ zc`ªasr†k–‡^Rµ´È…~‰|c¤4Cu]PjhdP@XgYdaJHMjJZSOYfZCD?E?0<<59<74<<8=:<C:F:;>6:@C;6@OLH<:<DHCBCD<EF81211DB.00483+-).323971#%5*>3==Qwj6*Yi[J[P_fT7H:aP72%œ£“™²¨©¥³ª¥µ¨¤¼¸Á°ºÀ²·´½´¶¨²±¤²´§ ¯¶©›©»®£±²¡²´±¡¤žž¨ª±©´©¦žŸ¬˜™™˜˜—™¤®Ÿœ—¨­±©£žŽ«¢§•˜›¡§¡˜¢¢£¡›¢¢¨œž ž•™›§¡œ§•›šŸ¡˜’•ˆ²nhµr¬ˆp§r´vt¶{œš¦Ž£~ž£}°u‚ÒÒu\®|…¤n›ª¦k‡…}­}˜™{±s“y³e–t…žoŸf”RɋZÂ\Ÿyb_­_vs…a–ˆ]Yʝo¿~rMKµSUÆdUQjceXAOk_liPUFH9=WR[WXHB?J<2?;5=<56>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>II:1746@>/.24252-).26,742&60;5:=Pqh9'Wi\ANT_eP5G=aM62.£ž‘¦°­¥©»­¦µ¥§¶»¼³»¿¸¸µ¼¼´¦µµ£³²£ ¬°¥˜¨»®¥²±œ´¸ª ¥¡ª¥²¨¬ª¥š›©Ÿ––šš“•¥«¢˜“¦«±¦¡•’¬Ÿ¥’”¡œ¥§ •›¦§¢›£ ®š ž–›£Ÿ¦”•™£ž•™–’›…¬|x¨w£‹‡ªp­Œ…¨„š›£‹“›‹¢~‘—‡®„³\r²S¯}‚‚£~q×}w…~ž‡™šw¯†Š‘œˆw´aše›‚‚•l’[°WKšu˜yf`­^vv†g—ˆj]¯v•žwk5yÈ®³_CTo^g`EPl_pmVUM.echRYQ;AC@L:5?91><16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK97<46:>/04333.2..18*.32%!04767=Pke>&Vg\@=V_cN6GB`I:77 ”¡·±™³Á­¨²§ª³º·µ¹¿º¸³·¾¶¦¸µ¡¶®  ©¬Ÿ•©¶«©²²«­´¤›©  ¨¢µ§¦ª¤™ž•¥¡””š“—¥¨œ”§­°¥ ”™¨Ÿ¢‘¢š©¥¡•š¦©ž¤Ÿ­œ Ÿ”žœŸ¡™˜œ•–¢ ”˜‘§‡©~¦y¡„ªp­ƒ§†—¡£‹˜—ˆ£†”ªz‹yp±Z¨ƒ‚ˆ xtØv‡t¨‚›’¤|–Ÿ„{²^œd ~‚•n“]«\[“‘hgªcr{€j˜†q]«Z‰ kmdOJC¡\ZMt]bfMZa_rt_JU5Jš‘XHE=GEAL35A8.;>05A78@<6=<F?:<6?=B7.HVJE@H6KIN@IK@EN::@4.;>102154+*05/7,&21($%6671<OedA&Uf[?1T_bL7FH_C1=7¢šš¿­˜³Â®«¬¨§µ±¸±µ¿º»³²¸¼ª»¶¡²¥Ÿ¦¨¨Ÿ“¬±©°«·­ª¯¡˜¢ ¦¥¤º££¬¡—œ’£ –•Ÿ›•š¢¡‘ŽŒ©°°¦–š§¦Ÿ’¤˜§«¨–˜©¨Ÿ ¡¤®£ ž¡Ž•¡™  ’œ—›•ž¡––¬œ®nr´t©Œw‹¦t´zu´‚”§¤”‰¤‡Žu¸o‹{‹¢kk¶Z¡†e——h ¢§m”r´t“™³j†’ˆ­ju´af¢o‡’k˜]­`N¡|‡‘Rs£ly~n˜†o\¯V<œweTon.[§ObRkeblZb\`p|cSYQ>?lo2BB@>M:!7@6.;@37C58??3;<CDBJFMIF62JTKEBJ6IJP?HOCFP=<E50;;010/75,+,326/#00,,289/9N`eD'UdY>/U^aL5FM^81A8¥šœžº¤›±À®®««¨·ª¸¯µÁµ½²±»¸¬Â·ª¬¡§¤¢’¬«¨¶¤´¨®ª¡—¨ ¥«¸£­œ–™¦£—Žž¡œ™ŸŸ‘”•«¶°¦˜“›¬©–Œ”¦š¥­£’˜«³¤ ž¨¬°˜¡¢™¡— ›–›—¡“©”«™‡Ô”š»u±Ä€Ä‡~֗œ¸yŠ’™Ž˜ŠŒ§‡y¢¶u}wvÁƒš²aƒºyÀ|u¸bµŒ‡©}•‚¬©q{u¼ˆ§ ia¦¯¢~u‡«}¾ns¼t²ƒuxŠmšˆpm¤t½]w}[ay¼jZV[iy^iacfbmxoX[YCA@q?CG+4H"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,;:08LXaF'TcX</T^`K5<L\-6?9§šŸ¢¼£—°Ã¯­ªª­±¨¹¯·Å±»³¯¼°®Â²­¦£Ÿ¥¢œ‘«¥ª³¥µ§­¤ –š«™§­¹£®˜•¡‘¦ “Ž£ž™Ÿš–“¯¹±«•–£§¦”–¥¤­Ÿ‘¡¨¬ œŸ©¤²¢¤Ž¦¡•¡šœ—•¤™° ’•ªž…™¶€’’¸–yƒ“›¶wnlotoy„Ž‰ržÀ»¼š{²¨pt‘¹ƒ|††‹†{Š‡Œ—}¤»¹½œuy³£tu—ut°u™žf‡j¶tsqw¶Œ^€y}ˆgƒylzb‹¬pt…~W[§iDdYTf_c]cQgfqmuBMOLD;ZL>J2;0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITAKNGEOF?G<7>7070/9:.,/-*8/%&2(4$(>7/7KT_G'SbW8*O]]=+;VV'=:<¦¡¡¿¦•²Â³«ª¨­«ª»¯±Æ¯µ´°¹¨µ¹®«¤¢§Ÿ ™”­¥®«§¶¨¨Ÿœ–¡¤ž¬¥¾§¡ª—•œ‘¢›’¢¨¢”Ÿ—’˜”²µ¶¬—££¢‹’’¦œ¦«–©¥¦œ›¡ª¦¦¢¨¡‘¬ž—¢ž—–˜ž°©”œ§¢kjªz‰tœv{fˆ{½¾Àºo’ƒq”…_rjZ^›Šad‡–l`•cmœvb•l€™•”f^`cq›‰hrŒ|†”fj~qtx~c\xuhP\n„||ŠjWlz‚rIJo…pNqMDV\f`LZWfc_O[mujqRODDM<HH<L?1,2A?8/5?C<9;@;=C>RVVWYZ[[\]`aaa`\UG5CFUEKOHFPIIH;8=51:.1;:./-76=5&"/*2,%;8-7IR^I'S_V4)P^L(3>\O'?2>¨Ÿ©¢Á¤š³¹¶£¬¦¯¦¨¶²¬È¬°´­¶¤¾²³§¡¤ª£œšš¬§®¤¥¶ª¥›˜–¢œ§­©¾¨©¥•”›– š“™¦©¨’Ÿ˜œ°²¾«š¦§¢‰“‘©›©¤œœ¬ £š›£§¬¢Ÿ©¡™®›”¦ —”Ÿ˜±¥™¢¨™’Ÿ¤¦›¨¤›ž›œ›‘—‚ho~qw‘—”„‰´ª…˜•ŠŒ™—ˆ”•‰ƒ““‘‰Ž’”˜”™—šŸ¡š›”Ÿ›z¤…kj|‘}uŠ‹ƒr‚xzvv‹|‰jstƒudw}vkoxl_b[ogMXYfj_WYoynmfSOFS9PZNRO'*;KB635=@A9:C><ENSSTVWXZZ\]`bba_^^[TKCSGKNDGPLOI<:;489,2;820)6IRO8")+/2#4;*7FO[I'R^T10T^:+=8]K,<-@² ³¢¿¢£°±· ª¦³§¥°µªÉ«­²§¶¦Á¨µ¡Ÿ¥¦œ¥–•¡¬§­¤¤·¬ ™——¡˜­ª¦ÁŸ¬¤–’œ—Ÿ˜”•£ž£¨“˜¨¨²Â¯™ªœªž•–©žªœž¡­˜¡›¢¥¯¦¡£§ž¬˜–¥™š¡žž°¡¢§–™”š•¢¤˜¤ ™¢˜•‹‹Ž˜®|•œ‚‘‰©¨…€˜—‹„ ˆ{„‘……š‘‡†Š•›—Ž‘˜ž£–™’œ~e¡³®…Š„w{‹~xyzpgy‘ˆkuyˆrhsyuƒ†jtbxe_hdcdfjYk{pjj\SLPD_UF@>>,4@F;45;>A;<?>>HNNOPSTVVXZ\_aca_^^]^]XVJKLBIOMRJ;<:786/3964.(&$-1..)+*7%+<(6CMLD/T\Q05M[17E4\G5<,@²Ÿ¹¯¾­«­±² ª¦²­£¬³°Å°«®¤³¯¼¥µœ¡¨£¡ž™—©§ª¦¥¦³¶Ÿ••žšš°¦®¿¡¬¢‘‘žšš”’–¢—©„©«£´Ç³Ÿ©£ª–•—š§ž©œ ¥¬”ŸŸŸª®¨¤¢ª¡«šžŸ¡˜¥ŸœŸ°¤™Ÿ©”™™ž’¦œšªŸœ˜f…“}e›czmhjz£«ješ˜~g…‹eeihz¢ŽkhŒ˜‘¢wkj‹™£Ÿ˜slnz„Œ†yXe]†‚^l‹‹ƒw\htww’€‡ow‚xsmy„svˆ‡‚zh„X]jsd]s‰ij|rmc]QNVJdX@I3=F8?FD71<=?AC;;DGHHILNORRTW[^`aa`]]]]]_]ZUODHOKSN=>==6535554*&&%,*%.++'6*$;'/BI[J.6ZO6)EY/DO1YB;?.=¤žº¼¹¯«²°«¥¨­¯±§®®°½±ª©¥®°± ­—¡¤ž¢šš¦¬­¤¦¨ª³®ž–¤£°¦·¹¥®£š¢š“’› ™™¦–{¤«¢¨´Ã·¤¡¦®ž”ž£Ÿ¤¤ª©’Ÿ ž ª¯©©¢©ž¦›¥ž§ ¬—¢œ¥±¥˜¬–¢Ÿ›“§™¡¬š ½„‰s´s…Ÿ†­hw¹Ä¸q’¡£z¦™™t«‚}ËÀÀºq‹£‡ƒž}–˜ˆžÀ½‚–œÁÁ|z‘ŒšÂÀ}j¥²pŽ‚oÊz€›x’ƒŽ€vy€yq{€†px„Š’xlu‘be^wc_eb]thmdbXKUIQYHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^_`a_^^^^___^\SMPGUNA@?=6468266*&%#)*&.+*)109*#>I[L*#CP/#F[3PY/UAB;/8•¡¹Ã´¯¯¿©©”£°ª°¯®¦²µ¯«¦§¦±« «˜›£ œ›ª§£ž¬£¥©¥¥´¤ž£”¦®­¸´§¯¢’‘™¦“‘ ¢˜œ žˆ¦«¤«­¿¿° ¨®¨–‘Ÿ¢™£¤ª£“¡¡¬®¨ª¥£¢¤Ÿ£¤œ­©’¤›©®ªœž«®£—˜§˜£¤™žΔz{¥‚z–—›_­]Ž¨€¡¡|§•›u«ƒ¯^dŒª{¨‡… t—“ˆ³c‚«† ³j„¯t|–‡¸a‚­Y£Ín‘v{Û{™q~ˆ’ue{ˆvvl~‡m}„Ž}k€Œ_pjof`_xd[qhjcf`RTSW^JOC4AHED8>5;@?A;=8@>??BDDFIJLNPROS\___^]]_``_^^[WOUJ=?><5578164('$!',&&/(&+360$7;SL+,-J0';\:L-!P@F4.1¬ÁÀÀ´´°·˜ž‘¤ª©­µ«¦²¬¬¬¥¬¦°ª¡§œš¦˜œ¢¯Ÿ¡Ÿ¨§£¦¡Ÿ±¬œž•¦®­±«¨¬ ”’›Ÿ¥“Ÿ¥—¨¤ž­£ª°¨¿Å²§©±­–’žœ¢—¡ªªŸ•¡žœ­®¦©¨›¥¥¢ ª’¬³–¥¢«ªž¤¨§£²¢”›¨œ¡œ–•‘—¡r†Œ˜v†¨‡q°|q¬}  ‚¥žx«‚~­r­¬‡†Ÿv˜’{|—ªˆ¢Œ‘Œœ}«zˆ“Ÿz­VœÄ{p“Á}•mupŒmfwe‡naxnrn‡‰Ž‚lŽcnsuo`fmd_oijnfcXS\`ZRRC8IH@C<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;92478452&# 1' 1''45-&7=WJ-<(=1)3V@F!G;C1.+¯ÓÆDz³Ÿ£££¢®¯·¯©±§¨ª©®«¬§¢¤š£•Ÿ¦« ¢¦ ¨¨£Ÿž°­˜›–¨§¯­¨§©ž—•š¤¢’”¡®š§£®¬¢¬µ©¹Ì±¬¦­«–”œ¢™Ÿ®¬–¡™žž©±¨¨¨›ª¦£¡ªš¯±¢¨¬¯¦š§¬««³¤“™¥§œ–“…¤k¤uŠz©u{²q‚¥Š˜‹qˆ ›‡¤_aR«…€®ƒœu®‚¨††Ÿz™—†{f€£Š¤˜†‚£}©”†®^{¨U¢’‚{£Ÿ€|İŌs¯´³¹rb©¯Âth‹‹•€k–mlxwwnkfedqqf|ic]V_iXXTLLPLCCAB;C@@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^aa`_^]\][SIB6799664,&$" ''!+-"$.!3-&@DWH,G+56*1PKL# A9D4,'ÁÉÖÖÀ¡™«¨¡¯¢Ÿ±´°¯©¬£§§«««©¥¦ ›¥Ÿ¦§¦¤¬š¢¬¡¤ ¯£ž›“ª¤µ°¯¡©›œ–•§¤‘›¢¨ŸŸ¦œ°¥¢¨±¬¶Ç±´©«©•‘¡™ ¥³š¡”œž§ªª¢­šª¦ ¡©¢²¬¡ª³²¡œ«ª±±¹¦”˜¥©š“}ªmŸ„ˆv«y|°n‚¤‹ˆŸ–•ž–Ò¸´¸É‚²_`”©ƒ¥ˆ‡ z˜–šyªÉtš£”¨©’šŒ~š‰šÆÆwe¡‚¥t‚ Ž‚}¯_oµc±uK£‡m§Gƒ“dœzn”Ž|nyt|zm[fjrqgi^aXcm\^YILLJEDBB=A<A?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^_`^\\\\\XMB75785/)(%&%$&),5FNPPMFLJVF*L0/>-4OTQ;<F2-$§¤Àǹ­©²®­¥£œ³¹¬«¡¥›¨¦«¬©¦ ¦¥˜«£Ÿ¯¬¦¡­šŸ©¥§¶ £˜”¨«¶³¬œ¦œ –¦­’šœ§£ ª¦­ ¢¦©°³Á±²©¬§“‰—¥›¢¤¯¦—¢•˜œ¥¥©™®œ«¥¤«£¶¬¡±¹°žœ°¨µµ¶§–™ª¦œ¡ƒžNwš‚€Ÿ{„£|‚¤ƒ†¦ŸœŸ”„¸|}z¹ƒ€ÍÆöx›¢’‹Ÿ~™——ŠvŸ—Š¤˜¤¨~¯…œƒž„¬}™”a¥l£q…}–„r¬`¤sq€ša¼}RUu‘¡”z{†rys„~o[lnwsjnZd_hnbd]KKQSAGGFH::K>B108856877-*5==?BDGILNPTWYYZ[\__^]__\ZZZYUSOH@772.,*.+*'&?QTVWWWYXXWUOTF<E2:P[T6?G,-!‹‡™©¬¤«¹«¯ œ¡­³´¦Ÿ¡•¥¯®®©§ž¥¥š¤§¡³®¢©§³ š©¤”£µ££–—¡©µ¹¤›££“¢²™ž›¦¥ ¢¯¬›£§¢µ±Ã°­©¬©‘‡œ§£¤œ¥—ž˜˜™¥£¨˜­¡«¢¤—®¥»¬¢·¶®žž¶´º³¶©š ²£¦ ˆÒµÃ·z‡Ž†‘“€¦w”¢wŒ¡’…¥ƒŒr«ˆ†´nsjš¤–ŠŸ}—™‡‡s®‚¥›£¦Š“ˆ”šmp²\¥s“zœl™{™~n©a¢rs~Ÿbs²¸hwŽ’£–{‰‰Ž‡u{xlhwhxsn€t]ddmmfh`JYWW<GF?S3@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^``]Z[ZXURRQF:2230/++(@QRTUTSTVWWXXWUUVTQOQ[U%!2AH$*%’rŠ­¿¿¼»µž—¨¤®¶¢¢™•£ª¨®©«™¥¢Ÿ¦  µ¦¢©§±¤”«£¤­¤ž‘ššª´´¤¥œ©’”—¯  ž¦£œ§œ³˜Ÿ©£µªÂ¯¨ª¨¡Œƒ¢¡¦£•ššœ˜š˜¦£¥—©§« £›¬¦¼¬•½°­Ÿ£²µ»­·©ž¬µ¦«š|¨’}|°x‹€¤¥ˆœm±o ‡­|¢ƒ¨—š‚¬Š†­†¡•¨¡£˜†Ÿ™–{’~«™–‹«w ˆ“’z¯]£}¦§ež€|—uj®]¥lr†™]`[Œ m”£–€‘‰’ˆxy–~il~b}tm€y`gepogghBX_Z=JS2S8AAC7$$3+''3, /667436:@CFIKMNQSSSVZ]_a`aaa^][ZXSPONI8152.*,ATVVVUTUUUUTTUTSSVWWXVUVQHFIJ$))¼’š„©Æ÷Á´Ÿ›­ ®¹¦£Žš£¤ ¯®©Ÿ£ž­˜ž¹ £«¡°ªš®¡‘ª©¥—Šš®±­§ ¨›­˜™­¢¡¥¡™¥œ­—Ÿ¨¥¶¨¾®¤©£Ÿ‹Ž›š ¦ž’“™š“š™¥£¢˜§«ª¡¢ž¨¨¼¤—ì«£¢­´»­°©£¶±¬®šw¯Šœ†‡|º­‰˜d°Œd–®}¡„§—œ‚­Œ†°‡¨š¤¢£’… \lk‚³`­|{‚²lgn™—‹‡±Z}µ\¤ƒkÈ¢fŸ|»YvµZ²}S¯z¬X€¡m–¥˜ˆ”’“ywŒ›|cs|bƒwt€|aifonfefOTb[AS]=H(>9=4!!-$1. *1/04579:<ACFHJLNPPRTWZ^```ab__\[XUPNJGC553./@UYXWXWXXWWXWVWWWWXWWXYZZ[\XWWGB;ҟ³±·¾»´Â³£œ­§¥·© ‹™ Ÿ²±¨ž¢Ÿµ˜ ³¨ª«ž°­ž¬œ•¯©£Ž‰›Ž¯¬©§£¨š®“š©š¡¥Ÿ™¤¢¥˜ž¢¨±¨»®¤¨žŽ|‹›–¡ ™‘™›‘™—¨žŸ—§­¥¤¤¢¤¨ºŸ Æ§¦©¡¬¶·®°©¡¿°°°˜‚ª“£®Ž›€†¤—˜€¸Ãº„”…¨™žƒ¬Œ„¯Š©š¦«’ֽªb¤¿½}£‚ƒ×»¸µ„”’‚ž½¾„k£‚p«…oz²±Çƒk«±½¬yx¢¾»t€”Œ£™˜“™w™yb|ydŒfx{`kejjbPb[Ri\?S`BL)<:4/$%2 $(0496678;>ADFGJKMNNQTW]a\__a^`[\YTQMIC><A?5=SYYXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ»•´´²Àº²¾³¢¯§¦³§Œ—¥¿©¶¯§¡¿¦¦±›ž±œ¹¨Ÿ®¯¥§•”¯¬—Œƒš‘®¦£¬¡¥œª ˜Š£“¦§›š ¨¢˜ ¬¬©¸­§£š—’{‡™‘§›“Ž—˜˜“©˜ž–¨¨ž¨¦ ¢ªºž©Å£¡°¤¬´µ¬²¬£¿«³²uvª¤¶…eŠ pg¬Šnnw¥›¡‚v²œ˜q‘Žr—ª¤›™°¥rmmmf‹xomƒšqzjqig‰–•—rii…‡gq‡d^‹cioZ]g~x¦`br’pfd€Œ‘ŽŸ••—’šz…“td†wgŒjx~ydlcelbJdWIjY9OcDO'J9+# ",)-2.5:457:<?ABDEHKLMOQSV\W[\``a]][TPLHD=:AB7MXYZYYZYXXYXWWVWY]^^]\\\]^]^][[UW^¨•­´©ºº²³«©¢®Ÿ¤´ª™’½±ÃǼ´©ž¿«¬£ §« º£¤®¬­¦Ž–­ªŒ…•—­Ÿ¦«¢Ÿ¤¤ ’‹¥’¦™©š–£© •œ¥¥¦®¹ª«™š“’{„—¦—‘—”Ž—•¦“–§¢™¯¥¡«¹Ÿ°Á¨¥´§­±³¬°®ª¼§²»˜Œ£©¥µœ‰—£˜‡©›”’ª´šœ¤®¢µ™¥£ £¤ž£¥¢—¬§““‡“•™“˜‘•…¤š—–ŽŒ”“Šˆ…hŒtƒwt‡Œq§m}–“””ŽŽ›‘ž“”“€…“‹phvo‰wu|yikecocUaX?hZGa^MW+E=+&!640. %2(*799469;>?ABDFJKKMPPQWUVY^`ab]^UQKEC>9=@ASX[\YWXXXXXYXXZ[[\^__`^^^__```_YY`¥–©ª¤µ¸®¯¢°¥® ¡·±‘ŽªÄ¼Ã¹¶©¡¤›¥°¨¤·§©µ§¨‘˜¬£ŒˆŠœ§–­¤¡š¨žŸ“–¤—¨š©™”¦ £š§˜ ´¹§ª˜š{•‹¡”Š•‘•’—¤Žž˜§žš´£œ¦«·¨¯Â¯¤¸§°°²¯«¬¶½£²Àš“§¥¦´¢’§ŸŽ© ’Ÿ¢­±›¢¥³«³š¦£Ÿ§¬ Ÿž˜­ž“š¢œ”—«™™š——Ÿ‘‡ ž•”†”Ž–‚fŽˆuˆwz‰„tœjˆ’–•’‰}Œ–‘’–ž™’†—…xq”ry‰q{~jnd^pi`\_XlbO_bNX9FFD=2<=7.*%+)&&406658:==?AACHJGJKLMSSSUZ`aiaeVPJACB;9EMV[^^[Z\[[[\]]_^]^_`aabaaa`bbbdb\[c˜–¤¨£°´¬¯£ª§® ¨¶ª‘›£²¹­ª«¡¢™zœ¡°¤¦±©—œ¸¦£”˜©œŽ†Š‰œ£¯Ÿ¤–© ¡“—™œ®‹«–¨™§Œ˜¨Ž¸µ£¥—›‰y‚“Œ›“Š•‘“Ž‘–¡‹œ§·¢ƒ®µ¢°°u¤¿¤³ y{¢­µ¿—w¯¦¡Š€ª~d\bw ¤žƒ–~m”µ¥©±­¦f ¢•u{œ™p™ª™m€¤©Šeœ¥œ‘˜™—Œ“œ‘„›•„”ˆ“‹†yl‘ˆv‡q|†ai‰Œ•“Œ[v•fhŽŒqy¡••dx—…€v—h‚‰‚nykpe`vokkh[dca`lPY=MMMRF=?SB90/&4:306678<;>@ABFHBGGIKLTUUY]_gggXQJ<DH<9VR[`ab`^__`aa_\]___aabcdabaaedchd^]fœ–¦£¡°±¬«ª¦©®£§­¥’•ª´®°¥™©¥ª–t‹œ¯ ¨«§”—¹  œ¤ž‘~ˆ‰›žŽ¬š¤•¨¢žŽ—’ž…u®ˆ¦š¨‘–£ˆ›¹³§Ÿ˜˜‹‰uw’—“‰““Œ’Ÿ™ž¥˜›±•€Œ›µ´Œ’½§¢~§£{¥±ºƒŽ© „Œ…±ª¯ŒŠ–£šy‹¬†Ÿ£©«ª‰–ˆ›w¥œ{ˆœ˜§„‚{ž³{Š† ˜™•˜—‚‘—–„ššbyˆ’…Ž“‹„nr‘ˆz‚q†€‡tˆ†—“x–h“t št{™‚›™„˜~‘ˆ‚˜iŒŒ„jx{qpgexmilj[cihdpZ[HSKP@E5-YST6)!09=>643568;:=>>?DI@IEJKGSX[X[aaifYQH9EL<?bV^bded`aa`bb_]`aabbbcfgcba`edcgcaah˜¤ ¦®®«¨­ ©±¦§ª¥™“¬Ä¼¯ ”¥§´ƒ¬§¢ ¾ž™Ÿš¡‘}†Ž˜—ˆ¬£–¡¡’”‰†€‘¨Ž†¡œ£“–†ž¹±§š’Ž…pu‰•Š”Ž›‹Ž‘•ž£”«‡Ÿ´‰´š®‹Êˆ«¯Š·…°„³±†©ªš|¨r{wœŽ¦–h•¤y´Œ¡ ¨ª”šÂƒ«‰™¡rž€›¥~—†–²¡}¡“Ÿ˜˜€”›‰™’‹|…”‡–”Š…nt“†€{s‡‚„}…u†ƒ˜‚Åf€©‡¢j—€™€ŠŒƒˆ˜o’„gwt{vgivpghk^bnlfjWdF\QL2E46M`c7&3<EGD:63658;8>==>BL?NIJLCQZ]\Wb^jl[QE=KM@IdX]cfhgbbbbcc__babcccdiicbbbecafcbbi•—¢ °©©¨¦¬ ¥¹±©«¦š”ž¡¤©¡”£©¶¢° §¥ž‰”½š“ ’yƒ––‘ˆ«™œ›š¢…Œv››Ž ‘‡£›–˜—†¢¸¬¥™›ŒŒ~bm‹“ŒŒŒ—‹‘ž’ž ˜¡§~¡§‡­ –® ž‘‡‚¡­²‰¤¬œŒš~¢v€™”k‚«uM«x‡“œª©‚ª«…¢|{§jž€“lg—†˜·‰ž~n`cXƒ˜|dgŒs™}y—l]}˜oaTr†]`mz„`Ye‚~…™r¨ªkƒ£nr¥oŸ›gdžlZl‰{eY_‚~aWPoveotqjjo]ioljgWfM\WE8A4GC^k4+ICQMN=84859;6@;;>BO>QRKMBJ\]_W^^cu_MD:MNMTb\\ffiibbdbddbab`bdcabjkdbddgdbgeach˜—¡¹¡ª¤¦¬’¢¶¼«¯¢™–ž ¥««Ÿœ­´¢¨’  ¡§œ™Ž˜´™‹žŒ•‹u”’Š¦––˜žŸ~“……¬£‡œ‘Š˜¨—™š‘‡¥¯¦¢•™‡‰€inˆˆ‹ŽŽ‰‹Œ‘‹‘¡Š’Ÿš¡¤“£¡” wœ–§ƒ£©€‡¬¯‡¥z„š}¢ps“‡•{žŒym‡œ‹š’ªœ‡~„¢tw¦gž~w¥_˜{}“s¢n˜·´ºt“ˆ‚€¶¨dÆ¸|q•¶Œr›¤dt¬«a~j³~n~‰„ƒŒ˜q€£lr£rž‚}£^œ™³•p|—ž³tr[ž²‚ibqtuqhoXjkqpd[g\aKC=D5QAYq2<SG_JR=<395::6C<;@IP?TNNQ@D_^[ZW``{dIC7LWUVcaZffkkbbeadc`ab`dd_`cknccddhdbgfchh”–•¤¹™«œ“ Ž¥¸¶­® š¡›¢£¤¬šš±¬«“—¡™¡¥šš”ž¬›‹‰‘x‹…q€–‰¡“”—}‘ŠŽ¨ †˜Ž‰‘¢“›šŒ‹¨§¤ž–‡„~k{†}ƒ‹‰Ž“Ÿ•›Ÿœ Ÿ‹‰wœ˜¢ r¡Œ‰©‰¨’™ª®®~z ™y£“x€s—‡Œœ}•Ÿ‡›Žš¨ˆ£d¡~Œ—›mžh›Žoš™{€Š§}rht«ƒžƒsªg”š]›…v„hªj€¹f\©pœa•Œ_§vwŠ‹€hšu‡“’˜~žl˜j¦™\¨~w»j}©ZŽ„]³g[nrxwki[piwwa^dVaAPDN6VBRm4JZZ^NZD@151;;7H?:CHU?YSX]>Db]V`Qad|iFB9N[]XefXffnmbbe_aa__``ec^bdoq_deekecihgki–‰ª¶œ¨‰c•œ¬»²°¬¥›š§Ÿ¬™°§«ž—£š¢ ™–– ¤™†‰iˆ€r{—ˆ‹––„’•˜z‹„–¤œ‰•†Š’œ›ˆ¨¡Ÿš‹Š€€i†y–Œ{ˆŽ‡Ž•™}’¡žŸ¡“˜rhŸŠ Œp’‚©‰š¡¥«¢ª±®¤¢¸—w£³¢£ˆ”xzª™¢Ÿ™‰˜r¡~ˆŽ°µ}lš‘¡x~™µ££«¨„™|›}œ›tªZ]o{—‹xžbM{{†ez˜BMŸY¢js}o‚Š„™v›y‡‰±³~š’¦s}mp|”o™ri£]•vHec_tq|}ne_kguzbc_P]W\SV@YEQgDRV\aX^ID=B8?A:HE8LEXAWRZVEFb\Z`K`m}qEC<V^bZejVghmobff^a`\]^`hb_ecvl^egfldelhili”ž±®š„S_¡§´º³³¨š¢‹š©››§’ «£ ¨žžš™•˜ –‡‡‰w…nx•…›‹}‘“–ˆr‰’¡›r’€ˆ˜”Ÿš„Ž¨›™•ŠŠŠ|ƒl„…q‚¡Œx…Œˆ‡‘˜”z‘£Ÿž£ˆ®†}µ„ž{¦–z©‚—Ÿ‘Œ£Ÿ§ixn~™t sq|…˜o“‚­|¤„§Ÿ›ƒ¤p^©hv£dp¦aœÓ|{™xrsc¢†‘~¢r£vk³Œ`ƒ˜Štª²¨¼w„o¿¦ª´^œor—p‚t£r^¤gt¦`h¦l›Ó˜yšnvy—k›yv—rl©¥g_eyq„lhfcmuvf^aQZePQaHVIT_WS[ej[ePECKLJKAJD8P@QNXSXOSQ`eejSdxywJGEd]eZhiSihjncjf`c_\]]_ibahe|d^dgdkdjlfhmh˜›°¬T]K~ª¯±´°³¢œ˜„—¦  ¢Œ¤§Ÿ—©Š™˜™”š“’ ˜Žˆ…{p}ƒh}‚“šw‘ŽŠp€†“’l˜“|ˆ‘’£•ƒŽ©™“’Š…‰yƒvˆ€nŸ†w€‘…‡˜¡–x’¡£™Ÿ‰³¡¢¶‹z¬§¤®¥q©€›‘†‚Ÿ•~¥£›†˜qž„¢­®‰—‹Œ¤•ƒ¯£•wµ¶¶É¢t”ƒŸ`—©my–‡ ›u¡‡w ~‘—‹oMf£“r›‰t¥{zub„ƒn~¡mrd`œst˜k{j´¶´Æ¦s˜}yœjš™«s€šlsw—i™yt˜qPD}³^jvkx‡fkfbstolU[RYhOQhIULXRU\gknUgWMJAJMKHJNAQJPecjmeuss~x{nt‰z{UQNm^h\kiRjhilgmfce_\\\_ibdhk{_]dgcjfnmeime¢‰°¨…e@”¢²«¯¯µ¡¢–§¡¡£‹¤¦œ¦‚™——Ž—›“Žˆƒyky†eƒŒ—ŸyuˆŒ‚j……’„‹…zŒŠ•¥’‚—¨–‹‘‹€ˆz€}‹yp …y”†ˆ•ž”~“¤¦›•–ƒgnxœl¢d|r¥xœ˜ph§ƒšŽ}¥{¢—ƒ–rŸv€‰”•¹nŠ¢b}™£—‰nsk«ku np§a›j‹i–‡›•u¢~š`‹†uoˆbh¡fžj›uqeg‰‚os¢[_[d¡n^‰q|€trd¥nx¢cf§g—q‹—m¡oRˆn ^d§T‹]T˜mmrkqmphkwsjnQVUUeXSlIXN[HWhhsjYkVPREV\MXRaUhj^wu{|p}|r‚{sw€ƒw^QsagbpgPkhhklohdg_]]]`jbjivu]\chcjirlfkmc¥™¦zetmŒ§®¥©°±¥Ÿ‹–©œ£‹¡¡š¢¢€•™“Žš‹—‘ŽŠ{†q€ˆh‹Š|—šsu‰}|eƒ‡•Š‰•š‚|ˆ†–¦€¡ª…Š‰}€€Žsi¦ƒ}…’Œ‡—Ÿ†‘©¥‰¦x–›~¥‰–Œ²™ž‘„¯—Ÿ¥z˜‰{©u¨„šn¥¢Œ’„Œƒ¼m|¥¯‚‡…‡•˜ž¢~¦|s¨•¡–iŸp¬c–Š–“x¨mª£‰v‰ƒw«‘¦ˆk’±lw³©l‹†oo ž’•b«Œªx€Ž§ŸwŸ}…¤– h™‡u¬fž­Œ¶sv¾Œ¤“Yƒ¦«aurto{upbj}nglRTXT``\kL\Q[I]lmv_[qX[_Zgsenoqcqt`wz~yryƒsƒ~{{Œ‚€vbydcnsdRlggomrifia_^\ajbllzo\\bibmiwmglob–¦«€Ÿ¥–ªªž§§­£˜ˆ–©™¢‰š¤œ¨„Œš†œ‘…’ŒŒt…zˆƒo…~—“tu†r‘ƒn‹’‡†”|{…—¤¥¤€Ž‰„”u‚‡“nl‹¨€‚‹“ˆ›žˆ‹’ª¢ €t”—ˆ~y”¯¤‚q†y“Ž‡{s©q}}z˜–›„x{}}‡“•“‹w’š¡¢„{‹m†\zys{qin~“Šr€t‚”“q†„ƒf_‚Œxwt•vpzop‰n…†_wixŽg‚ƒ†ªœt}–i‰ˆo}u{‚tllfŒsx{—w„[kWyinwrqowxo]k…nigVY^V\ejcU`T]Q^owykjvdijju|pqtsaotbt{xuy‚u€y‹…‚~{n€mdyn^Wnghukxjijd\`ZcielqunZ[bkdlkymhloaŽ•º©§‹¡£›¦¤™¤«¡Ÿƒƒ–ª‘Ÿˆ™¦š¨™ƒœ‹~–”‡ŽŠ‰Œr‚|Ž|~„{—Žts„p•†|}’‹††…x~€†˜£Œ{¦ŸŠ…„•‚†Ž˜wq„ª…‘œ‡ž‡‹š§Ÿ «ƒ‰•›~Š—­¨“¨‘yqŸ”…}•p€«‡q~•qjo|Ÿ‹‘Šgm]„Žž s—ŠsulƒwtYro‡‘‚~Œj]id{…„‰€`iy|œ|„„w‚ˆ…jz‰lbqsƒw`tƒŠ‘¨–‡gŽ‚lvŠn‚Šwmcecyƒz•Z\ignv[{ywtmsrƒf\mŠkkbYX\YXkq[^`Y]]er}ztotbjjj{|qzvtdmthm{~uz}{yz€€o†‰ƒ{}szshT\rilvpuglgd]aYjhkjqrmW[emlgryohjm`ŒŒ«²¢£¡šžž˜™¨¡ }‚–«ŒŸ“†š¢‘¥•{˜…|’™‰ˆ††Šr}€Šv„‹‚„–Šro€s˜†„~“ƒƒ†Š‚z€ƒŠšŸ¥ †xŽ—ˆ•Š‹œ—„ƒy¬—˜“‰œ†‡¡ªž¢¢¤‹‡“›£š–«¢¨¨¢“‰™‘~z‘†ª€“‘’“œ±¥š”žŽŒ°‘˜„¦ŽŽ–¡Š‘„Š“‹l}wxf‚†‘‹}‰ž„ˆŒˆˆ…„‘x|{uœ¤ŠˆŒ Œ‡–€€Žƒwqu†…€y‰ˆ‹‘§‘„‡Ž‡‚‹Šzƒˆ†Œtjƒ|y™irh`tŠq~{wvovt]^o‡gn_^YZ\SgqUc[[`lgt{{rnocjjh{mx~phookf€{r‚€w}…{mƒŒ…|zy|}z„xNdvjsnq{elebb`[sfpfrqmU]ltmhxzpgikeˆž»Ÿ—£¡˜•™˜”˜¤ œz~—©Œ…Ÿœ‹ž—}x•ƒ{Ž™‰‡ƒ„†mx€r€‡~ˆ“„ml~z—‡„ƒ~€†„‡|‡ƒŒš’†©‚rŠ…’‘‹‘|{©ƒ‘—•Ž›–……›¦Ÿ¢šž†ƒ’š™™™¦¡¦žž—‚”y~Š†§|}‘†˜ª¡œ’œŽ©‘€žŽŠ•œ „˜€ˆ„py‡rua„ˆwŒ™„†…†„•nzvu”¤Œ‡œ††u‚Œ~~ss|Š…|zŽ…”¨‡„‚‰‡‡s‚…†ˆymj}{mhklg^yg}{vuvu{w\`p}nt`cZ[]QflSdZ]`jhuy~pllckjg€krkktnwm„yn†€v‚€}…wq‚‡~{{}€{‚‹`i{kuhjƒejc`i\cugobumlTbqyeoyzrejmm‹ŠŸ¸š¢¤Ÿ“’–—‹šŸžœzw›¤›‰†¤”‹˜šyzŽ…|Š‘ƒŒ‚‚‚l{xr€…}Š}kh}‚—‰ˆŽ|~…„‡|››ˆ¦›oŠŠ‹’† ¡Š…Œ|¨‡Ž‘–’–’wŒ£ ¡–›€š˜“š£¢¤›˜’œˆ{‚†‰¡~|—¤  ‘™¥Œœ’Š”™““ˆƒuu‚qwa~ŽˆsŠ–}‰Œqƒ†‡hxrzŽš“‘™€‰Œsƒ‰}~rz|†|{“Ž„—¦”Œ†{„……‚s€„…xdpzxypljf^~sh|uvt|s€j^`twpwdcX]^RihTdX^`giuyqfjclge€jm}gmpj}w†zk‹r~uv‚†|{€}jrƒntibˆilb_qVtolm`xhmWjsvctzzqbkoy‰Ÿ³’¥¦Ž˜…œ¡š›|u£Ÿ—Œ¡Šˆ›–x|†‡~„Š~ˆ‚€p~{tu‚…~‰wgc}†—Š‚Šx}€Œƒy–€•—••ž™}o‹“…¥›‡Œ‰ƒ¦•„’Š•—’‘v‘¡¡˜”˜z˜—Ž–š¥žš”•{’‰…zˆ˜Ÿ‚‹ŽŒs—¢ž ‘—ŽŽ¡ŒŒƒ˜˜„”—š™Ž}ŠŽ‚xr~n{d}‹‡q‡”€‘‚k‡ƒ‚€‹†fvp}ˆ”šŽ~•y‹}‚‰~}r€y‹‡{†’‹Œ™¤—‚„Œv‡ƒ€tx†‚s^vw}s}vfleaijwstu}q|cdasnurmaY_]ZkcRbW__gjty…pbjbkfh|‚khthlnh|‚yl…q€ƒƒt|ƒŒ€~z‚ƒ~|mu‰ttmfŠljacuVƒipn`xglajvpfx{yq_ql……¯˜§©žŽ—‡…Ÿ“•—|w¨›Š˜y–œ‹Œ™y|Œ}}ƒ{€ƒ€xsxys}€ƒˆ‹€d^}‹•‡…ˆt}~‰~˜„–”–Œ£ –~q†{“‘Š¦ŒŽŠ’ ‘ƒ“—‘Š— š’’t€Ž’”‰ž§™™Ž•—u‘’Œmˆš‘›{ˆ‰‰o—š¢‘”Š‹‹†“€””–ˆšŠ}‹Š‚{qzkvm|Œn…“ƒ•xp‚„~Œesj}‚˜˜…€u’Š…z‰wx~‡‚~…‡•¥‘y…‚tˆ†{~qr~„k`ytyp|nance{bnovsxwttaw`olunp]Z^]]i]O\Wb`glrzˆk_idichw‡mflhilg€|zwnˆs€ƒ…}t†‰zƒ}z„}|Žry‹xxnlˆkh_iqb‡hqoevgmlazhj|{xpawm‹™š«¡¥©ž‹‹‘†‰‹”–|v¬˜Œ–|ž“‘—”‰w~{Š}|€vx€ptszo…}€‰~|a\~‘‡€„„rz†z‘‡‘‘›’¤š“||Š’¤‰Š–šŒ…—’•ˆˆŒ’“Œn„‘‰ž™¢¡˜˜Š—“pŒœ†h‰›•{‰…Šp–š”¡ˆŠ˜Œ‚’Ÿ}“‘”š|‹†‰usukqnu}‹uo†‘Ž’rt€|‚‚Š~ernz›•~…Šu’Œ‚uŠ{p‚‚ˆ~†Ž‹†Ž–«Ž{ˆ}~Š„v|nl~‚€afwstnzb^oakt^pjzyymtqez^nlsmsYY]_`iZOVWdbepq‡e]ihfbgqnchheihzwuoŽ…s‚ƒ|vƒ‰…x…|x„†z€‰w‹{{sy„kk_ohtkqomqgoke{amywplww‰£™£¨¡§›ˆ‹ŠŽœ†’št¨”’† Œ–”‘t|v…xxrsz†lroxm‰v€€‡nq[Y~’ˆ€vu€ †Š’œ— ’–w‰~€ŒˆœžŠ†’—–…ˆ“˜Ž–‹ŠŽŒŠŽ‘„m‰‹‘Šœ–¡œ™–†™‰lˆ¦…h‰ŸŒ“€…Œx“˜’ˆˆ“~™}’Ž‘Ž›“}‹…pvplnoq|‡jsƒ™‹rx€u‚‰„zgtpw‚›}Š…{•“{xŠur‹|‡Ž|Œˆ…Šœ¥‰|„v‰~wwlh}~[qrqoowZ^p`pk^oj|zqnmjmw`pokqnYX```lWPSYeeato„‚a]kldbfk’n`ff_gjurro‹€tƒyv‹€y†x‡†vƒ…{‡‹|w‹jqc|b…|opltjhnlww_q~y{tus‚~¥•›­Ÿ§—…Œƒ~–•ƒŽt‰ž“’†‹šŒ–ŽŒzrxt‚pr„tquˆloltl‡vƒ}mnUQ«”‡‚x€vr‚y ‚’’˜š‘˜wz‚Œ’£š“Žˆ”˜’„…–˜‹“‹‰Žˆ„‘‹}r‹…ˆˆœšŸ›—–•€j‰ŸŠi‰¢‰”…’„Šqƒ‘—šŒŽ‹‹Žw{“‘{ŒŽ“˜|‰~‚lwjollm{€bz~—‚wz‚xƒ}zhumvˆ—Œ€‰‡|•’r|†rxŽ{ŒŽ|Š…Ž‘Ÿ †}|wŠ|vogi~v]vnmkprU]nbra_mnyphpfgtviqlawf]Ue`_qSPN[ec\woˆ{^\hpabef‘j_gd[go~olqsŠ}v|†uvŒy|†€x‡ƒs†…~ŒŒ„|z•xgrkƒ`‡~ook{`imt€t^s|x†xts…|y¡š±œ¥ƒŠ‚™ˆ‰›~Š˜’Ž„ˆ˜Ž„wtws€pp…tpqƒojium‚n}|musRN‚ßɒ֓|otƒuƒŸ‚‘v”˜›˜{“r…Ÿ¡““‰’›“…}••‡Œ‡’‰œŽx{ˆŒ‰œœœ›–”zŽxi‹”ŠnŠ¥†”‰˜„†cŒ‘˜”‰–‹Œ‰‹pz•Š|‰‹“’Šz‡}m|esokm{z\z{~€†{ziuktŒ‹ƒ‡†~—m€€p‚Ž€Ž‰~…|„‘–›œŒ}wx‚Žwrkdn|€igsngislS]ndpY_lqwgkkbgytppd`xa`Uk_^tOMK_fb[wp‰t\[du`beeŽc`fbXissmkqv‹|ty‡‚vw~‹s€‡z‰r‰‡Šˆ}~™vesn|e‡~nokYlnyzr`vz{vrv‰vyŸŒœ¯› ‚„x‡”~{ˆ›†„žŽ…Œ—„“ˆuwpyqoƒpmn~rcdwp|nz|jhlb¤šÁÜ®ï¢slvƒu„¡„‘n••Ÿ“š€‘p…‹£—‰Ž•Š–ƒ€”…ˆ€’ŠŠ—‡{vŠx†…››—™v‹xp‰‹Ž¦†“‹ž††^‹”—‰ŽˆŠŠ„‰l|—ƒ~‰†Š‘†v‡~~l}dxujoztX‰{’ˆ†z€†zgtjŠ‹„„˜‡mƒwp‰’ƒ’†€„|’—”›‘utx‡‹trodrv_rloahtfR`pgkU_nsyarc`i~qsn[csbcVnZ\wLLKcf`]ur‰m[\dx^`de„_cc^Xirknkrw‹}sw„yx|‰qƒ…}}ˆ{t‹‰‡•†~˜sguqym‹znsp€Wqzvyqdvy†Œhv€‰q€ˆ™¨œ£’„}p‹“wx‰›ƒ„ŸŒŽ|–šˆ…|swpsjoljm|t^`wv{ptzg`e|ëÚµÉÃ܉sltvŠšˆŒi—›”’ˆp…ˆ …‹•ŠŒ—“{’‡‚ˆz‘‹†‚€wxƒ„r‡‚’›–“˜‡Œvˆ€r‡„Œ‰œ¤…–Ž „Šaƒ•…ˆ…ˆŒ†€‡h}”€~ƒ…ŠŽ‚r‡€rwhvriuxmZ}“ƒ†}€ƒ„‹ƒwbumŠ‚‘Œƒ€”“pƒmzˆ‘ˆ”†}ƒ“”‘˜‰nqy‹„tjoiou~]rhm\it_QdqhfS_qvt`p`]h„qsjWgidiXmW[tLJKef^aqs…i[\ex]^dgz`d_]YknenjswŠ~ss‚{vzˆs…„|‡vvŠ†˜‚{“vlwvyx“tnwz|Xy†q€ngxv‘‚dv†…pŠ—†š¡›¢Š†sn‘Šrvš|‰™ˆ‰|Ÿ„š‚yrsnodr~iflww[_x{zqqiagaÕ¶Ž‘¦xnqw{p’Œ†j˜ˆš‹…zh‡‹™†’††—|ŒŒ€€‰{~‰…zu{ƒ|q†€•™’”‚‰v„ˆx†ƒ• ¡ˆ—‘¡€‰a”‡„‡ƒˆŒ‚f}‘€€ƒŒ~mƒ}ƒulmwutxvkcŽ‚…|„€…‰p`tr†}Žƒ}€’Š{r…g{…Œ‰Ž…}†€•‘”…nox‹~tlmhhwy_giiXktYRhribPbrxmbe^Zj„ntc\h`em_oTZnMGNfd[fmq€kZ[br_\clvde]]Zllbljsv†qo|}tx†x…ƒ}€‡ux‰’•|‰†v‰oxyz„’omz€v^ƒtlhzs”sgr‡|q’’„šŸ› ‡†uu“~mu’•}‡ƒŠš}Œšv~wroljat|gbiuyZ`w{ymq~edhhW_rs—¼Ä„uq”ˆ}q–‹†›’‹‡riˆŽ•€{•‹„š‹|Š…|{‰‹”ˆu‰†vw~ru…”…”„„rŠw†~Œ›Ÿšˆ•ž‰f~“‚…‚ˆˆq}f~Œ|y€ˆŒ}i~„vgpyxtxtlj†‹‚‹€y‚…„l_sy{~Ž‹†|ƒ‚sƒjz…‰ˆ†y…~‚™Ž‘~nmzˆ|usmfezsa[pbWnqSSmrhaNguxf`^]YootZfb^kn`pOYjQDSf`Yjmm|nY[]lbZbovdg\]`kickjsvƒqn|€tuƒzƒƒ}…v~ˆ–x„Štˆrxy~ooz€qixz~ml{u•jjw„sl“†Ÿ™Ÿ™…‡n}‹uiw–~Š‚”—Šz–o{tqkjd`s{h`eqzZ`r|ygqy`ee±²wKbZ¥ÙЖqzŠw}“Š„˜‹…nk…‘‘zy’†„˜Š|†ww‰Š„–€o‹ˆqu~{jy…ƒ¤ƒ“„€p€„x†{ˆž›–•‘–…ˆp{“‚}‚‚ˆ‚mvh€…xr€ƒŠˆ|e~…vdqs€iyqpu™Ž†ƒŠ}wy…zƒk\rs‚‰†Š~‡Š|‰s‚nr†ˆ‘‡‡t†{‚šŽ…ynn}ƒ~uycegzn]XvZWpkNWqrf`Klwta^\[Zu~spXg^gjr`oNWgR?Xf^Zojgyq[ZXjeYcpx_g\^elgfkiqw‡ol~€up‚{€‚‚v„ˆ—‰q‚q{†|zy„”Œujy~ko~t|or{z“on~xg’‹‚¡™œ‘‚…f†‚ogy”ˆ}~„‚˜Š|Žhxskkf_aoxm_box\dk‚yaqu_eeÔ꽋2:>‹Žqy…‡u‚–Œ~’‹~mk„ŒŒu}…”ˆ|‚wnv‡„ƒ—wnˆ…lu{ufy‚ƒ¦‹‚Ž‹„~nvx…|‰Ÿ’’“”ŽŒ‡{’†w~ƒŒ‚kqh€~yn||‚‹„wbz…‚rdri~nuru‚œŒ€†€tvt‚p\n€uyŒ„‹|ˆ~‰y{rmŠ…’…tƒz€˜Œ‹€umjv€ts[ggunWV|SYodLZrre[Iqxo\[[Y]uuiZb[hfodjMWeP=]e\]ue`toZYUncYdqyZh]`gmgikipw}Žli‚„yn€|}‚zu‚“„p‹nx~€{{ˆ“‰hz}js{r†zsv}~Œyx„}|k‹ƒ›ž–‹€lŒ}jh~‹z}~ƒ”‚~}Šˆkuqghb[bgrn_aks`hpˆybss^cd› n]6Z¯µti€ˆ|‘†u…•…sŽŠ‰vol„‚†ty‰x‰|’‡y~rgv‰~~˜oq‡ivynfy‡„¤‡€‡ŒŠo€w‚ƒ€œ‰„–“™ŠŒ…‰|ˆpz}„{h~lj€{zj{w‚ˆr`w~rdrgvƒnu|†–’‚}ƒpxz|u€mYp€wuƒ‡xˆv„‰|yto‹‚’‚‡s€~”‰Š|onimtm[edqoPZzN[n[O[rodUKsxiWYZZaqua^]`gdiifNYgM@`c[`u`]ulWWSt`ZdorWj^bhkgmlipw|’kh„Š}|o~~{€zw€Š‹ƒq|‡orxƒ{‰Œƒi}{mwxv‹v|x‚†ƒ~}zm„‹‡˜£Œ„ƒ{uŠxjlƒ‡x}z‚‘€€~‹ƒprpcf^Yg_po_`gpfjn‰tato[adjuz€¿œ¦¤È¸q„‚r’{w…’‚s‹‡rroƒ{ƒst‡tˆw“ˆyypcw‡z€“ir„wgwucj|‚‡€Ž~s€u‡{‚•’…{˜–ˆ‚‰{‰‰kxy~tgzhkytizw€ƒ}h`xˆ}kkth|iv‚Œ’•|€q|w|t€cVx~st‹…‚}„rˆŠyyrq…ƒ€€z~w†„wjqhl‡qo\f`qlIduK]lTSYrnbQOtxaRXX]ap‚t]b\ieedkdP[pICc`[co]]xgTWVv^[fnhVk^ajgennipwz’miˆŒy}r{~y‚|v}ƒˆ†ƒpw„rnw‚‚~ˆ‹“p€{xyzŒt‚x‚„z€uo~Š‹›ž‡}…yw…zgt…‹y~{ˆ…„w€gpn_d\XeYlra``plkh‰n`shY^cnw©Ú©Ç†‡²qˆwoŒtz…y’‰tst}wpqm„t“…xtk`z‚y‰fr„phun[m}€“€x‘“~y|nŠxƒ“†w˜Œ“ˆ†…|…ltv~lgvdm{vmjww|abx†ziuuc~|hu‡–}vwq€{}nZWupv…ˆ€zmŠ‡uylv‚„…}~z}tŒ‚~thtenŠƒlrYh]sdFmmKZ`WVUwmbPRtvXPVX^`r„p^acmed^ocT\qFBe^]eg][zbQV\t[[gk`Vj_`offkphpvxŽtkŽuvx}w„{t}ƒˆ‡ƒor€tqu~…‰Šzvxƒ{|†‡w‡|}}„€{~ruy‹ Œˆyˆvt‚x^}…—‹x†ƒt…†„xŠ{bnl[b[[aVisb`[gnpf‡raqeW\bk|Ê·¹¡jmmŠlqƒq{ƒ‰~z„yxsxut{jlvc„u‘‚vof_}‚zŒŠer‚kjqcXlz…›ˆ‚r–•w}oŠs…ŽŠt™’‰†‹ƒ{y}ppo|fgqamxqjlqx}}z]ez€xjvxfƒwhtˆŒŽ–~s‰ko~‚yo}^Ysnt‹|‚opŠ€rwix‚ƒxs{uˆ}{sgsan‹€kpVi\v[GmjMVU]SU{kaOTurPQTW^cu†i]`ljfcZoaXboGAg\`e^\V{]NUepY[jh]Wg`_rfkgqgpsw†xn•‹tzx~yƒˆur‡…Žƒpp|xwvz……‡Œ†y{t‹}}†„ƒ‡~~}†~|yuxw‘“Ÿ~‹|Šmuxc‚†•†s‘Šo……{„ucnjY_[\]Tgsd`Xcqrg€rbkdVZ_jx¾®{Ÿ·nas…hszqx…z}‹~wwrvo{vejoa‡uŽ€sjb^~yy‹„fqhkkZVow‰£…p™“rzv„oƒ„”Šu—ŠŽ‰…‰…}xtqnhx_jl`mvjgjlywzvZg}|yfs~m…ueu†Ž†—€qhk{„unvc]q}lu}Œ{‚gvˆ~oriw€z€t~m{|ƒ{xqflam‰}klUi_vUJijNRNgLX{haNUukLPTU_gv„g^aqhgbXi]\kgJDjYbcVYUyYMVmjY]kd\Ydb^tfldqgrpuwq™†v~w|…‡}us‚ˆ€•ƒnsy{zts„†‰‰ƒx}u~|…Šƒ‚„{~Šƒ{w|wwšœ—zˆ‚†iv|{lƒƒ’€rŽq†‚ƒ€pflgX][\[Sdpd^WbruiuoeebW[[hpor€s‰ddy}isusrƒw€ƒxvrumjzqagkg†sƒmf]_}p{‰imxgjdUWroŒ¦|„{v–‘t}t~|o~}“ˆx›}‰‡ƒ‡ƒ}upqlgt\lg^ltdgfizo{rYgwuhpx‚wbw†‹|•‚okn{ƒrgtfanzhsx‹{~cw„wklru|r{{uh€€ywodfbm…{ljUhaoRJhjOKNoG^zfaMUtdJOSWakwf]gtif`WdWbp\KKjWcaUTUrVKXudZ_k`[Zcd_vgmbpitorut™‚w€x€†„z|u‚„~—…nrt|zuq„…€z‹vs|•€…„}}Œ†z~€w{£¥Šy‡…ƒkt{zu‚€‹zn„sy„}‚ƒvojieV][ZZSbnd[Xas{jhmi`bX^Ziikp€gl`hyxjrssmƒ€z|utmzgiyj_enhv„geXbwj~‡{ojpgf]TXog§v€z|Žzvq€qux|“‚z—v†„€†ˆvjruggn[ld]mr_hajyh{l[nƒrtjp~zxaw†…y…t‰rpzscrj]qxertˆ|yctqgjyusmyxvye„|€ywqddcm{|jjTgaeSJkfOGQjEaxfaMSr]JNUYelx|f_nqje]VaUnnVJSgWe]XMUkTI[y_[_j]]Zbe_yhlaoovnpxuz˜~wy€€‡†zxyƒ~“ƒqtt~zvt„ˆ‘}|‘kr•€{ƒŸ…~‡}€~†‚€Š{w„«žz‡‡‚jr€yu€~tn†n}€sŠ€jpnddY_ZYZTbjg[Z_u‚i^ml\aW[[keqt}ii\kvugsvql„{}|xurlyfiwf]dshzw’ccTeph‚…xxgijaWVYgcŽ§o~w€‹Ž{qri{q}~xs…~€€†ndvrdgg\ja]oo[h_muezh]t€orkr|~uvbu†Œ{‰ˆysu€vbqn[rtcqs…|ues€mam{pkj|zvtg‡w{zvqebdmr}ijSg]\TKqbPFV`GcvfaKSoXKMXXhkv{eenqgd[W]XweTJ\bWgWYHWdOGaxZ]_lZ^\bc^~ij`otxmpovƒ˜zr€€|‰Œ†}uu…y‡Œ|suuyzzŒŽ|~…‰is–zŠœ~~…z{}†‰sq­‹{{†|eq‡ys|zurn…l{~lzcpobe^eVYYWcfk_]\s…hXqn[^XZ[kzbpwvlaYlssgtuolƒx~xvmnsdhte[gufvv‘z_]Rfgkƒ‚t~bdj\TW]bcŽ¤ixsƒ†‘ynq|jzo‰~vŠt‚y}y€idvm`f_^i_]tkYf]oobze\w|knopxytues„“€ˆƒ‰{wps~tcxe\qqbqr‚|tgse_nwjehz}uopƒvt}srb_fmn|dhSfWXSMv^PIYWHbtcaITmSJNZWjlr|cmmscbZZ[aw\SKc]WhSVFX_MFiuX^`l[[_ab]„ihanxympkvym‚~€“ˆ„vtˆtŒ†tqvvx}}~Œ~”~pw•ƒ}™’y€€xz}tˆ„tq™ zz~‡”wct‡xrwtkto~kx|p‘s^po`gblTZZWhcmf\\q‰eSrn[YXW_kvdiuji]Ymspksssi„|~~zvnmkdipc[jrdtvŽs[VSear€r‚]bc]SZ`\c‘Ÿeqq…„’ull{opr}~s‚xt{zzdeug]bY`g[^vhWb]piawa[|vijroxtsuiq‚–„‡…wtkq~ogxX]lncrs€ztgp~\`prb`ksmnvsqxkpa\ellz`fReTWQOuZQOXQHcsa`GVjQIQZVkkk}fnorb[ZXYlqWRPfVVhSTEY[NHqtX_clbX```]‹jcdmzxlpiuy‡{kƒ}€„š|ƒ„y|ˆn‡rnvz|t‚‚|‹‚ƒ˜tx“…ž‰u€‚t‚qˆƒvp¡–sy…Š†zdvŠnnznfxpykrvsk^uoagekR][UgalkZ\qŒdOon\VWTfishbted\Xntloutxj†|{‡vscdkn`\nmcsx‡kZTVcdx}}q†]d_cTZ_Yb••cmpƒ…Štki|pguyv~m{uvp{u_fsc[]VacXateU_`mdaq]]~phitqtquwkm…”‚‰}‡rsgprtpT\gkfrt€vtcmwVcrl[_pg~fnx~stsjmaZdijw^eScTUPSlVPVSPGdr_aFXiOIXTWnie}jlxlbW]U[tdSRWhQXfTSGYYOMwvZ_ekiYa`]^Žnbfkyvnoivv€lƒ€}‡˜{€‡€‰k“ˆrft€{u€ƒ}‰ŽŒ“r|Š‘„‡Ÿ†{†t†s~ƒvn¤‹r€ŒŠvvly‹`d{pfysxlmrwƒgd|mcfghS_^Ug_ko[^nhNim`UVSnfskexed\Xoslqzwrl‡{v›zykaelm^`ojeqx~gZVX`lx|{p„_c^gVX_Wc›ˆbkp‡}xllzn]xtn|kvtop|sXjn_Y\UabWdpbS_bibblZa~lfltvomwwli†€Š{‰nrfr~ntnd[aiiptts_imSeqeVcod|dsx}wlpmk`Yafgt\dU`URNWdQO[NOHdo\bGYiMJ_KYmd`yin~e`U_T]u\SR`fN\`URI[XPYtu]_ekhXb`Z^qcgjxqsnhvt{„r‚ƒzˆŽ~|‰ˆyn‰tkstˆ…‡‘„–y}Œ‡‘›„€|…s€styso““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~~~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~}~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’’’’’’’’’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’““““““““’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŒŒŒŒŒŒŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ>.1111/o‡„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffc€¾»»»»½³mfgggggmnnnnorJ,00//,I…ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ-h…‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____[~ÈÄÄÄÄÆ»g^_____egggghk=;ƒ€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}z{z|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‘‰ˆˆˆˆˆ‡Œ‡‡‡‡‡‡‰’“’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰Œ’‘‘‘‘‘‰ˆ‰‰‰‰‰ŠŠŠŠŠŠŠ†ƒƒƒ‚‚‚„ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|yzz{|{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘“““““Ž’’‘‰‡ŽŠ’“ˆŽŽŽ…Š‘‘‘‘ŽŽŽŽŽŽŽŽŒ‹‹‹‹‹‹‹ŽŽŽŽŽŽŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…‘Š†Ž‰‰Žˆ‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰‘Š„‹‰‰‹ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰Œ‰ˆŒˆ‡ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}|}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹Œ‹†‰Œˆ†ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz||||}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒ‰‹‹ŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzzz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{y{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}}}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†…………………„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰ŽŠ‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~€~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†††…†…„„„……††……………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{}~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““””””“””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••””•“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””’’“““““’’“”““““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}}~}~~~~~}~~~~}€€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘’’““’““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’‘‘‘‘’’“’“’‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}~~~~}~~€€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡ƒ‹Šˆ‰‰†……„„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxy}zxwy||||~~~~~~€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzop{xy{|{xw{xuwttvutvwuqrqnprpghklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkigfgggihgmgjghehgccbab``]X[[WXWTVQPTSSMJLKLLNOOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__`c_\_]`]^Z^]YY^ba^^ZY_\XWSNMLKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{yvwxwz{|~}~~~€€€~~€€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSSPMJMNPROMPQQQQRVVRQQTPPNNOLJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTttuxzzxvvwwz{|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMOPPRQPNNOOONOOPQONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMMMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKLFDFJKKKHJLLLOMLLNOOOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOONLORNYpprwxwwtttwz|~}~~~~~~~~~€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEBA@@CCDEACEHKOKIIJHGJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOPNPOP`pprxxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAFQE=C=?EH9:;=?=<AF@>:<>><ED=?EA?@A@DEGGGGBDDEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOABA@BA?;><>??<899;;:@:;><;;<<HL==AA?BC=ADDFBFFDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnpprttsqrwxy}}}~}~~~€~~€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;::;88:87:<978;;>=;;:8:@@BB?A?CFDBCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqususqtxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;<?@AB@=<9<=<979::989::78:9:;;8789;:8<;=@A@=;;><==@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJINJIJKKJIHGJKIJfrqstsurrvyy{}~~~~}~~€€€€€€€€€€€VLNPPNRQPPQQN8=?=<:=>A@A?>>@?>=;<<>?=<=;:<===<<<<;<:;<>=>??A@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquuuusuxyy|}~~~~~~~€~€€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AB?=?CCC@><=?@??=;>=>CE??@=;===<;:=>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVpoqssttuyz{{|~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???CED?=;<@>:;::97:<9==@=:<;;<;89;?>=<=;<@==<<>;=<=>A@BAA@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pprrrtuvz{}}}~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC??AAABA@=<=;>>:::<:8988:;=@?<;;<;::;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFFHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvvw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@A@;BCBC@???@=?@><>@?===?==>CD?;<=>@==>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hlpppqtuvy||}||~~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGABDCDA?@@@?=@><=??@@@C@@?@@>=<=@EABBFHC=<@DCAA?>=@A>>>?<>@DGE@>@A?@CFECBBC@BDDBDEAB>ABBAB@?=ABCDCCACEGA?=Vppqpruuwz||||}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@A@>;><?=<:>=?BBE@??Na_J@CEIIIIMMKECFGHEGEEEDDCA?@>>BFJJGEEFFFJNMKJIGGHKLJGGCDDDEDABBC@CDEDDEDEFCBAEeopqqtvux{|{||~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@DED?<ACDB?>A?ADEDCWu†‰Š~XGHJLLMOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHIHGFEFFFDFHGEEHHFHGHFQnopqrvvy{{{z}}~}}}}}~~}~~€€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFIHIGHHIGFBDFDDCAUt‡‰‡‡†ˆ‚WILMLMNLJGGGGDGGGGFHFHECDDFEDDHHCCCGJJKLLLKLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrtwwz{{z{~}~~}}}}}~~}€~~€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKKKJKMJKHHFFGFEPl„‡†††‡‡ˆ‡|PKLKHGFFDECC@ACCCCFFEB@>>@AA@BD???DFGDEGIKIIGHIGIIIJIHFJJJJIJIJJJFILLJJKKfopsstvxy{{{||}~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKKKKKMLKMLIFJVl†…„„†††‡ˆ†ŠuIIFB??@???<<<>::<AA@><998<<=;>;9;?ABAACCC@ABEDBCFHIHHHLMLGIJMMNMJJKKJLMSloqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHGIHKLONNQNQ^r…„„……†‡ˆˆˆ‰‰ŒŽfBB=88::9878896479;<:8567789787689;<<>A;999==>;;=ADEHJMLLGIHORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@BFHKHLKNTg{„„ƒ‚ƒ„†‰Š‹Œ‹Š‰Š‹Œ‰T:8656766646763468:876565677778:7788:;7688989876:<@GFIFIFEFOSRSSROPPRTepqsttwy{|{|}~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHEB@5788=:=DBDFFDVx„„‚‚ƒ‚†‰ŠŠ‰‰ŠŠŠŠ‹‰ŠŠH676468874578467799776765::;::<89999877:::8878589;A=>>BA?AKLOQPQOOPQWkqrttuwz{{{}}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A@<:579897:A9<D?P}„ƒƒ„„„†‰ŠŠˆ‡ˆˆ‰ŠŠŒŠ‰‰Œz>:88;<=>9:;<89;9:;::9;::>==?;;<=:><:<;<<=<::<8::;:999<?<=ABDIILKJKLWorsutvx{{{|{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?;;<:89989999:>=??Cv„ƒ„……†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>BCEEBAAB>@CA@?=>>@???@?@==?B?AA?A?=AA@??A<><;:;:9;?=;;==AACABCAXpqtttvy{{|}{}~~}}}~~~~~~€€€€€€€€€€~REBAGJNOLIGK:8:;9::<<:::<;=>@?=a…ƒ„„…„†‰‰ˆ‡†††‡ˆ‰Š‹‹ŠŠŠ‹‰‹^>DGIKJJFGGDFHGECA@CECC@BCB?@DHECEDEEAFEFDFFD@B>=@>=?@>???>?>>:;=<`qrttuwzzz}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD979=:<;>=>>;><??C>J~ƒ„…†††ˆ‰ˆˆ‡†††‡‰ŠŠ‹ŒŒŒ‹ŠŠ‡WGLLMKNIIKHIJJIFDDFGFDCFGEBHIKGHGFGGEKJLIJKJCFCCDBAACBDCCDDCA=;=@hpsttvwzx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€OA>=?DLK@BBA97;>;<:=?>?<?>BAE?h„‚……‡ˆˆ‰‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹‹ŠŒPMPMKNKJLIIJHKGEGHHIEEIGFELLMIJGGHIJNMOMLNKHGGGEECFFFFDEHHFCA?@Lmptuvxyyy|||}}~~~~}}}}~~~~~€€€€€€€€€€€€QA?>?FGG=<@@87<:;<:=?<==?@CBHS~ƒ„„…†‡‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒ‹ŠqMQOMLLLLIHHFJJEJHGKJIJHHGKLNLLHHIJMPNONMOKIGIJHIDIHHFFGGIGCBACUoquwxz{xyzz||}~~~~}~}~~~~~€€€€€€€€€€€€€€TDAABGGB?8?@8:;7<=:<?<=>@BCCLm„ƒ„„……†‡ˆˆˆˆˆ‡†ˆˆˆˆ‰‰ŒŒ‹ŒŒŒ‹‹‹‹^RRPMNMKJGFCHKGLJFKOLKJJLMLOPNHIKLOQQPQOOJIJJMKLFGHGFGIFEEB@BB\prwxyzyyy{z{|~~~~~}}}}~~~~€€€€€€€€€€€€€€UECEEGGED;?A;=<8?==>@ED>BDCFJt†ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹‹ŒŒŒŒ‹‹|WVRRTROLKKEFFKONOWVQPORSRMSTOMSLPSUWRSRPLJMMMLNGGJFFHJDDEEBDCcquyyzzz{z{zz|~}}~}}}}|}~~€€€€€€€€UFEGGGGHF>@B=?=<A?AADTKBHIFIKx†ƒ……„…‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŽ‹‹‹gVVkaERQQPK;;QSR`u]UVTVYYRXXRZfPUWZ]RTWQPNRPPQQKKKGHJHEFIIIHIjsvyyzyz{{|z{|}|}~}}}}}}~€€€€€€€€€~~THJIIGFFE??A@EACFDCDKVPJPPNPPy†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ”œŒŠŠŒ}aŠ‹‹‡l[dU:XXXSQ?@VUY\d`VYbr^]V]ZVEQYZ\Y_TYgRUVXTTVSOOMKLJIILMKOMTptvxyxxzyz{z{|}|~~}~}}}~}~€€€€€€€€€€~~~~VJJIHGFDDBA?HLIMPKIJOSRQTVUVTu…„…………†‡ˆ‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~Œ‰Š‹znpXZ[ZRSRWVTZZuƒYU}a\X]^WIV^^[[_YHYXY\]XXYWRQMPQMMOSQQURbtsvwwvxxxz{{|}}}~}~}}}~~€€€€€€€€€€€xy}YNKJIIFBD@A:OQQWXPPPQRSRVWWWWl‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡ƒŠ~fYY\YSVTWRQWVc–€QerXZW_hP`fZZX\hbGOZig\[\]]WSNSPPQVVVVYZostwvvtwxx{{|}}}~~~}~}}}€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZZRSQOQRQURUSV^ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PVXTRTRQQLOMKfyZ]TYUV]ZLTZUST^ZXWWWzkXZ\\^SPPOINOWVXZZdqtwvttvxyy{{|}}}~}}}~}}~€€€~~zxwvsu{€€tk~~kry^[VUSROKFCDAM^ƒlVRSOOQOQVQSRRTcdv€ƒ‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ymqVIKNNKMKHJDFHEC>ScURQQNKRURMOYQMNQSUUMQSRPNLKHCIGRSTY]mrvwuttw{zz{{}|}}}~}}}~}~€€}}~~~€€~{vsw}~~du}iqt`d]][YUQLHLIal’tPQSMQRPS[RSRQRUUbs{|~€‚}{{€ƒ‚…†‡‚†††„†…†u_]KC>BBCCA?DPCC@C>BHGV@HNMG]iQHGOFDEFHGHBCHGHJGDAAC@NPMRdtuvuttvy|{{{{}}}|{~}}}~~€€€||}€€€}vt{mh|gnqfiedb\XSQPURsWe[OONLRRPUYSUQQTROV`klsvz{xytrnstsyx~~ƒ€ƒƒ‚€‚€‚kLG>>::>@?>>>jPKaEFHIEB?GLMGMQUJBE?><=<==?=?ACB?><=B>IMFUouuvstvx{|{}{|}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QQZ\Y^IJOPNKLQRQTVUWQQWVPX[b]agmmlnjh`nrimlqu{z}{xz||xwxdB@@A<:BCAACA[\O{NOONKLMOOPLKLWNIGAA<977599=;;;8989?;BG>\tuvvuvwy|||}||}}~}|}}}}~}xuwz{zwyxuw{|yxuywcqhipmnmmhf^OO^\ZIGOQQOMPQNQRTVXSRYTNYZ[WY\_^_e_]^qwk^`gkwooljomnlfbYGFFHBAFHEEFCLQOaWRXQPSSRU[OOQVPMIDF>996587979:365795<B=ftuwxwzy{}}||{|}~~~{}~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZWMKSTSPQUOLRSTWXSTXQLXYYVXXVXY]WXXhsk]V`tkaa_]d`_^YUPMONLIGJKIHFCPOSZWTTNQSYS\eUOSTQNKIHC?A9988978847578599Gnruyyz{{}}}}|{}|}~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPWVVSTVOOUVWXYSUTLKSUUUUWPTUWTUR]n^RNY`[VY;DUWS[fJLPRROMMNMMLJFPPUYSTOJNOUST\VRUSRNMLIHHF?>=:787659967665Xqqtxzz{|}}}~||}|~}}y}}|~~~}||}}~}|rvqxxruuqqnppopuvtnjddjppqrpnfedc\^RTZVWTSVTRXWYYYRUOIGOPOOMRJOPOONNOTLMIPPSTU2<XMI@Q=c`QSQPMPPONNMPNTRPRLILKORPQRRTQROLMKLLHCBA=:9876;B4566;eprvxy{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqpuuvcjgeWhtrrqniihpVVTUXUVURWVUZYXWVQSFFAFGGHFJDHJHGEHLHKIGLMPMG/E_R>4@>joaRRQ@GTQOPPQNQOPOLJLLPPNMPQQNQOJLMMKGEECB;==<9=G6676Enquwz{{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknbePSTRSUOWVUYYVQQQO@>;=?@BAC@BEDA@GHGHFFHJMLDGCORC8DMS]gSQSAGUPOQQPMMNLJLKLNOOQLONMILKIKKLKGFFED<AA>;@E;<89Trsuy{{{|||{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLONMQSLTUTWWULLKH=987;?A?==A@B==EHFDFFIGJJ@FAA@FGDIOHQRa\QPROSNOOLLOMKMLMON[VKMQOGIHCIKLLKFFFE?BC>=BG?B?@druw{z{{|{zzw|xy~~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCE=9879?B?;>A@@>AEJECHGIGIEBB?><B@@GJEMObePMOMWKLNKLMMLLKNNSdMJLRIIIFBJKLMNJGIFBBB@?EFEHDLopvzyy{{z|zwsxux||yznqqmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGLLIMPMPOHKE?B=99::?B?<ABAADEGKFDIIGGHCC?B>?@@=CEDLMQTLJIMTFIIJLIJKIILMOPQPKGCKHCCKKLNONIJIGCCCDIJMLIZsnxyxzz{y|vrpurtyyvxjqokllnttmsv{stxronqovsnporpopstyjN`gsjt|ygosqjqheqHKCFGHGJKIJLDGB<>=:::;AB?=BBCCHEJLJEIIFGHCC;A@B>@?BDDIMOGHJGHKDHIKMHJLHIJLJM]RHIDNGBELLNNPNKMJKFGGJMNRNMcnjwvw{y{z}qmlskptttuhpmjikktpnttyprztorqowsoqptrprutykNVmulq{vinoikthepFJCFEFDEEFEGCC@=<=:;:;AD@?BCEEIFJJLFIIGFFDB:ACC>?CCCEGKMHJNHDHEILNMHILGFFIILNKIHEOICGNMOMPNNOMKIHIOSQRNSggfrosxv{z|lhjoekpmsqfmlhikltmoutwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhmf_pGJCEEDBBAE@DB>?>;;;>;=?DB?ACFGKGJILHGGGFEC?=DEB>ACBCEGHIGMPIEFGKNOKFHIFECDIJHKIGHPKDJNLQNONOPOJJIMRUURPXeaamfproryzgehhcilfqlflmgiklsmpwutpnvrosrsutqssutsuvvvyvutvlkuumrvqlnlerMGEDFBA@AD<BA>A=::=?;>?AB?@BEGJFJGIGFFFDCBAAEFCBBBDEEGGHFLPLHNJJLKIFHEFECCHIHKJGKRNCOONQPOONOPKKKPUWVVTY`_]i`ninhrsbeffdhhfnifmmhkkmriqvusqmvnoqrswsrstuvvvvwvwvvtwuksunutsqskksMGGEFAB@DE<AA@C<8:=>:@=@C@@ADFIEHFFHFEEDCEBDIFCGEAEGEFFGEIMKHQMJKHHIEFHHECIIIKMKPSNDRSRQSNPMOPMLNSWVXYVX^Z]d`icjigk_defchggkggkmkmlpqgttursnvoqprtxqssuvu‚‘yvvtxuuwxnouorsuqqipzMGGGHBBBEE<@CBD<7:>>;>;AB>??CEGDFDDGECECDFFFJEEIGBGHFGFECFJJGMKLKHJKFIHJHEKKLLNORTOHTUTQTPRMNQOMQWZVZYWZ^ZXa`a`^hec`deggjhhjghnllomqpiuuxrrpupppruvpusuvu{~}xvtwvvvwplupmsunossyNHHGIDBCHE=@EBD=8:>>=<<BB=@>ABFCECCGCCDDFGGGIFHJHCIHGIGFDHKIGKHMKJKLHKJMKINLONORUVOLVVTQTRRLOQPOTZZY\ZZ\__]_c_\bdlc`dghr…hgjfjnnponsqjtuxrsstrnpqvrquruus~yŽ}uuvvvvxriuqkrtlqwquLIJHJFBDGE=AGDD@:<>@?>?CB<@>AAGCEDCHDEDFFGHFHGIKJEJHHJHFFLHHHJGLKLLLIMJMNMOLPPRUVWOKVVUSSRQLORRQV[[]^[]^``a`bf]d`fg`eijdssfjhflprqossnswwpuvtsmoruorspurvrtvuuuwvuwsgtrkqrkrwpwJJKIKGBEDE<AFDDB;??A@@ADA@B>ACHBEDFGEHEFEIHFIHJLHHJJIKJFJKHIKJGKKLLIIMKMNNOLOQRUWVMNTVUSRQPMNTSRW[^^_]^``abb`ddebdibdijgv‹lkigmosqpqpprywruutsmmssmqrotuuspswtuuwvuuufqskpqjrvpwJLLKLGCCAE<@EEDC=AACBBCEACDAAEGCGGHFEIFCGJGGJFILHIJMJMLGKIHLKNQKRPLRLJMMNPPPUOWXX[NSQW\ZSVPNTUTTXZ_bb_da^ac_afcabhnhbihhmxvmhinosrpqrrrvtsusssnksqmprotvsqquvuswywutucmtkopjqtqwLMLLLGDA@D>>DEFC?CAEDDFCBEGCBHFBHJIGHJFDKJGHJHIKGJJNKNLILHJMJZfJd[JlRGNM_nUls[qpbwcRPbvuhucavaXnqbdvimzf\lt`lkV`wvijghfglmjmojmosrprrqrsrssrtrnltonpqquurqstvvuuywutt`ktkppkqsryLNJKJFB?@B?<DDFDCCCEEDFBEFGDDJEEJLKIKLGGNIHJKGKJIJJNLMMLLIMML[sbdp]llULNer]geqlntgpi_aYnmbppbkjjgoqtetno\pvgpOLryvkaakeelxmkvlnpsrprqpqrqrrrtrmmsnnoprutqsstuuutwyvttbmukpplrrr{KLIHGED?AA?=BEFBECEDEEDCHHGDDKHGKMMJLLFJOHJKJIKJJIJMMNMMMKNMN[rponppkjLOPmXNibtrpamov\YlP[mmZqmkplxxtsip\`slqkUuyxoc^kfbgppjioppsspqpqqrrqqrrtlmrmmnorutqtrtuutuuzvutenukpolsrryJKGGEEDBAB=??EGBGDHEEDBFIHHEGKJGMLNJLMGLNIMKHIMIJIJJNONNMLNML\hdu]lqVkMOQnUZk^klvaldtTecNlYl\toljlxjwuhp]_skhWbcw|oc`ghacityknnqsspqpqprqppprukmqmmmoqstrsrtvvswvzvuthoulsomsrtvIMFIEEDCAB<B@BFCGFKGECCHKHHFILKFMKKRRLHMMINJIGMGJJHINOMNLJMMJZtppoqqlkOQRnYskgooqqomt^nXat_nopoqsoousttjZ^tcwxrjnzhaacfabjmtupsuvsqppqort{~}wlkqnlmnprsqttsuutxxyytukoumtonssvtIKHJCDDE@@>CCAFCHIMHFCFJLIGFJMLFOJJWRKGLKKNIIJLIKJIIKLMMLIKKJSkbYi^_jcrrZ_Yjo_eeUk_c[aaQ`mh\j\nijd[oedp]Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunvqrutwrHHFJDECFA@AEDCFBHJLGFCFKLIEFJOLIOJL[QJFHILMIHJJKKIHIGKKKKGHJIKKLJIKLNT[]TPUMQONOOVQOPQNOQJJNPQdqiTYV[[\UYZ]X]\\cfaafbcf_^fkmhmtyrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyyxuvqruovrtsuusHCEGFF@EC?CGDFGCIKLGFDGJLHDGIPKLOKLWMIFEHJJHIKHLJIGHHJHHHEFKHHJNKHO\W^O\\`^OXYS\\b^MYZMXaRKYaZS`d\aX[ddVVX\YZX\VY\^c_d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtPBCDLMACCBDIEGGFKJKHEEJJJFEHHPJLMJMRIHEAHFJIKKILJIGFJHEFGEEJFBILIJS_Y`X`a[`UXZT]^Z_RY\P^\YN_\^S[^d^Z]`c_Y_b[`^[UYYZ_^ccbaceiekrpoppnow††……†‚{€……††…†…uqprrsuyzzyyxxxwryvxrqxvtvaSJJMIDCACFGEGGIJJIIDFKKKEFIINJNLHLNGHF>HGLIKKJKKIGEIFCDEBFJD?IKHNZbY^^a_RTSW__\]Y^QY\MV_WKQY[Q[_ba]^ca`babcceZRZWW]Z]d`__cebhommllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxYQJFDGEBDHHFGHIFGJGHFHKIKDDJJMMLLHJJHJG@GFNKKKMKKKIGIEE@DAHIA>HIFO]`Z[d]_TQRX]\\\_[KW\LR\YIM^QQ]_bccccb\dbadcfXRWUT\X[a_^_aa_dlkmjklnv~uz|„………………††††……††‚zrsuu{…‡‡‡†…„~xpzwvx\RMC@IFCEKIFGGIGGJGFFILJNECJJLNJLIKKIIGCHHQMKKOMKKIHHFE?EBHHA@FECS]Y^X_X_[]UXXO]\QKJV^X^[]VZaRR__bb``bb_cbaddaXPRRS\S\]]^^___diglknnp{{|~{€‚ƒ„………………„„…ƒ„…‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKBAGFDGMRHDRKFHHHDFKIMPEGIJKNLLJLLJIGDHKQOMLPMMKLIJDEAECHFAAFCAUUE\T^SW`XNTUMYZLJKT`a[_X_^b]OYb\``_bca]baW`_UQPQRYS^\[]]^`bffflfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDFFHDIScQEW_IGGHDFMJPPFIIJKNLLKMLJJGEJNQQNNPMNMNILBEACCFCB@CD?LGCLLPOOMFMFFHIGFLKMOPILOPPSPLQTSUZXWYWWcVNRTPQPOQVT\YY[]\aaefdhdlmqsszy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKN^MHHYMGHJHGMLQQIKJKKNMUNOKKLGGKPSSNPPNOOOILFaED^LDfbCLZG^\smOMVnYKCP_TkVgJ]XU^DLQULMSVQRTXVTXTT\TOeZhheZUkTXWU[\[``abbcagignlhsz|}~„„„ƒƒƒƒ}}zr{z{‚€ƒ„„……„…ƒƒ~z{LIEFFHEELPTJKG`THJOJIOMRQKMKLORUROPJLNGHMQ[YOPPNPQPJKQQI|YYrsWPmGqnoaVPqqtOBksmqspSo_[nX]V\XUkhU]VcY`YZ^UUWituu`av_Yb\\f[_aaab_acgmom`pwtx‚ƒ„‚}~€vxzmv~tx}€|~€‚„|€ƒz~wwNIEHMMBDLLGJLFRVLKOHLRXWQNOOMQTNOQPLLOGMPS[ZTQROPPQLIZx]TxdhXRSPvftlpbnfkRrNLwmjrpsrqrpoo€]ezuxqqzq~r}ku}aRh|esspss|}p~xor```bb[bahlnkblfgmw~€ƒ~{xw€tvziq~nt|~wx{~€ƒx|u|||ssNKF`]GADMMHKKHKPOMNJNV^YULQSNYYLSSSNLPIQRTYWWPTPPPSLHgxlcxqmZJKTypumubnvPddHevqmwo€jfxxiWrQhzmijzz~lxzphnXuujvuqash}ilx|o___cb\_cegjjegbcdlmppstsssyqrxbmtgry{ssuy~svzn|}yxrnMJRtNCBEPQHKLJLQOOOMPZ`ZXKSWPa^RVQYSMPJSTVXWWOUPONRKLrouuquqch`UnKqp^GhyWvTKhx}w`y{sna]modSgrunmypwkustqlm\s~zkmy|lun|kqwux^__b_^`edighfe^bbiiijknokqnmjpacfcowxompsynqpj{ztromKKZVHGEGRQKMNLLQQPPPQW\YUNVYUfXRRY^TMNJTTWWYWOSOONRIRmHiwK`dvvTVlNnl{rajguTKWkg|lmlx_Zpz{_`zscroxqgc|ir{]TKl_vuljv|{nyl|p]^^b[_ceegfeec[ccikkrsrwgmihdg`alagsrlglmr|kmhk{tmmkmOGJKHJHHRQMOPLLSSROSRXRWTPWZVVTTTa`QONKTSSQVVOOMNOQKHQNPULKKRSRQROVUQQORRXXPMOUTWXX[[UQRW[WXW[ORTWWXQ]XV\UTOXRWWXYZ`\hs_\[[]]_cZ_ddegdddcZdbgffmnmuffgc`f^]g`dlhfgkhpzhggkujhgilPIKKLMKJTRNRQPLVVTPTUXUZURZ]UUTWUYXOOLNWTPNUSNPNLQPKIQQKQMJJOQTQPQSRJHMOPQRPPPTURXW\WSSPQUUVSZQNRRWTRXUSXTSQUSUUYYX^Z_a]\[Z\\`c\^bcdgeeecZ`adabhhjncad^_c]Zc\bma^ffgmsdihkkedcghQJKKNOLMTQOTQRMXWUTVXWWZVS\`VWVYUXTQPKOXSPNUPNQOLSPMOUSNQNMNQSPTPQTTNKMORTTQQQUWUYZ[YRURTXWVY\SOSTWTSYTVXTRQWVVX\Z\`]WY_]^]\]aa^[bcchgfdcX``b^`hegea^_]]^ZZ_Z_g`^^]chkahfhfd`bdbPKMLPQLPUPPTQOQZYXWYZZXXV]jdVXYZWVSTOKOVTPOTPPQOMRQORXTQQOMORTMWQSTUONNQTVURRRTXVZ]\ZVVQRWXU[[VPSUUUUXSWXTRQXVV[_[^`_V_]^`]\`___ZccehheebYb`b^_fdc`b]\\\\YZ[X[a[^]]_b__bddbd__`\PMNNRQMRSPSTQOV\ZZW[[\YZ[dqmhd_[YVVXRMMWSMMRORSOMPSRU[UTPPLPWUPVQRRXMOPRUXUTTSTYX[^]\[VROUWU[ZVQSVTUWUSXZSRQZWW]_[```Vb\`a]`b_\`]cachiegaZc`a__ee_`c[Z\[\ZZYYW\Z\Z`^_[^^a`_c\Y`ZQNONVQPUSPUUSPW\\\Y^]_W\^jpwy€c\[VVYRNPWSNQQPRTRLRTTY[WUORNSXUSQRPRZOQSTV[VVVSVZX]^\\^VSNTVV[[UQTUUWXRSY[SRR\XZ^_]ba`Wb[cb^ac_\bab_dgieg^\d`a`acd_b_YZ_[\[XXYWWZZZa]][]\\Z]`W[[ZPOOOYPUUSRWRTP[]^]\`\`U\\hjr}slh\UYWQOS[SRQSRUUUKRWVZZZSOSQUUTRMTPRZRTUTX]WXXSX\X^]YZ]UUNVVW^ZWQTUWXXSVY[TRV]Y]^a^cc_Y`[eb_dd^^cca^efieg_^daaabcd_b^X[_[\[XXXXW[Z[`][[\[XZ[^V^Y]POOR[PZUVWVSTT^^`_^b\`U]^bkyum}lZUZVQQT\TTTVTVYWLRZV\[\RPUSWUUROVPSXSWUV[^X[YUZ^X_^Y\YRWRYXY_YYRTUYYYUWY[UTZ]]^ab`ed]^]]eabfd^_dc`\gehfeb`ea_aabb_`^VY^Z\\ZYYWV]Z]^[Z[\[WY\]VXW]SOPWYQ]UWYWWUX_`aa`c]`U]^beev‚{hXYZTVTV\XWWVWW]XOU\Y^]]TSXRVUSQRWQSVTXXX^^X][U]_X__X\VQXTZZZaX[TVWZYZWXYYWV]^`_dcbfe^b\`fbdfd_`dba[fchfdfaf__bbaa`_^VU]Z[\[Y\YY][[[XXY[ZZZ]_]TY]UNTZVT\UWWYWV\`abcac__V[`da_zuohZ\ZVXVX[ZY[YXY`VOU][`a\UUYPTVTRUUQTUW[[\__Z_\V__Y]^Y]VRXWZY\bY]UVZ[Z[ZZXZXY__``dcdeecdZbfcgfe^ab`c]bciedg`h^bbcaa`^_YT[ZZ[[X\XX\[Z[WWZXX\[\`]V]]SOVZVVZVYVXWX^`badada^YYadb`kfh^\][WXYZ\\\_[Z[bVSW^]ac\SVYPVUUUUUSUTX]]_``]a]Wa^[^\[^XUXW[Z__[^WX\\\]][Z\WZ_a^`ddeffgcYcfehgd^c`_ec]fidei`g^cbcaa`__\XY[YZYYZXW[[Z[WXZTZ]\[`\U^bMRWZWWZY[\XWY^`badada]^Yacb_a`a_\]]XW[[]]__\Z]cXYX]`cd_RXYPWUWXWVVWV]]^aba_b^Ya]]^Y]]YXUV[[`^]_YY^]^^`\ZZY[_b_cfdfgfhcZefgigc_c^afeZiicfjdf_bbca``_]]ZW[YYXXZYWZ[ZYWXVU\]]]``bbxKWW\YW]\\]ZW\]_`bdbca]`Xbcb`cac^\]\XW[]_]`_][`d\\XZbecaR\YOXVY[YYWYZ`^abc`ac_\b]_][^]YYTX]\__^_[Z^^`bb[[W[]`bbdfdgffhe]eghifcab[cg`\iichjge`baca_`_]]\Y\YXWXYYW\[ZWVXPXZ]acffrkJYW][Z_]\^\Y][^_bcbaa]b[bdb`cbb]][ZWXjq`\`_]\ac_^YYcedbT_ZQYW\]\[Y[[c`ccc`bda`c^`\^^^ZXU[^\\aa_][`abfb^[S\_`cddfegffgf_fghhgdd`[eg^ahhchigd`b`cb___]][Z[YXXXVZV\[ZVVULXX\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ‡‰‡…‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vvvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyyz{{zz{zzzzzzzzz{{{{zz{{{{{{{||||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vvuvvvvuvvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyyzzz{{zzzzzzzzz{{z{zzzz{{{{{||||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚ƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||vˆ‹‹‹‹‹‹}}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÓÏÄÅÅÅÅÅÇÒÔÔÔÓÓÓľ¾¾¾¾Â¢ŠŒŒŒŒ‰~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}vŒƒ~~†“y1333332j‚€€€{­éääääåàÔÔÔÔÔÔÖãååååäåÒËÌÍÌÍЪ’‹}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}vxxxxxxxwwwwwwwxyyzzyywopppppprrrrrrrwzyyzzz~ƒƒƒƒƒƒƒ‚‚ƒƒƒ‚ƒ„„„„„ƒƒ‚‚ƒƒƒ‚ƒ€||}}}}}|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚‚‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vvvuuuxvvvz{x{xwvx|zyyz~|yyxxxxyyyyzzyyyyzzzyxxyyyyyyyyyyyyyyyyyyyyyyyyyz{{{{||{|||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwvz}y{{y|{xwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwvz~zy{x{zxxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z{xwwxy|z|w|yxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚ƒ‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{xzzz}|z|x|xxxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyy{yyzyyxxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyyyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyyyyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oxyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{|||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}|}}}|||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹ŠŠ‹‡‡‡„ƒ‚‚‚‚€‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡„…‚‚‚‚€‚‚‚‚‚‚€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹ˆ‰ˆ‰†„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚€‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚€€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrstuttssrrsrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqstsssrqqppnnnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqqrssssqpqpoonnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrqrrssrrqppoopoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpppqrrqqqpopooppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqpqqqqqqpooppppppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒ„‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqqqqqpppppppppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsquŒ‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqqqpqqqqpqpqpqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrqqqqqrqqqrrqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrssrrrrrstrrsrsssssssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚ƒ‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz|~~|vvwwvuxzxxxxwwwvx|yy|zyy|{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†ŠŒˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~|{{z{|{}|{{{{{{zyxyxxz{zzzyyz||{zz|||zzz{}}|~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}|||~|}~~~~~}}||}ƒ€€}|}|}}{}}|||}}}}€‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆ‹‹‰Š††ƒ‚‚‚‚‚‚‚ƒ‚€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€€€€‚€€~~~~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒˆ†‡‰Œ‹‹Š†…ƒ‚‚‚‚‚ƒ‚‚‚€‚‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~~€€€~~~~}~~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Š‡ˆŠŽ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~~~~€~~~~~~~~€€€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒ„ƒ‚‚‡’“‹ŠŠ‹Š‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚‚‚€€€€€€€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒŽ‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒƒ‚„„‚ƒ‚‡ƒ‚‚€‚‚‚‚ƒ‚‚ƒ‚ƒ‚ƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚‚„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„„„……ƒƒ‚‚ƒ€‚ƒƒ…………††‡††††‡‡‡†††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„……„…ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠ‡‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚‚€ƒ‚€€€€‚‚‚ƒƒ‚‚ƒƒƒ„„ƒ‚ƒ…ƒ‚‚„…‡‡‡‡††‡‡‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ‘‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„„ƒƒƒ‚ƒ„…„„……„ƒ‚„……‚„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆˆ‡†…†††‡ˆ‘’’ŽŽ‘Œ‰‡…‚‚‚‚‚ƒ€€€€€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚‚€ƒ‚‚‚‚‚‚‚‚ƒ€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„…„„…„…†’“‘ŽŽŽŽ‰ˆ‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚‚€€€€‚„ƒƒ‚ƒ‚‚‚‚ƒƒˆ‡‡‡‡…„‚~~€€€~~~€‚€‚‚‚€€€€~€‚€‚ƒƒ€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“‘Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰‰‡…„ƒ‚„„ƒ‚‚ƒ‚‚ƒ„‚ƒ„……„‚„‚€‚‚‚„ƒ‚ƒ‚‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘‘ŽŒ‡…ƒƒƒ‚‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒ„„„ƒ‚ƒ‚ƒ……ƒƒƒ„ƒ„ƒƒ…„…„„„€‚ƒ‚‚„ƒƒ‚‚„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚‚„„…„……†……ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”““’ŒŒŠ…„„ƒƒ‚‚ƒ‚‚‚‚‚ƒ‚‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~€€‚€€€‚‚‚‚‚‚€‚‚‚‚‚ƒƒ‚‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚ƒƒƒƒ„…„……„ƒ„……†………„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†””’”’‹‡„„ƒƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚‚€€€€€€€€€…………††‡‡††…†ƒƒƒƒ€‚‚‚‚€~€€€€€€ƒ€‚„ƒ‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“‘Š†ƒƒƒ„‚‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„……‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€€€ƒ‚‚ƒ‚‚ƒƒƒ„‚ƒƒƒ‚€€€‚‚‚ƒ‚‚ƒƒƒƒ‚ƒƒ„‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†ƒ„ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„……‚‚ƒ‚‚„‚‚†…„„ƒƒ„„„†…„„…‚}}}~‚„ƒƒƒƒƒ„ƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„„…………„…†…†……………………………††…†††…†††‡†…………ƒ„„„‡““’‘’Œ‹ˆ…………‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒƒ‚‚€€€€€€€€€€€€……………†‡‡†………„„……„„„„„ƒ„ƒƒƒ„…ƒ‚ƒ„……†…††…†‡‡†ƒ~~~~~ƒ„ƒƒ„„„„„„„„„„„„………„…„†……†…†††…†……‡……†…††††…„…………………†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„ƒƒƒ…………‡‡……‡…~€„…„…†††…………††‡††…†……†‡‡‡ˆ‡‡‡†††‡‡‡†††††††…„ƒ„………„……††‡‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘“’‘‹ˆˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒƒ„„„…„ƒ‚‚ƒƒ„ƒƒ‚„…„…‡‡…„‚€€€……†‡ˆˆ‡‡‡‡ˆ‡ˆ‡ˆˆˆ††‡ˆˆ‰‰‰ˆ‡†‡‡‡ˆˆ†‡†‡ˆ†‡…„ƒ„…††………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†…†„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡‡…ƒƒ…„ƒƒƒ‚„„„„…„€‚€€~{z€†ˆˆŠŠ‰‰ˆˆ‰‰‰‰Š‹Šˆˆˆ‰Š‹‹Š‰ˆˆ‡ˆˆˆ‡‡ˆ‡‡ˆ†‡†„ƒƒ…‡‡‡†……„„„……„……†„„„………†…†…ƒ‰”“Ž‘ŽŠ†…†…ƒ‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒƒƒ„‰Š‡‡„„…„ƒƒ„ƒ…„ƒƒ‚‚‚‚‚‚€~|}}}~|{|ƒ‡‰‹‹ŠŠŠˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰‡†††‡…†ˆˆ‰ˆ‡†‡„ƒ‚…ˆˆˆ‡‡…‚‚ƒƒ‚ƒƒ„‚‚‚ƒ‚„ƒ„ƒŽ“’‹ˆ…„†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚ƒƒ…‰Š‰‡…‡…„……„ƒ…„ƒ‚‚‚‚‚ƒ~}~~~~~~}}~}}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡‡‰†ˆ†ˆ‡‡‰ˆ„ƒ„ƒ…„„……†ˆ‡†…ƒ‚‚„…‡†‡††ƒ‚‚ƒ„‚ƒ„„‚ƒƒ„ƒ„‘’‘Ž‹‡„††ƒ‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒƒ…†ˆ‹Š†…†„‚††‚€ƒƒƒƒƒƒ‚‚}|}€~~~}|}}|z|„†‡†„ƒƒƒ„………ƒƒ…„„„„…„…„‚‚ƒ‚„„‚ƒƒ…†…„‚‚‚ƒƒ…ƒ„„…„„†ƒ„„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰†„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€„„…„………‡‡‡‡†€…ƒƒ……„‡ˆ…ƒ€€~}‚ƒƒƒƒ‚‚€}}€€}~~}}}}zzz~ƒ„„‚€‚‚~‚ƒ‚‚‚‚ƒƒ€€€ƒ‚€€€€‚‚„ƒƒ…„‚‚„ƒ‚‚‚„ƒ……†Œ“‘Ž‹ˆ……ƒ‚„‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€ƒƒ~~~||ƒƒ‚ƒ‚ƒ~}~€€€~}}}}~}|zzz‚‚€~€€~}€€€€€€}}€~€€€€€€‚€€‚‚€‚„ƒ†’ŽŠ‡‡†ƒƒ‚‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒ‚ƒ„…€|}}~}}~€€~}~}|}~‚ƒƒ‚‚}}~~€€€~}}}|{{{zzyz€€~~~~|~~€~€€€~~~~}|~€~~€€€~€€~€€…’’Ž‹‹‡‰…„„‚‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~~~~€€~€}}„ƒ‚€~}~~€€€~}}}}{{|zzyyy{~~}~€€~€€‚€|~~~~}|€~~€~€€~€~~~~~}||}…’’Œ‹Šˆ‰ˆ„…„‚‚‚‚ƒ‚‚ƒƒ‚ƒƒƒƒƒ€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€‚‚ƒ€€‚ƒƒ€€~}}~~~~}}}}}|||{zyyyy}€€€€€€‚‚€~€~~~~~‚€€€€~€€~~€}~}}{|†“‘Œ‹Šˆ‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…ƒƒƒƒ…„„„„ƒƒ‚ƒ‚‚‚‚~}}}~~€}}}}}}}}|{zzyyyy€‚‚ƒ…ƒ€ƒ€‚€ƒ‚‚ƒ‚€€ƒ„‚€€€€€€‚‚€€€€€€~~||Š“Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€~}~~~ƒ†‡‡ˆ‚†„…„„…„…†…†††……†€ƒƒƒ‚‚€}}}}}}~~}}}}}}}}}|{yyyyx|ƒƒ„…‚„ƒ‚‚ƒ…†‚ƒ„ƒ‚‚ƒƒƒ‚‚‚…ƒˆ…‚‚‚„ƒ‚ƒ‚‚‚‚€€€€~Ž“Œ‡ˆ‡ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€~}}}~~~€ƒ„‡ˆ„†††…††‡‡††‡‡‡†‡‡}€€‚~}}}}}}}}}}}}||~~~|{yxwxyy€‚ƒƒ„ƒ„„„——ƒƒ„}~‚‚‚‚ƒ†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ……„…ƒ‚ƒƒ‚ƒƒ‚‚‚‚ƒƒ‚‚’‹ˆˆ‡ˆ‡††„†…„„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€~}~€‚………††‡‡†‡‡ˆ†‡‡‡††ˆ‡|}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yxy|~‰—„ƒƒ„„”“€~~„‹€€€„†‰…„‚……‹ƒ‚……††„ƒ……ƒ„„ƒƒ„ƒ„„„ˆ’Ž‹‰ˆˆŠ‡ˆ‡…†…„…„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„„†…||||}}||}}}}}}}}}}||‘•–ƒ{z„”|xyz{|‚ƒ€ƒ‚€~|~~{ˆ‘||Ž–}‚†Š…ƒƒ„ƒƒ‰}ƒ„……ƒ…†…„……ƒ„……†„„Ž‘‹ŠŠŒŠ‰Š‡…†…ƒƒ‚‚‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚ƒ„ƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚ƒ}}||}}|||}||}|}}}|||{‹‘—Œz{|€zzz{|yy}}~€€|{{~~}‚•‘„ˆ~|~‚„||‚„‚€‡ƒ}‚‚‚€ƒƒ„„„„„‚„ƒ„…‚„‘‘‹ŒŒŽŠ‰‰†……ƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚‚ƒ…ƒ„…………ƒƒƒ„‚ƒƒ‚ƒ‚‚€€€~~~}||||||||||||||}|||~~Š‚{z{zxz{{|}{~}~}}}}||}†~}‚~~€‚||€‚€€~}{Š‚}€~€€‚‚€€€€‹“‹‹ŽŒˆ‡ˆ……„„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ…„††„„€†”ˆ€€~~~€|||||||||||||}|||||||y{{{xxy{{z|€~|~~}€‚‚€€€‚‘€€~€~~~€}}}{}}}}}||}€€€~€~~‚“‘‹ŒŒŠ…††…„„…ƒƒƒ‚ƒƒƒƒ‚‚€€€€€€€€€}{z|€€€x~w{€‚‚‚‚ƒ†‡††~ˆ•Š~€€€~€~~~|{{|||||||||~}|{}|||{|||zzy{|z}…ƒ‚~~€~…‚~€~~€…†‚€~~ƒ‡}|~€€€~}}}}~{|}€}~€Œ‘‹Ž‡„††…„„ƒƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}~€‚„††……~€€€~~}€€€€}}||}~}|}}}}}}|~|}|{}||z{z|}}†„‚€€}~}~~Œ„†~}||~‚}}}}€|{}|~„ƒ€~~~~}}}~€~~~„’ŒŒ‹Ž‹Š†„†„„ƒƒƒƒ‚ƒ‚ƒ‚ƒ‚€€}|||}~{{}w~vx~}|}|}~~‚ƒ€{~}|~~€€~€~~€€€€~~~~~~}~~}|~}~}}|{|||{|z}~€ƒƒ‚~|}|}|}ƒ~Œ~|{{}~}~~}{{{}{z{{{€†„‚„ƒ‚€~‚‚‚‚‚€ŠŒŠŠŒ‹Šˆ„„„ƒ„ƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€~}~~€€€€}€~~~|‚~~}}}{{}}|z||~€‚€€||}|||||}|}{~{{{|||}|{{{{||zz}z~‚~ƒ„‚‚…†……††‡†‚„ŽŒŠ‰Š†‡…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~~€€‚‚€~~€€~}ƒ||}}|}}}}{|~~~~}~|||||||~~{|{||||}|}|~|}||{{|y{|{{}{}~~€€ƒ‡‰‰‰Š‰‹‰…ˆ‹ˆˆ†……ƒ‚‚ƒ„„ƒƒ‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€~~~}€€€€ƒƒ€€€€€€€€~|z|}}~}}~~Œ†}}~{{ƒ‚}}}}}|}|}}}~|}{}|}}~|~}}}}|{{z|{||{z{{zzz{~~‚…ˆ‡ˆ‹‹‹Š‰ŒŒ‰‡†…„ƒ‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~€€€€~~€€€€€‚„ƒ€€€€~}~€~{~‘Œ|}Š€Œ~~}}}~}}~}|||}}|}|}}}~}}~~|{{{||}|{z{|yzyxy{~„ƒ„ˆ‰Šˆ‰ŒŠ‡ˆ…„„ƒ‚‚‚‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}y|zr}{{|||~~}}‚€€€‚…ƒ„‚‚‚‚€€ƒ‚€}~€~|ˆ‚~ƒ„„ƒ~}|‡}}~}||~|}}|}}}~}~}}}{|}~||{|}zzyyzy{{~~ƒ‡„ˆŒŠ‰……„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{|}}}}zx~‚€‚‚€€€€€‚‚‚‚†…„ƒ€‚„~€}~~}€€}~„€~~}~}}Š…}~}~~€}}}|~~~}€}}}|}||{|}{{{zzz{{|}~}€ƒˆŒ‰Š‡………„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv~€ƒ‚‚‚‚‚ƒƒƒ‚…†„‚€€€€‚€„~~€€}~€~}~~€€~€€}~€~€~|}}|~~~~€}‚€|}€}||}}||{||{{{|{|||}|ˆ‰‡‡…†……„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{zz||{v{tw~vr{~~{xuw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€ƒ€€€€ƒ~~€€}€}}~~€€‚€€€}€€€€€~|}}}}~~}ƒ}€~‚€}~|~~}}}{|~|}|||{|{|}ˆ††„…‡…„…„‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz}}yxtt€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚~~~€}~€}}}~€€‚€€€‚}~€€€€€~}}}~}~~}}„€~}€}}~}~~}~|{|z|{z€…‚ƒ„…„„„…ƒ‚‚‚€€‚‚ƒ‚‚ƒ„ƒ„ƒƒ‚‚‚ƒ€€~~~~~}~~~{{z~‰‡~xry}qzx{xytu}‚ƒ‚ƒƒƒƒ…„…„ƒƒ„„ƒƒ„‚€€€~}}~€~~~€}}|}}~€€€€‚€€€ƒ€~€~€€€~~~~~}~~……€€€ƒ~€~€~€~}{z{z|{z‚ƒ‚‚‚‚ƒ‚ƒ‚€€‚€€‚ƒ‚ƒ„ƒ„‚„‚‚‚‚€~€~}~~~~}~}}z{|…„{{ry{|pwuvwyvtz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€€€}}}~}~~}~|}}~€€€€€ƒ‚€~€€€€€€€€‚‚‚„€ƒ€€|{{z|{|€‚€~‚‚ƒƒƒ‚„‚„‚€‚€~€€}~~}}}~}}{{z€x|vyz|qtxwvxury……‚„„‚„……†„„‚„ƒƒ‚€€~€€|}}~€}~~}|~~~€~€€ƒƒƒ€€‚€€€€€€€€‚ƒ€„}ƒ„€€‚}z{{||}}€|~}€€~}}€~‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxzzruyyvwwsu†…ƒ……‚„„…„„„‚ƒ‚ƒ€~€~€}}}~~€~~~}|€|~€~€‚ƒ€€‚ƒ„‚€€€€€‚ƒ‚ƒ€~‚‚„€€‚‚‚„‚~{{|||}}}~}z~}~y~|||~}~€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„…„‚„„…„ƒ‚ƒƒ€}~}}}€~~~}}}€€~|~€~‚‚ƒ‡…€~~€€€€€€‚€€~€‚‚‚ƒ‚ƒƒ…‚}}}|{||yz{z~y|yx~{{{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzswvst†„„…ƒ‚ƒ„„ƒƒ‚‚ƒ‚‚€|€€~€}~}~€€€~|~€€~}~~€}€€ƒ„ƒ~}~~~€€€‚€~€~€‚‚€„‚„…†ƒ€~}||||zyvyyzyvyv~|{{{~}{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…ƒƒƒƒ‚ƒ‚‚ƒ‚ƒ‚€~€}}}|€€€|€€€€}€~~~}~~‚‚‚~~}~~~~€}€€~~~~~€‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{z{~†}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvqxyrx…………ƒ„„‚‚ƒ‚‚€ƒ€€~~~~€~}~|€€€€{€~€€€€}€~~}}}~€‚~~~~}}}~~|~€~~~‚~~€€ƒ‚ƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}}{|z{}zzx{|zz{xtxuqrtpxxqy„………ƒ„ƒ‚ƒƒ‚‚‚€‚€€€€}~~€}|~}€€€|€€~€}€~~}}|€€€€€~~~~}|~~|}€~}~€‚~€€~ƒ‚‚„……‚‚~}}{{||zw{ywxwwx{{z{|…Š}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzz{zxswuqqspxwq{…†……ƒ…‚ƒƒ‚€€€€~~}|~}€€‚€€}~€~€€€}~|}€€€€~}|~}}}~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{y{zwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{|||zzzzzzxsvupprowvr{…‡„…ƒ„‚ƒ‚‚‚‚‚€€}}~€‚}~~~€€€‚€€€~}~|€€€€~}~~€€‚€€€€€„‚‚€~|}~~z}„}t|}zzzz|yyzz†…wy|||||}|||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚€€€€€€~}€€‚‚‚‚€~€€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€‚€€~}~z’‹z|}|{}y{zzxyxy{||}|||||||}}}||}|~}~~~}|z||{|}{yzzzyysuuooqpwst}…‡ƒƒ‚ƒ‚€€‚‚€‚€€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€}~€~}€€€€€€€€€€€‚‚€€€}~|†ˆ||~{{~yz{z{~wwy{|{}||||{}|}|}}|}|~~~~|z|}{}}{yz{zyxstunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}€~~€€€€€€€‚‚‚€€€€€€}~€}€ƒ‚{~~{|}{z||{‡yxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€€€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ„„€~‚€€€€‚~€€‚€€€€€€€€€~}€~€€€€€€€€€€€€‚€€€€€~}~}~~{}|}|||wxuxxy{||}{||||}~~}}~€€€|}||}{z{yz|xzsrunwqqzqvw……ƒ„ƒƒ‚ƒƒ€‚…ƒƒ„ƒ‚‚€€€‚ƒ‚€‚‚…ƒ€€~‚ƒ€€€€€€€‚€€‚€~€€€€€€€€€€€€€€€€€€€€€€‚‚‚‚€‚‚€€€‡~~|z}|{}~xwvyyy|}|||{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚ƒ„„€€‚†ƒƒƒ‚„€„ƒ‚‚€€‚‚„‚‚„‚€€ƒ‚€€€€ƒ~€ƒ‚}‚€€€~€€€€€€‚‚€‚ƒ‚‚ƒƒƒ‚€€€„}}}|}z}€zyvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysruowqwysw{…‚‚ƒ‚ƒ„‚ƒ„ƒ€€‚ƒ†ƒƒƒ‚‚„„ƒ‚€€‚ƒ‚‚‚~€€‚‚‚‚€€€€‚„€~ƒ‚~€ƒ‚€~€‚ƒ‚€ƒ‚ƒ‚ƒ‚‚„€ƒ‚„ƒƒ„„ƒƒ„ƒƒ‚€‚€}€|z|{{w|yyy{z}~}||||}~~€€€ƒ„€}€~{{{z{ztpxrytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚‚„†„‚ƒƒƒ„„„€ƒ€ƒ‚‚‚‚‚€‚€~€€‚‚‚‚‚€ƒ‚‚ƒ€~ƒ„„ƒ‚‚ƒ‚‚‚„ƒƒ„‚„‚ƒ‚‚‚‚ƒƒ„ƒ„„„„„…ƒ„‚ƒ‚‚ƒ€€~||€||x|yzyz|}|{||}}}||€€€€€‚~€€€€{{|zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚‚…„„ƒƒ‚ƒ„„…‚‚‚ƒƒ‚‚‚€€}€€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€‚€€‚„ƒƒ‚‚‚ƒ‚‚ƒƒƒƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{~~}y|zzz}||}z||}}|z{~~~€€€€€€€€}}||}|vrvxxvtvt}‡‡ƒ‚„…ƒƒ„…„€‚„…„„ƒ‚ƒ„„€„…ƒ‚‚‚ƒƒ‚ƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚‚‚ƒ„‚‚€€‚€ƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒƒƒ„ƒ€‚ƒ‚„ƒ‚‚~ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz{}}||z|~}}}}~~€€€€~~€€€€~|}}~~}|{xvuv„‡ƒ‚ƒ…ƒƒ„†„‚…†…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚ƒ~€€‚‚ƒ‚ƒƒƒ„‚‚‚ƒƒ‚ƒ‚ƒ„„ƒƒ‚„‚„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒ„„„„„„…„ƒƒ„…„„„ƒ‚€}‚€}||{||€}}~€~~}~||}}}~~~€}}~€~~}}}~}}~~€||‚‚ƒƒ†ƒ„ƒ†„‚ˆ‡…„ƒƒ„„…‚„……ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒ‚ƒƒƒƒƒ‚ƒ€‚…ƒƒƒƒ„ƒƒ„ƒ‚„„…ƒ‚‚ƒƒƒ„ƒƒƒ„„„„……„„„…………„ƒƒƒ}„}}||||~}~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒ„…ƒ„ƒ…~‚Š‹…„„ƒ‚ƒ…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…ƒ„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ…ƒƒ……„……‡‡†‡…„„…„ƒ~~|~}}€~||~~|z|}}}}}~~~€}}|€€~~~~~€‚€……„ƒ…„‚„ƒ†€‚……Š‰„„ƒ„……ƒ‡††„„„„…„…„„ƒ„„‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ„}uzƒ€~„„‚ƒƒ‚ƒ„ƒƒ„…ƒ„…†„…†}„y|~ƒ{…ƒ€„ƒ~}~}}‚ƒ}{}~€~}{||}}}}|}}€‚}}|€€€€‚‚ƒƒ‚‚†„„„†„ƒ„…ƒ„†„Šˆ………ƒ……„†††ƒ„„………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚„usqƒ†tpurstƒv{}u‚ƒ‚vy…€ƒ€„…„‚……‚hzrss|€s‚ƒƒƒ}}}~}~‚ƒ|}€}}||||}|||~}~€}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ…ƒ†ˆ††…ƒ††‡‡†‡ƒ……†…ƒ‚…†„……ƒƒƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vzy…r„ƒpvxqvtturstvi€nrotvnulwm{sn€ˆym}rsvsvmmxlpylu}~}~€}€~}€€}}||}}|}~}€€€~|~€‚€€€€€€€‚ƒ‚ƒ„…ˆ††€‚…ƒƒ„‡†ƒ………†‡‡„ƒ†‡ˆ‰†‡„…†ˆ‡„ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoomw}x†pqzprtfu~n{ysoy€}}€|}|~€€~~€€€~~~€~}€}€€~~€‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„†……††ˆ„„†‡ˆˆ†‡…††‹Š…„†‡‡…„………„‚…………†……†…†quprsoszy~ƒtˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„qjoyxpkyszozwvvp€~~~z~}}}~}€ƒƒ€‚ƒ„€€}~€~}~€~~‚€€„‡†ƒƒ†„„…†‡†…………††ˆ…„†…‡†…†„††‰ˆ…„‰Šˆ…„††……ƒ……„…††††…ƒx‹yrˆz{pp……x…xyks~y{krƒ‡ƒz|m{yyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|tpozls|nw‚€~~}}{}{|}}~}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡……………‡‡ˆ†„†…†††…„……………†‰‰‡…„†…††…††„††‡††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ††……ƒ„††…†„†„ƒ„„†„„„ƒ„„…„…„…„†ƒ†‡…†„„…‡†„„……„…}w…„„„ƒ‚}~{|{~{||}~}|~~€€}€~~~€~~~~}}}~|{|~||‰†…„†††…‡‡…………††‡ˆ†„†…††……ƒ……†…„††††……†„…††††…††‡‡†…‡ˆˆˆˆ†„‡…†‡ˆ†…ˆ‡ˆ…‡††ˆ……†‡…††…„ƒ……†……ƒ„„„„…„……„……„†‡††…„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ‚}€{{|}{||}~||~}€}~€~~€}}|€}~~~~~~||}~{|||{{~ˆ‡„„ˆ†††‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡……†……†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ…„ˆ…†‡‡‡†ˆ†‡…‡‡†‡……†‡…‡†…‚ƒ…††„„ƒ„„ƒ„†„………††„††…†…„††…„ƒ……‚…‡…ƒ‚‚…ƒ„~€€|{}~{|{}~}||~}~~|~}}~~}}||~~|}€|||}|||~z{{}~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†ƒ…„‡†„…‡ƒ„…„…‡„…††…†„††‡‡††ˆ‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…‡‡†‡†‡†‡…ˆˆ‡‡…††‡…‡‡…„„…†……„„„ƒ„……†††…†„‡††‡……††…„ƒ„ƒ‚„‡ƒ„‚„„ƒ€€€{{~~|||}}|||}}|}|~}|}}|||}}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††„…†…†††…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡…‡†…‡‡‡…‡†ˆˆ‡‡…‡‡‡…†‡„‚„ƒ„†…‡……„ƒ„„…††††††‡††ˆ…†…†…„‚ƒ‚ƒƒ‡ƒ€‚ƒƒ‚‚‚€{}~~{||~}|}}|}{||||||}{{{}|{~|{|}}|}}}|zz{{||ˆ‡‚††††‡††…„…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡‰ˆˆ‡†ˆŠ‡†‡‡‡ˆ‰‡…ˆ‡†ˆ‡††‡‡…‡†ˆˆ‡†…‡†‡††‡ƒƒ„„ƒ††‡……„„„…†††††…‡‡‡‡ˆ††„†…ƒƒ‚‚‚ƒ†ƒ~‚‚ƒ€ƒƒ|~~||}}|}}|}z{{z{|||{{{~{{}{{{~||||}~}{z|z|}‰‡ƒ†…†…††……„……………„ƒ…†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…‰Š‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……‡ƒ„†…„††‡†……ƒ……††††‡…‡†‡‡‡‡…„……ƒ‚€ƒ…‚ƒ~ƒ~~~||}}{}}|}zz{y{|}{{{{~||||z{}||||~}|{{{{|{‰‡„†„†„††…„………„„ƒ„‚€ƒ…‚‚z„Œ{€„…‡†††…„‡ˆ‡†‡……‡Š‡„‡…‡†ˆ†…‡„†‡‰††ˆˆ‡‡†‡ˆ†„†††‡†…‡ƒ„…„†††‡……„ƒ……‡…‡†‡…††‡†††„ƒ„…€€ƒƒƒ‚}€~ƒ~€||}}~}{~}|}yzzy{}}zz{{}|}||z{}||}|~~€|{{|~}|ˆ‡…†…†„†………………ƒƒƒ€…‚€€}|{„…††„…„ƒ‡‡†††…„†‰†‚†„†††……‡…‡ˆ‰†…ˆ‡‰‡††‡…„†……†…„‡ƒ„…„ˆ††‡……„‚†…†…‡†‡„†††……†ƒƒƒ„€€€„€ƒ€|€~~‚€}€||}~}~{~}||yzzyz}}yzz{|{|{{z{}}|}|~~~|{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€€ƒ~~~€yz}€ƒƒ…‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡†ˆˆ……ˆ‡‰‡†…†…ƒ†„…‡ƒ„†„„…„‡†…†…†„ƒ†…†††††„…†‡……†‚‚ƒƒ~€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|{{{{|}}}|~}||}~|{ˆ……††††„…„…ƒ…‚€€€€~€‚‚}}{‚ƒƒ…†…„ƒƒ†ƒƒ„‚€…‡…‚ƒƒ„„„…†‡ˆ‡……ˆ†‰‡…ƒ„„‚…ƒ„†‚ƒ………†„‡†………†ƒ„…„…†…†„ƒ……†ƒ……ƒƒ~€~ƒ{€}}‚}€~~~}}}}{|{zyzzyzz|yzzz{{|z{{{|}~}}}}||}€}|†ƒ††††…ƒ„ƒ…‚…€€€~€|~~€€‚‚‚„…ƒ‚‚„€ƒ‚€„……‚€‚ƒƒ„…†ˆ†…„…‡…‡……‚ƒ‚ƒ‚‚…ƒ…„…†„††‡††…‚„„ƒ„†……ƒ„„ƒ„ƒ…„€€‚‚}}~~€„~{||€}€}}ƒ|~~}}~{~{{zyzzyzz{yzzz{{|z{|{{}~}|}||}€~€†„……„‡„ƒƒ‚†‚ƒ€€~~€}|}~~~‚„ƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡†„„††„…ƒ…‚‚‚ƒ‚„„„……†‡‡†…„ƒƒƒƒ„†…„ƒ‚ƒ‚„ƒƒ€€~}|~~|ƒ}|~||€~‚}‚|~}||||{{zzzzy{zzzzzzz{|y{}||~€}~}}}€€€†„„…„…‚ƒ‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„†„ƒƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…„……‚‚‚ƒ…„‚‚€…ƒ~€~||~}|~ƒ}{~|}€ƒ~}€~}|||}{{zzzyy{yzzyzz{{{z{}||‚€~€€€€€ÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÌÌÌËËËËËËËËËËËËËËÌËËËËËËËËËËËËËÌÌÌÌÌÍÍÍÎÎÏÏÏÏÐÐÐÑÑÑÒÒÒÒÒÒÒÓÓÓÓÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÔÔÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÓÓÒÒÒÒÒÒÒÑÑÑÑÑÓdžse`[KYgUMFH@=77897<<<:<;>6:=8<;:9878;;:?;=;<<>;?A?BBACDEDA>=<;@CCA@CCAAGHGIKRÂÕÒÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌËËËËËËËËËËËËÌÌÌËËËËËËËËËËËËÌÌÌÍÍÍÍÍÎÏÏÏÐÐÐÐÑÑÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÒÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÓÓÓÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÓÔÔÔÔÔÔÔÓÓÓÓÓÒÒÒÒÒÒÑÑÑÒ̌rg`\MYeRKGK?;378;89>=9<:A:;=7:<<::78:;=?;?<=<?>?A=AA>CCDB@A>:;?CDACDDBBIGHHIN¾ÕÒÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÊÊËËÊÊÊÊÊÊÊËËËËËËËËËËËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÌÌÌÌÌÌËËËËËÌÌÌÌÌÌÌÌÌËËÌÌÌÌËËËËÌÌÌÍÍÍÍÍÎÎÏÏÐÐÐÐÐÑÑÒÒÒÒÒÓÓÓÓÓÓÓÓÔÓÓÓÓÓÓÓÔÔÔÕÕÕÔÔÔÔÓÓÓÔÔÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÒÓÓÓÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓÒÒÒÒÑÑÒϒwh_^OWgMKFL=8765999<>9?<D9;<8:<=;979:<=@;>=>;<><=>A@>DCCC?A=:;=BCECCDA?EHJIJLºÕÓÓÓÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËÊÊÊËËËËËËËËËÌËËËÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÏÏÏÐÐÐÐÐÑÑÒÒÓÓÓÓÓÓÓÓÓÔÔÔÔÓÔÔÔÔÔÔÔÔÕÕÕÔÔÔÔÔÓÔÔÔÔÓÓÓÓÔÔÔÔÔÕÔÔÔÔÕÕÔÔÓÓÓÓÒÒÒÒÒÒÒÒÓÓÓÓÔÔÕÕÕÕÖÖÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓÓÒÒÒÒÓÓÓÔÔÔÔÕÕÕÕÔÔÔÔÓÓÓÓÓÓÓÒÒÒÑÑњ~gabNUjJHIK?<:937677=;>9=:::89:;;88:;;<>:===:<?<=?B@?CDCD>@==<@CDCBDBD>DHIIKL¶×ÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÎÎÎÏÏÏÐÐÐÐÐÑÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÔÔÔÔÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÔÕÕÕÕÕÔÔÔÓÓÓÓÓÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÒÒÒÑҟƒi_dSXlHHHK@=78476::?;D<<9<<97:9;::;<::;9>=>9=@;?AAB?BBAC=??><@BECCB@A;FIGMLI²ØÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÕÕÕÖÖËËËËËËËËËËËËËËËËËËËÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÐÑÒÒÒÒÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÓÓÓÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÔÕÔÔÔÔÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÓÓÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÓÓÓÓÓÒÒÒÔ£ˆl_fRVjGHGIA>366:;<8C<BA><A<89:<::<<<9<=:;<==<?=@?@A?@A@B<>>?<BCCCF@AA=HJINMG®ØÓÔÔÔÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌËËËËËËËËËËËËËËËËÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÏÏÏÐÐÐÐÑÑÑÒÒÒÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÔÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÔÔÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÒÒÖ®ŠkceRXhLJGIB8494:;:9@9?CE@<<999=:=;<<:=<;9<=;;?=@==>@@?BA>@<=9@DCBAAB><HJKMNH¨ÙÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌÌÑÓÓÓÓÓÓÓÓÓÓÓÓÓÎÊËËËÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÏÏÏÏÏÏÏÏÏÏÏÏÐÐÑÑÑÑÑÑÑÑÑÑÑÒÒÑÕÙØØØÙÙÙÚÚÚÛÛÛÛÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÙÙÚÛÛÛÛÛÛÛÚÛÜÛÜÛÙ××××××××ÖÖÖÖÖ×ÚÚÚÚÚÚÚÚÚÚÚÛÜÜ×ÕÕÕÕÕÕÕÕÕÕÕÖÖÖ×ÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÓÓÔÔÔÔÔÕÕÕÕÖÕÕÕÕÕÕÕÔÔÔÔÓÓÓÓÓÓÒÕºŠkhhRXeIILO@99:4;A<7=9AC>@?=8::;9=;>?:;<<:;<:;>=@=???A@AA?A<<;>ADCAD@=<IIJMNF£ÚÓÔÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÌ̈́mpppppppppppj§ãÝÝÞÞÞÞÞÞÞÞÞÞÝÒÐÐÐÐÐÐÐÐÐÐÐÐÑȹ¹¹¹¹¹¹¹¹¹¹ºº·¥¤¤¤¤¤¤¤¤¤¤¤¤§†`cccccccccddde„‹ŠŠŠŠŠŠŠŠŠŠŠ‰’™˜˜˜˜˜˜˜˜˜˜˜˜—Œ‹ŠŠŠŠŠŠŠŠŠŠŠˆ ¿¼½½½½½½½½½½¾´ŠŠŠŠŠŠŠŠŠŠŠŠ‹‡½æáââââââââãããâØ××ÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÔÔÔÔÔÓÓÓÓÓÕÑqkjNSbLLVN<::77>C>8>:??A<?@7;:;;=;>>:;<><;=;=?>@<??=@@@A>?<><@AEBBF@@?GHJKOFžÚÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××ÌÎN&+++++++++++"ŠôëëêêêêêêêêêëéÕÒÒÒÒÒÒÒÒÒÒÒÒÔÄ©ªªªªªªªªªªª«¦†„……………………………ŠNJTSSSSSSSSSSSQblkkkkkkkkkkkkiUSSSSSSSSSSSSNz¯ªªªªªªªªªªª¬›SRSSSSSSSSSSSKªòëëëëëëëëëëëëéÙ××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔÓÔ˘vliJN_MRUM><<7;@C>6:7=?;=B?9<9=;<:<=;=;=;;=<=>==;A=<A@AA=<?<;@BCADE=A@CFKKOF˜ÜÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××××ÍÎR+11111111111'óééééééééêêéêéÕÒÒÒÒÒÒÒÒÒÒÒÒÔŪ«««««««««««¬¨ˆ‡‡‡‡‡‡‡‡‡‡‡‡RNYWWWWWWWWWWWVepoooooooooooomYWWWWWWWWWWWWS~°¬««««««««««®XWWWWWWWWWWWWO«ñêêêêêêêêêêêêéÙ×Ø×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÔÔќzqiJT]ORUND>?;>@@8:;8<;;<?:;;8;99;<;:<9;;<;:===>=A?>??>=<=?<<AACADE<>@EFJKMF“ÜÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××××××××ÍÏ\9===========5“ðççççççççççççæÕÑÒÒÒÒÒÒÒÒÒÒÒÓÅ­®®®®®®®®®®®¯«Ž’]"''''''(((((')Zcbababbbbbbbaoxwwwwwwwwwwwwucbbbbbbbbbbbb^…²¯¯¯¯¯¯¯¯¯¯¯±¡babbbbbbbbbbb[¯ïééééééééééééçÙØØØØØ×××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔÔÖ£{qdI[`NNUO@A?=DB?;=:9;:==;<;:9899;<;<<::;<:;@=<=<@A<AA;;<@?<=B?DCCE<>BDFJLLEÜÕÕÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÍÍÅÂÃÃÃÃÃÃÃÃÃÃÃÂÉÐÏÏÏÏÏÏÏÏÐÐÐÐÐÏÎÎÎÎÎÎÏÎÎÎÎÏÏÍÌÌÌÌÌÌÌÌÌÌÌÌÌËÉÉÊÊÊÊÊÊÊÊÊÊÊÊÇÂÃÃÄÄÄÄÅÅÅÆÆÆÆËÌËÌËÌÌÍÌÌÌÌÌËÍÎÎÎÎÎÎÎÎÎÎÎÎÎÍÌÌÌÌÌÌÌÌÌÌËËËËÏÓÓÒÒÒÒÒÒÒÒÒÓÓÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÔØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØ××××××××Ö××××××ÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÖÕÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÔÔÔÔÔׯp^F^bPQWNGFCCIA?=;<:<8@B<=8::898;?;<<;;<<<<?;<>:>>8>B<>=A><>B@DEC@<>@>CIIKD‡ÜÕÖÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØØØÎÍÏÐÐÏÏÏÏÏÏÏÐÔÐÐÎÌÍÌÏÓÒÒÎÍÏÒÎÎÎÎÎÎÎÑÔÔÓÎÐÔÒÏÎÐÔÒÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÐÑÑÑÑÑÑÒÓÓÔÔÔÔÕÕÕÖÖÖÖ×ÖÖÖ×Ö×××××××××ÖÖ××××××Ö×××××Ö××××××××ÖÖÖÖÖÖÕÕÖÕÖÖÖÖÖÖÖÖ×ÖÖØØØØØÙÙÙÙÙÙÙÙÙØ×ØØØØØØØØØÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØ×××××ØØ×××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÖÕÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÔÔÕÕظ‚oWJ_cRQZKHAA<B==;:>><>?==?79:9978><<>;;<;<;?==>9;;9=>?@>@=;:B?BCB?=>@>BEGJB€ÜÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØÎÎÎÎÎÎÎÍÍÍÍÎʟÊÍÍÍÍйƒ„‹ÇÓÀšËÏÎÎÎÎÑ°ƒ„“Ïɔ¨ÒÐƓ«ÒÎÎÎÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÐÐÐÐÐÐÐÐÑÑÑÑÒÒÓÓÓÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÕÕÕÕÕÖÖÖÖÕÕÕÕÕÕÕÔÔÔÔÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØ×××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕØÀ€nUO`cWY[LLC@==;=:<>B>BC@<:898:::7;?>?<<;<:9?<<=89<?A>===A@=;AB@BC>;@?AAIGJAzÛÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙØØÙÙÎÎÎÎÎÎÎÎÎÎÍÒ©­ÑÎÎÎΛ·¶¤¢À“ž¬ÓÎÎÎÏɛº¸¬ž«›°Ð™­™³ÒÎÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÑÑÒÒÒÓÓÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÕÕÕÖÖÖÖÖÖÕÕÕÕÕÕÕÔÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖ××××××Ø×××ØØØØØØØÙØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØÙÙØØØÙØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕ×ÈoZSae^]\OJD=@?>;7:>9?D>A98789;;<89?==<=<>;:A;9;9;<C@<;=>@A>=BD?BC==?>?>HIH?uÚÖÖÖ××××××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÎÎÎÎÎÎÎÎÎÎÏȞ¼¦ÒÐÐÎÊ —~‚曯§ÔÏÏÏÑ⏊”‡œžÅ“†ÎÏÎÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏÏÐÐÐÑÑÑÑÑÒÒÒÓÓÓÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÕÕÕÕÕÕÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙÙØØØØØ×××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÖÕÕÕÕÕ×͈s]Xih^_`OIF:A@>?<<:6?B@C:647:;:<:9><>==;?=<A><<:<<=<:<@=@B>>AB=CC==>;?AEKH@pÙÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÏÏÏÏÏÏÎÎÎÎÒ¬¥§©ÕÀ¼ÒǝžËÓɊ™ªÔÏÏÏÑ¿žŠ¨ÐԻȘ™Æ½É–™ÆÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÐÑÑÒÒÒÒÓÓÓÔÔÔÕÕÕÕÕÕÕÖÖÖÖÖÕÖÖÖÖÖÖÖÕÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÖÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙØØØØ××××××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖАu[[jia^]SNI<C@A>@>:8FA?C:749::9;;8;=?>>=A=<?@=><<<<<:=@@??=>B@?@B@<@=>AEKG?k×××××××××ØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÏÏÏÏÏÏÏÏÏÐ̝—¬Ðš—Ê޲ž–ÍÖ­™ªÔÏÏÏѺ¥­œžÒє–ŸÎё˜ ÎÐÐÐÏÏÏÏÏÏÏÏÏÏÏÏÏÏÐÐÐÑÑÒÒÒÓÓÓÓÔÔÔÔÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ×××××××××××Ø××ØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØ×××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÖҔr^^kkje]OLG?DCC@:=;<B<>=964:99::97;?@;<=@<<A><=;=<?<:<C@>=;=@>B>@A>@=@?FID?fÕ××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÏÏÏÏÏÏÏÏÏÓ±¢€›¯É £¿Êœ¥Œ§­Øª™ªÔÏÏÏÑÀ Ÿ“¥¼³ŸÂ›Ú­£¿ÕÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÔÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÕÕÕÕÕÕÕÖÖÖÕÖÖÖÖÖÖÕÖÖÖÖÖ××××××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ××××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖғp`^phfeZQHGBEC@@7::<>:<97659:6:<;7<@@<::=:=?>=<9@<<::9?@>=<=@AC?@?>A;?@FJB?bÒØ××ØØØØØØØØØÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏÐϐlœ–ת£ÓÒ®¦µ˜ŸÕª™ªÔÏÐÐÐÒ¦¯®›§Ð‹“žÇˈ•žÈÒÑÑÐÐÐÑÑÐÐÐÐÐÐÐÐÐÐÐÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖ×ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×ÖÖ×××ØØØ×××××ØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ÖÖÖÖÖÖ×ғn`\qdgdZUJ@CFCAB8;?<=;<<8558968;:9<:>?<==9<?>=::>9<::8>?<==<>@ACA><<:BDDJFB]ÐÙ××ØØØØØØØØÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÏÏÏÏÏÏÏÏѽŸÃ·Ö—ÀÓÑÐÒÊÒ͗›Ôª™«ÕÑÏÐÐÑÉ×Ę¡ÐÚ¥™³ÐÛ¢™µÕÑÑÑÑÑÑÑÑÑÑÐÐÑÑÑÑÑÑÑÒÒÓÓÓÔÔÔÕÕÕÕÖÖÖÖ××××××ÖÖÖÖÖÖ××××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØØØØØØØÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØ××××××××××ÖÖ××ÖÖ×××××××××××ÖÖ×ёl]\oghb]OF@HIGE@<<>><=><756:969;::;8@?:<<9<>=;;:?9?:;9=>==;;=<@CB??>;CFFGHDYÍÚØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÛÛÛÐÐÐÏÏÏÏÏÏϕ~{¥’Ô¢šÓ̒—£›¡Ø«™«Õҗ¦Õōž ž ’§™ ­¨˜ž»ÕÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÓÓÔÔÔÕÕÕÕÖÖÖ××××××××××××××××××ÖÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ××××ØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØ×××××××××××××××××××××××××Ö×όdV^pk\``NEHMIIOC>:B==@B;557<:7:;::;9==9::9=>?=;9>;<:<;9><>;<=>@CB?>A<ACGFFEUÉÛØØØÙÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÜÜÜÜÜÜÐÐÐÐÐÐÏÏÏÐÑÕ§™­É£¨¾Ê±£µÙ©›©Ø¸«¡ÉÁ¡­¡£¥¦¤¨ ¯§¢©œÐÓÒÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒÓÒÓÓÓÓÔÔÔÕÕÖÖÖÖ××××××××××××××××××××ÖÖÖÖÖÖ×××××××ÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖÖ××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙØØØØØØ×××××××××××××××ØØ×××××××Ø͆]WbodO]TKHFSQKL@>=D<?CF=557;96:;:<=:;?::98:==?>;?;>=:;9>;=<=>ADB@?>?<@AEGEDRÅÛØÙÙÙÙÙÙÙÙÙÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÜÐÐÐÐÐÐÐÐÐÐÐÓ¹€½Ó›–ÏÔµ‹‘ŸÓÔ¼»ÔΔ ÓÕ«ªÖœ‘ŽºÕš‘Ž¾ÖÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÔÔÕÕÕÖÖÖ×××××××ØØØØ××××××××××××××ÖÖÖ××××××ÖÖÖÖÖÖÖÖÖÖ×××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÚÙÙÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØ×××××××××ØØØØØØØØØØØ××ÙË~ZUjj[L_MJLJULFB<=?GFHKH=657:979:;:<=9>99:8;=>>A>=9<<:=>>:=99:?EA@>=??B@GEDEPÁÜÙÙÙÙÙÙÙÙÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÜÜÐÐÐÐÐÐÐÐÐÐÐÐÑÁÑÑÊÈÒÐÔĸÒÒÑÒÂÒÐÓÇÌÒÑÔÁ¾ÕÓÓ¹ÇÖÓÓ¸ÈÕÒÒÒÒÒÓÓÓÓÓÓÓÒÒÒÓÓÓÓÔÔÔÔÔÕÕÕÖÖÖ××××××××ØØØØØ××××Ø×××××××××××××××××ÖÖÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙØØØØ××××××ØØØØØØØØØØØØØ×ÚÇw\RgiZNZNLPQWEJ??=?AELL@>775;8899:;<><>8::9;>?@=>>:5::;=?:;9:<>BB@????ABGDCDN¼ÝÙÙÙÙÙÙÙÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÐÑÑÐÐÐÐÐÐÐÐÐÐÒÐÐÑÑÐÐÑÓÔÑÑÑÑÓÑÑÑÒÒÑÑÑÔÕÒÒÒÕÔÓÓÓÖÔÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÖÖÖ×××××ØØØØØØØØØØ×××ØØ××××××××××××××××××ÖÖÖÖÖÖÖÖ××ÖÖÖÖÖÖÖÖÖ×××××ØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÚÚÙÚÚÚÛÚÚÚÚÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØÛÁsXUikSLRNPRYTFI<>C?ABEJ>>786977899;;=?@<=89;;;?><<95:=>;99;<???BBA=A=@ABFBBBKµÞÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÓÓÔÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÖ××××ØØØØØØØØØØØØ××ØØØ×××××××××××××××××××××ÖÖÖ××××ÖÖÖÖÖÖÖÖ×××××ØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØÙÙÙÙÙÙÙÙØØØØØØܼoTTllLKRJTRUKFD:>GDDADF<?89:9599:7<=;>@==79:;9>;9966:=@A>;<9:>?CA>?B=>BCEBABJ°ÞÙÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÖÖÖÖÖÖ××××ØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××××××××ÖÖÖÖÖ×Ö××××ØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØܶkS[pkKUWR\QWHD><BJE=HJ?=<788:59896;><=@<<599<:?;9848<==AA<>;:<>@?=>A==CFGB?BIªßÚÚÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÒÐÏÔÐÎÏÒÒÓÒÒÒÒÒÒÒÒÒÒÓÓÓÔÔÔÔÔÔÓÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÖÖÖÖÖ×××××ØØØØØØØØØØØØØØØØØØØØØ××××××××ØØØ××××××××××××××××××××××××ØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝ°dSar_OZTW_QRGB=EILAALD??;:889386869>=>?=:6:;>;==:968:=;@@<@?=??B><><<BEGIB>CI¤àÚÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÒÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÑÓÓѹ»Ìº›œºÐÈÓÓÒÒÒÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ××××××××××××××××××××ØØØØØØØØØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÛÛÚÚÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÞª_U`n[UYQZ^OLGCFMIFDDJ;AA;<886486987<?A?=:7<?><??;:688==@A=@>A@=@:;:>=AEGIB@CGžáÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÓ¾Àʚ ¢•ˆ‘žª“©ÏÔÓÓÓÓÓÓÓÓÓÔÔÔÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖ××××××ØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØ××××××××××××××××××ØØØØØØØØØÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÞ¢\U^nX^]NZPTNCCLIIIFJD<BA<;876797799=?A?<:9@?<>B?:8776=??@=@A??<=;;8><?EIHA?CF—áÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÓÓÓÓÓÒÒÒÒÒÒÒÒÒÒÔȕœ®›™µ‰}“Œ‚„ÄÕÓÓÓÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖ××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØ×××××××××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙݚZXanYaWOWMPEBDLIMKFIE>BD98867975698==A>:89>><?@?<5676<>?>;@@@?>>?>;?>ABFGB@CH‘âÛÛÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞßßßÔÓÓÓÓÓÓÓÓÓÓÒÒÒÒÓϨ~‘¬’ŽŒ†€ˆ‰„£ÊÔÓÓÓÓÓÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØ×ØØØØØØØØØØØØØ××××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÚÙÚܒZYcnZZRU^PL<@GNHRIHE>;HF89757875898;>>=;89A>=@?A>7596;>AB??@@BB?>?>A@DAFHB?EJŒâÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞßßßßßßßÔÔÔÓÓÓÓÓÓÓÓÓÓÓÖµ¥šˆ‹…€…‹ˆƒŠ‹†ÂÖÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖÖÖÖ××××××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØ×××××××××ØØØØØØØØØØÙÙÙÙÙÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛۈZ[gj\XLZ_VH:LHLJJCEFC@LH7:7678858789<<;;98@?=>??<67<47?BBA@@???A==?@>@@FE==DKˆâÜÜÜÜÝÝÝÝÝÞÞÞÞÞÞÞÞÞßßßßßßßßßÔÔÔÔÔÔÓÓÓÓÓÓÓÔŒ‚ƒ…†}‚}|y~‚ƒ~¤ÛÖÔÔÔÔÔÔÕÕÕÕÕÕÕÖÖÕÖÖÖÖÖÖÖ×××××××××××××××ØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÙÙÙÙÙÙÙÙÙÙØØÙØØØØØØØØØØØØØØØØØØØØØØØØ××××××ØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÜÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÛـZ^mhZSI][XJDMHJSLGFA@?JB8;669975868;:;:<98==;@=;:65<7;=B@AA<>=@A=<@??>BDE><DKƒâÜÝÝÝÝÝÝÞÞÞÞÞÞÞÞßßßßßßßßßßßßÕÕÔÔÔÔÔÔÓÓÓÓÓز„¨}ƒyv„ˆ{wy‚~~‹®ÀÕÔÔÔÕÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÚÚÚÚÚÚÚÚÛÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÚÚÚÛÛÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÖy\ZlfXRO`QRAHGJFXLF@@CCK?;;788765768:9<<:=;?=;=><;88<9=?BABC<<?AB>=ABCBDEC@;CL}áÝÝÝÝÝÞÞÞÞÞÞÞßßßßßßßßßßßààààÕÕÕÔÕÔÔÔÔÔÓÔÒ»žŸuŠy{ˆ€€‚…ƒrs€…ƒŒ¬×ÕÔÕÕÕÕÖÖÖÖÖÖÖÖÖÖÖÖÖ××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙØØÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÛÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÛÛÛÛÛÝÐr]_peWKPcOKBGCJHKFA<A=HPA::77876787<:8==<>;@?<?=;:;9:9<@B@BC@=A@?=@BCCA@@?@;EMxàÝÝÝÞÞÞßßßßßßßßßßßßàààààààààÕÕÕÕÕÕÕÕÔÕÔ×Èx‹…|‚ˆzƒ„~‚‚sit…‹†ÔÖÕÔÕÖÖÖÖÖÖÖÖÖÖÖ×××××××ØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÜÜÜÜÜÜÜÛÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÞÊj\cqeROX^K?GLIOKE@>AB?IO>9:76;76:;7;:8:<<>;==;><:;89:89ABBA@@;@B=:>ABC?>=>?=FNtßÞÞÞÞÞÞßßßßßßßàààààààààààààáÕÕÕÕÕÕÕÕÕÕÖΝ†™~““Š‚|}‚sq›‰€‚ƒ‰ÀÙÚ·´Ð×ÖÖÖÖ××××××××××ØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛßÀcZ[m`VPSSJDLHMHI<>ADCFND<<979:68;97<989<=;9@>:A?<757;8:@AEA?>9=B?;=BBB:>=;=>FNqÞÞÞÞÞßßßßßßßàààààààààààáááááÖÖÖÖÖÖÖÖÕÖØˊ€‡…ƒ—Œx{{yo}ukw›tv{x‰ÇƘŒ­ØÙ××××××××ØØØØØØØØØØØØØØØØÙÙÙÙÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÜÛÛÛÛÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜÜÜÜà·cWYkbRMUQLJKFKFC@>BA?EM>>=899:79:75=77:><;;B<9?=9668=9:@BF@>=<@BD@=@?C;@=<>?FOmÜßÞÞßßßààààààààààààáááááááááÖÖÖÖÖÖÖÖÖ×Õ­†zw}«Ÿyxz{stƒ~oq{yzs{v“Š…€‰¤ÍÙØ×××ØØØØØØØØØØØØØØØØØØØÙÙÙÙÚÚÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØØØÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÜÜÜÛÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜá­a[^lbRMVLMGKKDFBB;A=<ELCA>8:9:77966:5;>@;=;?=<?=:99:<9<ECF@?>@CBD=9=?A=B?=@>GOiÛßÞßßßàààààààááááááááááááâââÖÖÖÖÖÖÖÖ×И‡ƒ}zƒv{uszyzª¦wrr~‡‡‡€€~‚„„‘ÉÌÙ××ØØØØØØØØØØØØØØØØØØÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÙÙÙØØØÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜá¥_TbmbPOSIHGFJIIBA>BB<EED@>8:8;77:7886>?=;<9=<:>=;:67;6:DAF>???>CA?;==>;DC?><HOgÙàßßßàààààááááááááááââââââââÖÖÖÖÖÖ×ØØÈ~vvƒ~~tvx†‚zyuwœ¡»¡„‚€€~‡ŠŠ|†Œœ¨ÎØØØØØØØØØÙØØØØÙÙØØØØØÙÙÙÙÚÚÚÚÚÚÚÛÛÚÛÛÚÛÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÝÝÝÝÜߚ[Ogk\PQPICOJKGLGJB@?AGD@A<8<885897677@@?;<9>=8=<<:78=9?DCF>A?B@C?<:>=?>ED?=;KQc×áßàààààáááááááâââââââââââããÖÖÖÖÖ×ÕÁÜ´nxrs{pzyv…ˆ„{x}€˜¥Œ|~{‘…–‹†ƒŽ‘½ÝÙØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØÙÙÙÙÙÚÚÚÚÚÚÛÛÛÚÚÛÚÚÚÚÚÚÛÛÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÙÙÙÙÙÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝލXWhnYPQKHJSIMHMIKAC?CFBAD::<864887666?>>:<9<;:==<<8;<;DDDE>?>B>B?8=??CCB@A>;LTcÕáßàààááááááââââââââââââããããÖÖÖÖÖ׬”¶zxrow•{t{‹€xun~…ƒ{…ˆr|}›œŽ‰Š‚~ƒ}‡“šÇÔØØÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÙY`hl\QKGGOKNNOMDFBH?CHDD@:;;875777858@>@;<9<;<>:9;99;9FDEB<@>?<@C;>@?@?B?>:;JUcÕáààáááááâââââââââââããããããããÖÖ××Ûʅ„wqrnnx•„{x„yvpxsw‹‘Ž‚vs}Š†ˆwwuwƒƒ|ˆˆ“ÃÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÚÚÚÚÛÚÛÛÛÛÛÛÛÛÛÛÛÛÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÚÚÚÚÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÒuYhijVNJHMNGMDPIFH?E=FLDC>;;<977966958>>?=;<@;=<:7;7998GDEB=A=B?>@<?AA?@B@>;<KTbÔâàááááââââââââããããããããããããã××××Ē{‰olnuv~„ƒŠ†~urmemˆ†ŠŽ„{sƒ‡Š{x{ƒ„ŠŠ±ÎÚÙÙÙÙÙÙÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßÞÞÞáÉl[jjjSNGGNOEHFMII@;D>HI@=<:::868:77948=<==;8<<<<86789::EBEA?@<B?CC>>CDA@@?@<=KQaÓãàááâââââââããããããããããããããää×××Ù©v…~|wlpwyx|Œ}Š…€wjstwz}n‹{~yz~„€ƒ~x|~‡†–¶ÓÚÙÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßÞÞã½jaikiQNFMLKJXMNGA@@OAC?@;<89996866684;><=;96::9:958989:BDF?>>>@@@B?<A@?<>?A9>JO^Òãáááâââââãããããããããããããäääää×××Úʊ„€ysomqsuw€”xv€|u‡…wuru ™z{wvyv„tmln{x€š‹“»ÜÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßÞã³iinihPPOLLOROKSF?EDDD><<8;87995687673:>;>=7:>99996::87<CEG??;?>@=>A=;=>9A@@8ANQ\ÐäááââââããããããããããããääääääääØØØØÚ¹Ž€zvunjoxp}ktrvw„…y‡‡y•Žyyzuwzsko|€|v}ˆ|€²ÞÚÚÚÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÝÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÚÛÛÛÛÛÚÚÚÚÚÚÚÚÚÚÚÛÛÚÛÛÛÛÛÛÛÛÛÛÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÜÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÞÞÞÞÞÞÝÞÞÞÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßàààààààßßßßßâªjkhkdSPOFPTRNHRK>DDCB;;9::86785668784;?<?=9<<7;::7::7:=CBC=A>?<9=>A@;<<;E@>;CNS\ÐäáââââããããããããããäääääääääääØØØÙ֞ov{oxxvpntwpptpso~‰sz†…„zsmr€z†}oƒ“v|}ƒ†µÝÚÛÛÛÜÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßààààààààààààààßßßâ mhfkfUVRGPQNKLLEBHEG=8=<::778677656748><==:8:8>:;7877::>CD;CB>=8=@AC?><>E<>=BMP_ÒãáâââãããããããããäääääääääääääØØØÜÀvv€‚~zxxpluyrk}lsotghi€ihxsg~‰‰xp‚†{w}~…Š½ÝÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÜÜÜÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßààààààààààààààààààààߔkmfnfSSIPYTLHFNFFEBF=;><;9778579645758<;=>::;;@9;;87:99@BA<AA??9?@BECA@@C;;=DKM`ÖäââââããããããããääääääääääääääÙÙÚ٘s{ª„–‚rtuv}xhl|whxwnkpty€ƒvt|„‚}sp€Šx‚yƒÈÞÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßàßßßßßßààààààààààààààààààààààáۋnmgscYQMU[WHCIFNKGBD??B:;:66756764876;<;>?:<9<B879:::9:AABABC@A>=?BCCDABF98=DJNbØäâââããããããääääääääääääääääåÙÙÚܨq‚µx‘~slzn„v‚}khjƒxv|u}……tfpy}w}z€Š…{}|~€´ÞÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßÞÞÞÞÞßßßßßßßßßßßààààààààààààààààààààààáààààààààâ؅oqkuaVOUU\ODMF>JGJED<?B:<9868456747649;;<;8>;<A88:=8=8:==@@@?AB?@>@CBCAAE76;DLNcÚäââããããããääääääääääääääääååÛÚÚݞlnsq…rmpnu„~krvvzsxxsoupmkv|y…ˆ€vrƒƒ±ßÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààáááààáááááááááàâׅmqov^RWSZZQJHC@Q@BD<9?A:<975745664756=<:==9>:<@8::<6;9;>=BBB;AB@C@@DDC<=@7:<EKMeÜãââãããããäääääääääääääååååååÓÎÆÀ~qlox{vounjssm’†xnttnot†okpn‚tmvr}ƒvqwyŠ¦ßÜÜÜÝÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÝÝÝÝÜÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞßßÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààáááááááááááááááááâֆnpmq`RYPW_YJLLIR?D=9;BF;:974565754666>=;?>9=9;>8=;:48;@@CBCABFA?C@ABDD;=>9;<BLMdàåããäääããäääääääääääåååååååå¹·µ¨srlpwztwxmqruw„trsllkq|npntkq€w}„ƒ~y€srŠ ÙÝÜÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààááááááááááááááááááááãՇqljl^XZUW`VVPOPL=A:;<FA8:873656965857?=;?>9=8;<9=;;5:=CBB<CCDDDAA?>BCC<=>89<CKKcÍÑÙáÖÈØãäääääääääääåååååååååµµ¶«ryrn}vuwhjhipovmkkgefqtmy€nmywvˆxqkjhuuytuÁßÜÝÝÝÝÝÝÝÝÞÞÞÞÝÝÝÝÞÝÝÝÝÝÝÝÝÝÝÞÞÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààßßààààààààààààààààààààààààààááááááááááááááááââáááãՆqpciaWSYW_LRORMK@>89;A>87964767:66649>?:<?:?9::7:=<99<AA=;ACECF@>>>AED>@A78>FHJ^²µ¸Á¹µ»Èàåååääåäååçççççæåææ涶µµŽ}~pz„urvgbcelkrofilvmw†}…yllwxkvp|}xsuy|wv‡¹àÝÝÝÝÝÝÝÞÞÞÞÞÞÞÝÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÝÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááâââââââââââááãՇun^ncZTSXWKSKJMRGA8;;><98756566968669?<:==;?:;;9<<;9:>>>;<=ADBCA@@A?BC<<=7;>DEJ^±µ´µ¶··¶ËÚÉÞååÝàâÞÕÔÖÓÔàãàß߶¶·®‡{nyzrumchllmitxzqyzzˆ‡ƒzih}qdoq|†~y{}|{†§ÚÞÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààààààààààààààààáááááááááââââââââââââááãֆvlao_]WY\ZRPHJWLEG=@=;;=9646555867678?;9==<<99<:><:98>B;;>>@D@CEA@@=?@<==59<BGF]±µµ¶¸¹¹¹º½¸ÃÓÒ½ÁÁÀº»¼º»ÄÌſ÷··„iu}gu‡yguqkkyxpw|}ymiw{xwniuplyxww}{†‚y€ ÜÞÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÝÝÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààßßßßßßßßßßàààßßààààààààààààààààààààáàáááááááááááááááááâââââââââââââââáãׅrkgta[XX_^SUUQUJLF?ID;9=6647757877789<<:><8<:=>9;<9;9?A<=?C?A@EBBA<=C@:><549DGGZ±µµ¶·¹¹¹¹¹¹·¹¹¸¸¹¹ºººº¹¹º¹º»··¹npszopysnsulsvxqqpokoq~si‡„}ts‡umu…‰€rv…§ÝÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààßßßßàààààààààààààààààààààààáààáááááááááááááááááááááââââââââââââââââáã׉qklr[WW]`TQUTPROJC@MA=;9653464687779:>;<>;9<:<<9<=<;==>=CDD@CBA?@><>A<8=:66:BJHX±µ´¶¶¸¹¹¸¸¹¸··¸¸¹ºº¹¹¸¸¸¸ºº»·¸¬{rxqvs~plmzrgolmntp{wwrrwzo†’v||zvy|s}‡ru­ÓßÝÝÝÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßàààààààààààààààààßßàààààààààààààààààááááààááááááááááááááááááááááááââââââââââââââââââãׇojqjUVWa[OQRPNWIDDIJ?:9:753495766788:<;<>:<::=<9;<=;==<;=DGDCA<<<<>>@;8<815:AFEV®µµµ¶·¸¸¹¸¸¸¸¸·¸¹ºº¸¸··¸¸¹º»·¹ªrpxw|{{‚whnqjojcirmsr~xtqljv€y}€€uv€ukŠ‹€v‘ÕßÝÝÞÞßßßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßàßÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßàààààààßààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááââââââââââââââââââââã؆mlteVP\gXMXSRQYECKPN;9887553956676889>9=>9<99<;6899:<@@=>@F@BB@:><A=?;;;616<BGDP¨¶µµ¶¶¶·¸·¸¸¸¸¸¸¹º¹¸¸·····¹º·¶´‰rwx}‰|pzo}shjlggltlqwtqlvsqqwqr|yxƒv{wi‹‘Š}ÎßÝÞÞÞÛØÙÚÙÛÞßßßÞßàÞßßßÜÛÜÜÝÞÞààßààààßÞÞÞßØÒßÞßßÞÞÞßßÞÞßÞßßÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßààßàààààààààààààààààààààààààààààààààààààààààààààààáááááááááááááááááââáâââââââââââââããâããâââããããââââãâä׃hgudVUdeWJZYW[T=EMKH=8757643944775679=:=><=<9;<99:>9<>?>AACAEED>;<A><9<;737>DHEJ¡¶µµµµµ¶¶·¸¸¸¸··¸¸¸·¶¶¶¶¶·¸¹¶¶¶‹}zllzplyvnjhgeqzxoioopusmswgo}‚ƒryjprz©àßÝÙËÆ¿¼½¿¾ÂÍÒÐÖÞÙÜà×ÐÍÃÂÃÃÇÕ×ÓÙÜ×ÔØ×ÐÇÄÅǽ¼ÏÊÏÎØÝØÎÜÝÜÚÝÓÑÜÞßßÞßÞÞÞÞÞàßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààààààáááâââââââßâãâáâàáÞÖÛßÒÃÊÉÇÑÛÜâäááàÙÚÞÖÆÄÅÄÍÚÚßäáââÚ×ÞË}ifqaY^eaMLTKRZL;HMHFA=766534664876569<;>>:>99<979;;:>=<@@CDBGFBA=<C@=9<;777?DFFF™¶´µµµ¶¶¶¸¸¸¸¸¸·¸¸·³µ¶·¶··¸¹µ¶·¢—qoopintvqfeckngormfgkreov|€xdsshqrieeno°ßÑÅ¿»¹¹¹¹¹ººº»º½ÍÆÃÇ¿ºººº»»»Á½ÁŽ¼¿¾¼»ºº¹¹ºº¹¹ºÃÅùÀÃÁ¼¿¹·¿ÏÏÔÞØÜÞßàÞÒÚàßßàààßßßßßßßßßßààààààààààààààààààààààààààààááààààààààààááááâââáàáââââáÚÚÝÑÂûÅÓÖàÝÉÓî¹À±ª«««°´¶ÉÒÅÑı¸¿´«««¬¯´´¼ÌÄÕδ´»«xlmm`]b_YKSUTQPD@QMHD?:78573156498466:<;=<8<96::88975<<<?@A@BDCBA<>B??===758>CEC@¶´´µµ·¸¸¸¸¸¸¹¹¸·µ±«­¯³±³³³´´´¶¦ž‹kn{vqyxgch_qwaknoho}onckilxwlk†~lpzvmlpoy±Æ¼º»»º¹¹¹ºººººººººººººººº»»º»»¼»ººº¹º»»ºººººººº¹¸··¸¸··¶µµµµ¸·»Ç¾ÃÅÇÍĸÀÉÇÒÜÙÙßÞÞàßßßßààáààààààààààààààààààààààààààáÜØââââáááàáàÞ×ÆÆÑÐÎÔÞÞÓÎÒßÒ¸¸¼²­­¬¬¬®±¾¹®·¬¨©©©ª«««ªªª«¬¬¸¬ªªª««««­®®®®®®¼³­¬«¤ynom_^]]TMRS\TJA?PIH>89683730573785766:<?<89;:::89:659;<>?D?CEBCB?@@A?@><787:AED?…¸´´µµ·¸¸¹¹¸¸··´®¬«ªª­®®®¯°±³³µ£pnnrmpƒ}uiaehfdcdqsmmwngimmepsoosqs|‡zu}uŸ»ºº»»ºº¹¹¹ººººººº¹ºººº¹¸¹¹¹¹ºººº»º¹¹¹¹¹ºº¹¹º¹¹¸¸¸···¸¸···¶¶µµ¶¶¶µµµµµ¶µ····ºÁ¾¼ÆÉÊÛßààÞÛÝÝÞáâÐÖâáààààààààààààààáààáâÓ¾¼ÌØÝÜâàÑÙÛĽ·°°±±¯³»»³°´½³®®®­­­­¬«ªªª©©¨©©©©©ª««ªªª©©¨©©©©©©©ªªª¬­®®®®®®®®¬­¤xibqfaYZVQRN\SF=BRDA7<;6956545658756578;><;999:8779768<;>;D??C@ADA>?C=><>::77?CF>x²°³´µ¶·¸·¶²®®­¬««ª©ª­­¬¬®¯±³´µ·Œnrtjh€yfjfel]hnphlqbcfr‚~vhhljnz†…|xqqy€¯º¹ººº¹¹¸¹¹¹¹¹¹¹¹¹¹¹¹¹¸¸·····¸¹¹¹¹¹¸···¸¹¹¸¸¸¸··¶¶¶·····¶¶¶¶µ´´µµµµ¶¶µµ¶········¶·¸¿ÆÏÐľ¿ÀÄ××¼ÉÚÚàáàààááààààááàÛÞÞÔͼ·¶·ºÀÀÉķȾ²°°°°¯°¯®®®¯°°¯®®®®®­¬­¬«««ª©©©©©©©©©©¨©©¨©©©©©¨©©¨©©ªª«­¬­­­®¯®­¬­¡yjdmgb\XQPQKTJB:IQ?A7<94:565455688686;:9<==;:86688:867>===>AAEBBCAA@A:==?=9:7=AG<lª¦¨«­°±°®«©¨ª««©©©©«¬¬­­­®°³´µ¸¥€‡oigstfkpmjdlornkmckp|‰„njl|xc{Š~sjsnkq»¹¹¹¹¹¹¹¸¸¹¹¹¹¹¹¹º¹¸¸········¸¹¹¸¸¸·¶¶¶·····¶¶·¶¶¶¶·¶¶¶µµµµ¶µ´´´µµµ¶¶¶¶¶·····¸¸¸·¶·¶¶¸¹¸¸··¸¾¾¸º½½ÇÛàáàØÙÝááàÝ×ÊÁú¹¹¸·¸¸¸·µ´´´²²±±±°°¯¯¯¯¯¯¯¯¯¯¯®®­­¬¬¬««¬ªª©¨¨©©¦§©©§¡¥¨©©©¨¢Ÿ¡¡œ¢§¨§©«¬¬­®¯°°®­®xpljac`YQMQLRFC9MPE>8;727967443578797;::==<::974:98658??@B=DCCCAC@BA@;@?@?<<:;CH=c¨¥¥¥¦¨¨¨§§§¨©ª©¨¨¨©ªª¬­®°°°³´µµµ¥˜v~qfkxqomfelhclgfii}umio}vy…fhwoxoqorx§»¹¹¹¹¹¹¹¸¸¹º¹¹¹¹¹¹¹¸··µµµ¶¶¶······¶¶µµ¶¶·¶µµµ¶¶···¶µ´´´´´´´µ´´´´µµµ¶¶¶¶¶·······¶¶¶·¶¶··¸·¶·¸¸·¸¸¸¸¸ÀÅÓʼ¼ÃÍÏÈÀ½º¹¹¹ºº¹¸¸¸¸¸·µ´´´³³²²²±°¯¯¯¯®®®¯¯¯¯®­¬¬¬««¬¬¬«§¡ ž Ÿ›¡¡–™¤¤¦¨Ÿ™™™™šŸ ŸžŸ¤ª­®¯®­­¬¬™upikca^]UNSKRDD8NKGA:85269654737778979:;==>88875:9958?@@AD>FABC@BCBA?<@BB@=>::DF>\¦¥¦¦¦¦¦¦§¨§§¨¨¨¨§§©««¬¬­­­­´´´µ·¤s}unsrfjqcimchfhlnui_cgusvzngppr~zqˆ¡»¹¹¹¹ººººº¹¶³¶µ¸¹¶¶µµ¶¶µµµµµµ·¶¶·¶¶¶µµ¶µµµµ´´´¶¶···µ´´³³´´µµ´´´µµµ¶¶¶¶¶¶···¸··¶¶¶¶µ¶µµ¶¶¶¶¶¶¶¶¶·¶¶·¸¸·º¸¸¸¸·¸¸¹¹¹¹ºººº¹¸····µµ´´´³³²²²±±°°¯®®®®®®¯¯­­¬¬«©¥¤¦¦¤œ™››š™šš™—————–™›˜™˜™™›žŸŸœž ¤¥¤££¢¢¢tncpa^^[TSTHTJ?<QBFC;8637:554838997897;9;=;7:75699858>??@E>B??C?<AAB?=?DA?>=9=CF?U¤¥¦¦§¨§¨©©¨§¨¨¨¨¨¨¨ª¬«ª©¨©«µµµ¶¹£wŠqr‡†wtphykbcaelinsj_ceccejkbdjlv—~¨½¹·¶·¹»»º¸µ±¬««ª®°¬¬««­­««¯°±¯¯°²µµ¶·µµ¶µµµµµµµ¶¶´¯¯³´´´¯­®¯²µ´µµµµµ¶·············³°²¶µ´¶¶¶··¶¶¶µµµ¶¶···¹¸¸¸···¸¸¸¹ºººº¹¸¸···µµ´´´´´´´´³³²±°¯¯¯¯¯®¯¯­¨£¢ œšššš™™š››šššš›š™™™˜——–˜™™™šœœŸŸ Ÿ   ¡¡   ŸŸ‹tnit]`f^RTKDTI=ESHEB;:4469445738887899:;;?=8:93589639=>@?@:@BBB@?@BB?=>AAB?=:>EC@Q£¦¥¥§¨§©«ª¨¦¨¨¨©§¨¨¨¨§§¨¨©ªµµ···²™´}Œugijlfc`cheoxpibq|ypjffdfksj…Œ¬¶²°­­­´·²°°­¬«ª©¨¨§¨©©©©¨¨§¨¨©©§¨ª««­­¬ª¬­­¬¬®®­­«§¥¤§ª¬¨¤£¤¥©°±±³µµ¶·¸··µµ¶·¸····²©¥¦¬«¨¯´¶µ³µ··¶µµµ¶¶¶·····¶¶····¹ººº¹¸¸··µ±³´´´²±°®¬«¬®®°±°­«ª©ª¨¨£œš™˜™˜˜˜˜™™™™™™šš™›››œœ›™—˜ššœœœœŸ ¡¡¢¢¢ ¡   ŸžŠujknY\aVKODGUG>OWHD=<834484548289889::<99@<69:367914<??@@A:CFEBADBCA:;?ABC?@=@DC@O£§¦¥§¦¨ªªª¦¤¦§§¨¨¨¨¨¦¦¦¨««­µ¶···¸­²up{ƒv`bikbefadgf}ˆylr€}qoqxcmnqf¬¬«««¬¬­®®¬­­¬¬ª§¥¦¥¥¥¦¨¨¨¨¨¥§¨¨¨¨¨§¨©©©§¥¤£¢¢¢£¢ ¢¢¡¢¡  ¡¡¢£¤££¥¥¥¨°´³³³°«ª©ª³´¶·¶±¨¥£¢¡¡¢¤¨ª©¨«³´±®®±³µ¶¶¶·¸¸········¶¶¸·´±®©¦§«¬©§¦¥¤¤¤¤¤¥¨©¦£ Ÿžœœ››šš™™˜——™™™˜˜™šššššššš››™˜šœ›œ ¡ ¡££¢    Ÿž…tklhWXSJGMEHMG@SWFG==93637455738::::9<=::A<6=8378837;@??@@:BEC@BDCA?;<@CBCA@<AC@=N¢§¦¦§§©ª«©¤¥¥¥¥¦¨¨¨©¦¦§¨©©ªµ¶¶···¸³sh{sbgjkiibadih]]m|rfkr|t|nmss~ ©©«««ª«­­¬«¬«©©¨¥£¤¦¦¦¥¦§§ª©¦¦§§§¨¨§§¨¨§¥£¤¢¡¡¡¡ŸžžŸŸŸŸžŸ ¡¡£¥¤££¤¤¤¦§§§¦¥¤¥¦¦¦§ª­«¦¤¢¡¡ ¡¤¥¥¥§§¥§¨¨¦¥¥¨¯´¶·¶µµ¶¶µµ³°¬«©©®«¨¥¥¦¦¦¥¤¤¥¥¥¦¥¤¤¤¤¥¢¡¡¡ ž›››œ›šš™˜—˜˜˜˜˜™š™™™™˜™™™™š™™œœœœœœ›œŸŸŸ ¡¡¢   Ÿœ€sknd^SJHMFDLKEDQSCG=<8362846464898:;9;><9=;9=7359656<@=?@?<?BC>BBB?=>>BCAE@?:>E@;O£¦¥¤¦§¨©§¥¤¥¥¤¥§§§¨¨¦§§¦¥¦¦µµ¶¶¶µ¶¹Šmqmo||qgjf`al`TN[hjnom‚}qgqv~š¨§¨ª©©ª««¬ªªª¨¦¥¥¤¢£¥¦¦¥¥¥¦©ª©¦¥£¤¥¦¦¤££¢¢¢¢  ŸŸžžœœœœœœžŸ ¢¡¢££¢¡¢¢¤¥¤¢¢££¤¤£¤¤¤£¡ Ÿ¡¢¤¦§§¨©©§¥¥¤¢¤¤¥¨­°°¬«ª«¬ª©§¥¥¦¥¥¥¥¦¥¦¨¨©¨¥¥¥¤¤¤¥¤££¤£¢¡¡¡¢¢ žœœ›››š™˜˜˜˜™š›™———––——˜˜™ššœ›ššš››››œœž  ¡ žžžžœœ›~znrb^SMJPEFNMB@OE>I;=5363836675:;89;9:>=;:9:>7669656>B>>A?=>CA>CC@@;@@BBBE@>;>E?<P ¤£¤£££¤¤¢¤¥¥¤¥¦¦¦§§¦¦¦¥¦¦¥´µµµ´´µ¸h|}es‚zlpua_cTNOQ[hlillqmnqntœ¢¤§¨¨¨©«ªªªª©§¦¥¤££££¤¤¥¦¦¥§¬­©¤¡žž£¤¡žžŸ  žœœœœššš››œœ›››œžžŸ  ¡ Ÿ ¡£¢ ¡£¤¤£¢¤¥¥¥¤¢Ÿ £¤¤¤¦©©¨§¥¡œŸ£¥¨©©¨§¨¨¨©§¦¥¥¤¤¤¥¦¦¦¦¦¦¦§§¥¥¤££££¢¢¢¡¡¢¢¡¢£¤¢Ÿžœš››šš™˜——˜––•”””••—˜˜š››œ›šššš››œ››œžŸŸž›œœœš›š~qt`[TMGMHFLJ??NC<@;<4383747678;=8::99;=;;89=7789588?@=?A>;=D?=D@??:@AA?AE@><<C?<N¢¡¢¢  ¢¥¤¤¤¥¥¦§§§§¦¦¦¦¥¦¦¥µµµ´´´´·Œv¥±wfsroslcdiXORQOO]€md`Zm‘‘’¢¢£¥¦¦¦§§¨¨¨§¦¥¥¤£¢¡¡¡¢£¥§¦¦§¬¬§¦ œ›¡¡ž›ššœ™˜š›ššš™™™››››ššššš›œž ¡ ŸžŸ¡ žŸ¢£¤££¦§¨§¨¥¢ ¡¡¡¡¤¥¥¥¤ œ™™›ž£¦¦¦¦¦¦§¦§¦¥£¥¤¥¥¦¨¨§§§¥¥¥¥¥¤¤£££¢¡¢¢¢¢¢¡¡¢££¢ Ÿžžœ›œ››™–”””“““““”””•–—šš››››š™™ššœ›šššš™š—wos]ZNHJNGEFIDEN@<==<45;46465679;899899<;<7:;7888588?B?AA<>?@<<B@A>=A>??=BA@::@<<O¢¡Ÿ ŸŸ£¤¤¤¥¦§¨¨§§§¦¦¦¦¦¦¥µ´´´´´´µ´—¶§ufxvclccec[RSSRM^ ŒxXhv–£žž¡¡£££££¤¤¥¦¦¥¤¤¢¡¡¤£££¢£¥¦¥¦¦§§¦Ÿ›š›¢ ™––•š›™——˜˜šš˜˜šššš››š™™™ž ¢£££¢¤¤¥¢ž¡¡¡¢£¥¦¦¥¤£¡  ŸŸ¡¡Ÿ  š˜—™šœ ¤££¤¥¦§¦¥¥££¤¤¤¤¥§§¦¦¦¦¦¥¥¦¤£££¤£¢¢£¤¡Ÿ ¡¡ ¡ ¡ ŸŸžœš˜—•“’’’’’’““’“”•–™šš››šššš›žžžœœœ››šš™™™”}tlt^ZOHEGFBENE?F;:>?;46:69364688:89788:<;<9;;::67899>?@><=@>@:9@A?=A??AA>AA?:9=>:P Ÿ›œœ›Ÿ¢£¥¥¥¥§¨¨§¦¦¦¦§¦¦§´´´´³²²±°°­«x†~›šwb]SRQQLb ¢‹Zˆ  Ÿ˜™œœž¡¡ ¤§§¦¥¤¢¡£§¦¥¥¢¢¥¦¦¥¦§¦¦ ›™›¡ —““’—šœš———˜šš™šššš›š˜˜™š    ¡Ÿ¡¢¢¤¦¦¢ž ŸŸ ¡£¤£¢¡Ÿžžžœš›™šš™˜—™ž ¡¡¢¢¢¢¤¥¥¦¤¤¤¤¢¢¢¢¤¥¥¥¥¥¥¥¦¥¥£¤£¢¢¢¡  ¡ žŸŸŸŸŸžŸŸ Ÿœ›š™—•”””“‘‘’’’’’’“”•—˜™š™™ššš›ŸŸžœœœœš™™š˜——‘|rgq^]PF?AD?JOBBF8CE>>98;7748459::;979:<;:<=><<:67698>?A>;?>=<8:>A@AB??AB@DA>:8>A<Sœœ››ššœœ¡¢£¢£¢¤¦§¦¥¥¦¦¦¤££²²°­«§¦¦§¦¥¦¨¥Ÿ¨¨§ª§¡y„\QROL\œ €b™ žœ•“•–—™šž¡¦¦¦¦¤£¢¢¦§§¦£¥¦¦¥¥¦§¦¦¢œž¡Ÿ—‘‘”—›˜–––˜›™ššššš™—˜š›¡¡ŸžŸžœ›œž  žŸžŸŸ ¢£¤£¢ Ÿž™–———˜˜™››ž¢¢¢¢¢¢¡¢£¥¥¤£¢£¤¢¡¡¡¢£¤¤¤¤£¤¤¤¤¢¢¢¡¢¡ ŸŸ žžžžžž›™˜—•““””“’‘’‘’’‘’“”–——˜˜™šššœžœ››š˜˜š™—•–zjfj`bNF>?@=JE@C@;@A<:;9:765846789=88;:;?;:;<:9:7768;;;=<::<=<7;>CBDC?=AC@DA?<:@B;W™˜šš™™š››œžŸ¢¢¡¢¤¥¤¤¥¦¤¢ ž¨§¦¥¦¥¥¥§¦§¦¦¦¦¤¥¦§¨§¡©rNQMJT–¡zršœœžœ—•”•–˜˜——šž¢¢¡¢£¤¤££¥¦¥¥¦§¦¤¥¦¦¥¥£  ¡¡Ÿ™’–š™žœ–———™›œœœšš™—™››žŸœœ™™šœœžžŸŸŸ¡¡  ¡¢ Ÿž›—•••—šžŸŸ¡¡¢¢¢££¡¡   œ¡¢¢£¤¤£¢¡¤¥¤£¤£¤£¢¢¢¢¢¡ ¡ŸŸœœœœžžš—––•”““’’’’‘’’’’‘’”•–—˜˜˜˜š›œœœœœœœ›™˜™˜–”•—‹xlcdbdQGA=C;KHD:;;<>9::9:73795:888<98;9==;:;:9<<7647?<:=;<?><;8<ACACBB>?B@BA@:?@?;Y™˜šššš››››œ ¡¡¡¡¡¢¢¢¢¢¡ŸŸ¤¥¦¦§§¥¥¦§¦¦¦¥¤¤¦¥¤¤¤¥¦†PRPOO˜pzš››œžœœœœ›››™˜˜›žžžŸ £¤¢¡¡¢¢¢£¤¤¥¦¥¤££¡¡¡žœš•“”˜›š›žš˜˜˜˜šœžœš›˜–™œ›œœœœœšš›œžžžžŸŸœœœ¡¡ ›–•••–œ ¡ ŸŸ¡ ¢£¢£¡›™––––˜œž ¢§¨¤¡  ¢££¢¢¢    ŸŸŸŸ žœ››œœœ™šœ›–“’’’’”“’’’’’’“’’’‘’”•–—˜˜˜˜™šœ›š›››œœš™˜˜—••–—‡wdghdbMCE<D9IJE9:;==::88:64795<968979<;;<::<;:<<8787>=;>>:B?:::?ADBCAA@?DAA@>:@>=:[š˜™š›š››››žŸ  ¡¢¢   ŸŸžžœ¥¤¥¦§¦¥¥¦¦¤¢¢¢££¤£¢££¢§–TXURNgmkžš››Ÿ  ŸžžžžœœžžžŸ ¡ ŸŸ   ¡¢££££££¢¡ ž›™™˜™™™š™˜žž˜˜™™š›š–•—–•˜œœœ›žœ›œœž›˜šž¡¡›› ¢¡š••––™ ¢ ›ž ¡£¢Ÿž›——”’’”—˜™ ¢§§¥¡ Ÿž ¡¡¢¡ Ÿžœœ››œ››šš™šœœ™—™–•“‘‘’’’’’‘’“““““““”•––———™šœ››œ›œœšš™——––••”„rflbd[DBL=?8FKB<@>>=9;9:=85886;856:8<<;;<<;9<:==9587<9<?<:A?:::@@CBDAC@?CA@>=<@==:_š—™š˜—˜šœœŸŸŸ¡¡¡ ŸŸŸžŸ  ž¥¤¤¤££¢¢££¡ŸŸ¡¡¢¤£¢£¤¢­§W^]TW_nkšš›œž››œŸžœœœœŸ   ¡¡¡  ¡  ¡¢¡¡¢¡Ÿžœšššš›œš™š›™œž™–––——“ŽŽ”–›œ›š››Ÿœœœœœž–”™œŸ¢ŸœœŸ¡ ›——™™šœœœ››žŸš—–––”““”˜šššŸ ¡¦¦¥ ŸžŸž ¡¡ žœ››œœ››œ››š™˜™™™™——˜•”’’’’’‘‘““–˜—”“’”•”•–•–™™™š›œœœšš™—–––––€ooe^`W@JH8?7IE?EA<=;::;;;75;86;746::>;:=>>=;;;>;:8:996@A=:<=:;9?ACBDEC>?AA??>>?=<;`—•——–•—™›ž¡¡ ¡¢¢ žžžžž  Ÿ›¥¥£¤¤¢  Ÿ ŸŸ¡¢££££¤¡°£]ed`ankžœ›››››™˜šœžœ›››œœœž¢¤¡ž ¡¡¢¢¡   ¡¡ ŸŸžœš™š›››œ›š›™šœ˜—••–‘Ž’˜œœ›œœž œ›œœœžš••›žŸ¡Ÿœœžžœšššššššš››š——–“’••–•“•–š›ššžŸ¢¥£žžŸŸŸžŸŸžžŸœœ›šœšš›š˜™˜˜˜˜˜˜•”“‘‘‘’““‘“”˜™˜•“”•••–•–—™™—™šžžœš˜˜——––——˜}nm_eVTEK<7>7REC>BA8;<;98:86;77:679:=>:<<=>=<=:?=:8<=9;@>>?=>99;?BC@CEC=?CB>@@>@=<<a•’”•––—šœž    ¡  žžžžž Ÿžž›¥¥¤£¢ ŸŸž›™›œœžŸ Ÿž«˜cimnifmžœ››œ›š™™™šš››œ››š›œ £¤ žžŸ     Ÿ ¡  Ÿž›š™šš›››››Ÿžœ™˜šš˜˜˜˜’Ž“—œ›œœœœœœœžžžš•—œ ¡¡Ÿžž Ÿœœ›ššš›šš˜š™•“““’“–——•”˜˜™›œœœ Ÿ žžžžŸŸŸžžŸ¢£¤¢ žžœ›ššš›™˜™™˜——–•””“‘‘‘’“““’’“”˜™˜–•”•–––––—˜˜˜˜—™šš™———–—–—–—‰xvg]_WTEE99;<Y>@8B?9;;>98;8:;79:589;=<9=;=><=>;??;9><<>?>@AA=87;BCE?AEC=@DBA@D;;>;<b–“””–•”–˜˜™››œœœœœžŸžœš¤¤¤¤ Ÿžžœ››š™˜˜˜™›œžœ¦‰ektxm[…¢œœœš›ššššœ›š›› ¢¢ž›œœ›œžžŸžœšš›œœœ›œœžžœ›šššš›œ•‘“—›œŸœœœœœžŸžŸœ—˜Ÿ¡¡ žœŸ Ÿœ›››š›š™™™™™—•–•–˜———––˜™›žžŸ¡¡ ŸŸžžŸŸŸŸŸ¡¢¢¡¡ŸŸŸœ™›šœ›šš™—––˜———–•“’‘“””“””””–™˜–••—™˜—˜—————˜—˜————––˜——•——ƒxv_[]^Q=F:98?UCA;CC:<>?::97;8887489<;<8;;<=:=>:?A=:=<>>@@=@A>96<DCE@AEE=>EDD?B;:<9:d—”••–”””””•—˜˜š™šœœœžžœ›££¤£ žœ›š™š™˜˜˜™˜š››››¥‰kqvzoešŸžžœœ›žœžžœœ›œ  ›šš››š›œššš›œœ›™™œœœžœ›šŸŸ›œ›™™™›ŸŸŸœœŸŸŸŸ›šŸ  Ÿœž ž››››››œšš›š™›œš™˜—˜˜˜˜šŸ    Ÿ¡¡¡  ŸžŸŸŸžžŸ¡¢¡ ŸžžŸžœšš›››šš™––—™™˜˜˜–”“””••““••”•–•••”˜™›š™––—•–˜˜–—“””‘‘“Œ‘“–}xjabb\P<@<68CVHDB:8;:>;7796=:99647:;<=9::;?;==<@>;;>:=?=>@A?@<7;ACE??DD>?DDC>B=;<;:g–“““““““””•–—–—––—™››œ›››š™££¢ Ÿž›š˜—˜———˜™˜™œ››š¤€jjoysq— žœœžžžžŸžžœœœž›œ›šššš›››™˜˜ššš™™™˜š›œœœœ›šŸ›œœ››œ››œœžžœœœ››žžžœ›ž››œœœœœœ››š™›š™˜™™˜š™™šœŸŸŸ£¥¢Ÿ¡¢¢¡¡Ÿž  ŸŸŸž ¢¡¡¡ŸŸŸŸ™š›š™˜•–—–••–“’“”“”“’“‘”‘Ž‘Ž•–›˜•˜”™—”˜‘Œ“œ“’Œ…Œ‡ƒ†wqgjd[\QA>86BG`BEG@>;<;:8865<8:834:69==99:<=;<:<><:>@:>@><?@?><8:CAD?>BD?>CEB=B@<<<:g˜“’’““’“”•”•——––•–—™™™ššššš¤¢ ŸŸ›š™˜˜˜——˜™˜™œœ¨}ges{zs‰¢Ÿžžžžžžžžžžœ›œ›š››››œ›˜˜˜™™˜˜™™™›œœžžžžžžžœ›››œœ›œœžŸŸŸœ›š›œ™™œ››šœœœœžœ›™—••——˜šš›››žŸ¢£¡ ¡¡œ›œ›››šœ™œœŸ Ÿ˜™™™”’’”—”Ž‘Œ‰‹‹‰‹Ž‘‘‰˜˜’Œ‹’˜˜¢¨ª¦¥¥¬£¦¡šž§§²¨¢•£ Ÿ—pqil\[\MF<77GGX>HNTF9>:89875=9873396:><:7:<;::::<<;?>;@@>;=>A<<67@>B@>AF><ADA=CB>=<9f˜”““““’“”•“•—˜˜˜–——˜™™ššššš¢¡Ÿžœ›™˜˜˜˜˜˜˜™™™›œ›œ¬jmzyq‡¡žžœžžžžžžžžžžœ››œ›››››››™˜˜˜˜˜˜˜™™œœœžžžžžŸŸžžžžœœœžŸŸŸž  Ÿžœ›œž›š››žž›››œœžœš˜—”‘Ž‘•˜”–”˜™š›˜›˜•ŒŽŽ“’’‘‰Ž‘‘ŽŠ‹ˆˆ‹‹ƒ‘Œ“••œ˜¡ œ’Ÿ¤¢¤©š›—šœ£©­½ÁÁº¼¸½º¹À¼¹º·º»»´½³ÁµnufgZ^YLIE:;LIS<VRIC:A:;;775:::82568;=<99;;<:7:8:<:=?9<?><<=A;958<;@?A?D=<AB@<DC===:a““‘””“““““”—˜–—™˜™˜™š›ššššŸ žŸŸœš™šššš™˜—˜™™™™™™©…pu{€wo‰¡žžžžžŸŸžžŸžŸŸžžžŸžœœ››››››š˜˜˜˜™™˜š›œœžžž  Ÿžž¡ žžžžŸŸžžŸ žžžœœœ›š˜œ›•˜šš˜˜˜˜™’Œ—” —“ŒŠŠˆ‰Œˆ“‘‡ŠŠ‹ŽŠŒ‹ˆˆ‰‰Ž‘Ž†…‰†Š†…‹ˆ’’—–’š˜“”ž¤¦¦ª«±¬¯¯«¦«ª±¹¹µ´´®¬¯´ÀÈÅÅÁ¾ÆÃÄÄúµ¾·¶´³°¶µ¾ªptr\f_]]IF??EKLVI\LD?=B:C9977;9971798:>88:<<;979:;=:>?9>A<;><>:969<:A>CAA=<B@@>BD>?>9\‡„ƒ‡‹Š‰†…ŠŒ‘“•˜˜‡•––’˜šš™žŸ Ÿšš›››œœ›˜–˜™——˜›ªŽzuv{y‚ ŸŸžŸ   ŸŸŸŸ  ŸžžŸžžœš››››››˜˜˜——˜™››œœœžžžžœ››œœ¡¡Ÿžžœ˜–––˜••’–™–“‘ŠŒŒ‹‹–‰ˆ„‹‘™Ž}…‹Œ‡ŠŒ›Œ‘‹ŠŽ“ŒŒŒˆ’‹Œ…‰Œ†‹ˆ‡Š…Œ„Š—“˜š•›œ£ª¡¢¤œ¢«±·´¹µ±³­¯²²¥§³º±ºº¼¶·¶ÀÃý½¼¶¿ºº¼Áµ¸À¾´¯®¦©¯·šn|g[cZ]_HE>AKISXY^AF99=9F??:7;;;63:7:9>8::<=998;9;<:>=;@@;<B<@:847<;B?AB>>;CDD@CC=>>9a™•‹‘…–’ˆy}{…‹ƒŠ‚Š‰†k€x‹–š‘””‘“–—šš˜–“’“’››ˆvwsq}r‘ ›››œžž ¡ ››––›œšœ›œ›˜™š˜˜™ššš–‹“–™˜•˜˜–›œ—•’‘’‘”“’—›™˜›—Ž‹Ž‚‡‹‹‹Š‹ˆ‘Œ‡‡†Šˆ‰‘Š‡Œ„…Š‹Š„”Œƒ“”™•‹”“‘•‘–•Ž‘Œ”ŽŠˆ‡†‡‰‰‰Š‰‰Š…‡Ž‰˜’”š›—˜ ¡§ ¤£šª©³¶±µ°¨©¢¨®­Ÿª¯°­µ¹¸¼Â¿Áĸ±µ°®¶³°¸¾¼º¼¾º³³§±·Âu€cb^ZWRMHFEPIYW_[CP:BC=GF?87::75597<9<98:=>::7;;>;;=;=?A;?><?:8537:AA@B>>:CDC?AC;=>9g©¥¢¢™Ÿ ¢¦—”ˆ‚ˆ‚u‡ˆŠˆŠ{{v{zyzˆ’~}|z~‚‘…€}s|}|„‡~tpxvs|vˆˆ‰‡ˆŠŒŒ‘˜œ—ˆŽ„‹‹ˆ‹‘‹ŒŽŽ‹……‡‹ŒŒ‡ˆ‹Ž‹‡Œ…†‹†ŠŠ‰Š†ˆ˜‘ˆƒˆƒ‚…|‹‹Œ†‰‹ˆŠŒˆ‹Œ–‡‰‹ŠŽ–““œœš–œœ›ž›š›˜—“‘•–’‘‹‹–”ŒŠƒ‹„„‰ŒŠŽŠ‹Š‘‰“““”•“’œ™ž—Ÿ Ÿ¥¢¯±©®¤¤Ÿ˜¤­¦¦¸·¬¬»½½ÂÃÀ¿¿¯¥­°°´·¸³´¸¶´µ®¬´¯¸´¶yzcf`^VPQAEKOI\^_TGGBKLBD@=88;957797;7=<9=>=9;8:;@<:=:>BA8?<:?86429;B@?B>=8AB?>@D;@>7`¥ š—¡š¡ ——Ÿ—•‚ Ÿ£¡š’ŽŒŒrqpovqnpmnpvnoophpqpt~sqrqw{ryvwrrwvz{y|}{ˆ„‹‘†‹‹†Š‹‹‰†„†‚€‚‰‘ƒ€ƒŒ†‹‰…€‡}€’†„„†ƒ„Œˆ‡‹ˆ‘•‘ŽŠ“—Ž•˜§¤Ÿ•˜––¥Ÿ›«¦ª·µ¸²±§¯ª§¦¡Ÿš–’••‘ŠŒ‰“›•‹‹††‰Œ•‹™’••”›˜“”Œ‘Œ–—•¢•ž¦©«§££ª°›œ¦Ÿ¦«¡´½¾³³¿¹»»º¹¼½®¨®±®°¸¼³´±±ª°©¨±±²¨¥wrt_ha`TVQIJHVM^^^TLJEQJEGC=:9974868388=:=<>;9;8:;?<<>9?C?8;:8<776379E>?C?=7@@A=?D<>=8TŒ†‡‡”Œ•™—œ–™–•œ–•œ  š˜–xqnmrxqqlnrpkqopmrs{uvwy~uqxvtw{rn|}yx}yƒ†ƒ…‚ƒ‹‹‹‹Ž‹‰‰…‚}s}ˆ€~œ„……‰‹Šz}}†ŽŠ†”‘‹—”—’˜¡–ž—•›§¦Ÿ  ¦°«¡£¥µ´²ª¦ª¯¢±¶¹½Â»¹Ã¾¼¸½¸µ±¬°¬¥›’“™Ÿ›”“•Žš šŸŸ—£ª¬¡Ÿž›­¡§ª°©¦¦¤˜‘‘•”£¤¢¬¤¬³´³³¨·¶»¸°²¯­­²·¶º²µº³·¹»¸¼º¶²¯¬±±²³´³±±­®³±³³¬¡—vqs_c^RQTMOIGXOZ\dTNGUOEDJD>8:875888597::=<?:8<899=;==:B>?8;:9:986257B>?D@@6>?B?<C<=>:N|‚ŽŒŒ““——š”––‘‘”—“ššž¡œrorqqqqqpnsqoutrqvw€uw|y…~w{|y}|€‰‰‰ƒ}z‡ˆ‰€€†ˆ†‹†ˆ…„ˆˆ‰„€‚z||}~’ˆx…‹Šƒ„…ŠŒ‘™””” ššŸ¢­±­©¤¥­¯¬¬¬µ®¾¹­®©µ°·±«±¶¬¯½ÂÂÀ¾º¼¶²®¶¶±´®º»³®¬§©§«§¢©­ ©¨¢¯°¸´±¼ººº²´µ¯¼´·³··»·¹­­°©¬µ¹±·²´·¶°»»¼»ºº¼µ¼¸´Áµ¬ªª«´±·¸¹µ¶´³°¬¦®°ª«°±«¬®°²±´®ª£“xvreg[LRPFMHSWRe^gTPL\QHLRCA997958866;79:<:>98;:::<<>=<D>96;;88>95156BFDD?@7>>C>:A?@@;K‚‰—˜”––›˜‹’–Ž—‘‘•—”™—Ÿ›™œ|tuvuyustnvrstuvw}}~z|ƒ~‚}€„‚…‘‰‚—ŽŽ‡‚€ˆ‹…~Š‹‡Œ‹Š‡’Š‡†‘“‘‘„‡}}ƒˆŒŽ‹ŽŠ‰Ž””˜‘•›š¨®²¯¯µ´³­²µ¸°¼µµ±ª°ª³µ´»·´³¶´µ¯¸¸·­§¢¦¬°°¯¶··¾µ¹¼³²±®µ»°´¯¯²»¶±¸À½´´´³¸³¼º¶´ºÀ½¹º¹º¾¹¹¹¾µ²±¯²¯ªµ´±³±´³®¸¸µ¿¯¤¦¨£«¬±¯³®®°°¬­«ª«¢¢¦¨¢§­«ª¥¬§¢§˜xyqfeYOOMIRMWLO_^\NUTbQDTM;?9<895775795:::9;8:<<:=<>>??B=86::9:@;5266AFCC>?7>=CB9?B?>;KŽ‘“˜™•™‘“¢˜“’’‹“‹Ž•—–›•”›†‚}zxvttst~wzwv€‚ƒ†‹Œ„„…Š†‰‡‘“–‘–š•ˆŒž˜–•’“—šš˜ “—š ™›£ •› ¤£š“ˆˆ‹‰‘‘Ž‘Ž‹˜šŒ”š—œœ›Ÿœ¤¬´¹º¼¯¶´¸´´²·¸¹³«¯ª¨¬µ²²µ®±«®¦·³³±¥¡¨µ°¯­¬«µº²»ºº´²·º¾»¹±¸°¹­¨²¸»®­´´·µ»¶¶¹¹¼·´¯±´·¶¹³·µ¦­©«¨¨¯¬©®­®§¢±´±´«¦¨§ £«®¨ª®¨¬²°¯¯©¨¡ž¡¡£¦£ ¢š¥£ž¨—rwngbUKTOOJCPK_bXZQ\S_LHQIA@9:866775894;9;9<7;>:8<<=?B@A=;6999:?;6378>FBB@B9>=@C>@FB>8G“–‘•“’”‘Ÿ™™•’’ŽŒ“––’Ž‘•‘’†yrsu{„Ž‡…‘“’˜œœ˜••˜£œš¡§ª©Ÿœ–—•¢¢¡œ™ž™¥¨¬¯­©§ª©¨§¡¥¨¨«©©¯¡›Ÿ¡££ šŸ œ”˜”˜  ¡¤ž›š¤§¤©«®¬¥£¨«¯±´®ª¬®³¯¬¬´³´¹®®­¬ª¬²°°­°¨ª¦²´´¸®ª¶º°¯ª®¬°·³¸´·µ´»¼¸µµ±µ«²¬¨²³»¯­±²´¶µ±±´³³¯¬«¯³¶´±¬®´ªª¦¥§­«¨¨«©ª¨Ÿ©³°ª§©¥£¢£°­©¦­¥¨«­¬©¥¤¢ ¥¢¥£˜™œ•ž¢¢¦—nuegdVOXKKJKSTpbYdW_[\RZPLC<89:698747748:<:<8:=97<<;>C?A>;9:9:;>=8458ADEDBC9>;@>B?GD>7B’›”••–•Ž–—š™•‘Š“”’Ž’‘ŠŠ‰”—š“‰‚†Ž•‘”Ÿš›¢ŸŸ£ž¡¡Ÿ˜£¤§¥¥¦©©­«©¢¦¤¨¥¤¡Ÿž££­­¬­¨«®®ªª«¤¡¢¥©§§©¨£¢œ››¤ ¥¨£ ˜™Ÿ¡¢©§ ¢¢®¬«ª§­®¨¥¤©©©©¦£¨ª©§¤§®°¯³¯«°«ª¯²¯°³¹¯«¨°±®°²¹³´¯­¯µ°¬³±®¬µµ´´³³°¯¬¬ª¬«¬¯±´³°°®°°°¬ª­«ª«¦¥®°²°«¦©°¯©£¤©«§¨¦¨¦«°«©¯©¦¨©¦¥£¨°­ª©¨¢©£¥§¤¡¡ ¢¥¡ž—–˜”› ¤©”ns^ji_UZNRNPORd\dc[\Y\PYOK@<;9:7:8735338:=9:89:9:=<<@D>@=9:<<<>;>95:<BAEACA9>;?@D@CB@7@‘ž˜”—™–‘‡‹”’—‘ˆƒ‰‹“Ž‡‡„…•™–˜—™–šž¢šœ¢¤¡ ŸšŸ ¡ ¦¡   ££¢¥¨©«­©ª¦£¦¥ ¥ ¦¨¦¥§¨¦©¨£§¦™œ¤¥¢¡ ¡¡ œ˜™Ÿ ¡¤¤¢žž– ›š¢¢ ¡Ÿ ¢¨ œŸ¡¥¡ ¦£¢Ÿ¤¡¬¦žŸ¡¡¤¬ª§¬¨¯«§´±®®¯µ²¬ª°«©­­µ°®®¬®·®§¬ª¤¨¯²¯¬«²¯ªª©««­©®®®±±­ª­©«§§«¨©«¢¦©¨¨¥¨¨¬¨¨¥¤¥¨§¨¨¦©¬¯¯¨«©¡¢¢¥££©«¬¦¨¥£¨¢¡ ¤Ÿ¡¡›Ÿš™•œœ£ª”osfnrd]]PUOWO^ddlgbaZZRTOMA:=::8;95163288;9999;99<;=?C>@=9;:;<@=><99<AAEAFA:=;?AABAEB8=Š–”“˜š–ˆ„Ž‘’Œˆˆˆ‰‰‘ŽŠŠˆ››™œ ¥¢¥ž¢£¡šž¡œšž›œ£¨§«  £˜ —œ¡££¥£¢¢¤¬¨¥© ž¦©§«©¤Ÿ¢ ¢¦¡¦­¦¦ŸŸŸŸŸ™šœœ¡ ¡¤Ÿ¡›šœ ž¡Ÿžž £™–š˜£¢¢¤Ÿ™œ¡¡¢ ›šž ¡¤ §£ª±¨®«¬©¤ªª«¨¬¦¥¬ª°³¯««©°«¦©¥¥¨«¬§¦§¯«¥§««©«¨«ªª«­¨¥¨£¦¥§¬©¬¨¢œ¤¡£¦£ª©¨¦§£¤§¨¦§¨§©¨«©¡¢¨£œž¦¥£¨¨§£¥¥¦© ¤ž¢ž—˜Ÿ¢¢¥ž˜”•ž £—uwkvwa_\UYQUV[c^r`h_cSQXTH><=8;9:85373347:89=9;:9<<A@C==>8;<=<@?C?:8:>?C@DA:;><@?CCEC9<‚˜™žš•’Š‰‘‘—‘‡„‰‚’œŸ¡¤©¥©§¨¬­¦¢¢Ÿ˜¤¦£¤­±®²§¦¬›žž›š£§ Ÿ£ŸŸ¢¯«ª¬¨¨«°©¨©¨¡Ÿ §©­°²¯¬£¢¦¡©¥ž¤£¢¦ ¥¤¢¥£ž žŸ¥¢¢žŸ¢˜•žšžŸ¤¡›•˜ ¡žœ››™™•žŸ£¨ž¢¨¡š¡£¦¢¤¨©ª¨«°±¨¥¥§§¨¤¥©©ª§¢¥¦¨¦ž¥¥¢ ¥¥£¥¦ £¥££¥§¥©©ª¤§¤¦¢¦§¤«©§§¤¡¥¨¬§¦¥¥££¨¤•£Ÿ› £©§¨¦¡££©¨ ¨¢ œ•‘šŸ ¡¦¢›—’šš •|wo}yf[[_^Z\V\hdocmihb^PP@?;:898<;634333799;<9;;9>=B@@=;=8<=@=<<CA>:8=?D?C>:9?<B??ADB9:€ž¤§¢ž›Ÿ ™™ ––Š†ˆ„‹Š“—”‘£¥§ª®­¬³²³´¸·­©ª§¯´²±ª®®±²®±­¥«³¬±±©«¯««¬¶°´°«±²±£Ÿ¢ª©§®·¶´´¶³¯¬«®«¶°©²±­®§¦ž¢££›œ—¢¨¥¡Ÿž£›ž¡š–¤œ›–™¢§Ÿ Ÿ£ ›”–™–—šŸ ™•ž¢™˜¥ ¤§ª©¨ª­¬¥©¤¥©§ª©ª¬§¤¤¤£¢™™¡žšš¡ Ÿ¥¥˜ž¤¦¤ª¨¢§¥¥¡ª§©§§§£¨¥¦¥¡¤¨§¬¢§¤¡¦¥¥£•—˜›™•£§¥¥¤Ÿ¥£¢ª£Ÿš™˜–œœš¡¡š““—˜›wrvxib[_^\bY`dnmkma_d`POA@<;9;8:9614364777:=:<;9==B?>?=<:?9:;<>BE@=9;@A>C<;9?9@@@@BC;9{š££œ ¢™Ÿ¢¢ ˜›˜–˜’”›š–—´´®µ¸³´¸¶·´¸¹·µ¹¸¹½¼¸ª‹œ²¸¼´½ºµ»º»¸³º¿¸·¹»±·¯¨®²­¢œŸª²¸¼¼½»º¿´¯±³µ´··¯µ´µ²°¨¤¢Ÿ —•š—¤ª¦¦¡¤£¤«¥¥˜¡¤£ ¡¢¨¡£ ¥¡œ“™˜˜™œ£žœš›—›™–¥š›Ÿ¡¨©©¨«¯¯®©¨©«¬¬­«¨«§¥£ œŸ£££Ÿ ¢¥©¦šœ¢§¤©Ÿ¡£¢¢ ¥¦§¦¤¨ Ÿ¢¤¡£¢¨¨§£¥ ¡¨¦¦¥£™›˜›“¡¤ž¢Ÿ˜˜• ›¡¥ Ÿ››œ›š™› š˜™˜“‘†€vxyxc[RYT__alhukpgiibYSL@<:;89797556285678:<;;;;@>?@=>>9:<967>;BFB<8;?CCD<>9>7>AB?FC;8p’š›”ž››•—¢¦£¢–—ž–——¡›”˜¾·±¸¹¶··¸»—”¶½»½½Àŵ¢»˜ ·¿¿ºÁÉ´»¶²¶¿ÅÁ¨ ¶³º±ª®´±°±´´¶¼¼¾¼¼½Æº¸·º½´¯µ±±º¸·²³²ª¦¦Ÿ˜¤¤§¨¤®¤««µµ®³ §ª¬§ª©¥¦ § ¡¦¡“–˜Ÿ¢¤£žœ¡ ¡—¤š™ ¦ªªª­®­­°±«¬­¬©©«®¨¦¥¦¥¦¤¤¦¦ž£§©¤¡œ ¢£¦ ¢£Ÿ£¤Ÿ¢¥ ¤œ›¡žŸ£¡¡¥¤¥©£¤¥¢¤§§¡Ÿž–“œ ˜™’ŒŒ—–Ÿ›–œšœš’–””˜“š˜Š‹‡€€|‚xa]YSah`fsositcidb[LK>:8898897345254669<<;=<?A?@@=>>89;867?9BEC<;<>CDC=@;=7=CC@EB<7gŒ‘“Šš•˜›••˜›¢§«¦•—˜•™¡ž——¾µ³´»º¹¸¹Â‡˜·«¸»ÀÂų£Ã§¸³½¿´Äǽ´»¸¾¶ÀÄÄ® °¢µ¶µ½¾ÁÃÆÃù½¿ÀÀ½¿Ä½¼º½¾´§ª˜±À½¸µ¹À³¯¯ªª¨­§§¤¯§ª´¼±´µ¨¯±°¯¬ª¢¦£¬ŸŸ¦«—š¨Ÿ¥¥Ÿ œ «°°¬¢«œ˜› ¨¯²²³«¨®·µ²­­©¦¥¨«¥¥¤­©¤¡Ÿ §žž¦¨©¦žŸšž¡¥¦©œ£›—¢¦š›šŸœš¡œ™ž ¨£Ÿ¡Ÿ¥¢ £¢¡”™š™“Š‹„“›Ž˜•›—˜“‘’‰—˜˜“‹Š‹}€€…p`a^^jbbnwuvnl[bQU\MG;<97979:7444143768<;;<<@@=@?>?>::9:7:?>EEE<==@BBBAB;<8@CC@D?;5_ŒŒ†…–‹”•—˜—˜Ÿ¦§¥–•–‘—›Ÿ›š—¹±¶³¹¼¼¹ºµª²¼±¾Á´¼Ç¹¸»®¿§ÆÿÊÆÉÈÅÅɼÂÇÇ¿±±§¼¼¾ÅÄÆÉÇÅÆ»ÄÀÅÆÀ¹¯½¼À¾¾³«ªŒ³»¾´µ·Âº­¯°µª«¦ª£­¤§±¶«µ²­³­¨®¯§¦°¯²­ª¯³¤«µ©§¨¤  ž©²¸¾µµµª©¦®²·¸·¶©«¸¼¹·±¯®§¢£¨§¤Ÿ¨£Ÿž ™¡œ¢¤§§¡ž”›š ¡¥ž ¡ž–£”–˜›¡šŸ–“‘–”¢Ÿšžœ›¡ž¤Ÿž•œ˜’“Œ‰“—Ÿ‰–‘›”˜‘‘•–ƒŒ•—–’‹Œˆ|ƒjfhaklfnuqruqf^_\RIE?:::7848<7654233657<:;<;=@>?@><=999;:<<>BDE>>=@CCCDD::8ABBAC@92[“ˆ„‘Š‹‘‘•’šŸœ“’˜”š—š•¶±¹µµ¾¾¶¸µ¸³¼¼ÄĺÃÇÁ¿´³ÅÅÆ¿ÂÍÇËÎËËÇÁÃÆÇÈÊÅÄÅû¼¼ÁÅÁÅÅ¿ÃÂÆÅÀ±“¾º¿Ã¶¶º©´³´©«³»»±Ÿ›±¯¬¤¬®´§ª©¨ª­¬©¥¥ž©¯«²»º¸»·¹·³¹¸³®¬³´ª°µ¹½Áº¾¾¼¾´º¹¸»º²±´¼»º»³³²§¤¦««¢¡ š›šœ—š›žœœ –œ–›™ž¢£”œ‰ŽŽ‘ž›œ•‡’‹˜˜–šœ›˜œ›žžœšž”Ž˜˜š“‘™—ž¡•˜š’—””‘”š˜““–’‹‘~z|tklncolhqwnyiia\gaQFDA<997644:8465332656=99;;=>;>>=;=99;;;?=ACABA@<@CCCEB;89D??@B?;2W›‘‡…’Žˆ“•‘””›”“–š‘³·¸¸¸¾»°µ²¸¶µ¶ÀÃÁ¾ÃÂÀ¾»¾»»¼ÄÌÄÌÐÊÆÆÀÅÇËÈÔËÊÈÆ¿»»¾Ä¾ÅÈÆÆÃÄø´À·´¼Á¹··¿À»®¥®·¼·­œ£·°¦­´µ¬®¥¥£¨¤  ¥™ª³²¾Á¾º¹º¸µ´²±´´³ºÀ¾À¿¾½»»½¾À·¶·¶»»²»¾¹¸¸»¶·´¬¨©©«¦¨£ž“ššœ˜‘’™—‘‘˜š—ž˜–“–œ›Ÿž”“‰‰~†ˆ‹–”˜™‘‰•‘—–•™›š–˜—˜žœ¡˜•™™›˜—œ›Ÿž£œž–˜—“—œ™™œ”–”–“‰vyz{vnkiguZfrwsxef]d[RXIF?;78876169744333646;8:<;=<8=><:;<:=;;>>DAADB@@ABCCDC=99B@??@?=2L–š–’“ŒŠ˜‹‹Œ’’Šˆ†˜Š”—³»µ¶¿½½±¶¸Á½¼´¸¿Á±¸·¾ÁŽ»¼ÂÆÉ¿ÈÎÉÁÄÁÇÊÊÆÊÅÌÈÍÆÈÅ¿ÃÀËÍÏÉÆÃÃÄÂĽ¸¾ÁÃÀľÁÏÏÎÆ«¯¶´µ« §´³®«¸µ³«©£¢­©¬¦­Ÿ¬µ´¿Â¾¹¸½¶°­«¬¯µ´º¾Å¿»¼º³¹»¸¹¹µ­°´½»±¿¼¸²¶¹³¹»´­­¨¬¬ª©§—ž›š•Œ˜”“‹•–”œ™—•–™’˜Ÿ™ŠŠ~‰ŠŠ‘Ž•—“”Ÿ™–”™˜™–˜“”›¡ž¡˜˜š™™–žž˜›¢šœ›˜š›™–——–œ™”œ˜~€xyuueeiig]iomxwbb``]XWFE8:8:979449766512334;:=?;==::=;<>:;?><B@CBBEB=?CCCCDE@9:BAAB>BA5B—”•™’šŽ’‘”•‹Š‡Œ”ˆ‰’š¶»´¼ÆÁĽÁÅÂÀ´³½¿¬°¯ºÃÊþÍÈÅ·ÁÈÅ¿ÁÂÈËÊÂÂÄÉÌÍÏÏÌÃÇÆÈÈÈÇÉÇÅÉÇÈÇ¿ÅÇÄÄÇÈÊÒÏÒ̼¸¶´¸¸Á¾¾º½º¼º¼¬­¦©»º¹·À²µ¸²Àƺ··Á³±­­©«µ³»¶Ã¶¶½µ±·¾¶³·¸°µ¶¿»°½º´«°±±³¼º³³®«­«­±££ šŽ˜—•œ––˜–•’œ™“›Ÿœ–‘”Ž•‰Œ•“”›ž˜™’’œ—”™’“–™˜•œž£œ•Ÿ“œ¢œœ Ÿ£ž˜”•——›š™ }qtqob`gugiitmxl]d[U_YLHC6<9988:53:664413525;:<>;;<=<;<=<;<?=?B?EABCC>@A@EEDEA;7>CBB>CB8;š‘–š”’”””Ž•”Ž‹Œ‰“‹ˆ“›·ÀºÆÅÄÃÌÂÁĽ¾µ¯·»¯¯³ºÀÇÅÄÁÌËŶ¹ÀÂÂÄÇÊÑËÂÃÄÆÉÅÍÐÎÇÌÉÂÁÆÁËÊÈÆÌÉÍÅÆÅÃÆÅÉÍÐÍÏÌÇÄÀÃÂÉÍÇÅÁÄÇÁ»¾´±°°Á¾¿ÁÆ¿¾¸·Ãºº¶À¾µ²¬©¯²¸¾´À´´¸´·¹Ä¹¯¼¾¹¾¿Â¿µº¶«ª¬®¯°·¾¼¶´®­­®µ¤¥¨¨¦šœœœž¢œ™“’•˜ ˜˜•™™™—ŽŒ”}—Ÿ™™˜“‘“ Ž’•Ž”•¢œ¤ž›žž–œ£ ¡¢¤£¤¢žš™››œžœƒ}r|xpg`jjvlidtnsb\bTWTSMG:7;9977:748784523425;:9>:=<?=8;=999=<@A@EBABAA?@?DEDE@<:>BCB@CA:4€¡—”™˜•‰”“–“‰‘Œ”‘Žˆ–Š‹—œÅËÃüÀÃÇÁ¹½½»¸¶··®²·¸¼ÀÂÀÂÇÆǺ¼ÀÂÄÇÈÆÒÉÁÃÿ¿¾ÄËÈÊËȼ»ÈÇÉÍÈÃÈÉÉÅÅÃÂÁÂÇÇÈÊÇÌÈÇÈÍÆÌÏÅ·ÀÀÀÀ»»½µ³³¿¿¹¿Ã¹À·»Á¼º¸»¹½»²°¯°¬¹Â¸½¹·µ·º½Å½¸ÆÈÂÁÂƽ¼µ©®®°°¯³º·¹¶°¯­¯³©¦«©®¦§ž¤¥£££¢ ›•˜ž‘—œ—‘‘•—™•™‘”˜’•Œ˜£šœž…‰Ÿ“|’–•’””—§ ¢¤ŸžŸžŸ¡¡¤¢¢£¡£¢œŸž£¡¦™yzyrofegcjdajmnn^X\VUNPJF99;97677637895613527<;<@;?<<:8:<998>=@??F?BAC?=A>@DCCA<9<CACDA@:3l¢•—–˜˜™˜ˆ’‘••ŽŽ“––ÊË»¹º¹Á»º·¾Á¼¼»¹±®µº¸¸»Äº¾À¾¾»¼ÀÅÁƾÆÁ¹»Ãº¸¹¼¾ÁÆÁƺ¹ÉÉÃÅÄÀÄÁÂÁÄÁþ½ÂÀÀÁÂËÃÆÌËÅÈа¾½¸º»¼¾·´°¹¾³¼¾±¹µ¸»¶¼³µ¹¶¹¶¹·±­ºÁº¼Á¿·¾Ä¿ÆÃÃÇÇ»À¿¿¸²³³µ´±®·´·µ´±¬­±§¥¥§°­¨Ÿ§«¦£¨¥¦¦  Ÿ”˜™”‘‘•”—“˜—š¡ž¡œ¡¡¥ –”›‘——˜š“ž™™©¤¥¤¥¢ šž ¤¢£œ¢¡£ žœžž©¥¨•}{ƒxnfadbabccjbfbZYY\XQNE=;9:;77996499:5314527:;:@=?<<977;:9:<>@?>D<BAD@?>=BDBBB>:9B?AB=>85YŸœ˜“™–‘•˜˜š—‘“‘“”’’’””ÅǸµº¹Â¹¹¼ÃŸ»¹±±¶¼ºµ¹À»»¹¶·´´µ¿º½¿¹½ºº´¿¸µ·³¯»¼·À·¾Â¿Á»¿À¼»Å¾»ÁÄÀ¾¾¸¼ÁÁ˾½ÉÄÀÀÊÀ±Á¿»¸»¾¹µ·´¸¼´½¸µ´°³¼±·¶¸¿¶½¹½¾¹·º¾»¿ÀŽ½ËÃÆÃÄÀþ¶¹º¶¿¸»¿¼¸¶³²«°°²µ³³®¬«§¦ž§®­«¢¨«¦¦ª£§¨ª£Ÿ˜››š˜œœ˜—œ›¡¥šž¡¡ ¡¦ š›œ˜› ŸœŸœ ¨¡£¤¤¢Ÿš¢ ¢Ÿž—¤¡¢Ÿš˜ž¨¥¡‹|y‡}qc`bbgjffiei]UUSYOSKE8?6;;779;65:;<6313417;98?=>;<;76998:;=@?>@==?B><@ACCA?C=96<@A@<=87I”˜›“”‘•˜•‘–’•‘‘”•”“’’˜•ÁÂÀº¼¹¾¶¸¾ÄÀ±½º²´³¸¼µ·¼À¼½´´±°µ·µºÁ¸¾¸¿¼½·µ·°®¸¶¹¿»ÀÀ·Á¼»Ã¶ºÈ¸¶¹»½¹º¶»ÅÅʽ¹ÅÀ¿¼Á¾¸Æ½ÁÀ¼Å¸¶·´¸¶¶»»¸¶´·ºµ´¸¼½¹¿¹ÃÀÀ»¹¼»¾½ÈĽÇÄúÀ½¾¶²¶¸²¹´ºÂº·²±¬¬«­²¯²®¯¨£¤ž«¬¬ª¤¦¤¤¨ª¢§¦­¨¡¡¡¦Ÿ£¢¢ž›œ¢Ÿ £œ›¡Ÿ¢ ¤ ž›—™Ÿ¡žž¡¥¤¡¢¢¡ž¡£œ¢ž ™˜£Ÿž š™ ¢¦„zƒ€xpmeefoiekgXXNKKJRILHC9>8=;6:;967<89860431799;?=>:<:889<8:;;;<=A>==CA<?CCD@??<:7>BDA?@88?‰˜šŒŒ“—•Œ’š’‘—˜–””’š”þÆÁÁ¼¼¸¸º¿·¼±Â¶´¼±´¶¸³º½¿½¼²­¯¬±°·¼¶»¼ÀĹ···¶º¹º»À½ÃÀºÄ¾Ǹ¹¸­·µ¸º´·³»ÅÆËÁ»ÆÀÀ¿½¼¿ÉÃÄžƸµ²²½¸¸¸¾ºº¹¼»º´·»º¹¿¼ÄÀ¿¹º¸¿¹»ÅƽÅòº½»±¯¶¸³·³º¾À¹¶¬±«®©ª©­ªª®¦¤¥§®­©¥£¢£¡¤¥¥¦¢¦­£¢¥£Ÿ¡£¡œšœ¡Ÿ ¥¡ žœ ¥ ž—•™ŸŸ Ÿ¢¦¥ ¤žœ›Ÿ£ŸŸ™œ™ž¤œ–œ£œž¡œ¦–~†|knpgpksebl_[THKJDJBCG?9;8=<7;;978;7<<6275169<<=<A;<:;:9>9:;==@>D?=>D@??AFD??<=97?ACB@B9:9wœ˜‹‡‹’“–“š“˜’‘ŽŽ˜’½·Ç¾Ã¾½»¾¼½¶º¸½º·½³³°¸¸µ¹¼¼À·ª­¤®°·»³½¾»Ä·¶¸¶·À¿Ä¼ÂÅÅÇÇÊÉÆÏÂÁ¸¯µµ¼¾¸»²¾ÄÄÊÅÁÉÿ¿¾½ÇÌÇÇÄǽµµ¶Á½º»¿Âº¿Á¿½¶·½½½ÁÁÀ¿¼¹·¼Â»·¿Å»Â¿¾µ·¼¼¯¯·¶°´³º¹º»¯©­«­«¬¦ª¢§®¨¥ª­­¯§¤ Ÿ¦£ž¢£¨££«£¢¢ž›››”–™œœŸ¥žŸž™˜ž—£ œ—™š™š££¢ž££§ ¦ › £ž– ™œ  ›”— Ÿ¥œ˜¢†qelintnwcga[bPKTHEECGC<;98=:7:=:89;7<=53650689:<;@=<:><9>99=>;?>C<?>@?=??FD@A?>:7?@CC?A=:8f¡˜‹•’••Ž–™•—›•ŽŒŒ›“¹¶Á´¿¼¹¼ÃÀ¾Àºµ¶²²À¸¯²¼¼°·»¶»¼«ª£°¹½¾³¼¾¼Å¸²¸¹½ÇÉÊÃÇÈÆÆÉÈÌÎÑÌÊŵºÀÃÈ¿¿µ¿À¿ÆÆ¿ËÆÿÁ¼ÀÃÌÊÇÅÆÁ¹½¼Ä¿À¿ÂȽÇÇÅżºÄ¿»Á¿ºÀ¼»»ÀĽ·¹Â¹¾½·´¶¸º®¯µ±°°²¶·´·¬®¬ª¬¬«¨«¡¦³ª¥­¯­¬¨©¥£¤§Ÿ¢££§¡§¢¢žœœš™Œ–—™¢™ž›•’”¡ ™žŸ˜˜¦¦¢Ÿ¢¢¦¢§¥¢ ¤£¡› ›œ¢Ÿ—••žž¤š–Ÿ‰ƒtolltkln_b^aaMHM?E@?DC;;::;:8;<:9<>9:>4455199:9<;@<?==<8<;:<;;?>C>B>@?=??EEBAB?;6?BED=AA::YŸ˜“’•š•š“–—œ•›™–”•‘’“™¶¸¶±º»º¾Á¹¹Æ»¶µ²¥¾½´¶Á¿­³½´¸Á±°±´¼Ã¼ºº¾¼Ä¿·½¿½ÇÌÆÇÉÆÆ¿ÄÄÊÈÌÌÍËÆÂÃËμ¹½º¹ÀÿÈÆÄÁÁ¿ÅÀÊÉÃÃÃùþ½¹¿¼ÂÆÂÉÎÇƾºÆ½º¿¹·À¹¹¾À¾µ´¼¸¶»°¯²²µ¯°¯®¬®³°³²¸«±²±ª°««¬«¬¶­¨¬®²¦«¬©©¡¥ ¥¦¤¬¤¦¡ ¡ž¡  Œ”—“›Ÿ¦™žž™“˜Ÿ žž¢›˜§­¨¢¤  ¢ª¦©¡¨¡¥›  £Ÿ”˜˜¢§¡Ÿ›‚{z‡zmmw{_pc[]_^SI>BEIBC>C;>69:;;;;;;;==9=566218:9;;:A;?<<>7;<;<==<=@>AAA>>ABAECBD@<6>CDE>BD?;S™›™˜žš š–œ™Ÿ’•› •–”š˜º½´°»¼ÁÄ¿Åƺ¶¹²£»½´·Ä»°µºµ¹Ä¸´¼¶º½Á¼»¿¶¿Á¿¼¿ºÀËÂÇÈÀ¿¼¼¿ÅÂÇËÈÁÃÀÀÉÊÂÀ»»°´»½ÀÅÆÅÅ¿À¿ËÇÂÀÈÀºÂ»º³ººÁ¾ÀÊÎÊĽµ¼¼¹¿¹¹µµ³¿À¾·´³´¸­·ª¯°°²±¯«¯§¯¶®²±¹®¶¶¸´³°±­¶´º±®¬®¶§¬²¬­¤£¡§§¨²«ª¥¤§§¥¥ ¦—›£Ÿ¤¦­¢ž£¢š¥¢¢ŸŸ¡¥žž°´°¤¥žŸ¤©§¯§© « ¢¢š¢¤šž¡¦§¯©±•‚{}‚zmsxsgp]Z^\YQEDCMIAD=G::59;:<<:;;;=?:=54512788;<;B<?>:;6:=:;>=?@?;AAA>>?B@ABBE>:5:ABI?@B@;LšžŸ˜ž™ššœ’ •›žŸ›•‘‘–žº¶Ã¼Æ¾¿ÈÅ·µ¸·¶¹»´¯·¶²µ³·¹¼»¶»»½ºÃ»·½·¹À»º¸¸µÅÁÃû¹³´ºÁ½¿ÇÀ¹À¼¾ÅĽ¾¹²°®¸·¿ÃÇÃĽ½¿¿Ãþ¿Ç¼¼¿´´®µµ¼¾¿ÎÍË·²¸¸¸½¹»±¶²ÈÀ»¶´±°·¬³©°­­³·¯«®ª±µ¯±¯·³ººÀ¿¶·¶²»ºÀµ²­³·¬°º¯²¥¢¥«¬¯¹³²¨°¯±¯ª¢¨¡¤­¨­¬³®Ÿ¨§¦¥¦«¤¤ž¦ª£¦²¸³«¥œŸ§¦§®«ª¥°¥¥¥›¤£˜Ÿ§±¬µ¸°²Ž„y|wluzpmh\__YSPAEHGK@DCH<=6;99<;::;:=?<=55613698<A>@;=@;;9<=8:=<@>::>=>==>@BBBAD=745=DG=CB?<E”ž   œ—š˜˜•™™Ÿš›œ–‘’ÃÀ½¼ļ¼»Å»·³·¶¶»»³ –µ¬¯±´´´¶¸¹ÁÀ·½¹¸¹¶µ¿³´²¸±»ÁÀ÷·­°µ¸¸¸Âº´»·»¾À»»¼®¯®³²¹ÁÂÄþ¼¿»º¸¶Áµ¿ºµ®¯­°½À¹ÏÊÉñ¯µ´´½º¾¹º»Êûº¶¯°½±¸¯²³°·½¶®¯®°·°¬¬²¶½¼Äº½·¶À¿Á·µ°¶²±³º±±¯§«¯«¶¿·µ©º³µ¹±§«¨§¶®²±µ¹¨¬¬¯ª¯°ª¨§¬±¬²¶½´±¬¤¨«¨¨«¬«¨¶©¦¨ž¦˜£®¼±»Á´¦‰|‚zrvvwmp`^e][TJ<>?FF=FCC9:5;99><<::<>>>>88315789>?A?;:?=<;==9;<9;:7;>==CA??ABDBA<858=CF=DD?<?‰žŸ——•”“–™ž››š›˜””ŠŽŽÁ¾Ã¾¾¾¹¶ºÀ±µ±³··Âµ³«­³¨©®µ¯­´¶¹Ã¿·º·¶¶²´À¶²´¸³ºÀÁù·²²²´²·¾º³µ²¼º¼¶º¾²´´´°¸¾ÃÆÄÀ½¿¹³¯²¼º®»´³¦«¨­º¾¸Ë¿¾¬«°¯³º·¹¾»ÀÅÁ»¼·°µÄµ¿´¸»´»Ã³¶¶±¸¬©¥«²½·¿¿»»·±¼½¼¶±¯««©­³¯°°«°´©¸À¶²©´µ°·¶­¬¦«»³®´¸Â°±±µ±²µ±¬°²¸¸¹¸¾´±³®¬±­©¯®ª²¸®­­¨§¡ž©¶¿¸º¿°–‰}€|qswtvql^b`[]NHA?=HCFMD@775;:9><<98=>;=?:8325768??B?:8>>=<9<9;;:<;;:<@>BB=@A?BB?<;7:<AD>BC?>AŠ ›¡”˜••“˜šœ–›•š•›„ˆ†»´½¿»¼¹·³¼¼¬³²´´¶ÀµÀ¯²³ªª±·­©¹³·À½»¼¸¶º¶±Àº·¹¸¹»ÁÁÄû»¶´´°¶º¶´²¬¼¹¸µ¸Áº¸³±¬·¼ÁÇÿ¹ºµ®¥¬³°¦°­¨ž Ÿ¥­¶µÂ·¶´¥¨«¨°¶³²ºµ»»»µ¸¶°µÄ²¾¼¿¼¹ºÅȺ½¾¶±§¤ž¡©±®µ¸¶²°«´·¶±¨¦ž ™¥¦¤¬§«¬¶©¯º±­¤¦­¥«±«¬©­¸¶°²¸Á¶±±µ±¯»¶²·µµ²¼µº²°±²®´²ª®­§¸µ²µ­®ª¨¨²º½À¶´©Ž‚{vo{ourmb\fX\]RNMA>JB@JI@665;78>:;87>><;?:9327575<<><<8>><<999;;;>;;9<>?A=<B@??B@>;67:@DACA?AB‰ ¥ ”–˜˜•ž œ—›˜™‘Œ™‰ƒ†„µ¯´»»´µ°±¶º®°´³¯µºµº°µ³±­¶º®¬¼²¸¹·»¿½¹¾À´¿»¼º¸¾Â¼ÂÊǾÀ¸¹¶²´¶³´¯¬»º¸¶¹Àö®®ª²¶¼½¹¶²±­­Ÿ¤§§£¦–™™šŸ©®¹¬««Ÿ¥¨¤«®®§¯¬¯±±­±®®°¹°´¼¾¸¹¸Çż¼»¸©¢œ˜›Ÿ§¦¬±®²©¦©ª®©¢š——‘œš˜£ž¢¢¯§¤¬¦¨ššžš¡§§¦§©¯¶²«´¶¯ª°¯±©¹¶±µ±®¬·³¶¯®«®«´µ­¯««±­±²¨­««³µ·º½°«¡‹z‚yqvsmtik][jT\\OMHDFLAFMF8665:5:>8;97<=:;=:9236777>;=>::?><;<::;9;>;=9<>=B<;@?@?A?>:55:@EBDA@BAˆŸ¢¦¡˜›žš¥©˜›š™”Œ™‡†‡†®­®¸¹±²¨®¯¸²«°°ª²µ¹¹¾µ²¸´¹ºµ¹»µµ³µ»¼À»¾À´¿¹¹º±ºÃ¼ÂÊÅ¿»¿¿¹³´³±±®°¹¹¶¼¸»¿²²²®±®¹¯ª«­¬£¨¡ž—˜¡•’•—˜Ÿ¨®¤£¤ ¢§¢£©©¡¦§¥ª­§¬§¨§¬«¬²»´³´¹º¶²¶­© š––›Ÿ«¬«¯£££¡© ›“Ž“’’™–š¤¥ Ÿž§˜•’”˜ž¤£¡¥ª¬­¢©ª©¤©­®¥´±®±­ª©®¯°­¥¦ª¤¨³®­¬©¦¦©«¦ª§«²¬¯³±«©–wrxhtsndT`cW\QNLH?HQCMC=8875:7<>:;<89<;;<;8248978;;<;8<=>;=<:9<:;==<::@=<<;@>B@A?>958;<FACD?AAˆ£¦¢£ž Ÿ§Ÿ¨ª›Ÿ›œ™˜Ž—‹Œª©¨±¯°­¥§¦²¯©¦« ¯°»µ½¼·ÀÁ¾¼¼¼¹®­¯²²ºº··µµ¼´¯´«¶º¸ÀÄÁ»µ¼½¸²­³°¯¬®·¶²´´¯ª¤ž›œœž¨¨Ÿ ¨©Ÿ¡§–›——“–Ž—›¤¨  ¢¢¢¥¥££ ž¥ ¤¬¤¦¨¤¢££«¬³®©®®®§ª­¨¬¡œš˜™˜›©¨ª«ž¥¢›£œ”ŒŽ“–•–˜Ÿžžš˜¦—“’–¢ ¥£¦¤§ ¢¤£¡¡««¤²­ª¬¬§£¬®­«Ÿ¡¢¤¤¯¬¬©¦£¢ª¤ªª¤©«¦©¬«¦ ˆyƒ|vybvln\PhTPNGOLLCOQ@>;>39:5;9=;:9=99<;<<;936996:;?=:8;:><:<;9;=;<<=><@=?<8;@@A??>949<7ACBD=@CŽª¤£¢¡¢ª¤¦¨¦¡ž™˜•“•§¤¡¦¨©¥¤ ¡§«¡œ¢›§«µ²¼½ÀÂÂÀ¾À¹µ§¥¬ª¨µ²±°®¯²§¦¯£¯®µÁºµ·²·¶²´«²´®ª«¯°²´®¥ž’˜”™ Ÿ¢ œ¤¥Ÿž¨”›–—Œ—‘—“˜¢ªŸŸŸ £¥¨œŸ ¡œ¢Ÿ£¨§œ§¡ ¤Ÿ¬¨¬¬ ©«¦ ¤¨¦¬£ž™—š«¦©°£¥§ž œ•“‘˜–•˜—Ÿ˜›™›£™—”•š §¨¥ £¢¡£ž ©ª¥®®¦¨©¡¢ª®ª§¡ ¢£©¬«§©¦¤¡©¢¥©¦¥¤¢¦¤¨£’}}€uu}mk{dhUQcMIHGNRMJMG;D@<2?859;>;99;8:<;;;9948;87;;><:9<:=;;<=9<<<>==A>@B@=7:?AB@@?855<:@C@D>AF–®¤¢¥ž£¢©¨¨©ª¥¦ž¢˜˜™™•›¢ž›ž£¢ £ ¡š ˜˜—–¡¨¬®¶·º¹º··»®¨ ¡©¡ ­«ª¦©¤©£¤®¥¬¬´¼·¬²±¯±­µ¯¯³µª§­¬£œ™”Ž‘–—™™ £¢›¥žš¤———–’‘‘“š—› ¤ªž¡¡ž¦§ª¢Ÿ §ŸŸ¤§©ž£¦Ÿªª­ª®§¨°¥£¤¦§¬¦¡¤¡›˜ž¯¨®±ª¥ªª š˜˜˜•“–š“••™•š——˜ žœœ—›¡šžš¢§¥Ÿ¡¢¢£œ›¡¦§¦¨­£©¥ž¤§©¤¥¥¡¥¤¬¬©¦«§¢ ¤£¤§§¡  ¥¢¦ ‰{€}vx|dxy`bRU_HIIKSTIRPL9>A67=65;:<<9;;8:<=:;8657:69>=><99=9==<>=;;<:>=<???@==7:>@@@??865=<>ABF@@G ®¤¦«¡£ª¬®­§¬©¨ ¢¦ž››žš œš•™ŸŸ›žŸž–”“—““œž£¨®­¬««¯ª¯©Ÿ—ž¥žž¥¦¤ ¢Ÿ¦ ¢®«¬­µ²¶¦¯´«©ª´±°°¸­§¡œžš”˜šš‘Ž’–‘ŒŽ”™¢œ—£™š—˜™”™˜–›Ÿ¥¦© ¦£ž§®®«¦¢±£š¤¦¦ª¢¡ª¢©¤¨²«±²«º¨¦«§««©¬¬§  £±­²°´©±¯¢™œž¡˜››š˜™›”•š–˜œ¤¡ š£ šœ™Ÿ¤¢ž Ÿ¢¦›¥¦¥¤¥¨£§£ž¦£¢ž¦¥¢¥¥¨¬¤¦­§ Ÿž ¥¡žž¥ ¦™{|vvsh‚le[SZYMQJNOTLRLA7>B68<76:<<=:<98:;<:;976:=59<;@=78;7=;===:;<8>==@>A>>>88<?@@=?758=>=A@F@AH¡ª ««¡¤ª«°­©­©§¥¥¥¤ ¡Ÿž¥——”˜™ž˜œ›–”™’’œ˜¡ª¢¦ ž§¡¤Ÿœ’œ¢›Ÿ¡£ž Ÿ£ ¢¯®¬¯±¬¶§­±­¦¦°®­¬°§ŸŸ£ —‘”œ¡œš˜’“Ÿ¡¤›ž›–ŸšŸ—›¢ž¥¡ž¤Ÿ¤¨­­¨¬¨¤¬´·¶°§´¬¢­­£¯¥¤¦¡©¨®µ³²½¶¾°¬±®­©ª´±°§«¨²µ·³·¬±´£ ¥Ÿ«¡¡¢ Ÿš˜••Ÿ››˜¤¡ £¡ ž›œ¥ Ÿœ¡¨ŸŸ§©ž¡£¤ ¦ ž§¡Ÿœ¦£Ÿ¢¥£¨ ©«¥Ÿ›š¦¢žœ£ž§‚|xuiwu]lZR`HQUHFUVJBMG=JH8E<67;>=<:<98::;:<966:<7;>=?>97=9>;<@<:@::@?;@>A@=<97:>@?:?758=>?A@D@BFœ«ž©©¢¥©©®¨¦ª¥¦§¦¨ª¡¥¤£¦’“•˜–œššœš•“™›Ž“ž™¨®ž§ž›¡žšš’˜žœ¢¢  ¢ŸŸžŸ©«§¬©ª´««­«¥¥ª¨«¬ª¥ Ÿš’’”˜™–––Œˆ‹•ž–žš¦  ¨¥±ª§®£«­¶°´²±®¶¸½Àº­µ´°·°®´©¦¤¥¬©¹³µ»Ã¼ÃÁ¶º¶«¯±¹·¼¯³°µÁ¼·¼²²´¡«¢©¨±©ª¨§§š˜™©¦ ™§ Ÿž§§¥¤žª¡¢ž›Ÿ¨ ¤§­™Ÿ£žž§ž ¦žœœ¢¡›£¢¡œ¦¥¥¤Ÿ¢™œ›¤Ÿ › œ£‰…„~vqmivmhm\X[BVMJGMGBFM<>L=4<96:=?<;::88<9:;;<54:<89>>?>88?9<;=?;=A=:?><@>?>?=<6;?A=;?867<<@DBDABC•ª ¦©£©ª¨©£¡© ¦¨§¬®¥©¥©ª”’—™”šššœ˜˜™œš˜šª ±¢·£°¦ ž—™–™ž›œ¤ŸŸ¤šœ¤¢¤£¢ª¯¬§©£ ¡¬¯®ª«§ ŸŸ¢£žŸž››””••žž˜”†š¡›«¤«²°¹²²±²±º½¼¼¹¶¸Ã¾¿Â¿¶ººÀĹ½»¬®§±­±Â¶¸ÂÆÀÈÊÀÊ¿°¹¹½¹Â½¸³»Åüº¶³©²­ª²´¯³®©®£«¦µ±¬¢¯¥ ¢¯±­°¤¤¯£¡ š¡§¡¤ªª™ ™š£ ¦¨¡œž¢ž™¤žž˜˜££¡¤ž¦™›¢¤žŸ›››œ‡…{trkkurphW[QETHDIPH>EA4EH95;=6;<><<::89<89;8::8;<7;>=>=68@9;;=@<=@97<=;>=>=B>>7:A@><>958=;=C@ACBA‘ª¡¥ª§¥ª¨¦Ÿ¢§œ¦¬§±²«­£©¬•’•š”—œ¢¡›ž ¡œŸ©²«»²¿«¯¬¥ž ¡œ˜›Ÿ › ŸŸ—¤•››žšžœŸ¥¦§  ¬±¯§¤¤£¡Ÿ¦¬§Ÿ—œ•’š™•ŒŠ†ˆ†ymˆ ¤¢«¬´¼¶Ã¾¾³»ÁÃÂÅÀ¿ÂÆÆÅÃÈÂÀÅÈÍÐÈËò·µ¾²¾Å»¾ÌÍÅÌËËÒƾ¿À½ÇÆ·ÃÉÈÂÀŽ¹³¹º´»·°µ²ªº±®º¶¾ººª·¬ªª¸º´»®­¸£¦¢ž§¥¢£©¦™›Ÿ˜š§ª§ ¡¡¤˜”£–”š‘œŸ¤ž§ŸžŸ¢˜™”˜”ˆ„}zrkdioxjeZ[FJLDDSLDBD7:?;549979>?;<;;8><6:=9<=9<=:;=>>>7;A:>9=>9=>87;::;??=B>?7:A@=<=866<:<A?AAA>’« §®¨¢«¥¤¢¢¥¡¥ª«°²­®¤©¦”••š–”›¤¦¡ª§¢«¬¼¼¿ÃÁ³²¸§¡¡«ª¢ž¡¢žœ› ’ŸŸ–Ÿ™’š–›™£¡¯³©¡›ŸŸš—˜˜“–—”‹‚ƒ‚wsqnp¦­®´¹Å»ÍÇË¿ÂÌÎÍÌÈÉÑÌÍÌÇÉÅÆÌÐÒÕÎÓɽÀ¿Ã»ÆÅÈÅÑÓÌÓÏÒÓÌÊÂÅÆÆÊÇοÈÐËÆÄÆÄÀ»ÂÀ¾¾¾µ½³­¾¿ÂÂÆÄÆí¾¸±¸¼ÃÁÁº¼¼µ®§§­¨ ¢©¥š– š™¨«©£¤¤ž—›‹™‰•˜› Ÿ£—žš““‹•…€ytsebgrof^ZYCNLCEPIDB@55589B=68:A>;;><9>=7:=9:<8<<<;??><=>C<;:@=:;::8889;A><@?>8;AA<;>786:<>B>CA@>“¯Ÿ¨¯¦¨«£¢¥ ¦¦¤«¨«­ª®¢ª£’œ——›˜›£¬žŸ®¦¥±ªÅÆÌÎÍ¿°Â©¥¨­­ª¡£Ÿœš©“™¡Ž “”’—™¤±±«¤  œ™—•“”—’Œ‡„„‰‡ƒ€€yrroly¤¶º¹¾ËÁÓÒÓÈÍÎÑÓÑÒÑÐÑÑÍÎÎÐÅÎÔÕØÒ×ÍÆÇÉÌÃÅÊÎÊÓ×Ñ×ÒÔÕÓÓÈÌÆÌÍÉÒÌÍÓÍÄÆÉÉÀÅËÇÈÈž³³ÇÄËÊÊÎÅÉ¿½¾¼ÁÇÄÌÌÈÉÀÿ­¯²¨ž¢ª£š“žœ˜ž¦©¬¤¥¦–—Š•…‘”‡’’’™›š–˜›•Œ†‘‹{ruvgbhwidVWQDMF@IQB=B<:23@<D<79<B=;=?;;>=9:><;>8:99:?:>=@>@<>;>;9==<96::>=<<@?>9:@A;9>9:::;>><A?A>¬¢¢©¦§¨¤Ÿ¢ª¨£¬££§¦¬¢©Ÿ”£˜–Ÿž¤¯› °«¨¬±ÉÍÔ×ÏƻǬ­´¸¬®£Ÿ¤£ž ¤¬›–©–—Œ—¦°®¥ž¡¥¢ž›–•–”Š}wpkebhqoq{…Š€vpnqtp…³Â¾ÅÑÐ×ÖÖÒÖÍÔÖ×ÔÓÑÓÔÔÒÏÑÃÐÓÖ×ÕÖÒËÉÎÐËÆÍÑÉÑÕÖÙÕ×ÒÖØÎÒÉÎÑÌÎÐËÒϾÆÆÉÂËËËÎÏÅÆƶ¿É¾ÒÌËÏÅÉǾÂÂÇÎÌÏÐÎÌÊÇ͸·»¨Ÿ¦«§Ÿ˜ž£žª¥­©¨¨’•ˆ„Œ‘†Œˆ“•™–Œ˜’†‡Œ„|xsvpc`erb]R\IJFAEHI>;@8=4585:76:<@=;><;9@;9:<;;<7==;:>;=<><?::<;;9;?=95;<><<=??>:;@B;9?98;==>?<A@D<†« œ§ §£¢› ›©¤¥© Ÿ¡¡¦Ÿ¨Ÿ˜¤¢›©¦¢¦¬š¤°±©¨µÐÔ×ÚÒÇÆË´¶ÂƲ¶©¢¥¦¡¢«µ§š±¡–•Œ¦­«œ•˜¡›¡¢Ÿž›–Šxida____^_`^blusqpolrqu’ÄÇÆÔÕÖ××ÓÖÏÕÔÚÔÔÏÏÕÔÔÑÑÌÑÎÓ×ÖÓÕÐÏÒÓÑÉÓÐÇÐØ×ØÐ×Ò×ÙÕÕÌÎÏÉÌÑËÎÏ¿ÅÁÆÅÎÌÐÐÑÈËË¿ÉËÅÓÍËÎÇÃÉÆÆÈËÊÔÓÐÔÏÒÌÒÁ¹Å±¥¨µ®§š¨¬¥²¨°³¬¬““Žˆ‹Žƒ‹„Ž™“™‚…Œ{zqstmacim_VP_JJBFCQM?<>44:=52755<<@<;<:9:@:8;:>:=8>::<@=<9;=?9:?=;=<==:6<=?@=<==>:<@B;:=74:><??=FAD=‚¤œ ¥¥¥£™œ¤ž££ŸŸ š§žœ¡©Ÿ¯®«ª«¦®¸¨«·ØÔÕÙÙÑÎÐÀ¼ÌÉ·À¯§«©£¤±¶³£¶ªŸ¡ª©¡˜–˜š›¡ž™ž”~rfcc__a`_a`_``_`fmppnkorww›ÌÀÒÕÓØØÖÙÑÒÒ×ÏÓÎËÓÍÕÔÑÊÏÌÓÖÒÑÖÍÐÕÕÑÅÑÔÊÐÔÕÕÍÑÐØ×××ËÈÎÃÈÎÌÉ̿ȾÇÈÍÍÏÊÐÍÎËÎÎÇÊÏÏÊÎÊÁÈÆÉÌÉËÑÒÌÓÑÑÏÏʽǹ°­»¸µª¶°­¨¸­³¿»±šŸ”‘ŽˆŽ…‘™Œ‘‘•Ž‘€…ˆyvopokbenpaW\ZIFFDLWE;@<33<=86855;>@=9<<8<>9<@;@:=8>98:?<=8;>B::=<:A==<:6=<?@=<;=>8;@A=:<88;><=>:EBE>Ÿ™¥§ Ÿ£§š›Ÿœ—žž¡ššœš¦›Ÿ¤§ž¸¶µµ­¥­®¾µ±ÀÙÒ×ÚÜÖÏÍËÃÓв«­®¬¦³±¸«³·©£Ÿœ–”—›žŸŸž•–˜•Šl__^adb```a``a^__^]bmroostuvy¤¾ËÕÑÖÔÓØÖÎÎÓËÍÎÅÎÊÒÒÏÆÎÍÍÔÌÎÓÍÊ×ÕÐÌÑÓÊËÐÑÓÉÍÑÕÒÕÕÊÀÉÁÅÌÂÇÉÂÌÂÅÇÊÊÎÊÌÌÏÍÓËÅÇÏÌÇÇÊÄÆÀÅÉËÌÏÐÆÏÎÍÍÌÏÅÇÀ·¹½Âýù²³¾°»ÃĶª˜¥¡™–‘••’‹”š‘”””‚‰…xprkmh``qhXXhVMGLIPPB;D>;67:89:57==@;:<=9<=9==:>:<8;=9;@<>;>>A<9=>=B=;775?<<?<<;<<8;A@<:<9;:;<=A:EAE>„ž›¨­ž¤¤ªœžŸ˜’—›Ÿš›ž™™¢•¡©©¥ÅÃÁ¿»µ²±Ç¹ËÕÖÙÚÛØÌÍÏÉÖÖÅĸ²¶ª£®­¸¹±²À¡—Ž˜–”’‘–—–‘Œ}fbcb`]^acb`_``aa`_][]grqqrsqmry¤ÆÓÏËÐÏÔÕÉÄÉÉÆÆ¿ÃÅÎÎÇÅÇÍÊÑÈËÎÍÆÑÒÏÎÌÔÊÇÊÍÎÇÆÏÒËÐÏźľÆɼÂÆÈÎÄÂÇÀÆÍÇÃËÉÊÏÇÃÃÏÈÆÁÆÇÿÀÆËËËÎÂÊËÈÇÌÐÄÅǺÇÃÈÈÂÏÀ½¼¿°ÁÊǹ½ª°²§¥¢œ˜›£™—™‘•˜‰‚wntdk`^fqa[W`GHHGIMTG?J=64355<<48===:;=<9:;9?=9<;<8:<::@=@<==><:C><?=889:@>?><;;;;8:>?<;:79<>=;>=FAC=ƒ ›ª®¥®ª«š —”Ž—š™ ššœ›¥³±¬ÉÍÊÈľ½ºÍÍÆÐÕÕÙÚÛØÐÊÐÐÒÔÊź¾¾°¨·ª¾¹¹³¥’ŽŽ–†ƒ„„‚~……€t`[^^^`^`cdc_]]^_``_[Z\akrrookloo}¸ÑÈÉÊÏËÍĺ¿Ã»»º¹¾ÈÆÂÃÀÃÇÊÉÈÊÇÁÅËÆÈËÍÉÄÁÉÉÁÁËÐÄËÈ¿¹ÁºÅǽ¿ÅÎÊ¿úÉÇȺÇÅÄÊ¿½ÁËÆÅþż¼¿ÂÄËÄÄ»¿ÉÂÅÇÒÅÁȾÊÉÆÇÆÐÃÃÆïÄËÇÃÊ·¿¼º´©¬¥¥˜Ÿ˜¬£ ¥š£ ›”{vrtfiZanmZ[XQDLFBGDLCFR?54334?<3:<<;9<<<8;=;A=:<:;7;=9;=;=;:8>><B>;?<99;?=;@><;9999:;=:<:69<><;>;CBD>¥œ©²©´®°žž˜œ‰”›™šŸ¢Ÿš¨¿¸¼ËÐÒÌÇÂÃÇÍÏÎÍÕÐÖÙØÙÐÌÔÎÏÐËĸÆÁ¶µ¼±À¶º¬‘Œ“—‡{€…†€vxusq_Z[]`abcdded`\\]]_^`[YZ\borokilposÆ¼ÉÅÌÀÆÁ°¶º²²´²±Á¼»»¹¸ÀÁÁž½¹½¿¹ÄÊÅŽÆÀ·»ÄÉ¿ÂÉ»·ººÅþ¼ÁÍÂƾ½µÀ½Ãº¼ÆºÂ¹³»Åö¿¶µ¾¿ºË¼µºÈº¿½ËÃÁÅÂÅÈÅÈÅÐÆÂÌDzÆÉÃÎÍÀÅ¿½²·°³§¨¨¹±¥­°«­¬”yvwjeh`hocV^YJEJFHKAEBEI@9:648853;:;<9<<;9;9:@>::<:7:;7:;;?<:<@=@?=??;=;;@<>>>:998978:<<<;9:<>;;>:@@E>~¬ ¬µª·´²¡žŸ—š”–šŸ¦¢ž·ÆÂÄÈÎÒËÊÊÇÍÍÏÒÉÑÆÖÕÖØÏÌÐÈÍÈÊŽÊÁ²µº·º¶¯‘ŠŒ…y€††€~„|tud\\]^``bcbbeeb]][\^\^]Z[]]hsqmggnpry½ÌÀúÀ¸­°°§ª­¬§¸´¶´³²³ºµ½±·°´®²»Â»Áļ¿ºµ²º¾À¸Ç¸³»µÀ¼·½ÆÀû´¯²¶º¾³Ä¶ºµ¬¸¼½À½°¹¶®¶º²Å¼¶®»¿´¶´Å¼¾ÂÅ¿ÃÄÅÇËÅÀÆÆ»ÇËÀÏÉÇÃÆÁ÷þ¾¶¹¾Æ¿¬µºµ·¶Žxtxfgebkn^V^`FKHHJFBCADE?<:565633;:;=:;;:;>8<A=<:;87999;<:>;9>?=@?>B@=@::>;?==9:::856;=><<:;9>=9?:<@@<ˆ·¦«³±¼¼±­Ÿ ™””˜—ž«£¯ª§¤ÆËÎÈÆÉÎÌÐÍÎÉËÉËÊËÆÑÏÓÑÏÇÊÆÊÅÄÀ¼Ï½³¹½¹¸·›Ž‡‰Š{y~††wx}th^]]]_`_`da^cec__\[^\]^Z[[]_lpnhfjnnr|¤Ç¿¹¸µ°«¬§ž¢ª§ž«¬³­©«©³­¶°²¨®§¬²»º¶Â¹º¹°«µ¹»´Â¹¯¿°½¼»µ»Ç¹Â¶­ª¨°±Àµ¸¼¯°§±³´»¼«­µ¥®¶®º±°ª¹¯­»­»¸»¿¿½¹Â¿ÆÂÅÀ¼ÆÁÇ˸ÅÇÅ¿ÇÃúÄÆ»ÅÉÌ˳¹Â¼º²ˆrvvkiablhYWW[ALKMIEAC?FA;9:995854::9;<=;:;>8;@<=9:79>9;<:8;;:>>9A=?@?;>:;<:=<<8989768<<=;<::;>=;?;;>@<ŠÀ«¨¸·¹Ã­³©™”–™¡œ¦°µ±·¦ÆÏÒÌÄÆÂÅÐÈÏÃÄÇÁÆÆÅÅÌÃÊÌÃÄÁÇÀº»»Ê·´»½µµ«‘‰|y~Š…z{„xn^]]]]_`__dcbccb`_^[[ZZ]ZZZZ]dnohfgiknr­¹°µ®¦¥§§š ¤ šœ¥«­£§¢«©¬ª°£¦Ÿª­´¶±½¹¯·¯¨®¸´´»·³¼®·¹´±»Á±Á®¤¨¢«±²³§¼ª«¨«¬­´³¥¨­ ¤¯©²¥§¨®¥§¶¬°²·¹º»±¼½¾¾Ä¿µÁÀÇÈ·¿ÀÄ·ÄÂÀ»¿ÄþÄÈÌÊ¿¾ÃÀÀ©†rsrji]aodWVXPHZRSKFFE>?@:789776437:99:<;;<<7;=;;;<89>8=;<6:=;?=7A>?@?:<<:=9:;:7778879<;<;9;:<979><>?A;ŒÂ¯®¼·¹Ä°¶°›™•œ˜ª©°±³µ½¯ÆÑÐÍÄÈ»»ÌÃÌÀ½Ê¹ÀÅÀ¼ÌºÃÆź¼Ä½¹¶¼Å¸¶¸»®±•ƒ‰{~€xt|swf_]\\^_`^_ccab``_^]\ZXY[[YXZ\_fkfegehkor…ª¥¬¦ œ¡¥”ž£›—‘¡£ª£¢Ÿ¤¤§¤¬Ÿ›¤¥«²¯¶·§°¬§ª´«´¹°¶´¬¶¸±¯º¹°·¤Ÿ£Ÿ¦±§«§¹ª¤¦§¨§²­ §¦žš¤¦¬žŸ§¤Ÿ °¬¬¬±³²³°µ¼¶»ÁÁ²º¾ÃÁ±¹¹Â³À½¿µ¸»½¾¼ÂÆÄÂþ¿Ã ƒwplae_ko`UY_HNhOTGEJF<=?=:;;825536999;9::<:7<?<<;<88<9<:;78::<98>:?=98<:;=:7676788666;::;9:;<859<:>>@;Èµ¶½¸ºÁ»¾µ ž”¡¦º¶«³³»³ÅÐÉÌÃǹ¸ÉÂÎÁºË¹½È»¶Ç»·ÃƳ¾Å»¶¯¸¿»°³¶¯¢„‡‡‚}yvtpmkjjqi_`]\\]_`_acb````]\[\\XYXXXVX[]^dcbegggjmoˆ© —•š¡–›¢˜•ž¡¢¦›žŸ£¥ §žš¢›Ÿª°¬±µ¢©ª©«¬¤µ¸­¶¯¬²´®²µ®°ªŸž£¢²¤¥©¸­¡¦¦Ÿ¨¬«™ŸŸ™Ÿ¥š™£œ›¯¨«§ª«¬­°²¸®¸¹º°¶»»º«³²¹²½´¶±±µ´¿µ½¿½ÂÁºº½—ƒzrk_e^ddXTX^IW]KPGIJFA<??@;?<04536:;9;899<<7>?;=;;88<898<78:;;:;?:=;78<:=<74776757466;79:;:8:98:;9:<?;‰É¶¸¾»·ÁÁÁ´¤¤™š¤¦À²¯¶¬´·ÆÐÉÉÁǼ¼ÅÅÐÁ¼Ê»»Á»µÅ¸µÁÁ³Âû¬©´¹·§±²©‹†ˆ€ysnpnkc^bff]]^]]]\]_`abccba_\[[Z[YXXWWWXXX[^bddeffhikr¨”””›—›¡––œ¡¡¨›œ¥¥ ¤›Ÿ š˜­­­¯² ¥¢­«¦¡µ°±±¬§®²§¹²¦¶ ¢žš£¡­¢¡©µª¢£¦¥¦£–˜—˜›Ÿ™—œœ›¬¡«¦¢£¥­«²³ª´°²ª²¸³®©¯²²²·³­©¬®±·°ºµ¹½¾¶³±”„yue^e^[YVSZUL\QLJEHKIB=?AA@@:245249989;9:=<6=?;<>;7;;777>6:>;:8:=;<=:;<:=;8797465546785::8:99<87:89>@:È½¸½¿¶¾½¿³¥£˜¥±Âµ¶½­µ¸ÃÍÉÈÁƸÂÁÈкÃÆÀ¶¼½¶Ãº¶¿Áµ»¿ºª¦°º±§±¯š}……€ypqtqhediec\\[[]]\[^`a^__`^\[Z\ZYXVWWVXWXXVWadecdeddhjv¢œ””•——Ÿ—™”˜Ÿ¡›– ¡¨£Ÿ¨œ›šª¦®°«›££¶© Ÿ®¨µ©¦¦¬°£¶¯£¶ ¢›˜˜«¦¡›¬¸¯¢¡£œ¡Ÿ “•¡”––›˜—–—œ•Ÿ¨©£¡œ£ªª°­§³«ª¦¬²°¥ª®²±¯°®¯¦§§²®±´¯»³¹·­£”yud^aVYWSRTKM^LPLGHLKE<@><B<;7553398899:9>:8>>;=<<7>=676=7;=;979;;<>99:;:867654531045679:8:9::7:;99=@:vÀ¼µ¹Â±¾¸¼®§§£ª»À½À¹®´¸ÂÍÈÇÄžǺÊ͵ÄÅı¿¿¹ÀÁº¿¿¹¹¼·§¦°»¦¨¡¤‰~xrjlrtpihedgb\\ZYZ\\\]^]\[\^\[\Y[\ZXVWWVWXWWWU[ccbbcbcdfj–“•‹’”“›˜œ––› œŸ• Ÿ¥¤£¥¦žœŸ¤Ÿª¯¦Ÿ¢¤µ§ ¡¢§³¡¥§¤®¤°¬«´ž ””©¡¡”¬±°ž¢£ž˜›“‹¡”‘“—˜’——˜–¦›¦¡¢™¤¤¤«¤¤°¦¥¢ª«¬¥¨®®®«¨©©³¥¦«®³±®»µ°¯®Ÿ’yvrea\Z]XNLQGRaMVPOJMOEBD?9=69:754599;9887<89=>;>;<69:7;6;7;;:85:;:;;6<;8846863321./2556;:8;7876<;:;;A8x»»±µ½°»²·¬ž¤¦­·»¼Áź±¹¶ÅÊËÁÄÇÇɸÈƵÅÂÈ®º¼Â¼ÂÀÁ½¼·º¶¥§±µ¢Š˜ˆ€wodbgihfhjgjm`]\[ZZYZ\]\[\^_\ZY[YYY[WUXWTTWUSTSU``_`a_`acdi”“‰‘Ž“’“œ”•–¤™ –œŸ¤¡¬¥££¢£¡›ªª¥™ž¥°©ŸŸœ¤ª§¡««©¨­­¢¡¡”—¢šœª¨°›Ÿ¢Ÿž—˜“Šž’’’•˜˜“› ¢œ¤ ¡• ¡£¤›¢ª¤¢¤ª¢«­¥­±©¦¥¦¦µ¦ª¨­³µ´¹º¯©¬ž‹rpo`[WVURFQOHZ\ORJTKSLEGIC8;;=<8666:9;::76977:;:=<<6;<8>598:88659:;<97?<9678452121..1426:86:859898:;9@9{µ´­´»²°¬²­§§¯¹¹³¿Èº¶À¯ÆÉμÂËÍÉ·ËÀ´ÀÇÌ°µ¼Ç»ÁÇý¾¶ºµ¤ª¯®™‡Žƒ|uijjmhjlnkkme]\\[[\ZXZ][[^``\XXZYXWXWTVVUTUURSOQY]\]^____bdmŽ„‘†‘Ž™“”’œš¢œ› §¨ª§ª¥¨¤¢˜¤®¤”™¥¯©Ÿ›˜š ž®™›©²Ÿ¤¦Ÿ££ ”“›–•‘¨©¬šœ ¡ š”Œ™Ž‹Œ’Œ–”¡ ¢œ›¢•› ¢ —¡¨¢¢¨« «¯¤­·¥¢£¢¬­©¨«¯³¸²½µ³«¯˜ƒrrh[XYSUREYLQ\YMTNPLQRINIB<??A?=65799<<987:79:;<=>;7;;:=67:;8976989:6:=99577571140-+/434988::8::748=8?9~³®¨³¶®¨§¯­›©¨¬·¶¬»Ê»¶¿¬ÌÇƹÂÏÐɵƾº¾ÆË´°½Ä¼ÂÄüÀ²¹¯¥ª¯«ž—†wxoninnnqghigd]Z[[[[\[YZ[\\^__\XXYXWXWVUTSUVUUTSNOQYZZZ]\\^_`d~‹‹Š’—‘–™¢ ›Ÿªª¦­ª¦¯¢§™Ÿ¬ ”•¤¨§—Ž™®–—¦©˜žœ“¥ ‘’’’•§ª¤™™™–ŽŒ‹“†ˆƒŠ‘”  £—•Ÿ•š ¡’›¥¥§¨¨ ±°¦±¼¦Ÿ£¬µ«­§°´°¹µ¿±­±«|prbVTUNRIGVPSRLLXMJLNRGMKACFDC>@75889;9:7::7<=:;@>:9;9:?759::876958779;85576661320-*.102877;99;8948;8@8³­¦±·ª¥¢°«ª§©²°¤¶Æ´¹º³Ëƺ¼ÃËÑÌ´¹º¾ÀÄǵ´¶¼²º»Ã¾Á°³­°®°«›¢ˆkhmoroqkpkdfge^ZYZYZZZ[ZZZ\\]\ZXXXYYWXWUUTRSUSVURNNNRWXYYYY\\]aj€zv‰‡‰˜‰”“˜š˜¨›Ÿª¤¤«œ¦˜ ¥›’ž¢š—–„ƒ‘š£“¢œ••–‡¡šš“‹ŽŠ™£§œ••—›’‡”ŽŒ€‹€Š‘’‘ ™Ÿ¡•“˜˜”¡¤˜Œ™¤¦§¦ Ÿ´²§²· œ¢·¬ª­¤²²¦µ¼µ««±£ˆxrm]NPQLODNNNPLFNNKJNNQHMJAGKHHC=858889:;69:68;99><8:>9;?8789:886857688974577820301*)-/12776:999984988A7w¶§¤¶°¤§£©¥ ©¥¤³ª¢²Ãµµ²³ÇǸ»ÄÊÍǵ¯¼¿¸¼Ä³²®¶¢¬µÃºº®ª«´¯¯Ÿ—§}^`gsqvqjnifhhj_XYXXXYYYZZY[[\\YXXWYYXUVRSRPQTQSUQNMKLSWWVXXYX[]aosvp„ˆ‚‡€‘ƒŽŠ”“¡Žš›¢ ¢—¤–¡›•Œ‡˜šŒs‚}Œ––…™“Žz™Ž›‹‚‰‰˜Ÿ¢ž“˜–„Ž“~~s‰Žz†’œš™™•¢¢‰š ¡££›¢´¯¬¯¬Ÿ˜¥¸¦¥°¡±®œ°»ª©¯ª™vrbVLQOPMCSNLQMCPPHINSMHJJDJLEJJ<749888;;69;7:<9::;79?9>@79:<89764445874312585/0102)(,-12764889::65:87A7w·¢£´¨¥¥¨£¦¥¦¥¦³§¥´Á¸°´°ÊƹºÂÏÇ¿´¯½Ã¯±Ç²­§¬•£­¿·°¯Ÿ§¬¬ª–”¢rWV`hgihincjhgb\XXXXXYYYYYYZ[[[YYYVWWWSTPNPNOOPSTRMMJHNSSSTUUWY[]ilrl…|tNXr‚—†œ—Š“ž—œ•”•“Ž–ˆ“‰_;Wo{Š“‰‹‘Œ…†rŠ„–x‚z…“”ƒ•Ž‘‚†|’xqo…~‰€—™˜“Šˆœ‡ž—†‡–žš  —§¯¨­©¨ž–­´¢¦­™¬«˜§³¡©­£’|qm_ZNSQVLDTJPMMFOOJELQMKOJIMOFIH=7599999:7:;:>>8:==6:?8>?589;79675333760.-/344110//()++-3844879<:79;86A9x· ¢­¡¦¦© §¨§¢©°¨§´Â¹±µ°Éù´¿ÏÀº±±¸Ä«®É®§¢…š¢º­¦§•¥¤£ –Ž–iPMRVZZW]^bgc_YWWWXXXYZYXYXYZZZYXXVWWUSRNLKHGb\MORNKHFHNQQMPRTVXZ`moiz‚tPB@•‘‘}‰”Œ„ŠšŒ–•Š’‡…•…xˆ`JQnxŠ‘„|„Œ‰„~n~“wuvx„™pQˆŠ‡{~x”vgw…ˆ~Šˆ•Š‘–‹ƒ‰‡”„š‹„’›–žœ”¤£§©¥£ž›±«¡¤¤‘¦ª–¡©œ¢¦¨‡ske][HQQSMIUMSILLPIGFKNLMTKQQOFIC<769:8:;;8:;8>?99>=7;<6;;478;6775344696/3/.115221/,')+*,4833979:99::::?9v¶œ¢¦Ÿ¡®¡§¨¥¦§¯¬ª¶¼¶¸¶³Â¼·¨»É¹·©ª·¸­¶Àª¢›’‚™±Ÿ¡™ŒŸ–˜”‘ŠŒeMLNNOLMQW[\ZXZUUVVVWYYXXYXXYYYZXXVVWUSPMJE@@›kssIMKDDDINOhYNQSTUZnƒtw~ji]U‰”‰t†€{…Œ’€‘™‹{†uxsnupty}‰ª„yzhv{Žprmx€ŠŒ’xz€{€vrq’xgu„ƒ„„z•‰ˆŠŒŠ€ƒŠŒ“ƒz€˜”›•‘Ÿ¨žŸŸ ©¥Ÿ˜¨¤“ Ÿ•žž¤qf`\\JVOQGKXROJMMSJJJMPHLQLRTMEHA<78;99>=:;<98@?::>=7==79937795675252572/2.,./200/-+(().1262198798776:<<7v®˜£¡˜œž´©¯©¥¬«°±ª½´²¼¸¶»µ³ ¸»³«Ÿ­«¬µ³¥ž–‘˜†“¤–œŒ‚–ˆ‰††ƒfJIJIGFHHPTTTWWSTUUUVWWWXXXXXYXYYWWUVUSPKF>93N<~žMHJD@=ADj”~LOQRSV^uƒ}ygw—˜Ž}gy€vx‰|„˜’r†{vzok~­|sŠ{†’€}tfv|…logs|‰Œ‡€lyq}pmurhq€}ŽpCŠ„‚ƒ„wwzŠ„}‹zt~Ž’˜Š’››£—™šž¢–‹¥›—Ž–˜ŽumkeaYWXTQJSVTOPOQWKNKOOJQOIOOKFD<;79;::?=9<:99??;8<=7<9999266856633621224.,,-..-0-+*''*.1362/876966527995y¦—Ÿž– ¦°¬®«§©°¯±¬¼¸¬»¾¹´®©›±¨­œ—ž§¬§¤›“‡–}Ž•‘”€{Šz„€~~€eJGHFB@CDILLMQRPQSUTTUVWWWXWYYYYYYYVVTSQKD78f70?¨iNHC=;:DŠ…zZJNPQTX^eprmˆ§ªÀ~uyb{wo|yˆy|‹…omŒ‘xsxjj‚r–‘‹}–I’˜nhw~‚licly…’†ksl|nr{…imp~sŒˆƒ…z}~zvott…ywp|ŽŒŠ“ƒ–—˜š“–—™—ž—Œƒ‰Ÿ’Š’†–}lhmnmWUWTRQYOSUUTYVMNHNKNNKCINGE?:89;99:><9<;::=>:8:<9?868727565541442/024*+**-.+-*(*(',-1250,5567485HA895w™‘›™šž¤­°¢­ª¨µ¯®¬´¿«¼Â¿¦£š•¥˜ŸŽ…Œ–¢¤››”–v‘}„‹|x~t}wtw|fOEGD@<>>AFGGKKKMPRRRTTTTVVWWXYZYYZWVTSPLE1@š3 jrA™o;<95<€‚†_IMOORWZRY\`§ˆbšitze~omz‹ˆuˆ†tl™‘ss|jkŽLy„’‰„Žg1v†sl~}ƒtfet~„„…€filukp{gpp{n’Ž{s}}qpnum‚~wytjy‰‚ˆ‰ƒ–“’‹‘”•—Ž€yˆ—ˆ†‰†‡uiingcWQYWXY\NPVWZYOIIEJJHGBAFDCG=998;9:9<:9;:::@<9:<98>787715244533645031.**+*,,++)(+'),,226-+5775478iO8;5n’ˆ™‘š–¤¨®ž²ž¦º®«²°Â²»ÃǛ—”™‹Ž†z…‘š–’Ž’Šs‰„w‹ŒvwuxvoxsiUFID?<;9:?@ADDEGJLOQQQQRSTUVVXZZYXVUTSPKE80/\`³G9XP;9441–º‹HLMOPQVLAIQIb¯³ q|xm}lqƒ…yƒ††yqŸ”sx€su”‡5q¨Ž¡¡„¢„vp†{†{sŒ­ˆ€hfbimqmo‚uioXuoš‘vl{|mrnpzsumbv„†€†‘‘Š‹Š’‹‘Œ‹ƒvy‹€~ƒ€}Žxpnnj^Z[][YXa`SO\[YXLHJFJG?CABG>CD=;97=;:;;9:99;:?<88=:8;66651121353475531./,,+)*))***)(*)+/3DM2166643<vR7=7b’’ˆ–‘¤§ž¯•¥´¨­°®Á³ºÁƗŒ”‰}n‚‘“Š„‹‰ˆw„…n—ŠŒy{{q{t|ko^JPG>@7458;;<=>@BEILLLMNPQRUUVWXYXVUTSPLE<5*K[@-gI94/>’ƒ©®_HLMNPL7CMRSDJ†v€||v~lw‡‡|}…‚Œ~u¡™y~†€„™…›œa†ªŸ‹‚zvˆ~‰‡ŽsŠ—ƒ{\dqtz{wŠmgiayn…‚znws„zqsywkni]w‡}‡|ˆˆ€‹“—ƒ†‡}q…€„|uw{|‡tmqrde^ZZ]S[g^XQVY]WGKKELG?F@DC>AA=;97<;;=<::99;;=>79>9986754244104646654-,)+('''&(())((+++/00Uq<23331E~W4=9\Œw‰”Œ‘Ÿ¦‘ ªŸ°©¯À±»Åº–‘”ˆz†vk€Œ’ƒ~‹…y„‚t¢…ƒ€sƒ}lylSXLAE311267688:<?BEGFGJKMOPQSTUWVVVTSPMF@:2= #–cŒ[5311i?GoIFILMORLKT]YRJi„ˆ{‰y|r|‹z|ˆ†~—‡w¡™ˆ†’”¥¬©H†­¯¯Š€€“Š‹„‘¨‡€˜˜Šœsl|†‡}Žhggx~m…†…q„…Gk€xqyvhmk_w}ƒˆˆ…Œz•žœŠ‹‰’{u‹v|xmow~}qqpjZ\[ZccWgf]VPQXZQDLLGOIDFCCA@CA=978:::;;:888::?>6;>7595773344236656768;DFLMMLC7+"%'+)++,/00+nu22420L\5=<^„t|~Š…‡‘–˜’— ¬ §¹¯³½´—’‹˜‹}tqŠ“~ƒ”•}‡†¥‡‰€ƒˆ†yˆŠ€u…y_cVLC60./23123668:=??BEGHJLNQSTUTTVUSQOGC?80,#‡[>?84.]•ps£UFIKMNPW`YpZ\^j“‡•€„‚…‘“~…ˆ€š–‚  —•›š¥­“™»±§»È犌¡¤Ž“‰€{rƒžŸ‘œ~v……‹‡ihoƒ€tŒ†„‹q‡‚v‡€{v…}nvug”†‰‰ˆ‰ˆ¢«£–‰˜€{‚Š{zogky~w{pic\YY\i]ag`[PMNYSRIQKDNGCKDB@DDA<:87=<:<:88778:==8<=68756623445576867<BB?<8:>CQ^e\G2'&,,--.1(?Œ[.310Oƒ_4?;nvpgxƒ{€Œ€‘‹šš¤œ¡¬¦«¯°—’‘„¡”„xw€”}’†“–‹’›Ž„€‚Œ‹‚‰Ž…€Š€mpj^CA4--////02234779;=?BDHJOQRSRSSTRPOHDB<87/9C><<63.l“—MQIIKLKNV`cggmu›š““‹Žšˆ“‹ ¡’£©¤£¬“¨¶¢§Á®ǯxº”š|Œ¡ž™„’„‚¡ž“™’„Š…˜•lou‰‹•Œw„ql…Š—’ƒ…ˆr‰¡—‡“Š—¥¶©›–¢ƒ‡“…~€kjk}~}q_[b^Yfj\ll_YLHPSQNNMGIQDDNFACEGB>:97=<:;:987767;:6=:785456345566668556310.*,,)().:Pa\@,(-++0,'rˆ7240O„b3@<unhYpƒpu‡qv‘†~—–š”ŸŸ›§ ª–“˜žhf¤š~…”’z€‘‰’’}‹…™’‘ƒ€‹Ž‰†’ˆ„‰…xxhNR>//.,/.-/000212457;?CFNPRTPQQSQNPIEE>;<:CF?><752<@R5HHHLLMNR^oŠ|s} ›§¦¢™¡—¢•œŸ¨ž©«Ÿ¨¬©ªµ—«¾«¶ÈÉ·ÈÑϾ› piª¨Ÿ„“‘…œ šš™§‘‘ˆ•¡™šwz~”˜‘¡’——”ž{v•’«³‰— }•žœŽ“–š¤£§¶°ž‘š¨ˆ—Ž‚‰lss||ynf^[__agc`gg]REKKQOJJMGGMCHMFFCBGDA:85<<899975658>75=84745754546958:616863/0.-*,/.-'#*;XbB(*,1-(K—^063Q…f3A@ib_Pqu`n}awŽ}|”ŽŽŠŸ’—ž•œª˜žªBD}‡‰ˆ™Žy‚‹Ž|Š†‘‚ƒ‰ŒŠ…“…‚†‰€‡w_bP460-1/,.00./..0015>AAMQRSPRTUSNSLEE@<>=FH@A@8662<9<FHGIJNOQYm†w•‹£§ªµ½¸¥®¬¬¨©´¬°·²²­»±³¾œ³Ã¬»É˸ÿ·¥£°²¬¬ª£Š–˜…¥¦ ¢˜‚¦™¢ª§¤‡…“£  ª¡¤©Žœ°‹•¤§¸»œ¡£°“££ž‘¤¢¬°­³µ£•¦«‰šŠ“‹•z{~ƒ{e^fZc`]bc^fg`[PDJHTOFHLGKHFGHAKFCFFA:87=<88:974658<54<76:54644739<38<202551/1.-**/,-*(*&%5XX/,0,,0„871P…h5AC[XTLicWjpXz…v‚“…ˆ‚œƒ’‘Œ’Úȝ–sV—ˆˆœ}†Œ‹Š{‰ƒ‡‘Žƒ…Œ†…ˆ’†‚„‰†‡‡‡qna@E64<3/110-,+-1/-4?DANVQRSUUWUM\QGGD<>>FHCD@8;<5C;=FKJGHROPW“ „®£³ª²ÁÇÄ«³Å¶­³À³¸¾¶¿µÁ¶»»¤¸Æ©¶ÉǶ¾¹´¨£´­°°›™’šŸ‰§¯ª¤•wŸ¤—¡«±²˜–©­¨®µ»²º¬¯µ¢±¬²µ¼¸µ®µ §¨£¨›©°®³º·¹¨œ¸ª¥’” †z€rX_bUd``a__f`\UJDELVRIJKEKHEA@@KDBMF<867;<97:986555711<8895466597>=3891.0121130,*,.,+++*('*)EZ00*/+h’O60R‡j6AEWQJL\ZQcdWzuq”}„†“v†~€{¿»£¼‚´”“Ž›„ˆ“Š‰z‡Œ“ˆ…‚Ž€‰††ˆ…Š‡‘zyo]W@EN<6:46AB764//7CHCQ\OQUXU\WO_UIKJA@>GKFFD;>@7D7?BJKEFWTP^¤­¤²´Ã¶¸ÁÌÊ·¼Ä½³´Â¸¸Âµ¿°¸t±´¦ºÅ¤°Æ¹±³²´¨¤¶¶ª° ¢–›¢’¥±­¥­¬§¤˜ ¬³¹¡¨±¹µ»¾Ì¿ÅŽ¼³Â¸º¸¿¸»¸º­­±¦±ª®¾±½¼Â­™»©•®˜™«‰~€yhUa_VhcieV[dZWUJHGMRHDIKAID>?BBL@@MD99669:?6:9966246/19599364627;=?6:1./58::650*(,---,,*((++(ES/*00Jk52P‡m6?FRLALRWTYVZwjp„Ž„o{rxˆb¹¡š£‰•”–“”“—’‡‡{‡•Š„Šz|‹ˆ†|Š‚‹„•}xzufP\dGEL:Qd`[^SF?;HPE[cQQYYZgZS`aMSOEA?IJHEFA@C<D6B?HGJLTZT^”¯¸µ»¹ÉÀ»½Êͼ½Á¼¸¶¼¼·¾µº²Æ`u²¥±šž«¾ª¥¨«ª¤¢³µ «§ž•–ž˜Ÿ®¥§§¥ž£”¢§°³§²²¼¶Á½ÓÉÉÓÆÂÅÌÂÊÃÁ¾¾¿¼½¸µ°¹··ÃºÆ¾Äɱžº«¢¬¦©·Š€|o\^^\U`]hfSYbWSWJFFNKA>HD=KB=B@=F>;H@796379>489:57045/26389374526?8@>GKRTTRPPQRQJA9/,,,*+((,-+/P>(.48€}<2Kˆq9>CKE@JMPRLQ]hmlq†slrrsˆÕÀ¶š •™™‘—’––Ž†ˆ}‡ƒŒ–Š‚€‚y{‹„‡{‹yŠ‚—t}zlfpvY]\Peeb`ed][XX\NdmURmn_o_XgeUYTJDBKKHFHHHHBI9D@HKTTV]Z[“¹À¹¾¸ÆÁ»¹ÊË»·º¶¸¹´¸µµ®··™du©ž­p^¢­˜¡¢›¤ž«¥”ŸŸ”Ž–˜˜¨ž¦ŸŸš™ƒ£¬¤ª°¬·°¼¸ÔÐÎÖÏÉËÑÌÏÎÊÇÀÀÂʾÁ½ÁÁÅÄÆÊÀÉÏ´¤¼±µ°œ¬¹½š}wi[\YW[_XabQ\aTRLDBFHF<@F>BIB@D=:E>=J?47535;=468977022/24169775555D3ELM>510006:477@IOJ;.&**(-./,@M+/54m‰I0H‰t?>BD@CDGKODR\Zi`p—“‘”nlotu‡³¬¡¡Ÿ‹™œ™–‘›’…ŠŠ‰†ŒŒ‰|ƒs{Šƒ…{ŠtŠ‡•t{ylmu|iseilhfjih`fiimZnt—­¤½ˆ‡g[oh]ZYTHKOPJKPLSQHLAJFKP__bgjb˜¸Ç°º´»¾¶±ÅǶ°¹±±»­³²¨¬¸­¶¨žœ§šN›ž –‘§˜¥•Š““ˆ‘‰‘’›¡˜›•–‡ž™¦š¬¯¨¯§³³ÔÔÔÖÑËÏÓÔÎÓÏÌÅÂÊпÊÉËÉÒÈÍÎÃÐÒ¸°Ä½Äº¦·»Å¢~laYZ[V^VYdZP]XORCCIFDJ;AD>BH?@B8;D>@I=56655;:687654/10146278875367C5B8?-0,1348=97,.,1;FL=),(.0007K?-46TˆW0D‡wC;B>EBACJM?UYSfWs‘™‚hrpyyƒ¡ªž¦—Œ››˜‹Ž•‘šŽ}‰‹†ŽŠŠ‹ˆ|…‚p‡‚†{‡rƒ’‹~qyulqxr{nxsli€pmcinpyix}~Ë¿Ãߧncxnd[a`KPRUNY^P]]MQNTQUT\nnwƒr—®¸¬µ¨°¶«­½Á²«µ¦¥¹§¬¯¢¬´¤±®›˜˜Œ‘”’…›§’œ‰ƒ‹„Š‰„‹„”•——”›œ˜™™ž«¬¤§¢¬¬ÎÒÕÑÍËÒÓÓÐÔÑÎÈÃÔÑÈÎÒÓÓÖÍÒÑÅÒÖÆÁÏÈÈ鿸МvkbZ_[U^Q\ZPPUQOI>AGBCF=AB?FE>@?:==<<JA45465<888664412/03526768533;=<E=@11+/349?5901022-2EO3)/3.32=N248C}_2A†tD:==I>@CFH<VRMO[u‡†‹wlwp}~€ žž¡Œ™“”‹Œ“–…y…‘ŒŠˆ‘‡ƒ{r~€‚‡z…v…“‘‰€owsls||w|s‚xqk€rriprzyr{¾Ë›²„vr…wiai]DZZ[WfdXekTX]]ac^cx{Œ‚™ª¤¤¢ ¡©¦ª²º«¦´£¢®¢¤®£§² ‰¦›•“‘Š’‰‚”‰k•£™„†~‘ƒƒ”—­‹•Ž•šŽ…’—§¯¡  ¥¤¨ÈÍÏÇÂËÐÓÑÔÒÎÓÍÆÖÓÍÔØÖÖØÕ×ÕÊÕÚÍÊØÖÑË­ÄÃ̇ok_]\VRWR[PJHJJK@;:<ECE=CD>HC?CB;<9<:GB46544<5687543250/2546745544<>=E?A62/-16;=081/254/-.;R017/532ED28>nb5=tM99@I<AD?A;PLFKYq€v~isyr‚Š€•ž”…‹–‰Š‰Žˆ€x„”™‹‰ˆ‹‰„ys{}ƒ‡w€{‡‘—„oxqnu€vx}t†|yl‡vun}v„uy|ž¶<A‹Æ¥~}jeWICecfchjdoy[_fhkninƒ‰’ŒžŸ ž‘—™ £¤§³¥¤² ¢¥Ÿ¢©¢£²œ‡Ÿ’’“‘‹‹‡„„~œœŒ‚„…z”‚ª–£Œ’‹˜“‹}—Šš‘ª³˜šœ§œ¦½ÃŸ¶ÅÍÑÐÒÐËÒËÉÔÎÑÕÚ××ØÔÙØÍØÛÎÉÚÚÒÖ¿ÌÍ´tsjaYVPSPXUEGKJFF>:7:@BC:GE@EDBDA;?;;7DC75655;0689443341014558744449@>DBC<33.6FTWOQJAJF?2*(.BT29254/7K75<`bA<svV87AH:?B><9QECJTlnopbqqt†}—‘ž‹‡’ƒ‰†…Š‚ˆ}x…——‰ƒˆ†‡{…yq{{„…uz…Žžzp}ppz€r{r„‡€nŽzuw}}ƒu€}‡‰°tYªÂ·’pnc=^hrqqpnww‚fioruyrz‹‡”’›– –ˆŒ“œŸ›Ÿ« ¡¬œ¢šš ¦Ÿ ¬šŒš‘“Ž…}ˆˆƒ…‹Ž ™”ˆƒ‡~l™z„™‡ˆ“ŒŽ•Œ†{›ˆ“®«“•—ž˜¦®µ¼¨­½ÆËÈÉËËÏÉÃÒÊÔ×Ø×Ø×ÔÛ×ÓÙÛÖÏÛÚÒÖÉÕ̒twedXWNQR\GCFII?B>=8:>@;>I=@BABEA>?:87DB755479.566435532323647553458EBDCEB56<FNSM[nfcnsk`V>,5LG865433BF4=W_hLux^8;?F<<A<:9D>CGRk_mdbflv€ˆq‘›€y€Ž~ƒ‚…„|}„˜Ž‡Œ†‡wƒyo{{‡‚tz’žŽ¡vvƒtu~t€„o‚o’…u}‚…zw‡|‰¸Æ¥Ãʸ‚–œxpfNec‚z‚w…¡‘‹yyw{„€|„vm”–•–˜‘ƒ‰—š——¦˜ —Ÿ““˜£ž›¬–‘‹Ž“ƒŒ…‰‰‚†‘žœšˆ…Œ†˜{ˆ‰Ÿ—‰Ž‹‹‚| ˆŠ¼ ˜“—™œ¨¦¥­ž§µ¿¿¿¸ÇÉÍÎÄÍÊÑÕÕÔÙÕ×ÛÔ×ÙÚÛ×ÛÚÙØÎÛƂuucea]RUUTMKDND;==<9:<?9>A6>?@=?>=9867CA6455=80665547745613854564557HH=DJE7925;H>;9;7IP\ZRUXL9T>;95327I8=NYMHxxd5=>C=<@:6:>>@EQ_Yfa]\itzyl‰’wvzŠ|~€€~†{~‚‘Š…†z…ˆ|v~um}}‡~t’ž‘ ƒ’|†~x~y‹Šoƒ›t™‡~‚Š…|~‘{©Ã ½œ¤œ~Š…}‰sŒ‹€s¦šœ˜”…{‘‰„iGp¡¤žŒŒ‘’…ˆ‹‘“•›“”‘—Œ–Ÿ”¡•’ŽŽ‘Œ~Ž‹„‰’–™ŸŸˆŒ”‘ƒŒ¦™ˆ…Žƒ†„€¤…Š‹·—‘”•¡¦ £®¶¹´«ÀÆÊÐÇÇÌÏÓÒÒØÒÕ×À×ØÙÛØÚÚÙÙ×ܶttsffbT]YRONHDLC>=>99;:::<=6A>?==9:;;37D@8378>70688357<37804976755546FP5DNI8938AK=;3C@I<:DWO<MTHN?96333>C;[X>5YypZ<<A<=>8589?=DRSRX^VXfmmmiŽŠqsxŠ{{€||ˆ{}|‹‡‚~uƒ†zsztm~…~w†›¡›ž”“€Œˆ˜‡€œ’nˆ©…{¡Œ}‘Žƒ‰…›‘Š£¢Ÿ‘¤¯ ‹‘‹…‹“†Wr­‹Ÿ«œƒ™œŽ[‚¢‘‚Ÿ“•Œ‡ˆŒ’’Œ”••ŒŠˆ–œ–—’Œ“”†€Œ‰’Ž‹Š—˜££†“• ŠŠˆŽœƒ‰€ƒ‡…¤„‹²˜œ’”—¡ ž™’›§²¸¬¥½ÂÇÍÇÆÏËÏÌÎÖÐÑÔ­ÖÕØÚØÚÚ×ÖÙٜkxpccYYUQUWC@ID???:48:;7:<;4<<?=>7;::1:G=:27=@50677255?65;55858:57735HR7GOK994=EJB>1FCLB98:GX@5HWI66223:ECeX?&_yi_z>>9<;88;<@;BQKKSYPTcbymb~‘ƒonx‹yz{}‡||w†…€sp…‚{uwvt„‚…}’¦¢Ÿ¦¢—Š”—‹Š¨—rŠ³„¨’„™”…š£– ˜“‰›ž¢“©°Ÿ‘•‘ŽŽˆ–Œo·„šÄȲ¢¦œ˜–‘²d¤ÍǕŽ†‡‰’“•Š…ŠŠ†–šœ‘•“‡•˜„€Œ™‰Ž«——¤£ˆ™ž•š‰‡——Š…‡¤ˆ“¨š—“–˜¡˜ž™“œ›¢²´¥£½Á¾ÇÅÅÈÈÉÂÊÒÍÍÔ¨ÒÑÖÖÖØÚÔÓÚÎnzd_[Z[LHTZBBHD;B>837<<:9>64::<:72?:929I:>67BC32:96264>=4;>6949;57944KQ<JQK9A7BGI@64JELF>;88ETA7>\86214:;E`XAFathLcZ>5;::5;:=:EMFHSWSRBc‚GvŽ}|m~ˆy{~{‚‚ƒww€ƒ|mn‹{}xx|„‡Š~‹¢³§£ª³¢—§ ¥¤–•®¢ƒ‘¸•’³š¢¡Œ¥œ°£¤™‘§–©š¬¯¤˜•–•‹˜š—¡ÀŽ£É¸«œ£¦®˜’›²…†¨¢œ˜…‰‰Ž•Œ‹“ˆ†‡‰“˜•ŒŒ”“‡”˜†„’œu’™³–—¥¡‡œ™’Š‘Š—›‰‹—Ž†~Œ˜ž‰›šš“˜—Ÿ“ ”ž› ±®¢¤¸¾´ÅÇĽÃÃÀÆÍÊÉÒ¦ÎÍÔÒÐÖØÓÐعnuqY]R]UNGINEACE5>;77:?<<7=43669774>5;5<K<>;<BA75<;4277?@6?@784987;<55OMDPRL8@=EAGA5:JENED:6A@BS>9DO323575=v\<R\tiZM]S<=88467=:JFDGNZ\YJf`;I„‹zzn…†z}„x†~px}~}osz~‚|x†‹‰†„’¦»¬¨±½¯¥­³³©¤¢°¬Ššµ£¹¦•­¥–ª­¸§¤£ š©˜ª¤®°ªš™œ”–‘— ˜š»»®Ê¡j·¸«°•™ž£¬“—¾£^ª²ƒŠŠ”‡‘|ŽŽ}ƒ†Ž”•ˆˆ“–Œ•‹—™“™´—•«Šœ”‘’Œ™›‹“ž‹Š–Ÿ¡Œ”—™’›˜ž”¡ ”œ¥®¨¡¤´¸¬ÂÈŵº½¼ÅÇÈÂÑ ÆÊÍÍÅ×ÖÑËԞlvdYWP[PNEC?=CBB8@885?G=<6<35345454B49:BL:B;AHC;:@<746<B9?@B874::6><47TKCUQJ7<:IAD@4AJHNBA?6DA<JND/T=254:EJ\XJZQmgppDi`KI6757:>J@CIPdHb`bpI@‹Š~s†‡}‚ˆuƒŠ‚n}}}pw‡wŽ‚‡|Œ†Œ™ªÂÀ¯½Æ»³´À½µ­«³¶Œ¨²®­½«›»¥¨­¹¹«§¦¢¢¤£ª¯²±ªžœ¤™›˜˜Ÿ£¦¥’£º¯©¿¼­®²¹¥¥¨~ˆ‡œ­½°ƒŒŒ‹ƒŽƒ‘zˆŽœˆˆ—‹•—”‘š–¨š±š‘¬œŽš’Ž”–—’ ’‰•›£¬”–”œ’ ›˜Ÿ “šž¦¥¤¢£°²¦ÁÆð°»·ÅÃÿͦÇÄÇĽÖÑÍÅʅoo^YW\YLJBKAFH?A@C;:5>A>>5<7=333241A17@BM>G@CNCA=C=;86CC5BIB:878:5B>79VKDWOF8=4K@C>4EKHN>BA6BB?BSE58P145;<8;D>9Ljj];WRdKgZUN79GD?CF\eF`igZ]]“ŒŒ‰{‡Œ‡ƒŒu‡‘Šo~{‚q~z•z’””˜“–§³ÆÉ¿ÁÌÂùǽ»¯«º»˜³·º²À®¦À¤«°»½ª®«££ž§«®µ°©› ªœ¡œ–Ÿ°µ§Œ£»º¶Á¼¬©´¥¥©”…ŽªÄ䂋‡ˆ„†•”zƒ‘‘¡ŒŒ”’Ž‰—Ÿ˜“™•—¦ ¯œŒ«œ–‘‘••Ž‘•’¡”‡—Ÿ¡³ž”™“Ÿ —¤žšŸ›Ÿ”˜ž¥£¦¦¤¯­¥ÀÄ¶Éý¶Ï²Ä¿Ä¼³ÑÊÈ´puiYUYgPKHCMKLJAB>DE<5AE<;3=9B332263A05IEN>I@HR@H>C@;>=FA5AU@;998<7E>8>VJCWOG8?4L@B;5JKCL?B?<BF=AHL9+G<367464A?7OaOaE/=>6klj`@:H>?EBeZMe\eTbj™–Š‹ˆ“†‰y‡”r€{x‡‚‚y¡–¨™š™º½ÇÈÉÁÒÉÊÂͽ³­¼¾§ºÀ½»Ä·¬Á©¬³¼¿ª°ª¤¥¤¬®³­¶µ  ¯Ÿ¥¢™£´½©œ©½Â£¶·¯¬”²¬¬­—‡šª¦¥‘‚Œ“¥–ŠuŠ’y…Ž’Ÿ“”‹”£™—œ””£žªž‘¥šŒ•–ˆ|–““£›• ¢œµ¥ž–¤£¡¥¥˜•—›¤£©§¢²¬¨»Àį¥³·Ì¿¹¯Ä³»¾Â¹­ÂÃÂÀ—hu^VTXXIJLIFDDIDCBDL:4DI:;4=8E.12242B26SHO<JBJQEKCDE:ELB<7EV=;=89?<I?:EUIAWQG7A:K:B79JMBI@C><DG<BCO=20H366170=B:=jjJK5QS3SppdN;D=@F>iH_XaZccVžŽ—Žž’‰ŠŠ “„x…•ˆŠ‘€–¡™­§¤˜Â½ÇÃÇÅÓÎÎÍ˼¸°º¼´½Ë»Ã¶¶¼­³¿¹½®¯¨ ©¨¶®­©²·šž­¢§¡ž«·¸ª¥¯¿Å±½º³¨«·´¯¯—–¥¬¨ ‘Ž“²Å§–Ž|’•|‡’™©˜—““’•“¥“™“¡£¢œ˜Ÿ˜‹ŒŽˆZ——’—¤™e˜¢Ÿ²¥•¡•ª«©¦šž¦—˜–˜” £¨¥ž¶«©¹»Ã´¥´¶ËÀ¸ª¶«²»¸®¨¸º½·gjWTRSMEJRMK?BHEEIHG96FM;>7>AJ.32025C55OVN<LFKRLOHGI>IQ?:8IS;;?79>DLB@HSK@WPF:A?G6A7;HMCE;C>4FE:BABG9/:A3603>GD94=tdMG;E+:f|gV;>@BFBpEjIReaLF¥”œ—¢—©–Œ‘ƒˆ¦“ˆ‚‡‚œ„ƒ•”š¢ž¯¾¯¡Æ¼ÄÄÆÆÎÎÎÒÊ¿»¶²»»»¾ÏµÄ¾¹¹·³±µ³¸³«§œ«¬¹ª¨§¯¯˜¤¯¤§¤¥µÀ°¬¬´¿Ã¹Àº´¨º·¹´°–¥­¯®¤‹“•¡tš}—š„Ž—™Œ°•šš•’’™™¥£• š–š©›  ™Š•œ`J–œ›•š¥–T–¯Ÿ¯œž£”®­ª¤™ ¥““˜˜›Ÿ§¢™´¨ª³»»»«°²È¿¸¦¬«­²²£¡²²´¤mjbYWMOJDOPPR;HKIHJCD>:KU?A:=EM07544:B44MWO;JKOUNQJPHHJOB<>MR;>=8:<CR>DHRIBWNI@BAF3>58JKCA=C;5EA:A?>H@5+C52,>c]g:35tde@R7&#3}hW;:BC@=QEWSsbWFHª—™ ¢¨¯™‘—‡‹¨–Žˆ“… ‡„— ›£¤´Éµ©Å¹ÂÄÈÊÉÈÌÍÇ¿»³®¹¹ÁÁ̵Ⱥ¹µº°¯¯³µ¦£›ª´µª©¦­¬š¥®¥¤¨¬º¿¨¬¶·¿ÂÀ¾¹³³Å³º¾­¤¯µ¬¹¦ˆ›˜¦›v¿Ÿ„™žŽ“ššŒ®—¡œ›—”šŸ ¨ž¨Ÿ™šªš¡§ž˜‘ƒnv’¢š•¢‘®²£«”§©—ª¬£¢ž¤§’‘™œ‡”œ¢–±¦©«¹¶½²²®¾¹¶ £§¨¥¦œ›­©©‹_b^]OJKFGMJVM=NFOKMBDD<QV=AABDO18=76?B75UXO?HNQYSPQUKQJJEAEMQ??=8=;GR<EDQBGYMKAHDE::39KIB>CB99C><@>;;G7-2>-1‚hNz\/0kh`<=BB86zfW;:=.-R`MUH~e^HE«•›¡Ÿ»¯™” Œ“«œ‘’“‰«†¡žŒ£¬”£¤¶Æ¾´À¹ÂÂÇÉÅÂÍȾ¹²¯ºµÁÂɵƲ¼µºª¨­­°¢£˜ª´»¦©¦«ª©¯§£ª«½»¨¬½µ¸¾Ç¼·¶¹Â³¿Áµª¶·¬¾¥£˜’¢ ½Ÿ‰š¡™—Ÿž·Ÿ©œ¥¢›œ¡š¨¤³ ›¦œ¨ªž˜•”›‹–‰Œ¤¡”¢ ´¯¥¥’¯ª™ª©œœ¢¢¨””Ÿ‚žž›•©¤¡¡³´º´­¨¶²²ž£¥›—”˜ª¡žu\Y]\HGEFLPINEGHCSLJBEGAWSCH=AGQ1;B7:BF79\YKALPTUSMWRNUJE@JJNO9D@5=<NQC??P?EZMJAKDG@53=IG?=EA97A;<@<<3@</(;*H‘B:SJ0,[oW71<*B€dT49-19f\FCCpbGE§—£ŸžÃ­œ—¥˜šªœ—›šª–•§¦•­¬™¢«¶Äü¾¶ÁÂÀÇÿÌÅ»½¹²°¹³¿Âǵ¿°¼·¹¶¥¤««­ ¡™ªªÄ¢¤©«¥ž¬¯«¢©©¾·§­¿²¹·Ç¶µ¹¹À³Àø¶³´°½£—£—”œ”®Ÿ¢£¥££ ½¥©©«œœ¡›¥ž½¢™£Ÿ¢©¬¡—Ž–ž“ž‡„“Ÿ¤ žµ¬¦œ•°¦™®¥œ™¨œŸŒ˜”žƒŽ ™›’¥¤š˜«±µ±ª¥ª­¬œ˜  ’Ž•¨ž”e_W_\MHGINLHFDIB>QIA<GII\ROK=IOU5BF9>GG5CaZKBNRUWVQXTRUI@8RQPM:GA4CHQSIC;C>GVKC@O>K<06;GF>;FA55?9:?9;15D0-,/Mv\4KZ5,MnW<-=)#zbQ5CKQ9mQF<KxeaVK¢š£œžÅ¬¡Ÿ¬Ÿž® “£Ÿ–¥ ¦©¬˜¶±£ª³¶ÅĽ¿µÀ»ÈÁ¾ÉǶ¸µ´±³´·ÁŶ¾±¸µ¸´Ÿ¦¬ª¬žž¥¤Á¥Ÿ©­Ÿ¤ª­¯¢¦¨¼µ¦±½¹·¶Ä²´¸»À´Å¹¹¯³µµ£¥•’”¡®Ÿ™¢ž©¨¬£šÂ¬©ž¬®››ž™¥ ½¡¤˜««¬¦¡ššŸ’ž‰ŽW–Ÿ¥¡ ¸ª¦“˜´¢ž°Ÿ™­•Ž˜“œŽŸ—•¡£–¥­±«©¡¢¥¤••˜ŠŽ‘’¤žˆ^aXb_KHJJNFEAGK?>KB:9JKN]QQI=LW\9FI=DMH8Hb[KCLPSYYVWOZ^IA=WQJL?H?5HLXSHA:@ADPH?>Q>K7099FE;8G?.6>78>77/1?91%1QUm[JO10=gWD17=-+w`S6S[kWqGE6=ue\KMžž¡™ŸÄ¨¦¡´¢³¨”«¥ ¤Ÿ­©¬»°¨¬¶±ÇÅÁ²ÃýÆüÄɼ¯°¶­°´¯¾Ã´¹²°º´¬™¨±©ªš¥¡§Á­›¬°›ª£®±©¤¨¼¶§·»¾°·Ä­³³ÃÀ´È´¼¸¬´¶­ª¢¦–••£¬¡Ÿ ›§«°¯¯»±¦ ©¨š™˜“¢£¸ ¡£’°°¬¥¦Ÿ“¢ž•ž•ž›¢ž§´§¦Œ—²›¢­™œš«’•’™‘ •ŽŸ ”‹¥«¯¥¦¡œ ‘‘š“…Š‘›~_dYfeIHLISAC@IH;;G?99ONV^RSJ?P^]=HPBLLI9Nc\LELRTY[SUO\bHA?ZQAHAKB7FELKM?;BHDNB=;N@A3/97CB97F;+6<46<25-/4@1+&VtSeO?104b[M23>0<v]^?[T]ep@8;H–weA4ž£Ÿ› Ã©¤ª³¢¤µª–³­§¢¤²¬®©»²­±µ´ÆÀÄ´ÀĽÉĵ¿ÇÁ´«µ¨¯¸¬¿Ã³¸¯­¶¹¥˜ª²««˜Ÿ¦—­»´›¨°š­ ­´²§«¹²¨º´¹³¹Àª·²Ä¾¶Ç¨À¯®·µ©§¬¡˜—’¦¥¢¢˜™¥¯¸®²µ¶ Ÿ©¤š”–”¤ ·¢¥¥–°²²§«¦¢Ÿšš›•—¨Ÿ ˜¡ž¯²¢¦–­˜¤ª–—œ¢šŒ’–˜…•ž“‹›“Š¨¨ª¢¦ ™•‹Ž™…”ˆ“žwag[jiLOMNT=CANC;:I@77RO]^RVQAW`\BJSHVKH:Td\NFON[W[RPQX]GAB[PBG>NC9HGHOP??CIBLB<2IA94177B>;7E7+6914801-/.<6-#Bqgsk23/1[bZ23806p[bH04IogUCWFŒyfC;££¡¦À§¨¯±¢ªµ«žº±¬¤«´¶±°¹·°·¸¸Å½Ãǽ½ÄÂÅ¿¸ÀÅÀ¹©¶¤¬»­ÀÁ··ª­±º¡“­±­²–¤§‘ª¹ªŸ¦±œ« ¯´³«©µ¶­¼­´³¹·¬¸±Ã»ÀÀ§Ä«±·¯©««§ž˜™«¡¢¡‘˜¡±¯³¬°¹š›©Ÿš—“˜§ ¶©¦£¢±±´¬³¨­ œ  ›ž¥œ¢—£³¯›Ÿ“¤™Ÿ§™“¡“—ˆ“–’•–œ’ˆš˜”Ž¨¨¦Ÿ¢›˜›’…™Š}‹•„™hfk`lmWPQ[UABET@<;IA8:XPd^PWWEY_^NMRN^KJ>Yc^OHPO\UYPKTWZI?DXPDF?N@=IGGQPB=DEBM?:1D?77547?=95E4+75/251--.,1=*'+=\p=>1.0dZc?1647gY`F(?8l}g[V;‰{cC>§Ÿ¢ª½¢ª°¬¤²¹ª¦¶µ¬¡­µ½¯³¸»»¾·¶À¿ÉĹÄÿ¿·Ã¼À¶®µ¦«·±»½¾´©®±¶ž–«®§®—¦¨Ž§»Ÿ¤¬³ž¬¢±°³¬©µ´µ½®±²µ¬°´³Á»Æ·¬½°±¸¬­ª£²¦ž¥ª ¤—šŸ³ª³««³š§œ›–Ž¡¦¤´®¨¡­®®±¨´­³ª¤œŸ¨¤ž•¢™›¨µ©—™‘‘™Ÿ©œ•—„”–Š˜›“Š––š–¦¥£ œ–•–’”…zŽ’‚‹”djqfoq^FYgVDCMWD[9HC6>]Qh\NZ]G[^^ONRXdJJB\b_QLMOXWXPJVVWL=EUJEDAM@AFHHQPA;GDFK=87B=68719><65D0+80/05/*,/-*=,,%2+*5K1/'_^_T150=`V^8*C3YU\gK6ŒzfL@¤š¡¥­·¤¬ª¦¯®·ª¯¶¼¨§±·Æ·±¶½ÁõµºÄ¾ÌƹÃÀ¹¾¹Ã·À¸±³«©º¶º¹¾´©­°µ—˜§¬©¬›««Ž«¾«­±£« ±­³®­µ²¸¸ª®¯±¨µ¯µ»¼Ê³ª·¶±´¯®¦¡´ ›©­ ¦––›š²£®¡¦¯—¡¤šš“Ž£¦¨³ª¢§³­«¶¥¯²¶¯£™¬§š—Ÿ›™«·¢—“Ž˜œ —–’©š’‘—Œœ›˜–Š”’ž™¤¡¢ ˜–’’•z‹…zŒŠ‚Š‘jmwlt{aFakYIGZZ={JFD6AbTi[M\bK\][RSRb`LKE_`_QLIPWVUOGWVUN:IVIH?CK?EDHHQNA?HHHE<7=>:75609?866B,-8,/04,(,/-*76((9.$:K5."U_T_/5(C_Q\.*A/JGP[G3cYUKD™—¡²©²ª­¦¤¯®¶ª¸¶º¥¬´·Ê»´»º¿¿µ³·ÃÀÌȼü¶½¿¿·¾»°»­¦¹¹¶µÂ¶ª­°·”–§®«©£°©”¯º¤¬±³§¨£²´±²°´±·³©¯¬²§·¯·´ÄÆ·©¶·¬±­©§£¶  ¨²¡¥•œš•²ž¨œ ªŽ©£ž›–˜¦¦¥¸¨£²µ¬¨²¨®²¶«¤™ «¨›œžœ”©¸œ”ŽŽŠ—›¡—–¤Ÿ›”‚”œš—–•ˆ–—š§œ¤Ÿ‘—‘•vƒ‡{„ƒ‹Šlovt{~\Lfm[KNc\>b{GI8GgWf\L^cMYYWUXTi]OOH`\^PJHQVURKHWUVM8MZNE@FK?HBCKSM??LOH@;:>;6;041<=458?)07)1.2)),,-+-9$042%9B7.#ANGe27'GbLV%,A.=ELQ<3rkICC‘™¥¯¥®¯«¨¥±³´«¸²¸¡¬µ¹É¹®Á»Ã¸³±µÂÂÎÅÀÁ½´½¿¾º¾¼²Ã§¨¸°µµ¿¼®«²±› §±­¦¦¯¥²µ­ª±±¬©¨µ»­´²´­³­ª¬¨¬©¸­²°ÈÁ¹¥º±©­­¥¨®±¦¥¤¯¤©œž›°š££££‘­Ÿ¤  ¢«¦§º¥¬¶¶¦«¬©­±¶®£ž£¨ª› ››’£³™‰†¡Ÿ”Œ“›ž‘‘ƒŒ’’œ™—•”‡—’•™§› žŒ“‘Žw}…|{|†ˆˆprq}||\Sdo]NXe\FD–[G;NmXb\M`bNVWVWTXg]QRLcYZTKGOTSNGIVS\N;P^IBDHJAE??KSO>:NMC<<>9:5=+32=6249:(45)/+1()+,-*&5*/&0)38:1&*3Bc:6*HeHJ*:G>3BHS,>k;GHœª¬£ª±¤©¥´µ²µ¶²²¢¬®½Ìº®ÀºÇ±´­´ÂÃÑÅƾÀ²¾À»¾·»Ä¦«¶«²¶¼À¯«±¬Ÿ£§­©©¥°£ª²ª¯¬°¯°®¬´½§¶°²©²©«¥¥£­º­ª²Ãº¶­»©©¨¬©§±¥ª¥£¯ª¨¢Ÿœ£­•¥ž˜ž™¬¢§©¢­¦¤®¬¸³²¢ª£ «¯±¬žŸ¦§©™¤™™Ÿ¦˜‡„Ž‰‹ ŽŠ‹”š„…”žœ”—•†–”“—¤œ›‹’Ž‰~~‡…|v~…ƒ„rqp‡tl_Z`maQrp\K<…|F?XtXaZNd\NVVUWQ\a^SONgXVVKGLNRHEIVR]c<P]D<FHHBG?=JPL:>OJ=9?=2:7;*25>10485(5/*,.30;),,'%234$,2-860)(1;\J0.JgEF6;B/4EKX2@•Y=LE–˜­©¢«³œªª±·­¹·¯¬¦««½É¼°½¶Â¯±«³ÃÃÎÏÿ¿´ÀÁù¿³Çꮶ­²¸¿¾±¬­«¤§ª°¨¨©±¥´®ª±®®²±´®µ½¤·³¬¬®¨« £ž°·«ª­º·¥·¶¤ª§¬«ª­¡©§§²²¤§¦¡¡¬—ª¡•› ¦ž¥¢ª¤­£ §±¸®®¤¦£›ª¬­ª¢¤£¤˜ ›–—œ“‚ƒˆ…› ‹‰Š—Ž‰‚‹—¢š›Œ“’‘“£š›š‰‹‹|†€ƒzs‚|ru‹¤‡xk_`leWd†cN?g“LEbyWcYReUNVUVTO\]aUKMhVUVIJHIOBGISQYoANX@:JGFEG>>EQH8CKE87C72:::*39?./463)4+*,+.#4.-+&(+79*&6+<-2,&06VY.0JgAA;;B+:JO^4D‡=GFD—“°¦£«±˜«ª®¶¬·³¬¦¬ª©¼ÀÀ·¸²¼µ¦²°ÃÉËÑÀÀ»¹¿¾Á¹Á¹Àì±´±³ºÀ¾²°®¬««¨¶ª§®¯ª¹°¨²²¯³­·«¹¸¦´·«¬¤©ª¤ž³³©¨¤´´ ·® ª¨ª¨«§ «¬©¹¶ªªªª¢ª ­œ’ª¡ ¥¢¦£ªŸ¨µ¯©¦«£¤™¥¨§ªœ¢££Ÿ™™ ˜~‡Œ‡ƒ†ƒˆ‰ŒŽ‹‚…•¡™š’‘“Ÿ—™–Œ‹ƒu‡xt‚~xv}€‡oqgfow\_rˆjO^™VHnyUeWQcPMVTUPOXZbUHOiTUSGOXUI>IHOQPxLNW=<KD?@A<@CUC9AK=5;E13;:7*4:=+-341*8**+*,))(/*&)%3;,$2)2021%/1Pa02?f=NX?C,>LT_0Ji5OD<—±¢¦¬¯š¬¦­°´µ°¬¦°ª©º¾»¿°­¹®¢¶¯ÉÇÈÑÀ¾½»»Á½ºÃ¿¾¿­±±±µ¼»Á±°³ª³©¤´©¥®³³¹±£®¸²±³»«»°ª®¶«ªžª«Ÿ£ ¶®©¡Ÿ°²¡¶ªž¨§ª£ª¡¢­­¨¾°¬®­¢¨¨ ¬™°¡˜¢ §¨Ÿ¨›š«±ª£ ®¢¡”¢¤£§˜š¨¥˜—˜žŠ‡”ˆ}†„„£–„Š…‹ƒƒ“Ÿ–‡‘“‘œ”—Š††xu‚|uxyyrqwf~†¤vi_ci€tfˆŒ|RXp_KxsSdTQ_MMSZfNLVYdXGRhRQ?BNQaQ:IHLSIqQLS;<I?;<=;@@W<<?H73CB15:93-5::)-31--5)(+-,42#2)',%.;.&1.0-14%,0Kg:48_=ad?F1CP[[*HL9U@4’³¡¥§­¤§¤­§µ³²«¥°§ª·½À»¯§¹ª¦®°ÉÇÈÑü¿¾¸½¾¼ÈºÀ·¯¯³±ºº·À²²º¬¸¬¢´§¨­³·º³¨¨¾¶¯·¾°¿§­¬µ«­œ©¯£Ÿ¤­¬¨œžª²¤´¨›«§©£¨£©¨©¾¬´°®ª¤ ®œ›³¢•¤›¤¦ ¥››ª¬¦ œ«¢œ“œ¢¦˜—¨©’˜š”Š‚…~ƒ€ˆ…~}‹†ƒ“š’…“¢Œ”‘‹‘›’•‡‰€r{z~|ix|ysnnzfƒw…Šdaf_qƒylfx]^T?W{mTbPQYLLNru]HZ[gYEUeOC>JNDCA9HGKS?jaIQ8=H<<<>:<?T6:?C45H>2;59027<5(.5/-11'/>KH0%90%,,09/,,+6'17#-0GiI24X=fbAJ7GS`U*=9CV=*•²š ¡ª¦¥¢«¥¸³´¦ª±¦¬·Á½µ¯¢¹¬§§°ÂÊÉÌÁ¶½À´·¿ºÈ´Â´²±´±½·¹½µ­¸µ¾¬¡³§«¬±¶¸µ¬Ÿ¿½ª³Á´¼¡¯³µª¬Ÿ­°£œ¥©ª¤žœ¤°¥° Ÿ«©§¡©œ¥©¡­¼¨®±®¡«£¤®žŸ­¦—Ÿ›¡¤ ›¤«£››¥¥–—• £—›–¥¬Œž‘‘‘‹‚Š€€Ž{™”Œˆ{~‹…Ž‹‰„’—†”£Š“’‡‘š‘“€‰}yl~vyxc|zpnnpufrj„hdf]krŒl`hp`o=[ylU^NPRKJMTZWM\^lWDW_O^OHMDF;7HEKO<rhKK9AE;;=>;;=J49B<3;G<4?18-68;2(09/,4/.=-*K>)49&'.34.0+/4&,:$41AgY14S=e_DL6KVdO*;1NW=#”š­š ˜¨¤¤ ¨¤¸°¯¤¯¯©«¸Á¹²­Ÿ¹¯«¨´ºÈËȾ¶Â¾¯´½·Ä¶Â±­¸±²À´»½·¨¹·½ª£´¨©«²¯º±«œ½¾¦°Á¶·¢¯¶µ§¦§°³Ÿž¥¦¨¢¦™Ÿ¬¨©ž¡ª®¦ ¦˜¤© ±¹Ÿ¤±¯¡¬¡¬¤œ§§¨™š›Ÿ¥–›Ÿ«§—¡ª“š”™Ÿ”™–¡©‘š‰Ž†|‡~‚}| Œˆx‚‹„‰‹‹…‡“šŽ‰•Ÿ‰‘•‚‹—Ž‘}…|sp~rtt`zxhmnnmg}qc{mid`[d„~^YsjrIIiXZMPLKHPRQIO\_nSDXZRgNGKEF56HBLI5ZeJ@6EB9:>=>::C59>:3@F<2@23.:;83&2<0,85B*)-B*,4;NN@;73-.+-7**<%53<ec24M?e]FO=QZgH*=/WT5(—Ÿ§š—®¡¡¡¥¡·«²¦´´©¨¹Ã´²­ ¸­®­°µÆÈÀ¶¾Á¹°´¼·¾»½¯ª½°´¿±½Ã¹©»º·§§µ©¨¬²®´±¨œ¿¸¦®½¸³ ±·°¨¥§¯±›¡¤ ¥¥ —œ¯¦¡ž£¨¯¡Ÿ¡”¥¥¢¸°¡¦±«Ÿ¬£¯˜œª¥¨ž—šž¥”››ž¨¬šŸ¦——˜–žŽ“—¢¨¢‰‹†z„~„‹z—‰†x†ƒ‡‹…“˜Ž–™Š—~†—yzprwppt_ywdkkjgf‚lerjkdgW`r^YkuiXE~^ZXOOKHHRUG29^^mPDWUYeLHJEE07F?KB6IJH;6F949>=<98@8;8:7@I>8<4-3<<75(5>1,;A1(+6<#8R=*113>D5,-'42+;+139cl84HBf[HTCT]hE.:1]Q,2—¤£˜–«ž¦¡£¡¸ª°¡»¸¥¬½Ã²¯®¢µ°¬­¯µÅĽ³¾º·°³¹¸º¸º®­¿³µ¸¯¿Á¸«½º´¥¢³«©«´­®³¤žÃ¶§ª¸·¬ ³¼ª§¥¨¯«™¢§œ¤¦”˜¡²¥™ž¤©©œ¡Ÿ”¦ ¤¹¨¤§­¦ž¥¡¨“ ©¡¡ ™›ž¡“œ—¡£¬œœ›£–“––œŽ”“£§¤‰ŠŽ†y„|…†}‰Š†x€„‡‡ˆ‘…”“’Œ•”Ž”{ƒ—‹w|musmmtbxthfifcmƒfghdfgh]daheZezb`PsT[[SKJHIOS@ *i^jLCVU^`KHGEC.:B<F<6KPD8:D357==895?:;4>8@L=>93)8><:9*6@3.E4(+,>0-O?.+-7-1195,&.5-80576`sB3CDh[KWGU`hB377`L'2Ÿ¤¥“¦§œŸžž¤¶­¨ªº·§¬ÃÀ¶¯¬¢¶®§¯¯·ÀÀ¼±Á·±®²¶µ¹¸µ¬ª¼³¯²±½¿·®¼¼°¥Ÿ¶¬¦§µª«¯¡¡Å¬ª¨²µ¬­´º§©«±¥—ªŸ§¥’™¥­¢˜¤ª¡›¡œ˜¡ž§·¥°«­¡¡ž¡•¡¦Ÿ¢ ™œšœ”›ž•¦Ÿ®£™˜Ÿ–••™Œ˜š§ ‡ŠŠˆx…w‚‚‚‡Š‚ˆ{…ˆ……„–•‘‘’{ƒ•…s~gyplklguskafcas~adefdhhbenY]X\lcaLgWZ`VIGIKMRX>9`liHBUS\ZIGFEA.<?9A89RF@7:B037=7692:<97:9DM=B<0*<@;A<-5B37=++,/A*JK./*+3722(57$+7.72685\yN2>HiZLZJVbfA:3@aE%5¥¡’Œ¯¡š™ —¥´²£²¾·¡±Å»¹°±£·««®©¹½¼»­À²®¯®¶¯³¹²§«¹°¯®´¶»¶¯¹¾­¦žµ« ¡²¦«° ¦Å¡³¦°²±·­´«®¬®¢™¨«¦Ÿ•›§¦ ™¥£©šŸ›•­±¥º¨®¢¡š›ž™Ÿ¤š¥—Ÿ˜œ–š¡”ª—­ªœ•ž”•šŽ•”˜§§ŒŠ‰Ž{t‚‚‹˜…†|ˆˆ„…ŠŒˆ’…”œ“’‘—Žƒo‚gyniljgqrkZhcaq`dgjmjdhecl\lluqbSbiceZIGLMOYQPUaeT@VRZTFGFE@/<=7?6<EMa8:?249@37818?7=8>FJ@D92-=A=A=05@9@1-+.3<;K6/.+,-24:5#3*)6.55465Z|]1:Lj[M[KXdc@A1G`A'4”£²œ•¡›©³°Ÿ¸À¶ ´Á»½¹±¦¶°©®¥¸¹··­»°­««·ªµ¹­¤³µ±¯©±¶¶±³¶»§© ¶ªžŸ«£ª®¬Ä™¯§°²¸µ¬«ž°­¯ª¢›¤­©›•§¤šª£¥–š œ’œ£¬«©»ž¦¤ —šš¡k£–™qƒ˜¥€v’¬©ž—˜¢“Š˜™€—ŠŸŽx…’‚li~w„ql†Š†}„‹†o]dag„˜†l‹”’ux‹„ƒfˆhvjfX\itnMOibepƒe]dfnjg\[\‰„ˆhOKD8FTg^JHQPUVKHRapteF[QUPEGFC>1;=6=6<4f\5:<75;D4860:B7?:>FLCB343=@@@=28@E=1,,08>G701.*.*/668,#1'214:286Xl15Ok\N[K[fb>G1N_;+.¤›ˆ–²›”¡œª®¬£½Å¯©·Â¸¾¼­§·±¦«¤¸´²³±¹®©§¬´¦±µ¢§¸¶µ¨§­¶³®´®´¢ªŸ´«ž£¦§©œ°¿•¨¨±µ¹­­¤¨¬ª«¥¡Ÿœ¡¨¨›˜¢¦¦œœ§¨“žŸ™Ÿ¨«¤µ°£¢£œ–˜™—£ˆ¡’š‡¡ˆ•Ÿ¢€¥€¨­Ÿ•”ž”‰„rxŽƒˆ u‡Œi–ˆf~sx o‡‡„~Œ|¡  ™€|‡ŸtˆŽv›Šk‡‚ƒnied{mrbT†mdmi˜qXiom†V]hZkiY‡pkyr‡h‡„Y^FN>F^MFSVVQPRWTg^MZLRRPEFG><49=9<7;0<<799:6=F5860<B;<9=FQG=.5<;@=@>59GA82*/1<I:/01.*/(-4583%&2115>1<8Xƒt15Rk[O[L[g_=K1T]7/(Ž§˜„ž­š™Ÿ«ª¨ª¾Ã®²¹¼·Á¿ª¤·±ª¬¦³µ¯¯³·«©¥²­¥¶´›¬µ¶µ¥¦©³²­²¨¯žª¡²© ¤¥œ¢¥ž±¸•¦¨¨·¾¦­¦©©¬§¥¡Ÿ™¡¨¤š™§£¤˜œ¥ª—”¢œ”“¤¦§¡·¥£Ÿ£˜•“˜”ˆ®˜•ŠªŒ™¤†±¥¯ •›¡—z‚Ô¨€‡”À›Æxw±¥·—d€Àœ¿y„„yƒ|‘Êq–¼œÅ{r¶§º{l—±«±yilX±®ofj¼“¼ngymqŽØ}Rjb¶²|~p•uš¡ªVNWaOVMFV\XPPS‹\W[PA\DPNDFI<<57=;:9:.=;878;9>F6:74>@>69?ERI:.5>;B<?A8:J>52*22AE/.32.+/)-/186- /416A1=:Wƒw11Tk\O[M]g\>L1YZ41!§”¨ªŸ˜ž¥­²ª°Â½²µÀµ·¿Â«¦´®­©¨¯´ª°¶´¨¨¦¶¦¨¹¯œ²²¶ª¥¤§²¯®±§«ž§¥²¥¢¢ ˜œ¢¡²¯–Ÿ¤¡µº£ª¨ ¬­¤¡›š£© ˜›© Ÿ—ž¨¨‘§›”ž¢§£¡°£žŸ£––“˜’™…¯kjŒŽªh…–‡­fr Ÿ–›©—q®¡¤wº|k v±_j´[¥€eœ`fzfixkªe¾sg¦Œv±j|±xu’”cmm§n\„ Eigˆ–Euœ_}f{£¦X^Š«g|Œw{j¨8J¯[XTlcZKOY`\VV;NˆPWV0ISSJCEF=?46?;8:90=8999:=<D8;:6=A@6<@HQG907<AC>@D8@G=13-33E3/.53/+/(.0.:6/'$203B/=;U‚v2-Vj\OYL_gY:N5]W31’£–ƒ­§¥Ÿ£¥«²¸­´½¾°·Å²¸ºÃ§©°¬°©ª±¯¤±»±¥¥¯³£ª¹©³³±£¤ ª­°¬¯§¨ ££±œ¤ž™–™ž°©˜œ£ µ³¡«š¡¬¬Ÿš— £©™ž¥ œ™¡§¤¢›—¡ ¬Ÿ¦¦ šŸ¡•”‘—‘›†µ›µy‡©š¶™x‡´›·•˜˜¬—k¦{…†‘”’w«gj±[¬{Ž‡”t‰pŽ†ˆ‘—xƒƒ‹—Œƒ …°vwŸrkkm|‹O¥XHdd™~ch¦_xqtR’†]O©mboz…€a/S¢n[Tkg`LK]dX\ZB>°wWXA#MiEBDA@A19>88:84;:9<9:A:E::;6:CB8=?KNH:5:AFBAAD<FD;0201;E,0.940,.(/3,>831/2-D1<<S}n3+Xj\OXM_fW7K9`T50— •‰´§§¡­©¨³¬ª»·Â°¼Â­¹¶Â«­­¯¯¨¯³ª¢°¼«¢¨¶­£¬µ¤¥³´¨£¢¨ª²¨°¨¦Ÿ  °— ›––—›¡±¥œ›¥©¶¯¡¨Ž©§©›–˜ ¦©›Ÿ¤ œ £¥£–›ž˜šž£«œ¦šœš¢ –“‘““„Õ“™¹q±ÂƇ}֔œ»}œ—¨’¤{†¡€¥‚y«yV¯{‰~Ÿj¹Z¹w‡„}¦ƒ”|™{©yŽ{±mŽ„u¼†o•P¯§ÅŠQ zc`ªasr†k–‡^Rµ´È…~‰|c¤4Cu]QihdP@XgYcaJHMjJZSOYfZCD?E?0<<59;74<<8=:<C:F:;>6:@C;6@OLH<:<DHCBCD<EF81211DB.00483+-).323971#%5*>3==Qwj6*Yi[J[P_fT7H:aP72%œ£“™²¨©¥³ª¥µ¨¤¼¸Á°ºÀ²·´½´¶§²±¤²´§ ¯¶©›©»®£±²¡²´±¡¤žž¨©°©´©¦žŸ¬˜™™˜˜–˜£® œ—©®±©£žŽ¬¢§•—›¡§¡˜¢¢£¡›¢¢¨œž ž•™›§¡œ§”›šŸ¡˜’•ˆ²nhµr¬ˆp§r´vt¶{œš¦Ž£~ž£}°u‚ÒÒu\®|…¤n›ª¦k‡…}­}˜™{±s“y³e–t…žnŸf”RɋZÂ\Ÿyb_­_vs„a–ˆ]Yʝo¿~rMKµSUÆdUQjceXAOk_lhPUFH9=WR[WXHB?J<2?;5=<56>;7><=C;G9;@7;>D;.CRJG>?<IJFCED>II:1746@>/.24252-).26,742&60;5:=Pqh9'Wi\BMT_eP5G=aM62.£ž‘¦°­¥©»­¦´¥§¶»¼³»¾¸¸µ¼¼´¦µµ£³²£ ¬°¥˜¨»®¥²±œ´¸ª ¥¡ª¥²¨¬ª¥š›©Ÿ––™™“”¥«¢˜”§«±¦¡•’¬Ÿ¥’”¡œ¥§ •›¦§¢›£ ®š ž–›£Ÿœ¥”•™£ž•™–’›…¬|x¨w£‹‡ªp­Œ…¨„š›£‹“›‹¢~‘—‡®„³\r²S¯}‚‚£~q×}w…~ž‡™šw¯†Š‘œˆw´aše›•l’[°WKšu˜yfa­^vv…f—ˆj]¯v•žwk5yÈ®³`DUo]g`EPl_pmVUM.echRYQ;AC@L:5?91><16?98@=:C:G;<?:>>E9-EUJE@C:MKJBHG>GK97<46:>/04333.2..18*.32%!04767=Pke>&Vg\@<U_cN6GB`I:77 ”¡·±™³Á­¨²§ª³º·µ¹¾º¸³·¾¶¦¸µ¡¶®  ©¬Ÿ•©¶«©²²«­´¤›©  ¨¢µ§¦ª¤™ž•¥¡””š’–¥¨œ”‘¨­°¥ ”™¨ž¢‘¢š©¥¡•š¦©ž¤Ÿ­œ Ÿ”žœŸ¡™˜›•–¢ ”˜‘§‡©~¦y¡„ªp­ƒ§†—¡£‹˜—ˆ£†”ªz‹yp±Z¨ƒ‚ˆ xtØv‡t¨‚›’¤|–Ÿ„{²^œd }‚•n“]«\[“‘hgªcrz€j˜†q]«Z‰ kmdOJC¡\[Mt]bfMZa_rt`JU5Jš‘XHE=GEAL35A8.;>05A78@<6=<F?:<6?=B7.HVJE@H6KIN@IK@EN::@4.;>102154+*05/7,&21($%6671<OedA&Uf[?0T_bL7FH_C1=7¢šš¿­˜³Â®«¬¨§µ±¸±µ¾º»³²¹¼ª»¶¡²¥Ÿ¦¨¨Ÿ“¬±©°«·­ª¯¡˜¢ ¦¥¤¹££¬¡—œ’£ –•Ÿ›•™¢¡‘ŽŒª°°¦–š§¦ŸŒ’¤˜§«¨–˜©¨Ÿ ¡¤®£ ž¡Ž•¡™  ’œ—›•ž¡––¬œ®nr´t©Œw‹¦t´zu´‚”§¤”‰¤‡Žu¸o‹{‹¢kk¶Z¡†e——h ¢§m”r´t“™³j†’ˆ­ju´af¢o†’k˜]­`N¡|‡‘Rs£ly~}n˜†o\¯V<œweTon.[§OcRkeblZb\`q|cSYQ>?lo2BB@>M:!7@6.;@37C58??3;<CDBJFMIF62JTKEBJ6IJP?HOCFP=<E50;;010/75,+,326/#00,,289/9N`eD'UdY>.U^bL5FM^81A8¥šœžº¤›±À®­««¨·ª¸¯µÀµ½²±»¸¬Â·ª¬¡§¤¢’¬«¨¶¤´¨®ª¡—¨ ¥«¸£­œ–™¦£—Žž¡œ™Ÿ ‘”•¬¶°¦˜“›¬©–Œ”¦™¥­£’—«³¤ ž¨¬°˜¡¢™¡— ›–›— ”©”«™‡Ô”š»u±Ä€Ä‡~֗œ¸yŠ’™Ž˜ŠŒ§‡y¢¶u}wvÁƒš²aƒºyÀ|u¸bµŒ‡©}•‚¬©q{u¼ˆ§ ia¦Ž¯¢~u‡«}¾ns¼t²ƒux€‰mšˆpm¤t½]w}[ay¼jZV\jz^iacfbnyoX[YCA@q?CG+4H"';?10<?7:B99=C4<@NZ^``___ZPPRKEFJ4HLR@JNEFOB<E84=9020.87-*./180"-1,3,;:08LXaF'TcX</S]`K5<L[-6?9§šŸ¢¼£—°Ã¯­©«­±¨¹¯·Ä±»³¯¼°®Â²­¦£Ÿ¥¢œ‘«¥ª³¥µ§­¤ –š«™§¬¸£®˜•¡‘¦ “Ž£ž™Ÿš–“°¹±«•–£§§”–¥¤­Ÿ‘¡¨¬ œŸ©¤²¢¤Ž¦¡•¡™›–•£™° ’•ªž…™¶€’’¸–yƒ“›¶wnlotoy„Ž‰ržÀ»¼š{²¨pt‘¹ƒ|††‹†{Š‡Œ—}¤»¹½œuy³£tu—ut°u™žf‡j¶tsqw¶‹^€y|ˆgƒylzb‹¬pt…~W[§iDdZTf_c]bPgfqnuBMOLD;ZL>J2;0 8>;.3=A99?=;<C6BTYZZ[[Z[^`b`]SGGH4DITAKNGEOF?G<7?7070/9:.,/-*8/%&2(4$(>7/7KT_G'SbW8*O]]=+;VV'=:<¦¡¡¿¦•²Â³¬ª¨­«ª»¯°Æ¯µ´°¸§µ¹®«¤¢§Ÿ ™”­¥®«§¶¨¨Ÿœ–¡¤ž¬¤½§¡ª—•œ‘¢›’¢¨¢”Ÿ—’˜”²µ¶¬—££¢‹’’¦›¥«œ–©¥¦œ›¡ª¦¦¢¨¡‘¬ž—¢ž—–—ž°©”œ§¢kjªz‰tœv{fˆ{½¾Àºo’ƒq”…_rjZ^›Šac‡–l`•cmœvb•l€™•”f^`cq›‰hrŒ|†”fj~qtx~c\xuhP\n„||ŠjXlz‚qHJo…pNqMDV\faL[Wfc^O[mukrRODDM<HH<L?1,2A?8/5?C<9;@;=C>RVVWYZ[[\]`aaa`\UG5CFTEJOHFPIIH;8=51:.1;:./-76=5&"/*2,%;8-7IR^I'S_V4)P^L(3>\O'?2>¨Ÿ©¢Á¤š³¹¶£¬¦¯¦¨¶²¬È¬°´­¶¤¾²³§¡¤ª£œšš¬§®¤¥¶ª¥›˜–¢œ§­©¾¨©¥•”›– š“™¦©¨’Ÿ˜œ°²¾«š¦§¢‰“‘©›¨¤œœ¬ £š›£§¬¢Ÿ©¡™®›”¦ –”Ÿ—±¥™¢¨™’Ÿ¥¦›¨¤›ž›œ›’—‚ho~qw‘—”„‰´ª…˜•ŠŒ™—ˆ”•‰ƒ““‘‰Ž’”˜”™—šŸ¡š›”Ÿ›z¤…kj|‘}uŠ‹ƒr‚wyvv‹|‰jst„tcv}vkoxl_b[ogMXYfj_WYozonfSOFR9PZNRO'*;KB635=@A9:C><ENSSTVWXZZ\]`bba_^^[TKCRGKNDGPLOI<:;489,2;820)6IRO8")+/2#4;*7FO[I'R^T10T^:+=8]K,<-@² ³¢¿¢£°±· ª¦³§¥°µªÈ«­³§¶¦Á¨µ¡Ÿ¥¦œ¥–•¡¬§­¤¤·¬ ™—–¡˜­ª¥ÁŸ¬¤–’œ—Ÿ˜”•£ž£¨“˜¨¨²Â¯™ªœªž•–©žªœž¡­™¡›¢¥¯¦¡£§ž¬˜–¥™š¡žž°¡¢§–™”™”¢¤˜¤ ™¢˜•Œ‹Ž˜®|•œ‚‘‰©¨…€˜—‹„ ˆ{„‘……š‘‡†Š•›—Ž‘˜ž£–™’œ~e¡³®…Š„w{‹~xyzofy‘ˆkuy‰qhsyuƒ†€jsbwe_hecdfjYk{qjj\RKPD_UF@>>,4@F;45;>A;<?>>HNNOPSTVVXZ\_aca_^^]^]XVJKLBIOMRJ;<:786/3964.(&$-1..)+*7%+<(6CMLD/T\Q05M[17E4\G5<,@²Ÿ¹¯¾­«­±² ª¦²­£¬³°Å°«®¤³¯¼¥µœ¡¨£¡ž™—©§ª¦¥¦³¶Ÿ••žšš°¦®¾¡¬¢‘‘žšš”’–¡›—©„©«£´Ç³Ÿ©£ª–•—š§ž¨œ ¤¬”ŸŸŸª®¨¤¢ª¡«šžŸ ˜¥Ÿœž°¤™Ÿ©”š™ž’¦œšªŸœ˜f…”}e›czmhjz£«ješ˜~g…‹eeihz¢ŽkhŒ˜‘¢wkj‹™£Ÿ˜slmz„Œ†yXe]†‚^l‹‹ƒw\htww’€‡ox‚x€rmx„svˆ‡Žƒzh„X]jtd]sˆhj|qmc]QMWJdX@I3=F8?FD71<=?AC;;DGHHILNORRTW[^`aa`]]]]]_^ZTODHOKSN=>==6535554*&&%,*%.++'6*$;'/BI[J.6ZO6)EY/DO1YB;?.=¤žº¼¹¯«²°«¥¨­¯±§®®°½±ª©¥®°± ­—¡¤ž¢šš¦¬­¤¦¨ª´®ž–¤£°¦·¹¥®£š¢š“’› ˜˜¦–{¤«¢¨´Ã·¤¡¦®ž”ž£Ÿ£¤ª©“Ÿ ž ª¯©©¢©ž¦›¥ž§ ¬—¡›¥±¥˜¬–£Ÿ›“§™ ¬šŸ½„Št´s…Ÿ†­hw¹Ä¸q’¡£z¦™™t«‚}ËÀÀºq‹£‡ƒž}–˜ˆžÀ½‚–œÁÁ|z‘ŒšÂÀ}j¥²pŽ‚oÊz€›x’ƒŽ€wy€yp{†px„Š’xlu‘ae^xd_eb]thmdbXLUIQYHOD2IE?DB>/<?>@A:8DCBCEHIKMNPSVY^_`a_^^^^___^\SMPGUNA??=6468266*&%#)*&.+*)109*#>I[L*#CP/#F[3PY/UAB;/8•¡¹Ã´¯¯¿©©”£°ª°¯®¦²µ¯ª§§¦±« «˜›£ œ›ª§£ž¬£¥©¥¥´¤ž£”¦®¬¸´§¯¢’‘™¦“‘ ¡—› žˆ¦«¤«­¿¿° ¨®¨–‘Ÿ¢™¢¤ª¤”¡¡¬®¨ª¥¢¢¤Ÿ£¤œ­©’¤š¨®ªœž«®£—˜§˜£¤™žΔz{¥‚z–—›_­]Ž¨€¡¡|§•›u«ƒ¯^dŒª{¨‡… t—“ˆ³c‚«† ³j„¯t|–‡¸a‚­Y£Ín‘v{Û{™q~ˆ’ve{ˆuvk}‡m}„Ž~k€Œ^pjpg`_xd[qhjce`RTSW^JOC4AHED8>5;@?A;=8@>??BDDFIJLNPROS\___^]]_``_^^[WOUJ=?><5578164('$!',&&/(&+360$7;SL+,-J0';\:L-!P@F4.1¬ÁÀÀ´´°·˜ž‘¤ª©­µ«¦²¬¬¬¥­¦°ª¡§œš¦˜œ¢¯Ÿ¡Ÿ¨§£¦¡Ÿ±¬œŸ•¦®­±«¨¬ ”’›Ÿ¥“Ÿ¥—¨¤ž­£ª°¨¿Å²§©±­–’žœ¢—¡ªªŸ•¡žœ­®¦©§›¦¥¢ ª’¬³–¥¢«ªž¤¨§£²¢“›©œ¢œ–•‘—¡r†Œ˜v†¨‡q°|q¬}  ‚¥žx«‚~­r­¬‡†Ÿv˜’{|—ªˆ¢Œ‘Œœ}«zˆ“Ÿz­VœÄ{p“Á}•mupŒmfwe‡naxnrn‡‰Ž‚lŽcnsuo`fmd_oijnfcXS\`ZRRC8IH@C<><@FDCEA=<<<>@@ABEFGE@CISWYZ\]^^\^_a_^^][ZRC>;92478452&# 1' 1''45-&7=WJ-=(>1)3V@F!G;C1.+¯ÓÆDz³ £££¢®¯·¯©±§¨ª©®«¬§¢¤š£•Ÿ¦« ¢¦ ¨¨£Ÿž°¬˜›–¨§¯­¨§©ž—•š¤¢’”¡®š§£®¬¢¬µ©¹Ì±¬¦­«–”œ¢™Ÿ®¬–¡™žž©±§¨¨šª¦£¡ªš®±¢¨«¯¦š§¬««³¤“™¥§œ–“…¤k¤uŠz©u{²q‚¥Š˜‹qˆ ›‡¤_aR«…€®ƒœu®‚¨††Ÿz™—†{f€£Š¤˜†‚£}©”†®^{¨U¢’‚{£Ÿ€|İŌs¯´³¹rb©¯Âth‹‹•€k–mlxwwnkfedqqf|ic]V_iXXTLLPLCCAB;C@@BI<=:9:<=>>?A=86;DLPRTVX[^^]\^aa`_^]\][SIB679:664,&$" ''!+-"$.!3-&@DWH,G+66*1PKL# A9D4,'ÁÉÖÖÀ ™«¨¡¯¢Ÿ±´°¯©¬£§§«««©¥¦ ›¥Ÿ¦§¦¤¬š¢¬¡¤ ¯£ž›“ª¤µ°¯¡©›œ–•§¤‘›¢¨ŸŸ¦œ°¥¢¨±¬¶Ç±´©«©•‘¡™ ¥³š¡”œž§ªª¢¬™ª¦ ¡©¡²­¡©²²¡œ«ª±°¸¦”˜¦ªš“}ªmŸ„ˆv«y|°n‚¤‹ˆŸ–•ž–Ò¸´¸É‚²_`”©ƒ¥ˆ‡ z˜–šyªÉtš£”¨©’šŒ~š‰šÆÆwe¡‚¥t‚ Ž‚}¯_oµc±uK£‡m§Gƒ“dœzn”Ž|nyt|zm[fjrqgi^aWcm\^YILLJEDBB=A<A?J;79799:;;;3.6<AFILMOQSWZ[[[]^_^_`^\\\\\XMB75785/)(%&%$&),5FNPPMFLJVF*L1/=-4OTQ;<F2,$§¤Àǹ­©²®­¥£œ³¹¬«¡¥›¨¦«¬©¦ ¦¥˜«£Ÿ¯¬¦¡­šŸ©¥§µ ¤˜”¨«¶³¬œ¦œ –¦­’šœ§£ ª¦­ £§©°³Á±²©¬§“‰—¥›¢¤¯¦—¢•˜œ¥¥©™­œ«¥¤«£¶« ±¸°žœ°¨µµ¶§–™ª¦œ¡ƒžNwš‚€Ÿ{„£|‚¤ƒ†¦ŸœŸ”„¸|}z¹ƒ€ÍÆöx›¢’‹Ÿ~™——ŠvŸ—Š¤˜¤¨~¯…œƒžƒ¬}™”a¥l£q…}–„r¬`¤sq€ša¼}RUu‘¡”z{†rys…p[lnwsjnZd^gnbd]KKQSAGGFH::K>B108856877-*5==?BDGILNPTWYYZ[\__^]__\ZZZYUSOH@772.,*.+*'&?QTVWWWYXXWUOTF<E2:P[S6?G,- ‹‡™©«¤«¹«¯ œ¡­³´¦Ÿ¡•¥¯®®©§ž¥¥š¤§¡³®¢©§³ š©¤”£µ££–—¡©µ¹¤›££“¢²™ž›¦¥ ¢¯¬œ¤¨¢µ±Ã°­©¬©‘‡œ§£¤œ¥—ž˜˜™¥£¨˜¬¡«¢¤—®¤º¬¡¶¶®žž¶´º³¶©š ²¤¦ ˆÒµÃ·z‡Ž†‘“€¦w”¢wŒ¡’…¥ƒŒr«ˆ†´nsjš¤–ŠŸ}—™‡‡s®‚¥›£¦Š“ˆ”šmp²\¥s“zœl™{™~n©a¢rs~Ÿbs²¸hwŽ’£–{‰‰Ž‡u{xŽ‚lhwhxsn€t]dcmmfh`JYWW<GF?S3@F><*(63.013)&4:;<=>@CEIKNPRTVWWY]__^^``]Z[ZXURRQF:2230/++(@QRTUTSTVWWXXWUUVUQOQ[U%!2AH#*%’rŠ­¿¿¼»µž—¨¤®¶¢¢™•£ª¨®©«™¥¢Ÿ¦  µ¦¢©§±¤”«£¤­¤ž‘ššª´´¤¥œ©’”—¯  ž¦£œ§œ³™ ª£µªÂ¯¨ª¨¡Œƒ¢¡¦£•ššœ˜š˜¦£¥—©¦« £›¬¦¼¬”½°­Ÿ£±µ»­·©ž«µ§«š|¨’}|°x‹€¤¥ˆœm±o ‡­|¢ƒ¨—š‚¬Š†­†¡•¨¡£˜†Ÿ™–{’~«™–‹«w ˆ“’z¯]£}¦§ež€|—uj®]¥lr†™]`[Œ m”£–€‘‰’ˆxy—jl~b}tm€y`heoohghBX_Z=JS2S8AAC7$$3+''3, /667436:@CFIKMNQSSSVZ]_a`aaa^][ZWSPONI8152.*,ATVVVUTUUUUTTUTSSVWWXVUUQHFIJ#((¼’š„©Æ÷Á´Ÿ›­ ®¹¦£Žš£¤ ¯®©Ÿ£ž­˜ž¹ £«¡°ªš®¡‘ª©¥—Šš­±­§ ¨›­˜™­¢¡¥¡™¤œ­—Ÿ¨¥¶¨¾®¤©£Ÿ‹Ž›š ¦ž’”™š“š™¤£¢˜§ªª ¢ž§§¼¤—¬«£¢­´»­°©£¶²¬®šw¯Šœ…‡|º­‰˜d°Œd–®}¡„§—œ‚­Œ…°‡¨š¤¢£’… \lk‚³`­|{‚²lgn™—‹‡±Z}µ\¤ƒkÈ¢fŸ{»YvµZ²}S¯z¬X€¡m–¥˜‡”‘’ywŒœ}cs|bƒwt€|ajfonfefOTb[AS]=H(>9=4!!,$1. *1/04579:<ACFHJLNPPRTWZ^`_`ab^_\[XUPMJGC553./@UYXWXWWXWWXWVWWWWXWWXYZZ[\XWWGB;ҟ³±·¾»´Â³£œ­§¥·© ‹™ Ÿ²±¨ž¢Ÿµ˜ ³¨ª«ž°­ž¬œ•¯©£Ž‰›Ž®¬©§£¨š®“š©š¡¤Ÿ™£¢¥˜ž¢¨±¨»®¤¨žŽ|‹›–¡ ™’š›‘™—¨žŸ—§¬¤£¤¢£¨ºžŸÆ§¦©¡¬¶·®±ª¡¿±°°˜‚ª“£®Ž›€†¤—˜€€¸Ãº„”…¨™žƒ¬Œ„¯Š©›¦«’սªb¤¿½}£‚ƒ×»¸µ„”’‚ž½¾„k£‚p«„o€z²±Çƒk«±½¬yx¢¾»t€”Œ£™Œ˜’™w™yb|ydŒfx{`kejjbPb[Ri\?S`BL)<:4/$%2 $(0496678;>ADFGJKMNNQTW]a\__a^`[\YTQMHC><A?5=SYYXYYZYZZYXWWXYZZYYXY[[]]\ZVXTWZ»•´´²Àº²¾³¢®§¥³§Œ—¥¿©¶¯§¡¿¦¦±›ž±œ¹¨Ÿ®¯¥§•”¯¬—Œƒš‘®¦£¬¡¥œª ˜Š£“¦¦›š ¨¢˜ ¬¬©¸­§£š—’{‡™‘§›“—˜˜“©˜ž–¨§ž¨¦ ¡ªº¨Å£¡°¤¬´µ¬²¬£¿«³²uvª¤¶…e‰Ÿpg¬Šnnw¥›¡‚v²œ˜q‘Žr—«¤›™¯¥rmmmf‹xomƒšqzjqig‰–•—rii…‡gq‡d^‹cjpZ]g~x¦`br’pfd€Œ‘ŽŸ””–’šz„“td†wgŒjx~ydlcelbJdWIjY9OcDO'J9+# ",)-2.5:457:<?ABDEHKLMOQSV\W[\``a]][TPLHD=:AB7MXYZYYZYXXYXWWVWY]^^]\\\]^]^][[UW^¨•­´©ºº²³«©¢®Ÿ£³ª˜’½±ÃǼ´©ž¿«¬£ §« º£¤®¬­¦Ž–­ªŒ…•–­Ÿ¦«¢Ÿ¤¤ ’‹¥’¦™©š–¢© •œ¥¥¦®¹ª«™š“’{„—¦—‘—”Ž—•¦“–¦¡™®¥œ¡«¸ž°Á¨¥´§­±³¬°®ª¼§²¼˜Œ£©¥µœ‰–¢˜‡©›”’ª´šœ¤®¢µ™¥¤ £¤Ÿ¤¦¢–¬§““‡“•™“˜‘•…¤š—–ŽŒ”“Šˆ…hŒuƒwu‡Œq§m}–“””ŽŽ›’“’…“Œphvo‰wu|yikecocUaX?hZGb_NW+E=+&!640. %2(*799469;>?ABDFJKKMPPQWTVY^`ab]^UPKEC>9=@ASX[\YWXXXXXYXXZZ[\^__`^^^__```_YY`¥–©ª¤µ¸®¯¢°¥®  ·±ŽªÄ¼Ã¹¶©¡¤›¥°¨¤·§©µ§¨‘˜¬£ŒˆŠœ§–­¤¡š¨žŸ“–¤—¨š¨™“¥ £š§˜ ´¹§ª˜š{•‹¡”Š•‘•’—¤Ž˜§žš³¢œ¥ª¶§®Á¯¤¸§°°²¯¬­¶¾¤³Áš“§¥¦´¢’¦žŽ© Œ’Ÿ¢­±›¢¥³«³š¦£Ÿ§¬  žž˜­ž“š¢œ”—«™™š——Ÿ‘‡ •”†”Ž–‚fŽˆvˆwzˆ„tœjˆ’–•’‰}Œ–‘’–Ž˜’…—†zq”ry‰q{~jnd^pi`\_XlbO_cOX9FFD=2<=7.*%+)&&416658:==?AACHJGJKLMSSSUZ`aiaeUPJACB;9EMV[^^[Z\[[[\]]_^]^_`aabaaa`bbbdb\[c˜–¤¨£°´¬¯£ª§® §µª‘›£²¹­ª«¡¢™zœ¡°¤¦±©—œ¸¦£”˜©œŽ†Š‰œ¢¯Ÿ¤–© ¡“—™œ®‹ª–Ž§˜§Œ˜¨Ž¸µ£¥—›‰y‚“Œ›“Š•‘“Ž‘–¡‹œ¦œ¶¢~ƒ®´¢°¯u¤¿¤³ y{£­µÀ˜x°¦¡Š€ª~d\bvŸ¤žƒ–~m”µ¥©±­¦f ¢•u{œ™q™ª™m€¤©Šeœ¥œ‘˜™—Œ“œ‘…›•„”ˆ“‹†yl‘ˆvˆr|†ai‰Œ•“Œ[v•fhŽ‹qxŸ•”dw—†w—h‚‰‚nykpe`vokkh[dcaamQY=MMMRF=?SB90/&4:306678<;>@ABFHBGFIKLTUUY]_gggWQI<DH<9VR[`ab`^__`aa_\]___aabcdabaaedchd^]fœ–¦£¡°±¬«ª¦©®£§­¥’•ª´®°¥™©¥ª–s‹œ¯ ¨«§”—¹  œ¤ž‘~ˆ‰šž¬š¤•¨¢žŽ—’ž…u®ˆ¥™¨‘–£ˆš¸³§Ÿ˜˜‹‰tw’—“‰““Œ’ŸŒ™ž¤˜›°”€Œ›µ´Œ’½§¢~§£{¥²»„Ž© „Œ…±ª¯Œ‰–£šy€‹¬†Ÿ£©«ª‰–ˆ›w¥œ{ˆœ˜§„‚{ž³{Š† ˜™•˜—‘—–„ššbyˆ’…Ž“‹„nr‘ˆz‚r†€‡tˆ†—“x–h“t št{™›˜„˜~‰‚—iŒŒ„jx{qpgexmilj[cihdqZ[HSKP@E5-YST6)!09=>743568;:=>>?DI@IEJKGSX[X[aaifYQH9EL<?bV^bded`aa`bb_]`aabbbcfgcba`edcgcaah˜¤ ¦®®«¨­ ©±¦§ª¥™“¬Ä¼¯ ”¥§³œƒ¬§¢ ¾ž™Ÿš¡‘}†Ž˜—ˆ¬£–¡¡’”‰†€‘¨Ž†¡œ£“–…ž¸±¨š’…pu‰•Š“Ž›‹Ž‘•ž¢”ª†Ÿ´‰´š®‹Êˆ«¯Š·…°„³³‡©ªš{¨r{wœŽ¦–h•¤y´Œ¡ ¨ª”šÂ‚«‰™¡rž€›¥~—†–²¡}¡“Ÿ˜˜€”›‰™’‹}†”‡–”Š…nt“†€{s‡‚„}…u†ƒ˜‚Åf€©‡¢i–€™€Š‹ƒˆ˜o’„gwt|wgivpghk^bnlfjWdF\QL2E46M`c7&3<EGD:63658;8>==>BL?NIJLCQZ]\Wb^jl[QE=KM@JdX]cfhgbbbbcc__babcccdiicbbbecafcbbi•—¢ °©©¨¦¬ ¥¹±©«¦š”ž¡¤©¡”£¨µ¡¯ §¥ž‰”½š“ ’yƒ––‘ˆ«™œ›š¢…Œw›œŽ ‘‡£›–˜—…¡¸­¥™›ŒŒ~bm‹“ŒŒŒ—‹‘ž’žŸ— ¦}¡§‡­ –® ž‘‡‚¡®³‰¤¬œŒš}¢u€™”k‚«uM«x‡“œª©‚ª«…¢|{§jž€“lg—†˜·‰ž~n`cXƒ˜|dgŒs™~z˜l]}˜oaTr‡]`mz„`Ye‚~…™r¨ªkƒ£nr¥oŸšgdžlZl‰{eY_‚~aWPpveotqjjo]ioljgWfM\WE8A4FC^k4+ICQMN=84859;6@;;>BO>QRKMBJ\]_W^^cu_MD:MONTb\\ffiibbdbddbab`bdcabjkdbddgdbgeach˜—¡¹¡ª¤¦¬’¢¶¼ª®¢™–ž ¥««Ÿœ­´¡§‘  ¡§œ™Ž˜´™‹žŒ•‹u”‘Š¦––˜žŸ~“…†¬¤‡œ‘Š˜¨—™š‘‡¤¯¦¢•™‡‰€inˆˆ‹Ž‰Š‘‹‘¡Š’œžš¡£“£¡” wœ–§ƒ£©€‡¬±ˆ¥z„š|¢pr“‡•{žŒym‡›‹š’ªœ‡~„¢tw¦gž~w¥_˜{}“s¢n˜·´ºt“ˆ‚€¶¨dÅ¹|q•¶Œr›¤du¬«a~j³~n~‰„ƒŒ˜q€£kr£rž|£^œ™³•p|—ž³tr[ž²ƒjbqtuqhoXjkqpd[g\aKC=D6QAYq2<SG_JR=<395:96C<;@IP?TNNQ@E_^[YW``{dIC7LWUVcaZffkkbbeadc`ab`dd_`cknccddhdbgfchh”–•¤¹™«œ“ Ž¥¸µ¬­ š¡›¢£¤¬šš±¬«“˜¡™¡¥šš”ž¬›‹‰‘x‹…q€•Œ‰¡“”—}‘ŠŽ¨ ‡˜Ž‰‘¢“›šŒŠ¨§¤ž–‡„~jz†~}ƒŠ‰Ž“Ÿ”œž›Ÿž‹‰wœ˜¢ r¡Œ‰©‰¨’™«®‚®~z ™y£“x€s—‡Œœ}”ž†›Žš¨ˆ£d¡~Œ—›mžh›Žoš™{€Š§}rht«ƒžƒsªg”š]›…w…žhªj€¹f\©pœa•Œ_§vwŠ‹€hšu‡“’˜}žl˜j¦™\¨~w»j}©ZŽ„]³g[nrxwki[piwwa^dVaAPDN7UBQm4JZZ^NZD@151<;7H?:CHU?YSX]>Db]V`Qad|iFB9N[]YefXffnmbbe_aa__``ec^bdoq_deekecihgki–‰ª¶œ¨‰c•œ¬»±¯«¥›š§Ÿ¬™°§«ž—£š¢ ™–– ¤™†‰iˆ€rz–ˆ‹––„’”˜z‹„–¤œ‰•†Š’œ›ˆ¨¢Ÿš‹Š€€i€…y–‹zˆŽ‡Ž•™}’¡Ÿ¡’—rhŸŠ Œp’‚©‰š¡¥ª£«°®¤¢¸—v£³¢£ˆ”xz©˜¢Ÿ™‰˜r }ˆŽ°µ}lš‘¡x~™µ££«¨„™|›}œ›tªZ]o{—ŒyžcM{{†ez˜BMŸY¢js}o‚Š„™v›y‡‰±³}™’¦s}mp|”o™ri£]•vHec_tq|}ne_kguzbc_P]W\SV@YEPgDRV\aX^ID=B8?B:IE7LEXAWR[VEFb\Z`K`m}qEC<V^bZejVghmobff^a`\]^`hb_ecvl^egfldelhili”ž°®š„S_¡§´º²²¨š¢‹š©››§’ «£ ¨žžš™•˜ –‡‡‰w…nx”„›‹}‘“–ˆr‰’¡›r’€ˆ˜”Ÿš„Ž¨œš•ŠŠŠ|ƒl„…q‚¡‹w„Œˆ‡‘˜”z‘¢Ÿ¢‡­†}µ„ž{¦–z©‚—Ÿ‘Œ¤¡€§ixn~™s sq|…˜o“‚¬{£„§Ÿ›ƒ¤p_©hv£dp¦aœÓ|{™xrsc¢†‘~¢r£vk³Œ`ƒ˜‹u«³¨¼w„o¿¦ª´^œor—p‚t£r^¤gt¦`h¦kšÓ˜yšnvy—k›yv—rl©¥g_eyq„lhfcmuvf_aQZePQaHVIT_WS[ej[ePECKLIKBKE8P@QNXSXOSQ`ediSdxywJGEd]eZhiSihjncjf`c_\]]_hbahe|d^dgdkdjlghmh˜›°¬T]K~ª¯±´°²¢œ˜„—¦  ¢Œ¤§Ÿ—©Š™˜™”š“’ ˜Ž‡…{p}ƒh|‚“šw‘ŽŠp€†“‘k˜“|ˆ‘’£•‚¨™“’Š…‰yƒvˆ€nŸ†w‘…†— •x‘ ¢™Ÿˆ³¡¢¶‹z¬§¤®¥q©€›‘†‚Ÿ•~¥£›†˜qž„¢­¯Š—‹Œ¤•ƒ¯£•wµ¶¶Ê¢t”ƒŸ`—©my–‡ ›u¡‡w ~‘—‹oMf£“q›‰t¥{zub„ƒn~ mrd`œst˜k{j´¶´Æ¦s˜}yœjš™«s€šlsw—i™yt˜qPD}³^ivkx†fkfbstolU[RYhOQgIULXRU\gknUgWMJAIMKHJNAQJPecjmeussy{nt‰z{UQNm^h[kiRjhilgmfce_\\\_ibdhk{_]dgcjfnleime¢ˆ¯§…e@”¢²«¯¯µ¡¢–§¡¡£‹¤¦œ¦‚™——Ž—›“Žˆƒyky†eƒŒ— yuˆŒ‚j……’„‹…zŒŠ•¥’‚—¨–Œ‘‹€ˆz€}‹yp …y€”†ˆ•ž”~’¤¦›•–„fnxœl¢d|r¥xœ˜ph§ƒšŽ}¥{¢—ƒ–rŸv‰”–¹nŠ¢b}š£—‰ntk«ku np§a›j‹i–‡›•u¢~š`‹†uoˆbh¡fžj›uqeg‰‚os¢[_[d¡n^‰q|€trd¥nx¢cf§g—qŠ—m¡oRˆn ^d§T‹]T˜mmskqmphkwsjnQVUUeXRlIXO[HWhhsjYkVPREV\LXRaUhj^wu{|p}|rƒ{sw€ƒw^QsagbpgPkhhklohdg_]]]`jbjivu]\chcjirlfkmc¦™¦{etmŒ§®¥©°±¥Ÿ‹•©œ£‹¡¡š¢¢€•™“Žš‹—‘ŽŠ{†q€ˆhŠŠ|—›su‰}|eƒ‡•Š‰•š‚|ˆ†–¦€¡ª„Š‰}€€Žsi¦ƒ}…’Œ‡—Ÿ†‘¨¥œˆ¦x•›~¥‰–Œ²™ž‘„¯—Ÿ¥z˜‰{©u¨‘„šn¥¢Œ’„Œƒ¼m|¥¯‚‡…‡•˜ž£~¦|s¨•¡–iŸp¬c–Š–“x¨mª£‰v‰ƒw«‘¦ˆk’±lw³©l‹†oo ž’•b«Œªx€Ž§ŸwŸ}…¤– g™†t«fž­Œ¶sv¾Œ¤“Yƒ¦«avrto{upbj~nglRTXT``\jL\Q[H]lmv_[qX[_Zgsenoqcqt`wz~yryƒs„~{{Œ‚€vbydcnsdRlggomrifia_^\ajbllzo\\bibmiwmglob–¦ª€Ÿ¥–ªªž§§­£˜ˆ–©™¢‰š¤œ¨„Œš†œ‘…’ŒŒt…zˆƒoŒ„~—“tu†r‘ƒn‹’†…”|{…—¤¤¤€‰„”u‚‡“nl‹¨€‚Š“ˆ›ˆŠ’©¢Ÿt“—ˆ~y”¯¤‚q†y“Ž†{s©q}}z—–›…Žx{}}†“•“‹w’š¡£…|‹m†\zys{qin~“Šr€t‚”“q†„ƒf_‚Œxwt•vpzop‰n…†_wixŽg‚ƒ†ªœt}–i‰ˆo}u{‚tllfŒsx{—w„[kWyinwrrowxo\k…nifVY^V\ejcU`T]P^owykjvdijju{pqtsaotbt{xuz‚u€y‹…‚~{n€mdyn^Wnhhukxjijd\`ZcielqunZ[bkdlkymhlo`Ž”¹©§‹¡£›¦¤™¤«¡Ÿƒƒ–©‘Ÿˆ™¦š¨™ƒœ‹~–”‡ŽŠ‰r‚|Ž|~Ž„{—Žts„p•†|}’‹††…x~€†˜£Œ{¦ŸŠ„„•‚†Ž˜wq„ª…‘›Ž‡†Šš¦Ÿ «ƒˆ”›~Š—­¨“¨‘yqŸ”…|•p€¬‡q~•qjp}Ÿ‹‘Šgm]„ŒŽž¡‘t—ŽŠsulƒwtYro‡‘‚~Œj]id{…„‰€`iy|œ|„„w‚ˆ…jz‰lbqsƒw`tƒŠ‘¨–‡gŽ‚lvŠm‚Švmcecyƒz•Z\ignv[{ywunsrƒf[l‰kkbYX\YXkq[^_Y]\er}ztotbjji{{qzvtdmthm{~uz}{yz€€o†‰ƒ{}szshT\rilvouglgd]aYjhkjqrmW[emlgryohjm`ŒŒ«±¢£¡šžž˜™¨¡ }‚–«ŒŸ“†š¢‘¥•{˜…|’™‰ˆ‡‡Šq}€Šv„‹„–Šro€s˜‡„~“ƒƒ†Š‚z€ƒŠšŸ¥Ÿ†wŽ—ˆ•Š‹œ—„ƒy¬—˜“‰œ…‡ ©ž¡¢£‹‡’›£š–«¢¨¨¢“‰™‘~z‘†ª“‘’“²¦š”žŽŒ°‘˜„§ŽŽ–¢‹’…Š“‹l}wxf‚†‘‹}‰ž„ˆŒˆˆ…„‘x|{uœ¤ŠˆŒ Œ‡–€€Žƒwqu†…€yŠˆ‹‘§‘„‡Ž‡‚‹Šyƒˆ…Œtjƒ|y™irhasŠq~{wwpwt]]n†hn_^YZ\SgqUc[Z`kgt{{rnocjjh~{lx~phookf€{r‚€w}„{mƒŒ…|zy|}z„yOdwksnpzelebb`[sfpfrqmU]ltmhxzpgikeˆž»Ÿ—£¡˜•™˜”˜¤ œz~—©Œ…Ÿœ‹ž—}x•ƒ{Ž™‰†ƒ„†mx€r€‡~ˆ“„mk~z—‡„ƒ~€†„‡|‡‚Œš’†©‚rŠ…’‘‹‘|{©ƒ‘–”›•……š¥Ÿ¢šž†ƒ’š™™™¦ ¦žž—‚”y~Š†§|}‘†˜ª¡“Ž¨Œ‘€ŸŽŠ•œ¡„™€ˆ„py‡rua„ˆwŒ™„†…†„•nzvu”¤ŒŽ‡œ††v‚~~ts|Š…|zŽ…”¨‡„‚‰ˆˆs‚……ˆymj}{mhklg^yg}{vuvu{w\_p}mt`cZ[^PflSdZ]`jhty~pllckjg€krkktnwm„yn†€v‚€}…vq‚‡~{{}€{‚‹`i|kuhiƒejc`i\cugobumlTbqyeoyzrejmm‹ŠŸ¸š¢¤Ÿ“’–—‹šŸžœzw›¤›‰†¤”‹˜šyz†|Š’ƒŒ‚‚‚m{~wr€…}Š}kh}—‰ˆŽ|~…„‡|››ˆ¦›p‹Š‹’† ¡Š…Œ|¨‡Ž‘•‘”‘wŒ£ ¡–›€š˜“š¢¢¤›˜’œˆ{‚†‘‰£~|˜¤  ’š¥‹œ’Š”™€””ˆ‚uu‚qwa~ŽˆsŠ–}‰Œqƒ†‡hxrzŽš”‘™€Št„Š~s{|†|{“Ž„—¦”Œ†{„…†ƒs~€„…xdpzwypljf^}sh|uvt|s€j^`twpwdcX]^RigTdX^`giuxpfkclgejm}gmpj|w†zk‹r~uv‚†|{€}jr„ntibˆilb_qVtolm`xhmWjsvctzzqbkoy‰Ÿ³’¥¦Ž˜…œ¡š›|u¢ž—Œ¡Šˆ›–x|†ˆ~„Š~ˆ‚pzsu‚…~‰wgc}†—Š‚Šx}€Œƒy–€•—••ž™}o‹“…¥›‡Œ‰ƒ¦”„‘‰”•‘u‘¡¡˜”˜z˜—Ž–š¥žš”•{’‰…zˆ™ ‚‹ŽŒs˜£ž ’˜ŽŽ ‹‹ƒ˜˜„”—›€š}‰Ž‚wr~n{d€}‹‡q‡”€‘‚k‡ƒ‚€‹†fvp}ˆ”šŽ•yŽ‹~‚‰~}sy‹‡{†’‹Œ™¤—ƒ„‹v‡ƒ€sx†‚s^vw}r}vfle`ijwstu}q|cdasourmaY_]ZjcRbW__gjtx†pbjbkfh|‚khthloh|yl…q€ƒƒt|ƒŒ€~z‚ƒ~|mu‰ttmfŠljbcuVƒipn`xglajvpfx{yq_ql……¯˜§©žŽ—‡…Ÿ“•—|v§›Š˜y—œ‹Œ™y|Œ}}ƒ{€‚€xsxys}€ƒˆ‹€d^}‹•‡…ˆt}~‰~˜„–”–Œ£ –~q†{“‘Š¦ŒŽŠ’ ‚Ž“–Š€— š’’s€Ž’”‰ž§™™Ž•—u‘’Œmˆš’œ|ˆ‰‰o˜š¢’•Š‹‹†“€””—ˆ›Š}ŠŠ‚{qzkvm|Œn…“ƒ•xp‚„~Œesj}‚˜˜†u’‹†{‰wz‚ˆ‚~…‡•¥‘y…‚tˆ†{~qr~„€k`ytyp{nance{bnovsxwttaw`olunp]Z^]]i]O\Wb`glrzˆj_idichw‡mflhilg€|zwnˆs€ƒ…}t†‰zƒ}z„}|Žry‹yxnl‡kh_irb‡hqoevgmlazhj|{xpawm‹™™«¡¥©ž‹‹‘†‰‹”–|v¬˜Œ–|Ÿ“‘—”‰w~{Š||€vx€osszo…|€€‰~|`[~‘‡€„„rz†z‘‡‘‘›’¤š“||Š’¤‰Š–šŒ„—‘”ˆˆŒ’“Œn„‘‰ž™¢¡˜˜Š—“pŒœ†hŠ›‘–{‰…Šp–š”¡‘‘ˆŠ˜Œ‚’Ÿ}“‘”š|‹†ˆusukqnu}‹uo†‘Ž’rt€|‚‚Š~gsnz›•~†Šv’ƒuŠ{qƒ€ƒ‰~†Ž‹†Ž–«Ž{ˆ|~Š„v|nl}‚€afwstnza^oakt^pjzyymtqez^nlsmsYY]_`iZOVWdbepp~‡e]ihfbgpnchhehg€zwtoŽ…s‚ƒ|vƒ‰…x…|x„†z€‰w‹|{syƒjj_phtkqomqgoke{amywplww‰£˜£¨¡§›ˆ‹ŠŽœ†’št¨”‘‡¡–”‘t|v…xxrsz…lqoxl‰v€†nq[Y~’ˆ€vu€ †Š’œ— ’–w‰~€ŒˆœŠ†’—–…ˆ“˜Ž–‹ŠŽŒŠŽ‘ƒm‰‹‘Šœ–¡œ™–†™‰lˆ¦…h‰ Œ“€…Œx”˜’‘ˆˆ“~™}’Ž‘›“}‹…pvplnop|†jsƒ™‹rx€u‚‰ƒzhupw‚›}Š†{–“|xŠvrŒ}ˆ|Œˆ…Šœ¥‰|„vŠ~wwkh~~[qrqoowZ^papk^oj|zqnmjmw`pokqnYX```lWPRYeeato„a]kldbfk’n`ff_fjuqro‹€tƒyv‹€y†x‡†vƒ…{†‹€{w‹jpc|b…|opltjhnlww_q~y{tus‚~¥•›­Ÿ§—…Œƒ~–•ƒŽt‰ž“’…‹›Œ–ŽŒzrxt‚pr„tquˆlnltl‡v‚}mnUQ«”‡‚x€vr‚y‚ ‚’’˜š‘˜wz‚Œ’£š“Žˆ”˜’ƒ…•˜Š’‹‰Žˆ„‘‹}rŠ…ˆˆœ™ž›—–•€i‰ŸŠi‰£Š”†’„Šqƒ‘˜š‹‹Žw{“‘{ŒŽ“—Ž}‰~‚lwjollm{€bz~—‚w{‚xƒ}zivmvˆ—Œ€‰ˆ}•’s{†ry|Œ|Š…Ž‘Ÿ ‡}|wŠ|vogi~v]vnmkprU]nbra_mnyphpfgtviqlawf]Ue`_qSPM[ec\woˆ{^\hpabef‘j_gd[go}olqs‰}v|†uvŒy|†€x‡ƒs†…~ŒŒ„|z•xgqjƒ`‡~ook{`imt€t^s|x†xts…|y¡š±œ¥ƒŠ‚™ˆ‰›~‰˜’Ž„ˆ˜Ž„wtws€po„tpqƒojium‚n||mtsRN‚ßɒ֓|otƒuƒŸ‚‘v”˜›˜{“r…¡““‰’š“…}••‡Œ‡’‰œŽx{ˆŒ‰œœœ›–”{ŽwiŒ”Šn‹¦‡•Š˜„†cŒ‘˜Ž”‰–‹Œ‰‹pz•Š|Ž‰‹”’‹{‡}€m|esokm{z[z{~€†{ziuktŒ‹ƒ‡†~—m€€p‚Ž€Ž‰~…|„‘–›œŒ}wx‚Žwqkdn|€igsngislS^oepY_lqwgkkbgytppd`xa`Uk_]tOMK_eb[wp‰s\[du`beeŽc`fbXissmkqv‹|sy†‚vw~‹s€‡z‰r‰‡‰‰}~™vesn|e‡~nokYlnyzr`vz{vrv‰vyŸŒœ¯› ‚„x‡”~{ˆ›†„Ž…Œ—„“ˆuwpyqo„pmm~rcdwp|my|jhlc¤šÁÜ®ï¢slvƒu„¡„n••Ÿ“š€‘p…Š¡–‰Ž•Šœ•‚€”…ˆ€’ŠŠ—‡{vŠx†…››—™wŒwpŠ‹Ž€§‡”‹ž††^‹”—ŠŽˆŠŠ„‰l|—ƒ~‰†‹“‡w‡l}dxujoztX‰{’ˆ†{€†zgtjŠ‹„„˜‡mƒwp‰’ƒ’†€„|’—”›‘utx‡‹trpdrv_rloahtfR`qgkU_nsyarc`i~qsn[csacVnZ[vLLKbe`]ur‰m[\dx^`de„_cc^Xirknkrw‹}sv„xx|‰qƒ…}}ˆ{t‹ˆ‡•…Œ˜shuqym‹znsp€Wqzvyqdvy†Œhv€‰q€ˆ™¨œ£’„}p‹“wx‰›ƒ„ŸŽ|–šˆ…|swpsjoljl|t^`wv{ptzg`e|ëÚµÉÃ܉sltv‰™ˆŒh—›”’ˆp…ˆŸ…‹•ŠŒ—“{Œ’‡‚ˆz‘‹†‚€wxƒ„r‡‚’›–“˜‡vˆqˆ…ŒŠ¥†—Ž „Ša„•†ˆ…ˆŒ†€‡h}”€~ƒ…‹ƒrˆ€€rwhvriuwlZ}“ƒ†~„„‹ƒwbumŠ‚‘Œƒ€”“pƒmzˆ‘ˆ”†}ƒ“”‘˜Šnqy‹…tjoiou~]rhm\it_RdqifS_qvt`p`]h„qsjWgidiWmW[sKIKde]aqr…i[\ex]^dgz`d_]YknenjswŠ~ss~{vzˆs…„|‡vv‰…˜Œ‚|”vlwvyx“tnwz|Xy†q€ngxv‘‚dv†…pŠ—†š¡›¢Š†sn‘Šrvš}Š™ˆ‰|Ÿ„š‚yrsnodr~iflww[_xzzqqiagaÕ¶Ž‘¦xnqw{p’Œ…i˜ˆš‹…zh‡‹™†’††—{ŒŒ€€‰{~‰…zu{ƒ|q†€•™’”‚‰v…ˆy†ƒŽ– ¢‰˜’¡€‰a”‡„‡ƒˆŒ‚f}‘€€ƒŽ‘n„~„ulmwutxvkcŽ‚†}…€…‰p`tr†}Žƒ}€’Š{r…g{…Œ‰Ž…}†€•‘”…nox‹~tlmhixz`giiXkuYRiribQbrxmbe^Zj„ntb\h`em^nTZmMGNec[fmpkY[br_\clvde]]Zllbljsv†qo|}tx†x…ƒ}€‡ux‰€’•|‰†w‰oxyz„’omz€v^ƒtlhzs”sgr‡|q’’„šŸ› ‡†uu“~mu’•}‡„Šš}Œšv~wroljat|gbiuyZ`w{ymp~edhhW_rs—¼Ä„uq”ˆ}q–‹†›’‹‡riˆŽ•€{•‹„š‹{Š†|z‰‹”ˆu‰†vw~ru…”…”„„sŠw‡Œœ œ‰–ž‰f}“‚…‚ˆˆq}f~Œ|y€‰~j~…vfpyxtxtlj†‹‚‹yƒ…„l_sy{~Ž‹†|ƒ‚sƒjz…‰ˆ†y…~‚™Ž‘~nmzˆ|usmfe{tb[pbWnqSSnshaNguxf`^]YootZfb^kn`pPYjQDRf`Yjml{nY[]lbZbovdg\]`kickjsv‚pn~|€tuƒzƒƒ}…v}ˆ–x„‹uˆrxy~ooz€qixz~ml{u•kjw„sl“†Ÿ™Ÿ™…‡n}‹uiw–~€‰ƒ•—Šz–o{tqkjd`szh_eqzZar|ygpyaed±²wKbZ¥ÙЖqzŠw|“Š„˜‹…nk…‘‘zy’†„˜‰{†ww‰Š„–€o‹ˆqu~{jy…ƒ¥ƒ“„€p€…x†|‰Ÿœ˜Ž–’–…ˆp{“‚}‚‚ˆ‚mvh€…yr€…‹ˆ}f~…vdqs€iyppu™Ž†ƒ‹}wy„zƒk\rs‚‰†Š~‡Š|‰s‚nr†ˆ‘‡‡t†{‚šŽ…ynn}ƒ~uycfh{o^XvZWplNWqsg`Klwta^\[Zu~spXg^gjq`oNWgQ>Xe]YnjgypZZXjeYcpx_g\^elgfkiqw‡nl~€up‚{€‚‚v„ˆ—‰q‚q{†|zy„”Œujy~ko~t|or{z“oo~xg’‹‚¡™œ‘‚…f†‚ogy”ˆ}~„‚˜‰|Žhxskkf_`oxm_box\dk‚z`qu_eeÔ꽋2:>‹Žqy…‡Œu‚–Œ~’‹~mk„ŒŒu}„”ˆ{‚wmu†„ƒ—wnˆ…lu{ufyƒ¦‹‚‹„~nvy†}‰ ““”•ŽŒ‡{’†xƒŒ‚kqh€~yn||ƒ‹„xbz…‚rerinuru‚œŒ€†€tvt‚p[n€uyŒ„‹|ˆ~‰y{rmŠ…’…tƒz€˜Œ‹€unjv€ts[ggunWV|SYodKZrre[Iqxo\[[Y]utiZb[hfocjMWeP=]e\\ue`toZXTncYdqyZh]`gmgikipw}Žli‚„yn€|}‚€‚zu‚€“„p€‹nx~€{{ˆ“Šhz}js{r†zsv}~Œyx„}|k‹ƒ›ž–‹€lŒ}jh~‹z}~ƒ”‚~}Šˆkuqghb[bfrn_aks`hpˆybss^cd› n]6Z¯µti€ˆ|‘†u…•…sŽŠ‰vok„‚‡ty‰xˆ|’‡y~rfuˆ~~˜oq‡ivynfy‡„¤†€‡ŒŠo€x‚„€œŠ…—“šŠŒ…‰|ˆq{}„{h~lj€{zj{wƒˆs`x‚resgvƒnu|†–’‚}ƒpxz|u€mXp€wuƒ‡xˆv„‰|yto‹‚’‚‡s€~”‰Š|onimtm[edqoPZzN[o[N[rodUKsxiWYZZaqua^]`gdiifNYgM@`c[`u`]ulWWSt`ZdorWj]bhkgmlhpw|’kh„Š}|o~~|‚€zw€Š‹ƒq|‡orxƒ{‰Œƒj}{mvxvŠv|x‚†ƒ~}zm„‹‡˜£Œ„ƒ{uŠxjlƒ‡x}z‚‘€€~‹ƒprpcf^Yf_po_`gofjn‰tato[adjuz€¿œ¦¤È¸q…‚r’{w…’‚s‹‡rroƒzƒst‡t‡w“‡xypbv‡z€“ir„wgwucj|‚‡€Ž~su‡|ƒ–“†{™—ˆ‚‰{‰‰kxy~tgzhkysizw„~h`x‰~lkth|iv‚Œ’•|€q|w|t€bVx~st‹…‚}„rˆŠyyrq…ƒ€€z~w†„wjqhl‡qo\f`qlIduK]mUSYsnbQOtxaRXX]apƒs\b\ieedkdQ[pICc`[co]]xgTVUv^[enhVk]`jgennhpwz’miˆŒy}r{~y‚|v}ƒˆ†ƒow„rnw‚‚~ˆ‹“p€|wxzŒt‚x‚„z€uo~Š‹›ž‡}…yw…zgt…‹y~{ˆ…„w€gpn_d\XdYlra``plkh‰n`shY^cnw©Ú©Ç†‡²qˆwoŒtz…y’‰tss}voqm„s“…xtk`y‚y‰fr„phun[m}’€x‘“~y|oŠx„”Ž‡w™“ˆ†…|€…mtu~lfvdm{vnkww€€}acy‡zivvc~|hu‡–}vwq€{}nZWupv…ˆ€zmŠ‡uylv‚„…}~z}tŒ‚~thtenŠƒlrYh]sdFmmKZaWVUxmbPRtvXPVX^`r„o]acmed^ocT\qFBe^]eg][zbQU[t[Zgk`Vj^`offkqhpvxŽtkŽuvx~w„{t}ƒˆ‡ƒor€tqu~…‰‹{w€x‚{|…‡w‡|}}„€{~ruy‹ Œˆyˆvt‚x^}…—‹x…ƒt…†„xŠ{bnl[b[[`Visb`[gnof‡raqeW\bk|Ê·¹¡jmm‰kqƒq{ƒ‰~z„yxsxtt{jlubƒu‘vnf_}‚zŒŠer‚kjqcXlz„›ˆr–•w}p‹s…Štš’‰†‹ƒ{y~qpo|dgpamxqkmqx~~z]f{xjvyfƒwhtˆŒŽ–~s‰ko~‚yo}^Yt€mt‹|‚opŠ€rwix‚ƒxs{uˆ}{sgran‹€kpVi\v[GmjMVU]SU{kaOTurPQTW^cu…i]`ljfcZoaXboGAg\`e^\V{]NUdoYZjh]Wg`_rfjhrgpsw†xn•‹tzw~zƒˆur‡…Ž‚pp|xvvz……‡Œ†z{tŠ}}†„ƒ‡~~}†~|yuxw‘“Ÿ~‹|Šmuxc‚†•†s‘Šo……{„ucnjY_Z\]Tgsd`Xdqrg€rbkdVZ_jx¾®{Ÿ¶mas„gszqx…z}‹~wwruo{vejn`†uŽ€sia^~yy‹„fqhkkZVow‰¢€„p™“rzw…p……•‹v˜‹Ž‰…‰…}ytrohx_il`mvkhkkyx{w[g~}yfs~m…ueu†Ž†—€qhk{„unvc]r~lu}Œ{‚gvˆ~oriw€z€t~m{|ƒ{xqflam‰}klUi_vUJijNRNgLX|haNUukLPTU_gvƒg^aqhgbXi]\kgJDjYbcVYUyYMVmiY]kd\Ydb^tfldqgrpuwp™†v~w}…‡}us‚ˆ€”‚nsy{zts„†‰‰ƒy~uŽ~|„Šƒ‚„{~Šƒ{w|wwšœ—zˆ‚†iv|{lƒƒ’rŽq†‚ƒ€pflfW][\ZSdpd^WbruiuoeebW[[hpor€s‰ddy|hsusrƒw€‚xvrumjzqagkf†sƒmf]_}p{‰imxgjdUWroŒ¥|„{v–‘t}t~}p~”ˆy›~‰‡ƒ‡ƒ}upqlgt[kg^ltdhfizo|rZhwuiqx‚wbw†‹|•‚pkn{ƒrgtfao{gsxŠ|~cw„wklrv|r|{uh€€ywodfbm…{ljUhaoRJhiOKNoG^zfaMUtdJOSWakwf]gtif`WdWbp\KKjWcaUTUrVKXudY^k`[Zcd_vfmbpitorut™‚w€w†„z}u‚„~—…mrt|zuq„…€z‹vs|•€…„}}Œ†z~w{£¥Šy‡…ƒkt{zu‚€‹yn„sy„}‚ƒvojheV][ZYSbnd[Xas{jhli`bX^Ziikp€gl`gywirsslƒ€y~{utmzgiyj_enh€v„feXbwj‡{ojpgf]TXog§v€z|Žzvq€qux|“ƒ{—v†„€†ˆvjruggn[ld]mr_hajyh|m[nƒsukp~zxaw†…y‘†t‰rqzscrj]pxertˆ|yctqgjzusmzyvye„|€ywqddcm{|jjTgaeSJkfOGQjEaxfaMSr]JNUYelx{f_nqjd]VaUnnVJSgWe]XMUkTI[x^[_k]]Zbe_yhlaoovnpxuz˜~wy€€‡†zyzƒ~“ƒqttzwt„ˆ‘}|‘kr•€{‚Ÿ…~‡}€~†‚€‰{w„«žz‡‡‚jr€yu€~€tn†n}€sŠ€jomddY_ZYYTbjg[Z_u‚i^ml\aW[[keqt}ii\jvtfsvqkƒz}|xurlyfiwf]drgyw’€bbTeph‚…xxgijaWVYgbŽ§o~w€‹Ž{qri{q}y‘s…~€€†ndvrdgg\ja]oo[h_mue{h^uorkr|~uvbu†Œ{‰ˆ‚ysv€vbqn[rtcqr…|ues€mam{qkj|{vsg‡w{zvqebdmr}ijSg]\TKqaPFV`GcvfaKSoXKMXXhkv{eenqgdZX]XweTJ\bWgWYHWdOGaxZ]_l[^\ac^~ij`otxmpovƒ˜zr€€|‰Œ†}vv†x‡Œ|suu‚y{z‚ŒŽ|~…‰is–zŠœ~~…z{}†‰sq­‹{{†|eq‡ys|zurn…l{~lzcpobe]eVYYVcfk_]\s…hXpnZ^XZ[kzbpwvlaYlrrftuokƒw~xvmnsdhte[gteuv‘y^\Rfgkƒ‚t~bdj\TW]abŽ¤ixsƒ†‘ynq|jzo‰~w‹t‚y}y€idvm`f_^i_]tkYf]oocze\x}loopxytues„“€‡„Š|xps~tcxe\qqbqr|tgse_nwjeh{}uopƒvt}srb_fmn|dhSfWXSMv^PIYWHbtcaISlSJNZWjlr|dmmscaZZ[aw\SKc]WhSVFX_MFiuX^`l[[^ab]„ihanxympkv€ym‚~€“ˆ„vt‰tŒ†tqvu‚x}}~Œ~”~pw•ƒ}™’y€€xz}tˆ„tp™ zz~‡”wct‡xrwtkto~kx|p‘s^po`gblTZZWhcmf\\q‰eSqn[ZXW_kvdiuji^Ylrokssrh„|~{vnmkdipc[krdtvŽsZVTear€r‚]bc]SY`[cŸeqq…„’ull{opr}~s‚xt{zzdeug]bY`g[^vhWb]piaxa\|vjkroxtsuiq‚–„‡€…wtkr~ogxX]lncrs€ztgp~\`qscaks€mnvsrxkpa\ellz`fReTWQOuZPOXQHcsa`FUjQJQZVkkk}fnorb[ZXYlqWRPfVVhSTEY[NHqtX_clbX```]‹jcdmzxlpiuy‡{kƒ}€„š|ƒ„y|ˆn‡rnvz}t‚‚|‹‚ƒ˜tx“…ž‰u€‚t‚qˆƒvp¡–sy…Š†zdvŠnnznfxpykrvsk^tnagekR][UgalkZ\qŒdOom\VWTfishbted\Xmtloutxj…|{‡vscdkn`\mmcsx‡kYTVcdx}}q†]d_cTZ_Xb••cmpƒ…Štki|pguyv~m{uvp{u_fsc[]VacXateU_`mdaq]]~phitqtquwkm…”‚‰}‡rshpqtpT\gkfqt€vscmwVcsl\`phgnx~sssjmaZdijw^eScTUPSlVPVSPGdr_`EWiOIXTWnie}ilxlbW]U[tdSRWhQXfTSGYYOMwuZ_ekiYa`]^Žnbfkyvnoiuv€lƒ€}‡˜{€‡€‰k“ˆrft€{u€ƒ}‰Œ“r|Š‘„‡Ÿ†{†t†s~‚vn¤‹r€ŒŠvvly‹`d{pfysxlmrwƒgd{lbfghS_^Ug_ko[^nhMil`UVSnfskexed\Xoskqzwrk‡zvœzykaelm^`njeqx~gYVX`lx|{p„_c^gVX_Wc›ˆbkp‡}xllzn]xsn}kvtop|sXjn_Y\UabWdpbS_bibblZa~lfltvomwwli†€Š|‰nrgq~ntnd[aiiot€tr_imSereVdpd|esx}wkpmk`Yafgt\dU`URNWdQN[NOHdo\bFYiMJ_KYmd`yin~e`U_T]u\SR`fN\`URI[XPYtu]_ekhXb`Z^qcgjxqsnhvs{ƒr‚ƒzˆŽ~|‰‡yn‰tkstˆ…‡’„–y}Œ‡‘›„€|…s€stxso““““““““““’’’’’’’’’’’’“““’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚€~zz}~~}}~~~~~~~~~~€€€€€€€€ƒ‡ŒŽŽŽŽ’’’““’’’’’’’’’’‘‘‘‘’’’’’’’’’’’’’’’’’‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‚}z{|~~}}~}~~~~~~~~~€€€€€€€€€ƒ†ŒŽŒŒŒŒŒŒ’‘‘‘‘‘‘‘’’’’’’’‘’’’’’“’’’’‘‘‘‘‘’’’‘‘‘‘ŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽ‚|z||}~}}~}}}~}~~~~~~€€€€€€€€ƒ†‹ŽŽŒŒŒŒŒŒŒŒ’‘’’’’’‘‘’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽŽŽŒŒŒŒŒŒŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŽŽŒŒŒŽŽŽŽƒ|z|{}~|}~}|}~~}~~~~~€€€€€€€ƒ†‹ŒŒŒŒŒŒŒŒŒŒ”ÎÚØØØØښ„„„„ˆ]-0000-F¡¡¡¡¡¡ š™šššššŠƒ„„„ƒ„wegfffc€¾»»»»½³mfgggge¡    £€cggggfo„ƒƒƒƒƒƒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŽ…}}{{z}~||~}}}~}}~~~~~€€€€€€€‚…ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒ”Ûéççççêœ~‚‚‚‚†S7¤¤¤¤¤¤£œœœœœœœ‰‚‚‚r]____[~ÈÄÄÄÄÆ»g^____]¥£¤¤¤§|\____^j‚€Š‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ†|}z{z|}{|~}}}~}}~~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹’—˜˜˜˜™™’Œ‡‡‡‡‡‡‰““’’’’’‘‘‘‘‘‘‘ŽŽŽ‹‰‰‰‰‰‰Œ’‘‘‘‘‘‰ˆ‰‰‰‰‰Ž‹ˆˆˆˆˆˆ‰ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹ŒŒ‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽˆ|yzz{|{}}}}|}}}}~~~€€€€‚…ŠŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‘‹Ž‘‘‰‡ŽŠ’“ˆŒŽˆ‘‘‘‘ŽŽŽŽŽŽŽŽŒ‹‹‹‹‹‹‹ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‰~}xxy|}|}}}||}}~}~~~€€€€€‚‚„ŠŒŒŒŒŒŒŒŒ‹‹‹‹‹Š‹‘‘‘„Ž†Š…‘Š‡Ž‹‡‡ŠŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~|wvx{}|{}}||}}~~~~~€€€€€€‚„ŠŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠ…ŽˆŽ††‰‘Š„Œ‹††ŒŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠ‹ŠŠ‹ŠŠ‹‹ŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹~{wvx{|||}}}}}}~~~~€€€€€„‰ŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠ…ƒŒŽŽ‰Œ‰‡†Œ‰‰ŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ}|vvx||{|}}|}}~~~~~~~€€€€€„‰‹Œ‹‹‹‹‹ŠŠŠ‰‰‰‰‰Œ†Œ‰Ž‡…‰Ž‹Œ‹…‡‡†ˆ†‰ŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹ŒŒŒŒŒŒ‹‹ŒŒŒŠ~wxz{zz||||}}~~~~~~~€€€€€€€€€„ŠŒ‹‹‹ŠŠŠŠŠ‰‰‰‰‰‰ŒŽ‹ŒŠŒŽŒ‰Š‹Œ‰ŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹Œˆ€}xyzzz{}|{{}~~~~~~~€€€€€€€„Š‹‹ŠŠŠŠŠ‰‰‰‰‰‰ˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒ‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹ŠŠŠ‹‹‹‡€|xzzy{||{||}~~~~~~€€€€€„‰‹ŠŠŠŠ‰‰‰‰‰‰‰ˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‡€{yyxz||z{{}}~~~~~~€€€„ˆ‹Š‰‰‰‰‰‰‰‰ˆˆˆˆˆŽŽŽŽŽŽŽŒŒ’ŽŽŽŽŽŽŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠ‰‰‰ŠŠŠŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹†{xyxz|z{{|}}~~~~~~~~€€€€€„ˆŠ‰‰‰‰‰‰‰ˆˆˆˆ‡‡‡ŽŽŽŽŽŽŽŽŽŒ“ŽŽŽŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒ‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠ‰‰ŠŠŠŠŠŠ…€zxyy|{zz{||}~~}~~}~€€€€€„ˆŠ‰‰‰ˆˆˆˆˆˆ‡‡‡‡‡ŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠ‰‰‰‰‰‰‰ŠŠ…yzyx{{z{||{~~~}~~~~~€€€€€‚„‡Š‰‰ˆˆˆˆ‡‡‡‡‡‡‡‡ŽŽŽ‹•‰ŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰„~y{yz{{y{}|{~~~}~}~~~~€€€€€€€€„‡‰ˆˆˆ‡‡‡‡‡‡‡‡†††ŒŒŒ‰ŠˆŒ‘ŒŒŒŒŒŒŒŒ‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠ‰Š‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ƒ~y{z|{z{}}{|~~~~}~~~€€€€€€ƒ†ˆˆ‡‡‡‡‡††††††††ŒŒŒŒŒ‹‰ŒŠˆ‡‰†ŒŽŒŒ‘ŽŒŒŒ‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆ‰‰‚x{{{zz|}||}~~}}~€€€€€€€€ƒ†ˆ‡‡‡††††††††††…ŒŒŒŒ‹ŒŽŽŒŠŠ‡„ˆ‹ŠŒ‹Ž‹‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠ‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‚xz{zzz{||}}~~~}}~~€€€€€€€€ƒ…ˆ‡‡†††††††……………ŒŒŒŒ’Œˆ‹‰‰‹‹‹‹‰‹ŒŠŒ‹‹‹‹‹‹ŠŠ‹‹ŠŠŠ‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰Š‰ŠŠ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡|x{|yzz|||}}~~}}~~€€€€€€‚„‡‡††††………………………ŒŒ‘‘‰Œ†‰Œ‹ˆˆ‰Œ‰‡ŽŠŠŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‰ŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡…€zy}{{{z||||}~~}}~~€€€€€‚„‡†††………………………„„‹‹ŽŽŒ‹ˆ‡‰‰Œ……ŽŠ‰Œ‹ŽŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡††‡‡‡‡„~yy}zzz{}{|}~~~~}}}~€€‚„†…†……………………„„„„‹‹ŒŽŒŒ‹‡‰ˆŠ‰†‚ˆŽˆŠ‹‘“‹‰‰‰‰‰‰‰‰‰‰‰‰ˆ‰‰‰‰‰‰‰‰‰‰‰ŠŠŠŠ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆ‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡†††‡††††††††‡‡ƒ}zy{zyz||{}~~~~~}~~~~€€€€~€‚„†………………„„„„„„„„ŠŠŽ‰ˆˆŠŠ‡ˆ‡Š‰ˆŠˆˆ‡Š†‹‘Š‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆ‡‡ˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††‡‚|yyzyz{{{{}~~~~~~~}€€€€~€€€‚„†………„„„„„„„„„„„Š‹‰‰‰‹Š‡‡…‡‰‹Š‰„‹‰ŽŠ‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††{xzzx{|{{|~~~~~~}}€€€€‚„†……„„„„„„„„„„„„ˆ‰‹ˆ†‡ˆ‰‹‹Œ‹‰ŠŠŠŽŽˆ‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††………………††€{xyyxxzz|}}~~~~~}~€€€€€€€‚ƒ†ˆ†ˆ†ƒ„„„„ƒƒƒƒƒ’’ŽŠ‡Š‹Š‹‡‹‰Š‰‹ˆ‡Š‹ˆŠ’Šˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡†††††††††††††††††††††………………††zyxxxyyy|}~~~~~}~~€€€€€€‚ƒ‡ŽŽˆ‡„……††………’ŽŠ‰‰ˆˆ‰ŠŠˆˆ‡†ŠŒˆ‡‰‰Ž‘‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††‡‡‡‡†††††††††††††††††††††…………………………†yxwwwyzy{|}~~~~~~~~~~€€€€€€€ƒ‡ŽŽŽŽŽŽŒŽŽŒŽ‰‡†ˆ‰‰‡ˆŠ‹ˆ‰Œ‰‰†ŠŽ‘‹ˆˆˆˆˆ‡‡‡‡ˆˆˆˆˆˆ‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††††††……………………………†~ywywwzyy|{}~~~~~~~~~~~€~€„ˆŽŽŽŽŽŽŽŽŽŽŽŽ‘Ž‹‰Œˆˆ‰†‡‰†ˆŠˆ‡‹Œ‹Žˆ‡ˆ‰‰‰ˆ‡‡‡ˆˆ‰‰ˆ‡‡‡‡ˆˆ‰ˆˆˆˆˆ‡ˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡††††††††††††††††††††††††……††……†…†…†…„„„……††…„………~ywyvxyx{|{~~~~~~~~~~~~~~~€ƒ†ŽŽŽŽŽŽŽ‹ŽŠ†ˆŠ„„‹‰‡ƒ…„ƒ‹‰‹‰ŒŽŒ‹ŽŒŽŽŒŒŒŠ‰ˆ‡ˆ‰‡‡†‡‡‡‡‡†††††††††††††††††††††††††††‡‡‰ŠŠˆ‡‰‹ŒŽ‹ˆ‰‹‹ŽŒ‰ˆ‰Œ€ywwvzyx{{{}~~~~~~~~~~~~~~€€€ƒ†ŒŽŒŽŠ‰‹ŒŒ‡…‰‹‡†ˆ‡†‡‡‹ŽŽŽŽŽŽŽŽŽŒ‹‹‰‡‡‡‡†ˆ††††††††††‡‹‰‡‡ˆˆ‹Œ‹Œ‹ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ€xvxxzxz|z|~~~~~~~~~~~~~}~€€ƒ†ŒŒŒŒŒ’“““’’ŒŒŒŠ‡ŠŒŠ‡‡‰‰…‚Š‹ˆ‰…‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒ‹‰†‡‡‡‡‰Š‹ŽŒŽŽŽŽŒŒŽŒŒŒ‹‹}wuwyzz{{z~~~~~~~~~~~~~}~€€€€ƒ…’‘‘’““““““’’‹‹‹‹Š‰ŒŠ‹‹‰‹Š†‡ŽˆˆŒŽŽŒ‹ŒŒŒŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹ŒŒ‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹ŒŽ’““’’”‘“••”““ŽŽŽŽ{vvwxzz{{{}~~~~~~~~~~~~~~€€€‚„’’“’“’’““‘’’’Š‰ŠŒ‰‹Š‰Œ‹ŠŠˆ‡‰ŠŠ‹‰ŠŒŽ’””“””““’‘’ŽŽ’Ž‘‘ŽŒ‹ŠŠŠ‹‹ŠŠ‹ŽŒŒŒŠŠŠŠŠŠŠŠŠ‹ŠŠŠŠ‹Œ‹‹‹ŒŒŒŠŠ‹‹‹Ž‘’“““””“”““”””“““’’’’’“‘zuvvx{{{zz}~~~~~~~~~~~}~~~~~€€‚„‹‘‘‘‘‘’’’‘‘’‘‘‰‰ˆˆŠŒ‰ˆ‰‰‹‰†„‰†ŒŠ‡Œ’’’“““”••–••”““””””“””””••••••””““‘‘’ŽŒ‘•••“’’ŽŠŠ‹ŠŠ‹ŽŽ‘’‘’’’’‘‘’’’““““““““““““’“’’’’’’’’’’xuwyz{{{z{}}}}~~~~}~~~~~€€‚„‹‘’’’‘‘‘‘‘‘ˆˆˆˆ‹‹‰ƒ‡‹‹ŒŒˆ‡‡Œ’”’’““”•–––••”’’““””””•••–—––––•”“””””•”””““•••”“’““““‘’‘‘’““““’’’“’’’’’’’’’’’’’““““””““’’““’’’’‘‘‘‘vrwzz{{{|}~}}}~~~~~~~~~~€€€€‚„Š‘‘‘‘‘‡‡‡‡ˆˆˆ…‹ŠŒŽŽŽ•”““““””•••””•“’’“’“•””•–––––––––”““““““””“’“”••”“’’’’“““““““““’’’’’’’’’‘’’‘‘‘‘‘‘’“”””””“’‘‘‘‘‘‘‘‘‘‘‘‘Œtswzz{{{|}}}~}~~~~~~~~~~~~ƒ„Š‘‘‡ˆŠ‹Œ‹ŽŒŽŽ‘’‘’““’’’’“”””’’“““““’’“”““““••••”••”““““’’““”“’“”””“’’’’’“““’’’’’‘‘’’’’’’’’’’’‘’‘‘‘’’““”””““’‘‘‘‘‘‘‘Šstvz||z{}|}}~}~~~~~}~~~~}€€‚ƒŠ‘‘ŽŽŽŽŽ‘’’’’’‘’’““““’‘’’’‘‘’’““’““’“”““““”“’““““““““’“““’’’’’’’’’’‘‘‘‘’‘‘‘‘‘’’‘‘‘‘’‘‘‘‘‘’’’’’’’’’’’‘‘†suv{||{|}}}~~}~~~€~}~}~~~€ŠŽŽŽˆ‘‘’’’’“““““’’’“’’‘‘‘‘’’“’“’‘‘’’’‘’’’’’’’““’‘‘’“’‘‘’’’’’‘‘‘‘‘‘’‘‘‘‘‘’‘‘‘‘‘‘‘‘’’’’’’’‘‘‘‘rtx|||{||}}~~~~~~€€}~~~~€€ŠŽŽŽŽŽŽŽŽŽŽ†Ž‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ŽŽŽŽxrvy|}|z}|}}~~~~~€€~~€€€ŠŽŽŽŽŽŽŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŒŒŒŠƒ‰ˆssvx}~|y}|}}~~~}~~€€€€€€€€‰ŽŽŽŽŽŽŽŽŽŒŽŽŽŽŽŽˆ‘ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŽŒ‹‹‰‰‰ˆ……„ƒ‚‚„‚ty}zxurkeimolffggpsswy}~yz{|}}~~~~}~~€€€€€€€€€€‰ŒŒŒŒŒŒ‹‹‹ŒŒŒŒŒŒŒ†‘‘ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŠ‰Š‹‹‰‡‚€‡ˆ„{z€~{}||}ysrrrruupmkjjigcda_[\]^XUWXYSKEIJJKLMOOK`ttwy}}xzy{||}~~~}~~~€€€€€€€€€€€€€ƒ„…„…ˆ‹‹ŒŒŒ‹‹‹Œ†‰ŠŠŠŠŠ‡ƒŽ‘Š‹‹‹‹Œ‰‰ŠŠŠŠŠ‹‹‹‡ƒ‹Šˆ‰‰†……„„‡‰‰…‚ƒ{|yz{zspqqqmljglmgefefdcededeeeedddcaa^]\ZXXWTPQRSRSMMJIFDHJGGHGGLNIgsuxy}zxwy||||~~~~~~~€€€€€€€€€€€g^`cacnq}{z{}w||vxz{xxzop{xy{|{xw{xuwttvutvwuqrqnprpghklnomjiihheeddd_`ab``^]YXZZ[]]_`_`___`ba^^^^YY]\][WWVRTRSSNQJHIFDEHLLHFGIKJIMmrtxz{zwwy{z{|~~}~~~~~~€€€€€€€€€€‚gX[ZY\[\c\Z\^`kqmpponnonkinlklojikkijkigfgggihgmgjghehgbcbab``]X[[WXWTVQPTSSMJLKLLNNOTXXWUUTRPPMMPONKLMPQOLLJGIIGHHIHHHGFGHJJHHHIIHIVpsuyz{yvvyzz{|~}}~~~~~€~€€€€€€€€l[XVVVYYZYYXUVhjlnnlkkjhhihdedb\bf__`c_\_]`]^Z^]YY^ba^^ZY_\XWSNMLKKKLIKMNKJKKLJKPLKKFGGIIFGIHIFEHGFFEDEEDDEIIIGHGHFFKMKIIIHGHKMMKLLLUqsvyz{yvwxwz{|~}~~~€€€~~€€€€€‚hRTUVSUWYYYWWW[[ac_^\[XVVYVRTRQQUTSSSPMJMNPROMPQQQQRVVRPQTPPNNOLJMLKLJJKKFIIJLIGJHIIEGGFFEEHIJGFGFFGGHJGGHHJLJJKIIHJKKJHJKJHIKLMOPPKTttuxzzxvvwwz{|~}~~~~~~~€€€€€€€€€‚iPRTWUTVYWXXZ[TTSRPQSQQQONNPPQOLNPONNMLKMNNPMOPPRQPNNOOONOOPQONNONNPNMMKIHHJIIIIGFGGGIJHIHHIHHGHGHHIHILKJIHJJIJJHGJLKJIIHJJKLNMNMOQLUsrswzywvtvxz{}}}~~~~~~~~€€€€€€€€€€€€lOONTYUU][YWWXNMJJIFJOLJJGIJMMKJLMJGIIIJKLFDFJKKKHJLLLOMLLNOOOMNOLNNNPPOLMLNMLLJIHGIHIHHIIKLKKJIKJIJIIIIIGGJIGIIJJNMNLHIJIIJMOOMKORNYpprwxwwtttwz|~}~~~~~~~~~€€€€€€€€€€€oKJMNQNNUWVVRSIECEERDDA>B?D@@>BDA@ADGFEHEBA@@CCDEACEHKOKIIJHGJIJIIKJLPNMLMMLMMMLIHDFFGFFFIJIIKJHLJIJJJIHHJKKHFGIJIKMNNJKOMLKMMOONPOP`porwxvtrsuwz}}}~~~~~~}€€€€€€€€€€€€€€sPPNNPMJKPRPNQCDBAEQE=C=?EH9:;=?=<AF@>:<>><ED=?EA?@A@DEGGGGBDDEFEGGGGJGHJKGCDGJGCDEAACGHGHGHJKJHILKIHJKKMNLMLLJJLKIKMOOPSQOPPNOPRQMPgposvutrqtxy}}}}~~~~€~~€€€€€€€€€€€€‚vTUQQPOLMPPNOOAAA@BA?;><>??<898;;:@:;><;;<<HL==AA?BC=ADDFBFFDGIHC?@@@AABAA?><=>A@@?>?@EGGGIKLNMNMLMMJKMPUSNLNQNNMNLMMNONNMKKNNNMNNLTnpprttsqrvyy}}}~}~~~€~~€€€€€€€€€€€€€‚xQQRTRSQSSQQRO@@=>?<?>@A?=>9;::;88:87:<978;;>=;;:8:@@AB?A?CFDBCC?;>>@CCA?>?A>@@B?@<?B@ACEEEJKPOPOMMNLLLORQPRNLLOMKNOLLLKLKKJKKJMMKK\qqqtsusqtxxz}~}~~~~~~€€€€€€€€€€€€€|RMOQPQRRTRSSN<;<;;<?@AB@=<9<=<979::988::78:9:;;8789;:8<;=@A@=;;><==@BCA?ABA=>==;=?CDB@?ADBEGJJJJJLMLLLMLLNUSKLMTIPJIMJIJKKJIHGJKIJfrqstsurrvyy{}~~~~}~~€€€€€€€€€€€VLNPPNRQPPQQN8=?<<:=>A@A?>>@?>=;<<>?=<=;:<===<<<<;<:;<>=>??A@>?A?@@A@@@=??=<:;==<?@ABBA@BDFFFGFGGHIKLLLKLKJKIJJMLLJLKIHILLJIIHIKGMmpquuuusuxyy|}~~~~~~~€~€€€€€€€€€€‚aKOONNOPOOPPO:<><=;?>>AA?=?BCC@><=?@??=;>=>CE??@=;===<;:=>AA?>@@?A??=<><=;;<=>A@?@>@CCDBDEHEEGHHHGFIJIIIIIHJJJJLKJJIIHHJJKLKIKJJHVpoqssttuyz{{|~~~~~~€€€€€€€€€€€‚mLPQNOPNNOPPO><<=>??@>@@???CED?=;<@>:;::97:<9==@=:<;;<;89;?>=<=;<@==<<>;=<=>A@BA@@?BDCDEFFFCEGHIIHHIKKLMJJIJMMJKJKIHHHHJIJKJJNLII_pprrrtuvz{}}}~~~~~~~~€€€€€€€€€€€€€€€‚vMNNMNNLLNPOL>A<<=?>BC?>AAABA@=<=;>=:::<:8988:;=??<;;<;::;>??=<8:><=>?=;>?@BCBBCCABBABBDBBDBDCFIGFEHIIKMJIJJKLJJIJEDIIFFHHIJJLJFFgpoqqtvvw{||}|~~}}}~~~€~~€€€€€€€€€€€€€€€zNIKKLLLEILNM<?<<=>@@AA;BCBC@???@=??><>@?===?==>CD?;<=>@==>AC@<9;A?>>A=;?B@BCB@CCACA==>@=?AAA@CEE@@CBCGGEDCFEFFGED@AGGFCFDGHJGC>Hlpppqtuvy||}||~}~~~~~~~~€€€€€€€€€€€€€€~QHKMMMKJKLOQ@?>>AA@@AGACDCDA?@@@?=@><=??@@@C@@?@@>=<=@EABBFHC=<@DCAA?>=@A>>>?<>@DGE@>@A?@CFECBBC@BDDBDEAB>ABBAB@@=ABCDCCACEGA?=Vppqpruuwz||||}~}}}}}~}~~~~€€€€€€€€€€€€~RHKMMLKKNNRUDB@CCAAB@BC@@AA@A@>;><?=<:>=?BBD@??Na_J@CEIIIIMMKECFGHEGEEEDDCA?@>>BFJJGDEGFFJNNKJIGGHKLJGGCDDDEDABBC@CDEDDEDEFCBAEeopqqtvux{|z||~}}}}}~~}€~€€€€€€€€€€}RIIJJHJJLORSGFEGHDGHD@><;>@DED?<ACDB?=A?ADEDCWu†‰Š~XGHJLLMOOLHGHGHIIHHGGHHECEEEEFHJJFEGIJMOOMMKJKJMNKIHGHIHGFEFFFDFHGEEHHFHGHFQnnpqrvvy{{{z}}~}}}}}~~}~~€€€€€€€€€€€|PHGHIFGIJMNNJLIIJKLNJFCABCFIHIGHHIGFBDFDDCAUt‡‰‡‡†ˆ‚WILMLMNLJGGGGDGGGGFHFHECDDFEDDHHCCCFJJKLLLLLLIJKJJIIIHJHHGHIHGGHFFFHJIIIIH]ooqrtwwz{{z{~}~~}}}}}~~}€~~€€€€€€€€€€€€€|MGFHFEFGGJKJLMLKMNMOKIHHJKKKKJKMJKHHFFGFEPl„‡†††‡‡‡‡|PKLKHGFFDECC@ACCCCFFEB@>>@AA@BD???DFGDEGIKIIGHIGIIJJIHFJJJJIJIJJJFILLJJKKfopsstvxy{{{||}~}}}}}~~}~€€€€€€€€€€€€€€€}OFFGFGHGEFGGMMMKLKIGCCCDIKKKKKKMLKMLIFJUl†…„„†††‡ˆ†ŠuIIFB??@???<<<>::<AA@><998<<=;>;9;?ABAACCC@ABEDBCFHIHHHLMLGIJMMNMJJKKJLMSloqtsswy{{{|}}~~}}}}}~~~~€~€€€€€€€€€€~QFEFGIIGDCEFNMLJIHE?9:>@EHGIHKLONNQNQ^r…„„……†‡‡ˆˆ‰‰ŒŽfBB=88::9878896479;<:8567789787689;<<>A;999==>;;=ADEHJMLLGIHORQPPNLMMOQ]oprtsuxz{{||~~~~}}~}}~~€€€€€€€€€€€€€€€€QGFGHJHFEFGHLLJIIGCB56:<C@BFHKHLKNTg{„„ƒ‚ƒ„†‰Š‹‹‹Š‰Š‹Œ‰T;8656766645763468:876565677778:7788:;7688989876:<@GFIFIFEFOSRSSROPPRTepqsttwy{|{|}~~~}}}}}€~€€€€€€€€€€€€€€€€~RHHHIKIGIJIJJKDEHDB@5788=:<DBDFFDVx„„‚‚ƒƒ…‰ŠŠ‰‰ŠŠŠŠ‹‰ŠŠH676468874578467799776765::;::<89999877:::8878589;A=>>BA?AKLOQPQOOPQWkqrttuwz{{{}}~~~}}}}~€~~€€€€€€€€€€€€€€~THGIILMKJKKLIH?@A?<:579897:A9<D?P}„ƒƒ„„„†‰ŠŠˆ‡ˆˆˆŠŠŒŠ‰‰z>:88;<=>9:;<89;9:;::9;::>==?;;;=:><:<;<<=;::<8::;:999<?<=ABDIJLKJKLWorsutvx{{{|{}~~}}}}~~€€€€€€€€€€€€~TFEFILNNLJJMB?;;<:89989999:>=??Cv„ƒ„……†ˆ‰ˆ‡†††ˆ‰ˆ‰‹Œ‹‰ŠŠŒl<;>BCEEBAAB>@CA@?=>>@???@?@==?B?AA?A?=AA@??A<><;:;:9;?=:;==AACABCAXpqtttvy{{|}{}~~}}}~~~~~~€€€€€€€€€€~RECAGJNOLIGK:89;9::<<:::<;=>@?=a…ƒ„„……†‰‰ˆ‡†††‡ˆ‰Š‹‹ŠŠŠ‹‰‹^>DGIKJJFGGDFHGEC@@CECCABCB?@DHECEDEEAFEFDFFD@B>=@>=?@>>>?>?>>:;=<`qrttuwzzz}}}~~~~}}}}~~~~~~€€€€€€€€€€€€€€€~PD@=CHOMGFBD979=:<;>=>>;><??C>J~ƒ„…†††ˆ‰ˆˆ‡†††‡‰ŠŠ‹ŒŒŒ‹ŠŠ‡WGLLMKNIIKHIJJIECDFGFDCFGEBHIKGHGFGGEKJLIJKJCFCCDBAACBDCCDDCA=;=@hpsttvwzx{||}}~~~}}}~~~~~}~€€€€€€€€€€€€€€OA>=?DLK@BBA97;>;<:=?>?<?>BAE?h„‚……‡‡ˆˆ‰ˆˆ‡†††ˆˆˆ‰ŠŒŒŒ‹‹ŠŒPMPMKNKJLIIJHKFDGHHIEEIGFELLMIJGGHIJNMOMLNKHFGGEECFFFFDEHHFCA?@Lmptuvxyyy|||}}~~~}}}}~~~~~€€€€€€€€€€€€QA?>?FGG=<@@87<:;<:=?<==?@CBHS~ƒ„„…†‡‡ˆˆˆˆˆˆ‡‡ˆˆˆ‰ŠŒŒŒŒŒ‹ŠqMQOMLLLLIHHFJIDJHGKJIJHHGKLNLLHHIJMPNONMOKIGIJHIDIHHFFGGIFCBACUoquwxy{xyzz||}~~~~}~}~~~~~€€€€€€€€€€€€€TDAABGGB?8?@8:;7<=:<?<==@BCDLm„ƒ„„……†‡ˆˆˆˆˆ‡†ˆˆˆˆˆ‰ŒŒ‹ŒŒŒ‹‹‹‹^RRPMNMKJGFCHJGLJGKOLKKJLMLOPNHIKLOQQPQOOJIJJMKLFGHGFGIFEEB@BB\prwxyzyyy{z{|~~~~~}}}}~~~~€€€€€€€€€€€€€€€~UECEEGGED;?A;=<8?==>@ED>CDCFJu†ƒƒƒ„„†ˆˆˆˆˆˆ‡‡ˆˆˆˆˆŠ‹‹‹ŒŒŒŒ‹‹|WVRRTROLKKEFFKONOWVQPORSRMSTOMSLPSUWRSRPLJMMMLNGGJFFHJDDEEBDCcquyyzzz{z{zz|~}}~}}}}|}~~€€€€€€€€UFFGGGGHF>@B=?=<A?AADTKBHIFILy†ƒ……„…‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰Š‹ŠŠŒŒŒŒŽ‹‹‹gVVkaERQQPK;:QSR`u]UVTVYYRXXRZfPUWZ]RTWQPNRPPQQKKKGHJHEFIIIHIjsvyyzyz{{|z{|}|}~}}}}}}~€€€€€€€€€~~THJIIGFFE??A@EACFDCDKVPJPPNOPy†…‡†…†‡ˆˆˆˆˆˆˆˆˆˆˆˆ‰ˆ”œŒŠŠŒ}aŠ‹‹‡l[dU:XXXSQ>@VUY\d`VYbr^]V]ZVEQYZ\Y_TYgRUVXTTVSOOMKLJIILMKOMTptvxyxwyyz{z{|}|~~}~}}}~}~€€€€€€€€€€~~~~VJJIHGFDDBA?HLIMPKIJOSRQTVUVTu…„…………†‡ˆ‡ˆˆˆˆˆˆˆˆˆˆ‰œ ‰Žg;~Œ‰Š‹znpXZ[ZRSRVVTZZuƒYU}a\X]^WIV^^[[_YHYXY\]XXYWRQMPQMMOSQQURbtsvwwvxxxz{{|}}}~}~}}}~~€€€€€€€€€€€xy}YNKJIIFBD@A:OQQWXPPPQRSRVWWWWl‚ƒ…„…†‡‡‡‡‡ˆˆˆˆˆˆˆˆˆ–šœ—ˆŠn†‰ˆ‡ƒŠ~fYY\YSVTWRQWVc–€QerXZW_hP`fZZX\hbGOZig\[\]]WSNSPPQVVVVYZostwvvtwxx{{|}}}~~~}~}|~€€€€€€€€}r}ot|]SPOMKJEC?@;PPZZZRSQOQRQURUSV^ux€…„„…††††‡‡‡‡ˆˆˆ‡‡ˆ‡ƒ‘Ž‰‰ˆ†…ˆˆ†}€{\PVXTRTRQQLOMKfyZ]TYUV]ZLTZUST^ZYWWWzkXZ\\^SPPOINOWVXZZeqtwvttvxyy{{|}}}~}~}~}}~€€€~~zxwvsu{€€tk~~kry^[VUSROKFCDAM^ƒlVRSOOQOQVQSRRTcdv€ƒ‚ƒ„„„„……„„ƒ††††‡ˆ†~‰‰ˆ‡†ƒ‡‡‡ymqVIKNNKMKHJDFHEC>ScURQQNKRURMOYRNOQSUUMQSRPNLKHCIGRSTY]mrvwuttw{zz{{}{}}}~}}}~}~€}}~~€€~{vsw}~~du}iqt`d]][YUQLHLIal’tPQSMQRPS[RSRQRUUbs{|~€‚}{{€ƒ‚…†‡‚†††„†…†u_]KC>BBCCA?DPCC@C>BHGV@HNMG]iQHFOFEFFHGHBCHGHJGDAAC@NPMRdtuvuttvy|{z{{|}}|{~}}}~~€€€||}€€€}vt{mh|gnqfiedb\XSQPURsWe[OONLQRPUYSUQQTROV`klsvz{xytrnstsyx~~ƒ€ƒƒ‚€‚€‚kLG>>::>@?>>>jPKaEFHIEB?GLMGMQUJBE??==<==?=?ACB?><=B>IMFUouuvstvx{|z|{|}}}}|~}}|~~€zywxwvvx{~€~}{xv|uaxglpjljif`[QQZ\Y^IJOPNKLQRQTVUWQQWVPX[b]agmmlnjh`nrimlqu{z}{xz||xwxdB@@A<:BCAACA[\O{NOONKLMOOPLKLWNIGAA<977599=;;;8989?;AG>\tuuvuvwy|||}||}|~}|}}}}~}xuwz{zwyxuw{|yxuywcqhipmnmmhf^OO^\ZIGOQQOMPQNQRTVXSRYTNYZ[WY\_^_e_]^qwk^`gkwooljomnlfbYGFFHBAFHEEFCLQOaWRXQPSSRU[OOQVPMIDF>996586979:365795<B=ftuwxwzy{}}||{|}}~~{}~}}~~~~{wuy}|zx||||twvwvuwknihqnooojk`UW^ZWMKSTSPQUOLRSTWXSTXQLXYYVXXVXY]WXXhsk]V`tkaa_]d`_^YUPMONLIGJKIHECPOSZWTTNQSYS\eUOSTQNKIHC?A9988978847578599Gnruyyz{{}}}}|{}}}~~z}~|}~}~~}~|ttu{xrqoontxqrsxvuqfdgrnppqnmd]__YWOPWVVSTVOOUVWXYSUTLKSUUUUWPTUWTUR]n^RNY`[VY;DUWS[fJLPRROMMNMMLJEPPUYSTOJNOUSS\VRUSRNMLIHHF??=:787659967665Xqqtxzz{|}}}~||}|~}}y}}|~~~}||}}~}|rvqxxruuqqnppopuvtnjddjppqrpnfedc\^RTZVWTSVTRXWYYYRUOIGOPOOMRJOPOONNOTLMIPPSTU2<XMI@Q=c`QSQPMPPONMLPNTRPRLILKORPQRRTQROLMKLLHCBA=:9876;B4566;eprvxy{||}~|}|}}}}|{x|z{}}~|{y}|}|{puowuputosvpqqpuuvcjgeWhtrrqniihpVVTUXUVURWVUZYXWVQSFFAFGGHFJDHJHGEHLHKIGLMPMG/E_R>4@>joaRRQ@GTPOPOQNQOPOLJLLOPNMPQQNQOJLMMKGEECB;==<9=G6676Enquwz{{|}}|z||}~~}{yvxwyy|}zzv}{|zzoqnwrpvqmpspopssstfg`hZWkrsrlmmknbePSTRSUOWVUYYVQQQO@>;=?@BAC?BEDA@GHGHFFHJMLDGCORC8EMS]gSQSAGUOOQPPMMNLJLKLNOOQLONMILKIKKLKGFFED<AA>;@E;<89Trsuy{{{|||{y|zz~~|{uturvvzzxzr|{|yymqoxrqunnqroootssrutkgg^ejmpkoqmimcLONMQSLTUTWWULLKH=987;?A?<=A@B==EHFDFFIGJJ@FAA@FGDIOHQRa\QPROSOOOLMOMKMLMON[VKMQOGIHCIKLLKFFFE?BD>=BG?B?@druw{z{{|{zzw|wy~~{{qstprswtxxsz{yvwlqovqttloqrnnosvrtsrrklenshmnmlmljkILHHOQJQSQTSOKHCE=9879?B?;>A@@>AEJECHGIGIEBB?><BA@GJEMObePMOMVKLNKLMMLLKNNSdMJLRIIIFBJKLMNJGIFBBB@?EFEHDLopvzyyz{z|zwsxtx||yznqqmnorrvrsx|xvvmpmsputlpprooorvurVVnqgly„jmqrnnjhoHJCGLLIMPMPOHKE?B=99::?B?<ABAADEGKFDIIGGHCC?B>?@A=CEDLMQTLJIMTFIIJLIJKIILMOPRPKGCKHCCKJLNONIJIGDCCDIJMLIZsnxyxzz{y|vrpurtyyvxjqokllnttmsv{stxronqovsnporpopstyjN`gsjt|ygosqjqheqHKCFGHGJKIJLDGB<>=:::;AB?=BBCCHEJLJEIIFGHCC;A@B>@?BDDIMOGHJGHKDHIKMHJLHIJLJM]RHIDNGBELKNNPNKMJKFGGJMNRNMcnjwvw{y{z}qmlskptttuhpmjikktpnttyprztorqowsoqptrprutykNVmulq{vinoikthepFJCFEFDEEFEGCC@=<=:;:;AD@?BCEEIFJJLFIIGFFDB:ACC>?CCCEGKMHJNHDHEILNMHILGFFIILNKIHEOICGNMOMPNNOMKIHIOSQRNSggfrosxv{z|lhjoekpmsqgnlhikltmoutwqoxtotsrvspqrtsrtuuvvXVuukotrkovlhmf_pGJCEEDBBAE@DB>?>;;;>;=?CB?ACFGJGJILHGGGFEC?=DEB>ACBCEGHIGMPIEFGKNOKFHIFECDIIHKIGHPKDJNLPNONOPOJJIMRUUROXeaamfproryzgehhcilfqlflmgiklsmpwutpnvrosrsutqssutsuvvvyvutvlkuumrvqlnlerMGEEFBA@AD<BA>A=::=?;>?AB?@BEGJFJGIGFFFDCBAAEFCBBBDEEGGHFLPLHNJJLKIFHEFECCHHHKJGKRNCOONQPOONOPKKKPUWVUTY`_]ianinhrsbeffdhhfnifmmhkkmriqvusqmvnoqrswsrstuvvvvwvwvvtwuksunutsqskksMGGEGAB@DE<AA@C<8:=>:@=@C@@ADFIEHFFHFEEDCEBDIFCGEAEGEFFGEIMKHQMJKHHIEFHHECIIIKMKPSNDRSRQSNPMOPMLNSWVXYWY^[]d`icjigk_defchggkggkmkmlpqgttursnvoqprtxqssuvu‚‘yvvtxuuwxnouorsuqqipzMGGGHBBBEE<@CBD<7:>>;>;@B>??CEGDFDDGECECDFFFJEEIGBGHFGFECFJJGMJLKHJKFIHJHEKKLLNORTOHTUTQTPRMNROMQWZVZYW[^ZXa```^hec`deggjhhjghnllomqpiuuxrrpupppruvpusuvu{~}xvtwvvvwplupmsunossyMHHGIDBCHE=@EBD=8:>>=<<BB=@>ABFCECCGCCDDFGGGIFHKHCIHGIGFDHKIGJHMKJKLHKJMKINLONORUVOLVVTQTRRLOQPOTZZY\ZZ]`_]_c_\bdlc`dghr…hgjfjnnponsqjtuxrsstrnpqvrquruus~yŽ}uuvvvvxriuqkrtlqwquLIJHJFBDGE=AGDD@:<>@?>?CB<@>AAFCEDDGDEDFFHHFHGIKJEJHHKHEFLHHHJGLKLLLIMJMNMOLPPRUVWOKVVUSSRQLORRQV[[]^[]^`_a`bf]d`fh`eijdssfjhglprqossnswwpuvtsmoruorspurvrtvuuuwvuwsgtrkqrkrwpwJJKIKGBEDE<AFDDB;??A@@ADA@B>ACHBEDFGEHDFEIHFIHJMHHJJILJEJKHIJJGKJLLIIMKMNNOLOQRUWVMNTVUSRQPMNTSRW[^^_]^``aab`ddebdibdijgv‹lkigmosqpqpprywruutsmmssmqrotuuspswtuuwvuuufqskpqjrvpwJLLKLGCCAE<@EEDC=AACBBCEACDAAEGCGGHFEIECGIGGJFILHIJMKMLFKIHKKNQKRPLRLJMMNPPPUOWXX[NSQW\ZSVPNTUTTXZ_bb_da^ac_afcabhnhbihhmxvmhinosrpqrrrvtsusssnksqmprotvsqquvuswywutucmtkopjqtqwLMKLLGDA@D>>DEFC?CAEDDFCBEGCBHFBHIIGHJFDKJGHJHIKGJJNKNLILHKLJZfJd[JlRGNM_nUls[qpbwcRPbvuhucavaXnqbdvimzf\lt`lkV`wvijghfglmjmojmosrprrqrsrssrtrnltonpqquurqstvvuuywutt`ktkppkqsryLNJJJFB?@C?<DDFDCCCEEDFBEFGDDJEEIKKIKLGGNJHJKGKJIJJNLMMLLIMML[sbdo]llULNer]geqlntgpi_aYnmbppbkjjgoqtetno\pvgpOLryvkaakeelxmkvlnosrprqpqrqrrrtrmmsnnoprutqsstuuutwyvttbmukpplrrr{KLIHGED?AA?=BEFBECEDEEDBHHGDDKHGKMMJLLFJNHJKJIKJJIJMMNMMMKNMM[rponppkjLOPmXNibtrpamov\YlP[mmZqmkplxxtsip]`slqkUuyxoc^kfbgppjioppsspqpqqrrqqrrtlmrmmnorutqtrtuutuuzvutenukpolsrryJKGGEEDBAB=??EGBGDHEEDBFIHHEGKJGMLNJLMGLNIMKHIMIJIJJNONNMLNML\hdu]lqVkMOQnUZk^klvaldtTecNlYl\toljlxjwuho]`skhWbcw|oc`ghacityknnqsspqpqprqppprukmqmmmoqstrsrtvvswvzvuthoulsomsrtvIMFIEEDCAB<B@BFCGFKGECCHJHHFILKFMKKRRLHMMINJIGMGJJHINOMNLJMMJZtppoqqljOQRnYskgooqqomt^nXat_nopoqsoousttj[^tcwxrjnzhaacfabjmtupstvsqppqort{~}wlkqnlmnprsqttsuutxxyytukoumupnssvtIKHJCDDE@@=CCAFCHIMHFCFJLIGFJMLFOJJWRKGKJJNIHIKIKJIIKLMMLIKKJSkbYi^^ibrrZ_Yjo_eeUk_c[aaQ`mh\j\nijd[oedp\Z\k[mqcpsldgcdg``kmppotyruqopqny…ˆ‡‡†…€vsnkmmonqrttrtuuvyxxsunqunwqrutwrHHFJDECFA@AEDCFBHJLGFCFKLIEFJOLIOJL[QJFHHKMIHJIKKIHIGKKKKGHJIKKLJIJLMS[]TPUMQONOOVQOPQNOQJJNPQdqiTYV[[\UY[]X]\\cfaafbcf_^fkmhmtxrtroppt†‡†††……†‡ƒzpmmlkqsttrtvtuyyxuvqruovrtsuusHCEGFF@EC?CGDFGCIKLGFDGJLHDGIPKLOKLWMIFEGIJHIJHLJIGHHJHHHEEKHHJNKHO\V]O]\`^OXYS\\b^MYZMXaRKYaZS`d\aX[ddVVX\YZX\VY\^c_d`a_ehkgmttqqtpqr†††…†………†††„}rkiorssstwyyxyxwxtqxrxsqrurtPBCDLMACCBDIEGGFKJKGEEJJJFEHHPJLMJMRIHEAHFJIKKILJIGFJHEFGEEJFBILIJT_Y_X`a[`UXZT]^Z_RY\P^\YN_\^S[^d^Z]`c_Y_b[`^[UYYZ_^ccbaceiekrpoppnow††……†‚{€……††…†…uqprrsuyzzyyxxxwryvxrqxvtvaSJJMIDCACFGEGGIJJIIDFKKKEFIINJNLHLNGHF>HGLIKKJKKIGEIFDDEBFJD?IKHNZbY^^a_RTSW__\]Y^QY\MV_WKQY[Q[_ba]^ca`babcceZRZWW]Z]d`__cebhommllllu…„ƒyu|„………††……††ƒ}wrrtwyyyy~}yuyvvrnzwvxYQJFCGEBDHHFGHIFGJGHFHKIKDDJJMMLLHJJHIG@GFNJKKMKKKIGIEE@DAHIA>HIFO]`Z[d]_TQRX]\\\_[KW\LR\YIM^QQ]_bccccb\dbadcfXRWUT\X[a_^_aa_dlkmjklnv~uz|„………………††††……††‚zrsuu{…‡‡‡†…„~xpzwvx\RMB@IFCEKIFGGIGGJFFFILJNECJJLNJLIKKIIGCHHQMKKOMKKIHHFE@EBHHA@FECS]Y^X_X_[]UXXP]\QKJV^X^[]VZaRR__bb``bb_cbaddaXPRRS\S\]]^^___diglknnp{{|~{€‚ƒ„………………„„…ƒ„…‡‡srw…‡‡‡‡‡‡‡‡‡‡…ƒ€|x\SKBAGFDGMRHDRKFHHHDFKIMPEGIJKNLLJLLJIGDHKQOMLPMMKLIJDEAECHFAAFCAUUE\T^SV`XNTUMYZLJKT`a[_X_^b]OYb\``^bca]baW`_UQPQRYS^\[]]^`bffflfoow|{€{}€„„„„„………ƒƒ…‚ƒ‚……†zo†††‡‡ˆ‡†††……„…ƒ~INFDFFGDIScQEW_IGGHDFMJPPFIIJKNLLKMLJJGEJNQQNNPMNLNILBEACCFCB@CD?LGCLLOOOMFMFFHIGFLKMOPILOPPSPLQTSUYXWYWWcVNRTPQPOQVT\YY[]\aaefdhdlmqsszy{z„„„„„„„„‚„€~{ƒ}{…„††‡‡‡………„„„‚€}KIEEGFGDKN^MHHYMGHJHGMLQQIKJKKNMUNOKKLGGKPSSNPPNOOOILFaED^LDfbCLZG^\smOLVnYKCO_TkVgI]WU^DLQULMSVQSTXVTXTT\TOeZhheZUkTXWU[\[``abbcagignlhrz}}~ƒ„„„ƒƒƒ}}zr{z{‚€ƒ„„……„…ƒƒ~z{LIEFFHEELPTJKG`THJOJIOMRQKMKLORUROPJLNGIMQ[YOPPNPQPJKQQI|YYrsWPmGqnoaVQqqtOBjsnqspSo_[nX]V\XUkhU]VcY`YZ^UUWituu`av_Yb\\f[_aaab_acgmom`pwtx‚ƒƒ‚}~€vxzmv~tx}€|~€‚„|€ƒz~wwNIEHMMBDLLGJLFRVLKOHLRXWQNOOMQTNOQPLLOHNPS[ZTQROPPQLIZx]TxdhXRSPvftlpbnfkRrNLwmjrpsrqrpoo€]ezuxqqzq~r}ku}aRh|esspss|}p~xor```bb[bahlnkblfgmw~€ƒ~{xw€tvziq~nt|~wx{~€ƒx|u|||ssNKF`]GADMMHKKHKPOMNJNV^YULQSNYYLSSSNLPIRRTYWWQTPPPRLHgxlcxqmZJKTypumubnvPddHevqmwo€jfxxiWrQhzmijzz}lxzphnXuujvuqash}ilx|o___cb\_degjjegbcdllppstsssyqrxbmtgry{ssuy~svzn|}yxrnMJRtNCBEPQHKLJLQOOOMPY`ZXKTWPa^RVQYSMPJSTVXWWPUPONRJLrouuquqch`VnKqp^GhyWvTKhx}w`y{sm`]modSgrunmypwkustqlm\s~zkmy|lun|kqwux^__b_^`edighfe^bbiiijknokqnmjpacfdowxompsynqpj{ztromKKZVHGEGRQJMNLLQQPPPQW\YUNVYUfXRRY^TMNJTTWWYWOSOONQIRmHiwK`dvvTVlNnl{rajguTKVkg|lmlw^Zpz{_`zscroxqgc|ir{]TKl_vuljv|{nyl|p]^^b[_ceegfeec[ccikkrsrwgmihdg`alagsrkglmr|kmhk{tmmkmOGJKHJHHRQMOPLLSSROSRXRWTPWZVVTTTa`QONKTSSQVVOOMNOQKHQNPULKKRSRQROVUQQORRXXPMOUTWXXZZTQRW[WWW[ORTWWXQ]XV\UTOXRWXXYZ`\hs_\[Y\]_cZ_ddegddcbZdbgffmnmuffgc`f^]g`dlgegkhpzhggkujhhilPIKKLMKJTRNRQPLVUTPTUXUZVR[]VUTWUYXOOLNWTPNUSNPNLQPKIQQKQMJJOQTQPQSRJHMOPQQPPPSURXW\WRRPQUUVSZQNRRWTSXUSXTSQUTUVYYX^Z_a]\[Z\\`c\^bcdgeeecZ`adabhhjncad^_c]Zc\bma^ffgmsdihkkedcfhQJKKNOLMTQOTQRMXWUTVXWWZVS\`VWVYUXTQPKOXSPNUPMQOLSPMOUSNQNMNQSPTPQTTNKMORTTQQQUVSXZ[YRURTXWVY\SOSTWTSYTVXTRQWVVX\Z\`]VY_]^]\]aa^[bcchgfdcX``b^`hegea^_]]^ZZ_Z_g`^^]chkahfhfd`bdbPKMLPQLPUPPTQOQZYXWY[ZXYV]jdVXYZWVSTOKOVTPOTPPQOMRQORXTQQOMORTMWQSTUOMNQTVURRRTWUZ]\ZVVQRWXU[[VPSUUTUXSWXTRQXVV[_[_`_V_]^`]\`___ZccehheebYb`b^_fdc`b]\\\\YZ[X[b\^]]_b__bddbd__`\PMNNRQMRSPSTQOV\ZZW[[\YZ[dqmhd_[YVVXRMMWSMMRORROLPSRU[UTPPLOWUPVRSRXMOPRUXUTTRTXX[^]\[VROUWU[ZVQSVTUWUSXZSRQZWW]_[```Vb\`a]`b_\`]cachiegaZc`a__ee_`c[Z\[\ZZYYW\Z\Z`^`[^^a`_c\Y`ZQNONVQPUSPUUSPW\\\Y^\_W\^jpwy€c\[VVYRNPWSNQQPRTRLRTTY[WUORNRWURRTQRYOQSTV[VVVSVZX]^\\^VSNTVV[[UQTUUWXRSY[SRR\XZ^_]ba`Wb[cb^ac^\bab_dgieg^\d`a`acd_b_ZZ^[\[XXYWWZZZa]][]\\Z]`W[[ZPOOOYPUUSRXRTP[]^]\`\`U\\hjr}slh\UYWQOS[SRQSRUUUKRWVZZZSOSQUUTRNVQRZRTUTX]WXXSW\X^]YZ]UUNVVW^ZWQTUWXXSVY[TRV]Y]^a^cc_Y`[eb_dd^^cca^efieg_^daaabcd_b^X[_[\[XXXXW[Z[`][[\[XZ[^V^Y]POOR[PZUVWVTTT^^`_^b\`U]^bkyum~l[UZVQQT\TTTUTVYWLRZV\[\RPUSWUUROWQSWSWUV[^X[YUZ^X_^Y\YRWRYYY_YYRTUYYYUWY[UTZ]]^ab`ed]^]]eabfd^^dc`\gehfeb`ea_aabb_`^WY^Z\\ZYYWV]Z]^[Z[\[WY\]VXW]SOPWYQ]UWYWWUX_`aa`c]`U]^beev‚{iYYZTVTV\XWWVWW]XOU\Y^]]TSXRVUSQSWQSVTXXX^^X][V]_X__X\VQXTZZZaX[TVWZYZWXYYWV]_`_dcbfe^b\`fbdfd_`dba[fchfdfaf__abaa`_^VU]Y[\[Y\YY][[[XXY[ZZZ]_]TY]UNTZVT\UWWYWV\`abcac__V[`da_zupiZ\ZVXVX[ZY[YXY`VOU][`a\TUYPTVTRUUQSUW[[\__Z_\V__Y]^Y]VRXWZY\aY]UVZ[Z[ZZXZXY__``dcdeecdZbfcgfe^ab`c]bciedg`h^bbcaa`^_YT[ZZ[[X\XX\[Z[WWZXX\[\`]V]]SOVZVVZVYVXWX^`badada^YYadb`kfh_]][WXYZ\\\_[Z[bVSW^]ac\SVYPVUUUUUSUTX]]_``]a]Wa^[^\[^XUXW[Z__Z^WX\\\]][Z\WZ_a^`ddeffgcYcfehgd^c`_ec]fidei`g^cbcaa`__\XYZYZYXZXW[[Z[WXZTZ]\[`\U^bMRWZWWZY[\XWY^`baeada]^Yacb_a`a_\]]XX\[]]__\Z]cXYX]`cd_RXYPWUWWWVVWV]]^aba_b^Ya]]^Y]]YXUV[[`^\_YY^]^^`\ZZY[_b_cfdfgfhcZefgigc_c^afeZiicficf_bbca``_]]ZW[YYXXZYWZ[ZYWYVU[]]]``bbxKWW\YW]\\]ZW\]_`bdbca]`Xbcb`cac^\]\XX\\_]`_][`d\\XZbecaR\YOXVXYXYWYZ`^abc`ac_\b]_][^]YYTX]\__^_[Z^^`bb[[W[]`bbdfdgffhe]eghifcab[cg`\iichife`bbca_`_]]\Y\YXWXYYW\[ZWVXPXZ]acffrkJYW][Z_]\^\Y][^_bcbaa]b[bdb`cbb]][ZWXjq`\`_]\ac_^YYcedaT_ZQYW[\[[Y[[c`ccc`bda`c^`\^^^YXU[^\\aa_][`abfb^[S\_`cddfegffgf_fghhgdd`[eg^ahhcihfc`bacb___]][Z[YXXXVZV\[ZVVVMXX\gikhuxvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzz{zzz{{{{{{{{{{{{{{{|{{{{{{{{{{|||||||||||||{{{{||||||||||{{{|||||{{{{{{{}‰ˆ†Š‡…‚‚ƒ‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€~|||||||||||||||vvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwwwxxxxyyyzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{z{{{{{{|||||||||||{{{{{{{{{{{|{{{{{{{||||{{{{{{{|‰‰‡‰†…‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€}|||{|||||||||||vvvvvvvvvvvwvwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyyyyyyyyyyz{{zz{zzzzzzzz{||||{|{zzzzz{{|||||||||||{{{{{{{|||{{{{{{{{{|||||{|{{{{‡‰ˆ‰…„ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€‚€~|||||||||||||||vvvvvvvwwvwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxyyyyyyyyyyyzzz{{zzzzzzzzz{}}}}|}|zzzzz{{||||||||||||||||{|||||{{{{{{{||||||{{{{{{†‰‰ˆ……ƒ‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€~||||||||||}}}||upooooppz~}}}}}„Œ‹‹‹‹Žx))***)+=?>>>>>m€~~{¥×ÓÓÓÓÓÏÄÅÅÅÅÅÇÒÔÔÔÓÓØZ%+++*"‹ÛÒÒÒÒÖº}~~}|||||||||||||||||{||||||||||{{{{{„‹‡‡†‡‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€~||||||||}}|||}}upnoooooz€~†“y1333332j‚€€€{­éääääåàÔÔÔÔÔÔÖãåååååëTïååååéÇ}~}}}||||||||||||||||||||||||||||{{{‚‡ˆ‡‡ƒ‚„‚‚‚‚‚‚‚ƒ‚‚‚‚€€€€€€€€€€€€€~|||||||}|||}}}}vuuuuuuuvwwwwwwxyyzzyzwopppppprrrrrrrwzyyzzz~ƒƒƒƒƒƒƒ‚‚ƒƒƒ‚ƒ„„„„„ƒ„wsssssr|…„„„„…‚|}}}}}}}}}}}|||||||||||||||||||||||||||{{€Œ†‰‡‡„ƒ„‚‚‚‚‚‚‚ƒ‚‚‚€€€€€€€€€€~||||||||}}}}}}}vvvvvvywvvz{x{xwvy|zzyy}yyyxxxxyyyyzzyyyyzzzyxxyyyyyyyyyyyyyyyyyyy|}}}}}}{zzzzzz{||||}}}}}}}}}||}}}}||||||||||||||||||||||‹‡‹Šˆ„ƒƒ‚‚‚ƒ‚‚‚ƒ‚‚‚€€€€€€€~}}||||||}}}}}}}wwwvvw}xww}zx}xwvz}zz{y|{xwwwwxxxxxyyyyyzzz{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||}}}}}}}}}}}}}}}}}}}||||||||{{||||||||||~Š‰ŒŒ‰…ƒ„„‚‚ƒ‚‚‚‚‚‚‚€€€€€€€€€€€}}}|||}}}}}}}}}}wwwwwz}x{x||w{xwvz~zy}x|zxxxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||||||||||}}}}|}}}}}}}}}}}}}|||||||{{||||||||||}ŠŠŠ…ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€}|}}}|}}}}}}}}}}wwwww}~ywwx{z{xwwxy}y|z{zwxxxxxxxxxyyyzzzz{{{{{{{{{{{{{{{{{{{{{{{{|||{||||||||||||||}}}}||}||}||||}}}}}|||||||||||||||||||~Š‰Ž‰„„„ƒ‚ƒ‚‚‚‚‚‚‚€‚€€€€€€€||}}}}|}}}}}}~~~wwwwwy|y{x|}y{xzzz|||}{}{xxxxxxxxyyyyzzzz{{{{{{{{{{{{{{{{{{{{|||{{||{|||||||||}||}}}}}}}||||||||}|}}}}}|||||||||||||||||||ˆ‡Š‡…††ƒƒƒƒ‚‚‚‚‚€€‚€€€€€€||}}}}}}}}}}~~~~wwwwwvxxywyzxzxyyy{yzzy{xxxyyxxxxyyyyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}||}||}}}}}|}}}}}||||||||||||}‡ˆŒˆ†‡‡„‚ƒ„„‚‚‚‚‚‚€€€€€€||}}}}}}}}}~~~~~wwwwwwwwwwwxxxxxxxxxxyyxyyyyyyyyyyzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}|||€‡ˆ‹‡‡‰†ƒƒ„ƒƒ‚‚‚‚‚€€€€€{|}}}}}}}}~~~~~~wwwwwwwwxxwxvyyxxxxxyyyyyyyyyyyyyzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||{||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||}}}|}}|†ŠŠ‰‰ˆ„ƒ…„„‚‚‚‚‚€€€€€€||}}}}}~~~~~~~xxwxxxxxvqdj^jmyyyxyyyyyyyyyzzzzzzzzzzz{{{|{|||{{{{{{{{{{{{{{{{{{{{{{{{{{{||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|…‰Š‰Š‡„……„ƒ‚‚‚‚‚€€€€€~|}~~~~~~~~~~~xxxxxxxymdbe__^oxyyyyyyyyyyzzzzzzzzzzz{{{{{{|||||||{{{{{{{{{{{{{{{{{{{{{{{|||||}||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚…ŠŠ‰‰„„†…„ƒƒ‚‚‚‚‚‚€€€€€€€~|}~~~~~~~~~xxxxxxyndegedb^fxyyyyzzzzzzzzzzzzzzz{{{{{{{||||||{||{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‰ˆŠ„…†„ƒƒ„‚‚‚‚€€€€€||~~~~~~~xxxxxywgedefdea_iyzzzzzzzzzzzzzz{{{{{{{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{|{|||||||||}}}}}}}}}}}}}}|}}}}}}}}}}}}}}}}}}}}}}}}}|‚†‹‡‰‡„„†„ƒƒ…‚‚‚€€€€€€~||~€yyyyyykeabeeaee^bxws{zzzzzzzzzzz{{{{{{{{{{{{|{{{{{{{{{{{{{{{{{{{{{{{{{||||||||}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ƒ†‹†ˆ……†„‚ƒ„„‚‚‚‚€€€‚||€€€€yyyyytccedcfcghdfld^s{zzzzzzzzzzzz{{{{{{{|||{{{{{{{{{{{{{{{{{{{{{{{{{{|||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~ƒ†‹††††…ƒƒƒ„ƒ‚‚‚€€€€~||€€€€€€€€yyyzwdacgbbd][e_a]^`ahxzzzzzzzzzzz{{{{{{|||{|{{{{{{{{{{{{{{{{{{{{{|||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~„…‹‡††††„ƒƒƒ‚‚‚‚‚‚€€€~}}€€€€€€€€€€€€yyyoobbbd^cg_]aa`\_db[m|zzzzzzzzzz{{{{|||{{{{{{{{{{{{{{{{{{||{{|{||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~„ˆ‹†„‡††„„ƒƒ‚‚‚‚€€~~}€€€€€€€€€€€€€yzp]bedbd^fgg`Ybbace_\]s{{zzz{{{{{{||||||||{{{{{{{{{{{{{{||||||{|||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}~}}~~~~~~~~~~~~~€…ŒŠ„…††…ƒƒƒ„‚‚‚‚‚€‚€€€€~~€€€€€€€€€€yzlbdgcbgfa``dabedcdc^\bu|{{{{{{{{{||||{{||||{{{{{{{{{{{|||||||||||||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~‡Œ‰…††‡…ƒ„ƒ‚‚‚‚‚ƒ‚€‚‚‚~€€€€€€€€z{tggffddff`^_acehde^bd`t|{{{{{{||||||||||{{|{||{{{{{||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~‚‰Šˆ††ˆ†…ƒ„ƒ‚‚‚‚‚‚€‚‚‚‚€zzmhccgfgegffgbedebg[be`v||{{||||||||||{{||||{|||{{|||||||||||||||||||||||}}|}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„‰Šˆ†‰‡……„„ƒ‚‚‚‚‚‚€€€{ziidcjfa`fecccgidcb`bdbt}||||||{|||||||{||||||||||||||||||||||||||||||||||||}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€„ŠŒˆ‡‰†„……ƒ‚‚‚‚‚€€vsedgcdfebefgdfhfec``cd`q}||||||||||||||||||||||||||||||||||||||||||}||}}|||}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~€€€…ŠŒ‰ˆŠ‰††ƒ‚‚‚‚‚€‚€~~€‚‚‚‚‚‚‚‚‚‚ssgeddeijhfggcaffefgfeecu}|||||||||||||||||||||||||||||||||||||||||||}}}}}}|}}}}}}}~~~~~~~~~~~~~~~~~~~€€€€€€€…‹ŠŠ‰Š‡‡†„‚‚‚‚‚€‚‚€€~ttsu}‚€€~~€trgdecfijiecec`fddggbbeap}||||||||||||||||}}}|||||||||||||||}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~€€€€€€€†‹‹ŠŠ‹‡‡‡„ƒ‚‚‚‚€‚‚€‚€€€~sssstuxuuttuvuupfcfehhighgefeb_defc`bgw||||}}}}}|||||}}}}}}}}}|}}||}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~€€€€€€€€€€€‡ŒŒˆ‹Š‡‡‡ƒ…‚‚‚‚€‚‚‚‚‚‚€€€~ssssssssttttssuoccagehhgjfdegfhfcbeb^by}|{{|}}}}}|||}}}}}}}{|}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€€€€€€‡‹‹‡‰ˆ‰…„…‚‚‚‚€‚‚‚‚‚€€~tsssssssssssssurgeedejhhgfihgceebdchdg{xusstvvyxvtttvwwwvtttuuxwxxwwz{|}}|}~~~~~~~~~~~~~~~~~~~~~€~|{{}~|yyvvvy||zzwvwy{}{x„ŒŒŠŒ‡‡ˆ„…„‚‚‚‚‚‚€€~usssssssssssssushegheklhjgijgggfddbednuttsstsssssssssssssstssssssssssttuusuwxy{~~}~|}x|~~}|xuvwywxvtssstutssssssstsssttstttsƒŒŠ‰‡ˆ†ƒ†ƒ‚€ƒ‚‚€€€€usttssssssrsssvvichjhjlefilh`fedc`ddftuuutttttttttttttttttttttttttttttsttssssstvvuuwux|~}~|zxustuuutssssssstttttttttuutttuuttuutuuuut†Œ‹ˆ†‡„„…‚‚‚€€‚‚‚€€€€vsssssssssssssvvsggjfhgfhhfdigccgeefpvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuttuttttttttstttvuuwvtsttttttttuuuuutuuuuuuuuttssssttsstttttuutu‰ŽŒŒŠ‡‡„„…‚‚‚‚€€€‚‚‚‚€€€wsssssrrrrsssrvvund]cgeikhehggjjigepvuuuuutttstttttttuuuuuuuttuuttuuuuuuuuuuutttuuuuuuuttuttuuuuuuuuuuuuuuuuuuuttsssssssttssssssttttttuŠŽŒŒ‰††„‡…‚‚‚€‚‚‚€€€xsssssrrrrrsssvvwwibhhgjkihfddefihputtttssrqrrtuutttttttssrqqqqssttttttttttutrrrstttttuuuuuuuttuttttttttttttttssssssssssssssttstttttttu‹ŽŒ‰†………‡„‚‚‚‚€€‚‚‚€€yssssrqrrrrssswwwwljhdhikvzkefehgmrststsrpppqrstuttssrrsrqpoooopqsssrrrrstttsqpqrstttttttsstsssstttttsttttttttstttssrrqqrrsssrsssttttsvŒ‡‡……„„‚‚‚‚‚‚€‚‚‚€yssrrqqrrrrssswwwwssjgiihy}qnulnpqrrrqqpopqqqstsssrqqppnnnmnmnnnpqrrrrrrrrsqpoopqrrssrqrrrrrrrrrrrssrsssssssssssrqoonnooqrssrrssrrssrv‹‡†………ƒ‚‚‚‚‚‚‚‚‚‚‚xqpppqqrrrrssswwvvwvrqtsnv~vsxppprrrrqqppqqqqrssssqpqpoonnnnnonoppqqqqqppqrponopqqqqqppqqqqqrrrrrrrrrqqrqqrrrrqpoonnmnmnoqrrrrrrrrsrqxŽ†ƒƒ†„‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€wopopqrrrssssrvvvvvvwvvusy~wwwopqqqqqqpppqrqrrssrrqppoopoooooooopopooooppqooopppppopoppqrqqqrrrrqqqqqqqqpppppqoonnnmmnmnopqqqqqqqqqqp{†ƒƒ…ƒ‚‚‚‚‚‚‚‚‚‚ƒ‚ƒ‚€vnopppqqqqqpppvvvvvuttssq}€}}sopqqqppppqqpppqrrqqqpopooppooppooooooooopqqpnoppoopooprrrrqqqpqrqpqqqpppppppppoonnmnnnnnonopppqqqqqqqqp‚‘ŽŠ„„ƒ…„ƒ‚‚‚‚‚‚‚‚‚‚‚‚€€uooopqqqqpppppvvvutsrrrrq€‚€yppppoppppqqqqpqqqqqqpooppppppopqppooopoooqqppoppooonopqqpppopooppppppppppooooooonnmmmnnnnonoopoppppppppp‰Œˆ„ƒ„†ƒƒ‚‚‚‚‚‚€€‚‚€€€tnoopqqqppoopovvusrqqqqqp€ƒƒrppppppppppqqppqqqqqpppppppppqpppppppppoppqqpppqqooonopppooooppooppppppppppoooonnnnnnmnnnmnnoppoooooopsquŒ‰ƒ‚…‡ƒƒ‚‚‚‚‚‚‚€‚€€€€€tooonooooooooovutsqqqqqrr€‚‚tqqqqqqqqqqqqqqqqqpqqqqpqpqpqqqpppppqqqpqpppqpppppppppppppppqqqpqppppqppqqpqqqqqqrqrqprtrrttttuvtstttuww‚‹ˆƒ‚†‡„„‚ƒ‚‚‚‚‚€€€€€€uoooooooonooooutsrrrrrrrrƒƒƒ‚vqrrqqqrqrrqqrrrqqqqqrqqqrrqqrqqqqqqqqqqqpqqqqqqrssrrrsuutttttttuvwwwwwwxxxxwwxxxwvwvuvvvvwxz{|{{{zzzzz|†‹ˆƒƒˆ‡‡…ƒƒ‚‚‚‚‚‚€€€€€€€wqqqqqpnnpoppovtuussssssuˆƒ‚ƒyrssrrrsrrssrrrrrstrrsrsssssssrssttuuuuutuwxwwwwxxxwxxxyyyyyxxyyyzz{{{{{zzzyyxwwwuvuvvwyzz{~~~}}~~~~~€Œ‹Š‡ƒ…ˆ‹ˆ„ƒ„ƒ‚‚‚‚‚‚‚€€€€€€|zzyy|yxxvuvvtyvwxwwvwvvz|~~|vvwwvuxzxxxxwwwvx|yy|zyy|{yyyxxyyzzyyyxxzzyyxxxxwvwwxxwxxyyz{{z||}~}~}{{{{zyzyy{{~€~~~}}}~~~~~~€ŽŠ‡„†Š‹ˆ††„ƒ‚‚‚‚‚‚‚‚€‚‚‚€€€~}}}}|{{{yxxxxyyyxyxyyyxzzzzzz{{{|}~|{{z{|{}|{{{{{{zyxyxxz{zzzyyz||{zz|||zzz{}}|~~€‚€‚€€€€~~~~}}~€€~~~~€€ƒŽŒ‡†…ˆ‹Œˆ‡†…ƒ‚‚‚‚‚‚‚‚ƒ‚€€€‚ƒ‚‚}zzxxwxxxxyxxyzzy{~|z|}}{|}}}|||~|}~~~~~}}||}ƒ€€}|}|}}{}}|||}}}}~‚„„ƒ‚€€€~~~~€€€€€€€€€„‹‡††ˆŒ‹ˆŠ††ƒ‚‚‚‚‚‚‚ƒ‚€€€€€‚„‚‚€€€€~~€€~}|}}}}€}€~€~€€€€€€€€‚€€~~~~~~€€€€ƒ„‚‚‚‚€€€€€€€€€€€€€€€€‚€€…ŽŽŒˆ†‡‰Œ‹‹Š†…ƒ‚‚‚‚‚ƒ‚‚‚€‚‚€€€€€‚…ƒ‚€€~~€}~~~}}}~~~~~€€€€€€~~€€€~~~~~}~~~~€‚‚ƒƒ‚‚ƒ‚‚ƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚†‘Š‡ˆŠŽ‰†…‚‚‚‚‚‚‚ƒ‚‚‚€€€…„ƒ‚‚‚‚€€€€|||{|}||~~~~~~~~~~~€~~~~~~~~~€€€€‚‚€€‚ƒƒ„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ‚ƒƒƒ‚‚‚‚‚‚ƒƒƒƒƒ‚‚‚‚ƒƒƒ‚‚‡’’‹Š‹‹Š‡„‚‚‚‚‚‚ƒ‚‚€€€€€€€€ƒ„ƒƒƒ„ƒƒƒ‚‚‚|}||}‚}~‚ˆ‚‚„‚ƒƒ‚‚‚€€€€€€€€€€€€€€€€€ƒƒ…„„ƒ„ƒ‚‚‚ƒƒ‚‚ƒ‚‚ƒƒƒƒƒƒ„ƒƒ‚„……ƒƒ„„‚‚ƒ„ƒ‚ƒƒƒƒƒ‚‚ƒƒ‚€Š”“ŠŠŒŽ‹†ƒ‚‚‚‚‚ƒ‚€‚€€€€€€‚ƒƒƒ„„„ƒ‚‚‚‚}||~~€ƒ€ƒƒ‚„†…††…„……ƒƒƒƒƒ‚„„‚‚‚‡ƒ‚‚€‚‚‚‚ƒ‚‚ƒ‚ƒ‚ƒƒ‚€€‚‚ƒ‚‚‚ƒƒ„……„ƒƒ‚„„„„ƒ„„„ƒƒƒ„ƒƒƒƒƒ„ƒ„ƒ„…„„„ƒƒƒƒ‚‚‚‚‚‚‚‚‚‚‚””ŽŽ‘‘ŽŠˆ„‚‚‚‚‚ƒ€€€€€€€€‚‚„‚ƒ„ƒ‚ƒƒƒ‚‚}}}€€€‚ƒƒƒƒ„†„„ƒ„……ƒƒ‚ƒ€‚ƒ‚…………††‡††††‡‡‡†††‡‡††„‚‚ƒ„ƒƒƒƒƒƒƒ„„………ƒ…„…„„„ƒ‚ƒƒ‚ƒ„„ƒ‚‚ƒ„‚ƒƒƒƒƒ‚‚‚‚‚‚‚ƒƒ„„ƒ…………††ˆ“““’‘ŒŠ‡‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€„„„‚‚‚‚‚€ƒ€€€€‚‚‚ƒƒ‚‚ƒƒƒ„ƒƒ‚ƒ…ƒ‚‚„…‡‡‡‡††‡‡‡ˆˆ‡‡‡ˆˆˆ…„ƒ€‚‚‚ƒ‚ƒ„„…„ƒƒƒ„ƒƒ„„ƒ‚ƒƒ„„„ƒƒƒƒƒƒ„„ƒƒ‚„ƒƒƒƒ„……†‡‡‡‡ˆˆˆ‰‰Ž“’’ŽŽ‘‹‰‡‚‚‚‚‚‚‚‚‚‚€€€€€€€€€ƒƒ‚‚‚‚€€………†ƒ‚€~~‚„‚‚ƒ„ƒ‚ƒƒƒƒ‚‚„„ƒ„ƒ‚ƒ„…„„……„ƒ‚„……‚„„……ƒ‚€€€€„ƒƒ„……„‚‚‚‚ƒ‚ƒƒ…„‚ƒ„„„…††††††……†‡‡…†ˆ‡†‡ˆ‡†††ˆˆ‡†…†††‡ˆ‘’’ŽŽ‘Œ‰‡…‚‚‚‚‚ƒ€€€€€‚€€€€€€€„„ƒ‚‚€€‚ˆ‡†‡…„‚€}}~€€€‚€‚‚‚‚‚‚‚‚‚ƒ€€€€€€€~€‚‚ƒƒ„ƒƒ„ƒƒ‚‚‚ƒƒƒ„„ƒ„„„ƒ……†…‡‡ˆ‡‡‡‡‡‡‡‡††††‡………††„…„„…„…†’“‘ŽŽŽŽ‰‰‡„‚‚‚‚‚‚‚€‚‚‚‚‚‚‚‚€€€€€‚„ƒƒ‚ƒ‚‚‚ƒƒˆ‡‡‡‡…„‚~~€€€~~~€‚€‚‚‚€€€€~€‚€‚ƒƒ€€€€€€€€ƒƒ‚ƒƒƒƒ‚ƒ‚‚‚ƒ‚‚‚‚ƒ‚‚„ƒ„„ƒƒ„„…………††††…„„„……„„………„„„„ƒ„„„„„„Š”“’Žˆ†…„ƒ‚‚‚‚‚€‚‚‚‚‚‚€€€€€€€ƒƒ‚‚ƒ‚‚‚‚ƒ‚ˆ‰‰‰ˆ‡…„ƒ‚„„ƒ‚‚ƒ‚‚ƒ„‚ƒ„……„‚„‚€‚‚‚„ƒ‚ƒ‚‚ƒƒ„ƒƒ„„ƒƒ‚ƒ‚ƒƒƒƒƒ‚‚‚‚‚‚ƒ„„„…„…………„…„„…………ƒƒƒ„„„„………„„„„„„ƒƒƒƒƒŽ•’‘‘ŽŒ‡…ƒƒƒ‚‚‚‚‚‚€‚ƒ‚€‚€€€€€€€€€€ƒ…„„„ƒƒƒ„ƒ„ƒ†‡‰ˆ†…ƒ„ƒ„ƒ…ƒƒ‚ƒ……ƒƒƒ„ƒ„ƒƒ…„…„„„€‚ƒ‚‚„ƒƒ‚‚„…„ƒƒƒ‚‚ƒ„„ƒƒƒƒƒ„…„„ƒƒ‚‚‚‚‚„„…„……………ƒƒ…………†…†…„„…„……†………„…„„„ƒ„ƒƒ„‘”“’’ŒŒŠ…„„ƒƒ‚‚ƒ‚‚‚‚‚ƒ‚‚€€€€€€€†††††††‡‡††…„ƒ…†‚€‡‚€~€€‚€€€‚‚‚‚‚‚‚€‚‚‚‚‚‚ƒƒ‚‚ƒ…ƒƒƒ‚ƒƒƒ„‚‚„„ƒ„„…„ƒƒ‚‚‚‚‚ƒƒƒƒ„…………„ƒ„……†……„„„„„ƒ„„……………„ƒƒ„ƒ„ƒ‚†”“’”’‹‡„„„ƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚‚‚€€€€€€€€€…………††††††…†ƒƒƒƒ€‚‚‚‚€~€€€€€€ƒ€€‚„ƒ‚‚ƒ‚ƒƒ‚ƒ‚‚‚‚ƒƒƒ„ƒƒƒƒƒƒ„„‚‚‚‚ƒ‚‚ƒƒƒƒ„…„„„„ƒƒ„„ƒƒƒƒ„„ƒƒƒƒƒƒ„ƒƒƒƒƒ‚ƒƒ‚ƒ‚‹”“’“‘Š†ƒƒƒ„‚‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€ƒ„„……„………„„…‚ƒ‚ƒ‚‚ƒƒƒ€€€€€€€€ƒ‚‚ƒ‚‚ƒƒƒ„‚ƒƒƒ‚€€€‚‚‚ƒ‚‚ƒƒƒƒ‚ƒƒ„‚‚‚ƒƒ‚‚ƒƒ‚‚ƒ‚ƒƒ…„ƒƒƒƒ„ƒƒ„„„„„……„„…„ƒ„„ƒƒ„„„„„„„ƒ„„…„ƒƒ„„„ƒƒ‚‚ƒ”’’’‹Œˆ†„„ƒƒ‚ƒƒƒƒƒƒ‚‚‚‚‚‚‚ƒ‚€‚€€€€€€€€€€„ƒ……„…………„……ƒ„„…ƒƒ„…„‚‚‚ƒ‚‚„‚‚†…ƒ„ƒƒ„„„†…„„…‚}}}~‚„ƒƒƒƒƒ„ƒƒƒ„„„ƒƒ„„„„ƒ„„„ƒ„ƒƒ…†………„……………„…†…††…………………………††…†††…†††‡†…………ƒ„„„‡““’‘’Œ‹ˆ…†……‚‚‚ƒƒƒƒ‚ƒ‚‚ƒƒƒ‚‚‚€€€€€€€€€€€€€……†……†‡‡†………„„……„„„„„ƒ„ƒƒƒ„…ƒ‚ƒ„……†…††…†‡‡†ƒ~~~~~ƒ„ƒƒ„„„„„„„„„„„„………„…„†……†…†††…†……‡……†…††††…„……………„…†††‡†††††‡‡ˆˆˆ†……†„……†”“’‘‹Š‡†‡†„‚‚‚ƒƒƒƒƒ‚ƒ‚‚ƒƒƒ‚€€€€€€€€€€€€€€‡‡‡††‡‡ˆ‡‡††„ƒƒƒ„ƒƒƒƒ„ƒƒƒƒƒ„„ƒƒƒ…………‡‡……‡…~€„…„…†††…………††‡††…†……†‡‡‡ˆ‡‡‡†††‡‡‡†††‡†††…„ƒ„………„……†††‡‡††††‡‡‡‡ˆˆ‡†††‡‡‡‘“’‘‹ˆˆ…†„ƒ‚‚‚ƒƒƒƒƒ‚‚ƒ‚‚‚‚ƒ‚€€€€€€€€€€€€€†‡ˆ‡‡‡‡ˆ‰‰ˆˆƒƒ‚‚ƒƒ„„„…„ƒ‚‚ƒƒ„ƒƒ‚ƒ…„…‡ˆ…ƒ‚€€€€……†‡ˆˆ‡‡‡‡ˆ‡ˆ‡ˆˆˆ††‡ˆˆ‰‰‰ˆ‡†‡‡‡ˆˆ†‡†‡ˆ††…„ƒ„…††………†††‡‡…†‡†‡††‡‡‡‡‡‡‡‡…‡““‘‘‹‡†…†„‚‚‚ƒƒƒƒƒƒ‚‚‚‚‚ƒ‚‚€€€€€€€€€€€€†ˆˆˆˆ‡‡ˆ‰‰‰ˆƒ‚‚ƒƒƒ„…‡‡‡…ƒƒ…„ƒƒƒ‚„„„„…„€‚€€~{z€†ˆˆŠŠ‰‰ˆˆ‰‰‰‰Š‹Šˆˆˆ‰‰‹‹ŠŠˆˆ‡ˆˆˆ‡‡ˆˆ‡ˆ†‡†„ƒƒ…‡‡‡†……„„„……„……†„„„………†…†…ƒ‰”“Ž‘ŽŠ†…†…ƒ‚ƒƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€†‰ˆˆ‰‡ˆˆ‰‰ˆˆ„‚‚ƒƒƒƒ„‰Š‡‡„……„ƒƒ…ƒ…„ƒƒ‚‚‚‚‚‚€~|}}}~|{|ƒ‡‰‹‹ŠŠŠˆˆŠ‰ˆ‰‹Š‰‰ˆ‰ˆŠŠ‰‹‰‡†††‡…†ˆˆ‰ˆ‡††„ƒ‚„ˆˆˆˆ‡…‚‚ƒƒ‚ƒƒ„‚‚‚ƒ‚„ƒ„ƒŽ“’‹ˆ…„†„‚‚ƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€…ˆ‡‡‡†‡ˆˆˆ‡‡„‚ƒƒ‚ƒƒ…‰Š‰‡…‡…„……„ƒ…„ƒ‚‚‚‚‚ƒ~}~~~~~~}}~}}}ƒ‡‰ŠŠ‡‡…†‡‡‡‡ˆ‡‡‰‡ˆ†ˆ‡‡‰ˆ„ƒ„ƒ…„„……†ˆ‡†…ƒ‚‚ƒ…‡†‡††ƒ‚‚ƒ„‚ƒ„„‚ƒƒ„ƒ„‘’‘Ž‹‡„††ƒ‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€…††…†††‡‡ˆ‡†‚„„ƒ‚…†ˆ‹Š†…†„‚††‚€ƒƒƒƒƒƒ‚‚}|}€~~~}|}}|z|„†‡†„ƒƒƒ„………ƒƒ…„„„„„„…„‚‚ƒ‚„„‚ƒƒ…†…„‚‚‚ƒƒ…ƒ„„…„„†ƒƒ„…ƒ‚ƒ‚ƒƒ„…„‡’‘Œ‰†„…„…‚€ƒƒƒƒƒ‚‚‚‚‚‚‚‚€€€€€€€€€€€€ƒ„…„………‡‡‡‡†€…ƒƒ……„‡ˆ…ƒ€€~}‚ƒƒƒƒ‚‚€}}€€}~~}}}}zzz~ƒ„„‚€‚‚~‚ƒ‚‚‚‚ƒƒ€€€ƒ‚€€€€‚‚„ƒƒ…„‚ƒ„ƒ‚‚‚„ƒ……†Œ“‘Ž‹ˆ……ƒ‚„‚ƒƒƒ‚‚‚‚‚‚‚‚‚€€€€€€€€€€‚‚ƒƒ‚„ƒ„……††~€€€€ƒ‚~~~~||ƒƒ‚ƒ‚ƒ}}~€€€~}}}}~}|zzz‚‚€~€~}€€€€€~}}€~€€€€€€‚€€‚‚€‚„ƒ†’ŽŠ‡‡†ƒƒ‚‚ƒƒƒ‚‚‚‚‚‚‚ƒ‚‚€€€€€€€€€€€‚ƒ„‚‚ƒ‚ƒ„…€|}}~}}~€€~}~~{}~‚ƒƒ‚‚}}~€€€~}}}|{{{zzyz€€~~~~|~~€~€€~~~~}|~€~~€€€~€€~€€…’’Ž‹‹‡‰…„ƒ‚‚ƒƒƒƒƒƒ‚‚‚ƒƒ‚€‚€€€€€€€€~„„‚ƒƒ‚ƒƒ€|~~~~€€~€}}„ƒ‚€~}~~€€€~}}}|{{|zzyyy{~~}~€€~€€‚€|~~~~}|€~~€~€€~€~~~~~}||}…’’Œ‹Šˆ‰ˆ„…„‚‚‚‚ƒ‚‚ƒƒ‚ƒƒƒƒƒ€€€€€€€€€~€„ƒ‚ƒ„„ƒ„€€€€‚‚ƒ€~€‚ƒƒ€€}}}~~~~}}}}}|||{zyyyy}€€€€€€‚‚€~€~~~~~€‚€€€€~€€~~€}~}}{|†“‘Œ‹Š‡‡Šˆ††„ƒ‚‚ƒƒƒƒƒ‚ƒƒ‚‚‚€€€€€€€€€€€€~~€€„†‡†‡‚„ƒ…ƒƒƒƒ…„„„„ƒƒƒƒ‚‚‚‚~~}}}~~€}}}}}}}}|{zzyyyy€‚‚‚„ƒ€ƒ€‚€ƒ‚ƒƒ‚€€€ƒ„‚€€€€€€‚‚€€€€€€~~||Š“Š‰ˆˆˆ‰ˆ†††„‚‚‚‚ƒƒƒƒƒ‚ƒƒ‚‚€€€€€€€€€€€€~}~~~ƒ†‡‡ˆ‚†„…ƒ„…„…†††††……†€ƒƒƒ‚‚€}}}}}}~~}}}}}}}}}|{yyyyx|‚ƒ„…‚„ƒ‚‚ƒ…†‚ƒ„ƒ‚‚ƒƒƒ‚‚‚…ƒˆ…‚‚‚„ƒ‚ƒ‚‚‚‚€€€~Ž“Œ‡ˆ†ˆ‡††…††„‚ƒ‚‚‚ƒƒƒƒƒƒƒ‚€€€€€€€€€€~}}}~~~€ƒ„‡ˆ„†††…††‡‡††‡‡‡†‡‡}€€‚~}}}}}}}}}}}}||~~~|{yxwxyy€‚ƒƒ„ƒ„„„——ƒƒ„}~‚‚‚‚ƒ†ˆŒ…ƒ‚‚„‚„ƒ‚ƒ……„…ƒ‚ƒƒ‚ƒƒ‚‚‚‚ƒƒ‚‚’‹ˆˆ‡‰‡††„†…„„„‚‚‚ƒƒƒƒƒƒ‚€€€€€€~€€€€€~}~€‚………††‡‡†‡‡ˆ†‡‡‡†‡‡‡|}|}~}}}}}}}}}}}}}|{ˆ’‚{|z|†yxy|~‰—„ƒƒ„„”“€~~„‹€€€„†‰…„‚‚……‹ƒ‚……††„ƒ……ƒ„„ƒƒ„ƒ…„„ˆ’Ž‹‰ˆˆ‰‡ˆ‡…†…„…„‚‚‚ƒƒƒƒƒƒ‚€€€€€€€€€€€€€€€€€ƒƒ†‡††‡††ˆ‡†††…„„†…||||}}||}}}}}}}}}}||‘•–ƒ{z„”|xyz{|‚ƒ€ƒ‚€~|~~{ˆ‘||Ž–}‚†Š…ƒƒ„‚ƒ‰~ƒ„……ƒ…†…„……ƒ„……†„„Ž‘‹ŠŠŒŠ‰Š‡…†…ƒƒ‚‚‚‚‚ƒ„ƒƒ‚€€€€€€€€€€€€€€~~‚‚‚ƒ„ƒ‚ƒ‚‚…†„„……„†„ƒ„ƒ‚ƒ}}||}}|||}||}|}}}|||{‹‘—Œz{|€zzz{|yy}}~€€|{{~~}‚•‘„ˆ~|~‚„||‚„‚€‡ƒ}‚‚‚€ƒƒ„„„„„‚„ƒ„…‚„‘‘‹ŒŒŽŠ‰‰†……ƒƒ‚‚‚ƒƒ‚‚ƒƒ‚‚€€€€€€€€€€€€~{€€z|€‚ƒ…ƒƒ…………ƒƒƒ„‚ƒƒ‚ƒ‚‚€€€~~~}||||||||||||||}}||~~Š‚{z{zxz{z|}{~}~}}}}||}†~}‚~~€‚||€‚€~}{Š‚}€~€€‚‚€€€€‹“‹‹Žˆ‡ˆ†…„„ƒ‚‚‚‚ƒƒ‚‚ƒƒ€€€€€€€~}|{||}€€|zx{€‚ƒ…„ƒ…„††„„€†”ˆ€‚€~~~€|||||||||||||}|||||||y{{{xxy{{z|€~|~~}€‚‚€€€‚‘€€~€~~~€}|}{}}}|}||}€€€~€~~”‘‹ŒŒŠ†††…„„…ƒƒƒ‚ƒƒƒƒ‚‚€€€€€€€€}{z|€€€x~w{€‚‚‚‚ƒ†‡††~ˆ•Š~€€€~€~~~|{{|||||||||~}|{}|||{|||zzy{|z}…ƒ‚~~€~…‚~€~~€…†‚€~~ƒ‡}|~€€€~}}}}}z|}€}~€Œ‘ŒŽ‡„††…„„ƒƒƒƒ‚ƒƒƒƒ‚€€€€€{z{y€wz}~€‚„††……~€€€~~~€€€€}|||}~}|}}}}}}|~|}|{}||z{z{}}†„‚€€}~}~}‹„†~}||~‚}}}}€|{}|~„ƒ€~~~~}|~}~€~~~„’ŒŒ‹Ž‹Š†„†„„ƒƒƒƒ‚ƒ‚ƒ‚ƒ‚€€}|||}~{{}w~vx~}|}|}~~‚ƒ€{~}|~~€€~€~~€€€€~~~~~~}~~}|~}~}}|{|||z{z}~€ƒƒ‚~|}|}|}ƒ~Œ~|{{}~}~~}{{{}{z{{{€†„‚„ƒ‚€~‚‚‚‚‚€Š‹ŠŠŒ‹Šˆ„„…ƒ„ƒƒƒ‚‚‚‚‚‚‚‚€‚‚‚‚€€€~}||~~~y}~v{vx}|||{}}~€€€~}~~~€€€€}€~~~|‚~~}}}{{}}|z||~€‚€€||}|||||}|}{~{{{|||}|{{{{||zz}z~‚~ƒ„‚‚…†……††‡†‚„‹Š‰Š†‡…‚ƒ„„„„ƒ‚‚‚‚‚‚‚‚‚€‚€€€~{|~~|z~xyvw|||{{}|€~~€~~€€‚‚€~~€€~}ƒ||}}|}}}}{|~~~~}~|||||||~~{|{||||}|}|~|}||{{|y{|{{}{}~~€€ƒ‡‰‰‰Š‰‹‰…ˆŒŠˆˆ†……ƒ‚‚ƒ„„ƒƒ‚‚‚‚‚‚‚‚€€|{zzy{}z|~~y|yxxt|||{|||~€€~~~}€€€€ƒƒ€€€€€€€€~|z|}}~}}~~Œ†}}~{{ƒ‚}}}}}|}|}}}~|}{}|}}~|~}}}}|{{z|{||{z{{zzz{~~‚…ˆ‡‡‹‹‹Š‰ŒŒ‰‡†…„ƒ‚‚‚ƒƒƒƒ‚‚ƒ‚‚€€~zxyyz~~{yzx~s|||{|||~~~€€€€~~€€€€‚„ƒ€€€€~}~€~{~‘Œ|}Š€Œ~~}}}~}}~}|||}}|}|}}}~}}~~|{{{||}|{z{|yzyxy{~„‚„ˆ‰Šˆ‰ŒŠ‡ˆ…„„ƒ‚‚‚‚ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚€€~€€~{zy{}}y|zr}{{|||~~}}‚€€€‚…ƒ„‚‚‚‚€€ƒ‚€}~€~|ˆ‚~ƒ„„ƒ~}|‡}}~}||~|}}|}}}~}~}}}{|}~||{|}zzyyzy{{~~€ƒ‡„ˆŒ‰‰……„„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~z{y}}zzz}q~‚z{|}}}}zx~‚€‚‚€€€€€‚‚‚‚†…„ƒ€‚„~€}~~}€€}~„€~~}~}}Š…}~}~~€}}}|~~~}€}}}|}||{|}{{{zzz{{|}~}€ƒˆŒ‰‰‡………„ƒ‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€~~~}yzz}|yw{t{‡|tw}~}{{vv~€ƒ‚‚‚‚‚ƒƒƒ‚…†„‚€€€€‚€„~~€€}~€}}~~€€~~€€}~€~€~|}}|~~~~€}‚€|}€}||}}||{||{{{|{|||}|ˆ‰‡‡…†……„„ƒ‚ƒ‚€€‚ƒ‚‚‚ƒ‚‚‚‚‚‚‚ƒ‚€€~~~~~{{z||{v{tw~vr{~~{xuw|€‚‚‚‚ƒƒƒƒ‚‚„ƒ„ƒ…†ƒ‚€ƒ€€€€ƒ~~€€}€}}~~€€‚€€€}€€€€€~|}}}}~~}ƒ}€~‚€}~|~~}}}{|~|}|||{|{|}ˆ…†„…‡…„…„‚‚ƒ€€‚‚ƒ‚‚‚ƒƒƒƒ‚‚€~€€~~~~~~~~z{z}‚ƒ}uqz|zqz}}yxtt€€‚‚‚ƒ‚ƒ…ƒ„ƒ‚ƒ„„„„…„€€~€‚~~~€}~€}}}~€€‚€€€‚}~€€€€€~}}}~}~~}}„€~}€}}~}~~}~|{|z|{z€…‚ƒ„…„„„…ƒ‚‚‚€€‚‚ƒ‚‚ƒ„ƒ„ƒƒ‚‚‚ƒ€€~~~~~}~~~{{z~‰‡~xry}qzx{xytu}‚ƒ‚ƒƒƒƒ…„…„ƒƒ„„ƒƒ„‚€€€~}}~€~~~€}}|}}~€€€€‚€€€ƒ€~€~€€€~~~~~}~~……€€€ƒ~€~€~€~}{z{z|{z‚ƒ‚‚‚‚ƒ‚ƒ‚€€‚€€‚ƒ‚ƒ„ƒ„‚„‚‚‚‚€~€~}~~~~}~}}z{|…„{{ry{|pwuvwyvtz„„„„ƒ„……†„ƒƒ…„‚ƒƒ‚€€€}}}~}~~}~|}}~€€€€€ƒ‚€~€€€€€€€€‚‚‚„€ƒ€€|{{z|{|€‚€~‚‚ƒƒƒ‚„‚„‚€‚€~€€}~~}}}~}}{{z€x|vyz|qtxwvxury……‚…„‚„……†„„‚„ƒƒ‚€€~€€|}}~€}~~}|~~~~€€ƒƒƒ€€‚€€€€€€€€‚ƒ€„}ƒ„€€‚}z{{||}}€|}}€€~}}€~‚€‚‚‚‚ƒ‚‚€‚€~~}}}~}}}}}}z{{|v}yxzzruyyvwwsu†…ƒ……‚„„…„„„‚ƒ‚ƒ€~€~€}}}~~€~~}|€|~€~€‚ƒ€€‚ƒ„‚€€€€€‚ƒ‚ƒ€~‚‚„€€‚‚‚„‚~{{|||}}}~}z~}}y~|||~}~€€‚ƒ‚€€‚€}~}}}}}~}|}}}}z{z|v|zw{xrvy{vvvst†„„……„„…„ƒ‚ƒƒ€}~}}}€~~~}}}€€~|~€~‚‚ƒ‡…€~~€€€€€€‚€€~€‚‚‚ƒ‚ƒƒ…‚}}}|{||yz{z~y{yx~{{{~}}€~€€€‚ƒ‚€}~|}~}}}}}|~~|}|y{|xz|wzwsxwzsvvst†„„…ƒ‚ƒ„„ƒ‚‚ƒ‚‚€|€~€}~}~€€€~~|~€€~}~~€}€€ƒ„ƒ~}~~~€€€‚€~~€‚‚€„‚„„†„€~}||||zyvyyzyvyv~|{{{~}{}€}}‚~~}}|}}}}}}}|~|}y{{zy|wxxtuuxrwwtv†„„…ƒƒƒƒ‚ƒ‚‚ƒ‚ƒ‚€~€~}}|€€€€|€€€€|€~~~}~~€‚‚~~}~~~~€}€€~~~~~€‚ƒ‚ƒ„‡„€€~|}||{|uyyxxxyw{|{z{~†}~}z{~~~}~€€€}~€~}}|}}}}}}|{}ƒ‚||z{{{z{wvxursvqwyrx…………ƒ„„‚‚ƒ‚‚€ƒ€€~~~~€~}~|€€€€{€~€€€}€~~}}}~€‚~~~~}}}~~|~€~~~‚~~€€ƒ‚ƒƒ†„€~|}||{|xw{xuywwy|z{{}’‡}|}wz}~~}}~~€|~€~}}|}}}}}}{|z{}zzx{|zz{xtxuqrtpxxqy„………ƒ„ƒ‚ƒƒ‚‚‚€€€€€}~~€}|~}€€€|€€~€}€~~}}|€€€€€~~~~}|~~~|}€~}~€‚~€€~ƒ‚‚ƒ……‚‚~}}{{||yw{ywxwwx{{z{|…Š}{zwz|}}||}}}~|}~~}}||}~~}}||{zz|{{zyzz{zxswuqqspxwq{…†……ƒ…‚ƒƒ‚€€€€~~}|~}€€‚€€}~€~€€€}~|}€€€€~~|~}}}~~‚€€~ƒ‚‚„ƒ„‚‚~~||z|{{xzzwsvwxy{z{yz~{{wz|}|||~}|}}|}}}||}}}}}}|}{y{|||zzzzzzxsvupprowvr{…‡„…ƒ„‚ƒ‚‚‚‚‚€€€}}~€‚}~~~€€€‚€€€~}~|€€€€€~}~~€€‚€€€€€„‚‚€~|}~~z}„}t|}zzzz|yyzz†…wy|||||}{||||}}}||}}}}~}}}}zy}||}zzzzzzysuuooqowts|…†ƒ„‚ƒ‚‚‚‚‚‚‚€€€€€€€~}€€‚‚‚€~€€€€‚}}~‚€€€€€€€€~~}€€€€€€€€€€‚€€~}~z‘‹z|}|{}y{zzxyxy{||}||{||||}}}||}|~}~~~}|z||{|}{yzzzyysuuooqpwst}…‡ƒƒ‚ƒ‚€€‚‚€‚€€€€~~€€‚‚€‚‚€€‚~€€|~€€‚€€€€€€€~}~€~}€€€€€€€€€€€‚‚€€€}~|†ˆ||~{{~yz{z{~wwy{|{}||||{}|}|}}|}|~~~~|z|}{}}{yz{zyystunsqpxruz…†ƒƒ‚ƒ‚€€€‚‚‚‚€~‚‚ƒƒ€‚€€€€}€€€€€€~€€€~}€~~€€€€€€€‚‚‚€€€€€€}~€}€ƒ‚{~~{|}{z||{‡yxxy|||}{||}}}||}}~}}}~~€}{|}|||{zy{{yysrunvrpxquv……ƒ„ƒ‚‚€€€‚€‚‚‚‚ƒƒ‚€‚€€€‚‚‚ƒ„„€~‚€€€€‚~€€‚€€€€€€€€€~}€€€€€€€€€€€‚€€€€€~}~}~~{}|}{||wxuxxy{||}|||||}~~}}~€€|}||}{z{yz|xzsrunwqqzqvw……ƒ„ƒƒ‚‚ƒ€‚…ƒƒ„ƒ‚‚‚€€‚ƒ‚€‚‚…ƒ€€~‚ƒ€€€€€€€€‚€€€~€€€€€€€€€€€€€€€€€€€€€€‚‚‚‚€‚‚€€€‡~~|z}|{}~xwvyyy|}}|}{||}}~~€€~}~€€€‚€|~}}~|w{zz{yysqunwpuzqvy……‚ƒ‚ƒƒ‚ƒ„„€€‚†ƒƒƒ‚„€„ƒ‚‚€‚‚„‚‚„‚€€ƒ‚€€€ƒ~€ƒ‚}‚€€€~€€€€€€‚‚‚€‚ƒ‚‚ƒƒƒ‚€€€„}}}|}z}€zyvzxy{{|}}{|}}}}~€€€€€€ƒƒ€}~~~}yy{zzzysruowqwysw{…‚‚ƒ‚ƒ„‚ƒ„ƒ€€‚ƒ†ƒƒƒ‚‚„„ƒ‚€€‚ƒ‚‚‚~€€‚‚ƒ€€€€€‚„€~ƒ~€ƒ‚€~€‚ƒ‚€‚‚ƒ‚ƒ‚‚„€ƒ‚„ƒƒ„„ƒƒ„ƒƒ‚€‚€}€|z|{{w|yyy{z}~}||||}~~€€€„„€}€~{{{z{ztpxrytvxtw{„‚ƒ‚ƒƒ„‚„ƒƒ‚‚„†„‚ƒƒ‚„„„€ƒ€ƒ‚‚‚‚‚€‚€~€€‚‚‚‚‚€ƒ‚‚ƒ€~ƒ~„„ƒ‚‚ƒ‚‚‚ƒƒƒ„‚„‚ƒ‚‚‚‚ƒƒ„ƒ„„„„„…ƒ„‚ƒ‚‚ƒ€€~||€||x|yzyz|}|{||}}}||€€€€€‚~€€€€{{{zzzupxwyvu|uv|€€ƒ‚ƒƒƒƒ„„„€‚‚…„„ƒƒ‚ƒ„„…‚‚‚ƒƒ‚‚‚€€}€€‚ƒ‚‚‚‚€‚‚ƒ‚‚ƒ€ƒ€‚„ƒƒ‚‚‚ƒ‚‚ƒƒ„ƒƒ„€‚„ƒƒƒƒ‚ƒ…‚„„„„„„ƒ„„‚„ƒ„„‚‚€{~~}y|zzz}||}z||}}|z{~~~€€€€€€€€}}||}|vrvxxvt~vu}‡‡ƒ‚„…ƒƒ„…„€‚„…„„ƒ‚ƒ„„€„…ƒ‚‚‚ƒƒ‚ƒ‚‚€‚€}€€‚ƒ‚‚‚‚„‚‚‚ƒ„‚‚€€ƒƒ…„ƒ‚ƒ€‚‚ƒ‚ƒƒƒ„ƒ„ƒ€‚ƒ‚„ƒ‚‚~ƒ‚„„‚ƒƒ„„„„ƒ„„ƒ„ƒ…„ƒƒƒ‚‚€{€||}zz{}}||z|~}|}}~~€€€€~~€€€€~|}}~~}|{xvvv„‡ƒ‚ƒ…ƒƒ„†„‚…†…„„ƒƒ„„‚„……‚‚ƒƒ„‚ƒ‚ƒ‚‚~€€‚‚ƒ‚ƒƒƒ„‚‚‚ƒƒ‚ƒƒ~„„ƒƒ‚„„ƒƒƒ‚„ƒƒ„‚€ƒ„ƒ„ƒƒ‚‚ƒ‚‚„ƒ‚ƒ„„„„„„…„ƒƒ„…„„„ƒ‚€}‚}||{||€}}~€~~}~|||}}~~~€}}~€~~}}}~}}~~€||€‚‚ƒƒ†ƒ„ƒ†„‚ˆ‡…„ƒƒ„„…‚„……ƒƒ„ƒ„ƒƒ‚ƒ‚ƒ~ƒƒ„‚ƒƒ„„ƒ‚ƒ‚„ƒƒƒ‚‚ƒ‚ƒ„ƒƒƒ‚ƒ…ƒƒƒƒ„ƒƒ„ƒ€‚„„…ƒ‚‚ƒƒƒ„ƒƒƒ„ƒ„„„…„„„…………„ƒƒƒ}„}}||||~}~}}{|}}}}}~~€€€~}|~‚~~~~}}€€€€„„ƒƒ„…ƒ„ƒ…~‚Š‹…„„ƒ‚ƒ…†††ƒ„„„„„ƒƒƒƒ„‚ƒƒ…„…„…„ƒ‚„„„…„ƒƒ‚„ƒ…ƒ„……†„‚€ƒ‡„ƒƒƒ…„……„„ƒƒ‡‚ƒ‚ƒ‚„ƒ‚ƒƒ…ƒƒ……„……‡‡†‡…„„…„ƒ~~|~}}€~||~~|z|}}}}}~~~€}}|€€~~~~~€‚€……„ƒ…„‚„ƒ†€‚……‹‰„„ƒ„……ƒ‡††„„„„…„„„„ƒ„„‚ƒƒƒ„„†„…„ƒƒ„„ƒ|ƒ„{„wyƒ}„~~ruƒ‚v~ƒ…}uyƒ€~„„‚ƒƒ‚ƒ„ƒƒ„…ƒ„…†„…†}„y|~„{…ƒ€„ƒ€~}~}}ƒ}{}~€~}|||}}}}|}}€‚}}|€€€€‚‚ƒƒ‚‚†„„„†„ƒ„…ƒ„…„Šˆ………ƒ……„†††ƒ„„………„……„„…‚‚ƒ„………†„…„ƒ„……‚h€…j|{qq|s†stt}‚„usqƒ†tpurstƒv{}u‚ƒ€‚vy…€ƒ€„…„‚……‚hzrss|€sƒƒƒ}}}~}~‚ƒ|}~€}}||||}|||~}~€}}}€‚€‚‚‚‚‚„‡„…„…„‚„††ƒ…ƒ†ˆ††…ƒ††‡‡†‡ƒ……†…„‚…†„……ƒ‚ƒ„„†††„†„ƒ„…†}q{pyv~ƒ‚nypus|vzy…r„ƒpvxqvtturstvi€nrotvnulwm{sn€ˆym}rsvsvmmxlpylu}~}~€}€~}€€}}|||}|}~}€€€~|~€‚€€€€€€€‚ƒ‚ƒ„…ˆ††€‚…ƒƒ„‡†ƒ………†‡‡„ƒ†‡ˆ‰†‡„…†ˆˆ…ƒ…†……„„ƒ…„‚…††…†…„†…‡vpt{pru‡…ƒmuovo|ur„yy‡xqtwnwhwznpv‚rƒ~ozyymonzoomw}x†pqzprtfu~n{ysoy€}}|}|€~€€~~€€€~~~€~}€}€€€~~€‚ƒ‚‚„…‡‡„~‡„ƒƒ…‡†„†……††ˆ„„†‡ˆˆ†‡„††‹‰…„†‡‡…ƒ………„‚…………††…†…†quprsoszy~„tˆtu~ˆvn‚r„†ynjrqmsw|ut|„~xquwnyuzqvxuzy„qjoyxpkyszozwvvp€~~~z~}}}~}€ƒƒ€‚ƒ„‚€€}~~~€~~‚€€„‡†ƒƒ†„„…†‡†…………††ˆ…„†…‡†…†„††‰ˆ…„‰Šˆ…„††……ƒ……„…††††…ƒx‹yrˆz{pp…„x…xyks~y{krƒ‡ƒz|m{yyt}€vno€€ot|uwqy}}m~uoƒ…†z€rr{|tpozks|nw‚€~~}}{}{|}}~}‚‚ƒƒ€€€€~~}~}€~|}€~~€ƒˆ…†ƒ…………†‡……………‡‡ˆ†„†…‡††…„……„……†‰‰‡†„†…††…††„††‡††…†‡‡‡††„†…†‡ˆ‡…‡††ƒ‡†……ƒ„††…†„†„ƒ„„†„„„ƒ„„…„…„…„†ƒ†‡…†„„…‡†„„……„…}w…ƒ„„ƒ‚}~{|{~{||}~}|~~€}€~~~€~~~~}}}~|{|~||‰†…„†††…‡†…………††‡ˆ†„†…††……ƒ„…†…„††††……†„…††††…††‡‡†…‡ˆˆˆˆ†„‡…†‡ˆ†…ˆ‡ˆ…‡††ˆ……††…††…ƒ‚……†……ƒ„„„„…„……„……„†‡††…„†‡†„„…†ƒ…„‚„ƒƒ…ƒƒ‚}€{{|}{||}~||~}€}~€~~€}}|€}~~~~~|}}~{|||{{~ˆ‡„„ˆ†††‡†……„††††ˆ‡„…†‡†…„ƒƒ„†…„‡……†……†„…††‡‡…‡†‰ˆ††ˆ‡ˆ‰ˆ…„ˆ…†‡†‡†ˆ†‡…‡‡†‡……†‡…‡†…‚ƒ…††„„ƒ„„ƒ„†„………††„††…†…„††…„ƒ……‚…‡…ƒ‚‚…ƒ„~€€|{}}{|{}~}||~}~~|~}}~~}}||~~|}€|||}|||~z{{}~ˆ‡‚…ˆ‡‡††††„„††‡†ˆ†ƒ„„††„…‡ƒ„…„…‡„…††…†„††‡‡††ˆ‡‰ˆ††ˆ‡ˆŠˆ…‡ˆ…‡‡†‡†‡†‡…ˆˆ‡‡…††‡…‡‡…„„…†……„„„ƒ„……†††…†„‡††‡……††…„ƒ„ƒ‚„‡ƒ„‚„„ƒ€€€{{~}{||}}|||}}|}|~}|}}|||}}|~}{|}|}|~|||zz||}ˆ‡‚†ˆ‡†‡†††„…†…†††…ƒ…„†…„ˆ‰ƒ„ƒ„†„†††††„‡‡ˆˆ‡‡‡ˆŠˆ†‡ˆ‡ˆ‰ˆ…ˆ‡…‡††‡‡‡…‡†ˆˆ‡‡…‡‡‡…†‡„‚„ƒ„†…‡……„ƒ„„…††††††‡……‡…†…†…„‚ƒ‚ƒƒ‡ƒ€‚ƒƒ‚‚‚€{|~~|||~}|}}|}{||||||}{{{}|{~|{|}}|}}}|zz{{||ˆ‡‚††††‡††…„…†…………„ƒ…‚†„ƒˆ‡zz‚…†„††…‡†„‡‡‰ˆˆ‡†ˆŠ‡†‡‡†ˆ‰‡…ˆ‡†ˆ‡††‡‡…‡†ˆˆ‡†…‡†‡††‡ƒƒ„„ƒ††‡……„„„…†††††…‡‡††‡††„†…ƒƒ‚‚‚ƒ†ƒ~‚‚ƒ€ƒƒ|~~||}}|}}|}z{{z{|||{{{~{{}{{{~||||}~}{z|z|}‰‡ƒ†…†…††……„……………„ƒ…†„‚„„|€†‚……†……†…„‡‡ˆˆˆ†…ˆŠ‡…‡†‡‡ˆ‡…ˆ…†‡ˆ††‡‡†‡†ˆˆ‡…†‡†‡……‡ƒ„†…„††‡†……ƒ……††††‡…‡†‡†‡‡…„……ƒ‚€ƒ…‚ƒ~ƒ~~}||}}{}}|}zz{y{|}{{{{~||||z{}||||~}|{{{{|{‰‡„†„†„††…„…†…„„ƒ„‚€ƒ…ƒ‚z„Œ{€„…‡†††…„‡ˆ‡†‡……‡‰‡„‡…‡†ˆ†…‡„†‡ˆ††ˆˆ‡‡†‡ˆ†„†††‡†…‡ƒ„…„†††‡……„ƒ……‡…‡†‡…†††…††„ƒ„…€€ƒƒƒ‚}€~ƒ~€||}}~}{~}|}yzzy{}}zz{{}|}||z{}||}|~~€|{{|~}|ˆ‡…†…†„†………………ƒƒƒ€‚…‚€€}|{„…††„…„ƒ‡‡†††…„†‰†‚†„†††……‡†‡ˆ‰†…ˆ‡‰‡††‡…„†……†……‡ƒ„…„ˆ††‡……„‚†…†…‡†‡„†††……†ƒƒƒ…€€€ƒƒ€|€~~‚€}€||}~}~{~}||yyzyz}}yzz{|{|{{z{}}|}|~~~|{{}~}|ˆ†…†††„……„……„ƒ‚‚€‚€€€ƒ~~~€yz}€ƒ„…‡…„ƒƒ‡†ƒ„…„‚…ˆ…‚„ƒƒ…………‡‡‡ˆˆ……ˆ‡‰‡†…†…ƒ†„…‡ƒ„†„„…„‡†…†…†„ƒ†…†††††„…†‡……†‚‚ƒ„~€€€€ƒ€{}~‚~~€~€~}}~}{}{zyzzyz|}yzz{{z|{{{{|}}}|~}||}~|{ˆ……††††„…„…ƒ…‚€€€€~‚‚}}{‚ƒƒ…†…„ƒ‚†ƒƒ„‚€…‡…‚ƒƒ„„„††‡‡‡……ˆ†‰‡†„„„‚…ƒ„†‚ƒ…„„†„‡†………†ƒ„…„…†…†„ƒ……†ƒ……ƒƒ~€€ƒ|€}}‚}€~~~}}}}{|{zyzzyzz|yzz{{{}z{{{|}~}}€}}||}€}|†ƒ††††…ƒ„‚…‚…€€€~€‚|~~€€‚‚‚ƒ„ƒ‚‚„€ƒ‚€„……‚€‚ƒƒ„…†ˆ†…„…‡…‡……‚ƒ‚ƒ‚‚…ƒ…„…†„††‡††…‚„„ƒ„†……ƒ„„ƒ„ƒ…„€€‚‚}}~~€„~{||€}€}}ƒ|~~}}~{~{{zyzzyzz{yzzz{{|z{|||~~}|}||}€~€†„……„‡„ƒƒ‚†‚ƒ€€~~€}‚|}~~~‚ƒƒ‚‚‚€‚€€‚…„‚€€‚ƒ……‡†„„††„…ƒ…‚‚‚ƒ‚„„„……†‡‡†…„ƒƒƒƒ„†…„ƒ‚ƒ‚„ƒƒ€€~}|~~|ƒ}|~||€~‚}‚|~}||||{{zyzzy{zzzzzzz{|y{}||€}~}}}€€€†„„…„…‚ƒ‚‚„‚‚€€~}~~~~€}}€~~~‚ƒƒ‚„‡~€€‚„ƒ~€‚‚…„†„ƒƒ……‚„ƒ€€‚€„ƒƒ†……‡‡…………‚‚‚ƒ…„‚‚€…ƒ~€~||~}|~ƒ}{~{}€ƒ~}€~}|||}{{zyzyy{yzzyzz{{{z{}||‚€~€€€€€
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_aac_stereo_128kbps_48000hz.aac b/media/codec2/hidl/1.0/vts/functional/res/bbb_aac_stereo_128kbps_48000hz.aac
new file mode 100644
index 0000000..831102d
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_aac_stereo_128kbps_48000hz.aac
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_aac_stereo_128kbps_48000hz.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_aac_stereo_128kbps_48000hz.info
new file mode 100644
index 0000000..5fcda0b
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_aac_stereo_128kbps_48000hz.info
@@ -0,0 +1,469 @@
+5 32 0
+5 32 0
+337 1 0
+322 1 21333
+279 1 42666
+280 1 64000
+283 1 85333
+317 1 106666
+318 1 128000
+321 1 149333
+313 1 170666
+312 1 192000
+317 1 213333
+330 1 234666
+350 1 256000
+355 1 277333
+333 1 298666
+325 1 320000
+376 1 341333
+335 1 362666
+351 1 384000
+350 1 405333
+339 1 426666
+329 1 448000
+350 1 469333
+330 1 490666
+359 1 512000
+316 1 533333
+345 1 554666
+357 1 576000
+325 1 597333
+336 1 618666
+339 1 640000
+312 1 661333
+350 1 682666
+338 1 704000
+353 1 725333
+340 1 746666
+332 1 768000
+340 1 789333
+339 1 810666
+333 1 832000
+333 1 853333
+345 1 874666
+340 1 896000
+343 1 917333
+335 1 938666
+339 1 960000
+342 1 981333
+348 1 1002666
+350 1 1024000
+351 1 1045333
+342 1 1066666
+366 1 1088000
+340 1 1109333
+354 1 1130666
+340 1 1152000
+334 1 1173333
+338 1 1194666
+340 1 1216000
+351 1 1237333
+346 1 1258666
+331 1 1280000
+321 1 1301333
+343 1 1322666
+342 1 1344000
+345 1 1365333
+326 1 1386666
+342 1 1408000
+356 1 1429333
+351 1 1450666
+343 1 1472000
+347 1 1493333
+349 1 1514666
+350 1 1536000
+330 1 1557333
+341 1 1578666
+340 1 1600000
+330 1 1621333
+340 1 1642666
+335 1 1664000
+344 1 1685333
+359 1 1706666
+337 1 1728000
+346 1 1749333
+330 1 1770666
+351 1 1792000
+355 1 1813333
+352 1 1834666
+325 1 1856000
+342 1 1877333
+327 1 1898666
+349 1 1920000
+326 1 1941333
+337 1 1962666
+378 1 1984000
+321 1 2005333
+319 1 2026666
+346 1 2048000
+352 1 2069333
+349 1 2090666
+331 1 2112000
+330 1 2133333
+329 1 2154666
+333 1 2176000
+367 1 2197333
+362 1 2218666
+337 1 2240000
+337 1 2261333
+360 1 2282666
+333 1 2304000
+317 1 2325333
+344 1 2346666
+335 1 2368000
+337 1 2389333
+349 1 2410666
+336 1 2432000
+348 1 2453333
+349 1 2474666
+342 1 2496000
+359 1 2517333
+340 1 2538666
+340 1 2560000
+348 1 2581333
+334 1 2602666
+328 1 2624000
+341 1 2645333
+339 1 2666666
+337 1 2688000
+350 1 2709333
+326 1 2730666
+360 1 2752000
+344 1 2773333
+340 1 2794666
+343 1 2816000
+361 1 2837333
+329 1 2858666
+345 1 2880000
+345 1 2901333
+330 1 2922666
+342 1 2944000
+344 1 2965333
+330 1 2986666
+329 1 3008000
+335 1 3029333
+366 1 3050666
+328 1 3072000
+349 1 3093333
+339 1 3114666
+340 1 3136000
+335 1 3157333
+327 1 3178666
+348 1 3200000
+339 1 3221333
+334 1 3242666
+350 1 3264000
+325 1 3285333
+361 1 3306666
+338 1 3328000
+350 1 3349333
+353 1 3370666
+327 1 3392000
+346 1 3413333
+348 1 3434666
+339 1 3456000
+342 1 3477333
+334 1 3498666
+350 1 3520000
+354 1 3541333
+363 1 3562666
+322 1 3584000
+337 1 3605333
+355 1 3626666
+329 1 3648000
+324 1 3669333
+338 1 3690666
+356 1 3712000
+330 1 3733333
+321 1 3754666
+337 1 3776000
+345 1 3797333
+335 1 3818666
+348 1 3840000
+342 1 3861333
+348 1 3882666
+335 1 3904000
+344 1 3925333
+357 1 3946666
+368 1 3968000
+324 1 3989333
+343 1 4010666
+341 1 4032000
+329 1 4053333
+356 1 4074666
+317 1 4096000
+351 1 4117333
+340 1 4138666
+340 1 4160000
+332 1 4181333
+355 1 4202666
+357 1 4224000
+327 1 4245333
+338 1 4266666
+323 1 4288000
+346 1 4309333
+352 1 4330666
+347 1 4352000
+343 1 4373333
+311 1 4394666
+338 1 4416000
+365 1 4437333
+349 1 4458666
+327 1 4480000
+355 1 4501333
+319 1 4522666
+349 1 4544000
+351 1 4565333
+337 1 4586666
+340 1 4608000
+349 1 4629333
+316 1 4650666
+344 1 4672000
+334 1 4693333
+344 1 4714666
+347 1 4736000
+348 1 4757333
+334 1 4778666
+338 1 4800000
+331 1 4821333
+344 1 4842666
+342 1 4864000
+336 1 4885333
+326 1 4906666
+364 1 4928000
+350 1 4949333
+350 1 4970666
+363 1 4992000
+358 1 5013333
+305 1 5034666
+344 1 5056000
+346 1 5077333
+342 1 5098666
+330 1 5120000
+318 1 5141333
+361 1 5162666
+354 1 5184000
+313 1 5205333
+330 1 5226666
+350 1 5248000
+347 1 5269333
+346 1 5290666
+357 1 5312000
+325 1 5333333
+335 1 5354666
+331 1 5376000
+366 1 5397333
+329 1 5418666
+349 1 5440000
+371 1 5461333
+326 1 5482666
+333 1 5504000
+319 1 5525333
+327 1 5546666
+353 1 5568000
+356 1 5589333
+348 1 5610666
+338 1 5632000
+331 1 5653333
+341 1 5674666
+362 1 5696000
+326 1 5717333
+359 1 5738666
+315 1 5760000
+376 1 5781333
+343 1 5802666
+354 1 5824000
+353 1 5845333
+344 1 5866666
+334 1 5888000
+345 1 5909333
+355 1 5930666
+322 1 5952000
+334 1 5973333
+353 1 5994666
+338 1 6016000
+351 1 6037333
+334 1 6058666
+339 1 6080000
+345 1 6101333
+347 1 6122666
+355 1 6144000
+312 1 6165333
+352 1 6186666
+354 1 6208000
+318 1 6229333
+344 1 6250666
+363 1 6272000
+321 1 6293333
+339 1 6314666
+356 1 6336000
+334 1 6357333
+354 1 6378666
+325 1 6400000
+321 1 6421333
+341 1 6442666
+337 1 6464000
+351 1 6485333
+343 1 6506666
+341 1 6528000
+344 1 6549333
+341 1 6570666
+364 1 6592000
+319 1 6613333
+348 1 6634666
+332 1 6656000
+333 1 6677333
+343 1 6698666
+348 1 6720000
+347 1 6741333
+350 1 6762666
+342 1 6784000
+341 1 6805333
+326 1 6826666
+351 1 6848000
+329 1 6869333
+323 1 6890666
+350 1 6912000
+361 1 6933333
+326 1 6954666
+345 1 6976000
+345 1 6997333
+311 1 7018666
+349 1 7040000
+358 1 7061333
+352 1 7082666
+347 1 7104000
+364 1 7125333
+328 1 7146666
+318 1 7168000
+351 1 7189333
+340 1 7210666
+341 1 7232000
+355 1 7253333
+336 1 7274666
+352 1 7296000
+341 1 7317333
+334 1 7338666
+348 1 7360000
+342 1 7381333
+335 1 7402666
+342 1 7424000
+359 1 7445333
+349 1 7466666
+329 1 7488000
+356 1 7509333
+292 1 7530666
+316 1 7552000
+318 1 7573333
+320 1 7594666
+342 1 7616000
+285 1 7637333
+326 1 7658666
+352 1 7680000
+392 1 7701333
+364 1 7722666
+384 1 7744000
+334 1 7765333
+317 1 7786666
+326 1 7808000
+373 1 7829333
+354 1 7850666
+329 1 7872000
+347 1 7893333
+353 1 7914666
+338 1 7936000
+317 1 7957333
+354 1 7978666
+345 1 8000000
+350 1 8021333
+351 1 8042666
+332 1 8064000
+358 1 8085333
+315 1 8106666
+336 1 8128000
+358 1 8149333
+343 1 8170666
+319 1 8192000
+370 1 8213333
+344 1 8234666
+361 1 8256000
+343 1 8277333
+337 1 8298666
+354 1 8320000
+332 1 8341333
+348 1 8362666
+328 1 8384000
+345 1 8405333
+340 1 8426666
+346 1 8448000
+341 1 8469333
+344 1 8490666
+342 1 8512000
+341 1 8533333
+345 1 8554666
+337 1 8576000
+335 1 8597333
+335 1 8618666
+340 1 8640000
+345 1 8661333
+341 1 8682666
+342 1 8704000
+338 1 8725333
+343 1 8746666
+336 1 8768000
+338 1 8789333
+353 1 8810666
+339 1 8832000
+329 1 8853333
+349 1 8874666
+323 1 8896000
+351 1 8917333
+359 1 8938666
+357 1 8960000
+341 1 8981333
+333 1 9002666
+335 1 9024000
+328 1 9045333
+347 1 9066666
+343 1 9088000
+369 1 9109333
+331 1 9130666
+344 1 9152000
+330 1 9173333
+346 1 9194666
+337 1 9216000
+341 1 9237333
+338 1 9258666
+329 1 9280000
+360 1 9301333
+336 1 9322666
+341 1 9344000
+341 1 9365333
+345 1 9386666
+351 1 9408000
+349 1 9429333
+336 1 9450666
+326 1 9472000
+349 1 9493333
+343 1 9514666
+357 1 9536000
+342 1 9557333
+325 1 9578666
+346 1 9600000
+326 1 9621333
+402 1 9642666
+331 1 9664000
+339 1 9685333
+371 1 9706666
+314 1 9728000
+310 1 9749333
+364 1 9770666
+338 1 9792000
+339 1 9813333
+337 1 9834666
+355 1 9856000
+351 1 9877333
+332 1 9898666
+316 1 9920000
+474 1 9941333
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_aac_stereo_128kbps_48000hz_multi_frame.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_aac_stereo_128kbps_48000hz_multi_frame.info
new file mode 100644
index 0000000..182af20
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_aac_stereo_128kbps_48000hz_multi_frame.info
@@ -0,0 +1,443 @@
+5 32 0
+5 32 0
+337 1 0
+322 1 21333
+279 1 42666
+563 1 64000
+635 1 106666
+634 1 149333
+629 1 192000
+680 1 234666
+688 1 277333
+1036 1 320000
+1040 1 384000
+1009 1 448000
+1020 1 512000
+1357 1 576000
+1353 1 661333
+1351 1 746666
+1351 1 832000
+343 1 917333
+335 1 938666
+339 1 960000
+342 1 981333
+348 1 1002666
+350 1 1024000
+351 1 1045333
+342 1 1066666
+366 1 1088000
+340 1 1109333
+354 1 1130666
+340 1 1152000
+334 1 1173333
+338 1 1194666
+340 1 1216000
+351 1 1237333
+346 1 1258666
+331 1 1280000
+321 1 1301333
+343 1 1322666
+342 1 1344000
+345 1 1365333
+326 1 1386666
+342 1 1408000
+356 1 1429333
+351 1 1450666
+343 1 1472000
+347 1 1493333
+349 1 1514666
+350 1 1536000
+330 1 1557333
+341 1 1578666
+340 1 1600000
+330 1 1621333
+340 1 1642666
+335 1 1664000
+344 1 1685333
+359 1 1706666
+337 1 1728000
+346 1 1749333
+330 1 1770666
+351 1 1792000
+355 1 1813333
+352 1 1834666
+325 1 1856000
+342 1 1877333
+327 1 1898666
+349 1 1920000
+326 1 1941333
+337 1 1962666
+378 1 1984000
+321 1 2005333
+319 1 2026666
+346 1 2048000
+352 1 2069333
+349 1 2090666
+331 1 2112000
+330 1 2133333
+329 1 2154666
+333 1 2176000
+367 1 2197333
+362 1 2218666
+337 1 2240000
+337 1 2261333
+360 1 2282666
+333 1 2304000
+317 1 2325333
+344 1 2346666
+335 1 2368000
+337 1 2389333
+349 1 2410666
+336 1 2432000
+348 1 2453333
+349 1 2474666
+342 1 2496000
+359 1 2517333
+340 1 2538666
+340 1 2560000
+348 1 2581333
+334 1 2602666
+328 1 2624000
+341 1 2645333
+339 1 2666666
+337 1 2688000
+350 1 2709333
+326 1 2730666
+360 1 2752000
+344 1 2773333
+340 1 2794666
+343 1 2816000
+361 1 2837333
+329 1 2858666
+345 1 2880000
+345 1 2901333
+330 1 2922666
+342 1 2944000
+344 1 2965333
+330 1 2986666
+329 1 3008000
+335 1 3029333
+366 1 3050666
+328 1 3072000
+349 1 3093333
+339 1 3114666
+340 1 3136000
+335 1 3157333
+327 1 3178666
+348 1 3200000
+339 1 3221333
+334 1 3242666
+350 1 3264000
+325 1 3285333
+361 1 3306666
+338 1 3328000
+350 1 3349333
+353 1 3370666
+327 1 3392000
+346 1 3413333
+348 1 3434666
+339 1 3456000
+342 1 3477333
+334 1 3498666
+350 1 3520000
+354 1 3541333
+363 1 3562666
+322 1 3584000
+337 1 3605333
+355 1 3626666
+329 1 3648000
+324 1 3669333
+338 1 3690666
+356 1 3712000
+330 1 3733333
+321 1 3754666
+337 1 3776000
+345 1 3797333
+335 1 3818666
+348 1 3840000
+342 1 3861333
+348 1 3882666
+335 1 3904000
+344 1 3925333
+357 1 3946666
+368 1 3968000
+324 1 3989333
+343 1 4010666
+341 1 4032000
+329 1 4053333
+356 1 4074666
+317 1 4096000
+351 1 4117333
+340 1 4138666
+340 1 4160000
+332 1 4181333
+355 1 4202666
+357 1 4224000
+327 1 4245333
+338 1 4266666
+323 1 4288000
+346 1 4309333
+352 1 4330666
+347 1 4352000
+343 1 4373333
+311 1 4394666
+338 1 4416000
+365 1 4437333
+349 1 4458666
+327 1 4480000
+355 1 4501333
+319 1 4522666
+349 1 4544000
+351 1 4565333
+337 1 4586666
+340 1 4608000
+349 1 4629333
+316 1 4650666
+344 1 4672000
+334 1 4693333
+344 1 4714666
+347 1 4736000
+348 1 4757333
+334 1 4778666
+338 1 4800000
+331 1 4821333
+344 1 4842666
+342 1 4864000
+336 1 4885333
+326 1 4906666
+364 1 4928000
+350 1 4949333
+350 1 4970666
+363 1 4992000
+358 1 5013333
+305 1 5034666
+344 1 5056000
+346 1 5077333
+342 1 5098666
+330 1 5120000
+318 1 5141333
+361 1 5162666
+354 1 5184000
+313 1 5205333
+330 1 5226666
+350 1 5248000
+347 1 5269333
+346 1 5290666
+357 1 5312000
+325 1 5333333
+335 1 5354666
+331 1 5376000
+366 1 5397333
+329 1 5418666
+349 1 5440000
+371 1 5461333
+326 1 5482666
+333 1 5504000
+319 1 5525333
+327 1 5546666
+353 1 5568000
+356 1 5589333
+348 1 5610666
+338 1 5632000
+331 1 5653333
+341 1 5674666
+362 1 5696000
+326 1 5717333
+359 1 5738666
+315 1 5760000
+376 1 5781333
+343 1 5802666
+354 1 5824000
+353 1 5845333
+344 1 5866666
+334 1 5888000
+345 1 5909333
+355 1 5930666
+322 1 5952000
+334 1 5973333
+353 1 5994666
+338 1 6016000
+351 1 6037333
+334 1 6058666
+339 1 6080000
+345 1 6101333
+347 1 6122666
+355 1 6144000
+312 1 6165333
+352 1 6186666
+354 1 6208000
+318 1 6229333
+344 1 6250666
+363 1 6272000
+321 1 6293333
+339 1 6314666
+356 1 6336000
+334 1 6357333
+354 1 6378666
+325 1 6400000
+321 1 6421333
+341 1 6442666
+337 1 6464000
+351 1 6485333
+343 1 6506666
+341 1 6528000
+344 1 6549333
+341 1 6570666
+364 1 6592000
+319 1 6613333
+348 1 6634666
+332 1 6656000
+333 1 6677333
+343 1 6698666
+348 1 6720000
+347 1 6741333
+350 1 6762666
+342 1 6784000
+341 1 6805333
+326 1 6826666
+351 1 6848000
+329 1 6869333
+323 1 6890666
+350 1 6912000
+361 1 6933333
+326 1 6954666
+345 1 6976000
+345 1 6997333
+311 1 7018666
+349 1 7040000
+358 1 7061333
+352 1 7082666
+347 1 7104000
+364 1 7125333
+328 1 7146666
+318 1 7168000
+351 1 7189333
+340 1 7210666
+341 1 7232000
+355 1 7253333
+336 1 7274666
+352 1 7296000
+341 1 7317333
+334 1 7338666
+348 1 7360000
+342 1 7381333
+335 1 7402666
+342 1 7424000
+359 1 7445333
+349 1 7466666
+329 1 7488000
+356 1 7509333
+292 1 7530666
+316 1 7552000
+318 1 7573333
+320 1 7594666
+342 1 7616000
+285 1 7637333
+326 1 7658666
+352 1 7680000
+392 1 7701333
+364 1 7722666
+384 1 7744000
+334 1 7765333
+317 1 7786666
+326 1 7808000
+373 1 7829333
+354 1 7850666
+329 1 7872000
+347 1 7893333
+353 1 7914666
+338 1 7936000
+317 1 7957333
+354 1 7978666
+345 1 8000000
+350 1 8021333
+351 1 8042666
+332 1 8064000
+358 1 8085333
+315 1 8106666
+336 1 8128000
+358 1 8149333
+343 1 8170666
+319 1 8192000
+370 1 8213333
+344 1 8234666
+361 1 8256000
+343 1 8277333
+337 1 8298666
+354 1 8320000
+332 1 8341333
+348 1 8362666
+328 1 8384000
+345 1 8405333
+340 1 8426666
+346 1 8448000
+341 1 8469333
+344 1 8490666
+342 1 8512000
+341 1 8533333
+345 1 8554666
+337 1 8576000
+335 1 8597333
+335 1 8618666
+340 1 8640000
+345 1 8661333
+341 1 8682666
+342 1 8704000
+338 1 8725333
+343 1 8746666
+336 1 8768000
+338 1 8789333
+353 1 8810666
+339 1 8832000
+329 1 8853333
+349 1 8874666
+323 1 8896000
+351 1 8917333
+359 1 8938666
+357 1 8960000
+341 1 8981333
+333 1 9002666
+335 1 9024000
+328 1 9045333
+347 1 9066666
+343 1 9088000
+369 1 9109333
+331 1 9130666
+344 1 9152000
+330 1 9173333
+346 1 9194666
+337 1 9216000
+341 1 9237333
+338 1 9258666
+329 1 9280000
+360 1 9301333
+336 1 9322666
+341 1 9344000
+341 1 9365333
+345 1 9386666
+351 1 9408000
+349 1 9429333
+336 1 9450666
+326 1 9472000
+349 1 9493333
+343 1 9514666
+357 1 9536000
+342 1 9557333
+325 1 9578666
+346 1 9600000
+326 1 9621333
+402 1 9642666
+331 1 9664000
+339 1 9685333
+371 1 9706666
+314 1 9728000
+310 1 9749333
+364 1 9770666
+338 1 9792000
+339 1 9813333
+337 1 9834666
+355 1 9856000
+351 1 9877333
+332 1 9898666
+316 1 9920000
+474 1 9941333
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_amrwb_1ch_14kbps_16000hz.amrwb b/media/codec2/hidl/1.0/vts/functional/res/bbb_amrwb_1ch_14kbps_16000hz.amrwb
new file mode 100644
index 0000000..0d82593
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_amrwb_1ch_14kbps_16000hz.amrwb
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_amrwb_1ch_14kbps_16000hz.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_amrwb_1ch_14kbps_16000hz.info
new file mode 100644
index 0000000..f6a61d4
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_amrwb_1ch_14kbps_16000hz.info
@@ -0,0 +1,494 @@
+41 1 0
+41 1 20000
+41 1 40000
+41 1 60000
+41 1 80000
+41 1 100000
+41 1 120000
+41 1 140000
+41 1 160000
+41 1 180000
+41 1 200000
+41 1 220000
+41 1 240000
+41 1 260000
+41 1 280000
+41 1 300000
+41 1 320000
+41 1 340000
+41 1 360000
+41 1 380000
+41 1 400000
+41 1 420000
+41 1 440000
+41 1 460000
+41 1 480000
+41 1 500000
+41 1 520000
+41 1 540000
+41 1 560000
+41 1 580000
+41 1 600000
+41 1 620000
+41 1 640000
+41 1 660000
+41 1 680000
+41 1 700000
+41 1 720000
+41 1 740000
+41 1 760000
+41 1 780000
+41 1 800000
+41 1 820000
+41 1 840000
+41 1 860000
+41 1 880000
+41 1 900000
+41 1 920000
+41 1 940000
+41 1 960000
+41 1 980000
+41 1 1000000
+41 1 1020000
+41 1 1040000
+41 1 1060000
+41 1 1080000
+41 1 1100000
+41 1 1120000
+41 1 1140000
+41 1 1160000
+41 1 1180000
+41 1 1200000
+41 1 1220000
+41 1 1240000
+41 1 1260000
+41 1 1280000
+41 1 1300000
+41 1 1320000
+41 1 1340000
+41 1 1360000
+41 1 1380000
+41 1 1400000
+41 1 1420000
+41 1 1440000
+41 1 1460000
+41 1 1480000
+41 1 1500000
+41 1 1520000
+41 1 1540000
+41 1 1560000
+41 1 1580000
+41 1 1600000
+41 1 1620000
+41 1 1640000
+41 1 1660000
+41 1 1680000
+41 1 1700000
+41 1 1720000
+41 1 1740000
+41 1 1760000
+41 1 1780000
+41 1 1800000
+41 1 1820000
+41 1 1840000
+41 1 1860000
+41 1 1880000
+41 1 1900000
+41 1 1920000
+41 1 1940000
+41 1 1960000
+41 1 1980000
+41 1 2000000
+41 1 2020000
+41 1 2040000
+41 1 2060000
+41 1 2080000
+41 1 2100000
+41 1 2120000
+41 1 2140000
+41 1 2160000
+41 1 2180000
+41 1 2200000
+41 1 2220000
+41 1 2240000
+41 1 2260000
+41 1 2280000
+41 1 2300000
+41 1 2320000
+41 1 2340000
+41 1 2360000
+41 1 2380000
+41 1 2400000
+41 1 2420000
+41 1 2440000
+41 1 2460000
+41 1 2480000
+41 1 2500000
+41 1 2520000
+41 1 2540000
+41 1 2560000
+41 1 2580000
+41 1 2600000
+41 1 2620000
+41 1 2640000
+41 1 2660000
+41 1 2680000
+41 1 2700000
+41 1 2720000
+41 1 2740000
+41 1 2760000
+41 1 2780000
+41 1 2800000
+41 1 2820000
+41 1 2840000
+41 1 2860000
+41 1 2880000
+41 1 2900000
+41 1 2920000
+41 1 2940000
+41 1 2960000
+41 1 2980000
+41 1 3000000
+41 1 3020000
+41 1 3040000
+41 1 3060000
+41 1 3080000
+41 1 3100000
+41 1 3120000
+41 1 3140000
+41 1 3160000
+41 1 3180000
+41 1 3200000
+41 1 3220000
+41 1 3240000
+41 1 3260000
+41 1 3280000
+41 1 3300000
+41 1 3320000
+41 1 3340000
+41 1 3360000
+41 1 3380000
+41 1 3400000
+41 1 3420000
+41 1 3440000
+41 1 3460000
+41 1 3480000
+41 1 3500000
+41 1 3520000
+41 1 3540000
+41 1 3560000
+41 1 3580000
+41 1 3600000
+41 1 3620000
+41 1 3640000
+41 1 3660000
+41 1 3680000
+41 1 3700000
+41 1 3720000
+41 1 3740000
+41 1 3760000
+41 1 3780000
+41 1 3800000
+41 1 3820000
+41 1 3840000
+41 1 3860000
+41 1 3880000
+41 1 3900000
+41 1 3920000
+41 1 3940000
+41 1 3960000
+41 1 3980000
+41 1 4000000
+41 1 4020000
+41 1 4040000
+41 1 4060000
+41 1 4080000
+41 1 4100000
+41 1 4120000
+41 1 4140000
+41 1 4160000
+41 1 4180000
+41 1 4200000
+41 1 4220000
+41 1 4240000
+41 1 4260000
+41 1 4280000
+41 1 4300000
+41 1 4320000
+41 1 4340000
+41 1 4360000
+41 1 4380000
+41 1 4400000
+41 1 4420000
+41 1 4440000
+41 1 4460000
+41 1 4480000
+41 1 4500000
+41 1 4520000
+41 1 4540000
+41 1 4560000
+41 1 4580000
+41 1 4600000
+41 1 4620000
+41 1 4640000
+41 1 4660000
+41 1 4680000
+41 1 4700000
+41 1 4720000
+41 1 4740000
+41 1 4760000
+41 1 4780000
+41 1 4800000
+41 1 4820000
+41 1 4840000
+41 1 4860000
+41 1 4880000
+41 1 4900000
+41 1 4920000
+41 1 4940000
+41 1 4960000
+41 1 4980000
+41 1 5000000
+41 1 5020000
+41 1 5040000
+41 1 5060000
+41 1 5080000
+41 1 5100000
+41 1 5120000
+41 1 5140000
+41 1 5160000
+41 1 5180000
+41 1 5200000
+41 1 5220000
+41 1 5240000
+41 1 5260000
+41 1 5280000
+41 1 5300000
+41 1 5320000
+41 1 5340000
+41 1 5360000
+41 1 5380000
+41 1 5400000
+41 1 5420000
+41 1 5440000
+41 1 5460000
+41 1 5480000
+41 1 5500000
+41 1 5520000
+41 1 5540000
+41 1 5560000
+41 1 5580000
+41 1 5600000
+41 1 5620000
+41 1 5640000
+41 1 5660000
+41 1 5680000
+41 1 5700000
+41 1 5720000
+41 1 5740000
+41 1 5760000
+41 1 5780000
+41 1 5800000
+41 1 5820000
+41 1 5840000
+41 1 5860000
+41 1 5880000
+41 1 5900000
+41 1 5920000
+41 1 5940000
+41 1 5960000
+41 1 5980000
+41 1 6000000
+41 1 6020000
+41 1 6040000
+41 1 6060000
+41 1 6080000
+41 1 6100000
+41 1 6120000
+41 1 6140000
+41 1 6160000
+41 1 6180000
+41 1 6200000
+41 1 6220000
+41 1 6240000
+41 1 6260000
+41 1 6280000
+41 1 6300000
+41 1 6320000
+41 1 6340000
+41 1 6360000
+41 1 6380000
+41 1 6400000
+41 1 6420000
+41 1 6440000
+41 1 6460000
+41 1 6480000
+41 1 6500000
+41 1 6520000
+41 1 6540000
+41 1 6560000
+41 1 6580000
+41 1 6600000
+41 1 6620000
+41 1 6640000
+41 1 6660000
+41 1 6680000
+41 1 6700000
+41 1 6720000
+41 1 6740000
+41 1 6760000
+41 1 6780000
+41 1 6800000
+41 1 6820000
+41 1 6840000
+41 1 6860000
+41 1 6880000
+41 1 6900000
+41 1 6920000
+41 1 6940000
+41 1 6960000
+41 1 6980000
+41 1 7000000
+41 1 7020000
+41 1 7040000
+41 1 7060000
+41 1 7080000
+41 1 7100000
+41 1 7120000
+41 1 7140000
+41 1 7160000
+41 1 7180000
+41 1 7200000
+41 1 7220000
+41 1 7240000
+41 1 7260000
+41 1 7280000
+41 1 7300000
+41 1 7320000
+41 1 7340000
+41 1 7360000
+41 1 7380000
+41 1 7400000
+41 1 7420000
+41 1 7440000
+41 1 7460000
+41 1 7480000
+41 1 7500000
+41 1 7520000
+41 1 7540000
+41 1 7560000
+41 1 7580000
+41 1 7600000
+41 1 7620000
+41 1 7640000
+41 1 7660000
+41 1 7680000
+41 1 7700000
+41 1 7720000
+41 1 7740000
+41 1 7760000
+41 1 7780000
+41 1 7800000
+41 1 7820000
+41 1 7840000
+41 1 7860000
+41 1 7880000
+41 1 7900000
+41 1 7920000
+41 1 7940000
+41 1 7960000
+41 1 7980000
+41 1 8000000
+41 1 8020000
+41 1 8040000
+41 1 8060000
+41 1 8080000
+41 1 8100000
+41 1 8120000
+41 1 8140000
+41 1 8160000
+41 1 8180000
+41 1 8200000
+41 1 8220000
+41 1 8240000
+41 1 8260000
+41 1 8280000
+41 1 8300000
+41 1 8320000
+41 1 8340000
+41 1 8360000
+41 1 8380000
+41 1 8400000
+41 1 8420000
+41 1 8440000
+41 1 8460000
+41 1 8480000
+41 1 8500000
+41 1 8520000
+41 1 8540000
+41 1 8560000
+41 1 8580000
+41 1 8600000
+41 1 8620000
+41 1 8640000
+41 1 8660000
+41 1 8680000
+41 1 8700000
+41 1 8720000
+41 1 8740000
+41 1 8760000
+41 1 8780000
+41 1 8800000
+41 1 8820000
+41 1 8840000
+41 1 8860000
+41 1 8880000
+41 1 8900000
+41 1 8920000
+41 1 8940000
+41 1 8960000
+41 1 8980000
+41 1 9000000
+41 1 9020000
+41 1 9040000
+41 1 9060000
+41 1 9080000
+41 1 9100000
+41 1 9120000
+41 1 9140000
+41 1 9160000
+41 1 9180000
+41 1 9200000
+41 1 9220000
+41 1 9240000
+41 1 9260000
+41 1 9280000
+41 1 9300000
+41 1 9320000
+41 1 9340000
+41 1 9360000
+41 1 9380000
+41 1 9400000
+41 1 9420000
+41 1 9440000
+41 1 9460000
+41 1 9480000
+41 1 9500000
+41 1 9520000
+41 1 9540000
+41 1 9560000
+41 1 9580000
+41 1 9600000
+41 1 9620000
+41 1 9640000
+41 1 9660000
+41 1 9680000
+41 1 9700000
+41 1 9720000
+41 1 9740000
+41 1 9760000
+41 1 9780000
+41 1 9800000
+41 1 9820000
+41 1 9840000
+41 1 9860000
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_amrwb_1ch_14kbps_16000hz_multi_frame.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_amrwb_1ch_14kbps_16000hz_multi_frame.info
new file mode 100644
index 0000000..c420009
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_amrwb_1ch_14kbps_16000hz_multi_frame.info
@@ -0,0 +1,460 @@
+41 1 0
+41 1 20000
+82 1 40000
+82 1 80000
+82 1 120000
+82 1 160000
+82 1 200000
+82 1 240000
+82 1 280000
+82 1 320000
+82 1 360000
+123 1 400000
+123 1 460000
+123 1 520000
+123 1 580000
+123 1 640000
+164 1 700000
+164 1 780000
+164 1 860000
+164 1 940000
+164 1 1020000
+41 1 1100000
+41 1 1120000
+41 1 1140000
+41 1 1160000
+41 1 1180000
+41 1 1200000
+41 1 1220000
+41 1 1240000
+41 1 1260000
+41 1 1280000
+41 1 1300000
+41 1 1320000
+41 1 1340000
+41 1 1360000
+41 1 1380000
+41 1 1400000
+41 1 1420000
+41 1 1440000
+41 1 1460000
+41 1 1480000
+41 1 1500000
+41 1 1520000
+41 1 1540000
+41 1 1560000
+41 1 1580000
+41 1 1600000
+41 1 1620000
+41 1 1640000
+41 1 1660000
+41 1 1680000
+41 1 1700000
+41 1 1720000
+41 1 1740000
+41 1 1760000
+41 1 1780000
+41 1 1800000
+41 1 1820000
+41 1 1840000
+41 1 1860000
+41 1 1880000
+41 1 1900000
+41 1 1920000
+41 1 1940000
+41 1 1960000
+41 1 1980000
+41 1 2000000
+41 1 2020000
+41 1 2040000
+41 1 2060000
+41 1 2080000
+41 1 2100000
+41 1 2120000
+41 1 2140000
+41 1 2160000
+41 1 2180000
+41 1 2200000
+41 1 2220000
+41 1 2240000
+41 1 2260000
+41 1 2280000
+41 1 2300000
+41 1 2320000
+41 1 2340000
+41 1 2360000
+41 1 2380000
+41 1 2400000
+41 1 2420000
+41 1 2440000
+41 1 2460000
+41 1 2480000
+41 1 2500000
+41 1 2520000
+41 1 2540000
+41 1 2560000
+41 1 2580000
+41 1 2600000
+41 1 2620000
+41 1 2640000
+41 1 2660000
+41 1 2680000
+41 1 2700000
+41 1 2720000
+41 1 2740000
+41 1 2760000
+41 1 2780000
+41 1 2800000
+41 1 2820000
+41 1 2840000
+41 1 2860000
+41 1 2880000
+41 1 2900000
+41 1 2920000
+41 1 2940000
+41 1 2960000
+41 1 2980000
+41 1 3000000
+41 1 3020000
+41 1 3040000
+41 1 3060000
+41 1 3080000
+41 1 3100000
+41 1 3120000
+41 1 3140000
+41 1 3160000
+41 1 3180000
+41 1 3200000
+41 1 3220000
+41 1 3240000
+41 1 3260000
+41 1 3280000
+41 1 3300000
+41 1 3320000
+41 1 3340000
+41 1 3360000
+41 1 3380000
+41 1 3400000
+41 1 3420000
+41 1 3440000
+41 1 3460000
+41 1 3480000
+41 1 3500000
+41 1 3520000
+41 1 3540000
+41 1 3560000
+41 1 3580000
+41 1 3600000
+41 1 3620000
+41 1 3640000
+41 1 3660000
+41 1 3680000
+41 1 3700000
+41 1 3720000
+41 1 3740000
+41 1 3760000
+41 1 3780000
+41 1 3800000
+41 1 3820000
+41 1 3840000
+41 1 3860000
+41 1 3880000
+41 1 3900000
+41 1 3920000
+41 1 3940000
+41 1 3960000
+41 1 3980000
+41 1 4000000
+41 1 4020000
+41 1 4040000
+41 1 4060000
+41 1 4080000
+41 1 4100000
+41 1 4120000
+41 1 4140000
+41 1 4160000
+41 1 4180000
+41 1 4200000
+41 1 4220000
+41 1 4240000
+41 1 4260000
+41 1 4280000
+41 1 4300000
+41 1 4320000
+41 1 4340000
+41 1 4360000
+41 1 4380000
+41 1 4400000
+41 1 4420000
+41 1 4440000
+41 1 4460000
+41 1 4480000
+41 1 4500000
+41 1 4520000
+41 1 4540000
+41 1 4560000
+41 1 4580000
+41 1 4600000
+41 1 4620000
+41 1 4640000
+41 1 4660000
+41 1 4680000
+41 1 4700000
+41 1 4720000
+41 1 4740000
+41 1 4760000
+41 1 4780000
+41 1 4800000
+41 1 4820000
+41 1 4840000
+41 1 4860000
+41 1 4880000
+41 1 4900000
+41 1 4920000
+41 1 4940000
+41 1 4960000
+41 1 4980000
+41 1 5000000
+41 1 5020000
+41 1 5040000
+41 1 5060000
+41 1 5080000
+41 1 5100000
+41 1 5120000
+41 1 5140000
+41 1 5160000
+41 1 5180000
+41 1 5200000
+41 1 5220000
+41 1 5240000
+41 1 5260000
+41 1 5280000
+41 1 5300000
+41 1 5320000
+41 1 5340000
+41 1 5360000
+41 1 5380000
+41 1 5400000
+41 1 5420000
+41 1 5440000
+41 1 5460000
+41 1 5480000
+41 1 5500000
+41 1 5520000
+41 1 5540000
+41 1 5560000
+41 1 5580000
+41 1 5600000
+41 1 5620000
+41 1 5640000
+41 1 5660000
+41 1 5680000
+41 1 5700000
+41 1 5720000
+41 1 5740000
+41 1 5760000
+41 1 5780000
+41 1 5800000
+41 1 5820000
+41 1 5840000
+41 1 5860000
+41 1 5880000
+41 1 5900000
+41 1 5920000
+41 1 5940000
+41 1 5960000
+41 1 5980000
+41 1 6000000
+41 1 6020000
+41 1 6040000
+41 1 6060000
+41 1 6080000
+41 1 6100000
+41 1 6120000
+41 1 6140000
+41 1 6160000
+41 1 6180000
+41 1 6200000
+41 1 6220000
+41 1 6240000
+41 1 6260000
+41 1 6280000
+41 1 6300000
+41 1 6320000
+41 1 6340000
+41 1 6360000
+41 1 6380000
+41 1 6400000
+41 1 6420000
+41 1 6440000
+41 1 6460000
+41 1 6480000
+41 1 6500000
+41 1 6520000
+41 1 6540000
+41 1 6560000
+41 1 6580000
+41 1 6600000
+41 1 6620000
+41 1 6640000
+41 1 6660000
+41 1 6680000
+41 1 6700000
+41 1 6720000
+41 1 6740000
+41 1 6760000
+41 1 6780000
+41 1 6800000
+41 1 6820000
+41 1 6840000
+41 1 6860000
+41 1 6880000
+41 1 6900000
+41 1 6920000
+41 1 6940000
+41 1 6960000
+41 1 6980000
+41 1 7000000
+41 1 7020000
+41 1 7040000
+41 1 7060000
+41 1 7080000
+41 1 7100000
+41 1 7120000
+41 1 7140000
+41 1 7160000
+41 1 7180000
+41 1 7200000
+41 1 7220000
+41 1 7240000
+41 1 7260000
+41 1 7280000
+41 1 7300000
+41 1 7320000
+41 1 7340000
+41 1 7360000
+41 1 7380000
+41 1 7400000
+41 1 7420000
+41 1 7440000
+41 1 7460000
+41 1 7480000
+41 1 7500000
+41 1 7520000
+41 1 7540000
+41 1 7560000
+41 1 7580000
+41 1 7600000
+41 1 7620000
+41 1 7640000
+41 1 7660000
+41 1 7680000
+41 1 7700000
+41 1 7720000
+41 1 7740000
+41 1 7760000
+41 1 7780000
+41 1 7800000
+41 1 7820000
+41 1 7840000
+41 1 7860000
+41 1 7880000
+41 1 7900000
+41 1 7920000
+41 1 7940000
+41 1 7960000
+41 1 7980000
+41 1 8000000
+41 1 8020000
+41 1 8040000
+41 1 8060000
+41 1 8080000
+41 1 8100000
+41 1 8120000
+41 1 8140000
+41 1 8160000
+41 1 8180000
+41 1 8200000
+41 1 8220000
+41 1 8240000
+41 1 8260000
+41 1 8280000
+41 1 8300000
+41 1 8320000
+41 1 8340000
+41 1 8360000
+41 1 8380000
+41 1 8400000
+41 1 8420000
+41 1 8440000
+41 1 8460000
+41 1 8480000
+41 1 8500000
+41 1 8520000
+41 1 8540000
+41 1 8560000
+41 1 8580000
+41 1 8600000
+41 1 8620000
+41 1 8640000
+41 1 8660000
+41 1 8680000
+41 1 8700000
+41 1 8720000
+41 1 8740000
+41 1 8760000
+41 1 8780000
+41 1 8800000
+41 1 8820000
+41 1 8840000
+41 1 8860000
+41 1 8880000
+41 1 8900000
+41 1 8920000
+41 1 8940000
+41 1 8960000
+41 1 8980000
+41 1 9000000
+41 1 9020000
+41 1 9040000
+41 1 9060000
+41 1 9080000
+41 1 9100000
+41 1 9120000
+41 1 9140000
+41 1 9160000
+41 1 9180000
+41 1 9200000
+41 1 9220000
+41 1 9240000
+41 1 9260000
+41 1 9280000
+41 1 9300000
+41 1 9320000
+41 1 9340000
+41 1 9360000
+41 1 9380000
+41 1 9400000
+41 1 9420000
+41 1 9440000
+41 1 9460000
+41 1 9480000
+41 1 9500000
+41 1 9520000
+41 1 9540000
+41 1 9560000
+41 1 9580000
+41 1 9600000
+41 1 9620000
+41 1 9640000
+41 1 9660000
+41 1 9680000
+41 1 9700000
+41 1 9720000
+41 1 9740000
+41 1 9760000
+41 1 9780000
+41 1 9800000
+41 1 9820000
+41 1 9840000
+41 1 9860000
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_av1_176_144.av1 b/media/codec2/hidl/1.0/vts/functional/res/bbb_av1_176_144.av1
new file mode 100644
index 0000000..1d67af9
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_av1_176_144.av1
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_av1_176_144.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_av1_176_144.info
new file mode 100644
index 0000000..cc51168
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_av1_176_144.info
@@ -0,0 +1,300 @@
+6027 1 0
+6879 0 33000
+5 0 66000
+532 0 100000
+5 0 133000
+2458 0 166000
+5 0 200000
+475 0 233000
+5 0 266000
+1262 0 300000
+5 0 333000
+554 0 366000
+27 0 400000
+6971 0 433000
+5 0 466000
+601 0 500000
+5 0 533000
+3276 0 566000
+5 0 600000
+658 0 633000
+5 0 666000
+1680 0 700000
+5 0 733000
+610 0 766000
+24 0 800000
+6728 0 833000
+5 0 866000
+764 0 900000
+5 0 933000
+2656 0 966000
+5 0 1000000
+462 0 1033000
+5 0 1066000
+1459 0 1100000
+5 0 1133000
+608 0 1166000
+24 0 1200000
+7038 0 1233000
+5 0 1266000
+721 0 1300000
+5 0 1333000
+3102 0 1366000
+5 0 1400000
+752 0 1433000
+5 0 1466000
+1815 0 1500000
+5 0 1533000
+755 0 1566000
+25 0 1600000
+7657 0 1633000
+5 0 1666000
+852 0 1700000
+5 0 1733000
+3537 0 1766000
+5 0 1800000
+673 0 1833000
+5 0 1866000
+1774 0 1900000
+5 0 1933000
+554 0 1966000
+24 0 2000000
+8028 0 2033000
+5 0 2066000
+715 0 2100000
+5 0 2133000
+3395 0 2166000
+5 0 2200000
+736 0 2233000
+5 0 2266000
+1759 0 2300000
+5 0 2333000
+605 0 2366000
+23 0 2400000
+7651 0 2433000
+5 0 2466000
+619 0 2500000
+5 0 2533000
+2788 0 2566000
+5 0 2600000
+556 0 2633000
+5 0 2666000
+1335 0 2700000
+5 0 2733000
+521 0 2766000
+24 0 2800000
+2274 0 2833000
+676 0 2866000
+25 0 2900000
+6224 0 2933000
+5798 0 2966000
+5 0 3000000
+448 0 3033000
+5 0 3066000
+1950 0 3100000
+5 0 3133000
+386 0 3166000
+5 0 3200000
+1218 0 3233000
+5 0 3266000
+1316 0 3300000
+5 0 3333000
+580 0 3366000
+26 0 3400000
+6673 0 3433000
+5 0 3466000
+473 0 3500000
+5 0 3533000
+2467 0 3566000
+5 0 3600000
+429 0 3633000
+5 0 3666000
+1420 0 3700000
+5 0 3733000
+583 0 3766000
+29 0 3800000
+8492 0 3833000
+5 0 3866000
+720 0 3900000
+5 0 3933000
+3635 0 3966000
+5 0 4000000
+621 0 4033000
+5 0 4066000
+1969 0 4100000
+5 0 4133000
+49 0 4166000
+25 0 4200000
+7416 0 4233000
+5 0 4266000
+947 0 4300000
+5 0 4333000
+3713 0 4366000
+5 0 4400000
+714 0 4433000
+5 0 4466000
+2003 0 4500000
+5 0 4533000
+750 0 4566000
+25 0 4600000
+8470 0 4633000
+5 0 4666000
+737 0 4700000
+5 0 4733000
+4094 0 4766000
+5 0 4800000
+1019 0 4833000
+5 0 4866000
+2160 0 4900000
+5 0 4933000
+828 0 4966000
+24 0 5000000
+9282 0 5033000
+5 0 5066000
+655 0 5100000
+5 0 5133000
+3491 0 5166000
+5 0 5200000
+651 0 5233000
+5 0 5266000
+1906 0 5300000
+5 0 5333000
+662 0 5366000
+24 0 5400000
+9724 0 5433000
+5 0 5466000
+617 0 5500000
+5 0 5533000
+3145 0 5566000
+5 0 5600000
+578 0 5633000
+5 0 5666000
+1592 0 5700000
+5 0 5733000
+569 0 5766000
+25 0 5800000
+10015 0 5833000
+5 0 5866000
+609 0 5900000
+5 0 5933000
+3618 0 5966000
+5 0 6000000
+734 0 6033000
+5 0 6066000
+1748 0 6100000
+5 0 6133000
+550 0 6166000
+24 0 6200000
+8806 0 6233000
+5 0 6266000
+498 0 6300000
+5 0 6333000
+2913 0 6366000
+5 0 6400000
+597 0 6433000
+5 0 6466000
+1235 0 6500000
+5 0 6533000
+362 0 6566000
+24 0 6600000
+6592 0 6633000
+5 0 6666000
+468 0 6700000
+5 0 6733000
+1920 0 6766000
+5 0 6800000
+419 0 6833000
+5 0 6866000
+843 0 6900000
+5 0 6933000
+237 0 6966000
+24 0 7000000
+2687 0 7033000
+5 0 7066000
+399 0 7100000
+5 0 7133000
+200 0 7166000
+143 0 7200000
+25 0 7233000
+12603 0 7266000
+1139 0 7300000
+5 0 7333000
+56 0 7366000
+5 0 7400000
+273 0 7433000
+5 0 7466000
+48 0 7500000
+5 0 7533000
+102 0 7566000
+5 0 7600000
+39 0 7633000
+24 0 7666000
+3635 0 7700000
+5 0 7733000
+46 0 7766000
+5 0 7800000
+647 0 7833000
+5 0 7866000
+61 0 7900000
+5 0 7933000
+824 0 7966000
+5 0 8000000
+691 0 8033000
+27 0 8066000
+4573 0 8100000
+5 0 8133000
+473 0 8166000
+5 0 8200000
+1637 0 8233000
+5 0 8266000
+451 0 8300000
+5 0 8333000
+969 0 8366000
+5 0 8400000
+234 0 8433000
+24 0 8466000
+3361 0 8500000
+5 0 8533000
+168 0 8566000
+5 0 8600000
+662 0 8633000
+5 0 8666000
+129 0 8700000
+5 0 8733000
+443 0 8766000
+5 0 8800000
+183 0 8833000
+23 0 8866000
+2769 0 8900000
+5 0 8933000
+182 0 8966000
+5 0 9000000
+890 0 9033000
+5 0 9066000
+171 0 9100000
+5 0 9133000
+599 0 9166000
+5 0 9200000
+236 0 9233000
+23 0 9266000
+2316 0 9300000
+5 0 9333000
+333 0 9366000
+5 0 9400000
+759 0 9433000
+5 0 9466000
+210 0 9500000
+5 0 9533000
+324 0 9566000
+5 0 9600000
+98 0 9633000
+23 0 9666000
+1107 0 9700000
+5 0 9733000
+42 0 9766000
+5 0 9800000
+145 0 9833000
+5 0 9866000
+109 0 9900000
+89 0 9933000
+24 0 9966000
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_av1_640_360.av1 b/media/codec2/hidl/1.0/vts/functional/res/bbb_av1_640_360.av1
new file mode 100644
index 0000000..529bace
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_av1_640_360.av1
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_av1_640_360.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_av1_640_360.info
new file mode 100644
index 0000000..fca7833
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_av1_640_360.info
@@ -0,0 +1,167 @@
+12571 1 0
+9881 0 33000
+5 0 66000
+544 0 100000
+5 0 133000
+2642 0 166000
+5 0 200000
+531 0 233000
+5 0 266000
+1359 0 300000
+5 0 333000
+551 0 366000
+28 0 400000
+10791 0 433000
+5 0 466000
+655 0 500000
+5 0 533000
+3769 0 566000
+5 0 600000
+711 0 633000
+5 0 666000
+2004 0 700000
+5 0 733000
+657 0 766000
+26 0 800000
+8969 0 833000
+5 0 866000
+630 0 900000
+5 0 933000
+2787 0 966000
+5 0 1000000
+404 0 1033000
+5 0 1066000
+1518 0 1100000
+5 0 1133000
+493 0 1166000
+26 0 1200000
+9900 0 1233000
+5 0 1266000
+620 0 1300000
+5 0 1333000
+3072 0 1366000
+5 0 1400000
+668 0 1433000
+5 0 1466000
+1821 0 1500000
+5 0 1533000
+682 0 1566000
+26 0 1600000
+9560 0 1633000
+5 0 1666000
+667 0 1700000
+5 0 1733000
+3249 0 1766000
+5 0 1800000
+589 0 1833000
+5 0 1866000
+1816 0 1900000
+5 0 1933000
+548 0 1966000
+26 0 2000000
+9916 0 2033000
+5 0 2066000
+628 0 2100000
+5 0 2133000
+3034 0 2166000
+5 0 2200000
+590 0 2233000
+5 0 2266000
+1581 0 2300000
+5 0 2333000
+524 0 2366000
+26 0 2400000
+8182 0 2433000
+5 0 2466000
+552 0 2500000
+5 0 2533000
+2412 0 2566000
+5 0 2600000
+489 0 2633000
+5 0 2666000
+1227 0 2700000
+5 0 2733000
+432 0 2766000
+26 0 2800000
+2017 0 2833000
+516 0 2866000
+26 0 2900000
+16619 0 2933000
+6710 0 2966000
+5 0 3000000
+425 0 3033000
+5 0 3066000
+1964 0 3100000
+5 0 3133000
+386 0 3166000
+5 0 3200000
+1129 0 3233000
+5 0 3266000
+1156 0 3300000
+5 0 3333000
+486 0 3366000
+28 0 3400000
+10304 0 3433000
+5 0 3466000
+412 0 3500000
+5 0 3533000
+2608 0 3566000
+5 0 3600000
+397 0 3633000
+5 0 3666000
+1514 0 3700000
+5 0 3733000
+533 0 3766000
+26 0 3800000
+11698 0 3833000
+5 0 3866000
+542 0 3900000
+5 0 3933000
+3334 0 3966000
+5 0 4000000
+547 0 4033000
+5 0 4066000
+1809 0 4100000
+5 0 4133000
+55 0 4166000
+26 0 4200000
+9496 0 4233000
+5 0 4266000
+658 0 4300000
+5 0 4333000
+3232 0 4366000
+5 0 4400000
+600 0 4433000
+5 0 4466000
+1766 0 4500000
+5 0 4533000
+550 0 4566000
+25 0 4600000
+9951 0 4633000
+5 0 4666000
+624 0 4700000
+5 0 4733000
+3617 0 4766000
+5 0 4800000
+644 0 4833000
+5 0 4866000
+1841 0 4900000
+5 0 4933000
+649 0 4966000
+25 0 5000000
+9901 0 5033000
+5 0 5066000
+515 0 5100000
+5 0 5133000
+2814 0 5166000
+5 0 5200000
+511 0 5233000
+5 0 5266000
+1521 0 5300000
+5 0 5333000
+509 0 5366000
+26 0 5400000
+10579 0 5433000
+5 0 5466000
+575 0 5500000
+5 0 5533000
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_avc_176x144_300kbps_60fps.h264 b/media/codec2/hidl/1.0/vts/functional/res/bbb_avc_176x144_300kbps_60fps.h264
new file mode 100644
index 0000000..da1e75d
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_avc_176x144_300kbps_60fps.h264
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_avc_176x144_300kbps_60fps.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_avc_176x144_300kbps_60fps.info
new file mode 100644
index 0000000..5456309
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_avc_176x144_300kbps_60fps.info
@@ -0,0 +1,62 @@
+28 32 0
+10 32 0
+4780 1 33333
+960 0 100000
+480 0 66666
+246 0 50000
+264 0 83333
+1160 0 166666
+404 0 133333
+237 0 116666
+193 0 150000
+936 0 233333
+384 0 200000
+199 0 183333
+275 0 216666
+1086 0 300000
+520 0 266666
+301 0 250000
+270 0 283333
+1232 0 366666
+559 0 333333
+287 0 316666
+274 0 350000
+1084 0 433333
+485 0 400000
+307 0 383333
+284 0 416666
+1052 0 500000
+504 0 466666
+298 0 450000
+327 0 483333
+1189 0 566666
+358 0 533333
+172 0 516666
+185 0 550000
+1115 0 633333
+463 0 600000
+218 0 583333
+255 0 616666
+1155 0 700000
+622 0 666666
+356 0 650000
+341 0 683333
+1240 0 766666
+610 0 733333
+341 0 716666
+380 0 750000
+1326 0 833333
+620 0 800000
+396 0 783333
+353 0 816666
+1196 0 900000
+623 0 866666
+375 0 850000
+362 0 883333
+1192 0 966666
+654 0 933333
+359 0 916666
+352 0 950000
+828 0 1016666
+436 0 983333
+401 0 1000000
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_avc_640x360_768kbps_30fps.h264 b/media/codec2/hidl/1.0/vts/functional/res/bbb_avc_640x360_768kbps_30fps.h264
new file mode 100644
index 0000000..1d8c68f
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_avc_640x360_768kbps_30fps.h264
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_avc_640x360_768kbps_30fps.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_avc_640x360_768kbps_30fps.info
new file mode 100644
index 0000000..b5f3b9b
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_avc_640x360_768kbps_30fps.info
@@ -0,0 +1,242 @@
+29 32 0
+9 32 0
+38469 1 66666
+3270 0 200000
+443 0 133333
+246 0 100000
+214 0 166666
+2280 0 300000
+368 0 233333
+238 0 266666
+688 0 433333
+287 0 366666
+234 0 333333
+172 0 400000
+1363 0 566666
+273 0 500000
+166 0 466666
+182 0 533333
+3731 0 700000
+349 0 633333
+216 0 600000
+229 0 666666
+6061 0 833333
+408 0 766666
+271 0 733333
+241 0 800000
+7004 0 966666
+442 0 900000
+261 0 866666
+229 0 933333
+7354 0 1100000
+404 0 1033333
+264 0 1000000
+198 0 1066666
+4542 0 1233333
+286 0 1166666
+205 0 1133333
+131 0 1200000
+3329 0 1333333
+216 0 1266666
+136 0 1300000
+2353 0 1366666
+986 0 1400000
+808 0 1433333
+318 0 1466666
+62 0 1500000
+55649 1 1533333
+1606 0 1566666
+2935 0 1600000
+3564 0 1633333
+3324 0 1666666
+4543 0 1700000
+1740 0 1733333
+2737 0 1766666
+2762 0 1800000
+3185 0 1833333
+3238 0 1866666
+3395 0 1900000
+3421 0 1933333
+3482 0 1966666
+3370 0 2000000
+3656 0 2033333
+3509 0 2066666
+3684 0 2100000
+3732 0 2133333
+3366 0 2166666
+3374 0 2200000
+3202 0 2233333
+3449 0 2266666
+3360 0 2300000
+3372 0 2333333
+3460 0 2366666
+3511 0 2400000
+3471 0 2433333
+3330 0 2466666
+3377 0 2500000
+3744 0 2533333
+3667 0 2566666
+3867 0 2600000
+3776 0 2633333
+3329 0 2666666
+3876 0 2700000
+3385 0 2733333
+3566 0 2766666
+3301 0 2800000
+3570 0 2833333
+3132 0 2866666
+3487 0 2900000
+3270 0 2933333
+3472 0 2966666
+3487 0 3000000
+3503 0 3033333
+3443 0 3066666
+3528 0 3100000
+3258 0 3133333
+3707 0 3166666
+3120 0 3200000
+3347 0 3233333
+3372 0 3266666
+3161 0 3300000
+3393 0 3333333
+3399 0 3366666
+2905 0 3400000
+3543 0 3433333
+3103 0 3466666
+3099 0 3500000
+3457 0 3533333
+3191 0 3566666
+3290 0 3600000
+3312 0 3633333
+2955 0 3666666
+3341 0 3700000
+3102 0 3733333
+3186 0 3766666
+3180 0 3800000
+2839 0 3833333
+3089 0 3866666
+3110 0 3900000
+3165 0 3933333
+2684 0 3966666
+3082 0 4000000
+2694 0 4033333
+3051 0 4066666
+3002 0 4100000
+2929 0 4133333
+2676 0 4166666
+2411 0 4200000
+2874 0 4233333
+2572 0 4266666
+2420 0 4300000
+2500 0 4333333
+2137 0 4366666
+2344 0 4400000
+2028 0 4433333
+1754 0 4466666
+1627 0 4500000
+1375 0 4533333
+1069 0 4566666
+801 0 4600000
+21689 1 4633333
+261 0 4733333
+76 0 4666666
+45 0 4700000
+334 0 4800000
+61 0 4766666
+1577 0 4933333
+280 0 4866666
+72 0 4833333
+479 0 4900000
+2181 0 5066666
+919 0 5000000
+349 0 4966666
+534 0 5033333
+4860 0 5166666
+759 0 5100000
+677 0 5133333
+3101 0 5300000
+498 0 5233333
+327 0 5200000
+213 0 5266666
+1640 0 5433333
+259 0 5366666
+162 0 5333333
+148 0 5400000
+2130 0 5566666
+397 0 5500000
+191 0 5466666
+180 0 5533333
+1757 0 5700000
+338 0 5633333
+194 0 5600000
+141 0 5666666
+1103 0 5833333
+289 0 5766666
+149 0 5733333
+148 0 5800000
+3914 0 5966666
+1025 0 5900000
+714 0 5866666
+428 0 5933333
+4604 0 6100000
+1456 0 6033333
+699 0 6000000
+892 0 6066666
+4535 0 6233333
+1301 0 6166666
+708 0 6133333
+592 0 6200000
+2175 0 6333333
+603 0 6266666
+411 0 6300000
+1813 0 6366666
+5055 0 6466666
+1538 0 6400000
+2201 0 6433333
+6249 0 6533333
+1420 0 6500000
+2254 0 6566666
+2441 0 6633333
+293 0 6600000
+2062 0 6700000
+213 0 6666666
+2455 0 6800000
+344 0 6733333
+204 0 6766666
+3920 0 6933333
+751 0 6866666
+376 0 6833333
+337 0 6900000
+2882 0 7066666
+457 0 7000000
+222 0 6966666
+184 0 7033333
+2734 0 7200000
+472 0 7133333
+185 0 7100000
+250 0 7166666
+2735 0 7333333
+301 0 7266666
+307 0 7233333
+109 0 7300000
+1852 0 7466666
+322 0 7400000
+153 0 7366666
+195 0 7433333
+1506 0 7600000
+350 0 7533333
+170 0 7500000
+145 0 7566666
+2123 0 7733333
+430 0 7666666
+364 0 7633333
+190 0 7700000
+1296 0 7800000
+196 0 7766666
+858 0 7833333
+3865 0 7933333
+693 0 7866666
+1606 0 7900000
+4884 0 7966666
+2821 0 8033333
+2211 0 8000000
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_flac_stereo_680kbps_48000hz.flac b/media/codec2/hidl/1.0/vts/functional/res/bbb_flac_stereo_680kbps_48000hz.flac
new file mode 100644
index 0000000..db94d8e
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_flac_stereo_680kbps_48000hz.flac
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_flac_stereo_680kbps_48000hz.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_flac_stereo_680kbps_48000hz.info
new file mode 100644
index 0000000..0355295
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_flac_stereo_680kbps_48000hz.info
@@ -0,0 +1,415 @@
+42 32 0
+1386 1 0
+2401 1 24000
+2321 1 48000
+2367 1 72000
+2370 1 96000
+2334 1 120000
+2396 1 144000
+2375 1 168000
+2431 1 192000
+2428 1 216000
+2334 1 240000
+2261 1 264000
+2124 1 288000
+2152 1 312000
+2295 1 336000
+2183 1 360000
+2393 1 384000
+2400 1 408000
+2246 1 432000
+2289 1 456000
+2400 1 480000
+2335 1 504000
+2294 1 528000
+2260 1 552000
+2206 1 576000
+2185 1 600000
+2155 1 624000
+2118 1 648000
+2094 1 672000
+2050 1 696000
+2059 1 720000
+2030 1 744000
+2022 1 768000
+2078 1 792000
+2082 1 816000
+2094 1 840000
+2111 1 864000
+2043 1 888000
+2023 1 912000
+2024 1 936000
+2056 1 960000
+2108 1 984000
+2138 1 1008000
+2140 1 1032000
+2111 1 1056000
+2110 1 1080000
+2137 1 1104000
+2157 1 1128000
+2174 1 1152000
+2200 1 1176000
+2203 1 1200000
+2237 1 1224000
+2261 1 1248000
+2215 1 1272000
+2133 1 1296000
+2091 1 1320000
+2088 1 1344000
+2122 1 1368000
+2139 1 1392000
+2146 1 1416000
+2231 1 1440000
+2282 1 1464000
+2273 1 1488000
+2304 1 1512000
+2292 1 1536000
+2255 1 1560000
+2181 1 1584000
+2081 1 1608000
+2012 1 1632000
+2011 1 1656000
+2066 1 1680000
+2069 1 1704000
+2120 1 1728000
+2141 1 1752000
+2148 1 1776000
+2181 1 1800000
+2176 1 1824000
+2240 1 1848000
+2297 1 1872000
+2325 1 1896000
+2336 1 1920000
+2329 1 1944000
+2299 1 1968000
+2322 1 1992000
+2347 1 2016000
+2287 1 2040000
+2286 1 2064000
+2269 1 2088000
+2320 1 2112000
+2305 1 2136000
+2384 1 2160000
+2429 1 2184000
+2370 1 2208000
+2365 1 2232000
+2361 1 2256000
+2370 1 2280000
+2393 1 2304000
+2342 1 2328000
+2325 1 2352000
+2334 1 2376000
+2316 1 2400000
+2317 1 2424000
+2305 1 2448000
+2360 1 2472000
+2331 1 2496000
+2332 1 2520000
+2361 1 2544000
+2417 1 2568000
+2438 1 2592000
+2403 1 2616000
+2386 1 2640000
+2382 1 2664000
+2350 1 2688000
+2355 1 2712000
+2383 1 2736000
+2384 1 2760000
+2383 1 2784000
+2373 1 2808000
+2374 1 2832000
+2347 1 2856000
+2353 1 2880000
+2381 1 2904000
+2401 1 2928000
+2401 1 2952000
+2385 1 2976000
+2382 1 3000000
+2328 1 3024000
+2303 1 3048000
+2272 1 3072000
+2270 1 3096000
+2312 1 3120000
+2273 1 3144000
+2330 1 3168000
+2339 1 3192000
+2296 1 3216000
+2317 1 3240000
+2440 1 3264000
+2353 1 3288000
+2346 1 3312000
+2303 1 3336000
+2308 1 3360000
+2287 1 3384000
+2316 1 3408000
+2367 1 3432000
+2335 1 3456000
+2350 1 3480000
+2395 1 3504000
+2408 1 3528000
+2413 1 3552000
+2415 1 3576000
+2468 1 3600000
+2437 1 3624000
+2372 1 3648000
+2371 1 3672000
+2341 1 3696000
+2328 1 3720000
+2273 1 3744000
+2244 1 3768000
+2233 1 3792000
+2229 1 3816000
+2252 1 3840000
+2236 1 3864000
+2217 1 3888000
+2179 1 3912000
+2251 1 3936000
+2192 1 3960000
+2199 1 3984000
+2212 1 4008000
+2190 1 4032000
+2102 1 4056000
+2120 1 4080000
+2167 1 4104000
+2024 1 4128000
+2010 1 4152000
+2067 1 4176000
+2035 1 4200000
+2051 1 4224000
+2012 1 4248000
+2066 1 4272000
+2025 1 4296000
+1987 1 4320000
+1972 1 4344000
+1966 1 4368000
+1999 1 4392000
+1987 1 4416000
+1922 1 4440000
+2020 1 4464000
+2072 1 4488000
+2021 1 4512000
+2017 1 4536000
+2099 1 4560000
+2064 1 4584000
+2109 1 4608000
+2093 1 4632000
+2090 1 4656000
+2148 1 4680000
+2184 1 4704000
+2179 1 4728000
+2152 1 4752000
+2143 1 4776000
+2159 1 4800000
+2123 1 4824000
+2129 1 4848000
+2147 1 4872000
+2192 1 4896000
+2051 1 4920000
+2116 1 4944000
+2124 1 4968000
+2088 1 4992000
+2073 1 5016000
+2146 1 5040000
+2133 1 5064000
+2073 1 5088000
+2059 1 5112000
+2044 1 5136000
+2012 1 5160000
+2034 1 5184000
+2053 1 5208000
+2013 1 5232000
+1981 1 5256000
+2094 1 5280000
+2076 1 5304000
+1968 1 5328000
+2028 1 5352000
+2031 1 5376000
+2020 1 5400000
+2019 1 5424000
+2030 1 5448000
+2015 1 5472000
+1962 1 5496000
+2070 1 5520000
+2087 1 5544000
+1964 1 5568000
+2069 1 5592000
+2034 1 5616000
+1994 1 5640000
+1985 1 5664000
+2030 1 5688000
+2066 1 5712000
+1954 1 5736000
+1733 1 5760000
+1649 1 5784000
+1652 1 5808000
+1631 1 5832000
+1656 1 5856000
+1672 1 5880000
+1667 1 5904000
+1696 1 5928000
+1672 1 5952000
+1701 1 5976000
+1651 1 6000000
+1674 1 6024000
+1695 1 6048000
+1702 1 6072000
+1707 1 6096000
+1694 1 6120000
+1727 1 6144000
+1730 1 6168000
+1708 1 6192000
+1704 1 6216000
+1735 1 6240000
+1758 1 6264000
+1753 1 6288000
+1748 1 6312000
+1763 1 6336000
+1737 1 6360000
+1783 1 6384000
+1839 1 6408000
+1861 1 6432000
+1832 1 6456000
+1947 1 6480000
+1939 1 6504000
+1926 1 6528000
+1896 1 6552000
+1909 1 6576000
+1869 1 6600000
+1900 1 6624000
+1896 1 6648000
+1883 1 6672000
+1903 1 6696000
+1895 1 6720000
+1865 1 6744000
+1878 1 6768000
+1881 1 6792000
+1861 1 6816000
+1791 1 6840000
+1787 1 6864000
+1798 1 6888000
+1811 1 6912000
+1824 1 6936000
+1895 1 6960000
+2079 1 6984000
+2034 1 7008000
+2038 1 7032000
+2018 1 7056000
+2030 1 7080000
+2067 1 7104000
+1982 1 7128000
+1911 1 7152000
+1904 1 7176000
+1874 1 7200000
+1876 1 7224000
+1944 1 7248000
+1977 1 7272000
+1977 1 7296000
+1979 1 7320000
+2012 1 7344000
+1961 1 7368000
+1773 1 7392000
+1780 1 7416000
+1801 1 7440000
+1892 1 7464000
+1869 1 7488000
+1936 1 7512000
+2154 1 7536000
+2226 1 7560000
+2159 1 7584000
+2253 1 7608000
+2286 1 7632000
+2214 1 7656000
+2111 1 7680000
+2027 1 7704000
+1994 1 7728000
+1882 1 7752000
+1887 1 7776000
+1993 1 7800000
+1962 1 7824000
+1982 1 7848000
+1966 1 7872000
+1962 1 7896000
+1928 1 7920000
+1878 1 7944000
+1857 1 7968000
+1885 1 7992000
+1919 1 8016000
+1904 1 8040000
+1909 1 8064000
+1909 1 8088000
+1933 1 8112000
+1824 1 8136000
+1756 1 8160000
+1733 1 8184000
+1705 1 8208000
+1755 1 8232000
+1756 1 8256000
+1725 1 8280000
+1761 1 8304000
+1736 1 8328000
+1706 1 8352000
+1662 1 8376000
+1604 1 8400000
+1613 1 8424000
+1692 1 8448000
+1736 1 8472000
+1779 1 8496000
+1768 1 8520000
+1758 1 8544000
+1708 1 8568000
+1642 1 8592000
+1645 1 8616000
+1581 1 8640000
+1651 1 8664000
+1731 1 8688000
+1743 1 8712000
+1717 1 8736000
+1715 1 8760000
+1646 1 8784000
+1551 1 8808000
+1563 1 8832000
+1649 1 8856000
+1742 1 8880000
+1724 1 8904000
+1676 1 8928000
+1664 1 8952000
+1587 1 8976000
+1497 1 9000000
+1503 1 9024000
+1644 1 9048000
+1658 1 9072000
+1680 1 9096000
+1611 1 9120000
+1694 1 9144000
+1668 1 9168000
+1677 1 9192000
+1604 1 9216000
+1567 1 9240000
+1639 1 9264000
+1552 1 9288000
+1486 1 9312000
+1494 1 9336000
+1480 1 9360000
+1509 1 9384000
+1457 1 9408000
+1423 1 9432000
+1459 1 9456000
+1444 1 9480000
+1424 1 9504000
+1413 1 9528000
+1498 1 9552000
+1455 1 9576000
+1393 1 9600000
+1638 1 9624000
+1919 1 9648000
+1979 1 9672000
+1894 1 9696000
+2002 1 9720000
+2062 1 9744000
+2098 1 9768000
+1919 1 9792000
+1738 1 9816000
+1890 1 9840000
+1971 1 9864000
+2429 1 9888000
+1861 1 9912000
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_g711alaw_1ch_8khz.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_g711alaw_1ch_8khz.info
new file mode 100644
index 0000000..66e5480
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_g711alaw_1ch_8khz.info
@@ -0,0 +1,10 @@
+8192 1 0
+8192 1 1024000
+8192 1 2048000
+8192 1 3072000
+8192 1 4096000
+8192 1 5120000
+8192 1 6144000
+8192 1 7168000
+8192 1 8192000
+5462 1 9216000
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_g711alaw_1ch_8khz.raw b/media/codec2/hidl/1.0/vts/functional/res/bbb_g711alaw_1ch_8khz.raw
new file mode 100644
index 0000000..cfc4a11
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_g711alaw_1ch_8khz.raw
@@ -0,0 +1 @@
+kogOÇÅØÕJvCusXÓÕIvJ~}KuY]ÁÈÄôôôÊØIrtBRTóùÇÚÆÖTÅùììãÿÕOeb}ÙþíéëáÁ[sggDôåàààåÆ^LLKeZQIÙ÷ñóPvxnmpUäíäþÜ`hfvùèïæçÃugmtewX[ß_XØÄÔÏÏØÁXÐÖyegqRÛøåÿáøTGesF|OÂõÉÐYßYuÂæï•æÈJkkwø됗çÇwbimLùäæìäØCz|ybpÃåãçáèø[vxxJBôÿõþô]qgau_ÝûàãåÂÆVe|UÁTOpIp`dqÐôÁ÷äØLBFKrevtysgf}sOÔBqRÜÜFqÜÍNNMqwZÂûçåûôÙsiaØûãèêíý[ebfÜä闕èïøYxdx|J÷çäè”êâØsxgffyÄüÙPLdf{OÚÌöñÑ@q`oz@ÎåÿËÚ_}blCðåçùÝFfimbd[ÍäåVFHr||dv\ØÇ_EÛÖIpa~ÐöúãçðR|`opñí”íøôDdnkdÝ䗖•ëîýÕppCDØöñÍÉÄöñÝ[ÇÃS{RÓÜÌÏTÜSWÔPÕÎÉÈÕvFEV÷øÍ]qKrcgUäíçÆÔH`knc~wÃûÉSACwxcfdx~{fgg|Ldf|ÓõÅÕö÷ÐMgggFç闑‘—áB}LÜ헓œ“•íÔx|uôåõñüÒÅÛÀñSu\qfg{XÄAsKw[WM^Xsvra}EÍàøñÿSr}`erOåéàçö\tjjdÙáæúÌvfoj`CÑóðSNszxcg`}ÙßÁçäçÈxz|@üäåâÿØUsHÖäîèêâæáøØ^QÄö÷ÂÆñòóØÐÌÎÏÃDygfsDÙòþæîçÇ_ZßWMv}OÓXDÜÉÈWxbkmLßþåÀNdisÖÛÝMvNdczuGPÎýüùðPv~e@ÌäáäÿûÂÕÓuPð÷ÏÆôàÿÐ]ycdpÍííïáð\daEÊúæùÐDZ^TÆà”êäõZurd|WÄúãë—àüðP{acHÌðùÄKsckibwÖÒW^Ô|nkjkaAÍÃß]Sdln}Å÷ÿúÊAu~rrXüçõÈÃýçýääñ×DEÇÕÏáíàÊFBDIÖÖÆÂÛÝÝSUÓÝ\uJB\_]U^@PØøúÌËÌD}gHå핖êïäñúÿñåçæäþáîàûÛ~kbZÉúìîðgkgsydooaqWÔÑF|aieRÀ÷ÿü÷IdepDÝÁË×wtH\ÆÁ÷çøðÇÝÛWv|feUòåûûçåQJKSöà•—ïÃ@syrÔ唔ìãääãæ÷ÀÕðäá藕ïûÂöÀÚÄÅSXqRÃÜÜZq}{cblzNJsyok`q_UA{ikcH@}fd_ÚÈÍÔWQrA×ßÍÈÏ^~NÆÑÚöñýþó÷ZCÑðæåôõùÂNv\×WÅøáàâåGfmbEå두‘•üÈÆAÓäíèâàì÷PSSÌ÷QPÄÏÚÅÂßghbe|vEqxcnkom|FFwd|ufhdzspKPKGSAtadMÂÛÄÁÈF|t\òí•àÌYVSßßÃËÍÂØËøûÀÊÒ}maHÙÎçìíàÎM|qrJZÄÇËäáäåäñÒõãï蔗îý_K_Ï÷ØØÂÚSØÅQIEweddxx}aocd~sz{J}njmxPöþòÜGJI^ÅñåðÒôÍQZDFÖõåçÍÐÛHdli{^\ÛúåóDyrbn}[UÀÞôãæçûW×ÇÄ픗“éúÃÈæåçéäùý×ÁÍÔÞóÎÜwzE^HRNwA}pAsx~ljj|@w\Ozxzt\sfef~KH÷ûÃQAOXÖöøòõÇ[CvgIÙöùóÇÐFuÑÖ@RÜT×TÇöðPygvqMöýþçàíáÞ@psNWËåäúýËñÁÌåüÄþúþÊÍÖT×ÝóùæúÊÓZxep^ßUÖÛXKRvMWWÉÓXGJA~``bbXðåùÆÓPeavqÑÿÉÂÏqcfdfeesJÒUrljhgMýáÉÕ×vMwlfPUÀóÆÚÀþïëãúÀÚóúããùøáúâìçàãÈÍðÑL]ÅøåôñÈþóÑßÃN×ÉØ÷[fyr`~|gfK^ÚÒNJH@s||jawqtH|ÚÙdLqfpX_þ÷Sqy~zwÍüÿíýPdhisYÉæýÅÅÊÈþÞwwÐTUðûóÇÑFYJpCóóöÌEI\ÒóàååæãýËÎXuÅÌÃÿðüãà÷_yyuÏ픔çFr|eLQDÏøÛØÞfeKBws|uBtB}`rI|YYBôÖ~s`jeATÐZBMFÝV^ÍXuVFw[s|@OBÖLrØÉñøÎ@[RÎþÿúÖDØÔÅãáï”àòÎ\ÆçäãþÖ@YÚÿçìãòóÕe`zzEØ÷øä÷ÅÎßÆUupFÙúä÷@~vpv×ÞVöÌPKefpHIryvuL|amkj`ex}cmmcdSÿçåÉHxy~×ñõÌæàûþóýæàíêïçùæáúðýåãèíãàÉÒÅÅðåäåúÀBrvpyx}I\ÞÊòSggrtQÞßöø÷ÑPws_ÊÂCsegzz{pee}{dze|s`lcglha{a`bjla~}gsÒþàæöÚÅÇóäåýçéîàááãèêêêéãìèïæùþåçáâîãùÿÄM}|eerqDD}aa~|IDÜõûúÏ|laz~wGWÍôÍÚY~sLGCDÑPEFNv|uÞÍÚØ[sdonmih`abiiagdp_ÕPDKMÑýâéìíꑖ‘“œœŸ’–èàççàãáûÉuggpIßÎÝÖÔRF|c`d~suOÔÃööÁP}sWÞÕÜQETÓÞÊß@Nsyyddffacbbz_\DE|gf`f|`lbnniknlg|spBSÃÜßÞ^ÑÏðùäóýáçúääìî떓—”îèèꔕ–‘—•äÛÔÚÄÃôËóñÿùÜt}p\ÍóñùýÌÌTVMsI_LuK|zzdgmiolgd`lncfdzflii~LSVEXÑÝÕX@GTòäå÷ÆÆÏÄÂòýðòóõÉØÑÜ÷ËöüüüÿæáåöÎÈôüæãããéê•ïþùáíæååúåàîïçóòçæäçýóõÏÂU}mhhmojjhinjjo|LvBST×_s{d}Y×ßR\ÑVPYqpMÜùçöÇõüúäáçøþûìèãþÄÜÑSÐÔØñåçþWtGZÉæàíæøúôÓGFÛ÷óåáåÿóüùôñðûììèâþòËÊÀ^tzgzypga|{psd~glikmobammbobaw×ÞÃAtEqZßD^ÓÆåçýðôóö÷üÙPÊþáâûòòðþæàçþäøûçñôüñúïììîè•íóDz\ÃðíäÎÈÑWÇTÑüäãâãáõËÅXXqd|qpLuajngtrc`nkmxyeailfcafim~}F@}}ddd{|rVóäàåÛWØÎÿääþÏðóöüÙÅóúé•ãÿñõËõ÷ÊðáâãéûÏþûûýôËÉñÊÃ÷ÏÚýååçýöúäíèãñ_QU[ÑSqqrytt~|wFwajjocaafdbcfbqÁÀÈØQÑÑPÖÔLJQÎüû÷^NJp\ÅÊÏÍõÙVYFÔýæìãüùççâæùçæâíéèàææûñÌÇÃüûæú÷ÂBZÑôþõþúùæýÖ[RÚÞÑ^Ig`blxgfy}Gugac`aa`afey~H~dsJ]^NpevHsqwp{g{IwswITÖNdIßÄó÷×[RÞÿçþôõüòÂÈ÷ûâáæäüþüä藕áãàçäúòú••—–”èäææçåÉõôÂÇw`b||tgmhakkcdqfxxuDydinbduXÅusqa|e~v_ÉÚÞC~c`O×öÝXÔvEv{|pPQÊÍBq}Z]ÇÍËåùáæäàúâããíçæäçâéìàíçàæøæýùúúåÀS_õãïìáþUy|_FAT_Ing}CBppxdad~z|pAtdgeSDuO|pyx|FRMÒÁôÇLqyÖÉôÌZ[daeFKZ\ÝÁZpz×ÊÊýÅÏTITÓúùðùøåÏÃÞÿããïçááñ÷ÉæíãâàìäôÛôíë•ãäòWÖVßÛÖÓRÒXxmhm`eaduxdv@v|dptdmib{uyg{ccf|EQÃÔ_Xr{^ðåùQApafUÓÑD@ÖJrztÌõóõÂÎÙÚÀÿåæãçáääþöáãîîàáåçäíîææûøñÆ]AóùÿøÙÖ@[[R÷ÀÄÇPw}dkasLÃPu{ysÝÕDGsg``igAtMqbkkinrCIXursvxuÎ÷òöPHIB}HAs]ÞÜÒÕsetNõãæåòÃPÚñÇôýñýÿÎPòæâêâøúæçâëâíìúñÊöÁøáÿäÉv~~ywÈ÷ôýÓGLp`awvÝÁ@Bvdb~tsÕÑY]\qd|zvDzdgabbgcyCKtp{ctRÑ÷PAvxgfBJL@}{zcy_Ààçý÷ñüýïîíìúýÌÌÔÝùäíàíëë•ìëëâïãàûóÅRÌöûþÚZr}esSVÄÑTM~aizLÀóõÆEM}rA@MBHHqq{~@SÕCLprdlc```dzspdeGÑÄÑFr`cbxHpsDXLJuuÃäãéãÿÃÃUÖðúùùýÂÓBy@ÉôúìëííáçíáçãèîãâòôúþüÚMaf{dBÓPDÜËÚÄHvÛÒÒÕÚB|JATÔÙÀ÷Mq~`}sGTÖBadoo`aeeFCu}beKÕÁÂÄtMvtZpxdqIxeb{uBÛÁýÄÀ÷ÉûûøäåçñÀ\GßÚøøçäúçûãïïâïëéæòÇÊÃñÎ_qlggt^ÝÚ÷ý÷Ô^ÓýçäñùÝGxxtG]uQZylnicr[CPvzdd{~[qGÐ×tygeBÖK@Zswt]KSuCÜRve}q^ðõÄÄGLMÝÓåìúåÉÔLOPÂãìäçõSFÉÿûíäïïäËÁñýâéåýWreHqÍÈõÎVKpÕÞöãûöÙ|``I]ÃôÉÌ\rduO^ÆÚÕOgcaquAÒÑTpcjieVÐ^vfm`JÒÀÉÍßJfkfJÑüóóÙ}lopÆúïììüÓBSÒÄàëêàñ×ZÅüà••––îüÚÍõçàäö[ebfvEÃõÎÆJ~~L×ôààóV}dgwÙ÷ôMxboio{FðûÛw`knsZÛ×Ñ^xb`wÛøÈ\q|s|ÙþíâþôÚØG\Åôû÷_p{d`MõóðÉÍÞÓÑÚñûãâðXv@@_öþæåóüü÷ÞÉáàçßry{pËæçòÚÆÝTÜÄþýøóArxqKÙðËÞJNMuKwÅñÉÜ{fmlbeCGBKt|fa{KLp@}gcdKVØÇÚRBC\ÖÓÅØÓÜOeyKÞøüÃQYP]S÷àìâãåÃFMÇòáæáæòõ÷óøáíàþÈ×L{}qÛýÉÃÞÈôÉöøäðÅÍÄCzqtEYex{y~CFÑÁ]BsebzrÝFregdqDØñDtAvgdMSöô×ÖC_ÜùæüçðØZyggwwWÃAv|O\Õ÷òíæÃÝ_@BÒÎðåòÌÖÖÄòäûäçðÌÓÒTÛÏóáåÃ@\ÀðþúããüÙY^uCÜËýÀ[xadwÞðççñEciibrqAI{nlxBÐÓÒDygzt}LRÓÒNxceZÝñ÷ÃËÅ[uABÑÛ]QLpgx×ÊæííãüÞÖõòþâíïæÏXNÜôáîàçþÃ^BGFÛÂÂÙ@~fpÑþáåøõULNÔÔÍÉÓ×sf`eDÚÿóÈÖNw|uFYPtpzmio{GÁUGGBY_ÛÂÚÆÜÛEyzyZßüääþÃÕDF_ÑÆVGr`lozÕûæåóßEuHÑÍõÏñÀu{xFÓóçççüñåùåæàæûòÏÆÚÀòçúÇUÕGEÑÉåúôÜÑtdeYÌñ÷÷ÚwqLsHAC}eljorÕ@wHrxp}]ÎÞTVXyewMÐñÌÑÒux_ÜÂüäòÑ[x~wp×ÿþÏÂÈÊåääíìåõ÷×HRQÒýùõ÷òÀôùüåäþÍÐEq@HwÜö×JtrtUÛòáåÜQ@z`gsÒöÆËöÛ]ÐÑ\×Ôt}`jjinopJ|wI^ÆôüççñÊÎÀÆÐÕ×ÂØAGBtZÇÃÞÞ_K~eexxeNÑVEF\ÇÚÜËúøÍÕRMp|pTðñÊùäúåçííæùðòùý÷ÍÂ÷Í\MXWßÅõõÈÜA×ÂÙR\ÒÒPFXÇßÒÁ÷ÏQNydammolozqgzsJVÛÜÞÁRuFFHxID_tORG[ÝÚWÒPsKPTÛÚÛ÷ýöÉþåæááíâç÷ÄöÑvwHRÙ]DÄÂÁþúúùÉõôñÏÞß]NpsrwCHWØÝÎôÝXÝÖXSPÐßWÀÄÔ]ÖÎÁÒ@JqydcdepLGCuLÜÓA\ÓßÛÃÎÂÕXIqpsD×ÒÆÅÝT×Kp@AHtHOw@ßÆÍÇôýþçúðÓØÀOvq]ÞÞÐÕÌÊðÿÿúüýöÿçðõðýÄ^_PÖÐEUW×Ò@@tTÄ×ØÞÚUØÂWÏØØÅÝßMqx~xbadz{z~d{rpGE]ÖÜÜ]ÅÛ]SOqx~pS[×ÒÏÊWZBWÍÎÈ÷óýóöÁðåøçäùñËÀÔÖTÖÚÛÌÕÕU^Q^A[ÜÂÆÚÐÃÊRGNwMHOwru@FRÄÜÌÍÁþúòöÊÃÛÑRØðòÀÝUHzagzwutBMvwOHK_RÒÒWÑSTÞÍÃÖRY]Zw}EBLGH@LBE_R[PGA\PÒÂóöóòÎÂÜSÕÃð÷ÃTTÃÎÄÌüúäáøðüðüäúõÛÝSNvqCS[YÐP]ÓÐÓÞÉÎÍÚ[NSÖÐØWXWXwpydxp}~}|x||zdzsZ@wJUÜÒÊÊÌÙ]BCAF_PSEML\ÙÙÒÀóðôÊÆ÷ûáãçúûþÂW[D_×ßSNw@PUßÅÉñóñÌÞØÝÓÝÇõÉÅVAsvIptKZFCQÜØÄôþüËÝÚËýòÌÛUStqr}tCZMv}|sKGFUÜÐRwvYÖÄÛÎðßNtL@MA_Swqp}ydzwRVØÍÍÊ÷ðÌÅÌÃÃÄ×TÛÃÛÄÄÙ×S[ÄÅÐÏüùóøûþøçàææýÆWqtMG@ÑÓQÑ^X\VÜÚöðÂßÜÄËÁ^ÛÏ[uCqgacgdgxysvtutuNp|Kw|BÓÚõòõÔBu@__VÆÁÄÑ^usqBQÚËõóüñýüòúåüòýÍÙUTUXANvt_ÒØÝßÝRDSÝÞÆñýóòÈØT[Y[PTÒÓÛÐCuwO×ÍÿáçùüòöÊÜØÃÃØSHg`gex|spCJvAJJC[_WÝÉóËÞ]@t~|LSSÔ_@Yqrp~{tÑÎ÷ÁÁÃÄÄÍÀÉðòýÝOGKXÜÚÉðóÉÀÜ×[\TÇÌÉýüøóñøòôÀÖQUØßØÝUÔQA@_PÆÉõÄÐÒWÄõÍÓÛÏÌ^qe`l`de{swrr|CFPUÙËÀWÕÒWÅÒRGLQÑWZ×Þ]EtF_ÒóþÿüÉÝõÇÑÃÈóøýÍÇQX_@_PÐÝ_CXCwD@]ÂÛÆÏÆ^_PÑÈÐTÖÁÅ×ÜÜÖÑÇÖ^ÔTÙôñððÁÊþòýñððÊÄBdd|y|L^]Osyp}vAAX^×U@Lwt\ÑQZNuGAL@DYWÓSMBQRAÒÚWÑÂñòËÂ÷ÍÇÚÞÓØßÐÆÃöÀA×]QÝÒÇØØÔÀÖSÖQÁöòöÍÔÑÄTÃßTÄØÜÐÕ^ÙÄÉôÃÎÍÏÚÜQÕÜHBwsr{ee}e}ec``ywIG×ÑÞÉØËÃØñÿÌÔEuSZ[QP_]\IJqJ]ÖÎÌöùåÿøûôòðÂÜV[P]HPÙÝÕCtptPØUÝÝQÇÆÒÖÔÖÌÍYNwuQßÒÚöååÈÚÐ]ÓÙÂöðñþðÍËÍÙÄÒ@NNvpy~wttt}~|tGu|vLB[FFSØÁ÷ÃAt}JMGWÄÁÑ^CBDÐÙÐØÍÅÒÐÝÉÈÚðøóöôÁÐP]Ú÷ÉÆRVËÄÙÒEYÖ×ÛÜÖ÷ÿÂÇÔMAYUÙßÁðÌÜßHrCuZØËøþÙÞÇÙÈËÚÆÐRUqegg}gadgJsv|eCÐÜÀÍöåòËóÓG_K@ÓÑÆËSBLt@RTØÀÊóÅÙ÷ÊýäñÃóðñôZvHuZÓÑ\XVÕ_GXu@XwIØËòùßS^vwF\×õóõÅÚÀÆÊÇÝÅýúùòV_PPØÈÉÒÂÑJKJvuXLwysOHw}~y}}uCAQPZPTEÑÝ@@YÀÿöÐAqywu^ÇÅöüÚP×Ý÷ÿþûøçáåÏÄÕRÐÐÂÂP^VwqQWUÖ[IDÁòðÄÅÚTG@TØÚÊüÝTßYV×YMÚôô÷ÞU\ZYÒËÉÓ_Fxds}tJrpJ|{yevsKL_]ßÃÓÛÏõÏß]]ÀÂÉ÷Ý@CKs@WÚÎËõÛÜÛÃÎðòûãæøåöÕÓPG[X_QF}stCY[AINVÛÐÏËÖÇÒRGO^ÀÎÓÊôÇÛÛÃÉóçæóðÎ[@LGYSÔ×M{rr~wYVYÕÄßwqtz{r~|qOHvADH@VVRÒÊýõöÊÙUYDN_PÁÇUÐÙÕ_Þ÷óûáçüôÆÞÇÎËôôÈõßFHXAKWTAMSÒÐÝÝÚÕ_QQCMTÜVUÇÙÞÍÊÉôôØÐStJuEÔÅÄÊòÀ\tHuvGWQS_LKzmadewwJtC__UßÄÇÉÃÌÊÄÏÐ^YMvJÑßÀÍËÁSVØÀØòåúüÊÿËÔÐÃÀÚöÊÉÐÑ_OZ\ÕÔÌÀÔXF\KvIZCAÒÁÙ]UÖSWÄôÎÌýäòôôÛ_HERTÆòËÑÕMr|MECÕÄÑtwO~aar}xHUYsrrvtIOH]ÑÑÔWWZLGÕPDÛóÈÅÁÆÛÜÁÎÏõåáåÿüþÉÄöñöúåö÷ÞÔÕVÐÕUÖÁÑDuyxe|ZG_ÎòôÄWÒÇÕÓÄÁÂööðÇCLwpJwMÒÚÕRYÕÕXS_LWÇÝÜ_vrecezqEDGOqrtZ]NAË÷ËôØRUCAUZVÙØßÖÜÂÌõËØÀñòäúôÌõÄÍÊÃðøðÄßÛÔ[PXptWÄÆPLwyf}wuÒ÷÷ÁÒÑÔÙÈÛWÃúäýðñÆ]D×^DÕßÇURÇÅÑRw}sEWPZ@t}eacf|wIr|CuvKvsNÍöõØßYtstHJ×÷öÑÙÿñôÇÅÒÙ÷ÁöðóòýóÈØßøáúòðæåÿÃPEAÅÒÕYuv{mbaeEÃ÷ôôóõÂÝÔWÃøóÏÎõß]s}|~\UDFÕÊÂÞSApwZGZBwICymnbp}NPW[XGCAÒ÷óþýÌÝ]w~rZÉôÏÎõðôÎPGVÞñõñûúúýÏW[ZÂñôýðååþÃQ^EÔ[Y×^usdcgx]×Ùòö÷ÙÓ][XÚùôöýò÷Ú_wOvG×RßÝÌÍÞYHvpFHCYqps{gddwFwBGJ|yqtZÉÃóøÆEvr{{yÑ÷ÇõñýñÊÞPPUõöøàççåñÞÖTÊøåàæûùù÷ÕPßÊÅØÒAqza`ddIVWÄÛÁÏÈÈÇÁÉþÿöÇTßGrd`fpMDÒßËÈÆÔIAFTÑÒÕBI{gmiatMF_uJwJtuÝÊøýòñÏßRI~|ZPÛÀÐÈóôVZÕÝÊöäàáàçô\MMUÁöùýýüÊÚTÒ÷ýÍØÅDNvefd|BV]QE]ÛØÒÝôþðÂÁÎßÈËQMuKASUÂÊô÷ÛRtI]]WQQDIennmgw^_PAvp}{}_ÄÁÚßÙÐQGHNN_×ÔRWÕRVÐ[LEYQØðæíïïáðÂÉÎöûáàáäÿÄÕÆÆÚÙQRDtsyz}uJEYLC_QØÙÂþûðÈÙÐUY^WNuvsFDVÄÍÄÉÔIDNqNJ[]Ire`gzyDTQÒWXRvw×ÐUÚÐ]_AX[J[UYÖÞÔÞÑÓÏ×GQX^ÁÍòãíìãøðÃÐÍñóåäþöWRØSQÓ\[PE@HvCDNADutBTÌõüäÿòñÌÚÝWVVILJwE_ÕÆöÊÄÒÕPvqDQÜÖSJgcaf`~uutHMHwJA\YZ_@HF^YTÆS\ÕYZYWÖÖÓVYHLTÎåàëîáæûÇÉóøãíííç÷ÇÜWXEÝßÑßPFGLp_RICvrG]ÔÌÈÁÛØÌÅØÍÔ^SNyvqJUQß÷Ù[DvrwuWÑØRzecarrKEG]ÕPSÖQSÞÝU×ÝÑ×ØÜ×WR@_\EQÓ×SPLuDÓÅÿááâåùÊÅËòæäàãúõÒÓM_YDEZÞWU]ÖÝ\VSD|ytt^ÚÌÉÃÄÓÞÀÎòñÉÁVGL]TRÅÃØCr~y|DRÞÉÂEwrytC}qOtvrwZDAXu}LHOÖV^[P^_ÕÚÀÄßS\H@ÖVýîîâçäøåúûâììãæùÌÂÝRR^MCÔUWTVÄÎÓS_OvBHs^ßTOLOKTÅÛÓÑÙEHtAÔ^À÷Ú\JJyptq^ÅÀCqpxewBZ@EAÒÜÖÁßÅPE_ZYuMSW@pJ@EÐßÄÄÛÑCF]ÒÏüãáääüõÇ÷ñüúäúÌÎÇÚÑTÑVßÅÒ_@ÝßÕÙÜÜQLswC[ÝÛÞÑÑßÉöÊñÊÌTCvpÜÃÜÅÄËTCppSDSÐßDr|eyye~vKvqpwZFBBXÕSFrsZIpwNpzvJYPßöÄÝGEGÜûäæàììáæäáàïíååÿõÜØÅßÒÂÈÆÌÃÝÂôÁÄÕÐÐqeeqursppwMZ×ÃÀôÄZ_B|sRÛ×SÖVLJwuRÖÕÑLJvaeqtqv@HtwG\ÓÏØÆßÙÓCMN@G@PIvvv[PÅÁÒP@NvÔÀÿùçãããáíãâãçúÀÝXAYu^ÐÔÖßÍÑÞõóóõËÅÓ\LMwvuspqvXÛôøÿ÷ÅÙÕOMZ^ÕQSWW[IBÐÒ^^Fw}svpuryqtvq@ÜÒDPTMGANuqqp}ssrsC×ÏÍÐßX@GFWÀòòÿçâííïîëïáãüØÈËÚÔÓÝWÝÍ÷ôõþúûôÀÒA]Es~s~ag`evKÒÍ÷ÃßÄGOJwJNXCRÒÐÛÑSßÄÕA[s~J~spgdqrH_ÜÏôËÒÄÜVÁÖVTu~xe~IVÆÁÌ×^M~wFAÒÎÌöøûåâïïìïàäÿÀÏÀÓØÕJJÐ×TÎýøøæùö÷ÓÔÐECNemg`o~GÁöÿÿÉòßVÒÖßÚÝu\×J@UßÐÙÙD^J~spsrecf}aaMVTÄÊÕÕÑSD^]Nvd`g``|YSVÂQZGHOSÆöåûåàãããéêè•ëàçäÿöòõÅßXÝÜTÅðääãçóôÇQtHLeaokhicSÑÛ÷ÛÛÔ[\\×QRHqu|qLSÜÓ÷Û@EvsuK|{~aeffpCÔÛóôÃõÀÒÔP@qMebdg|BW\ÚÉRÐVNÐÌÎõøðÉåçæâéîé•àúäÊÅÉÄWÅÝKCGNÖÿçæâáþýÅZPGylh`fzF]RÆÈÀÆÄÔÉñÝÄÍRtLCFÒÀÅÁÞOpvxxseazgnlcavWTÇÈÇ×TPEEKsvxonffyL^ÖÀÚÔÆÙÀÿøýüçøøãâ뗖”•îçäûÿûûôÀÏÖMGXÖüúþåøÍØTEVSOyaciinmzsqBU^GÙÝÌóÀSU×BuCPÅÏÂÒQve~yyB@~xy`be~XÇÉÈÎÄ[EPRØÍÕpyaafetG^ÐÚÕÝÌÎýåøõöùüùçâé•ëæäþÏõññÿðßSWZqDÃýøøùòËÛWÖÇÉõ]}ebbfew_TÓØÛÐÈÿÿõÈÆÔÙQ[×ÐÚÆGwrredex|xgcbbndC^ÜÕSYDNuCÔÚTI}zdnc`gK[ESÆØÕÎýüûøçáãàí땖–îíãçÿýþöô÷ÍÄÚÔÑ÷üøçòÌÀÓ[BYÖTE|foikjlfEÐCÙÀÙWÆôÅËÚßQCOwLÕØÛCIDO|~r|rreaaz~pPÅÏÒÒ×X^_ÚõÎÅY}dam`{MÐØWWÜÚÃÀòùÿçøõËñûøíèîãçäðÎØÏÊÛÌÐEÓÚÈöæãçåõÝQRÕVØ×DrbcoogJÙÁõßRÏÃÞÍþÿÌÄGttpPßÏÇUX|pebds|bbibcdEßÓÓÓs|MGØ÷õWvxlomaOßÑ_ÜItÈõñæíâáúËÏþæ薔”ëçÊóùÊùáÿÑ[FEÈþäîîâçØuuDETÍÕmjldRÁS[peJÁ÷òþÿÌLege|WÁðÚTXffe}tG]ylbÓóþøýÌv~BÅüüðÐvdolcrÑÚÅAwzgZÏáâáâùÅG\Êæê•êâúËLRÎùæþ÷Ps|HØÿë•ëïäÉLqUÀðôÚLdbna{Uð÷ÇBKtIÙ÷ççôÒwzddtÝõòÉAv`dq@\ynnaB÷ÿö\wN}}Ý÷ñÇS}cc`fHÂÚÔqa|L^ÄøíâçöÇñúä▕•èùòòòýàïåÉZ|HÍóòè”êíÌÐÛÆÓÍðÓArmifgCÒCNda}CTÒòñØDef^FÜÂVÐIzes@QÓDxajlrFÕýóóÜqPVÅòñÐPsa`yDÑÊRBqcgtVÁøåööÕGÔ÷úçéïæä÷ÁÌöÿãíÇZKsHSÿáëëæçóÎÌòüýúÛB}{gcuÕÏñAKtppCËñäðP@vq~×ÍÑÀ]try}PZVpmkctLÓÕCuKO^õÂÆËÕ}lgx{RÜÇÒwegrNÇôÿáþÉPÍüùïîèêèøÊùÿáââìøÞwIÑÅûâéâåÌØ÷Éúäô÷Åwlkb`}DSC|fklfsÂÌñÂBevqÖ÷ÄÛQLgaqÁÜ@M~chcÄÀÄÛ×G@ßÒúæÍöÓIafrtÍÃÕÐ]|oewÝåüäüÆVQË÷æïìãúðPWÎ÷âàáåÛDsCÐòìïãøþðËúæïîáôHsab}GØß@|e`leHÛñ÷ÌXMJrXÅÏöÆqbgJYÓ^Igohlzqtwxx{HÕÒÉõÃAwqdxARVWBydfyXÙúçåùþøóåâïïîàýúñÀòøáãìçÎÀVÑ÷ääæáÿûòýâìïâûÈNqecdq}zzljhigwZÞßÒ^LNIWÏÌW_E}vqWÇÏÅX|lb`atGKu@psSÓËÿþ÷ßQHKJ|E_Mt}amzrBÉòòôöñõùúæâæòöÍ×ØÅÜðùúòÈÅÐÏÂôùüòþð÷øæãíéíúðÅYOqtwrzf`f{qCUÝÜÙWGXWÕÝÁÔWU[FOLOZ\Iaonmba|}vrsBV×ÖÅÛQ@qrr~ruvs|ysHSØöùÿÿóäæàíâìààáùóóüóóýÏÇÏÊôñýüúúûùøåäãïàçùËÁ\OwsydgooohmcezxwIKARQÝÑST×ÔÖW^PEu}v}e{{{{eHBHNEXÖÞÛÒßÚYXOvuHt|tv{r}q]TÄõòÏÁðÿçáæäææþûüñþËÚÕÕWYÚÞÆóôñúàäúáæíìíáææÊÚSLZC~~q~dz{}Jt[_U_JY]×ØÙÃÍÎÑ_\D^@rgafm`ca~yxyvsxsBA\GAVRLtOtAO}wr}zgsI]ÛÉôÿùûçâïëèîéãåùóðððÚRWWÞÙÀñüùýûòóüýçãìæùäõÝWGJyclihbcft@vwKJYF^ÑßUÙôÝÒP[ÜÑRJffdz}qGFAvCÕSÛÙÍÇ_[KqCM^AHq||xs}XØÚÚÑTÔÁüäãæãïâæøøõËÀÕQSHKI]Øõþúæçúøûúæáàíàøðô÷÷÷ÊYt}dc`erN^]P^RÙõñÍßÒ\BNtsrvp}s{a`f`a`g`fa`dpLw]ÍØ^_Busvs}dz|z~tØÆöüýñóüçìèïéèàáúæçúñõÀÕÖUÒ×ÛÎöóðôþøùúãàåáçåùñËÍ_qp~aggaf~vwABAFFYEXÐÖÓR^ZHLOIJI~d|xzsqptKtupswuGXÕÚÛÞÅÝÚ_trr~dyrwtWÞÉõÎËñþäþÿåþþüüËÀÀÁÔÙÌÞÔÞØÅÜXØÇÎõ÷ÏñÿûãéîààäúüýÃWHvq}sK^N[UÐDXMEWÜSSÒÖÔWSBwwqpdgf`dzd`f`fzed}rpJRPQS]EOLvp}|vNOUÇÄÏÿùõõ÷ñùçáãììââãáøðôÀT_S\TÛËÏõòüñýð÷þøúçæøðýüðÉØ×MsrquwIp}suvstMqLÐVTÖPDGtde~~yxs{zs}swqsKOHZ×QYPEODBJHJIMwKRSSÔÔUÃÂÞÃ÷õÍüúäææäçþöÈõÀÒÜFLFDGÖÜÇöýöýùùûúäççþüóüööÊÅÇÜPßÌÐÑÔSDEJKHvtZVÜÉÀßÑ×us~flbmi`dedyepwpprywprqEBvwCtK[]ÐÙÙ\VÐÓÅËÏÉõùàæàììãáæäýó÷ÈÆÛØÇÄÝPTÅÚõðóøûåúýöðöõÃÈÌØÚÄÚVPSÕQ^tC^vvtLtKNKOGSÜÅÕWFCJp~dffd{~dz|rvNM_T]EQ]OFFAYDvvprt]ÃÄßÓWRÓVVWUÙÈþýþÿåþýðñÊÚÇÄÐLXVÖ\DN]ÜÀòåàæäúçøôô÷Ãôÿøüð÷÷öñóÃØ]RÔÜPGFÑÖ[S_^GQVW_Aqwvyda`mccbcegz~}wOwpKI}{rsuwqsqpX]ÙßÅÍ×ßÄÞÐØÆòûåþäáæåæçøü÷þùòÂÁÂÛÕ_KC[ÔõòþùæäûäüÎÁßÓßÞÐÝÅÎöÌÉÍÝAOELJtsIELvJ\BY[VXMLCO|~~gaaff}sZÕDPÙØ@CAJpwwJwru^PÐÞÝÑ\VÖÐ[F\ÄÓÎõÈÉÈýûçñòööÎÈÏÎÄÐRVYvZDTÝÈòúçäääóÎðýóò÷ÎÊõøúçýòòÌÄÄYLYASÐÖqL^F^ÛUFBOMIvfg{dggloibdqvsCIwuvg{zyeefxKFÕÅÕÓPÕPÇÕQÜÉñþýôþùøçîáåçáäåÿÈÎËÅÖÒAuAÞÊðüåäùÎõ÷ÐÒÀÌØÍôÌÊòÍýÿÜÕÕ^LMMutGCPXqJ]XTÝSDAGsHvezszdyegdyyES^SFwvtptwspNqvCAC×ßQT][^Ö]WÓßÒôñÊüøýüäúøüÊÚËÏÙØÝZL@CEÔRÜöùüþÿÂõ÷÷ñüõôýüüúóöþùøýýÃÇØÛÐÚVA_[AWÄTÐÒÞXZu|zgaaaoobggx{pJKpJpfdzzf{ez~||FCHGÝVDÐÜÒVTÐ÷õõóæçàìîîïìæâûöÊöÛÓÜÜ_]\YÊÅÂÈôSRÓÜÖÜÓÞóÆÆõóÚËñ÷ÏÎÄßôÓ×ÖS@QYFB\NSÉTÛÑAruHs|fxrdr~yIDRÕ]pJBqwvr|ppsquyH_SÔ\DF]ÑÖÒ×VÏÎÁôýðöåæææÿ÷ðôÛÓVEMA[A^]ÜÍõöñÅYXÓÇÜÂÈðüüùäåððøùýùûûÿò÷ÈÄÛÀÉÐPßØßØÚÖRpgdxal`ffaggyd~tp|s{z~dgs|~sqzIOB[^QÑQÒßÙÝÍ÷þøúÿçíååáæäàáççúÀÁÍÐVQYBUÛÂÌÅYQPMvOspX×ÃÊÌÔõ÷ÂßØ×ÎöýùÿÎÔôÉÌËÄATÙßÞÚEB^qrsdo`a~r}xwKuF^q|NK_DtepvI]Ôpr@GÓÔY]ÇRÖÞRv\ÝÛ÷ñ÷òúðüòõÑÌ÷÷÷ÂQ^FK×Ð\KPÔÉòÎÜßÕTU_LsM\ÍóÿôüýüýóôðúøæáäüåúúþûöÐÖÜÑÕ×^[@teebkhcgdezy}|sefg~dxxgzrt_urpOuSÆÏÈÈÜÙÀÝÛõÿýáãæáçòþåýðòËÓÐTSTÐÐÄÒQÖÛÛÂ÷ÃÅÓLwNr}HA[ÞõÃÈÁÅÎñõòðÂÍñññÿð÷þüÃÇÑS_ßÑÖ]wxeccdzxpIvO[@MY@IIpge~yqALAQZXF[OPßØÆÇT\ÖUÑÛõÂóýòóòôÀËÍØÝ×Hq}wHRYZW\YÙÍÛÈ÷ÌÐÔOqNFAÝÃÄËñóôùäçáçåäûüøååúàáåûýÌÃÀ×ÒÔFydbiilcfde{dx|qrsqrzda``f~wDLIIBKYÖÂÀËÊÆÑÜÙÇÈöåçæäæäúååóôÂÔECtqXWÕÜÙRRÕÓÜÛÛÐTEvr|xrMG[VVY\ÓÎÿþþþÿòñòþüüäáãæäÿ÷÷ÉËÂUL}g``dd{yyprqAYZCAIs|{eexrtLBBMN\TÝÎÀÀÇÜÔWÙÁÎöýøþüöËöõÆßSNt~{}vqBGDRTRVÛÅÄÝÝSEKwJXQÜÜßÀÂÎËùäçæççáåúäæàæáãìàçúÿÊÍÖArdbnlbafd`dez{}wup~yxgbgfge~~suIPÄÚÌðõË÷ôÁÌÈüåûøçàáçççûñÃÀUFtHNtwwqvuIYÐÓÄÏÒQZEu|pLDED^GZQÐôññöñóòòøåçáçåäçááääåóÚUO~zdfe{edz~{suI@@wr|~~{strpwuHDÔÁõ÷öðñËÌõöôññ÷óóýúüÈôÌÖDqy{ee{xgd{xyCWÑÛÓÔ×@J[G@UÙÄÌÍËöóóüåäúåçùåãìïïáçæåøûùò÷ÊÌVu|eddfdd`fgg{qvwvzedae}vKw|tuuSÛØËñôñ÷È÷ÿòòòóòååäáæúóñÞX_EKCLwtvr|ssvG_AIuvwsx}rq@@@YSÒÀÍÎöñôõòøûäæçäååàáúäàäüõÇØWOtv~deyerBD_ZBI}z}~}w@DHI_RQQÆö÷ôüþóþþøúðÌôÈÌÏôñöôËÓBupr{{~dggaaezvs}r}rpruLEDCETPTÀÈòüøûøþåçææáãíãæãàáàæúôÓ]P@prtw~egged{tw~rwrz}stqptwpN^RÔöÿüþþøáäúààæääúùþåæàåñ÷õÐ[]OuLJuKxyp~yrwszgf`fgxwwzywydg{vuqGXDPÞÌÊÎöùþüùåäááíãÿó÷ÙÕE[ÜßTSPX[KHZY^ÕQVGCPU][@CDuH@[×Ëóüòöðü÷óúæãäåæåþûò÷ÍUS×O}vwuHq~zge{z~MXu~{{~rywEtqEAwvLS×ÔPÖÄÕSÅÉöô÷ÃÄÈöþçùüøüÏSMxvOY]wKYDJI]R[EBNCKCVÒ\\VIrr|MÖÞËøäúççþúàíïìâàìîãíâùüòÃØÔ^TÁÅÓÔGpegz|rrt|dzfceee~~{dzd{x{~|pKGU÷È÷ÊÚÁÊÚÁÁÅÛÇÍÝÖZA^U^][\SQÝÆðôÍÚß\R]QÕÜØÁÊU@K@GSTÚÏòüøäùûúæåúùúåáæàæüÊß×tK@QÓØÓÃÚÕFLZq}|s}rstI}IQNJr}wMHERYvKO|qtAQØßßÏÆQÄØE[GD_@swLvrLvzzeJXFWÇWBTPEÕPVÇÃÜÆÅV_WYUÑÔÃðøûáâáçàääåýøçäÿäçýöõÆÈÏÀñýÿðóóÈÌÛR]MswKJwDZZXOp}zgzpwAvsrxeyerrIES^ÖQ_@AIpKKAYQ]ÐÔRMDuvDGWÛÒVÓT\FTGGS]ÓÃÐVÔR^EÜWÑØÞðçúÿþÿðôðÌÉÊöûçýÊõ÷ÍÀÊÚÅÄÚÍñÙÖÀÀR^R^WÖÓÃòÌÌööÛÙÑÑÔQPßÏSARSDR^BNNCÐÙXH@H~yef`afpxxps|~|wN@ÒÒXBYDMMupqKLU×VVßÐÝßÖR×ÜÇööôõ÷ÏÏÌÀÚËôñþþòüøúçæúýü÷óýñÊõÙÙÆÛPQÜÓÃÃÁÆÈÃÀÜÖB^Q_ÔSZVÖB_VYK[G_ÒßÛÏÙC@AA~yqwswpdyp|epsZQS\ÖPESYBsJJMIZFÖPtL\EFQ\Ñ×ÑÐÞZIM[GKM@DPÑUÌÀÄõñÄÚÁÈ÷ðóòùôÎÍñññüþñùûäáåùÿúøÿñÌÙÊÌÍÍÛÞÃËÇØÌÄßõÂÀßSXRYJtB|{~z|}efddgerdyqtKwx{ptpvJ~@^\]DKE_FD[EIT]ÜÄÒQÐ]^]UQ@T\ÁÊÌÁôÁÉËËÑPÖÕôÎÚÛËÀÊÏÁÐÖÒÅòñ÷óÿ÷ôÎÌÚÁÒÚöÃÁôõÉññ÷ô÷Íóúðö÷ÆÚÚÖREYEÒß[ADuH@uwup~Jp~sqvwqJMKtY^YX^@[Z@MJpqMwws}|vvw}~suOHFA]X_SPXFSÑÞÅÍËöËõóüððùåæãáúþ÷ñÿðÎ÷óñùÿððþüååñË÷÷ÂõÎËôÊØÆÛVUÞÓVÒ\XSAOWÑXGLr|eyzywpy~|vItM^BA]@JDAN^^EW\uBRGC^^ZPPQÒWG]TBttqpIJNDOtA_E]ÔÚÆÏÚÁÃÛßÁõÏÉÊöÎðýäáçæââáæååþûýþóÈÏÊÊÃÀÃËÚÁÝÀÄÒÅÃÙÕ×Ò×XR_ÚÙVW^@JttvpBNYO}}rs|s|~~}{|dgyz~}rxyrqMNADAFCZDC@X]ÝYE\YÑßÞÑÔPÔÜÙÐÖÝÛÇÝÛÞØÀöþúúúåûúøäåûûááçäøùþþðúÿô÷ýñÏÛP^QR@SCvJQPVRZD^E@V_BFS@LKtH[AMELvBVVÖUTTUDLv}zw\ZNtJwJrsp}xJBNq|pr}y{ezgqFZIGFGY\ÖÚÁÇüúúððó÷õñññüöøçþñýüûääååûóùøðÉöòöÊõßÒÞÖÎðËõñ÷ÊÍÁÐQR]×Õ[GAGKv}dddzqq}vvvzzdxqXÖPY_ZFKHAMZ×ÄÛÖWT__ONHvswJpy|rp~qtvKQÝÝUÕÙÁÂÚööÏÃöôññòäàæåâáäþûüüóüøûÚ^ÔOtG×ÕØÅÇÏÃSÑÄTÔÃööÉðöüóQVÛÓÞÊÎÏÌÀÜ÷Åws}yrD^DwJsLd|px}Jst}pr\q}w@uwvss}qsDyex~eqJOuOFO\B\V]M\ÝÙÐÍðüúóýûúýþçàáéèââûòûýñååååúüýÿöÊÆØÐÚÚ×ÑÆTP^vIXEXÛÜÝÄÞTÐ_KIDuJUAHuJpFBMWÕ@ZÓPTSDuOs}vrdK}MGEBZJpJpe}rex~~wrpGqsC[GÖÝÓTÜTÝÎÝÐÁÉÍþüý÷òõ÷üÂôûçùçåøðöÎð÷ÞÂóùðøùüôôÃ÷öËõòÿüäøûóõÞÍÂÐÔØÑQÑAus}wNp~xp|Ovrxx{|yyrrtFNHtuwG\LE_uFAq}{dfedffz{JDOJtutPPZPÒÓóü÷ô÷ôÂøþüÿûüàâçææúòæÿýðÎÛ÷ÉÚ×SNuÓÕÖÝÚÞñÍÓÝÄZQÁÅÉÞÃÂö÷ÂÀÏYPÉÐÕ×DCÕEqLwgswv[uHBFZvEJyOOCH}uB^V[ÔAvMIJrfgdgddx```g~y|IB[Z_TJH@ÔÆÞÃöòÿåááåæàíìààáæáæåÿÎÌÄõôññ÷ÏÃÁØß^SQT\PTEXVÚÈÍÀõñÉÄÃÞFKIwNvy|Irt\@NKKuEJv}rdNq~wpu]IEÕRvYDtr}zr{clmblsHtqpxwtuwFtwVÓØÆÛÙ÷÷üûáåçïèîàúøäûøþåóúçäûõVÕÒTÝÖÔYÔÖÞÜW@ÓÃÈòüñÁóýåþôÞØÕWÚß\ZÒÒÊöÒBXM]×]JtGG__p{qr@Õ\pvANNweabn`ge`fefgdikjjmf``}wuwFO@^Òöçøðäáçæíáæàîꗕê•êééïçÿñÿýåÏÄÁÓMXÜUV×ÁÁñÆÁÆÇUßÅPZSÚÈýôõ÷õÚÏÁÓGE^YP@^VYAVÖSYXD\SX]XAMLwwtwtFYXRDLMKyg`afacmamhoccdxwZUÖÞÙÒÐÓV×ÃÀÎüàã蕕êêîìâçäæûýåýÍÈòÊôÅÜÃÈÂ÷óÎÂØÌ][ÏßÒøóúíâæìíäþòüÊðÆÏô^pEIwKsI[]GÓTw{zlnii`afxBOuwFuup}vsyeryf`ed~eHuvC×P^URCZDQÇØÚýäùåââàìàííãæáàûýñ÷ñþõüûý÷ðÊ×F@qy{zqvuEÇÏÃÏöÃÎÌÂòþÿñùùôÉÊÍó÷ôøÿÊÚÌßZAwezfcfffz|eeqrexy}vv~zyxysprp~ys|e{zgffbl`dx~pAØÚÁðýýòðôðüÿäàãìëëêèìãìíçæçþüÿõÖWEXÑÑEWÖ]ÝÛÓVÒÝÞÁÞWÙÇ×WÞÒÃÃÜÅÊÊÆÉÛØÓÕGO}}|pppMItB[tv{s~{{y~pwrp~~ewyd}reyxaaa``rzztCuVÞWÕT@FÆ^ZÝÞÝþþñçíàï”îè”èáïáòüúñóüÈùøôÎÎÔWÝEw_\HSUEQÀØ÷øòüáåÿæþÍòóÙÃÀ\Y×wpM|gzdgs|`gzmaecfyeyKvyuNsZ^~vDtptxe|f`|vJIuJCs|Jq~H[@ÞØÝÂý÷ôñ÷õùù÷þûûýúý÷õÉÙ÷öÇÌÈÏÛÊÇÖÑQMYUQWÞÝÜþøðåçòúúñöóõÚööÈöËÜËÈÜÍñÃÑßXpt|f~qqp{bmfmogbkmbcge``yyq~xMDQÝÚÜÖÓTVÙPCUÂÃÃßÙÚÅÁËýÈÅÆÊÈÎÛÛÄñöñÿ÷õòøýðõ÷ÑÞÕÑSJywOvvtLpANFGCJÕÃöòòÿüäøùÿðüãââíîìâìáçóWWÀ×Ô×ÚÝÕ^tuJ~|xzdz|d~ya~y~vvyp|eavMAAÝÛÅõñÃóýýùÿýðûùðòýÌñÊ÷üòðöùöÇØÑ_QHN[]\TÊôÌôÃÞÛTÒÞÐ^_ÑTWÞT[]ÑÐÖßÖÞö÷ÆÎÈÈôñýûûûåáäûäùóòúûðÌÁÅÀÐQTFvwD[[EZF_[vsvwJLMLBAQÇÜÐ×PYSPAtHCK@DXZBOF^X\ÕÑÝÚ×ÔQQÕQTTTÇÀÏðöÌÐÓÔÑWZ\Ü×TÒÒÉÏÈÊöüÿäàæçùüñôðÈÀÂØÍõÏóòòÈÒQV]PA[_SÜTÙÚÍÚÝÆÈÛÌÃÁÄS^ÕÃÆÒBOZ]CMGGOZQGADBXTMKXÕÓÌÇÛÛÚÕÔÞÔRWqgzdddepr|JFyypr|}}qEFJMTFUÁßßÏôñþýÁÏöÕÒÃÌÏÎõýò÷ÎþåõñòðüòôõÊÌÅÃÅÁýñËÂÁõÎÄ\A[v}KwGOKQ×^RÙôõÅÒRÙT_S@uEUØÙßSÖØPYRYJNtsggazdc|GuILK^ZEdd|wNtez|}|{xeqwEÅÂQTSÕ\DAZÙÎðøååæçúøöØÁõõôÌØÇÛßÓUTÔQÔÅýþ÷ÉÀÌÇÜ\DMDÖØ]R×ÔØ×ROAA_]Gwr]ÜPq|pEAFVÍôüÿöÊ^tuIuZÖßÃôÍÙ×Np|xfde``ag~eomgfgstHZOH@tgaggxJpNÛÛÆ÷ßXÓUESÆÐÁöÊýúñÉýõÍûäþáâæãâýÎÈÞÜËØUöó÷ýðÔ]PLwDtr[WT×Öu~gew|KÑQAtr~{dd}uK_ÄõñÍÑÚÑRPÖQBG\ßõÖRÔ^×WÐWÞÌÆÀÀBuqg`cmmd~vPTK^ÕJOCr|qrsPYvQ[uACH\ØÞËå÷ÛÊÇÓÜ]UÊöóåàøùáçúä÷ÏððËøäýúü÷ÂÇSÞÏÇÕÉÜALu|r~eJtL_Ò_ÔÝÞVSwygd~pJONMZwLSGEÐÒ×ÜW^EC|OICÝØõüþÿóöÔÕ[uE_RYÐÖÖÅP^WPVÌ÷ýóÌõÂ]GMRS^ÒÚËõÃÊÀTØÜPRQ×ÅôÃÜñðÄËÊÙÚÐVôñÈÎúñÇ÷ÈÀÁØÒÉñôÿàðÉôTMtezBFMÔÂY]ßXuCs[ÃÐ[QD~sdgxdLÒÅÄòÈY[@qsv|BÝ×ÒÎÍÖÁõÃñ÷õúáåäûøóððÅßÓÒÇöôÿååååýÉßÙÜÆÕÅôÀößÐÒRpBAH@tuF^HEQSsFZ×ÁÏôñüÎÁÕSEÖÑÂÍóøæàäåð÷Á÷õËÀÁÛÞ\OtryxwKÔSÇÊñÌßÔZvesvtvIGÒTÑÖ^DGWÐÞ]ÖÉðÏßÀÁPWÑØýöåïëíàáùôôõöûùäíìæøõÔ]ÞTWÁPWõ÷ÉËßp~q}AU\ÂûÄ@K|bmgces}RóÙÙÄÙßÌØUÉÈTÂòÂôõßXßÜÂûúýãçôþñUZ[|y{aJIt]BMÔWJZ×Q_ðÜÐÎÓNJw}]ÇÂðäöýæýÏÂUFÞõÅÊåòúåðôôÆÝõ÷ÉòùÊÿòÁRQXCÓÂÚÇÖHFAwy}y}HIq[T^ÙÀÜLEuswvsy}qdgprv[T[ÛÌÙÁ÷Ü]WJpNOvVÐßÿáñÌ÷ÑF\VK[PDÖYdgdfdvtvÜÇßöòÓS\\EÕVQ÷õÉýöÆÌÖ]PÉÙUÍÌÃÂW[[AÔÖõÛ×ß[_ÕWP\SQAPPPÕÒõÅÚÀQFq|tpvJpJJMpwtKMBKvLsK}abijjkhbyp~EIqpqOCFPÑÒÕZÇÒÅÇÇÀóùøüÿÿüûõËØÛÖÔ[XQRBZQ\XuZÔÝUÛÓVQVQWÝÖÕVRX^ALGQQZty|x{ewCDUÄÂÇÔDSÐÐVÞÐØÌÊÌÊÊÁÎÃÞÒÄQUÄßLrxezzezsy|JBKwsKN}yzaccconmmf{ysMOÔÏËÛÜÌßÏÈÉÍöñüææûøûþáæúóðÎÅØÀÖ×ÇÑQCu|psG××NO[DGNN}GAIYÕOY\WÙR@[PCXÐTwDÒ[\×ÜWÓÍüÈÃÝÕßÄPÕÄWÑÙÂÞÚWVÑÙDYYvttJ}OsvEAsYRBZÝÓ@\w}vwer{aaxy@MAØôÛööÊÍöõôýñùæúöûûñòúöðþõõñÈÝÑ_DYDuZUXÕÓAHRBBVÑÝÛÍÍõÛVPÚßÑÄÁÙÀÅÑÌÎÁÛÔMDFuKR^ZÑRWÆÝL__FZSYÀñÅôÿüñøòÈðÍÖÆÏÑÑÑLtDJOWÛÇñýØÎÍDpLr{{x~uJrHMpHÓÓWöñ÷äþðÏÈÐÄÌóôøäþäôñýöÑÁöÊÛÇÍÄôÈñÉÅÛÞÎÁÐÓQSÜÇÚÒÝÞÑÚ×]TQÐÐÀôÊÐR×ÚRYÓÜÒÞÊÏÈÚÒÝÝVÝÅÓÛÅÄÓPFNC_]Î÷üúçææçõÄÞ_[ÖÓÝÐßßÓÑPTÖÒÃðÉÓÓ]Msvdx~xuDMKQÀÈùòóôûÆôÇÉÝñËÎöñðòøÛôÊÄÝÏÅÚÁÏõýßVÚúGÎðØü÷×ZQ||tF^P^ÓÃÐ^ÖÝWUÇÂØÄÂÏÙÐÀËßÓÏñóðüðõÀÞÒÛ^ME^TÕ\u\Ü]Ãð÷ÿçàçýñôÏßÙöÄM^ÅÒÞÜÓßÇÛÚÎSHLvtQXusLLEÔtpuMEESS[^õòÙSÝÝÇðòùýÊÈÊÇ_R\_ÂðöÎõÃÈòÀÖÐPÖÀÖMK}grNwswtC\]PÒP@TW^ÕØ×ÄÊÏËöÊÙÂÁÀõØÓÅPHOGvvYZYYJvHABÖÚÓÌÆTÐßÖÕTÑÅÊÈöüÊÁÅÓÓTusruHpqtJwqtu_UØÖW_stNtAtNÑÄÚÃõØE^X[ÙRu|LZBHIXÞÐÔÛFJF^ÝQYtxqtMursu[TÇÎÃÚÚÄÌÈÑ\WÛ÷ñüüÿóýüþýÊØÃõÁÓp{g|xggffr|vx`g|se`cezzr}|rrp]UYÖÁØöôÓTÚÍÙËÍÃüùøåÿÎØÇÔÀÀ@uFW]ÇõÀÏÂSÜÁ]SVKOM~d`ed|tyAG@QÌWqpdaebijoappurMFHÙÛÜÇõÅÞÈ÷ÊüåæîìàâéàçæúçåñÒÐÆÒÌ÷Ù^I}ds~adaombbmag`xyyOOe||dytzed`af|}ÕÞRÞß_×È×ÖßEOWÓ^ÐÎØÉùåìëíïêìàïìáúñÙÛÉÈÈòÈÛÃQYÁÓLD|zxgcbljcl`ygmlcmgddxfg|OQÝ÷ÎÛôÉÂþò÷óóöüüüÿøåúãììèïäòñÄÅôÍÞWKC@PWÐÎPE_KNvrabccgb`eagvHXWDwCLrtrrffa~Hp\ÜYÐÙÛòúáççæãìãââíã앗êëàåçåøÿýËÚß×ZÔZ\]pez|d~re`bbaagzqBIÚðð÷ÄÔÓÞÕVÐÆSSÔÕõýùäùþþùúþûÎÕE@PPÑ@FÖÕÜðñþÿÏÃÇØTÔ]ELC^ÝÌËóÉÐRSVÕÓÐ\GvvGMwxpCSÚÞY[ÐT\ÜÇÆØÈòúíìââäþúåûääýòðÌðøúüÿúþüøøÿöÝÒ_KHIL}zps[ÚÌñÍÀØÍôÁËÝZSvKACCp[P_ÝÄðòÆÏÇ×XFO~dezqZÖÏÛ×T×ÀØÂÄF×SSÜßÌUÞÍÆòþäàäåþüÊÈüÈÛÀÆÏööòñÀV^YX^Yvppr@SÒÕ×Üß÷üþçååüôÁQßP@]ÜÛõùçááúýùóÃÑEvwr{}A]XÕÒTÆ÷ýóüûüòÞTÕKvCGZRÕßÙÎÐN[R\ZEOsxeeddxsu]R_ÍÜUßMGLK@PôËõÿþãâúççäÿôöÖSÔQÉ÷ðóÃËÏÆß^Ù\rMqsq|veOÐQÇÄõüÂÈöõÀÅõRNPEXÔQVLGVÐÌÞÏÏÞÊÆMwq}aaytLWÙUÜÍÂÅÆÊÓ_ÒÐÙÂðýÏÛÇÄËÀÅÄ_D^D^^A||LJwtBCvB\VAG}exrvvMEHC×ÞÊýöÈÁÎôÎÅØQ@rJPÝÅÆõÏÃõóñÎÝ_ryrJYOCFvFÑÞÈÛÛÁÓØÓÕÞ_Gt{qC@HH^MATÙÀ_NK~~pw|f{f`~rG@tZKEUTßÓÚÐ\ÕÓÏÊÉñÉÁöûçû÷ÂS[ÖÛÀT×ÒEÖÆØÅ×ÓRADGMww|ff{yz~MuIPÜÃÀÂUCss}dxyxzsRÖQÀÇÔÓÓÕIAXMJwuIvCÖGLXÞÙÀöÈÝÓSPVÓØMNMXRYÜÖA\]^L@ÔAwq|dggeeesqOPLxygesrrw[VÛðçàåùúüÉóüôðóÿÊõöÉññõÌÜÉðñÆÇÌSRÜÔHpv}G]R×YTPuGÐRTEOyy}ge}Htw_VVYMug`gfffyzeHÖÙÚõÌSYYQÒÊðôÀÃñõÈõýÚRÐÚÌñóóôööÃÌU^}dxztCEYtHws@PÁ×MK}}OSPWÔÅÌüäóÊØÜÓAPÃÄVQØÇüúóýÌÇÀÐÇòúóÂÆÐØËôýõÄ×ÐÛóåüööðÂÉÂT\v~yIMEBvwqJLIvfb`mbdex{ytÞÌÐ\uupqSZßÅÝÈóæäùçüþúøçáïâæþÿøûóô÷ÉÔÝÆÃÈÏÄU×ÙÈ^HCv}~Htq]^[V\ÜÜ÷òÁEsCCLÜÅÐWPßÒÇÆÜ××ÞÙU\Ò]I[UÚËóÿ÷ýýÿûçâàûöõËöûþËÙØÎÉö÷ôÛÑVS_t}xf`mbgdvxxzgOVÁÔGHpGÕÅóóöñõþåæúýð÷ðûüýüõôÚÇÊ÷öÆÈÆÖõñüðÏôÑPÝÊòÜÚÙÔÌÊøýõòÈÚËðÏ_NvsBP\F[YvAÚÙRJ[tpuL\HMJpHPÀØÑÛTÐõÿýÃËÊÎÌ÷üóðñÿøäãíæúåþÌÒÐÜÇÓÓÒÆõÎÀÛÇÆÜÙÎØUBr}qLC@MwMEEÜÕÕU@PQÑÔPØÖØÔ_Ã_D\LEBVÛ\ÐEC_ZÊõWÁÄÆÏöçüçæÿûóäÿPÞÁÅÜÐþÌÀõÄ÷ÒÇÌwvqd`mygbaobme^}ep}VVrE_\ÕVÿôÖÆÆÏÆûàÿûåÿËÎçúÅV×ÄÝôûòþÿòÊËçøØ[Q×TÚðñÊöõß^õðÙSNwdfquvpxd`~J~abfag}}dfd{zJGXOv|{uUÛÚÚPRWÈóð÷ÍÃÃ÷ôòåàæñýýúäÎÞ[BÖPÒØÁÇKO[ZP^Ys`faewJ^sxrzJZOp`}txtA_epxwZSVy~u}CÝÊÞLPVQôää÷Îýòøàîéæàçýøàà÷ÇÊÇÛËúøÎØZHpJ\}gljjadbcnjlyaba`adLÐ\Dts|JÙÛPPLqOÕÿðõõÖZ^ñþËóÂPTÅúþþýöÎÈúäðöÇ]VÂòûåþñQHVÃÙT_}aeqtp|flcgcfahjhaeypyygBAYGNwNÒÀ÷åçûÏõþååæáåøäáââíâåþóñóðÏWYÔÕÑÈÏÁÖ[^Lwtwqze{wqOKpvgfgfydeyeqtCG@AAHHBuJrvx}BSÐÐXOMÑÑÚËòáúòåæìâàáþûåäåûúþüüøäúÿõÑMvtprr~xeqJHv`ommnmagfgx~wKwwz|XM\^]TAÝôüåóñÜÄüóäçàâûäàìîíãòÁóýÿúðþýòçàáçþÁIJJvqr~rHGXIPDffaabhcaad~HuYF|rttsCuqDÐöÈÊðÖÝÃÅ÷ÎøãæàâèïãíúþÿõõÒÍôÃðýäçûåÃEMJKxs~q^\@M_@w|e{acf`gt@HvYIrHJD@FYIDVôü÷àçôÈÃóÌñåùá핗ê•êéâæáÿùúôòäíìççäñÏÒFqxygag}@K[UGtxfllalma{HtFZFAIBpHQKCRÝôÁðñÌÌÝÜIKÜÖÜðþçàîêïîíæòßõóÏóÿäçì”ìáûÿÄFÓÑFZ_ÔIFØU\[\qcgd`lcgma~wqxs~`ewMM[ÞÑÑäïãææáòôûåçãèê—””æñüõõÊÍÇTÆøúñÆÁYdg|ddpzd|I^BIGwdgzgg}p{u^suMxda~q~JuqIPõÈÈ÷ÕEuNVQôþûá㔔•–•îâäçùäáñüúçàæáûôßADALYpzpu~vwd`onioa`ax{}xqB}ffddvÔQZÜöüþçáå÷ÌÅREÍùýåíïì蔕éàþÂÐöÿÈÊóøþúìâüÄVZpXTKtpNw~vJ~egcbbommcadqdoiingg~KTÜÌåöÅÑ^Aw^ôÈöûãé闗éèïäýñýüÎÉõ÷õòáðÂÇ[JsC^F^JMFwQZ~xamnif`aegxzy{cmhnh`{{rwVÂõøÄÒWsHvOËÎóøçé葖ê•âççþçúöÃÐÏßÆñÁÙZuHpJNHN|qJ}t~abbfd~vFBBIpygfcc{NLsGÇÊõôÏÜRONuJ×ÖW÷øäæãíàåùöÊÇÄ÷ÓÝÃÞÌñþùÂÙÙÚ×ÖÆU_ZNLqvtdg`nl`a|ysBr}zbmhjidvwAÔÉüåäåþüÉØßÆòñüåçàííííáçüñðÎÈÏÅßWÒÃØÁTYEH\ÐÖÆÚÖFJSIqprgfzeptB[MßS}}{zbkooa|KqGUG_ZMrf~tIÔÎóòäïìíèêèççáåäúü÷ÚôòðøùüÄßÊÉÈýÊÔFJNq|szcbcagLÑYXYTRCwpxg`ffxttJDÙÇ×ÔÜKq|xrtPÜÝÁýçúúìæøäåøäçøöðýøááîîàãàæàâãùðÈU_^^Adcab`f}ppp~x~|fokijigyd|AÕÇÁØPJWFw@×ÀÇÃüççáãáåúúððçû÷ÅÞÆÇôóýóüøúúàãäýýüÃØÀØÑYOLIYTTØÅÝTB^[effcbo`gzH}zsX×A}vMJH[VTØÇõýøáââëëììáíàæáûúäáâåäãäæàííæåÿ÷ßEEpxx`gee{y\PM^uLOzaimlbaeqexrvQCvKvNKN]UÍØÕÆôøúúâæàíãìããáÿþÿäâçâáúàåäââæöÏÝRÒ\YL~wqJ]VÃÖ@[tCArymlmnd~ru}vKCÛÝ_LvuvCSÛÅÐÝ^Óååúåûääîéâîá÷ÏöúåçáåæâïîéèçòÎSÜÕQY|daz|Ctxgzyybjjiolnlm`yJSYH@HYPßôØÇÙQÝÍøæúçáåæãâàúôÚÍõðúÿóýùäøààü÷ÌÆ×RÉÚELuwpMÕW^TØÖFÜÖpd`bbma`ooma`pE|e~s|gwrvtJrCÂ÷ÊÿäçåáïâãíâäçâãáæääûøáåñóÈÐ\WWKvrxfbcccd~yyyrg`cc`bolibfbg{qt}pLuttKvt_KHGZGEØýýøÿðÎØÎÍÂðýÉÛÃôÀÊòó÷ËöüüùûÎÕÙÆQVTQpzpOUÛÉÔrtwx~dzbjkhm`{wdzHuG_ÑÔOZSÕÌôþÌPÄßÌÿæãÿôöÎüàìäÈòÉÄÆÍÈÞWÕSQÜËÇJw|yuDMpxdgDÎÎVFqdeKEp~z`azB\CI~}@ß\\HdxsÜôÝÅEuAßûòþäÏÀÌÿãçæü×F\õÈÅñÑ@_ØþüòõDtvTÙO^pff}×ÁÌÀKzdIÖATWtfeOYÑÍ_xeJÒß÷÷VqKÓñøçüÐHUñôñåûÚÄðþæéïåÂÊþüûáçØDÜßÃÿøÆ~a~pt~zgbfe}_ÒRzmaevMuz`f`dZÁõSyq[ÝÊòÍ[SÙÛýääôSAXÒôúæñÓÔÇåããäòÎÔ×ÇôóÀÓ]]ÈòùüÁØZ^ÁððWXQI^ÌÃÍÕu~|L_ÓXutafJYWXIdmrAN@wtQÉðÅÙØAÑýçáääöÇûâéîâçÈÀöøäüþÎPÝðüöËÀOt[TÅÖXGqsßñôÜÜqzsAÆÂõÀXOBÔÈÄÏExx~HBNpgzv[ÛÔÛ\wYRÁÎÅÅAI@\ñòûúÞÅõüæáâäòõÇöó÷ÂY[V×ÉÎöÛ]ÒØ÷ðÊÙMsrx}v^_tuqGÛÚôÛ]XpLMWRqwuBTÄÁÅW×ÓÃõüúÚÓÔ]ÜõøúõÂÙÄöñÿõÚÁ_DVÑÜ^ZM^ÚÉöÉÇÁPSÃÚÐO}eLRÆÒÖWDÂñôôßRu}tLECvqqOÒÚÄÌõÂÖÈÿýþ÷Ò[OÐÜÁôÚÇEYËÌôÃÄSvSE@VIvp~NP\ÐÐ^vDÔRÞÊ]s}sIÑÊÇÌFGÅÛËñôÜHJJwX[]M_ÄÅö÷ÿ÷ÖÇÁóùôüÕK×ÔöççäÃØÝÈøÈýÃLJyvOEP{puq×ANG~ppAQLF{cg`}DQTJ}rCôýÿõPEq@ÛØÈ×NMO×ÆÍÌÞÙÕÛóðòÂ_FEÞÊýôÞSBCÆþøðÁ_wBVÅÇÒOtwMÝÄÖ\Duw^ÅÜ_pdgdrO@IurGÂñÂÕSHqvOAw|g{pÀÿñöÂÃÛðáíáôWMRÍË÷ÈÄÀ\Tôúú÷ÙQG_ÑÃÎXp{zwMDAvLCYÂÁÙZyd`wDSQqr}_ÁÎÈÓPvsprxf`ldM_×SÑ\IEMYSw~wÀËÆØÑßSÅþäâæ÷ÃEÑ\DPEZvLÕØÆËÛÜ×ÐÆÓÄÐu~ywJF]^XNY÷þåûñÍECv}Jup|rK@EÄÞÒW\QHM@LupARÛ÷õÌÜÞôõóÿôÅY]_QÀôôÓEGA]ÅÞ×AFEGVPD}e{d~M\ÚÅÒÊÏÿáùÌÖ_[pDW^BpKFÕÌÌÚôÚ×OFÝGp{ypvÚ÷ÀôÖ^A[õÀPÕEEuFô\BFwryG]tQÑ^MPùóÈÀÜWNØýÕÍòÍÏüìâååòØ@OÞP\Å×JtÊÊUÝÆ×E^ÎÌÙÑV^Zòçõöùô××ò÷ÍÁÚÝuXÙÔTEKem}z}MrMÃÜÖXKv}TÒWÖØÏÒÀáçåæåóÜÓÙTSXALsXÞGAXGuIT\YÑPZ[ÛõßÝÇÄØÍö÷ÅÊôÝÛ÷ôöðñÒDLvC}z}~KÖÇÆÐßDuMQ[MR\PÀüå÷ýüÅÃÂñÇSÙYH\\ØÓÅÍÕÍôòÉÔÄGHÖÚòÊÎôÜÌßôþÊùöÄññûñÍõR[DBH~t|ap@Ó÷Ã÷Å^[L]C_ÖuYÚÊåøúüÁÇÓÜÑZ]LKGwIqt@vrrq_ZRGuELYÄõóöÉ÷Éô÷õÎÚ÷ôÊùû÷ÛÕUAvME^AuurFÞÃÆÕ×QPÙßÁÅÔËÈþáàâæûòÂÊòÀÙ@tttDMQXw~mayyvrvdsqSÜÖÇÔØòôþøøúóùåäæøöÕVÑSÑ×Dpfypw@LLsdpJ^ÁÙÀVTÜÎùäæäòöôö÷ñüØÐÔÔÊóüÙw~yqvgyr}|a{EØS}|vDVQÄÊÅPKZÌþÿÅWEI^×ØõÖÕ]QËÿóÞ]HNDUÍôÃÝWVÁòþýñÀÐRÄÎÚÁ[w@SUÙÑYHH[SÔQNCPÄö÷ÌØWZFWWÒÅÂß^ØñÍõÅZw~p~~Hqy{{v^P@[usOAYßÞV_Òñòåçæäò÷ÿóýåËTY×WÔØÒL|}wpstuza~~rOX_qqu^ÙÍñËÈñóàììãøñÆÝÀØÃÓIuuHUPAtz~xedyde}pRÛñÈÙßRÁÉôûöÌÇÚÏöüóÚÓFFR×QXBtv|pqwtHwKDN\]SÞßÅðùúöÎ÷ôôöÌóýõÉCCÜÓSXAYt}|zpuN@w@XEOFÔÑÜÜP]XR\X]PWÞ]PNAÔ×UZYÕQG_tIJu[HLYXW_QÒTÀÀÜÑÒÙÛÐ×ÛÏÀÄÞÀ÷ùùÉÚÚßÔUÐ÷ýðóñôöÈÉØÖÓRV×\ÖUX@uNRMFJ~w|~||y~gacgrN[A^ZA]ÇõöñðñÿÿòøüüûõôñôõÄÝÜBvf`amgaofu\Y]ÆðÃÌðüûýøúüäàãæáïàûõ÷ÎÕEgcnnkhlgdfveLCqSYQÓSôüóÿñäàûãéìçÇØO|yf`xqYÓÛÉÇÜÄÊññöÎStwHFGLÖÔXÇôûçøÊId{r}xsysZÐ÷ÏÐWLÕô÷ûþöÌS]DÕÆÛÜRWÚÉûùñÝw}~}}{x|}LEÔÊýøöýåûýððÍÕUÝRBTÞQSÝññÚVYz`gzfg~rqeZTÐÔÚPÞöÌöõÅÀÐÂõÆññÞÚØôðõ÷ÖK}@vxt}eerFQÌýðõóåüøûýðÜÄÊÞóþõÍÓÅÀÇÐLr}eccbddaexwAÜð÷Åõõñäáâàùçäÿùçíàäçæçäñ÷Â[qgbkknnoaquERIJI[^XÓÒAw|rOr_ÑÝöòøùÈÈÉÕ[ZCBJ_\LGQ×ÚÓ]DuqZVÓÄÒÞÕY^PÝÈôóåíëâàáðþòñÿËÉ÷ßÛöüûþôËPYÕPÝEvuzdv}wMvNKLÆÄ_MdfaegewNGMCÓÖÅßÓÚÊÎóååçåòñÉóçáäþòçäúòÚWpacho``zgevu[ÝÇôÈòúæíïìãäúåúäáäýúåÿò×_wamnjnnfea{|t]ÔÒÞÔßÛÅÊôôñÇÌÚÞÃÎôñõÝZqLG|xdyKXõöÁÌÕÛÚÒäçåìàääüäùÂËÏÚÙXÛÊßýÁFTEÝØvH}{q}F^tH|fpw\ÌÓÓ×WÜPÐôÇÌôÅÇÇ÷äúóÜMCrz|{~wvKDM]OwttDYWÀÄÊÈßÚÆòûþååüÿñåáû÷×tppqwHtv|p|{tp~xd{|pMXLtvsOODEBVSQÝÏÿúýÄÕG@OF\DYÔTÙôÿáãàâãíâàçöÒÐGJAKpqdd{y|}DGq}wpp|dr~yYEÐÄÍöôöúåååçæûÊõ÷ÀÝ^]NrIMKHJMG~pt}HIsecdx{tMÑWDÔÎ÷ðøääöÊòÊÇÈõõWWÅ×ÄÍÍÁOCRq~wJehcfdztZsvÑÞÂ÷ÿåø÷äàæâáæüÂñÊÍðö÷×HßÑßÝLZIyvqzy~fb`t@~~tYq}GQNEÜVLIRÀS^ØÛT@ÑüÌÛÜÑEBEßÜÜ÷ùööñóó÷ùóÌ÷òüþÊÎúöÎõ÷ÏR@TC@PÑÕN}v}gya`ce[@tCvNvNÀñññõ÷þüåùôöÉËùÚÄÃQÓrde|qgohhbcfeepqvTÙÄÝÀÎÎùæàçäúåüÌáèêèúÞVwZNruJFMtF^EHw]@KÅÇÞÜÑZYLDßÂ÷ÅÊòÏÅÜL|u{s}}E@×ñöÉÎòúòöñÃÒF@\KB^Lvagmcr}zzimbnaz~I_õýôøæåçç藗“”éãæçûìèæÿõäáóÁÖzcbmnnhjikcgeq}e~z}tEÍÀÖYSôùðøüçìëîâûÁÙSCLEÞËöÂ@tvtEQWSQ]Kw^\SW×ÙÎòúüýÿüñP[XFÐÖMutLWØ÷ññ÷ÞÄÏÄÊÉÂÍØUÒ]NKLtdf~HYN~gmlgy}qEÖÑòøúáãëéìꖗêéìáøúäøúËÝQIFWur~`ikihhbfyyz~D_TÓØÓUÝÀÆÐÓÛ_\EÄöÀôÿðñÿÿ÷ôÎõôËÛ÷þþñùýôËðõÆÀÅÝ_@MOA[urstptw]ÅÇÊ]LGrNMrvruWVÀÙ\ÒÓSÙÒÃôÁÍÅ×ÆØÇõ÷ùÎ_ÕÞÎóÝ@sf`cbambmicepLBÖÐ]Ã÷óáçáîâìïíèîéîææàäùTv~niijnofx~sY]Ò÷þáçãæòúäáïáæàæìâÿøÉÐÐFuvxtMHw}vOLY\ÑÛVuNpvqf`lnbof~uÜÑsspBPLVÑZÅýäéìéèãäçâéâàøÉÍÖFÖBMJgabatxmohkmb|~~Mpt×ÒûäÿüõÉóðçáåîãåäåìçôõÑTÂÊÄÖpzaolnczagcca`g~aer|JqDÌÜÞÐQËþûææåââæûÿøðÙßJzrt_Ð@Ð]BÃÉöñÔÉÕITÜÍñPÚÂPØËúíäáüÅ×Ò_ÜtsLFSPT÷ÑÐÁÛÌóüíçñûÛÐWwMHzz`mzg~ginkcoaciac`wCTÖYÆöæꔗ–ê—•îîííâñðäáãáùùWX_^[r}C|ea`z{ffcfafxqI_EXB]ÞÄöÊÙÆÉüÿüåúçþÊÜÙÇ÷ÏÞÙÜÝUGIuOJKM[[ROp~}q@uHE×ÇÇß]YSRG\F[RQÓÚÂýóúúûçåüÿñüýöôÞ]ÕFFqsq|{t}~ycg`ogapRQÍÌÛöðÿà蔕锔•ëàìäÂýÿÃÓORKwvwvxxxdinlhocgdagefgeLBqI[QYEWYtTÎôöúî•íæáãíì”ïäûæííæàäôØÆôÚEEpfcmdd`ez~rz~}tÆõÑÖ\ÛÝ_ÄËÀö÷åûôüúÉÐXÍü÷ñùöÚOC\u^ÂÒufpZp}}pdb`y`of{d}RÐÂòúàáãêï锔êàäåúðñýÏÃÞÊ\OpsdkjjodalmdpHUÿäûüüäúúàáúåäøÊÑÏõÅUFGU[STw}uAFGWÄ^B~rEXÛóÅRGqqs|sxeblzyCPCqp@\ÓÚðòûùþçúçàääçûäùþåÊÂVKMwIREs{d~|{tu}`kobcqADK~N_QÜÞÚÛRÕÚÇÊûúÿðçìíàãííæúüÊõÈÁ_v||zacmlkjklg~xfd|uM^ÚÌTRQÏþáèãåøûäÿÉËÇPFJAZDÔBwGEÙÇWÚÝEtyq^PÝT[PZÐÉßÈÁÐÓGvAWôôÅöô÷øøçæåùøýýøúÊTÔDwwrz`ihjkhndqCtt^TQÓñàáàëéìïéëâúçúõÁÉúðÙõõØÁËóÂZE^LqOÐUqvL~sDursqdgvJuwFNDÕöòÌÛËÂßÊýóóúæüõôùðÞSWRJtTVHwLNs}F@tuNW^uPXBNGQXXÃ÷ÆYNTÝÖÆÎÇÀËòüýóóÚÔRÐÒ_TÂÚÜÆDtsswxg``zfdMNOPÌÂÊøâìåûçáçäìïûñúççøçùÐvvOse{pz`d|zzeprfa{dxss~yvwu@TÑ\MYQ@]ÞÇÜÌúåçàïïáíéíþöýñÙ×ÎÌÚÀÏËZ}uH{d|vz`zwKtMÜQÓ÷çäñÈÌÁÞØ÷úåóûöÀÄÚÎÂÑT^@AÓÉóÛSJvpvItKchicarIEqd~vAPÒËÕNJYÂôðÿåùûæííììáóÑÝõóÊÈô×KwwC]ÓUTGwIM_GFÐÅßÂÿæáçõÐHJZXT\CIMGWÇñðËÂÍÀÀ÷ÍÂÕBQõöýòÍÝupHtdaikbzsNNFÅõþþóúøçì””éàï蕕âáô]R||Muu|fwrse|{cxpJZLFGwYWÑÉÃõP}JPSÐÕUÕJ×ÊÈðüáâðüûåæóôÈW@ZUÑQD[pmlfaaayy}eey|wCRËÜÇýüåääåúÿùääûÞWÚH}xrOr}u[VSÂôÝA\Ý[stPÑ@]Ýöý÷úäñÏôä÷ÖÙÈß[ßÆÆÒVÆôðöô÷ÕpKD\E@RP@wvppyd{df`ld`ce~ILuÙÛUÕÊðÂXGRIBZVÙ]ÚæàçåââöËöÈõØõùýôøüäåðäÿÖÜÕVOg`binil`gxvzdyv_Æöòúóõóòý÷ñåðÃööÊòòöôÑ×@Juax|okbdesHpsuXÕßÙõôËUGÖÕÖÌ÷þúÿüÃÓÂËõÏÀÍ÷ÀÀ÷ôôÄÞTTÔGVÜL|e}w}OV^P]BUÓV÷ÏÞXqDZt^ÇóûýÉõÎÃÏôÍ]LprLHRÔJZDKÔ\Óñ÷TEzafm{sqfap{yXÑØXGR×WÆÿþõÀ÷òûøûãäÂÎÈøæáìâüÂÖGLptWCgcaerX\ÑÐ\^QÜÛÁÒAvqHÜ÷ÃôüÑÕ_WðöÿæñV]Ý÷÷ÊýûÃ[tKJsFF}`nmaae|vzl`gs[PDOeJZôçæïâøþûþÿæåþÈ]NMVÕÁöòÆ[L]VßÇÒVuSÉßóðóûStßÃôæä÷ÏISÑYÉüøÃXryezNP[@uwJAÜÿòÎRy{zgBIamjm`}ÇØQVLqÕ\ÂÿÌÉÔØÇôýàãáçäùúúþäñÕNMLÝÎÿá÷[[CPÂóäüÆVWSTØÌþËWI~ez~rx}ffeg|ZÜÇ×N]SRôüòòUÓÂÈúáîéæ÷Ç^IWØRF|`ddf~YTÞWtL{wØßÒXu[@]õùý÷QwpyYöôÎÜCÑÃÉùàâáçÛ]CZËÌÍÉÒÑÇßÜðþÁÝsxzrR]EB~epuÓûæçÿÝÕÇôíàùòÈÔ[EMÃÊUÑqfdf|eggmnko`}Cwqal{N×ÆÇóÌÜÕÁÈùâàûÈÚ]ÓÉ÷õþóþÿøäãìãùÊßR\ÌÂÛ\txdw×ÁÎÑ[qame@RALIJPÕÄØÌôûñÃØÂýËÄÃØYUßÒWÙÙØAglcpNNG@q|rvÙÄÀ^s}Z_wAQVSÐÚÓüùýÈ@OFÀÏÁòóÚ_WôýâîãñYs}]ÕØØFtNGßÀöûÊ]RÕQõòÀÈÅpOÙßÜñðÊÞyg~vE]ZEHsMQRÜÎÑ@qxtVZHLt_ôÄÑÚÞCyacepB^M]XwAÓÝôææýÙYÕÇ÷üòúýöåáúæàûÄ\BLÓÐTZXDOZÑÅÉúöÜNsffs_ÖTÛP@@XÞþÄRCq{yE\V^]QÍåïèëçÆBwsvÙØWCN~dxrKÑVp{fcietN|qNMPWÏÿýÄ]ÕÃÑ÷ûþÅÒUTØÜùäöUGq||FÄØÂåçäääìèâùÉ×ÕZZÆÞGWP_ÚÄöùßrahoccsFIARFVÚüàåÉÖIvpdv{eryKJFÅFconhczXÔIu^FÑñåé•úÏÛÑVWÎðññáãæáàíãõÓTPT]ÔTÔZVÅòåíëïôu~gnjm``mayuAÓ÷ñ]wA[KpTßÜUÓÈûçï•ëä×tvsxD@p{gds}wÒÜ^u{ep~K_^XÓõääøãàòÕIwp~vBwuBuVËóïêáôPIAK[ÁËÌôñùæçîîäÍRYLez|pwT÷Éñä÷Ó\wswNTÞPX\ÇÍÿíäÄ^pxfcagdaeJÓÐÎåùS|y|egdrItÝÂüàë•ú×Xv~f}ZuYñä픑—ãáàæñÓ[vuswÓñóçáäÉG}}`olbrguÜÞòäàäðTÜXMIEÁBHDÈðþåøÀÕNq}edeqvI^ÏÈôåçüôÕuelagg|@CÛÜÚôþòßI~updO[ÐÞ÷æîꔔèáÇT^vQÐÌ×[W÷åíáôô^ufytXWÕØÎåæâàðÇQLeoi`mfz`e\Ä÷ùüçýßL`cqawRIJÁüðÿóóÄÕpd```gyxrRÊÍóóùÿúØÐÓÂñÞòðýûçûçàáåàõwrrOOG@ÑÅ÷öÀÍöÛÙ]z{cbgM_]SÍÃ×ðüõöR`cmncHXÜõÿøàíâííñXG}vty|HQÐ×ÓÄYLueknndr|}pXVÛÍóüÿòÞ|MUSßÙØËýðæçùúúôZ~uTDSFuÁùýçâîãçåÎSDHp|vp]ÉÞÔÂôÑßÛUDwechilaswXÏ÷Æ÷üôÐKJtuswHp||HS^TÎQreeeL@EWtZ]ÔÎõóáýÀ^NQÄÁSÄÆÁÈùãè•êàöUMIGÑHTÑS]WÚÎòóÂK|{fflkbamzuÙÊðþÈõÜQA_X__UVSßõñô÷ØÉ×Gq}vprNuMPBA[ÙÖT@vtrJLZEOSÝÅØÉáæùÀt}{``xZWÁöÿýæëïíãõÌÀ^ZIJtA]ÜÂüïáåæòUEw~ONey{qCFÄÄÜÃUK^[qut|wqFÅVÞÓ_ÐNtÞô^NIyqC_ÞÛõÇUÀÓtstzrA{M×óü÷ÏÐÏüÊÌþ÷ðòÕFTÈäççíáçþÌÚóôßÞÆÐLvHES^GVNsqÕ\NuL^ÞØÐØRFwqgfgOBI[\GUVßøüäóÿÈTWP@wYÑVZÚÈþøð\R|bcarxxaay|EËøöñöÝÚõóöøåýúþöøïèúÁP~qY^×ÀÆ_GIYÐýäÍÅS{~PÐÂ÷÷ÅÖôÉÙÊþ÷Ö\xkbcmed`asvvAÿü×ÒY_ÆÏÞüõÑ@B@JVõñÔWGOwrd}JtsuOwAPÇÝÒÛÊóäåãèíçäüðåáìäÏÅÆßÛUß÷ÛuKJpKBÝÙTu]V_ZEÛÓJuXFRÞÆÅ×qwO×ôõÿÏNq}ax@QÒÓCLUYÇÂóÍ\ÕÕDLÒÜFpfft@SÛòùÃ]CFOÞöõÁNpFÞÆüäæäúùóõýçþýÎÏÁÈÞôúòõÇÌÇÓÞøõÓ[M^YDÛûôÉÕ@w||DZJKpwwvM]_ÖUSJt@]V\@~~rJ_ÎõÎÀYwJRÏðÂÜAA^]ØüûóñÌÜVWÚÆÛÆÙÊóðüùøðöÍ×ÒÇÈÁÒÒVSBÝýççùåôOtwJv~sdgxrNSÜTÎÌTVX]S[ÜQAAWPWÃôòÍÔItDÙÓTSJvCB[ÜÐõÄ^NtI[vq]D\ÜÄÂÇ\ÇÔKwqs|tRÕÔRDÜÁýýòûÈØÏÄÞUZÖLÔÂÐÏÚÃÊÓÔßUT]NwOK@Ø]RUÛôÏÛÞWPÌØÒßØÛÛWWYGQNqwNq||qJ@ÔÌØÅßÙÉ×]^ECsytNX^TÕÔõPtw|xdg|HDÆÊñðõáåäàäù÷ÄÃß]]U×ÐTÒýòÝGygfmes{NJXÕTÈñ÷÷ÿüûõôôÁôüýçäóû÷ÆÒZgfc`daa~|rB[ÆõÅ_XNwxd|xyZG\ßÖõÃÉØõüþÝqt|{}uITUÌËòÈÛÑÕU]ÇÊÌÍÂRÓÖ×UÒÌÍÛÜÚÔÛ×^_YÕÊÂÀÙÜÖWÒÕ×\QTÚ×[_ØÙÒöùðÙACLag{qCQNOEuJrx|tJq}yx{ytIXÍøÿóñóÞÑÐÇðåäðßÍüòöÄÆßÓLKS×FKT\WÃòúýÐ]GDAuK@VÔÆUQÕ^Æ÷ÿäúô]taaxg`azuMZÄÇQQXOUÙôö[u@CZEÓÆÂØTVtssOwK_[@s~OÛÎÎÂËÁ÷óÇõõÐÅÂÎùæãáûÍRJLJN[ÕÂÖFDuJP×ÝÆÀ^Nu}}|~pNL_TÑÄÝTQ_]ÙÙÓ_DRXBVõôý÷ÌÆ[HCG[ÖÏóüÈÊÈËÍÙÝ×XKKdgxpvtGÁùçàæòÍDqL[JEÛßP\Ó÷ýúáâæÉT]×[NIAtqYÓPIu|z~DQÓYwLvssvÓòððüÏÕÑÏñÌùãâàûðþúþÉÜÑP@pwKqr|daBÞÓÒ[ts|ryqwLSÃÏÛÌúåùãïîîãåöÁÃTÔÉÅÍPCqtItxfypvWÄUÑSÆÛÙðòóÊÐAG\UßôùçäåøûçàæÓ]C}~gcbcgdrPõöþåÈÀÉóôÜÄËÁßÙÛÎñóýÿöðöôÓqp~gblgqs|rqsxJØÇÎüýóÈÖÙôýþðþóÏôÍÆPÎüûÿùÿÌÄUQ_B_Ku@|dz~|v[ÏÈÊûûúøÉÞÒÞÎÌÛÙÓÛñØ^×ÚËÂÏØ[ZÄÀZIqNYW×BJwvq|xytTYwCGYW÷áãàû÷ÒØÀÛÛÄ÷òüûóåæäù÷ÌÂÆßÒMvILF\ÙËÿåýWUÝFvqIqqrr~F]ÔÏÈ÷òÈÖÜÊõÚFRÙWßÛ\vNF@RE\ÌÈÅMqy}tGN@Hqs{}]ÂüûûáçðûúåæåõÂÝPZNLy}OSYDÔÖÑ]BLXßýáçùöÛÝTÃóåÿÍ×]DI@tswtB_DXÔÐvgaeywZRXTQ|v\ÝÆÊÿ÷ÑQGLRßÂÄÓ××ÝÏÞGW_XWÖRvvv~tSÄËúçÿ÷ÏZOXSÍÊõÙBt@I^ÞÍõÊóÂÇÿøÎÝVWZ@\KzdmnlfdptwuseeHUÝÎß[_]ÝÉðøçåàûÍÁWÔE}pp}pv|xdgzuZÖÛÃVLCtBÒýäøùùõÄÛöåúÇÕFII~zf`ddyvKAVBM]ZÂðýûðñÀ@pvtNMMu]EvqtIÕVV××ÀÆßÉÒQÁÄôÈÅÚ^MFu_ØÑÉÃXYXqpeuÄÑÇÞDq}pqvEE^ÔV×ÕGDZQÛÜÆöÈÖDws{qOwADu~x@GLEÞX^ÞÐPBÝöñááúçûýñÉÅSER@wDV@JprqYËÍÑðÎÓ\rxxIHu_ÑWUQWØÆôóÎôúòÎÝR__ÔÕDØÞFGwzep_ÒGJp`cmlg{y{pWVQÊËÂùàëéé”îáæöÍÎÄÙÄñÂ^ÕÑvNEGEGGEr{epOÕÆöüóðòðôÿþûþñöÞ[AOMYYF^]@Iv}ddrMM@ÑPJJvx|svFJ}pKu_óäçáíìãçþòöÈÌÃÆØÙÛÖTW×ÇÁÉðöPpwt@ÔWÓÎÉñüüüüýúøøüûúÈÕ×ÕSßSÐðÌWG|ggd}}|uJvs|}psvJ[XVÇÁÂÆõäàæïèîâþÃÝT\Ntt~t@L@@Pôõõùüý÷ÒVX@×Øõþý÷ÊÀßÎòÿôòýòòÍßÐÐWWUQ_ØÒYpg~uwZß\W^ttIrpOt~zrpuMTÉåæíìîîáûÉÝ[RS_X[Nwxw@F[GqB@JKJwEQÚöþãîïáæààúäæþ÷Á×ÐRARÒNÖ|KPftONFÝÖÑÆÏÕFwxe}}wNvCvCÜÄÿâïïàääóÌ]rp|{|vCGHEÕÑËõÈÂ^ÖVZÖFAÐQÕÖ×ÐÚÆÌÑÙùòøûÿþÛ\EL×ÝÐÕFv|de}z@ÔZ_AZPLt|d}r}N×É÷ÍöúæìâââáüÄ]Nqsqs}}rtBVVÝÙÖÑÑWOwAFGVÃÊôòÿùõÎõÏòùñðÈØSCtr}}w|qq|JÕÐÑQ\ÝW@sx{~ys}}qv]ÐÙÌüàîé”êâòÒÒÆÞÜ×KZCvqwHQW×ÔAÝ\Mv~uFMÜÌ÷úýýåýÿçùåöôòÝI~rJJJu|xagz|YÐUMXXqe`fyss|GCNVÕÆøæàæäàÿÓOqvGWQD^UDWÆÄÂúúñÃÂÚ_vrODTUÕÓÌÚÝÅÁÔÇáìáààóØ^RÕÁõÆÔÕRpy|rOGw~p|`lhjcfdxvNM^ÖÌýâéîìãðÊÙÓWUÚ\NO]LFLMKÕÎÀÚßÔLOyeJÄôÿòööõ÷óòþãäøùåÉ×X}xw}|swXÓÐTXGKxydgfegeyrMp}N@UðøåçåóÏÙÖßÈÈÆÏÛÐT]ÑØÐÑGJHJtxdccfdqAÄßÃÈööüáïèìíçåùÊÀÚÝÜT_XOFI~dg}tp}~}qghjhcxyGFKÕÐÇóæííâîéàüÂÌÒAGS@Hu@J|~JDY_FBMF}~r}sGÓÄÙ×ÂÞÑÃòóöñ÷ðüðÇÐÒÙØ÷ðÏY]UHwJAwpAFKrx`hkmzvp~ARJZ÷ææìîíáääÿÌÝÂñóõÓ]ÚÐV_^HqMt}dzd`a~GÀÍÂÈËøÿåáæäàâæúüúôUELJCJtxxggxr~gvtCIup|y}MUPRW×Ý÷øåÿáíàãàæÿ÷ñýõòòÌÎÛÑØÁÒGvQÝXÕÖMusqB[ÌÀÖØÞÏÊÉòóóäåÿúþðùÊÃVEQuxx~{rydeeyffdbhofezrCBYÔñçàïèîêêíéìçåúóýÂÜTKFAtvrswquuXVREWÝÆÁÒÏö÷þäååúçáääæàæúûóÍÉTutzd~~q}~qvHMv~xeabfzfyf|DÔ×Ô÷çÿúââíìîîáíàòóËÒÌÆÜRrt`ezexyzzvÐCqÓÖÀÿäìì薕•–•éîäüÏÈÅeccno`cbomfcxNvpv}r{||ztHFÝõóýóúåøúüÿåúóðñ÷ÒBOt}J[EXZYAFSPBANNCZÖ^Y]ÑßË÷óùûäãî镕êîíæòÃ_p}prwgcblhjlacbmccdefzMUÚøí镗êîéëîáçäòÊÉ\pyyg`blmgyrOUY^ÖÖS^Þ××Øôÿþççøúäûåäáããæñ]Drcbb`eppvNLHqpqydegcdd`fqCXÕ×Ìøäæìëêê•êéíâåÂ]QÝYHebblhkiaggxzytw|pBÛòçì‘––””éïíûÈUymkjjjjnhfruBM@JHDEXX_ÛôóçåòùËÆÃõýûææÿüÊ]KstDYÖßD]ÓTPPVTßÕYYLp|gcg|wHGAÀñòäâꗔëïìæóÅDKOu~fmnnhkfvÅüä藔‘—ê•••ê”èìçÞJwzbmhkjjllfpGSÝÖÞÎõËÀþåäãíïïáæþùççáçöÖ\rbko`ggr}vp}}qMDDAHx`ccf~z~tNPÔÙÌúãïéè딕éíáçðÈÖ@pemhknafdged{b`~^Áñá핗——••””•ëìäùÙtgbmjibaeLÑÝÇÎøåäàçäçûýòõõüåùÃZNpzdg|rt}wBDAtJVô÷ô÷ÊñÇRHJCM×ÆÆñòÿúàíïîãâíéîàøÏÍÓK~glhholc``g}TÀòåáïïîâàáäãììíáþðË]Kxgdf`bbhilbg}LIÔÈñäííáàïììâãâãæææûçÿÍÙXv{dffdryesKr~ab`gpI_XGJvr}pJY_UÌÇÞÀÊùçàæâèëèëéâýÛØOgabkhomcz|rMOpAÕÒÊåàí•””••ê•îæþÈ_I|fomooapQÍåâêëêèèèîïïçÿùñÄÑ×IvvvvwtOM[ÕPRQÕPÐÊõÆðúúý÷ÏÖDOuGÓÓÁÊËÁÂøäþöðùþåáæûÈÀRvw~fcokhkhlniodrNQÌõôýçæáààìèèééïíçäóÛH}qeabcmkkiib`eFÙóàéîîë•ëîîê”èéìíàúø÷ÃXs||~p}fe|{za```a{ytvvZYDL@G]ßÙßÇÝÛÍÍÑÖÐTÄðòäçÿõöüÅÖÚÑÑÙ×]FYÕÖVENR×WßÏòòÊøçãìî땔‘‘–êïâäÍZKyalhnapTÛõüçàççæææäåÿó÷ÏÛÒtx{y}~NJvtHS_tt[ÓßÁòùääáçòÒÚÁßÜÍóôÈôüäúùáãàäçàæùóþòÓOKuveefbhjolmzN]QÜñåûøæíâ떔îäæäÁ^pvvalnnonaa`fwCRõäæåçâïãàãïéâáâïâáçòÞRE]IJHqfezdfcg~egztqypAIuq@ß]ZCLItGVYZZVÕ@EÖÉÈÛõÏÉÃ×ÚÄÓUSYwI[N}exppysqEHMÑÐÁÎþìëꖑ–••—ëáúðÀS{fmihhcex_÷üüüúäúúúçäþåýÐBqpts~e`mds~}HXUWØóúþþåúðõüåáøËÇPuuÔÇÝÐÅÍÀÅËþùñöôÀÖQXR]tq|{c`dojhc~}yzpLÓöáíâììçûææõÜÓÕQGvuvyfadgz~vGtKRSUÁýäøþþþùýÿæçûäæø÷ÿóôöÊÍÇEvuu}gzxyzzsIrfcablgzvBA[@ON[ÝÇWÐÐÛPSÍÊÞÕW^BAÒÐÁÆÛØÕSQÛÄEwtwptÒðýÀÚØÝÝöûàî”•êêâóËÄÝ]E_VHfijlo`alobafpEMKG]TÓÊòüóôÁÖEFCuvdddgd~BIyvDVÁþãîæý÷ÀÁÈÊÿùò÷ôöõÍÃWX_ÐÆÎòúçâáûåòúãàæûþòÂÝÝÜ]rljonmcfqDÀýûãìîéëèãóÑts~sC@Lwzcmbd|ttHOuEÆûçøûçãì핔–•ïìçÿýýüýÙÔDKHO^Zt}gdqIWÅöÊÄEwKNvqJwpsvvÔÓX@qqvEÖØPuuqst\Ïü÷ñÿòóýääñÑJpqrvZCLtvL_UÅýùýÿáí딗•ïçúùùúäå÷ÎÖBwO@AKxfgcl`fbl`axv[ÍåååäûååùüýöÑLKy{~e{zgevWÍññòöÃõòùùüøòôõÁóçûÈõÃÜÐÞÁÿæÿ÷ÏÇÄ÷þúäÿÌ÷ÈÚõñØ[Jd```m`mnhjjlxK\ÝÙÁüüùãáÈÃÞZFJOVÒBtKMKH_ÑÇÖu@UVÄÎÁUÞÅÃôóòàìçûøäæáççäøõ÷ÌÉÿòÆDX^SVÕÂûþÊÅÇ]IBte`mnalnaedaeqE×ÑÄòôÃÞÒWÇñòö÷ÄÑÃßÛÈ×GNvwvuCQRCZP_XÆóþÿþåáì뗑”ïàçúò÷ñþ÷ÕDXCJA\YN}{|yxxdmiio`d|K]\DSWQÐôðÛS@OJ}t@pacg|vKFÒÎÅÄòùþùæçü÷ÅÈÍÒßÜDvtMSÇÎ÷ÿþôÍðÿûæìïâíãïíàæûÃRZYLq|dzajhlmmgsßÍÎøçøñöòËÜÔÖÜFyz}zdgdggg}D@D^YL^ÒÛÊùçâãäåæãáâìâçøùçùÂÀÃÕHO_SP_RÛ×]^ÇÌÚÛ×XrggealnljicxvB\ZDPÖ[VVYMHFÚÁPMDMedwqwwCGqpZ^B[]]XXÜþæçäãâåûæàææáàäóÎöÂÒÕS@uGÔØÖDHHec`qyp@Aqy~wquYVFBDÐÕLvwKadp|||uLvAWÐÜÞÌÍ_RÐËõÚÇÞXKw@R\ÅÿçúäàïãäæàçýþæãçýôÎÖLt_XMIupg```a`cgbibeHG_ÇËÂÍôÿñËËÀ^JNAwd``oogdyqutwKÜÉðçàíàæââàæççäñõËÃÍÓW_[VTÚÎÉÊ÷ËÏñøççþóðÙGFEBuq|alkjonlfJLVÉÈÇÝØÁÐWÞÅÝÔYMq}ye~y~qv~~}ppNPßÀÛÀÈôðåâ蕕èéèïèëìàæáçóÈÜ\OzgzypuKus|e~su\TECNJCuuKHOtuJsrabae{{zyxdzv^WßÃÄÛRLVÛÉöüåþüöÂÍÃÅÂÂÌóäâàåþòùøòúçææäøýýüò÷öô÷ÚR_GIq}~zeaccmbdID\ÛÃÄÀÂÅÞW_FEMIqe`mkkhocg~suqvCÓÈüúäæìîìïïíãæûùþüøçûñ÷ôñöðýðÇÐÔØõöüù÷ÎÝÖÒR^ZBMt||~e{{fdrBSÐÒSNwpvN@[QPupps}{xdaafxppwNOE×ôóøæâîé딗•êëîâæäåÿòóðÊßUWWUÕÙñÌÇËöùûñÌÇÍÈÜ\Z@]ÑSDwqJM@BIuwp}{z|qreffgeu@Os~rKut[WÖÞÄÉöþúüñÉÆõøáíïéîïâãâ锕èâæáààåóÃÚU@MYÑÖGs}|xexrttwOXWÇôÂÐEIrzfffdedd`cblonom`dyvBE[SQÇõùàéêꕕ•êèèèîïïïãääääûóÊÎÂöÿùççæåûààáåóÀRutv|yfmhnlcfg`ocfy}rpwtABGNzaazwZQÕÁÍÂüåàâããääã镔—”èìãàããæûþýö÷ðôÐRZMOKNAFBqegcijna`fdeeexx~xzzdeeddzrwB^VÜÞÖÙÀÎÆÈþøùøÿýÿùþÿúççæäþñðÿøùúûÿËÚÛÞSBp|ppwtJqq~dedxqJJwsyewtr|rs}qFBB[YYYGRÕQVVÝQÕÏËÍÒ\ZPÓÇñÿýÿûòÿüóþÿøüóð÷ÿÿ÷ÂÙ_ZSY[Orggd{vL@MJNZCI]ÓÄÓYYYBtKG@uGDZ]RVÑÒÒÛÀÎôôÆÌÌÂÈ÷÷÷÷ÆÐÖÔEp}xz|rx||z|wD]YXÐÐRÓÀØÔ_ÔÐVÓÒÀÁÑEEMHGÖÅÆÍÇôÍÉÿøùøûÿõÄÂÂÀÀÈÃÞ]]ÙÉÆV_SRr|efmmbmg~JEtruGHJ^ÙÖVSVROBIu@KuuvCE×ÙÜÝÈññåáàçáàãçúæçäûòòÎÁõ÷ùñÂÀÜ^vK[Npwprdccbmhnnhl`f{dagffdsHIOKIs~sH@[^Y[ZÝÀñùüþäàæáìâããáçøüùýðôØÕDWÚñúùðö÷ö÷ðóÀÓE@txeamijjjhmohnlnoba{{z~wtOX]UÓÛËÉöäàéë•êèîèèîìàççåùåäúòýýñôóúúøöÎØVADDMHr{aaggdcaalomaga`agclcgdabfacewZ\DÐÚÜÅýãííïèëïìéèìáááçääåäÿ÷÷ÀÒÕÜÀØÛßÕÕE_ÚÐDuIOOSÜÛÀROFCtpLI}zgexdxJrfzuspÑÁõðÂË÷ôôöòóðöñþüòøúòôõôÂðåøûù÷ÈôÀßÚÛPZF[Y@[ZMr}ptMOLK}s|~qBSSYÖÙÀöýåÿóòüÿüåæçþöÂÍ×G^SGtKW\M]ÖÚV[]^]_ÍóÊÞVTÕDA]]XuCQBMÕ×PIqvruRSDLK_RN[ÒÇÍÏöøúáîê•éïïââïîíçÿðñÂÒÆÎÇVWÅÓPÖÞÓNygccfgg`lbconcc``ztwIWÇÃÑQÜÒQßË÷÷ÆÔÛÇßÆÈÈÊöäæåáãàáæäåýþåæçúûåäûñ÷ÊÓÔTÙÓDRWP[Iurgg{~edzxza`ffccfygd}tIwqvpxtTöýðþûþýäàâáâéîâ압ïãíïàúäçáåùþ÷ÚÛÏÉÅÒÜÑYuHNL}zedbolc`llmcllmbonl`fazsrptZVYÔÉÿÿúãâääæáâãàââáäçáûüþûçåûúùñ÷óÎÝÚÞQEMMuutJGCIOAQ_KHIv||~cmfaaggdgddrIvMPÑØÓ×ÃËÍôþå÷ôüððýüþøùüäçäçäçæäøÿöÁÒÕI{ss|~xzeedetIsp|~}rqssFwrD_QÕÙÁõõÚËþ÷ÌÈÎÌÁÀÚÇß[]ÖDPÛÓßÙÜÄÍÛÝÌÃÑS^_SXXBKuwqvwEÑWTÝØØÂWERXJuHvJOtwv}sJq|tÐÝÚ÷óúäåùääåääúûåý÷ÆÁÀõÇÁñôÙÛÚÇÔ]EIt{dddccblboimaaf{~stJLqsstI|xezwqwDR×Èýòçïìïïëëîîìíàåûø÷ÊðñÊÄÙÏÏÀÙÂÄÑÞTD}ga`cbionknmadyzy}vJ__CODRFqOw~dfy|qtDÑÎÊöúúùçâãàíîèíãâàáøýüóþúùøÿðüýöÈË÷UFAwgacoihhiilllmcbccnklcnbaezdNXA@YÜÊôýáàçæââçäììáàããåøåøóðñðõÍôÊ÷ÂÚ×YGKMCNBHvuJMÐÛÓÞUZLF\_RCtrz`oommmm``ce}ptNC\TÍóùúùäúùúäáãáæøûúøæàæúøøòõñ÷ÌßT]MMw}pvsqqIHLYK}{~rzdexdegbcccdsrvYÑÍ÷ÿúúÿýûúöÈöñÏÂÀÁÜÜÑÙÈÌÚÚ×[\WÚÝ\MFAwvLV_]ZC@WÓÍýùòðöóÿòüÍXZWZtM[Z\]LuC\Àóðñüüöôûÿ÷ÎÎôÁÙÜÓÄÄÕYNuNT×PRDAGZSÖNwrMKuHwuwNAtK[MGONG@FGu|z{vLFYVÝÚÂüäãïîîíïïéèïììáøòðòôÆÝÝTWTÕSZJJq{dge`gd`onb`gxtFSÔWÓÙW×ÜQ]EWß[FQ_AN[\PÞÅñååäæàíâîéìííéïàáàäóÏÊÈÏÈôüüðôõËÌÒÝZtq{|~fddciilobncd{`nbmlbzgfexqHqtBQUÂññøåàãïîêêêêê•îâæáàääúýÛVÆÆÇÄÃÆÝWPP[NMGHp}pNRGG^FM^R]QQÝPLtwtqx|yd`cg~vu]ÞÅØ÷óÿüûåúæâììâááýýññ÷ÂõÏ÷ðõÈõÌÛÚÉÉÛÁÂÍÌÐSV^Y[PDANL[AppGK}y{zx{ss|xyyO[S×ÚöòýöøäûúåúþüåææçäåöÖBD_U]W_Ou{|ruOttuswHÕÁÂÇÑR\QÛÈÃðóûåüòòð÷ÍÞV]S^ÔßÚÜßÒÚÆÌÈ÷öÎýóöÿ÷ÍÇUENGSÔWELKCD\S[KqzedgzrJqygddrJFYPJ}yt@ZD_Ô^S]ÕÄËÈÙÝ××ßÄÃõüäøòüùçæâéîìíåüõýöÆÞÔÜÖMrzeg`fccnilcy~yyepLZYEÖÑTÚÙÊüóöÎÛÛÐÀÌòøõÁÞÂÈôòûçàçáááèèéìçþõÉöòæçùðØ\wwOCtygaijhibmikjilcfrvy~tDY^Úôóüøàãääáíî藑–—•”êïíïáþýùóûåüþÏSM@DBDCydcnihhlbljilaegegg`bgeyKZV@vpvIEÅðóÈ÷ÿðåçäæåæçæåäíîíàääúñúçúñ÷ûúüýýðÊÁ×Xqex}yff``oo`blob``af{dmgegaz\ÐENDQSQõñÄ_SQÜÍòáãæçãâæåàíïåöÿòÈÈËÉÔAERÝÔÝöôÑG@tg`d{zca|{|}pqz{v][MÇöÃQSTÙÓÉýóñÌýåøòûúôÜÐÞÌöðäáåðõôÒX\ÚÃ\@P^KBDXKKVQÝÞÂüóÝREuzcmcboocmonlnklafgOÖÑÔÅôóóûàããàíééîééíçþðñôñøûôÛÓ^qz{zfeyzestp}ptHMDÞõÄGLtdbnhonncsqv^PAA×Áöññáéáäìéíìꕕê땗””—ëáþõÍÛUTÑÓR@Cqxdg|egpYwKAt}|I[tz~u}gggnndywKHGÄóôñæìâàîîìéꐐ’’‘ëâúôÓINZHy~~{efxqps|yypGvrNÒBp}wwwq~xabbmbacaf}VVZEQÉýüçàãìêê•ê蕗‘“‘‘–—èçñÂÔv~yezfeprytACWÀÙ_XÅÚMzaf`bmlonkomoib``azvsrLÅÊÍÅÍÏÉñäæíéïëêëèèïìë”ëíäåàåÎÔDry{y{~x~}e{r~sBP\u~wOKr~dfzNYVÅÞßÚÄØÌÅÖÓÌñôÍÃñùøÿûýðñäãíîîííäåæüôûæùý÷õðñÑDt~z{dg{ptqt~{eda{df~fmcfil`c~v@PØÌòþýääøøüó÷À÷ûçáæçæáâàîëíîïàøñÊÁôÂÔ\DBEYÔStpxbohncg{e|{d{|{{}r}y|tAppVÑZTÜôøàéïïíæäýüûäâéïâìïããáæûñôÈÆWX^VX@MuCC]PEtyeaijhknbclnmhoa`nhldqMQÛÏöøæíïìíïãççääúçáàãâïê•ïè•íçÁÞÝÕU×ØWßÑPUW×Yv{fgfom`mmbfefaxfsA\s`gfaarAÚôñúäåäþÿûüüÿåäçââîéèèéëâ闔âøþÝZuOYÓÛÞÁÂÈÄ]DEqdmnkinjjjkkay`hhikhl`deHÝÍóÿþýöÏÊÃÄËøçæáìïèêèìꑖïøúñÄXMNuHM\ÜÛÅPP×]veddc`ezzqvzfsYÒlgoinextVÀôôõþøÿòþÿýðùäùäíèêé엗”ãÇÛZq~|qIqpwA[SPZÔTCpqIvygbo`afiiefcjiff{OTÂÿûþòðòõôÍöýõñûäáíâíãìéìèçÎÁPtysvswqMXNCYÓRtyxd`c`eyxuK|afttvy`nkho`dI^UÏóçáãïîæóýäçæàìâââîìí•èîáôÈÒX_BDOreywZ[DEJe`ggacoooiooca`gfljkhklzp\ÑñÿÿáãáäáãéïæãììîîëãíáàìÿùüôÀVÑÖHJJAQGKJECusq{``gzedxrvzysxged`nmddz~qwuYôýæîè•êè•ê•—–—”ëîéïïïéâæúþöÙË÷ÌÀÔQÓQVUÕQN|gfc`g`bhionbobbmmm`ffagsvEÙÏÌñæáàâìíê”êëíáàïàáàûûäàïîìããáþñòñöòöÈÉÅR]YNvxdgdge~dee~z{dfdye`gacdy}JLÔÎùáé”ëéë땔•””—éïíááâìàäåþóóòäáøööô÷õöýñÂDuv{zryecmoibceyef`loiobkicfsRÒÅôüäâèꔖ”ëèèìâààåñòçäþøääóÈÆÜÎöòûåóÉ÷ôÌÊÞQGeydyvOOrz`e}JCLJrxzdc`zppZÇöà锗•ééꕕ••îíáûÌÊÿñöÍÑÝÀôòüöÎÁÖWÖÚÛÙÑ[Cu|{{gbhnlclmbmb`d~wvy|rpJDÕÏõôÈðçà蕗—•ïãäþóóôÄÞÚÇÌóøåÿþÊ÷ýóÿüóôØ[NuNws}{}}xy{~dcjhl`de|~e{~qwNF_Þôûáìèéïâáã蔔•êïåðÇßÂÛßÚÐÏòûááàäôRJJYÔÖÓ_sgabbconmlnofcmojibfrt{af|qLG×÷òçíꕕ•âýÀÐÄóøúòôÌÅÒÛËðüåäçãâàåòÁS|ad}uK]QGrddgf``fbldxydcmhleywutMÝüæàìïꗐ’—ëáöRFTÐÉñòþûòýøæäùýôÌÍÿþÎRI{iko`g{yenhikoblnjkces_ÊüöûããàààãæçáûñÆPu|r^Ûøæ씗”èîáøÊÜS_A\ÜGw}z`iodrGLI]Cwr{dcmolmgwKxgfmlmetÕôñçïïéèîìæûóòûäàáþñÌÚÔUÛöçããìíää÷ßFy`njnfgbcloofzzrtrdggbhnon`CÕ[OOttsBÝÏýúáãáçøýÉÛØÓßÄùààçøÿçåöþáíïìàåõTEpglhihndq}y{xp~HGuquutrsu}edHYÏåáàäùûÿ÷ñåäþäçæàäääþøåæçåìèéìçäçüÏÀòõÉÏ×P[vzbom`nobc``f{adyxpsvuvvt_ÚÉäãïïãæøõÜPV[CÐÁöþäááúçãïé镕•éíæýÈÙTÐTÑßÞÝÖÓRqxeaabbgx}yeamcfdyvwN]ÖßÍÀ×ÐÃöùà锔éâàúÿùýðö÷öúäåàíìâìïïééîïäðôÐLvzab`cae{}vsygcllmombil`caeqLSß÷ñüþþÿýýòñõñýüðÃòðÉóùøçáæããíïééìããáçääúøÎÅÛÕZKAMw~qIE_NtJtr|yr|sz{eesqvBUÁòýáàáàççäùþðÏÌÈùúóô÷ýñóúàïïîêéïîíâåÿöÁÄßÞÝZvxzgagfafg~wegffa``cagd|qprp@PÓÀÀôó÷ùåóöõÁÓPÖS\ÐÊóýðöýþäãííïïïéìáäüõWG_^A]PÑßSGNvvJ}}N[DDuss|z{qvstIDÖßÂÉÎËôñ÷ÉËñýþüóýöËÚÐßÀÍÊó÷ñþåøùüùýÎôôõÛÔÖ]w{gfcomggd{ydohhllbafgfe~ezfagdyLßÇØÁôÅ\XGYÔ×ÊöÊÉ÷ðÈÃÅÇÄÇÊåäúùûþÀV\WÑQTÅÇÔVUPGqezpBLp|s}g`fx|y{r{e}p}eerttFËðÍÉÈ÷ÎÑÞÌÍÌÍÈÃÛÎÈöö÷òüýôòÿðöÀÇÜPNOOIJ|r|||zz{{abomamb`bonlfcdeyxggg{~ruHwqqDSSÐÖQYGEWÕÀôÿÿðþçááäæûÊÆÖÒÔÑÛÇÇÛØ×ÑÊ÷Ï×^]ÔR}eqFNsdxtLHpzgdzfadvPDuIÚóÎØÍÏôðÍÃÞÄÍÅÖAAVRÙÎùàáúüäçøþöÝÃÂ÷ÇÜÂÙÐXABupKL@_ted`bggagfdfaddgegdgxET×RZXSXvtX\DNX\PUÖÆÆõñ÷ôÿáâàææççòðùúúåäûýòòü÷ÙßÔXC]ÒÞÞÐ\F^HMJtCIvpHD[QGATRUÀôóööÃÜÃÃÐS]ÑÝÒ]QÍõóûúøøåäáíâæçüöòÉÍÞÒÀTP[ABvuIuuvqKAYtIMpr{eegyrKKuOMBOYQÓÅWÙÒY_SSÖP]ÞØÁÆÉññûäåæäçààãíîíàæäûûüðòËÞÜÝÛÛÀËõÁÂöñËÂßS^Otw@VZX\CGSÑÇÌ÷ôÉÉÃÀÁÔWPXDwqHZÅÉöüñóðóòýýñò÷óûñðþóÈÐ×ÞÕ]\\DXTS\ÔÓXHKJtqu}{fga``cfzyx~wJ\ÓÒÑ\ZCqIMKKNZ]^Ð÷óåàìì—‘–––——”•êïíàÿËÞWWßÇÌÏÏö÷õöÊÞÒSY^Ktssqyfcbblcfdyzvursr{stGÐÏÈ÷ñóüþûæáçøúúæàâïáúøþóöóóüøýüýÎÚÑ_FJ}{fx~{fcmoihm`ege~y}wJs~e{sJpKOtuXÑÖßËþæìîꕕ—‘———””ëéãùËÎÛÑÔÒÑÚÛÜÉõÌÁÌWXIKpxe`boklomga`ddgdeqZWÁöññõñùþò÷óòóÿûåúäæøÿñöòþøåæååûòóÉÆÆ]Lvy{zeefokjhmd{~|}|ys|yxyz{~s|~sOF]ÂûàæãïêëîêéíâáäÿÀÅÜYrqu|{pB[BC^P\XRYNwtqyf`fnczp|~yy}wOA_RVÒÇÎ÷÷ÌßÒØÎôñóòýÊÛßÛßØÓ×ÖØôòö÷ùýÀ]×ÚÚQ^UÛÕ^Bsrss{``gz{gzwuX]\VÐÁÂÜÔ\[YOwqs|ppx}wNGÖöýñþúúäúÿÃÛ×tedcnll`gd~vtIVÎ÷ðþúùñÃÖFsealnh`gbbfwNDE_RÈåãíæäøñööÈÓÑÜT^ÓÏÆÓÀÚUÝØÅ÷ÿþúüûÿüóÎÌÚÅÚÄõõÄÁÂÔS^]]BACsx}xr}wZA^UÀ÷ÎÒÞßTSXZCqtvwdg{fx}H[GVÂööóÿóÊËÁÅßRNNw|x|}qtvqqCÚ÷þæäùûûÿüôÞTDGJz~pHKuuqNÃòòÿåàâàãàåóõËÂßÛÞ×ÜÙÄÚÚÁÍðÿçíèêêëèìáàçüðñÍÅÝ_RBIBAE^DNGYZXFBuqMO@ZXXHt|}v}ggzy~xyrrvvw^ÕßñÿúæåùåýÊÈòõÜÖ]I}|zeqEÄñðäìîéëèîàúüôÍÐ\Ie{}}qwKFLVõðåæàâïïãìâãæúÿöÍÂÄ××ÒÒÕÚÀõýääææááâìãúðÍÙÔ^SBq~afyydddag{fgdfafe{~qwvBJtBIMOOQ[ÖÔ[ÝÜÙÛÐVTÙÉüäúÿþñýüòþóôÂÚ×SMvygdd{vBDÝÀüçûûäåäååðÓPMvsqvBÒÚÍôðçããî•êïìííìãçðÞTXDH[^E_BSÇÆÇõýýùÿý÷ßÓRupz`okjnmcfzg`fztBAW\OH\P[PPU]ON^P×ÂØÚÏÃñòöùåûúåççãæåäþòüðÍÛÐROw}zgxz`ce}JÔÀÎôÿøøàâíïáäýËØPOBKwqpvNE]TÚôüçãîéèëéèìçüÎRJe`ga`mllmoof{@WPÞÞÒÒ\ENxg`llolob`c`aagx|qtG\XÐÀÜÑÑÄÈÎËÏÝ×RDÕõñ÷ôÎÁÚÃÀÎüäÿÿýÿöÁÁÂõñ÷ÎÂÜÔRXÖÐYBIIE\RF[TÖÌ÷ñó÷öùùýø÷ØUTBwYPHDU\ÓØÙØÚÅÝßÁ÷ÊÈÛÒÔOv|abcoinnkhca{GÚÏðùñõôÁÕPV_pafcfzaggfd{MRÀÁÙöõòûÌôñÀÇÙÆÆP]ONIHBWPÕÝÂöóðôðòøàæäáùòðöýñÏÚßÁÅÖ\[t|{ez{zsMÜ÷÷ð÷çàùäàþÊßDHqeaconhncfade~DQODÐÐÀÈÄÖYupp}dedcmbmfeex|rR÷ýùûøååþðÊßW^RYNsre`{qswAS\YÑÂÄÞÄÀôóöÊÌÇÒÜÏÅÝÓÐÔÆÿåáææáçâéèèéãåååñÞQEMIHXXGÔ×ÔÛßPEOtvMGP]NvqOÔ@pzgdffaclhjmcbf|AÙõÿåçáåÿáæðõÜYZt|xgddfyLEVÒÇöåæãïîïãâïãúÊÑFpda`ac`gpODSQÚñûäãïéìáããæúö÷ýòÊÃÊÆÜßÖÖÉñðõñøÿüä薑êìîéíû÷]IDIzljhoohjcyqrstMEVYutuLJq}x|s}p{eqKuEÖ÷ÿúçäçàààãáø÷ÁÁ×@t||q}qASV_ÓÎñÿóýåæàæúýÀÛÔYXAXYI\RSÒÍðóøäàîëîééàäòõÅURMswLAFXÒÀñþåáââàâàæäÿ÷ÏÑ[xfgahkimac~MZTÆöÊÍÀÚÜ\ÕFuM~g{{xsLG[ÓÊñäæáìîìãîìæúòñÂßQsrqy{dg~H@MTÁÿÿåíìïéèîíààçòöÄR^CN^ALFP^[ÐÆýÿúääøçààáûòËÞQ[Kqrxdafdddy}JCB\ÑYNRTSNsqz{yfblfgae|sqquNANCRÕQÓýýÆÂÌÄÓÁÃUUQ\@KZÑÇÅÚÈðäøçáääååóÉÃÚØÝURYYÕ×TÜØÛËÌ÷äååááäûäåûûùðÊÃÜQXLutJO[ôòòòÿýðåàçþýÄ_CK|fmnjjnohildsLÃööüøøþÿóõÃÐEB|{gaa`ayrqJLRÐÚöõÂÉÃÆØÒÊòÎÇÆÐTGD_tqrv^MGÜÂôûáà藔èèéãæúÿÓT]KJF_OvwLuGÓÞÇñóýûúçáãâãæûÈÑVXLpy`mlme~|r{z{~psdlonhhomobdgywuvvvyqOI@TÐÝÌðóõþûóöÅßÑßÑLJvrsZWÖÙÛßÙÅÏÙT_uvJF\ÙÀÃõñó÷òùùøûüýÿýüøæææááäääþôØBr|qvwKNM^ÑÜÓÞËÀõðóñÈÜUÐZOuNJ{gcloookhhnm`dqRÓÃÈõôñù÷ÅÔMq{ggca`cg{qDWWTYRÔÝõðöÈõ÷÷ýøøúúôÉËÂÙ\BHpyggqPQÀ÷õüåæáàìâçåúûòøûý÷ÄÕQÕT^CIuuSÁÆòççáããáííãúôÍ\vygggg`bllmgx|rsdcfdxe~pwJU^OSP[[VÔuzds[ÆÅ_BISÊþåõÜ]PÝÖTuysDRRMeuTÖUSP\ÑÞÙÇÖUÚÂýçáìïììíààæäøõÍËõòûÿ÷ÎÍÙÔWRÖÙÒÀÛÂÀÄÌÈÍËôÅÌðôöñöÌÀôÇÀñÍÅÚÙQEteamijkibgKÃÈÈõõôôÚõüÝR\H[[uuu[\BL]TSÒÞÈóóó÷÷öÍÄöþö÷ôÜÓÕ@qrtK~xr|rAQØôõ÷üøæàíë”êëë蔔éæÿõÁWÕÞQ^UÐÙÍÉËÞÈÊÉ÷òçãáäøö÷ÚEYRBOvsq~eeamblhle}pCGpFSEÒÇWOIqx~xegfdgeKÑ×WÜÄÀÛÏôÏö÷ðûùÊÑWAvvqHGÑØ×ÐÒÚÚÜÔÅÏÌÈÊöýûúøü÷ÊÁÁóúþÿóðóóôÈÂÖ\\ÛÆÀ÷ýÿÿääçááúþûÿ÷ÊÉ÷ðÍÒQÔÔEB[Dtyeg{v|aboinom`fddxtCSÞÛÙÝVQÛõÈÛQ]D_PIM[[LvqrvL\×QSSRÒÅØÛÃÇTÔßËñ÷öÄÓ\tHJHNvtBÜÏ÷ñöÿúçàïêèéïìâæüÎÓQKvsrwvKZMG]UÞÂòçááááìîáäúþñôÊÄPJya``onnolmmmbg`bcdqKCvpuspJNJtwJFG]]NEQQV×ÁÛÅÁÂ÷ÍÞQ\GJAAIrsGE\YHtqwLOYÞÓRGTÉýðüÿûûüÿúáãáäÿüñÃÞWÕ×Y[TÙÁ÷ðñòõöõØÀÄTVED\\AEAHODÐÅÝÞÒQGtAJKt|~zd``ma`ad{vuG^QTÙWTßUW[Kwvedz}dfxpu_ÜÒÛÐÔÍÂÍðöÍÄÔßÄØQ×Y}rrw@LtHvLZUÐÖßØôñäæååçàçúääøôÇÆÖW^ÔÙÔÝßÖÖWQÒÖÜôóõðäããàæäþÊÊÌÖ]JszlhlagrNC^SÄôñö÷õôößÐWPÕAKvuMOLX_VVÇñôÆÓÓQGvrqqvquL@FA_ÓÔWWPØÊôóùöËÇÓÁÌÛÀÈôÿúüüûúåðóùÊÍÀÙßÛÁÅÆßÖÖÐÅÄÃöòÿùúýþååøòøüñÃUYX]FXJqvuwv~`fgfdg`ffccc`ged}qJVÎòðóñÈ÷òýòòýöñôÍÝÒÝVFCR]QÇÉõö÷÷ÈËÀÚÖÒZqr~vspvwuBÛðóöñøúäãí镕éãåððóõÐ\PGF@HOHZÖ×ÒÍöýåååçúðÿù÷ðöÈ÷ð÷Ç×R\u|yz`bmlmb`dx|rHF^ÝØÆÈôöÇ×PTVQCp{amfe|JKDÔÅÅÉôöýýúçæãæøôÂß_FAKutuKZWÔÀõüýòñõõõÊÛVÔWRÝÞÌ÷ÍÆÁ÷Êõ÷òþõÈ÷ýýðÏÃØ×ÛôÉÈÁTÝÝÚÄÒWWÝÑÞÒÔÑWQQ[qfbbbc`f{gdfzssO}BL\Ö×R]\_×Ì÷ØÜÐÝÀÏöÌ×ÁQuVÐVOvv{{yswNML]ÜÄÐÑÁÏÊðÌõöõÁôüÅTVuK]ÆÛÒÈñøúãéîâøÿûü÷ÅÒM~anmdgf~OßÏËñÿþäàãïìààáøÆ×[uItp{amhiogdgxrtuIvys}OUÝ×_RVU\ÙËÞÖ\A^ZUU\ZJtp[ÜÒÚÆØÁôÈöòÈÄ×DBOtqxabagg}uG]ÓÙÓÅÎóÿäããâéèîìãÿÁÝQEHZ^EB\^QÁöòòÊÈôÎÝS_Yvx{{{sCONYÝÆôóòÉÄÒÝ_ut|dcb`okhklikbd|JSÜÊ÷òäçäúýÄTWL|qOHt@FBRTÖÒÆÉÎÁÀõÊÞÐEI\GCSÒUWÇÃÁÉÉßÞÌßWYÖ×FDPÙØÆÌÊñþóöýýýüùùûøüõÈ÷õÛWÑ×R_ÑØÚ÷ýùþçàáààäóÍß^N}cjknadr]ÞÌôýóõôðóÊÅÅ×QWCCELyzyrqHRÖÍóòöôòñÊõÁÔ][urLBqpquMSÄóþùñÅÎý÷ÝP×ÑÔUßÊ÷ñÿäáààæáçðÀÙÌÇ]HrwKr{~LÕWTÜÐÛñðøàïîàåäûøÿüðÆØ_XÕYuJq~|ppxzdadglkjklf}uVÁôÿûâïïïíæåÿôÚÓROuf``adyK]Y]×ØÇôþþÿýôËÃÁÑGIrr|}~{wpvÓóúæâìïíâíçûùóôÀÄWÔÅÚÛØTSÐÛÇËÂÄÄTTÖÛÏÍÚÕPQÑÌÈÊÀÇÉÈôÎØPWPB@CtJs{dxrr}}wJO@[×ÞÎÎË÷Þ^Otp}z{yI]ÓÓÑÇ÷úáâíçûýÚÖSK|g``g{wICtHWÆôôðóöòóþüÿñÄÅÙ×S_]ÕÅÞÞÚÈùýþäûùÿðÎÆÀÛPAMJBX\TUÔßËÿùûúòóôÂÛZK~fcbmlcclincerqtVÂÁÃóüøäåúþÿóõÊÂÎÅ×Ñ_X]GYMpqp~xeed~}vCA[ÔÒÛÊüúæàåüÉÀÚYtprxddysquESÕÉþáãâïìææäðõÃW[\f`cd~}pqAÑÏ÷üààíãááòúñÉôÜÔGv~Jte`laz{xdcmmcagdafzqu}vJBVôÿóýûáàäòÄõòùõXX]ÝWspZ]u|rvIw}vuBCttJHsrNXY]ÝÚØÓÀñúçäøóõÎÆ÷üôÍÇÕQ]QXIBCuBTÛÅÞÂÌØÙÕ^PXNAYX[]_YE^S^ÓÉÎÌÀÀÛÓVQGJvyegafgeee~yyvZ]ÓÅÚÅÜÂð÷ÎÂÚV[AvJHv|e|J^TÝÞÙÉËÍôüýñýöÍö÷ÊÝWGvwtIHqOK|pqvMLMZQ×ÇöûäúçäøùþýÉËÈÎËÓßØRIpwursIONYXÐÍöÿýòòõ÷ÊÆÁÃVwuvsygfa`fac`x}p@_ÐÞÐÑØÇÀöòûøþúü÷ôËÀÝD[FMAMIKKMt~r|xxwZTÑÔÓÚÂóùùúúæçûååüËÌÂÃÀÏÛ×SXEZ_XVÔÖTÓÌÆÒÕÑÜÜÉõÍÀÀßÓÝWDOJHA^ÕÝÎôÏÇÛÆÚÄÊ÷öÊÊÁQ\[_ENusr~{~ef``z~rw@ÖÛÀÎòþÿÿüúäæäý÷ÁßTÕ××QGMAF@MuwsrstM\ÞÞÜVEF[W×Õ_S××ÓÔ×ÞÜÙÀ÷ÿûåäääøûøùûúÿöõÎÌÙ×PDMtqtrruvssvH^×ÚËÌËôöõÃÛÑRLOYRSTR@w|}pqJur|~|r}swNMFTÆÌöüòôÀÅÁÍÍÍÚØÜßÐ^WWSFNY××W×]FKNQØÃô÷÷ôôñõÁÐWZwtBED\]ZNK@AGÕÙÛÆÏ÷ñðòýÿòòúæáææþÎÒÕ\ZYEMtpKZ_QQR^DVßÓÝÙÑXOA_\PWQPYGNqyf`blmage|IMFÒËýäãâàçäúÿýõÆÖ_BL[]^\O~sqvuLMAEPTÑßßÓÒÚÄÍÌÀÍÆÖ×ÞÆÇÅÇÁÏÁÆÁßÙßV]Y[VÝÄÎÊÙÕÒÞÚÂÉÃÙW_D@EAHIFYÝÈñóý÷Ïõð÷ÎÂÌÄÑ×ÔQ^EOr|xzzzx~{a`fgzrIX_\XWßÃÉÂÇÚÀôöòùÿôÀõñöôÎÂÑSXGKtqx|ptFYPÔÔU\WÐ×ÖÞô÷õõÈÇßßUQ]\WWÜÀÂÌÒÖÄËñýåúøóôôÌÂÐGt}|pI@FNND\ÔVWÐÖWYXGX^ZVÙÍÌÎõÊÃÒQ^@Js{edgz~pLFYWÑÛÈüûûðÌÃØÒßÁÁÄÞÖÔWQSZKvq}}qJF__ÒÍÏÀÎÂÆÙØÆß×ÑÑÕVÓßÝÜÅÆÅÛÛÛÞÜßÜÞÒÕTQ_[ÔÜWÖÚØØÄÇÅÖ_XZFVÖÒÃÇÇÏ÷ÉÂÀ×]D@GMZSYGX]X[\_^FBJq}{x{z~|r}qO[\RßÞÅÉÂÎÍÆÍÀÁÌ÷÷÷ñöóÿþÿòÉÒ]YQ]BCKuuJEFF\[YÔÒÚÀËõËÍÉÈÐ^GBFAMCGFDDGZY]PPÐÅÎ÷ðóöôÉÁØÐÖÑ×ÛÛÐÜ××ØÞÝßÙÑÝÖ×ÐÑÝÓÒÕÖÝÕRIqq|xegfe~~xsHwH_T×ÜÃÎËöôÊÈôõÈõöüýüòñöð÷ÙÐVAAGLIwHALuL@F@LMZRÐÛÛÄÆÃÁÞÝÝÐÕÕßÜßÞÚÁÃÃÌÍÂÀÞÓÓTQ[@ZEGDIuDPÖÚ÷òüþúäúýöÅFrzd{xy~sIF_Ö×ÜÃÂÁÍÌÚÖ]IvssvuNAPÔÝØÞßÆÎÏÉÎÄÆßÕTÕVÕÑ×ÓÙQ_BKLMGA\RSÔÞØ×QQLLA[_ÑÁÈôôôÊÂööõñüøýõÆØÖÓÔ[^\[WVÝÆÀËð÷ÁÚÜPXMuvqtprwCARÕP_EF_QÖØÂõóôôñÉÌÌÅÝÒWYOH@LJABN[WÔÓØÌËÊ÷÷ÛSAv~zegg{|stRßØÂÈÆÆÊÍÚÅØÒTÔWVRTÖÒÇÏÎñÿýóóÿþüò÷ÅÖR@O@FD[]PWY_RZE^AXW×TW×ÕFM_FBXSÐÍóúúååøóýöÌÏÁÐSMqrwuLDY\VTTV]V×\[[@trxze{yrvIA_ÞÛ×Ö×ÔÝØÃËðþýñððÎÝÖVDLMBHJLOZ×ÝÚÂÏÈÍÀÎÀÂÍÄÛÛÓÔTQ^FLES]UØÞÝÓT@JtsprtKEØÅÆÈÈÏÂÉôôóþþùúåääåÿ÷ÁÚÝWDButtqOCFGuwrzdddaffge~s|~qtCÔôþåççåùùóÀÝSAA[^]ÑÝÇÌôñöö÷Ãß×ÜÐT×TVPRRGIussrswtvqtwtKHBYÕÛÇËòòôôöÈÚÃ÷óüåäåáãáæçûòÉÛÐV\YDF^Y^Q_CupvuqtIwJIHKOwprz~puVUUÐQ]P\EXQÑÛÆÈÉÂôÊÚßÚ×V]AA@RßÅôòüýõÃ×Dwyg`aag}qvvuJJB\ÓÍòøøúåÿ÷ÏÙT×ÝÇÂÌõÎôýýþþüËÇßQRP\AORÑÝÅßW[AANBSÝØÀÊðöÏÛ^t~z}v@YGPQRX^VQ××ÖÐÖÞUX]RX]^@OuwvwB_×ÅÎÃÄÅßÐÐP[GLIJMZ\@v}gdee}J[ÑÇÈòñÍÂÈôõõôÉÉÎÀÎñûúúûÿðõ÷ÊõôËÎÃÆÓDNws|rwvuF_TÒÙÒVFLI@\WÑÙÁÅÓßÑÔßÙÃÀÏÊÃÌôòýþåùñÛ_O|gc`{}suBOKI@A@DABIJJq}gbomfzsuXÙÎ÷òúåúäååúÿÿöÈñþúáâáäóÏßVYGF\ÐÕ×ÑRZMsswwqrvBG@\U]_XEVÒÆôñýýõÎõôÊËÂÁÁßRR×ÙÆÂñòöÍÓ]Mp~ruOLZXZ]RR^G@OJCDGYAtqrydz{x~sHO@Q×Þ÷óòÿÿÿþùåæáááúÿô×DMttMX×ÓÝØßßÁÃÚÙÞSAMODGLOuLLNC[X^ÝÇØÄÈôÈÃõÂÒUPEE]ÑÍôñòðóñÉÀÙWÑÂÆÙÙÝÕQ[QT]@wr}yy}r||rqr|~eeyyqXTÐÙÀö÷ôÊô÷ðüäãíàæåü÷Ý^CtwuKCFAFED_ÑÚÅÐWT]]\D@@OHLOMNNC\ÖÄôòåúÿøûó÷ÚÑÝVÑÛØÄØÑÕÕZAZD_VÖØÆÄÏÁÝÚÞXIqs}}vvqHJNLJNDBHFSÔßÚÃÅÅÍÆØØÞÛÎòùùøúøþýÉÞ×]t|vJtILABLZ^FNHHLYX[YDEHtHNLCO[×ÄÊýþüùüòþ÷ÊÊÉÍÍÛÄÂÚÚÛÐÔ_FAuu@YRÞØßÁÃÆÕ@CJwqtvptILMLAHIZE_ÝôóóñóñÊËßRWÖÒÙÃÉÈÈõñõÍÁÝÖ\D^RWS]AOGYXAOuJMD@OFCHtN_^FOKKBRÑÛÀÄÄÆõõÄÜÚÍÅÓÇÈ÷ñÈÄÅÞTDMCLNX×ÅÍÃÍÉÀÕSUTÔ_GCwv}|rss|qtwMQßÓÚôõñý÷ÌÀÏõñðüýòùûÿòòñÍÙÐTÐÐÞV[EKt}yegzypr}r}qvtGQÑTPPÑÇÌÊÏËÍÏôÁÓÖ×ÐÜÞßÞÅÃõÃÇÁßÖ_GCOL@^EZWÐÔCuJOD_AJBMKBEGLwqwqKZWÛÂÁÉýåù÷Êðñðÿûùøÿýþý÷ËÃØÐQÕÜÚÞÕ_SÕ\MJvp}stpp}rpuIC_\^]ÛÍÏööÊ÷õÍÓR_Q]TÕY_ÐÜÐÐÞØÖÕÔQ]WP^]YEVÑÒEN@DCABJNOtJKMwy~|y}OZUÝÒÄõõËÄÁðòðûççççåøòðÉØßÑRVÞÜURQ×V_\ZG[ANF^EE\PXMC@LH@\ÔÙÅÆÊõÍÄßÖWT×ÒÓÕ×ÒÆÂÇßÞØÐV\U×S_X[]P]\Cv}xeedeqtJNLBOuttu[WÖÀÌÌõõÈÈÀÅÈÉÉÈÊñþüýýðñôÌÃÐUÖÖQVSPÜÒÔ]EG@tKE_ÖÆÅØÞÖQZAEOFVÝÅÆÃÃÎÃÄÄÆõÊÍÏÌÂÆÃØT_TÖTÔRFCGA@F^QÖÑÕS[Bp{}rtMHr}|edegd|L[ÔÁÏËõÈÉÉðýòðñòýüüñÊÊö÷õõÂßÓÙÝÑßÇÄÝPFKqr}|K]ÖÚØÝÖÑQZ@OMGWÄØÚÇÚÇØÚÃÊñóðöüùþþóÊÎ÷ôÀÝTL}yr~|sqq|}|spsqEÑÐÖW\MIts}x|uGVÓÜÀÚÖÛÂ÷ðõÏÏÃÎÎÍÌôËõôÀÀßTÒÒÖÅÊôÉß_AqrqK@SÓÜÓ]RP_SAtK[TßÏö÷ÌÇÅÓÑØÇÁÌõõôýüñËÊðòüýõÞTV_YQÕYOtq~e}swD_FOuvrs{efd~}t@SUSQ×ÖÛ÷ôðþüúçççúøþ÷ÌÆÖDS]C[UØÐX_DvwuvCÕÒØÝÙÙÕÑÅÖ^ZADVÑØÃÂôÍÛÆÅßÅÜÓÃôðüòóðÍÀÏÆÆÞVRS^XÕÑVNqq|rqvN@PÔÑ×ÑS@ALKwqs{zyyrOCKOJCX^ÑÚÍóüùåääúýôõÍÙÅ××ÒP×ÓTVDwNLqwZÖÚÄÄÏÎÂÉÚÒ×AIAF\WÕÜÒTÑ×TÑT]TÛõòÿúúÿýöÈÊÊÃÆÅÞÞÛØÖENt}|rrwBLAXALMvssqrx{}tHYUÐÚØÜÛßÚÀÏñùóÿûüòöõËÁÙÑÔRPRFAJOFIKvqqwFVÝ×ÚÂÁÏÉôÊÀÑCF^UßÄÃÜÖßÜ×]WRSØËòüååòöõööñÈTWTP^FLv}||x}vJBFE^\V_BBMNHqx~puJKZSÕÕU×ÞÄÃðóòþûøþðôö÷õÎÒQÖØÐY@X_Z\ZOBHuCASTWÓÞÖÞõôÄTY_]ÐÚU_ÕS_S^YYZ]Ö×ÊÿüýððóññòöÙÒßÞÞY[[OHv}qyrpM@F^ALCOws}{x}ppeqE@XÕÄÁÎ÷ýøüååûûýóüùóÍÌÏÂÚÜÖGXVRTRZAOvpwu[]X]\ÓÍÀÝÔÖÔÑÑÙßTÑÙßÅÍØÝÅÓ×ÛÉõÈÂôõÌööÉÎÍÀÛU^Ytpwxyws|ssJIDWR@^EIDNvq}ps{x|~rHFÕÁÅÀÊËóòþþóÊôõÊòöÎö÷öõÃÀÞVWT^UÓR_^EY^ÑÓ\[SQÖÆÉÆÇÆÎÐSÓT\D[P^P]^[^ÑÛÊöññöüÿòòðñõõÅÑÒVZIvwqs}sssvvHq|xxzy|~rqy~sstOSÜØ÷öôðùåøúúüñ÷ñôÊÊÎÁÁÃØÔPT[LE\S]\GLFGBA_XYÑÆÎñðüýñõÇÜ×ÔWTÑTÔÕS_SÙÚÛÁõÏÇÈÇÆÌÆÃÒÙØTDY\utvvMuKOLXAwwJssstJvButw~xqwDRTÄÙÏóýÿÿòñõÁÁÄØÂÌÍöô÷ñÂÙÞÓQRZ\×SRP_YBJHI@QÐÙÊ÷õ÷õÎÇQX_QQR]]]Y]ÝÂö÷Êñýóýñöö÷õ÷ýöÈØWQZKsrvs}pJuq}y{{ezx{yzyw}yrwL_ÝÜÍôôÿäççûÿðõÀÉÉÁÉÈ÷ðòóôÞÓTZZ\FWÔ[XCuNJptESÙÀÉý÷ñðÌÀÚTWÝÑÖÙWÑÐ_ÑÅÌõÃÄÎÉËÊÌÍöÈôðÉÀÞR\GuvtvqwqtHNur|qqpvwpvtps}|r~y|qI^P\ÝÊðþååðÈÌÀÂËðñýøùùÿòðÁ^DS[E\_REAZBHuwAPÖÁËÎðóÏÂÁÜÓÔ_[[QTGZWÒÛÁôÍÀÇõ÷ÈðððòýüñóöÏÒYEF_Gwp}rpr|{zde~~ye~zzepv|}}vOWSRÄÌüúäçøþýõÊñòòùòðòôñõÐ[tvtwwwtwuwJBK[UÝÏ÷ýûäûøýô÷ÌØÝVQT[[PSÜÍÆÁÆÓÝÚÇÀÚÚÀÛÒÜÜÛßPR\@^T_DFD_VXZAIJJOKvwv~{xzrq|{espvI\×Å÷öñóöÃÏõÏõýüüóóýð÷Ã×YGNIHNGZGFBZ]UÞõ÷ôòþùóððÍÞÛÐGOH}rvuXÒÀÏÁËÊÏõòð÷öñüñËôÂÝÛÝPTÖWÖYMLMBw}rsp~zdefgxy|tsy}stKFTÍüåûøúþöðö÷ðýÿýö÷ËÁØÓ^MCLwrswKNIwu@XÕÆÉððüøýüùýðÌÙ×[tqspLEÜËÎôÎÇÎËÈõÊÁÏÇÝÞÒÑÖY_TRVÓÔS_EQTSVGOGLKJHsxd{~rqxzg`dy}w[ÐÏôñòòóðôôöðýýñ÷ÌÏöÆ×ÜÔW×XGLLAKtMG[ÔÅÍ÷õóòôôÊÏ÷õVGLJt}rwM\ÖÅÀ÷õ÷óöýÿýÿýÎÂÅÜÅÜVÕÓÜÚÝÑÔ]ZOIOHvHHps~|ddexy|zdfddepO\ßÀõ÷öòüýÿùýøûùüöýôÀÂÜTTÖ]AIB^LB[CCYSÓÚÌÈÈôñöôòöÂÅ^_PDF@_VÔ×ÇÏÍ÷ËÈð÷õ÷ÁÞÑDÕÐX]Ö]ÑØWÓVTÓZ[ÓÔ\ÕYE_uJpzxd~zgedfgfazzJw\ßÞ÷ññûäúåùñò÷õ÷ËÌÈÀÅÃÙßÜSÐÕ_ÙÞÒÚÜÖÞÁÀÀÆÁÎÅÄÄÔTEODBNDXYP^SØÃôðÿùúûþòôÎÇÛÓR\VQÕÕ×ÓÖÐW_\ZMLBJKqpp~ezxz{gfdgz{e|spqqwX]ÔõóóúúäåòóñõðöÌÊËÇÆßÕÑ]WTGGÑÐÔØÒÆÊÅÏÌÌ÷ÈôñôÀÚÛØÞPDVVVXuZVQÖÚËýòËÎÄÜÔES×VF]ÛÞÒWÐØØÃßÜÈÆÓT×ÜÖ]AIpyxdgfacladfgdey{ezpHGTÈüåäåùþüôõ÷÷òñõóòÊÏÛÜÆÅÒTØÆÒÓÂöõÊÊÚÎÂÖÕUÖWG[Ô×^EZ@BMOK[ØÞÍùäåøÿö÷ÈÞÚÆÀØÑßÇÇÐQQVWUÐÔWQFA\YYDJxygggacmagd~y|~|ptNYÜØÌðýþþÿðÊÏÎÌÃÎËÚÚÅÙÇQWÐÕÓPÒßÚÂÌñýùþðüËÞÂÇÞÚÞÓÄÍÐÚUHD@Jw@QÓÇÆôÊõôØÒRYÑØÚÇÎÂöÀRßVQÕÕWÅÎÝÅÆUÅÆÐRO}dxzaa`ccaccffdaazvMEÔßÏýüÿþþÌÏ÷õ÷Îöôó÷ßÃÅÞÉÓWÝÌÅÄ÷ÚÌûÿññõÒÕQ^CJZ@\WPÃÕPÖuJIÜ[×÷ÞðûóþÎÂÛVVÖÏÐÇñÎÇÑÖZCXJGTÐV×ÕPÞÐWWtOrrggdoafbf`fdedftqOÕTÙôþóðüÉËö÷ÃÂÃÃÈÅÒÔEÑ^@ÔÓÏÀÌÂØÊðøùúþ÷ü÷ÌÞP]_Ó\WÅßÂUO^S^[ÑÒÙöõóñÏÉÀÑRWØÚÛËôÅÞÛW\E[C^ÅÑQRÏÀRÆßWPZpysfmbb`cmmlbllbfy|t]õñõóõñôÃÍÿþÎ÷ûÿñôõÝ_ÐÑ]ÆóËÄõöÈÊûýÊúüÎÎþTJÖJ}R_FÒÜJWÔRÁGÚýËýûÊððÐÈôVÇñÞÆÎËÍ\\ÑJuÒMMÚÔAZÄÞ_^Û]vÐHgyxnh~figdmffm~J{YÈ_ËûÝÌóÖÚöÌòþØ÷ùÆÍÄÖÖA_ØWÆåÀÝñÉÍöçûÏðáñØåÃtWÓrvÆSwZE~q_[ÆÉ]ÉúÓÈûRÖóSVðÛñû×ÍòYSÞ\_CUòßWþ_LðÚDXÁÚuwMdbdmibabn`gmyfrD]ÖÅðÀTÂÃEÁ÷ÌðøçóñåÆUüQqÂÍÇËóýÜÖûËZåäÔñãÃ[ÍÌvvÜGtÚÀ}sÔD~ÖýÖQçø[óä\EùÏuÎæÁÏåÆMÃÞqJßNCÌÝ^ÓÚS[×WwPÍCvYrleiipyguihNulAöX[åÌqßùItçþ_ûîÏÎàÇLÈõsÕåÃßäÿÛúæÅôãðÉççÍôðGCÆ×}Tôp~QueVÒvUäÝ^ÿÀuYÊIYþÉÖäàÅÍýÖLÇÖwØð]DöÚOÛõN@ÍAvÂÅfwScnt~kdv|m}\`rüÓMòösRäSMãæUçèÖQáÃyÉÿuÖïõ_ãàÔçîÒÎîðÕçäAÞøCsôØ{Þþ{dò]gÍåHWîô|ùüfMåD}àùHåàtVàQdðÁzÂþ~wþLaüßlQöaqóz`ÍJHd]ZbAQkIæ}sàÜfðåzÑîÅYéù{ðãyKáBzàûsùëVʔóRëã[àèDÏî@qäPfóômJðe|åXzäåvÎæ}vüMgôóvÊãW[àôIþö{ÑæLqç×dð÷`Dóz~òBaõÅb}]nmGfef`wjoÞLaÃÊeÐåOuçñFàãBóâ^FæÖdðóqÌæSÍéþWáæSûìÔÍîõDäô{ËüHñqgÊÚgWùMFçÞ~ôÃeYöLRàþYòæÕÞáÛLÿýOÁäMFþ_xPRgvÃJËÐy__bd_bhsdashiv~fPÓXôX[öÊ_úäSÅäÓLñÀ}ÅÿtFçÆHçâQÊíÀÑãúÓåìÀÂáÄKóðpDõt~ÆP{Ñôu_þW|ÁÚYóB[àñXùç\ÚäÔ]åòLÎäOKò]gMXavÁw}ÍÑZÒdzSfk|~`pk}zcAÞzuò\tþùZðáW×ÿÅtÞÞxDþ\wþùHñàSÛíÿPçìÁõîþ\øåDÒçR}ÃË|IÆJsÊÅyßûrsþTzÌúuÑæÄBåårßçTÖâöuüäw[ðvgÜVgFðqpþQ`_ÆdfXddHkxc{XleÈ_eÍÿAÏîÂFäø|Òþ}zòÃqôåDÐìÿJóíÚÍîø_áïUÆìÇ@åú[üt~÷Ö`_û}püTsõ÷[ÿTLþúAÁãTwóÍqòâßÝáÿLÅûsxòQb[ñg{óXmEËebÑsxQMcdDn`öPgÂäw@îðtúàZYúScÛùJáÆxäãMÇéö[íì[ö•ôCâá@õèÖ~øñeXúwcÌ÷`uäÔñÿzOàÑ{þáv@ãØdÎúÖìÇIãíIQâYzÏÅcsÿqaÊËguütlFJmFodkFzi\ÈduúÚvûáFÅïÅróÊavþ\}ùçEÀéõ×ììWÊïößãæÝÈíóÔçþKVóu~ØGfXÏqBåõuÈÿ}uùÕróûZØçØrÇÃvXÿÄ^ååRÂøÕsÓB`wÓryÁ_dUÌ|Óei||djzvbpÁKÎÈtØæÁLýçGÖÿIa×ÜgFùUHäæÐûèößîáÄã•ðÉãòÆìíÔÀç×sÚPbrW}qòñ@õývtóÐ}ÍüKSæöBöõ}EÿÔAäåVöæÖSÿÜg@ÊssõQ{[Ùy[Îsctaa`isQd}ÆCÚ÷_ÅçÐBøÿ}NôqzÉÆ}ÐàÛÒãáÛúî÷ôéæÄäà×ÐãýUþöpDÌ}lwpbI÷AEæÿtÛþ^AòÚwÇýYÑäÖwÉôtÖøÝQåýCÇûUM÷WeÔÁ{yÝJfYÑe}WzkdfohJHfFöCuü÷KÙþFXúÞ|ÝÉ}JõTsÄõYõâÂÞíäÌí•ûä•þQøçÇÉáÆAþÁzGÖgbPW{Yö_RýÌwôäCwÏQ|ôõyZø^eöòtÃæÁWåñuõúJLüÀr×Åf~Êvm\DogKhglapbÐ|gõÎtÞåÕuóÍKÁÂ}GûßpÁüAÖãñVàà×øêùñ•ìÌçà@ßíÇrüóLÑ÷w~ÑJeUÂvEäô^úà×ÅàÕ}øýwÓçUuçòÚá@XíÌxñö|_óGr÷Ôd\Ra{Íxo^BiyJkud`FobÙPpóûYÇçVuóÖPÐztñMgÆÀOÜçUEåñ_áéýú–ãVãâ\ÚæßOúÿXÉùKtõMdPÒeQûÔTçùNØòtLòÐqööNÝäÖvóñEÁýXDóÇsßóMPÈAwßCdDEcfBxh~~bsj}irÍBuóÌN÷åXÒçßqÈËuÝÍJ^åÂ[ûúNÜçÃVããÙçéÇÝâÿw×òOYüÙIôÂ}]ÌF~ÒÔMýòÜóæSDûÇ[ùå_ÛâËBþüw]þÔ}ÄÒ{NVr~ÝRdEÒzpÝud]taJDabLxo}{hdEfg÷ÜÒótGûÌNöðsBÈJe_DTÊDÕðÛ@÷üÐóãöðéáôïìÜÊàÍPûÿ^ÚçÔBùÚ|SÍtBöÔIßØvQùÇFåáÕËáÀRçõJôúFN÷_zVÝdvÄ{gÌS{GÙvqÕ|gvqn`wch~zkgGefÇBbQðtZá÷XæíGÐáBzôÌsÆäFVüÙGýó@ÍåÞÄâçÚÿäÞÍáÍKñóJÕúØSóÝ{ÚúuNÿÐ|ÅÉMôçÚÀïáÀääTTûÍuÊñrÅbEtl{FfeßCfÞ÷xCð@eSIbwDaaFeoOPgØrgÝØsÄáÄÑæùXÇÄzJõu|ñô{QûYAäÀyôâÜÃéåõìæÃæãÕÓæõEóûG\ñIrõPa^Üg|ÇMsóåYö•óÔàúKõâÑQû×}TØdsÖfmDIcMØeDöIw÷Q`KYafFapqdDcgPzaõÔ{ÂãÈÀèçÖúðqÖåMNùÖÌñvQû[}õÉwÍàÙÃîóËìåN÷æCÖáÁqöõyÙûusòÑeÄðtÖàÃÅêíÈåãSÝàÉKóÍzuÄgcÔ{~vjgÔedÏÝsÂÿrNðJeÚXorRofWzgVC`@ÃrFó_QâùCÿåzEü}z÷ÔbSü|[ûP|ÉÌqôâÝñ”æü•èÊäíÂöíÉ_ûÈd\ý||ôsmÛÞfMøAEàðÄìäZýæAÎíWBæÖgÎÃbrÖnlß|nÝÖfWñ{pñrcÚOiOYbFhk]xjRßc\øuMâü_ïï\óìNqúÐ~ÈÁzQÎ|HõqeÆQÎÿ[÷éÎÁìûTçþÓàæWûúvÒæLwçÐzòðeÙäEÞï÷Îèÿ]û÷pÌýIÐós{ÖqourjevkyÌzzüQ{ðÅÊðz_òdzÛfmUqi]Ól^ÉcMûwZïÊRâÚýVlÓÄ`\ÿdBäwrüZ}åôHâàSáèÚúèWÆé×GìÈtøÅg÷öfÛñaDüeqàApìý\îâAþáyÖâFÒïZ}ùwoÙv]Xk^ÈcDþdrþ~f÷JiÔ[sÔcÞlmËmûRmå÷dæ•Zä—OVí}yäZ~û\aùßmôÀoÔÿgÄéHЕÆRëópíü`äàpüìsWê\Oêô|äÚ{äåyäëNÿ•_ÍèrqàApâ_añ[[@wN~ÚnzåydäpmåFhôÞk[õjvóbròdzÿ|cüM`úõxáâ}ñäaNðasäz`úHaàÞfûø{öïCù•Ðý–ñÇëËpãÀxãÿdüød÷çeÇàduçzdâP{éüqíàröàeÀïpQíKyùtmËHkÙAjAØcJÆ{qÑbaQgf_~l^IoJÚztÎpwñXqðÎZäçÞáätôüePñsBôptötw÷t}ËÅvÊü^õæÚÙúßR÷×Y÷ËÐñÊÝùùÎýüÛÉôÇÃÎÄØøòÊøüÛÍÑu[Åw[ÅuDÃ@Gsfuvxvr|NStuÖItArvMtw@u|X@AÓ\BÐÐL^ÝNPÅÕÛüñÑÉÑ}[CsD_u@ÞÑWÝ\ÜöÌÄôñÃÊý÷÷ðÀÏñÊÍÉÃÏÌÝÑÒÅÃÄÙÀÂÚÏÏ×ÞÅÙÂôõÌðþÄÐÇÅßÍÅSÚÆVÖ×LJGX@At}sseagg{~{|vrsr{}sEXB]ÚÍÙÙõÌ÷òöôóþÈßÛÑEEWCLQS[P_NB[]×Ý×ÒØØÕVVZRÙÎôòüüýöÊýóûðõÎÉðÏòüðóýùÿÿðÂÎÄY]WZ_ECJZPMwOprOMFMtvqyezg|wtKGUÕEOHIIuYÐS^WÞÕÜÔRÞÌÇÓÇÏÖ^BtHFIOGGE\QÔÓÕÛÁ÷ôñÌÏöÅQÐÔ]ÖÎôöùåòòõÞÒÛÛÅÅÒWÙÙPÎÛÛõýýðÿÁËÆWÛØôôÖÃQ×ßCÙWLÔWVR_Cx~flkicazxx^IsL}ysB^Ù]ÒÂÍñØñÿ÷äÍõôÓÂDZVZ]VW_LXZ]EG_ÜÆTWÛDMYw}pJ[ßË÷þþúáõóþòçñùöôùÆôþË÷òøÿñËÝÛÑMA_ÆR×Óx\ÑJrG_NR×IZDqxfgabex|LIYCJtGwuT××ßôËRÁÃÔÓÊÄÝÀÍFACrvrCGI[A@[]Ó^ÐÄýôÁÌÁßQYVNFQ^TÈðôöøôÍõððóüñô÷õØÇÓÚÁÍØôýÇØÇT\ÚõÅÈðÚ]ÚÃRVÅÆÝÇÜ\Lu}fmooli`ade{{ad~xXßÐÎùðÏýÿñýøþþøòÎÛUDCDDB^GEAGFuX^]ÁÓD×[wv@q~wFuÙËÁôÿüøæäáéáãíáäçûñ÷ÁÉñõÀÇÛWRCZQXTÐPEZYsv[AI×ÚÔX×BywsfeeeyrqHsgreytBÕÂõ÷ðóüóÁÍôÎÃÅTQS[Nvsru@|CFYYÑÙÑÎûñÒÃÖ_Ñ]EIvTÈÔQÆÃÍÁÆÕÌþýùøûæüÿóôÙVÃÝÝÆÓÔÝÅÑVÎñÇÞÎÚÊÑ@ÐQÕÊÝÑÎßYHtx``lnbmgf`bb`hm`l}_ÜóûääíâååæøúòÙÆËÁÙXpJtvstpepIJ_PÓÆÑVKFBMHgeBL^QÓÍ÷öÈþåäçâáíèáãíúÍóðÐÚVX__ÔYF_ÖTGZÜGvEqpXRTÛÌÄÛÖ_YZea|ddvr`z|bcgez~MSÚòæäÿøäðôøöGVÝ^M@F~y{qsBÑBNÔÉÆ÷ûöÛõÈÑ\KwtpZBBÞÁÛßÆ÷öåäááçàääçûðöÎÃG@WZ]ÓX×ÀÄÔÝÄÔ×TE\_OÒÂÁÈÿÂÖÍt`agbiddcxcb`h`ibr}WÒøáçîìïàäÿËÈõÞßÝSÔLOIx}vzqJHJWÏÛôðÞÂÐqw}|xJsqÙ^Ùôõðõàåù”äê”þ–äæ•E”gÇÁb÷cõf_KÑGØC_FxÀaÆeó[ÀøÞäÑÍE|Jde{d}d}}}ezf`~drMWÅÈåüóâÌýötþwÐÍeønÁvz×cÆgÛtÇQýÌáòþáØú}÷`IqdAdDKFØYØÎ÷åòáäæçìáàâøåÊÅ^@TtJ×sÏÒZçröQCúoærØôTæ[ä×÷|Xcth|zmejÓsmiehp`|ßsòüóãáíæáÿüõÈÁÛUE[@OxszNxvYqÞ^Îü\ÍåeÉÒiÿl`õðféjîÕ̑CðéîäüèáìåúÔýHPw}HaÙ|õJ_KZ[LXLØGÉØÛßñðÖÖFNC`u@Piö[úpÉëcÿæg“tëÕÅàzðqÅvRÜÄdÆd×OzÿdæAàÍåóÁçGûyRE`Çj}}lÈeLØwþÃÙìÝæï֖öù”Èìç^ãÙ~ïoöËc‘`Êøl•c]ä—xØãj•bôÂjìFrñq|ðÍmgÌüaÎÄSçØãÿâøäáÓçZõÁNÎÒÒ]sHOgRpwÄqô×tõXHólÀ]á^DàhUøo‘@å—ržßì‘qžNê—ež`áÊ”üHméáz|öjþfÒÑ_óKñßø\òÔÖÉfÍoHnÁK~hôÑujàù_f—f”ÛÙë|ápÎTMöEýFôtÂsqÙeópôôqç}åÏ{ãlÈqjáÖ~æçuCâpêÑäåûãÂíøèðîþöätäsÆÞBâ{øÄxàhòXlîjã]a•kétHákúcJ{krhfaa{M{YeöIVýTêÁàãQíXÑægûô~ëgË÷nö`sWfKÈvvóÜÒyÎNdÌyyõoÆVmìÅâ}”ðđA”îNžÒï•A–FÔùFSËMDúzÒÅn×oôbæoý÷f—ҔhãÃ`”ÐÏâ~ÇàtÀìiYýo—|æá~—iàÇm–ìÇg–møÅaúdqÿzôËfîdÜújïo[óéiLÃâßÚm”hâüxœb”íPžL”ëV•ÅÏìOææx”{Áøèjx÷ëiNàèiWæ—jóþ–õdòÈjgÁænÉÆx”eêÿߒf‘YÂîn‘fåöxîþwpöúcuóhìjÂÔkáçqtäeâeÀÖwôfþDýôLëJâáT’ÑèëZ–TùäDæÕÎSÏ^wÓÚgoÂÀ~bíbôúfì^YïRÎâSÐòmSEÕoØrQÜB{áqÇíu÷ädçÈ{ëw_ìcøÛ`çzuàzÐðyæôaíCâmRçbûønâtjèxæäÊh–`\“lèïwŸôÜYþ–sêì`–×e•\äázëÅø”tb–kóç“t~—øCá|GùjZ]fádãÊɔv–ÜF–mîÉdmÛçï`lïËXi”kôöiïiÇÔoçbù_uîlåqrãàAZéoìðIè]åîÕïçÒãÍôøßñÓÀKZÒn^bgBÇ`pÉiìYuêHäçMêËÕàB×Qz}deirgPkJLhædÍü}—}×ãdúÐqæYEÿÔC÷BtÍsY÷PUýþCþôqüCdðXböX`õtdÊzfËzòKBç@öâßáìûäíäùíä÷îýuêÅeú{aQhlÃoaùfsíxöî`ìýmêSgão|åwDÙknóGÈmâT]^ø–räåeéR}ïqQùmÒÍÐHküctìjñàníM~âjÞþhùFrãcôôfædRûaçSØàtéüóìT•ÜÈîIìÓ\ízÙÈmÃbmV@rcðaðôÑâÔîþÓéNæß}ãfMTkUljE~jôcÔýdã×ÎàwçÓÁøpæTÏÊvàvFüeØ×såÔJáÀZûÔ]ô}GÚesÔ}APdWKd]|@qsù_Xá÷ôâñäêßå•Ôáé^íçuòÉ}CVfgBbdTbyû^qâÿuçñrÿÞdÿÐ`ÂZnps|EQcÀæOüîTóâSTìOCâMvæNvøsyðtcÊCgô[{ùÛrûÇzÄÊaXügßýyÏøfDùdeç~wë}֔@̖EӖsʗføíiüÊnÿvnöahðmgýkÂügêò×Xàí{àÝKçdÜ×lXlcfKnyÓcðNJïòý{î^OâvÙùpÎåLÒáHWâqßæ}ÛûO\àPeåqcÊg{Ïx[Û~ÔrbÁ`cø{\äFø÷ÝãÚåæ]èåەõþáUÿÝÕÉtôs{ðbDBlõf_åxæÁrâqtú|VùJCÈagÜcQivÛpEÿÉBçý|úøLÉñ\×ÝÍZYõt\ñw]GÐD`ñOaàÞ|åÒeÜÑdBÿOKíÅvæÉ`ÏÉoÙàeØîqF•V|•Òe—ÝeêØdîÈaçØaçTfñZ`ÐX`ÓÛpøÎVäÁÂÃGü×Gá\sÂzd~bgc}vaZTgÖö|DÿPDåÀpøÊ~åä{ýètÛêYSë@zíVfìÏiäÚôVÍÃnòúlÃõmYQaPÎqÜöNýÎLæ_ÛíMúæRíñÑîÃ^ãÛ@åCqùrxÆezÃtsôDsÈQsÉÑvóÕÕý~Û]lÛdgÙfAÆdTù}QøÅå|ÇþyÞøHÇú@ÄçWÚú^Òÿp\Õrýppóa]ÑcÒGgÍÉHçþväÉzöÐ~ðÄyÆÀvÉÍpÁÏuòðAùßÑæuüåJäÃDóVDö[ÀuvöwÕó~ØðpSôY]øÝ^þÕ×_crÝfdÉsaÜGe\ÝJ@ÏÑKÃËWÉÉòõ×å÷\ùûÙÍåVPöHw×tcJFoqPaAðDRþÒOÕÛKqËÖ}ÞÊ^qÞô}_þWSþøÜùìõÂçþL÷áeEát}ôÐe_ÓfIØfyÃfÍY{õòLÙøÒ_Ç\HMZDv[ÏZxôØnÏÿ`Dÿ@säòtòýKôåsXçAqøÇuÀÅ}uXpysvyywÕEWãÐG•ñÿøsIúH{åÞfÊÄm]ùaQísÔëÈÖíÏvúöc÷æ`ÐíeNâyqádxæ~gæpcåFsæDBáQqð×dÇÝgÅVmôÔjÑÐkQÌcÁûüèu֕Hqî_xâý}àçeýàmMäfaõhÕNlôÊcûçgüåbÔçfZçgRáfNäf}ö}ZãÜõ‘úÁ”ÊBíLdøJzæRgøÞoÚÂnZÉhuônrãreíËeãçxûÊdøÎfýóaÍÿc]ñiNünG•qSé\XþqIôzyäO~ãT{ãÖmåÄo÷ØiWÇaÜõqûäwæîfÆïf@îeváwdýAnQQjDä{ÍëB÷êpVì{eãDeìÐeãCfçÑbåÌbûÜaúÜfçðgøæaÓåf@ÿ{Löarù{aÿxhÈpfæÊqéç~íþdùÈfúù|áäföäaßÿfQõnGöisñypöXvýGzþYeåöeôçyÜúaXõlEøpÞéõÄêÿZàßföØcöÿcEô`N÷b[ðnFøc}æâ[NëAtéBgìðdäógùûcÈújuäi{ãp|íÐ~ãÔbûTjÏü`TåaZãeuîpdîÐbåÂmýùgøàdñìgDèríveâKaàuôÑPò`VâsÄëJBîMgàÊfúülÊþoÃàaÖïHwâØzåÏfçð`ûäoWàd}æydåKgä_nñÅÑål\ì|ßér\î@xãügåçcðç`ØábOâzgávoÿQmüÉlõåoVíaIîrî[Hï]fûÄiÍç`Ðìt×éP_ì]záÏm÷úiwùleÿ`dáp`âÁ`çúdþæ~ýídÛìawìvsàÔrãÛgåÀhËñEålIçdpç~dãVmçón÷älÙãbSìaMèyaí]aíÈfïôlæûôànVïf\èeqécbíejæEiæÍnåÿnøíböêdDïdxíedèAaîÊcãä`çïcüîoÀîiwícgàyfâM`âßhåðÆûjßæiQâiN•}s–Ùr•ÍaïônàüjýåißånJà`pìefìqhä^oàÃbãÿaáæcÄágOádrìszïtmâÑcáýgåûlÍüMúkdãz~î|{•\p—ô{íúaòømÊæcØíe^•NJïGxçMm÷JjÚSRÀh]åbÝëDèv|ïVqíÖ{àÁcòða÷ã|ÖãtuøgøMcåõaýädÆåcEämzøfyáw`çYbçÍgàç{æñcäÓiàOlívwîzÓêaáîcëòmîagéÚæìZb‘`P”ã÷–myëÂÀëdd”kçìn—Ða”`uëmÁílÕônÞùaÏúfUþgpõrüYqä÷HóúpSæ\~õÝgYówsñTgFÉ~qûòs]äE`ßýfbþÉlEïÕaá”@w”îguîPjÐëFmýì}cåí}xàçabúþaböÁjmöÀhfçäesïâ~ááp|àït`Çç@eÎíÓfXåRmpüÀa~øút~öåDeÜçP`yôÙfxöþ}gÒþZzÃâôpGÿô|{ßðE}SðÄvQåäÑZüäÒ^ÎQruÎÉNwÒõT@ÅûðÕWÎ÷ÕOPÄEpY_qwÄ÷Ý^Û÷ÀCMÓÙÑ]ÕÇPwJÓÜYIRÄXsIÓÄ^FÍýÚÐÏñÉÑ×ÍÈVDEVQuwZUXwwFYtZ×ÑTE_PXtuX]P@QÙÑÞÂóþñöýðÇÞÚÒÒÖÕÜÐÜÕUßÚÇÄÁÇÅWXÖÕ^uuBts}J[DXPßÓÖÆÁÙßÛÈÈÀÞÛÓ^]ÐT_S×PX\WUÕUT_G×ÜVQÓÚÞQTQP^^Z@CLA^AY^WÒÛÞUTÔRGOBASP\QÔÖÒÃÌÎÍÁÍÇØÛÄÜÕÒÖRUÝÔSTßÃÎÊô÷ÏÈÈÌØTQBttuIMXXSRTÐÔTTSXSTQÔ^YS[X\TÓ×RRÔUÔÛÛÒÓÝÆÇÚÁÀÆÞÅÄÖRWÓS@_\DKJBBvN_FtIGCuuuFAAXY\WÑßÁËòÿþüð÷ÎÃÃÎÝ\ÜÅÝUÝØÆÌÌËÌÂÇÄÙÑÕ_Lvqv|tMXFIYUQSPÞßßÀÏÆÝÞÓVQ]ÕÓÖßÝÓWÖÙÝSY]XDPRT××ÐÔSRÝÑV__]X[PSS^SP\DGGIMYIJERXFDPÑÕÐÇõËËôðÉßÙÜRE_ÕÐÐÛÚÝÅÊðËÌöóóÊöñÌÖ]\BttDDJKAD[SPZ\RT_]Q^C@BZ]WÞÛÛÝÝÞÚÄV×Ý×ÐßÛØÃÃÄÙÐÜPWÕWR^^QÕZNZD@prq|x}pvpN[GMG_@XÝßÃñúåøøüóôÎÜS_VÇÂÇÃõö÷ôÏÊÊÆÚÅßÒÜÕZIwspILtutO\]DÔÍÃØÅÄÀÓÕUS\WÝÛÛÛÙÐÕßÔZXRS^Y\×ÕQÔÕ\SSS\_TWQT×T]UWÐ]BIwqqpvHBL[ZBFZDXSÄôÌôüôÇØÇÒ^GTÒÝÍôöóÿùùòóùð÷öñõÄÙÜ_wqJws}swvv@MFQÕÕÐWQ_FF[YUÐÛÆÙÐÛÆÔRTÝÙßÍÊÁßÃÂÝ×ÐÔXLXZBC^PGOGVEHDu|x{ysCCBZQP[^ÝØÚöååþýòðÌÜØÐ×ÚÌÈÍÊòþôÊòôÅÅÌÂW[U×LuBOJtNtpKAuKXÓÙÁÉ÷ôÞÔÖÑ×TÓÆÀÕWÓ×]ZX[ETÒ×TÔ×P^]TTE\ÕYOATÔRVÖßÑÒÞÖ^ZDs{}wqvFGKu[SGEQ×ÒÇõõÍÁÚ×ÔUÝÎñðöýüøääúðöóýÊÍÀÚÕ[[]XE_CpswLvvvuuHQÑTÕÕFE\UÛÞÓÜÐÖßÃÆZVW]ÝÏÍõÅÑÚPXVRÝÕZ@uON@GHF_W]ZRFuq|}sJuBBA@OPÐÑÓÔÄöõôñþñÑRØÀÙËÿÏÎñùðôñÿöÆÎðÁÑW_DvpNR_M@[YtI[_AEWÔ×ßÉÞWÓÈÅßÍÏÚVÐÄ^O^V@tG×ÑWPÝVCBBWWWÜÜWTØOEÓUÄX]ÍÇTPÖZw}uAtrwYDzv\ADJ]ÅÝÊÌÌZvÖWÞþäöóþåÿðûàüðåäþ÷óÛ^TH_XqOCqs}tqss_Cr{LU@JRWwRôÎPÓôþÎXUWSRÁËÖñÊÀåxJýÃpKöÌÂÆpy^FupOGÓYuÒ_rrYGKz[Û_[qvQWßÕG]ÛÂÙÞôÊÕÑÛðüÓÂþõÉäåûüñðÁÛ÷ô]J×T×uIÝ_O^PÑMOX\[C]ÑV]^UVBÔÚV^ÅÉQ×SÕÔtFÑQCÂQ@[RÛVw\ÅT_ØõÝZ\TUHG[VQÔVPQD\ÜKq×XFMqLCvr_YuÚÅÕSU×ÖQÂÛÊþøääúáíàæææýðóóÍÓÆÏÐEWÓHpNBwqMYOuBNS@uuruvsKLÕÒÒÓÛßÝ×_ÝÖÖÙÌñØÄÆÝÅVQE@XXÔ\[YQDELJIrsu}sOCKtwuFFLEu@FXTSSXSÒ]RWßÔSÚÉôÿþÿùûçãáäåøùõôÈßß×VÑ_TÝS]NXÒÚÀV\^ÓÛ\Z@]GerOMJMQ\vu\PI@]ÝÅÂõÊÖÔÓÄÐX^TÐZ^WÀÐÅÀÉÃXUDOI@_@GBZIvJt}}sJNqvLHZXIuuFNrAÖÝÕ÷æçûçìææáãããÿø÷ôÐÕöÑÔÒÑÚI{YÑ^SÜÐZF×]LLwC|gdqssIYBGôÆY]ÊÚõøãäþöÀôÌÛÐÇÞOHrAÎUQÖÐÃØ~wQustVNrw{spFÕLWDwW\GPAÔtPY|wtuÑûûùáãåùÆúæÿñÛôÉ×S_QVFLÌÐBGvÂQEÅÍÒÆÙÚDw_DMG]@Bvr@M|tw^}pY_÷ùÂþÒÍôÜVsÒuvñÐûØùÅJðËýÏôËÀZôÚ]XL×OuvexCfJFv]vRO}XqJxdrtWÃËòæçøçæýþûåýó÷øýý\MP[ÙLwyFvR[DVEÕAAXpzBCsUwEX@LMVV[YRXÁþçäüàøôðÝÓõÒØÉÅÏÂßQÖTSßYÓQBFsGBqHtLuwNtuKER[BÖCMW__^LHNB]ÀööþüççùþåúäÿüöúçÇÓ_VßÇÒß_RÕ_ÓÐÙÐÛÒTXEXp~~~y|IpsLJFHHKvpDØÇÈôññÇÄõÄÀÐÑôôÀÅÞÉÈÑTÄñPÑWRTL^HAr{y|y|e|tv}uEMtpFOttKqJCÔÆÄÊÿüóåçãääàûøääðóÁÃËÀÜÅÅ\STPÕ^JÔ@\F^T]tIqpDAEE^@RQ×YJXÓÑÒÙõÿðÈÈÇTßÑÔS]ÖÅÙÖ]ÔÞQWQSuN[]OsOJqvJtuKqsKK_Ô^RYEZX_BtvvMPÐÇõÈüø÷òäàúåäåüñöñÅÝÛÁÌÑÖÙQ[[_PÕÑSÔØÔVR_HuIMNNZCIFFHuqMOJATÕÜÚÆÄÆÌÁÒÒÄÛÒÜÍÌÁÇôõÀÅÆÓSXG@uwtw}pwp|dd|{ywOtwvuNrpvvtHWÒÄöåäçáìééìììãàááÿò÷öÎÀÙÔWSENHH@AMGRDGFOtuNEZL[ZYAAZSEYÐÕÔPØÁÄßÌôÌUÑÐDM^ÑRYWØÛÓ×ÚÞXILu|srsqtvMIMwtAGX]PRYDFMNtJtJBAXÒÇÆñúäûäáçøüûûýôüüöÄôôßVÐØWZ\×RZPÜÒVW×S\XS_ROwA@NK@EGB[YYYRQÖßÛÌÌÄÝUQÕRVÓÙÒÜÌõÌÅÚÅ×OILu|{}p|~wt}xpHwpKIwspqvvptHAM\ÛôüùáííìîâáæàåäåøøÎóÚÖÞMXPH_KqRD@u[WBHGSWXRWPZLY_CBQÕPRUÒÚßÙÏÅÛÇØÐ\GXGAG[VÔRÓØßßÖÕ_@NCCJvvuIOIXYZGNXXIOCOr|ps|e}qstDÞðýåæáæçãáäúääúúçåÿõÉ÷ÁÔÐ×W_XPÑÖYV×PDLYSE@ALNuvMFuI[^\YPßÙÐÚÍÀÇÑ×Ô\]VÔÖÕÑÞÙÔÝÃÝÖTURLIDEurrOwqC]XKJNCt}pqr~sqs||J[XÝòûûúæàææáàæûååäøÿüôÁÒÑÐÕPTÔ]YSSZMOD@JC__CJE]AORSEAI]VVÖÅÆÆÙÝÅÞQ_X[[ZPÑ×ÖÓÒÝÒÓÒÕQQSR]__XBtu@[QWÕ×[L@EBvrs}x{~ydd|uDQÃöóÿûäççäççûùäçæúþøòõôÉÂÁØÙØÐÖTYZ@tKCHMJqttLFMBEZ@BKCWPÓÅÚÃÛßÄßÖÕ×ÐÔÕ×ÅÇßØÜÐÖWT\@^VREMNwr}tuNG_YDLwJuqq{{yz~uM_ÞÚÏöðòååæààãåÿúàæåûåÿÎôôÂÆØÀÅÒ×_GAOLtuMOLJLGX[RSXFDABBGYÕßÓÑÒÖÔQPS]\DD^Q×ÞÁÇßRWÓPX[PÞÓÔUVYNLD]ZET\XF@EuwsyxzdewM_ÕØÚÉ÷þåäççäøåçááàæáæäøýñðóñóñÁ×P^LuuKtr|ssqswu@HwZYAuAVÔQUÐÐÓÑßÎØÅßÑÖTÛÅÄÃÂÄÖPÑ\ECDSÕ_COHp}wHpuOGJwuBt}|}s~}wMODQßßÜÄ÷òóùååúøþäççäçäåüýýËÉõðöÏÂÚÔ\XFJvvJMJIA]Z@GWRMESW]S×ÞPPVÐTR^WÔZE_UWTÜÏÏÏÄÀÓ[GE\RWTÔW^EYDDBKNMC_^Juvv|xy}e{tMHO_ÑRÑÅöóõ÷ýüóýúçáááâààæäøö÷üòËËÆßWDLJspsvqpvKJvBICJL^\G__^Y\PTÖ\]WÝÑT×ÙÝ×ØÌÈõÏÙÞ\FCRDMGGEO@@MttJMNDR\KqvvqsquIvK^W_VÖÝÓÐØÊôÌËðüñðøåûúäææúûùóÉÊ÷ÊÁÁÌÅUZGGLtOAAtIAELNZV\HDÜÜE^TÔXE_WMuOZXIGWÖÖÓÆôõÏØÙ[HGP^@GSÕZZ_PBt@QDF_RKrvtIr~qvqvLSZEXÓßVQÙÊÜÐÌñööòúççæãíæþøúòôôðöÊÏÍÃTX^YFBLZNvsKAJJ[SLBÕÝYAEÔÔX_T]@@RÕ_ZPÒÑÕÞóýÍÝÞUAOMCKwt]_@CYZMA]ßRBIBtspHpdevuJICVVSÓÎÚÞÙÀÎÍÏðòõôðåäåäáøüÿÿÿñõðòÉÆÃÍÝRYT]_E@@JstFCHuAYQSÕÑVYWÖRD_PGX_\PSYSW×ÚÏÈÀßTÔSFtOFCOXV[YYSW]SÝÐ]L@BItp|xyyqwvq@]TÔßÇÅÓÑÄÃÁÅÈÌÏõùååúúúùÿüó÷÷ñÿñôËÈÚÐVÕÓÔ^G\DC@DCHtMAZDFEY\Y\RUSGZSRP^XZZV×ØÚÀÙÄÅÚT_YDCNFSTRSQUÖÜÑÕ\YFDFOtsp}r}wvsvKB^ÐÃÆÙÉËÎÍÉÏÇÓÇõ÷ðøåûûþåûùýñ÷öÎÃ÷ÈÜVUÖQGRÑPLZY[OJ@CMOFZTZEX^[Y]X\\\QXADF_D]ÐÞÑÝÚØTEQTEuFR[GGEÔÔVTÑÜ\^×VJwuKyz|JwpCG\_WÄÉÅÙÍ÷ÀÜØÁÜVÒÏñöýúäòüúäøðóüñÎÊ÷ôÞÖÜÐYQÑÛÝQQÒÓCI@ZwrCÕRB@QYNFÕÖEMCCupwADCGÓÄßÞÀÎU\VÐRGVÑQC]ÑÐ]]Õ×RSPÜYq|rrze|t}pCAZ\ÛËÄÚôöÈÜÐÛRXÓðòüúáãæäææùóõòóÉÁ÷ÂSE_TDGQÑ^GXRFOMDHuL\ÕXGGÕW_\ÞÝQ^XXKuNYXYPÙÃÌÚÁÄÑRZVSXQÔZG\WSSXPÑVQVÕFsyr|z|JGOwCS^QÝÛÓÛßÄÆÔPY[[SØ÷ôòäææääçäýÊôñõôÍÏÛT]WTV×ÁÇÕQQQEDBOuOZSZNME\YG[ÕROwItrqOEB^ÐÆÇÞÙØÖ\^WÕÙÅÅÄÔÑÒÔ^GQÓÕS]_Osx~{epNLNBSTDYÓÐÖßÇÞÑÕÓÕVßÁËùååãâàæäçùôóü÷ÇÁÆØTZ\\Y]S×Ð^ZQ\@BAFAA[XNHB@DD[ÑÖSXY[OvO^Y[ÝÂÝÕÑÜVXD_QÖÜÄÇÙÖÕT^ABSVXA^EJvppsvtDPS]TÑTC]ÓÐ×SÐßW]Ñ×VÐÂ÷óþúááäûúùñõòýÈÂÀÇÒUÞÄØÜÒÅÅßÔWW[M@[XBIXI}sKOwNBGZZXY@JqtZ_ÔÜØÙÕQ×ÔRVÙÅÅÉ÷öÃÓÐÐSZ_×YHAAJsrs||stB[PVWV^ZZRP\ÔÞ×^ÔÚØÙÌ÷ÿùúçççøüóüðñööÈÙ×ÓÑQÕÝÑÕ×ÓßÖVT]FLFW]@O@LwGED@C×ÞßÝÑP_CKBFF\TT^LBANNE]ÑÜÙÆÇÅßVPSY[\SCtuBMNBOMDSTPWÜÑVRY[V×TPYRGXÖÝÒÞÉòøûúåùòö÷óÿþò÷ÏÇÆÚÇÇÚÄÁÎÃÒØßVX\ZJuO[Ksqq|spvJODQWÕWGALHN[P×ÖÒÝWPÒÓÖÞØÍôÏÌËÀÞVPQY[MJtvrvwwvtOHGGGQRXSPWÕÛÙU]R×ÖÓØÈ÷ôðøåúÿòöËõÏöóöÊõÂÅÞßÓÞÛÙÅÄÚÞÛÝQ@GGFLHO@tw@MBYVSQ^RR^RIJwJICEXDFA@M@PÔ×ÜÍõ÷ÌÀØßÔWÕWFINNBuNC^[[Z__]SR_G]×ÐZ]PXMNGX]ÔÚÌÊ÷ÿøøñôõôÊô÷öñöýóñô÷ööÎÎË÷ÈÆÐÐÕDMNBv|pt|~vCGGAGBN@OHqJBMM@XS__RÔÝTßÆÂÛÁËñôÆÙÙÔFA@Buuuq|pqJKtHAZE[DSVVÕÚÓW\ÔÑZ\ÚËÊÈõöÊðýüôËôÈÚÚÀÏÂÇÏÃÉÁÄÏÏÛÞÌòðÇÜÒÚWZGFNHMDLE]ÔÐÔÑUXMJqqsvuutqpO[utEÐÔWTÂÏÁË÷ÉÆÅÅÞ]_\SYVX]XLZRZLC_PCLRÑ]ZXÕ\LK@HqFPßÝÓÇÎÇÊõö÷÷öñôÃÍÏôÈÏôþýñðòðõ÷üðÂÇÞÙ_COKtqpptKIARY[MGt|ysrsvuupNE][TÁôõÈÊñ÷ÎÉËôÆÙÝÖ^MNX\ZI@[BuwuwuMFLFYSSSUTYAAFZDWßÂÍÍÁôðÈÏöòýðñðÍÚÞÛÖÝÙÁÁÛÄÀÍÎõõ÷ÈÀÀÂÜVCBG@MD_SPSÑÓTYEwqspp|}r~xvJuH^ÓÚÅÍÃÌÉÍÀÌÊÎÃÙÜ×RYUQPW××QV_GMXXGZ\R\X\]GuvtvvtD]RQÝÅÌÍÉ÷ðòüþûùõÌÏÈÛÆõôÉË÷÷õöýðöôöÎÛVGHutJtHMM]PXOFAJ}}qsyysv~~w@BL×Í÷õ÷óÿðÏô÷ÊÆØßß_D[^ELEUQ[XAtwMADHXÕÔ\VÔQOvNCGLYÑÄßÓËðÌÏ÷ýýöðÿñÛÚÚÞPVØÂÇßÄÎÉÍÏòø÷öòñÅ^AXBvI\PWÓÜÛP]]Dtqpv|e{xed{|twO×ÎÇßÄññØÆññÂÁÃÏÜSÔÐÔÑÝÄÁÜUQ]DEOX[CYPXNNLu|ystptCTTRÐÌÎÉöÿûûþüùóËÀËÉÂÁÊñËÈõóöôýúþñÊÎÑEuwJpptZX_X\DOJHup|rtr~~ryyrM^PÖÉ÷ôËôð÷õÊöôÍÞÐÐWX]UWTQQR[IBvvqwHDE]SFGwutKqMLA_TÜÜÝÛõöòýþùÿöñôÏÀÄÁÅÞÝÅÂÃÅÃÈ÷õñòþüñÏÞWFGN@E]UÔÜÑ][GCLvqssxdfaggzrtIC^×ÐÖÓÄØÂÃÎ÷õôÍÛÙÆÆÄÀÏÂÀÝÄßR\AHtuK[_ZKtttrvKtuKADZCRÔÑÆÈðøåúÿÿýñöõ÷ËÊÊÏô÷È÷òòýóóüýõÅQ_EHwtLMIKACJKLKJtqwNqzzexy}uG\ÖÙÅÇÀÍÂÀÅÇÀËÊÍØÚÑÔÛÅÛÛÛØU_YGBtqspuIZEBBA\RG[V\DXPR_PÝÞÞÛËóýñõóöÍÀÀÇØÝÅÄÚÅÏÏÎõ÷ýüýÿðôÎÜÜßPD]ÕSZEPQ^S_ZFJwq~faafddJM@_UÕUÔÓßÐÛÈôöõôðôÃÈôÊÊÉÍÄÓÐÜÔDtvprrvvppwOJvLXKquCXAFUÁÍõüûøÿýÿòððòüöÎËðôöòð÷ÉôñõÇÞÅÝSGE[OsqJuwJZYNL]R\ZMurxzx}qwGVUTÙÀÛÑÔÒÜÙØÁÀÆÀÎÎÍÅÚÇßÔÕÒÐTWVYHtNJvqtCFGA^S\AG\GIMRRYVÚÀÃÂËôõÏÆÁÈôÃÌÎÂÁÉ÷öö÷óòüòð÷ñôÈÀÚÓÑÑ\XZ\P^^SYGAFNKpx{fa`dx|qBG[Z_]\UÙÅÀõñüûþòóòðÉõËÏÆÀÎÆÝWAuvsrqvsrqJuHuuvvwuMGRÕßÎô÷ðóòôöôðüòñ÷òÿüÿüóñõôÉÊÉÅÆÃÀÝTTPGDGDEDEA@G[@C@Iqvq||}qvuBFDPSPSÕUÕÓ×ÐÝÃôöõôÉÁÆÃÇØØÝÖÓÓÕW\DLNNuINNHuKB@MuOLJKL\QUÖÂÈÌÆÎôÎÁÍËö÷õöýüñòòñôÊññõõ÷öÊÌÉÚÐÖÒWSTPS]EONts|~~{eee{zxrvwqNBZEAVÙÒØÌôÎÉòòüòüðòðÈËóôÃÛÅÓZF\XvvvJ}|r}xx~xysJst_ÅÇÛÈò÷ôðòýðòÿûýýþúåùñðýÈÉËËÚÇÏÏÜÐÐÑ×P^\U^[FZHwtBwy~s}ex|pswwuLAC\W_GÔÍÞÐÞËÃÚËòôÎ÷ðõÉÈÍÍÇØPWÓU^TWDBEMqrpq}rsrrptJtL_ÑÔTÛñõÏôðööðòñöòòùúþöùùòöòüôÆÈÊÝÖÁÇÔWPÔYXAtvIv|red{dde|}sJtwMZ]EPÅÌÃÀÀ÷óðÊòÿññðüöôôÉÜÒQ_^\[OB@Bttp~yv}x~r~e~vvJYPÕÑÆÏöòüðÿúùóýþñðÿúýòùøýòóö÷ôÏÞØÙÔQÕSX[\@JJIIIX@Jqvryyx|p}sNAHIEXDVÙÄÓÒÚÇÏ÷ôõðóðõüþôÁÌÄSV×PYZE@M[@KtKqsvtqrr~zytwuYÖRTÄÊ÷ÊñýþýóóþüôÊüþüÿååòðýðÏÎÀÜ×ÖYGY^MOFOtO\BH@Fwrvq{{ss~pOuHMLJDUÕÐÌôÂÇ÷ôÎ÷ýþýóððöôÀÒßÓ^ES[CNOJJLFIIMwpuHp|~x}wHGÑÙ×Ûô÷õñÿüöýøÿüùó÷òùþÿúúòôðôÃÁÄÕSQ^CM[BwH^ACRPDDMv~eex{d|qqswwJAPÓÝÁÎËôóðñþûüýùúòðñÁÕÓÙPP×]AMBLK@Cpptrypw{aerxewON_ÐÜÇöô÷ñüüòøäøüøûøúäçäååý÷÷ÉÙÛ×Y_^NwBFKvBZLL[ELuvs}s{~}yytAvqA[FPÌÊÍËñôõððññóñöóýôÂÅÑYVÖQE^^COE\GMHtvur}qq{z|s}sNE_ÔÙÇÈ÷öñÿüóòøúòòøò÷üåûþûüÊÀÌÇÐÞÖ\__G@^TDI_WGM_Zwptpyzgex{~KBwJYW\ÒÏÎÂÉöôõ÷÷öòýóòþöÇÁÇW_ÖÜ][ÔÕXZ\ANHv}sqyz|sdgy~e~KFBWÃÃÊüûþúäúûäçøüúûýûçäÿòöÁÑÐSFEYAEWW[Z^CKD\BNGBvvtp{{{|vqvERD_ÚËÇÆËöÎõ÷ÉÃÂÆÀöó÷ËôÏÝU×_FYWR]ÔÖXMCOwtHvvuv}rqy{rvppC^PÜÌôñÿúùûääþûûñÎ÷ñôðþý÷ËÀÖSSDF\T×ÒÄß]^QVXW×DHCIs~efdze~wpqGTPÕÁÈÇÅôöÎÏÍÙÑÛÂÃõòöÈ÷ÊÐUÛÜPÔØßÔÖPOuvpsvtr|przz~ye}vst_Õ×Âðýþåäçàãçåäøô÷þüô÷üöÂØÖ@OALN\U]PÑPBB_FKD^NwOu}|r|y|qpKYYX×ÇÂÂñóõõðÊÜÒÖ]\ÔÒßÃÈÀÆÇ×[PÖP^ÔÙÐPQQZAFKuBButHwqIqrHBIDUÐÒÆô÷öúçåäåÿöôÈÚÚÈËÃôüÎÑÒÐ_ZQ×ÔÓÙÞÄÃÜU×ÝPAERMrrszdxx{|pptDGCQÙßÇñóôõôÅTÑÙÕQÙÍÏÊöÉØÇÚWUÇÒ\ÕØP@]YwpHt|vKrsp}tq}HYLNÕÇÙÂüúäàíæçàäüýýôÉôöÍÄÅUAM@IJE]A@ÕßÑÒÖ]VÓÕX\ÕFtHOvvNOuJ@FDRTRÔÏÊÉô÷ÃßÛÜZDQYGTÛÒÐÄÞVP××]ÕÑVUÜÐRPUXIESLuDZINCJuOOqvLKuZÕ×ÛöùøåæäååúñÏõËÌÌÎÛÐÑP@@_EAX×ÔÐÌÎÄÄÀÛÓÝÑX@ZFtww|yrr~}tLwJYPÕÄÍÁÍÎÍÅÇÚÐPÖßÓÛÌÍÀÇÇÆÞØØTQ×ÑUÕV[DFDLuNJtJIuJutwwutwHBFQÛÈñþåæáààäåûóöôõÏÄÅÖ]GAIvJutAW×ÖÑÞØÓßßÕQPRX__@NNOqqBG@F[]TÑØÅÇÆÆÄÅÙÐS_\]_VÓÝÒÐTTÑ×QYSQÕ×UÑÖÕQVÕPPSPWR[[ECNJqpvvquAEPØÌ÷üåäåúûþñ÷ôõËÂÆÛÒÖSEXZC@QÓÜÄÁÂÏÏÌÄÝÑÔS[\^@twws}}ppvvJXR\WÝÚÅÙÜÝÓ×ÔÖÔÜØÄÏÏÎÂÏÃÅÞÐÑW×ÝWQÕV_^EGC@DBNFLwwtqppps|u[]×ÌÊ÷üäæææáäøþðôñôÆÞÜÔXGFJswNMZSUVÖÒÜÙØÛVRT\^WPAMECHIEG@]VUÒØßÐÛÅÖSÖÑGF[[G\Ò×ÖÜÓÔ×ÖVSÕTVÕßÞ×ÙÚÑWÑßQ]ÕUP_ZNKus|||~vD\R×ÆÍÈñþÿýüÿöô÷ÊÈõÏÚÚÇÒWPQ^A\×ÖÜÚÆÁØÙÅÚÞÔYZRFHLJq|}qpqN@G^VÓØÜØÚÐÕU×Ð×PQÕTTÝÃÈÅÄÃÄÝÓÒÑWPSWWUU]R^@AFABLCHtJItpqpqIZÕÛÎÊõòøùùääþüòóÊÌËÀßÐÐW[[AIHJLAVVS×ÒÜ×ÒØÐS^RPRY[ZOKOMEYRÔßØÚÂÃÁÆÚÜÖÔP^XANuOFE\WUVSÑÐÕTÕWPÕÙÚÙÄÃÅÑÕU××WVRYGHHNtpsvKIGTÒÓØÁÉôöðñôõôÊÃÙÞØÜÔÐÒÓ×Ö×]\VÕÜÄÂÆÄÉÌÅØÝÔRSRFBBuspwtNGEZS×ÔÖØÙÕT×ÕSPUPYYAGP×ÔÕÞÅÞÚÌÅÔÜÝ_VÙØÖÑÞÑSRPXX\CJHKqsJKqvDEZÒÛÒÆ÷ñ÷óþòðýòõ÷ñÇÜÚÞV^UUED\BKZEM^ÝÑQÝÇÖWÒÓ^VÐPZ[[LMQUSÖÅÅÆÈÃÞÀÎÛWQWALZAtIMHuMFF]ÑÐTÔÝQ]VS]ÒÏÃÛÂËÁÅÅßUÐÞS@GFBLA@KN^\\PUÖØÀÄØÅÂÍÅÀÀØÀÆÝÔÖÐÐÒÝØÖWTUQRTÜÀÍÍÈËõÏßÜ×_YYBwwKNM@[Z\ÕTTÕUÐÔÕW]_UÑQQPSQÔÔQÕØÃÇÅÂÛÝÔ]ZGSÕÕÐÒÞÝØÄTX[EMtwvwNBLB^QÔÒÙÜÙÍõËÍÉôô÷õÈËÉÏÙÐÓTWÑÓV^S\GCIuC\\_×ÅÃÆÀÀÙÝßÓUVS[X×ÙÕÔÄÀÙÐÜÞÞØU^^YAOGEBNCDCNCZYQÕPWÐÑ^Z\\VÙÆÁÍõËÉöõÄÚÙQCCZCBD[OMXDZQV]WÙÝQÔÚÓUÐÝÒÅÃÜÐÚÄßÚÉÎÓÖÝURY]WÓÛÞÄÏôÏÆÎÚÕWQXCABNC_X@PWDF\WW×U\^VW[_ÖS]ÔÐV]ÜÚÞØÅÜ×ÞÑGA\YFQÙÙßÅÇÒÝÞT\^@qsNMJH_^[WV]×ÇØÓÆÌÄÅÊÈÆÀÃÅÛÆßÖÓÚÒVÝØWX[MqwNINQÐWÞÈÎÆÊ÷ÆßÙÐRTÓÔQÒÚÓÑÅÙPTÜÕ]QQGMEOuBFttBOKEVQTÖÖTVT_\×ÜÖÝÌÎÉõñÊÃõÏÓ×ÐZHDDHHE[NO@MCPW^]ÕU\RÞÝÔÛÁßÓÁÃÆÍÃØÛÀÇÖWP[ERQTÞÚÛØÇÏÀÀÍÚÕSWYD\[@GQ_MYQY[WW_WÔSXQS[^ÔQF_ÔTVÝÛÝÞÅÝSPVX[QUWÓÙÜÜÅÛÑÖÓWFG^DOMFAEXGZ_^]UÜÜÑÝÄÅÄÍÌÃÀÄÞÐßÙÓÑÒ×ÔÒÓP^YGMB_Y[TÐÑÐÄÌÆÅÚØÖÓØÓ×ÐÔÕÖÜÓÕ×ÝU^VV^DZ[Y_Y[@MMuIGA@[VÕÔÕÖ×ÔÜÒÓØÙÒÝÆÃÃÏÉÃÙÄÙVQQGHBZLHCDBLY^Z]_DYÒÙÞÀÊØQÜÆÓÖÚÙ×ÒÞÜßÅßRWÙÜÑÜÜUWÝßÒÅÍÜSÓÙQP×Q[EZZ_TRAQÜURÔÕXZRTPUÐ_@\RF[URZVÙÓÔÞØWÒÌßUÝÜQ\ÐßVUØÔ[ÔÓ]E^AKLYAHX_O[×V_UÐÖÞÈõÉ÷öÅÔÆÁÖT×Q[QÓUWÓÕGSØTZWÐ_]ßÙÕÜÂÖSÚÅWUÅÜRÕÛßUÙÅ×ÒÇÔYWÕE[Ð×GEUEt@FJLD@GTÝÕWÛÇÝÛÌßWÝÓ\SÞÞPÒÌÒÑÏÃP]\CBEZKu\]NDWDB^ÕTÐË÷ÀÃõÇÝÁØ^YTP^ÔÝUTÇÂÜØÆÙÑÑ×]QÞÜWÕÒTÕÝÖ]]ÖQ^ÖÝW×ÆÆÑÒÞ×PQV[WÙQFZSEB^RABQS[VÖPÔÂÌÞÜÇÞPPPFY×ÔRTÄÇØÚÛÕX^DNB@LD\YMGQR]ÑÚÀÊóöÍÎõÃÛßÕ[E_GA^PRQÙÚÔÜÃÜRP×PPÑÖSÔÄÜTÒÓÖßÜÝÐÙÎÁßÄÛ×ÔÖÕ\]PSVQ]FZ_OLEGDEECF]U×ÑÙÙÐÜÜÖWWTVÕßßÜÏÈÆØÄÄÔQ\MHNMLM@LLCG^\ÒÁÃÏÍÉÍÀÂÇÝ×ÔRXZFEVÕÕßÞØÇÜÑTRÔÖÔÕPÖÝÐÐÜÐÑßÑÝÝÕÐÛßÖÔÑÖW]SRS×ÖUTVWW\_]X_Q[ZXEZ\ÕÑÕÓÙÑWÕW]VUWQÕÜØÞÅØÙÙÝÕYZECBDZ@@EEG[RÔÇÎÌÀÎÉÃÃÁÚÜÑÔ^ADDGXRPPUÖÔPVTPÐÙÑÑØÚßÙÇÀÚÛÄÑÕÝßÒÒÝÔWTÔV[VÕQU×VY_][ZRSYXRDC[GD_RTWÔÝÖÑÅÞÑÓÜÐÔÜÛØØÀÙÖÒÑXEX[FDYFO@@OCRWWßÅßÓÅÀÅÅÌÄÓÜÓP^SSY_R]\VU\VÐÝ×ÑÙÝÐÙÅÞÛÚÓÖÐÒÔÔßÝÖÓÑPSP][SÑÖÕÐÓSPTP]\P][RSDCDA@XSSPTÑÔÐÄÛÓßÜ×ÐÝÝÝÐUR^SPY^P]SÕQ_[E[C[TÕÖÜßÐÝØÅÇÇÅÜÐÜÕ[Y_ED[XYY]PSSÔÖÖÜØÙÚÃÀÁÇÚÝÓßÝ×ÜÚÓÖÓÖVPWTWWÔP\S^_RVQ]VQR\]Y@BMHB]QPÑßÞÅÆÃÁÁÄÙÙÚÄÜÐ×]YXSRZ^^EZ^^EZXD[\RSÕÔVWÔÒÙÆÂÁÇÛßÖÔTS^ZY]QWWTÕÖÐÝÛÅÞØÛÒÐÜÚßÜÙÒÐÒÒÐÐÖTWP\_QUWR]QWU×ÖÕÕÑÝÖÑU^DCLOF^\QWVUÜÇÇÇÃÄØØßÓÔU]EFZEX^__\T×ÕUT\[QWRVÓÐTÑÜÒÞÃÃØÙÜÑW]_FFE[ZESQSQTUÖØØÜÇÄßÛÁÆÚÛÅÛßßßÓÛÁÒÔUT\X^[@CXE[ÕUWÐÛÜT×ÐPFAMuFSSÔÒÞÝÄÉÎÅÂËÄØÆÙÐÖT^B@FLOX[ARU]Y^^GE\GBV×\QÐÒÞÁÍÍÇÇØÝßÜVQÐÕ\\VTWÔÓQ]×W^ÕÒWTÓÓUÔØÓTßÅÝÜÁßWVTV]VU^XWP\UÝÜÙÃÂÛÞÙ×Y[ZLIAE_Õ×ÔÜÁÀÞÛÃÄÒÙÙÖÕQEMNLIO_ÔRQÝÔSÔÖR]TQZ\ÒÕ]ÓÝ×ÝÁÇÄÄÛÓTÔT^\T_D\V^YQÕSVß×TßÒTÑÜ×ÖÛÇØÙÀÀÚÁÇÐÕÖT[ZQ]AYQDDWÕVÝÁÛßÆÛQ^QEM\WSUÙÜÖÞÀÇÙÂÉÞÜÄÑ^RSGIBAO@\EGVU^]ÐQ[_QXZQT_QÜÐÒÎôÎÃÍÁÜÐÐPRÐ×X^TYCZRX^ÑÜWÔ×ZFVVSÕßØÝØÆÚÞÆÇ×ÑÙ×VTTYESQD^ÑÔÐÂÏÇÃÇÜÕR\Z[TÕ\_VSQ×ØÛÅÏÂÓ×ÓXF]\DE\]XXZFZWQYRÑ×_]W\XRQSWßÅÀ÷ôÆÄÇÙÕSPP]Q\ACBLBDRQ×ØÄÔXR\\V×ÑÞÇÇÙÙÄÆÄÆÁÝÖÝÙÑR_YE[^EE×ÞÓÒÛÚÞÜÝW\]QPRPXEPÓÐÒÍõÎÂÃÜPUÔ]_SRE[[OtLEB@\S^VUYF]Q[\×ÖTÇ÷ÉÃËÈÄÅÛÔRUÓ]ZR[LEVXXÔÝVR×\LXTYXÓÙÑÔÝÕWÄÉÅÚÈÃÓØØP[VÕ[EÕT_ÞÆÑÔÛÂßÝÚÕXTÑ[DS]FSÐÑÞÏõÒÕÚÝQÑÒ]XUÕE@AJwAXMEÔÕ_^\EFSUXRÞÓÑÄÏÚÛËÌÒÒÞÕ_ÕUZ[UWGYQ__UTZ[ÔQZ\VYYÓÒQWÓÖ×ÇÊÏÍõÎÝÓÒVSTT]PÜÓPTÔV×ÆÅÒÓÜTZ\PX_ÖQEPÐÒÜÄÇÑ×ÇÛÕÐÓVVW]AF_GJL^Z^ÕPED]S_RÖUWÞÓTÖßÚÇÅÙÐ×ÒÑ]RWSRUQPVVPYXRSP×PZ]UTWTTVUÝßÓÄÉÃÚÅÙ×UÑÑQVÐÐU×Õ^^UÓÔÐÚÞÖÐÑSPÐÐPQÖÖÑÓÜÒÝÅÚÓÐÒ×PUUDCEGFEGLC]YMFXZF^SR×ÙÓ×ÖÑÕÖÃÀÜÇÏÛÖÞÚÑÒÛÖ^WØTZ][MGS]AZ]DZPP[RÐTVÝÇÅÄÎÏÜØÂÄÞÙÇÚÅÃÜÔÒÒWQ×ÔPÕ×\EYRX]V_YWÒÕVÓÞÒÞÅÓWÒÛÖWÐT\QÔSYTÔ^ZXZ@D\EC_×Q]W^A[WVSÐÞÜÓÞÖVÝØÖVÑÝÑÜØÐVUÖTQVP^]U][WÕQUÖ×ÐÚÅÑ×ÜÝWÐÙÖÔØÅÝÐÐÔQÔßUWÙÝVÔÝÖWÐÙTSÒÞÖÝÙÖ×ÞÅÒWÖ×_PTYEXDCGXY_VPABEEDYXXPWUSPÖPZVÖÔÝÄÛÜÝÞÝßÃÛUÐÚßÑÒÜÔ]^_GA[ZCGXYRÕÔV×ÞÙÜÄÅÞÛÆÄÛÄÆÅÞßßÑÖÐÖÕÑÓÓÒÑW_VW[EPVRSVUUÒÓÑÝÝÓÕÔÐÕQWUÔVQRRWP__QV_]VSS_XXY[ZX^YDDZ\RQPPÔÖÓÝÓÛÄÛÚÚÅÁÇÛßÒÔTSGEZ[]RÕÖÔÝØÙÜÝÓÞÛØÝÜÙØÐQTTPÕÔWÕÜÞÝÜØÒÖÒÒÖWTW×ÒÖW×ÞÞ×ÐØÝÕÔU_^WW]SRZ[_FOADEXWÔ]Q×]AD^ZXRRXRÓÔP×ÔRTÜÝÝÚÃÚßÆÇÜÅÎÅÔ×ÑS[GMuHDD_ÔÐÕÓÜTTÞÄÅÆÌÃÄÀÆ×STT]VÖÖUÜÄßÐÜÝÑÜÜV\TT^[PPRWÑÐÓÞÞÕPP\RÔÝÓÖÓÐV_EAA\R\ÕÝ×VPYCAEZEZ[ZY\XG^P]RTÕTUÒÑ×ÜÄÅÄÍÃÅÆÆÒP\\XX]]]ÖÒÕÕÔSPÑÞÛØØÇÙÐT_\WVSÔÜÜÒÜÛÛßÄÁÜÚÄÓÜØ×\R×ÐÖÑÞßØÁÝWTRZYRW_YQ_NJKuLZZYSÕQ[DEAXR\SUTPQWR]ÔÜ×WÝÝ×ÖÖVQ×ÙÞÚÆÛÛÁÛU_R[BA_\YT×R_WUÔÒØÞÞÆÁÜÓÔWÔßßÐßÚÞÖÖÜÒÑÙÙÒÒÝÖTP]AETÕVÐÞßÅÁÙÐÝÜÕPÔÖVÕÖS[[YY\P]\VÕYC@@MA^^^RQZG^XXWÖÕUÐÝÖVVPP×ÓÓÙÇÁÁÁÆØÐÓÑSY^_X]_DXQS_WÖTÔÐW^^]STÜßßÞÇÛÐÝÄÆÚÇÀÁÆÌÃÝÐÑWÔÜÜÐßÅÙÜÅÄßÓÓQ_]S][E@MAX[[YYZY^DMDYZZS×WU×VPÔÑÑÒÞÜÜØÛÑR\R\RTÕÓÞÞ×WÑÑVTÕS[_\ZFXY]UÐTQÖÓÖÔÕVPÕÒÝØÃÍÇÚÚÞÝÚÛÑÔÒØÙÙÞÔ]RSSWÑÐÒÙÜ×ÐÅÆÛÞÒÐÐÐÖWW×TVÔÔPY\_A@AGXR]Y\TT[[]_YSVRUÐÜÓÑÑP_ÕÐÕÔßÞÒÝÒÑÑßÜTWÑ×UTPYZYS\^R^X_Y@C^RQÖßÅÚÂÁÞÛÅÛØÛØÜÝßÄÛßÞßÝßÝÖÝÅÚÝÒßÝÐÙß×ÑÜ×RR]\]UÔ]]\E@@AIHES]×ØÓTÔW^SÓÓPPÖÑÐÞÙÑUWVPVÓÔUÑU_^RPQVQSWÓÖPWQ\]VÕW]]YEE[XSÜßÓÚËËÀÀÆÛØÃÚÖÓÑU_SU_YUÐVTßÒ×ÒÒ×ÕßÙÖÜÇÚÙÚØÑÑßØÝÒßÖQP^LIGFCDWTWÐT^FFADR]FFRPX]ÔURVTUÐÄÛ×ÒÙÖ×ÛØÕWÒÒÖÞØÑ×ÜÔ^SQYNNOqvAY^ÑÇÚÅÌÍßßÀÅ×ÝÚÑTUP[YVWVÝÚÓßÂÁÜÜÅÙÝÞÙÖÑÅÝÔÒÐSRÖÑWTÖRDGGOBRS]ÖÇÚÖÝÜPX_GLADMLYY@XÔÕ]PÕWÕÐÓUTÐÑUÓÓTTÒÝÖÜÆÚÒßÜVVVZOBFC@_×ÑÞÍÎÂÀÅÒÓÒÕ\]T]F@DBFSW×ßÚØÙÆÁÛØÂÀÛÛÆÁÇÃÆÛØÄßÑÒÜÕQUS[GEZ@D^^RÖ×^EGMJuuvvJHuM[XPÓÞßßÛÄßßÚÞÝÅÄÝÝÙÙßÛÇØÙÄßTUÖS[FOtvuNOGUÒÝÁÂØÝÜÝTWÕQ\VQ[_UWWÒÅÄÅÇÃÄÅÂÂÇÁÀÙÙÇÄßÜÛÒQÔÖSWÒÕPVQ_EY^EXÕÔUÐ×\FCLwswvpuOKCRR\ÕÜÐUÒÜUÔØßÜÄÀÛÚÃÃßØÃÄÓÝÜTÕÑQZ[_CKFEA_ÜÛÙÄÆÜÐÐQGYQYG^RY]×ÓÑÅÏÁÅÍÃÅÇÊÌÇÌËÂÁÈÁÓÛÅUPÖÐÕ×ÜÖPUUYFXZF[WP_SSAIOwrvuqqOACYTWQÐÜÖÐØØßØÅÙÛÌÊÉÃÃÅÝÙÅÒÕÑÖVQV^GFCKKG^QÒÝÖÖÜßÖQ\XFZ\_RÔÖ×ÓÞÄÇÉõÂÁÏÈÉÊÈÁÃÎÌÆÅØÒÕWVPÕÑÒÒÖ×WQVSXD[^_]]\QQ^@OItuwvuHLD_]\PÕVSWTUÐÝÝßÄÃÈÎÇÚÜÓÓÖÖÖÒÓÖÔVSPSYD[ZEVÔÕÐÙßÐÕURY^E@E_QWÐßÜØÀÍÁÁÎÌÂÎÉÌÎ÷ÈÇÇÅÐÐÝÑU×ÓÖÑÛÞÖÑßÔ_R]ZFFABE_AICAutOJvuINC\\ZPÔ^XTÐ×ÐØÛÄÈõÌÀÏÍÜØÄÜÓÜßÕÕÝÔRPTDBY[BXVRVßÙWSÕ]FDYEZÕÕVÒÄÙÓÚÏÚÅÊõÉ÷ñÊÎöÎÜÜØÔ_QÕPUÜÑ×ØÅÐTÑÕZDXANF[@A_DHMFKwCGJBYZERPFF^XFS×QTØÇÞÅÈÏÇÁÌÄÚÂÚÖÝÙÕWÛÆÝÓÝWEZZBZWPSÖÞÐÕÕV[ZYAGRV\WÙÜ×ÓÛØÜÆÁÇÎôËÏÈÌÞÙÆß×ÒÓSSÖÖÑÛÆØßÞÑ][DOK@FLBDCHIItu@@uOZGF^^GDYZZVÐ×ÓÆÆÙÁËÎÌÎÎÂÎõÁÝÒÓUTÝÝÑÖ×_GZZBGP][QÖVRW]GYR^[VTRTßÐÖÝÞÚØÁÌÉõ÷õÏÌÌÄÚÛÝÕÕÕR_]QVÐÒ×ÖÐTY[DA@ZXZDYZMLMCCDYEF[^_YY@FDCCE\]VÓØÙÅÆÃÍÁÆÁÁÚÒÐÖTUÑÙßßÙßÔP]PPQÕÕÐÑÖÕUVRPV]YX\YZQÔUWÐÜßßÜÛÇÌÁÁÂÎÀÄÃÌÄÞÒÖS^]]QÖÒÐÜÝ×P\FMGDCMEDML@@@F@CMMOI@DAOA^DZQ×WÖÛÙÙÆÌÂÌÏÌÂÌÂÚÓÐÔSVÒÞÑÑÜÓPPWÕWÕWÕ×URRU]YPU]^VW^\T×TÔØÅÄÆÍÀÈôÏÃÊÌÝßÆÛUÑÞÖ]PQ\\TTTWS[G^ZCDR[@XRF@Y\[XQ_FCBLA@LNGYGZT×WÓÅÀØÁÍÃÆÄÇÙÛÞ×UÔVSÕÛßÒÙÛUSTÖUTÐÐÑÔÐÔÐÓTPUV[[WÕ]QÒÒ×ÝÛØßÙØÄÆÇÃÂÎØÝÅÁÙÒÞÚÖ\VÔTSQPQ\XGZDCLD[AZRQ^PUU_Y^DHtuuJuHFYZZRÓÖÔÞÀÅØÆÀÆÅÆÁÂÄÙÓÒÐTÕÜÛÞÙÇÅ×ÕÖ×\SÔÑÕÕÔÔÓÑ×TÕ^Z\VR]PÖÑWÐßÜÓÞÇÍÀÂÌÉÀÜÒÅÀßÛÆÄÓÕWW\[ZEAIJOCINMGE^SÕV]×ÓT_\_XMOMCOLAY[A_ÖÓÔÜÚÁÞÝØÅßßØÅÅÒÒÞÜWWÓÄÛÜÚÅÑÕÕUÔTÓØÅÛÙÚÀØÖÖÖRE]WV\QÔÕRPTÔÔÕÔÐØÙßØÄÞÑßÃÛÜßÅÚÒ×ÑÐWRRRZLLFMuN_TQTÞÅ×UÖÕZCFEBuu@BtuODA[WÖÕÐØÅØÐÝÆÆÛÄÃÌÆÛÅÀØÑßÄÅÓÐÞÛÔRPÔUQÕÇÙÐØÀÞRSÕUDDSU\^VÖTPÐÄÅÓÒÇÂÒÖÅÁÜÞÁÃØØÁÂÚÓÓÒÑS[YDHtKKwsK[[YUØÛÞÒUWQ^[ZXMIC@uwM[[YUÖÐÓÙÜÝßÜÜÚÞÑÓÚÇÓÖÞÇÒÒÜÞÔÑÔÜÓVVÓÛÝÐÂôÀÙÄÁVXQÐS@YÕQDF_ÔS\ÑÇÜÔÒÇÖZVÚÛÕØÏÆÝÅÏÁÝÚÁÇÒQRS^LIBOJJF\]ÔÛÀÛUSY_EBNABwqutrpFY@FÕÞÕSÑÚÞÝÁõÈØßÎÉÐÖÃÈÞÑÛÆÖÕØÅÕR×ÝÑVÑÚÅÞß×T_[^_^Y_^ZAAG\×ÜßÛÌÀÜ×ßÞÖÓÈËÇÛõõÛÑÇÎßÔÒßSAGS@qwCBwuXP[SÜÒZB^QFBRWGHHNHtL[[[PÔÕWTÔ×ÝÄÂÄÇÂÇÝÐÛÇÞÚÂÙWÕÚÞWQÒÒVVÚÍÄÞÃÎÜPÑÛÔYPÐWZXSGtLSQXSÝÞS_TÓÔÖÁÈÂÚÍôÍÙØÚÚÄÚÜÝßÓUPS_FFY\YD\ÖVYXRY@ODFutBtxKNvJRPADT×R]ØÎÇßÏðõÇÄÏÍÝÞÌÃÓÑÄØUUÒÐUUÔÖÖÓÐÕT]\WÔ×Ô×Q\][G[RPY_ÖÐ×ÓÄß×ØËÉÃËðõÌÊõÌÛßÁÅQ_ÔÑ[ND^@K^×_B^WYIFR]Y^R\YDFFOJCZD@D_^[^R]QÑßÜØÙßØÅÞTUÚÚ×ÑÚßUWÐÓP]ÓÆÛÖÒÃÆÕUÚÛÑÓÆÚÔPÓÓYG\PRY[_ZABDXE\ÒÆÇÆÈôôôõÎÂÂÂÇÇÇÛÓÒÜÕ]VÑÕSVÐ×^E_XACX]@KOAw|sJutO[DA[^_^_WÜÛÄÂÉÊÊÊÊËÌÈËÏÀÁØÜÑÐÕ]WÕPRÕUS^YZDEP×××ÕÒÑRYQWPRÕÕR_VQXXQÖÒÃÈõÊõôËÈÈËÉÀØØÜÓVR\ABDR^^TÑP_]P\_PP_^]\\GCCFZ^SP\[YGBCYRVÔÒßÜÙÜÒÓÒÑÜÚÆÄÅÄÙÑUUUÐ×UÔßÝ×ÐÞÒWÑØÚÒØÃÄÖVVR^_VRYDZGLtJBO@SÜÛÆÎËÃÃÏËÊÊËÌÀÇÛÑ×ÖÕVT×ÖÓÐÑWQ]]RÕREZ^DHKuvpwKNOD[ZFLMDYYÐØÅÅÍÈÀÅÌôÎÉô÷õËÍÆÒÔÖUÔWS]Q\ZE^^_RWWUÝÜÒÕÕ\]QT]STPZFZFAXWUßÁÊôôÊÆÃÎËÍÈÈÁÝÓQED^DMG[Y_VP]_VWQT]_QT^G@CNBA@CXV^ZEZFE_S]×ÝÙÝÑÔÕØÅÛÛÃÂÀÆÁØÒØØÓ×ÐÑÖÔÔPWÐßÞÙÚÙÚÀÃÞÖÔÔPPR__YAJwvqwNCGRÜÛÄÆÀÃÌÈÈÊôöõÃÅÝTWTP^]U×ÑÑÖÔÔVSWQYD\^@JIuvspqwuKNB@G_SVTÓÚÛÞÛÅÇÀÎÊÉÊÊõÎÈÁÛÚÚÓÔÑÐÕPQ]XX]RWPTÑßß×ÑÜÝQUÝÓTÔÔR@MFB@C[R×ÐÞÇÍÇÀÈÈÂÍÊÉÇÞßV]XEOB[DZ]T]RÕÖPWÔÐ×ÔUS]^[A@HuJBKwOXDO[]\ZQUUVÑÙÄÆÚÇÍÌÛÄÃÃÙØÅØÑØÁÛÒÖÑWUTÕTÜØØÚÂÆÒÒÝ×]PP_FAOINJwH@MFSÓÑßÂôÈËöñõÈõÊÏØØÝÐPYYQXDRWRXPQ_[RRYZ[F@CBCHuwwqttHC[[STWÖÓÓÐÄÆÀÃôËÂÎõËÃÍÂÃÙÝÞÙÖÑÖÔP__^\^PÖÞÓØÀÂßÅÀÚÒ××PXDYZAMFFAF^QÕÑÛÈÊÊËôÌÅÛÚÒÑÕW\X^GGGXE^SVQÕÑßÝÑÓÐÑTWRSZGFMwqtutwNB@LEY[D\ÔÑÑÜÀÃÆÄÉËÌÆÏÎÁÄÌËÀÛÙÇÙÜÑÖ×UTÑÒÜÞØÆÄÙÐßÜÖ][@MJuOOKuCDZGRÑÜÙÏðòñöñôÍÇÃÁÜVTÑVX\QSYYWP^ZSWSZXS]ZDZEAILKwqtKLOLD^XG_VV]UØÇÚÂõõÍÂõôÌÄÃÍÁßÅÆÙÔÔßÓS_T×PRÝÚÜÑÛÆØÒßÅÞVX^Y@HM@CLAE[YRÖÒÙÇÈ÷ôÉÃÌÀÝÔÓÒWRQTP^WÑ×UÔÒÐUTÜßÑVUÔRD^Q[LLAOqqKKqqI@LJOFFAXTÐÜØÃÉÈÎÎÉÏÍÌËÏÏÎÎÂÅØÛÚÝTÔÒÒTÕÛÆØÓØÚÓPTÑQD@ZENuIOutCXDDQßßÞÌñðÊÊ÷ÈÅÒÛÚÜÐÓßÓ×TÓßÖTÕÑÔQWWS_^R\XFEDNHHIuqwKHwtDYDO[S_^WÆÍÍÏ÷ñÎÍÈÉÁÛÃÍÁÅÛÚÐ×ÐÓÔ]PWP]SÑßÜÐÒÞÐ×UÑÓP\\SXABAECMGYSRTÜÛÛÁõËÂÅØØÖÑÒÖÔT×TPRTÝÑÖÐÞÛÑÐÝß×VUWQ_]SYEBIOIJttvuKtttHOH@^×ÝÛÃÏÊÃÁÃÌËÂÃÈ÷ËÁÌÂÂÚÞØÜÜ×ÕÑÐÝÝßÐÑÒWRPUWXXRWXLCCCJuOBFDPÒÅÆÀÊËÊËÃÇÛÁÛÝßÛÇÑTÕ×ÖPQÔÐÑQVWT]ZXY[ACGEZOOMC@INNOMNMCEEF[SÓÝÝÅÉ÷ÏÀÏÈÏÚÇÂÃØÒØÙÙÐÑÓ×ÑTRRQÖTÔÑÜÞÕÕÔÜÒUÐßÚÐPPS]AMF[XD_TÒÝÐÛÄÄÞÑÓÒÝÔÕÓÝÜÕV]]WRQÕÙÙ×ÐÙÚÑPÕÔV[E_\\D[^[AKHJuqqtuONIB@Z[RÖÙÂÁÀÏõôÊõôöôÃÃÍÉÁÙÇÆÛÔUÒÝÑWÖÐÓ×QP]R\[\PTP[ZE[NICFEAZPÓÜÝÀËõÍÇÁÃÂÛØÆÀÁÒÓÑÔVYQÕÕVV×ÔÕV]^EZFC@D[FFX\[MBC@OwJCZBOEY\XPßÆÀÀËÊÊËõ÷õÊÌÄÅÙÛÞÓÐÓßÔU×ÓÝWSUÜÐPÕÓÐPSÐÐÖQSVR\ZXXXE@Z]WÖÐÒØÇÄÙÜÞÅÜÒØÄÇÓ×Ö×VXSÑÒÔTÓÞß×Õ×T]ZX_YY^S_^]_[@@MwvuLJtHFYDDQßÞÖÝÂõÊÊðòöÊÉËÂÅÞØÛÞÙÞÙÙÅÅÓÕUÝßWSPÔP[^QTYFX^AKCYZCC_PSP×ÜÞÄÅÛÚÆÍÀÀÀÃÌÆÚÞÞÒSVÔ×Q^SUTXE]P\@CYYYEY_XZZ^EALNNJHLBAXS^YVÛÀÝßÍôÊÎôð÷ÏÁÀÆÜÕÕßÓ×UÓßÞÜÑÕUÖÔWV×Ó×PTÑÒT]]]ZOBZ^ZDRÔÕ]\UÑÖUÖÙÅÆÁÀÇÄÆÅßÑÓ×R^QUWPÕÖÕ^XSÕW[YVVRY_PR^X[FFNtttJuKM[ZAZ\ÖßÒßÄÎÏÇÌöóôÎÊ÷ÎØÜÅØÓ×ÜÛØßÒÝÓÖTTÕ×ÐURSWÔPXZ\YJuG_D@_TT\RÑÞÝÐÝÄÁÆÅÇÂÌÆÚÅÙÞ×]^SWSRPPW^@F^^AXUÐW_PÔUYGZZFNJMFBICCBCAADSTTÖØÂÀÄÃÈ÷ÉÌÏËÎØßÚÃÅÓÝÙØÝ×ÒßÝ×ÑÞÇÚÒÝÝÑÕQR\\^CIB[FCZ^W_[WÒÓVPÐÚßÒÆÎÏÃÁÂÆÚÜÕQTÕVPVÕT^D[_\Y]VÖT\RVVX@G[GItHMNtK@F@BAYQPWÒÛÆÀÍËÊôËÉÎÉÉÆÚÄÍÁÝÓÙØÓÔÔÒØÝÑßÛÛÔWTUS[X]RDAEDZDAZ\S^_PÕÑUÔÐØÅÙÅÂÏÃÙÙÛÚÐT×Ñ×RRQTQ[XY]]YPUÑÕSTÔUS_YEAIKHNMNO@EDOME\X^ÕØÂÂÀÉôõÌÍÌÃÄÜÛÆÆÚØÛØØÜÐÑßØÐÖßÅÅÓÕÔÖVXEX\Z@FY]YXRTWX[RPP^]UÐÓÒÞÇÁÚßÙÛÛßÒÓÐ×S\RÕÕR]WÔWRUÝÝÔVÔÕTR^^E@HKLLIJN@EZ@D[_^[]ÐÅÚØÀõôÏÌÈËÂÛÅÁÁÚßÚÄÚÞßÛÙßÖUÖÓÝÔWTÕWXGZ^EBG\W]\×ÑT__RSRX\UÝÒÖÞÇÃÚÜÞÙÙÓÔÖÐ×]_STQ_RWÖ×WÔÜÛÐWÖÐÔYEYXANMFEGBAG@CCFE^[D^ÕÜÑÑÞÀÏÆÇÍÈÏÄÇÃÌÆÛÆÍÂÄÄÀÆÛÓÑÐÝÜÑÖÜÜÖ]ZD[E@C[PS\PÔTYDY_DOGRTQRÖÙØÝÒÙØØÞÝÝÝÜÑUÔÐÓÑ×ÖÒÖVTÓÒUSWÓÕXAXYZAGXY[FGGFAAZY^^^SWÕ×ÔÜÄÂÃÃÏõÊÀÆÂËÌÚÛÁÆÞÞÄÛÝUUÖ×UQWÐ×Q\\_^^X\QWÕ]STÕQ]PVVX[]P\[QÓÜÐUÑÝÐWWÑÓÑÕ×ÓÒÝÖÕ×ÔÑ××ÑÐÖVÔÑÖSZ\RPY^VWRDDGACCFDGFFEE[^\ÕÜÛÅÇÃÃÀÅÇËôÈÂÎÈÈÂÛÁÃÅÜÒÙÓÖÕWÖUP]\\\_X^QV\Y\_]_Z]WPYDY]\^QÜÛÜÐÞØÒ×ÔÒØßÑÐÙÜÐTVÔÔÕVWWRSY]VQSX_SP\\TÖQEDY^[GZ_^EBEYYYRÖßÅÛÚÁÆÄÞÙÇÏÌÅÅÀÆØÒÙÅÛßÔÐÝÖUWÔÕTSQÕTTVÕÖÑURQÔUS^]R\@MFDEFXÕ×TSQÑ×Õ×ÝÇÅÝÝÞßÓTTÑÒÓÓÑÐÑU\]PSQSPTTQPWÔU_D^^DOCG@IuICDZ_UÜÚÙÙÇÁÀÄÀÎËËÍÂÍÍÀÞÛÁÇÙÓßÙÐQRÕÕS_RP]][_RPW]TÕWS^^ZDABG^SSSÔÝÐWWÒÜÓÓØÄÄÅÝßßÐÕWÑÑ×ÔUÕPYGE_Y^]QTÐ×V×ÐÓÕWWUQEAF@MNNFXEZQÖÖ××ßÙÛÛÙÇÆÇÅÅÇÇÅÙÛÁÆÁÛÙÚÞÐTÕÑÔTW×ÐÐWWÓÓÖUÔÔV^DGMCLIAZ[X^SVWQPUÒÞßØÃÃÚÞÙÚÄÝÐÙßÝÝÑ×ÔQYY\\\XRVQQRTÖ×ÐTVV\GNOIIHOAE[G\TUÑÔÙÅÆÀÅÍÏÌÁÇÃÀÃÀÁÄØÛÒÓÓÖURQÕTVPVTTVRÕÐÑÔ×ÓU]EZEFF@[\SRRUTÕÕ×ÜÞßÒÙÄÛØÐÑÐÖ×ÔÖÓÐTQWV]Y_\\RSQÔÔÖÔÓÞÙÙÖÒÖPYGZDABO@AAMG^^XYUßÞÞÜÛÛÛØÝÄÁÆÇÇÂÆÆÙÞÙÓÑUÖÖÕÖWUÝÖÐÜÐÝØÖ×ÒVSFCAMMHNBAFCYSRPTÐÙÚÙÚÀÄÚÞÙÛØÞÑÜÙÓÖT×ÖWS\SRQ]]WTÔVWÖUUQU\\\GDMACIFFC@G_]RQÓÞÜÛÅÄÃÇÅÇÃÍÌÆÛÅßÙÑÐUÕU^\VSTRQ×ÖUÕßÓÝÒÖÒÕVR\]^DCFDEXXPPRVVÔÓÞßÒÙÙÛÒÖÞÓÑÔÖÜ×ÕQÕÕWV\TUUWTßÓßÒÝÙÓÑÔÕTPSX[^ZALLKIHNDGDY_TÐÝÓßÛØØØÁÃÁÀÍÎÀÆÅßØÜÝÑVÑU×ÕÑÜÒßÐÓßÓÐWÔV_[GD@NHHBIBAXRRTWÑÞØÛÜÇÆÆÇÛÁÇÜÐÐÞßÐÔÕÒQR]QÕ\VVÕÐUÖÕÖUÕU]Q__^X]X^@GDAGF]WWVQÖÝÝÓÞÆÅÚßÙÆØÇÚÚÄßÞ×ÑÔPQSÕWWÑ×ÜßÙÒÒÙÞÓÔ×ÑTU]R\DAOFBB[EPRVTTÓÐÐÓÐÜßÒÑÒÜÐÑUÝÐÔÔWÔÑTTWÜPÐÄÒÁWÞÝÑØÕW_P\\YFYYDBHBBNMG][__UÔÖÐ×ÆÚÀÅÞÄÀÌÀÇÌÁÄØÜÙÐ×QÕÐÑÜÓßÜÞÜÒÛÝÔR\DQSY[A@IuHH@FE]VVÕÑÝßßÓÞÀÅÄÅØÅÚÙÓÞÅÙÐTÔÕWVR××UTWÖÖWVWÔV\ZE^G[ZX\[GMAD\^YÖÐÖÕÔÞÜÓÐÙÅÞßÝÛÄÚÞÙØÜÓ×T×VPPSÖ×ÓÖÓßÝÞÓÞÙÓÖVVWQSPV\XGCEDD[]TWTVW×UUQU×Õ×TÑÓÓÓ×ÜÞÐÔÔÐ×TUÓØÜÒÒØÆØÓÐÜÐVP_R\\X[Y@CKHAOLAYP\YYPÕWWÔÙÙÝÙØÀÀÁÀÂÍÅØÞÚÞ×ÒÐÝØÞßÒßÙÞÓÖÜÖSYE^ZGDEE@MLFFF^]QVQWWÖÐÒÑÝÛßØÜÛÁÄÇÅÀÀÄÙÖÓÕQWVÖ×VPVÕVRRQV\^X^R\Y[XXZD[]RPPV×TVQWÐÖÖÒÙÛÝÜÜØÚßßÞØßÐ×U×VWWTÐ×ÖÑÐÒÐÓÑßÙÐÖTÑÖVPPÕS]__SXYX[_ZY^]R^]^PQQÔÕÒÞÜÜØÁÇØÝÜÞÐÖÓÚÄØÛØÙÒ×ÐÔÓÑTWSQ[DFBANLNMFCC@ZX_\]UQTÕÑßÞÙØÇÁÁÍÁÌÎÁÂÇÁÁØßÜßÒÐÖTÐUWWRWS]X[[AFCEZE[[]YZZZ]X\PWÑÑÒÒÜÛÞØÞÄÀÅÆÅÁÇÚÞÓÒTVPSÕQRSPQSPRTQRQYR]XYE__^X\V__]PWPTUÔÔTÑÔÑÝÑÑÐÐ×ÖÖÖÓÔ××ÑÒÐÒÐÜßÝÐ×ÐÓÐÝÜØØÞÝÒÓTTPPQ]R^^ZGAL@BLBB[^^^]TTTW×ÜÝÞÙÅÀÆÆÆÀÁÇÆÇÆÄÚØÝØÜÐÐÐÐUW_]REABMNINuKuKHMEDYY\WWÕ×ÝØÙÚÚÆÌÂÀÁÌÃÀÁÚÇÄÄÛÓÓ×UVQUTVSÕÕQS^RRXGAXX[DFEDGFE_^\QÑÒÒÜÒÚÚÛÛÙÄÇÛÙÙÅÅØÜßÝÑÖVPSRPSVTVVWÕVRSPVPSYXPRYZ^\XXZYY]TWÔÐÖ××Ó×Ó××ÜÐÓÖÐÑÞÕÔÐÓÓ×ÖÐÝÐÐÐØßÞÚÀÄÄÃØÙßÜQ^S]^DDZFBLOBL@G[RPQSÕU×Ô×ßÓÞÞØÃÁÇÅÅÇÆÚØÅÆÛÙßÝÖÜÙÃÉÅPÝ_YTN@MLANwNL[HuLAAR_^ÖRÓTØÜSÆÀÆÚÆßÜÝÒÂÐÐÚÂÜÜÐßß×VVØVÐÝSÕÞWYUP[GC_ÔE@]XBX@UÞQVÁÁÅÁÚÍÌÜÞÇÚÍÛÁÍÌÙÆÛÒÅÔQÄÒQTXV^\_ßÖRÃÔWQSÑZ_^_JVZp\q[tFÖPU\Q^ÜÖVÝ[ÕØTTQÙWÕQTUUUØÑÖÚßWÚÅSØÇËÙÄõÊßÅôÞUÕÒ×Õ\]IACtDrB[^wAVCGRÔwÓÀEÑÃÛÀ
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_g711mulaw_1ch_8khz.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_g711mulaw_1ch_8khz.info
new file mode 100644
index 0000000..f00b9cd
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_g711mulaw_1ch_8khz.info
@@ -0,0 +1,10 @@
+8192 1 0
+8192 1 1024000
+8192 1 2048000
+8192 1 3072000
+8192 1 4096000
+8192 1 5120000
+8192 1 6144000
+8192 1 7168000
+8192 1 8192000
+5462 1 9216000
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_g711mulaw_1ch_8khz.raw b/media/codec2/hidl/1.0/vts/functional/res/bbb_g711mulaw_1ch_8khz.raw
new file mode 100644
index 0000000..f38f1ca
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_g711mulaw_1ch_8khz.raw
@@ -0,0 +1 @@
+?CK^åæêý\X`ZTjòþ]X[PS\[koãÜåÙÚÚÜê]TZ`p|ÕÏåèäø{çÏÄÄÇÑþ^MFSëÐÅÁÀÉãiUKKfÚÍÈÈÈÍäl^^\QMhv]ëÙ×ÕtXOBEV}ÌÅÌÐîH@<=JXÏÀÃÊËá[KEQZMYiiìmjéåûÞÞéãjõ÷OMQKWpéÏÍÑÉÏ}eMUdR^àÛÝôkìk[àʾÊÜ\?9:?YÏÀ¹¼ËåYFAE_ÏÌÊÄÌêaMQOFVáÍÇËÉÀÎhWNO[`ÚÑÛÐÚoWKI[lïÎÈÇÍàãwMR}â|^V]VHLWóÙãØÌê_`c\TMXZOUKJSU^ý`WpîîdWîß]]_WYhàÎËÍÎÚêUAIêÎÇÀ¿ÅÓhMFJîÌÀ¼¾ÀÃÏkOLOR\ÙËÌÀ¼¿ÆêUNJJJOæÒêt_LJN^çßØ×÷bWHCMbÝÍÑÜçlSFDaÖÍËÏïcJAEFLhßÌÍwc]TRRLWmêälféø]VIPôØÎÇËÖpQQHCVÖŽÅÏÚfLB?Lî̼»¾¿ÂÓþVU`féØÖßÝæØ×îiåásQNpòîÞÞ}îryütþÝÝÝÿXdgxÙÏßoW\TGK~ÌÄËäû]H?BGPYáÎÝqc`XOGILOPNJKJR_LJRòÛçþØÙô_QKKKdËÁ¼ºº¼É`S^µ¸¾ÅüOR[ÚÌÛÖÒðçéâ×r[nWJKNjæbU\Yiz_ljUXTIRgßÈÏ×ÑqSRHMT^ÍÁÈËØmZ?9?LêÉÊÎßWJC?Ha÷ÕÕq^UMQOGKHSëíãËÌËÜOMQaÒÌÍÆÑê}TQ]ùÌÂÀ¾ÆÊÉÏéluæØÙàã×ÓÕêôßÞÞáfOKJUfêÔÐÊÁËålhí{_XS^òjeîÝÝzOF?E_íÐÍá^LA<8>Uøéî_X^QLGMZeuÞÓÒÏÕsXPMbßÌÉÌÑÎàþó[uÖØÞäÙÈÑóoOGLVßÅÅÃÉÖnLIgÜÎÊÏóegl}äȽ¾ËÛh[TLRzåÎÆ¿¼ÇÒÕuNIG]ßÕÏæ\UG@@=FYøðylûRB?>>?IbßáínqLDBSçÙÑÎÜcZPTTjÒËÛÝáÒËÒÌÌ×ûfgåþÞÉÅÈÜd`f]÷øãàèïîq~ñïn[[`nmo~lbtéÏÎßÜßfSJ]Íž»¾ÃË×ÎÑ×ÌËÊÌÐÉÂÈÎéP@=FhÝÎÄÂÖK;69<?KUOLC=:6:CIWzýödRI><AMpâÙÑÒÙ]LMVfïâÜúYZ\mããÙËÎÖåîéyXRJM}ÔÍÎÎËÍu\\rØȾ¼ÃàbUPSüͽ½ÄÇÌÌÇÊÙáþÖÌÉÀ¼¾ÃÎàØâèæçrjVpáîîhWSNGFDN^[UOC>@HWl~bNA?<=G]aSJLmçÜßýzwTcúìßÝÞlP^ä÷èØ×ÓÐÕÙhaöÕÊÍÚÛÏà^XnúzçÎÉÈÆÍeIEFfÍ¿º¹º¾ÒÜãcóÌÅÀÆÈÄÙtrsßØutåÞèæàíK@FLRWgWOGB@CERddYLR[J@LNUU\t\QeqbZIL_àéæãÜdRYnÔžÈßkwqíìáÜßàêÜÏÎáÜðSEH]ëÝËÄÅÈÞ_RVT\hæåÜÌÈÌÍÌ×ðÛÇÃÀ½¼ÂÓm\mÞÙééàèsêæv]gYMLLOORQICGLPUNN[SB87?EOtØÐÔîe[]lç×ÍÖðÚßuhecøÚÍËßóé]LDANlméÎÍÕfOSFARi}âìÚÇÉËÎzúåæĽ¼¶¸ÁÎáÜÊÍËÁÌÏÓùãßûìÕÝîYNfk]p^YcSVcUOPC?>>RbYn^NONZnUJMJP\]ÙÎàvc^jøØÏÔÛäiaXK]ëØÏÕåôd[÷ùbpî|û{åØÖuOKWW_ØÓÐËÈÅÉëbVU]{ÜÍÌÍÓÜ×ãßÍÒæÐÍÐÛßø{úïÕÏÊÎÜòhOMVlí~÷éi\pWQ_yzÝñid[cPHHFFjÖÍÏäñtMIXWöÑÝàÞWGJLJMMQT\ñ~SD?@K_ÓÉÝÿûW_YDJt~âÕäèâÐÿÇÎâèÕÍÇÇÏÏÉÎÆÄËÈÇÝßÖö_oçÏÍÚÖÜÐÕ÷íá^ùÝéØiIOTHPRKJ\lèð^\]aURRP?IYWZ\RçêL_WJUjlÐØsWOPMYßÒÑÅÓtL@AUkÝÊÒæçÜÝÐìYXó|~ÖÎÕåödk\VaÕÕØÞg]nðÕÈÍÍÊÇÓÜÝjZçßáÑÖÒÇÈÙlOO[ÞŽ½ËdTRM_vfÞÏéêìQJMQ\`YUR[`Z`SHT]Rkj`ÚøPUH?Mc|ôh`_cîxlßj[xdYhUQb^`ø_TêÝ×ÏÞbipÞÐÐÎøféüçÆɽÈÓÝmäËÌÇÐ÷bkèÑËÄÇÔÔÿMHMNgéÙÏÌÙçÝíä}[UdêÍÌØbPXVXúìx×ßt\MJV]]TOX[_QHE?8:=?HMOSQGEEGLqÐËÍÝ]OOPú×ÛßÊÈÎÐÕÓÊÈžÃËÏÊÉÎÖÓÍÇÀþ½ÅÇÈÝðææÖÍÌÍÎâ`TXVOOS]nìÛÔqKKTZvìíØÏÙösYUmÛàaUMKMNNVMMSNKNMRUHDFKD@INIHF>>DIPSKUðÐÈÉØèçåÔÌÍÓËÁÂÈÉÉÇÀ¾¾¿ÁÇÄÀÃÊÏÐÍËÉÆÂÇÏÑå_SRMMTWefRIIPQQ]fîÛÎÍÞRDIMPYd{ßÚßçkPU_eafõsfc^XRQ[ìßèéiULCBEA=@HIFA>;;>@IKLVmÿsf\_÷ÓÆÁÄÅ¿º»º¸¸¶¶µµ´·¹¹»ÀÇËËÈÇÉÎÝ[KKV]ìÞïøûpdRGHLPU[^ûáØØãtSUzìþíwg|òìÛíb^UQOOLLJJIGFFNmmfgRKJHJRHDFBBA>?ADKRUV`ráîììl÷ÞÕÏÌÕÓÉËÎÌÌÄ¿»¸¹¼½ÂÀÀ¿½¾»º¼¾ÌéüçæáÙÜÕ×ÑÏîZSVnßÕ×ÏÓßß|x_U]m_Z\RNMLKEACDKLHD>:9>BGJLNJDA>=AP_rwgj÷ïþjbe{ÔÌÍØääÞæàÔÓÖÔÕÛÝêõîÙÜØÒÒÒÑÊÉÍØÞÝÙÒÊÇÇÆÁ¿¾ÂÐÏÉÅÊÍÍÍÍÈÁÃËÕÓËÊÌËÓÕÛÞà}SE@>>@EC?>?@>9:>AB?>;;=CR^W`r{úmUNLSkúípnöxukWV_îÏËØäÛÒÎÌÉËÏÐÎÄÀÇÐæî÷sôûê×ÍËÐ{ZehÝÊÈÅÊÏÎÚóedéÙÕÍÉÍÑÕÒÐÙ×ÖÎÄÃÀÆÐÔÜÜâlZMKNOQUKHRNVULPKDA=<869<?ECFIEEFCFIYûìàcZfWhíflòäÍËÓÖÚÕØÙÒëtÜÐÉÆÎÔÔÖÐÊÈËÐÌÏÎËÖÚÒ×ÎÃÄÄÂÀ¾ÅÕfNnáÖÅÌÝÝõzä{öÒÌÇÆÇÉÛÜçijWLRWV_[I?=BKZTGHB<><<@EOOMIADJGIJAEPRdbSSLLLNRTxÕÌÈÍézêÞÑÌÌÐÞÖÕØÒëæÕÎÁ¾ÇÑ×ÛÜÛÙÜÖÉÆÇÁÎÞÐÎÎÓÚÜÝ×ÜáÙÞçÓÍÍËÓØÎÌÅÀÇ×mw~iörVWTOZZPQYdXI?:<<;?<78:=CGIIJLFGJFWãâÝêwö÷tøü^\vÞÑÎÙl][VnçÜÞßÚêxkdüÓÊÄÇÒÏËËÆÊÐËÊÆÅÁÀÈÊÊÎ×ßåáÒÎÊÍÙà`höÚÐÛÐÎÏÊÓ÷hqèìõl]JHEDNJJOSe[KIGHIIHIJMOP\PLU[ol^VLX\TWYUNKN]YUY]|÷^QL]ìæÕÙùipìÑËÐÚÛÒÔàÝÙÎÆÉÊÌÒÐÒÌÀ¼¾ÉÇÈËÌÎÓξ¾¼»½ÀÌÊÉËÍÝÚÚàåYHFRQRZKE<<=@I??GLWJOO[fOLABFL[iæ[UWIRMPXlÝèìaPGH^ùØïjüXfXNRVtuÜß`WShnäßÜÍÏÉÉÌÇÍÆÇÇÅËÊÌÊÆÀÄÈÅËÈÊÏÊÓÏÎÎÍârlÛÇÃÄÉÐ}QPRmdb{m]B:7<KR``VVNLILPNRVcZLKMre[^QVOORcp_ñãÚå_WOøÝÚßhiQLIMd\gnïãhVNúÛÜÓæÞ|]}òÎÏÖÏÏÍÞáëÑÇÇÃËÉÉ×ÙÝÊÅÇÆÈÄÌÚéÙÅÀ¾ÇÌÔzùxíéùòpðjNE@EHMIL[QOLXbWRLVZLEAFNZOKNGGJRgwáûmjTQNlÖÍÏwcUIIQ~ñõfbø[TNZßÛÔÛàÝëèâÑÍÊÇËÉÌÌÐØÉÇÂÂÈÈÍËÌÅÂÊÊÎÎÖänbÕÏÑÏêøbiipÙâååuYSL@IU_átZQNOUïýedTKHHAKcZ_VF@?ABTa]j[TUXO[ÞÙÔØt]]`S]bUoìîñýUMY^ÛÇÊÍÔátè×åÚÓ×ÓÑÝsÔÊÆ¿ÆÏÎÊËÆ¿ÆÅÄÎ×ÛØãÏÉÑÌÝXPPOYÝÙÚÓóe_VHIYWïâa`XLFPZUþõknnWLRNXeNLKIFFJGOa\ZVNGZpöÙscXOKJ`[_bSQNNGPmâÈÊÓÙ×ÒÒÃÂÅÄÍÒÞßýïÏËÅÈÅ¿¿¾Ä¿¿ÆÃÇÈÎÔæqßØÎÐèhTSMTryæõ}_PIAM_âÕÛãg_STcb_`]]WWNPbrýa_VTLDGHHHLNUVLMeõåõdTHFFO]VUfj_[[[áÌÇÁÇÑáà}øÖÎÏÏÓàó`OaÝÚÎÄ¿ÅÅÉËÅÉËÇÀÂÇÆÔÚÎÐÒè_IJNL`òtfíÜçæ\Xéððþè`R[Qc}üëâÙ_WPHSTe{ù`ILCCHIMMda[RFM\þâàæZ_XZhVOLW]OMFN[`éãÓåáÙÝÎÎÎÌÍË×ândìèÏÏËÌÎÊÎÆÃÃÆÿÁÊÔåÜà×ÞmWDKJQZlïçÙÓÙýlòÓÊÌ×ÏïeOOZeo[ugODBAGTiatXMLLNPhVeôúZOKM`ø\bhUYYn\q[`îpWMSWlÖÛæåe__ïñÌÄÎÍÝû_^tàÇÄÌËÛqcÝÑÎÅÌÃÃÌÜã×ÓÆÁÍÓ{TLQ]WßÝÛÞx\Vþì×ÇÎØëRHH]oáÚÝßnTL[^lãçÿ^KGIWZcñö{VG>?AMxôlWJEH\ðâÝßì\J@J[öÒÕÔêRDCVäÍÃÄÄÒò`qðæÈ¿¿È×úhçÒȾ¾»»ÂÒçßÛËÈÌ×iMEJXgáÚÞä[PP_úÚÈÈÕwSLKYëÙÚ_OFCACNdÖÎéYH?=BUgéú÷lOF>HYéÏÝnVRURëÐÅÆÐÚçêenæÙÎÙmVNLH_ÚÕÖÝßìò÷è×ÎÇÆÖjXbblØÐÊÍÕÒÒÙëÝÉÈËíTONQVÜÊËÔçäï|îæÐÓÏÔcTOW\êÖÜì\^_[\Yç×ÝîNJEDFMae`\YRJHN\^UbSKGK\yêåèq``nøóçéòî^QMO\ëÏÒàvktnsÙÈÄÆÇÍác_äÔÉÊÉÊÔÛØÕÏÉÅÈÐÝù_NSWéÓÝáìÜÚÝØÏÌÖæßæaMVYgjMONPQPadõão`UMFMQTïdSMKQLWfê×fZcXKK_r×ÚúùamîÏÊÒËÖêhOKKYY{ácXR^nþÙÔÅÊàïmb`ðÞÖÍÔßøøåÔÌÎËËÖßñð|èÞÕÉÍábnâÖÐÍÇÇÒëkl[aîÜÒâhOILXëÖÊË×gGAAFTWb]NB=DO`ôññfOKNZS_pòð^OGMhî×ÙáÜæi[c`öénv_VKOúÛÊÅÅÇÑëøÛÔÐÆÅÃÊÞj^íÚÈÂÈËÐál`edéààëbPJU÷ÐÉÍÏÛ~_]üýßÝñùUJHMfçÑÕÝø^YR[dksZVMEACNdã}ee`kméàèäîégONPgìÒËÌÐáÿfdmöäxeTHDCMýÎÊÌÕìg[]õßÛÞ×á[NNdòÕËËËÒ×ÍÏÍÊÈÊÎÔÞäèáÔËÎä~þeg÷ÝÍÍÚîõZLMQkß×ÙÙèYW_U\baSMD;<?CTþbX]TOVSoÞë}yiOMY_ô×ß÷ð[OmîàÒËÔöiOPYVúÑÐÞàÝÜÍÌÌÅÃÍÛÙù]qvðÓÏÛÙÔáÚÏÒÍÌÐßôfWa]YîØú\YTZ~èÔÉÍíwbMHKUðØäÜØéoõõnûüZSH??ABCV\RY]läÚÒËË×ÜÞâäõþûàêce`Zhåáìëm\PMMOOM^÷xgdnåçîÜÎÏßþp_VRV|Ö×ÜÏÌÎÍËÅÅÊÏÖÔÏÓÙßàÙßn_izíçÛÛÜîbûàëqnððtcjåíðãØÞu^OLIEECDCNWKNU\yéîìâp[dd]OQ]fmZ^peiîèzðtU\s|éèéÙÓØÝÐÍÊÉÉÄÆËÙæØöXX]pëofæàãÐÎÎÏÝÛÙ×Þìío^VUTXa\zêïÞÚïjïøjssóìyáæün÷Þãðb\WOKGLQMU_eaZ_îòcmñíéáÞàýj]WVUfùðäçï{ú\Vbb\Z]^YbíäßåÚÒÐËÍÕñéâ^XWnëìôþÞÛÖÐÑÍÒÓØÑËÕÛÖÓålmsøóg~yùðbbZ{æùêëè~éàzÞêêæïí_WOPOFILNNMPLNTVego÷îînçéos^VOQPVshùðÞÜyh`zßÞÝØÕÓÕ×âÖÍÎËÌÏ×Üâüù}÷èéßýþ~lukbhíàãèõàÜpe^Y_\^YT[bcpæíßßãÐÍÔØÛàéõpêÖÔâî}]NIKMY[Z`_WY^\\mqñðyör{ëßàøqkohYSPg`_e]a^`gmqhsecntñàÕØÕÔÞàírþáÖÙá|}áÞæßÒÍËÉÏÖÒÖÒÌÎÛèîr^XVarijôunòôóìÝÞßèh^søóêzjzjYVOKOVSPSRORRMLMUhbX\~îðÜÛßëo`acdmsqg_^nêëñâÕÖÚÛäÙÎÉÇËÎÎÐàzhelúìq^Ybt}íçÝ×Õ×ßìêïñïåÛÝçycUW]VZ\gd`víêæÚÐÒÜïçÜÓÔßé}rZVTSZag_XSQRU\dd~îôpYXjøæéÞÖí^Z_b_cmrYVVSOLNYpyêßßÜÙÖßçßááæú{èàéææëùqiæçôÞÒÏÕÏÎÐÏËÈÊÊÓãzWZ_eböñuökjmwîçØÖàííåÜãlèÞi[aWKIGKLKOOUXZ[Z[^VR\YR`òèÛÔÛü`[amlyããæõk[UW`wèÜÚÕÒ×ÓÑÔÎÍÒÔÓßë}{~jc^XZmðêïíïpfrîìä×ÓÕÔÝê{hkhu}ññèô`[Y^úßÑÉËÏÒÔØÜîêàáêq]QKHKLOQUV`[Xc\\ailyïÝÕÜënbZPR_rrümakWTVPNZ÷ÞÙãâáåæßáÝÖÔÓï^e\jîèÝÖÕÝâîûim{åßÝÓÒÏÕ×ÎÔÙáùu~êíéï~üvcbltäÝÛæõñ{æÛßòèÞßlWPMHDHLMNUYTTQRadu~êÜâyþðzçðpe_vözhùìogYdmðÔÐÑÑÝîÛåöáÝÕÏÓßåwimbltóîmaiaYfbnàèäÞãlmuõÝô|øâçûíî÷õåùkü|ëÚ×ÖÕâÛÐÔÒ×ÖÖÜæ`LLROR_lo^UOUSXbcjlú~b_YZnövh^Zec_bfk{ós_`wpcðèzõà×ÔÜàØßåçëòêíóãáØâcúovîðåêêûâùsøuâØÔØßý÷å|áí|åêíôÿkêæÝÚáÝßÞèîvþî]`XUSNMMSMSMGHHOX]eùöìÝéÜáé×Ñßüg[rhivulon][W\oøÞÞØÏÍÑÏÎÚÓÖàîwisn]tëïþaZVZtê}îïuåäñøûøßßk^YZvíðèØÍÍÝèóoñëàØÖÖÐÕßÜßëåñb^]XVOPXZZZSPRZeZRX_`hddqêâØàcZQS\_eyæãõk``fôëôéßçðóïÝÝçÖÏÔØÚãõsoçÙÝäpwÜæëðgkùúèî÷ÙÑàåü_ck~ëíâÖßîì]Ta[gêÜÏÐêìåëÝÜèäõq}WMQKKSKIKKQ\UXQMaôîâßØÍÔÜÕòel\bò÷äÜq`_Zbp|éâÜÕçëÙÛÓÌ×àÕÖ×ÚgX\[hòönjxÿmej[bjY]êÜÔÏìrlXXcnúÛÕÛæèáäÜåîçÓÎÏÔwmttêÜÝñà÷[\\X[j^YOU^]YSPOSS[acwths{g÷ïbakâÑØõcWOY[låçØÒètùïØÑÐÎÏËÉÍÞæýqóôààtlxYWvz~øh]fâÔÕåçè{eb|êèÛÒï}íkyúk_çÚÚÙì~ngkðÜÝòldOLUSZ\TV\RNQOMPXU\_loíáóéÞÛÞíooáàÝÙïba\UbzèÞÜÛèîéàÞÖÔÎÇÊÏÍØýòueijmudSUZ`kib]^xéõÞÜøåðpe^kâÞòÜÚäééáÝÕËÊÕÖÝib_ekrüú_NTTPXjwkýåíYVZMNQTPRW^]Xce]bxxpðÛÓÛØÛë~jf^ltãå}ôêþlìÙÕÎÉÊÒÚäìåÝÜÚÙÝÛíd]jb\y|b_rðõîîèþmwva_{íy~åëìßÜÝÚÚêôrZ[ZfüçæÜÔánZ][Xdzvqm_\MEILMQYY\Zamm~íæåÝáßÜæÞõlk_X\÷íáßÜãqwêâêÔÍÎÒÛÐÜûõáâèØÜÝõöm^hnÿüßâüjcn\X]habðâëo~ùrzåÚÞßÓÌÔÚÚém]fq{äÔÜöÿ_TR_gaþæöZY^PIITSN\~kUTTXZ]^]o÷õü{yh_eþseèÕÝçãäèîãÞÞÛÍÉÍÑÒÐÝåØÖØÍÍØÙìûþxóÿ}øãöf[OOMRhelÞÔÚæyñäþñæãàØ×Öäa_YV[Y_ðèþpjþþjsm^{åîîmXTMGMNWgfe^WTZho^cÜÙÜÚép~`b~hxëéíøîàßÛÜêá×ÓÌÎÚßÛæßÛáÖÏÖæíéühujVZzæãt^YOJSX[ñÙÙãðõüëÝézáÎÌÓÖ×ãofúlfþíå~påæõpYSUgzugbZSMIGJRY]TQa[X\XU]ßØÛêíjZUZ]\ùÙØõëÑ×ÚåçñëÙãØÖÕÔÓÕÝéíÏÉÍÔÖÊÍÑásgcçñýk[XNEFHMgáÙÙÚÕÛàïüyáÏÕÞÞÛínUSRPn~fdÿÛàìrbUYhdh`Y]aODBFQVS^tyiieacðØÕÐÓÞïoYPThÝÚÞÝÛÕÚÝsewë×Û×ÎÍÎÓÞzihà×ÚÓÖÍÍÐàukgýikûl[ULGKOnùëÓØÙëònijèÏÚØÓÔÙèmY^Xdûqíïßßìk]XVd]`kVVUNKLLYdY`e[RPOWYhÝàÔÏägXTNNO÷ÙåÛ×Ó×Ûìtt~Û×ÎÈËËÍ×ëø|ÛÏÍÈÊÎÏÏÙþsìÛçéðbWNIHLL]xzæèâÞÜÝåãÝÐÑØå{íeSLHJU_fðíÜÝäü]cd|öñþ`]NJEAIZ_dm[[Y\Z[ïÜÏÓÔ×Þíp]PQRgséáõÝÕÚwhÿïÜ×ÌÈÉÈËÚn__~âØÏÓÒÒÜç|ðÙÓßéçe]XMJLR`wnvgoéêðïÚÐÖàãÞíÝÜv_[\cr~àÛÚÙépZ]noywuf]MBBEJYlmtcXVSNSmåãèíëôud]^^múüq{ýqxói_gkwêÖÊÄÃÃÉÖàÝÝØÎÉÈÉÌÑæýääçêvpeZUONS[[gk_aluêëàÐÎÖÜëõ~klz^[XUcfxåßåÝü]e]W^[ho]TMHKNOe|uðyjpXYûô~èôomcii\i~k÷ëüì÷óÞùewjlãßÓÇÅÄÇÏÖáóßÖÕÍÌÐØzpêqwòmitga]Xaf^ce[Z`}ÞÚÒÌÑÔ×ßèïzxx]_[Xglþã×ÛæñýtXWfuî÷s[KGIJHP[[Z]_\X[bmkhmb]dlk{äsnþkhk{øøñxk]_|ÞÍÈ¿ÂÉÊÎåÝÕÏÇÅÅÅËÙåîyigïìöìtce_Vmp]aXTeoûßÝãéêßçéßýlr^OXW\~víÙêifXTY[zöêpQNMGHTS\geoÿtqùurëï~úïõùêîúzqamngvòûrt_ZfòçÑÉÉÆÍÏÜçÜÔÊÌÈÇÎÛðò_mjfggìz}oùînxrfQOZZkèßÝáæóìâÞÔ×Ýâxe^o{pæáêaTPOQRfpìÝàgQYSOQZaSW^ZXTYheci[S^]Q^øyliskmýçâæíqn\bøyÓÁÂÆËÌÏÌÎÎÆÄÄÇÉÏßàïppk_aü}z}xåÝòsm^X`]Ulí|^_^\{çèóõëf]YcükâÙçn[[OVYWlçâaVVQOMQY`gbgbðîøãíçtfmgk[_szbV\bfõíåæéö`dnðÞÒÇÉÌÌÒÚåÙ×ÒÎÌÎßÞåèö|öyìçðmaïíÿëîíu_UQY`iïéìööìÝØÛ×Üß}aXVîàíçæÜ{aVVrfsôìfTRMOOLPX\WWVYgd``jÿrdTUg]UY^VMX[ktíØæïegdîÎÌÊÈÄÄÉÊÌÉÈÃÅÍÍÐÛîêçìðàÝãÞáïàÚãæÿõóWMMVZSUUVX_húáâÚæhm`RUqéúrøw_\Y[p÷ýö_\XILWZVWb]ZYenòÞêäíëòa_^bebs]XXXhuçãðtb^QXýáÑÏËÇÇÇÉÅÇÆÆËÎâïick[kóüøíßöìÛÕÕÛÜçòn__YX[UVQWXjéÚÏÑÙçêý^_hkývsy{i]`ôðllcYSQUXV[TOWZXWbîðft}_dc^[WWVSUUTU`úÞßóíjbecyáÔÔÑËÆÅÅÿÂÉÇÒéÜÜèýñïzîßÙÚÛÐÎÎÚáðbofUPUPIKHMW\ñßÙàìæe^\X\^i`pðõéöríæýchUP[PUVQKLWT]mîÞÙÜñæîxãùx{[POQMP]xããßûl_PYdcñÝßØÏÎÍÆÃÃÄÃÈÌÑâÞáòêý\[õú|ÞÓÏÏÊÏØÙòýõg`]MEKGCPeâØÑÑÝÔìxðøìèï[nù\b~íóêêfl\PUVUTMGJSII_w{æÜþþöqfko^XLHKHHRjryàvhe]^säØÍÎÍÈÇÇÇÁ¿À¾¿ÈËÌÑØÓÚçíjïî|çÖÌÌÇËÔÚåvZ]_MIC@@AGQqöèÙééýinnúwp]W[RW^rîñÙébgXU[\RNPILJJVaûéÕÚáÛâñüubW_MFLKQ`zmèÝpóy^ôÞÞÛÏÕÝÍËÊÆÁÁÁ¾ÈÎÌÜçÝæyçï\`e^÷ÑËÊÆÉÐÓçhuePQQD@HJNdopäÝâäæýÝÖîæßpZ_adðâçãì^VXOOUMINKBDGIX{{äÝåú{tgf\UXOCBJJO_løâèüäêáÑÏÒÒËÏÏÇÆ¿¼»½¾ÂËÌÎÑÎÎÚâÞ÷_ejøÒÎÐÍÎßê}fxq^OIGA@BENUW`}leêïßÕâs}û`[asæÞàðvXMPOO`bPOOHFMPjäÝÝÞæigtpêßþVQOIIJMZelóèþïßÞÓÍÏÛØÏÑÏËÆÁ¾¿ÊÌÐÞÛ××ÑÖìszgWfáÓÏÎÏÔÜéyøäÝÛnSQMFFJMYm}òêéóÝÑÑÛÝäüêwiûôèäeYSTMLMORNKGFFBLalíþqkf^[aýç|]SMLBGHK\igqäêþÞÓÒÎÏËÈÇÈÅÀ¾»»ÂÅÇËÑÓÐØÚÙßæèû÷ØÒÏÊÔÞâñi`kù{fQJCA??DJgôaëâë{äÚæÜèíwa^X_þêéa]e^RPSRTTMIIMPVtçÞñðújlmèÛÞækSLIEHN_ôêzzîèàáÔÏÑËÏÚÜ×ÎÏÅÀÂÇËÌÖÝêÞÛéßófóèÝØÊÇËÍÛïvqþxêùfTFFCCK\êâÚìpÞàìßÐÑßæeZZVtíÞä~iRVLFLUQEFA=FGLgíòòòUR_eêÙÛzXODCEI^ì÷mî]ZÝÛ×ÊÅÆÉÎÜÞÐÊÀ»¼½¿ËÜÕÏÜÏÉÑõidfÝÐÌÂÂÆËê[Zff|ßþQE?=>DLpãsiVM\ãÙÔÐÑß_MKMRyãÖç|jJJMSYeoOD>=FPòÕÐÏÓßXP`çÒÒÖôXLCDGT÷ççcYNKgÞÉÆÉÆÏæemÜÊ¿¾¿ÆÍÜ_pÝÏÊÐÙtUR]êÑ¿¾¿ÃÌÝ_V}âÖÚè_LEBIN~ÖØä`\Z]ëÙËËÙðYNLLZïÛÔÝbWQHLWbnOB;9=BI`ÙÑØnY^SRïÙ×åsSGGHJ]àçüWIR_kåÏÅÆËØå×ÎÌÆ»½¾ÀÏÔÔÔÓÈÃÍÝhR]ßÕÔÀ½¾ÅÞóéäñßÖòcTD>AJK`ða^LIS`|ðÔ×éfMJQkcíàyô]MMUbvòfOI?>DTdþÓÔÕîQWtxçÔ×õtUIHOfõÜp`WFKZyãÏÍØØþeýÙÍËÁÃÊÌÙãßØÑÇÄåg\U]qÐÉ¿¿ÊËÕÞßÔÒÒÍé`SNKG[ÿÞ×c\ZVV`Ü×ÌÖubXWPùß÷âoZSQOSthwVD?;>>GZ_ñþ`[\^kÛàäÜÿRDKONqîåðYMKT^äÚÑÉÐÝußÒÏÃÂÀ¿ÀÏÜÏÑÉÆÆÄÏëY]÷çÎÆÁÆÍßêÙÝÎÌÚÙçYD?FHSfqaRJ?DJUàß×à`QMXWøØæèv_KIPVãîb_PG=@FQæáæèùebíðÎÊßØò]IJTZßáþõoQCMYïÍÒÌÒäxvÜØÊÃÄÇÎÖtzÝÙÆÈÈÍéfUaõÔÄÂÇÎÐÖÜÎÊÃÂÉÚ]UIFSeéíbRMHDM]éÖÙßj_[TjæÞØäWQQFK[kòl]KC@>DNWZYOOQN]ÿðÝÛábYVLOcpwz`OLJOjëÎËÍÏÐÏÔÍÆÃÃÂÈÓÎÖâÔÏÉÇÄËÞâyöÙÌÌÊÉÑÎÔÓÆÄÃÆÎÝ^WMGLWSNMD?@AKXhëíðl^^]yÞÞ{mgQSWWzåÞçjRDFHIZd\[aVUqòÜÑÐØív]\\Rfl_YSIEMS`ÝÔÓÚØ×ÛÏÍÊÅÊÔØßùêçîÖÏÎÔÝçôÞàÚÏÒÔÐÖØÏÊÇÅÁÅÎÕçk^WQZYSMJHJNWa~ïîêyejyÿîãüz}ic^_^hn]PICBEFIRRQXTU`xúøçéubWSTPT[XURQOU\rê×ÏÑÑÕÌÊÈÅÆÄÈÈÈÏÕÕÒÕÕÓÞåÞÜÚ×ÒÑÍÎÎÏÏÍÌÇÃÈËÏÜân^YUOLKCCB@EGMNOY]\bpvïöq}úüùzktg[SXSMNNNNMQ]`\^fjøëéñìèkj^XZ]ZRZWNTSWo{åÛÔÞãÖÑËÉÊÌÉÊÐÎÑÖÐÜèþýzkèìäÕÚ×ÎÈÌÎÉÊÅÄÅÉÊÊÛèr^h`PPWPLNNS[Zim~m\joúêëáßÞõlmflaTKIJEHGIPOOOXTOU`bnecyp^Z^Zc^SYSSNKU]oéÝÚÑÐÎËÆÿÀÂÁÇÍÏÔÖÖÖèpyzìëâ×ÒÏÒÎÔÕÒÓËÇÄÊÏÌÛïzd[QOGDA@FGJQZbXY\\jdk÷ì~ëÙîñuiîõp\QQJJLNRWdccXaþréëßåmi\W`_kc]WRROUSjêçèõ}üãÒÌÇÊÇÃÆÊÏÏÛÜáþvr]\]néÛÐÍÊËÍÏÎÎÊÉÈÅÈÏÕÚØÙÙÛkYSKGGMQT]lotlpêÛ×ßíðn`^ZTTXVQSUNIHJHIHKHJIHLV_Xoßêkm`[UXUSLNRMPZéäØÒÓ×ÕÒËÄÀÃÁÀÈÉÎÊËÎ×Ûâþù~ðúéÞØÕÕÙÐÏÏÍÇÈÍÉËÍÏ×ÜßmWVPIJKIJPXXc`bddkfjôøòplh]_^]\]PLQONUWVZ\ZZUUY[ejÿèéëçïèlZTTPLOTYZ{ìÝÛÝÜ×ÐÌÐÑÍÐÐÒÒÜáââýëßìüëêçîjéåÞÛÙÞ×ÑÎÇÁÂÈÈÌÍÒÓáz]WVSU\k^h~õei_gzíqrðùüyq`YQYVVLKJHLMKHJHJNMLSTV[puvsog^^XVSRX^^~åæÞÑÏÛÚØ×ÐËÉÇÄÄÆÅÇÉÏÖÚâ|mrm}éÜÞÛÓÒ×ÓÕÙÐÏÎËÊÎÖÓÒÖÝêú_UTW[Y]VSU[XTZ_W_ów{øteeZQLMQPPOOTNNUSUYWT\^]húvktf^f`\\[]_Y\qrqüü~ààìàÙÚßÒÍÌÊÊÌËÐØÜÛâðîd^dfe÷îåØÓØÓÏÏÎÍÌËËÐÒÕÒ×ØÜæåîuíÞôöûqfg[\]WZhyíÝâíöú[UPJDFEAHLMLOMPVQQYVUTOYVTWf`XYaZ\inôëënyóòçÜÞÝÛÏÈÊÈÄÄÇÉÉÌÓÕÙÝäèéåæïu{çèÛÖÔÏÎÍÎÓ×ÖØÛáÝßéçåèytsþvlZalXXZ_Z\^\^drîçþ{d`\VPLJJLNPLNRTX^_m|ogvo^dcckfXXVTZoáåìñzqóxxz~ëÜÐÓÐÑÍÐÓÖ×Üèäåõ_jxønf^oîâÓÍÈÊÌÎËÎÚÚÙáÚÑÏÒÕÙÙØ×Õàênqüîsed÷÷ismlewx{lbVYXOKIHEFGFGMKNPSY^YV\]SNTU[YWUVVioêíçßûíæìôéäÔÎÍÐÌÉÊÍÊËÏÒÙÐÏÔàãàèþm\aiûÛÔÐÏÉÌÎÌÑÞãíóììõïçÝ×ÞÝßïc^f_[ZU]g_W\m`jixj__`^RPQPKIIJJSUhýftëêaac\VYY\YT[lsóìïõnxùóidnæòÝÛÝÝÝÓÎË×ÔØØÞÝÞÞæõpxkXhf}ïÝÔÍËÌÌËÕÞÖÓÕÔÙÞÜÛÏÎËÓÔÔßææk_jbrõ÷W_ldlé}c`^_]XIKNLKJDCAFLVXUa]Y[XKNNOMQMJO\cÿçþñtÿtåÿwîÝ×ÐÓÙÐÏÏËÂÉÍËÉÌÍÑÝÝÜçøðb[cìÛÖÒÍÌÏÝÛÙõðáÞêßÚßÜÔßÓÑîýþl___[Ze`sjW\oj}îsfbeU]XMNUNLOMKLOPfrlrdXXZVZYUU^WXacaûíu{oikøoyñìðÚ×ÛÒÏÓÒÌÍÏÑÛçÜÞëêïg_aagüqîØÏÒÐÑàÚÙÙ×ÒÛÚÓÒÒÎÕØÐÏÏÓÓáåêéôèycmiczæ{ôðìih[RNJIIICCFKKONU\\V\VJLNNJNMNPRQda]eîyfóîñy|óÙÛÚÔÊËÈÄÂÂÃÄÊÆÎØÜØéñîîlonjÜçàÝÚqpñî÷îóìÔääÛÕèÜ×ÙÞÝæìÚòúørbukd`n]rÝ{éöbT[]URQJOTLQTPO]fqþoV\`WYXTRVVUV[O]mrümfco÷÷ñûxÞÞãÚÓÕ×ÍÊÊÊÑØÖÚéñxf_bibkoîßÛØ×çkjóåîàÝÖÒÒÏÌÍÖÖÎÏÓÐÎÎÑÔÙÝæéâÝõtìêíêèøpVKLOIDHJJIKKQOLPZVQTNNPLKURPUWMQ]^`ilwõwñíëïßÙÐÏÍÑËÅÍÌÉÊÌÈÉËËÎâãßóyvk`~éàßçkwt_X^UVjûáÛßüÛØàíéùÞØÓÏÑÞýÚÝßÜæc|ëíëèg`lWTULCHIPTROY\[dlWR^\lfZMVX]oýVTbdòûknåp÷ìpXmïéÙ×ÙÔÎÖÒÔÛößÙØØàvld\úôn\tüÝÔÝîíþ{}m^U_mßÕÑÚÒÓÒÓÕÙÖÎÏÊÉÌÒÍÍÎÐÎØó÷îöýúkibZMMF@@GKLMNOSQRUMJKPLONKNTQYm[TV^[säÞÝÝíëâïéÚÑÒÈÆÊÉËÔÐÍÓÖÔÜòô|r|ôóæñv÷éèàÙáçó_X]TS]ciìÛáÝãçÞ×ÛÔÖàß×××ÑÖÙÐÒàå÷qmíö÷oYOMGGLMOV]X^ib_kb]]VKLPOWc_cuhjdh^síêää}nù~öéÛàÕÓÔÕÔÚáÜßêîû]WSY\pjgynkêßéÝÙÞôû^W^dcïáæÜ×ÕÚÏËËÉËÍÌÎÒÏÍÍÍÈÉÌÎÓßáâûðûdPLFAADFJLMNLORWTUWTMLHHHJPYe_]]`\k÷àâÜÛäõîëäÝØÍËÊÌÊÌÎÍÍÕÙàügaZWjzþîëppþñîééô|fXTQOT_diwykmñÝÑÐÐÐÑÔ×ÔÐÑÒÌÉÇÊÌÑÙÙÝÜà}_SKHHLLNOOQVSWckg`c]URNMMOTZ_``_^m}îÝâáäîýzëâÞØÓÏÐÑØÜØÛäìr^ZPNSXW`efp|pxéçæïîsg\X\jvîîìâàÝÜÏÌËÊËËÉÍÍÌÊÈÊÉÇÄÈËÍÑÜß÷bTLEBDFIJKHLMNNSY[VPOOKFKJKMPPU[]uæèßÖÚÜÙÙãßÝÒÍÎÏÊÇÉËËËÎ×áâ~dZ]^ZYYWX[]kôòæÞðwhg[RV^efflehuôÚ××Ø×ÔÔÔÎÍËÉËÍÌËÉÉÌÌÍÔè~^PNLJMNMKNPNU[]abYTRPQPNUYTVY[]füãÛÙØÕ×ÜßÛØÚ××ÙÕÕÓÍÒÝÚßøfWONMMNQOKLNOO`zöèóûúb\idb~êæßßÜØÕÕÒÌÌÍÍËÏÍÇÄÃÃÉËÊÍÏÎÏÔÙÜßx[RMLLJLLHJKKNWXYXQMMLIMQSX\YRZZ[réêÜ×Ú×ØÝÙÑÔÔÔÕÔÍÍÌÉÊÎÕ×ìimg\a_YZXTRTUXdmb][XYUOQSTWbbbksðâßÞØ×ÚÛÔÏÎÌÊËÌÍÍÈÉÍÌÈÌÒÛåêz^ZXPLMQOMT`emg`]SNSQPSYbf]]lpvvãØÙÚÒÐÕÐÐÏÎÖßÚÜßÞÚ×ØÙÜñ`[VTQNNPLKKIIMNQXUSTSTVT[_gfag{u}âÜÓÒÏÎÏÐÍËÊÊÉÇÅÇÊÇÈÉÈÉÍÚñosbVTYYPMKKLLNYYPTYTNQSUYWVYYV]kpüØÑÒÐÐÏÉËÎÈÈÊÌÌÎÏÐÍÊÈÍ×ÙÛôhn^[_\[\OOVPOTYUNKJHJKOYYMOYOKKNW[WejftìÞÜÞØÏÐÑÏÍÌÉÉÅÇÑÕØêýgiîì{qtji\]hjlÿuweas}oha`f[]ahúÜÔÒÔØÖÒÙÕÎÊÇÌÍÊÍÐÎÓÙß~qú^SXYZ]VQPNKLNNP_jZPNNPTOYgYVgbYX_rúûuøåÿrçÝØÚÙáæÝØÐËÏÒÏÒÞs_QOX^koY\kf\]nqhf`^a\`yðmnx]TTR_øìÜÎÌÎËËÐÎÈÅÃÄÆÈÄÂÇÄÆÏÒÔáêýl|ãçòûdVQMKMRSSZQLNJGMMLPPNLMLNQONQPRV\d~ÙÝÙÛèâÛçâãçéåßïøhcl~loinqwïäÖÚßèínpouþîêãÛ~b\aer}èÞÔÒÏÌÏÎÎÊÍÎÏÍÍÉÊÈÊÑÜìùZ\auñêñàçýd_gWSRUSTQUZ]S]v^[TSY_]gpkX\^RWZcwêííÞävåêfidfmbUY_XT^XMNMQ\idyäy`}tgÿsyäáíäçwl{k~õûàÖÏÎÉÆÉËÈÌÌÍÓÏËÌÑÌËÓØÛãÝÞá×ÓÑÖÕÕÝßépo_UY\\Yehhi^VSNKNQVYcXUTOMQOMTT]grk÷umbc]V\\bkvnóûp_f[Xfdzéðxò{md{edqoòáówüplfîyöêëÖËÎÑÐÐÖÙÕßÝÛØÎÊÓÜÛÙßâÜèçæèß×êùâáqlql{øòáÔßßØØéêööüwuíÞsbprfpk`]^aôëj]b]POMIHIJQVOOVUQRPRY^bððj`kf__[VW\_}úxxìóïíùqúîåØ×ÚÛØÞÞÞâèÜÚÖÐÐÔÒÏÎËÊÍÓÒÙÕÓÖÜÛêëäétwîóàáâãÝáâî÷`lwmürgxø`lxk\idmðíéÞëabcbPQOQWYUYVLOVRMVUgvqnøtgrk`U\\_]hdøuZ_ngdunöû÷õìh]_ie\_aeu÷}ßâæÛ×æèãÝÙÖÔÔÏÚÝß×Ö×ÒÐ×ÏÎÌÉÍÏÑÎÏÑ×ßêÜßßßèìáÜåéßæíÛàâíqjpk\Z`RNPNQSMJKLKMTLOWY\YONVZVW\Pblmof\gmdfif]}oîæðuónlo~wb}nãÛßãÚãÝÜÜöt÷ÿÚÝèéÜâÜÞãõ÷ðæÔ×ÙÕÑÙÚÞßèãñèØáãÚÛÝÖ×ÙÚÙßÕÎÖØÙäçèùpgkgñíicf[]b[X[VP\VPUWQXXW\_\Zjljjlahgb_[VW_YYUSRXXYSPU[^]dcojmrujcqõìçßÜØÜÛÕÒÖÕÏÍÊÇÉÎÐÙ×ÑÖÞÙÕ×ÏÑÕÖÐÒÍÍ×ÜÙÙàÛÞÜÚÜêäéx~ëòxðnjqc^zöie_TRQMOQNOYVOPRQX]Y_k`coa\fc^llf{n[`peaklgttwñ{eo}`YZWV]\]f^ZcmfoüèäÞçãáéíãÛÞÝÛØÝÕÓÌÉËÊÆÆÉÊÍÍÐÎÓÐÕÝÞÜÜáâáÜçãîáæðçáëýúðùiplèëx{lb\ZZXV`^k^SSTURURPPSNRLKONPSTQOOTW_]cfcdagfabioîkgmköíë÷ütûíëó÷ïéäïéìéâØÐÎÎÍÍÎÍÏÌÍÎÎÉÉËÌÎÐÐÐÕÎÑÚÙÒ×ÞèslupbraX[vuyphflgaxl`drb^\Z\ic_g_X`xxù}}|}f_XSNXnh^Z\Y\TUVSO\`^WRVTRONMNKWdg]ddekn÷èãåÒÎÎÖÖÕÙÛÖ×ÖÒ×ÏËÐ×ÒÒÎÌÌÍÍÎÕÏÏÖÝØÔØÛÛíðìøÝÖÜÚ×ÙÜßãóvpnûÿidbe\WSLLLNWVSXXXQNNLOWjøtklhd\]c_gùæèøy}ml^^\XUY[VQORTVPWYX\wïï}ýëâàèØØÞáØÚ××ÓÌÈÊÍÆÉÌÐÎÒÒÕÒÏÎèlû^ZeûýêçäÞárõæ|üáØØÝÖØÒÕuxéòìÜÞÞßáîÙçYUSOTflfY\U_QKRVOS[UZSVTnWSYb[YXUUSWUfOMOPMW\^[^d^n`nyo_nïëôßÖÒÎÕÓÎÍÓÐËÈÉÁÀÆÆÎÔÎÓÖÍÍÍÍÎÒÓÑ×Üäêôèèúöä{tlX]igjéîïæë{ôm\]e[\}c\[\Vc`_yþbhòu{rfZ^USXTLP\S_eg`h\V\VMRTMQOPPYTVeWUaie÷ïñ|î|ïÞîôãÝßÐÒÓÙÔÛÙÒàÚÎËÏËÍÏÖØÝÖÙìàÔÏÖÏÏÒÙÚáÙØÜÛÔÑÒÌÏÎÕÛëßàôüê÷vöc[USY]VPOVRQ^XTOONRQOOTTZd^]Z[Yem^gmZdcVSNLJMLIJNN\f^[Z[ZuthtðñÕÒØÚÙÚàÏÐÒÑÎÒÈÆËÊÊÎÔÊÑÓÖÞéÙÝèús][òþøîèì×ßóïægvãçÝìààØÙàâÞkuÝôýúfaþgW_YKUXXi[]`dhXg[O^^a]S[`kwiübX_]\TIKLKLLOHHHKPOR]`ihl{[]büäìáØÔÐÍÉÉÍÉÈÄÄÈÈÉÊÉÊÌÑÞßæÛÙ××ÙÞáâêílrv|nu{gjwèÝßâÛ×Ýæáëc\]Y^XOR]TZma^\\[g\XSTLQ^WPYV[o]gýpXkeZTSMSNGDEEDT]ZWVOYZ[YdZYxñêäéëÙÙÒÎÉÍËÃÀÂÈÍÏÌÎÎÐÍÕÍËËÎÛyýñ|ïøûkûøìîybòáÜÔÒ×âÕÓÍÐÚëéÿ{èínhñðÜØð`i_núo\ZdemmVNWTbÿmVXb]^YMIFBHKMHJMJKLA???EJHHSYZYd^akñ×ÊÏÖÌÉÊÊÅÉÊÈ¿¼¾¿¾¾ÀÁÃËÑÖÑÓÍÞåãó_jí~yûãâ×äãäå~íçthrèÝÓÚÛÙÛçÞãòegkktblxkbxùqkjfnriojc__YYYYZdkjpf__\OKHIJIGEIE@CGGLOYh~øìëðóñxúáâÞÒÈÇÀ¾¾¿¿ÂÄÆËÌÊÎÓÍÓßÜÔÜÚçîáÝàØÕÞàêßoiÞíñÏÕÎÅÆÊÄÅÌÐÔÒÛÖäÞÚlVf]Y\U]ioeò|YNNDBAAHIJO`^[Yd[[VRXUOMSOJHMLQPM][Xaûul}qahfvåéèÓÌÏÍÆÆÈÄÇÅÅÇÊÉÈÎÒÖÙ×ÐÛÒÎÓÙÕÛùdbWONMWXZgäÞáÞØáÝßàÔÐÑ×ÐÏÙÝÜßÕÙÚÏÑÛèÞíhbYMMJGJJJMRMMWSLOOSXXPMPOOUVTVPPTRMNNKJJFDHLOPVcêçãÖÒÓÔÖÚÖÒÑÌÈÇÄÀ¿¿ÀÄÇÄÅËÊËÐÒÑÛøygiöögzùoïéòxðïìãìzëåû{ìñàáîçÜÛäÝéêóþd^SSRUVV_]Z`iZXQQNUPNNOPVYTVPPMYOLRTMOOIIIHHTNNZ`[xì{þ{bdälhïëïÐÐÖËÅÈüÂÀ½ÀÉÃÉÔÒÍ×ÕÒÜÏÏÙÞÞûzïgYln\r}gvâêÙÏÓÒÈÍÑÊÐßÓÕëáâmkùYV_QJNLKURHKMEILGJOMO\WO[^UhkPXfZVZOMRJHRXQ[][\aUR\WP]ibìêïàÓÙÚ×ÙÚÏÏÙÐÎÎÓÎÓÙÛÝëÙ×åßÝÞéÜåù÷v_k~uyìïíÐÏÕÌËÔÍÍ×ØÕÛèØ×ÝØÜîÜÜíß×àöíiUZRJPWWUNFEJECKF?EFGKMHHOQOWPO_fvîçí÷ó|xësa~àááíëççãÜÓÜæäÛÜÞééæ×Ø×ÑØÛÔÏÓÖÛÙõìþör[OY^XXZ_Vb^de`\þáØÔÔÐÒÌÏÏÑÖÒÇÆÆÅÂÄÆÄÉËÔz{âúýùèîþlZ[\PQRQQONLNRLPOIPOQPWXQOVPRMIX_ccïéçÛÖáÕÒÒÏÑÓÖÎÏÖÔÓß×ÛÙÒÔÖØÏ×åê÷mv]]ion{ÜÚßÙáëé|ðìôlmõ}yì{ioöõ÷í÷ìØØäÝÜÜÚ×ÓÎÎÎÌÉÌÎÌÏÕÔÍÎÖßãçâõw|dXYfhighcmiXUWY[__^`cuäîóûtjrucZ]a\bfjh`^dljný÷ïèúûvvþu|||åâÞÖØßôñý÷yhnîû{ññÝÞÝÛØÒÑÌÈÊËÐÒÖÚÖÝâàéßÛÞÕÔÓÝðvwotcimrî{êèßçïäÝéßáâæskþáãð`^goa_ee^hvdce`j|_\jÿòÞåèèèþüëûp{WKQNLLLMVTR\dPOVTRSSWgd[_|c~ãííÞÚ×ÐÒãÞØþðàßÞÞÛÒÔÙÞÐÍÛ×ÔÖÒÔÚÛÛßçàçâÓ×ÜàãÚÞænchWS\Ye^\vúlpëÚÛçñqê{mrb[g~êêírøêtkpk\^ZUKKINLGRd[]_\khgLLQY^ZLMRSQNOMWYfçàw{sþnfchëÞÖÏÍÍÊËÍÏØêãÛÛÚßêåéíò~{üvýçÓÐÙÝâßåînf_eùênpúüêúp^cclodYToítWRVgccxßÚÒÑØÜlZ[][høíàÚßêù^UROJLMHHIKPMCDKJKUZ]h^]bZKIKKO[V]èéäØíjò~fsãôãØÜÓÎ×ÝÓÛßÎÌÐÉÆÊÇÆÓÞÝìîÜê~ØÕÙÓÕüot_YfZTiz{úø[PPKMYQ\õucZTPNLLS[\læÚ×ßöè÷ptøu`dníÛøqýlû{ôzìßãáâ`[VKHGEELPWu}\lÿ\^aTQWTUtkXui[c`\néëÜÍÙèÛåóîo~Û×ÕÍÈÏÐÉÊÎÌÙÞÖÖÜÏÌÓÍÑÙàårìÞåýÝîc_[RTPM\Z_mñlûïìwrYOQKLPVQ\^]_gX_sdgõðúízlgaR^]QaïêÚÒÐÐÕØýþi[gmpjôøøçslyswßÙÓÕßÛàoe_prkñèÜÛáÛá|êîspvúæÚáî×ÖæÜÜêçóyÚÖÜÞÎ×åÙÝâãêðÝ×ÚÑÈÖÝÚ|_ZMN`d_üàkoíj[aUiàôiufQPULKOL^ðçæÔÝkhbWUXR`ïûðÞß÷âÛà×ÙÛÍÉÍÌÎÏÕÖÖçíóñåØÚÐÍÍÍÌÓÝíëíäþçÚâØíôðpV`c\bY[cl\furUchúãÞÙ×ÒÝãÿsg÷÷àßÕÏÊÈÌÍÖÙãÙÛÜâãéìn^ZTOOY\üräÛ×ßíühXMTXZW]eð|÷ølfe{ôìoøÝÖÞíáâuy÷êÓ×ÍÿÄÈÉÏÚÚÛØÎÏÌÅÄÊÏÛünë|{ãszÛÙÝÜíVPWSc}nàÎåb\RFEKGLURpÕêëæëíßê~ÝÝ{àÔàÚÛìjíîàÎÍÓÇËÙÐ×}ghROQNI\]Zo`_üy[húwmÖîôÝò^\YSoåàÖÌØÓÊÓÞà}dìÛçÜÍÔÎÍÖÚÚäïÛØÝÓÐÛÑÔâpvjaóàèåø]dcXOSOS]]Wi{lëâí_g[UXWQUQOSWLKVTXh{héßëãÙîo{[U]^XyóíÑÉ×ßÙõcmw\itføkLKLJLXZXíäìØÔñqnngÿxwÙÛÝÓØäßùotÝë~ßßàà{iicüùÛéúìimÿztmqwcsstÿñÛçèáwdWRZVX[V\Q\_QVYZ\_`\X_U\RIFA???@FOVPf]WVW^adtöðýhåðæååâÕÏÎÒÑÑÒÎÚÜêé÷ûijvp`hvmj[hûï~éòwvxw{îøýypilc^evvhZORONMYaf~æàåûeqôôwëôéßÛßÛÛãÞáëðæw~åì^TOMNNMMUOR\`\XUP\^SOMIGGGBBEEJNOU_^üÞÜéîßìÞÝÝßØÖÒÊÊÎÏÎÐÉÊÎÔÖÝçêâøûåöua[RVUdûú^^iee^]Sdc]kÿ^jm{ëpbit`iõ}YfðinúíyòßÑÝáîýíætýæyöëàìèzxöëfkkXZY[S^UXgcUkp`hïòbnYSWYMSNIIOOQb_bêÚéØØÜßØÚÚÓ×ÐÊÍØÎÎ×ÔÎØÕÐÛÛ×Ýïölfjf[h~jþóc]p``yöïèßßÛéxtèìõåãêâçõÞÝãèý_fd[\plh÷qzãï^mmdhqká×çÚÑÒ×ÏÔÝÕß÷äÞööö_Yf\^zèå×ÓêÝßfV_TNNOP[\T]_V\óózØ×ÙÌÐÖÞÝôæßÕÚÏÌÐÌÚ×Ó×õãØÛèåßæÚÝ×ÝçéìÝâóówrîåèðïëöèúo}uóôâÚÜôpúèpkñíðìÛÞÜèðîïwïçñéææòtd^amoÞÙÒÎËÊÊËÛæëmiøòïóíìòõu|ùðàÕÝòón_UXLNPOZf_\vâÝÏÔÕÙÎãÚåÝï×ÜÞØ×ÖÔÏéÚÛæïÞæèãÞÚÓíxèÎeÞÖêÒÙûguRRZdltlñáôl÷ïy~åàêæàÞëóâÜíñÞ×ÕÖÒÖÛáìñél_gk|þn[mînáÖÙÑËÈËÓ×ÚÞíëØæ_læðìîòìäéèÞr]_XZuj[U_^gýZQV[_ggrqikÛÓêrïïäÖÔÏÓÜÝÛämqnmàÖØÞÛáÜÓáøótøá÷_\SKT^XUYYanotðta|zkýêûæÜÞÜØÜëàãâÚêòæt]^eWXjgkk[X]c`øèòÞã{õì÷þ|öçÜÝ×ÒÜãçóó|ZTT[]VWZ\XQWZ[l~ê÷{mUZ^ZcZ^öæèáÛêgljiëq[R^g`\]iìõüéd\dlîvkZOWZ_[SU[i|åÞáèèåßÝõm{éÙ×ÒÒÑÕÓÑÐÓÛêáÚâòVNKROKKIJQTRXOHKQPUMHGMNNTSRTTVo~køãê×Úñ{çßêÜßàÒÏÏÍÑÞéåüâábZdzoåÛáÞàrîãoqy\^_PLHMLRZObebvÞ{VULIMF>A?CIVQV[TP_c]ëéîäÛçìÝÙÜÒÍÊÂÄÈÆÁÈËÊÎËÍ×ðôäðßÙël]SLUPILHCEFEEIKHOOP^^MRRLOZNMLHIJRSþëpììmûÝûùíg^zólôÞêÝÏÍÄÀÅÿÄÈÃÄÉÎ×êèÝÝÜÔÜéáwkãó_eRMOJGFD>?GDHOKEDGEKLLOJKR^uïÙÞéÚÝàÐÔÙÕÕ×ÒÒÒÑÎÌÎÇÄÄÀÃÌÔ×æçÚßìz\abtzôÞtgm\^WQTIFGGKFGMIKW]izfYa_TZTTQJJIP]VmíjôëéÓÍÉËËÊÇÄÇÆÆÄÇĽ¼¾¿ÈÍËÍÏÑÓÜèíúhýhnoUMMRLPTMHFFIIKNV`]èÕÖÙæüñìÿwõärrüþÛÓÏÌÏÐÐÏÎÐÎÞÿgbusöacùÿîÖ×ÐÑÞáåé}üog^alïßÜÕÝôqsyþòômeXXe_YOQQV`qèìkhô{nîåäêÜÔÎÅÄÆÆÌÐÎÍÎÌËÓÔÖÞÖÏÎÒÑÎÐÑÏÏÑØïðm\]]_SNVUhèß×ßáêßÚãÜïhrX\caaVhtmïæÕÔäÞåûjd^PLMMWhøÞéû{ùâéàædûrsîíß~ëßäÔÐÌÈÌÍÐÒÜÜÒÝéáäÞ××Ó×âykkjkkWVVTbqñþûîìÙÒÐËÍÍÒÚãuísanîéÛÏËÈÉÎÒÐÕáöfXXTNScojýð|äÙÓÕÒÎÒÔë}ý\XaehpÿíëÞô^hpnhg^UOMMQLLQOUZopmßî~í_e_\asÚÜÛÑÐÇÆÎËËÌÑÚØørüvÝÙÕÕàÜÞäìlênT_WUWRXM^ôväæÛÒàÜØÛâçÛq^sgjüvx_ewóßìÞÞìÛä_YWSIIQOZ^zë~îßàçäÛòmðóëàÖÓÞéåæÜâææmflfllcRR_\YZ`aPX`mwbeSMOTXX_g\`ùëÜÓØÜãÞÙÞçêwbT\uïçäÛÞàÛÕ×ÞïmTOT\k^adWcöëÝééãòêñþìmeZNWab]]l_c{ëâm^\PPUYRJNJHPTebZh\g~}íòèônþòÞÜÝ×ÝãØÎËÎØàri÷éâ}ûðgùäéçúñqbfe_XYRJJNONP_[]tíàâà~aUUSLOPONTqøvâäûóñÿ]cj_[Y[]Xaød_iìêâØÝîòqtwòê_^_iqjîùcnol_aûbXWRLKKMMMQUW^s_OOQKMUTTYixéÖËÈÍÏÍÒÝÔÒÚÖÕÑÜÛØÝ××ÛßîÝÖÖãåÞqpîû]VXSPeopûk{t[dôp{f^POSKMS]ZXmwxk_[KHKJJJONM\ùëçÛÞrkkvðÜÖÚáá×ÛÝÛÓçpóèÞ×ÕÕÚØØáß}lSLOMZagkZ]YTbtãù_\SS^quzüæßÒÌÕÜêîóbuáæxvêåÒÍÕÒßåâõåÔÎÕàäóêÜÚÓÛæûõéÕÍÒØØÖàÝà|nXPOQ]_g`XXW\_]WJFHEFLMQNNOZìßón[[VWrhíæîÜÕÊÌÐËÒÐÎÏËÉÃÆÊÐÑÏÎÔÚÙÝýïäáÝÞå~úëÝl]aXSP\ZVolixmííÙÓãgUaa_îæóztíðåãíúùìë}mðo]h~èÜÔÑÙÓÒÑÎËÆÈÎØÛÜØÎÐÜëéÝÝØÙÚé÷yrmZSOJHEFJLXOOMK^yãüd]VeýçÕÕ××ÛÐÍÊÎÓÖÙÖÎÒÓÒÚÚèäÛØØäÝäøÛ×ÒÖÞÚ÷tïÜÔíèêýßÛÏÓÛÔÝèÜÖÞl]XQU`undikXcèëp[iZV[_n\_[V]uâêöé{ôÛÑÓàÜÜÞÞÙÒÕÖ×ÑÏÌÇÄÊÍÍÐßñôîäòóðäÛÞâéääîëÞê}`SSW_ab_X_ggîþý~btvöüsêøéülámem^g`xénógalhÜÚzãæäÞØËÒÊÊÐÎÔÌÑuëâçîôÐßâÛåØðåßYWVLHEOKFICFEMlSMVSPQywTgmnýxÑÚøääÞäÎÈÑÎÍÑÜÞËÎçxùæîÚÎÔÐÑÔÛÜËÏêiwú|èÖ×ÛØÛìkÛÖëq^YLJW[WVOLHP\PIFJIKSSKJLNNQ\ei^XRN[~éçèupzÝÕÖÙßààÙÚÔÍÈÊ×ÓÒÎÌÞëi`øtðêãå\^hgulkUHJIMY\kTOTM\h^VHSZOZclQMVOYgrxOP[SaïÜë_txuÚÌËÙÞÓÔÏÈÂÁÉÈËÒÏÈÇÙåÜåéÜÎÏÞêh]V[mSJD>>>ILFGB?>COIFIHIL_ônfZUR[ëést_W^þÑÖÛÛøgl×ÐÜÕàu{æÎÐÐÓØÞÜÎÌÖØånwàÔÎÍÐÖw\xáë}lSIMQWZVRJDGKGJI@?@IMOVOOKQ`cke^Y]ðâÙÍËÎÞÛÐÍÍÊÉÍÏÌÉÅÆÅÆÍÐÔ×ÕÕÞyjüþ÷ÝÞã÷il_YZXWNMNQXW^\VXKJKJOLMOMWZaebcb]]`[[TXOS`róôj^_÷öçÜÔÉÍÔÍÊÄÆÈÉÐÎÍÌÌÎÎÐÒÑÏÌÎÑÛõ_WZVQTTPQNMW\]XHCEEBEIKJKOPY\XYNRj_nlo{cîÙÒÍÕ×íåÒÕÌËÈÆÎÌÈÄÂÅÇÔâÕÓÐÎÖÐÓÔËÈÉËÐã][\XWQSPT]dj]sfJIIIF@GHILP\[kdQRTZZUa[WfõØÜÜÖ÷ïáæÙÝÏÇÊÈÅÀÃÇÅÍÐÑÛÛñßÚáÖÓÌËÎÍág_\\OQTPWknb_mbYRMNHFJHJZa\Xk]T]\ebdj]fyÚÒÙÈËÚÜáÔß×ÍÏÉž¼¿¾¿ÁÆÊÉÑÏÎÚÔÌÅÄËËÌ×ÞðcWOOKIKSa\i~dZNJDDICEIN]Zdgdc]`V]v\apîÚãÖ×ßßîí]\íøíÖÐÊÈ¿ÂÂÅÊÔíÛÕÞÕÑÌËĽÄÉÎÐædóõdgmý]dé~nhnWGKLHDGJEIPYWNTPHLX__iì÷õÌÃÇÊÊÉÔÙÎÍËÇÀ¿Â½¸¹¼½½Ê×ÒÛÛÜßå{äÎÎ×äãkLKRLLVNLR]k`]eYLKNKKSVQN[lU[_OLIPWP[[W]tÛÝÜÙÿg[]xwÚÐÎÉǽ½¾»¾ÂÆÌËÏÌÉ×ÒÎËÇÊÉÎÚícec_kVNPV[PXXLHCAACIHIONSNW`SJJLKXüvgîØÒÐËÉÍÙßçpgßÏÓÍÅÃÄÀ½¾ÁÈÐàóØÑÝÜÕÏÐÍÄÆÒæyhVj}\ZU]YPX\PMKG>>FFCEEGILWKC@A>;BKKP\{îßÍ×æölbYlÚÝØÎÇÁÁ¼¼ÁÀÃÌÒ×ÓÒÝÝÛØÚÔÉÖàåi[Ualck[_dYvgPOIEBAJHIMKONONGE@B@>HNNTXxàÛÏæðzU]W^ÜÞÕÏËÁÀº»¿¾ÆËËÐËÎØáôÞíãÖãëh[]V\^]^RW\SYPIF>>==FJLPXd``]VPKJGGN^^UeäÜÛÚÞîp^][[ú÷zØÏÌÊÇÅÈÍÏØÜåæÙñîàëß×ÐÏàëêèùùã~lh]_WWZLKHB>=DHIQOU`TSMFE@?ALXYcûÝÒÍÌÍÐÒÝêíãÔÖÒÍËÇÅÅÅÅÉËÒ×ÖÞÝÞçíyðàéã}kf]nôøäèød\r]WVQTJINMVZ`h_írSRNMF?CCIQR\We~emh_TJPZ]ýÞÕÔÌÃÄÅÀ¿ÀËËÉÍÌÎÒÙèÚÔÖÏÐÒåíÜÝÝÓÛýd\^WQUNGFGIK_õkjk{paYVOKHIJOZZ\fëäúüî\WROSZuîïâÓËÎÎÄÊÏÌÍÎÌËÏØÖÓÎÉÉÂÂÈÇÈÊÈÆÇÏÖÝ~lklbLGIFHJSVVVPOPRJC@A>?AKOLRcþåâêt[{cXbûâäáÑËËÉÇÉÍÍÎÖÖËÎÙçëãåÚÕÓÕÒÏÎÎÈÇÌÒÒÒàêâêõk^_]k}{êæî{`liMJJGFCHKN\RNUjúbSW_[]ix{éåÛÓÎÉÆÆ¿¿ÄÄÉÅÈÊÉÎÎÌÉÆÍÌÇÌÊÈÅÅÊÍÑÙífgVOOHKMMNOnu_l[_^NQI@EDFHMWMOTXuaX\X^\^o~ßêýäÚÏÎÍÆÊÈÅÇÄÇÇÉÑÐÑÌÆËÆÉÎÈÍÌÆÆÊØÞïqðnk_PYW[oyáùbiZ`cSOEDEBLPT[RW\aèïm_X[WaqèçõïlñÍÍÎÍÎÌÌÂÁÆÂÉÙÞ×ÎÍËÉÌÊÆÃÂÁÀËÔÞrîþwkRQLINR`ZOPKMQPOF?><>ABDBDEHO[qk]b]ksìÚêåëvïßÏÊÎËÉÍÊÇÆÈÍÚèßÛÖÎÐÕÓÏÌÏÈÈÒØÞãûqÝèg_[YU_þyl|ê÷dîùVLHFFEIHCCEIHVgRMPURKQYTXZ\TaàÙÜÑÌËÍÉÃÆÇÅÆÌËÆÇÉÊÌÌÎÏÉÍ×ÕÝômz{\XTOJFGGGLPOPOTKHGGHFCDAFJFKNWZSV_[ZZ\XZm\]egefêÒÒÏÑÖÞêÞßàÖÓÝéáÚâÛÔÕÙÜØÑÒÏÎÝÿêäwy{vUNV^}éÝýTZYOPLNE>?@EHNYLN]Zdmõû^hrýßÚÐßtæíßÑÊÇÑÚØÞÒÈÄÌÝÔÝåãßÝìzþqvîÜå[XRO[f_VOLKQfÞÞxdWLM\gVPMHIN`n`]QPSbínn]LOUîÚïçf[cìÎÔÐÌÞâÞÐÇËÊÒùdmÛÝæ×öbmêÐÒÔÛfZX}ë^lVJJSúãßâ\NL]÷b|{ZJM^k÷ßlOM[ðíÙÙxW\ñ×ÎËÒô]}×Ú×ÍÎèåÖÐÊÁÃÍàÛÐÒÎÉËéfîíàÑÏäPIPVZPMKFJMRmñpNEIMX_[MHJHLhâÛqPWiîÛÔßiqëéÓÌÌÚqcjñÚÎÊ×óüåÍÇÇÌÔÝüúäÙÕâñnoÝÔÏÒãêhlãÖÕziv]lßàßýZPR_lój[ZIJ[kzj]LESc^bYZQPvÝÖçëêcöÓËÉÌÌØåÎÅÁÂÆËÜáØÏÌÒÐÞuïÖÒØÜâ^Zh|çùjeWUí×ÚîíWNUcäàÛâj^`üÝåÞgOOP]`]VKMXiéûènYkpãÝææc]bnÖÓÎÎìæÛÒÊÉÆÌÔÛåØÕÙàkixúÝÞØéoðêÙÕÜê_TTOSXlmZ[WeéçÚèojV^_zpWY[`}æâæ{úóàÛÑÍèóüoîÛÏÎÛàëæØ×ÑÚèãmfwöílh_kèÝØÝåãssáçó^QSMP_päñùzfà×ÚÚíp[SY_g`XWW^ðèåßÚàøÜÑÓÐÙðh^ôíãÚèåfkÜßÚàærXrgby]XVP^snôôlXfüpìÜoUSU]öÜåÞcdçèÜ×Ùî\[\Yjio_mæçØÙÑÙùåãÕÏÚÒý\ùüØËËÌáéîÝÏÝÓà_\OX^ftNU[Wûc^ePVUcw^cNGKHSfw|[SS`ÚÓÑÛtgWbéêÜú^_^úäßßìêýèÕÖÔàmdgìÜÓÚës`aäÐÏÖâlY`wçäð^YY_ïæùnf[YlçîmVLKLT^b][TQeà×àþr]WX^cYRKNVâÑ×ØààèÖÉÄÉÚy_pßÜÙÜåán|ÙÎÎÙêvem÷áÞiVNMY_fcX_akàãëhOLHYfrvWTSQmãÞÝòsXTVQTOJHDL_múrön]f_krYPQYâÜäéöìrçÐÌÆÊÙágönftghX^ýêãÜéîúóãòæôZPOY\coli^kÙÐÍÎ×ßf`XS\[VRS\afæìðymu]_b_ZVcpéÙÛßíìÚÛÕÑÚçknmwâÚÚòfecoçìúcdfexufSMNLP_nèçðÜÞÑÉÏßømiVfzl`V\dþÞßèÚèù^cîeVNOVXçÙáÚ÷lciÛâuþgg[cÚn`dYTOdoZvöl_sÏÕÝáîy^êÓþßÔßÞÒÄÆÍÍÔêb^ësnçú\ZÜÛ~ïäúglÞßêõxlhÔËÚØÏÚûúÔÙßãçï[jëý|g\MEQSNQS_T_áîøj\XR{ðzøêÞðâÉËÍÊÍÕîñë}ric_Ujìecie[]|nk÷thiéÚíîåæêßØÙçÜÚïéÙÚØÖ×ðf^XaSNSP\øåäôìfQZ_vi_pmtâÒÍÙÓÒçàà×årëj\nnêòçßþßÙÔÝüæe]øèÔÛÞÚîßíÚÐÜÏØæ××Î×ßÛpie`]PZRIUbóÙàÙçkh_o`mø[kçÜÍÏÎÒâåòî÷ho_\eY]WZbXTTWlgpd[g_jæÛÕØÝÙÝÚÙÛÞèÙÚÜÏÎÙèý~cX_glc[[TcìáäþûuuêíãçüÜÜÐÈÈÅÊÎÔàÛÔâëbZZZe_viYPEIOOXTWPLTWrî÷åýêÔÚÐÏÏÎÕÏÌÌÊÏØýx÷rõúeVJOVYa__ULV\lâëáw{îÞÏÌÊÌÔ×ÙØÙ×ÒéôýýÛÕÒëYPOWXKOTRRINfêrSRXexuåÜçu\hÞÐÑæ{g]lûéÛùþovÜÐÕìo\^f}ßÚáïzxãÔÐÓÖâôpæÝèãiYQQbr}ëök]]irýv]atæØÙßêzhdyyðçàíkê×ßÛçgYPVPP]WONNXlsbi[U^ckììxmð×ÔÍËÉÌÔÙÑÕÓÍÜ{kù{üêð_RSYVUZ[NIPPT^imWWZkëß×ÜÝ×ÔÈÄÄÇÏ×äîâêàñ][[]~tcZNQPOMLOKMRVqè×ÝëípãÝÚÎØßåèÞØÒÔèóddpúvj`ZXRUWXZ]Y\f]norëíçÕÏÎØÝØÚÚØÞÕÓÛÝaaîóqjckZSRMVZ^aYbjg^cüöîîsojqnjns{ìot^cüù~hkÿudlZ][Zi]^jjzmwð{ââî÷ðëéôúéÞáæìâÙÏÏÝèçíý~ôÙÓÖÔ×Ú×ÝÝéùòpwûmù~ib[^p_d\PYRPRROPKIGKT^ibkhboåÛØ×Ö×ÑÑÔÏÒÒÎÛÚ×ÙÚæïî`WJHIEKICJZnknäÖàÞÖÒÎÓÎÎÒÌÈÇÊÉÃÈÎÛÙÝþgQKGBB?>@DKLJQQQXM^aWqjuórÚÑÔÑ×ÌÈÎÇÁÃËåê^RQOIHOWkñéÝåîåÜÖÖØÞsYY\dd^øüjåÚÎËÏÜ]LNQTSOUOUhóÙÞô{_ýÚØÎÐØßsofþäéîpzèÝÎÏ×ïYSPSSNORS^gýÛÒÏ×ÓÍÎÓÖÖßþ}ïp`|ìurî××çxjNHKNJKPTVMQh{óüèsìØßØÛæâôàÛä××ìèêÚÕÛÙù\SQaXOZSMMTcwÞÓÖÛÕÍÒÏÎÓÖîåÜìÕÐÛßóçáåó_TSMGGFLLIMOYcîÖÙçÛÛ×ËÉÆÈÏËÌÑÏËÅÈÌËÊËÌ×ÙàiWKF@?BBCIW[gp][]hljòðcYRT^Slõï×ÔÏÏÝÝÝýhha`\ln^evúèñne[WgyóæñëþkltïÝÚÕÍÅ¿ÆÈÉÕÐÔ×ÑÜÝÙìéØÒÎÐÚÜtkÿsïgX[MLXSY_X^\_ãæm_QLJIMKMY^e_aó÷æìóèÜÝÕÍÍËÍÔ×ÝÕËÉÌÐÔËÌÎÔèzVIG@CHHNKMX[iïåÚÜÔÍÊÅÃÄÇËÍÍÎÌÉÌÓÎÍÑÔúmXIEB>==?BBIMINQZnüðìüíéçÛÚÚ×åßèëàÝÚ×ÛîhW_eROLO\jÚØãßýéèðÌËÍÄÈÌÌÒÌÏàÜÞèëièÛìÓãc}gïéX]SNWSdlY\QJVYnßóòûzîsóÚåßÚçäåÙÌÎÕî_`SMRNPYX\e_o^YYZfjzáæÜÝíçäÔÎÐÍÍÒÑ×ÍÉÎÙùYVVWY]ZXRVRNYVPOLNRV_j_YXU^^ef`wruïÞÑÎÓåÿda^dnfkü{ëÚÑÉÇÈÆÇÅÆÈËØñôe\b\VWLLNOQRedWSYVVRLTPOkgôæßØÙØÎÍÍÍËÊÎÜÛÙâïkn]T]_\\\_ePVZS]]UMGLONY_ö{füÝØÖÏÌÌØÛÔÛäÝÛÛ{yæûåßßã^apWPY\M@>FJLNZhTX÷ìàÙÑÍÏÙÌÈÊÆÉÊÑà×ÜßÖØØú]íöíî_h]OXVNOPJFGZbPPZjWSew^fîx_]qâqlêè|bõÒÞéíög`gíîîÙÏØØ×ÕÕÙÏÔßÙÔÑÐÜÝÎØÝÛÙÞqb|abs÷ý]SXSKOIHFMiaZ`X]X^á×××ÛÙÐÒÍÏÙØÝÜÏèæàuñTLMRWKC@>@FGJMMVWX}ëåïâÝÝÏÊÈËÌÍÍÒßÉÀ¿ÀÎìxYh]TZ[d_Zdlg\Ynb\çäìî÷gk_eíàÙæÜÔÞçî_R[NUSSgbú××ÝÝÔÍÔØ×áðcbn\`l_XQIKEGTSNMAEFBINP]mÛÓÚÏÊÍËËÀ¼¼¹¸½ÁÇÊËÎÄÀÊÑÚÌÉÕâøNGFEB<;B@?A?GKMVSMPMSYgßâùjrÚÏÖÏÑÊÄÀÁÆÎãëra_gìÜØàbZXZgvzsuo\YlmrzûëÝÔÎÒÓÑÑ×uhidõù_ZZ_{êÙ××ÙëæÞæÜÝàßê}ðo^\^ZLJP]k]PKE>DKOSWgùöÓÏÎÉÇ¿ÁÄ¿»¼¾ÁÄÉÏÎÌÏÎÜïu]dz[TPHA?A@@FJOOMPfm}òéò}ïâäõñélngæØâÚÑÕ×ÑÑÙÚÞÛÚÜéÙÐÐ×ÏÓÚÜÖÛäâæïmb_^ci[TUZVZYoçåÛo_dT^_TXS[zwâênñòsëðáÚãßçùäêåÚÙÏÝmÿìÞÕïbTJHGFIEFEAGMV_`ùôoáÙÔÉËÉÂÆÄÃÅÀÂÁÂÊÊÇÌÐ|XPBA=<=<<A?>BCJOPUjoðÙÐÉËÆÊÔÎÌÉÃÉÊÈÊÄÆÑÏÝõôd[XOZ_]YSX^_jmõéx[]VWWJHDBFCJP[îöUUV`u_xöhçÓÌÁÄÁÀÇÌËÆÁÆÈÏÝßødø`_[KIFIZOEC@?DFRPP_VZûñÎÌÑÒÛÝÔÕÊÈÍÂÇÍÌÍÄËÚÛ÷|àÛæùVNICDBGNIJGGIHKPILTR[WfßîìôvÜÐÎÊÊÍÆÆÊÎÑÏÖëí\MTZlóaôo`áÝØ×üÝþ]|îß×tèàséÜÎÅÌÉÒçúðmîZU^dqt|ÙõóâèÞÕÒÅË×ÎéózY_]NNHEMKPKAB=?GCIGAIGHYa}ùjäØÊ¿½¼»¿¼¾ÂÂÅÄÆ×ÕÌÉÇÉÐÏzimlhTS`RMIHNNIJGJIJNW]lgj`nìåØÛêäÝÒÐÒÍÎËÐÜîëåÙÞëëîï}d][^\\_iiq^VPSWb[]gûååìojqpenciqvòèàÓÕÍÎÎËÍÑÑ×ÒÓ×ÚìoýddWUWRNZRPOGKHCKIVpvßßéØÖÑÈÀ½¾À½½¾¿ÈÄÌàÓÑáñ^p\YXYXOOOLABD@CGKLIKMJKM_`W]hvkg{kZ{ÞÚØξÅÊÉÇÅĽÃÌÎÊÅÅÊÈÌÚêãÚèggUJGDLLHMNPTNPSZäÛöùnèîlæÜâØØÍÎÚÒÍÝôjßÒÙ×Ï×è^an[làð[JVhVSSVLFHPHCJPNLSpõàÔÍÈÉÇ¿ÃÁ½½¿ÈÌÍÎÖ×ÓÞáìÜn^VUL?<=??CLIDELV\}ÑÌÎÒÒÌÍÍÈÉÍÌÌÏÜöÞÛæ~cd}iq{YR[cdezål`PSfjéÕçpeWWURTNMFDNOataWVanñèÖÔÎÏÐËÍËÈÌÌËÎÌÏÐÍÜày\_Y]pgUNLPRNZ[SH?CFGWce\P]mvîëèéqÿèäÛÎÎÑÖËÄÄÈÇÅÅÊÎÑÜÛÜãmXRRMIGED?=??DKPNJLR[_lèß}pvÞÐÉÀÇÍÎÎÌÑÝÜåtc[cgfû`YegëåzçîgYOWlsï}ithôÝìÝâôòeXbzÚÚçØÚÙÏÏËÊÍÏÏÓÓÎÎÛ}ûfYYTMHA@?;;<>=<?@BLW`ZZl{wñ×ÈÉÈ¿ÁÄÃÁ¿ÆÎËÎÛâÝÎÖëÚÛêãÜÕàhgl_W^ô~WX_QPUeZTUWQLKW[ZYd^fþØÔÞéÜàíÛÓÕÔÎÉÒÛÙÏÖìq{p[Z{w]Y^^USdbZ[^yl[sj`^dvjiáÙäk]}ïùäÞåâÜÔÒÓÕÕèýqôðm|àèîäfZUUYOKHHMJL_^^tßàÜÏÅÄÍÎËÉËËÄÃÎ×ÍÊËÎÊÏõWX^UMNVNGLRNNMVTJIQNLOUUPOXY[b|ön_kwaoìäîßÎÍËÈÃÃÉÅÁÅÐØÒ×ëúÞßçâÞÜhS[]NLRXNHNY\Z_îvòØËÌ×ÝÞãìêÙÍÍÕÎØáæèÝàö|lbcñÝÕèr\XVX]Z\QF@AGIT]fWLPWcsñÜÿ^\kàÙÖÐÍÏÎÊÅÅÃÄÉÕöïÛÔÜÜÚû\YYaoñ~|dY]_ledôçíàÑÊÉËÛõ]\hj}na]_dyå×ÖÜàßââÙßàþ`uÛØÓÔßï[V\ZLIA?88;=FMT^^dçÛÐÐÕÎÏËĽº½½ÁÈÃÀ¾¾ÆÉÙopRR_[[RJXSQUMRNGNV\h_deYkzöÝáÚtS\sqõÿ}ý[ùÜÝÖÑÉÆÖÒÎÍÊÕÚÝzbh}÷veiVEDIIIIOOSMLORYapÜîåÓÒÍÌÌÌÍÑÏÌÌÎìzè\ROT^TRZixsàÚïcmïhUZtöbnîØÓØÎÌ×ÞÚÌÙùëÝíiíääðwäÚÖØÙÙþV\engbqtbYXVVPLNLJHCLHGLP]_[ëé}þÛÖàjep]`hwënèÊÈËÍÆÆØÜØÜÛêÛÏÓÚÏÒÌÍÖÌÑùíÿx^KHFABADHKNWQNLPXmãØÓÎÔÛÕÓÓÙ×ÍÖà×ØÛÔÔØÙöûb\[INRC>?FLMU]VU[iÿíëÛÚÜ~e÷þùßÙÐÎÑÒáñàÜÛÞâßÙâáÙÚÙåì||ýexî_QMSYR^wlto`~ñxÙÞìjWfhZlåÕÎÓÝÛÝáÞÚßn_VT_]pý\hf\ýmò×Ù|fNIJDNUQVJIVNOjöêjdpúzãÑÐÛâÙÔÎÏÎÇÌàÞÝÏÊÉÄÆÒàùd_VZ{aQKGIMTjnöõnlvîéãðcXW]îÙáÚÒöþmzÖØÑÊ×woïÙÙÜÓÎáiZ\\UcdSHAEHILRWNDHKTite^PM[gÚËÊÃÅÏÐÎÐÑÊÍÐÜn]_yþãØÔãh_owíäñy[rÝíÕÕÕÎsZíàÚÊÌÙÞ]qökÝÒÏáiTOMM^tib[X[bíÑÔÞqONNK`]IE?=DHSäêvy_VþmàÑÞÝûêåÚÓÈÇÉËÌÏÎÎÐÌ×ý^__ïÞÑÉÙii`tàÕÌÒãxzq}êßÐÜz]PMMPTOSJJMKRhîåú^oqqÚÒÔÔ}ñàÝÎÉÂÁÊÙäl]yêpdQHLKJPk|ìyZ_NYéìðj[iboÛÏÓØuYVOjØÚÞíaöàÝÏÈÆÈËéo`gÜßßÝñöåíîÖÐãïUOMTpog`PMVZòÎÊËÑïþåÚÅÈÏÔÝýig_àÜ~õWJLJRMKKEB?CHSaYVIDN]ûäåÕßíþâÝÏÅÈÎÝènñÝÙÚÐÕÐÑÏÌÇÄÇÏÜípnßàénZOLYúâÞ÷iWIEMapb_][týæêßÙÎ×àêàÒÜåáêj~ìñyëëêcKDGV^^ebWRTQXêæálUSQhmYbvyrôèñÒÏÓÝa^câÞâÔÔèmzÚÓÆÂÇ×kURoþêêdY^eíá×ÎÜopývÛÔâÜçV^ëíîÖÖÛìOKPXfnhf]U_vqîÞõaVQOZyh]^ZlÚåõèìaOIGMV`l_oiYbòïÚÊÊÓêkþäÙÒÔÎÓØÍÉÎÊÈÎæn`_òô|hjf^h÷çÝÎØî^UJJUmø|étbaiìÐåpaWNOgnxkowßÍÃÀÀËä`YUXëê{`^PLOT\õyVNJGAMY^RV]_syÞÐÓæoýá÷ÙÎÐçð}|êíÏËØ~dWRRdæéàÍËÌÌÌÄÀÆÏÝûÿhgãìdzumèæØÏíSI@CGGUc]bqcyèÒÈÍÝ÷]XVLQXNMTO\\dçdGCB@GNiû][lcõ×ÍÁ¾ÎÞéöxyÞÖ××ÉÇÊÉÈÅÇÛò{t}oû|ühxçÓÍÅ¿ÃÚ[PKB?EGHEIO[cóØÖoYch\V}ìî}ñÜÎËþ¿ÌúYXUOfaVNKLUSYñîl[NMVP\lljòÛÌÌÏÇÈÔþ]YVPX`Y[`[xÜÕÿÉÚt]b\iãÜÞÚ×ÏÊËÂÂÌßpk^QMNRUQY|ÙÝ×ÌÙónYQTY^}ìtinåßÑÅÌælUOJGIKLIM[ñôÝÍÏrRORMKLS]PZïàÑÈ¿¾ÍújXPPJSh[k×ÌŽº»ÇÉÈÊ×ñiX[UYñ×ÕËÉÌÝeSRHCDFQTK[îëÓÌÈÌÖ{íi_]gã`]fÜÕÐÍÏâþ]WSMLLWX]lÞÝÚÍËÒÚý[MDIKKRaaéîèÚÐÔí]P[ULQ^hôìÙÊ¿½½ÀÉå|lQXwóßùhzÙÍÅÉÙÚl[QJOZiyþêÝÍÊÆÈÖåv_MC@HEJNHMnæØÐÑËÓí^HGWIYp][ãÒÖÑÕÕæÿVLHGHKONTqÜßÕÕÏÑÎêóòà×ìÔÖÓÎËÎËÈÉÌÈÛYTT^^ebõçÙ×âßØèêoMNGEK_lnqßàúÖÒÛØqHGEBGQ\jîÛÑÏÈÅÆÅÅ×jeRXZOR]wóùòæk_[M?ABLTRSVjxéßÕÒÑÔëR_}rìëêÜÓÖÊËÏÍÍÚhP[|fqd[ãÏÓËÅÂÇËÍÞqe]VRXVnÝìüàÚöíé}fYMG@ADIUYjÞØãÙÒÙõ\\Z[UY]VRR]qk|ÞvTMMM_bgzZhoýÝÛÕÉÓál^væâsæäâÜÏÇÀ¾¿ÈØ}_]dö]|öso{çÞÔÕà\RNJJD@EIEN[êÛÖÐÜÛívcljml~ysíÛ×ÚÙêÝùeWSXVT^[_u`ciëù}bXYT\_hf^rîçêÝÉÊÏâYSNGHOg{ãØÑÓÊ¿ÃÅÇÛßákh][ZbníàÒÃÉÍÊÔ}gYP^^MONV`dææîá~\liV[YRYWdçwìòlô^ZëÚl^]PWamëèÛå}âòZUZNTcNQ_úÕÒÙÞôÞÒÛßÐÙÖÔÿd{ÝÌËËÅÉËÐÞèÕÚíìäô_W]fslew^UWþn^Z_lëéõêpdYWKIK^`]ind~yíÏÒÌÕÑÝ|{tbYk÷xhèÝÐÎÕnpRFGISOOQIIORfÜÏ×ÖØïèÚÕØÏÍÓÎÐØÏÃÀÎãuPWklúâäme]kóÓÌßçrNPtôàÙÙçøÚÝëÜÐÙømO@FGEMLHIUXXcÑÒúñkmäÞìÒÛõa`b\xÛ×ü{e^YTLS\YT[^YcsåïðéÛÕÌÍÇÀÅËÌÒÖÍÈÄÌÞçäíé~íÙéZ\[U\`ïë|[oxlhgéò[[jdpìäçúWY^úÙÛÑÞ^VSIObuñña_}kåàÕßnþþe_ðîdVJJZbrèÔÏán`c^ìØÛâ]VdìäÒÌÊÌÍÏÕÛÒËÐÒÝÞãÝëÚÍÔÛåÞåòëÏÛñh_kkfèÎÙÝþbXRQfh\\UYYX_olø}q[ZboymaPPT\lÞÛÝâkY\pÞÖàîcckoêÒÎÕ×ßîyzèãéäëÛÔÕÒÏÏÖ×ßûñåÝãñðxs`îÓËËÏÍÚ^ZY[WPULKOT^rî}ÞÞ|wjosiíucczuzáÚÔßü]Zfëò}s[Xa`iîôÚæl^Y]hXWofníæàånåü\YWURZpþýpfîâÓÓÔÎÝêÞæë}gø_QüàõÞèáÜóüí~|o^Y^\aêoq}éÚÞéì{tßéðíêèèzzjev^WX^WRQV[bûßéçíêÝúolg`QQUOZ]jl|þüÛuYYQOLKPR]eäÜ×ÖÛÉÍÌÈÌÏÙåáíoo~úó|ðÓÔïdOKIEMUNQ]\iþ}Ý×ÙÙÑÒÎÛÚÚãÚÒÓËÌÕÎÙäðhKJGHLHIPRT`iäÛçlj^YOLROPgeníøÛáÝêÛÒÐïWZRNSZ]{~ÞÜÔÝèöÿ~oäÜßßàpó÷ú}ñÞßéíèûéûkmkþÛàâëî÷yñÿúnu|èùilêêñØÏÕêca_IKNWav]^g[\QTORZ\WSPONOZ]jßÏÐÕ×ÕëöõäÖÍÌÖíßÒÔØæäíò_\súd\|nyáÔÍÓôndec[\bxüä}wþläÙÑÌÎÚoZIIOKHIN[_hæåuuj^}ëÚØi[b`ggòäàê|xZUU^Y\mibUP^éÝÞàÜãÙÕåÛÚóçàÞÐÊÇÉÎßp[^\^iþàødf[\sùïäâl^ZSSRPV^_m|÷æî}vmoëêòmfpi`yÛÚÓÙßãi]aeiùÞÕÒÝÜÝÜßëïúj\\QLJOVXZeâÐËÈÊÔßfW^i[géítmòÙÓÎÉÆÊÝ{oûi^]cZWkòu][RMPfvòkY^XUUXñÔÖÖÒÞýöÞÖßÏÇÆÈÎÕÐÍÐÝîötbVY\WTRLI`ìñðhZUQTOWY_ráÞèßÎÍÐÇÃÂÂÇÍØãá}ýÝæßt`WZ]ZOJOVXzæ~öräéëÖÔÕÜôcem}ìÚÏËÌÍÏÎËÈÊñoaSPKGFFKLTtÛØÐÍÝâÝÕÚîåÜâíëéÞ×ÕÓÑ×Ö×ÚòWVPKEDKWURTWUO\êåÝÒÓÕÝùëÚÓÐÖÐÕÞÚßäuÞÒÎÑÐÐßæ~vm`m\[bRLNPRXiÞÜÛÎÎÎÎÝìñìÞßèëñè×êlúèÜàÞêihæâg]V^kzú`\XXWRNOZ|kYadjyÙÉÇÈÎÙðêâèéæØÔÑÎÕÍÊÌÏÙßàãíñ_X]_dnëÜÑÍÓ{}ïdXW]WWTSPQdoûÞÝÙÔÜøîÜÛèdpëzìénX^dapfnßÝç_WOQSZe^b\WUNSoàÒÎÎÉËÖÎÎÍÊÍÛàïsh^_OS^rkeû÷ön`_jíÓÉÊÏØéî|àÔÍÑßùof]bZUYZ`meiýõXKIMOYhpi|uRXnïäÜÑÙöve^píàæóúúïÞëeymjzùpXQXWPZræÜÎËÑÙÞg^isßÛÛê`Zb]lëßÛÜÔàåÑÏÞîxyhbn\PMLEBDJLVZY[UMLQ]~ïÞíimoïÝÖÏËÍÇÎßãzügSVVSVXROLKN[høéàx_aZ`ðÓÌÏÏÏÚæéØÍÍåýd]]PNJHLLOX\by`_ngàÖÓÎÕ×ábVXQZ^__[ngXWY]þwwùúáäíÝðvâæÚÝçèl_d[mêöÝájkjWVM[æöåìeWRVWWgglûxûþeehwéíäØÝùfYUNW^Ycf[PObd_gìjkìôt`ï××ÉÉÍËÎÓ×ÝçrgpbYfxa[VTWkÜßõÖÞómTOO]][lõ{}vyêãÚÔÞÚÎÓÞîpmmûýeêìdeYNMVmðe\VHGEDKNONVywwÜÜàÏÈ¿ÁÁ½ÁÉÊØßÞæêæ×àkýöX^gegeegTNQMV^ýäØÑÕÖÔÖÚÐÐÎÐ×Øìic^_kkclob]XSLLT__aõu\\XOQUQWd\RU\[mÕÌËÉÅÃÇËÐÔØÝÞáãêêèø{{úåâÝÖØsVYZbüzóÞÝ×ÒÒÒÒÓÎÏÏÒÎÎÜþúþsíróÖßzeRKKLSSRZ[XURSVUX\hjyåãàãÛÌÈÊÃÀÂÆÐáï|n^ZYPZb_abtÚÛÛÏÒÓÙðxjbûêÛÐÓÙÜâíÞÔÑÚÔÓÔÔßíóôzz~vmêñkVKP[YhínzlZZ]TV^ZPNTU[_|ÝÍÊÅÃÂÂÉÎÝïipqljh^YQOYbdidW`b\\[YgwèØÐÇÂÃÉÊÈÈÎÌÊÐÙãúópcpñ^øR\uJZ^^dïø÷äÞþcYNMSSY^XaX`îåÑÆÃÃÈÌÌÕÞoTVRNRXad]gÿ÷ÜÛÜàl÷xhùdcóvþùûõèäÞ÷ëÏÔÏÎÑÐémg_úïõÿdWRLMSNbügmcht^ZRLSTS]úÝÙßØÎÊÄÆÆÆÉÒæo^WUWUQRSTY`xxïëøööz^YcddyáÜÙÔÑÏÚÝÛÞÔÏÖÖÝéraZTSSYRQQWVR[ÿô÷unïybUONPOTSSWXoôëßÑÈÂÁ½¿ÆÔððäëîû\h`XWX]vzûûcïn_XP[d_îßÙÎÓÓÍÓÑËÏÍØÚÔî]PT\[[[RQNIKQMRkô~_jjWMHJQOUURea^wÿãÏÊÈÊÌÈÑò^WXeywfk~fyãåàÎÍ×áàèmXT^f|~ÿóßèïçãüåÉÄÉÈÈÕêlqþãÛäýÿpUPRTQ^eYPVRHD@?>GJLOX^_løßÓÅÁÂÄÇÖÜëòy}çm^^o_d__\ýÞâçíü_^OM\æÚÑÔ××ÛÙÕÔÐÇÌÏÏÍÝújROQYQQQSQRUYjòó|ie\OOLKJMKMOT_VS^b}ÖÏÍËÍÕÞêøìÝÝãÞèõ|oöêóõe\][ZOLGGILWcæíáÝØØÒÉÃÀÄÅËÍÏÛáèïî}mj^c]PLKSZVSPRWK@?@FNOdd\þõåÔÊÅÅÆÂÁÈÒàÞðcera][a[RP[fjmd`_dSPTRUdóåëûàìöáÔÔØ×ÙÖÒÖäõðëéÙÖÞkn~]Y\cYVcd\TOH@>?ENXVPbq\gÙÊÊÄÂÅÈÌÌÑÞîà×ÕÛñnèôyml]W_ZSKNLHIPeâßàÝÜÏÑÌÉÊÌÈÆÊÎÑÎÚ~g_[a\ZONKKNTPKXZ`][VRQOS_~up{úïÙÎÍÑÉÅÈÇÈÊÑÙ×ÓÚÔÔßÞéõêâðeWvïjýù_[TW`iÞâøêëÞÜÝÔÕÕÌÍÑÎÐÖÏÜàxgu[OOPNTOLMLOJJLF@CJMNSa`kû×ËÈÃÀ¿¿ÄÁÄËÍÎÕÓàí|\ccZXTUYW[[jypgzïäâðÞØÙÐÌÍÍÎËÉÌÌÊÈÊÍÎÕßÝ{ZZNLPPWSPWX]_XPOMIFJNIPQIReüúüÙËÑÍÆÆÄÄÂÂÉÅÈÔÕÜðßãîpTYQHMNMOONNXõaWò÷âÑÌÄÄÀ»¾¾»¾ÁÂÌÒÞÝçMGGBCHGFCEJGN]XVXSTNRQNZ]dïÚÕÓÕÍÌÏÎÒÑÍÍÕÖ×Ùð`^ZS\hfjhkccrt`c^^ahùljoöíÜØÕÏÎÌÇÂÀ¾¾¿ÂÅÊÔámVSVTYQJGFD@?DIGFEGGLMJN_}èÏÅÁ¾¼¾ÂÁÀÂÉÊÌÔÜÝnVOQPKHFDEKOT^}kl÷øskìûûêÚÑÐËËÎÎÌÎÍÌÉÆÇÊ×ofTGFFHMVVX^_]WVWQOLMKGLLHJVajþúßÏÌÊÄ¿¾¾¾¿ÁÅÆÍàouïk]MFED@@@IKKONOYYRV`éÔËľ¹º»»½½ÁÃÅÎÜ~OE?>?>??;>A@JT[`_b\]fgjjléÚÕËÍÔÏÜäáÛÓÎÊÊÑÒÛn\UZfk÷ìeoò|tuy}ìýkj^VRKGKRY]ecâ×ÔÌÆ¿¼½¿ÃÄÊÕçf\^[PJE><9678:;<;>BB@?JXçÒÌÀ¼½º¼¿¾¾¾¿½ÀÄÊë\YNFE@<?>>DDJVeqïøëÞÛÜâÐÍÌÇÅÃÃÉÊÐÏËËÉËØømTE@=>CHKKTSQXVSQSW_ffc]OHGGJPNPZ^tüêßÎÇÃÁÀ¿½½ÁÅÉËÖÜùbVME@?BIJLKMLNFHPlã×Éž¼¼¼¾¾½½¾¿ÄÌÏëZKFE?>=<:;;;;<>AFIM_öîåÞÏÍÌÈËÌËÎÓÔÛÛÒÍÏáh^VNLKPRTZSX`fcZ\xÚÙÙÙÛ×äp]\a_úää×ÔÐÎÇÅÃÂÇÆÅÁÂÈÏÞßñ\PJD@>;:9:=@CDGHHKS{áÔÍÉÃÃÂÆÈÉËÇÄÄÅÉÐÖÜo\OKLJGFF@ADFKS_]ýÝ×ÌÄÅÉÈÃÃÄÆÇÆÇÊÊÊÎËÐßëjXNLJJLTOMU\TPIFHKV]mie\XTSV[km~ÞåëâÜÏËÈÊÆÀ¿À¿ÀÆÓéê^QKIF?@CEGNRS_^VcþñÜÍÈÅÁ¾½¾½½¾¾¿¾ÂÉÐÜl]RJCEC=>=;769;=CIVvßÍƾ¿¿ÀÀÀÂÃÃËÑÏ×åõù]XXXXYY^_iÿupvþtôÜÛäÖÍÎÒØÞùe^[dòòãÜÜãàÏÌÐØÖÏÐÍÉÊÎÝâpXYPJGC>?@?=@DBACLT]vßÛÚÒÊÊÉÈÈÄÀÀÀÁÃÅËÌÕé]SVMIFGE??AAFHMdëÕÈÁ¿¾¿Â¿½ÀÁÄÅÈÎÏÙájURQPQVSJMRNMIHHGINOZXXhke_benìëíåïéßßö÷ó|æÖÔÌËÑÚØÒç÷èööêúndkýøxg^qúzìÞÔÓÜÏËÇÄÂÀ¾½ºº»¾ÃÆÌßh\OIC@<;978768;=BIV{èÛÑËÈËËÊÊÊÌÍÑÕÙÞéðZONOSP]\WZ]slZZhóíâÔÏÌÌÉËÔðèãíîßÕÚÝÙÒÌÍÏÉÇÈÌËÈÊÏÕÐÔó^\[XMMJF@=?=;:=BDEN^nuíÖÍÎÏÊÅÆ¿»½ÂÌÊÌãlVXXIDBBC>BHIHJYapÛÌÊÍËÆÃÇÈÇÃÁÆÉÆÃÆÉËÔëpgo][\WQJMNLJGKPLKNYWOVc]ZWbíoha_]Yewkggwÿaf÷ÝÝèÛÞÝáûèåó~rjY]i^SMOVUOUWf]_õôãÝÐÄÀ¾»º»¾¾¼ÀÈÍÖáqNIE@==><99:<@@GMNQlÙÒÒÒÎÌÍÎÎËÌÐÍÒô`WVYUPQMHELUPR]j~{êÔÎÐÐÌÎÖÛÒÍÉÎÜät[ZüäîôçßáçÜÐÐÖØÚâ÷vjpoZWRNGHLC>>==?@GPSONQV_ñØÉÅÆÄÄËÎÊÊÛíòÿvdX[XOJILKNPXdZ\pr~ãÓÌÏÐÐÐÏÓÑÊËÎÌÊÏÙÑÔÚØÜßägX[ZSKMOONNU]TJGIFDKNX`cib^^hîåzôôétqßÜìþzl`cðóããèéýrvéågXZYVZðÖÓáçêïï×ÎÈÂþ»½¾¿¾ÅÕÜæïogmx]IA=>?DCHIDCFIJVg_\eo}óÛÔÒÔÚãùfdaZXLLLKLP`]QOWfxãÐÇÂÊÒØâãÝÜÑÏÔÙÚØÛßázjmõãÝÔÎËÆÉÎÍÔÍÇÈÊÎÐÓàïïîoTD>=98:<?CBEGJVfâÓÎÇÄÂÁÀÀÇÕöZUPTab_YMGEFLRZZ\^ZgäÎÊÏÎËÇÄž¼»¾ÃÄËÑÓÒÒÓëüf\\^lgZSKLV]yçØÜægY\^XW\YVUXXüòjbVQWXg÷êt[[WUZnÞÒÙ×ÑÓÕÓÌÌ×õ\VWTQXha_ZX_m}çÓÐÓÐÉÅ¿½¼¾ÃËÍÏÏÎÌÍÙÞø`Y^bc\OJKGDHJFDHIOXißÍÍÍÌÎÍÍÏÒÓ×ö_\ONQPLNNKMXzß×ÖÔØáÛÔÐÏÒÏÔÙÛãÕËÎÝÛáíóìãÑÊÑÙÞäæÙÐÎÌÑÞÙÝèÚ×êh\LHHGEHEB@>?DN\nïëãÑÒÏÇÉÝáìhd\^wð`Z\_\\m÷åù[b~yåÝâ~ìçáÚÕÔÈÄËÎÏÌÊÉËËËÏÛÙßÝÑÔäfjlrxýàÎÐÜçåo]`YMHDBHDBIMKIMWfûöåÔÚáìðzåÖÔØÙåöáíèÝûe^XYX[awqahtmjäÕÐÑÐÍÉÄ¿¼º¼ÃÈËÎÔÙ×ÐØÿfja\cmk]SNROOOKE@@CHLR\omeqzvóÚÕésa^\RZbVIFKRX\cðÞçæÔÏÐÏÊËÒØçÝßñìîfXY_råÞÙÑÐÚßÖÑÎÊÃÃÆÅÆÃÅÈÊÎáqhk_WRLMI=;>?>@DEEKTìßÞÏËÏ×ØÔÜîýøîcONSNLKLKKKSfbelk^lðéÜÏËÆÇÌÍÊÇÉÆÄÆËÎÏËÐàâáý]^mstmpéúolåÞèéûiSKKMIDBD?<>AGOX`nhet÷hxxk_]dçât_f_MLQYWYYaeWVhl`inoijîÐÊËÌÇÆÍÎÊÈÊÊÉÈÌÕÞØàðþqa[eûêøf]]MGHQWOUbbWOPYW[kyc`fôý_XY\QILVRRR[_Xc{ôîëßßmpôÜÛèäìj\YbqnæÐËÎÌÈÃÇÌÉÈËÒÐÊÇËÓÚÞ÷_Zmj_]ZVKGHHIHGJFAFM\emäÜàßÚÑ×ÜÜâl[]cYLHHC==CJLOW[ZY\íÝÖËÈÅÈÊÆÆÈÊËÊË×ÛÜáßñzliy{èÝÝÜÙÜÞ×ÏËËÐÕÕëedg`[WQID?>CBCJQ[^yÝÜåîêãô{ìçïüj_WSOMPPPWXPPSVU^síâéâÜÚÖÍÆÀ¾¾ÀÁÀÂÀ¿ÄÈÊÉËÔÜîn^NJNOV[\[URMPT[n|g`]\a[[\]^Z[[UQTQIFIMNNNOOLNXkzíáæèq_xéÝØÒÍÐÒØàßáçààßÕÌÆÈÍÐÔÐÏÔÍËÊÊËÏÓÓÒÔÙØÚÙèpmd]WSPNMIGGEFL]fnéáåâàçìyldf_]WMHD??@CGKPU[WXañÝÒÎÌÉÄÂÄÃÃÅÇÊÎÏÐÒÎËÎ×ÙÚ××ÖÒÖäôüêÛØÒÏÙÞï÷ðplg`_ZRRPMNQNJLT`qóñq]YVX]bivs[VVUSQNOLIIJNVVY^^gûÚÕÏÊÆÂÁ¿½¼¾¾¿ÂÆÊÌÍÐÔÕÖÛì~{y}ÿë×ßäÜØÐÎ×ßäßÜínhboöqfYV[_a`][YVRNNRWTMJJJMQ[b^TPT\[Yhz÷ìæÝØÐÎÑ×ÝäÛÏÉÅÃÁÂÃÆÇÆÁ½¾ÀÆÊÉÈÈÍÕàè}b_köùeTSROMOSZZY^jzäÚàôg]TMJJJKMLLHFFDCBCEHLPX`girvåÛÏÈÁ¿¿¾¾¾¿ÀÀÀÂÃÃÃÇÌÌÌÌÎÕÜÞàØÑÏËËÊÍÎÈÈÉÍÕâp[ZXROIE@<<<>BDGJKHCGJPQSTVYZc`d]QNIINYhwÿãßàÒÍÈÆÇÇÌÌÇÁ¾½¼½ÀÄÇÈÇÇÊÎÐÓ×ÙÖÚópg_^\^cd`WMKGA?BIHJLMMMOOPONNLMMLLMQTY`kxíìøêâÞäÝÐÏÏÏÑÓÑÏÐÑÎËËÊÌÐÖÖÐÎÐÎÎÑÜèéës`VRVVYZ\WWPLMLOW[\YUOMQYZTRSQURWd``ikkjepþvwyïvþÞÜßðnhuñä×ÑÓÑÎÔÐÒÕÐÐÏÑÕÖÙÑÑÙàëmhrji^TKKLNQX_b_\^ha]oòæòjkk`Z\ea[efgopxõñðéâÞÚÚãßßàÜÙÙØÙäõøýfVRONRSORRNRYenjjóóqòáêýlýõyñðáãögg_]e÷çäßåÚßÝÑÏÐÏÎÑÛæààââÝáìnoêÝãxlrpTQQMJEEFEKP[gZS[e]\lë÷xqxp^`][b\[[XagúëîîÝ××ÍÉÈËÉÈÇËÍÊËÌÎÔÔÝãÛÙÏ×àáîlX\h^VYVTLGGFE@BB@DHJNLIKJJLU\]^\]UPU]ailkhhïá×ÏÑÐÌÈÊÉÄÆÇÇÉËÏÒÏÒÖÚêþfyè×ÎÏÖØØØÙÖÔâógbZOMIEA?>==?@EC@BDBCFINNMPYZ^jo~òèÜÝ×ÌÈÁ¿¾¾ÀÂÀÀÂÄÈËËÌÏÍÌÎÔÓÒ×ÚÕÎÍÏØÝêycff_]SQNIIJKLGIIDCDIKIHIKGDGKLIFIIGMYhmfôèîçÒÇÅÅÃÀÀÃÄÁÀÄÉÉÉËÌÌÍÌÑÙÙáðþíâêéíýþgmèôf[]^^rîéâp^daZV_]SNKMOLO\TJN[TVöãÛÖàÜÙÙÚØÓÕÖØÖÐÒÔÏÎÔÙÚÚàÖÍÏÎÏÙÝÚáìèéthdikbhg_TRQQVZ_^_\SURPV`rrkøëáØÓÍÐÕÔÒÑÒÍÊËÐØàßúdlseZ\{n_n÷èxiokomßÕÜìx{ýecooj[`v`_þùu]VXSPZpqf^\mp^iðåßÞØÏÎɾ¾ÁÃÃÆÆÃÂÅËÑÖ×àðãÞåx{çñsùìò^QOKGGJKJHDFGBBGGHHMZY]zåáõuîñvíÜÙØäýéåíäÝÝÛØÌÊÌÉÇÈÉÊÌÍÒÐÍÊËÎÎÍÌÎ×ÙÜñý{êñfpyui][TKKNPMLNONIHJJGGJOKLSZ]YWXVOZ}ØÓÖÐÎÐÓÌÈÆÉÆÁÂÆľ¾ÃÇÅÂÈÎÌËÉÍÏÐÙçéÞÝçñîök[]^_SNMLFCDGHDDEGCDEFCBDHJINUTVZhyjüÝÑÑÎÇÆÌÌÊÉÆÇÈÆÆÉÌËÉÎÒÐÎËÍÎÎÏ×ÙÔÞïèìwf__Z[Y\ea]^cum\]]XRRPGEJHIKKKKLLS]X_u÷êñùáÜßÚÐÍØÚÒÖÖÓÒÐÏÏÑÌËÌËÌËÊÌÏÐØãðþ]NUURPONMMLMZ]UVQPQSTWUQUdYTfmvþëãÚÚèÜÐÙßÝÞÞãáèåíinøeséóíëîæßéîÞàörkmrjj`\[XWXYgö{{ïêêàzgpj[Z]X\^ZYXSU[WRZõïçÙÕÍÌÍÏÌÌÍËÌÎÎÍÓÙäãâÛäãÖÚëéçåüog]ZNKLLGGFDFCAEHIJNPUZ[_WUTZ]RNQMNYWYfpûÝÓÓËÃÃÿ¿ÂÂÄÅÇÍÎÏÙÛÖ×ÜæëÞÞáëàæöë}fSKIHGFACB?BEILOMOSX\mm`^fqdW^YPLJOQWYf÷ÞÜØÎÎÏËÆÇÈÅÂÀÅÇÆÇÉÏÓÒÕÐÎÏÏÐÖÒÓØÝÜÙ}ccYQKIGCA@@AADDDEGFGGB?DGAFHMMLQ]jcbkîÜÚÓÉÈËÊÆÆËÌÄÄÈÈÇÇÍÏÍÏÕÖ×ÖÛßÚÜÙàèùke\_a^`]X[[_ôéñì~g^dnlpaZTNHCCEEEEHHGMSVZ^am|ßÕÏÍÏÌÎÐÍÌÉÇÉÊÏÎÎÏÊÈÊÎÏÏÔÚ×Ùßì}n__YSVWUVW]]^k\SNPTMLMNLMKFGGGLUTXkößÙÑÎÎÑÓÎÎ×ÜØ×ÞàâãîíõêÜßèèùin{èïn_dcYX_xlnh`byóßÓÏÓÖØÕÑÔÒßigzhZ_ihnn_Q[amâÕÕ×ÒÒØÚÎÑÙÞÞÚãëîòåæþj^[^|ûupfcegrù]YSQ_\QZ\Y[X^cZ\i_e^^eaddZRNNX_dkyïçàÒÌÇÃÂÂÄÃÃÀÀÃÄÄÉÏÔÖÓÚäïî{y|þrg\[WNLKQMHJLHCBEHKOZdrûzòëzúíuogzíhdumc^imsìç×ÍÍÌÊÈÅÆÂÀÄÅÄÁÃÈÉÈÌÔÞÜÝÞÝÚÒÑÖÚÛÜßðïgYWNRPJLLGAADCFBGLNHBFEDFMKJMNW]WZ`u~à××ÏÍÈÇþ¿¿¿¾¾ÂÆÊÉÈËÌÎÓèxããåæàãï{sui^_e]VSV^peeld_lpovvït^ZYZWOROLHGKPX[oìçêÙÕÑÑÎÍÎÊÆÄÄÆÉÉÓÓ××ÙàÛÞÙÖÛÝÚßèèÝÝéãàßßôsxlkitfb]_hcVVe\SONNONUUROOQOQ^hrùçØÔÓØÏÌÎÎÍÎÐÒÍÊÊËÌÍØ÷`fm~o{m^[NRS[^ZZ[UY]ýãàåöqnwéÜáÖÕÎÍÒÔÓÖÙßìwoqküìçîíñçãÞÝÙØÞÓÕØÑÙßå}g^esü{g_\`emri\WMMLKNT[WOKLLT\cku\SOYahemüksoþæÜÜêïûúíæáÛÒÌÏÓÒÏËÊÆÀÂÄÅÍÒÛÓØäìûî÷_TNMKHJGGB==<:<>ADGOPOOMV^hkg÷ö|çëÛÒÔØÞééóâßÔÎÚãìàÝÚÔÎËÈËÉÉÈÀÀÁÄËÐÛÝØÔÊËÏÖêmYY^aYOKIA=>>><<=>?@AFEA@=<<?ADGJTXOPZekkèÚÕÒÏÈÇÌÌÉÅÂÀ¼º»¼¾½¾ÃÅÃÉÐÓÏÕÎÍÒÐÞq_ae`faOLGBA@@DED?ADIMKLKKHFKMO\hwbXVX]fæÖÕÝÙÑÖÍËÌÊÍÊËÊÍÌÅÁÅÈÌÌÎÖÎËÎ×ÙÎÎÒÒÓÕÜãùjWMOSOJJHGCCHFDCFHHIINLEKLKINmóg^evrvÛ×æmqvíßÔÉÇÊËÇÆÉÌÈÅÃÍØÑÓÝÜÜÝýcgpïýïØÚ÷dbZKHLNMGIRNRSVWNNXni_åØáwq}ëòÝÓÔ×ßÓÍÏÓÎÎÚîôëßØÖÌÉÌÖÛÚñjnèánbsl\`ej\\yvîìàÒÕïpg[NGEGFBCGEBBDB>@DIJK^øöüçÚÕÕÎÈÇÇÈÅÁÀÂÁÁÅËÐÖ×Ú×ÏÎÚéòlWMNPMJMOMMUZVSVZ]_eìÛæe_YLFB@CBBGTWXlsccúâØ××ÉÀÉÌÄÁÅÄ¿¾¾¿À¾¼½½¼¿ÉÐÛßé~{÷òpaaWOLKQRMKVkY\cZSR]iZNPZSKKKB<88989;>BLOY\\eæÕÚ×ÊÄÆÈÂÂÄÁ¿¹¹¹¹¹·¹¹·ºÀÆÎÚò]^h\OPPNMJOVVURQOOVeXQT]ñ`VSYYXWPNIFFEFIFIJSyyhgwÝÓÒËÈÇľ¿¾¿À¾¼º¹¸¸¹º»¼ÀË×àüXPOMMJMVTOQZca{áëmjçç_NIJHFEDCB@CEBAFHHINWUT^çÛßçßÞÝ×ÌÊÅÁÿ¿ÀÀÀÃÄ¿½¿ÅÌÍÈÌÞüfTONONQPNPSMNSPU`un[PY^\SPLJN]jxçìíèæéÞç÷òß×Úßá×ÏÏÑÎÓÖÖËÇÅÂÂÅÅÌÍÊÑÚÎÊÏÓÙÚÖÖöeZPNNLKNVZWZPNMLINLJPJEGJA>DGGPXasêÞÔÐÓÌÌÏÏÒÕØâÙÎËÉÊËÉÉÆÈ¿ÅÂÃÈÏÖÜãÚàýne`gkûsZVOFC@BGKNMRNLNRNNSTSORZcVVy÷g|íÚÏÈÁ¾¾ÁÂÃÅÊÌÓÒÎÌÆÁÃÆÃÃÇÇÉÉÎ×ÚÝãzjlxia_[``oufZOMIA>?@?BFGDBE@CIHB>>@DLW_vèÞØÎÊÅÃÄÅÃÇËËÌËÎËÉÈÇÆÿ¾ÃÀ¾ÅËâëîþ~úê{íõu~zúkXNJKIBEHEEFJMJIOQJUcmUHKJIITcèÚÖÎËÍÌÐÑÎÒÒÐÍÌËÆÆÂÁÀÀÀ¿ÆÁ¼½ÆÏÐïh[^jòéëãàÝæofgWLEB@AB?>?>=??=?IOH@@A?@DHLM]îßÕÑÐÓØÞÜáåÜÏËÊÉÄÃÀ¿ÀÄ¿º»ÃÏÎ×æi_^[\_nîéæssûoXQMLLGHMMNWXNJUjñQDKCA=BMQOZwâÚÚÛÐÏÑÔÐÐÓÕÏÌÏÌÅÀ¿Áü¼½ÇåéhWPRW]WUYcirshü|aVW]XPOKFCHIJAAMJG?;;;;;AJJN^|àÑÎÐÓÖÔÛÚßØÒÛ×ÎÌÉÅÆÅÇÃÁÃÀËÝãtZPUXUYW_j^`kópZPOLHGHMOO[\RIJZZXOHB?@CGLQ]l~ÞÔËÉÇÃÂÊÕÓÌËÊÈÄÆÆÆÂÄžÀÂÉÙÝðim`f^TMOYgheg[MHKJIGCCCACCGHHKJD?===<>@@?DNVn÷×ÑÑÉÇÉÌÉÆÁÃÊÇÄÄÂÂÀÇÅÉÈÃÑÏÒÚáxõ÷][\bue\\g`[UWNHHKMMLNTWMPUPNKMLHBELLNPWY[kÚÓÊÂÀ¾¿À¾¿¾¼»¼½¿ÂÁÃÂÃÁÆÊÎÐØëÜÙßáüwòwx}ÿu^RKJGHKHF@>>>>ACBFCFFEEDHJJIKUWgëÞÞÖÉÉÈÆÄÅ¿½¿ÀÄÉÈÃÈÉÈÎÎÌÈÃÂÄÇÇÉÐ×Ô×ØÔØÝÝçpok^XNLKLKMPLMMPNNLJLPMHKIGLOS\_üÞÏÉÁ½¿À¿¿¾½¾½½¼ÁÃÄÉÉÆÄÈËÍÐÔÕÔÌÉÏØØÚÙÛØÓÖàf[XNNSPMGECAFGLQOMJHDCACF?=AGJUpðçÚÒÌÆÀ¿½»½¿ÀÀÄÆÈÈÍ×ÔËÌÐÎÌÌÕÜäíÞØÔÎÍÕÝÙÙßÜëvePMOLOX^^TNHMS[a_\TNMLGHNQVVhåØÈÁ½¼¾ÁÁ¿¾¾¾¾ÂÅÉÎÞÜÑ××ßõïâÚÓÒØÝãùyøèéëöia[RNQNKF@=>BDGDDFEFHLPXXORTV[eýÞÛÚÜÖËÇÀ¾¼¼¾ÂÇÌÐÕÕÙåìèåÞÕÏÍÑÐÛÙÓÕÐÒÕÚêi][^YUSNSSOONQPLG?@DGLMQPMNPQWY^cmìÙÎÈÄÀÁÃÆÉÇÀ½½¾¿ÃÍÖåíàèìèôÞÔÎÉÉÈÌÚp\[küùòlUKHFFGCBEDBCJGEC?<98:AFJTZNIJQW_eûÙÔËÅ¿¾¾¾ÆÓáôåÕÏÎÔÚÞçðéÜÖÒÍÌËÇÆÈÍÔãrRILS[\oveTLLKJHHIFDLOOLGE@;:<>DMOY[Z_ïÒÊÈÄþ¼¸·¹¼¿ÈØpd{õÝ×ÔÐÎÔÓÏÊÌÏÒÚßßÑÐÝp]NA<<?CHKNOMB@A?><<>>>CFDB?<87;@GMUlÜÒØÎÇÇÇÈÈÇÊËÉÎ×äu[RTkéÏÊĽ¼½ÀÂÉÏÜîslcnîdYSNHACLTd_]oaYTNLGECDEKY\NKJEDEMZþÚ×ËÃÃÁÀÂÄÊÎÕÔÎÌÈÉÐ×ßçý}éØËÇÇÄÅÌÌÙícOHB>?BIKFGDC>=CJMMTZTLKKF@BCBHQaýi^^YZT`ïÞÓÎÉÇÉËÎÓÝèêóíåÏÈÇËÎÑËÌØÐÉÅÃÄÈÍÛ|gVKD@A@BLWSONOVQP]e[W[[ZTU[SMLQ]kÞÍÉÈËÏÎÑØ×ÍÌÐÌËÊÈÌÌÌÐÏÍÊËÍÃÀÁÄËÌËÒÞâÔÛÝÞûsiWNF><:<;=CEHBCFGHHJNILOOVUX[XXZmèÝÌÇÃÃÇÊÏÛîuyi`óãØÐÌÉÉÍËÇÂÁÁ¾¾¾ÁÅÊÓÝë|ô}÷íìïøñpWOMIIFFJOSOMHEGJLOXY]o÷ìßâùôá×ÏÈÁ½½ÁÆÈÍÑÏÓÖØØØÍÌÍÈÅÄÆÄÃÃÁÁÂÃÌÖÚó_XNIFHGIMNRXUOKGDDECEFADHGIMQW_qíÙ×ÒÐÐÑÓÓÔ×Û×ÓÒÖàÔÖÝÕÏÎËÉÊÇÇÅÃÁÁÄÇÇÉËÌÌÍÏÝçèÿg\c_YPW]gm]Z\ZTROTRUNNLMUWX`~ãÔÒÉÈÉÈËËÌÐÐÕÞÞÝÐÎÔÚÙÓ×ÕÍÈÿÀÃÂÅÆÍÑØâåíìïhXONKIJJIJKPYMJJJIHHGIKLRWVTVbtñáâÚÕÙÏÍÕØÛãòt÷smóÜÕÓÖØÓÐÌÇÅÅÃÃÃÁÄÉÌÒÛzemlcntöírd^XW[SS^hff[UTRNNWXUZ]f÷íàÝÞÜÚ×ÙÝÜ×ÓÐÒÕÓØÜèõìáßÜÕØ×ÐÍÎÐÒÏÓÝÚÙÛéûùoYNKIGCEKKLNOLC@@DDFIJKJMPMMJIKLO_íåêãÚçnjeküúÜØÛÝÙÖÝáçåååÜÍËÎÏÎÐâynzöv}çåýx}seWQPMMV`_VRUSKHJORONTNMSVRMLTYZcÜÖßÝÜÙÝ÷ìÞßÞßÝáéÝÝØØÙÔÒÓÚÓÑÖØâåîu]^^]\RTRQQQNNNNIFCEIEFHFCBDJGLMOOKKKNPT[]XWWfrrôùvkegyÿâÚÑÑÖÐËÉÉÌÊÎÜä÷ñüõéååéêûöÜÙÞùknûpSMWd^ULOY_]VMKLMJILXuf[]èÕÞêßÞÚÖßáëæßçùccxqëÞÏÈÉÎÒÌËÎÐ×îáàÙåîàëôic`[V\^amZQMLHFKJIKJLJILLKMKLKOg}ùqhirjXZinf^int~øãäÛ×ÙÙÑÉÆÈÊÊËËÔÖÐÎÍÍÌÎÓÔÔÒÙëìüj`oðëìôndl]_[Za]XV]ehuec|p~âÚÕØØáîááôroöïðoußÛÕÎÎÏÏÍÌÉÅÆÊÊÒ×ÔÝßìðâ{sib`X[][[WW\bkZ]_UTNMQMKOQQQT\\Z^_`^kvñçzëñkmrs÷toìéãäÝ××ÎÌÌÊÌËÈÈÇÅÂÄÈÊÌÎÎÑÖÔÜìîïéèâÜÛãà××Üàíql^YYbxhjnaesöåßÙÚÝÝáââü{tjfYW]hçÝØÒ×ÕÖÔÔÓÓ×ÔÙÕÎ×ÖÐÕÝôûìýonnfi{qnüñj]\\ZW[RQNJKIGHGJNOOPY[nòðõngaW]_\\^holôÙÕÍÈÄÄý½¼º»»»¼¼½½¿ÃÅÈÑÜìyzíäßÞÞØÙÛØÜëðqkk\ZUUWOJGFFDGJLONW[TUTQNQUZeôÞÝÙ×ÕÒÐÎÊÉËÏÎÍÊÈÆÃÉÎÏÐÔØÕÕÒÏÓÒÓÞèömd[SNJOQPQNJGECA@EHMKMPOSX\UPMNU\V\^Y[iö÷íÜÐÊÄ¿¾¾¼¹¹º¼¼¼½½¿ÁÇÏÜÞéöüðöèèîÝÛßãßzj]\VOMHFC>;;<;;>?DCEKIHLKKLLWg{ã×××Û×ÏÐÔÙÕÔÔÑÎÍÎÌÊÏÑ×ØÔÐÎÍÊÍÍÎÓÕÝãän_XPNNMMJC?>>>>@ELNPRQSROTROOQQONNPTRPU^dnàÎÈÉÇþ¿Á¾ÁÅÆÉÌÑâæîkTV[RNV`h`akunipk^YZWOJHJB<:;=<>GMVRPOOSY^cmpyðäÝÙÙßìðêÞÚÖÕÔÓÜéíéìêòùøéÚÔØÙÏÓáoúèèvl~éýk`UTUTNHHKNNKNY[innyôãàîýnij^XWUQQVVOSY^e÷ØÓ×ÐÎÎÌÎÑàéùZQMLGBDDHKKPXZ]xÞÙÕÐÍÐ×á÷dUMIDB@GKFEJQY^fgmqÝÍÇÅÊÌÏ×ØØÝòõî{kòÞäòáè~îêæÙÑÐÎÒÎÑÒÕÞÞèæèæÛÛåãàüslno`baUOSOTSYhck}âÙÞðìí}rjh`WZXYLKNJOS]ieyàØØÔÑÕÛÜãçìp^^YRORSWZXWW`èØÐÊÌÏÎÎÑÒÚì|fe[PNPQV]\[[W^áÓÔÑÍÈÆÈÇÈÍÕÛÜàíèìûîëæçèãßÖÐËÅÀ¿¿¿ÀÄÉÈËÑÖ×ßçïmp`]`cfke]ekhic`[W_^bhji]ZRSXSKKNOPQOOTQTXXYlÿí×ÑÎÊÍÏÍÓÜÝÔÛîøo]SRMMQWgæ×ÕÌÄÂÁ¿ÀÂÈÎÑÚßôn]QMNSSVY\d_xÛÖÍÊÈÆÃÃÇÄÆÇÊÎÑØßàæúúððÿèáÚÓÌÌÊÊÉÉÆÄÇÎÖßêýkr`WPIJOQPLLLIKNJKLJIJMNPWYX`\Z`]_^^uiøüiïíëéõy|ëÝÒÌÎÑÐ×ÓÒÔÐÕÚàèúq_XOKLLNPX`fïâÒËÎÎÌÍÌÍÍÖòu_XQQTWX`ðèßÚÖËÇǾ¿ÃÄÅÅÃÇËÖì}jf\ilgm`råãåÛÓÓÐÐÓÙìòp[VNHB?>=<<>BEGJMKHJNY`czn^]mtist~o^^ltùàêèÞá×ÔØÏÍÎÍÍËËÇÊÍÌÐÔÒÖßèôp^YSMKOMHGMS\üâÝÚÑÏÏÈÆÅÃÉÌÓÜét^`\YWUX^gn{çÙÒËÇÂÁÀ¿ÁÀÄËÒÞp\MHKIHEDDECCJNazsììðñng^OKHDDCDCFHGHIIKOQWZenjóáíõ÷æÝÝÜÞïûpeýÛ×ÙÚÞãèáâÞÒÌÑÑÓÑ×âãàÛ×ÙÞàîûpjøôk`]]fnpdh|øÞÙ×ÕÙØÏÐÒÏÙé~{`Yku]e}nòêëêèçïíãÙÜÝéñû^WRIFGCABB?><<@GINeçÞÖÏ×ÚÙãÿuxmUIJGJMIKKJKN_pâãëØÛÔÎßÚ×âäêääto^^]]`ytýïàØÔÕÚÖÔÏÈÊÌÉÏÔÖØÓ×ÞèìâçùmiZRNMMQNMU_îÙØÖÙËÇÐÌÈÐÜìf]VMIGCB@BGJILMPfv^fõóâÝæ÷k[VVSLMLGEFEJMMORTpÙÓÏÎÎÍÍÐÖÜízlqk^USMHNVUYcrnk÷àåìæáÚÕØÜÞåðîÞæïñôüãÑÍÉÊÊÉËÆÁÀÀÀÇÍÌÍ×ëvg_]]ijeüûüéísg^ZX_eto^WV^ýaVNKKJJIGD@>?DGFJRcêÛÑÍËÉÍÐÉÊÖÛîjhZROKLLJO_fwðå×ÍÊÇÃÂÃÇÆÃÇÎÜödVLIHIGHKV^ervè×ÎÌÇÃÁÄÉÇÆÊÎØÙÓÔÛàÛãîì÷ùÝ×ÖÛ×ÏÑÒËÀ»º¾ÄÂÁÅÎØo]e]ND>=>@CC@=?GOWTUY_fxj[Z[_\WRORUSUNMQW\[gøÙÑÎËÌËÈÈÇÇÉÏÙããùbZRRWSWcrwmòÞÖÑÕÓÍÊÈÊÎÓâéûkicjj]nprðßÖÕÏÌÇ¿ÂÁÁÈÌÓÛç}p_UY_bdjðâ×ÐÍÉÆÆÈÆÈÊÌÑØÞöiOJKI@>=;<<:9<?AEIGP_h|ã×Ûßâèînþd[_PKNNOQT_eiñÛ×ÌÊÉÄÂÃÆÂÄÊÍÔ×àíuUSWONLKP]b_|ãÑÐÍÅÄÃÁÀÂÅÈÈËÔØæpla^lc_dtlhóäÓÑÎÌÌÏËÈÈÉÎÔÜìwi\WTOLIJLLLOS[a`nök^q|s]UWMNOJFDJKIMQUWW[]c]`qývóÓÓäàßæóãá~~vna\h÷åçèÝÖÌÏËÉÌÌÍÍÔÝáèêï}pkkþú}îêéÜßÙÌÍÍÉÈÌÎËÍÎÎÐÖÛàîvj_[Z[^iÚÔÓÔÑÒÕÍÇËÐÓæla\RJDB><<::>??BC@ADLU_à×ØÒÏÏÐÑÕÛáôg`RNKIIHHOTW\_pôèØÛàÝàäêðÜÔÝääõ{efmYWTPWk_eîàÚÎÉÈÀ¼½ÀÀÁÇÊÍÑñ{n\\dm^XY_ZeóìåÖÕÓÎÍËÉÇÆÇÊÎÝõxj_VOGEDEMQPRTNNNPVUQLDCB@@CDCFKKOY[XXXQOW^]b}ôïßÖÕÛÐÎÔØçí÷íö_[XTUg{÷ëéíëçÞë{m[X\dnëâáÛ×ÕØÔÏÏÎÎÒÓÑÓÒÏÉÊÊÉÉÌÌËÐÚé`SRVXY\^_kõîòìÜáÛÖÕÖÝí~ôg^[^\NKGDCCC?>@@BEHLWpòáÝÛÚ×ÏÙçü_WNKKGIHGJNWfzz|kqüîÚÕØÝÛÙÙÓÏÏÎÎÚÝÜàën`]VPKKWsuâÙÛÒÍÊÉÈÄÆËÍÎÎÔÏÎÓØåþwý|la][[qãäÓËËÉÇÇÉÅÅÇÎÚßnXOKKKKHFDDEKNRTUKGJLQOMPVY\~l^quiiwüZMLUhäçm`]rÜÐÍÛîotïø|[OUfpp_QM[|ø}qunõìëåø~èàÓËÉÄÃÄÄÅÈÈÊÌÏÚßÜÛÓÎÑØÞßêüzp÷ëðáéàâåÞÝßÜÚçßÖÚ×××ßâÚåâ×ßæèëwgZMIEA?>=;;=>@AFK\àÝÝÚÛÚÚçÛÒïqn]ii[[[hn`_n|qðëÝÕÔÕÙÙØßæØÐØÙÚîòÿaWTZ\POTRTbuêÚÛÙÒÏÊÈÅ¿½¿¿¿À½½ÁÊÑÛã{ýìvk~óêßÝÜëÝÛÝÙÓËÇÉÌÏØÙègkp`^XTWPMLIEFD@DMSVaeVcqgðåy^]WOPOMJJLKM\õúyíåâéÞÚÞØÙÖÎÏÛö{cWWW\eõêûôðèèîüæÞßÝÜØÓÎÎÏÒØÜããÕÎÐÐÕÖÕÕÚÝà÷mnéãâÙÓÑÑÌÌËÈÉÎÐÎÑÙÜÝÙÖßñwüûf`heZOLKNXRIFCABCEHJLLOZaqìéëîyuéÛÜéwoflt]_hi_WWTX_nùwqspðæééàå|üíÜ×ØØæónZ][\]XZ`îÞÙ×ØÑÍÊÈÿÀÁÃÄÆÊÑÞòv\XUQTYX\g_eo}ìàÔËÉÉÉÉÃÂÉÌÎÐ×ÚÜåu\OIHHCBBCDEEEFKHFGLW\`XV[TV[^\ZY[ceon^guwxûãèæãàØßìwnd[cc]TUdgnk]ZVY_^kìòqe}ÝÓÖÒÐÎÎÒÑÍÉÇÉÌÑÒ×áëzþújh|ëãÙÖ×ÔÛØÛêâæ}xgfnncgc]^fóçîìðvdZb\\ZRPNLHHEHHILNX[dlv{ëy{ì~zh\YXQMLMSLJOV[mîñéóýßàßÕØßæüíæêvúkSTTYa_Y]X_h~ôøíêÚ×ÌÊÍÍËÈËÎÌÌÏÚåãøzlüêüïíøøyuðøîÚÕÛÖÌÇÇÈÊÌÐÛÛÞ÷o\UMD@>=;;<=>>DIKT^alqæÚ×ØÙÛÚØíõytþc\X[_^_jmyyä×ÙäóówdXTWWXW[_adcmòûyztéÛÚÕÏØÜåóãßéâÝÚÑÎÒÒÎÎÍÖÕÏÜßâêíéâæäì÷ùôçåàØÓÐÏÎÓÐÍÍÏÓÏÒ×á~kjndi\WX[YXPHJKJLKHJIGGGHKMLSW\xÞÔÖÕ×ÝÙÔÓÔÔÓØ×Úßïðïxd`pouåÝÛØÙÙÜÜâèøñgQWTPXUVXY[`éÖÔØ×ÏÎÌÇÅÁ¾¾ÁÇÍÕÖÕÛômsddb]^]høùñß×ÒÍÍÍËÍÖÑÏØÖ×ÝØÖÙåùpn[RQONHFEDEFHLORT]dlïêãÝÚØåús|xw`VNIEJMQ\\füæçÝÚ×ÒÓÍËÊÇÉÏÚàìmdb\[ZZ\hzýâÚÑÓÔ×ÛÛÛÛéwûzpïìÞÙßãâÙÜÚØÔÐÛÝÙÓÓÖÞàéúéÚÝÝã}ïïèæðzzïõìðüö{vwiWJFFFFHJNKLJMUU^SQ`_n÷úpnnmúßÙêîôïáÞØßûãv[wóx^WXNNOUX^__oíæõöãÞÜÖÞÛØÛãÙÒç}x[\nãéðÝ×ÏÍÇÁÂÆÏÑÎÒØçð_PHBELKJP^íÞÜ×ÐÐÌÈÇÃÄÈÈÈÏãúi[]ZVNIE><=@ACKLKOTZ[]WOUR^~îûmpy~nëÜëønclh~}ng\ZViîñèãêãÚÝØÔÝæúe`^ZWOIFIKKR[doóëòçÝÕÐÌÇÇÆÁÀÂÄÇÑãïug]hlg`mkvãØÔÔÛÜÚÞïrmkXONNNUa^^kîãÚÕÔÝæðïm[YRLGFHC?@@D@?FLQ\ríÛÙÔÌËÌÎÓæ}y_RW^\Zbd`q|øðäÝÞââÛÜëôg]ne`rð}zåáãÝÝíìÞízkøúdftëêäßÜ×ÐÕØÒÓÒÑÐÏÎÏÒÛÝÙÚézöúpm÷êèÙÓÐÐËÈÉÈÈÌÕßík^SG?<:89;=?BILToìÞÚÓÕÛÚÖÕÜççûuyaag^ONOTW]qøßÕÓ×ÚÔ×ÜÛãüoi[T^`WVV[_sæÕÐÏ×çÞÓÙîtûõü~íÜÙ×ÑÌÉÈÈÊÉËÖáêßåo]TY\TNP^þy|îóé×ÖÏÈÃÁÈÍÌÎÏÑÒÖäêmjÿkZ\VPPRVUONLILKD?>??DJR[wãÚÑÎÆÃÃÃÅÉÍÑÚèóp^[QJHHILP\okoúêåÚÐÐÑÓÚÜáãõe]TTRSPNYVXòÕÍÊÆÄÃÅÆÅËÎÏÕÚâæ{ýçèèê|sôèåÜàææ{{øèÞßèýtvößÝÜâåÝÝÚÝétyt`baZ[UNLOSTSSY[^biùìÝÞÜÙìl^YVSQNNOQ]oñòõäØÎÉÆÅËÎÓè÷r\RKHHKNQY]aZ]zäÚÚÖÕØÔÔÐÒÑ×åçëùrmoþçìëèÝÏÓÐÌÎÐÑÖÞäâétc_\`jn|~ýíÜÑÏÎÎÓÕÚàèh\PJGFEDGGDAAGMTWZyàãàÕÒÏÌÍÎÐÑÕÛÜàÝçû÷mjndk_VWVPOQMMLPSWaciüñéÛÒÎÊÈÍÒÝâèkZUTOLLOUWZgsþÝÐÉÇÆÃÄÊÊÌÖÚá{inQJHGLPSVWcõÞÙÒÈÈÅÇÉÉÔÍ×ÝÚíüeXP\ZMHDIMNOLGEEGIKLIJNWZSX\`xÚÑÕÓÎÉÈÌÔåÛÔÏÛjjnïzUUgo[RTX]YSX[``ZZ\]UT^jknïèéñá×ÎÊÌÏÔÛÞäÙÒÚßåÿwnuj]`a[`|éæìàßêëþktj^ckiiomkglrlñÝÞßââéòxwe[XPMKIJKMMMPOOXhoñçèçîàÖÙÞàèyicX\]XRMR\l}ïëëÝÜßÚÒÒÖÓ×ßØÙÜîzeXYZ]]W^\RVWX_^_gvúåØÎÌÎËÌÏÏÐÓÝÜÝÝÜñíêp]VYZSU]^^kjóßØÑÒÔÔÛØÛäãáwY[XTOKJIHJIGHOSVbmóëõõêåáØÔÎÏÐÎÑÙÚÜáïfid_c_]\\_ZQPTROOXg|öüòèàÕÏÏÎÎÊËÎÍÌÒÜÞàáâÞèûsjggljxýø}òÞãðþöîíÝÛßáâíòïyf^\]ckýïÝÚÞåéãèæÜÙØÜÛãvnimf^ZUTPQNPQLJHHNPTYa÷éâÞÔÐÑÑÒÍÌÊÌÓÙãí|ýúùve_cdb_[YUSUZ_nììîxgdhzùýmrúûòüúëîëâÙÑÎÌÌÌÌÏÎÏÏÎÎÑØÛÞßëúuf_ZWYTT[XUUX\lùèÜßÜÚØÛáéõp_^kps{qbYRSVW[[TRPRTSUX^_d|äßØÒÔÙáæâßßßèêîíõlyzsd^kúú{únd\^vêàÚÙØÚÙ×ÛãózgYZ`gfnng^\aceÿëéäÞÙ×ÖÔÓÑÔÔÎÊÉÊÊÐÞðýngkg_ZV\glvvpleyìòîêöj^clntyvtkd^WOJGFDEIKMR]_cðÜÓÌÇÆÈËÌÎÐÓÚãøm`_hnln^PQUWW[__cgt|öìíóðèåßÞâßä÷ùëääæåãÞãäãìêíyokixïæÞÜëýñìçàÝàêzmeafc]]dkïÜ×ÕÓÙÞÛÖÙÝàßæöûûwlg^TRONNMOPNIGJKMT]jmmizíàÝàåèâÚØÔÐÑÙáÛ×ØÚÝàösje\ZWOQVZdksüû~mzôùùìÚÙÛÛÝåíí~vomz{îáàÞðøæÜÖÓÍÍÏÕÚÚßàôeZRQRU]ac]^fnüxzôøyjjejkhxëßÞÞÛÜàðwlb\UQNMLKMPV_djzõèÝÒÎÎÖÞáêðìããæì÷ýzvrh\XVSSW[dmmðßÞâÞàäëêäìû÷õþxóíïîçäçèééëíííìðþ{wlhýîy÷çêéæåçømjhdyøðàååÞÙÝàâúnfbe_hskejojinmkd`[WSNONNPRTSV^inpíìæÝàÞßäßââßÙÙÙ×ØÕÑÐÑÔÝñokwn``\[[\fdcniküðèáÜÛÜßÝÝôke`dc_aedffdhkotuõçÝÙÖÕ×ÙÝãéõùöùééôîùúêëïíëöïøûõ÷îòðý÷ïþp]VWRQNMKJMPPOU]Y\m}ûîàÞÜØÚÛÝÚÛÝÚØÒÓÒÓ×ØÖÙëóyccd_]Y]c_[^adb__hpõééæäàãìîïôÿýíîíìçãááßßàâìñó|vibhfef][ftøçÙÔÑÐÍÌÎÒØçdTPMLNOOPU]cmøúîáàãßÞèøn]XUUX[^btüîêììäÞÞÝÝæäíþ|ÿxÿ÷úñëvl`\__dcmqrýìêúvv__cim÷ãÜÚÚÚÜàØØÛÖÒÏÓÛãéøòûilniyxîäâÜÖÙâçîtj_[XVYVTYabqþtlgdmwøêàÛÕÚÚ×Ýßßçïð{k^\b^\c`]i{üóéßÜÜÙÙésbXPMMKKNRTZpíêàÝããÜßèçéð}ýyxp|øñåÞÞ×ÑÓÕÕÐÐÒÔÙçøqa^acfhosykmqhglcizù}zúþd_ld`jsõßÕÎÍÍÍÏÕÓØßÞãôr_VQSY[^fjny}|woxúniibYTOMMNPTX]bmìéú÷ùýïéáÜÖÐÒ×ÖÖÞï÷xe__`\\^^hûïçàÞÝßâÝâàßæèéòü}wld_gro~éëïò{b[ZUVTZ\gêæäÝÜÞàÝÚÚÕÐÐÏÎÍÌÌÍÑÙãèï{e`[ZZW^add[YTNKLLIJJKMPURPWZaüÙÐÍËËÍÏÏÕáïrbcikn÷ïåßÚ×ØØÙáíûîô|ú|xspqe][UUTQTYYXWZYZ\\`jþéåÜÔÔÚÚØÜçáÙÔÒÍÌÍÉÇÉÊËÎÔÝèôxmjedlklvmaZVXZWZ]Y\]]\^YUSNPV[w~~õuotngjw÷éãÝÝàÚÛèíçúxoccbpíæÚÔÒÓÛàúeYOKHIIKSWXX[\\`nñßÔÏÏÍÍÑØÞê{ùïåàßÛÝÚÓÓÐÐÒÜåívptnc^põïçìzicc^`sïêâÛÖØÞélZPMRXbjetvpjkxwúùøôùì~iopjolb^[YXY`múçÞàåçìôôsie^]\_hmbXSKLMMS[h÷åÝÔ×ßàÝÙÛÛÚÝÝÞâÞ×ÎÎÍÎÑÖÛÙÛÛÚÜÞáäòf^YTRTYW[dl|ñëðxd_]bnyõêãçñí÷ûíëááÞÛáßÚÔÓÐÍÐ×èl^RKGHNSU[`^\]bbbfb`]\\WSQKFCEJNU[jëÞÙÔÎÍÍÌÍÍÍÐÑØÜ×ÐÎÉÆÉÌÕÞíykednôÿûõph_UUYYWTW`ebn}nmjgwðãÚ×ÓÓÛÞÛÚÜÜàããíqpùëãà×ÔØßño_VQPT[^^higoppkeb^\`fejbZWTOLNNOPT]^bwùìÙÕÔÑÑÑÐÏÍÊÉÉÉÎÑÙúf_ZZ_jûòîêííâàèêìqb_^fd_^[__^ahjlïåêåÝÚÝáÛàñ~tggoößÚ×ÔÕÔ×Ýâëzõàäëëïýviv}nbYTSOOSTRRQTWTRPMMOOWi}óëâØØÚÜÚÙÖÒÌÆÅÈÊÍÒÙïlaZY[\adbdgfm÷èæôy|oonfba^\_^_^^anøæÚÔÍÎÑÏÎÔÙèöïxõéêæêöþÿhchfmw÷êäæÞâïçìj]WTSQSXXW\\^_\^e`]dqüíèáæçßãêêëèÞÔÏÏÏÎÏÐÓÝìùoZRX\Z]_c`_hld^]]_kjhkfg]Z]^_`^iûåÛÓÐÒÏÒÓÐØÛÜÝßßèæàèèèôûlcc[[ajqìéíãáãýb`\YWZXVZ]___c]]hfmîÚÕÕ×Õ×ÜÜípzøñëàÝÝÝÛ×Ûßãïønflpzrnc^ekjc^[[_fb^da\Z^mkd^\\`pöèáææäÛÛæîèßçòäÝÙ×Üåçë|e_a_^júçßáßÝáÿr~}ümeaYXSRTUURWZY_vìñèÚÛ×ÓÙÞâÞÛ×ÖÒÓÔÏÎÑÔÔ×ßëõ}ôóìxhg\ZSOMKMOVTRTSWXZew÷|tuõåßÜÞÜßÞÚãñùúõîìíìæáÛàåãìøld`^_bkghzóýa[[^emc[`_\`ge_YWYW\h{éàãÝÒÍÏÙÛÖ×ÖÑÎÏÏÑÓÐÓÙÜáêóvÿîèìþlqýn_[XVSUZVQVSTV[]`mmknéßÞØ×ÜÙÛßòpmvo}ÿkmõíôóëêùÿüuozslojfyöñg^afab`[^^Z\\_YPPROS^h}îñæÚÛÜæãÕÔÖÎËËËËÍÏÔÖÝêíöqxìî~quûxmnheic^clggnti_ab_]bnüëçäÛÚßæíøy}úðòÿùðäàäíìêõxn~ûrmjhotonaXSOMMLMWZ[^_`^[ZZZiz÷âÞßÛÛÝÝâæÝÝÝÝÜ×ÐÒÓÓÖ×Úßáô~÷øwxquîðüngebZ\gmøäçêìøuhbg^dyïçäááÝàæåäÚÜßÞßàäáê|m{ø}üpdaecbclw÷öýri`VNQSTY_\TRRMLMKLR_iüãÞÜÛÝÝÝÖÓÔÖ×ÔÓÒÒ×ÛÜØÙÛÛàíòêîõíåæîsd\WTSQ\oøçêïø÷vhb^_ezåêèåçåêèàÜ×ÕÖØÒÏÐÐÕÛÞÙÚáî|^SOTPRUWWRSQQUVUWföô÷{n_]ZUSQOR[exòîâèùèàÙÖÛÞÞáÞÝßßÚÜÚÚâáí|ðñ÷æÜÚÝímbWTW\bròíòoqtmqcZ\i|íÞØÙßåæòöêåãÞÛÛÚÓÑ×ÜÛÖÔÒÓÛë}wmkvþk^ZWPMQSQUYfld^[WTTQNMJLPSZbs~rvúøéÙÙÖÐÒÎËËËÎÏÐØÞãøfroah}éõjlfXY[X`þðêïëëÿõçølhcexöêáàÚßéãçìçîóáÚÖÑÔÕÖßâÞääëwpqkjýõx^VWRTWX^buûöú÷rbb^\YWUNNOOS^a\^\ajlöçßÕÑÏÍÌÌÎÓÚÛßëçûùðtúó|wfY^_WYhøçæåÞÞàÝèðúb]cdmzþîð}õú{ö|o{èÛÔÑÎÍÑÓØÝÜÜáäæìëéê÷g]ZSQQRTTY`_cic__XTUWTONSY]k}ôèêîèíèáÞ×ÏÔÑÎÒÔØÛÜãë÷ýpuqcc\^c]\XWWYcyïùèàãÞÝÚÜá÷adl~íåáí÷íîúo{pqéÜÔÒÍÍÔØÛØØ×Ü|{}tkc_XSRRQOSX\`dglnwm``_^]VOPV[[\gsþý~ûìæáÖÔÔÐÎÏÐÖÙ×ÙÚÞñvùêôjajmgnh^`\Zabr}{òìùëÛÚå{kloõè~mþsmrljkhoøúÜÑÑÓÖÕÕ××ÔØëðíëìkii^\XQSWQOTV_bckb_`^YUSNOSVVMWgbiþæãÞÙÓÏÒÍÍÎÎÒÕÒÏÕßßÞàçîùdjyp|phc^XUYZiojonóßâïýùüö÷ëì|öëíçßéïæòùéÝÛÝàÚÛß×ØÝÞßâè}lkZUYOOYTRUU\]fzpalg]e^XWSVUNORPT\dþãçáÛÜÕÓÐÐÕÛÚÛÜÔØÞØÙØÛáâìwy|l~òpmlgkl÷òmiqwùãÝäåãÞóqó|mfiultnlilöéÜØ××ØÒÑÔÔÖ×ÛÛçöñxh]XYWTRUUUXX]WPQOONOQPQTWOPUUZ^sîéÙØÚÕÏÍÏÎÎÒ×Ù×ÚÜÛÞããáéût|i_gnrone_dd`cljkõäÝ×ÖÒÓ×Ûåîùýz|ö|ýþslqêçéãÛÞåÝåäßãáðëê}fkn[ZXX_Z\^_jcXX[UQUUZ\X`[ZYPOQWYfq|æëÞÕÓÑÑÔ×ÛãâåêàÞßØÚØ×àëìòwphmúspsmk`\\]bvõëÜÙÛÙÛÞåvilvwponnknïàØÙÜ×ÓÕÓ×Ø×ÙÛÙÓ×Ýêzuh\UTXUSV\ZWSONNMNONQPMOYSOQTY_mîîßÚÙÑÌËËÎÑÕÛâÝÝãÝÝÙÖÔÔÚëñ|hgndyýija[^[VZgrëâÝÓÙ×ÖÞâè|zïöøë{öóm÷æßÛáåÞÝÜÛÞßØÜÚÖÝáìpne[XZXWYVZ\^[TQWWVXYUXZVURRTPORW]lsnîÛÖÐÍÍÖÝßáàÜÖÖÓÏÏÏÑÔÕãkfsigmmpfbh`][Yct÷ãÜÝÖÕÞàâíòüliiw{dhzñéãÚßâäÛÙÜÖÖÖÔÓÒ×ÕØÞðkfdmeXVSTVTRNNLMPPPMPQMNMVXRSSX^zqqæßÒÎÌËÏÐÓÚÛÖÔÔÐÔÖÔÙ×ÛôiZXZYYYZY[Y\`\i~ïÞØÓÎÌÎÏÓÚÙÞéïwu|ihusîßäãäñïçåâççâéðîîéíspmbk|mfdfmxihb]\[^\XYXPNONTWRNMQUUX]nùçÙØÖÕØàÞÛÞÛÓÒÒÔÕÓÖÙáûje^]]]ehed`go}ìÛÙÚÓÐÏÕÖÖßìéõd^]RTXZjðáÞãÜÛÞÛÔÖÙØ×ÒÖÜÚàïéït|øzøk___`YQRTQUVQPMLMJKOORZUPSUY\c|ßÒÍÎÏÎÐØÖØÙÖÒÑÓØÙÜãêñl_a^YTUY\^]Y[bjþäÝÖÖÒÏÓÒÏÒÖßêûiZWUV_gîÜÝÚÝåÝÜÝÛÜâÞåïìðõøkm|pyñýrmgv}rxe^e_\[\UQOLNPTWONKHLPRYhôÞÚ×ÔÔÕÖÚÚØÖÓÓ×ØßÞØäùîýyúie__c\Z_ehüçßÙÛÕÔÚÚÜÞÙÛwe_\ZSSY_nøçâÙÛÙÕ×ÓÑÓÑÓÞàçíçíxþóîèî÷ýoh^]^\X]]VUPRQLLMNORQNLJLLMV^nìâÛØØÔÒÓÑÏÓÏÎÐÒ×ÓÚâàî|}ønc]`l_`iaajqòèßÜÜÚ×ØÚÔØàçlmtfcblxûúäÞßÙÜÝÖØÛÙâìöfýõjoønöêzñy{ñghòünÿkgm[\VNQOLPNKMLIKJIMMQ[YmíìÙÖ×ÎÌÍÍÐ×ÔÙÛÙÜÞÝáçáëìîróÿmëìðçîøëãáâäãÝææåü|g^f`^fjkulréáÚÖÑÏÎÎÐÓÚÝåéòqnxvÿþúòùõzlnh__`\\WVVPMMONNKJLKNNMRUVWVXjoûÛÕÕÎÍÌÌÔÕ×ÛÖ×ßÛÜåäíÿõoz|eeöôûéñãÜæÞßßØÝÚ×Úâçèéìsfxwyj[hwvøèÜÓÔÜÞåíügsùxdoéìð{õéêàíîÝäó{úîøoc]VOOLKJIGDILJKLMONMNV]e{ÝÒÍÌÍÏÐÒÚÛÙØÔ×ÛÕÔÛÞéîäçñ}êäðóàØÛÛÜèÞàøÿ}øydhüûlfgb`_^\iêìßÏÌÍÏÑØÙÜìèäâêöíäåôuvxz~ôüyvdcnkje[QOOKKKIGEIKLPORPRVZ^jîêßÖÓÐÐÑÖÜÞÝßàÞÜèççêåvzõÿñtðíèàÞ×ÓÏÐÖÒÜëàåëèìóæßôç}]fa[YbvòåäÚÛÛÚêñpkõêçäÞàØâpíxwýþzçÝïçä~æäôq^SLOMIIHGGIGGJJLIIMX_güíÞÓÑÑÐÐÞÞÙÛÙÞØÚÕÙíáçìÝóyïßçæÙèßÎÑ×ÖÛðÿwl`[hbnysàþtø[[]îhùÙëÕÎÕÐÞàéyyùÞôå×Þå÷øhaj\e{óxùþsìõ{zZ^TTKKLCIJFJHJLMLJZW^þ|ëÚÐÕÖÒÝÜØÙáààáÝçðüfõkbûñÞâßàêÜÕÏÏÍÐÙÒÙßëuolómyçíà}^lrliöðëØÛÕ×ÞÝâ÷pzêçéÜÙçìé{mgialçöwpÞâpäízugVOTJEFFHGEEDFDDFJORZnÛÖÚÕÛÖÚáßÑÐÞÙÎÑÖÚÚïmôönäÕÜæÚØÝÛÎÒÛÎÒÞÞÐ|[ù[Splcðí[yûQqãeçÓÜÓÎÜÕÖôÝÚxå×ëäÞÜßnn÷\[ñ__èüchæìllénXó]KOOB@PJAKLEJJEP\NjÝmÜÎïßÕ÷èØÞÔÐêÙÏäßæ÷ùcmêzäÍâï×ÝßØËÎÞÖÉ×êÍàZzñTXäqYhfPWliäÝoÝÎóÝÎp÷ÕrxÖè×ÎúßÔkqënma~ÔíyÐm_Öèfjãè[Y_LFLEAFIFBHK>EOJTeo÷çÕâ}àágãØÞÖÏËÕ×Íä}ÒvWàßåÜÕÓíùÎÜgÌÌü×ÇáhßßXXîdZèâSUýePøÓøvËÏhÕÌnfÏÞ[ÞÊâÞÍä_áìW\ì^aßïlóçsiûyYtß`XjTDMQAAVO>K[A@^ZDbØihÍßWíÏ]ZËÐlÎÂÞÞÈå_ÝÛUýÍáíÌÑéÍÊæÚÇÖÝËËßÚÖeaãúR|ÚVPv[MyðX~ÌïlÑâ[kÜ]kÐÝùÌÈçßÒù_åøYêÖnfØè^èÛ^bßcWàçJXqGBZP?LX>=RE=RnHSÒò_Ô×UpÌr_ÇÊ~ËÀøwÉáPÝÑ[øÃÚmÇÈýËÂðÞÂÖþËÌcëÏaTÚêNëÐNLÔoKßÍ\{ÂÚRÏÒJ_ÍfSÈÏ]ÌÈZwÈvLÖãNàÐPYÐ_IÒìDvØIWÕNHßQ=\]<Lo=;gF:bv?]ÊSUÈíJÖÍNöÂçkÁÏNÖÇP\É`NÈÎTÏ¿yܽÕp¿ÇiÈÀfÞÂaWËtJÕÚE\ÖMRÍjNÌÍXÞÊSXÑ_KÚÕXÜÇ{iÈÚ]ÐØNöÊ_WËúLÕÙHeÕNPÔ`IÛçFSoBEeJ<MJ9HY?Cì_IáÛMóÍ^[Ë×dÈÇ`ÕÆlcÊøLÕÕWßÊqßÁÐzÉÊqÎÄüßÂÛfÌÚNÜÒQ\×WKÜèK{Ï_dËìPÚàMkØ_pÈÐkÔÉþëÉé_ÑÓ^ãÌ_dÐmNtpKXá[QÜôOlmELmF@UL>IU@AXPJtòQjÙji×ÜmÎÌrçÌñ_×âSçÑZcËä]ËÆuÜÄâöÇÎòÍÄâàÉæ\ÕÖVeÛZPätNõÙZmÐzRâèQjÕ`hÈÖjÏËnèÌýoÍÔ^ÞÌ^\ÔoK_jIXãYSßõQhñLNrJ?QP>HV>?SMFcìM[ÔnZÐÏhÖÉzúÐçZëìOeÐnYÐÏ]×ÈréÅÑsËÃâÛÂÐnÏÍeðËpSáÜR]ä[UÜæOìÎTUÐ|MßÎ[öÊæ`ÍÍTíË|ùÆØ[ÒÌYhÕXKíxKdÕWVÐvHmäLJiL=L\?=OG<NiDLÜmMßÑcÞÂàcÌÎRðÐSNÓáWÙÍfôÄÑ[ÕÅçßÂÏmÉÃ~äÄäbÍÎQiÒZPÙøHmÎSUÒ{UÛÙPhÑ|_ÐÎcãÆ|YÕßWÔÆíïÉÑ_æÎUOÔwFi×KNÕjEfÜMEõU;Nw=<_F9LfBHØtKàÌYbÂÖZÍÈgkÎrGéÏQ\ÈäOÌÇ_åÁ×hÅÄiؾÚ`ÆÉbÛÀøPÏ×MiÎYFßÙH[ËüQ×ÑM^ÈõNÐÉXbÇêLÞÎQ÷Ää]ÇÅ]uÆkNÞçFUÑVIÜÜKZÒZDc\>EdC9LQ:?dNAnÝLZÎèWÎÉdçÃçTÕÜIXÐnSÏËfáÁÛûÄÄzÜÃØíÇÊïÝÅÕüËÐ\xÕ[PêeJjÞW`ÍÛ[ÝÑSZÏÿTÕÎhêËéTåàXiÑælÌÍpàÏþUó`HYóTOâmL~ßRQñMARR<>L>:NXFVã\QÞÝYêÊã_ÓËdøÑ]IûîKdÏ}]ÌÊôÎÀØìÂÉæǾÖÝÆÔäÄÅüâËûUçtFS{RVÔ×bÛÓXZÕõSßÒ\rÊØ`ØÛSfÑücÌÍwØÊùrÑíKaÛUUÛuNhëPiÞUGZQ=>I=;IHAUuLSäaQèÙmçËó`ÏÑS]ÚWMÝäSôÈèðÆÉèÍÂÙÚÁÊæÌÈûôÇÓ~ÐØVeßSDYVF]ÙcfÊÑZéÐlcÔèYåÓkõÌùYÝÚZøÏïvÍÓaåÎ~_Ù{MüãNPï\JköMS{N?LJ8>PC@\\JcØa[ÑÙ\êÐdjÍìRîÝS\Û}UåÛjÛÆàìÅÌßžÎ̾ÐwÏËåÝÉäcÐãMeøKFuzNkØmpÓßYÚÌ`YÞuRÙÛOgÏkMØÔZáÊãzÍ×[ÛÎ\_ÑáTúæJPÜXEnfCK\@;KD:HV=FôRKÚÞZìÌÿ[Õß\ãàSeÎíVãÒcøÇ×xÈÈùϾÏÖ¾ÄßËÈbíÅåTÒÕ_õØYPõ\M~àXgÌÚlÍÈùæÈþSÏÒYóË~[ËÔQçÉajÅßO×ØRmÕeTÙüLmqINßOCl`AP\?>ZL:HdCFëuVÕÎjåËx[ÕøQtôMZ×_Käá^îË~gÍ×lÉÁÓλÇxÇÆmèÊí^ÎÑjÝÏ\ZÛ_KtðLwÎû|ËÏ^êÔZ_ÔôWØØ]îÌøXÕ×gãÒjfÕåUíÕ_sÝcYíaLffGJ`O@PP=FU?<SQATß`ZÔß^ÙÍjñËìWÝÜ[ïß[kÍàhÎÎ^îËàwÇÇêËÁåïÆÐYûÓ^jÒë]ÚàSoßdPñý_ÒÓîÕÊqfÎåiÏÍméÆÜ`ÐÒXoÐüRæñN^wTPïpLgðNVï[LoZI\fIF^OCSN@LgJKØîQðÕZeÎß^ØÕU`Ý[MmfP{ÛeÿÖébØÒóÕÇØÖÁÈÚÃÄîÜÈßuÎÑlèËü`ÏèQqßZ`Øû]íéXvÏäcÍÉþÜÉâpËÛ[ÚÎd^ØmMxïLXæNKÞrNdêXWþQKWVAHYG@PN?KeMJå`FvÕZhÉÙjÊÅeôÉ`MÚßUãÌdxÒëeÓÕbßÍìæÆËèÑÌìßÉß\×Õ[ýÎêqÕïNèÎ[^ÑõRçÝ_ÚËçáÃÉáÌÌ}{Îß[Ü×QSçQFgYDNdJMíaJìÙOaÖbLr]FYfIIcMC^sKQêTKîêUæÉæöÊÏjåæN[Û[R×ÚNvÎkcËâOÚÆîáÁÍÛÄÉáÊÇÿñÊÛgÕÎdn×]TÛuIlîKRå_UÕÍkؾÕüÈÎ\ÛÆ÷vÎûS|êLU÷JEf]G_êLeØ]YÙwH\kIJdI>VW=LfGKtNIÛüNàÇÝâÀËøÎÖWùÍ_^ÏùQß×WvÎiSÛÝYßÈëàÂÕÜÄÍ^ÙÊaùÉãWØÛOêÎ[UÔöMæÖY÷Èàæ¿ÅÝÍÇsïÈÝ\ÕßNZæKGüN=PX?KûMLÞîUàÑT^Ö[MçjCTpCJ{MKwaHaáTdÕmuÆÏ`ÑÍNgÒSNÙüFqÒRhÎtRÝÞWÚÆî×½ÊѾÀÜÌÅàØÅÝmÎÝLnÓQRÚTEéìJ_ÏcgÈÖåÃÌhÓÊcÞÅy`ÊøKÞáFS÷BDíRBïøJ{×NV×TGç^A^j>Fd@?oO?pìGnÏ[_ÆÒmÃÃnÕÄ^WÎôPÝãNwÝQ]ÛWMäwQÝÑhÙÁÝãÄÎ{ËÐñÈÊzÎÎXðÊ_YËôMÔÖMëÌfìÃÙÞÀÑnÎÙVßÓ]õÕUNøVC[T?MW@OßNMÒwNÖçPÛÖNmÔLNèJE}WAoóDlÝG_ÎYhÃÛpÆèQÓyDñåHnÑL`ÌXTÒhRÍÚ]ÆÇsÉÀèÎÀzäÀùeÄÝYÏçKÙØJé×IfÑMWÈcVÃÓmÂÆbÐÉOøÅdðÃhSÏYCëW>nj?lÝGeÐLTÐPJØ\Aüh=Uü=GëDEÜQEÎqEÍÙLʾh̼^xÅSOÌhPÎnIÏíEÚâCüÐKæÁ\ô¾äp¿ÕVÅÒHÌÈUÒÄU{¿n^¿ÙRÌèNÌÍOÌ¿^оlßÀTWÈcVÆmIÖh=ib;Y^:PèBNÍPLÌVEÍd@Úì?iÛ?XÕFTÔLNÑRGÑ_HÎÛNÉÅS×ÌI^ÖIUÌMHÍ\IÈëJÎÏNØÃ`оôÓ»×äÀÜUÇáNÇÑLÒÏLÙËMåÈL[ËNLÆtNÁÒWÅÈTØÈMâÃVwÅ\OÏZEÜ]@ëb?cêG\ãNW÷FIvKJmPDk]C[çMZÞUY×jWÖÞhÌËìÉÌYÚÒMt×U`ÚVZØYYÙZSÜçXÜÒkÚÊèëÎíqÙúkÙÜó×ÜïÏÏÝÓÒéÝÚåáÞæêÏÔÛÏÒéßõ[iæYhç[fábQeUJ[WOXTQ^qZ[ø]ZcSX_ZYb[Riacòm`ôõ_lï^tæýéÒ×öÝöSi`Ufl[bìõ{înîØÞåÚÖáÜÓÙÙÖâÞ×ÛßÝàÞßîõñçáåêâàèÞÞùìçëàÚÛÞÖÐæôåçíßçrèäwùû_[ejbcZSTUMIJKNPNRXTUTNQSQUfi`oèßëëÛßÙÔØÚÕÐÜíéöfgza_wrisl]`ioúïûðéêýxwhqëÞÚÔÒÒÓØÜÓÕÎÖÚÞÝÖÞÔÒÖÕÒÏÑÐÖàÞækoyhmg`\gs_Y^VT^_d_ZXWOMMKRYZ\d~ýg^\]][jôqlzìýíüpëßåòåÞøk`Y]c]^degnvûóþéãÙÚ×ßÞ×çuõüo÷ÞÚØÏÍÔÓÛìñééççð{ëêuÞééÛÓÓÕÑãÜäzéêÚÚùàwúì`ëy_ýzxqmaOPJD@AGIMNOl]U_SOQU`lënðàß×é×ÑÙÌßÚÙóàehygnxzl_jhogemîã|yée_kYSV[iíÜØÐÐÍÉÛÕÐÓËÖÏØÚÏäÚÐÜÙÔÏÑ×Üîèõ_bmäpúòOnö\Tem]pù]hfWOJKIFMOR_]k`[ZeY[}úúíÚÜqãàýòÜæïáßdcaTXTae]icahnòlõæÓÚãÞãìwky]cuk|ÝÖÚ×ÏÚßÛÖÖÕÒ×ÙÙÚéäòèãßêÚÓåêå}nèÛçÝÖçoèápwçäïåîm_[SJECCDAHILMNNILPOPjíõÞÏÖÞÓÑ×ÓÎÐÐÏÔÞé~eaff`legbec[jlnãñeúiYXbWPYd[êÜâÙÑÒÏÉÌÉÁÉÇÅÉÌËÎ×ÙâÝ×Úâåézpahvj}ôsghkUXic]ûçýjú`OYUJMMMOTW]UKQTMOY`ýàÛÙÖÕÒÕâßÚÝáæ|vrh]XUT[aRadkkõë÷ÞÎ×ðàømõog]X|ÜüväáßãäþÞÐÓÏÏÎÊÒÑÕÚëwáïïäóýîçõxÞ×åëÞèÜöaóvþÜïöÞìk]ZOHHCBFEKJHFFH@EHDSlîÕÎÌÌÅÆÍÍÊÎÍÔêäÜãëiV[ZXUYVMV]\mtóäöw\d`_]KM`_lvòßÙØÝÐÍÌËÆÉÅÀÉÇÄÎßÔÖôèximmükdmø{dhîeXgWVjp}éßæéùmjgMIRLLWTHNRFGKMNP_rèÔÊÌÑÏÌÖÚÏØexîl_adPQPNWT`õ`^üÝäÙÎØéÛÝ÷m\YZVh``ìâéìäÙØÍÌÉÉËÈÌÌÊÎÖ×Þàdbzhoòjùâåýïæûù|gnl^ñàãÝÑàøßZHIKFALLGOGFH@HAETSzðÏÉËÂÄÃÈÌÑÜÝÛììîsü^^]OSXNW[]\zÞéÚÖìàõWYRRO[UWëkëÚÛÖÛÈÍϽ̿½Ð»Ìʾg½KåãEÙGÛJl\öeêamdOâIãMÕiâÏëËößfQ\LMNKSLSRSMNJHPLT_yçÜÍÒÕÆßÒØZÐYôßMÏBãXMúGäKéZävÓßÉÔÐÉêÎSÙH]WLcLf\cêjêÞÙÍÔÉÌÊÊÄÉÈÆÏÍÜçlb{Z\úTÞñgËTØw`ÎCÊTêÚ}ÊiÌúÙRjGZ@RNDM?ò;UDAM@VHRíUÔÒÕÇÉÅÊÉÐÒÛÝãé~gib^OUN^OWkWìlÝÒnßÍMÝðAÐCHÛ;ÖJPÁ?Âþߺa¶ÕÁÂ̸ÒÀÈÄÍÍüÓ]tYS]IëRÛ[l\hh_i_éeÝêéí×Öøùd^aH[a<tPAØ<Pi<Î<VÝ<¿GÑÊK¸Z¿þæÈNÖWçXpîæLäKù^NÑKÉcÈßÍÕãËeÎOqfHå?SRDÝM_éYÐáëÄïÊÃ÷»×ϽÜÄËlÇëPÃCØÜGºGÛÏD¾GoÌ=¼OéÇ?¾FÚà?Ä<cT:×4WR9Ö4ßEKÞ=ÒIÞårËêÇÑÆÏÌÉóËhÛã^ÝðñnU]^KpVYæWÚùZÛj\ÕDâo=É;lf:È@}ÎCºaͼT³íĺW³]¾¼M³HÉÛ<½9Ò]EÁ:ÉMR×?ÐJðölÕ\×íÏnÔýùÝJßC]QBã=\P@Ú<÷[?È=ÏlJ¼I½èë¿QÉVÞ{_ØgÓdÚZàUWëMÕUÙÚWÊSÍÞNÇDÝW?É8÷P>Ê9Ë[aÆV¾öËÍÎÇàÅÏÀÖÂÐØÌZÌUäì`ÆNÏæOÈ@ÓiDÂ?ÇoI¾?ÁZ]É@ÎG[N?T=P@JIQIN_NkM×]wÓ|¿âÈÇwÅj÷ÉKÎÚP¿KÜÙB×HUyJ\ÝXXÕPíñOÞ^LßOOÛBäxEÄQçÆS½Öæºc½Â]³ð¾c»cüÏcrÜ_fÎNðçBùQCÚFQÊCÓÙJ¼Qð½@ÇáH½;óÞ5Å8På2È:Zá7ÄAjÓC¼RÊÉP¼AÈåE»>ÄåK»EÏçIÎLWÑNÚÜJÂLíÎ?ÃCiÔ;ÁA_à<Æ>ìèE½@ÆÒOµF½Ås³_½¿w¾çÞÄ^ÊÊO½NãÏ;À?OÙ9¿A^È<ÀAzÊ;¼>ÔÐ<»7ÛL;Ó0Ý>Jâ;ÊBÝäO½M¿Ñì·JºkàÂBºJÍØOÂ>ÐXVØ<ÎGZÕ@Ä?àý?É>ËWZÌMÆMâ÷XÙJÐfÓÚ_¿[ÆÉ{·÷ÀÀh»}ÏÌeÊýÝrÞlYñ>èKCà:áPFÅFÚÎJÄlkÃpÞÆrõÔEqg8ýC>ê:Tw:î`NÉWäÅ[ÙÌLËÜN¿YmÄGÏéHËM[ÈNôÖOÊÚIÅ`QÆEpËFÎÏBÆZ?À=OÊ8ÌÜ@»Hn¸DÀÃX´ÚáµkлU¿ÄH»úM¾=nÌ4ÉM<¿;çÎ9½ZF»?ÕË<¸ZP¼9Ïa6É6Re8Ï?hoJÈLÇÜݽX»îd»EÂÝL¸EéË<ÃHDÃ:ÜiA½?ÚØAÃAåüCËFÐm[ÂDÍWTÇ=ÈbgÁCÄÖ]ÀnÍÂýÃËðÇßÚÏí×òâ\hñBlFK`:äHUÝAÄj[¿]ÌÊ_¿ÜÿÈ`ûwMSLMATK=u?[_@ÊLßÒS¼SûÇLÎõWÊkgÑû`Ù`ZßUkÙt}ÓÐaÐÚVÒ`LÖjFØjHÚZKÜNJÜQMÔ\`ËaØÆíÉÄÎÌÅÌÏÅÌÙÂÓ[¾çMÎNHv@DáCIÏJUÅOØÂHÄÓD¿rKÇCRÍ:Yf;ë?BÔ>eÜEÆ|o¹lÏ»TÌÌLÁpSÃVvÏEðß;ó]?ÒGZÄ?×ÈBÄ_PÆ>ìÐ@ÏdTÇGÚÚJÊLqÎIËrêÇZÁÒÔÄ|¾íÝÂ]ÄòmÅNëÝEáFEx:bTGÖIÖÚõÆüÂÐóÁ^ÊìSÆJ_{?~D?g9PQ?ÚFüÓLÇúÞÇYËòãÏVÊ{ÞÜXÈXdÒMêùUÍý\ÉâhÎûoÚSdèMUûRctLz\LoRbWUÏmjÉØÚÆÖ̾ì;ýÉÁlÅË[ÔÝSaxJK`FL{FOÎlWÆÑ[Ë×TÑìLÑôGàhBVU=RQ=gvGâÊ^ÒÂ|ÕÆr{Ä^aÆ_XÊ^XÏUOÖZGÛaKÚiNÏéTÎäNæÜIjÑKíÓOÞÏJfÏLMËPY¿Sø½bß»gñ»UÛ¼JÏÅAÑÜBÑWBØI@ÖEKÒ?àÒK¿Ôà¼jÈÅNÈï\ËKîúDjDGJ>\BOñGÖ^\ÃPÔÓNÂl^ÅXëÏVÞÍ_ñÉ]zÆWíÊSèÎ^mÈsMÍWGÜKNÞOhèPüSFãHGÏNnÌdÏÙïÇçÍÊoÀÍé¾ÚÐÉ~ÑïþÝZÚUNÖFf`DÛJmÍOÊãSÆWZÎRyÏ\aÝIKî>GwAXèVgÐÝ`ËÓRÍÏ^Ý×nûïßhjÛZn×YoeôfH×^IÈìRÍðMíõL`Ñ^\ÅçXÊÝHÞÝCëÈMéÂWd¾yR¾ñM¼ïM¾êKÂÝIËêIË|J×gHõjHòéVÏÝxÌãààeÒúeÉnUàNLPFKGSXIh|KøØReÑtfÍâUÏÛPÍÌNÓÀZé¿ks¿bNÅxJÄÞAÌè<Úx<ßáBÓÍDáÛEkuIsÞWîØ]ÓÞ^ÊléÅ_ÍÊpÅ×öÂálÇébÍaVÏTOäMNàYUÚfTÝvUÝ÷XÕþÿÓPénDéLKëJbäL}ÐRuÏQçÍRäÐOìÏ\åÍbæË{çÎlñÑVnýTÓVVÕIo÷GðeKßÝ]ËÐXÌÝMØôPÖæOäáWÝßVãÞ[ÔÖcÐìõÊ[ÑÍ\ÌàfÕxeØhQâ[XØXýÕPêÖVqÚkoÎîkÐþQûlGTïJLÝTIíeMnï\aÞõ\áÜzÝÝÔÛúÍÙmÏÎëßÍytØ]YùZG\dCWtIcÖeqÐð^ÿé\WÜøSìÜkWìÚSmÐzsÐÏîÏÄÛàËÐ_ÙÉMgÉZSÚôMmòJ]êJOáQJßkNÛÔ_ëÎñmän]_heXhÞhOÚêBÞÑHeÑbUÌÔZÔÓ\ÚÍTiËbWÏå[âçR[iVPUXOOYÿgzÇõe¾×PÑÎU]Í]NÍìJÜæEoÏIuÅUü¿ÜùÅÞWÍØGÙÊHôÅM^ÆOWÉKOÊPKÊVGÍdUÊe`ÉwWÕûLåîKçwEÚü?öó?wßGãÎPÒÀ[ø¾]WÂmNÅÓSÈËMÒÈE_ÌJIÛQ@þ^DÚÛGÎËKÒÍFûËJhËKpÉJ^ÌJSØShÇíÛºÍã½Ü`Å_KÏ[NÊpKÏìCèàBhÝ@[ÙBTÇTMÅÜMÇËOÎÛLÏÝJÓÕIßÑGo×A^ÒBe¾WrÁmiÐW]ÚNOÌ^PÇ|NÆøEÌæCÙêA{åHîÛWÎÌYÊÂJäÃJbÂMXÉYLÓcAwv>fÌNß¿`Ù¾VyÄNMÇfMÄôMÇaJËõFÍßFÎíIÍíJËÖKÏÊIñÍJbÑN_ØISÏNIÑN@ÜVJÊÛWÁËPÅÐLÏÜJÎÏRÉÌJØÌIíÑJwÛBeØAU×OV×jXÓeNÐkMÍØLÙËOîÎIjÛDgÏVìÁÛæ¿ÑhÈìJØéGØÐGgÚH]ÙFiÖBdÏGSÊQQÆh^¿bZÁ`KÄÖLÌÕKÏÎGÜÎ>[ÌANÇURÅõPÇüFÎ}?ÞÒH{ÍIhÇMZÂVLÂôFÍàEÓÏJÏÈLÖÄJfÀTQÅXMÆ\IÈ[=Ú÷>tÔHxÆUæ¿[`Â_KÈÜJÎÒDÜÐCáÈIùÃ]YÆêNÍÞJËÕHÎËC{ÇLSÊOLÍ\JÌmA×ç=÷ÍCnÄQíÁTnÂaOÆÒKÌËGÕËHêÉF^ÆNKÉXCÑvEÒÝDÛÍCxÅI]ÁQTÁi\ÃoJÎæAßËHóÄZúÁslÄoNÉÞDÙÎAYÏDMÑHLÉVHÆãHËÎLÐÊPÓÅLèÃIYÄXUÈüTÇéKÍá@Ü×>gÍD]ËLVËPLÇxEÊÕBÙÌDëÇFrÄI_ÀOIÅoIÅÜJÃÚDÊÎ>ÚÈBxÃJnÀMWÁGFÅM?ÊfAÊßBÍÑBÎÅFØ¿LfÃLOÅMLÀcIÂÛGÇÌHËÃGÒÂCáÂAYÅFKÈOJÆ_HÅí@ÍÖ>äÎ>íÊAvÆA^¾SU»êT¾ßIÃÚBÈÒ?ÓÌAíÍB\ÈHVÄMJÃW@ÌlCÇáFÇÑHÉÊGæÉK^ÉLTÄUNÃZEÅöGÉÓKÍÎDßÒ=_Í?LÆNPÂRN½nV¼ÚNÅÎIÔÎEÜÊGêÅMk¾^\ÃeOË_EÙ\?èq<qâ@oÍFï¿QeÀXRÃxWÅøNÈãGÔÖIÙÇRùÇZ[ÎQKÏ_GÍÛIÓÌKäÍGgÌEMÏJOÈYHËjFÊßKÈËNÊ×GÌòAÈ^DÅXYÂMñ¿IÈÂG¿ÔEÂIKÁ>çÊ:ÄhFºHu½=ÆÙ=»EO¿8àá:¿LL½?ÊÄB¼ôI½H[¿DâÅDýÙBìÏIÞÍJ~ÐKVÛPTÒkWÌÙ]ÕÎVqÊmPÛîKjÕYU×|KdÝPWÎÔUoÌgHìÓJFÐÝDgÃÿIɽbY½ÂK[Âu?ô¿dEÓÄSGÍÅSNÈËIFÎÐIFØâ?EØâ@JËÌMUÃÆQPÉÉURÇÃZHåËaMÞÅòJiÍqEVÒâIPÏÎZPØÍfMîËsHOÚëJOØÐSKðÐhNáÆÚVeÐÚQNíÖgSrÖæXvÍÌöhÒÌñQlÞvT[ÞÝ^YðÛ{bçÎÖÿyÞÙý^tægQVklWYåØïlèÙâ`_òë÷oýätY[òík]pæiU]òækcßÓèôÞ×Ý÷úßÝxfgwv[Yh~jYYdkZhúö|gmtjZ[jntavëõìàÕÐ×ØÓÖåìèððùýîõîþ~íçåæãäç{jøþl[[`ZUS\ifjuìò÷ããëìèÝÝâëéòlnó|mrûujnz~ý~|meûîxwóèëw{wtkkhba_ckbkl{ðéì}}üpe^`brunuüøñáßÝßãßäêéæîýðøq~ïüs{íàÞÜÚÙÞÝÝßê|u`ZZ[]_jirp|ôý{{rir}wýljrijn|òúppü}ûéèðóïäåèââäìçåøpzñrbmnf\\``X^mdZ]ea[[[dccijnzõíãÜÔÑÐÒÖÙÞáàÝïmîæï~îêäßßÜÞàåæëöÿm_XWXRY_jc]k~vquìííáÞäîëòxvnþóøìïòzøëîrknjfsp|úùôûrpîõxmmojitqqkrtneed]_k]\gpjcfs÷þóåÛÜÜÙÖÝíêîqfmÿôôéèîçÜÖÜß×ÕÕÜØ×ßønn`ZYff[\cfiquhmp}moulaa`hozìèéîïëèæwûïûóíèéááæêôîtzýyplluþh]gfaVTWROSUXV^ie_embiïíá×ÎÍÏÏÒÕÚÞîrmxåàåáÛ×ÙÚÞÜÛãèçíðîþh]YUV]_Z[Z^nnfûßáêçæâòþ~rnzïèééëôýíühjprljnúþvýþmqrsnm|zu|ú{o~yôo`]YWWVX\`_ig`dhfjqæÚÞÚÒÚåêåðld|ñïßÙØÕÑÏÏÓÕÏÖÙØ×ÚæëîlYW\YUSUYXXb_dwÿþôzwmddhj~ôéäëôéäûq|îëíßÛãìáàîûôüj^jh``lte^exg]fZQONQQOUaa`hvuilîêèØÍÍÐÓÔÕÞîêóúèßÝßÛÓÐÙÜÔÚæçßàzi}û_[`^[Y^ZV\c[\jñêãÝÙÚìûø÷ú|òäâþzòúnhjhg}ðù|ûútlo{|gnÿj^b|üpx÷íöñë÷lhfUNSXWWde\[hsegvúñäÛÛßãèúü}îÞ×ÖØÒÒÏÌÌÎÖØÕÓÛßâçÿhhnjfmaUUY_XXX[Z]vö}ÿÿdgn~éìòíôùíáähxynîÞßÚçõçuixpîÿgb[^^be\dmzogpc[WRSU\[``bb^uôõóüæØÛÚ×ÐÖöqêâëÜÑÞÞ×ÏÖÚ×ÐØãÞÖâõzmfWV]qm_bikZ]imcgyýúìÝëzóÜçíßÞèxõåk^lxbZeùö{tïxa``yyzîíy{ê^fñ~åjoßä{uøhYS[cZTYjfNXmbe\næïÛßßhWùzìÐÌØÕÐÍÑÕÎÈÒÖÍÌÐÙÕèl}]ljW^aWUSZWUUlaSN_}b\p{XpÙÞtòÙÐÞj~zspãÜù×ÜáÍO\ÒáV\ØßàãVOkdZV^eòj[ðmTSke\NiémhWXw{íþdoéàëìÚÛÿöéÖÒòàÐÛÝÌÍÎÒ×ÕâéÙÚo\ù|ú[]ïm^lu÷_^jnian÷xol~x`ýèxkæÝuùsþüZd÷vaàvbipéxYnç{méÛïhn|}]dixvüwtvfnî\Wùic_V^aXTlk[çæþr}úøvàéÛÐÏÌÌÎÉÅÈÊÉÊÒÖÕÕßòäÞóf{ó]V^`YW_j^Z`^sbZ[T[XU\^ÿððñèíïúmïøùêß×éæäîæwwgbjjûnijwfg_\]TUZSU^a\YY[cd_f[bdj{srjrðopzíýqèÝÚÑÐÑÏÎËÇÉÌÍÏÏÚÚÝííùwöm}îro^jðçáynkóénhbodMT^_\_wnX[nt]aoïçàÛÛøüòæõjl}õhlzáóçâÝáj~e^]bmbe`h]X\ZSSU\]WX^]gj]Z[c^SbùïÿÙÊËÎËÄÊÊÉÇÇÇÑÏÙÚôþØõûñ÷è]Nkökrîógdún_^YaRKLVTU]k`eÚäkoÛèÚÏÇÌÐØâÚßéôäì^\QTcÞ~uùõáêPYv[UZw^TYNUVdÿ^yfY{nescüZtjRYZ[öÎÎÐÉÇÌÏäÎÊÑÖéÚÝúsmwxd^ßô`eXàvgçßñäëèfYmf_dob`XTb_RYYlSVklÙÐàÐðßÚîyUð[W×õÎêÏç\ÖÜÓÞÚÜâhÚçnj_û^[XMO`J[cXoXp^SjW\NLTZzàÜÔÊËÏÊÊÓÐÎÍÓÕÙÏÓÓm_uhë_YPQdXphexgýccjVN`aU~Ygjb__wwikpjãÐËÌÒÇÏÚÖîòÛðéÝçÞàívø|ríjòv`dUd`V\Z_[X^Z[\gph`øa_ymml_]]`oâØØÐÒËËÏÐÍÎÌÑÒØÎËåñlxìåðílpÿmòôëõéð{jgiVPPPOR]VU_[d]]\XVféåÝÚ××åæÛæâóöÚÚâæìÝÝõ|æ×tö{p}^k]cTNORORMRYXS[f_ZVd^ZZ\W\aýãæÜÑÒÕÍËÇËÌÈÎÏÌÌÖÔãàÜâîççnq|tþl\ûandl}nZ]WVfbggkbpuûj\iòöðêÛÑÖÝÜå{íõûsnøçëùnüìuzvq[]ho^U^[WX[Z[\WU\\mýlpkfhjm`ZXX_tõåÛÝÒÏÙÔÌÈÎÍÌÍÒ×Ø×çïéãßõøêvihmtþ÷qüêüwqm][]_^^ha]dd][W_^\c|þîçäæäßãððæéðîßßãåÚÚâçäòrjeb[YZYRVYVRLKQNOY^YYX[^TUXWZ\zðæØÍÌËÉÄÁÁÄÄÄÇÈÉÉÑÔÙØÞáëýyqf^]]bc_eqfdd^Z[^fh_ihkccgrgkóÿütêâæíÞÚß~öôf_l÷pjyééóûçìj]_[RTTUWZX_]_XZcejoupjfd_^Z\Z\`cjðåä×ÎÌÎÌÉËÎÒÎÎÓÙÒÒØåÚÚíwôêygmûqgtîñwzûsmirmp^Ycb]\bfe`ikkkqvøíéßßæï}vþpwòêðîÞÛßçèçú^]_[RNSVRPYZSOU]YV\]YUVWXXVZ]c_néÚÒÏÉÅÅÄÂÆÉÊÇÍÌÍÏÏÞÕèøë_js]m\WpfbZh{`]dr{iqzug_kma`vÿtp~ðèíêÞæéäêóneiecdiyûpñêìíøÿmb^a`[XX[]^]jkhe^ji]^a^TRVURMSWUZfìÖÓÍÊÉÊËÇÉÌÍÌÌÎÎËÍÑÛÝÙãûõùzmjuöùkyútf_jrgbc_^ZX_c[]iknktíëõèßáåõúûnoxý÷ýöìëýïáïù|~q^]ff[TT^YWanj\\^aZSVWTQPTWUQQ\ijîÔÎÎÍÊÈÊÊÉÈÊÎÍÍÌÎÑÑÚãðöôþt|ýokssh_^eb\alma[goc^qrgc]oxxøæãäëïçìvmiihhuõúøòðïðòñývvqpnmmj`Z[biwzÿùi_bg`XTUSONPOLLR[fuáØÕÑÎÌËÊÌËËÎÏÌËÊÎÐÏÔÛÚÝàãéêêõø{jhbZ\a\_\WZZ_d_`ghb`\azsòæçáéìæíøýûóûýúæåìéîõø{{malxpg_^YTSZ[^eljf_Y[[WWNNPNQPQ[_mìèÞØÖÔÍÍÊÈÈÇÍÑÎÈÊÍÎÍÐÝÚÚàãêáæðúmeb^_Z[_^_[_ejiprjdfc``ejþìñöð÷üusrnnfflwùìãåíp{ótjhtìóý~wk^_fohf{njdbg[YUQOOQNLMPY_mýêçÝÙÐÍÌËËÌÎÍËÉÉÈÊÉÊÌÏÓ×ÖÕ×Õ×ãùtl_[[\ZTRUUWUY[b]Ygkc[cxüu~ôóò÷íÝêçí÷ø|èææáàæùuöngaerýla^]VQSX]V[^e[Y[`ZSRSUPSY_^fvííîæÙÓÕÏÍÍÎÏÐÌÊËÌËÌÍÒÓÓÜÝÛÖØÞàèümjd\WX\_\]cngbdzq_fsyorúìssxô|qlzûhgm}z|îÞÞÞæáòiegnpz}üzlgjfe`\]_aml\[WXROOSQMNZ_]^m÷pöçØÕÛÙÓÒÕÓÎËÉÉÉÆÈÈÊÌÏ×ÙÒÓÜÜäízf_[UVUWVVX\\X`]a\_lndmmlkmu}÷no{ï÷|úëïúéßÝÛÞëìncapf_eef^ab_ZY\_^epn\WXXVUVZ]X\kzlyùïòóêÜÚÞÜÖÒ×ÖÏÍÎÎÌÊÊÎÎÏÕÝÜÙÛããßç}hed^Z^ccZ]cf_^hwn]eîîgl}ýjgmz_Z^hj]dzøùóãÚÛÞêêi\dslbeqþghms`Zbufcmp\TXZ]SPWXWX_rhgjòìxvëÜîõÞ×ØØÔÎËËÊÇÄÊÐÏÍÔÚÚÖØÜÞßá{jljd`_h^XU\c\[hr^`þïkcgûûim{nabpþmhtðöþëÕÒßïì~b^_a\XZombakh_bníp`]`YUV\VLMX[\]axwsóÞèëëáÞßÞÖÔÛÚÕÍÌÍÌÉÏÒÑÐÑ×ÛÖÔÝãàßïpj|omgaa[UZca\[ckvsýöxk{÷pfmsejmntqkryúèÞÝâì}ürdZ^d`^jxijkqzoqïón_b`]YVROOOWYXWbn{ýìåçóöæáãæÝßÞÛÏÍÍÍÎÎÏÑÒÕØÙ×Ñ×ÚÜÝèôxþóülenf`afa]Z_cgfcgknjnp~rdhrptljhhxúêçâëæçç}mkea]ds{psw~÷í÷þnkcfc^YUVRTSYXUX\`lôáäêÝÜÞßÝÞäñäÛÙÖÏÍÎÎÐÍÎÏÒ×ÙØÝáÙÝíw}øvepöt_hji^\ba_^dg{ggjkhjojnnmvjcfdmeoóì÷ïèê{fv|gZdpieegüüx{÷înlúw[Y[\OMR\YV`enm{æÝæêßÙáîêãîwðÞ××ÓÎÌÔÒÍÌÎÖÕÒ×ÞÛÙÚìøîõkv÷éïvvðó`]bgYTaþp`bvj^cý÷g_a`[VYceaeóåíìáÞ}nyôpewövanõónnþùqrtîkVRTSNMQZSPVacgnéÜåçÚØÝîõéqjòÖÔÒÎÉÇÊËÊÊÏÕÛÔÕÝãÙàqgm{few÷lejpc^_e\Z_nýjdeÿymnìïwkjj\Z]kjksëáÞèãæ÷qhwqiuûgdn{qqisõxvwþdUOTRNR\e^YarlwïéñéíæäütjiiréÙÚÔÌÊÊËÌËÌÓÛÚ×ÛÚßÞé}oy|xúãåþuvuff`^[^gsh^_gnjeiþp^Y]ZTW^f`lóäåëêêønlyýëæçæüöðýlevòþrom^UQOPNMV^_]`s|ekóóøíåëõþóþwíâÜÏÍÍÇÆÈÊÌËÏÚÕÒÙåãäé{hnnkorúókhuna`bdccii]]`bfei÷÷riji^X^lkiïàïþõîxifluøîååëøÿ}lc`qxjblg\XVVUXZftro}÷|aoñôúróízo÷ûxôàØÕÐÍÉÉÌÎÎÏ×ÛÔÓÝàâåð}ìåéîðççíûyzi_bij`]j]SU\^Y^`eghika[WZhmüîéêþvúüqxëççÝÙØáòôôqhmùk]cc[UTURQUZ`hux{xlghpumýìùlûçêêßÙÐÏÍÊËËÏÒÕÒÖ×ØØÜêúñövýïöþúñìøx}oc_d{oa^b_Xegeb`ùëíîõtma\`ddn|{l_`c^]go÷îëãåçíxtsjhmqaZ[`_^`^_fs{uzîöxpkixù|skpeiøïðìÝÔÏÎÎÍÏÔØÙÕÑÐÓÙÞåäèååçåãÝáðêíxjng\[^i\UWWQUVX\^fu{þzec_]]iuú÷ðïzsññ÷ìêßÚÞßÜáìwuwkh_[ZXTXYYXZ^]eeeupjqt{þèë}opûøñéÝÙÚÖÏÍÎÑÔØÜÛÞØÕ×ÜÛàæìíóìèëçæçìèïvbeed_]^aZYa_`jyswlpqlp]\Y[]`fifdcb_btüúíßÛÙßâêìüyýzd]]^`[^aliihmmorpmeoúõhoui_^djnýèßÜÙÐÏÏ×ÚÛÚÜÚÙØ×ØÓÕ×ÚÙØ×ÝÞÜØÝäóóþf_^`XRVZRPWaeecd`^b^\W\`__ajrmmpüï}íäàèãÜ×Úäëëüdcb`[[[WRVW[\Y]chgifrxyþèò{nü÷hnèÜÛÝÛØÛÖÒÒÚÜÙÝèçâÞàåÞáÝãæÞÞéìßÓÖäîðèyhed^]_f_foûóüö}j_\WWUX[[ZWV^i[Ygôüz{àÞãÜÙÝãççìnmnrkyjoj_hph^amta_põnhjýn_\b\WdtíïñåÞåÜÛØÙÙØ×ÙáßÞÚÜÞÚÐÓ×ÖÔÕÛÙÒÖàåìêma^\ZWVVZ\]bpki_eZROUTTX[[V]foi|ãÚÛÜÛÖÙÝÝÜÚäëï÷l_^ing]ai`[Y[Y[_d_dksqr}}kccdhfzíàßßãÚÖÝÞ×ÔÓÕ×ÖßèëèøïêãâéæáßÞÛÛÙÜââàíxa`eb_fmrtr÷ò}kgYWUUVRSTPOW[[\kñèçßáÞÝßâßÛÞáëíúpk}vuzúùuyle_jiegmpnjnoe[XZXXZfopwïçÞßÝÙÖÔÒÐÎÏÚßÞÝéäÚÚÝÜÙÙÛØÓÕØÙ×Þéxe][Z\Z]__ntj^dc[SSWUPOUXPPYb`^ùßØÛÙÕÑÖÞÚÙÛãêìímeilf_g~viibZY_bf]iýûmyüu^W^ad_k÷æíñÜÖßÞÙÓÓØÖÐ×èèçëuxêàåíåÞÝßÞÔÏÙØÔÖçlbj`X]ms{óíétnofZWVWRMNOMLNRYY^ûÞåìå×ÖêäÖ×àãàÞîrûôüõïæãí~uoef^jiaktj^^_[ROUZVZa|{qôßÝÝØÑÎÎÐÒÏÕÜáÜÝàãÜ×ÜÝÛÕØÙÓÎÐ×ÛÞög[Y\VVZhimjmf^\]ZVRTZTPPTOPT_lsùÝÙÚÜÚÖÙÛÛØÚßìôózjo~{|uwpi]`XXWY]egnqdeY[Z\W_^bm{îîïéÛØÔÓÐÐÑØ×ÚÞâæãçìïçàáçáÝÙÛ×ÔÐÒ×Þì{de^bgn~ûíönie`_XWUUOLJIKKNTZ]alúõ÷òåéààÝÙÛÚßéëãäæâÞàáîæìqnc]Z[\hlh\ZZZTX\Z[\cfhaqýõäÝÖÏÍÎÑÑÓ××ÛØÜÛÜÞÚÙÝÙÔÔÓÕÔÒÓÚçvlg]YZ__]\c`\\_\\ZWY^WNMMOOS[enøëçåâßàáæåâÜÜßêèõýéçééèê~lke`ZVTV[]hg``cmpeiwnejsqmuîììéÜÕÓ×ÛÕØßââåêîææèçÞÞÞÛÙÒÒÓÑÖÚÞîííufoþrggtvlqmhc\YWPJIIIKLQ\_bm}þ~üñíôèÝÚØÛÚÖÚáÝÚÛÜÝßæòôíýeZXVTPTXXVVY^\X_j\W[aicd~ãßÛÒÎÏÑÓÑÔÖÖÔÒØÞÜÖÚØÓÖÙÝÚ×Ûåëçïregh^TW\[Y[hk^^opnh_[TOMOSWYex}}ëâé÷üðîëêââãáÝÝßççåíûÿðó{zxk]Z]\XWZaceblsmbdnd]_ppkxèâààÜÚÛÞäâÝÚáßÞàãÝÙ×ØÙÕÔÒÔÖÙÖÚÝâèòõ÷njhnullqkdcd]\VONJIHLOQRW`ehgmon}êæâÛÖÒÎÐÔÔÔÖÝÛÜÞãâÝäï{c[XTTQWXUTW\[]Z[XXYZ_epýìÝÚÙÕÕÔÚ×ÚÖÒÔ×ÙÔÐÒÑÒÕ×ÛÚÝÛÝçäááï|}sefefgfgcbeibaa]WXWRRSWX[`dftrtrÿ~ÿòúõïáÚØÚÚÝãäáåêêïøóñþymf^]][]^^][\`b_[^^[\^nu}÷àÜßäÞÚÞãßÜØÙÛØÓÑ×ÓÔÖÚÛ××ÛÛÙØÛÞÝèóøð{r{sqng^]ZURPPNMMMNNOTXYW^`hgcyëðêßÚÞÝÔÓÒÔÒÖÔÖÝÜÕÚàéçñhcmiXXX[SRTSOOPOQQOU\UZmæåéÝÔØÚÖÓÒÖÔÑÎÓÓÐÎÍÏ×ÖÓÝÝÜÜèåÞÞîõó÷útkm~lhdh]YZ`YOPUSMORVUYY[_can{meüßìôìÜáèÜÔÚÞÙÖÚÝÝßßäêtzò~k|yf`g_WTVWQSTUTTVZ\Z_möü|é×ÛÞÚÖØØÖÔÖ×ÔÔÏÍÐØÏÏÔØÓÒÚäÝÜï÷âåü{uýjjcZX]XRTQLLNLLMRSQU[YY_hogtçßááâÙÕÖÜÔÑ××ÖÒØÚÚÝîðvmlni^`b`ZZUPOXSOPTPMPXW[kuýöäÞØÔÒÖÑÎÏÕÓÐ×ÖÐÎÓÔÏÏÓÔÕØÙÚÞìêëûuþriinb\[]]]ja[WWTOOPORVSU^c\]fjfyëæóñèåÞÙÙÛÖÕÕÛÒÐÚãßærwûskhga_ib\Z\WUXZVTTPNOZY[køp{æÛÙÜ×ÓÐÓÕÕÐÒÚÛÒÐÒÑÍÍÔÖÓÖÞÞâîúøkekl_^d^Z^n`]bdYTXWNNTUPV^[]_^[f}þôßÙàåÙÙÞÙÓÐÓÕÖÖØÚâðíñkgqh`^^\[^d]]_YV[]VQPQOSY]eõëúéÚÙÚ×ÑÒØÓÏÑÒÏÕÙÔÏÐÑÎÍÔÚÖÚáãæþsvl`_i`Y]lcaqtff_XPQQMMONLRVWUXY\ctóïâÝÜÚÕÖ×ÐÎÒÒÏÎÔÖÖãþñëuuûob_`^\baVVZTOVYNIMTNMY^^móîå×ÚÙ×ÒÒÔÏÌÏÒÏÎÏÎÌËÌÍÍÓÙÙÝëéúkll]Y`d\X`h__ig_[XUSUQNPSOOZbXWcidtßÜßÜ×ÚÛÖÕ××Ô×ØÔÓÚàæõkx÷wgkla^gnd_]ZX[TRWWNNRURU^gmüëäÝÙØ×ÑÑÔÔÏÎÔÓÏÔÙÒÍÎÐÎÒÛáßåôìønmlebl}f]mze_lhYVZVQONKMONP\`Y\jznñÞÝàÝØÚÛÙÙØÔÓÔÓÐØäãå{møîohüþihnc^]XRUWPMRULKOPMP\d`{ááÛÒÎÐÎÌÍÎËËÏÒÍÎÓÎËÌÑÔØãõõsdgkcgz{ihla\en`^e`XXZUQNNNRXWXgpfmçÜåäÜØÝÛØÝààãâØÕÙÜÚÞï~úmdkypoü÷i_a^XZ]XX[XSTWONTXVV`ltîßÚ×ÐÎÏÎÌÌÐÎÎ×ÝÙ×ÚÕÐÓÙÜá÷rsecm{ùðæíokvxjzûf]a]UPPMJLNMPYVWe{tÿãÝåæÚØÞÞßëöéàáÛÔØÝÙÜô}éíuýêíûøt^ZXVUWZTRVTNNPOMRXUZlþùàÖÓÐÌÌËÈÇËÍÌÏÙÙÐÒÚÙÒØàéùb^b_]m~osõu``md\fl^Y^[SRTRORWV\jkjùåàà×ÕÛÛÖÛîñùonýðíáÝáäåûiuùtlüëótuvhbd\Z``[Z\YQV]WT]`]f}õñãÚÙØÎËÍÌÍÑ×ÚÝèçÝÜáÚÒÞöðómhvùüòëìæáî~úïscgp_TTUNLOONRVUZfdavëìå×ÕÚÛÚç|õëþwëßÞÛØÝêäèz~åðmÿêtbokYV]ZRX\TQUVQSZWS]k^]þåëàÒÎÌÈÅÊÊÈÌÒÓÓÙÝÚØßåæ}b_b]\focbÿí÷ð÷oxñýjnÿcZ\^XX^^[[bdfp|pûÞÜÝÚÙáíèíhfvke|èðóæìxuùûnþõx}íõpu~j]gr_[eh]^a\[^^WW_\[hýúéØÏÏÍÊÌÍÍÎ×ÞÛÜßßÞéôõtbbmgciúüôßÞææâéòîöjbhdZYYROSTPRZ_Y[ksþåßãßÞßæåèõuøìòéßßâååäìéê{vù÷~þxhfce_[]\Z\][\[YYY[ZY]`dvèÝ×ÐÍÊÉÈÈÌÍÎÕØÚÛÞæçùnec]X[[Zbzúùõìêòìíÿvtqjlmb]^^WW`ebcio|öêçåääæçëórlmomxòïðó{}öúwkqwþù~÷øývxýttst{piiga^[WVWXW[cgtéßÙÒÍÌÍÎÎÐÖÙÙÛÜàãéð÷rgih`avóíæãàÞÞßåï÷ürinlaYYYUSSVVXX\jpnyïççëíïòúû÷üîêæÞÞÞàÞáçìó÷yúïzvþxlkgdabf`^c_YYZWVVVTR[inùßÜÙÒÌÊÊÊÉÌÎÐÖÙ×Úäëíüjdd\UY^_hs~xøñíëêéxp|mlztc_fa]]febnw~ðêíôèç÷rùöediienðùøíñûûùxrý|xþíìùëèözöíwoþ~smg^\[URRRPXenpúäßÝÖÐÐÓÒÑ×ÚÙÜÝÛÞçèåð{sulcnûøíèãâêëçèìükhpd]^[WRSWUW^belyñéîêèôý}úóútvÿ{}ïáÝææáæîóð÷ztr{{~~opkacdc`_`\Z[]ZVWUW]hþéÞÛÚÔÏÏÏÌÌÐÒÔÕÜÞÜâìõõ{iic]]\_cyxsûðíûðéôskptpkih^\^_fkpüíêèàáâäèíùýtlib]Z^cgny~wsöôþ}ÿzsýëèêæáçõý~úû{wpke]\^ZUUX\]e|ðñêâÝÚ×Ö×ÚÛÚÜàêìéîûôðóû÷úonxþîæàäæÝßçéïüpspc``[TVYZ^eghrúýøêêý{úÿst~tkkcetúüýëçìèßçüîïmxëêø÷ìösptjjna\]\WU[\WXeggðéðäÙÖÙÕÐÔÖÓÔÛÙ×äîèìxl~}gfn`\gg_lïõwïå÷yðòlwõthii__u~qùæçäÝáìâÞé{wzc_hcZ]_][_ddo÷ô|üïvoyroðÞàèàÜâççì~óìsbed`_bb\^knmt}øêáåéçàßçââéâäîý÷óóðîê÷z|~up{îâßßÝÜÛÞíîúmkj`YY\^_aihnþ|}ÿ~õüþ{om~öuuuruüývþêáåçàéïýogeqþýóðìïêå}jhg_ZYXY^`_`kvüðëíëßÛÜßÝÚÚÙÛÜÜÝÞëõñ{zöñxkrnea][amnmûçáãââêïìñ}yriiúëþýæâêõîììé~llkc^eg`^af`^agkvýs{óõlhnnwëäãßÛÜÝØÛæçëvaaha`fi^_ifguyozëïvüçò}óïðçáîôèåíèÝÞó÷î~pkoyòèìæÞÚÞäÞèÿywjac`]amjbt{fdnzzú}mlxzimøqoýóynîèìêçîúì÷ecnkdwëëíçäñïì}nlbWU]_\]mlizwnùåêòäÞæçÜÝäâàæéãìùñèðwîêzii_WY^]^wõ{ìÝÞäÜÙäíëôp{ñývðèó÷çëu|íýovwe_g^[`cYZ`^\gyw|øø}y}mmùî÷ïßÞÝÚ×ÜáÛÞóûôh]ff]\fi]^b_atzloþ~nqìïüéãíñâáãßàéèâåøztigpu{ìèéêåÞââßçþqykfnhbevm_kvkizzmzürjvsikývcmý}xîéïìçïstxjiu~zñëîîçé÷øó{ddlf^_dcgjegmln~îîöïæçæßßáâæìóíëñöðùýñòtlkd_`mki|õöôæßäæçêùòêóúõûÿøîòþúï}lwxlfghjljib__[]dcbhwýüÿøùûîðñêëðïãááÞÝáëæëxuwe]`h_]`f`_klhnmfkñëìâÜêuîäñøèëûðìííçípzëíöíî~{ïíðçßîròëwsùwifhhm|pcuî~pûýihp|s~ómbnqdi~phxëóüìê{ñßì~ïîvnóìx~êüiýònglc\^kb\im^iùwm}óøìÝÚÝÙ×çýäãø|úviwó~zòþdrê{h{ôloíëýîà÷rèç{}çîpÿéí~ëçûðåûk{ýgiôûeg}fYbd[^ebe}ïÿ{éäïéÞízïònsëìuðßð÷Þáuona`gh\[no^fzf`lþ}ôÜÙâáÚåïãêkk|slüï~}åàîêäëö÷ûovìîzÿñ|þïøooøwkøïzúääõðëùsvwizëwdhqg`kpc`vsiyøuüàÞìîåëuutdkùýp}æäêèéþike^`b_fnk_ewpn÷çâÛÕØßÝÛàéíýigmebltpuëèûîáíptùutõùsüæí|ðòùìíïóêÞãíæéùû÷ýnnuqwwodhm^^feeggado~û÷êëôîîù{y|yýíííÞÝäêææûvm_]]___b__`elmðãáÞßÝßâàåïúüpjgdgwþþíìéåîõ{pûøûýuùïóôíôöíõïïþôéíøû÷øzorpsùø}|wzznmnjmuigighnþöþóëözþzow}zvÿîêìçéëëïÿjgfa`fhbbggeipýåÞßâÞÝááãèíöülcefejpst~øütw|tõê÷÷êèíëäáèéæõþïìððîûz|ýxhyýv~ûwkmoigprkipfaheelp{{üïøöæë÷ñîõýíèêêâëøð÷jfjicfkd^ab^`p{zíçíñçâççÞæòîòtkrrkmponx}nxôîúöëïõëçìéèòøôðüýíï÷ò÷tssoirö÷þôóst}sonuoiprfafbajrqs}öûôæéòìîúõïïïó~qlssklsoqþvmighai}þùîíôïêçääçíóîþikmgfijkkosqrýøùîêëçáâãåèîóìïùîèñùñ÷xuz|yyüunqllpyvoxvpnokb`_]`nvtöíëçãáããæëëèåíôúojjrphllfhklghjfinqrÿûxzûðëäàãåéí÷ý{qlhkowy{|þøóïéçëêèðõíèíîëðôððóôø{ysmmu~ypovz~úøþþõïù÷~kfa_^dlnv{y~îåääàæêéíòû}ogdggjllmm|ùþ}|nivypyñô{öîðìááêêíõzomcdghhgqwqv{~÷êêîäåíéãäèéæéíííòéãðû~|mjlibaighþ~{ôèí|ùôtcb_[drrüðìîæÝÞæàÜæêäëóù|l`bd^^jicp}okkldfne`yúnvõðìãßßååéîíîxuõÿnnx|züóvoúzlÿñ{|òò~ýéò}íçïîãì{w|xoy~ljysm}ïîëáàéìêûkhh^]cgmÿùûîâáìéàæðëë÷ÿvg_^_]^müpwïýrü÷po{vhnðÿoóîúïãåææéó|ü}kn}mfmylkwþrxíû}íð{öîúùéåéëááèãåõþù|ihuncjvff{þyïãéíãéuluf_m{q~ëîùìâåëàÝìîæõlprd]`c^bnfew~loôvimuigu{mvîôðÝÚÝáßãîôõupôûjk{kahpjkõîzýúgcyyqþìêîêäèìãåúöëúy|}kfrvfl÷ýôàÞäáåíþpnhh|ÿnlysvúéèæÞàòúóidonfgmnjjhdhywkpöûmoznipvr{íçâÙÚäæåëþsstounba`_`fpwûêåýjpnmyû÷ëååêêæäæäãïùîë÷pmkfilggûìòðéèëîïzmowtpujgtñôðßÛÞàáît~üomqqgii^Z_g`bnqlx~kdouimùø|åÙÝáÜÝæçèýp~ñohph_gwjiýïypûm_i|kjòëöûïýzæÝçèÝáñêêtixýifý|mìäöýèàìîèþi|öhfrodsôöìÞÛñþèïvöðoj}ýfac\Ycj_güýmlngdr~ipìòöæÞçéÜßððìþmþ~gi~zekvmm~{hiüuhmxkkñðwyòùùåÜÞßÚÞïòðys||nsîót|ûxùäæðóí|hmuimøufsóñíæå÷úåéþóòxx{ncdmd\_lhkÿtgforlpø}zìñ|øíèåæëõúðöopzqq~wtxwtkjprsútho~}y}|w~ïíóæÝàèçëú}õövyóõ~ùýll~òüôèìøóöqtõôsuùøöòíðïæèòôðût}}fagedfe_aok_cjgclrpúëóú÷öýøáâîåÞè÷ìè÷ðéølzê|hoh_esochofhtuipó|wîåçåÞÞîêàæëêäèçáîüññzuùüsþùmgkpjoxmj{ðÿwóëðìçó{ðéùzõ{nvûsk}ülhjhafngamúun{lci{xrõëîòìøxîêøxöîõîéóx~ù|vytlo~oi{þw~øùõèçöúîïzóëøüêçïôôûuýí~yëïxýïø{óë}rðëøïë÷úìçð{øúms}kfjeadjkmysc`ggfjjjs{~rtøthxøüïæèîïìïíàé}õèíöðíüolmebigaeikpþûxùìëîåçìèãæèåäçìííõøôøþõóñðõzmxyiguxpry~~ðñöïïóþüõþw{~ûyuppzslmwxmnyssmjjkihjljfehnpuutýøòïòèæéèççãåéíñü}qeggiopýøýïêëíïñìéêîîëêõv|{tÿû{ýîìïîêð÷ððùz{zûð÷yûëìúõêïþü}mlyyorphimd^bffjzüouúocelhjpqipòýuûüp|îïïçáèìääíçÞçüùörie_[]fflüõÿòî}{ìåæäßáæâäùs|{nx÷ù~îåíôîî÷îîym{|lhtsq{õôòìëÿusnpüîòøóôymfcbnpmþïûwsk`bghghihjnjdlunp|ÿ|~ðöûîæææßáçãäðummiionoøðýþüqs÷ìéêêåêô{mmzwrûîíðîèéìæãîèæñîêúnpúóøöìíêãï{|phkq{mjwm^[\[_hhksþwhfgcjpnr~}svzpoüîúyîïùù÷xuúêìèäèéãé}mpi`cmnj|úpm{~üðêììããîòüyýìíôíèëù÷íñõëëððïø{uocg|þxõìíçãëóïîýtü÷xþùrhikjntnnyþk`ab_blllpvheljjz÷þ}óïùxystùòòëåââãäéôòösklmjnmfivqmzø{ûóyklos{îìíìåéóïæãèåâãäßáïóõyüîîõíçëîçæìòóvloroigb_ciihkkhklf_fkghqûz}ûwtýõöðìîîêéöpnqnq|þòëìúzöõx{þrimnhdiko~õ}vøó÷ýýxsþðïêàßåèçëïèéõýðêëëìýoprr{÷ôðëíûóçäéìðõõô÷zzû}yýüuknlcbcdipojn|}iinmkqxp}óîñö÷tmÿóÿüììðïðöõíí}yõù~|ujhjqnlpljmkb`kpwùíçèàãìéçéêéêíïíæéíëíïíï÷ïçèïðìïóêíúöîúpqomo}ûoongbbb]]gqoûêò{û{lròòusùõôìëõ~zwsyòü}ö~mlqtvyvszòùuzwnoyþyookggijsîíóèÜÜáâãééáèøóõ}ms~mk}õx|íðùñðûþíëøîåèëçê÷÷ìêïðìøvtl_]ddafz|{ó}kddcfpoddqsjoû~px|~óåéûñë÷ùéêÿzððùìéöûîûlrvk^^^WXcklõåççÞßííâçúîç÷|~sikx{xïèòíàâîíçëïëë÷öæïûðóqpøõz|ùpfed^`qro÷åè÷îîtime_cf_^jkbjýþnuýzÿõò~|ô÷}òò{}ðî÷îäçðíîyxwh^`d`bmù÷ëßÞàâçðóðþnn|ncaf`dr{úìçêêäãèéàâéèããåáãéêæí÷ñîýv}shdggbfklp÷ùlge_[[[XX[][_ijtòìííéæííçëïçåîïëëíèåêëæí{~ùrid^ZX[^^e}ðîãàéïîï|zþunxwhl~zzñçæçäáæçààåãâêëååííéðwü÷s{ðþuwvlgklgjþü~õúmda_XUYXVZ^\apqmþîô~ðî~üêìíåâèèááíêáåòïî|þövgima\cgcmîéêåäîóõuejvkdlpkoùñõçÞãçßáçäÜßåÞÜàãÝãñèç}uøóÿúí÷u~~kcihciytmsrc]^XTW[WW^cak|{vôî÷ôêêìêçêèßÛÝàáçïëæñþöøxvwked`\\elvðî÷÷îí÷vmjdhmlpüøùóëæåÝÛàãÞÝÝÛÝãáÝßäçêðý{xtÿöðñùúzwyrifhlloonuwlb^]ZZYX[]_fmonuÿxry|~ôïîíåáÝÞåèîñòùø÷ñóùýxqtsjfihgxüÿõëíóþ}pkkgbfmvzôíîêâßããÞÞàÞÝßÝÙÜåäæõôî÷}ûóøöéìø÷íûmqnhdcc`gmb]ac[Z^\X[]]annhtülj}õúôééæÝÛÞáÞßíêåîòîíþýîüqt{f`ki`jypxíëysþodekfhýþxðåêñèÞèçÛÛÝÙ×ÜÝØÞîîéûlvÿs~íöúêçõ|öþhejb]chbcme]_c\Yad[`khgqtddljdrûv|êåëçÝÞåãßæèàèøîëþ{éäïóïyghh`gzts÷ëõýþxhgkbdpxmzëîúòéêîäâåÝÚÜÞÜßëëäíúñòsqøø÷éäêíëöoif^\ac_`fa]]]YZbb[^hddllefkghwõûòãäêãÜÞßÝÞàÝÛãïñó~|ïï÷øûlehh`dsohvùxpyoekplix{p{íôùïëçêâßÝÛÙÚÞÞÞæèèïþÿþpmovwóðùøô{kifbbhjhfkh___a`ekgdhkljkadf`afnnxóêêçäáßãäââèðó÷}~õëììëíüsouswþÿõö÷ý~xpsxokjmkhwü~{óîììíéäßããàÞâåáßåìñ÷qkoovøðôíïúsnc_dfa_gf__baadba__^]beb^clfhuûzùéêëäÞàßÞßàÞàèñôürwðìö÷íótt{þzÿ{þù~pq~nkt}nlyzln}ù|ûéææãßâÝÚÞáÜßïíãè}÷ìøotvnn|||zqiekgafpibjpdbkniiumd``_cb^^ekdh{úzñçâêãßàäååêèìú~ûxqþéíðêé~q|ø~{ôó÷üõüôò|t}xiizþnwñðûïéêíëêæãäáàÞêïçãêðëç÷nxü{rvuvnjehfa_fichpvlt~~lklf]Z[[\[]dkhgqòøüëáçêãâäçããàæëòðó}þíéëëåæûÿøúnrûöÿþûüóöú}þlhmxpntøö{ôííóìåßâàßÝâíñçâíéãæóýzznhggb]\^a]^_eglqþyoúñ{mnmj_^_a^^cjicmùòýíçãìïêçììêæçñðìí{zòæéîèæöÿþ~ý|òêçéëèâêùùùpgn{ynvüþpt}üûÿüôéëìêæìöíáéîíçèðú÷ózpppg__d_[^m}u{ìçû~÷þhadg`[[b`Z[^fci{øþôêæêôïäãèåáßäéçâê÷íæçñôìéüptû~uýåêõêâìpqý}ffs~nly÷}uôåçòðåàðøçãîìâàêéãàçóòñ÷rikf]Z\\XU\hik}ééìñ~{wkihj_]ab[Y_hhj}øóóëîïíîíèìõòèåòøìåññíìüöûíóxwòéîôàÙâëæãxjvõsbjývfdmüqnõäîýñäùhxçéÿéÞãïçÞãïèãåñuqql_]`^[\cnoýéâé}rkmf`]c`YV[ZTVdkbdÿëþr÷çìïãÛÝêìÞÝôøàÜìöèä÷þêæýpúî÷xöèçëíû}milmlkllhccenùîíéßâíúìëùñÜÜåèÛÚéöåÞìüðìqcerbWY``YZishqîðh`lud`qze]]^]Z^iiitýÿy{ûùïæàåäàåïóéåìèàê{ýèì{wðñxyèßæëàÞît÷éüktõzhjrdZ_suiqïìrl}ñýøâÜàçßÚßëêçèæçîïíò~uqmddkmkfnøxjjpkb^fd[Z`ZOQ\]X[ptcf{ùpoêÝåìÞÖÚåæÞßïìÞàóõæê}~ðõ~~ýø÷òôþ{onzýùýúunniehptjmøôúòåíûêÜÝáÜÖÛßÜÛÞéìãçulüõh^fla\lùl`l{k]dpoklpnkfdd^[agfbfmlilqnvõííêëìéæë|~çèúõèí}zóñtoòäé÷ðàäÿ~èèöóäçütòòkdmtqkimhb`fjfmñãåãÜÚÚÚÛÞàààåååéòðíýoxöÿrxõûkgmjc`inb\^bYRU[[Z^ifcilmlmzîéæàÝÜÜÜÜÜÞÝÜÞâãêîöõþoyÿspþ~sljhfgsúúúýðöpjwztpþþpmxvjjv÷ðáÝÛÛÛÚÜÝÝÜÝáééíòxpmc`epll{ösmotmmtsmkomndaachlqunikd``kpxûðíîëíññð÷îèäåçåëõ~}~ôù}üíïúõëð{÷éèðéàæøyyplmxpkfgd^Z\`^bqîéäÞÜàáÞÜÜÛÜßáäé÷û÷þw}úùòõ÷ywoopÿpfhlf]\ZXVY\^^eihd__fjkôéççßÝâçßÚÝÝÚÙÛÜßäðüù~ýzsovnhflkmq{{~ïîðþþnov{oq|thchccjy~íâÜÚÚÜãáÞÜßÝÝãïóugfkf_eikmxuomwzv{omv}leba^`cbajykhghdgmqoûïëîöüþêæèèáàâäãêðééñùô÷øûûszôíëëèêçááìøûüuspmmkc[YXVY]aepîéæäâáßÝÝÜÚØÛáæï|y|ulo}ùö÷÷üüwryvkfnka\][XUVWYZ\]`bemrx{òèèìéçåâÞÛÝÜÛÛÝÝâéèèñü÷ôþsvnjjoqyt{öíìúöîïv~ïñ|üüpb_d`bahpùôìåßåâÝÝàßÛÝäìíxojg^`ifhn}npÿùsyüôúý~rolhcb][\`\Y^je^iomhw}}yöëåäèåßßéæááëéæêõêãèñø÷z}|þ}íêéçàäððïùossldc^]^\Y\b_drò÷íàÚÝÜØ×ÚÝÛÛÞéêîõskkvjepzqjuvmiqpkhidba`a][YYWZZ]ahiq{yøñòôæäâáÚÜàÞÛÜàßàáëïìëùõøütmllnlsùìòêâàìçâçðùûsjfkgc_dccdlvþõéÝÜÜÜÚßçéèðöþynjkeeejglrwvþ÷íïõñõö|{prhed_YWZ[YX]`b_gjifný÷÷îâáãæÝÜßäÞÞãæßÜáéëåëîöùû}|õðîìêäæëôíîøohb_\[^^\[aehepöíëÞÖÔ×Ø×Úßåàãîw}÷xjmwskkyslhryrhjrnhfhgb]^\YWY\^^_fkielxwo~êåèàÚÛßàÛÚßæáßãíæãëýüíñrm|ûtqïèîöèäêðíçìyjljb]_ba_cgikqùðëåÝÙÚÝàßâïüòðzqv}tlzöù~üñô}|îíöy~ûqflui^^c^WW\\WW]b^\^ccbj{ôîêáÝÝÞÞÝÞßßÜÞÞÞÞàçêéèï}üðð}þéäêòêèót{õufbhg^Z]^[Z`jffvìíëÞ×ÖÛÜÙÜçñéèîôòìñû|ñíø|þöüvzyrmlpnjcgf]\\][WX\]XZfke^hrlkzäßßÞÙ×ÞßÝÝãéáßãçéèóúôòüou{torõííôðìôû~öòtmmqjb`bga_ekrp|íééãÛÜàçéêùöðøý{û|sp{î÷øôëè÷óïíúx~zwmoqkg`]^]\ZZXZ\ZZZ]^]blùïéáÞÜáãáßÜààÜÙÜãßààèìêîîúý÷óïîíô÷ðzpt~{jiqzi_aaa\[^`cetðçãâÛÜÜÜáåéãèïíéåõ}ÿú÷tvüóöuxz{ohjjicaegh^^_`b]^]^_]_aggdisòïîæÝÙÞáÞÝÞçåààêðêêëóöóú÷{pqwø|ûõíìþþüíð~ôíèôutqoc_cijem|ñîôéæåë÷ñðïüÿóïîþwooypwýëêúóëç÷uÿûwhgmnneilic\]\[WWY[^^]`ahipùêàââÞÛÚÜÛÚØÚàáßÝãëåäéý~ñïöyøóóúvuopmint|siggh^]`dfchuóîïáÜÛßäâààééäáãðóõûxkvýþwwúýýxnlghdabfiddjmi_`ab^Y\`h`^gknjtíäââÜÜÜÜÛÙÛÜßæçêéìòôñíû}ûñîzr~íôtÿòôtrõóùvsxqnhiiigbhoyøõðêäæëíëçîðéæåòúøúyjs÷ñü|ñëìúÿú{ogjmjklqmkomibb_YX[^\Z]djffvíìøîàÛÛÛÕÔ×ÜÝÜàçìééìêìëëççòÿ~ïí{suýuilu}kdjlb\akgaaltsuúíìåçéèäßââááßäèììðrxýùwlr~|igotnbakkkgkmjhhkgc_^^\]_`bjslkxéâïíßÚÛÞÚÖÙÞãâäíÿþíñù}óììí÷þ~øûywûñúu}öð}nnog^`hlgfpüýon~öù~ùëæããâååäçíõóúplv~zuþ÷ÿljqþ{ikxxpkmupliidd^ZZZ\[\_hhchnùíðíæÞÞåßØÕÚÞÜÙÞêíçêòúîèéíðïóø{|þûô~qrzütjhmj[[emeam}|npöìîõïæãäæåàßãèçëìúolqzsqstylbdllbj~õylsû}kehhd]\_c`]`a`abcer}{øêàâæáÝÙÝßÞÜÞêíèàæòïëêïùñíïúöìåèñïïõývpmml`]`idahlzmiyñòwtóèíðäÞÞáãàäçîþw{ýysxÿ}lfimnknwù|mpxyiaeie]Z]_^Z\adb`cjvt{ðéäâßÜÜÚÜÝÞÝÝäçæßãïòëéòýûñêïöíèéûz|~rijopfcffhechnslmsýö~üóêçëçàÞáëëéçõ|ùõûppu|uiikooku~öýs|ý}qmkgc]\]^_^^aff^_gnjlþêààâÝÚÛßßÞàæîéääçêéêéîô÷íêõ÷ìççñþýøyigjmhbdkokjp|zjiqttln~ôññëåãçíëèéíðòóúrmpÿþpoyûzp~ïîüxýþ}qllfb]\__]\^aggbeimlioôçèêáÛÚÞßÝÜàèçããèíèæèìíéëí÷~ùòïûy|þ{idhkg`enyonú÷|mmqspim~ïñøìåáçîìëëñüøõûomr{wmpyøúyýîèôzøôûkgkic^_dfd`cdbaacfkhflÿîõõëâÞãäßÜÞååàÞäéãßàææâäéò÷ôïîõ÷îíùngeifbahusntý{kfjmf^ep|wqùëêïðêêêëïïîîõ~üõóöú÷ðøw{óñ~q{óýjcjkgcejkiddedcchjkllrzýúûîåàáàÞÛÜáäàÜßçéâäëëæèï~~øù~wzõúummmklinvzÿos{þvotywiiosniuóíô}÷ïôzzöóöþùóðïøþúýöùû÷õøxü÷ùrgmptjlxyqffeb`acedddggilnýîèæåàáâçäÜÚÝàÞÝÜàéâáçîðëó÷ÿzø}tommnljlvwmknmomgozujfjonkwîéîôìéðùüðêìöôëîô|xýýÿxzzprkoxvrjmssnn|ùwgfklhegmlg`gjkkp÷ìçéèâäæìëåÞßççâäêðëçèíûóï÷}zýÿ|svý}|yþøö~pvü}rkopmb_dfgdjþû}svöúþúïåçïïììó|{÷ðóó÷ôõ~nourvqu|{wtyü~mfllf^adb][]afgl}íèêëåãâåâÝÜÜßàßßâìéâåëòíëôwpþÿqmptoohmquzo}þyqllhfc`eksqsüïôzzðîñòêæåçîííôýz÷÷ùü~ýskeglklnu|ôûxúóñþz{~ugcdb_^^difguùøùúíëéèëåãäçæäåæëéãäãéëèìõ|þöü|zùôõz{ñòù~ûýykfe_`^]bhhilqxzvt~ðìíêááçìëèæïôëìïïõûýukkmmnjpywwp|øûõ{xxne^^]]\^cgien|~÷ûëçäâçßÞÞãåáâàââæêéðóñø~pvþ}xtw||xpþôõüúò}oghgcdbinqpp~|þýúíìíðëæéêôöó÷ùýøòõ|uzxokmnnpqvûû÷üòìêë÷ð÷tjdhfc`^bbb_dlljk~íëìîéèéêïåâäåäàääêìëòö~ùùÿøy}ï÷ôîôïêøûðxqd`c__\^`bdaksps{õëçëèâæèìëèéìöîëñ÷|úøzrnqpvooy{üyyø~~v~mnnef_ca]dd`bemnpuóëîèçæàåæåàßÞãèçíëöõ~þ~lnxr|puûù~ýíóïð÷ðýxpnolf`dfgjjstqxxûóììðëëéðøìó÷ýøîùþwÿýywm|~~y|íòíðïêóõûþ|urjilhc__\]]]fefkl}ôïñíééêêãàãâßÞâãæíéîîöwö~ùþöîðìôòíòõzýymiefb^]]`]`cjpq|yöìêéíåãäåéãäîôõëíôûþðvpnuþnwxýô}øþø~þ~nvmlljojlbefcedozzwwùîïñìäççìëäéåçèæíìúõüsurÿyzöùîìëðñëìñüùö}}opneb^d``igupw||òõóñôîíðöðîôö~ïôýüyü÷}|zîsóæðãzìïõêþzmunnkdkkf`\``]_eoimm~üøôùäèâçìæâßâåÞãæéîëôûuýôöîòìîìîñèïûpnfvqkicb][]]acgoxyÿöïíìòìâçæçêçèëòìæêõ{üþyxpùú}}zøøzx{üwnhgkeiginie_cfnlk÷óùþüìíòôëçëìîéæèìëéíòú|úyutr÷ûóøòìïìóìëñøyyzvsuxnieafefhn|y}wyù~~u}úþû|÷òòòùíìôüûõú|~òêíñðêãéóõíôytlpnnjijba\]b^_bksmkkuþzyüëëîëêâáãâàßæêìèìùðôïêìíðìëìòøîùrkfkgefgga__dddkovxvzz÷ôðöîéìêîèãæåçââæë÷ñþvyxøûxtwÿxqquynljlqnkijjhfhopttwû|yuyôøùñêèîîîêèìíìêíóú~úyz{{ôúøöõñóòöíëõø{ö÷wtsþromlqikjimhkkoploktuwüýðìíîêãåêîíìô÷óèæêèêëðúõüó÷{zsvifc`c^^^_d`abgjlno~u{ýöíìëêåâãßãßÞâàäããêíîìðôù{ô}{zpzrojiibdaghghinkhhgojnuyööððîéëêìæáæäçãåèìñð}wssþvqrsuqup{wqvjpojkglmljnwllot{s{~ýü}öüöïõõôõù÷÷øòüúûöðóñóîíïõûóñõîîêêìïðó||stwopllgec_b`_``hklko|{|zûíïìêæâäääâãåäåäæèêïêîôôôõ}zmopgc`_^]^[\[\]_gfkknzzþúîêëèèäßàââßáâãèåææéóóù~xv~|xsÿþwqlppjecjjhfdgeecgllnu÷ððîðçèèéëååéëëççéîíïöøwtsptrx{yy{ýwqquxurkjtpkhlnijhkko{züóùùùòùòûúîõòøôõìþûôòóúøóîôôôêíìçâåæàêëìívlrolffhd`^^`_aeipuwrþ~úûûíòìëêáãäææåäèéçäéëíïøîëáÝçtïlk}^b_^b^Y^_h\[_ccpll÷qò{éîräâäèäìîïðàôôèàîîõííúxxêxôïqþë{k~tieamügaoj`jb~ìwxããçãèßßíìåèßéãßßëãéðæývæðw|jxknmíùpáýzvsõhmlm\ygVnWhZcøs~mvlí÷wïiþê}|vë{ÿv}}~~ê÷øèíyèçqêåÜêæÛÜíæÚì~þðûÿmo]baZfT`ilYcwadpýYóâföáèâ
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_gsm_1ch_8khz_13kbps.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_gsm_1ch_8khz_13kbps.info
new file mode 100644
index 0000000..2dfbe31
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_gsm_1ch_8khz_13kbps.info
@@ -0,0 +1,17 @@
+975 1 0
+975 1 600000
+975 1 1200000
+975 1 1800000
+975 1 2400000
+975 1 3000000
+975 1 3600000
+975 1 4200000
+975 1 4800000
+975 1 5400000
+975 1 6000000
+975 1 6600000
+975 1 7200000
+975 1 7800000
+975 1 8400000
+975 1 9000000
+520 1 9600000
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_gsm_1ch_8khz_13kbps.raw b/media/codec2/hidl/1.0/vts/functional/res/bbb_gsm_1ch_8khz_13kbps.raw
new file mode 100644
index 0000000..df903a8
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_gsm_1ch_8khz_13kbps.raw
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_h263_352x288_300kbps_12fps.h263 b/media/codec2/hidl/1.0/vts/functional/res/bbb_h263_352x288_300kbps_12fps.h263
new file mode 100644
index 0000000..652581f
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_h263_352x288_300kbps_12fps.h263
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_h263_352x288_300kbps_12fps.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_h263_352x288_300kbps_12fps.info
new file mode 100644
index 0000000..75bfcb6
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_h263_352x288_300kbps_12fps.info
@@ -0,0 +1,122 @@
+26362 1 0
+12023 0 83333
+10647 0 166666
+10269 0 250000
+11076 0 333333
+11104 0 416666
+5909 0 500000
+4291 0 583333
+5149 0 666666
+5353 0 750000
+5185 0 833333
+2736 0 916666
+21575 1 1000000
+2196 0 1083333
+4340 0 1166666
+3109 0 1250000
+4410 0 1333333
+1731 0 1416666
+4557 0 1500000
+3376 0 1583333
+1352 0 1666666
+2844 0 1750000
+1787 0 1833333
+1088 0 1916666
+36843 1 2000000
+2520 0 2083333
+3749 0 2166666
+3784 0 2250000
+3402 0 2333333
+3795 0 2416666
+2345 0 2500000
+3142 0 2583333
+2948 0 2666666
+2018 0 2750000
+5133 0 2833333
+2276 0 2916666
+23468 1 3000000
+1522 0 3083333
+2299 0 3166666
+3273 0 3250000
+2630 0 3333333
+2915 0 3416666
+3032 0 3500000
+1890 0 3583333
+3718 0 3666666
+1990 0 3750000
+3139 0 3833333
+1806 0 3916666
+23208 1 4000000
+1419 0 4083333
+2263 0 4166666
+3131 0 4250000
+2645 0 4333333
+1880 0 4416666
+2239 0 4500000
+3637 0 4583333
+1941 0 4666666
+1577 0 4750000
+3777 0 4833333
+1816 0 4916666
+19601 1 5000000
+1104 0 5083333
+2808 0 5166666
+2411 0 5250000
+2159 0 5333333
+2411 0 5416666
+2408 0 5500000
+2388 0 5583333
+2418 0 5666666
+1481 0 5750000
+1926 0 5833333
+9022 1 5916666
+292 0 6000000
+701 0 6083333
+747 0 6166666
+2059 0 6250000
+1693 0 6333333
+2078 0 6416666
+2975 0 6500000
+1317 0 6583333
+1742 0 6666666
+1019 0 6750000
+1053 0 6833333
+14183 1 6916666
+1467 0 7000000
+994 0 7083333
+1709 0 7166666
+838 0 7250000
+1328 0 7333333
+2292 0 7416666
+1829 0 7500000
+1728 0 7583333
+2436 0 7666666
+1852 0 7750000
+2190 0 7833333
+15167 1 7916666
+1188 0 8000000
+2070 0 8083333
+3316 0 8166666
+2636 0 8250000
+950 0 8333333
+1260 0 8416666
+906 0 8500000
+1294 0 8583333
+1298 0 8666666
+1897 0 8750000
+1348 0 8833333
+13194 1 8916666
+1042 0 9000000
+1258 0 9083333
+1457 0 9166666
+990 0 9250000
+900 0 9333333
+963 0 9416666
+3448 0 9500000
+774 0 9583333
+1075 0 9666666
+750 0 9750000
+1054 0 9833333
+13139 1 9916666
+3104 0 10000000
+3366 0 10083333
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_hevc_176x144_176kbps_60fps.hevc b/media/codec2/hidl/1.0/vts/functional/res/bbb_hevc_176x144_176kbps_60fps.hevc
new file mode 100644
index 0000000..f82236f
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_hevc_176x144_176kbps_60fps.hevc
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_hevc_176x144_176kbps_60fps.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_hevc_176x144_176kbps_60fps.info
new file mode 100644
index 0000000..c4357ce
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_hevc_176x144_176kbps_60fps.info
@@ -0,0 +1,61 @@
+1695 32 0
+1938 1 33333
+471 0 83333
+153 0 66666
+99 0 50000
+657 0 150000
+260 0 116666
+115 0 100000
+99 0 133333
+622 0 216666
+211 0 183333
+79 0 166666
+95 0 200000
+597 0 283333
+288 0 250000
+145 0 233333
+147 0 266666
+676 0 350000
+284 0 316666
+144 0 300000
+131 0 333333
+658 0 416666
+270 0 383333
+101 0 366666
+151 0 400000
+529 0 483333
+257 0 450000
+98 0 433333
+160 0 466666
+664 0 566666
+186 0 533333
+147 0 500000
+67 0 516666
+78 0 550000
+575 0 633333
+230 0 600000
+134 0 583333
+114 0 616666
+629 0 700000
+224 0 666666
+138 0 650000
+129 0 683333
+645 0 750000
+264 0 733333
+145 0 716666
+705 0 816666
+365 0 783333
+156 0 766666
+160 0 800000
+725 0 883333
+330 0 850000
+138 0 833333
+162 0 866666
+638 0 950000
+337 0 916666
+170 0 900000
+133 0 933333
+432 0 1016666
+287 0 983333
+130 0 966666
+136 0 1000000
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_hevc_640x360_1600kbps_30fps.hevc b/media/codec2/hidl/1.0/vts/functional/res/bbb_hevc_640x360_1600kbps_30fps.hevc
new file mode 100644
index 0000000..651f7cf
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_hevc_640x360_1600kbps_30fps.hevc
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_hevc_640x360_1600kbps_30fps.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_hevc_640x360_1600kbps_30fps.info
new file mode 100644
index 0000000..299491a
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_hevc_640x360_1600kbps_30fps.info
@@ -0,0 +1,302 @@
+1075 32 0
+1075 32 0
+68613 1 66687
+19025 0 199687
+2405 0 133687
+777 0 99687
+681 0 166687
+20254 0 333687
+2927 0 266687
+766 0 233687
+658 0 299687
+20786 0 466687
+4214 0 399687
+609 0 366687
+661 0 433687
+20838 0 599687
+4209 0 533687
+506 0 499687
+586 0 566687
+20415 0 733687
+4207 0 666687
+427 0 633687
+514 0 699687
+24457 0 899687
+1904 0 833687
+921 0 766687
+992 0 799687
+543 0 866687
+24342 0 1066687
+1822 0 999687
+840 0 933687
+892 0 966687
+715 0 1033687
+22893 0 1233687
+1618 0 1166687
+881 0 1099687
+890 0 1133687
+794 0 1199687
+24292 0 1399687
+1673 0 1333687
+755 0 1266687
+810 0 1299687
+588 0 1366687
+19828 0 1533687
+1538 0 1466687
+894 0 1433687
+933 0 1499687
+19853 0 1666687
+2011 0 1599687
+981 0 1566687
+900 0 1633687
+22869 0 1833687
+1562 0 1766687
+842 0 1699687
+765 0 1733687
+665 0 1799687
+22346 0 1966687
+2245 0 1899687
+516 0 1866687
+604 0 1933687
+24333 0 2099687
+1765 0 2033687
+318 0 1999687
+320 0 2066687
+18577 0 2199687
+1123 0 2166687
+337 0 2133687
+17509 0 2299687
+869 0 2266687
+901 0 2233687
+23366 0 2433687
+1217 0 2366687
+380 0 2333687
+347 0 2399687
+19542 0 2533687
+1887 0 2499687
+467 0 2466687
+18939 0 2666687
+2863 0 2599687
+317 0 2566687
+272 0 2633687
+19353 0 2799687
+2092 0 2733687
+203 0 2699687
+310 0 2766687
+18800 0 2933687
+2038 0 2866687
+242 0 2833687
+199 0 2899687
+17452 0 3099687
+1060 0 3033687
+301 0 2966687
+452 0 2999687
+256 0 3066687
+21352 0 3199687
+409 0 3166687
+173 0 3133687
+19142 0 3299687
+642 0 3266687
+468 0 3233687
+19066 0 3433687
+635 0 3366687
+197 0 3333687
+190 0 3399687
+18813 0 3566687
+969 0 3499687
+165 0 3466687
+203 0 3533687
+17362 0 3733687
+246 0 3666687
+236 0 3599687
+174 0 3633687
+164 0 3699687
+17081 0 3899687
+353 0 3833687
+222 0 3766687
+181 0 3799687
+148 0 3866687
+10835 0 3999687
+185 0 3966687
+139 0 3933687
+7510 0 4133687
+149 0 4066687
+129 0 4033687
+132 0 4099687
+1063 0 4166687
+805 0 4266687
+157 0 4233687
+394 0 4199687
+90840 0 4399687
+6159 0 4333687
+1752 0 4299687
+985 0 4366687
+31338 0 4533687
+3390 0 4466687
+772 0 4433687
+781 0 4499687
+31084 0 4666687
+3498 0 4599687
+818 0 4566687
+881 0 4633687
+30416 0 4799687
+3265 0 4733687
+815 0 4699687
+790 0 4766687
+31053 0 4933687
+3106 0 4866687
+708 0 4833687
+713 0 4899687
+30230 0 5066687
+3214 0 4999687
+639 0 4966687
+768 0 5033687
+29657 0 5199687
+3013 0 5133687
+622 0 5099687
+720 0 5166687
+29344 0 5333687
+3196 0 5266687
+713 0 5233687
+775 0 5299687
+30420 0 5466687
+3374 0 5399687
+803 0 5366687
+717 0 5433687
+29960 0 5599687
+3283 0 5533687
+793 0 5499687
+790 0 5566687
+31011 0 5733687
+3397 0 5666687
+809 0 5633687
+831 0 5699687
+31194 0 5866687
+3401 0 5799687
+807 0 5766687
+827 0 5833687
+30326 0 5999687
+3186 0 5933687
+818 0 5899687
+863 0 5966687
+31559 0 6133687
+3364 0 6066687
+840 0 6033687
+919 0 6099687
+32013 0 6266687
+3495 0 6199687
+871 0 6166687
+803 0 6233687
+30294 0 6399687
+3153 0 6333687
+716 0 6299687
+812 0 6366687
+29952 0 6533687
+3299 0 6466687
+801 0 6433687
+749 0 6499687
+30598 0 6666687
+3536 0 6599687
+887 0 6566687
+850 0 6633687
+17246 0 6699687
+31110 0 6833687
+3198 0 6766687
+809 0 6733687
+836 0 6799687
+29784 0 6966687
+3155 0 6899687
+859 0 6866687
+958 0 6933687
+30666 0 7099687
+3371 0 7033687
+886 0 6999687
+861 0 7066687
+30416 0 7233687
+3350 0 7166687
+917 0 7133687
+987 0 7199687
+29509 0 7366687
+3574 0 7299687
+972 0 7266687
+885 0 7333687
+30872 0 7499687
+3399 0 7433687
+898 0 7399687
+1027 0 7466687
+31155 0 7633687
+3454 0 7566687
+965 0 7533687
+841 0 7599687
+28487 0 7766687
+3616 0 7699687
+921 0 7666687
+991 0 7733687
+23208 0 7899687
+3551 0 7833687
+918 0 7799687
+894 0 7866687
+16982 0 8033687
+3458 0 7966687
+844 0 7933687
+943 0 7999687
+30396 0 8199687
+4963 0 8133687
+1416 0 8066687
+1639 0 8099687
+524 0 8166687
+1368 0 8299687
+565 0 8266687
+392 0 8233687
+41317 1 8399687
+185 0 8366687
+477 0 8333687
+5342 0 8533687
+1275 0 8466687
+121 0 8433687
+982 0 8499687
+6465 0 8699687
+2606 0 8633687
+1163 0 8566687
+943 0 8599687
+1186 0 8666687
+11593 0 8833687
+3122 0 8766687
+1278 0 8733687
+1593 0 8799687
+9099 0 8999687
+978 0 8933687
+748 0 8866687
+835 0 8899687
+364 0 8966687
+4799 0 9099687
+365 0 9066687
+215 0 9033687
+4367 0 9199687
+302 0 9166687
+480 0 9133687
+6180 0 9333687
+771 0 9266687
+246 0 9233687
+281 0 9299687
+4636 0 9399687
+211 0 9366687
+4037 0 9499687
+382 0 9466687
+486 0 9433687
+3975 0 9599687
+312 0 9566687
+474 0 9533687
+6880 0 9733687
+1116 0 9666687
+206 0 9633687
+698 0 9699687
+6254 0 9899687
+2581 0 9833687
+1303 0 9766687
+985 0 9799687
+967 0 9866687
+6486 0 10033687
+3555 0 9966687
+1430 0 9933687
+1605 0 9999687
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_mp3_stereo_192kbps_48000hz.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_mp3_stereo_192kbps_48000hz.info
new file mode 100644
index 0000000..21fbfd4
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_mp3_stereo_192kbps_48000hz.info
@@ -0,0 +1,414 @@
+576 1 0
+576 1 24000
+576 1 48000
+576 1 72000
+576 1 96000
+576 1 120000
+576 1 144000
+576 1 168000
+576 1 192000
+576 1 216000
+576 1 240000
+576 1 264000
+576 1 288000
+576 1 312000
+576 1 336000
+576 1 360000
+576 1 384000
+576 1 408000
+576 1 432000
+576 1 456000
+576 1 480000
+576 1 504000
+576 1 528000
+576 1 552000
+576 1 576000
+576 1 600000
+576 1 624000
+576 1 648000
+576 1 672000
+576 1 696000
+576 1 720000
+576 1 744000
+576 1 768000
+576 1 792000
+576 1 816000
+576 1 840000
+576 1 864000
+576 1 888000
+576 1 912000
+576 1 936000
+576 1 960000
+576 1 984000
+576 1 1008000
+576 1 1032000
+576 1 1056000
+576 1 1080000
+576 1 1104000
+576 1 1128000
+576 1 1152000
+576 1 1176000
+576 1 1200000
+576 1 1224000
+576 1 1248000
+576 1 1272000
+576 1 1296000
+576 1 1320000
+576 1 1344000
+576 1 1368000
+576 1 1392000
+576 1 1416000
+576 1 1440000
+576 1 1464000
+576 1 1488000
+576 1 1512000
+576 1 1536000
+576 1 1560000
+576 1 1584000
+576 1 1608000
+576 1 1632000
+576 1 1656000
+576 1 1680000
+576 1 1704000
+576 1 1728000
+576 1 1752000
+576 1 1776000
+576 1 1800000
+576 1 1824000
+576 1 1848000
+576 1 1872000
+576 1 1896000
+576 1 1920000
+576 1 1944000
+576 1 1968000
+576 1 1992000
+576 1 2016000
+576 1 2040000
+576 1 2064000
+576 1 2088000
+576 1 2112000
+576 1 2136000
+576 1 2160000
+576 1 2184000
+576 1 2208000
+576 1 2232000
+576 1 2256000
+576 1 2280000
+576 1 2304000
+576 1 2328000
+576 1 2352000
+576 1 2376000
+576 1 2400000
+576 1 2424000
+576 1 2448000
+576 1 2472000
+576 1 2496000
+576 1 2520000
+576 1 2544000
+576 1 2568000
+576 1 2592000
+576 1 2616000
+576 1 2640000
+576 1 2664000
+576 1 2688000
+576 1 2712000
+576 1 2736000
+576 1 2760000
+576 1 2784000
+576 1 2808000
+576 1 2832000
+576 1 2856000
+576 1 2880000
+576 1 2904000
+576 1 2928000
+576 1 2952000
+576 1 2976000
+576 1 3000000
+576 1 3024000
+576 1 3048000
+576 1 3072000
+576 1 3096000
+576 1 3120000
+576 1 3144000
+576 1 3168000
+576 1 3192000
+576 1 3216000
+576 1 3240000
+576 1 3264000
+576 1 3288000
+576 1 3312000
+576 1 3336000
+576 1 3360000
+576 1 3384000
+576 1 3408000
+576 1 3432000
+576 1 3456000
+576 1 3480000
+576 1 3504000
+576 1 3528000
+576 1 3552000
+576 1 3576000
+576 1 3600000
+576 1 3624000
+576 1 3648000
+576 1 3672000
+576 1 3696000
+576 1 3720000
+576 1 3744000
+576 1 3768000
+576 1 3792000
+576 1 3816000
+576 1 3840000
+576 1 3864000
+576 1 3888000
+576 1 3912000
+576 1 3936000
+576 1 3960000
+576 1 3984000
+576 1 4008000
+576 1 4032000
+576 1 4056000
+576 1 4080000
+576 1 4104000
+576 1 4128000
+576 1 4152000
+576 1 4176000
+576 1 4200000
+576 1 4224000
+576 1 4248000
+576 1 4272000
+576 1 4296000
+576 1 4320000
+576 1 4344000
+576 1 4368000
+576 1 4392000
+576 1 4416000
+576 1 4440000
+576 1 4464000
+576 1 4488000
+576 1 4512000
+576 1 4536000
+576 1 4560000
+576 1 4584000
+576 1 4608000
+576 1 4632000
+576 1 4656000
+576 1 4680000
+576 1 4704000
+576 1 4728000
+576 1 4752000
+576 1 4776000
+576 1 4800000
+576 1 4824000
+576 1 4848000
+576 1 4872000
+576 1 4896000
+576 1 4920000
+576 1 4944000
+576 1 4968000
+576 1 4992000
+576 1 5016000
+576 1 5040000
+576 1 5064000
+576 1 5088000
+576 1 5112000
+576 1 5136000
+576 1 5160000
+576 1 5184000
+576 1 5208000
+576 1 5232000
+576 1 5256000
+576 1 5280000
+576 1 5304000
+576 1 5328000
+576 1 5352000
+576 1 5376000
+576 1 5400000
+576 1 5424000
+576 1 5448000
+576 1 5472000
+576 1 5496000
+576 1 5520000
+576 1 5544000
+576 1 5568000
+576 1 5592000
+576 1 5616000
+576 1 5640000
+576 1 5664000
+576 1 5688000
+576 1 5712000
+576 1 5736000
+576 1 5760000
+576 1 5784000
+576 1 5808000
+576 1 5832000
+576 1 5856000
+576 1 5880000
+576 1 5904000
+576 1 5928000
+576 1 5952000
+576 1 5976000
+576 1 6000000
+576 1 6024000
+576 1 6048000
+576 1 6072000
+576 1 6096000
+576 1 6120000
+576 1 6144000
+576 1 6168000
+576 1 6192000
+576 1 6216000
+576 1 6240000
+576 1 6264000
+576 1 6288000
+576 1 6312000
+576 1 6336000
+576 1 6360000
+576 1 6384000
+576 1 6408000
+576 1 6432000
+576 1 6456000
+576 1 6480000
+576 1 6504000
+576 1 6528000
+576 1 6552000
+576 1 6576000
+576 1 6600000
+576 1 6624000
+576 1 6648000
+576 1 6672000
+576 1 6696000
+576 1 6720000
+576 1 6744000
+576 1 6768000
+576 1 6792000
+576 1 6816000
+576 1 6840000
+576 1 6864000
+576 1 6888000
+576 1 6912000
+576 1 6936000
+576 1 6960000
+576 1 6984000
+576 1 7008000
+576 1 7032000
+576 1 7056000
+576 1 7080000
+576 1 7104000
+576 1 7128000
+576 1 7152000
+576 1 7176000
+576 1 7200000
+576 1 7224000
+576 1 7248000
+576 1 7272000
+576 1 7296000
+576 1 7320000
+576 1 7344000
+576 1 7368000
+576 1 7392000
+576 1 7416000
+576 1 7440000
+576 1 7464000
+576 1 7488000
+576 1 7512000
+576 1 7536000
+576 1 7560000
+576 1 7584000
+576 1 7608000
+576 1 7632000
+576 1 7656000
+576 1 7680000
+576 1 7704000
+576 1 7728000
+576 1 7752000
+576 1 7776000
+576 1 7800000
+576 1 7824000
+576 1 7848000
+576 1 7872000
+576 1 7896000
+576 1 7920000
+576 1 7944000
+576 1 7968000
+576 1 7992000
+576 1 8016000
+576 1 8040000
+576 1 8064000
+576 1 8088000
+576 1 8112000
+576 1 8136000
+576 1 8160000
+576 1 8184000
+576 1 8208000
+576 1 8232000
+576 1 8256000
+576 1 8280000
+576 1 8304000
+576 1 8328000
+576 1 8352000
+576 1 8376000
+576 1 8400000
+576 1 8424000
+576 1 8448000
+576 1 8472000
+576 1 8496000
+576 1 8520000
+576 1 8544000
+576 1 8568000
+576 1 8592000
+576 1 8616000
+576 1 8640000
+576 1 8664000
+576 1 8688000
+576 1 8712000
+576 1 8736000
+576 1 8760000
+576 1 8784000
+576 1 8808000
+576 1 8832000
+576 1 8856000
+576 1 8880000
+576 1 8904000
+576 1 8928000
+576 1 8952000
+576 1 8976000
+576 1 9000000
+576 1 9024000
+576 1 9048000
+576 1 9072000
+576 1 9096000
+576 1 9120000
+576 1 9144000
+576 1 9168000
+576 1 9192000
+576 1 9216000
+576 1 9240000
+576 1 9264000
+576 1 9288000
+576 1 9312000
+576 1 9336000
+576 1 9360000
+576 1 9384000
+576 1 9408000
+576 1 9432000
+576 1 9456000
+576 1 9480000
+576 1 9504000
+576 1 9528000
+576 1 9552000
+576 1 9576000
+576 1 9600000
+576 1 9624000
+576 1 9648000
+576 1 9672000
+576 1 9696000
+576 1 9720000
+576 1 9744000
+576 1 9768000
+576 1 9792000
+576 1 9816000
+576 1 9840000
+576 1 9864000
+576 1 9888000
+576 1 9912000
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_mp3_stereo_192kbps_48000hz.mp3 b/media/codec2/hidl/1.0/vts/functional/res/bbb_mp3_stereo_192kbps_48000hz.mp3
new file mode 100644
index 0000000..b83a4413
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_mp3_stereo_192kbps_48000hz.mp3
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_mp3_stereo_192kbps_48000hz_multi_frame.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_mp3_stereo_192kbps_48000hz_multi_frame.info
new file mode 100644
index 0000000..575c75f
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_mp3_stereo_192kbps_48000hz_multi_frame.info
@@ -0,0 +1,385 @@
+576 1 0
+576 1 24000
+1152 1 48000
+1152 1 96000
+1152 1 144000
+1152 1 192000
+1728 1 240000
+1728 1 312000
+1728 1 384000
+1728 1 456000
+1728 1 528000
+2304 1 600000
+2304 1 696000
+2304 1 792000
+2304 1 888000
+2304 1 984000
+576 1 1080000
+576 1 1104000
+576 1 1128000
+576 1 1152000
+576 1 1176000
+576 1 1200000
+576 1 1224000
+576 1 1248000
+576 1 1272000
+576 1 1296000
+576 1 1320000
+576 1 1344000
+576 1 1368000
+576 1 1392000
+576 1 1416000
+576 1 1440000
+576 1 1464000
+576 1 1488000
+576 1 1512000
+576 1 1536000
+576 1 1560000
+576 1 1584000
+576 1 1608000
+576 1 1632000
+576 1 1656000
+576 1 1680000
+576 1 1704000
+576 1 1728000
+576 1 1752000
+576 1 1776000
+576 1 1800000
+576 1 1824000
+576 1 1848000
+576 1 1872000
+576 1 1896000
+576 1 1920000
+576 1 1944000
+576 1 1968000
+576 1 1992000
+576 1 2016000
+576 1 2040000
+576 1 2064000
+576 1 2088000
+576 1 2112000
+576 1 2136000
+576 1 2160000
+576 1 2184000
+576 1 2208000
+576 1 2232000
+576 1 2256000
+576 1 2280000
+576 1 2304000
+576 1 2328000
+576 1 2352000
+576 1 2376000
+576 1 2400000
+576 1 2424000
+576 1 2448000
+576 1 2472000
+576 1 2496000
+576 1 2520000
+576 1 2544000
+576 1 2568000
+576 1 2592000
+576 1 2616000
+576 1 2640000
+576 1 2664000
+576 1 2688000
+576 1 2712000
+576 1 2736000
+576 1 2760000
+576 1 2784000
+576 1 2808000
+576 1 2832000
+576 1 2856000
+576 1 2880000
+576 1 2904000
+576 1 2928000
+576 1 2952000
+576 1 2976000
+576 1 3000000
+576 1 3024000
+576 1 3048000
+576 1 3072000
+576 1 3096000
+576 1 3120000
+576 1 3144000
+576 1 3168000
+576 1 3192000
+576 1 3216000
+576 1 3240000
+576 1 3264000
+576 1 3288000
+576 1 3312000
+576 1 3336000
+576 1 3360000
+576 1 3384000
+576 1 3408000
+576 1 3432000
+576 1 3456000
+576 1 3480000
+576 1 3504000
+576 1 3528000
+576 1 3552000
+576 1 3576000
+576 1 3600000
+576 1 3624000
+576 1 3648000
+576 1 3672000
+576 1 3696000
+576 1 3720000
+576 1 3744000
+576 1 3768000
+576 1 3792000
+576 1 3816000
+576 1 3840000
+576 1 3864000
+576 1 3888000
+576 1 3912000
+576 1 3936000
+576 1 3960000
+576 1 3984000
+576 1 4008000
+576 1 4032000
+576 1 4056000
+576 1 4080000
+576 1 4104000
+576 1 4128000
+576 1 4152000
+576 1 4176000
+576 1 4200000
+576 1 4224000
+576 1 4248000
+576 1 4272000
+576 1 4296000
+576 1 4320000
+576 1 4344000
+576 1 4368000
+576 1 4392000
+576 1 4416000
+576 1 4440000
+576 1 4464000
+576 1 4488000
+576 1 4512000
+576 1 4536000
+576 1 4560000
+576 1 4584000
+576 1 4608000
+576 1 4632000
+576 1 4656000
+576 1 4680000
+576 1 4704000
+576 1 4728000
+576 1 4752000
+576 1 4776000
+576 1 4800000
+576 1 4824000
+576 1 4848000
+576 1 4872000
+576 1 4896000
+576 1 4920000
+576 1 4944000
+576 1 4968000
+576 1 4992000
+576 1 5016000
+576 1 5040000
+576 1 5064000
+576 1 5088000
+576 1 5112000
+576 1 5136000
+576 1 5160000
+576 1 5184000
+576 1 5208000
+576 1 5232000
+576 1 5256000
+576 1 5280000
+576 1 5304000
+576 1 5328000
+576 1 5352000
+576 1 5376000
+576 1 5400000
+576 1 5424000
+576 1 5448000
+576 1 5472000
+576 1 5496000
+576 1 5520000
+576 1 5544000
+576 1 5568000
+576 1 5592000
+576 1 5616000
+576 1 5640000
+576 1 5664000
+576 1 5688000
+576 1 5712000
+576 1 5736000
+576 1 5760000
+576 1 5784000
+576 1 5808000
+576 1 5832000
+576 1 5856000
+576 1 5880000
+576 1 5904000
+576 1 5928000
+576 1 5952000
+576 1 5976000
+576 1 6000000
+576 1 6024000
+576 1 6048000
+576 1 6072000
+576 1 6096000
+576 1 6120000
+576 1 6144000
+576 1 6168000
+576 1 6192000
+576 1 6216000
+576 1 6240000
+576 1 6264000
+576 1 6288000
+576 1 6312000
+576 1 6336000
+576 1 6360000
+576 1 6384000
+576 1 6408000
+576 1 6432000
+576 1 6456000
+576 1 6480000
+576 1 6504000
+576 1 6528000
+576 1 6552000
+576 1 6576000
+576 1 6600000
+576 1 6624000
+576 1 6648000
+576 1 6672000
+576 1 6696000
+576 1 6720000
+576 1 6744000
+576 1 6768000
+576 1 6792000
+576 1 6816000
+576 1 6840000
+576 1 6864000
+576 1 6888000
+576 1 6912000
+576 1 6936000
+576 1 6960000
+576 1 6984000
+576 1 7008000
+576 1 7032000
+576 1 7056000
+576 1 7080000
+576 1 7104000
+576 1 7128000
+576 1 7152000
+576 1 7176000
+576 1 7200000
+576 1 7224000
+576 1 7248000
+576 1 7272000
+576 1 7296000
+576 1 7320000
+576 1 7344000
+576 1 7368000
+576 1 7392000
+576 1 7416000
+576 1 7440000
+576 1 7464000
+576 1 7488000
+576 1 7512000
+576 1 7536000
+576 1 7560000
+576 1 7584000
+576 1 7608000
+576 1 7632000
+576 1 7656000
+576 1 7680000
+576 1 7704000
+576 1 7728000
+576 1 7752000
+576 1 7776000
+576 1 7800000
+576 1 7824000
+576 1 7848000
+576 1 7872000
+576 1 7896000
+576 1 7920000
+576 1 7944000
+576 1 7968000
+576 1 7992000
+576 1 8016000
+576 1 8040000
+576 1 8064000
+576 1 8088000
+576 1 8112000
+576 1 8136000
+576 1 8160000
+576 1 8184000
+576 1 8208000
+576 1 8232000
+576 1 8256000
+576 1 8280000
+576 1 8304000
+576 1 8328000
+576 1 8352000
+576 1 8376000
+576 1 8400000
+576 1 8424000
+576 1 8448000
+576 1 8472000
+576 1 8496000
+576 1 8520000
+576 1 8544000
+576 1 8568000
+576 1 8592000
+576 1 8616000
+576 1 8640000
+576 1 8664000
+576 1 8688000
+576 1 8712000
+576 1 8736000
+576 1 8760000
+576 1 8784000
+576 1 8808000
+576 1 8832000
+576 1 8856000
+576 1 8880000
+576 1 8904000
+576 1 8928000
+576 1 8952000
+576 1 8976000
+576 1 9000000
+576 1 9024000
+576 1 9048000
+576 1 9072000
+576 1 9096000
+576 1 9120000
+576 1 9144000
+576 1 9168000
+576 1 9192000
+576 1 9216000
+576 1 9240000
+576 1 9264000
+576 1 9288000
+576 1 9312000
+576 1 9336000
+576 1 9360000
+576 1 9384000
+576 1 9408000
+576 1 9432000
+576 1 9456000
+576 1 9480000
+576 1 9504000
+576 1 9528000
+576 1 9552000
+576 1 9576000
+576 1 9600000
+576 1 9624000
+576 1 9648000
+576 1 9672000
+576 1 9696000
+576 1 9720000
+576 1 9744000
+576 1 9768000
+576 1 9792000
+576 1 9816000
+576 1 9840000
+576 1 9864000
+576 1 9888000
+576 1 9912000
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_mpeg2_176x144_105kbps_25fps.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_mpeg2_176x144_105kbps_25fps.info
new file mode 100644
index 0000000..c540642
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_mpeg2_176x144_105kbps_25fps.info
@@ -0,0 +1,249 @@
+6458 1 40000
+4040 0 80000
+3255 0 120000
+3026 0 160000
+3293 0 200000
+3089 0 240000
+3305 0 280000
+1794 0 320000
+1848 0 360000
+1288 0 400000
+1511 0 440000
+1527 0 480000
+6146 1 520000
+1243 0 560000
+1099 0 600000
+1354 0 640000
+1366 0 680000
+1042 0 720000
+1600 0 760000
+875 0 800000
+1728 0 840000
+1254 0 880000
+994 0 920000
+1591 0 960000
+6265 1 1000000
+1018 0 1040000
+825 0 1080000
+869 0 1120000
+921 0 1160000
+975 0 1200000
+924 0 1240000
+834 0 1280000
+1066 0 1320000
+793 0 1360000
+889 0 1400000
+2050 0 1440000
+6276 1 1480000
+881 0 1520000
+260 0 1560000
+730 0 1600000
+431 0 1640000
+351 0 1680000
+321 0 1720000
+3802 0 1760000
+146 0 1800000
+6462 0 1840000
+3246 0 1880000
+533 0 1920000
+6231 1 1960000
+1378 0 2000000
+719 0 2040000
+818 0 2080000
+856 0 2120000
+937 0 2160000
+611 0 2200000
+3031 0 2240000
+1041 0 2280000
+604 0 2320000
+714 0 2360000
+1283 0 2400000
+7565 1 2440000
+602 0 2480000
+530 0 2520000
+2579 0 2560000
+115 0 2600000
+1058 0 2640000
+689 0 2680000
+1119 0 2720000
+698 0 2760000
+1006 0 2800000
+545 0 2840000
+1617 0 2880000
+9123 1 2920000
+527 0 2960000
+1576 0 3000000
+465 0 3040000
+741 0 3080000
+521 0 3120000
+1322 0 3160000
+775 0 3200000
+863 0 3240000
+910 0 3280000
+915 0 3320000
+926 0 3360000
+7556 1 3400000
+741 0 3440000
+527 0 3480000
+2516 0 3520000
+459 0 3560000
+404 0 3600000
+509 0 3640000
+1227 0 3680000
+1561 0 3720000
+490 0 3760000
+712 0 3800000
+803 0 3840000
+7524 1 3880000
+730 0 3920000
+461 0 3960000
+2526 0 4000000
+453 0 4040000
+632 0 4080000
+783 0 4120000
+843 0 4160000
+918 0 4200000
+961 0 4240000
+948 0 4280000
+959 0 4320000
+7598 1 4360000
+678 0 4400000
+569 0 4440000
+893 0 4480000
+624 0 4520000
+755 0 4560000
+2234 0 4600000
+556 0 4640000
+944 0 4680000
+739 0 4720000
+862 0 4760000
+938 0 4800000
+7574 1 4840000
+699 0 4880000
+701 0 4920000
+530 0 4960000
+689 0 5000000
+778 0 5040000
+856 0 5080000
+930 0 5120000
+975 0 5160000
+1021 0 5200000
+1074 0 5240000
+978 0 5280000
+8021 1 5320000
+704 0 5360000
+610 0 5400000
+697 0 5440000
+711 0 5480000
+820 0 5520000
+843 0 5560000
+251 0 5600000
+3367 0 5640000
+507 0 5680000
+3168 1 5720000
+779 0 5760000
+316 0 5800000
+635 0 5840000
+204 0 5880000
+978 0 5920000
+127 0 5960000
+589 0 6000000
+604 0 6040000
+666 0 6080000
+582 0 6120000
+729 0 6160000
+4152 1 6200000
+858 0 6240000
+739 0 6280000
+885 0 6320000
+749 0 6360000
+950 0 6400000
+593 0 6440000
+771 0 6480000
+678 0 6520000
+529 0 6560000
+835 0 6600000
+391 0 6640000
+4692 1 6680000
+473 0 6720000
+724 0 6760000
+381 0 6800000
+909 0 6840000
+394 0 6880000
+659 0 6920000
+367 0 6960000
+658 0 7000000
+523 0 7040000
+554 0 7080000
+553 0 7120000
+6080 1 7160000
+496 0 7200000
+763 0 7240000
+939 0 7280000
+715 0 7320000
+672 0 7360000
+614 0 7400000
+811 0 7440000
+916 0 7480000
+1153 0 7520000
+940 0 7560000
+322 0 7600000
+6613 1 7640000
+851 0 7680000
+1007 0 7720000
+520 0 7760000
+456 0 7800000
+639 0 7840000
+758 0 7880000
+879 0 7920000
+1152 0 7960000
+1061 0 8000000
+946 0 8040000
+859 0 8080000
+3610 1 8120000
+871 0 8160000
+746 0 8200000
+367 0 8240000
+397 0 8280000
+930 0 8320000
+337 0 8360000
+418 0 8400000
+740 0 8440000
+637 0 8480000
+666 0 8520000
+627 0 8560000
+4338 1 8600000
+745 0 8640000
+783 0 8680000
+465 0 8720000
+460 0 8760000
+455 0 8800000
+506 0 8840000
+492 0 8880000
+485 0 8920000
+517 0 8960000
+534 0 9000000
+395 0 9040000
+5626 1 9080000
+1169 0 9120000
+564 0 9160000
+261 0 9200000
+327 0 9240000
+303 0 9280000
+1145 0 9320000
+257 0 9360000
+498 0 9400000
+465 0 9440000
+414 0 9480000
+553 0 9520000
+5617 1 9560000
+1052 0 9600000
+592 0 9640000
+323 0 9680000
+497 0 9720000
+467 0 9760000
+705 0 9800000
+1086 0 9840000
+1253 0 9880000
+1252 0 9920000
+776 0 9960000
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_mpeg2_176x144_105kbps_25fps.m2v b/media/codec2/hidl/1.0/vts/functional/res/bbb_mpeg2_176x144_105kbps_25fps.m2v
new file mode 100644
index 0000000..cdf90c3
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_mpeg2_176x144_105kbps_25fps.m2v
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_mpeg2_352x288_1mbps_60fps.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_mpeg2_352x288_1mbps_60fps.info
new file mode 100644
index 0000000..417caf9
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_mpeg2_352x288_1mbps_60fps.info
@@ -0,0 +1,60 @@
+16680 1 16666
+17017 0 33333
+10534 0 50000
+10289 0 66666
+3698 0 83333
+2776 0 100000
+1936 0 116666
+1493 0 133333
+1217 0 150000
+993 0 166666
+805 0 183333
+857 0 200000
+5082 1 216666
+812 0 233333
+718 0 250000
+746 0 266666
+762 0 283333
+865 0 300000
+782 0 316666
+833 0 333333
+750 0 350000
+819 0 366666
+826 0 383333
+846 0 400000
+4522 1 416666
+678 0 433333
+718 0 450000
+803 0 466666
+769 0 483333
+762 0 500000
+587 0 516666
+635 0 533333
+658 0 550000
+714 0 566666
+677 0 583333
+699 0 600000
+4616 1 616666
+800 0 633333
+831 0 650000
+928 0 666666
+869 0 683333
+931 0 700000
+930 0 716666
+974 0 733333
+978 0 750000
+932 0 766666
+918 0 783333
+978 0 800000
+4655 1 816666
+897 0 833333
+896 0 850000
+883 0 866666
+949 0 883333
+965 0 900000
+951 0 916666
+901 0 933333
+965 0 950000
+955 0 966666
+948 0 983333
+968 0 1000000
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_mpeg2_352x288_1mbps_60fps.m2v b/media/codec2/hidl/1.0/vts/functional/res/bbb_mpeg2_352x288_1mbps_60fps.m2v
new file mode 100644
index 0000000..2f67c2b
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_mpeg2_352x288_1mbps_60fps.m2v
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_mpeg4_352x288_512kbps_30fps.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_mpeg4_352x288_512kbps_30fps.info
new file mode 100644
index 0000000..69ba9b2
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_mpeg4_352x288_512kbps_30fps.info
@@ -0,0 +1,241 @@
+47 32 0
+21115 1 0
+16456 0 33333
+11880 0 66666
+12155 0 100000
+11402 0 133333
+5345 0 166666
+2986 0 200000
+1924 0 233333
+2275 0 266666
+2793 0 300000
+2756 0 333333
+2933 0 366666
+21100 1 400000
+1302 0 433333
+2206 0 466666
+1599 0 500000
+2558 0 533333
+2784 0 566666
+2458 0 600000
+2480 0 633333
+1446 0 666666
+3109 0 700000
+944 0 733333
+3134 0 766666
+21342 1 800000
+652 0 833333
+1708 0 866666
+2202 0 900000
+1695 0 933333
+1661 0 966666
+1652 0 1000000
+1679 0 1033333
+1690 0 1066666
+1824 0 1100000
+1803 0 1133333
+1598 0 1166666
+21540 1 1200000
+205 0 1233333
+1124 0 1266666
+1069 0 1300000
+838 0 1333333
+765 0 1366666
+4265 0 1400000
+94 0 1433333
+20463 0 1466666
+1028 0 1500000
+1475 0 1533333
+3630 0 1566666
+28373 1 1600000
+725 0 1633333
+1119 0 1666666
+1427 0 1700000
+1679 0 1733333
+1866 0 1766666
+1197 0 1800000
+1572 0 1833333
+1651 0 1866666
+1678 0 1900000
+1688 0 1933333
+1659 0 1966666
+19900 1 2000000
+584 0 2033333
+1475 0 2066666
+1678 0 2100000
+1010 0 2133333
+1435 0 2166666
+1612 0 2200000
+1602 0 2233333
+1709 0 2266666
+1737 0 2300000
+1835 0 2333333
+926 0 2366666
+20090 1 2400000
+631 0 2433333
+1576 0 2466666
+941 0 2500000
+2349 0 2533333
+1112 0 2566666
+1566 0 2600000
+1773 0 2633333
+979 0 2666666
+2246 0 2700000
+904 0 2733333
+1342 0 2766666
+20147 1 2800000
+630 0 2833333
+982 0 2866666
+2089 0 2900000
+1021 0 2933333
+1506 0 2966666
+1642 0 3000000
+968 0 3033333
+1262 0 3066666
+2270 0 3100000
+864 0 3133333
+1252 0 3166666
+20145 1 3200000
+595 0 3233333
+918 0 3266666
+1167 0 3300000
+1347 0 3333333
+1597 0 3366666
+1636 0 3400000
+944 0 3433333
+1295 0 3466666
+1397 0 3500000
+1413 0 3533333
+1432 0 3566666
+20180 1 3600000
+525 0 3633333
+1068 0 3666666
+1230 0 3700000
+1428 0 3733333
+916 0 3766666
+1948 0 3800000
+966 0 3833333
+1342 0 3866666
+1338 0 3900000
+1379 0 3933333
+1296 0 3966666
+17378 1 4000000
+583 0 4033333
+936 0 4066666
+1745 0 4100000
+987 0 4133333
+1393 0 4166666
+1495 0 4200000
+869 0 4233333
+1938 0 4266666
+828 0 4300000
+1851 0 4333333
+834 0 4366666
+17280 1 4400000
+580 0 4433333
+869 0 4466666
+1605 0 4500000
+843 0 4533333
+6147 1 4566666
+220 0 4600000
+1106 0 4633333
+395 0 4666666
+304 0 4700000
+1946 0 4733333
+154 0 4766666
+482 0 4800000
+949 0 4833333
+1088 0 4866666
+974 0 4900000
+876 0 4933333
+9164 1 4966666
+1019 0 5000000
+983 0 5033333
+1375 0 5066666
+1041 0 5100000
+789 0 5133333
+1037 0 5166666
+812 0 5200000
+732 0 5233333
+972 0 5266666
+708 0 5300000
+623 0 5333333
+10667 1 5366666
+463 0 5400000
+911 0 5433333
+861 0 5466666
+507 0 5500000
+1015 0 5533333
+501 0 5566666
+934 0 5600000
+812 0 5633333
+855 0 5666666
+804 0 5700000
+783 0 5733333
+10610 1 5766666
+950 0 5800000
+1292 0 5833333
+1002 0 5866666
+728 0 5900000
+960 0 5933333
+1230 0 5966666
+1315 0 6000000
+1248 0 6033333
+995 0 6066666
+1401 0 6100000
+905 0 6133333
+9326 1 6166666
+726 0 6200000
+667 0 6233333
+833 0 6266666
+1007 0 6300000
+1172 0 6333333
+1910 0 6366666
+1954 0 6400000
+1498 0 6433333
+1188 0 6466666
+784 0 6500000
+1005 0 6533333
+10030 1 6566666
+452 0 6600000
+763 0 6633333
+639 0 6666666
+671 0 6700000
+867 0 6733333
+963 0 6766666
+982 0 6800000
+995 0 6833333
+982 0 6866666
+747 0 6900000
+574 0 6933333
+12353 1 6966666
+474 0 7000000
+969 0 7033333
+633 0 7066666
+723 0 7100000
+1221 0 7133333
+674 0 7166666
+776 0 7200000
+572 0 7233333
+912 0 7266666
+564 0 7300000
+594 0 7333333
+16661 1 7366666
+518 0 7400000
+656 0 7433333
+625 0 7466666
+583 0 7500000
+584 0 7533333
+1027 0 7566666
+812 0 7600000
+729 0 7633333
+766 0 7666666
+901 0 7700000
+960 0 7733333
+12336 1 7766666
+944 0 7800000
+1398 0 7833333
+1625 0 7866666
+2103 0 7900000
+1630 0 7933333
+1228 0 7966666
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_mpeg4_352x288_512kbps_30fps.m4v b/media/codec2/hidl/1.0/vts/functional/res/bbb_mpeg4_352x288_512kbps_30fps.m4v
new file mode 100644
index 0000000..b7ead00
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_mpeg4_352x288_512kbps_30fps.m4v
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_opus_stereo_128kbps_48000hz.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_opus_stereo_128kbps_48000hz.info
new file mode 100644
index 0000000..1ced12b
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_opus_stereo_128kbps_48000hz.info
@@ -0,0 +1,499 @@
+19 32 0
+8 32 0
+8 32 0
+529 1 0
+329 1 13500
+349 1 33500
+336 1 53500
+383 1 73500
+359 1 93500
+344 1 113500
+343 1 133500
+332 1 153500
+320 1 173500
+319 1 193500
+323 1 213500
+320 1 233500
+328 1 253500
+340 1 273500
+318 1 293500
+319 1 313500
+335 1 333500
+511 1 353500
+395 1 373500
+327 1 393500
+479 1 413500
+332 1 433500
+320 1 453500
+321 1 473500
+310 1 493500
+310 1 513500
+310 1 533500
+326 1 553500
+330 1 573500
+318 1 593500
+309 1 613500
+304 1 633500
+298 1 653500
+294 1 673500
+300 1 693500
+314 1 713500
+304 1 733500
+307 1 753500
+321 1 773500
+333 1 793500
+335 1 813500
+306 1 833500
+315 1 853500
+320 1 873500
+315 1 893500
+308 1 913500
+320 1 933500
+311 1 953500
+311 1 973500
+313 1 993500
+314 1 1013500
+308 1 1033500
+307 1 1053500
+317 1 1073500
+328 1 1093500
+317 1 1113500
+312 1 1133500
+308 1 1153500
+315 1 1173500
+320 1 1193500
+322 1 1213500
+323 1 1233500
+322 1 1253500
+322 1 1273500
+301 1 1293500
+303 1 1313500
+308 1 1333500
+299 1 1353500
+297 1 1373500
+293 1 1393500
+295 1 1413500
+297 1 1433500
+300 1 1453500
+294 1 1473500
+299 1 1493500
+296 1 1513500
+303 1 1533500
+313 1 1553500
+306 1 1573500
+303 1 1593500
+311 1 1613500
+307 1 1633500
+310 1 1653500
+339 1 1673500
+325 1 1693500
+320 1 1713500
+315 1 1733500
+316 1 1753500
+338 1 1773500
+325 1 1793500
+325 1 1813500
+328 1 1833500
+304 1 1853500
+297 1 1873500
+322 1 1893500
+311 1 1913500
+307 1 1933500
+300 1 1953500
+301 1 1973500
+309 1 1993500
+300 1 2013500
+306 1 2033500
+305 1 2053500
+298 1 2073500
+291 1 2093500
+301 1 2113500
+300 1 2133500
+439 1 2153500
+292 1 2173500
+308 1 2193500
+305 1 2213500
+298 1 2233500
+297 1 2253500
+293 1 2273500
+408 1 2293500
+298 1 2313500
+452 1 2333500
+297 1 2353500
+303 1 2373500
+300 1 2393500
+310 1 2413500
+299 1 2433500
+306 1 2453500
+316 1 2473500
+308 1 2493500
+313 1 2513500
+309 1 2533500
+310 1 2553500
+315 1 2573500
+309 1 2593500
+317 1 2613500
+311 1 2633500
+328 1 2653500
+333 1 2673500
+326 1 2693500
+323 1 2713500
+316 1 2733500
+325 1 2753500
+316 1 2773500
+319 1 2793500
+326 1 2813500
+320 1 2833500
+328 1 2853500
+312 1 2873500
+314 1 2893500
+309 1 2913500
+306 1 2933500
+295 1 2953500
+304 1 2973500
+326 1 2993500
+291 1 3013500
+299 1 3033500
+293 1 3053500
+288 1 3073500
+294 1 3093500
+292 1 3113500
+292 1 3133500
+288 1 3153500
+308 1 3173500
+304 1 3193500
+292 1 3213500
+382 1 3233500
+381 1 3253500
+299 1 3273500
+316 1 3293500
+308 1 3313500
+301 1 3333500
+297 1 3353500
+299 1 3373500
+294 1 3393500
+295 1 3413500
+317 1 3433500
+297 1 3453500
+309 1 3473500
+313 1 3493500
+320 1 3513500
+329 1 3533500
+330 1 3553500
+324 1 3573500
+324 1 3593500
+309 1 3613500
+304 1 3633500
+313 1 3653500
+312 1 3673500
+299 1 3693500
+295 1 3713500
+301 1 3733500
+295 1 3753500
+297 1 3773500
+302 1 3793500
+298 1 3813500
+299 1 3833500
+296 1 3853500
+292 1 3873500
+307 1 3893500
+303 1 3913500
+313 1 3933500
+318 1 3953500
+313 1 3973500
+353 1 3993500
+371 1 4013500
+292 1 4033500
+300 1 4053500
+381 1 4073500
+294 1 4093500
+301 1 4113500
+305 1 4133500
+299 1 4153500
+305 1 4173500
+322 1 4193500
+315 1 4213500
+326 1 4233500
+338 1 4253500
+320 1 4273500
+319 1 4293500
+327 1 4313500
+330 1 4333500
+310 1 4353500
+303 1 4373500
+299 1 4393500
+293 1 4413500
+293 1 4433500
+294 1 4453500
+295 1 4473500
+295 1 4493500
+323 1 4513500
+309 1 4533500
+309 1 4553500
+301 1 4573500
+473 1 4593500
+291 1 4613500
+297 1 4633500
+294 1 4653500
+293 1 4673500
+304 1 4693500
+292 1 4713500
+302 1 4733500
+296 1 4753500
+298 1 4773500
+301 1 4793500
+307 1 4813500
+285 1 4833500
+294 1 4853500
+304 1 4873500
+294 1 4893500
+295 1 4913500
+325 1 4933500
+319 1 4953500
+323 1 4973500
+313 1 4993500
+303 1 5013500
+296 1 5033500
+295 1 5053500
+290 1 5073500
+297 1 5093500
+296 1 5113500
+296 1 5133500
+292 1 5153500
+295 1 5173500
+287 1 5193500
+294 1 5213500
+290 1 5233500
+297 1 5253500
+297 1 5273500
+297 1 5293500
+292 1 5313500
+297 1 5333500
+290 1 5353500
+293 1 5373500
+293 1 5393500
+291 1 5413500
+292 1 5433500
+290 1 5453500
+291 1 5473500
+296 1 5493500
+295 1 5513500
+327 1 5533500
+293 1 5553500
+291 1 5573500
+291 1 5593500
+311 1 5613500
+291 1 5633500
+294 1 5653500
+296 1 5673500
+295 1 5693500
+289 1 5713500
+295 1 5733500
+295 1 5753500
+297 1 5773500
+292 1 5793500
+297 1 5813500
+292 1 5833500
+295 1 5853500
+296 1 5873500
+295 1 5893500
+303 1 5913500
+304 1 5933500
+301 1 5953500
+307 1 5973500
+304 1 5993500
+310 1 6013500
+310 1 6033500
+305 1 6053500
+301 1 6073500
+302 1 6093500
+305 1 6113500
+298 1 6133500
+300 1 6153500
+300 1 6173500
+292 1 6193500
+297 1 6213500
+301 1 6233500
+297 1 6253500
+297 1 6273500
+298 1 6293500
+297 1 6313500
+300 1 6333500
+293 1 6353500
+293 1 6373500
+297 1 6393500
+294 1 6413500
+307 1 6433500
+302 1 6453500
+307 1 6473500
+320 1 6493500
+330 1 6513500
+333 1 6533500
+337 1 6553500
+331 1 6573500
+323 1 6593500
+312 1 6613500
+326 1 6633500
+328 1 6653500
+332 1 6673500
+333 1 6693500
+340 1 6713500
+336 1 6733500
+324 1 6753500
+312 1 6773500
+301 1 6793500
+289 1 6813500
+302 1 6833500
+296 1 6853500
+299 1 6873500
+289 1 6893500
+295 1 6913500
+299 1 6933500
+374 1 6953500
+391 1 6973500
+365 1 6993500
+340 1 7013500
+330 1 7033500
+337 1 7053500
+328 1 7073500
+329 1 7093500
+319 1 7113500
+312 1 7133500
+308 1 7153500
+304 1 7173500
+312 1 7193500
+311 1 7213500
+316 1 7233500
+299 1 7253500
+330 1 7273500
+330 1 7293500
+330 1 7313500
+342 1 7333500
+439 1 7353500
+322 1 7373500
+298 1 7393500
+293 1 7413500
+310 1 7433500
+303 1 7453500
+317 1 7473500
+453 1 7493500
+377 1 7513500
+374 1 7533500
+292 1 7553500
+295 1 7573500
+274 1 7593500
+292 1 7613500
+291 1 7633500
+367 1 7653500
+295 1 7673500
+298 1 7693500
+297 1 7713500
+301 1 7733500
+292 1 7753500
+344 1 7773500
+296 1 7793500
+297 1 7813500
+306 1 7833500
+308 1 7853500
+305 1 7873500
+313 1 7893500
+306 1 7913500
+322 1 7933500
+313 1 7953500
+305 1 7973500
+304 1 7993500
+313 1 8013500
+324 1 8033500
+312 1 8053500
+318 1 8073500
+311 1 8093500
+302 1 8113500
+305 1 8133500
+312 1 8153500
+313 1 8173500
+312 1 8193500
+335 1 8213500
+333 1 8233500
+346 1 8253500
+339 1 8273500
+337 1 8293500
+341 1 8313500
+335 1 8333500
+325 1 8353500
+324 1 8373500
+317 1 8393500
+315 1 8413500
+303 1 8433500
+317 1 8453500
+452 1 8473500
+324 1 8493500
+321 1 8513500
+335 1 8533500
+327 1 8553500
+315 1 8573500
+321 1 8593500
+319 1 8613500
+308 1 8633500
+314 1 8653500
+322 1 8673500
+328 1 8693500
+320 1 8713500
+324 1 8733500
+331 1 8753500
+330 1 8773500
+328 1 8793500
+318 1 8813500
+314 1 8833500
+318 1 8853500
+318 1 8873500
+325 1 8893500
+338 1 8913500
+341 1 8933500
+333 1 8953500
+330 1 8973500
+338 1 8993500
+333 1 9013500
+330 1 9033500
+344 1 9053500
+479 1 9073500
+473 1 9093500
+333 1 9113500
+337 1 9133500
+495 1 9153500
+353 1 9173500
+352 1 9193500
+344 1 9213500
+336 1 9233500
+324 1 9253500
+321 1 9273500
+350 1 9293500
+347 1 9313500
+343 1 9333500
+345 1 9353500
+337 1 9373500
+335 1 9393500
+333 1 9413500
+336 1 9433500
+334 1 9453500
+333 1 9473500
+331 1 9493500
+329 1 9513500
+319 1 9533500
+321 1 9553500
+316 1 9573500
+322 1 9593500
+448 1 9613500
+312 1 9633500
+306 1 9653500
+301 1 9673500
+303 1 9693500
+296 1 9713500
+300 1 9733500
+295 1 9753500
+300 1 9773500
+297 1 9793500
+300 1 9813500
+297 1 9833500
+512 1 9853500
+292 1 9873500
+468 1 9893500
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_opus_stereo_128kbps_48000hz.opus b/media/codec2/hidl/1.0/vts/functional/res/bbb_opus_stereo_128kbps_48000hz.opus
new file mode 100644
index 0000000..2b6b870
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_opus_stereo_128kbps_48000hz.opus
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_raw_1ch_16khz_s16le.raw b/media/codec2/hidl/1.0/vts/functional/res/bbb_raw_1ch_16khz_s16le.raw
new file mode 100644
index 0000000..4a2f41b
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_raw_1ch_16khz_s16le.raw
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_raw_1ch_8khz_s16le.raw b/media/codec2/hidl/1.0/vts/functional/res/bbb_raw_1ch_8khz_s16le.raw
new file mode 100644
index 0000000..3149eb2
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_raw_1ch_8khz_s16le.raw
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_raw_1ch_8khz_s32le.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_raw_1ch_8khz_s32le.info
new file mode 100644
index 0000000..10e24cc
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_raw_1ch_8khz_s32le.info
@@ -0,0 +1,10 @@
+16384 1 0
+16384 1 1024000
+16384 1 2048000
+16384 1 3072000
+16384 1 4096000
+16384 1 5120000
+16384 1 6144000
+16384 1 7168000
+16384 1 8192000
+10924 1 9216000
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_raw_1ch_8khz_s32le.raw b/media/codec2/hidl/1.0/vts/functional/res/bbb_raw_1ch_8khz_s32le.raw
new file mode 100644
index 0000000..fd91b46
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_raw_1ch_8khz_s32le.raw
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_raw_2ch_48khz_s16le.raw b/media/codec2/hidl/1.0/vts/functional/res/bbb_raw_2ch_48khz_s16le.raw
new file mode 100644
index 0000000..498b2ec
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_raw_2ch_48khz_s16le.raw
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_vorbis_stereo_128kbps_48000hz.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_vorbis_stereo_128kbps_48000hz.info
new file mode 100644
index 0000000..d9a6d33
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_vorbis_stereo_128kbps_48000hz.info
@@ -0,0 +1,520 @@
+30 32 0
+4140 32 0
+33 32 0
+52 1 0
+58 1 2666
+61 1 5333
+56 1 8000
+59 1 10666
+63 1 13333
+66 1 16000
+71 1 18666
+76 1 21333
+374 1 24000
+366 1 36000
+378 1 57333
+393 1 78666
+393 1 100000
+386 1 121333
+375 1 142666
+388 1 164000
+378 1 185333
+379 1 206666
+374 1 228000
+356 1 249333
+358 1 270666
+332 1 292000
+335 1 313333
+363 1 334666
+341 1 356000
+360 1 377333
+341 1 398666
+335 1 420000
+357 1 441333
+355 1 462666
+363 1 484000
+382 1 505333
+371 1 526666
+357 1 548000
+353 1 569333
+350 1 590666
+327 1 612000
+315 1 633333
+307 1 654666
+303 1 676000
+295 1 697333
+312 1 718666
+316 1 740000
+315 1 761333
+318 1 782666
+330 1 804000
+318 1 825333
+315 1 846666
+322 1 868000
+315 1 889333
+310 1 910666
+315 1 932000
+314 1 953333
+302 1 974666
+313 1 996000
+322 1 1017333
+323 1 1038666
+319 1 1060000
+325 1 1081333
+328 1 1102666
+330 1 1124000
+333 1 1145333
+330 1 1166666
+344 1 1188000
+331 1 1209333
+342 1 1230666
+339 1 1252000
+314 1 1273333
+285 1 1294666
+295 1 1316000
+302 1 1337333
+305 1 1358666
+309 1 1380000
+327 1 1401333
+304 1 1422666
+336 1 1444000
+350 1 1465333
+346 1 1486666
+352 1 1508000
+341 1 1529333
+343 1 1550666
+351 1 1572000
+319 1 1593333
+328 1 1614666
+328 1 1636000
+324 1 1657333
+338 1 1678666
+317 1 1700000
+328 1 1721333
+335 1 1742666
+341 1 1764000
+335 1 1785333
+348 1 1806666
+362 1 1828000
+361 1 1849333
+344 1 1870666
+340 1 1892000
+333 1 1913333
+329 1 1934666
+328 1 1956000
+323 1 1977333
+310 1 1998666
+318 1 2020000
+312 1 2041333
+295 1 2062666
+329 1 2084000
+318 1 2105333
+311 1 2126666
+317 1 2148000
+62 1 2169333
+75 1 2181333
+73 1 2184000
+332 1 2186666
+327 1 2198666
+332 1 2220000
+325 1 2241333
+329 1 2262666
+330 1 2284000
+61 1 2305333
+61 1 2317333
+70 1 2320000
+70 1 2322666
+319 1 2325333
+303 1 2337333
+292 1 2358666
+313 1 2380000
+318 1 2401333
+346 1 2422666
+328 1 2444000
+316 1 2465333
+341 1 2486666
+328 1 2508000
+338 1 2529333
+341 1 2550666
+337 1 2572000
+347 1 2593333
+384 1 2614666
+358 1 2636000
+363 1 2657333
+363 1 2678666
+358 1 2700000
+339 1 2721333
+369 1 2742666
+343 1 2764000
+348 1 2785333
+363 1 2806666
+350 1 2828000
+358 1 2849333
+352 1 2870666
+338 1 2892000
+335 1 2913333
+342 1 2934666
+338 1 2956000
+340 1 2977333
+292 1 2998666
+279 1 3020000
+299 1 3041333
+303 1 3062666
+298 1 3084000
+297 1 3105333
+280 1 3126666
+297 1 3148000
+290 1 3169333
+306 1 3190666
+301 1 3212000
+306 1 3233333
+289 1 3254666
+311 1 3276000
+317 1 3297333
+344 1 3318666
+308 1 3340000
+304 1 3361333
+304 1 3382666
+312 1 3404000
+305 1 3425333
+299 1 3446666
+301 1 3468000
+318 1 3489333
+313 1 3510666
+330 1 3532000
+325 1 3553333
+325 1 3574666
+321 1 3596000
+349 1 3617333
+288 1 3638666
+300 1 3660000
+312 1 3681333
+302 1 3702666
+278 1 3724000
+284 1 3745333
+286 1 3766666
+274 1 3788000
+295 1 3809333
+281 1 3830666
+288 1 3852000
+278 1 3873333
+306 1 3894666
+62 1 3916000
+59 1 3928000
+61 1 3930666
+55 1 3933333
+70 1 3936000
+72 1 3938666
+324 1 3941333
+309 1 3953333
+301 1 3974666
+301 1 3996000
+291 1 4017333
+289 1 4038666
+306 1 4060000
+305 1 4081333
+286 1 4102666
+294 1 4124000
+290 1 4145333
+297 1 4166666
+308 1 4188000
+296 1 4209333
+292 1 4230666
+287 1 4252000
+291 1 4273333
+298 1 4294666
+295 1 4316000
+294 1 4337333
+295 1 4358666
+275 1 4380000
+280 1 4401333
+288 1 4422666
+285 1 4444000
+274 1 4465333
+298 1 4486666
+301 1 4508000
+300 1 4529333
+305 1 4550666
+297 1 4572000
+59 1 4593333
+56 1 4605333
+57 1 4608000
+55 1 4610666
+58 1 4613333
+57 1 4616000
+58 1 4618666
+68 1 4621333
+67 1 4624000
+71 1 4626666
+289 1 4629333
+282 1 4641333
+273 1 4662666
+279 1 4684000
+286 1 4705333
+282 1 4726666
+284 1 4748000
+278 1 4769333
+281 1 4790666
+280 1 4812000
+263 1 4833333
+260 1 4854666
+271 1 4876000
+273 1 4897333
+282 1 4918666
+279 1 4940000
+297 1 4961333
+291 1 4982666
+309 1 5004000
+283 1 5025333
+292 1 5046666
+304 1 5068000
+296 1 5089333
+293 1 5110666
+282 1 5132000
+273 1 5153333
+284 1 5174666
+281 1 5196000
+265 1 5217333
+272 1 5238666
+277 1 5260000
+280 1 5281333
+276 1 5302666
+273 1 5324000
+278 1 5345333
+280 1 5366666
+280 1 5388000
+268 1 5409333
+282 1 5430666
+277 1 5452000
+274 1 5473333
+275 1 5494666
+270 1 5516000
+282 1 5537333
+279 1 5558666
+260 1 5580000
+272 1 5601333
+275 1 5622666
+273 1 5644000
+276 1 5665333
+288 1 5686666
+294 1 5708000
+271 1 5729333
+277 1 5750666
+288 1 5772000
+276 1 5793333
+282 1 5814666
+276 1 5836000
+275 1 5857333
+268 1 5878666
+270 1 5900000
+266 1 5921333
+268 1 5942666
+282 1 5964000
+279 1 5985333
+279 1 6006666
+287 1 6028000
+286 1 6049333
+280 1 6070666
+290 1 6092000
+266 1 6113333
+292 1 6134666
+264 1 6156000
+271 1 6177333
+277 1 6198666
+292 1 6220000
+298 1 6241333
+284 1 6262666
+287 1 6284000
+275 1 6305333
+291 1 6326666
+287 1 6348000
+283 1 6369333
+284 1 6390666
+271 1 6412000
+282 1 6433333
+277 1 6454666
+282 1 6476000
+285 1 6497333
+280 1 6518666
+271 1 6540000
+289 1 6561333
+287 1 6582666
+294 1 6604000
+277 1 6625333
+281 1 6646666
+274 1 6668000
+271 1 6689333
+279 1 6710666
+288 1 6732000
+280 1 6753333
+284 1 6774666
+278 1 6796000
+276 1 6817333
+275 1 6838666
+263 1 6860000
+266 1 6881333
+247 1 6902666
+269 1 6924000
+263 1 6945333
+283 1 6966666
+280 1 6988000
+281 1 7009333
+299 1 7030666
+285 1 7052000
+288 1 7073333
+299 1 7094666
+288 1 7116000
+279 1 7137333
+276 1 7158666
+277 1 7180000
+282 1 7201333
+285 1 7222666
+295 1 7244000
+294 1 7265333
+304 1 7286666
+282 1 7308000
+299 1 7329333
+283 1 7350666
+282 1 7372000
+287 1 7393333
+306 1 7414666
+304 1 7436000
+289 1 7457333
+299 1 7478666
+281 1 7500000
+281 1 7521333
+66 1 7542666
+63 1 7554666
+289 1 7557333
+270 1 7569333
+257 1 7590666
+246 1 7612000
+264 1 7633333
+280 1 7654666
+273 1 7676000
+285 1 7697333
+267 1 7718666
+275 1 7740000
+278 1 7761333
+293 1 7782666
+281 1 7804000
+297 1 7825333
+294 1 7846666
+286 1 7868000
+290 1 7889333
+290 1 7910666
+289 1 7932000
+286 1 7953333
+282 1 7974666
+306 1 7996000
+287 1 8017333
+312 1 8038666
+312 1 8060000
+307 1 8081333
+293 1 8102666
+289 1 8124000
+285 1 8145333
+290 1 8166666
+285 1 8188000
+311 1 8209333
+307 1 8230666
+314 1 8252000
+318 1 8273333
+319 1 8294666
+315 1 8316000
+300 1 8337333
+295 1 8358666
+291 1 8380000
+282 1 8401333
+295 1 8422666
+296 1 8444000
+288 1 8465333
+304 1 8486666
+299 1 8508000
+298 1 8529333
+305 1 8550666
+295 1 8572000
+296 1 8593333
+295 1 8614666
+287 1 8636000
+292 1 8657333
+308 1 8678666
+287 1 8700000
+307 1 8721333
+295 1 8742666
+292 1 8764000
+292 1 8785333
+279 1 8806666
+289 1 8828000
+303 1 8849333
+307 1 8870666
+310 1 8892000
+300 1 8913333
+299 1 8934666
+299 1 8956000
+288 1 8977333
+290 1 8998666
+291 1 9020000
+304 1 9041333
+299 1 9062666
+304 1 9084000
+290 1 9105333
+309 1 9126666
+301 1 9148000
+296 1 9169333
+288 1 9190666
+305 1 9212000
+317 1 9233333
+292 1 9254666
+300 1 9276000
+301 1 9297333
+295 1 9318666
+282 1 9340000
+296 1 9361333
+295 1 9382666
+287 1 9404000
+292 1 9425333
+301 1 9446666
+311 1 9468000
+301 1 9489333
+307 1 9510666
+300 1 9532000
+309 1 9553333
+298 1 9574666
+304 1 9596000
+60 1 9617333
+59 1 9629333
+64 1 9632000
+64 1 9634666
+77 1 9637333
+72 1 9640000
+306 1 9642666
+297 1 9654666
+294 1 9676000
+295 1 9697333
+308 1 9718666
+303 1 9740000
+308 1 9761333
+289 1 9782666
+300 1 9804000
+304 1 9825333
+308 1 9846666
+64 1 9868000
+63 1 9880000
+64 1 9882666
+64 1 9885333
+60 1 9888000
+74 1 9890666
+69 1 9893333
+68 1 9896000
+61 1 9898666
+71 1 9901333
+76 1 9904000
+73 1 9906666
+70 1 9909333
+72 1 9912000
+60 1 9914666
+69 1 9917333
+82 1 9920000
+278 1 9922666
+30 1 9934666
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_vorbis_stereo_128kbps_48000hz.vorbis b/media/codec2/hidl/1.0/vts/functional/res/bbb_vorbis_stereo_128kbps_48000hz.vorbis
new file mode 100644
index 0000000..404c5f8
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_vorbis_stereo_128kbps_48000hz.vorbis
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_vp8_176x144_240kbps_60fps.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_vp8_176x144_240kbps_60fps.info
new file mode 100644
index 0000000..901ea45
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_vp8_176x144_240kbps_60fps.info
@@ -0,0 +1,60 @@
+10271 1 0
+106 0 17000
+134 0 33000
+149 0 50000
+152 0 67000
+159 0 83000
+114 0 100000
+723 0 117000
+175 0 133000
+186 0 150000
+201 0 167000
+270 0 183000
+383 0 200000
+255 0 217000
+286 0 233000
+273 0 250000
+1224 0 267000
+220 0 283000
+231 0 300000
+192 0 317000
+182 0 333000
+289 0 350000
+204 0 367000
+237 0 383000
+187 0 400000
+898 0 417000
+231 0 433000
+266 0 450000
+278 0 467000
+205 0 483000
+255 0 500000
+169 0 517000
+233 0 533000
+1011 0 550000
+202 0 567000
+251 0 583000
+223 0 600000
+283 0 617000
+362 0 633000
+217 0 650000
+245 0 667000
+960 0 683000
+233 0 700000
+286 0 717000
+272 0 733000
+254 0 750000
+331 0 767000
+218 0 783000
+261 0 800000
+981 0 817000
+226 0 833000
+226 0 850000
+279 0 867000
+225 0 883000
+295 0 900000
+175 0 917000
+249 0 933000
+996 0 950000
+169 0 967000
+224 0 983000
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_vp8_176x144_240kbps_60fps.vp8 b/media/codec2/hidl/1.0/vts/functional/res/bbb_vp8_176x144_240kbps_60fps.vp8
new file mode 100644
index 0000000..6eba56c
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_vp8_176x144_240kbps_60fps.vp8
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_vp8_640x360_2mbps_30fps.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_vp8_640x360_2mbps_30fps.info
new file mode 100644
index 0000000..9c00c77
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_vp8_640x360_2mbps_30fps.info
@@ -0,0 +1,300 @@
+86980 1 0
+6741 0 33000
+9433 0 67000
+9363 0 100000
+8671 0 133000
+9003 0 167000
+7751 0 200000
+13207 0 233000
+8542 0 267000
+9344 0 300000
+8069 0 333000
+8588 0 367000
+12087 0 400000
+7315 0 433000
+9654 0 467000
+13100 0 500000
+7832 0 533000
+10060 0 567000
+8540 0 600000
+8667 0 633000
+8532 0 667000
+6018 0 700000
+8520 0 733000
+15350 0 767000
+6110 0 800000
+7876 0 833000
+6133 0 867000
+9476 0 900000
+11002 0 933000
+7484 0 967000
+8760 0 1000000
+16515 0 1033000
+7482 0 1067000
+6983 0 1100000
+7561 0 1133000
+8263 0 1167000
+10682 0 1200000
+8108 0 1233000
+7924 0 1267000
+8693 0 1300000
+14190 0 1333000
+7393 0 1367000
+6864 0 1400000
+9431 0 1433000
+7674 0 1467000
+8458 0 1500000
+5899 0 1533000
+8259 0 1567000
+7963 0 1600000
+14779 0 1633000
+6877 0 1667000
+7268 0 1700000
+8526 0 1733000
+8467 0 1767000
+11200 0 1800000
+7261 0 1833000
+8280 0 1867000
+6718 0 1900000
+17742 0 1933000
+5206 0 1967000
+5700 0 2000000
+5872 0 2033000
+7915 0 2067000
+8493 0 2100000
+6545 0 2133000
+9072 0 2167000
+13200 0 2200000
+9632 0 2233000
+10016 0 2267000
+7824 0 2300000
+10628 0 2333000
+10401 0 2367000
+10892 0 2400000
+9023 0 2433000
+10734 0 2467000
+15045 0 2500000
+7940 0 2533000
+9657 0 2567000
+8743 0 2600000
+8074 0 2633000
+9445 0 2667000
+6494 0 2700000
+8601 0 2733000
+13478 0 2767000
+6942 0 2800000
+8002 0 2833000
+7940 0 2867000
+8320 0 2900000
+12215 0 2933000
+6668 0 2967000
+11384 0 3000000
+8378 0 3033000
+12908 0 3067000
+8420 0 3100000
+7502 0 3133000
+8482 0 3167000
+10968 0 3200000
+12338 0 3233000
+8657 0 3267000
+10468 0 3300000
+13878 0 3333000
+9374 0 3367000
+9857 0 3400000
+10381 0 3433000
+9984 0 3467000
+9956 0 3500000
+8905 0 3533000
+8672 0 3567000
+8122 0 3600000
+9677 0 3633000
+9812 0 3667000
+9622 0 3700000
+9023 0 3733000
+7147 0 3767000
+9146 0 3800000
+7488 0 3833000
+10812 0 3867000
+8340 0 3900000
+13280 0 3933000
+5167 0 3967000
+6991 0 4000000
+6543 0 4033000
+5952 0 4067000
+5164 0 4100000
+4011 0 4133000
+3794 0 4167000
+12959 0 4200000
+71020 1 4233000
+5351 0 4267000
+6283 0 4300000
+5080 0 4333000
+6707 0 4367000
+5857 0 4400000
+5221 0 4433000
+10972 0 4467000
+7023 0 4500000
+6907 0 4533000
+7851 0 4567000
+4843 0 4600000
+6085 0 4633000
+4868 0 4667000
+5093 0 4700000
+12807 0 4733000
+6330 0 4767000
+4209 0 4800000
+4596 0 4833000
+6316 0 4867000
+4954 0 4900000
+5533 0 4933000
+7749 0 4967000
+12486 0 5000000
+5468 0 5033000
+4353 0 5067000
+5786 0 5100000
+5551 0 5133000
+6711 0 5167000
+5688 0 5200000
+6258 0 5233000
+12975 0 5267000
+4873 0 5300000
+4552 0 5333000
+4844 0 5367000
+4774 0 5400000
+5025 0 5433000
+5204 0 5467000
+4814 0 5500000
+14835 0 5533000
+5343 0 5567000
+4808 0 5600000
+5071 0 5633000
+6324 0 5667000
+5243 0 5700000
+4995 0 5733000
+5134 0 5767000
+11054 0 5800000
+4807 0 5833000
+5118 0 5867000
+6424 0 5900000
+4984 0 5933000
+7187 0 5967000
+5505 0 6000000
+6941 0 6033000
+11517 0 6067000
+5646 0 6100000
+6832 0 6133000
+5294 0 6167000
+6200 0 6200000
+6328 0 6233000
+4348 0 6267000
+4607 0 6300000
+12958 0 6333000
+4308 0 6367000
+6084 0 6400000
+4494 0 6433000
+5338 0 6467000
+5742 0 6500000
+5472 0 6533000
+8459 0 6567000
+13075 0 6600000
+8986 0 6633000
+9583 0 6667000
+8792 0 6700000
+9004 0 6733000
+9632 0 6767000
+9393 0 6800000
+9259 0 6833000
+11927 0 6867000
+10323 0 6900000
+15248 0 6933000
+11244 0 6967000
+15558 0 7000000
+6197 0 7033000
+8044 0 7067000
+11432 0 7100000
+8737 0 7133000
+13885 0 7167000
+11158 0 7200000
+15152 0 7233000
+7025 0 7267000
+8025 0 7300000
+13362 0 7333000
+8090 0 7367000
+13637 0 7400000
+6148 0 7433000
+9270 0 7467000
+8633 0 7500000
+10673 0 7533000
+14208 0 7567000
+8084 0 7600000
+13783 0 7633000
+10660 0 7667000
+7466 0 7700000
+14433 0 7733000
+10934 0 7767000
+7239 0 7800000
+12548 0 7833000
+6564 0 7867000
+10761 0 7900000
+10992 0 7933000
+12924 0 7967000
+12348 0 8000000
+6770 0 8033000
+14288 0 8067000
+29345 1 8100000
+1822 0 8133000
+1087 0 8167000
+1109 0 8200000
+2007 0 8233000
+1798 0 8267000
+1635 0 8300000
+19607 0 8333000
+919 0 8367000
+2357 0 8400000
+3578 0 8433000
+4497 0 8467000
+4314 0 8500000
+3851 0 8533000
+3822 0 8567000
+4252 0 8600000
+4775 0 8633000
+12203 0 8667000
+5078 0 8700000
+5876 0 8733000
+6124 0 8767000
+4490 0 8800000
+3538 0 8833000
+3450 0 8867000
+3611 0 8900000
+2847 0 8933000
+2605 0 8967000
+12243 0 9000000
+1946 0 9033000
+1847 0 9067000
+2035 0 9100000
+2572 0 9133000
+2326 0 9167000
+2645 0 9200000
+2938 0 9233000
+2495 0 9267000
+2609 0 9300000
+9744 0 9333000
+1796 0 9367000
+1985 0 9400000
+1759 0 9433000
+2259 0 9467000
+2233 0 9500000
+2044 0 9533000
+2502 0 9567000
+2307 0 9600000
+2739 0 9633000
+11707 0 9667000
+5168 0 9700000
+4483 0 9733000
+3044 0 9767000
+4241 0 9800000
+4392 0 9833000
+4934 0 9867000
+5934 0 9900000
+5647 0 9933000
+5326 0 9967000
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_vp8_640x360_2mbps_30fps.vp8 b/media/codec2/hidl/1.0/vts/functional/res/bbb_vp8_640x360_2mbps_30fps.vp8
new file mode 100644
index 0000000..6ec460c
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_vp8_640x360_2mbps_30fps.vp8
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_vp9_176x144_285kbps_60fps.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_vp9_176x144_285kbps_60fps.info
new file mode 100644
index 0000000..ca1a03c
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_vp9_176x144_285kbps_60fps.info
@@ -0,0 +1,60 @@
+6939 1 0
+6818 0 17000
+310 0 33000
+273 0 50000
+267 0 67000
+239 0 83000
+232 0 100000
+222 0 117000
+186 0 133000
+194 0 150000
+189 0 167000
+18 0 183000
+2014 0 200000
+297 0 217000
+287 0 233000
+237 0 250000
+263 0 267000
+238 0 283000
+257 0 300000
+229 0 317000
+187 0 333000
+191 0 350000
+18 0 367000
+2203 0 383000
+265 0 400000
+224 0 417000
+254 0 433000
+252 0 450000
+273 0 467000
+208 0 483000
+154 0 500000
+182 0 517000
+138 0 533000
+18 0 550000
+2502 0 567000
+286 0 583000
+304 0 600000
+341 0 617000
+259 0 633000
+275 0 650000
+222 0 667000
+254 0 683000
+253 0 700000
+225 0 717000
+18 0 733000
+2501 0 750000
+282 0 767000
+298 0 783000
+252 0 800000
+242 0 817000
+250 0 833000
+260 0 850000
+218 0 867000
+213 0 883000
+144 0 900000
+18 0 917000
+233 0 933000
+254 0 950000
+229 0 967000
+239 0 983000
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_vp9_176x144_285kbps_60fps.vp9 b/media/codec2/hidl/1.0/vts/functional/res/bbb_vp9_176x144_285kbps_60fps.vp9
new file mode 100644
index 0000000..2633c8a
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_vp9_176x144_285kbps_60fps.vp9
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_vp9_640x360_1600kbps_30fps.info b/media/codec2/hidl/1.0/vts/functional/res/bbb_vp9_640x360_1600kbps_30fps.info
new file mode 100644
index 0000000..afe9679
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_vp9_640x360_1600kbps_30fps.info
@@ -0,0 +1,300 @@
+54918 1 0
+46280 0 33000
+2006 0 67000
+2841 0 100000
+3044 0 133000
+3429 0 167000
+3196 0 200000
+2926 0 233000
+2821 0 267000
+1150 0 300000
+36 0 333000
+38084 0 367000
+3689 0 400000
+3473 0 433000
+3011 0 467000
+3090 0 500000
+2516 0 533000
+2771 0 567000
+3250 0 600000
+1159 0 633000
+34 0 667000
+39690 0 700000
+3615 0 733000
+2494 0 767000
+2893 0 800000
+3329 0 833000
+2939 0 867000
+2352 0 900000
+2732 0 933000
+1746 0 967000
+33 0 1000000
+41501 0 1033000
+2997 0 1067000
+2666 0 1100000
+3582 0 1133000
+2616 0 1167000
+2923 0 1200000
+2696 0 1233000
+1628 0 1267000
+1887 0 1300000
+33 0 1333000
+42876 0 1367000
+2588 0 1400000
+3316 0 1433000
+2287 0 1467000
+3375 0 1500000
+2108 0 1533000
+2961 0 1567000
+1730 0 1600000
+1800 0 1633000
+34 0 1667000
+43797 0 1700000
+2484 0 1733000
+2556 0 1767000
+2671 0 1800000
+2338 0 1833000
+3133 0 1867000
+2002 0 1900000
+1794 0 1933000
+1279 0 1967000
+32 0 2000000
+42642 0 2033000
+2686 0 2067000
+2202 0 2100000
+2145 0 2133000
+2566 0 2167000
+2190 0 2200000
+1580 0 2233000
+1711 0 2267000
+648 0 2300000
+32 0 2333000
+40409 0 2367000
+2628 0 2400000
+1973 0 2433000
+2360 0 2467000
+3043 0 2500000
+1730 0 2533000
+1456 0 2567000
+2312 0 2600000
+369 0 2633000
+32 0 2667000
+41391 0 2700000
+2967 0 2733000
+2454 0 2767000
+1825 0 2800000
+1853 0 2833000
+1746 0 2867000
+2347 0 2900000
+1362 0 2933000
+441 0 2967000
+34 0 3000000
+42503 0 3033000
+1877 0 3067000
+1690 0 3100000
+1367 0 3133000
+1520 0 3167000
+1240 0 3200000
+1094 0 3233000
+739 0 3267000
+392 0 3300000
+33 0 3333000
+35104 0 3367000
+1463 0 3400000
+2029 0 3433000
+1626 0 3467000
+1956 0 3500000
+799 0 3533000
+556 0 3567000
+584 0 3600000
+191 0 3633000
+36 0 3667000
+37652 0 3700000
+862 0 3733000
+524 0 3767000
+641 0 3800000
+584 0 3833000
+360 0 3867000
+365 0 3900000
+361 0 3933000
+154 0 3967000
+36 0 4000000
+125740 0 4033000
+332 0 4067000
+381 0 4100000
+420 0 4133000
+464 0 4167000
+288 0 4200000
+2660 0 4233000
+127564 1 4267000
+30696 0 4300000
+3423 0 4333000
+3310 0 4367000
+3513 0 4400000
+3735 0 4433000
+3358 0 4467000
+3108 0 4500000
+2800 0 4533000
+1751 0 4567000
+41 0 4600000
+39862 0 4633000
+3739 0 4667000
+3755 0 4700000
+3408 0 4733000
+3783 0 4767000
+3423 0 4800000
+2801 0 4833000
+2549 0 4867000
+1461 0 4900000
+40 0 4933000
+41667 0 4967000
+3623 0 5000000
+3356 0 5033000
+3424 0 5067000
+3548 0 5100000
+3119 0 5133000
+2905 0 5167000
+2772 0 5200000
+1623 0 5233000
+43 0 5267000
+46783 0 5300000
+3462 0 5333000
+3470 0 5367000
+3677 0 5400000
+3684 0 5433000
+3266 0 5467000
+3127 0 5500000
+2809 0 5533000
+1750 0 5567000
+40 0 5600000
+46215 0 5633000
+3599 0 5667000
+3558 0 5700000
+3544 0 5733000
+3632 0 5767000
+3548 0 5800000
+2968 0 5833000
+2715 0 5867000
+1729 0 5900000
+41 0 5933000
+45958 0 5967000
+3776 0 6000000
+3525 0 6033000
+3644 0 6067000
+3786 0 6100000
+3222 0 6133000
+2923 0 6167000
+2752 0 6200000
+1592 0 6233000
+41 0 6267000
+46031 0 6300000
+3520 0 6333000
+3380 0 6367000
+3371 0 6400000
+3427 0 6433000
+3135 0 6467000
+2988 0 6500000
+2730 0 6533000
+1671 0 6567000
+41 0 6600000
+45846 0 6633000
+3535 0 6667000
+3507 0 6700000
+3429 0 6733000
+3491 0 6767000
+3325 0 6800000
+2979 0 6833000
+2800 0 6867000
+1610 0 6900000
+40 0 6933000
+45958 0 6967000
+3762 0 7000000
+3254 0 7033000
+3408 0 7067000
+3860 0 7100000
+3198 0 7133000
+2966 0 7167000
+2882 0 7200000
+1763 0 7233000
+42 0 7267000
+46130 0 7300000
+3593 0 7333000
+3523 0 7367000
+3939 0 7400000
+3980 0 7433000
+3470 0 7467000
+3191 0 7500000
+2969 0 7533000
+1740 0 7567000
+41 0 7600000
+46300 0 7633000
+3739 0 7667000
+3781 0 7700000
+3964 0 7733000
+4023 0 7767000
+3480 0 7800000
+3065 0 7833000
+2934 0 7867000
+1805 0 7900000
+42 0 7933000
+38166 0 7967000
+4062 0 8000000
+3844 0 8033000
+4547 0 8067000
+934 0 8100000
+365 0 8133000
+181 0 8167000
+463 0 8200000
+419 0 8233000
+38 0 8267000
+9702 0 8300000
+344 0 8333000
+276 0 8367000
+1350 0 8400000
+1703 0 8433000
+1843 0 8467000
+1228 0 8500000
+35580 1 8533000
+27458 0 8567000
+2144 0 8600000
+2482 0 8633000
+2004 0 8667000
+2822 0 8700000
+2570 0 8733000
+1726 0 8767000
+1248 0 8800000
+844 0 8833000
+35 0 8867000
+14207 0 8900000
+1037 0 8933000
+749 0 8967000
+829 0 9000000
+915 0 9033000
+685 0 9067000
+767 0 9100000
+798 0 9133000
+342 0 9167000
+31 0 9200000
+12590 0 9233000
+923 0 9267000
+819 0 9300000
+776 0 9333000
+863 0 9367000
+729 0 9400000
+471 0 9433000
+638 0 9467000
+276 0 9500000
+38 0 9533000
+17272 0 9567000
+856 0 9600000
+1158 0 9633000
+2172 0 9667000
+2751 0 9700000
+2142 0 9733000
+1267 0 9767000
+1965 0 9800000
+1510 0 9833000
+34 0 9867000
+2692 0 9900000
+2778 0 9933000
+2585 0 9967000
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_vp9_640x360_1600kbps_30fps.vp9 b/media/codec2/hidl/1.0/vts/functional/res/bbb_vp9_640x360_1600kbps_30fps.vp9
new file mode 100644
index 0000000..c1e2001
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_vp9_640x360_1600kbps_30fps.vp9
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/sine_amrnb_1ch_12kbps_8000hz.amrnb b/media/codec2/hidl/1.0/vts/functional/res/sine_amrnb_1ch_12kbps_8000hz.amrnb
new file mode 100644
index 0000000..3daf2e0
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/sine_amrnb_1ch_12kbps_8000hz.amrnb
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/sine_amrnb_1ch_12kbps_8000hz.info b/media/codec2/hidl/1.0/vts/functional/res/sine_amrnb_1ch_12kbps_8000hz.info
new file mode 100644
index 0000000..b36e813
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/sine_amrnb_1ch_12kbps_8000hz.info
@@ -0,0 +1,833 @@
+32 1 0
+32 1 20000
+32 1 40000
+32 1 60000
+32 1 80000
+32 1 100000
+32 1 120000
+32 1 140000
+32 1 160000
+32 1 180000
+32 1 200000
+32 1 220000
+32 1 240000
+32 1 260000
+32 1 280000
+32 1 300000
+32 1 320000
+32 1 340000
+32 1 360000
+32 1 380000
+32 1 400000
+32 1 420000
+32 1 440000
+32 1 460000
+32 1 480000
+32 1 500000
+32 1 520000
+32 1 540000
+32 1 560000
+32 1 580000
+32 1 600000
+32 1 620000
+32 1 640000
+32 1 660000
+32 1 680000
+32 1 700000
+32 1 720000
+32 1 740000
+32 1 760000
+32 1 780000
+32 1 800000
+32 1 820000
+32 1 840000
+32 1 860000
+32 1 880000
+32 1 900000
+32 1 920000
+32 1 940000
+32 1 960000
+32 1 980000
+32 1 1000000
+32 1 1020000
+32 1 1040000
+32 1 1060000
+32 1 1080000
+32 1 1100000
+32 1 1120000
+32 1 1140000
+32 1 1160000
+32 1 1180000
+32 1 1200000
+32 1 1220000
+32 1 1240000
+32 1 1260000
+32 1 1280000
+32 1 1300000
+32 1 1320000
+32 1 1340000
+32 1 1360000
+32 1 1380000
+32 1 1400000
+32 1 1420000
+32 1 1440000
+32 1 1460000
+32 1 1480000
+32 1 1500000
+32 1 1520000
+32 1 1540000
+32 1 1560000
+32 1 1580000
+32 1 1600000
+32 1 1620000
+32 1 1640000
+32 1 1660000
+32 1 1680000
+32 1 1700000
+32 1 1720000
+32 1 1740000
+32 1 1760000
+32 1 1780000
+32 1 1800000
+32 1 1820000
+32 1 1840000
+32 1 1860000
+32 1 1880000
+32 1 1900000
+32 1 1920000
+32 1 1940000
+32 1 1960000
+32 1 1980000
+32 1 2000000
+32 1 2020000
+32 1 2040000
+32 1 2060000
+32 1 2080000
+32 1 2100000
+32 1 2120000
+32 1 2140000
+32 1 2160000
+32 1 2180000
+32 1 2200000
+32 1 2220000
+32 1 2240000
+32 1 2260000
+32 1 2280000
+32 1 2300000
+32 1 2320000
+32 1 2340000
+32 1 2360000
+32 1 2380000
+32 1 2400000
+32 1 2420000
+32 1 2440000
+32 1 2460000
+32 1 2480000
+32 1 2500000
+32 1 2520000
+32 1 2540000
+32 1 2560000
+32 1 2580000
+32 1 2600000
+32 1 2620000
+32 1 2640000
+32 1 2660000
+32 1 2680000
+32 1 2700000
+32 1 2720000
+32 1 2740000
+32 1 2760000
+32 1 2780000
+32 1 2800000
+32 1 2820000
+32 1 2840000
+32 1 2860000
+32 1 2880000
+32 1 2900000
+32 1 2920000
+32 1 2940000
+32 1 2960000
+32 1 2980000
+32 1 3000000
+32 1 3020000
+32 1 3040000
+32 1 3060000
+32 1 3080000
+32 1 3100000
+32 1 3120000
+32 1 3140000
+32 1 3160000
+32 1 3180000
+32 1 3200000
+32 1 3220000
+32 1 3240000
+32 1 3260000
+32 1 3280000
+32 1 3300000
+32 1 3320000
+32 1 3340000
+32 1 3360000
+32 1 3380000
+32 1 3400000
+32 1 3420000
+32 1 3440000
+32 1 3460000
+32 1 3480000
+32 1 3500000
+32 1 3520000
+32 1 3540000
+32 1 3560000
+32 1 3580000
+32 1 3600000
+32 1 3620000
+32 1 3640000
+32 1 3660000
+32 1 3680000
+32 1 3700000
+32 1 3720000
+32 1 3740000
+32 1 3760000
+32 1 3780000
+32 1 3800000
+32 1 3820000
+32 1 3840000
+32 1 3860000
+32 1 3880000
+32 1 3900000
+32 1 3920000
+32 1 3940000
+32 1 3960000
+32 1 3980000
+32 1 4000000
+32 1 4020000
+32 1 4040000
+32 1 4060000
+32 1 4080000
+32 1 4100000
+32 1 4120000
+32 1 4140000
+32 1 4160000
+32 1 4180000
+32 1 4200000
+32 1 4220000
+32 1 4240000
+32 1 4260000
+32 1 4280000
+32 1 4300000
+32 1 4320000
+32 1 4340000
+32 1 4360000
+32 1 4380000
+32 1 4400000
+32 1 4420000
+32 1 4440000
+32 1 4460000
+32 1 4480000
+32 1 4500000
+32 1 4520000
+32 1 4540000
+32 1 4560000
+32 1 4580000
+32 1 4600000
+32 1 4620000
+32 1 4640000
+32 1 4660000
+32 1 4680000
+32 1 4700000
+32 1 4720000
+32 1 4740000
+32 1 4760000
+32 1 4780000
+32 1 4800000
+32 1 4820000
+32 1 4840000
+32 1 4860000
+32 1 4880000
+32 1 4900000
+32 1 4920000
+32 1 4940000
+32 1 4960000
+32 1 4980000
+32 1 5000000
+32 1 5020000
+32 1 5040000
+32 1 5060000
+32 1 5080000
+32 1 5100000
+32 1 5120000
+32 1 5140000
+32 1 5160000
+32 1 5180000
+32 1 5200000
+32 1 5220000
+32 1 5240000
+32 1 5260000
+32 1 5280000
+32 1 5300000
+32 1 5320000
+32 1 5340000
+32 1 5360000
+32 1 5380000
+32 1 5400000
+32 1 5420000
+32 1 5440000
+32 1 5460000
+32 1 5480000
+32 1 5500000
+32 1 5520000
+32 1 5540000
+32 1 5560000
+32 1 5580000
+32 1 5600000
+32 1 5620000
+32 1 5640000
+32 1 5660000
+32 1 5680000
+32 1 5700000
+32 1 5720000
+32 1 5740000
+32 1 5760000
+32 1 5780000
+32 1 5800000
+32 1 5820000
+32 1 5840000
+32 1 5860000
+32 1 5880000
+32 1 5900000
+32 1 5920000
+32 1 5940000
+32 1 5960000
+32 1 5980000
+32 1 6000000
+32 1 6020000
+32 1 6040000
+32 1 6060000
+32 1 6080000
+32 1 6100000
+32 1 6120000
+32 1 6140000
+32 1 6160000
+32 1 6180000
+32 1 6200000
+32 1 6220000
+32 1 6240000
+32 1 6260000
+32 1 6280000
+32 1 6300000
+32 1 6320000
+32 1 6340000
+32 1 6360000
+32 1 6380000
+32 1 6400000
+32 1 6420000
+32 1 6440000
+32 1 6460000
+32 1 6480000
+32 1 6500000
+32 1 6520000
+32 1 6540000
+32 1 6560000
+32 1 6580000
+32 1 6600000
+32 1 6620000
+32 1 6640000
+32 1 6660000
+32 1 6680000
+32 1 6700000
+32 1 6720000
+32 1 6740000
+32 1 6760000
+32 1 6780000
+32 1 6800000
+32 1 6820000
+32 1 6840000
+32 1 6860000
+32 1 6880000
+32 1 6900000
+32 1 6920000
+32 1 6940000
+32 1 6960000
+32 1 6980000
+32 1 7000000
+32 1 7020000
+32 1 7040000
+32 1 7060000
+32 1 7080000
+32 1 7100000
+32 1 7120000
+32 1 7140000
+32 1 7160000
+32 1 7180000
+32 1 7200000
+32 1 7220000
+32 1 7240000
+32 1 7260000
+32 1 7280000
+32 1 7300000
+32 1 7320000
+32 1 7340000
+32 1 7360000
+32 1 7380000
+32 1 7400000
+32 1 7420000
+32 1 7440000
+32 1 7460000
+32 1 7480000
+32 1 7500000
+32 1 7520000
+32 1 7540000
+32 1 7560000
+32 1 7580000
+32 1 7600000
+32 1 7620000
+32 1 7640000
+32 1 7660000
+32 1 7680000
+32 1 7700000
+32 1 7720000
+32 1 7740000
+32 1 7760000
+32 1 7780000
+32 1 7800000
+32 1 7820000
+32 1 7840000
+32 1 7860000
+32 1 7880000
+32 1 7900000
+32 1 7920000
+32 1 7940000
+32 1 7960000
+32 1 7980000
+32 1 8000000
+32 1 8020000
+32 1 8040000
+32 1 8060000
+32 1 8080000
+32 1 8100000
+32 1 8120000
+32 1 8140000
+32 1 8160000
+32 1 8180000
+32 1 8200000
+32 1 8220000
+32 1 8240000
+32 1 8260000
+32 1 8280000
+32 1 8300000
+32 1 8320000
+32 1 8340000
+32 1 8360000
+32 1 8380000
+32 1 8400000
+32 1 8420000
+32 1 8440000
+32 1 8460000
+32 1 8480000
+32 1 8500000
+32 1 8520000
+32 1 8540000
+32 1 8560000
+32 1 8580000
+32 1 8600000
+32 1 8620000
+32 1 8640000
+32 1 8660000
+32 1 8680000
+32 1 8700000
+32 1 8720000
+32 1 8740000
+32 1 8760000
+32 1 8780000
+32 1 8800000
+32 1 8820000
+32 1 8840000
+32 1 8860000
+32 1 8880000
+32 1 8900000
+32 1 8920000
+32 1 8940000
+32 1 8960000
+32 1 8980000
+32 1 9000000
+32 1 9020000
+32 1 9040000
+32 1 9060000
+32 1 9080000
+32 1 9100000
+32 1 9120000
+32 1 9140000
+32 1 9160000
+32 1 9180000
+32 1 9200000
+32 1 9220000
+32 1 9240000
+32 1 9260000
+32 1 9280000
+32 1 9300000
+32 1 9320000
+32 1 9340000
+32 1 9360000
+32 1 9380000
+32 1 9400000
+32 1 9420000
+32 1 9440000
+32 1 9460000
+32 1 9480000
+32 1 9500000
+32 1 9520000
+32 1 9540000
+32 1 9560000
+32 1 9580000
+32 1 9600000
+32 1 9620000
+32 1 9640000
+32 1 9660000
+32 1 9680000
+32 1 9700000
+32 1 9720000
+32 1 9740000
+32 1 9760000
+32 1 9780000
+32 1 9800000
+32 1 9820000
+32 1 9840000
+32 1 9860000
+32 1 9880000
+32 1 9900000
+32 1 9920000
+32 1 9940000
+32 1 9960000
+32 1 9980000
+32 1 10000000
+32 1 10020000
+32 1 10040000
+32 1 10060000
+32 1 10080000
+32 1 10100000
+32 1 10120000
+32 1 10140000
+32 1 10160000
+32 1 10180000
+32 1 10200000
+32 1 10220000
+32 1 10240000
+32 1 10260000
+32 1 10280000
+32 1 10300000
+32 1 10320000
+32 1 10340000
+32 1 10360000
+32 1 10380000
+32 1 10400000
+32 1 10420000
+32 1 10440000
+32 1 10460000
+32 1 10480000
+32 1 10500000
+32 1 10520000
+32 1 10540000
+32 1 10560000
+32 1 10580000
+32 1 10600000
+32 1 10620000
+32 1 10640000
+32 1 10660000
+32 1 10680000
+32 1 10700000
+32 1 10720000
+32 1 10740000
+32 1 10760000
+32 1 10780000
+32 1 10800000
+32 1 10820000
+32 1 10840000
+32 1 10860000
+32 1 10880000
+32 1 10900000
+32 1 10920000
+32 1 10940000
+32 1 10960000
+32 1 10980000
+32 1 11000000
+32 1 11020000
+32 1 11040000
+32 1 11060000
+32 1 11080000
+32 1 11100000
+32 1 11120000
+32 1 11140000
+32 1 11160000
+32 1 11180000
+32 1 11200000
+32 1 11220000
+32 1 11240000
+32 1 11260000
+32 1 11280000
+32 1 11300000
+32 1 11320000
+32 1 11340000
+32 1 11360000
+32 1 11380000
+32 1 11400000
+32 1 11420000
+32 1 11440000
+32 1 11460000
+32 1 11480000
+32 1 11500000
+32 1 11520000
+32 1 11540000
+32 1 11560000
+32 1 11580000
+32 1 11600000
+32 1 11620000
+32 1 11640000
+32 1 11660000
+32 1 11680000
+32 1 11700000
+32 1 11720000
+32 1 11740000
+32 1 11760000
+32 1 11780000
+32 1 11800000
+32 1 11820000
+32 1 11840000
+32 1 11860000
+32 1 11880000
+32 1 11900000
+32 1 11920000
+32 1 11940000
+32 1 11960000
+32 1 11980000
+32 1 12000000
+32 1 12020000
+32 1 12040000
+32 1 12060000
+32 1 12080000
+32 1 12100000
+32 1 12120000
+32 1 12140000
+32 1 12160000
+32 1 12180000
+32 1 12200000
+32 1 12220000
+32 1 12240000
+32 1 12260000
+32 1 12280000
+32 1 12300000
+32 1 12320000
+32 1 12340000
+32 1 12360000
+32 1 12380000
+32 1 12400000
+32 1 12420000
+32 1 12440000
+32 1 12460000
+32 1 12480000
+32 1 12500000
+32 1 12520000
+32 1 12540000
+32 1 12560000
+32 1 12580000
+32 1 12600000
+32 1 12620000
+32 1 12640000
+32 1 12660000
+32 1 12680000
+32 1 12700000
+32 1 12720000
+32 1 12740000
+32 1 12760000
+32 1 12780000
+32 1 12800000
+32 1 12820000
+32 1 12840000
+32 1 12860000
+32 1 12880000
+32 1 12900000
+32 1 12920000
+32 1 12940000
+32 1 12960000
+32 1 12980000
+32 1 13000000
+32 1 13020000
+32 1 13040000
+32 1 13060000
+32 1 13080000
+32 1 13100000
+32 1 13120000
+32 1 13140000
+32 1 13160000
+32 1 13180000
+32 1 13200000
+32 1 13220000
+32 1 13240000
+32 1 13260000
+32 1 13280000
+32 1 13300000
+32 1 13320000
+32 1 13340000
+32 1 13360000
+32 1 13380000
+32 1 13400000
+32 1 13420000
+32 1 13440000
+32 1 13460000
+32 1 13480000
+32 1 13500000
+32 1 13520000
+32 1 13540000
+32 1 13560000
+32 1 13580000
+32 1 13600000
+32 1 13620000
+32 1 13640000
+32 1 13660000
+32 1 13680000
+32 1 13700000
+32 1 13720000
+32 1 13740000
+32 1 13760000
+32 1 13780000
+32 1 13800000
+32 1 13820000
+32 1 13840000
+32 1 13860000
+32 1 13880000
+32 1 13900000
+32 1 13920000
+32 1 13940000
+32 1 13960000
+32 1 13980000
+32 1 14000000
+32 1 14020000
+32 1 14040000
+32 1 14060000
+32 1 14080000
+32 1 14100000
+32 1 14120000
+32 1 14140000
+32 1 14160000
+32 1 14180000
+32 1 14200000
+32 1 14220000
+32 1 14240000
+32 1 14260000
+32 1 14280000
+32 1 14300000
+32 1 14320000
+32 1 14340000
+32 1 14360000
+32 1 14380000
+32 1 14400000
+32 1 14420000
+32 1 14440000
+32 1 14460000
+32 1 14480000
+32 1 14500000
+32 1 14520000
+32 1 14540000
+32 1 14560000
+32 1 14580000
+32 1 14600000
+32 1 14620000
+32 1 14640000
+32 1 14660000
+32 1 14680000
+32 1 14700000
+32 1 14720000
+32 1 14740000
+32 1 14760000
+32 1 14780000
+32 1 14800000
+32 1 14820000
+32 1 14840000
+32 1 14860000
+32 1 14880000
+32 1 14900000
+32 1 14920000
+32 1 14940000
+32 1 14960000
+32 1 14980000
+32 1 15000000
+32 1 15020000
+32 1 15040000
+32 1 15060000
+32 1 15080000
+32 1 15100000
+32 1 15120000
+32 1 15140000
+32 1 15160000
+32 1 15180000
+32 1 15200000
+32 1 15220000
+32 1 15240000
+32 1 15260000
+32 1 15280000
+32 1 15300000
+32 1 15320000
+32 1 15340000
+32 1 15360000
+32 1 15380000
+32 1 15400000
+32 1 15420000
+32 1 15440000
+32 1 15460000
+32 1 15480000
+32 1 15500000
+32 1 15520000
+32 1 15540000
+32 1 15560000
+32 1 15580000
+32 1 15600000
+32 1 15620000
+32 1 15640000
+32 1 15660000
+32 1 15680000
+32 1 15700000
+32 1 15720000
+32 1 15740000
+32 1 15760000
+32 1 15780000
+32 1 15800000
+32 1 15820000
+32 1 15840000
+32 1 15860000
+32 1 15880000
+32 1 15900000
+32 1 15920000
+32 1 15940000
+32 1 15960000
+32 1 15980000
+32 1 16000000
+32 1 16020000
+32 1 16040000
+32 1 16060000
+32 1 16080000
+32 1 16100000
+32 1 16120000
+32 1 16140000
+32 1 16160000
+32 1 16180000
+32 1 16200000
+32 1 16220000
+32 1 16240000
+32 1 16260000
+32 1 16280000
+32 1 16300000
+32 1 16320000
+32 1 16340000
+32 1 16360000
+32 1 16380000
+32 1 16400000
+32 1 16420000
+32 1 16440000
+32 1 16460000
+32 1 16480000
+32 1 16500000
+32 1 16520000
+32 1 16540000
+32 1 16560000
+32 1 16580000
+32 1 16600000
+32 1 16620000
+32 1 16640000
diff --git a/media/codec2/hidl/1.0/vts/functional/res/sine_amrnb_1ch_12kbps_8000hz_multi_frame.info b/media/codec2/hidl/1.0/vts/functional/res/sine_amrnb_1ch_12kbps_8000hz_multi_frame.info
new file mode 100644
index 0000000..0176eaf4
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/sine_amrnb_1ch_12kbps_8000hz_multi_frame.info
@@ -0,0 +1,807 @@
+32 1 0
+32 1 20000
+64 1 40000
+64 1 80000
+64 1 120000
+96 1 160000
+96 1 220000
+96 1 280000
+96 1 340000
+128 1 400000
+128 1 480000
+128 1 560000
+128 1 640000
+128 1 720000
+32 1 800000
+32 1 820000
+32 1 840000
+32 1 860000
+32 1 880000
+32 1 900000
+32 1 920000
+32 1 940000
+32 1 960000
+32 1 980000
+32 1 1000000
+32 1 1020000
+32 1 1040000
+32 1 1060000
+32 1 1080000
+32 1 1100000
+32 1 1120000
+32 1 1140000
+32 1 1160000
+32 1 1180000
+32 1 1200000
+32 1 1220000
+32 1 1240000
+32 1 1260000
+32 1 1280000
+32 1 1300000
+32 1 1320000
+32 1 1340000
+32 1 1360000
+32 1 1380000
+32 1 1400000
+32 1 1420000
+32 1 1440000
+32 1 1460000
+32 1 1480000
+32 1 1500000
+32 1 1520000
+32 1 1540000
+32 1 1560000
+32 1 1580000
+32 1 1600000
+32 1 1620000
+32 1 1640000
+32 1 1660000
+32 1 1680000
+32 1 1700000
+32 1 1720000
+32 1 1740000
+32 1 1760000
+32 1 1780000
+32 1 1800000
+32 1 1820000
+32 1 1840000
+32 1 1860000
+32 1 1880000
+32 1 1900000
+32 1 1920000
+32 1 1940000
+32 1 1960000
+32 1 1980000
+32 1 2000000
+32 1 2020000
+32 1 2040000
+32 1 2060000
+32 1 2080000
+32 1 2100000
+32 1 2120000
+32 1 2140000
+32 1 2160000
+32 1 2180000
+32 1 2200000
+32 1 2220000
+32 1 2240000
+32 1 2260000
+32 1 2280000
+32 1 2300000
+32 1 2320000
+32 1 2340000
+32 1 2360000
+32 1 2380000
+32 1 2400000
+32 1 2420000
+32 1 2440000
+32 1 2460000
+32 1 2480000
+32 1 2500000
+32 1 2520000
+32 1 2540000
+32 1 2560000
+32 1 2580000
+32 1 2600000
+32 1 2620000
+32 1 2640000
+32 1 2660000
+32 1 2680000
+32 1 2700000
+32 1 2720000
+32 1 2740000
+32 1 2760000
+32 1 2780000
+32 1 2800000
+32 1 2820000
+32 1 2840000
+32 1 2860000
+32 1 2880000
+32 1 2900000
+32 1 2920000
+32 1 2940000
+32 1 2960000
+32 1 2980000
+32 1 3000000
+32 1 3020000
+32 1 3040000
+32 1 3060000
+32 1 3080000
+32 1 3100000
+32 1 3120000
+32 1 3140000
+32 1 3160000
+32 1 3180000
+32 1 3200000
+32 1 3220000
+32 1 3240000
+32 1 3260000
+32 1 3280000
+32 1 3300000
+32 1 3320000
+32 1 3340000
+32 1 3360000
+32 1 3380000
+32 1 3400000
+32 1 3420000
+32 1 3440000
+32 1 3460000
+32 1 3480000
+32 1 3500000
+32 1 3520000
+32 1 3540000
+32 1 3560000
+32 1 3580000
+32 1 3600000
+32 1 3620000
+32 1 3640000
+32 1 3660000
+32 1 3680000
+32 1 3700000
+32 1 3720000
+32 1 3740000
+32 1 3760000
+32 1 3780000
+32 1 3800000
+32 1 3820000
+32 1 3840000
+32 1 3860000
+32 1 3880000
+32 1 3900000
+32 1 3920000
+32 1 3940000
+32 1 3960000
+32 1 3980000
+32 1 4000000
+32 1 4020000
+32 1 4040000
+32 1 4060000
+32 1 4080000
+32 1 4100000
+32 1 4120000
+32 1 4140000
+32 1 4160000
+32 1 4180000
+32 1 4200000
+32 1 4220000
+32 1 4240000
+32 1 4260000
+32 1 4280000
+32 1 4300000
+32 1 4320000
+32 1 4340000
+32 1 4360000
+32 1 4380000
+32 1 4400000
+32 1 4420000
+32 1 4440000
+32 1 4460000
+32 1 4480000
+32 1 4500000
+32 1 4520000
+32 1 4540000
+32 1 4560000
+32 1 4580000
+32 1 4600000
+32 1 4620000
+32 1 4640000
+32 1 4660000
+32 1 4680000
+32 1 4700000
+32 1 4720000
+32 1 4740000
+32 1 4760000
+32 1 4780000
+32 1 4800000
+32 1 4820000
+32 1 4840000
+32 1 4860000
+32 1 4880000
+32 1 4900000
+32 1 4920000
+32 1 4940000
+32 1 4960000
+32 1 4980000
+32 1 5000000
+32 1 5020000
+32 1 5040000
+32 1 5060000
+32 1 5080000
+32 1 5100000
+32 1 5120000
+32 1 5140000
+32 1 5160000
+32 1 5180000
+32 1 5200000
+32 1 5220000
+32 1 5240000
+32 1 5260000
+32 1 5280000
+32 1 5300000
+32 1 5320000
+32 1 5340000
+32 1 5360000
+32 1 5380000
+32 1 5400000
+32 1 5420000
+32 1 5440000
+32 1 5460000
+32 1 5480000
+32 1 5500000
+32 1 5520000
+32 1 5540000
+32 1 5560000
+32 1 5580000
+32 1 5600000
+32 1 5620000
+32 1 5640000
+32 1 5660000
+32 1 5680000
+32 1 5700000
+32 1 5720000
+32 1 5740000
+32 1 5760000
+32 1 5780000
+32 1 5800000
+32 1 5820000
+32 1 5840000
+32 1 5860000
+32 1 5880000
+32 1 5900000
+32 1 5920000
+32 1 5940000
+32 1 5960000
+32 1 5980000
+32 1 6000000
+32 1 6020000
+32 1 6040000
+32 1 6060000
+32 1 6080000
+32 1 6100000
+32 1 6120000
+32 1 6140000
+32 1 6160000
+32 1 6180000
+32 1 6200000
+32 1 6220000
+32 1 6240000
+32 1 6260000
+32 1 6280000
+32 1 6300000
+32 1 6320000
+32 1 6340000
+32 1 6360000
+32 1 6380000
+32 1 6400000
+32 1 6420000
+32 1 6440000
+32 1 6460000
+32 1 6480000
+32 1 6500000
+32 1 6520000
+32 1 6540000
+32 1 6560000
+32 1 6580000
+32 1 6600000
+32 1 6620000
+32 1 6640000
+32 1 6660000
+32 1 6680000
+32 1 6700000
+32 1 6720000
+32 1 6740000
+32 1 6760000
+32 1 6780000
+32 1 6800000
+32 1 6820000
+32 1 6840000
+32 1 6860000
+32 1 6880000
+32 1 6900000
+32 1 6920000
+32 1 6940000
+32 1 6960000
+32 1 6980000
+32 1 7000000
+32 1 7020000
+32 1 7040000
+32 1 7060000
+32 1 7080000
+32 1 7100000
+32 1 7120000
+32 1 7140000
+32 1 7160000
+32 1 7180000
+32 1 7200000
+32 1 7220000
+32 1 7240000
+32 1 7260000
+32 1 7280000
+32 1 7300000
+32 1 7320000
+32 1 7340000
+32 1 7360000
+32 1 7380000
+32 1 7400000
+32 1 7420000
+32 1 7440000
+32 1 7460000
+32 1 7480000
+32 1 7500000
+32 1 7520000
+32 1 7540000
+32 1 7560000
+32 1 7580000
+32 1 7600000
+32 1 7620000
+32 1 7640000
+32 1 7660000
+32 1 7680000
+32 1 7700000
+32 1 7720000
+32 1 7740000
+32 1 7760000
+32 1 7780000
+32 1 7800000
+32 1 7820000
+32 1 7840000
+32 1 7860000
+32 1 7880000
+32 1 7900000
+32 1 7920000
+32 1 7940000
+32 1 7960000
+32 1 7980000
+32 1 8000000
+32 1 8020000
+32 1 8040000
+32 1 8060000
+32 1 8080000
+32 1 8100000
+32 1 8120000
+32 1 8140000
+32 1 8160000
+32 1 8180000
+32 1 8200000
+32 1 8220000
+32 1 8240000
+32 1 8260000
+32 1 8280000
+32 1 8300000
+32 1 8320000
+32 1 8340000
+32 1 8360000
+32 1 8380000
+32 1 8400000
+32 1 8420000
+32 1 8440000
+32 1 8460000
+32 1 8480000
+32 1 8500000
+32 1 8520000
+32 1 8540000
+32 1 8560000
+32 1 8580000
+32 1 8600000
+32 1 8620000
+32 1 8640000
+32 1 8660000
+32 1 8680000
+32 1 8700000
+32 1 8720000
+32 1 8740000
+32 1 8760000
+32 1 8780000
+32 1 8800000
+32 1 8820000
+32 1 8840000
+32 1 8860000
+32 1 8880000
+32 1 8900000
+32 1 8920000
+32 1 8940000
+32 1 8960000
+32 1 8980000
+32 1 9000000
+32 1 9020000
+32 1 9040000
+32 1 9060000
+32 1 9080000
+32 1 9100000
+32 1 9120000
+32 1 9140000
+32 1 9160000
+32 1 9180000
+32 1 9200000
+32 1 9220000
+32 1 9240000
+32 1 9260000
+32 1 9280000
+32 1 9300000
+32 1 9320000
+32 1 9340000
+32 1 9360000
+32 1 9380000
+32 1 9400000
+32 1 9420000
+32 1 9440000
+32 1 9460000
+32 1 9480000
+32 1 9500000
+32 1 9520000
+32 1 9540000
+32 1 9560000
+32 1 9580000
+32 1 9600000
+32 1 9620000
+32 1 9640000
+32 1 9660000
+32 1 9680000
+32 1 9700000
+32 1 9720000
+32 1 9740000
+32 1 9760000
+32 1 9780000
+32 1 9800000
+32 1 9820000
+32 1 9840000
+32 1 9860000
+32 1 9880000
+32 1 9900000
+32 1 9920000
+32 1 9940000
+32 1 9960000
+32 1 9980000
+32 1 10000000
+32 1 10020000
+32 1 10040000
+32 1 10060000
+32 1 10080000
+32 1 10100000
+32 1 10120000
+32 1 10140000
+32 1 10160000
+32 1 10180000
+32 1 10200000
+32 1 10220000
+32 1 10240000
+32 1 10260000
+32 1 10280000
+32 1 10300000
+32 1 10320000
+32 1 10340000
+32 1 10360000
+32 1 10380000
+32 1 10400000
+32 1 10420000
+32 1 10440000
+32 1 10460000
+32 1 10480000
+32 1 10500000
+32 1 10520000
+32 1 10540000
+32 1 10560000
+32 1 10580000
+32 1 10600000
+32 1 10620000
+32 1 10640000
+32 1 10660000
+32 1 10680000
+32 1 10700000
+32 1 10720000
+32 1 10740000
+32 1 10760000
+32 1 10780000
+32 1 10800000
+32 1 10820000
+32 1 10840000
+32 1 10860000
+32 1 10880000
+32 1 10900000
+32 1 10920000
+32 1 10940000
+32 1 10960000
+32 1 10980000
+32 1 11000000
+32 1 11020000
+32 1 11040000
+32 1 11060000
+32 1 11080000
+32 1 11100000
+32 1 11120000
+32 1 11140000
+32 1 11160000
+32 1 11180000
+32 1 11200000
+32 1 11220000
+32 1 11240000
+32 1 11260000
+32 1 11280000
+32 1 11300000
+32 1 11320000
+32 1 11340000
+32 1 11360000
+32 1 11380000
+32 1 11400000
+32 1 11420000
+32 1 11440000
+32 1 11460000
+32 1 11480000
+32 1 11500000
+32 1 11520000
+32 1 11540000
+32 1 11560000
+32 1 11580000
+32 1 11600000
+32 1 11620000
+32 1 11640000
+32 1 11660000
+32 1 11680000
+32 1 11700000
+32 1 11720000
+32 1 11740000
+32 1 11760000
+32 1 11780000
+32 1 11800000
+32 1 11820000
+32 1 11840000
+32 1 11860000
+32 1 11880000
+32 1 11900000
+32 1 11920000
+32 1 11940000
+32 1 11960000
+32 1 11980000
+32 1 12000000
+32 1 12020000
+32 1 12040000
+32 1 12060000
+32 1 12080000
+32 1 12100000
+32 1 12120000
+32 1 12140000
+32 1 12160000
+32 1 12180000
+32 1 12200000
+32 1 12220000
+32 1 12240000
+32 1 12260000
+32 1 12280000
+32 1 12300000
+32 1 12320000
+32 1 12340000
+32 1 12360000
+32 1 12380000
+32 1 12400000
+32 1 12420000
+32 1 12440000
+32 1 12460000
+32 1 12480000
+32 1 12500000
+32 1 12520000
+32 1 12540000
+32 1 12560000
+32 1 12580000
+32 1 12600000
+32 1 12620000
+32 1 12640000
+32 1 12660000
+32 1 12680000
+32 1 12700000
+32 1 12720000
+32 1 12740000
+32 1 12760000
+32 1 12780000
+32 1 12800000
+32 1 12820000
+32 1 12840000
+32 1 12860000
+32 1 12880000
+32 1 12900000
+32 1 12920000
+32 1 12940000
+32 1 12960000
+32 1 12980000
+32 1 13000000
+32 1 13020000
+32 1 13040000
+32 1 13060000
+32 1 13080000
+32 1 13100000
+32 1 13120000
+32 1 13140000
+32 1 13160000
+32 1 13180000
+32 1 13200000
+32 1 13220000
+32 1 13240000
+32 1 13260000
+32 1 13280000
+32 1 13300000
+32 1 13320000
+32 1 13340000
+32 1 13360000
+32 1 13380000
+32 1 13400000
+32 1 13420000
+32 1 13440000
+32 1 13460000
+32 1 13480000
+32 1 13500000
+32 1 13520000
+32 1 13540000
+32 1 13560000
+32 1 13580000
+32 1 13600000
+32 1 13620000
+32 1 13640000
+32 1 13660000
+32 1 13680000
+32 1 13700000
+32 1 13720000
+32 1 13740000
+32 1 13760000
+32 1 13780000
+32 1 13800000
+32 1 13820000
+32 1 13840000
+32 1 13860000
+32 1 13880000
+32 1 13900000
+32 1 13920000
+32 1 13940000
+32 1 13960000
+32 1 13980000
+32 1 14000000
+32 1 14020000
+32 1 14040000
+32 1 14060000
+32 1 14080000
+32 1 14100000
+32 1 14120000
+32 1 14140000
+32 1 14160000
+32 1 14180000
+32 1 14200000
+32 1 14220000
+32 1 14240000
+32 1 14260000
+32 1 14280000
+32 1 14300000
+32 1 14320000
+32 1 14340000
+32 1 14360000
+32 1 14380000
+32 1 14400000
+32 1 14420000
+32 1 14440000
+32 1 14460000
+32 1 14480000
+32 1 14500000
+32 1 14520000
+32 1 14540000
+32 1 14560000
+32 1 14580000
+32 1 14600000
+32 1 14620000
+32 1 14640000
+32 1 14660000
+32 1 14680000
+32 1 14700000
+32 1 14720000
+32 1 14740000
+32 1 14760000
+32 1 14780000
+32 1 14800000
+32 1 14820000
+32 1 14840000
+32 1 14860000
+32 1 14880000
+32 1 14900000
+32 1 14920000
+32 1 14940000
+32 1 14960000
+32 1 14980000
+32 1 15000000
+32 1 15020000
+32 1 15040000
+32 1 15060000
+32 1 15080000
+32 1 15100000
+32 1 15120000
+32 1 15140000
+32 1 15160000
+32 1 15180000
+32 1 15200000
+32 1 15220000
+32 1 15240000
+32 1 15260000
+32 1 15280000
+32 1 15300000
+32 1 15320000
+32 1 15340000
+32 1 15360000
+32 1 15380000
+32 1 15400000
+32 1 15420000
+32 1 15440000
+32 1 15460000
+32 1 15480000
+32 1 15500000
+32 1 15520000
+32 1 15540000
+32 1 15560000
+32 1 15580000
+32 1 15600000
+32 1 15620000
+32 1 15640000
+32 1 15660000
+32 1 15680000
+32 1 15700000
+32 1 15720000
+32 1 15740000
+32 1 15760000
+32 1 15780000
+32 1 15800000
+32 1 15820000
+32 1 15840000
+32 1 15860000
+32 1 15880000
+32 1 15900000
+32 1 15920000
+32 1 15940000
+32 1 15960000
+32 1 15980000
+32 1 16000000
+32 1 16020000
+32 1 16040000
+32 1 16060000
+32 1 16080000
+32 1 16100000
+32 1 16120000
+32 1 16140000
+32 1 16160000
+32 1 16180000
+32 1 16200000
+32 1 16220000
+32 1 16240000
+32 1 16260000
+32 1 16280000
+32 1 16300000
+32 1 16320000
+32 1 16340000
+32 1 16360000
+32 1 16380000
+32 1 16400000
+32 1 16420000
+32 1 16440000
+32 1 16460000
+32 1 16480000
+32 1 16500000
+32 1 16520000
+32 1 16540000
+32 1 16560000
+32 1 16580000
+32 1 16600000
+32 1 16620000
+32 1 16640000
diff --git a/media/codec2/hidl/1.0/vts/functional/video/Android.bp b/media/codec2/hidl/1.0/vts/functional/video/Android.bp
new file mode 100644
index 0000000..be35b02
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/video/Android.bp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+cc_test {
+    name: "VtsHalMediaC2V1_0TargetVideoDecTest",
+    defaults: ["VtsHalMediaC2V1_0Defaults"],
+    srcs: ["VtsHalMediaC2V1_0TargetVideoDecTest.cpp"],
+}
+
+cc_test {
+    name: "VtsHalMediaC2V1_0TargetVideoEncTest",
+    defaults: ["VtsHalMediaC2V1_0Defaults"],
+    srcs: ["VtsHalMediaC2V1_0TargetVideoEncTest.cpp"],
+}
+
diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
new file mode 100644
index 0000000..5e28750
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
@@ -0,0 +1,900 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "codec2_hidl_hal_video_dec_test"
+
+#include <android-base/logging.h>
+#include <gtest/gtest.h>
+#include <stdio.h>
+#include <fstream>
+
+#include <codec2/hidl/client.h>
+#include <C2AllocatorIon.h>
+#include <C2Config.h>
+#include <C2Debug.h>
+#include <C2Buffer.h>
+#include <C2BufferPriv.h>
+
+using android::C2AllocatorIon;
+
+#include <VtsHalHidlTargetTestBase.h>
+#include "media_c2_video_hidl_test_common.h"
+#include "media_c2_hidl_test_common.h"
+
+struct FrameInfo {
+    int bytesCount;
+    uint32_t flags;
+    int64_t timestamp;
+};
+
+class LinearBuffer : public C2Buffer {
+   public:
+    explicit LinearBuffer(const std::shared_ptr<C2LinearBlock>& block)
+        : C2Buffer(
+              {block->share(block->offset(), block->size(), ::C2Fence())}) {}
+
+    explicit LinearBuffer(const std::shared_ptr<C2LinearBlock>& block, size_t size)
+        : C2Buffer(
+              {block->share(block->offset(), size, ::C2Fence())}) {}
+};
+
+static ComponentTestEnvironment* gEnv = nullptr;
+
+namespace {
+
+class Codec2VideoDecHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   private:
+    typedef ::testing::VtsHalHidlTargetTestBase Super;
+
+   public:
+    ::std::string getTestCaseInfo() const override {
+        return ::std::string() +
+                "Component: " + gEnv->getComponent().c_str() + " | " +
+                "Instance: " + gEnv->getInstance().c_str() + " | " +
+                "Res: " + gEnv->getRes().c_str();
+    }
+
+    // google.codec2 Video test setup
+    virtual void SetUp() override {
+        Super::SetUp();
+        mDisableTest = false;
+        ALOGV("Codec2VideoDecHidlTest SetUp");
+        mClient = android::Codec2Client::CreateFromService(
+            gEnv->getInstance().c_str());
+        ASSERT_NE(mClient, nullptr);
+        mListener.reset(new CodecListener(
+            [this](std::list<std::unique_ptr<C2Work>>& workItems) {
+                handleWorkDone(workItems);
+            }));
+        ASSERT_NE(mListener, nullptr);
+        for (int i = 0; i < MAX_INPUT_BUFFERS; ++i) {
+            mWorkQueue.emplace_back(new C2Work);
+        }
+        mClient->createComponent(gEnv->getComponent().c_str(), mListener,
+                                 &mComponent);
+        ASSERT_NE(mComponent, nullptr);
+
+        std::shared_ptr<C2AllocatorStore> store =
+            android::GetCodec2PlatformAllocatorStore();
+        CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR,
+                                       &mLinearAllocator),
+                 C2_OK);
+        mLinearPool = std::make_shared<C2PooledBlockPool>(mLinearAllocator,
+                                                          mBlockPoolId++);
+        ASSERT_NE(mLinearPool, nullptr);
+
+        mCompName = unknown_comp;
+        struct StringToName {
+            const char* Name;
+            standardComp CompName;
+        };
+
+        const StringToName kStringToName[] = {
+            {"h263", h263}, {"avc", avc}, {"mpeg2", mpeg2}, {"mpeg4", mpeg4},
+            {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9}, {"av1", av1},
+        };
+
+        const size_t kNumStringToName =
+            sizeof(kStringToName) / sizeof(kStringToName[0]);
+
+        // Find the component type
+        std::string comp = std::string(gEnv->getComponent());
+        for (size_t i = 0; i < kNumStringToName; ++i) {
+            if (strcasestr(comp.c_str(), kStringToName[i].Name)) {
+                mCompName = kStringToName[i].CompName;
+                break;
+            }
+        }
+        mEos = false;
+        mFramesReceived = 0;
+        mTimestampUs = 0u;
+        mTimestampDevTest = false;
+        if (mCompName == unknown_comp) mDisableTest = true;
+
+        C2SecureModeTuning secureModeTuning{};
+        mComponent->query({ &secureModeTuning }, {}, C2_MAY_BLOCK, nullptr);
+        if (secureModeTuning.value == C2Config::SM_READ_PROTECTED) {
+            mDisableTest = true;
+        }
+
+        if (mDisableTest) std::cout << "[   WARN   ] Test Disabled \n";
+    }
+
+    virtual void TearDown() override {
+        if (mComponent != nullptr) {
+            if (::testing::Test::HasFatalFailure()) return;
+            mComponent->release();
+            mComponent = nullptr;
+        }
+        Super::TearDown();
+    }
+
+    // callback function to process onWorkDone received by Listener
+    void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
+        for (std::unique_ptr<C2Work>& work : workItems) {
+            if (!work->worklets.empty()) {
+                // For decoder components current timestamp always exceeds
+                // previous timestamp
+                typedef std::unique_lock<std::mutex> ULock;
+                bool codecConfig = ((work->worklets.front()->output.flags &
+                                     C2FrameData::FLAG_CODEC_CONFIG) != 0);
+                if (!codecConfig &&
+                    !work->worklets.front()->output.buffers.empty()) {
+                    EXPECT_GE(
+                        (work->worklets.front()->output.ordinal.timestamp.peeku()),
+                        mTimestampUs);
+                    mTimestampUs =
+                        work->worklets.front()->output.ordinal.timestamp.peeku();
+
+                    ULock l(mQueueLock);
+                    if (mTimestampDevTest) {
+                        bool tsHit = false;
+                        std::list<uint64_t>::iterator it = mTimestampUslist.begin();
+                        while (it != mTimestampUslist.end()) {
+                            if (*it == mTimestampUs) {
+                                mTimestampUslist.erase(it);
+                                tsHit = true;
+                                break;
+                            }
+                            it++;
+                        }
+                        if (tsHit == false) {
+                            if (mTimestampUslist.empty() == false) {
+                                EXPECT_EQ(tsHit, true)
+                                    << "TimeStamp not recognized";
+                            } else {
+                                std::cout << "[   INFO   ] Received non-zero "
+                                             "output / TimeStamp not recognized \n";
+                            }
+                        }
+                    }
+                }
+                bool mCsd;
+                workDone(mComponent, work, mFlushedIndices, mQueueLock,
+                         mQueueCondition, mWorkQueue, mEos, mCsd,
+                         mFramesReceived);
+                (void)mCsd;
+            }
+        }
+    }
+
+    enum standardComp {
+        h263,
+        avc,
+        mpeg2,
+        mpeg4,
+        hevc,
+        vp8,
+        vp9,
+        av1,
+        unknown_comp,
+    };
+
+    bool mEos;
+    bool mDisableTest;
+    bool mTimestampDevTest;
+    uint64_t mTimestampUs;
+    std::list<uint64_t> mTimestampUslist;
+    std::list<uint64_t> mFlushedIndices;
+    standardComp mCompName;
+    uint32_t mFramesReceived;
+    C2BlockPool::local_id_t mBlockPoolId;
+    std::shared_ptr<C2BlockPool> mLinearPool;
+    std::shared_ptr<C2Allocator> mLinearAllocator;
+
+    std::mutex mQueueLock;
+    std::condition_variable mQueueCondition;
+    std::list<std::unique_ptr<C2Work>> mWorkQueue;
+
+    std::shared_ptr<android::Codec2Client> mClient;
+    std::shared_ptr<android::Codec2Client::Listener> mListener;
+    std::shared_ptr<android::Codec2Client::Component> mComponent;
+
+   protected:
+    static void description(const std::string& description) {
+        RecordProperty("description", description);
+    }
+};
+
+void validateComponent(
+    const std::shared_ptr<android::Codec2Client::Component>& component,
+    Codec2VideoDecHidlTest::standardComp compName, bool& disableTest) {
+    // Validate its a C2 Component
+    if (component->getName().find("c2") == std::string::npos) {
+        ALOGE("Not a c2 component");
+        disableTest = true;
+        return;
+    }
+
+    // Validate its not an encoder and the component to be tested is video
+    if (component->getName().find("encoder") != std::string::npos) {
+        ALOGE("Expected Decoder, given Encoder");
+        disableTest = true;
+        return;
+    }
+    std::vector<std::unique_ptr<C2Param>> queried;
+    c2_status_t c2err =
+        component->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE},
+                         C2_DONT_BLOCK, &queried);
+    if (c2err != C2_OK && queried.size() == 0) {
+        ALOGE("Query media type failed => %d", c2err);
+    } else {
+        std::string inputDomain =
+            ((C2StreamMediaTypeSetting::input*)queried[0].get())->m.value;
+        if (inputDomain.find("video/") == std::string::npos) {
+            ALOGE("Expected Video Component");
+            disableTest = true;
+            return;
+        }
+    }
+
+    // Validates component name
+    if (compName == Codec2VideoDecHidlTest::unknown_comp) {
+        ALOGE("Component InValid");
+        disableTest = true;
+        return;
+    }
+    ALOGV("Component Valid");
+}
+
+// number of elementary streams per component
+#define STREAM_COUNT 2
+// LookUpTable of clips and metadata for component testing
+void GetURLForComponent(Codec2VideoDecHidlTest::standardComp comp, char* mURL,
+                        char* info, size_t streamIndex = 1) {
+    struct CompToURL {
+        Codec2VideoDecHidlTest::standardComp comp;
+        const char mURL[STREAM_COUNT][512];
+        const char info[STREAM_COUNT][512];
+    };
+    ASSERT_TRUE(streamIndex < STREAM_COUNT);
+
+    static const CompToURL kCompToURL[] = {
+        {Codec2VideoDecHidlTest::standardComp::avc,
+         {"bbb_avc_176x144_300kbps_60fps.h264",
+          "bbb_avc_640x360_768kbps_30fps.h264"},
+         {"bbb_avc_176x144_300kbps_60fps.info",
+          "bbb_avc_640x360_768kbps_30fps.info"}},
+        {Codec2VideoDecHidlTest::standardComp::hevc,
+         {"bbb_hevc_176x144_176kbps_60fps.hevc",
+          "bbb_hevc_640x360_1600kbps_30fps.hevc"},
+         {"bbb_hevc_176x144_176kbps_60fps.info",
+          "bbb_hevc_640x360_1600kbps_30fps.info"}},
+        {Codec2VideoDecHidlTest::standardComp::mpeg2,
+         {"bbb_mpeg2_176x144_105kbps_25fps.m2v",
+          "bbb_mpeg2_352x288_1mbps_60fps.m2v"},
+         {"bbb_mpeg2_176x144_105kbps_25fps.info",
+          "bbb_mpeg2_352x288_1mbps_60fps.info"}},
+        {Codec2VideoDecHidlTest::standardComp::h263,
+         {"", "bbb_h263_352x288_300kbps_12fps.h263"},
+         {"", "bbb_h263_352x288_300kbps_12fps.info"}},
+        {Codec2VideoDecHidlTest::standardComp::mpeg4,
+         {"", "bbb_mpeg4_352x288_512kbps_30fps.m4v"},
+         {"", "bbb_mpeg4_352x288_512kbps_30fps.info"}},
+        {Codec2VideoDecHidlTest::standardComp::vp8,
+         {"bbb_vp8_176x144_240kbps_60fps.vp8",
+          "bbb_vp8_640x360_2mbps_30fps.vp8"},
+         {"bbb_vp8_176x144_240kbps_60fps.info",
+          "bbb_vp8_640x360_2mbps_30fps.info"}},
+        {Codec2VideoDecHidlTest::standardComp::vp9,
+         {"bbb_vp9_176x144_285kbps_60fps.vp9",
+          "bbb_vp9_640x360_1600kbps_30fps.vp9"},
+         {"bbb_vp9_176x144_285kbps_60fps.info",
+          "bbb_vp9_640x360_1600kbps_30fps.info"}},
+        {Codec2VideoDecHidlTest::standardComp::av1,
+         {"bbb_av1_640_360.av1",
+          "bbb_av1_176_144.av1"},
+         {"bbb_av1_640_360.info",
+          "bbb_av1_176_144.info"}},
+    };
+
+    for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) {
+        if (kCompToURL[i].comp == comp) {
+            strcat(mURL, kCompToURL[i].mURL[streamIndex]);
+            strcat(info, kCompToURL[i].info[streamIndex]);
+            return;
+        }
+    }
+}
+
+void decodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
+                   std::mutex &queueLock, std::condition_variable& queueCondition,
+                   std::list<std::unique_ptr<C2Work>>& workQueue,
+                   std::list<uint64_t>& flushedIndices,
+                   std::shared_ptr<C2BlockPool>& linearPool,
+                   std::ifstream& eleStream,
+                   android::Vector<FrameInfo>* Info,
+                   int offset, int range, bool signalEOS = true) {
+    typedef std::unique_lock<std::mutex> ULock;
+    int frameID = offset;
+    int maxRetry = 0;
+    while (1) {
+        if (frameID == (int)Info->size() || frameID == (offset + range)) break;
+        uint32_t flags = 0;
+        std::unique_ptr<C2Work> work;
+        // Prepare C2Work
+        while (!work && (maxRetry < MAX_RETRY)) {
+            ULock l(queueLock);
+            if (!workQueue.empty()) {
+                work.swap(workQueue.front());
+                workQueue.pop_front();
+            } else {
+                queueCondition.wait_for(l, TIME_OUT);
+                maxRetry++;
+            }
+        }
+        if (!work && (maxRetry >= MAX_RETRY)) {
+            ASSERT_TRUE(false) << "Wait for generating C2Work exceeded timeout";
+        }
+        int64_t timestamp = (*Info)[frameID].timestamp;
+        if ((*Info)[frameID].flags) flags = (1 << ((*Info)[frameID].flags - 1));
+        if (signalEOS && ((frameID == (int)Info->size() - 1) ||
+                          (frameID == (offset + range - 1))))
+            flags |= C2FrameData::FLAG_END_OF_STREAM;
+
+        work->input.flags = (C2FrameData::flags_t)flags;
+        work->input.ordinal.timestamp = timestamp;
+        work->input.ordinal.frameIndex = frameID;
+        {
+            ULock l(queueLock);
+            flushedIndices.emplace_back(frameID);
+        }
+
+        int size = (*Info)[frameID].bytesCount;
+        char* data = (char*)malloc(size);
+        ASSERT_NE(data, nullptr);
+
+        eleStream.read(data, size);
+        ASSERT_EQ(eleStream.gcount(), size);
+
+        work->input.buffers.clear();
+        auto alignedSize = ALIGN(size, PAGE_SIZE);
+        if (size) {
+            std::shared_ptr<C2LinearBlock> block;
+            ASSERT_EQ(C2_OK,
+                    linearPool->fetchLinearBlock(
+                        alignedSize, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE},
+                        &block));
+            ASSERT_TRUE(block);
+
+            // Write View
+            C2WriteView view = block->map().get();
+            if (view.error() != C2_OK) {
+                fprintf(stderr, "C2LinearBlock::map() failed : %d", view.error());
+                break;
+            }
+            ASSERT_EQ((size_t)alignedSize, view.capacity());
+            ASSERT_EQ(0u, view.offset());
+            ASSERT_EQ((size_t)alignedSize, view.size());
+
+            memcpy(view.base(), data, size);
+
+            work->input.buffers.emplace_back(new LinearBuffer(block, size));
+            free(data);
+        }
+        work->worklets.clear();
+        work->worklets.emplace_back(new C2Worklet);
+        std::list<std::unique_ptr<C2Work>> items;
+        items.push_back(std::move(work));
+
+        // DO THE DECODING
+        ASSERT_EQ(component->queue(&items), C2_OK);
+        ALOGV("Frame #%d size = %d queued", frameID, size);
+        frameID++;
+        maxRetry = 0;
+    }
+}
+
+TEST_F(Codec2VideoDecHidlTest, validateCompName) {
+    if (mDisableTest) return;
+    ALOGV("Checks if the given component is a valid video component");
+    validateComponent(mComponent, mCompName, mDisableTest);
+    ASSERT_EQ(mDisableTest, false);
+}
+
+class Codec2VideoDecDecodeTest
+    : public Codec2VideoDecHidlTest,
+      public ::testing::WithParamInterface<std::pair<int32_t, bool>> {
+};
+
+// Bitstream Test
+TEST_P(Codec2VideoDecDecodeTest, DecodeTest) {
+    description("Decodes input file");
+    if (mDisableTest) return;
+
+    uint32_t streamIndex = GetParam().first;
+    bool signalEOS = GetParam().second;
+    char mURL[512], info[512];
+    std::ifstream eleStream, eleInfo;
+    strcpy(mURL, gEnv->getRes().c_str());
+    strcpy(info, gEnv->getRes().c_str());
+    GetURLForComponent(mCompName, mURL, info, streamIndex);
+
+    eleInfo.open(info);
+    ASSERT_EQ(eleInfo.is_open(), true) << mURL << " - file not found";
+    android::Vector<FrameInfo> Info;
+    int bytesCount = 0;
+    uint32_t flags = 0;
+    uint32_t timestamp = 0;
+    mTimestampDevTest = true;
+    mFlushedIndices.clear();
+    mTimestampUslist.clear();
+    while (1) {
+        if (!(eleInfo >> bytesCount)) break;
+        eleInfo >> flags;
+        eleInfo >> timestamp;
+        bool codecConfig = flags ?
+            ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0 : 0;
+        if (mTimestampDevTest && !codecConfig)
+            mTimestampUslist.push_back(timestamp);
+        Info.push_back({bytesCount, flags, timestamp});
+    }
+    eleInfo.close();
+
+    ASSERT_EQ(mComponent->start(), C2_OK);
+    // Reset total no of frames received
+    mFramesReceived = 0;
+    mTimestampUs = 0;
+    ALOGV("mURL : %s", mURL);
+    eleStream.open(mURL, std::ifstream::binary);
+    ASSERT_EQ(eleStream.is_open(), true);
+    ASSERT_NO_FATAL_FAILURE(decodeNFrames(
+        mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices,
+        mLinearPool, eleStream, &Info, 0, (int)Info.size(), signalEOS));
+
+    // If EOS is not sent, sending empty input with EOS flag
+    size_t infoSize = Info.size();
+    if (!signalEOS) {
+        ASSERT_NO_FATAL_FAILURE(
+            waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, 1));
+        ASSERT_NO_FATAL_FAILURE(
+            testInputBuffer(mComponent, mQueueLock, mWorkQueue,
+                            C2FrameData::FLAG_END_OF_STREAM, false));
+        infoSize += 1;
+    }
+    // blocking call to ensures application to Wait till all the inputs are
+    // consumed
+    if (!mEos) {
+        ALOGV("Waiting for input consumption");
+        ASSERT_NO_FATAL_FAILURE(
+            waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+    }
+
+    eleStream.close();
+    if (mFramesReceived != infoSize) {
+        ALOGE("Input buffer count and Output buffer count mismatch");
+        ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived,
+              infoSize);
+        ASSERT_TRUE(false);
+    }
+
+    if (mTimestampDevTest) EXPECT_EQ(mTimestampUslist.empty(), true);
+    ASSERT_EQ(mComponent->stop(), C2_OK);
+}
+// DecodeTest with StreamIndex and EOS / No EOS
+INSTANTIATE_TEST_CASE_P(StreamIndexAndEOS, Codec2VideoDecDecodeTest,
+                        ::testing::Values(std::make_pair(0, false),
+                                          std::make_pair(0, true),
+                                          std::make_pair(1, false),
+                                          std::make_pair(1, true)));
+
+// Adaptive Test
+TEST_F(Codec2VideoDecHidlTest, AdaptiveDecodeTest) {
+    description("Adaptive Decode Test");
+    if (mDisableTest) return;
+    if (!(mCompName == avc || mCompName == hevc || mCompName == vp8 ||
+          mCompName == vp9 || mCompName == mpeg2))
+        return;
+
+    typedef std::unique_lock<std::mutex> ULock;
+    ASSERT_EQ(mComponent->start(), C2_OK);
+
+    mTimestampDevTest = true;
+    uint32_t timestampOffset = 0;
+    uint32_t offset = 0;
+    android::Vector<FrameInfo> Info;
+    for (uint32_t i = 0; i < STREAM_COUNT * 2; i++) {
+        char mURL[512], info[512];
+        std::ifstream eleStream, eleInfo;
+
+        strcpy(mURL, gEnv->getRes().c_str());
+        strcpy(info, gEnv->getRes().c_str());
+        GetURLForComponent(mCompName, mURL, info, i % STREAM_COUNT);
+
+        eleInfo.open(info);
+        ASSERT_EQ(eleInfo.is_open(), true) << mURL << " - file not found";
+        int bytesCount = 0;
+        uint32_t flags = 0;
+        uint32_t timestamp = 0;
+        uint32_t timestampMax = 0;
+        while (1) {
+            if (!(eleInfo >> bytesCount)) break;
+            eleInfo >> flags;
+            eleInfo >> timestamp;
+            timestamp += timestampOffset;
+            Info.push_back({bytesCount, flags, timestamp});
+            bool codecConfig = flags ?
+                ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0 : 0;
+
+            {
+                ULock l(mQueueLock);
+                if (mTimestampDevTest && !codecConfig)
+                    mTimestampUslist.push_back(timestamp);
+            }
+            if (timestampMax < timestamp) timestampMax = timestamp;
+        }
+        timestampOffset = timestampMax;
+        eleInfo.close();
+
+        // Reset Total frames before second decode loop
+        // mFramesReceived = 0;
+        ALOGV("mURL : %s", mURL);
+        eleStream.open(mURL, std::ifstream::binary);
+        ASSERT_EQ(eleStream.is_open(), true);
+        ASSERT_NO_FATAL_FAILURE(
+            decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                          mFlushedIndices, mLinearPool, eleStream, &Info,
+                          offset, (int)(Info.size() - offset), false));
+
+        eleStream.close();
+        offset = (int)Info.size();
+    }
+
+    // Send EOS
+    // TODO Add function to send EOS work item
+    int maxRetry = 0;
+    std::unique_ptr<C2Work> work;
+    while (!work && (maxRetry < MAX_RETRY)) {
+        ULock l(mQueueLock);
+        if (!mWorkQueue.empty()) {
+            work.swap(mWorkQueue.front());
+            mWorkQueue.pop_front();
+        } else {
+            mQueueCondition.wait_for(l, TIME_OUT);
+            maxRetry++;
+        }
+    }
+    ASSERT_NE(work, nullptr);
+    work->input.flags = (C2FrameData::flags_t)C2FrameData::FLAG_END_OF_STREAM;
+    work->input.ordinal.timestamp = 0;
+    work->input.ordinal.frameIndex = 0;
+    work->input.buffers.clear();
+    work->worklets.clear();
+    work->worklets.emplace_back(new C2Worklet);
+
+    std::list<std::unique_ptr<C2Work>> items;
+    items.push_back(std::move(work));
+    ASSERT_EQ(mComponent->queue(&items), C2_OK);
+
+    // blocking call to ensures application to Wait till all the inputs are
+    // consumed
+    ALOGV("Waiting for input consumption");
+    ASSERT_NO_FATAL_FAILURE(
+        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+
+    if (mFramesReceived != ((Info.size()) + 1)) {
+        ALOGE("Input buffer count and Output buffer count mismatch");
+        ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived,
+              Info.size() + 1);
+        ASSERT_TRUE(false);
+    }
+
+    if (mTimestampDevTest) EXPECT_EQ(mTimestampUslist.empty(), true);
+}
+
+// thumbnail test
+TEST_F(Codec2VideoDecHidlTest, ThumbnailTest) {
+    description("Test Request for thumbnail");
+    if (mDisableTest) return;
+
+    char mURL[512], info[512];
+    std::ifstream eleStream, eleInfo;
+
+    strcpy(mURL, gEnv->getRes().c_str());
+    strcpy(info, gEnv->getRes().c_str());
+    GetURLForComponent(mCompName, mURL, info);
+
+    eleInfo.open(info);
+    ASSERT_EQ(eleInfo.is_open(), true);
+    android::Vector<FrameInfo> Info;
+    int bytesCount = 0;
+    uint32_t flags = 0;
+    uint32_t timestamp = 0;
+    while (1) {
+        if (!(eleInfo >> bytesCount)) break;
+        eleInfo >> flags;
+        eleInfo >> timestamp;
+        Info.push_back({bytesCount, flags, timestamp});
+    }
+    eleInfo.close();
+
+    for (size_t i = 0; i < MAX_ITERATIONS; i++) {
+        ASSERT_EQ(mComponent->start(), C2_OK);
+
+        // request EOS for thumbnail
+        // signal EOS flag with last frame
+        size_t j = -1;
+        do {
+            j++;
+            flags = 0;
+            if (Info[j].flags) flags = 1u << (Info[j].flags - 1);
+
+        } while (!(flags & SYNC_FRAME));
+        eleStream.open(mURL, std::ifstream::binary);
+        ASSERT_EQ(eleStream.is_open(), true);
+        ASSERT_NO_FATAL_FAILURE(decodeNFrames(
+            mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+            mFlushedIndices, mLinearPool, eleStream, &Info, 0, j + 1));
+        ASSERT_NO_FATAL_FAILURE(
+            waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+        eleStream.close();
+        EXPECT_GE(mFramesReceived, 1U);
+        ASSERT_EQ(mEos, true);
+        ASSERT_EQ(mComponent->stop(), C2_OK);
+    }
+    ASSERT_EQ(mComponent->release(), C2_OK);
+}
+
+TEST_F(Codec2VideoDecHidlTest, EOSTest) {
+    description("Test empty input buffer with EOS flag");
+    if (mDisableTest) return;
+    typedef std::unique_lock<std::mutex> ULock;
+    ASSERT_EQ(mComponent->start(), C2_OK);
+    std::unique_ptr<C2Work> work;
+    // Prepare C2Work
+    {
+        ULock l(mQueueLock);
+        if (!mWorkQueue.empty()) {
+            work.swap(mWorkQueue.front());
+            mWorkQueue.pop_front();
+        } else {
+            ASSERT_TRUE(false) << "mWorkQueue Empty at the start of test";
+        }
+    }
+    ASSERT_NE(work, nullptr);
+
+    work->input.flags = (C2FrameData::flags_t)C2FrameData::FLAG_END_OF_STREAM;
+    work->input.ordinal.timestamp = 0;
+    work->input.ordinal.frameIndex = 0;
+    work->input.buffers.clear();
+    work->worklets.clear();
+    work->worklets.emplace_back(new C2Worklet);
+
+    std::list<std::unique_ptr<C2Work>> items;
+    items.push_back(std::move(work));
+    ASSERT_EQ(mComponent->queue(&items), C2_OK);
+
+    {
+        ULock l(mQueueLock);
+        if (mWorkQueue.size() != MAX_INPUT_BUFFERS) {
+            mQueueCondition.wait_for(l, TIME_OUT);
+        }
+    }
+    ASSERT_EQ(mEos, true);
+    ASSERT_EQ(mWorkQueue.size(), (size_t)MAX_INPUT_BUFFERS);
+    ASSERT_EQ(mComponent->stop(), C2_OK);
+}
+
+TEST_F(Codec2VideoDecHidlTest, FlushTest) {
+    description("Tests Flush calls");
+    if (mDisableTest) return;
+    typedef std::unique_lock<std::mutex> ULock;
+    ASSERT_EQ(mComponent->start(), C2_OK);
+    char mURL[512], info[512];
+    std::ifstream eleStream, eleInfo;
+
+    strcpy(mURL, gEnv->getRes().c_str());
+    strcpy(info, gEnv->getRes().c_str());
+    GetURLForComponent(mCompName, mURL, info);
+
+    eleInfo.open(info);
+    ASSERT_EQ(eleInfo.is_open(), true);
+    android::Vector<FrameInfo> Info;
+    int bytesCount = 0;
+    uint32_t flags = 0;
+    uint32_t timestamp = 0;
+    mFlushedIndices.clear();
+    while (1) {
+        if (!(eleInfo >> bytesCount)) break;
+        eleInfo >> flags;
+        eleInfo >> timestamp;
+        Info.push_back({bytesCount, flags, timestamp});
+    }
+    eleInfo.close();
+
+    ALOGV("mURL : %s", mURL);
+    eleStream.open(mURL, std::ifstream::binary);
+    ASSERT_EQ(eleStream.is_open(), true);
+    // Decode 128 frames and flush. here 128 is chosen to ensure there is a key
+    // frame after this so that the below section can be covered for all
+    // components
+    uint32_t numFramesFlushed = 128;
+    ASSERT_NO_FATAL_FAILURE(decodeNFrames(
+        mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices,
+        mLinearPool, eleStream, &Info, 0, numFramesFlushed, false));
+    // flush
+    std::list<std::unique_ptr<C2Work>> flushedWork;
+    c2_status_t err =
+        mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
+    ASSERT_EQ(err, C2_OK);
+    ASSERT_NO_FATAL_FAILURE(
+        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
+                               (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
+
+    {
+        // Update mFlushedIndices based on the index received from flush()
+        ULock l(mQueueLock);
+        for (std::unique_ptr<C2Work>& work : flushedWork) {
+            ASSERT_NE(work, nullptr);
+            auto frameIndexIt =
+                std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
+                          work->input.ordinal.frameIndex.peeku());
+            if (!mFlushedIndices.empty() &&
+                (frameIndexIt != mFlushedIndices.end())) {
+                mFlushedIndices.erase(frameIndexIt);
+                work->input.buffers.clear();
+                work->worklets.clear();
+                mWorkQueue.push_back(std::move(work));
+            }
+        }
+    }
+    // Seek to next key frame and start decoding till the end
+    mFlushedIndices.clear();
+    int index = numFramesFlushed;
+    bool keyFrame = false;
+    flags = 0;
+    while (index < (int)Info.size()) {
+        if (Info[index].flags) flags = 1u << (Info[index].flags - 1);
+        if ((flags & SYNC_FRAME) == SYNC_FRAME) {
+            keyFrame = true;
+            break;
+        }
+        flags = 0;
+        eleStream.ignore(Info[index].bytesCount);
+        index++;
+    }
+    if (keyFrame) {
+        ASSERT_NO_FATAL_FAILURE(
+            decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                          mFlushedIndices, mLinearPool, eleStream, &Info, index,
+                          (int)Info.size() - index));
+    }
+    eleStream.close();
+    err = mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
+    ASSERT_EQ(err, C2_OK);
+    ASSERT_NO_FATAL_FAILURE(
+        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
+                               (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
+    {
+        // Update mFlushedIndices based on the index received from flush()
+        ULock l(mQueueLock);
+        for (std::unique_ptr<C2Work>& work : flushedWork) {
+            ASSERT_NE(work, nullptr);
+            uint64_t frameIndex = work->input.ordinal.frameIndex.peeku();
+            std::list<uint64_t>::iterator frameIndexIt = std::find(
+                mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex);
+            if (!mFlushedIndices.empty() &&
+                (frameIndexIt != mFlushedIndices.end())) {
+                mFlushedIndices.erase(frameIndexIt);
+                work->input.buffers.clear();
+                work->worklets.clear();
+                mWorkQueue.push_back(std::move(work));
+            }
+        }
+    }
+    ASSERT_EQ(mFlushedIndices.empty(), true);
+    ASSERT_EQ(mComponent->stop(), C2_OK);
+}
+
+TEST_F(Codec2VideoDecHidlTest, DecodeTestEmptyBuffersInserted) {
+    description("Decode with multiple empty input frames");
+    if (mDisableTest) return;
+
+    char mURL[512], info[512];
+    std::ifstream eleStream, eleInfo;
+
+    strcpy(mURL, gEnv->getRes().c_str());
+    strcpy(info, gEnv->getRes().c_str());
+    GetURLForComponent(mCompName, mURL, info);
+
+    eleInfo.open(info);
+    ASSERT_EQ(eleInfo.is_open(), true) << mURL << " - file not found";
+    android::Vector<FrameInfo> Info;
+    int bytesCount = 0;
+    uint32_t frameId = 0;
+    uint32_t flags = 0;
+    uint32_t timestamp = 0;
+    bool codecConfig = false;
+    // This test introduces empty CSD after every 20th frame
+    // and empty input frames at an interval of 5 frames.
+    while (1) {
+        if (!(frameId % 5)) {
+            if (!(frameId % 20)) flags = 32;
+            else flags = 0;
+            bytesCount = 0;
+        } else {
+            if (!(eleInfo >> bytesCount)) break;
+            eleInfo >> flags;
+            eleInfo >> timestamp;
+            codecConfig = flags ?
+                ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0 : 0;
+        }
+        Info.push_back({bytesCount, flags, timestamp});
+        frameId++;
+    }
+    eleInfo.close();
+
+    ASSERT_EQ(mComponent->start(), C2_OK);
+    ALOGV("mURL : %s", mURL);
+    eleStream.open(mURL, std::ifstream::binary);
+    ASSERT_EQ(eleStream.is_open(), true);
+    ASSERT_NO_FATAL_FAILURE(decodeNFrames(
+        mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices,
+        mLinearPool, eleStream, &Info, 0, (int)Info.size()));
+
+    // blocking call to ensures application to Wait till all the inputs are
+    // consumed
+    if (!mEos) {
+        ALOGV("Waiting for input consumption");
+        ASSERT_NO_FATAL_FAILURE(
+            waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+    }
+
+    eleStream.close();
+    if (mFramesReceived != Info.size()) {
+        ALOGE("Input buffer count and Output buffer count mismatch");
+        ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived,
+              Info.size());
+        ASSERT_TRUE(false);
+    }
+}
+
+}  // anonymous namespace
+
+// TODO : Video specific configuration Test
+int main(int argc, char** argv) {
+    gEnv = new ComponentTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    gEnv->init(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        int status = RUN_ALL_TESTS();
+        LOG(INFO) << "C2 Test result = " << status;
+    }
+    return status;
+}
diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp
new file mode 100644
index 0000000..c1f5a92
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp
@@ -0,0 +1,738 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "codec2_hidl_hal_video_enc_test"
+
+#include <android-base/logging.h>
+#include <gtest/gtest.h>
+#include <stdio.h>
+#include <fstream>
+
+#include <codec2/hidl/client.h>
+#include <C2AllocatorIon.h>
+#include <C2Config.h>
+#include <C2Debug.h>
+#include <C2Buffer.h>
+#include <C2BufferPriv.h>
+
+using android::C2AllocatorIon;
+
+#include <VtsHalHidlTargetTestBase.h>
+#include "media_c2_video_hidl_test_common.h"
+#include "media_c2_hidl_test_common.h"
+
+class GraphicBuffer : public C2Buffer {
+public:
+  explicit GraphicBuffer(const std::shared_ptr<C2GraphicBlock> &block)
+      : C2Buffer({block->share(C2Rect(block->width(), block->height()),
+                               ::C2Fence())}) {}
+};
+
+static ComponentTestEnvironment* gEnv = nullptr;
+
+namespace {
+
+class Codec2VideoEncHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   private:
+    typedef ::testing::VtsHalHidlTargetTestBase Super;
+
+   public:
+    ::std::string getTestCaseInfo() const override {
+        return ::std::string() +
+                "Component: " + gEnv->getComponent().c_str() + " | " +
+                "Instance: " + gEnv->getInstance().c_str() + " | " +
+                "Res: " + gEnv->getRes().c_str();
+    }
+
+    // google.codec2 Video test setup
+    virtual void SetUp() override {
+        Super::SetUp();
+        mDisableTest = false;
+        ALOGV("Codec2VideoEncHidlTest SetUp");
+        mClient = android::Codec2Client::CreateFromService(
+            gEnv->getInstance().c_str());
+        ASSERT_NE(mClient, nullptr);
+        mListener.reset(new CodecListener(
+            [this](std::list<std::unique_ptr<C2Work>>& workItems) {
+                handleWorkDone(workItems);
+            }));
+        ASSERT_NE(mListener, nullptr);
+        for (int i = 0; i < MAX_INPUT_BUFFERS; ++i) {
+            mWorkQueue.emplace_back(new C2Work);
+        }
+        mClient->createComponent(gEnv->getComponent().c_str(), mListener,
+                                 &mComponent);
+        ASSERT_NE(mComponent, nullptr);
+
+        std::shared_ptr<C2AllocatorStore> store =
+            android::GetCodec2PlatformAllocatorStore();
+        CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_GRAPHIC,
+                                       &mGraphicAllocator),
+                 C2_OK);
+        mGraphicPool = std::make_shared<C2PooledBlockPool>(mGraphicAllocator,
+                                                           mBlockPoolId++);
+        ASSERT_NE(mGraphicPool, nullptr);
+
+        mCompName = unknown_comp;
+        struct StringToName {
+            const char* Name;
+            standardComp CompName;
+        };
+
+        const StringToName kStringToName[] = {
+            {"h263", h263}, {"avc", avc}, {"mpeg4", mpeg4},
+            {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9},
+        };
+
+        const size_t kNumStringToName =
+            sizeof(kStringToName) / sizeof(kStringToName[0]);
+
+        // Find the component type
+        std::string comp = std::string(gEnv->getComponent());
+        for (size_t i = 0; i < kNumStringToName; ++i) {
+            if (strcasestr(comp.c_str(), kStringToName[i].Name)) {
+                mCompName = kStringToName[i].CompName;
+                break;
+            }
+        }
+        mEos = false;
+        mCsd = false;
+        mFramesReceived = 0;
+        mFailedWorkReceived = 0;
+        mTimestampUs = 0u;
+        mTimestampDevTest = false;
+        if (mCompName == unknown_comp) mDisableTest = true;
+        if (mDisableTest) std::cout << "[   WARN   ] Test Disabled \n";
+    }
+
+    virtual void TearDown() override {
+        if (mComponent != nullptr) {
+            if (::testing::Test::HasFatalFailure()) return;
+            mComponent->release();
+            mComponent = nullptr;
+        }
+        Super::TearDown();
+    }
+
+    bool setupConfigParam(int32_t nWidth, int32_t nHeight);
+
+    // callback function to process onWorkDone received by Listener
+    void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
+        for (std::unique_ptr<C2Work>& work : workItems) {
+            if (!work->worklets.empty()) {
+                // For encoder components current timestamp always exceeds
+                // previous timestamp
+                typedef std::unique_lock<std::mutex> ULock;
+                if (!mTimestampUslist.empty()) {
+                    EXPECT_GE((work->worklets.front()
+                                   ->output.ordinal.timestamp.peeku()),
+                              mTimestampUs);
+                    mTimestampUs = work->worklets.front()
+                                       ->output.ordinal.timestamp.peeku();
+                    // Currently this lock is redundant as no mTimestampUslist is only initialized
+                    // before queuing any work to component. Once AdaptiveTest is added similar to
+                    // the one in video decoders, this is needed.
+                    ULock l(mQueueLock);
+
+                    if (mTimestampDevTest) {
+                        bool tsHit = false;
+                        std::list<uint64_t>::iterator it =
+                            mTimestampUslist.begin();
+                        while (it != mTimestampUslist.end()) {
+                            if (*it == mTimestampUs) {
+                                mTimestampUslist.erase(it);
+                                tsHit = true;
+                                break;
+                            }
+                            it++;
+                        }
+                        if (tsHit == false) {
+                            if (mTimestampUslist.empty() == false) {
+                                EXPECT_EQ(tsHit, true)
+                                    << "TimeStamp not recognized";
+                            } else {
+                                std::cout
+                                    << "[   INFO   ] Received non-zero "
+                                       "output / TimeStamp not recognized \n";
+                            }
+                        }
+                    }
+                }
+
+                if (work->result != C2_OK) mFailedWorkReceived++;
+                workDone(mComponent, work, mFlushedIndices, mQueueLock,
+                         mQueueCondition, mWorkQueue, mEos, mCsd,
+                         mFramesReceived);
+            }
+        }
+    }
+
+    enum standardComp {
+        h263,
+        avc,
+        mpeg4,
+        hevc,
+        vp8,
+        vp9,
+        unknown_comp,
+    };
+
+    bool mEos;
+    bool mCsd;
+    bool mDisableTest;
+    bool mConfig;
+    bool mTimestampDevTest;
+    standardComp mCompName;
+    uint32_t mFramesReceived;
+    uint32_t mFailedWorkReceived;
+    uint64_t mTimestampUs;
+
+    std::list<uint64_t> mTimestampUslist;
+    std::list<uint64_t> mFlushedIndices;
+
+    C2BlockPool::local_id_t mBlockPoolId;
+    std::shared_ptr<C2BlockPool> mGraphicPool;
+    std::shared_ptr<C2Allocator> mGraphicAllocator;
+
+    std::mutex mQueueLock;
+    std::condition_variable mQueueCondition;
+    std::list<std::unique_ptr<C2Work>> mWorkQueue;
+
+    std::shared_ptr<android::Codec2Client> mClient;
+    std::shared_ptr<android::Codec2Client::Listener> mListener;
+    std::shared_ptr<android::Codec2Client::Component> mComponent;
+
+   protected:
+    static void description(const std::string& description) {
+        RecordProperty("description", description);
+    }
+};
+
+void validateComponent(
+    const std::shared_ptr<android::Codec2Client::Component>& component,
+    Codec2VideoEncHidlTest::standardComp compName, bool& disableTest) {
+    // Validate its a C2 Component
+    if (component->getName().find("c2") == std::string::npos) {
+        ALOGE("Not a c2 component");
+        disableTest = true;
+        return;
+    }
+
+    // Validate its not an encoder and the component to be tested is video
+    if (component->getName().find("decoder") != std::string::npos) {
+        ALOGE("Expected Encoder, given Decoder");
+        disableTest = true;
+        return;
+    }
+    std::vector<std::unique_ptr<C2Param>> queried;
+    c2_status_t c2err =
+        component->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE},
+                         C2_DONT_BLOCK, &queried);
+    if (c2err != C2_OK && queried.size() == 0) {
+        ALOGE("Query media type failed => %d", c2err);
+    } else {
+        std::string inputDomain =
+            ((C2StreamMediaTypeSetting::input*)queried[0].get())->m.value;
+        if (inputDomain.find("video/") == std::string::npos) {
+            ALOGE("Expected Video Component");
+            disableTest = true;
+            return;
+        }
+    }
+
+    // Validates component name
+    if (compName == Codec2VideoEncHidlTest::unknown_comp) {
+        ALOGE("Component InValid");
+        disableTest = true;
+        return;
+    }
+    ALOGV("Component Valid");
+}
+
+// Set Default config param.
+bool Codec2VideoEncHidlTest::setupConfigParam(int32_t nWidth, int32_t nHeight) {
+    std::vector<std::unique_ptr<C2SettingResult>> failures;
+    C2StreamPictureSizeInfo::input inputSize(0u, nWidth, nHeight);
+    std::vector<C2Param*> configParam{&inputSize};
+    c2_status_t status =
+        mComponent->config(configParam, C2_DONT_BLOCK, &failures);
+    if (status == C2_OK && failures.size() == 0u) return true;
+    return false;
+}
+
+// LookUpTable of clips for component testing
+void GetURLForComponent(char* URL) {
+    strcat(URL, "bbb_352x288_420p_30fps_32frames.yuv");
+}
+
+void encodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
+                   std::mutex &queueLock, std::condition_variable& queueCondition,
+                   std::list<std::unique_ptr<C2Work>>& workQueue,
+                   std::list<uint64_t>& flushedIndices,
+                   std::shared_ptr<C2BlockPool>& graphicPool,
+                   std::ifstream& eleStream, bool& disableTest,
+                   uint32_t frameID, uint32_t nFrames, uint32_t nWidth,
+                   int32_t nHeight, bool flushed = false, bool signalEOS = true) {
+    typedef std::unique_lock<std::mutex> ULock;
+
+    uint32_t maxRetry = 0;
+    int bytesCount = nWidth * nHeight * 3 >> 1;
+    int32_t timestampIncr = ENCODER_TIMESTAMP_INCREMENT;
+    uint64_t timestamp = 0;
+    c2_status_t err = C2_OK;
+    while (1) {
+        if (nFrames == 0) break;
+        uint32_t flags = 0;
+        std::unique_ptr<C2Work> work;
+        // Prepare C2Work
+        while (!work && (maxRetry < MAX_RETRY)) {
+            ULock l(queueLock);
+            if (!workQueue.empty()) {
+                work.swap(workQueue.front());
+                workQueue.pop_front();
+            } else {
+                queueCondition.wait_for(l, TIME_OUT);
+                maxRetry++;
+            }
+        }
+        if (!work && (maxRetry >= MAX_RETRY)) {
+            ASSERT_TRUE(false) << "Wait for generating C2Work exceeded timeout";
+        }
+        if (signalEOS && (nFrames == 1))
+            flags |= C2FrameData::FLAG_END_OF_STREAM;
+        if (flushed) {
+            flags |= SYNC_FRAME;
+            flushed = false;
+        }
+
+        work->input.flags = (C2FrameData::flags_t)flags;
+        work->input.ordinal.timestamp = timestamp;
+        work->input.ordinal.frameIndex = frameID;
+        {
+            ULock l(queueLock);
+            flushedIndices.emplace_back(frameID);
+        }
+        char* data = (char*)malloc(bytesCount);
+        ASSERT_NE(data, nullptr);
+        memset(data, 0, bytesCount);
+        if (eleStream.is_open()) {
+            eleStream.read(data, bytesCount);
+            ASSERT_EQ(eleStream.gcount(), bytesCount);
+        }
+        std::shared_ptr<C2GraphicBlock> block;
+        err = graphicPool->fetchGraphicBlock(
+                nWidth, nHeight, HAL_PIXEL_FORMAT_YV12,
+                {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}, &block);
+        if (err != C2_OK) {
+            fprintf(stderr, "fetchGraphicBlock failed : %d\n", err);
+            disableTest = true;
+            break;
+        }
+
+        ASSERT_TRUE(block);
+        // Graphic View
+        C2GraphicView view = block->map().get();
+        if (view.error() != C2_OK) {
+            fprintf(stderr, "C2GraphicBlock::map() failed : %d", view.error());
+            disableTest = true;
+            break;
+        }
+
+        uint8_t* pY = view.data()[C2PlanarLayout::PLANE_Y];
+        uint8_t* pU = view.data()[C2PlanarLayout::PLANE_U];
+        uint8_t* pV = view.data()[C2PlanarLayout::PLANE_V];
+
+        memcpy(pY, data, nWidth * nHeight);
+        memcpy(pU, data + nWidth * nHeight, (nWidth * nHeight >> 2));
+        memcpy(pV, data + (nWidth * nHeight * 5 >> 2), nWidth * nHeight >> 2);
+
+        work->input.buffers.clear();
+        work->input.buffers.emplace_back(new GraphicBuffer(block));
+        work->worklets.clear();
+        work->worklets.emplace_back(new C2Worklet);
+        free(data);
+
+        std::list<std::unique_ptr<C2Work>> items;
+        items.push_back(std::move(work));
+
+        // DO THE ENCODING
+        ASSERT_EQ(component->queue(&items), C2_OK);
+        ALOGV("Frame #%d size = %d queued", frameID, bytesCount);
+        nFrames--;
+        timestamp += timestampIncr;
+        frameID++;
+        maxRetry = 0;
+    }
+}
+
+TEST_F(Codec2VideoEncHidlTest, validateCompName) {
+    if (mDisableTest) return;
+    ALOGV("Checks if the given component is a valid video component");
+    validateComponent(mComponent, mCompName, mDisableTest);
+    ASSERT_EQ(mDisableTest, false);
+}
+
+class Codec2VideoEncEncodeTest : public Codec2VideoEncHidlTest,
+                                 public ::testing::WithParamInterface<bool> {
+};
+
+TEST_P(Codec2VideoEncEncodeTest, EncodeTest) {
+    description("Encodes input file");
+    if (mDisableTest) return;
+
+    char mURL[512];
+    int32_t nWidth = ENC_DEFAULT_FRAME_WIDTH;
+    int32_t nHeight = ENC_DEFAULT_FRAME_HEIGHT;
+    bool signalEOS = GetParam();
+
+    strcpy(mURL, gEnv->getRes().c_str());
+    GetURLForComponent(mURL);
+
+    std::ifstream eleStream;
+    eleStream.open(mURL, std::ifstream::binary);
+    ASSERT_EQ(eleStream.is_open(), true) << mURL << " file not found";
+    ALOGV("mURL : %s", mURL);
+
+    mTimestampUs = 0;
+    mTimestampDevTest = true;
+    mFlushedIndices.clear();
+    mTimestampUslist.clear();
+    uint32_t inputFrames = ENC_NUM_FRAMES;
+    uint32_t timestamp = 0;
+    // Add input timestamp to timestampUslist
+    while (inputFrames) {
+        if (mTimestampDevTest) mTimestampUslist.push_back(timestamp);
+        timestamp += ENCODER_TIMESTAMP_INCREMENT;
+        inputFrames--;
+    }
+    if (!setupConfigParam(nWidth, nHeight)) {
+        std::cout << "[   WARN   ] Test Skipped \n";
+        return;
+    }
+    ASSERT_EQ(mComponent->start(), C2_OK);
+    ASSERT_NO_FATAL_FAILURE(
+        encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                      mFlushedIndices, mGraphicPool, eleStream, mDisableTest,
+                      0, ENC_NUM_FRAMES, nWidth, nHeight, false, signalEOS));
+    // mDisableTest will be set if buffer was not fetched properly.
+    // This may happen when resolution is not proper but config suceeded
+    // In this cases, we skip encoding the input stream
+    if (mDisableTest) {
+        std::cout << "[   WARN   ] Test Disabled \n";
+        ASSERT_EQ(mComponent->stop(), C2_OK);
+        return;
+    }
+
+    // If EOS is not sent, sending empty input with EOS flag
+    inputFrames = ENC_NUM_FRAMES;
+    if (!signalEOS) {
+        ASSERT_NO_FATAL_FAILURE(
+            waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, 1));
+        ASSERT_NO_FATAL_FAILURE(
+            testInputBuffer(mComponent, mQueueLock, mWorkQueue,
+                            C2FrameData::FLAG_END_OF_STREAM, false));
+        inputFrames += 1;
+    }
+
+    // blocking call to ensures application to Wait till all the inputs are
+    // consumed
+    ALOGD("Waiting for input consumption");
+    ASSERT_NO_FATAL_FAILURE(
+        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+
+    eleStream.close();
+    if (mFramesReceived != inputFrames) {
+        ALOGE("Input buffer count and Output buffer count mismatch");
+        ALOGE("framesReceived : %d inputFrames : %d", mFramesReceived,
+              inputFrames);
+        ASSERT_TRUE(false);
+    }
+
+    if (!mCsd && (mCompName != vp8 && mCompName != vp9)) {
+        ASSERT_TRUE(false) << "CSD Buffer not received";
+    }
+
+    if (mCsd && (mCompName == vp8 || mCompName == vp9)) {
+        ASSERT_TRUE(false) << "CSD Buffer not expected";
+    }
+
+    if (mTimestampDevTest) EXPECT_EQ(mTimestampUslist.empty(), true);
+    ASSERT_EQ(mComponent->stop(), C2_OK);
+}
+
+// EncodeTest with EOS / No EOS
+INSTANTIATE_TEST_CASE_P(EncodeTestwithEOS, Codec2VideoEncEncodeTest,
+                        ::testing::Values(true, false));
+
+TEST_F(Codec2VideoEncHidlTest, EOSTest) {
+    description("Test empty input buffer with EOS flag");
+    if (mDisableTest) return;
+    ASSERT_EQ(mComponent->start(), C2_OK);
+
+    typedef std::unique_lock<std::mutex> ULock;
+    std::unique_ptr<C2Work> work;
+    {
+        ULock l(mQueueLock);
+        if (!mWorkQueue.empty()) {
+            work.swap(mWorkQueue.front());
+            mWorkQueue.pop_front();
+        } else {
+            ALOGE("mWorkQueue Empty is not expected at the start of the test");
+            ASSERT_TRUE(false);
+        }
+    }
+    ASSERT_NE(work, nullptr);
+    work->input.flags = (C2FrameData::flags_t)C2FrameData::FLAG_END_OF_STREAM;
+    work->input.ordinal.timestamp = 0;
+    work->input.ordinal.frameIndex = 0;
+    work->input.buffers.clear();
+    work->worklets.clear();
+    work->worklets.emplace_back(new C2Worklet);
+
+    std::list<std::unique_ptr<C2Work>> items;
+    items.push_back(std::move(work));
+    ASSERT_EQ(mComponent->queue(&items), C2_OK);
+    uint32_t queueSize;
+    {
+        ULock l(mQueueLock);
+        queueSize = mWorkQueue.size();
+        if (queueSize < MAX_INPUT_BUFFERS) {
+            mQueueCondition.wait_for(l, TIME_OUT);
+        }
+    }
+    ASSERT_EQ(mEos, true);
+    ASSERT_EQ(mComponent->stop(), C2_OK);
+}
+
+TEST_F(Codec2VideoEncHidlTest, FlushTest) {
+    description("Test Request for flush");
+    if (mDisableTest) return;
+
+    typedef std::unique_lock<std::mutex> ULock;
+    char mURL[512];
+    int32_t nWidth = ENC_DEFAULT_FRAME_WIDTH;
+    int32_t nHeight = ENC_DEFAULT_FRAME_HEIGHT;
+    strcpy(mURL, gEnv->getRes().c_str());
+    GetURLForComponent(mURL);
+
+    if (!setupConfigParam(nWidth, nHeight)) {
+        std::cout << "[   WARN   ] Test Skipped \n";
+        return;
+    }
+    ASSERT_EQ(mComponent->start(), C2_OK);
+
+    // Setting default configuration
+    mFlushedIndices.clear();
+    std::ifstream eleStream;
+    uint32_t numFramesFlushed = 10;
+    uint32_t numFrames = ENC_NUM_FRAMES;
+    eleStream.open(mURL, std::ifstream::binary);
+    ASSERT_EQ(eleStream.is_open(), true);
+    ALOGV("mURL : %s", mURL);
+    ASSERT_NO_FATAL_FAILURE(
+        encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                      mFlushedIndices, mGraphicPool, eleStream, mDisableTest,
+                      0, numFramesFlushed, nWidth, nHeight));
+    // mDisableTest will be set if buffer was not fetched properly.
+    // This may happen when resolution is not proper but config suceeded
+    // In this cases, we skip encoding the input stream
+    if (mDisableTest) {
+        std::cout << "[   WARN   ] Test Disabled \n";
+        ASSERT_EQ(mComponent->stop(), C2_OK);
+        return;
+    }
+
+    std::list<std::unique_ptr<C2Work>> flushedWork;
+    c2_status_t err =
+        mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
+    ASSERT_EQ(err, C2_OK);
+    ASSERT_NO_FATAL_FAILURE(
+        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
+            (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
+    uint64_t frameIndex;
+    {
+        //Update mFlushedIndices based on the index received from flush()
+        ULock l(mQueueLock);
+        for (std::unique_ptr<C2Work>& work : flushedWork) {
+            ASSERT_NE(work, nullptr);
+            frameIndex = work->input.ordinal.frameIndex.peeku();
+            std::list<uint64_t>::iterator frameIndexIt = std::find(
+                mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex);
+            if (!mFlushedIndices.empty() &&
+                (frameIndexIt != mFlushedIndices.end())) {
+                mFlushedIndices.erase(frameIndexIt);
+                work->input.buffers.clear();
+                work->worklets.clear();
+                mWorkQueue.push_back(std::move(work));
+            }
+        }
+    }
+    mFlushedIndices.clear();
+    ASSERT_NO_FATAL_FAILURE(
+        encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                      mFlushedIndices, mGraphicPool, eleStream, mDisableTest,
+                      numFramesFlushed, numFrames - numFramesFlushed,
+                      nWidth, nHeight, true));
+    eleStream.close();
+    // mDisableTest will be set if buffer was not fetched properly.
+    // This may happen when resolution is not proper but config suceeded
+    // In this cases, we skip encoding the input stream
+    if (mDisableTest) {
+        std::cout << "[   WARN   ] Test Disabled \n";
+        ASSERT_EQ(mComponent->stop(), C2_OK);
+        return;
+    }
+
+    err = mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
+    ASSERT_EQ(err, C2_OK);
+    ASSERT_NO_FATAL_FAILURE(
+        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
+            (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
+    {
+        //Update mFlushedIndices based on the index received from flush()
+        ULock l(mQueueLock);
+        for (std::unique_ptr<C2Work>& work : flushedWork) {
+            ASSERT_NE(work, nullptr);
+            frameIndex = work->input.ordinal.frameIndex.peeku();
+            std::list<uint64_t>::iterator frameIndexIt = std::find(
+                mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex);
+            if (!mFlushedIndices.empty() &&
+                (frameIndexIt != mFlushedIndices.end())) {
+                mFlushedIndices.erase(frameIndexIt);
+                work->input.buffers.clear();
+                work->worklets.clear();
+                mWorkQueue.push_back(std::move(work));
+            }
+        }
+    }
+    ASSERT_EQ(mFlushedIndices.empty(), true);
+    ASSERT_EQ(mComponent->stop(), C2_OK);
+}
+
+TEST_F(Codec2VideoEncHidlTest, InvalidBufferTest) {
+    description("Tests feeding larger/smaller input buffer");
+    if (mDisableTest) return;
+
+    std::ifstream eleStream;
+    int32_t nWidth = ENC_DEFAULT_FRAME_WIDTH / 2;
+    int32_t nHeight = ENC_DEFAULT_FRAME_HEIGHT / 2;
+
+    if (!setupConfigParam(nWidth, nHeight)) {
+        std::cout << "[   WARN   ] Test Skipped \n";
+        return;
+    }
+    ASSERT_EQ(mComponent->start(), C2_OK);
+
+    ASSERT_NO_FATAL_FAILURE(
+        encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                      mFlushedIndices, mGraphicPool, eleStream, mDisableTest,
+                      0, 1, nWidth, nHeight, false, false));
+
+    // Feed larger input buffer.
+    ASSERT_NO_FATAL_FAILURE(
+        encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                      mFlushedIndices, mGraphicPool, eleStream, mDisableTest,
+                      1, 1, nWidth*2, nHeight*2, false, false));
+
+    // Feed smaller input buffer.
+    ASSERT_NO_FATAL_FAILURE(
+        encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                      mFlushedIndices, mGraphicPool, eleStream, mDisableTest,
+                      2, 1, nWidth/2, nHeight/2, false, true));
+
+    // blocking call to ensures application to Wait till all the inputs are
+    // consumed
+    ALOGD("Waiting for input consumption");
+    ASSERT_NO_FATAL_FAILURE(
+        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+
+    if (mFramesReceived != 3) {
+        std::cout << "[   WARN   ] Component didn't receive all buffers back \n";
+        ALOGW("framesReceived : %d inputFrames : 3", mFramesReceived);
+    }
+
+    if (mFailedWorkReceived == 0) {
+        std::cout << "[   WARN   ] Expected failed frame count mismatch \n";
+        ALOGW("failedFramesReceived : %d", mFailedWorkReceived);
+    }
+
+    ASSERT_EQ(mComponent->stop(), C2_OK);
+}
+
+class Codec2VideoEncResolutionTest : public Codec2VideoEncHidlTest,
+        public ::testing::WithParamInterface<std::pair<int32_t, int32_t> > {
+};
+
+TEST_P(Codec2VideoEncResolutionTest, ResolutionTest) {
+    description("Tests encoding at different resolutions");
+    if (mDisableTest) return;
+
+    std::ifstream eleStream;
+    int32_t nWidth = GetParam().first;
+    int32_t nHeight = GetParam().second;
+    ALOGD("Trying encode for width %d height %d", nWidth, nHeight);
+    mEos = false;
+
+    if (!setupConfigParam(nWidth, nHeight)) {
+        std::cout << "[   WARN   ] Test Skipped \n";
+        return;
+    }
+    ASSERT_EQ(mComponent->start(), C2_OK);
+
+    ASSERT_NO_FATAL_FAILURE(
+        encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                      mFlushedIndices, mGraphicPool, eleStream, mDisableTest,
+                      0, MAX_INPUT_BUFFERS, nWidth, nHeight, false, true));
+
+    // mDisableTest will be set if buffer was not fetched properly.
+    // This may happen when resolution is not proper but config suceeded
+    // In this cases, we skip encoding the input stream
+    if (mDisableTest) {
+        std::cout << "[   WARN   ] Test Disabled \n";
+        ASSERT_EQ(mComponent->stop(), C2_OK);
+        return;
+    }
+
+    ALOGD("Waiting for input consumption");
+    ASSERT_NO_FATAL_FAILURE(
+        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+
+    ASSERT_EQ(mEos, true);
+    ASSERT_EQ(mComponent->stop(), C2_OK);
+    ASSERT_EQ(mComponent->reset(), C2_OK);
+}
+
+INSTANTIATE_TEST_CASE_P(NonStdSizes, Codec2VideoEncResolutionTest, ::testing::Values(
+    std::make_pair(52, 18),
+    std::make_pair(365, 365),
+    std::make_pair(484, 362),
+    std::make_pair(244, 488)));
+
+}  // anonymous namespace
+
+int main(int argc, char** argv) {
+    gEnv = new ComponentTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    gEnv->init(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        int status = RUN_ALL_TESTS();
+        LOG(INFO) << "C2 Test result = " << status;
+    }
+    return status;
+}
diff --git a/media/codec2/hidl/1.0/vts/functional/video/media_c2_video_hidl_test_common.h b/media/codec2/hidl/1.0/vts/functional/video/media_c2_video_hidl_test_common.h
new file mode 100644
index 0000000..e37ca38
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/video/media_c2_video_hidl_test_common.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MEDIA_C2_VIDEO_HIDL_TEST_COMMON_H
+#define MEDIA_C2_VIDEO_HIDL_TEST_COMMON_H
+
+#define ENCODER_TIMESTAMP_INCREMENT 40000
+#define ENC_NUM_FRAMES 32
+#define ENC_DEFAULT_FRAME_WIDTH 352
+#define ENC_DEFAULT_FRAME_HEIGHT 288
+#define MAX_ITERATIONS 128
+
+#define ALIGN(_sz, _align) ((_sz + (_align - 1)) & ~(_align - 1))
+
+/*
+ * Common video utils
+ */
+
+
+#endif  // MEDIA_C2_VIDEO_HIDL_TEST_COMMON_H
diff --git a/media/codec2/hidl/client/Android.bp b/media/codec2/hidl/client/Android.bp
new file mode 100644
index 0000000..6038a40
--- /dev/null
+++ b/media/codec2/hidl/client/Android.bp
@@ -0,0 +1,38 @@
+cc_library {
+    name: "libcodec2_client",
+
+    srcs: [
+        "client.cpp",
+    ],
+
+    shared_libs: [
+        "android.hardware.graphics.bufferqueue@1.0",
+        "android.hardware.media.bufferpool@2.0",
+        "android.hardware.media.c2@1.0",
+        "libbase",
+        "libbinder",
+        "libcodec2",
+        "libcodec2_hidl_client@1.0",
+        "libcodec2_vndk",
+        "libcutils",
+        "libgui",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libstagefright_bufferpool@2.0",
+        "libui",
+        "libutils",
+    ],
+
+    export_include_dirs: [
+        "include",
+    ],
+
+    export_shared_lib_headers: [
+        "libcodec2",
+        "libcodec2_hidl_client@1.0",
+        "libcodec2_vndk",
+    ],
+
+}
+
diff --git a/media/codec2/hidl/client/client.cpp b/media/codec2/hidl/client/client.cpp
new file mode 100644
index 0000000..5ed54f1
--- /dev/null
+++ b/media/codec2/hidl/client/client.cpp
@@ -0,0 +1,1422 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2Client"
+#include <android-base/logging.h>
+
+#include <codec2/hidl/client.h>
+
+#include <deque>
+#include <iterator>
+#include <limits>
+#include <map>
+#include <mutex>
+#include <sstream>
+#include <thread>
+#include <type_traits>
+#include <vector>
+
+#include <android-base/properties.h>
+#include <bufferpool/ClientManager.h>
+#include <cutils/native_handle.h>
+#include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h>
+#include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h>
+#include <hidl/HidlSupport.h>
+
+#include <android/hardware/media/bufferpool/2.0/IClientManager.h>
+#include <android/hardware/media/c2/1.0/IComponent.h>
+#include <android/hardware/media/c2/1.0/IComponentInterface.h>
+#include <android/hardware/media/c2/1.0/IComponentListener.h>
+#include <android/hardware/media/c2/1.0/IComponentStore.h>
+#include <android/hardware/media/c2/1.0/IConfigurable.h>
+#include <android/hidl/manager/1.2/IServiceManager.h>
+
+#include <C2Debug.h>
+#include <C2BufferPriv.h>
+#include <C2PlatformSupport.h>
+
+namespace android {
+
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+using namespace ::android::hardware::media::c2::V1_0;
+using namespace ::android::hardware::media::c2::V1_0::utils;
+using namespace ::android::hardware::media::bufferpool::V2_0;
+using namespace ::android::hardware::media::bufferpool::V2_0::implementation;
+
+using HGraphicBufferProducer1 = ::android::hardware::graphics::bufferqueue::
+        V1_0::IGraphicBufferProducer;
+using HGraphicBufferProducer2 = ::android::hardware::graphics::bufferqueue::
+        V2_0::IGraphicBufferProducer;
+using B2HGraphicBufferProducer2 = ::android::hardware::graphics::bufferqueue::
+        V2_0::utils::B2HGraphicBufferProducer;
+using H2BGraphicBufferProducer2 = ::android::hardware::graphics::bufferqueue::
+        V2_0::utils::H2BGraphicBufferProducer;
+
+namespace /* unnamed */ {
+
+// c2_status_t value that corresponds to hwbinder transaction failure.
+constexpr c2_status_t C2_TRANSACTION_FAILED = C2_CORRUPTED;
+
+// Searches for a name in GetServiceNames() and returns the index found. If the
+// name is not found, the returned index will be equal to
+// GetServiceNames().size().
+size_t getServiceIndex(char const* name) {
+    std::vector<std::string> const& names = Codec2Client::GetServiceNames();
+    size_t i = 0;
+    for (; i < names.size(); ++i) {
+        if (name == names[i]) {
+            break;
+        }
+    }
+    return i;
+}
+
+}  // unnamed namespace
+
+// This class caches a Codec2Client object and its component traits. The client
+// will be created the first time it is needed, and it can be refreshed if the
+// service dies (by calling invalidate()). The first time listComponents() is
+// called from the client, the result will be cached.
+class Codec2Client::Cache {
+    // Cached client
+    std::shared_ptr<Codec2Client> mClient;
+    mutable std::mutex mClientMutex;
+
+    // Cached component traits
+    std::vector<C2Component::Traits> mTraits;
+    std::once_flag mTraitsInitializationFlag;
+
+    // The index of the service. This is based on GetServiceNames().
+    size_t mIndex;
+    // Called by s() exactly once to initialize the cache. The index must be a
+    // valid index into the vector returned by GetServiceNames(). Calling
+    // init(index) will associate the cache to the service with name
+    // GetServiceNames()[index].
+    void init(size_t index) {
+        mIndex = index;
+    }
+
+public:
+    Cache() = default;
+
+    // Initializes mClient if needed, then returns mClient.
+    // If the service is unavailable but listed in the manifest, this function
+    // will block indefinitely.
+    std::shared_ptr<Codec2Client> getClient() {
+        std::scoped_lock lock{mClientMutex};
+        if (!mClient) {
+            mClient = Codec2Client::_CreateFromIndex(mIndex);
+        }
+        return mClient;
+    }
+
+    // Causes a subsequent call to getClient() to create a new client. This
+    // function should be called after the service dies.
+    //
+    // Note: This function is called only by ForAllServices().
+    void invalidate() {
+        std::scoped_lock lock{mClientMutex};
+        mClient = nullptr;
+    }
+
+    // Returns a list of traits for components supported by the service. This
+    // list is cached.
+    std::vector<C2Component::Traits> const& getTraits() {
+        std::call_once(mTraitsInitializationFlag, [this]() {
+            bool success{false};
+            // Spin until _listComponents() is successful.
+            while (true) {
+                std::shared_ptr<Codec2Client> client = getClient();
+                mTraits = client->_listComponents(&success);
+                if (success) {
+                    break;
+                }
+                using namespace std::chrono_literals;
+                static constexpr auto kServiceRetryPeriod = 5s;
+                LOG(INFO) << "Failed to retrieve component traits from service "
+                             "\"" << GetServiceNames()[mIndex] << "\". "
+                             "Retrying...";
+                std::this_thread::sleep_for(kServiceRetryPeriod);
+            }
+        });
+        return mTraits;
+    }
+
+    // List() returns the list of all caches.
+    static std::vector<Cache>& List() {
+        static std::vector<Cache> sCaches{[]() {
+            size_t numServices = GetServiceNames().size();
+            std::vector<Cache> caches(numServices);
+            for (size_t i = 0; i < numServices; ++i) {
+                caches[i].init(i);
+            }
+            return caches;
+        }()};
+        return sCaches;
+    }
+};
+
+// Codec2ConfigurableClient
+
+const C2String& Codec2ConfigurableClient::getName() const {
+    return mName;
+}
+
+Codec2ConfigurableClient::Codec2ConfigurableClient(
+        const sp<IConfigurable>& base)
+      : mBase{base},
+        mName{[base]() -> C2String {
+                C2String outName;
+                Return<void> transStatus = base->getName(
+                        [&outName](const hidl_string& name) {
+                            outName = name.c_str();
+                        });
+                return transStatus.isOk() ? outName : "";
+            }()} {
+}
+
+c2_status_t Codec2ConfigurableClient::query(
+        const std::vector<C2Param*> &stackParams,
+        const std::vector<C2Param::Index> &heapParamIndices,
+        c2_blocking_t mayBlock,
+        std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
+    hidl_vec<ParamIndex> indices(
+            stackParams.size() + heapParamIndices.size());
+    size_t numIndices = 0;
+    for (C2Param* const& stackParam : stackParams) {
+        if (!stackParam) {
+            LOG(WARNING) << "query -- null stack param encountered.";
+            continue;
+        }
+        indices[numIndices++] = static_cast<ParamIndex>(stackParam->index());
+    }
+    size_t numStackIndices = numIndices;
+    for (const C2Param::Index& index : heapParamIndices) {
+        indices[numIndices++] =
+                static_cast<ParamIndex>(static_cast<uint32_t>(index));
+    }
+    indices.resize(numIndices);
+    if (heapParams) {
+        heapParams->reserve(heapParams->size() + numIndices);
+    }
+    c2_status_t status;
+    Return<void> transStatus = mBase->query(
+            indices,
+            mayBlock == C2_MAY_BLOCK,
+            [&status, &numStackIndices, &stackParams, heapParams](
+                    Status s, const Params& p) {
+                status = static_cast<c2_status_t>(s);
+                if (status != C2_OK && status != C2_BAD_INDEX) {
+                    LOG(DEBUG) << "query -- call failed: "
+                               << status << ".";
+                    return;
+                }
+                std::vector<C2Param*> paramPointers;
+                if (!parseParamsBlob(&paramPointers, p)) {
+                    LOG(ERROR) << "query -- error while parsing params.";
+                    status = C2_CORRUPTED;
+                    return;
+                }
+                size_t i = 0;
+                for (auto it = paramPointers.begin();
+                        it != paramPointers.end(); ) {
+                    C2Param* paramPointer = *it;
+                    if (numStackIndices > 0) {
+                        --numStackIndices;
+                        if (!paramPointer) {
+                            LOG(WARNING) << "query -- null stack param.";
+                            ++it;
+                            continue;
+                        }
+                        for (; i < stackParams.size() && !stackParams[i]; ) {
+                            ++i;
+                        }
+                        if (i >= stackParams.size()) {
+                            LOG(ERROR) << "query -- unexpected error.";
+                            status = C2_CORRUPTED;
+                            return;
+                        }
+                        if (stackParams[i]->index() != paramPointer->index()) {
+                            LOG(WARNING) << "query -- param skipped: "
+                                            "index = "
+                                         << stackParams[i]->index() << ".";
+                            stackParams[i++]->invalidate();
+                            continue;
+                        }
+                        if (!stackParams[i++]->updateFrom(*paramPointer)) {
+                            LOG(WARNING) << "query -- param update failed: "
+                                            "index = "
+                                         << paramPointer->index() << ".";
+                        }
+                    } else {
+                        if (!paramPointer) {
+                            LOG(WARNING) << "query -- null heap param.";
+                            ++it;
+                            continue;
+                        }
+                        if (!heapParams) {
+                            LOG(WARNING) << "query -- "
+                                            "unexpected extra stack param.";
+                        } else {
+                            heapParams->emplace_back(
+                                    C2Param::Copy(*paramPointer));
+                        }
+                    }
+                    ++it;
+                }
+            });
+    if (!transStatus.isOk()) {
+        LOG(ERROR) << "query -- transaction failed.";
+        return C2_TRANSACTION_FAILED;
+    }
+    return status;
+}
+
+c2_status_t Codec2ConfigurableClient::config(
+        const std::vector<C2Param*> &params,
+        c2_blocking_t mayBlock,
+        std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
+    Params hidlParams;
+    if (!createParamsBlob(&hidlParams, params)) {
+        LOG(ERROR) << "config -- bad input.";
+        return C2_TRANSACTION_FAILED;
+    }
+    c2_status_t status;
+    Return<void> transStatus = mBase->config(
+            hidlParams,
+            mayBlock == C2_MAY_BLOCK,
+            [&status, &params, failures](
+                    Status s,
+                    const hidl_vec<SettingResult> f,
+                    const Params& o) {
+                status = static_cast<c2_status_t>(s);
+                if (status != C2_OK && status != C2_BAD_INDEX) {
+                    LOG(DEBUG) << "config -- call failed: "
+                               << status << ".";
+                }
+                size_t i = failures->size();
+                failures->resize(i + f.size());
+                for (const SettingResult& sf : f) {
+                    if (!objcpy(&(*failures)[i++], sf)) {
+                        LOG(ERROR) << "config -- "
+                                   << "invalid SettingResult returned.";
+                        return;
+                    }
+                }
+                if (!updateParamsFromBlob(params, o)) {
+                    LOG(ERROR) << "config -- "
+                               << "failed to parse returned params.";
+                    status = C2_CORRUPTED;
+                }
+            });
+    if (!transStatus.isOk()) {
+        LOG(ERROR) << "config -- transaction failed.";
+        return C2_TRANSACTION_FAILED;
+    }
+    return status;
+}
+
+c2_status_t Codec2ConfigurableClient::querySupportedParams(
+        std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const {
+    // TODO: Cache and query properly!
+    c2_status_t status;
+    Return<void> transStatus = mBase->querySupportedParams(
+            std::numeric_limits<uint32_t>::min(),
+            std::numeric_limits<uint32_t>::max(),
+            [&status, params](
+                    Status s,
+                    const hidl_vec<ParamDescriptor>& p) {
+                status = static_cast<c2_status_t>(s);
+                if (status != C2_OK) {
+                    LOG(DEBUG) << "querySupportedParams -- call failed: "
+                               << status << ".";
+                    return;
+                }
+                size_t i = params->size();
+                params->resize(i + p.size());
+                for (const ParamDescriptor& sp : p) {
+                    if (!objcpy(&(*params)[i++], sp)) {
+                        LOG(ERROR) << "querySupportedParams -- "
+                                   << "invalid returned ParamDescriptor.";
+                        return;
+                    }
+                }
+            });
+    if (!transStatus.isOk()) {
+        LOG(ERROR) << "querySupportedParams -- transaction failed.";
+        return C2_TRANSACTION_FAILED;
+    }
+    return status;
+}
+
+c2_status_t Codec2ConfigurableClient::querySupportedValues(
+        std::vector<C2FieldSupportedValuesQuery>& fields,
+        c2_blocking_t mayBlock) const {
+    hidl_vec<FieldSupportedValuesQuery> inFields(fields.size());
+    for (size_t i = 0; i < fields.size(); ++i) {
+        if (!objcpy(&inFields[i], fields[i])) {
+            LOG(ERROR) << "querySupportedValues -- bad input";
+            return C2_TRANSACTION_FAILED;
+        }
+    }
+
+    c2_status_t status;
+    Return<void> transStatus = mBase->querySupportedValues(
+            inFields,
+            mayBlock == C2_MAY_BLOCK,
+            [&status, &inFields, &fields](
+                    Status s,
+                    const hidl_vec<FieldSupportedValuesQueryResult>& r) {
+                status = static_cast<c2_status_t>(s);
+                if (status != C2_OK) {
+                    LOG(DEBUG) << "querySupportedValues -- call failed: "
+                               << status << ".";
+                    return;
+                }
+                if (r.size() != fields.size()) {
+                    LOG(ERROR) << "querySupportedValues -- "
+                                  "input and output lists "
+                                  "have different sizes.";
+                    status = C2_CORRUPTED;
+                    return;
+                }
+                for (size_t i = 0; i < fields.size(); ++i) {
+                    if (!objcpy(&fields[i], inFields[i], r[i])) {
+                        LOG(ERROR) << "querySupportedValues -- "
+                                      "invalid returned value.";
+                        status = C2_CORRUPTED;
+                        return;
+                    }
+                }
+            });
+    if (!transStatus.isOk()) {
+        LOG(ERROR) << "querySupportedValues -- transaction failed.";
+        return C2_TRANSACTION_FAILED;
+    }
+    return status;
+}
+
+// Codec2Client::Component::HidlListener
+struct Codec2Client::Component::HidlListener : public IComponentListener {
+    std::weak_ptr<Component> component;
+    std::weak_ptr<Listener> base;
+
+    virtual Return<void> onWorkDone(const WorkBundle& workBundle) override {
+        std::list<std::unique_ptr<C2Work>> workItems;
+        if (!objcpy(&workItems, workBundle)) {
+            LOG(DEBUG) << "onWorkDone -- received corrupted WorkBundle.";
+            return Void();
+        }
+        // release input buffers potentially held by the component from queue
+        std::shared_ptr<Codec2Client::Component> strongComponent =
+                component.lock();
+        if (strongComponent) {
+            strongComponent->handleOnWorkDone(workItems);
+        }
+        if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) {
+            listener->onWorkDone(component, workItems);
+        } else {
+            LOG(DEBUG) << "onWorkDone -- listener died.";
+        }
+        return Void();
+    }
+
+    virtual Return<void> onTripped(
+            const hidl_vec<SettingResult>& settingResults) override {
+        std::vector<std::shared_ptr<C2SettingResult>> c2SettingResults(
+                settingResults.size());
+        for (size_t i = 0; i < settingResults.size(); ++i) {
+            std::unique_ptr<C2SettingResult> c2SettingResult;
+            if (!objcpy(&c2SettingResult, settingResults[i])) {
+                LOG(DEBUG) << "onTripped -- received corrupted SettingResult.";
+                return Void();
+            }
+            c2SettingResults[i] = std::move(c2SettingResult);
+        }
+        if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) {
+            listener->onTripped(component, c2SettingResults);
+        } else {
+            LOG(DEBUG) << "onTripped -- listener died.";
+        }
+        return Void();
+    }
+
+    virtual Return<void> onError(Status s, uint32_t errorCode) override {
+        LOG(DEBUG) << "onError --"
+                   << " status = " << s
+                   << ", errorCode = " << errorCode
+                   << ".";
+        if (std::shared_ptr<Listener> listener = base.lock()) {
+            listener->onError(component, s == Status::OK ?
+                    errorCode : static_cast<c2_status_t>(s));
+        } else {
+            LOG(DEBUG) << "onError -- listener died.";
+        }
+        return Void();
+    }
+
+    virtual Return<void> onFramesRendered(
+            const hidl_vec<RenderedFrame>& renderedFrames) override {
+        std::shared_ptr<Listener> listener = base.lock();
+        if (!listener) {
+            LOG(DEBUG) << "onFramesRendered -- listener died.";
+            return Void();
+        }
+        for (const RenderedFrame& renderedFrame : renderedFrames) {
+            listener->onFrameRendered(
+                    renderedFrame.bufferQueueId,
+                    renderedFrame.slotId,
+                    renderedFrame.timestampNs);
+        }
+        return Void();
+    }
+
+    virtual Return<void> onInputBuffersReleased(
+            const hidl_vec<InputBuffer>& inputBuffers) override {
+        std::shared_ptr<Listener> listener = base.lock();
+        if (!listener) {
+            LOG(DEBUG) << "onInputBuffersReleased -- listener died.";
+            return Void();
+        }
+        for (const InputBuffer& inputBuffer : inputBuffers) {
+            LOG(VERBOSE) << "onInputBuffersReleased --"
+                            " received death notification of"
+                            " input buffer:"
+                            " frameIndex = " << inputBuffer.frameIndex
+                         << ", bufferIndex = " << inputBuffer.arrayIndex
+                         << ".";
+            listener->onInputBufferDone(
+                    inputBuffer.frameIndex, inputBuffer.arrayIndex);
+        }
+        return Void();
+    }
+
+};
+
+// Codec2Client
+Codec2Client::Codec2Client(const sp<IComponentStore>& base,
+                           size_t serviceIndex)
+      : Configurable{
+            [base]() -> sp<IConfigurable> {
+                Return<sp<IConfigurable>> transResult =
+                        base->getConfigurable();
+                return transResult.isOk() ?
+                        static_cast<sp<IConfigurable>>(transResult) :
+                        nullptr;
+            }()
+        },
+        mBase{base},
+        mServiceIndex{serviceIndex} {
+    Return<sp<IClientManager>> transResult = base->getPoolClientManager();
+    if (!transResult.isOk()) {
+        LOG(ERROR) << "getPoolClientManager -- transaction failed.";
+    } else {
+        mHostPoolManager = static_cast<sp<IClientManager>>(transResult);
+    }
+}
+
+sp<Codec2Client::Base> const& Codec2Client::getBase() const {
+    return mBase;
+}
+
+std::string const& Codec2Client::getServiceName() const {
+    return GetServiceNames()[mServiceIndex];
+}
+
+c2_status_t Codec2Client::createComponent(
+        const C2String& name,
+        const std::shared_ptr<Codec2Client::Listener>& listener,
+        std::shared_ptr<Codec2Client::Component>* const component) {
+
+    c2_status_t status;
+    sp<Component::HidlListener> hidlListener = new Component::HidlListener{};
+    hidlListener->base = listener;
+    Return<void> transStatus = mBase->createComponent(
+            name,
+            hidlListener,
+            ClientManager::getInstance(),
+            [&status, component, hidlListener](
+                    Status s,
+                    const sp<IComponent>& c) {
+                status = static_cast<c2_status_t>(s);
+                if (status != C2_OK) {
+                    return;
+                }
+                *component = std::make_shared<Codec2Client::Component>(c);
+                hidlListener->component = *component;
+            });
+    if (!transStatus.isOk()) {
+        LOG(ERROR) << "createComponent(" << name.c_str()
+                   << ") -- transaction failed.";
+        return C2_TRANSACTION_FAILED;
+    } else if (status != C2_OK) {
+        LOG(ERROR) << "createComponent(" << name.c_str()
+                   << ") -- call failed: " << status << ".";
+        return status;
+    } else if (!*component) {
+        LOG(ERROR) << "createComponent(" << name.c_str()
+                   << ") -- null component.";
+        return C2_CORRUPTED;
+    }
+
+    status = (*component)->setDeathListener(*component, listener);
+    if (status != C2_OK) {
+        LOG(ERROR) << "createComponent(" << name.c_str()
+                   << ") -- failed to set up death listener: "
+                   << status << ".";
+    }
+
+    (*component)->mBufferPoolSender.setReceiver(mHostPoolManager);
+    return status;
+}
+
+c2_status_t Codec2Client::createInterface(
+        const C2String& name,
+        std::shared_ptr<Codec2Client::Interface>* const interface) {
+    c2_status_t status;
+    Return<void> transStatus = mBase->createInterface(
+            name,
+            [&status, interface](
+                    Status s,
+                    const sp<IComponentInterface>& i) {
+                status = static_cast<c2_status_t>(s);
+                if (status != C2_OK) {
+                    return;
+                }
+                *interface = std::make_shared<Interface>(i);
+            });
+    if (!transStatus.isOk()) {
+        LOG(ERROR) << "createInterface(" << name.c_str()
+                   << ") -- transaction failed.";
+        return C2_TRANSACTION_FAILED;
+    } else if (status != C2_OK) {
+        LOG(ERROR) << "createComponent(" << name.c_str()
+                   << ") -- call failed: " << status << ".";
+        return status;
+    }
+
+    return status;
+}
+
+c2_status_t Codec2Client::createInputSurface(
+        std::shared_ptr<InputSurface>* const inputSurface) {
+    c2_status_t status;
+    Return<void> transStatus = mBase->createInputSurface(
+            [&status, inputSurface](
+                    Status s,
+                    const sp<IInputSurface>& i) {
+                status = static_cast<c2_status_t>(s);
+                if (status != C2_OK) {
+                    return;
+                }
+                *inputSurface = std::make_shared<InputSurface>(i);
+            });
+    if (!transStatus.isOk()) {
+        LOG(ERROR) << "createInputSurface -- transaction failed.";
+        return C2_TRANSACTION_FAILED;
+    } else if (status != C2_OK) {
+        LOG(DEBUG) << "createInputSurface -- call failed: "
+                   << status << ".";
+    }
+    return status;
+}
+
+std::vector<C2Component::Traits> const& Codec2Client::listComponents() const {
+    return Cache::List()[mServiceIndex].getTraits();
+}
+
+std::vector<C2Component::Traits> Codec2Client::_listComponents(
+        bool* success) const {
+    std::vector<C2Component::Traits> traits;
+    std::string const& serviceName = getServiceName();
+    Return<void> transStatus = mBase->listComponents(
+            [&traits, &serviceName](Status s,
+                   const hidl_vec<IComponentStore::ComponentTraits>& t) {
+                if (s != Status::OK) {
+                    LOG(DEBUG) << "_listComponents -- call failed: "
+                               << static_cast<c2_status_t>(s) << ".";
+                    return;
+                }
+                traits.resize(t.size());
+                for (size_t i = 0; i < t.size(); ++i) {
+                    if (!objcpy(&traits[i], t[i])) {
+                        LOG(ERROR) << "_listComponents -- corrupted output.";
+                        return;
+                    }
+                    traits[i].owner = serviceName;
+                }
+            });
+    if (!transStatus.isOk()) {
+        LOG(ERROR) << "_listComponents -- transaction failed.";
+        *success = false;
+    } else {
+        *success = true;
+    }
+    return traits;
+}
+
+c2_status_t Codec2Client::copyBuffer(
+        const std::shared_ptr<C2Buffer>& src,
+        const std::shared_ptr<C2Buffer>& dst) {
+    // TODO: Implement?
+    (void)src;
+    (void)dst;
+    LOG(ERROR) << "copyBuffer not implemented";
+    return C2_OMITTED;
+}
+
+std::shared_ptr<C2ParamReflector>
+        Codec2Client::getParamReflector() {
+    // TODO: this is not meant to be exposed as C2ParamReflector on the client side; instead, it
+    // should reflect the HAL API.
+    struct SimpleParamReflector : public C2ParamReflector {
+        virtual std::unique_ptr<C2StructDescriptor> describe(C2Param::CoreIndex coreIndex) const {
+            hidl_vec<ParamIndex> indices(1);
+            indices[0] = static_cast<ParamIndex>(coreIndex.coreIndex());
+            std::unique_ptr<C2StructDescriptor> descriptor;
+            Return<void> transStatus = mBase->getStructDescriptors(
+                    indices,
+                    [&descriptor](
+                            Status s,
+                            const hidl_vec<StructDescriptor>& sd) {
+                        c2_status_t status = static_cast<c2_status_t>(s);
+                        if (status != C2_OK) {
+                            LOG(DEBUG) << "SimpleParamReflector -- "
+                                          "getStructDescriptors() failed: "
+                                       << status << ".";
+                            descriptor.reset();
+                            return;
+                        }
+                        if (sd.size() != 1) {
+                            LOG(DEBUG) << "SimpleParamReflector -- "
+                                          "getStructDescriptors() "
+                                          "returned vector of size "
+                                       << sd.size() << ". "
+                                          "It should be 1.";
+                            descriptor.reset();
+                            return;
+                        }
+                        if (!objcpy(&descriptor, sd[0])) {
+                            LOG(DEBUG) << "SimpleParamReflector -- "
+                                          "getStructDescriptors() returned "
+                                          "corrupted data.";
+                            descriptor.reset();
+                            return;
+                        }
+                    });
+            return descriptor;
+        }
+
+        SimpleParamReflector(sp<Base> base)
+            : mBase(base) { }
+
+        sp<Base> mBase;
+    };
+
+    return std::make_shared<SimpleParamReflector>(mBase);
+};
+
+std::vector<std::string> const& Codec2Client::GetServiceNames() {
+    static std::vector<std::string> sServiceNames{[]() {
+        using ::android::hardware::media::c2::V1_0::IComponentStore;
+        using ::android::hidl::manager::V1_2::IServiceManager;
+
+        while (true) {
+            sp<IServiceManager> serviceManager = IServiceManager::getService();
+            CHECK(serviceManager) << "Hardware service manager is not running.";
+
+            // There are three categories of services based on names.
+            std::vector<std::string> defaultNames; // Prefixed with "default"
+            std::vector<std::string> vendorNames;  // Prefixed with "vendor"
+            std::vector<std::string> otherNames;   // Others
+            Return<void> transResult;
+            transResult = serviceManager->listManifestByInterface(
+                    IComponentStore::descriptor,
+                    [&defaultNames, &vendorNames, &otherNames](
+                            hidl_vec<hidl_string> const& instanceNames) {
+                        for (hidl_string const& instanceName : instanceNames) {
+                            char const* name = instanceName.c_str();
+                            if (strncmp(name, "default", 7) == 0) {
+                                defaultNames.emplace_back(name);
+                            } else if (strncmp(name, "vendor", 6) == 0) {
+                                vendorNames.emplace_back(name);
+                            } else {
+                                otherNames.emplace_back(name);
+                            }
+                        }
+                    });
+            if (transResult.isOk()) {
+                // Sort service names in each category.
+                std::sort(defaultNames.begin(), defaultNames.end());
+                std::sort(vendorNames.begin(), vendorNames.end());
+                std::sort(otherNames.begin(), otherNames.end());
+
+                // Concatenate the three lists in this order: default, vendor,
+                // other.
+                std::vector<std::string>& names = defaultNames;
+                names.reserve(names.size() + vendorNames.size() + otherNames.size());
+                names.insert(names.end(),
+                             std::make_move_iterator(vendorNames.begin()),
+                             std::make_move_iterator(vendorNames.end()));
+                names.insert(names.end(),
+                             std::make_move_iterator(otherNames.begin()),
+                             std::make_move_iterator(otherNames.end()));
+
+                // Summarize to logcat.
+                if (names.empty()) {
+                    LOG(INFO) << "No Codec2 services declared in the manifest.";
+                } else {
+                    std::stringstream stringOutput;
+                    stringOutput << "Available Codec2 services:";
+                    for (std::string const& name : names) {
+                        stringOutput << " \"" << name << "\"";
+                    }
+                    LOG(INFO) << stringOutput.str();
+                }
+
+                return names;
+            }
+            LOG(ERROR) << "Could not retrieve the list of service instances of "
+                       << IComponentStore::descriptor
+                       << ". Retrying...";
+        }
+    }()};
+    return sServiceNames;
+}
+
+std::shared_ptr<Codec2Client> Codec2Client::CreateFromService(
+        const char* name) {
+    size_t index = getServiceIndex(name);
+    return index == GetServiceNames().size() ?
+            nullptr : _CreateFromIndex(index);
+}
+
+std::vector<std::shared_ptr<Codec2Client>> Codec2Client::
+        CreateFromAllServices() {
+    std::vector<std::shared_ptr<Codec2Client>> clients(
+            GetServiceNames().size());
+    for (size_t i = GetServiceNames().size(); i > 0; ) {
+        --i;
+        clients[i] = _CreateFromIndex(i);
+    }
+    return clients;
+}
+
+std::shared_ptr<Codec2Client> Codec2Client::_CreateFromIndex(size_t index) {
+    std::string const& name = GetServiceNames()[index];
+    LOG(INFO) << "Creating a Codec2 client to service \"" << name << "\"";
+    sp<Base> baseStore = Base::getService(name);
+    CHECK(baseStore) << "Codec2 service \"" << name << "\""
+                        " inaccessible for unknown reasons.";
+    LOG(INFO) << "Client to Codec2 service \"" << name << "\" created";
+    return std::make_shared<Codec2Client>(baseStore, index);
+}
+
+c2_status_t Codec2Client::ForAllServices(
+        const std::string &key,
+        std::function<c2_status_t(const std::shared_ptr<Codec2Client>&)>
+            predicate) {
+    c2_status_t status = C2_NO_INIT;  // no IComponentStores present
+
+    // Cache the mapping key -> index of Codec2Client in Cache::List().
+    static std::mutex key2IndexMutex;
+    static std::map<std::string, size_t> key2Index;
+
+    // By default try all stores. However, try the last known client first. If
+    // the last known client fails, retry once. We do this by pushing the last
+    // known client in front of the list of all clients.
+    std::deque<size_t> indices;
+    for (size_t index = Cache::List().size(); index > 0; ) {
+        indices.push_front(--index);
+    }
+
+    bool wasMapped = false;
+    {
+        std::scoped_lock lock{key2IndexMutex};
+        auto it = key2Index.find(key);
+        if (it != key2Index.end()) {
+            indices.push_front(it->second);
+            wasMapped = true;
+        }
+    }
+
+    for (size_t index : indices) {
+        Cache& cache = Cache::List()[index];
+        std::shared_ptr<Codec2Client> client{cache.getClient()};
+        if (client) {
+            status = predicate(client);
+            if (status == C2_OK) {
+                std::scoped_lock lock{key2IndexMutex};
+                key2Index[key] = index; // update last known client index
+                return C2_OK;
+            }
+        }
+        if (wasMapped) {
+            LOG(INFO) << "Could not find \"" << key << "\""
+                         " in the last instance. Retrying...";
+            wasMapped = false;
+            cache.invalidate();
+        }
+    }
+    return status;  // return the last status from a valid client
+}
+
+std::shared_ptr<Codec2Client::Component>
+        Codec2Client::CreateComponentByName(
+        const char* componentName,
+        const std::shared_ptr<Listener>& listener,
+        std::shared_ptr<Codec2Client>* owner) {
+    std::shared_ptr<Component> component;
+    c2_status_t status = ForAllServices(
+            componentName,
+            [owner, &component, componentName, &listener](
+                    const std::shared_ptr<Codec2Client> &client)
+                        -> c2_status_t {
+                c2_status_t status = client->createComponent(componentName,
+                                                             listener,
+                                                             &component);
+                if (status == C2_OK) {
+                    if (owner) {
+                        *owner = client;
+                    }
+                } else if (status != C2_NOT_FOUND) {
+                    LOG(DEBUG) << "IComponentStore("
+                                   << client->getServiceName()
+                               << ")::createComponent(\"" << componentName
+                               << "\") returned status = "
+                               << status << ".";
+                }
+                return status;
+            });
+    if (status != C2_OK) {
+        LOG(DEBUG) << "Could not create component \"" << componentName << "\". "
+                      "Status = " << status << ".";
+    }
+    return component;
+}
+
+std::shared_ptr<Codec2Client::Interface>
+        Codec2Client::CreateInterfaceByName(
+        const char* interfaceName,
+        std::shared_ptr<Codec2Client>* owner) {
+    std::shared_ptr<Interface> interface;
+    c2_status_t status = ForAllServices(
+            interfaceName,
+            [owner, &interface, interfaceName](
+                    const std::shared_ptr<Codec2Client> &client)
+                        -> c2_status_t {
+                c2_status_t status = client->createInterface(interfaceName,
+                                                             &interface);
+                if (status == C2_OK) {
+                    if (owner) {
+                        *owner = client;
+                    }
+                } else if (status != C2_NOT_FOUND) {
+                    LOG(DEBUG) << "IComponentStore("
+                                   << client->getServiceName()
+                               << ")::createInterface(\"" << interfaceName
+                               << "\") returned status = "
+                               << status << ".";
+                }
+                return status;
+            });
+    if (status != C2_OK) {
+        LOG(DEBUG) << "Could not create interface \"" << interfaceName << "\". "
+                      "Status = " << status << ".";
+    }
+    return interface;
+}
+
+std::vector<C2Component::Traits> const& Codec2Client::ListComponents() {
+    static std::vector<C2Component::Traits> sList{[]() {
+        std::vector<C2Component::Traits> list;
+        for (Cache& cache : Cache::List()) {
+            std::vector<C2Component::Traits> const& traits = cache.getTraits();
+            list.insert(list.end(), traits.begin(), traits.end());
+        }
+        return list;
+    }()};
+    return sList;
+}
+
+std::shared_ptr<Codec2Client::InputSurface> Codec2Client::CreateInputSurface(
+        char const* serviceName) {
+    int32_t inputSurfaceSetting = ::android::base::GetIntProperty(
+            "debug.stagefright.c2inputsurface", int32_t(0));
+    if (inputSurfaceSetting <= 0) {
+        return nullptr;
+    }
+    size_t index = GetServiceNames().size();
+    if (serviceName) {
+        index = getServiceIndex(serviceName);
+        if (index == GetServiceNames().size()) {
+            LOG(DEBUG) << "CreateInputSurface -- invalid service name: \""
+                       << serviceName << "\"";
+        }
+    }
+
+    std::shared_ptr<Codec2Client::InputSurface> inputSurface;
+    if (index != GetServiceNames().size()) {
+        std::shared_ptr<Codec2Client> client = Cache::List()[index].getClient();
+        if (client->createInputSurface(&inputSurface) == C2_OK) {
+            return inputSurface;
+        }
+    }
+    LOG(INFO) << "CreateInputSurface -- attempting to create an input surface "
+                 "from all services...";
+    for (Cache& cache : Cache::List()) {
+        std::shared_ptr<Codec2Client> client = cache.getClient();
+        if (client->createInputSurface(&inputSurface) == C2_OK) {
+            LOG(INFO) << "CreateInputSurface -- input surface obtained from "
+                         "service \"" << client->getServiceName() << "\"";
+            return inputSurface;
+        }
+    }
+    LOG(WARNING) << "CreateInputSurface -- failed to create an input surface "
+                    "from all services";
+    return nullptr;
+}
+
+// Codec2Client::Listener
+
+Codec2Client::Listener::~Listener() {
+}
+
+// Codec2Client::Interface
+Codec2Client::Interface::Interface(const sp<Base>& base)
+      : Configurable{
+            [base]() -> sp<IConfigurable> {
+                Return<sp<IConfigurable>> transResult =
+                        base->getConfigurable();
+                return transResult.isOk() ?
+                        static_cast<sp<IConfigurable>>(transResult) :
+                        nullptr;
+            }()
+        },
+        mBase{base} {
+}
+
+// Codec2Client::Component
+Codec2Client::Component::Component(const sp<Base>& base)
+      : Configurable{
+            [base]() -> sp<IConfigurable> {
+                Return<sp<IComponentInterface>> transResult1 =
+                        base->getInterface();
+                if (!transResult1.isOk()) {
+                    return nullptr;
+                }
+                Return<sp<IConfigurable>> transResult2 =
+                        static_cast<sp<IComponentInterface>>(transResult1)->
+                        getConfigurable();
+                return transResult2.isOk() ?
+                        static_cast<sp<IConfigurable>>(transResult2) :
+                        nullptr;
+            }()
+        },
+        mBase{base},
+        mBufferPoolSender{nullptr} {
+}
+
+Codec2Client::Component::~Component() {
+}
+
+c2_status_t Codec2Client::Component::createBlockPool(
+        C2Allocator::id_t id,
+        C2BlockPool::local_id_t* blockPoolId,
+        std::shared_ptr<Codec2Client::Configurable>* configurable) {
+    c2_status_t status;
+    Return<void> transStatus = mBase->createBlockPool(
+            static_cast<uint32_t>(id),
+            [&status, blockPoolId, configurable](
+                    Status s,
+                    uint64_t pId,
+                    const sp<IConfigurable>& c) {
+                status = static_cast<c2_status_t>(s);
+                configurable->reset();
+                if (status != C2_OK) {
+                    LOG(DEBUG) << "createBlockPool -- call failed: "
+                               << status << ".";
+                    return;
+                }
+                *blockPoolId = static_cast<C2BlockPool::local_id_t>(pId);
+                *configurable = std::make_shared<Configurable>(c);
+            });
+    if (!transStatus.isOk()) {
+        LOG(ERROR) << "createBlockPool -- transaction failed.";
+        return C2_TRANSACTION_FAILED;
+    }
+    return status;
+}
+
+c2_status_t Codec2Client::Component::destroyBlockPool(
+        C2BlockPool::local_id_t localId) {
+    Return<Status> transResult = mBase->destroyBlockPool(
+            static_cast<uint64_t>(localId));
+    if (!transResult.isOk()) {
+        LOG(ERROR) << "destroyBlockPool -- transaction failed.";
+        return C2_TRANSACTION_FAILED;
+    }
+    return static_cast<c2_status_t>(static_cast<Status>(transResult));
+}
+
+void Codec2Client::Component::handleOnWorkDone(
+        const std::list<std::unique_ptr<C2Work>> &workItems) {
+    // Output bufferqueue-based blocks' lifetime management
+    mOutputBufferQueue.holdBufferQueueBlocks(workItems);
+}
+
+c2_status_t Codec2Client::Component::queue(
+        std::list<std::unique_ptr<C2Work>>* const items) {
+    WorkBundle workBundle;
+    if (!objcpy(&workBundle, *items, &mBufferPoolSender)) {
+        LOG(ERROR) << "queue -- bad input.";
+        return C2_TRANSACTION_FAILED;
+    }
+    Return<Status> transStatus = mBase->queue(workBundle);
+    if (!transStatus.isOk()) {
+        LOG(ERROR) << "queue -- transaction failed.";
+        return C2_TRANSACTION_FAILED;
+    }
+    c2_status_t status =
+            static_cast<c2_status_t>(static_cast<Status>(transStatus));
+    if (status != C2_OK) {
+        LOG(DEBUG) << "queue -- call failed: " << status << ".";
+    }
+    return status;
+}
+
+c2_status_t Codec2Client::Component::flush(
+        C2Component::flush_mode_t mode,
+        std::list<std::unique_ptr<C2Work>>* const flushedWork) {
+    (void)mode; // Flush mode isn't supported in HIDL yet.
+    c2_status_t status;
+    Return<void> transStatus = mBase->flush(
+            [&status, flushedWork](
+                    Status s, const WorkBundle& wb) {
+                status = static_cast<c2_status_t>(s);
+                if (status != C2_OK) {
+                    LOG(DEBUG) << "flush -- call failed: " << status << ".";
+                    return;
+                }
+                if (!objcpy(flushedWork, wb)) {
+                    status = C2_CORRUPTED;
+                } else {
+                    status = C2_OK;
+                }
+            });
+    if (!transStatus.isOk()) {
+        LOG(ERROR) << "flush -- transaction failed.";
+        return C2_TRANSACTION_FAILED;
+    }
+
+    // Indices of flushed work items.
+    std::vector<uint64_t> flushedIndices;
+    for (const std::unique_ptr<C2Work> &work : *flushedWork) {
+        if (work) {
+            if (work->worklets.empty()
+                    || !work->worklets.back()
+                    || (work->worklets.back()->output.flags &
+                        C2FrameData::FLAG_INCOMPLETE) == 0) {
+                // input is complete
+                flushedIndices.emplace_back(
+                        work->input.ordinal.frameIndex.peeku());
+            }
+        }
+    }
+
+    // Output bufferqueue-based blocks' lifetime management
+    mOutputBufferQueue.holdBufferQueueBlocks(*flushedWork);
+
+    return status;
+}
+
+c2_status_t Codec2Client::Component::drain(C2Component::drain_mode_t mode) {
+    Return<Status> transStatus = mBase->drain(
+            mode == C2Component::DRAIN_COMPONENT_WITH_EOS);
+    if (!transStatus.isOk()) {
+        LOG(ERROR) << "drain -- transaction failed.";
+        return C2_TRANSACTION_FAILED;
+    }
+    c2_status_t status =
+            static_cast<c2_status_t>(static_cast<Status>(transStatus));
+    if (status != C2_OK) {
+        LOG(DEBUG) << "drain -- call failed: " << status << ".";
+    }
+    return status;
+}
+
+c2_status_t Codec2Client::Component::start() {
+    Return<Status> transStatus = mBase->start();
+    if (!transStatus.isOk()) {
+        LOG(ERROR) << "start -- transaction failed.";
+        return C2_TRANSACTION_FAILED;
+    }
+    c2_status_t status =
+            static_cast<c2_status_t>(static_cast<Status>(transStatus));
+    if (status != C2_OK) {
+        LOG(DEBUG) << "start -- call failed: " << status << ".";
+    }
+    return status;
+}
+
+c2_status_t Codec2Client::Component::stop() {
+    Return<Status> transStatus = mBase->stop();
+    if (!transStatus.isOk()) {
+        LOG(ERROR) << "stop -- transaction failed.";
+        return C2_TRANSACTION_FAILED;
+    }
+    c2_status_t status =
+            static_cast<c2_status_t>(static_cast<Status>(transStatus));
+    if (status != C2_OK) {
+        LOG(DEBUG) << "stop -- call failed: " << status << ".";
+    }
+    return status;
+}
+
+c2_status_t Codec2Client::Component::reset() {
+    Return<Status> transStatus = mBase->reset();
+    if (!transStatus.isOk()) {
+        LOG(ERROR) << "reset -- transaction failed.";
+        return C2_TRANSACTION_FAILED;
+    }
+    c2_status_t status =
+            static_cast<c2_status_t>(static_cast<Status>(transStatus));
+    if (status != C2_OK) {
+        LOG(DEBUG) << "reset -- call failed: " << status << ".";
+    }
+    return status;
+}
+
+c2_status_t Codec2Client::Component::release() {
+    Return<Status> transStatus = mBase->release();
+    if (!transStatus.isOk()) {
+        LOG(ERROR) << "release -- transaction failed.";
+        return C2_TRANSACTION_FAILED;
+    }
+    c2_status_t status =
+            static_cast<c2_status_t>(static_cast<Status>(transStatus));
+    if (status != C2_OK) {
+        LOG(DEBUG) << "release -- call failed: " << status << ".";
+    }
+    return status;
+}
+
+c2_status_t Codec2Client::Component::setOutputSurface(
+        C2BlockPool::local_id_t blockPoolId,
+        const sp<IGraphicBufferProducer>& surface,
+        uint32_t generation) {
+    uint64_t bqId = 0;
+    sp<IGraphicBufferProducer> nullIgbp;
+    sp<HGraphicBufferProducer2> nullHgbp;
+
+    sp<HGraphicBufferProducer2> igbp = surface ?
+            surface->getHalInterface<HGraphicBufferProducer2>() : nullHgbp;
+    if (surface && !igbp) {
+        igbp = new B2HGraphicBufferProducer2(surface);
+    }
+
+    if (!surface) {
+        mOutputBufferQueue.configure(nullIgbp, generation, 0);
+    } else if (surface->getUniqueId(&bqId) != OK) {
+        LOG(ERROR) << "setOutputSurface -- "
+                   "cannot obtain bufferqueue id.";
+        bqId = 0;
+        mOutputBufferQueue.configure(nullIgbp, generation, 0);
+    } else {
+        mOutputBufferQueue.configure(surface, generation, bqId);
+    }
+    ALOGD("generation remote change %u", generation);
+
+    Return<Status> transStatus = mBase->setOutputSurface(
+            static_cast<uint64_t>(blockPoolId),
+            bqId == 0 ? nullHgbp : igbp);
+    if (!transStatus.isOk()) {
+        LOG(ERROR) << "setOutputSurface -- transaction failed.";
+        return C2_TRANSACTION_FAILED;
+    }
+    c2_status_t status =
+            static_cast<c2_status_t>(static_cast<Status>(transStatus));
+    if (status != C2_OK) {
+        LOG(DEBUG) << "setOutputSurface -- call failed: " << status << ".";
+    }
+    return status;
+}
+
+status_t Codec2Client::Component::queueToOutputSurface(
+        const C2ConstGraphicBlock& block,
+        const QueueBufferInput& input,
+        QueueBufferOutput* output) {
+    return mOutputBufferQueue.outputBuffer(block, input, output);
+}
+
+c2_status_t Codec2Client::Component::connectToInputSurface(
+        const std::shared_ptr<InputSurface>& inputSurface,
+        std::shared_ptr<InputSurfaceConnection>* connection) {
+    c2_status_t status;
+    Return<void> transStatus = mBase->connectToInputSurface(
+            inputSurface->mBase,
+            [&status, connection](
+                    Status s, const sp<IInputSurfaceConnection>& c) {
+                status = static_cast<c2_status_t>(s);
+                if (status != C2_OK) {
+                    LOG(DEBUG) << "connectToInputSurface -- call failed: "
+                               << status << ".";
+                    return;
+                }
+                *connection = std::make_shared<InputSurfaceConnection>(c);
+            });
+    if (!transStatus.isOk()) {
+        LOG(ERROR) << "connectToInputSurface -- transaction failed";
+        return C2_TRANSACTION_FAILED;
+    }
+    return status;
+}
+
+c2_status_t Codec2Client::Component::connectToOmxInputSurface(
+        const sp<HGraphicBufferProducer1>& producer,
+        const sp<HGraphicBufferSource>& source,
+        std::shared_ptr<InputSurfaceConnection>* connection) {
+    c2_status_t status;
+    Return<void> transStatus = mBase->connectToOmxInputSurface(
+            producer, source,
+            [&status, connection](
+                    Status s, const sp<IInputSurfaceConnection>& c) {
+                status = static_cast<c2_status_t>(s);
+                if (status != C2_OK) {
+                    LOG(DEBUG) << "connectToOmxInputSurface -- call failed: "
+                               << status << ".";
+                    return;
+                }
+                *connection = std::make_shared<InputSurfaceConnection>(c);
+            });
+    if (!transStatus.isOk()) {
+        LOG(ERROR) << "connectToOmxInputSurface -- transaction failed.";
+        return C2_TRANSACTION_FAILED;
+    }
+    return status;
+}
+
+c2_status_t Codec2Client::Component::disconnectFromInputSurface() {
+    Return<Status> transStatus = mBase->disconnectFromInputSurface();
+    if (!transStatus.isOk()) {
+        LOG(ERROR) << "disconnectToInputSurface -- transaction failed.";
+        return C2_TRANSACTION_FAILED;
+    }
+    c2_status_t status =
+            static_cast<c2_status_t>(static_cast<Status>(transStatus));
+    if (status != C2_OK) {
+        LOG(DEBUG) << "disconnectFromInputSurface -- call failed: "
+                   << status << ".";
+    }
+    return status;
+}
+
+c2_status_t Codec2Client::Component::setDeathListener(
+        const std::shared_ptr<Component>& component,
+        const std::shared_ptr<Listener>& listener) {
+
+    struct HidlDeathRecipient : public hardware::hidl_death_recipient {
+        std::weak_ptr<Component> component;
+        std::weak_ptr<Listener> base;
+
+        virtual void serviceDied(
+                uint64_t /* cookie */,
+                const wp<::android::hidl::base::V1_0::IBase>& /* who */
+                ) override {
+            if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) {
+                listener->onDeath(component);
+            } else {
+                LOG(DEBUG) << "onDeath -- listener died.";
+            }
+        }
+    };
+
+    sp<HidlDeathRecipient> deathRecipient = new HidlDeathRecipient();
+    deathRecipient->base = listener;
+    deathRecipient->component = component;
+
+    component->mDeathRecipient = deathRecipient;
+    Return<bool> transResult = component->mBase->linkToDeath(
+            component->mDeathRecipient, 0);
+    if (!transResult.isOk()) {
+        LOG(ERROR) << "setDeathListener -- linkToDeath() transaction failed.";
+        return C2_TRANSACTION_FAILED;
+    }
+    if (!static_cast<bool>(transResult)) {
+        LOG(DEBUG) << "setDeathListener -- linkToDeath() call failed.";
+        return C2_CORRUPTED;
+    }
+    return C2_OK;
+}
+
+// Codec2Client::InputSurface
+Codec2Client::InputSurface::InputSurface(const sp<IInputSurface>& base)
+      : Configurable{
+            [base]() -> sp<IConfigurable> {
+                Return<sp<IConfigurable>> transResult =
+                        base->getConfigurable();
+                return transResult.isOk() ?
+                        static_cast<sp<IConfigurable>>(transResult) :
+                        nullptr;
+            }()
+        },
+        mBase{base},
+        mGraphicBufferProducer{new
+            H2BGraphicBufferProducer2([base]() -> sp<HGraphicBufferProducer2> {
+                Return<sp<HGraphicBufferProducer2>> transResult =
+                        base->getGraphicBufferProducer();
+                return transResult.isOk() ?
+                        static_cast<sp<HGraphicBufferProducer2>>(transResult) :
+                        nullptr;
+            }())} {
+}
+
+sp<IGraphicBufferProducer>
+        Codec2Client::InputSurface::getGraphicBufferProducer() const {
+    return mGraphicBufferProducer;
+}
+
+sp<IInputSurface> Codec2Client::InputSurface::getHalInterface() const {
+    return mBase;
+}
+
+// Codec2Client::InputSurfaceConnection
+Codec2Client::InputSurfaceConnection::InputSurfaceConnection(
+        const sp<IInputSurfaceConnection>& base)
+      : Configurable{
+            [base]() -> sp<IConfigurable> {
+                Return<sp<IConfigurable>> transResult =
+                        base->getConfigurable();
+                return transResult.isOk() ?
+                        static_cast<sp<IConfigurable>>(transResult) :
+                        nullptr;
+            }()
+        },
+        mBase{base} {
+}
+
+c2_status_t Codec2Client::InputSurfaceConnection::disconnect() {
+    Return<Status> transResult = mBase->disconnect();
+    return static_cast<c2_status_t>(static_cast<Status>(transResult));
+}
+
+}  // namespace android
+
diff --git a/media/codec2/hidl/client/include/codec2/hidl/client.h b/media/codec2/hidl/client/include/codec2/hidl/client.h
new file mode 100644
index 0000000..b8a7fb5
--- /dev/null
+++ b/media/codec2/hidl/client/include/codec2/hidl/client.h
@@ -0,0 +1,433 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_HIDL_CLIENT_H
+#define CODEC2_HIDL_CLIENT_H
+
+#include <gui/IGraphicBufferProducer.h>
+#include <codec2/hidl/1.0/ClientBlockHelper.h>
+#include <C2PlatformSupport.h>
+#include <C2Component.h>
+#include <C2Buffer.h>
+#include <C2Param.h>
+#include <C2.h>
+
+#include <hidl/HidlSupport.h>
+#include <utils/StrongPointer.h>
+
+#include <functional>
+#include <map>
+#include <memory>
+#include <mutex>
+
+/**
+ * This file contains minimal interfaces for the framework to access Codec2.0.
+ *
+ * Codec2Client is the main class that contains the following inner classes:
+ * - Listener
+ * - Configurable
+ * - Interface
+ * - Component
+ *
+ * Classes in Codec2Client, interfaces in Codec2.0, and  HIDL interfaces are
+ * related as follows:
+ * - Codec2Client <==> C2ComponentStore <==> IComponentStore
+ * - Codec2Client::Listener <==> C2Component::Listener <==> IComponentListener
+ * - Codec2Client::Configurable <==> [No equivalent] <==> IConfigurable
+ * - Codec2Client::Interface <==> C2ComponentInterface <==> IComponentInterface
+ * - Codec2Client::Component <==> C2Component <==> IComponent
+ *
+ * The entry point is Codec2Client::CreateFromService(), which creates a
+ * Codec2Client object. From Codec2Client, Interface and Component objects can
+ * be created by calling createComponent() and createInterface().
+ *
+ * createComponent() takes a Listener object, which must be implemented by the
+ * user.
+ *
+ * At the present, createBlockPool() is the only method that yields a
+ * Configurable object. Note, however, that Interface, Component and
+ * Codec2Client are all subclasses of Configurable.
+ */
+
+// Forward declaration of relevant HIDL interfaces
+
+namespace android::hardware::media::c2::V1_0 {
+struct IConfigurable;
+struct IComponent;
+struct IComponentInterface;
+struct IComponentStore;
+struct IInputSink;
+struct IInputSurface;
+struct IInputSurfaceConnection;
+}  // namespace android::hardware::media::c2::V1_0
+
+namespace android::hardware::media::bufferpool::V2_0 {
+struct IClientManager;
+}  // namespace android::hardware::media::bufferpool::V2_0
+
+namespace android::hardware::graphics::bufferqueue::V1_0 {
+struct IGraphicBufferProducer;
+}  // android::hardware::graphics::bufferqueue::V1_0
+
+namespace android::hardware::media::omx::V1_0 {
+struct IGraphicBufferSource;
+}  // namespace android::hardware::media::omx::V1_0
+
+namespace android {
+
+// This class is supposed to be called Codec2Client::Configurable, but forward
+// declaration of an inner class is not possible.
+struct Codec2ConfigurableClient {
+
+    typedef ::android::hardware::media::c2::V1_0::IConfigurable Base;
+
+    const C2String& getName() const;
+
+    c2_status_t query(
+            const std::vector<C2Param*>& stackParams,
+            const std::vector<C2Param::Index> &heapParamIndices,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2Param>>* const heapParams) const;
+
+    c2_status_t config(
+            const std::vector<C2Param*> &params,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2SettingResult>>* const failures);
+
+    c2_status_t querySupportedParams(
+            std::vector<std::shared_ptr<C2ParamDescriptor>>* const params
+            ) const;
+
+    c2_status_t querySupportedValues(
+            std::vector<C2FieldSupportedValuesQuery>& fields,
+            c2_blocking_t mayBlock) const;
+
+    // base cannot be null.
+    Codec2ConfigurableClient(const sp<Base>& base);
+
+protected:
+    sp<Base> mBase;
+    C2String mName;
+
+    friend struct Codec2Client;
+};
+
+struct Codec2Client : public Codec2ConfigurableClient {
+
+    typedef ::android::hardware::media::c2::V1_0::IComponentStore Base;
+
+    struct Listener;
+
+    typedef Codec2ConfigurableClient Configurable;
+
+    struct Component;
+
+    struct Interface;
+
+    struct InputSurface;
+
+    struct InputSurfaceConnection;
+
+    typedef Codec2Client Store;
+
+    sp<Base> const& getBase() const;
+
+    std::string const& getServiceName() const;
+
+    c2_status_t createComponent(
+            C2String const& name,
+            std::shared_ptr<Listener> const& listener,
+            std::shared_ptr<Component>* const component);
+
+    c2_status_t createInterface(
+            C2String const& name,
+            std::shared_ptr<Interface>* const interface);
+
+    c2_status_t createInputSurface(
+            std::shared_ptr<InputSurface>* const inputSurface);
+
+    std::vector<C2Component::Traits> const& listComponents() const;
+
+    c2_status_t copyBuffer(
+            std::shared_ptr<C2Buffer> const& src,
+            std::shared_ptr<C2Buffer> const& dst);
+
+    std::shared_ptr<C2ParamReflector> getParamReflector();
+
+    // Returns the list of IComponentStore service names that are available on
+    // the device. This list is specified at the build time in manifest files.
+    // Note: A software service will have "_software" as a suffix.
+    static std::vector<std::string> const& GetServiceNames();
+
+    // Create a service with a given service name.
+    static std::shared_ptr<Codec2Client> CreateFromService(char const* name);
+
+    // Get clients to all services.
+    static std::vector<std::shared_ptr<Codec2Client>> CreateFromAllServices();
+
+    // Try to create a component with a given name from all known
+    // IComponentStore services.
+    static std::shared_ptr<Component> CreateComponentByName(
+            char const* componentName,
+            std::shared_ptr<Listener> const& listener,
+            std::shared_ptr<Codec2Client>* owner = nullptr);
+
+    // Try to create a component interface with a given name from all known
+    // IComponentStore services.
+    static std::shared_ptr<Interface> CreateInterfaceByName(
+            char const* interfaceName,
+            std::shared_ptr<Codec2Client>* owner = nullptr);
+
+    // List traits from all known IComponentStore services.
+    static std::vector<C2Component::Traits> const& ListComponents();
+
+    // Create an input surface.
+    static std::shared_ptr<InputSurface> CreateInputSurface(
+            char const* serviceName = nullptr);
+
+    // base cannot be null.
+    Codec2Client(sp<Base> const& base, size_t serviceIndex);
+
+protected:
+    sp<Base> mBase;
+
+    // Finds the first store where the predicate returns OK, and returns the last
+    // predicate result. Uses key to remember the last store found, and if cached,
+    // it tries that store before trying all stores (one retry).
+    static c2_status_t ForAllServices(
+            const std::string& key,
+            std::function<c2_status_t(std::shared_ptr<Codec2Client> const&)>
+                predicate);
+
+    size_t mServiceIndex;
+    mutable std::vector<C2Component::Traits> mTraitsList;
+
+    sp<::android::hardware::media::bufferpool::V2_0::IClientManager>
+            mHostPoolManager;
+
+    static std::shared_ptr<Codec2Client> _CreateFromIndex(size_t index);
+
+    std::vector<C2Component::Traits> _listComponents(bool* success) const;
+
+    class Cache;
+};
+
+struct Codec2Client::Interface : public Codec2Client::Configurable {
+
+    typedef ::android::hardware::media::c2::V1_0::IComponentInterface Base;
+
+    Interface(const sp<Base>& base);
+
+protected:
+    sp<Base> mBase;
+};
+
+struct Codec2Client::Listener {
+
+    // This is called when the component produces some output.
+    virtual void onWorkDone(
+            const std::weak_ptr<Component>& comp,
+            std::list<std::unique_ptr<C2Work>>& workItems) = 0;
+
+    // This is called when the component goes into a tripped state.
+    virtual void onTripped(
+            const std::weak_ptr<Component>& comp,
+            const std::vector<std::shared_ptr<C2SettingResult>>& settingResults
+            ) = 0;
+
+    // This is called when the component encounters an error.
+    virtual void onError(
+            const std::weak_ptr<Component>& comp,
+            uint32_t errorCode) = 0;
+
+    // This is called when the process that hosts the component shuts down
+    // unexpectedly.
+    virtual void onDeath(
+            const std::weak_ptr<Component>& comp) = 0;
+
+    // This is called when an input buffer is no longer in use by the codec.
+    // Input buffers that have been returned by onWorkDone() or flush() will not
+    // trigger a call to this function.
+    virtual void onInputBufferDone(
+            uint64_t frameIndex, size_t arrayIndex) = 0;
+
+    // This is called when the component becomes aware of a frame being
+    // rendered.
+    virtual void onFrameRendered(
+            uint64_t bufferQueueId,
+            int32_t slotId,
+            int64_t timestampNs) = 0;
+
+    virtual ~Listener();
+
+};
+
+struct Codec2Client::Component : public Codec2Client::Configurable {
+
+    typedef ::android::hardware::media::c2::V1_0::IComponent Base;
+
+    c2_status_t createBlockPool(
+            C2Allocator::id_t id,
+            C2BlockPool::local_id_t* blockPoolId,
+            std::shared_ptr<Configurable>* configurable);
+
+    c2_status_t destroyBlockPool(
+            C2BlockPool::local_id_t localId);
+
+    c2_status_t queue(
+            std::list<std::unique_ptr<C2Work>>* const items);
+
+    c2_status_t flush(
+            C2Component::flush_mode_t mode,
+            std::list<std::unique_ptr<C2Work>>* const flushedWork);
+
+    c2_status_t drain(C2Component::drain_mode_t mode);
+
+    c2_status_t start();
+
+    c2_status_t stop();
+
+    c2_status_t reset();
+
+    c2_status_t release();
+
+    typedef ::android::
+            IGraphicBufferProducer IGraphicBufferProducer;
+    typedef IGraphicBufferProducer::
+            QueueBufferInput QueueBufferInput;
+    typedef IGraphicBufferProducer::
+            QueueBufferOutput QueueBufferOutput;
+
+    typedef ::android::hardware::graphics::bufferqueue::V1_0::
+            IGraphicBufferProducer HGraphicBufferProducer1;
+    typedef ::android::hardware::graphics::bufferqueue::V2_0::
+            IGraphicBufferProducer HGraphicBufferProducer2;
+    typedef ::android::hardware::media::omx::V1_0::
+            IGraphicBufferSource HGraphicBufferSource;
+
+    // Set the output surface to be used with a blockpool previously created by
+    // createBlockPool().
+    c2_status_t setOutputSurface(
+            C2BlockPool::local_id_t blockPoolId,
+            const sp<IGraphicBufferProducer>& surface,
+            uint32_t generation);
+
+    // Extract a slot number from of the block, then call
+    // IGraphicBufferProducer::queueBuffer().
+    //
+    // If the output surface has not been set, NO_INIT will be returned.
+    //
+    // If the block does not come from a bufferqueue-based blockpool,
+    // attachBuffer() will be called, followed by queueBuffer().
+    //
+    // If the block has a bqId that does not match the id of the output surface,
+    // DEAD_OBJECT will be returned.
+    //
+    // If the call to queueBuffer() is successful but the block cannot be
+    // associated to the output surface for automatic cancellation upon
+    // destruction, UNKNOWN_ERROR will be returned.
+    //
+    // Otherwise, the return value from queueBuffer() will be returned.
+    status_t queueToOutputSurface(
+            const C2ConstGraphicBlock& block,
+            const QueueBufferInput& input,
+            QueueBufferOutput* output);
+
+    // Connect to a given InputSurface.
+    c2_status_t connectToInputSurface(
+            const std::shared_ptr<InputSurface>& inputSurface,
+            std::shared_ptr<InputSurfaceConnection>* connection);
+
+    c2_status_t connectToOmxInputSurface(
+            const sp<HGraphicBufferProducer1>& producer,
+            const sp<HGraphicBufferSource>& source,
+            std::shared_ptr<InputSurfaceConnection>* connection);
+
+    c2_status_t disconnectFromInputSurface();
+
+    // base cannot be null.
+    Component(const sp<Base>& base);
+
+    ~Component();
+
+protected:
+    sp<Base> mBase;
+
+    ::android::hardware::media::c2::V1_0::utils::DefaultBufferPoolSender
+            mBufferPoolSender;
+
+    ::android::hardware::media::c2::V1_0::utils::OutputBufferQueue
+            mOutputBufferQueue;
+
+    static c2_status_t setDeathListener(
+            const std::shared_ptr<Component>& component,
+            const std::shared_ptr<Listener>& listener);
+    sp<::android::hardware::hidl_death_recipient> mDeathRecipient;
+
+    friend struct Codec2Client;
+
+    struct HidlListener;
+    void handleOnWorkDone(const std::list<std::unique_ptr<C2Work>> &workItems);
+
+};
+
+struct Codec2Client::InputSurface : public Codec2Client::Configurable {
+public:
+    typedef ::android::hardware::media::c2::V1_0::IInputSurface Base;
+
+    typedef ::android::hardware::media::c2::V1_0::IInputSurfaceConnection
+            ConnectionBase;
+
+    typedef Codec2Client::InputSurfaceConnection Connection;
+
+    typedef ::android::IGraphicBufferProducer IGraphicBufferProducer;
+
+    sp<IGraphicBufferProducer> getGraphicBufferProducer() const;
+
+    // Return the underlying IInputSurface.
+    sp<Base> getHalInterface() const;
+
+    // base cannot be null.
+    InputSurface(const sp<Base>& base);
+
+protected:
+    sp<Base> mBase;
+
+    sp<IGraphicBufferProducer> mGraphicBufferProducer;
+
+    friend struct Codec2Client;
+    friend struct Component;
+};
+
+struct Codec2Client::InputSurfaceConnection : public Codec2Client::Configurable {
+
+    typedef ::android::hardware::media::c2::V1_0::IInputSurfaceConnection Base;
+
+    c2_status_t disconnect();
+
+    // base cannot be null.
+    InputSurfaceConnection(const sp<Base>& base);
+
+protected:
+    sp<Base> mBase;
+
+    friend struct Codec2Client::InputSurface;
+};
+
+}  // namespace android
+
+#endif  // CODEC2_HIDL_CLIENT_H
+
diff --git a/media/codec2/hidl/services/Android.bp b/media/codec2/hidl/services/Android.bp
new file mode 100644
index 0000000..216525e
--- /dev/null
+++ b/media/codec2/hidl/services/Android.bp
@@ -0,0 +1,39 @@
+cc_binary {
+    name: "android.hardware.media.c2@1.0-service",
+    defaults: ["hidl_defaults"],
+    soc_specific: true,
+    relative_install_path: "hw",
+    srcs: [
+        "vendor.cpp",
+    ],
+
+    init_rc: ["android.hardware.media.c2@1.0-service.rc"],
+
+    shared_libs: [
+        "android.hardware.media.c2@1.0",
+        "android.hardware.media.omx@1.0",
+        "libavservices_minijail_vendor",
+        "libbinder",
+        "libcodec2_hidl@1.0",
+        "libcodec2_vndk",
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libstagefright_omx",
+        "libstagefright_xmlparser",
+        "libutils",
+    ],
+
+    arch: {
+        arm: {
+            required: ["codec2.vendor.base.policy"],
+        },
+        x86: {
+            required: ["codec2.vendor.base.policy"],
+        },
+    },
+
+    compile_multilib: "32",
+}
+
diff --git a/media/codec2/hidl/services/Android.mk b/media/codec2/hidl/services/Android.mk
new file mode 100644
index 0000000..d9b28e7
--- /dev/null
+++ b/media/codec2/hidl/services/Android.mk
@@ -0,0 +1,24 @@
+LOCAL_PATH := $(call my-dir)
+
+# vendor service seccomp policy
+ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH), x86 x86_64 arm arm64))
+include $(CLEAR_VARS)
+LOCAL_MODULE := codec2.vendor.base.policy
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/seccomp_policy
+LOCAL_REQUIRED_MODULES := crash_dump.policy
+ifdef TARGET_2ND_ARCH
+    ifneq ($(TARGET_TRANSLATE_2ND_ARCH),true)
+        LOCAL_SRC_FILES := seccomp_policy/codec2.vendor.base-$(TARGET_2ND_ARCH).policy
+    else
+        LOCAL_SRC_FILES := seccomp_policy/codec2.vendor.base-$(TARGET_ARCH).policy
+    endif
+else
+    LOCAL_SRC_FILES := seccomp_policy/codec2.vendor.base-$(TARGET_ARCH).policy
+endif
+include $(BUILD_PREBUILT)
+endif
+
+include $(call all-makefiles-under, $(LOCAL_PATH))
+
diff --git a/media/codec2/hidl/services/android.hardware.media.c2@1.0-service.rc b/media/codec2/hidl/services/android.hardware.media.c2@1.0-service.rc
new file mode 100644
index 0000000..8806bd1
--- /dev/null
+++ b/media/codec2/hidl/services/android.hardware.media.c2@1.0-service.rc
@@ -0,0 +1,7 @@
+service android-hardware-media-c2-hal-1-0 /vendor/bin/hw/android.hardware.media.c2@1.0-service
+    class hal
+    user mediacodec
+    group camera mediadrm drmrpc
+    ioprio rt 4
+    writepid /dev/cpuset/foreground/tasks
+
diff --git a/media/codec2/hidl/services/seccomp_policy/codec2.software.base-arm.policy b/media/codec2/hidl/services/seccomp_policy/codec2.software.base-arm.policy
new file mode 100644
index 0000000..d5871d1
--- /dev/null
+++ b/media/codec2/hidl/services/seccomp_policy/codec2.software.base-arm.policy
@@ -0,0 +1,73 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Organized by frequency of systemcall - in descending order for
+# best performance.
+futex: 1
+ioctl: 1
+write: 1
+prctl: 1
+clock_gettime: 1
+getpriority: 1
+read: 1
+close: 1
+writev: 1
+dup: 1
+ppoll: 1
+mmap2: 1
+getrandom: 1
+
+# mremap: Ensure |flags| are (MREMAP_MAYMOVE | MREMAP_FIXED) TODO: Once minijail
+# parser support for '<' is in this needs to be modified to also prevent
+# |old_address| and |new_address| from touching the exception vector page, which
+# on ARM is statically loaded at 0xffff 0000. See
+# http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0211h/Babfeega.html
+# for more details.
+mremap: arg3 == 3
+munmap: 1
+mprotect: 1
+madvise: 1
+openat: 1
+sigaltstack: 1
+clone: 1
+setpriority: 1
+getuid32: 1
+fstat64: 1
+fstatfs64: 1
+pread64: 1
+faccessat: 1
+readlinkat: 1
+exit: 1
+rt_sigprocmask: 1
+set_tid_address: 1
+restart_syscall: 1
+exit_group: 1
+rt_sigreturn: 1
+pipe2: 1
+gettimeofday: 1
+sched_yield: 1
+nanosleep: 1
+lseek: 1
+_llseek: 1
+sched_get_priority_max: 1
+sched_get_priority_min: 1
+statfs64: 1
+sched_setscheduler: 1
+fstatat64: 1
+ugetrlimit: 1
+getdents64: 1
+getrandom: 1
+
+@include /system/etc/seccomp_policy/crash_dump.arm.policy
+
diff --git a/media/codec2/hidl/services/seccomp_policy/codec2.software.base-x86.policy b/media/codec2/hidl/services/seccomp_policy/codec2.software.base-x86.policy
new file mode 100644
index 0000000..20c7625
--- /dev/null
+++ b/media/codec2/hidl/services/seccomp_policy/codec2.software.base-x86.policy
@@ -0,0 +1,57 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+read: 1
+mprotect: 1
+prctl: 1
+openat: 1
+getuid32: 1
+writev: 1
+ioctl: 1
+close: 1
+mmap2: 1
+fstat64: 1
+madvise: 1
+fstatat64: 1
+futex: 1
+munmap: 1
+faccessat: 1
+_llseek: 1
+lseek: 1
+clone: 1
+sigaltstack: 1
+setpriority: 1
+restart_syscall: 1
+exit: 1
+exit_group: 1
+rt_sigreturn: 1
+ugetrlimit: 1
+readlinkat: 1
+_llseek: 1
+fstatfs64: 1
+pread64: 1
+mremap: 1
+dup: 1
+set_tid_address: 1
+write: 1
+nanosleep: 1
+
+# Required by AddressSanitizer
+gettid: 1
+sched_yield: 1
+getpid: 1
+gettid: 1
+
+@include /system/etc/seccomp_policy/crash_dump.x86.policy
+
diff --git a/media/codec2/hidl/services/seccomp_policy/codec2.vendor.base-arm.policy b/media/codec2/hidl/services/seccomp_policy/codec2.vendor.base-arm.policy
new file mode 100644
index 0000000..d5871d1
--- /dev/null
+++ b/media/codec2/hidl/services/seccomp_policy/codec2.vendor.base-arm.policy
@@ -0,0 +1,73 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Organized by frequency of systemcall - in descending order for
+# best performance.
+futex: 1
+ioctl: 1
+write: 1
+prctl: 1
+clock_gettime: 1
+getpriority: 1
+read: 1
+close: 1
+writev: 1
+dup: 1
+ppoll: 1
+mmap2: 1
+getrandom: 1
+
+# mremap: Ensure |flags| are (MREMAP_MAYMOVE | MREMAP_FIXED) TODO: Once minijail
+# parser support for '<' is in this needs to be modified to also prevent
+# |old_address| and |new_address| from touching the exception vector page, which
+# on ARM is statically loaded at 0xffff 0000. See
+# http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0211h/Babfeega.html
+# for more details.
+mremap: arg3 == 3
+munmap: 1
+mprotect: 1
+madvise: 1
+openat: 1
+sigaltstack: 1
+clone: 1
+setpriority: 1
+getuid32: 1
+fstat64: 1
+fstatfs64: 1
+pread64: 1
+faccessat: 1
+readlinkat: 1
+exit: 1
+rt_sigprocmask: 1
+set_tid_address: 1
+restart_syscall: 1
+exit_group: 1
+rt_sigreturn: 1
+pipe2: 1
+gettimeofday: 1
+sched_yield: 1
+nanosleep: 1
+lseek: 1
+_llseek: 1
+sched_get_priority_max: 1
+sched_get_priority_min: 1
+statfs64: 1
+sched_setscheduler: 1
+fstatat64: 1
+ugetrlimit: 1
+getdents64: 1
+getrandom: 1
+
+@include /system/etc/seccomp_policy/crash_dump.arm.policy
+
diff --git a/media/codec2/hidl/services/seccomp_policy/codec2.vendor.base-x86.policy b/media/codec2/hidl/services/seccomp_policy/codec2.vendor.base-x86.policy
new file mode 100644
index 0000000..20c7625
--- /dev/null
+++ b/media/codec2/hidl/services/seccomp_policy/codec2.vendor.base-x86.policy
@@ -0,0 +1,57 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+read: 1
+mprotect: 1
+prctl: 1
+openat: 1
+getuid32: 1
+writev: 1
+ioctl: 1
+close: 1
+mmap2: 1
+fstat64: 1
+madvise: 1
+fstatat64: 1
+futex: 1
+munmap: 1
+faccessat: 1
+_llseek: 1
+lseek: 1
+clone: 1
+sigaltstack: 1
+setpriority: 1
+restart_syscall: 1
+exit: 1
+exit_group: 1
+rt_sigreturn: 1
+ugetrlimit: 1
+readlinkat: 1
+_llseek: 1
+fstatfs64: 1
+pread64: 1
+mremap: 1
+dup: 1
+set_tid_address: 1
+write: 1
+nanosleep: 1
+
+# Required by AddressSanitizer
+gettid: 1
+sched_yield: 1
+getpid: 1
+gettid: 1
+
+@include /system/etc/seccomp_policy/crash_dump.x86.policy
+
diff --git a/media/codec2/hidl/services/vendor.cpp b/media/codec2/hidl/services/vendor.cpp
new file mode 100644
index 0000000..ef2f98e
--- /dev/null
+++ b/media/codec2/hidl/services/vendor.cpp
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "android.hardware.media.c2@1.0-service"
+
+#include <codec2/hidl/1.0/ComponentStore.h>
+#include <hidl/HidlTransportSupport.h>
+#include <binder/ProcessState.h>
+#include <minijail.h>
+
+#include <C2Component.h>
+
+// OmxStore is added for visibility by dumpstate.
+#include <media/stagefright/omx/1.0/OmxStore.h>
+
+// This is created by module "codec2.vendor.base.policy". This can be modified.
+static constexpr char kBaseSeccompPolicyPath[] =
+        "/vendor/etc/seccomp_policy/codec2.vendor.base.policy";
+
+// Additional device-specific seccomp permissions can be added in this file.
+static constexpr char kExtSeccompPolicyPath[] =
+        "/vendor/etc/seccomp_policy/codec2.vendor.ext.policy";
+
+class DummyC2Store : public C2ComponentStore {
+public:
+    DummyC2Store() = default;
+
+    virtual ~DummyC2Store() override = default;
+
+    virtual C2String getName() const override {
+        return "default";
+    }
+
+    virtual c2_status_t createComponent(
+            C2String /*name*/,
+            std::shared_ptr<C2Component>* const /*component*/) override {
+        return C2_NOT_FOUND;
+    }
+
+    virtual c2_status_t createInterface(
+            C2String /* name */,
+            std::shared_ptr<C2ComponentInterface>* const /* interface */) override {
+        return C2_NOT_FOUND;
+    }
+
+    virtual std::vector<std::shared_ptr<const C2Component::Traits>>
+            listComponents() override {
+        return {};
+    }
+
+    virtual c2_status_t copyBuffer(
+            std::shared_ptr<C2GraphicBuffer> /* src */,
+            std::shared_ptr<C2GraphicBuffer> /* dst */) override {
+        return C2_OMITTED;
+    }
+
+    virtual c2_status_t query_sm(
+        const std::vector<C2Param*>& /* stackParams */,
+        const std::vector<C2Param::Index>& /* heapParamIndices */,
+        std::vector<std::unique_ptr<C2Param>>* const /* heapParams */) const override {
+        return C2_OMITTED;
+    }
+
+    virtual c2_status_t config_sm(
+            const std::vector<C2Param*>& /* params */,
+            std::vector<std::unique_ptr<C2SettingResult>>* const /* failures */) override {
+        return C2_OMITTED;
+    }
+
+    virtual std::shared_ptr<C2ParamReflector> getParamReflector() const override {
+        return nullptr;
+    }
+
+    virtual c2_status_t querySupportedParams_nb(
+            std::vector<std::shared_ptr<C2ParamDescriptor>>* const /* params */) const override {
+        return C2_OMITTED;
+    }
+
+    virtual c2_status_t querySupportedValues_sm(
+            std::vector<C2FieldSupportedValuesQuery>& /* fields */) const override {
+        return C2_OMITTED;
+    }
+};
+
+int main(int /* argc */, char** /* argv */) {
+    ALOGD("android.hardware.media.c2@1.0-service starting...");
+
+    signal(SIGPIPE, SIG_IGN);
+    android::SetUpMinijail(kBaseSeccompPolicyPath, kExtSeccompPolicyPath);
+
+    // vndbinder is needed by BufferQueue.
+    android::ProcessState::initWithDriver("/dev/vndbinder");
+    android::ProcessState::self()->startThreadPool();
+
+    // Extra threads may be needed to handle a stacked IPC sequence that
+    // contains alternating binder and hwbinder calls. (See b/35283480.)
+    android::hardware::configureRpcThreadpool(8, true /* callerWillJoin */);
+
+    // Create IComponentStore service.
+    {
+        using namespace ::android::hardware::media::c2::V1_0;
+        android::sp<IComponentStore> store;
+
+        // Vendor's TODO: Replace this with
+        // store = new utils::ComponentStore(
+        //         /* implementation of C2ComponentStore */);
+        ALOGD("Instantiating Codec2's dummy IComponentStore service...");
+        store = new utils::ComponentStore(
+                std::make_shared<DummyC2Store>());
+
+        if (store == nullptr) {
+            ALOGE("Cannot create Codec2's IComponentStore service.");
+        } else {
+            if (store->registerAsService("default") != android::OK) {
+                ALOGE("Cannot register Codec2's "
+                        "IComponentStore service.");
+            } else {
+                ALOGI("Codec2's IComponentStore service created.");
+            }
+        }
+    }
+
+    // Register IOmxStore service.
+    {
+        using namespace ::android::hardware::media::omx::V1_0;
+        android::sp<IOmxStore> omxStore = new implementation::OmxStore();
+        if (omxStore == nullptr) {
+            ALOGE("Cannot create IOmxStore HAL service.");
+        } else if (omxStore->registerAsService() != android::OK) {
+            ALOGE("Cannot register IOmxStore HAL service.");
+        }
+    }
+
+    android::hardware::joinRpcThreadpool();
+    return 0;
+}
diff --git a/media/codec2/sfplugin/Android.bp b/media/codec2/sfplugin/Android.bp
new file mode 100644
index 0000000..9c84c71
--- /dev/null
+++ b/media/codec2/sfplugin/Android.bp
@@ -0,0 +1,62 @@
+cc_library_shared {
+    name: "libsfplugin_ccodec",
+
+    srcs: [
+        "C2OMXNode.cpp",
+        "CCodec.cpp",
+        "CCodecBufferChannel.cpp",
+        "CCodecBuffers.cpp",
+        "CCodecConfig.cpp",
+        "Codec2Buffer.cpp",
+        "Codec2InfoBuilder.cpp",
+        "Omx2IGraphicBufferSource.cpp",
+        "PipelineWatcher.cpp",
+        "ReflectedParamUpdater.cpp",
+        "SkipCutBuffer.cpp",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+
+    header_libs: [
+        "libcodec2_internal",
+    ],
+
+    shared_libs: [
+        "android.hardware.cas.native@1.0",
+        "android.hardware.graphics.bufferqueue@1.0",
+        "android.hardware.media.c2@1.0",
+        "android.hardware.media.omx@1.0",
+        "libbase",
+        "libbinder",
+        "libcodec2",
+        "libcodec2_client",
+        "libcodec2_vndk",
+        "libcutils",
+        "libgui",
+        "libhidlallocatorutils",
+        "libhidlbase",
+        "liblog",
+        "libmedia",
+        "libmedia_omx",
+        "libsfplugin_ccodec_utils",
+        "libstagefright_bufferqueue_helper",
+        "libstagefright_codecbase",
+        "libstagefright_foundation",
+        "libstagefright_omx",
+        "libstagefright_omx_utils",
+        "libstagefright_xmlparser",
+        "libui",
+        "libutils",
+    ],
+
+    sanitize: {
+        cfi: true,
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+    },
+}
diff --git a/media/codec2/sfplugin/C2OMXNode.cpp b/media/codec2/sfplugin/C2OMXNode.cpp
new file mode 100644
index 0000000..78d221e
--- /dev/null
+++ b/media/codec2/sfplugin/C2OMXNode.cpp
@@ -0,0 +1,467 @@
+/*
+ * Copyright 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef __LP64__
+#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
+#endif
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2OMXNode"
+#include <log/log.h>
+
+#include <C2AllocatorGralloc.h>
+#include <C2BlockInternal.h>
+#include <C2Component.h>
+#include <C2PlatformSupport.h>
+
+#include <OMX_Component.h>
+#include <OMX_Index.h>
+#include <OMX_IndexExt.h>
+
+#include <android/fdsan.h>
+#include <media/stagefright/omx/OMXUtils.h>
+#include <media/stagefright/MediaErrors.h>
+#include <ui/Fence.h>
+#include <ui/GraphicBuffer.h>
+#include <utils/Thread.h>
+
+#include "C2OMXNode.h"
+
+namespace android {
+
+namespace {
+
+class Buffer2D : public C2Buffer {
+public:
+    explicit Buffer2D(C2ConstGraphicBlock block) : C2Buffer({ block }) {}
+};
+
+}  // namespace
+
+class C2OMXNode::QueueThread : public Thread {
+public:
+    QueueThread() : Thread(false) {}
+    ~QueueThread() override = default;
+    void queue(
+            const std::shared_ptr<Codec2Client::Component> &comp,
+            int fenceFd,
+            std::unique_ptr<C2Work> &&work,
+            android::base::unique_fd &&fd0,
+            android::base::unique_fd &&fd1) {
+        Mutexed<Jobs>::Locked jobs(mJobs);
+        auto it = jobs->queues.try_emplace(comp, comp, systemTime()).first;
+        it->second.workList.emplace_back(
+                std::move(work), fenceFd, std::move(fd0), std::move(fd1));
+        jobs->cond.broadcast();
+    }
+
+protected:
+    bool threadLoop() override {
+        constexpr nsecs_t kIntervalNs = nsecs_t(10) * 1000 * 1000;  // 10ms
+        constexpr nsecs_t kWaitNs = kIntervalNs * 2;
+        for (int i = 0; i < 2; ++i) {
+            Mutexed<Jobs>::Locked jobs(mJobs);
+            nsecs_t nowNs = systemTime();
+            bool queued = false;
+            for (auto it = jobs->queues.begin(); it != jobs->queues.end(); ) {
+                Queue &queue = it->second;
+                if (queue.workList.empty()
+                        || nowNs - queue.lastQueuedTimestampNs < kIntervalNs) {
+                    ++it;
+                    continue;
+                }
+                std::shared_ptr<Codec2Client::Component> comp = queue.component.lock();
+                if (!comp) {
+                    it = jobs->queues.erase(it);
+                    continue;
+                }
+                std::list<std::unique_ptr<C2Work>> items;
+                std::vector<int> fenceFds;
+                std::vector<android::base::unique_fd> uniqueFds;
+                while (!queue.workList.empty()) {
+                    items.push_back(std::move(queue.workList.front().work));
+                    fenceFds.push_back(queue.workList.front().fenceFd);
+                    uniqueFds.push_back(std::move(queue.workList.front().fd0));
+                    uniqueFds.push_back(std::move(queue.workList.front().fd1));
+                    queue.workList.pop_front();
+                }
+
+                jobs.unlock();
+                for (int fenceFd : fenceFds) {
+                    sp<Fence> fence(new Fence(fenceFd));
+                    fence->waitForever(LOG_TAG);
+                }
+                comp->queue(&items);
+                for (android::base::unique_fd &ufd : uniqueFds) {
+                    (void)ufd.release();
+                }
+                jobs.lock();
+
+                it = jobs->queues.upper_bound(comp);
+                queued = true;
+            }
+            if (queued) {
+                return true;
+            }
+            if (i == 0) {
+                jobs.waitForConditionRelative(jobs->cond, kWaitNs);
+            }
+        }
+        return true;
+    }
+
+private:
+    struct WorkFence {
+        WorkFence(std::unique_ptr<C2Work> &&w, int fd) : work(std::move(w)), fenceFd(fd) {}
+
+        WorkFence(
+                std::unique_ptr<C2Work> &&w,
+                int fd,
+                android::base::unique_fd &&uniqueFd0,
+                android::base::unique_fd &&uniqueFd1)
+            : work(std::move(w)),
+              fenceFd(fd),
+              fd0(std::move(uniqueFd0)),
+              fd1(std::move(uniqueFd1)) {}
+
+        std::unique_ptr<C2Work> work;
+        int fenceFd;
+        android::base::unique_fd fd0;
+        android::base::unique_fd fd1;
+    };
+    struct Queue {
+        Queue(const std::shared_ptr<Codec2Client::Component> &comp, nsecs_t timestamp)
+            : component(comp), lastQueuedTimestampNs(timestamp) {}
+        Queue(const Queue &) = delete;
+        Queue &operator =(const Queue &) = delete;
+
+        std::weak_ptr<Codec2Client::Component> component;
+        std::list<WorkFence> workList;
+        nsecs_t lastQueuedTimestampNs;
+    };
+    struct Jobs {
+        std::map<std::weak_ptr<Codec2Client::Component>,
+                 Queue,
+                 std::owner_less<std::weak_ptr<Codec2Client::Component>>> queues;
+        Condition cond;
+    };
+    Mutexed<Jobs> mJobs;
+};
+
+C2OMXNode::C2OMXNode(const std::shared_ptr<Codec2Client::Component> &comp)
+    : mComp(comp), mFrameIndex(0), mWidth(0), mHeight(0), mUsage(0),
+      mAdjustTimestampGapUs(0), mFirstInputFrame(true),
+      mQueueThread(new QueueThread) {
+    android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS);
+    mQueueThread->run("C2OMXNode", PRIORITY_AUDIO);
+}
+
+status_t C2OMXNode::freeNode() {
+    mComp.reset();
+    android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
+    return mQueueThread->requestExitAndWait();
+}
+
+status_t C2OMXNode::sendCommand(OMX_COMMANDTYPE cmd, OMX_S32 param) {
+    if (cmd == OMX_CommandStateSet && param == OMX_StateLoaded) {
+        // Reset first input frame so if C2OMXNode is recycled, the timestamp does not become
+        // negative. This is a workaround for HW codecs that do not handle timestamp rollover.
+        mFirstInputFrame = true;
+    }
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::getParameter(OMX_INDEXTYPE index, void *params, size_t size) {
+    status_t err = ERROR_UNSUPPORTED;
+    switch ((uint32_t)index) {
+        case OMX_IndexParamConsumerUsageBits: {
+            OMX_U32 *usage = (OMX_U32 *)params;
+            *usage = mUsage;
+            err = OK;
+            break;
+        }
+        case OMX_IndexParamPortDefinition: {
+            if (size < sizeof(OMX_PARAM_PORTDEFINITIONTYPE)) {
+                return BAD_VALUE;
+            }
+            OMX_PARAM_PORTDEFINITIONTYPE *pDef = (OMX_PARAM_PORTDEFINITIONTYPE *)params;
+            // TODO: read these from intf()
+            pDef->nBufferCountActual = 16;
+            pDef->eDomain = OMX_PortDomainVideo;
+            pDef->format.video.nFrameWidth = mWidth;
+            pDef->format.video.nFrameHeight = mHeight;
+            err = OK;
+            break;
+        }
+        default:
+            break;
+    }
+    return err;
+}
+
+status_t C2OMXNode::setParameter(OMX_INDEXTYPE index, const void *params, size_t size) {
+    if (params == NULL) {
+        return BAD_VALUE;
+    }
+    switch ((uint32_t)index) {
+        case OMX_IndexParamMaxFrameDurationForBitrateControl:
+            // handle max/fixed frame duration control
+            if (size != sizeof(OMX_PARAM_U32TYPE)) {
+                return BAD_VALUE;
+            }
+            // The incoming number is an int32_t contained in OMX_U32.
+            mAdjustTimestampGapUs = (int32_t)((OMX_PARAM_U32TYPE*)params)->nU32;
+            return OK;
+
+        case OMX_IndexParamConsumerUsageBits:
+            if (size != sizeof(OMX_U32)) {
+                return BAD_VALUE;
+            }
+            mUsage = *((OMX_U32 *)params);
+            return OK;
+    }
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::getConfig(OMX_INDEXTYPE index, void *config, size_t size) {
+    (void)index;
+    (void)config;
+    (void)size;
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::setConfig(OMX_INDEXTYPE index, const void *config, size_t size) {
+    (void)index;
+    (void)config;
+    (void)size;
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
+    (void)portIndex;
+    (void)mode;
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::prepareForAdaptivePlayback(
+        OMX_U32 portIndex, OMX_BOOL enable,
+        OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) {
+    (void)portIndex;
+    (void)enable;
+    (void)maxFrameWidth;
+    (void)maxFrameHeight;
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::configureVideoTunnelMode(
+        OMX_U32 portIndex, OMX_BOOL tunneled,
+        OMX_U32 audioHwSync, native_handle_t **sidebandHandle) {
+    (void)portIndex;
+    (void)tunneled;
+    (void)audioHwSync;
+    *sidebandHandle = nullptr;
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::getGraphicBufferUsage(OMX_U32 portIndex, OMX_U32* usage) {
+    (void)portIndex;
+    *usage = 0;
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::setInputSurface(const sp<IOMXBufferSource> &bufferSource) {
+    c2_status_t err = GetCodec2PlatformAllocatorStore()->fetchAllocator(
+            C2PlatformAllocatorStore::GRALLOC,
+            &mAllocator);
+    if (err != OK) {
+        return UNKNOWN_ERROR;
+    }
+    mBufferSource = bufferSource;
+    return OK;
+}
+
+status_t C2OMXNode::allocateSecureBuffer(
+        OMX_U32 portIndex, size_t size, buffer_id *buffer,
+        void **bufferData, sp<NativeHandle> *nativeHandle) {
+    (void)portIndex;
+    (void)size;
+    (void)nativeHandle;
+    *buffer = 0;
+    *bufferData = nullptr;
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::useBuffer(
+        OMX_U32 portIndex, const OMXBuffer &omxBuf, buffer_id *buffer) {
+    (void)portIndex;
+    (void)omxBuf;
+    *buffer = 0;
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::freeBuffer(OMX_U32 portIndex, buffer_id buffer) {
+    (void)portIndex;
+    (void)buffer;
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::fillBuffer(
+        buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd) {
+    (void)buffer;
+    (void)omxBuf;
+    (void)fenceFd;
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::emptyBuffer(
+        buffer_id buffer, const OMXBuffer &omxBuf,
+        OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
+    std::shared_ptr<Codec2Client::Component> comp = mComp.lock();
+    if (!comp) {
+        return NO_INIT;
+    }
+
+    uint32_t c2Flags = (flags & OMX_BUFFERFLAG_EOS)
+            ? C2FrameData::FLAG_END_OF_STREAM : 0;
+    std::shared_ptr<C2GraphicBlock> block;
+
+    android::base::unique_fd fd0, fd1;
+    C2Handle *handle = nullptr;
+    if (omxBuf.mBufferType == OMXBuffer::kBufferTypeANWBuffer
+            && omxBuf.mGraphicBuffer != nullptr) {
+        std::shared_ptr<C2GraphicAllocation> alloc;
+        handle = WrapNativeCodec2GrallocHandle(
+                omxBuf.mGraphicBuffer->handle,
+                omxBuf.mGraphicBuffer->width,
+                omxBuf.mGraphicBuffer->height,
+                omxBuf.mGraphicBuffer->format,
+                omxBuf.mGraphicBuffer->usage,
+                omxBuf.mGraphicBuffer->stride);
+        if (handle != nullptr) {
+            // unique_fd takes ownership of the fds, we'll get warning if these
+            // fds get closed by somebody else. Onwership will be released before
+            // we return, so that the fds get closed as usually when this function
+            // goes out of scope (when both items and block are gone).
+            native_handle_t *nativeHandle = reinterpret_cast<native_handle_t*>(handle);
+            fd0.reset(nativeHandle->numFds > 0 ? nativeHandle->data[0] : -1);
+            fd1.reset(nativeHandle->numFds > 1 ? nativeHandle->data[1] : -1);
+        }
+        c2_status_t err = mAllocator->priorGraphicAllocation(handle, &alloc);
+        if (err != OK) {
+            (void)fd0.release();
+            (void)fd1.release();
+            return UNKNOWN_ERROR;
+        }
+        block = _C2BlockFactory::CreateGraphicBlock(alloc);
+    } else if (!(flags & OMX_BUFFERFLAG_EOS)) {
+        return BAD_VALUE;
+    }
+
+    std::unique_ptr<C2Work> work(new C2Work);
+    work->input.flags = (C2FrameData::flags_t)c2Flags;
+    work->input.ordinal.timestamp = timestamp;
+
+    // WORKAROUND: adjust timestamp based on gapUs
+    {
+        work->input.ordinal.customOrdinal = timestamp; // save input timestamp
+        if (mFirstInputFrame) {
+            // grab timestamps on first frame
+            mPrevInputTimestamp = timestamp;
+            mPrevCodecTimestamp = timestamp;
+            mFirstInputFrame = false;
+        } else if (mAdjustTimestampGapUs > 0) {
+            work->input.ordinal.timestamp =
+                mPrevCodecTimestamp
+                        + c2_min((timestamp - mPrevInputTimestamp).peek(), mAdjustTimestampGapUs);
+        } else if (mAdjustTimestampGapUs < 0) {
+            work->input.ordinal.timestamp = mPrevCodecTimestamp - mAdjustTimestampGapUs;
+        }
+        mPrevInputTimestamp = work->input.ordinal.customOrdinal;
+        mPrevCodecTimestamp = work->input.ordinal.timestamp;
+        ALOGV("adjusting %lld to %lld (gap=%lld)",
+              work->input.ordinal.customOrdinal.peekll(),
+              work->input.ordinal.timestamp.peekll(),
+              (long long)mAdjustTimestampGapUs);
+    }
+
+    work->input.ordinal.frameIndex = mFrameIndex++;
+    work->input.buffers.clear();
+    if (block) {
+        std::shared_ptr<C2Buffer> c2Buffer(
+                new Buffer2D(block->share(
+                        C2Rect(block->width(), block->height()), ::C2Fence())));
+        work->input.buffers.push_back(c2Buffer);
+    }
+    work->worklets.clear();
+    work->worklets.emplace_back(new C2Worklet);
+    mBufferIdsInUse.lock()->emplace(work->input.ordinal.frameIndex.peeku(), buffer);
+    mQueueThread->queue(comp, fenceFd, std::move(work), std::move(fd0), std::move(fd1));
+
+    return OK;
+}
+
+status_t C2OMXNode::getExtensionIndex(
+        const char *parameterName, OMX_INDEXTYPE *index) {
+    (void)parameterName;
+    *index = OMX_IndexMax;
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::dispatchMessage(const omx_message& msg) {
+    if (msg.type != omx_message::EVENT) {
+        return ERROR_UNSUPPORTED;
+    }
+    if (msg.u.event_data.event != OMX_EventDataSpaceChanged) {
+        return ERROR_UNSUPPORTED;
+    }
+    android_dataspace dataSpace = (android_dataspace)msg.u.event_data.data1;
+    uint32_t pixelFormat = msg.u.event_data.data3;
+
+    // TODO: set dataspace on component to see if it impacts color aspects
+    ALOGD("dataspace changed to %#x pixel format: %#x", dataSpace, pixelFormat);
+    return OK;
+}
+
+sp<IOMXBufferSource> C2OMXNode::getSource() {
+    return mBufferSource;
+}
+
+void C2OMXNode::setFrameSize(uint32_t width, uint32_t height) {
+    mWidth = width;
+    mHeight = height;
+}
+
+void C2OMXNode::onInputBufferDone(c2_cntr64_t index) {
+    if (!mBufferSource) {
+        ALOGD("Buffer source not set (index=%llu)", index.peekull());
+        return;
+    }
+
+    int32_t bufferId = 0;
+    {
+        decltype(mBufferIdsInUse)::Locked bufferIds(mBufferIdsInUse);
+        auto it = bufferIds->find(index.peeku());
+        if (it == bufferIds->end()) {
+            ALOGV("Untracked input index %llu (maybe already removed)", index.peekull());
+            return;
+        }
+        bufferId = it->second;
+        (void)bufferIds->erase(it);
+    }
+    (void)mBufferSource->onInputBufferEmptied(bufferId, -1);
+}
+
+}  // namespace android
diff --git a/media/codec2/sfplugin/C2OMXNode.h b/media/codec2/sfplugin/C2OMXNode.h
new file mode 100644
index 0000000..1717c96
--- /dev/null
+++ b/media/codec2/sfplugin/C2OMXNode.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef C2_OMX_NODE_H_
+#define C2_OMX_NODE_H_
+
+#include <atomic>
+
+#include <android/IOMXBufferSource.h>
+#include <codec2/hidl/client.h>
+#include <media/stagefright/foundation/Mutexed.h>
+#include <media/IOMX.h>
+#include <media/OMXBuffer.h>
+
+namespace android {
+
+/**
+ * IOmxNode implementation around codec 2.0 component, only to be used in
+ * IGraphicBufferSource::configure. Only subset of IOmxNode API is implemented
+ * and others are left as stub. As a result, one cannot expect this IOmxNode
+ * to work in any other usage than IGraphicBufferSource.
+ */
+struct C2OMXNode : public BnOMXNode {
+    explicit C2OMXNode(const std::shared_ptr<Codec2Client::Component> &comp);
+    ~C2OMXNode() override = default;
+
+    // IOMXNode
+    status_t freeNode() override;
+    status_t sendCommand(OMX_COMMANDTYPE cmd, OMX_S32 param) override;
+    status_t getParameter(
+            OMX_INDEXTYPE index, void *params, size_t size) override;
+    status_t setParameter(
+            OMX_INDEXTYPE index, const void *params, size_t size) override;
+    status_t getConfig(
+            OMX_INDEXTYPE index, void *params, size_t size) override;
+    status_t setConfig(
+            OMX_INDEXTYPE index, const void *params, size_t size) override;
+    status_t setPortMode(OMX_U32 port_index, IOMX::PortMode mode) override;
+    status_t prepareForAdaptivePlayback(
+            OMX_U32 portIndex, OMX_BOOL enable,
+            OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) override;
+    status_t configureVideoTunnelMode(
+            OMX_U32 portIndex, OMX_BOOL tunneled,
+            OMX_U32 audioHwSync, native_handle_t **sidebandHandle) override;
+    status_t getGraphicBufferUsage(
+            OMX_U32 port_index, OMX_U32* usage) override;
+    status_t setInputSurface(
+            const sp<IOMXBufferSource> &bufferSource) override;
+    status_t allocateSecureBuffer(
+            OMX_U32 port_index, size_t size, buffer_id *buffer,
+            void **buffer_data, sp<NativeHandle> *native_handle) override;
+    status_t useBuffer(
+            OMX_U32 port_index, const OMXBuffer &omxBuf, buffer_id *buffer) override;
+    status_t freeBuffer(
+            OMX_U32 port_index, buffer_id buffer) override;
+    status_t fillBuffer(
+            buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd) override;
+    status_t emptyBuffer(
+            buffer_id buffer, const OMXBuffer &omxBuf,
+            OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) override;
+    status_t getExtensionIndex(
+            const char *parameter_name,
+            OMX_INDEXTYPE *index) override;
+    status_t dispatchMessage(const omx_message &msg) override;
+
+    /**
+     * Returns underlying IOMXBufferSource object.
+     */
+    sp<IOMXBufferSource> getSource();
+
+    /**
+     * Configure the frame size.
+     */
+    void setFrameSize(uint32_t width, uint32_t height);
+
+    /**
+     * Clean up work item reference.
+     *
+     * \param index input work index
+     */
+    void onInputBufferDone(c2_cntr64_t index);
+
+private:
+    std::weak_ptr<Codec2Client::Component> mComp;
+    sp<IOMXBufferSource> mBufferSource;
+    std::shared_ptr<C2Allocator> mAllocator;
+    std::atomic_uint64_t mFrameIndex;
+    uint32_t mWidth;
+    uint32_t mHeight;
+    uint64_t mUsage;
+
+    // WORKAROUND: timestamp adjustment
+
+    // if >0: this is the max timestamp gap, if <0: this is -1 times the fixed timestamp gap
+    // if 0: no timestamp adjustment is made
+    // note that C2OMXNode can be recycled between encoding sessions.
+    int32_t mAdjustTimestampGapUs;
+    bool mFirstInputFrame; // true for first input
+    c2_cntr64_t mPrevInputTimestamp; // input timestamp for previous frame
+    c2_cntr64_t mPrevCodecTimestamp; // adjusted (codec) timestamp for previous frame
+
+    Mutexed<std::map<uint64_t, buffer_id>> mBufferIdsInUse;
+
+    class QueueThread;
+    sp<QueueThread> mQueueThread;
+};
+
+}  // namespace android
+
+#endif  // C2_OMX_NODE_H_
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
new file mode 100644
index 0000000..9d1cc60
--- /dev/null
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -0,0 +1,1883 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "CCodec"
+#include <utils/Log.h>
+
+#include <sstream>
+#include <thread>
+
+#include <C2Config.h>
+#include <C2Debug.h>
+#include <C2ParamInternal.h>
+#include <C2PlatformSupport.h>
+
+#include <android/IGraphicBufferSource.h>
+#include <android/IOMXBufferSource.h>
+#include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
+#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <android-base/stringprintf.h>
+#include <cutils/properties.h>
+#include <gui/IGraphicBufferProducer.h>
+#include <gui/Surface.h>
+#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
+#include <media/omx/1.0/WGraphicBufferSource.h>
+#include <media/openmax/OMX_IndexExt.h>
+#include <media/stagefright/BufferProducerWrapper.h>
+#include <media/stagefright/MediaCodecConstants.h>
+#include <media/stagefright/PersistentSurface.h>
+
+#include "C2OMXNode.h"
+#include "CCodec.h"
+#include "CCodecBufferChannel.h"
+#include "InputSurfaceWrapper.h"
+#include "Omx2IGraphicBufferSource.h"
+
+extern "C" android::PersistentSurface *CreateInputSurface();
+
+namespace android {
+
+using namespace std::chrono_literals;
+using ::android::hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer;
+using android::base::StringPrintf;
+using BGraphicBufferSource = ::android::IGraphicBufferSource;
+using ::android::hardware::media::c2::V1_0::IInputSurface;
+
+namespace {
+
+class CCodecWatchdog : public AHandler {
+private:
+    enum {
+        kWhatWatch,
+    };
+    constexpr static int64_t kWatchIntervalUs = 3300000;  // 3.3 secs
+
+public:
+    static sp<CCodecWatchdog> getInstance() {
+        static sp<CCodecWatchdog> instance(new CCodecWatchdog);
+        static std::once_flag flag;
+        // Call Init() only once.
+        std::call_once(flag, Init, instance);
+        return instance;
+    }
+
+    ~CCodecWatchdog() = default;
+
+    void watch(sp<CCodec> codec) {
+        bool shouldPost = false;
+        {
+            Mutexed<std::set<wp<CCodec>>>::Locked codecs(mCodecsToWatch);
+            // If a watch message is in flight, piggy-back this instance as well.
+            // Otherwise, post a new watch message.
+            shouldPost = codecs->empty();
+            codecs->emplace(codec);
+        }
+        if (shouldPost) {
+            ALOGV("posting watch message");
+            (new AMessage(kWhatWatch, this))->post(kWatchIntervalUs);
+        }
+    }
+
+protected:
+    void onMessageReceived(const sp<AMessage> &msg) {
+        switch (msg->what()) {
+            case kWhatWatch: {
+                Mutexed<std::set<wp<CCodec>>>::Locked codecs(mCodecsToWatch);
+                ALOGV("watch for %zu codecs", codecs->size());
+                for (auto it = codecs->begin(); it != codecs->end(); ++it) {
+                    sp<CCodec> codec = it->promote();
+                    if (codec == nullptr) {
+                        continue;
+                    }
+                    codec->initiateReleaseIfStuck();
+                }
+                codecs->clear();
+                break;
+            }
+
+            default: {
+                TRESPASS("CCodecWatchdog: unrecognized message");
+            }
+        }
+    }
+
+private:
+    CCodecWatchdog() : mLooper(new ALooper) {}
+
+    static void Init(const sp<CCodecWatchdog> &thiz) {
+        ALOGV("Init");
+        thiz->mLooper->setName("CCodecWatchdog");
+        thiz->mLooper->registerHandler(thiz);
+        thiz->mLooper->start();
+    }
+
+    sp<ALooper> mLooper;
+
+    Mutexed<std::set<wp<CCodec>>> mCodecsToWatch;
+};
+
+class C2InputSurfaceWrapper : public InputSurfaceWrapper {
+public:
+    explicit C2InputSurfaceWrapper(
+            const std::shared_ptr<Codec2Client::InputSurface> &surface) :
+        mSurface(surface) {
+    }
+
+    ~C2InputSurfaceWrapper() override = default;
+
+    status_t connect(const std::shared_ptr<Codec2Client::Component> &comp) override {
+        if (mConnection != nullptr) {
+            return ALREADY_EXISTS;
+        }
+        return toStatusT(comp->connectToInputSurface(mSurface, &mConnection));
+    }
+
+    void disconnect() override {
+        if (mConnection != nullptr) {
+            mConnection->disconnect();
+            mConnection = nullptr;
+        }
+    }
+
+    status_t start() override {
+        // InputSurface does not distinguish started state
+        return OK;
+    }
+
+    status_t signalEndOfInputStream() override {
+        C2InputSurfaceEosTuning eos(true);
+        std::vector<std::unique_ptr<C2SettingResult>> failures;
+        c2_status_t err = mSurface->config({&eos}, C2_MAY_BLOCK, &failures);
+        if (err != C2_OK) {
+            return UNKNOWN_ERROR;
+        }
+        return OK;
+    }
+
+    status_t configure(Config &config __unused) {
+        // TODO
+        return OK;
+    }
+
+private:
+    std::shared_ptr<Codec2Client::InputSurface> mSurface;
+    std::shared_ptr<Codec2Client::InputSurfaceConnection> mConnection;
+};
+
+class GraphicBufferSourceWrapper : public InputSurfaceWrapper {
+public:
+//    explicit GraphicBufferSourceWrapper(const sp<BGraphicBufferSource> &source) : mSource(source) {}
+    GraphicBufferSourceWrapper(
+            const sp<BGraphicBufferSource> &source,
+            uint32_t width,
+            uint32_t height,
+            uint64_t usage)
+        : mSource(source), mWidth(width), mHeight(height) {
+        mDataSpace = HAL_DATASPACE_BT709;
+        mConfig.mUsage = usage;
+    }
+    ~GraphicBufferSourceWrapper() override = default;
+
+    status_t connect(const std::shared_ptr<Codec2Client::Component> &comp) override {
+        mNode = new C2OMXNode(comp);
+        mNode->setFrameSize(mWidth, mHeight);
+
+        // Usage is queried during configure(), so setting it beforehand.
+        OMX_U32 usage = mConfig.mUsage & 0xFFFFFFFF;
+        (void)mNode->setParameter(
+                (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
+                &usage, sizeof(usage));
+
+        // NOTE: we do not use/pass through color aspects from GraphicBufferSource as we
+        // communicate that directly to the component.
+        mSource->configure(mNode, mDataSpace);
+        return OK;
+    }
+
+    void disconnect() override {
+        if (mNode == nullptr) {
+            return;
+        }
+        sp<IOMXBufferSource> source = mNode->getSource();
+        if (source == nullptr) {
+            ALOGD("GBSWrapper::disconnect: node is not configured with OMXBufferSource.");
+            return;
+        }
+        source->onOmxIdle();
+        source->onOmxLoaded();
+        mNode.clear();
+    }
+
+    status_t GetStatus(const binder::Status &status) {
+        status_t err = OK;
+        if (!status.isOk()) {
+            err = status.serviceSpecificErrorCode();
+            if (err == OK) {
+                err = status.transactionError();
+                if (err == OK) {
+                    // binder status failed, but there is no servie or transaction error
+                    err = UNKNOWN_ERROR;
+                }
+            }
+        }
+        return err;
+    }
+
+    status_t start() override {
+        sp<IOMXBufferSource> source = mNode->getSource();
+        if (source == nullptr) {
+            return NO_INIT;
+        }
+        constexpr size_t kNumSlots = 16;
+        for (size_t i = 0; i < kNumSlots; ++i) {
+            source->onInputBufferAdded(i);
+        }
+
+        source->onOmxExecuting();
+        return OK;
+    }
+
+    status_t signalEndOfInputStream() override {
+        return GetStatus(mSource->signalEndOfInputStream());
+    }
+
+    status_t configure(Config &config) {
+        std::stringstream status;
+        status_t err = OK;
+
+        // handle each configuration granually, in case we need to handle part of the configuration
+        // elsewhere
+
+        // TRICKY: we do not unset frame delay repeating
+        if (config.mMinFps > 0 && config.mMinFps != mConfig.mMinFps) {
+            int64_t us = 1e6 / config.mMinFps + 0.5;
+            status_t res = GetStatus(mSource->setRepeatPreviousFrameDelayUs(us));
+            status << " minFps=" << config.mMinFps << " => repeatDelayUs=" << us;
+            if (res != OK) {
+                status << " (=> " << asString(res) << ")";
+                err = res;
+            }
+            mConfig.mMinFps = config.mMinFps;
+        }
+
+        // pts gap
+        if (config.mMinAdjustedFps > 0 || config.mFixedAdjustedFps > 0) {
+            if (mNode != nullptr) {
+                OMX_PARAM_U32TYPE ptrGapParam = {};
+                ptrGapParam.nSize = sizeof(OMX_PARAM_U32TYPE);
+                float gap = (config.mMinAdjustedFps > 0)
+                        ? c2_min(INT32_MAX + 0., 1e6 / config.mMinAdjustedFps + 0.5)
+                        : c2_max(0. - INT32_MAX, -1e6 / config.mFixedAdjustedFps - 0.5);
+                // float -> uint32_t is undefined if the value is negative.
+                // First convert to int32_t to ensure the expected behavior.
+                ptrGapParam.nU32 = int32_t(gap);
+                (void)mNode->setParameter(
+                        (OMX_INDEXTYPE)OMX_IndexParamMaxFrameDurationForBitrateControl,
+                        &ptrGapParam, sizeof(ptrGapParam));
+            }
+        }
+
+        // max fps
+        // TRICKY: we do not unset max fps to 0 unless using fixed fps
+        if ((config.mMaxFps > 0 || (config.mFixedAdjustedFps > 0 && config.mMaxFps == -1))
+                && config.mMaxFps != mConfig.mMaxFps) {
+            status_t res = GetStatus(mSource->setMaxFps(config.mMaxFps));
+            status << " maxFps=" << config.mMaxFps;
+            if (res != OK) {
+                status << " (=> " << asString(res) << ")";
+                err = res;
+            }
+            mConfig.mMaxFps = config.mMaxFps;
+        }
+
+        if (config.mTimeOffsetUs != mConfig.mTimeOffsetUs) {
+            status_t res = GetStatus(mSource->setTimeOffsetUs(config.mTimeOffsetUs));
+            status << " timeOffset " << config.mTimeOffsetUs << "us";
+            if (res != OK) {
+                status << " (=> " << asString(res) << ")";
+                err = res;
+            }
+            mConfig.mTimeOffsetUs = config.mTimeOffsetUs;
+        }
+
+        if (config.mCaptureFps != mConfig.mCaptureFps || config.mCodedFps != mConfig.mCodedFps) {
+            status_t res =
+                GetStatus(mSource->setTimeLapseConfig(config.mCodedFps, config.mCaptureFps));
+            status << " timeLapse " << config.mCaptureFps << "fps as " << config.mCodedFps << "fps";
+            if (res != OK) {
+                status << " (=> " << asString(res) << ")";
+                err = res;
+            }
+            mConfig.mCaptureFps = config.mCaptureFps;
+            mConfig.mCodedFps = config.mCodedFps;
+        }
+
+        if (config.mStartAtUs != mConfig.mStartAtUs
+                || (config.mStopped != mConfig.mStopped && !config.mStopped)) {
+            status_t res = GetStatus(mSource->setStartTimeUs(config.mStartAtUs));
+            status << " start at " << config.mStartAtUs << "us";
+            if (res != OK) {
+                status << " (=> " << asString(res) << ")";
+                err = res;
+            }
+            mConfig.mStartAtUs = config.mStartAtUs;
+            mConfig.mStopped = config.mStopped;
+        }
+
+        // suspend-resume
+        if (config.mSuspended != mConfig.mSuspended) {
+            status_t res = GetStatus(mSource->setSuspend(config.mSuspended, config.mSuspendAtUs));
+            status << " " << (config.mSuspended ? "suspend" : "resume")
+                    << " at " << config.mSuspendAtUs << "us";
+            if (res != OK) {
+                status << " (=> " << asString(res) << ")";
+                err = res;
+            }
+            mConfig.mSuspended = config.mSuspended;
+            mConfig.mSuspendAtUs = config.mSuspendAtUs;
+        }
+
+        if (config.mStopped != mConfig.mStopped && config.mStopped) {
+            status_t res = GetStatus(mSource->setStopTimeUs(config.mStopAtUs));
+            status << " stop at " << config.mStopAtUs << "us";
+            if (res != OK) {
+                status << " (=> " << asString(res) << ")";
+                err = res;
+            } else {
+                status << " delayUs";
+                res = GetStatus(mSource->getStopTimeOffsetUs(&config.mInputDelayUs));
+                if (res != OK) {
+                    status << " (=> " << asString(res) << ")";
+                } else {
+                    status << "=" << config.mInputDelayUs << "us";
+                }
+                mConfig.mInputDelayUs = config.mInputDelayUs;
+            }
+            mConfig.mStopAtUs = config.mStopAtUs;
+            mConfig.mStopped = config.mStopped;
+        }
+
+        // color aspects (android._color-aspects)
+
+        // consumer usage is queried earlier.
+
+        ALOGD("ISConfig%s", status.str().c_str());
+        return err;
+    }
+
+    void onInputBufferDone(c2_cntr64_t index) override {
+        mNode->onInputBufferDone(index);
+    }
+
+private:
+    sp<BGraphicBufferSource> mSource;
+    sp<C2OMXNode> mNode;
+    uint32_t mWidth;
+    uint32_t mHeight;
+    Config mConfig;
+};
+
+class Codec2ClientInterfaceWrapper : public C2ComponentStore {
+    std::shared_ptr<Codec2Client> mClient;
+
+public:
+    Codec2ClientInterfaceWrapper(std::shared_ptr<Codec2Client> client)
+        : mClient(client) { }
+
+    virtual ~Codec2ClientInterfaceWrapper() = default;
+
+    virtual c2_status_t config_sm(
+            const std::vector<C2Param *> &params,
+            std::vector<std::unique_ptr<C2SettingResult>> *const failures) {
+        return mClient->config(params, C2_MAY_BLOCK, failures);
+    };
+
+    virtual c2_status_t copyBuffer(
+            std::shared_ptr<C2GraphicBuffer>,
+            std::shared_ptr<C2GraphicBuffer>) {
+        return C2_OMITTED;
+    }
+
+    virtual c2_status_t createComponent(
+            C2String, std::shared_ptr<C2Component> *const component) {
+        component->reset();
+        return C2_OMITTED;
+    }
+
+    virtual c2_status_t createInterface(
+            C2String, std::shared_ptr<C2ComponentInterface> *const interface) {
+        interface->reset();
+        return C2_OMITTED;
+    }
+
+    virtual c2_status_t query_sm(
+            const std::vector<C2Param *> &stackParams,
+            const std::vector<C2Param::Index> &heapParamIndices,
+            std::vector<std::unique_ptr<C2Param>> *const heapParams) const {
+        return mClient->query(stackParams, heapParamIndices, C2_MAY_BLOCK, heapParams);
+    }
+
+    virtual c2_status_t querySupportedParams_nb(
+            std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const {
+        return mClient->querySupportedParams(params);
+    }
+
+    virtual c2_status_t querySupportedValues_sm(
+            std::vector<C2FieldSupportedValuesQuery> &fields) const {
+        return mClient->querySupportedValues(fields, C2_MAY_BLOCK);
+    }
+
+    virtual C2String getName() const {
+        return mClient->getName();
+    }
+
+    virtual std::shared_ptr<C2ParamReflector> getParamReflector() const {
+        return mClient->getParamReflector();
+    }
+
+    virtual std::vector<std::shared_ptr<const C2Component::Traits>> listComponents() {
+        return std::vector<std::shared_ptr<const C2Component::Traits>>();
+    }
+};
+
+}  // namespace
+
+// CCodec::ClientListener
+
+struct CCodec::ClientListener : public Codec2Client::Listener {
+
+    explicit ClientListener(const wp<CCodec> &codec) : mCodec(codec) {}
+
+    virtual void onWorkDone(
+            const std::weak_ptr<Codec2Client::Component>& component,
+            std::list<std::unique_ptr<C2Work>>& workItems) override {
+        (void)component;
+        sp<CCodec> codec(mCodec.promote());
+        if (!codec) {
+            return;
+        }
+        codec->onWorkDone(workItems);
+    }
+
+    virtual void onTripped(
+            const std::weak_ptr<Codec2Client::Component>& component,
+            const std::vector<std::shared_ptr<C2SettingResult>>& settingResult
+            ) override {
+        // TODO
+        (void)component;
+        (void)settingResult;
+    }
+
+    virtual void onError(
+            const std::weak_ptr<Codec2Client::Component>& component,
+            uint32_t errorCode) override {
+        // TODO
+        (void)component;
+        (void)errorCode;
+    }
+
+    virtual void onDeath(
+            const std::weak_ptr<Codec2Client::Component>& component) override {
+        { // Log the death of the component.
+            std::shared_ptr<Codec2Client::Component> comp = component.lock();
+            if (!comp) {
+                ALOGE("Codec2 component died.");
+            } else {
+                ALOGE("Codec2 component \"%s\" died.", comp->getName().c_str());
+            }
+        }
+
+        // Report to MediaCodec.
+        sp<CCodec> codec(mCodec.promote());
+        if (!codec || !codec->mCallback) {
+            return;
+        }
+        codec->mCallback->onError(DEAD_OBJECT, ACTION_CODE_FATAL);
+    }
+
+    virtual void onFrameRendered(uint64_t bufferQueueId,
+                                 int32_t slotId,
+                                 int64_t timestampNs) override {
+        // TODO: implement
+        (void)bufferQueueId;
+        (void)slotId;
+        (void)timestampNs;
+    }
+
+    virtual void onInputBufferDone(
+            uint64_t frameIndex, size_t arrayIndex) override {
+        sp<CCodec> codec(mCodec.promote());
+        if (codec) {
+            codec->onInputBufferDone(frameIndex, arrayIndex);
+        }
+    }
+
+private:
+    wp<CCodec> mCodec;
+};
+
+// CCodecCallbackImpl
+
+class CCodecCallbackImpl : public CCodecCallback {
+public:
+    explicit CCodecCallbackImpl(CCodec *codec) : mCodec(codec) {}
+    ~CCodecCallbackImpl() override = default;
+
+    void onError(status_t err, enum ActionCode actionCode) override {
+        mCodec->mCallback->onError(err, actionCode);
+    }
+
+    void onOutputFramesRendered(int64_t mediaTimeUs, nsecs_t renderTimeNs) override {
+        mCodec->mCallback->onOutputFramesRendered(
+                {RenderedFrameInfo(mediaTimeUs, renderTimeNs)});
+    }
+
+    void onOutputBuffersChanged() override {
+        mCodec->mCallback->onOutputBuffersChanged();
+    }
+
+private:
+    CCodec *mCodec;
+};
+
+// CCodec
+
+CCodec::CCodec()
+    : mChannel(new CCodecBufferChannel(std::make_shared<CCodecCallbackImpl>(this))) {
+}
+
+CCodec::~CCodec() {
+}
+
+std::shared_ptr<BufferChannelBase> CCodec::getBufferChannel() {
+    return mChannel;
+}
+
+status_t CCodec::tryAndReportOnError(std::function<status_t()> job) {
+    status_t err = job();
+    if (err != C2_OK) {
+        mCallback->onError(err, ACTION_CODE_FATAL);
+    }
+    return err;
+}
+
+void CCodec::initiateAllocateComponent(const sp<AMessage> &msg) {
+    auto setAllocating = [this] {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() != RELEASED) {
+            return INVALID_OPERATION;
+        }
+        state->set(ALLOCATING);
+        return OK;
+    };
+    if (tryAndReportOnError(setAllocating) != OK) {
+        return;
+    }
+
+    sp<RefBase> codecInfo;
+    CHECK(msg->findObject("codecInfo", &codecInfo));
+    // For Codec 2.0 components, componentName == codecInfo->getCodecName().
+
+    sp<AMessage> allocMsg(new AMessage(kWhatAllocate, this));
+    allocMsg->setObject("codecInfo", codecInfo);
+    allocMsg->post();
+}
+
+void CCodec::allocate(const sp<MediaCodecInfo> &codecInfo) {
+    if (codecInfo == nullptr) {
+        mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
+        return;
+    }
+    ALOGD("allocate(%s)", codecInfo->getCodecName());
+    mClientListener.reset(new ClientListener(this));
+
+    AString componentName = codecInfo->getCodecName();
+    std::shared_ptr<Codec2Client> client;
+
+    // set up preferred component store to access vendor store parameters
+    client = Codec2Client::CreateFromService("default");
+    if (client) {
+        ALOGI("setting up '%s' as default (vendor) store", client->getServiceName().c_str());
+        SetPreferredCodec2ComponentStore(
+                std::make_shared<Codec2ClientInterfaceWrapper>(client));
+    }
+
+    std::shared_ptr<Codec2Client::Component> comp =
+            Codec2Client::CreateComponentByName(
+            componentName.c_str(),
+            mClientListener,
+            &client);
+    if (!comp) {
+        ALOGE("Failed Create component: %s", componentName.c_str());
+        Mutexed<State>::Locked state(mState);
+        state->set(RELEASED);
+        state.unlock();
+        mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
+        state.lock();
+        return;
+    }
+    ALOGI("Created component [%s]", componentName.c_str());
+    mChannel->setComponent(comp);
+    auto setAllocated = [this, comp, client] {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() != ALLOCATING) {
+            state->set(RELEASED);
+            return UNKNOWN_ERROR;
+        }
+        state->set(ALLOCATED);
+        state->comp = comp;
+        mClient = client;
+        return OK;
+    };
+    if (tryAndReportOnError(setAllocated) != OK) {
+        return;
+    }
+
+    // initialize config here in case setParameters is called prior to configure
+    Mutexed<Config>::Locked config(mConfig);
+    status_t err = config->initialize(mClient, comp);
+    if (err != OK) {
+        ALOGW("Failed to initialize configuration support");
+        // TODO: report error once we complete implementation.
+    }
+    config->queryConfiguration(comp);
+
+    mCallback->onComponentAllocated(componentName.c_str());
+}
+
+void CCodec::initiateConfigureComponent(const sp<AMessage> &format) {
+    auto checkAllocated = [this] {
+        Mutexed<State>::Locked state(mState);
+        return (state->get() != ALLOCATED) ? UNKNOWN_ERROR : OK;
+    };
+    if (tryAndReportOnError(checkAllocated) != OK) {
+        return;
+    }
+
+    sp<AMessage> msg(new AMessage(kWhatConfigure, this));
+    msg->setMessage("format", format);
+    msg->post();
+}
+
+void CCodec::configure(const sp<AMessage> &msg) {
+    std::shared_ptr<Codec2Client::Component> comp;
+    auto checkAllocated = [this, &comp] {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() != ALLOCATED) {
+            state->set(RELEASED);
+            return UNKNOWN_ERROR;
+        }
+        comp = state->comp;
+        return OK;
+    };
+    if (tryAndReportOnError(checkAllocated) != OK) {
+        return;
+    }
+
+    auto doConfig = [msg, comp, this]() -> status_t {
+        AString mime;
+        if (!msg->findString("mime", &mime)) {
+            return BAD_VALUE;
+        }
+
+        int32_t encoder;
+        if (!msg->findInt32("encoder", &encoder)) {
+            encoder = false;
+        }
+
+        // TODO: read from intf()
+        if ((!encoder) != (comp->getName().find("encoder") == std::string::npos)) {
+            return UNKNOWN_ERROR;
+        }
+
+        int32_t storeMeta;
+        if (encoder
+                && msg->findInt32("android._input-metadata-buffer-type", &storeMeta)
+                && storeMeta != kMetadataBufferTypeInvalid) {
+            if (storeMeta != kMetadataBufferTypeANWBuffer) {
+                ALOGD("Only ANW buffers are supported for legacy metadata mode");
+                return BAD_VALUE;
+            }
+            mChannel->setMetaMode(CCodecBufferChannel::MODE_ANW);
+        }
+
+        sp<RefBase> obj;
+        sp<Surface> surface;
+        if (msg->findObject("native-window", &obj)) {
+            surface = static_cast<Surface *>(obj.get());
+            setSurface(surface);
+        }
+
+        Mutexed<Config>::Locked config(mConfig);
+        config->mUsingSurface = surface != nullptr;
+
+        // Enforce required parameters
+        int32_t i32;
+        float flt;
+        if (config->mDomain & Config::IS_AUDIO) {
+            if (!msg->findInt32(KEY_SAMPLE_RATE, &i32)) {
+                ALOGD("sample rate is missing, which is required for audio components.");
+                return BAD_VALUE;
+            }
+            if (!msg->findInt32(KEY_CHANNEL_COUNT, &i32)) {
+                ALOGD("channel count is missing, which is required for audio components.");
+                return BAD_VALUE;
+            }
+            if ((config->mDomain & Config::IS_ENCODER)
+                    && !mime.equalsIgnoreCase(MEDIA_MIMETYPE_AUDIO_FLAC)
+                    && !msg->findInt32(KEY_BIT_RATE, &i32)
+                    && !msg->findFloat(KEY_BIT_RATE, &flt)) {
+                ALOGD("bitrate is missing, which is required for audio encoders.");
+                return BAD_VALUE;
+            }
+        }
+        if (config->mDomain & (Config::IS_IMAGE | Config::IS_VIDEO)) {
+            if (!msg->findInt32(KEY_WIDTH, &i32)) {
+                ALOGD("width is missing, which is required for image/video components.");
+                return BAD_VALUE;
+            }
+            if (!msg->findInt32(KEY_HEIGHT, &i32)) {
+                ALOGD("height is missing, which is required for image/video components.");
+                return BAD_VALUE;
+            }
+            if ((config->mDomain & Config::IS_ENCODER) && (config->mDomain & Config::IS_VIDEO)) {
+                int32_t mode = BITRATE_MODE_VBR;
+                if (msg->findInt32(KEY_BITRATE_MODE, &mode) && mode == BITRATE_MODE_CQ) {
+                    if (!msg->findInt32(KEY_QUALITY, &i32)) {
+                        ALOGD("quality is missing, which is required for video encoders in CQ.");
+                        return BAD_VALUE;
+                    }
+                } else {
+                    if (!msg->findInt32(KEY_BIT_RATE, &i32)
+                            && !msg->findFloat(KEY_BIT_RATE, &flt)) {
+                        ALOGD("bitrate is missing, which is required for video encoders.");
+                        return BAD_VALUE;
+                    }
+                }
+                if (!msg->findInt32(KEY_I_FRAME_INTERVAL, &i32)
+                        && !msg->findFloat(KEY_I_FRAME_INTERVAL, &flt)) {
+                    ALOGD("I frame interval is missing, which is required for video encoders.");
+                    return BAD_VALUE;
+                }
+                if (!msg->findInt32(KEY_FRAME_RATE, &i32)
+                        && !msg->findFloat(KEY_FRAME_RATE, &flt)) {
+                    ALOGD("frame rate is missing, which is required for video encoders.");
+                    return BAD_VALUE;
+                }
+            }
+        }
+
+        /*
+         * Handle input surface configuration
+         */
+        if ((config->mDomain & (Config::IS_VIDEO | Config::IS_IMAGE))
+                && (config->mDomain & Config::IS_ENCODER)) {
+            config->mISConfig.reset(new InputSurfaceWrapper::Config{});
+            {
+                config->mISConfig->mMinFps = 0;
+                int64_t value;
+                if (msg->findInt64(KEY_REPEAT_PREVIOUS_FRAME_AFTER, &value) && value > 0) {
+                    config->mISConfig->mMinFps = 1e6 / value;
+                }
+                if (!msg->findFloat(
+                        KEY_MAX_FPS_TO_ENCODER, &config->mISConfig->mMaxFps)) {
+                    config->mISConfig->mMaxFps = -1;
+                }
+                config->mISConfig->mMinAdjustedFps = 0;
+                config->mISConfig->mFixedAdjustedFps = 0;
+                if (msg->findInt64(KEY_MAX_PTS_GAP_TO_ENCODER, &value)) {
+                    if (value < 0 && value >= INT32_MIN) {
+                        config->mISConfig->mFixedAdjustedFps = -1e6 / value;
+                        config->mISConfig->mMaxFps = -1;
+                    } else if (value > 0 && value <= INT32_MAX) {
+                        config->mISConfig->mMinAdjustedFps = 1e6 / value;
+                    }
+                }
+            }
+
+            {
+                double value;
+                if (msg->findDouble("time-lapse-fps", &value)) {
+                    config->mISConfig->mCaptureFps = value;
+                    (void)msg->findAsFloat(KEY_FRAME_RATE, &config->mISConfig->mCodedFps);
+                }
+            }
+
+            {
+                config->mISConfig->mSuspended = false;
+                config->mISConfig->mSuspendAtUs = -1;
+                int32_t value;
+                if (msg->findInt32(KEY_CREATE_INPUT_SURFACE_SUSPENDED, &value) && value) {
+                    config->mISConfig->mSuspended = true;
+                }
+            }
+            config->mISConfig->mUsage = 0;
+        }
+
+        /*
+         * Handle desired color format.
+         */
+        if ((config->mDomain & (Config::IS_VIDEO | Config::IS_IMAGE))) {
+            int32_t format = -1;
+            if (!msg->findInt32(KEY_COLOR_FORMAT, &format)) {
+                /*
+                 * Also handle default color format (encoders require color format, so this is only
+                 * needed for decoders.
+                 */
+                if (!(config->mDomain & Config::IS_ENCODER)) {
+                    format = (surface == nullptr) ? COLOR_FormatYUV420Planar : COLOR_FormatSurface;
+                }
+            }
+
+            if (format >= 0) {
+                msg->setInt32("android._color-format", format);
+            }
+        }
+
+        std::vector<std::unique_ptr<C2Param>> configUpdate;
+        // NOTE: We used to ignore "video-bitrate" at configure; replicate
+        //       the behavior here.
+        sp<AMessage> sdkParams = msg;
+        int32_t videoBitrate;
+        if (sdkParams->findInt32(PARAMETER_KEY_VIDEO_BITRATE, &videoBitrate)) {
+            sdkParams = msg->dup();
+            sdkParams->removeEntryAt(sdkParams->findEntryByName(PARAMETER_KEY_VIDEO_BITRATE));
+        }
+        status_t err = config->getConfigUpdateFromSdkParams(
+                comp, sdkParams, Config::IS_CONFIG, C2_DONT_BLOCK, &configUpdate);
+        if (err != OK) {
+            ALOGW("failed to convert configuration to c2 params");
+        }
+
+        int32_t maxBframes = 0;
+        if ((config->mDomain & Config::IS_ENCODER)
+                && (config->mDomain & Config::IS_VIDEO)
+                && sdkParams->findInt32(KEY_MAX_B_FRAMES, &maxBframes)
+                && maxBframes > 0) {
+            std::unique_ptr<C2StreamGopTuning::output> gop =
+                C2StreamGopTuning::output::AllocUnique(2 /* flexCount */, 0u /* stream */);
+            gop->m.values[0] = { P_FRAME, UINT32_MAX };
+            gop->m.values[1] = {
+                C2Config::picture_type_t(P_FRAME | B_FRAME),
+                uint32_t(maxBframes)
+            };
+            configUpdate.push_back(std::move(gop));
+        }
+
+        err = config->setParameters(comp, configUpdate, C2_DONT_BLOCK);
+        if (err != OK) {
+            ALOGW("failed to configure c2 params");
+            return err;
+        }
+
+        std::vector<std::unique_ptr<C2Param>> params;
+        C2StreamUsageTuning::input usage(0u, 0u);
+        C2StreamMaxBufferSizeInfo::input maxInputSize(0u, 0u);
+        C2PrependHeaderModeSetting prepend(PREPEND_HEADER_TO_NONE);
+
+        std::initializer_list<C2Param::Index> indices {
+        };
+        c2_status_t c2err = comp->query(
+                { &usage, &maxInputSize, &prepend },
+                indices,
+                C2_DONT_BLOCK,
+                &params);
+        if (c2err != C2_OK && c2err != C2_BAD_INDEX) {
+            ALOGE("Failed to query component interface: %d", c2err);
+            return UNKNOWN_ERROR;
+        }
+        if (params.size() != indices.size()) {
+            ALOGE("Component returns wrong number of params: expected %zu actual %zu",
+                    indices.size(), params.size());
+            return UNKNOWN_ERROR;
+        }
+        if (usage) {
+            if (usage.value & C2MemoryUsage::CPU_READ) {
+                config->mInputFormat->setInt32("using-sw-read-often", true);
+            }
+            if (config->mISConfig) {
+                C2AndroidMemoryUsage androidUsage(C2MemoryUsage(usage.value));
+                config->mISConfig->mUsage = androidUsage.asGrallocUsage();
+            }
+        }
+
+        // NOTE: we don't blindly use client specified input size if specified as clients
+        // at times specify too small size. Instead, mimic the behavior from OMX, where the
+        // client specified size is only used to ask for bigger buffers than component suggested
+        // size.
+        int32_t clientInputSize = 0;
+        bool clientSpecifiedInputSize =
+            msg->findInt32(KEY_MAX_INPUT_SIZE, &clientInputSize) && clientInputSize > 0;
+        // TEMP: enforce minimum buffer size of 1MB for video decoders
+        // and 16K / 4K for audio encoders/decoders
+        if (maxInputSize.value == 0) {
+            if (config->mDomain & Config::IS_AUDIO) {
+                maxInputSize.value = encoder ? 16384 : 4096;
+            } else if (!encoder) {
+                maxInputSize.value = 1048576u;
+            }
+        }
+
+        // verify that CSD fits into this size (if defined)
+        if ((config->mDomain & Config::IS_DECODER) && maxInputSize.value > 0) {
+            sp<ABuffer> csd;
+            for (size_t ix = 0; msg->findBuffer(StringPrintf("csd-%zu", ix).c_str(), &csd); ++ix) {
+                if (csd && csd->size() > maxInputSize.value) {
+                    maxInputSize.value = csd->size();
+                }
+            }
+        }
+
+        // TODO: do this based on component requiring linear allocator for input
+        if ((config->mDomain & Config::IS_DECODER) || (config->mDomain & Config::IS_AUDIO)) {
+            if (clientSpecifiedInputSize) {
+                // Warn that we're overriding client's max input size if necessary.
+                if ((uint32_t)clientInputSize < maxInputSize.value) {
+                    ALOGD("client requested max input size %d, which is smaller than "
+                          "what component recommended (%u); overriding with component "
+                          "recommendation.", clientInputSize, maxInputSize.value);
+                    ALOGW("This behavior is subject to change. It is recommended that "
+                          "app developers double check whether the requested "
+                          "max input size is in reasonable range.");
+                } else {
+                    maxInputSize.value = clientInputSize;
+                }
+            }
+            // Pass max input size on input format to the buffer channel (if supplied by the
+            // component or by a default)
+            if (maxInputSize.value) {
+                config->mInputFormat->setInt32(
+                        KEY_MAX_INPUT_SIZE,
+                        (int32_t)(c2_min(maxInputSize.value, uint32_t(INT32_MAX))));
+            }
+        }
+
+        int32_t clientPrepend;
+        if ((config->mDomain & Config::IS_VIDEO)
+                && (config->mDomain & Config::IS_ENCODER)
+                && msg->findInt32(KEY_PREPEND_HEADERS_TO_SYNC_FRAMES, &clientPrepend)
+                && clientPrepend
+                && (!prepend || prepend.value != PREPEND_HEADER_TO_ALL_SYNC)) {
+            ALOGE("Failed to set KEY_PREPEND_HEADERS_TO_SYNC_FRAMES");
+            return BAD_VALUE;
+        }
+
+        if ((config->mDomain & (Config::IS_VIDEO | Config::IS_IMAGE))) {
+            // propagate HDR static info to output format for both encoders and decoders
+            // if component supports this info, we will update from component, but only the raw port,
+            // so don't propagate if component already filled it in.
+            sp<ABuffer> hdrInfo;
+            if (msg->findBuffer(KEY_HDR_STATIC_INFO, &hdrInfo)
+                    && !config->mOutputFormat->findBuffer(KEY_HDR_STATIC_INFO, &hdrInfo)) {
+                config->mOutputFormat->setBuffer(KEY_HDR_STATIC_INFO, hdrInfo);
+            }
+
+            // Set desired color format from configuration parameter
+            int32_t format;
+            if (msg->findInt32("android._color-format", &format)) {
+                if (config->mDomain & Config::IS_ENCODER) {
+                    config->mInputFormat->setInt32(KEY_COLOR_FORMAT, format);
+                } else {
+                    config->mOutputFormat->setInt32(KEY_COLOR_FORMAT, format);
+                }
+            }
+        }
+
+        // propagate encoder delay and padding to output format
+        if ((config->mDomain & Config::IS_DECODER) && (config->mDomain & Config::IS_AUDIO)) {
+            int delay = 0;
+            if (msg->findInt32("encoder-delay", &delay)) {
+                config->mOutputFormat->setInt32("encoder-delay", delay);
+            }
+            int padding = 0;
+            if (msg->findInt32("encoder-padding", &padding)) {
+                config->mOutputFormat->setInt32("encoder-padding", padding);
+            }
+        }
+
+        // set channel-mask
+        if (config->mDomain & Config::IS_AUDIO) {
+            int32_t mask;
+            if (msg->findInt32(KEY_CHANNEL_MASK, &mask)) {
+                if (config->mDomain & Config::IS_ENCODER) {
+                    config->mInputFormat->setInt32(KEY_CHANNEL_MASK, mask);
+                } else {
+                    config->mOutputFormat->setInt32(KEY_CHANNEL_MASK, mask);
+                }
+            }
+        }
+
+        ALOGD("setup formats input: %s and output: %s",
+                config->mInputFormat->debugString().c_str(),
+                config->mOutputFormat->debugString().c_str());
+        return OK;
+    };
+    if (tryAndReportOnError(doConfig) != OK) {
+        return;
+    }
+
+    Mutexed<Config>::Locked config(mConfig);
+
+    mCallback->onComponentConfigured(config->mInputFormat, config->mOutputFormat);
+}
+
+void CCodec::initiateCreateInputSurface() {
+    status_t err = [this] {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() != ALLOCATED) {
+            return UNKNOWN_ERROR;
+        }
+        // TODO: read it from intf() properly.
+        if (state->comp->getName().find("encoder") == std::string::npos) {
+            return INVALID_OPERATION;
+        }
+        return OK;
+    }();
+    if (err != OK) {
+        mCallback->onInputSurfaceCreationFailed(err);
+        return;
+    }
+
+    (new AMessage(kWhatCreateInputSurface, this))->post();
+}
+
+sp<PersistentSurface> CCodec::CreateOmxInputSurface() {
+    using namespace android::hardware::media::omx::V1_0;
+    using namespace android::hardware::media::omx::V1_0::utils;
+    using namespace android::hardware::graphics::bufferqueue::V1_0::utils;
+    typedef android::hardware::media::omx::V1_0::Status OmxStatus;
+    android::sp<IOmx> omx = IOmx::getService();
+    typedef android::hardware::graphics::bufferqueue::V1_0::
+            IGraphicBufferProducer HGraphicBufferProducer;
+    typedef android::hardware::media::omx::V1_0::
+            IGraphicBufferSource HGraphicBufferSource;
+    OmxStatus s;
+    android::sp<HGraphicBufferProducer> gbp;
+    android::sp<HGraphicBufferSource> gbs;
+
+    using ::android::hardware::Return;
+    Return<void> transStatus = omx->createInputSurface(
+            [&s, &gbp, &gbs](
+                    OmxStatus status,
+                    const android::sp<HGraphicBufferProducer>& producer,
+                    const android::sp<HGraphicBufferSource>& source) {
+                s = status;
+                gbp = producer;
+                gbs = source;
+            });
+    if (transStatus.isOk() && s == OmxStatus::OK) {
+        return new PersistentSurface(
+                new H2BGraphicBufferProducer(gbp),
+                sp<::android::IGraphicBufferSource>(new LWGraphicBufferSource(gbs)));
+    }
+
+    return nullptr;
+}
+
+sp<PersistentSurface> CCodec::CreateCompatibleInputSurface() {
+    sp<PersistentSurface> surface(CreateInputSurface());
+
+    if (surface == nullptr) {
+        surface = CreateOmxInputSurface();
+    }
+
+    return surface;
+}
+
+void CCodec::createInputSurface() {
+    status_t err;
+    sp<IGraphicBufferProducer> bufferProducer;
+
+    sp<AMessage> inputFormat;
+    sp<AMessage> outputFormat;
+    uint64_t usage = 0;
+    {
+        Mutexed<Config>::Locked config(mConfig);
+        inputFormat = config->mInputFormat;
+        outputFormat = config->mOutputFormat;
+        usage = config->mISConfig ? config->mISConfig->mUsage : 0;
+    }
+
+    sp<PersistentSurface> persistentSurface = CreateCompatibleInputSurface();
+
+    if (persistentSurface->getHidlTarget()) {
+        sp<IInputSurface> hidlInputSurface = IInputSurface::castFrom(
+                persistentSurface->getHidlTarget());
+        if (!hidlInputSurface) {
+            ALOGE("Corrupted input surface");
+            mCallback->onInputSurfaceCreationFailed(UNKNOWN_ERROR);
+            return;
+        }
+        std::shared_ptr<Codec2Client::InputSurface> inputSurface =
+                std::make_shared<Codec2Client::InputSurface>(hidlInputSurface);
+        err = setupInputSurface(std::make_shared<C2InputSurfaceWrapper>(
+                inputSurface));
+        bufferProducer = inputSurface->getGraphicBufferProducer();
+    } else {
+        int32_t width = 0;
+        (void)outputFormat->findInt32("width", &width);
+        int32_t height = 0;
+        (void)outputFormat->findInt32("height", &height);
+        err = setupInputSurface(std::make_shared<GraphicBufferSourceWrapper>(
+                persistentSurface->getBufferSource(), width, height, usage));
+        bufferProducer = persistentSurface->getBufferProducer();
+    }
+
+    if (err != OK) {
+        ALOGE("Failed to set up input surface: %d", err);
+        mCallback->onInputSurfaceCreationFailed(err);
+        return;
+    }
+
+    mCallback->onInputSurfaceCreated(
+            inputFormat,
+            outputFormat,
+            new BufferProducerWrapper(bufferProducer));
+}
+
+status_t CCodec::setupInputSurface(const std::shared_ptr<InputSurfaceWrapper> &surface) {
+    Mutexed<Config>::Locked config(mConfig);
+    config->mUsingSurface = true;
+
+    // we are now using surface - apply default color aspects to input format - as well as
+    // get dataspace
+    bool inputFormatChanged = config->updateFormats(config->IS_INPUT);
+    ALOGD("input format %s to %s",
+            inputFormatChanged ? "changed" : "unchanged",
+            config->mInputFormat->debugString().c_str());
+
+    // configure dataspace
+    static_assert(sizeof(int32_t) == sizeof(android_dataspace), "dataspace size mismatch");
+    android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
+    (void)config->mInputFormat->findInt32("android._dataspace", (int32_t*)&dataSpace);
+    surface->setDataSpace(dataSpace);
+
+    status_t err = mChannel->setInputSurface(surface);
+    if (err != OK) {
+        // undo input format update
+        config->mUsingSurface = false;
+        (void)config->updateFormats(config->IS_INPUT);
+        return err;
+    }
+    config->mInputSurface = surface;
+
+    if (config->mISConfig) {
+        surface->configure(*config->mISConfig);
+    } else {
+        ALOGD("ISConfig: no configuration");
+    }
+
+    return OK;
+}
+
+void CCodec::initiateSetInputSurface(const sp<PersistentSurface> &surface) {
+    sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
+    msg->setObject("surface", surface);
+    msg->post();
+}
+
+void CCodec::setInputSurface(const sp<PersistentSurface> &surface) {
+    sp<AMessage> inputFormat;
+    sp<AMessage> outputFormat;
+    uint64_t usage = 0;
+    {
+        Mutexed<Config>::Locked config(mConfig);
+        inputFormat = config->mInputFormat;
+        outputFormat = config->mOutputFormat;
+        usage = config->mISConfig ? config->mISConfig->mUsage : 0;
+    }
+    auto hidlTarget = surface->getHidlTarget();
+    if (hidlTarget) {
+        sp<IInputSurface> inputSurface =
+                IInputSurface::castFrom(hidlTarget);
+        if (!inputSurface) {
+            ALOGE("Failed to set input surface: Corrupted surface.");
+            mCallback->onInputSurfaceDeclined(UNKNOWN_ERROR);
+            return;
+        }
+        status_t err = setupInputSurface(std::make_shared<C2InputSurfaceWrapper>(
+                std::make_shared<Codec2Client::InputSurface>(inputSurface)));
+        if (err != OK) {
+            ALOGE("Failed to set up input surface: %d", err);
+            mCallback->onInputSurfaceDeclined(err);
+            return;
+        }
+    } else {
+        int32_t width = 0;
+        (void)outputFormat->findInt32("width", &width);
+        int32_t height = 0;
+        (void)outputFormat->findInt32("height", &height);
+        status_t err = setupInputSurface(std::make_shared<GraphicBufferSourceWrapper>(
+                surface->getBufferSource(), width, height, usage));
+        if (err != OK) {
+            ALOGE("Failed to set up input surface: %d", err);
+            mCallback->onInputSurfaceDeclined(err);
+            return;
+        }
+    }
+    mCallback->onInputSurfaceAccepted(inputFormat, outputFormat);
+}
+
+void CCodec::initiateStart() {
+    auto setStarting = [this] {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() != ALLOCATED) {
+            return UNKNOWN_ERROR;
+        }
+        state->set(STARTING);
+        return OK;
+    };
+    if (tryAndReportOnError(setStarting) != OK) {
+        return;
+    }
+
+    (new AMessage(kWhatStart, this))->post();
+}
+
+void CCodec::start() {
+    std::shared_ptr<Codec2Client::Component> comp;
+    auto checkStarting = [this, &comp] {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() != STARTING) {
+            return UNKNOWN_ERROR;
+        }
+        comp = state->comp;
+        return OK;
+    };
+    if (tryAndReportOnError(checkStarting) != OK) {
+        return;
+    }
+
+    c2_status_t err = comp->start();
+    if (err != C2_OK) {
+        mCallback->onError(toStatusT(err, C2_OPERATION_Component_start),
+                           ACTION_CODE_FATAL);
+        return;
+    }
+    sp<AMessage> inputFormat;
+    sp<AMessage> outputFormat;
+    status_t err2 = OK;
+    {
+        Mutexed<Config>::Locked config(mConfig);
+        inputFormat = config->mInputFormat;
+        outputFormat = config->mOutputFormat;
+        if (config->mInputSurface) {
+            err2 = config->mInputSurface->start();
+        }
+    }
+    if (err2 != OK) {
+        mCallback->onError(err2, ACTION_CODE_FATAL);
+        return;
+    }
+    err2 = mChannel->start(inputFormat, outputFormat);
+    if (err2 != OK) {
+        mCallback->onError(err2, ACTION_CODE_FATAL);
+        return;
+    }
+
+    auto setRunning = [this] {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() != STARTING) {
+            return UNKNOWN_ERROR;
+        }
+        state->set(RUNNING);
+        return OK;
+    };
+    if (tryAndReportOnError(setRunning) != OK) {
+        return;
+    }
+    mCallback->onStartCompleted();
+
+    (void)mChannel->requestInitialInputBuffers();
+}
+
+void CCodec::initiateShutdown(bool keepComponentAllocated) {
+    if (keepComponentAllocated) {
+        initiateStop();
+    } else {
+        initiateRelease();
+    }
+}
+
+void CCodec::initiateStop() {
+    {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() == ALLOCATED
+                || state->get()  == RELEASED
+                || state->get() == STOPPING
+                || state->get() == RELEASING) {
+            // We're already stopped, released, or doing it right now.
+            state.unlock();
+            mCallback->onStopCompleted();
+            state.lock();
+            return;
+        }
+        state->set(STOPPING);
+    }
+
+    mChannel->stop();
+    (new AMessage(kWhatStop, this))->post();
+}
+
+void CCodec::stop() {
+    std::shared_ptr<Codec2Client::Component> comp;
+    {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() == RELEASING) {
+            state.unlock();
+            // We're already stopped or release is in progress.
+            mCallback->onStopCompleted();
+            state.lock();
+            return;
+        } else if (state->get() != STOPPING) {
+            state.unlock();
+            mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
+            state.lock();
+            return;
+        }
+        comp = state->comp;
+    }
+    status_t err = comp->stop();
+    if (err != C2_OK) {
+        // TODO: convert err into status_t
+        mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
+    }
+
+    {
+        Mutexed<Config>::Locked config(mConfig);
+        if (config->mInputSurface) {
+            config->mInputSurface->disconnect();
+            config->mInputSurface = nullptr;
+        }
+    }
+    {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() == STOPPING) {
+            state->set(ALLOCATED);
+        }
+    }
+    mCallback->onStopCompleted();
+}
+
+void CCodec::initiateRelease(bool sendCallback /* = true */) {
+    bool clearInputSurfaceIfNeeded = false;
+    {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() == RELEASED || state->get() == RELEASING) {
+            // We're already released or doing it right now.
+            if (sendCallback) {
+                state.unlock();
+                mCallback->onReleaseCompleted();
+                state.lock();
+            }
+            return;
+        }
+        if (state->get() == ALLOCATING) {
+            state->set(RELEASING);
+            // With the altered state allocate() would fail and clean up.
+            if (sendCallback) {
+                state.unlock();
+                mCallback->onReleaseCompleted();
+                state.lock();
+            }
+            return;
+        }
+        if (state->get() == STARTING
+                || state->get() == RUNNING
+                || state->get() == STOPPING) {
+            // Input surface may have been started, so clean up is needed.
+            clearInputSurfaceIfNeeded = true;
+        }
+        state->set(RELEASING);
+    }
+
+    if (clearInputSurfaceIfNeeded) {
+        Mutexed<Config>::Locked config(mConfig);
+        if (config->mInputSurface) {
+            config->mInputSurface->disconnect();
+            config->mInputSurface = nullptr;
+        }
+    }
+
+    mChannel->stop();
+    // thiz holds strong ref to this while the thread is running.
+    sp<CCodec> thiz(this);
+    std::thread([thiz, sendCallback] { thiz->release(sendCallback); }).detach();
+}
+
+void CCodec::release(bool sendCallback) {
+    std::shared_ptr<Codec2Client::Component> comp;
+    {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() == RELEASED) {
+            if (sendCallback) {
+                state.unlock();
+                mCallback->onReleaseCompleted();
+                state.lock();
+            }
+            return;
+        }
+        comp = state->comp;
+    }
+    comp->release();
+
+    {
+        Mutexed<State>::Locked state(mState);
+        state->set(RELEASED);
+        state->comp.reset();
+    }
+    if (sendCallback) {
+        mCallback->onReleaseCompleted();
+    }
+}
+
+status_t CCodec::setSurface(const sp<Surface> &surface) {
+    return mChannel->setSurface(surface);
+}
+
+void CCodec::signalFlush() {
+    status_t err = [this] {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() == FLUSHED) {
+            return ALREADY_EXISTS;
+        }
+        if (state->get() != RUNNING) {
+            return UNKNOWN_ERROR;
+        }
+        state->set(FLUSHING);
+        return OK;
+    }();
+    switch (err) {
+        case ALREADY_EXISTS:
+            mCallback->onFlushCompleted();
+            return;
+        case OK:
+            break;
+        default:
+            mCallback->onError(err, ACTION_CODE_FATAL);
+            return;
+    }
+
+    mChannel->stop();
+    (new AMessage(kWhatFlush, this))->post();
+}
+
+void CCodec::flush() {
+    std::shared_ptr<Codec2Client::Component> comp;
+    auto checkFlushing = [this, &comp] {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() != FLUSHING) {
+            return UNKNOWN_ERROR;
+        }
+        comp = state->comp;
+        return OK;
+    };
+    if (tryAndReportOnError(checkFlushing) != OK) {
+        return;
+    }
+
+    std::list<std::unique_ptr<C2Work>> flushedWork;
+    c2_status_t err = comp->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
+    {
+        Mutexed<std::list<std::unique_ptr<C2Work>>>::Locked queue(mWorkDoneQueue);
+        flushedWork.splice(flushedWork.end(), *queue);
+    }
+    if (err != C2_OK) {
+        // TODO: convert err into status_t
+        mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
+    }
+
+    mChannel->flush(flushedWork);
+
+    {
+        Mutexed<State>::Locked state(mState);
+        state->set(FLUSHED);
+    }
+    mCallback->onFlushCompleted();
+}
+
+void CCodec::signalResume() {
+    auto setResuming = [this] {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() != FLUSHED) {
+            return UNKNOWN_ERROR;
+        }
+        state->set(RESUMING);
+        return OK;
+    };
+    if (tryAndReportOnError(setResuming) != OK) {
+        return;
+    }
+
+    (void)mChannel->start(nullptr, nullptr);
+
+    {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() != RESUMING) {
+            state.unlock();
+            mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
+            state.lock();
+            return;
+        }
+        state->set(RUNNING);
+    }
+
+    (void)mChannel->requestInitialInputBuffers();
+}
+
+void CCodec::signalSetParameters(const sp<AMessage> &msg) {
+    std::shared_ptr<Codec2Client::Component> comp;
+    auto checkState = [this, &comp] {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() == RELEASED) {
+            return INVALID_OPERATION;
+        }
+        comp = state->comp;
+        return OK;
+    };
+    if (tryAndReportOnError(checkState) != OK) {
+        return;
+    }
+
+    // NOTE: We used to ignore "bitrate" at setParameters; replicate
+    //       the behavior here.
+    sp<AMessage> params = msg;
+    int32_t bitrate;
+    if (params->findInt32(KEY_BIT_RATE, &bitrate)) {
+        params = msg->dup();
+        params->removeEntryAt(params->findEntryByName(KEY_BIT_RATE));
+    }
+
+    Mutexed<Config>::Locked config(mConfig);
+
+    /**
+     * Handle input surface parameters
+     */
+    if ((config->mDomain & (Config::IS_VIDEO | Config::IS_IMAGE))
+            && (config->mDomain & Config::IS_ENCODER) && config->mInputSurface && config->mISConfig) {
+        (void)params->findInt64(PARAMETER_KEY_OFFSET_TIME, &config->mISConfig->mTimeOffsetUs);
+
+        if (params->findInt64("skip-frames-before", &config->mISConfig->mStartAtUs)) {
+            config->mISConfig->mStopped = false;
+        } else if (params->findInt64("stop-time-us", &config->mISConfig->mStopAtUs)) {
+            config->mISConfig->mStopped = true;
+        }
+
+        int32_t value;
+        if (params->findInt32(PARAMETER_KEY_SUSPEND, &value)) {
+            config->mISConfig->mSuspended = value;
+            config->mISConfig->mSuspendAtUs = -1;
+            (void)params->findInt64(PARAMETER_KEY_SUSPEND_TIME, &config->mISConfig->mSuspendAtUs);
+        }
+
+        (void)config->mInputSurface->configure(*config->mISConfig);
+        if (config->mISConfig->mStopped) {
+            config->mInputFormat->setInt64(
+                    "android._stop-time-offset-us", config->mISConfig->mInputDelayUs);
+        }
+    }
+
+    std::vector<std::unique_ptr<C2Param>> configUpdate;
+    (void)config->getConfigUpdateFromSdkParams(
+            comp, params, Config::IS_PARAM, C2_MAY_BLOCK, &configUpdate);
+    // Prefer to pass parameters to the buffer channel, so they can be synchronized with the frames.
+    // Parameter synchronization is not defined when using input surface. For now, route
+    // these directly to the component.
+    if (config->mInputSurface == nullptr
+            && (property_get_bool("debug.stagefright.ccodec_delayed_params", false)
+                    || comp->getName().find("c2.android.") == 0)) {
+        mChannel->setParameters(configUpdate);
+    } else {
+        (void)config->setParameters(comp, configUpdate, C2_MAY_BLOCK);
+    }
+}
+
+void CCodec::signalEndOfInputStream() {
+    mCallback->onSignaledInputEOS(mChannel->signalEndOfInputStream());
+}
+
+void CCodec::signalRequestIDRFrame() {
+    std::shared_ptr<Codec2Client::Component> comp;
+    {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() == RELEASED) {
+            ALOGD("no IDR request sent since component is released");
+            return;
+        }
+        comp = state->comp;
+    }
+    ALOGV("request IDR");
+    Mutexed<Config>::Locked config(mConfig);
+    std::vector<std::unique_ptr<C2Param>> params;
+    params.push_back(
+            std::make_unique<C2StreamRequestSyncFrameTuning::output>(0u, true));
+    config->setParameters(comp, params, C2_MAY_BLOCK);
+}
+
+void CCodec::onWorkDone(std::list<std::unique_ptr<C2Work>> &workItems) {
+    if (!workItems.empty()) {
+        Mutexed<std::list<std::unique_ptr<C2Work>>>::Locked queue(mWorkDoneQueue);
+        queue->splice(queue->end(), workItems);
+    }
+    (new AMessage(kWhatWorkDone, this))->post();
+}
+
+void CCodec::onInputBufferDone(uint64_t frameIndex, size_t arrayIndex) {
+    mChannel->onInputBufferDone(frameIndex, arrayIndex);
+    if (arrayIndex == 0) {
+        // We always put no more than one buffer per work, if we use an input surface.
+        Mutexed<Config>::Locked config(mConfig);
+        if (config->mInputSurface) {
+            config->mInputSurface->onInputBufferDone(frameIndex);
+        }
+    }
+}
+
+void CCodec::onMessageReceived(const sp<AMessage> &msg) {
+    TimePoint now = std::chrono::steady_clock::now();
+    CCodecWatchdog::getInstance()->watch(this);
+    switch (msg->what()) {
+        case kWhatAllocate: {
+            // C2ComponentStore::createComponent() should return within 100ms.
+            setDeadline(now, 1500ms, "allocate");
+            sp<RefBase> obj;
+            CHECK(msg->findObject("codecInfo", &obj));
+            allocate((MediaCodecInfo *)obj.get());
+            break;
+        }
+        case kWhatConfigure: {
+            // C2Component::commit_sm() should return within 5ms.
+            setDeadline(now, 1500ms, "configure");
+            sp<AMessage> format;
+            CHECK(msg->findMessage("format", &format));
+            configure(format);
+            break;
+        }
+        case kWhatStart: {
+            // C2Component::start() should return within 500ms.
+            setDeadline(now, 1500ms, "start");
+            start();
+            break;
+        }
+        case kWhatStop: {
+            // C2Component::stop() should return within 500ms.
+            setDeadline(now, 1500ms, "stop");
+            stop();
+            break;
+        }
+        case kWhatFlush: {
+            // C2Component::flush_sm() should return within 5ms.
+            setDeadline(now, 1500ms, "flush");
+            flush();
+            break;
+        }
+        case kWhatCreateInputSurface: {
+            // Surface operations may be briefly blocking.
+            setDeadline(now, 1500ms, "createInputSurface");
+            createInputSurface();
+            break;
+        }
+        case kWhatSetInputSurface: {
+            // Surface operations may be briefly blocking.
+            setDeadline(now, 1500ms, "setInputSurface");
+            sp<RefBase> obj;
+            CHECK(msg->findObject("surface", &obj));
+            sp<PersistentSurface> surface(static_cast<PersistentSurface *>(obj.get()));
+            setInputSurface(surface);
+            break;
+        }
+        case kWhatWorkDone: {
+            std::unique_ptr<C2Work> work;
+            bool shouldPost = false;
+            {
+                Mutexed<std::list<std::unique_ptr<C2Work>>>::Locked queue(mWorkDoneQueue);
+                if (queue->empty()) {
+                    break;
+                }
+                work.swap(queue->front());
+                queue->pop_front();
+                shouldPost = !queue->empty();
+            }
+            if (shouldPost) {
+                (new AMessage(kWhatWorkDone, this))->post();
+            }
+
+            // handle configuration changes in work done
+            Mutexed<Config>::Locked config(mConfig);
+            bool changed = false;
+            Config::Watcher<C2StreamInitDataInfo::output> initData =
+                config->watch<C2StreamInitDataInfo::output>();
+            if (!work->worklets.empty()
+                    && (work->worklets.front()->output.flags
+                            & C2FrameData::FLAG_DISCARD_FRAME) == 0) {
+
+                // copy buffer info to config
+                std::vector<std::unique_ptr<C2Param>> updates;
+                for (const std::unique_ptr<C2Param> &param
+                        : work->worklets.front()->output.configUpdate) {
+                    updates.push_back(C2Param::Copy(*param));
+                }
+                unsigned stream = 0;
+                for (const std::shared_ptr<C2Buffer> &buf : work->worklets.front()->output.buffers) {
+                    for (const std::shared_ptr<const C2Info> &info : buf->info()) {
+                        // move all info into output-stream #0 domain
+                        updates.emplace_back(C2Param::CopyAsStream(*info, true /* output */, stream));
+                    }
+                    for (const C2ConstGraphicBlock &block : buf->data().graphicBlocks()) {
+                        // ALOGV("got output buffer with crop %u,%u+%u,%u and size %u,%u",
+                        //      block.crop().left, block.crop().top,
+                        //      block.crop().width, block.crop().height,
+                        //      block.width(), block.height());
+                        updates.emplace_back(new C2StreamCropRectInfo::output(stream, block.crop()));
+                        updates.emplace_back(new C2StreamPictureSizeInfo::output(
+                                stream, block.crop().width, block.crop().height));
+                        break; // for now only do the first block
+                    }
+                    ++stream;
+                }
+
+                changed = config->updateConfiguration(updates, config->mOutputDomain);
+
+                // copy standard infos to graphic buffers if not already present (otherwise, we
+                // may overwrite the actual intermediate value with a final value)
+                stream = 0;
+                const static std::vector<C2Param::Index> stdGfxInfos = {
+                    C2StreamRotationInfo::output::PARAM_TYPE,
+                    C2StreamColorAspectsInfo::output::PARAM_TYPE,
+                    C2StreamDataSpaceInfo::output::PARAM_TYPE,
+                    C2StreamHdrStaticInfo::output::PARAM_TYPE,
+                    C2StreamHdr10PlusInfo::output::PARAM_TYPE,
+                    C2StreamPixelAspectRatioInfo::output::PARAM_TYPE,
+                    C2StreamSurfaceScalingInfo::output::PARAM_TYPE
+                };
+                for (const std::shared_ptr<C2Buffer> &buf : work->worklets.front()->output.buffers) {
+                    if (buf->data().graphicBlocks().size()) {
+                        for (C2Param::Index ix : stdGfxInfos) {
+                            if (!buf->hasInfo(ix)) {
+                                const C2Param *param =
+                                    config->getConfigParameterValue(ix.withStream(stream));
+                                if (param) {
+                                    std::shared_ptr<C2Param> info(C2Param::Copy(*param));
+                                    buf->setInfo(std::static_pointer_cast<C2Info>(info));
+                                }
+                            }
+                        }
+                    }
+                    ++stream;
+                }
+            }
+            if (config->mInputSurface) {
+                config->mInputSurface->onInputBufferDone(work->input.ordinal.frameIndex);
+            }
+            mChannel->onWorkDone(
+                    std::move(work), changed ? config->mOutputFormat : nullptr,
+                    initData.hasChanged() ? initData.update().get() : nullptr);
+            break;
+        }
+        case kWhatWatch: {
+            // watch message already posted; no-op.
+            break;
+        }
+        default: {
+            ALOGE("unrecognized message");
+            break;
+        }
+    }
+    setDeadline(TimePoint::max(), 0ms, "none");
+}
+
+void CCodec::setDeadline(
+        const TimePoint &now,
+        const std::chrono::milliseconds &timeout,
+        const char *name) {
+    int32_t mult = std::max(1, property_get_int32("debug.stagefright.ccodec_timeout_mult", 1));
+    Mutexed<NamedTimePoint>::Locked deadline(mDeadline);
+    deadline->set(now + (timeout * mult), name);
+}
+
+void CCodec::initiateReleaseIfStuck() {
+    std::string name;
+    bool pendingDeadline = false;
+    {
+        Mutexed<NamedTimePoint>::Locked deadline(mDeadline);
+        if (deadline->get() < std::chrono::steady_clock::now()) {
+            name = deadline->getName();
+        }
+        if (deadline->get() != TimePoint::max()) {
+            pendingDeadline = true;
+        }
+    }
+    if (name.empty()) {
+        constexpr std::chrono::steady_clock::duration kWorkDurationThreshold = 3s;
+        std::chrono::steady_clock::duration elapsed = mChannel->elapsed();
+        if (elapsed >= kWorkDurationThreshold) {
+            name = "queue";
+        }
+        if (elapsed > 0s) {
+            pendingDeadline = true;
+        }
+    }
+    if (name.empty()) {
+        // We're not stuck.
+        if (pendingDeadline) {
+            // If we are not stuck yet but still has deadline coming up,
+            // post watch message to check back later.
+            (new AMessage(kWhatWatch, this))->post();
+        }
+        return;
+    }
+
+    ALOGW("previous call to %s exceeded timeout", name.c_str());
+    initiateRelease(false);
+    mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
+}
+
+}  // namespace android
+
+extern "C" android::CodecBase *CreateCodec() {
+    return new android::CCodec;
+}
+
+// Create Codec 2.0 input surface
+extern "C" android::PersistentSurface *CreateInputSurface() {
+    using namespace android;
+    // Attempt to create a Codec2's input surface.
+    std::shared_ptr<Codec2Client::InputSurface> inputSurface =
+            Codec2Client::CreateInputSurface();
+    if (!inputSurface) {
+        if (property_get_int32("debug.stagefright.c2inputsurface", 0) == -1) {
+            sp<IGraphicBufferProducer> gbp;
+            sp<OmxGraphicBufferSource> gbs = new OmxGraphicBufferSource();
+            status_t err = gbs->initCheck();
+            if (err != OK) {
+                ALOGE("Failed to create persistent input surface: error %d", err);
+                return nullptr;
+            }
+            return new PersistentSurface(
+                    gbs->getIGraphicBufferProducer(),
+                    sp<IGraphicBufferSource>(
+                        new Omx2IGraphicBufferSource(gbs)));
+        } else {
+            return nullptr;
+        }
+    }
+    return new PersistentSurface(
+            inputSurface->getGraphicBufferProducer(),
+            static_cast<sp<android::hidl::base::V1_0::IBase>>(
+            inputSurface->getHalInterface()));
+}
+
diff --git a/media/codec2/sfplugin/CCodec.h b/media/codec2/sfplugin/CCodec.h
new file mode 100644
index 0000000..b0b3c4f
--- /dev/null
+++ b/media/codec2/sfplugin/CCodec.h
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef C_CODEC_H_
+#define C_CODEC_H_
+
+#include <chrono>
+#include <list>
+#include <memory>
+#include <set>
+
+#include <C2Component.h>
+#include <codec2/hidl/client.h>
+
+#include <android/native_window.h>
+#include <media/hardware/MetadataBufferType.h>
+#include <media/stagefright/foundation/Mutexed.h>
+#include <media/stagefright/CodecBase.h>
+#include <media/stagefright/FrameRenderTracker.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/SkipCutBuffer.h>
+#include <utils/NativeHandle.h>
+#include <hardware/gralloc.h>
+#include <nativebase/nativebase.h>
+
+#include "CCodecConfig.h"
+
+namespace android {
+
+class CCodecBufferChannel;
+class InputSurfaceWrapper;
+struct MediaCodecInfo;
+
+class CCodec : public CodecBase {
+public:
+    CCodec();
+
+    virtual std::shared_ptr<BufferChannelBase> getBufferChannel() override;
+    virtual void initiateAllocateComponent(const sp<AMessage> &msg) override;
+    virtual void initiateConfigureComponent(const sp<AMessage> &msg) override;
+    virtual void initiateCreateInputSurface() override;
+    virtual void initiateSetInputSurface(const sp<PersistentSurface> &surface) override;
+    virtual void initiateStart() override;
+    virtual void initiateShutdown(bool keepComponentAllocated = false) override;
+
+    virtual status_t setSurface(const sp<Surface> &surface) override;
+
+    virtual void signalFlush() override;
+    virtual void signalResume() override;
+
+    virtual void signalSetParameters(const sp<AMessage> &params) override;
+    virtual void signalEndOfInputStream() override;
+    virtual void signalRequestIDRFrame() override;
+
+    void initiateReleaseIfStuck();
+    void onWorkDone(std::list<std::unique_ptr<C2Work>> &workItems);
+    void onInputBufferDone(uint64_t frameIndex, size_t arrayIndex);
+
+protected:
+    virtual ~CCodec();
+
+    virtual void onMessageReceived(const sp<AMessage> &msg) override;
+
+private:
+    typedef std::chrono::steady_clock::time_point TimePoint;
+
+    status_t tryAndReportOnError(std::function<status_t()> job);
+
+    void initiateStop();
+    void initiateRelease(bool sendCallback = true);
+
+    void allocate(const sp<MediaCodecInfo> &codecInfo);
+    void configure(const sp<AMessage> &msg);
+    void start();
+    void stop();
+    void flush();
+    void release(bool sendCallback);
+
+    /**
+     * Creates an input surface for the current device configuration compatible with CCodec.
+     * This could be backed by the C2 HAL or the OMX HAL.
+     */
+    static sp<PersistentSurface> CreateCompatibleInputSurface();
+
+    /// Creates an input surface to the OMX HAL
+    static sp<PersistentSurface> CreateOmxInputSurface();
+
+    /// handle a create input surface call
+    void createInputSurface();
+    void setInputSurface(const sp<PersistentSurface> &surface);
+    status_t setupInputSurface(const std::shared_ptr<InputSurfaceWrapper> &surface);
+
+    void setDeadline(
+            const TimePoint &now,
+            const std::chrono::milliseconds &timeout,
+            const char *name);
+
+    enum {
+        kWhatAllocate,
+        kWhatConfigure,
+        kWhatStart,
+        kWhatFlush,
+        kWhatStop,
+        kWhatRelease,
+        kWhatCreateInputSurface,
+        kWhatSetInputSurface,
+        kWhatSetParameters,
+
+        kWhatWorkDone,
+        kWhatWatch,
+    };
+
+    enum {
+        RELEASED,
+        ALLOCATED,
+        FLUSHED,
+        RUNNING,
+
+        ALLOCATING,  // RELEASED -> ALLOCATED
+        STARTING,    // ALLOCATED -> RUNNING
+        STOPPING,    // RUNNING -> ALLOCATED
+        FLUSHING,    // RUNNING -> FLUSHED
+        RESUMING,    // FLUSHED -> RUNNING
+        RELEASING,   // {ANY EXCEPT RELEASED} -> RELEASED
+    };
+
+    struct State {
+        inline State() : mState(RELEASED) {}
+        inline int get() const { return mState; }
+        inline void set(int newState) { mState = newState; }
+
+        std::shared_ptr<Codec2Client::Component> comp;
+    private:
+        int mState;
+    };
+
+    struct NamedTimePoint {
+        NamedTimePoint() : mTimePoint(TimePoint::max()), mName("") {}
+
+        inline void set(
+                const TimePoint &timePoint,
+                const char *name) {
+            mTimePoint = timePoint;
+            mName = name;
+        }
+
+        inline TimePoint get() const { return mTimePoint; }
+        inline const char *getName() const { return mName; }
+    private:
+        TimePoint mTimePoint;
+        const char *mName;
+    };
+
+    Mutexed<State> mState;
+    std::shared_ptr<CCodecBufferChannel> mChannel;
+
+    std::shared_ptr<Codec2Client> mClient;
+    std::shared_ptr<Codec2Client::Listener> mClientListener;
+    struct ClientListener;
+
+    Mutexed<NamedTimePoint> mDeadline;
+    typedef CCodecConfig Config;
+    Mutexed<Config> mConfig;
+    Mutexed<std::list<std::unique_ptr<C2Work>>> mWorkDoneQueue;
+
+    friend class CCodecCallbackImpl;
+
+    DISALLOW_EVIL_CONSTRUCTORS(CCodec);
+};
+
+}  // namespace android
+
+#endif  // C_CODEC_H_
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
new file mode 100644
index 0000000..8308292
--- /dev/null
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -0,0 +1,1700 @@
+/*
+ * Copyright 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "CCodecBufferChannel"
+#include <utils/Log.h>
+
+#include <numeric>
+
+#include <C2AllocatorGralloc.h>
+#include <C2PlatformSupport.h>
+#include <C2BlockInternal.h>
+#include <C2Config.h>
+#include <C2Debug.h>
+
+#include <android/hardware/cas/native/1.0/IDescrambler.h>
+#include <android-base/stringprintf.h>
+#include <binder/MemoryDealer.h>
+#include <gui/Surface.h>
+#include <media/openmax/OMX_Core.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ALookup.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/AUtils.h>
+#include <media/stagefright/foundation/hexdump.h>
+#include <media/stagefright/MediaCodec.h>
+#include <media/stagefright/MediaCodecConstants.h>
+#include <media/MediaCodecBuffer.h>
+#include <system/window.h>
+
+#include "CCodecBufferChannel.h"
+#include "Codec2Buffer.h"
+#include "SkipCutBuffer.h"
+
+namespace android {
+
+using android::base::StringPrintf;
+using hardware::hidl_handle;
+using hardware::hidl_string;
+using hardware::hidl_vec;
+using namespace hardware::cas::V1_0;
+using namespace hardware::cas::native::V1_0;
+
+using CasStatus = hardware::cas::V1_0::Status;
+
+namespace {
+
+constexpr size_t kSmoothnessFactor = 4;
+constexpr size_t kRenderingDepth = 3;
+
+// This is for keeping IGBP's buffer dropping logic in legacy mode other
+// than making it non-blocking. Do not change this value.
+const static size_t kDequeueTimeoutNs = 0;
+
+}  // namespace
+
+CCodecBufferChannel::QueueGuard::QueueGuard(
+        CCodecBufferChannel::QueueSync &sync) : mSync(sync) {
+    Mutex::Autolock l(mSync.mGuardLock);
+    // At this point it's guaranteed that mSync is not under state transition,
+    // as we are holding its mutex.
+
+    Mutexed<CCodecBufferChannel::QueueSync::Counter>::Locked count(mSync.mCount);
+    if (count->value == -1) {
+        mRunning = false;
+    } else {
+        ++count->value;
+        mRunning = true;
+    }
+}
+
+CCodecBufferChannel::QueueGuard::~QueueGuard() {
+    if (mRunning) {
+        // We are not holding mGuardLock at this point so that QueueSync::stop() can
+        // keep holding the lock until mCount reaches zero.
+        Mutexed<CCodecBufferChannel::QueueSync::Counter>::Locked count(mSync.mCount);
+        --count->value;
+        count->cond.broadcast();
+    }
+}
+
+void CCodecBufferChannel::QueueSync::start() {
+    Mutex::Autolock l(mGuardLock);
+    // If stopped, it goes to running state; otherwise no-op.
+    Mutexed<Counter>::Locked count(mCount);
+    if (count->value == -1) {
+        count->value = 0;
+    }
+}
+
+void CCodecBufferChannel::QueueSync::stop() {
+    Mutex::Autolock l(mGuardLock);
+    Mutexed<Counter>::Locked count(mCount);
+    if (count->value == -1) {
+        // no-op
+        return;
+    }
+    // Holding mGuardLock here blocks creation of additional QueueGuard objects, so
+    // mCount can only decrement. In other words, threads that acquired the lock
+    // are allowed to finish execution but additional threads trying to acquire
+    // the lock at this point will block, and then get QueueGuard at STOPPED
+    // state.
+    while (count->value != 0) {
+        count.waitForCondition(count->cond);
+    }
+    count->value = -1;
+}
+
+// CCodecBufferChannel::ReorderStash
+
+CCodecBufferChannel::ReorderStash::ReorderStash() {
+    clear();
+}
+
+void CCodecBufferChannel::ReorderStash::clear() {
+    mPending.clear();
+    mStash.clear();
+    mDepth = 0;
+    mKey = C2Config::ORDINAL;
+}
+
+void CCodecBufferChannel::ReorderStash::flush() {
+    mPending.clear();
+    mStash.clear();
+}
+
+void CCodecBufferChannel::ReorderStash::setDepth(uint32_t depth) {
+    mPending.splice(mPending.end(), mStash);
+    mDepth = depth;
+}
+
+void CCodecBufferChannel::ReorderStash::setKey(C2Config::ordinal_key_t key) {
+    mPending.splice(mPending.end(), mStash);
+    mKey = key;
+}
+
+bool CCodecBufferChannel::ReorderStash::pop(Entry *entry) {
+    if (mPending.empty()) {
+        return false;
+    }
+    entry->buffer     = mPending.front().buffer;
+    entry->timestamp  = mPending.front().timestamp;
+    entry->flags      = mPending.front().flags;
+    entry->ordinal    = mPending.front().ordinal;
+    mPending.pop_front();
+    return true;
+}
+
+void CCodecBufferChannel::ReorderStash::emplace(
+        const std::shared_ptr<C2Buffer> &buffer,
+        int64_t timestamp,
+        int32_t flags,
+        const C2WorkOrdinalStruct &ordinal) {
+    bool eos = flags & MediaCodec::BUFFER_FLAG_EOS;
+    if (!buffer && eos) {
+        // TRICKY: we may be violating ordering of the stash here. Because we
+        // don't expect any more emplace() calls after this, the ordering should
+        // not matter.
+        mStash.emplace_back(buffer, timestamp, flags, ordinal);
+    } else {
+        flags = flags & ~MediaCodec::BUFFER_FLAG_EOS;
+        auto it = mStash.begin();
+        for (; it != mStash.end(); ++it) {
+            if (less(ordinal, it->ordinal)) {
+                break;
+            }
+        }
+        mStash.emplace(it, buffer, timestamp, flags, ordinal);
+        if (eos) {
+            mStash.back().flags = mStash.back().flags | MediaCodec::BUFFER_FLAG_EOS;
+        }
+    }
+    while (!mStash.empty() && mStash.size() > mDepth) {
+        mPending.push_back(mStash.front());
+        mStash.pop_front();
+    }
+}
+
+void CCodecBufferChannel::ReorderStash::defer(
+        const CCodecBufferChannel::ReorderStash::Entry &entry) {
+    mPending.push_front(entry);
+}
+
+bool CCodecBufferChannel::ReorderStash::hasPending() const {
+    return !mPending.empty();
+}
+
+bool CCodecBufferChannel::ReorderStash::less(
+        const C2WorkOrdinalStruct &o1, const C2WorkOrdinalStruct &o2) {
+    switch (mKey) {
+        case C2Config::ORDINAL:   return o1.frameIndex < o2.frameIndex;
+        case C2Config::TIMESTAMP: return o1.timestamp < o2.timestamp;
+        case C2Config::CUSTOM:    return o1.customOrdinal < o2.customOrdinal;
+        default:
+            ALOGD("Unrecognized key; default to timestamp");
+            return o1.frameIndex < o2.frameIndex;
+    }
+}
+
+// Input
+
+CCodecBufferChannel::Input::Input() : extraBuffers("extra") {}
+
+// CCodecBufferChannel
+
+CCodecBufferChannel::CCodecBufferChannel(
+        const std::shared_ptr<CCodecCallback> &callback)
+    : mHeapSeqNum(-1),
+      mCCodecCallback(callback),
+      mFrameIndex(0u),
+      mFirstValidFrameIndex(0u),
+      mMetaMode(MODE_NONE),
+      mInputMetEos(false) {
+    mOutputSurface.lock()->maxDequeueBuffers = kSmoothnessFactor + kRenderingDepth;
+    {
+        Mutexed<Input>::Locked input(mInput);
+        input->buffers.reset(new DummyInputBuffers(""));
+        input->extraBuffers.flush();
+        input->inputDelay = 0u;
+        input->pipelineDelay = 0u;
+        input->numSlots = kSmoothnessFactor;
+        input->numExtraSlots = 0u;
+    }
+    {
+        Mutexed<Output>::Locked output(mOutput);
+        output->outputDelay = 0u;
+        output->numSlots = kSmoothnessFactor;
+    }
+}
+
+CCodecBufferChannel::~CCodecBufferChannel() {
+    if (mCrypto != nullptr && mDealer != nullptr && mHeapSeqNum >= 0) {
+        mCrypto->unsetHeap(mHeapSeqNum);
+    }
+}
+
+void CCodecBufferChannel::setComponent(
+        const std::shared_ptr<Codec2Client::Component> &component) {
+    mComponent = component;
+    mComponentName = component->getName() + StringPrintf("#%d", int(uintptr_t(component.get()) % 997));
+    mName = mComponentName.c_str();
+}
+
+status_t CCodecBufferChannel::setInputSurface(
+        const std::shared_ptr<InputSurfaceWrapper> &surface) {
+    ALOGV("[%s] setInputSurface", mName);
+    mInputSurface = surface;
+    return mInputSurface->connect(mComponent);
+}
+
+status_t CCodecBufferChannel::signalEndOfInputStream() {
+    if (mInputSurface == nullptr) {
+        return INVALID_OPERATION;
+    }
+    return mInputSurface->signalEndOfInputStream();
+}
+
+status_t CCodecBufferChannel::queueInputBufferInternal(sp<MediaCodecBuffer> buffer) {
+    int64_t timeUs;
+    CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
+
+    if (mInputMetEos) {
+        ALOGD("[%s] buffers after EOS ignored (%lld us)", mName, (long long)timeUs);
+        return OK;
+    }
+
+    int32_t flags = 0;
+    int32_t tmp = 0;
+    bool eos = false;
+    if (buffer->meta()->findInt32("eos", &tmp) && tmp) {
+        eos = true;
+        mInputMetEos = true;
+        ALOGV("[%s] input EOS", mName);
+    }
+    if (buffer->meta()->findInt32("csd", &tmp) && tmp) {
+        flags |= C2FrameData::FLAG_CODEC_CONFIG;
+    }
+    ALOGV("[%s] queueInputBuffer: buffer->size() = %zu", mName, buffer->size());
+    std::unique_ptr<C2Work> work(new C2Work);
+    work->input.ordinal.timestamp = timeUs;
+    work->input.ordinal.frameIndex = mFrameIndex++;
+    // WORKAROUND: until codecs support handling work after EOS and max output sizing, use timestamp
+    // manipulation to achieve image encoding via video codec, and to constrain encoded output.
+    // Keep client timestamp in customOrdinal
+    work->input.ordinal.customOrdinal = timeUs;
+    work->input.buffers.clear();
+
+    uint64_t queuedFrameIndex = work->input.ordinal.frameIndex.peeku();
+    std::vector<std::shared_ptr<C2Buffer>> queuedBuffers;
+    sp<Codec2Buffer> copy;
+
+    if (buffer->size() > 0u) {
+        Mutexed<Input>::Locked input(mInput);
+        std::shared_ptr<C2Buffer> c2buffer;
+        if (!input->buffers->releaseBuffer(buffer, &c2buffer, false)) {
+            return -ENOENT;
+        }
+        // TODO: we want to delay copying buffers.
+        if (input->extraBuffers.numComponentBuffers() < input->numExtraSlots) {
+            copy = input->buffers->cloneAndReleaseBuffer(buffer);
+            if (copy != nullptr) {
+                (void)input->extraBuffers.assignSlot(copy);
+                if (!input->extraBuffers.releaseSlot(copy, &c2buffer, false)) {
+                    return UNKNOWN_ERROR;
+                }
+                bool released = input->buffers->releaseBuffer(buffer, nullptr, true);
+                ALOGV("[%s] queueInputBuffer: buffer copied; %sreleased",
+                      mName, released ? "" : "not ");
+                buffer.clear();
+            } else {
+                ALOGW("[%s] queueInputBuffer: failed to copy a buffer; this may cause input "
+                      "buffer starvation on component.", mName);
+            }
+        }
+        work->input.buffers.push_back(c2buffer);
+        queuedBuffers.push_back(c2buffer);
+    } else if (eos) {
+        flags |= C2FrameData::FLAG_END_OF_STREAM;
+    }
+    work->input.flags = (C2FrameData::flags_t)flags;
+    // TODO: fill info's
+
+    work->input.configUpdate = std::move(mParamsToBeSet);
+    work->worklets.clear();
+    work->worklets.emplace_back(new C2Worklet);
+
+    std::list<std::unique_ptr<C2Work>> items;
+    items.push_back(std::move(work));
+    mPipelineWatcher.lock()->onWorkQueued(
+            queuedFrameIndex,
+            std::move(queuedBuffers),
+            PipelineWatcher::Clock::now());
+    c2_status_t err = mComponent->queue(&items);
+    if (err != C2_OK) {
+        mPipelineWatcher.lock()->onWorkDone(queuedFrameIndex);
+    }
+
+    if (err == C2_OK && eos && buffer->size() > 0u) {
+        work.reset(new C2Work);
+        work->input.ordinal.timestamp = timeUs;
+        work->input.ordinal.frameIndex = mFrameIndex++;
+        // WORKAROUND: keep client timestamp in customOrdinal
+        work->input.ordinal.customOrdinal = timeUs;
+        work->input.buffers.clear();
+        work->input.flags = C2FrameData::FLAG_END_OF_STREAM;
+        work->worklets.emplace_back(new C2Worklet);
+
+        queuedFrameIndex = work->input.ordinal.frameIndex.peeku();
+        queuedBuffers.clear();
+
+        items.clear();
+        items.push_back(std::move(work));
+
+        mPipelineWatcher.lock()->onWorkQueued(
+                queuedFrameIndex,
+                std::move(queuedBuffers),
+                PipelineWatcher::Clock::now());
+        err = mComponent->queue(&items);
+        if (err != C2_OK) {
+            mPipelineWatcher.lock()->onWorkDone(queuedFrameIndex);
+        }
+    }
+    if (err == C2_OK) {
+        Mutexed<Input>::Locked input(mInput);
+        bool released = false;
+        if (buffer) {
+            released = input->buffers->releaseBuffer(buffer, nullptr, true);
+        } else if (copy) {
+            released = input->extraBuffers.releaseSlot(copy, nullptr, true);
+        }
+        ALOGV("[%s] queueInputBuffer: buffer%s %sreleased",
+              mName, (buffer == nullptr) ? "(copy)" : "", released ? "" : "not ");
+    }
+
+    feedInputBufferIfAvailableInternal();
+    return err;
+}
+
+status_t CCodecBufferChannel::setParameters(std::vector<std::unique_ptr<C2Param>> &params) {
+    QueueGuard guard(mSync);
+    if (!guard.isRunning()) {
+        ALOGD("[%s] setParameters is only supported in the running state.", mName);
+        return -ENOSYS;
+    }
+    mParamsToBeSet.insert(mParamsToBeSet.end(),
+                          std::make_move_iterator(params.begin()),
+                          std::make_move_iterator(params.end()));
+    params.clear();
+    return OK;
+}
+
+status_t CCodecBufferChannel::queueInputBuffer(const sp<MediaCodecBuffer> &buffer) {
+    QueueGuard guard(mSync);
+    if (!guard.isRunning()) {
+        ALOGD("[%s] No more buffers should be queued at current state.", mName);
+        return -ENOSYS;
+    }
+    return queueInputBufferInternal(buffer);
+}
+
+status_t CCodecBufferChannel::queueSecureInputBuffer(
+        const sp<MediaCodecBuffer> &buffer, bool secure, const uint8_t *key,
+        const uint8_t *iv, CryptoPlugin::Mode mode, CryptoPlugin::Pattern pattern,
+        const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
+        AString *errorDetailMsg) {
+    QueueGuard guard(mSync);
+    if (!guard.isRunning()) {
+        ALOGD("[%s] No more buffers should be queued at current state.", mName);
+        return -ENOSYS;
+    }
+
+    if (!hasCryptoOrDescrambler()) {
+        return -ENOSYS;
+    }
+    sp<EncryptedLinearBlockBuffer> encryptedBuffer((EncryptedLinearBlockBuffer *)buffer.get());
+
+    ssize_t result = -1;
+    ssize_t codecDataOffset = 0;
+    if (mCrypto != nullptr) {
+        ICrypto::DestinationBuffer destination;
+        if (secure) {
+            destination.mType = ICrypto::kDestinationTypeNativeHandle;
+            destination.mHandle = encryptedBuffer->handle();
+        } else {
+            destination.mType = ICrypto::kDestinationTypeSharedMemory;
+            destination.mSharedMemory = mDecryptDestination;
+        }
+        ICrypto::SourceBuffer source;
+        encryptedBuffer->fillSourceBuffer(&source);
+        result = mCrypto->decrypt(
+                key, iv, mode, pattern, source, buffer->offset(),
+                subSamples, numSubSamples, destination, errorDetailMsg);
+        if (result < 0) {
+            return result;
+        }
+        if (destination.mType == ICrypto::kDestinationTypeSharedMemory) {
+            encryptedBuffer->copyDecryptedContent(mDecryptDestination, result);
+        }
+    } else {
+        // Here we cast CryptoPlugin::SubSample to hardware::cas::native::V1_0::SubSample
+        // directly, the structure definitions should match as checked in DescramblerImpl.cpp.
+        hidl_vec<SubSample> hidlSubSamples;
+        hidlSubSamples.setToExternal((SubSample *)subSamples, numSubSamples, false /*own*/);
+
+        hardware::cas::native::V1_0::SharedBuffer srcBuffer;
+        encryptedBuffer->fillSourceBuffer(&srcBuffer);
+
+        DestinationBuffer dstBuffer;
+        if (secure) {
+            dstBuffer.type = BufferType::NATIVE_HANDLE;
+            dstBuffer.secureMemory = hidl_handle(encryptedBuffer->handle());
+        } else {
+            dstBuffer.type = BufferType::SHARED_MEMORY;
+            dstBuffer.nonsecureMemory = srcBuffer;
+        }
+
+        CasStatus status = CasStatus::OK;
+        hidl_string detailedError;
+        ScramblingControl sctrl = ScramblingControl::UNSCRAMBLED;
+
+        if (key != nullptr) {
+            sctrl = (ScramblingControl)key[0];
+            // Adjust for the PES offset
+            codecDataOffset = key[2] | (key[3] << 8);
+        }
+
+        auto returnVoid = mDescrambler->descramble(
+                sctrl,
+                hidlSubSamples,
+                srcBuffer,
+                0,
+                dstBuffer,
+                0,
+                [&status, &result, &detailedError] (
+                        CasStatus _status, uint32_t _bytesWritten,
+                        const hidl_string& _detailedError) {
+                    status = _status;
+                    result = (ssize_t)_bytesWritten;
+                    detailedError = _detailedError;
+                });
+
+        if (!returnVoid.isOk() || status != CasStatus::OK || result < 0) {
+            ALOGI("[%s] descramble failed, trans=%s, status=%d, result=%zd",
+                    mName, returnVoid.description().c_str(), status, result);
+            return UNKNOWN_ERROR;
+        }
+
+        if (result < codecDataOffset) {
+            ALOGD("invalid codec data offset: %zd, result %zd", codecDataOffset, result);
+            return BAD_VALUE;
+        }
+
+        ALOGV("[%s] descramble succeeded, %zd bytes", mName, result);
+
+        if (dstBuffer.type == BufferType::SHARED_MEMORY) {
+            encryptedBuffer->copyDecryptedContentFromMemory(result);
+        }
+    }
+
+    buffer->setRange(codecDataOffset, result - codecDataOffset);
+    return queueInputBufferInternal(buffer);
+}
+
+void CCodecBufferChannel::feedInputBufferIfAvailable() {
+    QueueGuard guard(mSync);
+    if (!guard.isRunning()) {
+        ALOGV("[%s] We're not running --- no input buffer reported", mName);
+        return;
+    }
+    feedInputBufferIfAvailableInternal();
+}
+
+void CCodecBufferChannel::feedInputBufferIfAvailableInternal() {
+    if (mInputMetEos ||
+           mReorderStash.lock()->hasPending() ||
+           mPipelineWatcher.lock()->pipelineFull()) {
+        return;
+    } else {
+        Mutexed<Output>::Locked output(mOutput);
+        if (output->buffers->numClientBuffers() >= output->numSlots) {
+            return;
+        }
+    }
+    size_t numInputSlots = mInput.lock()->numSlots;
+    for (size_t i = 0; i < numInputSlots; ++i) {
+        sp<MediaCodecBuffer> inBuffer;
+        size_t index;
+        {
+            Mutexed<Input>::Locked input(mInput);
+            if (input->buffers->numClientBuffers() >= input->numSlots) {
+                return;
+            }
+            if (!input->buffers->requestNewBuffer(&index, &inBuffer)) {
+                ALOGV("[%s] no new buffer available", mName);
+                break;
+            }
+        }
+        ALOGV("[%s] new input index = %zu [%p]", mName, index, inBuffer.get());
+        mCallback->onInputBufferAvailable(index, inBuffer);
+    }
+}
+
+status_t CCodecBufferChannel::renderOutputBuffer(
+        const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) {
+    ALOGV("[%s] renderOutputBuffer: %p", mName, buffer.get());
+    std::shared_ptr<C2Buffer> c2Buffer;
+    bool released = false;
+    {
+        Mutexed<Output>::Locked output(mOutput);
+        if (output->buffers) {
+            released = output->buffers->releaseBuffer(buffer, &c2Buffer);
+        }
+    }
+    // NOTE: some apps try to releaseOutputBuffer() with timestamp and/or render
+    //       set to true.
+    sendOutputBuffers();
+    // input buffer feeding may have been gated by pending output buffers
+    feedInputBufferIfAvailable();
+    if (!c2Buffer) {
+        if (released) {
+            std::call_once(mRenderWarningFlag, [this] {
+                ALOGW("[%s] The app is calling releaseOutputBuffer() with "
+                      "timestamp or render=true with non-video buffers. Apps should "
+                      "call releaseOutputBuffer() with render=false for those.",
+                      mName);
+            });
+        }
+        return INVALID_OPERATION;
+    }
+
+#if 0
+    const std::vector<std::shared_ptr<const C2Info>> infoParams = c2Buffer->info();
+    ALOGV("[%s] queuing gfx buffer with %zu infos", mName, infoParams.size());
+    for (const std::shared_ptr<const C2Info> &info : infoParams) {
+        AString res;
+        for (size_t ix = 0; ix + 3 < info->size(); ix += 4) {
+            if (ix) res.append(", ");
+            res.append(*((int32_t*)info.get() + (ix / 4)));
+        }
+        ALOGV("  [%s]", res.c_str());
+    }
+#endif
+    std::shared_ptr<const C2StreamRotationInfo::output> rotation =
+        std::static_pointer_cast<const C2StreamRotationInfo::output>(
+                c2Buffer->getInfo(C2StreamRotationInfo::output::PARAM_TYPE));
+    bool flip = rotation && (rotation->flip & 1);
+    uint32_t quarters = ((rotation ? rotation->value : 0) / 90) & 3;
+    uint32_t transform = 0;
+    switch (quarters) {
+        case 0: // no rotation
+            transform = flip ? HAL_TRANSFORM_FLIP_H : 0;
+            break;
+        case 1: // 90 degrees counter-clockwise
+            transform = flip ? (HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90)
+                    : HAL_TRANSFORM_ROT_270;
+            break;
+        case 2: // 180 degrees
+            transform = flip ? HAL_TRANSFORM_FLIP_V : HAL_TRANSFORM_ROT_180;
+            break;
+        case 3: // 90 degrees clockwise
+            transform = flip ? (HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90)
+                    : HAL_TRANSFORM_ROT_90;
+            break;
+    }
+
+    std::shared_ptr<const C2StreamSurfaceScalingInfo::output> surfaceScaling =
+        std::static_pointer_cast<const C2StreamSurfaceScalingInfo::output>(
+                c2Buffer->getInfo(C2StreamSurfaceScalingInfo::output::PARAM_TYPE));
+    uint32_t videoScalingMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
+    if (surfaceScaling) {
+        videoScalingMode = surfaceScaling->value;
+    }
+
+    // Use dataspace from format as it has the default aspects already applied
+    android_dataspace_t dataSpace = HAL_DATASPACE_UNKNOWN; // this is 0
+    (void)buffer->format()->findInt32("android._dataspace", (int32_t *)&dataSpace);
+
+    // HDR static info
+    std::shared_ptr<const C2StreamHdrStaticInfo::output> hdrStaticInfo =
+        std::static_pointer_cast<const C2StreamHdrStaticInfo::output>(
+                c2Buffer->getInfo(C2StreamHdrStaticInfo::output::PARAM_TYPE));
+
+    // HDR10 plus info
+    std::shared_ptr<const C2StreamHdr10PlusInfo::output> hdr10PlusInfo =
+        std::static_pointer_cast<const C2StreamHdr10PlusInfo::output>(
+                c2Buffer->getInfo(C2StreamHdr10PlusInfo::output::PARAM_TYPE));
+
+    {
+        Mutexed<OutputSurface>::Locked output(mOutputSurface);
+        if (output->surface == nullptr) {
+            ALOGI("[%s] cannot render buffer without surface", mName);
+            return OK;
+        }
+    }
+
+    std::vector<C2ConstGraphicBlock> blocks = c2Buffer->data().graphicBlocks();
+    if (blocks.size() != 1u) {
+        ALOGD("[%s] expected 1 graphic block, but got %zu", mName, blocks.size());
+        return UNKNOWN_ERROR;
+    }
+    const C2ConstGraphicBlock &block = blocks.front();
+
+    // TODO: revisit this after C2Fence implementation.
+    android::IGraphicBufferProducer::QueueBufferInput qbi(
+            timestampNs,
+            false, // droppable
+            dataSpace,
+            Rect(blocks.front().crop().left,
+                 blocks.front().crop().top,
+                 blocks.front().crop().right(),
+                 blocks.front().crop().bottom()),
+            videoScalingMode,
+            transform,
+            Fence::NO_FENCE, 0);
+    if (hdrStaticInfo || hdr10PlusInfo) {
+        HdrMetadata hdr;
+        if (hdrStaticInfo) {
+            struct android_smpte2086_metadata smpte2086_meta = {
+                .displayPrimaryRed = {
+                    hdrStaticInfo->mastering.red.x, hdrStaticInfo->mastering.red.y
+                },
+                .displayPrimaryGreen = {
+                    hdrStaticInfo->mastering.green.x, hdrStaticInfo->mastering.green.y
+                },
+                .displayPrimaryBlue = {
+                    hdrStaticInfo->mastering.blue.x, hdrStaticInfo->mastering.blue.y
+                },
+                .whitePoint = {
+                    hdrStaticInfo->mastering.white.x, hdrStaticInfo->mastering.white.y
+                },
+                .maxLuminance = hdrStaticInfo->mastering.maxLuminance,
+                .minLuminance = hdrStaticInfo->mastering.minLuminance,
+            };
+
+            struct android_cta861_3_metadata cta861_meta = {
+                .maxContentLightLevel = hdrStaticInfo->maxCll,
+                .maxFrameAverageLightLevel = hdrStaticInfo->maxFall,
+            };
+
+            hdr.validTypes = HdrMetadata::SMPTE2086 | HdrMetadata::CTA861_3;
+            hdr.smpte2086 = smpte2086_meta;
+            hdr.cta8613 = cta861_meta;
+        }
+        if (hdr10PlusInfo) {
+            hdr.validTypes |= HdrMetadata::HDR10PLUS;
+            hdr.hdr10plus.assign(
+                    hdr10PlusInfo->m.value,
+                    hdr10PlusInfo->m.value + hdr10PlusInfo->flexCount());
+        }
+        qbi.setHdrMetadata(hdr);
+    }
+    // we don't have dirty regions
+    qbi.setSurfaceDamage(Region::INVALID_REGION);
+    android::IGraphicBufferProducer::QueueBufferOutput qbo;
+    status_t result = mComponent->queueToOutputSurface(block, qbi, &qbo);
+    if (result != OK) {
+        ALOGI("[%s] queueBuffer failed: %d", mName, result);
+        return result;
+    }
+    ALOGV("[%s] queue buffer successful", mName);
+
+    int64_t mediaTimeUs = 0;
+    (void)buffer->meta()->findInt64("timeUs", &mediaTimeUs);
+    mCCodecCallback->onOutputFramesRendered(mediaTimeUs, timestampNs);
+
+    return OK;
+}
+
+status_t CCodecBufferChannel::discardBuffer(const sp<MediaCodecBuffer> &buffer) {
+    ALOGV("[%s] discardBuffer: %p", mName, buffer.get());
+    bool released = false;
+    {
+        Mutexed<Input>::Locked input(mInput);
+        if (input->buffers && input->buffers->releaseBuffer(buffer, nullptr, true)) {
+            released = true;
+        }
+    }
+    {
+        Mutexed<Output>::Locked output(mOutput);
+        if (output->buffers && output->buffers->releaseBuffer(buffer, nullptr)) {
+            released = true;
+        }
+    }
+    if (released) {
+        sendOutputBuffers();
+        feedInputBufferIfAvailable();
+    } else {
+        ALOGD("[%s] MediaCodec discarded an unknown buffer", mName);
+    }
+    return OK;
+}
+
+void CCodecBufferChannel::getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) {
+    array->clear();
+    Mutexed<Input>::Locked input(mInput);
+
+    if (!input->buffers->isArrayMode()) {
+        input->buffers = input->buffers->toArrayMode(input->numSlots);
+    }
+
+    input->buffers->getArray(array);
+}
+
+void CCodecBufferChannel::getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) {
+    array->clear();
+    Mutexed<Output>::Locked output(mOutput);
+
+    if (!output->buffers->isArrayMode()) {
+        output->buffers = output->buffers->toArrayMode(output->numSlots);
+    }
+
+    output->buffers->getArray(array);
+}
+
+status_t CCodecBufferChannel::start(
+        const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat) {
+    C2StreamBufferTypeSetting::input iStreamFormat(0u);
+    C2StreamBufferTypeSetting::output oStreamFormat(0u);
+    C2PortReorderBufferDepthTuning::output reorderDepth;
+    C2PortReorderKeySetting::output reorderKey;
+    C2PortActualDelayTuning::input inputDelay(0);
+    C2PortActualDelayTuning::output outputDelay(0);
+    C2ActualPipelineDelayTuning pipelineDelay(0);
+
+    c2_status_t err = mComponent->query(
+            {
+                &iStreamFormat,
+                &oStreamFormat,
+                &reorderDepth,
+                &reorderKey,
+                &inputDelay,
+                &pipelineDelay,
+                &outputDelay,
+            },
+            {},
+            C2_DONT_BLOCK,
+            nullptr);
+    if (err == C2_BAD_INDEX) {
+        if (!iStreamFormat || !oStreamFormat) {
+            return UNKNOWN_ERROR;
+        }
+    } else if (err != C2_OK) {
+        return UNKNOWN_ERROR;
+    }
+
+    {
+        Mutexed<ReorderStash>::Locked reorder(mReorderStash);
+        reorder->clear();
+        if (reorderDepth) {
+            reorder->setDepth(reorderDepth.value);
+        }
+        if (reorderKey) {
+            reorder->setKey(reorderKey.value);
+        }
+    }
+
+    uint32_t inputDelayValue = inputDelay ? inputDelay.value : 0;
+    uint32_t pipelineDelayValue = pipelineDelay ? pipelineDelay.value : 0;
+    uint32_t outputDelayValue = outputDelay ? outputDelay.value : 0;
+
+    size_t numInputSlots = inputDelayValue + pipelineDelayValue + kSmoothnessFactor;
+    size_t numOutputSlots = outputDelayValue + kSmoothnessFactor;
+
+    // TODO: get this from input format
+    bool secure = mComponent->getName().find(".secure") != std::string::npos;
+
+    std::shared_ptr<C2AllocatorStore> allocatorStore = GetCodec2PlatformAllocatorStore();
+    int poolMask = property_get_int32(
+            "debug.stagefright.c2-poolmask",
+            1 << C2PlatformAllocatorStore::ION |
+            1 << C2PlatformAllocatorStore::BUFFERQUEUE);
+
+    if (inputFormat != nullptr) {
+        bool graphic = (iStreamFormat.value == C2BufferData::GRAPHIC);
+        std::shared_ptr<C2BlockPool> pool;
+        {
+            Mutexed<BlockPools>::Locked pools(mBlockPools);
+
+            // set default allocator ID.
+            pools->inputAllocatorId = (graphic) ? C2PlatformAllocatorStore::GRALLOC
+                                                : C2PlatformAllocatorStore::ION;
+
+            // query C2PortAllocatorsTuning::input from component. If an allocator ID is obtained
+            // from component, create the input block pool with given ID. Otherwise, use default IDs.
+            std::vector<std::unique_ptr<C2Param>> params;
+            err = mComponent->query({ },
+                                    { C2PortAllocatorsTuning::input::PARAM_TYPE },
+                                    C2_DONT_BLOCK,
+                                    &params);
+            if ((err != C2_OK && err != C2_BAD_INDEX) || params.size() != 1) {
+                ALOGD("[%s] Query input allocators returned %zu params => %s (%u)",
+                        mName, params.size(), asString(err), err);
+            } else if (err == C2_OK && params.size() == 1) {
+                C2PortAllocatorsTuning::input *inputAllocators =
+                    C2PortAllocatorsTuning::input::From(params[0].get());
+                if (inputAllocators && inputAllocators->flexCount() > 0) {
+                    std::shared_ptr<C2Allocator> allocator;
+                    // verify allocator IDs and resolve default allocator
+                    allocatorStore->fetchAllocator(inputAllocators->m.values[0], &allocator);
+                    if (allocator) {
+                        pools->inputAllocatorId = allocator->getId();
+                    } else {
+                        ALOGD("[%s] component requested invalid input allocator ID %u",
+                                mName, inputAllocators->m.values[0]);
+                    }
+                }
+            }
+
+            // TODO: use C2Component wrapper to associate this pool with ourselves
+            if ((poolMask >> pools->inputAllocatorId) & 1) {
+                err = CreateCodec2BlockPool(pools->inputAllocatorId, nullptr, &pool);
+                ALOGD("[%s] Created input block pool with allocatorID %u => poolID %llu - %s (%d)",
+                        mName, pools->inputAllocatorId,
+                        (unsigned long long)(pool ? pool->getLocalId() : 111000111),
+                        asString(err), err);
+            } else {
+                err = C2_NOT_FOUND;
+            }
+            if (err != C2_OK) {
+                C2BlockPool::local_id_t inputPoolId =
+                    graphic ? C2BlockPool::BASIC_GRAPHIC : C2BlockPool::BASIC_LINEAR;
+                err = GetCodec2BlockPool(inputPoolId, nullptr, &pool);
+                ALOGD("[%s] Using basic input block pool with poolID %llu => got %llu - %s (%d)",
+                        mName, (unsigned long long)inputPoolId,
+                        (unsigned long long)(pool ? pool->getLocalId() : 111000111),
+                        asString(err), err);
+                if (err != C2_OK) {
+                    return NO_MEMORY;
+                }
+            }
+            pools->inputPool = pool;
+        }
+
+        bool forceArrayMode = false;
+        Mutexed<Input>::Locked input(mInput);
+        input->inputDelay = inputDelayValue;
+        input->pipelineDelay = pipelineDelayValue;
+        input->numSlots = numInputSlots;
+        input->extraBuffers.flush();
+        input->numExtraSlots = 0u;
+        if (graphic) {
+            if (mInputSurface) {
+                input->buffers.reset(new DummyInputBuffers(mName));
+            } else if (mMetaMode == MODE_ANW) {
+                input->buffers.reset(new GraphicMetadataInputBuffers(mName));
+                // This is to ensure buffers do not get released prematurely.
+                // TODO: handle this without going into array mode
+                forceArrayMode = true;
+            } else {
+                input->buffers.reset(new GraphicInputBuffers(numInputSlots, mName));
+            }
+        } else {
+            if (hasCryptoOrDescrambler()) {
+                int32_t capacity = kLinearBufferSize;
+                (void)inputFormat->findInt32(KEY_MAX_INPUT_SIZE, &capacity);
+                if ((size_t)capacity > kMaxLinearBufferSize) {
+                    ALOGD("client requested %d, capped to %zu", capacity, kMaxLinearBufferSize);
+                    capacity = kMaxLinearBufferSize;
+                }
+                if (mDealer == nullptr) {
+                    mDealer = new MemoryDealer(
+                            align(capacity, MemoryDealer::getAllocationAlignment())
+                                * (numInputSlots + 1),
+                            "EncryptedLinearInputBuffers");
+                    mDecryptDestination = mDealer->allocate((size_t)capacity);
+                }
+                if (mCrypto != nullptr && mHeapSeqNum < 0) {
+                    mHeapSeqNum = mCrypto->setHeap(mDealer->getMemoryHeap());
+                } else {
+                    mHeapSeqNum = -1;
+                }
+                input->buffers.reset(new EncryptedLinearInputBuffers(
+                        secure, mDealer, mCrypto, mHeapSeqNum, (size_t)capacity,
+                        numInputSlots, mName));
+                forceArrayMode = true;
+            } else {
+                input->buffers.reset(new LinearInputBuffers(mName));
+            }
+        }
+        input->buffers->setFormat(inputFormat);
+
+        if (err == C2_OK) {
+            input->buffers->setPool(pool);
+        } else {
+            // TODO: error
+        }
+
+        if (forceArrayMode) {
+            input->buffers = input->buffers->toArrayMode(numInputSlots);
+        }
+    }
+
+    if (outputFormat != nullptr) {
+        sp<IGraphicBufferProducer> outputSurface;
+        uint32_t outputGeneration;
+        {
+            Mutexed<OutputSurface>::Locked output(mOutputSurface);
+            output->maxDequeueBuffers = numOutputSlots + reorderDepth.value + kRenderingDepth;
+            outputSurface = output->surface ?
+                    output->surface->getIGraphicBufferProducer() : nullptr;
+            if (outputSurface) {
+                output->surface->setMaxDequeuedBufferCount(output->maxDequeueBuffers);
+            }
+            outputGeneration = output->generation;
+        }
+
+        bool graphic = (oStreamFormat.value == C2BufferData::GRAPHIC);
+        C2BlockPool::local_id_t outputPoolId_;
+
+        {
+            Mutexed<BlockPools>::Locked pools(mBlockPools);
+
+            // set default allocator ID.
+            pools->outputAllocatorId = (graphic) ? C2PlatformAllocatorStore::GRALLOC
+                                                 : C2PlatformAllocatorStore::ION;
+
+            // query C2PortAllocatorsTuning::output from component, or use default allocator if
+            // unsuccessful.
+            std::vector<std::unique_ptr<C2Param>> params;
+            err = mComponent->query({ },
+                                    { C2PortAllocatorsTuning::output::PARAM_TYPE },
+                                    C2_DONT_BLOCK,
+                                    &params);
+            if ((err != C2_OK && err != C2_BAD_INDEX) || params.size() != 1) {
+                ALOGD("[%s] Query output allocators returned %zu params => %s (%u)",
+                        mName, params.size(), asString(err), err);
+            } else if (err == C2_OK && params.size() == 1) {
+                C2PortAllocatorsTuning::output *outputAllocators =
+                    C2PortAllocatorsTuning::output::From(params[0].get());
+                if (outputAllocators && outputAllocators->flexCount() > 0) {
+                    std::shared_ptr<C2Allocator> allocator;
+                    // verify allocator IDs and resolve default allocator
+                    allocatorStore->fetchAllocator(outputAllocators->m.values[0], &allocator);
+                    if (allocator) {
+                        pools->outputAllocatorId = allocator->getId();
+                    } else {
+                        ALOGD("[%s] component requested invalid output allocator ID %u",
+                                mName, outputAllocators->m.values[0]);
+                    }
+                }
+            }
+
+            // use bufferqueue if outputting to a surface.
+            // query C2PortSurfaceAllocatorTuning::output from component, or use default allocator
+            // if unsuccessful.
+            if (outputSurface) {
+                params.clear();
+                err = mComponent->query({ },
+                                        { C2PortSurfaceAllocatorTuning::output::PARAM_TYPE },
+                                        C2_DONT_BLOCK,
+                                        &params);
+                if ((err != C2_OK && err != C2_BAD_INDEX) || params.size() != 1) {
+                    ALOGD("[%s] Query output surface allocator returned %zu params => %s (%u)",
+                            mName, params.size(), asString(err), err);
+                } else if (err == C2_OK && params.size() == 1) {
+                    C2PortSurfaceAllocatorTuning::output *surfaceAllocator =
+                        C2PortSurfaceAllocatorTuning::output::From(params[0].get());
+                    if (surfaceAllocator) {
+                        std::shared_ptr<C2Allocator> allocator;
+                        // verify allocator IDs and resolve default allocator
+                        allocatorStore->fetchAllocator(surfaceAllocator->value, &allocator);
+                        if (allocator) {
+                            pools->outputAllocatorId = allocator->getId();
+                        } else {
+                            ALOGD("[%s] component requested invalid surface output allocator ID %u",
+                                    mName, surfaceAllocator->value);
+                            err = C2_BAD_VALUE;
+                        }
+                    }
+                }
+                if (pools->outputAllocatorId == C2PlatformAllocatorStore::GRALLOC
+                        && err != C2_OK
+                        && ((poolMask >> C2PlatformAllocatorStore::BUFFERQUEUE) & 1)) {
+                    pools->outputAllocatorId = C2PlatformAllocatorStore::BUFFERQUEUE;
+                }
+            }
+
+            if ((poolMask >> pools->outputAllocatorId) & 1) {
+                err = mComponent->createBlockPool(
+                        pools->outputAllocatorId, &pools->outputPoolId, &pools->outputPoolIntf);
+                ALOGI("[%s] Created output block pool with allocatorID %u => poolID %llu - %s",
+                        mName, pools->outputAllocatorId,
+                        (unsigned long long)pools->outputPoolId,
+                        asString(err));
+            } else {
+                err = C2_NOT_FOUND;
+            }
+            if (err != C2_OK) {
+                // use basic pool instead
+                pools->outputPoolId =
+                    graphic ? C2BlockPool::BASIC_GRAPHIC : C2BlockPool::BASIC_LINEAR;
+            }
+
+            // Configure output block pool ID as parameter C2PortBlockPoolsTuning::output to
+            // component.
+            std::unique_ptr<C2PortBlockPoolsTuning::output> poolIdsTuning =
+                    C2PortBlockPoolsTuning::output::AllocUnique({ pools->outputPoolId });
+
+            std::vector<std::unique_ptr<C2SettingResult>> failures;
+            err = mComponent->config({ poolIdsTuning.get() }, C2_MAY_BLOCK, &failures);
+            ALOGD("[%s] Configured output block pool ids %llu => %s",
+                    mName, (unsigned long long)poolIdsTuning->m.values[0], asString(err));
+            outputPoolId_ = pools->outputPoolId;
+        }
+
+        Mutexed<Output>::Locked output(mOutput);
+        output->outputDelay = outputDelayValue;
+        output->numSlots = numOutputSlots;
+        if (graphic) {
+            if (outputSurface) {
+                output->buffers.reset(new GraphicOutputBuffers(mName));
+            } else {
+                output->buffers.reset(new RawGraphicOutputBuffers(numOutputSlots, mName));
+            }
+        } else {
+            output->buffers.reset(new LinearOutputBuffers(mName));
+        }
+        output->buffers->setFormat(outputFormat->dup());
+
+
+        // Try to set output surface to created block pool if given.
+        if (outputSurface) {
+            mComponent->setOutputSurface(
+                    outputPoolId_,
+                    outputSurface,
+                    outputGeneration);
+        }
+
+        if (oStreamFormat.value == C2BufferData::LINEAR
+                && mComponentName.find("c2.qti.") == std::string::npos) {
+            // WORKAROUND: if we're using early CSD workaround we convert to
+            //             array mode, to appease apps assuming the output
+            //             buffers to be of the same size.
+            output->buffers = output->buffers->toArrayMode(numOutputSlots);
+
+            int32_t channelCount;
+            int32_t sampleRate;
+            if (outputFormat->findInt32(KEY_CHANNEL_COUNT, &channelCount)
+                    && outputFormat->findInt32(KEY_SAMPLE_RATE, &sampleRate)) {
+                int32_t delay = 0;
+                int32_t padding = 0;;
+                if (!outputFormat->findInt32("encoder-delay", &delay)) {
+                    delay = 0;
+                }
+                if (!outputFormat->findInt32("encoder-padding", &padding)) {
+                    padding = 0;
+                }
+                if (delay || padding) {
+                    // We need write access to the buffers, and we're already in
+                    // array mode.
+                    output->buffers->initSkipCutBuffer(delay, padding, sampleRate, channelCount);
+                }
+            }
+        }
+    }
+
+    // Set up pipeline control. This has to be done after mInputBuffers and
+    // mOutputBuffers are initialized to make sure that lingering callbacks
+    // about buffers from the previous generation do not interfere with the
+    // newly initialized pipeline capacity.
+
+    {
+        Mutexed<PipelineWatcher>::Locked watcher(mPipelineWatcher);
+        watcher->inputDelay(inputDelayValue)
+                .pipelineDelay(pipelineDelayValue)
+                .outputDelay(outputDelayValue)
+                .smoothnessFactor(kSmoothnessFactor);
+        watcher->flush();
+    }
+
+    mInputMetEos = false;
+    mSync.start();
+    return OK;
+}
+
+status_t CCodecBufferChannel::requestInitialInputBuffers() {
+    if (mInputSurface) {
+        return OK;
+    }
+
+    C2StreamBufferTypeSetting::output oStreamFormat(0u);
+    c2_status_t err = mComponent->query({ &oStreamFormat }, {}, C2_DONT_BLOCK, nullptr);
+    if (err != C2_OK) {
+        return UNKNOWN_ERROR;
+    }
+    size_t numInputSlots = mInput.lock()->numSlots;
+    std::vector<sp<MediaCodecBuffer>> toBeQueued;
+    for (size_t i = 0; i < numInputSlots; ++i) {
+        size_t index;
+        sp<MediaCodecBuffer> buffer;
+        {
+            Mutexed<Input>::Locked input(mInput);
+            if (!input->buffers->requestNewBuffer(&index, &buffer)) {
+                if (i == 0) {
+                    ALOGW("[%s] start: cannot allocate memory at all", mName);
+                    return NO_MEMORY;
+                } else {
+                    ALOGV("[%s] start: cannot allocate memory, only %zu buffers allocated",
+                            mName, i);
+                }
+                break;
+            }
+        }
+        if (buffer) {
+            Mutexed<std::list<sp<ABuffer>>>::Locked configs(mFlushedConfigs);
+            ALOGV("[%s] input buffer %zu available", mName, index);
+            bool post = true;
+            if (!configs->empty()) {
+                sp<ABuffer> config = configs->front();
+                configs->pop_front();
+                if (buffer->capacity() >= config->size()) {
+                    memcpy(buffer->base(), config->data(), config->size());
+                    buffer->setRange(0, config->size());
+                    buffer->meta()->clear();
+                    buffer->meta()->setInt64("timeUs", 0);
+                    buffer->meta()->setInt32("csd", 1);
+                    post = false;
+                } else {
+                    ALOGD("[%s] buffer capacity too small for the config (%zu < %zu)",
+                            mName, buffer->capacity(), config->size());
+                }
+            } else if (oStreamFormat.value == C2BufferData::LINEAR && i == 0
+                    && mComponentName.find("c2.qti.") == std::string::npos) {
+                // WORKAROUND: Some apps expect CSD available without queueing
+                //             any input. Queue an empty buffer to get the CSD.
+                buffer->setRange(0, 0);
+                buffer->meta()->clear();
+                buffer->meta()->setInt64("timeUs", 0);
+                post = false;
+            }
+            if (post) {
+                mCallback->onInputBufferAvailable(index, buffer);
+            } else {
+                toBeQueued.emplace_back(buffer);
+            }
+        }
+    }
+    for (const sp<MediaCodecBuffer> &buffer : toBeQueued) {
+        if (queueInputBufferInternal(buffer) != OK) {
+            ALOGV("[%s] Error while queueing initial buffers", mName);
+        }
+    }
+    return OK;
+}
+
+void CCodecBufferChannel::stop() {
+    mSync.stop();
+    mFirstValidFrameIndex = mFrameIndex.load(std::memory_order_relaxed);
+    if (mInputSurface != nullptr) {
+        mInputSurface.reset();
+    }
+}
+
+void CCodecBufferChannel::flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) {
+    ALOGV("[%s] flush", mName);
+    {
+        Mutexed<std::list<sp<ABuffer>>>::Locked configs(mFlushedConfigs);
+        for (const std::unique_ptr<C2Work> &work : flushedWork) {
+            if (!(work->input.flags & C2FrameData::FLAG_CODEC_CONFIG)) {
+                continue;
+            }
+            if (work->input.buffers.empty()
+                    || work->input.buffers.front()->data().linearBlocks().empty()) {
+                ALOGD("[%s] no linear codec config data found", mName);
+                continue;
+            }
+            C2ReadView view =
+                    work->input.buffers.front()->data().linearBlocks().front().map().get();
+            if (view.error() != C2_OK) {
+                ALOGD("[%s] failed to map flushed codec config data: %d", mName, view.error());
+                continue;
+            }
+            configs->push_back(ABuffer::CreateAsCopy(view.data(), view.capacity()));
+            ALOGV("[%s] stashed flushed codec config data (size=%u)", mName, view.capacity());
+        }
+    }
+    {
+        Mutexed<Input>::Locked input(mInput);
+        input->buffers->flush();
+        input->extraBuffers.flush();
+    }
+    {
+        Mutexed<Output>::Locked output(mOutput);
+        output->buffers->flush(flushedWork);
+    }
+    mReorderStash.lock()->flush();
+    mPipelineWatcher.lock()->flush();
+}
+
+void CCodecBufferChannel::onWorkDone(
+        std::unique_ptr<C2Work> work, const sp<AMessage> &outputFormat,
+        const C2StreamInitDataInfo::output *initData) {
+    if (handleWork(std::move(work), outputFormat, initData)) {
+        feedInputBufferIfAvailable();
+    }
+}
+
+void CCodecBufferChannel::onInputBufferDone(
+        uint64_t frameIndex, size_t arrayIndex) {
+    if (mInputSurface) {
+        return;
+    }
+    std::shared_ptr<C2Buffer> buffer =
+            mPipelineWatcher.lock()->onInputBufferReleased(frameIndex, arrayIndex);
+    bool newInputSlotAvailable;
+    {
+        Mutexed<Input>::Locked input(mInput);
+        newInputSlotAvailable = input->buffers->expireComponentBuffer(buffer);
+        if (!newInputSlotAvailable) {
+            (void)input->extraBuffers.expireComponentBuffer(buffer);
+        }
+    }
+    if (newInputSlotAvailable) {
+        feedInputBufferIfAvailable();
+    }
+}
+
+bool CCodecBufferChannel::handleWork(
+        std::unique_ptr<C2Work> work,
+        const sp<AMessage> &outputFormat,
+        const C2StreamInitDataInfo::output *initData) {
+    if ((work->input.ordinal.frameIndex - mFirstValidFrameIndex.load()).peek() < 0) {
+        // Discard frames from previous generation.
+        ALOGD("[%s] Discard frames from previous generation.", mName);
+        return false;
+    }
+
+    if (mInputSurface == nullptr && (work->worklets.size() != 1u
+            || !work->worklets.front()
+            || !(work->worklets.front()->output.flags & C2FrameData::FLAG_INCOMPLETE))) {
+        mPipelineWatcher.lock()->onWorkDone(work->input.ordinal.frameIndex.peeku());
+    }
+
+    if (work->result == C2_NOT_FOUND) {
+        ALOGD("[%s] flushed work; ignored.", mName);
+        return true;
+    }
+
+    if (work->result != C2_OK) {
+        ALOGD("[%s] work failed to complete: %d", mName, work->result);
+        mCCodecCallback->onError(work->result, ACTION_CODE_FATAL);
+        return false;
+    }
+
+    // NOTE: MediaCodec usage supposedly have only one worklet
+    if (work->worklets.size() != 1u) {
+        ALOGI("[%s] onWorkDone: incorrect number of worklets: %zu",
+                mName, work->worklets.size());
+        mCCodecCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
+        return false;
+    }
+
+    const std::unique_ptr<C2Worklet> &worklet = work->worklets.front();
+
+    std::shared_ptr<C2Buffer> buffer;
+    // NOTE: MediaCodec usage supposedly have only one output stream.
+    if (worklet->output.buffers.size() > 1u) {
+        ALOGI("[%s] onWorkDone: incorrect number of output buffers: %zu",
+                mName, worklet->output.buffers.size());
+        mCCodecCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
+        return false;
+    } else if (worklet->output.buffers.size() == 1u) {
+        buffer = worklet->output.buffers[0];
+        if (!buffer) {
+            ALOGD("[%s] onWorkDone: nullptr found in buffers; ignored.", mName);
+        }
+    }
+
+    std::optional<uint32_t> newInputDelay, newPipelineDelay;
+    while (!worklet->output.configUpdate.empty()) {
+        std::unique_ptr<C2Param> param;
+        worklet->output.configUpdate.back().swap(param);
+        worklet->output.configUpdate.pop_back();
+        switch (param->coreIndex().coreIndex()) {
+            case C2PortReorderBufferDepthTuning::CORE_INDEX: {
+                C2PortReorderBufferDepthTuning::output reorderDepth;
+                if (reorderDepth.updateFrom(*param)) {
+                    mReorderStash.lock()->setDepth(reorderDepth.value);
+                    ALOGV("[%s] onWorkDone: updated reorder depth to %u",
+                          mName, reorderDepth.value);
+                    size_t numOutputSlots = mOutput.lock()->numSlots;
+                    Mutexed<OutputSurface>::Locked output(mOutputSurface);
+                    output->maxDequeueBuffers =
+                        numOutputSlots + reorderDepth.value + kRenderingDepth;
+                    if (output->surface) {
+                        output->surface->setMaxDequeuedBufferCount(output->maxDequeueBuffers);
+                    }
+                } else {
+                    ALOGD("[%s] onWorkDone: failed to read reorder depth", mName);
+                }
+                break;
+            }
+            case C2PortReorderKeySetting::CORE_INDEX: {
+                C2PortReorderKeySetting::output reorderKey;
+                if (reorderKey.updateFrom(*param)) {
+                    mReorderStash.lock()->setKey(reorderKey.value);
+                    ALOGV("[%s] onWorkDone: updated reorder key to %u",
+                          mName, reorderKey.value);
+                } else {
+                    ALOGD("[%s] onWorkDone: failed to read reorder key", mName);
+                }
+                break;
+            }
+            case C2PortActualDelayTuning::CORE_INDEX: {
+                if (param->isGlobal()) {
+                    C2ActualPipelineDelayTuning pipelineDelay;
+                    if (pipelineDelay.updateFrom(*param)) {
+                        ALOGV("[%s] onWorkDone: updating pipeline delay %u",
+                              mName, pipelineDelay.value);
+                        newPipelineDelay = pipelineDelay.value;
+                        (void)mPipelineWatcher.lock()->pipelineDelay(pipelineDelay.value);
+                    }
+                }
+                if (param->forInput()) {
+                    C2PortActualDelayTuning::input inputDelay;
+                    if (inputDelay.updateFrom(*param)) {
+                        ALOGV("[%s] onWorkDone: updating input delay %u",
+                              mName, inputDelay.value);
+                        newInputDelay = inputDelay.value;
+                        (void)mPipelineWatcher.lock()->inputDelay(inputDelay.value);
+                    }
+                }
+                if (param->forOutput()) {
+                    C2PortActualDelayTuning::output outputDelay;
+                    if (outputDelay.updateFrom(*param)) {
+                        ALOGV("[%s] onWorkDone: updating output delay %u",
+                              mName, outputDelay.value);
+                        (void)mPipelineWatcher.lock()->outputDelay(outputDelay.value);
+
+                        bool outputBuffersChanged = false;
+                        size_t numOutputSlots = 0;
+                        {
+                            Mutexed<Output>::Locked output(mOutput);
+                            output->outputDelay = outputDelay.value;
+                            numOutputSlots = outputDelay.value + kSmoothnessFactor;
+                            if (output->numSlots < numOutputSlots) {
+                                output->numSlots = numOutputSlots;
+                                if (output->buffers->isArrayMode()) {
+                                    OutputBuffersArray *array =
+                                        (OutputBuffersArray *)output->buffers.get();
+                                    ALOGV("[%s] onWorkDone: growing output buffer array to %zu",
+                                          mName, numOutputSlots);
+                                    array->grow(numOutputSlots);
+                                    outputBuffersChanged = true;
+                                }
+                            }
+                            numOutputSlots = output->numSlots;
+                        }
+
+                        if (outputBuffersChanged) {
+                            mCCodecCallback->onOutputBuffersChanged();
+                        }
+
+                        uint32_t depth = mReorderStash.lock()->depth();
+                        Mutexed<OutputSurface>::Locked output(mOutputSurface);
+                        output->maxDequeueBuffers = numOutputSlots + depth + kRenderingDepth;
+                        if (output->surface) {
+                            output->surface->setMaxDequeuedBufferCount(output->maxDequeueBuffers);
+                        }
+                    }
+                }
+                break;
+            }
+            default:
+                ALOGV("[%s] onWorkDone: unrecognized config update (%08X)",
+                      mName, param->index());
+                break;
+        }
+    }
+    if (newInputDelay || newPipelineDelay) {
+        Mutexed<Input>::Locked input(mInput);
+        size_t newNumSlots =
+            newInputDelay.value_or(input->inputDelay) +
+            newPipelineDelay.value_or(input->pipelineDelay) +
+            kSmoothnessFactor;
+        if (input->buffers->isArrayMode()) {
+            if (input->numSlots >= newNumSlots) {
+                input->numExtraSlots = 0;
+            } else {
+                input->numExtraSlots = newNumSlots - input->numSlots;
+            }
+            ALOGV("[%s] onWorkDone: updated number of extra slots to %zu (input array mode)",
+                  mName, input->numExtraSlots);
+        } else {
+            input->numSlots = newNumSlots;
+        }
+    }
+
+    if (outputFormat != nullptr) {
+        Mutexed<Output>::Locked output(mOutput);
+        ALOGD("[%s] onWorkDone: output format changed to %s",
+                mName, outputFormat->debugString().c_str());
+        output->buffers->setFormat(outputFormat);
+
+        AString mediaType;
+        if (outputFormat->findString(KEY_MIME, &mediaType)
+                && mediaType == MIMETYPE_AUDIO_RAW) {
+            int32_t channelCount;
+            int32_t sampleRate;
+            if (outputFormat->findInt32(KEY_CHANNEL_COUNT, &channelCount)
+                    && outputFormat->findInt32(KEY_SAMPLE_RATE, &sampleRate)) {
+                output->buffers->updateSkipCutBuffer(sampleRate, channelCount);
+            }
+        }
+    }
+
+    int32_t flags = 0;
+    if (worklet->output.flags & C2FrameData::FLAG_END_OF_STREAM) {
+        flags |= MediaCodec::BUFFER_FLAG_EOS;
+        ALOGV("[%s] onWorkDone: output EOS", mName);
+    }
+
+    sp<MediaCodecBuffer> outBuffer;
+    size_t index;
+
+    // WORKAROUND: adjust output timestamp based on client input timestamp and codec
+    // input timestamp. Codec output timestamp (in the timestamp field) shall correspond to
+    // the codec input timestamp, but client output timestamp should (reported in timeUs)
+    // shall correspond to the client input timesamp (in customOrdinal). By using the
+    // delta between the two, this allows for some timestamp deviation - e.g. if one input
+    // produces multiple output.
+    c2_cntr64_t timestamp =
+        worklet->output.ordinal.timestamp + work->input.ordinal.customOrdinal
+                - work->input.ordinal.timestamp;
+    if (mInputSurface != nullptr) {
+        // When using input surface we need to restore the original input timestamp.
+        timestamp = work->input.ordinal.customOrdinal;
+    }
+    ALOGV("[%s] onWorkDone: input %lld, codec %lld => output %lld => %lld",
+          mName,
+          work->input.ordinal.customOrdinal.peekll(),
+          work->input.ordinal.timestamp.peekll(),
+          worklet->output.ordinal.timestamp.peekll(),
+          timestamp.peekll());
+
+    if (initData != nullptr) {
+        Mutexed<Output>::Locked output(mOutput);
+        if (output->buffers->registerCsd(initData, &index, &outBuffer) == OK) {
+            outBuffer->meta()->setInt64("timeUs", timestamp.peek());
+            outBuffer->meta()->setInt32("flags", MediaCodec::BUFFER_FLAG_CODECCONFIG);
+            ALOGV("[%s] onWorkDone: csd index = %zu [%p]", mName, index, outBuffer.get());
+
+            output.unlock();
+            mCallback->onOutputBufferAvailable(index, outBuffer);
+        } else {
+            ALOGD("[%s] onWorkDone: unable to register csd", mName);
+            output.unlock();
+            mCCodecCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
+            return false;
+        }
+    }
+
+    if (!buffer && !flags) {
+        ALOGV("[%s] onWorkDone: Not reporting output buffer (%lld)",
+              mName, work->input.ordinal.frameIndex.peekull());
+        return true;
+    }
+
+    if (buffer) {
+        for (const std::shared_ptr<const C2Info> &info : buffer->info()) {
+            // TODO: properly translate these to metadata
+            switch (info->coreIndex().coreIndex()) {
+                case C2StreamPictureTypeMaskInfo::CORE_INDEX:
+                    if (((C2StreamPictureTypeMaskInfo *)info.get())->value & C2Config::SYNC_FRAME) {
+                        flags |= MediaCodec::BUFFER_FLAG_SYNCFRAME;
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    {
+        Mutexed<ReorderStash>::Locked reorder(mReorderStash);
+        reorder->emplace(buffer, timestamp.peek(), flags, worklet->output.ordinal);
+        if (flags & MediaCodec::BUFFER_FLAG_EOS) {
+            // Flush reorder stash
+            reorder->setDepth(0);
+        }
+    }
+    sendOutputBuffers();
+    return true;
+}
+
+void CCodecBufferChannel::sendOutputBuffers() {
+    ReorderStash::Entry entry;
+    sp<MediaCodecBuffer> outBuffer;
+    size_t index;
+
+    while (true) {
+        Mutexed<ReorderStash>::Locked reorder(mReorderStash);
+        if (!reorder->hasPending()) {
+            break;
+        }
+        if (!reorder->pop(&entry)) {
+            break;
+        }
+
+        Mutexed<Output>::Locked output(mOutput);
+        status_t err = output->buffers->registerBuffer(entry.buffer, &index, &outBuffer);
+        if (err != OK) {
+            bool outputBuffersChanged = false;
+            if (err != WOULD_BLOCK) {
+                if (!output->buffers->isArrayMode()) {
+                    output->buffers = output->buffers->toArrayMode(output->numSlots);
+                }
+                OutputBuffersArray *array = (OutputBuffersArray *)output->buffers.get();
+                array->realloc(entry.buffer);
+                outputBuffersChanged = true;
+            }
+            ALOGV("[%s] sendOutputBuffers: unable to register output buffer", mName);
+            reorder->defer(entry);
+
+            output.unlock();
+            reorder.unlock();
+
+            if (outputBuffersChanged) {
+                mCCodecCallback->onOutputBuffersChanged();
+            }
+            return;
+        }
+        output.unlock();
+        reorder.unlock();
+
+        outBuffer->meta()->setInt64("timeUs", entry.timestamp);
+        outBuffer->meta()->setInt32("flags", entry.flags);
+        ALOGV("[%s] sendOutputBuffers: out buffer index = %zu [%p] => %p + %zu (%lld)",
+                mName, index, outBuffer.get(), outBuffer->data(), outBuffer->size(),
+                (long long)entry.timestamp);
+        mCallback->onOutputBufferAvailable(index, outBuffer);
+    }
+}
+
+status_t CCodecBufferChannel::setSurface(const sp<Surface> &newSurface) {
+    static std::atomic_uint32_t surfaceGeneration{0};
+    uint32_t generation = (getpid() << 10) |
+            ((surfaceGeneration.fetch_add(1, std::memory_order_relaxed) + 1)
+                & ((1 << 10) - 1));
+
+    sp<IGraphicBufferProducer> producer;
+    if (newSurface) {
+        newSurface->setScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
+        newSurface->setDequeueTimeout(kDequeueTimeoutNs);
+        newSurface->setMaxDequeuedBufferCount(mOutputSurface.lock()->maxDequeueBuffers);
+        producer = newSurface->getIGraphicBufferProducer();
+        producer->setGenerationNumber(generation);
+    } else {
+        ALOGE("[%s] setting output surface to null", mName);
+        return INVALID_OPERATION;
+    }
+
+    std::shared_ptr<Codec2Client::Configurable> outputPoolIntf;
+    C2BlockPool::local_id_t outputPoolId;
+    {
+        Mutexed<BlockPools>::Locked pools(mBlockPools);
+        outputPoolId = pools->outputPoolId;
+        outputPoolIntf = pools->outputPoolIntf;
+    }
+
+    if (outputPoolIntf) {
+        if (mComponent->setOutputSurface(
+                outputPoolId,
+                producer,
+                generation) != C2_OK) {
+            ALOGI("[%s] setSurface: component setOutputSurface failed", mName);
+            return INVALID_OPERATION;
+        }
+    }
+
+    {
+        Mutexed<OutputSurface>::Locked output(mOutputSurface);
+        output->surface = newSurface;
+        output->generation = generation;
+    }
+
+    return OK;
+}
+
+PipelineWatcher::Clock::duration CCodecBufferChannel::elapsed() {
+    // When client pushed EOS, we want all the work to be done quickly.
+    // Otherwise, component may have stalled work due to input starvation up to
+    // the sum of the delay in the pipeline.
+    size_t n = 0;
+    if (!mInputMetEos) {
+        size_t outputDelay = mOutput.lock()->outputDelay;
+        Mutexed<Input>::Locked input(mInput);
+        n = input->inputDelay + input->pipelineDelay + outputDelay;
+    }
+    return mPipelineWatcher.lock()->elapsed(PipelineWatcher::Clock::now(), n);
+}
+
+void CCodecBufferChannel::setMetaMode(MetaMode mode) {
+    mMetaMode = mode;
+}
+
+status_t toStatusT(c2_status_t c2s, c2_operation_t c2op) {
+    // C2_OK is always translated to OK.
+    if (c2s == C2_OK) {
+        return OK;
+    }
+
+    // Operation-dependent translation
+    // TODO: Add as necessary
+    switch (c2op) {
+    case C2_OPERATION_Component_start:
+        switch (c2s) {
+        case C2_NO_MEMORY:
+            return NO_MEMORY;
+        default:
+            return UNKNOWN_ERROR;
+        }
+    default:
+        break;
+    }
+
+    // Backup operation-agnostic translation
+    switch (c2s) {
+    case C2_BAD_INDEX:
+        return BAD_INDEX;
+    case C2_BAD_VALUE:
+        return BAD_VALUE;
+    case C2_BLOCKING:
+        return WOULD_BLOCK;
+    case C2_DUPLICATE:
+        return ALREADY_EXISTS;
+    case C2_NO_INIT:
+        return NO_INIT;
+    case C2_NO_MEMORY:
+        return NO_MEMORY;
+    case C2_NOT_FOUND:
+        return NAME_NOT_FOUND;
+    case C2_TIMED_OUT:
+        return TIMED_OUT;
+    case C2_BAD_STATE:
+    case C2_CANCELED:
+    case C2_CANNOT_DO:
+    case C2_CORRUPTED:
+    case C2_OMITTED:
+    case C2_REFUSED:
+        return UNKNOWN_ERROR;
+    default:
+        return -static_cast<status_t>(c2s);
+    }
+}
+
+}  // namespace android
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.h b/media/codec2/sfplugin/CCodecBufferChannel.h
new file mode 100644
index 0000000..ee3455d
--- /dev/null
+++ b/media/codec2/sfplugin/CCodecBufferChannel.h
@@ -0,0 +1,359 @@
+/*
+ * Copyright 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CCODEC_BUFFER_CHANNEL_H_
+
+#define CCODEC_BUFFER_CHANNEL_H_
+
+#include <map>
+#include <memory>
+#include <vector>
+
+#include <C2Buffer.h>
+#include <C2Component.h>
+#include <Codec2Mapper.h>
+
+#include <codec2/hidl/client.h>
+#include <media/stagefright/foundation/Mutexed.h>
+#include <media/stagefright/CodecBase.h>
+#include <media/ICrypto.h>
+
+#include "CCodecBuffers.h"
+#include "InputSurfaceWrapper.h"
+#include "PipelineWatcher.h"
+
+namespace android {
+
+class MemoryDealer;
+
+class CCodecCallback {
+public:
+    virtual ~CCodecCallback() = default;
+    virtual void onError(status_t err, enum ActionCode actionCode) = 0;
+    virtual void onOutputFramesRendered(int64_t mediaTimeUs, nsecs_t renderTimeNs) = 0;
+    virtual void onOutputBuffersChanged() = 0;
+};
+
+/**
+ * BufferChannelBase implementation for CCodec.
+ */
+class CCodecBufferChannel
+    : public BufferChannelBase, public std::enable_shared_from_this<CCodecBufferChannel> {
+public:
+    explicit CCodecBufferChannel(const std::shared_ptr<CCodecCallback> &callback);
+    virtual ~CCodecBufferChannel();
+
+    // BufferChannelBase interface
+    virtual status_t queueInputBuffer(const sp<MediaCodecBuffer> &buffer) override;
+    virtual status_t queueSecureInputBuffer(
+            const sp<MediaCodecBuffer> &buffer,
+            bool secure,
+            const uint8_t *key,
+            const uint8_t *iv,
+            CryptoPlugin::Mode mode,
+            CryptoPlugin::Pattern pattern,
+            const CryptoPlugin::SubSample *subSamples,
+            size_t numSubSamples,
+            AString *errorDetailMsg) override;
+    virtual status_t renderOutputBuffer(
+            const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) override;
+    virtual status_t discardBuffer(const sp<MediaCodecBuffer> &buffer) override;
+    virtual void getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) override;
+    virtual void getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) override;
+
+    // Methods below are interface for CCodec to use.
+
+    /**
+     * Set the component object for buffer processing.
+     */
+    void setComponent(const std::shared_ptr<Codec2Client::Component> &component);
+
+    /**
+     * Set output graphic surface for rendering.
+     */
+    status_t setSurface(const sp<Surface> &surface);
+
+    /**
+     * Set GraphicBufferSource object from which the component extracts input
+     * buffers.
+     */
+    status_t setInputSurface(const std::shared_ptr<InputSurfaceWrapper> &surface);
+
+    /**
+     * Signal EOS to input surface.
+     */
+    status_t signalEndOfInputStream();
+
+    /**
+     * Set parameters.
+     */
+    status_t setParameters(std::vector<std::unique_ptr<C2Param>> &params);
+
+    /**
+     * Start queueing buffers to the component. This object should never queue
+     * buffers before this call has completed.
+     */
+    status_t start(const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat);
+
+    /**
+     * Request initial input buffers to be filled by client.
+     */
+    status_t requestInitialInputBuffers();
+
+    /**
+     * Stop queueing buffers to the component. This object should never queue
+     * buffers after this call, until start() is called.
+     */
+    void stop();
+
+    void flush(const std::list<std::unique_ptr<C2Work>> &flushedWork);
+
+    /**
+     * Notify input client about work done.
+     *
+     * @param workItems   finished work item.
+     * @param outputFormat new output format if it has changed, otherwise nullptr
+     * @param initData    new init data (CSD) if it has changed, otherwise nullptr
+     */
+    void onWorkDone(
+            std::unique_ptr<C2Work> work, const sp<AMessage> &outputFormat,
+            const C2StreamInitDataInfo::output *initData);
+
+    /**
+     * Make an input buffer available for the client as it is no longer needed
+     * by the codec.
+     *
+     * @param frameIndex The index of input work
+     * @param arrayIndex The index of buffer in the input work buffers.
+     */
+    void onInputBufferDone(uint64_t frameIndex, size_t arrayIndex);
+
+    PipelineWatcher::Clock::duration elapsed();
+
+    enum MetaMode {
+        MODE_NONE,
+        MODE_ANW,
+    };
+
+    void setMetaMode(MetaMode mode);
+
+private:
+    class QueueGuard;
+
+    /**
+     * Special mutex-like object with the following properties:
+     *
+     * - At STOPPED state (initial, or after stop())
+     *   - QueueGuard object gets created at STOPPED state, and the client is
+     *     supposed to return immediately.
+     * - At RUNNING state (after start())
+     *   - Each QueueGuard object
+     */
+    class QueueSync {
+    public:
+        /**
+         * At construction the sync object is in STOPPED state.
+         */
+        inline QueueSync() {}
+        ~QueueSync() = default;
+
+        /**
+         * Transition to RUNNING state when stopped. No-op if already in RUNNING
+         * state.
+         */
+        void start();
+
+        /**
+         * At RUNNING state, wait until all QueueGuard object created during
+         * RUNNING state are destroyed, and then transition to STOPPED state.
+         * No-op if already in STOPPED state.
+         */
+        void stop();
+
+    private:
+        Mutex mGuardLock;
+
+        struct Counter {
+            inline Counter() : value(-1) {}
+            int32_t value;
+            Condition cond;
+        };
+        Mutexed<Counter> mCount;
+
+        friend class CCodecBufferChannel::QueueGuard;
+    };
+
+    class QueueGuard {
+    public:
+        QueueGuard(QueueSync &sync);
+        ~QueueGuard();
+        inline bool isRunning() { return mRunning; }
+
+    private:
+        QueueSync &mSync;
+        bool mRunning;
+    };
+
+    void feedInputBufferIfAvailable();
+    void feedInputBufferIfAvailableInternal();
+    status_t queueInputBufferInternal(sp<MediaCodecBuffer> buffer);
+    bool handleWork(
+            std::unique_ptr<C2Work> work, const sp<AMessage> &outputFormat,
+            const C2StreamInitDataInfo::output *initData);
+    void sendOutputBuffers();
+
+    QueueSync mSync;
+    sp<MemoryDealer> mDealer;
+    sp<IMemory> mDecryptDestination;
+    int32_t mHeapSeqNum;
+
+    std::shared_ptr<Codec2Client::Component> mComponent;
+    std::string mComponentName; ///< component name for debugging
+    const char *mName; ///< C-string version of component name
+    std::shared_ptr<CCodecCallback> mCCodecCallback;
+    std::shared_ptr<C2BlockPool> mInputAllocator;
+    QueueSync mQueueSync;
+    std::vector<std::unique_ptr<C2Param>> mParamsToBeSet;
+
+    struct Input {
+        Input();
+
+        std::unique_ptr<InputBuffers> buffers;
+        size_t numSlots;
+        FlexBuffersImpl extraBuffers;
+        size_t numExtraSlots;
+        uint32_t inputDelay;
+        uint32_t pipelineDelay;
+    };
+    Mutexed<Input> mInput;
+    struct Output {
+        std::unique_ptr<OutputBuffers> buffers;
+        size_t numSlots;
+        uint32_t outputDelay;
+    };
+    Mutexed<Output> mOutput;
+    Mutexed<std::list<sp<ABuffer>>> mFlushedConfigs;
+
+    std::atomic_uint64_t mFrameIndex;
+    std::atomic_uint64_t mFirstValidFrameIndex;
+
+    sp<MemoryDealer> makeMemoryDealer(size_t heapSize);
+
+    struct OutputSurface {
+        sp<Surface> surface;
+        uint32_t generation;
+        int maxDequeueBuffers;
+    };
+    Mutexed<OutputSurface> mOutputSurface;
+
+    struct BlockPools {
+        C2Allocator::id_t inputAllocatorId;
+        std::shared_ptr<C2BlockPool> inputPool;
+        C2Allocator::id_t outputAllocatorId;
+        C2BlockPool::local_id_t outputPoolId;
+        std::shared_ptr<Codec2Client::Configurable> outputPoolIntf;
+    };
+    Mutexed<BlockPools> mBlockPools;
+
+    std::shared_ptr<InputSurfaceWrapper> mInputSurface;
+
+    MetaMode mMetaMode;
+
+    Mutexed<PipelineWatcher> mPipelineWatcher;
+
+    class ReorderStash {
+    public:
+        struct Entry {
+            inline Entry() : buffer(nullptr), timestamp(0), flags(0), ordinal({0, 0, 0}) {}
+            inline Entry(
+                    const std::shared_ptr<C2Buffer> &b,
+                    int64_t t,
+                    int32_t f,
+                    const C2WorkOrdinalStruct &o)
+                : buffer(b), timestamp(t), flags(f), ordinal(o) {}
+            std::shared_ptr<C2Buffer> buffer;
+            int64_t timestamp;
+            int32_t flags;
+            C2WorkOrdinalStruct ordinal;
+        };
+
+        ReorderStash();
+
+        void clear();
+        void flush();
+        void setDepth(uint32_t depth);
+        void setKey(C2Config::ordinal_key_t key);
+        bool pop(Entry *entry);
+        void emplace(
+                const std::shared_ptr<C2Buffer> &buffer,
+                int64_t timestamp,
+                int32_t flags,
+                const C2WorkOrdinalStruct &ordinal);
+        void defer(const Entry &entry);
+        bool hasPending() const;
+        uint32_t depth() const { return mDepth; }
+
+    private:
+        std::list<Entry> mPending;
+        std::list<Entry> mStash;
+        uint32_t mDepth;
+        C2Config::ordinal_key_t mKey;
+
+        bool less(const C2WorkOrdinalStruct &o1, const C2WorkOrdinalStruct &o2);
+    };
+    Mutexed<ReorderStash> mReorderStash;
+
+    std::atomic_bool mInputMetEos;
+    std::once_flag mRenderWarningFlag;
+
+    inline bool hasCryptoOrDescrambler() {
+        return mCrypto != nullptr || mDescrambler != nullptr;
+    }
+};
+
+// Conversion of a c2_status_t value to a status_t value may depend on the
+// operation that returns the c2_status_t value.
+enum c2_operation_t {
+    C2_OPERATION_NONE,
+    C2_OPERATION_Component_connectToOmxInputSurface,
+    C2_OPERATION_Component_createBlockPool,
+    C2_OPERATION_Component_destroyBlockPool,
+    C2_OPERATION_Component_disconnectFromInputSurface,
+    C2_OPERATION_Component_drain,
+    C2_OPERATION_Component_flush,
+    C2_OPERATION_Component_queue,
+    C2_OPERATION_Component_release,
+    C2_OPERATION_Component_reset,
+    C2_OPERATION_Component_setOutputSurface,
+    C2_OPERATION_Component_start,
+    C2_OPERATION_Component_stop,
+    C2_OPERATION_ComponentStore_copyBuffer,
+    C2_OPERATION_ComponentStore_createComponent,
+    C2_OPERATION_ComponentStore_createInputSurface,
+    C2_OPERATION_ComponentStore_createInterface,
+    C2_OPERATION_Configurable_config,
+    C2_OPERATION_Configurable_query,
+    C2_OPERATION_Configurable_querySupportedParams,
+    C2_OPERATION_Configurable_querySupportedValues,
+    C2_OPERATION_InputSurface_connectToComponent,
+    C2_OPERATION_InputSurfaceConnection_disconnect,
+};
+
+status_t toStatusT(c2_status_t c2s, c2_operation_t c2op = C2_OPERATION_NONE);
+
+}  // namespace android
+
+#endif  // CCODEC_BUFFER_CHANNEL_H_
diff --git a/media/codec2/sfplugin/CCodecBuffers.cpp b/media/codec2/sfplugin/CCodecBuffers.cpp
new file mode 100644
index 0000000..26c702d
--- /dev/null
+++ b/media/codec2/sfplugin/CCodecBuffers.cpp
@@ -0,0 +1,1072 @@
+/*
+ * Copyright 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "CCodecBuffers"
+#include <utils/Log.h>
+
+#include <C2PlatformSupport.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MediaCodecConstants.h>
+
+#include "CCodecBuffers.h"
+
+namespace android {
+
+namespace {
+
+sp<GraphicBlockBuffer> AllocateGraphicBuffer(
+        const std::shared_ptr<C2BlockPool> &pool,
+        const sp<AMessage> &format,
+        uint32_t pixelFormat,
+        const C2MemoryUsage &usage,
+        const std::shared_ptr<LocalBufferPool> &localBufferPool) {
+    int32_t width, height;
+    if (!format->findInt32("width", &width) || !format->findInt32("height", &height)) {
+        ALOGD("format lacks width or height");
+        return nullptr;
+    }
+
+    std::shared_ptr<C2GraphicBlock> block;
+    c2_status_t err = pool->fetchGraphicBlock(
+            width, height, pixelFormat, usage, &block);
+    if (err != C2_OK) {
+        ALOGD("fetch graphic block failed: %d", err);
+        return nullptr;
+    }
+
+    return GraphicBlockBuffer::Allocate(
+            format,
+            block,
+            [localBufferPool](size_t capacity) {
+                return localBufferPool->newBuffer(capacity);
+            });
+}
+
+}  // namespace
+
+// CCodecBuffers
+
+void CCodecBuffers::setFormat(const sp<AMessage> &format) {
+    CHECK(format != nullptr);
+    mFormat = format;
+}
+
+sp<AMessage> CCodecBuffers::dupFormat() {
+    return mFormat != nullptr ? mFormat->dup() : nullptr;
+}
+
+void CCodecBuffers::handleImageData(const sp<Codec2Buffer> &buffer) {
+    sp<ABuffer> imageDataCandidate = buffer->getImageData();
+    if (imageDataCandidate == nullptr) {
+        return;
+    }
+    sp<ABuffer> imageData;
+    if (!mFormat->findBuffer("image-data", &imageData)
+            || imageDataCandidate->size() != imageData->size()
+            || memcmp(imageDataCandidate->data(), imageData->data(), imageData->size()) != 0) {
+        ALOGD("[%s] updating image-data", mName);
+        sp<AMessage> newFormat = dupFormat();
+        newFormat->setBuffer("image-data", imageDataCandidate);
+        MediaImage2 *img = (MediaImage2*)imageDataCandidate->data();
+        if (img->mNumPlanes > 0 && img->mType != img->MEDIA_IMAGE_TYPE_UNKNOWN) {
+            int32_t stride = img->mPlane[0].mRowInc;
+            newFormat->setInt32(KEY_STRIDE, stride);
+            ALOGD("[%s] updating stride = %d", mName, stride);
+            if (img->mNumPlanes > 1 && stride > 0) {
+                int32_t vstride = (img->mPlane[1].mOffset - img->mPlane[0].mOffset) / stride;
+                newFormat->setInt32(KEY_SLICE_HEIGHT, vstride);
+                ALOGD("[%s] updating vstride = %d", mName, vstride);
+            }
+        }
+        setFormat(newFormat);
+        buffer->setFormat(newFormat);
+    }
+}
+
+// InputBuffers
+
+sp<Codec2Buffer> InputBuffers::cloneAndReleaseBuffer(const sp<MediaCodecBuffer> &buffer) {
+    sp<Codec2Buffer> copy = createNewBuffer();
+    if (copy == nullptr) {
+        return nullptr;
+    }
+    std::shared_ptr<C2Buffer> c2buffer;
+    if (!releaseBuffer(buffer, &c2buffer, true)) {
+        return nullptr;
+    }
+    if (!copy->canCopy(c2buffer)) {
+        return nullptr;
+    }
+    if (!copy->copy(c2buffer)) {
+        return nullptr;
+    }
+    return copy;
+}
+
+// OutputBuffers
+
+void OutputBuffers::initSkipCutBuffer(
+        int32_t delay, int32_t padding, int32_t sampleRate, int32_t channelCount) {
+    CHECK(mSkipCutBuffer == nullptr);
+    mDelay = delay;
+    mPadding = padding;
+    mSampleRate = sampleRate;
+    setSkipCutBuffer(delay, padding, channelCount);
+}
+
+void OutputBuffers::updateSkipCutBuffer(int32_t sampleRate, int32_t channelCount) {
+    if (mSkipCutBuffer == nullptr) {
+        return;
+    }
+    int32_t delay = mDelay;
+    int32_t padding = mPadding;
+    if (sampleRate != mSampleRate) {
+        delay = ((int64_t)delay * sampleRate) / mSampleRate;
+        padding = ((int64_t)padding * sampleRate) / mSampleRate;
+    }
+    setSkipCutBuffer(delay, padding, channelCount);
+}
+
+void OutputBuffers::submit(const sp<MediaCodecBuffer> &buffer) {
+    if (mSkipCutBuffer != nullptr) {
+        mSkipCutBuffer->submit(buffer);
+    }
+}
+
+void OutputBuffers::transferSkipCutBuffer(const sp<SkipCutBuffer> &scb) {
+    mSkipCutBuffer = scb;
+}
+
+void OutputBuffers::setSkipCutBuffer(int32_t skip, int32_t cut, int32_t channelCount) {
+    if (mSkipCutBuffer != nullptr) {
+        size_t prevSize = mSkipCutBuffer->size();
+        if (prevSize != 0u) {
+            ALOGD("[%s] Replacing SkipCutBuffer holding %zu bytes", mName, prevSize);
+        }
+    }
+    mSkipCutBuffer = new SkipCutBuffer(skip, cut, channelCount);
+}
+
+// LocalBufferPool
+
+std::shared_ptr<LocalBufferPool> LocalBufferPool::Create(size_t poolCapacity) {
+    return std::shared_ptr<LocalBufferPool>(new LocalBufferPool(poolCapacity));
+}
+
+sp<ABuffer> LocalBufferPool::newBuffer(size_t capacity) {
+    Mutex::Autolock lock(mMutex);
+    auto it = std::find_if(
+            mPool.begin(), mPool.end(),
+            [capacity](const std::vector<uint8_t> &vec) {
+                return vec.capacity() >= capacity;
+            });
+    if (it != mPool.end()) {
+        sp<ABuffer> buffer = new VectorBuffer(std::move(*it), shared_from_this());
+        mPool.erase(it);
+        return buffer;
+    }
+    if (mUsedSize + capacity > mPoolCapacity) {
+        while (!mPool.empty()) {
+            mUsedSize -= mPool.back().capacity();
+            mPool.pop_back();
+        }
+        if (mUsedSize + capacity > mPoolCapacity) {
+            ALOGD("mUsedSize = %zu, capacity = %zu, mPoolCapacity = %zu",
+                    mUsedSize, capacity, mPoolCapacity);
+            return nullptr;
+        }
+    }
+    std::vector<uint8_t> vec(capacity);
+    mUsedSize += vec.capacity();
+    return new VectorBuffer(std::move(vec), shared_from_this());
+}
+
+LocalBufferPool::VectorBuffer::VectorBuffer(
+        std::vector<uint8_t> &&vec, const std::shared_ptr<LocalBufferPool> &pool)
+    : ABuffer(vec.data(), vec.capacity()),
+      mVec(std::move(vec)),
+      mPool(pool) {
+}
+
+LocalBufferPool::VectorBuffer::~VectorBuffer() {
+    std::shared_ptr<LocalBufferPool> pool = mPool.lock();
+    if (pool) {
+        // If pool is alive, return the vector back to the pool so that
+        // it can be recycled.
+        pool->returnVector(std::move(mVec));
+    }
+}
+
+void LocalBufferPool::returnVector(std::vector<uint8_t> &&vec) {
+    Mutex::Autolock lock(mMutex);
+    mPool.push_front(std::move(vec));
+}
+
+// FlexBuffersImpl
+
+size_t FlexBuffersImpl::assignSlot(const sp<Codec2Buffer> &buffer) {
+    for (size_t i = 0; i < mBuffers.size(); ++i) {
+        if (mBuffers[i].clientBuffer == nullptr
+                && mBuffers[i].compBuffer.expired()) {
+            mBuffers[i].clientBuffer = buffer;
+            return i;
+        }
+    }
+    mBuffers.push_back({ buffer, std::weak_ptr<C2Buffer>() });
+    return mBuffers.size() - 1;
+}
+
+bool FlexBuffersImpl::releaseSlot(
+        const sp<MediaCodecBuffer> &buffer,
+        std::shared_ptr<C2Buffer> *c2buffer,
+        bool release) {
+    sp<Codec2Buffer> clientBuffer;
+    size_t index = mBuffers.size();
+    for (size_t i = 0; i < mBuffers.size(); ++i) {
+        if (mBuffers[i].clientBuffer == buffer) {
+            clientBuffer = mBuffers[i].clientBuffer;
+            if (release) {
+                mBuffers[i].clientBuffer.clear();
+            }
+            index = i;
+            break;
+        }
+    }
+    if (clientBuffer == nullptr) {
+        ALOGV("[%s] %s: No matching buffer found", mName, __func__);
+        return false;
+    }
+    std::shared_ptr<C2Buffer> result = mBuffers[index].compBuffer.lock();
+    if (!result) {
+        result = clientBuffer->asC2Buffer();
+        mBuffers[index].compBuffer = result;
+    }
+    if (c2buffer) {
+        *c2buffer = result;
+    }
+    return true;
+}
+
+bool FlexBuffersImpl::expireComponentBuffer(const std::shared_ptr<C2Buffer> &c2buffer) {
+    for (size_t i = 0; i < mBuffers.size(); ++i) {
+        std::shared_ptr<C2Buffer> compBuffer =
+                mBuffers[i].compBuffer.lock();
+        if (!compBuffer || compBuffer != c2buffer) {
+            continue;
+        }
+        mBuffers[i].compBuffer.reset();
+        ALOGV("[%s] codec released buffer #%zu", mName, i);
+        return true;
+    }
+    ALOGV("[%s] codec released an unknown buffer", mName);
+    return false;
+}
+
+void FlexBuffersImpl::flush() {
+    ALOGV("[%s] buffers are flushed %zu", mName, mBuffers.size());
+    mBuffers.clear();
+}
+
+size_t FlexBuffersImpl::numClientBuffers() const {
+    return std::count_if(
+            mBuffers.begin(), mBuffers.end(),
+            [](const Entry &entry) {
+                return (entry.clientBuffer != nullptr);
+            });
+}
+
+size_t FlexBuffersImpl::numComponentBuffers() const {
+    return std::count_if(
+            mBuffers.begin(), mBuffers.end(),
+            [](const Entry &entry) {
+                return !entry.compBuffer.expired();
+            });
+}
+
+// BuffersArrayImpl
+
+void BuffersArrayImpl::initialize(
+        const FlexBuffersImpl &impl,
+        size_t minSize,
+        std::function<sp<Codec2Buffer>()> allocate) {
+    mImplName = impl.mImplName + "[N]";
+    mName = mImplName.c_str();
+    for (size_t i = 0; i < impl.mBuffers.size(); ++i) {
+        sp<Codec2Buffer> clientBuffer = impl.mBuffers[i].clientBuffer;
+        bool ownedByClient = (clientBuffer != nullptr);
+        if (!ownedByClient) {
+            clientBuffer = allocate();
+        }
+        mBuffers.push_back({ clientBuffer, impl.mBuffers[i].compBuffer, ownedByClient });
+    }
+    ALOGV("[%s] converted %zu buffers to array mode of %zu", mName, mBuffers.size(), minSize);
+    for (size_t i = impl.mBuffers.size(); i < minSize; ++i) {
+        mBuffers.push_back({ allocate(), std::weak_ptr<C2Buffer>(), false });
+    }
+}
+
+status_t BuffersArrayImpl::grabBuffer(
+        size_t *index,
+        sp<Codec2Buffer> *buffer,
+        std::function<bool(const sp<Codec2Buffer> &)> match) {
+    // allBuffersDontMatch remains true if all buffers are available but
+    // match() returns false for every buffer.
+    bool allBuffersDontMatch = true;
+    for (size_t i = 0; i < mBuffers.size(); ++i) {
+        if (!mBuffers[i].ownedByClient && mBuffers[i].compBuffer.expired()) {
+            if (match(mBuffers[i].clientBuffer)) {
+                mBuffers[i].ownedByClient = true;
+                *buffer = mBuffers[i].clientBuffer;
+                (*buffer)->meta()->clear();
+                (*buffer)->setRange(0, (*buffer)->capacity());
+                *index = i;
+                return OK;
+            }
+        } else {
+            allBuffersDontMatch = false;
+        }
+    }
+    return allBuffersDontMatch ? NO_MEMORY : WOULD_BLOCK;
+}
+
+bool BuffersArrayImpl::returnBuffer(
+        const sp<MediaCodecBuffer> &buffer,
+        std::shared_ptr<C2Buffer> *c2buffer,
+        bool release) {
+    sp<Codec2Buffer> clientBuffer;
+    size_t index = mBuffers.size();
+    for (size_t i = 0; i < mBuffers.size(); ++i) {
+        if (mBuffers[i].clientBuffer == buffer) {
+            if (!mBuffers[i].ownedByClient) {
+                ALOGD("[%s] Client returned a buffer it does not own according to our record: %zu",
+                      mName, i);
+            }
+            clientBuffer = mBuffers[i].clientBuffer;
+            if (release) {
+                mBuffers[i].ownedByClient = false;
+            }
+            index = i;
+            break;
+        }
+    }
+    if (clientBuffer == nullptr) {
+        ALOGV("[%s] %s: No matching buffer found", mName, __func__);
+        return false;
+    }
+    ALOGV("[%s] %s: matching buffer found (index=%zu)", mName, __func__, index);
+    std::shared_ptr<C2Buffer> result = mBuffers[index].compBuffer.lock();
+    if (!result) {
+        result = clientBuffer->asC2Buffer();
+        mBuffers[index].compBuffer = result;
+    }
+    if (c2buffer) {
+        *c2buffer = result;
+    }
+    return true;
+}
+
+bool BuffersArrayImpl::expireComponentBuffer(const std::shared_ptr<C2Buffer> &c2buffer) {
+    for (size_t i = 0; i < mBuffers.size(); ++i) {
+        std::shared_ptr<C2Buffer> compBuffer =
+                mBuffers[i].compBuffer.lock();
+        if (!compBuffer) {
+            continue;
+        }
+        if (c2buffer == compBuffer) {
+            if (mBuffers[i].ownedByClient) {
+                // This should not happen.
+                ALOGD("[%s] codec released a buffer owned by client "
+                      "(index %zu)", mName, i);
+            }
+            mBuffers[i].compBuffer.reset();
+            ALOGV("[%s] codec released buffer #%zu(array mode)", mName, i);
+            return true;
+        }
+    }
+    ALOGV("[%s] codec released an unknown buffer (array mode)", mName);
+    return false;
+}
+
+void BuffersArrayImpl::getArray(Vector<sp<MediaCodecBuffer>> *array) const {
+    array->clear();
+    for (const Entry &entry : mBuffers) {
+        array->push(entry.clientBuffer);
+    }
+}
+
+void BuffersArrayImpl::flush() {
+    for (Entry &entry : mBuffers) {
+        entry.ownedByClient = false;
+    }
+}
+
+void BuffersArrayImpl::realloc(std::function<sp<Codec2Buffer>()> alloc) {
+    size_t size = mBuffers.size();
+    mBuffers.clear();
+    for (size_t i = 0; i < size; ++i) {
+        mBuffers.push_back({ alloc(), std::weak_ptr<C2Buffer>(), false });
+    }
+}
+
+void BuffersArrayImpl::grow(
+        size_t newSize, std::function<sp<Codec2Buffer>()> alloc) {
+    CHECK_LT(mBuffers.size(), newSize);
+    while (mBuffers.size() < newSize) {
+        mBuffers.push_back({ alloc(), std::weak_ptr<C2Buffer>(), false });
+    }
+}
+
+size_t BuffersArrayImpl::numClientBuffers() const {
+    return std::count_if(
+            mBuffers.begin(), mBuffers.end(),
+            [](const Entry &entry) {
+                return entry.ownedByClient;
+            });
+}
+
+size_t BuffersArrayImpl::arraySize() const {
+    return mBuffers.size();
+}
+
+// InputBuffersArray
+
+void InputBuffersArray::initialize(
+        const FlexBuffersImpl &impl,
+        size_t minSize,
+        std::function<sp<Codec2Buffer>()> allocate) {
+    mAllocate = allocate;
+    mImpl.initialize(impl, minSize, allocate);
+}
+
+void InputBuffersArray::getArray(Vector<sp<MediaCodecBuffer>> *array) const {
+    mImpl.getArray(array);
+}
+
+bool InputBuffersArray::requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) {
+    sp<Codec2Buffer> c2Buffer;
+    status_t err = mImpl.grabBuffer(index, &c2Buffer);
+    if (err == OK) {
+        c2Buffer->setFormat(mFormat);
+        handleImageData(c2Buffer);
+        *buffer = c2Buffer;
+        return true;
+    }
+    return false;
+}
+
+bool InputBuffersArray::releaseBuffer(
+        const sp<MediaCodecBuffer> &buffer,
+        std::shared_ptr<C2Buffer> *c2buffer,
+        bool release) {
+    return mImpl.returnBuffer(buffer, c2buffer, release);
+}
+
+bool InputBuffersArray::expireComponentBuffer(
+        const std::shared_ptr<C2Buffer> &c2buffer) {
+    return mImpl.expireComponentBuffer(c2buffer);
+}
+
+void InputBuffersArray::flush() {
+    mImpl.flush();
+}
+
+size_t InputBuffersArray::numClientBuffers() const {
+    return mImpl.numClientBuffers();
+}
+
+sp<Codec2Buffer> InputBuffersArray::createNewBuffer() {
+    return mAllocate();
+}
+
+// LinearInputBuffers
+
+bool LinearInputBuffers::requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) {
+    sp<Codec2Buffer> newBuffer = createNewBuffer();
+    if (newBuffer == nullptr) {
+        return false;
+    }
+    *index = mImpl.assignSlot(newBuffer);
+    *buffer = newBuffer;
+    return true;
+}
+
+bool LinearInputBuffers::releaseBuffer(
+        const sp<MediaCodecBuffer> &buffer,
+        std::shared_ptr<C2Buffer> *c2buffer,
+        bool release) {
+    return mImpl.releaseSlot(buffer, c2buffer, release);
+}
+
+bool LinearInputBuffers::expireComponentBuffer(
+        const std::shared_ptr<C2Buffer> &c2buffer) {
+    return mImpl.expireComponentBuffer(c2buffer);
+}
+
+void LinearInputBuffers::flush() {
+    // This is no-op by default unless we're in array mode where we need to keep
+    // track of the flushed work.
+    mImpl.flush();
+}
+
+std::unique_ptr<InputBuffers> LinearInputBuffers::toArrayMode(size_t size) {
+    std::unique_ptr<InputBuffersArray> array(
+            new InputBuffersArray(mComponentName.c_str(), "1D-Input[N]"));
+    array->setPool(mPool);
+    array->setFormat(mFormat);
+    array->initialize(
+            mImpl,
+            size,
+            [pool = mPool, format = mFormat] () -> sp<Codec2Buffer> {
+                return Alloc(pool, format);
+            });
+    return std::move(array);
+}
+
+size_t LinearInputBuffers::numClientBuffers() const {
+    return mImpl.numClientBuffers();
+}
+
+// static
+sp<Codec2Buffer> LinearInputBuffers::Alloc(
+        const std::shared_ptr<C2BlockPool> &pool, const sp<AMessage> &format) {
+    int32_t capacity = kLinearBufferSize;
+    (void)format->findInt32(KEY_MAX_INPUT_SIZE, &capacity);
+    if ((size_t)capacity > kMaxLinearBufferSize) {
+        ALOGD("client requested %d, capped to %zu", capacity, kMaxLinearBufferSize);
+        capacity = kMaxLinearBufferSize;
+    }
+
+    // TODO: read usage from intf
+    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+    std::shared_ptr<C2LinearBlock> block;
+
+    c2_status_t err = pool->fetchLinearBlock(capacity, usage, &block);
+    if (err != C2_OK) {
+        return nullptr;
+    }
+
+    return LinearBlockBuffer::Allocate(format, block);
+}
+
+sp<Codec2Buffer> LinearInputBuffers::createNewBuffer() {
+    return Alloc(mPool, mFormat);
+}
+
+// EncryptedLinearInputBuffers
+
+EncryptedLinearInputBuffers::EncryptedLinearInputBuffers(
+        bool secure,
+        const sp<MemoryDealer> &dealer,
+        const sp<ICrypto> &crypto,
+        int32_t heapSeqNum,
+        size_t capacity,
+        size_t numInputSlots,
+        const char *componentName, const char *name)
+    : LinearInputBuffers(componentName, name),
+      mUsage({0, 0}),
+      mDealer(dealer),
+      mCrypto(crypto),
+      mMemoryVector(new std::vector<Entry>){
+    if (secure) {
+        mUsage = { C2MemoryUsage::READ_PROTECTED, 0 };
+    } else {
+        mUsage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+    }
+    for (size_t i = 0; i < numInputSlots; ++i) {
+        sp<IMemory> memory = mDealer->allocate(capacity);
+        if (memory == nullptr) {
+            ALOGD("[%s] Failed to allocate memory from dealer: only %zu slots allocated",
+                  mName, i);
+            break;
+        }
+        mMemoryVector->push_back({std::weak_ptr<C2LinearBlock>(), memory, heapSeqNum});
+    }
+}
+
+std::unique_ptr<InputBuffers> EncryptedLinearInputBuffers::toArrayMode(size_t size) {
+    std::unique_ptr<InputBuffersArray> array(
+            new InputBuffersArray(mComponentName.c_str(), "1D-EncryptedInput[N]"));
+    array->setPool(mPool);
+    array->setFormat(mFormat);
+    array->initialize(
+            mImpl,
+            size,
+            [pool = mPool,
+             format = mFormat,
+             usage = mUsage,
+             memoryVector = mMemoryVector] () -> sp<Codec2Buffer> {
+                return Alloc(pool, format, usage, memoryVector);
+            });
+    return std::move(array);
+}
+
+
+// static
+sp<Codec2Buffer> EncryptedLinearInputBuffers::Alloc(
+        const std::shared_ptr<C2BlockPool> &pool,
+        const sp<AMessage> &format,
+        C2MemoryUsage usage,
+        const std::shared_ptr<std::vector<EncryptedLinearInputBuffers::Entry>> &memoryVector) {
+    int32_t capacity = kLinearBufferSize;
+    (void)format->findInt32(KEY_MAX_INPUT_SIZE, &capacity);
+    if ((size_t)capacity > kMaxLinearBufferSize) {
+        ALOGD("client requested %d, capped to %zu", capacity, kMaxLinearBufferSize);
+        capacity = kMaxLinearBufferSize;
+    }
+
+    sp<IMemory> memory;
+    size_t slot = 0;
+    int32_t heapSeqNum = -1;
+    for (; slot < memoryVector->size(); ++slot) {
+        if (memoryVector->at(slot).block.expired()) {
+            memory = memoryVector->at(slot).memory;
+            heapSeqNum = memoryVector->at(slot).heapSeqNum;
+            break;
+        }
+    }
+    if (memory == nullptr) {
+        return nullptr;
+    }
+
+    std::shared_ptr<C2LinearBlock> block;
+    c2_status_t err = pool->fetchLinearBlock(capacity, usage, &block);
+    if (err != C2_OK || block == nullptr) {
+        return nullptr;
+    }
+
+    memoryVector->at(slot).block = block;
+    return new EncryptedLinearBlockBuffer(format, block, memory, heapSeqNum);
+}
+
+sp<Codec2Buffer> EncryptedLinearInputBuffers::createNewBuffer() {
+    // TODO: android_2020
+    return nullptr;
+}
+
+// GraphicMetadataInputBuffers
+
+GraphicMetadataInputBuffers::GraphicMetadataInputBuffers(
+        const char *componentName, const char *name)
+    : InputBuffers(componentName, name),
+      mImpl(mName),
+      mStore(GetCodec2PlatformAllocatorStore()) { }
+
+bool GraphicMetadataInputBuffers::requestNewBuffer(
+        size_t *index, sp<MediaCodecBuffer> *buffer) {
+    sp<Codec2Buffer> newBuffer = createNewBuffer();
+    if (newBuffer == nullptr) {
+        return false;
+    }
+    *index = mImpl.assignSlot(newBuffer);
+    *buffer = newBuffer;
+    return true;
+}
+
+bool GraphicMetadataInputBuffers::releaseBuffer(
+        const sp<MediaCodecBuffer> &buffer,
+        std::shared_ptr<C2Buffer> *c2buffer,
+        bool release) {
+    return mImpl.releaseSlot(buffer, c2buffer, release);
+}
+
+bool GraphicMetadataInputBuffers::expireComponentBuffer(
+        const std::shared_ptr<C2Buffer> &c2buffer) {
+    return mImpl.expireComponentBuffer(c2buffer);
+}
+
+void GraphicMetadataInputBuffers::flush() {
+    // This is no-op by default unless we're in array mode where we need to keep
+    // track of the flushed work.
+}
+
+std::unique_ptr<InputBuffers> GraphicMetadataInputBuffers::toArrayMode(
+        size_t size) {
+    std::shared_ptr<C2Allocator> alloc;
+    c2_status_t err = mStore->fetchAllocator(mPool->getAllocatorId(), &alloc);
+    if (err != C2_OK) {
+        return nullptr;
+    }
+    std::unique_ptr<InputBuffersArray> array(
+            new InputBuffersArray(mComponentName.c_str(), "2D-MetaInput[N]"));
+    array->setPool(mPool);
+    array->setFormat(mFormat);
+    array->initialize(
+            mImpl,
+            size,
+            [format = mFormat, alloc]() -> sp<Codec2Buffer> {
+                return new GraphicMetadataBuffer(format, alloc);
+            });
+    return std::move(array);
+}
+
+size_t GraphicMetadataInputBuffers::numClientBuffers() const {
+    return mImpl.numClientBuffers();
+}
+
+sp<Codec2Buffer> GraphicMetadataInputBuffers::createNewBuffer() {
+    std::shared_ptr<C2Allocator> alloc;
+    c2_status_t err = mStore->fetchAllocator(mPool->getAllocatorId(), &alloc);
+    if (err != C2_OK) {
+        return nullptr;
+    }
+    return new GraphicMetadataBuffer(mFormat, alloc);
+}
+
+// GraphicInputBuffers
+
+GraphicInputBuffers::GraphicInputBuffers(
+        size_t numInputSlots, const char *componentName, const char *name)
+    : InputBuffers(componentName, name),
+      mImpl(mName),
+      mLocalBufferPool(LocalBufferPool::Create(
+              kMaxLinearBufferSize * numInputSlots)) { }
+
+bool GraphicInputBuffers::requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) {
+    sp<Codec2Buffer> newBuffer = createNewBuffer();
+    if (newBuffer == nullptr) {
+        return false;
+    }
+    *index = mImpl.assignSlot(newBuffer);
+    handleImageData(newBuffer);
+    *buffer = newBuffer;
+    return true;
+}
+
+bool GraphicInputBuffers::releaseBuffer(
+        const sp<MediaCodecBuffer> &buffer,
+        std::shared_ptr<C2Buffer> *c2buffer,
+        bool release) {
+    return mImpl.releaseSlot(buffer, c2buffer, release);
+}
+
+bool GraphicInputBuffers::expireComponentBuffer(
+        const std::shared_ptr<C2Buffer> &c2buffer) {
+    return mImpl.expireComponentBuffer(c2buffer);
+}
+
+void GraphicInputBuffers::flush() {
+    // This is no-op by default unless we're in array mode where we need to keep
+    // track of the flushed work.
+}
+
+std::unique_ptr<InputBuffers> GraphicInputBuffers::toArrayMode(size_t size) {
+    std::unique_ptr<InputBuffersArray> array(
+            new InputBuffersArray(mComponentName.c_str(), "2D-BB-Input[N]"));
+    array->setPool(mPool);
+    array->setFormat(mFormat);
+    array->initialize(
+            mImpl,
+            size,
+            [pool = mPool, format = mFormat, lbp = mLocalBufferPool]() -> sp<Codec2Buffer> {
+                C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+                return AllocateGraphicBuffer(
+                        pool, format, HAL_PIXEL_FORMAT_YV12, usage, lbp);
+            });
+    return std::move(array);
+}
+
+size_t GraphicInputBuffers::numClientBuffers() const {
+    return mImpl.numClientBuffers();
+}
+
+sp<Codec2Buffer> GraphicInputBuffers::createNewBuffer() {
+    // TODO: read usage from intf
+    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+    return AllocateGraphicBuffer(
+            mPool, mFormat, HAL_PIXEL_FORMAT_YV12, usage, mLocalBufferPool);
+}
+
+// OutputBuffersArray
+
+void OutputBuffersArray::initialize(
+        const FlexBuffersImpl &impl,
+        size_t minSize,
+        std::function<sp<Codec2Buffer>()> allocate) {
+    mAlloc = allocate;
+    mImpl.initialize(impl, minSize, allocate);
+}
+
+status_t OutputBuffersArray::registerBuffer(
+        const std::shared_ptr<C2Buffer> &buffer,
+        size_t *index,
+        sp<MediaCodecBuffer> *clientBuffer) {
+    sp<Codec2Buffer> c2Buffer;
+    status_t err = mImpl.grabBuffer(
+            index,
+            &c2Buffer,
+            [buffer](const sp<Codec2Buffer> &clientBuffer) {
+                return clientBuffer->canCopy(buffer);
+            });
+    if (err == WOULD_BLOCK) {
+        ALOGV("[%s] buffers temporarily not available", mName);
+        return err;
+    } else if (err != OK) {
+        ALOGD("[%s] grabBuffer failed: %d", mName, err);
+        return err;
+    }
+    c2Buffer->setFormat(mFormat);
+    if (!c2Buffer->copy(buffer)) {
+        ALOGD("[%s] copy buffer failed", mName);
+        return WOULD_BLOCK;
+    }
+    submit(c2Buffer);
+    handleImageData(c2Buffer);
+    *clientBuffer = c2Buffer;
+    ALOGV("[%s] grabbed buffer %zu", mName, *index);
+    return OK;
+}
+
+status_t OutputBuffersArray::registerCsd(
+        const C2StreamInitDataInfo::output *csd,
+        size_t *index,
+        sp<MediaCodecBuffer> *clientBuffer) {
+    sp<Codec2Buffer> c2Buffer;
+    status_t err = mImpl.grabBuffer(
+            index,
+            &c2Buffer,
+            [csd](const sp<Codec2Buffer> &clientBuffer) {
+                return clientBuffer->base() != nullptr
+                        && clientBuffer->capacity() >= csd->flexCount();
+            });
+    if (err != OK) {
+        return err;
+    }
+    memcpy(c2Buffer->base(), csd->m.value, csd->flexCount());
+    c2Buffer->setRange(0, csd->flexCount());
+    c2Buffer->setFormat(mFormat);
+    *clientBuffer = c2Buffer;
+    return OK;
+}
+
+bool OutputBuffersArray::releaseBuffer(
+        const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) {
+    return mImpl.returnBuffer(buffer, c2buffer, true);
+}
+
+void OutputBuffersArray::flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) {
+    (void)flushedWork;
+    mImpl.flush();
+    if (mSkipCutBuffer != nullptr) {
+        mSkipCutBuffer->clear();
+    }
+}
+
+void OutputBuffersArray::getArray(Vector<sp<MediaCodecBuffer>> *array) const {
+    mImpl.getArray(array);
+}
+
+size_t OutputBuffersArray::numClientBuffers() const {
+    return mImpl.numClientBuffers();
+}
+
+void OutputBuffersArray::realloc(const std::shared_ptr<C2Buffer> &c2buffer) {
+    switch (c2buffer->data().type()) {
+        case C2BufferData::LINEAR: {
+            uint32_t size = kLinearBufferSize;
+            const C2ConstLinearBlock &block = c2buffer->data().linearBlocks().front();
+            if (block.size() < kMaxLinearBufferSize / 2) {
+                size = block.size() * 2;
+            } else {
+                size = kMaxLinearBufferSize;
+            }
+            mAlloc = [format = mFormat, size] {
+                return new LocalLinearBuffer(format, new ABuffer(size));
+            };
+            ALOGD("[%s] reallocating with linear buffer of size %u", mName, size);
+            break;
+        }
+
+        case C2BufferData::GRAPHIC: {
+            // This is only called for RawGraphicOutputBuffers.
+            mAlloc = [format = mFormat,
+                      lbp = LocalBufferPool::Create(kMaxLinearBufferSize * mImpl.arraySize())] {
+                return ConstGraphicBlockBuffer::AllocateEmpty(
+                        format,
+                        [lbp](size_t capacity) {
+                            return lbp->newBuffer(capacity);
+                        });
+            };
+            ALOGD("[%s] reallocating with graphic buffer: format = %s",
+                  mName, mFormat->debugString().c_str());
+            break;
+        }
+
+        case C2BufferData::INVALID:         [[fallthrough]];
+        case C2BufferData::LINEAR_CHUNKS:   [[fallthrough]];
+        case C2BufferData::GRAPHIC_CHUNKS:  [[fallthrough]];
+        default:
+            ALOGD("Unsupported type: %d", (int)c2buffer->data().type());
+            return;
+    }
+    mImpl.realloc(mAlloc);
+}
+
+void OutputBuffersArray::grow(size_t newSize) {
+    mImpl.grow(newSize, mAlloc);
+}
+
+// FlexOutputBuffers
+
+status_t FlexOutputBuffers::registerBuffer(
+        const std::shared_ptr<C2Buffer> &buffer,
+        size_t *index,
+        sp<MediaCodecBuffer> *clientBuffer) {
+    sp<Codec2Buffer> newBuffer = wrap(buffer);
+    if (newBuffer == nullptr) {
+        return NO_MEMORY;
+    }
+    newBuffer->setFormat(mFormat);
+    *index = mImpl.assignSlot(newBuffer);
+    handleImageData(newBuffer);
+    *clientBuffer = newBuffer;
+    ALOGV("[%s] registered buffer %zu", mName, *index);
+    return OK;
+}
+
+status_t FlexOutputBuffers::registerCsd(
+        const C2StreamInitDataInfo::output *csd,
+        size_t *index,
+        sp<MediaCodecBuffer> *clientBuffer) {
+    sp<Codec2Buffer> newBuffer = new LocalLinearBuffer(
+            mFormat, ABuffer::CreateAsCopy(csd->m.value, csd->flexCount()));
+    *index = mImpl.assignSlot(newBuffer);
+    *clientBuffer = newBuffer;
+    return OK;
+}
+
+bool FlexOutputBuffers::releaseBuffer(
+        const sp<MediaCodecBuffer> &buffer,
+        std::shared_ptr<C2Buffer> *c2buffer) {
+    return mImpl.releaseSlot(buffer, c2buffer, true);
+}
+
+void FlexOutputBuffers::flush(
+        const std::list<std::unique_ptr<C2Work>> &flushedWork) {
+    (void) flushedWork;
+    // This is no-op by default unless we're in array mode where we need to keep
+    // track of the flushed work.
+}
+
+std::unique_ptr<OutputBuffers> FlexOutputBuffers::toArrayMode(size_t size) {
+    std::unique_ptr<OutputBuffersArray> array(new OutputBuffersArray(mComponentName.c_str()));
+    array->setFormat(mFormat);
+    array->transferSkipCutBuffer(mSkipCutBuffer);
+    std::function<sp<Codec2Buffer>()> alloc = getAlloc();
+    array->initialize(mImpl, size, alloc);
+    return std::move(array);
+}
+
+size_t FlexOutputBuffers::numClientBuffers() const {
+    return mImpl.numClientBuffers();
+}
+
+// LinearOutputBuffers
+
+void LinearOutputBuffers::flush(
+        const std::list<std::unique_ptr<C2Work>> &flushedWork) {
+    if (mSkipCutBuffer != nullptr) {
+        mSkipCutBuffer->clear();
+    }
+    FlexOutputBuffers::flush(flushedWork);
+}
+
+sp<Codec2Buffer> LinearOutputBuffers::wrap(const std::shared_ptr<C2Buffer> &buffer) {
+    if (buffer == nullptr) {
+        ALOGV("[%s] using a dummy buffer", mName);
+        return new LocalLinearBuffer(mFormat, new ABuffer(0));
+    }
+    if (buffer->data().type() != C2BufferData::LINEAR) {
+        ALOGV("[%s] non-linear buffer %d", mName, buffer->data().type());
+        // We expect linear output buffers from the component.
+        return nullptr;
+    }
+    if (buffer->data().linearBlocks().size() != 1u) {
+        ALOGV("[%s] no linear buffers", mName);
+        // We expect one and only one linear block from the component.
+        return nullptr;
+    }
+    sp<Codec2Buffer> clientBuffer = ConstLinearBlockBuffer::Allocate(mFormat, buffer);
+    if (clientBuffer == nullptr) {
+        ALOGD("[%s] ConstLinearBlockBuffer::Allocate failed", mName);
+        return nullptr;
+    }
+    submit(clientBuffer);
+    return clientBuffer;
+}
+
+std::function<sp<Codec2Buffer>()> LinearOutputBuffers::getAlloc() {
+    return [format = mFormat]{
+        // TODO: proper max output size
+        return new LocalLinearBuffer(format, new ABuffer(kLinearBufferSize));
+    };
+}
+
+// GraphicOutputBuffers
+
+sp<Codec2Buffer> GraphicOutputBuffers::wrap(const std::shared_ptr<C2Buffer> &buffer) {
+    return new DummyContainerBuffer(mFormat, buffer);
+}
+
+std::function<sp<Codec2Buffer>()> GraphicOutputBuffers::getAlloc() {
+    return [format = mFormat]{
+        return new DummyContainerBuffer(format);
+    };
+}
+
+// RawGraphicOutputBuffers
+
+RawGraphicOutputBuffers::RawGraphicOutputBuffers(
+        size_t numOutputSlots, const char *componentName, const char *name)
+    : FlexOutputBuffers(componentName, name),
+      mLocalBufferPool(LocalBufferPool::Create(
+              kMaxLinearBufferSize * numOutputSlots)) { }
+
+sp<Codec2Buffer> RawGraphicOutputBuffers::wrap(const std::shared_ptr<C2Buffer> &buffer) {
+    if (buffer == nullptr) {
+        sp<Codec2Buffer> c2buffer = ConstGraphicBlockBuffer::AllocateEmpty(
+                mFormat,
+                [lbp = mLocalBufferPool](size_t capacity) {
+                    return lbp->newBuffer(capacity);
+                });
+        if (c2buffer == nullptr) {
+            ALOGD("[%s] ConstGraphicBlockBuffer::AllocateEmpty failed", mName);
+            return nullptr;
+        }
+        c2buffer->setRange(0, 0);
+        return c2buffer;
+    } else {
+        return ConstGraphicBlockBuffer::Allocate(
+                mFormat,
+                buffer,
+                [lbp = mLocalBufferPool](size_t capacity) {
+                    return lbp->newBuffer(capacity);
+                });
+    }
+}
+
+std::function<sp<Codec2Buffer>()> RawGraphicOutputBuffers::getAlloc() {
+    return [format = mFormat, lbp = mLocalBufferPool]{
+        return ConstGraphicBlockBuffer::AllocateEmpty(
+                format,
+                [lbp](size_t capacity) {
+                    return lbp->newBuffer(capacity);
+                });
+    };
+}
+
+}  // namespace android
diff --git a/media/codec2/sfplugin/CCodecBuffers.h b/media/codec2/sfplugin/CCodecBuffers.h
new file mode 100644
index 0000000..2cb6b81
--- /dev/null
+++ b/media/codec2/sfplugin/CCodecBuffers.h
@@ -0,0 +1,877 @@
+/*
+ * Copyright 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CCODEC_BUFFERS_H_
+
+#define CCODEC_BUFFERS_H_
+
+#include <string>
+
+#include <C2Config.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/MediaCodecBuffer.h>
+
+#include "Codec2Buffer.h"
+#include "SkipCutBuffer.h"
+
+namespace android {
+
+constexpr size_t kLinearBufferSize = 1048576;
+// This can fit 4K RGBA frame, and most likely client won't need more than this.
+constexpr size_t kMaxLinearBufferSize = 4096 * 2304 * 4;
+
+/**
+ * Base class for representation of buffers at one port.
+ */
+class CCodecBuffers {
+public:
+    CCodecBuffers(const char *componentName, const char *name = "Buffers")
+        : mComponentName(componentName),
+          mChannelName(std::string(componentName) + ":" + name),
+          mName(mChannelName.c_str()) {
+    }
+    virtual ~CCodecBuffers() = default;
+
+    /**
+     * Set format for MediaCodec-facing buffers.
+     */
+    void setFormat(const sp<AMessage> &format);
+
+    /**
+     * Return a copy of current format.
+     */
+    sp<AMessage> dupFormat();
+
+    /**
+     * Returns true if the buffers are operating under array mode.
+     */
+    virtual bool isArrayMode() const { return false; }
+
+    /**
+     * Fills the vector with MediaCodecBuffer's if in array mode; otherwise,
+     * no-op.
+     */
+    virtual void getArray(Vector<sp<MediaCodecBuffer>> *) const {}
+
+    /**
+     * Return number of buffers the client owns.
+     */
+    virtual size_t numClientBuffers() const = 0;
+
+    /**
+     * Examine image data from the buffer and update the format if necessary.
+     */
+    void handleImageData(const sp<Codec2Buffer> &buffer);
+
+protected:
+    std::string mComponentName; ///< name of component for debugging
+    std::string mChannelName; ///< name of channel for debugging
+    const char *mName; ///< C-string version of channel name
+    // Format to be used for creating MediaCodec-facing buffers.
+    sp<AMessage> mFormat;
+
+private:
+    DISALLOW_EVIL_CONSTRUCTORS(CCodecBuffers);
+};
+
+class InputBuffers : public CCodecBuffers {
+public:
+    InputBuffers(const char *componentName, const char *name = "Input[]")
+        : CCodecBuffers(componentName, name) { }
+    virtual ~InputBuffers() = default;
+
+    /**
+     * Set a block pool to obtain input memory blocks.
+     */
+    void setPool(const std::shared_ptr<C2BlockPool> &pool) { mPool = pool; }
+
+    /**
+     * Get a new MediaCodecBuffer for input and its corresponding index.
+     * Returns false if no new buffer can be obtained at the moment.
+     */
+    virtual bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) = 0;
+
+    /**
+     * Release the buffer obtained from requestNewBuffer() and get the
+     * associated C2Buffer object back. Returns true if the buffer was on file
+     * and released successfully.
+     */
+    virtual bool releaseBuffer(
+            const sp<MediaCodecBuffer> &buffer,
+            std::shared_ptr<C2Buffer> *c2buffer,
+            bool release) = 0;
+
+    /**
+     * Release the buffer that is no longer used by the codec process. Return
+     * true if and only if the buffer was on file and released successfully.
+     */
+    virtual bool expireComponentBuffer(
+            const std::shared_ptr<C2Buffer> &c2buffer) = 0;
+
+    /**
+     * Flush internal state. After this call, no index or buffer previously
+     * returned from requestNewBuffer() is valid.
+     */
+    virtual void flush() = 0;
+
+    /**
+     * Return array-backed version of input buffers. The returned object
+     * shall retain the internal state so that it will honor index and
+     * buffer from previous calls of requestNewBuffer().
+     */
+    virtual std::unique_ptr<InputBuffers> toArrayMode(size_t size) = 0;
+
+    /**
+     * Release the buffer obtained from requestNewBuffer(), and create a deep
+     * copy clone of the buffer.
+     *
+     * \return  the deep copy clone of the buffer; nullptr if cloning is not
+     *          possible.
+     */
+    sp<Codec2Buffer> cloneAndReleaseBuffer(const sp<MediaCodecBuffer> &buffer);
+
+protected:
+    virtual sp<Codec2Buffer> createNewBuffer() = 0;
+
+    // Pool to obtain blocks for input buffers.
+    std::shared_ptr<C2BlockPool> mPool;
+
+private:
+    DISALLOW_EVIL_CONSTRUCTORS(InputBuffers);
+};
+
+class OutputBuffers : public CCodecBuffers {
+public:
+    OutputBuffers(const char *componentName, const char *name = "Output")
+        : CCodecBuffers(componentName, name) { }
+    virtual ~OutputBuffers() = default;
+
+    /**
+     * Register output C2Buffer from the component and obtain corresponding
+     * index and MediaCodecBuffer object. Returns false if registration
+     * fails.
+     */
+    virtual status_t registerBuffer(
+            const std::shared_ptr<C2Buffer> &buffer,
+            size_t *index,
+            sp<MediaCodecBuffer> *clientBuffer) = 0;
+
+    /**
+     * Register codec specific data as a buffer to be consistent with
+     * MediaCodec behavior.
+     */
+    virtual status_t registerCsd(
+            const C2StreamInitDataInfo::output * /* csd */,
+            size_t * /* index */,
+            sp<MediaCodecBuffer> * /* clientBuffer */) = 0;
+
+    /**
+     * Release the buffer obtained from registerBuffer() and get the
+     * associated C2Buffer object back. Returns true if the buffer was on file
+     * and released successfully.
+     */
+    virtual bool releaseBuffer(
+            const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) = 0;
+
+    /**
+     * Flush internal state. After this call, no index or buffer previously
+     * returned from registerBuffer() is valid.
+     */
+    virtual void flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) = 0;
+
+    /**
+     * Return array-backed version of output buffers. The returned object
+     * shall retain the internal state so that it will honor index and
+     * buffer from previous calls of registerBuffer().
+     */
+    virtual std::unique_ptr<OutputBuffers> toArrayMode(size_t size) = 0;
+
+    /**
+     * Initialize SkipCutBuffer object.
+     */
+    void initSkipCutBuffer(
+            int32_t delay, int32_t padding, int32_t sampleRate, int32_t channelCount);
+
+    /**
+     * Update the SkipCutBuffer object. No-op if it's never initialized.
+     */
+    void updateSkipCutBuffer(int32_t sampleRate, int32_t channelCount);
+
+    /**
+     * Submit buffer to SkipCutBuffer object, if initialized.
+     */
+    void submit(const sp<MediaCodecBuffer> &buffer);
+
+    /**
+     * Transfer SkipCutBuffer object to the other Buffers object.
+     */
+    void transferSkipCutBuffer(const sp<SkipCutBuffer> &scb);
+
+protected:
+    sp<SkipCutBuffer> mSkipCutBuffer;
+
+private:
+    int32_t mDelay;
+    int32_t mPadding;
+    int32_t mSampleRate;
+
+    void setSkipCutBuffer(int32_t skip, int32_t cut, int32_t channelCount);
+
+    DISALLOW_EVIL_CONSTRUCTORS(OutputBuffers);
+};
+
+/**
+ * Simple local buffer pool backed by std::vector.
+ */
+class LocalBufferPool : public std::enable_shared_from_this<LocalBufferPool> {
+public:
+    /**
+     * Create a new LocalBufferPool object.
+     *
+     * \param poolCapacity  max total size of buffers managed by this pool.
+     *
+     * \return  a newly created pool object.
+     */
+    static std::shared_ptr<LocalBufferPool> Create(size_t poolCapacity);
+
+    /**
+     * Return an ABuffer object whose size is at least |capacity|.
+     *
+     * \param   capacity  requested capacity
+     * \return  nullptr if the pool capacity is reached
+     *          an ABuffer object otherwise.
+     */
+    sp<ABuffer> newBuffer(size_t capacity);
+
+private:
+    /**
+     * ABuffer backed by std::vector.
+     */
+    class VectorBuffer : public ::android::ABuffer {
+    public:
+        /**
+         * Construct a VectorBuffer by taking the ownership of supplied vector.
+         *
+         * \param vec   backing vector of the buffer. this object takes
+         *              ownership at construction.
+         * \param pool  a LocalBufferPool object to return the vector at
+         *              destruction.
+         */
+        VectorBuffer(std::vector<uint8_t> &&vec, const std::shared_ptr<LocalBufferPool> &pool);
+
+        ~VectorBuffer() override;
+
+    private:
+        std::vector<uint8_t> mVec;
+        std::weak_ptr<LocalBufferPool> mPool;
+    };
+
+    Mutex mMutex;
+    size_t mPoolCapacity;
+    size_t mUsedSize;
+    std::list<std::vector<uint8_t>> mPool;
+
+    /**
+     * Private constructor to prevent constructing non-managed LocalBufferPool.
+     */
+    explicit LocalBufferPool(size_t poolCapacity)
+        : mPoolCapacity(poolCapacity), mUsedSize(0) {
+    }
+
+    /**
+     * Take back the ownership of vec from the destructed VectorBuffer and put
+     * it in front of the pool.
+     */
+    void returnVector(std::vector<uint8_t> &&vec);
+
+    DISALLOW_EVIL_CONSTRUCTORS(LocalBufferPool);
+};
+
+class BuffersArrayImpl;
+
+/**
+ * Flexible buffer slots implementation.
+ */
+class FlexBuffersImpl {
+public:
+    FlexBuffersImpl(const char *name)
+        : mImplName(std::string(name) + ".Impl"),
+          mName(mImplName.c_str()) { }
+
+    /**
+     * Assign an empty slot for a buffer and return the index. If there's no
+     * empty slot, just add one at the end and return it.
+     *
+     * \param buffer[in]  a new buffer to assign a slot.
+     * \return            index of the assigned slot.
+     */
+    size_t assignSlot(const sp<Codec2Buffer> &buffer);
+
+    /**
+     * Release the slot from the client, and get the C2Buffer object back from
+     * the previously assigned buffer. Note that the slot is not completely free
+     * until the returned C2Buffer object is freed.
+     *
+     * \param   buffer[in]        the buffer previously assigned a slot.
+     * \param   c2buffer[in,out]  pointer to C2Buffer to be populated. Ignored
+     *                            if null.
+     * \return  true  if the buffer is successfully released from a slot
+     *          false otherwise
+     */
+    bool releaseSlot(
+            const sp<MediaCodecBuffer> &buffer,
+            std::shared_ptr<C2Buffer> *c2buffer,
+            bool release);
+
+    /**
+     * Expire the C2Buffer object in the slot.
+     *
+     * \param   c2buffer[in]  C2Buffer object which the component released.
+     * \return  true  if the buffer is found in one of the slots and
+     *                successfully released
+     *          false otherwise
+     */
+    bool expireComponentBuffer(const std::shared_ptr<C2Buffer> &c2buffer);
+
+    /**
+     * The client abandoned all known buffers, so reclaim the ownership.
+     */
+    void flush();
+
+    /**
+     * Return the number of buffers that are sent to the client but not released
+     * yet.
+     */
+    size_t numClientBuffers() const;
+
+    /**
+     * Return the number of buffers that are sent to the component but not
+     * returned back yet.
+     */
+    size_t numComponentBuffers() const;
+
+private:
+    friend class BuffersArrayImpl;
+
+    std::string mImplName; ///< name for debugging
+    const char *mName; ///< C-string version of name
+
+    struct Entry {
+        sp<Codec2Buffer> clientBuffer;
+        std::weak_ptr<C2Buffer> compBuffer;
+    };
+    std::vector<Entry> mBuffers;
+};
+
+/**
+ * Static buffer slots implementation based on a fixed-size array.
+ */
+class BuffersArrayImpl {
+public:
+    BuffersArrayImpl()
+        : mImplName("BuffersArrayImpl"),
+          mName(mImplName.c_str()) { }
+
+    /**
+     * Initialize buffer array from the original |impl|. The buffers known by
+     * the client is preserved, and the empty slots are populated so that the
+     * array size is at least |minSize|.
+     *
+     * \param impl[in]      FlexBuffersImpl object used so far.
+     * \param minSize[in]   minimum size of the buffer array.
+     * \param allocate[in]  function to allocate a client buffer for an empty slot.
+     */
+    void initialize(
+            const FlexBuffersImpl &impl,
+            size_t minSize,
+            std::function<sp<Codec2Buffer>()> allocate);
+
+    /**
+     * Grab a buffer from the underlying array which matches the criteria.
+     *
+     * \param index[out]    index of the slot.
+     * \param buffer[out]   the matching buffer.
+     * \param match[in]     a function to test whether the buffer matches the
+     *                      criteria or not.
+     * \return OK           if successful,
+     *         WOULD_BLOCK  if slots are being used,
+     *         NO_MEMORY    if no slot matches the criteria, even though it's
+     *                      available
+     */
+    status_t grabBuffer(
+            size_t *index,
+            sp<Codec2Buffer> *buffer,
+            std::function<bool(const sp<Codec2Buffer> &)> match =
+                [](const sp<Codec2Buffer> &) { return true; });
+
+    /**
+     * Return the buffer from the client, and get the C2Buffer object back from
+     * the buffer. Note that the slot is not completely free until the returned
+     * C2Buffer object is freed.
+     *
+     * \param   buffer[in]        the buffer previously grabbed.
+     * \param   c2buffer[in,out]  pointer to C2Buffer to be populated. Ignored
+     *                            if null.
+     * \return  true  if the buffer is successfully returned
+     *          false otherwise
+     */
+    bool returnBuffer(
+            const sp<MediaCodecBuffer> &buffer,
+            std::shared_ptr<C2Buffer> *c2buffer,
+            bool release);
+
+    /**
+     * Expire the C2Buffer object in the slot.
+     *
+     * \param   c2buffer[in]  C2Buffer object which the component released.
+     * \return  true  if the buffer is found in one of the slots and
+     *                successfully released
+     *          false otherwise
+     */
+    bool expireComponentBuffer(const std::shared_ptr<C2Buffer> &c2buffer);
+
+    /**
+     * Populate |array| with the underlying buffer array.
+     *
+     * \param array[out]  an array to be filled with the underlying buffer array.
+     */
+    void getArray(Vector<sp<MediaCodecBuffer>> *array) const;
+
+    /**
+     * The client abandoned all known buffers, so reclaim the ownership.
+     */
+    void flush();
+
+    /**
+     * Reallocate the array with the given allocation function.
+     *
+     * \param alloc[in] the allocation function for client buffers.
+     */
+    void realloc(std::function<sp<Codec2Buffer>()> alloc);
+
+    /**
+     * Grow the array to the new size. It is a programming error to supply
+     * smaller size as the new size.
+     *
+     * \param newSize[in] new size of the array.
+     * \param alloc[in]   the alllocation function for client buffers to fill
+     *                    the new empty slots.
+     */
+    void grow(size_t newSize, std::function<sp<Codec2Buffer>()> alloc);
+
+    /**
+     * Return the number of buffers that are sent to the client but not released
+     * yet.
+     */
+    size_t numClientBuffers() const;
+
+    /**
+     * Return the size of the array.
+     */
+    size_t arraySize() const;
+
+private:
+    std::string mImplName; ///< name for debugging
+    const char *mName; ///< C-string version of name
+
+    struct Entry {
+        const sp<Codec2Buffer> clientBuffer;
+        std::weak_ptr<C2Buffer> compBuffer;
+        bool ownedByClient;
+    };
+    std::vector<Entry> mBuffers;
+};
+
+class InputBuffersArray : public InputBuffers {
+public:
+    InputBuffersArray(const char *componentName, const char *name = "Input[N]")
+        : InputBuffers(componentName, name) { }
+    ~InputBuffersArray() override = default;
+
+    /**
+     * Initialize this object from the non-array state. We keep existing slots
+     * at the same index, and for empty slots we allocate client buffers with
+     * the given allocate function. If the number of slots is less than minSize,
+     * we fill the array to the minimum size.
+     *
+     * \param impl[in]      existing non-array state
+     * \param minSize[in]   minimum size of the array
+     * \param allocate[in]  allocate function to fill empty slots
+     */
+    void initialize(
+            const FlexBuffersImpl &impl,
+            size_t minSize,
+            std::function<sp<Codec2Buffer>()> allocate);
+
+    bool isArrayMode() const final { return true; }
+
+    std::unique_ptr<InputBuffers> toArrayMode(size_t) final {
+        return nullptr;
+    }
+
+    void getArray(Vector<sp<MediaCodecBuffer>> *array) const final;
+
+    bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) override;
+
+    bool releaseBuffer(
+            const sp<MediaCodecBuffer> &buffer,
+            std::shared_ptr<C2Buffer> *c2buffer,
+            bool release) override;
+
+    bool expireComponentBuffer(
+            const std::shared_ptr<C2Buffer> &c2buffer) override;
+
+    void flush() override;
+
+    size_t numClientBuffers() const final;
+
+protected:
+    sp<Codec2Buffer> createNewBuffer() override;
+
+private:
+    BuffersArrayImpl mImpl;
+    std::function<sp<Codec2Buffer>()> mAllocate;
+};
+
+class LinearInputBuffers : public InputBuffers {
+public:
+    LinearInputBuffers(const char *componentName, const char *name = "1D-Input")
+        : InputBuffers(componentName, name),
+          mImpl(mName) { }
+    ~LinearInputBuffers() override = default;
+
+    bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) override;
+
+    bool releaseBuffer(
+            const sp<MediaCodecBuffer> &buffer,
+            std::shared_ptr<C2Buffer> *c2buffer,
+            bool release) override;
+
+    bool expireComponentBuffer(
+            const std::shared_ptr<C2Buffer> &c2buffer) override;
+
+    void flush() override;
+
+    std::unique_ptr<InputBuffers> toArrayMode(size_t size) override;
+
+    size_t numClientBuffers() const final;
+
+protected:
+    sp<Codec2Buffer> createNewBuffer() override;
+
+    FlexBuffersImpl mImpl;
+
+private:
+    static sp<Codec2Buffer> Alloc(
+            const std::shared_ptr<C2BlockPool> &pool, const sp<AMessage> &format);
+};
+
+class EncryptedLinearInputBuffers : public LinearInputBuffers {
+public:
+    EncryptedLinearInputBuffers(
+            bool secure,
+            const sp<MemoryDealer> &dealer,
+            const sp<ICrypto> &crypto,
+            int32_t heapSeqNum,
+            size_t capacity,
+            size_t numInputSlots,
+            const char *componentName, const char *name = "EncryptedInput");
+
+    ~EncryptedLinearInputBuffers() override = default;
+
+    std::unique_ptr<InputBuffers> toArrayMode(size_t size) override;
+
+protected:
+    sp<Codec2Buffer> createNewBuffer() override;
+
+private:
+    struct Entry {
+        std::weak_ptr<C2LinearBlock> block;
+        sp<IMemory> memory;
+        int32_t heapSeqNum;
+    };
+
+    static sp<Codec2Buffer> Alloc(
+            const std::shared_ptr<C2BlockPool> &pool,
+            const sp<AMessage> &format,
+            C2MemoryUsage usage,
+            const std::shared_ptr<std::vector<Entry>> &memoryVector);
+
+    C2MemoryUsage mUsage;
+    sp<MemoryDealer> mDealer;
+    sp<ICrypto> mCrypto;
+    std::shared_ptr<std::vector<Entry>> mMemoryVector;
+};
+
+class GraphicMetadataInputBuffers : public InputBuffers {
+public:
+    GraphicMetadataInputBuffers(const char *componentName, const char *name = "2D-MetaInput");
+    ~GraphicMetadataInputBuffers() override = default;
+
+    bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) override;
+
+    bool releaseBuffer(
+            const sp<MediaCodecBuffer> &buffer,
+            std::shared_ptr<C2Buffer> *c2buffer,
+            bool release) override;
+
+    bool expireComponentBuffer(
+            const std::shared_ptr<C2Buffer> &c2buffer) override;
+
+    void flush() override;
+
+    std::unique_ptr<InputBuffers> toArrayMode(size_t size) final;
+
+    size_t numClientBuffers() const final;
+
+protected:
+    sp<Codec2Buffer> createNewBuffer() override;
+
+private:
+    FlexBuffersImpl mImpl;
+    std::shared_ptr<C2AllocatorStore> mStore;
+};
+
+class GraphicInputBuffers : public InputBuffers {
+public:
+    GraphicInputBuffers(
+            size_t numInputSlots, const char *componentName, const char *name = "2D-BB-Input");
+    ~GraphicInputBuffers() override = default;
+
+    bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) override;
+
+    bool releaseBuffer(
+            const sp<MediaCodecBuffer> &buffer,
+            std::shared_ptr<C2Buffer> *c2buffer,
+            bool release) override;
+
+    bool expireComponentBuffer(
+            const std::shared_ptr<C2Buffer> &c2buffer) override;
+
+    void flush() override;
+
+    std::unique_ptr<InputBuffers> toArrayMode(
+            size_t size) final;
+
+    size_t numClientBuffers() const final;
+
+protected:
+    sp<Codec2Buffer> createNewBuffer() override;
+
+private:
+    FlexBuffersImpl mImpl;
+    std::shared_ptr<LocalBufferPool> mLocalBufferPool;
+};
+
+class DummyInputBuffers : public InputBuffers {
+public:
+    DummyInputBuffers(const char *componentName, const char *name = "2D-Input")
+        : InputBuffers(componentName, name) { }
+    ~DummyInputBuffers() override = default;
+
+    bool requestNewBuffer(size_t *, sp<MediaCodecBuffer> *) override {
+        return false;
+    }
+
+    bool releaseBuffer(
+            const sp<MediaCodecBuffer> &, std::shared_ptr<C2Buffer> *, bool) override {
+        return false;
+    }
+
+    bool expireComponentBuffer(const std::shared_ptr<C2Buffer> &) override {
+        return false;
+    }
+    void flush() override {
+    }
+
+    std::unique_ptr<InputBuffers> toArrayMode(size_t) final {
+        return nullptr;
+    }
+
+    bool isArrayMode() const final { return true; }
+
+    void getArray(Vector<sp<MediaCodecBuffer>> *array) const final {
+        array->clear();
+    }
+
+    size_t numClientBuffers() const final {
+        return 0u;
+    }
+
+protected:
+    sp<Codec2Buffer> createNewBuffer() override {
+        return nullptr;
+    }
+};
+
+class OutputBuffersArray : public OutputBuffers {
+public:
+    OutputBuffersArray(const char *componentName, const char *name = "Output[N]")
+        : OutputBuffers(componentName, name) { }
+    ~OutputBuffersArray() override = default;
+
+    /**
+     * Initialize this object from the non-array state. We keep existing slots
+     * at the same index, and for empty slots we allocate client buffers with
+     * the given allocate function. If the number of slots is less than minSize,
+     * we fill the array to the minimum size.
+     *
+     * \param impl[in]      existing non-array state
+     * \param minSize[in]   minimum size of the array
+     * \param allocate[in]  allocate function to fill empty slots
+     */
+    void initialize(
+            const FlexBuffersImpl &impl,
+            size_t minSize,
+            std::function<sp<Codec2Buffer>()> allocate);
+
+    bool isArrayMode() const final { return true; }
+
+    std::unique_ptr<OutputBuffers> toArrayMode(size_t) final {
+        return nullptr;
+    }
+
+    status_t registerBuffer(
+            const std::shared_ptr<C2Buffer> &buffer,
+            size_t *index,
+            sp<MediaCodecBuffer> *clientBuffer) final;
+
+    status_t registerCsd(
+            const C2StreamInitDataInfo::output *csd,
+            size_t *index,
+            sp<MediaCodecBuffer> *clientBuffer) final;
+
+    bool releaseBuffer(
+            const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) override;
+
+    void flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) override;
+
+    void getArray(Vector<sp<MediaCodecBuffer>> *array) const final;
+
+    size_t numClientBuffers() const final;
+
+    /**
+     * Reallocate the array, filled with buffers with the same size as given
+     * buffer.
+     *
+     * \param c2buffer[in] the reference buffer
+     */
+    void realloc(const std::shared_ptr<C2Buffer> &c2buffer);
+
+    /**
+     * Grow the array to the new size. It is a programming error to supply
+     * smaller size as the new size.
+     *
+     * \param newSize[in] new size of the array.
+     */
+    void grow(size_t newSize);
+
+private:
+    BuffersArrayImpl mImpl;
+    std::function<sp<Codec2Buffer>()> mAlloc;
+};
+
+class FlexOutputBuffers : public OutputBuffers {
+public:
+    FlexOutputBuffers(const char *componentName, const char *name = "Output[]")
+        : OutputBuffers(componentName, name),
+          mImpl(mName) { }
+
+    status_t registerBuffer(
+            const std::shared_ptr<C2Buffer> &buffer,
+            size_t *index,
+            sp<MediaCodecBuffer> *clientBuffer) override;
+
+    status_t registerCsd(
+            const C2StreamInitDataInfo::output *csd,
+            size_t *index,
+            sp<MediaCodecBuffer> *clientBuffer) final;
+
+    bool releaseBuffer(
+            const sp<MediaCodecBuffer> &buffer,
+            std::shared_ptr<C2Buffer> *c2buffer) override;
+
+    void flush(
+            const std::list<std::unique_ptr<C2Work>> &flushedWork) override;
+
+    std::unique_ptr<OutputBuffers> toArrayMode(size_t size) override;
+
+    size_t numClientBuffers() const final;
+
+    /**
+     * Return an appropriate Codec2Buffer object for the type of buffers.
+     *
+     * \param buffer  C2Buffer object to wrap.
+     *
+     * \return  appropriate Codec2Buffer object to wrap |buffer|.
+     */
+    virtual sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) = 0;
+
+    /**
+     * Return a function that allocates an appropriate Codec2Buffer object for
+     * the type of buffers, to be used as an empty array buffer. The function
+     * must not refer to this pointer, since it may be used after this object
+     * destructs.
+     *
+     * \return  a function that allocates appropriate Codec2Buffer object,
+     *          which can copy() from C2Buffers.
+     */
+    virtual std::function<sp<Codec2Buffer>()> getAlloc() = 0;
+
+private:
+    FlexBuffersImpl mImpl;
+};
+
+class LinearOutputBuffers : public FlexOutputBuffers {
+public:
+    LinearOutputBuffers(const char *componentName, const char *name = "1D-Output")
+        : FlexOutputBuffers(componentName, name) { }
+
+    void flush(
+            const std::list<std::unique_ptr<C2Work>> &flushedWork) override;
+
+    sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override;
+
+    std::function<sp<Codec2Buffer>()> getAlloc() override;
+};
+
+class GraphicOutputBuffers : public FlexOutputBuffers {
+public:
+    GraphicOutputBuffers(const char *componentName, const char *name = "2D-Output")
+        : FlexOutputBuffers(componentName, name) { }
+
+    sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override;
+
+    std::function<sp<Codec2Buffer>()> getAlloc() override;
+};
+
+class RawGraphicOutputBuffers : public FlexOutputBuffers {
+public:
+    RawGraphicOutputBuffers(
+            size_t numOutputSlots, const char *componentName, const char *name = "2D-BB-Output");
+    ~RawGraphicOutputBuffers() override = default;
+
+    sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override;
+
+    std::function<sp<Codec2Buffer>()> getAlloc() override;
+
+private:
+    std::shared_ptr<LocalBufferPool> mLocalBufferPool;
+};
+
+}  // namespace android
+
+#endif  // CCODEC_BUFFERS_H_
diff --git a/media/codec2/sfplugin/CCodecConfig.cpp b/media/codec2/sfplugin/CCodecConfig.cpp
new file mode 100644
index 0000000..1cfdc19
--- /dev/null
+++ b/media/codec2/sfplugin/CCodecConfig.cpp
@@ -0,0 +1,1621 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "CCodecConfig"
+#include <cutils/properties.h>
+#include <log/log.h>
+
+#include <C2Component.h>
+#include <C2Debug.h>
+#include <C2Param.h>
+#include <util/C2InterfaceHelper.h>
+
+#include <media/stagefright/MediaCodecConstants.h>
+
+#include "CCodecConfig.h"
+#include "Codec2Mapper.h"
+
+#define DRC_DEFAULT_MOBILE_REF_LEVEL 64  /* 64*-0.25dB = -16 dB below full scale for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_CUT   127 /* maximum compression of dynamic range for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_BOOST 127 /* maximum compression of dynamic range for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_HEAVY 1   /* switch for heavy compression for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_EFFECT 3  /* MPEG-D DRC effect type; 3 => Limited playback range */
+#define DRC_DEFAULT_MOBILE_ENC_LEVEL (-1) /* encoder target level; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
+// names of properties that can be used to override the default DRC settings
+#define PROP_DRC_OVERRIDE_REF_LEVEL  "aac_drc_reference_level"
+#define PROP_DRC_OVERRIDE_CUT        "aac_drc_cut"
+#define PROP_DRC_OVERRIDE_BOOST      "aac_drc_boost"
+#define PROP_DRC_OVERRIDE_HEAVY      "aac_drc_heavy"
+#define PROP_DRC_OVERRIDE_ENC_LEVEL  "aac_drc_enc_target_level"
+#define PROP_DRC_OVERRIDE_EFFECT     "ro.aac_drc_effect_type"
+
+namespace android {
+
+// CCodecConfig
+
+namespace {
+
+/**
+ * mapping between SDK and Codec 2.0 configurations.
+ */
+struct ConfigMapper {
+    /**
+     * Value mapper (C2Value => C2Value)
+     */
+    typedef std::function<C2Value(C2Value)> Mapper;
+
+    /// shorthand
+    typedef CCodecConfig::Domain Domain;
+
+    ConfigMapper(std::string mediaKey, C2String c2struct, C2String c2field)
+        : mDomain(Domain::ALL), mMediaKey(mediaKey), mStruct(c2struct), mField(c2field) { }
+
+    /// Limits this parameter to the given domain
+    ConfigMapper &limitTo(uint32_t domain) {
+        C2_CHECK(domain & Domain::GUARD_BIT);
+        mDomain = Domain(mDomain & domain);
+        return *this;
+    }
+
+    /// Adds SDK => Codec 2.0 mapper (should not be in the SDK format)
+    ConfigMapper &withMapper(Mapper mapper) {
+        C2_CHECK(!mMapper);
+        C2_CHECK(!mReverse);
+        mMapper = mapper;
+        return *this;
+    }
+
+    /// Adds SDK <=> Codec 2.0 value mappers
+    ConfigMapper &withMappers(Mapper mapper, Mapper reverse) {
+        C2_CHECK(!mMapper);
+        C2_CHECK(!mReverse);
+        mMapper = mapper;
+        mReverse = reverse;
+        return *this;
+    }
+
+    /// Adds SDK <=> Codec 2.0 value mappers based on C2Mapper
+    template<typename C2Type, typename SdkType=int32_t>
+    ConfigMapper &withC2Mappers() {
+        C2_CHECK(!mMapper);
+        C2_CHECK(!mReverse);
+        mMapper = [](C2Value v) -> C2Value {
+            SdkType sdkValue;
+            C2Type c2Value;
+            if (v.get(&sdkValue) && C2Mapper::map(sdkValue, &c2Value)) {
+                return c2Value;
+            }
+            return C2Value();
+        };
+        mReverse = [](C2Value v) -> C2Value {
+            SdkType sdkValue;
+            C2Type c2Value;
+            using C2ValueType=typename _c2_reduce_enum_to_underlying_type<C2Type>::type;
+            if (v.get((C2ValueType*)&c2Value) && C2Mapper::map(c2Value, &sdkValue)) {
+                return sdkValue;
+            }
+            return C2Value();
+        };
+        return *this;
+    }
+
+    /// Maps from SDK values in an AMessage to a suitable C2Value.
+    C2Value mapFromMessage(const AMessage::ItemData &item) const {
+        C2Value value;
+        int32_t int32Value;
+        int64_t int64Value;
+        float floatValue;
+        double doubleValue;
+        if (item.find(&int32Value)) {
+            value = int32Value;
+        } else if (item.find(&int64Value)) {
+            value = int64Value;
+        } else if (item.find(&floatValue)) {
+            value = floatValue;
+        } else if (item.find(&doubleValue)) {
+            value = (float)doubleValue;
+        }
+        if (value.type() != C2Value::NO_INIT && mMapper) {
+            value = mMapper(value);
+        }
+        return value;
+    }
+
+    /// Maps from a C2Value to an SDK value in an AMessage.
+    AMessage::ItemData mapToMessage(C2Value value) const {
+        AMessage::ItemData item;
+        int32_t int32Value;
+        uint32_t uint32Value;
+        int64_t int64Value;
+        uint64_t uint64Value;
+        float floatValue;
+        if (value.type() != C2Value::NO_INIT && mReverse) {
+            value = mReverse(value);
+        }
+        if (value.get(&int32Value)) {
+            item.set(int32Value);
+        } else if (value.get(&uint32Value) && uint32Value <= uint32_t(INT32_MAX)) {
+            // SDK does not support unsigned values
+            item.set((int32_t)uint32Value);
+        } else if (value.get(&int64Value)) {
+            item.set(int64Value);
+        } else if (value.get(&uint64Value) && uint64Value <= uint64_t(INT64_MAX)) {
+            // SDK does not support unsigned values
+            item.set((int64_t)uint64Value);
+        } else if (value.get(&floatValue)) {
+            item.set(floatValue);
+        }
+        return item;
+    }
+
+    Domain domain() const { return mDomain; }
+    std::string mediaKey() const { return mMediaKey; }
+    std::string path() const { return mField.size() ? mStruct + '.' + mField : mStruct; }
+    Mapper mapper() const { return mMapper; }
+    Mapper reverse() const { return mReverse; }
+
+private:
+    Domain mDomain;         ///< parameter domain (mask) containing port, kind and config domains
+    std::string mMediaKey;  ///< SDK key
+    C2String mStruct;       ///< Codec 2.0 struct name
+    C2String mField;        ///< Codec 2.0 field name
+    Mapper mMapper;         ///< optional SDK => Codec 2.0 value mapper
+    Mapper mReverse;        ///< optional Codec 2.0 => SDK value mapper
+};
+
+template <typename PORT, typename STREAM>
+AString QueryMediaTypeImpl(
+        const std::shared_ptr<Codec2Client::Component> &component) {
+    AString mediaType;
+    std::vector<std::unique_ptr<C2Param>> queried;
+    c2_status_t c2err = component->query(
+            {}, { PORT::PARAM_TYPE, STREAM::PARAM_TYPE }, C2_DONT_BLOCK, &queried);
+    if (c2err != C2_OK && queried.size() == 0) {
+        ALOGD("Query media type failed => %s", asString(c2err));
+    } else {
+        PORT *portMediaType =
+            PORT::From(queried[0].get());
+        if (portMediaType) {
+            mediaType = AString(
+                    portMediaType->m.value,
+                    strnlen(portMediaType->m.value, portMediaType->flexCount()));
+        } else {
+            STREAM *streamMediaType = STREAM::From(queried[0].get());
+            if (streamMediaType) {
+                mediaType = AString(
+                        streamMediaType->m.value,
+                        strnlen(streamMediaType->m.value, streamMediaType->flexCount()));
+            }
+        }
+        ALOGD("read media type: %s", mediaType.c_str());
+    }
+    return mediaType;
+}
+
+AString QueryMediaType(
+        bool input, const std::shared_ptr<Codec2Client::Component> &component) {
+    typedef C2PortMediaTypeSetting P;
+    typedef C2StreamMediaTypeSetting S;
+    if (input) {
+        return QueryMediaTypeImpl<P::input, S::input>(component);
+    } else {
+        return QueryMediaTypeImpl<P::output, S::output>(component);
+    }
+}
+
+}  // namespace
+
+/**
+ * Set of standard parameters used by CCodec that are exposed to MediaCodec.
+ */
+struct StandardParams {
+    typedef CCodecConfig::Domain Domain;
+
+    // standard (MediaCodec) params are keyed by media format key
+    typedef std::string SdkKey;
+
+    /// used to return reference to no config mappers in getConfigMappersForSdkKey
+    static const std::vector<ConfigMapper> NO_MAPPERS;
+
+    /// Returns Codec 2.0 equivalent parameters for an SDK format key.
+    const std::vector<ConfigMapper> &getConfigMappersForSdkKey(std::string key) const {
+        auto it = mConfigMappers.find(key);
+        if (it == mConfigMappers.end()) {
+            ALOGD("no c2 equivalents for %s", key.c_str());
+            return NO_MAPPERS;
+        }
+        ALOGV("found %zu eqs for %s", it->second.size(), key.c_str());
+        return it->second;
+    }
+
+    /**
+     * Adds a SDK <=> Codec 2.0 parameter mapping. Multiple Codec 2.0 parameters may map to a
+     * single SDK key, in which case they shall be ordered from least authoritative to most
+     * authoritative. When constructing SDK formats, the last mapped Codec 2.0 parameter that
+     * is supported by the component will determine the exposed value. (TODO: perhaps restrict this
+     * by domain.)
+     */
+    void add(const ConfigMapper &cm) {
+        auto it = mConfigMappers.find(cm.mediaKey());
+        ALOGV("%c%c%c%c %c%c%c %04x %9s %s => %s",
+              ((cm.domain() & Domain::IS_INPUT) ? 'I' : ' '),
+              ((cm.domain() & Domain::IS_OUTPUT) ? 'O' : ' '),
+              ((cm.domain() & Domain::IS_CODED) ? 'C' : ' '),
+              ((cm.domain() & Domain::IS_RAW) ? 'R' : ' '),
+              ((cm.domain() & Domain::IS_CONFIG) ? 'c' : ' '),
+              ((cm.domain() & Domain::IS_PARAM) ? 'p' : ' '),
+              ((cm.domain() & Domain::IS_READ) ? 'r' : ' '),
+              cm.domain(),
+              it == mConfigMappers.end() ? "adding" : "extending",
+              cm.mediaKey().c_str(), cm.path().c_str());
+        if (it == mConfigMappers.end()) {
+            std::vector<ConfigMapper> eqs = { cm };
+            mConfigMappers.emplace(cm.mediaKey(), eqs);
+        } else {
+            it->second.push_back(cm);
+        }
+    }
+
+    /**
+     * Returns all paths for a specific domain.
+     *
+     * \param any maximum domain mask. Returned parameters must match at least one of the domains
+     *            in the mask.
+     * \param all minimum domain mask. Returned parameters must match all of the domains in the
+     *            mask. This is restricted to the bits of the maximum mask.
+     */
+    std::vector<std::string> getPathsForDomain(
+            Domain any, Domain all = Domain::ALL) const {
+        std::vector<std::string> res;
+        for (const std::pair<std::string, std::vector<ConfigMapper>> &el : mConfigMappers) {
+            for (const ConfigMapper &cm : el.second) {
+                ALOGV("filtering %s %x %x %x %x", cm.path().c_str(), cm.domain(), any,
+                        (cm.domain() & any), (cm.domain() & any & all));
+                if ((cm.domain() & any) && ((cm.domain() & any & all) == (any & all))) {
+                    res.push_back(cm.path());
+                }
+            }
+        }
+        return res;
+    }
+
+    /**
+     * Returns SDK <=> Codec 2.0 mappings.
+     *
+     * TODO: replace these with better methods as this exposes the inner structure.
+     */
+    const std::map<SdkKey, std::vector<ConfigMapper>> getKeys() const {
+        return mConfigMappers;
+    }
+
+private:
+    std::map<SdkKey, std::vector<ConfigMapper>> mConfigMappers;
+};
+
+const std::vector<ConfigMapper> StandardParams::NO_MAPPERS;
+
+
+CCodecConfig::CCodecConfig()
+    : mInputFormat(new AMessage),
+      mOutputFormat(new AMessage),
+      mUsingSurface(false) { }
+
+void CCodecConfig::initializeStandardParams() {
+    typedef Domain D;
+    mStandardParams = std::make_shared<StandardParams>();
+    std::function<void(const ConfigMapper &)> add =
+        [params = mStandardParams](const ConfigMapper &cm) {
+            params->add(cm);
+    };
+    std::function<void(const ConfigMapper &)> deprecated = add;
+
+    // allow int32 or float SDK values and represent them as float
+    ConfigMapper::Mapper makeFloat = [](C2Value v) -> C2Value {
+        // convert from i32 to float
+        int32_t i32Value;
+        float fpValue;
+        if (v.get(&i32Value)) {
+            return (float)i32Value;
+        } else if (v.get(&fpValue)) {
+            return fpValue;
+        }
+        return C2Value();
+    };
+
+    ConfigMapper::Mapper negate = [](C2Value v) -> C2Value {
+        int32_t value;
+        if (v.get(&value)) {
+            return -value;
+        }
+        return C2Value();
+    };
+
+    add(ConfigMapper(KEY_MIME,     C2_PARAMKEY_INPUT_MEDIA_TYPE,    "value")
+        .limitTo(D::INPUT & D::READ));
+    add(ConfigMapper(KEY_MIME,     C2_PARAMKEY_OUTPUT_MEDIA_TYPE,   "value")
+        .limitTo(D::OUTPUT & D::READ));
+
+    add(ConfigMapper(KEY_BIT_RATE, C2_PARAMKEY_BITRATE, "value")
+        .limitTo(D::ENCODER & D::OUTPUT));
+    // we also need to put the bitrate in the max bitrate field
+    add(ConfigMapper(KEY_MAX_BIT_RATE, C2_PARAMKEY_BITRATE, "value")
+        .limitTo(D::ENCODER & D::READ & D::OUTPUT));
+    add(ConfigMapper(PARAMETER_KEY_VIDEO_BITRATE, C2_PARAMKEY_BITRATE, "value")
+        .limitTo(D::ENCODER & D::VIDEO & D::PARAM));
+    add(ConfigMapper(KEY_BITRATE_MODE, C2_PARAMKEY_BITRATE_MODE, "value")
+        .limitTo(D::ENCODER & D::CODED)
+        .withC2Mappers<C2Config::bitrate_mode_t>());
+    // remove when codecs switch to PARAMKEY and new modes
+    deprecated(ConfigMapper(KEY_BITRATE_MODE, "coded.bitrate-mode", "value")
+               .limitTo(D::ENCODER));
+    add(ConfigMapper(KEY_FRAME_RATE, C2_PARAMKEY_FRAME_RATE, "value")
+        .limitTo(D::VIDEO)
+        .withMappers(makeFloat, [](C2Value v) -> C2Value {
+            // read back always as int
+            float value;
+            if (v.get(&value)) {
+                return (int32_t)value;
+            }
+            return C2Value();
+        }));
+
+    add(ConfigMapper(KEY_MAX_INPUT_SIZE, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE, "value")
+        .limitTo(D::INPUT));
+    // remove when codecs switch to PARAMKEY
+    deprecated(ConfigMapper(KEY_MAX_INPUT_SIZE, "coded.max-frame-size", "value")
+               .limitTo(D::INPUT));
+
+    // Rotation
+    // Note: SDK rotation is clock-wise, while C2 rotation is counter-clock-wise
+    add(ConfigMapper(KEY_ROTATION, C2_PARAMKEY_VUI_ROTATION, "value")
+        .limitTo(D::VIDEO & D::CODED)
+        .withMappers(negate, negate));
+    add(ConfigMapper(KEY_ROTATION, C2_PARAMKEY_ROTATION, "value")
+        .limitTo(D::VIDEO & D::RAW)
+        .withMappers(negate, negate));
+
+    // android 'video-scaling'
+    add(ConfigMapper("android._video-scaling", C2_PARAMKEY_SURFACE_SCALING_MODE, "value")
+        .limitTo(D::VIDEO & D::DECODER & D::RAW));
+
+    // Color Aspects
+    //
+    // configure default for decoders
+    add(ConfigMapper(KEY_COLOR_RANGE,       C2_PARAMKEY_DEFAULT_COLOR_ASPECTS,   "range")
+        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::CODED & (D::CONFIG | D::PARAM))
+        .withC2Mappers<C2Color::range_t>());
+    add(ConfigMapper(KEY_COLOR_TRANSFER,    C2_PARAMKEY_DEFAULT_COLOR_ASPECTS,   "transfer")
+        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::CODED & (D::CONFIG | D::PARAM))
+        .withC2Mappers<C2Color::transfer_t>());
+    add(ConfigMapper("color-primaries",     C2_PARAMKEY_DEFAULT_COLOR_ASPECTS,   "primaries")
+        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::CODED & (D::CONFIG | D::PARAM)));
+    add(ConfigMapper("color-matrix",        C2_PARAMKEY_DEFAULT_COLOR_ASPECTS,   "matrix")
+        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::CODED & (D::CONFIG | D::PARAM)));
+
+    // read back final for decoder output (also, configure final aspects as well. This should be
+    // overwritten based on coded/default values if component supports color aspects, but is used
+    // as final values if component does not support aspects at all)
+    add(ConfigMapper(KEY_COLOR_RANGE,       C2_PARAMKEY_COLOR_ASPECTS,   "range")
+        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::RAW)
+        .withC2Mappers<C2Color::range_t>());
+    add(ConfigMapper(KEY_COLOR_TRANSFER,    C2_PARAMKEY_COLOR_ASPECTS,   "transfer")
+        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::RAW)
+        .withC2Mappers<C2Color::transfer_t>());
+    add(ConfigMapper("color-primaries",     C2_PARAMKEY_COLOR_ASPECTS,   "primaries")
+        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::RAW));
+    add(ConfigMapper("color-matrix",        C2_PARAMKEY_COLOR_ASPECTS,   "matrix")
+        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::RAW));
+
+    // configure source aspects for encoders and read them back on the coded(!) port.
+    // This is to ensure muxing the desired aspects into the container.
+    add(ConfigMapper(KEY_COLOR_RANGE,       C2_PARAMKEY_COLOR_ASPECTS,   "range")
+        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::CODED)
+        .withC2Mappers<C2Color::range_t>());
+    add(ConfigMapper(KEY_COLOR_TRANSFER,    C2_PARAMKEY_COLOR_ASPECTS,   "transfer")
+        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::CODED)
+        .withC2Mappers<C2Color::transfer_t>());
+    add(ConfigMapper("color-primaries",     C2_PARAMKEY_COLOR_ASPECTS,   "primaries")
+        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::CODED));
+    add(ConfigMapper("color-matrix",        C2_PARAMKEY_COLOR_ASPECTS,   "matrix")
+        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::CODED));
+
+    // read back coded aspects for encoders (on the raw port), but also configure
+    // desired aspects here.
+    add(ConfigMapper(KEY_COLOR_RANGE,       C2_PARAMKEY_VUI_COLOR_ASPECTS,   "range")
+        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::RAW)
+        .withC2Mappers<C2Color::range_t>());
+    add(ConfigMapper(KEY_COLOR_TRANSFER,    C2_PARAMKEY_VUI_COLOR_ASPECTS,   "transfer")
+        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::RAW)
+        .withC2Mappers<C2Color::transfer_t>());
+    add(ConfigMapper("color-primaries",     C2_PARAMKEY_VUI_COLOR_ASPECTS,   "primaries")
+        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::RAW));
+    add(ConfigMapper("color-matrix",        C2_PARAMKEY_VUI_COLOR_ASPECTS,   "matrix")
+        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::RAW));
+
+    // Dataspace
+    add(ConfigMapper("android._dataspace", C2_PARAMKEY_DATA_SPACE, "value")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+
+    // HDR
+    add(ConfigMapper("smpte2086.red.x", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.red.x")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+    add(ConfigMapper("smpte2086.red.y", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.red.y")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+    add(ConfigMapper("smpte2086.green.x", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.green.x")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+    add(ConfigMapper("smpte2086.green.y", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.green.y")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+    add(ConfigMapper("smpte2086.blue.x", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.blue.x")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+    add(ConfigMapper("smpte2086.blue.y", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.blue.y")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+    add(ConfigMapper("smpte2086.white.x", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.white.x")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+    add(ConfigMapper("smpte2086.white.y", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.white.y")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+    add(ConfigMapper("smpte2086.max-luminance", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.max-luminance")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+    add(ConfigMapper("smpte2086.min-luminance", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.min-luminance")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+    add(ConfigMapper("cta861.max-cll", C2_PARAMKEY_HDR_STATIC_INFO, "max-cll")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+    add(ConfigMapper("cta861.max-fall", C2_PARAMKEY_HDR_STATIC_INFO, "max-fall")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+
+    add(ConfigMapper(std::string(KEY_FEATURE_) + FEATURE_SecurePlayback,
+                     C2_PARAMKEY_SECURE_MODE, "value"));
+
+    add(ConfigMapper(KEY_PREPEND_HEADERS_TO_SYNC_FRAMES,
+                     C2_PARAMKEY_PREPEND_HEADER_MODE, "value")
+        .limitTo(D::ENCODER & D::VIDEO)
+        .withMappers([](C2Value v) -> C2Value {
+            int32_t value;
+            if (v.get(&value)) {
+                return value ? C2Value(C2Config::PREPEND_HEADER_TO_ALL_SYNC)
+                             : C2Value(C2Config::PREPEND_HEADER_TO_NONE);
+            }
+            return C2Value();
+        }, [](C2Value v) -> C2Value {
+            C2Config::prepend_header_mode_t value;
+            using C2ValueType=typename _c2_reduce_enum_to_underlying_type<decltype(value)>::type;
+            if (v.get((C2ValueType *)&value)) {
+                switch (value) {
+                    case C2Config::PREPEND_HEADER_TO_NONE:      return 0;
+                    case C2Config::PREPEND_HEADER_TO_ALL_SYNC:  return 1;
+                    case C2Config::PREPEND_HEADER_ON_CHANGE:    [[fallthrough]];
+                    default:                                    return C2Value();
+                }
+            }
+            return C2Value();
+        }));
+    // remove when codecs switch to PARAMKEY
+    deprecated(ConfigMapper(KEY_PREPEND_HEADERS_TO_SYNC_FRAMES,
+                            "coding.add-csd-to-sync-frames", "value")
+               .limitTo(D::ENCODER & D::VIDEO));
+    // convert to timestamp base
+    add(ConfigMapper(KEY_I_FRAME_INTERVAL, C2_PARAMKEY_SYNC_FRAME_INTERVAL, "value")
+        .withMappers([](C2Value v) -> C2Value {
+            // convert from i32 to float
+            int32_t i32Value;
+            float fpValue;
+            if (v.get(&i32Value)) {
+                return int64_t(1000000) * i32Value;
+            } else if (v.get(&fpValue)) {
+                return int64_t(c2_min(1000000 * fpValue + 0.5, (double)INT64_MAX));
+            }
+            return C2Value();
+        }, [](C2Value v) -> C2Value {
+            int64_t i64;
+            if (v.get(&i64)) {
+                return float(i64) / 1000000;
+            }
+            return C2Value();
+        }));
+    // remove when codecs switch to proper coding.gop (add support for calculating gop)
+    deprecated(ConfigMapper("i-frame-period", "coding.gop", "intra-period")
+               .limitTo(D::ENCODER & D::VIDEO));
+    add(ConfigMapper(KEY_INTRA_REFRESH_PERIOD, C2_PARAMKEY_INTRA_REFRESH, "period")
+        .limitTo(D::VIDEO & D::ENCODER)
+        .withMappers(makeFloat, [](C2Value v) -> C2Value {
+            // read back always as int
+            float value;
+            if (v.get(&value)) {
+                return (int32_t)value;
+            }
+            return C2Value();
+        }));
+    deprecated(ConfigMapper(PARAMETER_KEY_REQUEST_SYNC_FRAME,
+                     "coding.request-sync", "value")
+        .limitTo(D::PARAM & D::ENCODER)
+        .withMapper([](C2Value) -> C2Value { return uint32_t(1); }));
+    add(ConfigMapper(PARAMETER_KEY_REQUEST_SYNC_FRAME,
+                     C2_PARAMKEY_REQUEST_SYNC_FRAME, "value")
+        .limitTo(D::PARAM & D::ENCODER)
+        .withMapper([](C2Value) -> C2Value { return uint32_t(1); }));
+
+    add(ConfigMapper(KEY_OPERATING_RATE,   C2_PARAMKEY_OPERATING_RATE,     "value")
+        .limitTo(D::PARAM | D::CONFIG) // write-only
+        .withMapper(makeFloat));
+    // C2 priorities are inverted
+    add(ConfigMapper(KEY_PRIORITY,         C2_PARAMKEY_PRIORITY,           "value")
+        .withMappers(negate, negate));
+    // remove when codecs switch to PARAMKEY
+    deprecated(ConfigMapper(KEY_OPERATING_RATE,   "ctrl.operating-rate",     "value")
+               .withMapper(makeFloat));
+    deprecated(ConfigMapper(KEY_PRIORITY,         "ctrl.priority",           "value"));
+
+    add(ConfigMapper(KEY_WIDTH,         C2_PARAMKEY_PICTURE_SIZE,       "width")
+        .limitTo(D::VIDEO | D::IMAGE));
+    add(ConfigMapper(KEY_HEIGHT,        C2_PARAMKEY_PICTURE_SIZE,       "height")
+        .limitTo(D::VIDEO | D::IMAGE));
+
+    add(ConfigMapper("crop-left",       C2_PARAMKEY_CROP_RECT,       "left")
+        .limitTo(D::VIDEO | D::IMAGE));
+    add(ConfigMapper("crop-top",        C2_PARAMKEY_CROP_RECT,       "top")
+        .limitTo(D::VIDEO | D::IMAGE));
+    add(ConfigMapper("crop-width",      C2_PARAMKEY_CROP_RECT,       "width")
+        .limitTo(D::VIDEO | D::IMAGE));
+    add(ConfigMapper("crop-height",     C2_PARAMKEY_CROP_RECT,       "height")
+        .limitTo(D::VIDEO | D::IMAGE));
+
+    add(ConfigMapper(KEY_MAX_WIDTH,     C2_PARAMKEY_MAX_PICTURE_SIZE,    "width")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+    add(ConfigMapper(KEY_MAX_HEIGHT,    C2_PARAMKEY_MAX_PICTURE_SIZE,    "height")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+
+    add(ConfigMapper("csd-0",           C2_PARAMKEY_INIT_DATA,       "value")
+        .limitTo(D::OUTPUT & D::READ));
+
+    add(ConfigMapper(KEY_HDR10_PLUS_INFO, C2_PARAMKEY_INPUT_HDR10_PLUS_INFO, "value")
+        .limitTo(D::VIDEO & D::PARAM & D::INPUT));
+
+    add(ConfigMapper(KEY_HDR10_PLUS_INFO, C2_PARAMKEY_OUTPUT_HDR10_PLUS_INFO, "value")
+        .limitTo(D::VIDEO & D::OUTPUT));
+
+    add(ConfigMapper(C2_PARAMKEY_TEMPORAL_LAYERING, C2_PARAMKEY_TEMPORAL_LAYERING, "")
+        .limitTo(D::ENCODER & D::VIDEO & D::OUTPUT));
+
+    // Pixel Format (use local key for actual pixel format as we don't distinguish between
+    // SDK layouts for flexible format and we need the actual SDK color format in the media format)
+    add(ConfigMapper("android._color-format",  C2_PARAMKEY_PIXEL_FORMAT, "value")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW)
+        .withMappers([](C2Value v) -> C2Value {
+            int32_t value;
+            if (v.get(&value)) {
+                switch (value) {
+                    case COLOR_FormatSurface:
+                        return (uint32_t)HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
+                    case COLOR_FormatYUV420Flexible:
+                        return (uint32_t)HAL_PIXEL_FORMAT_YCBCR_420_888;
+                    case COLOR_FormatYUV420Planar:
+                    case COLOR_FormatYUV420SemiPlanar:
+                    case COLOR_FormatYUV420PackedPlanar:
+                    case COLOR_FormatYUV420PackedSemiPlanar:
+                        return (uint32_t)HAL_PIXEL_FORMAT_YV12;
+                    default:
+                        // TODO: support some sort of passthrough
+                        break;
+                }
+            }
+            return C2Value();
+        }, [](C2Value v) -> C2Value {
+            uint32_t value;
+            if (v.get(&value)) {
+                switch (value) {
+                    case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
+                        return COLOR_FormatSurface;
+                    case HAL_PIXEL_FORMAT_YV12:
+                    case HAL_PIXEL_FORMAT_YCBCR_420_888:
+                        return COLOR_FormatYUV420Flexible;
+                    default:
+                        // TODO: support some sort of passthrough
+                        break;
+                }
+            }
+            return C2Value();
+        }));
+
+    add(ConfigMapper(KEY_CHANNEL_COUNT, C2_PARAMKEY_CHANNEL_COUNT,       "value")
+        .limitTo(D::AUDIO)); // read back to both formats
+    add(ConfigMapper(KEY_CHANNEL_COUNT, C2_PARAMKEY_CODED_CHANNEL_COUNT, "value")
+        .limitTo(D::AUDIO & D::CODED));
+
+    add(ConfigMapper(KEY_SAMPLE_RATE,   C2_PARAMKEY_SAMPLE_RATE,        "value")
+        .limitTo(D::AUDIO)); // read back to both port formats
+    add(ConfigMapper(KEY_SAMPLE_RATE,   C2_PARAMKEY_CODED_SAMPLE_RATE,  "value")
+        .limitTo(D::AUDIO & D::CODED));
+
+    add(ConfigMapper(KEY_PCM_ENCODING,  C2_PARAMKEY_PCM_ENCODING,       "value")
+        .limitTo(D::AUDIO)
+        .withMappers([](C2Value v) -> C2Value {
+            int32_t value;
+            C2Config::pcm_encoding_t to;
+            if (v.get(&value) && C2Mapper::map(value, &to)) {
+                return to;
+            }
+            return C2Value();
+        }, [](C2Value v) -> C2Value {
+            C2Config::pcm_encoding_t value;
+            int32_t to;
+            using C2ValueType=typename _c2_reduce_enum_to_underlying_type<decltype(value)>::type;
+            if (v.get((C2ValueType*)&value) && C2Mapper::map(value, &to)) {
+                return to;
+            }
+            return C2Value();
+        }));
+
+    add(ConfigMapper(KEY_IS_ADTS, C2_PARAMKEY_AAC_PACKAGING, "value")
+        .limitTo(D::AUDIO & D::CODED)
+        .withMappers([](C2Value v) -> C2Value {
+            int32_t value;
+            if (v.get(&value) && value) {
+                return C2Config::AAC_PACKAGING_ADTS;
+            }
+            return C2Value();
+        }, [](C2Value v) -> C2Value {
+            uint32_t value;
+            if (v.get(&value) && value == C2Config::AAC_PACKAGING_ADTS) {
+                return (int32_t)1;
+            }
+            return C2Value();
+        }));
+
+    std::shared_ptr<C2Mapper::ProfileLevelMapper> mapper =
+        C2Mapper::GetProfileLevelMapper(mCodingMediaType);
+
+    add(ConfigMapper(KEY_PROFILE, C2_PARAMKEY_PROFILE_LEVEL, "profile")
+        .limitTo(D::CODED)
+        .withMappers([mapper](C2Value v) -> C2Value {
+            C2Config::profile_t c2 = PROFILE_UNUSED;
+            int32_t sdk;
+            if (mapper && v.get(&sdk) && mapper->mapProfile(sdk, &c2)) {
+                return c2;
+            }
+            return PROFILE_UNUSED;
+        }, [mapper](C2Value v) -> C2Value {
+            C2Config::profile_t c2;
+            int32_t sdk;
+            using C2ValueType=typename _c2_reduce_enum_to_underlying_type<decltype(c2)>::type;
+            if (mapper && v.get((C2ValueType*)&c2) && mapper->mapProfile(c2, &sdk)) {
+                return sdk;
+            }
+            return C2Value();
+        }));
+
+    add(ConfigMapper(KEY_LEVEL, C2_PARAMKEY_PROFILE_LEVEL, "level")
+        .limitTo(D::CODED)
+        .withMappers([mapper](C2Value v) -> C2Value {
+            C2Config::level_t c2 = LEVEL_UNUSED;
+            int32_t sdk;
+            if (mapper && v.get(&sdk) && mapper->mapLevel(sdk, &c2)) {
+                return c2;
+            }
+            return LEVEL_UNUSED;
+        }, [mapper](C2Value v) -> C2Value {
+            C2Config::level_t c2;
+            int32_t sdk;
+            using C2ValueType=typename _c2_reduce_enum_to_underlying_type<decltype(c2)>::type;
+            if (mapper && v.get((C2ValueType*)&c2) && mapper->mapLevel(c2, &sdk)) {
+                return sdk;
+            }
+            return C2Value();
+        }));
+
+    // convert to dBFS and add default
+    add(ConfigMapper(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, C2_PARAMKEY_DRC_TARGET_REFERENCE_LEVEL, "value")
+        .limitTo(D::AUDIO & D::DECODER & D::CONFIG)
+        .withMapper([](C2Value v) -> C2Value {
+            int32_t value;
+            if (!v.get(&value) || value < 0) {
+                value = property_get_int32(PROP_DRC_OVERRIDE_REF_LEVEL, DRC_DEFAULT_MOBILE_REF_LEVEL);
+            }
+            return float(-0.25 * c2_min(value, 127));
+        }));
+
+    // convert to 0-1 (%) and add default
+    add(ConfigMapper(KEY_AAC_DRC_ATTENUATION_FACTOR, C2_PARAMKEY_DRC_ATTENUATION_FACTOR, "value")
+        .limitTo(D::AUDIO & D::DECODER & D::CONFIG)
+        .withMapper([](C2Value v) -> C2Value {
+            int32_t value;
+            if (!v.get(&value) || value < 0) {
+                value = property_get_int32(PROP_DRC_OVERRIDE_CUT, DRC_DEFAULT_MOBILE_DRC_CUT);
+            }
+            return float(c2_min(value, 127) / 127.);
+        }));
+
+    // convert to 0-1 (%) and add default
+    add(ConfigMapper(KEY_AAC_DRC_BOOST_FACTOR, C2_PARAMKEY_DRC_BOOST_FACTOR, "value")
+        .limitTo(D::AUDIO & D::DECODER & D::CONFIG)
+        .withMapper([](C2Value v) -> C2Value {
+            int32_t value;
+            if (!v.get(&value) || value < 0) {
+                value = property_get_int32(PROP_DRC_OVERRIDE_BOOST, DRC_DEFAULT_MOBILE_DRC_BOOST);
+            }
+            return float(c2_min(value, 127) / 127.);
+        }));
+
+    // convert to compression type and add default
+    add(ConfigMapper(KEY_AAC_DRC_HEAVY_COMPRESSION, C2_PARAMKEY_DRC_COMPRESSION_MODE, "value")
+        .limitTo(D::AUDIO & D::DECODER & D::CONFIG)
+        .withMapper([](C2Value v) -> C2Value {
+            int32_t value;
+            if (!v.get(&value) || value < 0) {
+                value = property_get_int32(PROP_DRC_OVERRIDE_HEAVY, DRC_DEFAULT_MOBILE_DRC_HEAVY);
+            }
+            return value == 1 ? C2Config::DRC_COMPRESSION_HEAVY : C2Config::DRC_COMPRESSION_LIGHT;
+        }));
+
+    // convert to dBFS and add default
+    add(ConfigMapper(KEY_AAC_ENCODED_TARGET_LEVEL, C2_PARAMKEY_DRC_ENCODED_TARGET_LEVEL, "value")
+        .limitTo(D::AUDIO & D::DECODER & D::CONFIG)
+        .withMapper([](C2Value v) -> C2Value {
+            int32_t value;
+            if (!v.get(&value) || value < 0) {
+                value = property_get_int32(PROP_DRC_OVERRIDE_ENC_LEVEL, DRC_DEFAULT_MOBILE_ENC_LEVEL);
+            }
+            return float(-0.25 * c2_min(value, 127));
+        }));
+
+    // convert to effect type (these map to SDK values) and add default
+    add(ConfigMapper(KEY_AAC_DRC_EFFECT_TYPE, C2_PARAMKEY_DRC_EFFECT_TYPE, "value")
+        .limitTo(D::AUDIO & D::DECODER & D::CONFIG)
+        .withMapper([](C2Value v) -> C2Value {
+            int32_t value;
+            if (!v.get(&value) || value < -1 || value > 8) {
+                value = property_get_int32(PROP_DRC_OVERRIDE_EFFECT, DRC_DEFAULT_MOBILE_DRC_EFFECT);
+                // ensure value is within range
+                if (value < -1 || value > 8) {
+                    value = DRC_DEFAULT_MOBILE_DRC_EFFECT;
+                }
+            }
+            return value;
+        }));
+
+    add(ConfigMapper(KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT, C2_PARAMKEY_MAX_CHANNEL_COUNT, "value")
+        .limitTo(D::AUDIO));
+
+    add(ConfigMapper(KEY_AAC_SBR_MODE, C2_PARAMKEY_AAC_SBR_MODE, "value")
+        .limitTo(D::AUDIO & D::ENCODER & D::CONFIG)
+        .withMapper([](C2Value v) -> C2Value {
+            int32_t value;
+            if (!v.get(&value) || value < 0) {
+                return C2Config::AAC_SBR_AUTO;
+            }
+            switch (value) {
+                case 0: return C2Config::AAC_SBR_OFF;
+                case 1: return C2Config::AAC_SBR_SINGLE_RATE;
+                case 2: return C2Config::AAC_SBR_DUAL_RATE;
+                default: return C2Config::AAC_SBR_AUTO + 1; // invalid value
+            }
+        }));
+
+    add(ConfigMapper(KEY_QUALITY, C2_PARAMKEY_QUALITY, "value")
+        .limitTo(D::ENCODER & (D::CONFIG | D::PARAM)));
+    add(ConfigMapper(KEY_FLAC_COMPRESSION_LEVEL, C2_PARAMKEY_COMPLEXITY, "value")
+        .limitTo(D::AUDIO & D::ENCODER));
+    add(ConfigMapper("complexity", C2_PARAMKEY_COMPLEXITY, "value")
+        .limitTo(D::ENCODER & (D::CONFIG | D::PARAM)));
+
+    add(ConfigMapper(KEY_GRID_COLUMNS, C2_PARAMKEY_TILE_LAYOUT, "columns")
+        .limitTo(D::IMAGE));
+    add(ConfigMapper(KEY_GRID_ROWS, C2_PARAMKEY_TILE_LAYOUT, "rows")
+        .limitTo(D::IMAGE));
+    add(ConfigMapper(KEY_TILE_WIDTH, C2_PARAMKEY_TILE_LAYOUT, "tile.width")
+        .limitTo(D::IMAGE));
+    add(ConfigMapper(KEY_TILE_HEIGHT, C2_PARAMKEY_TILE_LAYOUT, "tile.height")
+        .limitTo(D::IMAGE));
+
+    add(ConfigMapper(KEY_LATENCY, C2_PARAMKEY_PIPELINE_DELAY_REQUEST, "value")
+        .limitTo(D::VIDEO & D::ENCODER));
+
+    add(ConfigMapper(C2_PARAMKEY_INPUT_TIME_STRETCH, C2_PARAMKEY_INPUT_TIME_STRETCH, "value"));
+
+    /* still to do
+    constexpr char KEY_PUSH_BLANK_BUFFERS_ON_STOP[] = "push-blank-buffers-on-shutdown";
+
+       not yet used by MediaCodec, but defined as MediaFormat
+    KEY_AUDIO_SESSION_ID // we use "audio-hw-sync"
+    KEY_OUTPUT_REORDER_DEPTH
+    */
+}
+
+status_t CCodecConfig::initialize(
+        const std::shared_ptr<Codec2Client> &client,
+        const std::shared_ptr<Codec2Client::Component> &component) {
+    C2ComponentDomainSetting domain(C2Component::DOMAIN_OTHER);
+    C2ComponentKindSetting kind(C2Component::KIND_OTHER);
+
+    std::vector<std::unique_ptr<C2Param>> queried;
+    c2_status_t c2err = component->query({ &domain, &kind }, {}, C2_DONT_BLOCK, &queried);
+    if (c2err != C2_OK) {
+        ALOGD("Query domain & kind failed => %s", asString(c2err));
+        // TEMP: determine kind from component name
+        if (kind.value == C2Component::KIND_OTHER) {
+            if (component->getName().find("encoder") != std::string::npos) {
+                kind.value = C2Component::KIND_ENCODER;
+            } else if (component->getName().find("decoder") != std::string::npos) {
+                kind.value = C2Component::KIND_DECODER;
+            }
+        }
+
+        // TEMP: determine domain from media type (port (preferred) or stream #0)
+        if (domain.value == C2Component::DOMAIN_OTHER) {
+            AString mediaType = QueryMediaType(true /* input */, component);
+            if (mediaType.startsWith("audio/")) {
+                domain.value = C2Component::DOMAIN_AUDIO;
+            } else if (mediaType.startsWith("video/")) {
+                domain.value = C2Component::DOMAIN_VIDEO;
+            } else if (mediaType.startsWith("image/")) {
+                domain.value = C2Component::DOMAIN_IMAGE;
+            }
+        }
+    }
+
+    mDomain = (domain.value == C2Component::DOMAIN_VIDEO ? Domain::IS_VIDEO :
+               domain.value == C2Component::DOMAIN_IMAGE ? Domain::IS_IMAGE :
+               domain.value == C2Component::DOMAIN_AUDIO ? Domain::IS_AUDIO : Domain::OTHER_DOMAIN)
+            | (kind.value == C2Component::KIND_DECODER ? Domain::IS_DECODER :
+               kind.value == C2Component::KIND_ENCODER ? Domain::IS_ENCODER : Domain::OTHER_KIND);
+
+    mInputDomain = Domain(((mDomain & IS_DECODER) ? IS_CODED : IS_RAW) | IS_INPUT);
+    mOutputDomain = Domain(((mDomain & IS_ENCODER) ? IS_CODED : IS_RAW) | IS_OUTPUT);
+
+    ALOGV("domain is %#x (%u %u)", mDomain, domain.value, kind.value);
+
+    std::vector<C2Param::Index> paramIndices;
+    switch (kind.value) {
+    case C2Component::KIND_DECODER:
+        mCodingMediaType = QueryMediaType(true /* input */, component).c_str();
+        break;
+    case C2Component::KIND_ENCODER:
+        mCodingMediaType = QueryMediaType(false /* input */, component).c_str();
+        break;
+    default:
+        mCodingMediaType = "";
+    }
+
+    c2err = component->querySupportedParams(&mParamDescs);
+    if (c2err != C2_OK) {
+        ALOGD("Query supported params failed after returning %zu values => %s",
+                mParamDescs.size(), asString(c2err));
+        return UNKNOWN_ERROR;
+    }
+    for (const std::shared_ptr<C2ParamDescriptor> &desc : mParamDescs) {
+        mSupportedIndices.emplace(desc->index());
+    }
+
+    mReflector = client->getParamReflector();
+    if (mReflector == nullptr) {
+        ALOGE("Failed to get param reflector");
+        return UNKNOWN_ERROR;
+    }
+
+    // enumerate all fields
+    mParamUpdater = std::make_shared<ReflectedParamUpdater>();
+    mParamUpdater->clear();
+    mParamUpdater->supportWholeParam(
+            C2_PARAMKEY_TEMPORAL_LAYERING, C2StreamTemporalLayeringTuning::CORE_INDEX);
+    mParamUpdater->addParamDesc(mReflector, mParamDescs);
+
+    // TEMP: add some standard fields even if not reflected
+    if (kind.value == C2Component::KIND_ENCODER) {
+        mParamUpdater->addStandardParam<C2StreamInitDataInfo::output>(C2_PARAMKEY_INIT_DATA);
+    }
+    if (domain.value == C2Component::DOMAIN_IMAGE || domain.value == C2Component::DOMAIN_VIDEO) {
+        if (kind.value != C2Component::KIND_ENCODER) {
+            addLocalParam<C2StreamPictureSizeInfo::output>(C2_PARAMKEY_PICTURE_SIZE);
+            addLocalParam<C2StreamCropRectInfo::output>(C2_PARAMKEY_CROP_RECT);
+            addLocalParam(
+                    new C2StreamPixelAspectRatioInfo::output(0u, 1u, 1u),
+                    C2_PARAMKEY_PIXEL_ASPECT_RATIO);
+            addLocalParam(new C2StreamRotationInfo::output(0u, 0), C2_PARAMKEY_ROTATION);
+            addLocalParam(new C2StreamColorAspectsInfo::output(0u), C2_PARAMKEY_COLOR_ASPECTS);
+            addLocalParam<C2StreamDataSpaceInfo::output>(C2_PARAMKEY_DATA_SPACE);
+            addLocalParam<C2StreamHdrStaticInfo::output>(C2_PARAMKEY_HDR_STATIC_INFO);
+            addLocalParam(new C2StreamSurfaceScalingInfo::output(0u, VIDEO_SCALING_MODE_SCALE_TO_FIT),
+                          C2_PARAMKEY_SURFACE_SCALING_MODE);
+        } else {
+            addLocalParam(new C2StreamColorAspectsInfo::input(0u), C2_PARAMKEY_COLOR_ASPECTS);
+        }
+    }
+
+    initializeStandardParams();
+
+    // subscribe to all supported standard (exposed) params
+    // TODO: limit this to params that are actually in the domain
+    std::vector<std::string> formatKeys = mStandardParams->getPathsForDomain(Domain(1 << 30));
+    std::vector<C2Param::Index> indices;
+    mParamUpdater->getParamIndicesForKeys(formatKeys, &indices);
+    mSubscribedIndices.insert(indices.begin(), indices.end());
+
+    // also subscribe to some non-SDK standard parameters
+    // for number of input/output buffers
+    mSubscribedIndices.emplace(C2PortSuggestedBufferCountTuning::input::PARAM_TYPE);
+    mSubscribedIndices.emplace(C2PortSuggestedBufferCountTuning::output::PARAM_TYPE);
+    mSubscribedIndices.emplace(C2ActualPipelineDelayTuning::PARAM_TYPE);
+    mSubscribedIndices.emplace(C2PortActualDelayTuning::input::PARAM_TYPE);
+    mSubscribedIndices.emplace(C2PortActualDelayTuning::output::PARAM_TYPE);
+    // for output buffer array allocation
+    mSubscribedIndices.emplace(C2StreamMaxBufferSizeInfo::output::PARAM_TYPE);
+    // init data (CSD)
+    mSubscribedIndices.emplace(C2StreamInitDataInfo::output::PARAM_TYPE);
+
+    return OK;
+}
+
+status_t CCodecConfig::subscribeToConfigUpdate(
+        const std::shared_ptr<Codec2Client::Component> &component,
+        const std::vector<C2Param::Index> &indices,
+        c2_blocking_t blocking) {
+    mSubscribedIndices.insert(indices.begin(), indices.end());
+    // TODO: enable this when components no longer crash on this config
+    if (mSubscribedIndices.size() != mSubscribedIndicesSize && false) {
+        std::vector<uint32_t> indices;
+        for (C2Param::Index ix : mSubscribedIndices) {
+            indices.push_back(ix);
+        }
+        std::unique_ptr<C2SubscribedParamIndicesTuning> subscribeTuning =
+            C2SubscribedParamIndicesTuning::AllocUnique(indices);
+        std::vector<std::unique_ptr<C2SettingResult>> results;
+        c2_status_t c2Err = component->config({ subscribeTuning.get() }, blocking, &results);
+        if (c2Err != C2_OK && c2Err != C2_BAD_INDEX) {
+            ALOGD("Failed to subscribe to parameters => %s", asString(c2Err));
+            // TODO: error
+        }
+        ALOGV("Subscribed to %zu params", mSubscribedIndices.size());
+        mSubscribedIndicesSize = mSubscribedIndices.size();
+    }
+    return OK;
+}
+
+status_t CCodecConfig::queryConfiguration(
+        const std::shared_ptr<Codec2Client::Component> &component) {
+    // query all subscribed parameters
+    std::vector<C2Param::Index> indices(mSubscribedIndices.begin(), mSubscribedIndices.end());
+    std::vector<std::unique_ptr<C2Param>> queried;
+    c2_status_t c2Err = component->query({}, indices, C2_MAY_BLOCK, &queried);
+    if (c2Err != OK) {
+        ALOGI("query failed after returning %zu values (%s)", queried.size(), asString(c2Err));
+        // TODO: error
+    }
+
+    updateConfiguration(queried, ALL);
+    return OK;
+}
+
+bool CCodecConfig::updateConfiguration(
+        std::vector<std::unique_ptr<C2Param>> &configUpdate, Domain domain) {
+    ALOGV("updating configuration with %zu params", configUpdate.size());
+    bool changed = false;
+    for (std::unique_ptr<C2Param> &p : configUpdate) {
+        if (p && *p) {
+            auto insertion = mCurrentConfig.emplace(p->index(), nullptr);
+            if (insertion.second || *insertion.first->second != *p) {
+                if (mSupportedIndices.count(p->index()) || mLocalParams.count(p->index())) {
+                    // only track changes in supported (reflected or local) indices
+                    changed = true;
+                } else {
+                    ALOGV("an unlisted config was %s: %#x",
+                            insertion.second ? "added" : "updated", p->index());
+                }
+            }
+            insertion.first->second = std::move(p);
+        }
+    }
+
+    ALOGV("updated configuration has %zu params (%s)", mCurrentConfig.size(),
+            changed ? "CHANGED" : "no change");
+    if (changed) {
+        return updateFormats(domain);
+    }
+    return false;
+}
+
+bool CCodecConfig::updateFormats(Domain domain) {
+    // get addresses of params in the current config
+    std::vector<C2Param*> paramPointers;
+    for (const auto &it : mCurrentConfig) {
+        paramPointers.push_back(it.second.get());
+    }
+
+    ReflectedParamUpdater::Dict reflected = mParamUpdater->getParams(paramPointers);
+    ALOGD("c2 config is %s", reflected.debugString().c_str());
+
+    bool changed = false;
+    if (domain & mInputDomain) {
+        sp<AMessage> oldFormat = mInputFormat;
+        mInputFormat = mInputFormat->dup(); // trigger format changed
+        mInputFormat->extend(getSdkFormatForDomain(reflected, mInputDomain));
+        if (mInputFormat->countEntries() != oldFormat->countEntries()
+                || mInputFormat->changesFrom(oldFormat)->countEntries() > 0) {
+            changed = true;
+        } else {
+            mInputFormat = oldFormat; // no change
+        }
+    }
+    if (domain & mOutputDomain) {
+        sp<AMessage> oldFormat = mOutputFormat;
+        mOutputFormat = mOutputFormat->dup(); // trigger output format changed
+        mOutputFormat->extend(getSdkFormatForDomain(reflected, mOutputDomain));
+        if (mOutputFormat->countEntries() != oldFormat->countEntries()
+                || mOutputFormat->changesFrom(oldFormat)->countEntries() > 0) {
+            changed = true;
+        } else {
+            mOutputFormat = oldFormat; // no change
+        }
+    }
+    ALOGV_IF(changed, "format(s) changed");
+    return changed;
+}
+
+sp<AMessage> CCodecConfig::getSdkFormatForDomain(
+        const ReflectedParamUpdater::Dict &reflected, Domain portDomain) const {
+    sp<AMessage> msg = new AMessage;
+    for (const std::pair<std::string, std::vector<ConfigMapper>> &el : mStandardParams->getKeys()) {
+        for (const ConfigMapper &cm : el.second) {
+            if ((cm.domain() & portDomain) == 0 // input-output-coded-raw
+                || (cm.domain() & mDomain) != mDomain // component domain + kind (these must match)
+                || (cm.domain() & IS_READ) == 0) {
+                continue;
+            }
+            auto it = reflected.find(cm.path());
+            if (it == reflected.end()) {
+                continue;
+            }
+            C2Value c2Value;
+            sp<ABuffer> bufValue;
+            AString strValue;
+            AMessage::ItemData item;
+            if (it->second.find(&c2Value)) {
+                item = cm.mapToMessage(c2Value);
+            } else if (it->second.find(&bufValue)) {
+                item.set(bufValue);
+            } else if (it->second.find(&strValue)) {
+                item.set(strValue);
+            } else {
+                ALOGD("unexpected untyped query value for key: %s", cm.path().c_str());
+                continue;
+            }
+            msg->setItem(el.first.c_str(), item);
+        }
+    }
+
+    { // convert from Codec 2.0 rect to MediaFormat rect and add crop rect if not present
+        int32_t left, top, width, height;
+        if (msg->findInt32("crop-left", &left) && msg->findInt32("crop-width", &width)
+                && msg->findInt32("crop-top", &top) && msg->findInt32("crop-height", &height)
+                && left >= 0 && width >=0 && width <= INT32_MAX - left
+                && top >= 0 && height >=0 && height <= INT32_MAX - top) {
+            msg->removeEntryAt(msg->findEntryByName("crop-left"));
+            msg->removeEntryAt(msg->findEntryByName("crop-top"));
+            msg->removeEntryAt(msg->findEntryByName("crop-width"));
+            msg->removeEntryAt(msg->findEntryByName("crop-height"));
+            msg->setRect("crop", left, top, left + width - 1, top + height - 1);
+        } else if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) {
+            msg->setRect("crop", 0, 0, width - 1, height - 1);
+        }
+    }
+
+    { // convert temporal layering to schema
+        sp<ABuffer> tmp;
+        if (msg->findBuffer(C2_PARAMKEY_TEMPORAL_LAYERING, &tmp) && tmp != nullptr) {
+            C2StreamTemporalLayeringTuning *layering =
+                C2StreamTemporalLayeringTuning::From(C2Param::From(tmp->data(), tmp->size()));
+            if (layering && layering->m.layerCount > 0
+                    && layering->m.bLayerCount < layering->m.layerCount) {
+                // check if this is webrtc compatible
+                AString mime;
+                if (msg->findString(KEY_MIME, &mime) &&
+                        mime.equalsIgnoreCase(MIMETYPE_VIDEO_VP8) &&
+                        layering->m.bLayerCount == 0 &&
+                        (layering->m.layerCount == 1
+                                || (layering->m.layerCount == 2
+                                        && layering->flexCount() >= 1
+                                        && layering->m.bitrateRatios[0] == .6f)
+                                || (layering->m.layerCount == 3
+                                        && layering->flexCount() >= 2
+                                        && layering->m.bitrateRatios[0] == .4f
+                                        && layering->m.bitrateRatios[1] == .6f)
+                                || (layering->m.layerCount == 4
+                                        && layering->flexCount() >= 3
+                                        && layering->m.bitrateRatios[0] == .25f
+                                        && layering->m.bitrateRatios[1] == .4f
+                                        && layering->m.bitrateRatios[2] == .6f))) {
+                    msg->setString(KEY_TEMPORAL_LAYERING, AStringPrintf(
+                            "webrtc.vp8.%u-layer", layering->m.layerCount));
+                } else if (layering->m.bLayerCount) {
+                    msg->setString(KEY_TEMPORAL_LAYERING, AStringPrintf(
+                            "android.generic.%u+%u",
+                            layering->m.layerCount - layering->m.bLayerCount,
+                            layering->m.bLayerCount));
+                } else if (layering->m.bLayerCount) {
+                    msg->setString(KEY_TEMPORAL_LAYERING, AStringPrintf(
+                            "android.generic.%u", layering->m.layerCount));
+                }
+            }
+            msg->removeEntryAt(msg->findEntryByName(C2_PARAMKEY_TEMPORAL_LAYERING));
+        }
+    }
+
+    { // convert color info
+        C2Color::primaries_t primaries;
+        C2Color::matrix_t matrix;
+        if (msg->findInt32("color-primaries", (int32_t*)&primaries)
+                && msg->findInt32("color-matrix", (int32_t*)&matrix)) {
+            int32_t standard;
+
+            if (C2Mapper::map(primaries, matrix, &standard)) {
+                msg->setInt32(KEY_COLOR_STANDARD, standard);
+            }
+
+            msg->removeEntryAt(msg->findEntryByName("color-primaries"));
+            msg->removeEntryAt(msg->findEntryByName("color-matrix"));
+        }
+
+
+        // calculate dataspace for raw graphic buffers if not specified by component, or if
+        // using surface with unspecified aspects (as those must be defaulted which may change
+        // the dataspace)
+        if ((portDomain & IS_RAW) && (mDomain & (IS_IMAGE | IS_VIDEO))) {
+            android_dataspace dataspace;
+            ColorAspects aspects = {
+                ColorAspects::RangeUnspecified, ColorAspects::PrimariesUnspecified,
+                ColorAspects::TransferUnspecified, ColorAspects::MatrixUnspecified
+            };
+            ColorUtils::getColorAspectsFromFormat(msg, aspects);
+            ColorAspects origAspects = aspects;
+            if (mUsingSurface) {
+                // get image size (default to HD)
+                int32_t width = 1280;
+                int32_t height = 720;
+                int32_t left, top, right, bottom;
+                if (msg->findRect("crop", &left, &top, &right, &bottom)) {
+                    width = right - left + 1;
+                    height = bottom - top + 1;
+                } else {
+                    (void)msg->findInt32(KEY_WIDTH, &width);
+                    (void)msg->findInt32(KEY_HEIGHT, &height);
+                }
+                ColorUtils::setDefaultCodecColorAspectsIfNeeded(aspects, width, height);
+                ColorUtils::setColorAspectsIntoFormat(aspects, msg);
+            }
+
+            if (!msg->findInt32("android._dataspace", (int32_t*)&dataspace)
+                    || aspects.mRange != origAspects.mRange
+                    || aspects.mPrimaries != origAspects.mPrimaries
+                    || aspects.mTransfer != origAspects.mTransfer
+                    || aspects.mMatrixCoeffs != origAspects.mMatrixCoeffs) {
+                dataspace = ColorUtils::getDataSpaceForColorAspects(aspects, true /* mayExpand */);
+                msg->setInt32("android._dataspace", dataspace);
+            }
+        }
+
+        // HDR static info
+
+        C2HdrStaticMetadataStruct hdr;
+        if (msg->findFloat("smpte2086.red.x", &hdr.mastering.red.x)
+                && msg->findFloat("smpte2086.red.y", &hdr.mastering.red.y)
+                && msg->findFloat("smpte2086.green.x", &hdr.mastering.green.x)
+                && msg->findFloat("smpte2086.green.y", &hdr.mastering.green.y)
+                && msg->findFloat("smpte2086.blue.x", &hdr.mastering.blue.x)
+                && msg->findFloat("smpte2086.blue.y", &hdr.mastering.blue.y)
+                && msg->findFloat("smpte2086.white.x", &hdr.mastering.white.x)
+                && msg->findFloat("smpte2086.white.y", &hdr.mastering.white.y)
+                && msg->findFloat("smpte2086.max-luminance", &hdr.mastering.maxLuminance)
+                && msg->findFloat("smpte2086.min-luminance", &hdr.mastering.minLuminance)
+                && msg->findFloat("cta861.max-cll", &hdr.maxCll)
+                && msg->findFloat("cta861.max-fall", &hdr.maxFall)) {
+            if (hdr.mastering.red.x >= 0                && hdr.mastering.red.x <= 1
+                    && hdr.mastering.red.y >= 0         && hdr.mastering.red.y <= 1
+                    && hdr.mastering.green.x >= 0       && hdr.mastering.green.x <= 1
+                    && hdr.mastering.green.y >= 0       && hdr.mastering.green.y <= 1
+                    && hdr.mastering.blue.x >= 0        && hdr.mastering.blue.x <= 1
+                    && hdr.mastering.blue.y >= 0        && hdr.mastering.blue.y <= 1
+                    && hdr.mastering.white.x >= 0       && hdr.mastering.white.x <= 1
+                    && hdr.mastering.white.y >= 0       && hdr.mastering.white.y <= 1
+                    && hdr.mastering.maxLuminance >= 0  && hdr.mastering.maxLuminance <= 65535
+                    && hdr.mastering.minLuminance >= 0  && hdr.mastering.minLuminance <= 6.5535
+                    && hdr.maxCll >= 0                  && hdr.maxCll <= 65535
+                    && hdr.maxFall >= 0                 && hdr.maxFall <= 65535) {
+                HDRStaticInfo meta;
+                meta.mID = meta.kType1;
+                meta.sType1.mR.x = hdr.mastering.red.x / 0.00002 + 0.5;
+                meta.sType1.mR.y = hdr.mastering.red.y / 0.00002 + 0.5;
+                meta.sType1.mG.x = hdr.mastering.green.x / 0.00002 + 0.5;
+                meta.sType1.mG.y = hdr.mastering.green.y / 0.00002 + 0.5;
+                meta.sType1.mB.x = hdr.mastering.blue.x / 0.00002 + 0.5;
+                meta.sType1.mB.y = hdr.mastering.blue.y / 0.00002 + 0.5;
+                meta.sType1.mW.x = hdr.mastering.white.x / 0.00002 + 0.5;
+                meta.sType1.mW.y = hdr.mastering.white.y / 0.00002 + 0.5;
+                meta.sType1.mMaxDisplayLuminance = hdr.mastering.maxLuminance + 0.5;
+                meta.sType1.mMinDisplayLuminance = hdr.mastering.minLuminance / 0.0001 + 0.5;
+                meta.sType1.mMaxContentLightLevel = hdr.maxCll + 0.5;
+                meta.sType1.mMaxFrameAverageLightLevel = hdr.maxFall + 0.5;
+                msg->removeEntryAt(msg->findEntryByName("smpte2086.red.x"));
+                msg->removeEntryAt(msg->findEntryByName("smpte2086.red.y"));
+                msg->removeEntryAt(msg->findEntryByName("smpte2086.green.x"));
+                msg->removeEntryAt(msg->findEntryByName("smpte2086.green.y"));
+                msg->removeEntryAt(msg->findEntryByName("smpte2086.blue.x"));
+                msg->removeEntryAt(msg->findEntryByName("smpte2086.blue.y"));
+                msg->removeEntryAt(msg->findEntryByName("smpte2086.white.x"));
+                msg->removeEntryAt(msg->findEntryByName("smpte2086.white.y"));
+                msg->removeEntryAt(msg->findEntryByName("smpte2086.max-luminance"));
+                msg->removeEntryAt(msg->findEntryByName("smpte2086.min-luminance"));
+                msg->removeEntryAt(msg->findEntryByName("cta861.max-cll"));
+                msg->removeEntryAt(msg->findEntryByName("cta861.max-fall"));
+                msg->setBuffer(KEY_HDR_STATIC_INFO, ABuffer::CreateAsCopy(&meta, sizeof(meta)));
+            } else {
+                ALOGD("found invalid HDR static metadata %s", msg->debugString(8).c_str());
+            }
+        }
+    }
+
+    ALOGV("converted to SDK values as %s", msg->debugString().c_str());
+    return msg;
+}
+
+/// converts an AMessage value to a ParamUpdater value
+static void convert(const AMessage::ItemData &from, ReflectedParamUpdater::Value *to) {
+    int32_t int32Value;
+    int64_t int64Value;
+    sp<ABuffer> bufValue;
+    AString strValue;
+    float floatValue;
+    double doubleValue;
+
+    if (from.find(&int32Value)) {
+        to->set(int32Value);
+    } else if (from.find(&int64Value)) {
+        to->set(int64Value);
+    } else if (from.find(&bufValue)) {
+        to->set(bufValue);
+    } else if (from.find(&strValue)) {
+        to->set(strValue);
+    } else if (from.find(&floatValue)) {
+        to->set(C2Value(floatValue));
+    } else if (from.find(&doubleValue)) {
+        // convert double to float
+        to->set(C2Value((float)doubleValue));
+    }
+    // ignore all other AMessage types
+}
+
+/// relaxes Codec 2.0 specific value types to SDK types (mainly removes signedness and counterness
+/// from 32/64-bit values.)
+static void relaxValues(ReflectedParamUpdater::Value &item) {
+    C2Value c2Value;
+    int32_t int32Value;
+    int64_t int64Value;
+    (void)item.find(&c2Value);
+    if (c2Value.get(&int32Value) || c2Value.get((uint32_t*)&int32Value)
+            || c2Value.get((c2_cntr32_t*)&int32Value)) {
+        item.set(int32Value);
+    } else if (c2Value.get(&int64Value)
+            || c2Value.get((uint64_t*)&int64Value)
+            || c2Value.get((c2_cntr64_t*)&int64Value)) {
+        item.set(int64Value);
+    }
+}
+
+ReflectedParamUpdater::Dict CCodecConfig::getReflectedFormat(
+        const sp<AMessage> &params_, Domain configDomain) const {
+    // create a modifiable copy of params
+    sp<AMessage> params = params_->dup();
+    ALOGV("filtering with config domain %x", configDomain);
+
+    // convert some macro parameters to Codec 2.0 specific expressions
+
+    { // make i-frame-interval frame based
+        float iFrameInterval;
+        if (params->findAsFloat(KEY_I_FRAME_INTERVAL, &iFrameInterval)) {
+            float frameRate;
+            if (params->findAsFloat(KEY_FRAME_RATE, &frameRate)) {
+                params->setInt32("i-frame-period",
+                        (frameRate <= 0 || iFrameInterval < 0)
+                                 ? -1 /* no sync frames */
+                                 : (int32_t)c2_min(iFrameInterval * frameRate + 0.5,
+                                                   (float)INT32_MAX));
+            }
+        }
+    }
+
+    if (mDomain == (IS_VIDEO | IS_ENCODER)) {
+        // convert capture-rate into input-time-stretch
+        float frameRate, captureRate;
+        if (params->findAsFloat(KEY_FRAME_RATE, &frameRate)) {
+            if (!params->findAsFloat("time-lapse-fps", &captureRate)
+                    && !params->findAsFloat(KEY_CAPTURE_RATE, &captureRate)) {
+                captureRate = frameRate;
+            }
+            if (captureRate > 0 && frameRate > 0) {
+                params->setFloat(C2_PARAMKEY_INPUT_TIME_STRETCH, captureRate / frameRate);
+            }
+        }
+    }
+
+    {   // reflect temporal layering into a binary blob
+        AString schema;
+        if (params->findString(KEY_TEMPORAL_LAYERING, &schema)) {
+            unsigned int numLayers = 0;
+            unsigned int numBLayers = 0;
+            int tags;
+            char dummy;
+            std::unique_ptr<C2StreamTemporalLayeringTuning::output> layering;
+            if (sscanf(schema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1
+                && numLayers > 0) {
+                switch (numLayers) {
+                    case 1:
+                        layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
+                                {}, 0u, 1u, 0u);
+                        break;
+                    case 2:
+                        layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
+                                { .6f }, 0u, 2u, 0u);
+                        break;
+                    case 3:
+                        layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
+                                { .4f, .6f }, 0u, 3u, 0u);
+                        break;
+                    default:
+                        layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
+                                { .25f, .4f, .6f }, 0u, 4u, 0u);
+                        break;
+                }
+            } else if ((tags = sscanf(schema.c_str(), "android.generic.%u%c%u%c",
+                        &numLayers, &dummy, &numBLayers, &dummy))
+                && (tags == 1 || (tags == 3 && dummy == '+'))
+                && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
+                layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
+                        {}, 0u, numLayers + numBLayers, numBLayers);
+            } else {
+                ALOGD("Ignoring unsupported ts-schema [%s]", schema.c_str());
+            }
+            if (layering) {
+                params->setBuffer(C2_PARAMKEY_TEMPORAL_LAYERING,
+                                  ABuffer::CreateAsCopy(layering.get(), layering->size()));
+            }
+        }
+    }
+
+    { // convert from MediaFormat rect to Codec 2.0 rect
+        int32_t offset;
+        int32_t end;
+        AMessage::ItemData item;
+        if (params->findInt32("crop-left", &offset) && params->findInt32("crop-right", &end)
+                && offset >= 0 && end >= offset - 1) {
+            size_t ix = params->findEntryByName("crop-right");
+            params->setEntryNameAt(ix, "crop-width");
+            item.set(end - offset + 1);
+            params->setEntryAt(ix, item);
+        }
+        if (params->findInt32("crop-top", &offset) && params->findInt32("crop-bottom", &end)
+                && offset >= 0 && end >= offset - 1) {
+            size_t ix = params->findEntryByName("crop-bottom");
+            params->setEntryNameAt(ix, "crop-height");
+            item.set(end - offset + 1);
+            params->setEntryAt(ix, item);
+        }
+    }
+
+    { // convert color info
+        int32_t standard;
+        if (params->findInt32(KEY_COLOR_STANDARD, &standard)) {
+            C2Color::primaries_t primaries;
+            C2Color::matrix_t matrix;
+
+            if (C2Mapper::map(standard, &primaries, &matrix)) {
+                params->setInt32("color-primaries", primaries);
+                params->setInt32("color-matrix", matrix);
+            }
+        }
+
+        sp<ABuffer> hdrMeta;
+        if (params->findBuffer(KEY_HDR_STATIC_INFO, &hdrMeta)
+                && hdrMeta->size() == sizeof(HDRStaticInfo)) {
+            HDRStaticInfo *meta = (HDRStaticInfo*)hdrMeta->data();
+            if (meta->mID == meta->kType1) {
+                params->setFloat("smpte2086.red.x", meta->sType1.mR.x * 0.00002);
+                params->setFloat("smpte2086.red.y", meta->sType1.mR.y * 0.00002);
+                params->setFloat("smpte2086.green.x", meta->sType1.mG.x * 0.00002);
+                params->setFloat("smpte2086.green.y", meta->sType1.mG.y * 0.00002);
+                params->setFloat("smpte2086.blue.x", meta->sType1.mB.x * 0.00002);
+                params->setFloat("smpte2086.blue.y", meta->sType1.mB.y * 0.00002);
+                params->setFloat("smpte2086.white.x", meta->sType1.mW.x * 0.00002);
+                params->setFloat("smpte2086.white.y", meta->sType1.mW.y * 0.00002);
+                params->setFloat("smpte2086.max-luminance", meta->sType1.mMaxDisplayLuminance);
+                params->setFloat("smpte2086.min-luminance", meta->sType1.mMinDisplayLuminance * 0.0001);
+                params->setFloat("cta861.max-cll", meta->sType1.mMaxContentLightLevel);
+                params->setFloat("cta861.max-fall", meta->sType1.mMaxFrameAverageLightLevel);
+            }
+        }
+    }
+
+    // this is to verify that we set proper signedness for standard parameters
+    bool beVeryStrict = property_get_bool("debug.stagefright.ccodec_strict_type", false);
+    // this is to allow vendors to use the wrong signedness for standard parameters
+    bool beVeryLax = property_get_bool("debug.stagefright.ccodec_lax_type", false);
+
+    ReflectedParamUpdater::Dict filtered;
+    for (size_t ix = 0; ix < params->countEntries(); ++ix) {
+        AMessage::Type type;
+        AString name = params->getEntryNameAt(ix, &type);
+        AMessage::ItemData msgItem = params->getEntryAt(ix);
+        ReflectedParamUpdater::Value item;
+        convert(msgItem, &item); // convert item to param updater item
+
+        if (name.startsWith("vendor.")) {
+            // vendor params pass through as is
+            filtered.emplace(name.c_str(), item);
+            continue;
+        }
+        // standard parameters may get modified, filtered or duplicated
+        for (const ConfigMapper &cm : mStandardParams->getConfigMappersForSdkKey(name.c_str())) {
+            // note: we ignore port domain for configuration
+            if ((cm.domain() & configDomain)
+                    // component domain + kind (these must match)
+                    && (cm.domain() & mDomain) == mDomain) {
+                // map arithmetic values, pass through string or buffer
+                switch (type) {
+                    case AMessage::kTypeBuffer:
+                    case AMessage::kTypeString:
+                        break;
+                    case AMessage::kTypeInt32:
+                    case AMessage::kTypeInt64:
+                    case AMessage::kTypeFloat:
+                    case AMessage::kTypeDouble:
+                        // for now only map settings with mappers as we are not creating
+                        // signed <=> unsigned mappers
+                        // TODO: be precise about signed unsigned
+                        if (beVeryStrict || cm.mapper()) {
+                            item.set(cm.mapFromMessage(params->getEntryAt(ix)));
+                            // also allow to relax type strictness
+                            if (beVeryLax) {
+                                relaxValues(item);
+                            }
+                        }
+                        break;
+                    default:
+                        continue;
+                }
+                filtered.emplace(cm.path(), item);
+            }
+        }
+    }
+    ALOGV("filtered %s to %s", params->debugString(4).c_str(),
+            filtered.debugString(4).c_str());
+    return filtered;
+}
+
+status_t CCodecConfig::getConfigUpdateFromSdkParams(
+        std::shared_ptr<Codec2Client::Component> component,
+        const sp<AMessage> &sdkParams, Domain configDomain,
+        c2_blocking_t blocking,
+        std::vector<std::unique_ptr<C2Param>> *configUpdate) const {
+    ReflectedParamUpdater::Dict params = getReflectedFormat(sdkParams, configDomain);
+
+    std::vector<C2Param::Index> indices;
+    mParamUpdater->getParamIndicesFromMessage(params, &indices);
+    if (indices.empty()) {
+        ALOGD("no recognized params in: %s", params.debugString().c_str());
+        return OK;
+    }
+
+    configUpdate->clear();
+    std::vector<C2Param::Index> supportedIndices;
+    for (C2Param::Index ix : indices) {
+        if (mSupportedIndices.count(ix)) {
+            supportedIndices.push_back(ix);
+        } else if (mLocalParams.count(ix)) {
+            // query local parameter here
+            auto it = mCurrentConfig.find(ix);
+            if (it != mCurrentConfig.end()) {
+                configUpdate->emplace_back(C2Param::Copy(*it->second));
+            }
+        }
+    }
+
+    c2_status_t err = component->query({ }, supportedIndices, blocking, configUpdate);
+    if (err != C2_OK) {
+        ALOGD("query failed after returning %zu params => %s", configUpdate->size(), asString(err));
+    }
+
+    if (configUpdate->size()) {
+        mParamUpdater->updateParamsFromMessage(params, configUpdate);
+    }
+    return OK;
+}
+
+status_t CCodecConfig::setParameters(
+        std::shared_ptr<Codec2Client::Component> component,
+        std::vector<std::unique_ptr<C2Param>> &configUpdate,
+        c2_blocking_t blocking) {
+    status_t result = OK;
+    if (configUpdate.empty()) {
+        return OK;
+    }
+
+    std::vector<C2Param::Index> indices;
+    std::vector<C2Param *> paramVector;
+    for (const std::unique_ptr<C2Param> &param : configUpdate) {
+        if (mSupportedIndices.count(param->index())) {
+            // component parameter
+            paramVector.push_back(param.get());
+            indices.push_back(param->index());
+        } else if (mLocalParams.count(param->index())) {
+            // handle local parameter here
+            LocalParamValidator validator = mLocalParams.find(param->index())->second;
+            c2_status_t err = C2_OK;
+            std::unique_ptr<C2Param> copy = C2Param::Copy(*param);
+            if (validator) {
+                err = validator(copy);
+            }
+            if (err == C2_OK) {
+                ALOGV("updated local parameter value for %s",
+                        mParamUpdater->getParamName(param->index()).c_str());
+
+                mCurrentConfig[param->index()] = std::move(copy);
+            } else {
+                ALOGD("failed to set parameter value for %s => %s",
+                        mParamUpdater->getParamName(param->index()).c_str(), asString(err));
+                result = BAD_VALUE;
+            }
+        }
+    }
+    // update subscribed param indices
+    subscribeToConfigUpdate(component, indices, blocking);
+
+    std::vector<std::unique_ptr<C2SettingResult>> failures;
+    c2_status_t err = component->config(paramVector, blocking, &failures);
+    if (err != C2_OK) {
+        ALOGD("config failed => %s", asString(err));
+        // This is non-fatal.
+    }
+    for (const std::unique_ptr<C2SettingResult> &failure : failures) {
+        switch (failure->failure) {
+            case C2SettingResult::BAD_VALUE:
+                ALOGD("Bad parameter value");
+                result = BAD_VALUE;
+                break;
+            default:
+                ALOGV("failure = %d", int(failure->failure));
+                break;
+        }
+    }
+
+    // Re-query parameter values in case config could not update them and update the current
+    // configuration.
+    configUpdate.clear();
+    err = component->query({}, indices, blocking, &configUpdate);
+    if (err != C2_OK) {
+        ALOGD("query failed after returning %zu params => %s", configUpdate.size(), asString(err));
+    }
+    (void)updateConfiguration(configUpdate, ALL);
+
+    // TODO: error value
+    return result;
+}
+
+const C2Param *CCodecConfig::getConfigParameterValue(C2Param::Index index) const {
+    auto it = mCurrentConfig.find(index);
+    if (it == mCurrentConfig.end()) {
+        return nullptr;
+    } else {
+        return it->second.get();
+    }
+}
+
+}  // namespace android
diff --git a/media/codec2/sfplugin/CCodecConfig.h b/media/codec2/sfplugin/CCodecConfig.h
new file mode 100644
index 0000000..3bafe3f
--- /dev/null
+++ b/media/codec2/sfplugin/CCodecConfig.h
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef C_CODEC_CONFIG_H_
+#define C_CODEC_CONFIG_H_
+
+#include <map>
+#include <memory>
+#include <set>
+#include <vector>
+
+#include <C2Component.h>
+#include <codec2/hidl/client.h>
+
+#include <utils/RefBase.h>
+
+#include "InputSurfaceWrapper.h"
+#include "ReflectedParamUpdater.h"
+
+namespace android {
+
+struct AMessage;
+struct StandardParams;
+
+/**
+ * Struct managing the codec configuration for CCodec.
+ */
+struct CCodecConfig {
+
+    /**
+     * Domain consists of a bitmask divided into fields, and specifiers work by excluding other
+     * values in those domains.
+     *
+     * Component domains are composed by or-ing the individual IS_ constants, e.g.
+     * IS_DECODER | IS_AUDIO.
+     *
+     * Config specifiers are composed by or-ing the individual mask constants, and
+     * and-ing these groups: e.g. (DECODER | ENCODER) & AUDIO.
+     *
+     * The naming of these constants was to limit the length of mask names as these are used more
+     * commonly as masks.
+     */
+    enum Domain : uint32_t {
+        // component domain (domain & kind)
+        GUARD_BIT   = (1 << 1),   ///< this is to prevent against accidental && or || usage
+        IS_AUDIO    = (1 << 2),   ///< for audio codecs
+        IS_VIDEO    = (1 << 3),   ///< for video codecs
+        IS_IMAGE    = (1 << 4),   ///< for image codecs
+        OTHER_DOMAIN = (1 << 5),  ///< for other domains
+
+        IS_ENCODER  = (1 << 6),   ///< for encoders
+        IS_DECODER  = (1 << 7),   ///< for decoders
+        OTHER_KIND  = (1 << 8),   ///< for other domains
+
+        // config domain
+        IS_PARAM    = (1 << 9),   ///< for setParameter
+        IS_CONFIG   = (1 << 10),  ///< for configure
+        IS_READ     = (1 << 11),  ///< for getFormat
+
+        // port domain
+        IS_INPUT    = (1 << 12),  ///< for input port (getFormat)
+        IS_OUTPUT   = (1 << 13),  ///< for output port (getFormat)
+        IS_RAW      = (1 << 14),  ///< for raw port (input-encoder, output-decoder)
+        IS_CODED    = (1 << 15),  ///< for coded port (input-decoder, output-encoder)
+
+        ALL     = ~0U,
+        NONE    = 0,
+
+        AUDIO   = ~(IS_IMAGE | IS_VIDEO | OTHER_DOMAIN),
+        VIDEO   = ~(IS_AUDIO | IS_IMAGE | OTHER_DOMAIN),
+        IMAGE   = ~(IS_AUDIO | IS_VIDEO | OTHER_DOMAIN),
+
+        DECODER = ~(IS_ENCODER | OTHER_KIND),
+        ENCODER = ~(IS_DECODER | OTHER_KIND),
+
+        PARAM   = ~(IS_CONFIG | IS_READ),
+        CONFIG  = ~(IS_PARAM  | IS_READ),
+        READ    = ~(IS_CONFIG | IS_PARAM),
+
+        INPUT   = ~(IS_OUTPUT | IS_RAW    | IS_CODED),
+        OUTPUT  = ~(IS_INPUT  | IS_RAW    | IS_CODED),
+        RAW     = ~(IS_INPUT  | IS_OUTPUT | IS_CODED),
+        CODED   = ~(IS_INPUT  | IS_RAW    | IS_OUTPUT),
+    };
+
+    // things required to manage formats
+    std::vector<std::shared_ptr<C2ParamDescriptor>> mParamDescs;
+    std::shared_ptr<C2ParamReflector> mReflector;
+
+    std::shared_ptr<ReflectedParamUpdater> mParamUpdater;
+
+    Domain mDomain; // component domain
+    Domain mInputDomain; // input port domain
+    Domain mOutputDomain; // output port domain
+    std::string mCodingMediaType;  // media type of the coded stream
+
+    // standard MediaCodec to Codec 2.0 params mapping
+    std::shared_ptr<StandardParams> mStandardParams;
+
+    std::set<C2Param::Index> mSupportedIndices; ///< indices supported by the component
+    std::set<C2Param::Index> mSubscribedIndices; ///< indices to subscribe to
+    size_t mSubscribedIndicesSize; ///< count of currently subscribed indices
+
+    sp<AMessage> mInputFormat;
+    sp<AMessage> mOutputFormat;
+
+    bool mUsingSurface; ///< using input or output surface
+
+    std::shared_ptr<InputSurfaceWrapper> mInputSurface;
+    std::unique_ptr<InputSurfaceWrapper::Config> mISConfig;
+
+    /// the current configuration. Updated after configure() and based on configUpdate in
+    /// onWorkDone
+    std::map<C2Param::Index, std::unique_ptr<C2Param>> mCurrentConfig;
+
+    typedef std::function<c2_status_t(std::unique_ptr<C2Param>&)> LocalParamValidator;
+
+    /// Parameter indices tracked in current config that are not supported by the component.
+    /// these are provided so that optional parameters can remain in the current configuration.
+    /// as such, these parameters have no dependencies. TODO: use C2InterfaceHelper for this.
+    /// For now support a validation function.
+    std::map<C2Param::Index, LocalParamValidator> mLocalParams;
+
+    CCodecConfig();
+
+    /// initializes the members required to manage the format: descriptors, reflector,
+    /// reflected param helper, domain, standard params, and subscribes to standard
+    /// indices.
+    status_t initialize(
+            const std::shared_ptr<Codec2Client> &client,
+            const std::shared_ptr<Codec2Client::Component> &component);
+
+
+    /**
+     * Adds a locally maintained parameter. This is used for output configuration that can be
+     * appended to the output buffers in case it is not supported by the component.
+     */
+    template<typename T>
+    bool addLocalParam(
+            const std::string &name,
+            C2ParamDescriptor::attrib_t attrib = C2ParamDescriptor::IS_READ_ONLY,
+            std::function<c2_status_t(std::unique_ptr<T>&)> validator_ =
+                std::function<c2_status_t(std::unique_ptr<T>&)>()) {
+        C2Param::Index index = T::PARAM_TYPE;
+        if (mSupportedIndices.count(index) || mLocalParams.count(index)) {
+            if (mSupportedIndices.count(index)) {
+                mSubscribedIndices.emplace(index);
+            }
+            ALOGD("ignoring local param %s (%#x) as it is already %s",
+                    name.c_str(), (uint32_t)index, mSupportedIndices.count(index) ? "supported" : "local");
+            return false; // already supported by the component or already added
+        }
+
+        // wrap typed validator into untyped validator
+        LocalParamValidator validator;
+        if (validator_) {
+            validator = [validator_](std::unique_ptr<C2Param>& p){
+                c2_status_t res = C2_BAD_VALUE;
+                std::unique_ptr<T> typed(static_cast<T*>(p.release()));
+                // if parameter is correctly typed
+                if (T::From(typed.get())) {
+                    res = validator_(typed);
+                    p.reset(typed.release());
+                }
+                return res;
+            };
+        }
+
+        mLocalParams.emplace(index, validator);
+        mParamUpdater->addStandardParam<T>(name, attrib);
+        return true;
+    }
+
+    /**
+     * Adds a locally maintained parameter with a default value.
+     */
+    template<typename T>
+    bool addLocalParam(
+            std::unique_ptr<T> default_,
+            const std::string &name,
+            C2ParamDescriptor::attrib_t attrib = C2ParamDescriptor::IS_READ_ONLY,
+            std::function<c2_status_t(std::unique_ptr<T>&)> validator_ =
+                std::function<c2_status_t(std::unique_ptr<T>&)>()) {
+        if (addLocalParam<T>(name, attrib, validator_)) {
+            if (validator_) {
+                c2_status_t err = validator_(default_);
+                if (err != C2_OK) {
+                    ALOGD("default value for %s is invalid => %s", name.c_str(), asString(err));
+                    return false;
+                }
+            }
+            mCurrentConfig[T::PARAM_TYPE] = std::move(default_);
+            return true;
+        }
+        return false;
+    }
+
+    template<typename T>
+    bool addLocalParam(
+            T *default_, const std::string &name,
+            C2ParamDescriptor::attrib_t attrib = C2ParamDescriptor::IS_READ_ONLY,
+            std::function<c2_status_t(std::unique_ptr<T>&)> validator_ =
+                std::function<c2_status_t(std::unique_ptr<T>&)>()) {
+        return addLocalParam(std::unique_ptr<T>(default_), name, attrib, validator_);
+    }
+
+    /// Applies configuration updates, and updates format in the specific domain.
+    /// Returns true if formats were updated
+    /// \param domain input/output bitmask
+    bool updateConfiguration(
+            std::vector<std::unique_ptr<C2Param>> &configUpdate, Domain domain);
+
+    /// Updates formats in the specific domain. Returns true if any of the formats have changed.
+    /// \param domain input/output bitmask
+    bool updateFormats(Domain domain);
+
+    /**
+     * Applies SDK configurations in a specific configuration domain.
+     * Updates relevant input/output formats and subscribes to parameters specified in the
+     * configuration.
+     * \param domain config/setParam bitmask
+     * \param blocking blocking mode to use with the component
+     */
+    status_t getConfigUpdateFromSdkParams(
+            std::shared_ptr<Codec2Client::Component> component,
+            const sp<AMessage> &sdkParams, Domain domain,
+            c2_blocking_t blocking,
+            std::vector<std::unique_ptr<C2Param>> *configUpdate) const;
+
+    /**
+     * Applies a configuration update to the component.
+     * Updates relevant input/output formats and subscribes to parameters specified in the
+     * configuration.
+     * \param blocking blocking mode to use with the component
+     */
+    status_t setParameters(
+            std::shared_ptr<Codec2Client::Component> component,
+            std::vector<std::unique_ptr<C2Param>> &configUpdate,
+            c2_blocking_t blocking);
+
+    /// Queries subscribed indices (which contains all SDK-exposed values) and updates
+    /// input/output formats.
+    status_t queryConfiguration(
+            const std::shared_ptr<Codec2Client::Component> &component);
+
+    /// Queries a configuration parameter value. Returns nullptr if the parameter is not
+    /// part of the current configuration
+    const C2Param *getConfigParameterValue(C2Param::Index index) const;
+
+    /**
+     * Object that can be used to access configuration parameters and if they change.
+     */
+    template<typename T>
+    struct Watcher {
+        ~Watcher() = default;
+
+        /// returns true if the value of this configuration has changed
+        bool hasChanged() const {
+            const C2Param *value = mParent->getConfigParameterValue(mIndex);
+            if (value && mValue) {
+                return *value != *mValue;
+            } else {
+                return value != mValue.get();
+            }
+        }
+
+        /// updates the current value and returns it
+        std::shared_ptr<const T> update() {
+            const C2Param *value = mParent->getConfigParameterValue(mIndex);
+            if (value) {
+                mValue = std::shared_ptr<const T>(T::From(C2Param::Copy(*value).release()));
+            }
+            return mValue;
+        }
+
+    private:
+        Watcher(C2Param::Index index, const CCodecConfig *parent)
+            : mParent(parent), mIndex(index) {
+            update();
+        }
+
+        friend struct CCodecConfig;
+
+        const CCodecConfig *mParent;
+        std::shared_ptr<const T> mValue;
+        C2Param::Index mIndex;
+    };
+
+    /**
+     * Returns a watcher object for a parameter.
+     */
+    template<typename T>
+    Watcher<T> watch(C2Param::Index index = T::PARAM_TYPE) const {
+        if (index.type() != T::PARAM_TYPE) {
+            __builtin_trap();
+        }
+        return Watcher<T>(index, this);
+    }
+
+private:
+
+    /// initializes the standard MediaCodec to Codec 2.0 params mapping
+    void initializeStandardParams();
+
+    /// Adds indices to the subscribed indices, and updated subscription to component
+    /// \param blocking blocking mode to use with the component
+    status_t subscribeToConfigUpdate(
+            const std::shared_ptr<Codec2Client::Component> &component,
+            const std::vector<C2Param::Index> &indices,
+            c2_blocking_t blocking = C2_DONT_BLOCK);
+
+    /// Gets SDK format from codec 2.0 reflected configuration
+    /// \param domain input/output bitmask
+    sp<AMessage> getSdkFormatForDomain(
+            const ReflectedParamUpdater::Dict &reflected, Domain domain) const;
+
+    /**
+     * Converts a set of configuration parameters in an AMessage to a list of path-based Codec
+     * 2.0 configuration parameters.
+     *
+     * \param domain config/setParam bitmask
+     */
+    ReflectedParamUpdater::Dict getReflectedFormat(
+            const sp<AMessage> &config, Domain domain) const;
+};
+
+DEFINE_ENUM_OPERATORS(CCodecConfig::Domain)
+
+}  // namespace android
+
+#endif  // C_CODEC_H_
+
diff --git a/media/codec2/sfplugin/Codec2Buffer.cpp b/media/codec2/sfplugin/Codec2Buffer.cpp
new file mode 100644
index 0000000..5c8ad56
--- /dev/null
+++ b/media/codec2/sfplugin/Codec2Buffer.cpp
@@ -0,0 +1,815 @@
+/*
+ * Copyright 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2Buffer"
+#include <utils/Log.h>
+
+#include <hidlmemory/FrameworkUtils.h>
+#include <media/hardware/HardwareAPI.h>
+#include <media/stagefright/MediaCodecConstants.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/AUtils.h>
+#include <nativebase/nativebase.h>
+#include <ui/Fence.h>
+
+#include <C2AllocatorGralloc.h>
+#include <C2BlockInternal.h>
+#include <C2Debug.h>
+
+#include "Codec2Buffer.h"
+
+namespace android {
+
+// Codec2Buffer
+
+bool Codec2Buffer::canCopyLinear(const std::shared_ptr<C2Buffer> &buffer) const {
+    if (const_cast<Codec2Buffer *>(this)->base() == nullptr) {
+        return false;
+    }
+    if (!buffer) {
+        // Nothing to copy, so we can copy by doing nothing.
+        return true;
+    }
+    if (buffer->data().type() != C2BufferData::LINEAR) {
+        return false;
+    }
+    if (buffer->data().linearBlocks().size() == 0u) {
+        // Nothing to copy, so we can copy by doing nothing.
+        return true;
+    } else if (buffer->data().linearBlocks().size() > 1u) {
+        // We don't know how to copy more than one blocks.
+        return false;
+    }
+    if (buffer->data().linearBlocks()[0].size() > capacity()) {
+        // It won't fit.
+        return false;
+    }
+    return true;
+}
+
+bool Codec2Buffer::copyLinear(const std::shared_ptr<C2Buffer> &buffer) {
+    // We assume that all canCopyLinear() checks passed.
+    if (!buffer || buffer->data().linearBlocks().size() == 0u
+            || buffer->data().linearBlocks()[0].size() == 0u) {
+        setRange(0, 0);
+        return true;
+    }
+    C2ReadView view = buffer->data().linearBlocks()[0].map().get();
+    if (view.error() != C2_OK) {
+        ALOGD("Error while mapping: %d", view.error());
+        return false;
+    }
+    if (view.capacity() > capacity()) {
+        ALOGD("C2ConstLinearBlock lied --- it actually doesn't fit: view(%u) > this(%zu)",
+                view.capacity(), capacity());
+        return false;
+    }
+    memcpy(base(), view.data(), view.capacity());
+    setRange(0, view.capacity());
+    return true;
+}
+
+void Codec2Buffer::setImageData(const sp<ABuffer> &imageData) {
+    mImageData = imageData;
+}
+
+// LocalLinearBuffer
+
+bool LocalLinearBuffer::canCopy(const std::shared_ptr<C2Buffer> &buffer) const {
+    return canCopyLinear(buffer);
+}
+
+bool LocalLinearBuffer::copy(const std::shared_ptr<C2Buffer> &buffer) {
+    return copyLinear(buffer);
+}
+
+// DummyContainerBuffer
+
+static uint8_t sDummyByte[1] = { 0 };
+
+DummyContainerBuffer::DummyContainerBuffer(
+        const sp<AMessage> &format, const std::shared_ptr<C2Buffer> &buffer)
+    : Codec2Buffer(format, new ABuffer(sDummyByte, 1)),
+      mBufferRef(buffer) {
+    setRange(0, buffer ? 1 : 0);
+}
+
+std::shared_ptr<C2Buffer> DummyContainerBuffer::asC2Buffer() {
+    return std::move(mBufferRef);
+}
+
+bool DummyContainerBuffer::canCopy(const std::shared_ptr<C2Buffer> &) const {
+    return !mBufferRef;
+}
+
+bool DummyContainerBuffer::copy(const std::shared_ptr<C2Buffer> &buffer) {
+    mBufferRef = buffer;
+    setRange(0, mBufferRef ? 1 : 0);
+    return true;
+}
+
+// LinearBlockBuffer
+
+// static
+sp<LinearBlockBuffer> LinearBlockBuffer::Allocate(
+        const sp<AMessage> &format, const std::shared_ptr<C2LinearBlock> &block) {
+    C2WriteView writeView(block->map().get());
+    if (writeView.error() != C2_OK) {
+        return nullptr;
+    }
+    return new LinearBlockBuffer(format, std::move(writeView), block);
+}
+
+std::shared_ptr<C2Buffer> LinearBlockBuffer::asC2Buffer() {
+    return C2Buffer::CreateLinearBuffer(mBlock->share(offset(), size(), C2Fence()));
+}
+
+bool LinearBlockBuffer::canCopy(const std::shared_ptr<C2Buffer> &buffer) const {
+    return canCopyLinear(buffer);
+}
+
+bool LinearBlockBuffer::copy(const std::shared_ptr<C2Buffer> &buffer) {
+    return copyLinear(buffer);
+}
+
+LinearBlockBuffer::LinearBlockBuffer(
+        const sp<AMessage> &format,
+        C2WriteView&& writeView,
+        const std::shared_ptr<C2LinearBlock> &block)
+    : Codec2Buffer(format, new ABuffer(writeView.data(), writeView.size())),
+      mWriteView(writeView),
+      mBlock(block) {
+}
+
+// ConstLinearBlockBuffer
+
+// static
+sp<ConstLinearBlockBuffer> ConstLinearBlockBuffer::Allocate(
+        const sp<AMessage> &format, const std::shared_ptr<C2Buffer> &buffer) {
+    if (!buffer
+            || buffer->data().type() != C2BufferData::LINEAR
+            || buffer->data().linearBlocks().size() != 1u) {
+        return nullptr;
+    }
+    C2ReadView readView(buffer->data().linearBlocks()[0].map().get());
+    if (readView.error() != C2_OK) {
+        return nullptr;
+    }
+    return new ConstLinearBlockBuffer(format, std::move(readView), buffer);
+}
+
+ConstLinearBlockBuffer::ConstLinearBlockBuffer(
+        const sp<AMessage> &format,
+        C2ReadView&& readView,
+        const std::shared_ptr<C2Buffer> &buffer)
+    : Codec2Buffer(format, new ABuffer(
+            // NOTE: ABuffer only takes non-const pointer but this data is
+            //       supposed to be read-only.
+            const_cast<uint8_t *>(readView.data()), readView.capacity())),
+      mReadView(readView),
+      mBufferRef(buffer) {
+}
+
+std::shared_ptr<C2Buffer> ConstLinearBlockBuffer::asC2Buffer() {
+    return std::move(mBufferRef);
+}
+
+// GraphicView2MediaImageConverter
+
+namespace {
+
+class GraphicView2MediaImageConverter {
+public:
+    /**
+     * Creates a C2GraphicView <=> MediaImage converter
+     *
+     * \param view C2GraphicView object
+     * \param colorFormat desired SDK color format for the MediaImage (if this is a flexible format,
+     *        an attempt is made to simply represent the graphic view as a flexible SDK format
+     *        without a memcpy)
+     * \param copy whether the converter is used for copy or not
+     */
+    GraphicView2MediaImageConverter(
+            const C2GraphicView &view, int32_t colorFormat, bool copy)
+        : mInitCheck(NO_INIT),
+          mView(view),
+          mWidth(view.width()),
+          mHeight(view.height()),
+          mColorFormat(colorFormat),
+          mAllocatedDepth(0),
+          mBackBufferSize(0),
+          mMediaImage(new ABuffer(sizeof(MediaImage2))) {
+        if (view.error() != C2_OK) {
+            ALOGD("Converter: view.error() = %d", view.error());
+            mInitCheck = BAD_VALUE;
+            return;
+        }
+        MediaImage2 *mediaImage = (MediaImage2 *)mMediaImage->base();
+        const C2PlanarLayout &layout = view.layout();
+        if (layout.numPlanes == 0) {
+            ALOGD("Converter: 0 planes");
+            mInitCheck = BAD_VALUE;
+            return;
+        }
+        memset(mediaImage, 0, sizeof(*mediaImage));
+        mAllocatedDepth = layout.planes[0].allocatedDepth;
+        uint32_t bitDepth = layout.planes[0].bitDepth;
+
+        // align width and height to support subsampling cleanly
+        uint32_t stride = align(view.crop().width, 2) * divUp(layout.planes[0].allocatedDepth, 8u);
+        uint32_t vStride = align(view.crop().height, 2);
+
+        switch (layout.type) {
+            case C2PlanarLayout::TYPE_YUV:
+                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_YUV;
+                if (layout.numPlanes != 3) {
+                    ALOGD("Converter: %d planes for YUV layout", layout.numPlanes);
+                    mInitCheck = BAD_VALUE;
+                    return;
+                }
+                if (layout.planes[0].channel != C2PlaneInfo::CHANNEL_Y
+                        || layout.planes[1].channel != C2PlaneInfo::CHANNEL_CB
+                        || layout.planes[2].channel != C2PlaneInfo::CHANNEL_CR
+                        || layout.planes[0].colSampling != 1
+                        || layout.planes[0].rowSampling != 1
+                        || layout.planes[1].colSampling != 2
+                        || layout.planes[1].rowSampling != 2
+                        || layout.planes[2].colSampling != 2
+                        || layout.planes[2].rowSampling != 2) {
+                    ALOGD("Converter: not YUV420 for YUV layout");
+                    mInitCheck = BAD_VALUE;
+                    return;
+                }
+                switch (mColorFormat) {
+                    case COLOR_FormatYUV420Flexible:
+                        if (!copy) {
+                            // try to map directly. check if the planes are near one another
+                            const uint8_t *minPtr = mView.data()[0];
+                            const uint8_t *maxPtr = mView.data()[0];
+                            int32_t planeSize = 0;
+                            for (uint32_t i = 0; i < layout.numPlanes; ++i) {
+                                const C2PlaneInfo &plane = layout.planes[i];
+                                ssize_t minOffset = plane.minOffset(mWidth, mHeight);
+                                ssize_t maxOffset = plane.maxOffset(mWidth, mHeight);
+                                if (minPtr > mView.data()[i] + minOffset) {
+                                    minPtr = mView.data()[i] + minOffset;
+                                }
+                                if (maxPtr < mView.data()[i] + maxOffset) {
+                                    maxPtr = mView.data()[i] + maxOffset;
+                                }
+                                planeSize += std::abs(plane.rowInc) * align(mHeight, 64)
+                                        / plane.rowSampling / plane.colSampling
+                                        * divUp(mAllocatedDepth, 8u);
+                            }
+
+                            if ((maxPtr - minPtr + 1) <= planeSize) {
+                                // FIXME: this is risky as reading/writing data out of bound results
+                                //        in an undefined behavior, but gralloc does assume a
+                                //        contiguous mapping
+                                for (uint32_t i = 0; i < layout.numPlanes; ++i) {
+                                    const C2PlaneInfo &plane = layout.planes[i];
+                                    mediaImage->mPlane[i].mOffset = mView.data()[i] - minPtr;
+                                    mediaImage->mPlane[i].mColInc = plane.colInc;
+                                    mediaImage->mPlane[i].mRowInc = plane.rowInc;
+                                    mediaImage->mPlane[i].mHorizSubsampling = plane.colSampling;
+                                    mediaImage->mPlane[i].mVertSubsampling = plane.rowSampling;
+                                }
+                                mWrapped = new ABuffer(const_cast<uint8_t *>(minPtr),
+                                                       maxPtr - minPtr + 1);
+                                break;
+                            }
+                        }
+                        [[fallthrough]];
+
+                    case COLOR_FormatYUV420Planar:
+                    case COLOR_FormatYUV420PackedPlanar:
+                        mediaImage->mPlane[mediaImage->Y].mOffset = 0;
+                        mediaImage->mPlane[mediaImage->Y].mColInc = 1;
+                        mediaImage->mPlane[mediaImage->Y].mRowInc = stride;
+                        mediaImage->mPlane[mediaImage->Y].mHorizSubsampling = 1;
+                        mediaImage->mPlane[mediaImage->Y].mVertSubsampling = 1;
+
+                        mediaImage->mPlane[mediaImage->U].mOffset = stride * vStride;
+                        mediaImage->mPlane[mediaImage->U].mColInc = 1;
+                        mediaImage->mPlane[mediaImage->U].mRowInc = stride / 2;
+                        mediaImage->mPlane[mediaImage->U].mHorizSubsampling = 2;
+                        mediaImage->mPlane[mediaImage->U].mVertSubsampling = 2;
+
+                        mediaImage->mPlane[mediaImage->V].mOffset = stride * vStride * 5 / 4;
+                        mediaImage->mPlane[mediaImage->V].mColInc = 1;
+                        mediaImage->mPlane[mediaImage->V].mRowInc = stride / 2;
+                        mediaImage->mPlane[mediaImage->V].mHorizSubsampling = 2;
+                        mediaImage->mPlane[mediaImage->V].mVertSubsampling = 2;
+                        break;
+
+                    case COLOR_FormatYUV420SemiPlanar:
+                    case COLOR_FormatYUV420PackedSemiPlanar:
+                        mediaImage->mPlane[mediaImage->Y].mOffset = 0;
+                        mediaImage->mPlane[mediaImage->Y].mColInc = 1;
+                        mediaImage->mPlane[mediaImage->Y].mRowInc = stride;
+                        mediaImage->mPlane[mediaImage->Y].mHorizSubsampling = 1;
+                        mediaImage->mPlane[mediaImage->Y].mVertSubsampling = 1;
+
+                        mediaImage->mPlane[mediaImage->U].mOffset = stride * vStride;
+                        mediaImage->mPlane[mediaImage->U].mColInc = 2;
+                        mediaImage->mPlane[mediaImage->U].mRowInc = stride;
+                        mediaImage->mPlane[mediaImage->U].mHorizSubsampling = 2;
+                        mediaImage->mPlane[mediaImage->U].mVertSubsampling = 2;
+
+                        mediaImage->mPlane[mediaImage->V].mOffset = stride * vStride + 1;
+                        mediaImage->mPlane[mediaImage->V].mColInc = 2;
+                        mediaImage->mPlane[mediaImage->V].mRowInc = stride;
+                        mediaImage->mPlane[mediaImage->V].mHorizSubsampling = 2;
+                        mediaImage->mPlane[mediaImage->V].mVertSubsampling = 2;
+                        break;
+
+                    default:
+                        ALOGD("Converter: incompactible color format (%d) for YUV layout", mColorFormat);
+                        mInitCheck = BAD_VALUE;
+                        return;
+                }
+                break;
+            case C2PlanarLayout::TYPE_YUVA:
+                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_YUVA;
+                // We don't have an SDK YUVA format
+                ALOGD("Converter: incompactible color format (%d) for YUVA layout", mColorFormat);
+                mInitCheck = BAD_VALUE;
+                return;
+            case C2PlanarLayout::TYPE_RGB:
+                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_RGB;
+                switch (mColorFormat) {
+                    // TODO media image
+                    case COLOR_FormatRGBFlexible:
+                    case COLOR_Format24bitBGR888:
+                    case COLOR_Format24bitRGB888:
+                        break;
+                    default:
+                        ALOGD("Converter: incompactible color format (%d) for RGB layout", mColorFormat);
+                        mInitCheck = BAD_VALUE;
+                        return;
+                }
+                if (layout.numPlanes != 3) {
+                    ALOGD("Converter: %d planes for RGB layout", layout.numPlanes);
+                    mInitCheck = BAD_VALUE;
+                    return;
+                }
+                break;
+            case C2PlanarLayout::TYPE_RGBA:
+                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_RGBA;
+                switch (mColorFormat) {
+                    // TODO media image
+                    case COLOR_FormatRGBAFlexible:
+                    case COLOR_Format32bitABGR8888:
+                    case COLOR_Format32bitARGB8888:
+                    case COLOR_Format32bitBGRA8888:
+                        break;
+                    default:
+                        ALOGD("Incompactible color format (%d) for RGBA layout", mColorFormat);
+                        mInitCheck = BAD_VALUE;
+                        return;
+                }
+                if (layout.numPlanes != 4) {
+                    ALOGD("Converter: %d planes for RGBA layout", layout.numPlanes);
+                    mInitCheck = BAD_VALUE;
+                    return;
+                }
+                break;
+            default:
+                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_UNKNOWN;
+                ALOGD("Unknown layout");
+                mInitCheck = BAD_VALUE;
+                return;
+        }
+        mediaImage->mNumPlanes = layout.numPlanes;
+        mediaImage->mWidth = view.crop().width;
+        mediaImage->mHeight = view.crop().height;
+        mediaImage->mBitDepth = bitDepth;
+        mediaImage->mBitDepthAllocated = mAllocatedDepth;
+
+        uint32_t bufferSize = 0;
+        for (uint32_t i = 0; i < layout.numPlanes; ++i) {
+            const C2PlaneInfo &plane = layout.planes[i];
+            if (plane.allocatedDepth < plane.bitDepth
+                    || plane.rightShift != plane.allocatedDepth - plane.bitDepth) {
+                ALOGD("rightShift value of %u unsupported", plane.rightShift);
+                mInitCheck = BAD_VALUE;
+                return;
+            }
+            if (plane.allocatedDepth > 8 && plane.endianness != C2PlaneInfo::NATIVE) {
+                ALOGD("endianness value of %u unsupported", plane.endianness);
+                mInitCheck = BAD_VALUE;
+                return;
+            }
+            if (plane.allocatedDepth != mAllocatedDepth || plane.bitDepth != bitDepth) {
+                ALOGV("different allocatedDepth/bitDepth per plane unsupported");
+                mInitCheck = BAD_VALUE;
+                return;
+            }
+            bufferSize += stride * vStride
+                    / plane.rowSampling / plane.colSampling;
+        }
+
+        mBackBufferSize = bufferSize;
+        mInitCheck = OK;
+    }
+
+    status_t initCheck() const { return mInitCheck; }
+
+    uint32_t backBufferSize() const { return mBackBufferSize; }
+
+    /**
+     * Wrap C2GraphicView using a MediaImage2. Note that if not wrapped, the content is not mapped
+     * in this function --- the caller should use CopyGraphicView2MediaImage() function to copy the
+     * data into a backing buffer explicitly.
+     *
+     * \return media buffer. This is null if wrapping failed.
+     */
+    sp<ABuffer> wrap() const {
+        if (mBackBuffer == nullptr) {
+            return mWrapped;
+        }
+        return nullptr;
+    }
+
+    bool setBackBuffer(const sp<ABuffer> &backBuffer) {
+        if (backBuffer == nullptr) {
+            return false;
+        }
+        if (backBuffer->capacity() < mBackBufferSize) {
+            return false;
+        }
+        backBuffer->setRange(0, mBackBufferSize);
+        mBackBuffer = backBuffer;
+        return true;
+    }
+
+    /**
+     * Copy C2GraphicView to MediaImage2.
+     */
+    status_t copyToMediaImage() {
+        if (mInitCheck != OK) {
+            return mInitCheck;
+        }
+        return ImageCopy(mBackBuffer->base(), getMediaImage(), mView);
+    }
+
+    const sp<ABuffer> &imageData() const { return mMediaImage; }
+
+private:
+    status_t mInitCheck;
+
+    const C2GraphicView mView;
+    uint32_t mWidth;
+    uint32_t mHeight;
+    int32_t mColorFormat;  ///< SDK color format for MediaImage
+    sp<ABuffer> mWrapped;  ///< wrapped buffer (if we can map C2Buffer to an ABuffer)
+    uint32_t mAllocatedDepth;
+    uint32_t mBackBufferSize;
+    sp<ABuffer> mMediaImage;
+    std::function<sp<ABuffer>(size_t)> mAlloc;
+
+    sp<ABuffer> mBackBuffer;    ///< backing buffer if we have to copy C2Buffer <=> ABuffer
+
+    MediaImage2 *getMediaImage() {
+        return (MediaImage2 *)mMediaImage->base();
+    }
+};
+
+}  // namespace
+
+// GraphicBlockBuffer
+
+// static
+sp<GraphicBlockBuffer> GraphicBlockBuffer::Allocate(
+        const sp<AMessage> &format,
+        const std::shared_ptr<C2GraphicBlock> &block,
+        std::function<sp<ABuffer>(size_t)> alloc) {
+    C2GraphicView view(block->map().get());
+    if (view.error() != C2_OK) {
+        ALOGD("C2GraphicBlock::map failed: %d", view.error());
+        return nullptr;
+    }
+
+    int32_t colorFormat = COLOR_FormatYUV420Flexible;
+    (void)format->findInt32("color-format", &colorFormat);
+
+    GraphicView2MediaImageConverter converter(view, colorFormat, false /* copy */);
+    if (converter.initCheck() != OK) {
+        ALOGD("Converter init failed: %d", converter.initCheck());
+        return nullptr;
+    }
+    bool wrapped = true;
+    sp<ABuffer> buffer = converter.wrap();
+    if (buffer == nullptr) {
+        buffer = alloc(converter.backBufferSize());
+        if (!converter.setBackBuffer(buffer)) {
+            ALOGD("Converter failed to set back buffer");
+            return nullptr;
+        }
+        wrapped = false;
+    }
+    return new GraphicBlockBuffer(
+            format,
+            buffer,
+            std::move(view),
+            block,
+            converter.imageData(),
+            wrapped);
+}
+
+GraphicBlockBuffer::GraphicBlockBuffer(
+        const sp<AMessage> &format,
+        const sp<ABuffer> &buffer,
+        C2GraphicView &&view,
+        const std::shared_ptr<C2GraphicBlock> &block,
+        const sp<ABuffer> &imageData,
+        bool wrapped)
+    : Codec2Buffer(format, buffer),
+      mView(view),
+      mBlock(block),
+      mWrapped(wrapped) {
+    setImageData(imageData);
+}
+
+std::shared_ptr<C2Buffer> GraphicBlockBuffer::asC2Buffer() {
+    uint32_t width = mView.width();
+    uint32_t height = mView.height();
+    if (!mWrapped) {
+        (void)ImageCopy(mView, base(), imageData());
+    }
+    return C2Buffer::CreateGraphicBuffer(
+            mBlock->share(C2Rect(width, height), C2Fence()));
+}
+
+// GraphicMetadataBuffer
+GraphicMetadataBuffer::GraphicMetadataBuffer(
+        const sp<AMessage> &format,
+        const std::shared_ptr<C2Allocator> &alloc)
+    : Codec2Buffer(format, new ABuffer(sizeof(VideoNativeMetadata))),
+      mAlloc(alloc) {
+    ((VideoNativeMetadata *)base())->pBuffer = nullptr;
+}
+
+std::shared_ptr<C2Buffer> GraphicMetadataBuffer::asC2Buffer() {
+#ifndef __LP64__
+    VideoNativeMetadata *meta = (VideoNativeMetadata *)base();
+    ANativeWindowBuffer *buffer = (ANativeWindowBuffer *)meta->pBuffer;
+    if (buffer == nullptr) {
+        ALOGD("VideoNativeMetadata contains null buffer");
+        return nullptr;
+    }
+
+    ALOGV("VideoNativeMetadata: %dx%d", buffer->width, buffer->height);
+    C2Handle *handle = WrapNativeCodec2GrallocHandle(
+            buffer->handle,
+            buffer->width,
+            buffer->height,
+            buffer->format,
+            buffer->usage,
+            buffer->stride);
+    std::shared_ptr<C2GraphicAllocation> alloc;
+    c2_status_t err = mAlloc->priorGraphicAllocation(handle, &alloc);
+    if (err != C2_OK) {
+        ALOGD("Failed to wrap VideoNativeMetadata into C2GraphicAllocation");
+        return nullptr;
+    }
+    std::shared_ptr<C2GraphicBlock> block = _C2BlockFactory::CreateGraphicBlock(alloc);
+
+    meta->pBuffer = 0;
+    // TODO: wrap this in C2Fence so that the component can wait when it
+    //       actually starts processing.
+    if (meta->nFenceFd >= 0) {
+        sp<Fence> fence(new Fence(meta->nFenceFd));
+        fence->waitForever(LOG_TAG);
+    }
+    return C2Buffer::CreateGraphicBuffer(
+            block->share(C2Rect(buffer->width, buffer->height), C2Fence()));
+#else
+    ALOGE("GraphicMetadataBuffer does not work on 64-bit arch");
+    return nullptr;
+#endif
+}
+
+// ConstGraphicBlockBuffer
+
+// static
+sp<ConstGraphicBlockBuffer> ConstGraphicBlockBuffer::Allocate(
+        const sp<AMessage> &format,
+        const std::shared_ptr<C2Buffer> &buffer,
+        std::function<sp<ABuffer>(size_t)> alloc) {
+    if (!buffer
+            || buffer->data().type() != C2BufferData::GRAPHIC
+            || buffer->data().graphicBlocks().size() != 1u) {
+        ALOGD("C2Buffer precond fail");
+        return nullptr;
+    }
+    std::unique_ptr<const C2GraphicView> view(std::make_unique<const C2GraphicView>(
+            buffer->data().graphicBlocks()[0].map().get()));
+    std::unique_ptr<const C2GraphicView> holder;
+
+    int32_t colorFormat = COLOR_FormatYUV420Flexible;
+    (void)format->findInt32("color-format", &colorFormat);
+
+    GraphicView2MediaImageConverter converter(*view, colorFormat, false /* copy */);
+    if (converter.initCheck() != OK) {
+        ALOGD("Converter init failed: %d", converter.initCheck());
+        return nullptr;
+    }
+    bool wrapped = true;
+    sp<ABuffer> aBuffer = converter.wrap();
+    if (aBuffer == nullptr) {
+        aBuffer = alloc(converter.backBufferSize());
+        if (!converter.setBackBuffer(aBuffer)) {
+            ALOGD("Converter failed to set back buffer");
+            return nullptr;
+        }
+        wrapped = false;
+        converter.copyToMediaImage();
+        // We don't need the view.
+        holder = std::move(view);
+    }
+    return new ConstGraphicBlockBuffer(
+            format,
+            aBuffer,
+            std::move(view),
+            buffer,
+            converter.imageData(),
+            wrapped);
+}
+
+// static
+sp<ConstGraphicBlockBuffer> ConstGraphicBlockBuffer::AllocateEmpty(
+        const sp<AMessage> &format,
+        std::function<sp<ABuffer>(size_t)> alloc) {
+    int32_t width, height;
+    if (!format->findInt32("width", &width)
+            || !format->findInt32("height", &height)) {
+        ALOGD("format had no width / height");
+        return nullptr;
+    }
+    // NOTE: we currently only support YUV420 formats for byte-buffer mode.
+    sp<ABuffer> aBuffer(alloc(align(width, 16) * align(height, 16) * 3 / 2));
+    return new ConstGraphicBlockBuffer(
+            format,
+            aBuffer,
+            nullptr,
+            nullptr,
+            nullptr,
+            false);
+}
+
+ConstGraphicBlockBuffer::ConstGraphicBlockBuffer(
+        const sp<AMessage> &format,
+        const sp<ABuffer> &aBuffer,
+        std::unique_ptr<const C2GraphicView> &&view,
+        const std::shared_ptr<C2Buffer> &buffer,
+        const sp<ABuffer> &imageData,
+        bool wrapped)
+    : Codec2Buffer(format, aBuffer),
+      mView(std::move(view)),
+      mBufferRef(buffer),
+      mWrapped(wrapped) {
+    setImageData(imageData);
+}
+
+std::shared_ptr<C2Buffer> ConstGraphicBlockBuffer::asC2Buffer() {
+    mView.reset();
+    return std::move(mBufferRef);
+}
+
+bool ConstGraphicBlockBuffer::canCopy(const std::shared_ptr<C2Buffer> &buffer) const {
+    if (mWrapped || mBufferRef) {
+        ALOGD("ConstGraphicBlockBuffer::canCopy: %swrapped ; buffer ref %s",
+                mWrapped ? "" : "not ", mBufferRef ? "exists" : "doesn't exist");
+        return false;
+    }
+    if (!buffer) {
+        // Nothing to copy, so we can copy by doing nothing.
+        return true;
+    }
+    if (buffer->data().type() != C2BufferData::GRAPHIC) {
+        ALOGD("ConstGraphicBlockBuffer::canCopy: buffer precondition unsatisfied");
+        return false;
+    }
+    if (buffer->data().graphicBlocks().size() == 0) {
+        return true;
+    } else if (buffer->data().graphicBlocks().size() != 1u) {
+        ALOGD("ConstGraphicBlockBuffer::canCopy: too many blocks");
+        return false;
+    }
+
+    int32_t colorFormat = COLOR_FormatYUV420Flexible;
+    // FIXME: format() is not const, but we cannot change it, so do a const cast here
+    const_cast<ConstGraphicBlockBuffer *>(this)->format()->findInt32("color-format", &colorFormat);
+
+    GraphicView2MediaImageConverter converter(
+            buffer->data().graphicBlocks()[0].map().get(), colorFormat, true /* copy */);
+    if (converter.initCheck() != OK) {
+        ALOGD("ConstGraphicBlockBuffer::canCopy: converter init failed: %d", converter.initCheck());
+        return false;
+    }
+    if (converter.backBufferSize() > capacity()) {
+        ALOGD("ConstGraphicBlockBuffer::canCopy: insufficient capacity: req %u has %zu",
+                converter.backBufferSize(), capacity());
+        return false;
+    }
+    return true;
+}
+
+bool ConstGraphicBlockBuffer::copy(const std::shared_ptr<C2Buffer> &buffer) {
+    if (!buffer || buffer->data().graphicBlocks().size() == 0) {
+        setRange(0, 0);
+        return true;
+    }
+    int32_t colorFormat = COLOR_FormatYUV420Flexible;
+    format()->findInt32("color-format", &colorFormat);
+
+    GraphicView2MediaImageConverter converter(
+            buffer->data().graphicBlocks()[0].map().get(), colorFormat, true /* copy */);
+    if (converter.initCheck() != OK) {
+        ALOGD("ConstGraphicBlockBuffer::copy: converter init failed: %d", converter.initCheck());
+        return false;
+    }
+    sp<ABuffer> aBuffer = new ABuffer(base(), capacity());
+    if (!converter.setBackBuffer(aBuffer)) {
+        ALOGD("ConstGraphicBlockBuffer::copy: set back buffer failed");
+        return false;
+    }
+    setRange(0, aBuffer->size());  // align size info
+    converter.copyToMediaImage();
+    setImageData(converter.imageData());
+    mBufferRef = buffer;
+    return true;
+}
+
+// EncryptedLinearBlockBuffer
+
+EncryptedLinearBlockBuffer::EncryptedLinearBlockBuffer(
+        const sp<AMessage> &format,
+        const std::shared_ptr<C2LinearBlock> &block,
+        const sp<IMemory> &memory,
+        int32_t heapSeqNum)
+    : Codec2Buffer(format, new ABuffer(memory->pointer(), memory->size())),
+      mBlock(block),
+      mMemory(memory),
+      mHeapSeqNum(heapSeqNum) {
+}
+
+std::shared_ptr<C2Buffer> EncryptedLinearBlockBuffer::asC2Buffer() {
+    return C2Buffer::CreateLinearBuffer(mBlock->share(offset(), size(), C2Fence()));
+}
+
+void EncryptedLinearBlockBuffer::fillSourceBuffer(
+        ICrypto::SourceBuffer *source) {
+    source->mSharedMemory = mMemory;
+    source->mHeapSeqNum = mHeapSeqNum;
+}
+
+void EncryptedLinearBlockBuffer::fillSourceBuffer(
+        hardware::cas::native::V1_0::SharedBuffer *source) {
+    ssize_t offset;
+    size_t size;
+
+    mHidlMemory = hardware::fromHeap(mMemory->getMemory(&offset, &size));
+    source->heapBase = *mHidlMemory;
+    source->offset = offset;
+    source->size = size;
+}
+
+bool EncryptedLinearBlockBuffer::copyDecryptedContent(
+        const sp<IMemory> &decrypted, size_t length) {
+    C2WriteView view = mBlock->map().get();
+    if (view.error() != C2_OK) {
+        return false;
+    }
+    if (view.size() < length) {
+        return false;
+    }
+    memcpy(view.data(), decrypted->pointer(), length);
+    return true;
+}
+
+bool EncryptedLinearBlockBuffer::copyDecryptedContentFromMemory(size_t length) {
+    return copyDecryptedContent(mMemory, length);
+}
+
+native_handle_t *EncryptedLinearBlockBuffer::handle() const {
+    return const_cast<native_handle_t *>(mBlock->handle());
+}
+
+}  // namespace android
diff --git a/media/codec2/sfplugin/Codec2Buffer.h b/media/codec2/sfplugin/Codec2Buffer.h
new file mode 100644
index 0000000..36dcab9
--- /dev/null
+++ b/media/codec2/sfplugin/Codec2Buffer.h
@@ -0,0 +1,406 @@
+/*
+ * Copyright 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_BUFFER_H_
+
+#define CODEC2_BUFFER_H_
+
+#include <C2Buffer.h>
+
+#include <android/hardware/cas/native/1.0/types.h>
+#include <binder/IMemory.h>
+#include <media/hardware/VideoAPI.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/MediaCodecBuffer.h>
+#include <media/ICrypto.h>
+
+namespace android {
+
+/**
+ * Copies a graphic view into a media image.
+ *
+ * \param imgBase base of MediaImage
+ * \param img MediaImage data
+ * \param view graphic view
+ *
+ * \return OK on success
+ */
+status_t ImageCopy(uint8_t *imgBase, const MediaImage2 *img, const C2GraphicView &view);
+
+/**
+ * Copies a media image into a graphic view.
+ *
+ * \param view graphic view
+ * \param imgBase base of MediaImage
+ * \param img MediaImage data
+ *
+ * \return OK on success
+ */
+status_t ImageCopy(C2GraphicView &view, const uint8_t *imgBase, const MediaImage2 *img);
+
+class Codec2Buffer : public MediaCodecBuffer {
+public:
+    using MediaCodecBuffer::MediaCodecBuffer;
+    ~Codec2Buffer() override = default;
+
+    /**
+     * \return  C2Buffer object represents this buffer.
+     */
+    virtual std::shared_ptr<C2Buffer> asC2Buffer() = 0;
+
+    /**
+     * Test if we can copy the content of |buffer| into this object.
+     *
+     * \param   buffer  C2Buffer object to copy.
+     * \return  true    if the content of buffer can be copied over to this buffer
+     *          false   otherwise.
+     */
+    virtual bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const {
+        (void)buffer;
+        return false;
+    }
+
+    /**
+     * Copy the content of |buffer| into this object. This method assumes that
+     * canCopy() check already passed.
+     *
+     * \param   buffer  C2Buffer object to copy.
+     * \return  true    if successful
+     *          false   otherwise.
+     */
+    virtual bool copy(const std::shared_ptr<C2Buffer> &buffer) {
+        (void)buffer;
+        return false;
+    }
+
+    sp<ABuffer> getImageData() const { return mImageData; }
+
+protected:
+    /**
+     * canCopy() implementation for linear buffers.
+     */
+    bool canCopyLinear(const std::shared_ptr<C2Buffer> &buffer) const;
+
+    /**
+     * copy() implementation for linear buffers.
+     */
+    bool copyLinear(const std::shared_ptr<C2Buffer> &buffer);
+
+    /**
+     * sets MediaImage data for flexible graphic buffers
+     */
+    void setImageData(const sp<ABuffer> &imageData);
+
+    sp<ABuffer> mImageData;
+};
+
+/**
+ * MediaCodecBuffer implementation on top of local linear buffer. This cannot
+ * cross process boundary so asC2Buffer() returns only nullptr.
+ */
+class LocalLinearBuffer : public Codec2Buffer {
+public:
+    using Codec2Buffer::Codec2Buffer;
+
+    std::shared_ptr<C2Buffer> asC2Buffer() override { return nullptr; }
+    bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const override;
+    bool copy(const std::shared_ptr<C2Buffer> &buffer) override;
+};
+
+/**
+ * MediaCodecBuffer implementation to be used only as a dummy wrapper around a
+ * C2Buffer object.
+ */
+class DummyContainerBuffer : public Codec2Buffer {
+public:
+    DummyContainerBuffer(
+            const sp<AMessage> &format,
+            const std::shared_ptr<C2Buffer> &buffer = nullptr);
+
+    std::shared_ptr<C2Buffer> asC2Buffer() override;
+    bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const override;
+    bool copy(const std::shared_ptr<C2Buffer> &buffer) override;
+
+private:
+    std::shared_ptr<C2Buffer> mBufferRef;
+};
+
+/**
+ * MediaCodecBuffer implementation wraps around C2LinearBlock.
+ */
+class LinearBlockBuffer : public Codec2Buffer {
+public:
+    /**
+     * Allocate a new LinearBufferBlock wrapping around C2LinearBlock object.
+     *
+     * \param   format  mandatory buffer format for MediaCodecBuffer
+     * \param   block   C2LinearBlock object to wrap around.
+     * \return          LinearBlockBuffer object with writable mapping.
+     *                  nullptr if unsuccessful.
+     */
+    static sp<LinearBlockBuffer> Allocate(
+            const sp<AMessage> &format, const std::shared_ptr<C2LinearBlock> &block);
+
+    virtual ~LinearBlockBuffer() = default;
+
+    std::shared_ptr<C2Buffer> asC2Buffer() override;
+    bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const override;
+    bool copy(const std::shared_ptr<C2Buffer> &buffer) override;
+
+private:
+    LinearBlockBuffer(
+            const sp<AMessage> &format,
+            C2WriteView &&writeView,
+            const std::shared_ptr<C2LinearBlock> &block);
+    LinearBlockBuffer() = delete;
+
+    C2WriteView mWriteView;
+    std::shared_ptr<C2LinearBlock> mBlock;
+};
+
+/**
+ * MediaCodecBuffer implementation wraps around C2ConstLinearBlock.
+ */
+class ConstLinearBlockBuffer : public Codec2Buffer {
+public:
+    /**
+     * Allocate a new ConstLinearBlockBuffer wrapping around C2Buffer object.
+     *
+     * \param   format  mandatory buffer format for MediaCodecBuffer
+     * \param   buffer  linear C2Buffer object to wrap around.
+     * \return          ConstLinearBlockBuffer object with readable mapping.
+     *                  nullptr if unsuccessful.
+     */
+    static sp<ConstLinearBlockBuffer> Allocate(
+            const sp<AMessage> &format, const std::shared_ptr<C2Buffer> &buffer);
+
+    virtual ~ConstLinearBlockBuffer() = default;
+
+    std::shared_ptr<C2Buffer> asC2Buffer() override;
+
+private:
+    ConstLinearBlockBuffer(
+            const sp<AMessage> &format,
+            C2ReadView &&readView,
+            const std::shared_ptr<C2Buffer> &buffer);
+    ConstLinearBlockBuffer() = delete;
+
+    C2ReadView mReadView;
+    std::shared_ptr<C2Buffer> mBufferRef;
+};
+
+/**
+ * MediaCodecBuffer implementation wraps around C2GraphicBlock.
+ *
+ * This object exposes the underlying bits via accessor APIs and "image-data"
+ * metadata, created automatically at allocation time.
+ */
+class GraphicBlockBuffer : public Codec2Buffer {
+public:
+    /**
+     * Allocate a new GraphicBlockBuffer wrapping around C2GraphicBlock object.
+     * If |block| is not in good color formats, it allocates YV12 local buffer
+     * and copies the content over at asC2Buffer().
+     *
+     * \param   format  mandatory buffer format for MediaCodecBuffer
+     * \param   block   C2GraphicBlock object to wrap around.
+     * \param   alloc   a function to allocate backing ABuffer if needed.
+     * \return          GraphicBlockBuffer object with writable mapping.
+     *                  nullptr if unsuccessful.
+     */
+    static sp<GraphicBlockBuffer> Allocate(
+            const sp<AMessage> &format,
+            const std::shared_ptr<C2GraphicBlock> &block,
+            std::function<sp<ABuffer>(size_t)> alloc);
+
+    virtual ~GraphicBlockBuffer() = default;
+
+    std::shared_ptr<C2Buffer> asC2Buffer() override;
+
+private:
+    GraphicBlockBuffer(
+            const sp<AMessage> &format,
+            const sp<ABuffer> &buffer,
+            C2GraphicView &&view,
+            const std::shared_ptr<C2GraphicBlock> &block,
+            const sp<ABuffer> &imageData,
+            bool wrapped);
+    GraphicBlockBuffer() = delete;
+
+    inline MediaImage2 *imageData() { return (MediaImage2 *)mImageData->data(); }
+
+    C2GraphicView mView;
+    std::shared_ptr<C2GraphicBlock> mBlock;
+    const bool mWrapped;
+};
+
+/**
+ * MediaCodecBuffer implementation wraps around VideoNativeMetadata.
+ */
+class GraphicMetadataBuffer : public Codec2Buffer {
+public:
+    /**
+     * Construct a new GraphicMetadataBuffer with local linear buffer for
+     * VideoNativeMetadata.
+     *
+     * \param   format      mandatory buffer format for MediaCodecBuffer
+     */
+    GraphicMetadataBuffer(
+            const sp<AMessage> &format, const std::shared_ptr<C2Allocator> &alloc);
+    virtual ~GraphicMetadataBuffer() = default;
+
+    std::shared_ptr<C2Buffer> asC2Buffer() override;
+
+private:
+    GraphicMetadataBuffer() = delete;
+
+    std::shared_ptr<C2Allocator> mAlloc;
+};
+
+/**
+ * MediaCodecBuffer implementation wraps around graphic C2Buffer object.
+ *
+ * This object exposes the underlying bits via accessor APIs and "image-data"
+ * metadata, created automatically at allocation time.
+ */
+class ConstGraphicBlockBuffer : public Codec2Buffer {
+public:
+    /**
+     * Allocate a new ConstGraphicBlockBuffer wrapping around C2Buffer object.
+     * If |buffer| is not in good color formats, it allocates YV12 local buffer
+     * and copies the content of |buffer| over to expose.
+     *
+     * \param   format  mandatory buffer format for MediaCodecBuffer
+     * \param   buffer  graphic C2Buffer object to wrap around.
+     * \param   alloc   a function to allocate backing ABuffer if needed.
+     * \return          ConstGraphicBlockBuffer object with readable mapping.
+     *                  nullptr if unsuccessful.
+     */
+    static sp<ConstGraphicBlockBuffer> Allocate(
+            const sp<AMessage> &format,
+            const std::shared_ptr<C2Buffer> &buffer,
+            std::function<sp<ABuffer>(size_t)> alloc);
+
+    /**
+     * Allocate a new ConstGraphicBlockBuffer which allocates YV12 local buffer
+     * and copies the content of |buffer| over to expose.
+     *
+     * \param   format  mandatory buffer format for MediaCodecBuffer
+     * \param   alloc   a function to allocate backing ABuffer if needed.
+     * \return          ConstGraphicBlockBuffer object with no wrapping buffer.
+     */
+    static sp<ConstGraphicBlockBuffer> AllocateEmpty(
+            const sp<AMessage> &format,
+            std::function<sp<ABuffer>(size_t)> alloc);
+
+    virtual ~ConstGraphicBlockBuffer() = default;
+
+    std::shared_ptr<C2Buffer> asC2Buffer() override;
+    bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const override;
+    bool copy(const std::shared_ptr<C2Buffer> &buffer) override;
+
+private:
+    ConstGraphicBlockBuffer(
+            const sp<AMessage> &format,
+            const sp<ABuffer> &aBuffer,
+            std::unique_ptr<const C2GraphicView> &&view,
+            const std::shared_ptr<C2Buffer> &buffer,
+            const sp<ABuffer> &imageData,
+            bool wrapped);
+    ConstGraphicBlockBuffer() = delete;
+
+    sp<ABuffer> mImageData;
+    std::unique_ptr<const C2GraphicView> mView;
+    std::shared_ptr<C2Buffer> mBufferRef;
+    const bool mWrapped;
+};
+
+/**
+ * MediaCodecBuffer implementation wraps around C2LinearBlock for component
+ * and IMemory for client. Underlying C2LinearBlock won't be mapped for secure
+ * usecases..
+ */
+class EncryptedLinearBlockBuffer : public Codec2Buffer {
+public:
+    /**
+     * Construct a new EncryptedLinearBufferBlock wrapping around C2LinearBlock
+     * object and writable IMemory region.
+     *
+     * \param   format      mandatory buffer format for MediaCodecBuffer
+     * \param   block       C2LinearBlock object to wrap around.
+     * \param   memory      IMemory object to store encrypted content.
+     * \param   heapSeqNum  Heap sequence number from ICrypto; -1 if N/A
+     */
+    EncryptedLinearBlockBuffer(
+            const sp<AMessage> &format,
+            const std::shared_ptr<C2LinearBlock> &block,
+            const sp<IMemory> &memory,
+            int32_t heapSeqNum = -1);
+    EncryptedLinearBlockBuffer() = delete;
+
+    virtual ~EncryptedLinearBlockBuffer() = default;
+
+    std::shared_ptr<C2Buffer> asC2Buffer() override;
+
+    /**
+     * Fill the source buffer structure with appropriate value based on
+     * internal IMemory object.
+     *
+     * \param source  source buffer structure to fill.
+     */
+    void fillSourceBuffer(ICrypto::SourceBuffer *source);
+    void fillSourceBuffer(
+            hardware::cas::native::V1_0::SharedBuffer *source);
+
+    /**
+     * Copy the content of |decrypted| into C2LinearBlock inside. This shall
+     * only be called in non-secure usecases.
+     *
+     * \param   decrypted   decrypted content to copy from.
+     * \param   length      length of the content
+     * \return  true        if successful
+     *          false       otherwise.
+     */
+    bool copyDecryptedContent(const sp<IMemory> &decrypted, size_t length);
+
+    /**
+     * Copy the content of internal IMemory object into C2LinearBlock inside.
+     * This shall only be called in non-secure usecases.
+     *
+     * \param   length      length of the content
+     * \return  true        if successful
+     *          false       otherwise.
+     */
+    bool copyDecryptedContentFromMemory(size_t length);
+
+    /**
+     * Return native handle of secure buffer understood by ICrypto.
+     *
+     * \return secure buffer handle
+     */
+    native_handle_t *handle() const;
+
+private:
+
+    std::shared_ptr<C2LinearBlock> mBlock;
+    sp<IMemory> mMemory;
+    sp<hardware::HidlMemory> mHidlMemory;
+    int32_t mHeapSeqNum;
+};
+
+}  // namespace android
+
+#endif  // CODEC2_BUFFER_H_
diff --git a/media/codec2/sfplugin/Codec2InfoBuilder.cpp b/media/codec2/sfplugin/Codec2InfoBuilder.cpp
new file mode 100644
index 0000000..6b75eba
--- /dev/null
+++ b/media/codec2/sfplugin/Codec2InfoBuilder.cpp
@@ -0,0 +1,560 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2InfoBuilder"
+#include <log/log.h>
+
+#include <strings.h>
+
+#include <C2Component.h>
+#include <C2Config.h>
+#include <C2Debug.h>
+#include <C2PlatformSupport.h>
+#include <Codec2Mapper.h>
+
+#include <OMX_Audio.h>
+#include <OMX_AudioExt.h>
+#include <OMX_IndexExt.h>
+#include <OMX_Types.h>
+#include <OMX_Video.h>
+#include <OMX_VideoExt.h>
+#include <OMX_AsString.h>
+
+#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <android/hardware/media/omx/1.0/IOmxObserver.h>
+#include <android/hardware/media/omx/1.0/IOmxNode.h>
+#include <android/hardware/media/omx/1.0/types.h>
+
+#include <android-base/properties.h>
+#include <codec2/hidl/client.h>
+#include <cutils/native_handle.h>
+#include <media/omx/1.0/WOmxNode.h>
+#include <media/stagefright/MediaCodecConstants.h>
+#include <media/stagefright/foundation/ALookup.h>
+#include <media/stagefright/foundation/MediaDefs.h>
+#include <media/stagefright/omx/OMXUtils.h>
+#include <media/stagefright/xmlparser/MediaCodecsXmlParser.h>
+
+#include "Codec2InfoBuilder.h"
+
+namespace android {
+
+using Traits = C2Component::Traits;
+
+namespace /* unnamed */ {
+
+bool hasPrefix(const std::string& s, const char* prefix) {
+    size_t prefixLen = strlen(prefix);
+    return s.compare(0, prefixLen, prefix) == 0;
+}
+
+bool hasSuffix(const std::string& s, const char* suffix) {
+    size_t suffixLen = strlen(suffix);
+    return suffixLen > s.size() ? false :
+            s.compare(s.size() - suffixLen, suffixLen, suffix) == 0;
+}
+
+void addSupportedProfileLevels(
+        std::shared_ptr<Codec2Client::Interface> intf,
+        MediaCodecInfo::CapabilitiesWriter *caps,
+        const Traits& trait, const std::string &mediaType) {
+    std::shared_ptr<C2Mapper::ProfileLevelMapper> mapper =
+        C2Mapper::GetProfileLevelMapper(trait.mediaType);
+    // if we don't know the media type, pass through all values unmapped
+
+    // TODO: we cannot find levels that are local 'maxima' without knowing the coding
+    // e.g. H.263 level 45 and level 30 could be two values for highest level as
+    // they don't include one another. For now we use the last supported value.
+    bool encoder = trait.kind == C2Component::KIND_ENCODER;
+    C2StreamProfileLevelInfo pl(encoder /* output */, 0u);
+    std::vector<C2FieldSupportedValuesQuery> profileQuery = {
+        C2FieldSupportedValuesQuery::Possible(C2ParamField(&pl, &pl.profile))
+    };
+
+    c2_status_t err = intf->querySupportedValues(profileQuery, C2_DONT_BLOCK);
+    ALOGV("query supported profiles -> %s | %s", asString(err), asString(profileQuery[0].status));
+    if (err != C2_OK || profileQuery[0].status != C2_OK) {
+        return;
+    }
+
+    // we only handle enumerated values
+    if (profileQuery[0].values.type != C2FieldSupportedValues::VALUES) {
+        return;
+    }
+
+    // determine if codec supports HDR
+    bool supportsHdr = false;
+    bool supportsHdr10Plus = false;
+
+    std::vector<std::shared_ptr<C2ParamDescriptor>> paramDescs;
+    c2_status_t err1 = intf->querySupportedParams(&paramDescs);
+    if (err1 == C2_OK) {
+        for (const std::shared_ptr<C2ParamDescriptor> &desc : paramDescs) {
+            switch ((uint32_t)desc->index()) {
+            case C2StreamHdr10PlusInfo::output::PARAM_TYPE:
+                supportsHdr10Plus = true;
+                break;
+            case C2StreamHdrStaticInfo::output::PARAM_TYPE:
+                supportsHdr = true;
+                break;
+            default:
+                break;
+            }
+        }
+    }
+
+    // For VP9, the static info is always propagated by framework.
+    supportsHdr |= (mediaType == MIMETYPE_VIDEO_VP9);
+
+    for (C2Value::Primitive profile : profileQuery[0].values.values) {
+        pl.profile = (C2Config::profile_t)profile.ref<uint32_t>();
+        std::vector<std::unique_ptr<C2SettingResult>> failures;
+        err = intf->config({&pl}, C2_DONT_BLOCK, &failures);
+        ALOGV("set profile to %u -> %s", pl.profile, asString(err));
+        std::vector<C2FieldSupportedValuesQuery> levelQuery = {
+            C2FieldSupportedValuesQuery::Current(C2ParamField(&pl, &pl.level))
+        };
+        err = intf->querySupportedValues(levelQuery, C2_DONT_BLOCK);
+        ALOGV("query supported levels -> %s | %s", asString(err), asString(levelQuery[0].status));
+        if (err != C2_OK || levelQuery[0].status != C2_OK
+                || levelQuery[0].values.type != C2FieldSupportedValues::VALUES
+                || levelQuery[0].values.values.size() == 0) {
+            continue;
+        }
+
+        C2Value::Primitive level = levelQuery[0].values.values.back();
+        pl.level = (C2Config::level_t)level.ref<uint32_t>();
+        ALOGV("supporting level: %u", pl.level);
+        int32_t sdkProfile, sdkLevel;
+        if (mapper && mapper->mapProfile(pl.profile, &sdkProfile)
+                && mapper->mapLevel(pl.level, &sdkLevel)) {
+            caps->addProfileLevel((uint32_t)sdkProfile, (uint32_t)sdkLevel);
+            // also list HDR profiles if component supports HDR
+            if (supportsHdr) {
+                auto hdrMapper = C2Mapper::GetHdrProfileLevelMapper(trait.mediaType);
+                if (hdrMapper && hdrMapper->mapProfile(pl.profile, &sdkProfile)) {
+                    caps->addProfileLevel((uint32_t)sdkProfile, (uint32_t)sdkLevel);
+                }
+                if (supportsHdr10Plus) {
+                    hdrMapper = C2Mapper::GetHdrProfileLevelMapper(
+                            trait.mediaType, true /*isHdr10Plus*/);
+                    if (hdrMapper && hdrMapper->mapProfile(pl.profile, &sdkProfile)) {
+                        caps->addProfileLevel((uint32_t)sdkProfile, (uint32_t)sdkLevel);
+                    }
+                }
+            }
+        } else if (!mapper) {
+            caps->addProfileLevel(pl.profile, pl.level);
+        }
+
+        // for H.263 also advertise the second highest level if the
+        // codec supports level 45, as level 45 only covers level 10
+        // TODO: move this to some form of a setting so it does not
+        // have to be here
+        if (mediaType == MIMETYPE_VIDEO_H263) {
+            C2Config::level_t nextLevel = C2Config::LEVEL_UNUSED;
+            for (C2Value::Primitive v : levelQuery[0].values.values) {
+                C2Config::level_t level = (C2Config::level_t)v.ref<uint32_t>();
+                if (level < C2Config::LEVEL_H263_45 && level > nextLevel) {
+                    nextLevel = level;
+                }
+            }
+            if (nextLevel != C2Config::LEVEL_UNUSED
+                    && nextLevel != pl.level
+                    && mapper
+                    && mapper->mapProfile(pl.profile, &sdkProfile)
+                    && mapper->mapLevel(nextLevel, &sdkLevel)) {
+                caps->addProfileLevel(
+                        (uint32_t)sdkProfile, (uint32_t)sdkLevel);
+            }
+        }
+    }
+}
+
+void addSupportedColorFormats(
+        std::shared_ptr<Codec2Client::Interface> intf,
+        MediaCodecInfo::CapabilitiesWriter *caps,
+        const Traits& trait, const std::string &mediaType) {
+    (void)intf;
+
+    // TODO: get this from intf() as well, but how do we map them to
+    // MediaCodec color formats?
+    bool encoder = trait.kind == C2Component::KIND_ENCODER;
+    if (mediaType.find("video") != std::string::npos
+            || mediaType.find("image") != std::string::npos) {
+        // vendor video codecs prefer opaque format
+        if (trait.name.find("android") == std::string::npos) {
+            caps->addColorFormat(COLOR_FormatSurface);
+        }
+        caps->addColorFormat(COLOR_FormatYUV420Flexible);
+        caps->addColorFormat(COLOR_FormatYUV420Planar);
+        caps->addColorFormat(COLOR_FormatYUV420SemiPlanar);
+        caps->addColorFormat(COLOR_FormatYUV420PackedPlanar);
+        caps->addColorFormat(COLOR_FormatYUV420PackedSemiPlanar);
+        // framework video encoders must support surface format, though it is unclear
+        // that they will be able to map it if it is opaque
+        if (encoder && trait.name.find("android") != std::string::npos) {
+            caps->addColorFormat(COLOR_FormatSurface);
+        }
+    }
+}
+
+class Switch {
+    enum Flags : uint8_t {
+        // flags
+        IS_ENABLED = (1 << 0),
+        BY_DEFAULT = (1 << 1),
+    };
+
+    constexpr Switch(uint8_t flags) : mFlags(flags) {}
+
+    uint8_t mFlags;
+
+public:
+    // have to create class due to this bool conversion operator...
+    constexpr operator bool() const {
+        return mFlags & IS_ENABLED;
+    }
+
+    constexpr Switch operator!() const {
+        return Switch(mFlags ^ IS_ENABLED);
+    }
+
+    static constexpr Switch DISABLED() { return 0; };
+    static constexpr Switch ENABLED() { return IS_ENABLED; };
+    static constexpr Switch DISABLED_BY_DEFAULT() { return BY_DEFAULT; };
+    static constexpr Switch ENABLED_BY_DEFAULT() { return IS_ENABLED | BY_DEFAULT; };
+
+    const char *toString(const char *def = "??") const {
+        switch (mFlags) {
+        case 0:                         return "0";
+        case IS_ENABLED:                return "1";
+        case BY_DEFAULT:                return "(0)";
+        case IS_ENABLED | BY_DEFAULT:   return "(1)";
+        default: return def;
+        }
+    }
+
+};
+
+const char *asString(const Switch &s, const char *def = "??") {
+    return s.toString(def);
+}
+
+Switch isSettingEnabled(
+        std::string setting, const MediaCodecsXmlParser::AttributeMap &settings,
+        Switch def = Switch::DISABLED_BY_DEFAULT()) {
+    const auto enablement = settings.find(setting);
+    if (enablement == settings.end()) {
+        return def;
+    }
+    return enablement->second == "1" ? Switch::ENABLED() : Switch::DISABLED();
+}
+
+Switch isVariantEnabled(
+        std::string variant, const MediaCodecsXmlParser::AttributeMap &settings) {
+    return isSettingEnabled("variant-" + variant, settings);
+}
+
+Switch isVariantExpressionEnabled(
+        std::string exp, const MediaCodecsXmlParser::AttributeMap &settings) {
+    if (!exp.empty() && exp.at(0) == '!') {
+        return !isVariantEnabled(exp.substr(1, exp.size() - 1), settings);
+    }
+    return isVariantEnabled(exp, settings);
+}
+
+Switch isDomainEnabled(
+        std::string domain, const MediaCodecsXmlParser::AttributeMap &settings) {
+    return isSettingEnabled("domain-" + domain, settings);
+}
+
+} // unnamed namespace
+
+status_t Codec2InfoBuilder::buildMediaCodecList(MediaCodecListWriter* writer) {
+    // TODO: Remove run-time configurations once all codecs are working
+    // properly. (Assume "full" behavior eventually.)
+    //
+    // debug.stagefright.ccodec supports 5 values.
+    //   0 - No Codec 2.0 components are available.
+    //   1 - Audio decoders and encoders with prefix "c2.android." are available
+    //       and ranked first.
+    //       All other components with prefix "c2.android." are available with
+    //       their normal ranks.
+    //       Components with prefix "c2.vda." are available with their normal
+    //       ranks.
+    //       All other components with suffix ".avc.decoder" or ".avc.encoder"
+    //       are available but ranked last.
+    //   2 - Components with prefix "c2.android." are available and ranked
+    //       first.
+    //       Components with prefix "c2.vda." are available with their normal
+    //       ranks.
+    //       All other components with suffix ".avc.decoder" or ".avc.encoder"
+    //       are available but ranked last.
+    //   3 - Components with prefix "c2.android." are available and ranked
+    //       first.
+    //       All other components are available with their normal ranks.
+    //   4 - All components are available with their normal ranks.
+    //
+    // The default value (boot time) is 1.
+    //
+    // Note: Currently, OMX components have default rank 0x100, while all
+    // Codec2.0 software components have default rank 0x200.
+    int option = ::android::base::GetIntProperty("debug.stagefright.ccodec", 4);
+
+    // Obtain Codec2Client
+    std::vector<Traits> traits = Codec2Client::ListComponents();
+
+    // parse APEX XML first, followed by vendor XML
+    MediaCodecsXmlParser parser;
+    parser.parseXmlFilesInSearchDirs(
+            parser.getDefaultXmlNames(),
+            { "/apex/com.android.media.swcodec/etc" });
+
+    // TODO: remove these c2-specific files once product moved to default file names
+    parser.parseXmlFilesInSearchDirs(
+            { "media_codecs_c2.xml", "media_codecs_performance_c2.xml" });
+
+    // parse default XML files
+    parser.parseXmlFilesInSearchDirs();
+
+    if (parser.getParsingStatus() != OK) {
+        ALOGD("XML parser no good");
+        return OK;
+    }
+
+    MediaCodecsXmlParser::AttributeMap settings = parser.getServiceAttributeMap();
+    for (const auto &v : settings) {
+        if (!hasPrefix(v.first, "media-type-")
+                && !hasPrefix(v.first, "domain-")
+                && !hasPrefix(v.first, "variant-")) {
+            writer->addGlobalSetting(v.first.c_str(), v.second.c_str());
+        }
+    }
+
+    for (const Traits& trait : traits) {
+        C2Component::rank_t rank = trait.rank;
+
+        // Interface must be accessible for us to list the component, and there also
+        // must be an XML entry for the codec. Codec aliases listed in the traits
+        // allow additional XML entries to be specified for each alias. These will
+        // be listed as separate codecs. If no XML entry is specified for an alias,
+        // those will be treated as an additional alias specified in the XML entry
+        // for the interface name.
+        std::vector<std::string> nameAndAliases = trait.aliases;
+        nameAndAliases.insert(nameAndAliases.begin(), trait.name);
+        for (const std::string &nameOrAlias : nameAndAliases) {
+            bool isAlias = trait.name != nameOrAlias;
+            std::shared_ptr<Codec2Client::Interface> intf =
+                Codec2Client::CreateInterfaceByName(nameOrAlias.c_str());
+            if (!intf) {
+                ALOGD("could not create interface for %s'%s'",
+                        isAlias ? "alias " : "",
+                        nameOrAlias.c_str());
+                continue;
+            }
+            if (parser.getCodecMap().count(nameOrAlias) == 0) {
+                if (isAlias) {
+                    std::unique_ptr<MediaCodecInfoWriter> baseCodecInfo =
+                        writer->findMediaCodecInfo(trait.name.c_str());
+                    if (!baseCodecInfo) {
+                        ALOGD("alias '%s' not found in xml but canonical codec info '%s' missing",
+                                nameOrAlias.c_str(),
+                                trait.name.c_str());
+                    } else {
+                        ALOGD("alias '%s' not found in xml; use an XML <Alias> tag for this",
+                                nameOrAlias.c_str());
+                        // merge alias into existing codec
+                        baseCodecInfo->addAlias(nameOrAlias.c_str());
+                    }
+                } else {
+                    ALOGD("component '%s' not found in xml", trait.name.c_str());
+                }
+                continue;
+            }
+            std::string canonName = trait.name;
+
+            // TODO: Remove this block once all codecs are enabled by default.
+            switch (option) {
+            case 0:
+                continue;
+            case 1:
+                if (hasPrefix(canonName, "c2.vda.")) {
+                    break;
+                }
+                if (hasPrefix(canonName, "c2.android.")) {
+                    if (trait.domain == C2Component::DOMAIN_AUDIO) {
+                        rank = 1;
+                        break;
+                    }
+                    break;
+                }
+                if (hasSuffix(canonName, ".avc.decoder") ||
+                        hasSuffix(canonName, ".avc.encoder")) {
+                    rank = std::numeric_limits<decltype(rank)>::max();
+                    break;
+                }
+                continue;
+            case 2:
+                if (hasPrefix(canonName, "c2.vda.")) {
+                    break;
+                }
+                if (hasPrefix(canonName, "c2.android.")) {
+                    rank = 1;
+                    break;
+                }
+                if (hasSuffix(canonName, ".avc.decoder") ||
+                        hasSuffix(canonName, ".avc.encoder")) {
+                    rank = std::numeric_limits<decltype(rank)>::max();
+                    break;
+                }
+                continue;
+            case 3:
+                if (hasPrefix(canonName, "c2.android.")) {
+                    rank = 1;
+                }
+                break;
+            }
+
+            const MediaCodecsXmlParser::CodecProperties &codec =
+                parser.getCodecMap().at(nameOrAlias);
+
+            // verify that either the codec is explicitly enabled, or one of its domains is
+            bool codecEnabled = codec.quirkSet.find("attribute::disabled") == codec.quirkSet.end();
+            if (!codecEnabled) {
+                for (const std::string &domain : codec.domainSet) {
+                    const Switch enabled = isDomainEnabled(domain, settings);
+                    ALOGV("codec entry '%s' is in domain '%s' that is '%s'",
+                            nameOrAlias.c_str(), domain.c_str(), asString(enabled));
+                    if (enabled) {
+                        codecEnabled = true;
+                        break;
+                    }
+                }
+            }
+            // if codec has variants, also check that at least one of them is enabled
+            bool variantEnabled = codec.variantSet.empty();
+            for (const std::string &variant : codec.variantSet) {
+                const Switch enabled = isVariantExpressionEnabled(variant, settings);
+                ALOGV("codec entry '%s' has a variant '%s' that is '%s'",
+                        nameOrAlias.c_str(), variant.c_str(), asString(enabled));
+                if (enabled) {
+                    variantEnabled = true;
+                    break;
+                }
+            }
+            if (!codecEnabled || !variantEnabled) {
+                ALOGD("codec entry for '%s' is disabled", nameOrAlias.c_str());
+                continue;
+            }
+
+            ALOGV("adding codec entry for '%s'", nameOrAlias.c_str());
+            std::unique_ptr<MediaCodecInfoWriter> codecInfo = writer->addMediaCodecInfo();
+            codecInfo->setName(nameOrAlias.c_str());
+            codecInfo->setOwner(("codec2::" + trait.owner).c_str());
+
+            bool encoder = trait.kind == C2Component::KIND_ENCODER;
+            typename std::underlying_type<MediaCodecInfo::Attributes>::type attrs = 0;
+
+            if (encoder) {
+                attrs |= MediaCodecInfo::kFlagIsEncoder;
+            }
+            if (trait.owner == "software") {
+                attrs |= MediaCodecInfo::kFlagIsSoftwareOnly;
+            } else {
+                attrs |= MediaCodecInfo::kFlagIsVendor;
+                if (trait.owner == "vendor-software") {
+                    attrs |= MediaCodecInfo::kFlagIsSoftwareOnly;
+                } else if (codec.quirkSet.find("attribute::software-codec")
+                        == codec.quirkSet.end()) {
+                    attrs |= MediaCodecInfo::kFlagIsHardwareAccelerated;
+                }
+            }
+            codecInfo->setAttributes(attrs);
+            if (!codec.rank.empty()) {
+                uint32_t xmlRank;
+                char dummy;
+                if (sscanf(codec.rank.c_str(), "%u%c", &xmlRank, &dummy) == 1) {
+                    rank = xmlRank;
+                }
+            }
+            ALOGV("rank: %u", (unsigned)rank);
+            codecInfo->setRank(rank);
+
+            for (const std::string &alias : codec.aliases) {
+                ALOGV("adding alias '%s'", alias.c_str());
+                codecInfo->addAlias(alias.c_str());
+            }
+
+            for (auto typeIt = codec.typeMap.begin(); typeIt != codec.typeMap.end(); ++typeIt) {
+                const std::string &mediaType = typeIt->first;
+                const Switch typeEnabled = isSettingEnabled(
+                        "media-type-" + mediaType, settings, Switch::ENABLED_BY_DEFAULT());
+                const Switch domainTypeEnabled = isSettingEnabled(
+                        "media-type-" + mediaType + (encoder ? "-encoder" : "-decoder"),
+                        settings, Switch::ENABLED_BY_DEFAULT());
+                ALOGV("type '%s-%s' is '%s/%s'",
+                        mediaType.c_str(), (encoder ? "encoder" : "decoder"),
+                        asString(typeEnabled), asString(domainTypeEnabled));
+                if (!typeEnabled || !domainTypeEnabled) {
+                    ALOGD("media type '%s' for codec entry '%s' is disabled", mediaType.c_str(),
+                            nameOrAlias.c_str());
+                    continue;
+                }
+
+                ALOGI("adding type '%s'", typeIt->first.c_str());
+                const MediaCodecsXmlParser::AttributeMap &attrMap = typeIt->second;
+                std::unique_ptr<MediaCodecInfo::CapabilitiesWriter> caps =
+                    codecInfo->addMediaType(mediaType.c_str());
+                for (const auto &v : attrMap) {
+                    std::string key = v.first;
+                    std::string value = v.second;
+
+                    size_t variantSep = key.find(":::");
+                    if (variantSep != std::string::npos) {
+                        std::string variant = key.substr(0, variantSep);
+                        const Switch enabled = isVariantExpressionEnabled(variant, settings);
+                        ALOGV("variant '%s' is '%s'", variant.c_str(), asString(enabled));
+                        if (!enabled) {
+                            continue;
+                        }
+                        key = key.substr(variantSep + 3);
+                    }
+
+                    if (key.find("feature-") == 0 && key.find("feature-bitrate-modes") != 0) {
+                        int32_t intValue = 0;
+                        // Ignore trailing bad characters and default to 0.
+                        (void)sscanf(value.c_str(), "%d", &intValue);
+                        caps->addDetail(key.c_str(), intValue);
+                    } else {
+                        caps->addDetail(key.c_str(), value.c_str());
+                    }
+                }
+
+                addSupportedProfileLevels(intf, caps.get(), trait, mediaType);
+                addSupportedColorFormats(intf, caps.get(), trait, mediaType);
+            }
+        }
+    }
+    return OK;
+}
+
+}  // namespace android
+
+extern "C" android::MediaCodecListBuilderBase *CreateBuilder() {
+    return new android::Codec2InfoBuilder;
+}
diff --git a/media/codec2/sfplugin/Codec2InfoBuilder.h b/media/codec2/sfplugin/Codec2InfoBuilder.h
new file mode 100644
index 0000000..30c189e
--- /dev/null
+++ b/media/codec2/sfplugin/Codec2InfoBuilder.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_INFO_BUILDER_H_
+#define CODEC2_INFO_BUILDER_H_
+
+#include <media/stagefright/MediaCodecList.h>
+#include <utils/Errors.h>
+
+namespace android {
+
+class Codec2InfoBuilder : public MediaCodecListBuilderBase {
+public:
+    Codec2InfoBuilder() = default;
+    ~Codec2InfoBuilder() override = default;
+    status_t buildMediaCodecList(MediaCodecListWriter* writer) override;
+};
+
+}  // namespace android
+
+#endif  // CODEC2_INFO_BUILDER_H_
diff --git a/media/codec2/sfplugin/InputSurfaceWrapper.h b/media/codec2/sfplugin/InputSurfaceWrapper.h
new file mode 100644
index 0000000..bb35763
--- /dev/null
+++ b/media/codec2/sfplugin/InputSurfaceWrapper.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INPUT_SURFACE_WRAPPER_H_
+#define INPUT_SURFACE_WRAPPER_H_
+
+#include <codec2/hidl/client.h>
+#include <system/graphics.h>
+
+namespace android {
+
+/**
+ * Wrapper interface around InputSurface.
+ */
+class InputSurfaceWrapper {
+public:
+    InputSurfaceWrapper()
+        : mDataSpace(HAL_DATASPACE_UNKNOWN) {
+    }
+
+    virtual ~InputSurfaceWrapper() = default;
+
+    /**
+     * Connect the surface with |comp|. A surface can
+     * connect to at most one component at a time.
+     *
+     * \return OK               successfully connected to |comp|
+     * \return ALREADY_EXISTS   already connected to another component.
+     */
+    virtual status_t connect(
+            const std::shared_ptr<Codec2Client::Component> &comp) = 0;
+
+    /**
+     * Disconnect the surface from the component if any.
+     */
+    virtual void disconnect() = 0;
+
+    /**
+     * Start pushing buffers to the surface.
+     */
+    virtual status_t start() = 0;
+
+    /**
+     * Ref: GraphicBufferSource::signalEndOfInputStream.
+     */
+    virtual status_t signalEndOfInputStream() = 0;
+
+    /// Input Surface configuration
+    struct Config {
+        // IN PARAMS (GBS)
+        float mMinFps; // minimum fps (repeat frame to achieve this)
+        float mMaxFps; // max fps (via frame drop)
+        float mCaptureFps; // capture fps
+        float mCodedFps;   // coded fps
+        bool mSuspended; // suspended
+        int64_t mTimeOffsetUs; // time offset (input => codec)
+        int64_t mSuspendAtUs; // suspend/resume time
+        int64_t mStartAtUs; // start time
+        bool mStopped; // stopped
+        int64_t mStopAtUs; // stop time
+
+        // OUT PARAMS (GBS)
+        int64_t mInputDelayUs; // delay between encoder input and surface input
+
+        // IN PARAMS (CODEC WRAPPER)
+        float mFixedAdjustedFps; // fixed fps via PTS manipulation
+        float mMinAdjustedFps; // minimum fps via PTS manipulation
+        uint64_t mUsage; // consumer usage
+    };
+
+    /**
+     * Configures input surface.
+     *
+     * \param config configuration. This can be updated during this call to provide output
+     *               parameters, but not to provide configured parameters (to avoid continually
+     *               reconfiguring)
+     */
+    virtual status_t configure(Config &config) = 0;
+
+    /**
+     * Configures desired data space.
+     *
+     * \param dataSpace desired data space
+     */
+    inline void setDataSpace(android_dataspace dataSpace) {
+        mDataSpace = dataSpace;
+    }
+
+    /**
+     * Clean up C2Work related references if necessary. No-op by default.
+     *
+     * \param index index of input work.
+     */
+    virtual void onInputBufferDone(c2_cntr64_t /* index */) {}
+
+protected:
+    android_dataspace mDataSpace;
+};
+
+}  // namespace android
+
+#endif  // INPUT_SURFACE_WRAPPER_H_
diff --git a/media/codec2/sfplugin/Omx2IGraphicBufferSource.cpp b/media/codec2/sfplugin/Omx2IGraphicBufferSource.cpp
new file mode 100644
index 0000000..764fa00
--- /dev/null
+++ b/media/codec2/sfplugin/Omx2IGraphicBufferSource.cpp
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef __LP64__
+#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
+#endif
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Omx2IGraphicBufferSource"
+#include <android-base/logging.h>
+
+#include "Omx2IGraphicBufferSource.h"
+
+#include <android/BnOMXBufferSource.h>
+#include <media/OMXBuffer.h>
+#include <media/stagefright/omx/OMXUtils.h>
+
+#include <OMX_Component.h>
+#include <OMX_Index.h>
+#include <OMX_IndexExt.h>
+
+namespace android {
+
+namespace /* unnamed */ {
+
+// OmxGraphicBufferSource -> IOMXBufferSource
+
+struct OmxGbs2IOmxBs : public BnOMXBufferSource {
+    sp<OmxGraphicBufferSource> mBase;
+    OmxGbs2IOmxBs(sp<OmxGraphicBufferSource> const& base) : mBase{base} {}
+    BnStatus onOmxExecuting() override {
+        return mBase->onOmxExecuting();
+    }
+    BnStatus onOmxIdle() override {
+        return mBase->onOmxIdle();
+    }
+    BnStatus onOmxLoaded() override {
+        return mBase->onOmxLoaded();
+    }
+    BnStatus onInputBufferAdded(int32_t bufferId) override {
+        return mBase->onInputBufferAdded(bufferId);
+    }
+    BnStatus onInputBufferEmptied(
+            int32_t bufferId,
+            OMXFenceParcelable const& fenceParcel) override {
+        return mBase->onInputBufferEmptied(bufferId, fenceParcel.get());
+    }
+};
+
+struct OmxNodeWrapper : public IOmxNodeWrapper {
+    sp<IOMXNode> mBase;
+    OmxNodeWrapper(sp<IOMXNode> const& base) : mBase{base} {}
+    status_t emptyBuffer(
+            int32_t bufferId, uint32_t flags,
+            const sp<GraphicBuffer> &buffer,
+            int64_t timestamp, int fenceFd) override {
+        return mBase->emptyBuffer(bufferId, buffer, flags, timestamp, fenceFd);
+    }
+    void dispatchDataSpaceChanged(
+            int32_t dataSpace, int32_t aspects, int32_t pixelFormat) override {
+        omx_message msg{};
+        msg.type = omx_message::EVENT;
+        msg.fenceFd = -1;
+        msg.u.event_data.event = OMX_EventDataSpaceChanged;
+        msg.u.event_data.data1 = dataSpace;
+        msg.u.event_data.data2 = aspects;
+        msg.u.event_data.data3 = pixelFormat;
+        mBase->dispatchMessage(msg);
+    }
+};
+
+} // unnamed namespace
+
+// Omx2IGraphicBufferSource
+Omx2IGraphicBufferSource::Omx2IGraphicBufferSource(
+        sp<OmxGraphicBufferSource> const& base)
+      : mBase{base},
+        mOMXBufferSource{new OmxGbs2IOmxBs(base)} {
+}
+
+BnStatus Omx2IGraphicBufferSource::setSuspend(
+        bool suspend, int64_t timeUs) {
+    return BnStatus::fromStatusT(mBase->setSuspend(suspend, timeUs));
+}
+
+BnStatus Omx2IGraphicBufferSource::setRepeatPreviousFrameDelayUs(
+        int64_t repeatAfterUs) {
+    return BnStatus::fromStatusT(mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs));
+}
+
+BnStatus Omx2IGraphicBufferSource::setMaxFps(float maxFps) {
+    return BnStatus::fromStatusT(mBase->setMaxFps(maxFps));
+}
+
+BnStatus Omx2IGraphicBufferSource::setTimeLapseConfig(
+        double fps, double captureFps) {
+    return BnStatus::fromStatusT(mBase->setTimeLapseConfig(fps, captureFps));
+}
+
+BnStatus Omx2IGraphicBufferSource::setStartTimeUs(
+        int64_t startTimeUs) {
+    return BnStatus::fromStatusT(mBase->setStartTimeUs(startTimeUs));
+}
+
+BnStatus Omx2IGraphicBufferSource::setStopTimeUs(
+        int64_t stopTimeUs) {
+    return BnStatus::fromStatusT(mBase->setStopTimeUs(stopTimeUs));
+}
+
+BnStatus Omx2IGraphicBufferSource::getStopTimeOffsetUs(
+        int64_t *stopTimeOffsetUs) {
+    return BnStatus::fromStatusT(mBase->getStopTimeOffsetUs(stopTimeOffsetUs));
+}
+
+BnStatus Omx2IGraphicBufferSource::setColorAspects(
+        int32_t aspects) {
+    return BnStatus::fromStatusT(mBase->setColorAspects(aspects));
+}
+
+BnStatus Omx2IGraphicBufferSource::setTimeOffsetUs(
+        int64_t timeOffsetsUs) {
+    return BnStatus::fromStatusT(mBase->setTimeOffsetUs(timeOffsetsUs));
+}
+
+BnStatus Omx2IGraphicBufferSource::signalEndOfInputStream() {
+    return BnStatus::fromStatusT(mBase->signalEndOfInputStream());
+}
+
+BnStatus Omx2IGraphicBufferSource::configure(
+        const sp<IOMXNode>& omxNode, int32_t dataSpace) {
+    if (omxNode == NULL) {
+        return BnStatus::fromServiceSpecificError(BAD_VALUE);
+    }
+
+    // Do setInputSurface() first, the node will try to enable metadata
+    // mode on input, and does necessary error checking. If this fails,
+    // we can't use this input surface on the node.
+    status_t err = omxNode->setInputSurface(mOMXBufferSource);
+    if (err != NO_ERROR) {
+        ALOGE("Unable to set input surface: %d", err);
+        return BnStatus::fromServiceSpecificError(err);
+    }
+
+    uint32_t consumerUsage;
+    if (omxNode->getParameter(
+            (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
+            &consumerUsage, sizeof(consumerUsage)) != OK) {
+        consumerUsage = 0;
+    }
+
+    OMX_PARAM_PORTDEFINITIONTYPE def;
+    InitOMXParams(&def);
+    def.nPortIndex = 0; // kPortIndexInput
+
+    err = omxNode->getParameter(
+            OMX_IndexParamPortDefinition, &def, sizeof(def));
+    if (err != NO_ERROR) {
+        ALOGE("Failed to get port definition: %d", err);
+        return BnStatus::fromServiceSpecificError(UNKNOWN_ERROR);
+    }
+
+    return BnStatus::fromStatusT(mBase->configure(
+            new OmxNodeWrapper(omxNode),
+            dataSpace,
+            def.nBufferCountActual,
+            def.format.video.nFrameWidth,
+            def.format.video.nFrameHeight,
+            consumerUsage));
+}
+
+} // namespace android
+
diff --git a/media/codec2/sfplugin/Omx2IGraphicBufferSource.h b/media/codec2/sfplugin/Omx2IGraphicBufferSource.h
new file mode 100644
index 0000000..20fd1ec
--- /dev/null
+++ b/media/codec2/sfplugin/Omx2IGraphicBufferSource.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OMX_2_IGRAPHICBUFFERSOURCE_H_
+#define OMX_2_IGRAPHICBUFFERSOURCE_H_
+
+#include <android/BnGraphicBufferSource.h>
+#include <media/stagefright/omx/OmxGraphicBufferSource.h>
+
+namespace android {
+
+using BnStatus = ::android::binder::Status;
+
+struct Omx2IGraphicBufferSource : public BnGraphicBufferSource {
+    sp<OmxGraphicBufferSource> mBase;
+    sp<IOMXBufferSource> mOMXBufferSource;
+    Omx2IGraphicBufferSource(sp<OmxGraphicBufferSource> const& base);
+    BnStatus configure(const sp<IOMXNode>& omxNode, int32_t dataSpace) override;
+    BnStatus setSuspend(bool suspend, int64_t timeUs) override;
+    BnStatus setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs) override;
+    BnStatus setMaxFps(float maxFps) override;
+    BnStatus setTimeLapseConfig(double fps, double captureFps) override;
+    BnStatus setStartTimeUs(int64_t startTimeUs) override;
+    BnStatus setStopTimeUs(int64_t stopTimeUs) override;
+    BnStatus getStopTimeOffsetUs(int64_t *stopTimeOffsetUs) override;
+    BnStatus setColorAspects(int32_t aspects) override;
+    BnStatus setTimeOffsetUs(int64_t timeOffsetsUs) override;
+    BnStatus signalEndOfInputStream() override;
+};
+
+} // namespace android
+
+#endif // OMX_2_IGRAPHICBUFFERSOURCE_H_
+
diff --git a/media/codec2/sfplugin/PipelineWatcher.cpp b/media/codec2/sfplugin/PipelineWatcher.cpp
new file mode 100644
index 0000000..74d14e8
--- /dev/null
+++ b/media/codec2/sfplugin/PipelineWatcher.cpp
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "PipelineWatcher"
+
+#include <numeric>
+
+#include <log/log.h>
+
+#include "PipelineWatcher.h"
+
+namespace android {
+
+PipelineWatcher &PipelineWatcher::inputDelay(uint32_t value) {
+    mInputDelay = value;
+    return *this;
+}
+
+PipelineWatcher &PipelineWatcher::pipelineDelay(uint32_t value) {
+    mPipelineDelay = value;
+    return *this;
+}
+
+PipelineWatcher &PipelineWatcher::outputDelay(uint32_t value) {
+    mOutputDelay = value;
+    return *this;
+}
+
+PipelineWatcher &PipelineWatcher::smoothnessFactor(uint32_t value) {
+    mSmoothnessFactor = value;
+    return *this;
+}
+
+void PipelineWatcher::onWorkQueued(
+        uint64_t frameIndex,
+        std::vector<std::shared_ptr<C2Buffer>> &&buffers,
+        const Clock::time_point &queuedAt) {
+    ALOGV("onWorkQueued(frameIndex=%llu, buffers(size=%zu), queuedAt=%lld)",
+          (unsigned long long)frameIndex,
+          buffers.size(),
+          (long long)queuedAt.time_since_epoch().count());
+    auto it = mFramesInPipeline.find(frameIndex);
+    if (it != mFramesInPipeline.end()) {
+        ALOGD("onWorkQueued: Duplicate frame index (%llu); previous entry removed",
+              (unsigned long long)frameIndex);
+        (void)mFramesInPipeline.erase(it);
+    }
+    (void)mFramesInPipeline.try_emplace(frameIndex, std::move(buffers), queuedAt);
+}
+
+std::shared_ptr<C2Buffer> PipelineWatcher::onInputBufferReleased(
+        uint64_t frameIndex, size_t arrayIndex) {
+    ALOGV("onInputBufferReleased(frameIndex=%llu, arrayIndex=%zu)",
+          (unsigned long long)frameIndex, arrayIndex);
+    auto it = mFramesInPipeline.find(frameIndex);
+    if (it == mFramesInPipeline.end()) {
+        ALOGD("onInputBufferReleased: frameIndex not found (%llu); ignored",
+              (unsigned long long)frameIndex);
+        return nullptr;
+    }
+    if (it->second.buffers.size() <= arrayIndex) {
+        ALOGD("onInputBufferReleased: buffers at %llu: size %zu, requested index: %zu",
+              (unsigned long long)frameIndex, it->second.buffers.size(), arrayIndex);
+        return nullptr;
+    }
+    std::shared_ptr<C2Buffer> buffer(std::move(it->second.buffers[arrayIndex]));
+    ALOGD_IF(!buffer, "onInputBufferReleased: buffer already released (%llu:%zu)",
+             (unsigned long long)frameIndex, arrayIndex);
+    return buffer;
+}
+
+void PipelineWatcher::onWorkDone(uint64_t frameIndex) {
+    ALOGV("onWorkDone(frameIndex=%llu)", (unsigned long long)frameIndex);
+    auto it = mFramesInPipeline.find(frameIndex);
+    if (it == mFramesInPipeline.end()) {
+        ALOGD("onWorkDone: frameIndex not found (%llu); ignored",
+              (unsigned long long)frameIndex);
+        return;
+    }
+    (void)mFramesInPipeline.erase(it);
+}
+
+void PipelineWatcher::flush() {
+    mFramesInPipeline.clear();
+}
+
+bool PipelineWatcher::pipelineFull() const {
+    if (mFramesInPipeline.size() >=
+            mInputDelay + mPipelineDelay + mOutputDelay + mSmoothnessFactor) {
+        ALOGV("pipelineFull: too many frames in pipeline (%zu)", mFramesInPipeline.size());
+        return true;
+    }
+    size_t sizeWithInputReleased = std::count_if(
+            mFramesInPipeline.begin(),
+            mFramesInPipeline.end(),
+            [](const decltype(mFramesInPipeline)::value_type &value) {
+                for (const std::shared_ptr<C2Buffer> &buffer : value.second.buffers) {
+                    if (buffer) {
+                        return false;
+                    }
+                }
+                return true;
+            });
+    if (sizeWithInputReleased >=
+            mPipelineDelay + mOutputDelay + mSmoothnessFactor) {
+        ALOGV("pipelineFull: too many frames in pipeline, with input released (%zu)",
+              sizeWithInputReleased);
+        return true;
+    }
+
+    size_t sizeWithInputsPending = mFramesInPipeline.size() - sizeWithInputReleased;
+    if (sizeWithInputsPending > mPipelineDelay + mInputDelay + mSmoothnessFactor) {
+        ALOGV("pipelineFull: too many inputs pending (%zu) in pipeline, with inputs released (%zu)",
+              sizeWithInputsPending, sizeWithInputReleased);
+        return true;
+    }
+    ALOGV("pipeline has room (total: %zu, input released: %zu)",
+          mFramesInPipeline.size(), sizeWithInputReleased);
+    return false;
+}
+
+PipelineWatcher::Clock::duration PipelineWatcher::elapsed(
+        const PipelineWatcher::Clock::time_point &now, size_t n) const {
+    if (mFramesInPipeline.size() <= n) {
+        return Clock::duration::zero();
+    }
+    std::vector<Clock::duration> durations;
+    for (const decltype(mFramesInPipeline)::value_type &value : mFramesInPipeline) {
+        Clock::duration elapsed = now - value.second.queuedAt;
+        ALOGV("elapsed: frameIndex = %llu elapsed = %lldms",
+              (unsigned long long)value.first,
+              std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count());
+        durations.push_back(elapsed);
+    }
+    std::nth_element(durations.begin(), durations.end(), durations.begin() + n,
+                     std::greater<Clock::duration>());
+    return durations[n];
+}
+
+}  // namespace android
diff --git a/media/codec2/sfplugin/PipelineWatcher.h b/media/codec2/sfplugin/PipelineWatcher.h
new file mode 100644
index 0000000..1e23147
--- /dev/null
+++ b/media/codec2/sfplugin/PipelineWatcher.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PIPELINE_WATCHER_H_
+#define PIPELINE_WATCHER_H_
+
+#include <chrono>
+#include <map>
+#include <memory>
+
+#include <C2Work.h>
+
+namespace android {
+
+/**
+ * PipelineWatcher watches the pipeline and infers the status of work items from
+ * events.
+ */
+class PipelineWatcher {
+public:
+    typedef std::chrono::steady_clock Clock;
+
+    PipelineWatcher()
+        : mInputDelay(0),
+          mPipelineDelay(0),
+          mOutputDelay(0),
+          mSmoothnessFactor(0) {}
+    ~PipelineWatcher() = default;
+
+    /**
+     * \param value the new input delay value
+     * \return  this object
+     */
+    PipelineWatcher &inputDelay(uint32_t value);
+
+    /**
+     * \param value the new pipeline delay value
+     * \return  this object
+     */
+    PipelineWatcher &pipelineDelay(uint32_t value);
+
+    /**
+     * \param value the new output delay value
+     * \return  this object
+     */
+    PipelineWatcher &outputDelay(uint32_t value);
+
+    /**
+     * \param value the new smoothness factor value
+     * \return  this object
+     */
+    PipelineWatcher &smoothnessFactor(uint32_t value);
+
+    /**
+     * Client queued a work item to the component.
+     *
+     * \param frameIndex  input frame index of this work
+     * \param buffers     input buffers of the queued work item
+     * \param queuedAt    time when the client queued the buffer
+     */
+    void onWorkQueued(
+            uint64_t frameIndex,
+            std::vector<std::shared_ptr<C2Buffer>> &&buffers,
+            const Clock::time_point &queuedAt);
+
+    /**
+     * The component released input buffers from a work item.
+     *
+     * \param frameIndex  input frame index
+     * \param arrayIndex  index of the buffer at the original |buffers| in
+     *                    onWorkQueued().
+     * \return  buffers[arrayIndex]
+     */
+    std::shared_ptr<C2Buffer> onInputBufferReleased(
+            uint64_t frameIndex, size_t arrayIndex);
+
+    /**
+     * The component finished processing a work item.
+     *
+     * \param frameIndex  input frame index
+     */
+    void onWorkDone(uint64_t frameIndex);
+
+    /**
+     * Flush the pipeline.
+     */
+    void flush();
+
+    /**
+     * \return  true  if pipeline does not need more work items to proceed
+     *                smoothly, considering delays and smoothness factor;
+     *          false otherwise.
+     */
+    bool pipelineFull() const;
+
+    /**
+     * Return elapsed processing time of a work item, nth from the longest
+     * processing time to the shortest.
+     *
+     * \param now current timestamp
+     * \param n   nth work item, from the longest processing time to the
+     *            shortest. It's a 0-based index.
+     * \return  elapsed processing time of nth work item.
+     */
+    Clock::duration elapsed(const Clock::time_point &now, size_t n) const;
+
+private:
+    uint32_t mInputDelay;
+    uint32_t mPipelineDelay;
+    uint32_t mOutputDelay;
+    uint32_t mSmoothnessFactor;
+
+    struct Frame {
+        Frame(std::vector<std::shared_ptr<C2Buffer>> &&b,
+              const Clock::time_point &q)
+            : buffers(b),
+              queuedAt(q) {}
+        std::vector<std::shared_ptr<C2Buffer>> buffers;
+        const Clock::time_point queuedAt;
+    };
+    std::map<uint64_t, Frame> mFramesInPipeline;
+};
+
+}  // namespace android
+
+#endif  // PIPELINE_WATCHER_H_
diff --git a/media/codec2/sfplugin/ReflectedParamUpdater.cpp b/media/codec2/sfplugin/ReflectedParamUpdater.cpp
new file mode 100644
index 0000000..55b0ec9
--- /dev/null
+++ b/media/codec2/sfplugin/ReflectedParamUpdater.cpp
@@ -0,0 +1,582 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ReflectedParamUpdater"
+#include <utils/Log.h>
+
+#include <iostream>
+#include <set>
+#include <sstream>
+
+#include <C2Debug.h>
+#include <C2ParamInternal.h>
+
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AString.h>
+#include <media/stagefright/foundation/hexdump.h>
+
+#include "ReflectedParamUpdater.h"
+
+namespace android {
+
+std::string ReflectedParamUpdater::Dict::debugString(size_t indent_) const {
+    std::string indent(indent_, ' ');
+    std::stringstream s;
+    s << "Dict {" << std::endl;
+
+    for (const auto &it : *this) {
+        s << indent << "  ";
+
+        C2Value c2Value;
+        int32_t int32Value;
+        uint32_t uint32Value;
+        int64_t int64Value;
+        uint64_t uint64Value;
+        float floatValue;
+        sp<ABuffer> bufValue;
+        AString strValue;
+        if (it.second.find(&c2Value)) {
+            switch (c2Value.type()) {
+                case C2Value::INT32:
+                    (void)c2Value.get(&int32Value);
+                    s << "c2::i32 " << it.first << " = " << int32Value;
+                    break;
+                case C2Value::UINT32:
+                    (void)c2Value.get(&uint32Value);
+                    s << "c2::u32 " << it.first << " = " << uint32Value;
+                    break;
+                case C2Value::CNTR32:
+                    // dump counter value as unsigned
+                    (void)c2Value.get((c2_cntr32_t*)&uint32Value);
+                    s << "c2::c32 " << it.first << " = " << uint32Value;
+                    break;
+                case C2Value::INT64:
+                    (void)c2Value.get(&int64Value);
+                    s << "c2::i64 " << it.first << " = " << int64Value;
+                    break;
+                case C2Value::UINT64:
+                    (void)c2Value.get(&uint64Value);
+                    s << "c2::u64 " << it.first << " = " << uint64Value;
+                    break;
+                case C2Value::CNTR64:
+                    // dump counter value as unsigned
+                    (void)c2Value.get((c2_cntr64_t*)&uint64Value);
+                    s << "c2::c64 " << it.first << " = " << uint64Value;
+                    break;
+                case C2Value::FLOAT:
+                    (void)c2Value.get(&floatValue);
+                    s << "c2::float " << it.first << " = " << floatValue;
+                    break;
+                default:
+                    // dump unsupported values for debugging, these should not be used
+                    s << "c2::unsupported " << it.first;
+            }
+        } else if (it.second.find(&int32Value)) {
+            s << "int32_t " << it.first << " = " << int32Value;
+        } else if (it.second.find(&int64Value)) {
+            s << "int64_t " << it.first << " = " << int64Value;
+        } else if (it.second.find(&strValue)) {
+            s << "string " << it.first << " = \"" << strValue.c_str() << "\"";
+        } else if (it.second.find(&bufValue)) {
+            s << "Buffer " << it.first << " = ";
+            if (bufValue != nullptr && bufValue->data() != nullptr && bufValue->size() <= 64) {
+                s << "{" << std::endl;
+                AString tmp;
+                hexdump(bufValue->data(), bufValue->size(), indent_ + 4, &tmp);
+                s << tmp.c_str() << indent << "  }";
+            } else {
+                s << (void*)bufValue.get();
+            }
+        } else {
+            // dump unsupported values for debugging, this should never happen.
+            s << "unsupported " << it.first;
+        }
+        s << std::endl;
+    }
+    s << indent << "}";
+
+    return s.str();
+}
+
+void ReflectedParamUpdater::addParamDesc(
+        const std::shared_ptr<C2ParamReflector> &reflector,
+        const std::vector<std::shared_ptr<C2ParamDescriptor>> &paramDescs) {
+    for (const std::shared_ptr<C2ParamDescriptor> &desc : paramDescs) {
+        std::unique_ptr<C2StructDescriptor> structDesc = reflector->describe(
+                desc->index().coreIndex());
+        if (structDesc == nullptr) {
+            ALOGD("Could not describe %s", desc->name().c_str());
+            continue;
+        }
+        addParamDesc(desc, *structDesc, reflector, true /* markVendor */);
+    }
+
+    // TEMP: also add vendor parameters as non-vendor
+    for (const std::shared_ptr<C2ParamDescriptor> &desc : paramDescs) {
+        if (!desc->index().isVendor()) {
+            continue;
+        }
+        std::unique_ptr<C2StructDescriptor> structDesc = reflector->describe(
+                desc->index().coreIndex());
+        if (structDesc) {
+            addParamDesc(desc, *structDesc, reflector, false /* markVendor */);
+        }
+    }
+}
+
+void ReflectedParamUpdater::addParamStructDesc(
+        std::shared_ptr<C2ParamDescriptor> desc,
+        C2String path,
+        size_t offset,
+        const C2StructDescriptor &structDesc,
+        const std::shared_ptr<C2ParamReflector> &reflector) {
+    for (auto it = structDesc.begin(); it != structDesc.end(); ++it) {
+        C2String fieldName = path + "." + it->name();
+        if (it->type() & C2FieldDescriptor::STRUCT_FLAG) {
+            if (reflector == nullptr || it->extent() != 1) {
+                ALOGD("ignored struct field %s", fieldName.c_str());
+                continue;
+            }
+            std::unique_ptr<C2StructDescriptor> structDesc_ = reflector->describe(
+                    C2Param::CoreIndex(it->type()).coreIndex());
+            if (structDesc_ == nullptr) {
+                ALOGD("Could not describe structure of %s", fieldName.c_str());
+                continue;
+            }
+            addParamStructDesc(desc, fieldName, offset + _C2ParamInspector::GetOffset(*it),
+                               *structDesc_, reflector);
+            continue;
+        }
+
+        // verify extent and type
+        switch (it->type()) {
+            case C2FieldDescriptor::INT32:
+            case C2FieldDescriptor::UINT32:
+            case C2FieldDescriptor::CNTR32:
+            case C2FieldDescriptor::INT64:
+            case C2FieldDescriptor::UINT64:
+            case C2FieldDescriptor::CNTR64:
+            case C2FieldDescriptor::FLOAT:
+                if (it->extent() != 1) {
+                    ALOGD("extent() != 1 for single value type: %s", fieldName.c_str());
+                    continue;
+                }
+                break;
+            case C2FieldDescriptor::STRING:
+            case C2FieldDescriptor::BLOB:
+                break;
+
+            default:
+                ALOGD("Unrecognized type: %s", fieldName.c_str());
+                continue;
+        }
+
+        ALOGV("%s registered", fieldName.c_str());
+        // TODO: get the proper size by iterating through the fields.
+        // only insert fields the very first time
+        mMap.emplace(fieldName, FieldDesc {
+            desc,
+            std::make_unique<C2FieldDescriptor>(
+                    it->type(), it->extent(), it->name(),
+                    _C2ParamInspector::GetOffset(*it),
+                    _C2ParamInspector::GetSize(*it)),
+            offset,
+        });
+    }
+}
+
+void ReflectedParamUpdater::addParamDesc(
+        std::shared_ptr<C2ParamDescriptor> desc, const C2StructDescriptor &structDesc,
+        const std::shared_ptr<C2ParamReflector> &reflector, bool markVendor) {
+    C2String paramName = desc->name();
+
+    // Do not reflect requested parameters
+    // TODO: split these once aliases are introduced into '.actual' and '.requested' and alias
+    // the name to '.actual'.
+    if (desc->index() & C2Param::CoreIndex::IS_REQUEST_FLAG) {
+        return;
+    }
+
+    // prefix vendor parameters
+    if (desc->index().isVendor() && markVendor) {
+        paramName = "vendor." + paramName;
+    }
+    mParamNames.emplace(desc->index(), paramName);
+
+    // also allow setting whole parameters in a binary fashion via ByteBuffer
+    // this is opt-in for now
+    auto it = mWholeParams.find(paramName);
+    if (it != mWholeParams.end() && it->second.coreIndex() == desc->index().coreIndex()) {
+        mMap.emplace(paramName, FieldDesc{ desc, nullptr, 0 /* offset */ });
+        // don't add fields of whole parameters.
+        return;
+    }
+
+    addParamStructDesc(desc, paramName, 0 /* offset */, structDesc, reflector);
+}
+
+void ReflectedParamUpdater::supportWholeParam(std::string name, C2Param::CoreIndex index) {
+    mWholeParams.emplace(name, index);
+}
+
+std::string ReflectedParamUpdater::getParamName(C2Param::Index index) const {
+    auto it = mParamNames.find(index);
+    if (it != mParamNames.end()) {
+        return it->second;
+    }
+
+    std::stringstream ret;
+    ret << "<unknown " << index << ">";
+    return ret.str();
+}
+
+void ReflectedParamUpdater::getParamIndicesFromMessage(
+        const Dict &params,
+        std::vector<C2Param::Index> *vec /* nonnull */) const {
+    CHECK(vec != nullptr);
+    vec->clear();
+    std::set<C2Param::Index> indices;
+    parseMessageAndDoWork(
+            params,
+            [&indices](const std::string &, const FieldDesc &desc, const void *, size_t) {
+                indices.insert(desc.paramDesc->index());
+            });
+    for (const C2Param::Index &index : indices) {
+        vec->push_back(index);
+    }
+}
+
+void ReflectedParamUpdater::getParamIndicesForKeys(
+        const std::vector<std::string> &keys,
+        std::vector<C2Param::Index> *vec /* nonnull */) const {
+    CHECK(vec != nullptr);
+    vec->clear();
+    std::set<C2Param::Index> indices;
+
+    std::set<std::string> keyMap(keys.begin(), keys.end());
+
+    ALOGV("in getParamIndicesForKeys with %zu keys and map of %zu entries",
+            keyMap.size(), mMap.size());
+    for (const std::pair<const std::string, FieldDesc> &kv : mMap) {
+        const std::string &name = kv.first;
+        const FieldDesc &desc = kv.second;
+        ALOGV("count of %s is %zu", name.c_str(), keyMap.count(name));
+        if (keyMap.count(name) > 0) {
+            indices.insert(desc.paramDesc->index());
+        }
+    }
+
+    for (const C2Param::Index &index : indices) {
+        vec->push_back(index);
+    }
+}
+
+void ReflectedParamUpdater::updateParamsFromMessage(
+        const Dict &params,
+        std::vector<std::unique_ptr<C2Param>> *vec /* nonnull */) const {
+    CHECK(vec != nullptr);
+
+    std::map<C2Param::Index, std::unique_ptr<C2Param>*> paramsMap;
+    for (std::unique_ptr<C2Param> &param : *vec) {
+        if (param && *param) {
+            paramsMap[param->index()] = &param;
+        }
+    }
+
+    parseMessageAndDoWork(
+            params,
+            [&paramsMap](const std::string &name, const FieldDesc &desc, const void *ptr, size_t size) {
+                std::unique_ptr<C2Param> *param = nullptr;
+                auto paramIt = paramsMap.find(desc.paramDesc->index());
+                if (paramIt == paramsMap.end()) {
+                    ALOGD("%s found, but param #%d isn't present to update",
+                            name.c_str(), (int32_t)desc.paramDesc->index());
+                    return;
+                }
+                param = paramIt->second;
+
+                struct _C2Param : public C2Param {
+                    using C2Param::C2Param;
+                    _C2Param(uint32_t size, uint32_t index) : C2Param(size, index) { }
+                };
+
+                // we will handle whole param updates as part of a flexible param update using
+                // a zero offset.
+                size_t offset = 0;
+                size_t minOffset = 0;
+
+                // if this descriptor has a field, use the offset and size and ensure that offset
+                // is not part of the header
+                if (desc.fieldDesc) {
+                    minOffset = sizeof(C2Param);
+                    offset = sizeof(C2Param) + desc.offset
+                            + _C2ParamInspector::GetOffset(*desc.fieldDesc);
+                }
+
+                // reallocate or trim flexible param (or whole param) as necessary
+                if (!desc.fieldDesc /* whole param */ || desc.fieldDesc->extent() == 0) {
+                    // reallocate param if more space is needed
+                    if (param->get()->size() < offset + size) {
+                        if (size > INT32_MAX - offset || offset < minOffset) {
+                            // size too long or offset too early - abandon
+                            return;
+                        }
+                        C2Param *newParam = (C2Param *)::operator new(offset + size);
+                        new (newParam) _C2Param(offset + size, param->get()->index());
+                        if (offset > sizeof(C2Param)) {
+                            memcpy(newParam + 1, param->get() + 1, offset - sizeof(C2Param));
+                        }
+                        param->reset(newParam);
+                    } else if (param->get()->size() > offset + size) {
+                        // trim parameter size
+                        _C2ParamInspector::TrimParam(param->get(), offset + size);
+                    }
+                } else if (desc.fieldDesc->type() == C2FieldDescriptor::BLOB) {
+                    // zero fill blobs if updating with smaller blob
+                    if (desc.fieldDesc->extent() > size) {
+                        memset((uint8_t *)(param->get()) + offset + size, 0,
+                               desc.fieldDesc->extent() - size);
+                    }
+                }
+
+                memcpy((uint8_t *)(param->get()) + offset, ptr, size);
+            });
+}
+
+void ReflectedParamUpdater::parseMessageAndDoWork(
+        const Dict &params,
+        std::function<void(const std::string &, const FieldDesc &, const void *, size_t)> work) const {
+    for (const std::pair<const std::string, FieldDesc> &kv : mMap) {
+        const std::string &name = kv.first;
+        const FieldDesc &desc = kv.second;
+        auto param = params.find(name);
+        if (param == params.end()) {
+            continue;
+        }
+
+        // handle whole parameters
+        if (!desc.fieldDesc) {
+            sp<ABuffer> tmp;
+            if (param->second.find(&tmp) && tmp != nullptr) {
+                C2Param *tmpAsParam = C2Param::From(tmp->data(), tmp->size());
+                if (tmpAsParam && tmpAsParam->type().type() == desc.paramDesc->index().type()) {
+                    work(name, desc, tmp->data(), tmp->size());
+                } else {
+                    ALOGD("Param blob does not match param for '%s' (%p, %x vs %x)",
+                            name.c_str(), tmpAsParam, tmpAsParam ? tmpAsParam->type().type() : 0xDEADu,
+                            desc.paramDesc->index().type());
+                }
+            }
+            continue;
+        }
+
+        int32_t int32Value;
+        int64_t int64Value;
+        C2Value c2Value;
+
+        C2FieldDescriptor::type_t fieldType = desc.fieldDesc->type();
+        size_t fieldExtent = desc.fieldDesc->extent();
+        switch (fieldType) {
+            case C2FieldDescriptor::INT32:
+                if ((param->second.find(&c2Value) && c2Value.get(&int32Value))
+                        || param->second.find(&int32Value)) {
+                    work(name, desc, &int32Value, sizeof(int32Value));
+                }
+                break;
+            case C2FieldDescriptor::UINT32:
+                if ((param->second.find(&c2Value) && c2Value.get((uint32_t*)&int32Value))
+                        || param->second.find(&int32Value)) {
+                    work(name, desc, &int32Value, sizeof(int32Value));
+                }
+                break;
+            case C2FieldDescriptor::CNTR32:
+                if ((param->second.find(&c2Value) && c2Value.get((c2_cntr32_t*)&int32Value))
+                        || param->second.find(&int32Value)) {
+                    work(name, desc, &int32Value, sizeof(int32Value));
+                }
+                break;
+            case C2FieldDescriptor::INT64:
+                if ((param->second.find(&c2Value) && c2Value.get(&int64Value))
+                        || param->second.find(&int64Value)) {
+                    work(name, desc, &int64Value, sizeof(int64Value));
+                }
+                break;
+            case C2FieldDescriptor::UINT64:
+                if ((param->second.find(&c2Value) && c2Value.get((uint64_t*)&int64Value))
+                        || param->second.find(&int64Value)) {
+                    work(name, desc, &int64Value, sizeof(int64Value));
+                }
+                break;
+            case C2FieldDescriptor::CNTR64:
+                if ((param->second.find(&c2Value) && c2Value.get((c2_cntr64_t*)&int64Value))
+                        || param->second.find(&int64Value)) {
+                    work(name, desc, &int64Value, sizeof(int64Value));
+                }
+                break;
+            case C2FieldDescriptor::FLOAT: {
+                float tmp;
+                if (param->second.find(&c2Value) && c2Value.get(&tmp)) {
+                    work(name, desc, &tmp, sizeof(tmp));
+                }
+                break;
+            }
+            case C2FieldDescriptor::STRING: {
+                AString tmp;
+                if (!param->second.find(&tmp)) {
+                    break;
+                }
+                if (fieldExtent > 0 && tmp.size() >= fieldExtent) {
+                    AString truncated(tmp, 0, fieldExtent - 1);
+                    ALOGD("String value too long to fit: original \"%s\" truncated to \"%s\"",
+                            tmp.c_str(), truncated.c_str());
+                    tmp = truncated;
+                }
+                work(name, desc, tmp.c_str(), tmp.size() + 1);
+                break;
+            }
+
+            case C2FieldDescriptor::BLOB: {
+                sp<ABuffer> tmp;
+                if (!param->second.find(&tmp) || tmp == nullptr) {
+                    break;
+                }
+
+                if (fieldExtent > 0 && tmp->size() > fieldExtent) {
+                    ALOGD("Blob value too long to fit. Truncating.");
+                    tmp->setRange(tmp->offset(), fieldExtent);
+                }
+                work(name, desc, tmp->data(), tmp->size());
+                break;
+            }
+
+            default:
+                ALOGD("Unsupported data type for %s", name.c_str());
+                break;
+        }
+    }
+}
+
+ReflectedParamUpdater::Dict
+ReflectedParamUpdater::getParams(const std::vector<std::unique_ptr<C2Param>> &params_) const {
+    std::vector<C2Param*> params;
+    params.resize(params_.size());
+    std::transform(params_.begin(), params_.end(), params.begin(),
+                   [](const std::unique_ptr<C2Param>& p) -> C2Param* { return p.get(); });
+    return getParams(params);
+}
+
+ReflectedParamUpdater::Dict
+ReflectedParamUpdater::getParams(const std::vector<C2Param*> &params) const {
+    Dict ret;
+
+    // convert vector to map
+    std::map<C2Param::Index, C2Param *> paramsMap;
+    for (C2Param *param : params) {
+        if (param != nullptr && *param) {
+            paramsMap[param->index()] = param;
+        }
+    }
+
+    for (const std::pair<const std::string, FieldDesc> &kv : mMap) {
+        const std::string &name = kv.first;
+        const FieldDesc &desc = kv.second;
+        if (paramsMap.count(desc.paramDesc->index()) == 0) {
+            continue;
+        }
+        C2Param *param = paramsMap[desc.paramDesc->index()];
+        Value value;
+
+        // handle whole params first
+        if (!desc.fieldDesc) {
+            sp<ABuffer> buf = ABuffer::CreateAsCopy(param, param->size());
+            value.set(buf);
+            ret.emplace(name, value);
+            continue;
+        }
+
+        size_t offset = sizeof(C2Param) + desc.offset
+                + _C2ParamInspector::GetOffset(*desc.fieldDesc);
+        uint8_t *data = (uint8_t *)param + offset;
+        C2FieldDescriptor::type_t fieldType = desc.fieldDesc->type();
+        switch (fieldType) {
+            case C2FieldDescriptor::STRING: {
+                size_t length = desc.fieldDesc->extent();
+                if (length == 0) {
+                    length = param->size() - offset;
+                }
+
+                if (param->size() < length || param->size() - length < offset) {
+                    ALOGD("param too small for string: length %zu size %zu offset %zu",
+                            length, param->size(), offset);
+                    break;
+                }
+                value.set(AString((char *)data, strnlen((char *)data, length)));
+                break;
+            }
+
+            case C2FieldDescriptor::BLOB: {
+                size_t length = desc.fieldDesc->extent();
+                if (length == 0) {
+                    length = param->size() - offset;
+                }
+
+                if (param->size() < length || param->size() - length < offset) {
+                    ALOGD("param too small for blob: length %zu size %zu offset %zu",
+                            length, param->size(), offset);
+                    break;
+                }
+
+                sp<ABuffer> buf = ABuffer::CreateAsCopy(data, length);
+                value.set(buf);
+                break;
+            }
+
+            default: {
+                size_t valueSize = C2Value::SizeFor((C2Value::type_t)fieldType);
+                if (param->size() < valueSize || param->size() - valueSize < offset) {
+                    ALOGD("param too small for c2value: size %zu offset %zu",
+                            param->size(), offset);
+                    break;
+                }
+
+                C2Value c2Value;
+                switch (fieldType) {
+                    case C2FieldDescriptor::INT32:  c2Value = *((int32_t *)data); break;
+                    case C2FieldDescriptor::UINT32: c2Value = *((uint32_t *)data); break;
+                    case C2FieldDescriptor::CNTR32: c2Value = *((c2_cntr32_t *)data); break;
+                    case C2FieldDescriptor::INT64:  c2Value = *((int64_t *)data); break;
+                    case C2FieldDescriptor::UINT64: c2Value = *((uint64_t *)data); break;
+                    case C2FieldDescriptor::CNTR64: c2Value = *((c2_cntr64_t *)data); break;
+                    case C2FieldDescriptor::FLOAT:  c2Value = *((float *)data); break;
+                    default:
+                        ALOGD("Unsupported data type for %s", name.c_str());
+                        continue;
+                }
+                value.set(c2Value);
+            }
+        }
+        ret.emplace(name, value);
+    }
+    return ret;
+}
+
+void ReflectedParamUpdater::clear() {
+    mMap.clear();
+}
+
+}  // namespace android
diff --git a/media/codec2/sfplugin/ReflectedParamUpdater.h b/media/codec2/sfplugin/ReflectedParamUpdater.h
new file mode 100644
index 0000000..5436ba5
--- /dev/null
+++ b/media/codec2/sfplugin/ReflectedParamUpdater.h
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef REFLECTED_PARAM_BUILDER_H_
+#define REFLECTED_PARAM_BUILDER_H_
+
+#include <map>
+#include <memory>
+
+#include <C2.h>
+#include <C2Param.h>
+
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/AData.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/AString.h>
+
+namespace android {
+
+/**
+ * Utility class to query and update Codec 2.0 configuration values. Use custom dictionary as
+ * AMessage cannot represent all types of Codec 2.0 parameters and C2Value cannot represent
+ * all types of SDK values. We want to be precise when setting standard parameters (use C2Value
+ * for arithmetic values), but also support int32 and int64 for SDK values specifically for
+ * vendor parameters (as SDK API does not allow specifying proper type.) When querying fields,
+ * we can use C2Values as they are defined.
+ *
+ *      Item => Codec 2.0 value mappings:
+ *     CValue::type => type
+ *     int32 => int32, ctr32 or uint32
+ *     int64 => int64, ctr64 or uint64
+ *     AString => string
+ *     ABuffer => blob
+ *     'Rect' => C2RectStruct (not exposed in SDK as a rectangle)
+ */
+class ReflectedParamUpdater {
+public:
+    ReflectedParamUpdater() = default;
+    ~ReflectedParamUpdater() = default;
+
+    /**
+     * Element for values
+     */
+    struct Value : public AData<C2Value, int32_t, int64_t, AString, sp<ABuffer>>::Basic {
+        // allow construction from base types
+        Value() = default;
+        explicit Value(C2Value i)            { set(i); }
+        explicit Value(int32_t i)            { set(i); }
+        explicit Value(int64_t i)            { set(i); }
+        explicit Value(const AString &i)     { set(i); }
+        explicit Value(const sp<ABuffer> &i) { set(i); }
+    };
+
+    struct Dict : public std::map<std::string, Value> {
+        Dict() = default;
+        std::string debugString(size_t indent = 0) const;
+    };
+
+    /**
+     * Enumerates all fields of the parameter descriptors supplied, so that this opbject can later
+     * query and update these.
+     *
+     * For now only first-level fields are supported. Also, array fields are not supported.
+     *
+     * \param reflector   C2ParamReflector object for C2Param reflection.
+     * \param paramDescs  vector of C2ParamDescriptor objects that this object
+     *                    would recognize when building params.
+     */
+    void addParamDesc(
+            const std::shared_ptr<C2ParamReflector> &reflector,
+            const std::vector<std::shared_ptr<C2ParamDescriptor>> &paramDescs);
+
+    /**
+     * Adds fields of a standard parameter (that may not be supported by the parameter reflector
+     * or may not be listed as a supported value by the component). If the parameter name is
+     * used for another parameter, this operation is a no-op. (Technically, this is by fields).
+     *
+     * \param T standard parameter type
+     * \param name parameter name
+     */
+    template<typename T>
+    void addStandardParam(const std::string &name, C2ParamDescriptor::attrib_t attrib =
+                          C2ParamDescriptor::IS_READ_ONLY) {
+        addParamDesc(std::make_shared<C2ParamDescriptor>(
+                C2Param::Index(T::PARAM_TYPE), attrib, name.c_str()),
+                C2StructDescriptor((T*)nullptr), nullptr /* descriptor */);
+    }
+
+    /**
+     * Adds fields of a structure (or a parameater) described by the struct descriptor. If
+     * reflector is provided, fields of sub-structures are also added. Otherwise, only top-level
+     * fundamental typed fields (arithmetic, string and blob) are added.
+     *
+     * \param paramDesc parameter descriptor
+     * \param fieldDesc field descriptor
+     * \param path path/name of the structure (field or parent parameter)
+     * \param offset offset of the structure in the parameter
+     * \param reflector  C2ParamReflector object for C2Param reflection (may be null)
+     */
+    void addParamStructDesc(
+            std::shared_ptr<C2ParamDescriptor> paramDesc, C2String path, size_t offset,
+            const C2StructDescriptor &structDesc,
+            const std::shared_ptr<C2ParamReflector> &reflector);
+
+    /**
+     * Adds fields of a parameter described by the struct descriptor. If reflector is provided,
+     * fields of sub-structures are also added. Otherwise, only top-level fundamental typed fields
+     * (arithmetic, string and blob) are added.
+     *
+     * \param paramDesc parameter descriptor
+     * \param fieldDesc field descriptor
+     * \param reflector  C2ParamReflector object for C2Param reflection (may be null)
+     * \param markVendor TEMP if true, prefix vendor parameter names with "vendor."
+     */
+    void addParamDesc(
+            std::shared_ptr<C2ParamDescriptor> paramDesc, const C2StructDescriptor &structDesc,
+            const std::shared_ptr<C2ParamReflector> &reflector,
+            bool markVendor = true);
+
+    /**
+     * Add support for setting a parameter as a binary blob.
+     *
+     * \param name name of the parameter
+     * \param coreIndex parameter (core) index
+     */
+    void supportWholeParam(std::string name, C2Param::CoreIndex coreIndex);
+
+    /**
+     * Returns the name of the parameter for an index.
+     */
+    std::string getParamName(C2Param::Index index) const;
+
+    /**
+     * Get list of param indices from field names and values in AMessage object.
+     *
+     * TODO: This should be in the order that they are listed by the component.
+     *
+     * \param params[in]  Dict object with field name to value pairs.
+     * \param vec[out]    vector to store the indices from |params|.
+     */
+    void getParamIndicesFromMessage(
+            const Dict &params,
+            std::vector<C2Param::Index> *vec /* nonnull */) const;
+
+    /**
+     * Get list of param indices from field names (only) in AMessage object.
+     *
+     * \param params[in]  Vector object with field names.
+     * \param vec[out]    vector to store the indices from |params|.
+     */
+    void getParamIndicesForKeys(
+            const std::vector<std::string> &keys,
+            std::vector<C2Param::Index> *vec /* nonnull */) const;
+
+    /**
+     * Update C2Param objects from field name and value in AMessage object.
+     *
+     * \param params[in]    Dict object with field name to value pairs.
+     * \param vec[in,out]   vector of the C2Param objects to be updated.
+     */
+    void updateParamsFromMessage(
+            const Dict &params,
+            std::vector<std::unique_ptr<C2Param>> *vec /* nonnull */) const;
+
+    /**
+     * Get fields from C2Param objects in AMessage object.
+     *
+     * \param params[in]    vector of the C2Param objects to be queried
+     * \return a Dict object containing the known parameters
+     */
+    Dict getParams(
+            const std::vector<C2Param*> &params /* nonnull */) const;
+
+    Dict getParams(
+            const std::vector<std::unique_ptr<C2Param>> &params /* nonnull */) const;
+
+    /**
+     * Clear param descriptors in this object.
+     */
+    void clear();
+
+private:
+    struct FieldDesc {
+        std::shared_ptr<C2ParamDescriptor> paramDesc;
+        std::unique_ptr<C2FieldDescriptor> fieldDesc;
+        size_t offset;
+    };
+    std::map<std::string, FieldDesc> mMap;
+    std::map<C2Param::Index, std::string> mParamNames;
+    std::map<std::string, C2Param::CoreIndex> mWholeParams;
+
+    void parseMessageAndDoWork(
+            const Dict &params,
+            std::function<void(const std::string &, const FieldDesc &, const void *, size_t)> work) const;
+
+    C2_DO_NOT_COPY(ReflectedParamUpdater);
+};
+
+}  // namespace android
+
+#endif  // REFLECTED_PARAM_BUILDER_H_
diff --git a/media/codec2/sfplugin/SkipCutBuffer.cpp b/media/codec2/sfplugin/SkipCutBuffer.cpp
new file mode 100644
index 0000000..8d1de65
--- /dev/null
+++ b/media/codec2/sfplugin/SkipCutBuffer.cpp
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "SkipCutBuffer"
+#include <utils/Log.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MediaBuffer.h>
+#include "SkipCutBuffer.h"
+
+namespace android {
+
+SkipCutBuffer::SkipCutBuffer(size_t skip, size_t cut, size_t num16BitChannels) {
+
+    mWriteHead = 0;
+    mReadHead = 0;
+    mCapacity = 0;
+    mCutBuffer = nullptr;
+
+    if (num16BitChannels == 0 || num16BitChannels > INT32_MAX / 2) {
+        ALOGW("# channels out of range: %zu, using passthrough instead", num16BitChannels);
+        return;
+    }
+    size_t frameSize = num16BitChannels * 2;
+    if (skip > INT32_MAX / frameSize || cut > INT32_MAX / frameSize
+            || cut * frameSize > INT32_MAX - 4096) {
+        ALOGW("out of range skip/cut: %zu/%zu, using passthrough instead",
+                skip, cut);
+        return;
+    }
+    skip *= frameSize;
+    cut *= frameSize;
+
+    mFrontPadding = mSkip = skip;
+    mBackPadding = cut;
+    mCapacity = cut + 4096;
+    mCutBuffer = new (std::nothrow) char[mCapacity];
+    ALOGV("skipcutbuffer %zu %zu %d", skip, cut, mCapacity);
+}
+
+SkipCutBuffer::~SkipCutBuffer() {
+    delete[] mCutBuffer;
+}
+
+void SkipCutBuffer::submit(MediaBuffer *buffer) {
+    if (mCutBuffer == nullptr) {
+        // passthrough mode
+        return;
+    }
+
+    int32_t offset = buffer->range_offset();
+    int32_t buflen = buffer->range_length();
+
+    // drop the initial data from the buffer if needed
+    if (mFrontPadding > 0) {
+        // still data left to drop
+        int32_t to_drop = (buflen < mFrontPadding) ? buflen : mFrontPadding;
+        offset += to_drop;
+        buflen -= to_drop;
+        buffer->set_range(offset, buflen);
+        mFrontPadding -= to_drop;
+    }
+
+
+    // append data to cutbuffer
+    char *src = ((char*) buffer->data()) + offset;
+    write(src, buflen);
+
+
+    // the mediabuffer is now empty. Fill it from cutbuffer, always leaving
+    // at least mBackPadding bytes in the cutbuffer
+    char *dst = (char*) buffer->data();
+    size_t copied = read(dst, buffer->size());
+    buffer->set_range(0, copied);
+}
+
+template <typename T>
+void SkipCutBuffer::submitInternal(const sp<T>& buffer) {
+    if (mCutBuffer == nullptr) {
+        // passthrough mode
+        return;
+    }
+
+    int32_t offset = buffer->offset();
+    int32_t buflen = buffer->size();
+
+    // drop the initial data from the buffer if needed
+    if (mFrontPadding > 0) {
+        // still data left to drop
+        int32_t to_drop = (buflen < mFrontPadding) ? buflen : mFrontPadding;
+        offset += to_drop;
+        buflen -= to_drop;
+        buffer->setRange(offset, buflen);
+        mFrontPadding -= to_drop;
+    }
+
+
+    // append data to cutbuffer
+    char *src = (char*) buffer->data();
+    write(src, buflen);
+
+
+    // the mediabuffer is now empty. Fill it from cutbuffer, always leaving
+    // at least mBackPadding bytes in the cutbuffer
+    char *dst = (char*) buffer->base();
+    size_t copied = read(dst, buffer->capacity());
+    buffer->setRange(0, copied);
+}
+
+void SkipCutBuffer::submit(const sp<ABuffer>& buffer) {
+    submitInternal(buffer);
+}
+
+void SkipCutBuffer::submit(const sp<MediaCodecBuffer>& buffer) {
+    submitInternal(buffer);
+}
+
+void SkipCutBuffer::clear() {
+    mWriteHead = mReadHead = 0;
+    mFrontPadding = mSkip;
+}
+
+void SkipCutBuffer::write(const char *src, size_t num) {
+    int32_t sizeused = (mWriteHead - mReadHead);
+    if (sizeused < 0) sizeused += mCapacity;
+
+    // Everything must fit. Make sure the buffer is a little larger than needed,
+    // so there is no ambiguity as to whether mWriteHead == mReadHead means buffer
+    // full or empty
+    size_t available = mCapacity - sizeused - 32;
+    if (available < num) {
+        int32_t newcapacity = mCapacity + (num - available);
+        char * newbuffer = new char[newcapacity];
+        memcpy(newbuffer, mCutBuffer, mCapacity);
+        delete [] mCutBuffer;
+        mCapacity = newcapacity;
+        mCutBuffer = newbuffer;
+        ALOGV("reallocated buffer at size %d", newcapacity);
+    }
+
+    size_t copyfirst = (mCapacity - mWriteHead);
+    if (copyfirst > num) copyfirst = num;
+    if (copyfirst) {
+        memcpy(mCutBuffer + mWriteHead, src, copyfirst);
+        num -= copyfirst;
+        src += copyfirst;
+        mWriteHead += copyfirst;
+        CHECK_LE(mWriteHead, mCapacity);
+        if (mWriteHead == mCapacity) mWriteHead = 0;
+        if (num) {
+            memcpy(mCutBuffer, src, num);
+            mWriteHead += num;
+        }
+    }
+}
+
+size_t SkipCutBuffer::read(char *dst, size_t num) {
+    int32_t available = (mWriteHead - mReadHead);
+    if (available < 0) available += mCapacity;
+
+    available -= mBackPadding;
+    if (available <=0) {
+        return 0;
+    }
+    if (available < int32_t(num)) {
+        num = available;
+    }
+
+    size_t copyfirst = (mCapacity - mReadHead);
+    if (copyfirst > num) copyfirst = num;
+    if (copyfirst) {
+        memcpy(dst, mCutBuffer + mReadHead, copyfirst);
+        num -= copyfirst;
+        dst += copyfirst;
+        mReadHead += copyfirst;
+        CHECK_LE(mReadHead, mCapacity);
+        if (mReadHead == mCapacity) mReadHead = 0;
+        if (num) {
+            memcpy(dst, mCutBuffer, num);
+            mReadHead += num;
+        }
+    }
+    return available;
+}
+
+size_t SkipCutBuffer::size() {
+    int32_t available = (mWriteHead - mReadHead);
+    if (available < 0) available += mCapacity;
+    return available;
+}
+
+}  // namespace android
diff --git a/media/codec2/sfplugin/SkipCutBuffer.h b/media/codec2/sfplugin/SkipCutBuffer.h
new file mode 100644
index 0000000..0fb5690
--- /dev/null
+++ b/media/codec2/sfplugin/SkipCutBuffer.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SKIP_CUT_BUFFER_H_
+
+#define SKIP_CUT_BUFFER_H_
+
+#include <media/MediaCodecBuffer.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/foundation/ABuffer.h>
+
+namespace android {
+
+/**
+ * utility class to cut the start and end off a stream of data in MediaBuffers
+ *
+ */
+class SkipCutBuffer: public RefBase {
+ public:
+    // 'skip' is the number of frames to skip from the beginning
+    // 'cut' is the number of frames to cut from the end
+    // 'num16BitChannels' is the number of channels, which are assumed to be 16 bit wide each
+    SkipCutBuffer(size_t skip, size_t cut, size_t num16Channels);
+
+    // Submit one MediaBuffer for skipping and cutting. This may consume all or
+    // some of the data in the buffer, or it may add data to it.
+    // After this, the caller should continue processing the buffer as usual.
+    void submit(MediaBuffer *buffer);
+    void submit(const sp<ABuffer>& buffer);    // same as above, but with an ABuffer
+    void submit(const sp<MediaCodecBuffer>& buffer);    // same as above, but with an ABuffer
+    void clear();
+    size_t size(); // how many bytes are currently stored in the buffer
+
+ protected:
+    virtual ~SkipCutBuffer();
+
+ private:
+    void write(const char *src, size_t num);
+    size_t read(char *dst, size_t num);
+    template <typename T>
+    void submitInternal(const sp<T>& buffer);
+    int32_t mSkip;
+    int32_t mFrontPadding;
+    int32_t mBackPadding;
+    int32_t mWriteHead;
+    int32_t mReadHead;
+    int32_t mCapacity;
+    char* mCutBuffer;
+    DISALLOW_EVIL_CONSTRUCTORS(SkipCutBuffer);
+};
+
+}  // namespace android
+
+#endif  // OMX_CODEC_H_
diff --git a/media/codec2/sfplugin/tests/Android.bp b/media/codec2/sfplugin/tests/Android.bp
new file mode 100644
index 0000000..be7f55c
--- /dev/null
+++ b/media/codec2/sfplugin/tests/Android.bp
@@ -0,0 +1,52 @@
+cc_test {
+    name: "ccodec_unit_test",
+
+    srcs: [
+        "ReflectedParamUpdater_test.cpp",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/codec2/sfplugin",
+    ],
+
+    shared_libs: [
+        "libcodec2",
+        "libsfplugin_ccodec",
+        "libstagefright_foundation",
+        "libutils",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+}
+
+cc_test {
+    name: "mc_sanity_test",
+
+    srcs: [
+        "MediaCodec_sanity_test.cpp",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/codec2/sfplugin",
+    ],
+
+    shared_libs: [
+        "libbinder",
+        "libcodec2",
+        "libgui",
+        "libmedia",
+        "libmedia_omx",
+        "libsfplugin_ccodec",
+        "libstagefright",
+        "libstagefright_foundation",
+        "libutils",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+}
diff --git a/media/codec2/sfplugin/tests/MediaCodec_sanity_test.cpp b/media/codec2/sfplugin/tests/MediaCodec_sanity_test.cpp
new file mode 100644
index 0000000..ba3687b
--- /dev/null
+++ b/media/codec2/sfplugin/tests/MediaCodec_sanity_test.cpp
@@ -0,0 +1,453 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+
+#include <algorithm>
+
+#include <binder/ProcessState.h>
+#include <gtest/gtest.h>
+#include <gui/Surface.h>
+#include <media/ICrypto.h>
+#include <media/MediaCodecBuffer.h>
+#include <media/hardware/VideoAPI.h>
+#include <media/stagefright/MediaCodec.h>
+#include <media/stagefright/MediaCodecConstants.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/foundation/AMessage.h>
+
+namespace android {
+
+class MediaCodecSanityTest : public ::testing::Test {
+public:
+    MediaCodecSanityTest()
+        : looper(new ALooper),
+          cfg(new AMessage),
+          ifmt(new AMessage),
+          ofmt(new AMessage) {
+        ProcessState::self()->startThreadPool();
+        looper->start();
+    }
+
+    ~MediaCodecSanityTest() {
+        if (codec != nullptr) {
+            codec->release();
+        }
+        looper->stop();
+    }
+
+    sp<ALooper> looper;
+    sp<MediaCodec> codec;
+    sp<AMessage> cfg;
+    sp<AMessage> ifmt;
+    sp<AMessage> ofmt;
+};
+
+const static size_t kLinearBufferSize = 1048576;
+
+// data for a codec input frame
+struct FrameData {
+    const uint8_t *data;
+    size_t size;
+    template<size_t N>
+    constexpr FrameData(const uint8_t(&data_)[N]) : data(data_), size(N) { }
+};
+
+// one yellow frame of 240x180 (albeit 4:4:4)
+const uint8_t avcStream_A1[] = { // IDR frame
+    0x00, 0x00, 0x00, 0x01, 0x67, 0x64, 0x00, 0x0d, 0xac, 0xd9, 0x41, 0x41, 0xfa, 0x10, 0x00, 0x00,
+    0x03, 0x00, 0x10, 0x00, 0x00, 0x03, 0x03, 0x20, 0xf1, 0x42, 0x99, 0x60,
+
+    0x00, 0x00, 0x00, 0x01, 0x68, 0xeb, 0xe3, 0xcb, 0x22, 0xc0,
+
+    0x00, 0x00, 0x01, 0x65, 0x88, 0x84, 0x00, 0x2b, 0xff, 0xfe, 0xd8, 0xe7, 0xf3, 0x2c, 0xa5, 0x60,
+    0xca, 0xbb, 0xf1, 0x5c, 0x44, 0x7c, 0x9a, 0xa5, 0xc3, 0xab, 0x2f, 0x77, 0x0a, 0x94, 0x0d, 0x19,
+    0x43, 0x3b, 0x4f, 0x25, 0xea, 0x66, 0x00, 0x01, 0x24, 0xcd, 0x35, 0x5f, 0xc2, 0x34, 0x89, 0xd1,
+    0xa5, 0x60, 0x09, 0x98, 0x00, 0x01, 0x1b, 0x0e, 0xcb, 0x0d, 0x04, 0x86, 0x94, 0xe2, 0x32, 0x3c,
+    0xdd, 0x0f,
+};
+
+FrameData avcStream_A[] __unused = { avcStream_A1 };
+
+// AVC stream of 2 yellow frames (240x180)
+const uint8_t avcStream_B1[] = { // IDR frame
+    0x00, 0x00, 0x00, 0x01, 0x67, 0x64, 0x00, 0x0c, 0xac, 0xd9, 0x41, 0x41, 0xfa, 0x10, 0x00, 0x00,
+    0x03, 0x00, 0x10, 0x00, 0x00, 0x03, 0x02, 0x80, 0xf1, 0x42, 0x99, 0x60,
+
+    0x00, 0x00, 0x00, 0x01, 0x68, 0xeb, 0xe3, 0xcb, 0x22, 0xc0,
+
+    0x00, 0x00, 0x01, 0x65, 0x88, 0x84, 0x00, 0x33, 0xff, 0xfe, 0xdf, 0x32, 0xf8, 0x14, 0xd6, 0x25,
+    0xd0, 0x74, 0x42, 0x50, 0x84, 0x6f, 0xf4, 0xc2, 0x5c, 0x76, 0x37, 0x17, 0x72, 0xac, 0x52, 0xfc,
+    0xd6, 0x1f, 0xd2, 0xd0, 0x60, 0xb2, 0x20, 0x00, 0x10, 0x3d, 0x2a, 0xc0, 0xe4, 0x27, 0xcb, 0xce,
+    0xea, 0x25, 0x00, 0x81, 0x00, 0x00, 0x0f, 0x40, 0xbc, 0x81, 0x15, 0xc1, 0x65, 0x20, 0x80, 0x81,
+    0x7a, 0x57, 0x51,
+};
+
+const uint8_t avcStream_B2[] = { // P frame
+    0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x21, 0x6c, 0x42, 0xbf, 0xfe, 0x38, 0x40, 0x00, 0x0d, 0x48,
+};
+
+FrameData avcStream_B[] = { avcStream_B1, avcStream_B2 };
+
+class MediaCodecInputBufferSizeTest : public MediaCodecSanityTest,
+        public ::testing::WithParamInterface<int32_t> {
+};
+
+TEST_P(MediaCodecInputBufferSizeTest, TestAvcDecoder) {
+    codec = MediaCodec::CreateByComponentName(looper, "c2.android.avc.decoder");
+    cfg->setInt32("width", 320);
+    cfg->setInt32("height", 240);
+    cfg->setString("mime", MIMETYPE_VIDEO_AVC);
+
+    const int32_t InputSize = GetParam();
+    if (InputSize >= 0) {
+        cfg->setInt32("max-input-size", InputSize);
+    }
+
+    EXPECT_EQ(codec->configure(cfg, nullptr, nullptr, 0), OK);
+    EXPECT_EQ(codec->getInputFormat(&ifmt), OK);
+    int32_t maxInputSize;
+    ASSERT_TRUE(ifmt->findInt32("max-input-size", &maxInputSize));
+    if (InputSize > 0) {
+        EXPECT_EQ(maxInputSize, InputSize);
+    } else {
+        EXPECT_GE(maxInputSize, 1 << 20); // 1 MB
+    }
+    EXPECT_EQ(codec->start(),  OK);
+    size_t ix;
+    EXPECT_EQ(codec->dequeueInputBuffer(&ix, 1000000), OK);
+    sp<MediaCodecBuffer> buf;
+    EXPECT_EQ(codec->getInputBuffer(ix, &buf),  OK);
+    EXPECT_GE(buf->size(), (size_t)maxInputSize);
+    EXPECT_LE(buf->size(), (size_t)maxInputSize + 4096u);
+}
+
+TEST_P(MediaCodecInputBufferSizeTest, TestVideoDecoder) {
+    codec = MediaCodec::CreateByComponentName(looper, "c2.android.vp8.decoder");
+    cfg->setInt32("width", 320);
+    cfg->setInt32("height", 240);
+    cfg->setString("mime", MIMETYPE_VIDEO_VP8);
+
+    const int32_t InputSize = GetParam();
+    if (InputSize >= 0) {
+        cfg->setInt32("max-input-size", InputSize);
+    }
+
+    EXPECT_EQ(codec->configure(cfg, nullptr, nullptr, 0), OK);
+    EXPECT_EQ(codec->getInputFormat(&ifmt), OK);
+    int32_t maxInputSize;
+    ASSERT_TRUE(ifmt->findInt32("max-input-size", &maxInputSize));
+    if (InputSize > 0) {
+        EXPECT_EQ(maxInputSize, InputSize);
+    } else {
+        EXPECT_GE(maxInputSize, 1 << 20); // 1 MB
+    }
+    EXPECT_EQ(codec->start(),  OK);
+    size_t ix;
+    EXPECT_EQ(codec->dequeueInputBuffer(&ix, 1000000), OK);
+    sp<MediaCodecBuffer> buf;
+    EXPECT_EQ(codec->getInputBuffer(ix, &buf),  OK);
+    EXPECT_GE(buf->size(), (size_t)maxInputSize);
+    EXPECT_LE(buf->size(), (size_t)maxInputSize + 4096u);
+}
+
+TEST_P(MediaCodecInputBufferSizeTest, TestAudioDecoder) {
+    codec = MediaCodec::CreateByComponentName(looper, "c2.android.aac.decoder");
+    cfg->setInt32("sample-rate", 44100);
+    cfg->setInt32("channel-count", 2);
+    cfg->setString("mime", MIMETYPE_AUDIO_AAC);
+
+    const int32_t InputSize = GetParam();
+    if (InputSize >= 0) {
+        cfg->setInt32("max-input-size", InputSize);
+    }
+
+    EXPECT_EQ(codec->configure(cfg, nullptr, nullptr, 0), OK);
+    EXPECT_EQ(codec->getInputFormat(&ifmt), OK);
+    int32_t maxInputSize;
+    if (InputSize > 0) {
+        ASSERT_TRUE(ifmt->findInt32("max-input-size", &maxInputSize));
+        EXPECT_EQ(maxInputSize, InputSize);
+    } else {
+        if (ifmt->findInt32("max-input-size", &maxInputSize)) {
+            EXPECT_EQ(maxInputSize, 1 << 19); // 512 KB
+        }
+        maxInputSize = kLinearBufferSize; // input size is set by channel
+    }
+
+    EXPECT_EQ(codec->start(),  OK);
+    size_t ix;
+    EXPECT_EQ(codec->dequeueInputBuffer(&ix, 1000000), OK);
+    sp<MediaCodecBuffer> buf;
+    EXPECT_EQ(codec->getInputBuffer(ix, &buf),  OK);
+    EXPECT_GE(buf->size(), (size_t)maxInputSize);
+    EXPECT_LE(buf->size(), (size_t)maxInputSize + 4096u);
+}
+
+INSTANTIATE_TEST_CASE_P(InputSizes, MediaCodecInputBufferSizeTest, ::testing::Values(-1, 1234, 12345678));
+
+TEST_F(MediaCodecSanityTest, TestAvcDecoderHdrStaticInfo) {
+    codec = MediaCodec::CreateByComponentName(looper, "c2.android.avc.decoder");
+    cfg->setInt32("width", 320);
+    cfg->setInt32("height", 240);
+    cfg->setString("mime", MIMETYPE_VIDEO_AVC);
+    HDRStaticInfo info = { .mID = HDRStaticInfo::kType1, .sType1 = {
+        .mR = { .x = 35400, .y = 14600 }, .mG = { .x = 8500,  .y = 39850 },
+        .mB = { .x = 6550,  .y =  2300 }, .mW = { .x = 15635, .y = 16450 },
+        .mMaxDisplayLuminance = 1000, .mMinDisplayLuminance = 1000,
+        .mMaxContentLightLevel = 1000, .mMaxFrameAverageLightLevel = 120 }
+    };
+    cfg->setBuffer("hdr-static-info", ABuffer::CreateAsCopy(&info, sizeof(info)));
+
+    EXPECT_EQ(codec->configure(cfg, nullptr, nullptr, 0), OK);
+    EXPECT_EQ(codec->getOutputFormat(&ofmt), OK);
+    sp<ABuffer> oinfo;
+    ASSERT_TRUE(ofmt->findBuffer("hdr-static-info", &oinfo));
+    ASSERT_EQ(oinfo->size(), sizeof(info));
+    EXPECT_EQ(memcmp(oinfo->data(), &info, sizeof(info)),  0);
+
+    EXPECT_EQ(codec->start(),  OK);
+    // assume we can submit all input before dequeuing output
+    size_t frameIx = 0;
+    size_t ix;
+    sp<MediaCodecBuffer> buf;
+    for (const FrameData &frame : avcStream_B) {
+        EXPECT_EQ(codec->dequeueInputBuffer(&ix, 1000000), OK);
+        EXPECT_EQ(codec->getInputBuffer(ix, &buf),  OK);
+        ASSERT_GE(buf->capacity(), frame.size);
+        memcpy(buf->base(), frame.data, frame.size);
+        EXPECT_EQ(buf->setRange(0, frame.size), OK);
+        bool eos = ++frameIx == NELEM(avcStream_B);
+        EXPECT_EQ(codec->queueInputBuffer(ix, 0, frame.size, frameIx * 33333,
+                                          eos ? BUFFER_FLAG_END_OF_STREAM : 0),  OK);
+    }
+
+    size_t offset, size;
+    int64_t ts;
+    uint32_t flags;
+    bool mInfoFormatChangedOk = true;
+    bool mInfoBuffersChangedOk = true;
+    while (true) {
+        status_t err = codec->dequeueOutputBuffer(&ix, &offset, &size, &ts, &flags, 1000000);
+        if (err == INFO_FORMAT_CHANGED && mInfoFormatChangedOk) {
+            mInfoFormatChangedOk = false;
+        } else if (err == INFO_OUTPUT_BUFFERS_CHANGED && mInfoBuffersChangedOk) {
+            mInfoBuffersChangedOk = false;
+        } else {
+            ASSERT_EQ(err, OK);
+            break;
+        }
+    }
+    EXPECT_EQ(codec->getOutputBuffer(ix, &buf), OK);
+    EXPECT_EQ(codec->getOutputFormat(ix, &ofmt), OK);
+    ASSERT_TRUE(ofmt->findBuffer("hdr-static-info", &oinfo));
+    ASSERT_EQ(oinfo->size(), sizeof(info));
+    EXPECT_EQ(memcmp(oinfo->data(), &info, sizeof(info)),  0);
+}
+
+TEST_F(MediaCodecSanityTest, TestVideoDecoderHdrStaticInfo) {
+    codec = MediaCodec::CreateByComponentName(looper, "c2.android.mpeg4.decoder");
+    cfg->setInt32("width", 320);
+    cfg->setInt32("height", 240);
+    cfg->setString("mime", MIMETYPE_VIDEO_MPEG4);
+    HDRStaticInfo info = { .mID = HDRStaticInfo::kType1, .sType1 = {
+        .mR = { .x = 35400, .y = 14600 }, .mG = { .x = 8500,  .y = 39850 },
+        .mB = { .x = 6550,  .y =  2300 }, .mW = { .x = 15635, .y = 16450 },
+        .mMaxDisplayLuminance = 1000, .mMinDisplayLuminance = 1000,
+        .mMaxContentLightLevel = 1000, .mMaxFrameAverageLightLevel = 120 }
+    };
+    cfg->setBuffer("hdr-static-info", ABuffer::CreateAsCopy(&info, sizeof(info)));
+
+    EXPECT_EQ(codec->configure(cfg, nullptr, nullptr, 0), OK);
+    EXPECT_EQ(codec->getOutputFormat(&ofmt), OK);
+    sp<ABuffer> oinfo;
+    ASSERT_TRUE(ofmt->findBuffer("hdr-static-info", &oinfo));
+    ASSERT_EQ(oinfo->size(), sizeof(info));
+    EXPECT_EQ(memcmp(oinfo->data(), &info, sizeof(info)),  0);
+}
+
+class MediaCodecByteBufferTest : public MediaCodecSanityTest,
+        public ::testing::WithParamInterface<int32_t> {
+};
+
+TEST_P(MediaCodecByteBufferTest, TestVideoDecoder420Planar) {
+    codec = MediaCodec::CreateByComponentName(looper, "c2.android.avc.decoder");
+//    codec = MediaCodec::CreateByComponentName(looper, "OMX.google.h264.decoder");
+    cfg->setInt32("width", 320);
+    cfg->setInt32("height", 240);
+    cfg->setString("mime", MIMETYPE_VIDEO_AVC);
+    const int32_t Color = GetParam();
+    if (Color >= 0) {
+        cfg->setInt32("color-format", Color);
+    }
+    int32_t xcolor = Color == -1 ? COLOR_FormatYUV420Planar : Color;
+
+    EXPECT_EQ(codec->configure(cfg, nullptr, nullptr, 0), OK);
+    EXPECT_EQ(codec->getOutputFormat(&ofmt), OK);
+    int32_t ocolor = -1;
+    EXPECT_TRUE(ofmt->findInt32("color-format", &ocolor));
+    EXPECT_EQ(ocolor, xcolor);
+
+    EXPECT_EQ(codec->start(),  OK);
+    // assume we can submit all input before dequeuing output
+    size_t frameIx = 0;
+    size_t ix;
+    sp<MediaCodecBuffer> buf;
+    for (const FrameData &frame : avcStream_A) {
+        EXPECT_EQ(codec->dequeueInputBuffer(&ix, 1000000), OK);
+        EXPECT_EQ(codec->getInputBuffer(ix, &buf),  OK);
+        ASSERT_GE(buf->capacity(), frame.size);
+        memcpy(buf->base(), frame.data, frame.size);
+        EXPECT_EQ(buf->setRange(0, frame.size), OK);
+        bool eos = ++frameIx == NELEM(avcStream_A);
+        EXPECT_EQ(codec->queueInputBuffer(ix, 0, frame.size, frameIx * 33333,
+                                          eos ? BUFFER_FLAG_END_OF_STREAM : 0),  OK);
+    }
+
+    size_t offset, size;
+    int64_t ts;
+    uint32_t flags;
+    bool mInfoFormatChangedOk = true;
+    bool mInfoBuffersChangedOk = true;
+    while (true) {
+        status_t err = codec->dequeueOutputBuffer(&ix, &offset, &size, &ts, &flags, 1000000);
+        if (err == INFO_FORMAT_CHANGED && mInfoFormatChangedOk) {
+            mInfoFormatChangedOk = false;
+        } else if (err == INFO_OUTPUT_BUFFERS_CHANGED && mInfoBuffersChangedOk) {
+            mInfoBuffersChangedOk = false;
+        } else {
+            ASSERT_EQ(err, OK);
+            break;
+        }
+    }
+    EXPECT_EQ(codec->getOutputBuffer(ix, &buf), OK);
+    EXPECT_EQ(codec->getOutputFormat(ix, &ofmt), OK);
+    ASSERT_TRUE(ofmt->findInt32("color-format", &ocolor));
+    EXPECT_EQ(ocolor, xcolor) << ofmt->debugString(8).c_str() << buf->meta()->debugString(8).c_str();
+    // expect an image-data in both format and meta
+    sp<ABuffer> imgBuf, imgBuf2;
+    ASSERT_TRUE(ofmt->findBuffer("image-data", &imgBuf));
+    ASSERT_TRUE(buf->meta()->findBuffer("image-data", &imgBuf2));
+    EXPECT_EQ(imgBuf->size(), sizeof(MediaImage2));
+    ASSERT_EQ(imgBuf->size(), imgBuf2->size());
+    EXPECT_EQ(0, memcmp(imgBuf->data(), imgBuf2->data(), imgBuf->size()));
+    MediaImage2 *img = (MediaImage2*)imgBuf->data();
+    EXPECT_EQ(img->mType, img->MEDIA_IMAGE_TYPE_YUV);
+    EXPECT_EQ(img->mNumPlanes, 3u);
+    EXPECT_EQ(img->mWidth, 320u);
+    EXPECT_EQ(img->mHeight, 240u);
+    EXPECT_EQ(img->mBitDepth, 8u);
+    EXPECT_EQ(img->mBitDepthAllocated, 8u);
+
+    // read strides from format
+    int32_t stride, vstride;
+    ofmt->findInt32("stride", &stride)          || ofmt->findInt32("width", &stride);
+    ofmt->findInt32("slice-height", &vstride)   || ofmt->findInt32("height", &vstride);
+
+    EXPECT_EQ(img->mPlane[img->Y].mHorizSubsampling, 1u);
+    EXPECT_EQ(img->mPlane[img->Y].mVertSubsampling, 1u);
+    EXPECT_EQ(img->mPlane[img->U].mHorizSubsampling, 2u);
+    EXPECT_EQ(img->mPlane[img->U].mVertSubsampling, 2u);
+    EXPECT_EQ(img->mPlane[img->V].mHorizSubsampling, 2u);
+    EXPECT_EQ(img->mPlane[img->V].mVertSubsampling, 2u);
+
+    switch (xcolor) {
+        // defined formats
+        case COLOR_FormatYUV420Planar:
+        case COLOR_FormatYUV420PackedPlanar:
+            EXPECT_EQ(img->mPlane[img->Y].mOffset, 0u);
+            EXPECT_EQ(img->mPlane[img->Y].mColInc, 1);
+            EXPECT_EQ(img->mPlane[img->Y].mRowInc, stride);
+
+            EXPECT_EQ(img->mPlane[img->U].mOffset, (uint32_t)(stride * vstride));
+            EXPECT_EQ(img->mPlane[img->U].mColInc, 1);
+            EXPECT_EQ(img->mPlane[img->U].mRowInc, stride / 2);
+
+            EXPECT_EQ(img->mPlane[img->V].mOffset, (uint32_t)(stride * vstride * 5 / 4));
+            EXPECT_EQ(img->mPlane[img->V].mColInc, 1);
+            EXPECT_EQ(img->mPlane[img->V].mRowInc, stride / 2);
+
+            EXPECT_GE(size, (size_t)(stride * vstride * 5 / 4 + stride / 2 * 119 + 160));
+            EXPECT_LE(size, (size_t)(stride * vstride * 3 / 2));
+            break;
+
+        case COLOR_FormatYUV420SemiPlanar:
+        case COLOR_FormatYUV420PackedSemiPlanar:
+            EXPECT_EQ(img->mPlane[img->Y].mOffset, 0u);
+            EXPECT_EQ(img->mPlane[img->Y].mColInc, 1);
+            EXPECT_EQ(img->mPlane[img->Y].mRowInc, stride);
+
+            EXPECT_EQ(img->mPlane[img->U].mOffset, (uint32_t)(stride * vstride));
+            EXPECT_EQ(img->mPlane[img->U].mColInc, 2);
+            EXPECT_EQ(img->mPlane[img->U].mRowInc, stride);
+
+            EXPECT_EQ(img->mPlane[img->V].mOffset, (uint32_t)(stride * vstride + 1));
+            EXPECT_EQ(img->mPlane[img->V].mColInc, 2);
+            EXPECT_EQ(img->mPlane[img->V].mRowInc, stride);
+
+            EXPECT_GE(size, (size_t)(stride * vstride + stride * 119 + 320));
+            EXPECT_LE(size, (size_t)(stride * vstride * 3 / 2));
+            break;
+
+        case COLOR_FormatYUV420Flexible:
+            // anything goes, but stride should match Y plane
+            EXPECT_EQ(img->mPlane[img->Y].mRowInc, stride);
+
+            EXPECT_GE(size,
+                      std::max({
+                            img->mPlane[img->Y].mOffset + 239 * img->mPlane[img->Y].mRowInc
+                                    + 319 * img->mPlane[img->Y].mColInc + 1,
+                            img->mPlane[img->U].mOffset + 119 * img->mPlane[img->U].mRowInc
+                                    + 159 * img->mPlane[img->U].mColInc + 1,
+                            img->mPlane[img->V].mOffset + 119 * img->mPlane[img->V].mRowInc
+                                    + 159 * img->mPlane[img->V].mColInc + 1 }));
+            break;
+
+        default:
+            break;
+    }
+
+    // validate all pixels
+#if 0
+    fprintf(stderr, "MediaImage { F(%ux%u) @%u+%d+%d @%u+%d+%d @%u+%d+%d }\n",
+            img->mWidth, img->mHeight,
+            img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc,
+            img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc,
+            img->mPlane[2].mOffset, img->mPlane[2].mColInc, img->mPlane[2].mRowInc);
+#endif
+    for (ix = 0; ix < 3; ++ix) {
+        const static uint8_t expected[] = { 210, 16, 146 };
+        for (uint32_t y = 0; y < img->mHeight / img->mPlane[ix].mVertSubsampling ; ++y) {
+            for (uint32_t x = 0; x < img->mWidth / img->mPlane[ix].mHorizSubsampling; ++x) {
+                uint8_t val = buf->data()[img->mPlane[ix].mOffset + img->mPlane[ix].mColInc * x
+                        + img->mPlane[ix].mRowInc * y];
+                ASSERT_EQ(val, expected[ix]) << "incorrect value for plane "
+                        << ix << " at x=" << x << ", y=" << y;
+            }
+        }
+    }
+}
+
+INSTANTIATE_TEST_CASE_P(InputSizes, MediaCodecByteBufferTest, ::testing::Values(
+        -1,
+        COLOR_FormatYUV420Planar,
+        COLOR_FormatYUV420SemiPlanar,
+        COLOR_FormatYUV420PackedPlanar,
+        COLOR_FormatYUV420PackedSemiPlanar,
+        COLOR_FormatYUV420Flexible));
+
+} // namespace android
diff --git a/media/codec2/sfplugin/tests/ReflectedParamUpdater_test.cpp b/media/codec2/sfplugin/tests/ReflectedParamUpdater_test.cpp
new file mode 100644
index 0000000..c7db0e3
--- /dev/null
+++ b/media/codec2/sfplugin/tests/ReflectedParamUpdater_test.cpp
@@ -0,0 +1,352 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define __C2_GENERATE_GLOBAL_VARS__
+
+#include <set>
+
+#include <gtest/gtest.h>
+
+#include <C2ParamDef.h>
+
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/hexdump.h>
+#include <ReflectedParamUpdater.h>
+
+namespace android {
+
+namespace {
+
+enum {
+    kParamIndexTestStart = 0x1000,
+    kParamIndexInt,
+    kParamIndexString,
+    kParamIndexComposite,
+    kParamIndexFlexString,
+
+    kParamIndexLong = C2Param::TYPE_INDEX_VENDOR_START,
+};
+
+typedef C2GlobalParam<C2Info, C2Int32Value, kParamIndexInt> C2IntInfo;
+typedef C2GlobalParam<C2Info, C2Int64Value, kParamIndexLong> C2LongInfo;
+
+struct C2FixedSizeStringStruct {
+    char value[12];
+
+    DEFINE_AND_DESCRIBE_BASE_C2STRUCT(FixedSizeString)
+    C2FIELD(value, "value")
+};
+typedef C2GlobalParam<C2Info, C2FixedSizeStringStruct, kParamIndexString> C2StringInfo;
+
+struct C2CompositeStruct {
+    int32_t i32;
+    uint64_t u64;
+    char str[12];
+    uint8_t blob[8];
+    uint8_t flexBlob[];
+
+    C2CompositeStruct() = default;
+
+    DEFINE_AND_DESCRIBE_BASE_FLEX_C2STRUCT(Composite, flexBlob)
+    C2FIELD(i32, "i32")
+    C2FIELD(u64, "u64")
+    C2FIELD(str, "str")
+    C2FIELD(blob, "blob")
+    C2FIELD(flexBlob, "flex-blob")
+};
+static_assert(C2CompositeStruct::FLEX_SIZE == 1, "");
+static_assert(_C2FlexHelper<C2CompositeStruct>::FLEX_SIZE == 1, "");
+typedef C2GlobalParam<C2Info, C2CompositeStruct, kParamIndexComposite> C2CompositeInfo;
+
+typedef C2GlobalParam<C2Info, C2StringValue, kParamIndexFlexString> C2FlexStringInfo;
+
+#define SUPPORTED_TYPES   \
+    C2IntInfo,            \
+    C2LongInfo,           \
+    C2StringInfo,         \
+    C2CompositeInfo,      \
+    C2FlexStringInfo
+
+template<typename... TYPES> struct describe_impl;
+template<typename T, typename... TYPES> struct describe_impl<T, TYPES...> {
+    static std::unique_ptr<C2StructDescriptor> describe(C2Param::CoreIndex index) {
+        if (index == T::CORE_INDEX) {
+            return std::make_unique<C2StructDescriptor>(T::CORE_INDEX, T::FieldList());
+        } else {
+            return describe_impl<TYPES...>::describe(index);
+        }
+    }
+};
+
+template<> struct describe_impl<> {
+    static std::unique_ptr<C2StructDescriptor> describe(C2Param::CoreIndex) {
+        return nullptr;
+    }
+};
+
+template<typename T> const char *GetName()        { return nullptr; }
+template<> const char *GetName<C2IntInfo>()       { return "int"; }
+template<> const char *GetName<C2LongInfo>()      { return "long"; }
+template<> const char *GetName<C2StringInfo>()    { return "string"; }
+template<> const char *GetName<C2CompositeInfo>() { return "composite"; }
+template<> const char *GetName<C2FlexStringInfo>() { return "flex-string"; }
+
+template<typename... TYPES> struct fill_descriptors_impl;
+template<typename T, typename... TYPES> struct fill_descriptors_impl<T, TYPES...> {
+    static void fill(std::vector<std::shared_ptr<C2ParamDescriptor>> *vec) {
+        fill_descriptors_impl<TYPES...>::fill(vec);
+        vec->push_back(std::make_shared<C2ParamDescriptor>(
+                T::PARAM_TYPE, C2ParamDescriptor::IS_PERSISTENT, GetName<T>()));
+    }
+};
+
+template<> struct fill_descriptors_impl<> {
+    static void fill(std::vector<std::shared_ptr<C2ParamDescriptor>> *) {}
+};
+
+template<typename T> T *CastParam(const std::unique_ptr<C2Param> &param) {
+    return (T *)param.get();
+}
+
+class ParamReflector : public C2ParamReflector {
+public:
+    ParamReflector() = default;
+    ~ParamReflector() override = default;
+
+    std::unique_ptr<C2StructDescriptor> describe(C2Param::CoreIndex paramIndex) const override {
+        return describe_impl<SUPPORTED_TYPES>::describe(paramIndex);
+    }
+};
+
+}  // namespace
+
+class ReflectedParamUpdaterTest : public ::testing::Test {
+public:
+    ReflectedParamUpdaterTest() : mReflector(new ParamReflector) {
+        fill_descriptors_impl<SUPPORTED_TYPES>::fill(&mDescriptors);
+    }
+
+    std::shared_ptr<C2ParamReflector> mReflector;
+    std::vector<std::shared_ptr<C2ParamDescriptor>> mDescriptors;
+};
+
+TEST_F(ReflectedParamUpdaterTest, SingleValueTest) {
+    ReflectedParamUpdater updater;
+
+    ReflectedParamUpdater::Dict msg;
+    msg.emplace("int.value", int32_t(12));
+    msg.emplace("vendor.long.value", int64_t(34));
+
+    updater.addParamDesc(mReflector, mDescriptors);
+
+    std::vector<C2Param::Index> indices;
+    updater.getParamIndicesFromMessage(msg, &indices);
+    EXPECT_EQ(1, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2IntInfo::PARAM_TYPE; }));
+    EXPECT_EQ(1, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2LongInfo::PARAM_TYPE; }));
+    EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2StringInfo::PARAM_TYPE; }));
+    EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2CompositeInfo::PARAM_TYPE; }));
+    EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2FlexStringInfo::PARAM_TYPE; }));
+
+    std::vector<std::unique_ptr<C2Param>> params;
+    params.emplace_back(new C2IntInfo);
+    params.emplace_back(new C2LongInfo);
+    EXPECT_EQ(0, CastParam<C2IntInfo>(params[0])->value);
+    EXPECT_EQ(0, CastParam<C2LongInfo>(params[1])->value);
+
+    updater.updateParamsFromMessage(msg, &params);
+    EXPECT_EQ(12, CastParam<C2IntInfo>(params[0])->value);
+    EXPECT_EQ(34, CastParam<C2LongInfo>(params[1])->value);
+
+    C2Value c2Value;
+    int32_t int32Value = 0;
+    int64_t int64Value = 0;
+    msg = updater.getParams(params);
+    ASSERT_EQ(1u, msg.count("int.value"));
+    EXPECT_EQ(true, msg["int.value"].find(&c2Value));
+    EXPECT_EQ(true, c2Value.get(&int32Value));
+    EXPECT_EQ(12, int32Value);
+
+    ASSERT_EQ(1u, msg.count("vendor.long.value"));
+    EXPECT_EQ(true, msg["vendor.long.value"].find(&c2Value));
+    EXPECT_EQ(true, c2Value.get(&int64Value));
+    EXPECT_EQ(34, int64Value);
+}
+
+TEST_F(ReflectedParamUpdaterTest, StringTest) {
+    ReflectedParamUpdater updater;
+
+    ReflectedParamUpdater::Dict msg;
+    msg.emplace("string.value", AString("56"));
+    msg.emplace("flex-string.value", AString("Some string"));
+    updater.addParamDesc(mReflector, mDescriptors);
+
+    std::vector<C2Param::Index> indices;
+    updater.getParamIndicesFromMessage(msg, &indices);
+    EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2IntInfo::PARAM_TYPE; }));
+    EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2LongInfo::PARAM_TYPE; }));
+    EXPECT_EQ(1, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2StringInfo::PARAM_TYPE; }));
+    EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2CompositeInfo::PARAM_TYPE; }));
+    EXPECT_EQ(1, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2FlexStringInfo::PARAM_TYPE; }));
+
+    std::vector<std::unique_ptr<C2Param>> params;
+    params.emplace_back(new C2StringInfo);
+    EXPECT_EQ(0, CastParam<C2StringInfo>(params[0])->value[0]);
+    params.emplace_back(C2FlexStringInfo::AllocUnique(0));
+    EXPECT_EQ(0u, CastParam<C2FlexStringInfo>(params[1])->flexCount());
+    char *flexStringData = &CastParam<C2FlexStringInfo>(params[1])->m.value[0];
+
+    updater.updateParamsFromMessage(msg, &params);
+    EXPECT_STREQ("56", CastParam<C2StringInfo>(params[0])->value);
+    EXPECT_EQ(12u, CastParam<C2FlexStringInfo>(params[0])->flexCount());
+    EXPECT_STREQ("Some string", CastParam<C2FlexStringInfo>(params[1])->m.value);
+    EXPECT_NE(flexStringData, &CastParam<C2FlexStringInfo>(params[1])->m.value[0]);
+    flexStringData = &CastParam<C2FlexStringInfo>(params[1])->m.value[0];
+
+    // verify truncation and in-place update
+    msg["string.value"] = ReflectedParamUpdater::Value(AString("1234567890ABCDE"));
+    msg["flex-string.value"] = ReflectedParamUpdater::Value(AString("abc"));
+    updater.updateParamsFromMessage(msg, &params);
+    EXPECT_STREQ("1234567890A", CastParam<C2StringInfo>(params[0])->value);
+    EXPECT_EQ(4u, CastParam<C2FlexStringInfo>(params[1])->flexCount());
+    EXPECT_STREQ("abc", CastParam<C2FlexStringInfo>(params[1])->m.value);
+    EXPECT_EQ(flexStringData, &CastParam<C2FlexStringInfo>(params[1])->m.value[0]);
+
+    AString strValue;
+    msg = updater.getParams(params);
+    ASSERT_EQ(1u, msg.count("string.value"));
+    EXPECT_EQ(true, msg["string.value"].find(&strValue));
+    EXPECT_STREQ("1234567890A", strValue.c_str());
+
+    ASSERT_EQ(1u, msg.count("flex-string.value"));
+    EXPECT_EQ(true, msg["flex-string.value"].find(&strValue));
+    EXPECT_STREQ("abc", strValue.c_str());
+}
+
+TEST_F(ReflectedParamUpdaterTest, CompositeTest) {
+    ReflectedParamUpdater updater;
+
+    ReflectedParamUpdater::Dict msg;
+    msg.emplace("composite.i32", int32_t(78));
+    msg.emplace("composite.u64", int64_t(910));
+    msg.emplace("composite.str", AString("1112"));
+    msg.emplace("composite.blob", ABuffer::CreateAsCopy("buffer08", 8));
+    msg.emplace("composite.flex-blob", ABuffer::CreateAsCopy("flex-buffer-14", 14));
+
+    updater.addParamDesc(mReflector, mDescriptors);
+
+    std::vector<C2Param::Index> indices;
+    updater.getParamIndicesFromMessage(msg, &indices);
+    EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2IntInfo::PARAM_TYPE; }));
+    EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2LongInfo::PARAM_TYPE; }));
+    EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2StringInfo::PARAM_TYPE; }));
+    EXPECT_EQ(1, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2CompositeInfo::PARAM_TYPE; }));
+
+    std::vector<std::unique_ptr<C2Param>> params;
+    params.emplace_back(C2CompositeInfo::AllocUnique(0));
+    EXPECT_EQ(0, CastParam<C2CompositeInfo>(params[0])->m.i32);
+    EXPECT_EQ(0u, CastParam<C2CompositeInfo>(params[0])->m.u64);
+    EXPECT_EQ(0, CastParam<C2CompositeInfo>(params[0])->m.str[0]);
+    EXPECT_EQ(0, memcmp("\0\0\0\0\0\0\0\0", CastParam<C2CompositeInfo>(params[0])->m.blob, 8));
+    EXPECT_EQ(0u, CastParam<C2CompositeInfo>(params[0])->flexCount());
+    uint8_t *flexBlobData = &CastParam<C2CompositeInfo>(params[0])->m.flexBlob[0];
+
+    updater.updateParamsFromMessage(msg, &params);
+    EXPECT_EQ(78, CastParam<C2CompositeInfo>(params[0])->m.i32);
+    EXPECT_EQ(910u, CastParam<C2CompositeInfo>(params[0])->m.u64);
+    EXPECT_STREQ("1112", CastParam<C2CompositeInfo>(params[0])->m.str);
+    EXPECT_EQ(0, memcmp("buffer08", CastParam<C2CompositeInfo>(params[0])->m.blob, 8));
+    AString hex;
+    hexdump(CastParam<C2CompositeInfo>(params[0])->m.blob, 8, 0, &hex);
+    printf("%s\n", hex.c_str());
+    ASSERT_EQ(14u, CastParam<C2CompositeInfo>(params[0])->flexCount());
+    EXPECT_EQ(0, memcmp("flex-buffer-14", CastParam<C2CompositeInfo>(params[0])->m.flexBlob, 14));
+    EXPECT_NE(flexBlobData, &CastParam<C2CompositeInfo>(params[0])->m.flexBlob[0]);
+    flexBlobData = &CastParam<C2CompositeInfo>(params[0])->m.flexBlob[0];
+
+    // test setting and zero extending shorter blob than allowed
+    msg.clear();
+    msg.emplace("composite.blob", ABuffer::CreateAsCopy("buf05", 5));
+    updater.updateParamsFromMessage(msg, &params);
+    EXPECT_EQ(0, memcmp("buf05\0\0\0", CastParam<C2CompositeInfo>(params[0])->m.blob, 8));
+    ASSERT_EQ(14u, CastParam<C2CompositeInfo>(params[0])->flexCount());
+    EXPECT_EQ(0, memcmp("flex-buffer-14", CastParam<C2CompositeInfo>(params[0])->m.flexBlob, 14));
+    EXPECT_EQ(flexBlobData, &CastParam<C2CompositeInfo>(params[0])->m.flexBlob[0]);
+
+    // test setting and trimming larger blob than allowed
+    msg.clear();
+    msg.emplace("composite.blob", ABuffer::CreateAsCopy("ReallyLongBuffer", 16));
+    updater.updateParamsFromMessage(msg, &params);
+    EXPECT_EQ(0, memcmp("ReallyLo", CastParam<C2CompositeInfo>(params[0])->m.blob, 8));
+    ASSERT_EQ(14u, CastParam<C2CompositeInfo>(params[0])->flexCount());
+    EXPECT_EQ(0, memcmp("flex-buffer-14", CastParam<C2CompositeInfo>(params[0])->m.flexBlob, 14));
+    EXPECT_EQ(flexBlobData, &CastParam<C2CompositeInfo>(params[0])->m.flexBlob[0]);
+
+    // test trimming flex blob in-place
+    msg.clear();
+    msg.emplace("composite.flex-blob", ABuffer::CreateAsCopy("buf05", 5));
+    updater.updateParamsFromMessage(msg, &params);
+    ASSERT_EQ(5u, CastParam<C2CompositeInfo>(params[0])->flexCount());
+    EXPECT_EQ(0, memcmp("buf05", CastParam<C2CompositeInfo>(params[0])->m.flexBlob, 5));
+    EXPECT_EQ(flexBlobData, &CastParam<C2CompositeInfo>(params[0])->m.flexBlob[0]);
+}
+
+TEST_F(ReflectedParamUpdaterTest, CompositePartialTest) {
+    ReflectedParamUpdater updater;
+
+    ReflectedParamUpdater::Dict msg;
+    msg.emplace("composite.i32", C2Value(1314));
+    msg.emplace("composite.str", AString("1516"));
+
+    updater.addParamDesc(mReflector, mDescriptors);
+
+    std::vector<C2Param::Index> indices;
+    updater.getParamIndicesFromMessage(msg, &indices);
+    EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2IntInfo::PARAM_TYPE; }));
+    EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2LongInfo::PARAM_TYPE; }));
+    EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2StringInfo::PARAM_TYPE; }));
+    EXPECT_EQ(1, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2CompositeInfo::PARAM_TYPE; }));
+
+    std::vector<std::unique_ptr<C2Param>> params;
+    params.emplace_back(C2CompositeInfo::AllocUnique(12u));
+    EXPECT_EQ(0, CastParam<C2CompositeInfo>(params[0])->m.i32);
+    EXPECT_EQ(0u, CastParam<C2CompositeInfo>(params[0])->m.u64);
+    EXPECT_EQ(0, CastParam<C2CompositeInfo>(params[0])->m.str[0]);
+
+    updater.updateParamsFromMessage(msg, &params);
+    EXPECT_EQ(1314, CastParam<C2CompositeInfo>(params[0])->m.i32);
+    EXPECT_EQ(0u, CastParam<C2CompositeInfo>(params[0])->m.u64);
+    EXPECT_STREQ("1516", CastParam<C2CompositeInfo>(params[0])->m.str);
+}
+
+} // namespace android
diff --git a/media/codec2/sfplugin/utils/Android.bp b/media/codec2/sfplugin/utils/Android.bp
new file mode 100644
index 0000000..8c8f025
--- /dev/null
+++ b/media/codec2/sfplugin/utils/Android.bp
@@ -0,0 +1,40 @@
+cc_library_shared {
+    name: "libsfplugin_ccodec_utils",
+    vendor_available: true,
+
+    srcs: [
+        "Codec2BufferUtils.cpp",
+        "Codec2Mapper.cpp",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+
+    export_include_dirs: [
+        ".",
+    ],
+
+    shared_libs: [
+        "libbase",
+        "libcodec2",
+        "libcodec2_vndk",
+        "libcutils",
+        "liblog",
+        "libstagefright_foundation",
+        "libutils",
+    ],
+
+    static_libs: [
+        "libyuv_static",
+    ],
+
+    sanitize: {
+        cfi: true,
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+    },
+}
diff --git a/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp b/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
new file mode 100644
index 0000000..bf2a07e
--- /dev/null
+++ b/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
@@ -0,0 +1,533 @@
+/*
+ * Copyright 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2BufferUtils"
+#include <utils/Log.h>
+
+#include <libyuv.h>
+
+#include <list>
+#include <mutex>
+
+#include <media/hardware/HardwareAPI.h>
+#include <media/stagefright/foundation/AUtils.h>
+
+#include <C2Debug.h>
+
+#include "Codec2BufferUtils.h"
+
+namespace android {
+
+namespace {
+
+/**
+ * A flippable, optimizable memcpy. Constructs such as (from ? src : dst) do not work as the results are
+ * always const.
+ */
+template<bool ToA, size_t S>
+struct MemCopier {
+    template<typename A, typename B>
+    inline static void copy(A *a, const B *b, size_t size) {
+        __builtin_memcpy(a, b, size);
+    }
+};
+
+template<size_t S>
+struct MemCopier<false, S> {
+    template<typename A, typename B>
+    inline static void copy(const A *a, B *b, size_t size) {
+        MemCopier<true, S>::copy(b, a, size);
+    }
+};
+
+/**
+ * Copies between a MediaImage and a graphic view.
+ *
+ * \param ToMediaImage whether to copy to (or from) the MediaImage
+ * \param view graphic view (could be ConstGraphicView or GraphicView depending on direction)
+ * \param img MediaImage data
+ * \param imgBase base of MediaImage (could be const uint8_t* or uint8_t* depending on direction)
+ */
+template<bool ToMediaImage, typename View, typename ImagePixel>
+static status_t _ImageCopy(View &view, const MediaImage2 *img, ImagePixel *imgBase) {
+    // TODO: more efficient copying --- e.g. copy interleaved planes together, etc.
+    const C2PlanarLayout &layout = view.layout();
+    const size_t bpp = divUp(img->mBitDepthAllocated, 8u);
+
+    for (uint32_t i = 0; i < layout.numPlanes; ++i) {
+        typename std::conditional<ToMediaImage, uint8_t, const uint8_t>::type *imgRow =
+            imgBase + img->mPlane[i].mOffset;
+        typename std::conditional<ToMediaImage, const uint8_t, uint8_t>::type *viewRow =
+            viewRow = view.data()[i];
+        const C2PlaneInfo &plane = layout.planes[i];
+        if (plane.colSampling != img->mPlane[i].mHorizSubsampling
+                || plane.rowSampling != img->mPlane[i].mVertSubsampling
+                || plane.allocatedDepth != img->mBitDepthAllocated
+                || plane.allocatedDepth < plane.bitDepth
+                // MediaImage only supports MSB values
+                || plane.rightShift != plane.allocatedDepth - plane.bitDepth
+                || (bpp > 1 && plane.endianness != plane.NATIVE)) {
+            return BAD_VALUE;
+        }
+
+        uint32_t planeW = img->mWidth / plane.colSampling;
+        uint32_t planeH = img->mHeight / plane.rowSampling;
+
+        bool canCopyByRow = (plane.colInc == 1) && (img->mPlane[i].mColInc == 1);
+        bool canCopyByPlane = canCopyByRow && (plane.rowInc == img->mPlane[i].mRowInc);
+        if (canCopyByPlane) {
+            MemCopier<ToMediaImage, 0>::copy(imgRow, viewRow, plane.rowInc * planeH);
+        } else if (canCopyByRow) {
+            for (uint32_t row = 0; row < planeH; ++row) {
+                MemCopier<ToMediaImage, 0>::copy(
+                        imgRow, viewRow, std::min(plane.rowInc, img->mPlane[i].mRowInc));
+                imgRow += img->mPlane[i].mRowInc;
+                viewRow += plane.rowInc;
+            }
+        } else {
+            for (uint32_t row = 0; row < planeH; ++row) {
+                decltype(imgRow) imgPtr = imgRow;
+                decltype(viewRow) viewPtr = viewRow;
+                for (uint32_t col = 0; col < planeW; ++col) {
+                    MemCopier<ToMediaImage, 0>::copy(imgPtr, viewPtr, bpp);
+                    imgPtr += img->mPlane[i].mColInc;
+                    viewPtr += plane.colInc;
+                }
+                imgRow += img->mPlane[i].mRowInc;
+                viewRow += plane.rowInc;
+            }
+        }
+    }
+    return OK;
+}
+
+}  // namespace
+
+status_t ImageCopy(uint8_t *imgBase, const MediaImage2 *img, const C2GraphicView &view) {
+    if (view.crop().width != img->mWidth || view.crop().height != img->mHeight) {
+        return BAD_VALUE;
+    }
+    if ((IsNV12(view) && IsI420(img)) || (IsI420(view) && IsNV12(img))) {
+        // Take shortcuts to use libyuv functions between NV12 and I420 conversion.
+        const uint8_t* src_y = view.data()[0];
+        const uint8_t* src_u = view.data()[1];
+        const uint8_t* src_v = view.data()[2];
+        int32_t src_stride_y = view.layout().planes[0].rowInc;
+        int32_t src_stride_u = view.layout().planes[1].rowInc;
+        int32_t src_stride_v = view.layout().planes[2].rowInc;
+        uint8_t* dst_y = imgBase + img->mPlane[0].mOffset;
+        uint8_t* dst_u = imgBase + img->mPlane[1].mOffset;
+        uint8_t* dst_v = imgBase + img->mPlane[2].mOffset;
+        int32_t dst_stride_y = img->mPlane[0].mRowInc;
+        int32_t dst_stride_u = img->mPlane[1].mRowInc;
+        int32_t dst_stride_v = img->mPlane[2].mRowInc;
+        if (IsNV12(view) && IsI420(img)) {
+            if (!libyuv::NV12ToI420(src_y, src_stride_y, src_u, src_stride_u, dst_y, dst_stride_y,
+                                    dst_u, dst_stride_u, dst_v, dst_stride_v, view.crop().width,
+                                    view.crop().height)) {
+                return OK;
+            }
+        } else {
+            if (!libyuv::I420ToNV12(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v,
+                                    dst_y, dst_stride_y, dst_u, dst_stride_u, view.crop().width,
+                                    view.crop().height)) {
+                return OK;
+            }
+        }
+    }
+    return _ImageCopy<true>(view, img, imgBase);
+}
+
+status_t ImageCopy(C2GraphicView &view, const uint8_t *imgBase, const MediaImage2 *img) {
+    if (view.crop().width != img->mWidth || view.crop().height != img->mHeight) {
+        return BAD_VALUE;
+    }
+    if ((IsNV12(img) && IsI420(view)) || (IsI420(img) && IsNV12(view))) {
+        // Take shortcuts to use libyuv functions between NV12 and I420 conversion.
+        const uint8_t* src_y = imgBase + img->mPlane[0].mOffset;
+        const uint8_t* src_u = imgBase + img->mPlane[1].mOffset;
+        const uint8_t* src_v = imgBase + img->mPlane[2].mOffset;
+        int32_t src_stride_y = img->mPlane[0].mRowInc;
+        int32_t src_stride_u = img->mPlane[1].mRowInc;
+        int32_t src_stride_v = img->mPlane[2].mRowInc;
+        uint8_t* dst_y = view.data()[0];
+        uint8_t* dst_u = view.data()[1];
+        uint8_t* dst_v = view.data()[2];
+        int32_t dst_stride_y = view.layout().planes[0].rowInc;
+        int32_t dst_stride_u = view.layout().planes[1].rowInc;
+        int32_t dst_stride_v = view.layout().planes[2].rowInc;
+        if (IsNV12(img) && IsI420(view)) {
+            if (!libyuv::NV12ToI420(src_y, src_stride_y, src_u, src_stride_u, dst_y, dst_stride_y,
+                                    dst_u, dst_stride_u, dst_v, dst_stride_v, view.width(),
+                                    view.height())) {
+                return OK;
+            }
+        } else {
+            if (!libyuv::I420ToNV12(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v,
+                                    dst_y, dst_stride_y, dst_u, dst_stride_u, view.width(),
+                                    view.height())) {
+                return OK;
+            }
+        }
+    }
+    return _ImageCopy<false>(view, img, imgBase);
+}
+
+bool IsYUV420(const C2GraphicView &view) {
+    const C2PlanarLayout &layout = view.layout();
+    return (layout.numPlanes == 3
+            && layout.type == C2PlanarLayout::TYPE_YUV
+            && layout.planes[layout.PLANE_Y].channel == C2PlaneInfo::CHANNEL_Y
+            && layout.planes[layout.PLANE_Y].allocatedDepth == 8
+            && layout.planes[layout.PLANE_Y].bitDepth == 8
+            && layout.planes[layout.PLANE_Y].rightShift == 0
+            && layout.planes[layout.PLANE_Y].colSampling == 1
+            && layout.planes[layout.PLANE_Y].rowSampling == 1
+            && layout.planes[layout.PLANE_U].channel == C2PlaneInfo::CHANNEL_CB
+            && layout.planes[layout.PLANE_U].allocatedDepth == 8
+            && layout.planes[layout.PLANE_U].bitDepth == 8
+            && layout.planes[layout.PLANE_U].rightShift == 0
+            && layout.planes[layout.PLANE_U].colSampling == 2
+            && layout.planes[layout.PLANE_U].rowSampling == 2
+            && layout.planes[layout.PLANE_V].channel == C2PlaneInfo::CHANNEL_CR
+            && layout.planes[layout.PLANE_V].allocatedDepth == 8
+            && layout.planes[layout.PLANE_V].bitDepth == 8
+            && layout.planes[layout.PLANE_V].rightShift == 0
+            && layout.planes[layout.PLANE_V].colSampling == 2
+            && layout.planes[layout.PLANE_V].rowSampling == 2);
+}
+
+bool IsNV12(const C2GraphicView &view) {
+    if (!IsYUV420(view)) {
+        return false;
+    }
+    const C2PlanarLayout &layout = view.layout();
+    return (layout.rootPlanes == 2
+            && layout.planes[layout.PLANE_U].colInc == 2
+            && layout.planes[layout.PLANE_U].rootIx == layout.PLANE_U
+            && layout.planes[layout.PLANE_U].offset == 0
+            && layout.planes[layout.PLANE_V].colInc == 2
+            && layout.planes[layout.PLANE_V].rootIx == layout.PLANE_U
+            && layout.planes[layout.PLANE_V].offset == 1);
+}
+
+bool IsI420(const C2GraphicView &view) {
+    if (!IsYUV420(view)) {
+        return false;
+    }
+    const C2PlanarLayout &layout = view.layout();
+    return (layout.rootPlanes == 3
+            && layout.planes[layout.PLANE_U].colInc == 1
+            && layout.planes[layout.PLANE_U].rootIx == layout.PLANE_U
+            && layout.planes[layout.PLANE_U].offset == 0
+            && layout.planes[layout.PLANE_V].colInc == 1
+            && layout.planes[layout.PLANE_V].rootIx == layout.PLANE_V
+            && layout.planes[layout.PLANE_V].offset == 0);
+}
+
+bool IsYUV420(const MediaImage2 *img) {
+    return (img->mType == MediaImage2::MEDIA_IMAGE_TYPE_YUV
+            && img->mNumPlanes == 3
+            && img->mBitDepth == 8
+            && img->mBitDepthAllocated == 8
+            && img->mPlane[0].mHorizSubsampling == 1
+            && img->mPlane[0].mVertSubsampling == 1
+            && img->mPlane[1].mHorizSubsampling == 2
+            && img->mPlane[1].mVertSubsampling == 2
+            && img->mPlane[2].mHorizSubsampling == 2
+            && img->mPlane[2].mVertSubsampling == 2);
+}
+
+bool IsNV12(const MediaImage2 *img) {
+    if (!IsYUV420(img)) {
+        return false;
+    }
+    return (img->mPlane[1].mColInc == 2
+            && img->mPlane[2].mColInc == 2
+            && (img->mPlane[2].mOffset - img->mPlane[1].mOffset == 1));
+}
+
+bool IsI420(const MediaImage2 *img) {
+    if (!IsYUV420(img)) {
+        return false;
+    }
+    return (img->mPlane[1].mColInc == 1
+            && img->mPlane[2].mColInc == 1
+            && img->mPlane[2].mOffset > img->mPlane[1].mOffset);
+}
+
+MediaImage2 CreateYUV420PlanarMediaImage2(
+        uint32_t width, uint32_t height, uint32_t stride, uint32_t vstride) {
+    return MediaImage2 {
+        .mType = MediaImage2::MEDIA_IMAGE_TYPE_YUV,
+        .mNumPlanes = 3,
+        .mWidth = width,
+        .mHeight = height,
+        .mBitDepth = 8,
+        .mBitDepthAllocated = 8,
+        .mPlane = {
+            {
+                .mOffset = 0,
+                .mColInc = 1,
+                .mRowInc = (int32_t)stride,
+                .mHorizSubsampling = 1,
+                .mVertSubsampling = 1,
+            },
+            {
+                .mOffset = stride * vstride,
+                .mColInc = 1,
+                .mRowInc = (int32_t)stride / 2,
+                .mHorizSubsampling = 2,
+                .mVertSubsampling = 2,
+            },
+            {
+                .mOffset = stride * vstride * 5 / 4,
+                .mColInc = 1,
+                .mRowInc = (int32_t)stride / 2,
+                .mHorizSubsampling = 2,
+                .mVertSubsampling = 2,
+            }
+        },
+    };
+}
+
+MediaImage2 CreateYUV420SemiPlanarMediaImage2(
+        uint32_t width, uint32_t height, uint32_t stride, uint32_t vstride) {
+    return MediaImage2 {
+        .mType = MediaImage2::MEDIA_IMAGE_TYPE_YUV,
+        .mNumPlanes = 3,
+        .mWidth = width,
+        .mHeight = height,
+        .mBitDepth = 8,
+        .mBitDepthAllocated = 8,
+        .mPlane = {
+            {
+                .mOffset = 0,
+                .mColInc = 1,
+                .mRowInc = (int32_t)stride,
+                .mHorizSubsampling = 1,
+                .mVertSubsampling = 1,
+            },
+            {
+                .mOffset = stride * vstride,
+                .mColInc = 2,
+                .mRowInc = (int32_t)stride,
+                .mHorizSubsampling = 2,
+                .mVertSubsampling = 2,
+            },
+            {
+                .mOffset = stride * vstride + 1,
+                .mColInc = 2,
+                .mRowInc = (int32_t)stride,
+                .mHorizSubsampling = 2,
+                .mVertSubsampling = 2,
+            }
+        },
+    };
+}
+
+status_t ConvertRGBToPlanarYUV(
+        uint8_t *dstY, size_t dstStride, size_t dstVStride, size_t bufferSize,
+        const C2GraphicView &src) {
+    CHECK(dstY != nullptr);
+    CHECK((src.width() & 1) == 0);
+    CHECK((src.height() & 1) == 0);
+
+    if (dstStride * dstVStride * 3 / 2 > bufferSize) {
+        ALOGD("conversion buffer is too small for converting from RGB to YUV");
+        return NO_MEMORY;
+    }
+
+    uint8_t *dstU = dstY + dstStride * dstVStride;
+    uint8_t *dstV = dstU + (dstStride >> 1) * (dstVStride >> 1);
+
+    const C2PlanarLayout &layout = src.layout();
+    const uint8_t *pRed   = src.data()[C2PlanarLayout::PLANE_R];
+    const uint8_t *pGreen = src.data()[C2PlanarLayout::PLANE_G];
+    const uint8_t *pBlue  = src.data()[C2PlanarLayout::PLANE_B];
+
+#define CLIP3(x,y,z) (((z) < (x)) ? (x) : (((z) > (y)) ? (y) : (z)))
+    for (size_t y = 0; y < src.height(); ++y) {
+        for (size_t x = 0; x < src.width(); ++x) {
+            uint8_t red = *pRed;
+            uint8_t green = *pGreen;
+            uint8_t blue = *pBlue;
+
+            // using ITU-R BT.601 conversion matrix
+            unsigned luma =
+                CLIP3(0, (((red * 66 + green * 129 + blue * 25) >> 8) + 16), 255);
+
+            dstY[x] = luma;
+
+            if ((x & 1) == 0 && (y & 1) == 0) {
+                unsigned U =
+                    CLIP3(0, (((-red * 38 - green * 74 + blue * 112) >> 8) + 128), 255);
+
+                unsigned V =
+                    CLIP3(0, (((red * 112 - green * 94 - blue * 18) >> 8) + 128), 255);
+
+                dstU[x >> 1] = U;
+                dstV[x >> 1] = V;
+            }
+            pRed   += layout.planes[C2PlanarLayout::PLANE_R].colInc;
+            pGreen += layout.planes[C2PlanarLayout::PLANE_G].colInc;
+            pBlue  += layout.planes[C2PlanarLayout::PLANE_B].colInc;
+        }
+
+        if ((y & 1) == 0) {
+            dstU += dstStride >> 1;
+            dstV += dstStride >> 1;
+        }
+
+        pRed   -= layout.planes[C2PlanarLayout::PLANE_R].colInc * src.width();
+        pGreen -= layout.planes[C2PlanarLayout::PLANE_G].colInc * src.width();
+        pBlue  -= layout.planes[C2PlanarLayout::PLANE_B].colInc * src.width();
+        pRed   += layout.planes[C2PlanarLayout::PLANE_R].rowInc;
+        pGreen += layout.planes[C2PlanarLayout::PLANE_G].rowInc;
+        pBlue  += layout.planes[C2PlanarLayout::PLANE_B].rowInc;
+
+        dstY += dstStride;
+    }
+    return OK;
+}
+
+namespace {
+
+/**
+ * A block of raw allocated memory.
+ */
+struct MemoryBlockPoolBlock {
+    MemoryBlockPoolBlock(size_t size)
+        : mData(new uint8_t[size]), mSize(mData ? size : 0) { }
+
+    ~MemoryBlockPoolBlock() {
+        delete[] mData;
+    }
+
+    const uint8_t *data() const {
+        return mData;
+    }
+
+    size_t size() const {
+        return mSize;
+    }
+
+    C2_DO_NOT_COPY(MemoryBlockPoolBlock);
+
+private:
+    uint8_t *mData;
+    size_t mSize;
+};
+
+/**
+ * A simple raw memory block pool implementation.
+ */
+struct MemoryBlockPoolImpl {
+    void release(std::list<MemoryBlockPoolBlock>::const_iterator block) {
+        std::lock_guard<std::mutex> lock(mMutex);
+        // return block to free blocks if it is the current size; otherwise, discard
+        if (block->size() == mCurrentSize) {
+            mFreeBlocks.splice(mFreeBlocks.begin(), mBlocksInUse, block);
+        } else {
+            mBlocksInUse.erase(block);
+        }
+    }
+
+    std::list<MemoryBlockPoolBlock>::const_iterator fetch(size_t size) {
+        std::lock_guard<std::mutex> lock(mMutex);
+        mFreeBlocks.remove_if([size](const MemoryBlockPoolBlock &block) -> bool {
+            return block.size() != size;
+        });
+        mCurrentSize = size;
+        if (mFreeBlocks.empty()) {
+            mBlocksInUse.emplace_front(size);
+        } else {
+            mBlocksInUse.splice(mBlocksInUse.begin(), mFreeBlocks, mFreeBlocks.begin());
+        }
+        return mBlocksInUse.begin();
+    }
+
+    MemoryBlockPoolImpl() = default;
+
+    C2_DO_NOT_COPY(MemoryBlockPoolImpl);
+
+private:
+    std::mutex mMutex;
+    std::list<MemoryBlockPoolBlock> mFreeBlocks;
+    std::list<MemoryBlockPoolBlock> mBlocksInUse;
+    size_t mCurrentSize;
+};
+
+} // namespace
+
+struct MemoryBlockPool::Impl : MemoryBlockPoolImpl {
+};
+
+struct MemoryBlock::Impl {
+    Impl(std::list<MemoryBlockPoolBlock>::const_iterator block,
+         std::shared_ptr<MemoryBlockPoolImpl> pool)
+        : mBlock(block), mPool(pool) {
+    }
+
+    ~Impl() {
+        mPool->release(mBlock);
+    }
+
+    const uint8_t *data() const {
+        return mBlock->data();
+    }
+
+    size_t size() const {
+        return mBlock->size();
+    }
+
+private:
+    std::list<MemoryBlockPoolBlock>::const_iterator mBlock;
+    std::shared_ptr<MemoryBlockPoolImpl> mPool;
+};
+
+MemoryBlock MemoryBlockPool::fetch(size_t size) {
+    std::list<MemoryBlockPoolBlock>::const_iterator poolBlock = mImpl->fetch(size);
+    return MemoryBlock(std::make_shared<MemoryBlock::Impl>(
+            poolBlock, std::static_pointer_cast<MemoryBlockPoolImpl>(mImpl)));
+}
+
+MemoryBlockPool::MemoryBlockPool()
+    : mImpl(std::make_shared<MemoryBlockPool::Impl>()) {
+}
+
+MemoryBlock::MemoryBlock(std::shared_ptr<MemoryBlock::Impl> impl)
+    : mImpl(impl) {
+}
+
+MemoryBlock::MemoryBlock() = default;
+
+MemoryBlock::~MemoryBlock() = default;
+
+const uint8_t* MemoryBlock::data() const {
+    return mImpl ? mImpl->data() : nullptr;
+}
+
+size_t MemoryBlock::size() const {
+    return mImpl ? mImpl->size() : 0;
+}
+
+MemoryBlock MemoryBlock::Allocate(size_t size) {
+    return MemoryBlockPool().fetch(size);
+}
+
+}  // namespace android
diff --git a/media/codec2/sfplugin/utils/Codec2BufferUtils.h b/media/codec2/sfplugin/utils/Codec2BufferUtils.h
new file mode 100644
index 0000000..afadf00
--- /dev/null
+++ b/media/codec2/sfplugin/utils/Codec2BufferUtils.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_BUFFER_UTILS_H_
+#define CODEC2_BUFFER_UTILS_H_
+
+#include <C2Buffer.h>
+#include <C2ParamDef.h>
+
+#include <media/hardware/VideoAPI.h>
+#include <utils/Errors.h>
+
+namespace android {
+
+/**
+ * Converts an RGB view to planar YUV 420 media image.
+ *
+ * \param dstY       pointer to media image buffer
+ * \param dstStride  stride in bytes
+ * \param dstVStride vertical stride in pixels
+ * \param bufferSize media image buffer size
+ * \param src source image
+ *
+ * \retval NO_MEMORY media image is too small
+ * \retval OK on success
+ */
+status_t ConvertRGBToPlanarYUV(
+        uint8_t *dstY, size_t dstStride, size_t dstVStride, size_t bufferSize,
+        const C2GraphicView &src);
+
+/**
+ * Returns a planar YUV 420 8-bit media image descriptor.
+ *
+ * \param width width of image in pixels
+ * \param height height of image in pixels
+ * \param stride stride of image in pixels
+ * \param vstride vertical stride of image in pixels
+ */
+MediaImage2 CreateYUV420PlanarMediaImage2(
+        uint32_t width, uint32_t height, uint32_t stride, uint32_t vstride);
+
+/**
+ * Returns a semiplanar YUV 420 8-bit media image descriptor.
+ *
+ * \param width width of image in pixels
+ * \param height height of image in pixels
+ * \param stride stride of image in pixels
+ * \param vstride vertical stride of image in pixels
+ */
+MediaImage2 CreateYUV420SemiPlanarMediaImage2(
+        uint32_t width, uint32_t height, uint32_t stride, uint32_t vstride);
+
+/**
+ * Copies a graphic view into a media image.
+ *
+ * \param imgBase base of MediaImage
+ * \param img MediaImage data
+ * \param view graphic view
+ *
+ * \return OK on success
+ */
+status_t ImageCopy(uint8_t *imgBase, const MediaImage2 *img, const C2GraphicView &view);
+
+/**
+ * Copies a media image into a graphic view.
+ *
+ * \param view graphic view
+ * \param imgBase base of MediaImage
+ * \param img MediaImage data
+ *
+ * \return OK on success
+ */
+status_t ImageCopy(C2GraphicView &view, const uint8_t *imgBase, const MediaImage2 *img);
+
+/**
+ * Returns true iff a view has a YUV 420 888 layout.
+ */
+bool IsYUV420(const C2GraphicView &view);
+
+/**
+ * Returns true iff a view has a NV12 layout.
+ */
+bool IsNV12(const C2GraphicView &view);
+
+/**
+ * Returns true iff a view has a I420 layout.
+ */
+bool IsI420(const C2GraphicView &view);
+
+/**
+ * Returns true iff a MediaImage2 has a YUV 420 888 layout.
+ */
+bool IsYUV420(const MediaImage2 *img);
+
+/**
+ * Returns true iff a MediaImage2 has a NV12 layout.
+ */
+bool IsNV12(const MediaImage2 *img);
+
+/**
+ * Returns true iff a MediaImage2 has a I420 layout.
+ */
+bool IsI420(const MediaImage2 *img);
+
+/**
+ * A raw memory block to use for internal buffers.
+ *
+ * TODO: replace this with C2LinearBlocks from a private C2BlockPool
+ */
+struct MemoryBlock : public C2MemoryBlock<uint8_t> {
+    virtual const uint8_t* data() const override;
+    virtual size_t size() const override;
+
+    inline uint8_t *data() {
+        return const_cast<uint8_t*>(const_cast<const MemoryBlock*>(this)->data());
+    }
+
+    // allocates an unmanaged block (not in a pool)
+    static MemoryBlock Allocate(size_t);
+
+    // memory block with no actual memory (size is 0, data is null)
+    MemoryBlock();
+
+    struct Impl;
+    MemoryBlock(std::shared_ptr<Impl> impl);
+    virtual ~MemoryBlock();
+
+private:
+    std::shared_ptr<Impl> mImpl;
+};
+
+/**
+ * A raw memory mini-pool.
+ */
+struct MemoryBlockPool {
+    /**
+     * Fetches a block with a given size.
+     *
+     * \param size size in bytes
+     */
+    MemoryBlock fetch(size_t size);
+
+    MemoryBlockPool();
+    ~MemoryBlockPool() = default;
+
+private:
+    struct Impl;
+    std::shared_ptr<Impl> mImpl;
+};
+
+} // namespace android
+
+#endif  // CODEC2_BUFFER_UTILS_H_
diff --git a/media/codec2/sfplugin/utils/Codec2Mapper.cpp b/media/codec2/sfplugin/utils/Codec2Mapper.cpp
new file mode 100644
index 0000000..40160c7
--- /dev/null
+++ b/media/codec2/sfplugin/utils/Codec2Mapper.cpp
@@ -0,0 +1,947 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2Mapper"
+#include <utils/Log.h>
+
+#include <media/stagefright/MediaCodecConstants.h>
+#include <media/stagefright/SurfaceUtils.h>
+#include <media/stagefright/foundation/ALookup.h>
+#include <media/stagefright/foundation/ColorUtils.h>
+#include <media/stagefright/foundation/MediaDefs.h>
+
+#include <stdint.h>  // for INT32_MAX
+
+#include "Codec2Mapper.h"
+
+using namespace android;
+
+namespace {
+
+ALookup<C2Config::profile_t, int32_t> sAacProfiles = {
+    { C2Config::PROFILE_AAC_LC,         AACObjectLC },
+    { C2Config::PROFILE_AAC_MAIN,       AACObjectMain },
+    { C2Config::PROFILE_AAC_SSR,        AACObjectSSR },
+    { C2Config::PROFILE_AAC_LTP,        AACObjectLTP },
+    { C2Config::PROFILE_AAC_HE,         AACObjectHE },
+    { C2Config::PROFILE_AAC_SCALABLE,   AACObjectScalable },
+    { C2Config::PROFILE_AAC_ER_LC,      AACObjectERLC },
+    { C2Config::PROFILE_AAC_ER_SCALABLE, AACObjectERScalable },
+    { C2Config::PROFILE_AAC_LD,         AACObjectLD },
+    { C2Config::PROFILE_AAC_HE_PS,      AACObjectHE_PS },
+    { C2Config::PROFILE_AAC_ELD,        AACObjectELD },
+    { C2Config::PROFILE_AAC_XHE,        AACObjectXHE },
+};
+
+ALookup<C2Config::level_t, int32_t> sAvcLevels = {
+    { C2Config::LEVEL_AVC_1,    AVCLevel1 },
+    { C2Config::LEVEL_AVC_1B,   AVCLevel1b },
+    { C2Config::LEVEL_AVC_1_1,  AVCLevel11 },
+    { C2Config::LEVEL_AVC_1_2,  AVCLevel12 },
+    { C2Config::LEVEL_AVC_1_3,  AVCLevel13 },
+    { C2Config::LEVEL_AVC_2,    AVCLevel2 },
+    { C2Config::LEVEL_AVC_2_1,  AVCLevel21 },
+    { C2Config::LEVEL_AVC_2_2,  AVCLevel22 },
+    { C2Config::LEVEL_AVC_3,    AVCLevel3 },
+    { C2Config::LEVEL_AVC_3_1,  AVCLevel31 },
+    { C2Config::LEVEL_AVC_3_2,  AVCLevel32 },
+    { C2Config::LEVEL_AVC_4,    AVCLevel4 },
+    { C2Config::LEVEL_AVC_4_1,  AVCLevel41 },
+    { C2Config::LEVEL_AVC_4_2,  AVCLevel42 },
+    { C2Config::LEVEL_AVC_5,    AVCLevel5 },
+    { C2Config::LEVEL_AVC_5_1,  AVCLevel51 },
+    { C2Config::LEVEL_AVC_5_2,  AVCLevel52 },
+    { C2Config::LEVEL_AVC_6,    AVCLevel6 },
+    { C2Config::LEVEL_AVC_6_1,  AVCLevel61 },
+    { C2Config::LEVEL_AVC_6_2,  AVCLevel62 },
+};
+
+ALookup<C2Config::profile_t, int32_t> sAvcProfiles = {
+    // treat restricted profiles as full profile if there is no equivalent - which works for
+    // decoders, but not for encoders
+    { C2Config::PROFILE_AVC_BASELINE,               AVCProfileBaseline },
+    { C2Config::PROFILE_AVC_CONSTRAINED_BASELINE,   AVCProfileConstrainedBaseline },
+    { C2Config::PROFILE_AVC_MAIN,                   AVCProfileMain },
+    { C2Config::PROFILE_AVC_EXTENDED,               AVCProfileExtended },
+    { C2Config::PROFILE_AVC_HIGH,                   AVCProfileHigh },
+    { C2Config::PROFILE_AVC_PROGRESSIVE_HIGH,       AVCProfileHigh },
+    { C2Config::PROFILE_AVC_CONSTRAINED_HIGH,       AVCProfileConstrainedHigh },
+    { C2Config::PROFILE_AVC_HIGH_10,                AVCProfileHigh10 },
+    { C2Config::PROFILE_AVC_PROGRESSIVE_HIGH_10,    AVCProfileHigh10 },
+    { C2Config::PROFILE_AVC_HIGH_422,               AVCProfileHigh422 },
+    { C2Config::PROFILE_AVC_HIGH_444_PREDICTIVE,    AVCProfileHigh444 },
+    { C2Config::PROFILE_AVC_HIGH_10_INTRA,          AVCProfileHigh10 },
+    { C2Config::PROFILE_AVC_HIGH_422_INTRA,         AVCProfileHigh422 },
+    { C2Config::PROFILE_AVC_HIGH_444_INTRA,         AVCProfileHigh444 },
+    { C2Config::PROFILE_AVC_CAVLC_444_INTRA,        AVCProfileHigh444 },
+};
+
+ALookup<C2Config::bitrate_mode_t, int32_t> sBitrateModes = {
+    { C2Config::BITRATE_CONST,      BITRATE_MODE_CBR },
+    { C2Config::BITRATE_VARIABLE,   BITRATE_MODE_VBR },
+    { C2Config::BITRATE_IGNORE,     BITRATE_MODE_CQ },
+};
+
+ALookup<C2Color::matrix_t, ColorAspects::MatrixCoeffs> sColorMatricesSf = {
+    { C2Color::MATRIX_UNSPECIFIED,     ColorAspects::MatrixUnspecified },
+    { C2Color::MATRIX_BT709,           ColorAspects::MatrixBT709_5 },
+    { C2Color::MATRIX_FCC47_73_682,    ColorAspects::MatrixBT470_6M },
+    { C2Color::MATRIX_BT601,           ColorAspects::MatrixBT601_6 },
+    { C2Color::MATRIX_240M,       ColorAspects::MatrixSMPTE240M },
+    { C2Color::MATRIX_BT2020,          ColorAspects::MatrixBT2020 },
+    { C2Color::MATRIX_BT2020_CONSTANT, ColorAspects::MatrixBT2020Constant },
+    { C2Color::MATRIX_OTHER,           ColorAspects::MatrixOther },
+};
+
+ALookup<C2Color::primaries_t, ColorAspects::Primaries> sColorPrimariesSf = {
+    { C2Color::PRIMARIES_UNSPECIFIED,  ColorAspects::PrimariesUnspecified },
+    { C2Color::PRIMARIES_BT709,        ColorAspects::PrimariesBT709_5 },
+    { C2Color::PRIMARIES_BT470_M,      ColorAspects::PrimariesBT470_6M },
+    { C2Color::PRIMARIES_BT601_625,    ColorAspects::PrimariesBT601_6_625 },
+    { C2Color::PRIMARIES_BT601_525,    ColorAspects::PrimariesBT601_6_525 },
+    { C2Color::PRIMARIES_GENERIC_FILM, ColorAspects::PrimariesGenericFilm },
+    { C2Color::PRIMARIES_BT2020,       ColorAspects::PrimariesBT2020 },
+//    { C2Color::PRIMARIES_RP431,        ColorAspects::Primaries... },
+//    { C2Color::PRIMARIES_EG432,        ColorAspects::Primaries... },
+//    { C2Color::PRIMARIES_EBU3213,      ColorAspects::Primaries... },
+    { C2Color::PRIMARIES_OTHER,        ColorAspects::PrimariesOther },
+};
+
+ALookup<C2Color::range_t, int32_t> sColorRanges = {
+    { C2Color::RANGE_FULL,    COLOR_RANGE_FULL },
+    { C2Color::RANGE_LIMITED, COLOR_RANGE_LIMITED },
+};
+
+ALookup<C2Color::range_t, ColorAspects::Range> sColorRangesSf = {
+    { C2Color::RANGE_UNSPECIFIED, ColorAspects::RangeUnspecified },
+    { C2Color::RANGE_FULL,        ColorAspects::RangeFull },
+    { C2Color::RANGE_LIMITED,     ColorAspects::RangeLimited },
+    { C2Color::RANGE_OTHER,       ColorAspects::RangeOther },
+};
+
+ALookup<C2Color::transfer_t, int32_t> sColorTransfers = {
+    { C2Color::TRANSFER_LINEAR, COLOR_TRANSFER_LINEAR },
+    { C2Color::TRANSFER_170M,   COLOR_TRANSFER_SDR_VIDEO },
+    { C2Color::TRANSFER_ST2084, COLOR_TRANSFER_ST2084 },
+    { C2Color::TRANSFER_HLG,    COLOR_TRANSFER_HLG },
+};
+
+ALookup<C2Color::transfer_t, ColorAspects::Transfer> sColorTransfersSf = {
+    { C2Color::TRANSFER_UNSPECIFIED, ColorAspects::TransferUnspecified },
+    { C2Color::TRANSFER_LINEAR,      ColorAspects::TransferLinear },
+    { C2Color::TRANSFER_SRGB,        ColorAspects::TransferSRGB },
+    { C2Color::TRANSFER_170M,        ColorAspects::TransferSMPTE170M },
+    { C2Color::TRANSFER_GAMMA22,     ColorAspects::TransferGamma22 },
+    { C2Color::TRANSFER_GAMMA28,     ColorAspects::TransferGamma28 },
+    { C2Color::TRANSFER_ST2084,      ColorAspects::TransferST2084 },
+    { C2Color::TRANSFER_HLG,         ColorAspects::TransferHLG },
+    { C2Color::TRANSFER_240M,        ColorAspects::TransferSMPTE240M },
+    { C2Color::TRANSFER_XVYCC,       ColorAspects::TransferXvYCC },
+    { C2Color::TRANSFER_BT1361,      ColorAspects::TransferBT1361 },
+    { C2Color::TRANSFER_ST428,       ColorAspects::TransferST428 },
+    { C2Color::TRANSFER_OTHER,       ColorAspects::TransferOther },
+};
+
+ALookup<C2Config::level_t, int32_t> sDolbyVisionLevels = {
+    { C2Config::LEVEL_DV_MAIN_HD_24,  DolbyVisionLevelHd24 },
+    { C2Config::LEVEL_DV_MAIN_HD_30,  DolbyVisionLevelHd30 },
+    { C2Config::LEVEL_DV_MAIN_FHD_24, DolbyVisionLevelFhd24 },
+    { C2Config::LEVEL_DV_MAIN_FHD_30, DolbyVisionLevelFhd30 },
+    { C2Config::LEVEL_DV_MAIN_FHD_60, DolbyVisionLevelFhd60 },
+    { C2Config::LEVEL_DV_MAIN_UHD_24, DolbyVisionLevelUhd24 },
+    { C2Config::LEVEL_DV_MAIN_UHD_30, DolbyVisionLevelUhd30 },
+    { C2Config::LEVEL_DV_MAIN_UHD_48, DolbyVisionLevelUhd48 },
+    { C2Config::LEVEL_DV_MAIN_UHD_60, DolbyVisionLevelUhd60 },
+
+    // high tiers are not yet supported on android, for now map them to main tier
+    { C2Config::LEVEL_DV_HIGH_HD_24,  DolbyVisionLevelHd24 },
+    { C2Config::LEVEL_DV_HIGH_HD_30,  DolbyVisionLevelHd30 },
+    { C2Config::LEVEL_DV_HIGH_FHD_24, DolbyVisionLevelFhd24 },
+    { C2Config::LEVEL_DV_HIGH_FHD_30, DolbyVisionLevelFhd30 },
+    { C2Config::LEVEL_DV_HIGH_FHD_60, DolbyVisionLevelFhd60 },
+    { C2Config::LEVEL_DV_HIGH_UHD_24, DolbyVisionLevelUhd24 },
+    { C2Config::LEVEL_DV_HIGH_UHD_30, DolbyVisionLevelUhd30 },
+    { C2Config::LEVEL_DV_HIGH_UHD_48, DolbyVisionLevelUhd48 },
+    { C2Config::LEVEL_DV_HIGH_UHD_60, DolbyVisionLevelUhd60 },
+};
+
+ALookup<C2Config::profile_t, int32_t> sDolbyVisionProfiles = {
+    { C2Config::PROFILE_DV_AV_PER, DolbyVisionProfileDvavPer },
+    { C2Config::PROFILE_DV_AV_PEN, DolbyVisionProfileDvavPen },
+    { C2Config::PROFILE_DV_HE_DER, DolbyVisionProfileDvheDer },
+    { C2Config::PROFILE_DV_HE_DEN, DolbyVisionProfileDvheDen },
+    { C2Config::PROFILE_DV_HE_04, DolbyVisionProfileDvheDtr },
+    { C2Config::PROFILE_DV_HE_05, DolbyVisionProfileDvheStn },
+    { C2Config::PROFILE_DV_HE_DTH, DolbyVisionProfileDvheDth },
+    { C2Config::PROFILE_DV_HE_07, DolbyVisionProfileDvheDtb },
+    { C2Config::PROFILE_DV_HE_08, DolbyVisionProfileDvheSt },
+    { C2Config::PROFILE_DV_AV_09, DolbyVisionProfileDvavSe },
+};
+
+ALookup<C2Config::level_t, int32_t> sH263Levels = {
+    { C2Config::LEVEL_H263_10, H263Level10 },
+    { C2Config::LEVEL_H263_20, H263Level20 },
+    { C2Config::LEVEL_H263_30, H263Level30 },
+    { C2Config::LEVEL_H263_40, H263Level40 },
+    { C2Config::LEVEL_H263_45, H263Level45 },
+    { C2Config::LEVEL_H263_50, H263Level50 },
+    { C2Config::LEVEL_H263_60, H263Level60 },
+    { C2Config::LEVEL_H263_70, H263Level70 },
+};
+
+ALookup<C2Config::profile_t, int32_t> sH263Profiles = {
+    { C2Config::PROFILE_H263_BASELINE,          H263ProfileBaseline },
+    { C2Config::PROFILE_H263_H320,              H263ProfileH320Coding },
+    { C2Config::PROFILE_H263_V1BC,              H263ProfileBackwardCompatible },
+    { C2Config::PROFILE_H263_ISWV2,             H263ProfileISWV2 },
+    { C2Config::PROFILE_H263_ISWV3,             H263ProfileISWV3 },
+    { C2Config::PROFILE_H263_HIGH_COMPRESSION,  H263ProfileHighCompression },
+    { C2Config::PROFILE_H263_INTERNET,          H263ProfileInternet },
+    { C2Config::PROFILE_H263_INTERLACE,         H263ProfileInterlace },
+    { C2Config::PROFILE_H263_HIGH_LATENCY,      H263ProfileHighLatency },
+};
+
+ALookup<C2Config::level_t, int32_t> sHevcLevels = {
+    { C2Config::LEVEL_HEVC_MAIN_1,      HEVCMainTierLevel1 },
+    { C2Config::LEVEL_HEVC_MAIN_2,      HEVCMainTierLevel2 },
+    { C2Config::LEVEL_HEVC_MAIN_2_1,    HEVCMainTierLevel21 },
+    { C2Config::LEVEL_HEVC_MAIN_3,      HEVCMainTierLevel3 },
+    { C2Config::LEVEL_HEVC_MAIN_3_1,    HEVCMainTierLevel31 },
+    { C2Config::LEVEL_HEVC_MAIN_4,      HEVCMainTierLevel4 },
+    { C2Config::LEVEL_HEVC_MAIN_4_1,    HEVCMainTierLevel41 },
+    { C2Config::LEVEL_HEVC_MAIN_5,      HEVCMainTierLevel5 },
+    { C2Config::LEVEL_HEVC_MAIN_5_1,    HEVCMainTierLevel51 },
+    { C2Config::LEVEL_HEVC_MAIN_5_2,    HEVCMainTierLevel52 },
+    { C2Config::LEVEL_HEVC_MAIN_6,      HEVCMainTierLevel6 },
+    { C2Config::LEVEL_HEVC_MAIN_6_1,    HEVCMainTierLevel61 },
+    { C2Config::LEVEL_HEVC_MAIN_6_2,    HEVCMainTierLevel62 },
+
+    { C2Config::LEVEL_HEVC_HIGH_4,      HEVCHighTierLevel4 },
+    { C2Config::LEVEL_HEVC_HIGH_4_1,    HEVCHighTierLevel41 },
+    { C2Config::LEVEL_HEVC_HIGH_5,      HEVCHighTierLevel5 },
+    { C2Config::LEVEL_HEVC_HIGH_5_1,    HEVCHighTierLevel51 },
+    { C2Config::LEVEL_HEVC_HIGH_5_2,    HEVCHighTierLevel52 },
+    { C2Config::LEVEL_HEVC_HIGH_6,      HEVCHighTierLevel6 },
+    { C2Config::LEVEL_HEVC_HIGH_6_1,    HEVCHighTierLevel61 },
+    { C2Config::LEVEL_HEVC_HIGH_6_2,    HEVCHighTierLevel62 },
+
+    // map high tier levels below 4 to main tier
+    { C2Config::LEVEL_HEVC_MAIN_1,      HEVCHighTierLevel1 },
+    { C2Config::LEVEL_HEVC_MAIN_2,      HEVCHighTierLevel2 },
+    { C2Config::LEVEL_HEVC_MAIN_2_1,    HEVCHighTierLevel21 },
+    { C2Config::LEVEL_HEVC_MAIN_3,      HEVCHighTierLevel3 },
+    { C2Config::LEVEL_HEVC_MAIN_3_1,    HEVCHighTierLevel31 },
+};
+
+ALookup<C2Config::profile_t, int32_t> sHevcProfiles = {
+    { C2Config::PROFILE_HEVC_MAIN, HEVCProfileMain },
+    { C2Config::PROFILE_HEVC_MAIN_10, HEVCProfileMain10 },
+    { C2Config::PROFILE_HEVC_MAIN_STILL, HEVCProfileMainStill },
+    { C2Config::PROFILE_HEVC_MAIN_INTRA, HEVCProfileMain },
+    { C2Config::PROFILE_HEVC_MAIN_10_INTRA, HEVCProfileMain10 },
+};
+
+ALookup<C2Config::profile_t, int32_t> sHevcHdrProfiles = {
+    { C2Config::PROFILE_HEVC_MAIN_10, HEVCProfileMain10HDR10 },
+};
+
+ALookup<C2Config::profile_t, int32_t> sHevcHdr10PlusProfiles = {
+    { C2Config::PROFILE_HEVC_MAIN_10, HEVCProfileMain10HDR10Plus },
+};
+
+ALookup<C2Config::level_t, int32_t> sMpeg2Levels = {
+    { C2Config::LEVEL_MP2V_LOW,         MPEG2LevelLL },
+    { C2Config::LEVEL_MP2V_MAIN,        MPEG2LevelML },
+    { C2Config::LEVEL_MP2V_HIGH_1440,   MPEG2LevelH14 },
+    { C2Config::LEVEL_MP2V_HIGH,        MPEG2LevelHL },
+    { C2Config::LEVEL_MP2V_HIGHP,       MPEG2LevelHP },
+};
+
+ALookup<C2Config::profile_t, int32_t> sMpeg2Profiles = {
+    { C2Config::PROFILE_MP2V_SIMPLE,                MPEG2ProfileSimple },
+    { C2Config::PROFILE_MP2V_MAIN,                  MPEG2ProfileMain },
+    { C2Config::PROFILE_MP2V_SNR_SCALABLE,          MPEG2ProfileSNR },
+    { C2Config::PROFILE_MP2V_SPATIALLY_SCALABLE,    MPEG2ProfileSpatial },
+    { C2Config::PROFILE_MP2V_HIGH,                  MPEG2ProfileHigh },
+    { C2Config::PROFILE_MP2V_422,                   MPEG2Profile422 },
+};
+
+ALookup<C2Config::level_t, int32_t> sMpeg4Levels = {
+    { C2Config::LEVEL_MP4V_0,   MPEG4Level0 },
+    { C2Config::LEVEL_MP4V_0B,  MPEG4Level0b },
+    { C2Config::LEVEL_MP4V_1,   MPEG4Level1 },
+    { C2Config::LEVEL_MP4V_2,   MPEG4Level2 },
+    { C2Config::LEVEL_MP4V_3,   MPEG4Level3 },
+    { C2Config::LEVEL_MP4V_3B,  MPEG4Level3b },
+    { C2Config::LEVEL_MP4V_4,   MPEG4Level4 },
+    { C2Config::LEVEL_MP4V_4A,  MPEG4Level4a },
+    { C2Config::LEVEL_MP4V_5,   MPEG4Level5 },
+    { C2Config::LEVEL_MP4V_6,   MPEG4Level6 },
+};
+
+ALookup<C2Config::profile_t, int32_t> sMpeg4Profiles = {
+    { C2Config::PROFILE_MP4V_SIMPLE,            MPEG4ProfileSimple },
+    { C2Config::PROFILE_MP4V_SIMPLE_SCALABLE,   MPEG4ProfileSimpleScalable },
+    { C2Config::PROFILE_MP4V_CORE,              MPEG4ProfileCore },
+    { C2Config::PROFILE_MP4V_MAIN,              MPEG4ProfileMain },
+    { C2Config::PROFILE_MP4V_NBIT,              MPEG4ProfileNbit },
+    { C2Config::PROFILE_MP4V_ARTS,              MPEG4ProfileAdvancedRealTime },
+    { C2Config::PROFILE_MP4V_CORE_SCALABLE,     MPEG4ProfileCoreScalable },
+    { C2Config::PROFILE_MP4V_ACE,               MPEG4ProfileAdvancedCoding },
+    { C2Config::PROFILE_MP4V_ADVANCED_CORE,     MPEG4ProfileAdvancedCore },
+    { C2Config::PROFILE_MP4V_ADVANCED_SIMPLE,   MPEG4ProfileAdvancedSimple },
+};
+
+ALookup<C2Config::pcm_encoding_t, int32_t> sPcmEncodings = {
+    { C2Config::PCM_8, kAudioEncodingPcm8bit },
+    { C2Config::PCM_16, kAudioEncodingPcm16bit },
+    { C2Config::PCM_FLOAT, kAudioEncodingPcmFloat },
+};
+
+ALookup<C2Config::level_t, int32_t> sVp9Levels = {
+    { C2Config::LEVEL_VP9_1,    VP9Level1 },
+    { C2Config::LEVEL_VP9_1_1,  VP9Level11 },
+    { C2Config::LEVEL_VP9_2,    VP9Level2 },
+    { C2Config::LEVEL_VP9_2_1,  VP9Level21 },
+    { C2Config::LEVEL_VP9_3,    VP9Level3 },
+    { C2Config::LEVEL_VP9_3_1,  VP9Level31 },
+    { C2Config::LEVEL_VP9_4,    VP9Level4 },
+    { C2Config::LEVEL_VP9_4_1,  VP9Level41 },
+    { C2Config::LEVEL_VP9_5,    VP9Level5 },
+    { C2Config::LEVEL_VP9_5_1,  VP9Level51 },
+    { C2Config::LEVEL_VP9_5_2,  VP9Level52 },
+    { C2Config::LEVEL_VP9_6,    VP9Level6 },
+    { C2Config::LEVEL_VP9_6_1,  VP9Level61 },
+    { C2Config::LEVEL_VP9_6_2,  VP9Level62 },
+};
+
+ALookup<C2Config::profile_t, int32_t> sVp9Profiles = {
+    { C2Config::PROFILE_VP9_0, VP9Profile0 },
+    { C2Config::PROFILE_VP9_1, VP9Profile1 },
+    { C2Config::PROFILE_VP9_2, VP9Profile2 },
+    { C2Config::PROFILE_VP9_3, VP9Profile3 },
+    { C2Config::PROFILE_VP9_2, VP9Profile2HDR },
+    { C2Config::PROFILE_VP9_3, VP9Profile3HDR },
+    { C2Config::PROFILE_VP9_2, VP9Profile2HDR10Plus },
+    { C2Config::PROFILE_VP9_3, VP9Profile3HDR10Plus },
+};
+
+ALookup<C2Config::profile_t, int32_t> sVp9HdrProfiles = {
+    { C2Config::PROFILE_VP9_2, VP9Profile2HDR },
+    { C2Config::PROFILE_VP9_3, VP9Profile3HDR },
+};
+
+ALookup<C2Config::profile_t, int32_t> sVp9Hdr10PlusProfiles = {
+    { C2Config::PROFILE_VP9_2, VP9Profile2HDR10Plus },
+    { C2Config::PROFILE_VP9_3, VP9Profile3HDR10Plus },
+};
+
+ALookup<C2Config::level_t, int32_t> sAv1Levels = {
+    { C2Config::LEVEL_AV1_2,    AV1Level2  },
+    { C2Config::LEVEL_AV1_2_1,  AV1Level21 },
+    { C2Config::LEVEL_AV1_2_2,  AV1Level22 },
+    { C2Config::LEVEL_AV1_2_3,  AV1Level23 },
+    { C2Config::LEVEL_AV1_3,    AV1Level3  },
+    { C2Config::LEVEL_AV1_3_1,  AV1Level31 },
+    { C2Config::LEVEL_AV1_3_2,  AV1Level32 },
+    { C2Config::LEVEL_AV1_3_3,  AV1Level33 },
+    { C2Config::LEVEL_AV1_4,    AV1Level4  },
+    { C2Config::LEVEL_AV1_4_1,  AV1Level41 },
+    { C2Config::LEVEL_AV1_4_2,  AV1Level42 },
+    { C2Config::LEVEL_AV1_4_3,  AV1Level43 },
+    { C2Config::LEVEL_AV1_5,    AV1Level5  },
+    { C2Config::LEVEL_AV1_5_1,  AV1Level51 },
+    { C2Config::LEVEL_AV1_5_2,  AV1Level52 },
+    { C2Config::LEVEL_AV1_5_3,  AV1Level53 },
+    { C2Config::LEVEL_AV1_6,    AV1Level6  },
+    { C2Config::LEVEL_AV1_6_1,  AV1Level61 },
+    { C2Config::LEVEL_AV1_6_2,  AV1Level62 },
+    { C2Config::LEVEL_AV1_6_3,  AV1Level63 },
+    { C2Config::LEVEL_AV1_7,    AV1Level7  },
+    { C2Config::LEVEL_AV1_7_1,  AV1Level71 },
+    { C2Config::LEVEL_AV1_7_2,  AV1Level72 },
+    { C2Config::LEVEL_AV1_7_3,  AV1Level73 },
+};
+
+
+ALookup<C2Config::profile_t, int32_t> sAv1Profiles = {
+    // TODO: will need to disambiguate between Main8 and Main10
+    { C2Config::PROFILE_AV1_0, AV1ProfileMain8 },
+    { C2Config::PROFILE_AV1_0, AV1ProfileMain10 },
+};
+
+ALookup<C2Config::profile_t, int32_t> sAv1HdrProfiles = {
+    { C2Config::PROFILE_AV1_0, AV1ProfileMain10 },
+    { C2Config::PROFILE_AV1_0, AV1ProfileMain10HDR10 },
+};
+
+ALookup<C2Config::profile_t, int32_t> sAv1Hdr10PlusProfiles = {
+    { C2Config::PROFILE_AV1_0, AV1ProfileMain10HDR10Plus },
+};
+
+/**
+ * A helper that passes through vendor extension profile and level values.
+ */
+struct ProfileLevelMapperHelper : C2Mapper::ProfileLevelMapper {
+    virtual bool simpleMap(C2Config::level_t from, int32_t *to) = 0;
+    virtual bool simpleMap(int32_t from, C2Config::level_t *to) = 0;
+    virtual bool simpleMap(C2Config::profile_t from, int32_t *to) = 0;
+    virtual bool simpleMap(int32_t from, C2Config::profile_t *to) = 0;
+
+    template<typename T, typename U>
+    bool passThroughMap(T from, U *to) {
+        // allow (and pass through) vendor extensions
+        if (from >= (T)C2_PROFILE_LEVEL_VENDOR_START && from < (T)INT32_MAX) {
+            *to = (U)from;
+            return true;
+        }
+        return simpleMap(from, to);
+    }
+
+    virtual bool mapLevel(C2Config::level_t from, int32_t *to) {
+        return passThroughMap(from, to);
+    }
+
+    virtual bool mapLevel(int32_t from, C2Config::level_t *to) {
+        return passThroughMap(from, to);
+    }
+
+    virtual bool mapProfile(C2Config::profile_t from, int32_t *to) {
+        return passThroughMap(from, to);
+    }
+
+    virtual bool mapProfile(int32_t from, C2Config::profile_t *to) {
+        return passThroughMap(from, to);
+    }
+};
+
+// AAC only uses profiles, map all levels to unused or 0
+struct AacProfileLevelMapper : ProfileLevelMapperHelper {
+    virtual bool simpleMap(C2Config::level_t, int32_t *to) {
+        *to = 0;
+        return true;
+    }
+    virtual bool simpleMap(int32_t, C2Config::level_t *to) {
+        *to = C2Config::LEVEL_UNUSED;
+        return true;
+    }
+    virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
+        return sAacProfiles.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
+        return sAacProfiles.map(from, to);
+    }
+};
+
+struct AvcProfileLevelMapper : ProfileLevelMapperHelper {
+    virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
+        return sAvcLevels.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
+        return sAvcLevels.map(from, to);
+    }
+    virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
+        return sAvcProfiles.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
+        return sAvcProfiles.map(from, to);
+    }
+};
+
+struct DolbyVisionProfileLevelMapper : ProfileLevelMapperHelper {
+    virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
+        return sDolbyVisionLevels.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
+        return sDolbyVisionLevels.map(from, to);
+    }
+    virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
+        return sDolbyVisionProfiles.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
+        return sDolbyVisionProfiles.map(from, to);
+    }
+};
+
+struct H263ProfileLevelMapper : ProfileLevelMapperHelper {
+    virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
+        return sH263Levels.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
+        return sH263Levels.map(from, to);
+    }
+    virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
+        return sH263Profiles.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
+        return sH263Profiles.map(from, to);
+    }
+};
+
+struct HevcProfileLevelMapper : ProfileLevelMapperHelper {
+    HevcProfileLevelMapper(bool isHdr = false, bool isHdr10Plus = false) :
+        ProfileLevelMapperHelper(),
+        mIsHdr(isHdr), mIsHdr10Plus(isHdr10Plus) {}
+
+    virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
+        return sHevcLevels.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
+        return sHevcLevels.map(from, to);
+    }
+    virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
+        return mIsHdr10Plus ? sHevcHdr10PlusProfiles.map(from, to) :
+                     mIsHdr ? sHevcHdrProfiles.map(from, to) :
+                              sHevcProfiles.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
+        return mIsHdr10Plus ? sHevcHdr10PlusProfiles.map(from, to) :
+                     mIsHdr ? sHevcHdrProfiles.map(from, to) :
+                              sHevcProfiles.map(from, to);
+    }
+
+private:
+    bool mIsHdr;
+    bool mIsHdr10Plus;
+};
+
+struct Mpeg2ProfileLevelMapper : ProfileLevelMapperHelper {
+    virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
+        return sMpeg2Levels.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
+        return sMpeg2Levels.map(from, to);
+    }
+    virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
+        return sMpeg2Profiles.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
+        return sMpeg2Profiles.map(from, to);
+    }
+};
+
+struct Mpeg4ProfileLevelMapper : ProfileLevelMapperHelper {
+    virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
+        return sMpeg4Levels.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
+        return sMpeg4Levels.map(from, to);
+    }
+    virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
+        return sMpeg4Profiles.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
+        return sMpeg4Profiles.map(from, to);
+    }
+};
+
+// VP8 has no profiles and levels in Codec 2.0, but we use main profile and level 0 in MediaCodec
+// map all profiles and levels to that.
+struct Vp8ProfileLevelMapper : ProfileLevelMapperHelper {
+    virtual bool simpleMap(C2Config::level_t, int32_t *to) {
+        *to = VP8Level_Version0;
+        return true;
+    }
+    virtual bool simpleMap(int32_t, C2Config::level_t *to) {
+        *to = C2Config::LEVEL_UNUSED;
+        return true;
+    }
+    virtual bool simpleMap(C2Config::profile_t, int32_t *to) {
+        *to = VP8ProfileMain;
+        return true;
+    }
+    virtual bool simpleMap(int32_t, C2Config::profile_t *to) {
+        *to = C2Config::PROFILE_UNUSED;
+        return true;
+    }
+};
+
+struct Vp9ProfileLevelMapper : ProfileLevelMapperHelper {
+    Vp9ProfileLevelMapper(bool isHdr = false, bool isHdr10Plus = false) :
+        ProfileLevelMapperHelper(),
+        mIsHdr(isHdr), mIsHdr10Plus(isHdr10Plus) {}
+
+    virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
+        return sVp9Levels.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
+        return sVp9Levels.map(from, to);
+    }
+    virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
+        return mIsHdr10Plus ? sVp9Hdr10PlusProfiles.map(from, to) :
+                     mIsHdr ? sVp9HdrProfiles.map(from, to) :
+                              sVp9Profiles.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
+        return mIsHdr10Plus ? sVp9Hdr10PlusProfiles.map(from, to) :
+                     mIsHdr ? sVp9HdrProfiles.map(from, to) :
+                              sVp9Profiles.map(from, to);
+    }
+
+private:
+    bool mIsHdr;
+    bool mIsHdr10Plus;
+};
+
+struct Av1ProfileLevelMapper : ProfileLevelMapperHelper {
+    Av1ProfileLevelMapper(bool isHdr = false, bool isHdr10Plus = false) :
+        ProfileLevelMapperHelper(),
+        mIsHdr(isHdr), mIsHdr10Plus(isHdr10Plus) {}
+
+    virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
+        return sAv1Levels.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
+        return sAv1Levels.map(from, to);
+    }
+    virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
+        return mIsHdr10Plus ? sAv1Hdr10PlusProfiles.map(from, to) :
+                     mIsHdr ? sAv1HdrProfiles.map(from, to) :
+                              sAv1Profiles.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
+        return mIsHdr10Plus ? sAv1Hdr10PlusProfiles.map(from, to) :
+                     mIsHdr ? sAv1HdrProfiles.map(from, to) :
+                              sAv1Profiles.map(from, to);
+    }
+
+private:
+    bool mIsHdr;
+    bool mIsHdr10Plus;
+};
+
+} // namespace
+
+// static
+std::shared_ptr<C2Mapper::ProfileLevelMapper>
+C2Mapper::GetProfileLevelMapper(std::string mediaType) {
+    std::transform(mediaType.begin(), mediaType.begin(), mediaType.end(), ::tolower);
+    if (mediaType == MIMETYPE_AUDIO_AAC) {
+        return std::make_shared<AacProfileLevelMapper>();
+    } else if (mediaType == MIMETYPE_VIDEO_AVC) {
+        return std::make_shared<AvcProfileLevelMapper>();
+    } else if (mediaType == MIMETYPE_VIDEO_DOLBY_VISION) {
+        return std::make_shared<DolbyVisionProfileLevelMapper>();
+    } else if (mediaType == MIMETYPE_VIDEO_H263) {
+        return std::make_shared<H263ProfileLevelMapper>();
+    } else if (mediaType == MIMETYPE_VIDEO_HEVC) {
+        return std::make_shared<HevcProfileLevelMapper>();
+    } else if (mediaType == MIMETYPE_VIDEO_MPEG2) {
+        return std::make_shared<Mpeg2ProfileLevelMapper>();
+    } else if (mediaType == MIMETYPE_VIDEO_MPEG4) {
+        return std::make_shared<Mpeg4ProfileLevelMapper>();
+    } else if (mediaType == MIMETYPE_VIDEO_VP8) {
+        return std::make_shared<Vp8ProfileLevelMapper>();
+    } else if (mediaType == MIMETYPE_VIDEO_VP9) {
+        return std::make_shared<Vp9ProfileLevelMapper>();
+    } else if (mediaType == MIMETYPE_VIDEO_AV1) {
+        return std::make_shared<Av1ProfileLevelMapper>();
+    }
+    return nullptr;
+}
+
+// static
+std::shared_ptr<C2Mapper::ProfileLevelMapper>
+C2Mapper::GetHdrProfileLevelMapper(std::string mediaType, bool isHdr10Plus) {
+    std::transform(mediaType.begin(), mediaType.begin(), mediaType.end(), ::tolower);
+    if (mediaType == MIMETYPE_VIDEO_HEVC) {
+        return std::make_shared<HevcProfileLevelMapper>(true, isHdr10Plus);
+    } else if (mediaType == MIMETYPE_VIDEO_VP9) {
+        return std::make_shared<Vp9ProfileLevelMapper>(true, isHdr10Plus);
+    }
+    return nullptr;
+}
+
+// static
+bool C2Mapper::map(C2Config::bitrate_mode_t from, int32_t *to) {
+    return sBitrateModes.map(from, to);
+}
+
+// static
+bool C2Mapper::map(int32_t from, C2Config::bitrate_mode_t *to) {
+    return sBitrateModes.map(from, to);
+}
+
+// static
+bool C2Mapper::map(C2Config::pcm_encoding_t from, int32_t *to) {
+    return sPcmEncodings.map(from, to);
+}
+
+// static
+bool C2Mapper::map(int32_t from, C2Config::pcm_encoding_t *to) {
+    return sPcmEncodings.map(from, to);
+}
+
+// static
+bool C2Mapper::map(C2Color::range_t from, int32_t *to) {
+    bool res = true;
+    // map SDK defined values directly. For other values, use wrapping from ColorUtils.
+    if (!sColorRanges.map(from, to)) {
+        ColorAspects::Range sfRange;
+
+        // map known constants and keep vendor extensions. all other values are mapped to 'Other'
+        if (!sColorRangesSf.map(from, &sfRange)) {
+            // use static cast and ensure it is in the extension range
+            if (from < C2Color::RANGE_VENDOR_START || from > C2Color::RANGE_OTHER) {
+                sfRange = ColorAspects::RangeOther;
+                res = false;
+            }
+        }
+
+        *to = ColorUtils::wrapColorAspectsIntoColorRange(sfRange);
+    }
+    return res;
+}
+
+// static
+bool C2Mapper::map(int32_t from, C2Color::range_t *to) {
+    // map SDK defined values directly. For other values, use wrapping from ColorUtils.
+    if (!sColorRanges.map(from, to)) {
+        ColorAspects::Range sfRange;
+        (void)ColorUtils::unwrapColorAspectsFromColorRange(from, &sfRange);
+
+        // map known constants and keep vendor extensions. all other values are mapped to 'Other'
+        if (!sColorRangesSf.map(sfRange, to)) {
+            // use static cast and ensure it is in the extension range
+            *to = (C2Color::range_t)sfRange;
+            if (*to < C2Color::RANGE_VENDOR_START || *to > C2Color::RANGE_OTHER) {
+                *to = C2Color::RANGE_OTHER;
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+
+// static
+bool C2Mapper::map(C2Color::range_t from, ColorAspects::Range *to) {
+    return sColorRangesSf.map(from, to);
+}
+
+// static
+bool C2Mapper::map(ColorAspects::Range from, C2Color::range_t *to) {
+    return sColorRangesSf.map(from, to);
+}
+
+// static
+bool C2Mapper::map(C2Color::primaries_t primaries, C2Color::matrix_t matrix, int32_t *standard) {
+    ColorAspects::Primaries sfPrimaries;
+    ColorAspects::MatrixCoeffs sfMatrix;
+    bool res = true;
+
+    // map known constants and keep vendor extensions. all other values are mapped to 'Other'
+    if (!sColorPrimariesSf.map(primaries, &sfPrimaries)) {
+        // ensure it is in the extension range and use static cast
+        if (primaries < C2Color::PRIMARIES_VENDOR_START || primaries > C2Color::PRIMARIES_OTHER) {
+            // undefined non-extension values map to 'Other'
+            sfPrimaries = ColorAspects::PrimariesOther;
+            res = false;
+        } else {
+            sfPrimaries = (ColorAspects::Primaries)primaries;
+        }
+    }
+
+    if (!sColorMatricesSf.map(matrix, &sfMatrix)) {
+        // use static cast and ensure it is in the extension range
+        if (matrix < C2Color::MATRIX_VENDOR_START || matrix > C2Color::MATRIX_OTHER) {
+            // undefined non-extension values map to 'Other'
+            sfMatrix = ColorAspects::MatrixOther;
+            res = false;
+        } else {
+            sfMatrix = (ColorAspects::MatrixCoeffs)matrix;
+        }
+    }
+
+    *standard = ColorUtils::wrapColorAspectsIntoColorStandard(sfPrimaries, sfMatrix);
+
+    return res;
+}
+
+// static
+bool C2Mapper::map(int32_t standard, C2Color::primaries_t *primaries, C2Color::matrix_t *matrix) {
+    // first map to stagefright foundation aspects => these actually map nearly 1:1 to
+    // Codec 2.0 aspects
+    ColorAspects::Primaries sfPrimaries;
+    ColorAspects::MatrixCoeffs sfMatrix;
+    bool res = true;
+    (void)ColorUtils::unwrapColorAspectsFromColorStandard(standard, &sfPrimaries, &sfMatrix);
+
+    // map known constants and keep vendor extensions. all other values are mapped to 'Other'
+    if (!sColorPrimariesSf.map(sfPrimaries, primaries)) {
+        // use static cast and ensure it is in the extension range
+        *primaries = (C2Color::primaries_t)sfPrimaries;
+        if (*primaries < C2Color::PRIMARIES_VENDOR_START || *primaries > C2Color::PRIMARIES_OTHER) {
+            *primaries = C2Color::PRIMARIES_OTHER;
+            res = false;
+        }
+    }
+
+    if (!sColorMatricesSf.map(sfMatrix, matrix)) {
+        // use static cast and ensure it is in the extension range
+        *matrix = (C2Color::matrix_t)sfMatrix;
+        if (*matrix < C2Color::MATRIX_VENDOR_START || *matrix > C2Color::MATRIX_OTHER) {
+            *matrix = C2Color::MATRIX_OTHER;
+            res = false;
+        }
+    }
+
+    return res;
+}
+
+// static
+bool C2Mapper::map(C2Color::primaries_t from, ColorAspects::Primaries *to) {
+    return sColorPrimariesSf.map(from, to);
+}
+
+// static
+bool C2Mapper::map(ColorAspects::Primaries from, C2Color::primaries_t *to) {
+    return sColorPrimariesSf.map(from, to);
+}
+
+// static
+bool C2Mapper::map(C2Color::matrix_t from, ColorAspects::MatrixCoeffs *to) {
+    return sColorMatricesSf.map(from, to);
+}
+
+// static
+bool C2Mapper::map(ColorAspects::MatrixCoeffs from, C2Color::matrix_t *to) {
+    return sColorMatricesSf.map(from, to);
+}
+
+// static
+bool C2Mapper::map(C2Color::transfer_t from, int32_t *to) {
+    bool res = true;
+    // map SDK defined values directly. For other values, use wrapping from ColorUtils.
+    if (!sColorTransfers.map(from, to)) {
+        ColorAspects::Transfer sfTransfer;
+
+        // map known constants and keep vendor extensions. all other values are mapped to 'Other'
+        if (!sColorTransfersSf.map(from, &sfTransfer)) {
+            // use static cast and ensure it is in the extension range
+            if (from < C2Color::TRANSFER_VENDOR_START || from > C2Color::TRANSFER_OTHER) {
+                sfTransfer = ColorAspects::TransferOther;
+                res = false;
+            }
+        }
+
+        *to = ColorUtils::wrapColorAspectsIntoColorTransfer(sfTransfer);
+    }
+    return res;
+}
+
+// static
+bool C2Mapper::map(int32_t from, C2Color::transfer_t *to) {
+    // map SDK defined values directly. For other values, use wrapping from ColorUtils.
+    if (!sColorTransfers.map(from, to)) {
+        ColorAspects::Transfer sfTransfer;
+        (void)ColorUtils::unwrapColorAspectsFromColorTransfer(from, &sfTransfer);
+
+        // map known constants and keep vendor extensions. all other values are mapped to 'Other'
+        if (!sColorTransfersSf.map(sfTransfer, to)) {
+            // use static cast and ensure it is in the extension range
+            *to = (C2Color::transfer_t)sfTransfer;
+            if (*to < C2Color::TRANSFER_VENDOR_START || *to > C2Color::TRANSFER_OTHER) {
+                *to = C2Color::TRANSFER_OTHER;
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+
+// static
+bool C2Mapper::map(
+        C2Color::range_t range, C2Color::primaries_t primaries,
+        C2Color::matrix_t matrix, C2Color::transfer_t transfer, uint32_t *dataSpace) {
+#if 0
+    // pure reimplementation
+    *dataSpace = HAL_DATASPACE_UNKNOWN; // this is 0
+
+    switch (range) {
+        case C2Color::RANGE_FULL:    *dataSpace |= HAL_DATASPACE_RANGE_FULL;    break;
+        case C2Color::RANGE_LIMITED: *dataSpace |= HAL_DATASPACE_RANGE_LIMITED; break;
+        default: break;
+    }
+
+    switch (transfer) {
+        case C2Color::TRANSFER_LINEAR:  *dataSpace |= HAL_DATASPACE_TRANSFER_LINEAR;     break;
+        case C2Color::TRANSFER_SRGB:    *dataSpace |= HAL_DATASPACE_TRANSFER_SRGB;       break;
+        case C2Color::TRANSFER_170M:    *dataSpace |= HAL_DATASPACE_TRANSFER_SMPTE_170M; break;
+        case C2Color::TRANSFER_GAMMA22: *dataSpace |= HAL_DATASPACE_TRANSFER_GAMMA2_2;   break;
+        case C2Color::TRANSFER_GAMMA28: *dataSpace |= HAL_DATASPACE_TRANSFER_GAMMA2_8;   break;
+        case C2Color::TRANSFER_ST2084:  *dataSpace |= HAL_DATASPACE_TRANSFER_ST2084;     break;
+        case C2Color::TRANSFER_HLG:     *dataSpace |= HAL_DATASPACE_TRANSFER_HLG;        break;
+        default: break;
+    }
+
+    switch (primaries) {
+        case C2Color::PRIMARIES_BT601_525:
+            *dataSpace |= (matrix == C2Color::MATRIX_240M
+                            || matrix == C2Color::MATRIX_BT709)
+                    ? HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED
+                    : HAL_DATASPACE_STANDARD_BT601_525;
+            break;
+        case C2Color::PRIMARIES_BT601_625:
+            *dataSpace |= (matrix == C2Color::MATRIX_240M
+                            || matrix == C2Color::MATRIX_BT709)
+                    ? HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED
+                    : HAL_DATASPACE_STANDARD_BT601_625;
+            break;
+        case C2Color::PRIMARIES_BT2020:
+            *dataSpace |= (matrix == C2Color::MATRIX_BT2020_CONSTANT
+                    ? HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE
+                    : HAL_DATASPACE_STANDARD_BT2020);
+            break;
+        case C2Color::PRIMARIES_BT470_M:
+            *dataSpace |= HAL_DATASPACE_STANDARD_BT470M;
+            break;
+        case C2Color::PRIMARIES_BT709:
+            *dataSpace |= HAL_DATASPACE_STANDARD_BT709;
+            break;
+        default: break;
+    }
+#else
+    // for now use legacy implementation
+    ColorAspects aspects;
+    if (!sColorRangesSf.map(range, &aspects.mRange)) {
+        aspects.mRange = ColorAspects::RangeUnspecified;
+    }
+    if (!sColorPrimariesSf.map(primaries, &aspects.mPrimaries)) {
+        aspects.mPrimaries = ColorAspects::PrimariesUnspecified;
+    }
+    if (!sColorMatricesSf.map(matrix, &aspects.mMatrixCoeffs)) {
+        aspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
+    }
+    if (!sColorTransfersSf.map(transfer, &aspects.mTransfer)) {
+        aspects.mTransfer = ColorAspects::TransferUnspecified;
+    }
+    *dataSpace = ColorUtils::getDataSpaceForColorAspects(aspects, true /* mayExpand */);
+#endif
+    return true;
+}
+
+// static
+bool C2Mapper::map(C2Color::transfer_t from, ColorAspects::Transfer *to) {
+    return sColorTransfersSf.map(from, to);
+}
+
+// static
+bool C2Mapper::map(ColorAspects::Transfer from, C2Color::transfer_t *to) {
+    return sColorTransfersSf.map(from, to);
+}
diff --git a/media/codec2/sfplugin/utils/Codec2Mapper.h b/media/codec2/sfplugin/utils/Codec2Mapper.h
new file mode 100644
index 0000000..cec6f07
--- /dev/null
+++ b/media/codec2/sfplugin/utils/Codec2Mapper.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_CODEC2_MAPPER_H_
+#define ANDROID_CODEC2_MAPPER_H_
+
+#include <C2Config.h>
+
+#include <media/stagefright/foundation/ColorUtils.h>
+
+#include <memory>
+
+namespace android {
+
+    /**
+     * Utility class to map Codec 2.0 values to android values.
+     */
+    struct C2Mapper {
+        struct ProfileLevelMapper {
+            virtual bool mapProfile(C2Config::profile_t, int32_t*) = 0;
+            virtual bool mapProfile(int32_t, C2Config::profile_t*) = 0;
+            virtual bool mapLevel(C2Config::level_t, int32_t*) = 0;
+            virtual bool mapLevel(int32_t, C2Config::level_t*) = 0;
+            virtual ~ProfileLevelMapper() = default;
+        };
+
+        static std::shared_ptr<ProfileLevelMapper>
+        GetProfileLevelMapper(std::string mediaType);
+
+        static std::shared_ptr<ProfileLevelMapper>
+        GetHdrProfileLevelMapper(std::string mediaType, bool isHdr10Plus = false);
+
+        // convert between bitrates
+        static bool map(C2Config::bitrate_mode_t, int32_t*);
+        static bool map(int32_t, C2Config::bitrate_mode_t*);
+
+        // convert between pcm encodings
+        static bool map(C2Config::pcm_encoding_t, int32_t*);
+        static bool map(int32_t, C2Config::pcm_encoding_t*);
+
+        // convert between picture types
+        static bool map(C2Config::picture_type_t, int32_t*);
+        static bool map(int32_t, C2Config::picture_type_t*);
+
+        // convert between color aspects
+        static bool map(C2Color::range_t, int32_t*);
+        static bool map(int32_t, C2Color::range_t*);
+        static bool map(C2Color::primaries_t, C2Color::matrix_t, int32_t*);
+        static bool map(int32_t, C2Color::primaries_t*, C2Color::matrix_t*);
+        static bool map(C2Color::transfer_t, int32_t*);
+        static bool map(int32_t, C2Color::transfer_t*);
+
+        static bool map(
+                C2Color::range_t, C2Color::primaries_t, C2Color::matrix_t, C2Color::transfer_t,
+                uint32_t *dataSpace);
+
+        static bool map(C2Color::range_t, ColorAspects::Range*);
+        static bool map(ColorAspects::Range, C2Color::range_t*);
+        static bool map(C2Color::primaries_t, ColorAspects::Primaries*);
+        static bool map(ColorAspects::Primaries, C2Color::primaries_t*);
+        static bool map(C2Color::matrix_t, ColorAspects::MatrixCoeffs*);
+        static bool map(ColorAspects::MatrixCoeffs, C2Color::matrix_t*);
+        static bool map(C2Color::transfer_t, ColorAspects::Transfer*);
+        static bool map(ColorAspects::Transfer, C2Color::transfer_t*);
+    };
+}
+
+#endif  // ANDROID_CODEC2_MAPPER_H_
diff --git a/media/codec2/tests/Android.bp b/media/codec2/tests/Android.bp
new file mode 100644
index 0000000..fce6e21
--- /dev/null
+++ b/media/codec2/tests/Android.bp
@@ -0,0 +1,79 @@
+cc_test {
+    name: "codec2_core_param_test",
+
+    srcs: [
+        "C2Param_test.cpp",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/codec2/vndk/include",
+    ],
+
+    header_libs: [
+        "libcodec2_headers",
+    ],
+
+    // param tests must not depend on any codec2 libraries as all params should be templated
+    shared_libs: [
+    ],
+
+    static_libs: [
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+}
+
+cc_test {
+    name: "codec2_vndk_test",
+
+    srcs: [
+        "C2_test.cpp",
+        "C2SampleComponent_test.cpp",
+        "C2UtilTest.cpp",
+        "vndk/C2BufferTest.cpp",
+    ],
+
+    include_dirs: [
+    ],
+
+    shared_libs: [
+        "libcodec2",
+        "libcodec2_vndk",
+        "libcutils",
+        "liblog",
+        "libutils",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+}
+
+cc_test {
+    name: "codec2_vndk_interface_test",
+
+    srcs: [
+        "C2ComponentInterface_test.cpp",
+    ],
+
+    header_libs: [
+        "media_plugin_headers",
+    ],
+
+    shared_libs: [
+        "libcutils",
+        "liblog",
+        "libcodec2",
+        "libcodec2_vndk",
+        "libutils",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+}
diff --git a/media/codec2/tests/C2ComponentInterface_test.cpp b/media/codec2/tests/C2ComponentInterface_test.cpp
new file mode 100644
index 0000000..67f733d
--- /dev/null
+++ b/media/codec2/tests/C2ComponentInterface_test.cpp
@@ -0,0 +1,706 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "C2ComponentInterface_test"
+
+#include <dlfcn.h>
+#include <stdio.h>
+
+#include <gtest/gtest.h>
+#include <utils/Log.h>
+
+#include <C2Component.h>
+#include <C2Config.h>
+#include <util/C2InterfaceHelper.h>
+#include <C2Param.h>
+
+#if !defined(UNUSED)
+#define UNUSED(expr)                                                           \
+  do {                                                                         \
+      (void)(expr);                                                            \
+  } while (0)
+
+#endif //!defined(UNUSED)
+
+namespace android {
+
+template <class T> std::unique_ptr<T> alloc_unique_cstr(const char *cstr) {
+    size_t len = strlen(cstr);
+    std::unique_ptr<T> ptr = T::AllocUnique(len);
+    memcpy(ptr->m.value, cstr, len);
+    return ptr;
+}
+
+class C2CompIntfTest : public ::testing::Test {
+protected:
+    C2CompIntfTest() {}
+    ~C2CompIntfTest() override {}
+
+    void setComponent(std::shared_ptr<C2ComponentInterface> intf) {
+        mIntf = intf;
+    }
+
+    void resetResults() {
+        mIntf = nullptr;
+        mParamResults.clear();
+    }
+
+    template <typename T> void testUnsupportedParam();
+
+    template <typename T> void testSupportedParam();
+
+    // testReadOnlyParam() and testWritableParam() are the main functions for testing a parameter.
+    // A caller should find out if a tested parameter is read-only or writable before calling them
+    // and it must call one of the corresponded them.
+
+    // If a parameter is read-only this is called.
+    // Test read-only parameter |preParam|. The test expects failure while config() with |newParam|,
+    // and make sure |preParam| stay unchanged.
+    template <typename T>
+    void testReadOnlyParam(const T &preParam, const T &newParam);
+
+    // If a parameter is writable this is called.
+    // Test one filed |writableField| for given writable parameter |param|.
+    // |validValues| contains all values obtained from querySupportedValues() for |writableField|.
+    // The test checks validity for config() with each value, and make sure values are config-ed
+    // by query() them out. |invalidValues| contains some values which are not in |validValues|.
+    // The test expects C2_BAD_VALUE while config() with these values,
+    // and |param| should stay unchanged.
+    template <typename TParam, typename TRealField, typename TField>
+    void testWritableParam(TParam *const param, TRealField *const writableField,
+                           const std::vector<TField> &validValues,
+                           const std::vector<TField> &invalidValues);
+
+    // Test all the defined parameters in C2Param.h.
+    void testMain(std::shared_ptr<C2ComponentInterface> intf,
+                  const std::string &componentName);
+
+    // Check permission of parameter type |T| for testing interface.
+    // This should be called first of the testing per parameter type,
+    // therefore different testing process is applied according to the permission type.
+    template <typename T>
+    void checkParamPermission(
+            int *const writable,
+            const std::vector<std::shared_ptr<C2ParamDescriptor>> &supportedParams);
+
+private:
+    enum ParamPermission : int {
+        WRITABLE,
+        READONLY,
+        UNSUPPORTED,
+    };
+
+    struct paramTestInfo {
+        std::string name;
+        int result;
+        paramTestInfo(const char *name_, int result_)
+            : name(name_), result(result_) {}
+    };
+
+    // queryOnStack() and queryonHeap() both call an interface's query_vb() and
+    // check if a component has a parameter whose type is |T|.
+    // If a component has, the value should be copied into an argument, that is
+    // |p| in queryOnStack() and |heapParams| in queryOnHeap().
+    // The return value is c2_status_t (e.g. C2_OK).
+    template <typename T> c2_status_t queryOnStack(T *const p);
+
+    template <typename T>
+    c2_status_t queryOnHeap(const T &p,
+                         std::vector<std::unique_ptr<C2Param>> *const heapParams);
+
+    // Get a value whose type is |T| in a component. The value is copied to |param|.
+    // This should be called only if a component has the parameter.
+    template <typename T> void getValue(T *const param);
+
+    // Check if the parameter's value in component is equal to |expected| and
+    // queryOnStack() and queryOnHeap() are succeeded. When this function called,
+    // it should be guaranteed a component has the parameter.
+    template <typename T> void queryParamAsExpected(const T &expected);
+
+    // Test if query functions works correctly for supported parameters.
+    // "Support" means here a component has the parameter.
+    template <typename T> void querySupportedParam();
+
+    // Test query functions works correctly for unsupported parameters.
+    // "Unsupport" means here a component doesn't have the parameter.
+    template <typename T> void queryUnsupportedParam();
+
+    // Execute an interface's config_vb(). |T| is a single parameter type, not std::vector.
+    // config() creates std::vector<C2Param *> {p} and passes it to config_vb().
+    template <typename T>
+    c2_status_t
+    config(T *const p,
+           std::vector<std::unique_ptr<C2SettingResult>> *const failures);
+
+    // Test if config works correctly for read-only parameters.
+    // Because the failure of config() is assumed, |newParam| doesn't matter.
+    template <typename T> void configReadOnlyParam(const T &newParam);
+
+    // Test if config works correctly for writable parameters.
+    // This changes the parameter's value to |newParam|.
+    // |stConfig| is a return value of config().
+    template <typename T> void configWritableParamValidValue(const T &newParam, c2_status_t *stConfig);
+
+    // Test if config works correctly in the case an invalid value |newParam| is tried to write
+    // to an writable parameter.
+    template <typename T> void configWritableParamInvalidValue(const T &newParam);
+
+    // Create values for testing from |validValueInfos|. The values are returned as arguments.
+    // |validValues| : valid values, which can be written for the parameter.
+    // |InvalidValues| : invalid values, which cannot be written for the parameter.
+    //                   config() should be failed if these values are used as new values.
+    // This function should be called only for writable and supported parameters.
+    template <typename TField>
+    void getTestValues(const C2FieldSupportedValues &validValueInfos,
+                       std::vector<TField> *const validValues,
+                       std::vector<TField> *const invalidValues);
+
+    // Output the summary of test results. Categorizes parameters with their configuration.
+    void outputResults(const std::string &name);
+
+    std::shared_ptr<C2ComponentInterface> mIntf;
+    std::vector<paramTestInfo> mParamResults;
+    std::string mCurrentParamName;
+};
+
+// factory function
+// TODO(hiroh): Add factory functions for other types.
+template <typename T> std::unique_ptr<T> makeParam() {
+    return std::make_unique<T>();
+}
+
+template <> std::unique_ptr<C2PortMediaTypeSetting::input> makeParam() {
+    // TODO(hiroh): Set more precise length.
+    return C2PortMediaTypeSetting::input::AllocUnique(100);
+}
+
+#define TRACED_FAILURE(func)                            \
+    do {                                                \
+        SCOPED_TRACE(mCurrentParamName);             \
+        func;                                           \
+        if (::testing::Test::HasFatalFailure()) {       \
+            return;                                     \
+        }                                               \
+    } while (false)
+
+template <typename T> c2_status_t C2CompIntfTest::queryOnStack(T *const p) {
+    std::vector<C2Param*> stackParams{p};
+    return mIntf->query_vb(stackParams, {}, C2_DONT_BLOCK, nullptr);
+}
+
+template <typename T>
+c2_status_t C2CompIntfTest::queryOnHeap(
+        const T &p, std::vector<std::unique_ptr<C2Param>> *const heapParams) {
+    uint32_t index = p.index() & ~0x03FE0000;
+    if (p.forStream()) {
+        index |= ((p.stream() << 17) & 0x01FE0000) | 0x02000000;
+    }
+    return mIntf->query_vb({}, {index}, C2_DONT_BLOCK, heapParams);
+}
+
+template <typename T> void C2CompIntfTest::getValue(T *const param) {
+    // When getValue() is called, a component has to have the parameter.
+    ASSERT_EQ(C2_OK, queryOnStack(param));
+}
+
+template <typename T>
+void C2CompIntfTest::queryParamAsExpected(const T &expected) {
+    // TODO(hiroh): Don't create param on stack and call queryOnStack for flex params.
+    // Note that all the current supported parameters are non-flex params.
+    T stack;
+    std::unique_ptr<T> pHeap = makeParam<T>();
+    std::vector<std::unique_ptr<C2Param>> heapParams;
+
+    ASSERT_EQ(C2_OK, queryOnStack(&stack));
+
+    // |stack| is a parameter value. The parameter size shouldn't be 0.
+    EXPECT_NE(0u, stack.size());
+    EXPECT_EQ(stack, expected);
+
+    ASSERT_EQ(C2_OK, queryOnHeap(*pHeap, &heapParams));
+
+    // |*heapParams[0]| is a parameter value. The size of |heapParams| has to be one.
+    ASSERT_EQ(1u, heapParams.size());
+    EXPECT_TRUE(heapParams[0]);
+    EXPECT_EQ(*heapParams[0], expected);
+}
+
+template <typename T> void C2CompIntfTest::querySupportedParam() {
+    std::unique_ptr<T> param = makeParam<T>();
+    // The current parameter's value is acquired by getValue(), which should be succeeded.
+    getValue(param.get());
+    queryParamAsExpected(*param);
+}
+
+template <typename T> void C2CompIntfTest::queryUnsupportedParam() {
+    // TODO(hiroh): Don't create param on stack and call queryOnStack for flex params.
+    // Note that all the current supported parameters are non-flex params.
+    T stack;
+    std::unique_ptr<T> pHeap = makeParam<T>();
+    std::vector<std::unique_ptr<C2Param>> heapParams;
+    // If a component doesn't have the parameter, queryOnStack() and queryOnHeap()
+    // should return C2_BAD_INDEX.
+    ASSERT_EQ(C2_BAD_INDEX, queryOnStack(&stack));
+    EXPECT_FALSE(stack);
+    ASSERT_EQ(C2_BAD_INDEX, queryOnHeap(*pHeap, &heapParams));
+    EXPECT_EQ(0u, heapParams.size());
+}
+
+template <typename T>
+c2_status_t C2CompIntfTest::config(
+        T *const p, std::vector<std::unique_ptr<C2SettingResult>> *const failures) {
+    std::vector<C2Param*> params{p};
+    return mIntf->config_vb(params, C2_DONT_BLOCK, failures);
+}
+
+// Create a new parameter copied from |p|.
+template <typename T> std::unique_ptr<T> makeParamFrom(const T &p) {
+    std::unique_ptr<T> retP = makeParam<T>();
+    EXPECT_TRUE(retP->updateFrom(p));
+    EXPECT_TRUE(memcmp(retP.get(), &p, sizeof(T)) == 0);
+    return retP;
+}
+
+template <typename T>
+void C2CompIntfTest::configReadOnlyParam(const T &newParam) {
+    std::unique_ptr<T> p = makeParamFrom(newParam);
+
+    std::vector<C2Param*> params{p.get()};
+    std::vector<std::unique_ptr<C2SettingResult>> failures;
+
+    // config_vb should be failed because a parameter is read-only.
+    ASSERT_EQ(C2_BAD_VALUE, mIntf->config_vb(params, C2_DONT_BLOCK, &failures));
+    ASSERT_EQ(1u, failures.size());
+    EXPECT_EQ(C2SettingResult::READ_ONLY, failures[0]->failure);
+}
+
+template <typename T>
+void C2CompIntfTest::configWritableParamValidValue(const T &newParam, c2_status_t *configResult) {
+    std::unique_ptr<T> p = makeParamFrom(newParam);
+
+    std::vector<C2Param*> params{p.get()};
+    std::vector<std::unique_ptr<C2SettingResult>> failures;
+    // In most cases, config_vb return C2_OK and the parameter's value should be changed
+    // to |newParam|, which is confirmed in a caller of configWritableParamValueValue().
+    // However, this can return ~~~~ and the parameter's values is not changed,
+    // because there may be dependent limitations between fields or between parameters.
+    // TODO(hiroh): I have to fill the return value. Comments in C2Component.h doesn't mention
+    // about the return value when conflict happens. I set C2_BAD_VALUE to it temporarily now.
+    c2_status_t stConfig = mIntf->config_vb(params, C2_DONT_BLOCK, &failures);
+    if (stConfig == C2_OK) {
+        EXPECT_EQ(0u, failures.size());
+    } else {
+        ASSERT_EQ(C2_BAD_VALUE, stConfig);
+        EXPECT_EQ(1u, failures.size());
+        EXPECT_EQ(C2SettingResult::CONFLICT, failures[0]->failure);
+    }
+    *configResult = stConfig;
+}
+
+template <typename T>
+void C2CompIntfTest::configWritableParamInvalidValue(const T &newParam) {
+    std::unique_ptr<T> p = makeParamFrom(newParam);
+
+    std::vector<C2Param*> params{p.get()};
+    std::vector<std::unique_ptr<C2SettingResult>> failures;
+    // Although a parameter is writable, config_vb should be failed,
+    // because a new value is invalid.
+    ASSERT_EQ(C2_BAD_VALUE, mIntf->config_vb(params, C2_DONT_BLOCK, &failures));
+    ASSERT_EQ(1u, failures.size());
+    EXPECT_EQ(C2SettingResult::BAD_VALUE, failures[0]->failure);
+}
+
+// There is only used enum type for the field type, that is C2Component::domain_t.
+// If another field type is added, it is necessary to add function for that.
+template <>
+void C2CompIntfTest::getTestValues(
+        const C2FieldSupportedValues &validValueInfos,
+        std::vector<C2Component::domain_t> *const validValues,
+        std::vector<C2Component::domain_t> *const invalidValues) {
+    UNUSED(validValueInfos);
+    validValues->emplace_back(C2Component::DOMAIN_VIDEO);
+    validValues->emplace_back(C2Component::DOMAIN_AUDIO);
+    validValues->emplace_back(C2Component::DOMAIN_OTHER);
+
+    // There is no invalid value.
+    UNUSED(invalidValues);
+}
+
+template <typename TField>
+void C2CompIntfTest::getTestValues(
+        const C2FieldSupportedValues &validValueInfos,
+        std::vector<TField> *const validValues,
+        std::vector<TField> *const invalidValues) {
+    using TStorage = typename _c2_reduce_enum_to_underlying_type<TField>::type;
+
+    // The supported values are represented by C2Values. C2Value::Primitive needs to
+    // be transformed to a primitive value. This function is one to do that.
+    auto prim2Value = [](const C2Value::Primitive &prim) -> TField {
+        return (TField)prim.ref<TStorage>();
+        static_assert(std::is_same<TStorage, int32_t>::value ||
+                      std::is_same<TStorage, uint32_t>::value ||
+                      std::is_same<TStorage, int64_t>::value ||
+                      std::is_same<TStorage, uint64_t>::value ||
+                      std::is_same<TStorage, float>::value, "Invalid TField type.");
+    };
+
+    // The size of validValueInfos is one.
+    const auto &c2FSV = validValueInfos;
+
+    switch (c2FSV.type) {
+    case C2FieldSupportedValues::type_t::EMPTY: {
+        invalidValues->emplace_back(TField(0));
+        // TODO(hiroh) : Should other invalid values be tested?
+        break;
+    }
+    case C2FieldSupportedValues::type_t::RANGE: {
+        const auto &range = c2FSV.range;
+        auto rmin = prim2Value(range.min);
+        auto rmax = prim2Value(range.max);
+        auto rstep = prim2Value(range.step);
+
+        ASSERT_LE(rmin, rmax);
+
+        if (rstep != 0) {
+            // Increase linear
+            for (auto v = rmin; v <= rmax; v = TField(v + rstep)) {
+                validValues->emplace_back(v);
+            }
+            if (rmin > std::numeric_limits<TField>::min()) {
+                invalidValues->emplace_back(TField(rmin - 1));
+            }
+            if (rmax < std::numeric_limits<TField>::max()) {
+                invalidValues->emplace_back(TField(rmax + 1));
+            }
+            const unsigned int N = validValues->size();
+            if (N >= 2) {
+                if (std::is_same<TField, float>::value) {
+                    invalidValues->emplace_back(TField((validValues->at(0) + validValues->at(1)) / 2));
+                    invalidValues->emplace_back(TField((validValues->at(N - 2) + validValues->at(N - 1)) / 2));
+                } else {
+                    if (rstep > 1) {
+                        invalidValues->emplace_back(TField(validValues->at(0) + 1));
+                        invalidValues->emplace_back(TField(validValues->at(N - 1) - 1));
+                    }
+                }
+            }
+        } else {
+            // There should be two cases, except linear case.
+            // 1. integer geometric case
+            // 2. float geometric case
+
+            auto num = prim2Value(range.num);
+            auto denom = prim2Value(range.denom);
+
+            // If both range.num and range.denom are 1 and step is 0, we should use
+            // VALUES, shouldn't we?
+            ASSERT_FALSE(num == 1 && denom == 1);
+
+            // (num / denom) is not less than 1.
+            ASSERT_FALSE(denom == 0);
+            ASSERT_LE(denom, num);
+            for (auto v = rmin; v <= rmax; v = TField(v * num / denom)) {
+                validValues->emplace_back(v);
+            }
+
+            if (rmin > std::numeric_limits<TField>::min()) {
+                invalidValues->emplace_back(TField(rmin - 1));
+            }
+            if (rmax < std::numeric_limits<TField>::max()) {
+                invalidValues->emplace_back(TField(rmax + 1));
+            }
+
+            const unsigned int N = validValues->size();
+            if (N >= 2) {
+                if (std::is_same<TField, float>::value) {
+                    invalidValues->emplace_back(TField((validValues->at(0) + validValues->at(1)) / 2));
+                    invalidValues->emplace_back(TField((validValues->at(N - 2) + validValues->at(N - 1)) / 2));
+                } else {
+                    if (validValues->at(1) - validValues->at(0) > 1) {
+                        invalidValues->emplace_back(TField(validValues->at(0) + 1));
+                    }
+                    if (validValues->at(N - 1) - validValues->at(N - 2) > 1) {
+                        invalidValues->emplace_back(TField(validValues->at(N - 1) - 1));
+                    }
+                }
+            }
+        }
+        break;
+    }
+    case C2FieldSupportedValues::type_t::VALUES: {
+        for (const C2Value::Primitive &prim : c2FSV.values) {
+            validValues->emplace_back(prim2Value(prim));
+        }
+        auto minv = *std::min_element(validValues->begin(), validValues->end());
+        auto maxv = *std::max_element(validValues->begin(), validValues->end());
+        if (minv - 1 > std::numeric_limits<TField>::min()) {
+            invalidValues->emplace_back(TField(minv - 1));
+        }
+        if (maxv + 1 < std::numeric_limits<TField>::max()) {
+            invalidValues->emplace_back(TField(maxv + 1));
+        }
+        break;
+    }
+    case C2FieldSupportedValues::type_t::FLAGS: {
+        // TODO(hiroh) : Implement the case that param.type is FLAGS.
+        break;
+    }
+    }
+}
+
+template <typename T>
+void C2CompIntfTest::testReadOnlyParam(const T &preParam, const T &newParam) {
+    TRACED_FAILURE(configReadOnlyParam(newParam));
+    // Parameter value must not be changed
+    TRACED_FAILURE(queryParamAsExpected(preParam));
+}
+
+template <typename TParam, typename TRealField, typename TField>
+void C2CompIntfTest::testWritableParam(
+        TParam *const param, TRealField *const writableField,
+        const std::vector<TField> &validValues,
+        const std::vector<TField> &invalidValues) {
+    c2_status_t stConfig;
+
+    // Get the parameter's value in the beginning in order to reset the value at the end.
+    TRACED_FAILURE(getValue(param));
+    std::unique_ptr<TParam> defaultParam = makeParamFrom(*param);
+
+    // Test valid values
+    for (const auto &val : validValues) {
+        std::unique_ptr<TParam> preParam = makeParamFrom(*param);
+
+        // Param is try to be changed
+        *writableField = val;
+        TRACED_FAILURE(configWritableParamValidValue(*param, &stConfig));
+        if (stConfig == C2_OK) {
+            TRACED_FAILURE(queryParamAsExpected(*param));
+        } else {
+            // Param is unchanged because a field value conflicts with other field or parameter.
+            TRACED_FAILURE(queryParamAsExpected(*preParam));
+        }
+    }
+
+    // Store the current parameter in order to test |param| is unchanged
+    // after trying to write an invalid value.
+    std::unique_ptr<TParam> lastValidParam = makeParamFrom(*param);
+
+    // Test invalid values
+    for (const auto &val : invalidValues) {
+        // Param is changed
+        *writableField = val;
+        TRACED_FAILURE(configWritableParamInvalidValue(*param));
+        TRACED_FAILURE(queryParamAsExpected(*lastValidParam));
+    }
+    // Reset the parameter by config().
+    TRACED_FAILURE(configWritableParamValidValue(*defaultParam, &stConfig));
+}
+
+template <typename T> void C2CompIntfTest::testUnsupportedParam() {
+    TRACED_FAILURE(queryUnsupportedParam<T>());
+}
+
+template <typename T> void C2CompIntfTest::testSupportedParam() {
+    TRACED_FAILURE(querySupportedParam<T>());
+}
+
+bool isSupportedParam(
+        const C2Param &param,
+        const std::vector<std::shared_ptr<C2ParamDescriptor>> &sParams) {
+    for (const auto &pd : sParams) {
+        if (param.type() == pd->index().type()) {
+            return true;
+        }
+    }
+    return false;
+}
+
+template <typename T>
+void C2CompIntfTest::checkParamPermission(
+    int *const result,
+    const std::vector<std::shared_ptr<C2ParamDescriptor>> &supportedParams) {
+    std::unique_ptr<T> param = makeParam<T>();
+
+    if (!isSupportedParam(*param, supportedParams)) {
+        // If a parameter isn't supported, it just finish after calling testUnsupportedParam().
+        testUnsupportedParam<T>();
+        *result = ParamPermission::UNSUPPORTED;
+        return;
+    }
+
+    testSupportedParam<T>();
+
+    TRACED_FAILURE(getValue(param.get()));
+    std::vector<std::unique_ptr<C2SettingResult>> failures;
+    // Config does not change the parameter, because param is the present param.
+    // This config is executed to find out if a parameter is read-only or writable.
+    c2_status_t stStack = config(param.get(), &failures);
+    if (stStack == C2_BAD_VALUE) {
+        // Read-only
+        std::unique_ptr<T> newParam = makeParam<T>();
+        testReadOnlyParam(*param, *newParam);
+        *result = ParamPermission::READONLY;
+    } else {
+        // Writable
+        EXPECT_EQ(stStack, C2_OK);
+        *result = ParamPermission::WRITABLE;
+    }
+}
+
+void C2CompIntfTest::outputResults(const std::string &name) {
+    std::vector<std::string> params[3];
+    for (const auto &testInfo : mParamResults) {
+        int result = testInfo.result;
+        ASSERT_TRUE(0 <= result && result <= 2);
+        params[result].emplace_back(testInfo.name);
+    }
+    const char *resultString[] = {"Writable", "Read-Only", "Unsupported"};
+    printf("\n----TEST RESULTS (%s)----\n\n", name.c_str());
+    for (int i = 0; i < 3; i++) {
+        printf("[ %s ]\n", resultString[i]);
+        for (const auto &t : params[i]) {
+            printf("%s\n", t.c_str());
+        }
+        printf("\n");
+    }
+}
+
+#define TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, field_name_) \
+    do {                                                                \
+        std::unique_ptr<TParam_> param = makeParam<TParam_>();          \
+        std::vector<C2FieldSupportedValuesQuery> validValueInfos = {    \
+            C2FieldSupportedValuesQuery::Current(                       \
+                    C2ParamField(param.get(), &field_type_name_::field_name_)) \
+        };                                                              \
+        ASSERT_EQ(C2_OK,                                                \
+                  mIntf->querySupportedValues_vb(validValueInfos, C2_DONT_BLOCK));     \
+        ASSERT_EQ(1u, validValueInfos.size());                          \
+        std::vector<decltype(param->field_name_)> validValues;          \
+        std::vector<decltype(param->field_name_)> invalidValues;        \
+        getTestValues(validValueInfos[0].values, &validValues, &invalidValues);   \
+        testWritableParam(param.get(), &param->field_name_, validValues,\
+                          invalidValues);                               \
+    } while (0)
+
+#define TEST_VSSTRUCT_WRITABLE_FIELD(TParam_, field_type_name_)         \
+    do {                                                                \
+        TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, width);  \
+        TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, height); \
+    } while (0)
+
+#define TEST_U32_WRITABLE_FIELD(TParam_, field_type_name_)              \
+  TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, value)
+
+#define TEST_ENUM_WRITABLE_FIELD(TParam_, field_type_name_)             \
+  TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, value)
+
+// TODO(hiroh): Support parameters based on char[] and uint32_t[].
+//#define TEST_STRING_WRITABLE_FIELD(TParam_, field_type_name_)
+// TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, m.value)
+//#define TEST_U32ARRAY_WRITABLE_FIELD(Tparam_, field_type_name_)
+// TEST_GENERAL_WRITABLE_FIELD(Tparam_, uint32_t[], field_type_name_, values)
+
+#define EACH_TEST(TParam_, field_type_name_, test_name)                 \
+    do {                                                                \
+      int result = 0;                                                   \
+      this->mCurrentParamName = #TParam_;                            \
+      checkParamPermission<TParam_>(&result, supportedParams);          \
+      if (result == ParamPermission::WRITABLE) {                        \
+          test_name(TParam_, field_type_name_);                         \
+      }                                                                 \
+      mParamResults.emplace_back(#TParam_, result);                      \
+  } while (0)
+
+#define EACH_TEST_SELF(type_, test_name) EACH_TEST(type_, type_, test_name)
+#define EACH_TEST_INPUT(type_, test_name) EACH_TEST(type_::input, type_, test_name)
+#define EACH_TEST_OUTPUT(type_, test_name) EACH_TEST(type_::output, type_, test_name)
+void C2CompIntfTest::testMain(std::shared_ptr<C2ComponentInterface> intf,
+                              const std::string &componentName) {
+    setComponent(intf);
+
+    std::vector<std::shared_ptr<C2ParamDescriptor>> supportedParams;
+    ASSERT_EQ(C2_OK, mIntf->querySupportedParams_nb(&supportedParams));
+
+    EACH_TEST_SELF(C2ActualPipelineDelayTuning, TEST_U32_WRITABLE_FIELD);
+    EACH_TEST_SELF(C2ComponentAttributesSetting, TEST_U32_WRITABLE_FIELD);
+    EACH_TEST_INPUT(C2PortActualDelayTuning, TEST_U32_WRITABLE_FIELD);
+    EACH_TEST_OUTPUT(C2PortActualDelayTuning, TEST_U32_WRITABLE_FIELD);
+    EACH_TEST_INPUT(C2StreamBufferTypeSetting, TEST_U32_WRITABLE_FIELD);
+    EACH_TEST_OUTPUT(C2StreamBufferTypeSetting, TEST_U32_WRITABLE_FIELD);
+    EACH_TEST_INPUT(C2PortStreamCountTuning, TEST_U32_WRITABLE_FIELD);
+    EACH_TEST_OUTPUT(C2PortStreamCountTuning, TEST_U32_WRITABLE_FIELD);
+
+    EACH_TEST_SELF(C2ComponentDomainSetting, TEST_ENUM_WRITABLE_FIELD);
+
+    // TODO(hiroh): Support parameters based on uint32_t[] and char[].
+    // EACH_TEST_INPUT(C2PortMediaTypeSetting, TEST_STRING_WRITABLE_FIELD);
+    // EACH_TEST_OUTPUT(C2PortMediaTypeSetting, TEST_STRING_WRITABLE_FIELD);
+    // EACH_TEST_INPUT(C2StreamMimeConfig, TEST_STRING_WRITABLE_FIELD);
+    // EACH_TEST_OUTPUT(C2StreamMimeConfig, TEST_STRING_WRITABLE_FIELD);
+
+    // EACH_TEST_SELF(C2SupportedParamsInfo, TEST_U32ARRAY_WRITABLE_FIELD);
+    // EACH_TEST_SELF(C2RequiredParamsInfo, TEST_U32ARRAY_WRITABLE_FIELD);
+    // EACH_TEST_SELF(C2ReadOnlyParamsInfo, TEST_U32ARRAY_WRITABLE_FIELD);
+    // EACH_TEST_SELF(C2RequestedInfosInfo, TEST_U32ARRAY_WRITABLE_FIELD);
+
+    EACH_TEST_INPUT(C2StreamPictureSizeInfo, TEST_VSSTRUCT_WRITABLE_FIELD);
+    EACH_TEST_OUTPUT(C2StreamPictureSizeInfo, TEST_VSSTRUCT_WRITABLE_FIELD);
+    EACH_TEST_INPUT(C2StreamPictureSizeInfo, TEST_VSSTRUCT_WRITABLE_FIELD);
+    EACH_TEST_OUTPUT(C2StreamPictureSizeInfo, TEST_VSSTRUCT_WRITABLE_FIELD);
+    EACH_TEST_INPUT(C2MaxVideoSizeHintPortSetting, TEST_VSSTRUCT_WRITABLE_FIELD);
+    EACH_TEST_OUTPUT(C2MaxVideoSizeHintPortSetting, TEST_VSSTRUCT_WRITABLE_FIELD);
+
+    outputResults(componentName);
+    resetResults();
+}
+
+TEST_F(C2CompIntfTest, C2V4L2CodecIntf) {
+
+    // Read a shared object library.
+    void* compLib = dlopen("system/lib/libv4l2_codec2.so", RTLD_NOW);
+
+    if (!compLib) {
+        printf("Cannot open library: %s.\n", dlerror());
+        FAIL();
+        return;
+    }
+
+    typedef C2ComponentStore* create_t();
+    create_t* create_store= (create_t*) dlsym(compLib, "create_store");
+    const char* dlsym_error = dlerror();
+    if (dlsym_error) {
+        printf("Cannot load symbol create: %s.\n", dlsym_error);
+        FAIL();
+        return;
+    }
+
+    typedef void destroy_t(C2ComponentStore*);
+    destroy_t* destroy_store = (destroy_t*) dlsym(compLib, "destroy_store");
+    dlsym_error = dlerror();
+    if (dlsym_error) {
+        printf("Cannot load symbol destroy: %s.\n", dlsym_error);
+        FAIL();
+        return;
+    }
+
+    std::shared_ptr<C2ComponentStore> componentStore(create_store(), destroy_store);
+    std::shared_ptr<C2ComponentInterface> componentIntf;
+    componentStore->createInterface("v4l2.decoder", &componentIntf);
+    auto componentName = "C2V4L2Codec";
+    testMain(componentIntf, componentName);
+}
+
+} // namespace android
diff --git a/media/codec2/tests/C2Param_test.cpp b/media/codec2/tests/C2Param_test.cpp
new file mode 100644
index 0000000..564d4d2
--- /dev/null
+++ b/media/codec2/tests/C2Param_test.cpp
@@ -0,0 +1,2515 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2Param_test"
+
+#include <gtest/gtest.h>
+
+#define __C2_GENERATE_GLOBAL_VARS__
+#include <C2ParamDef.h>
+
+#include <list>
+
+void PrintTo(const _C2FieldId &id, ::std::ostream* os) {
+    *os << "@" << id._mOffset << "+" << id._mSize;
+}
+
+void PrintTo(const C2FieldDescriptor &fd, ::std::ostream *os) {
+    using FD=C2FieldDescriptor;
+    switch (fd.type()) {
+    case FD::INT32: *os << "i32"; break;
+    case FD::INT64: *os << "i64"; break;
+    case FD::UINT32: *os << "u32"; break;
+    case FD::UINT64: *os << "u64"; break;
+    case FD::FLOAT: *os << "float"; break;
+    case FD::STRING: *os << "char"; break;
+    case FD::BLOB: *os << "u8"; break;
+    default:
+        if (fd.type() & FD::STRUCT_FLAG) {
+            *os << "struct-" << (fd.type() & ~FD::STRUCT_FLAG);
+        } else {
+            *os << "type-" << fd.type();
+        }
+    }
+    *os << " " << fd.name();
+    if (fd.extent() > 1) {
+        *os << "[" << fd.extent() << "]";
+    } else if (fd.extent() == 0) {
+        *os << "[]";
+    }
+    *os << " (";
+    PrintTo(fd._mFieldId, os);
+    *os << "*" << fd.extent() << ")";
+}
+
+enum C2ParamIndexType : C2Param::type_index_t {
+    kParamIndexNumber,
+    kParamIndexNumbers,
+    kParamIndexNumber2,
+    kParamIndexVendorStart = C2Param::TYPE_INDEX_VENDOR_START,
+    kParamIndexVendorNumbers,
+};
+
+void ffff(int(*)(int)) {}
+
+/* ============================= STRUCT DECLARATION AND DESCRIPTION ============================= */
+
+typedef C2FieldDescriptor FD;
+
+class C2ParamTest : public ::testing::Test {
+};
+
+class C2ParamTest_ParamFieldList
+        : public ::testing::TestWithParam<std::vector<C2FieldDescriptor>> {
+};
+
+enum {
+    kParamIndexSize,
+    kParamIndexTestA,
+    kParamIndexTestB,
+    kParamIndexTestFlexS32,
+    kParamIndexTestFlexEndS32,
+    kParamIndexTestFlexS64,
+    kParamIndexTestFlexEndS64,
+    kParamIndexTestFlexSize,
+    kParamIndexTestFlexEndSize,
+};
+
+struct C2SizeStruct {
+    int32_t width;
+    int32_t height;
+    enum : uint32_t { CORE_INDEX = kParamIndexSize };                        // <= needed for C2FieldDescriptor
+    const static std::vector<C2FieldDescriptor> _FIELD_LIST;
+    static const std::vector<C2FieldDescriptor> FieldList();  // <= needed for C2FieldDescriptor
+    const static FD::type_t TYPE = (FD::type_t)(CORE_INDEX | FD::STRUCT_FLAG);
+};
+
+DEFINE_NO_NAMED_VALUES_FOR(C2SizeStruct)
+
+// Test 1. define a structure without any helper methods
+
+bool operator==(const C2FieldDescriptor &a, const C2FieldDescriptor &b) {
+    return a.type() == b.type()
+            && a.extent() == b.extent()
+            && a.name() == b.name()
+            && a._mFieldId == b._mFieldId;
+}
+
+struct C2TestStruct_A {
+    int32_t signed32;
+    int64_t signed64[2];
+    uint32_t unsigned32[1];
+    uint64_t unsigned64;
+    float fp32;
+    C2SizeStruct sz[3];
+    uint8_t blob[100];
+    char string[100];
+    bool yesNo[100];
+
+    const static std::vector<C2FieldDescriptor> _FIELD_LIST;
+    static const std::vector<C2FieldDescriptor> FieldList();
+    // enum : uint32_t { CORE_INDEX = kParamIndexTest };
+    // typedef C2TestStruct_A _type;
+} __attribute__((packed));
+
+const std::vector<C2FieldDescriptor> C2TestStruct_A::FieldList() {
+    return _FIELD_LIST;
+}
+const std::vector<C2FieldDescriptor> C2TestStruct_A::_FIELD_LIST =
+    { { FD::INT32,    1, "s32",   0, 4 },
+      { FD::INT64,    2, "s64",   4, 8 },
+      { FD::UINT32,   1, "u32",  20, 4 },
+      { FD::UINT64,   1, "u64",  24, 8 },
+      { FD::FLOAT,    1, "fp",   32, 4 },
+      { C2SizeStruct::TYPE, 3, "size", 36, 8 },
+      { FD::BLOB,   100, "blob", 60, 1 },
+      { FD::STRING, 100, "str", 160, 1 },
+      { FD::BLOB,   100, "y-n", 260, 1 } };
+
+TEST_P(C2ParamTest_ParamFieldList, VerifyStruct) {
+    std::vector<C2FieldDescriptor> fields = GetParam(), expected = C2TestStruct_A::_FIELD_LIST;
+
+    // verify first field descriptor
+    EXPECT_EQ(FD::INT32, fields[0].type());
+    EXPECT_STREQ("s32", fields[0].name().c_str());
+    EXPECT_EQ(1u, fields[0].extent());
+    EXPECT_EQ(_C2FieldId(0, 4), fields[0]._mFieldId);
+
+    EXPECT_EQ(expected[0], fields[0]);
+    EXPECT_EQ(expected[1], fields[1]);
+    EXPECT_EQ(expected[2], fields[2]);
+    EXPECT_EQ(expected[3], fields[3]);
+    EXPECT_EQ(expected[4], fields[4]);
+    EXPECT_EQ(expected[5], fields[5]);
+    EXPECT_EQ(expected[6], fields[6]);
+    EXPECT_EQ(expected[7], fields[7]);
+    for (size_t i = 8; i < fields.size() && i < expected.size(); ++i) {
+        EXPECT_EQ(expected[i], fields[i]);
+    }
+}
+
+INSTANTIATE_TEST_CASE_P(InitializerList, C2ParamTest_ParamFieldList, ::testing::Values(C2TestStruct_A::_FIELD_LIST));
+
+// define fields using C2FieldDescriptor pointer constructor
+const std::vector<C2FieldDescriptor> C2TestStruct_A_FD_PTR_fieldList =
+    { C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->signed32,   "s32"),
+      C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->signed64,   "s64"),
+      C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->unsigned32, "u32"),
+      C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->unsigned64, "u64"),
+      C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->fp32,      "fp"),
+      C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->sz,       "size"),
+      C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->blob,       "blob"),
+      C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->string,     "str"),
+    //  C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->yesNo,      "y-n")
+    };
+
+INSTANTIATE_TEST_CASE_P(PointerConstructor, C2ParamTest_ParamFieldList, ::testing::Values(C2TestStruct_A_FD_PTR_fieldList));
+
+// define fields using C2FieldDescriptor member-pointer constructor
+const std::vector<C2FieldDescriptor> C2TestStruct_A_FD_MEM_PTR_fieldList =
+    { C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::signed32,   "s32"),
+      C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::signed64,   "s64"),
+      C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::unsigned32, "u32"),
+      C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::unsigned64, "u64"),
+      C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::fp32,      "fp"),
+      C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::sz,       "size"),
+      C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::blob,       "blob"),
+      C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::string,     "str"),
+    //  C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::yesNo,      "y-n")
+    };
+
+INSTANTIATE_TEST_CASE_P(MemberPointerConstructor, C2ParamTest_ParamFieldList, ::testing::Values(C2TestStruct_A_FD_MEM_PTR_fieldList));
+
+// Test 2. define a structure with two-step helper methods
+
+struct C2TestAStruct {
+    int32_t signed32;
+    int64_t signed64[2];
+    uint32_t unsigned32[1];
+    uint64_t unsigned64;
+    float fp32;
+    C2SizeStruct sz[3];
+    uint8_t blob[100];
+    char string[100];
+    bool yesNo[100];
+
+private: // test access level
+    DEFINE_C2STRUCT(TestA)
+} C2_PACK;
+
+DESCRIBE_C2STRUCT(TestA, {
+    C2FIELD(signed32, "s32")
+    C2FIELD(signed64, "s64")
+    C2FIELD(unsigned32, "u32")
+    C2FIELD(unsigned64, "u64")
+    C2FIELD(fp32, "fp")
+    C2FIELD(sz, "size")
+    C2FIELD(blob, "blob")
+    C2FIELD(string, "str")
+    // C2FIELD(yesNo, "y-n")
+}) // ; optional
+
+INSTANTIATE_TEST_CASE_P(DescribeStruct2Step, C2ParamTest_ParamFieldList, ::testing::Values(C2TestAStruct::FieldList()));
+
+// Test 3. define a structure with one-step helper method
+
+struct C2TestBStruct {
+    int32_t signed32;
+    int64_t signed64[2];
+    uint32_t unsigned32[1];
+    uint64_t unsigned64;
+    float fp32;
+    C2SizeStruct sz[3];
+    uint8_t blob[100];
+    char string[100];
+    bool yesNo[100];
+
+private: // test access level
+    DEFINE_AND_DESCRIBE_C2STRUCT(TestB)
+
+    C2FIELD(signed32, "s32")
+    C2FIELD(signed64, "s64")
+    C2FIELD(unsigned32, "u32")
+    C2FIELD(unsigned64, "u64")
+    C2FIELD(fp32, "fp")
+    C2FIELD(sz, "size")
+    C2FIELD(blob, "blob")
+    C2FIELD(string, "str")
+    // C2FIELD(yesNo, "y-n")
+};
+
+INSTANTIATE_TEST_CASE_P(DescribeStruct1Step, C2ParamTest_ParamFieldList, ::testing::Values(C2TestBStruct::FieldList()));
+
+// Test 4. flexible members
+
+template<typename T>
+class C2ParamTest_FlexParamFieldList : public ::testing::Test {
+protected:
+    using type_t=FD::type_t;
+
+    // static std::vector<std::vector<C2FieldDescriptor>>
+    static std::vector<std::vector<C2FieldDescriptor>>
+            GetLists();
+
+    constexpr static type_t FlexType =
+            std::is_same<T, int32_t>::value ? FD::INT32 :
+            std::is_same<T, int64_t>::value ? FD::INT64 :
+            std::is_same<T, uint32_t>::value ? FD::UINT32 :
+            std::is_same<T, uint64_t>::value ? FD::UINT64 :
+            std::is_same<T, float>::value ? FD::FLOAT :
+            std::is_same<T, uint8_t>::value ? FD::BLOB :
+            std::is_same<T, char>::value ? FD::STRING :
+            std::is_same<T, C2SizeStruct>::value ? C2SizeStruct::TYPE : (type_t)0;
+    constexpr static size_t FLEX_SIZE = sizeof(T);
+};
+
+typedef ::testing::Types<int32_t, int64_t, C2SizeStruct> FlexTypes;
+TYPED_TEST_CASE(C2ParamTest_FlexParamFieldList, FlexTypes);
+
+TYPED_TEST(C2ParamTest_FlexParamFieldList, VerifyStruct) {
+    for (auto a : this->GetLists()) {
+        std::vector<C2FieldDescriptor> fields = a;
+        if (fields.size() > 1) {
+            EXPECT_EQ(2u, fields.size());
+            EXPECT_EQ(C2FieldDescriptor(FD::INT32, 1, "s32", 0, 4), fields[0]);
+            EXPECT_EQ(C2FieldDescriptor(this->FlexType, 0, "flex", 4, this->FLEX_SIZE),
+                      fields[1]);
+        } else {
+            EXPECT_EQ(1u, fields.size());
+            EXPECT_EQ(C2FieldDescriptor(this->FlexType, 0, "flex", 0, this->FLEX_SIZE),
+                      fields[0]);
+        }
+    }
+}
+
+struct C2TestStruct_FlexS32 {
+    int32_t mFlex[];
+
+    const static std::vector<C2FieldDescriptor> _FIELD_LIST;
+    static const std::vector<C2FieldDescriptor> FieldList();
+    // enum : uint32_t { CORE_INDEX = kParamIndexTestFlex, FLEX_SIZE = 4 };
+    // typedef C2TestStruct_FlexS32 _type;
+    // typedef int32_t FlexType;
+};
+
+const std::vector<C2FieldDescriptor> C2TestStruct_FlexS32::FieldList() {
+    return _FIELD_LIST;
+}
+const std::vector<C2FieldDescriptor> C2TestStruct_FlexS32::_FIELD_LIST = {
+    { FD::INT32, 0, "flex", 0, 4 }
+};
+
+struct C2TestStruct_FlexEndS32 {
+    int32_t signed32;
+    int32_t mFlex[];
+
+    const static std::vector<C2FieldDescriptor> _FIELD_LIST;
+    static const std::vector<C2FieldDescriptor> FieldList();
+    // enum : uint32_t { CORE_INDEX = kParamIndexTestFlexEnd, FLEX_SIZE = 4 };
+    // typedef C2TestStruct_FlexEnd _type;
+    // typedef int32_t FlexType;
+};
+
+const std::vector<C2FieldDescriptor> C2TestStruct_FlexEndS32::FieldList() {
+    return _FIELD_LIST;
+}
+const std::vector<C2FieldDescriptor> C2TestStruct_FlexEndS32::_FIELD_LIST = {
+    { FD::INT32, 1, "s32", 0, 4 },
+    { FD::INT32, 0, "flex", 4, 4 },
+};
+
+const static std::vector<C2FieldDescriptor> C2TestStruct_FlexEndS32_ptr_fieldList = {
+    C2FieldDescriptor(&((C2TestStruct_FlexEndS32*)0)->signed32, "s32"),
+    C2FieldDescriptor(&((C2TestStruct_FlexEndS32*)0)->mFlex, "flex"),
+};
+
+struct C2TestFlexS32Struct {
+    int32_t mFlexSigned32[];
+private: // test access level
+    C2TestFlexS32Struct() {}
+
+    DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(TestFlexS32, mFlexSigned32)
+    C2FIELD(mFlexSigned32, "flex")
+};
+
+struct C2TestFlexEndS32Struct {
+    int32_t signed32;
+    int32_t mFlexSigned32[];
+private: // test access level
+    C2TestFlexEndS32Struct() {}
+
+    DEFINE_FLEX_C2STRUCT(TestFlexEndS32, mFlexSigned32)
+} C2_PACK;
+
+DESCRIBE_C2STRUCT(TestFlexEndS32, {
+    C2FIELD(signed32, "s32")
+    C2FIELD(mFlexSigned32, "flex")
+}) // ; optional
+
+template<>
+std::vector<std::vector<C2FieldDescriptor>>
+//std::vector<std::vector<C2FieldDescriptor>>
+C2ParamTest_FlexParamFieldList<int32_t>::GetLists() {
+    return {
+        C2TestStruct_FlexS32::FieldList(),
+        C2TestStruct_FlexEndS32::FieldList(),
+        C2TestStruct_FlexEndS32_ptr_fieldList,
+        C2TestFlexS32Struct::FieldList(),
+        C2TestFlexEndS32Struct::FieldList(),
+    };
+}
+
+struct C2TestStruct_FlexS64 {
+    int64_t mFlexSigned64[];
+
+    const static std::vector<C2FieldDescriptor> _FIELD_LIST;
+    static const std::vector<C2FieldDescriptor> FieldList();
+    // enum : uint32_t { CORE_INDEX = kParamIndexTestFlexS64, FLEX_SIZE = 8 };
+    // typedef C2TestStruct_FlexS64 _type;
+    // typedef int64_t FlexType;
+};
+
+const std::vector<C2FieldDescriptor> C2TestStruct_FlexS64::FieldList() {
+    return _FIELD_LIST;
+}
+const std::vector<C2FieldDescriptor> C2TestStruct_FlexS64::_FIELD_LIST = {
+    { FD::INT64, 0, "flex", 0, 8 }
+};
+
+struct C2TestStruct_FlexEndS64 {
+    int32_t signed32;
+    int64_t mSigned64Flex[];
+
+    const static std::vector<C2FieldDescriptor> _FIELD_LIST;
+    static const std::vector<C2FieldDescriptor> FieldList();
+    // enum : uint32_t { CORE_INDEX = C2TestStruct_FlexEndS64, FLEX_SIZE = 8 };
+    // typedef C2TestStruct_FlexEndS64 _type;
+    // typedef int64_t FlexType;
+};
+
+const std::vector<C2FieldDescriptor> C2TestStruct_FlexEndS64::FieldList() {
+    return _FIELD_LIST;
+}
+const std::vector<C2FieldDescriptor> C2TestStruct_FlexEndS64::_FIELD_LIST = {
+    { FD::INT32, 1, "s32", 0, 4 },
+    { FD::INT64, 0, "flex", 4, 8 },
+};
+
+struct C2TestFlexS64Struct {
+    int64_t mFlexSigned64[];
+    C2TestFlexS64Struct() {}
+
+    DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(TestFlexS64, mFlexSigned64)
+    C2FIELD(mFlexSigned64, "flex")
+};
+
+struct C2TestFlexEndS64Struct {
+    int32_t signed32;
+    int64_t mFlexSigned64[];
+    C2TestFlexEndS64Struct() {}
+
+    DEFINE_FLEX_C2STRUCT(TestFlexEndS64, mFlexSigned64)
+} C2_PACK;
+
+DESCRIBE_C2STRUCT(TestFlexEndS64, {
+    C2FIELD(signed32, "s32")
+    C2FIELD(mFlexSigned64, "flex")
+}) // ; optional
+
+template<>
+std::vector<std::vector<C2FieldDescriptor>>
+//std::vector<std::vector<C2FieldDescriptor>>
+C2ParamTest_FlexParamFieldList<int64_t>::GetLists() {
+    return {
+        C2TestStruct_FlexS64::FieldList(),
+        C2TestStruct_FlexEndS64::FieldList(),
+        C2TestFlexS64Struct::FieldList(),
+        C2TestFlexEndS64Struct::FieldList(),
+    };
+}
+
+struct C2TestStruct_FlexSize {
+    C2SizeStruct mFlexSize[];
+
+    const static std::vector<C2FieldDescriptor> _FIELD_LIST;
+    static const std::vector<C2FieldDescriptor> FieldList();
+    // enum : uint32_t { CORE_INDEX = kParamIndexTestFlexSize, FLEX_SIZE = 8 };
+    // typedef C2TestStruct_FlexSize _type;
+    // typedef C2SizeStruct FlexType;
+};
+
+const std::vector<C2FieldDescriptor> C2TestStruct_FlexSize::FieldList() {
+    return _FIELD_LIST;
+}
+const std::vector<C2FieldDescriptor> C2TestStruct_FlexSize::_FIELD_LIST = {
+    { C2SizeStruct::TYPE, 0, "flex", 0, sizeof(C2SizeStruct) }
+};
+
+struct C2TestStruct_FlexEndSize {
+    int32_t signed32;
+    C2SizeStruct mSizeFlex[];
+
+    const static std::vector<C2FieldDescriptor> _FIELD_LIST;
+    static const std::vector<C2FieldDescriptor> FieldList();
+    // enum : uint32_t { CORE_INDEX = C2TestStruct_FlexEndSize, FLEX_SIZE = 8 };
+    // typedef C2TestStruct_FlexEndSize _type;
+    // typedef C2SizeStruct FlexType;
+};
+
+const std::vector<C2FieldDescriptor> C2TestStruct_FlexEndSize::FieldList() {
+    return _FIELD_LIST;
+}
+const std::vector<C2FieldDescriptor> C2TestStruct_FlexEndSize::_FIELD_LIST = {
+    { FD::INT32, 1, "s32", 0, 4 },
+    { C2SizeStruct::TYPE, 0, "flex", 4, sizeof(C2SizeStruct) },
+};
+
+struct C2TestFlexSizeStruct {
+    C2SizeStruct mFlexSize[];
+    C2TestFlexSizeStruct() {}
+
+    DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(TestFlexSize, mFlexSize)
+    C2FIELD(mFlexSize, "flex")
+};
+
+struct C2TestFlexEndSizeStruct {
+    int32_t signed32;
+    C2SizeStruct mFlexSize[];
+    C2TestFlexEndSizeStruct() {}
+
+    DEFINE_FLEX_C2STRUCT(TestFlexEndSize, mFlexSize)
+} C2_PACK;
+
+DESCRIBE_C2STRUCT(TestFlexEndSize, {
+    C2FIELD(signed32, "s32")
+    C2FIELD(mFlexSize, "flex")
+}) // ; optional
+
+struct C2TestBaseFlexEndSizeStruct {
+    int32_t signed32;
+    C2SizeStruct mFlexSize[];
+    C2TestBaseFlexEndSizeStruct() {}
+
+    DEFINE_BASE_FLEX_C2STRUCT(TestBaseFlexEndSize, mFlexSize)
+} C2_PACK;
+
+DESCRIBE_C2STRUCT(TestBaseFlexEndSize, {
+    C2FIELD(signed32, "s32")
+    C2FIELD(mFlexSize, "flex")
+}) // ; optional
+
+struct C2TestBaseFlexEndSize2Struct {
+    int32_t signed32;
+    C2SizeStruct mFlexSize[];
+    C2TestBaseFlexEndSize2Struct() {}
+
+    DEFINE_AND_DESCRIBE_BASE_FLEX_C2STRUCT(TestBaseFlexEndSize2, mFlexSize)
+    C2FIELD(signed32, "s32")
+    C2FIELD(mFlexSize, "flex")
+};
+
+template<>
+std::vector<std::vector<C2FieldDescriptor>>
+//std::vector<std::vector<C2FieldDescriptor>>
+C2ParamTest_FlexParamFieldList<C2SizeStruct>::GetLists() {
+    return {
+        C2TestStruct_FlexSize::FieldList(),
+        C2TestStruct_FlexEndSize::FieldList(),
+        C2TestFlexSizeStruct::FieldList(),
+        C2TestFlexEndSizeStruct::FieldList(),
+        C2TestBaseFlexEndSizeStruct::FieldList(),
+        C2TestBaseFlexEndSize2Struct::FieldList(),
+    };
+}
+
+TEST_F(C2ParamTest, FieldId) {
+    // pointer constructor
+    EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&((C2TestStruct_A*)0)->signed32));
+    EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&((C2TestStruct_A*)0)->signed64));
+    EXPECT_EQ(_C2FieldId(20, 4), _C2FieldId(&((C2TestStruct_A*)0)->unsigned32));
+    EXPECT_EQ(_C2FieldId(24, 8), _C2FieldId(&((C2TestStruct_A*)0)->unsigned64));
+    EXPECT_EQ(_C2FieldId(32, 4), _C2FieldId(&((C2TestStruct_A*)0)->fp32));
+    EXPECT_EQ(_C2FieldId(36, 8), _C2FieldId(&((C2TestStruct_A*)0)->sz));
+    EXPECT_EQ(_C2FieldId(60, 1), _C2FieldId(&((C2TestStruct_A*)0)->blob));
+    EXPECT_EQ(_C2FieldId(160, 1), _C2FieldId(&((C2TestStruct_A*)0)->string));
+    EXPECT_EQ(_C2FieldId(260, 1), _C2FieldId(&((C2TestStruct_A*)0)->yesNo));
+
+    EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&((C2TestFlexEndSizeStruct*)0)->signed32));
+    EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&((C2TestFlexEndSizeStruct*)0)->mFlexSize));
+
+    EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&((C2TestBaseFlexEndSizeStruct*)0)->signed32));
+    EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&((C2TestBaseFlexEndSizeStruct*)0)->mFlexSize));
+
+    // member pointer constructor
+    EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::signed32));
+    EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::signed64));
+    EXPECT_EQ(_C2FieldId(20, 4), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::unsigned32));
+    EXPECT_EQ(_C2FieldId(24, 8), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::unsigned64));
+    EXPECT_EQ(_C2FieldId(32, 4), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::fp32));
+    EXPECT_EQ(_C2FieldId(36, 8), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::sz));
+    EXPECT_EQ(_C2FieldId(60, 1), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::blob));
+    EXPECT_EQ(_C2FieldId(160, 1), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::string));
+    EXPECT_EQ(_C2FieldId(260, 1), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::yesNo));
+
+    EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId((C2TestFlexEndSizeStruct*)0, &C2TestFlexEndSizeStruct::signed32));
+    EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId((C2TestFlexEndSizeStruct*)0, &C2TestFlexEndSizeStruct::mFlexSize));
+
+    EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId((C2TestBaseFlexEndSizeStruct*)0, &C2TestBaseFlexEndSizeStruct::signed32));
+    EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId((C2TestBaseFlexEndSizeStruct*)0, &C2TestBaseFlexEndSizeStruct::mFlexSize));
+
+    // member pointer sans type pointer
+    EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&C2TestStruct_A::signed32));
+    EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&C2TestStruct_A::signed64));
+    EXPECT_EQ(_C2FieldId(20, 4), _C2FieldId(&C2TestStruct_A::unsigned32));
+    EXPECT_EQ(_C2FieldId(24, 8), _C2FieldId(&C2TestStruct_A::unsigned64));
+    EXPECT_EQ(_C2FieldId(32, 4), _C2FieldId(&C2TestStruct_A::fp32));
+    EXPECT_EQ(_C2FieldId(36, 8), _C2FieldId(&C2TestStruct_A::sz));
+    EXPECT_EQ(_C2FieldId(60, 1), _C2FieldId(&C2TestStruct_A::blob));
+    EXPECT_EQ(_C2FieldId(160, 1), _C2FieldId(&C2TestStruct_A::string));
+    EXPECT_EQ(_C2FieldId(260, 1), _C2FieldId(&C2TestStruct_A::yesNo));
+
+    EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&C2TestFlexEndSizeStruct::signed32));
+    EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&C2TestFlexEndSizeStruct::mFlexSize));
+
+    EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&C2TestBaseFlexEndSizeStruct::signed32));
+    EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&C2TestBaseFlexEndSizeStruct::mFlexSize));
+
+    typedef C2GlobalParam<C2Info, C2TestAStruct> C2TestAInfo;
+    typedef C2GlobalParam<C2Info, C2TestFlexEndSizeStruct> C2TestFlexEndSizeInfo;
+    typedef C2GlobalParam<C2Info, C2TestBaseFlexEndSizeStruct, kParamIndexTestFlexEndSize> C2TestFlexEndSizeInfoFromBase;
+
+    // pointer constructor in C2Param
+    EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId(&((C2TestAInfo*)0)->signed32));
+    EXPECT_EQ(_C2FieldId(12, 8), _C2FieldId(&((C2TestAInfo*)0)->signed64));
+    EXPECT_EQ(_C2FieldId(28, 4), _C2FieldId(&((C2TestAInfo*)0)->unsigned32));
+    EXPECT_EQ(_C2FieldId(32, 8), _C2FieldId(&((C2TestAInfo*)0)->unsigned64));
+    EXPECT_EQ(_C2FieldId(40, 4), _C2FieldId(&((C2TestAInfo*)0)->fp32));
+    EXPECT_EQ(_C2FieldId(44, 8), _C2FieldId(&((C2TestAInfo*)0)->sz));
+    EXPECT_EQ(_C2FieldId(68, 1), _C2FieldId(&((C2TestAInfo*)0)->blob));
+    EXPECT_EQ(_C2FieldId(168, 1), _C2FieldId(&((C2TestAInfo*)0)->string));
+    EXPECT_EQ(_C2FieldId(268, 1), _C2FieldId(&((C2TestAInfo*)0)->yesNo));
+
+    EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId(&((C2TestFlexEndSizeInfo*)0)->m.signed32));
+    EXPECT_EQ(_C2FieldId(12, 8), _C2FieldId(&((C2TestFlexEndSizeInfo*)0)->m.mFlexSize));
+
+    EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId(&((C2TestFlexEndSizeInfoFromBase*)0)->m.signed32));
+    EXPECT_EQ(_C2FieldId(12, 8), _C2FieldId(&((C2TestFlexEndSizeInfoFromBase*)0)->m.mFlexSize));
+
+    // member pointer in C2Param
+    EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::signed32));
+    EXPECT_EQ(_C2FieldId(12, 8), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::signed64));
+    EXPECT_EQ(_C2FieldId(28, 4), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::unsigned32));
+    EXPECT_EQ(_C2FieldId(32, 8), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::unsigned64));
+    EXPECT_EQ(_C2FieldId(40, 4), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::fp32));
+    EXPECT_EQ(_C2FieldId(44, 8), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::sz));
+    EXPECT_EQ(_C2FieldId(68, 1), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::blob));
+    EXPECT_EQ(_C2FieldId(168, 1), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::string));
+    EXPECT_EQ(_C2FieldId(268, 1), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::yesNo));
+
+    // NOTE: cannot use a member pointer for flex params due to introduction of 'm'
+    // EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId(&C2TestFlexEndSizeInfo::m.signed32));
+    // EXPECT_EQ(_C2FieldId(12, 8), _C2FieldId(&C2TestFlexEndSizeInfo::m.mFlexSize));
+
+    // EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId(&C2TestFlexEndSizeInfoFromBase::m.signed32));
+    // EXPECT_EQ(_C2FieldId(12, 8), _C2FieldId(&C2TestFlexEndSizeInfoFromBase::m.mFlexSize));
+
+
+}
+
+struct S32 {
+    template<typename T, class B=typename std::remove_extent<T>::type>
+    inline S32(const T*) {
+        static_assert(!std::is_array<T>::value, "should not be an array");
+        static_assert(std::is_same<B, int32_t>::value, "should be int32_t");
+    }
+};
+
+struct FLX {
+    template<typename U, typename T, class B=typename std::remove_extent<T>::type>
+    inline FLX(const T*, const U*) {
+        static_assert(std::is_array<T>::value, "should be an array");
+        static_assert(std::extent<T>::value == 0, "should be an array of 0 extent");
+        static_assert(std::is_same<B, U>::value, "should be type U");
+    }
+};
+
+struct MP {
+    template<typename U, typename T, typename ExpectedU, typename UnexpectedU>
+    inline MP(T U::*, const ExpectedU*, const UnexpectedU*) {
+        static_assert(!std::is_same<U, UnexpectedU>::value, "should not be member pointer of the base type");
+        static_assert(std::is_same<U, ExpectedU>::value, "should be member pointer of the derived type");
+    }
+
+    template<typename U, typename T, typename B, typename D>
+    inline MP(T D::*, const D*) { }
+};
+
+void compiledStatic_arrayTypePropagationTest() {
+    (void)S32(&((C2TestFlexEndS32Struct *)0)->signed32);
+    (void)FLX(&((C2TestFlexEndS32Struct *)0)->mFlexSigned32, (int32_t*)0);
+    (void)FLX(&((C2TestFlexS32Struct *)0)->mFlexSigned32, (int32_t*)0);
+
+    typedef C2GlobalParam<C2Info, C2TestAStruct> C2TestAInfo;
+
+    // TRICKY: &derivedClass::baseMember has type of baseClass::*
+    static_assert(std::is_same<decltype(&C2TestAInfo::signed32), int32_t C2TestAStruct::*>::value,
+                  "base member pointer should have base class in type");
+
+    // therefore, member pointer expands to baseClass::* in templates
+    (void)MP(&C2TestAInfo::signed32,
+             (C2TestAStruct*)0 /* expected */, (C2TestAInfo*)0 /* unexpected */);
+    // but can be cast to derivedClass::*
+    (void)MP((int32_t C2TestAInfo::*)&C2TestAInfo::signed32,
+             (C2TestAInfo*)0 /* expected */, (C2TestAStruct*)0 /* unexpected */);
+
+    // TRICKY: baseClass::* does not autoconvert to derivedClass::* even in templates
+    // (void)MP(&C2TestAInfo::signed32, (C2TestAInfo*)0);
+}
+
+TEST_F(C2ParamTest, MemberPointerCast) {
+    typedef C2GlobalParam<C2Info, C2TestAStruct> C2TestAInfo;
+
+    static_assert(offsetof(C2TestAInfo, signed32) == 8, "offset should be 8");
+    constexpr int32_t C2TestAStruct::* s32ptr = &C2TestAInfo::signed32;
+    constexpr int32_t C2TestAInfo::* s32ptr_derived = (int32_t C2TestAStruct::*)&C2TestAInfo::signed32;
+    constexpr int32_t C2TestAInfo::* s32ptr_cast2derived = (int32_t C2TestAInfo::*)s32ptr;
+    C2TestAInfo *info = (C2TestAInfo *)256;
+    C2TestAStruct *strukt = (C2TestAStruct *)info;
+    int32_t *info_s32_derived = &(info->*s32ptr_derived);
+    int32_t *info_s32_cast2derived = &(info->*s32ptr_cast2derived);
+    int32_t *info_s32 = &(info->*s32ptr);
+    int32_t *strukt_s32 = &(strukt->*s32ptr);
+
+    EXPECT_EQ(256u, (uintptr_t)info);
+    EXPECT_EQ(264u, (uintptr_t)strukt);
+    EXPECT_EQ(264u, (uintptr_t)info_s32_derived);
+    EXPECT_EQ(264u, (uintptr_t)info_s32_cast2derived);
+    EXPECT_EQ(264u, (uintptr_t)info_s32);
+    EXPECT_EQ(264u, (uintptr_t)strukt_s32);
+
+    typedef C2GlobalParam<C2Info, C2TestFlexEndSizeStruct> C2TestFlexEndSizeInfo;
+    static_assert(offsetof(C2TestFlexEndSizeInfo, m.signed32) == 8, "offset should be 8");
+    static_assert(offsetof(C2TestFlexEndSizeInfo, m.mFlexSize) == 12, "offset should be 12");
+
+    typedef C2GlobalParam<C2Info, C2TestBaseFlexEndSizeStruct, kParamIndexTestFlexEndSize> C2TestFlexEndSizeInfoFromBase;
+    static_assert(offsetof(C2TestFlexEndSizeInfoFromBase, m.signed32) == 8, "offset should be 8");
+    static_assert(offsetof(C2TestFlexEndSizeInfoFromBase, m.mFlexSize) == 12, "offset should be 12");
+}
+
+/* ===================================== PARAM USAGE TESTS ===================================== */
+
+struct C2NumberStruct {
+    int32_t mNumber;
+    C2NumberStruct() {}
+    C2NumberStruct(int32_t _number) : mNumber(_number) {}
+
+    DEFINE_AND_DESCRIBE_C2STRUCT(Number)
+    C2FIELD(mNumber, "number")
+};
+
+struct C2NumberBaseStruct {
+    int32_t mNumber;
+    C2NumberBaseStruct() {}
+    C2NumberBaseStruct(int32_t _number) : mNumber(_number) {}
+
+    DEFINE_AND_DESCRIBE_BASE_C2STRUCT(NumberBase)
+    C2FIELD(mNumber, "number")
+};
+
+struct C2NumbersStruct {
+    int32_t mNumbers[];
+    C2NumbersStruct() {}
+
+    DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(Numbers, mNumbers)
+    C2FIELD(mNumbers, "numbers")
+};
+static_assert(sizeof(C2NumbersStruct) == 0, "C2NumbersStruct has incorrect size");
+
+typedef C2GlobalParam<C2Info, C2NumberStruct> C2NumberInfo;
+
+typedef C2GlobalParam<C2Tuning, C2NumberStruct> C2NumberTuning;
+typedef   C2PortParam<C2Tuning, C2NumberStruct> C2NumberPortTuning;
+typedef C2StreamParam<C2Tuning, C2NumberStruct> C2NumberStreamTuning;
+
+typedef C2GlobalParam<C2Tuning, C2NumbersStruct> C2NumbersTuning;
+typedef   C2PortParam<C2Tuning, C2NumbersStruct> C2NumbersPortTuning;
+typedef C2StreamParam<C2Tuning, C2NumbersStruct> C2NumbersStreamTuning;
+
+//
+#if 0
+
+void test() {
+    C2NumberStruct s(10);
+    (void)C2NumberStruct::FieldList();
+};
+
+typedef C2StreamParam<C2Tuning, C2Int64Value, kParamIndexNumberB> C2NumberConfig4;
+typedef C2PortParam<C2Tuning, C2Int32Value, kParamIndexNumber> C2NumberConfig3;
+typedef C2GlobalParam<C2Tuning, C2StringValue, kParamIndexNumber> C2VideoNameConfig;
+
+void test3() {
+    C2NumberConfig3 s(10);
+    s.value = 11;
+    s = 12;
+    (void)C2NumberConfig3::FieldList();
+    std::shared_ptr<C2VideoNameConfig> n = C2VideoNameConfig::AllocShared(25);
+    strcpy(n->m.value, "lajos");
+    C2NumberConfig4 t(false, 0, 11);
+    t.value = 15;
+};
+
+struct C2NumbersStruct {
+    int32_t mNumbers[];
+    enum { CORE_INDEX = kParamIndexNumber };
+    const static std::vector<C2FieldDescriptor> FieldList();
+    static const std::vector<C2FieldDescriptor> FieldList();
+    C2NumbersStruct() {}
+
+    FLEX(C2NumbersStruct, mNumbers);
+};
+
+static_assert(sizeof(C2NumbersStruct) == 0, "yes");
+
+
+typedef C2GlobalParam<C2Info, C2NumbersStruct> C2NumbersInfo;
+
+const std::vector<C2FieldDescriptor> C2NumbersStruct::FieldList() {
+    return _FIELD_LIST;
+}
+const std::vector<C2FieldDescriptor> C2NumbersStruct::_FIELD_LIST =
+//    { { FD::INT32, 0, "widths" } };
+    { C2FieldDescriptor(&((C2NumbersStruct*)(nullptr))->mNumbers, "number") };
+
+typedef C2PortParam<C2Tuning, C2NumberStruct> C2NumberConfig;
+
+std::vector<C2FieldDescriptor> myList = C2NumberConfig::FieldList();
+
+    std::unique_ptr<C2ParamDescriptor> __test_describe(uint32_t paramType) {
+        std::list<C2FieldDescriptor> fields = describeC2Params<C2NumberConfig>();
+
+        auto widths = C2NumbersInfo::AllocShared(5);
+        widths->flexCount();
+        widths->m.mNumbers[4] = 1;
+
+        test();
+        test3();
+
+        C2NumberConfig outputWidth(false, 123);
+
+        C2Param::Index index(paramType);
+        switch (paramType) {
+        case C2NumberConfig::CORE_INDEX:
+            return std::unique_ptr<C2ParamDescriptor>(new C2ParamDescriptor{
+                true /* isRequired */,
+                "number",
+                index,
+            });
+        }
+        return nullptr;
+    }
+
+
+} // namespace android
+
+#endif
+//
+
+template<typename T>
+bool canSetPort(T &o, bool output) { return o.setPort(output); }
+bool canSetPort(...) { return false; }
+
+template<typename S, typename=decltype(((S*)0)->setPort(true))>
+static std::true_type _canCallSetPort(int);
+template<typename>
+static std::false_type _canCallSetPort(...);
+#define canCallSetPort(x) decltype(_canCallSetPort<std::remove_reference<decltype(x)>::type>(0))::value
+
+/* ======================================= STATIC TESTS ======================================= */
+
+static_assert(_C2Comparable<int>::value, "int is not comparable");
+static_assert(!_C2Comparable<void>::value, "void is comparable");
+
+struct C2_HIDE _test0 {
+    bool operator==(const _test0&);
+    bool operator!=(const _test0&);
+};
+struct C2_HIDE _test1 {
+    bool operator==(const _test1&);
+};
+struct C2_HIDE _test2 {
+    bool operator!=(const _test2&);
+};
+static_assert(_C2Comparable<_test0>::value, "class with == and != is not comparable");
+static_assert(_C2Comparable<_test1>::value, "class with == is not comparable");
+static_assert(_C2Comparable<_test2>::value, "class with != is not comparable");
+
+/* ======================================= C2PARAM TESTS ======================================= */
+
+struct _C2ParamInspector {
+    static void StaticTest();
+    static void StaticFromBaseTest();
+    static void StaticFlexTest();
+    static void StaticFlexFromBaseTest();
+};
+
+// TEST_F(_C2ParamInspector, StaticTest) {
+void _C2ParamInspector::StaticTest() {
+    typedef C2Param::Index I;
+
+    // C2NumberStruct: CORE_INDEX = kIndex                          (args)
+    static_assert(C2NumberStruct::CORE_INDEX == kParamIndexNumber, "bad index");
+    static_assert(sizeof(C2NumberStruct) == 4, "bad size");
+
+    // C2NumberTuning:             kIndex | tun | global           (args)
+    static_assert(C2NumberTuning::CORE_INDEX == kParamIndexNumber, "bad index");
+    static_assert(C2NumberTuning::PARAM_TYPE == (kParamIndexNumber | I::KIND_TUNING | I::DIR_GLOBAL), "bad index");
+    static_assert(sizeof(C2NumberTuning) == 12, "bad size");
+
+    static_assert(offsetof(C2NumberTuning, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2NumberTuning, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2NumberTuning, mNumber) == 8, "bad offset");
+
+    // C2NumberPortTuning:         kIndex | tun | port             (bool, args)
+    static_assert(sizeof(C2NumberPortTuning) == 12, "bad size");
+    // C2NumberPortTuning::input:  kIndex | tun | port | input     (args)
+    // C2NumberPortTuning::output: kIndex | tun | port | output    (args)
+    static_assert(C2NumberPortTuning::input::CORE_INDEX ==
+                  kParamIndexNumber, "bad index");
+    static_assert(C2NumberPortTuning::input::PARAM_TYPE ==
+                  (kParamIndexNumber | I::KIND_TUNING | I::DIR_INPUT), "bad index");
+    static_assert(C2NumberPortTuning::output::CORE_INDEX ==
+                  kParamIndexNumber, "bad index");
+    static_assert(C2NumberPortTuning::output::PARAM_TYPE ==
+                  (kParamIndexNumber | I::KIND_TUNING | I::DIR_OUTPUT), "bad index");
+    static_assert(sizeof(C2NumberPortTuning::input) == 12, "bad size");
+    static_assert(sizeof(C2NumberPortTuning::output) == 12, "bad size");
+    static_assert(offsetof(C2NumberPortTuning::input, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2NumberPortTuning::input, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2NumberPortTuning::input, mNumber) == 8, "bad offset");
+    static_assert(offsetof(C2NumberPortTuning::output, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2NumberPortTuning::output, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2NumberPortTuning::output, mNumber) == 8, "bad offset");
+
+    // C2NumberStreamTuning:       kIndex | tun | str              (bool, uint, args)
+    static_assert(sizeof(C2NumberStreamTuning) == 12u, "bad size");
+    // C2NumberStreamTuning::input kIndex | tun | str | input      (int, args)
+    // C2NumberStreamTuning::output kIx   | tun | str | output     (int, args)
+    static_assert(C2NumberStreamTuning::input::CORE_INDEX ==
+                  kParamIndexNumber, "bad index");
+    static_assert(C2NumberStreamTuning::input::PARAM_TYPE ==
+                  (kParamIndexNumber | I::KIND_TUNING | I::DIR_INPUT | I::IS_STREAM_FLAG), "bad index");
+    static_assert(C2NumberStreamTuning::output::CORE_INDEX ==
+                  kParamIndexNumber, "bad index");
+    static_assert(C2NumberStreamTuning::output::PARAM_TYPE ==
+                  (kParamIndexNumber | I::KIND_TUNING | I::DIR_OUTPUT | I::IS_STREAM_FLAG), "bad index");
+    static_assert(sizeof(C2NumberStreamTuning::input) == 12u, "bad size");
+    static_assert(sizeof(C2NumberStreamTuning::output) == 12u, "bad size");
+    static_assert(offsetof(C2NumberStreamTuning::input, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2NumberStreamTuning::input, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2NumberStreamTuning::input, mNumber) == 8, "bad offset");
+    static_assert(offsetof(C2NumberStreamTuning::output, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2NumberStreamTuning::output, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2NumberStreamTuning::output, mNumber) == 8, "bad offset");
+}
+
+void _C2ParamInspector::StaticFromBaseTest() {
+    enum { kParamIndexMy = 3102 };
+    typedef C2NumberBaseStruct C2MyStruct;
+    typedef C2GlobalParam<C2Setting, C2MyStruct, kParamIndexMy> C2MySetting;
+    typedef   C2PortParam<C2Setting, C2MyStruct, kParamIndexMy> C2MyPortSetting;
+    typedef C2StreamParam<C2Setting, C2MyStruct, kParamIndexMy> C2MyStreamSetting;
+
+    typedef C2Param::Index I;
+
+    // C2MyStruct has no CORE_INDEX
+    //static_assert(C2MyStruct::CORE_INDEX == kParamIndexMy, "bad index");
+    static_assert(sizeof(C2MyStruct) == 4, "bad size");
+
+    // C2MySetting:             kIndex | tun | global           (args)
+    static_assert(C2MySetting::CORE_INDEX == kParamIndexMy, "bad index");
+    static_assert(C2MySetting::PARAM_TYPE == (kParamIndexMy | I::KIND_SETTING | I::DIR_GLOBAL), "bad index");
+    static_assert(sizeof(C2MySetting) == 12, "bad size");
+
+    static_assert(offsetof(C2MySetting, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2MySetting, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2MySetting, mNumber) == 8, "bad offset");
+
+    // C2MyPortSetting:         kIndex | tun | port             (bool, args)
+    static_assert(sizeof(C2MyPortSetting) == 12, "bad size");
+    // C2MyPortSetting::input:  kIndex | tun | port | input     (args)
+    // C2MyPortSetting::output: kIndex | tun | port | output    (args)
+    static_assert(C2MyPortSetting::input::CORE_INDEX ==
+                  kParamIndexMy, "bad index");
+    static_assert(C2MyPortSetting::input::PARAM_TYPE ==
+                  (kParamIndexMy | I::KIND_SETTING | I::DIR_INPUT), "bad index");
+    static_assert(C2MyPortSetting::output::CORE_INDEX ==
+                  kParamIndexMy, "bad index");
+    static_assert(C2MyPortSetting::output::PARAM_TYPE ==
+                  (kParamIndexMy | I::KIND_SETTING | I::DIR_OUTPUT), "bad index");
+    static_assert(sizeof(C2MyPortSetting::input) == 12, "bad size");
+    static_assert(sizeof(C2MyPortSetting::output) == 12, "bad size");
+    static_assert(offsetof(C2MyPortSetting::input, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2MyPortSetting::input, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2MyPortSetting::input, mNumber) == 8, "bad offset");
+    static_assert(offsetof(C2MyPortSetting::output, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2MyPortSetting::output, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2MyPortSetting::output, mNumber) == 8, "bad offset");
+
+    // C2MyStreamSetting:       kIndex | tun | str              (bool, uint, args)
+    static_assert(sizeof(C2MyStreamSetting) == 12u, "bad size");
+    // C2MyStreamSetting::input kIndex | tun | str | input      (int, args)
+    // C2MyStreamSetting::output kIx   | tun | str | output     (int, args)
+    static_assert(C2MyStreamSetting::input::CORE_INDEX ==
+                  kParamIndexMy, "bad index");
+    static_assert(C2MyStreamSetting::input::PARAM_TYPE ==
+                  (kParamIndexMy | I::KIND_SETTING | I::DIR_INPUT | I::IS_STREAM_FLAG), "bad index");
+    static_assert(C2MyStreamSetting::output::CORE_INDEX ==
+                  kParamIndexMy, "bad index");
+    static_assert(C2MyStreamSetting::output::PARAM_TYPE ==
+                  (kParamIndexMy | I::KIND_SETTING | I::DIR_OUTPUT | I::IS_STREAM_FLAG), "bad index");
+    static_assert(sizeof(C2MyStreamSetting::input) == 12u, "bad size");
+    static_assert(sizeof(C2MyStreamSetting::output) == 12u, "bad size");
+    static_assert(offsetof(C2MyStreamSetting::input, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2MyStreamSetting::input, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2MyStreamSetting::input, mNumber) == 8, "bad offset");
+    static_assert(offsetof(C2MyStreamSetting::output, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2MyStreamSetting::output, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2MyStreamSetting::output, mNumber) == 8, "bad offset");
+}
+
+void _C2ParamInspector::StaticFlexTest() {
+    typedef C2Param::Index I;
+
+    // C2NumbersStruct: CORE_INDEX = kIndex                          (args)
+    static_assert(C2NumbersStruct::CORE_INDEX == (I::IS_FLEX_FLAG | kParamIndexNumbers), "bad index");
+    static_assert(sizeof(C2NumbersStruct) == 0, "bad size");
+
+    // C2NumbersTuning:             kIndex | tun | global           (args)
+    static_assert(C2NumbersTuning::CORE_INDEX == (I::IS_FLEX_FLAG | kParamIndexNumbers), "bad index");
+    static_assert(C2NumbersTuning::PARAM_TYPE == (I::IS_FLEX_FLAG | kParamIndexNumbers | I::KIND_TUNING | I::DIR_GLOBAL), "bad index");
+    static_assert(sizeof(C2NumbersTuning) == 8, "bad size");
+
+    static_assert(offsetof(C2NumbersTuning, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2NumbersTuning, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2NumbersTuning, m.mNumbers) == 8, "bad offset");
+
+    // C2NumbersPortTuning:         kIndex | tun | port             (bool, args)
+    static_assert(sizeof(C2NumbersPortTuning) == 8, "bad size");
+    // C2NumbersPortTuning::input:  kIndex | tun | port | input     (args)
+    // C2NumbersPortTuning::output: kIndex | tun | port | output    (args)
+    static_assert(C2NumbersPortTuning::input::CORE_INDEX ==
+                  (I::IS_FLEX_FLAG | kParamIndexNumbers), "bad index");
+    static_assert(C2NumbersPortTuning::input::PARAM_TYPE ==
+                  (I::IS_FLEX_FLAG | kParamIndexNumbers | I::KIND_TUNING | I::DIR_INPUT), "bad index");
+    static_assert(C2NumbersPortTuning::output::CORE_INDEX ==
+                  (I::IS_FLEX_FLAG | kParamIndexNumbers), "bad index");
+    static_assert(C2NumbersPortTuning::output::PARAM_TYPE ==
+                  (I::IS_FLEX_FLAG | kParamIndexNumbers | I::KIND_TUNING | I::DIR_OUTPUT), "bad index");
+    static_assert(sizeof(C2NumbersPortTuning::input) == 8, "bad size");
+    static_assert(sizeof(C2NumbersPortTuning::output) == 8, "bad size");
+    static_assert(offsetof(C2NumbersPortTuning::input, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2NumbersPortTuning::input, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2NumbersPortTuning::input, m.mNumbers) == 8, "bad offset");
+    static_assert(offsetof(C2NumbersPortTuning::output, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2NumbersPortTuning::output, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2NumbersPortTuning::output, m.mNumbers) == 8, "bad offset");
+
+    // C2NumbersStreamTuning:       kIndex | tun | str              (bool, uint, args)
+    static_assert(sizeof(C2NumbersStreamTuning) == 8, "bad size");
+    // C2NumbersStreamTuning::input kIndex | tun | str | input      (int, args)
+    // C2NumbersStreamTuning::output kIx   | tun | str | output     (int, args)
+    static_assert(C2NumbersStreamTuning::input::CORE_INDEX ==
+                  (I::IS_FLEX_FLAG | kParamIndexNumbers), "bad index");
+    static_assert(C2NumbersStreamTuning::input::PARAM_TYPE ==
+                  (I::IS_FLEX_FLAG | kParamIndexNumbers | I::KIND_TUNING | I::DIR_INPUT | I::IS_STREAM_FLAG), "bad index");
+    static_assert(C2NumbersStreamTuning::output::CORE_INDEX ==
+                  (I::IS_FLEX_FLAG | kParamIndexNumbers), "bad index");
+    static_assert(C2NumbersStreamTuning::output::PARAM_TYPE ==
+                  (I::IS_FLEX_FLAG | kParamIndexNumbers | I::KIND_TUNING | I::DIR_OUTPUT | I::IS_STREAM_FLAG), "bad index");
+    static_assert(sizeof(C2NumbersStreamTuning::input) == 8, "bad size");
+    static_assert(sizeof(C2NumbersStreamTuning::output) == 8, "bad size");
+    static_assert(offsetof(C2NumbersStreamTuning::input, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2NumbersStreamTuning::input, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2NumbersStreamTuning::input, m.mNumbers) == 8, "bad offset");
+    static_assert(offsetof(C2NumbersStreamTuning::output, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2NumbersStreamTuning::output, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2NumbersStreamTuning::output, m.mNumbers) == 8, "bad offset");
+}
+
+template<bool, unsigned ...N>
+struct _print_as_warning { };
+
+template<unsigned ...N>
+struct _print_as_warning<true, N...> : std::true_type { };
+
+#define static_assert_equals(a, b, msg) \
+static_assert(_print_as_warning<(a) == (b), a, b>::value, msg)
+
+void _C2ParamInspector::StaticFlexFromBaseTest() {
+    enum { kParamIndexMy = 1203 };
+    typedef C2TestBaseFlexEndSizeStruct C2MyStruct;
+    typedef C2GlobalParam<C2Info, C2MyStruct, kParamIndexMy> C2MyInfo;
+    typedef   C2PortParam<C2Info, C2MyStruct, kParamIndexMy> C2MyPortInfo;
+    typedef C2StreamParam<C2Info, C2MyStruct, kParamIndexMy> C2MyStreamInfo;
+
+    typedef C2Param::Index I;
+
+    // C2MyStruct has no CORE_INDEX
+    //static_assert(C2MyStruct::CORE_INDEX == (I::IS_FLEX_FLAG | kParamIndexMy), "bad index");
+    static_assert(sizeof(C2MyStruct) == 4, "bad size");
+
+    // C2MyInfo:             kIndex | tun | global           (args)
+    static_assert_equals(C2MyInfo::CORE_INDEX, (I::IS_FLEX_FLAG | kParamIndexMy), "bad index");
+    static_assert_equals(C2MyInfo::PARAM_TYPE, (I::IS_FLEX_FLAG | kParamIndexMy | I::KIND_INFO | I::DIR_GLOBAL), "bad index");
+    static_assert(sizeof(C2MyInfo) == 12, "bad size");
+
+    static_assert(offsetof(C2MyInfo, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2MyInfo, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2MyInfo, m.signed32) == 8, "bad offset");
+
+    // C2MyPortInfo:         kIndex | tun | port             (bool, args)
+    static_assert(sizeof(C2MyPortInfo) == 12, "bad size");
+    // C2MyPortInfo::input:  kIndex | tun | port | input     (args)
+    // C2MyPortInfo::output: kIndex | tun | port | output    (args)
+    static_assert(C2MyPortInfo::input::CORE_INDEX ==
+                  (I::IS_FLEX_FLAG | kParamIndexMy), "bad index");
+    static_assert(C2MyPortInfo::input::PARAM_TYPE ==
+                  (I::IS_FLEX_FLAG | kParamIndexMy | I::KIND_INFO | I::DIR_INPUT), "bad index");
+    static_assert(C2MyPortInfo::output::CORE_INDEX ==
+                  (I::IS_FLEX_FLAG | kParamIndexMy), "bad index");
+    static_assert(C2MyPortInfo::output::PARAM_TYPE ==
+                  (I::IS_FLEX_FLAG | kParamIndexMy | I::KIND_INFO | I::DIR_OUTPUT), "bad index");
+    static_assert(sizeof(C2MyPortInfo::input) == 12, "bad size");
+    static_assert(sizeof(C2MyPortInfo::output) == 12, "bad size");
+    static_assert(offsetof(C2MyPortInfo::input, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2MyPortInfo::input, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2MyPortInfo::input, m.signed32) == 8, "bad offset");
+    static_assert(offsetof(C2MyPortInfo::output, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2MyPortInfo::output, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2MyPortInfo::output, m.signed32) == 8, "bad offset");
+
+    // C2MyStreamInfo:       kIndex | tun | str              (bool, uint, args)
+    static_assert(sizeof(C2MyStreamInfo) == 12, "bad size");
+    // C2MyStreamInfo::input kIndex | tun | str | input      (int, args)
+    // C2MyStreamInfo::output kIx   | tun | str | output     (int, args)
+    static_assert(C2MyStreamInfo::input::CORE_INDEX ==
+                  (I::IS_FLEX_FLAG | kParamIndexMy), "bad index");
+    static_assert(C2MyStreamInfo::input::PARAM_TYPE ==
+                  (I::IS_FLEX_FLAG | kParamIndexMy | I::KIND_INFO | I::DIR_INPUT | I::IS_STREAM_FLAG), "bad index");
+    static_assert(C2MyStreamInfo::output::CORE_INDEX ==
+                  (I::IS_FLEX_FLAG | kParamIndexMy), "bad index");
+    static_assert(C2MyStreamInfo::output::PARAM_TYPE ==
+                  (I::IS_FLEX_FLAG | kParamIndexMy | I::KIND_INFO | I::DIR_OUTPUT | I::IS_STREAM_FLAG), "bad index");
+    static_assert(sizeof(C2MyStreamInfo::input) == 12, "bad size");
+    static_assert(sizeof(C2MyStreamInfo::output) == 12, "bad size");
+    static_assert(offsetof(C2MyStreamInfo::input, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2MyStreamInfo::input, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2MyStreamInfo::input, m.signed32) == 8, "bad offset");
+    static_assert(offsetof(C2MyStreamInfo::output, _mSize) == 0, "bad size");
+    static_assert(offsetof(C2MyStreamInfo::output, _mIndex) == 4, "bad offset");
+    static_assert(offsetof(C2MyStreamInfo::output, m.signed32) == 8, "bad offset");
+}
+
+TEST_F(C2ParamTest, ParamOpsTest) {
+    const C2NumberStruct str(100);
+    C2NumberStruct bstr;
+
+    {
+        EXPECT_EQ(100, str.mNumber);
+        bstr.mNumber = 100;
+
+        C2Param::CoreIndex index = C2NumberStruct::CORE_INDEX;
+        EXPECT_FALSE(index.isVendor());
+        EXPECT_FALSE(index.isFlexible());
+        EXPECT_EQ(index.coreIndex(), kParamIndexNumber);
+        EXPECT_EQ(index.typeIndex(), kParamIndexNumber);
+    }
+
+    const C2NumberTuning tun(100);
+    C2NumberTuning btun;
+
+    {
+      C2NumberInfo inf(100);
+      std::unique_ptr<C2NumbersTuning> tun_ = C2NumbersTuning::AllocUnique(1);
+
+      EXPECT_EQ(tun.coreIndex(), inf.coreIndex());
+      EXPECT_NE(tun.coreIndex(), tun_->coreIndex());
+      EXPECT_NE(tun.type(), inf.type());
+      EXPECT_NE(tun.type(), tun_->type());
+    }
+
+    {
+        // flags & invariables
+        for (const auto &p : { tun, btun }) {
+            EXPECT_TRUE((bool)p);
+            EXPECT_FALSE(!p);
+            EXPECT_EQ(12u, p.size());
+
+            EXPECT_FALSE(p.isVendor());
+            EXPECT_FALSE(p.isFlexible());
+            EXPECT_TRUE(p.isGlobal());
+            EXPECT_FALSE(p.forInput());
+            EXPECT_FALSE(p.forOutput());
+            EXPECT_FALSE(p.forStream());
+            EXPECT_FALSE(p.forPort());
+        }
+
+        // value
+        EXPECT_EQ(100, tun.mNumber);
+        EXPECT_EQ(0, btun.mNumber);
+        EXPECT_FALSE(tun == btun);
+        EXPECT_FALSE(tun.operator==(btun));
+        EXPECT_TRUE(tun != btun);
+        EXPECT_TRUE(tun.operator!=(btun));
+        btun.mNumber = 100;
+        EXPECT_EQ(tun, btun);
+
+        // index
+        EXPECT_EQ(C2Param::Type(tun.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
+        EXPECT_EQ(C2Param::Type(tun.type()).typeIndex(), kParamIndexNumber);
+        EXPECT_EQ(tun.type(), C2NumberTuning::PARAM_TYPE);
+        EXPECT_EQ(tun.stream(), ~0u);
+
+        C2Param::CoreIndex index = C2NumberTuning::CORE_INDEX;
+        EXPECT_FALSE(index.isVendor());
+        EXPECT_FALSE(index.isFlexible());
+        EXPECT_EQ(index.coreIndex(), kParamIndexNumber);
+        EXPECT_EQ(index.typeIndex(), kParamIndexNumber);
+
+        C2Param::Type type = C2NumberTuning::PARAM_TYPE;
+        EXPECT_FALSE(type.isVendor());
+        EXPECT_FALSE(type.isFlexible());
+        EXPECT_TRUE(type.isGlobal());
+        EXPECT_FALSE(type.forInput());
+        EXPECT_FALSE(type.forOutput());
+        EXPECT_FALSE(type.forStream());
+        EXPECT_FALSE(type.forPort());
+
+        EXPECT_EQ(C2NumberTuning::From(nullptr), nullptr);
+        EXPECT_EQ(C2NumberTuning::From(&tun), &tun);
+        EXPECT_EQ(C2NumberPortTuning::From(&tun), nullptr);
+        EXPECT_EQ(C2NumberPortTuning::input::From(&tun), nullptr);
+        EXPECT_EQ(C2NumberPortTuning::output::From(&tun), nullptr);
+        EXPECT_EQ(C2NumberStreamTuning::From(&tun), nullptr);
+        EXPECT_EQ(C2NumberStreamTuning::input::From(&tun), nullptr);
+        EXPECT_EQ(C2NumberStreamTuning::output::From(&tun), nullptr);
+
+        EXPECT_EQ(*(C2Param::Copy(btun)), btun);
+        btun.invalidate();
+        EXPECT_FALSE(C2Param::Copy(btun));
+    }
+
+    const C2NumberPortTuning outp1(true, 100), inp1(false, 100);
+    C2NumberPortTuning boutp1, binp1, binp3(false, 100);
+    const C2NumberPortTuning::input inp2(100);
+    C2NumberPortTuning::input binp2;
+    const C2NumberPortTuning::output outp2(100);
+    C2NumberPortTuning::output boutp2;
+
+    EXPECT_EQ(inp1.coreIndex(), tun.coreIndex());
+    EXPECT_EQ(outp1.coreIndex(), tun.coreIndex());
+    EXPECT_EQ(binp1.coreIndex(), tun.coreIndex());
+    EXPECT_EQ(boutp1.coreIndex(), tun.coreIndex());
+    EXPECT_EQ(inp2.coreIndex(), tun.coreIndex());
+    EXPECT_EQ(outp2.coreIndex(), tun.coreIndex());
+
+    EXPECT_EQ(inp1.type(), inp2.type());
+    EXPECT_EQ(outp1.type(), outp2.type());
+    EXPECT_NE(inp1.type(), outp1.type());
+    EXPECT_NE(inp2.type(), outp2.type());
+    EXPECT_NE(inp1.type(), binp1.type());
+    EXPECT_NE(outp1.type(), boutp1.type());
+    EXPECT_NE(inp1.type(), tun.type());
+    EXPECT_NE(inp2.type(), tun.type());
+
+    {
+        static_assert(canCallSetPort(binp3), "should be able to");
+        static_assert(canCallSetPort(binp1), "should be able to");
+        static_assert(!canCallSetPort(inp1), "should not be able to (const)");
+        static_assert(!canCallSetPort(inp2), "should not be able to (const & type)");
+        static_assert(!canCallSetPort(binp2), "should not be able to (type)");
+
+        // flags & invariables
+        for (const auto &p : { outp1, inp1, boutp1 }) {
+            EXPECT_EQ(12u, p.size());
+            EXPECT_FALSE(p.isVendor());
+            EXPECT_FALSE(p.isFlexible());
+            EXPECT_FALSE(p.isGlobal());
+            EXPECT_FALSE(p.forStream());
+            EXPECT_TRUE(p.forPort());
+        }
+        for (const auto &p : { inp2, binp2 }) {
+            EXPECT_EQ(12u, p.size());
+            EXPECT_FALSE(p.isVendor());
+            EXPECT_FALSE(p.isFlexible());
+            EXPECT_FALSE(p.isGlobal());
+            EXPECT_FALSE(p.forStream());
+            EXPECT_TRUE(p.forPort());
+        }
+        for (const auto &p : { outp2, boutp2 }) {
+            EXPECT_EQ(12u, p.size());
+            EXPECT_FALSE(p.isVendor());
+            EXPECT_FALSE(p.isFlexible());
+            EXPECT_FALSE(p.isGlobal());
+            EXPECT_FALSE(p.forStream());
+            EXPECT_TRUE(p.forPort());
+        }
+
+        // port specific flags & invariables
+        EXPECT_FALSE(outp1.forInput());
+        EXPECT_TRUE(outp1.forOutput());
+
+        EXPECT_TRUE(inp1.forInput());
+        EXPECT_FALSE(inp1.forOutput());
+
+        for (const auto &p : { outp1, inp1 }) {
+            EXPECT_TRUE((bool)p);
+            EXPECT_FALSE(!p);
+            EXPECT_EQ(100, p.mNumber);
+        }
+        for (const auto &p : { outp2, boutp2 }) {
+            EXPECT_TRUE((bool)p);
+            EXPECT_FALSE(!p);
+
+            EXPECT_FALSE(p.forInput());
+            EXPECT_TRUE(p.forOutput());
+        }
+        for (const auto &p : { inp2, binp2 }) {
+            EXPECT_TRUE((bool)p);
+            EXPECT_FALSE(!p);
+
+            EXPECT_TRUE(p.forInput());
+            EXPECT_FALSE(p.forOutput());
+        }
+        for (const auto &p : { boutp1 } ) {
+            EXPECT_FALSE((bool)p);
+            EXPECT_TRUE(!p);
+
+            EXPECT_FALSE(p.forInput());
+            EXPECT_FALSE(p.forOutput());
+            EXPECT_EQ(0, p.mNumber);
+        }
+
+        // values
+        EXPECT_EQ(100, inp2.mNumber);
+        EXPECT_EQ(100, outp2.mNumber);
+        EXPECT_EQ(0, binp1.mNumber);
+        EXPECT_EQ(0, binp2.mNumber);
+        EXPECT_EQ(0, boutp1.mNumber);
+        EXPECT_EQ(0, boutp2.mNumber);
+
+        EXPECT_TRUE(inp1 != outp1);
+        EXPECT_TRUE(inp1 == inp2);
+        EXPECT_TRUE(outp1 == outp2);
+        EXPECT_TRUE(binp1 == boutp1);
+        EXPECT_TRUE(binp2 != boutp2);
+
+        EXPECT_TRUE(inp1 != binp1);
+        binp1.mNumber = 100;
+        EXPECT_TRUE(inp1 != binp1);
+        binp1.setPort(false /* output */);
+        EXPECT_TRUE((bool)binp1);
+        EXPECT_FALSE(!binp1);
+        EXPECT_TRUE(inp1 == binp1);
+
+        EXPECT_TRUE(inp2 != binp2);
+        binp2.mNumber = 100;
+        EXPECT_TRUE(inp2 == binp2);
+
+        binp1.setPort(true /* output */);
+        EXPECT_TRUE(outp1 == binp1);
+
+        EXPECT_TRUE(outp1 != boutp1);
+        boutp1.mNumber = 100;
+        EXPECT_TRUE(outp1 != boutp1);
+        boutp1.setPort(true /* output */);
+        EXPECT_TRUE((bool)boutp1);
+        EXPECT_FALSE(!boutp1);
+        EXPECT_TRUE(outp1 == boutp1);
+
+        EXPECT_TRUE(outp2 != boutp2);
+        boutp2.mNumber = 100;
+        EXPECT_TRUE(outp2 == boutp2);
+
+        boutp1.setPort(false /* output */);
+        EXPECT_TRUE(inp1 == boutp1);
+
+        // index
+        EXPECT_EQ(C2Param::Type(inp1.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
+        EXPECT_EQ(C2Param::Type(inp1.type()).typeIndex(), kParamIndexNumber);
+        EXPECT_EQ(inp1.type(), C2NumberPortTuning::input::PARAM_TYPE);
+        EXPECT_EQ(inp1.stream(), ~0u);
+
+        EXPECT_EQ(C2Param::Type(inp2.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
+        EXPECT_EQ(C2Param::Type(inp2.type()).typeIndex(), kParamIndexNumber);
+        EXPECT_EQ(inp2.type(), C2NumberPortTuning::input::PARAM_TYPE);
+        EXPECT_EQ(inp2.stream(), ~0u);
+
+        EXPECT_EQ(C2Param::Type(outp1.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
+        EXPECT_EQ(C2Param::Type(outp1.type()).typeIndex(), kParamIndexNumber);
+        EXPECT_EQ(outp1.type(), C2NumberPortTuning::output::PARAM_TYPE);
+        EXPECT_EQ(outp1.stream(), ~0u);
+
+        EXPECT_EQ(C2Param::Type(outp2.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
+        EXPECT_EQ(C2Param::Type(outp2.type()).typeIndex(), kParamIndexNumber);
+        EXPECT_EQ(outp2.type(), C2NumberPortTuning::output::PARAM_TYPE);
+        EXPECT_EQ(outp2.stream(), ~0u);
+
+        C2Param::CoreIndex index = C2NumberPortTuning::input::PARAM_TYPE;
+        EXPECT_FALSE(index.isVendor());
+        EXPECT_FALSE(index.isFlexible());
+        EXPECT_EQ(index.coreIndex(), kParamIndexNumber);
+        EXPECT_EQ(index.typeIndex(), kParamIndexNumber);
+
+        index = C2NumberPortTuning::output::PARAM_TYPE;
+        EXPECT_FALSE(index.isVendor());
+        EXPECT_FALSE(index.isFlexible());
+        EXPECT_EQ(index.coreIndex(), kParamIndexNumber);
+        EXPECT_EQ(index.typeIndex(), kParamIndexNumber);
+
+        C2Param::Type type = C2NumberPortTuning::input::PARAM_TYPE;
+        EXPECT_FALSE(type.isVendor());
+        EXPECT_FALSE(type.isFlexible());
+        EXPECT_FALSE(type.isGlobal());
+        EXPECT_TRUE(type.forInput());
+        EXPECT_FALSE(type.forOutput());
+        EXPECT_FALSE(type.forStream());
+        EXPECT_TRUE(type.forPort());
+
+        type = C2NumberPortTuning::output::PARAM_TYPE;
+        EXPECT_FALSE(type.isVendor());
+        EXPECT_FALSE(type.isFlexible());
+        EXPECT_FALSE(type.isGlobal());
+        EXPECT_FALSE(type.forInput());
+        EXPECT_TRUE(type.forOutput());
+        EXPECT_FALSE(type.forStream());
+        EXPECT_TRUE(type.forPort());
+
+        EXPECT_EQ(C2NumberPortTuning::From(nullptr), nullptr);
+        EXPECT_EQ(C2NumberPortTuning::input::From(nullptr), nullptr);
+        EXPECT_EQ(C2NumberPortTuning::output::From(nullptr), nullptr);
+        EXPECT_EQ(C2NumberTuning::From(&inp1), nullptr);
+        EXPECT_EQ(C2NumberTuning::From(&inp2), nullptr);
+        EXPECT_EQ(C2NumberTuning::From(&outp1), nullptr);
+        EXPECT_EQ(C2NumberTuning::From(&outp2), nullptr);
+        EXPECT_EQ(C2NumberPortTuning::From(&inp1), &inp1);
+        EXPECT_EQ(C2NumberPortTuning::From(&inp2), (C2NumberPortTuning*)&inp2);
+        EXPECT_EQ(C2NumberPortTuning::From(&outp1), &outp1);
+        EXPECT_EQ(C2NumberPortTuning::From(&outp2), (C2NumberPortTuning*)&outp2);
+        EXPECT_EQ(C2NumberPortTuning::input::From(&inp1), (C2NumberPortTuning::input*)&inp1);
+        EXPECT_EQ(C2NumberPortTuning::input::From(&inp2), &inp2);
+        EXPECT_EQ(C2NumberPortTuning::input::From(&outp1), nullptr);
+        EXPECT_EQ(C2NumberPortTuning::input::From(&outp2), nullptr);
+        EXPECT_EQ(C2NumberPortTuning::output::From(&inp1), nullptr);
+        EXPECT_EQ(C2NumberPortTuning::output::From(&inp2), nullptr);
+        EXPECT_EQ(C2NumberPortTuning::output::From(&outp1), (C2NumberPortTuning::output*)&outp1);
+        EXPECT_EQ(C2NumberPortTuning::output::From(&outp2), &outp2);
+        EXPECT_EQ(C2NumberStreamTuning::From(&inp1), nullptr);
+        EXPECT_EQ(C2NumberStreamTuning::From(&inp2), nullptr);
+        EXPECT_EQ(C2NumberStreamTuning::From(&outp1), nullptr);
+        EXPECT_EQ(C2NumberStreamTuning::From(&outp2), nullptr);
+        EXPECT_EQ(C2NumberStreamTuning::input::From(&inp1), nullptr);
+        EXPECT_EQ(C2NumberStreamTuning::input::From(&inp2), nullptr);
+        EXPECT_EQ(C2NumberStreamTuning::input::From(&outp1), nullptr);
+        EXPECT_EQ(C2NumberStreamTuning::input::From(&outp2), nullptr);
+        EXPECT_EQ(C2NumberStreamTuning::output::From(&inp1), nullptr);
+        EXPECT_EQ(C2NumberStreamTuning::output::From(&inp2), nullptr);
+        EXPECT_EQ(C2NumberStreamTuning::output::From(&outp1), nullptr);
+        EXPECT_EQ(C2NumberStreamTuning::output::From(&outp2), nullptr);
+
+        EXPECT_EQ(*(C2Param::Copy(inp1)), inp1);
+        EXPECT_EQ(*(C2Param::Copy(inp2)), inp2);
+        EXPECT_EQ(*(C2Param::Copy(outp1)), outp1);
+        EXPECT_EQ(*(C2Param::Copy(outp2)), outp2);
+    }
+
+    const C2NumberStreamTuning outs1(true, 1u, 100), ins1(false, 1u, 100);
+    C2NumberStreamTuning bouts1, bins1, bins3(false, 1u, 100);
+    const C2NumberStreamTuning::input ins2(1u, 100);
+    C2NumberStreamTuning::input bins2;
+    const C2NumberStreamTuning::output outs2(1u, 100);
+    C2NumberStreamTuning::output bouts2;
+
+    EXPECT_EQ(ins1.coreIndex(), tun.coreIndex());
+    EXPECT_EQ(outs1.coreIndex(), tun.coreIndex());
+    EXPECT_EQ(bins1.coreIndex(), tun.coreIndex());
+    EXPECT_EQ(bouts1.coreIndex(), tun.coreIndex());
+    EXPECT_EQ(ins2.coreIndex(), tun.coreIndex());
+    EXPECT_EQ(outs2.coreIndex(), tun.coreIndex());
+
+    EXPECT_EQ(ins1.type(), ins2.type());
+    EXPECT_EQ(ins1.type(), bins2.type());
+    EXPECT_EQ(outs1.type(), outs2.type());
+    EXPECT_EQ(outs1.type(), bouts2.type());
+    EXPECT_NE(ins1.type(), outs1.type());
+    EXPECT_NE(ins2.type(), outs2.type());
+    EXPECT_NE(ins1.type(), bins1.type());
+    EXPECT_NE(outs1.type(), bouts1.type());
+    EXPECT_NE(ins1.type(), tun.type());
+    EXPECT_NE(ins2.type(), tun.type());
+
+    {
+        static_assert(canCallSetPort(bins3), "should be able to");
+        static_assert(canCallSetPort(bins1), "should be able to");
+        static_assert(!canCallSetPort(ins1), "should not be able to (const)");
+        static_assert(!canCallSetPort(ins2), "should not be able to (const & type)");
+        static_assert(!canCallSetPort(bins2), "should not be able to (type)");
+
+        // flags & invariables
+        for (const auto &p : { outs1, ins1, bouts1 }) {
+            EXPECT_EQ(12u, p.size());
+            EXPECT_FALSE(p.isVendor());
+            EXPECT_FALSE(p.isFlexible());
+            EXPECT_FALSE(p.isGlobal());
+            EXPECT_TRUE(p.forStream());
+            EXPECT_FALSE(p.forPort());
+        }
+        for (const auto &p : { ins2, bins2 }) {
+            EXPECT_EQ(12u, p.size());
+            EXPECT_FALSE(p.isVendor());
+            EXPECT_FALSE(p.isFlexible());
+            EXPECT_FALSE(p.isGlobal());
+            EXPECT_TRUE(p.forStream());
+            EXPECT_FALSE(p.forPort());
+        }
+        for (const auto &p : { outs2, bouts2 }) {
+            EXPECT_EQ(12u, p.size());
+            EXPECT_FALSE(p.isVendor());
+            EXPECT_FALSE(p.isFlexible());
+            EXPECT_FALSE(p.isGlobal());
+            EXPECT_TRUE(p.forStream());
+            EXPECT_FALSE(p.forPort());
+        }
+
+        // port specific flags & invariables
+        EXPECT_FALSE(outs1.forInput());
+        EXPECT_TRUE(outs1.forOutput());
+
+        EXPECT_TRUE(ins1.forInput());
+        EXPECT_FALSE(ins1.forOutput());
+
+        for (const auto &p : { outs1, ins1 }) {
+            EXPECT_TRUE((bool)p);
+            EXPECT_FALSE(!p);
+            EXPECT_EQ(100, p.mNumber);
+            EXPECT_EQ(1u, p.stream());
+        }
+        for (const auto &p : { outs2, bouts2 }) {
+            EXPECT_TRUE((bool)p);
+            EXPECT_FALSE(!p);
+
+            EXPECT_FALSE(p.forInput());
+            EXPECT_TRUE(p.forOutput());
+        }
+        for (const auto &p : { ins2, bins2 }) {
+            EXPECT_TRUE((bool)p);
+            EXPECT_FALSE(!p);
+
+            EXPECT_TRUE(p.forInput());
+            EXPECT_FALSE(p.forOutput());
+        }
+        for (const auto &p : { bouts1 } ) {
+            EXPECT_FALSE((bool)p);
+            EXPECT_TRUE(!p);
+
+            EXPECT_FALSE(p.forInput());
+            EXPECT_FALSE(p.forOutput());
+            EXPECT_EQ(0, p.mNumber);
+        }
+
+        // values
+        EXPECT_EQ(100, ins2.mNumber);
+        EXPECT_EQ(100, outs2.mNumber);
+        EXPECT_EQ(0, bins1.mNumber);
+        EXPECT_EQ(0, bins2.mNumber);
+        EXPECT_EQ(0, bouts1.mNumber);
+        EXPECT_EQ(0, bouts2.mNumber);
+
+        EXPECT_EQ(1u, ins2.stream());
+        EXPECT_EQ(1u, outs2.stream());
+        EXPECT_EQ(0u, bins1.stream());
+        EXPECT_EQ(0u, bins2.stream());
+        EXPECT_EQ(0u, bouts1.stream());
+        EXPECT_EQ(0u, bouts2.stream());
+
+        EXPECT_TRUE(ins1 != outs1);
+        EXPECT_TRUE(ins1 == ins2);
+        EXPECT_TRUE(outs1 == outs2);
+        EXPECT_TRUE(bins1 == bouts1);
+        EXPECT_TRUE(bins2 != bouts2);
+
+        EXPECT_TRUE(ins1 != bins1);
+        bins1.mNumber = 100;
+        EXPECT_TRUE(ins1 != bins1);
+        bins1.setPort(false /* output */);
+        EXPECT_TRUE(ins1 != bins1);
+        bins1.setStream(1u);
+        EXPECT_TRUE(ins1 == bins1);
+
+        EXPECT_TRUE(ins2 != bins2);
+        bins2.mNumber = 100;
+        EXPECT_TRUE(ins2 != bins2);
+        bins2.setStream(1u);
+        EXPECT_TRUE(ins2 == bins2);
+
+        bins1.setPort(true /* output */);
+        EXPECT_TRUE(outs1 == bins1);
+
+        EXPECT_TRUE(outs1 != bouts1);
+        bouts1.mNumber = 100;
+        EXPECT_TRUE(outs1 != bouts1);
+        bouts1.setPort(true /* output */);
+        EXPECT_TRUE(outs1 != bouts1);
+        bouts1.setStream(1u);
+        EXPECT_TRUE(outs1 == bouts1);
+
+        EXPECT_TRUE(outs2 != bouts2);
+        bouts2.mNumber = 100;
+        EXPECT_TRUE(outs2 != bouts2);
+        bouts2.setStream(1u);
+        EXPECT_TRUE(outs2 == bouts2);
+
+        bouts1.setPort(false /* output */);
+        EXPECT_TRUE(ins1 == bouts1);
+
+        // index
+        EXPECT_EQ(C2Param::Type(ins1.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
+        EXPECT_EQ(C2Param::Type(ins1.type()).typeIndex(), kParamIndexNumber);
+        EXPECT_EQ(ins1.type(), C2NumberStreamTuning::input::PARAM_TYPE);
+
+        EXPECT_EQ(C2Param::Type(ins2.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
+        EXPECT_EQ(C2Param::Type(ins2.type()).typeIndex(), kParamIndexNumber);
+        EXPECT_EQ(ins2.type(), C2NumberStreamTuning::input::PARAM_TYPE);
+
+        EXPECT_EQ(C2Param::Type(outs1.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
+        EXPECT_EQ(C2Param::Type(outs1.type()).typeIndex(), kParamIndexNumber);
+        EXPECT_EQ(outs1.type(), C2NumberStreamTuning::output::PARAM_TYPE);
+
+        EXPECT_EQ(C2Param::Type(outs2.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
+        EXPECT_EQ(C2Param::Type(outs2.type()).typeIndex(), kParamIndexNumber);
+        EXPECT_EQ(outs2.type(), C2NumberStreamTuning::output::PARAM_TYPE);
+
+        C2Param::CoreIndex index = C2NumberStreamTuning::input::PARAM_TYPE;
+        EXPECT_FALSE(index.isVendor());
+        EXPECT_FALSE(index.isFlexible());
+        EXPECT_EQ(index.coreIndex(), kParamIndexNumber);
+        EXPECT_EQ(index.typeIndex(), kParamIndexNumber);
+
+        index = C2NumberStreamTuning::output::PARAM_TYPE;
+        EXPECT_FALSE(index.isVendor());
+        EXPECT_FALSE(index.isFlexible());
+        EXPECT_EQ(index.coreIndex(), kParamIndexNumber);
+        EXPECT_EQ(index.typeIndex(), kParamIndexNumber);
+
+        C2Param::Type type = C2NumberStreamTuning::input::PARAM_TYPE;
+        EXPECT_FALSE(type.isVendor());
+        EXPECT_FALSE(type.isFlexible());
+        EXPECT_FALSE(type.isGlobal());
+        EXPECT_TRUE(type.forInput());
+        EXPECT_FALSE(type.forOutput());
+        EXPECT_TRUE(type.forStream());
+        EXPECT_FALSE(type.forPort());
+
+        type = C2NumberStreamTuning::output::PARAM_TYPE;
+        EXPECT_FALSE(type.isVendor());
+        EXPECT_FALSE(type.isFlexible());
+        EXPECT_FALSE(type.isGlobal());
+        EXPECT_FALSE(type.forInput());
+        EXPECT_TRUE(type.forOutput());
+        EXPECT_TRUE(type.forStream());
+        EXPECT_FALSE(type.forPort());
+
+        EXPECT_EQ(C2NumberPortTuning::From(nullptr), nullptr);
+        EXPECT_EQ(C2NumberPortTuning::input::From(nullptr), nullptr);
+        EXPECT_EQ(C2NumberPortTuning::output::From(nullptr), nullptr);
+        EXPECT_EQ(C2NumberTuning::From(&ins1), nullptr);
+        EXPECT_EQ(C2NumberTuning::From(&ins2), nullptr);
+        EXPECT_EQ(C2NumberTuning::From(&outs1), nullptr);
+        EXPECT_EQ(C2NumberTuning::From(&outs2), nullptr);
+        EXPECT_EQ(C2NumberPortTuning::From(&ins1), nullptr);
+        EXPECT_EQ(C2NumberPortTuning::From(&ins2), nullptr);
+        EXPECT_EQ(C2NumberPortTuning::From(&outs1), nullptr);
+        EXPECT_EQ(C2NumberPortTuning::From(&outs2), nullptr);
+        EXPECT_EQ(C2NumberPortTuning::input::From(&ins1), nullptr);
+        EXPECT_EQ(C2NumberPortTuning::input::From(&ins2), nullptr);
+        EXPECT_EQ(C2NumberPortTuning::input::From(&outs1), nullptr);
+        EXPECT_EQ(C2NumberPortTuning::input::From(&outs2), nullptr);
+        EXPECT_EQ(C2NumberPortTuning::output::From(&ins1), nullptr);
+        EXPECT_EQ(C2NumberPortTuning::output::From(&ins2), nullptr);
+        EXPECT_EQ(C2NumberPortTuning::output::From(&outs1), nullptr);
+        EXPECT_EQ(C2NumberPortTuning::output::From(&outs2), nullptr);
+        EXPECT_EQ(C2NumberStreamTuning::From(&ins1), &ins1);
+        EXPECT_EQ(C2NumberStreamTuning::From(&ins2), (C2NumberStreamTuning*)&ins2);
+        EXPECT_EQ(C2NumberStreamTuning::From(&outs1), &outs1);
+        EXPECT_EQ(C2NumberStreamTuning::From(&outs2), (C2NumberStreamTuning*)&outs2);
+        EXPECT_EQ(C2NumberStreamTuning::input::From(&ins1), (C2NumberStreamTuning::input*)&ins1);
+        EXPECT_EQ(C2NumberStreamTuning::input::From(&ins2), &ins2);
+        EXPECT_EQ(C2NumberStreamTuning::input::From(&outs1), nullptr);
+        EXPECT_EQ(C2NumberStreamTuning::input::From(&outs2), nullptr);
+        EXPECT_EQ(C2NumberStreamTuning::output::From(&ins1), nullptr);
+        EXPECT_EQ(C2NumberStreamTuning::output::From(&ins2), nullptr);
+        EXPECT_EQ(C2NumberStreamTuning::output::From(&outs1), (C2NumberStreamTuning::output*)&outs1);
+        EXPECT_EQ(C2NumberStreamTuning::output::From(&outs2), &outs2);
+
+        EXPECT_EQ(*(C2Param::Copy(ins1)), ins1);
+        EXPECT_EQ(*(C2Param::Copy(ins2)), ins2);
+        EXPECT_EQ(*(C2Param::Copy(outs1)), outs1);
+        EXPECT_EQ(*(C2Param::Copy(outs2)), outs2);
+    }
+
+    {
+        uint32_t videoWidth[] = { 12u, C2NumberStreamTuning::output::PARAM_TYPE, 100 };
+        C2Param *p1 = C2Param::From(videoWidth, sizeof(videoWidth));
+        EXPECT_NE(p1, nullptr);
+        EXPECT_EQ(12u, p1->size());
+        EXPECT_EQ(p1->type(), C2NumberStreamTuning::output::PARAM_TYPE);
+
+        p1 = C2Param::From(videoWidth, sizeof(videoWidth) + 2);
+        EXPECT_EQ(p1, nullptr);
+
+        p1 = C2Param::From(videoWidth, sizeof(videoWidth) - 2);
+        EXPECT_EQ(p1, nullptr);
+
+        p1 = C2Param::From(videoWidth, 3);
+        EXPECT_EQ(p1, nullptr);
+
+        p1 = C2Param::From(videoWidth, 0);
+        EXPECT_EQ(p1, nullptr);
+    }
+}
+
+void StaticTestAddCoreIndex() {
+    struct nobase {};
+    struct base { enum : uint32_t { CORE_INDEX = 1 }; };
+    static_assert(_C2AddCoreIndex<nobase, 2>::CORE_INDEX == 2, "should be 2");
+    static_assert(_C2AddCoreIndex<base, 1>::CORE_INDEX == 1, "should be 1");
+}
+
+class TestFlexHelper {
+    struct _Flex {
+        int32_t a;
+        char b[];
+        _Flex() {}
+        FLEX(_Flex, b);
+    };
+
+    struct _BoFlex {
+        _Flex a;
+        _BoFlex() {}
+        FLEX(_BoFlex, a);
+    };
+
+    struct _NonFlex {
+    };
+
+
+    static void StaticTest() {
+        static_assert(std::is_same<_C2FlexHelper<char>::FlexType, void>::value, "should be void");
+        static_assert(std::is_same<_C2FlexHelper<char[]>::FlexType, char>::value, "should be char");
+        static_assert(std::is_same<_C2FlexHelper<_Flex>::FlexType, char>::value, "should be char");
+
+        static_assert(std::is_same<_C2FlexHelper<_BoFlex>::FlexType, char>::value, "should be void");
+
+        static_assert(_C2Flexible<_Flex>::value, "should be flexible");
+        static_assert(!_C2Flexible<_NonFlex>::value, "should not be flexible");
+    }
+};
+
+TEST_F(C2ParamTest, FlexParamOpsTest) {
+//    const C2NumbersStruct str{100};
+    C2NumbersStruct bstr;
+    {
+//        EXPECT_EQ(100, str->m.mNumbers[0]);
+        (void)&bstr.mNumbers[0];
+
+        C2Param::CoreIndex index = C2NumbersStruct::CORE_INDEX;
+        EXPECT_FALSE(index.isVendor());
+        EXPECT_TRUE(index.isFlexible());
+        EXPECT_EQ(index.coreIndex(), kParamIndexNumbers | C2Param::CoreIndex::IS_FLEX_FLAG);
+        EXPECT_EQ(index.typeIndex(), kParamIndexNumbers);
+    }
+
+    std::unique_ptr<C2NumbersTuning> tun_ = C2NumbersTuning::AllocUnique(1);
+    tun_->m.mNumbers[0] = 100;
+    std::unique_ptr<const C2NumbersTuning> tun = std::move(tun_);
+    std::shared_ptr<C2NumbersTuning> btun = C2NumbersTuning::AllocShared(1);
+
+    {
+        // flags & invariables
+        const C2NumbersTuning *T[] = { tun.get(), btun.get() };
+        for (const auto p : T) {
+            EXPECT_TRUE((bool)(*p));
+            EXPECT_FALSE(!(*p));
+            EXPECT_EQ(12u, p->size());
+
+            EXPECT_FALSE(p->isVendor());
+            EXPECT_TRUE(p->isFlexible());
+            EXPECT_TRUE(p->isGlobal());
+            EXPECT_FALSE(p->forInput());
+            EXPECT_FALSE(p->forOutput());
+            EXPECT_FALSE(p->forStream());
+            EXPECT_FALSE(p->forPort());
+        }
+
+        // value
+        EXPECT_EQ(100, tun->m.mNumbers[0]);
+        EXPECT_EQ(0, btun->m.mNumbers[0]);
+        EXPECT_FALSE(*tun == *btun);
+        EXPECT_FALSE(tun->operator==(*btun));
+        EXPECT_TRUE(*tun != *btun);
+        EXPECT_TRUE(tun->operator!=(*btun));
+        btun->m.mNumbers[0] = 100;
+        EXPECT_EQ(*tun, *btun);
+
+        // index
+        EXPECT_EQ(C2Param::Type(tun->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
+        EXPECT_EQ(C2Param::Type(tun->type()).typeIndex(), kParamIndexNumbers);
+        EXPECT_EQ(tun->type(), C2NumbersTuning::PARAM_TYPE);
+        EXPECT_EQ(tun->stream(), ~0u);
+
+        C2Param::CoreIndex index = C2NumbersTuning::CORE_INDEX;
+        EXPECT_FALSE(index.isVendor());
+        EXPECT_TRUE(index.isFlexible());
+        EXPECT_EQ(index.coreIndex(), kParamIndexNumbers | C2Param::CoreIndex::IS_FLEX_FLAG);
+        EXPECT_EQ(index.typeIndex(), kParamIndexNumbers);
+
+        C2Param::Type type = C2NumbersTuning::PARAM_TYPE;
+        EXPECT_FALSE(type.isVendor());
+        EXPECT_TRUE(type.isFlexible());
+        EXPECT_TRUE(type.isGlobal());
+        EXPECT_FALSE(type.forInput());
+        EXPECT_FALSE(type.forOutput());
+        EXPECT_FALSE(type.forStream());
+        EXPECT_FALSE(type.forPort());
+
+        EXPECT_EQ(C2NumbersTuning::From(nullptr), nullptr);
+        EXPECT_EQ(C2NumbersTuning::From(tun.get()), tun.get());
+        EXPECT_EQ(C2NumbersPortTuning::From(tun.get()), nullptr);
+        EXPECT_EQ(C2NumbersPortTuning::input::From(tun.get()), nullptr);
+        EXPECT_EQ(C2NumbersPortTuning::output::From(tun.get()), nullptr);
+        EXPECT_EQ(C2NumbersStreamTuning::From(tun.get()), nullptr);
+        EXPECT_EQ(C2NumbersStreamTuning::input::From(tun.get()), nullptr);
+        EXPECT_EQ(C2NumbersStreamTuning::output::From(tun.get()), nullptr);
+
+        EXPECT_EQ(*(C2Param::Copy(*tun)), *tun);
+    }
+
+    std::unique_ptr<C2NumbersPortTuning> outp1_(C2NumbersPortTuning::AllocUnique(1, true)),
+            inp1_ = C2NumbersPortTuning::AllocUnique(1, false);
+    outp1_->m.mNumbers[0] = 100;
+    inp1_->m.mNumbers[0] = 100;
+    std::unique_ptr<const C2NumbersPortTuning> outp1 = std::move(outp1_);
+    std::unique_ptr<const C2NumbersPortTuning> inp1 = std::move(inp1_);
+    std::shared_ptr<C2NumbersPortTuning> boutp1(C2NumbersPortTuning::AllocShared(1)),
+            binp1 = C2NumbersPortTuning::AllocShared(1),
+            binp3 = C2NumbersPortTuning::AllocShared(1, false);
+    binp3->m.mNumbers[0] = 100;
+    std::unique_ptr<C2NumbersPortTuning::input> inp2_(C2NumbersPortTuning::input::AllocUnique(1));
+    inp2_->m.mNumbers[0] = 100;
+    std::unique_ptr<const C2NumbersPortTuning::input> inp2 = std::move(inp2_);
+    std::shared_ptr<C2NumbersPortTuning::input> binp2(C2NumbersPortTuning::input::AllocShared(1));
+    std::unique_ptr<C2NumbersPortTuning::output> outp2_(C2NumbersPortTuning::output::AllocUnique(1));
+    outp2_->m.mNumbers[0] = 100;
+    std::unique_ptr<const C2NumbersPortTuning::output> outp2 = std::move(outp2_);
+    std::shared_ptr<C2NumbersPortTuning::output> boutp2(C2NumbersPortTuning::output::AllocShared(1));
+
+    {
+        static_assert(canCallSetPort(*binp3), "should be able to");
+        static_assert(canCallSetPort(*binp1), "should be able to");
+        static_assert(!canCallSetPort(*inp1), "should not be able to (const)");
+        static_assert(!canCallSetPort(*inp2), "should not be able to (const & type)");
+        static_assert(!canCallSetPort(*binp2), "should not be able to (type)");
+
+        // flags & invariables
+        const C2NumbersPortTuning *P[] = { outp1.get(), inp1.get(), boutp1.get() };
+        for (const auto p : P) {
+            EXPECT_EQ(12u, p->size());
+            EXPECT_FALSE(p->isVendor());
+            EXPECT_TRUE(p->isFlexible());
+            EXPECT_FALSE(p->isGlobal());
+            EXPECT_FALSE(p->forStream());
+            EXPECT_TRUE(p->forPort());
+        }
+        const C2NumbersPortTuning::input *PI[] = { inp2.get(), binp2.get() };
+        for (const auto p : PI) {
+            EXPECT_EQ(12u, p->size());
+            EXPECT_FALSE(p->isVendor());
+            EXPECT_TRUE(p->isFlexible());
+            EXPECT_FALSE(p->isGlobal());
+            EXPECT_FALSE(p->forStream());
+            EXPECT_TRUE(p->forPort());
+        }
+        const C2NumbersPortTuning::output *PO[] = { outp2.get(), boutp2.get() };
+        for (const auto p : PO) {
+            EXPECT_EQ(12u, p->size());
+            EXPECT_FALSE(p->isVendor());
+            EXPECT_TRUE(p->isFlexible());
+            EXPECT_FALSE(p->isGlobal());
+            EXPECT_FALSE(p->forStream());
+            EXPECT_TRUE(p->forPort());
+        }
+
+        // port specific flags & invariables
+        EXPECT_FALSE(outp1->forInput());
+        EXPECT_TRUE(outp1->forOutput());
+
+        EXPECT_TRUE(inp1->forInput());
+        EXPECT_FALSE(inp1->forOutput());
+
+        const C2NumbersPortTuning *P2[] = { outp1.get(), inp1.get() };
+        for (const auto p : P2) {
+            EXPECT_TRUE((bool)(*p));
+            EXPECT_FALSE(!(*p));
+            EXPECT_EQ(100, p->m.mNumbers[0]);
+        }
+        for (const auto p : PO) {
+            EXPECT_TRUE((bool)(*p));
+            EXPECT_FALSE(!(*p));
+
+            EXPECT_FALSE(p->forInput());
+            EXPECT_TRUE(p->forOutput());
+        }
+        for (const auto p : PI) {
+            EXPECT_TRUE((bool)(*p));
+            EXPECT_FALSE(!(*p));
+
+            EXPECT_TRUE(p->forInput());
+            EXPECT_FALSE(p->forOutput());
+        }
+        const C2NumbersPortTuning *P3[] = { boutp1.get() };
+        for (const auto p : P3) {
+            EXPECT_FALSE((bool)(*p));
+            EXPECT_TRUE(!(*p));
+
+            EXPECT_FALSE(p->forInput());
+            EXPECT_FALSE(p->forOutput());
+            EXPECT_EQ(0, p->m.mNumbers[0]);
+        }
+
+        // values
+        EXPECT_EQ(100, inp2->m.mNumbers[0]);
+        EXPECT_EQ(100, outp2->m.mNumbers[0]);
+        EXPECT_EQ(0, binp1->m.mNumbers[0]);
+        EXPECT_EQ(0, binp2->m.mNumbers[0]);
+        EXPECT_EQ(0, boutp1->m.mNumbers[0]);
+        EXPECT_EQ(0, boutp2->m.mNumbers[0]);
+
+        EXPECT_TRUE(*inp1 != *outp1);
+        EXPECT_TRUE(*inp1 == *inp2);
+        EXPECT_TRUE(*outp1 == *outp2);
+        EXPECT_TRUE(*binp1 == *boutp1);
+        EXPECT_TRUE(*binp2 != *boutp2);
+
+        EXPECT_TRUE(*inp1 != *binp1);
+        binp1->m.mNumbers[0] = 100;
+        EXPECT_TRUE(*inp1 != *binp1);
+        binp1->setPort(false /* output */);
+        EXPECT_TRUE((bool)*binp1);
+        EXPECT_FALSE(!*binp1);
+        EXPECT_TRUE(*inp1 == *binp1);
+
+        EXPECT_TRUE(*inp2 != *binp2);
+        binp2->m.mNumbers[0] = 100;
+        EXPECT_TRUE(*inp2 == *binp2);
+
+        binp1->setPort(true /* output */);
+        EXPECT_TRUE(*outp1 == *binp1);
+
+        EXPECT_TRUE(*outp1 != *boutp1);
+        boutp1->m.mNumbers[0] = 100;
+        EXPECT_TRUE(*outp1 != *boutp1);
+        boutp1->setPort(true /* output */);
+        EXPECT_TRUE((bool)*boutp1);
+        EXPECT_FALSE(!*boutp1);
+        EXPECT_TRUE(*outp1 == *boutp1);
+
+        EXPECT_TRUE(*outp2 != *boutp2);
+        boutp2->m.mNumbers[0] = 100;
+        EXPECT_TRUE(*outp2 == *boutp2);
+
+        boutp1->setPort(false /* output */);
+        EXPECT_TRUE(*inp1 == *boutp1);
+
+        // index
+        EXPECT_EQ(C2Param::Type(inp1->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
+        EXPECT_EQ(C2Param::Type(inp1->type()).typeIndex(), kParamIndexNumbers);
+        EXPECT_EQ(inp1->type(), C2NumbersPortTuning::input::PARAM_TYPE);
+        EXPECT_EQ(inp1->stream(), ~0u);
+
+        EXPECT_EQ(C2Param::Type(inp2->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
+        EXPECT_EQ(C2Param::Type(inp2->type()).typeIndex(), kParamIndexNumbers);
+        EXPECT_EQ(inp2->type(), C2NumbersPortTuning::input::PARAM_TYPE);
+        EXPECT_EQ(inp2->stream(), ~0u);
+
+        EXPECT_EQ(C2Param::Type(outp1->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
+        EXPECT_EQ(C2Param::Type(outp1->type()).typeIndex(), kParamIndexNumbers);
+        EXPECT_EQ(outp1->type(), C2NumbersPortTuning::output::PARAM_TYPE);
+        EXPECT_EQ(outp1->stream(), ~0u);
+
+        EXPECT_EQ(C2Param::Type(outp2->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
+        EXPECT_EQ(C2Param::Type(outp2->type()).typeIndex(), kParamIndexNumbers);
+        EXPECT_EQ(outp2->type(), C2NumbersPortTuning::output::PARAM_TYPE);
+        EXPECT_EQ(outp2->stream(), ~0u);
+
+        C2Param::CoreIndex index = C2NumbersPortTuning::input::PARAM_TYPE;
+        EXPECT_FALSE(index.isVendor());
+        EXPECT_TRUE(index.isFlexible());
+        EXPECT_EQ(index.coreIndex(), kParamIndexNumbers | C2Param::CoreIndex::IS_FLEX_FLAG);
+        EXPECT_EQ(index.typeIndex(), kParamIndexNumbers);
+
+        index = C2NumbersPortTuning::output::PARAM_TYPE;
+        EXPECT_FALSE(index.isVendor());
+        EXPECT_TRUE(index.isFlexible());
+        EXPECT_EQ(index.coreIndex(), kParamIndexNumbers | C2Param::CoreIndex::IS_FLEX_FLAG);
+        EXPECT_EQ(index.typeIndex(), kParamIndexNumbers);
+
+        C2Param::Type type = C2NumbersPortTuning::input::PARAM_TYPE;
+        EXPECT_FALSE(type.isVendor());
+        EXPECT_TRUE(type.isFlexible());
+        EXPECT_FALSE(type.isGlobal());
+        EXPECT_TRUE(type.forInput());
+        EXPECT_FALSE(type.forOutput());
+        EXPECT_FALSE(type.forStream());
+        EXPECT_TRUE(type.forPort());
+
+        type = C2NumbersPortTuning::output::PARAM_TYPE;
+        EXPECT_FALSE(type.isVendor());
+        EXPECT_TRUE(type.isFlexible());
+        EXPECT_FALSE(type.isGlobal());
+        EXPECT_FALSE(type.forInput());
+        EXPECT_TRUE(type.forOutput());
+        EXPECT_FALSE(type.forStream());
+        EXPECT_TRUE(type.forPort());
+
+        EXPECT_EQ(C2NumbersPortTuning::From(nullptr), nullptr);
+        EXPECT_EQ(C2NumbersPortTuning::input::From(nullptr), nullptr);
+        EXPECT_EQ(C2NumbersPortTuning::output::From(nullptr), nullptr);
+        EXPECT_EQ(C2NumbersTuning::From(inp1.get()), nullptr);
+        EXPECT_EQ(C2NumbersTuning::From(inp2.get()), nullptr);
+        EXPECT_EQ(C2NumbersTuning::From(outp1.get()), nullptr);
+        EXPECT_EQ(C2NumbersTuning::From(outp2.get()), nullptr);
+        EXPECT_EQ(C2NumbersPortTuning::From(inp1.get()), inp1.get());
+        EXPECT_EQ(C2NumbersPortTuning::From(inp2.get()), (C2NumbersPortTuning*)inp2.get());
+        EXPECT_EQ(C2NumbersPortTuning::From(outp1.get()), outp1.get());
+        EXPECT_EQ(C2NumbersPortTuning::From(outp2.get()), (C2NumbersPortTuning*)outp2.get());
+        EXPECT_EQ(C2NumbersPortTuning::input::From(inp1.get()), (C2NumbersPortTuning::input*)inp1.get());
+        EXPECT_EQ(C2NumbersPortTuning::input::From(inp2.get()), inp2.get());
+        EXPECT_EQ(C2NumbersPortTuning::input::From(outp1.get()), nullptr);
+        EXPECT_EQ(C2NumbersPortTuning::input::From(outp2.get()), nullptr);
+        EXPECT_EQ(C2NumbersPortTuning::output::From(inp1.get()), nullptr);
+        EXPECT_EQ(C2NumbersPortTuning::output::From(inp2.get()), nullptr);
+        EXPECT_EQ(C2NumbersPortTuning::output::From(outp1.get()), (C2NumbersPortTuning::output*)outp1.get());
+        EXPECT_EQ(C2NumbersPortTuning::output::From(outp2.get()), outp2.get());
+        EXPECT_EQ(C2NumbersStreamTuning::From(inp1.get()), nullptr);
+        EXPECT_EQ(C2NumbersStreamTuning::From(inp2.get()), nullptr);
+        EXPECT_EQ(C2NumbersStreamTuning::From(outp1.get()), nullptr);
+        EXPECT_EQ(C2NumbersStreamTuning::From(outp2.get()), nullptr);
+        EXPECT_EQ(C2NumbersStreamTuning::input::From(inp1.get()), nullptr);
+        EXPECT_EQ(C2NumbersStreamTuning::input::From(inp2.get()), nullptr);
+        EXPECT_EQ(C2NumbersStreamTuning::input::From(outp1.get()), nullptr);
+        EXPECT_EQ(C2NumbersStreamTuning::input::From(outp2.get()), nullptr);
+        EXPECT_EQ(C2NumbersStreamTuning::output::From(inp1.get()), nullptr);
+        EXPECT_EQ(C2NumbersStreamTuning::output::From(inp2.get()), nullptr);
+        EXPECT_EQ(C2NumbersStreamTuning::output::From(outp1.get()), nullptr);
+        EXPECT_EQ(C2NumbersStreamTuning::output::From(outp2.get()), nullptr);
+
+        EXPECT_EQ(*(C2Param::Copy(*inp1)), *inp1);
+        EXPECT_EQ(*(C2Param::Copy(*inp2)), *inp2);
+        EXPECT_EQ(*(C2Param::Copy(*outp1)), *outp1);
+        EXPECT_EQ(*(C2Param::Copy(*outp2)), *outp2);
+    }
+
+    std::unique_ptr<C2NumbersStreamTuning> outs1_(C2NumbersStreamTuning::AllocUnique(1, true, 1u));
+    outs1_->m.mNumbers[0] = 100;
+    std::unique_ptr<const C2NumbersStreamTuning> outs1 = std::move(outs1_);
+    std::unique_ptr<C2NumbersStreamTuning> ins1_(C2NumbersStreamTuning::AllocUnique(1, false, 1u));
+    ins1_->m.mNumbers[0] = 100;
+    std::unique_ptr<const C2NumbersStreamTuning> ins1 = std::move(ins1_);
+    std::shared_ptr<C2NumbersStreamTuning> bouts1(C2NumbersStreamTuning::AllocShared(1));
+    std::shared_ptr<C2NumbersStreamTuning> bins1(C2NumbersStreamTuning::AllocShared(1));
+    std::shared_ptr<C2NumbersStreamTuning> bins3(C2NumbersStreamTuning::AllocShared(1, false, 1u));
+    bins3->m.mNumbers[0] = 100;
+    std::unique_ptr<C2NumbersStreamTuning::input> ins2_(C2NumbersStreamTuning::input::AllocUnique(1, 1u));
+    ins2_->m.mNumbers[0] = 100;
+    std::unique_ptr<const C2NumbersStreamTuning::input> ins2 = std::move(ins2_);
+    std::shared_ptr<C2NumbersStreamTuning::input> bins2(C2NumbersStreamTuning::input::AllocShared(1));
+    std::unique_ptr<C2NumbersStreamTuning::output> outs2_(C2NumbersStreamTuning::output::AllocUnique(1, 1u));
+    outs2_->m.mNumbers[0] = 100;
+    std::unique_ptr<const C2NumbersStreamTuning::output> outs2 = std::move(outs2_);
+    std::shared_ptr<C2NumbersStreamTuning::output> bouts2(C2NumbersStreamTuning::output::AllocShared(1));
+
+    {
+        static_assert(canCallSetPort(*bins3), "should be able to");
+        static_assert(canCallSetPort(*bins1), "should be able to");
+        static_assert(!canCallSetPort(*ins1), "should not be able to (const)");
+        static_assert(!canCallSetPort(*ins2), "should not be able to (const & type)");
+        static_assert(!canCallSetPort(*bins2), "should not be able to (type)");
+
+        // flags & invariables
+        const C2NumbersStreamTuning *S[] = { outs1.get(), ins1.get(), bouts1.get() };
+        for (const auto p : S) {
+            EXPECT_EQ(12u, p->size());
+            EXPECT_FALSE(p->isVendor());
+            EXPECT_TRUE(p->isFlexible());
+            EXPECT_FALSE(p->isGlobal());
+            EXPECT_TRUE(p->forStream());
+            EXPECT_FALSE(p->forPort());
+        }
+        const C2NumbersStreamTuning::input *SI[] = { ins2.get(), bins2.get() };
+        for (const auto p : SI) {
+            EXPECT_EQ(12u, p->size());
+            EXPECT_FALSE(p->isVendor());
+            EXPECT_TRUE(p->isFlexible());
+            EXPECT_FALSE(p->isGlobal());
+            EXPECT_TRUE(p->forStream());
+            EXPECT_FALSE(p->forPort());
+        }
+        const C2NumbersStreamTuning::output *SO[] = { outs2.get(), bouts2.get() };
+        for (const auto p : SO) {
+            EXPECT_EQ(12u, p->size());
+            EXPECT_FALSE(p->isVendor());
+            EXPECT_TRUE(p->isFlexible());
+            EXPECT_FALSE(p->isGlobal());
+            EXPECT_TRUE(p->forStream());
+            EXPECT_FALSE(p->forPort());
+        }
+
+        // port specific flags & invariables
+        EXPECT_FALSE(outs1->forInput());
+        EXPECT_TRUE(outs1->forOutput());
+
+        EXPECT_TRUE(ins1->forInput());
+        EXPECT_FALSE(ins1->forOutput());
+
+        const C2NumbersStreamTuning *S2[] = { outs1.get(), ins1.get() };
+        for (const auto p : S2) {
+            EXPECT_TRUE((bool)(*p));
+            EXPECT_FALSE(!(*p));
+            EXPECT_EQ(100, p->m.mNumbers[0]);
+            EXPECT_EQ(1u, p->stream());
+        }
+        for (const auto p : SO) {
+            EXPECT_TRUE((bool)(*p));
+            EXPECT_FALSE(!(*p));
+
+            EXPECT_FALSE(p->forInput());
+            EXPECT_TRUE(p->forOutput());
+        }
+        for (const auto p : SI) {
+            EXPECT_TRUE((bool)(*p));
+            EXPECT_FALSE(!(*p));
+
+            EXPECT_TRUE(p->forInput());
+            EXPECT_FALSE(p->forOutput());
+        }
+        const C2NumbersStreamTuning *S3[] = { bouts1.get() };
+        for (const auto p : S3) {
+            EXPECT_FALSE((bool)(*p));
+            EXPECT_TRUE(!(*p));
+
+            EXPECT_FALSE(p->forInput());
+            EXPECT_FALSE(p->forOutput());
+            EXPECT_EQ(0, p->m.mNumbers[0]);
+        }
+
+        // values
+        EXPECT_EQ(100, ins2->m.mNumbers[0]);
+        EXPECT_EQ(100, outs2->m.mNumbers[0]);
+        EXPECT_EQ(0, bins1->m.mNumbers[0]);
+        EXPECT_EQ(0, bins2->m.mNumbers[0]);
+        EXPECT_EQ(0, bouts1->m.mNumbers[0]);
+        EXPECT_EQ(0, bouts2->m.mNumbers[0]);
+
+        EXPECT_EQ(1u, ins2->stream());
+        EXPECT_EQ(1u, outs2->stream());
+        EXPECT_EQ(0u, bins1->stream());
+        EXPECT_EQ(0u, bins2->stream());
+        EXPECT_EQ(0u, bouts1->stream());
+        EXPECT_EQ(0u, bouts2->stream());
+
+        EXPECT_TRUE(*ins1 != *outs1);
+        EXPECT_TRUE(*ins1 == *ins2);
+        EXPECT_TRUE(*outs1 == *outs2);
+        EXPECT_TRUE(*bins1 == *bouts1);
+        EXPECT_TRUE(*bins2 != *bouts2);
+
+        EXPECT_TRUE(*ins1 != *bins1);
+        bins1->m.mNumbers[0] = 100;
+        EXPECT_TRUE(*ins1 != *bins1);
+        bins1->setPort(false /* output */);
+        EXPECT_TRUE(*ins1 != *bins1);
+        bins1->setStream(1u);
+        EXPECT_TRUE(*ins1 == *bins1);
+
+        EXPECT_TRUE(*ins2 != *bins2);
+        bins2->m.mNumbers[0] = 100;
+        EXPECT_TRUE(*ins2 != *bins2);
+        bins2->setStream(1u);
+        EXPECT_TRUE(*ins2 == *bins2);
+
+        bins1->setPort(true /* output */);
+        EXPECT_TRUE(*outs1 == *bins1);
+
+        EXPECT_TRUE(*outs1 != *bouts1);
+        bouts1->m.mNumbers[0] = 100;
+        EXPECT_TRUE(*outs1 != *bouts1);
+        bouts1->setPort(true /* output */);
+        EXPECT_TRUE(*outs1 != *bouts1);
+        bouts1->setStream(1u);
+        EXPECT_TRUE(*outs1 == *bouts1);
+
+        EXPECT_TRUE(*outs2 != *bouts2);
+        bouts2->m.mNumbers[0] = 100;
+        EXPECT_TRUE(*outs2 != *bouts2);
+        bouts2->setStream(1u);
+        EXPECT_TRUE(*outs2 == *bouts2);
+
+        bouts1->setPort(false /* output */);
+        EXPECT_TRUE(*ins1 == *bouts1);
+
+        // index
+        EXPECT_EQ(C2Param::Type(ins1->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
+        EXPECT_EQ(C2Param::Type(ins1->type()).typeIndex(), kParamIndexNumbers);
+        EXPECT_EQ(ins1->type(), C2NumbersStreamTuning::input::PARAM_TYPE);
+
+        EXPECT_EQ(C2Param::Type(ins2->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
+        EXPECT_EQ(C2Param::Type(ins2->type()).typeIndex(), kParamIndexNumbers);
+        EXPECT_EQ(ins2->type(), C2NumbersStreamTuning::input::PARAM_TYPE);
+
+        EXPECT_EQ(C2Param::Type(outs1->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
+        EXPECT_EQ(C2Param::Type(outs1->type()).typeIndex(), kParamIndexNumbers);
+        EXPECT_EQ(outs1->type(), C2NumbersStreamTuning::output::PARAM_TYPE);
+
+        EXPECT_EQ(C2Param::Type(outs2->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
+        EXPECT_EQ(C2Param::Type(outs2->type()).typeIndex(), kParamIndexNumbers);
+        EXPECT_EQ(outs2->type(), C2NumbersStreamTuning::output::PARAM_TYPE);
+
+        C2Param::CoreIndex index = C2NumbersStreamTuning::input::PARAM_TYPE;
+        EXPECT_FALSE(index.isVendor());
+        EXPECT_TRUE(index.isFlexible());
+        EXPECT_EQ(index.coreIndex(), kParamIndexNumbers | C2Param::CoreIndex::IS_FLEX_FLAG);
+        EXPECT_EQ(index.typeIndex(), kParamIndexNumbers);
+
+        index = C2NumbersStreamTuning::output::PARAM_TYPE;
+        EXPECT_FALSE(index.isVendor());
+        EXPECT_TRUE(index.isFlexible());
+        EXPECT_EQ(index.coreIndex(), kParamIndexNumbers | C2Param::CoreIndex::IS_FLEX_FLAG);
+        EXPECT_EQ(index.typeIndex(), kParamIndexNumbers);
+
+        C2Param::Type type = C2NumbersStreamTuning::input::PARAM_TYPE;
+        EXPECT_FALSE(type.isVendor());
+        EXPECT_TRUE(type.isFlexible());
+        EXPECT_FALSE(type.isGlobal());
+        EXPECT_TRUE(type.forInput());
+        EXPECT_FALSE(type.forOutput());
+        EXPECT_TRUE(type.forStream());
+        EXPECT_FALSE(type.forPort());
+
+        type = C2NumbersStreamTuning::output::PARAM_TYPE;
+        EXPECT_FALSE(type.isVendor());
+        EXPECT_TRUE(type.isFlexible());
+        EXPECT_FALSE(type.isGlobal());
+        EXPECT_FALSE(type.forInput());
+        EXPECT_TRUE(type.forOutput());
+        EXPECT_TRUE(type.forStream());
+        EXPECT_FALSE(type.forPort());
+
+        EXPECT_EQ(C2NumbersPortTuning::From(nullptr), nullptr);
+        EXPECT_EQ(C2NumbersPortTuning::input::From(nullptr), nullptr);
+        EXPECT_EQ(C2NumbersPortTuning::output::From(nullptr), nullptr);
+        EXPECT_EQ(C2NumbersTuning::From(ins1.get()), nullptr);
+        EXPECT_EQ(C2NumbersTuning::From(ins2.get()), nullptr);
+        EXPECT_EQ(C2NumbersTuning::From(outs1.get()), nullptr);
+        EXPECT_EQ(C2NumbersTuning::From(outs2.get()), nullptr);
+        EXPECT_EQ(C2NumbersPortTuning::From(ins1.get()), nullptr);
+        EXPECT_EQ(C2NumbersPortTuning::From(ins2.get()), nullptr);
+        EXPECT_EQ(C2NumbersPortTuning::From(outs1.get()), nullptr);
+        EXPECT_EQ(C2NumbersPortTuning::From(outs2.get()), nullptr);
+        EXPECT_EQ(C2NumbersPortTuning::input::From(ins1.get()), nullptr);
+        EXPECT_EQ(C2NumbersPortTuning::input::From(ins2.get()), nullptr);
+        EXPECT_EQ(C2NumbersPortTuning::input::From(outs1.get()), nullptr);
+        EXPECT_EQ(C2NumbersPortTuning::input::From(outs2.get()), nullptr);
+        EXPECT_EQ(C2NumbersPortTuning::output::From(ins1.get()), nullptr);
+        EXPECT_EQ(C2NumbersPortTuning::output::From(ins2.get()), nullptr);
+        EXPECT_EQ(C2NumbersPortTuning::output::From(outs1.get()), nullptr);
+        EXPECT_EQ(C2NumbersPortTuning::output::From(outs2.get()), nullptr);
+        EXPECT_EQ(C2NumbersStreamTuning::From(ins1.get()), ins1.get());
+        EXPECT_EQ(C2NumbersStreamTuning::From(ins2.get()), (C2NumbersStreamTuning*)ins2.get());
+        EXPECT_EQ(C2NumbersStreamTuning::From(outs1.get()), outs1.get());
+        EXPECT_EQ(C2NumbersStreamTuning::From(outs2.get()), (C2NumbersStreamTuning*)outs2.get());
+        EXPECT_EQ(C2NumbersStreamTuning::input::From(ins1.get()), (C2NumbersStreamTuning::input*)ins1.get());
+        EXPECT_EQ(C2NumbersStreamTuning::input::From(ins2.get()), ins2.get());
+        EXPECT_EQ(C2NumbersStreamTuning::input::From(outs1.get()), nullptr);
+        EXPECT_EQ(C2NumbersStreamTuning::input::From(outs2.get()), nullptr);
+        EXPECT_EQ(C2NumbersStreamTuning::output::From(ins1.get()), nullptr);
+        EXPECT_EQ(C2NumbersStreamTuning::output::From(ins2.get()), nullptr);
+        EXPECT_EQ(C2NumbersStreamTuning::output::From(outs1.get()), (C2NumbersStreamTuning::output*)outs1.get());
+        EXPECT_EQ(C2NumbersStreamTuning::output::From(outs2.get()), outs2.get());
+
+        EXPECT_EQ(*(C2Param::Copy(*ins1)), *ins1);
+        EXPECT_EQ(*(C2Param::Copy(*ins2)), *ins2);
+        EXPECT_EQ(*(C2Param::Copy(*outs1)), *outs1);
+        EXPECT_EQ(*(C2Param::Copy(*outs2)), *outs2);
+    }
+
+    {
+        C2Int32Value int32Value(INT32_MIN);
+        static_assert(std::is_same<decltype(int32Value.value), int32_t>::value, "should be int32_t");
+        EXPECT_EQ(INT32_MIN, int32Value.value);
+        std::vector<C2FieldDescriptor> fields = int32Value.FieldList();
+        EXPECT_EQ(1u, fields.size());
+        EXPECT_EQ(FD::INT32, fields.cbegin()->type());
+        EXPECT_EQ(1u, fields.cbegin()->extent());
+        EXPECT_EQ(C2String("value"), fields.cbegin()->name());
+    }
+
+    {
+        C2Uint32Value uint32Value(UINT32_MAX);
+        static_assert(std::is_same<decltype(uint32Value.value), uint32_t>::value, "should be uint32_t");
+        EXPECT_EQ(UINT32_MAX, uint32Value.value);
+        std::vector<C2FieldDescriptor> fields = uint32Value.FieldList();
+        EXPECT_EQ(1u, fields.size());
+        EXPECT_EQ(FD::UINT32, fields.cbegin()->type());
+        EXPECT_EQ(1u, fields.cbegin()->extent());
+        EXPECT_EQ(C2String("value"), fields.cbegin()->name());
+    }
+
+    {
+        C2Int64Value int64Value(INT64_MIN);
+        static_assert(std::is_same<decltype(int64Value.value), int64_t>::value, "should be int64_t");
+        EXPECT_EQ(INT64_MIN, int64Value.value);
+        std::vector<C2FieldDescriptor> fields = int64Value.FieldList();
+        EXPECT_EQ(1u, fields.size());
+        EXPECT_EQ(FD::INT64, fields.cbegin()->type());
+        EXPECT_EQ(1u, fields.cbegin()->extent());
+        EXPECT_EQ(C2String("value"), fields.cbegin()->name());
+    }
+
+    {
+        C2Uint64Value uint64Value(UINT64_MAX);
+        static_assert(std::is_same<decltype(uint64Value.value), uint64_t>::value, "should be uint64_t");
+        EXPECT_EQ(UINT64_MAX, uint64Value.value);
+        std::vector<C2FieldDescriptor> fields = uint64Value.FieldList();
+        EXPECT_EQ(1u, fields.size());
+        EXPECT_EQ(FD::UINT64, fields.cbegin()->type());
+        EXPECT_EQ(1u, fields.cbegin()->extent());
+        EXPECT_EQ(C2String("value"), fields.cbegin()->name());
+    }
+
+    {
+        C2FloatValue floatValue(123.4f);
+        static_assert(std::is_same<decltype(floatValue.value), float>::value, "should be float");
+        EXPECT_EQ(123.4f, floatValue.value);
+        std::vector<C2FieldDescriptor> fields = floatValue.FieldList();
+        EXPECT_EQ(1u, fields.size());
+        EXPECT_EQ(FD::FLOAT, fields.cbegin()->type());
+        EXPECT_EQ(1u, fields.cbegin()->extent());
+        EXPECT_EQ(C2String("value"), fields.cbegin()->name());
+    }
+
+    {
+        uint8_t initValue[] = "ABCD";
+        typedef C2GlobalParam<C2Setting, C2BlobValue, 0> BlobSetting;
+        std::unique_ptr<BlobSetting> blobValue = BlobSetting::AllocUnique(6, C2ConstMemoryBlock<uint8_t>(initValue));
+        static_assert(std::is_same<decltype(blobValue->m.value), uint8_t[]>::value, "should be uint8_t[]");
+        EXPECT_EQ(0, memcmp(blobValue->m.value, "ABCD\0", 6));
+        EXPECT_EQ(6u, blobValue->flexCount());
+        std::vector<C2FieldDescriptor> fields = blobValue->FieldList();
+        EXPECT_EQ(1u, fields.size());
+        EXPECT_EQ(FD::BLOB, fields.cbegin()->type());
+        EXPECT_EQ(0u, fields.cbegin()->extent());
+        EXPECT_EQ(C2String("value"), fields.cbegin()->name());
+
+        blobValue = BlobSetting::AllocUnique(3, C2ConstMemoryBlock<uint8_t>(initValue));
+        EXPECT_EQ(0, memcmp(blobValue->m.value, "ABC", 3));
+        EXPECT_EQ(3u, blobValue->flexCount());
+    }
+
+    {
+        constexpr char initValue[] = "ABCD";
+        typedef C2GlobalParam<C2Setting, C2StringValue, 0> StringSetting;
+        std::unique_ptr<StringSetting> stringValue = StringSetting::AllocUnique(6, C2ConstMemoryBlock<char>(initValue));
+        stringValue = StringSetting::AllocUnique(6, initValue);
+        static_assert(std::is_same<decltype(stringValue->m.value), char[]>::value, "should be char[]");
+        EXPECT_EQ(0, memcmp(stringValue->m.value, "ABCD\0", 6));
+        EXPECT_EQ(6u, stringValue->flexCount());
+        std::vector<C2FieldDescriptor> fields = stringValue->FieldList();
+        EXPECT_EQ(1u, fields.size());
+        EXPECT_EQ(FD::STRING, fields.cbegin()->type());
+        EXPECT_EQ(0u, fields.cbegin()->extent());
+        EXPECT_EQ(C2String("value"), fields.cbegin()->name());
+
+        stringValue = StringSetting::AllocUnique(3, C2ConstMemoryBlock<char>(initValue));
+        EXPECT_EQ(0, memcmp(stringValue->m.value, "AB", 3));
+        EXPECT_EQ(3u, stringValue->flexCount());
+
+        stringValue = StringSetting::AllocUnique(11, "initValue");
+        EXPECT_EQ(0, memcmp(stringValue->m.value, "initValue\0", 11));
+        EXPECT_EQ(11u, stringValue->flexCount());
+
+        stringValue = StringSetting::AllocUnique(initValue);
+        EXPECT_EQ(0, memcmp(stringValue->m.value, "ABCD", 5));
+        EXPECT_EQ(5u, stringValue->flexCount());
+
+        stringValue = StringSetting::AllocUnique({ 'A', 'B', 'C', 'D' });
+        EXPECT_EQ(0, memcmp(stringValue->m.value, "ABC", 4));
+        EXPECT_EQ(4u, stringValue->flexCount());
+    }
+
+    {
+        uint32_t videoWidth[] = { 12u, C2NumbersStreamTuning::output::PARAM_TYPE, 100 };
+        C2Param *p1 = C2Param::From(videoWidth, sizeof(videoWidth));
+        EXPECT_NE(nullptr, p1);
+        EXPECT_EQ(12u, p1->size());
+        EXPECT_EQ(p1->type(), C2NumbersStreamTuning::output::PARAM_TYPE);
+
+        C2NumbersStreamTuning::output *vst = C2NumbersStreamTuning::output::From(p1);
+        EXPECT_NE(nullptr, vst);
+        if (vst) {
+            EXPECT_EQ(1u, vst->flexCount());
+            EXPECT_EQ(100, vst->m.mNumbers[0]);
+        }
+
+        p1 = C2Param::From(videoWidth, sizeof(videoWidth) + 2);
+        EXPECT_EQ(nullptr, p1);
+
+        p1 = C2Param::From(videoWidth, sizeof(videoWidth) - 2);
+        EXPECT_EQ(nullptr, p1);
+
+        p1 = C2Param::From(videoWidth, 3);
+        EXPECT_EQ(nullptr, p1);
+
+        p1 = C2Param::From(videoWidth, 0);
+        EXPECT_EQ(nullptr, p1);
+    }
+
+    {
+        uint32_t videoWidth[] = { 16u, C2NumbersPortTuning::input::PARAM_TYPE, 101, 102 };
+
+        C2Param *p1 = C2Param::From(videoWidth, sizeof(videoWidth));
+        EXPECT_NE(nullptr, p1);
+        EXPECT_EQ(16u, p1->size());
+        EXPECT_EQ(p1->type(), C2NumbersPortTuning::input::PARAM_TYPE);
+
+        C2NumbersPortTuning::input *vpt = C2NumbersPortTuning::input::From(p1);
+        EXPECT_NE(nullptr, vpt);
+        if (vpt) {
+            EXPECT_EQ(2u, vpt->flexCount());
+            EXPECT_EQ(101, vpt->m.mNumbers[0]);
+            EXPECT_EQ(102, vpt->m.mNumbers[1]);
+        }
+
+        p1 = C2Param::From(videoWidth, sizeof(videoWidth) + 2);
+        EXPECT_EQ(nullptr, p1);
+
+        p1 = C2Param::From(videoWidth, sizeof(videoWidth) - 2);
+        EXPECT_EQ(nullptr, p1);
+
+        p1 = C2Param::From(videoWidth, 3);
+        EXPECT_EQ(nullptr, p1);
+
+        p1 = C2Param::From(videoWidth, 0);
+        EXPECT_EQ(nullptr, p1);
+    }
+}
+
+TEST_F(C2ParamTest, C2ValueTest) {
+    C2Value val;
+    int32_t i32 = -32;
+    int64_t i64 = -64;
+    uint32_t u32 = 32;
+    uint64_t u64 = 64;
+    float fp = 1.5f;
+
+    EXPECT_EQ(C2Value::NO_INIT, val.type());
+    EXPECT_EQ(false, val.get(&i32));
+    EXPECT_EQ(-32, i32);
+    EXPECT_EQ(false, val.get(&i64));
+    EXPECT_EQ(-64, i64);
+    EXPECT_EQ(false, val.get(&u32));
+    EXPECT_EQ(32u, u32);
+    EXPECT_EQ(false, val.get(&u64));
+    EXPECT_EQ(64u, u64);
+    EXPECT_EQ(false, val.get(&fp));
+    EXPECT_EQ(1.5f, fp);
+
+    val = int32_t(-3216);
+    EXPECT_EQ(C2Value::INT32, val.type());
+    EXPECT_EQ(true, val.get(&i32));
+    EXPECT_EQ(-3216, i32);
+    EXPECT_EQ(false, val.get(&i64));
+    EXPECT_EQ(-64, i64);
+    EXPECT_EQ(false, val.get(&u32));
+    EXPECT_EQ(32u, u32);
+    EXPECT_EQ(false, val.get(&u64));
+    EXPECT_EQ(64u, u64);
+    EXPECT_EQ(false, val.get(&fp));
+    EXPECT_EQ(1.5f, fp);
+
+    val = uint32_t(3216);
+    EXPECT_EQ(C2Value::UINT32, val.type());
+    EXPECT_EQ(false, val.get(&i32));
+    EXPECT_EQ(-3216, i32);
+    EXPECT_EQ(false, val.get(&i64));
+    EXPECT_EQ(-64, i64);
+    EXPECT_EQ(true, val.get(&u32));
+    EXPECT_EQ(3216u, u32);
+    EXPECT_EQ(false, val.get(&u64));
+    EXPECT_EQ(64u, u64);
+    EXPECT_EQ(false, val.get(&fp));
+    EXPECT_EQ(1.5f, fp);
+
+    val = int64_t(-6432);
+    EXPECT_EQ(C2Value::INT64, val.type());
+    EXPECT_EQ(false, val.get(&i32));
+    EXPECT_EQ(-3216, i32);
+    EXPECT_EQ(true, val.get(&i64));
+    EXPECT_EQ(-6432, i64);
+    EXPECT_EQ(false, val.get(&u32));
+    EXPECT_EQ(3216u, u32);
+    EXPECT_EQ(false, val.get(&u64));
+    EXPECT_EQ(64u, u64);
+    EXPECT_EQ(false, val.get(&fp));
+    EXPECT_EQ(1.5f, fp);
+
+    val = uint64_t(6432);
+    EXPECT_EQ(C2Value::UINT64, val.type());
+    EXPECT_EQ(false, val.get(&i32));
+    EXPECT_EQ(-3216, i32);
+    EXPECT_EQ(false, val.get(&i64));
+    EXPECT_EQ(-6432, i64);
+    EXPECT_EQ(false, val.get(&u32));
+    EXPECT_EQ(3216u, u32);
+    EXPECT_EQ(true, val.get(&u64));
+    EXPECT_EQ(6432u, u64);
+    EXPECT_EQ(false, val.get(&fp));
+    EXPECT_EQ(1.5f, fp);
+
+    val = 15.25f;
+    EXPECT_EQ(C2Value::FLOAT, val.type());
+    EXPECT_EQ(false, val.get(&i32));
+    EXPECT_EQ(-3216, i32);
+    EXPECT_EQ(false, val.get(&i64));
+    EXPECT_EQ(-6432, i64);
+    EXPECT_EQ(false, val.get(&u32));
+    EXPECT_EQ(3216u, u32);
+    EXPECT_EQ(false, val.get(&u64));
+    EXPECT_EQ(6432u, u64);
+    EXPECT_EQ(true, val.get(&fp));
+    EXPECT_EQ(15.25f, fp);
+}
+
diff --git a/media/codec2/tests/C2SampleComponent_test.cpp b/media/codec2/tests/C2SampleComponent_test.cpp
new file mode 100644
index 0000000..9956834
--- /dev/null
+++ b/media/codec2/tests/C2SampleComponent_test.cpp
@@ -0,0 +1,432 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SampleComponent_test"
+
+#include <gtest/gtest.h>
+
+#define __C2_GENERATE_GLOBAL_VARS__
+#include <C2Component.h>
+#include <C2Config.h>
+#include <C2Debug.h>
+#include <C2Enum.h>
+
+#include <unordered_map>
+
+class C2SampleComponentTest : public ::testing::Test {
+};
+
+void PrintTo(const C2FieldDescriptor &fd, ::std::ostream *os) {
+    using FD=C2FieldDescriptor;
+    switch (fd.type()) {
+    case FD::INT32: *os << "i32"; break;
+    case FD::INT64: *os << "i64"; break;
+    case FD::UINT32: *os << "u32"; break;
+    case FD::UINT64: *os << "u64"; break;
+    case FD::FLOAT: *os << "float"; break;
+    case FD::STRING: *os << "char"; break;
+    case FD::BLOB: *os << "u8"; break;
+    default:
+        if (fd.type() & FD::STRUCT_FLAG) {
+            *os << "struct-" << (fd.type() & ~FD::STRUCT_FLAG);
+        } else {
+            *os << "type-" << fd.type();
+        }
+    }
+    *os << " " << fd.name();
+    if (fd.extent() > 1) {
+        *os << "[" << fd.extent() << "]";
+    } else if (fd.extent() == 0) {
+        *os << "[]";
+    }
+    *os << " (" << fd._mFieldId << "*" << fd.extent() << ")";
+}
+
+C2ENUM(
+    MetadataType, int32_t,
+    kInvalid = -1,
+    kNone = 0,
+    kGralloc,
+    kNativeHandle,
+    kANativeWindow,
+    kCamera,
+)
+
+enum {
+    kParamIndexVideoConfig = 0x1234,
+};
+
+struct C2VideoConfigStruct {
+    int32_t width;
+    uint32_t height;
+    MetadataType metadataType;
+    int32_t supportedFormats[];
+
+    C2VideoConfigStruct() {}
+
+    DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(VideoConfig, supportedFormats)
+    C2FIELD(width, "width")
+    C2FIELD(height, "height")
+    C2FIELD(metadataType, "metadata-type")
+    C2FIELD(supportedFormats, "formats")
+};
+
+typedef C2PortParam<C2Tuning, C2VideoConfigStruct> C2VideoConfigPortTuning;
+
+class MyComponentInstance : public C2ComponentInterface {
+public:
+    virtual C2String getName() const override {
+        /// \todo this seems too specific
+        return "sample.interface";
+    };
+
+    virtual c2_node_id_t getId() const override {
+        /// \todo how are these shared?
+        return 0;
+    }
+
+    virtual c2_status_t config_vb(
+            const std::vector<C2Param*> &params,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2SettingResult>>* const failures) override {
+        (void)params;
+        (void)failures;
+        (void)mayBlock;
+        return C2_OMITTED;
+    }
+
+    virtual c2_status_t createTunnel_sm(c2_node_id_t targetComponent) override {
+        (void)targetComponent;
+        return C2_OMITTED;
+    }
+
+    virtual c2_status_t query_vb(
+            const std::vector<C2Param*> &stackParams,
+            const std::vector<C2Param::Index> &heapParamIndices,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2Param>>* const heapParams) const override {
+        for (C2Param* const param : stackParams) {
+            (void)mayBlock;
+            if (!*param) { // param is already invalid - remember it
+                continue;
+            }
+
+            // note: this does not handle stream params (should use index...)
+            if (!mMyParams.count(param->index())) {
+                continue; // not my param
+            }
+
+            C2Param & myParam = mMyParams.find(param->index())->second;
+            if (myParam.size() != param->size()) { // incorrect size
+                param->invalidate();
+                continue;
+            }
+
+            param->updateFrom(myParam);
+        }
+
+        for (const C2Param::Index index : heapParamIndices) {
+            if (mMyParams.count(index)) {
+                C2Param & myParam = mMyParams.find(index)->second;
+                std::unique_ptr<C2Param> paramCopy(C2Param::Copy(myParam));
+                heapParams->push_back(std::move(paramCopy));
+            }
+        }
+
+        return C2_OK;
+    }
+
+    std::unordered_map<uint32_t, C2Param &> mMyParams;
+
+    C2ComponentDomainSetting mDomainInfo;
+
+    MyComponentInstance() {
+        mMyParams.insert({mDomainInfo.index(), mDomainInfo});
+    }
+
+    virtual c2_status_t releaseTunnel_sm(c2_node_id_t targetComponent) override {
+        (void)targetComponent;
+        return C2_OMITTED;
+    }
+
+    class MyParamReflector : public C2ParamReflector {
+        const MyComponentInstance *instance;
+
+    public:
+        MyParamReflector(const MyComponentInstance *i) : instance(i) { }
+
+        virtual std::unique_ptr<C2StructDescriptor> describe(C2Param::CoreIndex paramIndex) const override {
+            switch (paramIndex.typeIndex()) {
+            case decltype(instance->mDomainInfo)::CORE_INDEX:
+            default:
+                return std::unique_ptr<C2StructDescriptor>(new C2StructDescriptor{
+                    instance->mDomainInfo.type(),
+                    decltype(instance->mDomainInfo)::FieldList(),
+                });
+            }
+            return nullptr;
+        }
+    };
+
+    virtual c2_status_t querySupportedValues_vb(
+            std::vector<C2FieldSupportedValuesQuery> &fields,
+            c2_blocking_t mayBlock) const override {
+        (void)mayBlock;
+        for (C2FieldSupportedValuesQuery &query : fields) {
+            if (query.field() == C2ParamField(&mDomainInfo, &C2ComponentDomainSetting::value)) {
+                query.values = C2FieldSupportedValues(
+                    false /* flag */,
+                    &mDomainInfo.value
+                    //,
+                    //{(int32_t)C2Component::DOMAIN_VIDEO}
+                );
+                query.status = C2_OK;
+            } else {
+                query.status = C2_BAD_INDEX;
+            }
+        }
+        return C2_OK;
+    }
+
+    std::shared_ptr<C2ParamReflector> getParamReflector() const {
+        return std::shared_ptr<C2ParamReflector>(new MyParamReflector(this));
+    }
+
+    virtual c2_status_t querySupportedParams_nb(
+            std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const override {
+        params->push_back(std::make_shared<C2ParamDescriptor>(
+                true /* required */, "_domain", &mDomainInfo));
+        params->push_back(std::shared_ptr<C2ParamDescriptor>(
+                new C2ParamDescriptor(true /* required */, "_domain", &mDomainInfo)));
+        return C2_OK;
+    }
+
+    virtual ~MyComponentInstance() override = default;
+};
+
+template<typename E, bool S=std::is_enum<E>::value>
+struct getter {
+    int32_t get(const C2FieldSupportedValues::Primitive &p, int32_t*) {
+        return p.i32;
+    }
+    int64_t get(const C2FieldSupportedValues::Primitive &p, int64_t*) {
+        return p.i64;
+    }
+    uint32_t get(const C2FieldSupportedValues::Primitive &p, uint32_t*) {
+        return p.u32;
+    }
+    uint64_t get(const C2FieldSupportedValues::Primitive &p, uint64_t*) {
+        return p.u64;
+    }
+    float get(const C2FieldSupportedValues::Primitive &p, float*) {
+        return p.fp;
+    }
+};
+
+template<typename E>
+struct getter<E, true> {
+     typename std::underlying_type<E>::type get(const C2FieldSupportedValues::Primitive &p, E*) {
+         using u=typename std::underlying_type<E>::type;
+         return getter<u>().get(p, (u*)0);
+     }
+};
+
+template<typename T, bool E=std::is_enum<T>::value>
+struct lax_underlying_type {
+    typedef typename std::underlying_type<T>::type type;
+};
+
+template<typename T>
+struct lax_underlying_type<T, false> {
+    typedef T type;
+};
+
+template<typename E>
+typename lax_underlying_type<E>::type get(
+        const C2FieldSupportedValues::Primitive &p, E*) {
+    return getter<E>().get(p, (E*)0);
+}
+
+template<typename T>
+void dumpFSV(const C2FieldSupportedValues &sv, T*t) {
+    using namespace std;
+    cout << (std::is_enum<T>::value ? (std::is_signed<typename lax_underlying_type<T>::type>::value ? "i" : "u")
+             : std::is_integral<T>::value ? std::is_signed<T>::value ? "i" : "u" : "f")
+         << (8 * sizeof(T));
+    if (sv.type == sv.RANGE) {
+        cout << ".range(" << get(sv.range.min, t);
+        if (get(sv.range.step, t) != std::is_integral<T>::value) {
+            cout << ":" << get(sv.range.step, t);
+        }
+        if (get(sv.range.num, t) != 1 || get(sv.range.denom, t) != 1) {
+            cout << ":" << get(sv.range.num, t) << "/" << get(sv.range.denom, t);
+        }
+        cout << get(sv.range.max, t) << ")";
+    }
+    if (sv.values.size()) {
+        cout << (sv.type == sv.FLAGS ? ".flags(" : ".list(");
+        const char *sep = "";
+        for (const C2FieldSupportedValues::Primitive &p : sv.values) {
+            cout << sep << get(p, t);
+            sep = ",";
+        }
+        cout << ")";
+    }
+    cout << endl;
+}
+
+void dumpType(C2Param::Type type) {
+    using namespace std;
+    cout << (type.isVendor() ? "Vendor" : "C2");
+    if (type.forInput()) {
+        cout << "Input";
+    } else if (type.forOutput()) {
+        cout << "Output";
+    } else if (type.forPort() && !type.forStream()) {
+        cout << "Port";
+    }
+    if (type.forStream()) {
+        cout << "Stream";
+    }
+
+    if (type.isFlexible()) {
+        cout << "Flex";
+    }
+
+    cout << type.typeIndex();
+
+    switch (type.kind()) {
+    case C2Param::INFO: cout << "Info"; break;
+    case C2Param::SETTING: cout << "Setting"; break;
+    case C2Param::TUNING: cout << "Tuning"; break;
+    case C2Param::STRUCT: cout << "Struct"; break;
+    default: cout << "Kind" << (int32_t)type.kind(); break;
+    }
+}
+
+void dumpType(C2Param::CoreIndex type) {
+    using namespace std;
+    cout << (type.isVendor() ? "Vendor" : "C2");
+    if (type.isFlexible()) {
+        cout << "Flex";
+    }
+
+    cout << type.typeIndex() << "Struct";
+}
+
+void dumpType(C2FieldDescriptor::type_t type) {
+    using namespace std;
+    switch (type) {
+    case C2FieldDescriptor::BLOB: cout << "blob "; break;
+    case C2FieldDescriptor::FLOAT: cout << "float "; break;
+    case C2FieldDescriptor::INT32: cout << "int32_t "; break;
+    case C2FieldDescriptor::INT64: cout << "int64_t "; break;
+    case C2FieldDescriptor::UINT32: cout << "uint32_t "; break;
+    case C2FieldDescriptor::UINT64: cout << "uint64_t "; break;
+    case C2FieldDescriptor::STRING: cout << "char "; break;
+    default:
+        cout << "struct ";
+        dumpType((C2Param::Type)type);
+        break;
+    }
+}
+
+void dumpStruct(const C2StructDescriptor &sd) {
+    using namespace std;
+    cout << "struct ";
+    dumpType(sd.coreIndex());
+    cout << " {" << endl;
+    //C2FieldDescriptor &f;
+    for (const C2FieldDescriptor &f : sd) {
+        PrintTo(f, &cout);
+        cout << endl;
+
+        if (f.namedValues().size()) {
+            cout << ".named(";
+            const char *sep = "";
+            for (const C2FieldDescriptor::NamedValueType &p : f.namedValues()) {
+                cout << sep << p.first << "=";
+                switch (f.type()) {
+                case C2FieldDescriptor::INT32: cout << get(p.second, (int32_t *)0); break;
+                case C2FieldDescriptor::INT64: cout << get(p.second, (int64_t *)0); break;
+                case C2FieldDescriptor::UINT32: cout << get(p.second, (uint32_t *)0); break;
+                case C2FieldDescriptor::UINT64: cout << get(p.second, (uint64_t *)0); break;
+                case C2FieldDescriptor::FLOAT: cout << get(p.second, (float *)0); break;
+                default: cout << "???"; break;
+                }
+                sep = ",";
+            }
+            cout << ")";
+        }
+    }
+
+    cout << "};" << endl;
+}
+
+void dumpDesc(const C2ParamDescriptor &pd) {
+    using namespace std;
+    if (pd.isRequired()) {
+        cout << "required ";
+    }
+    if (pd.isPersistent()) {
+        cout << "persistent ";
+    }
+    cout << "struct ";
+    dumpType(C2Param::Type(pd.index().type()));
+    cout << " " << pd.name() << ";" << endl;
+}
+
+TEST_F(C2SampleComponentTest, ReflectorTest) {
+    C2ComponentDomainSetting domainInfo;
+    std::shared_ptr<MyComponentInstance> myComp(new MyComponentInstance);
+    std::shared_ptr<C2ComponentInterface> comp = myComp;
+
+    std::unique_ptr<C2StructDescriptor> desc{
+        myComp->getParamReflector()->describe(C2ComponentDomainSetting::CORE_INDEX)};
+    dumpStruct(*desc);
+
+    std::vector<C2FieldSupportedValuesQuery> query = {
+        { C2ParamField(&domainInfo, &C2ComponentDomainSetting::value),
+          C2FieldSupportedValuesQuery::CURRENT },
+        C2FieldSupportedValuesQuery(C2ParamField(&domainInfo, &C2ComponentDomainSetting::value),
+          C2FieldSupportedValuesQuery::CURRENT),
+        C2FieldSupportedValuesQuery::Current(C2ParamField(&domainInfo, &C2ComponentDomainSetting::value)),
+    };
+
+    EXPECT_EQ(C2_OK, comp->querySupportedValues_vb(query, C2_DONT_BLOCK));
+
+    for (const C2FieldSupportedValuesQuery &q : query) {
+        dumpFSV(q.values, &domainInfo.value);
+    }
+}
+
+TEST_F(C2SampleComponentTest, FieldSupportedValuesTest) {
+    typedef C2GlobalParam<C2Info, C2Uint32Value, 0> Uint32TestInfo;
+    Uint32TestInfo t;
+    std::vector<C2FieldSupportedValues> values;
+    values.push_back(C2FieldSupportedValues(0, 10, 1));  // min, max, step
+    values.push_back(C2FieldSupportedValues(1, 64, 2, 1));  // min, max, num, den
+    values.push_back(C2FieldSupportedValues(false, {1, 2, 3}));  // flags, std::initializer_list
+    uint32_t val[] = {1, 3, 5, 7};
+    std::vector<uint32_t> v(std::begin(val), std::end(val));
+    values.push_back(C2FieldSupportedValues(false, v));  // flags, std::vector
+
+    for (const C2FieldSupportedValues &sv : values) {
+        dumpFSV(sv, &t.value);
+    }
+}
+
diff --git a/media/codec2/tests/C2UtilTest.cpp b/media/codec2/tests/C2UtilTest.cpp
new file mode 100644
index 0000000..59cd313
--- /dev/null
+++ b/media/codec2/tests/C2UtilTest.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2UtilTest"
+
+#include <gtest/gtest.h>
+
+#define __C2_GENERATE_GLOBAL_VARS__
+#include <_C2MacroUtils.h>
+#include <C2Enum.h>
+
+/** \file
+ * Tests for vndk/util.
+ */
+
+/* --------------------------------------- _C2MacroUtils --------------------------------------- */
+
+static_assert(0 == _C2_ARGC(), "should be 0");
+static_assert(1 == _C2_ARGC(1), "should be 1");
+static_assert(2 == _C2_ARGC(1, 2), "should be 2");
+static_assert(64 == _C2_ARGC(
+        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+        26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+        49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64), "should be 64");
+
+static_assert(0 == _C2_ARGC(,), "should be 0");
+static_assert(1 == _C2_ARGC(1,), "should be 1");
+static_assert(2 == _C2_ARGC(1, 2,), "should be 2");
+static_assert(64 == _C2_ARGC(
+        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+        26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+        49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,), "should be 64");
+
+/* ---------------------------------------- _C2EnumUtils ---------------------------------------- */
+
+class C2UtilTest : public ::testing::Test {
+};
+
+C2ENUM(Enum1, uint32_t,
+    Enum1Value1,
+    Enum1Value2,
+    Enum1Value4 = Enum1Value2 + 2,
+);
+
+C2ENUM_CUSTOM_PREFIX(Enum2, uint32_t, "Enum",
+    Enum2Value1,
+    Enum2Value2,
+    Enum2Value4 = Enum1Value2 + 2,
+);
+
+C2ENUM_CUSTOM_NAMES(Enum3, uint8_t,
+    ({ { "value1", Enum3Value1 },
+       { "value2", Enum3Value2 },
+       { "value4", Enum3Value4 },
+       { "invalid", Invalid } }),
+    Enum3Value1,
+    Enum3Value2,
+    Enum3Value4 = Enum3Value2 + 2,
+    Invalid,
+);
+
+TEST_F(C2UtilTest, EnumUtilsTest) {
+    std::vector<std::pair<C2String, Enum3>> pairs ( { { "value1", Enum3Value1 },
+      { "value2", Enum3Value2 },
+      { "value4", Enum3Value4 },
+      { "invalid", Invalid } });
+    Enum3 e3;
+    C2FieldDescriptor::namedValuesFor(e3);
+
+    // upper case
+    EXPECT_EQ("yes", _C2EnumUtils::camelCaseToDashed("YES"));
+    EXPECT_EQ("no", _C2EnumUtils::camelCaseToDashed("NO"));
+    EXPECT_EQ("yes-no", _C2EnumUtils::camelCaseToDashed("YES_NO"));
+    EXPECT_EQ("yes-no", _C2EnumUtils::camelCaseToDashed("YES__NO"));
+    EXPECT_EQ("a2dp", _C2EnumUtils::camelCaseToDashed("A2DP"));
+    EXPECT_EQ("mp2-ts", _C2EnumUtils::camelCaseToDashed("MP2_TS"));
+    EXPECT_EQ("block-2d", _C2EnumUtils::camelCaseToDashed("BLOCK_2D"));
+    EXPECT_EQ("mpeg-2-ts", _C2EnumUtils::camelCaseToDashed("MPEG_2_TS"));
+    EXPECT_EQ("_hidden-value", _C2EnumUtils::camelCaseToDashed("_HIDDEN_VALUE"));
+    EXPECT_EQ("__hidden-value2", _C2EnumUtils::camelCaseToDashed("__HIDDEN_VALUE2"));
+    EXPECT_EQ("__hidden-value-2", _C2EnumUtils::camelCaseToDashed("__HIDDEN_VALUE_2"));
+
+    // camel case
+    EXPECT_EQ("yes", _C2EnumUtils::camelCaseToDashed("Yes"));
+    EXPECT_EQ("no", _C2EnumUtils::camelCaseToDashed("No"));
+    EXPECT_EQ("yes-no", _C2EnumUtils::camelCaseToDashed("YesNo"));
+    EXPECT_EQ("yes-no", _C2EnumUtils::camelCaseToDashed("Yes_No"));
+    EXPECT_EQ("mp2-ts", _C2EnumUtils::camelCaseToDashed("MP2Ts"));
+    EXPECT_EQ("block-2d", _C2EnumUtils::camelCaseToDashed("Block2D"));
+    EXPECT_EQ("mpeg-2-ts", _C2EnumUtils::camelCaseToDashed("Mpeg2ts"));
+    EXPECT_EQ("_hidden-value", _C2EnumUtils::camelCaseToDashed("_HiddenValue"));
+    EXPECT_EQ("__hidden-value-2", _C2EnumUtils::camelCaseToDashed("__HiddenValue2"));
+
+    // mixed case
+    EXPECT_EQ("mp2t-s", _C2EnumUtils::camelCaseToDashed("MP2T_s"));
+    EXPECT_EQ("block-2d", _C2EnumUtils::camelCaseToDashed("Block_2D"));
+    EXPECT_EQ("block-2-d", _C2EnumUtils::camelCaseToDashed("Block2_D"));
+    EXPECT_EQ("mpeg-2-ts", _C2EnumUtils::camelCaseToDashed("Mpeg_2ts"));
+    EXPECT_EQ("mpeg-2-ts", _C2EnumUtils::camelCaseToDashed("Mpeg_2_TS"));
+    EXPECT_EQ("_hidden-value", _C2EnumUtils::camelCaseToDashed("_Hidden__VALUE"));
+    EXPECT_EQ("__hidden-value-2", _C2EnumUtils::camelCaseToDashed("__HiddenValue_2"));
+    EXPECT_EQ("_2", _C2EnumUtils::camelCaseToDashed("_2"));
+    EXPECT_EQ("__23", _C2EnumUtils::camelCaseToDashed("__23"));
+}
+
diff --git a/media/codec2/tests/C2_test.cpp b/media/codec2/tests/C2_test.cpp
new file mode 100644
index 0000000..2ada9f9
--- /dev/null
+++ b/media/codec2/tests/C2_test.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2_test"
+
+#include <gtest/gtest.h>
+
+#include <C2.h>
+
+/* ======================================= STATIC TESTS ======================================= */
+
+template<int N>
+struct c2_const_checker
+{
+    inline constexpr static int num() { return N; }
+};
+
+constexpr auto min_i32_i32 = c2_min(int32_t(1), int32_t(2));
+static_assert(std::is_same<decltype(min_i32_i32), const int32_t>::value, "should be int32_t");
+constexpr auto min_i32_i64 = c2_min(int32_t(3), int64_t(2));
+static_assert(std::is_same<decltype(min_i32_i64), const int64_t>::value, "should be int64_t");
+constexpr auto min_i8_i32 = c2_min(int8_t(0xff), int32_t(0xffffffff));
+static_assert(std::is_same<decltype(min_i8_i32), const int32_t>::value, "should be int32_t");
+
+static_assert(c2_const_checker<min_i32_i32>::num() == 1, "should be 1");
+static_assert(c2_const_checker<min_i32_i64>::num() == 2, "should be 2");
+static_assert(c2_const_checker<min_i8_i32>::num() == 0xffffffff, "should be 0xffffffff");
+
+constexpr auto min_u32_u32 = c2_min(uint32_t(1), uint32_t(2));
+static_assert(std::is_same<decltype(min_u32_u32), const uint32_t>::value, "should be uint32_t");
+constexpr auto min_u32_u64 = c2_min(uint32_t(3), uint64_t(2));
+static_assert(std::is_same<decltype(min_u32_u64), const uint32_t>::value, "should be uint32_t");
+constexpr auto min_u32_u8 = c2_min(uint32_t(0xffffffff), uint8_t(0xff));
+static_assert(std::is_same<decltype(min_u32_u8), const uint8_t>::value, "should be uint8_t");
+
+static_assert(c2_const_checker<min_u32_u32>::num() == 1, "should be 1");
+static_assert(c2_const_checker<min_u32_u64>::num() == 2, "should be 2");
+static_assert(c2_const_checker<min_u32_u8>::num() == 0xff, "should be 0xff");
+
+constexpr auto max_i32_i32 = c2_max(int32_t(1), int32_t(2));
+static_assert(std::is_same<decltype(max_i32_i32), const int32_t>::value, "should be int32_t");
+constexpr auto max_i32_i64 = c2_max(int32_t(3), int64_t(2));
+static_assert(std::is_same<decltype(max_i32_i64), const int64_t>::value, "should be int64_t");
+constexpr auto max_i8_i32 = c2_max(int8_t(0xff), int32_t(0xffffffff));
+static_assert(std::is_same<decltype(max_i8_i32), const int32_t>::value, "should be int32_t");
+
+static_assert(c2_const_checker<max_i32_i32>::num() == 2, "should be 2");
+static_assert(c2_const_checker<max_i32_i64>::num() == 3, "should be 3");
+static_assert(c2_const_checker<max_i8_i32>::num() == 0xffffffff, "should be 0xffffffff");
+
+constexpr auto max_u32_u32 = c2_max(uint32_t(1), uint32_t(2));
+static_assert(std::is_same<decltype(max_u32_u32), const uint32_t>::value, "should be uint32_t");
+constexpr auto max_u32_u64 = c2_max(uint32_t(3), uint64_t(2));
+static_assert(std::is_same<decltype(max_u32_u64), const uint64_t>::value, "should be uint64_t");
+constexpr auto max_u32_u8 = c2_max(uint32_t(0x7fffffff), uint8_t(0xff));
+static_assert(std::is_same<decltype(max_u32_u8), const uint32_t>::value, "should be uint32_t");
+
+static_assert(c2_const_checker<max_u32_u32>::num() == 2, "should be 2");
+static_assert(c2_const_checker<max_u32_u64>::num() == 3, "should be 3");
+static_assert(c2_const_checker<max_u32_u8>::num() == 0x7fffffff, "should be 0x7fffffff");
+
+/* ======================================= COUNTER TESTS ======================================= */
+
+void c2_cntr_static_test() {
+    // sanity checks for construction/assignment
+    constexpr c2_cntr32_t c32_a(123);
+    constexpr c2_cntr64_t c64_a(-456);
+    c2_cntr32_t c32_b __unused = c64_a;
+    // c32_b = 64.; // DISALLOWED
+    // c2_cntr64_t c64_b = c32_a; // DISALLOWED
+
+    // sanity checks for some constexpr operators
+    static_assert(std::is_same<decltype(c32_a + c64_a), decltype(c64_a + c32_a)>::value, "+ should result same type");
+    static_assert(c32_a + c64_a == c2_cntr32_t(-333), "123 + -456 = -333");
+    static_assert(c32_a + c32_a == c2_cntr32_t(246), "123 + 123 = 246");
+    static_assert(c64_a + c32_a == c2_cntr32_t(-333), "-456 + 123 = 579");
+    static_assert(std::is_same<decltype(c32_a + 1), decltype(1 + c32_a)>::value, "+ should result same type");
+    static_assert(c32_a + 456 == c2_cntr32_t(579), "123 + 456 = 579");
+    static_assert(456 + c64_a == c2_cntr64_t(0), "456 + -456 = 0");
+    static_assert(std::is_same<decltype(c32_a - c64_a), decltype(c64_a - c32_a)>::value, "- should result same type");
+    static_assert(c32_a - c64_a == c2_cntr32_t(579), "123 - -456 = 579");
+    static_assert(c32_a - c32_a == c2_cntr32_t(0), "123 - 123 = 0");
+    static_assert(c64_a - c32_a == c2_cntr32_t(-579), "-456 - 123 = -579");
+    static_assert(std::is_same<decltype(c32_a - 1), decltype(1 - c32_a)>::value, "- should result same type");
+    static_assert(c32_a - 456 == c2_cntr32_t(-333), "123 - 456 = -333");
+    static_assert(456 - c64_a == c2_cntr64_t(912), "456 - -456 = 912");
+    static_assert(std::is_same<decltype(c32_a * c64_a), decltype(c64_a * c32_a)>::value, "* should result same type");
+    static_assert(c32_a * c64_a == c2_cntr32_t(-56088), "123 * -456 = -56088");
+    static_assert(c32_a * c32_a == c2_cntr32_t(15129), "123 * 123 = 15129");
+    static_assert(c64_a * c32_a == c2_cntr32_t(-56088), "-456 * 123 = -56088");
+    static_assert(std::is_same<decltype(c32_a * 1), decltype(1 * c32_a)>::value, "* should result same type");
+    static_assert(c32_a * 456 == c2_cntr32_t(56088), "123 * 456 = 56088");
+    static_assert(456 * c64_a == c2_cntr64_t(-207936), "456 * -456 = -207936");
+
+    static_assert((c32_a << 26u) == c2_cntr32_t(0xEC000000), "123 << 26 = 0xEC000000");
+
+    // sanity checks for unary operators
+    static_assert(c2_cntr32_t(1) == +c2_cntr32_t(1), "1 == +1");
+    static_assert(c2_cntr32_t(1) == -c2_cntr32_t(-1), "1 == --1");
+
+    // sanity checks for comparison
+    using c8_t = c2_cntr_t<uint8_t>;
+    static_assert(c8_t(-0x80) > c8_t(0x7f), "80 > 7F");
+    static_assert(c8_t(-0x80) >= c8_t(0x7f), "80 >= 7F");
+    static_assert(c8_t(0x7f) > c8_t(0x7e), "7F > 7E");
+    static_assert(c8_t(0x7f) >= c8_t(0x7e), "7F >= 7E");
+    static_assert(!(c8_t(-0x80) > c8_t(0)), "80 !> 00");
+    static_assert(!(c8_t(-0x80) >= c8_t(0)), "80 !>= 00");
+    static_assert(!(c8_t(-0x80) > c8_t(-0x80)), "80 !> 80");
+    static_assert(c8_t(-0x80) >= c8_t(-0x80), "80 >= 80");
+
+    static_assert(c8_t(-0x80) == c8_t(0x80), "80 == 80");
+    static_assert(!(c8_t(-0x80) == c8_t(0)), "80 != 0");
+    static_assert(c8_t(-0x80) != c8_t(0x7f), "80 != 7F");
+    static_assert(!(c8_t(0x7f) != c8_t(0x7f)), "80 != 7F");
+
+    static_assert(c8_t(0x7f) < c8_t(-0x80), "7F < 80");
+    static_assert(c8_t(0x7f) <= c8_t(-0x80), "7F < 80");
+    static_assert(c8_t(0x7e) < c8_t(0x7f), "7E < 7F");
+    static_assert(c8_t(0x7e) <= c8_t(0x7f), "7E < 7F");
+    static_assert(!(c8_t(-0x40) < c8_t(0x40)), "-40 !< 40");
+    static_assert(!(c8_t(-0x40) <= c8_t(0x40)), "-40 !<= 40");
+    static_assert(!(c8_t(-0x40) < c8_t(-0x40)), "-40 !< -40");
+    static_assert(c8_t(-0x40) <= c8_t(-0x40), "-40 <= -40");
+
+    static_assert(c2_cntr32_t(-0x7fffffff - 1) > c2_cntr32_t(0x7fffffff), "80 > 7F");
+    static_assert(!(c2_cntr32_t(-0x7fffffff - 1) > c2_cntr32_t(0)), "80 !> 00");
+    static_assert(c2_cntr32_t(1) == c2_cntr32_t(c2_cntr64_t(0x100000001ul)), "1 == 1");
+}
+
+class C2Test : public ::testing::Test {
+};
+
+TEST_F(C2Test, CounterTest) {
+    c2_cntr32_t c32_a(123);
+    c2_cntr64_t c64_a(-456);
+    EXPECT_EQ(c32_a += 3, c2_cntr32_t(126));
+    EXPECT_EQ(c32_a += c64_a, c2_cntr32_t(-330));
+    EXPECT_EQ(c32_a <<= 2u, c2_cntr32_t(-1320));
+    EXPECT_EQ(c64_a *= 3, c2_cntr64_t(-1368));
+    EXPECT_EQ(c32_a -= c64_a, c2_cntr32_t(48));
+    EXPECT_EQ(c32_a -= 40, c2_cntr32_t(8));
+    EXPECT_EQ(c32_a *= c32_a, c2_cntr32_t(64));
+}
+
diff --git a/media/codec2/tests/vndk/C2BufferTest.cpp b/media/codec2/tests/vndk/C2BufferTest.cpp
new file mode 100644
index 0000000..780994a
--- /dev/null
+++ b/media/codec2/tests/vndk/C2BufferTest.cpp
@@ -0,0 +1,768 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <C2AllocatorIon.h>
+#include <C2AllocatorGralloc.h>
+#include <C2Buffer.h>
+#include <C2BufferPriv.h>
+#include <C2ParamDef.h>
+
+#include <system/graphics.h>
+
+namespace android {
+
+class C2BufferUtilsTest : public ::testing::Test {
+    static void StaticSegmentTest() {
+        // constructor
+        static_assert(C2Segment(123u, 456u).offset == 123, "");
+        static_assert(C2Segment(123u, 456u).size == 456, "");
+
+        // empty
+        static_assert(!C2Segment(123u, 456u).isEmpty(), "");
+        static_assert(C2Segment(123u, 0u).isEmpty(), "");
+
+        // valid
+        static_assert(C2Segment(123u, 456u).isValid(), "");
+        static_assert(C2Segment(123u, ~123u).isValid(), "");
+        static_assert(!C2Segment(123u, 1 + ~123u).isValid(), "");
+
+        // bool()
+        static_assert(C2Segment(123u, 456u), "");
+        static_assert((bool)C2Segment(123u, ~123u), "");
+        static_assert(!bool(C2Segment(123u, 1 + ~123u)), "");
+        static_assert(!bool(C2Segment(123u, 0)), "");
+
+        // !
+        static_assert(!!C2Segment(123u, 456u), "");
+        static_assert(!!C2Segment(123u, ~123u), "");
+        static_assert(!C2Segment(123u, 1 + ~123u), "");
+        static_assert(!C2Segment(123u, 0), "");
+
+        // contains
+        static_assert(C2Segment(123u, ~123u).contains(C2Segment(123u, 0)), "");
+        static_assert(!C2Segment(123u, 1 + ~123u).contains(C2Segment(123u, 0)), "");
+        static_assert(C2Segment(123u, ~123u).contains(C2Segment(123u, ~123u)), "");
+        static_assert(!C2Segment(123u, ~123u).contains(C2Segment(123u, 1 + ~123u)), "");
+        static_assert(!C2Segment(123u, 1 + ~123u).contains(C2Segment(123u, 1 + ~123u)), "");
+        static_assert(!C2Segment(123u, ~123u).contains(C2Segment(122u, 2u)), "");
+        static_assert(C2Segment(123u, ~123u).contains(C2Segment(123u, 2u)), "");
+        static_assert(C2Segment(123u, 3u).contains(C2Segment(124u, 2u)), "");
+        static_assert(!C2Segment(123u, 3u).contains(C2Segment(125u, 2u)), "");
+
+        // ==
+        static_assert(C2Segment(123u, 456u) == C2Segment(123u, 456u), "");
+        static_assert(!(C2Segment(123u, 456u) == C2Segment(123u, 457u)), "");
+        static_assert(!(C2Segment(123u, 456u) == C2Segment(123u, 455u)), "");
+        static_assert(!(C2Segment(123u, 456u) == C2Segment(122u, 456u)), "");
+        static_assert(!(C2Segment(123u, 456u) == C2Segment(124u, 456u)), "");
+        static_assert(!(C2Segment(123u, 0u) == C2Segment(124u, 0u)), "");
+        static_assert(C2Segment(123u, 0u) == C2Segment(123u, 0u), "");
+        static_assert(C2Segment(123u, 1 + ~123u) == C2Segment(124u, 1 + ~124u), "");
+
+        // !=
+        static_assert(!(C2Segment(123u, 456u) != C2Segment(123u, 456u)), "");
+        static_assert(C2Segment(123u, 456u) != C2Segment(123u, 457u), "");
+        static_assert(C2Segment(123u, 456u) != C2Segment(123u, 455u), "");
+        static_assert(C2Segment(123u, 456u) != C2Segment(122u, 456u), "");
+        static_assert(C2Segment(123u, 456u) != C2Segment(124u, 456u), "");
+        static_assert(C2Segment(123u, 0u) != C2Segment(124u, 0u), "");
+        static_assert(!(C2Segment(123u, 0u) != C2Segment(123u, 0u)), "");
+        static_assert(!(C2Segment(123u, 1 + ~123u) != C2Segment(124u, 1 + ~124u)), "");
+
+        // <=
+        static_assert(C2Segment(123u, 456u) <= C2Segment(123u, 456u), "");
+        static_assert(C2Segment(123u, 456u) <= C2Segment(123u, 457u), "");
+        static_assert(C2Segment(123u, 456u) <= C2Segment(122u, 457u), "");
+        static_assert(!(C2Segment(123u, 457u) <= C2Segment(123u, 456u)), "");
+        static_assert(!(C2Segment(122u, 457u) <= C2Segment(123u, 456u)), "");
+        static_assert(!(C2Segment(123u, 457u) <= C2Segment(124u, 457u)), "");
+        static_assert(!(C2Segment(122u, 457u) <= C2Segment(123u, 457u)), "");
+        static_assert(!(C2Segment(122u, 0u) <= C2Segment(123u, 0u)), "");
+        static_assert(C2Segment(123u, 0u) <= C2Segment(122u, 1u), "");
+        static_assert(C2Segment(122u, 0u) <= C2Segment(122u, 1u), "");
+        static_assert(!(C2Segment(122u, ~122u) <= C2Segment(122u, 1 + ~122u)), "");
+        static_assert(!(C2Segment(122u, 1 + ~122u) <= C2Segment(122u, ~122u)), "");
+        static_assert(!(C2Segment(122u, 1 + ~122u) <= C2Segment(122u, 1 + ~122u)), "");
+
+        // <
+        static_assert(!(C2Segment(123u, 456u) < C2Segment(123u, 456u)), "");
+        static_assert(C2Segment(123u, 456u) < C2Segment(123u, 457u), "");
+        static_assert(C2Segment(123u, 456u) < C2Segment(122u, 457u), "");
+        static_assert(!(C2Segment(123u, 457u) < C2Segment(123u, 456u)), "");
+        static_assert(!(C2Segment(122u, 457u) < C2Segment(123u, 456u)), "");
+        static_assert(!(C2Segment(123u, 457u) < C2Segment(124u, 457u)), "");
+        static_assert(!(C2Segment(122u, 457u) < C2Segment(123u, 457u)), "");
+        static_assert(!(C2Segment(122u, 0u) < C2Segment(123u, 0u)), "");
+        static_assert(C2Segment(123u, 0u) < C2Segment(122u, 1u), "");
+        static_assert(C2Segment(122u, 0u) < C2Segment(122u, 1u), "");
+        static_assert(!(C2Segment(122u, ~122u) < C2Segment(122u, 1 + ~122u)), "");
+        static_assert(!(C2Segment(122u, 1 + ~122u) < C2Segment(122u, ~122u)), "");
+        static_assert(!(C2Segment(122u, 1 + ~122u) < C2Segment(122u, 1 + ~122u)), "");
+
+        // <=
+        static_assert(C2Segment(123u, 456u) >= C2Segment(123u, 456u), "");
+        static_assert(C2Segment(123u, 457u) >= C2Segment(123u, 456u), "");
+        static_assert(C2Segment(122u, 457u) >= C2Segment(123u, 456u), "");
+        static_assert(!(C2Segment(123u, 456u) >= C2Segment(123u, 457u)), "");
+        static_assert(!(C2Segment(123u, 456u) >= C2Segment(122u, 457u)), "");
+        static_assert(!(C2Segment(124u, 457u) >= C2Segment(123u, 457u)), "");
+        static_assert(!(C2Segment(123u, 457u) >= C2Segment(122u, 457u)), "");
+        static_assert(!(C2Segment(123u, 0u) >= C2Segment(122u, 0u)), "");
+        static_assert(C2Segment(122u, 1u) >= C2Segment(123u, 0u), "");
+        static_assert(C2Segment(122u, 1u) >= C2Segment(122u, 0u), "");
+        static_assert(!(C2Segment(122u, 1 + ~122u) >= C2Segment(122u, ~122u)), "");
+        static_assert(!(C2Segment(122u, ~122u) >= C2Segment(122u, 1 + ~122u)), "");
+        static_assert(!(C2Segment(122u, 1 + ~122u) >= C2Segment(122u, 1 + ~122u)), "");
+
+        // <
+        static_assert(!(C2Segment(123u, 456u) > C2Segment(123u, 456u)), "");
+        static_assert(C2Segment(123u, 457u) > C2Segment(123u, 456u), "");
+        static_assert(C2Segment(122u, 457u) > C2Segment(123u, 456u), "");
+        static_assert(!(C2Segment(123u, 456u) > C2Segment(123u, 457u)), "");
+        static_assert(!(C2Segment(123u, 456u) > C2Segment(122u, 457u)), "");
+        static_assert(!(C2Segment(124u, 457u) > C2Segment(123u, 457u)), "");
+        static_assert(!(C2Segment(123u, 457u) > C2Segment(122u, 457u)), "");
+        static_assert(!(C2Segment(123u, 0u) > C2Segment(122u, 0u)), "");
+        static_assert(C2Segment(122u, 1u) > C2Segment(123u, 0u), "");
+        static_assert(C2Segment(122u, 1u) > C2Segment(122u, 0u), "");
+        static_assert(!(C2Segment(122u, 1 + ~122u) > C2Segment(122u, ~122u)), "");
+        static_assert(!(C2Segment(122u, ~122u) > C2Segment(122u, 1 + ~122u)), "");
+        static_assert(!(C2Segment(122u, 1 + ~122u) > C2Segment(122u, 1 + ~122u)), "");
+
+        // end
+        static_assert(C2Segment(123u, 456u).end() == 579u, "");
+        static_assert(C2Segment(123u, 0u).end() == 123u, "");
+        static_assert(C2Segment(123u, ~123u).end() == 0xffffffffu, "");
+        static_assert(C2Segment(123u, 1 + ~123u).end() == 0u, "");
+
+        // intersect
+        static_assert(C2Segment(123u, 456u).intersect(C2Segment(123u, 456u)) == C2Segment(123u, 456u), "");
+        static_assert(C2Segment(123u, 456u).intersect(C2Segment(123u, 460u)) == C2Segment(123u, 456u), "");
+        static_assert(C2Segment(123u, 456u).intersect(C2Segment(124u, 460u)) == C2Segment(124u, 455u), "");
+        static_assert(C2Segment(123u, 456u).intersect(C2Segment(579u, 460u)) == C2Segment(579u, 0u), "");
+        static_assert(C2Segment(123u, 456u).intersect(C2Segment(589u, 460u)) == C2Segment(589u, ~9u /* -10 */), "");
+        static_assert(C2Segment(123u, 456u).intersect(C2Segment(123u, 455u)) == C2Segment(123u, 455u), "");
+        static_assert(C2Segment(123u, 456u).intersect(C2Segment(122u, 456u)) == C2Segment(123u, 455u), "");
+        static_assert(C2Segment(123u, 456u).intersect(C2Segment(0u, 123u)) == C2Segment(123u, 0u), "");
+        static_assert(C2Segment(123u, 456u).intersect(C2Segment(0u, 0u)) == C2Segment(123u, ~122u /* -123 */), "");
+
+        // normalize (change invalid segments to empty segments)
+        static_assert(C2Segment(123u, 456u).normalize() == C2Segment(123u, 456u), "");
+        static_assert(C2Segment(123u, ~123u).normalize() == C2Segment(123u, ~123u), "");
+        static_assert(C2Segment(123u, 1 + ~123u).normalize() == C2Segment(123u, 0u), "");
+
+        // note: normalize cannot be used to make this work
+        static_assert(C2Segment(123u, 456u).intersect(C2Segment(150u, ~150u)).normalize() == C2Segment(150u, 429u), "");
+        static_assert(C2Segment(123u, 456u).intersect(C2Segment(150u, 1 + ~150u)).normalize() != C2Segment(150u, 429u), "");
+        static_assert(C2Segment(123u, 456u).intersect(C2Segment(150u, 1 + ~150u)).normalize() == C2Segment(150u, 0u), "");
+
+        // saturate (change invalid segments to full segments up to max)
+        static_assert(C2Segment(123u, 456u).saturate() == C2Segment(123u, 456u), "");
+        static_assert(C2Segment(123u, ~123u).saturate() == C2Segment(123u, ~123u), "");
+        static_assert(C2Segment(123u, 1 + ~123u).saturate() == C2Segment(123u, ~123u), "");
+
+        // note: saturate can be used to make this work but only partially
+        static_assert(C2Segment(123u, 456u).intersect(C2Segment(150u, 1 + ~150u).saturate()).normalize() == C2Segment(150u, 429u), "");
+        static_assert(C2Segment(123u, 456u).intersect(C2Segment(0u, 100u).saturate()).normalize() == C2Segment(123u, 0u), "");
+        static_assert(C2Segment(123u, 456u).intersect(C2Segment(1000u, 100u).saturate()).normalize() != C2Segment(579u, 0u), "");
+        static_assert(C2Segment(123u, 456u).intersect(C2Segment(1000u, 100u).saturate()).normalize() == C2Segment(1000u, 0u), "");
+
+    }
+
+    static void StaticLinearRangeAndCapacityTest() {
+        class TestCapacity : public _C2LinearCapacityAspect {
+            using _C2LinearCapacityAspect::_C2LinearCapacityAspect;
+            friend class C2BufferUtilsTest;
+        };
+
+        class TestRange : public _C2LinearRangeAspect {
+            using _C2LinearRangeAspect::_C2LinearRangeAspect;
+            friend class C2BufferUtilsTest;
+        };
+
+        // _C2LinearCapacityAspect
+        static_assert(TestCapacity(0u).capacity() == 0u, "");
+        constexpr TestCapacity cap(123u);
+        static_assert(TestCapacity(&cap).capacity() == 123u, "");
+        static_assert(TestCapacity(nullptr).capacity() == 0u, "");
+
+        // _C2LinearCapacityRange
+        static_assert(TestRange(&cap).capacity() == 123u, "");
+        static_assert(TestRange(&cap).offset() == 0u, "");
+        static_assert(TestRange(&cap).size() == 123u, "");
+        static_assert(TestRange(&cap).endOffset() == 123u, "");
+
+        constexpr TestRange range(&cap, 50u, 100u);
+
+        static_assert(range.capacity() == 123u, "");
+        static_assert(range.offset() == 50u, "");
+        static_assert(range.size() == 73u, "");
+        static_assert(range.endOffset() == 123u, "");
+
+        static_assert(TestRange(&cap, 20u, 30u).capacity() == 123u, "");
+        static_assert(TestRange(&cap, 20u, 30u).offset() == 20u, "");
+        static_assert(TestRange(&cap, 20u, 30u).size() == 30u, "");
+        static_assert(TestRange(&cap, 20u, 30u).endOffset() == 50u, "");
+
+        static_assert(TestRange(&cap, 200u, 30u).capacity() == 123u, "");
+        static_assert(TestRange(&cap, 200u, 30u).offset() == 123u, "");
+        static_assert(TestRange(&cap, 200u, 30u).size() == 0u, "");
+        static_assert(TestRange(&cap, 200u, 30u).endOffset() == 123u, "");
+
+    }
+
+};
+
+
+class C2BufferTest : public ::testing::Test {
+public:
+    C2BufferTest()
+        : mBlockPoolId(C2BlockPool::PLATFORM_START),
+          mLinearAllocator(std::make_shared<C2AllocatorIon>('i')),
+          mSize(0u),
+          mAddr(nullptr),
+          mGraphicAllocator(std::make_shared<C2AllocatorGralloc>('g')) {
+    }
+
+    ~C2BufferTest() = default;
+
+    void allocateLinear(size_t capacity) {
+        c2_status_t err = mLinearAllocator->newLinearAllocation(
+                capacity,
+                { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
+                &mLinearAllocation);
+        if (err != C2_OK) {
+            mLinearAllocation.reset();
+            FAIL() << "C2Allocator::newLinearAllocation() failed: " << err;
+        }
+    }
+
+    void mapLinear(size_t offset, size_t size, uint8_t **addr) {
+        ASSERT_TRUE(mLinearAllocation);
+        c2_status_t err = mLinearAllocation->map(
+                offset,
+                size,
+                { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
+                // TODO: fence
+                nullptr,
+                &mAddr);
+        if (err != C2_OK) {
+            mAddr = nullptr;
+            FAIL() << "C2LinearAllocation::map() failed: " << err;
+        }
+        ASSERT_NE(nullptr, mAddr);
+        mSize = size;
+        *addr = (uint8_t *)mAddr;
+    }
+
+    void unmapLinear() {
+        ASSERT_TRUE(mLinearAllocation);
+        ASSERT_NE(nullptr, mAddr);
+        ASSERT_NE(0u, mSize);
+
+        // TODO: fence
+        ASSERT_EQ(C2_OK, mLinearAllocation->unmap(mAddr, mSize, nullptr));
+        mSize = 0u;
+        mAddr = nullptr;
+    }
+
+    std::shared_ptr<C2BlockPool> makeLinearBlockPool() {
+        return std::make_shared<C2PooledBlockPool>(mLinearAllocator, mBlockPoolId++);
+    }
+
+    void allocateGraphic(uint32_t width, uint32_t height) {
+        c2_status_t err = mGraphicAllocator->newGraphicAllocation(
+                width,
+                height,
+                HAL_PIXEL_FORMAT_YCBCR_420_888,
+                { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
+                &mGraphicAllocation);
+        if (err != C2_OK) {
+            mGraphicAllocation.reset();
+            FAIL() << "C2Allocator::newGraphicAllocation() failed: " << err;
+        }
+    }
+
+    void mapGraphic(C2Rect rect, C2PlanarLayout *layout, uint8_t **addr) {
+        ASSERT_TRUE(mGraphicAllocation);
+        c2_status_t err = mGraphicAllocation->map(
+                rect,
+                { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
+                // TODO: fence
+                nullptr,
+                layout,
+                addr);
+        if (err != C2_OK) {
+            addr[C2PlanarLayout::PLANE_Y] = nullptr;
+            addr[C2PlanarLayout::PLANE_U] = nullptr;
+            addr[C2PlanarLayout::PLANE_V] = nullptr;
+            FAIL() << "C2GraphicAllocation::map() failed: " << err;
+        }
+        mMappedRect = rect;
+        memcpy(mAddrGraphic, addr, sizeof(uint8_t*) * C2PlanarLayout::MAX_NUM_PLANES);
+    }
+
+    void unmapGraphic() {
+        ASSERT_TRUE(mGraphicAllocation);
+
+        // TODO: fence
+        ASSERT_EQ(C2_OK, mGraphicAllocation->unmap(mAddrGraphic, mMappedRect, nullptr));
+    }
+
+    std::shared_ptr<C2BlockPool> makeGraphicBlockPool() {
+        return std::make_shared<C2BasicGraphicBlockPool>(mGraphicAllocator);
+    }
+
+private:
+    C2BlockPool::local_id_t mBlockPoolId;
+    std::shared_ptr<C2Allocator> mLinearAllocator;
+    std::shared_ptr<C2LinearAllocation> mLinearAllocation;
+    size_t mSize;
+    void *mAddr;
+    C2Rect mMappedRect;
+    uint8_t* mAddrGraphic[C2PlanarLayout::MAX_NUM_PLANES];
+
+    std::shared_ptr<C2Allocator> mGraphicAllocator;
+    std::shared_ptr<C2GraphicAllocation> mGraphicAllocation;
+};
+
+TEST_F(C2BufferTest, LinearAllocationTest) {
+    constexpr size_t kCapacity = 1024u * 1024u;
+
+    allocateLinear(kCapacity);
+
+    uint8_t *addr = nullptr;
+    mapLinear(0u, kCapacity, &addr);
+    ASSERT_NE(nullptr, addr);
+
+    for (size_t i = 0; i < kCapacity; ++i) {
+        addr[i] = i % 100u;
+    }
+
+    unmapLinear();
+    addr = nullptr;
+
+    mapLinear(kCapacity / 3, kCapacity / 3, &addr);
+    ASSERT_NE(nullptr, addr);
+    for (size_t i = 0; i < kCapacity / 3; ++i) {
+        ASSERT_EQ((i + kCapacity / 3) % 100, addr[i]) << " at i = " << i;
+    }
+}
+
+TEST_F(C2BufferTest, BlockPoolTest) {
+    constexpr size_t kCapacity = 1024u * 1024u;
+
+    std::shared_ptr<C2BlockPool> blockPool(makeLinearBlockPool());
+
+    std::shared_ptr<C2LinearBlock> block;
+    ASSERT_EQ(C2_OK, blockPool->fetchLinearBlock(
+            kCapacity,
+            { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
+            &block));
+    ASSERT_TRUE(block);
+
+    C2Acquirable<C2WriteView> writeViewHolder = block->map();
+    C2WriteView writeView = writeViewHolder.get();
+    ASSERT_EQ(C2_OK, writeView.error());
+    ASSERT_EQ(kCapacity, writeView.capacity());
+    ASSERT_EQ(0u, writeView.offset());
+    ASSERT_EQ(kCapacity, writeView.size());
+
+    uint8_t *data = writeView.data();
+    ASSERT_NE(nullptr, data);
+    for (size_t i = 0; i < writeView.size(); ++i) {
+        data[i] = i % 100u;
+    }
+
+    writeView.setOffset(kCapacity / 3);
+    data = writeView.data();
+    ASSERT_NE(nullptr, data);
+    for (size_t i = 0; i < writeView.size(); ++i) {
+        ASSERT_EQ((i + kCapacity / 3) % 100u, data[i]) << " at i = " << i
+            << "; data = " << static_cast<void *>(data);
+    }
+
+    C2Fence fence;
+    C2ConstLinearBlock constBlock = block->share(
+            kCapacity / 3, kCapacity / 3, fence);
+
+    C2Acquirable<C2ReadView> readViewHolder = constBlock.map();
+    C2ReadView readView = readViewHolder.get();
+    ASSERT_EQ(C2_OK, readView.error());
+    ASSERT_EQ(kCapacity / 3, readView.capacity());
+
+    // TODO: fence
+    const uint8_t *constData = readView.data();
+    ASSERT_NE(nullptr, constData);
+    for (size_t i = 0; i < readView.capacity(); ++i) {
+        ASSERT_EQ((i + kCapacity / 3) % 100u, constData[i]) << " at i = " << i
+                << "; data = " << static_cast<void *>(data)
+                << "; constData = " << static_cast<const void *>(constData);
+    }
+
+    readView = readView.subView(333u, 100u);
+    ASSERT_EQ(C2_OK, readView.error());
+    ASSERT_EQ(100u, readView.capacity());
+
+    constData = readView.data();
+    ASSERT_NE(nullptr, constData);
+    for (size_t i = 0; i < readView.capacity(); ++i) {
+        ASSERT_EQ((i + 333u + kCapacity / 3) % 100u, constData[i]) << " at i = " << i;
+    }
+}
+
+void fillPlane(const C2Rect rect, const C2PlaneInfo info, uint8_t *addr, uint8_t value) {
+    for (uint32_t row = 0; row < rect.height / info.rowSampling; ++row) {
+        int32_t rowOffset = (row + rect.top / info.rowSampling) * info.rowInc;
+        for (uint32_t col = 0; col < rect.width / info.colSampling; ++col) {
+            int32_t colOffset = (col + rect.left / info.colSampling) * info.colInc;
+            addr[rowOffset + colOffset] = value;
+        }
+    }
+}
+
+bool verifyPlane(const C2Rect rect, const C2PlaneInfo info, const uint8_t *addr, uint8_t value) {
+    for (uint32_t row = 0; row < rect.height / info.rowSampling; ++row) {
+        int32_t rowOffset = (row + rect.top / info.rowSampling) * info.rowInc;
+        for (uint32_t col = 0; col < rect.width / info.colSampling; ++col) {
+            int32_t colOffset = (col + rect.left / info.colSampling) * info.colInc;
+            if (addr[rowOffset + colOffset] != value) {
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+TEST_F(C2BufferTest, GraphicAllocationTest) {
+    constexpr uint32_t kWidth = 320;
+    constexpr uint32_t kHeight = 240;
+
+    allocateGraphic(kWidth, kHeight);
+
+    uint8_t *addr[C2PlanarLayout::MAX_NUM_PLANES];
+    C2Rect rect(kWidth, kHeight);
+    C2PlanarLayout layout;
+    mapGraphic(rect, &layout, addr);
+    ASSERT_NE(nullptr, addr[C2PlanarLayout::PLANE_Y]);
+    ASSERT_NE(nullptr, addr[C2PlanarLayout::PLANE_U]);
+    ASSERT_NE(nullptr, addr[C2PlanarLayout::PLANE_V]);
+
+    uint8_t *y = addr[C2PlanarLayout::PLANE_Y];
+    C2PlaneInfo yInfo = layout.planes[C2PlanarLayout::PLANE_Y];
+    uint8_t *u = addr[C2PlanarLayout::PLANE_U];
+    C2PlaneInfo uInfo = layout.planes[C2PlanarLayout::PLANE_U];
+    uint8_t *v = addr[C2PlanarLayout::PLANE_V];
+    C2PlaneInfo vInfo = layout.planes[C2PlanarLayout::PLANE_V];
+
+    fillPlane(rect, yInfo, y, 0);
+    fillPlane(rect, uInfo, u, 0);
+    fillPlane(rect, vInfo, v, 0);
+    fillPlane(C2Rect(kWidth / 2, kHeight / 2).at(kWidth / 4, kHeight / 4), yInfo, y, 0x12);
+    fillPlane(C2Rect(kWidth / 2, kHeight / 2).at(kWidth / 4, kHeight / 4), uInfo, u, 0x34);
+    fillPlane(C2Rect(kWidth / 2, kHeight / 2).at(kWidth / 4, kHeight / 4), vInfo, v, 0x56);
+
+    unmapGraphic();
+
+    mapGraphic(rect, &layout, addr);
+    ASSERT_NE(nullptr, addr[C2PlanarLayout::PLANE_Y]);
+    ASSERT_NE(nullptr, addr[C2PlanarLayout::PLANE_U]);
+    ASSERT_NE(nullptr, addr[C2PlanarLayout::PLANE_V]);
+
+    y = addr[C2PlanarLayout::PLANE_Y];
+    yInfo = layout.planes[C2PlanarLayout::PLANE_Y];
+    u = addr[C2PlanarLayout::PLANE_U];
+    uInfo = layout.planes[C2PlanarLayout::PLANE_U];
+    v = addr[C2PlanarLayout::PLANE_V];
+    vInfo = layout.planes[C2PlanarLayout::PLANE_V];
+
+    ASSERT_TRUE(verifyPlane(C2Rect(kWidth / 2, kHeight / 2).at(kWidth / 4, kHeight / 4), yInfo, y, 0x12));
+    ASSERT_TRUE(verifyPlane(C2Rect(kWidth / 2, kHeight / 2).at(kWidth / 4, kHeight / 4), uInfo, u, 0x34));
+    ASSERT_TRUE(verifyPlane(C2Rect(kWidth / 2, kHeight / 2).at(kWidth / 4, kHeight / 4), vInfo, v, 0x56));
+    ASSERT_TRUE(verifyPlane({ kWidth, kHeight / 4 }, yInfo, y, 0));
+    ASSERT_TRUE(verifyPlane({ kWidth, kHeight / 4 }, uInfo, u, 0));
+    ASSERT_TRUE(verifyPlane({ kWidth, kHeight / 4 }, vInfo, v, 0));
+    ASSERT_TRUE(verifyPlane({ kWidth / 4, kHeight }, yInfo, y, 0));
+    ASSERT_TRUE(verifyPlane({ kWidth / 4, kHeight }, uInfo, u, 0));
+    ASSERT_TRUE(verifyPlane({ kWidth / 4, kHeight }, vInfo, v, 0));
+}
+
+TEST_F(C2BufferTest, GraphicBlockPoolTest) {
+    constexpr uint32_t kWidth = 320;
+    constexpr uint32_t kHeight = 240;
+
+    std::shared_ptr<C2BlockPool> blockPool(makeGraphicBlockPool());
+
+    std::shared_ptr<C2GraphicBlock> block;
+    ASSERT_EQ(C2_OK, blockPool->fetchGraphicBlock(
+            kWidth,
+            kHeight,
+            HAL_PIXEL_FORMAT_YCBCR_420_888,
+            { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
+            &block));
+    ASSERT_TRUE(block);
+
+    C2Acquirable<C2GraphicView> graphicViewHolder = block->map();
+    C2GraphicView graphicView = graphicViewHolder.get();
+    ASSERT_EQ(C2_OK, graphicView.error());
+    ASSERT_EQ(kWidth, graphicView.width());
+    ASSERT_EQ(kHeight, graphicView.height());
+
+    uint8_t *const *data = graphicView.data();
+    C2PlanarLayout layout = graphicView.layout();
+    ASSERT_NE(nullptr, data);
+
+    uint8_t *y = data[C2PlanarLayout::PLANE_Y];
+    C2PlaneInfo yInfo = layout.planes[C2PlanarLayout::PLANE_Y];
+    uint8_t *u = data[C2PlanarLayout::PLANE_U];
+    C2PlaneInfo uInfo = layout.planes[C2PlanarLayout::PLANE_U];
+    uint8_t *v = data[C2PlanarLayout::PLANE_V];
+    C2PlaneInfo vInfo = layout.planes[C2PlanarLayout::PLANE_V];
+
+    fillPlane({ kWidth, kHeight }, yInfo, y, 0);
+    fillPlane({ kWidth, kHeight }, uInfo, u, 0);
+    fillPlane({ kWidth, kHeight }, vInfo, v, 0);
+    fillPlane(C2Rect(kWidth / 2, kHeight / 2).at(kWidth / 4, kHeight / 4), yInfo, y, 0x12);
+    fillPlane(C2Rect(kWidth / 2, kHeight / 2).at(kWidth / 4, kHeight / 4), uInfo, u, 0x34);
+    fillPlane(C2Rect(kWidth / 2, kHeight / 2).at(kWidth / 4, kHeight / 4), vInfo, v, 0x56);
+
+    C2Fence fence;
+    C2ConstGraphicBlock constBlock = block->share(C2Rect(kWidth, kHeight), fence);
+    block.reset();
+
+    C2Acquirable<const C2GraphicView> constViewHolder = constBlock.map();
+    const C2GraphicView constGraphicView = constViewHolder.get();
+    ASSERT_EQ(C2_OK, constGraphicView.error());
+    ASSERT_EQ(kWidth, constGraphicView.width());
+    ASSERT_EQ(kHeight, constGraphicView.height());
+
+    const uint8_t *const *constData = constGraphicView.data();
+    layout = graphicView.layout();
+    ASSERT_NE(nullptr, constData);
+
+    const uint8_t *cy = constData[C2PlanarLayout::PLANE_Y];
+    yInfo = layout.planes[C2PlanarLayout::PLANE_Y];
+    const uint8_t *cu = constData[C2PlanarLayout::PLANE_U];
+    uInfo = layout.planes[C2PlanarLayout::PLANE_U];
+    const uint8_t *cv = constData[C2PlanarLayout::PLANE_V];
+    vInfo = layout.planes[C2PlanarLayout::PLANE_V];
+
+    ASSERT_TRUE(verifyPlane(C2Rect(kWidth / 2, kHeight / 2).at(kWidth / 4, kHeight / 4), yInfo, cy, 0x12));
+    ASSERT_TRUE(verifyPlane(C2Rect(kWidth / 2, kHeight / 2).at(kWidth / 4, kHeight / 4), uInfo, cu, 0x34));
+    ASSERT_TRUE(verifyPlane(C2Rect(kWidth / 2, kHeight / 2).at(kWidth / 4, kHeight / 4), vInfo, cv, 0x56));
+    ASSERT_TRUE(verifyPlane({ kWidth, kHeight / 4 }, yInfo, cy, 0));
+    ASSERT_TRUE(verifyPlane({ kWidth, kHeight / 4 }, uInfo, cu, 0));
+    ASSERT_TRUE(verifyPlane({ kWidth, kHeight / 4 }, vInfo, cv, 0));
+    ASSERT_TRUE(verifyPlane({ kWidth / 4, kHeight }, yInfo, cy, 0));
+    ASSERT_TRUE(verifyPlane({ kWidth / 4, kHeight }, uInfo, cu, 0));
+    ASSERT_TRUE(verifyPlane({ kWidth / 4, kHeight }, vInfo, cv, 0));
+}
+
+class BufferData : public C2BufferData {
+public:
+    explicit BufferData(const std::vector<C2ConstLinearBlock> &blocks) : C2BufferData(blocks) {}
+    explicit BufferData(const std::vector<C2ConstGraphicBlock> &blocks) : C2BufferData(blocks) {}
+};
+
+class Buffer : public C2Buffer {
+public:
+    explicit Buffer(const std::vector<C2ConstLinearBlock> &blocks) : C2Buffer(blocks) {}
+    explicit Buffer(const std::vector<C2ConstGraphicBlock> &blocks) : C2Buffer(blocks) {}
+};
+
+TEST_F(C2BufferTest, BufferDataTest) {
+    std::shared_ptr<C2BlockPool> linearBlockPool(makeLinearBlockPool());
+    std::shared_ptr<C2BlockPool> graphicBlockPool(makeGraphicBlockPool());
+
+    constexpr uint32_t kWidth1 = 320;
+    constexpr uint32_t kHeight1 = 240;
+    constexpr C2Rect kCrop1(kWidth1, kHeight1);
+    constexpr uint32_t kWidth2 = 176;
+    constexpr uint32_t kHeight2 = 144;
+    constexpr C2Rect kCrop2(kWidth2, kHeight2);
+    constexpr size_t kCapacity1 = 1024u;
+    constexpr size_t kCapacity2 = 2048u;
+
+    std::shared_ptr<C2LinearBlock> linearBlock1;
+    std::shared_ptr<C2LinearBlock> linearBlock2;
+    ASSERT_EQ(C2_OK, linearBlockPool->fetchLinearBlock(
+            kCapacity1,
+            { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
+            &linearBlock1));
+    ASSERT_EQ(C2_OK, linearBlockPool->fetchLinearBlock(
+            kCapacity2,
+            { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
+            &linearBlock2));
+    std::shared_ptr<C2GraphicBlock> graphicBlock1;
+    std::shared_ptr<C2GraphicBlock> graphicBlock2;
+    ASSERT_EQ(C2_OK, graphicBlockPool->fetchGraphicBlock(
+            kWidth1,
+            kHeight1,
+            HAL_PIXEL_FORMAT_YCBCR_420_888,
+            { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
+            &graphicBlock1));
+    ASSERT_EQ(C2_OK, graphicBlockPool->fetchGraphicBlock(
+            kWidth2,
+            kHeight2,
+            HAL_PIXEL_FORMAT_YCBCR_420_888,
+            { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
+            &graphicBlock2));
+
+    std::shared_ptr<C2BufferData> data(new BufferData({ linearBlock1->share(0, kCapacity1, C2Fence()) }));
+    EXPECT_EQ(C2BufferData::LINEAR, data->type());
+    ASSERT_EQ(1u, data->linearBlocks().size());
+    EXPECT_EQ(linearBlock1->handle(), data->linearBlocks().front().handle());
+    EXPECT_TRUE(data->graphicBlocks().empty());
+
+    data.reset(new BufferData({
+        linearBlock1->share(0, kCapacity1, C2Fence()),
+        linearBlock2->share(0, kCapacity2, C2Fence()),
+    }));
+    EXPECT_EQ(C2BufferData::LINEAR_CHUNKS, data->type());
+    ASSERT_EQ(2u, data->linearBlocks().size());
+    EXPECT_EQ(linearBlock1->handle(), data->linearBlocks().front().handle());
+    EXPECT_EQ(linearBlock2->handle(), data->linearBlocks().back().handle());
+    EXPECT_TRUE(data->graphicBlocks().empty());
+
+    data.reset(new BufferData({ graphicBlock1->share(kCrop1, C2Fence()) }));
+    EXPECT_EQ(C2BufferData::GRAPHIC, data->type());
+    ASSERT_EQ(1u, data->graphicBlocks().size());
+    EXPECT_EQ(graphicBlock1->handle(), data->graphicBlocks().front().handle());
+    EXPECT_TRUE(data->linearBlocks().empty());
+
+    data.reset(new BufferData({
+        graphicBlock1->share(kCrop1, C2Fence()),
+        graphicBlock2->share(kCrop2, C2Fence()),
+    }));
+    EXPECT_EQ(C2BufferData::GRAPHIC_CHUNKS, data->type());
+    ASSERT_EQ(2u, data->graphicBlocks().size());
+    EXPECT_EQ(graphicBlock1->handle(), data->graphicBlocks().front().handle());
+    EXPECT_EQ(graphicBlock2->handle(), data->graphicBlocks().back().handle());
+    EXPECT_TRUE(data->linearBlocks().empty());
+}
+
+void DestroyCallback(const C2Buffer * /* buf */, void *arg) {
+    std::function<void(void)> *cb = (std::function<void(void)> *)arg;
+    (*cb)();
+}
+
+enum : uint32_t {
+    kParamIndexNumber1,
+    kParamIndexNumber2,
+};
+
+typedef C2GlobalParam<C2Info, C2Int32Value, kParamIndexNumber1> C2Number1Info;
+typedef C2GlobalParam<C2Info, C2Int32Value, kParamIndexNumber2> C2Number2Info;
+
+TEST_F(C2BufferTest, BufferTest) {
+    std::shared_ptr<C2BlockPool> alloc(makeLinearBlockPool());
+    constexpr size_t kCapacity = 1024u;
+    std::shared_ptr<C2LinearBlock> block;
+
+    ASSERT_EQ(C2_OK, alloc->fetchLinearBlock(
+            kCapacity,
+            { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
+            &block));
+
+    std::atomic_bool destroyed(false);
+    std::function<void(void)> arg = [&destroyed](){ destroyed = true; };
+
+    std::shared_ptr<C2Buffer> buffer(new Buffer( { block->share(0, kCapacity, C2Fence()) }));
+    ASSERT_EQ(C2_OK, buffer->registerOnDestroyNotify(&DestroyCallback, &arg));
+    EXPECT_FALSE(destroyed);
+    ASSERT_EQ(C2_DUPLICATE, buffer->registerOnDestroyNotify(&DestroyCallback, &arg));
+    buffer.reset();
+    EXPECT_TRUE(destroyed);
+
+    buffer.reset(new Buffer( { block->share(0, kCapacity, C2Fence()) }));
+    destroyed = false;
+    ASSERT_EQ(C2_OK, buffer->registerOnDestroyNotify(&DestroyCallback, &arg));
+    EXPECT_FALSE(destroyed);
+    ASSERT_EQ(C2_NOT_FOUND, buffer->unregisterOnDestroyNotify(&DestroyCallback, nullptr));
+    ASSERT_EQ(C2_OK, buffer->unregisterOnDestroyNotify(&DestroyCallback, &arg));
+    EXPECT_FALSE(destroyed);
+    ASSERT_EQ(C2_NOT_FOUND, buffer->unregisterOnDestroyNotify(&DestroyCallback, &arg));
+    buffer.reset();
+    EXPECT_FALSE(destroyed);
+
+    std::shared_ptr<C2Info> info1(new C2Number1Info(1));
+    std::shared_ptr<C2Info> info2(new C2Number2Info(2));
+    buffer.reset(new Buffer( { block->share(0, kCapacity, C2Fence()) }));
+    EXPECT_TRUE(buffer->info().empty());
+    EXPECT_FALSE(buffer->hasInfo(info1->type()));
+    EXPECT_FALSE(buffer->hasInfo(info2->type()));
+
+    ASSERT_EQ(C2_OK, buffer->setInfo(info1));
+    EXPECT_EQ(1u, buffer->info().size());
+    EXPECT_EQ(*info1, *buffer->info().front());
+    EXPECT_TRUE(buffer->hasInfo(info1->type()));
+    EXPECT_FALSE(buffer->hasInfo(info2->type()));
+
+    ASSERT_EQ(C2_OK, buffer->setInfo(info2));
+    EXPECT_EQ(2u, buffer->info().size());
+    EXPECT_TRUE(buffer->hasInfo(info1->type()));
+    EXPECT_TRUE(buffer->hasInfo(info2->type()));
+
+    std::shared_ptr<C2Info> removed = buffer->removeInfo(info1->type());
+    ASSERT_TRUE(removed);
+    EXPECT_EQ(*removed, *info1);
+    EXPECT_EQ(1u, buffer->info().size());
+    EXPECT_EQ(*info2, *buffer->info().front());
+    EXPECT_FALSE(buffer->hasInfo(info1->type()));
+    EXPECT_TRUE(buffer->hasInfo(info2->type()));
+
+    removed = buffer->removeInfo(info1->type());
+    ASSERT_FALSE(removed);
+    EXPECT_EQ(1u, buffer->info().size());
+    EXPECT_FALSE(buffer->hasInfo(info1->type()));
+    EXPECT_TRUE(buffer->hasInfo(info2->type()));
+
+    std::shared_ptr<C2Info> info3(new C2Number2Info(3));
+    ASSERT_EQ(C2_OK, buffer->setInfo(info3));
+    EXPECT_EQ(1u, buffer->info().size());
+    EXPECT_FALSE(buffer->hasInfo(info1->type()));
+    EXPECT_TRUE(buffer->hasInfo(info2->type()));
+
+    removed = buffer->removeInfo(info2->type());
+    ASSERT_TRUE(removed);
+    EXPECT_EQ(*info3, *removed);
+    EXPECT_TRUE(buffer->info().empty());
+    EXPECT_FALSE(buffer->hasInfo(info1->type()));
+    EXPECT_FALSE(buffer->hasInfo(info2->type()));
+}
+
+TEST_F(C2BufferTest, MultipleLinearMapTest) {
+    std::shared_ptr<C2BlockPool> pool(makeLinearBlockPool());
+    constexpr size_t kCapacity = 524288u;
+    for (int i = 0; i < 100; ++i) {
+        std::vector<C2WriteView> wViews;
+        std::vector<C2ReadView> rViews;
+        for (int j = 0; j < 16; ++j) {
+            std::shared_ptr<C2LinearBlock> block;
+            ASSERT_EQ(C2_OK, pool->fetchLinearBlock(
+                    kCapacity,
+                    { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
+                    &block));
+            wViews.push_back(block->map().get());
+            C2ConstLinearBlock cBlock = block->share(0, kCapacity / 2, C2Fence());
+            rViews.push_back(cBlock.map().get());
+        }
+    }
+}
+
+} // namespace android
diff --git a/media/codec2/vndk/Android.bp b/media/codec2/vndk/Android.bp
new file mode 100644
index 0000000..b6ddfab
--- /dev/null
+++ b/media/codec2/vndk/Android.bp
@@ -0,0 +1,105 @@
+cc_library_headers {
+    name: "libcodec2_internal",
+
+    export_include_dirs: [
+        "internal",
+    ],
+
+    // TODO: Remove this when this module is moved back to frameworks/av.
+    vendor_available: true,
+}
+
+// !!!DO NOT DEPEND ON THIS SHARED LIBRARY DIRECTLY!!!
+// use libcodec2-impl-defaults instead
+cc_library_shared {
+    name: "libcodec2_vndk",
+    vendor_available: true,
+
+    srcs: [
+        "C2AllocatorIon.cpp",
+        "C2AllocatorGralloc.cpp",
+        "C2Buffer.cpp",
+        "C2Config.cpp",
+        "C2PlatformStorePluginLoader.cpp",
+        "C2Store.cpp",
+        "platform/C2BqBuffer.cpp",
+        "types.cpp",
+        "util/C2Debug.cpp",
+        "util/C2InterfaceHelper.cpp",
+        "util/C2InterfaceUtils.cpp",
+        "util/C2ParamUtils.cpp",
+    ],
+
+    export_include_dirs: [
+        "include",
+    ],
+
+    export_shared_lib_headers: [
+        "libbase",
+        "android.hardware.media.bufferpool@2.0",
+    ],
+
+    local_include_dirs: [
+        "internal",
+    ],
+
+    header_libs: [
+        "media_plugin_headers",
+        "libcodec2_headers",
+    ],
+
+    shared_libs: [
+        "android.hardware.graphics.allocator@2.0",
+        "android.hardware.graphics.allocator@3.0",
+        "android.hardware.graphics.bufferqueue@2.0",
+        "android.hardware.graphics.mapper@2.0",
+        "android.hardware.graphics.mapper@3.0",
+        "android.hardware.media.bufferpool@2.0",
+        "libbase",
+        "libbinder",
+        "libcutils",
+        "libdl",
+        "libhardware",
+        "libhidlbase",
+        "libion",
+        "libfmq",
+        "liblog",
+        "libnativewindow",
+        "libstagefright_foundation",
+        "libstagefright_bufferpool@2.0",
+        "libui",
+        "libutils",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+}
+
+// public dependency for implementing Codec 2 components
+cc_defaults {
+    name: "libcodec2-impl-defaults",
+
+    shared_libs: [
+        "libbase", // for C2_LOG
+        "liblog", // for ALOG
+        "libcodec2",
+        "libcodec2_vndk",
+        "libutils",
+    ],
+}
+
+// public dependency for implementing Codec 2 framework utilities
+// THIS IS ONLY FOR FRAMEWORK USE ONLY
+cc_defaults {
+    name: "libcodec2-internal-defaults",
+    defaults: ["libcodec2-impl-defaults"],
+
+    shared_libs: [
+        "libcutils", // for properties
+    ],
+
+    // TODO: separate internal headers so they can be exposed here
+}
+
diff --git a/media/codec2/vndk/C2AllocatorGralloc.cpp b/media/codec2/vndk/C2AllocatorGralloc.cpp
new file mode 100644
index 0000000..af97e61
--- /dev/null
+++ b/media/codec2/vndk/C2AllocatorGralloc.cpp
@@ -0,0 +1,1152 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2AllocatorGralloc"
+#include <utils/Log.h>
+
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
+#include <android/hardware/graphics/mapper/3.0/IMapper.h>
+#include <cutils/native_handle.h>
+#include <hardware/gralloc.h>
+
+#include <C2AllocatorGralloc.h>
+#include <C2Buffer.h>
+#include <C2PlatformSupport.h>
+
+namespace android {
+
+namespace /* unnamed */ {
+    enum : uint64_t {
+        /**
+         * Usage mask that is passed through from gralloc to Codec 2.0 usage.
+         */
+        PASSTHROUGH_USAGE_MASK =
+            ~(GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_PROTECTED)
+    };
+
+    // verify that passthrough mask is within the platform mask
+    static_assert((~C2MemoryUsage::PLATFORM_MASK & PASSTHROUGH_USAGE_MASK) == 0, "");
+} // unnamed
+
+C2MemoryUsage C2AndroidMemoryUsage::FromGrallocUsage(uint64_t usage) {
+    // gralloc does not support WRITE_PROTECTED
+    return C2MemoryUsage(
+            ((usage & GRALLOC_USAGE_SW_READ_MASK) ? C2MemoryUsage::CPU_READ : 0) |
+            ((usage & GRALLOC_USAGE_SW_WRITE_MASK) ? C2MemoryUsage::CPU_WRITE : 0) |
+            ((usage & GRALLOC_USAGE_PROTECTED) ? C2MemoryUsage::READ_PROTECTED : 0) |
+            (usage & PASSTHROUGH_USAGE_MASK));
+}
+
+uint64_t C2AndroidMemoryUsage::asGrallocUsage() const {
+    // gralloc does not support WRITE_PROTECTED
+    return (((expected & C2MemoryUsage::CPU_READ) ? GRALLOC_USAGE_SW_READ_OFTEN : 0) |
+            ((expected & C2MemoryUsage::CPU_WRITE) ? GRALLOC_USAGE_SW_WRITE_OFTEN : 0) |
+            ((expected & C2MemoryUsage::READ_PROTECTED) ? GRALLOC_USAGE_PROTECTED : 0) |
+            (expected & PASSTHROUGH_USAGE_MASK));
+}
+
+using ::android::hardware::hidl_handle;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::graphics::common::V1_0::BufferUsage;
+using PixelFormat2 = ::android::hardware::graphics::common::V1_0::PixelFormat;
+using PixelFormat3 = ::android::hardware::graphics::common::V1_2::PixelFormat;
+
+using IAllocator2 = ::android::hardware::graphics::allocator::V2_0::IAllocator;
+using BufferDescriptor2 = ::android::hardware::graphics::mapper::V2_0::BufferDescriptor;
+using Error2 = ::android::hardware::graphics::mapper::V2_0::Error;
+using IMapper2 = ::android::hardware::graphics::mapper::V2_0::IMapper;
+
+using IAllocator3 = ::android::hardware::graphics::allocator::V3_0::IAllocator;
+using BufferDescriptor3 = ::android::hardware::graphics::mapper::V3_0::BufferDescriptor;
+using Error3 = ::android::hardware::graphics::mapper::V3_0::Error;
+using IMapper3 = ::android::hardware::graphics::mapper::V3_0::IMapper;
+
+namespace /* unnamed */ {
+
+struct BufferDescriptorInfo2 {
+    IMapper2::BufferDescriptorInfo mapperInfo;
+    uint32_t stride;
+};
+
+struct BufferDescriptorInfo3 {
+    IMapper3::BufferDescriptorInfo mapperInfo;
+    uint32_t stride;
+};
+
+/* ===================================== GRALLOC ALLOCATION ==================================== */
+c2_status_t maperr2error(Error2 maperr) {
+    switch (maperr) {
+        case Error2::NONE:           return C2_OK;
+        case Error2::BAD_DESCRIPTOR: return C2_BAD_VALUE;
+        case Error2::BAD_BUFFER:     return C2_BAD_VALUE;
+        case Error2::BAD_VALUE:      return C2_BAD_VALUE;
+        case Error2::NO_RESOURCES:   return C2_NO_MEMORY;
+        case Error2::UNSUPPORTED:    return C2_CANNOT_DO;
+    }
+    return C2_CORRUPTED;
+}
+
+c2_status_t maperr2error(Error3 maperr) {
+    switch (maperr) {
+        case Error3::NONE:           return C2_OK;
+        case Error3::BAD_DESCRIPTOR: return C2_BAD_VALUE;
+        case Error3::BAD_BUFFER:     return C2_BAD_VALUE;
+        case Error3::BAD_VALUE:      return C2_BAD_VALUE;
+        case Error3::NO_RESOURCES:   return C2_NO_MEMORY;
+        case Error3::UNSUPPORTED:    return C2_CANNOT_DO;
+    }
+    return C2_CORRUPTED;
+}
+
+bool native_handle_is_invalid(const native_handle_t *const handle) {
+    // perform basic validation of a native handle
+    if (handle == nullptr) {
+        // null handle is considered valid
+        return false;
+    }
+    return ((size_t)handle->version != sizeof(native_handle_t) ||
+            handle->numFds < 0 ||
+            handle->numInts < 0 ||
+            // for sanity assume handles must occupy less memory than INT_MAX bytes
+            handle->numFds > int((INT_MAX - handle->version) / sizeof(int)) - handle->numInts);
+}
+
+class C2HandleGralloc : public C2Handle {
+private:
+    struct ExtraData {
+        uint32_t width;
+        uint32_t height;
+        uint32_t format;
+        uint32_t usage_lo;
+        uint32_t usage_hi;
+        uint32_t stride;
+        uint32_t generation;
+        uint32_t igbp_id_lo;
+        uint32_t igbp_id_hi;
+        uint32_t igbp_slot;
+        uint32_t magic;
+    };
+
+    enum {
+        NUM_INTS = sizeof(ExtraData) / sizeof(int),
+    };
+    const static uint32_t MAGIC = '\xc2gr\x00';
+
+    static
+    const ExtraData* getExtraData(const C2Handle *const handle) {
+        if (handle == nullptr
+                || native_handle_is_invalid(handle)
+                || handle->numInts < NUM_INTS) {
+            return nullptr;
+        }
+        return reinterpret_cast<const ExtraData*>(
+                &handle->data[handle->numFds + handle->numInts - NUM_INTS]);
+    }
+
+    static
+    ExtraData *getExtraData(C2Handle *const handle) {
+        return const_cast<ExtraData *>(getExtraData(const_cast<const C2Handle *const>(handle)));
+    }
+
+public:
+    void getIgbpData(uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) const {
+        const ExtraData *ed = getExtraData(this);
+        *generation = ed->generation;
+        *igbp_id = unsigned(ed->igbp_id_lo) | uint64_t(unsigned(ed->igbp_id_hi)) << 32;
+        *igbp_slot = ed->igbp_slot;
+    }
+
+    static bool isValid(const C2Handle *const o) {
+        if (o == nullptr) { // null handle is always valid
+            return true;
+        }
+        const ExtraData *xd = getExtraData(o);
+        // we cannot validate width/height/format/usage without accessing gralloc driver
+        return xd != nullptr && xd->magic == MAGIC;
+    }
+
+    static C2HandleGralloc* WrapAndMoveNativeHandle(
+            const native_handle_t *const handle,
+            uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
+            uint32_t stride, uint32_t generation, uint64_t igbp_id = 0, uint32_t igbp_slot = 0) {
+        //CHECK(handle != nullptr);
+        if (native_handle_is_invalid(handle) ||
+            handle->numInts > int((INT_MAX - handle->version) / sizeof(int)) - NUM_INTS - handle->numFds) {
+            return nullptr;
+        }
+        ExtraData xd = {
+            width, height, format, uint32_t(usage & 0xFFFFFFFF), uint32_t(usage >> 32),
+            stride, generation, uint32_t(igbp_id & 0xFFFFFFFF), uint32_t(igbp_id >> 32),
+            igbp_slot, MAGIC
+        };
+        native_handle_t *res = native_handle_create(handle->numFds, handle->numInts + NUM_INTS);
+        if (res != nullptr) {
+            memcpy(&res->data, &handle->data, sizeof(int) * (handle->numFds + handle->numInts));
+            *getExtraData(res) = xd;
+        }
+        return reinterpret_cast<C2HandleGralloc *>(res);
+    }
+
+    static C2HandleGralloc* WrapNativeHandle(
+            const native_handle_t *const handle,
+            uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
+            uint32_t stride, uint32_t generation, uint64_t igbp_id = 0, uint32_t igbp_slot = 0) {
+        if (handle == nullptr) {
+            return nullptr;
+        }
+        native_handle_t *clone = native_handle_clone(handle);
+        if (clone == nullptr) {
+            return nullptr;
+        }
+        C2HandleGralloc *res = WrapAndMoveNativeHandle(
+                clone, width, height, format, usage, stride, generation, igbp_id, igbp_slot);
+        if (res == nullptr) {
+            native_handle_close(clone);
+        }
+        native_handle_delete(clone);
+        return res;
+    }
+
+    static bool MigrateNativeHandle(
+            native_handle_t *handle,
+            uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
+        if (handle == nullptr || !isValid(handle)) {
+            return false;
+        }
+        ExtraData *ed = getExtraData(handle);
+        if (!ed) return false;
+        ed->generation = generation;
+        ed->igbp_id_lo = uint32_t(igbp_id & 0xFFFFFFFF);
+        ed->igbp_id_hi = uint32_t(igbp_id >> 32);
+        ed->igbp_slot = igbp_slot;
+        return true;
+    }
+
+
+    static native_handle_t* UnwrapNativeHandle(
+            const C2Handle *const handle) {
+        const ExtraData *xd = getExtraData(handle);
+        if (xd == nullptr || xd->magic != MAGIC) {
+            return nullptr;
+        }
+        native_handle_t *res = native_handle_create(handle->numFds, handle->numInts - NUM_INTS);
+        if (res != nullptr) {
+            memcpy(&res->data, &handle->data, sizeof(int) * (res->numFds + res->numInts));
+        }
+        return res;
+    }
+
+    static const C2HandleGralloc* Import(
+            const C2Handle *const handle,
+            uint32_t *width, uint32_t *height, uint32_t *format,
+            uint64_t *usage, uint32_t *stride,
+            uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
+        const ExtraData *xd = getExtraData(handle);
+        if (xd == nullptr) {
+            return nullptr;
+        }
+        *width = xd->width;
+        *height = xd->height;
+        *format = xd->format;
+        *usage = xd->usage_lo | (uint64_t(xd->usage_hi) << 32);
+        *stride = xd->stride;
+        *generation = xd->generation;
+        *igbp_id = xd->igbp_id_lo | (uint64_t(xd->igbp_id_hi) << 32);
+        *igbp_slot = xd->igbp_slot;
+        return reinterpret_cast<const C2HandleGralloc *>(handle);
+    }
+};
+
+} // unnamed namespace
+
+native_handle_t *UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle) {
+    return C2HandleGralloc::UnwrapNativeHandle(handle);
+}
+
+C2Handle *WrapNativeCodec2GrallocHandle(
+        const native_handle_t *const handle,
+        uint32_t width, uint32_t height, uint32_t format, uint64_t usage, uint32_t stride,
+        uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
+    return C2HandleGralloc::WrapNativeHandle(handle, width, height, format, usage, stride,
+                                             generation, igbp_id, igbp_slot);
+}
+
+bool MigrateNativeCodec2GrallocHandle(
+        native_handle_t *handle,
+        uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
+    return C2HandleGralloc::MigrateNativeHandle(handle, generation, igbp_id, igbp_slot);
+}
+
+
+class C2AllocationGralloc : public C2GraphicAllocation {
+public:
+    virtual ~C2AllocationGralloc() override;
+
+    virtual c2_status_t map(
+            C2Rect rect, C2MemoryUsage usage, C2Fence *fence,
+            C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) override;
+    virtual c2_status_t unmap(
+            uint8_t **addr /* nonnull */, C2Rect rect, C2Fence *fence /* nullable */) override;
+    virtual C2Allocator::id_t getAllocatorId() const override { return mAllocatorId; }
+    virtual const C2Handle *handle() const override { return mLockedHandle ? : mHandle; }
+    virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const override;
+
+    // internal methods
+    // |handle| will be moved.
+    C2AllocationGralloc(
+              const BufferDescriptorInfo2 &info,
+              const sp<IMapper2> &mapper,
+              hidl_handle &hidlHandle,
+              const C2HandleGralloc *const handle,
+              C2Allocator::id_t allocatorId);
+    C2AllocationGralloc(
+              const BufferDescriptorInfo3 &info,
+              const sp<IMapper3> &mapper,
+              hidl_handle &hidlHandle,
+              const C2HandleGralloc *const handle,
+              C2Allocator::id_t allocatorId);
+    int dup() const;
+    c2_status_t status() const;
+
+private:
+    const BufferDescriptorInfo2 mInfo2{};
+    const sp<IMapper2> mMapper2{nullptr};
+    const BufferDescriptorInfo3 mInfo3{};
+    const sp<IMapper3> mMapper3{nullptr};
+    const hidl_handle mHidlHandle;
+    const C2HandleGralloc *mHandle;
+    buffer_handle_t mBuffer;
+    const C2HandleGralloc *mLockedHandle;
+    bool mLocked;
+    C2Allocator::id_t mAllocatorId;
+    std::mutex mMappedLock;
+};
+
+C2AllocationGralloc::C2AllocationGralloc(
+          const BufferDescriptorInfo2 &info,
+          const sp<IMapper2> &mapper,
+          hidl_handle &hidlHandle,
+          const C2HandleGralloc *const handle,
+          C2Allocator::id_t allocatorId)
+    : C2GraphicAllocation(info.mapperInfo.width, info.mapperInfo.height),
+      mInfo2(info),
+      mMapper2(mapper),
+      mHidlHandle(std::move(hidlHandle)),
+      mHandle(handle),
+      mBuffer(nullptr),
+      mLockedHandle(nullptr),
+      mLocked(false),
+      mAllocatorId(allocatorId) {
+}
+
+C2AllocationGralloc::C2AllocationGralloc(
+          const BufferDescriptorInfo3 &info,
+          const sp<IMapper3> &mapper,
+          hidl_handle &hidlHandle,
+          const C2HandleGralloc *const handle,
+          C2Allocator::id_t allocatorId)
+    : C2GraphicAllocation(info.mapperInfo.width, info.mapperInfo.height),
+      mInfo3(info),
+      mMapper3(mapper),
+      mHidlHandle(std::move(hidlHandle)),
+      mHandle(handle),
+      mBuffer(nullptr),
+      mLockedHandle(nullptr),
+      mLocked(false),
+      mAllocatorId(allocatorId) {
+}
+
+C2AllocationGralloc::~C2AllocationGralloc() {
+    if (mBuffer && mLocked) {
+        // implementation ignores addresss and rect
+        uint8_t* addr[C2PlanarLayout::MAX_NUM_PLANES] = {};
+        unmap(addr, C2Rect(), nullptr);
+    }
+    if (mBuffer) {
+        if (mMapper2) {
+            if (!mMapper2->freeBuffer(const_cast<native_handle_t *>(
+                    mBuffer)).isOk()) {
+                ALOGE("failed transaction: freeBuffer");
+            }
+        } else {
+            if (!mMapper3->freeBuffer(const_cast<native_handle_t *>(
+                    mBuffer)).isOk()) {
+                ALOGE("failed transaction: freeBuffer");
+            }
+        }
+    }
+    if (mHandle) {
+        native_handle_delete(
+                const_cast<native_handle_t *>(reinterpret_cast<const native_handle_t *>(mHandle)));
+    }
+    if (mLockedHandle) {
+        native_handle_delete(
+                const_cast<native_handle_t *>(
+                        reinterpret_cast<const native_handle_t *>(mLockedHandle)));
+    }
+}
+
+c2_status_t C2AllocationGralloc::map(
+        C2Rect rect, C2MemoryUsage usage, C2Fence *fence,
+        C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) {
+    uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
+    ALOGV("mapping buffer with usage %#llx => %#llx",
+          (long long)usage.expected, (long long)grallocUsage);
+
+    // TODO
+    (void) fence;
+
+    std::lock_guard<std::mutex> lock(mMappedLock);
+    if (mBuffer && mLocked) {
+        ALOGD("already mapped");
+        return C2_DUPLICATE;
+    }
+    if (!layout || !addr) {
+        ALOGD("wrong param");
+        return C2_BAD_VALUE;
+    }
+
+    c2_status_t err = C2_OK;
+    if (!mBuffer) {
+        if (mMapper2) {
+            if (!mMapper2->importBuffer(
+                    mHidlHandle, [&err, this](const auto &maperr, const auto &buffer) {
+                        err = maperr2error(maperr);
+                        if (err == C2_OK) {
+                            mBuffer = static_cast<buffer_handle_t>(buffer);
+                        }
+                    }).isOk()) {
+                ALOGE("failed transaction: importBuffer");
+                return C2_CORRUPTED;
+            }
+        } else {
+            if (!mMapper3->importBuffer(
+                    mHidlHandle, [&err, this](const auto &maperr, const auto &buffer) {
+                        err = maperr2error(maperr);
+                        if (err == C2_OK) {
+                            mBuffer = static_cast<buffer_handle_t>(buffer);
+                        }
+                    }).isOk()) {
+                ALOGE("failed transaction: importBuffer (@3.0)");
+                return C2_CORRUPTED;
+            }
+        }
+        if (err != C2_OK) {
+            ALOGD("importBuffer failed: %d", err);
+            return err;
+        }
+        if (mBuffer == nullptr) {
+            ALOGD("importBuffer returned null buffer");
+            return C2_CORRUPTED;
+        }
+        uint32_t generation = 0;
+        uint64_t igbp_id = 0;
+        uint32_t igbp_slot = 0;
+        if (mHandle) {
+            mHandle->getIgbpData(&generation, &igbp_id, &igbp_slot);
+        }
+        if (mMapper2) {
+            mLockedHandle = C2HandleGralloc::WrapAndMoveNativeHandle(
+                    mBuffer, mInfo2.mapperInfo.width, mInfo2.mapperInfo.height,
+                    (uint32_t)mInfo2.mapperInfo.format, mInfo2.mapperInfo.usage,
+                    mInfo2.stride, generation, igbp_id, igbp_slot);
+        } else {
+            mLockedHandle = C2HandleGralloc::WrapAndMoveNativeHandle(
+                    mBuffer, mInfo3.mapperInfo.width, mInfo3.mapperInfo.height,
+                    (uint32_t)mInfo3.mapperInfo.format, mInfo3.mapperInfo.usage,
+                    mInfo3.stride, generation, igbp_id, igbp_slot);
+        }
+    }
+
+    PixelFormat3 format = mMapper2 ?
+            PixelFormat3(mInfo2.mapperInfo.format) :
+            PixelFormat3(mInfo3.mapperInfo.format);
+    switch (format) {
+        case PixelFormat3::RGBA_1010102: {
+            // TRICKY: this is used for media as YUV444 in the case when it is queued directly to a
+            // Surface. In all other cases it is RGBA. We don't know which case it is here, so
+            // default to YUV for now.
+            void *pointer = nullptr;
+            if (mMapper2) {
+                if (!mMapper2->lock(
+                        const_cast<native_handle_t *>(mBuffer),
+                        grallocUsage,
+                        { (int32_t)rect.left, (int32_t)rect.top,
+                          (int32_t)rect.width, (int32_t)rect.height },
+                        // TODO: fence
+                        hidl_handle(),
+                        [&err, &pointer](const auto &maperr, const auto &mapPointer) {
+                            err = maperr2error(maperr);
+                            if (err == C2_OK) {
+                                pointer = mapPointer;
+                            }
+                        }).isOk()) {
+                    ALOGE("failed transaction: lock(RGBA_1010102)");
+                    return C2_CORRUPTED;
+                }
+            } else {
+                if (!mMapper3->lock(
+                        const_cast<native_handle_t *>(mBuffer),
+                        grallocUsage,
+                        { (int32_t)rect.left, (int32_t)rect.top,
+                          (int32_t)rect.width, (int32_t)rect.height },
+                        // TODO: fence
+                        hidl_handle(),
+                        [&err, &pointer](const auto &maperr, const auto &mapPointer,
+                                         int32_t bytesPerPixel, int32_t bytesPerStride) {
+                            err = maperr2error(maperr);
+                            if (err == C2_OK) {
+                                pointer = mapPointer;
+                            }
+                            (void)bytesPerPixel;
+                            (void)bytesPerStride;
+                        }).isOk()) {
+                    ALOGE("failed transaction: lock(RGBA_1010102) (@3.0)");
+                    return C2_CORRUPTED;
+                }
+            }
+            if (err != C2_OK) {
+                ALOGD("lock failed: %d", err);
+                return err;
+            }
+            // treat as 32-bit values
+            addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
+            addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer;
+            addr[C2PlanarLayout::PLANE_V] = (uint8_t *)pointer;
+            addr[C2PlanarLayout::PLANE_A] = (uint8_t *)pointer;
+            layout->type = C2PlanarLayout::TYPE_YUVA;
+            layout->numPlanes = 4;
+            layout->rootPlanes = 1;
+            int32_t stride = mMapper2 ?
+                    int32_t(mInfo2.stride) :
+                    int32_t(mInfo3.stride);
+            layout->planes[C2PlanarLayout::PLANE_Y] = {
+                C2PlaneInfo::CHANNEL_Y,         // channel
+                4,                              // colInc
+                4 * stride,                     // rowInc
+                1,                              // mColSampling
+                1,                              // mRowSampling
+                32,                             // allocatedDepth
+                10,                             // bitDepth
+                10,                             // rightShift
+                C2PlaneInfo::LITTLE_END,        // endianness
+                C2PlanarLayout::PLANE_Y,        // rootIx
+                0,                              // offset
+            };
+            layout->planes[C2PlanarLayout::PLANE_U] = {
+                C2PlaneInfo::CHANNEL_CB,         // channel
+                4,                              // colInc
+                4 * stride,                     // rowInc
+                1,                              // mColSampling
+                1,                              // mRowSampling
+                32,                             // allocatedDepth
+                10,                             // bitDepth
+                0,                              // rightShift
+                C2PlaneInfo::LITTLE_END,        // endianness
+                C2PlanarLayout::PLANE_Y,        // rootIx
+                0,                              // offset
+            };
+            layout->planes[C2PlanarLayout::PLANE_V] = {
+                C2PlaneInfo::CHANNEL_CR,         // channel
+                4,                              // colInc
+                4 * stride,                     // rowInc
+                1,                              // mColSampling
+                1,                              // mRowSampling
+                32,                             // allocatedDepth
+                10,                             // bitDepth
+                20,                             // rightShift
+                C2PlaneInfo::LITTLE_END,        // endianness
+                C2PlanarLayout::PLANE_Y,        // rootIx
+                0,                              // offset
+            };
+            layout->planes[C2PlanarLayout::PLANE_A] = {
+                C2PlaneInfo::CHANNEL_A,         // channel
+                4,                              // colInc
+                4 * stride,                     // rowInc
+                1,                              // mColSampling
+                1,                              // mRowSampling
+                32,                             // allocatedDepth
+                2,                              // bitDepth
+                30,                             // rightShift
+                C2PlaneInfo::LITTLE_END,        // endianness
+                C2PlanarLayout::PLANE_Y,        // rootIx
+                0,                              // offset
+            };
+            break;
+        }
+
+        case PixelFormat3::RGBA_8888:
+            // TODO: alpha channel
+            // fall-through
+        case PixelFormat3::RGBX_8888: {
+            void *pointer = nullptr;
+            if (mMapper2) {
+                if (!mMapper2->lock(
+                        const_cast<native_handle_t *>(mBuffer),
+                        grallocUsage,
+                        { (int32_t)rect.left, (int32_t)rect.top,
+                          (int32_t)rect.width, (int32_t)rect.height },
+                        // TODO: fence
+                        hidl_handle(),
+                        [&err, &pointer](const auto &maperr, const auto &mapPointer) {
+                            err = maperr2error(maperr);
+                            if (err == C2_OK) {
+                                pointer = mapPointer;
+                            }
+                        }).isOk()) {
+                    ALOGE("failed transaction: lock(RGBA_8888)");
+                    return C2_CORRUPTED;
+                }
+            } else {
+                if (!mMapper3->lock(
+                        const_cast<native_handle_t *>(mBuffer),
+                        grallocUsage,
+                        { (int32_t)rect.left, (int32_t)rect.top,
+                          (int32_t)rect.width, (int32_t)rect.height },
+                        // TODO: fence
+                        hidl_handle(),
+                        [&err, &pointer](const auto &maperr, const auto &mapPointer,
+                                         int32_t bytesPerPixel, int32_t bytesPerStride) {
+                            err = maperr2error(maperr);
+                            if (err == C2_OK) {
+                                pointer = mapPointer;
+                            }
+                            (void)bytesPerPixel;
+                            (void)bytesPerStride;
+                        }).isOk()) {
+                    ALOGE("failed transaction: lock(RGBA_8888) (@3.0)");
+                    return C2_CORRUPTED;
+                }
+            }
+            if (err != C2_OK) {
+                ALOGD("lock failed: %d", err);
+                return err;
+            }
+            addr[C2PlanarLayout::PLANE_R] = (uint8_t *)pointer;
+            addr[C2PlanarLayout::PLANE_G] = (uint8_t *)pointer + 1;
+            addr[C2PlanarLayout::PLANE_B] = (uint8_t *)pointer + 2;
+            layout->type = C2PlanarLayout::TYPE_RGB;
+            layout->numPlanes = 3;
+            layout->rootPlanes = 1;
+            int32_t stride = mMapper2 ?
+                    int32_t(mInfo2.stride) :
+                    int32_t(mInfo3.stride);
+            layout->planes[C2PlanarLayout::PLANE_R] = {
+                C2PlaneInfo::CHANNEL_R,         // channel
+                4,                              // colInc
+                4 * stride,                     // rowInc
+                1,                              // mColSampling
+                1,                              // mRowSampling
+                8,                              // allocatedDepth
+                8,                              // bitDepth
+                0,                              // rightShift
+                C2PlaneInfo::NATIVE,            // endianness
+                C2PlanarLayout::PLANE_R,        // rootIx
+                0,                              // offset
+            };
+            layout->planes[C2PlanarLayout::PLANE_G] = {
+                C2PlaneInfo::CHANNEL_G,         // channel
+                4,                              // colInc
+                4 * stride,                     // rowInc
+                1,                              // mColSampling
+                1,                              // mRowSampling
+                8,                              // allocatedDepth
+                8,                              // bitDepth
+                0,                              // rightShift
+                C2PlaneInfo::NATIVE,            // endianness
+                C2PlanarLayout::PLANE_R,        // rootIx
+                1,                              // offset
+            };
+            layout->planes[C2PlanarLayout::PLANE_B] = {
+                C2PlaneInfo::CHANNEL_B,         // channel
+                4,                              // colInc
+                4 * stride,                     // rowInc
+                1,                              // mColSampling
+                1,                              // mRowSampling
+                8,                              // allocatedDepth
+                8,                              // bitDepth
+                0,                              // rightShift
+                C2PlaneInfo::NATIVE,            // endianness
+                C2PlanarLayout::PLANE_R,        // rootIx
+                2,                              // offset
+            };
+            break;
+        }
+
+        case PixelFormat3::YCBCR_420_888:
+            // fall-through
+        case PixelFormat3::YV12:
+            // fall-through
+        default: {
+            struct YCbCrLayout {
+                void* y;
+                void* cb;
+                void* cr;
+                uint32_t yStride;
+                uint32_t cStride;
+                uint32_t chromaStep;
+            };
+            YCbCrLayout ycbcrLayout;
+            if (mMapper2) {
+                if (!mMapper2->lockYCbCr(
+                        const_cast<native_handle_t *>(mBuffer), grallocUsage,
+                        { (int32_t)rect.left, (int32_t)rect.top,
+                          (int32_t)rect.width, (int32_t)rect.height },
+                        // TODO: fence
+                        hidl_handle(),
+                        [&err, &ycbcrLayout](const auto &maperr, const auto &mapLayout) {
+                            err = maperr2error(maperr);
+                            if (err == C2_OK) {
+                                ycbcrLayout = YCbCrLayout{
+                                        mapLayout.y,
+                                        mapLayout.cb,
+                                        mapLayout.cr,
+                                        mapLayout.yStride,
+                                        mapLayout.cStride,
+                                        mapLayout.chromaStep};
+                            }
+                        }).isOk()) {
+                    ALOGE("failed transaction: lockYCbCr");
+                    return C2_CORRUPTED;
+                }
+            } else {
+                if (!mMapper3->lockYCbCr(
+                        const_cast<native_handle_t *>(mBuffer), grallocUsage,
+                        { (int32_t)rect.left, (int32_t)rect.top,
+                          (int32_t)rect.width, (int32_t)rect.height },
+                        // TODO: fence
+                        hidl_handle(),
+                        [&err, &ycbcrLayout](const auto &maperr, const auto &mapLayout) {
+                            err = maperr2error(maperr);
+                            if (err == C2_OK) {
+                                ycbcrLayout = YCbCrLayout{
+                                        mapLayout.y,
+                                        mapLayout.cb,
+                                        mapLayout.cr,
+                                        mapLayout.yStride,
+                                        mapLayout.cStride,
+                                        mapLayout.chromaStep};
+                            }
+                        }).isOk()) {
+                    ALOGE("failed transaction: lockYCbCr (@3.0)");
+                    return C2_CORRUPTED;
+                }
+            }
+            if (err != C2_OK) {
+                ALOGD("lockYCbCr failed: %d", err);
+                return err;
+            }
+            addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
+            addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
+            addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
+            layout->type = C2PlanarLayout::TYPE_YUV;
+            layout->numPlanes = 3;
+            layout->rootPlanes = 3;
+            layout->planes[C2PlanarLayout::PLANE_Y] = {
+                C2PlaneInfo::CHANNEL_Y,         // channel
+                1,                              // colInc
+                (int32_t)ycbcrLayout.yStride,   // rowInc
+                1,                              // mColSampling
+                1,                              // mRowSampling
+                8,                              // allocatedDepth
+                8,                              // bitDepth
+                0,                              // rightShift
+                C2PlaneInfo::NATIVE,            // endianness
+                C2PlanarLayout::PLANE_Y,        // rootIx
+                0,                              // offset
+            };
+            layout->planes[C2PlanarLayout::PLANE_U] = {
+                C2PlaneInfo::CHANNEL_CB,          // channel
+                (int32_t)ycbcrLayout.chromaStep,  // colInc
+                (int32_t)ycbcrLayout.cStride,     // rowInc
+                2,                                // mColSampling
+                2,                                // mRowSampling
+                8,                                // allocatedDepth
+                8,                                // bitDepth
+                0,                                // rightShift
+                C2PlaneInfo::NATIVE,              // endianness
+                C2PlanarLayout::PLANE_U,          // rootIx
+                0,                                // offset
+            };
+            layout->planes[C2PlanarLayout::PLANE_V] = {
+                C2PlaneInfo::CHANNEL_CR,          // channel
+                (int32_t)ycbcrLayout.chromaStep,  // colInc
+                (int32_t)ycbcrLayout.cStride,     // rowInc
+                2,                                // mColSampling
+                2,                                // mRowSampling
+                8,                                // allocatedDepth
+                8,                                // bitDepth
+                0,                                // rightShift
+                C2PlaneInfo::NATIVE,              // endianness
+                C2PlanarLayout::PLANE_V,          // rootIx
+                0,                                // offset
+            };
+            // handle interleaved formats
+            intptr_t uvOffset = addr[C2PlanarLayout::PLANE_V] - addr[C2PlanarLayout::PLANE_U];
+            if (uvOffset > 0 && uvOffset < (intptr_t)ycbcrLayout.chromaStep) {
+                layout->rootPlanes = 2;
+                layout->planes[C2PlanarLayout::PLANE_V].rootIx = C2PlanarLayout::PLANE_U;
+                layout->planes[C2PlanarLayout::PLANE_V].offset = uvOffset;
+            } else if (uvOffset < 0 && uvOffset > -(intptr_t)ycbcrLayout.chromaStep) {
+                layout->rootPlanes = 2;
+                layout->planes[C2PlanarLayout::PLANE_U].rootIx = C2PlanarLayout::PLANE_V;
+                layout->planes[C2PlanarLayout::PLANE_U].offset = -uvOffset;
+            }
+            break;
+        }
+    }
+    mLocked = true;
+
+    return C2_OK;
+}
+
+c2_status_t C2AllocationGralloc::unmap(
+        uint8_t **addr, C2Rect rect, C2Fence *fence /* nullable */) {
+    // TODO: check addr and size, use fence
+    (void)addr;
+    (void)rect;
+
+    std::lock_guard<std::mutex> lock(mMappedLock);
+    c2_status_t err = C2_OK;
+    if (mMapper2) {
+        if (!mMapper2->unlock(
+                const_cast<native_handle_t *>(mBuffer),
+                [&err, &fence](const auto &maperr, const auto &releaseFence) {
+                    // TODO
+                    (void) fence;
+                    (void) releaseFence;
+                    err = maperr2error(maperr);
+                    if (err == C2_OK) {
+                        // TODO: fence
+                    }
+                }).isOk()) {
+            ALOGE("failed transaction: unlock");
+            return C2_CORRUPTED;
+        }
+    } else {
+        if (!mMapper3->unlock(
+                const_cast<native_handle_t *>(mBuffer),
+                [&err, &fence](const auto &maperr, const auto &releaseFence) {
+                    // TODO
+                    (void) fence;
+                    (void) releaseFence;
+                    err = maperr2error(maperr);
+                    if (err == C2_OK) {
+                        // TODO: fence
+                    }
+                }).isOk()) {
+            ALOGE("failed transaction: unlock (@3.0)");
+            return C2_CORRUPTED;
+        }
+    }
+    if (err == C2_OK) {
+        mLocked = false;
+    }
+    return err;
+}
+
+bool C2AllocationGralloc::equals(const std::shared_ptr<const C2GraphicAllocation> &other) const {
+    return other && other->handle() == handle();
+}
+
+/* ===================================== GRALLOC ALLOCATOR ==================================== */
+class C2AllocatorGralloc::Impl {
+public:
+    Impl(id_t id, bool bufferQueue);
+
+    id_t getId() const {
+        return mTraits->id;
+    }
+
+    C2String getName() const {
+        return mTraits->name;
+    }
+
+    std::shared_ptr<const C2Allocator::Traits> getTraits() const {
+        return mTraits;
+    }
+
+    c2_status_t newGraphicAllocation(
+            uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
+            std::shared_ptr<C2GraphicAllocation> *allocation);
+
+    c2_status_t priorGraphicAllocation(
+            const C2Handle *handle,
+            std::shared_ptr<C2GraphicAllocation> *allocation);
+
+    c2_status_t status() const { return mInit; }
+
+private:
+    std::shared_ptr<C2Allocator::Traits> mTraits;
+    c2_status_t mInit;
+    sp<IAllocator2> mAllocator2;
+    sp<IMapper2> mMapper2;
+    sp<IAllocator3> mAllocator3;
+    sp<IMapper3> mMapper3;
+    const bool mBufferQueue;
+};
+
+void _UnwrapNativeCodec2GrallocMetadata(
+        const C2Handle *const handle,
+        uint32_t *width, uint32_t *height, uint32_t *format,uint64_t *usage, uint32_t *stride,
+        uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
+    (void)C2HandleGralloc::Import(handle, width, height, format, usage, stride,
+                                  generation, igbp_id, igbp_slot);
+}
+
+C2AllocatorGralloc::Impl::Impl(id_t id, bool bufferQueue)
+    : mInit(C2_OK), mBufferQueue(bufferQueue) {
+    // TODO: get this from allocator
+    C2MemoryUsage minUsage = { 0, 0 }, maxUsage = { ~(uint64_t)0, ~(uint64_t)0 };
+    Traits traits = { "android.allocator.gralloc", id, C2Allocator::GRAPHIC, minUsage, maxUsage };
+    mTraits = std::make_shared<C2Allocator::Traits>(traits);
+
+    // gralloc allocator is a singleton, so all objects share a global service
+    mAllocator3 = IAllocator3::getService();
+    mMapper3 = IMapper3::getService();
+    if (!mAllocator3 || !mMapper3) {
+        mAllocator3 = nullptr;
+        mMapper3 = nullptr;
+        mAllocator2 = IAllocator2::getService();
+        mMapper2 = IMapper2::getService();
+        if (!mAllocator2 || !mMapper2) {
+            mAllocator2 = nullptr;
+            mMapper2 = nullptr;
+            mInit = C2_CORRUPTED;
+        }
+    }
+}
+
+c2_status_t C2AllocatorGralloc::Impl::newGraphicAllocation(
+        uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
+        std::shared_ptr<C2GraphicAllocation> *allocation) {
+    uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
+    ALOGV("allocating buffer with usage %#llx => %#llx",
+          (long long)usage.expected, (long long)grallocUsage);
+
+    c2_status_t err = C2_OK;
+    hidl_handle buffer{};
+
+    if (mMapper2) {
+        BufferDescriptorInfo2 info = {
+            {
+                width,
+                height,
+                1u,  // layerCount
+                PixelFormat2(format),
+                grallocUsage,
+            },
+            0u,  // stride placeholder
+        };
+        BufferDescriptor2 desc;
+        if (!mMapper2->createDescriptor(
+                info.mapperInfo, [&err, &desc](const auto &maperr, const auto &descriptor) {
+                    err = maperr2error(maperr);
+                    if (err == C2_OK) {
+                        desc = descriptor;
+                    }
+                }).isOk()) {
+            ALOGE("failed transaction: createDescriptor");
+            return C2_CORRUPTED;
+        }
+        if (err != C2_OK) {
+            return err;
+        }
+
+        // IAllocator shares IMapper error codes.
+        if (!mAllocator2->allocate(
+                desc,
+                1u,
+                [&err, &buffer, &info](const auto &maperr, const auto &stride, auto &buffers) {
+                    err = maperr2error(maperr);
+                    if (err != C2_OK) {
+                        return;
+                    }
+                    if (buffers.size() != 1u) {
+                        err = C2_CORRUPTED;
+                        return;
+                    }
+                    info.stride = stride;
+                    buffer = buffers[0];
+                }).isOk()) {
+            ALOGE("failed transaction: allocate");
+            return C2_CORRUPTED;
+        }
+        if (err != C2_OK) {
+            return err;
+        }
+        allocation->reset(new C2AllocationGralloc(
+                info, mMapper2, buffer,
+                C2HandleGralloc::WrapAndMoveNativeHandle(
+                        buffer.getNativeHandle(),
+                        width, height,
+                        format, grallocUsage, info.stride,
+                        0, 0, mBufferQueue ? ~0 : 0),
+                mTraits->id));
+        return C2_OK;
+    } else {
+        BufferDescriptorInfo3 info = {
+            {
+                width,
+                height,
+                1u,  // layerCount
+                PixelFormat3(format),
+                grallocUsage,
+            },
+            0u,  // stride placeholder
+        };
+        BufferDescriptor3 desc;
+        if (!mMapper3->createDescriptor(
+                info.mapperInfo, [&err, &desc](const auto &maperr, const auto &descriptor) {
+                    err = maperr2error(maperr);
+                    if (err == C2_OK) {
+                        desc = descriptor;
+                    }
+                }).isOk()) {
+            ALOGE("failed transaction: createDescriptor");
+            return C2_CORRUPTED;
+        }
+        if (err != C2_OK) {
+            return err;
+        }
+
+        // IAllocator shares IMapper error codes.
+        if (!mAllocator3->allocate(
+                desc,
+                1u,
+                [&err, &buffer, &info](const auto &maperr, const auto &stride, auto &buffers) {
+                    err = maperr2error(maperr);
+                    if (err != C2_OK) {
+                        return;
+                    }
+                    if (buffers.size() != 1u) {
+                        err = C2_CORRUPTED;
+                        return;
+                    }
+                    info.stride = stride;
+                    buffer = buffers[0];
+                }).isOk()) {
+            ALOGE("failed transaction: allocate");
+            return C2_CORRUPTED;
+        }
+        if (err != C2_OK) {
+            return err;
+        }
+        allocation->reset(new C2AllocationGralloc(
+                info, mMapper3, buffer,
+                C2HandleGralloc::WrapAndMoveNativeHandle(
+                        buffer.getNativeHandle(),
+                        width, height,
+                        format, grallocUsage, info.stride,
+                        0, 0, mBufferQueue ? ~0 : 0),
+                mTraits->id));
+        return C2_OK;
+    }
+}
+
+c2_status_t C2AllocatorGralloc::Impl::priorGraphicAllocation(
+        const C2Handle *handle,
+        std::shared_ptr<C2GraphicAllocation> *allocation) {
+    if (mMapper2) {
+        BufferDescriptorInfo2 info;
+        info.mapperInfo.layerCount = 1u;
+        uint32_t generation;
+        uint64_t igbp_id;
+        uint32_t igbp_slot;
+        const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import(
+                handle,
+                &info.mapperInfo.width, &info.mapperInfo.height,
+                (uint32_t *)&info.mapperInfo.format,
+                (uint64_t *)&info.mapperInfo.usage,
+                &info.stride,
+                &generation, &igbp_id, &igbp_slot);
+        if (grallocHandle == nullptr) {
+            return C2_BAD_VALUE;
+        }
+
+        hidl_handle hidlHandle;
+        hidlHandle.setTo(C2HandleGralloc::UnwrapNativeHandle(grallocHandle), true);
+
+        allocation->reset(new C2AllocationGralloc(
+                info, mMapper2, hidlHandle, grallocHandle, mTraits->id));
+        return C2_OK;
+    } else {
+        BufferDescriptorInfo3 info;
+        info.mapperInfo.layerCount = 1u;
+        uint32_t generation;
+        uint64_t igbp_id;
+        uint32_t igbp_slot;
+        const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import(
+                handle,
+                &info.mapperInfo.width, &info.mapperInfo.height,
+                (uint32_t *)&info.mapperInfo.format,
+                (uint64_t *)&info.mapperInfo.usage,
+                &info.stride,
+                &generation, &igbp_id, &igbp_slot);
+        if (grallocHandle == nullptr) {
+            return C2_BAD_VALUE;
+        }
+
+        hidl_handle hidlHandle;
+        hidlHandle.setTo(C2HandleGralloc::UnwrapNativeHandle(grallocHandle), true);
+
+        allocation->reset(new C2AllocationGralloc(
+                info, mMapper3, hidlHandle, grallocHandle, mTraits->id));
+        return C2_OK;
+    }
+}
+
+C2AllocatorGralloc::C2AllocatorGralloc(id_t id, bool bufferQueue)
+        : mImpl(new Impl(id, bufferQueue)) {}
+
+C2AllocatorGralloc::~C2AllocatorGralloc() { delete mImpl; }
+
+C2Allocator::id_t C2AllocatorGralloc::getId() const {
+    return mImpl->getId();
+}
+
+C2String C2AllocatorGralloc::getName() const {
+    return mImpl->getName();
+}
+
+std::shared_ptr<const C2Allocator::Traits> C2AllocatorGralloc::getTraits() const {
+    return mImpl->getTraits();
+}
+
+c2_status_t C2AllocatorGralloc::newGraphicAllocation(
+        uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
+        std::shared_ptr<C2GraphicAllocation> *allocation) {
+    return mImpl->newGraphicAllocation(width, height, format, usage, allocation);
+}
+
+c2_status_t C2AllocatorGralloc::priorGraphicAllocation(
+        const C2Handle *handle,
+        std::shared_ptr<C2GraphicAllocation> *allocation) {
+    return mImpl->priorGraphicAllocation(handle, allocation);
+}
+
+c2_status_t C2AllocatorGralloc::status() const {
+    return mImpl->status();
+}
+
+bool C2AllocatorGralloc::isValid(const C2Handle* const o) {
+    return C2HandleGralloc::isValid(o);
+}
+
+} // namespace android
diff --git a/media/codec2/vndk/C2AllocatorIon.cpp b/media/codec2/vndk/C2AllocatorIon.cpp
new file mode 100644
index 0000000..752bc46
--- /dev/null
+++ b/media/codec2/vndk/C2AllocatorIon.cpp
@@ -0,0 +1,640 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2AllocatorIon"
+#include <utils/Log.h>
+
+#include <list>
+
+#include <ion/ion.h>
+#include <sys/mman.h>
+#include <unistd.h> // getpagesize, size_t, close, dup
+
+#include <C2AllocatorIon.h>
+#include <C2Buffer.h>
+#include <C2Debug.h>
+#include <C2ErrnoUtils.h>
+
+namespace android {
+
+namespace {
+    constexpr size_t USAGE_LRU_CACHE_SIZE = 1024;
+}
+
+/* size_t <=> int(lo), int(hi) conversions */
+constexpr inline int size2intLo(size_t s) {
+    return int(s & 0xFFFFFFFF);
+}
+
+constexpr inline int size2intHi(size_t s) {
+    // cast to uint64_t as size_t may be 32 bits wide
+    return int((uint64_t(s) >> 32) & 0xFFFFFFFF);
+}
+
+constexpr inline size_t ints2size(int intLo, int intHi) {
+    // convert in 2 stages to 64 bits as intHi may be negative
+    return size_t(unsigned(intLo)) | size_t(uint64_t(unsigned(intHi)) << 32);
+}
+
+/* ========================================= ION HANDLE ======================================== */
+/**
+ * ION handle
+ *
+ * There can be only a sole ion client per process, this is captured in the ion fd that is passed
+ * to the constructor, but this should be managed by the ion buffer allocator/mapper.
+ *
+ * ion uses ion_user_handle_t for buffers. We don't store this in the native handle as
+ * it requires an ion_free to decref. Instead, we share the buffer to get an fd that also holds
+ * a refcount.
+ *
+ * This handle will not capture mapped fd-s as updating that would require a global mutex.
+ */
+
+struct C2HandleIon : public C2Handle {
+    // ion handle owns ionFd(!) and bufferFd
+    C2HandleIon(int bufferFd, size_t size)
+        : C2Handle(cHeader),
+          mFds{ bufferFd },
+          mInts{ int(size & 0xFFFFFFFF), int((uint64_t(size) >> 32) & 0xFFFFFFFF), kMagic } { }
+
+    static bool isValid(const C2Handle * const o);
+
+    int bufferFd() const { return mFds.mBuffer; }
+    size_t size() const {
+        return size_t(unsigned(mInts.mSizeLo))
+                | size_t(uint64_t(unsigned(mInts.mSizeHi)) << 32);
+    }
+
+protected:
+    struct {
+        int mBuffer; // shared ion buffer
+    } mFds;
+    struct {
+        int mSizeLo; // low 32-bits of size
+        int mSizeHi; // high 32-bits of size
+        int mMagic;
+    } mInts;
+
+private:
+    typedef C2HandleIon _type;
+    enum {
+        kMagic = '\xc2io\x00',
+        numFds = sizeof(mFds) / sizeof(int),
+        numInts = sizeof(mInts) / sizeof(int),
+        version = sizeof(C2Handle)
+    };
+    //constexpr static C2Handle cHeader = { version, numFds, numInts, {} };
+    const static C2Handle cHeader;
+};
+
+const C2Handle C2HandleIon::cHeader = {
+    C2HandleIon::version,
+    C2HandleIon::numFds,
+    C2HandleIon::numInts,
+    {}
+};
+
+// static
+bool C2HandleIon::isValid(const C2Handle * const o) {
+    if (!o || memcmp(o, &cHeader, sizeof(cHeader))) {
+        return false;
+    }
+    const C2HandleIon *other = static_cast<const C2HandleIon*>(o);
+    return other->mInts.mMagic == kMagic;
+}
+
+// TODO: is the dup of an ion fd identical to ion_share?
+
+/* ======================================= ION ALLOCATION ====================================== */
+class C2AllocationIon : public C2LinearAllocation {
+public:
+    /* Interface methods */
+    virtual c2_status_t map(
+        size_t offset, size_t size, C2MemoryUsage usage, C2Fence *fence,
+        void **addr /* nonnull */) override;
+    virtual c2_status_t unmap(void *addr, size_t size, C2Fence *fenceFd) override;
+    virtual ~C2AllocationIon() override;
+    virtual const C2Handle *handle() const override;
+    virtual id_t getAllocatorId() const override;
+    virtual bool equals(const std::shared_ptr<C2LinearAllocation> &other) const override;
+
+    // internal methods
+    C2AllocationIon(int ionFd, size_t size, size_t align, unsigned heapMask, unsigned flags, C2Allocator::id_t id);
+    C2AllocationIon(int ionFd, size_t size, int shareFd, C2Allocator::id_t id);
+
+    c2_status_t status() const;
+
+protected:
+    class Impl;
+    class ImplV2;
+    Impl *mImpl;
+
+    // TODO: we could make this encapsulate shared_ptr and copiable
+    C2_DO_NOT_COPY(C2AllocationIon);
+};
+
+class C2AllocationIon::Impl {
+protected:
+    /**
+     * Constructs an ion allocation.
+     *
+     * \note We always create an ion allocation, even if the allocation or import fails
+     * so that we can capture the error.
+     *
+     * \param ionFd     ion client (ownership transferred to created object)
+     * \param capacity  size of allocation
+     * \param bufferFd  buffer handle (ownership transferred to created object). Must be
+     *                  invalid if err is not 0.
+     * \param buffer    ion buffer user handle (ownership transferred to created object). Must be
+     *                  invalid if err is not 0.
+     * \param err       errno during buffer allocation or import
+     */
+    Impl(int ionFd, size_t capacity, int bufferFd, ion_user_handle_t buffer, C2Allocator::id_t id, int err)
+        : mIonFd(ionFd),
+          mHandle(bufferFd, capacity),
+          mBuffer(buffer),
+          mId(id),
+          mInit(c2_map_errno<ENOMEM, EACCES, EINVAL>(err)),
+          mMapFd(-1) {
+        if (mInit != C2_OK) {
+            // close ionFd now on error
+            if (mIonFd >= 0) {
+                close(mIonFd);
+                mIonFd = -1;
+            }
+            // C2_CHECK(bufferFd < 0);
+            // C2_CHECK(buffer < 0);
+        }
+    }
+
+public:
+    /**
+     * Constructs an ion allocation by importing a shared buffer fd.
+     *
+     * \param ionFd     ion client (ownership transferred to created object)
+     * \param capacity  size of allocation
+     * \param bufferFd  buffer handle (ownership transferred to created object)
+     *
+     * \return created ion allocation (implementation) which may be invalid if the
+     * import failed.
+     */
+    static Impl *Import(int ionFd, size_t capacity, int bufferFd, C2Allocator::id_t id);
+
+    /**
+     * Constructs an ion allocation by allocating an ion buffer.
+     *
+     * \param ionFd     ion client (ownership transferred to created object)
+     * \param size      size of allocation
+     * \param align     desired alignment of allocation
+     * \param heapMask  mask of heaps considered
+     * \param flags     ion allocation flags
+     *
+     * \return created ion allocation (implementation) which may be invalid if the
+     * allocation failed.
+     */
+    static Impl *Alloc(int ionFd, size_t size, size_t align, unsigned heapMask, unsigned flags, C2Allocator::id_t id);
+
+    c2_status_t map(size_t offset, size_t size, C2MemoryUsage usage, C2Fence *fence, void **addr) {
+        (void)fence; // TODO: wait for fence
+        *addr = nullptr;
+        if (!mMappings.empty()) {
+            ALOGV("multiple map");
+            // TODO: technically we should return DUPLICATE here, but our block views don't
+            // actually unmap, so we end up remapping an ion buffer multiple times.
+            //
+            // return C2_DUPLICATE;
+        }
+        if (size == 0) {
+            return C2_BAD_VALUE;
+        }
+
+        int prot = PROT_NONE;
+        int flags = MAP_SHARED;
+        if (usage.expected & C2MemoryUsage::CPU_READ) {
+            prot |= PROT_READ;
+        }
+        if (usage.expected & C2MemoryUsage::CPU_WRITE) {
+            prot |= PROT_WRITE;
+        }
+
+        size_t alignmentBytes = offset % PAGE_SIZE;
+        size_t mapOffset = offset - alignmentBytes;
+        size_t mapSize = size + alignmentBytes;
+        Mapping map = { nullptr, alignmentBytes, mapSize };
+
+        c2_status_t err = mapInternal(mapSize, mapOffset, alignmentBytes, prot, flags, &(map.addr), addr);
+        if (map.addr) {
+            mMappings.push_back(map);
+        }
+        return err;
+    }
+
+    c2_status_t unmap(void *addr, size_t size, C2Fence *fence) {
+        if (mMappings.empty()) {
+            ALOGD("tried to unmap unmapped buffer");
+            return C2_NOT_FOUND;
+        }
+        for (auto it = mMappings.begin(); it != mMappings.end(); ++it) {
+            if (addr != (uint8_t *)it->addr + it->alignmentBytes ||
+                    size + it->alignmentBytes != it->size) {
+                continue;
+            }
+            int err = munmap(it->addr, it->size);
+            if (err != 0) {
+                ALOGD("munmap failed");
+                return c2_map_errno<EINVAL>(errno);
+            }
+            if (fence) {
+                *fence = C2Fence(); // not using fences
+            }
+            (void)mMappings.erase(it);
+            ALOGV("successfully unmapped: %d", mHandle.bufferFd());
+            return C2_OK;
+        }
+        ALOGD("unmap failed to find specified map");
+        return C2_BAD_VALUE;
+    }
+
+    virtual ~Impl() {
+        if (!mMappings.empty()) {
+            ALOGD("Dangling mappings!");
+            for (const Mapping &map : mMappings) {
+                (void)munmap(map.addr, map.size);
+            }
+        }
+        if (mMapFd >= 0) {
+            close(mMapFd);
+            mMapFd = -1;
+        }
+        if (mInit == C2_OK) {
+            if (mBuffer >= 0) {
+                (void)ion_free(mIonFd, mBuffer);
+            }
+            native_handle_close(&mHandle);
+        }
+        if (mIonFd >= 0) {
+            close(mIonFd);
+        }
+    }
+
+    c2_status_t status() const {
+        return mInit;
+    }
+
+    const C2Handle *handle() const {
+        return &mHandle;
+    }
+
+    C2Allocator::id_t getAllocatorId() const {
+        return mId;
+    }
+
+    virtual ion_user_handle_t ionHandle() const {
+        return mBuffer;
+    }
+
+protected:
+    virtual c2_status_t mapInternal(size_t mapSize, size_t mapOffset, size_t alignmentBytes,
+            int prot, int flags, void** base, void** addr) {
+        c2_status_t err = C2_OK;
+        if (mMapFd == -1) {
+            int ret = ion_map(mIonFd, mBuffer, mapSize, prot,
+                              flags, mapOffset, (unsigned char**)base, &mMapFd);
+            ALOGV("ion_map(ionFd = %d, handle = %d, size = %zu, prot = %d, flags = %d, "
+                  "offset = %zu) returned (%d)",
+                  mIonFd, mBuffer, mapSize, prot, flags, mapOffset, ret);
+            if (ret) {
+                mMapFd = -1;
+                *base = *addr = nullptr;
+                err = c2_map_errno<EINVAL>(-ret);
+            } else {
+                *addr = (uint8_t *)*base + alignmentBytes;
+            }
+        } else {
+            *base = mmap(nullptr, mapSize, prot, flags, mMapFd, mapOffset);
+            ALOGV("mmap(size = %zu, prot = %d, flags = %d, mapFd = %d, offset = %zu) "
+                  "returned (%d)",
+                  mapSize, prot, flags, mMapFd, mapOffset, errno);
+            if (*base == MAP_FAILED) {
+                *base = *addr = nullptr;
+                err = c2_map_errno<EINVAL>(errno);
+            } else {
+                *addr = (uint8_t *)*base + alignmentBytes;
+            }
+        }
+        return err;
+    }
+
+    int mIonFd;
+    C2HandleIon mHandle;
+    ion_user_handle_t mBuffer;
+    C2Allocator::id_t mId;
+    c2_status_t mInit;
+    int mMapFd; // only one for now
+    struct Mapping {
+        void *addr;
+        size_t alignmentBytes;
+        size_t size;
+    };
+    std::list<Mapping> mMappings;
+};
+
+class C2AllocationIon::ImplV2 : public C2AllocationIon::Impl {
+public:
+    /**
+     * Constructs an ion allocation for platforms with new (ion_4.12.h) api
+     *
+     * \note We always create an ion allocation, even if the allocation or import fails
+     * so that we can capture the error.
+     *
+     * \param ionFd     ion client (ownership transferred to created object)
+     * \param capacity  size of allocation
+     * \param bufferFd  buffer handle (ownership transferred to created object). Must be
+     *                  invalid if err is not 0.
+     * \param err       errno during buffer allocation or import
+     */
+    ImplV2(int ionFd, size_t capacity, int bufferFd, C2Allocator::id_t id, int err)
+        : Impl(ionFd, capacity, bufferFd, -1 /*buffer*/, id, err) {
+    }
+
+    virtual ~ImplV2() = default;
+
+    virtual ion_user_handle_t ionHandle() const {
+        return mHandle.bufferFd();
+    }
+
+protected:
+    virtual c2_status_t mapInternal(size_t mapSize, size_t mapOffset, size_t alignmentBytes,
+            int prot, int flags, void** base, void** addr) {
+        c2_status_t err = C2_OK;
+        *base = mmap(nullptr, mapSize, prot, flags, mHandle.bufferFd(), mapOffset);
+        ALOGV("mmapV2(size = %zu, prot = %d, flags = %d, mapFd = %d, offset = %zu) "
+              "returned (%d)",
+              mapSize, prot, flags, mHandle.bufferFd(), mapOffset, errno);
+        if (*base == MAP_FAILED) {
+            *base = *addr = nullptr;
+            err = c2_map_errno<EINVAL>(errno);
+        } else {
+            *addr = (uint8_t *)*base + alignmentBytes;
+        }
+        return err;
+    }
+
+};
+
+C2AllocationIon::Impl *C2AllocationIon::Impl::Import(int ionFd, size_t capacity, int bufferFd,
+        C2Allocator::id_t id) {
+    int ret = 0;
+    if (ion_is_legacy(ionFd)) {
+        ion_user_handle_t buffer = -1;
+        ret = ion_import(ionFd, bufferFd, &buffer);
+        return new Impl(ionFd, capacity, bufferFd, buffer, id, ret);
+    } else {
+        return new ImplV2(ionFd, capacity, bufferFd, id, ret);
+    }
+}
+
+C2AllocationIon::Impl *C2AllocationIon::Impl::Alloc(int ionFd, size_t size, size_t align,
+        unsigned heapMask, unsigned flags, C2Allocator::id_t id) {
+    int bufferFd = -1;
+    ion_user_handle_t buffer = -1;
+    size_t alignedSize = align == 0 ? size : (size + align - 1) & ~(align - 1);
+    int ret;
+
+    if (ion_is_legacy(ionFd)) {
+        ret = ion_alloc(ionFd, alignedSize, align, heapMask, flags, &buffer);
+        ALOGV("ion_alloc(ionFd = %d, size = %zu, align = %zu, prot = %d, flags = %d) "
+              "returned (%d) ; buffer = %d",
+              ionFd, alignedSize, align, heapMask, flags, ret, buffer);
+        if (ret == 0) {
+            // get buffer fd for native handle constructor
+            ret = ion_share(ionFd, buffer, &bufferFd);
+            if (ret != 0) {
+                ion_free(ionFd, buffer);
+                buffer = -1;
+            }
+        }
+        return new Impl(ionFd, alignedSize, bufferFd, buffer, id, ret);
+
+    } else {
+        ret = ion_alloc_fd(ionFd, alignedSize, align, heapMask, flags, &bufferFd);
+        ALOGV("ion_alloc_fd(ionFd = %d, size = %zu, align = %zu, prot = %d, flags = %d) "
+              "returned (%d) ; bufferFd = %d",
+              ionFd, alignedSize, align, heapMask, flags, ret, bufferFd);
+
+        return new ImplV2(ionFd, alignedSize, bufferFd, id, ret);
+    }
+}
+
+c2_status_t C2AllocationIon::map(
+    size_t offset, size_t size, C2MemoryUsage usage, C2Fence *fence, void **addr) {
+    return mImpl->map(offset, size, usage, fence, addr);
+}
+
+c2_status_t C2AllocationIon::unmap(void *addr, size_t size, C2Fence *fence) {
+    return mImpl->unmap(addr, size, fence);
+}
+
+c2_status_t C2AllocationIon::status() const {
+    return mImpl->status();
+}
+
+C2Allocator::id_t C2AllocationIon::getAllocatorId() const {
+    return mImpl->getAllocatorId();
+}
+
+bool C2AllocationIon::equals(const std::shared_ptr<C2LinearAllocation> &other) const {
+    if (!other || other->getAllocatorId() != getAllocatorId()) {
+        return false;
+    }
+    // get user handle to compare objects
+    std::shared_ptr<C2AllocationIon> otherAsIon = std::static_pointer_cast<C2AllocationIon>(other);
+    return mImpl->ionHandle() == otherAsIon->mImpl->ionHandle();
+}
+
+const C2Handle *C2AllocationIon::handle() const {
+    return mImpl->handle();
+}
+
+C2AllocationIon::~C2AllocationIon() {
+    delete mImpl;
+}
+
+C2AllocationIon::C2AllocationIon(int ionFd, size_t size, size_t align,
+                                 unsigned heapMask, unsigned flags, C2Allocator::id_t id)
+    : C2LinearAllocation(size),
+      mImpl(Impl::Alloc(ionFd, size, align, heapMask, flags, id)) { }
+
+C2AllocationIon::C2AllocationIon(int ionFd, size_t size, int shareFd, C2Allocator::id_t id)
+    : C2LinearAllocation(size),
+      mImpl(Impl::Import(ionFd, size, shareFd, id)) { }
+
+/* ======================================= ION ALLOCATOR ====================================== */
+C2AllocatorIon::C2AllocatorIon(id_t id)
+    : mInit(C2_OK),
+      mIonFd(ion_open()) {
+    if (mIonFd < 0) {
+        switch (errno) {
+        case ENOENT:    mInit = C2_OMITTED; break;
+        default:        mInit = c2_map_errno<EACCES>(errno); break;
+        }
+    } else {
+        C2MemoryUsage minUsage = { 0, 0 };
+        C2MemoryUsage maxUsage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+        Traits traits = { "android.allocator.ion", id, LINEAR, minUsage, maxUsage };
+        mTraits = std::make_shared<Traits>(traits);
+        mBlockSize = ::getpagesize();
+    }
+}
+
+C2AllocatorIon::~C2AllocatorIon() {
+    if (mInit == C2_OK) {
+        ion_close(mIonFd);
+    }
+}
+
+C2Allocator::id_t C2AllocatorIon::getId() const {
+    std::lock_guard<std::mutex> lock(mUsageMapperLock);
+    return mTraits->id;
+}
+
+C2String C2AllocatorIon::getName() const {
+    std::lock_guard<std::mutex> lock(mUsageMapperLock);
+    return mTraits->name;
+}
+
+std::shared_ptr<const C2Allocator::Traits> C2AllocatorIon::getTraits() const {
+    std::lock_guard<std::mutex> lock(mUsageMapperLock);
+    return mTraits;
+}
+
+void C2AllocatorIon::setUsageMapper(
+        const UsageMapperFn &mapper, uint64_t minUsage, uint64_t maxUsage, uint64_t blockSize) {
+    std::lock_guard<std::mutex> lock(mUsageMapperLock);
+    mUsageMapperCache.clear();
+    mUsageMapperLru.clear();
+    mUsageMapper = mapper;
+    Traits traits = {
+        mTraits->name, mTraits->id, LINEAR,
+        C2MemoryUsage(minUsage), C2MemoryUsage(maxUsage)
+    };
+    mTraits = std::make_shared<Traits>(traits);
+    mBlockSize = blockSize;
+}
+
+std::size_t C2AllocatorIon::MapperKeyHash::operator()(const MapperKey &k) const {
+    return std::hash<uint64_t>{}(k.first) ^ std::hash<size_t>{}(k.second);
+}
+
+c2_status_t C2AllocatorIon::mapUsage(
+        C2MemoryUsage usage, size_t capacity, size_t *align, unsigned *heapMask, unsigned *flags) {
+    std::lock_guard<std::mutex> lock(mUsageMapperLock);
+    c2_status_t res = C2_OK;
+    // align capacity
+    capacity = (capacity + mBlockSize - 1) & ~(mBlockSize - 1);
+    MapperKey key = std::make_pair(usage.expected, capacity);
+    auto entry = mUsageMapperCache.find(key);
+    if (entry == mUsageMapperCache.end()) {
+        if (mUsageMapper) {
+            res = mUsageMapper(usage, capacity, align, heapMask, flags);
+        } else {
+            *align = 0; // TODO make this 1
+            *heapMask = ~0; // default mask
+            if (usage.expected & (C2MemoryUsage::CPU_READ | C2MemoryUsage::CPU_WRITE)) {
+                *flags = ION_FLAG_CACHED; // cache CPU accessed buffers
+            } else {
+                *flags = 0;  // default flags
+            }
+            res = C2_NO_INIT;
+        }
+        // add usage to cache
+        MapperValue value = std::make_tuple(*align, *heapMask, *flags, res);
+        mUsageMapperLru.emplace_front(key, value);
+        mUsageMapperCache.emplace(std::make_pair(key, mUsageMapperLru.begin()));
+        if (mUsageMapperCache.size() > USAGE_LRU_CACHE_SIZE) {
+            // remove LRU entry
+            MapperKey lruKey = mUsageMapperLru.front().first;
+            mUsageMapperCache.erase(lruKey);
+            mUsageMapperLru.pop_back();
+        }
+    } else {
+        // move entry to MRU
+        mUsageMapperLru.splice(mUsageMapperLru.begin(), mUsageMapperLru, entry->second);
+        const MapperValue &value = entry->second->second;
+        std::tie(*align, *heapMask, *flags, res) = value;
+    }
+    return res;
+}
+
+c2_status_t C2AllocatorIon::newLinearAllocation(
+        uint32_t capacity, C2MemoryUsage usage, std::shared_ptr<C2LinearAllocation> *allocation) {
+    if (allocation == nullptr) {
+        return C2_BAD_VALUE;
+    }
+
+    allocation->reset();
+    if (mInit != C2_OK) {
+        return mInit;
+    }
+
+    size_t align = 0;
+    unsigned heapMask = ~0;
+    unsigned flags = 0;
+    c2_status_t ret = mapUsage(usage, capacity, &align, &heapMask, &flags);
+    if (ret && ret != C2_NO_INIT) {
+        return ret;
+    }
+
+    std::shared_ptr<C2AllocationIon> alloc
+        = std::make_shared<C2AllocationIon>(dup(mIonFd), capacity, align, heapMask, flags, mTraits->id);
+    ret = alloc->status();
+    if (ret == C2_OK) {
+        *allocation = alloc;
+    }
+    return ret;
+}
+
+c2_status_t C2AllocatorIon::priorLinearAllocation(
+        const C2Handle *handle, std::shared_ptr<C2LinearAllocation> *allocation) {
+    *allocation = nullptr;
+    if (mInit != C2_OK) {
+        return mInit;
+    }
+
+    if (!C2HandleIon::isValid(handle)) {
+        return C2_BAD_VALUE;
+    }
+
+    // TODO: get capacity and validate it
+    const C2HandleIon *h = static_cast<const C2HandleIon*>(handle);
+    std::shared_ptr<C2AllocationIon> alloc
+        = std::make_shared<C2AllocationIon>(dup(mIonFd), h->size(), h->bufferFd(), mTraits->id);
+    c2_status_t ret = alloc->status();
+    if (ret == C2_OK) {
+        *allocation = alloc;
+        native_handle_delete(const_cast<native_handle_t*>(
+                reinterpret_cast<const native_handle_t*>(handle)));
+    }
+    return ret;
+}
+
+bool C2AllocatorIon::isValid(const C2Handle* const o) {
+    return C2HandleIon::isValid(o);
+}
+
+} // namespace android
+
diff --git a/media/codec2/vndk/C2Buffer.cpp b/media/codec2/vndk/C2Buffer.cpp
new file mode 100644
index 0000000..710b536
--- /dev/null
+++ b/media/codec2/vndk/C2Buffer.cpp
@@ -0,0 +1,1304 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2Buffer"
+#include <utils/Log.h>
+
+#include <list>
+#include <map>
+#include <mutex>
+
+#include <C2AllocatorIon.h>
+#include <C2AllocatorGralloc.h>
+#include <C2BufferPriv.h>
+#include <C2BlockInternal.h>
+#include <bufferpool/ClientManager.h>
+
+namespace {
+
+using android::C2AllocatorGralloc;
+using android::C2AllocatorIon;
+using android::hardware::media::bufferpool::BufferPoolData;
+using android::hardware::media::bufferpool::V2_0::ResultStatus;
+using android::hardware::media::bufferpool::V2_0::implementation::BufferPoolAllocation;
+using android::hardware::media::bufferpool::V2_0::implementation::BufferPoolAllocator;
+using android::hardware::media::bufferpool::V2_0::implementation::ClientManager;
+using android::hardware::media::bufferpool::V2_0::implementation::ConnectionId;
+using android::hardware::media::bufferpool::V2_0::implementation::INVALID_CONNECTIONID;
+
+// This anonymous namespace contains the helper classes that allow our implementation to create
+// block/buffer objects.
+//
+// Inherit from the parent, share with the friend.
+class ReadViewBuddy : public C2ReadView {
+    using C2ReadView::C2ReadView;
+    friend class ::C2ConstLinearBlock;
+};
+
+class WriteViewBuddy : public C2WriteView {
+    using C2WriteView::C2WriteView;
+    friend class ::C2LinearBlock;
+};
+
+class ConstLinearBlockBuddy : public C2ConstLinearBlock {
+    using C2ConstLinearBlock::C2ConstLinearBlock;
+    friend class ::C2LinearBlock;
+};
+
+class LinearBlockBuddy : public C2LinearBlock {
+    using C2LinearBlock::C2LinearBlock;
+    friend class ::C2BasicLinearBlockPool;
+};
+
+class AcquirableReadViewBuddy : public C2Acquirable<C2ReadView> {
+    using C2Acquirable::C2Acquirable;
+    friend class ::C2ConstLinearBlock;
+};
+
+class AcquirableWriteViewBuddy : public C2Acquirable<C2WriteView> {
+    using C2Acquirable::C2Acquirable;
+    friend class ::C2LinearBlock;
+};
+
+class GraphicViewBuddy : public C2GraphicView {
+    using C2GraphicView::C2GraphicView;
+    friend class ::C2ConstGraphicBlock;
+    friend class ::C2GraphicBlock;
+};
+
+class AcquirableConstGraphicViewBuddy : public C2Acquirable<const C2GraphicView> {
+    using C2Acquirable::C2Acquirable;
+    friend class ::C2ConstGraphicBlock;
+};
+
+class AcquirableGraphicViewBuddy : public C2Acquirable<C2GraphicView> {
+    using C2Acquirable::C2Acquirable;
+    friend class ::C2GraphicBlock;
+};
+
+class ConstGraphicBlockBuddy : public C2ConstGraphicBlock {
+    using C2ConstGraphicBlock::C2ConstGraphicBlock;
+    friend class ::C2GraphicBlock;
+};
+
+class GraphicBlockBuddy : public C2GraphicBlock {
+    using C2GraphicBlock::C2GraphicBlock;
+    friend class ::C2BasicGraphicBlockPool;
+};
+
+class BufferDataBuddy : public C2BufferData {
+    using C2BufferData::C2BufferData;
+    friend class ::C2Buffer;
+};
+
+}  // namespace
+
+/* ========================================== 1D BLOCK ========================================= */
+
+/**
+ * This class is the base class for all 1D block and view implementations.
+ *
+ * This is basically just a placeholder for the underlying 1D allocation and the range of the
+ * alloted portion to this block. There is also a placeholder for a blockpool data.
+ */
+class C2_HIDE _C2Block1DImpl : public _C2LinearRangeAspect {
+public:
+    _C2Block1DImpl(const std::shared_ptr<C2LinearAllocation> &alloc,
+            const std::shared_ptr<_C2BlockPoolData> &poolData = nullptr,
+            size_t offset = 0, size_t size = ~(size_t)0)
+        : _C2LinearRangeAspect(alloc.get(), offset, size),
+          mAllocation(alloc),
+          mPoolData(poolData) { }
+
+    _C2Block1DImpl(const _C2Block1DImpl &other, size_t offset = 0, size_t size = ~(size_t)0)
+        : _C2LinearRangeAspect(&other, offset, size),
+          mAllocation(other.mAllocation),
+          mPoolData(other.mPoolData) { }
+
+    /** returns pool data  */
+    std::shared_ptr<_C2BlockPoolData> poolData() const {
+        return mPoolData;
+    }
+
+    /** returns native handle */
+    const C2Handle *handle() const {
+        return mAllocation ? mAllocation->handle() : nullptr;
+    }
+
+    /** returns the allocator's ID */
+    C2Allocator::id_t getAllocatorId() const {
+        // BAD_ID can only happen if this Impl class is initialized for a view - never for a block.
+        return mAllocation ? mAllocation->getAllocatorId() : C2Allocator::BAD_ID;
+    }
+
+    std::shared_ptr<C2LinearAllocation> getAllocation() const {
+        return mAllocation;
+    }
+
+private:
+    std::shared_ptr<C2LinearAllocation> mAllocation;
+    std::shared_ptr<_C2BlockPoolData> mPoolData;
+};
+
+/**
+ * This class contains the mapped data pointer, and the potential error.
+ *
+ * range is the mapped range of the underlying allocation (which is part of the allotted
+ * range).
+ */
+class C2_HIDE _C2MappedBlock1DImpl : public _C2Block1DImpl {
+public:
+    _C2MappedBlock1DImpl(const _C2Block1DImpl &block, uint8_t *data,
+                         size_t offset = 0, size_t size = ~(size_t)0)
+        : _C2Block1DImpl(block, offset, size), mData(data), mError(C2_OK) { }
+
+    _C2MappedBlock1DImpl(c2_status_t error)
+        : _C2Block1DImpl(nullptr), mData(nullptr), mError(error) {
+        // CHECK(error != C2_OK);
+    }
+
+    const uint8_t *data() const {
+        return mData;
+    }
+
+    uint8_t *data() {
+        return mData;
+    }
+
+    c2_status_t error() const {
+        return mError;
+    }
+
+private:
+    uint8_t *mData;
+    c2_status_t mError;
+};
+
+/**
+ * Block implementation.
+ */
+class C2Block1D::Impl : public _C2Block1DImpl {
+    using _C2Block1DImpl::_C2Block1DImpl;
+};
+
+const C2Handle *C2Block1D::handle() const {
+    return mImpl->handle();
+};
+
+C2Allocator::id_t C2Block1D::getAllocatorId() const {
+    return mImpl->getAllocatorId();
+};
+
+C2Block1D::C2Block1D(std::shared_ptr<Impl> impl, const _C2LinearRangeAspect &range)
+    // always clamp subrange to parent (impl) range for safety
+    : _C2LinearRangeAspect(impl.get(), range.offset(), range.size()), mImpl(impl) {
+}
+
+/**
+ * Read view implementation.
+ *
+ * range of Impl is the mapped range of the underlying allocation (which is part of the allotted
+ * range). range of View is 0 to capacity() (not represented as an actual range). This maps to a
+ * subrange of Impl range starting at mImpl->offset() + _mOffset.
+ */
+class C2ReadView::Impl : public _C2MappedBlock1DImpl {
+    using _C2MappedBlock1DImpl::_C2MappedBlock1DImpl;
+};
+
+C2ReadView::C2ReadView(std::shared_ptr<Impl> impl, uint32_t offset, uint32_t size)
+    : _C2LinearCapacityAspect(C2LinearCapacity(impl->size()).range(offset, size).size()),
+      mImpl(impl),
+      mOffset(C2LinearCapacity(impl->size()).range(offset, size).offset()) { }
+
+C2ReadView::C2ReadView(c2_status_t error)
+    : _C2LinearCapacityAspect(0u), mImpl(std::make_shared<Impl>(error)), mOffset(0u) {
+    // CHECK(error != C2_OK);
+}
+
+const uint8_t *C2ReadView::data() const {
+    return mImpl->error() ? nullptr : mImpl->data() + mOffset;
+}
+
+c2_status_t C2ReadView::error() const {
+    return mImpl->error();
+}
+
+C2ReadView C2ReadView::subView(size_t offset, size_t size) const {
+    C2LinearRange subRange(*this, offset, size);
+    return C2ReadView(mImpl, mOffset + subRange.offset(), subRange.size());
+}
+
+/**
+ * Write view implementation.
+ */
+class C2WriteView::Impl : public _C2MappedBlock1DImpl {
+    using _C2MappedBlock1DImpl::_C2MappedBlock1DImpl;
+};
+
+C2WriteView::C2WriteView(std::shared_ptr<Impl> impl)
+// UGLY: _C2LinearRangeAspect requires a bona-fide object for capacity to prevent spoofing, so
+// this is what we have to do.
+// TODO: use childRange
+    : _C2EditableLinearRangeAspect(std::make_unique<C2LinearCapacity>(impl->size()).get()), mImpl(impl) { }
+
+C2WriteView::C2WriteView(c2_status_t error)
+    : _C2EditableLinearRangeAspect(nullptr), mImpl(std::make_shared<Impl>(error)) {}
+
+uint8_t *C2WriteView::base() { return mImpl->data(); }
+
+uint8_t *C2WriteView::data() { return mImpl->data() + offset(); }
+
+c2_status_t C2WriteView::error() const { return mImpl->error(); }
+
+/**
+ * Const linear block implementation.
+ */
+C2ConstLinearBlock::C2ConstLinearBlock(std::shared_ptr<Impl> impl, const _C2LinearRangeAspect &range, C2Fence fence)
+    : C2Block1D(impl, range), mFence(fence) { }
+
+C2Acquirable<C2ReadView> C2ConstLinearBlock::map() const {
+    void *base = nullptr;
+    uint32_t len = size();
+    c2_status_t error = mImpl->getAllocation()->map(
+            offset(), len, { C2MemoryUsage::CPU_READ, 0 }, nullptr, &base);
+    // TODO: wait on fence
+    if (error == C2_OK) {
+        std::shared_ptr<ReadViewBuddy::Impl> rvi = std::shared_ptr<ReadViewBuddy::Impl>(
+                new ReadViewBuddy::Impl(*mImpl, (uint8_t *)base, offset(), len),
+                [base, len](ReadViewBuddy::Impl *i) {
+                    (void)i->getAllocation()->unmap(base, len, nullptr);
+                    delete i;
+        });
+        return AcquirableReadViewBuddy(error, C2Fence(), ReadViewBuddy(rvi, 0, len));
+    } else {
+        return AcquirableReadViewBuddy(error, C2Fence(), ReadViewBuddy(error));
+    }
+}
+
+C2ConstLinearBlock C2ConstLinearBlock::subBlock(size_t offset_, size_t size_) const {
+    C2LinearRange subRange(*mImpl, offset_, size_);
+    return C2ConstLinearBlock(mImpl, subRange, mFence);
+}
+
+/**
+ * Linear block implementation.
+ */
+C2LinearBlock::C2LinearBlock(std::shared_ptr<Impl> impl, const _C2LinearRangeAspect &range)
+    : C2Block1D(impl, range) { }
+
+C2Acquirable<C2WriteView> C2LinearBlock::map() {
+    void *base = nullptr;
+    uint32_t len = size();
+    c2_status_t error = mImpl->getAllocation()->map(
+            offset(), len, { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE }, nullptr, &base);
+    // TODO: wait on fence
+    if (error == C2_OK) {
+        std::shared_ptr<WriteViewBuddy::Impl> rvi = std::shared_ptr<WriteViewBuddy::Impl>(
+                new WriteViewBuddy::Impl(*mImpl, (uint8_t *)base, 0, len),
+                [base, len](WriteViewBuddy::Impl *i) {
+                    (void)i->getAllocation()->unmap(base, len, nullptr);
+                    delete i;
+        });
+        return AcquirableWriteViewBuddy(error, C2Fence(), WriteViewBuddy(rvi));
+    } else {
+        return AcquirableWriteViewBuddy(error, C2Fence(), WriteViewBuddy(error));
+    }
+}
+
+C2ConstLinearBlock C2LinearBlock::share(size_t offset_, size_t size_, C2Fence fence) {
+    return ConstLinearBlockBuddy(mImpl, C2LinearRange(*this, offset_, size_), fence);
+}
+
+C2BasicLinearBlockPool::C2BasicLinearBlockPool(
+        const std::shared_ptr<C2Allocator> &allocator)
+  : mAllocator(allocator) { }
+
+c2_status_t C2BasicLinearBlockPool::fetchLinearBlock(
+        uint32_t capacity,
+        C2MemoryUsage usage,
+        std::shared_ptr<C2LinearBlock> *block /* nonnull */) {
+    block->reset();
+
+    std::shared_ptr<C2LinearAllocation> alloc;
+    c2_status_t err = mAllocator->newLinearAllocation(capacity, usage, &alloc);
+    if (err != C2_OK) {
+        return err;
+    }
+
+    *block = _C2BlockFactory::CreateLinearBlock(alloc);
+
+    return C2_OK;
+}
+
+struct C2_HIDE C2PooledBlockPoolData : _C2BlockPoolData {
+
+    virtual type_t getType() const override {
+        return TYPE_BUFFERPOOL;
+    }
+
+    void getBufferPoolData(std::shared_ptr<BufferPoolData> *data) const {
+        *data = mData;
+    }
+
+    C2PooledBlockPoolData(const std::shared_ptr<BufferPoolData> &data) : mData(data) {}
+
+    virtual ~C2PooledBlockPoolData() override {}
+
+private:
+    std::shared_ptr<BufferPoolData> mData;
+};
+
+bool _C2BlockFactory::GetBufferPoolData(
+        const std::shared_ptr<const _C2BlockPoolData> &data,
+        std::shared_ptr<BufferPoolData> *bufferPoolData) {
+    if (data && data->getType() == _C2BlockPoolData::TYPE_BUFFERPOOL) {
+        const std::shared_ptr<const C2PooledBlockPoolData> poolData =
+                std::static_pointer_cast<const C2PooledBlockPoolData>(data);
+        poolData->getBufferPoolData(bufferPoolData);
+        return true;
+    }
+    return false;
+}
+
+std::shared_ptr<C2LinearBlock> _C2BlockFactory::CreateLinearBlock(
+        const std::shared_ptr<C2LinearAllocation> &alloc,
+        const std::shared_ptr<_C2BlockPoolData> &data, size_t offset, size_t size) {
+    std::shared_ptr<C2Block1D::Impl> impl =
+        std::make_shared<C2Block1D::Impl>(alloc, data, offset, size);
+    return std::shared_ptr<C2LinearBlock>(new C2LinearBlock(impl, *impl));
+}
+
+std::shared_ptr<_C2BlockPoolData> _C2BlockFactory::GetLinearBlockPoolData(
+        const C2Block1D &block) {
+    if (block.mImpl) {
+        return block.mImpl->poolData();
+    }
+    return nullptr;
+}
+
+std::shared_ptr<C2LinearBlock> _C2BlockFactory::CreateLinearBlock(
+        const C2Handle *handle) {
+    // TODO: get proper allocator? and mutex?
+    static std::unique_ptr<C2AllocatorIon> sAllocator = std::make_unique<C2AllocatorIon>(0);
+
+    std::shared_ptr<C2LinearAllocation> alloc;
+    if (C2AllocatorIon::isValid(handle)) {
+        c2_status_t err = sAllocator->priorLinearAllocation(handle, &alloc);
+        if (err == C2_OK) {
+            std::shared_ptr<C2LinearBlock> block = _C2BlockFactory::CreateLinearBlock(alloc);
+            return block;
+        }
+    }
+    return nullptr;
+}
+
+std::shared_ptr<C2LinearBlock> _C2BlockFactory::CreateLinearBlock(
+        const C2Handle *cHandle, const std::shared_ptr<BufferPoolData> &data) {
+    // TODO: get proper allocator? and mutex?
+    static std::unique_ptr<C2AllocatorIon> sAllocator = std::make_unique<C2AllocatorIon>(0);
+
+    std::shared_ptr<C2LinearAllocation> alloc;
+    if (C2AllocatorIon::isValid(cHandle)) {
+        native_handle_t *handle = native_handle_clone(cHandle);
+        if (handle) {
+            c2_status_t err = sAllocator->priorLinearAllocation(handle, &alloc);
+            const std::shared_ptr<C2PooledBlockPoolData> poolData =
+                    std::make_shared<C2PooledBlockPoolData>(data);
+            if (err == C2_OK && poolData) {
+                // TODO: config params?
+                std::shared_ptr<C2LinearBlock> block =
+                        _C2BlockFactory::CreateLinearBlock(alloc, poolData);
+                return block;
+            }
+        }
+    }
+    return nullptr;
+};
+
+/**
+ * Wrapped C2Allocator which is injected to buffer pool on behalf of
+ * C2BlockPool.
+ */
+class _C2BufferPoolAllocator : public BufferPoolAllocator {
+public:
+    _C2BufferPoolAllocator(const std::shared_ptr<C2Allocator> &allocator)
+        : mAllocator(allocator) {}
+
+    ~_C2BufferPoolAllocator() override {}
+
+    ResultStatus allocate(const std::vector<uint8_t> &params,
+                          std::shared_ptr<BufferPoolAllocation> *alloc,
+                          size_t *allocSize) override;
+
+    bool compatible(const std::vector<uint8_t> &newParams,
+                    const std::vector<uint8_t> &oldParams) override;
+
+    // Methods for codec2 component (C2BlockPool).
+    /**
+     * Transforms linear allocation parameters for C2Allocator to parameters
+     * for buffer pool.
+     *
+     * @param capacity      size of linear allocation
+     * @param usage         memory usage pattern for linear allocation
+     * @param params        allocation parameters for buffer pool
+     */
+    void getLinearParams(uint32_t capacity, C2MemoryUsage usage,
+                         std::vector<uint8_t> *params);
+
+    /**
+     * Transforms graphic allocation parameters for C2Allocator to parameters
+     * for buffer pool.
+     *
+     * @param width         width of graphic allocation
+     * @param height        height of graphic allocation
+     * @param format        color format of graphic allocation
+     * @param params        allocation parameter for buffer pool
+     */
+    void getGraphicParams(uint32_t width, uint32_t height,
+                          uint32_t format, C2MemoryUsage usage,
+                          std::vector<uint8_t> *params);
+
+    /**
+     * Transforms an existing native handle to an C2LinearAllcation.
+     * Wrapper to C2Allocator#priorLinearAllocation
+     */
+    c2_status_t priorLinearAllocation(
+            const C2Handle *handle,
+            std::shared_ptr<C2LinearAllocation> *c2Allocation);
+
+    /**
+     * Transforms an existing native handle to an C2GraphicAllcation.
+     * Wrapper to C2Allocator#priorGraphicAllocation
+     */
+    c2_status_t priorGraphicAllocation(
+            const C2Handle *handle,
+            std::shared_ptr<C2GraphicAllocation> *c2Allocation);
+
+private:
+    static constexpr int kMaxIntParams = 5; // large enough number;
+
+    enum AllocType : uint8_t {
+        ALLOC_NONE = 0,
+
+        ALLOC_LINEAR,
+        ALLOC_GRAPHIC,
+    };
+
+    union AllocParams {
+        struct {
+            AllocType allocType;
+            C2MemoryUsage usage;
+            uint32_t params[kMaxIntParams];
+        } data;
+        uint8_t array[0];
+
+        AllocParams() : data{ALLOC_NONE, {0, 0}, {0}} {}
+        AllocParams(C2MemoryUsage usage, uint32_t capacity)
+            : data{ALLOC_LINEAR, usage, {[0] = capacity}} {}
+        AllocParams(
+                C2MemoryUsage usage,
+                uint32_t width, uint32_t height, uint32_t format)
+                : data{ALLOC_GRAPHIC, usage, {width, height, format}} {}
+    };
+
+    const std::shared_ptr<C2Allocator> mAllocator;
+};
+
+struct LinearAllocationDtor {
+    LinearAllocationDtor(const std::shared_ptr<C2LinearAllocation> &alloc)
+        : mAllocation(alloc) {}
+
+    void operator()(BufferPoolAllocation *poolAlloc) { delete poolAlloc; }
+
+    const std::shared_ptr<C2LinearAllocation> mAllocation;
+};
+
+struct GraphicAllocationDtor {
+    GraphicAllocationDtor(const std::shared_ptr<C2GraphicAllocation> &alloc)
+        : mAllocation(alloc) {}
+
+    void operator()(BufferPoolAllocation *poolAlloc) { delete poolAlloc; }
+
+    const std::shared_ptr<C2GraphicAllocation> mAllocation;
+};
+
+ResultStatus _C2BufferPoolAllocator::allocate(
+        const std::vector<uint8_t>  &params,
+        std::shared_ptr<BufferPoolAllocation> *alloc,
+        size_t *allocSize) {
+    AllocParams c2Params;
+    memcpy(&c2Params, params.data(), std::min(sizeof(AllocParams), params.size()));
+    c2_status_t status = C2_BAD_VALUE;
+    switch(c2Params.data.allocType) {
+        case ALLOC_NONE:
+            break;
+        case ALLOC_LINEAR: {
+            std::shared_ptr<C2LinearAllocation> c2Linear;
+            status = mAllocator->newLinearAllocation(
+                    c2Params.data.params[0], c2Params.data.usage, &c2Linear);
+            if (status == C2_OK && c2Linear) {
+                BufferPoolAllocation *ptr = new BufferPoolAllocation(c2Linear->handle());
+                if (ptr) {
+                    *alloc = std::shared_ptr<BufferPoolAllocation>(
+                            ptr, LinearAllocationDtor(c2Linear));
+                    if (*alloc) {
+                        *allocSize = (size_t)c2Params.data.params[0];
+                        return ResultStatus::OK;
+                    }
+                    delete ptr;
+                }
+                return ResultStatus::NO_MEMORY;
+            }
+            break;
+        }
+        case ALLOC_GRAPHIC: {
+            std::shared_ptr<C2GraphicAllocation> c2Graphic;
+            status = mAllocator->newGraphicAllocation(
+                    c2Params.data.params[0],
+                    c2Params.data.params[1],
+                    c2Params.data.params[2],
+                    c2Params.data.usage, &c2Graphic);
+            if (status == C2_OK && c2Graphic) {
+                BufferPoolAllocation *ptr = new BufferPoolAllocation(c2Graphic->handle());
+                if (ptr) {
+                    *alloc = std::shared_ptr<BufferPoolAllocation>(
+                            ptr, GraphicAllocationDtor(c2Graphic));
+                    if (*alloc) {
+                        *allocSize = c2Params.data.params[0] * c2Params.data.params[1];
+                        return ResultStatus::OK;
+                    }
+                    delete ptr;
+                }
+                return ResultStatus::NO_MEMORY;
+            }
+            break;
+        }
+        default:
+            break;
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+bool _C2BufferPoolAllocator::compatible(
+        const std::vector<uint8_t>  &newParams,
+        const std::vector<uint8_t>  &oldParams) {
+    AllocParams newAlloc;
+    AllocParams oldAlloc;
+    memcpy(&newAlloc, newParams.data(), std::min(sizeof(AllocParams), newParams.size()));
+    memcpy(&oldAlloc, oldParams.data(), std::min(sizeof(AllocParams), oldParams.size()));
+
+    // TODO: support not exact matching. e.g) newCapacity < oldCapacity
+    if (newAlloc.data.allocType == oldAlloc.data.allocType &&
+            newAlloc.data.usage.expected == oldAlloc.data.usage.expected) {
+        for (int i = 0; i < kMaxIntParams; ++i) {
+            if (newAlloc.data.params[i] != oldAlloc.data.params[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+    return false;
+}
+
+void _C2BufferPoolAllocator::getLinearParams(
+        uint32_t capacity, C2MemoryUsage usage, std::vector<uint8_t> *params) {
+    AllocParams c2Params(usage, capacity);
+    params->assign(c2Params.array, c2Params.array + sizeof(AllocParams));
+}
+
+void _C2BufferPoolAllocator::getGraphicParams(
+        uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
+        std::vector<uint8_t> *params) {
+    AllocParams c2Params(usage, width, height, format);
+    params->assign(c2Params.array, c2Params.array + sizeof(AllocParams));
+}
+
+c2_status_t _C2BufferPoolAllocator::priorLinearAllocation(
+        const C2Handle *handle,
+        std::shared_ptr<C2LinearAllocation> *c2Allocation) {
+    return mAllocator->priorLinearAllocation(handle, c2Allocation);
+}
+
+c2_status_t _C2BufferPoolAllocator::priorGraphicAllocation(
+        const C2Handle *handle,
+        std::shared_ptr<C2GraphicAllocation> *c2Allocation) {
+    return mAllocator->priorGraphicAllocation(handle, c2Allocation);
+}
+
+class C2PooledBlockPool::Impl {
+public:
+    Impl(const std::shared_ptr<C2Allocator> &allocator)
+            : mInit(C2_OK),
+              mBufferPoolManager(ClientManager::getInstance()),
+              mAllocator(std::make_shared<_C2BufferPoolAllocator>(allocator)) {
+        if (mAllocator && mBufferPoolManager) {
+            if (mBufferPoolManager->create(
+                    mAllocator, &mConnectionId) == ResultStatus::OK) {
+                return;
+            }
+        }
+        mInit = C2_NO_INIT;
+    }
+
+    ~Impl() {
+        if (mInit == C2_OK) {
+            mBufferPoolManager->close(mConnectionId);
+        }
+    }
+
+    c2_status_t fetchLinearBlock(
+            uint32_t capacity, C2MemoryUsage usage,
+            std::shared_ptr<C2LinearBlock> *block /* nonnull */) {
+        block->reset();
+        if (mInit != C2_OK) {
+            return mInit;
+        }
+        std::vector<uint8_t> params;
+        mAllocator->getLinearParams(capacity, usage, &params);
+        std::shared_ptr<BufferPoolData> bufferPoolData;
+        native_handle_t *cHandle = nullptr;
+        ResultStatus status = mBufferPoolManager->allocate(
+                mConnectionId, params, &cHandle, &bufferPoolData);
+        if (status == ResultStatus::OK) {
+            native_handle_t *handle = native_handle_clone(cHandle);
+            if (handle) {
+                std::shared_ptr<C2LinearAllocation> alloc;
+                std::shared_ptr<C2PooledBlockPoolData> poolData =
+                        std::make_shared<C2PooledBlockPoolData>(bufferPoolData);
+                c2_status_t err = mAllocator->priorLinearAllocation(handle, &alloc);
+                if (err == C2_OK && poolData && alloc) {
+                    *block = _C2BlockFactory::CreateLinearBlock(alloc, poolData, 0, capacity);
+                    if (*block) {
+                        return C2_OK;
+                    }
+                }
+            }
+            return C2_NO_MEMORY;
+        }
+        if (status == ResultStatus::NO_MEMORY) {
+            return C2_NO_MEMORY;
+        }
+        return C2_CORRUPTED;
+    }
+
+    c2_status_t fetchGraphicBlock(
+            uint32_t width, uint32_t height, uint32_t format,
+            C2MemoryUsage usage,
+            std::shared_ptr<C2GraphicBlock> *block) {
+        block->reset();
+        if (mInit != C2_OK) {
+            return mInit;
+        }
+        std::vector<uint8_t> params;
+        mAllocator->getGraphicParams(width, height, format, usage, &params);
+        std::shared_ptr<BufferPoolData> bufferPoolData;
+        native_handle_t *cHandle = nullptr;
+        ResultStatus status = mBufferPoolManager->allocate(
+                mConnectionId, params, &cHandle, &bufferPoolData);
+        if (status == ResultStatus::OK) {
+            native_handle_t *handle = native_handle_clone(cHandle);
+            if (handle) {
+                std::shared_ptr<C2GraphicAllocation> alloc;
+                std::shared_ptr<C2PooledBlockPoolData> poolData =
+                    std::make_shared<C2PooledBlockPoolData>(bufferPoolData);
+                c2_status_t err = mAllocator->priorGraphicAllocation(
+                        handle, &alloc);
+                if (err == C2_OK && poolData && alloc) {
+                    *block = _C2BlockFactory::CreateGraphicBlock(
+                            alloc, poolData, C2Rect(width, height));
+                    if (*block) {
+                        return C2_OK;
+                    }
+                }
+            }
+            return C2_NO_MEMORY;
+        }
+        if (status == ResultStatus::NO_MEMORY) {
+            return C2_NO_MEMORY;
+        }
+        return C2_CORRUPTED;
+    }
+
+    ConnectionId getConnectionId() {
+        return mInit != C2_OK ? INVALID_CONNECTIONID : mConnectionId;
+    }
+
+private:
+    c2_status_t mInit;
+    const android::sp<ClientManager> mBufferPoolManager;
+    ConnectionId mConnectionId; // locally
+    const std::shared_ptr<_C2BufferPoolAllocator> mAllocator;
+};
+
+C2PooledBlockPool::C2PooledBlockPool(
+        const std::shared_ptr<C2Allocator> &allocator, const local_id_t localId)
+        : mAllocator(allocator), mLocalId(localId), mImpl(new Impl(allocator)) {}
+
+C2PooledBlockPool::~C2PooledBlockPool() {
+}
+
+c2_status_t C2PooledBlockPool::fetchLinearBlock(
+        uint32_t capacity,
+        C2MemoryUsage usage,
+        std::shared_ptr<C2LinearBlock> *block /* nonnull */) {
+    if (mImpl) {
+        return mImpl->fetchLinearBlock(capacity, usage, block);
+    }
+    return C2_CORRUPTED;
+}
+
+c2_status_t C2PooledBlockPool::fetchGraphicBlock(
+        uint32_t width,
+        uint32_t height,
+        uint32_t format,
+        C2MemoryUsage usage,
+        std::shared_ptr<C2GraphicBlock> *block) {
+    if (mImpl) {
+        return mImpl->fetchGraphicBlock(width, height, format, usage, block);
+    }
+    return C2_CORRUPTED;
+}
+
+int64_t C2PooledBlockPool::getConnectionId() {
+    if (mImpl) {
+        return mImpl->getConnectionId();
+    }
+    return 0;
+}
+
+/* ========================================== 2D BLOCK ========================================= */
+
+/**
+ * Implementation that is shared between all 2D blocks and views.
+ *
+ * For blocks' Impl's crop is always the allotted crop, even if it is a sub block.
+ *
+ * For views' Impl's crop is the mapped portion - which for now is always the
+ * allotted crop.
+ */
+class C2_HIDE _C2Block2DImpl : public _C2PlanarSectionAspect {
+public:
+    /**
+     * Impl's crop is always the or part of the allotted crop of the allocation.
+     */
+    _C2Block2DImpl(const std::shared_ptr<C2GraphicAllocation> &alloc,
+            const std::shared_ptr<_C2BlockPoolData> &poolData = nullptr,
+            const C2Rect &allottedCrop = C2Rect(~0u, ~0u))
+        : _C2PlanarSectionAspect(alloc.get(), allottedCrop),
+          mAllocation(alloc),
+          mPoolData(poolData) { }
+
+    virtual ~_C2Block2DImpl() = default;
+
+    /** returns pool data  */
+    std::shared_ptr<_C2BlockPoolData> poolData() const {
+        return mPoolData;
+    }
+
+    /** returns native handle */
+    const C2Handle *handle() const {
+        return mAllocation ? mAllocation->handle() : nullptr;
+    }
+
+    /** returns the allocator's ID */
+    C2Allocator::id_t getAllocatorId() const {
+        // BAD_ID can only happen if this Impl class is initialized for a view - never for a block.
+        return mAllocation ? mAllocation->getAllocatorId() : C2Allocator::BAD_ID;
+    }
+
+    std::shared_ptr<C2GraphicAllocation> getAllocation() const {
+        return mAllocation;
+    }
+
+private:
+    std::shared_ptr<C2GraphicAllocation> mAllocation;
+    std::shared_ptr<_C2BlockPoolData> mPoolData;
+};
+
+class C2_HIDE _C2MappingBlock2DImpl
+    : public _C2Block2DImpl, public std::enable_shared_from_this<_C2MappingBlock2DImpl> {
+public:
+    using _C2Block2DImpl::_C2Block2DImpl;
+
+    virtual ~_C2MappingBlock2DImpl() override = default;
+
+    /**
+     * This class contains the mapped data pointer, and the potential error.
+     */
+    struct Mapped {
+    private:
+        friend class _C2MappingBlock2DImpl;
+
+        Mapped(const std::shared_ptr<_C2Block2DImpl> &impl, bool writable, C2Fence *fence __unused)
+            : mImpl(impl), mWritable(writable) {
+            memset(mData, 0, sizeof(mData));
+            const C2Rect crop = mImpl->crop();
+            // gralloc requires mapping the whole region of interest as we cannot
+            // map multiple regions
+            mError = mImpl->getAllocation()->map(
+                    crop,
+                    { C2MemoryUsage::CPU_READ, writable ? C2MemoryUsage::CPU_WRITE : 0 },
+                    nullptr,
+                    &mLayout,
+                    mData);
+            if (mError != C2_OK) {
+                memset(&mLayout, 0, sizeof(mLayout));
+                memset(mData, 0, sizeof(mData));
+                memset(mOffsetData, 0, sizeof(mData));
+            } else {
+                // TODO: validate plane layout and
+                // adjust data pointers to the crop region's top left corner.
+                // fail if it is not on a subsampling boundary
+                for (size_t planeIx = 0; planeIx < mLayout.numPlanes; ++planeIx) {
+                    const uint32_t colSampling = mLayout.planes[planeIx].colSampling;
+                    const uint32_t rowSampling = mLayout.planes[planeIx].rowSampling;
+                    if (crop.left % colSampling || crop.right() % colSampling
+                            || crop.top % rowSampling || crop.bottom() % rowSampling) {
+                        // cannot calculate data pointer
+                        mImpl->getAllocation()->unmap(mData, crop, nullptr);
+                        memset(&mLayout, 0, sizeof(mLayout));
+                        memset(mData, 0, sizeof(mData));
+                        memset(mOffsetData, 0, sizeof(mData));
+                        mError = C2_BAD_VALUE;
+                        return;
+                    }
+                    mOffsetData[planeIx] =
+                        mData[planeIx] + (ssize_t)crop.left * mLayout.planes[planeIx].colInc
+                                + (ssize_t)crop.top * mLayout.planes[planeIx].rowInc;
+                }
+            }
+        }
+
+        explicit Mapped(c2_status_t error)
+            : mImpl(nullptr), mWritable(false), mError(error) {
+            // CHECK(error != C2_OK);
+            memset(&mLayout, 0, sizeof(mLayout));
+            memset(mData, 0, sizeof(mData));
+            memset(mOffsetData, 0, sizeof(mData));
+        }
+
+    public:
+        ~Mapped() {
+            if (mData[0] != nullptr) {
+                mImpl->getAllocation()->unmap(mData, mImpl->crop(), nullptr);
+            }
+        }
+
+        /** returns mapping status */
+        c2_status_t error() const { return mError; }
+
+        /** returns data pointer */
+        uint8_t *const *data() const { return mOffsetData; }
+
+        /** returns the plane layout */
+        C2PlanarLayout layout() const { return mLayout; }
+
+        /** returns whether the mapping is writable */
+        bool writable() const { return mWritable; }
+
+    private:
+        const std::shared_ptr<_C2Block2DImpl> mImpl;
+        bool mWritable;
+        c2_status_t mError;
+        uint8_t *mData[C2PlanarLayout::MAX_NUM_PLANES];
+        uint8_t *mOffsetData[C2PlanarLayout::MAX_NUM_PLANES];
+        C2PlanarLayout mLayout;
+    };
+
+    /**
+     * Maps the allotted region.
+     *
+     * If already mapped and it is currently in use, returns the existing mapping.
+     * If fence is provided, an acquire fence is stored there.
+     */
+    std::shared_ptr<Mapped> map(bool writable, C2Fence *fence) {
+        std::lock_guard<std::mutex> lock(mMappedLock);
+        std::shared_ptr<Mapped> existing = mMapped.lock();
+        if (!existing) {
+            existing = std::shared_ptr<Mapped>(new Mapped(shared_from_this(), writable, fence));
+            mMapped = existing;
+        } else {
+            // if we mapped the region read-only, we cannot remap it read-write
+            if (writable && !existing->writable()) {
+                existing = std::shared_ptr<Mapped>(new Mapped(C2_CANNOT_DO));
+            }
+            if (fence != nullptr) {
+                *fence = C2Fence();
+            }
+        }
+        return existing;
+    }
+
+private:
+    std::weak_ptr<Mapped> mMapped;
+    std::mutex mMappedLock;
+};
+
+class C2_HIDE _C2MappedBlock2DImpl : public _C2Block2DImpl {
+public:
+    _C2MappedBlock2DImpl(const _C2Block2DImpl &impl,
+                         std::shared_ptr<_C2MappingBlock2DImpl::Mapped> mapping)
+        : _C2Block2DImpl(impl), mMapping(mapping) {
+    }
+
+    virtual ~_C2MappedBlock2DImpl() override = default;
+
+    std::shared_ptr<_C2MappingBlock2DImpl::Mapped> mapping() const { return mMapping; }
+
+private:
+    std::shared_ptr<_C2MappingBlock2DImpl::Mapped> mMapping;
+};
+
+/**
+ * Block implementation.
+ */
+class C2Block2D::Impl : public _C2MappingBlock2DImpl {
+public:
+    using _C2MappingBlock2DImpl::_C2MappingBlock2DImpl;
+    virtual ~Impl() override = default;
+};
+
+const C2Handle *C2Block2D::handle() const {
+    return mImpl->handle();
+}
+
+C2Allocator::id_t C2Block2D::getAllocatorId() const {
+    return mImpl->getAllocatorId();
+}
+
+C2Block2D::C2Block2D(std::shared_ptr<Impl> impl, const _C2PlanarSectionAspect &section)
+    // always clamp subsection to parent (impl) crop for safety
+    : _C2PlanarSectionAspect(impl.get(), section.crop()), mImpl(impl) {
+}
+
+/**
+ * Graphic view implementation.
+ *
+ * range of Impl is the mapped range of the underlying allocation. range of View is the current
+ * crop.
+ */
+class C2GraphicView::Impl : public _C2MappedBlock2DImpl {
+public:
+    using _C2MappedBlock2DImpl::_C2MappedBlock2DImpl;
+    virtual ~Impl() override = default;
+};
+
+C2GraphicView::C2GraphicView(std::shared_ptr<Impl> impl, const _C2PlanarSectionAspect &section)
+    : _C2EditablePlanarSectionAspect(impl.get(), section.crop()), mImpl(impl) {
+}
+
+const uint8_t *const *C2GraphicView::data() const {
+    return mImpl->mapping()->data();
+}
+
+uint8_t *const *C2GraphicView::data() {
+    return mImpl->mapping()->data();
+}
+
+const C2PlanarLayout C2GraphicView::layout() const {
+    return mImpl->mapping()->layout();
+}
+
+const C2GraphicView C2GraphicView::subView(const C2Rect &rect) const {
+    return C2GraphicView(mImpl, C2PlanarSection(*mImpl, rect));
+}
+
+C2GraphicView C2GraphicView::subView(const C2Rect &rect) {
+    return C2GraphicView(mImpl, C2PlanarSection(*mImpl, rect));
+}
+
+c2_status_t C2GraphicView::error() const {
+    return mImpl->mapping()->error();
+}
+
+/**
+ * Const graphic block implementation.
+ */
+C2ConstGraphicBlock::C2ConstGraphicBlock(
+        std::shared_ptr<Impl> impl, const _C2PlanarSectionAspect &section, C2Fence fence)
+    : C2Block2D(impl, section), mFence(fence) { }
+
+C2Acquirable<const C2GraphicView> C2ConstGraphicBlock::map() const {
+    C2Fence fence;
+    std::shared_ptr<_C2MappingBlock2DImpl::Mapped> mapping =
+        mImpl->map(false /* writable */, &fence);
+    std::shared_ptr<GraphicViewBuddy::Impl> gvi =
+        std::shared_ptr<GraphicViewBuddy::Impl>(new GraphicViewBuddy::Impl(*mImpl, mapping));
+    return AcquirableConstGraphicViewBuddy(
+            mapping->error(), fence, GraphicViewBuddy(gvi, C2PlanarSection(*mImpl, crop())));
+}
+
+C2ConstGraphicBlock C2ConstGraphicBlock::subBlock(const C2Rect &rect) const {
+    return C2ConstGraphicBlock(mImpl, C2PlanarSection(*mImpl, crop().intersect(rect)), mFence);
+}
+
+/**
+ * Graphic block implementation.
+ */
+C2GraphicBlock::C2GraphicBlock(
+    std::shared_ptr<Impl> impl, const _C2PlanarSectionAspect &section)
+    : C2Block2D(impl, section) { }
+
+C2Acquirable<C2GraphicView> C2GraphicBlock::map() {
+    C2Fence fence;
+    std::shared_ptr<_C2MappingBlock2DImpl::Mapped> mapping =
+        mImpl->map(true /* writable */, &fence);
+    std::shared_ptr<GraphicViewBuddy::Impl> gvi =
+        std::shared_ptr<GraphicViewBuddy::Impl>(new GraphicViewBuddy::Impl(*mImpl, mapping));
+    return AcquirableGraphicViewBuddy(
+            mapping->error(), fence, GraphicViewBuddy(gvi, C2PlanarSection(*mImpl, crop())));
+}
+
+C2ConstGraphicBlock C2GraphicBlock::share(const C2Rect &crop, C2Fence fence) {
+    return ConstGraphicBlockBuddy(mImpl, C2PlanarSection(*mImpl, crop), fence);
+}
+
+/**
+ * Basic block pool implementations.
+ */
+C2BasicGraphicBlockPool::C2BasicGraphicBlockPool(
+        const std::shared_ptr<C2Allocator> &allocator)
+  : mAllocator(allocator) {}
+
+c2_status_t C2BasicGraphicBlockPool::fetchGraphicBlock(
+        uint32_t width,
+        uint32_t height,
+        uint32_t format,
+        C2MemoryUsage usage,
+        std::shared_ptr<C2GraphicBlock> *block /* nonnull */) {
+    block->reset();
+
+    std::shared_ptr<C2GraphicAllocation> alloc;
+    c2_status_t err = mAllocator->newGraphicAllocation(width, height, format, usage, &alloc);
+    if (err != C2_OK) {
+        return err;
+    }
+
+    *block = _C2BlockFactory::CreateGraphicBlock(alloc);
+
+    return C2_OK;
+}
+
+std::shared_ptr<C2GraphicBlock> _C2BlockFactory::CreateGraphicBlock(
+        const std::shared_ptr<C2GraphicAllocation> &alloc,
+        const std::shared_ptr<_C2BlockPoolData> &data, const C2Rect &allottedCrop) {
+    std::shared_ptr<C2Block2D::Impl> impl =
+        std::make_shared<C2Block2D::Impl>(alloc, data, allottedCrop);
+    return std::shared_ptr<C2GraphicBlock>(new C2GraphicBlock(impl, *impl));
+}
+
+std::shared_ptr<_C2BlockPoolData> _C2BlockFactory::GetGraphicBlockPoolData(
+        const C2Block2D &block) {
+    if (block.mImpl) {
+        return block.mImpl->poolData();
+    }
+    return nullptr;
+}
+
+std::shared_ptr<C2GraphicBlock> _C2BlockFactory::CreateGraphicBlock(
+        const C2Handle *cHandle,
+        const std::shared_ptr<BufferPoolData> &data) {
+    // TODO: get proper allocator? and mutex?
+    static std::unique_ptr<C2AllocatorGralloc> sAllocator = std::make_unique<C2AllocatorGralloc>(0);
+
+    std::shared_ptr<C2GraphicAllocation> alloc;
+    if (C2AllocatorGralloc::isValid(cHandle)) {
+        native_handle_t *handle = native_handle_clone(cHandle);
+        if (handle) {
+            c2_status_t err = sAllocator->priorGraphicAllocation(handle, &alloc);
+            const std::shared_ptr<C2PooledBlockPoolData> poolData =
+                    std::make_shared<C2PooledBlockPoolData>(data);
+            if (err == C2_OK && poolData) {
+                // TODO: config setup?
+                std::shared_ptr<C2GraphicBlock> block =
+                        _C2BlockFactory::CreateGraphicBlock(alloc, poolData);
+                return block;
+            }
+        }
+    }
+    return nullptr;
+};
+
+
+/* ========================================== BUFFER ========================================= */
+
+class C2BufferData::Impl {
+public:
+    explicit Impl(const std::vector<C2ConstLinearBlock> &blocks)
+        : mType(blocks.size() == 1 ? LINEAR : LINEAR_CHUNKS),
+          mLinearBlocks(blocks) {
+    }
+
+    explicit Impl(const std::vector<C2ConstGraphicBlock> &blocks)
+        : mType(blocks.size() == 1 ? GRAPHIC : GRAPHIC_CHUNKS),
+          mGraphicBlocks(blocks) {
+    }
+
+    type_t type() const { return mType; }
+    const std::vector<C2ConstLinearBlock> &linearBlocks() const { return mLinearBlocks; }
+    const std::vector<C2ConstGraphicBlock> &graphicBlocks() const { return mGraphicBlocks; }
+
+private:
+    type_t mType;
+    std::vector<C2ConstLinearBlock> mLinearBlocks;
+    std::vector<C2ConstGraphicBlock> mGraphicBlocks;
+};
+
+C2BufferData::C2BufferData(const std::vector<C2ConstLinearBlock> &blocks) : mImpl(new Impl(blocks)) {}
+C2BufferData::C2BufferData(const std::vector<C2ConstGraphicBlock> &blocks) : mImpl(new Impl(blocks)) {}
+
+C2BufferData::type_t C2BufferData::type() const { return mImpl->type(); }
+
+const std::vector<C2ConstLinearBlock> C2BufferData::linearBlocks() const {
+    return mImpl->linearBlocks();
+}
+
+const std::vector<C2ConstGraphicBlock> C2BufferData::graphicBlocks() const {
+    return mImpl->graphicBlocks();
+}
+
+class C2Buffer::Impl {
+public:
+    Impl(C2Buffer *thiz, const std::vector<C2ConstLinearBlock> &blocks)
+        : mThis(thiz), mData(blocks) {}
+    Impl(C2Buffer *thiz, const std::vector<C2ConstGraphicBlock> &blocks)
+        : mThis(thiz), mData(blocks) {}
+
+    ~Impl() {
+        for (const auto &pair : mNotify) {
+            pair.first(mThis, pair.second);
+        }
+    }
+
+    const C2BufferData &data() const { return mData; }
+
+    c2_status_t registerOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg) {
+        auto it = std::find_if(
+                mNotify.begin(), mNotify.end(),
+                [onDestroyNotify, arg] (const auto &pair) {
+                    return pair.first == onDestroyNotify && pair.second == arg;
+                });
+        if (it != mNotify.end()) {
+            return C2_DUPLICATE;
+        }
+        mNotify.emplace_back(onDestroyNotify, arg);
+        return C2_OK;
+    }
+
+    c2_status_t unregisterOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg) {
+        auto it = std::find_if(
+                mNotify.begin(), mNotify.end(),
+                [onDestroyNotify, arg] (const auto &pair) {
+                    return pair.first == onDestroyNotify && pair.second == arg;
+                });
+        if (it == mNotify.end()) {
+            return C2_NOT_FOUND;
+        }
+        mNotify.erase(it);
+        return C2_OK;
+    }
+
+    std::vector<std::shared_ptr<const C2Info>> info() const {
+        std::vector<std::shared_ptr<const C2Info>> result(mInfos.size());
+        std::transform(
+                mInfos.begin(), mInfos.end(), result.begin(),
+                [] (const auto &elem) { return elem.second; });
+        return result;
+    }
+
+    c2_status_t setInfo(const std::shared_ptr<C2Info> &info) {
+        // To "update" you need to erase the existing one if any, and then insert.
+        (void) mInfos.erase(info->coreIndex());
+        (void) mInfos.insert({ info->coreIndex(), info });
+        return C2_OK;
+    }
+
+    bool hasInfo(C2Param::Type index) const {
+        return mInfos.count(index.coreIndex()) > 0;
+    }
+
+    std::shared_ptr<const C2Info> getInfo(C2Param::Type index) const {
+        auto it = mInfos.find(index.coreIndex());
+        if (it == mInfos.end()) {
+            return nullptr;
+        }
+        return std::const_pointer_cast<const C2Info>(it->second);
+    }
+
+    std::shared_ptr<C2Info> removeInfo(C2Param::Type index) {
+        auto it = mInfos.find(index.coreIndex());
+        if (it == mInfos.end()) {
+            return nullptr;
+        }
+        std::shared_ptr<C2Info> ret = it->second;
+        (void) mInfos.erase(it);
+        return ret;
+    }
+
+private:
+    C2Buffer * const mThis;
+    BufferDataBuddy mData;
+    std::map<C2Param::CoreIndex, std::shared_ptr<C2Info>> mInfos;
+    std::list<std::pair<OnDestroyNotify, void *>> mNotify;
+};
+
+C2Buffer::C2Buffer(const std::vector<C2ConstLinearBlock> &blocks)
+    : mImpl(new Impl(this, blocks)) {}
+
+C2Buffer::C2Buffer(const std::vector<C2ConstGraphicBlock> &blocks)
+    : mImpl(new Impl(this, blocks)) {}
+
+const C2BufferData C2Buffer::data() const { return mImpl->data(); }
+
+c2_status_t C2Buffer::registerOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg) {
+    return mImpl->registerOnDestroyNotify(onDestroyNotify, arg);
+}
+
+c2_status_t C2Buffer::unregisterOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg) {
+    return mImpl->unregisterOnDestroyNotify(onDestroyNotify, arg);
+}
+
+const std::vector<std::shared_ptr<const C2Info>> C2Buffer::info() const {
+    return mImpl->info();
+}
+
+c2_status_t C2Buffer::setInfo(const std::shared_ptr<C2Info> &info) {
+    return mImpl->setInfo(info);
+}
+
+bool C2Buffer::hasInfo(C2Param::Type index) const {
+    return mImpl->hasInfo(index);
+}
+
+std::shared_ptr<const C2Info> C2Buffer::getInfo(C2Param::Type index) const {
+    return mImpl->getInfo(index);
+}
+
+std::shared_ptr<C2Info> C2Buffer::removeInfo(C2Param::Type index) {
+    return mImpl->removeInfo(index);
+}
+
+// static
+std::shared_ptr<C2Buffer> C2Buffer::CreateLinearBuffer(const C2ConstLinearBlock &block) {
+    return std::shared_ptr<C2Buffer>(new C2Buffer({ block }));
+}
+
+// static
+std::shared_ptr<C2Buffer> C2Buffer::CreateGraphicBuffer(const C2ConstGraphicBlock &block) {
+    return std::shared_ptr<C2Buffer>(new C2Buffer({ block }));
+}
+
diff --git a/media/codec2/vndk/C2Config.cpp b/media/codec2/vndk/C2Config.cpp
new file mode 100644
index 0000000..34680a7
--- /dev/null
+++ b/media/codec2/vndk/C2Config.cpp
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2Config"
+#include <utils/Log.h>
+
+/**
+ * Define and initialize global config field descriptors in this cpp file
+ */
+#define __C2_GENERATE_GLOBAL_VARS__
+#include <C2Config.h>
+
+DEFINE_C2_ENUM_VALUE_CUSTOM_HELPER(C2Config::profile_t, ({
+        { "unused", C2Config::PROFILE_UNUSED },
+        { "aac-lc", C2Config::PROFILE_AAC_LC },
+        { "aac-main", C2Config::PROFILE_AAC_MAIN },
+        { "aac-ssr", C2Config::PROFILE_AAC_SSR },
+        { "aac-ltp", C2Config::PROFILE_AAC_LTP },
+        { "aac-he", C2Config::PROFILE_AAC_HE },
+        { "aac-scalable", C2Config::PROFILE_AAC_SCALABLE },
+        { "aac-er-lc", C2Config::PROFILE_AAC_ER_LC },
+        { "aac-er-scalable", C2Config::PROFILE_AAC_ER_SCALABLE },
+        { "aac-ld", C2Config::PROFILE_AAC_LD },
+        { "aac-he-ps", C2Config::PROFILE_AAC_HE_PS },
+        { "aac-eld", C2Config::PROFILE_AAC_ELD },
+        { "aac-xhe", C2Config::PROFILE_AAC_XHE },
+        { "mp2v-simple", C2Config::PROFILE_MP2V_SIMPLE },
+        { "mp2v-main", C2Config::PROFILE_MP2V_MAIN },
+        { "mp2v-snr-scalable", C2Config::PROFILE_MP2V_SNR_SCALABLE },
+        { "mp2v-spatially-scalable", C2Config::PROFILE_MP2V_SPATIALLY_SCALABLE },
+        { "mp2v-high", C2Config::PROFILE_MP2V_HIGH },
+        { "mp2v-422", C2Config::PROFILE_MP2V_422 },
+        { "mp2v-multiview", C2Config::PROFILE_MP2V_MULTIVIEW },
+        { "h263-baseline", C2Config::PROFILE_H263_BASELINE },
+        { "h263-h320", C2Config::PROFILE_H263_H320 },
+        { "h263-v1bc", C2Config::PROFILE_H263_V1BC },
+        { "h263-iswv2", C2Config::PROFILE_H263_ISWV2 },
+        { "h263-iswv3", C2Config::PROFILE_H263_ISWV3 },
+        { "h263-high-compression", C2Config::PROFILE_H263_HIGH_COMPRESSION },
+        { "h263-internet", C2Config::PROFILE_H263_INTERNET },
+        { "h263-interlace", C2Config::PROFILE_H263_INTERLACE },
+        { "h263-high-latency", C2Config::PROFILE_H263_HIGH_LATENCY },
+        { "mp4v-simple", C2Config::PROFILE_MP4V_SIMPLE },
+        { "mp4v-simple-scalable", C2Config::PROFILE_MP4V_SIMPLE_SCALABLE },
+        { "mp4v-core", C2Config::PROFILE_MP4V_CORE },
+        { "mp4v-main", C2Config::PROFILE_MP4V_MAIN },
+        { "mp4v-nbit", C2Config::PROFILE_MP4V_NBIT },
+        { "mp4v-arts", C2Config::PROFILE_MP4V_ARTS },
+        { "mp4v-core-scalable", C2Config::PROFILE_MP4V_CORE_SCALABLE },
+        { "mp4v-ace", C2Config::PROFILE_MP4V_ACE },
+        { "mp4v-advanced-core", C2Config::PROFILE_MP4V_ADVANCED_CORE },
+        { "mp4v-simple-studio", C2Config::PROFILE_MP4V_SIMPLE_STUDIO },
+        { "mp4v-core-studio", C2Config::PROFILE_MP4V_CORE_STUDIO },
+        { "mp4v-advanced-simple", C2Config::PROFILE_MP4V_ADVANCED_SIMPLE },
+        { "mp4v-fgs", C2Config::PROFILE_MP4V_FGS },
+        { "avc-baseline", C2Config::PROFILE_AVC_BASELINE },
+        { "avc-constrained-baseline", C2Config::PROFILE_AVC_CONSTRAINED_BASELINE },
+        { "avc-main", C2Config::PROFILE_AVC_MAIN },
+        { "avc-extended", C2Config::PROFILE_AVC_EXTENDED },
+        { "avc-high", C2Config::PROFILE_AVC_HIGH },
+        { "avc-progressive-high", C2Config::PROFILE_AVC_PROGRESSIVE_HIGH },
+        { "avc-constrained-high", C2Config::PROFILE_AVC_CONSTRAINED_HIGH },
+        { "avc-high-10", C2Config::PROFILE_AVC_HIGH_10 },
+        { "avc-progressive-high-10", C2Config::PROFILE_AVC_PROGRESSIVE_HIGH_10 },
+        { "avc-high-422", C2Config::PROFILE_AVC_HIGH_422 },
+        { "avc-high-444-predictive", C2Config::PROFILE_AVC_HIGH_444_PREDICTIVE },
+        { "avc-high-10-intra", C2Config::PROFILE_AVC_HIGH_10_INTRA },
+        { "avc-high-422-intra", C2Config::PROFILE_AVC_HIGH_422_INTRA },
+        { "avc-high-444-intra", C2Config::PROFILE_AVC_HIGH_444_INTRA },
+        { "avc-cavlc-444-intra", C2Config::PROFILE_AVC_CAVLC_444_INTRA },
+        { "avc-scalable-baseline", C2Config::PROFILE_AVC_SCALABLE_BASELINE },
+        { "avc-scalable-constrained-baseline", C2Config::PROFILE_AVC_SCALABLE_CONSTRAINED_BASELINE },
+        { "avc-scalable-high", C2Config::PROFILE_AVC_SCALABLE_HIGH },
+        { "avc-scalable-constrained-high", C2Config::PROFILE_AVC_SCALABLE_CONSTRAINED_HIGH },
+        { "avc-scalable-high-intra", C2Config::PROFILE_AVC_SCALABLE_HIGH_INTRA },
+        { "avc-multiview-high", C2Config::PROFILE_AVC_MULTIVIEW_HIGH },
+        { "avc-stereo-high", C2Config::PROFILE_AVC_STEREO_HIGH },
+        { "avc-mfc-high", C2Config::PROFILE_AVC_MFC_HIGH },
+        { "avc-multiview-depth-high", C2Config::PROFILE_AVC_MULTIVIEW_DEPTH_HIGH },
+        { "avc-mfc-depth-high", C2Config::PROFILE_AVC_MFC_DEPTH_HIGH },
+        { "avc-enhanced-multiview-depth-high", C2Config::PROFILE_AVC_ENHANCED_MULTIVIEW_DEPTH_HIGH },
+        { "hevc-main", C2Config::PROFILE_HEVC_MAIN },
+        { "hevc-main-10", C2Config::PROFILE_HEVC_MAIN_10 },
+        { "hevc-main-still", C2Config::PROFILE_HEVC_MAIN_STILL },
+        { "hevc-mono", C2Config::PROFILE_HEVC_MONO },
+        { "hevc-mono-12", C2Config::PROFILE_HEVC_MONO_12 },
+        { "hevc-mono-16", C2Config::PROFILE_HEVC_MONO_16 },
+        { "hevc-main-12", C2Config::PROFILE_HEVC_MAIN_12 },
+        { "hevc-main-422-10", C2Config::PROFILE_HEVC_MAIN_422_10 },
+        { "hevc-main-422-12", C2Config::PROFILE_HEVC_MAIN_422_12 },
+        { "hevc-main-444", C2Config::PROFILE_HEVC_MAIN_444 },
+        { "hevc-main-444-10", C2Config::PROFILE_HEVC_MAIN_444_10 },
+        { "hevc-main-444-12", C2Config::PROFILE_HEVC_MAIN_444_12 },
+        { "hevc-main-intra", C2Config::PROFILE_HEVC_MAIN_INTRA },
+        { "hevc-main-10-intra", C2Config::PROFILE_HEVC_MAIN_10_INTRA },
+        { "hevc-main-12-intra", C2Config::PROFILE_HEVC_MAIN_12_INTRA },
+        { "hevc-main-422-10-intra", C2Config::PROFILE_HEVC_MAIN_422_10_INTRA },
+        { "hevc-main-422-12-intra", C2Config::PROFILE_HEVC_MAIN_422_12_INTRA },
+        { "hevc-main-444-intra", C2Config::PROFILE_HEVC_MAIN_444_INTRA },
+        { "hevc-main-444-10-intra", C2Config::PROFILE_HEVC_MAIN_444_10_INTRA },
+        { "hevc-main-444-12-intra", C2Config::PROFILE_HEVC_MAIN_444_12_INTRA },
+        { "hevc-main-444-16-intra", C2Config::PROFILE_HEVC_MAIN_444_16_INTRA },
+        { "hevc-main-444-still", C2Config::PROFILE_HEVC_MAIN_444_STILL },
+        { "hevc-main-444-16-still", C2Config::PROFILE_HEVC_MAIN_444_16_STILL },
+        { "hevc-high-444", C2Config::PROFILE_HEVC_HIGH_444 },
+        { "hevc-high-444-10", C2Config::PROFILE_HEVC_HIGH_444_10 },
+        { "hevc-high-444-14", C2Config::PROFILE_HEVC_HIGH_444_14 },
+        { "hevc-high-444-16-intra", C2Config::PROFILE_HEVC_HIGH_444_16_INTRA },
+        { "hevc-sx-main", C2Config::PROFILE_HEVC_SX_MAIN },
+        { "hevc-sx-main-10", C2Config::PROFILE_HEVC_SX_MAIN_10 },
+        { "hevc-sx-main-444", C2Config::PROFILE_HEVC_SX_MAIN_444 },
+        { "hevc-sx-main-444-10", C2Config::PROFILE_HEVC_SX_MAIN_444_10 },
+        { "hevc-sx-high-444", C2Config::PROFILE_HEVC_SX_HIGH_444 },
+        { "hevc-sx-high-444-10", C2Config::PROFILE_HEVC_SX_HIGH_444_10 },
+        { "hevc-sx-high-444-14", C2Config::PROFILE_HEVC_SX_HIGH_444_14 },
+        { "hevc-multiview-main", C2Config::PROFILE_HEVC_MULTIVIEW_MAIN },
+        { "hevc-scalable-main", C2Config::PROFILE_HEVC_SCALABLE_MAIN },
+        { "hevc-scalable-main-10", C2Config::PROFILE_HEVC_SCALABLE_MAIN_10 },
+        { "hevc-scalable-mono", C2Config::PROFILE_HEVC_SCALABLE_MONO },
+        { "hevc-scalable-mono-12", C2Config::PROFILE_HEVC_SCALABLE_MONO_12 },
+        { "hevc-scalable-mono-16", C2Config::PROFILE_HEVC_SCALABLE_MONO_16 },
+        { "hevc-scalable-main-444", C2Config::PROFILE_HEVC_SCALABLE_MAIN_444 },
+        { "hevc-3d-main", C2Config::PROFILE_HEVC_3D_MAIN },
+        { "vp9-0", C2Config::PROFILE_VP9_0 },
+        { "vp9-1", C2Config::PROFILE_VP9_1 },
+        { "vp9-2", C2Config::PROFILE_VP9_2 },
+        { "vp9-3", C2Config::PROFILE_VP9_3 },
+        { "av1-0", C2Config::PROFILE_AV1_0 },
+        { "av1-1", C2Config::PROFILE_AV1_1 },
+        { "av1-2", C2Config::PROFILE_AV1_2 },
+}))
+
+DEFINE_C2_ENUM_VALUE_CUSTOM_HELPER(C2Config::level_t, ({
+        { "unused", C2Config::LEVEL_UNUSED },
+        { "mp2v-low", C2Config::LEVEL_MP2V_LOW },
+        { "mp2v-main", C2Config::LEVEL_MP2V_MAIN },
+        { "mp2v-high-1440", C2Config::LEVEL_MP2V_HIGH_1440 },
+        { "mp2v-high", C2Config::LEVEL_MP2V_HIGH },
+        { "mp2v-highp", C2Config::LEVEL_MP2V_HIGHP },
+        { "h263-10", C2Config::LEVEL_H263_10 },
+        { "h263-20", C2Config::LEVEL_H263_20 },
+        { "h263-30", C2Config::LEVEL_H263_30 },
+        { "h263-40", C2Config::LEVEL_H263_40 },
+        { "h263-45", C2Config::LEVEL_H263_45 },
+        { "h263-50", C2Config::LEVEL_H263_50 },
+        { "h263-60", C2Config::LEVEL_H263_60 },
+        { "h263-70", C2Config::LEVEL_H263_70 },
+        { "mp4v-0", C2Config::LEVEL_MP4V_0 },
+        { "mp4v-0b", C2Config::LEVEL_MP4V_0B },
+        { "mp4v-1", C2Config::LEVEL_MP4V_1 },
+        { "mp4v-2", C2Config::LEVEL_MP4V_2 },
+        { "mp4v-3", C2Config::LEVEL_MP4V_3 },
+        { "mp4v-3b", C2Config::LEVEL_MP4V_3B },
+        { "mp4v-4", C2Config::LEVEL_MP4V_4 },
+        { "mp4v-4a", C2Config::LEVEL_MP4V_4A },
+        { "mp4v-5", C2Config::LEVEL_MP4V_5 },
+        { "mp4v-6", C2Config::LEVEL_MP4V_6 },
+        { "avc-1", C2Config::LEVEL_AVC_1 },
+        { "avc-1b", C2Config::LEVEL_AVC_1B },
+        { "avc-1.1", C2Config::LEVEL_AVC_1_1 },
+        { "avc-1.2", C2Config::LEVEL_AVC_1_2 },
+        { "avc-1.3", C2Config::LEVEL_AVC_1_3 },
+        { "avc-2", C2Config::LEVEL_AVC_2 },
+        { "avc-2.1", C2Config::LEVEL_AVC_2_1 },
+        { "avc-2.2", C2Config::LEVEL_AVC_2_2 },
+        { "avc-3", C2Config::LEVEL_AVC_3 },
+        { "avc-3.1", C2Config::LEVEL_AVC_3_1 },
+        { "avc-3.2", C2Config::LEVEL_AVC_3_2 },
+        { "avc-4", C2Config::LEVEL_AVC_4 },
+        { "avc-4.1", C2Config::LEVEL_AVC_4_1 },
+        { "avc-4.2", C2Config::LEVEL_AVC_4_2 },
+        { "avc-5", C2Config::LEVEL_AVC_5 },
+        { "avc-5.1", C2Config::LEVEL_AVC_5_1 },
+        { "avc-5.2", C2Config::LEVEL_AVC_5_2 },
+        { "avc-6", C2Config::LEVEL_AVC_6 },
+        { "avc-6.1", C2Config::LEVEL_AVC_6_1 },
+        { "avc-6.2", C2Config::LEVEL_AVC_6_2 },
+        { "hevc-main-1", C2Config::LEVEL_HEVC_MAIN_1 },
+        { "hevc-main-2", C2Config::LEVEL_HEVC_MAIN_2 },
+        { "hevc-main-2.1", C2Config::LEVEL_HEVC_MAIN_2_1 },
+        { "hevc-main-3", C2Config::LEVEL_HEVC_MAIN_3 },
+        { "hevc-main-3.1", C2Config::LEVEL_HEVC_MAIN_3_1 },
+        { "hevc-main-4", C2Config::LEVEL_HEVC_MAIN_4 },
+        { "hevc-main-4.1", C2Config::LEVEL_HEVC_MAIN_4_1 },
+        { "hevc-main-5", C2Config::LEVEL_HEVC_MAIN_5 },
+        { "hevc-main-5.1", C2Config::LEVEL_HEVC_MAIN_5_1 },
+        { "hevc-main-5.2", C2Config::LEVEL_HEVC_MAIN_5_2 },
+        { "hevc-main-6", C2Config::LEVEL_HEVC_MAIN_6 },
+        { "hevc-main-6.1", C2Config::LEVEL_HEVC_MAIN_6_1 },
+        { "hevc-main-6.2", C2Config::LEVEL_HEVC_MAIN_6_2 },
+        { "hevc-high-4", C2Config::LEVEL_HEVC_HIGH_4 },
+        { "hevc-high-4.1", C2Config::LEVEL_HEVC_HIGH_4_1 },
+        { "hevc-high-5", C2Config::LEVEL_HEVC_HIGH_5 },
+        { "hevc-high-5.1", C2Config::LEVEL_HEVC_HIGH_5_1 },
+        { "hevc-high-5.2", C2Config::LEVEL_HEVC_HIGH_5_2 },
+        { "hevc-high-6", C2Config::LEVEL_HEVC_HIGH_6 },
+        { "hevc-high-6.1", C2Config::LEVEL_HEVC_HIGH_6_1 },
+        { "hevc-high-6.2", C2Config::LEVEL_HEVC_HIGH_6_2 },
+        { "vp9-1", C2Config::LEVEL_VP9_1 },
+        { "vp9-1.1", C2Config::LEVEL_VP9_1_1 },
+        { "vp9-2", C2Config::LEVEL_VP9_2 },
+        { "vp9-2.1", C2Config::LEVEL_VP9_2_1 },
+        { "vp9-3", C2Config::LEVEL_VP9_3 },
+        { "vp9-3.1", C2Config::LEVEL_VP9_3_1 },
+        { "vp9-4", C2Config::LEVEL_VP9_4 },
+        { "vp9-4.1", C2Config::LEVEL_VP9_4_1 },
+        { "vp9-5", C2Config::LEVEL_VP9_5 },
+        { "vp9-5.1", C2Config::LEVEL_VP9_5_1 },
+        { "vp9-5.2", C2Config::LEVEL_VP9_5_2 },
+        { "vp9-6", C2Config::LEVEL_VP9_6 },
+        { "vp9-6.1", C2Config::LEVEL_VP9_6_1 },
+        { "vp9-6.2", C2Config::LEVEL_VP9_6_2 },
+        { "av1-2", C2Config::LEVEL_AV1_2 },
+        { "av1-2.1", C2Config::LEVEL_AV1_2_1 },
+        { "av1-2.2", C2Config::LEVEL_AV1_2_2 },
+        { "av1-2.3", C2Config::LEVEL_AV1_2_3 },
+        { "av1-3", C2Config::LEVEL_AV1_3 },
+        { "av1-3.1", C2Config::LEVEL_AV1_3_1 },
+        { "av1-3.2", C2Config::LEVEL_AV1_3_2 },
+        { "av1-3.3", C2Config::LEVEL_AV1_3_3 },
+        { "av1-4", C2Config::LEVEL_AV1_4 },
+        { "av1-4.1", C2Config::LEVEL_AV1_4_1 },
+        { "av1-4.2", C2Config::LEVEL_AV1_4_2 },
+        { "av1-4.3", C2Config::LEVEL_AV1_4_3 },
+        { "av1-5", C2Config::LEVEL_AV1_5 },
+        { "av1-5.1", C2Config::LEVEL_AV1_5_1 },
+        { "av1-5.2", C2Config::LEVEL_AV1_5_2 },
+        { "av1-5.3", C2Config::LEVEL_AV1_5_3 },
+        { "av1-6", C2Config::LEVEL_AV1_6 },
+        { "av1-6.1", C2Config::LEVEL_AV1_6_1 },
+        { "av1-6.2", C2Config::LEVEL_AV1_6_2 },
+        { "av1-6.3", C2Config::LEVEL_AV1_6_3 },
+        { "av1-7", C2Config::LEVEL_AV1_7 },
+        { "av1-7.1", C2Config::LEVEL_AV1_7_1 },
+        { "av1-7.2", C2Config::LEVEL_AV1_7_2 },
+        { "av1-7.3", C2Config::LEVEL_AV1_7_3 },
+}))
+
+DEFINE_C2_ENUM_VALUE_CUSTOM_HELPER(C2BufferData::type_t, ({
+        { "invalid",        C2BufferData::INVALID },
+        { "linear",         C2BufferData::LINEAR },
+        { "linear-chunks",  C2BufferData::LINEAR_CHUNKS },
+        { "graphic",        C2BufferData::GRAPHIC },
+        { "graphic-chunks", C2BufferData::GRAPHIC_CHUNKS },
+}))
+
+
diff --git a/media/codec2/vndk/C2PlatformStorePluginLoader.cpp b/media/codec2/vndk/C2PlatformStorePluginLoader.cpp
new file mode 100644
index 0000000..4c330e5
--- /dev/null
+++ b/media/codec2/vndk/C2PlatformStorePluginLoader.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2PlatformStorePluginLoader"
+
+#include <dlfcn.h>
+
+#include <utils/Log.h>
+
+#include "C2PlatformStorePluginLoader.h"
+
+/* static */ android::Mutex C2PlatformStorePluginLoader::sMutex;
+/* static */ std::unique_ptr<C2PlatformStorePluginLoader> C2PlatformStorePluginLoader::sInstance;
+
+namespace /* unnamed */ {
+
+constexpr const char kStorePluginPath[] = "libc2plugin_store.so";
+
+}  // unnamed
+
+C2PlatformStorePluginLoader::C2PlatformStorePluginLoader(const char *libPath)
+    : mCreateBlockPool(nullptr) {
+    mLibHandle = dlopen(libPath, RTLD_NOW | RTLD_NODELETE);
+    if (mLibHandle == nullptr) {
+        ALOGD("Failed to load library: %s (%s)", libPath, dlerror());
+        return;
+    }
+    mCreateBlockPool = (CreateBlockPoolFunc)dlsym(mLibHandle, "CreateBlockPool");
+    if (mCreateBlockPool == nullptr) {
+        ALOGD("Failed to find symbol: CreateBlockPool (%s)", dlerror());
+    }
+    mCreateAllocator = (CreateAllocatorFunc)dlsym(mLibHandle, "CreateAllocator");
+    if (mCreateAllocator == nullptr) {
+        ALOGD("Failed to find symbol: CreateAllocator (%s)", dlerror());
+    }
+}
+
+C2PlatformStorePluginLoader::~C2PlatformStorePluginLoader() {
+    if (mLibHandle != nullptr) {
+        ALOGV("Closing handle");
+        dlclose(mLibHandle);
+    }
+}
+
+c2_status_t C2PlatformStorePluginLoader::createBlockPool(
+        ::C2Allocator::id_t allocatorId, ::C2BlockPool::local_id_t blockPoolId,
+        std::shared_ptr<C2BlockPool>* pool) {
+    if (mCreateBlockPool == nullptr) {
+        ALOGD("Handle or CreateBlockPool symbol is null");
+        return C2_NOT_FOUND;
+    }
+
+    std::shared_ptr<::C2BlockPool> ptr(mCreateBlockPool(allocatorId, blockPoolId));
+    if (ptr) {
+        *pool = ptr;
+        return C2_OK;
+    }
+    ALOGD("Failed to CreateBlockPool by allocator id: %u", allocatorId);
+    return C2_BAD_INDEX;
+}
+
+c2_status_t C2PlatformStorePluginLoader::createAllocator(
+        ::C2Allocator::id_t allocatorId, std::shared_ptr<C2Allocator>* const allocator) {
+    if (mCreateAllocator == nullptr) {
+        ALOGD("Handle or CreateAllocator symbol is null");
+        return C2_NOT_FOUND;
+    }
+
+    c2_status_t res = C2_CORRUPTED;
+    allocator->reset(mCreateAllocator(allocatorId, &res));
+    if (res != C2_OK) {
+        ALOGD("Failed to CreateAllocator by id: %u, res: %d", allocatorId, res);
+        allocator->reset();
+        return res;
+    }
+    return C2_OK;
+}
+
+// static
+const std::unique_ptr<C2PlatformStorePluginLoader>& C2PlatformStorePluginLoader::GetInstance() {
+    android::Mutex::Autolock _l(sMutex);
+    if (!sInstance) {
+        ALOGV("Loading library");
+        sInstance.reset(new C2PlatformStorePluginLoader(kStorePluginPath));
+    }
+    return sInstance;
+}
diff --git a/media/codec2/vndk/C2Store.cpp b/media/codec2/vndk/C2Store.cpp
new file mode 100644
index 0000000..f8afa7c
--- /dev/null
+++ b/media/codec2/vndk/C2Store.cpp
@@ -0,0 +1,994 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "C2Store"
+#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+#include <C2AllocatorGralloc.h>
+#include <C2AllocatorIon.h>
+#include <C2BufferPriv.h>
+#include <C2BqBufferPriv.h>
+#include <C2Component.h>
+#include <C2Config.h>
+#include <C2PlatformStorePluginLoader.h>
+#include <C2PlatformSupport.h>
+#include <util/C2InterfaceHelper.h>
+
+#include <dlfcn.h>
+#include <unistd.h> // getpagesize
+
+#include <map>
+#include <memory>
+#include <mutex>
+
+namespace android {
+
+/**
+ * Returns the preferred component store in this process to access its interface.
+ */
+std::shared_ptr<C2ComponentStore> GetPreferredCodec2ComponentStore();
+
+/**
+ * The platform allocator store provides basic allocator-types for the framework based on ion and
+ * gralloc. Allocators are not meant to be updatable.
+ *
+ * \todo Provide allocator based on ashmem
+ * \todo Move ion allocation into its HIDL or provide some mapping from memory usage to ion flags
+ * \todo Make this allocator store extendable
+ */
+class C2PlatformAllocatorStoreImpl : public C2PlatformAllocatorStore {
+public:
+    C2PlatformAllocatorStoreImpl();
+
+    virtual c2_status_t fetchAllocator(
+            id_t id, std::shared_ptr<C2Allocator> *const allocator) override;
+
+    virtual std::vector<std::shared_ptr<const C2Allocator::Traits>> listAllocators_nb()
+            const override {
+        return std::vector<std::shared_ptr<const C2Allocator::Traits>>(); /// \todo
+    }
+
+    virtual C2String getName() const override {
+        return "android.allocator-store";
+    }
+
+    void setComponentStore(std::shared_ptr<C2ComponentStore> store);
+
+    ~C2PlatformAllocatorStoreImpl() override = default;
+
+private:
+    /// returns a shared-singleton ion allocator
+    std::shared_ptr<C2Allocator> fetchIonAllocator();
+
+    /// returns a shared-singleton gralloc allocator
+    std::shared_ptr<C2Allocator> fetchGrallocAllocator();
+
+    /// returns a shared-singleton bufferqueue supporting gralloc allocator
+    std::shared_ptr<C2Allocator> fetchBufferQueueAllocator();
+
+    /// component store to use
+    std::mutex _mComponentStoreSetLock; // protects the entire updating _mComponentStore and its
+                                        // dependencies
+    std::mutex _mComponentStoreReadLock; // must protect only read/write of _mComponentStore
+    std::shared_ptr<C2ComponentStore> _mComponentStore;
+};
+
+C2PlatformAllocatorStoreImpl::C2PlatformAllocatorStoreImpl() {
+}
+
+c2_status_t C2PlatformAllocatorStoreImpl::fetchAllocator(
+        id_t id, std::shared_ptr<C2Allocator> *const allocator) {
+    allocator->reset();
+    switch (id) {
+    // TODO: should we implement a generic registry for all, and use that?
+    case C2PlatformAllocatorStore::ION:
+    case C2AllocatorStore::DEFAULT_LINEAR:
+        *allocator = fetchIonAllocator();
+        break;
+
+    case C2PlatformAllocatorStore::GRALLOC:
+    case C2AllocatorStore::DEFAULT_GRAPHIC:
+        *allocator = fetchGrallocAllocator();
+        break;
+
+    case C2PlatformAllocatorStore::BUFFERQUEUE:
+        *allocator = fetchBufferQueueAllocator();
+        break;
+
+    default:
+        // Try to create allocator from platform store plugins.
+        c2_status_t res =
+                C2PlatformStorePluginLoader::GetInstance()->createAllocator(id, allocator);
+        if (res != C2_OK) {
+            return res;
+        }
+        break;
+    }
+    if (*allocator == nullptr) {
+        return C2_NO_MEMORY;
+    }
+    return C2_OK;
+}
+
+namespace {
+
+std::mutex gIonAllocatorMutex;
+std::weak_ptr<C2AllocatorIon> gIonAllocator;
+
+void UseComponentStoreForIonAllocator(
+        const std::shared_ptr<C2AllocatorIon> allocator,
+        std::shared_ptr<C2ComponentStore> store) {
+    C2AllocatorIon::UsageMapperFn mapper;
+    uint64_t minUsage = 0;
+    uint64_t maxUsage = C2MemoryUsage(C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE).expected;
+    size_t blockSize = getpagesize();
+
+    // query min and max usage as well as block size via supported values
+    C2StoreIonUsageInfo usageInfo;
+    std::vector<C2FieldSupportedValuesQuery> query = {
+        C2FieldSupportedValuesQuery::Possible(C2ParamField::Make(usageInfo, usageInfo.usage)),
+        C2FieldSupportedValuesQuery::Possible(C2ParamField::Make(usageInfo, usageInfo.capacity)),
+    };
+    c2_status_t res = store->querySupportedValues_sm(query);
+    if (res == C2_OK) {
+        if (query[0].status == C2_OK) {
+            const C2FieldSupportedValues &fsv = query[0].values;
+            if (fsv.type == C2FieldSupportedValues::FLAGS && !fsv.values.empty()) {
+                minUsage = fsv.values[0].u64;
+                maxUsage = 0;
+                for (C2Value::Primitive v : fsv.values) {
+                    maxUsage |= v.u64;
+                }
+            }
+        }
+        if (query[1].status == C2_OK) {
+            const C2FieldSupportedValues &fsv = query[1].values;
+            if (fsv.type == C2FieldSupportedValues::RANGE && fsv.range.step.u32 > 0) {
+                blockSize = fsv.range.step.u32;
+            }
+        }
+
+        mapper = [store](C2MemoryUsage usage, size_t capacity,
+                         size_t *align, unsigned *heapMask, unsigned *flags) -> c2_status_t {
+            if (capacity > UINT32_MAX) {
+                return C2_BAD_VALUE;
+            }
+            C2StoreIonUsageInfo usageInfo = { usage.expected, capacity };
+            std::vector<std::unique_ptr<C2SettingResult>> failures; // TODO: remove
+            c2_status_t res = store->config_sm({&usageInfo}, &failures);
+            if (res == C2_OK) {
+                *align = usageInfo.minAlignment;
+                *heapMask = usageInfo.heapMask;
+                *flags = usageInfo.allocFlags;
+            }
+            return res;
+        };
+    }
+
+    allocator->setUsageMapper(mapper, minUsage, maxUsage, blockSize);
+}
+
+}
+
+void C2PlatformAllocatorStoreImpl::setComponentStore(std::shared_ptr<C2ComponentStore> store) {
+    // technically this set lock is not needed, but is here for safety in case we add more
+    // getter orders
+    std::lock_guard<std::mutex> lock(_mComponentStoreSetLock);
+    {
+        std::lock_guard<std::mutex> lock(_mComponentStoreReadLock);
+        _mComponentStore = store;
+    }
+    std::shared_ptr<C2AllocatorIon> allocator;
+    {
+        std::lock_guard<std::mutex> lock(gIonAllocatorMutex);
+        allocator = gIonAllocator.lock();
+    }
+    if (allocator) {
+        UseComponentStoreForIonAllocator(allocator, store);
+    }
+}
+
+std::shared_ptr<C2Allocator> C2PlatformAllocatorStoreImpl::fetchIonAllocator() {
+    std::lock_guard<std::mutex> lock(gIonAllocatorMutex);
+    std::shared_ptr<C2AllocatorIon> allocator = gIonAllocator.lock();
+    if (allocator == nullptr) {
+        std::shared_ptr<C2ComponentStore> componentStore;
+        {
+            std::lock_guard<std::mutex> lock(_mComponentStoreReadLock);
+            componentStore = _mComponentStore;
+        }
+        allocator = std::make_shared<C2AllocatorIon>(C2PlatformAllocatorStore::ION);
+        UseComponentStoreForIonAllocator(allocator, componentStore);
+        gIonAllocator = allocator;
+    }
+    return allocator;
+}
+
+std::shared_ptr<C2Allocator> C2PlatformAllocatorStoreImpl::fetchGrallocAllocator() {
+    static std::mutex mutex;
+    static std::weak_ptr<C2Allocator> grallocAllocator;
+    std::lock_guard<std::mutex> lock(mutex);
+    std::shared_ptr<C2Allocator> allocator = grallocAllocator.lock();
+    if (allocator == nullptr) {
+        allocator = std::make_shared<C2AllocatorGralloc>(C2PlatformAllocatorStore::GRALLOC);
+        grallocAllocator = allocator;
+    }
+    return allocator;
+}
+
+std::shared_ptr<C2Allocator> C2PlatformAllocatorStoreImpl::fetchBufferQueueAllocator() {
+    static std::mutex mutex;
+    static std::weak_ptr<C2Allocator> grallocAllocator;
+    std::lock_guard<std::mutex> lock(mutex);
+    std::shared_ptr<C2Allocator> allocator = grallocAllocator.lock();
+    if (allocator == nullptr) {
+        allocator = std::make_shared<C2AllocatorGralloc>(
+                C2PlatformAllocatorStore::BUFFERQUEUE, true);
+        grallocAllocator = allocator;
+    }
+    return allocator;
+}
+
+namespace {
+    std::mutex gPreferredComponentStoreMutex;
+    std::shared_ptr<C2ComponentStore> gPreferredComponentStore;
+
+    std::mutex gPlatformAllocatorStoreMutex;
+    std::weak_ptr<C2PlatformAllocatorStoreImpl> gPlatformAllocatorStore;
+}
+
+std::shared_ptr<C2AllocatorStore> GetCodec2PlatformAllocatorStore() {
+    std::lock_guard<std::mutex> lock(gPlatformAllocatorStoreMutex);
+    std::shared_ptr<C2PlatformAllocatorStoreImpl> store = gPlatformAllocatorStore.lock();
+    if (store == nullptr) {
+        store = std::make_shared<C2PlatformAllocatorStoreImpl>();
+        store->setComponentStore(GetPreferredCodec2ComponentStore());
+        gPlatformAllocatorStore = store;
+    }
+    return store;
+}
+
+void SetPreferredCodec2ComponentStore(std::shared_ptr<C2ComponentStore> componentStore) {
+    static std::mutex mutex;
+    std::lock_guard<std::mutex> lock(mutex); // don't interleve set-s
+
+    // update preferred store
+    {
+        std::lock_guard<std::mutex> lock(gPreferredComponentStoreMutex);
+        gPreferredComponentStore = componentStore;
+    }
+
+    // update platform allocator's store as well if it is alive
+    std::shared_ptr<C2PlatformAllocatorStoreImpl> allocatorStore;
+    {
+        std::lock_guard<std::mutex> lock(gPlatformAllocatorStoreMutex);
+        allocatorStore = gPlatformAllocatorStore.lock();
+    }
+    if (allocatorStore) {
+        allocatorStore->setComponentStore(componentStore);
+    }
+}
+
+std::shared_ptr<C2ComponentStore> GetPreferredCodec2ComponentStore() {
+    std::lock_guard<std::mutex> lock(gPreferredComponentStoreMutex);
+    return gPreferredComponentStore ? gPreferredComponentStore : GetCodec2PlatformComponentStore();
+}
+
+namespace {
+
+class _C2BlockPoolCache {
+public:
+    _C2BlockPoolCache() : mBlockPoolSeqId(C2BlockPool::PLATFORM_START + 1) {}
+
+    c2_status_t _createBlockPool(
+            C2PlatformAllocatorStore::id_t allocatorId,
+            std::shared_ptr<const C2Component> component,
+            C2BlockPool::local_id_t poolId,
+            std::shared_ptr<C2BlockPool> *pool) {
+        std::shared_ptr<C2AllocatorStore> allocatorStore =
+                GetCodec2PlatformAllocatorStore();
+        std::shared_ptr<C2Allocator> allocator;
+        c2_status_t res = C2_NOT_FOUND;
+
+        switch(allocatorId) {
+            case C2PlatformAllocatorStore::ION:
+            case C2AllocatorStore::DEFAULT_LINEAR:
+                res = allocatorStore->fetchAllocator(
+                        C2AllocatorStore::DEFAULT_LINEAR, &allocator);
+                if (res == C2_OK) {
+                    std::shared_ptr<C2BlockPool> ptr =
+                            std::make_shared<C2PooledBlockPool>(
+                                    allocator, poolId);
+                    *pool = ptr;
+                    mBlockPools[poolId] = ptr;
+                    mComponents[poolId] = component;
+                }
+                break;
+            case C2PlatformAllocatorStore::GRALLOC:
+            case C2AllocatorStore::DEFAULT_GRAPHIC:
+                res = allocatorStore->fetchAllocator(
+                        C2AllocatorStore::DEFAULT_GRAPHIC, &allocator);
+                if (res == C2_OK) {
+                    std::shared_ptr<C2BlockPool> ptr =
+                        std::make_shared<C2PooledBlockPool>(allocator, poolId);
+                    *pool = ptr;
+                    mBlockPools[poolId] = ptr;
+                    mComponents[poolId] = component;
+                }
+                break;
+            case C2PlatformAllocatorStore::BUFFERQUEUE:
+                res = allocatorStore->fetchAllocator(
+                        C2PlatformAllocatorStore::BUFFERQUEUE, &allocator);
+                if (res == C2_OK) {
+                    std::shared_ptr<C2BlockPool> ptr =
+                            std::make_shared<C2BufferQueueBlockPool>(
+                                    allocator, poolId);
+                    *pool = ptr;
+                    mBlockPools[poolId] = ptr;
+                    mComponents[poolId] = component;
+                }
+                break;
+            default:
+                // Try to create block pool from platform store plugins.
+                std::shared_ptr<C2BlockPool> ptr;
+                res = C2PlatformStorePluginLoader::GetInstance()->createBlockPool(
+                        allocatorId, poolId, &ptr);
+                if (res == C2_OK) {
+                    *pool = ptr;
+                    mBlockPools[poolId] = ptr;
+                    mComponents[poolId] = component;
+                }
+                break;
+        }
+        return res;
+    }
+
+    c2_status_t createBlockPool(
+            C2PlatformAllocatorStore::id_t allocatorId,
+            std::shared_ptr<const C2Component> component,
+            std::shared_ptr<C2BlockPool> *pool) {
+        return _createBlockPool(allocatorId, component, mBlockPoolSeqId++, pool);
+    }
+
+    bool getBlockPool(
+            C2BlockPool::local_id_t blockPoolId,
+            std::shared_ptr<const C2Component> component,
+            std::shared_ptr<C2BlockPool> *pool) {
+        // TODO: use one iterator for multiple blockpool type scalability.
+        std::shared_ptr<C2BlockPool> ptr;
+        auto it = mBlockPools.find(blockPoolId);
+        if (it != mBlockPools.end()) {
+            ptr = it->second.lock();
+            if (!ptr) {
+                mBlockPools.erase(it);
+                mComponents.erase(blockPoolId);
+            } else {
+                auto found = mComponents.find(blockPoolId);
+                if (component == found->second.lock()) {
+                    *pool = ptr;
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+private:
+    C2BlockPool::local_id_t mBlockPoolSeqId;
+
+    std::map<C2BlockPool::local_id_t, std::weak_ptr<C2BlockPool>> mBlockPools;
+    std::map<C2BlockPool::local_id_t, std::weak_ptr<const C2Component>> mComponents;
+};
+
+static std::unique_ptr<_C2BlockPoolCache> sBlockPoolCache =
+    std::make_unique<_C2BlockPoolCache>();
+static std::mutex sBlockPoolCacheMutex;
+
+} // anynymous namespace
+
+c2_status_t GetCodec2BlockPool(
+        C2BlockPool::local_id_t id, std::shared_ptr<const C2Component> component,
+        std::shared_ptr<C2BlockPool> *pool) {
+    pool->reset();
+    std::lock_guard<std::mutex> lock(sBlockPoolCacheMutex);
+    std::shared_ptr<C2AllocatorStore> allocatorStore = GetCodec2PlatformAllocatorStore();
+    std::shared_ptr<C2Allocator> allocator;
+    c2_status_t res = C2_NOT_FOUND;
+
+    if (id >= C2BlockPool::PLATFORM_START) {
+        if (sBlockPoolCache->getBlockPool(id, component, pool)) {
+            return C2_OK;
+        }
+    }
+
+    switch (id) {
+    case C2BlockPool::BASIC_LINEAR:
+        res = allocatorStore->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &allocator);
+        if (res == C2_OK) {
+            *pool = std::make_shared<C2BasicLinearBlockPool>(allocator);
+        }
+        break;
+    case C2BlockPool::BASIC_GRAPHIC:
+        res = allocatorStore->fetchAllocator(C2AllocatorStore::DEFAULT_GRAPHIC, &allocator);
+        if (res == C2_OK) {
+            *pool = std::make_shared<C2BasicGraphicBlockPool>(allocator);
+        }
+        break;
+    // TODO: remove this. this is temporary
+    case C2BlockPool::PLATFORM_START:
+        res = sBlockPoolCache->_createBlockPool(
+                C2PlatformAllocatorStore::BUFFERQUEUE, component, id, pool);
+        break;
+    default:
+        break;
+    }
+    return res;
+}
+
+c2_status_t CreateCodec2BlockPool(
+        C2PlatformAllocatorStore::id_t allocatorId,
+        std::shared_ptr<const C2Component> component,
+        std::shared_ptr<C2BlockPool> *pool) {
+    pool->reset();
+
+    std::lock_guard<std::mutex> lock(sBlockPoolCacheMutex);
+    return sBlockPoolCache->createBlockPool(allocatorId, component, pool);
+}
+
+class C2PlatformComponentStore : public C2ComponentStore {
+public:
+    virtual std::vector<std::shared_ptr<const C2Component::Traits>> listComponents() override;
+    virtual std::shared_ptr<C2ParamReflector> getParamReflector() const override;
+    virtual C2String getName() const override;
+    virtual c2_status_t querySupportedValues_sm(
+            std::vector<C2FieldSupportedValuesQuery> &fields) const override;
+    virtual c2_status_t querySupportedParams_nb(
+            std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const override;
+    virtual c2_status_t query_sm(
+            const std::vector<C2Param*> &stackParams,
+            const std::vector<C2Param::Index> &heapParamIndices,
+            std::vector<std::unique_ptr<C2Param>> *const heapParams) const override;
+    virtual c2_status_t createInterface(
+            C2String name, std::shared_ptr<C2ComponentInterface> *const interface) override;
+    virtual c2_status_t createComponent(
+            C2String name, std::shared_ptr<C2Component> *const component) override;
+    virtual c2_status_t copyBuffer(
+            std::shared_ptr<C2GraphicBuffer> src, std::shared_ptr<C2GraphicBuffer> dst) override;
+    virtual c2_status_t config_sm(
+            const std::vector<C2Param*> &params,
+            std::vector<std::unique_ptr<C2SettingResult>> *const failures) override;
+    C2PlatformComponentStore();
+
+    virtual ~C2PlatformComponentStore() override = default;
+
+private:
+
+    /**
+     * An object encapsulating a loaded component module.
+     *
+     * \todo provide a way to add traits to known components here to avoid loading the .so-s
+     * for listComponents
+     */
+    struct ComponentModule : public C2ComponentFactory,
+            public std::enable_shared_from_this<ComponentModule> {
+        virtual c2_status_t createComponent(
+                c2_node_id_t id, std::shared_ptr<C2Component> *component,
+                ComponentDeleter deleter = std::default_delete<C2Component>()) override;
+        virtual c2_status_t createInterface(
+                c2_node_id_t id, std::shared_ptr<C2ComponentInterface> *interface,
+                InterfaceDeleter deleter = std::default_delete<C2ComponentInterface>()) override;
+
+        /**
+         * \returns the traits of the component in this module.
+         */
+        std::shared_ptr<const C2Component::Traits> getTraits();
+
+        /**
+         * Creates an uninitialized component module.
+         *
+         * \param name[in]  component name.
+         *
+         * \note Only used by ComponentLoader.
+         */
+        ComponentModule()
+            : mInit(C2_NO_INIT),
+              mLibHandle(nullptr),
+              createFactory(nullptr),
+              destroyFactory(nullptr),
+              mComponentFactory(nullptr) {
+        }
+
+        /**
+         * Initializes a component module with a given library path. Must be called exactly once.
+         *
+         * \note Only used by ComponentLoader.
+         *
+         * \param libPath[in] library path
+         *
+         * \retval C2_OK        the component module has been successfully loaded
+         * \retval C2_NO_MEMORY not enough memory to loading the component module
+         * \retval C2_NOT_FOUND could not locate the component module
+         * \retval C2_CORRUPTED the component module could not be loaded (unexpected)
+         * \retval C2_REFUSED   permission denied to load the component module (unexpected)
+         * \retval C2_TIMED_OUT could not load the module within the time limit (unexpected)
+         */
+        c2_status_t init(std::string libPath);
+
+        virtual ~ComponentModule() override;
+
+    protected:
+        std::recursive_mutex mLock; ///< lock protecting mTraits
+        std::shared_ptr<C2Component::Traits> mTraits; ///< cached component traits
+
+        c2_status_t mInit; ///< initialization result
+
+        void *mLibHandle; ///< loaded library handle
+        C2ComponentFactory::CreateCodec2FactoryFunc createFactory; ///< loaded create function
+        C2ComponentFactory::DestroyCodec2FactoryFunc destroyFactory; ///< loaded destroy function
+        C2ComponentFactory *mComponentFactory; ///< loaded/created component factory
+    };
+
+    /**
+     * An object encapsulating a loadable component module.
+     *
+     * \todo make this also work for enumerations
+     */
+    struct ComponentLoader {
+        /**
+         * Load the component module.
+         *
+         * This method simply returns the component module if it is already currently loaded, or
+         * attempts to load it if it is not.
+         *
+         * \param module[out] pointer to the shared pointer where the loaded module shall be stored.
+         *                    This will be nullptr on error.
+         *
+         * \retval C2_OK        the component module has been successfully loaded
+         * \retval C2_NO_MEMORY not enough memory to loading the component module
+         * \retval C2_NOT_FOUND could not locate the component module
+         * \retval C2_CORRUPTED the component module could not be loaded
+         * \retval C2_REFUSED   permission denied to load the component module
+         */
+        c2_status_t fetchModule(std::shared_ptr<ComponentModule> *module) {
+            c2_status_t res = C2_OK;
+            std::lock_guard<std::mutex> lock(mMutex);
+            std::shared_ptr<ComponentModule> localModule = mModule.lock();
+            if (localModule == nullptr) {
+                localModule = std::make_shared<ComponentModule>();
+                res = localModule->init(mLibPath);
+                if (res == C2_OK) {
+                    mModule = localModule;
+                }
+            }
+            *module = localModule;
+            return res;
+        }
+
+        /**
+         * Creates a component loader for a specific library path (or name).
+         */
+        ComponentLoader(std::string libPath)
+            : mLibPath(libPath) {}
+
+    private:
+        std::mutex mMutex; ///< mutex guarding the module
+        std::weak_ptr<ComponentModule> mModule; ///< weak reference to the loaded module
+        std::string mLibPath; ///< library path
+    };
+
+    struct Interface : public C2InterfaceHelper {
+        std::shared_ptr<C2StoreIonUsageInfo> mIonUsageInfo;
+
+        Interface(std::shared_ptr<C2ReflectorHelper> reflector)
+            : C2InterfaceHelper(reflector) {
+            setDerivedInstance(this);
+
+            struct Setter {
+                static C2R setIonUsage(bool /* mayBlock */, C2P<C2StoreIonUsageInfo> &me) {
+                    me.set().heapMask = ~0;
+                    me.set().allocFlags = 0;
+                    me.set().minAlignment = 0;
+                    return C2R::Ok();
+                }
+            };
+
+            addParameter(
+                DefineParam(mIonUsageInfo, "ion-usage")
+                .withDefault(new C2StoreIonUsageInfo())
+                .withFields({
+                    C2F(mIonUsageInfo, usage).flags({C2MemoryUsage::CPU_READ | C2MemoryUsage::CPU_WRITE}),
+                    C2F(mIonUsageInfo, capacity).inRange(0, UINT32_MAX, 1024),
+                    C2F(mIonUsageInfo, heapMask).any(),
+                    C2F(mIonUsageInfo, allocFlags).flags({}),
+                    C2F(mIonUsageInfo, minAlignment).equalTo(0)
+                })
+                .withSetter(Setter::setIonUsage)
+                .build());
+        }
+    };
+
+    /**
+     * Retrieves the component module for a component.
+     *
+     * \param module pointer to a shared_pointer where the component module will be stored on
+     *               success.
+     *
+     * \retval C2_OK        the component loader has been successfully retrieved
+     * \retval C2_NO_MEMORY not enough memory to locate the component loader
+     * \retval C2_NOT_FOUND could not locate the component to be loaded
+     * \retval C2_CORRUPTED the component loader could not be identified due to some modules being
+     *                      corrupted (this can happen if the name does not refer to an already
+     *                      identified component but some components could not be loaded due to
+     *                      bad library)
+     * \retval C2_REFUSED   permission denied to find the component loader for the named component
+     *                      (this can happen if the name does not refer to an already identified
+     *                      component but some components could not be loaded due to lack of
+     *                      permissions)
+     */
+    c2_status_t findComponent(C2String name, std::shared_ptr<ComponentModule> *module);
+
+    /**
+     * Loads each component module and discover its contents.
+     */
+    void visitComponents();
+
+    std::mutex mMutex; ///< mutex guarding the component lists during construction
+    bool mVisited; ///< component modules visited
+    std::map<C2String, ComponentLoader> mComponents; ///< path -> component module
+    std::map<C2String, C2String> mComponentNameToPath; ///< name -> path
+    std::vector<std::shared_ptr<const C2Component::Traits>> mComponentList;
+
+    std::shared_ptr<C2ReflectorHelper> mReflector;
+    Interface mInterface;
+};
+
+c2_status_t C2PlatformComponentStore::ComponentModule::init(
+        std::string libPath) {
+    ALOGV("in %s", __func__);
+    ALOGV("loading dll");
+    mLibHandle = dlopen(libPath.c_str(), RTLD_NOW|RTLD_NODELETE);
+    LOG_ALWAYS_FATAL_IF(mLibHandle == nullptr,
+            "could not dlopen %s: %s", libPath.c_str(), dlerror());
+
+    createFactory =
+        (C2ComponentFactory::CreateCodec2FactoryFunc)dlsym(mLibHandle, "CreateCodec2Factory");
+    LOG_ALWAYS_FATAL_IF(createFactory == nullptr,
+            "createFactory is null in %s", libPath.c_str());
+
+    destroyFactory =
+        (C2ComponentFactory::DestroyCodec2FactoryFunc)dlsym(mLibHandle, "DestroyCodec2Factory");
+    LOG_ALWAYS_FATAL_IF(destroyFactory == nullptr,
+            "destroyFactory is null in %s", libPath.c_str());
+
+    mComponentFactory = createFactory();
+    if (mComponentFactory == nullptr) {
+        ALOGD("could not create factory in %s", libPath.c_str());
+        mInit = C2_NO_MEMORY;
+    } else {
+        mInit = C2_OK;
+    }
+
+    if (mInit != C2_OK) {
+        return mInit;
+    }
+
+    std::shared_ptr<C2ComponentInterface> intf;
+    c2_status_t res = createInterface(0, &intf);
+    if (res != C2_OK) {
+        ALOGD("failed to create interface: %d", res);
+        return mInit;
+    }
+
+    std::shared_ptr<C2Component::Traits> traits(new (std::nothrow) C2Component::Traits);
+    if (traits) {
+        traits->name = intf->getName();
+
+        C2ComponentKindSetting kind;
+        C2ComponentDomainSetting domain;
+        res = intf->query_vb({ &kind, &domain }, {}, C2_MAY_BLOCK, nullptr);
+        bool fixDomain = res != C2_OK;
+        if (res == C2_OK) {
+            traits->kind = kind.value;
+            traits->domain = domain.value;
+        } else {
+            // TODO: remove this fall-back
+            ALOGD("failed to query interface for kind and domain: %d", res);
+
+            traits->kind =
+                (traits->name.find("encoder") != std::string::npos) ? C2Component::KIND_ENCODER :
+                (traits->name.find("decoder") != std::string::npos) ? C2Component::KIND_DECODER :
+                C2Component::KIND_OTHER;
+        }
+
+        uint32_t mediaTypeIndex =
+                traits->kind == C2Component::KIND_ENCODER ? C2PortMediaTypeSetting::output::PARAM_TYPE
+                : C2PortMediaTypeSetting::input::PARAM_TYPE;
+        std::vector<std::unique_ptr<C2Param>> params;
+        res = intf->query_vb({}, { mediaTypeIndex }, C2_MAY_BLOCK, &params);
+        if (res != C2_OK) {
+            ALOGD("failed to query interface: %d", res);
+            return mInit;
+        }
+        if (params.size() != 1u) {
+            ALOGD("failed to query interface: unexpected vector size: %zu", params.size());
+            return mInit;
+        }
+        C2PortMediaTypeSetting *mediaTypeConfig = C2PortMediaTypeSetting::From(params[0].get());
+        if (mediaTypeConfig == nullptr) {
+            ALOGD("failed to query media type");
+            return mInit;
+        }
+        traits->mediaType =
+            std::string(mediaTypeConfig->m.value,
+                        strnlen(mediaTypeConfig->m.value, mediaTypeConfig->flexCount()));
+
+        if (fixDomain) {
+            if (strncmp(traits->mediaType.c_str(), "audio/", 6) == 0) {
+                traits->domain = C2Component::DOMAIN_AUDIO;
+            } else if (strncmp(traits->mediaType.c_str(), "video/", 6) == 0) {
+                traits->domain = C2Component::DOMAIN_VIDEO;
+            } else if (strncmp(traits->mediaType.c_str(), "image/", 6) == 0) {
+                traits->domain = C2Component::DOMAIN_IMAGE;
+            } else {
+                traits->domain = C2Component::DOMAIN_OTHER;
+            }
+        }
+
+        // TODO: get this properly from the store during emplace
+        switch (traits->domain) {
+        case C2Component::DOMAIN_AUDIO:
+            traits->rank = 8;
+            break;
+        default:
+            traits->rank = 512;
+        }
+
+        params.clear();
+        res = intf->query_vb({}, { C2ComponentAliasesSetting::PARAM_TYPE }, C2_MAY_BLOCK, &params);
+        if (res == C2_OK && params.size() == 1u) {
+            C2ComponentAliasesSetting *aliasesSetting =
+                C2ComponentAliasesSetting::From(params[0].get());
+            if (aliasesSetting) {
+                // Split aliases on ','
+                // This looks simpler in plain C and even std::string would still make a copy.
+                char *aliases = ::strndup(aliasesSetting->m.value, aliasesSetting->flexCount());
+                ALOGD("'%s' has aliases: '%s'", intf->getName().c_str(), aliases);
+
+                for (char *tok, *ptr, *str = aliases; (tok = ::strtok_r(str, ",", &ptr));
+                        str = nullptr) {
+                    traits->aliases.push_back(tok);
+                    ALOGD("adding alias: '%s'", tok);
+                }
+                free(aliases);
+            }
+        }
+    }
+    mTraits = traits;
+
+    return mInit;
+}
+
+C2PlatformComponentStore::ComponentModule::~ComponentModule() {
+    ALOGV("in %s", __func__);
+    if (destroyFactory && mComponentFactory) {
+        destroyFactory(mComponentFactory);
+    }
+    if (mLibHandle) {
+        ALOGV("unloading dll");
+        dlclose(mLibHandle);
+    }
+}
+
+c2_status_t C2PlatformComponentStore::ComponentModule::createInterface(
+        c2_node_id_t id, std::shared_ptr<C2ComponentInterface> *interface,
+        std::function<void(::C2ComponentInterface*)> deleter) {
+    interface->reset();
+    if (mInit != C2_OK) {
+        return mInit;
+    }
+    std::shared_ptr<ComponentModule> module = shared_from_this();
+    c2_status_t res = mComponentFactory->createInterface(
+            id, interface, [module, deleter](C2ComponentInterface *p) mutable {
+                // capture module so that we ensure we still have it while deleting interface
+                deleter(p); // delete interface first
+                module.reset(); // remove module ref (not technically needed)
+    });
+    return res;
+}
+
+c2_status_t C2PlatformComponentStore::ComponentModule::createComponent(
+        c2_node_id_t id, std::shared_ptr<C2Component> *component,
+        std::function<void(::C2Component*)> deleter) {
+    component->reset();
+    if (mInit != C2_OK) {
+        return mInit;
+    }
+    std::shared_ptr<ComponentModule> module = shared_from_this();
+    c2_status_t res = mComponentFactory->createComponent(
+            id, component, [module, deleter](C2Component *p) mutable {
+                // capture module so that we ensure we still have it while deleting component
+                deleter(p); // delete component first
+                module.reset(); // remove module ref (not technically needed)
+    });
+    return res;
+}
+
+std::shared_ptr<const C2Component::Traits> C2PlatformComponentStore::ComponentModule::getTraits() {
+    std::unique_lock<std::recursive_mutex> lock(mLock);
+    return mTraits;
+}
+
+C2PlatformComponentStore::C2PlatformComponentStore()
+    : mVisited(false),
+      mReflector(std::make_shared<C2ReflectorHelper>()),
+      mInterface(mReflector) {
+
+    auto emplace = [this](const char *libPath) {
+        mComponents.emplace(libPath, libPath);
+    };
+
+    // TODO: move this also into a .so so it can be updated
+    emplace("libcodec2_soft_aacdec.so");
+    emplace("libcodec2_soft_aacenc.so");
+    emplace("libcodec2_soft_amrnbdec.so");
+    emplace("libcodec2_soft_amrnbenc.so");
+    emplace("libcodec2_soft_amrwbdec.so");
+    emplace("libcodec2_soft_amrwbenc.so");
+    emplace("libcodec2_soft_av1dec.so");
+    emplace("libcodec2_soft_avcdec.so");
+    emplace("libcodec2_soft_avcenc.so");
+    emplace("libcodec2_soft_flacdec.so");
+    emplace("libcodec2_soft_flacenc.so");
+    emplace("libcodec2_soft_g711alawdec.so");
+    emplace("libcodec2_soft_g711mlawdec.so");
+    emplace("libcodec2_soft_gsmdec.so");
+    emplace("libcodec2_soft_h263dec.so");
+    emplace("libcodec2_soft_h263enc.so");
+    emplace("libcodec2_soft_hevcdec.so");
+    emplace("libcodec2_soft_hevcenc.so");
+    emplace("libcodec2_soft_mp3dec.so");
+    emplace("libcodec2_soft_mpeg2dec.so");
+    emplace("libcodec2_soft_mpeg4dec.so");
+    emplace("libcodec2_soft_mpeg4enc.so");
+    emplace("libcodec2_soft_opusdec.so");
+    emplace("libcodec2_soft_opusenc.so");
+    emplace("libcodec2_soft_rawdec.so");
+    emplace("libcodec2_soft_vorbisdec.so");
+    emplace("libcodec2_soft_vp8dec.so");
+    emplace("libcodec2_soft_vp8enc.so");
+    emplace("libcodec2_soft_vp9dec.so");
+    emplace("libcodec2_soft_vp9enc.so");
+}
+
+c2_status_t C2PlatformComponentStore::copyBuffer(
+        std::shared_ptr<C2GraphicBuffer> src, std::shared_ptr<C2GraphicBuffer> dst) {
+    (void)src;
+    (void)dst;
+    return C2_OMITTED;
+}
+
+c2_status_t C2PlatformComponentStore::query_sm(
+        const std::vector<C2Param*> &stackParams,
+        const std::vector<C2Param::Index> &heapParamIndices,
+        std::vector<std::unique_ptr<C2Param>> *const heapParams) const {
+    return mInterface.query(stackParams, heapParamIndices, C2_MAY_BLOCK, heapParams);
+}
+
+c2_status_t C2PlatformComponentStore::config_sm(
+        const std::vector<C2Param*> &params,
+        std::vector<std::unique_ptr<C2SettingResult>> *const failures) {
+    return mInterface.config(params, C2_MAY_BLOCK, failures);
+}
+
+void C2PlatformComponentStore::visitComponents() {
+    std::lock_guard<std::mutex> lock(mMutex);
+    if (mVisited) {
+        return;
+    }
+    for (auto &pathAndLoader : mComponents) {
+        const C2String &path = pathAndLoader.first;
+        ComponentLoader &loader = pathAndLoader.second;
+        std::shared_ptr<ComponentModule> module;
+        if (loader.fetchModule(&module) == C2_OK) {
+            std::shared_ptr<const C2Component::Traits> traits = module->getTraits();
+            if (traits) {
+                mComponentList.push_back(traits);
+                mComponentNameToPath.emplace(traits->name, path);
+                for (const C2String &alias : traits->aliases) {
+                    mComponentNameToPath.emplace(alias, path);
+                }
+            }
+        }
+    }
+    mVisited = true;
+}
+
+std::vector<std::shared_ptr<const C2Component::Traits>> C2PlatformComponentStore::listComponents() {
+    // This method SHALL return within 500ms.
+    visitComponents();
+    return mComponentList;
+}
+
+c2_status_t C2PlatformComponentStore::findComponent(
+        C2String name, std::shared_ptr<ComponentModule> *module) {
+    (*module).reset();
+    visitComponents();
+
+    auto pos = mComponentNameToPath.find(name);
+    if (pos != mComponentNameToPath.end()) {
+        return mComponents.at(pos->second).fetchModule(module);
+    }
+    return C2_NOT_FOUND;
+}
+
+c2_status_t C2PlatformComponentStore::createComponent(
+        C2String name, std::shared_ptr<C2Component> *const component) {
+    // This method SHALL return within 100ms.
+    component->reset();
+    std::shared_ptr<ComponentModule> module;
+    c2_status_t res = findComponent(name, &module);
+    if (res == C2_OK) {
+        // TODO: get a unique node ID
+        res = module->createComponent(0, component);
+    }
+    return res;
+}
+
+c2_status_t C2PlatformComponentStore::createInterface(
+        C2String name, std::shared_ptr<C2ComponentInterface> *const interface) {
+    // This method SHALL return within 100ms.
+    interface->reset();
+    std::shared_ptr<ComponentModule> module;
+    c2_status_t res = findComponent(name, &module);
+    if (res == C2_OK) {
+        // TODO: get a unique node ID
+        res = module->createInterface(0, interface);
+    }
+    return res;
+}
+
+c2_status_t C2PlatformComponentStore::querySupportedParams_nb(
+        std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const {
+    return mInterface.querySupportedParams(params);
+}
+
+c2_status_t C2PlatformComponentStore::querySupportedValues_sm(
+        std::vector<C2FieldSupportedValuesQuery> &fields) const {
+    return mInterface.querySupportedValues(fields, C2_MAY_BLOCK);
+}
+
+C2String C2PlatformComponentStore::getName() const {
+    return "android.componentStore.platform";
+}
+
+std::shared_ptr<C2ParamReflector> C2PlatformComponentStore::getParamReflector() const {
+    return mReflector;
+}
+
+std::shared_ptr<C2ComponentStore> GetCodec2PlatformComponentStore() {
+    static std::mutex mutex;
+    static std::weak_ptr<C2ComponentStore> platformStore;
+    std::lock_guard<std::mutex> lock(mutex);
+    std::shared_ptr<C2ComponentStore> store = platformStore.lock();
+    if (store == nullptr) {
+        store = std::make_shared<C2PlatformComponentStore>();
+        platformStore = store;
+    }
+    return store;
+}
+
+} // namespace android
diff --git a/media/codec2/vndk/include/C2AllocatorGralloc.h b/media/codec2/vndk/include/C2AllocatorGralloc.h
new file mode 100644
index 0000000..ee7524e
--- /dev/null
+++ b/media/codec2/vndk/include/C2AllocatorGralloc.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef STAGEFRIGHT_CODEC2_ALLOCATOR_GRALLOC_H_
+#define STAGEFRIGHT_CODEC2_ALLOCATOR_GRALLOC_H_
+
+#include <functional>
+
+#include <C2Buffer.h>
+
+namespace android {
+
+/**
+ * Unwrap the native handle from a Codec2 handle allocated by C2AllocatorGralloc.
+ *
+ * @param handle a handle allocated by C2AllocatorGralloc. This includes handles returned for a
+ * graphic block allocation handle returned.
+ *
+ * @return a new NON-OWNING native handle that must be deleted using native_handle_delete.
+ */
+native_handle_t *UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle);
+
+/**
+ * Wrap the gralloc handle and metadata into Codec2 handle recognized by
+ * C2AllocatorGralloc.
+ *
+ * @return a new NON-OWNING C2Handle that must be deleted using native_handle_delete.
+ */
+C2Handle *WrapNativeCodec2GrallocHandle(
+        const native_handle_t *const handle,
+        uint32_t width, uint32_t height, uint32_t format, uint64_t usage, uint32_t stride,
+        uint32_t generation = 0, uint64_t igbp_id = 0, uint32_t igbp_slot = 0);
+
+/**
+ * When the gralloc handle is migrated to another bufferqueue, update
+ * bufferqueue information.
+ *
+ * @return {@code true} when native_handle is a wrapped codec2 handle.
+ */
+bool MigrateNativeCodec2GrallocHandle(
+        native_handle_t *handle,
+        uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot);
+
+/**
+ * \todo Get this from the buffer
+ */
+void _UnwrapNativeCodec2GrallocMetadata(
+        const C2Handle *const handle,
+        uint32_t *width, uint32_t *height, uint32_t *format, uint64_t *usage, uint32_t *stride,
+        uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot);
+
+class C2AllocatorGralloc : public C2Allocator {
+public:
+    virtual id_t getId() const override;
+
+    virtual C2String getName() const override;
+
+    virtual std::shared_ptr<const Traits> getTraits() const override;
+
+    virtual c2_status_t newGraphicAllocation(
+            uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
+            std::shared_ptr<C2GraphicAllocation> *allocation) override;
+
+    virtual c2_status_t priorGraphicAllocation(
+            const C2Handle *handle,
+            std::shared_ptr<C2GraphicAllocation> *allocation) override;
+
+    C2AllocatorGralloc(id_t id, bool bufferQueue = false);
+
+    c2_status_t status() const;
+
+    virtual ~C2AllocatorGralloc() override;
+
+    static bool isValid(const C2Handle* const o);
+
+private:
+    class Impl;
+    Impl *mImpl;
+};
+
+} // namespace android
+
+#endif // STAGEFRIGHT_CODEC2_ALLOCATOR_GRALLOC_H_
diff --git a/media/codec2/vndk/include/C2AllocatorIon.h b/media/codec2/vndk/include/C2AllocatorIon.h
new file mode 100644
index 0000000..1b2051f
--- /dev/null
+++ b/media/codec2/vndk/include/C2AllocatorIon.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef STAGEFRIGHT_CODEC2_ALLOCATOR_ION_H_
+#define STAGEFRIGHT_CODEC2_ALLOCATOR_ION_H_
+
+#include <functional>
+#include <list>
+#include <mutex>
+#include <tuple>
+#include <unordered_map>
+
+#include <C2Buffer.h>
+
+namespace android {
+
+class C2AllocatorIon : public C2Allocator {
+public:
+    // Usage mapper function used by the allocator
+    //   (usage, capacity) => (align, heapMask, flags)
+    //
+    // capacity is aligned to the default block-size (defaults to page size) to reduce caching
+    // overhead
+    typedef std::function<c2_status_t(C2MemoryUsage, size_t,
+                      /* => */ size_t*, unsigned*, unsigned*)> UsageMapperFn;
+
+    virtual id_t getId() const override;
+
+    virtual C2String getName() const override;
+
+    virtual std::shared_ptr<const Traits> getTraits() const override;
+
+    virtual c2_status_t newLinearAllocation(
+            uint32_t capacity, C2MemoryUsage usage,
+            std::shared_ptr<C2LinearAllocation> *allocation) override;
+
+    virtual c2_status_t priorLinearAllocation(
+            const C2Handle *handle,
+            std::shared_ptr<C2LinearAllocation> *allocation) override;
+
+    C2AllocatorIon(id_t id);
+
+    virtual c2_status_t status() const { return mInit; }
+
+    virtual ~C2AllocatorIon() override;
+
+    static bool isValid(const C2Handle* const o);
+
+    /**
+     * Updates the usage mapper for subsequent new allocations, as well as the supported
+     * minimum and maximum usage masks and default block-size to use for the mapper.
+     *
+     * \param mapper this method is called to map Codec 2.0 buffer usage to ion flags
+     *        required by the ion device
+     * \param minUsage minimum buffer usage required for supported allocations (defaults to 0)
+     * \param maxUsage maximum buffer usage supported by the ion allocator (defaults to SW_READ
+     *        | SW_WRITE)
+     * \param blockSize alignment used prior to calling |mapper| for the buffer capacity.
+     *        This also helps reduce the size of cache required for caching mapper results.
+     *        (defaults to the page size)
+     */
+    void setUsageMapper(
+            const UsageMapperFn &mapper, uint64_t minUsage, uint64_t maxUsage, uint64_t blockSize);
+
+private:
+    c2_status_t mapUsage(C2MemoryUsage usage, size_t size,
+                     /* => */ size_t *align, unsigned *heapMask, unsigned *flags);
+
+    c2_status_t mInit;
+    int mIonFd;
+
+    // this locks mTraits, mBlockSize, mUsageMapper, mUsageMapperLru and mUsageMapperCache
+    mutable std::mutex mUsageMapperLock;
+    std::shared_ptr<const Traits> mTraits;
+    size_t mBlockSize;
+    UsageMapperFn mUsageMapper;
+    typedef std::pair<uint64_t, size_t> MapperKey;
+    struct MapperKeyHash {
+        std::size_t operator()(const MapperKey &) const;
+    };
+    typedef std::tuple<size_t, unsigned, unsigned, c2_status_t> MapperValue;
+    typedef std::pair<MapperKey, MapperValue> MapperKeyValue;
+    typedef std::list<MapperKeyValue>::iterator MapperKeyValuePointer;
+    std::list<MapperKeyValue> mUsageMapperLru;
+    std::unordered_map<MapperKey, MapperKeyValuePointer, MapperKeyHash> mUsageMapperCache;
+};
+
+} // namespace android
+
+#endif // STAGEFRIGHT_CODEC2_ALLOCATOR_ION_H_
diff --git a/media/codec2/vndk/include/C2BqBufferPriv.h b/media/codec2/vndk/include/C2BqBufferPriv.h
new file mode 100644
index 0000000..e1a8138
--- /dev/null
+++ b/media/codec2/vndk/include/C2BqBufferPriv.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef STAGEFRIGHT_CODEC2_BQ_BUFFER_PRIV_H_
+#define STAGEFRIGHT_CODEC2_BQ_BUFFER_PRIV_H_
+
+#include <android/hardware/graphics/bufferqueue/2.0/IGraphicBufferProducer.h>
+
+#include <C2Buffer.h>
+
+#include <functional>
+
+class C2BufferQueueBlockPool : public C2BlockPool {
+public:
+    C2BufferQueueBlockPool(const std::shared_ptr<C2Allocator> &allocator, const local_id_t localId);
+
+    virtual ~C2BufferQueueBlockPool() override;
+
+    virtual C2Allocator::id_t getAllocatorId() const override {
+        return mAllocator->getId();
+    };
+
+    virtual local_id_t getLocalId() const override {
+        return mLocalId;
+    };
+
+    virtual c2_status_t fetchGraphicBlock(
+            uint32_t width,
+            uint32_t height,
+            uint32_t format,
+            C2MemoryUsage usage,
+            std::shared_ptr<C2GraphicBlock> *block /* nonnull */) override;
+
+    typedef std::function<void(uint64_t producer, int32_t slot, int64_t nsecs)> OnRenderCallback;
+
+    /**
+     * Sets render callback.
+     *
+     * \param renderCallbak callback to call for all dequeue buffer.
+     */
+    virtual void setRenderCallback(const OnRenderCallback &renderCallback = OnRenderCallback());
+
+    typedef ::android::hardware::graphics::bufferqueue::V2_0::
+            IGraphicBufferProducer HGraphicBufferProducer;
+    /**
+     * Configures an IGBP in order to create blocks. A newly created block is
+     * dequeued from the configured IGBP. Unique Id of IGBP and the slot number of
+     * blocks are passed via native_handle. Managing IGBP is responsibility of caller.
+     * When IGBP is not configured, block will be created via allocator.
+     * Since zero is not used for Unique Id of IGBP, if IGBP is not configured or producer
+     * is configured as nullptr, unique id which is bundled in native_handle is zero.
+     *
+     * \param producer      the IGBP, which will be used to fetch blocks
+     */
+    virtual void configureProducer(const android::sp<HGraphicBufferProducer> &producer);
+
+private:
+    const std::shared_ptr<C2Allocator> mAllocator;
+    const local_id_t mLocalId;
+
+    class Impl;
+    std::shared_ptr<Impl> mImpl;
+
+    friend struct C2BufferQueueBlockPoolData;
+};
+
+#endif // STAGEFRIGHT_CODEC2_BUFFER_PRIV_H_
diff --git a/media/codec2/vndk/include/C2BufferPriv.h b/media/codec2/vndk/include/C2BufferPriv.h
new file mode 100644
index 0000000..be5f69c
--- /dev/null
+++ b/media/codec2/vndk/include/C2BufferPriv.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef STAGEFRIGHT_CODEC2_BUFFER_PRIV_H_
+#define STAGEFRIGHT_CODEC2_BUFFER_PRIV_H_
+
+#include <functional>
+
+#include <C2Buffer.h>
+#include <android/hardware/media/bufferpool/2.0/IAccessor.h>
+
+class C2BasicLinearBlockPool : public C2BlockPool {
+public:
+    explicit C2BasicLinearBlockPool(const std::shared_ptr<C2Allocator> &allocator);
+
+    virtual ~C2BasicLinearBlockPool() override = default;
+
+    virtual C2Allocator::id_t getAllocatorId() const override {
+        return mAllocator->getId();
+    }
+
+    virtual local_id_t getLocalId() const override {
+        return BASIC_LINEAR;
+    }
+
+    virtual c2_status_t fetchLinearBlock(
+            uint32_t capacity,
+            C2MemoryUsage usage,
+            std::shared_ptr<C2LinearBlock> *block /* nonnull */) override;
+
+    // TODO: fetchCircularBlock
+
+private:
+    const std::shared_ptr<C2Allocator> mAllocator;
+};
+
+class C2BasicGraphicBlockPool : public C2BlockPool {
+public:
+    explicit C2BasicGraphicBlockPool(const std::shared_ptr<C2Allocator> &allocator);
+
+    virtual ~C2BasicGraphicBlockPool() override = default;
+
+    virtual C2Allocator::id_t getAllocatorId() const override {
+        return mAllocator->getId();
+    }
+
+    virtual local_id_t getLocalId() const override {
+        return BASIC_GRAPHIC;
+    }
+
+    virtual c2_status_t fetchGraphicBlock(
+            uint32_t width,
+            uint32_t height,
+            uint32_t format,
+            C2MemoryUsage usage,
+            std::shared_ptr<C2GraphicBlock> *block /* nonnull */) override;
+
+private:
+    const std::shared_ptr<C2Allocator> mAllocator;
+};
+
+class C2PooledBlockPool : public C2BlockPool {
+public:
+    C2PooledBlockPool(const std::shared_ptr<C2Allocator> &allocator, const local_id_t localId);
+
+    virtual ~C2PooledBlockPool() override;
+
+    virtual C2Allocator::id_t getAllocatorId() const override {
+        return mAllocator->getId();
+    }
+
+    virtual local_id_t getLocalId() const override {
+        return mLocalId;
+    }
+
+    virtual c2_status_t fetchLinearBlock(
+            uint32_t capacity,
+            C2MemoryUsage usage,
+            std::shared_ptr<C2LinearBlock> *block /* nonnull */) override;
+
+    virtual c2_status_t fetchGraphicBlock(
+            uint32_t width,
+            uint32_t height,
+            uint32_t format,
+            C2MemoryUsage usage,
+            std::shared_ptr<C2GraphicBlock> *block) override;
+
+    /**
+     * Retrieves the connection Id for underlying bufferpool
+     */
+    int64_t getConnectionId();
+
+    /**
+     * Retrieves the accessor which is used by underlying bufferpool. (It can be
+     * passed to receiving process.)
+     *
+     * \param accessor          IAccessor will be written to this out parameter.
+     *
+     * \return true             IAcessor is writen successfully.
+     * \return false            IAccessor is not written.
+     */
+    bool getAccessor(android::sp<android::hardware::media::bufferpool::V2_0::IAccessor> *accessor);
+
+private:
+    const std::shared_ptr<C2Allocator> mAllocator;
+    const local_id_t mLocalId;
+
+    class Impl;
+    std::unique_ptr<Impl> mImpl;
+};
+
+#endif // STAGEFRIGHT_CODEC2_BUFFER_PRIV_H_
diff --git a/media/codec2/vndk/include/C2ComponentFactory.h b/media/codec2/vndk/include/C2ComponentFactory.h
new file mode 100644
index 0000000..f6d8b98
--- /dev/null
+++ b/media/codec2/vndk/include/C2ComponentFactory.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef STAGEFRIGHT_CODEC2_COMPONENT_FACTORY_H_
+#define STAGEFRIGHT_CODEC2_COMPONENT_FACTORY_H_
+
+#include <C2Component.h>
+
+#include <functional>
+#include <memory>
+
+/**
+ * Component factory object that enables to create a component and/or interface from a dynamically
+ * linked library. This is needed because the component/interfaces are managed objects, but we
+ * cannot safely create a managed object and pass it in C.
+ *
+ * Components/interfaces typically inherit from std::enable_shared_from_this, but C requires
+ * passing simple pointer, and shared_ptr constructor needs to know the class to be constructed
+ * derives from enable_shared_from_this.
+ *
+ */
+class C2ComponentFactory {
+public:
+    typedef std::function<void(::C2Component*)> ComponentDeleter;
+    typedef std::function<void(::C2ComponentInterface*)> InterfaceDeleter;
+
+    /**
+     * Creates a component.
+     *
+     * This method SHALL return within 100ms.
+     *
+     * \param id        component ID for the created component
+     * \param component shared pointer where the created component is stored. Cleared on
+     *                  failure and updated on success.
+     *
+     * \retval C2_OK        the component was created successfully
+     * \retval C2_TIMED_OUT could not create the component within the time limit (unexpected)
+     * \retval C2_CORRUPTED some unknown error prevented the creation of the component (unexpected)
+     *
+     * \retval C2_NO_MEMORY not enough memory to create the component
+     */
+    virtual c2_status_t createComponent(
+            c2_node_id_t id, std::shared_ptr<C2Component>* const component,
+            ComponentDeleter deleter = std::default_delete<C2Component>()) = 0;
+
+    /**
+     * Creates a component interface.
+     *
+     * This method SHALL return within 100ms.
+     *
+     * \param id        component interface ID for the created interface
+     * \param interface shared pointer where the created interface is stored. Cleared on
+     *                  failure and updated on success.
+     *
+     * \retval C2_OK        the component interface was created successfully
+     * \retval C2_TIMED_OUT could not create the component interface within the time limit
+     *                      (unexpected)
+     * \retval C2_CORRUPTED some unknown error prevented the creation of the component interface
+     *                      (unexpected)
+     *
+     * \retval C2_NO_MEMORY not enough memory to create the component interface
+     */
+    virtual c2_status_t createInterface(
+            c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
+            InterfaceDeleter deleter = std::default_delete<C2ComponentInterface>()) = 0;
+
+    virtual ~C2ComponentFactory() = default;
+
+    typedef ::C2ComponentFactory* (*CreateCodec2FactoryFunc)(void);
+    typedef void (*DestroyCodec2FactoryFunc)(::C2ComponentFactory*);
+};
+
+
+#endif // STAGEFRIGHT_CODEC2_COMPONENT_FACTORY_H_
diff --git a/media/codec2/vndk/include/C2Debug.h b/media/codec2/vndk/include/C2Debug.h
new file mode 100644
index 0000000..af1cdab
--- /dev/null
+++ b/media/codec2/vndk/include/C2Debug.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef C2UTILS_DEBUG_H_
+#define C2UTILS_DEBUG_H_
+
+#include <util/C2Debug-log.h>
+
+// To allow arbitrary ordering of C2Debug.h and API headers and to keep debug utilities separately
+// from the API definitions, we provide API header specific debug headers.
+#ifdef C2PARAM_H_
+#include <util/C2Debug-param.h>
+#endif
+
+#endif  // C2UTILS_DEBUG_H_
diff --git a/media/codec2/vndk/include/C2ErrnoUtils.h b/media/codec2/vndk/include/C2ErrnoUtils.h
new file mode 100644
index 0000000..5b995f6
--- /dev/null
+++ b/media/codec2/vndk/include/C2ErrnoUtils.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef STAGEFRIGHT_CODEC2_ERRNO_UTILS_H_
+#define STAGEFRIGHT_CODEC2_ERRNO_UTILS_H_
+
+#include <errno.h>
+#include <C2.h>
+
+// standard ERRNO mappings
+template<int N> constexpr c2_status_t _c2_errno2status_impl();
+template<> constexpr c2_status_t _c2_errno2status_impl<0>()       { return C2_OK; }
+template<> constexpr c2_status_t _c2_errno2status_impl<EINVAL>()  { return C2_BAD_VALUE; }
+template<> constexpr c2_status_t _c2_errno2status_impl<EACCES>()  { return C2_REFUSED; }
+template<> constexpr c2_status_t _c2_errno2status_impl<EPERM>()   { return C2_REFUSED; }
+template<> constexpr c2_status_t _c2_errno2status_impl<ENOMEM>()  { return C2_NO_MEMORY; }
+
+// map standard errno-s to the equivalent c2_status_t
+template<int... N> struct _c2_map_errno_impl;
+template<int E, int ... N> struct _c2_map_errno_impl<E, N...> {
+    static c2_status_t map(int result) {
+        if (result == E) {
+            return _c2_errno2status_impl <E>();
+        } else {
+            return _c2_map_errno_impl<N...>::map(result);
+        }
+    }
+};
+template<> struct _c2_map_errno_impl<> {
+    static c2_status_t map(int result) {
+        return result == 0 ? C2_OK : C2_CORRUPTED;
+    }
+};
+
+template<int... N>
+c2_status_t c2_map_errno(int result) {
+    return _c2_map_errno_impl<N...>::map(result);
+}
+
+#endif // STAGEFRIGHT_CODEC2_ERRNO_UTILS_H_
+
diff --git a/media/codec2/vndk/include/C2PlatformStorePluginLoader.h b/media/codec2/vndk/include/C2PlatformStorePluginLoader.h
new file mode 100644
index 0000000..4c10643
--- /dev/null
+++ b/media/codec2/vndk/include/C2PlatformStorePluginLoader.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef STAGEFRIGHT_C2_PLATFORM_STORE_PLUGIN_LOADER_H_
+
+#define STAGEFRIGHT_C2_PLATFORM_STORE_PLUGIN_LOADER_H_
+
+#include <memory>
+
+#include <utils/Mutex.h>
+
+#include <C2.h>
+#include <C2Buffer.h>
+
+/**
+ * Extern C interface for creating block pool from platform store extension.
+ *
+ * \param alloctorId  the ID of the backing allocator type.
+ * \parem blockPoolId the ID of created block pool.
+ *
+ * \return pointer of created C2BlockPool, nullptr on error.
+ */
+typedef ::C2BlockPool* (*CreateBlockPoolFunc)(::C2Allocator::id_t, ::C2BlockPool::local_id_t);
+
+/**
+ * Extern C interface for creating allocator from platform store extension.
+ *
+ * \param alloctorId  the ID of the allocator to create.
+ * \param status      the returned status from creating allocator.
+ *
+ * \return pointer of created C2Allocator, nullptr on error.
+ */
+typedef ::C2Allocator* (*CreateAllocatorFunc)(::C2Allocator::id_t, ::c2_status_t*);
+
+class C2PlatformStorePluginLoader {
+public:
+    static const std::unique_ptr<C2PlatformStorePluginLoader>& GetInstance();
+    ~C2PlatformStorePluginLoader();
+
+    /**
+     * Creates block pool from platform store extension.
+     *
+     * \param alloctorId  the ID of the backing allocator type.
+     * \param blockPoolId the ID of created block pool.
+     * \param pool        shared pointer where the created block pool is stored.
+     *
+     * \retval C2_OK        the block pool was created successfully.
+     * \retval C2_NOT_FOUND the extension symbol was not found.
+     * \retval C2_BAD_INDEX the input allocatorId is not defined in platform store extension.
+     */
+    c2_status_t createBlockPool(::C2Allocator::id_t allocatorId,
+                                ::C2BlockPool::local_id_t blockPoolId,
+                                std::shared_ptr<C2BlockPool>* pool);
+
+    /**
+     * Creates allocator from platform store extension.
+     *
+     * Note that this allocator is not created as shared singleton as C2AllocatorStore does, because
+     * C interface only allows raw pointer transmission for extension.
+     *
+     * \param alloctorId  the ID of the allocator to create.
+     * \param allocator   shared pointer where the created allocator is stored.
+     *
+     * \retval C2_OK        the allocator was created successfully.
+     * \retval C2_TIMED_OUT could not create the allocator within the time limit (unexpected)
+     * \retval C2_CORRUPTED some unknown error prevented the creation of the allocator (unexpected)
+     * \retval C2_NOT_FOUND the extension symbol was not found.
+     * \retval C2_BAD_INDEX the input allocatorId is not defined in platform store extension.
+     * \retval C2_NO_MEMORY not enough memory to create the allocator
+     */
+    c2_status_t createAllocator(::C2Allocator::id_t allocatorId,
+                                std::shared_ptr<C2Allocator>* const allocator);
+
+private:
+    explicit C2PlatformStorePluginLoader(const char *libPath);
+
+    static android::Mutex sMutex;
+    static std::unique_ptr<C2PlatformStorePluginLoader> sInstance;
+
+    void *mLibHandle;
+    CreateBlockPoolFunc mCreateBlockPool;
+    CreateAllocatorFunc mCreateAllocator;
+};
+
+#endif  // STAGEFRIGHT_C2_PLATFORM_STORE_PLUGIN_LOADER_H_
diff --git a/media/codec2/vndk/include/C2PlatformSupport.h b/media/codec2/vndk/include/C2PlatformSupport.h
new file mode 100644
index 0000000..f31282c
--- /dev/null
+++ b/media/codec2/vndk/include/C2PlatformSupport.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef STAGEFRIGHT_CODEC2_PLATFORM_SUPPORT_H_
+#define STAGEFRIGHT_CODEC2_PLATFORM_SUPPORT_H_
+
+#include <C2Component.h>
+#include <C2ComponentFactory.h>
+
+#include <memory>
+
+namespace android {
+
+/**
+ * Returns the platform allocator store.
+ * \retval nullptr if the platform allocator store could not be obtained
+ */
+std::shared_ptr<C2AllocatorStore> GetCodec2PlatformAllocatorStore();
+
+/**
+ * Platform allocator store IDs
+ */
+class C2PlatformAllocatorStore : public C2AllocatorStore {
+public:
+    enum : id_t {
+        /**
+         * ID of the ion backed platform allocator.
+         *
+         * C2Handle consists of:
+         *   fd  shared ion buffer handle
+         *   int size (lo 32 bits)
+         *   int size (hi 32 bits)
+         *   int magic '\xc2io\x00'
+         */
+        ION = PLATFORM_START,
+
+        /**
+         * ID of the gralloc backed platform allocator.
+         *
+         * C2Handle layout is not public. Use C2AllocatorGralloc::UnwrapNativeCodec2GrallocHandle
+         * to get the underlying gralloc handle from a C2Handle, and WrapNativeCodec2GrallocHandle
+         * to create a C2Handle from a gralloc handle - for C2Allocator::priorAllocation.
+         */
+        GRALLOC,
+
+        /**
+         * ID of the bufferqueue backed platform allocator.
+         *
+         * C2Handle layout is not public. Use C2AllocatorGralloc::UnwrapNativeCodec2GrallocHandle
+         * to get the underlying handle from a C2Handle, and WrapNativeCodec2GrallocHandle
+         * to create a C2Handle from a handle - for C2Allocator::priorAllocation.
+         */
+        BUFFERQUEUE,
+
+        /**
+         * ID of indicating the end of platform allocator definition.
+         *
+         * \note always put this macro in the last place.
+         *
+         * Extended platform store plugin should use this macro as the start ID of its own allocator
+         * types.
+         */
+        PLATFORM_END,
+    };
+};
+
+/**
+ * Retrieves a block pool for a component.
+ *
+ * \param id        the local ID of the block pool
+ * \param component the component using the block pool (must be non-null)
+ * \param pool      pointer to where the obtained block pool shall be stored on success. nullptr
+ *                  will be stored here on failure
+ *
+ * \retval C2_OK        the operation was successful
+ * \retval C2_BAD_VALUE the component is null
+ * \retval C2_NOT_FOUND if the block pool does not exist
+ * \retval C2_NO_MEMORY not enough memory to fetch the block pool (this return value is only
+ *                      possible for basic pools)
+ * \retval C2_TIMED_OUT the operation timed out (this return value is only possible for basic pools)
+ * \retval C2_REFUSED   no permission to complete any required allocation (this return value is only
+ *                      possible for basic pools)
+ * \retval C2_CORRUPTED some unknown, unrecoverable error occured during operation (unexpected,
+ *                      this return value is only possible for basic pools)
+ */
+c2_status_t GetCodec2BlockPool(
+        C2BlockPool::local_id_t id, std::shared_ptr<const C2Component> component,
+        std::shared_ptr<C2BlockPool> *pool);
+
+/**
+ * Creates a block pool.
+ * \param allocatorId  the allocator ID which is used to allocate blocks
+ * \param component     the component using the block pool (must be non-null)
+ * \param pool          pointer to where the created block pool shall be store on success.
+ *                      nullptr will be stored here on failure
+ *
+ * \retval C2_OK        the operation was successful
+ * \retval C2_BAD_VALUE the component is null
+ * \retval C2_NOT_FOUND if the allocator does not exist
+ * \retval C2_NO_MEMORY not enough memory to create a block pool
+ */
+c2_status_t CreateCodec2BlockPool(
+        C2PlatformAllocatorStore::id_t allocatorId,
+        std::shared_ptr<const C2Component> component,
+        std::shared_ptr<C2BlockPool> *pool);
+
+/**
+ * Returns the platform component store.
+ * \retval nullptr if the platform component store could not be obtained
+ */
+std::shared_ptr<C2ComponentStore> GetCodec2PlatformComponentStore();
+
+/**
+ * Sets the preferred component store in this process for the sole purpose of accessing its
+ * interface. If this is not called, the default IComponentStore HAL (if exists) is the preferred
+ * store for this purpose. If the default IComponentStore HAL is not present, the platform
+ * component store is used.
+ */
+void SetPreferredCodec2ComponentStore(std::shared_ptr<C2ComponentStore> store);
+
+} // namespace android
+
+#endif // STAGEFRIGHT_CODEC2_PLATFORM_SUPPORT_H_
diff --git a/media/codec2/vndk/include/android-C2Debug-log.h b/media/codec2/vndk/include/android-C2Debug-log.h
new file mode 100644
index 0000000..5910228
--- /dev/null
+++ b/media/codec2/vndk/include/android-C2Debug-log.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef C2UTILS_ANDROID_DEBUG_LOG_H_
+#define C2UTILS_ANDROID_DEBUG_LOG_H_
+
+/*
+ * Android provides logging and debug macros. Redefine them with C2 prefix and add support for
+ * opting out of verbose logs.
+ */
+
+#ifdef C2_LOG_TAG
+#define LOG_TAG C2_LOG_TAG
+#endif
+
+#include <android-base/logging.h>
+
+#ifdef C2_LOG_VERBOSE
+#define C2_LOG(LEVEL) LOG(::android::base::LEVEL)
+#else
+/**
+ * Use as follows:
+ *
+ * #define C2_LOG_TAG "tag"
+ * //#define C2_LOG_VERBOSE  // enable verbose logs in this file
+ * #include <C2Debug.h>
+ *
+ * C2_LOG(DEBUG) << expr ...;
+ *
+ * Log levels are: VERBOSE, DEBUG, INFO, WARNING, ERROR, FATAL (aborts).
+ *
+ * No endl is required.
+ */
+#define C2_LOG(LEVEL) \
+        (::android::base::LEVEL != ::android::base::VERBOSE) && LOG(::android::base::LEVEL)
+#endif
+
+#define C2_CHECK    CHECK
+#define C2_CHECK_LT CHECK_LT
+#define C2_CHECK_LE CHECK_LE
+#define C2_CHECK_EQ CHECK_EQ
+#define C2_CHECK_GE CHECK_GE
+#define C2_CHECK_GT CHECK_GT
+#define C2_CHECK_NE CHECK_NE
+
+#define C2_DCHECK    DCHECK
+#define C2_DCHECK_LT DCHECK_LT
+#define C2_DCHECK_LE DCHECK_LE
+#define C2_DCHECK_EQ DCHECK_EQ
+#define C2_DCHECK_GE DCHECK_GE
+#define C2_DCHECK_GT DCHECK_GT
+#define C2_DCHECK_NE DCHECK_NE
+
+#endif  // C2UTILS_ANDROID_DEBUG_LOG_H_
diff --git a/media/codec2/vndk/include/types.h b/media/codec2/vndk/include/types.h
new file mode 100644
index 0000000..b41d3f8
--- /dev/null
+++ b/media/codec2/vndk/include/types.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_VNDK_TYPES_H
+#define CODEC2_VNDK_TYPES_H
+
+#include <android/hardware/graphics/bufferqueue/2.0/types.h>
+#include <android/hardware/graphics/common/1.2/types.h>
+#include <hidl/HidlSupport.h>
+#include <ui/Fence.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/Region.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace bufferqueue {
+namespace V2_0 {
+namespace utils {
+
+// Status
+// ======
+
+using HStatus = ::android::hardware::graphics::bufferqueue::V2_0::
+        Status;
+
+// A status_t value may have flags encoded. These flags are decoded into boolean
+// values if their corresponding output pointers are not null.
+bool b2h(status_t from, HStatus* to,
+         bool* bufferNeedsReallocation = nullptr,
+         bool* releaseAllBuffers = nullptr);
+// Simple 1-to-1 mapping. If BUFFER_NEEDS_REALLOCATION or RELEASE_ALL_BUFFERS
+// needs to be added, it must be done manually afterwards.
+bool h2b(HStatus from, status_t* to);
+
+// Fence
+// =====
+
+using BFence = ::android::Fence;
+// This class manages the lifetime of a copied handle. Its destructor calls
+// native_handle_delete() but not native_handle_close().
+struct HFenceWrapper {
+    HFenceWrapper() = default;
+    // Sets mHandle to a new value.
+    HFenceWrapper(native_handle_t* h);
+    // Deletes mHandle without closing.
+    ~HFenceWrapper();
+    // Deletes mHandle without closing, then sets mHandle to a new value.
+    HFenceWrapper& set(native_handle_t* h);
+    HFenceWrapper& operator=(native_handle_t* h);
+    // Returns a non-owning hidl_handle pointing to mHandle.
+    hidl_handle getHandle() const;
+    operator hidl_handle() const;
+protected:
+    native_handle_t* mHandle{nullptr};
+};
+
+// Does not clone the fd---only copy the fd. The returned HFenceWrapper should
+// not outlive the input Fence object.
+bool b2h(sp<BFence> const& from, HFenceWrapper* to);
+// Clones the fd and puts it in a new Fence object.
+bool h2b(native_handle_t const* from, sp<BFence>* to);
+
+// ConnectionType
+// ==============
+
+using HConnectionType = ::android::hardware::graphics::bufferqueue::V2_0::
+        ConnectionType;
+
+bool b2h(int from, HConnectionType* to);
+bool h2b(HConnectionType from, int* to);
+
+// Rect
+// ====
+
+using BRect = ::android::Rect;
+using HRect = ::android::hardware::graphics::common::V1_2::Rect;
+
+bool b2h(BRect const& from, HRect* to);
+bool h2b(HRect const& from, BRect* to);
+
+// Region
+// ======
+
+using BRegion = ::android::Region;
+using HRegion = ::android::hardware::hidl_vec<HRect>;
+
+bool b2h(BRegion const& from, HRegion* to);
+bool h2b(HRegion const& from, BRegion* to);
+
+// GraphicBuffer
+// =============
+
+using HardwareBuffer = ::android::hardware::graphics::common::V1_2::
+        HardwareBuffer;
+using HardwareBufferDescription = ::android::hardware::graphics::common::V1_2::
+        HardwareBufferDescription;
+
+// Does not clone the handle. The returned HardwareBuffer should not outlive the
+// input GraphicBuffer. Note that HardwareBuffer does not carry the generation
+// number, so this function needs another output argument.
+bool b2h(sp<GraphicBuffer> const& from, HardwareBuffer* to,
+         uint32_t* toGenerationNumber = nullptr);
+// Clones the handle and creates a new GraphicBuffer from the cloned handle.
+// Note that the generation number of the GraphicBuffer has to be set manually
+// afterwards because HardwareBuffer does not have such information.
+bool h2b(HardwareBuffer const& from, sp<GraphicBuffer>* to);
+
+}  // namespace utils
+}  // namespace V2_0
+}  // namespace bufferqueue
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
+
+#endif  // CODEC2_VNDK_TYPES_H
+
diff --git a/media/codec2/vndk/include/util/C2Debug-base.h b/media/codec2/vndk/include/util/C2Debug-base.h
new file mode 100644
index 0000000..a040e42
--- /dev/null
+++ b/media/codec2/vndk/include/util/C2Debug-base.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef C2UTILS_DEBUG_BASE_H_
+#define C2UTILS_DEBUG_BASE_H_
+
+#include <iostream>
+
+/**
+ * Debug print utilities for Codec 2.0 base objects.
+ */
+
+#define C2_DECLARE_AS_STRING_AND_DEFINE_STREAM_OUT(type) \
+const char *asString(type i, const char *def = "??"); \
+inline std::ostream& operator<<(std::ostream& os, const type &i) { \
+    return os << asString(i); \
+}
+
+C2_DECLARE_AS_STRING_AND_DEFINE_STREAM_OUT(c2_status_t)
+
+
+#endif  // C2UTILS_DEBUG_BASE_H_
+
diff --git a/media/codec2/vndk/include/util/C2Debug-interface.h b/media/codec2/vndk/include/util/C2Debug-interface.h
new file mode 100644
index 0000000..3f31875
--- /dev/null
+++ b/media/codec2/vndk/include/util/C2Debug-interface.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef C2UTILS_DEBUG_INTERFACE_H_
+#define C2UTILS_DEBUG_INTERFACE_H_
+
+#include <util/C2Debug-base.h>
+#include <util/C2InterfaceUtils.h>
+
+#include <iostream>
+
+template<typename T>
+std::ostream& operator<<(std::ostream& os, const C2SupportedRange<T> &i);
+
+template<typename T>
+std::ostream& operator<<(std::ostream& os, const C2SupportedValueSet<T> &i);
+
+template<typename T>
+std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<T> &i);
+
+#endif  // C2UTILS_DEBUG_INTERFACE_H_
diff --git a/media/codec2/vndk/include/util/C2Debug-log.h b/media/codec2/vndk/include/util/C2Debug-log.h
new file mode 100644
index 0000000..195c4c1
--- /dev/null
+++ b/media/codec2/vndk/include/util/C2Debug-log.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef C2UTILS_DEBUG_LOG_H_
+#define C2UTILS_DEBUG_LOG_H_
+
+// Platform specific debug utilities
+#ifdef __ANDROID__
+#include <android-C2Debug-log.h>
+#else
+// TODO: implement base debug utils
+#endif
+
+#endif  // C2UTILS_DEBUG_LOG_H_
diff --git a/media/codec2/vndk/include/util/C2Debug-param.h b/media/codec2/vndk/include/util/C2Debug-param.h
new file mode 100644
index 0000000..e1c1de0
--- /dev/null
+++ b/media/codec2/vndk/include/util/C2Debug-param.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef C2UTILS_DEBUG_PARAM_H_
+#define C2UTILS_DEBUG_PARAM_H_
+
+#include <C2Param.h>
+#include <util/C2Debug-base.h>
+
+#include <iostream>
+
+/**
+ * Debug/print declarations for objects defined in C2Param.h
+ */
+C2_DECLARE_AS_STRING_AND_DEFINE_STREAM_OUT(C2FieldDescriptor::type_t)
+
+std::ostream& operator<<(std::ostream& os, const C2Param::CoreIndex &i);
+std::ostream& operator<<(std::ostream& os, const C2Param::Type &i);
+std::ostream& operator<<(std::ostream& os, const C2Param::Index &i);
+std::ostream& operator<<(std::ostream& os, const _C2FieldId &i);
+std::ostream& operator<<(std::ostream& os, const C2FieldDescriptor &i);
+std::ostream& operator<<(std::ostream& os, const C2ParamField &i);
+
+#endif  // C2UTILS_DEBUG_PARAM_H_
diff --git a/media/codec2/vndk/include/util/C2InterfaceHelper.h b/media/codec2/vndk/include/util/C2InterfaceHelper.h
new file mode 100644
index 0000000..bfb43af
--- /dev/null
+++ b/media/codec2/vndk/include/util/C2InterfaceHelper.h
@@ -0,0 +1,752 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef C2UTILS_INTERFACE_HELPER_H_
+#define C2UTILS_INTERFACE_HELPER_H_
+
+#include <C2Component.h>
+#include <util/C2InterfaceUtils.h>
+
+#include <map>
+#include <mutex>
+#include <vector>
+
+#include <stddef.h>
+
+/**
+ * Interface Helper
+ */
+using C2R = C2SettingResultsBuilder;
+
+template<typename T, bool E=std::is_enum<T>::value>
+struct _c2_reduce_enum_to_underlying_type {
+    typedef T type;
+};
+
+template<typename T>
+struct _c2_reduce_enum_to_underlying_type<T, true> {
+    typedef typename std::underlying_type<T>::type type;
+};
+
+/**
+ * Helper class to implement parameter reflectors. This class is dynamic and is designed to be
+ * shared by multiple interfaces. This allows interfaces to add structure descriptors as needed.
+ */
+class C2ReflectorHelper : public C2ParamReflector {
+public:
+    C2ReflectorHelper() = default;
+    virtual ~C2ReflectorHelper() = default;
+    virtual std::unique_ptr<C2StructDescriptor> describe(
+            C2Param::CoreIndex paramIndex) const override;
+
+    /**
+     * Adds support for describing the given parameters.
+     *
+     * \param Params types of codec 2.0 structs (or parameters) to describe
+     */
+    template<typename... Params>
+    C2_INLINE void addStructDescriptors() {
+        std::vector<C2StructDescriptor> structs;
+        addStructDescriptors(structs, (_Tuple<Params...> *)nullptr);
+    }
+
+    /**
+     * Adds support for describing a specific struct.
+     *
+     * \param strukt descriptor for the struct that will be moved out.
+     */
+    void addStructDescriptor(C2StructDescriptor &&strukt);
+
+private:
+    template<typename... Params>
+    class C2_HIDE _Tuple { };
+
+    /**
+     * Adds support for describing the given descriptors.
+     *
+     * \param structs List of structure descriptors to add support for
+     */
+    void addStructDescriptors(
+            std::vector<C2StructDescriptor> &structs, _Tuple<> *);
+
+    /**
+     * Utility method that adds support for describing the given descriptors in a recursive manner
+     * one structure at a time using a list of structure descriptors temporary.
+     *
+     * \param T the type of codec 2.0 struct to describe
+     * \param Params rest of the structs
+     * \param structs Temporary list of structure descriptors used to optimize the operation.
+     */
+    template<typename T, typename... Params>
+    C2_INLINE void addStructDescriptors(
+            std::vector<C2StructDescriptor> &structs, _Tuple<T, Params...> *) {
+        structs.emplace_back((T*)nullptr);
+        addStructDescriptors(structs, (_Tuple<Params...> *)nullptr);
+    }
+
+    mutable std::mutex _mMutex;
+    std::map<C2Param::CoreIndex, const C2StructDescriptor> _mStructs; ///< descriptors
+};
+
+/**
+ * Utility class that implements the codec 2.0 interface API-s for some parameters.
+ *
+ * This class must be subclassed.
+ */
+class C2InterfaceHelper {
+public:
+    /**
+     * Returns the base offset of a field at |offset| that could be part of an array or part of a
+     * sub-structure.
+     *
+     * This method does not do field size verification, e.g. if offset if obtained from a structure,
+     * it will not stop at the structure boundary - this is okay, as we just want the base offset
+     * here, which is the same.
+     */
+    static
+    size_t GetBaseOffset(const std::shared_ptr<C2ParamReflector> &reflector,
+                                C2Param::CoreIndex index, size_t offset);
+
+    /**
+     * The interface helper class uses references to std::shared_ptr<T> config parameters.
+     * Internally, these need to be generalized to std::shared_ptr<C2Param> refs, but the cast is
+     * not allowed (as these are references). As such, this class never returns pointer to the
+     * shared_ptrs.
+     */
+    struct ParamRef {
+        template<typename T, typename enable=
+                typename std::enable_if<std::is_convertible<T, C2Param>::value>::type>
+        inline C2_HIDE ParamRef(std::shared_ptr<T> &param)
+            : _mRef(reinterpret_cast<std::shared_ptr<C2Param>*>(&param)) { }
+
+        // used by comparison operator for containers
+        operator std::shared_ptr<C2Param> *() const { return _mRef; }
+
+        /**
+         * Returns a shared pointer to the parameter.
+         */
+        std::shared_ptr<C2Param> get() const { return *_mRef; }
+
+    private:
+        std::shared_ptr<C2Param> *_mRef;
+    };
+
+    /**
+     * Field helper.
+     *
+     * Contains additional information for the field: possible values, and currently supported
+     * values.
+     */
+    class FieldHelper {
+    public:
+        /**
+         * Creates helper for a field with given possible values.
+         *
+         * \param param parameter reference. The parameter does not have to be initialized at this
+         *        point.
+         * \param field field identifier
+         * \param values possible values for the field
+         */
+        FieldHelper(const ParamRef &param, const _C2FieldId &field,
+                    std::unique_ptr<C2FieldSupportedValues> &&values);
+
+        /**
+         * Creates a param-field identifier for this field. This method is called after the
+         * underlying parameter has been initialized.
+         *
+         * \aram index
+         *
+         * @return C2ParamField
+         */
+        C2ParamField makeParamField(C2Param::Index index) const;
+
+        /**
+         * Sets the currently supported values for this field.
+         *
+         * \param values currently supported values that will be moved out
+         */
+        void setSupportedValues(std::unique_ptr<C2FieldSupportedValues> &&values);
+
+        /**
+         * Gets the currently supported values for this field. This defaults to the possible values
+         * if currently supported values were never set.
+         */
+        const C2FieldSupportedValues *getSupportedValues() const;
+
+        /**
+         * Gets the possible values for this field.
+         */
+        const C2FieldSupportedValues *getPossibleValues() const;
+
+    protected:
+        // TODO: move to impl for safety
+        ParamRef mParam;
+        _C2FieldId mFieldId;
+        std::unique_ptr<C2FieldSupportedValues> mPossible;
+        std::unique_ptr<C2FieldSupportedValues> mSupported; ///< if different from possible
+    };
+
+    template<typename T>
+    struct C2_HIDE Param;
+    class ParamHelper;
+
+    /**
+     * Factory is an interface to get the parameter helpers from a std::shared_ptr<T> &.
+     */
+    class Factory {
+        // \todo this may be already in ParamHelper
+        virtual std::shared_ptr<C2ParamReflector> getReflector() const = 0;
+
+        virtual std::shared_ptr<ParamHelper> getParamHelper(const ParamRef &param) const = 0;
+
+    public:
+        virtual ~Factory() = default;
+
+        template<typename T>
+        Param<T> get(std::shared_ptr<T> &param, std::shared_ptr<T> altValue = nullptr) const {
+            return Param<T>(getParamHelper(ParamRef(param)),
+                            altValue == nullptr ? param : altValue,
+                            getReflector());
+        }
+    };
+
+    /**
+     * Typed field helper.
+     */
+    template<typename T>
+    struct Field {
+        /**
+         * Constructor.
+         *
+         * \param helper helper for this field
+         * \param index  parameter index (this is needed as it is not available during parameter
+         *        construction) \todo remove
+         */
+        Field(std::shared_ptr<FieldHelper> helper, C2Param::Index index);
+
+        bool supportsAtAll(T value) const {
+            return C2FieldSupportedValuesHelper<T>(*_mHelper->getPossibleValues()).supports(value);
+        }
+
+        bool supportsNow(T value) const {
+            return C2FieldSupportedValuesHelper<T>(*_mHelper->getSupportedValues()).supports(value);
+        }
+
+        /**
+         * Creates a conflict resolution suggestion builder for this field.
+         */
+        C2ParamFieldValuesBuilder<T> shouldBe() const;
+
+        /**
+         * Creates a currently supported values builder for this field. This is only supported
+         * for non-const fields to disallow setting supported values for dependencies.
+         */
+        C2ParamFieldValuesBuilder<T> mustBe();
+
+        operator C2ParamField() const {
+            return _mField;
+        }
+
+        // TODO
+        C2R validatePossible(const T &value __unused) const {
+            /// TODO
+            return C2R::Ok();
+        }
+
+    private:
+        std::shared_ptr<FieldHelper> _mHelper;
+        C2ParamField _mField;
+    };
+
+    class ParamHelper {
+    public:
+        ParamHelper(ParamRef param, C2StringLiteral name, C2StructDescriptor &&);
+        ParamHelper(ParamHelper &&);
+        ~ParamHelper();
+
+        /**
+         * Finds a field descriptor.
+         */
+        std::shared_ptr<FieldHelper> findField(size_t baseOffs, size_t baseSize) const;
+
+        /// returns the parameter ref for this parameter
+        const ParamRef ref() const;
+
+        /// returns the current value of this parameter as modifiable. The constness of this
+        /// object determines the constness of the returned value.
+        std::shared_ptr<C2Param> value();
+
+        /// returns the current value of this parameter as const
+        std::shared_ptr<const C2Param> value() const;
+
+        /**
+         * Performs a configuration change request for this parameter.
+         *
+         * \param value    the value that is being assigned to this parameter.
+         *                 This could be pointing to the current value of the
+         *                 parameter. This must not change.
+         * \param mayBlock whether blocking is allowed
+         * \param endValue the resulting value
+         * \param factory  parameter factory (to access dependencies)
+         * \param failures vector of failures to append any failures from this
+         *                 operation
+         *
+         * \retval C2_OK        configuration was successful
+         * \retval C2_BAD_VALUE value is incorrect (TBD)
+         * \retval C2_NO_MEMORY not enough memory to perform the assignment
+         * \retval C2_TIMED_OUT configuration timed out
+         * \retval C2_BLOCKING  configuration requires blocking to be allowed
+         * \retval C2_CORRUPTED interface is corrupted
+         */
+        c2_status_t trySet(
+                const C2Param *value, bool mayBlock,
+                bool *changed,
+                Factory &factory,
+                std::vector<std::unique_ptr<C2SettingResult>>* const failures);
+
+        /// returns parameter indices that depend on this parameter
+        const std::vector<C2Param::Index> getDownDependencies() const;
+
+        /// adds a dependent parameter
+        void addDownDependency(C2Param::Index index);
+
+        /// returns that parameter refs for parameters that depend on this
+        const std::vector<ParamRef> getDependenciesAsRefs() const;
+
+        /// returns and moves out stored struct descriptor
+        C2StructDescriptor retrieveStructDescriptor();
+
+        /// returns the name of this parameter
+        C2String name() const;
+
+        /// returns the index of this parameter
+        C2Param::Index index() const;
+
+        /// returns the parameter descriptor
+        std::shared_ptr<const C2ParamDescriptor> getDescriptor() const;
+
+        /**
+         * Validates param helper.
+         *
+         * For now, this fills field info for const params.
+         *
+         * \retval C2_CORRUPTED the parameter cannot be added as such
+         */
+        c2_status_t validate(const std::shared_ptr<C2ParamReflector> &reflector);
+
+    protected:
+        typedef C2ParamDescriptor::attrib_t attrib_t;
+        attrib_t& attrib();
+
+        /// sets the default value of this parameter
+        void setDefaultValue(std::shared_ptr<C2Param> default_);
+
+        /// sets the setter method
+        void setSetter(std::function<C2R(const C2Param *, bool, bool *, Factory &)> setter);
+
+        /// sets the getter method
+        void setGetter(std::function<std::shared_ptr<C2Param>(bool)> getter);
+
+        /// sets the dependencies
+        void setDependencies(std::vector<C2Param::Index> indices, std::vector<ParamRef> refs);
+
+        /// sets the fields and their supported values
+        void setFields(std::vector<C2ParamFieldValues> &&fields);
+
+        /// build this into a final ParamHelper object
+        std::shared_ptr<ParamHelper> build();
+
+        class Impl;
+        std::unique_ptr<Impl> mImpl;
+    };
+
+    /**
+     * Typed parameter helper. This provides access to members as well as field helpers.
+     */
+    template<typename T>
+    struct C2_HIDE Param {
+        Param(
+                std::shared_ptr<ParamHelper> helper, std::shared_ptr<T> &param,
+                std::shared_ptr<C2ParamReflector> reflector)
+            : v(*param.get()),
+              _mTypedParam(param),
+              _mHelper(helper),
+              _mReflector(reflector) { }
+
+        template<typename S>
+        using FieldType = Field<
+                typename _c2_reduce_enum_to_underlying_type<
+                        typename std::remove_const<
+                                typename std::remove_extent<S>::type>::type>::type>;
+
+        template<typename S>
+        FieldType<S> F(S &field) {
+            size_t offs = (uintptr_t)&field - (uintptr_t)&get();
+            // this must fall either within sizeof(T) + FLEX_SIZE or param->size()
+            // size_t size = sizeof(field);
+            // mParam may be null
+            size_t baseSize = sizeof(typename std::remove_extent<S>::type);
+            size_t baseOffs = GetBaseOffset(
+                    _mReflector, T::CORE_INDEX, offs - sizeof(C2Param));
+            if (~baseOffs == 0) {
+                // C2_LOG(FATAL) << "unknown field at offset " << offs << " size " << sizeof(S)
+                //       << " base-size " << baseSize;
+                // __builtin_trap();
+            } else {
+                baseOffs += sizeof(C2Param);
+            }
+
+            std::shared_ptr<FieldHelper> helper = _mHelper->findField(baseOffs, baseSize);
+            return FieldType<S>(helper, _mTypedParam->index());
+        }
+
+        // const Param have const Fields; however, remove const from S
+        template<typename S>
+        const FieldType<S> F(S &field) const {
+            return const_cast<const FieldType<S>>(const_cast<Param *>(this)->F(field));
+        }
+
+        /// Returns a const ref value of this const param.
+        const T &get() const {
+            return *_mTypedParam.get();
+        }
+
+        /// Returns a modifiable ref value of this non-const param.
+        T &set() {
+            return *_mTypedParam.get();
+        }
+
+        /// Const-reference to the value.s
+        T const &v;
+
+    private:
+        std::shared_ptr<T> _mTypedParam;
+        std::shared_ptr<ParamHelper> _mHelper;
+        std::shared_ptr<C2ParamReflector> _mReflector;
+    };
+
+    template<typename T>
+    using C2P = Param<T>;
+
+    /**
+     * Templated move builder class for a parameter helper.
+     */
+    template<typename T>
+    class C2_HIDE ParamBuilder : private ParamHelper {
+    public:
+        /** Construct the parameter builder from minimal info required. */
+        ParamBuilder(std::shared_ptr<T> &param, C2StringLiteral name)
+            : ParamHelper(param, name, C2StructDescriptor((T*)nullptr)),
+              mTypedParam(&param) {
+            attrib() = attrib_t::IS_PERSISTENT;
+        }
+
+        /** Makes this parameter required. */
+        inline ParamBuilder &required() {
+            attrib() |= attrib_t::IS_REQUIRED;
+            return *this;
+        }
+
+        /** Makes this parameter transient (not persistent). */
+        inline ParamBuilder &transient() {
+            attrib() &= ~attrib_t::IS_PERSISTENT;
+            return *this;
+        }
+
+        /** Makes this parameter hidden (not exposed in JAVA API). */
+        inline ParamBuilder &hidden() {
+            attrib() |= attrib_t::IS_HIDDEN;
+            return *this;
+        }
+
+        /** Makes this parameter internal (not exposed to query/settings). */
+        inline ParamBuilder &internal() {
+            attrib() |= attrib_t::IS_INTERNAL;
+            return *this;
+        }
+
+        /** Adds default value. Must be added exactly once. */
+        inline ParamBuilder &withDefault(std::shared_ptr<T> default_) {
+            // CHECK(!mDefaultValue);
+            // WARN_IF(!default_); // could be nullptr if OOM
+            // technically, this could be in the parent
+            *mTypedParam = std::shared_ptr<T>(T::From(C2Param::Copy(*default_).release()));
+            setDefaultValue(default_);
+            std::shared_ptr<T> *typedParam = mTypedParam;
+            setGetter([typedParam](bool) -> std::shared_ptr<C2Param> {
+                return std::static_pointer_cast<C2Param>(*typedParam);
+            });
+            return *this;
+        }
+
+        /** Adds default value. Must be added exactly once. */
+        inline ParamBuilder &withDefault(T *default_) {
+            return withDefault(std::shared_ptr<T>(default_));
+        }
+
+        /** Adds all fields to this parameter with their possible values. */
+        inline ParamBuilder &withFields(std::vector<C2ParamFieldValues> &&fields_) {
+            setFields(std::move(fields_));
+            return *this;
+        }
+
+        /**
+         * Adds a constant value (also as default). Must be added exactly once.
+         *
+         * Const parameters by definition have no dependencies.
+         */
+        inline ParamBuilder &withConstValue(std::shared_ptr<T> default_) {
+            attrib() |= attrib_t::IS_CONST;
+            setSetter([default_](
+                    const C2Param *value, bool mayBlock __unused, bool *changed, Factory &) -> C2R {
+                *changed = false;
+                const T *typedValue = T::From(value);
+                if (typedValue == nullptr) {
+                    return C2R::Corrupted(); // TODO BadValue/Invalid. This should not happen here.
+                }
+                if (*typedValue != *default_) {
+                    return C2R::Corrupted(); // TODO ReadOnly(*default_);
+                }
+                *changed = false;
+                return C2R::Ok();
+            });
+            return withDefault(default_);
+        }
+
+        /** Adds constant value (also as default). Must be added exactly once. */
+        inline ParamBuilder &withConstValue(T *default_) {
+            return withConstValue(std::shared_ptr<T>(default_));
+        }
+
+        /**
+         * Use a strict setter.
+         *
+         * \param fn   strict setter
+         * \param deps dependencies (references)
+         */
+        template<typename ... Deps>
+        inline ParamBuilder &withSetter(
+                C2R (*fn)(bool, const C2P<T> &, C2P<T> &, const C2P<Deps> &...),
+                std::shared_ptr<Deps>& ... deps) {
+            attrib() |= attrib_t::IS_STRICT;
+            std::shared_ptr<T> *typedParam = mTypedParam;
+            setSetter([typedParam, fn, &deps...](
+                    const C2Param *value, bool mayBlock, bool *changed, Factory &factory) -> C2R {
+                *changed = false;
+                const T *typedValue = T::From(value);
+                if (typedValue == nullptr) {
+                    return C2R::Corrupted(); // TODO BadValue/Invalid. This should not happen here.
+                }
+                // Do copy-on-change for parameters in this helper so change can be detected by
+                // a change of the pointer. Do this by working on a proposed value.
+                std::shared_ptr<T> proposedValue =
+                    std::shared_ptr<T>(T::From(C2Param::Copy(*value).release()));
+                if (proposedValue == nullptr) {
+                    return C2R::NoMemory(value->index());
+                }
+                C2P<T> oldValue = factory.get(*typedParam);
+                // Get a parameter helper with value pointing to proposedValue
+                C2P<T> helper = factory.get(*typedParam, proposedValue);
+                C2R result = fn(mayBlock, oldValue, helper, factory.get(deps)...);
+
+                // If value changed, copy result to current value
+                if (helper.get() != *typedParam->get()) {
+                    *typedParam = proposedValue;
+                    *changed = true;
+                }
+                return result;
+            });
+            setDependencies(std::vector<C2Param::Index>{ deps->index()... },
+                            std::vector<ParamRef>{ ParamRef(deps)... });
+            return *this;
+        }
+
+        /**
+         * Use a non-strict setter.
+         *
+         * \param fn   non-strict setter
+         * \param deps dependencies (references)
+         */
+        template<typename ... Deps>
+        inline ParamBuilder &withSetter(
+                C2R (*fn)(bool, C2P<T> &, const C2P<Deps> &...), std::shared_ptr<Deps>& ... deps) {
+            std::shared_ptr<T> *typedParam = mTypedParam;
+            setSetter([typedParam, fn, &deps...](
+                    const C2Param *value, bool mayBlock, bool *changed, Factory &factory) -> C2R {
+                *changed = false;
+                const T *typedValue = T::From(value);
+                if (typedValue == nullptr) {
+                    return C2R::Corrupted(); // TODO BadValue/Invalid. This should not happen here.
+                }
+                // Do copy-on-change for parameters in this helper so change can be detected by
+                // a change of the pointer. Do this by working on a proposed value.
+                std::shared_ptr<T> proposedValue =
+                    std::shared_ptr<T>(T::From(C2Param::Copy(*value).release()));
+                if (proposedValue == nullptr) {
+                    return C2R::NoMemory(value->index());
+                }
+                // Get a parameter helper with value pointing to proposedValue
+                C2P<T> helper = factory.get(*typedParam, proposedValue);
+                C2R result = fn(mayBlock, helper, factory.get(deps)...);
+
+                // If value changed, copy result to current value
+                if (helper.get() != *typedParam->get()) {
+                    *typedParam = proposedValue;
+                    *changed = true;
+                }
+                return result;
+            });
+            setDependencies(std::vector<C2Param::Index>{ deps->index()... },
+                            std::vector<ParamRef>{ ParamRef(deps)... });
+            return *this;
+        }
+
+        /**
+         * Marks this a calculated (read-only) field.
+         *
+         * \param fn   non-strict setter (calculator)
+         * \param deps dependencies (references)
+         */
+        template<typename ... Deps>
+        inline ParamBuilder &calculatedAs(
+                C2R (*fn)(bool, C2P<T> &, const C2P<Deps> &...), std::shared_ptr<Deps>& ... deps) {
+            attrib() |= attrib_t::IS_READ_ONLY;
+            return withSetter(fn, std::forward<decltype(deps)>(deps)...);
+        }
+
+        inline std::shared_ptr<ParamHelper> build() {
+            return ParamHelper::build();
+        }
+
+    protected:
+        std::shared_ptr<T> *mTypedParam;
+    };
+
+    template<typename T>
+    static ParamBuilder<T> DefineParam(std::shared_ptr<T> &param, C2StringLiteral name) {
+        return ParamBuilder<T>(param, name);
+    }
+
+public:
+    c2_status_t query(
+            const std::vector<C2Param*> &stackParams,
+            const std::vector<C2Param::Index> &heapParamIndices,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2Param>>* const heapParams) const;
+
+    /**
+     * Helper implementing config calls as well as other configuration updates.
+     *
+     * This method is virtual, so implementations may provide wrappers around it (and perform
+     * actions just before and after a configuration).
+     *
+     * \param params
+     * \param mayBlock
+     * \param failures
+     * \param updateParams if true, the updated parameter values are copied back into the arguments
+     *                     passed in |params|
+     * \param changes      pointed to a vector to receive settings with their values changed. If not
+     *                     null, settings with their values changed are added to this.
+     * \return result from config
+     */
+    virtual c2_status_t config(
+            const std::vector<C2Param*> &params, c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2SettingResult>>* const failures,
+            bool updateParams = true,
+            std::vector<std::shared_ptr<C2Param>> *changes = nullptr);
+
+    c2_status_t querySupportedParams(
+            std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const;
+
+    c2_status_t querySupportedValues(
+            std::vector<C2FieldSupportedValuesQuery> &fields, c2_blocking_t mayBlock) const;
+
+    std::shared_ptr<C2ReflectorHelper> getReflector() {
+        return mReflector;
+    }
+
+    typedef std::unique_lock<std::mutex> Lock;
+
+    /**
+     * Locks the interface and returns a lock. This lock must be unlocked or released without
+     * calling any other blocking call.
+     */
+    Lock lock() const;
+
+private:
+    void setInterfaceAddressBounds(uintptr_t start, uintptr_t end) {
+        // TODO: exclude this helper
+        (void)start;
+        (void)end;
+    }
+
+protected:
+    mutable std::mutex mMutex;
+    std::shared_ptr<C2ReflectorHelper> mReflector;
+    struct FactoryImpl;
+    std::shared_ptr<FactoryImpl> _mFactory;
+
+    C2InterfaceHelper(std::shared_ptr<C2ReflectorHelper> reflector);
+
+    /**
+     * Adds a parameter to this interface.
+     * \note This method CHECKs.
+     *
+     * \param param parameter to add.
+     */
+    void addParameter(std::shared_ptr<ParamHelper> param);
+
+    /**
+     * Returns the dependency index for a parameter.
+     *
+     * \param ix the index of the parameter
+     */
+    size_t getDependencyIndex_l(C2Param::Index ix) const;
+
+    virtual ~C2InterfaceHelper() = default;
+
+    /**
+     * Sets subclass instance's address and size.
+     *
+     * \todo allow subclass to specify parameter address range directly (e.g. do not assume that
+     *       they are local to the subclass instance)
+     *
+     * \param T type of the derived instance
+     * \param instance pointer to the derived instance
+     */
+    template<typename T>
+    inline C2_HIDE void setDerivedInstance(T *instance) {
+        setInterfaceAddressBounds((uintptr_t)instance, (uintptr_t)(instance + 1));
+    }
+
+    C2_DO_NOT_COPY(C2InterfaceHelper);
+};
+
+/**
+ * Creates a C2ParamFieldValuesBuilder class for a field of a parameter
+ *
+ * \param spParam a configuration parameter in an interface class subclassed from C2InterfaceHelper.
+ * \param field   a field of such parameter
+ */
+#define C2F(spParam, field) \
+    C2ParamFieldValuesBuilder< \
+            typename _c2_reduce_enum_to_underlying_type< \
+                    typename std::remove_reference< \
+                            typename std::remove_extent< \
+                                    decltype(spParam->field)>::type>::type>::type>( \
+                                            C2ParamField(spParam.get(), &spParam->field))
+
+#endif  // C2UTILS_INTERFACE_HELPER_H_
diff --git a/media/codec2/vndk/include/util/C2InterfaceUtils.h b/media/codec2/vndk/include/util/C2InterfaceUtils.h
new file mode 100644
index 0000000..e9037e5
--- /dev/null
+++ b/media/codec2/vndk/include/util/C2InterfaceUtils.h
@@ -0,0 +1,1135 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef C2UTILS_INTERFACE_UTILS_H_
+#define C2UTILS_INTERFACE_UTILS_H_
+
+#include <C2Param.h>
+#include <C2Work.h>
+
+#include <cmath>
+#include <iterator>
+#include <limits>
+#include <type_traits>
+
+/**
+ * Helper class to map underlying types to C2Value types as well as to print field values. This is
+ * generally the same as simply the underlying type except for characters (STRING) and bytes (BLOB).
+ */
+template<typename T>
+struct C2_HIDE _C2FieldValueHelper {
+    typedef T ValueType;
+    inline static std::ostream& put(std::ostream &os, const C2Value::Primitive &p) {
+        return os << p.ref<T>();
+    }
+};
+
+template<>
+struct C2_HIDE _C2FieldValueHelper<uint8_t> {
+    typedef uint32_t ValueType;
+    static std::ostream& put(std::ostream &os, const C2Value::Primitive &p);
+};
+
+template<>
+struct C2_HIDE _C2FieldValueHelper<char> {
+    typedef int32_t ValueType;
+    static std::ostream& put(std::ostream &os, const C2Value::Primitive &p);
+};
+
+/**
+ * Supported value range utility for a field of a given type.
+ *
+ * This mimics C2FieldSupportedValue for RANGE type.
+ */
+template<typename T>
+class C2SupportedRange {
+    typedef typename _C2FieldValueHelper<T>::ValueType ValueType;
+
+//private:
+    constexpr static T MIN_VALUE = std::numeric_limits<T>::min();
+    constexpr static T MAX_VALUE = std::numeric_limits<T>::max();
+    constexpr static T MIN_STEP = std::is_floating_point<T>::value ? 0 : 1;
+
+public:
+    /**
+     * Constructs an empty range with no supported values.
+     *
+     * \note This is a specializated supported range representation that is only used for
+     * this object - it is equivalent to the EMPTY type in C2FieldSupportedValues.
+     */
+    inline static constexpr C2SupportedRange<T> None() {
+        return C2SupportedRange(MAX_VALUE, MIN_VALUE);
+    }
+
+    /**
+     * Constructs a range with all values supported.
+     */
+    inline static constexpr C2SupportedRange<T> Any() {
+        return C2SupportedRange(MIN_VALUE, MAX_VALUE);
+    }
+
+    /**
+     * Constructs a range with a single supported value.
+     *
+     * \param value the sole supported value
+     */
+    inline static constexpr C2SupportedRange<T> EqualTo(T value) {
+        return C2SupportedRange(value, value);
+    }
+
+    /**
+     * Constructs a range with supported values greater than a given value.
+     *
+     * \param value the given value
+     */
+    inline static C2SupportedRange<T> GreaterThan(T value) {
+        return (value == MAX_VALUE ? None() :
+                std::is_floating_point<T>::value ?
+                        C2SupportedRange(std::nextafter(value, MAX_VALUE), MAX_VALUE) :
+                        C2SupportedRange(value + MIN_STEP, MAX_VALUE));
+    }
+
+    /**
+     * Constructs a range with supported values greater than or equal to a given value.
+     *
+     * \param value the given value
+     */
+    inline static constexpr C2SupportedRange<T> GreaterThanOrEqualTo(T value) {
+        return C2SupportedRange(value, MAX_VALUE);
+    }
+
+    /**
+     * Constructs a range with supported values greater than or equal to (aka not less than) a given
+     * value.
+     *
+     * \param value the given value
+     */
+    inline static constexpr C2SupportedRange<T> NotLessThan(T value) {
+        return GreaterThanOrEqualTo(value);
+    }
+
+    /**
+     * Constructs a range with supported values less than or equal to a given value.
+     *
+     * \param value the given value
+     */
+    inline static constexpr C2SupportedRange<T> LessThanOrEqualTo(T value) {
+        return C2SupportedRange(MIN_VALUE, value);
+    }
+
+    /**
+     * Constructs a range with supported values less than or equal to (aka not greater than) a given
+     * value.
+     *
+     * \param value the given value
+     */
+    inline static constexpr C2SupportedRange<T> NotGreaterThan(T value) {
+        return LessThanOrEqualTo(value);
+    }
+
+    /**
+     * Constructs a range with supported values less than a given value.
+     *
+     * \param value the given value
+     */
+    inline static C2SupportedRange<T> LessThan(T value) {
+        return (value == MIN_VALUE ? None() :
+                std::is_floating_point<T>::value ?
+                        C2SupportedRange(MIN_VALUE, std::nextafter(value, MIN_VALUE)) :
+                        C2SupportedRange(MIN_VALUE, value - MIN_STEP));
+    }
+
+    /**
+     * Constructs a continuous or arithmetic range between two values.
+     *
+     * \param min the lower value
+     * \param max the higher value (if this is lower than |min| the range will be empty)
+     * \param step the step of the arithmetic range. (If this is 0 for floating point types or 1 for
+     *        integer types, the constructed range is continuous)
+     */
+    inline static constexpr
+    C2SupportedRange<T> InRange(T min, T max, T step = MIN_STEP) {
+        return C2SupportedRange(min, max, step);
+    }
+
+    /**
+     * Constructs a range over a geometric series between two values.
+     *
+     * \param min the lower bound of the range. This value is always part of the constructed range
+     *        as long as it is not greater than |max|.
+     * \param max the upper bound of the range. This value is only part of the constructed
+     *        range if it is part of the geometric series.
+     * \param num the numerator of the geometric series.
+     * \param denom the denominator of the geometric series.
+     */
+    inline static constexpr
+    C2SupportedRange<T> InSeries(T min, T max, T num, T denom) {
+        return C2SupportedRange(min, max, 0, num, denom);
+    }
+
+    /**
+     * Constructs a range over a multiply-accumulate series between two values.
+     *
+     * \param min the lower bound of the range. This value is always part of the constructed range
+     *        as long as it is not greater than |max|.
+     * \param max the upper bound of the range. This value is only part of the constructed
+     *        range if it is part of the series.
+     * \param step the accumulator of the multiply-accumulate series
+     * \param num the numerator of the multiply-accumulate series.
+     * \param denom the denominator of the multiply-accumulate series.
+     */
+    inline static constexpr
+    C2SupportedRange<T> InMacSeries(T min, T max, T step, T num, T denom) {
+        return C2SupportedRange(min, max, step, num, denom);
+    }
+
+    /**
+     * Constructs a range from a generic C2FieldSupportedValues object. This will be an empty
+     * range if the supported values are not of RANGE type.
+     *
+     * \param values the supported values object
+     */
+    C2SupportedRange(const C2FieldSupportedValues &values);
+
+    /**
+     * Returns whether this range is empty.
+     */
+    inline constexpr bool isEmpty() const {
+        return _mMin > _mMax;
+    }
+
+    /**
+     * Returns whether this range is valid.
+     *
+     * Ranges are valid if they are continuous or monotonic.
+     */
+    inline constexpr bool isValid() const {
+        // TODO: handle overflow or negative series
+        return _mDenom > 0 && _mNum >= _mDenom && _mMin * (_mDenom - _mNum) < _mStep * _mDenom;
+    }
+
+    /**
+     * Returns whether a value is part of this range.
+     *
+     * \param value the value to check.
+     */
+    bool contains(T value) const;
+
+    /**
+     * Returns a new range that is the intersection of this range and another, if it is
+     * representable as a range object.
+     *
+     * \param limit the other range
+     */
+    C2SupportedRange<T> limitedTo(const C2SupportedRange<T> &limit) const;
+
+    /**
+     * Converts this object to a C2FieldSupportedValues object.
+     */
+    inline operator C2FieldSupportedValues() const {
+        return C2FieldSupportedValues(_mMin, _mMax, _mStep, _mNum, _mDenom);
+    }
+
+    /**
+     * Returns the lower bound and starting point of this range.
+     */
+    inline C2_HIDE constexpr T min() const   { return _mMin;   }
+
+    /**
+     * Returns the upper bound of this range.
+     */
+    inline C2_HIDE constexpr T max() const   { return _mMax;   }
+
+    /**
+     * Returns the step of this range.
+     */
+    inline C2_HIDE constexpr T step() const  { return _mStep;  }
+
+    /**
+     * Returns the numerator of this range.
+     */
+    inline C2_HIDE constexpr T num() const   { return _mNum;   }
+
+    /**
+     * Returns the denominator of this range.
+     */
+    inline C2_HIDE constexpr T denom() const { return _mDenom; }
+
+private:
+    /**
+     * Returns whether x[i...] is all values between _mMin and _mMax.
+     */
+    inline C2_HIDE constexpr bool isSimpleRange() const {
+        return _mStep == MIN_STEP && _mNum == 1 && _mDenom == 1;
+    }
+
+    /**
+     * Returns whether x[i...] is defined as such:
+     * x[i + 1] = x[i] + _mStep, where _mStep > 0 and _mMin <= x[i] <= _mMax
+     */
+    inline C2_HIDE constexpr bool isArithmeticSeries() const {
+        return _mStep > MIN_STEP && _mNum == 1 && _mDenom == 1;
+    }
+
+    /**
+     * Returns whether x[i...] is defined as such:
+     * x[i] = x[0] * (_mNum / _mDenom) ^ i (with rounding), where _mNum > _mDenom > 0 and x[0] > 0
+     */
+    inline C2_HIDE constexpr bool isGeometricSeries() const {
+        return _mMin > 0 && _mStep == 0 && _mNum > _mDenom && _mDenom > 0;
+    }
+
+    /**
+     * Returns whether x[i...] is defined as such:
+     * x[i + 1] = x[i] * _mNum / _mDenom + _mStep (with rounding), while x[i + 1] > x[i], where
+     * _mStep != 0, _mDenom > 0 and _mNum > 0
+     */
+    inline C2_HIDE constexpr bool isMacSeries() const {
+        return _mStep != 0 && _mNum > 0 && _mDenom > 0;
+    }
+
+    /**
+     * Constructs an arithmetic or continuous range.
+     *
+     * \param min the lower value
+     * \param max the higher value (if this is lower than |min| the range will be empty)
+     * \param step the step of the arithmetic range. (If this is 0 for floating point types or 1 for
+     *        integer types, the constructed range is continuous)
+     */
+    constexpr C2_HIDE C2SupportedRange(T min, T max, T step = T(std::is_floating_point<T>::value ? 0 : 1))
+        : _mMin(min), _mMax(max), _mStep(step), _mNum(1), _mDenom(1) { }
+
+    /**
+     * Constructs a range over a geomertic sor multiply-accumulate series.
+     *
+     * \param min the lower bound of the range. This value is always part of the constructed range
+     *        as long as it is not greater than |max|.
+     * \param max the upper bound of the range. This value is only part of the constructed
+     *        range if it is part of the geometric series.
+     * \param step the accumulator of the multiply-accumulate series. This is 0 for a pure geometric
+     *        series
+     * \param num the numerator of the geometric series.
+     * \param denom the denominator of the geometric series.
+     */
+    constexpr C2_HIDE C2SupportedRange(T min, T max, T step, T num, T den)
+        : _mMin(min), _mMax(max), _mStep(step), _mNum(num), _mDenom(den) { }
+
+    T _mMin; ///< lower bound and starting point
+    T _mMax; ///< upper bound
+    T _mStep; ///< step of an arithmetic series (0 if continuous floating point range)
+    T _mNum; ///< numerator of a geometric series
+    T _mDenom; ///< denominator of a geometric series
+};
+
+/**
+ * Ordered supported flag set for a field of a given type.
+ */
+template<typename T>
+class C2SupportedFlags {
+    typedef typename _C2FieldValueHelper<T>::ValueType ValueType;
+
+public:
+    /**
+     * Constructs an empty flag set.
+     *
+     * \note This is a specializated supported flags representation that is only used for
+     * this object - it is equivalent to the EMPTY type in C2FieldSupportedValues.
+     */
+    static inline C2SupportedFlags<T> None() {
+        return C2SupportedFlags(std::initializer_list<C2Value::Primitive>());
+    }
+
+    /**
+     * Constructs a flags set of given flags.
+     *
+     * \param flags the ordered set of flags as an initializer list.
+     * \param min minimum set of flags to be set.
+     */
+    static inline C2SupportedFlags<T> Flags(const std::initializer_list<T> flags, T min = T(0)) {
+        return C2SupportedFlags(min, flags);
+    }
+
+    /**
+     * Constructs a flags set of given flags.
+     *
+     * \param flags the ordered set of flags.
+     * \param min minimum set of flags to be set.
+     */
+    static inline C2SupportedFlags<T> Flags(const std::vector<T> &flags, T min = T(0)) {
+        return C2SupportedFlags(min, flags);
+    }
+
+    /**
+     * Constructs a flag set from a generic C2FieldSupportedValues object. This will be an empty
+     * set if the supported values are not of FLAGS type.
+     *
+     * \param values the supported values object
+     */
+    C2SupportedFlags<T>(const C2FieldSupportedValues &values) {
+        if (values.type == C2FieldSupportedValues::FLAGS) {
+            _mValues.insert(_mValues.end(), values.values.begin(), values.values.end());
+        }
+    }
+
+    /**
+     * Returns whether this set is empty.
+     */
+    constexpr bool isEmpty() const {
+        return _mValues.empty();
+    }
+
+    /**
+     * Returns whether a value is part of this set.
+     *
+     * \param value the value to check.
+     */
+    bool contains(T value) const;
+
+    /**
+     * Returns a new flag set that is the intersection of this set and another.
+     *
+     * \param limit the other value set
+     */
+    C2SupportedFlags<T> limitedTo(const C2SupportedFlags<T> &limit) const;
+
+    /**
+     * Converts this object to a C2FieldSupportedValues object.
+     */
+    operator C2FieldSupportedValues() const {
+        return C2FieldSupportedValues(!isEmpty() /* flags */, _mValues);
+    }
+
+    /**
+     * Returns the ordered set of flags of this object.
+     */
+    const std::vector<T> flags() const;
+
+    /**
+     * Returns the minimum set of flags for this object.
+     */
+    T min() const;
+
+    /**
+     * Clears this supported value set.
+     */
+    inline void clear() {
+        _mValues.clear();
+    }
+
+private:
+    /**
+     * Constructs a flag set directly from an internal representation.
+     *
+     * \param values a vector containing the minimum flag set followed by the set of flags
+     */
+    C2SupportedFlags(std::vector<C2Value::Primitive> &&values)
+        : _mValues(values) {
+    }
+
+    /**
+     * Constructs a flag set from a set of flags and a minimum flag set.
+     *
+     * \param flags the set
+     */
+    C2SupportedFlags(T min, const std::vector<T> &flags) {
+        _mValues.emplace_back(min);
+        for (T elem : flags) {
+            _mValues.emplace_back(elem);
+        }
+    }
+
+    /**
+     * Constructs a flag set from a set of initializer list values and a minimum flag set
+     *
+     * \param flags the set
+     */
+    C2SupportedFlags(T min, const std::initializer_list<T> flags) {
+        _mValues.emplace_back(min);
+        for (T elem : flags) {
+            _mValues.emplace_back(elem);
+        }
+    }
+
+    std::vector<C2Value::Primitive> _mValues; ///< the minimum flag set followed by the set of flags
+};
+
+/**
+ * Ordered supported value set for a field of a given type.
+ */
+template<typename T>
+class C2SupportedValueSet {
+    typedef typename _C2FieldValueHelper<T>::ValueType ValueType;
+
+public:
+    /**
+     * Constructs an empty value set.
+     *
+     * \note This is a specializated supported range representation that is only used for
+     * this object - it is equivalent to the EMPTY type in C2FieldSupportedValues.
+     */
+    static inline C2SupportedValueSet<T> None() {
+        return C2SupportedValueSet({ });
+    }
+
+    /**
+     * Constructs a value set of given values.
+     *
+     * \param values the ordered set of values as an initializer list.
+     */
+    static inline C2SupportedValueSet<T> OneOf(const std::initializer_list<T> values) {
+        return C2SupportedValueSet(values);
+    }
+
+    /**
+     * Constructs a value set of given values.
+     *
+     * \param values the ordered set of values.
+     */
+    static inline C2SupportedValueSet<T> OneOf(const std::vector<T> &values) {
+        return C2SupportedValueSet(values);
+    }
+
+    /**
+     * Constructs a value set from a generic C2FieldSupportedValues object. This will be an empty
+     * set if the supported values are not of VALUES type.
+     *
+     * \param values the supported values object
+     */
+    C2SupportedValueSet<T>(const C2FieldSupportedValues &values) {
+        if (values.type == C2FieldSupportedValues::VALUES) {
+            _mValues.insert(_mValues.end(), values.values.begin(), values.values.end());
+        }
+    }
+
+    /**
+     * Returns whether this range is empty.
+     */
+    constexpr bool isEmpty() const {
+        return _mValues.empty();
+    }
+
+    /**
+     * Returns whether a value is part of this set.
+     *
+     * \param value the value to check.
+     */
+    bool contains(T value) const;
+
+    /**
+     * Returns a new value set that is the intersection of this set and another.
+     *
+     * \param limit the other value set
+     */
+    C2SupportedValueSet<T> limitedTo(const C2SupportedValueSet<T> &limit) const;
+
+    /**
+     * Returns a new value set that is the intersection of this set and a value range.
+     *
+     * \param limit the other range
+     */
+    C2SupportedValueSet<T> limitedTo(const C2SupportedRange<T> &limit) const;
+
+    /**
+     * Returns a new value set that is the intersection of this set and a flag set.
+     *
+     * \param limit the other flag set
+     */
+    C2SupportedValueSet<T> limitedTo(const C2SupportedFlags<T> &limit) const;
+
+    /**
+     * Converts this object to a C2FieldSupportedValues object.
+     */
+    operator C2FieldSupportedValues() const {
+        return C2FieldSupportedValues(false /* flags */, _mValues);
+    }
+
+    /**
+     * Returns the ordered set of values of this object.
+     */
+    const std::vector<T> values() const;
+
+    /**
+     * Clears this supported value set.
+     */
+    inline void clear() {
+        _mValues.clear();
+    }
+
+private:
+    /**
+     * Constructs a value set from a set of C2Value::Primitive values.
+     *
+     * \param values the set
+     */
+    C2SupportedValueSet(std::vector<C2Value::Primitive> &&values)
+        : _mValues(values) {
+    }
+
+    /**
+     * Constructs a value set from a set of values.
+     *
+     * \param values the set
+     */
+    C2SupportedValueSet(const std::vector<T> &values) {
+        for (T elem : values) {
+            _mValues.emplace_back(elem);
+        }
+    }
+
+    /**
+     * Constructs a value set from a set of initializer list values
+     *
+     * \param values the set
+     */
+    C2SupportedValueSet(const std::initializer_list<T> values) {
+        for (T elem : values) {
+            _mValues.emplace_back(elem);
+        }
+    }
+
+    std::vector<C2Value::Primitive> _mValues; ///< the supported set of values
+};
+
+/**
+ * Helper class to handle C2FieldSupporteValues object for fields of various types.
+ */
+template<typename T>
+class C2FieldSupportedValuesHelper;
+
+// templated operator must be predeclared for friend declaration
+template<typename T>
+std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<T> &i);
+
+template<typename T>
+class C2FieldSupportedValuesHelper {
+public:
+    /**
+     * Creates a helper for a specific type from a generic C2FieldSupportedValues struct.
+     */
+    C2FieldSupportedValuesHelper(const C2FieldSupportedValues &values);
+
+    // TRICKY: needed for std::unique_ptr<Impl> declaration
+    ~C2FieldSupportedValuesHelper();
+
+    // support copy constructor/operator
+    C2FieldSupportedValuesHelper(const C2FieldSupportedValuesHelper &);
+    C2FieldSupportedValuesHelper& operator=(const C2FieldSupportedValuesHelper &);
+
+    bool supports(T value) const;
+
+private:
+    // use pimpl as implementation may change in the future
+    struct Impl;
+    std::unique_ptr<Impl> _mImpl;
+
+    friend std::ostream& operator<< <T>(std::ostream& os, const C2FieldSupportedValuesHelper<T> &i);
+    //friend std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper &i);
+};
+
+/**
+ * Builder for supported values for a field of a given type.
+ *
+ * This builder can be used to successively restrict the supported values for a field. Upon
+ * creation, there are no supported values specified - which for this builder means that all
+ * values are supported.
+ */
+template<typename T>
+class C2ParamFieldValuesBuilder {
+public:
+    /**
+     * Creates a builder with no defined values - but implicitly any value allowed.
+     */
+    C2ParamFieldValuesBuilder(const C2ParamField &field);
+
+    /**
+     * Get C2ParamFieldValues from this builder.
+     */
+    operator C2ParamFieldValues() const;
+
+    /**
+     * Define the supported values as the currently supported values of this builder.
+     */
+    C2ParamFieldValuesBuilder<T> &any();
+
+    /**
+     * Restrict (and thus define) the supported values to none.
+     *
+     * \note This really should not be used from the builder as all params must have supported
+     *       values, but is here in case this is really the case.
+     */
+    C2ParamFieldValuesBuilder<T> &none();
+
+    /**
+     * Restrict (and thus define) the supported values to |value| alone.
+     */
+    C2ParamFieldValuesBuilder<T> &equalTo(T value);
+
+    /**
+     * Restrict (and thus define) the supported values to values greater than |value|.
+     */
+    inline C2ParamFieldValuesBuilder<T> &greaterThan(T value) {
+        return limitTo(C2SupportedRange<T>::GreaterThan(value));
+    }
+
+    /**
+     * Restrict (and thus define) the supported values to values greater than or equal to |value|.
+     */
+    C2ParamFieldValuesBuilder<T> &greaterThanOrEqualTo(T value) {
+        return limitTo(C2SupportedRange<T>::GreaterThanOrEqualTo(value));
+    }
+
+    /**
+     * Restrict (and thus define) the supported values to values greater than or equal to |value|.
+     */
+    C2ParamFieldValuesBuilder<T> &notLessThan(T value) {
+        return limitTo(C2SupportedRange<T>::NotLessThan(value));
+    }
+
+    /**
+     * Restrict (and thus define) the supported values to values less than or equal to |value|.
+     */
+    C2ParamFieldValuesBuilder<T> &lessThanOrEqualTo(T value) {
+        return limitTo(C2SupportedRange<T>::LessThanOrEqualTo(value));
+    }
+
+    /**
+     * Restrict (and thus define) the supported values to values less than or equal to |value|.
+     */
+    C2ParamFieldValuesBuilder<T> &notGreaterThan(T value) {
+        return limitTo(C2SupportedRange<T>::NotGreaterThan(value));
+    }
+
+    /**
+     * Restrict (and thus define) the supported values to values less than |value|.
+     */
+    C2ParamFieldValuesBuilder<T> &lessThan(T value) {
+        return limitTo(C2SupportedRange<T>::LessThan(value));
+    }
+
+    /**
+     * Restrict (and thus define) the supported values to values in the range of [ |min|, |max| ]
+     * with optional |step|.
+     */
+    C2ParamFieldValuesBuilder<T> &inRange(
+            T min, T max, T step = std::is_floating_point<T>::value ? T(0) : T(1))  {
+        return limitTo(C2SupportedRange<T>::InRange(min, max, step));
+    }
+
+    /**
+     * Restrict (and thus define) the supported values to values in the geometric series starting
+     * from |min| with factor |num| / |denom|, not greater than |max|.
+     */
+    C2ParamFieldValuesBuilder<T> &inSeries(T min, T max, T num, T denom) {
+        return limitTo(C2SupportedRange<T>::InSeries(min, max, num, denom));
+    }
+
+    /**
+     * Restrict (and thus define) the supported values to values in the multiply-accumulate series
+     * starting from |min| with factor |num| / |denom| and |step|, not greater than |max|.
+     */
+    C2ParamFieldValuesBuilder<T> &inMacSeries(T min, T max, T step, T num, T denom) {
+        return limitTo(C2SupportedRange<T>::InMacSeries(min, max, step, num, denom));
+    }
+
+    /**
+     * Restrict (and thus define) the supported values to values in |values|.
+     */
+    C2ParamFieldValuesBuilder<T> &oneOf(const std::initializer_list<T> values) {
+        return limitTo(C2SupportedValueSet<T>::OneOf(values));
+    }
+
+    /**
+     * Restrict (and thus define) the supported values to values in |values|.
+     */
+    C2ParamFieldValuesBuilder<T> &oneOf(const std::vector<T> &values) {
+        return limitTo(C2SupportedValueSet<T>::OneOf(values));
+    }
+
+    /**
+     * Restrict (and thus define) the supported values to flags in |flags| with at least |min|
+     * set.
+     */
+    C2ParamFieldValuesBuilder<T> &flags(const std::vector<T> &flags, T min = T(0)) {
+        return limitTo(C2SupportedFlags<T>::Flags(flags, min));
+    }
+
+    /**
+     * Restrict (and thus define) the supported values to flags in |values| with at least |min|
+     * set.
+     */
+    C2ParamFieldValuesBuilder<T> &flags(const std::initializer_list<T> flags, T min = T(0)) {
+        return limitTo(C2SupportedFlags<T>::Flags(flags, min));
+    }
+
+    virtual ~C2ParamFieldValuesBuilder();
+
+    // support copy constructor/operator
+    C2ParamFieldValuesBuilder(const C2ParamFieldValuesBuilder &);
+    C2ParamFieldValuesBuilder& operator=(const C2ParamFieldValuesBuilder &);
+
+private:
+    /**
+     * Restrict (and thus define) the supported values to a value set.
+     */
+    C2ParamFieldValuesBuilder<T> &limitTo(const C2SupportedValueSet<T> &limit);
+
+    /**
+     * Restrict (and thus define) the supported values to a value set.
+     */
+    C2ParamFieldValuesBuilder<T> &limitTo(const C2SupportedFlags<T> &limit);
+
+    /**
+     * Restrict (and thus define) the supported values to a range.
+     */
+    C2ParamFieldValuesBuilder<T> &limitTo(const C2SupportedRange<T> &limit);
+
+    struct Impl;
+    std::unique_ptr<Impl> _mImpl;
+};
+
+/**
+ * Builder for a list of setting conflicts.
+ */
+class C2SettingConflictsBuilder {
+public:
+    /**
+     * Creates an empty list of setting conflicts.
+     */
+    C2SettingConflictsBuilder();
+
+    /**
+     * Creates a list containing a single setting conflict.
+     */
+    C2SettingConflictsBuilder(C2ParamFieldValues &&conflict);
+
+    /**
+     * Adds a conflict to the current list of conflicts and returns this
+     */
+    C2SettingConflictsBuilder& with(C2ParamFieldValues &&conflict);
+
+    /**
+     * Gets the current list of conflicts (and moves them out of this builder.)
+     * (this is why it is not const)
+     */
+    std::vector<C2ParamFieldValues> retrieveConflicts();
+
+    /**
+     * Returns whether the current list is empty.
+     */
+    inline bool empty() const { return _mConflicts.empty(); }
+
+    inline operator bool() const { return empty(); }
+
+private:
+    std::vector<C2ParamFieldValues> _mConflicts;
+};
+
+/**
+ * Setting result builder for a parameter.
+ */
+struct C2SettingResultBuilder {
+    /**
+     * Creates a read-only setting result failure.
+     *
+     * This does not take FSV as only the current value of the field is supported.
+     */
+    static C2SettingResult ReadOnly(const C2ParamField &param);
+
+    /**
+     * Creates a bad-value or infoinformational bad-value setting result failure.
+     *
+     * This does not take FSV as the value is outside of the possible values. As such, there are no
+     * conflicts for this case either.
+     */
+    static C2SettingResult BadValue(const C2ParamField &paramField, bool isInfo = false);
+
+    /**
+     * Creates a conflict (or informational conflict) setting result failure.
+     *
+     * This takes FSV so use paramFieldValues and optional conflicts.
+     */
+    static C2SettingResult Conflict(
+            C2ParamFieldValues &&paramFieldValues, C2SettingConflictsBuilder &conflicts,
+            bool isInfo = false);
+
+    // TODO: retrieve results
+
+
+private:
+    C2ParamField _mParamField;
+    C2SettingResult _mResult;
+
+    C2SettingResultBuilder(const C2SettingResultBuilder &) = delete;
+};
+
+/**
+ * Setting results (PLURAL) builder.
+ *
+ * Setting results contain a failure status along with a list of failing fields or params.
+ */
+struct C2SettingResultsBuilder {
+    C2SettingResultsBuilder(const C2SettingResultsBuilder&) = delete;
+    C2SettingResultsBuilder(C2SettingResultsBuilder&&) = default;
+    C2SettingResultsBuilder &operator=(C2SettingResultsBuilder&&) = default;
+
+    /** \returns (default) successful result with no details. */
+    inline static C2SettingResultsBuilder Ok() {
+        return C2SettingResultsBuilder(C2_OK);
+    }
+
+    /** \returns Interface is in bad state, with no further details. */
+    inline static C2SettingResultsBuilder BadState() {
+        return C2SettingResultsBuilder(C2_BAD_STATE);
+    }
+
+    /** \returns Interface connection timed out, with no further details. */
+    inline static C2SettingResultsBuilder TimedOut() {
+        return C2SettingResultsBuilder(C2_TIMED_OUT);
+    }
+
+    /** \returns Interface connection is corrupted, with no further details. */
+    inline static C2SettingResultsBuilder Corrupted() {
+        return C2SettingResultsBuilder(C2_CORRUPTED);
+    }
+
+    inline static C2SettingResultsBuilder NoMemory(C2Param::Index index_ __unused) {
+        // TODO: try to add failure result
+        return C2SettingResultsBuilder(C2_NO_MEMORY);
+    }
+
+    // TODO: this should not be a constructor
+    /** Creates a builder with a single bad value setting result. */
+    C2SettingResultsBuilder(C2SettingResult &&result);
+
+    /** Combines this results with other results. */
+    C2SettingResultsBuilder plus(C2SettingResultsBuilder&& results);
+
+    /** Retrieve (get and move out) failures and return the failure status. */
+    c2_status_t retrieveFailures(std::vector<std::unique_ptr<C2SettingResult>>* const failures);
+
+private:
+    /** Setting results based on a single status. This is used when actual setting could not be
+     *  attempted to get a single C2SettingResult, or when a setting succeeded without
+     *  'complaints'. */
+    C2SettingResultsBuilder(c2_status_t status);
+        // status must be one of OK, BAD_STATE, TIMED_OUT, CORRUPTED or NO_MEMORY
+        // mainly: BLOCKING, BAD_INDEX, BAD_VALUE and NO_MEMORY requires a setting attempt, but
+        // NO_MEMORY may not allow us to create a results structure.
+
+    /**
+     * One of OK, BAD_INDEX, BAD_VALUE, BAD_STATE, NO_MEMORY, TIMED_OUT, BLOCKING or CORRUPTED.
+     */
+    c2_status_t _mStatus __unused;
+
+    /**
+     * Vector of individual setting result details.
+     */
+    std::vector<std::unique_ptr<C2SettingResult>> _mResults;
+};
+
+/**
+ * Utility class to enumerate fields of parameters.
+ */
+struct C2FieldUtils {
+    struct _Inspector;
+
+    /**
+     * An extended field descriptor object with structural information (lineage back to the root of
+     * the param).
+     */
+    struct Info {
+        typedef C2FieldDescriptor::type_t type_t; ///< field type
+        typedef C2FieldDescriptor::NamedValuesType NamedValuesType; ///< named values list type
+
+        /// returns the name of the field
+        C2String name() const;
+
+        /// returns the type of this field
+        type_t type() const;
+
+        /**
+         * Returns the defined name-value pairings for this field. The returned reference is
+         * only valid during the validity of this object
+         */
+        const NamedValuesType &namedValues() const;
+
+        /**
+         * The index of this field. E.g. param.field or param.field[0] has an index of 0, and
+         * param.struct[2].field[3] has an index of 3.
+         */
+        size_t index() const;
+
+        /// returns the length of the field in case it is an array. Returns 0 for
+        /// T[] arrays if this info comes from a C2Param::Index object, and the currently used
+        /// extent if it comes from a C2Param object. Returns 1 for T[1] arrays as well as if the
+        /// field is not an array.
+        size_t extent() const;
+
+        /**
+         * The (structural) depth of this field. E.g. param.field or param.field[0] has a depth of
+         *  0, and param.struct.field or param.struct[0].field[0] has a depth of 1.
+         */
+        size_t depth() const;
+
+        /**
+         * Returns the offset of this field in the parameter in bytes.
+         */
+        size_t offset() const;
+
+        /**
+         * Returns the size of this field in bytes.
+         */
+        size_t size() const;
+
+        /**
+         * The offset of this field's array. E.g. for param.struct[2].field[3] this is the offset
+         * of its smallest sibling: param.struct[2].field[0].
+         */
+        size_t arrayOffset() const;
+
+        /**
+         * Returns the size of this field's array. This is equivalent to extent() * size()
+         */
+        size_t arraySize() const;
+
+        /**
+         * The offset of the base field. The base field is a cousin of the current field where
+         * all indices are 0. E.g. the the base field for param.struct[2].field[3] is
+         * param.struct[0].field[0]. Base fields are used to specify supported values for
+         * all cousin fields.
+         */
+        size_t baseFieldOffset() const;
+
+        /**
+         * Returns whether this field is an arithmetic (integral, counter or float) field.
+         */
+        bool isArithmetic() const;
+
+        /**
+         * Returns whether this field can have a flexible extent. extent() returns the current
+         * extent.
+         */
+        bool isFlexible() const;
+
+        /// returns whether this info is valid
+        inline bool isValid() const { return _mImpl != nullptr; }
+
+        /// returns the info for the parent of this field, or an invalid Info object if it has no
+        /// parents
+        Info parent() const;
+
+        /// returns whether this info is valid
+        inline operator bool() const { return isValid(); }
+
+        struct Impl;
+        Info(std::shared_ptr<Impl>);
+
+    private:
+        std::shared_ptr<Impl> _mImpl;
+        friend struct _Inspector;
+    };
+
+    /**
+     * An (input) iterator object over fields using Info objects.
+     */
+    struct Iterator {
+        typedef Info const value_type;
+        typedef ptrdiff_t difference_type;
+        typedef Info const * pointer;
+        typedef Info const reference;
+        typedef std::input_iterator_tag iterator_category;
+
+        /// return Info at current position
+        virtual reference operator*() const;
+
+        /// move to the next field
+        virtual Iterator& operator++();
+
+        virtual bool operator==(const Iterator &) const;
+        inline bool operator!=(const Iterator &other) const { return !operator==(other); }
+
+        virtual ~Iterator() = default;
+
+        struct Impl;
+        Iterator(std::shared_ptr<Impl>);
+
+    protected:
+        std::shared_ptr<Impl> mImpl;
+    };
+
+    /**
+     * An (input) iterable object representing a list of fields.
+     */
+    struct List {
+        /// returns an iterator to the beginning of the list
+        virtual Iterator begin() const;
+
+        /// returns an iterator to the end of the list
+        virtual Iterator end() const;
+
+        virtual ~List() = default;
+
+        struct Impl;
+        List(std::shared_ptr<Impl>);
+
+    protected:
+        std::shared_ptr<Impl> mImpl;
+    };
+
+    /**
+     * Enumerates all (base) fields at index 0 of the parameter. The order of iteration is the
+     * following:
+     *   Fields of a structure are enumerated in field order. However, sub-fields of a structure
+     *   are enumerated directly after the structure field, and prior to sibling fields.
+     *
+     * In essence the order of enumeration is first by increasing offset, then by decreasing size.
+     *
+     * \param param parameter to enumerate its fields
+     * \param reflector parameter reflector used for enumeration
+     *
+     * \return an iterable object
+     */
+    static List enumerateFields(
+            const C2Param &param,
+            const std::shared_ptr<C2ParamReflector> &reflector);
+
+    /**
+     * Enumerates all cousin fields up to depth - level for a field. If level is 0, it enumerates
+     * only the field. For level 1, it enumerates all fields in its current array (which may be
+     * itself if extent is 1). The order of iteration is by increasing field offset.
+     */
+    static List enumerateCousins(
+            const Info &field,
+            uint32_t level = ~0);
+
+    /**
+     * Locates the field in a parameter and returns a list of 2 elements - the most-specific field
+     * array of the parameter that contains the entire field. If the field is not a valid field
+     * specifier for this parameter (e.g. it is outside the bounds of the parameter), it returns
+     * an empty list.
+     */
+    static std::vector<Info> locateField(
+            const C2Param &param, const _C2FieldId &field,
+            const std::shared_ptr<C2ParamReflector> &reflector);
+
+    static std::vector<Info> locateField(
+            const C2ParamField &pf, const std::shared_ptr<C2ParamReflector> &reflector);
+
+};
+
+#include <util/C2Debug-interface.h>
+
+#endif  // C2UTILS_INTERFACE_UTILS_H_
diff --git a/media/codec2/vndk/include/util/C2ParamUtils.h b/media/codec2/vndk/include/util/C2ParamUtils.h
new file mode 100644
index 0000000..b51bd94
--- /dev/null
+++ b/media/codec2/vndk/include/util/C2ParamUtils.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef C2UTILS_PARAM_UTILS_H_
+#define C2UTILS_PARAM_UTILS_H_
+
+#include <utility>
+#include <vector>
+
+/** \file
+ * Utilities for parameter handling to be used by Codec2 implementations.
+ */
+
+/// \cond INTERNAL
+
+struct C2Param;
+
+class C2ParamUtils {
+    friend class C2UtilTest_ParamUtilsTest_Test;
+
+public:
+
+    /// safe(r) parsing from parameter blob
+    static
+    C2Param *ParseFirst(const uint8_t *blob, size_t size);
+};
+
+/// \endcond
+
+#endif  // C2UTILS_PARAM_UTILS_H_
+
diff --git a/media/codec2/vndk/internal/C2BlockInternal.h b/media/codec2/vndk/internal/C2BlockInternal.h
new file mode 100644
index 0000000..4ae946a
--- /dev/null
+++ b/media/codec2/vndk/internal/C2BlockInternal.h
@@ -0,0 +1,381 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_STAGEFRIGHT_C2BLOCK_INTERNAL_H_
+#define ANDROID_STAGEFRIGHT_C2BLOCK_INTERNAL_H_
+
+#include <android/hardware/graphics/bufferqueue/2.0/IGraphicBufferProducer.h>
+
+#include <C2Buffer.h>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace bufferpool {
+
+struct BufferPoolData;
+
+}
+}
+}
+}
+
+/**
+ * Stores informations from C2BlockPool implementations which are required by C2Block.
+ */
+struct C2_HIDE _C2BlockPoolData {
+    enum type_t : int {
+        TYPE_BUFFERPOOL = 0,
+        TYPE_BUFFERQUEUE,
+    };
+
+    virtual type_t getType() const = 0;
+
+protected:
+    _C2BlockPoolData() = default;
+
+    virtual ~_C2BlockPoolData() = default;
+};
+
+struct C2BufferQueueBlockPoolData;
+
+/**
+ * Internal only interface for creating blocks by block pool/buffer passing implementations.
+ *
+ * \todo this must be hidden
+ */
+struct _C2BlockFactory {
+    /**
+     * Create a linear block from an allocation for an allotted range.
+     *
+     * \param alloc parent allocation
+     * \param data  blockpool data
+     * \param offset allotted range offset
+     * \param size  allotted size
+     *
+     * \return shared pointer to the linear block. nullptr if there was not enough memory to
+     *         create this block.
+     */
+    static
+    std::shared_ptr<C2LinearBlock> CreateLinearBlock(
+            const std::shared_ptr<C2LinearAllocation> &alloc,
+            const std::shared_ptr<_C2BlockPoolData> &data = nullptr,
+            size_t offset = 0,
+            size_t size = ~(size_t)0);
+
+    /**
+     * Create a graphic block from an allocation for an allotted section.
+     *
+     * \param alloc parent allocation
+     * \param data  blockpool data
+     * \param crop  allotted crop region
+     *
+     * \return shared pointer to the graphic block. nullptr if there was not enough memory to
+     *         create this block.
+     */
+    static
+    std::shared_ptr<C2GraphicBlock> CreateGraphicBlock(
+            const std::shared_ptr<C2GraphicAllocation> &alloc,
+            const std::shared_ptr<_C2BlockPoolData> &data = nullptr,
+            const C2Rect &allottedCrop = C2Rect(~0u, ~0u));
+
+    /**
+     * Return a block pool data from 1D block.
+     *
+     * \param shared pointer to the 1D block which is already created.
+     */
+    static
+    std::shared_ptr<_C2BlockPoolData> GetLinearBlockPoolData(
+            const C2Block1D& block);
+
+    /**
+     * Return a block pool data from 2D block.
+     *
+     * \param shared pointer to the 2D block which is already created.
+     */
+    static
+    std::shared_ptr<_C2BlockPoolData> GetGraphicBlockPoolData(
+            const C2Block2D& block);
+
+    /**
+     * Create a linear block from the received native handle.
+     *
+     * \param handle    native handle to a linear block
+     *
+     * \return shared pointer to the linear block. nullptr if there was not enough memory to
+     *         create this block.
+     */
+    static
+    std::shared_ptr<C2LinearBlock> CreateLinearBlock(
+            const C2Handle *handle);
+
+    /**
+     * Create a graphic block from the received native handle.
+     *
+     * \param handle    native handle to a graphic block
+     *
+     * \return shared pointer to the graphic block. nullptr if there was not enough memory to
+     *         create this block.
+     */
+    static
+    std::shared_ptr<C2GraphicBlock> CreateGraphicBlock(
+            const C2Handle *handle);
+
+    /**
+     * Create a linear block from the received bufferpool data.
+     *
+     * \param data  bufferpool data to a linear block
+     *
+     * \return shared pointer to the linear block. nullptr if there was not enough memory to
+     *         create this block.
+     */
+    static
+    std::shared_ptr<C2LinearBlock> CreateLinearBlock(
+            const C2Handle *handle,
+            const std::shared_ptr<android::hardware::media::bufferpool::BufferPoolData> &data);
+
+    /**
+     * Create a graphic block from the received bufferpool data.
+     *
+     * \param data  bufferpool data to a graphic block
+     *
+     * \return shared pointer to the graphic block. nullptr if there was not enough memory to
+     *         create this block.
+     */
+    static
+    std::shared_ptr<C2GraphicBlock> CreateGraphicBlock(
+            const C2Handle *handle,
+            const std::shared_ptr<android::hardware::media::bufferpool::BufferPoolData> &data);
+
+    /**
+     * Get bufferpool data from the blockpool data.
+     *
+     * \param poolData          blockpool data
+     * \param bufferPoolData    pointer to bufferpool data where the bufferpool
+     *                          data is stored.
+     *
+     * \return {\code true} when there is valid bufferpool data, {\code false} otherwise.
+     */
+    static
+    bool GetBufferPoolData(
+            const std::shared_ptr<const _C2BlockPoolData> &poolData,
+            std::shared_ptr<android::hardware::media::bufferpool::BufferPoolData> *bufferPoolData);
+
+    /*
+     * Life Cycle Management of BufferQueue-Based Blocks
+     * =================================================
+     *
+     * A block that is created by a bufferqueue-based blockpool requires some
+     * special treatment when it is destroyed. In particular, if the block
+     * corresponds to a held (dequeued/attached) GraphicBuffer in a slot of a
+     * bufferqueue, its destruction should trigger a call to
+     * IGraphicBufferProducer::cancelBuffer(). On the other hand, if the
+     * GraphicBuffer is not held, i.e., if it has been queued or detached,
+     * cancelBuffer() should not be called upon the destruction of the block.
+     *
+     * _C2BlockPoolData created by a bufferqueue-based blockpool includes two
+     * main pieces of information:
+     *   - "held" status: Whether cancelBuffer() should be called upon
+     *     destruction of the block.
+     *   - bufferqueue assignment: The quadruple (igbp, generation, bqId,
+     *     bqSlot), where igbp is the IGraphicBufferProducer instance of the
+     *     bufferqueue, generation is the latest generation number, of the
+     *     bufferqueue, bqId is the globally unique id of the bufferqueue, and
+     *     bqSlot is the slot in the bufferqueue.
+     *
+     * igbp is the instance of IGraphicBufferProducer on which cancelBuffer()
+     * will be called if "held" status is true when the block is destroyed.
+     * (bqSlot is an input to cancelBuffer().) However, only generation, bqId
+     * and bqSlot are retained when a block is transferred from one process to
+     * another. It is the responsibility of both the sending and receiving
+     * processes to maintain consistency of "held" status and igbp. Below are
+     * functions provided for this purpose:
+     *
+     *   - GetBufferQueueData(): Returns generation, bqId and bqSlot.
+     *   - HoldBlockFromBufferQueue(): Sets "held" status to true.
+     *   - BeginTransferBlockToClient()/EndTransferBlockToClient():
+     *     Clear "held" status to false if transfer was successful,
+     *     otherwise "held" status remains true.
+     *   - BeginAttachBlockToBufferQueue()/EndAttachBlockToBufferQueue():
+     *     The will keep "held" status true if attach was eligible.
+     *     Otherwise, "held" status is cleared to false. In that case,
+     *     ownership of buffer should be transferred to bufferqueue.
+     *   - DisplayBlockToBufferQueue()
+     *     This will clear "held" status to false.
+     *
+     * All these functions operate on _C2BlockPoolData, which can be obtained by
+     * calling GetGraphicBlockPoolData().
+     *
+     * Maintaining Consistency with IGraphicBufferProducer Operations
+     * ==============================================================
+     *
+     * dequeueBuffer()
+     *   - This function is called by the blockpool. It should not be called
+     *     manually. The blockpool will automatically generate the correct
+     *     information for _C2BlockPoolData, with "held" status set to true.
+     *
+     * queueBuffer()
+     *   - Before queueBuffer() is called, DisplayBlockToBufferQueue() should be
+     *     called to test eligibility. If it's not eligible, do not call
+     *     queueBuffer().
+     *
+     * attachBuffer() - remote migration only.
+     *   - Local migration on blockpool side will be done automatically by
+     *     blockpool.
+     *   - Before attachBuffer(), BeginAttachBlockToBufferQueue() should be called
+     *     to test eligiblity.
+     *   - After attachBuffer() is called, EndAttachBlockToBufferQueue() should
+     *     be called. This will set "held" status to true. If it returned
+     *     false, cancelBuffer() should be called.
+     *
+     * detachBuffer() - no-op.
+     */
+
+    /**
+     * Get bufferqueue data from the blockpool data.
+     *
+     * Calling this function with \p generation set to nullptr will return
+     * whether the block comes from a bufferqueue-based blockpool, but will not
+     * fill in the values for \p generation, \p bqId or \p bqSlot.
+     *
+     * \param[in]  poolData   blockpool data.
+     * \param[out] generation Generation number attached to the buffer.
+     * \param[out] bqId       Id of the bufferqueue owning the buffer (block).
+     * \param[out] bqSlot     Slot number of the buffer.
+     *
+     * \return \c true when there is valid bufferqueue data;
+     *         \c false otherwise.
+     */
+    static
+    bool GetBufferQueueData(
+            const std::shared_ptr<const _C2BlockPoolData>& poolData,
+            uint32_t* generation = nullptr,
+            uint64_t* bqId = nullptr,
+            int32_t* bqSlot = nullptr);
+
+    /**
+     * Hold a block from the designated bufferqueue. This causes the destruction
+     * of the block to trigger a call to cancelBuffer().
+     *
+     * This function assumes that \p poolData comes from a bufferqueue-based
+     * block. It does not check if that is the case.
+     *
+     * \param poolData blockpool data associated to the block.
+     * \param owner    block owner from client bufferqueue manager.
+     *                 If this is expired, the block is not owned by client
+     *                 anymore.
+     * \param igbp     \c IGraphicBufferProducer instance to be assigned to the
+     *                 block. This is not needed when the block is local.
+     *
+     * \return The previous held status.
+     */
+    static
+    bool HoldBlockFromBufferQueue(
+            const std::shared_ptr<_C2BlockPoolData>& poolData,
+            const std::shared_ptr<int>& owner,
+            const ::android::sp<::android::hardware::graphics::bufferqueue::
+                                V2_0::IGraphicBufferProducer>& igbp = nullptr);
+
+    /**
+     * Prepare a block to be transferred to other process. This blocks
+     * bufferqueue migration from happening. The block should be in held.
+     *
+     * This function assumes that \p poolData comes from a bufferqueue-based
+     * block. It does not check if that is the case.
+     *
+     * \param poolData blockpool data associated to the block.
+     *
+     * \return true if transfer is eligible, false otherwise.
+     */
+    static
+    bool BeginTransferBlockToClient(
+            const std::shared_ptr<_C2BlockPoolData>& poolData);
+
+    /**
+     * Called after transferring the specified block is finished. Make sure
+     * that BeginTransferBlockToClient() was called before this call.
+     *
+     * This will unblock bufferqueue migration. If transfer result was
+     * successful, this causes the destruction of the block not to trigger a
+     * call to cancelBuffer().
+     * This function assumes that \p poolData comes from a bufferqueue-based
+     * block. It does not check if that is the case.
+     *
+     * \param poolData blockpool data associated to the block.
+     *
+     * \return true if transfer began before, false otherwise.
+     */
+    static
+    bool EndTransferBlockToClient(
+            const std::shared_ptr<_C2BlockPoolData>& poolData,
+            bool transferred);
+
+    /**
+     * Prepare a block to be migrated to another bufferqueue. This blocks
+     * rendering until migration has been finished.  The block should be in
+     * held.
+     *
+     * This function assumes that \p poolData comes from a bufferqueue-based
+     * block. It does not check if that is the case.
+     *
+     * \param poolData blockpool data associated to the block.
+     *
+     * \return true if migration is eligible, false otherwise.
+     */
+    static
+    bool BeginAttachBlockToBufferQueue(
+            const std::shared_ptr<_C2BlockPoolData>& poolData);
+
+    /**
+     * Called after migration of the specified block is finished. Make sure
+     * that BeginAttachBlockToBufferQueue() was called before this call.
+     *
+     * This will unblock rendering. if redering is tried during migration,
+     * this returns false. In that case, cancelBuffer() should be called.
+     * This function assumes that \p poolData comes from a bufferqueue-based
+     * block. It does not check if that is the case.
+     *
+     * \param poolData blockpool data associated to the block.
+     *
+     * \return true if migration is eligible, false otherwise.
+     */
+    static
+    bool EndAttachBlockToBufferQueue(
+            const std::shared_ptr<_C2BlockPoolData>& poolData,
+            const std::shared_ptr<int>& owner,
+            const ::android::sp<::android::hardware::graphics::bufferqueue::
+                                V2_0::IGraphicBufferProducer>& igbp,
+            uint32_t generation,
+            uint64_t bqId,
+            int32_t bqSlot);
+
+    /**
+     * Indicates a block to be rendered very soon.
+     *
+     * This function assumes that \p poolData comes from a bufferqueue-based
+     * block. It does not check if that is the case.
+     *
+     * \param poolData blockpool data associated to the block.
+     *
+     * \return true if migration is eligible, false otherwise.
+     */
+    static
+    bool DisplayBlockToBufferQueue(
+            const std::shared_ptr<_C2BlockPoolData>& poolData);
+};
+
+#endif // ANDROID_STAGEFRIGHT_C2BLOCK_INTERNAL_H_
+
diff --git a/media/codec2/vndk/internal/C2ParamInternal.h b/media/codec2/vndk/internal/C2ParamInternal.h
new file mode 100644
index 0000000..24a8f27
--- /dev/null
+++ b/media/codec2/vndk/internal/C2ParamInternal.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_STAGEFRIGHT_C2PARAM_INTERNAL_H_
+#define ANDROID_STAGEFRIGHT_C2PARAM_INTERNAL_H_
+
+#include <C2Param.h>
+
+struct C2_HIDE _C2ParamInspector {
+    inline static uint32_t GetOffset(const C2FieldDescriptor &fd) {
+        return fd._mFieldId._mOffset;
+    }
+
+    inline static void SetOffset(C2FieldDescriptor &fd, uint32_t offset) {
+        fd._mFieldId._mOffset = offset;
+    }
+
+    inline static uint32_t GetEndOffset(const C2FieldDescriptor &fd, uint32_t paramSize = 0) {
+        uint32_t endOffset = fd._mFieldId._mOffset + fd._mExtent * fd._mFieldId._mSize;
+        /// for flex parameters return paramSize if given
+        return fd._mExtent ? endOffset : std::max(endOffset, paramSize);
+    }
+
+    inline static uint32_t GetSize(const C2FieldDescriptor &fd) {
+        return fd._mFieldId._mSize;
+    }
+
+    inline static uint32_t GetIndex(const C2ParamField &pf) {
+        return pf._mIndex;
+    }
+
+    inline static uint32_t GetOffset(const C2ParamField &pf) {
+        return pf._mFieldId._mOffset;
+    }
+
+    inline static uint32_t GetSize(const C2ParamField &pf) {
+        return pf._mFieldId._mSize;
+    }
+
+    inline static uint32_t GetOffset(const _C2FieldId &f) {
+        return f._mOffset;
+    }
+
+    inline static uint32_t GetSize(const _C2FieldId &f) {
+        return f._mSize;
+    }
+
+    inline static _C2FieldId GetField(const C2FieldDescriptor &fd) {
+        return fd._mFieldId;
+    }
+
+    inline static uint32_t GetAttrib(const C2ParamDescriptor &pd) {
+        return pd._mAttrib;
+    }
+
+    inline static _C2FieldId GetField(const C2ParamField &pf) {
+        return pf._mFieldId;
+    }
+
+    inline static
+    C2ParamField CreateParamField(C2Param::Index index, uint32_t offset, uint32_t size) {
+        return C2ParamField(index, offset, size);
+    }
+
+    inline static
+    C2ParamField CreateParamField(C2Param::Index index, _C2FieldId field) {
+        return C2ParamField(index, field._mOffset, field._mSize);
+    }
+
+    inline static
+    void TrimParam(C2Param *param, uint32_t newSize) {
+        if (param && *param && param->size() > newSize && newSize >= sizeof(C2Param)) {
+            param->_mSize = newSize;
+        }
+    }
+
+    inline static void AddNamedValues(
+            C2FieldDescriptor &fd, C2FieldDescriptor::NamedValuesType &&namedValues) {
+        fd._mNamedValues = std::move(namedValues);
+    }
+
+    inline static
+    C2StructDescriptor CreateStructDescriptor(C2Param::CoreIndex index,
+                                        std::vector<C2FieldDescriptor> &&fields) {
+        return C2StructDescriptor(index, std::move(fields));
+    }
+
+    inline static
+    C2FieldDescriptor OffsetFieldDescriptor(const C2FieldDescriptor &fd, size_t offset) {
+        return C2FieldDescriptor(fd, offset);
+    }
+
+    // expose attributes
+    typedef C2ParamDescriptor::attrib_t attrib_t;
+};
+
+#endif // ANDROID_STAGEFRIGHT_C2PARAM_INTERNAL_H_
+
diff --git a/media/codec2/vndk/platform/C2BqBuffer.cpp b/media/codec2/vndk/platform/C2BqBuffer.cpp
new file mode 100644
index 0000000..8304f74
--- /dev/null
+++ b/media/codec2/vndk/platform/C2BqBuffer.cpp
@@ -0,0 +1,792 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2BqBuffer"
+#include <utils/Log.h>
+
+#include <ui/BufferQueueDefs.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/Fence.h>
+
+#include <types.h>
+
+#include <hidl/HidlSupport.h>
+
+#include <C2AllocatorGralloc.h>
+#include <C2BqBufferPriv.h>
+#include <C2BlockInternal.h>
+
+#include <list>
+#include <map>
+#include <mutex>
+
+using ::android::BufferQueueDefs::NUM_BUFFER_SLOTS;
+using ::android::C2AllocatorGralloc;
+using ::android::C2AndroidMemoryUsage;
+using ::android::Fence;
+using ::android::GraphicBuffer;
+using ::android::sp;
+using ::android::status_t;
+using ::android::wp;
+using ::android::hardware::hidl_handle;
+using ::android::hardware::Return;
+
+using HBuffer = ::android::hardware::graphics::common::V1_2::HardwareBuffer;
+using HStatus = ::android::hardware::graphics::bufferqueue::V2_0::Status;
+using ::android::hardware::graphics::bufferqueue::V2_0::utils::b2h;
+using ::android::hardware::graphics::bufferqueue::V2_0::utils::h2b;
+using ::android::hardware::graphics::bufferqueue::V2_0::utils::HFenceWrapper;
+
+using HGraphicBufferProducer = ::android::hardware::graphics::bufferqueue::V2_0
+        ::IGraphicBufferProducer;
+
+struct C2BufferQueueBlockPoolData : public _C2BlockPoolData {
+
+    bool held;
+    bool local;
+    uint32_t generation;
+    uint64_t bqId;
+    int32_t bqSlot;
+    bool transfer; // local transfer to remote
+    bool attach; // attach on remote
+    bool display; // display on remote;
+    std::weak_ptr<int> owner;
+    sp<HGraphicBufferProducer> igbp;
+    std::shared_ptr<C2BufferQueueBlockPool::Impl> localPool;
+    mutable std::mutex lock;
+
+    virtual type_t getType() const override {
+        return TYPE_BUFFERQUEUE;
+    }
+
+    // Create a remote BlockPoolData.
+    C2BufferQueueBlockPoolData(
+            uint32_t generation, uint64_t bqId, int32_t bqSlot,
+            const std::shared_ptr<int> &owner,
+            const sp<HGraphicBufferProducer>& producer);
+
+    // Create a local BlockPoolData.
+    C2BufferQueueBlockPoolData(
+            uint32_t generation, uint64_t bqId, int32_t bqSlot,
+            const std::shared_ptr<C2BufferQueueBlockPool::Impl>& pool);
+
+    virtual ~C2BufferQueueBlockPoolData() override;
+
+    int migrate(const sp<HGraphicBufferProducer>& producer,
+                uint32_t toGeneration, uint64_t toBqId,
+                sp<GraphicBuffer> *buffers, uint32_t oldGeneration);
+};
+
+bool _C2BlockFactory::GetBufferQueueData(
+        const std::shared_ptr<const _C2BlockPoolData>& data,
+        uint32_t* generation, uint64_t* bqId, int32_t* bqSlot) {
+    if (data && data->getType() == _C2BlockPoolData::TYPE_BUFFERQUEUE) {
+        if (generation) {
+            const std::shared_ptr<const C2BufferQueueBlockPoolData> poolData =
+                    std::static_pointer_cast<const C2BufferQueueBlockPoolData>(data);
+            std::scoped_lock<std::mutex> lock(poolData->lock);
+            *generation = poolData->generation;
+            if (bqId) {
+                *bqId = poolData->bqId;
+            }
+            if (bqSlot) {
+                *bqSlot = poolData->bqSlot;
+            }
+        }
+        return true;
+    }
+    return false;
+}
+
+bool _C2BlockFactory::HoldBlockFromBufferQueue(
+        const std::shared_ptr<_C2BlockPoolData>& data,
+        const std::shared_ptr<int>& owner,
+        const sp<HGraphicBufferProducer>& igbp) {
+    const std::shared_ptr<C2BufferQueueBlockPoolData> poolData =
+            std::static_pointer_cast<C2BufferQueueBlockPoolData>(data);
+    std::scoped_lock<std::mutex> lock(poolData->lock);
+    if (!poolData->local) {
+        poolData->owner = owner;
+        poolData->igbp = igbp;
+    }
+    if (poolData->held) {
+        poolData->held = true;
+        return false;
+    }
+    poolData->held = true;
+    return true;
+}
+
+bool _C2BlockFactory::BeginTransferBlockToClient(
+        const std::shared_ptr<_C2BlockPoolData>& data) {
+    const std::shared_ptr<C2BufferQueueBlockPoolData> poolData =
+            std::static_pointer_cast<C2BufferQueueBlockPoolData>(data);
+    std::scoped_lock<std::mutex> lock(poolData->lock);
+    poolData->transfer = true;
+    return true;
+}
+
+bool _C2BlockFactory::EndTransferBlockToClient(
+        const std::shared_ptr<_C2BlockPoolData>& data,
+        bool transfer) {
+    const std::shared_ptr<C2BufferQueueBlockPoolData> poolData =
+            std::static_pointer_cast<C2BufferQueueBlockPoolData>(data);
+    std::scoped_lock<std::mutex> lock(poolData->lock);
+    poolData->transfer = false;
+    if (transfer) {
+        poolData->held = false;
+    }
+    return true;
+}
+
+bool _C2BlockFactory::BeginAttachBlockToBufferQueue(
+        const std::shared_ptr<_C2BlockPoolData>& data) {
+    const std::shared_ptr<C2BufferQueueBlockPoolData> poolData =
+            std::static_pointer_cast<C2BufferQueueBlockPoolData>(data);
+    std::scoped_lock<std::mutex> lock(poolData->lock);
+    if (poolData->local || poolData->display ||
+        poolData->attach || !poolData->held) {
+        return false;
+    }
+    if (poolData->bqId == 0) {
+        return false;
+    }
+    poolData->attach = true;
+    return true;
+}
+
+// if display was tried during attach, buffer should be retired ASAP.
+bool _C2BlockFactory::EndAttachBlockToBufferQueue(
+        const std::shared_ptr<_C2BlockPoolData>& data,
+        const std::shared_ptr<int>& owner,
+        const sp<HGraphicBufferProducer>& igbp,
+        uint32_t generation,
+        uint64_t bqId,
+        int32_t bqSlot) {
+    const std::shared_ptr<C2BufferQueueBlockPoolData> poolData =
+            std::static_pointer_cast<C2BufferQueueBlockPoolData>(data);
+    std::scoped_lock<std::mutex> lock(poolData->lock);
+    if (poolData->local || !poolData->attach ) {
+        return false;
+    }
+    if (poolData->display) {
+        poolData->attach = false;
+        poolData->held = false;
+        return false;
+    }
+    poolData->attach = false;
+    poolData->held = true;
+    poolData->owner = owner;
+    poolData->igbp = igbp;
+    poolData->generation = generation;
+    poolData->bqId = bqId;
+    poolData->bqSlot = bqSlot;
+    return true;
+}
+
+bool _C2BlockFactory::DisplayBlockToBufferQueue(
+        const std::shared_ptr<_C2BlockPoolData>& data) {
+    const std::shared_ptr<C2BufferQueueBlockPoolData> poolData =
+            std::static_pointer_cast<C2BufferQueueBlockPoolData>(data);
+    std::scoped_lock<std::mutex> lock(poolData->lock);
+    if (poolData->local || poolData->display || !poolData->held) {
+        return false;
+    }
+    if (poolData->bqId == 0) {
+        return false;
+    }
+    poolData->display = true;
+    if (poolData->attach) {
+        return false;
+    }
+    poolData->held = false;
+    return true;
+}
+
+std::shared_ptr<C2GraphicBlock> _C2BlockFactory::CreateGraphicBlock(
+        const C2Handle *handle) {
+    // TODO: get proper allocator? and mutex?
+    static std::unique_ptr<C2AllocatorGralloc> sAllocator = std::make_unique<C2AllocatorGralloc>(0);
+
+    std::shared_ptr<C2GraphicAllocation> alloc;
+    if (C2AllocatorGralloc::isValid(handle)) {
+        uint32_t width;
+        uint32_t height;
+        uint32_t format;
+        uint64_t usage;
+        uint32_t stride;
+        uint32_t generation;
+        uint64_t bqId;
+        uint32_t bqSlot;
+        android::_UnwrapNativeCodec2GrallocMetadata(
+                handle, &width, &height, &format, &usage, &stride, &generation, &bqId, &bqSlot);
+        c2_status_t err = sAllocator->priorGraphicAllocation(handle, &alloc);
+        if (err == C2_OK) {
+            std::shared_ptr<C2GraphicBlock> block;
+            if (bqId || bqSlot) {
+                // BQBBP
+                std::shared_ptr<C2BufferQueueBlockPoolData> poolData =
+                        std::make_shared<C2BufferQueueBlockPoolData>(generation,
+                                                                     bqId,
+                                                                     (int32_t)bqSlot,
+                                                                     nullptr,
+                                                                     nullptr);
+                block = _C2BlockFactory::CreateGraphicBlock(alloc, poolData);
+            } else {
+                block = _C2BlockFactory::CreateGraphicBlock(alloc);
+            }
+            return block;
+        }
+    }
+    return nullptr;
+}
+
+namespace {
+
+int64_t getTimestampNow() {
+    int64_t stamp;
+    struct timespec ts;
+    // TODO: CLOCK_MONOTONIC_COARSE?
+    clock_gettime(CLOCK_MONOTONIC, &ts);
+    stamp = ts.tv_nsec / 1000;
+    stamp += (ts.tv_sec * 1000000LL);
+    return stamp;
+}
+
+bool getGenerationNumber(const sp<HGraphicBufferProducer> &producer,
+                         uint32_t *generation) {
+    status_t status{};
+    int slot{};
+    bool bufferNeedsReallocation{};
+    sp<Fence> fence = new Fence();
+
+    using Input = HGraphicBufferProducer::DequeueBufferInput;
+    using Output = HGraphicBufferProducer::DequeueBufferOutput;
+    Return<void> transResult = producer->dequeueBuffer(
+            Input{640, 480, HAL_PIXEL_FORMAT_YCBCR_420_888, 0},
+            [&status, &slot, &bufferNeedsReallocation, &fence]
+            (HStatus hStatus, int32_t hSlot, Output const& hOutput) {
+                slot = static_cast<int>(hSlot);
+                if (!h2b(hStatus, &status) || !h2b(hOutput.fence, &fence)) {
+                    status = ::android::BAD_VALUE;
+                } else {
+                    bufferNeedsReallocation =
+                            hOutput.bufferNeedsReallocation;
+                }
+            });
+    if (!transResult.isOk() || status != android::OK) {
+        return false;
+    }
+    HFenceWrapper hFenceWrapper{};
+    if (!b2h(fence, &hFenceWrapper)) {
+        (void)producer->detachBuffer(static_cast<int32_t>(slot)).isOk();
+        ALOGE("Invalid fence received from dequeueBuffer.");
+        return false;
+    }
+    sp<GraphicBuffer> slotBuffer = new GraphicBuffer();
+    // N.B. This assumes requestBuffer# returns an existing allocation
+    // instead of a new allocation.
+    transResult = producer->requestBuffer(
+            slot,
+            [&status, &slotBuffer, &generation](
+                    HStatus hStatus,
+                    HBuffer const& hBuffer,
+                    uint32_t generationNumber){
+                if (h2b(hStatus, &status) &&
+                        h2b(hBuffer, &slotBuffer) &&
+                        slotBuffer) {
+                    *generation = generationNumber;
+                    slotBuffer->setGenerationNumber(generationNumber);
+                } else {
+                    status = android::BAD_VALUE;
+                }
+            });
+    if (!transResult.isOk()) {
+        return false;
+    } else if (status != android::NO_ERROR) {
+        (void)producer->detachBuffer(static_cast<int32_t>(slot)).isOk();
+        return false;
+    }
+    (void)producer->detachBuffer(static_cast<int32_t>(slot)).isOk();
+    return true;
+}
+
+};
+
+class C2BufferQueueBlockPool::Impl
+        : public std::enable_shared_from_this<C2BufferQueueBlockPool::Impl> {
+private:
+    c2_status_t fetchFromIgbp_l(
+            uint32_t width,
+            uint32_t height,
+            uint32_t format,
+            C2MemoryUsage usage,
+            std::shared_ptr<C2GraphicBlock> *block /* nonnull */) {
+        // We have an IGBP now.
+        C2AndroidMemoryUsage androidUsage = usage;
+        status_t status{};
+        int slot{};
+        bool bufferNeedsReallocation{};
+        sp<Fence> fence = new Fence();
+        ALOGV("tries to dequeue buffer");
+
+        { // Call dequeueBuffer().
+            using Input = HGraphicBufferProducer::DequeueBufferInput;
+            using Output = HGraphicBufferProducer::DequeueBufferOutput;
+            Return<void> transResult = mProducer->dequeueBuffer(
+                    Input{
+                        width,
+                        height,
+                        format,
+                        androidUsage.asGrallocUsage()},
+                    [&status, &slot, &bufferNeedsReallocation,
+                     &fence](HStatus hStatus,
+                             int32_t hSlot,
+                             Output const& hOutput) {
+                        slot = static_cast<int>(hSlot);
+                        if (!h2b(hStatus, &status) ||
+                                !h2b(hOutput.fence, &fence)) {
+                            status = ::android::BAD_VALUE;
+                        } else {
+                            bufferNeedsReallocation =
+                                    hOutput.bufferNeedsReallocation;
+                        }
+                    });
+            if (!transResult.isOk() || status != android::OK) {
+                if (transResult.isOk()) {
+                    ++mDqFailure;
+                    if (status == android::INVALID_OPERATION ||
+                        status == android::TIMED_OUT ||
+                        status == android::WOULD_BLOCK) {
+                        // Dequeue buffer is blocked temporarily. Retrying is
+                        // required.
+                        return C2_BLOCKING;
+                    }
+                }
+                ALOGD("cannot dequeue buffer %d", status);
+                return C2_BAD_VALUE;
+            }
+            mDqFailure = 0;
+            mLastDqTs = getTimestampNow();
+        }
+        HFenceWrapper hFenceWrapper{};
+        if (!b2h(fence, &hFenceWrapper)) {
+            ALOGE("Invalid fence received from dequeueBuffer.");
+            return C2_BAD_VALUE;
+        }
+        ALOGV("dequeued a buffer successfully");
+        if (fence) {
+            static constexpr int kFenceWaitTimeMs = 10;
+
+            status_t status = fence->wait(kFenceWaitTimeMs);
+            if (status == -ETIME) {
+                // fence is not signalled yet.
+                (void)mProducer->cancelBuffer(slot, hFenceWrapper.getHandle()).isOk();
+                return C2_BLOCKING;
+            }
+            if (status != android::NO_ERROR) {
+                ALOGD("buffer fence wait error %d", status);
+                (void)mProducer->cancelBuffer(slot, hFenceWrapper.getHandle()).isOk();
+                return C2_BAD_VALUE;
+            } else if (mRenderCallback) {
+                nsecs_t signalTime = fence->getSignalTime();
+                if (signalTime >= 0 && signalTime < INT64_MAX) {
+                    mRenderCallback(mProducerId, slot, signalTime);
+                } else {
+                    ALOGV("got fence signal time of %lld", (long long)signalTime);
+                }
+            }
+        }
+
+        sp<GraphicBuffer> &slotBuffer = mBuffers[slot];
+        uint32_t outGeneration;
+        if (bufferNeedsReallocation || !slotBuffer) {
+            if (!slotBuffer) {
+                slotBuffer = new GraphicBuffer();
+            }
+            // N.B. This assumes requestBuffer# returns an existing allocation
+            // instead of a new allocation.
+            Return<void> transResult = mProducer->requestBuffer(
+                    slot,
+                    [&status, &slotBuffer, &outGeneration](
+                            HStatus hStatus,
+                            HBuffer const& hBuffer,
+                            uint32_t generationNumber){
+                        if (h2b(hStatus, &status) &&
+                                h2b(hBuffer, &slotBuffer) &&
+                                slotBuffer) {
+                            slotBuffer->setGenerationNumber(generationNumber);
+                            outGeneration = generationNumber;
+                        } else {
+                            status = android::BAD_VALUE;
+                        }
+                    });
+            if (!transResult.isOk()) {
+                slotBuffer.clear();
+                return C2_BAD_VALUE;
+            } else if (status != android::NO_ERROR) {
+                slotBuffer.clear();
+                (void)mProducer->cancelBuffer(slot, hFenceWrapper.getHandle()).isOk();
+                return C2_BAD_VALUE;
+            }
+            if (mGeneration == 0) {
+                // getting generation # lazily due to dequeue failure.
+                mGeneration = outGeneration;
+            }
+        }
+        if (slotBuffer) {
+            ALOGV("buffer wraps %llu %d", (unsigned long long)mProducerId, slot);
+            C2Handle *c2Handle = android::WrapNativeCodec2GrallocHandle(
+                    slotBuffer->handle,
+                    slotBuffer->width,
+                    slotBuffer->height,
+                    slotBuffer->format,
+                    slotBuffer->usage,
+                    slotBuffer->stride,
+                    slotBuffer->getGenerationNumber(),
+                    mProducerId, slot);
+            if (c2Handle) {
+                std::shared_ptr<C2GraphicAllocation> alloc;
+                c2_status_t err = mAllocator->priorGraphicAllocation(c2Handle, &alloc);
+                if (err != C2_OK) {
+                    return err;
+                }
+                std::shared_ptr<C2BufferQueueBlockPoolData> poolData =
+                        std::make_shared<C2BufferQueueBlockPoolData>(
+                                slotBuffer->getGenerationNumber(),
+                                mProducerId, slot,
+                                shared_from_this());
+                mPoolDatas[slot] = poolData;
+                *block = _C2BlockFactory::CreateGraphicBlock(alloc, poolData);
+                return C2_OK;
+            }
+            // Block was not created. call requestBuffer# again next time.
+            slotBuffer.clear();
+            (void)mProducer->cancelBuffer(slot, hFenceWrapper.getHandle()).isOk();
+        }
+        return C2_BAD_VALUE;
+    }
+
+public:
+    Impl(const std::shared_ptr<C2Allocator> &allocator)
+        : mInit(C2_OK), mProducerId(0), mGeneration(0),
+          mDqFailure(0), mLastDqTs(0), mLastDqLogTs(0),
+          mAllocator(allocator) {
+    }
+
+    ~Impl() {
+        bool noInit = false;
+        for (int i = 0; i < NUM_BUFFER_SLOTS; ++i) {
+            if (!noInit && mProducer) {
+                Return<HStatus> transResult =
+                        mProducer->detachBuffer(static_cast<int32_t>(i));
+                noInit = !transResult.isOk() ||
+                         static_cast<HStatus>(transResult) == HStatus::NO_INIT;
+            }
+            mBuffers[i].clear();
+        }
+    }
+
+    c2_status_t fetchGraphicBlock(
+            uint32_t width,
+            uint32_t height,
+            uint32_t format,
+            C2MemoryUsage usage,
+            std::shared_ptr<C2GraphicBlock> *block /* nonnull */) {
+        block->reset();
+        if (mInit != C2_OK) {
+            return mInit;
+        }
+
+        static int kMaxIgbpRetryDelayUs = 10000;
+
+        std::unique_lock<std::mutex> lock(mMutex);
+        if (mLastDqLogTs == 0) {
+            mLastDqLogTs = getTimestampNow();
+        } else {
+            int64_t now = getTimestampNow();
+            if (now >= mLastDqLogTs + 5000000) {
+                if (now >= mLastDqTs + 1000000 || mDqFailure > 5) {
+                    ALOGW("last successful dequeue was %lld us ago, "
+                          "%zu consecutive failures",
+                          (long long)(now - mLastDqTs), mDqFailure);
+                }
+                mLastDqLogTs = now;
+            }
+        }
+        if (mProducerId == 0) {
+            std::shared_ptr<C2GraphicAllocation> alloc;
+            c2_status_t err = mAllocator->newGraphicAllocation(
+                    width, height, format, usage, &alloc);
+            if (err != C2_OK) {
+                return err;
+            }
+            std::shared_ptr<C2BufferQueueBlockPoolData> poolData =
+                    std::make_shared<C2BufferQueueBlockPoolData>(
+                            0, (uint64_t)0, ~0, shared_from_this());
+            *block = _C2BlockFactory::CreateGraphicBlock(alloc, poolData);
+            ALOGV("allocated a buffer successfully");
+
+            return C2_OK;
+        }
+        c2_status_t status = fetchFromIgbp_l(width, height, format, usage, block);
+        if (status == C2_BLOCKING) {
+            lock.unlock();
+            // in order not to drain cpu from component's spinning
+            ::usleep(kMaxIgbpRetryDelayUs);
+        }
+        return status;
+    }
+
+    void setRenderCallback(const OnRenderCallback &renderCallback) {
+        std::scoped_lock<std::mutex> lock(mMutex);
+        mRenderCallback = renderCallback;
+    }
+
+    void configureProducer(const sp<HGraphicBufferProducer> &producer) {
+        uint64_t producerId = 0;
+        uint32_t generation = 0;
+        bool haveGeneration = false;
+        if (producer) {
+            Return<uint64_t> transResult = producer->getUniqueId();
+            if (!transResult.isOk()) {
+                ALOGD("configureProducer -- failed to connect to the producer");
+                return;
+            }
+            producerId = static_cast<uint64_t>(transResult);
+            // TODO: provide gneration number from parameter.
+            haveGeneration = getGenerationNumber(producer, &generation);
+            if (!haveGeneration) {
+                ALOGW("get generationNumber failed %llu",
+                      (unsigned long long)producerId);
+            }
+        }
+        int migrated = 0;
+        {
+            sp<GraphicBuffer> buffers[NUM_BUFFER_SLOTS];
+            std::weak_ptr<C2BufferQueueBlockPoolData>
+                    poolDatas[NUM_BUFFER_SLOTS];
+            std::scoped_lock<std::mutex> lock(mMutex);
+            bool noInit = false;
+            for (int i = 0; i < NUM_BUFFER_SLOTS; ++i) {
+                if (!noInit && mProducer) {
+                    Return<HStatus> transResult =
+                            mProducer->detachBuffer(static_cast<int32_t>(i));
+                    noInit = !transResult.isOk() ||
+                             static_cast<HStatus>(transResult) == HStatus::NO_INIT;
+                }
+            }
+            int32_t oldGeneration = mGeneration;
+            if (producer) {
+                mProducer = producer;
+                mProducerId = producerId;
+                mGeneration = haveGeneration ? generation : 0;
+            } else {
+                mProducer = nullptr;
+                mProducerId = 0;
+                mGeneration = 0;
+                ALOGW("invalid producer producer(%d), generation(%d)",
+                      (bool)producer, haveGeneration);
+            }
+            if (mProducer && haveGeneration) { // migrate buffers
+                for (int i = 0; i < NUM_BUFFER_SLOTS; ++i) {
+                    std::shared_ptr<C2BufferQueueBlockPoolData> data =
+                            mPoolDatas[i].lock();
+                    if (data) {
+                        int slot = data->migrate(
+                                mProducer, generation,
+                                producerId, mBuffers, oldGeneration);
+                        if (slot >= 0) {
+                            buffers[slot] = mBuffers[i];
+                            poolDatas[slot] = data;
+                            ++migrated;
+                        }
+                    }
+                }
+            }
+            for (int i = 0; i < NUM_BUFFER_SLOTS; ++i) {
+                mBuffers[i] = buffers[i];
+                mPoolDatas[i] = poolDatas[i];
+            }
+        }
+        if (producer && haveGeneration) {
+            ALOGD("local generation change %u , "
+                  "bqId: %llu migrated buffers # %d",
+                  generation, (unsigned long long)producerId, migrated);
+        }
+    }
+
+private:
+    friend struct C2BufferQueueBlockPoolData;
+
+    void cancel(uint32_t generation, uint64_t igbp_id, int32_t igbp_slot) {
+        bool cancelled = false;
+        {
+        std::scoped_lock<std::mutex> lock(mMutex);
+        if (generation == mGeneration && igbp_id == mProducerId && mProducer) {
+            (void)mProducer->cancelBuffer(igbp_slot, hidl_handle{}).isOk();
+            cancelled = true;
+        }
+        }
+    }
+
+    c2_status_t mInit;
+    uint64_t mProducerId;
+    uint32_t mGeneration;
+    OnRenderCallback mRenderCallback;
+
+    size_t mDqFailure;
+    int64_t mLastDqTs;
+    int64_t mLastDqLogTs;
+
+    const std::shared_ptr<C2Allocator> mAllocator;
+
+    std::mutex mMutex;
+    sp<HGraphicBufferProducer> mProducer;
+    sp<HGraphicBufferProducer> mSavedProducer;
+
+    sp<GraphicBuffer> mBuffers[NUM_BUFFER_SLOTS];
+    std::weak_ptr<C2BufferQueueBlockPoolData> mPoolDatas[NUM_BUFFER_SLOTS];
+};
+
+C2BufferQueueBlockPoolData::C2BufferQueueBlockPoolData(
+        uint32_t generation, uint64_t bqId, int32_t bqSlot,
+        const std::shared_ptr<int>& owner,
+        const sp<HGraphicBufferProducer>& producer) :
+        held(producer && bqId != 0), local(false),
+        generation(generation), bqId(bqId), bqSlot(bqSlot),
+        transfer(false), attach(false), display(false),
+        owner(owner), igbp(producer),
+        localPool() {
+}
+
+C2BufferQueueBlockPoolData::C2BufferQueueBlockPoolData(
+        uint32_t generation, uint64_t bqId, int32_t bqSlot,
+        const std::shared_ptr<C2BufferQueueBlockPool::Impl>& pool) :
+        held(true), local(true),
+        generation(generation), bqId(bqId), bqSlot(bqSlot),
+        transfer(false), attach(false), display(false),
+        igbp(pool ? pool->mProducer : nullptr),
+        localPool(pool) {
+}
+
+C2BufferQueueBlockPoolData::~C2BufferQueueBlockPoolData() {
+    if (!held || bqId == 0) {
+        return;
+    }
+    if (local) {
+        if (localPool) {
+            localPool->cancel(generation, bqId, bqSlot);
+        }
+    } else if (igbp && !owner.expired()) {
+        igbp->cancelBuffer(bqSlot, hidl_handle{}).isOk();
+    }
+}
+int C2BufferQueueBlockPoolData::migrate(
+        const sp<HGraphicBufferProducer>& producer,
+        uint32_t toGeneration, uint64_t toBqId,
+        sp<GraphicBuffer> *buffers, uint32_t oldGeneration) {
+    std::scoped_lock<std::mutex> l(lock);
+    if (!held || bqId == 0) {
+        ALOGV("buffer is not owned");
+        return -1;
+    }
+    if (!local || !localPool) {
+        ALOGV("pool is not local");
+        return -1;
+    }
+    if (bqSlot < 0 || bqSlot >= NUM_BUFFER_SLOTS || !buffers[bqSlot]) {
+        ALOGV("slot is not in effect");
+        return -1;
+    }
+    if (toGeneration == generation && bqId == toBqId) {
+        ALOGV("cannot migrate to same bufferqueue");
+        return -1;
+    }
+    if (oldGeneration != generation) {
+        ALOGV("cannot migrate stale buffer");
+    }
+    if (transfer) {
+        // either transferred or detached.
+        ALOGV("buffer is in transfer");
+        return -1;
+    }
+    sp<GraphicBuffer> const& graphicBuffer = buffers[bqSlot];
+    graphicBuffer->setGenerationNumber(toGeneration);
+
+    HBuffer hBuffer{};
+    uint32_t hGenerationNumber{};
+    if (!b2h(graphicBuffer, &hBuffer, &hGenerationNumber)) {
+        ALOGD("I to O conversion failed");
+        return -1;
+    }
+
+    bool converted{};
+    status_t bStatus{};
+    int slot;
+    int *outSlot = &slot;
+    Return<void> transResult =
+            producer->attachBuffer(hBuffer, hGenerationNumber,
+                    [&converted, &bStatus, outSlot](
+                            HStatus hStatus, int32_t hSlot, bool releaseAll) {
+                        converted = h2b(hStatus, &bStatus);
+                        *outSlot = static_cast<int>(hSlot);
+                        if (converted && releaseAll && bStatus == android::OK) {
+                            bStatus = android::INVALID_OPERATION;
+                        }
+                    });
+    if (!transResult.isOk() || !converted || bStatus != android::OK) {
+        ALOGD("attach failed %d", static_cast<int>(bStatus));
+        return -1;
+    }
+    ALOGV("local migration from gen %u : %u slot %d : %d",
+          generation, toGeneration, bqSlot, slot);
+    generation = toGeneration;
+    bqId = toBqId;
+    bqSlot = slot;
+    return slot;
+}
+
+C2BufferQueueBlockPool::C2BufferQueueBlockPool(
+        const std::shared_ptr<C2Allocator> &allocator, const local_id_t localId)
+        : mAllocator(allocator), mLocalId(localId), mImpl(new Impl(allocator)) {}
+
+C2BufferQueueBlockPool::~C2BufferQueueBlockPool() {}
+
+c2_status_t C2BufferQueueBlockPool::fetchGraphicBlock(
+        uint32_t width,
+        uint32_t height,
+        uint32_t format,
+        C2MemoryUsage usage,
+        std::shared_ptr<C2GraphicBlock> *block /* nonnull */) {
+    if (mImpl) {
+        return mImpl->fetchGraphicBlock(width, height, format, usage, block);
+    }
+    return C2_CORRUPTED;
+}
+
+void C2BufferQueueBlockPool::configureProducer(const sp<HGraphicBufferProducer> &producer) {
+    if (mImpl) {
+        mImpl->configureProducer(producer);
+    }
+}
+
+void C2BufferQueueBlockPool::setRenderCallback(const OnRenderCallback &renderCallback) {
+    if (mImpl) {
+        mImpl->setRenderCallback(renderCallback);
+    }
+}
diff --git a/media/codec2/vndk/types.cpp b/media/codec2/vndk/types.cpp
new file mode 100644
index 0000000..99b1e9b
--- /dev/null
+++ b/media/codec2/vndk/types.cpp
@@ -0,0 +1,309 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cutils/native_handle.h>
+#include <ui/BufferQueueDefs.h>
+#include <types.h>
+#include <system/window.h>
+#include <vndk/hardware_buffer.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace bufferqueue {
+namespace V2_0 {
+namespace utils {
+
+// TODO: move this into ui/BufferQueueDefs.h so that we don't need
+// to include headers from libgui.
+enum {
+    // The API number used to indicate the currently connected producer
+    CURRENTLY_CONNECTED_API = -1,
+    // The API number used to indicate that no producer is connected
+    NO_CONNECTED_API        = 0,
+};
+
+// Status
+// ======
+
+bool b2h(status_t from, HStatus* to,
+         bool* bufferNeedsReallocation, bool* releaseAllBuffers) {
+    switch (from) {
+    case OK:
+        *to = HStatus::OK; break;
+    case NO_MEMORY:
+        *to = HStatus::NO_MEMORY; break;
+    case NO_INIT:
+        *to = HStatus::NO_INIT; break;
+    case BAD_VALUE:
+        *to = HStatus::BAD_VALUE; break;
+    case DEAD_OBJECT:
+        *to = HStatus::DEAD_OBJECT; break;
+    case INVALID_OPERATION:
+        *to = HStatus::INVALID_OPERATION; break;
+    case TIMED_OUT:
+        *to = HStatus::TIMED_OUT; break;
+    case WOULD_BLOCK:
+        *to = HStatus::WOULD_BLOCK; break;
+    case UNKNOWN_ERROR:
+        *to = HStatus::UNKNOWN_ERROR; break;
+    default:
+        status_t mask =
+                (bufferNeedsReallocation ? BufferQueueDefs::BUFFER_NEEDS_REALLOCATION : 0)
+                | (releaseAllBuffers ? BufferQueueDefs::RELEASE_ALL_BUFFERS : 0);
+        if (from & ~mask) {
+            *to = static_cast<HStatus>(from);
+        } else {
+            *to = HStatus::OK;
+            if (bufferNeedsReallocation) {
+                *bufferNeedsReallocation = from & BufferQueueDefs::BUFFER_NEEDS_REALLOCATION;
+            }
+            if (releaseAllBuffers) {
+                *releaseAllBuffers = from & BufferQueueDefs::RELEASE_ALL_BUFFERS;
+            }
+        }
+    }
+    return true;
+}
+
+bool h2b(HStatus from, status_t* to) {
+    switch (from) {
+    case HStatus::OK:
+        *to = OK; break;
+    case HStatus::NO_MEMORY:
+        *to = NO_MEMORY; break;
+    case HStatus::NO_INIT:
+        *to = NO_INIT; break;
+    case HStatus::BAD_VALUE:
+        *to = BAD_VALUE; break;
+    case HStatus::DEAD_OBJECT:
+        *to = DEAD_OBJECT; break;
+    case HStatus::INVALID_OPERATION:
+        *to = INVALID_OPERATION; break;
+    case HStatus::TIMED_OUT:
+        *to = TIMED_OUT; break;
+    case HStatus::WOULD_BLOCK:
+        *to = WOULD_BLOCK; break;
+    case HStatus::UNKNOWN_ERROR:
+        *to = UNKNOWN_ERROR; break;
+    default:
+        *to = static_cast<status_t>(from);
+    }
+    return true;
+}
+
+// Fence
+// =====
+
+HFenceWrapper::HFenceWrapper(native_handle_t* h) : mHandle{h} {
+}
+
+HFenceWrapper::~HFenceWrapper() {
+    native_handle_delete(mHandle);
+}
+
+HFenceWrapper& HFenceWrapper::set(native_handle_t* h) {
+    native_handle_delete(mHandle);
+    mHandle = h;
+    return *this;
+}
+
+HFenceWrapper& HFenceWrapper::operator=(native_handle_t* h) {
+    return set(h);
+}
+
+hidl_handle HFenceWrapper::getHandle() const {
+    return hidl_handle{mHandle};
+}
+
+HFenceWrapper::operator hidl_handle() const {
+    return getHandle();
+}
+
+bool b2h(sp<BFence> const& from, HFenceWrapper* to) {
+    if (!from) {
+        to->set(nullptr);
+        return true;
+    }
+    int fenceFd = from->get();
+    if (fenceFd == -1) {
+        to->set(nullptr);
+        return true;
+    }
+    native_handle_t* nh = native_handle_create(1, 0);
+    if (!nh) {
+        return false;
+    }
+    nh->data[0] = fenceFd;
+    to->set(nh);
+    return true;
+}
+
+bool h2b(native_handle_t const* from, sp<BFence>* to) {
+    if (!from || from->numFds == 0) {
+        *to = new ::android::Fence();
+        return true;
+    }
+    if (from->numFds != 1 || from->numInts != 0) {
+        return false;
+    }
+    *to = new BFence(dup(from->data[0]));
+    return true;
+}
+
+// ConnectionType
+// ==============
+
+bool b2h(int from, HConnectionType* to) {
+    *to = static_cast<HConnectionType>(from);
+    switch (from) {
+    case CURRENTLY_CONNECTED_API:
+        *to = HConnectionType::CURRENTLY_CONNECTED; break;
+    case NATIVE_WINDOW_API_EGL:
+        *to = HConnectionType::EGL; break;
+    case NATIVE_WINDOW_API_CPU:
+        *to = HConnectionType::CPU; break;
+    case NATIVE_WINDOW_API_MEDIA:
+        *to = HConnectionType::MEDIA; break;
+    case NATIVE_WINDOW_API_CAMERA:
+        *to = HConnectionType::CAMERA; break;
+    }
+    return true;
+}
+
+bool h2b(HConnectionType from, int* to) {
+    *to = static_cast<int>(from);
+    switch (from) {
+    case HConnectionType::CURRENTLY_CONNECTED:
+        *to = CURRENTLY_CONNECTED_API; break;
+    case HConnectionType::EGL:
+        *to = NATIVE_WINDOW_API_EGL; break;
+    case HConnectionType::CPU:
+        *to = NATIVE_WINDOW_API_CPU; break;
+    case HConnectionType::MEDIA:
+        *to = NATIVE_WINDOW_API_MEDIA; break;
+    case HConnectionType::CAMERA:
+        *to = NATIVE_WINDOW_API_CAMERA; break;
+    }
+    return true;
+}
+
+// Rect
+// ====
+
+bool b2h(BRect const& from, HRect* to) {
+    BRect* dst = reinterpret_cast<BRect*>(to->data());
+    dst->left = from.left;
+    dst->top = from.top;
+    dst->right = from.right;
+    dst->bottom = from.bottom;
+    return true;
+}
+
+bool h2b(HRect const& from, BRect* to) {
+    BRect const* src = reinterpret_cast<BRect const*>(from.data());
+    to->left = src->left;
+    to->top = src->top;
+    to->right = src->right;
+    to->bottom = src->bottom;
+    return true;
+}
+
+// Region
+// ======
+
+bool b2h(BRegion const& from, HRegion* to) {
+    size_t numRects;
+    BRect const* rectArray = from.getArray(&numRects);
+    to->resize(numRects);
+    for (size_t i = 0; i < numRects; ++i) {
+        if (!b2h(rectArray[i], &(*to)[i])) {
+            return false;
+        }
+    }
+    return true;
+}
+
+bool h2b(HRegion const& from, BRegion* to) {
+    if (from.size() > 0) {
+        BRect bRect;
+        if (!h2b(from[0], &bRect)) {
+            return false;
+        }
+        to->set(bRect);
+        for (size_t i = 1; i < from.size(); ++i) {
+            if (!h2b(from[i], &bRect)) {
+                return false;
+            }
+            to->addRectUnchecked(
+                    static_cast<int>(bRect.left),
+                    static_cast<int>(bRect.top),
+                    static_cast<int>(bRect.right),
+                    static_cast<int>(bRect.bottom));
+        }
+    } else {
+        to->clear();
+    }
+    return true;
+}
+
+// GraphicBuffer
+// =============
+
+// The handle is not cloned. Its lifetime is tied to the original GraphicBuffer.
+bool b2h(sp<GraphicBuffer> const& from, HardwareBuffer* to,
+         uint32_t* toGenerationNumber) {
+    if (!from) {
+        return false;
+    }
+    AHardwareBuffer* hwBuffer = from->toAHardwareBuffer();
+    to->nativeHandle.setTo(
+          const_cast<native_handle_t*>(
+              AHardwareBuffer_getNativeHandle(hwBuffer)),
+          false);
+    AHardwareBuffer_describe(
+            hwBuffer,
+            reinterpret_cast<AHardwareBuffer_Desc*>(to->description.data()));
+    if (toGenerationNumber) {
+        *toGenerationNumber = from->getGenerationNumber();
+    }
+    return true;
+}
+
+// The handle is cloned.
+bool h2b(HardwareBuffer const& from, sp<GraphicBuffer>* to) {
+    AHardwareBuffer_Desc const* desc =
+            reinterpret_cast<AHardwareBuffer_Desc const*>(
+            from.description.data());
+    native_handle_t const* handle = from.nativeHandle;
+    AHardwareBuffer* hwBuffer;
+    if (AHardwareBuffer_createFromHandle(
+            desc, handle, AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_CLONE,
+            &hwBuffer) != OK) {
+        return false;
+    }
+    *to = GraphicBuffer::fromAHardwareBuffer(hwBuffer);
+    AHardwareBuffer_release(hwBuffer);
+    return true;
+}
+
+}  // namespace utils
+}  // namespace V2_0
+}  // namespace bufferqueue
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
+
diff --git a/media/codec2/vndk/util/C2Debug.cpp b/media/codec2/vndk/util/C2Debug.cpp
new file mode 100644
index 0000000..b4aa719
--- /dev/null
+++ b/media/codec2/vndk/util/C2Debug.cpp
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <C2ParamInternal.h>
+#include <util/C2Debug-interface.h>
+#include <util/C2Debug-param.h>
+#include <util/C2InterfaceUtils.h>
+
+#include <iostream>
+
+#include <android-base/stringprintf.h>
+
+using android::base::StringPrintf;
+
+/* -------------------------------- asString -------------------------------- */
+
+const char *asString(c2_status_t i, const char *def) {
+    switch (i) {
+        case C2_OK:        return "OK";
+        case C2_BAD_VALUE: return "BAD_VALUE";
+        case C2_BAD_INDEX: return "BAD_INDEX";
+        case C2_CANNOT_DO: return "CANNOT_DO";
+        case C2_DUPLICATE: return "DUPLICATE";
+        case C2_NOT_FOUND: return "NOT_FOUND";
+        case C2_BAD_STATE: return "BAD_STATE";
+        case C2_BLOCKING:  return "BLOCKING";
+        case C2_CANCELED:  return "CANCELED";
+        case C2_NO_MEMORY: return "NO_MEMORY";
+        case C2_REFUSED:   return "REFUSED";
+        case C2_TIMED_OUT: return "TIMED_OUT";
+        case C2_OMITTED:   return "OMITTED";
+        case C2_CORRUPTED: return "CORRUPTED";
+        case C2_NO_INIT:   return "NO_INIT";
+        default:           return def;
+    }
+}
+
+const char *asString(C2FieldDescriptor::type_t i, const char *def) {
+    switch (i) {
+        case C2FieldDescriptor::BLOB:   return "u8";
+        case C2FieldDescriptor::CNTR32: return "c32";
+        case C2FieldDescriptor::CNTR64: return "c64";
+        case C2FieldDescriptor::FLOAT:  return "fp";
+        case C2FieldDescriptor::INT32:  return "i32";
+        case C2FieldDescriptor::INT64:  return "i64";
+        case C2FieldDescriptor::STRING: return "chr";
+        case C2FieldDescriptor::UINT32: return "u32";
+        case C2FieldDescriptor::UINT64: return "u64";
+        default: return (i & C2FieldDescriptor::STRUCT_FLAG) ? "struct" : def;
+    }
+}
+
+/* ------------------------------ C2ParamField ------------------------------ */
+
+static std::string attribParamCoreIndex(const C2Param::CoreIndex &i) {
+    return StringPrintf("%c%c%03x",
+            i.isFlexible() ? 'F' : '-',
+            i.isVendor() ? 'V' : '-',
+            i.coreIndex());
+}
+
+static std::string attribParamIndex(
+        const C2Param::Type &i, bool addStream, unsigned streamId) {
+    std::string v = StringPrintf("%c%c",
+            i.forInput() ? 'I' : i.forOutput() ? 'O' : '-',
+            i.forStream() ? 'S' : i.forPort() ? 'P' : 'G');
+    if (addStream) {
+        if (i.forStream()) {
+            v += StringPrintf("%02d", streamId);
+        } else {
+            v += "--";
+        }
+    }
+
+    return v
+            + StringPrintf("%c ",
+                       i.kind() == C2Param::STRUCT  ? 'S' :
+                       i.kind() == C2Param::INFO    ? 'i' :
+                       i.kind() == C2Param::TUNING  ? 't' :
+                       i.kind() == C2Param::SETTING ? 's' :
+                       i.kind() == C2Param::NONE    ? '-' : '?')
+            + attribParamCoreIndex(i);
+}
+
+std::ostream& operator<<(std::ostream& os, const C2Param::CoreIndex &i) {
+    return os << "Param::CoreIndex(" << attribParamCoreIndex(i) << ")";
+}
+
+std::ostream& operator<<(std::ostream& os, const C2Param::Type &i) {
+    return os << StringPrintf("Param::Type(%08x: ", i.type())
+            << attribParamIndex(i, false, 0) << ")";
+}
+
+std::ostream& operator<<(std::ostream& os, const C2Param::Index &i) {
+    return os << StringPrintf("Param::Index(%08x: ", (uint32_t)i)
+            << attribParamIndex(i, true, i.stream()) << ")";
+}
+
+static std::string attribFieldId(const _C2FieldId &i) {
+    return StringPrintf("Field(@%02x+%02x)",
+            _C2ParamInspector::GetOffset(i),
+            _C2ParamInspector::GetSize(i));
+}
+
+
+std::ostream& operator<<(std::ostream& os, const _C2FieldId &i) {
+    return os << "<" << attribFieldId(i) << ">";
+}
+
+
+std::ostream& operator<<(std::ostream& os, const C2FieldDescriptor &i) {
+    os << attribFieldId(_C2ParamInspector::GetField(i)) << " ";
+    if (i.namedValues().size()) {
+        os << "enum ";
+    }
+    return os << asString(i.type()) << " " << i.name()
+            << StringPrintf("[%zu]", i.extent());
+}
+
+
+std::ostream& operator<<(std::ostream& os, const C2ParamField &i) {
+    os << "<" << C2Param::Index(_C2ParamInspector::GetIndex(i))
+            << StringPrintf("::Field(@%02x+%02x)>",
+                            _C2ParamInspector::GetOffset(i),
+                            _C2ParamInspector::GetSize(i));
+    return os;
+}
+
+
+/* -------------------------- _C2FieldValueHelper -------------------------- */
+
+std::ostream& _C2FieldValueHelper<char>::put(std::ostream &os, const C2Value::Primitive &p) {
+    if (isprint(p.i32)) {
+        return os << StringPrintf("'%c'", p.i32);
+    } else {
+        return os << StringPrintf("'\\x%02x'", (uint32_t)p.i32);
+    }
+}
+
+std::ostream& _C2FieldValueHelper<uint8_t>::put(std::ostream &os, const C2Value::Primitive &p) {
+    return os << StringPrintf("0x%02x", p.u32);
+}
+
+/* ---------------------- C2FieldSupportedValuesHelper ---------------------- */
+
+template<typename T>
+std::ostream& operator<<(std::ostream &os, const c2_cntr_t<T> &v) {
+    return os << "ctr(" << v.peeku() << ")";
+}
+
+template<typename T>
+std::ostream& operator<<(std::ostream& os, const C2SupportedRange<T> &i) {
+    os << "Range(";
+    _C2FieldValueHelper<T>::put(os, i.min());
+    os << "..";
+    _C2FieldValueHelper<T>::put(os, i.max());
+    os << " *= " << i.num() << " /= " << i.denom() << " += " << i.step() << ")";
+    return os;
+}
+template std::ostream& operator<<(std::ostream& os, const C2SupportedRange<char> &i);
+template std::ostream& operator<<(std::ostream& os, const C2SupportedRange<uint8_t> &i);
+template std::ostream& operator<<(std::ostream& os, const C2SupportedRange<int32_t> &i);
+template std::ostream& operator<<(std::ostream& os, const C2SupportedRange<uint32_t> &i);
+//template std::ostream& operator<<(std::ostream& os, const C2SupportedRange<c2_cntr32_t> &i);
+template std::ostream& operator<<(std::ostream& os, const C2SupportedRange<int64_t> &i);
+template std::ostream& operator<<(std::ostream& os, const C2SupportedRange<uint64_t> &i);
+//template std::ostream& operator<<(std::ostream& os, const C2SupportedRange<c2_cntr64_t> &i);
+template std::ostream& operator<<(std::ostream& os, const C2SupportedRange<float> &i);
+
+template<typename T>
+std::ostream& operator<<(std::ostream& os, const C2SupportedFlags<T> &i) {
+    os << "Flags[";
+    if (!i.isEmpty()) {
+        os << "min=";
+        _C2FieldValueHelper<T>::put(os, i.min());
+    }
+    bool comma = false;
+    for (const T &v : i.flags()) {
+        if (comma) {
+            os << ", ";
+        }
+        _C2FieldValueHelper<T>::put(os, v);
+        comma = true;
+    }
+    os << "]";
+    return os;
+}
+template std::ostream& operator<<(std::ostream& os, const C2SupportedFlags<char> &i);
+template std::ostream& operator<<(std::ostream& os, const C2SupportedFlags<uint8_t> &i);
+template std::ostream& operator<<(std::ostream& os, const C2SupportedFlags<int32_t> &i);
+template std::ostream& operator<<(std::ostream& os, const C2SupportedFlags<uint32_t> &i);
+//template std::ostream& operator<<(std::ostream& os, const C2SupportedFlags<c2_cntr32_t> &i);
+template std::ostream& operator<<(std::ostream& os, const C2SupportedFlags<int64_t> &i);
+template std::ostream& operator<<(std::ostream& os, const C2SupportedFlags<uint64_t> &i);
+//template std::ostream& operator<<(std::ostream& os, const C2SupportedFlags<c2_cntr64_t> &i);
+template std::ostream& operator<<(std::ostream& os, const C2SupportedFlags<float> &i);
+
+template<typename T>
+std::ostream& operator<<(std::ostream& os, const C2SupportedValueSet<T> &i) {
+    os << "Values[";
+    bool comma = false;
+    for (const T &v : i.values()) {
+        if (comma) {
+            os << ", ";
+        }
+        _C2FieldValueHelper<T>::put(os, v);
+        comma = true;
+    }
+    os << "]";
+    return os;
+}
+template std::ostream& operator<<(std::ostream& os, const C2SupportedValueSet<char> &i);
+template std::ostream& operator<<(std::ostream& os, const C2SupportedValueSet<uint8_t> &i);
+template std::ostream& operator<<(std::ostream& os, const C2SupportedValueSet<int32_t> &i);
+template std::ostream& operator<<(std::ostream& os, const C2SupportedValueSet<uint32_t> &i);
+//template std::ostream& operator<<(std::ostream& os, const C2SupportedValueSet<c2_cntr32_t> &i);
+template std::ostream& operator<<(std::ostream& os, const C2SupportedValueSet<int64_t> &i);
+template std::ostream& operator<<(std::ostream& os, const C2SupportedValueSet<uint64_t> &i);
+//template std::ostream& operator<<(std::ostream& os, const C2SupportedValueSet<c2_cntr64_t> &i);
+template std::ostream& operator<<(std::ostream& os, const C2SupportedValueSet<float> &i);
+
+template<typename T>
+struct C2FieldSupportedValuesHelper<T>::Impl {
+    Impl(const C2FieldSupportedValues &values);
+
+private:
+    typedef typename _C2FieldValueHelper<T>::ValueType ValueType;
+    C2FieldSupportedValues::type_t _mType;
+    C2SupportedRange<ValueType> _mRange;
+    C2SupportedValueSet<ValueType> _mValues;
+    C2SupportedFlags<ValueType> _mFlags;
+
+public:
+//    friend std::ostream& operator<< <T>(std::ostream& os, const C2FieldSupportedValuesHelper<T>::Impl &i);
+//    friend std::ostream& operator<<(std::ostream& os, const Impl &i);
+    std::ostream& streamOut(std::ostream& os) const;
+};
+
+template<typename T>
+std::ostream& C2FieldSupportedValuesHelper<T>::Impl::streamOut(std::ostream& os) const {
+    if (_mType == C2FieldSupportedValues::RANGE) {
+        os << _mRange;
+    } else if (_mType == C2FieldSupportedValues::VALUES) {
+        os << _mValues;
+    } else if (_mType == C2FieldSupportedValues::FLAGS) {
+        os << _mFlags;
+    } else {
+        os << "Unknown FSV type: " << (uint32_t)_mType;
+    }
+    return os;
+}
+
+template<typename T>
+std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<T> &i) {
+    return i._mImpl->streamOut(os);
+}
+template std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<char> &i);
+template std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<uint8_t> &i);
+template std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<int32_t> &i);
+template std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<uint32_t> &i);
+//template std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<c2_cntr32_t> &i);
+template std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<int64_t> &i);
+template std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<uint64_t> &i);
+//template std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<c2_cntr64_t> &i);
+template std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<float> &i);
+
diff --git a/media/codec2/vndk/util/C2InterfaceHelper.cpp b/media/codec2/vndk/util/C2InterfaceHelper.cpp
new file mode 100644
index 0000000..9eb52d2
--- /dev/null
+++ b/media/codec2/vndk/util/C2InterfaceHelper.cpp
@@ -0,0 +1,876 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <C2Debug.h>
+#include <C2ParamInternal.h>
+#include <util/C2InterfaceHelper.h>
+
+#include <android-base/stringprintf.h>
+
+using ::android::base::StringPrintf;
+
+/* --------------------------------- ReflectorHelper --------------------------------- */
+
+void C2ReflectorHelper::addStructDescriptors(
+        std::vector<C2StructDescriptor> &structs, _Tuple<> *) {
+    std::lock_guard<std::mutex> lock(_mMutex);
+    for (C2StructDescriptor &strukt : structs) {
+        // TODO: check if structure descriptions conflict with existing ones
+        addStructDescriptor(std::move(strukt));
+    }
+}
+
+std::unique_ptr<C2StructDescriptor>
+C2ReflectorHelper::describe(C2Param::CoreIndex paramIndex) const {
+    std::lock_guard<std::mutex> lock(_mMutex);
+    auto it = _mStructs.find(paramIndex);
+    if (it == _mStructs.end()) {
+        return nullptr;
+    } else {
+        return std::make_unique<C2StructDescriptor>(it->second);
+    }
+};
+
+void C2ReflectorHelper::addStructDescriptor(C2StructDescriptor &&strukt) {
+    if (_mStructs.find(strukt.coreIndex()) != _mStructs.end()) {
+        // already added
+        // TODO: validate that descriptor matches stored descriptor
+    }
+    // validate that all struct fields are known to this reflector
+    for (const C2FieldDescriptor &fd : strukt) {
+        if (fd.type() & C2FieldDescriptor::STRUCT_FLAG) {
+            C2Param::CoreIndex coreIndex = fd.type() &~ C2FieldDescriptor::STRUCT_FLAG;
+            if (_mStructs.find(coreIndex) == _mStructs.end()) {
+                C2_LOG(INFO) << "missing struct descriptor #" << coreIndex << " for field "
+                        << fd.name() << " of struct #" << strukt.coreIndex();
+            }
+        }
+    }
+    _mStructs.emplace(strukt.coreIndex(), strukt);
+}
+
+
+/* ---------------------------- ParamHelper ---------------------------- */
+
+class C2InterfaceHelper::ParamHelper::Impl {
+public:
+    Impl(ParamRef param, C2StringLiteral name, C2StructDescriptor &&strukt)
+        : mParam(param), mName(name), _mStruct(strukt) { }
+
+    Impl(Impl&&) = default;
+
+    void addDownDependency(C2Param::Index index) {
+        mDownDependencies.push_back(index);
+    }
+
+    C2InterfaceHelper::ParamHelper::attrib_t& attrib() {
+        return mAttrib;
+    }
+
+    void build() {
+        // move dependencies into descriptor
+        mDescriptor = std::make_shared<C2ParamDescriptor>(
+                index(), (C2ParamDescriptor::attrib_t)mAttrib,
+                std::move(mName), std::move(mDependencies));
+    }
+
+    void createFieldsAndSupportedValues(const std::shared_ptr<C2ParamReflector> &reflector) {
+        for (const C2FieldUtils::Info &f :
+                C2FieldUtils::enumerateFields(*mDefaultValue, reflector)) {
+            if (!f.isArithmetic()) {
+                continue;
+            }
+            std::unique_ptr<C2FieldSupportedValues> fsvPointer;
+
+            // create a breakable structure
+            do {
+                C2FieldSupportedValues fsv;
+                switch (f.type()) {
+                    case C2FieldDescriptor::INT32:  fsv = C2SupportedRange<int32_t>::Any(); break;
+                    case C2FieldDescriptor::UINT32: fsv = C2SupportedRange<uint32_t>::Any(); break;
+                    case C2FieldDescriptor::INT64:  fsv = C2SupportedRange<int64_t>::Any(); break;
+                    case C2FieldDescriptor::UINT64: fsv = C2SupportedRange<uint64_t>::Any(); break;
+                    case C2FieldDescriptor::FLOAT:  fsv = C2SupportedRange<float>::Any(); break;
+                    case C2FieldDescriptor::BLOB:   fsv = C2SupportedRange<uint8_t>::Any(); break;
+                    case C2FieldDescriptor::STRING: fsv = C2SupportedRange<char>::Any(); break;
+                default:
+                    continue; // break out of do {} while
+                }
+                fsvPointer = std::make_unique<C2FieldSupportedValues>(fsv);
+            } while (false);
+
+            mFields.emplace_hint(
+                    mFields.end(),
+                    _C2FieldId(f.offset(), f.size()),
+                    std::make_shared<FieldHelper>(
+                            mParam, _C2FieldId(f.offset(), f.size()), std::move(fsvPointer)));
+        }
+    }
+
+    /**
+     * Finds a field descriptor.
+     */
+    std::shared_ptr<FieldHelper> findField(size_t baseOffs, size_t baseSize) const {
+        auto it = mFields.find(_C2FieldId(baseOffs, baseSize));
+        if (it == mFields.end()) {
+            return nullptr;
+        }
+        return it->second;
+    }
+
+    const std::vector<ParamRef> getDependenciesAsRefs() const {
+        return mDependenciesAsRefs;
+    }
+
+    std::shared_ptr<const C2ParamDescriptor> getDescriptor() const {
+        return mDescriptor;
+    }
+
+    const std::vector<C2Param::Index> getDownDependencies() const {
+        return mDownDependencies;
+    }
+
+    C2Param::Index index() const {
+        if (!mDefaultValue) {
+            fprintf(stderr, "%s missing default value\n", mName.c_str());
+        }
+        return mDefaultValue->index();
+    }
+
+    C2String name() const {
+        return mName;
+    }
+
+    const ParamRef ref() const {
+        return mParam;
+    }
+
+    C2StructDescriptor retrieveStructDescriptor() {
+        return std::move(_mStruct);
+    }
+
+    void setDefaultValue(std::shared_ptr<C2Param> default_) {
+        mDefaultValue = default_;
+    }
+
+    void setDependencies(std::vector<C2Param::Index> indices, std::vector<ParamRef> refs) {
+        mDependencies = indices;
+        mDependenciesAsRefs = refs;
+    }
+
+    void setFields(std::vector<C2ParamFieldValues> &&fields) {
+        // do not allow adding fields multiple times, or to const values
+        if (!mFields.empty()) {
+            C2_LOG(FATAL) << "Trying to add fields to param " << mName << " multiple times";
+        } else if (mAttrib & attrib_t::IS_CONST) {
+            C2_LOG(FATAL) << "Trying to add fields to const param " << mName;
+        }
+
+        for (C2ParamFieldValues &pfv : fields) {
+            mFields.emplace_hint(
+                    mFields.end(),
+                    // _C2FieldId constructor
+                    _C2ParamInspector::GetField(pfv.paramOrField),
+                    // Field constructor
+                    std::make_shared<FieldHelper>(mParam,
+                                            _C2ParamInspector::GetField(pfv.paramOrField),
+                                            std::move(pfv.values)));
+        }
+    }
+
+    void setGetter(std::function<std::shared_ptr<C2Param>(bool)> getter) {
+        mGetter = getter;
+    }
+
+    void setSetter(std::function<C2R(const C2Param *, bool, bool *, Factory &)> setter) {
+        mSetter = setter;
+    }
+
+    c2_status_t trySet(
+            const C2Param *value, bool mayBlock, bool *changed, Factory &f,
+            std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
+        C2R result = mSetter(value, mayBlock, changed, f);
+        return result.retrieveFailures(failures);
+    }
+
+    c2_status_t validate(const std::shared_ptr<C2ParamReflector> &reflector) {
+        if (!mSetter && mFields.empty()) {
+            C2_LOG(WARNING) << "Param " << mName << " has no setter, making it const";
+            // dependencies are empty in this case
+            mAttrib |= attrib_t::IS_CONST;
+        } else if (!mSetter) {
+            C2_LOG(FATAL) << "Param " << mName << " has no setter";
+        }
+
+        if (mAttrib & attrib_t::IS_CONST) {
+            createFieldsAndSupportedValues(reflector);
+        } else {
+            // TODO: update default based on setter and verify that FSV covers the values
+        }
+
+        if (mFields.empty()) {
+            C2_LOG(FATAL) << "Param " << mName << " has no fields";
+        }
+
+        return C2_OK;
+    }
+
+    std::shared_ptr<C2Param> value() {
+        return mParam.get();
+    }
+
+    std::shared_ptr<const C2Param> value() const {
+        return mParam.get();
+    }
+
+private:
+    typedef _C2ParamInspector::attrib_t attrib_t;
+    ParamRef mParam;
+    C2String mName;
+    C2StructDescriptor _mStruct;
+    std::shared_ptr<C2Param> mDefaultValue;
+    attrib_t mAttrib;
+    std::function<C2R(const C2Param *, bool, bool *, Factory &)> mSetter;
+    std::function<std::shared_ptr<C2Param>(bool)> mGetter;
+    std::vector<C2Param::Index> mDependencies;
+    std::vector<ParamRef> mDependenciesAsRefs;
+    std::vector<C2Param::Index> mDownDependencies; // TODO: this does not work for stream dependencies
+    std::map<_C2FieldId, std::shared_ptr<FieldHelper>> mFields;
+    std::shared_ptr<C2ParamDescriptor> mDescriptor;
+};
+
+C2InterfaceHelper::ParamHelper::ParamHelper(
+        ParamRef param, C2StringLiteral name, C2StructDescriptor &&strukt)
+    : mImpl(std::make_unique<C2InterfaceHelper::ParamHelper::Impl>(
+            param, name, std::move(strukt))) { }
+
+C2InterfaceHelper::ParamHelper::ParamHelper(C2InterfaceHelper::ParamHelper &&) = default;
+
+C2InterfaceHelper::ParamHelper::~ParamHelper() = default;
+
+void C2InterfaceHelper::ParamHelper::addDownDependency(C2Param::Index index) {
+    return mImpl->addDownDependency(index);
+}
+
+C2InterfaceHelper::ParamHelper::attrib_t& C2InterfaceHelper::ParamHelper::attrib() {
+    return mImpl->attrib();
+}
+
+std::shared_ptr<C2InterfaceHelper::ParamHelper> C2InterfaceHelper::ParamHelper::build() {
+    mImpl->build();
+    return std::make_shared<C2InterfaceHelper::ParamHelper>(std::move(*this));
+}
+
+std::shared_ptr<C2InterfaceHelper::FieldHelper>
+C2InterfaceHelper::ParamHelper::findField(size_t baseOffs, size_t baseSize) const {
+    return mImpl->findField(baseOffs, baseSize);
+}
+
+const std::vector<C2InterfaceHelper::ParamRef>
+C2InterfaceHelper::ParamHelper::getDependenciesAsRefs() const {
+    return mImpl->getDependenciesAsRefs();
+}
+
+std::shared_ptr<const C2ParamDescriptor>
+C2InterfaceHelper::ParamHelper::getDescriptor() const {
+    return mImpl->getDescriptor();
+}
+
+const std::vector<C2Param::Index> C2InterfaceHelper::ParamHelper::getDownDependencies() const {
+    return mImpl->getDownDependencies();
+}
+
+C2Param::Index C2InterfaceHelper::ParamHelper::index() const {
+    return mImpl->index();
+}
+
+C2String C2InterfaceHelper::ParamHelper::name() const {
+    return mImpl->name();
+}
+
+const C2InterfaceHelper::ParamRef C2InterfaceHelper::ParamHelper::ref() const {
+    return mImpl->ref();
+}
+
+C2StructDescriptor C2InterfaceHelper::ParamHelper::retrieveStructDescriptor() {
+    return mImpl->retrieveStructDescriptor();
+}
+
+void C2InterfaceHelper::ParamHelper::setDefaultValue(std::shared_ptr<C2Param> default_) {
+    mImpl->setDefaultValue(default_);
+}
+
+void C2InterfaceHelper::ParamHelper::setDependencies(
+        std::vector<C2Param::Index> indices, std::vector<ParamRef> refs) {
+    mImpl->setDependencies(indices, refs);
+}
+
+void C2InterfaceHelper::ParamHelper::setFields(std::vector<C2ParamFieldValues> &&fields) {
+    return mImpl->setFields(std::move(fields));
+}
+
+void C2InterfaceHelper::ParamHelper::setGetter(
+        std::function<std::shared_ptr<C2Param>(bool)> getter) {
+    mImpl->setGetter(getter);
+}
+
+void C2InterfaceHelper::ParamHelper::setSetter(
+        std::function<C2R(const C2Param *, bool, bool *, Factory &)> setter) {
+    mImpl->setSetter(setter);
+}
+
+c2_status_t C2InterfaceHelper::ParamHelper::trySet(
+        const C2Param *value, bool mayBlock, bool *changed, Factory &f,
+        std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
+    return mImpl->trySet(value, mayBlock, changed, f, failures);
+}
+
+c2_status_t C2InterfaceHelper::ParamHelper::validate(
+        const std::shared_ptr<C2ParamReflector> &reflector) {
+    return mImpl->validate(reflector);
+}
+
+std::shared_ptr<C2Param> C2InterfaceHelper::ParamHelper::value() {
+    return mImpl->value();
+}
+
+std::shared_ptr<const C2Param> C2InterfaceHelper::ParamHelper::value() const {
+    return mImpl->value();
+}
+
+/* ---------------------------- FieldHelper ---------------------------- */
+
+C2ParamField C2InterfaceHelper::FieldHelper::makeParamField(C2Param::Index index) const {
+    return _C2ParamInspector::CreateParamField(index, mFieldId);
+}
+
+C2InterfaceHelper::FieldHelper::FieldHelper(const ParamRef &param, const _C2FieldId &field,
+            std::unique_ptr<C2FieldSupportedValues> &&values)
+    : mParam(param),
+      mFieldId(field),
+      mPossible(std::move(values)) {
+    C2_LOG(VERBOSE) << "Creating field helper " << field << " "
+            << C2FieldSupportedValuesHelper<uint32_t>(*mPossible);
+}
+
+void C2InterfaceHelper::FieldHelper::setSupportedValues(
+        std::unique_ptr<C2FieldSupportedValues> &&values) {
+    mSupported = std::move(values);
+}
+
+const C2FieldSupportedValues *C2InterfaceHelper::FieldHelper::getSupportedValues() const {
+    return (mSupported ? mSupported : mPossible).get();
+}
+
+const C2FieldSupportedValues *C2InterfaceHelper::FieldHelper::getPossibleValues() const {
+    return mPossible.get();
+}
+
+
+/* ---------------------------- Field ---------------------------- */
+
+/**
+ * Wrapper around field-supported-values builder that gets stored in the
+ * field helper when the builder goes out of scope.
+ */
+template<typename T>
+struct SupportedValuesBuilder : C2ParamFieldValuesBuilder<T> {
+    SupportedValuesBuilder(
+            C2ParamField &field, std::shared_ptr<C2InterfaceHelper::FieldHelper> helper)
+        : C2ParamFieldValuesBuilder<T>(field), _mHelper(helper), _mField(field) {
+    }
+
+    /**
+     * Save builder values on destruction.
+     */
+    virtual ~SupportedValuesBuilder() override {
+        _mHelper->setSupportedValues(std::move(C2ParamFieldValues(*this).values));
+    }
+
+private:
+    std::shared_ptr<C2InterfaceHelper::FieldHelper> _mHelper;
+    C2ParamField _mField;
+};
+
+
+template<typename T>
+C2ParamFieldValuesBuilder<T> C2InterfaceHelper::Field<T>::shouldBe() const {
+    return C2ParamFieldValuesBuilder<T>(_mField);
+}
+
+template<typename T>
+C2ParamFieldValuesBuilder<T> C2InterfaceHelper::Field<T>::mustBe() {
+    return SupportedValuesBuilder<T>(_mField, _mHelper);
+}
+
+/*
+template<typename T> C2SettingResultsBuilder C2InterfaceHelper::Field<T>::validatePossible(T &value)
+const {
+    /// TODO
+    return C2SettingResultsBuilder::Ok();
+}
+*/
+
+template<typename T>
+C2InterfaceHelper::Field<T>::Field(std::shared_ptr<FieldHelper> helper, C2Param::Index index)
+    : _mHelper(helper), _mField(helper->makeParamField(index)) { }
+
+template struct C2InterfaceHelper::Field<uint8_t>;
+template struct C2InterfaceHelper::Field<char>;
+template struct C2InterfaceHelper::Field<int32_t>;
+template struct C2InterfaceHelper::Field<uint32_t>;
+//template struct C2InterfaceHelper::Field<c2_cntr32_t>;
+template struct C2InterfaceHelper::Field<int64_t>;
+template struct C2InterfaceHelper::Field<uint64_t>;
+//template struct C2InterfaceHelper::Field<c2_cntr64_t>;
+template struct C2InterfaceHelper::Field<float>;
+
+/* --------------------------------- Factory --------------------------------- */
+
+struct C2InterfaceHelper::FactoryImpl : public C2InterfaceHelper::Factory {
+    virtual std::shared_ptr<C2ParamReflector> getReflector() const override {
+        return _mReflector;
+    }
+
+    virtual std::shared_ptr<ParamHelper>
+    getParamHelper(const ParamRef &param) const override {
+        return _mParams.find(param)->second;
+    }
+
+public:
+    FactoryImpl(std::shared_ptr<C2ParamReflector> reflector)
+        : _mReflector(reflector) { }
+
+    virtual ~FactoryImpl() = default;
+
+    void addParam(std::shared_ptr<ParamHelper> param) {
+        _mParams.insert({ param->ref(), param });
+        _mIndexToHelper.insert({param->index(), param});
+
+        // add down-dependencies (and validate dependencies as a result)
+        size_t ix = 0;
+        for (const ParamRef &ref : param->getDependenciesAsRefs()) {
+            // dependencies must already be defined
+            if (!_mParams.count(ref)) {
+                C2_LOG(FATAL) << "Parameter " << param->name() << " has a dependency at index "
+                        << ix << " that is not yet defined";
+            }
+            _mParams.find(ref)->second->addDownDependency(param->index());
+            ++ix;
+        }
+
+        _mDependencyIndex.emplace(param->index(), _mDependencyIndex.size());
+    }
+
+    std::shared_ptr<ParamHelper> getParam(C2Param::Index ix) const {
+        // TODO: handle streams separately
+        const auto it = _mIndexToHelper.find(ix);
+        if (it == _mIndexToHelper.end()) {
+            return nullptr;
+        }
+        return it->second;
+    }
+
+    /**
+     * TODO: this could return a copy using proper pointer cast.
+     */
+    std::shared_ptr<C2Param> getParamValue(C2Param::Index ix) const {
+        std::shared_ptr<ParamHelper> helper = getParam(ix);
+        return helper ? helper->value() : nullptr;
+    }
+
+    c2_status_t querySupportedParams(
+            std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const {
+        for (const auto &it : _mParams) {
+            // TODO: change querySupportedParams signature?
+            params->push_back(
+                    std::const_pointer_cast<C2ParamDescriptor>(it.second->getDescriptor()));
+        }
+        // TODO: handle errors
+        return C2_OK;
+    }
+
+    size_t getDependencyIndex(C2Param::Index ix) {
+        // in this version of the helper there is only a single stream so
+        // we can look up directly by index
+        auto it = _mDependencyIndex.find(ix);
+        return it == _mDependencyIndex.end() ? SIZE_MAX : it->second;
+    }
+
+private:
+    std::map<ParamRef, std::shared_ptr<ParamHelper>> _mParams;
+    std::map<C2Param::Index, std::shared_ptr<ParamHelper>> _mIndexToHelper;
+    std::shared_ptr<C2ParamReflector> _mReflector;
+    std::map<C2Param::Index, size_t> _mDependencyIndex;
+};
+
+/* --------------------------------- Helper --------------------------------- */
+
+namespace {
+
+static std::string asString(C2Param *p) {
+    char addr[20];
+    sprintf(addr, "%p:[", p);
+    std::string v = addr;
+    for (size_t i = 0; i < p->size(); ++i) {
+        char d[4];
+        sprintf(d, " %02x", *(((uint8_t *)p) + i));
+        v += d + (i == 0);
+    }
+    return v + "]";
+}
+
+}
+
+C2InterfaceHelper::C2InterfaceHelper(std::shared_ptr<C2ReflectorHelper> reflector)
+    : mReflector(reflector),
+      _mFactory(std::make_shared<FactoryImpl>(reflector)) { }
+
+
+size_t C2InterfaceHelper::GetBaseOffset(const std::shared_ptr<C2ParamReflector> &reflector,
+        C2Param::CoreIndex index, size_t offset) {
+    std::unique_ptr<C2StructDescriptor> param = reflector->describe(index);
+    if (param == nullptr) {
+        return ~(size_t)0; // param structure not described
+    }
+
+    for (const C2FieldDescriptor &field : *param) {
+        size_t fieldOffset = _C2ParamInspector::GetOffset(field);
+        size_t fieldSize = _C2ParamInspector::GetSize(field);
+        size_t fieldExtent = field.extent();
+        if (offset < fieldOffset) {
+            return ~(size_t)0; // not found
+        }
+        if (offset == fieldOffset) {
+            // exact match
+            return offset;
+        }
+        if (field.extent() == 0 || offset < fieldOffset + fieldSize * fieldExtent) {
+            // reduce to first element in case of array
+            offset = fieldOffset + (offset - fieldOffset) % fieldSize;
+            if (field.type() >= C2FieldDescriptor::STRUCT_FLAG) {
+                // this offset is within a field
+                offset = GetBaseOffset(
+                        reflector, field.type() & ~C2FieldDescriptor::STRUCT_FLAG,
+                        offset - fieldOffset);
+                return ~offset ? fieldOffset + offset : offset;
+            }
+        }
+    }
+    return ~(size_t)0; // not found
+}
+
+void C2InterfaceHelper::addParameter(std::shared_ptr<ParamHelper> param) {
+    std::lock_guard<std::mutex> lock(mMutex);
+    mReflector->addStructDescriptor(param->retrieveStructDescriptor());
+    c2_status_t err = param->validate(mReflector);
+    if (err != C2_CORRUPTED) {
+        _mFactory->addParam(param);
+
+        // run setter to ensure correct values
+        bool changed = false;
+        std::vector<std::unique_ptr<C2SettingResult>> failures;
+        (void)param->trySet(param->value().get(), C2_MAY_BLOCK, &changed, *_mFactory, &failures);
+    }
+}
+
+c2_status_t C2InterfaceHelper::config(
+       const std::vector<C2Param*> &params, c2_blocking_t mayBlock,
+       std::vector<std::unique_ptr<C2SettingResult>>* const failures, bool updateParams,
+       std::vector<std::shared_ptr<C2Param>> *changes __unused /* TODO */) {
+    std::lock_guard<std::mutex> lock(mMutex);
+    bool paramWasInvalid = false; // TODO is this the same as bad value?
+    bool paramNotFound = false;
+    bool paramBadValue = false;
+    bool paramNoMemory = false;
+    bool paramBlocking = false;
+    bool paramTimedOut = false;
+    bool paramCorrupted = false;
+
+    // dependencies
+    // down dependencies are marked dirty, but params set are not immediately
+    // marked dirty (unless they become down dependency) so that we can
+    // avoid setting them if they did not change
+
+    // TODO: there could be multiple indices for the same dependency index
+    // { depIx, paramIx } may be a suitable key
+    std::map<size_t, std::pair<C2Param::Index, bool>> dependencies;
+
+    std::vector<std::unique_ptr<C2Param>> paramRequests;
+    std::vector<C2Param*> lateReadParams;
+
+    // we cannot determine the last valid parameter, so add an extra
+    // loop iteration after the last parameter
+    for (size_t p_ix = 0; p_ix <= params.size(); ++p_ix) {
+        C2Param *p = nullptr;
+        C2Param::Index paramIx = 0u;
+        size_t paramDepIx = SIZE_MAX;
+        bool last = p_ix == params.size();
+        if (!last) {
+            p = params[p_ix];
+            if (!*p) {
+                paramWasInvalid = true;
+                p->invalidate();
+                continue;
+            }
+
+            paramIx = p->index();
+
+            // convert parameter to request in case this is a split parameter
+            C2Param::Index requestParamIx = paramIx | C2Param::CoreIndex::IS_REQUEST_FLAG;
+
+            // setting a request directly is handled as normal
+            if (paramIx != requestParamIx) {
+                paramDepIx = getDependencyIndex_l(requestParamIx);
+                if (paramDepIx == SIZE_MAX) {
+                    // not a split parameter, handle it normally
+                    paramDepIx = getDependencyIndex_l(paramIx);
+                } else {
+                    // split parameter - replace with setting for the request - and queue to
+                    // read back actual value
+                    // TODO: read late params at the right time
+                    lateReadParams.emplace_back(p);
+                    std::unique_ptr<C2Param> request(C2Param::CopyAsRequest(*p));
+                    p = request.get();
+                    paramRequests.emplace_back(std::move(request));
+                }
+            }
+
+            if (paramDepIx == SIZE_MAX) {
+                // unsupported parameter
+                paramNotFound = true;
+                continue;
+            }
+
+            //
+            // first insert - mark not dirty
+            // it may have been marked dirty by a dependency update
+            // this does not overrwrite(!)
+            (void)dependencies.insert({ paramDepIx, { paramIx, false /* dirty */ }});
+            auto it = dependencies.find(paramDepIx);
+            C2_LOG(VERBOSE) << "marking dependency for setting at #" << paramDepIx << ": "
+                    << it->second.first << ", update "
+                    << (it->second.second ? "always (dirty)" : "only if changed");
+        } else {
+            // process any remaining dependencies
+            if (dependencies.empty()) {
+                continue;
+            }
+            C2_LOG(VERBOSE) << "handling dirty down dependencies after last setting";
+        }
+
+        // process any dirtied down-dependencies until the next param
+        while (dependencies.size() && dependencies.begin()->first <= paramDepIx) {
+            auto min = dependencies.begin();
+            C2Param::Index ix = min->second.first;
+            bool dirty = min->second.second;
+            dependencies.erase(min);
+
+            std::shared_ptr<ParamHelper> param = _mFactory->getParam(ix);
+            C2_LOG(VERBOSE) << "old value " << asString(param->value().get());
+            if (!last) {
+                C2_LOG(VERBOSE) << "new value " << asString(p);
+            }
+            if (!last && !dirty && ix == paramIx && *param->value() == *p) {
+                // no change in value - and dependencies were not updated
+                // no need to update
+                C2_LOG(VERBOSE) << "ignoring setting unchanged param " << ix;
+                continue;
+            }
+
+            // apply setting
+            bool changed = false;
+            C2_LOG(VERBOSE) << "setting param " << ix;
+            std::shared_ptr<C2Param> oldValue = param->value();
+            c2_status_t res = param->trySet(
+                    (!last && paramIx == ix) ? p : param->value().get(), mayBlock,
+                    &changed, *_mFactory, failures);
+            std::shared_ptr<C2Param> newValue = param->value();
+            C2_CHECK_EQ(oldValue == newValue, *oldValue == *newValue);
+            switch (res) {
+                case C2_OK: break;
+                case C2_BAD_VALUE: paramBadValue = true; break;
+                case C2_NO_MEMORY: paramNoMemory = true; break;
+                case C2_TIMED_OUT: paramTimedOut = true; break;
+                case C2_BLOCKING:  paramBlocking = true; break;
+                case C2_CORRUPTED: paramCorrupted = true; break;
+                default: ;// TODO fatal
+            }
+
+            // copy back result for configured values (or invalidate if it does not fit or match)
+            if (updateParams && !last && paramIx == ix) {
+                if (!p->updateFrom(*param->value())) {
+                    p->invalidate();
+                }
+            }
+
+            // compare ptrs as params are copy on write
+            if (changed) {
+                C2_LOG(VERBOSE) << "param " << ix << " value changed";
+                // value changed update down-dependencies and mark them dirty
+                for (const C2Param::Index ix : param->getDownDependencies()) {
+                    C2_LOG(VERBOSE) << 1;
+                    auto insert_res = dependencies.insert(
+                            { getDependencyIndex_l(ix), { ix, true /* dirty */ }});
+                    if (!insert_res.second) {
+                        (*insert_res.first).second.second = true; // mark dirty
+                    }
+
+                    auto it = dependencies.find(getDependencyIndex_l(ix));
+                    C2_CHECK(it->second.second);
+                    C2_LOG(VERBOSE) << "marking down dependencies to update at #"
+                            << getDependencyIndex_l(ix) << ": " << it->second.first;
+                }
+            }
+        }
+    }
+
+    // get late read parameters
+    for (C2Param *p : lateReadParams) {
+        std::shared_ptr<C2Param> value = _mFactory->getParamValue(p->index());
+        if (value) {
+            p->updateFrom(*value);
+        } else {
+            p->invalidate();
+        }
+    }
+
+    return (paramCorrupted ? C2_CORRUPTED :
+            paramBlocking ? C2_BLOCKING :
+            paramTimedOut ? C2_TIMED_OUT :
+            paramNoMemory ? C2_NO_MEMORY :
+            (paramBadValue || paramWasInvalid) ? C2_BAD_VALUE :
+            paramNotFound ? C2_BAD_INDEX : C2_OK);
+}
+
+size_t C2InterfaceHelper::getDependencyIndex_l(C2Param::Index ix) const {
+    return _mFactory->getDependencyIndex(ix);
+}
+
+c2_status_t C2InterfaceHelper::query(
+        const std::vector<C2Param*> &stackParams,
+        const std::vector<C2Param::Index> &heapParamIndices,
+        c2_blocking_t mayBlock __unused /* TODO */,
+        std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
+    std::lock_guard<std::mutex> lock(mMutex);
+    bool paramWasInvalid = false;
+    bool paramNotFound = false;
+    bool paramDidNotFit = false;
+    bool paramNoMemory = false;
+
+    for (C2Param* const p : stackParams) {
+        if (!*p) {
+            paramWasInvalid = true;
+            p->invalidate();
+        } else {
+            std::shared_ptr<C2Param> value = _mFactory->getParamValue(p->index());
+            if (!value) {
+                paramNotFound = true;
+                p->invalidate();
+            } else if (!p->updateFrom(*value)) {
+                paramDidNotFit = true;
+                p->invalidate();
+            }
+        }
+    }
+
+    for (const C2Param::Index ix : heapParamIndices) {
+        std::shared_ptr<C2Param> value = _mFactory->getParamValue(ix);
+        if (value) {
+            std::unique_ptr<C2Param> p = C2Param::Copy(*value);
+            if (p != nullptr) {
+                heapParams->push_back(std::move(p));
+            } else {
+                heapParams->push_back(nullptr);
+                paramNoMemory = true;
+            }
+        } else {
+            heapParams->push_back(nullptr);
+            paramNotFound = true;
+        }
+    }
+
+    return paramNoMemory ? C2_NO_MEMORY :
+           paramNotFound ? C2_BAD_INDEX :
+           // the following errors are not marked in the return value
+           paramDidNotFit ? C2_OK :
+           paramWasInvalid ? C2_OK : C2_OK;
+}
+
+c2_status_t C2InterfaceHelper::querySupportedParams(
+        std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const {
+    std::lock_guard<std::mutex> lock(mMutex);
+    return _mFactory->querySupportedParams(params);
+}
+
+
+c2_status_t C2InterfaceHelper::querySupportedValues(
+        std::vector<C2FieldSupportedValuesQuery> &fields, c2_blocking_t mayBlock __unused) const {
+    std::lock_guard<std::mutex> lock(mMutex);
+    for (C2FieldSupportedValuesQuery &query : fields) {
+        C2_LOG(VERBOSE) << "querying field " << query.field();
+        C2Param::Index ix = _C2ParamInspector::GetIndex(query.field());
+        std::shared_ptr<ParamHelper> param = _mFactory->getParam(ix);
+        if (!param) {
+            C2_LOG(VERBOSE) << "bad param";
+            query.status = C2_BAD_INDEX;
+            continue;
+        }
+        size_t offs = GetBaseOffset(
+                mReflector, ix,
+                _C2ParamInspector::GetOffset(query.field()) - sizeof(C2Param));
+        if (~offs == 0) {
+            C2_LOG(VERBOSE) << "field could not be found";
+            query.status = C2_NOT_FOUND;
+            continue;
+        }
+        offs += sizeof(C2Param);
+        C2_LOG(VERBOSE) << "field resolved to "
+                << StringPrintf("@%02zx+%02x", offs, _C2ParamInspector::GetSize(query.field()));
+        std::shared_ptr<FieldHelper> field =
+            param->findField(offs, _C2ParamInspector::GetSize(query.field()));
+        if (!field) {
+            C2_LOG(VERBOSE) << "bad field";
+            query.status = C2_NOT_FOUND;
+            continue;
+        }
+
+        const C2FieldSupportedValues *values = nullptr;
+        switch (query.type()) {
+        case C2FieldSupportedValuesQuery::CURRENT:
+            values = field->getSupportedValues();
+            break;
+        case C2FieldSupportedValuesQuery::POSSIBLE:
+            values = field->getPossibleValues();
+            break;
+        default:
+            C2_LOG(VERBOSE) << "bad query type: " << query.type();
+            query.status = C2_BAD_VALUE;
+        }
+        if (values) {
+            query.values = *values;
+            query.status = C2_OK;
+        } else {
+            C2_LOG(DEBUG) << "no values published by component";
+            query.status = C2_CORRUPTED;
+        }
+    }
+    return C2_OK;
+}
+
+std::unique_lock<std::mutex> C2InterfaceHelper::lock() const {
+    return std::unique_lock<std::mutex>(mMutex);
+}
diff --git a/media/codec2/vndk/util/C2InterfaceUtils.cpp b/media/codec2/vndk/util/C2InterfaceUtils.cpp
new file mode 100644
index 0000000..61ec911
--- /dev/null
+++ b/media/codec2/vndk/util/C2InterfaceUtils.cpp
@@ -0,0 +1,1292 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-parameter"
+#pragma clang diagnostic ignored "-Wunused-variable"
+#pragma clang diagnostic ignored "-Wunused-value"
+
+#define C2_LOG_VERBOSE
+
+#include <C2Debug.h>
+#include <C2Param.h>
+#include <C2ParamDef.h>
+#include <C2ParamInternal.h>
+#include <util/C2InterfaceUtils.h>
+
+#include <cmath>
+#include <limits>
+#include <map>
+#include <type_traits>
+
+#include <android-base/stringprintf.h>
+
+std::ostream& operator<<(std::ostream& os, const _C2FieldId &i);
+
+std::ostream& operator<<(std::ostream& os, const C2ParamField &i);
+
+/* ---------------------------- C2SupportedRange ---------------------------- */
+
+/**
+ * Helper class for supported values range calculations.
+ */
+template<typename T, bool FP=std::is_floating_point<T>::value>
+struct _C2TypedSupportedRangeHelper {
+    /**
+     * type of range size: a - b if a >= b and a and b are of type T
+     */
+    typedef typename std::make_unsigned<T>::type DiffType;
+
+    /**
+     * calculate (high - low) mod step
+     */
+    static DiffType mod(T low, T high, T step) {
+        return DiffType(high - low) % DiffType(step);
+    }
+};
+
+template<typename T>
+struct _C2TypedSupportedRangeHelper<T, true> {
+    typedef T DiffType;
+
+    static DiffType mod(T low, T high, T step) {
+        return fmod(high - low, step);
+    }
+};
+
+template<typename T>
+C2SupportedRange<T>::C2SupportedRange(const C2FieldSupportedValues &values) {
+    if (values.type == C2FieldSupportedValues::RANGE) {
+        _mMin = values.range.min.ref<ValueType>();
+        _mMax = values.range.max.ref<ValueType>();
+        _mStep = values.range.step.ref<ValueType>();
+        _mNum = values.range.num.ref<ValueType>();
+        _mDenom = values.range.denom.ref<ValueType>();
+    } else {
+        _mMin = MAX_VALUE;
+        _mMax = MIN_VALUE;
+        _mStep = MIN_STEP;
+        _mNum = 0;
+        _mDenom = 0;
+    }
+}
+
+template<typename T>
+bool C2SupportedRange<T>::contains(T value) const {
+    // value must fall between min and max
+    if (value < _mMin || value > _mMax) {
+        return false;
+    }
+    // simple ranges contain all values between min and max
+    if (isSimpleRange()) {
+        return true;
+    }
+    // min is always part of the range
+    if (value == _mMin) {
+        return true;
+    }
+    // stepped ranges require (val - min) % step to be zero
+    if (isArithmeticSeries()) {
+        return _C2TypedSupportedRangeHelper<T>::mod(_mMin, value, _mStep) == 0;
+    }
+    // pure geometric series require (val / min) to be integer multiple of (num/denom)
+    if (isGeometricSeries()) {
+        if (value <= 0) {
+            return false;
+        }
+        double log2base = log2(_mNum / _mDenom);
+        double power = llround(log2(value / double(_mMin)) / log2base);
+        // TODO: validate that result falls within precision (other than round)
+        return value == T(_mMin * pow(_mNum / _mDenom, power) + MIN_STEP / 2);
+    }
+    // multiply-accumulate series require validating by walking through the series
+    if (isMacSeries()) {
+        double lastValue = _mMin;
+        double base = _mNum / _mDenom;
+        while (true) {
+            // this cast is safe as _mMin <= lastValue <= _mMax
+            if (T(lastValue + MIN_STEP / 2) == value) {
+                return true;
+            }
+            double nextValue = fma(lastValue, base, _mStep);
+            if (nextValue <= lastValue || nextValue > _mMax) {
+                return false; // series is no longer monotonic or within range
+            }
+            lastValue = nextValue;
+        };
+    }
+    // if we are here, this must be an invalid range
+    return false;
+}
+
+template<typename T>
+C2SupportedRange<T> C2SupportedRange<T>::limitedTo(const C2SupportedRange<T> &limit) const {
+    // TODO - this only works for simple ranges
+    return C2SupportedRange(std::max(_mMin, limit._mMin), std::min(_mMax, limit._mMax),
+                                 std::max(_mStep, limit._mStep));
+}
+
+template class C2SupportedRange<uint8_t>;
+template class C2SupportedRange<char>;
+template class C2SupportedRange<int32_t>;
+template class C2SupportedRange<uint32_t>;
+//template class C2SupportedRange<c2_cntr32_t>;
+template class C2SupportedRange<int64_t>;
+template class C2SupportedRange<uint64_t>;
+//template class C2SupportedRange<c2_cntr64_t>;
+template class C2SupportedRange<float>;
+
+/* -------------------------- C2SupportedFlags -------------------------- */
+
+/**
+ * Ordered supported flag set for a field of a given type.
+ */
+// float flags are not supported, but define a few methods to support generic supported values code
+template<>
+bool C2SupportedFlags<float>::contains(float value) const {
+    return false;
+}
+
+template<>
+const std::vector<float> C2SupportedFlags<float>::flags() const {
+    return std::vector<float>();
+}
+
+template<>
+C2SupportedFlags<float> C2SupportedFlags<float>::limitedTo(const C2SupportedFlags<float> &limit) const {
+    std::vector<C2Value::Primitive> values;
+    return C2SupportedFlags(std::move(values));
+}
+
+template<>
+float C2SupportedFlags<float>::min() const {
+    return 0;
+}
+
+template<typename T>
+bool C2SupportedFlags<T>::contains(T value) const {
+    // value must contain the minimal mask
+    T minMask = min();
+    if (~value & minMask) {
+        return false;
+    }
+    value &= ~minMask;
+    // otherwise, remove flags from value and see if we arrive at 0
+    for (const C2Value::Primitive &v : _mValues) {
+        if (value == 0) {
+            break;
+        }
+        if ((~value & v.ref<ValueType>()) == 0) {
+            value &= ~v.ref<ValueType>();
+        }
+    }
+    return value == 0;
+}
+
+template<typename T>
+const std::vector<T> C2SupportedFlags<T>::flags() const {
+    std::vector<T> vals(c2_max(_mValues.size(), 1u) - 1);
+    if (!_mValues.empty()) {
+        std::transform(_mValues.cbegin() + 1, _mValues.cend(), vals.begin(),
+                       [](const C2Value::Primitive &p)->T {
+            return p.ref<ValueType>();
+        });
+    }
+    return vals;
+}
+
+template<typename T>
+C2SupportedFlags<T> C2SupportedFlags<T>::limitedTo(const C2SupportedFlags<T> &limit) const {
+    std::vector<C2Value::Primitive> values = _mValues; // make a copy
+    T minMask = min() | limit.min();
+    // minimum mask must be covered by both this and other
+    if (limit.contains(minMask) && contains(minMask)) {
+        values[0] = minMask;
+        // keep only flags that are covered by limit
+        std::remove_if(values.begin(), values.end(), [&limit, minMask](const C2Value::Primitive &v) -> bool {
+            T value = v.ref<ValueType>() | minMask;
+            return value == minMask || !limit.contains(value); });
+        // we also need to do it vice versa
+        for (const C2Value::Primitive &v : _mValues) {
+            T value = v.ref<ValueType>() | minMask;
+            if (value != minMask && contains(value)) {
+                values.emplace_back((ValueType)value);
+            }
+        }
+    }
+    return C2SupportedFlags(std::move(values));
+}
+
+template<typename T>
+T C2SupportedFlags<T>::min() const {
+    if (!_mValues.empty()) {
+        return _mValues.front().template ref<ValueType>();
+    } else {
+        return T(0);
+    }
+}
+
+template class C2SupportedFlags<uint8_t>;
+template class C2SupportedFlags<char>;
+template class C2SupportedFlags<int32_t>;
+template class C2SupportedFlags<uint32_t>;
+//template class C2SupportedFlags<c2_cntr32_t>;
+template class C2SupportedFlags<int64_t>;
+template class C2SupportedFlags<uint64_t>;
+//template class C2SupportedFlags<c2_cntr64_t>;
+
+/* -------------------------- C2SupportedValueSet -------------------------- */
+
+/**
+ * Ordered supported value set for a field of a given type.
+ */
+template<typename T>
+bool C2SupportedValueSet<T>::contains(T value) const {
+    return std::find_if(_mValues.cbegin(), _mValues.cend(),
+            [value](const C2Value::Primitive &p) -> bool {
+                return value == p.ref<ValueType>();
+            }) != _mValues.cend();
+}
+
+template<typename T>
+C2SupportedValueSet<T> C2SupportedValueSet<T>::limitedTo(const C2SupportedValueSet<T> &limit) const {
+    std::vector<C2Value::Primitive> values = _mValues; // make a copy
+    std::remove_if(values.begin(), values.end(), [&limit](const C2Value::Primitive &v) -> bool {
+        return !limit.contains(v.ref<ValueType>()); });
+    return C2SupportedValueSet(std::move(values));
+}
+
+template<typename T>
+C2SupportedValueSet<T> C2SupportedValueSet<T>::limitedTo(const C2SupportedRange<T> &limit) const {
+    std::vector<C2Value::Primitive> values = _mValues; // make a copy
+    std::remove_if(values.begin(), values.end(), [&limit](const C2Value::Primitive &v) -> bool {
+        return !limit.contains(v.ref<ValueType>()); });
+    return C2SupportedValueSet(std::move(values));
+}
+
+template<typename T>
+C2SupportedValueSet<T> C2SupportedValueSet<T>::limitedTo(const C2SupportedFlags<T> &limit) const {
+    std::vector<C2Value::Primitive> values = _mValues; // make a copy
+    std::remove_if(values.begin(), values.end(), [&limit](const C2Value::Primitive &v) -> bool {
+        return !limit.contains(v.ref<ValueType>()); });
+    return C2SupportedValueSet(std::move(values));
+}
+
+template<typename T>
+const std::vector<T> C2SupportedValueSet<T>::values() const {
+    std::vector<T> vals(_mValues.size());
+    std::transform(_mValues.cbegin(), _mValues.cend(), vals.begin(), [](const C2Value::Primitive &p) -> T {
+        return p.ref<ValueType>();
+    });
+    return vals;
+}
+
+template class C2SupportedValueSet<uint8_t>;
+template class C2SupportedValueSet<char>;
+template class C2SupportedValueSet<int32_t>;
+template class C2SupportedValueSet<uint32_t>;
+//template class C2SupportedValueSet<c2_cntr32_t>;
+template class C2SupportedValueSet<int64_t>;
+template class C2SupportedValueSet<uint64_t>;
+//template class C2SupportedValueSet<c2_cntr64_t>;
+template class C2SupportedValueSet<float>;
+
+/* ---------------------- C2FieldSupportedValuesHelper ---------------------- */
+
+template<typename T>
+struct C2FieldSupportedValuesHelper<T>::Impl {
+    Impl(const C2FieldSupportedValues &values)
+        : _mType(values.type),
+          _mRange(values),
+          _mValues(values),
+          _mFlags(values) { }
+
+    bool supports(T value) const;
+
+private:
+    typedef typename _C2FieldValueHelper<T>::ValueType ValueType;
+    C2FieldSupportedValues::type_t _mType;
+    C2SupportedRange<ValueType> _mRange;
+    C2SupportedValueSet<ValueType> _mValues;
+    C2SupportedValueSet<ValueType> _mFlags;
+
+//    friend std::ostream& operator<< <T>(std::ostream& os, const C2FieldSupportedValuesHelper<T>::Impl &i);
+//    friend std::ostream& operator<<(std::ostream& os, const Impl &i);
+    std::ostream& streamOut(std::ostream& os) const;
+};
+
+template<typename T>
+bool C2FieldSupportedValuesHelper<T>::Impl::supports(T value) const {
+    switch (_mType) {
+        case C2FieldSupportedValues::RANGE: return _mRange.contains(value);
+        case C2FieldSupportedValues::VALUES: return _mValues.contains(value);
+        case C2FieldSupportedValues::FLAGS: return _mFlags.contains(value);
+        default: return false;
+    }
+}
+
+template<typename T>
+C2FieldSupportedValuesHelper<T>::C2FieldSupportedValuesHelper(const C2FieldSupportedValues &values)
+    : _mImpl(std::make_unique<C2FieldSupportedValuesHelper<T>::Impl>(values)) { }
+
+template<typename T>
+C2FieldSupportedValuesHelper<T>::~C2FieldSupportedValuesHelper() = default;
+
+template<typename T>
+bool C2FieldSupportedValuesHelper<T>::supports(T value) const {
+    return _mImpl->supports(value);
+}
+
+template class C2FieldSupportedValuesHelper<uint8_t>;
+template class C2FieldSupportedValuesHelper<char>;
+template class C2FieldSupportedValuesHelper<int32_t>;
+template class C2FieldSupportedValuesHelper<uint32_t>;
+//template class C2FieldSupportedValuesHelper<c2_cntr32_t>;
+template class C2FieldSupportedValuesHelper<int64_t>;
+template class C2FieldSupportedValuesHelper<uint64_t>;
+//template class C2FieldSupportedValuesHelper<c2_cntr64_t>;
+template class C2FieldSupportedValuesHelper<float>;
+
+/* ----------------------- C2ParamFieldValuesBuilder ----------------------- */
+
+template<typename T>
+struct C2ParamFieldValuesBuilder<T>::Impl {
+    Impl(const C2ParamField &field)
+        : _mParamField(field),
+          _mType(type_t::RANGE),
+          _mDefined(false),
+          _mRange(C2SupportedRange<T>::Any()),
+          _mValues(C2SupportedValueSet<T>::None()),
+          _mFlags(C2SupportedFlags<T>::None()) { }
+
+    /**
+     * Get C2ParamFieldValues from this builder.
+     */
+    operator C2ParamFieldValues() const {
+        if (!_mDefined) {
+            return C2ParamFieldValues(_mParamField);
+        }
+        switch (_mType) {
+        case type_t::EMPTY:
+        case type_t::VALUES:
+            return C2ParamFieldValues(_mParamField, (C2FieldSupportedValues)_mValues);
+        case type_t::RANGE:
+            return C2ParamFieldValues(_mParamField, (C2FieldSupportedValues)_mRange);
+        case type_t::FLAGS:
+            return C2ParamFieldValues(_mParamField, (C2FieldSupportedValues)_mFlags);
+        default:
+            // TRESPASS
+            // should never get here
+            return C2ParamFieldValues(_mParamField);
+        }
+    }
+
+    /** Define the supported values as the currently supported values of this builder. */
+    void any() {
+        _mDefined = true;
+    }
+
+    /** Restrict (and thus define) the supported values to none. */
+    void none() {
+        _mDefined = true;
+        _mType = type_t::VALUES;
+        _mValues.clear();
+    }
+
+    /** Restrict (and thus define) the supported values to |value| alone. */
+    void equalTo(T value) {
+         return limitTo(C2SupportedValueSet<T>::OneOf({value}));
+    }
+
+    /** Restrict (and thus define) the supported values to a value set. */
+    void limitTo(const C2SupportedValueSet<T> &limit) {
+        if (!_mDefined) {
+            C2_LOG(VERBOSE) << "NA.limitTo(" << C2FieldSupportedValuesHelper<T>(limit) << ")";
+
+            // shortcut for first limit applied
+            _mDefined = true;
+            _mValues = limit;
+            _mType = _mValues.isEmpty() ? type_t::EMPTY : type_t::VALUES;
+        } else {
+            switch (_mType) {
+            case type_t::EMPTY:
+            case type_t::VALUES:
+                C2_LOG(VERBOSE) << "(" << C2FieldSupportedValuesHelper<T>(_mValues) << ").limitTo("
+                        << C2FieldSupportedValuesHelper<T>(limit) << ")";
+
+                _mValues = _mValues.limitedTo(limit);
+                _mType = _mValues.isEmpty() ? type_t::EMPTY : type_t::VALUES;
+                break;
+            case type_t::RANGE:
+                C2_LOG(VERBOSE) << "(" << C2FieldSupportedValuesHelper<T>(_mRange) << ").limitTo("
+                        << C2FieldSupportedValuesHelper<T>(limit) << ")";
+
+                _mValues = limit.limitedTo(_mRange);
+                _mType = _mValues.isEmpty() ? type_t::EMPTY : type_t::VALUES;
+                break;
+            case type_t::FLAGS:
+                C2_LOG(VERBOSE) << "(" << C2FieldSupportedValuesHelper<T>(_mRange) << ").limitTo("
+                        << C2FieldSupportedValuesHelper<T>(limit) << ")";
+
+                _mValues = limit.limitedTo(_mFlags);
+                _mType = _mValues.isEmpty() ? type_t::EMPTY : type_t::VALUES;
+                break;
+            default:
+                C2_LOG(FATAL); // should not be here
+            }
+            // TODO: support flags
+        }
+        C2_LOG(VERBOSE) << " = " << _mType << ":" << C2FieldSupportedValuesHelper<T>(_mValues);
+    }
+
+    /** Restrict (and thus define) the supported values to a flag set. */
+    void limitTo(const C2SupportedFlags<T> &limit) {
+        if (!_mDefined) {
+            C2_LOG(VERBOSE) << "NA.limitTo(" << C2FieldSupportedValuesHelper<T>(limit) << ")";
+
+            // shortcut for first limit applied
+            _mDefined = true;
+            _mFlags = limit;
+            _mType = _mFlags.isEmpty() ? type_t::EMPTY : type_t::FLAGS;
+        } else {
+            switch (_mType) {
+            case type_t::EMPTY:
+            case type_t::VALUES:
+                C2_LOG(VERBOSE) << "(" << C2FieldSupportedValuesHelper<T>(_mValues) << ").limitTo("
+                        << C2FieldSupportedValuesHelper<T>(limit) << ")";
+
+                _mValues = _mValues.limitedTo(limit);
+                _mType = _mValues.isEmpty() ? type_t::EMPTY : type_t::VALUES;
+                C2_LOG(VERBOSE) << " = " << _mType << ":" << C2FieldSupportedValuesHelper<T>(_mValues);
+                break;
+            case type_t::FLAGS:
+                C2_LOG(VERBOSE) << "(" << C2FieldSupportedValuesHelper<T>(_mFlags) << ").limitTo("
+                        << C2FieldSupportedValuesHelper<T>(limit) << ")";
+
+                _mFlags = _mFlags.limitedTo(limit);
+                _mType = _mFlags.isEmpty() ? type_t::EMPTY : type_t::FLAGS;
+                C2_LOG(VERBOSE) << " = " << _mType << ":" << C2FieldSupportedValuesHelper<T>(_mFlags);
+                break;
+            case type_t::RANGE:
+                C2_LOG(FATAL) << "limiting ranges to flags is not supported";
+                _mType = type_t::EMPTY;
+                break;
+            default:
+                C2_LOG(FATAL); // should not be here
+            }
+        }
+    }
+
+    void limitTo(const C2SupportedRange<T> &limit) {
+        if (!_mDefined) {
+            C2_LOG(VERBOSE) << "NA.limitTo(" << C2FieldSupportedValuesHelper<T>(limit) << ")";
+
+            // shortcut for first limit applied
+            _mDefined = true;
+            _mRange = limit;
+            _mType = _mRange.isEmpty() ? type_t::EMPTY : type_t::RANGE;
+            C2_LOG(VERBOSE) << " = " << _mType << ":" << C2FieldSupportedValuesHelper<T>(_mRange);
+        } else {
+            switch (_mType) {
+            case type_t::EMPTY:
+            case type_t::VALUES:
+                C2_LOG(VERBOSE) << "(" << C2FieldSupportedValuesHelper<T>(_mValues) << ").limitTo("
+                        << C2FieldSupportedValuesHelper<T>(limit) << ")";
+                _mValues = _mValues.limitedTo(limit);
+                _mType = _mValues.isEmpty() ? type_t::EMPTY : type_t::VALUES;
+                C2_LOG(VERBOSE) << " = " << _mType << ":" << C2FieldSupportedValuesHelper<T>(_mValues);
+                break;
+            case type_t::FLAGS:
+                C2_LOG(FATAL) << "limiting flags to ranges is not supported";
+                _mType = type_t::EMPTY;
+                break;
+            case type_t::RANGE:
+                C2_LOG(VERBOSE) << "(" << C2FieldSupportedValuesHelper<T>(_mRange) << ").limitTo("
+                        << C2FieldSupportedValuesHelper<T>(limit) << ")";
+                _mRange = _mRange.limitedTo(limit);
+                C2_DCHECK(_mValues.isEmpty());
+                _mType = _mRange.isEmpty() ? type_t::EMPTY : type_t::RANGE;
+                C2_LOG(VERBOSE) << " = " << _mType << ":" << C2FieldSupportedValuesHelper<T>(_mRange);
+                break;
+            default:
+                C2_LOG(FATAL); // should not be here
+            }
+        }
+    }
+
+private:
+    void instantiate() __unused {
+        (void)_mValues.values(); // instantiate non-const values()
+    }
+
+    void instantiate() const __unused {
+        (void)_mValues.values(); // instantiate const values()
+    }
+
+    typedef C2FieldSupportedValues::type_t type_t;
+
+    C2ParamField _mParamField;
+    type_t _mType;
+    bool _mDefined;
+    C2SupportedRange<T> _mRange;
+    C2SupportedValueSet<T> _mValues;
+    C2SupportedFlags<T> _mFlags;
+
+};
+
+template<typename T>
+C2ParamFieldValuesBuilder<T>::operator C2ParamFieldValues() const {
+    return (C2ParamFieldValues)(*_mImpl.get());
+}
+
+template<typename T>
+C2ParamFieldValuesBuilder<T>::C2ParamFieldValuesBuilder(const C2ParamField &field)
+    : _mImpl(std::make_unique<C2ParamFieldValuesBuilder<T>::Impl>(field)) { }
+
+template<typename T>
+C2ParamFieldValuesBuilder<T> &C2ParamFieldValuesBuilder<T>::any() {
+    _mImpl->any();
+    return *this;
+}
+
+template<typename T>
+C2ParamFieldValuesBuilder<T> &C2ParamFieldValuesBuilder<T>::none() {
+    _mImpl->none();
+    return *this;
+}
+
+template<typename T>
+C2ParamFieldValuesBuilder<T> &C2ParamFieldValuesBuilder<T>::equalTo(T value) {
+    _mImpl->equalTo(value);
+    return *this;
+}
+
+template<typename T>
+C2ParamFieldValuesBuilder<T> &C2ParamFieldValuesBuilder<T>::limitTo(const C2SupportedValueSet<T> &limit) {
+    _mImpl->limitTo(limit);
+    return *this;
+}
+
+template<typename T>
+C2ParamFieldValuesBuilder<T> &C2ParamFieldValuesBuilder<T>::limitTo(const C2SupportedFlags<T> &limit) {
+    _mImpl->limitTo(limit);
+    return *this;
+}
+
+template<typename T>
+C2ParamFieldValuesBuilder<T> &C2ParamFieldValuesBuilder<T>::limitTo(const C2SupportedRange<T> &limit) {
+    _mImpl->limitTo(limit);
+    return *this;
+}
+
+template<typename T>
+C2ParamFieldValuesBuilder<T>::C2ParamFieldValuesBuilder(const C2ParamFieldValuesBuilder<T> &other)
+    : _mImpl(std::make_unique<C2ParamFieldValuesBuilder<T>::Impl>(*other._mImpl.get())) { }
+
+template<typename T>
+C2ParamFieldValuesBuilder<T> &C2ParamFieldValuesBuilder<T>::operator=(
+        const C2ParamFieldValuesBuilder<T> &other) {
+    _mImpl = std::make_unique<C2ParamFieldValuesBuilder<T>::Impl>(*other._mImpl.get());
+    return *this;
+}
+
+template<typename T>
+C2ParamFieldValuesBuilder<T>::~C2ParamFieldValuesBuilder() = default;
+
+template class C2ParamFieldValuesBuilder<uint8_t>;
+template class C2ParamFieldValuesBuilder<char>;
+template class C2ParamFieldValuesBuilder<int32_t>;
+template class C2ParamFieldValuesBuilder<uint32_t>;
+//template class C2ParamFieldValuesBuilder<c2_cntr32_t>;
+template class C2ParamFieldValuesBuilder<int64_t>;
+template class C2ParamFieldValuesBuilder<uint64_t>;
+//template class C2ParamFieldValuesBuilder<c2_cntr64_t>;
+template class C2ParamFieldValuesBuilder<float>;
+
+/* ------------------------- C2SettingResultBuilder ------------------------- */
+
+C2SettingConflictsBuilder::C2SettingConflictsBuilder() : _mConflicts() { }
+
+C2SettingConflictsBuilder::C2SettingConflictsBuilder(C2ParamFieldValues &&conflict) {
+    _mConflicts.emplace_back(std::move(conflict));
+}
+
+C2SettingConflictsBuilder& C2SettingConflictsBuilder::with(C2ParamFieldValues &&conflict) {
+    _mConflicts.emplace_back(std::move(conflict));
+    return *this;
+}
+
+std::vector<C2ParamFieldValues> C2SettingConflictsBuilder::retrieveConflicts() {
+    return std::move(_mConflicts);
+}
+
+/* ------------------------- C2SettingResult/sBuilder ------------------------- */
+
+C2SettingResult C2SettingResultBuilder::ReadOnly(const C2ParamField &param) {
+    return C2SettingResult { C2SettingResult::READ_ONLY, { param }, { } };
+}
+
+C2SettingResult C2SettingResultBuilder::BadValue(const C2ParamField &paramField, bool isInfo) {
+    return { isInfo ? C2SettingResult::INFO_BAD_VALUE : C2SettingResult::BAD_VALUE,
+             { paramField }, { } };
+}
+
+C2SettingResult C2SettingResultBuilder::Conflict(
+        C2ParamFieldValues &&paramFieldValues, C2SettingConflictsBuilder &conflicts, bool isInfo) {
+    C2_CHECK(!conflicts.empty());
+    if (isInfo) {
+        return C2SettingResult {
+            C2SettingResult::INFO_CONFLICT,
+            std::move(paramFieldValues), conflicts.retrieveConflicts()
+        };
+    } else {
+        return C2SettingResult {
+            C2SettingResult::CONFLICT,
+            std::move(paramFieldValues), conflicts.retrieveConflicts()
+        };
+    }
+}
+
+C2SettingResultsBuilder::C2SettingResultsBuilder(C2SettingResult &&result)
+        : _mStatus(C2_BAD_VALUE) {
+    _mResults.emplace_back(new C2SettingResult(std::move(result)));
+}
+
+C2SettingResultsBuilder C2SettingResultsBuilder::plus(C2SettingResultsBuilder&& results) {
+    for (std::unique_ptr<C2SettingResult> &r : results._mResults) {
+        _mResults.emplace_back(std::move(r));
+    }
+    results._mResults.clear();
+    // TODO: mStatus
+    return std::move(*this);
+}
+
+c2_status_t C2SettingResultsBuilder::retrieveFailures(
+        std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
+    for (std::unique_ptr<C2SettingResult> &r : _mResults) {
+        failures->emplace_back(std::move(r));
+    }
+    _mResults.clear();
+    return _mStatus;
+}
+
+C2SettingResultsBuilder::C2SettingResultsBuilder(c2_status_t status) : _mStatus(status) {
+    // status must be one of OK, BAD_STATE, TIMED_OUT or CORRUPTED
+    // mainly: BLOCKING, BAD_INDEX, BAD_VALUE and NO_MEMORY requires a setting attempt
+}
+
+#pragma clang diagnostic pop
+
+/* ------------------------- C2FieldUtils ------------------------- */
+
+struct C2_HIDE C2FieldUtils::_Inspector {
+    /// returns the implementation object
+    inline static std::shared_ptr<Info::Impl> GetImpl(const Info &info) {
+        return info._mImpl;
+    }
+};
+
+/* ------------------------- C2FieldUtils::Info ------------------------- */
+
+struct C2_HIDE C2FieldUtils::Info::Impl {
+    C2FieldDescriptor field;
+    std::shared_ptr<Impl> parent;
+    uint32_t index;
+    uint32_t depth;
+    uint32_t baseFieldOffset;
+    uint32_t arrayOffset;
+    uint32_t usedExtent;
+
+    /// creates a copy of this object including copies of its parent chain
+    Impl clone() const;
+
+    /// creates a copy of a shared pointer to an object
+    static std::shared_ptr<Impl> Clone(const std::shared_ptr<Impl> &);
+
+    Impl(const C2FieldDescriptor &field_, std::shared_ptr<Impl> parent_,
+            uint32_t index_, uint32_t depth_, uint32_t baseFieldOffset_,
+            uint32_t arrayOffset_, uint32_t usedExtent_)
+        : field(field_), parent(parent_), index(index_), depth(depth_),
+          baseFieldOffset(baseFieldOffset_), arrayOffset(arrayOffset_), usedExtent(usedExtent_) { }
+};
+
+std::shared_ptr<C2FieldUtils::Info::Impl> C2FieldUtils::Info::Impl::Clone(const std::shared_ptr<Impl> &info) {
+    if (info) {
+        return std::make_shared<Impl>(info->clone());
+    }
+    return nullptr;
+}
+
+C2FieldUtils::Info::Impl C2FieldUtils::Info::Impl::clone() const {
+    Impl res = Impl(*this);
+    res.parent = Clone(res.parent);
+    return res;
+}
+
+C2FieldUtils::Info::Info(std::shared_ptr<Impl> impl)
+    : _mImpl(impl) { }
+
+size_t C2FieldUtils::Info::arrayOffset() const {
+    return _mImpl->arrayOffset;
+}
+
+size_t C2FieldUtils::Info::arraySize() const {
+    return extent() * size();
+}
+
+size_t C2FieldUtils::Info::baseFieldOffset() const {
+    return _mImpl->baseFieldOffset;
+};
+
+size_t C2FieldUtils::Info::depth() const {
+    return _mImpl->depth;
+}
+
+size_t C2FieldUtils::Info::extent() const {
+    return _mImpl->usedExtent;
+}
+
+size_t C2FieldUtils::Info::index() const {
+    return _mImpl->index;
+}
+
+bool C2FieldUtils::Info::isArithmetic() const {
+    switch (_mImpl->field.type()) {
+    case C2FieldDescriptor::BLOB:
+    case C2FieldDescriptor::CNTR32:
+    case C2FieldDescriptor::CNTR64:
+    case C2FieldDescriptor::FLOAT:
+    case C2FieldDescriptor::INT32:
+    case C2FieldDescriptor::INT64:
+    case C2FieldDescriptor::STRING:
+    case C2FieldDescriptor::UINT32:
+    case C2FieldDescriptor::UINT64:
+        return true;
+    default:
+        return false;
+    }
+}
+
+bool C2FieldUtils::Info::isFlexible() const {
+    return _mImpl->field.extent() == 0;
+}
+
+C2String C2FieldUtils::Info::name() const {
+    return _mImpl->field.name();
+}
+
+const C2FieldUtils::Info::NamedValuesType &C2FieldUtils::Info::namedValues() const {
+    return _mImpl->field.namedValues();
+}
+
+size_t C2FieldUtils::Info::offset() const {
+    return _C2ParamInspector::GetOffset(_mImpl->field);
+}
+
+C2FieldUtils::Info C2FieldUtils::Info::parent() const {
+    return Info(_mImpl->parent);
+};
+
+size_t C2FieldUtils::Info::size() const {
+    return _C2ParamInspector::GetSize(_mImpl->field);
+}
+
+C2FieldUtils::Info::type_t C2FieldUtils::Info::type() const {
+    return _mImpl->field.type();
+}
+
+/* ------------------------- C2FieldUtils::Iterator ------------------------- */
+
+struct C2_HIDE C2FieldUtils::Iterator::Impl : public _C2ParamInspector {
+    Impl() = default;
+
+    virtual ~Impl() = default;
+
+    /// implements object equality
+    virtual bool equals(const std::shared_ptr<Impl> &other) const {
+        return other != nullptr && mHead == other->mHead;
+    };
+
+    /// returns the info pointed to by this iterator
+    virtual value_type get() const {
+        return Info(mHead);
+    }
+
+    /// increments this iterator
+    virtual void increment() {
+        // note: this cannot be abstract as we instantiate this for List::end(). increment to end()
+        // instead.
+        mHead.reset();
+    }
+
+protected:
+    Impl(std::shared_ptr<C2FieldUtils::Info::Impl> head)
+        : mHead(head) { }
+
+    std::shared_ptr<Info::Impl> mHead; ///< current field
+};
+
+C2FieldUtils::Iterator::Iterator(std::shared_ptr<Impl> impl)
+    : mImpl(impl) { }
+
+C2FieldUtils::Iterator::value_type C2FieldUtils::Iterator::operator*() const {
+    return mImpl->get();
+}
+
+C2FieldUtils::Iterator& C2FieldUtils::Iterator::operator++() {
+    mImpl->increment();
+    return *this;
+}
+
+bool C2FieldUtils::Iterator::operator==(const Iterator &other) const {
+    return mImpl->equals(other.mImpl);
+}
+
+/* ------------------------- C2FieldUtils::List ------------------------- */
+
+struct C2_HIDE C2FieldUtils::List::Impl {
+    virtual std::shared_ptr<Iterator::Impl> begin() const = 0;
+
+    /// returns an iterator to the end of the list
+    virtual std::shared_ptr<Iterator::Impl> end() const {
+        return std::make_shared<Iterator::Impl>();
+    }
+
+    virtual ~Impl() = default;
+};
+
+C2FieldUtils::List::List(std::shared_ptr<Impl> impl)
+    : mImpl(impl) { }
+
+C2FieldUtils::Iterator C2FieldUtils::List::begin() const {
+    return C2FieldUtils::Iterator(mImpl->begin());
+}
+
+C2FieldUtils::Iterator C2FieldUtils::List::end() const {
+    return C2FieldUtils::Iterator(mImpl->end());
+}
+
+/* ------------------------- C2FieldUtils::enumerateFields ------------------------- */
+
+namespace {
+
+/**
+ * Iterator base class helper that allows descending into the field hierarchy.
+ */
+struct C2FieldUtilsFieldsIteratorHelper : public C2FieldUtils::Iterator::Impl {
+    virtual ~C2FieldUtilsFieldsIteratorHelper() override = default;
+
+    /// returns the base-field's offset of the parent field (or the param offset if no parent)
+    static inline uint32_t GetParentBaseFieldOffset(
+            const std::shared_ptr<C2FieldUtils::Info::Impl> parent) {
+        return parent == nullptr ? sizeof(C2Param) : parent->baseFieldOffset;
+    }
+
+    /// returns the offset of the parent field (or the param)
+    static inline uint32_t GetParentOffset(const std::shared_ptr<C2FieldUtils::Info::Impl> parent) {
+        return parent == nullptr ? sizeof(C2Param) : GetOffset(parent->field);
+    }
+
+protected:
+    C2FieldUtilsFieldsIteratorHelper(
+            std::shared_ptr<C2ParamReflector> reflector,
+            uint32_t paramSize,
+            std::shared_ptr<C2FieldUtils::Info::Impl> head = nullptr)
+        : C2FieldUtils::Iterator::Impl(head),
+          mParamSize(paramSize),
+          mReflector(reflector) { }
+
+    /// returns a leaf info object at a specific index for a child field
+    std::shared_ptr<C2FieldUtils::Info::Impl> makeLeaf(
+            const C2FieldDescriptor &field, uint32_t index) {
+        uint32_t parentOffset = GetParentOffset(mHead);
+        uint32_t arrayOffset = parentOffset + GetOffset(field);
+        uint32_t usedExtent = field.extent() ? :
+                (std::max(arrayOffset, mParamSize) - arrayOffset) / GetSize(field);
+
+        return std::make_shared<C2FieldUtils::Info::Impl>(
+                OffsetFieldDescriptor(field, parentOffset + index * GetSize(field)),
+                mHead /* parent */, index, mHead == nullptr ? 0 : mHead->depth + 1,
+                GetParentBaseFieldOffset(mHead) + GetOffset(field),
+                arrayOffset, usedExtent);
+    }
+
+    /// returns whether this struct index have been traversed to get to this field
+    bool visited(C2Param::CoreIndex index) const {
+        for (const std::shared_ptr<C2StructDescriptor> &sd : mHistory) {
+            if (sd->coreIndex() == index) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    uint32_t mParamSize;
+    std::shared_ptr<C2ParamReflector> mReflector;
+    std::vector<std::shared_ptr<C2StructDescriptor>> mHistory; // structure types visited
+};
+
+/**
+ * Iterator implementing enumerateFields() that visits each base field.
+ */
+struct C2FieldUtilsFieldsIterator : public C2FieldUtilsFieldsIteratorHelper {
+    /// enumerate base fields of a parameter
+    C2FieldUtilsFieldsIterator(const C2Param &param, std::shared_ptr<C2ParamReflector> reflector)
+        : C2FieldUtilsFieldsIteratorHelper(reflector, param.size()) {
+        descendInto(param.coreIndex());
+    }
+
+    /// enumerate base fields of a field
+    C2FieldUtilsFieldsIterator(std::shared_ptr<C2FieldUtilsFieldsIterator> impl)
+        : C2FieldUtilsFieldsIteratorHelper(impl->mReflector, impl->mParamSize, impl->mHead) {
+        mHistory = impl->mHistory;
+        if (mHead->field.type() & C2FieldDescriptor::STRUCT_FLAG) {
+            C2Param::CoreIndex index = { mHead->field.type() &~C2FieldDescriptor::STRUCT_FLAG };
+            if (!visited(index)) {
+                descendInto(index);
+            }
+        }
+    }
+
+    virtual ~C2FieldUtilsFieldsIterator() override = default;
+
+    /// Increments this iterator by visiting each base field.
+    virtual void increment() override {
+        // don't go past end
+        if (mHead == nullptr || _mFields.empty()) {
+            return;
+        }
+
+        // descend into structures
+        if (mHead->field.type() & C2FieldDescriptor::STRUCT_FLAG) {
+            C2Param::CoreIndex index = { mHead->field.type() &~C2FieldDescriptor::STRUCT_FLAG };
+            // do not recurse into the same structs
+            if (!visited(index) && descendInto(index)) {
+                return;
+            }
+        }
+
+        // ascend after the last field in the current struct
+        while (!mHistory.empty() && _mFields.back() == mHistory.back()->end()) {
+            mHead = mHead->parent;
+            mHistory.pop_back();
+            _mFields.pop_back();
+        }
+
+        // done if history is now empty
+        if (_mFields.empty()) {
+            // we could be traversing a sub-tree so clear head
+            mHead.reset();
+            return;
+        }
+
+        // move to the next field in the current struct
+        C2StructDescriptor::field_iterator next = _mFields.back();
+        mHead->field = OffsetFieldDescriptor(*next, GetParentOffset(mHead->parent));
+        mHead->index = 0; // reset index just in case for correctness
+        mHead->baseFieldOffset = GetParentBaseFieldOffset(mHead->parent) + GetOffset(*next);
+        mHead->arrayOffset = GetOffset(mHead->field);
+        mHead->usedExtent = mHead->field.extent() ? :
+                (std::max(mHead->arrayOffset, mParamSize) - mHead->arrayOffset)
+                        / GetSize(mHead->field);
+        ++_mFields.back();
+    }
+
+private:
+    /// If the current field is a known, valid (untraversed) structure, it modifies this iterator
+    /// to point to the first field of the structure and returns true. Otherwise, it does not
+    /// modify this iterator and returns false.
+    bool descendInto(C2Param::CoreIndex index) {
+        std::unique_ptr<C2StructDescriptor> descUnique = mReflector->describe(index);
+        // descend into known structs (as long as they have at least one field)
+        if (descUnique && descUnique->begin() != descUnique->end()) {
+            std::shared_ptr<C2StructDescriptor> desc(std::move(descUnique));
+            mHistory.emplace_back(desc);
+            C2StructDescriptor::field_iterator first = desc->begin();
+            mHead = makeLeaf(*first, 0 /* index */);
+            _mFields.emplace_back(++first);
+            return true;
+        }
+        return false;
+    }
+
+    /// next field pointers for each depth.
+    /// note: _mFields may be shorted than mHistory, if iterating at a depth
+    std::vector<C2StructDescriptor::field_iterator> _mFields;
+};
+
+/**
+ * Iterable implementing enumerateFields().
+ */
+struct C2FieldUtilsFieldIterable : public C2FieldUtils::List::Impl {
+    /// returns an iterator to the beginning of the list
+    virtual std::shared_ptr<C2FieldUtils::Iterator::Impl> begin() const override {
+        return std::make_shared<C2FieldUtilsFieldsIterator>(*_mParam, _mReflector);
+    };
+
+    C2FieldUtilsFieldIterable(const C2Param &param, std::shared_ptr<C2ParamReflector> reflector)
+        : _mParam(&param), _mReflector(reflector) { }
+
+private:
+    const C2Param *_mParam;
+    std::shared_ptr<C2ParamReflector> _mReflector;
+};
+
+}
+
+C2FieldUtils::List C2FieldUtils::enumerateFields(
+        const C2Param &param, const std::shared_ptr<C2ParamReflector> &reflector) {
+    return C2FieldUtils::List(std::make_shared<C2FieldUtilsFieldIterable>(param, reflector));
+}
+
+/* ------------------------- C2FieldUtils::enumerate siblings ------------------------- */
+
+namespace {
+
+struct C2FieldUtilsCousinsIterator : public C2FieldUtils::Iterator::Impl {
+    C2FieldUtilsCousinsIterator(
+                const std::shared_ptr<C2FieldUtils::Info::Impl> &info, size_t level)
+          // clone info chain as this iterator will change it
+        : C2FieldUtils::Iterator::Impl(C2FieldUtils::Info::Impl::Clone(info)) {
+        if (level == 0) {
+            return;
+        }
+
+        // store parent chain (up to level) for quick access
+        std::shared_ptr<C2FieldUtils::Info::Impl> node = mHead;
+        size_t ix = 0;
+        for (; ix < level && node; ++ix) {
+            node->index = 0;
+            _mPath.emplace_back(node);
+            node = node->parent;
+        }
+        setupPath(ix);
+    }
+
+    virtual ~C2FieldUtilsCousinsIterator() override = default;
+
+    /// Increments this iterator by visiting each index.
+    virtual void increment() override {
+        size_t ix = 0;
+        while (ix < _mPath.size()) {
+            if (++_mPath[ix]->index < _mPath[ix]->usedExtent) {
+                setupPath(ix + 1);
+                return;
+            }
+            _mPath[ix++]->index = 0;
+        }
+        mHead.reset();
+    }
+
+private:
+    /// adjusts field offsets along the path up to the specific level - 1.
+    /// This in-fact has to be done down the path from parent to child as child fields must
+    /// fall within parent fields.
+    void setupPath(size_t level) {
+        C2_CHECK_LE(level, _mPath.size());
+        uint32_t oldArrayOffset = level ? _mPath[level - 1]->arrayOffset : 0 /* unused */;
+        while (level) {
+            --level;
+            C2FieldUtils::Info::Impl &path = *_mPath[level];
+            uint32_t size = GetSize(path.field);
+            uint32_t offset = path.arrayOffset + size * path.index;
+            SetOffset(path.field, offset);
+            if (level) {
+                // reset child's array offset to fall within current index, but hold onto the
+                // original value of the arrayOffset so that we can adjust subsequent children.
+                // This is because the modulo is only defined within the current array.
+                uint32_t childArrayOffset =
+                    offset + (_mPath[level - 1]->arrayOffset - oldArrayOffset) % size;
+                oldArrayOffset = _mPath[level - 1]->arrayOffset;
+                _mPath[level - 1]->arrayOffset = childArrayOffset;
+            }
+        }
+    }
+
+    std::vector<std::shared_ptr<C2FieldUtils::Info::Impl>> _mPath;
+};
+
+/**
+ * Iterable implementing enumerateFields().
+ */
+struct C2FieldUtilsCousinsIterable : public C2FieldUtils::List::Impl {
+    /// returns an iterator to the beginning of the list
+    virtual std::shared_ptr<C2FieldUtils::Iterator::Impl> begin() const override {
+        return std::make_shared<C2FieldUtilsCousinsIterator>(_mHead, _mLevel);
+    };
+
+    C2FieldUtilsCousinsIterable(const C2FieldUtils::Info &field, uint32_t level)
+        : _mHead(C2FieldUtils::_Inspector::GetImpl(field)), _mLevel(level) { }
+
+private:
+    std::shared_ptr<C2FieldUtils::Info::Impl> _mHead;
+    size_t _mLevel;
+};
+
+}
+
+C2FieldUtils::List C2FieldUtils::enumerateCousins(const C2FieldUtils::Info &field, uint32_t level) {
+    return C2FieldUtils::List(std::make_shared<C2FieldUtilsCousinsIterable>(field, level));
+}
+
+/* ------------------------- C2FieldUtils::locateField ------------------------- */
+
+namespace {
+
+/**
+ * Iterator implementing locateField().
+ */
+struct C2FieldUtilsFieldLocator : public C2FieldUtilsFieldsIteratorHelper {
+    C2FieldUtilsFieldLocator(
+            C2Param::CoreIndex index, const _C2FieldId &field, uint32_t paramSize,
+            std::shared_ptr<C2ParamReflector> reflector)
+        : C2FieldUtilsFieldsIteratorHelper(reflector, paramSize),
+          _mField(field) {
+        while (descendInto(index)) {
+            if ((mHead->field.type() & C2FieldDescriptor::STRUCT_FLAG) == 0) {
+                break;
+            }
+            index = C2Param::CoreIndex(mHead->field.type() &~ C2FieldDescriptor::STRUCT_FLAG);
+        }
+    }
+
+    void increment() {
+        mHead = _mTail;
+        _mTail = nullptr;
+    }
+
+private:
+    /// If the current field is a known, valid (untraversed) structure, it modifies this iterator
+    /// to point to the field at the beginning/end of the given field of the structure and returns
+    /// true. Otherwise, including if no such field exists in the structure, it does not modify this
+    /// iterator and returns false.
+    bool descendInto(C2Param::CoreIndex index) {
+        // check that the boundaries of the field to be located are still within the same parent
+        // field
+        if (mHead != _mTail) {
+            return false;
+        }
+
+        std::unique_ptr<C2StructDescriptor> descUnique = mReflector->describe(index);
+        // descend into known structs (as long as they have at least one field)
+        if (descUnique && descUnique->begin() != descUnique->end()) {
+            std::shared_ptr<C2StructDescriptor> desc(std::move(descUnique));
+            mHistory.emplace_back(desc);
+
+            uint32_t parentOffset = GetParentOffset(mHead);
+
+            // locate field using a dummy field descriptor
+            C2FieldDescriptor dummy = {
+                C2FieldDescriptor::BLOB, 1 /* extent */, "name",
+                GetOffset(_mField) - parentOffset, GetSize(_mField)
+            };
+
+            // locate first field where offset is greater than dummy offset (which is one past)
+            auto it = std::upper_bound(
+                    desc->cbegin(), desc->cend(), dummy,
+                    [](const C2FieldDescriptor &a, const C2FieldDescriptor &b) -> bool {
+                return _C2ParamInspector::GetOffset(a) < _C2ParamInspector::GetOffset(b);
+            });
+            if (it == desc->begin()) {
+                // field is prior to first field
+                return false;
+            }
+            --it;
+            const C2FieldDescriptor &field = *it;
+
+            // check that dummy end-offset is within this field
+            uint32_t structSize = std::max(mParamSize, parentOffset) - parentOffset;
+            if (GetEndOffset(dummy) > GetEndOffset(field, structSize)) {
+                return false;
+            }
+
+            uint32_t startIndex = (GetOffset(dummy) - GetOffset(field)) / GetSize(field);
+            uint32_t endIndex =
+                (GetEndOffset(dummy) - GetOffset(field) + GetSize(field) - 1) / GetSize(field);
+            if (endIndex > startIndex) {
+                // Field size could be zero, in which case end index is still on start index.
+                // However, for all other cases, endIndex was rounded up to the next index, so
+                // decrement it.
+                --endIndex;
+            }
+            std::shared_ptr<C2FieldUtils::Info::Impl> startLeaf =
+                makeLeaf(field, startIndex);
+            if (endIndex == startIndex) {
+                _mTail = startLeaf;
+                mHead = startLeaf;
+            } else {
+                _mTail = makeLeaf(field, endIndex);
+                mHead = startLeaf;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    _C2FieldId _mField;
+    std::shared_ptr<C2FieldUtils::Info::Impl> _mTail;
+};
+
+/**
+ * Iterable implementing locateField().
+ */
+struct C2FieldUtilsFieldLocation : public C2FieldUtils::List::Impl {
+    /// returns an iterator to the beginning of the list
+    virtual std::shared_ptr<C2FieldUtils::Iterator::Impl> begin() const override {
+        return std::make_shared<C2FieldUtilsFieldLocator>(
+                _mIndex, _mField, _mParamSize, _mReflector);
+    };
+
+    C2FieldUtilsFieldLocation(
+            const C2ParamField &pf, std::shared_ptr<C2ParamReflector> reflector)
+        : _mIndex(C2Param::CoreIndex(_C2ParamInspector::GetIndex(pf))),
+          _mField(_C2ParamInspector::GetField(pf)),
+          _mParamSize(0),
+          _mReflector(reflector) { }
+
+
+    C2FieldUtilsFieldLocation(
+            const C2Param &param, const _C2FieldId &field,
+            std::shared_ptr<C2ParamReflector> reflector)
+        : _mIndex(param.coreIndex()),
+          _mField(field),
+          _mParamSize(param.size()),
+          _mReflector(reflector) { }
+
+private:
+    C2Param::CoreIndex _mIndex;
+    _C2FieldId _mField;
+    uint32_t _mParamSize;
+    std::shared_ptr<C2ParamReflector> _mReflector;
+};
+
+}
+
+std::vector<C2FieldUtils::Info> C2FieldUtils::locateField(
+        const C2ParamField &pf, const std::shared_ptr<C2ParamReflector> &reflector) {
+    C2FieldUtils::List location = { std::make_shared<C2FieldUtilsFieldLocation>(pf, reflector) };
+    return std::vector<Info>(location.begin(), location.end());
+}
+
+std::vector<C2FieldUtils::Info> C2FieldUtils::locateField(
+        const C2Param &param, const _C2FieldId &field,
+        const std::shared_ptr<C2ParamReflector> &reflector) {
+    C2FieldUtils::List location = {
+        std::make_shared<C2FieldUtilsFieldLocation>(param, field, reflector)
+    };
+    return std::vector<Info>(location.begin(), location.end());
+}
+
diff --git a/media/codec2/vndk/util/C2ParamUtils.cpp b/media/codec2/vndk/util/C2ParamUtils.cpp
new file mode 100644
index 0000000..80573d8
--- /dev/null
+++ b/media/codec2/vndk/util/C2ParamUtils.cpp
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define __C2_GENERATE_GLOBAL_VARS__ // to be able to implement the methods defined
+#include <C2Enum.h>
+#include <util/C2Debug-log.h>
+#include <util/C2ParamUtils.h>
+
+#include <utility>
+#include <vector>
+
+/** \file
+ * Utilities for parameter handling to be used by Codec2 implementations.
+ */
+
+/// \cond INTERNAL
+
+/* ---------------------------- UTILITIES FOR ENUMERATION REFLECTION ---------------------------- */
+
+static size_t countLeadingUnderscores(C2StringLiteral a) {
+    size_t i = 0;
+    while (a[i] == '_') {
+        ++i;
+    }
+    return i;
+}
+
+static size_t countMatching(C2StringLiteral a, const C2String &b) {
+    for (size_t i = 0; i < b.size(); ++i) {
+        if (!a[i] || a[i] != b[i]) {
+            return i;
+        }
+    }
+    return b.size();
+}
+
+// ABCDef => abc-def
+// ABCD2ef => abcd2-ef // 0
+// ABCD2Ef => ancd2-ef // -1
+// AbcDef => abc-def // -1
+// Abc2Def => abc-2def
+// Abc2def => abc-2-def
+// _Yo => _yo
+// _yo => _yo
+// C2_yo => c2-yo
+// C2__yo => c2-yo
+
+//static
+C2String _C2EnumUtils::camelCaseToDashed(C2String name) {
+    enum {
+        kNone = '.',
+        kLower = 'a',
+        kUpper = 'A',
+        kDigit = '1',
+        kDash = '-',
+        kUnderscore = '_',
+    } type = kNone;
+    size_t word_start = 0;
+    for (size_t ix = 0; ix < name.size(); ++ix) {
+        C2_LOG(VERBOSE) << name.substr(0, word_start) << "|"
+                << name.substr(word_start, ix - word_start) << "["
+                << name.substr(ix, 1) << "]" << name.substr(ix + 1)
+                << ": " << (char)type;
+        if (isupper(name[ix])) {
+            if (type == kLower) {
+                name.insert(ix++, 1, '-');
+                word_start = ix;
+            }
+            name[ix] = tolower(name[ix]);
+            type = kUpper;
+        } else if (islower(name[ix])) {
+            if (type == kDigit && ix > 0) {
+                name.insert(ix++, 1, '-');
+                word_start = ix;
+            } else if (type == kUpper && ix > word_start + 1) {
+                name.insert(ix++ - 1, 1, '-');
+                word_start = ix - 1;
+            }
+            type = kLower;
+        } else if (isdigit(name[ix])) {
+            if (type == kLower) {
+                name.insert(ix++, 1, '-');
+                word_start = ix;
+            }
+            type = kDigit;
+        } else if (name[ix] == '_') {
+            if (type == kDash) {
+                name.erase(ix--, 1);
+            } else if (type != kNone && type != kUnderscore) {
+                name[ix] = '-';
+                type = kDash;
+                word_start = ix + 1;
+            } else {
+                type = kUnderscore;
+                word_start = ix + 1;
+            }
+        } else {
+            name.resize(ix);
+        }
+    }
+    C2_LOG(VERBOSE) << "=> " << name;
+    return name;
+}
+
+//static
+std::vector<C2String> _C2EnumUtils::sanitizeEnumValueNames(
+        const std::vector<C2StringLiteral> names,
+        C2StringLiteral _prefix) {
+    std::vector<C2String> sanitizedNames;
+    C2String prefix;
+    size_t extraUnderscores = 0;
+    bool first = true;
+    if (_prefix) {
+        extraUnderscores = countLeadingUnderscores(_prefix);
+        prefix = _prefix + extraUnderscores;
+        first = false;
+        C2_LOG(VERBOSE) << "prefix:" << prefix << ", underscores:" << extraUnderscores;
+    }
+
+    // calculate prefix and minimum leading underscores
+    for (C2StringLiteral s : names) {
+        C2_LOG(VERBOSE) << s;
+        size_t underscores = countLeadingUnderscores(s);
+        if (first) {
+            extraUnderscores = underscores;
+            prefix = s + underscores;
+            first = false;
+        } else {
+            size_t matching = countMatching(
+                s + underscores,
+                prefix);
+            prefix.resize(matching);
+            extraUnderscores = std::min(underscores, extraUnderscores);
+        }
+        C2_LOG(VERBOSE) << "prefix:" << prefix << ", underscores:" << extraUnderscores;
+        if (prefix.size() == 0 && extraUnderscores == 0) {
+            break;
+        }
+    }
+
+    // we swallow the first underscore after upper case prefixes
+    bool upperCasePrefix = true;
+    for (size_t i = 0; i < prefix.size(); ++i) {
+        if (islower(prefix[i])) {
+            upperCasePrefix = false;
+            break;
+        }
+    }
+
+    for (C2StringLiteral s : names) {
+        size_t underscores = countLeadingUnderscores(s);
+        C2String sanitized = C2String(s, underscores - extraUnderscores);
+        sanitized.append(s + prefix.size() + underscores +
+                    (upperCasePrefix && s[prefix.size() + underscores] == '_'));
+        sanitizedNames.push_back(camelCaseToDashed(sanitized));
+    }
+
+    for (C2String s : sanitizedNames) {
+        C2_LOG(VERBOSE) << s;
+    }
+
+    return sanitizedNames;
+}
+
+//static
+std::vector<C2String> _C2EnumUtils::parseEnumValuesFromString(C2StringLiteral value) {
+    std::vector<C2String> foundNames;
+    size_t pos = 0, len = strlen(value);
+    do {
+        size_t endPos = strcspn(value + pos, " ,=") + pos;
+        if (endPos > pos) {
+            foundNames.emplace_back(value + pos, endPos - pos);
+        }
+        if (value[endPos] && value[endPos] != ',') {
+            endPos += strcspn(value + endPos, ",");
+        }
+        pos = strspn(value + endPos, " ,") + endPos;
+    } while (pos < len);
+    return foundNames;
+}
+
+/// safe(r) parsing from parameter blob
+//static
+C2Param *C2ParamUtils::ParseFirst(const uint8_t *blob, size_t size) {
+    // _mSize must fit into size, but really C2Param must also to be a valid param
+    if (size < sizeof(C2Param)) {
+        return nullptr;
+    }
+    // _mSize must match length
+    C2Param *param = (C2Param*)blob;
+    if (param->size() > size) {
+        return nullptr;
+    }
+    return param;
+}
+
diff --git a/media/common_time/Android.mk b/media/common_time/Android.mk
deleted file mode 100644
index aaa0db2..0000000
--- a/media/common_time/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-#
-# libcommon_time_client
-# (binder marshalers for ICommonClock as well as common clock and local clock
-# helper code)
-#
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libcommon_time_client
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := cc_helper.cpp \
-                   local_clock.cpp \
-                   ICommonClock.cpp \
-                   ICommonTimeConfig.cpp \
-                   utils.cpp
-LOCAL_SHARED_LIBRARIES := libbinder \
-                          libhardware \
-                          libutils \
-                          liblog
-
-LOCAL_CFLAGS := -Wall -Werror
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/media/common_time/ICommonClock.cpp b/media/common_time/ICommonClock.cpp
deleted file mode 100644
index f1f1fca..0000000
--- a/media/common_time/ICommonClock.cpp
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <sys/socket.h>
-
-#include <common_time/ICommonClock.h>
-#include <binder/Parcel.h>
-
-#include "utils.h"
-
-namespace android {
-
-/***** ICommonClock *****/
-
-enum {
-    IS_COMMON_TIME_VALID = IBinder::FIRST_CALL_TRANSACTION,
-    COMMON_TIME_TO_LOCAL_TIME,
-    LOCAL_TIME_TO_COMMON_TIME,
-    GET_COMMON_TIME,
-    GET_COMMON_FREQ,
-    GET_LOCAL_TIME,
-    GET_LOCAL_FREQ,
-    GET_ESTIMATED_ERROR,
-    GET_TIMELINE_ID,
-    GET_STATE,
-    GET_MASTER_ADDRESS,
-    REGISTER_LISTENER,
-    UNREGISTER_LISTENER,
-};
-
-const String16 ICommonClock::kServiceName("common_time.clock");
-const uint64_t ICommonClock::kInvalidTimelineID = 0;
-const int32_t ICommonClock::kErrorEstimateUnknown = 0x7FFFFFFF;
-
-class BpCommonClock : public BpInterface<ICommonClock>
-{
-  public:
-    explicit BpCommonClock(const sp<IBinder>& impl)
-        : BpInterface<ICommonClock>(impl) {}
-
-    virtual status_t isCommonTimeValid(bool* valid, uint32_t* timelineID) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
-        status_t status = remote()->transact(IS_COMMON_TIME_VALID,
-                                             data,
-                                             &reply);
-        if (status == OK) {
-            status = reply.readInt32();
-            if (status == OK) {
-                *valid = reply.readInt32();
-                *timelineID = reply.readInt32();
-            }
-        }
-        return status;
-    }
-
-    virtual status_t commonTimeToLocalTime(int64_t commonTime,
-            int64_t* localTime) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
-        data.writeInt64(commonTime);
-        status_t status = remote()->transact(COMMON_TIME_TO_LOCAL_TIME,
-                data, &reply);
-        if (status == OK) {
-            status = reply.readInt32();
-            if (status == OK) {
-                *localTime = reply.readInt64();
-            }
-        }
-        return status;
-    }
-
-    virtual status_t localTimeToCommonTime(int64_t localTime,
-            int64_t* commonTime) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
-        data.writeInt64(localTime);
-        status_t status = remote()->transact(LOCAL_TIME_TO_COMMON_TIME,
-                data, &reply);
-        if (status == OK) {
-            status = reply.readInt32();
-            if (status == OK) {
-                *commonTime = reply.readInt64();
-            }
-        }
-        return status;
-    }
-
-    virtual status_t getCommonTime(int64_t* commonTime) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
-        status_t status = remote()->transact(GET_COMMON_TIME, data, &reply);
-        if (status == OK) {
-            status = reply.readInt32();
-            if (status == OK) {
-                *commonTime = reply.readInt64();
-            }
-        }
-        return status;
-    }
-
-    virtual status_t getCommonFreq(uint64_t* freq) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
-        status_t status = remote()->transact(GET_COMMON_FREQ, data, &reply);
-        if (status == OK) {
-            status = reply.readInt32();
-            if (status == OK) {
-                *freq = reply.readInt64();
-            }
-        }
-        return status;
-    }
-
-    virtual status_t getLocalTime(int64_t* localTime) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
-        status_t status = remote()->transact(GET_LOCAL_TIME, data, &reply);
-        if (status == OK) {
-            status = reply.readInt32();
-            if (status == OK) {
-                *localTime = reply.readInt64();
-            }
-        }
-        return status;
-    }
-
-    virtual status_t getLocalFreq(uint64_t* freq) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
-        status_t status = remote()->transact(GET_LOCAL_FREQ, data, &reply);
-        if (status == OK) {
-            status = reply.readInt32();
-            if (status == OK) {
-                *freq = reply.readInt64();
-            }
-        }
-        return status;
-    }
-
-    virtual status_t getEstimatedError(int32_t* estimate) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
-        status_t status = remote()->transact(GET_ESTIMATED_ERROR, data, &reply);
-        if (status == OK) {
-            status = reply.readInt32();
-            if (status == OK) {
-                *estimate = reply.readInt32();
-            }
-        }
-        return status;
-    }
-
-    virtual status_t getTimelineID(uint64_t* id) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
-        status_t status = remote()->transact(GET_TIMELINE_ID, data, &reply);
-        if (status == OK) {
-            status = reply.readInt32();
-            if (status == OK) {
-                *id = static_cast<uint64_t>(reply.readInt64());
-            }
-        }
-        return status;
-    }
-
-    virtual status_t getState(State* state) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
-        status_t status = remote()->transact(GET_STATE, data, &reply);
-        if (status == OK) {
-            status = reply.readInt32();
-            if (status == OK) {
-                *state = static_cast<State>(reply.readInt32());
-            }
-        }
-        return status;
-    }
-
-    virtual status_t getMasterAddr(struct sockaddr_storage* addr) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
-        status_t status = remote()->transact(GET_MASTER_ADDRESS, data, &reply);
-        if (status == OK) {
-            status = reply.readInt32();
-            if (status == OK)
-                deserializeSockaddr(&reply, addr);
-        }
-        return status;
-    }
-
-    virtual status_t registerListener(
-            const sp<ICommonClockListener>& listener) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
-        data.writeStrongBinder(IInterface::asBinder(listener));
-
-        status_t status = remote()->transact(REGISTER_LISTENER, data, &reply);
-
-        if (status == OK) {
-            status = reply.readInt32();
-        }
-
-        return status;
-    }
-
-    virtual status_t unregisterListener(
-            const sp<ICommonClockListener>& listener) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
-        data.writeStrongBinder(IInterface::asBinder(listener));
-        status_t status = remote()->transact(UNREGISTER_LISTENER, data, &reply);
-
-        if (status == OK) {
-            status = reply.readInt32();
-        }
-
-        return status;
-    }
-};
-
-IMPLEMENT_META_INTERFACE(CommonClock, "android.os.ICommonClock");
-
-status_t BnCommonClock::onTransact(uint32_t code,
-                                   const Parcel& data,
-                                   Parcel* reply,
-                                   uint32_t flags) {
-    switch(code) {
-        case IS_COMMON_TIME_VALID: {
-            CHECK_INTERFACE(ICommonClock, data, reply);
-            bool valid;
-            uint32_t timelineID;
-            status_t status = isCommonTimeValid(&valid, &timelineID);
-            reply->writeInt32(status);
-            if (status == OK) {
-                reply->writeInt32(valid);
-                reply->writeInt32(timelineID);
-            }
-            return OK;
-        } break;
-
-        case COMMON_TIME_TO_LOCAL_TIME: {
-            CHECK_INTERFACE(ICommonClock, data, reply);
-            int64_t commonTime = data.readInt64();
-            int64_t localTime;
-            status_t status = commonTimeToLocalTime(commonTime, &localTime);
-            reply->writeInt32(status);
-            if (status == OK) {
-                reply->writeInt64(localTime);
-            }
-            return OK;
-        } break;
-
-        case LOCAL_TIME_TO_COMMON_TIME: {
-            CHECK_INTERFACE(ICommonClock, data, reply);
-            int64_t localTime = data.readInt64();
-            int64_t commonTime;
-            status_t status = localTimeToCommonTime(localTime, &commonTime);
-            reply->writeInt32(status);
-            if (status == OK) {
-                reply->writeInt64(commonTime);
-            }
-            return OK;
-        } break;
-
-        case GET_COMMON_TIME: {
-            CHECK_INTERFACE(ICommonClock, data, reply);
-            int64_t commonTime;
-            status_t status = getCommonTime(&commonTime);
-            reply->writeInt32(status);
-            if (status == OK) {
-                reply->writeInt64(commonTime);
-            }
-            return OK;
-        } break;
-
-        case GET_COMMON_FREQ: {
-            CHECK_INTERFACE(ICommonClock, data, reply);
-            uint64_t freq;
-            status_t status = getCommonFreq(&freq);
-            reply->writeInt32(status);
-            if (status == OK) {
-                reply->writeInt64(freq);
-            }
-            return OK;
-        } break;
-
-        case GET_LOCAL_TIME: {
-            CHECK_INTERFACE(ICommonClock, data, reply);
-            int64_t localTime;
-            status_t status = getLocalTime(&localTime);
-            reply->writeInt32(status);
-            if (status == OK) {
-                reply->writeInt64(localTime);
-            }
-            return OK;
-        } break;
-
-        case GET_LOCAL_FREQ: {
-            CHECK_INTERFACE(ICommonClock, data, reply);
-            uint64_t freq;
-            status_t status = getLocalFreq(&freq);
-            reply->writeInt32(status);
-            if (status == OK) {
-                reply->writeInt64(freq);
-            }
-            return OK;
-        } break;
-
-        case GET_ESTIMATED_ERROR: {
-            CHECK_INTERFACE(ICommonClock, data, reply);
-            int32_t error;
-            status_t status = getEstimatedError(&error);
-            reply->writeInt32(status);
-            if (status == OK) {
-                reply->writeInt32(error);
-            }
-            return OK;
-        } break;
-
-        case GET_TIMELINE_ID: {
-            CHECK_INTERFACE(ICommonClock, data, reply);
-            uint64_t id;
-            status_t status = getTimelineID(&id);
-            reply->writeInt32(status);
-            if (status == OK) {
-                reply->writeInt64(static_cast<int64_t>(id));
-            }
-            return OK;
-        } break;
-
-        case GET_STATE: {
-            CHECK_INTERFACE(ICommonClock, data, reply);
-            State state;
-            status_t status = getState(&state);
-            reply->writeInt32(status);
-            if (status == OK) {
-                reply->writeInt32(static_cast<int32_t>(state));
-            }
-            return OK;
-        } break;
-
-        case GET_MASTER_ADDRESS: {
-            CHECK_INTERFACE(ICommonClock, data, reply);
-            struct sockaddr_storage addr;
-            status_t status = getMasterAddr(&addr);
-
-            if ((status == OK) && !canSerializeSockaddr(&addr)) {
-                status = UNKNOWN_ERROR;
-            }
-
-            reply->writeInt32(status);
-
-            if (status == OK) {
-                serializeSockaddr(reply, &addr);
-            }
-
-            return OK;
-        } break;
-
-        case REGISTER_LISTENER: {
-            CHECK_INTERFACE(ICommonClock, data, reply);
-            sp<ICommonClockListener> listener =
-                interface_cast<ICommonClockListener>(data.readStrongBinder());
-            status_t status = registerListener(listener);
-            reply->writeInt32(status);
-            return OK;
-        } break;
-
-        case UNREGISTER_LISTENER: {
-            CHECK_INTERFACE(ICommonClock, data, reply);
-            sp<ICommonClockListener> listener =
-                interface_cast<ICommonClockListener>(data.readStrongBinder());
-            status_t status = unregisterListener(listener);
-            reply->writeInt32(status);
-            return OK;
-        } break;
-    }
-    return BBinder::onTransact(code, data, reply, flags);
-}
-
-/***** ICommonClockListener *****/
-
-enum {
-    ON_TIMELINE_CHANGED = IBinder::FIRST_CALL_TRANSACTION,
-};
-
-class BpCommonClockListener : public BpInterface<ICommonClockListener>
-{
-  public:
-    explicit BpCommonClockListener(const sp<IBinder>& impl)
-        : BpInterface<ICommonClockListener>(impl) {}
-
-    virtual void onTimelineChanged(uint64_t timelineID) {
-        Parcel data, reply;
-        data.writeInterfaceToken(
-                ICommonClockListener::getInterfaceDescriptor());
-        data.writeInt64(timelineID);
-        remote()->transact(ON_TIMELINE_CHANGED, data, &reply);
-    }
-};
-
-IMPLEMENT_META_INTERFACE(CommonClockListener,
-                         "android.os.ICommonClockListener");
-
-status_t BnCommonClockListener::onTransact(
-        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
-    switch(code) {
-        case ON_TIMELINE_CHANGED: {
-            CHECK_INTERFACE(ICommonClockListener, data, reply);
-            uint32_t timelineID = data.readInt64();
-            onTimelineChanged(timelineID);
-            return NO_ERROR;
-        } break;
-    }
-
-    return BBinder::onTransact(code, data, reply, flags);
-}
-
-}; // namespace android
diff --git a/media/common_time/ICommonTimeConfig.cpp b/media/common_time/ICommonTimeConfig.cpp
deleted file mode 100644
index e587b39..0000000
--- a/media/common_time/ICommonTimeConfig.cpp
+++ /dev/null
@@ -1,509 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <sys/socket.h>
-
-#include <common_time/ICommonTimeConfig.h>
-#include <binder/Parcel.h>
-
-#include "utils.h"
-
-namespace android {
-
-/***** ICommonTimeConfig *****/
-
-enum {
-    GET_MASTER_ELECTION_PRIORITY = IBinder::FIRST_CALL_TRANSACTION,
-    SET_MASTER_ELECTION_PRIORITY,
-    GET_MASTER_ELECTION_ENDPOINT,
-    SET_MASTER_ELECTION_ENDPOINT,
-    GET_MASTER_ELECTION_GROUP_ID,
-    SET_MASTER_ELECTION_GROUP_ID,
-    GET_INTERFACE_BINDING,
-    SET_INTERFACE_BINDING,
-    GET_MASTER_ANNOUNCE_INTERVAL,
-    SET_MASTER_ANNOUNCE_INTERVAL,
-    GET_CLIENT_SYNC_INTERVAL,
-    SET_CLIENT_SYNC_INTERVAL,
-    GET_PANIC_THRESHOLD,
-    SET_PANIC_THRESHOLD,
-    GET_AUTO_DISABLE,
-    SET_AUTO_DISABLE,
-    FORCE_NETWORKLESS_MASTER_MODE,
-};
-
-const String16 ICommonTimeConfig::kServiceName("common_time.config");
-
-class BpCommonTimeConfig : public BpInterface<ICommonTimeConfig>
-{
-  public:
-    explicit BpCommonTimeConfig(const sp<IBinder>& impl)
-        : BpInterface<ICommonTimeConfig>(impl) {}
-
-    virtual status_t getMasterElectionPriority(uint8_t *priority) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
-        status_t status = remote()->transact(GET_MASTER_ELECTION_PRIORITY,
-                                             data,
-                                             &reply);
-        if (status == OK) {
-            status = reply.readInt32();
-            if (status == OK) {
-                *priority = static_cast<uint8_t>(reply.readInt32());
-            }
-        }
-
-        return status;
-    }
-
-    virtual status_t setMasterElectionPriority(uint8_t priority) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
-        data.writeInt32(static_cast<int32_t>(priority));
-        status_t status = remote()->transact(SET_MASTER_ELECTION_PRIORITY,
-                                             data,
-                                             &reply);
-        if (status == OK) {
-            status = reply.readInt32();
-        }
-
-        return status;
-    }
-
-    virtual status_t getMasterElectionEndpoint(struct sockaddr_storage *addr) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
-        status_t status = remote()->transact(GET_MASTER_ELECTION_ENDPOINT,
-                                             data,
-                                             &reply);
-        if (status == OK) {
-            status = reply.readInt32();
-            if (status == OK) {
-                deserializeSockaddr(&reply, addr);
-            }
-        }
-
-        return status;
-    }
-
-    virtual status_t setMasterElectionEndpoint(
-            const struct sockaddr_storage *addr) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
-        if (!canSerializeSockaddr(addr))
-            return BAD_VALUE;
-        if (NULL == addr) {
-            data.writeInt32(0);
-        } else {
-            data.writeInt32(1);
-            serializeSockaddr(&data, addr);
-        }
-        status_t status = remote()->transact(SET_MASTER_ELECTION_ENDPOINT,
-                                             data,
-                                             &reply);
-        if (status == OK) {
-            status = reply.readInt32();
-        }
-
-        return status;
-    }
-
-    virtual status_t getMasterElectionGroupId(uint64_t *id) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
-        status_t status = remote()->transact(GET_MASTER_ELECTION_GROUP_ID,
-                                             data,
-                                             &reply);
-
-        if (status == OK) {
-            status = reply.readInt32();
-            if (status == OK) {
-                *id = static_cast<uint64_t>(reply.readInt64());
-            }
-        }
-
-        return status;
-    }
-
-    virtual status_t setMasterElectionGroupId(uint64_t id) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
-        data.writeInt64(id);
-        status_t status = remote()->transact(SET_MASTER_ELECTION_GROUP_ID,
-                                             data,
-                                             &reply);
-
-        if (status == OK) {
-            status = reply.readInt32();
-        }
-
-        return status;
-    }
-
-    virtual status_t getInterfaceBinding(String16& ifaceName) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
-        status_t status = remote()->transact(GET_INTERFACE_BINDING,
-                                             data,
-                                             &reply);
-        if (status == OK) {
-            status = reply.readInt32();
-            if (status == OK) {
-                ifaceName = reply.readString16();
-            }
-        }
-
-        return status;
-    }
-
-    virtual status_t setInterfaceBinding(const String16& ifaceName) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
-        data.writeString16(ifaceName);
-        status_t status = remote()->transact(SET_INTERFACE_BINDING,
-                                             data,
-                                             &reply);
-        if (status == OK) {
-            status = reply.readInt32();
-        }
-
-        return status;
-    }
-
-    virtual status_t getMasterAnnounceInterval(int *interval) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
-        status_t status = remote()->transact(GET_MASTER_ANNOUNCE_INTERVAL,
-                                             data,
-                                             &reply);
-        if (status == OK) {
-            status = reply.readInt32();
-            if (status == OK) {
-                *interval = reply.readInt32();
-            }
-        }
-
-        return status;
-    }
-
-    virtual status_t setMasterAnnounceInterval(int interval) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
-        data.writeInt32(interval);
-        status_t status = remote()->transact(SET_MASTER_ANNOUNCE_INTERVAL,
-                                             data,
-                                             &reply);
-        if (status == OK) {
-            status = reply.readInt32();
-        }
-
-        return status;
-    }
-
-    virtual status_t getClientSyncInterval(int *interval) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
-        status_t status = remote()->transact(GET_CLIENT_SYNC_INTERVAL,
-                                             data,
-                                             &reply);
-        if (status == OK) {
-            status = reply.readInt32();
-            if (status == OK) {
-                *interval = reply.readInt32();
-            }
-        }
-
-        return status;
-    }
-
-    virtual status_t setClientSyncInterval(int interval) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
-        data.writeInt32(interval);
-        status_t status = remote()->transact(SET_CLIENT_SYNC_INTERVAL,
-                                             data,
-                                             &reply);
-        if (status == OK) {
-            status = reply.readInt32();
-        }
-
-        return status;
-    }
-
-    virtual status_t getPanicThreshold(int *threshold) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
-        status_t status = remote()->transact(GET_PANIC_THRESHOLD,
-                                             data,
-                                             &reply);
-        if (status == OK) {
-            status = reply.readInt32();
-            if (status == OK) {
-                *threshold = reply.readInt32();
-            }
-        }
-
-        return status;
-    }
-
-    virtual status_t setPanicThreshold(int threshold) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
-        data.writeInt32(threshold);
-        status_t status = remote()->transact(SET_PANIC_THRESHOLD,
-                                             data,
-                                             &reply);
-        if (status == OK) {
-            status = reply.readInt32();
-        }
-
-        return status;
-    }
-
-    virtual status_t getAutoDisable(bool *autoDisable) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
-        status_t status = remote()->transact(GET_AUTO_DISABLE,
-                                             data,
-                                             &reply);
-        if (status == OK) {
-            status = reply.readInt32();
-            if (status == OK) {
-                *autoDisable = (0 != reply.readInt32());
-            }
-        }
-
-        return status;
-    }
-
-    virtual status_t setAutoDisable(bool autoDisable) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
-        data.writeInt32(autoDisable ? 1 : 0);
-        status_t status = remote()->transact(SET_AUTO_DISABLE,
-                                             data,
-                                             &reply);
-
-        if (status == OK) {
-            status = reply.readInt32();
-        }
-
-        return status;
-    }
-
-    virtual status_t forceNetworklessMasterMode() {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
-        status_t status = remote()->transact(FORCE_NETWORKLESS_MASTER_MODE,
-                                             data,
-                                             &reply);
-
-        if (status == OK) {
-            status = reply.readInt32();
-        }
-
-        return status;
-    }
-};
-
-IMPLEMENT_META_INTERFACE(CommonTimeConfig, "android.os.ICommonTimeConfig");
-
-status_t BnCommonTimeConfig::onTransact(uint32_t code,
-                                   const Parcel& data,
-                                   Parcel* reply,
-                                   uint32_t flags) {
-    switch(code) {
-        case GET_MASTER_ELECTION_PRIORITY: {
-            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
-            uint8_t priority;
-            status_t status = getMasterElectionPriority(&priority);
-            reply->writeInt32(status);
-            if (status == OK) {
-                reply->writeInt32(static_cast<int32_t>(priority));
-            }
-            return OK;
-        } break;
-
-        case SET_MASTER_ELECTION_PRIORITY: {
-            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
-            uint8_t priority = static_cast<uint8_t>(data.readInt32());
-            status_t status = setMasterElectionPriority(priority);
-            reply->writeInt32(status);
-            return OK;
-        } break;
-
-        case GET_MASTER_ELECTION_ENDPOINT: {
-            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
-            struct sockaddr_storage addr;
-            status_t status = getMasterElectionEndpoint(&addr);
-
-            if ((status == OK) && !canSerializeSockaddr(&addr)) {
-                status = UNKNOWN_ERROR;
-            }
-
-            reply->writeInt32(status);
-
-            if (status == OK) {
-                serializeSockaddr(reply, &addr);
-            }
-
-            return OK;
-        } break;
-
-        case SET_MASTER_ELECTION_ENDPOINT: {
-            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
-            struct sockaddr_storage addr;
-            int hasAddr = data.readInt32();
-
-            status_t status;
-            if (hasAddr) {
-                deserializeSockaddr(&data, &addr);
-                status = setMasterElectionEndpoint(&addr);
-            } else {
-                status = setMasterElectionEndpoint(&addr);
-            }
-
-            reply->writeInt32(status);
-            return OK;
-        } break;
-
-        case GET_MASTER_ELECTION_GROUP_ID: {
-            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
-            uint64_t id;
-            status_t status = getMasterElectionGroupId(&id);
-            reply->writeInt32(status);
-            if (status == OK) {
-                reply->writeInt64(id);
-            }
-            return OK;
-        } break;
-
-        case SET_MASTER_ELECTION_GROUP_ID: {
-            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
-            uint64_t id = static_cast<uint64_t>(data.readInt64());
-            status_t status = setMasterElectionGroupId(id);
-            reply->writeInt32(status);
-            return OK;
-        } break;
-
-        case GET_INTERFACE_BINDING: {
-            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
-            String16 ret;
-            status_t status = getInterfaceBinding(ret);
-            reply->writeInt32(status);
-            if (status == OK) {
-                reply->writeString16(ret);
-            }
-            return OK;
-        } break;
-
-        case SET_INTERFACE_BINDING: {
-            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
-            String16 ifaceName;
-            ifaceName = data.readString16();
-            status_t status = setInterfaceBinding(ifaceName);
-            reply->writeInt32(status);
-            return OK;
-        } break;
-
-        case GET_MASTER_ANNOUNCE_INTERVAL: {
-            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
-            int interval;
-            status_t status = getMasterAnnounceInterval(&interval);
-            reply->writeInt32(status);
-            if (status == OK) {
-                reply->writeInt32(interval);
-            }
-            return OK;
-        } break;
-
-        case SET_MASTER_ANNOUNCE_INTERVAL: {
-            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
-            int interval = data.readInt32();
-            status_t status = setMasterAnnounceInterval(interval);
-            reply->writeInt32(status);
-            return OK;
-        } break;
-
-        case GET_CLIENT_SYNC_INTERVAL: {
-            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
-            int interval;
-            status_t status = getClientSyncInterval(&interval);
-            reply->writeInt32(status);
-            if (status == OK) {
-                reply->writeInt32(interval);
-            }
-            return OK;
-        } break;
-
-        case SET_CLIENT_SYNC_INTERVAL: {
-            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
-            int interval = data.readInt32();
-            status_t status = setClientSyncInterval(interval);
-            reply->writeInt32(status);
-            return OK;
-        } break;
-
-        case GET_PANIC_THRESHOLD: {
-            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
-            int threshold;
-            status_t status = getPanicThreshold(&threshold);
-            reply->writeInt32(status);
-            if (status == OK) {
-                reply->writeInt32(threshold);
-            }
-            return OK;
-        } break;
-
-        case SET_PANIC_THRESHOLD: {
-            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
-            int threshold = data.readInt32();
-            status_t status = setPanicThreshold(threshold);
-            reply->writeInt32(status);
-            return OK;
-        } break;
-
-        case GET_AUTO_DISABLE: {
-            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
-            bool autoDisable;
-            status_t status = getAutoDisable(&autoDisable);
-            reply->writeInt32(status);
-            if (status == OK) {
-                reply->writeInt32(autoDisable ? 1 : 0);
-            }
-            return OK;
-        } break;
-
-        case SET_AUTO_DISABLE: {
-            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
-            bool autoDisable = (0 != data.readInt32());
-            status_t status = setAutoDisable(autoDisable);
-            reply->writeInt32(status);
-            return OK;
-        } break;
-
-        case FORCE_NETWORKLESS_MASTER_MODE: {
-            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
-            status_t status = forceNetworklessMasterMode();
-            reply->writeInt32(status);
-            return OK;
-        } break;
-    }
-    return BBinder::onTransact(code, data, reply, flags);
-}
-
-}; // namespace android
-
diff --git a/media/common_time/cc_helper.cpp b/media/common_time/cc_helper.cpp
deleted file mode 100644
index 6a7de74..0000000
--- a/media/common_time/cc_helper.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdint.h>
-
-#include <common_time/cc_helper.h>
-#include <common_time/ICommonClock.h>
-#include <utils/threads.h>
-
-namespace android {
-
-Mutex CCHelper::lock_;
-sp<ICommonClock> CCHelper::common_clock_;
-sp<ICommonClockListener> CCHelper::common_clock_listener_;
-uint32_t CCHelper::ref_count_ = 0;
-
-bool CCHelper::verifyClock_l() {
-    bool ret = false;
-
-    if (common_clock_ == NULL) {
-        common_clock_ = ICommonClock::getInstance();
-        if (common_clock_ == NULL)
-            goto bailout;
-    }
-
-    if (ref_count_ > 0) {
-        if (common_clock_listener_ == NULL) {
-            common_clock_listener_ = new CommonClockListener();
-            if (common_clock_listener_ == NULL)
-                goto bailout;
-
-            if (OK != common_clock_->registerListener(common_clock_listener_))
-                goto bailout;
-        }
-    }
-
-    ret = true;
-
-bailout:
-    if (!ret) {
-        common_clock_listener_ = NULL;
-        common_clock_ = NULL;
-    }
-    return ret;
-}
-
-CCHelper::CCHelper() {
-    Mutex::Autolock lock(&lock_);
-    ref_count_++;
-    verifyClock_l();
-}
-
-CCHelper::~CCHelper() {
-    Mutex::Autolock lock(&lock_);
-
-    assert(ref_count_ > 0);
-    ref_count_--;
-
-    // If we were the last CCHelper instance in the system, and we had
-    // previously register a listener, unregister it now so that the common time
-    // service has the chance to go into auto-disabled mode.
-    if (!ref_count_ &&
-       (common_clock_ != NULL) &&
-       (common_clock_listener_ != NULL)) {
-        common_clock_->unregisterListener(common_clock_listener_);
-        common_clock_listener_ = NULL;
-    }
-}
-
-void CCHelper::CommonClockListener::onTimelineChanged(uint64_t /*timelineID*/) {
-    // do nothing; listener is only really used as a token so the server can
-    // find out when clients die.
-}
-
-// Helper methods which attempts to make calls to the common time binder
-// service.  If the first attempt fails with DEAD_OBJECT, the helpers will
-// attempt to make a connection to the service again (assuming that the process
-// hosting the service had crashed and the client proxy we are holding is dead)
-// If the second attempt fails, or no connection can be made, the we let the
-// error propagate up the stack and let the caller deal with the situation as
-// best they can.
-#define CCHELPER_METHOD(decl, call)                 \
-    status_t CCHelper::decl {                       \
-        Mutex::Autolock lock(&lock_);               \
-                                                    \
-        if (!verifyClock_l())                       \
-            return DEAD_OBJECT;                     \
-                                                    \
-        status_t status = common_clock_->call;      \
-        if (DEAD_OBJECT == status) {                \
-            if (!verifyClock_l())                   \
-                return DEAD_OBJECT;                 \
-            status = common_clock_->call;           \
-        }                                           \
-                                                    \
-        return status;                              \
-    }
-
-#define VERIFY_CLOCK()
-
-CCHELPER_METHOD(isCommonTimeValid(bool* valid, uint32_t* timelineID),
-                isCommonTimeValid(valid, timelineID))
-CCHELPER_METHOD(commonTimeToLocalTime(int64_t commonTime, int64_t* localTime),
-                commonTimeToLocalTime(commonTime, localTime))
-CCHELPER_METHOD(localTimeToCommonTime(int64_t localTime, int64_t* commonTime),
-                localTimeToCommonTime(localTime, commonTime))
-CCHELPER_METHOD(getCommonTime(int64_t* commonTime),
-                getCommonTime(commonTime))
-CCHELPER_METHOD(getCommonFreq(uint64_t* freq),
-                getCommonFreq(freq))
-CCHELPER_METHOD(getLocalTime(int64_t* localTime),
-                getLocalTime(localTime))
-CCHELPER_METHOD(getLocalFreq(uint64_t* freq),
-                getLocalFreq(freq))
-
-}  // namespace android
diff --git a/media/common_time/local_clock.cpp b/media/common_time/local_clock.cpp
deleted file mode 100644
index a7c61fc..0000000
--- a/media/common_time/local_clock.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "common_time"
-#include <utils/Log.h>
-
-#include <assert.h>
-#include <stdint.h>
-
-#include <common_time/local_clock.h>
-#include <hardware/hardware.h>
-#include <hardware/local_time_hal.h>
-#include <utils/Errors.h>
-#include <utils/threads.h>
-
-namespace android {
-
-Mutex LocalClock::dev_lock_;
-local_time_hw_device_t* LocalClock::dev_ = NULL;
-
-LocalClock::LocalClock() {
-    int res;
-    const hw_module_t* mod;
-
-    AutoMutex lock(&dev_lock_);
-
-    if (dev_ != NULL)
-        return;
-
-    res = hw_get_module_by_class(LOCAL_TIME_HARDWARE_MODULE_ID, NULL, &mod);
-    if (res) {
-        ALOGE("Failed to open local time HAL module (res = %d)", res);
-    } else {
-        res = local_time_hw_device_open(mod, &dev_);
-        if (res) {
-            ALOGE("Failed to open local time HAL device (res = %d)", res);
-            dev_ = NULL;
-        }
-    }
-}
-
-bool LocalClock::initCheck() {
-    return (NULL != dev_);
-}
-
-int64_t LocalClock::getLocalTime() {
-    assert(NULL != dev_);
-    assert(NULL != dev_->get_local_time);
-
-    return dev_->get_local_time(dev_);
-}
-
-uint64_t LocalClock::getLocalFreq() {
-    assert(NULL != dev_);
-    assert(NULL != dev_->get_local_freq);
-
-    return dev_->get_local_freq(dev_);
-}
-
-status_t LocalClock::setLocalSlew(int16_t rate) {
-    assert(NULL != dev_);
-
-    if (!dev_->set_local_slew)
-        return INVALID_OPERATION;
-
-    return static_cast<status_t>(dev_->set_local_slew(dev_, rate));
-}
-
-int32_t LocalClock::getDebugLog(struct local_time_debug_event* records,
-                                int max_records) {
-    assert(NULL != dev_);
-
-    if (!dev_->get_debug_log)
-        return INVALID_OPERATION;
-
-    return dev_->get_debug_log(dev_, records, max_records);
-}
-
-}  // namespace android
diff --git a/media/common_time/utils.cpp b/media/common_time/utils.cpp
deleted file mode 100644
index 91cf2fd..0000000
--- a/media/common_time/utils.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <arpa/inet.h>
-#include <linux/socket.h>
-
-#include <binder/Parcel.h>
-
-namespace android {
-
-bool canSerializeSockaddr(const struct sockaddr_storage* addr) {
-    switch (addr->ss_family) {
-        case AF_INET:
-        case AF_INET6:
-            return true;
-        default:
-            return false;
-    }
-}
-
-void serializeSockaddr(Parcel* p, const struct sockaddr_storage* addr) {
-    switch (addr->ss_family) {
-        case AF_INET: {
-            const struct sockaddr_in* s =
-                reinterpret_cast<const struct sockaddr_in*>(addr);
-            p->writeInt32(AF_INET);
-            p->writeInt32(ntohl(s->sin_addr.s_addr));
-            p->writeInt32(static_cast<int32_t>(ntohs(s->sin_port)));
-        } break;
-
-        case AF_INET6: {
-            const struct sockaddr_in6* s =
-                reinterpret_cast<const struct sockaddr_in6*>(addr);
-            const int32_t* a =
-                reinterpret_cast<const int32_t*>(s->sin6_addr.s6_addr);
-            p->writeInt32(AF_INET6);
-            p->writeInt32(ntohl(a[0]));
-            p->writeInt32(ntohl(a[1]));
-            p->writeInt32(ntohl(a[2]));
-            p->writeInt32(ntohl(a[3]));
-            p->writeInt32(static_cast<int32_t>(ntohs(s->sin6_port)));
-            p->writeInt32(ntohl(s->sin6_flowinfo));
-            p->writeInt32(ntohl(s->sin6_scope_id));
-        } break;
-    }
-}
-
-void deserializeSockaddr(const Parcel* p, struct sockaddr_storage* addr) {
-    memset(addr, 0, sizeof(*addr));
-
-    addr->ss_family = p->readInt32();
-    switch(addr->ss_family) {
-        case AF_INET: {
-            struct sockaddr_in* s =
-                reinterpret_cast<struct sockaddr_in*>(addr);
-            s->sin_addr.s_addr = htonl(p->readInt32());
-            s->sin_port = htons(static_cast<uint16_t>(p->readInt32()));
-        } break;
-
-        case AF_INET6: {
-            struct sockaddr_in6* s =
-                reinterpret_cast<struct sockaddr_in6*>(addr);
-            int32_t* a = reinterpret_cast<int32_t*>(s->sin6_addr.s6_addr);
-
-            a[0] = htonl(p->readInt32());
-            a[1] = htonl(p->readInt32());
-            a[2] = htonl(p->readInt32());
-            a[3] = htonl(p->readInt32());
-            s->sin6_port = htons(static_cast<uint16_t>(p->readInt32()));
-            s->sin6_flowinfo = htonl(p->readInt32());
-            s->sin6_scope_id = htonl(p->readInt32());
-        } break;
-    }
-}
-
-}  // namespace android
diff --git a/media/common_time/utils.h b/media/common_time/utils.h
deleted file mode 100644
index ce79d0d..0000000
--- a/media/common_time/utils.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_LIBCOMMONCLOCK_UTILS_H
-#define ANDROID_LIBCOMMONCLOCK_UTILS_H
-
-#include <linux/socket.h>
-
-#include <binder/Parcel.h>
-#include <utils/Errors.h>
-
-namespace android {
-
-extern bool canSerializeSockaddr(const struct sockaddr_storage* addr);
-extern void serializeSockaddr(Parcel* p, const struct sockaddr_storage* addr);
-extern status_t deserializeSockaddr(const Parcel* p,
-                                    struct sockaddr_storage* addr);
-
-};  // namespace android
-
-#endif  // ANDROID_LIBCOMMONCLOCK_UTILS_H
diff --git a/media/extractors/Android.bp b/media/extractors/Android.bp
deleted file mode 100644
index e8176cf..0000000
--- a/media/extractors/Android.bp
+++ /dev/null
@@ -1,3 +0,0 @@
-subdirs = [
-    "*",
-]
diff --git a/media/extractors/aac/AACExtractor.cpp b/media/extractors/aac/AACExtractor.cpp
index 9fc5a76..5d00d94 100644
--- a/media/extractors/aac/AACExtractor.cpp
+++ b/media/extractors/aac/AACExtractor.cpp
@@ -19,48 +19,45 @@
 #include <utils/Log.h>
 
 #include "AACExtractor.h"
-#include <media/DataSourceBase.h>
-#include <media/MediaTrack.h>
+#include <media/MediaExtractorPluginApi.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/MediaBufferGroup.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/MetaData.h>
 #include <media/stagefright/MetaDataUtils.h>
 #include <utils/String8.h>
 
 namespace android {
 
-class AACSource : public MediaTrack {
+class AACSource : public MediaTrackHelper {
 public:
     AACSource(
-            DataSourceBase *source,
-            MetaDataBase &meta,
+            DataSourceHelper *source,
+            AMediaFormat *meta,
             const Vector<uint64_t> &offset_vector,
             int64_t frame_duration_us);
 
-    virtual status_t start(MetaDataBase *params = NULL);
-    virtual status_t stop();
+    virtual media_status_t start();
+    virtual media_status_t stop();
 
-    virtual status_t getFormat(MetaDataBase&);
+    virtual media_status_t getFormat(AMediaFormat*);
 
-    virtual status_t read(
-            MediaBufferBase **buffer, const ReadOptions *options = NULL);
+    virtual media_status_t read(
+            MediaBufferHelper **buffer, const ReadOptions *options = NULL);
 
 protected:
     virtual ~AACSource();
 
 private:
     static const size_t kMaxFrameSize;
-    DataSourceBase *mDataSource;
-    MetaDataBase mMeta;
+    DataSourceHelper *mDataSource;
+    AMediaFormat *mMeta;
 
     off64_t mOffset;
     int64_t mCurrentTimeUs;
     bool mStarted;
-    MediaBufferGroup *mGroup;
 
     Vector<uint64_t> mOffsetVector;
     int64_t mFrameDurationUs;
@@ -92,7 +89,7 @@
 // The returned value is the AAC frame size with the ADTS header length (regardless of
 //     the presence of the CRC).
 // If headerSize is non-NULL, it will be used to return the size of the header of this ADTS frame.
-static size_t getAdtsFrameLength(DataSourceBase *source, off64_t offset, size_t* headerSize) {
+static size_t getAdtsFrameLength(DataSourceHelper *source, off64_t offset, size_t* headerSize) {
 
     const size_t kAdtsHeaderLengthNoCrc = 7;
     const size_t kAdtsHeaderLengthWithCrc = 9;
@@ -133,8 +130,9 @@
 }
 
 AACExtractor::AACExtractor(
-        DataSourceBase *source, off64_t offset)
+        DataSourceHelper *source, off64_t offset)
     : mDataSource(source),
+      mMeta(nullptr),
       mInitCheck(NO_INIT),
       mFrameDurationUs(0) {
 
@@ -151,7 +149,9 @@
     }
     channel = (header[0] & 0x1) << 2 | (header[1] >> 6);
 
+    mMeta = AMediaFormat_new();
     MakeAACCodecSpecificData(mMeta, profile, sf_index, channel);
+    AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_AAC_PROFILE, profile + 1);
 
     off64_t streamSize, numFrames = 0;
     size_t frameSize = 0;
@@ -174,29 +174,32 @@
         // Round up and get the duration
         mFrameDurationUs = (1024 * 1000000ll + (sr - 1)) / sr;
         duration = numFrames * mFrameDurationUs;
-        mMeta.setInt64(kKeyDuration, duration);
+        AMediaFormat_setInt64(mMeta, AMEDIAFORMAT_KEY_DURATION, duration);
     }
 
     mInitCheck = OK;
 }
 
 AACExtractor::~AACExtractor() {
+    if (mMeta != nullptr) {
+        AMediaFormat_delete(mMeta);
+    }
 }
 
-status_t AACExtractor::getMetaData(MetaDataBase &meta) {
-    meta.clear();
+media_status_t AACExtractor::getMetaData(AMediaFormat *meta) {
+    AMediaFormat_clear(meta);
     if (mInitCheck == OK) {
-        meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC_ADTS);
+        AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_AAC_ADTS);
     }
 
-    return OK;
+    return AMEDIA_OK;
 }
 
 size_t AACExtractor::countTracks() {
     return mInitCheck == OK ? 1 : 0;
 }
 
-MediaTrack *AACExtractor::getTrack(size_t index) {
+MediaTrackHelper *AACExtractor::getTrack(size_t index) {
     if (mInitCheck != OK || index != 0) {
         return NULL;
     }
@@ -204,13 +207,12 @@
     return new AACSource(mDataSource, mMeta, mOffsetVector, mFrameDurationUs);
 }
 
-status_t AACExtractor::getTrackMetaData(MetaDataBase &meta, size_t index, uint32_t /* flags */) {
+media_status_t AACExtractor::getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t /* flags */) {
     if (mInitCheck != OK || index != 0) {
-        return UNKNOWN_ERROR;
+        return AMEDIA_ERROR_UNKNOWN;
     }
 
-    meta = mMeta;
-    return OK;
+    return AMediaFormat_copy(meta, mMeta);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -219,8 +221,8 @@
 const size_t AACSource::kMaxFrameSize = 8192;
 
 AACSource::AACSource(
-        DataSourceBase *source,
-        MetaDataBase &meta,
+        DataSourceHelper *source,
+        AMediaFormat *meta,
         const Vector<uint64_t> &offset_vector,
         int64_t frame_duration_us)
     : mDataSource(source),
@@ -228,7 +230,6 @@
       mOffset(0),
       mCurrentTimeUs(0),
       mStarted(false),
-      mGroup(NULL),
       mOffsetVector(offset_vector),
       mFrameDurationUs(frame_duration_us) {
 }
@@ -239,7 +240,7 @@
     }
 }
 
-status_t AACSource::start(MetaDataBase * /* params */) {
+media_status_t AACSource::start() {
     CHECK(!mStarted);
 
     if (mOffsetVector.empty()) {
@@ -249,30 +250,25 @@
     }
 
     mCurrentTimeUs = 0;
-    mGroup = new MediaBufferGroup;
-    mGroup->add_buffer(MediaBufferBase::Create(kMaxFrameSize));
+    mBufferGroup->add_buffer(kMaxFrameSize);
     mStarted = true;
 
-    return OK;
+    return AMEDIA_OK;
 }
 
-status_t AACSource::stop() {
+media_status_t AACSource::stop() {
     CHECK(mStarted);
 
-    delete mGroup;
-    mGroup = NULL;
-
     mStarted = false;
-    return OK;
+    return AMEDIA_OK;
 }
 
-status_t AACSource::getFormat(MetaDataBase &meta) {
-    meta = mMeta;
-    return OK;
+media_status_t AACSource::getFormat(AMediaFormat *meta) {
+    return AMediaFormat_copy(meta, mMeta);
 }
 
-status_t AACSource::read(
-        MediaBufferBase **out, const ReadOptions *options) {
+media_status_t AACSource::read(
+        MediaBufferHelper **out, const ReadOptions *options) {
     *out = NULL;
 
     int64_t seekTimeUs;
@@ -282,7 +278,7 @@
             int64_t seekFrame = seekTimeUs / mFrameDurationUs;
             if (seekFrame < 0 || seekFrame >= (int64_t)mOffsetVector.size()) {
                 android_errorWriteLog(0x534e4554, "70239507");
-                return ERROR_MALFORMED;
+                return AMEDIA_ERROR_MALFORMED;
             }
             mCurrentTimeUs = seekFrame * mFrameDurationUs;
 
@@ -292,13 +288,13 @@
 
     size_t frameSize, frameSizeWithoutHeader, headerSize;
     if ((frameSize = getAdtsFrameLength(mDataSource, mOffset, &headerSize)) == 0) {
-        return ERROR_END_OF_STREAM;
+        return AMEDIA_ERROR_END_OF_STREAM;
     }
 
-    MediaBufferBase *buffer;
-    status_t err = mGroup->acquire_buffer(&buffer);
+    MediaBufferHelper *buffer;
+    status_t err = mBufferGroup->acquire_buffer(&buffer);
     if (err != OK) {
-        return err;
+        return AMEDIA_ERROR_UNKNOWN;
     }
 
     frameSizeWithoutHeader = frameSize - headerSize;
@@ -307,37 +303,39 @@
         buffer->release();
         buffer = NULL;
 
-        return ERROR_IO;
+        return AMEDIA_ERROR_IO;
     }
 
     buffer->set_range(0, frameSizeWithoutHeader);
-    buffer->meta_data().setInt64(kKeyTime, mCurrentTimeUs);
-    buffer->meta_data().setInt32(kKeyIsSyncFrame, 1);
+    AMediaFormat *meta = buffer->meta_data();
+    AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, mCurrentTimeUs);
+    AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
 
     mOffset += frameSize;
     mCurrentTimeUs += mFrameDurationUs;
 
     *out = buffer;
-    return OK;
+    return AMEDIA_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
-static MediaExtractor* CreateExtractor(
-        DataSourceBase *source,
+static CMediaExtractor* CreateExtractor(
+        CDataSource *source,
         void *meta) {
     off64_t offset = *static_cast<off64_t*>(meta);
-    return new AACExtractor(source, offset);
+    return wrap(new AACExtractor(new DataSourceHelper(source), offset));
 }
 
-static MediaExtractor::CreatorFunc Sniff(
-        DataSourceBase *source, float *confidence, void **meta,
-        MediaExtractor::FreeMetaFunc *freeMeta) {
+static CreatorFunc Sniff(
+        CDataSource *source, float *confidence, void **meta,
+        FreeMetaFunc *freeMeta) {
     off64_t pos = 0;
 
+    DataSourceHelper helper(source);
     for (;;) {
         uint8_t id3header[10];
-        if (source->readAt(pos, id3header, sizeof(id3header))
+        if (helper.readAt(pos, id3header, sizeof(id3header))
                 < (ssize_t)sizeof(id3header)) {
             return NULL;
         }
@@ -364,7 +362,7 @@
 
     uint8_t header[2];
 
-    if (source->readAt(pos, &header, 2) != 2) {
+    if (helper.readAt(pos, &header, 2) != 2) {
         return NULL;
     }
 
@@ -383,17 +381,21 @@
     return NULL;
 }
 
+static const char *extensions[] = {
+    "aac",
+    NULL
+};
 
 extern "C" {
 // This is the only symbol that needs to be exported
 __attribute__ ((visibility ("default")))
-MediaExtractor::ExtractorDef GETEXTRACTORDEF() {
+ExtractorDef GETEXTRACTORDEF() {
     return {
-        MediaExtractor::EXTRACTORDEF_VERSION,
+        EXTRACTORDEF_VERSION,
         UUID("4fd80eae-03d2-4d72-9eb9-48fa6bb54613"),
         1, // version
         "AAC Extractor",
-        Sniff
+        { .v3 = {Sniff, extensions} },
     };
 }
 
diff --git a/media/extractors/aac/AACExtractor.h b/media/extractors/aac/AACExtractor.h
index 9dadbed..643d3f4 100644
--- a/media/extractors/aac/AACExtractor.h
+++ b/media/extractors/aac/AACExtractor.h
@@ -18,8 +18,9 @@
 
 #define AAC_EXTRACTOR_H_
 
-#include <media/MediaExtractor.h>
-#include <media/stagefright/MetaDataBase.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
+#include <media/NdkMediaFormat.h>
 
 #include <utils/Vector.h>
 
@@ -28,23 +29,23 @@
 struct AMessage;
 class String8;
 
-class AACExtractor : public MediaExtractor {
+class AACExtractor : public MediaExtractorPluginHelper {
 public:
-    AACExtractor(DataSourceBase *source, off64_t offset);
+    AACExtractor(DataSourceHelper *source, off64_t offset);
 
     virtual size_t countTracks();
-    virtual MediaTrack *getTrack(size_t index);
-    virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags);
+    virtual MediaTrackHelper *getTrack(size_t index);
+    virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
 
-    virtual status_t getMetaData(MetaDataBase& meta);
+    virtual media_status_t getMetaData(AMediaFormat *meta);
     virtual const char * name() { return "AACExtractor"; }
 
 protected:
     virtual ~AACExtractor();
 
 private:
-    DataSourceBase *mDataSource;
-    MetaDataBase mMeta;
+    DataSourceHelper *mDataSource;
+    AMediaFormat *mMeta;
     status_t mInitCheck;
 
     Vector<uint64_t> mOffsetVector;
@@ -55,7 +56,7 @@
 };
 
 bool SniffAAC(
-        DataSourceBase *source, String8 *mimeType, float *confidence, off64_t *offset);
+        DataSourceHelper *source, String8 *mimeType, float *confidence, off64_t *offset);
 
 }  // namespace android
 
diff --git a/media/extractors/aac/Android.bp b/media/extractors/aac/Android.bp
index 5f05b42..a58167a 100644
--- a/media/extractors/aac/Android.bp
+++ b/media/extractors/aac/Android.bp
@@ -8,7 +8,7 @@
 
     shared_libs: [
         "liblog",
-        "libmediaextractor",
+        "libmediandk",
     ],
 
     static_libs: [
@@ -35,9 +35,6 @@
             "unsigned-integer-overflow",
             "signed-integer-overflow",
         ],
-        diag: {
-            cfi: true,
-        },
     },
 
 }
diff --git a/media/extractors/amr/AMRExtractor.cpp b/media/extractors/amr/AMRExtractor.cpp
index f56d5ef..ffeff42 100644
--- a/media/extractors/amr/AMRExtractor.cpp
+++ b/media/extractors/amr/AMRExtractor.cpp
@@ -20,8 +20,6 @@
 
 #include "AMRExtractor.h"
 
-#include <media/DataSourceBase.h>
-#include <media/MediaTrack.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/MediaBufferGroup.h>
 #include <media/stagefright/MediaDefs.h>
@@ -31,29 +29,29 @@
 
 namespace android {
 
-class AMRSource : public MediaTrack {
+class AMRSource : public MediaTrackHelper {
 public:
     AMRSource(
-            DataSourceBase *source,
-            MetaDataBase &meta,
+            DataSourceHelper *source,
+            AMediaFormat *meta,
             bool isWide,
             const off64_t *offset_table,
             size_t offset_table_length);
 
-    virtual status_t start(MetaDataBase *params = NULL);
-    virtual status_t stop();
+    virtual media_status_t start();
+    virtual media_status_t stop();
 
-    virtual status_t getFormat(MetaDataBase &);
+    virtual media_status_t getFormat(AMediaFormat *);
 
-    virtual status_t read(
-            MediaBufferBase **buffer, const ReadOptions *options = NULL);
+    virtual media_status_t read(
+            MediaBufferHelper **buffer, const ReadOptions *options = NULL);
 
 protected:
     virtual ~AMRSource();
 
 private:
-    DataSourceBase *mDataSource;
-    MetaDataBase mMeta;
+    DataSourceHelper *mDataSource;
+    AMediaFormat *mMeta;
     bool mIsWide;
 
     off64_t mOffset;
@@ -98,27 +96,27 @@
     return frameSize;
 }
 
-static status_t getFrameSizeByOffset(DataSourceBase *source,
+static media_status_t getFrameSizeByOffset(DataSourceHelper *source,
         off64_t offset, bool isWide, size_t *frameSize) {
     uint8_t header;
     ssize_t count = source->readAt(offset, &header, 1);
     if (count == 0) {
-        return ERROR_END_OF_STREAM;
+        return AMEDIA_ERROR_END_OF_STREAM;
     } else if (count < 0) {
-        return ERROR_IO;
+        return AMEDIA_ERROR_IO;
     }
 
     unsigned FT = (header >> 3) & 0x0f;
 
     *frameSize = getFrameSize(isWide, FT);
     if (*frameSize == 0) {
-        return ERROR_MALFORMED;
+        return AMEDIA_ERROR_MALFORMED;
     }
-    return OK;
+    return AMEDIA_OK;
 }
 
 static bool SniffAMR(
-        DataSourceBase *source, bool *isWide, float *confidence) {
+        DataSourceHelper *source, bool *isWide, float *confidence) {
     char header[9];
 
     if (source->readAt(0, header, sizeof(header)) != sizeof(header)) {
@@ -144,7 +142,7 @@
     return false;
 }
 
-AMRExtractor::AMRExtractor(DataSourceBase *source)
+AMRExtractor::AMRExtractor(DataSourceHelper *source)
     : mDataSource(source),
       mInitCheck(NO_INIT),
       mOffsetTableLength(0) {
@@ -153,12 +151,12 @@
         return;
     }
 
-    mMeta.setCString(
-            kKeyMIMEType, mIsWide ? MEDIA_MIMETYPE_AUDIO_AMR_WB
-                                  : MEDIA_MIMETYPE_AUDIO_AMR_NB);
+    mMeta = AMediaFormat_new();
+    AMediaFormat_setString(mMeta, AMEDIAFORMAT_KEY_MIME,
+            mIsWide ? MEDIA_MIMETYPE_AUDIO_AMR_WB : MEDIA_MIMETYPE_AUDIO_AMR_NB);
 
-    mMeta.setInt32(kKeyChannelCount, 1);
-    mMeta.setInt32(kKeySampleRate, mIsWide ? 16000 : 8000);
+    AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, 1);
+    AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_SAMPLE_RATE, mIsWide ? 16000 : 8000);
 
     off64_t offset = mIsWide ? 9 : 6;
     off64_t streamSize;
@@ -166,11 +164,11 @@
     int64_t duration = 0;
 
     if (mDataSource->getSize(&streamSize) == OK) {
-         while (offset < streamSize) {
-             status_t status = getFrameSizeByOffset(source, offset, mIsWide, &frameSize);
-             if (status == ERROR_END_OF_STREAM) {
-                 break;
-             } else if (status != OK) {
+        while (offset < streamSize) {
+            status_t status = getFrameSizeByOffset(source, offset, mIsWide, &frameSize);
+            if (status == ERROR_END_OF_STREAM) {
+                break;
+            } else if (status != OK) {
                 return;
             }
 
@@ -185,30 +183,33 @@
             numFrames ++;
         }
 
-        mMeta.setInt64(kKeyDuration, duration);
+        AMediaFormat_setInt64(mMeta, AMEDIAFORMAT_KEY_DURATION, duration);
     }
 
     mInitCheck = OK;
 }
 
 AMRExtractor::~AMRExtractor() {
+    delete mDataSource;
+    AMediaFormat_delete(mMeta);
 }
 
-status_t AMRExtractor::getMetaData(MetaDataBase &meta) {
-    meta.clear();
+media_status_t AMRExtractor::getMetaData(AMediaFormat *meta) {
+    AMediaFormat_clear(meta);
 
     if (mInitCheck == OK) {
-        meta.setCString(kKeyMIMEType, mIsWide ? "audio/amr-wb" : "audio/amr");
+        AMediaFormat_setString(meta,
+                AMEDIAFORMAT_KEY_MIME, mIsWide ? MEDIA_MIMETYPE_AUDIO_AMR_WB : "audio/amr");
     }
 
-    return OK;
+    return AMEDIA_OK;
 }
 
 size_t AMRExtractor::countTracks() {
     return mInitCheck == OK ? 1 : 0;
 }
 
-MediaTrack *AMRExtractor::getTrack(size_t index) {
+MediaTrackHelper *AMRExtractor::getTrack(size_t index) {
     if (mInitCheck != OK || index != 0) {
         return NULL;
     }
@@ -217,19 +218,18 @@
             mOffsetTable, mOffsetTableLength);
 }
 
-status_t AMRExtractor::getTrackMetaData(MetaDataBase &meta, size_t index, uint32_t /* flags */) {
+media_status_t AMRExtractor::getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t /* flags */) {
     if (mInitCheck != OK || index != 0) {
-        return UNKNOWN_ERROR;
+        return AMEDIA_ERROR_UNKNOWN;
     }
 
-    meta = mMeta;
-    return OK;
+    return AMediaFormat_copy(meta, mMeta);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 AMRSource::AMRSource(
-        DataSourceBase *source, MetaDataBase &meta,
+        DataSourceHelper *source, AMediaFormat *meta,
         bool isWide, const off64_t *offset_table, size_t offset_table_length)
     : mDataSource(source),
       mMeta(meta),
@@ -250,43 +250,38 @@
     }
 }
 
-status_t AMRSource::start(MetaDataBase * /* params */) {
+media_status_t AMRSource::start() {
     CHECK(!mStarted);
 
     mOffset = mIsWide ? 9 : 6;
     mCurrentTimeUs = 0;
-    mGroup = new MediaBufferGroup;
-    mGroup->add_buffer(MediaBufferBase::Create(128));
+    mBufferGroup->add_buffer(128);
     mStarted = true;
 
-    return OK;
+    return AMEDIA_OK;
 }
 
-status_t AMRSource::stop() {
+media_status_t AMRSource::stop() {
     CHECK(mStarted);
 
-    delete mGroup;
-    mGroup = NULL;
-
     mStarted = false;
-    return OK;
+    return AMEDIA_OK;
 }
 
-status_t AMRSource::getFormat(MetaDataBase &meta) {
-    meta = mMeta;
-    return OK;
+media_status_t AMRSource::getFormat(AMediaFormat *meta) {
+    return AMediaFormat_copy(meta, mMeta);
 }
 
-status_t AMRSource::read(
-        MediaBufferBase **out, const ReadOptions *options) {
+media_status_t AMRSource::read(
+        MediaBufferHelper **out, const ReadOptions *options) {
     *out = NULL;
 
     int64_t seekTimeUs;
     ReadOptions::SeekMode mode;
     if (mOffsetTableLength > 0 && options && options->getSeekTo(&seekTimeUs, &mode)) {
         size_t size;
-        int64_t seekFrame = seekTimeUs / 20000ll;  // 20ms per frame.
-        mCurrentTimeUs = seekFrame * 20000ll;
+        int64_t seekFrame = seekTimeUs / 20000LL;  // 20ms per frame.
+        mCurrentTimeUs = seekFrame * 20000LL;
 
         size_t index = seekFrame < 0 ? 0 : seekFrame / 50;
         if (index >= mOffsetTableLength) {
@@ -296,7 +291,7 @@
         mOffset = mOffsetTable[index] + (mIsWide ? 9 : 6);
 
         for (size_t i = 0; i< seekFrame - index * 50; i++) {
-            status_t err;
+            media_status_t err;
             if ((err = getFrameSizeByOffset(mDataSource, mOffset,
                             mIsWide, &size)) != OK) {
                 return err;
@@ -309,7 +304,7 @@
     ssize_t n = mDataSource->readAt(mOffset, &header, 1);
 
     if (n < 1) {
-        return ERROR_END_OF_STREAM;
+        return AMEDIA_ERROR_END_OF_STREAM;
     }
 
     if (header & 0x83) {
@@ -317,20 +312,20 @@
 
         ALOGE("padding bits must be 0, header is 0x%02x", header);
 
-        return ERROR_MALFORMED;
+        return AMEDIA_ERROR_MALFORMED;
     }
 
     unsigned FT = (header >> 3) & 0x0f;
 
     size_t frameSize = getFrameSize(mIsWide, FT);
     if (frameSize == 0) {
-        return ERROR_MALFORMED;
+        return AMEDIA_ERROR_MALFORMED;
     }
 
-    MediaBufferBase *buffer;
-    status_t err = mGroup->acquire_buffer(&buffer);
+    MediaBufferHelper *buffer;
+    status_t err = mBufferGroup->acquire_buffer(&buffer);
     if (err != OK) {
-        return err;
+        return AMEDIA_ERROR_UNKNOWN;
     }
 
     n = mDataSource->readAt(mOffset, buffer->data(), frameSize);
@@ -340,50 +335,63 @@
         buffer = NULL;
 
         if (n < 0) {
-            return ERROR_IO;
+            return AMEDIA_ERROR_IO;
         } else {
             // only partial frame is available, treat it as EOS.
             mOffset += n;
-            return ERROR_END_OF_STREAM;
+            return AMEDIA_ERROR_END_OF_STREAM;
         }
     }
 
     buffer->set_range(0, frameSize);
-    buffer->meta_data().setInt64(kKeyTime, mCurrentTimeUs);
-    buffer->meta_data().setInt32(kKeyIsSyncFrame, 1);
+    AMediaFormat *meta = buffer->meta_data();
+    AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, mCurrentTimeUs);
+    AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
 
     mOffset += frameSize;
     mCurrentTimeUs += 20000;  // Each frame is 20ms
 
     *out = buffer;
 
-    return OK;
+    return AMEDIA_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
+static const char *extensions[] = {
+    "amr",
+    "awb",
+    NULL
+};
+
 extern "C" {
 // This is the only symbol that needs to be exported
 __attribute__ ((visibility ("default")))
-MediaExtractor::ExtractorDef GETEXTRACTORDEF() {
+ExtractorDef GETEXTRACTORDEF() {
     return {
-        MediaExtractor::EXTRACTORDEF_VERSION,
+        EXTRACTORDEF_VERSION,
         UUID("c86639c9-2f31-40ac-a715-fa01b4493aaf"),
         1,
         "AMR Extractor",
-        [](
-                DataSourceBase *source,
-                float *confidence,
-                void **,
-                MediaExtractor::FreeMetaFunc *) -> MediaExtractor::CreatorFunc {
-            if (SniffAMR(source, nullptr, confidence)) {
-                return [](
-                        DataSourceBase *source,
-                        void *) -> MediaExtractor* {
-                    return new AMRExtractor(source);};
-            }
-            return NULL;
-        }
+        {
+           .v3 = {
+               [](
+                   CDataSource *source,
+                   float *confidence,
+                   void **,
+                   FreeMetaFunc *) -> CreatorFunc {
+                   DataSourceHelper helper(source);
+                   if (SniffAMR(&helper, nullptr, confidence)) {
+                       return [](
+                               CDataSource *source,
+                               void *) -> CMediaExtractor* {
+                           return wrap(new AMRExtractor(new DataSourceHelper(source)));};
+                   }
+                   return NULL;
+               },
+               extensions
+           },
+        },
     };
 }
 
diff --git a/media/extractors/amr/AMRExtractor.h b/media/extractors/amr/AMRExtractor.h
index c90b325..b76ee9c 100644
--- a/media/extractors/amr/AMRExtractor.h
+++ b/media/extractors/amr/AMRExtractor.h
@@ -19,8 +19,9 @@
 #define AMR_EXTRACTOR_H_
 
 #include <utils/Errors.h>
-#include <media/MediaExtractor.h>
-#include <media/stagefright/MetaDataBase.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
+#include <media/NdkMediaFormat.h>
 
 namespace android {
 
@@ -28,23 +29,23 @@
 class String8;
 #define OFFSET_TABLE_LEN    300
 
-class AMRExtractor : public MediaExtractor {
+class AMRExtractor : public MediaExtractorPluginHelper {
 public:
-    explicit AMRExtractor(DataSourceBase *source);
+    explicit AMRExtractor(DataSourceHelper *source);
 
     virtual size_t countTracks();
-    virtual MediaTrack *getTrack(size_t index);
-    virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags);
+    virtual MediaTrackHelper *getTrack(size_t index);
+    virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
 
-    virtual status_t getMetaData(MetaDataBase& meta);
+    virtual media_status_t getMetaData(AMediaFormat *meta);
     virtual const char * name() { return "AMRExtractor"; }
 
 protected:
     virtual ~AMRExtractor();
 
 private:
-    DataSourceBase *mDataSource;
-    MetaDataBase mMeta;
+    DataSourceHelper *mDataSource;
+    AMediaFormat *mMeta;
     status_t mInitCheck;
     bool mIsWide;
 
diff --git a/media/extractors/amr/Android.bp b/media/extractors/amr/Android.bp
index d962b93..4bd933d 100644
--- a/media/extractors/amr/Android.bp
+++ b/media/extractors/amr/Android.bp
@@ -8,7 +8,7 @@
 
     shared_libs: [
         "liblog",
-        "libmediaextractor",
+        "libmediandk",
     ],
 
     static_libs: [
@@ -33,9 +33,6 @@
             "unsigned-integer-overflow",
             "signed-integer-overflow",
         ],
-        diag: {
-            cfi: true,
-        },
     },
 
 }
diff --git a/media/extractors/flac/Android.bp b/media/extractors/flac/Android.bp
index 6282793..3a3d051 100644
--- a/media/extractors/flac/Android.bp
+++ b/media/extractors/flac/Android.bp
@@ -8,13 +8,17 @@
     ],
 
     shared_libs: [
+        "libbinder_ndk",
         "liblog",
-        "libmediaextractor",
+        "libmediandk",
     ],
 
     static_libs: [
+        "libaudioutils",
         "libFLAC",
         "libstagefright_foundation",
+        "libstagefright_metadatautils",
+        "libutils",
     ],
 
     name: "libflacextractor",
@@ -35,9 +39,6 @@
             "unsigned-integer-overflow",
             "signed-integer-overflow",
         ],
-        diag: {
-            cfi: true,
-        },
     },
 
 }
diff --git a/media/extractors/flac/FLACExtractor.cpp b/media/extractors/flac/FLACExtractor.cpp
index e3da259..5329bd1 100644
--- a/media/extractors/flac/FLACExtractor.cpp
+++ b/media/extractors/flac/FLACExtractor.cpp
@@ -18,45 +18,62 @@
 #define LOG_TAG "FLACExtractor"
 #include <utils/Log.h>
 
+#include <stdint.h>
+
 #include "FLACExtractor.h"
 // libFLAC parser
 #include "FLAC/stream_decoder.h"
 
-#include <media/DataSourceBase.h>
-#include <media/MediaTrack.h>
-#include <media/VorbisComment.h>
+#include <android/binder_ibinder.h> // for AIBinder_getCallingUid
+#include <audio_utils/primitives.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/NdkMediaFormat.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/base64.h>
 #include <media/stagefright/MediaBufferGroup.h>
 #include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MetaData.h>
-#include <media/stagefright/MediaBufferBase.h>
+#include <media/stagefright/MetaDataUtils.h>
+#include <private/android_filesystem_config.h> // for AID_MEDIA
+#include <system/audio.h>
 
 namespace android {
 
+// MediaServer is capable of handling float extractor output, but general processes
+// may not be able to do so.
+// TODO: Improve API to set extractor float output.
+// (Note: duplicated with WAVExtractor.cpp)
+static inline bool shouldExtractorOutputFloat(int bitsPerSample)
+{
+    return bitsPerSample > 16 && AIBinder_getCallingUid() == AID_MEDIA;
+}
+
 class FLACParser;
 
-class FLACSource : public MediaTrack {
+class FLACSource : public MediaTrackHelper {
 
 public:
     FLACSource(
-            DataSourceBase *dataSource,
-            MetaDataBase &meta);
+            DataSourceHelper *dataSource,
+            AMediaFormat *meta,
+            bool outputFloat);
 
-    virtual status_t start(MetaDataBase *params);
-    virtual status_t stop();
-    virtual status_t getFormat(MetaDataBase &meta);
+    virtual media_status_t start();
+    virtual media_status_t stop();
+    virtual media_status_t getFormat(AMediaFormat *meta);
 
-    virtual status_t read(
-            MediaBufferBase **buffer, const ReadOptions *options = NULL);
+    virtual media_status_t read(
+            MediaBufferHelper **buffer, const ReadOptions *options = NULL);
 
 protected:
     virtual ~FLACSource();
 
 private:
-    DataSourceBase *mDataSource;
-    MetaDataBase mTrackMetadata;
+    DataSourceHelper *mDataSource;
+    AMediaFormat *mTrackMetadata;
+    const bool mOutputFloat;
     FLACParser *mParser;
     bool mInitCheck;
     bool mStarted;
@@ -73,14 +90,15 @@
 
 public:
     enum {
-        kMaxChannels = 8,
+        kMaxChannels = FCC_8,
     };
 
     explicit FLACParser(
-        DataSourceBase *dataSource,
+        DataSourceHelper *dataSource,
+        bool outputFloat,
         // If metadata pointers aren't provided, we don't fill them
-        MetaDataBase *fileMetadata = 0,
-        MetaDataBase *trackMetadata = 0);
+        AMediaFormat *fileMetadata = 0,
+        AMediaFormat *trackMetadata = 0);
 
     virtual ~FLACParser();
 
@@ -106,25 +124,26 @@
     }
 
     // media buffers
-    void allocateBuffers();
+    void allocateBuffers(MediaBufferGroupHelper *group);
     void releaseBuffers();
-    MediaBufferBase *readBuffer() {
+    MediaBufferHelper *readBuffer() {
         return readBuffer(false, 0LL);
     }
-    MediaBufferBase *readBuffer(FLAC__uint64 sample) {
+    MediaBufferHelper *readBuffer(FLAC__uint64 sample) {
         return readBuffer(true, sample);
     }
 
 private:
-    DataSourceBase *mDataSource;
-    MetaDataBase *mFileMetadata;
-    MetaDataBase *mTrackMetadata;
+    DataSourceHelper *mDataSource;
+    const bool mOutputFloat;
+    AMediaFormat *mFileMetadata;
+    AMediaFormat *mTrackMetadata;
     bool mInitCheck;
 
     // media buffers
     size_t mMaxBufferSize;
-    MediaBufferGroup *mGroup;
-    void (*mCopy)(short *dst, const int * src[kMaxChannels], unsigned nSamples, unsigned nChannels);
+    MediaBufferGroupHelper *mGroup;
+    void (*mCopy)(int16_t *dst, const int * src[kMaxChannels], unsigned nSamples, unsigned nChannels);
 
     // handle to underlying libFLAC parser
     FLAC__StreamDecoder *mDecoder;
@@ -147,7 +166,7 @@
     FLAC__StreamDecoderErrorStatus mErrorStatus;
 
     status_t init();
-    MediaBufferBase *readBuffer(bool doSeek, FLAC__uint64 sample);
+    MediaBufferHelper *readBuffer(bool doSeek, FLAC__uint64 sample);
 
     // no copy constructor or assignment
     FLACParser(const FLACParser &);
@@ -167,6 +186,7 @@
             const FLAC__Frame *frame, const FLAC__int32 * const buffer[]);
     void metadataCallback(const FLAC__StreamMetadata *metadata);
     void errorCallback(FLAC__StreamDecoderErrorStatus status);
+    size_t getOutputSampleSize() const { return mOutputFloat ? sizeof(float) : sizeof(int16_t); }
 
     // FLAC parser callbacks as C-callable functions
     static FLAC__StreamDecoderReadStatus read_callback(
@@ -362,9 +382,8 @@
     case FLAC__METADATA_TYPE_PICTURE:
         if (mFileMetadata != 0) {
             const FLAC__StreamMetadata_Picture *p = &metadata->data.picture;
-            mFileMetadata->setData(kKeyAlbumArt,
-                    MetaData::TYPE_NONE, p->data, p->data_length);
-            mFileMetadata->setCString(kKeyAlbumArtMIME, p->mime_type);
+            AMediaFormat_setBuffer(mFileMetadata, AMEDIAFORMAT_KEY_ALBUMART,
+                   p->data, p->data_length);
         }
         break;
     default:
@@ -379,122 +398,61 @@
     mErrorStatus = status;
 }
 
-// Copy samples from FLAC native 32-bit non-interleaved to 16-bit interleaved.
+// Copy samples from FLAC native 32-bit non-interleaved to 16-bit signed
+// or 32-bit float interleaved.
+// TODO: Consider moving to audio_utils.
 // These are candidates for optimization if needed.
-
-static void copyMono8(
+static void copyTo16Signed(
         short *dst,
-        const int * src[FLACParser::kMaxChannels],
+        const int *const *src,
         unsigned nSamples,
-        unsigned /* nChannels */) {
-    for (unsigned i = 0; i < nSamples; ++i) {
-        *dst++ = src[0][i] << 8;
-    }
-}
-
-static void copyStereo8(
-        short *dst,
-        const int * src[FLACParser::kMaxChannels],
-        unsigned nSamples,
-        unsigned /* nChannels */) {
-    for (unsigned i = 0; i < nSamples; ++i) {
-        *dst++ = src[0][i] << 8;
-        *dst++ = src[1][i] << 8;
-    }
-}
-
-static void copyMultiCh8(short *dst, const int * src[FLACParser::kMaxChannels], unsigned nSamples, unsigned nChannels)
-{
-    for (unsigned i = 0; i < nSamples; ++i) {
-        for (unsigned c = 0; c < nChannels; ++c) {
-            *dst++ = src[c][i] << 8;
+        unsigned nChannels,
+        unsigned bitsPerSample) {
+    const int leftShift = 16 - (int)bitsPerSample; // cast to int to prevent unsigned overflow.
+    if (leftShift >= 0) {
+        for (unsigned i = 0; i < nSamples; ++i) {
+            for (unsigned c = 0; c < nChannels; ++c) {
+                *dst++ = src[c][i] << leftShift;
+            }
+        }
+    } else {
+        const int rightShift = -leftShift;
+        for (unsigned i = 0; i < nSamples; ++i) {
+            for (unsigned c = 0; c < nChannels; ++c) {
+                *dst++ = src[c][i] >> rightShift;
+            }
         }
     }
 }
 
-static void copyMono16(
-        short *dst,
-        const int * src[FLACParser::kMaxChannels],
+static void copyToFloat(
+        float *dst,
+        const int *const *src,
         unsigned nSamples,
-        unsigned /* nChannels */) {
-    for (unsigned i = 0; i < nSamples; ++i) {
-        *dst++ = src[0][i];
-    }
-}
-
-static void copyStereo16(
-        short *dst,
-        const int * src[FLACParser::kMaxChannels],
-        unsigned nSamples,
-        unsigned /* nChannels */) {
-    for (unsigned i = 0; i < nSamples; ++i) {
-        *dst++ = src[0][i];
-        *dst++ = src[1][i];
-    }
-}
-
-static void copyMultiCh16(short *dst, const int * src[FLACParser::kMaxChannels], unsigned nSamples, unsigned nChannels)
-{
+        unsigned nChannels,
+        unsigned bitsPerSample) {
+    const unsigned leftShift = 32 - bitsPerSample;
     for (unsigned i = 0; i < nSamples; ++i) {
         for (unsigned c = 0; c < nChannels; ++c) {
-            *dst++ = src[c][i];
+            *dst++ = float_from_i32(src[c][i] << leftShift);
         }
     }
 }
 
-// 24-bit versions should do dithering or noise-shaping, here or in AudioFlinger
-
-static void copyMono24(
-        short *dst,
-        const int * src[FLACParser::kMaxChannels],
-        unsigned nSamples,
-        unsigned /* nChannels */) {
-    for (unsigned i = 0; i < nSamples; ++i) {
-        *dst++ = src[0][i] >> 8;
-    }
-}
-
-static void copyStereo24(
-        short *dst,
-        const int * src[FLACParser::kMaxChannels],
-        unsigned nSamples,
-        unsigned /* nChannels */) {
-    for (unsigned i = 0; i < nSamples; ++i) {
-        *dst++ = src[0][i] >> 8;
-        *dst++ = src[1][i] >> 8;
-    }
-}
-
-static void copyMultiCh24(short *dst, const int * src[FLACParser::kMaxChannels], unsigned nSamples, unsigned nChannels)
-{
-    for (unsigned i = 0; i < nSamples; ++i) {
-        for (unsigned c = 0; c < nChannels; ++c) {
-            *dst++ = src[c][i] >> 8;
-        }
-    }
-}
-
-static void copyTrespass(
-        short * /* dst */,
-        const int *[FLACParser::kMaxChannels] /* src */,
-        unsigned /* nSamples */,
-        unsigned /* nChannels */) {
-    TRESPASS();
-}
-
 // FLACParser
 
 FLACParser::FLACParser(
-        DataSourceBase *dataSource,
-        MetaDataBase *fileMetadata,
-        MetaDataBase *trackMetadata)
+        DataSourceHelper *dataSource,
+        bool outputFloat,
+        AMediaFormat *fileMetadata,
+        AMediaFormat *trackMetadata)
     : mDataSource(dataSource),
+      mOutputFloat(outputFloat),
       mFileMetadata(fileMetadata),
       mTrackMetadata(trackMetadata),
       mInitCheck(false),
       mMaxBufferSize(0),
       mGroup(NULL),
-      mCopy(copyTrespass),
       mDecoder(NULL),
       mCurrentPos(0LL),
       mEOF(false),
@@ -565,88 +523,59 @@
         case 8:
         case 16:
         case 24:
+        case 32: // generally not expected for FLAC
             break;
         default:
+            // Note: internally the FLAC extractor supports 2-32 bits.
             ALOGE("unsupported bits per sample %u", getBitsPerSample());
             return NO_INIT;
         }
         // check sample rate
-        switch (getSampleRate()) {
-        case  8000:
-        case 11025:
-        case 12000:
-        case 16000:
-        case 22050:
-        case 24000:
-        case 32000:
-        case 44100:
-        case 48000:
-        case 88200:
-        case 96000:
-            break;
-        default:
+        // Note: flac supports arbitrary sample rates up to 655350 Hz, but Android
+        // supports sample rates from 8kHz to 192kHz, so use that as the limit.
+        if (getSampleRate() < 8000 || getSampleRate() > 192000) {
             ALOGE("unsupported sample rate %u", getSampleRate());
             return NO_INIT;
         }
-        // configure the appropriate copy function, defaulting to trespass
-        static const struct {
-            unsigned mChannels;
-            unsigned mBitsPerSample;
-            void (*mCopy)(short *dst, const int * src[kMaxChannels], unsigned nSamples, unsigned nChannels);
-        } table[] = {
-            { 1,  8, copyMono8    },
-            { 2,  8, copyStereo8  },
-            { 8,  8, copyMultiCh8  },
-            { 1, 16, copyMono16   },
-            { 2, 16, copyStereo16 },
-            { 8, 16, copyMultiCh16 },
-            { 1, 24, copyMono24   },
-            { 2, 24, copyStereo24 },
-            { 8, 24, copyMultiCh24 },
-        };
-        for (unsigned i = 0; i < sizeof(table)/sizeof(table[0]); ++i) {
-            if (table[i].mChannels >= getChannels() &&
-                    table[i].mBitsPerSample == getBitsPerSample()) {
-                mCopy = table[i].mCopy;
-                break;
-            }
-        }
         // populate track metadata
         if (mTrackMetadata != 0) {
-            mTrackMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
-            mTrackMetadata->setInt32(kKeyChannelCount, getChannels());
-            mTrackMetadata->setInt32(kKeySampleRate, getSampleRate());
-            mTrackMetadata->setInt32(kKeyPcmEncoding, kAudioEncodingPcm16bit);
+            AMediaFormat_setString(mTrackMetadata,
+                    AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_RAW);
+            AMediaFormat_setInt32(mTrackMetadata,
+                    AMEDIAFORMAT_KEY_CHANNEL_COUNT, getChannels());
+            AMediaFormat_setInt32(mTrackMetadata,
+                    AMEDIAFORMAT_KEY_SAMPLE_RATE, getSampleRate());
+            AMediaFormat_setInt32(mTrackMetadata,
+                    AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, getBitsPerSample());
             // sample rate is non-zero, so division by zero not possible
-            mTrackMetadata->setInt64(kKeyDuration,
-                    (getTotalSamples() * 1000000LL) / getSampleRate());
+            AMediaFormat_setInt64(mTrackMetadata,
+                    AMEDIAFORMAT_KEY_DURATION, (getTotalSamples() * 1000000LL) / getSampleRate());
         }
     } else {
         ALOGE("missing STREAMINFO");
         return NO_INIT;
     }
     if (mFileMetadata != 0) {
-        mFileMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_FLAC);
+        AMediaFormat_setString(mFileMetadata,
+                AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_FLAC);
     }
     return OK;
 }
 
-void FLACParser::allocateBuffers()
+void FLACParser::allocateBuffers(MediaBufferGroupHelper *group)
 {
     CHECK(mGroup == NULL);
-    mGroup = new MediaBufferGroup;
-    mMaxBufferSize = getMaxBlockSize() * getChannels() * sizeof(short);
-    mGroup->add_buffer(MediaBufferBase::Create(mMaxBufferSize));
+    mGroup = group;
+    mMaxBufferSize = getMaxBlockSize() * getChannels() * getOutputSampleSize();
+    AMediaFormat_setInt32(mTrackMetadata, AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, mMaxBufferSize);
+    mGroup->add_buffer(mMaxBufferSize);
 }
 
 void FLACParser::releaseBuffers()
 {
-    CHECK(mGroup != NULL);
-    delete mGroup;
-    mGroup = NULL;
 }
 
-MediaBufferBase *FLACParser::readBuffer(bool doSeek, FLAC__uint64 sample)
+MediaBufferHelper *FLACParser::readBuffer(bool doSeek, FLAC__uint64 sample)
 {
     mWriteRequested = true;
     mWriteCompleted = false;
@@ -683,41 +612,53 @@
     }
     // acquire a media buffer
     CHECK(mGroup != NULL);
-    MediaBufferBase *buffer;
+    MediaBufferHelper *buffer;
     status_t err = mGroup->acquire_buffer(&buffer);
     if (err != OK) {
         return NULL;
     }
-    size_t bufferSize = blocksize * getChannels() * sizeof(short);
+    const size_t bufferSize = blocksize * getChannels() * getOutputSampleSize();
     CHECK(bufferSize <= mMaxBufferSize);
-    short *data = (short *) buffer->data();
     buffer->set_range(0, bufferSize);
     // copy PCM from FLAC write buffer to our media buffer, with interleaving
-    (*mCopy)(data, mWriteBuffer, blocksize, getChannels());
+    const unsigned bitsPerSample = getBitsPerSample();
+    if (mOutputFloat) {
+        copyToFloat(reinterpret_cast<float*>(buffer->data()),
+                    mWriteBuffer,
+                    blocksize,
+                    getChannels(),
+                    bitsPerSample);
+    } else {
+        copyTo16Signed(reinterpret_cast<short*>(buffer->data()),
+                       mWriteBuffer,
+                       blocksize,
+                       getChannels(),
+                       bitsPerSample);
+    }
     // fill in buffer metadata
     CHECK(mWriteHeader.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
     FLAC__uint64 sampleNumber = mWriteHeader.number.sample_number;
     int64_t timeUs = (1000000LL * sampleNumber) / getSampleRate();
-    buffer->meta_data().setInt64(kKeyTime, timeUs);
-    buffer->meta_data().setInt32(kKeyIsSyncFrame, 1);
+    AMediaFormat *meta = buffer->meta_data();
+    AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeUs);
+    AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
     return buffer;
 }
 
 // FLACsource
 
 FLACSource::FLACSource(
-        DataSourceBase *dataSource,
-        MetaDataBase &trackMetadata)
+        DataSourceHelper *dataSource,
+        AMediaFormat *trackMetadata,
+        bool outputFloat)
     : mDataSource(dataSource),
       mTrackMetadata(trackMetadata),
-      mParser(0),
-      mInitCheck(false),
+      mOutputFloat(outputFloat),
+      mParser(new FLACParser(mDataSource, outputFloat, 0, mTrackMetadata)),
+      mInitCheck(mParser->initCheck()),
       mStarted(false)
 {
     ALOGV("FLACSource::FLACSource");
-    // re-use the same track metadata passed into constructor from FLACExtractor
-    mParser = new FLACParser(mDataSource);
-    mInitCheck  = mParser->initCheck();
 }
 
 FLACSource::~FLACSource()
@@ -729,18 +670,18 @@
     delete mParser;
 }
 
-status_t FLACSource::start(MetaDataBase * /* params */)
+media_status_t FLACSource::start()
 {
     ALOGV("FLACSource::start");
 
     CHECK(!mStarted);
-    mParser->allocateBuffers();
+    mParser->allocateBuffers(mBufferGroup);
     mStarted = true;
 
-    return OK;
+    return AMEDIA_OK;
 }
 
-status_t FLACSource::stop()
+media_status_t FLACSource::stop()
 {
     ALOGV("FLACSource::stop");
 
@@ -748,19 +689,23 @@
     mParser->releaseBuffers();
     mStarted = false;
 
-    return OK;
+    return AMEDIA_OK;
 }
 
-status_t FLACSource::getFormat(MetaDataBase &meta)
+media_status_t FLACSource::getFormat(AMediaFormat *meta)
 {
-    meta = mTrackMetadata;
-    return OK;
+    const media_status_t status = AMediaFormat_copy(meta, mTrackMetadata);
+    if (status == OK) {
+        AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_PCM_ENCODING,
+                mOutputFloat ? kAudioEncodingPcmFloat : kAudioEncodingPcm16bit);
+    }
+    return status;
 }
 
-status_t FLACSource::read(
-        MediaBufferBase **outBuffer, const ReadOptions *options)
+media_status_t FLACSource::read(
+        MediaBufferHelper **outBuffer, const ReadOptions *options)
 {
-    MediaBufferBase *buffer;
+    MediaBufferHelper *buffer;
     // process an optional seek request
     int64_t seekTimeUs;
     ReadOptions::SeekMode mode;
@@ -781,20 +726,22 @@
         buffer = mParser->readBuffer();
     }
     *outBuffer = buffer;
-    return buffer != NULL ? (status_t) OK : (status_t) ERROR_END_OF_STREAM;
+    return buffer != NULL ? AMEDIA_OK : AMEDIA_ERROR_END_OF_STREAM;
 }
 
 // FLACExtractor
 
 FLACExtractor::FLACExtractor(
-        DataSourceBase *dataSource)
+        DataSourceHelper *dataSource)
     : mDataSource(dataSource),
       mParser(nullptr),
       mInitCheck(false)
 {
     ALOGV("FLACExtractor::FLACExtractor");
     // FLACParser will fill in the metadata for us
-    mParser = new FLACParser(mDataSource, &mFileMetadata, &mTrackMetadata);
+    mFileMetadata = AMediaFormat_new();
+    mTrackMetadata = AMediaFormat_new();
+    mParser = new FLACParser(mDataSource, false /* outputFloat */, mFileMetadata, mTrackMetadata);
     mInitCheck = mParser->initCheck();
 }
 
@@ -802,6 +749,9 @@
 {
     ALOGV("~FLACExtractor::FLACExtractor");
     delete mParser;
+    delete mDataSource;
+    AMediaFormat_delete(mFileMetadata);
+    AMediaFormat_delete(mTrackMetadata);
 }
 
 size_t FLACExtractor::countTracks()
@@ -809,42 +759,76 @@
     return mInitCheck == OK ? 1 : 0;
 }
 
-MediaTrack *FLACExtractor::getTrack(size_t index)
+MediaTrackHelper *FLACExtractor::getTrack(size_t index)
 {
     if (mInitCheck != OK || index > 0) {
         return NULL;
     }
-    return new FLACSource(mDataSource, mTrackMetadata);
+
+    return new FLACSource(
+            mDataSource, mTrackMetadata, shouldExtractorOutputFloat(mParser->getBitsPerSample()));
 }
 
-status_t FLACExtractor::getTrackMetaData(
-        MetaDataBase &meta,
+media_status_t FLACExtractor::getTrackMetaData(
+        AMediaFormat *meta,
         size_t index, uint32_t /* flags */) {
     if (mInitCheck != OK || index > 0) {
-        return UNKNOWN_ERROR;
+        return AMEDIA_ERROR_UNKNOWN;
     }
-    meta = mTrackMetadata;
-    return OK;
+    const media_status_t status = AMediaFormat_copy(meta, mTrackMetadata);
+    if (status == OK) {
+        AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_PCM_ENCODING,
+                shouldExtractorOutputFloat(mParser->getBitsPerSample())
+                        ? kAudioEncodingPcmFloat : kAudioEncodingPcm16bit);
+    }
+    return status;
 }
 
-status_t FLACExtractor::getMetaData(MetaDataBase &meta)
+media_status_t FLACExtractor::getMetaData(AMediaFormat *meta)
 {
-    meta = mFileMetadata;
-    return OK;
+    return AMediaFormat_copy(meta, mFileMetadata);
 }
 
 // Sniffer
 
-bool SniffFLAC(DataSourceBase *source, float *confidence)
+bool SniffFLAC(DataSourceHelper *source, float *confidence)
 {
-    // first 4 is the signature word
-    // second 4 is the sizeof STREAMINFO
-    // 042 is the mandatory STREAMINFO
-    // no need to read rest of the header, as a premature EOF will be caught later
-    uint8_t header[4+4];
-    if (source->readAt(0, header, sizeof(header)) != sizeof(header)
-            || memcmp("fLaC\0\0\0\042", header, 4+4))
-    {
+    // Skip ID3 tags
+    off64_t pos = 0;
+    uint8_t header[10];
+    for (;;) {
+        if (source->readAt(pos, header, sizeof(header)) != sizeof(header)) {
+            return false; // no more file to read.
+        }
+
+        // check for ID3 tag
+        if (memcmp("ID3", header, 3) != 0) {
+            break; // not an ID3 tag.
+        }
+
+        // skip the ID3v2 data and check again
+        const unsigned id3Len = 10 +
+                (((header[6] & 0x7f) << 21)
+                 | ((header[7] & 0x7f) << 14)
+                 | ((header[8] & 0x7f) << 7)
+                 | (header[9] & 0x7f));
+        pos += id3Len;
+
+        ALOGV("skipped ID3 tag of len %u new starting offset is %#016llx",
+                id3Len, (long long)pos);
+    }
+
+    // Check FLAC header.
+    // https://xiph.org/flac/format.html#stream
+    //
+    // Note: content stored big endian.
+    // byte offset  bit size  content
+    // 0            32        fLaC
+    // 4            8         metadata type STREAMINFO (0) (note: OR with 0x80 if last metadata)
+    // 5            24        size of metadata, for STREAMINFO (0x22).
+
+    if (memcmp("fLaC\x00\x00\x00\x22", header, 8) != 0 &&
+        memcmp("fLaC\x80\x00\x00\x22", header, 8) != 0) {
         return false;
     }
 
@@ -853,29 +837,40 @@
     return true;
 }
 
+static const char *extensions[] = {
+    "flac",
+    "fl",
+    NULL
+};
 
 extern "C" {
 // This is the only symbol that needs to be exported
 __attribute__ ((visibility ("default")))
-MediaExtractor::ExtractorDef GETEXTRACTORDEF() {
+ExtractorDef GETEXTRACTORDEF() {
     return {
-        MediaExtractor::EXTRACTORDEF_VERSION,
+            EXTRACTORDEF_VERSION,
             UUID("1364b048-cc45-4fda-9934-327d0ebf9829"),
             1,
             "FLAC Extractor",
-            [](
-                    DataSourceBase *source,
-                    float *confidence,
-                    void **,
-                    MediaExtractor::FreeMetaFunc *) -> MediaExtractor::CreatorFunc {
-                if (SniffFLAC(source, confidence)) {
-                    return [](
-                            DataSourceBase *source,
-                            void *) -> MediaExtractor* {
-                        return new FLACExtractor(source);};
+            {
+                .v3 = {
+                    [](
+                        CDataSource *source,
+                        float *confidence,
+                        void **,
+                        FreeMetaFunc *) -> CreatorFunc {
+                        DataSourceHelper helper(source);
+                        if (SniffFLAC(&helper, confidence)) {
+                            return [](
+                                    CDataSource *source,
+                                    void *) -> CMediaExtractor* {
+                                return wrap(new FLACExtractor(new DataSourceHelper(source)));};
+                        }
+                        return NULL;
+                    },
+                    extensions
                 }
-                return NULL;
-            }
+            },
      };
 }
 
diff --git a/media/extractors/flac/FLACExtractor.h b/media/extractors/flac/FLACExtractor.h
index 7fb6ec6..5a73d20 100644
--- a/media/extractors/flac/FLACExtractor.h
+++ b/media/extractors/flac/FLACExtractor.h
@@ -18,45 +18,44 @@
 #define FLAC_EXTRACTOR_H_
 
 #include <media/DataSourceBase.h>
-#include <media/MediaExtractor.h>
-#include <media/stagefright/MetaDataBase.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
+#include <media/NdkMediaFormat.h>
 #include <utils/String8.h>
 
 namespace android {
 
 class FLACParser;
 
-class FLACExtractor : public MediaExtractor {
+class FLACExtractor : public MediaExtractorPluginHelper {
 
 public:
-    explicit FLACExtractor(DataSourceBase *source);
+    explicit FLACExtractor(DataSourceHelper *source);
 
     virtual size_t countTracks();
-    virtual MediaTrack *getTrack(size_t index);
-    virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags);
+    virtual MediaTrackHelper *getTrack(size_t index);
+    virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
 
-    virtual status_t getMetaData(MetaDataBase& meta);
+    virtual media_status_t getMetaData(AMediaFormat *meta);
     virtual const char * name() { return "FLACExtractor"; }
 
 protected:
     virtual ~FLACExtractor();
 
 private:
-    DataSourceBase *mDataSource;
+    DataSourceHelper *mDataSource;
     FLACParser *mParser;
     status_t mInitCheck;
-    MetaDataBase mFileMetadata;
+    AMediaFormat *mFileMetadata;
 
     // There is only one track
-    MetaDataBase mTrackMetadata;
+    AMediaFormat *mTrackMetadata;
 
     FLACExtractor(const FLACExtractor &);
     FLACExtractor &operator=(const FLACExtractor &);
 
 };
 
-bool SniffFLAC(DataSourceBase *source, float *confidence);
-
 }  // namespace android
 
 #endif  // FLAC_EXTRACTOR_H_
diff --git a/media/extractors/midi/Android.bp b/media/extractors/midi/Android.bp
index fde09df..7d42e70 100644
--- a/media/extractors/midi/Android.bp
+++ b/media/extractors/midi/Android.bp
@@ -8,7 +8,7 @@
 
     shared_libs: [
         "liblog",
-        "libmediaextractor",
+        "libmediandk",
     ],
 
     static_libs: [
@@ -34,9 +34,6 @@
             "unsigned-integer-overflow",
             "signed-integer-overflow",
         ],
-        diag: {
-            cfi: true,
-        },
     },
 
 }
diff --git a/media/extractors/midi/MidiExtractor.cpp b/media/extractors/midi/MidiExtractor.cpp
index a30b6f8..9f4f9e6 100644
--- a/media/extractors/midi/MidiExtractor.cpp
+++ b/media/extractors/midi/MidiExtractor.cpp
@@ -24,35 +24,34 @@
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/MediaBufferGroup.h>
 #include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MetaData.h>
-#include <media/MediaTrack.h>
+#include <media/stagefright/MediaErrors.h>
 #include <libsonivox/eas_reverb.h>
 
 namespace android {
 
-// how many Sonivox output buffers to aggregate into one MediaBufferBase
+// how many Sonivox output buffers to aggregate into one MediaBuffer
 static const int NUM_COMBINE_BUFFERS = 4;
 
-class MidiSource : public MediaTrack {
+class MidiSource : public MediaTrackHelper {
 
 public:
     MidiSource(
             MidiEngine &engine,
-            MetaDataBase &trackMetadata);
+            AMediaFormat *trackMetadata);
 
-    virtual status_t start(MetaDataBase *params);
-    virtual status_t stop();
-    virtual status_t getFormat(MetaDataBase&);
+    virtual media_status_t start();
+    virtual media_status_t stop();
+    virtual media_status_t getFormat(AMediaFormat *);
 
-    virtual status_t read(
-            MediaBufferBase **buffer, const ReadOptions *options = NULL);
+    virtual media_status_t read(
+            MediaBufferHelper **buffer, const ReadOptions *options = NULL);
 
 protected:
     virtual ~MidiSource();
 
 private:
     MidiEngine &mEngine;
-    MetaDataBase &mTrackMetadata;
+    AMediaFormat *mTrackMetadata;
     bool mInitCheck;
     bool mStarted;
 
@@ -69,7 +68,7 @@
 
 MidiSource::MidiSource(
         MidiEngine &engine,
-        MetaDataBase &trackMetadata)
+        AMediaFormat *trackMetadata)
     : mEngine(engine),
       mTrackMetadata(trackMetadata),
       mInitCheck(false),
@@ -87,17 +86,17 @@
     }
 }
 
-status_t MidiSource::start(MetaDataBase * /* params */)
+media_status_t MidiSource::start()
 {
     ALOGV("MidiSource::start");
 
     CHECK(!mStarted);
     mStarted = true;
-    mEngine.allocateBuffers();
-    return OK;
+    mEngine.allocateBuffers(mBufferGroup);
+    return AMEDIA_OK;
 }
 
-status_t MidiSource::stop()
+media_status_t MidiSource::stop()
 {
     ALOGV("MidiSource::stop");
 
@@ -105,20 +104,19 @@
     mStarted = false;
     mEngine.releaseBuffers();
 
-    return OK;
+    return AMEDIA_OK;
 }
 
-status_t MidiSource::getFormat(MetaDataBase &meta)
+media_status_t MidiSource::getFormat(AMediaFormat *meta)
 {
-    meta = mTrackMetadata;
-    return OK;
+    return AMediaFormat_copy(meta, mTrackMetadata);
 }
 
-status_t MidiSource::read(
-        MediaBufferBase **outBuffer, const ReadOptions *options)
+media_status_t MidiSource::read(
+        MediaBufferHelper **outBuffer, const ReadOptions *options)
 {
     ALOGV("MidiSource::read");
-    MediaBufferBase *buffer;
+    MediaBufferHelper *buffer;
     // process an optional seek request
     int64_t seekTimeUs;
     ReadOptions::SeekMode mode;
@@ -131,7 +129,7 @@
     buffer = mEngine.readBuffer();
     *outBuffer = buffer;
     ALOGV("MidiSource::read %p done", this);
-    return buffer != NULL ? (status_t) OK : (status_t) ERROR_END_OF_STREAM;
+    return buffer != NULL ? AMEDIA_OK : AMEDIA_ERROR_END_OF_STREAM;
 }
 
 status_t MidiSource::init()
@@ -142,10 +140,9 @@
 
 // MidiEngine
 
-MidiEngine::MidiEngine(DataSourceBase *dataSource,
-        MetaDataBase *fileMetadata,
-        MetaDataBase *trackMetadata) :
-            mGroup(NULL),
+MidiEngine::MidiEngine(CDataSource *dataSource,
+        AMediaFormat *fileMetadata,
+        AMediaFormat *trackMetadata) :
             mEasData(NULL),
             mEasHandle(NULL),
             mEasConfig(NULL),
@@ -170,16 +167,20 @@
     }
 
     if (fileMetadata != NULL) {
-        fileMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MIDI);
+        AMediaFormat_setString(fileMetadata, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_MIDI);
     }
 
     if (trackMetadata != NULL) {
-        trackMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
-        trackMetadata->setInt64(kKeyDuration, 1000ll * temp); // milli->micro
+        AMediaFormat_setString(trackMetadata, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_RAW);
+        AMediaFormat_setInt64(
+                trackMetadata, AMEDIAFORMAT_KEY_DURATION, 1000ll * temp); // milli->micro
         mEasConfig = EAS_Config();
-        trackMetadata->setInt32(kKeySampleRate, mEasConfig->sampleRate);
-        trackMetadata->setInt32(kKeyChannelCount, mEasConfig->numChannels);
-        trackMetadata->setInt32(kKeyPcmEncoding, kAudioEncodingPcm16bit);
+        AMediaFormat_setInt32(
+                trackMetadata, AMEDIAFORMAT_KEY_SAMPLE_RATE, mEasConfig->sampleRate);
+        AMediaFormat_setInt32(
+                trackMetadata, AMEDIAFORMAT_KEY_CHANNEL_COUNT, mEasConfig->numChannels);
+        AMediaFormat_setInt32(
+                trackMetadata, AMEDIAFORMAT_KEY_PCM_ENCODING, kAudioEncodingPcm16bit);
     }
     mIsInitialized = true;
 }
@@ -191,7 +192,6 @@
     if (mEasData) {
         EAS_Shutdown(mEasData);
     }
-    delete mGroup;
     delete mIoWrapper;
 }
 
@@ -199,22 +199,20 @@
     return mIsInitialized ? OK : UNKNOWN_ERROR;
 }
 
-status_t MidiEngine::allocateBuffers() {
+status_t MidiEngine::allocateBuffers(MediaBufferGroupHelper *group) {
     // select reverb preset and enable
     EAS_SetParameter(mEasData, EAS_MODULE_REVERB, EAS_PARAM_REVERB_PRESET, EAS_PARAM_REVERB_CHAMBER);
     EAS_SetParameter(mEasData, EAS_MODULE_REVERB, EAS_PARAM_REVERB_BYPASS, EAS_FALSE);
 
-    mGroup = new MediaBufferGroup;
     int bufsize = sizeof(EAS_PCM)
             * mEasConfig->mixBufferSize * mEasConfig->numChannels * NUM_COMBINE_BUFFERS;
     ALOGV("using %d byte buffer", bufsize);
-    mGroup->add_buffer(MediaBufferBase::Create(bufsize));
+    mGroup = group;
+    mGroup->add_buffer(bufsize);
     return OK;
 }
 
 status_t MidiEngine::releaseBuffers() {
-    delete mGroup;
-    mGroup = NULL;
     return OK;
 }
 
@@ -224,13 +222,13 @@
     return result == EAS_SUCCESS ? OK : UNKNOWN_ERROR;
 }
 
-MediaBufferBase* MidiEngine::readBuffer() {
+MediaBufferHelper* MidiEngine::readBuffer() {
     EAS_STATE state;
     EAS_State(mEasData, mEasHandle, &state);
     if ((state == EAS_STATE_STOPPED) || (state == EAS_STATE_ERROR)) {
         return NULL;
     }
-    MediaBufferBase *buffer;
+    MediaBufferHelper *buffer;
     status_t err = mGroup->acquire_buffer(&buffer);
     if (err != OK) {
         ALOGE("readBuffer: no buffer");
@@ -239,7 +237,9 @@
     EAS_I32 timeMs;
     EAS_GetLocation(mEasData, mEasHandle, &timeMs);
     int64_t timeUs = 1000ll * timeMs;
-    buffer->meta_data().setInt64(kKeyTime, timeUs);
+    AMediaFormat *meta = buffer->meta_data();
+    AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeUs);
+    AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
 
     EAS_PCM* p = (EAS_PCM*) buffer->data();
     int numBytesOutput = 0;
@@ -263,18 +263,23 @@
 // MidiExtractor
 
 MidiExtractor::MidiExtractor(
-        DataSourceBase *dataSource)
+        CDataSource *dataSource)
     : mDataSource(dataSource),
       mInitCheck(false)
 {
     ALOGV("MidiExtractor ctor");
-    mEngine = new MidiEngine(mDataSource, &mFileMetadata, &mTrackMetadata);
+    mFileMetadata = AMediaFormat_new();
+    mTrackMetadata = AMediaFormat_new();
+    mEngine = new MidiEngine(mDataSource, mFileMetadata, mTrackMetadata);
     mInitCheck = mEngine->initCheck();
 }
 
 MidiExtractor::~MidiExtractor()
 {
     ALOGV("MidiExtractor dtor");
+    AMediaFormat_delete(mFileMetadata);
+    AMediaFormat_delete(mTrackMetadata);
+    delete mEngine;
 }
 
 size_t MidiExtractor::countTracks()
@@ -282,7 +287,7 @@
     return mInitCheck == OK ? 1 : 0;
 }
 
-MediaTrack *MidiExtractor::getTrack(size_t index)
+MediaTrackHelper *MidiExtractor::getTrack(size_t index)
 {
     if (mInitCheck != OK || index > 0) {
         return NULL;
@@ -290,27 +295,25 @@
     return new MidiSource(*mEngine, mTrackMetadata);
 }
 
-status_t MidiExtractor::getTrackMetaData(
-        MetaDataBase &meta,
+media_status_t MidiExtractor::getTrackMetaData(
+        AMediaFormat *meta,
         size_t index, uint32_t /* flags */) {
     ALOGV("MidiExtractor::getTrackMetaData");
     if (mInitCheck != OK || index > 0) {
-        return UNKNOWN_ERROR;
+        return AMEDIA_ERROR_UNKNOWN;
     }
-    meta = mTrackMetadata;
-    return OK;
+    return AMediaFormat_copy(meta, mTrackMetadata);
 }
 
-status_t MidiExtractor::getMetaData(MetaDataBase &meta)
+media_status_t MidiExtractor::getMetaData(AMediaFormat *meta)
 {
     ALOGV("MidiExtractor::getMetaData");
-    meta = mFileMetadata;
-    return OK;
+    return AMediaFormat_copy(meta, mFileMetadata);
 }
 
 // Sniffer
 
-bool SniffMidi(DataSourceBase *source, float *confidence)
+bool SniffMidi(CDataSource *source, float *confidence)
 {
     MidiEngine p(source, NULL, NULL);
     if (p.initCheck() == OK) {
@@ -323,28 +326,46 @@
 
 }
 
+static const char *extensions[] = {
+    "imy",
+    "mid",
+    "midi",
+    "mxmf",
+    "ota",
+    "rtttl",
+    "rtx",
+    "smf",
+    "xmf",
+    NULL
+};
+
 extern "C" {
 // This is the only symbol that needs to be exported
 __attribute__ ((visibility ("default")))
-MediaExtractor::ExtractorDef GETEXTRACTORDEF() {
+ExtractorDef GETEXTRACTORDEF() {
     return {
-        MediaExtractor::EXTRACTORDEF_VERSION,
+        EXTRACTORDEF_VERSION,
         UUID("ef6cca0a-f8a2-43e6-ba5f-dfcd7c9a7ef2"),
         1,
         "MIDI Extractor",
-        [](
-                DataSourceBase *source,
+        {
+            .v3 = {
+                [](
+                CDataSource *source,
                 float *confidence,
                 void **,
-                MediaExtractor::FreeMetaFunc *) -> MediaExtractor::CreatorFunc {
-            if (SniffMidi(source, confidence)) {
-                return [](
-                        DataSourceBase *source,
-                        void *) -> MediaExtractor* {
-                    return new MidiExtractor(source);};
+                FreeMetaFunc *) -> CreatorFunc {
+                    if (SniffMidi(source, confidence)) {
+                        return [](
+                                CDataSource *source,
+                                void *) -> CMediaExtractor* {
+                            return wrap(new MidiExtractor(source));};
+                    }
+                    return NULL;
+                },
+                extensions
             }
-            return NULL;
-        }
+        },
     };
 }
 
diff --git a/media/extractors/midi/MidiExtractor.h b/media/extractors/midi/MidiExtractor.h
index 244dd0f..2e78086 100644
--- a/media/extractors/midi/MidiExtractor.h
+++ b/media/extractors/midi/MidiExtractor.h
@@ -18,11 +18,12 @@
 #define MIDI_EXTRACTOR_H_
 
 #include <media/DataSourceBase.h>
-#include <media/MediaExtractor.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
 #include <media/stagefright/MediaBufferBase.h>
 #include <media/stagefright/MediaBufferGroup.h>
-#include <media/stagefright/MetaDataBase.h>
 #include <media/MidiIoWrapper.h>
+#include <media/NdkMediaFormat.h>
 #include <utils/String8.h>
 #include <libsonivox/eas.h>
 
@@ -30,48 +31,48 @@
 
 class MidiEngine {
 public:
-    explicit MidiEngine(DataSourceBase *dataSource,
-            MetaDataBase *fileMetadata,
-            MetaDataBase *trackMetadata);
+    explicit MidiEngine(CDataSource *dataSource,
+            AMediaFormat *fileMetadata,
+            AMediaFormat *trackMetadata);
     ~MidiEngine();
 
     status_t initCheck();
 
-    status_t allocateBuffers();
+    status_t allocateBuffers(MediaBufferGroupHelper *group);
     status_t releaseBuffers();
     status_t seekTo(int64_t positionUs);
-    MediaBufferBase* readBuffer();
+    MediaBufferHelper* readBuffer();
 private:
     MidiIoWrapper *mIoWrapper;
-    MediaBufferGroup *mGroup;
+    MediaBufferGroupHelper *mGroup;
     EAS_DATA_HANDLE mEasData;
     EAS_HANDLE mEasHandle;
     const S_EAS_LIB_CONFIG* mEasConfig;
     bool mIsInitialized;
 };
 
-class MidiExtractor : public MediaExtractor {
+class MidiExtractor : public MediaExtractorPluginHelper {
 
 public:
-    explicit MidiExtractor(DataSourceBase *source);
+    explicit MidiExtractor(CDataSource *source);
 
     virtual size_t countTracks();
-    virtual MediaTrack *getTrack(size_t index);
-    virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags);
+    virtual MediaTrackHelper *getTrack(size_t index);
+    virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
 
-    virtual status_t getMetaData(MetaDataBase& meta);
+    virtual media_status_t getMetaData(AMediaFormat *meta);
     virtual const char * name() { return "MidiExtractor"; }
 
 protected:
     virtual ~MidiExtractor();
 
 private:
-    DataSourceBase *mDataSource;
+    CDataSource *mDataSource;
     status_t mInitCheck;
-    MetaDataBase mFileMetadata;
+    AMediaFormat *mFileMetadata;
 
     // There is only one track
-    MetaDataBase mTrackMetadata;
+    AMediaFormat *mTrackMetadata;
 
     MidiEngine *mEngine;
 
@@ -88,7 +89,7 @@
 
 };
 
-bool SniffMidi(DataSourceBase *source, float *confidence);
+bool SniffMidi(CDataSource *source, float *confidence);
 
 }  // namespace android
 
diff --git a/media/extractors/mkv/Android.bp b/media/extractors/mkv/Android.bp
index 681fd35..1744d3d 100644
--- a/media/extractors/mkv/Android.bp
+++ b/media/extractors/mkv/Android.bp
@@ -11,7 +11,7 @@
 
     shared_libs: [
         "liblog",
-        "libmediaextractor",
+        "libmediandk",
     ],
 
     static_libs: [
@@ -40,9 +40,6 @@
             "unsigned-integer-overflow",
             "signed-integer-overflow",
         ],
-        diag: {
-            cfi: true,
-        },
     },
 
 }
diff --git a/media/extractors/mkv/MatroskaExtractor.cpp b/media/extractors/mkv/MatroskaExtractor.cpp
index d657582..23022e4 100644
--- a/media/extractors/mkv/MatroskaExtractor.cpp
+++ b/media/extractors/mkv/MatroskaExtractor.cpp
@@ -20,21 +20,20 @@
 
 #include "FLACDecoder.h"
 #include "MatroskaExtractor.h"
+#include "common/webmids.h"
 
 #include <media/DataSourceBase.h>
 #include <media/ExtractorUtils.h>
-#include <media/MediaTrack.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AUtils.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ByteUtils.h>
 #include <media/stagefright/foundation/ColorUtils.h>
 #include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/MediaBufferBase.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/MetaData.h>
 #include <media/stagefright/MetaDataUtils.h>
+#include <media/stagefright/foundation/avc_utils.h>
 #include <utils/String8.h>
 
 #include <arpa/inet.h>
@@ -44,7 +43,7 @@
 namespace android {
 
 struct DataSourceBaseReader : public mkvparser::IMkvReader {
-    explicit DataSourceBaseReader(DataSourceBase *source)
+    explicit DataSourceBaseReader(DataSourceHelper *source)
         : mSource(source) {
     }
 
@@ -68,8 +67,12 @@
     virtual int Length(long long* total, long long* available) {
         off64_t size;
         if (mSource->getSize(&size) != OK) {
-            *total = -1;
-            *available = (long long)((1ull << 63) - 1);
+            if (total) {
+                *total = -1;
+            }
+            if (available) {
+                *available = (long long)((1ull << 63) - 1);
+            }
 
             return 0;
         }
@@ -86,7 +89,7 @@
     }
 
 private:
-    DataSourceBase *mSource;
+    DataSourceHelper *mSource;
 
     DataSourceBaseReader(const DataSourceBaseReader &);
     DataSourceBaseReader &operator=(const DataSourceBaseReader &);
@@ -118,22 +121,25 @@
     const mkvparser::BlockEntry *mBlockEntry;
     long mBlockEntryIndex;
 
+    unsigned long mTrackType;
+    void seekwithoutcue_l(int64_t seekTimeUs, int64_t *actualFrameTimeUs);
+
     void advance_l();
 
     BlockIterator(const BlockIterator &);
     BlockIterator &operator=(const BlockIterator &);
 };
 
-struct MatroskaSource : public MediaTrack {
+struct MatroskaSource : public MediaTrackHelper {
     MatroskaSource(MatroskaExtractor *extractor, size_t index);
 
-    virtual status_t start(MetaDataBase *params);
-    virtual status_t stop();
+    virtual media_status_t start();
+    virtual media_status_t stop();
 
-    virtual status_t getFormat(MetaDataBase &);
+    virtual media_status_t getFormat(AMediaFormat *);
 
-    virtual status_t read(
-            MediaBufferBase **buffer, const ReadOptions *options);
+    virtual media_status_t read(
+            MediaBufferHelper **buffer, const ReadOptions *options);
 
 protected:
     virtual ~MatroskaSource();
@@ -143,6 +149,9 @@
         AVC,
         AAC,
         HEVC,
+        MP3,
+        PCM,
+        VORBIS,
         OTHER
     };
 
@@ -153,12 +162,21 @@
     BlockIterator mBlockIter;
     ssize_t mNALSizeLen;  // for type AVC or HEVC
 
-    List<MediaBufferBase *> mPendingFrames;
+    List<MediaBufferHelper *> mPendingFrames;
+
+    int64_t mCurrentTS; // add for mp3
+    uint32_t mMP3Header;
+
+    media_status_t findMP3Header(uint32_t * header,
+        const uint8_t *dataSource, int length, int *outStartPos);
+    media_status_t mp3FrameRead(
+            MediaBufferHelper **out, const ReadOptions *options,
+            int64_t targetSampleTimeUs);
 
     status_t advance();
 
-    status_t setWebmBlockCryptoInfo(MediaBufferBase *mbuf);
-    status_t readBlock();
+    status_t setWebmBlockCryptoInfo(MediaBufferHelper *mbuf);
+    media_status_t readBlock();
     void clearPendingFrames();
 
     MatroskaSource(const MatroskaSource &);
@@ -221,47 +239,43 @@
       mBlockIter(mExtractor,
                  mExtractor->mTracks.itemAt(index).mTrackNum,
                  index),
-      mNALSizeLen(-1) {
-    MetaDataBase &meta = mExtractor->mTracks.editItemAt(index).mMeta;
+      mNALSizeLen(-1),
+      mCurrentTS(0),
+      mMP3Header(0) {
+    MatroskaExtractor::TrackInfo &trackInfo = mExtractor->mTracks.editItemAt(index);
+    AMediaFormat *meta = trackInfo.mMeta;
 
     const char *mime;
-    CHECK(meta.findCString(kKeyMIMEType, &mime));
+    CHECK(AMediaFormat_getString(meta, AMEDIAFORMAT_KEY_MIME, &mime));
 
     mIsAudio = !strncasecmp("audio/", mime, 6);
 
     if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
         mType = AVC;
 
-        uint32_t dummy;
-        const uint8_t *avcc;
-        size_t avccSize;
-        int32_t nalSizeLen = 0;
-        if (meta.findInt32(kKeyNalLengthSize, &nalSizeLen)) {
-            if (nalSizeLen >= 0 && nalSizeLen <= 4) {
-                mNALSizeLen = nalSizeLen;
-            }
-        } else if (meta.findData(kKeyAVCC, &dummy, (const void **)&avcc, &avccSize)
-                && avccSize >= 5u) {
-            mNALSizeLen = 1 + (avcc[4] & 3);
-            ALOGV("mNALSizeLen = %zd", mNALSizeLen);
+        int32_t nalSizeLen = trackInfo.mNalLengthSize;
+        if (nalSizeLen >= 0 && nalSizeLen <= 4) {
+            mNALSizeLen = nalSizeLen;
         } else {
-            ALOGE("No mNALSizeLen");
+            ALOGE("No AVC mNALSizeLen");
         }
     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) {
         mType = HEVC;
 
-        uint32_t dummy;
-        const uint8_t *hvcc;
-        size_t hvccSize;
-        if (meta.findData(kKeyHVCC, &dummy, (const void **)&hvcc, &hvccSize)
-                && hvccSize >= 22u) {
-            mNALSizeLen = 1 + (hvcc[14+7] & 3);
-            ALOGV("mNALSizeLen = %zu", mNALSizeLen);
+        int32_t nalSizeLen = trackInfo.mNalLengthSize;
+        if (nalSizeLen >= 0 && nalSizeLen <= 4) {
+            mNALSizeLen = nalSizeLen;
         } else {
-            ALOGE("No mNALSizeLen");
+            ALOGE("No HEVC mNALSizeLen");
         }
     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
         mType = AAC;
+    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
+        mType = MP3;
+    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
+        mType = PCM;
+    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
+        mType = VORBIS;
     }
 }
 
@@ -269,25 +283,36 @@
     clearPendingFrames();
 }
 
-status_t MatroskaSource::start(MetaDataBase * /* params */) {
+media_status_t MatroskaSource::start() {
     if (mType == AVC && mNALSizeLen < 0) {
-        return ERROR_MALFORMED;
+        return AMEDIA_ERROR_MALFORMED;
     }
 
+    // allocate one small initial buffer, but leave plenty of room to grow
+    mBufferGroup->init(1 /* number of buffers */, 1024 /* buffer size */, 64 /* growth limit */);
     mBlockIter.reset();
 
-    return OK;
+    if (mType == MP3 && mMP3Header == 0) {
+        int start = -1;
+        media_status_t err = findMP3Header(&mMP3Header, NULL, 0, &start);
+        if (err != OK) {
+            ALOGE("No mp3 header found");
+            clearPendingFrames();
+            return err;
+        }
+    }
+
+    return AMEDIA_OK;
 }
 
-status_t MatroskaSource::stop() {
+media_status_t MatroskaSource::stop() {
     clearPendingFrames();
 
-    return OK;
+    return AMEDIA_OK;
 }
 
-status_t MatroskaSource::getFormat(MetaDataBase &meta) {
-    meta = mExtractor->mTracks.itemAt(mTrackIndex).mMeta;
-    return OK;
+media_status_t MatroskaSource::getFormat(AMediaFormat *meta) {
+    return AMediaFormat_copy(meta, mExtractor->mTracks.itemAt(mTrackIndex).mMeta);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -300,6 +325,7 @@
       mCluster(NULL),
       mBlockEntry(NULL),
       mBlockEntryIndex(0) {
+    mTrackType = mExtractor->mSegment->GetTracks()->GetTrackByNumber(trackNum)->GetType();
     reset();
 }
 
@@ -442,7 +468,7 @@
         for (size_t index = 0; index < count; index++) {
             pEntry = pSH->GetEntry(index);
 
-            if (pEntry->id == 0x0C53BB6B) { // Cues ID
+            if (pEntry->id == libwebm::kMkvCues) { // Cues ID
                 long len; long long pos;
                 pSegment->ParseCues(pEntry->pos, pos, len);
                 pCues = pSegment->GetCues();
@@ -452,12 +478,14 @@
         }
 
         if (!pCues) {
-            ALOGE("No Cues in file");
+            ALOGV("No Cues in file,seek without cue data");
+            seekwithoutcue_l(seekTimeUs, actualFrameTimeUs);
             return;
         }
     }
     else if (!pSH) {
-        ALOGE("No SeekHead");
+        ALOGV("No SeekHead, seek without cue data");
+        seekwithoutcue_l(seekTimeUs, actualFrameTimeUs);
         return;
     }
 
@@ -466,7 +494,9 @@
     while (!pCues->DoneParsing()) {
         pCues->LoadCuePoint();
         pCP = pCues->GetLast();
-        CHECK(pCP);
+        ALOGV("pCP = %s", pCP == NULL ? "NULL" : "not NULL");
+        if (pCP == NULL)
+            continue;
 
         size_t trackCount = mExtractor->mTracks.size();
         for (size_t index = 0; index < trackCount; ++index) {
@@ -504,6 +534,7 @@
     // Always *search* based on the video track, but finalize based on mTrackNum
     if (!pTP) {
         ALOGE("Did not locate the video track for seeking");
+        seekwithoutcue_l(seekTimeUs, actualFrameTimeUs);
         return;
     }
 
@@ -547,6 +578,31 @@
     return (mBlockEntry->GetBlock()->GetTime(mCluster) + 500ll) / 1000ll;
 }
 
+void BlockIterator::seekwithoutcue_l(int64_t seekTimeUs, int64_t *actualFrameTimeUs) {
+    mCluster = mExtractor->mSegment->FindCluster(seekTimeUs * 1000ll);
+    const long status = mCluster->GetFirst(mBlockEntry);
+    if (status < 0) {  // error
+        ALOGE("get last blockenry failed!");
+        mCluster = NULL;
+        return;
+    }
+    mBlockEntryIndex = 0;
+    while (!eos() && ((block()->GetTrackNumber() != mTrackNum) || (blockTimeUs() < seekTimeUs))) {
+        advance_l();
+    }
+
+    // video track will seek to the next key frame.
+    if (mTrackType == 1) {
+        while (!eos() && ((block()->GetTrackNumber() != mTrackNum) ||
+                      !mBlockEntry->GetBlock()->IsKey())) {
+            advance_l();
+        }
+    }
+    *actualFrameTimeUs = blockTimeUs();
+     ALOGV("seekTimeUs:%lld, actualFrameTimeUs:%lld, tracknum:%lld",
+              (long long)seekTimeUs, (long long)*actualFrameTimeUs, (long long)mTrackNum);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 
 static unsigned U24_AT(const uint8_t *ptr) {
@@ -579,7 +635,7 @@
 
 void MatroskaSource::clearPendingFrames() {
     while (!mPendingFrames.empty()) {
-        MediaBufferBase *frame = *mPendingFrames.begin();
+        MediaBufferHelper *frame = *mPendingFrames.begin();
         mPendingFrames.erase(mPendingFrames.begin());
 
         frame->release();
@@ -587,7 +643,7 @@
     }
 }
 
-status_t MatroskaSource::setWebmBlockCryptoInfo(MediaBufferBase *mbuf) {
+status_t MatroskaSource::setWebmBlockCryptoInfo(MediaBufferHelper *mbuf) {
     if (mbuf->range_length() < 1 || mbuf->range_length() - 1 > INT32_MAX) {
         // 1-byte signal
         return ERROR_MALFORMED;
@@ -601,17 +657,17 @@
         return ERROR_MALFORMED;
     }
 
-    MetaDataBase &meta = mbuf->meta_data();
+    AMediaFormat *meta = mbuf->meta_data();
     if (encrypted) {
         uint8_t ctrCounter[16] = { 0 };
-        uint32_t type;
         const uint8_t *keyId;
         size_t keyIdSize;
-        const MetaDataBase &trackMeta = mExtractor->mTracks.itemAt(mTrackIndex).mMeta;
-        CHECK(trackMeta.findData(kKeyCryptoKey, &type, (const void **)&keyId, &keyIdSize));
-        meta.setData(kKeyCryptoKey, 0, keyId, keyIdSize);
+        AMediaFormat *trackMeta = mExtractor->mTracks.itemAt(mTrackIndex).mMeta;
+        AMediaFormat_getBuffer(trackMeta, AMEDIAFORMAT_KEY_CRYPTO_KEY,
+                (void**)&keyId, &keyIdSize);
+        AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_KEY, keyId, keyIdSize);
         memcpy(ctrCounter, data + 1, 8);
-        meta.setData(kKeyCryptoIV, 0, ctrCounter, 16);
+        AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_IV, ctrCounter, 16);
         if (partitioned) {
             /*  0                   1                   2                   3
              *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
@@ -664,8 +720,10 @@
             }
             uint32_t sizeofPlainSizes = sizeof(uint32_t) * plainSizes.size();
             uint32_t sizeofEncryptedSizes = sizeof(uint32_t) * encryptedSizes.size();
-            meta.setData(kKeyPlainSizes, 0, plainSizes.data(), sizeofPlainSizes);
-            meta.setData(kKeyEncryptedSizes, 0, encryptedSizes.data(), sizeofEncryptedSizes);
+            AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES,
+                    plainSizes.data(), sizeofPlainSizes);
+            AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES,
+                    encryptedSizes.data(), sizeofEncryptedSizes);
             mbuf->set_range(frameOffset, mbuf->range_length() - frameOffset);
         } else {
             /*
@@ -685,8 +743,10 @@
              */
             int32_t plainSizes[] = { 0 };
             int32_t encryptedSizes[] = { static_cast<int32_t>(mbuf->range_length() - 9) };
-            meta.setData(kKeyPlainSizes, 0, plainSizes, sizeof(plainSizes));
-            meta.setData(kKeyEncryptedSizes, 0, encryptedSizes, sizeof(encryptedSizes));
+            AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES,
+                    plainSizes, sizeof(plainSizes));
+            AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES,
+                    encryptedSizes, sizeof(encryptedSizes));
             mbuf->set_range(9, mbuf->range_length() - 9);
         }
     } else {
@@ -703,19 +763,21 @@
          */
         int32_t plainSizes[] = { static_cast<int32_t>(mbuf->range_length() - 1) };
         int32_t encryptedSizes[] = { 0 };
-        meta.setData(kKeyPlainSizes, 0, plainSizes, sizeof(plainSizes));
-        meta.setData(kKeyEncryptedSizes, 0, encryptedSizes, sizeof(encryptedSizes));
+        AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES,
+                plainSizes, sizeof(plainSizes));
+        AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES,
+                encryptedSizes, sizeof(encryptedSizes));
         mbuf->set_range(1, mbuf->range_length() - 1);
     }
 
     return OK;
 }
 
-status_t MatroskaSource::readBlock() {
+media_status_t MatroskaSource::readBlock() {
     CHECK(mPendingFrames.empty());
 
     if (mBlockIter.eos()) {
-        return ERROR_END_OF_STREAM;
+        return AMEDIA_ERROR_END_OF_STREAM;
     }
 
     const mkvparser::Block *block = mBlockIter.block();
@@ -727,18 +789,41 @@
         const mkvparser::Block::Frame &frame = block->GetFrame(i);
         size_t len = frame.len;
         if (SIZE_MAX - len < trackInfo->mHeaderLen) {
-            return ERROR_MALFORMED;
+            return AMEDIA_ERROR_MALFORMED;
         }
 
         len += trackInfo->mHeaderLen;
-        MediaBufferBase *mbuf = MediaBufferBase::Create(len);
+        MediaBufferHelper *mbuf;
+        mBufferGroup->acquire_buffer(&mbuf, false /* nonblocking */, len /* requested size */);
+        mbuf->set_range(0, len);
         uint8_t *data = static_cast<uint8_t *>(mbuf->data());
         if (trackInfo->mHeader) {
             memcpy(data, trackInfo->mHeader, trackInfo->mHeaderLen);
         }
 
-        mbuf->meta_data().setInt64(kKeyTime, timeUs);
-        mbuf->meta_data().setInt32(kKeyIsSyncFrame, block->IsKey());
+        AMediaFormat *meta = mbuf->meta_data();
+        AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeUs);
+        AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, block->IsKey());
+
+        if (mType == VORBIS) {
+            int32_t sampleRate;
+            if (!AMediaFormat_getInt32(trackInfo->mMeta, AMEDIAFORMAT_KEY_SAMPLE_RATE,
+                                       &sampleRate)) {
+                return AMEDIA_ERROR_MALFORMED;
+            }
+            int64_t durationUs;
+            if (!AMediaFormat_getInt64(trackInfo->mMeta, AMEDIAFORMAT_KEY_DURATION,
+                                       &durationUs)) {
+                return AMEDIA_ERROR_MALFORMED;
+            }
+            // TODO: Explore if this can be handled similar to MPEG4 extractor where padding is
+            // signalled instead of VALID_SAMPLES
+            // Remaining valid samples in Vorbis track
+            if (durationUs > timeUs) {
+                int32_t validSamples = ((durationUs - timeUs) * sampleRate) / 1000000ll;
+                AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, validSamples);
+            }
+        }
 
         status_t err = frame.Read(mExtractor->mReader, data + trackInfo->mHeaderLen);
         if (err == OK
@@ -752,7 +837,7 @@
 
             mBlockIter.advance();
             mbuf->release();
-            return err;
+            return AMEDIA_ERROR_UNKNOWN;
         }
 
         mPendingFrames.push_back(mbuf);
@@ -760,11 +845,193 @@
 
     mBlockIter.advance();
 
-    return OK;
+    return AMEDIA_OK;
 }
 
-status_t MatroskaSource::read(
-        MediaBufferBase **out, const ReadOptions *options) {
+//the value of kMP3HeaderMask is from MP3Extractor
+static const uint32_t kMP3HeaderMask = 0xfffe0c00;
+
+media_status_t MatroskaSource::findMP3Header(uint32_t * header,
+        const uint8_t *dataSource, int length, int *outStartPos) {
+    if (NULL == header) {
+        ALOGE("header is null!");
+        return AMEDIA_ERROR_END_OF_STREAM;
+    }
+
+    //to find header start position
+    if (0 != *header) {
+        if (NULL == dataSource) {
+            *outStartPos = -1;
+            return AMEDIA_OK;
+        }
+        uint32_t tmpCode = 0;
+        for (int i = 0; i < length; i++) {
+            tmpCode = (tmpCode << 8) + dataSource[i];
+            if ((tmpCode & kMP3HeaderMask) == (*header & kMP3HeaderMask)) {
+                *outStartPos = i - 3;
+                return AMEDIA_OK;
+            }
+        }
+        *outStartPos = -1;
+        return AMEDIA_OK;
+    }
+
+    //to find mp3 header
+    uint32_t code = 0;
+    while (0 == *header) {
+        while (mPendingFrames.empty()) {
+            media_status_t err = readBlock();
+            if (err != OK) {
+                clearPendingFrames();
+                return err;
+            }
+        }
+        MediaBufferHelper *frame = *mPendingFrames.begin();
+        size_t size = frame->range_length();
+        size_t offset = frame->range_offset();
+        size_t i;
+        size_t frame_size;
+        for (i = 0; i < size; i++) {
+            ALOGV("data[%zu]=%x", i, *((uint8_t*)frame->data() + offset + i));
+            code = (code << 8) + *((uint8_t*)frame->data() + offset + i);
+            if (GetMPEGAudioFrameSize(code, &frame_size, NULL, NULL, NULL)) {
+                *header = code;
+                mBlockIter.reset();
+                clearPendingFrames();
+                return AMEDIA_OK;
+            }
+        }
+    }
+
+    return AMEDIA_ERROR_END_OF_STREAM;
+}
+
+media_status_t MatroskaSource::mp3FrameRead(
+        MediaBufferHelper **out, const ReadOptions *options,
+        int64_t targetSampleTimeUs) {
+    MediaBufferHelper *frame = *mPendingFrames.begin();
+    int64_t seekTimeUs;
+    ReadOptions::SeekMode mode;
+    if (options && options->getSeekTo(&seekTimeUs, &mode)) {
+        CHECK(AMediaFormat_getInt64(frame->meta_data(),
+                    AMEDIAFORMAT_KEY_TIME_US, &mCurrentTS));
+        if (mCurrentTS < 0) {
+            mCurrentTS = 0;
+            AMediaFormat_setInt64(frame->meta_data(),
+                    AMEDIAFORMAT_KEY_TIME_US, mCurrentTS);
+        }
+    }
+
+    int32_t start = -1;
+    while (start < 0) {
+        //find header start position
+        findMP3Header(&mMP3Header,
+            (const uint8_t*)frame->data() + frame->range_offset(),
+            frame->range_length(), &start);
+        ALOGV("start=%d, frame->range_length() = %zu, frame->range_offset() =%zu",
+                      start, frame->range_length(), frame->range_offset());
+        if (start >= 0)
+            break;
+        frame->release();
+        mPendingFrames.erase(mPendingFrames.begin());
+        while (mPendingFrames.empty()) {
+            media_status_t err = readBlock();
+            if (err != OK) {
+                clearPendingFrames();
+                return err;
+            }
+        }
+        frame = *mPendingFrames.begin();
+    }
+
+    frame->set_range(frame->range_offset() + start, frame->range_length() - start);
+
+    uint32_t header = *(uint32_t*)((uint8_t*)frame->data() + frame->range_offset());
+    header = ((header >> 24) & 0xff) | ((header >> 8) & 0xff00) |
+                    ((header << 8) & 0xff0000) | ((header << 24) & 0xff000000);
+    size_t frame_size;
+    int out_sampling_rate;
+    int out_channels;
+    int out_bitrate;
+    if (!GetMPEGAudioFrameSize(header, &frame_size,
+                               &out_sampling_rate, &out_channels, &out_bitrate)) {
+        ALOGE("MP3 Header read fail!!");
+        return AMEDIA_ERROR_UNSUPPORTED;
+    }
+
+    MediaBufferHelper *buffer;
+    mBufferGroup->acquire_buffer(&buffer, false /* nonblocking */, frame_size /* requested size */);
+    buffer->set_range(0, frame_size);
+
+    uint8_t *data = static_cast<uint8_t *>(buffer->data());
+    ALOGV("MP3 frame %zu frame->range_length() %zu", frame_size, frame->range_length());
+
+    if (frame_size > frame->range_length()) {
+        memcpy(data, (uint8_t*)(frame->data()) + frame->range_offset(), frame->range_length());
+        size_t sumSize = 0;
+        sumSize += frame->range_length();
+        size_t needSize = frame_size - frame->range_length();
+        frame->release();
+        mPendingFrames.erase(mPendingFrames.begin());
+        while (mPendingFrames.empty()) {
+            media_status_t err = readBlock();
+            if (err != OK) {
+                clearPendingFrames();
+                return err;
+            }
+        }
+        frame = *mPendingFrames.begin();
+        size_t offset = frame->range_offset();
+        size_t size = frame->range_length();
+
+        // the next buffer frame is not enough to fullfill mp3 frame,
+        // we have to read until mp3 frame is completed.
+        while (size < needSize) {
+            memcpy(data + sumSize, (uint8_t*)(frame->data()) + offset, size);
+            needSize -= size;
+            sumSize += size;
+            frame->release();
+            mPendingFrames.erase(mPendingFrames.begin());
+            while (mPendingFrames.empty()) {
+                media_status_t err = readBlock();
+                if (err != OK) {
+                    clearPendingFrames();
+                    return err;
+                }
+            }
+            frame = *mPendingFrames.begin();
+            offset = frame->range_offset();
+            size = frame->range_length();
+        }
+        memcpy(data + sumSize, (uint8_t*)(frame->data()) + offset, needSize);
+        frame->set_range(offset + needSize, size - needSize);
+     } else {
+        size_t offset = frame->range_offset();
+        size_t size = frame->range_length();
+        memcpy(data, (uint8_t*)(frame->data()) + offset, frame_size);
+        frame->set_range(offset + frame_size, size - frame_size);
+    }
+    if (frame->range_length() < 4) {
+        frame->release();
+        frame = NULL;
+        mPendingFrames.erase(mPendingFrames.begin());
+    }
+    ALOGV("MatroskaSource::read MP3 frame kKeyTime=%lld,kKeyTargetTime=%lld",
+                    (long long)mCurrentTS, (long long)targetSampleTimeUs);
+    AMediaFormat_setInt64(buffer->meta_data(),
+            AMEDIAFORMAT_KEY_TIME_US, mCurrentTS);
+    mCurrentTS += (int64_t)frame_size * 8000ll / out_bitrate;
+
+    if (targetSampleTimeUs >= 0ll)
+        AMediaFormat_setInt64(buffer->meta_data(),
+                AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
+    *out = buffer;
+    ALOGV("MatroskaSource::read MP3, keyTime=%lld for next frame", (long long)mCurrentTS);
+    return AMEDIA_OK;
+}
+
+media_status_t MatroskaSource::read(
+        MediaBufferHelper **out, const ReadOptions *options) {
     *out = NULL;
 
     int64_t targetSampleTimeUs = -1ll;
@@ -773,7 +1040,7 @@
     ReadOptions::SeekMode mode;
     if (options && options->getSeekTo(&seekTimeUs, &mode)) {
         if (mode == ReadOptions::SEEK_FRAME_INDEX) {
-            return ERROR_UNSUPPORTED;
+            return AMEDIA_ERROR_UNSUPPORTED;
         }
 
         if (!mExtractor->isLiveStreaming()) {
@@ -791,7 +1058,7 @@
     }
 
     while (mPendingFrames.empty()) {
-        status_t err = readBlock();
+        media_status_t err = readBlock();
 
         if (err != OK) {
             clearPendingFrames();
@@ -800,18 +1067,43 @@
         }
     }
 
-    MediaBufferBase *frame = *mPendingFrames.begin();
+    if (mType == MP3) {
+        return mp3FrameRead(out, options, targetSampleTimeUs);
+    }
+
+    MediaBufferHelper *frame = *mPendingFrames.begin();
     mPendingFrames.erase(mPendingFrames.begin());
 
     if ((mType != AVC && mType != HEVC) || mNALSizeLen == 0) {
         if (targetSampleTimeUs >= 0ll) {
-            frame->meta_data().setInt64(
-                    kKeyTargetTime, targetSampleTimeUs);
+            AMediaFormat_setInt64(frame->meta_data(),
+                    AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
+        }
+
+        if (mType == PCM) {
+            int32_t bitPerFrame = 16;
+            int32_t bigEndian = 0;
+            AMediaFormat *meta = AMediaFormat_new();
+            if (getFormat(meta) == AMEDIA_OK && meta != NULL) {
+                AMediaFormat_getInt32(meta,
+                                AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, &bitPerFrame);
+                AMediaFormat_getInt32(meta,
+                                AMEDIAFORMAT_KEY_PCM_BIG_ENDIAN, &bigEndian);
+            }
+            AMediaFormat_delete(meta);
+            if (bigEndian == 1 && bitPerFrame == 16) {
+                // Big-endian -> little-endian
+                uint16_t *dstData = (uint16_t *)frame->data() + frame->range_offset();
+                uint16_t *srcData = (uint16_t *)frame->data() + frame->range_offset();
+                for (size_t i = 0; i < frame->range_length() / 2; i++) {
+                    dstData[i] = ntohs(srcData[i]);
+                }
+            }
         }
 
         *out = frame;
 
-        return OK;
+        return AMEDIA_OK;
     }
 
     // Each input frame contains one or more NAL fragments, each fragment
@@ -829,7 +1121,7 @@
     size_t srcSize = frame->range_length();
 
     size_t dstSize = 0;
-    MediaBufferBase *buffer = NULL;
+    MediaBufferHelper *buffer = NULL;
     uint8_t *dstPtr = NULL;
 
     for (int32_t pass = 0; pass < 2; ++pass) {
@@ -850,7 +1142,7 @@
                 frame->release();
                 frame = NULL;
 
-                return ERROR_MALFORMED;
+                return AMEDIA_ERROR_MALFORMED;
             } else if (srcOffset + mNALSizeLen + NALsize > srcSize) {
                 break;
             }
@@ -878,7 +1170,7 @@
             frame->release();
             frame = NULL;
 
-            return ERROR_MALFORMED;
+            return AMEDIA_ERROR_MALFORMED;
         }
 
         if (pass == 0) {
@@ -889,16 +1181,20 @@
                 // each 4-byte nal size with a 4-byte start code
                 buffer = frame;
             } else {
-                buffer = MediaBufferBase::Create(dstSize);
+                mBufferGroup->acquire_buffer(
+                        &buffer, false /* nonblocking */, dstSize /* requested size */);
+                buffer->set_range(0, dstSize);
             }
 
+            AMediaFormat *frameMeta = frame->meta_data();
             int64_t timeUs;
-            CHECK(frame->meta_data().findInt64(kKeyTime, &timeUs));
+            CHECK(AMediaFormat_getInt64(frameMeta, AMEDIAFORMAT_KEY_TIME_US, &timeUs));
             int32_t isSync;
-            CHECK(frame->meta_data().findInt32(kKeyIsSyncFrame, &isSync));
+            CHECK(AMediaFormat_getInt32(frameMeta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, &isSync));
 
-            buffer->meta_data().setInt64(kKeyTime, timeUs);
-            buffer->meta_data().setInt32(kKeyIsSyncFrame, isSync);
+            AMediaFormat *bufMeta = buffer->meta_data();
+            AMediaFormat_setInt64(bufMeta, AMEDIAFORMAT_KEY_TIME_US, timeUs);
+            AMediaFormat_setInt32(bufMeta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, isSync);
 
             dstPtr = (uint8_t *)buffer->data();
         }
@@ -910,18 +1206,116 @@
     }
 
     if (targetSampleTimeUs >= 0ll) {
-        buffer->meta_data().setInt64(
-                kKeyTargetTime, targetSampleTimeUs);
+        AMediaFormat_setInt64(buffer->meta_data(),
+                AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
     }
 
     *out = buffer;
 
-    return OK;
+    return AMEDIA_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
-MatroskaExtractor::MatroskaExtractor(DataSourceBase *source)
+enum WaveID {
+    MKV_RIFF_WAVE_FORMAT_PCM = 0x0001,
+    MKV_RIFF_WAVE_FORMAT_ADPCM_ms = 0x0002,
+    MKV_RIFF_WAVE_FORMAT_ADPCM_ima_wav = 0x0011,
+    MKV_RIFF_WAVE_FORMAT_MPEGL12 = 0x0050,
+    MKV_RIFF_WAVE_FORMAT_MPEGL3 = 0x0055,
+    MKV_RIFF_WAVE_FORMAT_WMAV1 = 0x0160,
+    MKV_RIFF_WAVE_FORMAT_WMAV2 = 0x0161,
+};
+
+static const char *MKVWave2MIME(uint16_t id) {
+    switch (id) {
+        case  MKV_RIFF_WAVE_FORMAT_MPEGL12:
+            return MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II;
+
+        case  MKV_RIFF_WAVE_FORMAT_MPEGL3:
+            return MEDIA_MIMETYPE_AUDIO_MPEG;
+
+        case MKV_RIFF_WAVE_FORMAT_PCM:
+            return MEDIA_MIMETYPE_AUDIO_RAW;
+
+        case MKV_RIFF_WAVE_FORMAT_ADPCM_ms:
+            return MEDIA_MIMETYPE_AUDIO_MS_ADPCM;
+        case MKV_RIFF_WAVE_FORMAT_ADPCM_ima_wav:
+            return MEDIA_MIMETYPE_AUDIO_DVI_IMA_ADPCM;
+
+        case MKV_RIFF_WAVE_FORMAT_WMAV1:
+        case MKV_RIFF_WAVE_FORMAT_WMAV2:
+            return MEDIA_MIMETYPE_AUDIO_WMA;
+        default:
+            ALOGW("unknown wave %x", id);
+            return "";
+    };
+}
+
+static bool isMkvAudioCsdSizeOK(const char* mime, size_t csdSize) {
+    if ((!strcmp(mime, MEDIA_MIMETYPE_AUDIO_MS_ADPCM) && csdSize < 50) ||
+        (!strcmp(mime, MEDIA_MIMETYPE_AUDIO_DVI_IMA_ADPCM) && csdSize < 20) ||
+        (!strcmp(mime, MEDIA_MIMETYPE_AUDIO_WMA) && csdSize < 28) ||
+        (!strcmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG) && csdSize < 30)) {
+        return false;
+    }
+    return true;
+}
+
+// trans all FOURCC  to lower char
+static uint32_t FourCCtoLower(uint32_t fourcc) {
+    uint8_t ch_1 = tolower((fourcc >> 24) & 0xff);
+    uint8_t ch_2 = tolower((fourcc >> 16) & 0xff);
+    uint8_t ch_3 = tolower((fourcc >> 8) & 0xff);
+    uint8_t ch_4 = tolower((fourcc) & 0xff);
+    uint32_t fourcc_out = ch_1 << 24 | ch_2 << 16 | ch_3 << 8 | ch_4;
+
+    return fourcc_out;
+}
+
+static const char *MKVFourCC2MIME(uint32_t fourcc) {
+    ALOGV("MKVFourCC2MIME fourcc 0x%8.8x", fourcc);
+    uint32_t lowerFourcc = FourCCtoLower(fourcc);
+    switch (lowerFourcc) {
+        case FOURCC("mp4v"):
+            return MEDIA_MIMETYPE_VIDEO_MPEG4;
+
+        case FOURCC("s263"):
+        case FOURCC("h263"):
+            return MEDIA_MIMETYPE_VIDEO_H263;
+
+        case FOURCC("avc1"):
+        case FOURCC("h264"):
+            return MEDIA_MIMETYPE_VIDEO_AVC;
+
+        case FOURCC("mpg2"):
+            return MEDIA_MIMETYPE_VIDEO_MPEG2;
+
+        case FOURCC("xvid"):
+            return MEDIA_MIMETYPE_VIDEO_XVID;
+
+        case FOURCC("divx"):
+        case FOURCC("dx50"):
+            return MEDIA_MIMETYPE_VIDEO_DIVX;
+
+        case FOURCC("div3"):
+        case FOURCC("div4"):
+            return MEDIA_MIMETYPE_VIDEO_DIVX3;
+
+        case FOURCC("mjpg"):
+        case FOURCC("mppg"):
+            return MEDIA_MIMETYPE_VIDEO_MJPEG;
+
+        default:
+            char fourccString[5];
+            MakeFourCCString(fourcc, fourccString);
+            ALOGW("mkv unsupport fourcc %s", fourccString);
+            return "";
+    }
+}
+
+
+MatroskaExtractor::MatroskaExtractor(DataSourceHelper *source)
     : mDataSource(source),
       mReader(new DataSourceBaseReader(mDataSource)),
       mSegment(NULL),
@@ -953,17 +1347,56 @@
         return;
     }
 
-    // from mkvparser::Segment::Load(), but stop at first cluster
-    ret = mSegment->ParseHeaders();
-    if (ret == 0) {
-        long len;
-        ret = mSegment->LoadCluster(pos, len);
-        if (ret >= 1) {
-            // no more clusters
-            ret = 0;
+    if (mIsLiveStreaming) {
+        // from mkvparser::Segment::Load(), but stop at first cluster
+        ret = mSegment->ParseHeaders();
+        if (ret == 0) {
+            long len;
+            ret = mSegment->LoadCluster(pos, len);
+            if (ret >= 1) {
+                // no more clusters
+                ret = 0;
+            }
+        } else if (ret > 0) {
+            ret = mkvparser::E_BUFFER_NOT_FULL;
         }
-    } else if (ret > 0) {
-        ret = mkvparser::E_BUFFER_NOT_FULL;
+    } else {
+        ret = mSegment->ParseHeaders();
+        if (ret < 0) {
+            ALOGE("Segment parse header return fail %lld", ret);
+            delete mSegment;
+            mSegment = NULL;
+            return;
+        } else if (ret == 0) {
+            const mkvparser::Cues* mCues = mSegment->GetCues();
+            const mkvparser::SeekHead* mSH = mSegment->GetSeekHead();
+            if ((mCues == NULL) && (mSH != NULL)) {
+                size_t count = mSH->GetCount();
+                const mkvparser::SeekHead::Entry* mEntry;
+                for (size_t index = 0; index < count; index++) {
+                    mEntry = mSH->GetEntry(index);
+                    if (mEntry->id == libwebm::kMkvCues) { // Cues ID
+                        long len;
+                        long long pos;
+                        mSegment->ParseCues(mEntry->pos, pos, len);
+                        mCues = mSegment->GetCues();
+                        ALOGV("find cue data by seekhead");
+                        break;
+                    }
+                }
+            }
+
+            if (mCues) {
+                long len;
+                ret = mSegment->LoadCluster(pos, len);
+                ALOGV("has Cue data, Cluster num=%ld", mSegment->GetCount());
+            } else  {
+                long status_Load = mSegment->Load();
+                ALOGW("no Cue data,Segment Load status:%ld",status_Load);
+            }
+        } else if (ret > 0) {
+            ret = mkvparser::E_BUFFER_NOT_FULL;
+        }
     }
 
     if (ret < 0) {
@@ -994,13 +1427,22 @@
 
     delete mReader;
     mReader = NULL;
+
+    delete mDataSource;
+
+    for (size_t i = 0; i < mTracks.size(); ++i) {
+        TrackInfo *info = &mTracks.editItemAt(i);
+        if (info->mMeta) {
+            AMediaFormat_delete(info->mMeta);
+        }
+    }
 }
 
 size_t MatroskaExtractor::countTracks() {
     return mTracks.size();
 }
 
-MediaTrack *MatroskaExtractor::getTrack(size_t index) {
+MediaTrackHelper *MatroskaExtractor::getTrack(size_t index) {
     if (index >= mTracks.size()) {
         return NULL;
     }
@@ -1008,11 +1450,11 @@
     return new MatroskaSource(this, index);
 }
 
-status_t MatroskaExtractor::getTrackMetaData(
-        MetaDataBase &meta,
+media_status_t MatroskaExtractor::getTrackMetaData(
+        AMediaFormat *meta,
         size_t index, uint32_t flags) {
     if (index >= mTracks.size()) {
-        return UNKNOWN_ERROR;
+        return AMEDIA_ERROR_UNKNOWN;
     }
 
     if ((flags & kIncludeExtensiveMetaData) && !mExtractedThumbnails
@@ -1021,8 +1463,7 @@
         mExtractedThumbnails = true;
     }
 
-    meta = mTracks.itemAt(index).mMeta;
-    return OK;
+    return AMediaFormat_copy(meta, mTracks.itemAt(index).mMeta);
 }
 
 bool MatroskaExtractor::isLiveStreaming() const {
@@ -1057,7 +1498,7 @@
 }
 
 static void addESDSFromCodecPrivate(
-        MetaDataBase &meta,
+        AMediaFormat *meta,
         bool isAudio, const void *priv, size_t privSize) {
 
     int privSizeBytesRequired = bytesForSize(privSize);
@@ -1085,14 +1526,14 @@
     storeSize(esds, idx, privSize);
     memcpy(esds + idx, priv, privSize);
 
-    meta.setData(kKeyESDS, 0, esds, esdsSize);
+    AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CSD_0, priv, privSize);
 
     delete[] esds;
     esds = NULL;
 }
 
 status_t addVorbisCodecInfo(
-        MetaDataBase &meta,
+        AMediaFormat *meta,
         const void *_codecPrivate, size_t codecPrivateSize) {
     // hexdump(_codecPrivate, codecPrivateSize);
 
@@ -1150,7 +1591,8 @@
     if (codecPrivate[offset] != 0x01) {
         return ERROR_MALFORMED;
     }
-    meta.setData(kKeyVorbisInfo, 0, &codecPrivate[offset], len1);
+    // formerly kKeyVorbisInfo
+    AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CSD_0, &codecPrivate[offset], len1);
 
     offset += len1;
     if (codecPrivate[offset] != 0x03) {
@@ -1162,19 +1604,20 @@
         return ERROR_MALFORMED;
     }
 
-    meta.setData(
-            kKeyVorbisBooks, 0, &codecPrivate[offset],
-            codecPrivateSize - offset);
+    // formerly kKeyVorbisBooks
+    AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CSD_1,
+            &codecPrivate[offset], codecPrivateSize - offset);
 
     return OK;
 }
 
 static status_t addFlacMetadata(
-        MetaDataBase &meta,
+        AMediaFormat *meta,
         const void *codecPrivate, size_t codecPrivateSize) {
     // hexdump(codecPrivate, codecPrivateSize);
 
-    meta.setData(kKeyFlacMetadata, 0, codecPrivate, codecPrivateSize);
+    // formerly kKeyFlacMetadata
+    AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CSD_0, codecPrivate, codecPrivateSize);
 
     int32_t maxInputSize = 64 << 10;
     FLACDecoder *flacDecoder = FLACDecoder::Create();
@@ -1196,7 +1639,7 @@
                 * streamInfo.max_blocksize * streamInfo.channels;
         }
     }
-    meta.setInt32(kKeyMaxInputSize, maxInputSize);
+    AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, maxInputSize);
 
     delete flacDecoder;
     return OK;
@@ -1225,10 +1668,93 @@
     }
 
     // Override the synthesized nal length size, which is arbitrary
-    trackInfo->mMeta.setInt32(kKeyNalLengthSize, 0);
+    trackInfo->mNalLengthSize = 0;
     return OK;
 }
 
+status_t MatroskaExtractor::synthesizeMPEG2(TrackInfo *trackInfo, size_t index) {
+    ALOGV("synthesizeMPEG2");
+    BlockIterator iter(this, trackInfo->mTrackNum, index);
+    if (iter.eos()) {
+        return ERROR_MALFORMED;
+    }
+
+    const mkvparser::Block *block = iter.block();
+    if (block->GetFrameCount() <= 0) {
+        return ERROR_MALFORMED;
+    }
+
+    const mkvparser::Block::Frame &frame = block->GetFrame(0);
+    auto tmpData = heapbuffer<unsigned char>(frame.len);
+    long n = frame.Read(mReader, tmpData.get());
+    if (n != 0) {
+        return ERROR_MALFORMED;
+    }
+
+    size_t header_start = 0;
+    size_t header_lenth = 0;
+    for (header_start = 0; header_start < frame.len - 4; header_start++) {
+        if (ntohl(0x000001b3) == *(uint32_t*)((uint8_t*)tmpData.get() + header_start)) {
+            break;
+        }
+    }
+    bool isComplete_csd = false;
+    for (header_lenth = 0; header_lenth < frame.len - 4 - header_start; header_lenth++) {
+        if (ntohl(0x000001b8) == *(uint32_t*)((uint8_t*)tmpData.get()
+                                + header_start + header_lenth)) {
+            isComplete_csd = true;
+            break;
+        }
+    }
+    if (!isComplete_csd) {
+        ALOGE("can't parse complete csd for MPEG2!");
+        return ERROR_MALFORMED;
+    }
+    addESDSFromCodecPrivate(trackInfo->mMeta, false,
+                              (uint8_t*)(tmpData.get()) + header_start, header_lenth);
+
+    return OK;
+
+}
+
+status_t MatroskaExtractor::synthesizeMPEG4(TrackInfo *trackInfo, size_t index) {
+    ALOGV("synthesizeMPEG4");
+    BlockIterator iter(this, trackInfo->mTrackNum, index);
+    if (iter.eos()) {
+        return ERROR_MALFORMED;
+    }
+
+    const mkvparser::Block *block = iter.block();
+    if (block->GetFrameCount() <= 0) {
+        return ERROR_MALFORMED;
+    }
+
+    const mkvparser::Block::Frame &frame = block->GetFrame(0);
+    auto tmpData = heapbuffer<unsigned char>(frame.len);
+    long n = frame.Read(mReader, tmpData.get());
+    if (n != 0) {
+        return ERROR_MALFORMED;
+    }
+
+     size_t vosend;
+     bool isComplete_csd = false;
+     for (vosend = 0; (long)vosend < frame.len - 4; vosend++) {
+         if (ntohl(0x000001b6) == *(uint32_t*)((uint8_t*)tmpData.get() + vosend)) {
+             isComplete_csd = true;
+             break;  // Send VOS until VOP
+         }
+     }
+     if (!isComplete_csd) {
+         ALOGE("can't parse complete csd for MPEG4!");
+         return ERROR_MALFORMED;
+     }
+     addESDSFromCodecPrivate(trackInfo->mMeta, false, tmpData.get(), vosend);
+
+    return OK;
+
+}
+
+
 static inline bool isValidInt32ColourValue(long long value) {
     return value != mkvparser::Colour::kValueNotPresent
             && value >= INT32_MIN
@@ -1247,7 +1773,7 @@
 }
 
 void MatroskaExtractor::getColorInformation(
-        const mkvparser::VideoTrack *vtrack, MetaDataBase &meta) {
+        const mkvparser::VideoTrack *vtrack, AMediaFormat *meta) {
     const mkvparser::Colour *color = vtrack->GetColour();
     if (color == NULL) {
         return;
@@ -1256,7 +1782,7 @@
     // Color Aspects
     {
         int32_t primaries = 2; // ISO unspecified
-        int32_t transfer = 2; // ISO unspecified
+        int32_t isotransfer = 2; // ISO unspecified
         int32_t coeffs = 2; // ISO unspecified
         bool fullRange = false; // default
         bool rangeSpecified = false;
@@ -1265,7 +1791,7 @@
             primaries = color->primaries;
         }
         if (isValidInt32ColourValue(color->transfer_characteristics)) {
-            transfer = color->transfer_characteristics;
+            isotransfer = color->transfer_characteristics;
         }
         if (isValidInt32ColourValue(color->matrix_coefficients)) {
             coeffs = color->matrix_coefficients;
@@ -1278,14 +1804,21 @@
             rangeSpecified = true;
         }
 
-        ColorAspects aspects;
-        ColorUtils::convertIsoColorAspectsToCodecAspects(
-                primaries, transfer, coeffs, fullRange, aspects);
-        meta.setInt32(kKeyColorPrimaries, aspects.mPrimaries);
-        meta.setInt32(kKeyTransferFunction, aspects.mTransfer);
-        meta.setInt32(kKeyColorMatrix, aspects.mMatrixCoeffs);
-        meta.setInt32(
-                kKeyColorRange, rangeSpecified ? aspects.mRange : ColorAspects::RangeUnspecified);
+        int32_t range = 0;
+        int32_t standard = 0;
+        int32_t transfer = 0;
+        ColorUtils::convertIsoColorAspectsToPlatformAspects(
+                primaries, isotransfer, coeffs, fullRange,
+                &range, &standard, &transfer);
+        if (range != 0) {
+            AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_COLOR_RANGE, range);
+        }
+        if (standard != 0) {
+            AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_COLOR_STANDARD, standard);
+        }
+        if (transfer != 0) {
+            AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_COLOR_TRANSFER, transfer);
+        }
     }
 
     // HDR Static Info
@@ -1329,26 +1862,28 @@
         // Only advertise static info if at least one of the groups have been specified.
         if (memcmp(&info, &nullInfo, sizeof(info)) != 0) {
             info.mID = HDRStaticInfo::kType1;
-            meta.setData(kKeyHdrStaticInfo, 'hdrS', &info, sizeof(info));
+            ColorUtils::setHDRStaticInfoIntoAMediaFormat(info, meta);
         }
     }
 }
 
 status_t MatroskaExtractor::initTrackInfo(
-        const mkvparser::Track *track, MetaDataBase &meta, TrackInfo *trackInfo) {
+        const mkvparser::Track *track, AMediaFormat *meta, TrackInfo *trackInfo) {
     trackInfo->mTrackNum = track->GetNumber();
     trackInfo->mMeta = meta;
     trackInfo->mExtractor = this;
     trackInfo->mEncrypted = false;
     trackInfo->mHeader = NULL;
     trackInfo->mHeaderLen = 0;
+    trackInfo->mNalLengthSize = -1;
 
     for(size_t i = 0; i < track->GetContentEncodingCount(); i++) {
         const mkvparser::ContentEncoding *encoding = track->GetContentEncodingByIndex(i);
         for(size_t j = 0; j < encoding->GetEncryptionCount(); j++) {
             const mkvparser::ContentEncoding::ContentEncryption *encryption;
             encryption = encoding->GetEncryptionByIndex(j);
-            trackInfo->mMeta.setData(kKeyCryptoKey, 0, encryption->key_id, encryption->key_id_len);
+            AMediaFormat_setBuffer(trackInfo->mMeta,
+                    AMEDIAFORMAT_KEY_CRYPTO_KEY, encryption->key_id, encryption->key_id_len);
             trackInfo->mEncrypted = true;
             break;
         }
@@ -1373,6 +1908,8 @@
 void MatroskaExtractor::addTracks() {
     const mkvparser::Tracks *tracks = mSegment->GetTracks();
 
+    AMediaFormat *meta = nullptr;
+
     for (size_t index = 0; index < tracks->GetTracksCount(); ++index) {
         const mkvparser::Track *track = tracks->GetTrackByIndex(index);
 
@@ -1397,9 +1934,16 @@
 
         enum { VIDEO_TRACK = 1, AUDIO_TRACK = 2 };
 
-        MetaDataBase meta;
+        if (meta) {
+            AMediaFormat_clear(meta);
+        } else {
+            meta = AMediaFormat_new();
+        }
 
         status_t err = OK;
+        int32_t nalSize = -1;
+
+        bool isSetCsdFrom1stFrame = false;
 
         switch (track->GetType()) {
             case VIDEO_TRACK:
@@ -1408,37 +1952,95 @@
                     static_cast<const mkvparser::VideoTrack *>(track);
 
                 if (!strcmp("V_MPEG4/ISO/AVC", codecID)) {
-                    meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
-                    meta.setData(kKeyAVCC, 0, codecPrivate, codecPrivateSize);
+                    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_AVC);
+                    AMediaFormat_setBuffer(meta,
+                           AMEDIAFORMAT_KEY_CSD_AVC, codecPrivate, codecPrivateSize);
+                    if (codecPrivateSize > 4) {
+                        nalSize = 1 + (codecPrivate[4] & 3);
+                    }
                 } else if (!strcmp("V_MPEGH/ISO/HEVC", codecID)) {
-                    meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_HEVC);
+                    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_HEVC);
                     if (codecPrivateSize > 0) {
-                        meta.setData(kKeyHVCC, kTypeHVCC, codecPrivate, codecPrivateSize);
+                        AMediaFormat_setBuffer(meta,
+                               AMEDIAFORMAT_KEY_CSD_HEVC, codecPrivate, codecPrivateSize);
+                        if (codecPrivateSize > 14 + 7) {
+                            nalSize = 1 + (codecPrivate[14 + 7] & 3);
+                        }
                     } else {
                         ALOGW("HEVC is detected, but does not have configuration.");
                         continue;
                     }
                 } else if (!strcmp("V_MPEG4/ISO/ASP", codecID)) {
+                    AMediaFormat_setString(meta,
+                            AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_MPEG4);
                     if (codecPrivateSize > 0) {
-                        meta.setCString(
-                                kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
                         addESDSFromCodecPrivate(
                                 meta, false, codecPrivate, codecPrivateSize);
                     } else {
                         ALOGW("%s is detected, but does not have configuration.",
                                 codecID);
-                        continue;
+                        isSetCsdFrom1stFrame = true;
                     }
                 } else if (!strcmp("V_VP8", codecID)) {
-                    meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VP8);
+                    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_VP8);
                 } else if (!strcmp("V_VP9", codecID)) {
-                    meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VP9);
+                    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_VP9);
                     if (codecPrivateSize > 0) {
                       // 'csd-0' for VP9 is the Blob of Codec Private data as
                       // specified in http://www.webmproject.org/vp9/profiles/.
-                        meta.setData(
-                              kKeyVp9CodecPrivate, 0, codecPrivate,
-                              codecPrivateSize);
+                      AMediaFormat_setBuffer(meta,
+                             AMEDIAFORMAT_KEY_CSD_0, codecPrivate, codecPrivateSize);
+                    }
+                } else if (!strcmp("V_AV1", codecID)) {
+                    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_AV1);
+                    if (codecPrivateSize > 0) {
+                        // 'csd-0' for AV1 is the Blob of Codec Private data as
+                        // specified in https://aomediacodec.github.io/av1-isobmff/.
+                        AMediaFormat_setBuffer(
+                                meta, AMEDIAFORMAT_KEY_CSD_0, codecPrivate, codecPrivateSize);
+                    }
+                } else if (!strcmp("V_MPEG2", codecID) || !strcmp("V_MPEG1", codecID)) {
+                        AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME,
+                                MEDIA_MIMETYPE_VIDEO_MPEG2);
+                        if (codecPrivate != NULL) {
+                            addESDSFromCodecPrivate(meta, false, codecPrivate, codecPrivateSize);
+                        } else {
+                            ALOGW("No specific codec private data, find it from the first frame");
+                            isSetCsdFrom1stFrame = true;
+                        }
+                } else if (!strcmp("V_MJPEG", codecID)) {
+                        AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME,
+                                MEDIA_MIMETYPE_VIDEO_MJPEG);
+                } else if (!strcmp("V_MS/VFW/FOURCC", codecID)) {
+                    if (NULL == codecPrivate ||codecPrivateSize < 20) {
+                        ALOGE("V_MS/VFW/FOURCC has no valid private data(%p),codecPrivateSize:%zu",
+                                 codecPrivate, codecPrivateSize);
+                        continue;
+                    } else {
+                        uint32_t fourcc = *(uint32_t *)(codecPrivate + 16);
+                        fourcc = ntohl(fourcc);
+                        const char* mime = MKVFourCC2MIME(fourcc);
+                        ALOGV("V_MS/VFW/FOURCC type is %s", mime);
+                        if (!strncasecmp("video/", mime, 6)) {
+                            AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, mime);
+                        } else {
+                            ALOGE("V_MS/VFW/FOURCC continue,unsupport video type=%s,fourcc=0x%08x.",
+                                 mime, fourcc);
+                            continue;
+                        }
+                        if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) ||
+                            !strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) ||
+                            !strcmp(mime, MEDIA_MIMETYPE_VIDEO_XVID) ||
+                            !strcmp(mime, MEDIA_MIMETYPE_VIDEO_DIVX) ||
+                            !strcmp(mime, MEDIA_MIMETYPE_VIDEO_DIVX3) ||
+                            !strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2) ||
+                            !strcmp(mime, MEDIA_MIMETYPE_VIDEO_H263)) {
+                            isSetCsdFrom1stFrame = true;
+                        } else {
+                            ALOGW("FourCC have unsupport codec, type=%s,fourcc=0x%08x.",
+                                  mime, fourcc);
+                            continue;
+                        }
                     }
                 } else {
                     ALOGW("%s is not supported.", codecID);
@@ -1455,8 +2057,8 @@
                     ALOGW("track height exceeds int32_t, %lld", height);
                     continue;
                 }
-                meta.setInt32(kKeyWidth, (int32_t)width);
-                meta.setInt32(kKeyHeight, (int32_t)height);
+                AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_WIDTH, (int32_t)width);
+                AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_HEIGHT, (int32_t)height);
 
                 // setting display width/height is optional
                 const long long displayUnit = vtrack->GetDisplayUnit();
@@ -1466,8 +2068,10 @@
                         && displayHeight > 0 && displayHeight <= INT32_MAX) {
                     switch (displayUnit) {
                     case 0: // pixels
-                        meta.setInt32(kKeyDisplayWidth, (int32_t)displayWidth);
-                        meta.setInt32(kKeyDisplayHeight, (int32_t)displayHeight);
+                        AMediaFormat_setInt32(meta,
+                                AMEDIAFORMAT_KEY_DISPLAY_WIDTH, (int32_t)displayWidth);
+                        AMediaFormat_setInt32(meta,
+                                AMEDIAFORMAT_KEY_DISPLAY_HEIGHT, (int32_t)displayHeight);
                         break;
                     case 1: // centimeters
                     case 2: // inches
@@ -1481,8 +2085,10 @@
                         const long long computedHeight =
                                 std::max(height, width * displayHeight / displayWidth);
                         if (computedWidth <= INT32_MAX && computedHeight <= INT32_MAX) {
-                            meta.setInt32(kKeyDisplayWidth, (int32_t)computedWidth);
-                            meta.setInt32(kKeyDisplayHeight, (int32_t)computedHeight);
+                            AMediaFormat_setInt32(meta,
+                                    AMEDIAFORMAT_KEY_DISPLAY_WIDTH, (int32_t)computedWidth);
+                            AMediaFormat_setInt32(meta,
+                                    AMEDIAFORMAT_KEY_DISPLAY_HEIGHT, (int32_t)computedHeight);
                         }
                         break;
                     }
@@ -1502,34 +2108,77 @@
                     static_cast<const mkvparser::AudioTrack *>(track);
 
                 if (!strcmp("A_AAC", codecID)) {
-                    meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
-                    CHECK(codecPrivateSize >= 2);
-
+                    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_AAC);
+                    if (codecPrivateSize < 2) {
+                        ALOGW("Incomplete AAC Codec Info %zu byte", codecPrivateSize);
+                        continue;
+                    }
                     addESDSFromCodecPrivate(
                             meta, true, codecPrivate, codecPrivateSize);
                 } else if (!strcmp("A_VORBIS", codecID)) {
-                    meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS);
+                    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_VORBIS);
 
                     err = addVorbisCodecInfo(
                             meta, codecPrivate, codecPrivateSize);
                 } else if (!strcmp("A_OPUS", codecID)) {
-                    meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_OPUS);
-                    meta.setData(kKeyOpusHeader, 0, codecPrivate, codecPrivateSize);
-                    meta.setInt64(kKeyOpusCodecDelay, track->GetCodecDelay());
-                    meta.setInt64(kKeyOpusSeekPreRoll, track->GetSeekPreRoll());
+                    AMediaFormat_setString(meta,
+                            AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_OPUS);
+                    AMediaFormat_setBuffer(meta,
+                            AMEDIAFORMAT_KEY_CSD_0, codecPrivate, codecPrivateSize);
+                    int64_t codecDelay = track->GetCodecDelay();
+                    AMediaFormat_setBuffer(meta,
+                            AMEDIAFORMAT_KEY_CSD_1, &codecDelay, sizeof(codecDelay));
                     mSeekPreRollNs = track->GetSeekPreRoll();
+                    AMediaFormat_setBuffer(meta,
+                            AMEDIAFORMAT_KEY_CSD_2, &mSeekPreRollNs, sizeof(mSeekPreRollNs));
                 } else if (!strcmp("A_MPEG/L3", codecID)) {
-                    meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
+                    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_MPEG);
                 } else if (!strcmp("A_FLAC", codecID)) {
-                    meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_FLAC);
+                    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_FLAC);
                     err = addFlacMetadata(meta, codecPrivate, codecPrivateSize);
+                } else if (!strcmp("A_MPEG/L2", codecID)) {
+                    AMediaFormat_setString(meta,
+                            AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II);
+                } else if (!strcmp("A_PCM/INT/LIT", codecID) ||
+                         !strcmp("A_PCM/INT/BIG", codecID)) {
+                    AMediaFormat_setString(meta,
+                            AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_RAW);
+                    int32_t bigEndian = !strcmp("A_PCM/INT/BIG", codecID) ? 1: 0;
+                    AMediaFormat_setInt32(meta,
+                            AMEDIAFORMAT_KEY_PCM_BIG_ENDIAN, bigEndian);
+                } else if ((!strcmp("A_MS/ACM", codecID))) {
+                    if ((NULL == codecPrivate) || (codecPrivateSize < 18)) {
+                        ALOGW("unsupported audio: A_MS/ACM has no valid private data: %s, size: %zu",
+                               codecPrivate == NULL ? "null" : "non-null", codecPrivateSize);
+                        continue;
+                    } else {
+                        uint16_t ID = *(uint16_t *)codecPrivate;
+                        const char* mime = MKVWave2MIME(ID);
+                        ALOGV("A_MS/ACM type is %s", mime);
+                        if (!strncasecmp("audio/", mime, 6) &&
+                                isMkvAudioCsdSizeOK(mime, codecPrivateSize)) {
+                            AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, mime);
+                        } else {
+                            ALOGE("A_MS/ACM continue, unsupported audio type=%s, csdSize:%zu",
+                                mime, codecPrivateSize);
+                            continue;
+                        }
+                        if (!strcmp(mime, MEDIA_MIMETYPE_AUDIO_WMA)) {
+                            addESDSFromCodecPrivate(meta, true, codecPrivate, codecPrivateSize);
+                        } else if (!strcmp(mime, MEDIA_MIMETYPE_AUDIO_MS_ADPCM) ||
+                                    !strcmp(mime, MEDIA_MIMETYPE_AUDIO_DVI_IMA_ADPCM)) {
+                            uint32_t blockAlign = *(uint16_t*)(codecPrivate + 12);
+                            addESDSFromCodecPrivate(meta, true, &blockAlign, sizeof(blockAlign));
+                        }
+                    }
                 } else {
                     ALOGW("%s is not supported.", codecID);
                     continue;
                 }
 
-                meta.setInt32(kKeySampleRate, atrack->GetSamplingRate());
-                meta.setInt32(kKeyChannelCount, atrack->GetChannels());
+                AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, atrack->GetSamplingRate());
+                AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, atrack->GetChannels());
+                AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, atrack->GetBitDepth());
                 break;
             }
 
@@ -1542,7 +2191,7 @@
            char lang[4];
            strncpy(lang, language, 3);
            lang[3] = '\0';
-           meta.setCString(kKeyMediaLanguage, lang);
+           AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_LANGUAGE, lang);
         }
 
         if (err != OK) {
@@ -1551,20 +2200,54 @@
         }
 
         long long durationNs = mSegment->GetDuration();
-        meta.setInt64(kKeyDuration, (durationNs + 500) / 1000);
+        AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_DURATION, (durationNs + 500) / 1000);
+
+        const char *mimetype = "";
+        if (!AMediaFormat_getString(meta, AMEDIAFORMAT_KEY_MIME, &mimetype)) {
+            // do not add this track to the track list
+            ALOGW("ignoring track with unknown mime");
+            continue;
+        }
 
         mTracks.push();
         size_t n = mTracks.size() - 1;
         TrackInfo *trackInfo = &mTracks.editItemAt(n);
         initTrackInfo(track, meta, trackInfo);
+        trackInfo->mNalLengthSize = nalSize;
 
-        if (!strcmp("V_MPEG4/ISO/AVC", codecID) && codecPrivateSize == 0) {
+        if ((!strcmp("V_MPEG4/ISO/AVC", codecID) && codecPrivateSize == 0) ||
+            (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_AVC) && isSetCsdFrom1stFrame)) {
             // Attempt to recover from AVC track without codec private data
             err = synthesizeAVCC(trackInfo, n);
             if (err != OK) {
                 mTracks.pop();
+                continue;
+            }
+        } else if ((!strcmp("V_MPEG2", codecID) && codecPrivateSize == 0) ||
+            (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_MPEG2) && isSetCsdFrom1stFrame)) {
+            // Attempt to recover from MPEG2 track without codec private data
+            err = synthesizeMPEG2(trackInfo, n);
+            if (err != OK) {
+                mTracks.pop();
+                continue;
+            }
+        } else if ((!strcmp("V_MPEG4/ISO/ASP", codecID) && codecPrivateSize == 0) ||
+            (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_MPEG4) && isSetCsdFrom1stFrame) ||
+            (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_XVID) && isSetCsdFrom1stFrame) ||
+            (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_DIVX) && isSetCsdFrom1stFrame) ||
+            (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_DIVX3) && isSetCsdFrom1stFrame)) {
+            // Attempt to recover from MPEG4 track without codec private data
+            err = synthesizeMPEG4(trackInfo, n);
+            if (err != OK) {
+                mTracks.pop();
+                continue;
             }
         }
+        // the TrackInfo owns the metadata now
+        meta = nullptr;
+    }
+    if (meta) {
+        AMediaFormat_delete(meta);
     }
 }
 
@@ -1573,7 +2256,7 @@
         TrackInfo *info = &mTracks.editItemAt(i);
 
         const char *mime;
-        CHECK(info->mMeta.findCString(kKeyMIMEType, &mime));
+        CHECK(AMediaFormat_getString(info->mMeta, AMEDIAFORMAT_KEY_MIME, &mime));
 
         if (strncasecmp(mime, "video/", 6)) {
             continue;
@@ -1599,16 +2282,16 @@
             }
             iter.advance();
         }
-        info->mMeta.setInt64(kKeyThumbnailTime, thumbnailTimeUs);
+        AMediaFormat_setInt64(info->mMeta,
+                AMEDIAFORMAT_KEY_THUMBNAIL_TIME, thumbnailTimeUs);
     }
 }
 
-status_t MatroskaExtractor::getMetaData(MetaDataBase &meta) {
-    meta.setCString(
-            kKeyMIMEType,
-            mIsWebm ? "video/webm" : MEDIA_MIMETYPE_CONTAINER_MATROSKA);
+media_status_t MatroskaExtractor::getMetaData(AMediaFormat *meta) {
+    AMediaFormat_setString(meta,
+            AMEDIAFORMAT_KEY_MIME, mIsWebm ? "video/webm" : MEDIA_MIMETYPE_CONTAINER_MATROSKA);
 
-    return OK;
+    return AMEDIA_OK;
 }
 
 uint32_t MatroskaExtractor::flags() const {
@@ -1621,7 +2304,7 @@
 }
 
 bool SniffMatroska(
-        DataSourceBase *source, float *confidence) {
+        DataSourceHelper *source, float *confidence) {
     DataSourceBaseReader reader(source);
     mkvparser::EBMLHeader ebmlHeader;
     long long pos;
@@ -1634,28 +2317,40 @@
     return true;
 }
 
+static const char *extensions[] = {
+    "mka",
+    "mkv",
+    "webm",
+    NULL
+};
 
 extern "C" {
 // This is the only symbol that needs to be exported
 __attribute__ ((visibility ("default")))
-MediaExtractor::ExtractorDef GETEXTRACTORDEF() {
+ExtractorDef GETEXTRACTORDEF() {
     return {
-        MediaExtractor::EXTRACTORDEF_VERSION,
+        EXTRACTORDEF_VERSION,
         UUID("abbedd92-38c4-4904-a4c1-b3f45f899980"),
         1,
         "Matroska Extractor",
-        [](
-                DataSourceBase *source,
-                float *confidence,
-                void **,
-                MediaExtractor::FreeMetaFunc *) -> MediaExtractor::CreatorFunc {
-            if (SniffMatroska(source, confidence)) {
-                return [](
-                        DataSourceBase *source,
-                        void *) -> MediaExtractor* {
-                    return new MatroskaExtractor(source);};
+        {
+            .v3 = {
+                [](
+                    CDataSource *source,
+                    float *confidence,
+                    void **,
+                    FreeMetaFunc *) -> CreatorFunc {
+                    DataSourceHelper helper(source);
+                    if (SniffMatroska(&helper, confidence)) {
+                        return [](
+                                CDataSource *source,
+                                void *) -> CMediaExtractor* {
+                            return wrap(new MatroskaExtractor(new DataSourceHelper(source)));};
+                    }
+                    return NULL;
+                },
+                extensions
             }
-            return NULL;
         }
     };
 }
diff --git a/media/extractors/mkv/MatroskaExtractor.h b/media/extractors/mkv/MatroskaExtractor.h
index 3568ea1..99fad17 100644
--- a/media/extractors/mkv/MatroskaExtractor.h
+++ b/media/extractors/mkv/MatroskaExtractor.h
@@ -20,8 +20,9 @@
 
 #include "mkvparser/mkvparser.h"
 
-#include <media/MediaExtractor.h>
-#include <media/stagefright/MetaDataBase.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
+#include <media/NdkMediaFormat.h>
 #include <utils/Vector.h>
 #include <utils/threads.h>
 
@@ -34,16 +35,16 @@
 struct DataSourceBaseReader;
 struct MatroskaSource;
 
-struct MatroskaExtractor : public MediaExtractor {
-    explicit MatroskaExtractor(DataSourceBase *source);
+struct MatroskaExtractor : public MediaExtractorPluginHelper {
+    explicit MatroskaExtractor(DataSourceHelper *source);
 
     virtual size_t countTracks();
 
-    virtual MediaTrack *getTrack(size_t index);
+    virtual MediaTrackHelper *getTrack(size_t index);
 
-    virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags);
+    virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
 
-    virtual status_t getMetaData(MetaDataBase& meta);
+    virtual media_status_t getMetaData(AMediaFormat *meta);
 
     virtual uint32_t flags() const;
 
@@ -57,9 +58,15 @@
     friend struct BlockIterator;
 
     struct TrackInfo {
+        TrackInfo() {
+            mMeta = NULL;
+        }
+
+        ~TrackInfo() {
+        }
         unsigned long mTrackNum;
         bool mEncrypted;
-        MetaDataBase mMeta;
+        AMediaFormat *mMeta;
         const MatroskaExtractor *mExtractor;
         Vector<const mkvparser::CuePoint*> mCuePoints;
 
@@ -68,6 +75,7 @@
         // in ~MatroskaExtractor.
         unsigned char *mHeader;
         size_t mHeaderLen;
+        int32_t mNalLengthSize;
 
         const mkvparser::Track* getTrack() const;
         const mkvparser::CuePoint::TrackPosition *find(long long timeNs) const;
@@ -76,7 +84,7 @@
     Mutex mLock;
     Vector<TrackInfo> mTracks;
 
-    DataSourceBase *mDataSource;
+    DataSourceHelper *mDataSource;
     DataSourceBaseReader *mReader;
     mkvparser::Segment *mSegment;
     bool mExtractedThumbnails;
@@ -85,15 +93,17 @@
     int64_t mSeekPreRollNs;
 
     status_t synthesizeAVCC(TrackInfo *trackInfo, size_t index);
+    status_t synthesizeMPEG2(TrackInfo *trackInfo, size_t index);
+    status_t synthesizeMPEG4(TrackInfo *trackInfo, size_t index);
     status_t initTrackInfo(
             const mkvparser::Track *track,
-            MetaDataBase &meta,
+            AMediaFormat *meta,
             TrackInfo *trackInfo);
     void addTracks();
     void findThumbnails();
     void getColorInformation(
             const mkvparser::VideoTrack *vtrack,
-            MetaDataBase &meta);
+            AMediaFormat *meta);
     bool isLiveStreaming() const;
 
     MatroskaExtractor(const MatroskaExtractor &);
diff --git a/media/extractors/mp3/Android.bp b/media/extractors/mp3/Android.bp
index a3aeaca..4e2f248 100644
--- a/media/extractors/mp3/Android.bp
+++ b/media/extractors/mp3/Android.bp
@@ -12,13 +12,13 @@
 
     shared_libs: [
         "liblog",
-        "libmediaextractor",
-        "libstagefright_foundation",
+        "libmediandk",
     ],
 
     static_libs: [
         "libutils",
         "libstagefright_id3",
+        "libstagefright_foundation",
     ],
 
     name: "libmp3extractor",
@@ -39,9 +39,6 @@
             "unsigned-integer-overflow",
             "signed-integer-overflow",
         ],
-        diag: {
-            cfi: true,
-        },
     },
 
 }
diff --git a/media/extractors/mp3/MP3Extractor.cpp b/media/extractors/mp3/MP3Extractor.cpp
index 33cff96..a838ae6 100644
--- a/media/extractors/mp3/MP3Extractor.cpp
+++ b/media/extractors/mp3/MP3Extractor.cpp
@@ -24,8 +24,6 @@
 #include "VBRISeeker.h"
 #include "XINGSeeker.h"
 
-#include <media/DataSourceBase.h>
-#include <media/MediaTrack.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/foundation/avc_utils.h>
@@ -46,7 +44,7 @@
 static const uint32_t kMask = 0xfffe0c00;
 
 static bool Resync(
-        DataSourceBase *source, uint32_t match_header,
+        DataSourceHelper *source, uint32_t match_header,
         off64_t *inout_pos, off64_t *post_id3_pos, uint32_t *out_header) {
     if (post_id3_pos != NULL) {
         *post_id3_pos = 0;
@@ -209,35 +207,34 @@
     return valid;
 }
 
-class MP3Source : public MediaTrack {
+class MP3Source : public MediaTrackHelper {
 public:
     MP3Source(
-            MetaDataBase &meta, DataSourceBase *source,
+            AMediaFormat *meta, DataSourceHelper *source,
             off64_t first_frame_pos, uint32_t fixed_header,
             MP3Seeker *seeker);
 
-    virtual status_t start(MetaDataBase *params = NULL);
-    virtual status_t stop();
+    virtual media_status_t start();
+    virtual media_status_t stop();
 
-    virtual status_t getFormat(MetaDataBase &meta);
+    virtual media_status_t getFormat(AMediaFormat *meta);
 
-    virtual status_t read(
-            MediaBufferBase **buffer, const ReadOptions *options = NULL);
+    virtual media_status_t read(
+            MediaBufferHelper **buffer, const ReadOptions *options = NULL);
 
 protected:
     virtual ~MP3Source();
 
 private:
     static const size_t kMaxFrameSize;
-    MetaDataBase &mMeta;
-    DataSourceBase *mDataSource;
+    AMediaFormat *mMeta;
+    DataSourceHelper *mDataSource;
     off64_t mFirstFramePos;
     uint32_t mFixedHeader;
     off64_t mCurrentPos;
     int64_t mCurrentTimeUs;
     bool mStarted;
     MP3Seeker *mSeeker;
-    MediaBufferGroup *mGroup;
 
     int64_t mBasisTimeUs;
     int64_t mSamplesRead;
@@ -253,7 +250,7 @@
 };
 
 MP3Extractor::MP3Extractor(
-        DataSourceBase *source, Mp3Meta *meta)
+        DataSourceHelper *source, Mp3Meta *meta)
     : mInitCheck(NO_INIT),
       mDataSource(source),
       mFirstFramePos(-1),
@@ -285,6 +282,7 @@
     mFixedHeader = header;
     XINGSeeker *seeker = XINGSeeker::CreateFromSource(mDataSource, mFirstFramePos);
 
+    mMeta = AMediaFormat_new();
     if (seeker == NULL) {
         mSeeker = VBRISeeker::CreateFromSource(mDataSource, post_id3_pos);
     } else {
@@ -292,8 +290,8 @@
         int encd = seeker->getEncoderDelay();
         int encp = seeker->getEncoderPadding();
         if (encd != 0 || encp != 0) {
-            mMeta.setInt32(kKeyEncoderDelay, encd);
-            mMeta.setInt32(kKeyEncoderPadding, encp);
+            AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_ENCODER_DELAY, encd);
+            AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_ENCODER_PADDING, encp);
         }
     }
 
@@ -329,21 +327,23 @@
 
     switch (layer) {
         case 1:
-            mMeta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I);
+            AMediaFormat_setString(mMeta,
+                    AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I);
             break;
         case 2:
-            mMeta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II);
+            AMediaFormat_setString(mMeta,
+                    AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II);
             break;
         case 3:
-            mMeta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
+            AMediaFormat_setString(mMeta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_MPEG);
             break;
         default:
             TRESPASS();
     }
 
-    mMeta.setInt32(kKeySampleRate, sample_rate);
-    mMeta.setInt32(kKeyBitRate, bitrate * 1000);
-    mMeta.setInt32(kKeyChannelCount, num_channels);
+    AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_SAMPLE_RATE, sample_rate);
+    AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_BIT_RATE, bitrate * 1000);
+    AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, num_channels);
 
     int64_t durationUs;
 
@@ -363,7 +363,7 @@
     }
 
     if (durationUs >= 0) {
-        mMeta.setInt64(kKeyDuration, durationUs);
+        AMediaFormat_setInt64(mMeta, AMEDIAFORMAT_KEY_DURATION, durationUs);
     }
 
     mInitCheck = OK;
@@ -371,7 +371,8 @@
     // Get iTunes-style gapless info if present.
     // When getting the id3 tag, skip the V1 tags to prevent the source cache
     // from being iterated to the end of the file.
-    ID3 id3(mDataSource, true);
+    DataSourceHelper helper(mDataSource);
+    ID3 id3(&helper, true);
     if (id3.isValid()) {
         ID3::Iterator *com = new ID3::Iterator(id3, "COM");
         if (com->done()) {
@@ -390,8 +391,8 @@
 
                 int32_t delay, padding;
                 if (sscanf(value, " %*x %x %x %*x", &delay, &padding) == 2) {
-                    mMeta.setInt32(kKeyEncoderDelay, delay);
-                    mMeta.setInt32(kKeyEncoderPadding, padding);
+                    AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_ENCODER_DELAY, delay);
+                    AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_ENCODER_PADDING, padding);
                 }
                 break;
             }
@@ -404,13 +405,15 @@
 
 MP3Extractor::~MP3Extractor() {
     delete mSeeker;
+    delete mDataSource;
+    AMediaFormat_delete(mMeta);
 }
 
 size_t MP3Extractor::countTracks() {
     return mInitCheck != OK ? 0 : 1;
 }
 
-MediaTrack *MP3Extractor::getTrack(size_t index) {
+MediaTrackHelper *MP3Extractor::getTrack(size_t index) {
     if (mInitCheck != OK || index != 0) {
         return NULL;
     }
@@ -420,14 +423,14 @@
             mSeeker);
 }
 
-status_t MP3Extractor::getTrackMetaData(
-        MetaDataBase &meta,
+media_status_t MP3Extractor::getTrackMetaData(
+        AMediaFormat *meta,
         size_t index, uint32_t /* flags */) {
     if (mInitCheck != OK || index != 0) {
-        return UNKNOWN_ERROR;
+        return AMEDIA_ERROR_UNKNOWN;
     }
-    meta = mMeta;
-    return OK;
+    AMediaFormat_copy(meta, mMeta);
+    return AMEDIA_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -440,7 +443,7 @@
 // Set our max frame size to the nearest power of 2 above this size (aka, 4kB)
 const size_t MP3Source::kMaxFrameSize = (1 << 12); /* 4096 bytes */
 MP3Source::MP3Source(
-        MetaDataBase &meta, DataSourceBase *source,
+        AMediaFormat *meta, DataSourceHelper *source,
         off64_t first_frame_pos, uint32_t fixed_header,
         MP3Seeker *seeker)
     : mMeta(meta),
@@ -451,7 +454,6 @@
       mCurrentTimeUs(0),
       mStarted(false),
       mSeeker(seeker),
-      mGroup(NULL),
       mBasisTimeUs(0),
       mSamplesRead(0) {
 }
@@ -462,12 +464,10 @@
     }
 }
 
-status_t MP3Source::start(MetaDataBase *) {
+media_status_t MP3Source::start() {
     CHECK(!mStarted);
 
-    mGroup = new MediaBufferGroup;
-
-    mGroup->add_buffer(MediaBufferBase::Create(kMaxFrameSize));
+    mBufferGroup->add_buffer(kMaxFrameSize);
 
     mCurrentPos = mFirstFramePos;
     mCurrentTimeUs = 0;
@@ -477,27 +477,23 @@
 
     mStarted = true;
 
-    return OK;
+    return AMEDIA_OK;
 }
 
-status_t MP3Source::stop() {
+media_status_t MP3Source::stop() {
     CHECK(mStarted);
 
-    delete mGroup;
-    mGroup = NULL;
-
     mStarted = false;
 
-    return OK;
+    return AMEDIA_OK;
 }
 
-status_t MP3Source::getFormat(MetaDataBase &meta) {
-    meta = mMeta;
-    return OK;
+media_status_t MP3Source::getFormat(AMediaFormat *meta) {
+    return AMediaFormat_copy(meta, mMeta);
 }
 
-status_t MP3Source::read(
-        MediaBufferBase **out, const ReadOptions *options) {
+media_status_t MP3Source::read(
+        MediaBufferHelper **out, const ReadOptions *options) {
     *out = NULL;
 
     int64_t seekTimeUs;
@@ -509,11 +505,11 @@
         if (mSeeker == NULL
                 || !mSeeker->getOffsetForTime(&actualSeekTimeUs, &mCurrentPos)) {
             int32_t bitrate;
-            if (!mMeta.findInt32(kKeyBitRate, &bitrate)) {
+            if (!AMediaFormat_getInt32(mMeta, AMEDIAFORMAT_KEY_BIT_RATE, &bitrate)) {
                 // bitrate is in bits/sec.
                 ALOGI("no bitrate");
 
-                return ERROR_UNSUPPORTED;
+                return AMEDIA_ERROR_UNSUPPORTED;
             }
 
             mCurrentTimeUs = seekTimeUs;
@@ -527,10 +523,10 @@
         mSamplesRead = 0;
     }
 
-    MediaBufferBase *buffer;
-    status_t err = mGroup->acquire_buffer(&buffer);
+    MediaBufferHelper *buffer;
+    status_t err = mBufferGroup->acquire_buffer(&buffer);
     if (err != OK) {
-        return err;
+        return AMEDIA_ERROR_UNKNOWN;
     }
 
     size_t frame_size;
@@ -543,7 +539,8 @@
             buffer->release();
             buffer = NULL;
 
-            return (n < 0 ? n : ERROR_END_OF_STREAM);
+            return ((n < 0 && n != ERROR_END_OF_STREAM) ?
+                    AMEDIA_ERROR_UNKNOWN : AMEDIA_ERROR_END_OF_STREAM);
         }
 
         uint32_t header = U32_AT((const uint8_t *)buffer->data());
@@ -572,7 +569,7 @@
             buffer->release();
             buffer = NULL;
 
-            return ERROR_END_OF_STREAM;
+            return AMEDIA_ERROR_END_OF_STREAM;
         }
 
         mCurrentPos = pos;
@@ -587,13 +584,15 @@
         buffer->release();
         buffer = NULL;
 
-        return (n < 0 ? n : ERROR_END_OF_STREAM);
+        return ((n < 0 && n != ERROR_END_OF_STREAM) ?
+                AMEDIA_ERROR_UNKNOWN : AMEDIA_ERROR_END_OF_STREAM);
     }
 
     buffer->set_range(0, frame_size);
 
-    buffer->meta_data().setInt64(kKeyTime, mCurrentTimeUs);
-    buffer->meta_data().setInt32(kKeyIsSyncFrame, 1);
+    AMediaFormat *meta = buffer->meta_data();
+    AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, mCurrentTimeUs);
+    AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
 
     mCurrentPos += frame_size;
 
@@ -602,39 +601,40 @@
 
     *out = buffer;
 
-    return OK;
+    return AMEDIA_OK;
 }
 
-status_t MP3Extractor::getMetaData(MetaDataBase &meta) {
-    meta.clear();
+media_status_t MP3Extractor::getMetaData(AMediaFormat *meta) {
+    AMediaFormat_clear(meta);
     if (mInitCheck != OK) {
-        return UNKNOWN_ERROR;
+        return AMEDIA_ERROR_UNKNOWN;
     }
-    meta.setCString(kKeyMIMEType, "audio/mpeg");
+    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_MPEG);
 
-    ID3 id3(mDataSource);
+    DataSourceHelper helper(mDataSource);
+    ID3 id3(&helper);
 
     if (!id3.isValid()) {
-        return OK;
+        return AMEDIA_OK;
     }
 
     struct Map {
-        int key;
+        const char *key;
         const char *tag1;
         const char *tag2;
     };
     static const Map kMap[] = {
-        { kKeyAlbum, "TALB", "TAL" },
-        { kKeyArtist, "TPE1", "TP1" },
-        { kKeyAlbumArtist, "TPE2", "TP2" },
-        { kKeyComposer, "TCOM", "TCM" },
-        { kKeyGenre, "TCON", "TCO" },
-        { kKeyTitle, "TIT2", "TT2" },
-        { kKeyYear, "TYE", "TYER" },
-        { kKeyAuthor, "TXT", "TEXT" },
-        { kKeyCDTrackNumber, "TRK", "TRCK" },
-        { kKeyDiscNumber, "TPA", "TPOS" },
-        { kKeyCompilation, "TCP", "TCMP" },
+        { AMEDIAFORMAT_KEY_ALBUM, "TALB", "TAL" },
+        { AMEDIAFORMAT_KEY_ARTIST, "TPE1", "TP1" },
+        { AMEDIAFORMAT_KEY_ALBUMARTIST, "TPE2", "TP2" },
+        { AMEDIAFORMAT_KEY_COMPOSER, "TCOM", "TCM" },
+        { AMEDIAFORMAT_KEY_GENRE, "TCON", "TCO" },
+        { AMEDIAFORMAT_KEY_TITLE, "TIT2", "TT2" },
+        { AMEDIAFORMAT_KEY_YEAR, "TYE", "TYER" },
+        { AMEDIAFORMAT_KEY_AUTHOR, "TXT", "TEXT" },
+        { AMEDIAFORMAT_KEY_CDTRACKNUMBER, "TRK", "TRCK" },
+        { AMEDIAFORMAT_KEY_DISCNUMBER, "TPA", "TPOS" },
+        { AMEDIAFORMAT_KEY_COMPILATION, "TCP", "TCMP" },
     };
     static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]);
 
@@ -654,7 +654,7 @@
         it->getString(&s);
         delete it;
 
-        meta.setCString(kMap[i].key, s);
+        AMediaFormat_setString(meta, kMap[i].key, s.string());
     }
 
     size_t dataSize;
@@ -662,28 +662,28 @@
     const void *data = id3.getAlbumArt(&dataSize, &mime);
 
     if (data) {
-        meta.setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize);
-        meta.setCString(kKeyAlbumArtMIME, mime.string());
+        AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_ALBUMART, data, dataSize);
     }
 
-    return OK;
+    return AMEDIA_OK;
 }
 
-static MediaExtractor* CreateExtractor(
-        DataSourceBase *source,
+static CMediaExtractor* CreateExtractor(
+        CDataSource *source,
         void *meta) {
     Mp3Meta *metaData = static_cast<Mp3Meta *>(meta);
-    return new MP3Extractor(source, metaData);
+    return wrap(new MP3Extractor(new DataSourceHelper(source), metaData));
 }
 
-static MediaExtractor::CreatorFunc Sniff(
-        DataSourceBase *source, float *confidence, void **meta,
-        MediaExtractor::FreeMetaFunc *freeMeta) {
+static CreatorFunc Sniff(
+        CDataSource *source, float *confidence, void **meta,
+        FreeMetaFunc *freeMeta) {
     off64_t pos = 0;
     off64_t post_id3_pos;
     uint32_t header;
     uint8_t mpeg_header[5];
-    if (source->readAt(0, mpeg_header, sizeof(mpeg_header)) < (ssize_t)sizeof(mpeg_header)) {
+    DataSourceHelper helper(source);
+    if (helper.readAt(0, mpeg_header, sizeof(mpeg_header)) < (ssize_t)sizeof(mpeg_header)) {
         return NULL;
     }
 
@@ -691,7 +691,7 @@
         ALOGV("MPEG1PS container is not supported!");
         return NULL;
     }
-    if (!Resync(source, 0, &pos, &post_id3_pos, &header)) {
+    if (!Resync(&helper, 0, &pos, &post_id3_pos, &header)) {
         return NULL;
     }
 
@@ -707,16 +707,25 @@
     return CreateExtractor;
 }
 
+static const char *extensions[] = {
+    "mp2",
+    "mp3",
+    "mpeg",
+    "mpg",
+    "mpga",
+    NULL
+};
+
 extern "C" {
 // This is the only symbol that needs to be exported
 __attribute__ ((visibility ("default")))
-MediaExtractor::ExtractorDef GETEXTRACTORDEF() {
+ExtractorDef GETEXTRACTORDEF() {
     return {
-        MediaExtractor::EXTRACTORDEF_VERSION,
+        EXTRACTORDEF_VERSION,
         UUID("812a3f6c-c8cf-46de-b529-3774b14103d4"),
         1, // version
         "MP3 Extractor",
-        Sniff
+        { .v3 = {Sniff, extensions} }
     };
 }
 
diff --git a/media/extractors/mp3/MP3Extractor.h b/media/extractors/mp3/MP3Extractor.h
index 485b0ca..1e38ab7 100644
--- a/media/extractors/mp3/MP3Extractor.h
+++ b/media/extractors/mp3/MP3Extractor.h
@@ -19,35 +19,37 @@
 #define MP3_EXTRACTOR_H_
 
 #include <utils/Errors.h>
-#include <media/MediaExtractor.h>
-#include <media/stagefright/MetaDataBase.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
+#include <media/NdkMediaFormat.h>
 
 namespace android {
 
+class DataSourceHelper;
+
 struct AMessage;
-class DataSourceBase;
 struct MP3Seeker;
 class String8;
 struct Mp3Meta;
 
-class MP3Extractor : public MediaExtractor {
+class MP3Extractor : public MediaExtractorPluginHelper {
 public:
-    MP3Extractor(DataSourceBase *source, Mp3Meta *meta);
+    MP3Extractor(DataSourceHelper *source, Mp3Meta *meta);
     ~MP3Extractor();
 
     virtual size_t countTracks();
-    virtual MediaTrack *getTrack(size_t index);
-    virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags);
+    virtual MediaTrackHelper *getTrack(size_t index);
+    virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
 
-    virtual status_t getMetaData(MetaDataBase& meta);
+    virtual media_status_t getMetaData(AMediaFormat *meta);
     virtual const char * name() { return "MP3Extractor"; }
 
 private:
     status_t mInitCheck;
 
-    DataSourceBase *mDataSource;
+    DataSourceHelper *mDataSource;
     off64_t mFirstFramePos;
-    MetaDataBase mMeta;
+    AMediaFormat *mMeta;
     uint32_t mFixedHeader;
     MP3Seeker *mSeeker;
 
diff --git a/media/extractors/mp3/VBRISeeker.cpp b/media/extractors/mp3/VBRISeeker.cpp
index 523f14c..ca51b88 100644
--- a/media/extractors/mp3/VBRISeeker.cpp
+++ b/media/extractors/mp3/VBRISeeker.cpp
@@ -27,7 +27,9 @@
 
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ByteUtils.h>
-#include <media/DataSourceBase.h>
+
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
 
 namespace android {
 
@@ -37,7 +39,7 @@
 
 // static
 VBRISeeker *VBRISeeker::CreateFromSource(
-        DataSourceBase *source, off64_t post_id3_pos) {
+        DataSourceHelper *source, off64_t post_id3_pos) {
     off64_t pos = post_id3_pos;
 
     uint8_t header[4];
@@ -69,7 +71,7 @@
     size_t numFrames = U32_AT(&vbriHeader[14]);
 
     int64_t durationUs =
-        numFrames * 1000000ll * (sampleRate >= 32000 ? 1152 : 576) / sampleRate;
+        numFrames * 1000000LL * (sampleRate >= 32000 ? 1152 : 576) / sampleRate;
 
     ALOGV("duration = %.2f secs", durationUs / 1E6);
 
diff --git a/media/extractors/mp3/VBRISeeker.h b/media/extractors/mp3/VBRISeeker.h
index 9213f6e..507899c 100644
--- a/media/extractors/mp3/VBRISeeker.h
+++ b/media/extractors/mp3/VBRISeeker.h
@@ -24,11 +24,11 @@
 
 namespace android {
 
-class DataSourceBase;
+class DataSourceHelper;
 
 struct VBRISeeker : public MP3Seeker {
     static VBRISeeker *CreateFromSource(
-            DataSourceBase *source, off64_t post_id3_pos);
+            DataSourceHelper *source, off64_t post_id3_pos);
 
     virtual bool getDuration(int64_t *durationUs);
     virtual bool getOffsetForTime(int64_t *timeUs, off64_t *pos);
diff --git a/media/extractors/mp3/XINGSeeker.cpp b/media/extractors/mp3/XINGSeeker.cpp
index 95ca556..9f1fd7a 100644
--- a/media/extractors/mp3/XINGSeeker.cpp
+++ b/media/extractors/mp3/XINGSeeker.cpp
@@ -21,7 +21,9 @@
 #include <media/stagefright/foundation/avc_utils.h>
 
 #include <media/stagefright/foundation/ByteUtils.h>
-#include <media/DataSourceBase.h>
+
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
 
 namespace android {
 
@@ -44,7 +46,7 @@
 }
 
 bool XINGSeeker::getOffsetForTime(int64_t *timeUs, off64_t *pos) {
-    if (mSizeBytes == 0 || !mTOCValid || mDurationUs < 0) {
+    if (mSizeBytes == 0 || mDurationUs < 0) {
         return false;
     }
 
@@ -54,7 +56,7 @@
         fx = 0.0f;
     } else if( percent >= 100.0f ) {
         fx = 256.0f;
-    } else {
+    } else if (mTOCValid) {
         int a = (int)percent;
         float fa, fb;
         if ( a == 0 ) {
@@ -68,6 +70,8 @@
             fb = 256.0f;
         }
         fx = fa + (fb-fa)*(percent-a);
+    } else {
+        fx = percent * 2.56f;
     }
 
     *pos = (int)((1.0f/256.0f)*fx*mSizeBytes) + mFirstFramePos;
@@ -77,7 +81,7 @@
 
 // static
 XINGSeeker *XINGSeeker::CreateFromSource(
-        DataSourceBase *source, off64_t first_frame_pos) {
+        DataSourceHelper *source, off64_t first_frame_pos) {
 
     uint8_t buffer[4];
     int offset = first_frame_pos;
diff --git a/media/extractors/mp3/XINGSeeker.h b/media/extractors/mp3/XINGSeeker.h
index 5867eae..9acee38 100644
--- a/media/extractors/mp3/XINGSeeker.h
+++ b/media/extractors/mp3/XINGSeeker.h
@@ -22,11 +22,11 @@
 
 namespace android {
 
-class DataSourceBase;
+class DataSourceHelper;
 
 struct XINGSeeker : public MP3Seeker {
     static XINGSeeker *CreateFromSource(
-            DataSourceBase *source, off64_t first_frame_pos);
+            DataSourceHelper *source, off64_t first_frame_pos);
 
     virtual bool getDuration(int64_t *durationUs);
     virtual bool getOffsetForTime(int64_t *timeUs, off64_t *pos);
diff --git a/media/extractors/mp4/AC4Parser.cpp b/media/extractors/mp4/AC4Parser.cpp
new file mode 100644
index 0000000..13d60c8
--- /dev/null
+++ b/media/extractors/mp4/AC4Parser.cpp
@@ -0,0 +1,620 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "AC4Parser"
+
+#include <inttypes.h>
+#include <utils/Log.h>
+#include <utils/misc.h>
+
+#include "AC4Parser.h"
+
+#define BOOLSTR(a)  ((a)?"true":"false")
+#define BYTE_ALIGN mBitReader.skipBits(mBitReader.numBitsLeft() % 8)
+#define CHECK_BITS_LEFT(n) if (mBitReader.numBitsLeft() < n) {return false;}
+
+namespace android {
+
+AC4Parser::AC4Parser() {
+}
+
+AC4DSIParser::AC4DSIParser(ABitReader &br)
+    : mBitReader(br){
+
+    mDSISize = mBitReader.numBitsLeft();
+}
+
+// ETSI TS 103 190-2 V1.1.1 (2015-09) Table 79: channel_mode
+static const char *ChannelModes[] = {
+    "mono",
+    "stereo",
+    "3.0",
+    "5.0",
+    "5.1",
+    "7.0 (3/4/0)",
+    "7.1 (3/4/0.1)",
+    "7.0 (5/2/0)",
+    "7.1 (5/2/0.1)",
+    "7.0 (3/2/2)",
+    "7.1 (3/2/2.1)",
+    "7.0.4",
+    "7.1.4",
+    "9.0.4",
+    "9.1.4",
+    "22.2"
+};
+
+static const char* ContentClassifier[] = {
+    "Complete Main",
+    "Music and Effects",
+    "Visually Impaired",
+    "Hearing Impaired",
+    "Dialog",
+    "Commentary",
+    "Emergency",
+    "Voice Over"
+};
+
+bool AC4DSIParser::parseLanguageTag(uint32_t presentationID, uint32_t substreamID){
+    CHECK_BITS_LEFT(6);
+    uint32_t n_language_tag_bytes = mBitReader.getBits(6);
+    if (n_language_tag_bytes < 2 || n_language_tag_bytes >= 42) {
+        return false;
+    }
+    CHECK_BITS_LEFT(n_language_tag_bytes * 8);
+    char language_tag_bytes[42]; // TS 103 190 part 1 4.3.3.8.7
+    for (uint32_t i = 0; i < n_language_tag_bytes; i++) {
+        language_tag_bytes[i] = (char)mBitReader.getBits(8);
+    }
+    language_tag_bytes[n_language_tag_bytes] = 0;
+    ALOGV("%u.%u: language_tag = %s\n", presentationID, substreamID, language_tag_bytes);
+
+    std::string language(language_tag_bytes, n_language_tag_bytes);
+    mPresentations[presentationID].mLanguage = language;
+
+    return true;
+}
+
+// TS 103 190-1 v1.2.1 E.5 and TS 103 190-2 v1.1.1 E.9
+bool AC4DSIParser::parseSubstreamDSI(uint32_t presentationID, uint32_t substreamID){
+    CHECK_BITS_LEFT(5);
+    uint32_t channel_mode = mBitReader.getBits(5);
+    CHECK_BITS_LEFT(2);
+    uint32_t dsi_sf_multiplier = mBitReader.getBits(2);
+    CHECK_BITS_LEFT(1);
+    bool b_substream_bitrate_indicator = (mBitReader.getBits(1) == 1);
+    ALOGV("%u.%u: channel_mode = %u (%s)\n", presentationID, substreamID, channel_mode,
+    channel_mode < NELEM(ChannelModes) ? ChannelModes[channel_mode] : "reserved");
+    ALOGV("%u.%u: dsi_sf_multiplier = %u\n", presentationID,
+        substreamID, dsi_sf_multiplier);
+    ALOGV("%u.%u: b_substream_bitrate_indicator = %s\n", presentationID,
+        substreamID, BOOLSTR(b_substream_bitrate_indicator));
+
+    if (b_substream_bitrate_indicator) {
+        CHECK_BITS_LEFT(5);
+        uint32_t substream_bitrate_indicator = mBitReader.getBits(5);
+        ALOGV("%u.%u: substream_bitrate_indicator = %u\n", presentationID, substreamID,
+            substream_bitrate_indicator);
+    }
+    if (channel_mode >= 7 && channel_mode <= 10) {
+        CHECK_BITS_LEFT(1);
+        uint32_t add_ch_base = mBitReader.getBits(1);
+        ALOGV("%u.%u: add_ch_base = %u\n", presentationID, substreamID, add_ch_base);
+    }
+    CHECK_BITS_LEFT(1);
+    bool b_content_type = (mBitReader.getBits(1) == 1);
+    ALOGV("%u.%u: b_content_type = %s\n", presentationID, substreamID, BOOLSTR(b_content_type));
+    if (b_content_type) {
+        CHECK_BITS_LEFT(3);
+        uint32_t content_classifier = mBitReader.getBits(3);
+        ALOGV("%u.%u: content_classifier = %u (%s)\n", presentationID, substreamID,
+            content_classifier, ContentClassifier[content_classifier]);
+
+        // For streams based on TS 103 190 part 1 the presentation level channel_mode doesn't
+        // exist and so we use the channel_mode from either the CM or M&E substream
+        // (they are mutually exclusive)
+        if (mPresentations[presentationID].mChannelMode == -1 &&
+            (content_classifier == 0 || content_classifier == 1)) {
+            mPresentations[presentationID].mChannelMode = channel_mode;
+        }
+        mPresentations[presentationID].mContentClassifier = content_classifier;
+        CHECK_BITS_LEFT(1);
+        bool b_language_indicator = (mBitReader.getBits(1) == 1);
+        ALOGV("%u.%u: b_language_indicator = %s\n", presentationID, substreamID,
+            BOOLSTR(b_language_indicator));
+        if (b_language_indicator) {
+            if (!parseLanguageTag(presentationID, substreamID)) {
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+
+// ETSI TS 103 190-2 v1.1.1 section E.11
+bool AC4DSIParser::parseSubstreamGroupDSI(uint32_t presentationID, uint32_t groupID)
+{
+    CHECK_BITS_LEFT(1);
+    bool b_substreams_present = (mBitReader.getBits(1) == 1);
+    CHECK_BITS_LEFT(1);
+    bool b_hsf_ext = (mBitReader.getBits(1) == 1);
+    CHECK_BITS_LEFT(1);
+    bool b_channel_coded = (mBitReader.getBits(1) == 1);
+    CHECK_BITS_LEFT(8);
+    uint32_t n_substreams = mBitReader.getBits(8);
+    ALOGV("%u.%u: b_substreams_present = %s\n", presentationID, groupID,
+        BOOLSTR(b_substreams_present));
+    ALOGV("%u.%u: b_hsf_ext = %s\n", presentationID, groupID, BOOLSTR(b_hsf_ext));
+    ALOGV("%u.%u: b_channel_coded = %s\n", presentationID, groupID, BOOLSTR(b_channel_coded));
+    ALOGV("%u.%u: n_substreams = %u\n", presentationID, groupID, n_substreams);
+
+    for (uint32_t i = 0; i < n_substreams; i++) {
+        CHECK_BITS_LEFT(2);
+        uint32_t dsi_sf_multiplier = mBitReader.getBits(2);
+        CHECK_BITS_LEFT(1);
+        bool b_substream_bitrate_indicator = (mBitReader.getBits(1) == 1);
+        ALOGV("%u.%u.%u: dsi_sf_multiplier = %u\n", presentationID, groupID, i, dsi_sf_multiplier);
+        ALOGV("%u.%u.%u: b_substream_bitrate_indicator = %s\n", presentationID, groupID, i,
+            BOOLSTR(b_substream_bitrate_indicator));
+
+        if (b_substream_bitrate_indicator) {
+            CHECK_BITS_LEFT(5);
+            uint32_t substream_bitrate_indicator = mBitReader.getBits(5);
+            ALOGV("%u.%u.%u: substream_bitrate_indicator = %u\n", presentationID, groupID, i,
+                substream_bitrate_indicator);
+        }
+        if (b_channel_coded) {
+            CHECK_BITS_LEFT(24);
+            uint32_t dsi_substream_channel_mask = mBitReader.getBits(24);
+            ALOGV("%u.%u.%u: dsi_substream_channel_mask = 0x%06x\n", presentationID, groupID, i,
+                dsi_substream_channel_mask);
+        } else {
+            CHECK_BITS_LEFT(1);
+            bool b_ajoc = (mBitReader.getBits(1) == 1);
+            ALOGV("%u.%u.%u: b_ajoc = %s\n", presentationID, groupID, i, BOOLSTR(b_ajoc));
+            if (b_ajoc) {
+                CHECK_BITS_LEFT(1);
+                bool b_static_dmx = (mBitReader.getBits(1) == 1);
+                ALOGV("%u.%u.%u: b_static_dmx = %s\n", presentationID, groupID, i,
+                    BOOLSTR(b_static_dmx));
+                if (!b_static_dmx) {
+                    CHECK_BITS_LEFT(4);
+                    uint32_t n_dmx_objects_minus1 = mBitReader.getBits(4);
+                    ALOGV("%u.%u.%u: n_dmx_objects_minus1 = %u\n", presentationID, groupID, i,
+                        n_dmx_objects_minus1);
+                }
+                CHECK_BITS_LEFT(6);
+                uint32_t n_umx_objects_minus1 = mBitReader.getBits(6);
+                ALOGV("%u.%u.%u: n_umx_objects_minus1 = %u\n", presentationID, groupID, i,
+                    n_umx_objects_minus1);
+            }
+            CHECK_BITS_LEFT(4);
+            mBitReader.skipBits(4); // objects_assignment_mask
+        }
+    }
+
+    CHECK_BITS_LEFT(1);
+    bool b_content_type = (mBitReader.getBits(1) == 1);
+    ALOGV("%u.%u: b_content_type = %s\n", presentationID, groupID, BOOLSTR(b_content_type));
+    if (b_content_type) {
+        CHECK_BITS_LEFT(3);
+        uint32_t content_classifier = mBitReader.getBits(3);
+        ALOGV("%u.%u: content_classifier = %s (%u)\n", presentationID, groupID,
+            ContentClassifier[content_classifier], content_classifier);
+
+        mPresentations[presentationID].mContentClassifier = content_classifier;
+
+        CHECK_BITS_LEFT(1);
+        bool b_language_indicator = (mBitReader.getBits(1) == 1);
+        ALOGV("%u.%u: b_language_indicator = %s\n", presentationID, groupID,
+            BOOLSTR(b_language_indicator));
+
+        if (b_language_indicator) {
+            if (!parseLanguageTag(presentationID, groupID)) {
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+
+bool AC4DSIParser::parseBitrateDsi() {
+    CHECK_BITS_LEFT(2 + 32 + 32);
+    mBitReader.skipBits(2); // bit_rate_mode
+    mBitReader.skipBits(32); // bit_rate
+    mBitReader.skipBits(32); // bit_rate_precision
+
+    return true;
+}
+
+// TS 103 190-1 section E.4 (ac4_dsi) and TS 103 190-2 section E.6 (ac4_dsi_v1)
+bool AC4DSIParser::parse() {
+    CHECK_BITS_LEFT(3);
+    uint32_t ac4_dsi_version = mBitReader.getBits(3);
+    if (ac4_dsi_version > 1) {
+        ALOGE("error while parsing ac-4 dsi: only versions 0 and 1 are supported");
+        return false;
+    }
+
+    CHECK_BITS_LEFT(7 + 1 + 4 + 9);
+    uint32_t bitstream_version = mBitReader.getBits(7);
+    mBitReader.skipBits(1); // fs_index
+    mBitReader.skipBits(4); // frame_rate_index
+    uint32_t n_presentations = mBitReader.getBits(9);
+
+    int32_t short_program_id = -1;
+    if (bitstream_version > 1) {
+        if (ac4_dsi_version == 0) {
+            ALOGE("invalid ac4 dsi");
+            return false;
+        }
+        CHECK_BITS_LEFT(1);
+        bool b_program_id = (mBitReader.getBits(1) == 1);
+        if (b_program_id) {
+            CHECK_BITS_LEFT(16 + 1);
+            short_program_id = mBitReader.getBits(16);
+            bool b_uuid = (mBitReader.getBits(1) == 1);
+            if (b_uuid) {
+                const uint32_t kAC4UUIDSizeInBytes = 16;
+                char program_uuid[kAC4UUIDSizeInBytes];
+                CHECK_BITS_LEFT(kAC4UUIDSizeInBytes * 8);
+                for (uint32_t i = 0; i < kAC4UUIDSizeInBytes; i++) {
+                    program_uuid[i] = (char)(mBitReader.getBits(8));
+                }
+                ALOGV("UUID = %s", program_uuid);
+            }
+        }
+    }
+
+    if (ac4_dsi_version == 1) {
+        if (!parseBitrateDsi()) {
+            return false;
+        }
+        BYTE_ALIGN;
+    }
+
+    for (uint32_t presentation = 0; presentation < n_presentations; presentation++) {
+        mPresentations[presentation].mProgramID = short_program_id;
+        // known as b_single_substream in ac4_dsi_version 0
+        bool b_single_substream_group = false;
+        uint32_t presentation_config = 0, presentation_version = 0;
+        uint32_t pres_bytes = 0;
+        uint64_t start = 0;
+
+        if (ac4_dsi_version == 0) {
+            CHECK_BITS_LEFT(1 + 5 + 5);
+            b_single_substream_group = (mBitReader.getBits(1) == 1);
+            presentation_config = mBitReader.getBits(5);
+            presentation_version = mBitReader.getBits(5);
+        } else if (ac4_dsi_version == 1) {
+            CHECK_BITS_LEFT(8 + 8);
+            presentation_version = mBitReader.getBits(8);
+            pres_bytes = mBitReader.getBits(8);
+            if (pres_bytes == 0xff) {
+                CHECK_BITS_LEFT(16);
+                pres_bytes += mBitReader.getBits(16);
+            }
+            ALOGV("%u: pres_bytes = %u\n", presentation, pres_bytes);
+            if (presentation_version > 2) {
+                CHECK_BITS_LEFT(pres_bytes * 8);
+                mBitReader.skipBits(pres_bytes * 8);
+                continue;
+            }
+            /* record a marker, less the size of the presentation_config */
+            start = (mDSISize - mBitReader.numBitsLeft()) / 8;
+            // ac4_presentation_v0_dsi(), ac4_presentation_v1_dsi() and ac4_presentation_v2_dsi()
+            // all start with a presentation_config of 5 bits
+            CHECK_BITS_LEFT(5);
+            presentation_config = mBitReader.getBits(5);
+            b_single_substream_group = (presentation_config == 0x1f);
+        }
+
+        static const char *PresentationConfig[] = {
+            "Music&Effects + Dialog",
+            "Main + DE",
+            "Main + Associate",
+            "Music&Effects + Dialog + Associate",
+            "Main + DE + Associate",
+            "Arbitrary substream groups",
+            "EMDF only"
+        };
+        ALOGV("%u: b_single_substream/group = %s\n", presentation,
+            BOOLSTR(b_single_substream_group));
+        ALOGV("%u: presentation_version = %u\n", presentation, presentation_version);
+        ALOGV("%u: presentation_config = %u (%s)\n", presentation, presentation_config,
+            (presentation_config >= NELEM(PresentationConfig) ?
+            "reserved" : PresentationConfig[presentation_config]));
+
+        bool b_add_emdf_substreams = false;
+        if (!b_single_substream_group && presentation_config == 6) {
+            b_add_emdf_substreams = true;
+            ALOGV("%u: b_add_emdf_substreams = %s\n", presentation, BOOLSTR(b_add_emdf_substreams));
+        } else {
+            CHECK_BITS_LEFT(3 + 1);
+            uint32_t mdcompat = mBitReader.getBits(3);
+            ALOGV("%u: mdcompat = %d\n", presentation, mdcompat);
+
+            bool b_presentation_group_index = (mBitReader.getBits(1) == 1);
+            ALOGV("%u: b_presentation_group_index = %s\n", presentation,
+                BOOLSTR(b_presentation_group_index));
+            if (b_presentation_group_index) {
+                CHECK_BITS_LEFT(5);
+                mPresentations[presentation].mGroupIndex = mBitReader.getBits(5);
+                ALOGV("%u: presentation_group_index = %d\n", presentation,
+                    mPresentations[presentation].mGroupIndex);
+            }
+            CHECK_BITS_LEFT(2);
+            uint32_t dsi_frame_rate_multiply_info = mBitReader.getBits(2);
+            ALOGV("%u: dsi_frame_rate_multiply_info = %d\n", presentation,
+                dsi_frame_rate_multiply_info);
+            if (ac4_dsi_version == 1 && (presentation_version == 1 || presentation_version == 2)) {
+                CHECK_BITS_LEFT(2);
+                uint32_t dsi_frame_rate_fraction_info = mBitReader.getBits(2);
+                ALOGV("%u: dsi_frame_rate_fraction_info = %d\n", presentation,
+                    dsi_frame_rate_fraction_info);
+            }
+            CHECK_BITS_LEFT(5 + 10);
+            uint32_t presentation_emdf_version = mBitReader.getBits(5);
+            uint32_t presentation_key_id = mBitReader.getBits(10);
+            ALOGV("%u: presentation_emdf_version = %d\n", presentation, presentation_emdf_version);
+            ALOGV("%u: presentation_key_id = %d\n", presentation, presentation_key_id);
+
+            if (ac4_dsi_version == 1) {
+                bool b_presentation_channel_coded = false;
+                if (presentation_version == 0) {
+                    b_presentation_channel_coded = true;
+                } else {
+                    CHECK_BITS_LEFT(1);
+                    b_presentation_channel_coded = (mBitReader.getBits(1) == 1);
+                }
+                ALOGV("%u: b_presentation_channel_coded = %s\n", presentation,
+                    BOOLSTR(b_presentation_channel_coded));
+                if (b_presentation_channel_coded) {
+                    if (presentation_version == 1 || presentation_version == 2) {
+                        CHECK_BITS_LEFT(5);
+                        uint32_t dsi_presentation_ch_mode = mBitReader.getBits(5);
+                        mPresentations[presentation].mChannelMode = dsi_presentation_ch_mode;
+                        ALOGV("%u: dsi_presentation_ch_mode = %d (%s)\n", presentation,
+                            dsi_presentation_ch_mode,
+                            dsi_presentation_ch_mode < NELEM(ChannelModes) ?
+                            ChannelModes[dsi_presentation_ch_mode] : "reserved");
+
+                        if (dsi_presentation_ch_mode >= 11 && dsi_presentation_ch_mode <= 14) {
+                            CHECK_BITS_LEFT(1 + 2);
+                            uint32_t pres_b_4_back_channels_present = mBitReader.getBits(1);
+                            uint32_t pres_top_channel_pairs = mBitReader.getBits(2);
+                            ALOGV("%u: pres_b_4_back_channels_present = %s\n", presentation,
+                                BOOLSTR(pres_b_4_back_channels_present));
+                            ALOGV("%u: pres_top_channel_pairs = %d\n", presentation,
+                                pres_top_channel_pairs);
+                        }
+                    }
+                    // presentation_channel_mask in ac4_presentation_v0_dsi()
+                    CHECK_BITS_LEFT(24);
+                    uint32_t presentation_channel_mask_v1 = mBitReader.getBits(24);
+                    ALOGV("%u: presentation_channel_mask_v1 = 0x%06x\n", presentation,
+                        presentation_channel_mask_v1);
+                }
+                if (presentation_version == 1 || presentation_version == 2) {
+                    CHECK_BITS_LEFT(1);
+                    bool b_presentation_core_differs = (mBitReader.getBits(1) == 1);
+                    ALOGV("%u: b_presentation_core_differs = %s\n", presentation,
+                        BOOLSTR(b_presentation_core_differs));
+                    if (b_presentation_core_differs) {
+                        CHECK_BITS_LEFT(1);
+                        bool b_presentation_core_channel_coded = (mBitReader.getBits(1) == 1);
+                        if (b_presentation_core_channel_coded) {
+                            CHECK_BITS_LEFT(2);
+                            mBitReader.skipBits(2); // dsi_presentation_channel_mode_core
+                        }
+                    }
+                    CHECK_BITS_LEFT(1);
+                    bool b_presentation_filter = (mBitReader.getBits(1) == 1);
+                    ALOGV("%u: b_presentation_filter = %s\n", presentation,
+                        BOOLSTR(b_presentation_filter));
+                    if (b_presentation_filter) {
+                        CHECK_BITS_LEFT(1 + 8);
+                        bool b_enable_presentation = (mBitReader.getBits(1) == 1);
+                        if (!b_enable_presentation) {
+                            mPresentations[presentation].mEnabled = false;
+                        }
+                        ALOGV("%u: b_enable_presentation = %s\n", presentation,
+                            BOOLSTR(b_enable_presentation));
+                        uint32_t n_filter_bytes = mBitReader.getBits(8);
+                        CHECK_BITS_LEFT(n_filter_bytes * 8);
+                        for (uint32_t i = 0; i < n_filter_bytes; i++) {
+                            mBitReader.skipBits(8); // filter_data
+                        }
+                    }
+                }
+            } /* ac4_dsi_version == 1 */
+
+            if (b_single_substream_group) {
+                if (presentation_version == 0) {
+                    if (!parseSubstreamDSI(presentation, 0)) {
+                        return false;
+                    }
+                } else {
+                    if (!parseSubstreamGroupDSI(presentation, 0)) {
+                        return false;
+                    }
+                }
+            } else {
+                if (ac4_dsi_version == 1) {
+                    CHECK_BITS_LEFT(1);
+                    bool b_multi_pid = (mBitReader.getBits(1) == 1);
+                    ALOGV("%u: b_multi_pid = %s\n", presentation, BOOLSTR(b_multi_pid));
+                } else {
+                    CHECK_BITS_LEFT(1);
+                    bool b_hsf_ext = (mBitReader.getBits(1) == 1);
+                    ALOGV("%u: b_hsf_ext = %s\n", presentation, BOOLSTR(b_hsf_ext));
+                }
+                switch (presentation_config) {
+                case 0:
+                case 1:
+                case 2:
+                    if (presentation_version == 0) {
+                        if (!parseSubstreamDSI(presentation, 0)) {
+                            return false;
+                        }
+                        if (!parseSubstreamDSI(presentation, 1)) {
+                            return false;
+                        }
+                    } else {
+                        if (!parseSubstreamGroupDSI(presentation, 0)) {
+                            return false;
+                        }
+                        if (!parseSubstreamGroupDSI(presentation, 1)) {
+                            return false;
+                        }
+                    }
+                    break;
+                case 3:
+                case 4:
+                    if (presentation_version == 0) {
+                        if (!parseSubstreamDSI(presentation, 0)) {
+                            return false;
+                        }
+                        if (!parseSubstreamDSI(presentation, 1)) {
+                            return false;
+                        }
+                        if (!parseSubstreamDSI(presentation, 2)) {
+                            return false;
+                        }
+                    } else {
+                        if (!parseSubstreamGroupDSI(presentation, 0)) {
+                            return false;
+                        }
+                        if (!parseSubstreamGroupDSI(presentation, 1)) {
+                            return false;
+                        }
+                        if (!parseSubstreamGroupDSI(presentation, 2)) {
+                            return false;
+                        }
+                    }
+                    break;
+                case 5:
+                    if (presentation_version == 0) {
+                        if (!parseSubstreamDSI(presentation, 0)) {
+                            return false;
+                        }
+                    } else {
+                        CHECK_BITS_LEFT(3);
+                        uint32_t n_substream_groups_minus2 = mBitReader.getBits(3);
+                        ALOGV("%u: n_substream_groups_minus2 = %d\n", presentation,
+                            n_substream_groups_minus2);
+                        for (uint32_t sg = 0; sg < n_substream_groups_minus2 + 2; sg++) {
+                            if (!parseSubstreamGroupDSI(presentation, sg)) {
+                                return false;
+                            }
+                        }
+                    }
+                    break;
+                default:
+                    CHECK_BITS_LEFT(7);
+                    uint32_t n_skip_bytes = mBitReader.getBits(7);
+                    CHECK_BITS_LEFT(n_skip_bytes * 8)
+                    for (uint32_t j = 0; j < n_skip_bytes; j++) {
+                        mBitReader.getBits(8);
+                    }
+                    break;
+                }
+            }
+            CHECK_BITS_LEFT(1 + 1);
+            bool b_pre_virtualized = (mBitReader.getBits(1) == 1);
+            mPresentations[presentation].mPreVirtualized = b_pre_virtualized;
+            b_add_emdf_substreams = (mBitReader.getBits(1) == 1);
+            ALOGV("%u: b_pre_virtualized = %s\n", presentation, BOOLSTR(b_pre_virtualized));
+            ALOGV("%u: b_add_emdf_substreams = %s\n", presentation,
+                BOOLSTR(b_add_emdf_substreams));
+        }
+        if (b_add_emdf_substreams) {
+            CHECK_BITS_LEFT(7);
+            uint32_t n_add_emdf_substreams = mBitReader.getBits(7);
+            for (uint32_t j = 0; j < n_add_emdf_substreams; j++) {
+                CHECK_BITS_LEFT(5 + 10);
+                uint32_t substream_emdf_version = mBitReader.getBits(5);
+                uint32_t substream_key_id = mBitReader.getBits(10);
+                ALOGV("%u: emdf_substream[%d]: version=%d, key_id=%d\n", presentation, j,
+                    substream_emdf_version, substream_key_id);
+            }
+        }
+
+        bool b_presentation_bitrate_info = false;
+        if (presentation_version > 0) {
+            CHECK_BITS_LEFT(1);
+            b_presentation_bitrate_info = (mBitReader.getBits(1) == 1);
+        }
+
+        ALOGV("b_presentation_bitrate_info = %s\n", BOOLSTR(b_presentation_bitrate_info));
+        if (b_presentation_bitrate_info) {
+            if (!parseBitrateDsi()) {
+                return false;
+            }
+        }
+
+        if (presentation_version > 0) {
+            CHECK_BITS_LEFT(1);
+            bool b_alternative = (mBitReader.getBits(1) == 1);
+            ALOGV("b_alternative = %s\n", BOOLSTR(b_alternative));
+            if (b_alternative) {
+                BYTE_ALIGN;
+                CHECK_BITS_LEFT(16);
+                uint32_t name_len = mBitReader.getBits(16);
+                CHECK_BITS_LEFT(name_len * 8);
+                std::string &presentation_name =
+                    mPresentations[presentation].mDescription;
+                presentation_name.clear();
+                presentation_name.resize(name_len);
+                for (uint32_t i = 0; i < name_len; i++) {
+                    presentation_name[i] = (char)(mBitReader.getBits(8));
+                }
+                CHECK_BITS_LEFT(5);
+                uint32_t n_targets = mBitReader.getBits(5);
+                CHECK_BITS_LEFT(n_targets * (3 + 8));
+                for (uint32_t i = 0; i < n_targets; i++){
+                    mBitReader.skipBits(3); // target_md_compat
+                    mBitReader.skipBits(8); // target_device_category
+                }
+            }
+        }
+
+        BYTE_ALIGN;
+
+        if (ac4_dsi_version == 1) {
+            uint64_t end = (mDSISize - mBitReader.numBitsLeft()) / 8;
+            uint64_t presentation_bytes = end - start;
+            uint64_t skip_bytes = pres_bytes - presentation_bytes;
+            ALOGV("skipping = %" PRIu64 " bytes", skip_bytes);
+            CHECK_BITS_LEFT(skip_bytes * 8);
+            mBitReader.skipBits(skip_bytes * 8);
+        }
+
+        // we should know this or something is probably wrong
+        // with the bitstream (or we don't support it)
+        if (mPresentations[presentation].mChannelMode == -1) {
+            ALOGE("could not determing channel mode of presentation %d", presentation);
+            return false;
+        }
+    } /* each presentation */
+
+    return true;
+}
+
+};
diff --git a/media/extractors/mp4/AC4Parser.h b/media/extractors/mp4/AC4Parser.h
new file mode 100644
index 0000000..73b6e31
--- /dev/null
+++ b/media/extractors/mp4/AC4Parser.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AC4_PARSER_H_
+#define AC4_PARSER_H_
+
+#include <cstdint>
+#include <map>
+#include <string>
+
+#include <media/stagefright/foundation/ABitReader.h>
+
+namespace android {
+
+class AC4Parser {
+public:
+    AC4Parser();
+    virtual ~AC4Parser() { }
+
+    virtual bool parse() = 0;
+
+    struct AC4Presentation {
+        int32_t mChannelMode = -1;
+        int32_t mProgramID = -1;
+        int32_t mGroupIndex = -1;
+
+        // TS 103 190-1 v1.2.1 4.3.3.8.1
+        enum ContentClassifiers {
+            kCompleteMain,
+            kMusicAndEffects,
+            kVisuallyImpaired,
+            kHearingImpaired,
+            kDialog,
+            kCommentary,
+            kEmergency,
+            kVoiceOver
+        };
+
+        uint32_t mContentClassifier = kCompleteMain;
+
+        // ETSI TS 103 190-2 V1.1.1 (2015-09) Table 79: channel_mode
+        enum InputChannelMode {
+            kChannelMode_Mono,
+            kChannelMode_Stereo,
+            kChannelMode_3_0,
+            kChannelMode_5_0,
+            kChannelMode_5_1,
+            kChannelMode_7_0_34,
+            kChannelMode_7_1_34,
+            kChannelMode_7_0_52,
+            kChannelMode_7_1_52,
+            kChannelMode_7_0_322,
+            kChannelMode_7_1_322,
+            kChannelMode_7_0_4,
+            kChannelMode_7_1_4,
+            kChannelMode_9_0_4,
+            kChannelMode_9_1_4,
+            kChannelMode_22_2,
+            kChannelMode_Reserved,
+        };
+
+        bool mHasDialogEnhancements = false;
+        bool mPreVirtualized = false;
+        bool mEnabled = true;
+
+        std::string mLanguage;
+        std::string mDescription;
+    };
+    typedef std::map<uint32_t, AC4Presentation> AC4Presentations;
+
+    const AC4Presentations& getPresentations() const { return mPresentations; }
+
+protected:
+    AC4Presentations mPresentations;
+};
+
+class AC4DSIParser: public AC4Parser {
+public:
+    explicit AC4DSIParser(ABitReader &br);
+    virtual ~AC4DSIParser() { }
+
+    bool parse();
+
+private:
+    bool parseSubstreamDSI(uint32_t presentationID, uint32_t substreamID);
+    bool parseSubstreamGroupDSI(uint32_t presentationID, uint32_t groupID);
+    bool parseLanguageTag(uint32_t presentationID, uint32_t substreamID);
+    bool parseBitrateDsi();
+
+    uint64_t mDSISize;
+    ABitReader& mBitReader;
+};
+
+};
+
+#endif  // AC4_PARSER_H_
diff --git a/media/extractors/mp4/Android.bp b/media/extractors/mp4/Android.bp
index fa739e8..1b308aa 100644
--- a/media/extractors/mp4/Android.bp
+++ b/media/extractors/mp4/Android.bp
@@ -2,6 +2,7 @@
     name: "libmp4extractor_defaults",
 
     srcs: [
+        "AC4Parser.cpp",
         "ItemTable.cpp",
         "MPEG4Extractor.cpp",
         "SampleIterator.cpp",
@@ -14,7 +15,7 @@
 
     shared_libs: [
         "liblog",
-        "libmediaextractor",
+        "libmediandk"
     ],
 
     static_libs: [
@@ -46,9 +47,6 @@
             "unsigned-integer-overflow",
             "signed-integer-overflow",
         ],
-        diag: {
-            cfi: true,
-        },
     },
 
 }
diff --git a/media/extractors/mp4/ItemTable.cpp b/media/extractors/mp4/ItemTable.cpp
index ca9deab..8c8e6d1 100644
--- a/media/extractors/mp4/ItemTable.cpp
+++ b/media/extractors/mp4/ItemTable.cpp
@@ -17,8 +17,11 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "ItemTable"
 
+#include <unordered_set>
+
 #include <ItemTable.h>
-#include <media/DataSourceBase.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/foundation/ABuffer.h>
@@ -47,7 +50,7 @@
             offset(0), size(0), nextTileIndex(0) {}
 
     bool isGrid() const {
-        return type == FOURCC('g', 'r', 'i', 'd');
+        return type == FOURCC("grid");
     }
 
     status_t getNextTileItemId(uint32_t *nextTileItemId, bool reset) {
@@ -92,7 +95,7 @@
 
 struct Box {
 protected:
-    Box(DataSourceBase *source, uint32_t type) :
+    Box(DataSourceHelper *source, uint32_t type) :
         mDataSource(source), mType(type) {}
 
     virtual ~Box() {}
@@ -104,14 +107,14 @@
 
     inline uint32_t type() const { return mType; }
 
-    inline DataSourceBase *source() const { return mDataSource; }
+    inline DataSourceHelper *source() const { return mDataSource; }
 
     status_t parseChunk(off64_t *offset);
 
     status_t parseChunks(off64_t offset, size_t size);
 
 private:
-    DataSourceBase *mDataSource;
+    DataSourceHelper *mDataSource;
     uint32_t mType;
 };
 
@@ -186,7 +189,7 @@
 
 struct FullBox : public Box {
 protected:
-    FullBox(DataSourceBase *source, uint32_t type) :
+    FullBox(DataSourceHelper *source, uint32_t type) :
         Box(source, type), mVersion(0), mFlags(0) {}
 
     inline uint8_t version() const { return mVersion; }
@@ -221,8 +224,8 @@
 //
 
 struct PitmBox : public FullBox {
-    PitmBox(DataSourceBase *source) :
-        FullBox(source, FOURCC('p', 'i', 't', 'm')) {}
+    PitmBox(DataSourceHelper *source) :
+        FullBox(source, FOURCC("pitm")) {}
 
     status_t parse(off64_t offset, size_t size, uint32_t *primaryItemId);
 };
@@ -301,8 +304,8 @@
 };
 
 struct IlocBox : public FullBox {
-    IlocBox(DataSourceBase *source, KeyedVector<uint32_t, ItemLoc> *itemLocs) :
-        FullBox(source, FOURCC('i', 'l', 'o', 'c')),
+    IlocBox(DataSourceHelper *source, KeyedVector<uint32_t, ItemLoc> *itemLocs) :
+        FullBox(source, FOURCC("iloc")),
         mItemLocs(itemLocs), mHasConstructMethod1(false) {}
 
     status_t parse(off64_t offset, size_t size);
@@ -423,10 +426,8 @@
         }
         ALOGV("extent_count %d", extent_count);
 
-        if (extent_count > 1 && (offset_size == 0 || length_size == 0)) {
-            // if the item is dividec into more than one extents, offset and
-            // length must be present.
-            return ERROR_MALFORMED;
+        if (extent_count > 1) {
+            return ERROR_UNSUPPORTED;
         }
         offset += 2;
 
@@ -471,7 +472,7 @@
 //
 
 struct ItemReference : public Box, public RefBase {
-    ItemReference(DataSourceBase *source, uint32_t type, uint32_t itemIdSize) :
+    ItemReference(DataSourceHelper *source, uint32_t type, uint32_t itemIdSize) :
         Box(source, type), mItemId(0), mRefIdSize(itemIdSize) {}
 
     status_t parse(off64_t offset, size_t size);
@@ -496,7 +497,7 @@
     ALOGV("attach reference type 0x%x to item id %d)", type(), mItemId);
 
     switch(type()) {
-    case FOURCC('d', 'i', 'm', 'g'): {
+    case FOURCC("dimg"): {
         ssize_t itemIndex = itemIdToItemMap.indexOfKey(mItemId);
 
         // ignore non-image items
@@ -524,7 +525,7 @@
         }
         break;
     }
-    case FOURCC('t', 'h', 'm', 'b'): {
+    case FOURCC("thmb"): {
         ssize_t itemIndex = itemIdToItemMap.indexOfKey(mItemId);
 
         // ignore non-image items
@@ -553,7 +554,7 @@
         }
         break;
     }
-    case FOURCC('c', 'd', 's', 'c'): {
+    case FOURCC("cdsc"): {
         ssize_t itemIndex = itemIdToExifMap.indexOfKey(mItemId);
 
         // ignore non-exif block items
@@ -574,7 +575,7 @@
         }
         break;
     }
-    case FOURCC('a', 'u', 'x', 'l'): {
+    case FOURCC("auxl"): {
         ssize_t itemIndex = itemIdToItemMap.indexOfKey(mItemId);
 
         // ignore non-image items
@@ -626,8 +627,8 @@
 }
 
 struct IrefBox : public FullBox {
-    IrefBox(DataSourceBase *source, Vector<sp<ItemReference> > *itemRefs) :
-        FullBox(source, FOURCC('i', 'r', 'e', 'f')), mRefIdSize(0), mItemRefs(itemRefs) {}
+    IrefBox(DataSourceHelper *source, Vector<sp<ItemReference> > *itemRefs) :
+        FullBox(source, FOURCC("iref")), mRefIdSize(0), mItemRefs(itemRefs) {}
 
     status_t parse(off64_t offset, size_t size);
 
@@ -688,8 +689,8 @@
 };
 
 struct IspeBox : public FullBox, public ItemProperty {
-    IspeBox(DataSourceBase *source) :
-        FullBox(source, FOURCC('i', 's', 'p', 'e')), mWidth(0), mHeight(0) {}
+    IspeBox(DataSourceHelper *source) :
+        FullBox(source, FOURCC("ispe")), mWidth(0), mHeight(0) {}
 
     status_t parse(off64_t offset, size_t size) override;
 
@@ -724,8 +725,8 @@
 }
 
 struct HvccBox : public Box, public ItemProperty {
-    HvccBox(DataSourceBase *source) :
-        Box(source, FOURCC('h', 'v', 'c', 'C')) {}
+    HvccBox(DataSourceHelper *source) :
+        Box(source, FOURCC("hvcC")) {}
 
     status_t parse(off64_t offset, size_t size) override;
 
@@ -757,8 +758,8 @@
 }
 
 struct IrotBox : public Box, public ItemProperty {
-    IrotBox(DataSourceBase *source) :
-        Box(source, FOURCC('i', 'r', 'o', 't')), mAngle(0) {}
+    IrotBox(DataSourceHelper *source) :
+        Box(source, FOURCC("irot")), mAngle(0) {}
 
     status_t parse(off64_t offset, size_t size) override;
 
@@ -786,8 +787,8 @@
 }
 
 struct ColrBox : public Box, public ItemProperty {
-    ColrBox(DataSourceBase *source) :
-        Box(source, FOURCC('c', 'o', 'l', 'r')) {}
+    ColrBox(DataSourceHelper *source) :
+        Box(source, FOURCC("colr")) {}
 
     status_t parse(off64_t offset, size_t size) override;
 
@@ -811,11 +812,11 @@
     }
     offset += 4;
     size -= 4;
-    if (colour_type == FOURCC('n', 'c', 'l', 'x')) {
+    if (colour_type == FOURCC("nclx")) {
         return OK;
     }
-    if ((colour_type != FOURCC('r', 'I', 'C', 'C')) &&
-        (colour_type != FOURCC('p', 'r', 'o', 'f'))) {
+    if ((colour_type != FOURCC("rICC")) &&
+        (colour_type != FOURCC("prof"))) {
         return ERROR_MALFORMED;
     }
 
@@ -834,8 +835,8 @@
 }
 
 struct IpmaBox : public FullBox {
-    IpmaBox(DataSourceBase *source, Vector<AssociationEntry> *associations) :
-        FullBox(source, FOURCC('i', 'p', 'm', 'a')), mAssociations(associations) {}
+    IpmaBox(DataSourceHelper *source, Vector<AssociationEntry> *associations) :
+        FullBox(source, FOURCC("ipma")), mAssociations(associations) {}
 
     status_t parse(off64_t offset, size_t size);
 private:
@@ -908,8 +909,8 @@
 }
 
 struct IpcoBox : public Box {
-    IpcoBox(DataSourceBase *source, Vector<sp<ItemProperty> > *properties) :
-        Box(source, FOURCC('i', 'p', 'c', 'o')), mItemProperties(properties) {}
+    IpcoBox(DataSourceHelper *source, Vector<sp<ItemProperty> > *properties) :
+        Box(source, FOURCC("ipco")), mItemProperties(properties) {}
 
     status_t parse(off64_t offset, size_t size);
 protected:
@@ -929,22 +930,22 @@
 status_t IpcoBox::onChunkData(uint32_t type, off64_t offset, size_t size) {
     sp<ItemProperty> itemProperty;
     switch(type) {
-        case FOURCC('h', 'v', 'c', 'C'):
+        case FOURCC("hvcC"):
         {
             itemProperty = new HvccBox(source());
             break;
         }
-        case FOURCC('i', 's', 'p', 'e'):
+        case FOURCC("ispe"):
         {
             itemProperty = new IspeBox(source());
             break;
         }
-        case FOURCC('i', 'r', 'o', 't'):
+        case FOURCC("irot"):
         {
             itemProperty = new IrotBox(source());
             break;
         }
-        case FOURCC('c', 'o', 'l', 'r'):
+        case FOURCC("colr"):
         {
             itemProperty = new ColrBox(source());
             break;
@@ -965,10 +966,10 @@
 }
 
 struct IprpBox : public Box {
-    IprpBox(DataSourceBase *source,
+    IprpBox(DataSourceHelper *source,
             Vector<sp<ItemProperty> > *properties,
             Vector<AssociationEntry> *associations) :
-        Box(source, FOURCC('i', 'p', 'r', 'p')),
+        Box(source, FOURCC("iprp")),
         mProperties(properties), mAssociations(associations) {}
 
     status_t parse(off64_t offset, size_t size);
@@ -992,12 +993,12 @@
 
 status_t IprpBox::onChunkData(uint32_t type, off64_t offset, size_t size) {
     switch(type) {
-        case FOURCC('i', 'p', 'c', 'o'):
+        case FOURCC("ipco"):
         {
             IpcoBox ipcoBox(source(), mProperties);
             return ipcoBox.parse(offset, size);
         }
-        case FOURCC('i', 'p', 'm', 'a'):
+        case FOURCC("ipma"):
         {
             IpmaBox ipmaBox(source(), mAssociations);
             return ipmaBox.parse(offset, size);
@@ -1022,8 +1023,8 @@
 };
 
 struct InfeBox : public FullBox {
-    InfeBox(DataSourceBase *source) :
-        FullBox(source, FOURCC('i', 'n', 'f', 'e')) {}
+    InfeBox(DataSourceHelper *source) :
+        FullBox(source, FOURCC("infe")) {}
 
     status_t parse(off64_t offset, size_t size, ItemInfo *itemInfo);
 
@@ -1103,7 +1104,7 @@
         }
         ALOGV("item_name %s", item_name.c_str());
 
-        if (item_type == FOURCC('m', 'i', 'm', 'e')) {
+        if (item_type == FOURCC("mime")) {
             String8 content_type;
             if (!parseNullTerminatedString(&offset, &size, &content_type)) {
                 return ERROR_MALFORMED;
@@ -1116,7 +1117,7 @@
                     return ERROR_MALFORMED;
                 }
             }
-        } else if (item_type == FOURCC('u', 'r', 'i', ' ')) {
+        } else if (item_type == FOURCC("uri ")) {
             String8 item_uri_type;
             if (!parseNullTerminatedString(&offset, &size, &item_uri_type)) {
                 return ERROR_MALFORMED;
@@ -1127,20 +1128,19 @@
 }
 
 struct IinfBox : public FullBox {
-    IinfBox(DataSourceBase *source, Vector<ItemInfo> *itemInfos) :
-        FullBox(source, FOURCC('i', 'i', 'n', 'f')),
-        mItemInfos(itemInfos), mHasGrids(false) {}
+    IinfBox(DataSourceHelper *source, Vector<ItemInfo> *itemInfos) :
+        FullBox(source, FOURCC("iinf")), mItemInfos(itemInfos) {}
 
     status_t parse(off64_t offset, size_t size);
 
-    bool hasGrids() { return mHasGrids; }
+    bool hasFourCC(uint32_t type) { return mFourCCSeen.count(type) > 0; }
 
 protected:
     status_t onChunkData(uint32_t type, off64_t offset, size_t size) override;
 
 private:
     Vector<ItemInfo> *mItemInfos;
-    bool mHasGrids;
+    std::unordered_set<uint32_t> mFourCCSeen;
 };
 
 status_t IinfBox::parse(off64_t offset, size_t size) {
@@ -1178,7 +1178,7 @@
 }
 
 status_t IinfBox::onChunkData(uint32_t type, off64_t offset, size_t size) {
-    if (type != FOURCC('i', 'n', 'f', 'e')) {
+    if (type != FOURCC("infe")) {
         return OK;
     }
 
@@ -1187,7 +1187,7 @@
     status_t err = infeBox.parse(offset, size, &itemInfo);
     if (err == OK) {
         mItemInfos->push_back(itemInfo);
-        mHasGrids |= (itemInfo.itemType == FOURCC('g', 'r', 'i', 'd'));
+        mFourCCSeen.insert(itemInfo.itemType);
     }
     // InfeBox parse returns ERROR_UNSUPPORTED if the box if an unsupported
     // version. Ignore this error as it's not fatal.
@@ -1196,7 +1196,7 @@
 
 //////////////////////////////////////////////////////////////////
 
-ItemTable::ItemTable(DataSourceBase *source)
+ItemTable::ItemTable(DataSourceHelper *source)
     : mDataSource(source),
       mPrimaryItemId(0),
       mIdatOffset(0),
@@ -1213,31 +1213,31 @@
 
 status_t ItemTable::parse(uint32_t type, off64_t data_offset, size_t chunk_data_size) {
     switch(type) {
-        case FOURCC('i', 'l', 'o', 'c'):
+        case FOURCC("iloc"):
         {
             return parseIlocBox(data_offset, chunk_data_size);
         }
-        case FOURCC('i', 'i', 'n', 'f'):
+        case FOURCC("iinf"):
         {
             return parseIinfBox(data_offset, chunk_data_size);
         }
-        case FOURCC('i', 'p', 'r', 'p'):
+        case FOURCC("iprp"):
         {
             return parseIprpBox(data_offset, chunk_data_size);
         }
-        case FOURCC('p', 'i', 't', 'm'):
+        case FOURCC("pitm"):
         {
             return parsePitmBox(data_offset, chunk_data_size);
         }
-        case FOURCC('i', 'd', 'a', 't'):
+        case FOURCC("idat"):
         {
             return parseIdatBox(data_offset, chunk_data_size);
         }
-        case FOURCC('i', 'r', 'e', 'f'):
+        case FOURCC("iref"):
         {
             return parseIrefBox(data_offset, chunk_data_size);
         }
-        case FOURCC('i', 'p', 'r', 'o'):
+        case FOURCC("ipro"):
         {
             ALOGW("ipro box not supported!");
             break;
@@ -1276,7 +1276,7 @@
         return err;
     }
 
-    if (iinfBox.hasGrids()) {
+    if (iinfBox.hasFourCC(FOURCC("grid")) || iinfBox.hasFourCC(FOURCC("Exif"))) {
         mRequiredBoxes.insert('iref');
     }
 
@@ -1354,9 +1354,9 @@
         //   'grid': derived image from tiles
         //   'hvc1': coded image (or tile)
         //   'Exif': EXIF metadata
-        if (info.itemType != FOURCC('g', 'r', 'i', 'd') &&
-            info.itemType != FOURCC('h', 'v', 'c', '1') &&
-            info.itemType != FOURCC('E', 'x', 'i', 'f')) {
+        if (info.itemType != FOURCC("grid") &&
+            info.itemType != FOURCC("hvc1") &&
+            info.itemType != FOURCC("Exif")) {
             continue;
         }
 
@@ -1379,7 +1379,7 @@
             return ERROR_MALFORMED;
         }
 
-        if (info.itemType == FOURCC('E', 'x', 'i', 'f')) {
+        if (info.itemType == FOURCC("Exif")) {
             // Only add if the Exif data is non-empty. The first 4 bytes contain
             // the offset to TIFF header, which the Exif parser doesn't use.
             if (size > 4) {
@@ -1476,7 +1476,7 @@
     return mImageItemsValid ? mDisplayables.size() : 0;
 }
 
-sp<MetaData> ItemTable::getImageMeta(const uint32_t imageIndex) {
+AMediaFormat *ItemTable::getImageMeta(const uint32_t imageIndex) {
     if (!mImageItemsValid) {
         return NULL;
     }
@@ -1501,64 +1501,80 @@
         }
     }
 
-    sp<MetaData> meta = new MetaData;
-    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC);
+    AMediaFormat *meta = AMediaFormat_new();
+    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC);
 
     if (image->itemId == mPrimaryItemId) {
-        meta->setInt32(kKeyTrackIsDefault, 1);
+        AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_DEFAULT, 1);
     }
 
     ALOGV("image[%u]: size %dx%d", imageIndex, image->width, image->height);
 
-    meta->setInt32(kKeyWidth, image->width);
-    meta->setInt32(kKeyHeight, image->height);
+    AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_WIDTH, image->width);
+    AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_HEIGHT, image->height);
     if (image->rotation != 0) {
         // Rotation angle in HEIF is CCW, convert to CW here to be
         // consistent with the other media formats.
         switch(image->rotation) {
-            case 90: meta->setInt32(kKeyRotation, 270); break;
-            case 180: meta->setInt32(kKeyRotation, 180); break;
-            case 270: meta->setInt32(kKeyRotation, 90); break;
+            case 90:
+            case 180:
+            case 270:
+                AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_ROTATION, 360 - image->rotation);
+                break;
             default: break; // don't set if invalid
         }
     }
-    meta->setInt32(kKeyMaxInputSize, image->width * image->height * 1.5);
+    AMediaFormat_setInt32(meta,
+            AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, image->width * image->height * 1.5);
 
     if (!image->thumbnails.empty()) {
         ssize_t thumbItemIndex = mItemIdToItemMap.indexOfKey(image->thumbnails[0]);
         if (thumbItemIndex >= 0) {
             const ImageItem &thumbnail = mItemIdToItemMap[thumbItemIndex];
 
-            meta->setInt32(kKeyThumbnailWidth, thumbnail.width);
-            meta->setInt32(kKeyThumbnailHeight, thumbnail.height);
-            meta->setData(kKeyThumbnailHVCC, kTypeHVCC,
-                    thumbnail.hvcc->data(), thumbnail.hvcc->size());
-            ALOGV("image[%u]: thumbnail: size %dx%d, item index %zd",
-                    imageIndex, thumbnail.width, thumbnail.height, thumbItemIndex);
+            if (thumbnail.hvcc != NULL) {
+                AMediaFormat_setInt32(meta,
+                        AMEDIAFORMAT_KEY_THUMBNAIL_WIDTH, thumbnail.width);
+                AMediaFormat_setInt32(meta,
+                        AMEDIAFORMAT_KEY_THUMBNAIL_HEIGHT, thumbnail.height);
+                AMediaFormat_setBuffer(meta,
+                        AMEDIAFORMAT_KEY_THUMBNAIL_CSD_HEVC,
+                        thumbnail.hvcc->data(), thumbnail.hvcc->size());
+                ALOGV("image[%u]: thumbnail: size %dx%d, item index %zd",
+                        imageIndex, thumbnail.width, thumbnail.height, thumbItemIndex);
+            } else {
+                ALOGW("%s: thumbnail data is missing for image[%u]!", __FUNCTION__, imageIndex);
+            }
         } else {
             ALOGW("%s: Referenced thumbnail does not exist!", __FUNCTION__);
         }
     }
 
     if (image->isGrid()) {
-        meta->setInt32(kKeyGridRows, image->rows);
-        meta->setInt32(kKeyGridCols, image->columns);
-
+        AMediaFormat_setInt32(meta,
+                AMEDIAFORMAT_KEY_GRID_ROWS, image->rows);
+        AMediaFormat_setInt32(meta,
+                AMEDIAFORMAT_KEY_GRID_COLUMNS, image->columns);
         // point image to the first tile for grid size and HVCC
         image = &mItemIdToItemMap.editValueAt(tileItemIndex);
-        meta->setInt32(kKeyTileWidth, image->width);
-        meta->setInt32(kKeyTileHeight, image->height);
-        meta->setInt32(kKeyMaxInputSize, image->width * image->height * 1.5);
+        AMediaFormat_setInt32(meta,
+                AMEDIAFORMAT_KEY_TILE_WIDTH, image->width);
+        AMediaFormat_setInt32(meta,
+                AMEDIAFORMAT_KEY_TILE_HEIGHT, image->height);
+        AMediaFormat_setInt32(meta,
+                AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, image->width * image->height * 1.5);
     }
 
     if (image->hvcc == NULL) {
         ALOGE("%s: hvcc is missing for image[%u]!", __FUNCTION__, imageIndex);
         return NULL;
     }
-    meta->setData(kKeyHVCC, kTypeHVCC, image->hvcc->data(), image->hvcc->size());
+    AMediaFormat_setBuffer(meta,
+            AMEDIAFORMAT_KEY_CSD_HEVC, image->hvcc->data(), image->hvcc->size());
 
     if (image->icc != NULL) {
-        meta->setData(kKeyIccProfile, 0, image->icc->data(), image->icc->size());
+        AMediaFormat_setBuffer(meta,
+                AMEDIAFORMAT_KEY_ICC_PROFILE, image->icc->data(), image->icc->size());
     }
     return meta;
 }
@@ -1671,8 +1687,31 @@
     }
 
     // skip the first 4-byte of the offset to TIFF header
-    *offset = mItemIdToExifMap[exifIndex].offset + 4;
-    *size = mItemIdToExifMap[exifIndex].size - 4;
+    uint32_t tiffOffset;
+    if (!mDataSource->readAt(
+            mItemIdToExifMap[exifIndex].offset, &tiffOffset, 4)) {
+        return ERROR_IO;
+    }
+
+    // We need 'Exif\0\0' before the tiff header
+    tiffOffset = ntohl(tiffOffset);
+    if (tiffOffset < 6) {
+        return ERROR_MALFORMED;
+    }
+    // The first 4-byte of the item is the offset of the tiff header within the
+    // exif data. The size of the item should be > 4 for a non-empty exif (this
+    // was already checked when the item was added). Also check that the tiff
+    // header offset is valid.
+    if (mItemIdToExifMap[exifIndex].size <= 4 ||
+            tiffOffset > mItemIdToExifMap[exifIndex].size - 4) {
+        return ERROR_MALFORMED;
+    }
+
+    // Offset of 'Exif\0\0' relative to the beginning of 'Exif' item
+    // (first 4-byte is the tiff header offset)
+    uint32_t exifOffset = 4 + tiffOffset - 6;
+    *offset = mItemIdToExifMap[exifIndex].offset + exifOffset;
+    *size = mItemIdToExifMap[exifIndex].size - exifOffset;
     return OK;
 }
 
diff --git a/media/extractors/mp4/ItemTable.h b/media/extractors/mp4/ItemTable.h
index 536dcb0..be81b59 100644
--- a/media/extractors/mp4/ItemTable.h
+++ b/media/extractors/mp4/ItemTable.h
@@ -19,13 +19,15 @@
 
 #include <set>
 
+#include <media/NdkMediaFormat.h>
+
 #include <media/stagefright/foundation/ADebug.h>
 #include <utils/KeyedVector.h>
 #include <utils/RefBase.h>
 
 namespace android {
 
-class DataSourceBase;
+class DataSourceHelper;
 class MetaData;
 
 namespace heif {
@@ -45,13 +47,13 @@
 
 class ItemTable : public RefBase {
 public:
-    explicit ItemTable(DataSourceBase *source);
+    explicit ItemTable(DataSourceHelper *source);
 
     status_t parse(uint32_t type, off64_t offset, size_t size);
 
     bool isValid() { return mImageItemsValid; }
     uint32_t countImages() const;
-    sp<MetaData> getImageMeta(const uint32_t imageIndex);
+    AMediaFormat *getImageMeta(const uint32_t imageIndex);
     status_t findImageItem(const uint32_t imageIndex, uint32_t *itemIndex);
     status_t findThumbnailItem(const uint32_t imageIndex, uint32_t *itemIndex);
     status_t getImageOffsetAndSize(
@@ -62,7 +64,7 @@
     ~ItemTable();
 
 private:
-    DataSourceBase *mDataSource;
+    DataSourceHelper *mDataSource;
 
     KeyedVector<uint32_t, ItemLoc> mItemLocs;
     Vector<ItemInfo> mItemInfos;
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
old mode 100644
new mode 100755
index 7b3b81d..9d5890c
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -24,28 +24,31 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <log/log.h>
 #include <utils/Log.h>
 
+#include "AC4Parser.h"
 #include "MPEG4Extractor.h"
 #include "SampleTable.h"
 #include "ItemTable.h"
 #include "include/ESDS.h"
 
+#include <media/DataSourceBase.h>
 #include <media/ExtractorUtils.h>
-#include <media/MediaTrack.h>
 #include <media/stagefright/foundation/ABitReader.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/AudioPresentationInfo.h>
 #include <media/stagefright/foundation/AUtils.h>
 #include <media/stagefright/foundation/ByteUtils.h>
 #include <media/stagefright/foundation/ColorUtils.h>
 #include <media/stagefright/foundation/avc_utils.h>
 #include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/MediaBufferBase.h>
+#include <media/stagefright/foundation/OpusHeader.h>
 #include <media/stagefright/MediaBufferGroup.h>
 #include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MetaData.h>
+#include <media/stagefright/MetaDataBase.h>
 #include <utils/String8.h>
 
 #include <byteswap.h>
@@ -55,6 +58,8 @@
 #define UINT32_MAX       (4294967295U)
 #endif
 
+#define ALAC_SPECIFIC_INFO_SIZE (36)
+
 namespace android {
 
 enum {
@@ -66,35 +71,38 @@
     kMaxAtomSize = 64 * 1024 * 1024,
 };
 
-class MPEG4Source : public MediaTrack {
+class MPEG4Source : public MediaTrackHelper {
+static const size_t  kMaxPcmFrameSize = 8192;
 public:
     // Caller retains ownership of both "dataSource" and "sampleTable".
-    MPEG4Source(MetaDataBase &format,
-                DataSourceBase *dataSource,
+    MPEG4Source(AMediaFormat *format,
+                DataSourceHelper *dataSource,
                 int32_t timeScale,
                 const sp<SampleTable> &sampleTable,
                 Vector<SidxEntry> &sidx,
                 const Trex *trex,
                 off64_t firstMoofOffset,
-                const sp<ItemTable> &itemTable);
+                const sp<ItemTable> &itemTable,
+                uint64_t elstShiftStartTicks);
     virtual status_t init();
 
-    virtual status_t start(MetaDataBase *params = NULL);
-    virtual status_t stop();
+    virtual media_status_t start();
+    virtual media_status_t stop();
 
-    virtual status_t getFormat(MetaDataBase &);
+    virtual media_status_t getFormat(AMediaFormat *);
 
-    virtual status_t read(MediaBufferBase **buffer, const ReadOptions *options = NULL);
-    virtual bool supportNonblockingRead() { return true; }
-    virtual status_t fragmentedRead(MediaBufferBase **buffer, const ReadOptions *options = NULL);
+    virtual media_status_t read(MediaBufferHelper **buffer, const ReadOptions *options = NULL);
+    bool supportsNonBlockingRead() override { return true; }
+    virtual media_status_t fragmentedRead(
+            MediaBufferHelper **buffer, const ReadOptions *options = NULL);
 
     virtual ~MPEG4Source();
 
 private:
     Mutex mLock;
 
-    MetaDataBase &mFormat;
-    DataSourceBase *mDataSource;
+    AMediaFormat *mFormat;
+    DataSourceHelper *mDataSource;
     int32_t mTimescale;
     sp<SampleTable> mSampleTable;
     uint32_t mCurrentSampleIndex;
@@ -104,7 +112,7 @@
     off64_t mFirstMoofOffset;
     off64_t mCurrentMoofOffset;
     off64_t mNextMoofOffset;
-    uint32_t mCurrentTime;
+    uint32_t mCurrentTime; // in media timescale ticks
     int32_t mLastParsedTrackId;
     int32_t mTrackId;
 
@@ -125,21 +133,24 @@
 
     bool mIsAVC;
     bool mIsHEVC;
+    bool mIsAC4;
+    bool mIsPcm;
     size_t mNALLengthSize;
 
     bool mStarted;
 
-    MediaBufferGroup *mGroup;
-
-    MediaBufferBase *mBuffer;
-
-    bool mWantsNALFragments;
+    MediaBufferHelper *mBuffer;
 
     uint8_t *mSrcBuffer;
 
     bool mIsHeif;
+    bool mIsAudio;
     sp<ItemTable> mItemTable;
 
+    // Start offset from composition time to presentation time.
+    // Support shift only for video tracks through mElstShiftStartTicks for now.
+    uint64_t mElstShiftStartTicks;
+
     size_t parseNALSize(const uint8_t *data) const;
     status_t parseChunk(off64_t *offset);
     status_t parseTrackFragmentHeader(off64_t offset, off64_t size);
@@ -148,6 +159,8 @@
     status_t parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size);
     status_t parseClearEncryptedSizes(off64_t offset, bool isSubsampleEncryption, uint32_t flags);
     status_t parseSampleEncryption(off64_t offset);
+    // returns -1 for invalid layer ID
+    int32_t parseHEVCLayerId(const uint8_t *data, size_t size);
 
     struct TrackFragmentHeaderInfo {
         enum Flags {
@@ -193,14 +206,14 @@
 // possibly wrapping multiple times to cover all tracks, i.e.
 // Each CachedRangedDataSource caches the sampletable metadata for a single track.
 
-struct CachedRangedDataSource : public DataSourceBase {
-    explicit CachedRangedDataSource(DataSourceBase *source);
+class CachedRangedDataSource : public DataSourceHelper {
+public:
+    explicit CachedRangedDataSource(DataSourceHelper *source);
     virtual ~CachedRangedDataSource();
 
-    virtual status_t initCheck() const;
-    virtual ssize_t readAt(off64_t offset, void *data, size_t size);
-    virtual status_t getSize(off64_t *size);
-    virtual uint32_t flags();
+    ssize_t readAt(off64_t offset, void *data, size_t size) override;
+    status_t getSize(off64_t *size) override;
+    uint32_t flags() override;
 
     status_t setCachedRange(off64_t offset, size_t size, bool assumeSourceOwnershipOnSuccess);
 
@@ -208,7 +221,7 @@
 private:
     Mutex mLock;
 
-    DataSourceBase *mSource;
+    DataSourceHelper *mSource;
     bool mOwnsDataSource;
     off64_t mCachedOffset;
     size_t mCachedSize;
@@ -220,8 +233,9 @@
     CachedRangedDataSource &operator=(const CachedRangedDataSource &);
 };
 
-CachedRangedDataSource::CachedRangedDataSource(DataSourceBase *source)
-    : mSource(source),
+CachedRangedDataSource::CachedRangedDataSource(DataSourceHelper *source)
+    : DataSourceHelper(source),
+      mSource(source),
       mOwnsDataSource(false),
       mCachedOffset(0),
       mCachedSize(0),
@@ -231,7 +245,7 @@
 CachedRangedDataSource::~CachedRangedDataSource() {
     clearCache();
     if (mOwnsDataSource) {
-        delete (CachedRangedDataSource*)mSource;
+        delete mSource;
     }
 }
 
@@ -245,10 +259,6 @@
     mCachedSize = 0;
 }
 
-status_t CachedRangedDataSource::initCheck() const {
-    return mSource->initCheck();
-}
-
 ssize_t CachedRangedDataSource::readAt(off64_t offset, void *data, size_t size) {
     Mutex::Autolock autoLock(mLock);
 
@@ -301,29 +311,49 @@
 
 static const char *FourCC2MIME(uint32_t fourcc) {
     switch (fourcc) {
-        case FOURCC('m', 'p', '4', 'a'):
+        case FOURCC("mp4a"):
             return MEDIA_MIMETYPE_AUDIO_AAC;
 
-        case FOURCC('s', 'a', 'm', 'r'):
+        case FOURCC("samr"):
             return MEDIA_MIMETYPE_AUDIO_AMR_NB;
 
-        case FOURCC('s', 'a', 'w', 'b'):
+        case FOURCC("sawb"):
             return MEDIA_MIMETYPE_AUDIO_AMR_WB;
 
-        case FOURCC('m', 'p', '4', 'v'):
+        case FOURCC("ec-3"):
+            return MEDIA_MIMETYPE_AUDIO_EAC3;
+
+        case FOURCC("mp4v"):
             return MEDIA_MIMETYPE_VIDEO_MPEG4;
 
-        case FOURCC('s', '2', '6', '3'):
-        case FOURCC('h', '2', '6', '3'):
-        case FOURCC('H', '2', '6', '3'):
+        case FOURCC("s263"):
+        case FOURCC("h263"):
+        case FOURCC("H263"):
             return MEDIA_MIMETYPE_VIDEO_H263;
 
-        case FOURCC('a', 'v', 'c', '1'):
+        case FOURCC("avc1"):
             return MEDIA_MIMETYPE_VIDEO_AVC;
 
-        case FOURCC('h', 'v', 'c', '1'):
-        case FOURCC('h', 'e', 'v', '1'):
+        case FOURCC("hvc1"):
+        case FOURCC("hev1"):
             return MEDIA_MIMETYPE_VIDEO_HEVC;
+        case FOURCC("ac-4"):
+            return MEDIA_MIMETYPE_AUDIO_AC4;
+        case FOURCC("Opus"):
+            return MEDIA_MIMETYPE_AUDIO_OPUS;
+
+        case FOURCC("twos"):
+        case FOURCC("sowt"):
+            return MEDIA_MIMETYPE_AUDIO_RAW;
+        case FOURCC("alac"):
+            return MEDIA_MIMETYPE_AUDIO_ALAC;
+        case FOURCC("fLaC"):
+            return MEDIA_MIMETYPE_AUDIO_FLAC;
+        case FOURCC("av01"):
+            return MEDIA_MIMETYPE_VIDEO_AV1;
+        case FOURCC(".mp3"):
+        case 0x6D730055: // "ms U" mp3 audio
+            return MEDIA_MIMETYPE_AUDIO_MPEG;
         default:
             ALOGW("Unknown fourcc: %c%c%c%c",
                    (fourcc >> 24) & 0xff,
@@ -350,12 +380,11 @@
     return false;
 }
 
-MPEG4Extractor::MPEG4Extractor(DataSourceBase *source, const char *mime)
+MPEG4Extractor::MPEG4Extractor(DataSourceHelper *source, const char *mime)
     : mMoofOffset(0),
       mMoofFound(false),
       mMdatFound(false),
       mDataSource(source),
-      mCachedSource(NULL),
       mInitCheck(NO_INIT),
       mHeaderTimescale(0),
       mIsQT(false),
@@ -365,6 +394,7 @@
       mFirstTrack(NULL),
       mLastTrack(NULL) {
     ALOGV("mime=%s, mPreferHeif=%d", mime, mPreferHeif);
+    mFileMetaData = AMediaFormat_new();
 }
 
 MPEG4Extractor::~MPEG4Extractor() {
@@ -382,7 +412,8 @@
     }
     mPssh.clear();
 
-    delete mCachedSource;
+    delete mDataSource;
+    AMediaFormat_delete(mFileMetaData);
 }
 
 uint32_t MPEG4Extractor::flags() const {
@@ -391,13 +422,13 @@
                     (CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK) : 0);
 }
 
-status_t MPEG4Extractor::getMetaData(MetaDataBase &meta) {
+media_status_t MPEG4Extractor::getMetaData(AMediaFormat *meta) {
     status_t err;
     if ((err = readMetaData()) != OK) {
-        return UNKNOWN_ERROR;
+        return AMEDIA_ERROR_UNKNOWN;
     }
-    meta = mFileMetaData;
-    return OK;
+    AMediaFormat_copy(meta, mFileMetaData);
+    return AMEDIA_OK;
 }
 
 size_t MPEG4Extractor::countTracks() {
@@ -418,18 +449,18 @@
     return n;
 }
 
-status_t MPEG4Extractor::getTrackMetaData(
-        MetaDataBase &meta,
+media_status_t MPEG4Extractor::getTrackMetaData(
+        AMediaFormat *meta,
         size_t index, uint32_t flags) {
     status_t err;
     if ((err = readMetaData()) != OK) {
-        return UNKNOWN_ERROR;
+        return AMEDIA_ERROR_UNKNOWN;
     }
 
     Track *track = mFirstTrack;
     while (index > 0) {
         if (track == NULL) {
-            return UNKNOWN_ERROR;
+            return AMEDIA_ERROR_UNKNOWN;
         }
 
         track = track->next;
@@ -437,16 +468,18 @@
     }
 
     if (track == NULL) {
-        return UNKNOWN_ERROR;
+        return AMEDIA_ERROR_UNKNOWN;
     }
 
     [=] {
         int64_t duration;
         int32_t samplerate;
+        // Only for audio track.
         if (track->has_elst && mHeaderTimescale != 0 &&
-                track->meta.findInt64(kKeyDuration, &duration) &&
-                track->meta.findInt32(kKeySampleRate, &samplerate)) {
+                AMediaFormat_getInt64(track->meta, AMEDIAFORMAT_KEY_DURATION, &duration) &&
+                AMediaFormat_getInt32(track->meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, &samplerate)) {
 
+            // Elst has to be processed only the first time this function is called.
             track->has_elst = false;
 
             if (track->elst_segment_duration > INT64_MAX) {
@@ -454,65 +487,84 @@
             }
             int64_t segment_duration = track->elst_segment_duration;
             int64_t media_time = track->elst_media_time;
-            int64_t halfscale = mHeaderTimescale / 2;
-            ALOGV("segment_duration = %" PRId64 ", media_time = %" PRId64
-                  ", halfscale = %" PRId64 ", timescale = %d",
-                  segment_duration,
-                  media_time,
-                  halfscale,
-                  mHeaderTimescale);
+            int64_t halfscale = track->timescale / 2;
 
-            int64_t delay;
-            // delay = ((media_time * samplerate) + halfscale) / mHeaderTimescale;
-            if (__builtin_mul_overflow(media_time, samplerate, &delay) ||
-                    __builtin_add_overflow(delay, halfscale, &delay) ||
-                    (delay /= mHeaderTimescale, false) ||
-                    delay > INT32_MAX ||
-                    delay < INT32_MIN) {
-                return;
+            ALOGV("segment_duration = %" PRId64 ", media_time = %" PRId64
+                  ", halfscale = %" PRId64 ", mdhd_timescale = %d, track_timescale = %u",
+                  segment_duration, media_time,
+                  halfscale, mHeaderTimescale, track->timescale);
+
+            if ((uint32_t)samplerate != track->timescale){
+                ALOGV("samplerate:%" PRId32 ", track->timescale and samplerate are different!",
+                    samplerate);
+            }
+            // Both delay and paddingsamples have to be set inorder for either to be
+            // effective in the lower layers.
+            int64_t delay = 0;
+            if (media_time > 0) { // Gapless playback
+                // delay = ((media_time * samplerate) + halfscale) / track->timescale;
+                if (__builtin_mul_overflow(media_time, samplerate, &delay) ||
+                        __builtin_add_overflow(delay, halfscale, &delay) ||
+                        (delay /= track->timescale, false) ||
+                        delay > INT32_MAX ||
+                        delay < INT32_MIN) {
+                    ALOGW("ignoring edit list with bogus values");
+                    return;
+                }
             }
             ALOGV("delay = %" PRId64, delay);
-            track->meta.setInt32(kKeyEncoderDelay, delay);
+            AMediaFormat_setInt32(track->meta, AMEDIAFORMAT_KEY_ENCODER_DELAY, delay);
 
-            int64_t scaled_duration;
-            // scaled_duration = duration * mHeaderTimescale;
-            if (__builtin_mul_overflow(duration, mHeaderTimescale, &scaled_duration)) {
-                return;
-            }
-            ALOGV("scaled_duration = %" PRId64, scaled_duration);
+            int64_t paddingsamples = 0;
+            if (segment_duration > 0) {
+                int64_t scaled_duration;
+                // scaled_duration = duration * mHeaderTimescale;
+                if (__builtin_mul_overflow(duration, mHeaderTimescale, &scaled_duration)) {
+                    return;
+                }
+                ALOGV("scaled_duration = %" PRId64, scaled_duration);
 
-            int64_t segment_end;
-            int64_t padding;
-            // padding = scaled_duration - ((segment_duration + media_time) * 1000000);
-            if (__builtin_add_overflow(segment_duration, media_time, &segment_end) ||
-                    __builtin_mul_overflow(segment_end, 1000000, &segment_end) ||
-                    __builtin_sub_overflow(scaled_duration, segment_end, &padding)) {
-                return;
-            }
-            ALOGV("segment_end = %" PRId64 ", padding = %" PRId64, segment_end, padding);
-
-            if (padding < 0) {
-                // track duration from media header (which is what kKeyDuration is) might
-                // be slightly shorter than the segment duration, which would make the
+                int64_t segment_end;
+                int64_t padding;
+                int64_t segment_duration_e6;
+                int64_t media_time_scaled_e6;
+                int64_t media_time_scaled;
+                // padding = scaled_duration - ((segment_duration * 1000000) +
+                //                  ((media_time * mHeaderTimescale * 1000000)/track->timescale) )
+                // segment_duration is based on timescale in movie header box(mdhd)
+                // media_time is based on timescale track header/media timescale
+                if (__builtin_mul_overflow(segment_duration, 1000000, &segment_duration_e6) ||
+                    __builtin_mul_overflow(media_time, mHeaderTimescale, &media_time_scaled) ||
+                    __builtin_mul_overflow(media_time_scaled, 1000000, &media_time_scaled_e6)) {
+                    return;
+                }
+                media_time_scaled_e6 /= track->timescale;
+                if (__builtin_add_overflow(segment_duration_e6, media_time_scaled_e6, &segment_end)
+                    || __builtin_sub_overflow(scaled_duration, segment_end, &padding)) {
+                    return;
+                }
+                ALOGV("segment_end = %" PRId64 ", padding = %" PRId64, segment_end, padding);
+                // track duration from media header (which is what AMEDIAFORMAT_KEY_DURATION is)
+                // might be slightly shorter than the segment duration, which would make the
                 // padding negative. Clamp to zero.
-                padding = 0;
-            }
-
-            int64_t paddingsamples;
-            int64_t halfscale_e6;
-            int64_t timescale_e6;
-            // paddingsamples = ((padding * samplerate) + (halfscale * 1000000))
-            //                / (mHeaderTimescale * 1000000);
-            if (__builtin_mul_overflow(padding, samplerate, &paddingsamples) ||
-                    __builtin_mul_overflow(halfscale, 1000000, &halfscale_e6) ||
-                    __builtin_mul_overflow(mHeaderTimescale, 1000000, &timescale_e6) ||
-                    __builtin_add_overflow(paddingsamples, halfscale_e6, &paddingsamples) ||
-                    (paddingsamples /= timescale_e6, false) ||
-                    paddingsamples > INT32_MAX) {
-                return;
+                if (padding > 0) {
+                    int64_t halfscale_mht = mHeaderTimescale / 2;
+                    int64_t halfscale_e6;
+                    int64_t timescale_e6;
+                    // paddingsamples = ((padding * samplerate) + (halfscale_mht * 1000000))
+                    //                / (mHeaderTimescale * 1000000);
+                    if (__builtin_mul_overflow(padding, samplerate, &paddingsamples) ||
+                            __builtin_mul_overflow(halfscale_mht, 1000000, &halfscale_e6) ||
+                            __builtin_mul_overflow(mHeaderTimescale, 1000000, &timescale_e6) ||
+                            __builtin_add_overflow(paddingsamples, halfscale_e6, &paddingsamples) ||
+                            (paddingsamples /= timescale_e6, false) ||
+                            paddingsamples > INT32_MAX) {
+                        return;
+                    }
+                }
             }
             ALOGV("paddingsamples = %" PRId64, paddingsamples);
-            track->meta.setInt32(kKeyEncoderPadding, paddingsamples);
+            AMediaFormat_setInt32(track->meta, AMEDIAFORMAT_KEY_ENCODER_PADDING, paddingsamples);
         }
     }();
 
@@ -521,7 +573,7 @@
         track->includes_expensive_metadata = true;
 
         const char *mime;
-        CHECK(track->meta.findCString(kKeyMIMEType, &mime));
+        CHECK(AMediaFormat_getString(track->meta, AMEDIAFORMAT_KEY_MIME, &mime));
         if (!strncasecmp("video/", mime, 6)) {
             // MPEG2 tracks do not provide CSD, so read the stream header
             if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)) {
@@ -534,36 +586,38 @@
                     }
                     uint8_t header[kMaxTrackHeaderSize];
                     if (mDataSource->readAt(offset, &header, size) == (ssize_t)size) {
-                        track->meta.setData(kKeyStreamHeader, 'mdat', header, size);
+                        AMediaFormat_setBuffer(track->meta,
+                                AMEDIAFORMAT_KEY_MPEG2_STREAM_HEADER, header, size);
                     }
                 }
             }
 
             if (mMoofOffset > 0) {
                 int64_t duration;
-                if (track->meta.findInt64(kKeyDuration, &duration)) {
+                if (AMediaFormat_getInt64(track->meta,
+                        AMEDIAFORMAT_KEY_DURATION, &duration)) {
                     // nothing fancy, just pick a frame near 1/4th of the duration
-                    track->meta.setInt64(
-                            kKeyThumbnailTime, duration / 4);
+                    AMediaFormat_setInt64(track->meta,
+                            AMEDIAFORMAT_KEY_THUMBNAIL_TIME, duration / 4);
                 }
             } else {
                 uint32_t sampleIndex;
-                uint32_t sampleTime;
+                uint64_t sampleTime;
                 if (track->timescale != 0 &&
                         track->sampleTable->findThumbnailSample(&sampleIndex) == OK
                         && track->sampleTable->getMetaDataForSample(
                             sampleIndex, NULL /* offset */, NULL /* size */,
                             &sampleTime) == OK) {
-                    track->meta.setInt64(
-                            kKeyThumbnailTime,
-                            ((int64_t)sampleTime * 1000000) / track->timescale);
+                        AMediaFormat_setInt64(track->meta,
+                                AMEDIAFORMAT_KEY_THUMBNAIL_TIME,
+                                ((int64_t)sampleTime * 1000000) / track->timescale);
                 }
             }
         }
     }
 
-    meta = track->meta;
-    return OK;
+    AMediaFormat_copy(meta, track->meta);
+    return AMEDIA_OK;
 }
 
 status_t MPEG4Extractor::readMetaData() {
@@ -598,12 +652,14 @@
         off64_t exifOffset;
         size_t exifSize;
         if (mItemTable->getExifOffsetAndSize(&exifOffset, &exifSize) == OK) {
-            mFileMetaData.setInt64(kKeyExifOffset, (int64_t)exifOffset);
-            mFileMetaData.setInt64(kKeyExifSize, (int64_t)exifSize);
+            AMediaFormat_setInt64(mFileMetaData,
+                    AMEDIAFORMAT_KEY_EXIF_OFFSET, (int64_t)exifOffset);
+            AMediaFormat_setInt64(mFileMetaData,
+                    AMEDIAFORMAT_KEY_EXIF_SIZE, (int64_t)exifSize);
         }
         for (uint32_t imageIndex = 0;
                 imageIndex < mItemTable->countImages(); imageIndex++) {
-            sp<MetaData> meta = mItemTable->getImageMeta(imageIndex);
+            AMediaFormat *meta = mItemTable->getImageMeta(imageIndex);
             if (meta == NULL) {
                 ALOGE("heif image %u has no meta!", imageIndex);
                 continue;
@@ -620,7 +676,6 @@
 
             ALOGV("adding HEIF image track %u", imageIndex);
             Track *track = new Track;
-            track->next = NULL;
             if (mLastTrack != NULL) {
                 mLastTrack->next = track;
             } else {
@@ -628,26 +683,26 @@
             }
             mLastTrack = track;
 
-            track->meta = *(meta.get());
-            track->meta.setInt32(kKeyTrackID, imageIndex);
-            track->includes_expensive_metadata = false;
-            track->skipTrack = false;
+            track->meta = meta;
+            AMediaFormat_setInt32(track->meta, AMEDIAFORMAT_KEY_TRACK_ID, imageIndex);
             track->timescale = 1000000;
         }
     }
 
     if (mInitCheck == OK) {
         if (findTrackByMimePrefix("video/") != NULL) {
-            mFileMetaData.setCString(
-                    kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG4);
+            AMediaFormat_setString(mFileMetaData,
+                    AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_CONTAINER_MPEG4);
         } else if (findTrackByMimePrefix("audio/") != NULL) {
-            mFileMetaData.setCString(kKeyMIMEType, "audio/mp4");
+            AMediaFormat_setString(mFileMetaData,
+                    AMEDIAFORMAT_KEY_MIME, "audio/mp4");
         } else if (findTrackByMimePrefix(
                 MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC) != NULL) {
-            mFileMetaData.setCString(
-                    kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_HEIF);
+            AMediaFormat_setString(mFileMetaData,
+                    AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_CONTAINER_HEIF);
         } else {
-            mFileMetaData.setCString(kKeyMIMEType, "application/octet-stream");
+            AMediaFormat_setString(mFileMetaData,
+                    AMEDIAFORMAT_KEY_MIME, "application/octet-stream");
         }
     } else {
         mInitCheck = err;
@@ -672,7 +727,7 @@
             memcpy(ptr + 20, mPssh[i].data, mPssh[i].datalen);
             ptr += (20 + mPssh[i].datalen);
         }
-        mFileMetaData.setData(kKeyPssh, 'pssh', buf, psshsize);
+        AMediaFormat_setBuffer(mFileMetaData, AMEDIAFORMAT_KEY_PSSH, buf, psshsize);
         free(buf);
     }
 
@@ -698,21 +753,21 @@
 
 static bool underMetaDataPath(const Vector<uint32_t> &path) {
     return path.size() >= 5
-        && path[0] == FOURCC('m', 'o', 'o', 'v')
-        && path[1] == FOURCC('u', 'd', 't', 'a')
-        && path[2] == FOURCC('m', 'e', 't', 'a')
-        && path[3] == FOURCC('i', 'l', 's', 't');
+        && path[0] == FOURCC("moov")
+        && path[1] == FOURCC("udta")
+        && path[2] == FOURCC("meta")
+        && path[3] == FOURCC("ilst");
 }
 
 static bool underQTMetaPath(const Vector<uint32_t> &path, int32_t depth) {
     return path.size() >= 2
-            && path[0] == FOURCC('m', 'o', 'o', 'v')
-            && path[1] == FOURCC('m', 'e', 't', 'a')
+            && path[0] == FOURCC("moov")
+            && path[1] == FOURCC("meta")
             && (depth == 2
             || (depth == 3
-                    && (path[2] == FOURCC('h', 'd', 'l', 'r')
-                    ||  path[2] == FOURCC('i', 'l', 's', 't')
-                    ||  path[2] == FOURCC('k', 'e', 'y', 's'))));
+                    && (path[2] == FOURCC("hdlr")
+                    ||  path[2] == FOURCC("ilst")
+                    ||  path[2] == FOURCC("keys"))));
 }
 
 // Given a time in seconds since Jan 1 1904, produce a human-readable string.
@@ -816,7 +871,7 @@
         ALOGE("b/23540914");
         return ERROR_MALFORMED;
     }
-    if (chunk_type != FOURCC('m', 'd', 'a', 't') && chunk_data_size > kMaxAtomSize) {
+    if (chunk_type != FOURCC("mdat") && chunk_data_size > kMaxAtomSize) {
         char errMsg[100];
         sprintf(errMsg, "%s atom has size %" PRId64, chunk, chunk_data_size);
         ALOGE("%s (b/28615448)", errMsg);
@@ -824,8 +879,8 @@
         return ERROR_MALFORMED;
     }
 
-    if (chunk_type != FOURCC('c', 'p', 'r', 't')
-            && chunk_type != FOURCC('c', 'o', 'v', 'r')
+    if (chunk_type != FOURCC("cprt")
+            && chunk_type != FOURCC("covr")
             && mPath.size() == 5 && underMetaDataPath(mPath)) {
         off64_t stop_offset = *offset + chunk_size;
         *offset = data_offset;
@@ -844,40 +899,40 @@
     }
 
     switch(chunk_type) {
-        case FOURCC('m', 'o', 'o', 'v'):
-        case FOURCC('t', 'r', 'a', 'k'):
-        case FOURCC('m', 'd', 'i', 'a'):
-        case FOURCC('m', 'i', 'n', 'f'):
-        case FOURCC('d', 'i', 'n', 'f'):
-        case FOURCC('s', 't', 'b', 'l'):
-        case FOURCC('m', 'v', 'e', 'x'):
-        case FOURCC('m', 'o', 'o', 'f'):
-        case FOURCC('t', 'r', 'a', 'f'):
-        case FOURCC('m', 'f', 'r', 'a'):
-        case FOURCC('u', 'd', 't', 'a'):
-        case FOURCC('i', 'l', 's', 't'):
-        case FOURCC('s', 'i', 'n', 'f'):
-        case FOURCC('s', 'c', 'h', 'i'):
-        case FOURCC('e', 'd', 't', 's'):
-        case FOURCC('w', 'a', 'v', 'e'):
+        case FOURCC("moov"):
+        case FOURCC("trak"):
+        case FOURCC("mdia"):
+        case FOURCC("minf"):
+        case FOURCC("dinf"):
+        case FOURCC("stbl"):
+        case FOURCC("mvex"):
+        case FOURCC("moof"):
+        case FOURCC("traf"):
+        case FOURCC("mfra"):
+        case FOURCC("udta"):
+        case FOURCC("ilst"):
+        case FOURCC("sinf"):
+        case FOURCC("schi"):
+        case FOURCC("edts"):
+        case FOURCC("wave"):
         {
-            if (chunk_type == FOURCC('m', 'o', 'o', 'v') && depth != 0) {
+            if (chunk_type == FOURCC("moov") && depth != 0) {
                 ALOGE("moov: depth %d", depth);
                 return ERROR_MALFORMED;
             }
 
-            if (chunk_type == FOURCC('m', 'o', 'o', 'v') && mInitCheck == OK) {
+            if (chunk_type == FOURCC("moov") && mInitCheck == OK) {
                 ALOGE("duplicate moov");
                 return ERROR_MALFORMED;
             }
 
-            if (chunk_type == FOURCC('m', 'o', 'o', 'f') && !mMoofFound) {
+            if (chunk_type == FOURCC("moof") && !mMoofFound) {
                 // store the offset of the first segment
                 mMoofFound = true;
                 mMoofOffset = *offset;
             }
 
-            if (chunk_type == FOURCC('s', 't', 'b', 'l')) {
+            if (chunk_type == FOURCC("stbl")) {
                 ALOGV("sampleTable chunk is %" PRIu64 " bytes long.", chunk_size);
 
                 if (mDataSource->flags()
@@ -888,8 +943,8 @@
 
                     if (cachedSource->setCachedRange(
                             *offset, chunk_size,
-                            mCachedSource != NULL /* assume ownership on success */) == OK) {
-                        mDataSource = mCachedSource = cachedSource;
+                            true /* assume ownership on success */) == OK) {
+                        mDataSource = cachedSource;
                     } else {
                         delete cachedSource;
                     }
@@ -903,7 +958,7 @@
             }
 
             bool isTrack = false;
-            if (chunk_type == FOURCC('t', 'r', 'a', 'k')) {
+            if (chunk_type == FOURCC("trak")) {
                 if (depth != 1) {
                     ALOGE("trak: depth %d", depth);
                     return ERROR_MALFORMED;
@@ -912,7 +967,6 @@
 
                 ALOGV("adding new track");
                 Track *track = new Track;
-                track->next = NULL;
                 if (mLastTrack) {
                     mLastTrack->next = track;
                 } else {
@@ -920,17 +974,30 @@
                 }
                 mLastTrack = track;
 
-                track->includes_expensive_metadata = false;
-                track->skipTrack = false;
-                track->timescale = 0;
-                track->meta.setCString(kKeyMIMEType, "application/octet-stream");
-                track->has_elst = false;
-                track->subsample_encryption = false;
+                track->meta = AMediaFormat_new();
+                AMediaFormat_setString(track->meta,
+                        AMEDIAFORMAT_KEY_MIME, "application/octet-stream");
             }
 
             off64_t stop_offset = *offset + chunk_size;
             *offset = data_offset;
             while (*offset < stop_offset) {
+
+                // pass udata terminate
+                if (mIsQT && stop_offset - *offset == 4 && chunk_type == FOURCC("udta")) {
+                    // handle the case that udta terminates with terminate code x00000000
+                    // note that 0 terminator is optional and we just handle this case.
+                    uint32_t terminate_code = 1;
+                    mDataSource->readAt(*offset, &terminate_code, 4);
+                    if (0 == terminate_code) {
+                        *offset += 4;
+                        ALOGD("Terminal code for udta");
+                        continue;
+                    } else {
+                        ALOGW("invalid udta Terminal code");
+                    }
+                }
+
                 status_t err = parseChunk(offset, depth + 1);
                 if (err != OK) {
                     if (isTrack) {
@@ -947,8 +1014,10 @@
 
             if (isTrack) {
                 int32_t trackId;
-                // There must be exact one track header per track.
-                if (!mLastTrack->meta.findInt32(kKeyTrackID, &trackId)) {
+                // There must be exactly one track header per track.
+
+                if (!AMediaFormat_getInt32(mLastTrack->meta,
+                        AMEDIAFORMAT_KEY_TRACK_ID, &trackId)) {
                     mLastTrack->skipTrack = true;
                 }
 
@@ -957,6 +1026,7 @@
                     mLastTrack->skipTrack = true;
                 }
 
+
                 if (mLastTrack->skipTrack) {
                     ALOGV("skipping this track...");
                     Track *cur = mFirstTrack;
@@ -977,7 +1047,22 @@
 
                     return OK;
                 }
-            } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) {
+
+                // place things we built elsewhere into their final locations
+
+                // put aggregated tx3g data into the metadata
+                if (mLastTrack->mTx3gFilled > 0) {
+                    ALOGV("Putting %zu bytes of tx3g data into meta data",
+                          mLastTrack->mTx3gFilled);
+                    AMediaFormat_setBuffer(mLastTrack->meta,
+                        AMEDIAFORMAT_KEY_TEXT_FORMAT_DATA,
+                        mLastTrack->mTx3gBuffer, mLastTrack->mTx3gFilled);
+                    // drop it now to reduce our footprint
+                    free(mLastTrack->mTx3gBuffer);
+                    mLastTrack->mTx3gBuffer = NULL;
+                }
+
+            } else if (chunk_type == FOURCC("moov")) {
                 mInitCheck = OK;
 
                 return UNKNOWN_ERROR;  // Return a dummy error.
@@ -985,7 +1070,7 @@
             break;
         }
 
-        case FOURCC('s', 'c', 'h', 'm'):
+        case FOURCC("schm"):
         {
 
             *offset += chunk_size;
@@ -1000,23 +1085,23 @@
             scheme_type = ntohl(scheme_type);
             int32_t mode = kCryptoModeUnencrypted;
             switch(scheme_type) {
-                case FOURCC('c', 'b', 'c', '1'):
+                case FOURCC("cbc1"):
                 {
                     mode = kCryptoModeAesCbc;
                     break;
                 }
-                case FOURCC('c', 'b', 'c', 's'):
+                case FOURCC("cbcs"):
                 {
                     mode = kCryptoModeAesCbc;
                     mLastTrack->subsample_encryption = true;
                     break;
                 }
-                case FOURCC('c', 'e', 'n', 'c'):
+                case FOURCC("cenc"):
                 {
                     mode = kCryptoModeAesCtr;
                     break;
                 }
-                case FOURCC('c', 'e', 'n', 's'):
+                case FOURCC("cens"):
                 {
                     mode = kCryptoModeAesCtr;
                     mLastTrack->subsample_encryption = true;
@@ -1024,13 +1109,13 @@
                 }
             }
             if (mode != kCryptoModeUnencrypted) {
-                mLastTrack->meta.setInt32(kKeyCryptoMode, mode);
+                AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_CRYPTO_MODE, mode);
             }
             break;
         }
 
 
-        case FOURCC('e', 'l', 's', 't'):
+        case FOURCC("elst"):
         {
             *offset += chunk_size;
 
@@ -1051,6 +1136,7 @@
 
             if (entry_count != 1) {
                 // we only support a single entry at the moment, for gapless playback
+                // or start offset
                 ALOGW("ignoring edit list with %d entries", entry_count);
             } else {
                 off64_t entriesoffset = data_offset + 8;
@@ -1085,7 +1171,7 @@
             break;
         }
 
-        case FOURCC('f', 'r', 'm', 'a'):
+        case FOURCC("frma"):
         {
             *offset += chunk_size;
 
@@ -1100,17 +1186,31 @@
                 return ERROR_MALFORMED;
             }
 
-            mLastTrack->meta.setCString(kKeyMIMEType, FourCC2MIME(original_fourcc));
+            AMediaFormat_setString(mLastTrack->meta,
+                    AMEDIAFORMAT_KEY_MIME, FourCC2MIME(original_fourcc));
             uint32_t num_channels = 0;
             uint32_t sample_rate = 0;
             if (AdjustChannelsAndRate(original_fourcc, &num_channels, &sample_rate)) {
-                mLastTrack->meta.setInt32(kKeyChannelCount, num_channels);
-                mLastTrack->meta.setInt32(kKeySampleRate, sample_rate);
+                AMediaFormat_setInt32(mLastTrack->meta,
+                        AMEDIAFORMAT_KEY_CHANNEL_COUNT, num_channels);
+                AMediaFormat_setInt32(mLastTrack->meta,
+                        AMEDIAFORMAT_KEY_SAMPLE_RATE, sample_rate);
             }
+
+            if (!mIsQT && original_fourcc == FOURCC("alac")) {
+                off64_t tmpOffset = *offset;
+                status_t err = parseALACSampleEntry(&tmpOffset);
+                if (err != OK) {
+                    ALOGE("parseALACSampleEntry err:%d Line:%d", err, __LINE__);
+                    return err;
+                }
+                *offset = tmpOffset + 8;
+            }
+
             break;
         }
 
-        case FOURCC('t', 'e', 'n', 'c'):
+        case FOURCC("tenc"):
         {
             *offset += chunk_size;
 
@@ -1202,21 +1302,28 @@
             }
 
             int32_t tmpAlgorithmId;
-            if (!mLastTrack->meta.findInt32(kKeyCryptoMode, &tmpAlgorithmId)) {
-                mLastTrack->meta.setInt32(kKeyCryptoMode, defaultAlgorithmId);
+            if (!AMediaFormat_getInt32(mLastTrack->meta,
+                    AMEDIAFORMAT_KEY_CRYPTO_MODE, &tmpAlgorithmId)) {
+                AMediaFormat_setInt32(mLastTrack->meta,
+                        AMEDIAFORMAT_KEY_CRYPTO_MODE, defaultAlgorithmId);
             }
 
-            mLastTrack->meta.setInt32(kKeyCryptoDefaultIVSize, defaultIVSize);
-            mLastTrack->meta.setData(kKeyCryptoKey, 'tenc', defaultKeyId, 16);
-            mLastTrack->meta.setInt32(kKeyEncryptedByteBlock, defaultEncryptedByteBlock);
-            mLastTrack->meta.setInt32(kKeySkipByteBlock, defaultSkipByteBlock);
+            AMediaFormat_setInt32(mLastTrack->meta,
+                    AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE, defaultIVSize);
+            AMediaFormat_setBuffer(mLastTrack->meta,
+                    AMEDIAFORMAT_KEY_CRYPTO_KEY, defaultKeyId, 16);
+            AMediaFormat_setInt32(mLastTrack->meta,
+                    AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK, defaultEncryptedByteBlock);
+            AMediaFormat_setInt32(mLastTrack->meta,
+                    AMEDIAFORMAT_KEY_CRYPTO_SKIP_BYTE_BLOCK, defaultSkipByteBlock);
             if (defaultConstantIv != NULL) {
-                mLastTrack->meta.setData(kKeyCryptoIV, 'dciv', defaultConstantIv->data(), defaultConstantIv->size());
+                AMediaFormat_setBuffer(mLastTrack->meta, AMEDIAFORMAT_KEY_CRYPTO_IV,
+                        defaultConstantIv->data(), defaultConstantIv->size());
             }
             break;
         }
 
-        case FOURCC('t', 'k', 'h', 'd'):
+        case FOURCC("tkhd"):
         {
             *offset += chunk_size;
 
@@ -1228,7 +1335,7 @@
             break;
         }
 
-        case FOURCC('t', 'r', 'e', 'f'):
+        case FOURCC("tref"):
         {
             off64_t stop_offset = *offset + chunk_size;
             *offset = data_offset;
@@ -1244,7 +1351,7 @@
             break;
         }
 
-        case FOURCC('t', 'h', 'm', 'b'):
+        case FOURCC("thmb"):
         {
             *offset += chunk_size;
 
@@ -1261,7 +1368,7 @@
             break;
         }
 
-        case FOURCC('p', 's', 's', 'h'):
+        case FOURCC("pssh"):
         {
             *offset += chunk_size;
 
@@ -1297,7 +1404,7 @@
             break;
         }
 
-        case FOURCC('m', 'd', 'h', 'd'):
+        case FOURCC("mdhd"):
         {
             *offset += chunk_size;
 
@@ -1360,8 +1467,13 @@
                 }
             }
             if (duration != 0 && mLastTrack->timescale != 0) {
-                mLastTrack->meta.setInt64(
-                        kKeyDuration, (duration * 1000000) / mLastTrack->timescale);
+                long double durationUs = ((long double)duration * 1000000) / mLastTrack->timescale;
+                if (durationUs < 0 || durationUs > INT64_MAX) {
+                    ALOGE("cannot represent %lld * 1000000 / %lld in 64 bits",
+                          (long long) duration, (long long) mLastTrack->timescale);
+                    return ERROR_MALFORMED;
+                }
+                AMediaFormat_setInt64(mLastTrack->meta, AMEDIAFORMAT_KEY_DURATION, durationUs);
             }
 
             uint8_t lang[2];
@@ -1388,13 +1500,12 @@
             lang_code[2] = (lang[1] & 0x1f) + 0x60;
             lang_code[3] = '\0';
 
-            mLastTrack->meta.setCString(
-                    kKeyMediaLanguage, lang_code);
+            AMediaFormat_setString(mLastTrack->meta, AMEDIAFORMAT_KEY_LANGUAGE, lang_code);
 
             break;
         }
 
-        case FOURCC('s', 't', 's', 'd'):
+        case FOURCC("stsd"):
         {
             uint8_t buffer[8];
             if (chunk_data_size < (off64_t)sizeof(buffer)) {
@@ -1423,7 +1534,7 @@
                 if (mLastTrack == NULL)
                     return ERROR_MALFORMED;
 
-                CHECK(mLastTrack->meta.findCString(kKeyMIMEType, &mime));
+                CHECK(AMediaFormat_getString(mLastTrack->meta, AMEDIAFORMAT_KEY_MIME, &mime));
                 if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) &&
                         strcasecmp(mime, "application/octet-stream")) {
                     // For now we only support a single type of media per track.
@@ -1446,7 +1557,7 @@
             }
             break;
         }
-        case FOURCC('m', 'e', 't', 't'):
+        case FOURCC("mett"):
         {
             *offset += chunk_size;
 
@@ -1463,20 +1574,68 @@
                 return ERROR_IO;
             }
 
-            String8 mimeFormat((const char *)(buffer.get()), chunk_data_size);
-            mLastTrack->meta.setCString(kKeyMIMEType, mimeFormat.string());
+            // Prior to API 29, the metadata track was not compliant with ISO/IEC
+            // 14496-12-2015. This led to some ISO-compliant parsers failing to read the
+            // metatrack. As of API 29 and onwards, a change was made to metadata track to
+            // make it compliant with the standard. The workaround is to write the
+            // null-terminated mime_format string twice. This allows compliant parsers to
+            // read the missing reserved, data_reference_index, and content_encoding fields
+            // from the first mime_type string. The actual mime_format field would then be
+            // read correctly from the second string. The non-compliant Android frameworks
+            // from API 28 and earlier would still be able to read the mime_format correctly
+            // as it would only read the first null-terminated mime_format string. To enable
+            // reading metadata tracks generated from both the non-compliant and compliant
+            // formats, a check needs to be done to see which format is used.
+            int null_pos = 0;
+            const unsigned char *str = buffer.get();
+            while (null_pos < chunk_data_size) {
+              if (*(str + null_pos) == '\0') {
+                break;
+              }
+              ++null_pos;
+            }
 
+            if (null_pos == chunk_data_size - 1) {
+              // This is not a standard ompliant metadata track.
+              String8 mimeFormat((const char *)(buffer.get()), chunk_data_size);
+              AMediaFormat_setString(mLastTrack->meta,
+                  AMEDIAFORMAT_KEY_MIME, mimeFormat.string());
+            } else {
+              // This is a standard compliant metadata track.
+              String8 contentEncoding((const char *)(buffer.get() + 8));
+              String8 mimeFormat((const char *)(buffer.get() + 8 + contentEncoding.size() + 1),
+                  chunk_data_size - 8 - contentEncoding.size() - 1);
+              AMediaFormat_setString(mLastTrack->meta,
+                  AMEDIAFORMAT_KEY_MIME, mimeFormat.string());
+            }
             break;
         }
 
-        case FOURCC('m', 'p', '4', 'a'):
-        case FOURCC('e', 'n', 'c', 'a'):
-        case FOURCC('s', 'a', 'm', 'r'):
-        case FOURCC('s', 'a', 'w', 'b'):
+        case FOURCC("mp4a"):
+        case FOURCC("enca"):
+        case FOURCC("samr"):
+        case FOURCC("sawb"):
+        case FOURCC("Opus"):
+        case FOURCC("twos"):
+        case FOURCC("sowt"):
+        case FOURCC("alac"):
+        case FOURCC("fLaC"):
+        case FOURCC(".mp3"):
+        case 0x6D730055: // "ms U" mp3 audio
         {
-            if (mIsQT && chunk_type == FOURCC('m', 'p', '4', 'a')
-                    && depth >= 1 && mPath[depth - 1] == FOURCC('w', 'a', 'v', 'e')) {
-                // Ignore mp4a embedded in QT wave atom
+            if (mIsQT && depth >= 1 && mPath[depth - 1] == FOURCC("wave")) {
+
+                if (chunk_type == FOURCC("alac")) {
+                    off64_t offsetTmp = *offset;
+                    status_t err = parseALACSampleEntry(&offsetTmp);
+                    if (err != OK) {
+                        ALOGE("parseALACSampleEntry err:%d Line:%d", err, __LINE__);
+                        return err;
+                    }
+                }
+
+                // Ignore all atoms embedded in QT wave atom
+                ALOGV("Ignore all atoms embedded in QT wave atom");
                 *offset += chunk_size;
                 break;
             }
@@ -1505,7 +1664,7 @@
             off64_t stop_offset = *offset + chunk_size;
             *offset = data_offset + sizeof(buffer);
 
-            if (mIsQT && chunk_type == FOURCC('m', 'p', '4', 'a')) {
+            if (mIsQT) {
                 if (version == 1) {
                     if (mDataSource->readAt(*offset, buffer, 16) < 16) {
                         return ERROR_IO;
@@ -1538,15 +1697,117 @@
                 }
             }
 
-            if (chunk_type != FOURCC('e', 'n', 'c', 'a')) {
+            if (chunk_type != FOURCC("enca")) {
                 // if the chunk type is enca, we'll get the type from the frma box later
-                mLastTrack->meta.setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
+                AMediaFormat_setString(mLastTrack->meta,
+                        AMEDIAFORMAT_KEY_MIME, FourCC2MIME(chunk_type));
                 AdjustChannelsAndRate(chunk_type, &num_channels, &sample_rate);
+
+                if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, FourCC2MIME(chunk_type))) {
+                    AMediaFormat_setInt32(mLastTrack->meta,
+                            AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, sample_size);
+                    if (chunk_type == FOURCC("twos")) {
+                        AMediaFormat_setInt32(mLastTrack->meta,
+                                AMEDIAFORMAT_KEY_PCM_BIG_ENDIAN, 1);
+                    }
+                }
             }
             ALOGV("*** coding='%s' %d channels, size %d, rate %d\n",
                    chunk, num_channels, sample_size, sample_rate);
-            mLastTrack->meta.setInt32(kKeyChannelCount, num_channels);
-            mLastTrack->meta.setInt32(kKeySampleRate, sample_rate);
+            AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, num_channels);
+            AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, sample_rate);
+
+            if (chunk_type == FOURCC("Opus")) {
+                uint8_t opusInfo[AOPUS_OPUSHEAD_MAXSIZE];
+                data_offset += sizeof(buffer);
+                size_t opusInfoSize = chunk_data_size - sizeof(buffer);
+
+                if (opusInfoSize < AOPUS_OPUSHEAD_MINSIZE ||
+                    opusInfoSize > AOPUS_OPUSHEAD_MAXSIZE) {
+                    return ERROR_MALFORMED;
+                }
+                // Read Opus Header
+                if (mDataSource->readAt(
+                        data_offset, opusInfo, opusInfoSize) < opusInfoSize) {
+                    return ERROR_IO;
+                }
+
+                // OpusHeader must start with this magic sequence, overwrite first 8 bytes
+                // http://wiki.xiph.org/OggOpus#ID_Header
+                strncpy((char *)opusInfo, "OpusHead", 8);
+
+                // Version shall be 0 as per mp4 Opus Specific Box
+                // (https://opus-codec.org/docs/opus_in_isobmff.html#4.3.2)
+                if (opusInfo[8]) {
+                    return ERROR_MALFORMED;
+                }
+                // Force version to 1 as per OpusHead definition
+                // (http://wiki.xiph.org/OggOpus#ID_Header)
+                opusInfo[8] = 1;
+
+                // Read Opus Specific Box values
+                size_t opusOffset = 10;
+                uint16_t pre_skip = U16_AT(&opusInfo[opusOffset]);
+                uint32_t sample_rate = U32_AT(&opusInfo[opusOffset + 2]);
+                uint16_t out_gain = U16_AT(&opusInfo[opusOffset + 6]);
+
+                // Convert Opus Specific Box values. ParseOpusHeader expects
+                // the values in LE, however MP4 stores these values as BE
+                // https://opus-codec.org/docs/opus_in_isobmff.html#4.3.2
+                memcpy(&opusInfo[opusOffset], &pre_skip, sizeof(pre_skip));
+                memcpy(&opusInfo[opusOffset + 2], &sample_rate, sizeof(sample_rate));
+                memcpy(&opusInfo[opusOffset + 6], &out_gain, sizeof(out_gain));
+
+                static const int64_t kSeekPreRollNs = 80000000;  // Fixed 80 msec
+                static const int32_t kOpusSampleRate = 48000;
+                int64_t codecDelay = pre_skip * 1000000000ll / kOpusSampleRate;
+
+                AMediaFormat_setBuffer(mLastTrack->meta,
+                            AMEDIAFORMAT_KEY_CSD_0, opusInfo, opusInfoSize);
+                AMediaFormat_setBuffer(mLastTrack->meta,
+                        AMEDIAFORMAT_KEY_CSD_1, &codecDelay, sizeof(codecDelay));
+                AMediaFormat_setBuffer(mLastTrack->meta,
+                        AMEDIAFORMAT_KEY_CSD_2, &kSeekPreRollNs, sizeof(kSeekPreRollNs));
+
+                data_offset += opusInfoSize;
+                *offset = data_offset;
+                CHECK_EQ(*offset, stop_offset);
+            }
+
+            if (!mIsQT && chunk_type == FOURCC("alac")) {
+                data_offset += sizeof(buffer);
+
+                status_t err = parseALACSampleEntry(&data_offset);
+                if (err != OK) {
+                    ALOGE("parseALACSampleEntry err:%d Line:%d", err, __LINE__);
+                    return err;
+                }
+                *offset = data_offset;
+                CHECK_EQ(*offset, stop_offset);
+            }
+
+            if (chunk_type == FOURCC("fLaC")) {
+
+                // From https://github.com/xiph/flac/blob/master/doc/isoflac.txt
+                // 4 for mime, 4 for blockType and BlockLen, 34 for metadata
+                uint8_t flacInfo[4 + 4 + 34];
+                // skipping dFla, version
+                data_offset += sizeof(buffer) + 12;
+                size_t flacOffset = 4;
+                // Add flaC header mime type to CSD
+                strncpy((char *)flacInfo, "fLaC", 4);
+                if (mDataSource->readAt(
+                        data_offset, flacInfo + flacOffset, sizeof(flacInfo) - flacOffset) <
+                        (ssize_t)sizeof(flacInfo) - flacOffset) {
+                    return ERROR_IO;
+                }
+                data_offset += sizeof(flacInfo) - flacOffset;
+
+                AMediaFormat_setBuffer(mLastTrack->meta, AMEDIAFORMAT_KEY_CSD_0, flacInfo,
+                                       sizeof(flacInfo));
+                *offset = data_offset;
+                CHECK_EQ(*offset, stop_offset);
+            }
 
             while (*offset < stop_offset) {
                 status_t err = parseChunk(offset, depth + 1);
@@ -1561,14 +1822,15 @@
             break;
         }
 
-        case FOURCC('m', 'p', '4', 'v'):
-        case FOURCC('e', 'n', 'c', 'v'):
-        case FOURCC('s', '2', '6', '3'):
-        case FOURCC('H', '2', '6', '3'):
-        case FOURCC('h', '2', '6', '3'):
-        case FOURCC('a', 'v', 'c', '1'):
-        case FOURCC('h', 'v', 'c', '1'):
-        case FOURCC('h', 'e', 'v', '1'):
+        case FOURCC("mp4v"):
+        case FOURCC("encv"):
+        case FOURCC("s263"):
+        case FOURCC("H263"):
+        case FOURCC("h263"):
+        case FOURCC("avc1"):
+        case FOURCC("hvc1"):
+        case FOURCC("hev1"):
+        case FOURCC("av01"):
         {
             uint8_t buffer[78];
             if (chunk_data_size < (ssize_t)sizeof(buffer)) {
@@ -1598,12 +1860,13 @@
             if (mLastTrack == NULL)
                 return ERROR_MALFORMED;
 
-            if (chunk_type != FOURCC('e', 'n', 'c', 'v')) {
+            if (chunk_type != FOURCC("encv")) {
                 // if the chunk type is encv, we'll get the type from the frma box later
-                mLastTrack->meta.setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
+                AMediaFormat_setString(mLastTrack->meta,
+                        AMEDIAFORMAT_KEY_MIME, FourCC2MIME(chunk_type));
             }
-            mLastTrack->meta.setInt32(kKeyWidth, width);
-            mLastTrack->meta.setInt32(kKeyHeight, height);
+            AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_WIDTH, width);
+            AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_HEIGHT, height);
 
             off64_t stop_offset = *offset + chunk_size;
             *offset = data_offset + sizeof(buffer);
@@ -1620,8 +1883,8 @@
             break;
         }
 
-        case FOURCC('s', 't', 'c', 'o'):
-        case FOURCC('c', 'o', '6', '4'):
+        case FOURCC("stco"):
+        case FOURCC("co64"):
         {
             if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) {
                 return ERROR_MALFORMED;
@@ -1640,7 +1903,7 @@
             break;
         }
 
-        case FOURCC('s', 't', 's', 'c'):
+        case FOURCC("stsc"):
         {
             if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
                 return ERROR_MALFORMED;
@@ -1658,8 +1921,8 @@
             break;
         }
 
-        case FOURCC('s', 't', 's', 'z'):
-        case FOURCC('s', 't', 'z', '2'):
+        case FOURCC("stsz"):
+        case FOURCC("stz2"):
         {
             if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) {
                 return ERROR_MALFORMED;
@@ -1675,6 +1938,8 @@
                 return err;
             }
 
+            adjustRawDefaultFrameSize();
+
             size_t max_size;
             err = mLastTrack->sampleTable->getMaxSampleSize(&max_size);
 
@@ -1691,12 +1956,15 @@
                     ALOGE("max sample size too big: %zu", max_size);
                     return ERROR_MALFORMED;
                 }
-                mLastTrack->meta.setInt32(kKeyMaxInputSize, max_size + 10 * 2);
+                AMediaFormat_setInt32(mLastTrack->meta,
+                        AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, max_size + 10 * 2);
             } else {
                 // No size was specified. Pick a conservatively large size.
                 uint32_t width, height;
-                if (!mLastTrack->meta.findInt32(kKeyWidth, (int32_t*)&width) ||
-                    !mLastTrack->meta.findInt32(kKeyHeight,(int32_t*) &height)) {
+                if (!AMediaFormat_getInt32(mLastTrack->meta,
+                        AMEDIAFORMAT_KEY_WIDTH, (int32_t*)&width) ||
+                    !AMediaFormat_getInt32(mLastTrack->meta,
+                            AMEDIAFORMAT_KEY_HEIGHT,(int32_t*) &height)) {
                     ALOGE("No width or height, assuming worst case 1080p");
                     width = 1920;
                     height = 1080;
@@ -1711,7 +1979,7 @@
                 }
 
                 const char *mime;
-                CHECK(mLastTrack->meta.findCString(kKeyMIMEType, &mime));
+                CHECK(AMediaFormat_getString(mLastTrack->meta, AMEDIAFORMAT_KEY_MIME, &mime));
                 if (!strncmp(mime, "audio/", 6)) {
                     // for audio, use 128KB
                     max_size = 1024 * 128;
@@ -1728,26 +1996,28 @@
                 // HACK: allow 10% overhead
                 // TODO: read sample size from traf atom for fragmented MPEG4.
                 max_size += max_size / 10;
-                mLastTrack->meta.setInt32(kKeyMaxInputSize, max_size);
+                AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, max_size);
             }
 
             // NOTE: setting another piece of metadata invalidates any pointers (such as the
             // mimetype) previously obtained, so don't cache them.
             const char *mime;
-            CHECK(mLastTrack->meta.findCString(kKeyMIMEType, &mime));
+            CHECK(AMediaFormat_getString(mLastTrack->meta, AMEDIAFORMAT_KEY_MIME, &mime));
             // Calculate average frame rate.
             if (!strncasecmp("video/", mime, 6)) {
                 size_t nSamples = mLastTrack->sampleTable->countSamples();
                 if (nSamples == 0) {
                     int32_t trackId;
-                    if (mLastTrack->meta.findInt32(kKeyTrackID, &trackId)) {
+                    if (AMediaFormat_getInt32(mLastTrack->meta,
+                            AMEDIAFORMAT_KEY_TRACK_ID, &trackId)) {
                         for (size_t i = 0; i < mTrex.size(); i++) {
                             Trex *t = &mTrex.editItemAt(i);
                             if (t->track_ID == (uint32_t) trackId) {
                                 if (t->default_sample_duration > 0) {
                                     int32_t frameRate =
                                             mLastTrack->timescale / t->default_sample_duration;
-                                    mLastTrack->meta.setInt32(kKeyFrameRate, frameRate);
+                                    AMediaFormat_setInt32(mLastTrack->meta,
+                                            AMEDIAFORMAT_KEY_FRAME_RATE, frameRate);
                                 }
                                 break;
                             }
@@ -1755,28 +2025,38 @@
                     }
                 } else {
                     int64_t durationUs;
-                    if (mLastTrack->meta.findInt64(kKeyDuration, &durationUs)) {
+                    if (AMediaFormat_getInt64(mLastTrack->meta,
+                            AMEDIAFORMAT_KEY_DURATION, &durationUs)) {
                         if (durationUs > 0) {
                             int32_t frameRate = (nSamples * 1000000LL +
                                         (durationUs >> 1)) / durationUs;
-                            mLastTrack->meta.setInt32(kKeyFrameRate, frameRate);
+                            AMediaFormat_setInt32(mLastTrack->meta,
+                                    AMEDIAFORMAT_KEY_FRAME_RATE, frameRate);
                         }
                     }
                     ALOGV("setting frame count %zu", nSamples);
-                    mLastTrack->meta.setInt32(kKeyFrameCount, nSamples);
+                    AMediaFormat_setInt32(mLastTrack->meta,
+                            AMEDIAFORMAT_KEY_FRAME_COUNT, nSamples);
                 }
             }
 
             break;
         }
 
-        case FOURCC('s', 't', 't', 's'):
+        case FOURCC("stts"):
         {
             if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
                 return ERROR_MALFORMED;
 
             *offset += chunk_size;
 
+            if (depth >= 1 && mPath[depth - 1] != FOURCC("stbl")) {
+                char chunk[5];
+                MakeFourCCString(mPath[depth - 1], chunk);
+                ALOGW("stts's parent box (%s) is not stbl, skip it.", chunk);
+                break;
+            }
+
             status_t err =
                 mLastTrack->sampleTable->setTimeToSampleParams(
                         data_offset, chunk_data_size);
@@ -1788,7 +2068,7 @@
             break;
         }
 
-        case FOURCC('c', 't', 't', 's'):
+        case FOURCC("ctts"):
         {
             if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
                 return ERROR_MALFORMED;
@@ -1806,7 +2086,7 @@
             break;
         }
 
-        case FOURCC('s', 't', 's', 's'):
+        case FOURCC("stss"):
         {
             if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
                 return ERROR_MALFORMED;
@@ -1825,7 +2105,7 @@
         }
 
         // \xA9xyz
-        case FOURCC(0xA9, 'x', 'y', 'z'):
+        case FOURCC("\251xyz"):
         {
             *offset += chunk_size;
 
@@ -1871,11 +2151,11 @@
             if (buffer[len - 1] != '/') {
                 buffer[len] = '/';
             }
-            mFileMetaData.setCString(kKeyLocation, &buffer[0]);
+            AMediaFormat_setString(mFileMetaData, AMEDIAFORMAT_KEY_LOCATION, &buffer[0]);
             break;
         }
 
-        case FOURCC('e', 's', 'd', 's'):
+        case FOURCC("esds"):
         {
             *offset += chunk_size;
 
@@ -1883,9 +2163,10 @@
                 return ERROR_MALFORMED;
             }
 
-            uint8_t buffer[256];
-            if (chunk_data_size > (off64_t)sizeof(buffer)) {
-                return ERROR_BUFFER_TOO_SMALL;
+            auto tmp = heapbuffer<uint8_t>(chunk_data_size);
+            uint8_t *buffer = tmp.get();
+            if (buffer == NULL) {
+                return -ENOMEM;
             }
 
             if (mDataSource->readAt(
@@ -1901,11 +2182,11 @@
             if (mLastTrack == NULL)
                 return ERROR_MALFORMED;
 
-            mLastTrack->meta.setData(
-                    kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4);
+            AMediaFormat_setBuffer(mLastTrack->meta, 
+                    AMEDIAFORMAT_KEY_ESDS, &buffer[4], chunk_data_size - 4);
 
             if (mPath.size() >= 2
-                    && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) {
+                    && mPath[mPath.size() - 2] == FOURCC("mp4a")) {
                 // Information from the ESDS must be relied on for proper
                 // setup of sample rate and channel count for MPEG4 Audio.
                 // The generic header appears to only contain generic
@@ -1919,21 +2200,22 @@
                 }
             }
             if (mPath.size() >= 2
-                    && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'v')) {
+                    && mPath[mPath.size() - 2] == FOURCC("mp4v")) {
                 // Check if the video is MPEG2
                 ESDS esds(&buffer[4], chunk_data_size - 4);
 
                 uint8_t objectTypeIndication;
                 if (esds.getObjectTypeIndication(&objectTypeIndication) == OK) {
                     if (objectTypeIndication >= 0x60 && objectTypeIndication <= 0x65) {
-                        mLastTrack->meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2);
+                        AMediaFormat_setString(mLastTrack->meta,
+                                AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_MPEG2);
                     }
                 }
             }
             break;
         }
 
-        case FOURCC('b', 't', 'r', 't'):
+        case FOURCC("btrt"):
         {
             *offset += chunk_size;
             if (mLastTrack == NULL) {
@@ -1953,15 +2235,17 @@
             uint32_t maxBitrate = U32_AT(&buffer[4]);
             uint32_t avgBitrate = U32_AT(&buffer[8]);
             if (maxBitrate > 0 && maxBitrate < INT32_MAX) {
-                mLastTrack->meta.setInt32(kKeyMaxBitRate, (int32_t)maxBitrate);
+                AMediaFormat_setInt32(mLastTrack->meta,
+                        AMEDIAFORMAT_KEY_MAX_BIT_RATE, (int32_t)maxBitrate);
             }
             if (avgBitrate > 0 && avgBitrate < INT32_MAX) {
-                mLastTrack->meta.setInt32(kKeyBitRate, (int32_t)avgBitrate);
+                AMediaFormat_setInt32(mLastTrack->meta,
+                        AMEDIAFORMAT_KEY_BIT_RATE, (int32_t)avgBitrate);
             }
             break;
         }
 
-        case FOURCC('a', 'v', 'c', 'C'):
+        case FOURCC("avcC"):
         {
             *offset += chunk_size;
 
@@ -1980,12 +2264,12 @@
             if (mLastTrack == NULL)
                 return ERROR_MALFORMED;
 
-            mLastTrack->meta.setData(
-                    kKeyAVCC, kTypeAVCC, buffer.get(), chunk_data_size);
+            AMediaFormat_setBuffer(mLastTrack->meta, 
+                    AMEDIAFORMAT_KEY_CSD_AVC, buffer.get(), chunk_data_size);
 
             break;
         }
-        case FOURCC('h', 'v', 'c', 'C'):
+        case FOURCC("hvcC"):
         {
             auto buffer = heapbuffer<uint8_t>(chunk_data_size);
 
@@ -2002,14 +2286,36 @@
             if (mLastTrack == NULL)
                 return ERROR_MALFORMED;
 
-            mLastTrack->meta.setData(
-                    kKeyHVCC, kTypeHVCC, buffer.get(), chunk_data_size);
+            AMediaFormat_setBuffer(mLastTrack->meta, 
+                    AMEDIAFORMAT_KEY_CSD_HEVC, buffer.get(), chunk_data_size);
 
             *offset += chunk_size;
             break;
         }
+        case FOURCC("av1C"):
+        {
+            auto buffer = heapbuffer<uint8_t>(chunk_data_size);
 
-        case FOURCC('d', '2', '6', '3'):
+            if (buffer.get() == NULL) {
+                ALOGE("b/28471206");
+                return NO_MEMORY;
+            }
+
+            if (mDataSource->readAt(
+                        data_offset, buffer.get(), chunk_data_size) < chunk_data_size) {
+                return ERROR_IO;
+            }
+
+            if (mLastTrack == NULL)
+                return ERROR_MALFORMED;
+
+            AMediaFormat_setBuffer(mLastTrack->meta,
+                   AMEDIAFORMAT_KEY_CSD_0, buffer.get(), chunk_data_size);
+
+            *offset += chunk_size;
+            break;
+        }
+        case FOURCC("d263"):
         {
             *offset += chunk_size;
             /*
@@ -2038,12 +2344,13 @@
             if (mLastTrack == NULL)
                 return ERROR_MALFORMED;
 
-            mLastTrack->meta.setData(kKeyD263, kTypeD263, buffer, chunk_data_size);
+            AMediaFormat_setBuffer(mLastTrack->meta,
+                    AMEDIAFORMAT_KEY_D263, buffer, chunk_data_size);
 
             break;
         }
 
-        case FOURCC('m', 'e', 't', 'a'):
+        case FOURCC("meta"):
         {
             off64_t stop_offset = *offset + chunk_size;
             *offset = data_offset;
@@ -2087,13 +2394,13 @@
             break;
         }
 
-        case FOURCC('i', 'l', 'o', 'c'):
-        case FOURCC('i', 'i', 'n', 'f'):
-        case FOURCC('i', 'p', 'r', 'p'):
-        case FOURCC('p', 'i', 't', 'm'):
-        case FOURCC('i', 'd', 'a', 't'):
-        case FOURCC('i', 'r', 'e', 'f'):
-        case FOURCC('i', 'p', 'r', 'o'):
+        case FOURCC("iloc"):
+        case FOURCC("iinf"):
+        case FOURCC("iprp"):
+        case FOURCC("pitm"):
+        case FOURCC("idat"):
+        case FOURCC("iref"):
+        case FOURCC("ipro"):
         {
             if (mIsHeif) {
                 if (mItemTable == NULL) {
@@ -2109,9 +2416,9 @@
             break;
         }
 
-        case FOURCC('m', 'e', 'a', 'n'):
-        case FOURCC('n', 'a', 'm', 'e'):
-        case FOURCC('d', 'a', 't', 'a'):
+        case FOURCC("mean"):
+        case FOURCC("name"):
+        case FOURCC("data"):
         {
             *offset += chunk_size;
 
@@ -2126,7 +2433,7 @@
             break;
         }
 
-        case FOURCC('m', 'v', 'h', 'd'):
+        case FOURCC("mvhd"):
         {
             *offset += chunk_size;
 
@@ -2166,19 +2473,19 @@
                 duration = d32;
             }
             if (duration != 0 && mHeaderTimescale != 0 && duration < UINT64_MAX / 1000000) {
-                mFileMetaData.setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale);
+                AMediaFormat_setInt64(mFileMetaData,
+                        AMEDIAFORMAT_KEY_DURATION, duration * 1000000 / mHeaderTimescale);
             }
 
             String8 s;
             if (convertTimeToDate(creationTime, &s)) {
-                mFileMetaData.setCString(kKeyDate, s.string());
+                AMediaFormat_setString(mFileMetaData, AMEDIAFORMAT_KEY_DATE, s.string());
             }
 
-
             break;
         }
 
-        case FOURCC('m', 'e', 'h', 'd'):
+        case FOURCC("mehd"):
         {
             *offset += chunk_size;
 
@@ -2216,13 +2523,14 @@
             }
 
             if (duration != 0 && mHeaderTimescale != 0) {
-                mFileMetaData.setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale);
+                AMediaFormat_setInt64(mFileMetaData,
+                        AMEDIAFORMAT_KEY_DURATION, duration * 1000000 / mHeaderTimescale);
             }
 
             break;
         }
 
-        case FOURCC('m', 'd', 'a', 't'):
+        case FOURCC("mdat"):
         {
             mMdatFound = true;
 
@@ -2230,7 +2538,7 @@
             break;
         }
 
-        case FOURCC('h', 'd', 'l', 'r'):
+        case FOURCC("hdlr"):
         {
             *offset += chunk_size;
 
@@ -2248,16 +2556,17 @@
             // For the 3GPP file format, the handler-type within the 'hdlr' box
             // shall be 'text'. We also want to support 'sbtl' handler type
             // for a practical reason as various MPEG4 containers use it.
-            if (type == FOURCC('t', 'e', 'x', 't') || type == FOURCC('s', 'b', 't', 'l')) {
+            if (type == FOURCC("text") || type == FOURCC("sbtl")) {
                 if (mLastTrack != NULL) {
-                    mLastTrack->meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP);
+                    AMediaFormat_setString(mLastTrack->meta,
+                            AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_TEXT_3GPP);
                 }
             }
 
             break;
         }
 
-        case FOURCC('k', 'e', 'y', 's'):
+        case FOURCC("keys"):
         {
             *offset += chunk_size;
 
@@ -2270,7 +2579,7 @@
             break;
         }
 
-        case FOURCC('t', 'r', 'e', 'x'):
+        case FOURCC("trex"):
         {
             *offset += chunk_size;
 
@@ -2289,52 +2598,65 @@
             break;
         }
 
-        case FOURCC('t', 'x', '3', 'g'):
+        case FOURCC("tx3g"):
         {
             if (mLastTrack == NULL)
                 return ERROR_MALFORMED;
 
-            uint32_t type;
-            const void *data;
-            size_t size = 0;
-            if (!mLastTrack->meta.findData(
-                    kKeyTextFormatData, &type, &data, &size)) {
-                size = 0;
-            }
-
-            if ((chunk_size > SIZE_MAX) || (SIZE_MAX - chunk_size <= size)) {
+            // complain about ridiculous chunks
+            if (chunk_size > kMaxAtomSize) {
                 return ERROR_MALFORMED;
             }
 
-            uint8_t *buffer = new (std::nothrow) uint8_t[size + chunk_size];
-            if (buffer == NULL) {
+            // complain about empty atoms
+            if (chunk_data_size <= 0) {
+                ALOGE("b/124330204");
+                android_errorWriteLog(0x534e4554, "124330204");
                 return ERROR_MALFORMED;
             }
 
-            if (size > 0) {
-                memcpy(buffer, data, size);
+            // should fill buffer based on "data_offset" and "chunk_data_size"
+            // instead of *offset and chunk_size;
+            // but we've been feeding the extra data to consumers for multiple releases and
+            // if those apps are compensating for it, we'd break them with such a change
+            //
+
+            if (mLastTrack->mTx3gSize - mLastTrack->mTx3gFilled < chunk_size) {
+                size_t growth = kTx3gGrowth;
+                if (growth < chunk_size) {
+                    growth = chunk_size;
+                }
+                // although this disallows 2 tx3g atoms of nearly kMaxAtomSize...
+                if ((uint64_t) mLastTrack->mTx3gSize + growth > kMaxAtomSize) {
+                    ALOGE("b/124330204 - too much space");
+                    android_errorWriteLog(0x534e4554, "124330204");
+                    return ERROR_MALFORMED;
+                }
+                uint8_t *updated = (uint8_t *)realloc(mLastTrack->mTx3gBuffer,
+                                                mLastTrack->mTx3gSize + growth);
+                if (updated == NULL) {
+                    return ERROR_MALFORMED;
+                }
+                mLastTrack->mTx3gBuffer = updated;
+                mLastTrack->mTx3gSize += growth;
             }
 
-            if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size))
+            if ((size_t)(mDataSource->readAt(*offset,
+                                             mLastTrack->mTx3gBuffer + mLastTrack->mTx3gFilled,
+                                             chunk_size))
                     < chunk_size) {
-                delete[] buffer;
-                buffer = NULL;
 
                 // advance read pointer so we don't end up reading this again
                 *offset += chunk_size;
                 return ERROR_IO;
             }
 
-            mLastTrack->meta.setData(
-                    kKeyTextFormatData, 0, buffer, size + chunk_size);
-
-            delete[] buffer;
-
+            mLastTrack->mTx3gFilled += chunk_size;
             *offset += chunk_size;
             break;
         }
 
-        case FOURCC('c', 'o', 'v', 'r'):
+        case FOURCC("covr"):
         {
             *offset += chunk_size;
 
@@ -2358,19 +2680,19 @@
                 return ERROR_MALFORMED;
             }
 
-            mFileMetaData.setData(
-                kKeyAlbumArt, MetaData::TYPE_NONE,
+            AMediaFormat_setBuffer(mFileMetaData,
+                AMEDIAFORMAT_KEY_ALBUMART,
                 buffer.get() + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox);
 
             break;
         }
 
-        case FOURCC('c', 'o', 'l', 'r'):
+        case FOURCC("colr"):
         {
             *offset += chunk_size;
             // this must be in a VisualSampleEntry box under the Sample Description Box ('stsd')
             // ignore otherwise
-            if (depth >= 2 && mPath[depth - 2] == FOURCC('s', 't', 's', 'd')) {
+            if (depth >= 2 && mPath[depth - 2] == FOURCC("stsd")) {
                 status_t err = parseColorInfo(data_offset, chunk_data_size);
                 if (err != OK) {
                     return err;
@@ -2380,12 +2702,12 @@
             break;
         }
 
-        case FOURCC('t', 'i', 't', 'l'):
-        case FOURCC('p', 'e', 'r', 'f'):
-        case FOURCC('a', 'u', 't', 'h'):
-        case FOURCC('g', 'n', 'r', 'e'):
-        case FOURCC('a', 'l', 'b', 'm'):
-        case FOURCC('y', 'r', 'r', 'c'):
+        case FOURCC("titl"):
+        case FOURCC("perf"):
+        case FOURCC("auth"):
+        case FOURCC("gnre"):
+        case FOURCC("albm"):
+        case FOURCC("yrrc"):
         {
             *offset += chunk_size;
 
@@ -2398,7 +2720,7 @@
             break;
         }
 
-        case FOURCC('I', 'D', '3', '2'):
+        case FOURCC("ID32"):
         {
             *offset += chunk_size;
 
@@ -2411,7 +2733,7 @@
             break;
         }
 
-        case FOURCC('-', '-', '-', '-'):
+        case FOURCC("----"):
         {
             mLastCommentMean.clear();
             mLastCommentName.clear();
@@ -2420,7 +2742,7 @@
             break;
         }
 
-        case FOURCC('s', 'i', 'd', 'x'):
+        case FOURCC("sidx"):
         {
             status_t err = parseSegmentIndex(data_offset, chunk_data_size);
             if (err != OK) {
@@ -2430,13 +2752,46 @@
             return UNKNOWN_ERROR; // stop parsing after sidx
         }
 
-        case FOURCC('a', 'c', '-', '3'):
+        case FOURCC("ac-3"):
         {
             *offset += chunk_size;
-            return parseAC3SampleEntry(data_offset);
+            // bypass ac-3 if parse fail
+            if (parseAC3SpecificBox(data_offset) != OK) {
+                if (mLastTrack != NULL) {
+                    ALOGW("Fail to parse ac-3");
+                    mLastTrack->skipTrack = true;
+                }
+            }
+            return OK;
         }
 
-        case FOURCC('f', 't', 'y', 'p'):
+        case FOURCC("ec-3"):
+        {
+            *offset += chunk_size;
+            // bypass ec-3 if parse fail
+            if (parseEAC3SpecificBox(data_offset) != OK) {
+                if (mLastTrack != NULL) {
+                    ALOGW("Fail to parse ec-3");
+                    mLastTrack->skipTrack = true;
+                }
+            }
+            return OK;
+        }
+
+        case FOURCC("ac-4"):
+        {
+            *offset += chunk_size;
+            // bypass ac-4 if parse fail
+            if (parseAC4SpecificBox(data_offset) != OK) {
+                if (mLastTrack != NULL) {
+                    ALOGW("Fail to parse ac-4");
+                    mLastTrack->skipTrack = true;
+                }
+            }
+            return OK;
+        }
+
+        case FOURCC("ftyp"):
         {
             if (chunk_data_size < 8 || depth != 0) {
                 return ERROR_MALFORMED;
@@ -2461,16 +2816,16 @@
                 brandSet.insert(brand);
             }
 
-            if (brandSet.count(FOURCC('q', 't', ' ', ' ')) > 0) {
+            if (brandSet.count(FOURCC("qt  ")) > 0) {
                 mIsQT = true;
             } else {
-                if (brandSet.count(FOURCC('m', 'i', 'f', '1')) > 0
-                 && brandSet.count(FOURCC('h', 'e', 'i', 'c')) > 0) {
+                if (brandSet.count(FOURCC("mif1")) > 0
+                 && brandSet.count(FOURCC("heic")) > 0) {
                     ALOGV("identified HEIF image");
 
                     mIsHeif = true;
-                    brandSet.erase(FOURCC('m', 'i', 'f', '1'));
-                    brandSet.erase(FOURCC('h', 'e', 'i', 'c'));
+                    brandSet.erase(FOURCC("mif1"));
+                    brandSet.erase(FOURCC("heic"));
                 }
 
                 if (!brandSet.empty()) {
@@ -2507,36 +2862,330 @@
     return OK;
 }
 
-status_t MPEG4Extractor::parseAC3SampleEntry(off64_t offset) {
+status_t MPEG4Extractor::parseChannelCountSampleRate(
+        off64_t *offset, uint16_t *channelCount, uint16_t *sampleRate) {
     // skip 16 bytes:
     //  + 6-byte reserved,
     //  + 2-byte data reference index,
     //  + 8-byte reserved
-    offset += 16;
-    uint16_t channelCount;
-    if (!mDataSource->getUInt16(offset, &channelCount)) {
+    *offset += 16;
+    if (!mDataSource->getUInt16(*offset, channelCount)) {
+        ALOGE("MPEG4Extractor: error while reading sample entry box: cannot read channel count");
         return ERROR_MALFORMED;
     }
     // skip 8 bytes:
     //  + 2-byte channelCount,
     //  + 2-byte sample size,
     //  + 4-byte reserved
-    offset += 8;
-    uint16_t sampleRate;
-    if (!mDataSource->getUInt16(offset, &sampleRate)) {
-        ALOGE("MPEG4Extractor: error while reading ac-3 block: cannot read sample rate");
+    *offset += 8;
+    if (!mDataSource->getUInt16(*offset, sampleRate)) {
+        ALOGE("MPEG4Extractor: error while reading sample entry box: cannot read sample rate");
         return ERROR_MALFORMED;
     }
-
     // skip 4 bytes:
     //  + 2-byte sampleRate,
     //  + 2-byte reserved
-    offset += 4;
-    return parseAC3SpecificBox(offset, sampleRate);
+    *offset += 4;
+    return OK;
 }
 
-status_t MPEG4Extractor::parseAC3SpecificBox(
-        off64_t offset, uint16_t sampleRate) {
+status_t MPEG4Extractor::parseAC4SpecificBox(off64_t offset) {
+    if (mLastTrack == NULL) {
+        return ERROR_MALFORMED;
+    }
+
+    uint16_t sampleRate, channelCount;
+    status_t status;
+    if ((status = parseChannelCountSampleRate(&offset, &channelCount, &sampleRate)) != OK) {
+        return status;
+    }
+    uint32_t size;
+    // + 4-byte size
+    // + 4-byte type
+    // + 3-byte payload
+    const uint32_t kAC4MinimumBoxSize = 4 + 4 + 3;
+    if (!mDataSource->getUInt32(offset, &size) || size < kAC4MinimumBoxSize) {
+        ALOGE("MPEG4Extractor: error while reading ac-4 block: cannot read specific box size");
+        return ERROR_MALFORMED;
+    }
+
+    // + 4-byte size
+    offset += 4;
+    uint32_t type;
+    if (!mDataSource->getUInt32(offset, &type) || type != FOURCC("dac4")) {
+        ALOGE("MPEG4Extractor: error while reading ac-4 specific block: header not dac4");
+        return ERROR_MALFORMED;
+    }
+
+    // + 4-byte type
+    offset += 4;
+    const uint32_t kAC4SpecificBoxPayloadSize = 1176;
+    uint8_t chunk[kAC4SpecificBoxPayloadSize];
+    ssize_t dsiSize = size - 8; // size of box - size and type fields
+    if (dsiSize >= (ssize_t)kAC4SpecificBoxPayloadSize ||
+        mDataSource->readAt(offset, chunk, dsiSize) != dsiSize) {
+        ALOGE("MPEG4Extractor: error while reading ac-4 specific block: bitstream fields");
+        return ERROR_MALFORMED;
+    }
+    // + size-byte payload
+    offset += dsiSize;
+    ABitReader br(chunk, dsiSize);
+    AC4DSIParser parser(br);
+    if (!parser.parse()){
+        ALOGE("MPEG4Extractor: error while parsing ac-4 specific block");
+        return ERROR_MALFORMED;
+    }
+
+    AMediaFormat_setString(mLastTrack->meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_AC4);
+    AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, channelCount);
+    AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, sampleRate);
+
+    AudioPresentationCollection presentations;
+    // translate the AC4 presentation information to audio presentations for this track
+    AC4DSIParser::AC4Presentations ac4Presentations = parser.getPresentations();
+    if (!ac4Presentations.empty()) {
+        for (const auto& ac4Presentation : ac4Presentations) {
+            auto& presentation = ac4Presentation.second;
+            if (!presentation.mEnabled) {
+                continue;
+            }
+            AudioPresentationV1 ap;
+            ap.mPresentationId = presentation.mGroupIndex;
+            ap.mProgramId = presentation.mProgramID;
+            ap.mLanguage = presentation.mLanguage;
+            if (presentation.mPreVirtualized) {
+                ap.mMasteringIndication = MASTERED_FOR_HEADPHONE;
+            } else {
+                switch (presentation.mChannelMode) {
+                    case AC4Parser::AC4Presentation::kChannelMode_Mono:
+                    case AC4Parser::AC4Presentation::kChannelMode_Stereo:
+                        ap.mMasteringIndication = MASTERED_FOR_STEREO;
+                        break;
+                    case AC4Parser::AC4Presentation::kChannelMode_3_0:
+                    case AC4Parser::AC4Presentation::kChannelMode_5_0:
+                    case AC4Parser::AC4Presentation::kChannelMode_5_1:
+                    case AC4Parser::AC4Presentation::kChannelMode_7_0_34:
+                    case AC4Parser::AC4Presentation::kChannelMode_7_1_34:
+                    case AC4Parser::AC4Presentation::kChannelMode_7_0_52:
+                    case AC4Parser::AC4Presentation::kChannelMode_7_1_52:
+                        ap.mMasteringIndication = MASTERED_FOR_SURROUND;
+                        break;
+                    case AC4Parser::AC4Presentation::kChannelMode_7_0_322:
+                    case AC4Parser::AC4Presentation::kChannelMode_7_1_322:
+                    case AC4Parser::AC4Presentation::kChannelMode_7_0_4:
+                    case AC4Parser::AC4Presentation::kChannelMode_7_1_4:
+                    case AC4Parser::AC4Presentation::kChannelMode_9_0_4:
+                    case AC4Parser::AC4Presentation::kChannelMode_9_1_4:
+                    case AC4Parser::AC4Presentation::kChannelMode_22_2:
+                        ap.mMasteringIndication = MASTERED_FOR_3D;
+                        break;
+                    default:
+                        ALOGE("Invalid channel mode in AC4 presentation");
+                        return ERROR_MALFORMED;
+                }
+            }
+
+            ap.mAudioDescriptionAvailable = (presentation.mContentClassifier ==
+                    AC4Parser::AC4Presentation::kVisuallyImpaired);
+            ap.mSpokenSubtitlesAvailable = (presentation.mContentClassifier ==
+                    AC4Parser::AC4Presentation::kVoiceOver);
+            ap.mDialogueEnhancementAvailable = presentation.mHasDialogEnhancements;
+            if (!ap.mLanguage.empty()) {
+                ap.mLabels.emplace(ap.mLanguage, presentation.mDescription);
+            }
+            presentations.push_back(std::move(ap));
+        }
+    }
+
+    if (presentations.empty()) {
+        // Clear audio presentation info in metadata.
+        AMediaFormat_setBuffer(
+                mLastTrack->meta, AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO, nullptr, 0);
+    } else {
+        std::ostringstream outStream(std::ios::out);
+        serializeAudioPresentations(presentations, &outStream);
+        AMediaFormat_setBuffer(
+                mLastTrack->meta, AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO,
+                outStream.str().data(), outStream.str().size());
+    }
+    return OK;
+}
+
+status_t MPEG4Extractor::parseEAC3SpecificBox(off64_t offset) {
+    if (mLastTrack == NULL) {
+        return ERROR_MALFORMED;
+    }
+
+    uint16_t sampleRate, channels;
+    status_t status;
+    if ((status = parseChannelCountSampleRate(&offset, &channels, &sampleRate)) != OK) {
+        return status;
+    }
+    uint32_t size;
+    // + 4-byte size
+    // + 4-byte type
+    // + 3-byte payload
+    const uint32_t kEAC3SpecificBoxMinSize = 11;
+    // 13 + 3 + (8 * (2 + 5 + 5 + 3 + 1 + 3 + 4 + (14 * 9 + 1))) bits == 152 bytes theoretical max
+    // calculated from the required bits read below as well as the maximum number of independent
+    // and dependant sub streams you can have
+    const uint32_t kEAC3SpecificBoxMaxSize = 152;
+    if (!mDataSource->getUInt32(offset, &size) ||
+        size < kEAC3SpecificBoxMinSize ||
+        size > kEAC3SpecificBoxMaxSize) {
+        ALOGE("MPEG4Extractor: error while reading eac-3 block: cannot read specific box size");
+        return ERROR_MALFORMED;
+    }
+
+    offset += 4;
+    uint32_t type;
+    if (!mDataSource->getUInt32(offset, &type) || type != FOURCC("dec3")) {
+        ALOGE("MPEG4Extractor: error while reading eac-3 specific block: header not dec3");
+        return ERROR_MALFORMED;
+    }
+
+    offset += 4;
+    uint8_t* chunk = new (std::nothrow) uint8_t[size];
+    if (chunk == NULL) {
+        return ERROR_MALFORMED;
+    }
+
+    if (mDataSource->readAt(offset, chunk, size) != (ssize_t)size) {
+        ALOGE("MPEG4Extractor: error while reading eac-3 specific block: bitstream fields");
+        delete[] chunk;
+        return ERROR_MALFORMED;
+    }
+
+    ABitReader br(chunk, size);
+    static const unsigned channelCountTable[] = {2, 1, 2, 3, 3, 4, 4, 5};
+    static const unsigned sampleRateTable[] = {48000, 44100, 32000};
+
+    if (br.numBitsLeft() < 16) {
+        delete[] chunk;
+        return ERROR_MALFORMED;
+    }
+    unsigned data_rate = br.getBits(13);
+    ALOGV("EAC3 data rate = %d", data_rate);
+
+    unsigned num_ind_sub = br.getBits(3) + 1;
+    ALOGV("EAC3 independant substreams = %d", num_ind_sub);
+    if (br.numBitsLeft() < (num_ind_sub * 23)) {
+        delete[] chunk;
+        return ERROR_MALFORMED;
+    }
+
+    unsigned channelCount = 0;
+    for (unsigned i = 0; i < num_ind_sub; i++) {
+        unsigned fscod = br.getBits(2);
+        if (fscod == 3) {
+            ALOGE("Incorrect fscod (3) in EAC3 header");
+            delete[] chunk;
+            return ERROR_MALFORMED;
+        }
+        unsigned boxSampleRate = sampleRateTable[fscod];
+        if (boxSampleRate != sampleRate) {
+            ALOGE("sample rate mismatch: boxSampleRate = %d, sampleRate = %d",
+                boxSampleRate, sampleRate);
+            delete[] chunk;
+            return ERROR_MALFORMED;
+        }
+
+        unsigned bsid = br.getBits(5);
+        if (bsid == 9 || bsid == 10) {
+            ALOGW("EAC3 stream (bsid=%d) may be silenced by the decoder", bsid);
+        } else if (bsid > 16) {
+            ALOGE("EAC3 stream (bsid=%d) is not compatible with ETSI TS 102 366 v1.4.1", bsid);
+            delete[] chunk;
+            return ERROR_MALFORMED;
+        }
+
+        // skip
+        br.skipBits(2);
+        unsigned bsmod = br.getBits(3);
+        unsigned acmod = br.getBits(3);
+        unsigned lfeon = br.getBits(1);
+        // we currently only support the first stream
+        if (i == 0)
+            channelCount = channelCountTable[acmod] + lfeon;
+        ALOGV("bsmod = %d, acmod = %d, lfeon = %d", bsmod, acmod, lfeon);
+
+        br.skipBits(3);
+        unsigned num_dep_sub = br.getBits(4);
+        ALOGV("EAC3 dependant substreams = %d", num_dep_sub);
+        if (num_dep_sub != 0) {
+            if (br.numBitsLeft() < 9) {
+                delete[] chunk;
+                return ERROR_MALFORMED;
+            }
+            static const char* chan_loc_tbl[] = { "Lc/Rc","Lrs/Rrs","Cs","Ts","Lsd/Rsd",
+                "Lw/Rw","Lvh/Rvh","Cvh","Lfe2" };
+            unsigned chan_loc = br.getBits(9);
+            unsigned mask = 1;
+            for (unsigned j = 0; j < 9; j++, mask <<= 1) {
+                if ((chan_loc & mask) != 0) {
+                    // we currently only support the first stream
+                    if (i == 0) {
+                        channelCount++;
+                        // these are 2 channels in the mask
+                        if (j == 0 || j == 1 || j == 4 || j == 5 || j == 6) {
+                            channelCount++;
+                        }
+                    }
+                    ALOGV(" %s", chan_loc_tbl[j]);
+                }
+            }
+        } else {
+            if (br.numBitsLeft() == 0) {
+                delete[] chunk;
+                return ERROR_MALFORMED;
+            }
+            br.skipBits(1);
+        }
+    }
+
+    if (br.numBitsLeft() != 0) {
+        if (br.numBitsLeft() < 8) {
+            delete[] chunk;
+            return ERROR_MALFORMED;
+        }
+        unsigned mask = br.getBits(8);
+        for (unsigned i = 0; i < 8; i++) {
+            if (((0x1 << i) && mask) == 0)
+                continue;
+
+            if (br.numBitsLeft() < 8) {
+                delete[] chunk;
+                return ERROR_MALFORMED;
+            }
+            switch (i) {
+                case 0: {
+                    unsigned complexity = br.getBits(8);
+                    ALOGV("Found a JOC stream with complexity = %d", complexity);
+                }break;
+                default: {
+                    br.skipBits(8);
+                }break;
+            }
+        }
+    }
+    AMediaFormat_setString(mLastTrack->meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_EAC3);
+    AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, channelCount);
+    AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, sampleRate);
+
+    delete[] chunk;
+    return OK;
+}
+
+status_t MPEG4Extractor::parseAC3SpecificBox(off64_t offset) {
+    if (mLastTrack == NULL) {
+        return ERROR_MALFORMED;
+    }
+
+    uint16_t sampleRate, channels;
+    status_t status;
+    if ((status = parseChannelCountSampleRate(&offset, &channels, &sampleRate)) != OK) {
+        return status;
+    }
     uint32_t size;
     // + 4-byte size
     // + 4-byte type
@@ -2549,7 +3198,7 @@
 
     offset += 4;
     uint32_t type;
-    if (!mDataSource->getUInt32(offset, &type) || type != FOURCC('d', 'a', 'c', '3')) {
+    if (!mDataSource->getUInt32(offset, &type) || type != FOURCC("dac3")) {
         ALOGE("MPEG4Extractor: error while reading ac-3 specific block: header not dac3");
         return ERROR_MALFORMED;
     }
@@ -2591,12 +3240,48 @@
     unsigned lfeon = br.getBits(1);
     unsigned channelCount = channelCountTable[acmod] + lfeon;
 
-    if (mLastTrack == NULL) {
+    AMediaFormat_setString(mLastTrack->meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_AC3);
+    AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, channelCount);
+    AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, sampleRate);
+    return OK;
+}
+
+status_t MPEG4Extractor::parseALACSampleEntry(off64_t *offset) {
+    // See 'external/alac/ALACMagicCookieDescription.txt for the detail'.
+    // Store ALAC magic cookie (decoder needs it).
+    uint8_t alacInfo[12];
+    off64_t data_offset = *offset;
+
+    if (mDataSource->readAt(
+            data_offset, alacInfo, sizeof(alacInfo)) < (ssize_t)sizeof(alacInfo)) {
+        return ERROR_IO;
+    }
+    uint32_t size = U32_AT(&alacInfo[0]);
+    if ((size != ALAC_SPECIFIC_INFO_SIZE) ||
+            (U32_AT(&alacInfo[4]) != FOURCC("alac")) ||
+            (U32_AT(&alacInfo[8]) != 0)) {
+        ALOGV("Size:%u, U32_AT(&alacInfo[4]):%u, U32_AT(&alacInfo[8]):%u",
+            size, U32_AT(&alacInfo[4]), U32_AT(&alacInfo[8]));
         return ERROR_MALFORMED;
     }
-    mLastTrack->meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC3);
-    mLastTrack->meta.setInt32(kKeyChannelCount, channelCount);
-    mLastTrack->meta.setInt32(kKeySampleRate, sampleRate);
+    data_offset += sizeof(alacInfo);
+    uint8_t cookie[size - sizeof(alacInfo)];
+    if (mDataSource->readAt(
+            data_offset, cookie, sizeof(cookie)) < (ssize_t)sizeof(cookie)) {
+        return ERROR_IO;
+    }
+
+    uint8_t bitsPerSample = cookie[5];
+    AMediaFormat_setInt32(mLastTrack->meta,
+            AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, bitsPerSample);
+    AMediaFormat_setInt32(mLastTrack->meta,
+            AMEDIAFORMAT_KEY_CHANNEL_COUNT, cookie[9]);
+    AMediaFormat_setInt32(mLastTrack->meta,
+            AMEDIAFORMAT_KEY_SAMPLE_RATE, U32_AT(&cookie[20]));
+    AMediaFormat_setBuffer(mLastTrack->meta,
+            AMEDIAFORMAT_KEY_CSD_0, cookie, sizeof(cookie));
+    data_offset += sizeof(cookie);
+    *offset = data_offset;
     return OK;
 }
 
@@ -2716,8 +3401,9 @@
         return ERROR_MALFORMED;
 
     int64_t metaDuration;
-    if (!mLastTrack->meta.findInt64(kKeyDuration, &metaDuration) || metaDuration == 0) {
-        mLastTrack->meta.setInt64(kKeyDuration, sidxDuration);
+    if (!AMediaFormat_getInt64(mLastTrack->meta,
+                AMEDIAFORMAT_KEY_DURATION, &metaDuration) || metaDuration == 0) {
+        AMediaFormat_setInt64(mLastTrack->meta, AMEDIAFORMAT_KEY_DURATION, sidxDuration);
     }
     return OK;
 }
@@ -2753,7 +3439,7 @@
 
         uint32_t type;
         if (!mDataSource->getUInt32(keyOffset + 4, &type)
-                || type != FOURCC('m', 'd', 't', 'a')) {
+                || type != FOURCC("mdta")) {
             return ERROR_MALFORMED;
         }
 
@@ -2795,7 +3481,7 @@
     }
     uint32_t atomFourCC;
     if (!mDataSource->getUInt32(offset + 4, &atomFourCC)
-            || atomFourCC != FOURCC('d', 'a', 't', 'a')) {
+            || atomFourCC != FOURCC("data")) {
         return ERROR_MALFORMED;
     }
     uint32_t dataType;
@@ -2815,7 +3501,7 @@
             return ERROR_MALFORMED;
         }
         if (!strcasecmp(mMetaKeyMap[index].c_str(), "com.android.capture.fps")) {
-            mFileMetaData.setFloat(kKeyCaptureFramerate, *(float *)&val);
+            AMediaFormat_setFloat(mFileMetaData, AMEDIAFORMAT_KEY_CAPTURE_RATE, *(float *)&val);
         }
     } else if (dataType == 67 && dataSize >= 4) {
         // BE signed int32
@@ -2824,7 +3510,8 @@
             return ERROR_MALFORMED;
         }
         if (!strcasecmp(mMetaKeyMap[index].c_str(), "com.android.video.temporal_layers_count")) {
-            mFileMetaData.setInt32(kKeyTemporalLayerCount, val);
+            AMediaFormat_setInt32(mFileMetaData,
+                    AMEDIAFORMAT_KEY_TEMPORAL_LAYER_COUNT, val);
         }
     } else {
         // add more keys if needed
@@ -2878,7 +3565,7 @@
     if (mLastTrack == NULL)
         return ERROR_MALFORMED;
 
-    mLastTrack->meta.setInt32(kKeyTrackID, id);
+    AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_TRACK_ID, id);
 
     size_t matrixOffset = dynSize + 16;
     int32_t a00 = U32_AT(&buffer[matrixOffset]);
@@ -2914,15 +3601,15 @@
     }
 
     if (rotationDegrees != 0) {
-        mLastTrack->meta.setInt32(kKeyRotation, rotationDegrees);
+        AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_ROTATION, rotationDegrees);
     }
 
     // Handle presentation display size, which could be different
-    // from the image size indicated by kKeyWidth and kKeyHeight.
+    // from the image size indicated by AMEDIAFORMAT_KEY_WIDTH and AMEDIAFORMAT_KEY_HEIGHT.
     uint32_t width = U32_AT(&buffer[dynSize + 52]);
     uint32_t height = U32_AT(&buffer[dynSize + 56]);
-    mLastTrack->meta.setInt32(kKeyDisplayWidth, width >> 16);
-    mLastTrack->meta.setInt32(kKeyDisplayHeight, height >> 16);
+    AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_DISPLAY_WIDTH, width >> 16);
+    AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_DISPLAY_HEIGHT, height >> 16);
 
     return OK;
 }
@@ -2950,68 +3637,64 @@
 
     uint32_t flags = U32_AT(buffer);
 
-    uint32_t metadataKey = 0;
+    const char *metadataKey = nullptr;
     char chunk[5];
     MakeFourCCString(mPath[4], chunk);
     ALOGV("meta: %s @ %lld", chunk, (long long)offset);
     switch ((int32_t)mPath[4]) {
-        case FOURCC(0xa9, 'a', 'l', 'b'):
+        case FOURCC("\251alb"):
         {
-            metadataKey = kKeyAlbum;
+            metadataKey = "album";
             break;
         }
-        case FOURCC(0xa9, 'A', 'R', 'T'):
+        case FOURCC("\251ART"):
         {
-            metadataKey = kKeyArtist;
+            metadataKey = "artist";
             break;
         }
-        case FOURCC('a', 'A', 'R', 'T'):
+        case FOURCC("aART"):
         {
-            metadataKey = kKeyAlbumArtist;
+            metadataKey = "albumartist";
             break;
         }
-        case FOURCC(0xa9, 'd', 'a', 'y'):
+        case FOURCC("\251day"):
         {
-            metadataKey = kKeyYear;
+            metadataKey = "year";
             break;
         }
-        case FOURCC(0xa9, 'n', 'a', 'm'):
+        case FOURCC("\251nam"):
         {
-            metadataKey = kKeyTitle;
+            metadataKey = "title";
             break;
         }
-        case FOURCC(0xa9, 'w', 'r', 't'):
+        case FOURCC("\251wrt"):
         {
-            metadataKey = kKeyWriter;
+            metadataKey = "writer";
             break;
         }
-        case FOURCC('c', 'o', 'v', 'r'):
+        case FOURCC("covr"):
         {
-            metadataKey = kKeyAlbumArt;
+            metadataKey = "albumart";
             break;
         }
-        case FOURCC('g', 'n', 'r', 'e'):
+        case FOURCC("gnre"):
+        case FOURCC("\251gen"):
         {
-            metadataKey = kKeyGenre;
+            metadataKey = "genre";
             break;
         }
-        case FOURCC(0xa9, 'g', 'e', 'n'):
-        {
-            metadataKey = kKeyGenre;
-            break;
-        }
-        case FOURCC('c', 'p', 'i', 'l'):
+        case FOURCC("cpil"):
         {
             if (size == 9 && flags == 21) {
                 char tmp[16];
                 sprintf(tmp, "%d",
                         (int)buffer[size - 1]);
 
-                mFileMetaData.setCString(kKeyCompilation, tmp);
+                AMediaFormat_setString(mFileMetaData, AMEDIAFORMAT_KEY_COMPILATION, tmp);
             }
             break;
         }
-        case FOURCC('t', 'r', 'k', 'n'):
+        case FOURCC("trkn"):
         {
             if (size == 16 && flags == 0) {
                 char tmp[16];
@@ -3019,11 +3702,11 @@
                 uint16_t* pTotalTracks = (uint16_t*)&buffer[12];
                 sprintf(tmp, "%d/%d", ntohs(*pTrack), ntohs(*pTotalTracks));
 
-                mFileMetaData.setCString(kKeyCDTrackNumber, tmp);
+                AMediaFormat_setString(mFileMetaData, AMEDIAFORMAT_KEY_CDTRACKNUMBER, tmp);
             }
             break;
         }
-        case FOURCC('d', 'i', 's', 'k'):
+        case FOURCC("disk"):
         {
             if ((size == 14 || size == 16) && flags == 0) {
                 char tmp[16];
@@ -3031,21 +3714,21 @@
                 uint16_t* pTotalDiscs = (uint16_t*)&buffer[12];
                 sprintf(tmp, "%d/%d", ntohs(*pDisc), ntohs(*pTotalDiscs));
 
-                mFileMetaData.setCString(kKeyDiscNumber, tmp);
+                AMediaFormat_setString(mFileMetaData, AMEDIAFORMAT_KEY_DISCNUMBER, tmp);
             }
             break;
         }
-        case FOURCC('-', '-', '-', '-'):
+        case FOURCC("----"):
         {
             buffer[size] = '\0';
             switch (mPath[5]) {
-                case FOURCC('m', 'e', 'a', 'n'):
+                case FOURCC("mean"):
                     mLastCommentMean.setTo((const char *)buffer + 4);
                     break;
-                case FOURCC('n', 'a', 'm', 'e'):
+                case FOURCC("name"):
                     mLastCommentName.setTo((const char *)buffer + 4);
                     break;
-                case FOURCC('d', 'a', 't', 'a'):
+                case FOURCC("data"):
                     if (size < 8) {
                         delete[] buffer;
                         buffer = NULL;
@@ -3075,8 +3758,10 @@
                             return ERROR_MALFORMED;
                         }
 
-                        mLastTrack->meta.setInt32(kKeyEncoderDelay, delay);
-                        mLastTrack->meta.setInt32(kKeyEncoderPadding, padding);
+                        AMediaFormat_setInt32(mLastTrack->meta,
+                                AMEDIAFORMAT_KEY_ENCODER_DELAY, delay);
+                        AMediaFormat_setInt32(mLastTrack->meta,
+                                AMEDIAFORMAT_KEY_ENCODER_PADDING, padding);
                     }
                 }
 
@@ -3091,12 +3776,16 @@
             break;
     }
 
-    if (size >= 8 && metadataKey && !mFileMetaData.hasData(metadataKey)) {
-        if (metadataKey == kKeyAlbumArt) {
-            mFileMetaData.setData(
-                    kKeyAlbumArt, MetaData::TYPE_NONE,
+    void *tmpData;
+    size_t tmpDataSize;
+    const char *s;
+    if (size >= 8 && metadataKey &&
+            !AMediaFormat_getBuffer(mFileMetaData, metadataKey, &tmpData, &tmpDataSize) &&
+            !AMediaFormat_getString(mFileMetaData, metadataKey, &s)) {
+        if (!strcmp(metadataKey, "albumart")) {
+            AMediaFormat_setBuffer(mFileMetaData, metadataKey,
                     buffer + 8, size - 8);
-        } else if (metadataKey == kKeyGenre) {
+        } else if (!strcmp(metadataKey, "genre")) {
             if (flags == 0) {
                 // uint8_t genre code, iTunes genre codes are
                 // the standard id3 codes, except they start
@@ -3110,18 +3799,18 @@
                 char genre[10];
                 sprintf(genre, "%d", genrecode);
 
-                mFileMetaData.setCString(metadataKey, genre);
+                AMediaFormat_setString(mFileMetaData, metadataKey, genre);
             } else if (flags == 1) {
                 // custom genre string
                 buffer[size] = '\0';
 
-                mFileMetaData.setCString(
+                AMediaFormat_setString(mFileMetaData, 
                         metadataKey, (const char *)buffer + 8);
             }
         } else {
             buffer[size] = '\0';
 
-            mFileMetaData.setCString(
+            AMediaFormat_setString(mFileMetaData, 
                     metadataKey, (const char *)buffer + 8);
         }
     }
@@ -3149,23 +3838,33 @@
     }
 
     int32_t type = U32_AT(&buffer[0]);
-    if ((type == FOURCC('n', 'c', 'l', 'x') && size >= 11)
-            || (type == FOURCC('n', 'c', 'l', 'c') && size >= 10)) {
-        int32_t primaries = U16_AT(&buffer[4]);
-        int32_t transfer = U16_AT(&buffer[6]);
-        int32_t coeffs = U16_AT(&buffer[8]);
-        bool fullRange = (type == FOURCC('n', 'c', 'l', 'x')) && (buffer[10] & 128);
-
-        ColorAspects aspects;
-        ColorUtils::convertIsoColorAspectsToCodecAspects(
-                primaries, transfer, coeffs, fullRange, aspects);
-
+    if ((type == FOURCC("nclx") && size >= 11)
+            || (type == FOURCC("nclc") && size >= 10)) {
         // only store the first color specification
-        if (!mLastTrack->meta.hasData(kKeyColorPrimaries)) {
-            mLastTrack->meta.setInt32(kKeyColorPrimaries, aspects.mPrimaries);
-            mLastTrack->meta.setInt32(kKeyTransferFunction, aspects.mTransfer);
-            mLastTrack->meta.setInt32(kKeyColorMatrix, aspects.mMatrixCoeffs);
-            mLastTrack->meta.setInt32(kKeyColorRange, aspects.mRange);
+        int32_t existingColor;
+        if (!AMediaFormat_getInt32(mLastTrack->meta,
+                AMEDIAFORMAT_KEY_COLOR_RANGE, &existingColor)) {
+            int32_t primaries = U16_AT(&buffer[4]);
+            int32_t isotransfer = U16_AT(&buffer[6]);
+            int32_t coeffs = U16_AT(&buffer[8]);
+            bool fullRange = (type == FOURCC("nclx")) && (buffer[10] & 128);
+
+            int32_t range = 0;
+            int32_t standard = 0;
+            int32_t transfer = 0;
+            ColorUtils::convertIsoColorAspectsToPlatformAspects(
+                    primaries, isotransfer, coeffs, fullRange,
+                    &range, &standard, &transfer);
+
+            if (range != 0) {
+                AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_COLOR_RANGE, range);
+            }
+            if (standard != 0) {
+                AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_COLOR_STANDARD, standard);
+            }
+            if (transfer != 0) {
+                AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_COLOR_TRANSFER, transfer);
+            }
         }
     }
 
@@ -3192,41 +3891,41 @@
         return ERROR_IO;
     }
 
-    uint32_t metadataKey = 0;
+    const char *metadataKey = nullptr;
     switch (mPath[depth]) {
-        case FOURCC('t', 'i', 't', 'l'):
+        case FOURCC("titl"):
         {
-            metadataKey = kKeyTitle;
+            metadataKey = "title";
             break;
         }
-        case FOURCC('p', 'e', 'r', 'f'):
+        case FOURCC("perf"):
         {
-            metadataKey = kKeyArtist;
+            metadataKey = "artist";
             break;
         }
-        case FOURCC('a', 'u', 't', 'h'):
+        case FOURCC("auth"):
         {
-            metadataKey = kKeyWriter;
+            metadataKey = "writer";
             break;
         }
-        case FOURCC('g', 'n', 'r', 'e'):
+        case FOURCC("gnre"):
         {
-            metadataKey = kKeyGenre;
+            metadataKey = "genre";
             break;
         }
-        case FOURCC('a', 'l', 'b', 'm'):
+        case FOURCC("albm"):
         {
             if (buffer[size - 1] != '\0') {
               char tmp[4];
               sprintf(tmp, "%u", buffer[size - 1]);
 
-              mFileMetaData.setCString(kKeyCDTrackNumber, tmp);
+              AMediaFormat_setString(mFileMetaData, AMEDIAFORMAT_KEY_CDTRACKNUMBER, tmp);
             }
 
-            metadataKey = kKeyAlbum;
+            metadataKey = "album";
             break;
         }
-        case FOURCC('y', 'r', 'r', 'c'):
+        case FOURCC("yrrc"):
         {
             if (size < 6) {
                 delete[] buffer;
@@ -3241,7 +3940,7 @@
             if (year < 10000) {
                 sprintf(tmp, "%u", year);
 
-                mFileMetaData.setCString(kKeyYear, tmp);
+                AMediaFormat_setString(mFileMetaData, AMEDIAFORMAT_KEY_YEAR, tmp);
             }
             break;
         }
@@ -3250,7 +3949,7 @@
             break;
     }
 
-    if (metadataKey > 0) {
+    if (metadataKey) {
         bool isUTF8 = true; // Common case
         char16_t *framedata = NULL;
         int len16 = 0; // Number of UTF-16 characters
@@ -3286,11 +3985,11 @@
 
         if (isUTF8) {
             buffer[size] = 0;
-            mFileMetaData.setCString(metadataKey, (const char *)buffer + 6);
+            AMediaFormat_setString(mFileMetaData, metadataKey, (const char *)buffer + 6);
         } else {
             // Convert from UTF-16 string to UTF-8 string.
             String8 tmpUTF8str(framedata, len16);
-            mFileMetaData.setCString(metadataKey, tmpUTF8str.string());
+            AMediaFormat_setString(mFileMetaData, metadataKey, tmpUTF8str.string());
         }
     }
 
@@ -3305,27 +4004,28 @@
 
     if (id3.isValid()) {
         struct Map {
-            int key;
+            const char *key;
             const char *tag1;
             const char *tag2;
         };
         static const Map kMap[] = {
-            { kKeyAlbum, "TALB", "TAL" },
-            { kKeyArtist, "TPE1", "TP1" },
-            { kKeyAlbumArtist, "TPE2", "TP2" },
-            { kKeyComposer, "TCOM", "TCM" },
-            { kKeyGenre, "TCON", "TCO" },
-            { kKeyTitle, "TIT2", "TT2" },
-            { kKeyYear, "TYE", "TYER" },
-            { kKeyAuthor, "TXT", "TEXT" },
-            { kKeyCDTrackNumber, "TRK", "TRCK" },
-            { kKeyDiscNumber, "TPA", "TPOS" },
-            { kKeyCompilation, "TCP", "TCMP" },
+            { AMEDIAFORMAT_KEY_ALBUM, "TALB", "TAL" },
+            { AMEDIAFORMAT_KEY_ARTIST, "TPE1", "TP1" },
+            { AMEDIAFORMAT_KEY_ALBUMARTIST, "TPE2", "TP2" },
+            { AMEDIAFORMAT_KEY_COMPOSER, "TCOM", "TCM" },
+            { AMEDIAFORMAT_KEY_GENRE, "TCON", "TCO" },
+            { AMEDIAFORMAT_KEY_TITLE, "TIT2", "TT2" },
+            { AMEDIAFORMAT_KEY_YEAR, "TYE", "TYER" },
+            { AMEDIAFORMAT_KEY_AUTHOR, "TXT", "TEXT" },
+            { AMEDIAFORMAT_KEY_CDTRACKNUMBER, "TRK", "TRCK" },
+            { AMEDIAFORMAT_KEY_DISCNUMBER, "TPA", "TPOS" },
+            { AMEDIAFORMAT_KEY_COMPILATION, "TCP", "TCMP" },
         };
         static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]);
 
         for (size_t i = 0; i < kNumMapEntries; ++i) {
-            if (!mFileMetaData.hasData(kMap[i].key)) {
+            const char *ss;
+            if (!AMediaFormat_getString(mFileMetaData, kMap[i].key, &ss)) {
                 ID3::Iterator *it = new ID3::Iterator(id3, kMap[i].tag1);
                 if (it->done()) {
                     delete it;
@@ -3341,7 +4041,7 @@
                 it->getString(&s);
                 delete it;
 
-                mFileMetaData.setCString(kMap[i].key, s);
+                AMediaFormat_setString(mFileMetaData, kMap[i].key, s);
             }
         }
 
@@ -3350,13 +4050,12 @@
         const void *data = id3.getAlbumArt(&dataSize, &mime);
 
         if (data) {
-            mFileMetaData.setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize);
-            mFileMetaData.setCString(kKeyAlbumArtMIME, mime.string());
+            AMediaFormat_setBuffer(mFileMetaData, AMEDIAFORMAT_KEY_ALBUMART, data, dataSize);
         }
     }
 }
 
-MediaTrack *MPEG4Extractor::getTrack(size_t index) {
+MediaTrackHelper *MPEG4Extractor::getTrack(size_t index) {
     status_t err;
     if ((err = readMetaData()) != OK) {
         return NULL;
@@ -3379,7 +4078,7 @@
 
     Trex *trex = NULL;
     int32_t trackId;
-    if (track->meta.findInt32(kKeyTrackID, &trackId)) {
+    if (AMediaFormat_getInt32(track->meta, AMEDIAFORMAT_KEY_TRACK_ID, &trackId)) {
         for (size_t i = 0; i < mTrex.size(); i++) {
             Trex *t = &mTrex.editItemAt(i);
             if (t->track_ID == (uint32_t) trackId) {
@@ -3395,16 +4094,15 @@
     ALOGV("getTrack called, pssh: %zu", mPssh.size());
 
     const char *mime;
-    if (!track->meta.findCString(kKeyMIMEType, &mime)) {
+    if (!AMediaFormat_getString(track->meta, AMEDIAFORMAT_KEY_MIME, &mime)) {
         return NULL;
     }
 
     sp<ItemTable> itemTable;
     if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
-        uint32_t type;
-        const void *data;
+        void *data;
         size_t size;
-        if (!track->meta.findData(kKeyAVCC, &type, &data, &size)) {
+        if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_CSD_AVC, &data, &size)) {
             return NULL;
         }
 
@@ -3415,10 +4113,9 @@
         }
     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)
             || !strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC)) {
-        uint32_t type;
-        const void *data;
+        void *data;
         size_t size;
-        if (!track->meta.findData(kKeyHVCC, &type, &data, &size)) {
+        if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_CSD_HEVC, &data, &size)) {
             return NULL;
         }
 
@@ -3430,11 +4127,29 @@
         if (!strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC)) {
             itemTable = mItemTable;
         }
+    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AV1)) {
+        void *data;
+        size_t size;
+        if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_CSD_0, &data, &size)) {
+            return NULL;
+        }
+
+        const uint8_t *ptr = (const uint8_t *)data;
+
+        if (size < 5 || ptr[0] != 0x81) {  // configurationVersion == 1
+            return NULL;
+        }
+    }
+
+    if (track->has_elst and !strncasecmp("video/", mime, 6) and track->elst_media_time > 0) {
+        track->elstShiftStartTicks = track->elst_media_time;
+        ALOGV("video track->elstShiftStartTicks :%" PRIu64, track->elstShiftStartTicks);
     }
 
     MPEG4Source *source =  new MPEG4Source(
             track->meta, mDataSource, track->timescale, track->sampleTable,
-            mSidxEntries, trex, mMoofOffset, itemTable);
+            mSidxEntries, trex, mMoofOffset, itemTable,
+            track->elstShiftStartTicks);
     if (source->init() != OK) {
         delete source;
         return NULL;
@@ -3445,26 +4160,26 @@
 // static
 status_t MPEG4Extractor::verifyTrack(Track *track) {
     const char *mime;
-    CHECK(track->meta.findCString(kKeyMIMEType, &mime));
+    CHECK(AMediaFormat_getString(track->meta, AMEDIAFORMAT_KEY_MIME, &mime));
 
-    uint32_t type;
-    const void *data;
+    void *data;
     size_t size;
     if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
-        if (!track->meta.findData(kKeyAVCC, &type, &data, &size)
-                || type != kTypeAVCC) {
+        if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_CSD_AVC, &data, &size)) {
             return ERROR_MALFORMED;
         }
     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) {
-        if (!track->meta.findData(kKeyHVCC, &type, &data, &size)
-                    || type != kTypeHVCC) {
+        if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_CSD_HEVC, &data, &size)) {
+            return ERROR_MALFORMED;
+        }
+    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AV1)) {
+        if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_CSD_0, &data, &size)) {
             return ERROR_MALFORMED;
         }
     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)
             || !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)
             || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
-        if (!track->meta.findData(kKeyESDS, &type, &data, &size)
-                || type != kTypeESDS) {
+        if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_ESDS, &data, &size)) {
             return ERROR_MALFORMED;
         }
     }
@@ -3549,16 +4264,14 @@
         if (mLastTrack == NULL)
             return ERROR_MALFORMED;
 
-        mLastTrack->meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP);
+        AMediaFormat_setString(mLastTrack->meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_QCELP);
         return OK;
     }
 
-    if (objectTypeIndication  == 0x6b) {
-        // The media subtype is MP3 audio
-        // Our software MP3 audio decoder may not be able to handle
-        // packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED
-        ALOGE("MP3 track in MP4/3GPP file is not supported");
-        return ERROR_UNSUPPORTED;
+    if (objectTypeIndication == 0x6B || objectTypeIndication == 0x69) {
+        // mp3 audio
+        AMediaFormat_setString(mLastTrack->meta,AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_MPEG);
+        return OK;
     }
 
     if (mLastTrack != NULL) {
@@ -3566,10 +4279,12 @@
         uint32_t avgBitrate = 0;
         esds.getBitRate(&maxBitrate, &avgBitrate);
         if (maxBitrate > 0 && maxBitrate < INT32_MAX) {
-            mLastTrack->meta.setInt32(kKeyMaxBitRate, (int32_t)maxBitrate);
+            AMediaFormat_setInt32(mLastTrack->meta,
+                    AMEDIAFORMAT_KEY_MAX_BIT_RATE, (int32_t)maxBitrate);
         }
         if (avgBitrate > 0 && avgBitrate < INT32_MAX) {
-            mLastTrack->meta.setInt32(kKeyBitRate, (int32_t)avgBitrate);
+            AMediaFormat_setInt32(mLastTrack->meta,
+                    AMEDIAFORMAT_KEY_BIT_RATE, (int32_t)avgBitrate);
         }
     }
 
@@ -3597,6 +4312,77 @@
         return ERROR_MALFORMED;
     }
 
+    if (objectTypeIndication == 0xdd) {
+        // vorbis audio
+        if (csd[0] != 0x02) {
+            return ERROR_MALFORMED;
+        }
+
+        // codecInfo starts with two lengths, len1 and len2, that are
+        // "Xiph-style-lacing encoded"..
+
+        size_t offset = 1;
+        size_t len1 = 0;
+        while (offset < csd_size && csd[offset] == 0xff) {
+            if (__builtin_add_overflow(len1, 0xff, &len1)) {
+                return ERROR_MALFORMED;
+            }
+            ++offset;
+        }
+        if (offset >= csd_size) {
+            return ERROR_MALFORMED;
+        }
+        if (__builtin_add_overflow(len1, csd[offset], &len1)) {
+            return ERROR_MALFORMED;
+        }
+        ++offset;
+        if (len1 == 0) {
+            return ERROR_MALFORMED;
+        }
+
+        size_t len2 = 0;
+        while (offset < csd_size && csd[offset] == 0xff) {
+            if (__builtin_add_overflow(len2, 0xff, &len2)) {
+                return ERROR_MALFORMED;
+            }
+            ++offset;
+        }
+        if (offset >= csd_size) {
+            return ERROR_MALFORMED;
+        }
+        if (__builtin_add_overflow(len2, csd[offset], &len2)) {
+            return ERROR_MALFORMED;
+        }
+        ++offset;
+        if (len2 == 0) {
+            return ERROR_MALFORMED;
+        }
+        if (offset >= csd_size || csd[offset] != 0x01) {
+            return ERROR_MALFORMED;
+        }
+        // formerly kKeyVorbisInfo
+        AMediaFormat_setBuffer(mLastTrack->meta,
+                AMEDIAFORMAT_KEY_CSD_0, &csd[offset], len1);
+
+        if (__builtin_add_overflow(offset, len1, &offset) ||
+                offset >= csd_size || csd[offset] != 0x03) {
+            return ERROR_MALFORMED;
+        }
+
+        if (__builtin_add_overflow(offset, len2, &offset) ||
+                offset >= csd_size || csd[offset] != 0x05) {
+            return ERROR_MALFORMED;
+        }
+
+        // formerly kKeyVorbisBooks
+        AMediaFormat_setBuffer(mLastTrack->meta,
+                AMEDIAFORMAT_KEY_CSD_1, &csd[offset], csd_size - offset);
+        AMediaFormat_setString(mLastTrack->meta,
+                AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_VORBIS);
+
+        return OK;
+    }
+
     static uint32_t kSamplingRate[] = {
         96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
         16000, 12000, 11025, 8000, 7350
@@ -3613,7 +4399,7 @@
         return ERROR_MALFORMED;
 
     //keep AOT type
-    mLastTrack->meta.setInt32(kKeyAACAOT, objectType);
+    AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_AAC_PROFILE, objectType);
 
     uint32_t freqIndex = br.getBits(4);
 
@@ -3634,7 +4420,7 @@
         sampleRate = kSamplingRate[freqIndex];
     }
 
-    if (objectType == AOT_SBR || objectType == AOT_PS) {//SBR specific config per 14496-3 table 1.13
+    if (objectType == AOT_SBR || objectType == AOT_PS) {//SBR specific config per 14496-3 tbl 1.13
         if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
         uint32_t extFreqIndex = br.getBits(4);
         int32_t extSampleRate __unused;
@@ -3651,7 +4437,7 @@
             extSampleRate = kSamplingRate[extFreqIndex];
         }
         //TODO: save the extension sampling rate value in meta data =>
-        //      mLastTrack->meta.setInt32(kKeyExtSampleRate, extSampleRate);
+        //      AMediaFormat_setInt32(mLastTrack->meta, kKeyExtSampleRate, extSampleRate);
     }
 
     switch (numChannels) {
@@ -3804,39 +4590,55 @@
         return ERROR_MALFORMED;
 
     int32_t prevSampleRate;
-    CHECK(mLastTrack->meta.findInt32(kKeySampleRate, &prevSampleRate));
+    CHECK(AMediaFormat_getInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, &prevSampleRate));
 
     if (prevSampleRate != sampleRate) {
         ALOGV("mpeg4 audio sample rate different from previous setting. "
              "was: %d, now: %d", prevSampleRate, sampleRate);
     }
 
-    mLastTrack->meta.setInt32(kKeySampleRate, sampleRate);
+    AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, sampleRate);
 
     int32_t prevChannelCount;
-    CHECK(mLastTrack->meta.findInt32(kKeyChannelCount, &prevChannelCount));
+    CHECK(AMediaFormat_getInt32(mLastTrack->meta,
+            AMEDIAFORMAT_KEY_CHANNEL_COUNT, &prevChannelCount));
 
     if (prevChannelCount != numChannels) {
         ALOGV("mpeg4 audio channel count different from previous setting. "
              "was: %d, now: %d", prevChannelCount, numChannels);
     }
 
-    mLastTrack->meta.setInt32(kKeyChannelCount, numChannels);
+    AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, numChannels);
 
     return OK;
 }
 
+void MPEG4Extractor::adjustRawDefaultFrameSize() {
+    int32_t chanCount = 0;
+    int32_t bitWidth = 0;
+    const char *mimeStr = NULL;
+
+    if(AMediaFormat_getString(mLastTrack->meta, AMEDIAFORMAT_KEY_MIME, &mimeStr) &&
+        !strcasecmp(mimeStr, MEDIA_MIMETYPE_AUDIO_RAW) &&
+        AMediaFormat_getInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &chanCount) &&
+        AMediaFormat_getInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, &bitWidth)) {
+        // samplesize in stsz may not right , so updade default samplesize
+        mLastTrack->sampleTable->setPredictSampleSize(chanCount * bitWidth / 8);
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 
 MPEG4Source::MPEG4Source(
-        MetaDataBase &format,
-        DataSourceBase *dataSource,
+        AMediaFormat *format,
+        DataSourceHelper *dataSource,
         int32_t timeScale,
         const sp<SampleTable> &sampleTable,
         Vector<SidxEntry> &sidx,
         const Trex *trex,
         off64_t firstMoofOffset,
-        const sp<ItemTable> &itemTable)
+        const sp<ItemTable> &itemTable,
+        uint64_t elstShiftStartTicks)
     : mFormat(format),
       mDataSource(dataSource),
       mTimescale(timeScale),
@@ -3857,45 +4659,50 @@
       mCurrentSampleInfoOffsets(NULL),
       mIsAVC(false),
       mIsHEVC(false),
+      mIsAC4(false),
+      mIsPcm(false),
       mNALLengthSize(0),
       mStarted(false),
-      mGroup(NULL),
       mBuffer(NULL),
-      mWantsNALFragments(false),
       mSrcBuffer(NULL),
       mIsHeif(itemTable != NULL),
-      mItemTable(itemTable) {
+      mItemTable(itemTable),
+      mElstShiftStartTicks(elstShiftStartTicks) {
 
     memset(&mTrackFragmentHeaderInfo, 0, sizeof(mTrackFragmentHeaderInfo));
 
-    mFormat.findInt32(kKeyCryptoMode, &mCryptoMode);
+    AMediaFormat_getInt32(mFormat,
+            AMEDIAFORMAT_KEY_CRYPTO_MODE, &mCryptoMode);
     mDefaultIVSize = 0;
-    mFormat.findInt32(kKeyCryptoDefaultIVSize, &mDefaultIVSize);
-    uint32_t keytype;
-    const void *key;
+    AMediaFormat_getInt32(mFormat,
+            AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE, &mDefaultIVSize);
+    void *key;
     size_t keysize;
-    if (mFormat.findData(kKeyCryptoKey, &keytype, &key, &keysize)) {
+    if (AMediaFormat_getBuffer(mFormat,
+            AMEDIAFORMAT_KEY_CRYPTO_KEY, &key, &keysize)) {
         CHECK(keysize <= 16);
         memset(mCryptoKey, 0, 16);
         memcpy(mCryptoKey, key, keysize);
     }
 
-    mFormat.findInt32(kKeyEncryptedByteBlock, &mDefaultEncryptedByteBlock);
-    mFormat.findInt32(kKeySkipByteBlock, &mDefaultSkipByteBlock);
+    AMediaFormat_getInt32(mFormat,
+            AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK, &mDefaultEncryptedByteBlock);
+    AMediaFormat_getInt32(mFormat,
+            AMEDIAFORMAT_KEY_CRYPTO_SKIP_BYTE_BLOCK, &mDefaultSkipByteBlock);
 
     const char *mime;
-    bool success = mFormat.findCString(kKeyMIMEType, &mime);
+    bool success = AMediaFormat_getString(mFormat, AMEDIAFORMAT_KEY_MIME, &mime);
     CHECK(success);
 
     mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
     mIsHEVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC) ||
               !strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC);
+    mIsAC4 = !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC4);
 
     if (mIsAVC) {
-        uint32_t type;
-        const void *data;
+        void *data;
         size_t size;
-        CHECK(format.findData(kKeyAVCC, &type, &data, &size));
+        CHECK(AMediaFormat_getBuffer(format, AMEDIAFORMAT_KEY_CSD_AVC, &data, &size));
 
         const uint8_t *ptr = (const uint8_t *)data;
 
@@ -3905,10 +4712,9 @@
         // The number of bytes used to encode the length of a NAL unit.
         mNALLengthSize = 1 + (ptr[4] & 3);
     } else if (mIsHEVC) {
-        uint32_t type;
-        const void *data;
+        void *data;
         size_t size;
-        CHECK(format.findData(kKeyHVCC, &type, &data, &size));
+        CHECK(AMediaFormat_getBuffer(format, AMEDIAFORMAT_KEY_CSD_HEVC, &data, &size));
 
         const uint8_t *ptr = (const uint8_t *)data;
 
@@ -3918,16 +4724,60 @@
         mNALLengthSize = 1 + (ptr[14 + 7] & 3);
     }
 
-    CHECK(format.findInt32(kKeyTrackID, &mTrackId));
+    mIsPcm = !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW);
+    mIsAudio = !strncasecmp(mime, "audio/", 6);
+
+    if (mIsPcm) {
+        int32_t numChannels = 0;
+        int32_t bitsPerSample = 0;
+        CHECK(AMediaFormat_getInt32(mFormat, AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, &bitsPerSample));
+        CHECK(AMediaFormat_getInt32(mFormat, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &numChannels));
+
+        int32_t bytesPerSample = bitsPerSample >> 3;
+        int32_t pcmSampleSize = bytesPerSample * numChannels;
+
+        size_t maxSampleSize;
+        status_t err = mSampleTable->getMaxSampleSize(&maxSampleSize);
+        if (err != OK || maxSampleSize != static_cast<size_t>(pcmSampleSize)
+               || bitsPerSample != 16) {
+            // Not supported
+            mIsPcm = false;
+        } else {
+            AMediaFormat_setInt32(mFormat,
+                    AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, pcmSampleSize * kMaxPcmFrameSize);
+        }
+    }
+
+    CHECK(AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_TRACK_ID, &mTrackId));
 
 }
 
 status_t MPEG4Source::init() {
+    status_t err = OK;
+    const char *mime;
+    CHECK(AMediaFormat_getString(mFormat, AMEDIAFORMAT_KEY_MIME, &mime));
     if (mFirstMoofOffset != 0) {
         off64_t offset = mFirstMoofOffset;
-        return parseChunk(&offset);
+        err = parseChunk(&offset);
+        if(err == OK && !strncasecmp("video/", mime, 6)
+            && !mCurrentSamples.isEmpty()) {
+            // Start offset should be less or equal to composition time of first sample.
+            // ISO : sample_composition_time_offset, version 0 (unsigned) for major brands.
+            mElstShiftStartTicks = std::min(mElstShiftStartTicks,
+                                            (uint64_t)(*mCurrentSamples.begin()).compositionOffset);
+        }
+        return err;
     }
-    return OK;
+
+    if (!strncasecmp("video/", mime, 6)) {
+        uint64_t firstSampleCTS = 0;
+        err = mSampleTable->getMetaDataForSample(0, NULL, NULL, &firstSampleCTS);
+        // Start offset should be less or equal to composition time of first sample.
+        // Composition time stamp of first sample cannot be negative.
+        mElstShiftStartTicks = std::min(mElstShiftStartTicks, firstSampleCTS);
+    }
+
+    return err;
 }
 
 MPEG4Source::~MPEG4Source() {
@@ -3938,21 +4788,13 @@
     free(mCurrentSampleInfoOffsets);
 }
 
-status_t MPEG4Source::start(MetaDataBase *params) {
+media_status_t MPEG4Source::start() {
     Mutex::Autolock autoLock(mLock);
 
     CHECK(!mStarted);
 
-    int32_t val;
-    if (params && params->findInt32(kKeyWantsNALFragments, &val)
-        && val != 0) {
-        mWantsNALFragments = true;
-    } else {
-        mWantsNALFragments = false;
-    }
-
     int32_t tmp;
-    CHECK(mFormat.findInt32(kKeyMaxInputSize, &tmp));
+    CHECK(AMediaFormat_getInt32(mFormat, AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, &tmp));
     size_t max_size = tmp;
 
     // A somewhat arbitrary limit that should be sufficient for 8k video frames
@@ -3960,32 +4802,30 @@
     const size_t kMaxBufferSize = 64 * 1024 * 1024;
     if (max_size > kMaxBufferSize) {
         ALOGE("bogus max input size: %zu > %zu", max_size, kMaxBufferSize);
-        return ERROR_MALFORMED;
+        return AMEDIA_ERROR_MALFORMED;
     }
     if (max_size == 0) {
         ALOGE("zero max input size");
-        return ERROR_MALFORMED;
+        return AMEDIA_ERROR_MALFORMED;
     }
 
     // Allow up to kMaxBuffers, but not if the total exceeds kMaxBufferSize.
     const size_t kInitialBuffers = 2;
     const size_t kMaxBuffers = 8;
     const size_t realMaxBuffers = min(kMaxBufferSize / max_size, kMaxBuffers);
-    mGroup = new MediaBufferGroup(kInitialBuffers, max_size, realMaxBuffers);
+    mBufferGroup->init(kInitialBuffers, max_size, realMaxBuffers);
     mSrcBuffer = new (std::nothrow) uint8_t[max_size];
     if (mSrcBuffer == NULL) {
         // file probably specified a bad max size
-        delete mGroup;
-        mGroup = NULL;
-        return ERROR_MALFORMED;
+        return AMEDIA_ERROR_MALFORMED;
     }
 
     mStarted = true;
 
-    return OK;
+    return AMEDIA_OK;
 }
 
-status_t MPEG4Source::stop() {
+media_status_t MPEG4Source::stop() {
     Mutex::Autolock autoLock(mLock);
 
     CHECK(mStarted);
@@ -3998,13 +4838,10 @@
     delete[] mSrcBuffer;
     mSrcBuffer = NULL;
 
-    delete mGroup;
-    mGroup = NULL;
-
     mStarted = false;
     mCurrentSampleIndex = 0;
 
-    return OK;
+    return AMEDIA_OK;
 }
 
 status_t MPEG4Source::parseChunk(off64_t *offset) {
@@ -4040,8 +4877,8 @@
 
     switch(chunk_type) {
 
-        case FOURCC('t', 'r', 'a', 'f'):
-        case FOURCC('m', 'o', 'o', 'f'): {
+        case FOURCC("traf"):
+        case FOURCC("moof"): {
             off64_t stop_offset = *offset + chunk_size;
             *offset = data_offset;
             while (*offset < stop_offset) {
@@ -4050,7 +4887,7 @@
                     return err;
                 }
             }
-            if (chunk_type == FOURCC('m', 'o', 'o', 'f')) {
+            if (chunk_type == FOURCC("moof")) {
                 // *offset points to the box following this moof. Find the next moof from there.
 
                 while (true) {
@@ -4079,7 +4916,7 @@
                         return ERROR_MALFORMED;
                     }
 
-                    if (chunk_type == FOURCC('m', 'o', 'o', 'f')) {
+                    if (chunk_type == FOURCC("moof")) {
                         mNextMoofOffset = *offset;
                         break;
                     } else if (chunk_size == 0) {
@@ -4091,7 +4928,7 @@
             break;
         }
 
-        case FOURCC('t', 'f', 'h', 'd'): {
+        case FOURCC("tfhd"): {
                 status_t err;
                 if ((err = parseTrackFragmentHeader(data_offset, chunk_data_size)) != OK) {
                     return err;
@@ -4100,7 +4937,7 @@
                 break;
         }
 
-        case FOURCC('t', 'r', 'u', 'n'): {
+        case FOURCC("trun"): {
                 status_t err;
                 if (mLastParsedTrackId == mTrackId) {
                     if ((err = parseTrackFragmentRun(data_offset, chunk_data_size)) != OK) {
@@ -4112,7 +4949,7 @@
                 break;
         }
 
-        case FOURCC('s', 'a', 'i', 'z'): {
+        case FOURCC("saiz"): {
             status_t err;
             if ((err = parseSampleAuxiliaryInformationSizes(data_offset, chunk_data_size)) != OK) {
                 return err;
@@ -4120,16 +4957,17 @@
             *offset += chunk_size;
             break;
         }
-        case FOURCC('s', 'a', 'i', 'o'): {
+        case FOURCC("saio"): {
             status_t err;
-            if ((err = parseSampleAuxiliaryInformationOffsets(data_offset, chunk_data_size)) != OK) {
+            if ((err = parseSampleAuxiliaryInformationOffsets(data_offset, chunk_data_size))
+                    != OK) {
                 return err;
             }
             *offset += chunk_size;
             break;
         }
 
-        case FOURCC('s', 'e', 'n', 'c'): {
+        case FOURCC("senc"): {
             status_t err;
             if ((err = parseSampleEncryption(data_offset)) != OK) {
                 return err;
@@ -4138,7 +4976,7 @@
             break;
         }
 
-        case FOURCC('m', 'd', 'a', 't'): {
+        case FOURCC("mdat"): {
             // parse DRM info if present
             ALOGV("MPEG4Source::parseChunk mdat");
             // if saiz/saoi was previously observed, do something with the sampleinfos
@@ -4253,7 +5091,8 @@
     if (entrycount > mCurrentSampleInfoOffsetsAllocSize) {
         uint64_t *newPtr = (uint64_t *)realloc(mCurrentSampleInfoOffsets, entrycount * 8);
         if (newPtr == NULL) {
-            ALOGE("failed to realloc %u -> %u", mCurrentSampleInfoOffsetsAllocSize, entrycount * 8);
+            ALOGE("failed to realloc %u -> %u",
+                    mCurrentSampleInfoOffsetsAllocSize, entrycount * 8);
             return NO_MEMORY;
         }
         mCurrentSampleInfoOffsets = newPtr;
@@ -4292,10 +5131,13 @@
     return parseClearEncryptedSizes(drmoffset, false, 0);
 }
 
-status_t MPEG4Source::parseClearEncryptedSizes(off64_t offset, bool isSubsampleEncryption, uint32_t flags) {
+status_t MPEG4Source::parseClearEncryptedSizes(
+        off64_t offset, bool isSubsampleEncryption, uint32_t flags) {
 
-    int ivlength;
-    CHECK(mFormat.findInt32(kKeyCryptoDefaultIVSize, &ivlength));
+    int32_t ivlength;
+    if (!AMediaFormat_getInt32(mFormat, AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE, &ivlength)) {
+        return ERROR_MALFORMED;
+    }
 
     // only 0, 8 and 16 byte initialization vectors are supported
     if (ivlength != 0 && ivlength != 8 && ivlength != 16) {
@@ -4478,7 +5320,7 @@
 
 status_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) {
 
-    ALOGV("MPEG4Extractor::parseTrackFragmentRun");
+    ALOGV("MPEG4Source::parseTrackFragmentRun");
     if (size < 8) {
         return -EINVAL;
     }
@@ -4585,8 +5427,30 @@
         sampleCtsOffset = 0;
     }
 
-    if (size < (off64_t)(sampleCount * bytesPerSample)) {
-        return -EINVAL;
+    if (bytesPerSample != 0) {
+        if (size < (off64_t)sampleCount * bytesPerSample) {
+            return -EINVAL;
+        }
+    } else {
+        if (sampleDuration == 0) {
+            ALOGW("b/123389881 sampleDuration == 0");
+            android_errorWriteLog(0x534e4554, "124389881 zero");
+            return -EINVAL;
+        }
+
+        // apply some sanity (vs strict legality) checks
+        //
+        // clamp the count of entries in the trun box, to avoid spending forever parsing
+        // this box. Clamping (vs error) lets us play *something*.
+        // 1 million is about 400 msecs on a Pixel3, should be no more than a couple seconds
+        // on the slowest devices.
+        static constexpr uint32_t kMaxTrunSampleCount = 1000000;
+        if (sampleCount > kMaxTrunSampleCount) {
+            ALOGW("b/123389881 clamp sampleCount(%u) @ kMaxTrunSampleCount(%u)",
+                  sampleCount, kMaxTrunSampleCount);
+            android_errorWriteLog(0x534e4554, "124389881 count");
+
+        }
     }
 
     Sample tmp;
@@ -4620,10 +5484,10 @@
         }
 
         ALOGV("adding sample %d at offset 0x%08" PRIx64 ", size %u, duration %u, "
-              " flags 0x%08x", i + 1,
+              " flags 0x%08x ctsOffset %" PRIu32, i + 1,
                 dataOffset, sampleSize, sampleDuration,
                 (flags & kFirstSampleFlagsPresent) && i == 0
-                    ? firstSampleFlags : sampleFlags);
+                    ? firstSampleFlags : sampleFlags, sampleCtsOffset);
         tmp.offset = dataOffset;
         tmp.size = sampleSize;
         tmp.duration = sampleDuration;
@@ -4639,10 +5503,10 @@
     return OK;
 }
 
-status_t MPEG4Source::getFormat(MetaDataBase &meta) {
+media_status_t MPEG4Source::getFormat(AMediaFormat *meta) {
     Mutex::Autolock autoLock(mLock);
-    meta = mFormat;
-    return OK;
+    AMediaFormat_copy(meta, mFormat);
+    return AMEDIA_OK;
 }
 
 size_t MPEG4Source::parseNALSize(const uint8_t *data) const {
@@ -4664,15 +5528,46 @@
     return 0;
 }
 
-status_t MPEG4Source::read(
-        MediaBufferBase **out, const ReadOptions *options) {
+int32_t MPEG4Source::parseHEVCLayerId(const uint8_t *data, size_t size) {
+    if (data == nullptr || size < mNALLengthSize + 2) {
+        return -1;
+    }
+
+    // HEVC NAL-header (16-bit)
+    //  1   6      6     3
+    // |-|uuuuuu|------|iii|
+    //      ^            ^
+    //  NAL_type        layer_id + 1
+    //
+    // Layer-id is non-zero only for Temporal Sub-layer Access pictures (TSA)
+    enum {
+        TSA_N = 2,
+        TSA_R = 3,
+        STSA_N = 4,
+        STSA_R = 5,
+    };
+
+    data += mNALLengthSize;
+    uint16_t nalHeader = data[0] << 8 | data[1];
+
+    uint16_t nalType = (nalHeader >> 9) & 0x3Fu;
+    if (nalType == TSA_N || nalType == TSA_R || nalType == STSA_N || nalType == STSA_R) {
+        int32_t layerIdPlusOne = nalHeader & 0x7u;
+        ALOGD_IF(layerIdPlusOne == 0, "got layerId 0 for TSA picture");
+        return layerIdPlusOne - 1;
+    }
+    return 0;
+}
+
+media_status_t MPEG4Source::read(
+        MediaBufferHelper **out, const ReadOptions *options) {
     Mutex::Autolock autoLock(mLock);
 
     CHECK(mStarted);
 
-    if (options != nullptr && options->getNonBlocking() && !mGroup->has_buffers()) {
+    if (options != nullptr && options->getNonBlocking() && !mBufferGroup->has_buffers()) {
         *out = nullptr;
-        return WOULD_BLOCK;
+        return AMEDIA_ERROR_WOULD_BLOCK;
     }
 
     if (mFirstMoofOffset > 0) {
@@ -4686,12 +5581,13 @@
     int64_t seekTimeUs;
     ReadOptions::SeekMode mode;
     if (options && options->getSeekTo(&seekTimeUs, &mode)) {
+
         if (mIsHeif) {
             CHECK(mSampleTable == NULL);
             CHECK(mItemTable != NULL);
             int32_t imageIndex;
-            if (!mFormat.findInt32(kKeyTrackID, &imageIndex)) {
-                return ERROR_MALFORMED;
+            if (!AMediaFormat_getInt32(mFormat, AMEDIAFORMAT_KEY_TRACK_ID, &imageIndex)) {
+                return AMEDIA_ERROR_MALFORMED;
             }
 
             status_t err;
@@ -4701,7 +5597,7 @@
                 err = mItemTable->findThumbnailItem(imageIndex, &mCurrentSampleIndex);
             }
             if (err != OK) {
-                return err;
+                return AMEDIA_ERROR_UNKNOWN;
             }
         } else {
             uint32_t findFlags = 0;
@@ -4723,6 +5619,9 @@
                     CHECK(!"Should not be here.");
                     break;
             }
+            if( mode != ReadOptions::SEEK_FRAME_INDEX) {
+                seekTimeUs += ((long double)mElstShiftStartTicks * 1000000) / mTimescale;
+            }
 
             uint32_t sampleIndex;
             status_t err = mSampleTable->findSampleAtTime(
@@ -4737,13 +5636,16 @@
                 findFlags = SampleTable::kFlagBefore;
             }
 
-            uint32_t syncSampleIndex;
-            if (err == OK) {
+            uint32_t syncSampleIndex = sampleIndex;
+            // assume every audio sample is a sync sample. This works around
+            // seek issues with files that were incorrectly written with an
+            // empty or single-sample stss block for the audio track
+            if (err == OK && !mIsAudio) {
                 err = mSampleTable->findSyncSampleNear(
                         sampleIndex, &syncSampleIndex, findFlags);
             }
 
-            uint32_t sampleTime;
+            uint64_t sampleTime;
             if (err == OK) {
                 err = mSampleTable->getMetaDataForSample(
                         sampleIndex, NULL, NULL, &sampleTime);
@@ -4756,14 +5658,15 @@
                     // this all the way to the MediaPlayer would cause abnormal
                     // termination. Legacy behaviour appears to be to behave as if
                     // we had seeked to the end of stream, ending normally.
-                    err = ERROR_END_OF_STREAM;
+                    return AMEDIA_ERROR_END_OF_STREAM;
                 }
                 ALOGV("end of stream");
-                return err;
+                return AMEDIA_ERROR_UNKNOWN;
             }
 
             if (mode == ReadOptions::SEEK_CLOSEST
                 || mode == ReadOptions::SEEK_FRAME_INDEX) {
+                sampleTime -= mElstShiftStartTicks;
                 targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale;
             }
 
@@ -4792,7 +5695,7 @@
 
     off64_t offset = 0;
     size_t size = 0;
-    uint32_t cts, stts;
+    uint64_t cts, stts;
     bool isSyncSample;
     bool newBuffer = false;
     if (mBuffer == NULL) {
@@ -4802,6 +5705,14 @@
         if (!mIsHeif) {
             err = mSampleTable->getMetaDataForSample(
                     mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample, &stts);
+            if(err == OK) {
+                /* Composition Time Stamp cannot be negative. Some files have video Sample
+                * Time(STTS)delta with zero value(b/117402420).  Hence subtract only
+                * min(cts, mElstShiftStartTicks), so that audio tracks can be played.
+                */
+                cts -= std::min(cts, mElstShiftStartTicks);
+            }
+
         } else {
             err = mItemTable->getImageOffsetAndSize(
                     options && options->getSeekTo(&seekTimeUs, &mode) ?
@@ -4813,191 +5724,156 @@
         }
 
         if (err != OK) {
-            return err;
+            if (err == ERROR_END_OF_STREAM) {
+                return AMEDIA_ERROR_END_OF_STREAM;
+            }
+            return AMEDIA_ERROR_UNKNOWN;
         }
 
-        err = mGroup->acquire_buffer(&mBuffer);
+        err = mBufferGroup->acquire_buffer(&mBuffer);
 
         if (err != OK) {
             CHECK(mBuffer == NULL);
-            return err;
+            return AMEDIA_ERROR_UNKNOWN;
         }
         if (size > mBuffer->size()) {
             ALOGE("buffer too small: %zu > %zu", size, mBuffer->size());
             mBuffer->release();
             mBuffer = NULL;
-            return ERROR_BUFFER_TOO_SMALL;
+            return AMEDIA_ERROR_UNKNOWN; // ERROR_BUFFER_TOO_SMALL
         }
     }
 
-    if ((!mIsAVC && !mIsHEVC) || mWantsNALFragments) {
+    if (!mIsAVC && !mIsHEVC && !mIsAC4) {
         if (newBuffer) {
-            ssize_t num_bytes_read =
-                mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
+            if (mIsPcm) {
+                // The twos' PCM block reader assumes that all samples has the same size.
 
-            if (num_bytes_read < (ssize_t)size) {
-                mBuffer->release();
-                mBuffer = NULL;
+                uint32_t samplesToRead = mSampleTable->getLastSampleIndexInChunk()
+                                                      - mCurrentSampleIndex + 1;
+                if (samplesToRead > kMaxPcmFrameSize) {
+                    samplesToRead = kMaxPcmFrameSize;
+                }
 
-                return ERROR_IO;
+                ALOGV("Reading %d PCM frames of size %zu at index %d to stop of chunk at %d",
+                      samplesToRead, size, mCurrentSampleIndex,
+                      mSampleTable->getLastSampleIndexInChunk());
+
+               size_t totalSize = samplesToRead * size;
+                uint8_t* buf = (uint8_t *)mBuffer->data();
+                ssize_t bytesRead = mDataSource->readAt(offset, buf, totalSize);
+                if (bytesRead < (ssize_t)totalSize) {
+                    mBuffer->release();
+                    mBuffer = NULL;
+
+                    return AMEDIA_ERROR_IO;
+                }
+
+                AMediaFormat *meta = mBuffer->meta_data();
+                AMediaFormat_clear(meta);
+                AMediaFormat_setInt64(
+                      meta, AMEDIAFORMAT_KEY_TIME_US, ((long double)cts * 1000000) / mTimescale);
+                AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
+
+                int32_t byteOrder;
+                AMediaFormat_getInt32(mFormat,
+                        AMEDIAFORMAT_KEY_PCM_BIG_ENDIAN, &byteOrder);
+
+                if (byteOrder == 1) {
+                    // Big-endian -> little-endian
+                    uint16_t *dstData = (uint16_t *)buf;
+                    uint16_t *srcData = (uint16_t *)buf;
+
+                    for (size_t j = 0; j < bytesRead / sizeof(uint16_t); j++) {
+                         dstData[j] = ntohs(srcData[j]);
+                    }
+                }
+
+                mCurrentSampleIndex += samplesToRead;
+                mBuffer->set_range(0, totalSize);
+            } else {
+                ssize_t num_bytes_read =
+                    mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
+
+                if (num_bytes_read < (ssize_t)size) {
+                    mBuffer->release();
+                    mBuffer = NULL;
+
+                    return AMEDIA_ERROR_IO;
+                }
+
+                CHECK(mBuffer != NULL);
+                mBuffer->set_range(0, size);
+                AMediaFormat *meta = mBuffer->meta_data();
+                AMediaFormat_clear(meta);
+                AMediaFormat_setInt64(
+                        meta, AMEDIAFORMAT_KEY_TIME_US, ((long double)cts * 1000000) / mTimescale);
+                AMediaFormat_setInt64(
+                        meta, AMEDIAFORMAT_KEY_DURATION, ((long double)stts * 1000000) / mTimescale);
+
+                if (targetSampleTimeUs >= 0) {
+                    AMediaFormat_setInt64(
+                            meta, AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
+                }
+
+                if (isSyncSample) {
+                    AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
+                }
+ 
+                ++mCurrentSampleIndex;
             }
-
-            CHECK(mBuffer != NULL);
-            mBuffer->set_range(0, size);
-            mBuffer->meta_data().clear();
-            mBuffer->meta_data().setInt64(
-                    kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
-            mBuffer->meta_data().setInt64(
-                    kKeyDuration, ((int64_t)stts * 1000000) / mTimescale);
-
-            if (targetSampleTimeUs >= 0) {
-                mBuffer->meta_data().setInt64(
-                        kKeyTargetTime, targetSampleTimeUs);
-            }
-
-            if (isSyncSample) {
-                mBuffer->meta_data().setInt32(kKeyIsSyncFrame, 1);
-            }
-
-            ++mCurrentSampleIndex;
         }
 
-        if (!mIsAVC && !mIsHEVC) {
-            *out = mBuffer;
-            mBuffer = NULL;
+        *out = mBuffer;
+        mBuffer = NULL;
 
-            return OK;
-        }
+        return AMEDIA_OK;
 
-        // Each NAL unit is split up into its constituent fragments and
-        // each one of them returned in its own buffer.
-
-        CHECK(mBuffer->range_length() >= mNALLengthSize);
-
-        const uint8_t *src =
-            (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
-
-        size_t nal_size = parseNALSize(src);
-        if (mNALLengthSize > SIZE_MAX - nal_size) {
-            ALOGE("b/24441553, b/24445122");
-        }
-        if (mBuffer->range_length() - mNALLengthSize < nal_size) {
-            ALOGE("incomplete NAL unit.");
-
-            mBuffer->release();
-            mBuffer = NULL;
-
-            return ERROR_MALFORMED;
-        }
-
-        MediaBufferBase *clone = mBuffer->clone();
-        CHECK(clone != NULL);
-        clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
-
+    } else if (mIsAC4) {
         CHECK(mBuffer != NULL);
-        mBuffer->set_range(
-                mBuffer->range_offset() + mNALLengthSize + nal_size,
-                mBuffer->range_length() - mNALLengthSize - nal_size);
-
-        if (mBuffer->range_length() == 0) {
-            mBuffer->release();
-            mBuffer = NULL;
-        }
-
-        *out = clone;
-
-        return OK;
-    } else {
-        // Whole NAL units are returned but each fragment is prefixed by
-        // the start code (0x00 00 00 01).
-        ssize_t num_bytes_read = 0;
-        int32_t drm = 0;
-        bool usesDRM = (mFormat.findInt32(kKeyIsDRM, &drm) && drm != 0);
-        if (usesDRM) {
-            num_bytes_read =
-                mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size);
-        } else {
-            num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size);
-        }
-
-        if (num_bytes_read < (ssize_t)size) {
+        // Make sure there is enough space to write the sync header and the raw frame
+        if (mBuffer->range_length() < (7 + size)) {
             mBuffer->release();
             mBuffer = NULL;
 
-            return ERROR_IO;
+            return AMEDIA_ERROR_IO;
         }
 
-        if (usesDRM) {
-            CHECK(mBuffer != NULL);
-            mBuffer->set_range(0, size);
+        uint8_t *dstData = (uint8_t *)mBuffer->data();
+        size_t dstOffset = 0;
+        // Add AC-4 sync header to MPEG4 encapsulated AC-4 raw frame
+        // AC40 sync word, meaning no CRC at the end of the frame
+        dstData[dstOffset++] = 0xAC;
+        dstData[dstOffset++] = 0x40;
+        dstData[dstOffset++] = 0xFF;
+        dstData[dstOffset++] = 0xFF;
+        dstData[dstOffset++] = (uint8_t)((size >> 16) & 0xFF);
+        dstData[dstOffset++] = (uint8_t)((size >> 8) & 0xFF);
+        dstData[dstOffset++] = (uint8_t)((size >> 0) & 0xFF);
 
-        } else {
-            uint8_t *dstData = (uint8_t *)mBuffer->data();
-            size_t srcOffset = 0;
-            size_t dstOffset = 0;
+        ssize_t numBytesRead = mDataSource->readAt(offset, dstData + dstOffset, size);
+        if (numBytesRead != (ssize_t)size) {
+            mBuffer->release();
+            mBuffer = NULL;
 
-            while (srcOffset < size) {
-                bool isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize);
-                size_t nalLength = 0;
-                if (!isMalFormed) {
-                    nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
-                    srcOffset += mNALLengthSize;
-                    isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength);
-                }
-
-                if (isMalFormed) {
-                    ALOGE("Video is malformed");
-                    mBuffer->release();
-                    mBuffer = NULL;
-                    return ERROR_MALFORMED;
-                }
-
-                if (nalLength == 0) {
-                    continue;
-                }
-
-                if (dstOffset > SIZE_MAX - 4 ||
-                        dstOffset + 4 > SIZE_MAX - nalLength ||
-                        dstOffset + 4 + nalLength > mBuffer->size()) {
-                    ALOGE("b/27208621 : %zu %zu", dstOffset, mBuffer->size());
-                    android_errorWriteLog(0x534e4554, "27208621");
-                    mBuffer->release();
-                    mBuffer = NULL;
-                    return ERROR_MALFORMED;
-                }
-
-                dstData[dstOffset++] = 0;
-                dstData[dstOffset++] = 0;
-                dstData[dstOffset++] = 0;
-                dstData[dstOffset++] = 1;
-                memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
-                srcOffset += nalLength;
-                dstOffset += nalLength;
-            }
-            CHECK_EQ(srcOffset, size);
-            CHECK(mBuffer != NULL);
-            mBuffer->set_range(0, dstOffset);
+            return AMEDIA_ERROR_IO;
         }
 
-        mBuffer->meta_data().clear();
-        mBuffer->meta_data().setInt64(
-                kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
-        mBuffer->meta_data().setInt64(
-                kKeyDuration, ((int64_t)stts * 1000000) / mTimescale);
+        mBuffer->set_range(0, dstOffset + size);
+        AMediaFormat *meta = mBuffer->meta_data();
+        AMediaFormat_clear(meta);
+        AMediaFormat_setInt64(
+                meta, AMEDIAFORMAT_KEY_TIME_US, ((long double)cts * 1000000) / mTimescale);
+        AMediaFormat_setInt64(
+                meta, AMEDIAFORMAT_KEY_DURATION, ((long double)stts * 1000000) / mTimescale);
 
         if (targetSampleTimeUs >= 0) {
-            mBuffer->meta_data().setInt64(
-                    kKeyTargetTime, targetSampleTimeUs);
-        }
-
-        if (mIsAVC) {
-            uint32_t layerId = FindAVCLayerId(
-                    (const uint8_t *)mBuffer->data(), mBuffer->range_length());
-            mBuffer->meta_data().setInt32(kKeyTemporalLayerId, layerId);
+            AMediaFormat_setInt64(
+                    meta, AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
         }
 
         if (isSyncSample) {
-            mBuffer->meta_data().setInt32(kKeyIsSyncFrame, 1);
+            AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
         }
 
         ++mCurrentSampleIndex;
@@ -5005,12 +5881,105 @@
         *out = mBuffer;
         mBuffer = NULL;
 
-        return OK;
+        return AMEDIA_OK;
+    } else {
+        // Whole NAL units are returned but each fragment is prefixed by
+        // the start code (0x00 00 00 01).
+        ssize_t num_bytes_read = 0;
+        num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size);
+
+        if (num_bytes_read < (ssize_t)size) {
+            mBuffer->release();
+            mBuffer = NULL;
+
+            return AMEDIA_ERROR_IO;
+        }
+
+        uint8_t *dstData = (uint8_t *)mBuffer->data();
+        size_t srcOffset = 0;
+        size_t dstOffset = 0;
+
+        while (srcOffset < size) {
+            bool isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize);
+            size_t nalLength = 0;
+            if (!isMalFormed) {
+                nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
+                srcOffset += mNALLengthSize;
+                isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength);
+            }
+
+            if (isMalFormed) {
+                //if nallength abnormal,ignore it.
+                ALOGW("abnormal nallength, ignore this NAL");
+                srcOffset = size;
+                break;
+            }
+
+            if (nalLength == 0) {
+                continue;
+            }
+
+            if (dstOffset > SIZE_MAX - 4 ||
+                    dstOffset + 4 > SIZE_MAX - nalLength ||
+                    dstOffset + 4 + nalLength > mBuffer->size()) {
+                ALOGE("b/27208621 : %zu %zu", dstOffset, mBuffer->size());
+                android_errorWriteLog(0x534e4554, "27208621");
+                mBuffer->release();
+                mBuffer = NULL;
+                return AMEDIA_ERROR_MALFORMED;
+            }
+
+            dstData[dstOffset++] = 0;
+            dstData[dstOffset++] = 0;
+            dstData[dstOffset++] = 0;
+            dstData[dstOffset++] = 1;
+            memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
+            srcOffset += nalLength;
+            dstOffset += nalLength;
+        }
+        CHECK_EQ(srcOffset, size);
+        CHECK(mBuffer != NULL);
+        mBuffer->set_range(0, dstOffset);
+
+        AMediaFormat *meta = mBuffer->meta_data();
+        AMediaFormat_clear(meta);
+        AMediaFormat_setInt64(
+                meta, AMEDIAFORMAT_KEY_TIME_US, ((long double)cts * 1000000) / mTimescale);
+        AMediaFormat_setInt64(
+                meta, AMEDIAFORMAT_KEY_DURATION, ((long double)stts * 1000000) / mTimescale);
+
+        if (targetSampleTimeUs >= 0) {
+            AMediaFormat_setInt64(
+                    meta, AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
+        }
+
+        if (mIsAVC) {
+            uint32_t layerId = FindAVCLayerId(
+                    (const uint8_t *)mBuffer->data(), mBuffer->range_length());
+            AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID, layerId);
+        } else if (mIsHEVC) {
+            int32_t layerId = parseHEVCLayerId(
+                    (const uint8_t *)mBuffer->data(), mBuffer->range_length());
+            if (layerId >= 0) {
+                AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID, layerId);
+            }
+        }
+
+        if (isSyncSample) {
+            AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
+        }
+
+        ++mCurrentSampleIndex;
+
+        *out = mBuffer;
+        mBuffer = NULL;
+
+        return AMEDIA_OK;
     }
 }
 
-status_t MPEG4Source::fragmentedRead(
-        MediaBufferBase **out, const ReadOptions *options) {
+media_status_t MPEG4Source::fragmentedRead(
+        MediaBufferHelper **out, const ReadOptions *options) {
 
     ALOGV("MPEG4Source::fragmentedRead");
 
@@ -5024,6 +5993,10 @@
     ReadOptions::SeekMode mode;
     if (options && options->getSeekTo(&seekTimeUs, &mode)) {
 
+        seekTimeUs += ((long double)mElstShiftStartTicks * 1000000) / mTimescale;
+        ALOGV("shifted seekTimeUs :%" PRId64 ", mElstShiftStartTicks:%" PRIu64, seekTimeUs,
+              mElstShiftStartTicks);
+
         int numSidxEntries = mSegments.size();
         if (numSidxEntries != 0) {
             int64_t totalTime = 0;
@@ -5051,7 +6024,7 @@
             mCurrentSampleIndex = 0;
             status_t err = parseChunk(&totalOffset);
             if (err != OK) {
-                return err;
+                return AMEDIA_ERROR_UNKNOWN;
             }
             mCurrentTime = totalTime * mTimescale / 1000000ll;
         } else {
@@ -5063,7 +6036,7 @@
             off64_t tmp = mCurrentMoofOffset;
             status_t err = parseChunk(&tmp);
             if (err != OK) {
-                return err;
+                return AMEDIA_ERROR_UNKNOWN;
             }
             mCurrentTime = 0;
         }
@@ -5078,16 +6051,20 @@
 
     off64_t offset = 0;
     size_t size = 0;
-    uint32_t cts = 0;
+    uint64_t cts = 0;
     bool isSyncSample = false;
     bool newBuffer = false;
-    if (mBuffer == NULL) {
+    if (mBuffer == NULL || mCurrentSampleIndex >= mCurrentSamples.size()) {
         newBuffer = true;
 
+        if (mBuffer != NULL) {
+            mBuffer->release();
+            mBuffer = NULL;
+        }
         if (mCurrentSampleIndex >= mCurrentSamples.size()) {
             // move to next fragment if there is one
             if (mNextMoofOffset <= mCurrentMoofOffset) {
-                return ERROR_END_OF_STREAM;
+                return AMEDIA_ERROR_END_OF_STREAM;
             }
             off64_t nextMoof = mNextMoofOffset;
             mCurrentMoofOffset = nextMoof;
@@ -5095,10 +6072,10 @@
             mCurrentSampleIndex = 0;
             status_t err = parseChunk(&nextMoof);
             if (err != OK) {
-                return err;
+                return AMEDIA_ERROR_UNKNOWN;
             }
             if (mCurrentSampleIndex >= mCurrentSamples.size()) {
-                return ERROR_END_OF_STREAM;
+                return AMEDIA_ERROR_END_OF_STREAM;
             }
         }
 
@@ -5106,59 +6083,65 @@
         offset = smpl->offset;
         size = smpl->size;
         cts = mCurrentTime + smpl->compositionOffset;
-        mCurrentTime += smpl->duration;
-        isSyncSample = (mCurrentSampleIndex == 0); // XXX
+        /* Composition Time Stamp cannot be negative. Some files have video Sample
+        * Time(STTS)delta with zero value(b/117402420).  Hence subtract only
+        * min(cts, mElstShiftStartTicks), so that audio tracks can be played.
+        */
+        cts -= std::min(cts, mElstShiftStartTicks);
 
-        status_t err = mGroup->acquire_buffer(&mBuffer);
+        mCurrentTime += smpl->duration;
+        isSyncSample = (mCurrentSampleIndex == 0);
+
+        status_t err = mBufferGroup->acquire_buffer(&mBuffer);
 
         if (err != OK) {
             CHECK(mBuffer == NULL);
             ALOGV("acquire_buffer returned %d", err);
-            return err;
+            return AMEDIA_ERROR_UNKNOWN;
         }
         if (size > mBuffer->size()) {
             ALOGE("buffer too small: %zu > %zu", size, mBuffer->size());
             mBuffer->release();
             mBuffer = NULL;
-            return ERROR_BUFFER_TOO_SMALL;
+            return AMEDIA_ERROR_UNKNOWN;
         }
     }
 
     const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex];
-    MetaDataBase &bufmeta = mBuffer->meta_data();
-    bufmeta.clear();
+    AMediaFormat *bufmeta = mBuffer->meta_data();
+    AMediaFormat_clear(bufmeta);
     if (smpl->encryptedsizes.size()) {
         // store clear/encrypted lengths in metadata
-        bufmeta.setData(kKeyPlainSizes, 0,
+        AMediaFormat_setBuffer(bufmeta, AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES,
                 smpl->clearsizes.array(), smpl->clearsizes.size() * 4);
-        bufmeta.setData(kKeyEncryptedSizes, 0,
+        AMediaFormat_setBuffer(bufmeta, AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES,
                 smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * 4);
-        bufmeta.setInt32(kKeyCryptoDefaultIVSize, mDefaultIVSize);
-        bufmeta.setInt32(kKeyCryptoMode, mCryptoMode);
-        bufmeta.setData(kKeyCryptoKey, 0, mCryptoKey, 16);
-        bufmeta.setInt32(kKeyEncryptedByteBlock, mDefaultEncryptedByteBlock);
-        bufmeta.setInt32(kKeySkipByteBlock, mDefaultSkipByteBlock);
+        AMediaFormat_setInt32(bufmeta, AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE, mDefaultIVSize);
+        AMediaFormat_setInt32(bufmeta, AMEDIAFORMAT_KEY_CRYPTO_MODE, mCryptoMode);
+        AMediaFormat_setBuffer(bufmeta, AMEDIAFORMAT_KEY_CRYPTO_KEY, mCryptoKey, 16);
+        AMediaFormat_setInt32(bufmeta,
+                AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK, mDefaultEncryptedByteBlock);
+        AMediaFormat_setInt32(bufmeta,
+                AMEDIAFORMAT_KEY_CRYPTO_SKIP_BYTE_BLOCK, mDefaultSkipByteBlock);
 
-        uint32_t type = 0;
-        const void *iv = NULL;
+        void *iv = NULL;
         size_t ivlength = 0;
-        if (!mFormat.findData(
-                kKeyCryptoIV, &type, &iv, &ivlength)) {
-            iv = smpl->iv;
+        if (!AMediaFormat_getBuffer(mFormat,
+                "crypto-iv", &iv, &ivlength)) {
+            iv = (void *) smpl->iv;
             ivlength = 16; // use 16 or the actual size?
         }
-        bufmeta.setData(kKeyCryptoIV, 0, iv, ivlength);
-
+        AMediaFormat_setBuffer(bufmeta, AMEDIAFORMAT_KEY_CRYPTO_IV, iv, ivlength);
     }
 
-    if ((!mIsAVC && !mIsHEVC)|| mWantsNALFragments) {
+    if (!mIsAVC && !mIsHEVC) {
         if (newBuffer) {
             if (!isInRange((size_t)0u, mBuffer->size(), size)) {
                 mBuffer->release();
                 mBuffer = NULL;
 
                 ALOGE("fragmentedRead ERROR_MALFORMED size %zu", size);
-                return ERROR_MALFORMED;
+                return AMEDIA_ERROR_MALFORMED;
             }
 
             ssize_t num_bytes_read =
@@ -5169,103 +6152,57 @@
                 mBuffer = NULL;
 
                 ALOGE("i/o error");
-                return ERROR_IO;
+                return AMEDIA_ERROR_IO;
             }
 
             CHECK(mBuffer != NULL);
             mBuffer->set_range(0, size);
-            mBuffer->meta_data().setInt64(
-                    kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
-            mBuffer->meta_data().setInt64(
-                    kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale);
+            AMediaFormat_setInt64(bufmeta,
+                    AMEDIAFORMAT_KEY_TIME_US, ((long double)cts * 1000000) / mTimescale);
+            AMediaFormat_setInt64(bufmeta,
+                    AMEDIAFORMAT_KEY_DURATION, ((long double)smpl->duration * 1000000) / mTimescale);
 
             if (targetSampleTimeUs >= 0) {
-                mBuffer->meta_data().setInt64(
-                        kKeyTargetTime, targetSampleTimeUs);
+                AMediaFormat_setInt64(bufmeta, AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
             }
 
             if (mIsAVC) {
                 uint32_t layerId = FindAVCLayerId(
                         (const uint8_t *)mBuffer->data(), mBuffer->range_length());
-                mBuffer->meta_data().setInt32(kKeyTemporalLayerId, layerId);
+                AMediaFormat_setInt32(bufmeta, AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID, layerId);
+            } else if (mIsHEVC) {
+                int32_t layerId = parseHEVCLayerId(
+                        (const uint8_t *)mBuffer->data(), mBuffer->range_length());
+                if (layerId >= 0) {
+                    AMediaFormat_setInt32(bufmeta, AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID, layerId);
+                }
             }
 
             if (isSyncSample) {
-                mBuffer->meta_data().setInt32(kKeyIsSyncFrame, 1);
+                AMediaFormat_setInt32(bufmeta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
             }
 
             ++mCurrentSampleIndex;
         }
 
-        if (!mIsAVC && !mIsHEVC) {
-            *out = mBuffer;
-            mBuffer = NULL;
+        *out = mBuffer;
+        mBuffer = NULL;
 
-            return OK;
-        }
+        return AMEDIA_OK;
 
-        // Each NAL unit is split up into its constituent fragments and
-        // each one of them returned in its own buffer.
-
-        CHECK(mBuffer->range_length() >= mNALLengthSize);
-
-        const uint8_t *src =
-            (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
-
-        size_t nal_size = parseNALSize(src);
-        if (mNALLengthSize > SIZE_MAX - nal_size) {
-            ALOGE("b/24441553, b/24445122");
-        }
-
-        if (mBuffer->range_length() - mNALLengthSize < nal_size) {
-            ALOGE("incomplete NAL unit.");
-
-            mBuffer->release();
-            mBuffer = NULL;
-
-            return ERROR_MALFORMED;
-        }
-
-        MediaBufferBase *clone = mBuffer->clone();
-        CHECK(clone != NULL);
-        clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
-
-        CHECK(mBuffer != NULL);
-        mBuffer->set_range(
-                mBuffer->range_offset() + mNALLengthSize + nal_size,
-                mBuffer->range_length() - mNALLengthSize - nal_size);
-
-        if (mBuffer->range_length() == 0) {
-            mBuffer->release();
-            mBuffer = NULL;
-        }
-
-        *out = clone;
-
-        return OK;
     } else {
         ALOGV("whole NAL");
         // Whole NAL units are returned but each fragment is prefixed by
         // the start code (0x00 00 00 01).
         ssize_t num_bytes_read = 0;
-        int32_t drm = 0;
-        bool usesDRM = (mFormat.findInt32(kKeyIsDRM, &drm) && drm != 0);
         void *data = NULL;
         bool isMalFormed = false;
-        if (usesDRM) {
-            if (mBuffer == NULL || !isInRange((size_t)0u, mBuffer->size(), size)) {
-                isMalFormed = true;
-            } else {
-                data = mBuffer->data();
-            }
+        int32_t max_size;
+        if (!AMediaFormat_getInt32(mFormat, AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, &max_size)
+                || !isInRange((size_t)0u, (size_t)max_size, size)) {
+            isMalFormed = true;
         } else {
-            int32_t max_size;
-            if (!mFormat.findInt32(kKeyMaxInputSize, &max_size)
-                    || !isInRange((size_t)0u, (size_t)max_size, size)) {
-                isMalFormed = true;
-            } else {
-                data = mSrcBuffer;
-            }
+            data = mSrcBuffer;
         }
 
         if (isMalFormed || data == NULL) {
@@ -5274,7 +6211,7 @@
                 mBuffer->release();
                 mBuffer = NULL;
             }
-            return ERROR_MALFORMED;
+            return AMEDIA_ERROR_MALFORMED;
         }
         num_bytes_read = mDataSource->readAt(offset, data, size);
 
@@ -5283,75 +6220,69 @@
             mBuffer = NULL;
 
             ALOGE("i/o error");
-            return ERROR_IO;
+            return AMEDIA_ERROR_IO;
         }
 
-        if (usesDRM) {
-            CHECK(mBuffer != NULL);
-            mBuffer->set_range(0, size);
+        uint8_t *dstData = (uint8_t *)mBuffer->data();
+        size_t srcOffset = 0;
+        size_t dstOffset = 0;
 
-        } else {
-            uint8_t *dstData = (uint8_t *)mBuffer->data();
-            size_t srcOffset = 0;
-            size_t dstOffset = 0;
-
-            while (srcOffset < size) {
-                isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize);
-                size_t nalLength = 0;
-                if (!isMalFormed) {
-                    nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
-                    srcOffset += mNALLengthSize;
-                    isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength)
-                            || !isInRange((size_t)0u, mBuffer->size(), dstOffset, (size_t)4u)
-                            || !isInRange((size_t)0u, mBuffer->size(), dstOffset + 4, nalLength);
-                }
-
-                if (isMalFormed) {
-                    ALOGE("Video is malformed; nalLength %zu", nalLength);
-                    mBuffer->release();
-                    mBuffer = NULL;
-                    return ERROR_MALFORMED;
-                }
-
-                if (nalLength == 0) {
-                    continue;
-                }
-
-                if (dstOffset > SIZE_MAX - 4 ||
-                        dstOffset + 4 > SIZE_MAX - nalLength ||
-                        dstOffset + 4 + nalLength > mBuffer->size()) {
-                    ALOGE("b/26365349 : %zu %zu", dstOffset, mBuffer->size());
-                    android_errorWriteLog(0x534e4554, "26365349");
-                    mBuffer->release();
-                    mBuffer = NULL;
-                    return ERROR_MALFORMED;
-                }
-
-                dstData[dstOffset++] = 0;
-                dstData[dstOffset++] = 0;
-                dstData[dstOffset++] = 0;
-                dstData[dstOffset++] = 1;
-                memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
-                srcOffset += nalLength;
-                dstOffset += nalLength;
+        while (srcOffset < size) {
+            isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize);
+            size_t nalLength = 0;
+            if (!isMalFormed) {
+                nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
+                srcOffset += mNALLengthSize;
+                isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength)
+                        || !isInRange((size_t)0u, mBuffer->size(), dstOffset, (size_t)4u)
+                        || !isInRange((size_t)0u, mBuffer->size(), dstOffset + 4, nalLength);
             }
-            CHECK_EQ(srcOffset, size);
-            CHECK(mBuffer != NULL);
-            mBuffer->set_range(0, dstOffset);
-        }
 
-        mBuffer->meta_data().setInt64(
-                kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
-        mBuffer->meta_data().setInt64(
-                kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale);
+            if (isMalFormed) {
+                ALOGE("Video is malformed; nalLength %zu", nalLength);
+                mBuffer->release();
+                mBuffer = NULL;
+                return AMEDIA_ERROR_MALFORMED;
+            }
+
+            if (nalLength == 0) {
+                continue;
+            }
+
+            if (dstOffset > SIZE_MAX - 4 ||
+                    dstOffset + 4 > SIZE_MAX - nalLength ||
+                    dstOffset + 4 + nalLength > mBuffer->size()) {
+                ALOGE("b/26365349 : %zu %zu", dstOffset, mBuffer->size());
+                android_errorWriteLog(0x534e4554, "26365349");
+                mBuffer->release();
+                mBuffer = NULL;
+                return AMEDIA_ERROR_MALFORMED;
+            }
+
+            dstData[dstOffset++] = 0;
+            dstData[dstOffset++] = 0;
+            dstData[dstOffset++] = 0;
+            dstData[dstOffset++] = 1;
+            memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
+            srcOffset += nalLength;
+            dstOffset += nalLength;
+        }
+        CHECK_EQ(srcOffset, size);
+        CHECK(mBuffer != NULL);
+        mBuffer->set_range(0, dstOffset);
+
+        AMediaFormat *bufmeta = mBuffer->meta_data();
+        AMediaFormat_setInt64(bufmeta,
+                AMEDIAFORMAT_KEY_TIME_US, ((long double)cts * 1000000) / mTimescale);
+        AMediaFormat_setInt64(bufmeta,
+                AMEDIAFORMAT_KEY_DURATION, ((long double)smpl->duration * 1000000) / mTimescale);
 
         if (targetSampleTimeUs >= 0) {
-            mBuffer->meta_data().setInt64(
-                    kKeyTargetTime, targetSampleTimeUs);
+            AMediaFormat_setInt64(bufmeta, AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
         }
 
         if (isSyncSample) {
-            mBuffer->meta_data().setInt32(kKeyIsSyncFrame, 1);
+            AMediaFormat_setInt32(bufmeta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
         }
 
         ++mCurrentSampleIndex;
@@ -5359,15 +6290,17 @@
         *out = mBuffer;
         mBuffer = NULL;
 
-        return OK;
+        return AMEDIA_OK;
     }
+
+    return AMEDIA_OK;
 }
 
 MPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix(
         const char *mimePrefix) {
     for (Track *track = mFirstTrack; track != NULL; track = track->next) {
         const char *mime;
-        if (track->meta.findCString(kKeyMIMEType, &mime)
+        if (AMediaFormat_getString(track->meta, AMEDIAFORMAT_KEY_MIME, &mime)
                 && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) {
             return track;
         }
@@ -5376,7 +6309,7 @@
     return NULL;
 }
 
-static bool LegacySniffMPEG4(DataSourceBase *source, float *confidence) {
+static bool LegacySniffMPEG4(DataSourceHelper *source, float *confidence) {
     uint8_t header[8];
 
     ssize_t n = source->readAt(4, header, sizeof(header));
@@ -5402,27 +6335,30 @@
 
 static bool isCompatibleBrand(uint32_t fourcc) {
     static const uint32_t kCompatibleBrands[] = {
-        FOURCC('i', 's', 'o', 'm'),
-        FOURCC('i', 's', 'o', '2'),
-        FOURCC('a', 'v', 'c', '1'),
-        FOURCC('h', 'v', 'c', '1'),
-        FOURCC('h', 'e', 'v', '1'),
-        FOURCC('3', 'g', 'p', '4'),
-        FOURCC('m', 'p', '4', '1'),
-        FOURCC('m', 'p', '4', '2'),
-        FOURCC('d', 'a', 's', 'h'),
+        FOURCC("isom"),
+        FOURCC("iso2"),
+        FOURCC("avc1"),
+        FOURCC("hvc1"),
+        FOURCC("hev1"),
+        FOURCC("av01"),
+        FOURCC("3gp4"),
+        FOURCC("mp41"),
+        FOURCC("mp42"),
+        FOURCC("dash"),
+        FOURCC("nvr1"),
 
         // Won't promise that the following file types can be played.
         // Just give these file types a chance.
-        FOURCC('q', 't', ' ', ' '),  // Apple's QuickTime
-        FOURCC('M', 'S', 'N', 'V'),  // Sony's PSP
+        FOURCC("qt  "),  // Apple's QuickTime
+        FOURCC("MSNV"),  // Sony's PSP
+        FOURCC("wmf "),
 
-        FOURCC('3', 'g', '2', 'a'),  // 3GPP2
-        FOURCC('3', 'g', '2', 'b'),
-        FOURCC('m', 'i', 'f', '1'),  // HEIF image
-        FOURCC('h', 'e', 'i', 'c'),  // HEIF image
-        FOURCC('m', 's', 'f', '1'),  // HEIF image sequence
-        FOURCC('h', 'e', 'v', 'c'),  // HEIF image sequence
+        FOURCC("3g2a"),  // 3GPP2
+        FOURCC("3g2b"),
+        FOURCC("mif1"),  // HEIF image
+        FOURCC("heic"),  // HEIF image
+        FOURCC("msf1"),  // HEIF image sequence
+        FOURCC("hevc"),  // HEIF image sequence
     };
 
     for (size_t i = 0;
@@ -5441,7 +6377,7 @@
 // Also try to identify where this file's metadata ends
 // (end of the 'moov' atom) and report it to the caller as part of
 // the metadata.
-static bool BetterSniffMPEG4(DataSourceBase *source, float *confidence) {
+static bool BetterSniffMPEG4(DataSourceHelper *source, float *confidence) {
     // We scan up to 128 bytes to identify this file as an MP4.
     static const off64_t kMaxScanOffset = 128ll;
 
@@ -5487,9 +6423,10 @@
 
         char chunkstring[5];
         MakeFourCCString(chunkType, chunkstring);
-        ALOGV("saw chunk type %s, size %" PRIu64 " @ %lld", chunkstring, chunkSize, (long long)offset);
+        ALOGV("saw chunk type %s, size %" PRIu64 " @ %lld",
+                chunkstring, chunkSize, (long long)offset);
         switch (chunkType) {
-            case FOURCC('f', 't', 'y', 'p'):
+            case FOURCC("ftyp"):
             {
                 if (chunkDataSize < 8) {
                     return false;
@@ -5524,7 +6461,7 @@
                 break;
             }
 
-            case FOURCC('m', 'o', 'o', 'v'):
+            case FOURCC("moov"):
             {
                 moovAtomEndOffset = offset + chunkSize;
 
@@ -5548,18 +6485,19 @@
     return true;
 }
 
-static MediaExtractor* CreateExtractor(DataSourceBase *source, void *) {
-    return new MPEG4Extractor(source);
+static CMediaExtractor* CreateExtractor(CDataSource *source, void *) {
+    return wrap(new MPEG4Extractor(new DataSourceHelper(source)));
 }
 
-static MediaExtractor::CreatorFunc Sniff(
-        DataSourceBase *source, float *confidence, void **,
-        MediaExtractor::FreeMetaFunc *) {
-    if (BetterSniffMPEG4(source, confidence)) {
+static CreatorFunc Sniff(
+        CDataSource *source, float *confidence, void **,
+        FreeMetaFunc *) {
+    DataSourceHelper helper(source);
+    if (BetterSniffMPEG4(&helper, confidence)) {
         return CreateExtractor;
     }
 
-    if (LegacySniffMPEG4(source, confidence)) {
+    if (LegacySniffMPEG4(&helper, confidence)) {
         ALOGW("Identified supported mpeg4 through LegacySniffMPEG4.");
         return CreateExtractor;
     }
@@ -5567,16 +6505,31 @@
     return NULL;
 }
 
+static const char *extensions[] = {
+    "3g2",
+    "3ga",
+    "3gp",
+    "3gpp",
+    "3gpp2",
+    "m4a",
+    "m4r",
+    "m4v",
+    "mov",
+    "mp4",
+    "qt",
+    NULL
+};
+
 extern "C" {
 // This is the only symbol that needs to be exported
 __attribute__ ((visibility ("default")))
-MediaExtractor::ExtractorDef GETEXTRACTORDEF() {
+ExtractorDef GETEXTRACTORDEF() {
     return {
-        MediaExtractor::EXTRACTORDEF_VERSION,
+        EXTRACTORDEF_VERSION,
         UUID("27575c67-4417-4c54-8d3d-8e626985a164"),
-        1, // version
+        2, // version
         "MP4 Extractor",
-        Sniff
+        { .v3 = {Sniff, extensions} },
     };
 }
 
diff --git a/media/extractors/mp4/MPEG4Extractor.h b/media/extractors/mp4/MPEG4Extractor.h
index 3ea0963..fcddbb8 100644
--- a/media/extractors/mp4/MPEG4Extractor.h
+++ b/media/extractors/mp4/MPEG4Extractor.h
@@ -20,9 +20,9 @@
 
 #include <arpa/inet.h>
 
-#include <media/DataSourceBase.h>
-#include <media/MediaExtractor.h>
-#include <media/stagefright/MetaDataBase.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
+#include <media/NdkMediaFormat.h>
 #include <media/stagefright/foundation/AString.h>
 #include <utils/KeyedVector.h>
 #include <utils/List.h>
@@ -31,8 +31,8 @@
 
 namespace android {
 struct AMessage;
-class DataSourceBase;
-struct CachedRangedDataSource;
+struct CDataSource;
+class DataSourceHelper;
 class SampleTable;
 class String8;
 namespace heif {
@@ -53,15 +53,15 @@
     uint32_t default_sample_flags;
 };
 
-class MPEG4Extractor : public MediaExtractor {
+class MPEG4Extractor : public MediaExtractorPluginHelper {
 public:
-    explicit MPEG4Extractor(DataSourceBase *source, const char *mime = NULL);
+    explicit MPEG4Extractor(DataSourceHelper *source, const char *mime = NULL);
 
     virtual size_t countTracks();
-    virtual MediaTrack *getTrack(size_t index);
-    virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags);
+    virtual MediaTrackHelper *getTrack(size_t index);
+    virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
 
-    virtual status_t getMetaData(MetaDataBase& meta);
+    virtual media_status_t getMetaData(AMediaFormat *meta);
     virtual uint32_t flags() const;
     virtual const char * name() { return "MPEG4Extractor"; }
 
@@ -77,17 +77,53 @@
     };
     struct Track {
         Track *next;
-        MetaDataBase meta;
+        AMediaFormat *meta;
         uint32_t timescale;
         sp<SampleTable> sampleTable;
         bool includes_expensive_metadata;
         bool skipTrack;
         bool has_elst;
+        /* signed int, ISO Spec allows media_time = -1 for other use cases.
+         * but we don't support empty edits for now.
+         */
         int64_t elst_media_time;
         uint64_t elst_segment_duration;
+        // unsigned int, shift start offset only when media_time > 0.
+        uint64_t elstShiftStartTicks;
         bool subsample_encryption;
+
+        uint8_t *mTx3gBuffer;
+        size_t mTx3gSize, mTx3gFilled;
+
+
+        Track() {
+            next = NULL;
+            meta = NULL;
+            timescale = 0;
+            includes_expensive_metadata = false;
+            skipTrack = false;
+            has_elst = false;
+            elst_media_time = 0;
+            elstShiftStartTicks = 0;
+            subsample_encryption = false;
+            mTx3gBuffer = NULL;
+            mTx3gSize = mTx3gFilled = 0;
+        }
+        ~Track() {
+            if (meta) {
+                AMediaFormat_delete(meta);
+                meta = NULL;
+            }
+            free (mTx3gBuffer);
+            mTx3gBuffer = NULL;
+        }
+
+      private:
+        DISALLOW_EVIL_CONSTRUCTORS(Track);
     };
 
+    static const int kTx3gGrowth = 16 * 1024;
+
     Vector<SidxEntry> mSidxEntries;
     off64_t mMoofOffset;
     bool mMoofFound;
@@ -97,8 +133,7 @@
 
     Vector<Trex> mTrex;
 
-    DataSourceBase *mDataSource;
-    CachedRangedDataSource *mCachedSource;
+    DataSourceHelper *mDataSource;
     status_t mInitCheck;
     uint32_t mHeaderTimescale;
     bool mIsQT;
@@ -108,7 +143,7 @@
 
     Track *mFirstTrack, *mLastTrack;
 
-    MetaDataBase mFileMetaData;
+    AMediaFormat *mFileMetaData;
 
     Vector<uint32_t> mPath;
     String8 mLastCommentMean;
@@ -139,17 +174,18 @@
 
     Track *findTrackByMimePrefix(const char *mimePrefix);
 
-    status_t parseAC3SampleEntry(off64_t offset);
-    status_t parseAC3SpecificBox(off64_t offset, uint16_t sampleRate);
+    status_t parseChannelCountSampleRate(
+            off64_t *offset, uint16_t *channelCount, uint16_t *sampleRate);
+    status_t parseAC3SpecificBox(off64_t offset);
+    status_t parseEAC3SpecificBox(off64_t offset);
+    status_t parseAC4SpecificBox(off64_t offset);
+    status_t parseALACSampleEntry(off64_t *offset);
+    void adjustRawDefaultFrameSize();
 
     MPEG4Extractor(const MPEG4Extractor &);
     MPEG4Extractor &operator=(const MPEG4Extractor &);
 };
 
-bool SniffMPEG4(
-        DataSourceBase *source, String8 *mimeType, float *confidence,
-        sp<AMessage> *);
-
 }  // namespace android
 
 #endif  // MPEG4_EXTRACTOR_H_
diff --git a/media/extractors/mp4/SampleIterator.cpp b/media/extractors/mp4/SampleIterator.cpp
index 93ee7c6..2890b26 100644
--- a/media/extractors/mp4/SampleIterator.cpp
+++ b/media/extractors/mp4/SampleIterator.cpp
@@ -111,8 +111,15 @@
             if ((err = getSampleSizeDirect(
                             firstChunkSampleIndex + i, &sampleSize)) != OK) {
                 ALOGE("getSampleSizeDirect return error");
-                mCurrentChunkSampleSizes.clear();
-                return err;
+                // stsc sample count is not sync with stsz sample count
+                if (err == ERROR_OUT_OF_RANGE) {
+                    ALOGW("stsc samples(%d) not sync with stsz samples(%d)", mSamplesPerChunk, i);
+                    mSamplesPerChunk = i;
+                    break;
+                } else{
+                    mCurrentChunkSampleSizes.clear();
+                    return err;
+                }
             }
 
             mCurrentChunkSampleSizes.push(sampleSize);
@@ -301,7 +308,7 @@
 }
 
 status_t SampleIterator::findSampleTimeAndDuration(
-        uint32_t sampleIndex, uint32_t *time, uint32_t *duration) {
+        uint32_t sampleIndex, uint64_t *time, uint64_t *duration) {
     if (sampleIndex >= mTable->mNumSampleSizes) {
         return ERROR_OUT_OF_RANGE;
     }
@@ -314,8 +321,8 @@
             break;
         }
         if (mTimeToSampleIndex == mTable->mTimeToSampleCount ||
-            (mTTSDuration != 0 && mTTSCount > UINT32_MAX / mTTSDuration) ||
-            mTTSSampleTime > UINT32_MAX - (mTTSCount * mTTSDuration)) {
+            (mTTSDuration != 0 && mTTSCount > UINT64_MAX / mTTSDuration) ||
+            mTTSSampleTime > UINT64_MAX - (mTTSCount * mTTSDuration)) {
             return ERROR_OUT_OF_RANGE;
         }
 
@@ -328,19 +335,27 @@
         ++mTimeToSampleIndex;
     }
 
-    *time = mTTSSampleTime + mTTSDuration * (sampleIndex - mTTSSampleIndex);
+    // below is equivalent to:
+    // *time = mTTSSampleTime + mTTSDuration * (sampleIndex - mTTSSampleIndex);
+    uint64_t tmp;
+    if (__builtin_sub_overflow(sampleIndex, mTTSSampleIndex, &tmp) ||
+            __builtin_mul_overflow(mTTSDuration, tmp, &tmp) ||
+            __builtin_add_overflow(mTTSSampleTime, tmp, &tmp)) {
+        return ERROR_OUT_OF_RANGE;
+    }
+    *time = tmp;
 
     int32_t offset = mTable->getCompositionTimeOffset(sampleIndex);
     if ((offset < 0 && *time < (offset == INT32_MIN ?
-            INT32_MAX : uint32_t(-offset))) ||
-            (offset > 0 && *time > UINT32_MAX - offset)) {
-        ALOGE("%u + %d would overflow", *time, offset);
+            INT64_MAX : uint64_t(-offset))) ||
+            (offset > 0 && *time > UINT64_MAX - offset)) {
+        ALOGE("%llu + %d would overflow", (unsigned long long) *time, offset);
         return ERROR_OUT_OF_RANGE;
     }
     if (offset > 0) {
         *time += offset;
     } else {
-        *time -= (offset == INT32_MIN ? INT32_MAX : (-offset));
+        *time -= (offset == INT64_MIN ? INT64_MAX : (-offset));
     }
 
     *duration = mTTSDuration;
diff --git a/media/extractors/mp4/SampleIterator.h b/media/extractors/mp4/SampleIterator.h
index 6a3fd3b..5a0ea76 100644
--- a/media/extractors/mp4/SampleIterator.h
+++ b/media/extractors/mp4/SampleIterator.h
@@ -33,8 +33,13 @@
     uint32_t getDescIndex() const { return mChunkDesc; }
     off64_t getSampleOffset() const { return mCurrentSampleOffset; }
     size_t getSampleSize() const { return mCurrentSampleSize; }
-    uint32_t getSampleTime() const { return mCurrentSampleTime; }
-    uint32_t getSampleDuration() const { return mCurrentSampleDuration; }
+    uint64_t getSampleTime() const { return mCurrentSampleTime; }
+    uint64_t getSampleDuration() const { return mCurrentSampleDuration; }
+
+    uint32_t getLastSampleIndexInChunk() const {
+        return mCurrentSampleIndex + mSamplesPerChunk -
+                ((mCurrentSampleIndex - mFirstChunkSampleIndex) % mSamplesPerChunk) - 1;
+    }
 
     status_t getSampleSizeDirect(
             uint32_t sampleIndex, size_t *size);
@@ -58,20 +63,20 @@
 
     uint32_t mTimeToSampleIndex;
     uint32_t mTTSSampleIndex;
-    uint32_t mTTSSampleTime;
+    uint64_t mTTSSampleTime;
     uint32_t mTTSCount;
-    uint32_t mTTSDuration;
+    uint64_t mTTSDuration;
 
     uint32_t mCurrentSampleIndex;
     off64_t mCurrentSampleOffset;
     size_t mCurrentSampleSize;
-    uint32_t mCurrentSampleTime;
-    uint32_t mCurrentSampleDuration;
+    uint64_t mCurrentSampleTime;
+    uint64_t mCurrentSampleDuration;
 
     void reset();
     status_t findChunkRange(uint32_t sampleIndex);
     status_t getChunkOffset(uint32_t chunk, off64_t *offset);
-    status_t findSampleTimeAndDuration(uint32_t sampleIndex, uint32_t *time, uint32_t *duration);
+    status_t findSampleTimeAndDuration(uint32_t sampleIndex, uint64_t *time, uint64_t *duration);
 
     SampleIterator(const SampleIterator &);
     SampleIterator &operator=(const SampleIterator &);
diff --git a/media/extractors/mp4/SampleTable.cpp b/media/extractors/mp4/SampleTable.cpp
index 81c353e..bf29bf1 100644
--- a/media/extractors/mp4/SampleTable.cpp
+++ b/media/extractors/mp4/SampleTable.cpp
@@ -25,7 +25,7 @@
 
 #include <arpa/inet.h>
 
-#include <media/DataSourceBase.h>
+#include <media/MediaExtractorPluginApi.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ByteUtils.h>
 
@@ -37,13 +37,13 @@
 namespace android {
 
 // static
-const uint32_t SampleTable::kChunkOffsetType32 = FOURCC('s', 't', 'c', 'o');
+const uint32_t SampleTable::kChunkOffsetType32 = FOURCC("stco");
 // static
-const uint32_t SampleTable::kChunkOffsetType64 = FOURCC('c', 'o', '6', '4');
+const uint32_t SampleTable::kChunkOffsetType64 = FOURCC("co64");
 // static
-const uint32_t SampleTable::kSampleSizeType32 = FOURCC('s', 't', 's', 'z');
+const uint32_t SampleTable::kSampleSizeType32 = FOURCC("stsz");
 // static
-const uint32_t SampleTable::kSampleSizeTypeCompact = FOURCC('s', 't', 'z', '2');
+const uint32_t SampleTable::kSampleSizeTypeCompact = FOURCC("stz2");
 
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -114,7 +114,7 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-SampleTable::SampleTable(DataSourceBase *source)
+SampleTable::SampleTable(DataSourceHelper *source)
     : mDataSource(source),
       mChunkOffsetOffset(-1),
       mChunkOffsetType(0),
@@ -614,7 +614,7 @@
     return OK;
 }
 
-uint32_t abs_difference(uint32_t time1, uint32_t time2) {
+uint32_t abs_difference(uint64_t time1, uint64_t time2) {
     return time1 > time2 ? time1 - time2 : time2 - time1;
 }
 
@@ -662,7 +662,7 @@
     }
 
     uint32_t sampleIndex = 0;
-    uint32_t sampleTime = 0;
+    uint64_t sampleTime = 0;
 
     for (uint32_t i = 0; i < mTimeToSampleCount; ++i) {
         uint32_t n = mTimeToSample[2 * i];
@@ -684,13 +684,13 @@
                         (compTimeDelta == INT32_MIN ?
                                 INT32_MAX : uint32_t(-compTimeDelta)))
                         || (compTimeDelta > 0 &&
-                                sampleTime > UINT32_MAX - compTimeDelta)) {
-                    ALOGE("%u + %d would overflow, clamping",
-                            sampleTime, compTimeDelta);
+                                sampleTime > UINT64_MAX - compTimeDelta)) {
+                    ALOGE("%llu + %d would overflow, clamping",
+                            (unsigned long long) sampleTime, compTimeDelta);
                     if (compTimeDelta < 0) {
                         sampleTime = 0;
                     } else {
-                        sampleTime = UINT32_MAX;
+                        sampleTime = UINT64_MAX;
                     }
                     compTimeDelta = 0;
                 }
@@ -701,10 +701,10 @@
             }
 
             ++sampleIndex;
-            if (sampleTime > UINT32_MAX - delta) {
-                ALOGE("%u + %u would overflow, clamping",
-                    sampleTime, delta);
-                sampleTime = UINT32_MAX;
+            if (sampleTime > UINT64_MAX - delta) {
+                ALOGE("%llu + %u would overflow, clamping",
+                    (unsigned long long) sampleTime, delta);
+                sampleTime = UINT64_MAX;
             } else {
                 sampleTime += delta;
             }
@@ -870,19 +870,19 @@
             if (err != OK) {
                 return err;
             }
-            uint32_t sample_time = mSampleIterator->getSampleTime();
+            uint64_t sample_time = mSampleIterator->getSampleTime();
 
             err = mSampleIterator->seekTo(mSyncSamples[left]);
             if (err != OK) {
                 return err;
             }
-            uint32_t upper_time = mSampleIterator->getSampleTime();
+            uint64_t upper_time = mSampleIterator->getSampleTime();
 
             err = mSampleIterator->seekTo(mSyncSamples[left - 1]);
             if (err != OK) {
                 return err;
             }
-            uint32_t lower_time = mSampleIterator->getSampleTime();
+            uint64_t lower_time = mSampleIterator->getSampleTime();
 
             // use abs_difference for safety
             if (abs_difference(upper_time, sample_time) >
@@ -946,13 +946,18 @@
             sampleIndex, sampleSize);
 }
 
+uint32_t SampleTable::getLastSampleIndexInChunk() {
+    Mutex::Autolock autoLock(mLock);
+    return mSampleIterator->getLastSampleIndexInChunk();
+}
+
 status_t SampleTable::getMetaDataForSample(
         uint32_t sampleIndex,
         off64_t *offset,
         size_t *size,
-        uint32_t *compositionTime,
+        uint64_t *compositionTime,
         bool *isSyncSample,
-        uint32_t *sampleDuration) {
+        uint64_t *sampleDuration) {
     Mutex::Autolock autoLock(mLock);
 
     status_t err;
diff --git a/media/extractors/mp4/SampleTable.h b/media/extractors/mp4/SampleTable.h
index e4e974b..076f4c3 100644
--- a/media/extractors/mp4/SampleTable.h
+++ b/media/extractors/mp4/SampleTable.h
@@ -21,18 +21,19 @@
 #include <sys/types.h>
 #include <stdint.h>
 
+#include <media/MediaExtractorPluginHelper.h>
 #include <media/stagefright/MediaErrors.h>
 #include <utils/RefBase.h>
 #include <utils/threads.h>
 
 namespace android {
 
-class DataSourceBase;
+class DataSourceHelper;
 struct SampleIterator;
 
 class SampleTable : public RefBase {
 public:
-    explicit SampleTable(DataSourceBase *source);
+    explicit SampleTable(DataSourceHelper *source);
 
     bool isValid() const;
 
@@ -65,9 +66,12 @@
             uint32_t sampleIndex,
             off64_t *offset,
             size_t *size,
-            uint32_t *compositionTime,
+            uint64_t *compositionTime,
             bool *isSyncSample = NULL,
-            uint32_t *sampleDuration = NULL);
+            uint64_t *sampleDuration = NULL);
+
+    // call only after getMetaDataForSample has been called successfully.
+    uint32_t getLastSampleIndexInChunk();
 
     enum {
         kFlagBefore,
@@ -85,6 +89,10 @@
 
     status_t findThumbnailSample(uint32_t *sample_index);
 
+    void setPredictSampleSize(uint32_t sampleSize) {
+        mDefaultSampleSize = sampleSize;
+    }
+
 protected:
     ~SampleTable();
 
@@ -99,7 +107,7 @@
     // Limit the total size of all internal tables to 200MiB.
     static const size_t kMaxTotalSize = 200 * (1 << 20);
 
-    DataSourceBase *mDataSource;
+    DataSourceHelper *mDataSource;
     Mutex mLock;
 
     off64_t mChunkOffsetOffset;
@@ -120,7 +128,7 @@
 
     struct SampleTimeEntry {
         uint32_t mSampleIndex;
-        uint32_t mCompositionTime;
+        uint64_t mCompositionTime;
     };
     SampleTimeEntry *mSampleTimeEntries;
 
diff --git a/media/extractors/mpeg2/Android.bp b/media/extractors/mpeg2/Android.bp
index 5e4a592..0f0c72c 100644
--- a/media/extractors/mpeg2/Android.bp
+++ b/media/extractors/mpeg2/Android.bp
@@ -15,19 +15,26 @@
         "android.hardware.cas@1.0",
         "android.hardware.cas.native@1.0",
         "android.hidl.token@1.0-utils",
-        "libbinder",
-        "libcrypto",
-        "libcutils",
-        "libhidlallocatorutils",
+        "android.hidl.allocator@1.0",
+        "libhidlmemory",
         "libhidlbase",
         "liblog",
-        "libmediaextractor",
-        "libstagefright_foundation",
+        "libmediandk",
+    ],
+
+    header_libs: [
+        "libbase_headers",
+        "libstagefright_headers",
+        "libmedia_headers",
     ],
 
     static_libs: [
+        "libcrypto",
+        "libstagefright_foundation_without_imemory",
         "libstagefright_mpeg2support",
         "libutils",
+        "libstagefright_mpeg2extractor",
+        "libstagefright_esds",
     ],
 
     name: "libmpeg2extractor",
@@ -48,9 +55,6 @@
             "unsigned-integer-overflow",
             "signed-integer-overflow",
         ],
-        diag: {
-            cfi: true,
-        },
     },
 
 }
diff --git a/media/extractors/mpeg2/ExtractorBundle.cpp b/media/extractors/mpeg2/ExtractorBundle.cpp
index 8a0fa03..a7c756b 100644
--- a/media/extractors/mpeg2/ExtractorBundle.cpp
+++ b/media/extractors/mpeg2/ExtractorBundle.cpp
@@ -18,39 +18,56 @@
 #define LOG_TAG "MPEG2ExtractorBundle"
 #include <utils/Log.h>
 
-#include <media/MediaExtractor.h>
+#include <media/MediaExtractorPluginHelper.h>
+#include <media/stagefright/MediaDefs.h>
 #include "MPEG2PSExtractor.h"
 #include "MPEG2TSExtractor.h"
 
 namespace android {
 
+struct CDataSource;
+
+static const char *extensions[] = {
+   "m2p",
+   "m2ts",
+   "mts",
+   "ts",
+   NULL
+};
+
 extern "C" {
 // This is the only symbol that needs to be exported
 __attribute__ ((visibility ("default")))
-MediaExtractor::ExtractorDef GETEXTRACTORDEF() {
+ExtractorDef GETEXTRACTORDEF() {
     return {
-        MediaExtractor::EXTRACTORDEF_VERSION,
+        EXTRACTORDEF_VERSION,
         UUID("3d1dcfeb-e40a-436d-a574-c2438a555e5f"),
         1,
         "MPEG2-PS/TS Extractor",
-        [](
-                DataSourceBase *source,
-                float *confidence,
-                void **,
-                MediaExtractor::FreeMetaFunc *) -> MediaExtractor::CreatorFunc {
-            if (SniffMPEG2TS(source, confidence)) {
-                return [](
-                        DataSourceBase *source,
-                        void *) -> MediaExtractor* {
-                    return new MPEG2TSExtractor(source);};
-            } else if (SniffMPEG2PS(source, confidence)) {
+        {
+            .v3 = {
+                [](
+                    CDataSource *source,
+                    float *confidence,
+                    void **,
+                    FreeMetaFunc *) -> CreatorFunc {
+                    DataSourceHelper helper(source);
+                    if (SniffMPEG2TS(&helper, confidence)) {
                         return [](
-                                DataSourceBase *source,
-                                void *) -> MediaExtractor* {
-                            return new MPEG2PSExtractor(source);};
+                                CDataSource *source,
+                                void *) -> CMediaExtractor* {
+                            return wrap(new MPEG2TSExtractor(new DataSourceHelper(source)));};
+                    } else if (SniffMPEG2PS(&helper, confidence)) {
+                        return [](
+                                CDataSource *source,
+                                void *) -> CMediaExtractor* {
+                            return wrap(new MPEG2PSExtractor(new DataSourceHelper(source)));};
+                    }
+                    return NULL;
+                },
+                extensions
             }
-            return NULL;
-        }
+        },
     };
 }
 
diff --git a/media/extractors/mpeg2/MPEG2PSExtractor.cpp b/media/extractors/mpeg2/MPEG2PSExtractor.cpp
index 6980b82..731584d 100644
--- a/media/extractors/mpeg2/MPEG2PSExtractor.cpp
+++ b/media/extractors/mpeg2/MPEG2PSExtractor.cpp
@@ -24,7 +24,6 @@
 #include "mpeg2ts/ESQueue.h"
 
 #include <media/DataSourceBase.h>
-#include <media/MediaTrack.h>
 #include <media/stagefright/foundation/ABitReader.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
@@ -34,22 +33,23 @@
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MetaData.h>
+#include <media/stagefright/Utils.h>
 #include <utils/String8.h>
 
 #include <inttypes.h>
 
 namespace android {
 
-struct MPEG2PSExtractor::Track : public MediaTrack, public RefBase {
+struct MPEG2PSExtractor::Track : public MediaTrackHelper {
     Track(MPEG2PSExtractor *extractor,
           unsigned stream_id, unsigned stream_type);
 
-    virtual status_t start(MetaDataBase *params);
-    virtual status_t stop();
-    virtual status_t getFormat(MetaDataBase &);
+    virtual media_status_t start();
+    virtual media_status_t stop();
+    virtual media_status_t getFormat(AMediaFormat *);
 
-    virtual status_t read(
-            MediaBufferBase **buffer, const ReadOptions *options);
+    virtual media_status_t read(
+            MediaBufferHelper **buffer, const ReadOptions *options);
 
 protected:
     virtual ~Track();
@@ -72,29 +72,29 @@
     DISALLOW_EVIL_CONSTRUCTORS(Track);
 };
 
-struct MPEG2PSExtractor::WrappedTrack : public MediaTrack {
-    WrappedTrack(MPEG2PSExtractor *extractor, const sp<Track> &track);
+struct MPEG2PSExtractor::WrappedTrack : public MediaTrackHelper {
+    WrappedTrack(MPEG2PSExtractor *extractor, Track *track);
 
-    virtual status_t start(MetaDataBase *params);
-    virtual status_t stop();
-    virtual status_t getFormat(MetaDataBase &);
+    virtual media_status_t start();
+    virtual media_status_t stop();
+    virtual media_status_t getFormat(AMediaFormat *);
 
-    virtual status_t read(
-            MediaBufferBase **buffer, const ReadOptions *options);
+    virtual media_status_t read(
+            MediaBufferHelper **buffer, const ReadOptions *options);
 
 protected:
     virtual ~WrappedTrack();
 
 private:
     MPEG2PSExtractor *mExtractor;
-    sp<MPEG2PSExtractor::Track> mTrack;
+    MPEG2PSExtractor::Track *mTrack;
 
     DISALLOW_EVIL_CONSTRUCTORS(WrappedTrack);
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 
-MPEG2PSExtractor::MPEG2PSExtractor(DataSourceBase *source)
+MPEG2PSExtractor::MPEG2PSExtractor(DataSourceHelper *source)
     : mDataSource(source),
       mOffset(0),
       mFinalResult(OK),
@@ -108,25 +108,27 @@
     }
 
     // Remove all tracks that were unable to determine their format.
-    MetaDataBase meta;
+    AMediaFormat *meta = AMediaFormat_new();
     for (size_t i = mTracks.size(); i > 0;) {
         i--;
-        if (mTracks.valueAt(i)->getFormat(meta) != OK) {
+        if (mTracks.valueAt(i)->getFormat(meta) != AMEDIA_OK) {
             mTracks.removeItemsAt(i);
         }
     }
+    AMediaFormat_delete(meta);
 
     mScanning = false;
 }
 
 MPEG2PSExtractor::~MPEG2PSExtractor() {
+    delete mDataSource;
 }
 
 size_t MPEG2PSExtractor::countTracks() {
     return mTracks.size();
 }
 
-MediaTrack *MPEG2PSExtractor::getTrack(size_t index) {
+MediaTrackHelper *MPEG2PSExtractor::getTrack(size_t index) {
     if (index >= mTracks.size()) {
         return NULL;
     }
@@ -134,20 +136,20 @@
     return new WrappedTrack(this, mTracks.valueAt(index));
 }
 
-status_t MPEG2PSExtractor::getTrackMetaData(
-        MetaDataBase &meta,
+media_status_t MPEG2PSExtractor::getTrackMetaData(
+        AMediaFormat *meta,
         size_t index, uint32_t /* flags */) {
     if (index >= mTracks.size()) {
-        return UNKNOWN_ERROR;
+        return AMEDIA_ERROR_UNKNOWN;
     }
 
     return mTracks.valueAt(index)->getFormat(meta);
 }
 
-status_t MPEG2PSExtractor::getMetaData(MetaDataBase &meta) {
-    meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG2PS);
+media_status_t MPEG2PSExtractor::getMetaData(AMediaFormat *meta) {
+    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_CONTAINER_MPEG2PS);
 
-    return OK;
+    return AMEDIA_OK;
 }
 
 uint32_t MPEG2PSExtractor::flags() const {
@@ -635,42 +637,55 @@
     mQueue = NULL;
 }
 
-status_t MPEG2PSExtractor::Track::start(MetaDataBase *) {
+media_status_t MPEG2PSExtractor::Track::start() {
     if (mSource == NULL) {
-        return NO_INIT;
+        return AMEDIA_ERROR_UNKNOWN;
     }
 
-    return mSource->start(NULL); // AnotherPacketSource::start doesn't use its argument
+    // initialize with one small buffer, but allow growth
+    mBufferGroup->init(1 /* one buffer */, 256 /* buffer size */, 64 /* max number of buffers */);
+
+    if (mSource->start(NULL) == OK) { // AnotherPacketSource::start doesn't use its argument
+        return AMEDIA_OK;
+    }
+    return AMEDIA_ERROR_UNKNOWN;
 }
 
-status_t MPEG2PSExtractor::Track::stop() {
+media_status_t MPEG2PSExtractor::Track::stop() {
     if (mSource == NULL) {
-        return NO_INIT;
+        return AMEDIA_ERROR_UNKNOWN;
     }
 
-    return mSource->stop();
+    if (mSource->stop() == OK) {
+        return AMEDIA_OK;
+    }
+    return AMEDIA_ERROR_UNKNOWN;
 }
 
-status_t MPEG2PSExtractor::Track::getFormat(MetaDataBase &meta) {
+void copyAMessageToAMediaFormat(AMediaFormat *format, sp<AMessage> msg);
+
+media_status_t MPEG2PSExtractor::Track::getFormat(AMediaFormat *meta) {
     if (mSource == NULL) {
-        return NO_INIT;
+        return AMEDIA_ERROR_UNKNOWN;
     }
 
     sp<MetaData> sourceMeta = mSource->getFormat();
-    meta = *sourceMeta;
-    return OK;
+    sp<AMessage> msg;
+    convertMetaDataToMessage(sourceMeta, &msg);
+    copyAMessageToAMediaFormat(meta, msg);
+    return AMEDIA_OK;
 }
 
-status_t MPEG2PSExtractor::Track::read(
-        MediaBufferBase **buffer, const ReadOptions *options) {
+media_status_t MPEG2PSExtractor::Track::read(
+        MediaBufferHelper **buffer, const ReadOptions *options) {
     if (mSource == NULL) {
-        return NO_INIT;
+        return AMEDIA_ERROR_UNKNOWN;
     }
 
     status_t finalResult;
     while (!mSource->hasBufferAvailable(&finalResult)) {
         if (finalResult != OK) {
-            return ERROR_END_OF_STREAM;
+            return AMEDIA_ERROR_END_OF_STREAM;
         }
 
         status_t err = mExtractor->feedMore();
@@ -680,7 +695,50 @@
         }
     }
 
-    return mSource->read(buffer, options);
+    MediaBufferBase *mbuf;
+    mSource->read(&mbuf, (MediaTrack::ReadOptions*) options);
+    size_t length = mbuf->range_length();
+    MediaBufferHelper *outbuf;
+    mBufferGroup->acquire_buffer(&outbuf, false, length);
+    memcpy(outbuf->data(), mbuf->data(), length);
+    outbuf->set_range(0, length);
+    *buffer = outbuf;
+    MetaDataBase &inMeta = mbuf->meta_data();
+    AMediaFormat *outMeta = outbuf->meta_data();
+    int64_t val64;
+    if (inMeta.findInt64(kKeyTime, &val64)) {
+        AMediaFormat_setInt64(outMeta, AMEDIAFORMAT_KEY_TIME_US, val64);
+    }
+    int32_t val32;
+    if (inMeta.findInt32(kKeyIsSyncFrame, &val32)) {
+        AMediaFormat_setInt32(outMeta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, val32);
+    }
+    if (inMeta.findInt32(kKeyCryptoMode, &val32)) {
+        AMediaFormat_setInt32(outMeta, AMEDIAFORMAT_KEY_CRYPTO_MODE, val32);
+    }
+    uint32_t bufType;
+    const void *bufData;
+    size_t bufSize;
+    if (inMeta.findData(kKeyCryptoIV, &bufType, &bufData, &bufSize)) {
+        AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_IV, bufData, bufSize);
+    }
+    if (inMeta.findData(kKeyCryptoKey, &bufType, &bufData, &bufSize)) {
+        AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_KEY, bufData, bufSize);
+    }
+    if (inMeta.findData(kKeyPlainSizes, &bufType, &bufData, &bufSize)) {
+        AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES, bufData, bufSize);
+    }
+    if (inMeta.findData(kKeyEncryptedSizes, &bufType, &bufData, &bufSize)) {
+        AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES, bufData, bufSize);
+    }
+    if (inMeta.findData(kKeySEI, &bufType, &bufData, &bufSize)) {
+        AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_SEI, bufData, bufSize);
+    }
+    if (inMeta.findData(kKeyAudioPresentationInfo, &bufType, &bufData, &bufSize)) {
+        AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO, bufData, bufSize);
+    }
+    mbuf->release();
+    return AMEDIA_OK;
 }
 
 status_t MPEG2PSExtractor::Track::appendPESData(
@@ -726,7 +784,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 MPEG2PSExtractor::WrappedTrack::WrappedTrack(
-        MPEG2PSExtractor *extractor, const sp<Track> &track)
+        MPEG2PSExtractor *extractor, Track *track)
     : mExtractor(extractor),
       mTrack(track) {
 }
@@ -734,27 +792,28 @@
 MPEG2PSExtractor::WrappedTrack::~WrappedTrack() {
 }
 
-status_t MPEG2PSExtractor::WrappedTrack::start(MetaDataBase *params) {
-    return mTrack->start(params);
+media_status_t MPEG2PSExtractor::WrappedTrack::start() {
+    mTrack->mBufferGroup = mBufferGroup;
+    return mTrack->start();
 }
 
-status_t MPEG2PSExtractor::WrappedTrack::stop() {
+media_status_t MPEG2PSExtractor::WrappedTrack::stop() {
     return mTrack->stop();
 }
 
-status_t MPEG2PSExtractor::WrappedTrack::getFormat(MetaDataBase &meta) {
+media_status_t MPEG2PSExtractor::WrappedTrack::getFormat(AMediaFormat *meta) {
     return mTrack->getFormat(meta);
 }
 
-status_t MPEG2PSExtractor::WrappedTrack::read(
-        MediaBufferBase **buffer, const ReadOptions *options) {
+media_status_t MPEG2PSExtractor::WrappedTrack::read(
+        MediaBufferHelper **buffer, const ReadOptions *options) {
     return mTrack->read(buffer, options);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 bool SniffMPEG2PS(
-        DataSourceBase *source, float *confidence) {
+        DataSourceHelper *source, float *confidence) {
     uint8_t header[5];
     if (source->readAt(0, header, sizeof(header)) < (ssize_t)sizeof(header)) {
         return false;
diff --git a/media/extractors/mpeg2/MPEG2PSExtractor.h b/media/extractors/mpeg2/MPEG2PSExtractor.h
index 8b9dad9..e5d591f 100644
--- a/media/extractors/mpeg2/MPEG2PSExtractor.h
+++ b/media/extractors/mpeg2/MPEG2PSExtractor.h
@@ -19,7 +19,8 @@
 #define MPEG2_PS_EXTRACTOR_H_
 
 #include <media/stagefright/foundation/ABase.h>
-#include <media/MediaExtractor.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
 #include <media/stagefright/MetaDataBase.h>
 #include <utils/threads.h>
 #include <utils/KeyedVector.h>
@@ -31,14 +32,14 @@
 struct Track;
 class String8;
 
-struct MPEG2PSExtractor : public MediaExtractor {
-    explicit MPEG2PSExtractor(DataSourceBase *source);
+struct MPEG2PSExtractor : public MediaExtractorPluginHelper {
+    explicit MPEG2PSExtractor(DataSourceHelper *source);
 
     virtual size_t countTracks();
-    virtual MediaTrack *getTrack(size_t index);
-    virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags);
+    virtual MediaTrackHelper *getTrack(size_t index);
+    virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
 
-    virtual status_t getMetaData(MetaDataBase& meta);
+    virtual media_status_t getMetaData(AMediaFormat *meta);
 
     virtual uint32_t flags() const;
     virtual const char * name() { return "MPEG2PSExtractor"; }
@@ -51,12 +52,12 @@
     struct WrappedTrack;
 
     mutable Mutex mLock;
-    DataSourceBase *mDataSource;
+    DataSourceHelper *mDataSource;
 
     off64_t mOffset;
     status_t mFinalResult;
     sp<ABuffer> mBuffer;
-    KeyedVector<unsigned, sp<Track> > mTracks;
+    KeyedVector<unsigned, Track* > mTracks;
     bool mScanning;
 
     bool mProgramStreamMapValid;
@@ -72,7 +73,7 @@
     DISALLOW_EVIL_CONSTRUCTORS(MPEG2PSExtractor);
 };
 
-bool SniffMPEG2PS(DataSourceBase *source, float *confidence);
+bool SniffMPEG2PS(DataSourceHelper *source, float *confidence);
 
 }  // namespace android
 
diff --git a/media/extractors/mpeg2/MPEG2TSExtractor.cpp b/media/extractors/mpeg2/MPEG2TSExtractor.cpp
index c83f7ce..50ce657 100644
--- a/media/extractors/mpeg2/MPEG2TSExtractor.cpp
+++ b/media/extractors/mpeg2/MPEG2TSExtractor.cpp
@@ -20,11 +20,12 @@
 #include <inttypes.h>
 #include <utils/Log.h>
 
+#include <android-base/macros.h>
+
 #include "MPEG2TSExtractor.h"
 
 #include <media/DataSourceBase.h>
 #include <media/IStreamSource.h>
-#include <media/MediaTrack.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ALooper.h>
@@ -33,6 +34,7 @@
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MetaData.h>
+#include <media/stagefright/Utils.h>
 #include <utils/String8.h>
 
 #include "mpeg2ts/AnotherPacketSource.h"
@@ -49,19 +51,19 @@
 static const int kMaxDurationReadSize = 250000LL;
 static const int kMaxDurationRetry = 6;
 
-struct MPEG2TSSource : public MediaTrack {
+struct MPEG2TSSource : public MediaTrackHelper {
     MPEG2TSSource(
             MPEG2TSExtractor *extractor,
             const sp<AnotherPacketSource> &impl,
             bool doesSeek);
     virtual ~MPEG2TSSource();
 
-    virtual status_t start(MetaDataBase *params = NULL);
-    virtual status_t stop();
-    virtual status_t getFormat(MetaDataBase &);
+    virtual media_status_t start();
+    virtual media_status_t stop();
+    virtual media_status_t getFormat(AMediaFormat *);
 
-    virtual status_t read(
-            MediaBufferBase **buffer, const ReadOptions *options = NULL);
+    virtual media_status_t read(
+            MediaBufferHelper **buffer, const ReadOptions *options = NULL);
 
 private:
     MPEG2TSExtractor *mExtractor;
@@ -86,56 +88,174 @@
 MPEG2TSSource::~MPEG2TSSource() {
 }
 
-status_t MPEG2TSSource::start(MetaDataBase *) {
-    return mImpl->start(NULL); // AnotherPacketSource::start() doesn't use its argument
+media_status_t MPEG2TSSource::start() {
+    // initialize with one small buffer, but allow growth
+    mBufferGroup->init(1 /* one buffer */, 256 /* buffer size */, 64 /* max number of buffers */);
+
+    if (!mImpl->start(NULL)) { // AnotherPacketSource::start() doesn't use its argument
+        return AMEDIA_OK;
+    }
+    return AMEDIA_ERROR_UNKNOWN;
 }
 
-status_t MPEG2TSSource::stop() {
-    return mImpl->stop();
+media_status_t MPEG2TSSource::stop() {
+    if (!mImpl->stop()) {
+        return AMEDIA_OK;
+    }
+    return AMEDIA_ERROR_UNKNOWN;
 }
 
-status_t MPEG2TSSource::getFormat(MetaDataBase &meta) {
+void copyAMessageToAMediaFormat(AMediaFormat *format, sp<AMessage> msg) {
+    size_t numEntries = msg->countEntries();
+    for (size_t i = 0; i < numEntries; i++) {
+        AMessage::Type type;
+        const char *name = msg->getEntryNameAt(i, &type);
+        AMessage::ItemData id = msg->getEntryAt(i);
+
+        switch (type) {
+            case AMessage::kTypeInt32:
+                int32_t val32;
+                if (id.find(&val32)) {
+                    AMediaFormat_setInt32(format, name, val32);
+                }
+                break;
+            case AMessage::kTypeInt64:
+                int64_t val64;
+                if (id.find(&val64)) {
+                    AMediaFormat_setInt64(format, name, val64);
+                }
+                break;
+            case AMessage::kTypeFloat:
+                float valfloat;
+                if (id.find(&valfloat)) {
+                    AMediaFormat_setFloat(format, name, valfloat);
+                }
+                break;
+            case AMessage::kTypeDouble:
+                double valdouble;
+                if (id.find(&valdouble)) {
+                    AMediaFormat_setDouble(format, name, valdouble);
+                }
+                break;
+            case AMessage::kTypeString:
+                if (AString s; id.find(&s)) {
+                    AMediaFormat_setString(format, name, s.c_str());
+                }
+                break;
+            case AMessage::kTypeBuffer:
+            {
+                sp<ABuffer> buffer;
+                if (id.find(&buffer)) {
+                    AMediaFormat_setBuffer(format, name, buffer->data(), buffer->size());
+                }
+                break;
+            }
+            default:
+                ALOGW("ignoring unsupported type %d '%s'", type, name);
+        }
+    }
+}
+
+media_status_t MPEG2TSSource::getFormat(AMediaFormat *meta) {
     sp<MetaData> implMeta = mImpl->getFormat();
-    meta = *implMeta;
-    return OK;
+    sp<AMessage> msg;
+    convertMetaDataToMessage(implMeta, &msg);
+    copyAMessageToAMediaFormat(meta, msg);
+    return AMEDIA_OK;
 }
 
-status_t MPEG2TSSource::read(
-        MediaBufferBase **out, const ReadOptions *options) {
+media_status_t MPEG2TSSource::read(
+        MediaBufferHelper **out, const ReadOptions *options) {
     *out = NULL;
 
     int64_t seekTimeUs;
     ReadOptions::SeekMode seekMode;
     if (mDoesSeek && options && options->getSeekTo(&seekTimeUs, &seekMode)) {
         // seek is needed
-        status_t err = mExtractor->seek(seekTimeUs, seekMode);
-        if (err != OK) {
-            return err;
+        status_t err = mExtractor->seek(seekTimeUs, (ReadOptions::SeekMode)seekMode);
+        if (err == ERROR_END_OF_STREAM) {
+            return AMEDIA_ERROR_END_OF_STREAM;
+        } else if (err != OK) {
+            return AMEDIA_ERROR_UNKNOWN;
         }
     }
 
     if (mExtractor->feedUntilBufferAvailable(mImpl) != OK) {
-        return ERROR_END_OF_STREAM;
+        return AMEDIA_ERROR_END_OF_STREAM;
     }
 
-    return mImpl->read(out, options);
+    MediaBufferBase *mbuf;
+    mImpl->read(&mbuf, (MediaTrack::ReadOptions*) options);
+    size_t length = mbuf->range_length();
+    MediaBufferHelper *outbuf;
+    mBufferGroup->acquire_buffer(&outbuf, false, length);
+    memcpy(outbuf->data(), mbuf->data(), length);
+    outbuf->set_range(0, length);
+    *out = outbuf;
+    MetaDataBase &inMeta = mbuf->meta_data();
+    AMediaFormat *outMeta = outbuf->meta_data();
+    AMediaFormat_clear(outMeta);
+    int64_t val64;
+    if (inMeta.findInt64(kKeyTime, &val64)) {
+        AMediaFormat_setInt64(outMeta, AMEDIAFORMAT_KEY_TIME_US, val64);
+    }
+    int32_t val32;
+    if (inMeta.findInt32(kKeyIsSyncFrame, &val32)) {
+        AMediaFormat_setInt32(outMeta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, val32);
+    }
+    if (inMeta.findInt32(kKeyCryptoMode, &val32)) {
+        AMediaFormat_setInt32(outMeta, AMEDIAFORMAT_KEY_CRYPTO_MODE, val32);
+    }
+    uint32_t bufType;
+    const void *bufData;
+    size_t bufSize;
+    if (inMeta.findData(kKeyCryptoIV, &bufType, &bufData, &bufSize)) {
+        AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_IV, bufData, bufSize);
+    }
+    if (inMeta.findData(kKeyCryptoKey, &bufType, &bufData, &bufSize)) {
+        AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_KEY, bufData, bufSize);
+    }
+    if (inMeta.findData(kKeyPlainSizes, &bufType, &bufData, &bufSize)) {
+        AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES, bufData, bufSize);
+    }
+    if (inMeta.findData(kKeyEncryptedSizes, &bufType, &bufData, &bufSize)) {
+        AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES, bufData, bufSize);
+    }
+    if (inMeta.findData(kKeySEI, &bufType, &bufData, &bufSize)) {
+        AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_SEI, bufData, bufSize);
+    }
+    if (inMeta.findData(kKeyAudioPresentationInfo, &bufType, &bufData, &bufSize)) {
+        AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO, bufData, bufSize);
+    }
+    mbuf->release();
+    return AMEDIA_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
-MPEG2TSExtractor::MPEG2TSExtractor(DataSourceBase *source)
+MPEG2TSExtractor::MPEG2TSExtractor(DataSourceHelper *source)
     : mDataSource(source),
       mParser(new ATSParser),
       mLastSyncEvent(0),
       mOffset(0) {
+    char header;
+    if (source->readAt(0, &header, 1) == 1 && header == 0x47) {
+        mHeaderSkip = 0;
+    } else {
+        mHeaderSkip = 4;
+    }
     init();
 }
 
+MPEG2TSExtractor::~MPEG2TSExtractor() {
+    delete mDataSource;
+}
+
 size_t MPEG2TSExtractor::countTracks() {
     return mSourceImpls.size();
 }
 
-MediaTrack *MPEG2TSExtractor::getTrack(size_t index) {
+MediaTrackHelper *MPEG2TSExtractor::getTrack(size_t index) {
     if (index >= mSourceImpls.size()) {
         return NULL;
     }
@@ -146,22 +266,23 @@
             (mSeekSyncPoints == &mSyncPoints.editItemAt(index)));
 }
 
-status_t MPEG2TSExtractor::getTrackMetaData(
-        MetaDataBase &meta,
+media_status_t MPEG2TSExtractor::getTrackMetaData(
+        AMediaFormat *meta,
         size_t index, uint32_t /* flags */) {
     sp<MetaData> implMeta = index < mSourceImpls.size()
         ? mSourceImpls.editItemAt(index)->getFormat() : NULL;
     if (implMeta == NULL) {
-        return UNKNOWN_ERROR;
+        return AMEDIA_ERROR_UNKNOWN;
     }
-    meta = *implMeta;
-    return OK;
+    sp<AMessage> msg = new AMessage;
+    convertMetaDataToMessage(implMeta, &msg);
+    copyAMessageToAMediaFormat(meta, msg);
+    return AMEDIA_OK;
 }
 
-status_t MPEG2TSExtractor::getMetaData(MetaDataBase &meta) {
-    meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG2TS);
-
-    return OK;
+media_status_t MPEG2TSExtractor::getMetaData(AMediaFormat *meta) {
+    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_CONTAINER_MPEG2TS);
+    return AMEDIA_OK;
 }
 
 //static
@@ -172,7 +293,7 @@
                     || !strcasecmp(MEDIA_MIMETYPE_AUDIO_SCRAMBLED, mime));
 }
 
-status_t MPEG2TSExtractor::setMediaCas(const uint8_t* casToken, size_t size) {
+media_status_t MPEG2TSExtractor::setMediaCas(const uint8_t* casToken, size_t size) {
     HalToken halToken;
     halToken.setToExternal((uint8_t*)casToken, size);
     sp<ICas> cas = ICas::castFrom(retrieveHalInterface(halToken));
@@ -182,20 +303,26 @@
     if (err == OK) {
         ALOGI("All tracks now have descramblers");
         init();
+        return AMEDIA_OK;
     }
-    return err;
+    return AMEDIA_ERROR_UNKNOWN;
+}
+
+status_t MPEG2TSExtractor::findIndexOfSource(const sp<AnotherPacketSource> &impl, size_t *index) {
+    for (size_t i = 0; i < mSourceImpls.size(); i++) {
+        if (mSourceImpls[i] == impl) {
+            *index = i;
+            return OK;
+        }
+    }
+    return NAME_NOT_FOUND;
 }
 
 void MPEG2TSExtractor::addSource(const sp<AnotherPacketSource> &impl) {
-    bool found = false;
-    for (size_t i = 0; i < mSourceImpls.size(); i++) {
-        if (mSourceImpls[i] == impl) {
-            found = true;
-            break;
-        }
-    }
-    if (!found) {
+    size_t index;
+    if (findIndexOfSource(impl, &index) != OK) {
         mSourceImpls.push(impl);
+        mSyncPoints.push();
     }
 }
 
@@ -203,6 +330,7 @@
     bool haveAudio = false;
     bool haveVideo = false;
     int64_t startTime = ALooper::GetNowUs();
+    size_t index;
 
     status_t err;
     while ((err = feedMore(true /* isInit */)) == OK
@@ -221,8 +349,9 @@
                     haveVideo = true;
                     addSource(impl);
                     if (!isScrambledFormat(*(format.get()))) {
-                        mSyncPoints.push();
-                        mSeekSyncPoints = &mSyncPoints.editTop();
+                        if (findIndexOfSource(impl, &index) == OK) {
+                            mSeekSyncPoints = &mSyncPoints.editItemAt(index);
+                        }
                     }
                 }
             }
@@ -236,10 +365,9 @@
                 if (format != NULL) {
                     haveAudio = true;
                     addSource(impl);
-                    if (!isScrambledFormat(*(format.get()))) {
-                        mSyncPoints.push();
-                        if (!haveVideo) {
-                            mSeekSyncPoints = &mSyncPoints.editTop();
+                    if (!isScrambledFormat(*(format.get())) && !haveVideo) {
+                        if (findIndexOfSource(impl, &index) == OK) {
+                            mSeekSyncPoints = &mSyncPoints.editItemAt(index);
                         }
                     }
                 }
@@ -260,22 +388,19 @@
         }
 
         // Wait only for 2 seconds to detect audio/video streams.
-        if (ALooper::GetNowUs() - startTime > 2000000ll) {
+        if (ALooper::GetNowUs() - startTime > 2000000LL) {
             break;
         }
     }
 
     off64_t size;
     if (mDataSource->getSize(&size) == OK && (haveAudio || haveVideo)) {
-        sp<AnotherPacketSource> impl = haveVideo
-                ? mParser->getSource(ATSParser::VIDEO)
-                : mParser->getSource(ATSParser::AUDIO);
         size_t prevSyncSize = 1;
         int64_t durationUs = -1;
         List<int64_t> durations;
         // Estimate duration --- stabilize until you get <500ms deviation.
         while (feedMore() == OK
-                && ALooper::GetNowUs() - startTime <= 2000000ll) {
+                && ALooper::GetNowUs() - startTime <= 2000000LL) {
             if (mSeekSyncPoints->size() > prevSyncSize) {
                 prevSyncSize = mSeekSyncPoints->size();
                 int64_t diffUs = mSeekSyncPoints->keyAt(prevSyncSize - 1)
@@ -303,17 +428,32 @@
                 }
             }
         }
-        status_t err;
-        int64_t bufferedDurationUs;
-        bufferedDurationUs = impl->getBufferedDurationUs(&err);
-        if (err == ERROR_END_OF_STREAM) {
-            durationUs = bufferedDurationUs;
+
+        bool found = false;
+        for (int i = 0; i < ATSParser::NUM_SOURCE_TYPES; ++i) {
+            ATSParser::SourceType type = static_cast<ATSParser::SourceType>(i);
+            sp<AnotherPacketSource> impl = mParser->getSource(type);
+            if (impl == NULL) {
+                continue;
+            }
+
+            int64_t trackDurationUs = durationUs;
+
+            status_t err;
+            int64_t bufferedDurationUs = impl->getBufferedDurationUs(&err);
+            if (err == ERROR_END_OF_STREAM) {
+                trackDurationUs = bufferedDurationUs;
+            }
+            if (trackDurationUs > 0) {
+                ALOGV("[SourceType%d] durationUs=%" PRId64 "", type, trackDurationUs);
+                const sp<MetaData> meta = impl->getFormat();
+                meta->setInt64(kKeyDuration, trackDurationUs);
+                impl->setFormat(meta);
+
+                found = true;
+            }
         }
-        if (durationUs > 0) {
-            const sp<MetaData> meta = impl->getFormat();
-            meta->setInt64(kKeyDuration, durationUs);
-            impl->setFormat(meta);
-        } else {
+        if (!found) {
             estimateDurationsFromTimesUsAtEnd();
         }
     }
@@ -326,7 +466,7 @@
     Mutex::Autolock autoLock(mLock);
 
     uint8_t packet[kTSPacketSize];
-    ssize_t n = mDataSource->readAt(mOffset, packet, kTSPacketSize);
+    ssize_t n = mDataSource->readAt(mOffset + mHeaderSkip, packet, kTSPacketSize);
 
     if (n < (ssize_t)kTSPacketSize) {
         if (n >= 0) {
@@ -336,7 +476,7 @@
     }
 
     ATSParser::SyncEvent event(mOffset);
-    mOffset += n;
+    mOffset += mHeaderSkip + n;
     status_t err = mParser->feedTSPacket(packet, kTSPacketSize, &event);
     if (event.hasReturnedData()) {
         if (isInit) {
@@ -405,15 +545,15 @@
                 break;
             }
 
-            ssize_t n = mDataSource->readAt(offset, packet, kTSPacketSize);
+            ssize_t n = mDataSource->readAt(offset+mHeaderSkip, packet, kTSPacketSize);
             if (n < 0) {
                 return n;
             } else if (n < (ssize_t)kTSPacketSize) {
                 break;
             }
 
-            offset += kTSPacketSize;
-            bytesRead += kTSPacketSize;
+            offset += kTSPacketSize + mHeaderSkip;
+            bytesRead += kTSPacketSize + mHeaderSkip;
             err = parser->feedTSPacket(packet, kTSPacketSize, &ev);
             if (err != OK) {
                 return err;
@@ -477,7 +617,7 @@
 }
 
 status_t MPEG2TSExtractor::seek(int64_t seekTimeUs,
-        const MediaTrack::ReadOptions::SeekMode &seekMode) {
+        const MediaTrackHelper::ReadOptions::SeekMode &seekMode) {
     if (mSeekSyncPoints == NULL || mSeekSyncPoints->isEmpty()) {
         ALOGW("No sync point to seek to.");
         // ... and therefore we have nothing useful to do here.
@@ -498,18 +638,18 @@
     }
 
     switch (seekMode) {
-        case MediaTrack::ReadOptions::SEEK_NEXT_SYNC:
+        case MediaTrackHelper::ReadOptions::SEEK_NEXT_SYNC:
             if (index == mSeekSyncPoints->size()) {
                 ALOGW("Next sync not found; starting from the latest sync.");
                 --index;
             }
             break;
-        case MediaTrack::ReadOptions::SEEK_CLOSEST_SYNC:
-        case MediaTrack::ReadOptions::SEEK_CLOSEST:
+        case MediaTrackHelper::ReadOptions::SEEK_CLOSEST_SYNC:
+        case MediaTrackHelper::ReadOptions::SEEK_CLOSEST:
             ALOGW("seekMode not supported: %d; falling back to PREVIOUS_SYNC",
                     seekMode);
-            // fall-through
-        case MediaTrack::ReadOptions::SEEK_PREVIOUS_SYNC:
+            FALLTHROUGH_INTENDED;
+        case MediaTrackHelper::ReadOptions::SEEK_PREVIOUS_SYNC:
             if (index == 0) {
                 ALOGW("Previous sync not found; starting from the earliest "
                         "sync.");
@@ -652,12 +792,22 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-bool SniffMPEG2TS(DataSourceBase *source, float *confidence) {
+bool SniffMPEG2TS(DataSourceHelper *source, float *confidence) {
     for (int i = 0; i < 5; ++i) {
         char header;
         if (source->readAt(kTSPacketSize * i, &header, 1) != 1
                 || header != 0x47) {
-            return false;
+            // not ts file, check if m2ts file
+            for (int j = 0; j < 5; ++j) {
+                char headers[5];
+                if (source->readAt((kTSPacketSize + 4) * j, &headers, 5) != 5
+                    || headers[4] != 0x47) {
+                    // not m2ts file too, return
+                    return false;
+                }
+            }
+            ALOGV("this is m2ts file\n");
+            break;
         }
     }
 
diff --git a/media/extractors/mpeg2/MPEG2TSExtractor.h b/media/extractors/mpeg2/MPEG2TSExtractor.h
index cbdd3cb..dcd1e7b 100644
--- a/media/extractors/mpeg2/MPEG2TSExtractor.h
+++ b/media/extractors/mpeg2/MPEG2TSExtractor.h
@@ -20,8 +20,8 @@
 #define MPEG2_TS_EXTRACTOR_H_
 
 #include <media/stagefright/foundation/ABase.h>
-#include <media/MediaExtractor.h>
-#include <media/MediaTrack.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
 #include <media/stagefright/MetaDataBase.h>
 #include <utils/threads.h>
 #include <utils/KeyedVector.h>
@@ -34,30 +34,33 @@
 struct AMessage;
 struct AnotherPacketSource;
 struct ATSParser;
-class DataSourceBase;
+struct CDataSource;
 struct MPEG2TSSource;
 class String8;
 
-struct MPEG2TSExtractor : public MediaExtractor {
-    explicit MPEG2TSExtractor(DataSourceBase *source);
+struct MPEG2TSExtractor : public MediaExtractorPluginHelper {
+    explicit MPEG2TSExtractor(DataSourceHelper *source);
 
     virtual size_t countTracks();
-    virtual MediaTrack *getTrack(size_t index);
-    virtual status_t getTrackMetaData(MetaDataBase &meta, size_t index, uint32_t flags);
+    virtual MediaTrackHelper *getTrack(size_t index);
+    virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
 
-    virtual status_t getMetaData(MetaDataBase& meta);
+    virtual media_status_t getMetaData(AMediaFormat *meta);
 
-    virtual status_t setMediaCas(const uint8_t* /*casToken*/, size_t /*size*/) override;
+    virtual media_status_t setMediaCas(const uint8_t* /*casToken*/, size_t /*size*/) override;
 
     virtual uint32_t flags() const;
     virtual const char * name() { return "MPEG2TSExtractor"; }
 
+protected:
+    virtual ~MPEG2TSExtractor();
+
 private:
     friend struct MPEG2TSSource;
 
     mutable Mutex mLock;
 
-    DataSourceBase *mDataSource;
+    DataSourceHelper *mDataSource;
 
     sp<ATSParser> mParser;
 
@@ -81,27 +84,29 @@
     // Try to feed more data from source to parser.
     // |isInit| means this function is called inside init(). This is a signal to
     // save SyncEvent so that init() can add SyncPoint after it updates |mSourceImpls|.
-    // This function returns OK if expected amount of data is fed from DataSourceBase to
+    // This function returns OK if expected amount of data is fed from DataSourceHelper to
     // parser and is successfully parsed. Otherwise, various error codes could be
-    // returned, e.g., ERROR_END_OF_STREAM, or no data availalbe from DataSourceBase, or
+    // returned, e.g., ERROR_END_OF_STREAM, or no data availalbe from DataSourceHelper, or
     // the data has syntax error during parsing, etc.
     status_t feedMore(bool isInit = false);
     status_t seek(int64_t seekTimeUs,
-            const MediaSource::ReadOptions::SeekMode& seekMode);
+            const MediaTrackHelper::ReadOptions::SeekMode& seekMode);
     status_t queueDiscontinuityForSeek(int64_t actualSeekTimeUs);
     status_t seekBeyond(int64_t seekTimeUs);
 
     status_t feedUntilBufferAvailable(const sp<AnotherPacketSource> &impl);
+    status_t findIndexOfSource(const sp<AnotherPacketSource> &impl, size_t *index);
 
     // Add a SynPoint derived from |event|.
     void addSyncPoint_l(const ATSParser::SyncEvent &event);
 
     status_t  estimateDurationsFromTimesUsAtEnd();
 
+    size_t mHeaderSkip;
     DISALLOW_EVIL_CONSTRUCTORS(MPEG2TSExtractor);
 };
 
-bool SniffMPEG2TS(DataSourceBase *source, float *confidence);
+bool SniffMPEG2TS(DataSourceHelper *source, float *confidence);
 
 }  // namespace android
 
diff --git a/media/extractors/ogg/Android.bp b/media/extractors/ogg/Android.bp
index 7c6fc75..604ec59 100644
--- a/media/extractors/ogg/Android.bp
+++ b/media/extractors/ogg/Android.bp
@@ -7,13 +7,18 @@
         "external/tremolo",
     ],
 
+    header_libs: [
+        "libaudio_system_headers",
+    ],
+
     shared_libs: [
         "liblog",
-        "libmediaextractor",
+        "libmediandk",
     ],
 
     static_libs: [
         "libstagefright_foundation",
+        "libstagefright_metadatautils",
         "libutils",
         "libvorbisidec",
     ],
@@ -36,9 +41,6 @@
             "unsigned-integer-overflow",
             "signed-integer-overflow",
         ],
-        diag: {
-            cfi: true,
-        },
     },
 
 }
diff --git a/media/extractors/ogg/OggExtractor.cpp b/media/extractors/ogg/OggExtractor.cpp
index b2fe69c..72b94bb 100644
--- a/media/extractors/ogg/OggExtractor.cpp
+++ b/media/extractors/ogg/OggExtractor.cpp
@@ -21,19 +21,17 @@
 #include "OggExtractor.h"
 
 #include <cutils/properties.h>
+#include <utils/Vector.h>
 #include <media/DataSourceBase.h>
 #include <media/ExtractorUtils.h>
-#include <media/MediaTrack.h>
-#include <media/VorbisComment.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/base64.h>
 #include <media/stagefright/foundation/ByteUtils.h>
-#include <media/stagefright/MediaBufferBase.h>
-#include <media/stagefright/MediaBufferGroup.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/MetaDataBase.h>
+#include <media/stagefright/MetaDataUtils.h>
+#include <system/audio.h>
 #include <utils/String8.h>
 
 extern "C" {
@@ -47,16 +45,16 @@
 
 namespace android {
 
-struct OggSource : public MediaTrack {
+struct OggSource : public MediaTrackHelper {
     explicit OggSource(OggExtractor *extractor);
 
-    virtual status_t getFormat(MetaDataBase &);
+    virtual media_status_t getFormat(AMediaFormat *);
 
-    virtual status_t start(MetaDataBase *params = NULL);
-    virtual status_t stop();
+    virtual media_status_t start();
+    virtual media_status_t stop();
 
-    virtual status_t read(
-            MediaBufferBase **buffer, const ReadOptions *options = NULL);
+    virtual media_status_t read(
+            MediaBufferHelper **buffer, const ReadOptions *options = NULL);
 
 protected:
     virtual ~OggSource();
@@ -71,28 +69,30 @@
 
 struct MyOggExtractor {
     MyOggExtractor(
-            DataSourceBase *source,
+            DataSourceHelper *source,
             const char *mimeType,
             size_t numHeaders,
             int64_t seekPreRollUs);
     virtual ~MyOggExtractor();
 
-    status_t getFormat(MetaDataBase &) const;
+    media_status_t getFormat(AMediaFormat *) const;
 
     // Returns an approximate bitrate in bits per second.
     virtual uint64_t approxBitrate() const = 0;
 
     status_t seekToTime(int64_t timeUs);
     status_t seekToOffset(off64_t offset);
-    virtual status_t readNextPacket(MediaBufferBase **buffer) = 0;
+    virtual media_status_t readNextPacket(MediaBufferHelper **buffer) = 0;
 
     status_t init();
 
-    status_t getFileMetaData(MetaDataBase &meta) {
-        meta = mFileMeta;
-        return OK;
+    media_status_t getFileMetaData(AMediaFormat *meta) {
+        return AMediaFormat_copy(meta, mFileMeta);
     }
 
+    void setBufferGroup(MediaBufferGroupHelper *group) {
+        mBufferGroup = group;
+    }
 protected:
     struct Page {
         uint64_t mGranulePosition;
@@ -110,7 +110,8 @@
         int64_t mTimeUs;
     };
 
-    DataSourceBase *mSource;
+    MediaBufferGroupHelper *mBufferGroup;
+    DataSourceHelper *mSource;
     off64_t mOffset;
     Page mCurrentPage;
     uint64_t mCurGranulePosition;
@@ -129,11 +130,13 @@
     vorbis_info mVi;
     vorbis_comment mVc;
 
-    MetaDataBase mMeta;
-    MetaDataBase mFileMeta;
+    AMediaFormat *mMeta;
+    AMediaFormat *mFileMeta;
 
     Vector<TOCEntry> mTableOfContents;
 
+    int32_t mHapticChannelCount;
+
     ssize_t readPage(off64_t offset, Page *page);
     status_t findNextPage(off64_t startOffset, off64_t *pageOffset);
 
@@ -146,7 +149,7 @@
     // 1 - bitstream identification header
     // 3 - comment header
     // 5 - codec setup header (Vorbis only)
-    virtual status_t verifyHeader(MediaBufferBase *buffer, uint8_t type) = 0;
+    virtual media_status_t verifyHeader(MediaBufferHelper *buffer, uint8_t type) = 0;
 
     // Read the next ogg packet from the underlying data source; optionally
     // calculate the timestamp for the output packet whilst pretending
@@ -154,9 +157,9 @@
     //
     // *buffer is NULL'ed out immediately upon entry, and if successful a new buffer is allocated;
     // clients are responsible for releasing the original buffer.
-    status_t _readNextPacket(MediaBufferBase **buffer, bool calcVorbisTimestamp);
+    media_status_t _readNextPacket(MediaBufferHelper **buffer, bool calcVorbisTimestamp);
 
-    int32_t getPacketBlockSize(MediaBufferBase *buffer);
+    int32_t getPacketBlockSize(MediaBufferHelper *buffer);
 
     void parseFileMetaData();
 
@@ -164,12 +167,14 @@
 
     void buildTableOfContents();
 
+    void setChannelMask(int channelCount);
+
     MyOggExtractor(const MyOggExtractor &);
     MyOggExtractor &operator=(const MyOggExtractor &);
 };
 
 struct MyVorbisExtractor : public MyOggExtractor {
-    explicit MyVorbisExtractor(DataSourceBase *source)
+    explicit MyVorbisExtractor(DataSourceHelper *source)
         : MyOggExtractor(source,
                 MEDIA_MIMETYPE_AUDIO_VORBIS,
                 /* numHeaders */ 3,
@@ -178,7 +183,7 @@
 
     virtual uint64_t approxBitrate() const;
 
-    virtual status_t readNextPacket(MediaBufferBase **buffer) {
+    virtual media_status_t readNextPacket(MediaBufferHelper **buffer) {
         return _readNextPacket(buffer, /* calcVorbisTimestamp = */ true);
     }
 
@@ -190,14 +195,14 @@
         return granulePos * 1000000ll / mVi.rate;
     }
 
-    virtual status_t verifyHeader(MediaBufferBase *buffer, uint8_t type);
+    virtual media_status_t verifyHeader(MediaBufferHelper *buffer, uint8_t type);
 };
 
 struct MyOpusExtractor : public MyOggExtractor {
     static const int32_t kOpusSampleRate = 48000;
     static const int64_t kOpusSeekPreRollUs = 80000; // 80 ms
 
-    explicit MyOpusExtractor(DataSourceBase *source)
+    explicit MyOpusExtractor(DataSourceHelper *source)
         : MyOggExtractor(source, MEDIA_MIMETYPE_AUDIO_OPUS, /*numHeaders*/ 2, kOpusSeekPreRollUs),
           mChannelCount(0),
           mCodecDelay(0),
@@ -208,16 +213,16 @@
         return 0;
     }
 
-    virtual status_t readNextPacket(MediaBufferBase **buffer);
+    virtual media_status_t readNextPacket(MediaBufferHelper **buffer);
 
 protected:
     virtual int64_t getTimeUsOfGranule(uint64_t granulePos) const;
-    virtual status_t verifyHeader(MediaBufferBase *buffer, uint8_t type);
+    virtual media_status_t verifyHeader(MediaBufferHelper *buffer, uint8_t type);
 
 private:
-    status_t verifyOpusHeader(MediaBufferBase *buffer);
-    status_t verifyOpusComments(MediaBufferBase *buffer);
-    uint32_t getNumSamplesInPacket(MediaBufferBase *buffer) const;
+    media_status_t verifyOpusHeader(MediaBufferHelper *buffer);
+    media_status_t verifyOpusComments(MediaBufferHelper *buffer);
+    uint32_t getNumSamplesInPacket(MediaBufferHelper *buffer) const;
 
     uint8_t mChannelCount;
     uint16_t mCodecDelay;
@@ -237,28 +242,30 @@
     }
 }
 
-status_t OggSource::getFormat(MetaDataBase &meta) {
+media_status_t OggSource::getFormat(AMediaFormat *meta) {
     return mExtractor->mImpl->getFormat(meta);
 }
 
-status_t OggSource::start(MetaDataBase * /* params */) {
+media_status_t OggSource::start() {
     if (mStarted) {
-        return INVALID_OPERATION;
+        return AMEDIA_ERROR_INVALID_OPERATION;
     }
-
+    // initialize buffer group with a single small buffer, but a generous upper limit
+    mBufferGroup->init(1 /* number of buffers */, 128 /* size */, 64 /* max number of buffers */);
+    mExtractor->mImpl->setBufferGroup(mBufferGroup);
     mStarted = true;
 
-    return OK;
+    return AMEDIA_OK;
 }
 
-status_t OggSource::stop() {
+media_status_t OggSource::stop() {
     mStarted = false;
 
-    return OK;
+    return AMEDIA_OK;
 }
 
-status_t OggSource::read(
-        MediaBufferBase **out, const ReadOptions *options) {
+media_status_t OggSource::read(
+        MediaBufferHelper **out, const ReadOptions *options) {
     *out = NULL;
 
     int64_t seekTimeUs;
@@ -266,41 +273,43 @@
     if (options && options->getSeekTo(&seekTimeUs, &mode)) {
         status_t err = mExtractor->mImpl->seekToTime(seekTimeUs);
         if (err != OK) {
-            return err;
+            return AMEDIA_ERROR_UNKNOWN;
         }
     }
 
-    MediaBufferBase *packet;
-    status_t err = mExtractor->mImpl->readNextPacket(&packet);
+    MediaBufferHelper *packet;
+    media_status_t err = mExtractor->mImpl->readNextPacket(&packet);
 
-    if (err != OK) {
+    if (err != AMEDIA_OK) {
         return err;
     }
 
+    AMediaFormat *meta = packet->meta_data();
 #if 0
     int64_t timeUs;
-    if (packet->meta_data().findInt64(kKeyTime, &timeUs)) {
+    if (AMediaFormat_findInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeStampUs)) {
         ALOGI("found time = %lld us", timeUs);
     } else {
         ALOGI("NO time");
     }
 #endif
 
-    packet->meta_data().setInt32(kKeyIsSyncFrame, 1);
+    AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
 
     *out = packet;
-
-    return OK;
+    ALOGV("returning buffer %p", packet);
+    return AMEDIA_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 MyOggExtractor::MyOggExtractor(
-        DataSourceBase *source,
+        DataSourceHelper *source,
         const char *mimeType,
         size_t numHeaders,
         int64_t seekPreRollUs)
-    : mSource(source),
+    : mBufferGroup(NULL),
+      mSource(source),
       mOffset(0),
       mCurGranulePosition(0),
       mPrevGranulePosition(0),
@@ -311,21 +320,26 @@
       mMimeType(mimeType),
       mNumHeaders(numHeaders),
       mSeekPreRollUs(seekPreRollUs),
-      mFirstDataOffset(-1) {
+      mFirstDataOffset(-1),
+      mHapticChannelCount(0) {
     mCurrentPage.mNumSegments = 0;
+    mCurrentPage.mFlags = 0;
 
     vorbis_info_init(&mVi);
     vorbis_comment_init(&mVc);
+    mMeta = AMediaFormat_new();
+    mFileMeta = AMediaFormat_new();
 }
 
 MyOggExtractor::~MyOggExtractor() {
+    AMediaFormat_delete(mFileMeta);
+    AMediaFormat_delete(mMeta);
     vorbis_comment_clear(&mVc);
     vorbis_info_clear(&mVi);
 }
 
-status_t MyOggExtractor::getFormat(MetaDataBase &meta) const {
-    meta = mMeta;
-    return OK;
+media_status_t MyOggExtractor::getFormat(AMediaFormat *meta) const {
+    return AMediaFormat_copy(meta, mMeta);
 }
 
 status_t MyOggExtractor::findNextPage(
@@ -351,7 +365,13 @@
             return OK;
         }
 
-        ++*pageOffset;
+        // see how far ahead to skip; avoid some fruitless comparisons
+        unsigned int i;
+        for (i = 1; i < 4 ; i++) {
+            if (signature[i] == 'O')
+                break;
+        }
+        *pageOffset += i;
     }
 }
 
@@ -395,19 +415,18 @@
 
     ALOGV("prevPageOffset at %lld, pageOffset at %lld",
             (long long)prevPageOffset, (long long)pageOffset);
-
+    uint8_t flag = 0;
     for (;;) {
         Page prevPage;
         ssize_t n = readPage(prevPageOffset, &prevPage);
 
         if (n <= 0) {
-            return (status_t)n;
+            return (flag & 0x4) ? OK : (status_t)n;
         }
-
+        flag = prevPage.mFlags;
         prevPageOffset += n;
-
+        *granulePos = prevPage.mGranulePosition;
         if (prevPageOffset == pageOffset) {
-            *granulePos = prevPage.mGranulePosition;
             return OK;
         }
     }
@@ -502,30 +521,30 @@
         ALOGV("failed to read %zu bytes at offset %#016llx, got %zd bytes",
                 sizeof(header), (long long)offset, n);
 
-        if (n < 0) {
-            return n;
-        } else if (n == 0) {
-            return ERROR_END_OF_STREAM;
+        if (n == 0 || n == ERROR_END_OF_STREAM) {
+            return AMEDIA_ERROR_END_OF_STREAM;
+        } else if (n < 0) {
+            return AMEDIA_ERROR_UNKNOWN;
         } else {
-            return ERROR_IO;
+            return AMEDIA_ERROR_IO;
         }
     }
 
     if (memcmp(header, "OggS", 4)) {
-        return ERROR_MALFORMED;
+        return AMEDIA_ERROR_MALFORMED;
     }
 
     if (header[4] != 0) {
         // Wrong version.
 
-        return ERROR_UNSUPPORTED;
+        return AMEDIA_ERROR_UNSUPPORTED;
     }
 
     page->mFlags = header[5];
 
     if (page->mFlags & ~7) {
         // Only bits 0-2 are defined in version 0.
-        return ERROR_MALFORMED;
+        return AMEDIA_ERROR_MALFORMED;
     }
 
     page->mGranulePosition = U64LE_AT(&header[6]);
@@ -542,7 +561,7 @@
     if (mSource->readAt(
                 offset + sizeof(header), page->mLace, page->mNumSegments)
             < (ssize_t)page->mNumSegments) {
-        return ERROR_IO;
+        return AMEDIA_ERROR_IO;
     }
 
     size_t totalSize = 0;;
@@ -565,22 +584,22 @@
     return sizeof(header) + page->mNumSegments + totalSize;
 }
 
-status_t MyOpusExtractor::readNextPacket(MediaBufferBase **out) {
+media_status_t MyOpusExtractor::readNextPacket(MediaBufferHelper **out) {
     if (mOffset <= mFirstDataOffset && mStartGranulePosition < 0) {
         // The first sample might not start at time 0; find out where by subtracting
         // the number of samples on the first page from the granule position
         // (position of last complete sample) of the first page. This happens
         // the first time before we attempt to read a packet from the first page.
-        MediaBufferBase *mBuf;
+        MediaBufferHelper *mBuf;
         uint32_t numSamples = 0;
         uint64_t curGranulePosition = 0;
         while (true) {
-            status_t err = _readNextPacket(&mBuf, /* calcVorbisTimestamp = */false);
-            if (err != OK && err != ERROR_END_OF_STREAM) {
+            media_status_t err = _readNextPacket(&mBuf, /* calcVorbisTimestamp = */false);
+            if (err != AMEDIA_OK && err != AMEDIA_ERROR_END_OF_STREAM) {
                 return err;
             }
             // First two pages are header pages.
-            if (err == ERROR_END_OF_STREAM || mCurrentPage.mPageNo > 2) {
+            if (err == AMEDIA_ERROR_END_OF_STREAM || mCurrentPage.mPageNo > 2) {
                 if (mBuf != NULL) {
                     mBuf->release();
                     mBuf = NULL;
@@ -601,32 +620,33 @@
         seekToOffset(0);
     }
 
-    status_t err = _readNextPacket(out, /* calcVorbisTimestamp = */false);
-    if (err != OK) {
+    media_status_t err = _readNextPacket(out, /* calcVorbisTimestamp = */false);
+    if (err != AMEDIA_OK) {
         return err;
     }
 
     int32_t currentPageSamples;
     // Calculate timestamps by accumulating durations starting from the first sample of a page;
     // We assume that we only seek to page boundaries.
-    if ((*out)->meta_data().findInt32(kKeyValidSamples, &currentPageSamples)) {
+    AMediaFormat *meta = (*out)->meta_data();
+    if (AMediaFormat_getInt32(meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, &currentPageSamples)) {
         // first packet in page
         if (mOffset == mFirstDataOffset) {
             currentPageSamples -= mStartGranulePosition;
-            (*out)->meta_data().setInt32(kKeyValidSamples, currentPageSamples);
+            AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, currentPageSamples);
         }
         mCurGranulePosition = mCurrentPage.mGranulePosition - currentPageSamples;
     }
 
     int64_t timeUs = getTimeUsOfGranule(mCurGranulePosition);
-    (*out)->meta_data().setInt64(kKeyTime, timeUs);
+    AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeUs);
 
     uint32_t frames = getNumSamplesInPacket(*out);
     mCurGranulePosition += frames;
-    return OK;
+    return AMEDIA_OK;
 }
 
-uint32_t MyOpusExtractor::getNumSamplesInPacket(MediaBufferBase *buffer) const {
+uint32_t MyOpusExtractor::getNumSamplesInPacket(MediaBufferHelper *buffer) const {
     if (buffer == NULL || buffer->range_length() < 1) {
         return 0;
     }
@@ -668,14 +688,70 @@
         TRESPASS();
     }
 
-    uint32_t numSamples = frameSizeUs * numFrames * kOpusSampleRate / 1000000;
+    uint32_t numSamples = (uint32_t)((uint64_t)frameSizeUs * numFrames * kOpusSampleRate) / 1000000;
     return numSamples;
 }
 
-status_t MyOggExtractor::_readNextPacket(MediaBufferBase **out, bool calcVorbisTimestamp) {
+/*
+ * basic mediabuffer implementation used during initial parsing of the
+ * header packets, which happens before we have a buffer group
+ */
+class StandAloneMediaBuffer : public MediaBufferHelper {
+private:
+    void *mData;
+    size_t mSize;
+    size_t mOffset;
+    size_t mLength;
+    AMediaFormat *mFormat;
+public:
+    StandAloneMediaBuffer(size_t size) : MediaBufferHelper(NULL) {
+        mSize = size;
+        mData = malloc(mSize);
+        mOffset = 0;
+        mLength = mSize;
+        mFormat = AMediaFormat_new();
+        ALOGV("created standalone media buffer %p of size %zu", this, mSize);
+    }
+
+    ~StandAloneMediaBuffer() override {
+        free(mData);
+        AMediaFormat_delete(mFormat);
+        ALOGV("deleted standalone media buffer %p of size %zu", this, mSize);
+    }
+
+    void release() override {
+        delete this;
+    }
+
+    void* data() override {
+        return mData;
+    }
+
+    size_t size() override {
+        return mSize;
+    }
+
+    size_t range_offset() override {
+        return mOffset;
+    }
+
+    size_t range_length() override {
+        return mLength;
+    }
+
+    void set_range(size_t offset, size_t length) override {
+        mOffset = offset;
+        mLength = length;
+    }
+    AMediaFormat *meta_data() override {
+        return mFormat;
+    }
+};
+
+media_status_t MyOggExtractor::_readNextPacket(MediaBufferHelper **out, bool calcVorbisTimestamp) {
     *out = NULL;
 
-    MediaBufferBase *buffer = NULL;
+    MediaBufferHelper *buffer = NULL;
     int64_t timeUs = -1;
 
     for (;;) {
@@ -709,16 +785,23 @@
                     buffer->release();
                 }
                 ALOGE("b/36592202");
-                return ERROR_MALFORMED;
+                return AMEDIA_ERROR_MALFORMED;
             }
-            MediaBufferBase *tmp = MediaBufferBase::Create(fullSize);
+            MediaBufferHelper *tmp;
+            if (mBufferGroup) {
+                mBufferGroup->acquire_buffer(&tmp, false, fullSize);
+                ALOGV("acquired buffer %p from group", tmp);
+            } else {
+                tmp = new StandAloneMediaBuffer(fullSize);
+            }
             if (tmp == NULL) {
                 if (buffer != NULL) {
                     buffer->release();
                 }
                 ALOGE("b/36592202");
-                return ERROR_MALFORMED;
+                return AMEDIA_ERROR_MALFORMED;
             }
+            AMediaFormat_clear(tmp->meta_data());
             if (buffer != NULL) {
                 memcpy(tmp->data(), buffer->data(), buffer->range_length());
                 tmp->set_range(0, buffer->range_length());
@@ -737,7 +820,7 @@
                 buffer->release();
                 ALOGV("failed to read %zu bytes at %#016llx, got %zd bytes",
                         packetSize, (long long)dataOffset, n);
-                return ERROR_IO;
+                return AMEDIA_ERROR_IO;
             }
 
             buffer->set_range(0, fullSize);
@@ -748,8 +831,9 @@
                 // We've just read the entire packet.
 
                 if (mFirstPacketInPage) {
-                    buffer->meta_data().setInt32(
-                            kKeyValidSamples, mCurrentPageSamples);
+                    AMediaFormat *meta = buffer->meta_data();
+                    AMediaFormat_setInt32(
+                            meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, mCurrentPageSamples);
                     mFirstPacketInPage = false;
                 }
 
@@ -770,11 +854,12 @@
                         mCurrentPage.mPrevPacketPos += actualBlockSize / 2;
                         mCurrentPage.mPrevPacketSize = curBlockSize;
                     }
-                    buffer->meta_data().setInt64(kKeyTime, timeUs);
+                    AMediaFormat *meta = buffer->meta_data();
+                    AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeUs);
                 }
                 *out = buffer;
 
-                return OK;
+                return AMEDIA_OK;
             }
 
             // fall through, the buffer now contains the start of the packet.
@@ -783,6 +868,7 @@
         CHECK_EQ(mNextLaceIndex, mCurrentPage.mNumSegments);
 
         mOffset += mCurrentPageSize;
+        uint8_t flag = mCurrentPage.mFlags;
         ssize_t n = readPage(mOffset, &mCurrentPage);
 
         if (n <= 0) {
@@ -793,7 +879,8 @@
 
             ALOGV("readPage returned %zd", n);
 
-            return n < 0 ? n : (status_t)ERROR_END_OF_STREAM;
+            if (flag & 0x04) return AMEDIA_ERROR_END_OF_STREAM;
+            return (media_status_t) n;
         }
 
         // Prevent a harmless unsigned integer overflow by clamping to 0
@@ -816,36 +903,38 @@
                 // is already complete.
 
                 if (timeUs >= 0) {
-                    buffer->meta_data().setInt64(kKeyTime, timeUs);
+                    AMediaFormat *meta = buffer->meta_data();
+                    AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeUs);
                 }
 
-                buffer->meta_data().setInt32(
-                        kKeyValidSamples, mCurrentPageSamples);
+                AMediaFormat *meta = buffer->meta_data();
+                AMediaFormat_setInt32(
+                        meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, mCurrentPageSamples);
                 mFirstPacketInPage = false;
 
                 *out = buffer;
 
-                return OK;
+                return AMEDIA_OK;
             }
         }
     }
 }
 
 status_t MyOggExtractor::init() {
-    mMeta.setCString(kKeyMIMEType, mMimeType);
+    AMediaFormat_setString(mMeta, AMEDIAFORMAT_KEY_MIME, mMimeType);
 
-    status_t err;
-    MediaBufferBase *packet;
+    media_status_t err;
+    MediaBufferHelper *packet;
     for (size_t i = 0; i < mNumHeaders; ++i) {
         // ignore timestamp for configuration packets
-        if ((err = _readNextPacket(&packet, /* calcVorbisTimestamp = */ false)) != OK) {
+        if ((err = _readNextPacket(&packet, /* calcVorbisTimestamp = */ false)) != AMEDIA_OK) {
             return err;
         }
         ALOGV("read packet of size %zu\n", packet->range_length());
         err = verifyHeader(packet, /* type = */ i * 2 + 1);
         packet->release();
         packet = NULL;
-        if (err != OK) {
+        if (err != AMEDIA_OK) {
             return err;
         }
     }
@@ -865,12 +954,12 @@
 
         int64_t durationUs = getTimeUsOfGranule(lastGranulePosition);
 
-        mMeta.setInt64(kKeyDuration, durationUs);
+        AMediaFormat_setInt64(mMeta, AMEDIAFORMAT_KEY_DURATION, durationUs);
 
         buildTableOfContents();
     }
 
-    return OK;
+    return AMEDIA_OK;
 }
 
 void MyOggExtractor::buildTableOfContents() {
@@ -902,7 +991,7 @@
         size_t denom = numerator - kMaxNumTOCEntries;
 
         size_t accum = 0;
-        for (ssize_t i = mTableOfContents.size() - 1; i >= 0; --i) {
+        for (ssize_t i = mTableOfContents.size(); i > 0; --i) {
             accum += denom;
             if (accum >= numerator) {
                 mTableOfContents.removeAt(i);
@@ -912,7 +1001,7 @@
     }
 }
 
-int32_t MyOggExtractor::getPacketBlockSize(MediaBufferBase *buffer) {
+int32_t MyOggExtractor::getPacketBlockSize(MediaBufferHelper *buffer) {
     const uint8_t *data =
         (const uint8_t *)buffer->data() + buffer->range_offset();
 
@@ -952,7 +1041,7 @@
     return pcmSamplePosition * 1000000ll / kOpusSampleRate;
 }
 
-status_t MyOpusExtractor::verifyHeader(MediaBufferBase *buffer, uint8_t type) {
+media_status_t MyOpusExtractor::verifyHeader(MediaBufferHelper *buffer, uint8_t type) {
     switch (type) {
         // there are actually no header types defined in the Opus spec; we choose 1 and 3 to mean
         // header and comments such that we can share code with MyVorbisExtractor.
@@ -961,11 +1050,11 @@
         case 3:
             return verifyOpusComments(buffer);
         default:
-            return INVALID_OPERATION;
+            return AMEDIA_ERROR_INVALID_OPERATION;
     }
 }
 
-status_t MyOpusExtractor::verifyOpusHeader(MediaBufferBase *buffer) {
+media_status_t MyOpusExtractor::verifyOpusHeader(MediaBufferHelper *buffer) {
     const size_t kOpusHeaderSize = 19;
     const uint8_t *data =
         (const uint8_t *)buffer->data() + buffer->range_offset();
@@ -975,29 +1064,31 @@
     if (size < kOpusHeaderSize
             || memcmp(data, "OpusHead", 8)
             || /* version = */ data[8] != 1) {
-        return ERROR_MALFORMED;
+        return AMEDIA_ERROR_MALFORMED;
     }
 
     mChannelCount = data[9];
     mCodecDelay = U16LE_AT(&data[10]);
 
-    mMeta.setData(kKeyOpusHeader, 0, data, size);
-    mMeta.setInt32(kKeySampleRate, kOpusSampleRate);
-    mMeta.setInt32(kKeyChannelCount, mChannelCount);
-    mMeta.setInt64(kKeyOpusSeekPreRoll /* ns */, kOpusSeekPreRollUs * 1000 /* = 80 ms*/);
-    mMeta.setInt64(kKeyOpusCodecDelay /* ns */,
-            mCodecDelay /* sample/s */ * 1000000000ll / kOpusSampleRate);
+    // kKeyOpusHeader is csd-0
+    AMediaFormat_setBuffer(mMeta, AMEDIAFORMAT_KEY_CSD_0, data, size);
+    AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_SAMPLE_RATE, kOpusSampleRate);
+    AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, mChannelCount);
+    int64_t codecdelay = mCodecDelay /* sample/s */ * 1000000000ll / kOpusSampleRate;
+    AMediaFormat_setBuffer(mMeta, AMEDIAFORMAT_KEY_CSD_1, &codecdelay, sizeof(codecdelay));
+    int64_t preroll = kOpusSeekPreRollUs * 1000 /* = 80 ms*/;
+    AMediaFormat_setBuffer(mMeta, AMEDIAFORMAT_KEY_CSD_2, &preroll, sizeof(preroll));
 
-    return OK;
+    return AMEDIA_OK;
 }
 
-status_t MyOpusExtractor::verifyOpusComments(MediaBufferBase *buffer) {
+media_status_t MyOpusExtractor::verifyOpusComments(MediaBufferHelper *buffer) {
     // add artificial framing bit so we can reuse _vorbis_unpack_comment
     int32_t commentSize = buffer->range_length() + 1;
     auto tmp = heapbuffer<uint8_t>(commentSize);
     uint8_t *commentData = tmp.get();
     if (commentData == nullptr) {
-        return ERROR_MALFORMED;
+        return AMEDIA_ERROR_MALFORMED;
     }
 
     memcpy(commentData,
@@ -1026,14 +1117,14 @@
     for (int i = 0; i < headerLen; ++i) {
         char chr = oggpack_read(&bits, 8);
         if (chr != OpusTags[i]) {
-            return ERROR_MALFORMED;
+            return AMEDIA_ERROR_MALFORMED;
         }
     }
 
     int32_t vendorLen = oggpack_read(&bits, 32);
     framingBitOffset += 4;
     if (vendorLen < 0 || vendorLen > commentSize - 8) {
-        return ERROR_MALFORMED;
+        return AMEDIA_ERROR_MALFORMED;
     }
     // skip vendor string
     framingBitOffset += vendorLen;
@@ -1044,13 +1135,13 @@
     int32_t n = oggpack_read(&bits, 32);
     framingBitOffset += 4;
     if (n < 0 || n > ((commentSize - oggpack_bytes(&bits)) >> 2)) {
-        return ERROR_MALFORMED;
+        return AMEDIA_ERROR_MALFORMED;
     }
     for (int i = 0; i < n; ++i) {
         int32_t len = oggpack_read(&bits, 32);
         framingBitOffset += 4;
         if (len  < 0 || len  > (commentSize - oggpack_bytes(&bits))) {
-            return ERROR_MALFORMED;
+            return AMEDIA_ERROR_MALFORMED;
         }
         framingBitOffset += len;
         for (int j = 0; j < len; ++j) {
@@ -1058,7 +1149,7 @@
         }
     }
     if (framingBitOffset < 0 || framingBitOffset >= commentSize) {
-        return ERROR_MALFORMED;
+        return AMEDIA_ERROR_MALFORMED;
     }
     commentData[framingBitOffset] = 1;
 
@@ -1075,22 +1166,23 @@
     oggpack_readinit(&bits, &ref);
     int err = _vorbis_unpack_comment(&mVc, &bits);
     if (0 != err) {
-        return ERROR_MALFORMED;
+        return AMEDIA_ERROR_MALFORMED;
     }
 
     parseFileMetaData();
-    return OK;
+    setChannelMask(mChannelCount);
+    return AMEDIA_OK;
 }
 
-status_t MyVorbisExtractor::verifyHeader(
-        MediaBufferBase *buffer, uint8_t type) {
+media_status_t MyVorbisExtractor::verifyHeader(
+        MediaBufferHelper *buffer, uint8_t type) {
     const uint8_t *data =
         (const uint8_t *)buffer->data() + buffer->range_offset();
 
     size_t size = buffer->range_length();
 
     if (size < 7 || data[0] != type || memcmp(&data[1], "vorbis", 6)) {
-        return ERROR_MALFORMED;
+        return AMEDIA_ERROR_MALFORMED;
     }
 
     ogg_buffer buf;
@@ -1109,7 +1201,7 @@
     oggpack_readinit(&bits, &ref);
 
     if (oggpack_read(&bits, 8) != type) {
-        return ERROR_MALFORMED;
+        return AMEDIA_ERROR_MALFORMED;
     }
     for (size_t i = 0; i < 6; ++i) {
         oggpack_read(&bits, 8);  // skip 'vorbis'
@@ -1119,13 +1211,13 @@
         case 1:
         {
             if (0 != _vorbis_unpack_info(&mVi, &bits)) {
-                return ERROR_MALFORMED;
+                return AMEDIA_ERROR_MALFORMED;
             }
 
-            mMeta.setData(kKeyVorbisInfo, 0, data, size);
-            mMeta.setInt32(kKeySampleRate, mVi.rate);
-            mMeta.setInt32(kKeyChannelCount, mVi.channels);
-            mMeta.setInt32(kKeyBitRate, mVi.bitrate_nominal);
+            AMediaFormat_setBuffer(mMeta, AMEDIAFORMAT_KEY_CSD_0, data, size);
+            AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_SAMPLE_RATE, mVi.rate);
+            AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, mVi.channels);
+            AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_BIT_RATE, mVi.bitrate_nominal);
 
             ALOGV("lower-bitrate = %ld", mVi.bitrate_lower);
             ALOGV("upper-bitrate = %ld", mVi.bitrate_upper);
@@ -1140,7 +1232,7 @@
             if (mSource->getSize(&size) == OK) {
                 uint64_t bps = approxBitrate();
                 if (bps != 0) {
-                    mMeta.setInt64(kKeyDuration, size * 8000000ll / bps);
+                    AMediaFormat_setInt64(mMeta, AMEDIAFORMAT_KEY_DURATION, size * 8000000ll / bps);
                 }
             }
             break;
@@ -1149,25 +1241,26 @@
         case 3:
         {
             if (0 != _vorbis_unpack_comment(&mVc, &bits)) {
-                return ERROR_MALFORMED;
+                return AMEDIA_ERROR_MALFORMED;
             }
 
             parseFileMetaData();
+            setChannelMask(mVi.channels);
             break;
         }
 
         case 5:
         {
             if (0 != _vorbis_unpack_books(&mVi, &bits)) {
-                return ERROR_MALFORMED;
+                return AMEDIA_ERROR_MALFORMED;
             }
 
-            mMeta.setData(kKeyVorbisBooks, 0, data, size);
+            AMediaFormat_setBuffer(mMeta, AMEDIAFORMAT_KEY_CSD_1, data, size);
             break;
         }
     }
 
-    return OK;
+    return AMEDIA_OK;
 }
 
 uint64_t MyVorbisExtractor::approxBitrate() const {
@@ -1180,20 +1273,45 @@
 
 
 void MyOggExtractor::parseFileMetaData() {
-    mFileMeta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_OGG);
+    AMediaFormat_setString(mFileMeta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_CONTAINER_OGG);
 
     for (int i = 0; i < mVc.comments; ++i) {
         const char *comment = mVc.user_comments[i];
         size_t commentLength = mVc.comment_lengths[i];
-        parseVorbisComment(&mFileMeta, comment, commentLength);
+        parseVorbisComment(mFileMeta, comment, commentLength);
         //ALOGI("comment #%d: '%s'", i + 1, mVc.user_comments[i]);
     }
+
+    AMediaFormat_getInt32(mFileMeta, AMEDIAFORMAT_KEY_HAPTIC_CHANNEL_COUNT, &mHapticChannelCount);
+}
+
+void MyOggExtractor::setChannelMask(int channelCount) {
+    // Set channel mask according to channel count. When haptic channel count is found in
+    // file meta, set haptic channel mask to try haptic playback.
+    if (mHapticChannelCount > 0) {
+        const audio_channel_mask_t hapticChannelMask =
+                haptic_channel_mask_from_count(mHapticChannelCount);
+        const int32_t audioChannelCount = channelCount - mHapticChannelCount;
+        if (hapticChannelMask == AUDIO_CHANNEL_INVALID
+                || audioChannelCount <= 0 || audioChannelCount > FCC_8) {
+            ALOGE("Invalid haptic channel count found in metadata: %d", mHapticChannelCount);
+        } else {
+            const audio_channel_mask_t channelMask = audio_channel_out_mask_from_count(
+                    audioChannelCount) | hapticChannelMask;
+            AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_CHANNEL_MASK, channelMask);
+            AMediaFormat_setInt32(
+                    mMeta, AMEDIAFORMAT_KEY_HAPTIC_CHANNEL_COUNT, mHapticChannelCount);
+        }
+    } else {
+        AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_CHANNEL_MASK,
+                audio_channel_out_mask_from_count(channelCount));
+    }
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 
-OggExtractor::OggExtractor(DataSourceBase *source)
+OggExtractor::OggExtractor(DataSourceHelper *source)
     : mDataSource(source),
       mInitCheck(NO_INIT),
       mImpl(NULL) {
@@ -1220,13 +1338,14 @@
 OggExtractor::~OggExtractor() {
     delete mImpl;
     mImpl = NULL;
+    delete mDataSource;
 }
 
 size_t OggExtractor::countTracks() {
     return mInitCheck != OK ? 0 : 1;
 }
 
-MediaTrack *OggExtractor::getTrack(size_t index) {
+MediaTrackHelper *OggExtractor::getTrack(size_t index) {
     if (index >= 1) {
         return NULL;
     }
@@ -1234,33 +1353,34 @@
     return new OggSource(this);
 }
 
-status_t OggExtractor::getTrackMetaData(
-        MetaDataBase &meta,
+media_status_t OggExtractor::getTrackMetaData(
+        AMediaFormat *meta,
         size_t index, uint32_t /* flags */) {
     if (index >= 1) {
-        return UNKNOWN_ERROR;
+        return AMEDIA_ERROR_UNKNOWN;
     }
 
     return mImpl->getFormat(meta);
 }
 
-status_t OggExtractor::getMetaData(MetaDataBase &meta) {
+media_status_t OggExtractor::getMetaData(AMediaFormat *meta) {
     return mImpl->getFileMetaData(meta);
 }
 
-static MediaExtractor* CreateExtractor(
-        DataSourceBase *source,
+static CMediaExtractor* CreateExtractor(
+        CDataSource *source,
         void *) {
-    return new OggExtractor(source);
+    return wrap(new OggExtractor(new DataSourceHelper(source)));
 }
 
-static MediaExtractor::CreatorFunc Sniff(
-        DataSourceBase *source,
+static CreatorFunc Sniff(
+        CDataSource *source,
         float *confidence,
         void **,
-        MediaExtractor::FreeMetaFunc *) {
+        FreeMetaFunc *) {
+    DataSourceHelper helper(source);
     char tmp[4];
-    if (source->readAt(0, tmp, 4) < 4 || memcmp(tmp, "OggS", 4)) {
+    if (helper.readAt(0, tmp, 4) < 4 || memcmp(tmp, "OggS", 4)) {
         return NULL;
     }
 
@@ -1269,16 +1389,23 @@
     return CreateExtractor;
 }
 
+static const char *extensions[] = {
+    "oga",
+    "ogg",
+    "opus",
+    NULL
+};
+
 extern "C" {
 // This is the only symbol that needs to be exported
 __attribute__ ((visibility ("default")))
-MediaExtractor::ExtractorDef GETEXTRACTORDEF() {
+ExtractorDef GETEXTRACTORDEF() {
     return {
-        MediaExtractor::EXTRACTORDEF_VERSION,
+        EXTRACTORDEF_VERSION,
         UUID("8cc5cd06-f772-495e-8a62-cba9649374e9"),
         1, // version
         "Ogg Extractor",
-        Sniff
+        { .v3 = {Sniff, extensions} },
     };
 }
 
diff --git a/media/extractors/ogg/OggExtractor.h b/media/extractors/ogg/OggExtractor.h
index 9fe2944..c75dfa9 100644
--- a/media/extractors/ogg/OggExtractor.h
+++ b/media/extractors/ogg/OggExtractor.h
@@ -19,25 +19,26 @@
 #define OGG_EXTRACTOR_H_
 
 #include <utils/Errors.h>
-#include <media/MediaExtractor.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
+#include <media/NdkMediaFormat.h>
 
 namespace android {
 
 struct AMessage;
-class DataSourceBase;
 class String8;
 
 struct MyOggExtractor;
 struct OggSource;
 
-struct OggExtractor : public MediaExtractor {
-    explicit OggExtractor(DataSourceBase *source);
+struct OggExtractor : public MediaExtractorPluginHelper {
+    explicit OggExtractor(DataSourceHelper *source);
 
     virtual size_t countTracks();
-    virtual MediaTrack *getTrack(size_t index);
-    virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags);
+    virtual MediaTrackHelper *getTrack(size_t index);
+    virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
 
-    virtual status_t getMetaData(MetaDataBase& meta);
+    virtual media_status_t getMetaData(AMediaFormat *meta);
     virtual const char * name() { return "OggExtractor"; }
 
 protected:
@@ -46,7 +47,7 @@
 private:
     friend struct OggSource;
 
-    DataSourceBase *mDataSource;
+    DataSourceHelper *mDataSource;
     status_t mInitCheck;
 
     MyOggExtractor *mImpl;
diff --git a/media/extractors/wav/Android.bp b/media/extractors/wav/Android.bp
index 067933e..7e89271 100644
--- a/media/extractors/wav/Android.bp
+++ b/media/extractors/wav/Android.bp
@@ -7,11 +7,13 @@
     ],
 
     shared_libs: [
+        "libbinder_ndk",
         "liblog",
-        "libmediaextractor",
+        "libmediandk",
     ],
 
     static_libs: [
+        "libaudioutils",
         "libfifo",
         "libstagefright_foundation",
     ],
@@ -34,9 +36,6 @@
             "unsigned-integer-overflow",
             "signed-integer-overflow",
         ],
-        diag: {
-            cfi: true,
-        },
     },
 
 }
diff --git a/media/extractors/wav/WAVExtractor.cpp b/media/extractors/wav/WAVExtractor.cpp
index f5a1b01..4fa7f27 100644
--- a/media/extractors/wav/WAVExtractor.cpp
+++ b/media/extractors/wav/WAVExtractor.cpp
@@ -20,21 +20,32 @@
 
 #include "WAVExtractor.h"
 
+#include <android/binder_ibinder.h> // for AIBinder_getCallingUid
 #include <audio_utils/primitives.h>
-#include <media/DataSourceBase.h>
-#include <media/MediaTrack.h>
 #include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/MediaBufferGroup.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MetaData.h>
+#include <private/android_filesystem_config.h> // for AID_MEDIA
+#include <system/audio.h>
 #include <utils/String8.h>
 #include <cutils/bitops.h>
 
 #define CHANNEL_MASK_USE_CHANNEL_ORDER 0
 
+// NOTE: This code assumes the device processor is little endian.
+
 namespace android {
 
+// MediaServer is capable of handling float extractor output, but general processes
+// may not be able to do so.
+// TODO: Improve API to set extractor float output.
+// (Note: duplicated with FLACExtractor.cpp)
+static inline bool shouldExtractorOutputFloat(int bitsPerSample)
+{
+    return bitsPerSample > 16 && AIBinder_getCallingUid() == AID_MEDIA;
+}
+
 enum {
     WAVE_FORMAT_PCM        = 0x0001,
     WAVE_FORMAT_IEEE_FLOAT = 0x0003,
@@ -55,22 +66,22 @@
     return ptr[1] << 8 | ptr[0];
 }
 
-struct WAVSource : public MediaTrack {
+struct WAVSource : public MediaTrackHelper {
     WAVSource(
-            DataSourceBase *dataSource,
-            MetaDataBase &meta,
+            DataSourceHelper *dataSource,
+            AMediaFormat *meta,
             uint16_t waveFormat,
-            int32_t bitsPerSample,
+            bool outputFloat,
             off64_t offset, size_t size);
 
-    virtual status_t start(MetaDataBase *params = NULL);
-    virtual status_t stop();
-    virtual status_t getFormat(MetaDataBase &meta);
+    virtual media_status_t start();
+    virtual media_status_t stop();
+    virtual media_status_t getFormat(AMediaFormat *meta);
 
-    virtual status_t read(
-            MediaBufferBase **buffer, const ReadOptions *options = NULL);
+    virtual media_status_t read(
+            MediaBufferHelper **buffer, const ReadOptions *options = NULL);
 
-    virtual bool supportNonblockingRead() { return true; }
+    bool supportsNonBlockingRead() override { return false; }
 
 protected:
     virtual ~WAVSource();
@@ -78,64 +89,72 @@
 private:
     static const size_t kMaxFrameSize;
 
-    DataSourceBase *mDataSource;
-    MetaDataBase &mMeta;
+    DataSourceHelper *mDataSource;
+    AMediaFormat *mMeta;
     uint16_t mWaveFormat;
+    const bool mOutputFloat;
     int32_t mSampleRate;
     int32_t mNumChannels;
     int32_t mBitsPerSample;
     off64_t mOffset;
     size_t mSize;
     bool mStarted;
-    MediaBufferGroup *mGroup;
     off64_t mCurrentPos;
 
     WAVSource(const WAVSource &);
     WAVSource &operator=(const WAVSource &);
 };
 
-WAVExtractor::WAVExtractor(DataSourceBase *source)
+WAVExtractor::WAVExtractor(DataSourceHelper *source)
     : mDataSource(source),
       mValidFormat(false),
       mChannelMask(CHANNEL_MASK_USE_CHANNEL_ORDER) {
+    mTrackMeta = AMediaFormat_new();
     mInitCheck = init();
 }
 
 WAVExtractor::~WAVExtractor() {
+    delete mDataSource;
+    AMediaFormat_delete(mTrackMeta);
 }
 
-status_t WAVExtractor::getMetaData(MetaDataBase &meta) {
-    meta.clear();
+media_status_t WAVExtractor::getMetaData(AMediaFormat *meta) {
+    AMediaFormat_clear(meta);
     if (mInitCheck == OK) {
-        meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_WAV);
+        AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_CONTAINER_WAV);
     }
 
-    return OK;
+    return AMEDIA_OK;
 }
 
 size_t WAVExtractor::countTracks() {
     return mInitCheck == OK ? 1 : 0;
 }
 
-MediaTrack *WAVExtractor::getTrack(size_t index) {
+MediaTrackHelper *WAVExtractor::getTrack(size_t index) {
     if (mInitCheck != OK || index > 0) {
         return NULL;
     }
 
     return new WAVSource(
             mDataSource, mTrackMeta,
-            mWaveFormat, mBitsPerSample, mDataOffset, mDataSize);
+            mWaveFormat, shouldExtractorOutputFloat(mBitsPerSample), mDataOffset, mDataSize);
 }
 
-status_t WAVExtractor::getTrackMetaData(
-        MetaDataBase &meta,
+media_status_t WAVExtractor::getTrackMetaData(
+        AMediaFormat *meta,
         size_t index, uint32_t /* flags */) {
     if (mInitCheck != OK || index > 0) {
-        return UNKNOWN_ERROR;
+        return AMEDIA_ERROR_UNKNOWN;
     }
 
-    meta = mTrackMeta;
-    return OK;
+    const media_status_t status = AMediaFormat_copy(meta, mTrackMeta);
+    if (status == OK) {
+        AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_PCM_ENCODING,
+                shouldExtractorOutputFloat(mBitsPerSample)
+                        ? kAudioEncodingPcmFloat : kAudioEncodingPcm16bit);
+    }
+    return status;
 }
 
 status_t WAVExtractor::init() {
@@ -185,7 +204,7 @@
                     && mWaveFormat != WAVE_FORMAT_MULAW
                     && mWaveFormat != WAVE_FORMAT_MSGSM
                     && mWaveFormat != WAVE_FORMAT_EXTENSIBLE) {
-                return ERROR_UNSUPPORTED;
+                return AMEDIA_ERROR_UNSUPPORTED;
             }
 
             uint8_t fmtSize = 16;
@@ -198,13 +217,13 @@
 
             mNumChannels = U16_LE_AT(&formatSpec[2]);
 
-            if (mNumChannels < 1 || mNumChannels > 8) {
+            if (mNumChannels < 1 || mNumChannels > FCC_8) {
                 ALOGE("Unsupported number of channels (%d)", mNumChannels);
-                return ERROR_UNSUPPORTED;
+                return AMEDIA_ERROR_UNSUPPORTED;
             }
 
             if (mWaveFormat != WAVE_FORMAT_EXTENSIBLE) {
-                if (mNumChannels != 1 && mNumChannels != 2) {
+                if (mNumChannels != 1 && mNumChannels != FCC_2) {
                     ALOGW("More than 2 channels (%d) in non-WAVE_EXT, unknown channel mask",
                             mNumChannels);
                 }
@@ -224,7 +243,7 @@
                     if (validBitsPerSample != 0) {
                         ALOGE("validBits(%d) != bitsPerSample(%d) are not supported",
                                 validBitsPerSample, mBitsPerSample);
-                        return ERROR_UNSUPPORTED;
+                        return AMEDIA_ERROR_UNSUPPORTED;
                     } else {
                         // we only support valitBitsPerSample == bitsPerSample but some WAV_EXT
                         // writers don't correctly set the valid bits value, and leave it at 0.
@@ -284,34 +303,33 @@
                 mDataOffset = offset;
                 mDataSize = chunkSize;
 
-                mTrackMeta.clear();
+                AMediaFormat_clear(mTrackMeta);
 
                 switch (mWaveFormat) {
                     case WAVE_FORMAT_PCM:
                     case WAVE_FORMAT_IEEE_FLOAT:
-                        mTrackMeta.setCString(
-                                kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
+                        AMediaFormat_setString(mTrackMeta,
+                                AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_RAW);
                         break;
                     case WAVE_FORMAT_ALAW:
-                        mTrackMeta.setCString(
-                                kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_ALAW);
+                        AMediaFormat_setString(mTrackMeta,
+                                AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_G711_ALAW);
                         break;
                     case WAVE_FORMAT_MSGSM:
-                        mTrackMeta.setCString(
-                                kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MSGSM);
+                        AMediaFormat_setString(mTrackMeta,
+                                AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_MSGSM);
                         break;
                     default:
                         CHECK_EQ(mWaveFormat, (uint16_t)WAVE_FORMAT_MULAW);
-                        mTrackMeta.setCString(
-                                kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_MLAW);
+                        AMediaFormat_setString(mTrackMeta,
+                                AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_G711_MLAW);
                         break;
                 }
 
-                mTrackMeta.setInt32(kKeyChannelCount, mNumChannels);
-                mTrackMeta.setInt32(kKeyChannelMask, mChannelMask);
-                mTrackMeta.setInt32(kKeySampleRate, mSampleRate);
-                mTrackMeta.setInt32(kKeyPcmEncoding, kAudioEncodingPcm16bit);
-
+                AMediaFormat_setInt32(mTrackMeta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, mNumChannels);
+                AMediaFormat_setInt32(mTrackMeta, AMEDIAFORMAT_KEY_CHANNEL_MASK, mChannelMask);
+                AMediaFormat_setInt32(mTrackMeta, AMEDIAFORMAT_KEY_SAMPLE_RATE, mSampleRate);
+                AMediaFormat_setInt32(mTrackMeta, AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, mBitsPerSample);
                 int64_t durationUs = 0;
                 if (mWaveFormat == WAVE_FORMAT_MSGSM) {
                     // 65 bytes decode to 320 8kHz samples
@@ -321,18 +339,18 @@
                     size_t bytesPerSample = mBitsPerSample >> 3;
 
                     if (!bytesPerSample || !mNumChannels)
-                        return ERROR_MALFORMED;
+                        return AMEDIA_ERROR_MALFORMED;
 
                     size_t num_samples = mDataSize / (mNumChannels * bytesPerSample);
 
                     if (!mSampleRate)
-                        return ERROR_MALFORMED;
+                        return AMEDIA_ERROR_MALFORMED;
 
                     durationUs =
                         1000000LL * num_samples / mSampleRate;
                 }
 
-                mTrackMeta.setInt64(kKeyDuration, durationUs);
+                AMediaFormat_setInt64(mTrackMeta, AMEDIAFORMAT_KEY_DURATION, durationUs);
 
                 return OK;
             }
@@ -347,25 +365,21 @@
 const size_t WAVSource::kMaxFrameSize = 32768;
 
 WAVSource::WAVSource(
-        DataSourceBase *dataSource,
-        MetaDataBase &meta,
+        DataSourceHelper *dataSource,
+        AMediaFormat *meta,
         uint16_t waveFormat,
-        int32_t bitsPerSample,
+        bool outputFloat,
         off64_t offset, size_t size)
     : mDataSource(dataSource),
       mMeta(meta),
       mWaveFormat(waveFormat),
-      mSampleRate(0),
-      mNumChannels(0),
-      mBitsPerSample(bitsPerSample),
+      mOutputFloat(outputFloat),
       mOffset(offset),
       mSize(size),
-      mStarted(false),
-      mGroup(NULL) {
-    CHECK(mMeta.findInt32(kKeySampleRate, &mSampleRate));
-    CHECK(mMeta.findInt32(kKeyChannelCount, &mNumChannels));
-
-    mMeta.setInt32(kKeyMaxInputSize, kMaxFrameSize);
+      mStarted(false) {
+    CHECK(AMediaFormat_getInt32(mMeta, AMEDIAFORMAT_KEY_SAMPLE_RATE, &mSampleRate));
+    CHECK(AMediaFormat_getInt32(mMeta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &mNumChannels));
+    CHECK(AMediaFormat_getInt32(mMeta, AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, &mBitsPerSample));
 }
 
 WAVSource::~WAVSource() {
@@ -374,52 +388,51 @@
     }
 }
 
-status_t WAVSource::start(MetaDataBase * /* params */) {
+media_status_t WAVSource::start() {
     ALOGV("WAVSource::start");
 
     CHECK(!mStarted);
 
     // some WAV files may have large audio buffers that use shared memory transfer.
-    mGroup = new MediaBufferGroup(4 /* buffers */, kMaxFrameSize);
-
-    if (mBitsPerSample == 8) {
-        // As a temporary buffer for 8->16 bit conversion.
-        mGroup->add_buffer(MediaBufferBase::Create(kMaxFrameSize));
+    if (!mBufferGroup->init(4 /* buffers */, kMaxFrameSize)) {
+        return AMEDIA_ERROR_UNKNOWN;
     }
 
     mCurrentPos = mOffset;
 
     mStarted = true;
 
-    return OK;
+    return AMEDIA_OK;
 }
 
-status_t WAVSource::stop() {
+media_status_t WAVSource::stop() {
     ALOGV("WAVSource::stop");
 
     CHECK(mStarted);
 
-    delete mGroup;
-    mGroup = NULL;
-
     mStarted = false;
 
-    return OK;
+    return AMEDIA_OK;
 }
 
-status_t WAVSource::getFormat(MetaDataBase &meta) {
+media_status_t WAVSource::getFormat(AMediaFormat *meta) {
     ALOGV("WAVSource::getFormat");
 
-    meta = mMeta;
-    return OK;
+    const media_status_t status = AMediaFormat_copy(meta, mMeta);
+    if (status == OK) {
+        AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, kMaxFrameSize);
+        AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_PCM_ENCODING,
+                mOutputFloat ? kAudioEncodingPcmFloat : kAudioEncodingPcm16bit);
+    }
+    return status;
 }
 
-status_t WAVSource::read(
-        MediaBufferBase **out, const ReadOptions *options) {
+media_status_t WAVSource::read(
+        MediaBufferHelper **out, const ReadOptions *options) {
     *out = NULL;
 
-    if (options != nullptr && options->getNonBlocking() && !mGroup->has_buffers()) {
-        return WOULD_BLOCK;
+    if (options != nullptr && options->getNonBlocking() && !mBufferGroup->has_buffers()) {
+        return AMEDIA_ERROR_WOULD_BLOCK;
     }
 
     int64_t seekTimeUs;
@@ -441,18 +454,22 @@
         mCurrentPos = pos + mOffset;
     }
 
-    MediaBufferBase *buffer;
-    status_t err = mGroup->acquire_buffer(&buffer);
+    MediaBufferHelper *buffer;
+    media_status_t err = mBufferGroup->acquire_buffer(&buffer);
     if (err != OK) {
         return err;
     }
 
-    // make sure that maxBytesToRead is multiple of 3, in 24-bit case
-    size_t maxBytesToRead =
-        mBitsPerSample == 8 ? kMaxFrameSize / 2 : 
-        (mBitsPerSample == 24 ? 3*(kMaxFrameSize/3): kMaxFrameSize);
+    // maxBytesToRead may be reduced so that in-place data conversion will fit in buffer size.
+    const size_t bufferSize = std::min(buffer->size(), kMaxFrameSize);
+    size_t maxBytesToRead;
+    if (mOutputFloat) { // destination is float at 4 bytes per sample, source may be less.
+        maxBytesToRead = (mBitsPerSample / 8) * (bufferSize / 4);
+    } else { // destination is int16_t at 2 bytes per sample, only source of 8 bits is less.
+        maxBytesToRead = mBitsPerSample == 8 ? bufferSize / 2 : bufferSize;
+    }
 
-    size_t maxBytesAvailable =
+    const size_t maxBytesAvailable =
         (mCurrentPos - mOffset >= (off64_t)mSize)
             ? 0 : mSize - (mCurrentPos - mOffset);
 
@@ -481,45 +498,59 @@
         buffer->release();
         buffer = NULL;
 
-        return ERROR_END_OF_STREAM;
+        return AMEDIA_ERROR_END_OF_STREAM;
     }
 
     buffer->set_range(0, n);
 
     // TODO: add capability to return data as float PCM instead of 16 bit PCM.
     if (mWaveFormat == WAVE_FORMAT_PCM) {
-        if (mBitsPerSample == 8) {
-            // Convert 8-bit unsigned samples to 16-bit signed.
-
-            // Create new buffer with 2 byte wide samples
-            MediaBufferBase *tmp;
-            CHECK_EQ(mGroup->acquire_buffer(&tmp), (status_t)OK);
-            tmp->set_range(0, 2 * n);
-
-            memcpy_to_i16_from_u8((int16_t *)tmp->data(), (const uint8_t *)buffer->data(), n);
-            buffer->release();
-            buffer = tmp;
-        } else if (mBitsPerSample == 24) {
-            // Convert 24-bit signed samples to 16-bit signed in place
-            const size_t numSamples = n / 3;
-
-            memcpy_to_i16_from_p24((int16_t *)buffer->data(), (const uint8_t *)buffer->data(), numSamples);
+        const size_t bytesPerFrame = (mBitsPerSample >> 3) * mNumChannels;
+        const size_t numFrames = n / bytesPerFrame;
+        const size_t numSamples = numFrames * mNumChannels;
+        if (mOutputFloat) {
+            float *fdest = (float *)buffer->data();
+            buffer->set_range(0, 4 * numSamples);
+            switch (mBitsPerSample) {
+            case 8: {
+                memcpy_to_float_from_u8(fdest, (const uint8_t *)buffer->data(), numSamples);
+            } break;
+            case 16: {
+                memcpy_to_float_from_i16(fdest, (const int16_t *)buffer->data(), numSamples);
+            } break;
+            case 24: {
+                memcpy_to_float_from_p24(fdest, (const uint8_t *)buffer->data(), numSamples);
+            } break;
+            case 32: { // buffer range is correct
+                memcpy_to_float_from_i32(fdest, (const int32_t *)buffer->data(), numSamples);
+            } break;
+            }
+        } else {
+            int16_t *idest = (int16_t *)buffer->data();
             buffer->set_range(0, 2 * numSamples);
-        }  else if (mBitsPerSample == 32) {
-            // Convert 32-bit signed samples to 16-bit signed in place
-            const size_t numSamples = n / 4;
-
-            memcpy_to_i16_from_i32((int16_t *)buffer->data(), (const int32_t *)buffer->data(), numSamples);
-            buffer->set_range(0, 2 * numSamples);
+            switch (mBitsPerSample) {
+            case 8: {
+                memcpy_to_i16_from_u8(idest, (const uint8_t *)buffer->data(), numSamples);
+            } break;
+            case 16:
+                // no conversion needed
+                break;
+            case 24: {
+                memcpy_to_i16_from_p24(idest, (const uint8_t *)buffer->data(), numSamples);
+            } break;
+            case 32: {
+                memcpy_to_i16_from_i32(idest, (const int32_t *)buffer->data(), numSamples);
+            } break;
+            }
         }
     } else if (mWaveFormat == WAVE_FORMAT_IEEE_FLOAT) {
-        if (mBitsPerSample == 32) {
-            // Convert 32-bit float samples to 16-bit signed in place
+        if (!mOutputFloat) { // mBitsPerSample == 32
+            int16_t *idest = (int16_t *)buffer->data();
             const size_t numSamples = n / 4;
-
-            memcpy_to_i16_from_float((int16_t *)buffer->data(), (const float *)buffer->data(), numSamples);
+            memcpy_to_i16_from_float(idest, (const float *)buffer->data(), numSamples);
             buffer->set_range(0, 2 * numSamples);
         }
+        // Note: if output encoding is float, no need to convert if source is float.
     }
 
     int64_t timeStampUs = 0;
@@ -532,39 +563,43 @@
                 / (mNumChannels * bytesPerSample) / mSampleRate;
     }
 
-    buffer->meta_data().setInt64(kKeyTime, timeStampUs);
+    AMediaFormat *meta = buffer->meta_data();
+    AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeStampUs);
+    AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
 
-    buffer->meta_data().setInt32(kKeyIsSyncFrame, 1);
     mCurrentPos += n;
 
     *out = buffer;
 
-    return OK;
+    return AMEDIA_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
-static MediaExtractor* CreateExtractor(
-        DataSourceBase *source,
+static CMediaExtractor* CreateExtractor(
+        CDataSource *source,
         void *) {
-    return new WAVExtractor(source);
+    return wrap(new WAVExtractor(new DataSourceHelper(source)));
 }
 
-static MediaExtractor::CreatorFunc Sniff(
-        DataSourceBase *source,
+static CreatorFunc Sniff(
+        CDataSource *source,
         float *confidence,
         void **,
-        MediaExtractor::FreeMetaFunc *) {
+        FreeMetaFunc *) {
+    DataSourceHelper *helper = new DataSourceHelper(source);
     char header[12];
-    if (source->readAt(0, header, sizeof(header)) < (ssize_t)sizeof(header)) {
+    if (helper->readAt(0, header, sizeof(header)) < (ssize_t)sizeof(header)) {
+        delete helper;
         return NULL;
     }
 
     if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) {
+        delete helper;
         return NULL;
     }
 
-    MediaExtractor *extractor = new WAVExtractor(source);
+    WAVExtractor *extractor = new WAVExtractor(helper); // extractor owns the helper
     int numTracks = extractor->countTracks();
     delete extractor;
     if (numTracks == 0) {
@@ -576,16 +611,21 @@
     return CreateExtractor;
 }
 
+static const char *extensions[] = {
+    "wav",
+    NULL
+};
+
 extern "C" {
 // This is the only symbol that needs to be exported
 __attribute__ ((visibility ("default")))
-MediaExtractor::ExtractorDef GETEXTRACTORDEF() {
+ExtractorDef GETEXTRACTORDEF() {
     return {
-        MediaExtractor::EXTRACTORDEF_VERSION,
+        EXTRACTORDEF_VERSION,
         UUID("7d613858-5837-4a38-84c5-332d1cddee27"),
         1, // version
         "WAV Extractor",
-        Sniff
+        { .v3 = {Sniff, extensions} },
     };
 }
 
diff --git a/media/extractors/wav/WAVExtractor.h b/media/extractors/wav/WAVExtractor.h
index 467d0b7..b514196 100644
--- a/media/extractors/wav/WAVExtractor.h
+++ b/media/extractors/wav/WAVExtractor.h
@@ -19,30 +19,31 @@
 #define WAV_EXTRACTOR_H_
 
 #include <utils/Errors.h>
-#include <media/MediaExtractor.h>
-#include <media/stagefright/MetaDataBase.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
+#include <media/NdkMediaFormat.h>
 
 namespace android {
 
 struct AMessage;
-class DataSourceBase;
+struct CDataSource;
 class String8;
 
-class WAVExtractor : public MediaExtractor {
+class WAVExtractor : public MediaExtractorPluginHelper {
 public:
-    explicit WAVExtractor(DataSourceBase *source);
+    explicit WAVExtractor(DataSourceHelper *source);
 
     virtual size_t countTracks();
-    virtual MediaTrack *getTrack(size_t index);
-    virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags);
+    virtual MediaTrackHelper *getTrack(size_t index);
+    virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
 
-    virtual status_t getMetaData(MetaDataBase& meta);
+    virtual media_status_t getMetaData(AMediaFormat *meta);
     virtual const char * name() { return "WAVExtractor"; }
 
     virtual ~WAVExtractor();
 
 private:
-    DataSourceBase *mDataSource;
+    DataSourceHelper *mDataSource;
     status_t mInitCheck;
     bool mValidFormat;
     uint16_t mWaveFormat;
@@ -52,7 +53,7 @@
     uint16_t mBitsPerSample;
     off64_t mDataOffset;
     size_t mDataSize;
-    MetaDataBase mTrackMeta;
+    AMediaFormat *mTrackMeta;
 
     status_t init();
 
diff --git a/media/img_utils/include/img_utils/DngUtils.h b/media/img_utils/include/img_utils/DngUtils.h
index de8f120..8819f87 100644
--- a/media/img_utils/include/img_utils/DngUtils.h
+++ b/media/img_utils/include/img_utils/DngUtils.h
@@ -49,6 +49,7 @@
             CFA_RGGB,
             CFA_BGGR,
             CFA_GBRG,
+            CFA_NONE,
         };
 
         OpcodeListBuilder();
@@ -89,7 +90,6 @@
                                                 CfaLayout cfa,
                                                 const float* lensShadingMap);
 
-
         /**
          * Add a GainMap opcode with the given fields.  The mapGains array
          * must have mapPointsV * mapPointsH * mapPlanes elements.
@@ -197,6 +197,33 @@
 
         status_t addOpcodePreamble(uint32_t opcodeId);
 
+    private:
+        /**
+         * Add Bayer GainMap opcode(s) for the given metadata parameters.
+         * CFA layout must match the layout of the shading map passed into the
+         * lensShadingMap parameter.
+         *
+         * Returns OK on success, or a negative error code.
+         */
+        status_t addBayerGainMapsForMetadata(uint32_t lsmWidth,
+                                                uint32_t lsmHeight,
+                                                uint32_t activeAreaWidth,
+                                                uint32_t activeAreaHeight,
+                                                CfaLayout cfa,
+                                                const float* lensShadingMap);
+
+        /**
+         * Add Bayer GainMap opcode(s) for the given metadata parameters.
+         * CFA layout must match the layout of the shading map passed into the
+         * lensShadingMap parameter.
+         *
+         * Returns OK on success, or a negative error code.
+         */
+        status_t addMonochromeGainMapsForMetadata(uint32_t lsmWidth,
+                                                uint32_t lsmHeight,
+                                                uint32_t activeAreaWidth,
+                                                uint32_t activeAreaHeight,
+                                                const float* lensShadingMap);
 };
 
 } /*namespace img_utils*/
diff --git a/media/img_utils/src/DngUtils.cpp b/media/img_utils/src/DngUtils.cpp
index 9ac7e2a..7914030 100644
--- a/media/img_utils/src/DngUtils.cpp
+++ b/media/img_utils/src/DngUtils.cpp
@@ -60,34 +60,36 @@
                                                    uint32_t activeAreaRight,
                                                    CfaLayout cfa,
                                                    const float* lensShadingMap) {
+    status_t err = OK;
     uint32_t activeAreaWidth = activeAreaRight - activeAreaLeft;
     uint32_t activeAreaHeight = activeAreaBottom - activeAreaTop;
-    double spacingV = 1.0 / std::max(1u, lsmHeight - 1);
-    double spacingH = 1.0 / std::max(1u, lsmWidth - 1);
 
-    std::vector<float> redMapVector(lsmWidth * lsmHeight);
-    float *redMap = redMapVector.data();
-
-    std::vector<float> greenEvenMapVector(lsmWidth * lsmHeight);
-    float *greenEvenMap = greenEvenMapVector.data();
-
-    std::vector<float> greenOddMapVector(lsmWidth * lsmHeight);
-    float *greenOddMap = greenOddMapVector.data();
-
-    std::vector<float> blueMapVector(lsmWidth * lsmHeight);
-    float *blueMap = blueMapVector.data();
-
-    size_t lsmMapSize = lsmWidth * lsmHeight * 4;
-
-    // Split lens shading map channels into separate arrays
-    size_t j = 0;
-    for (size_t i = 0; i < lsmMapSize; i += 4, ++j) {
-        redMap[j] = lensShadingMap[i + LSM_R_IND];
-        greenEvenMap[j] = lensShadingMap[i + LSM_GE_IND];
-        greenOddMap[j] = lensShadingMap[i + LSM_GO_IND];
-        blueMap[j] = lensShadingMap[i + LSM_B_IND];
+    switch (cfa) {
+        case CFA_RGGB:
+        case CFA_GRBG:
+        case CFA_GBRG:
+        case CFA_BGGR:
+            err = addBayerGainMapsForMetadata(lsmWidth, lsmHeight, activeAreaWidth,
+                    activeAreaHeight, cfa, lensShadingMap);
+            break;
+        case CFA_NONE:
+            err = addMonochromeGainMapsForMetadata(lsmWidth, lsmHeight, activeAreaWidth,
+                    activeAreaHeight, lensShadingMap);
+            break;
+        default:
+            ALOGE("%s: Unknown CFA layout %d", __FUNCTION__, cfa);
+            err = BAD_VALUE;
+            break;
     }
+    return err;
+}
 
+status_t OpcodeListBuilder::addBayerGainMapsForMetadata(uint32_t lsmWidth,
+                                                   uint32_t lsmHeight,
+                                                   uint32_t activeAreaWidth,
+                                                   uint32_t activeAreaHeight,
+                                                   CfaLayout cfa,
+                                                   const float* lensShadingMap) {
     uint32_t redTop = 0;
     uint32_t redLeft = 0;
     uint32_t greenEvenTop = 0;
@@ -143,10 +145,36 @@
             return BAD_VALUE;
     }
 
+    std::vector<float> redMapVector(lsmWidth * lsmHeight);
+    float *redMap = redMapVector.data();
+
+    std::vector<float> greenEvenMapVector(lsmWidth * lsmHeight);
+    float *greenEvenMap = greenEvenMapVector.data();
+
+    std::vector<float> greenOddMapVector(lsmWidth * lsmHeight);
+    float *greenOddMap = greenOddMapVector.data();
+
+    std::vector<float> blueMapVector(lsmWidth * lsmHeight);
+    float *blueMap = blueMapVector.data();
+
+    double spacingV = 1.0 / std::max(1u, lsmHeight - 1);
+    double spacingH = 1.0 / std::max(1u, lsmWidth - 1);
+
+    size_t lsmMapSize = lsmWidth * lsmHeight * 4;
+
+    // Split lens shading map channels into separate arrays
+    size_t j = 0;
+    for (size_t i = 0; i < lsmMapSize; i += 4, ++j) {
+        redMap[j] = lensShadingMap[i + LSM_R_IND];
+        greenEvenMap[j] = lensShadingMap[i + LSM_GE_IND];
+        greenOddMap[j] = lensShadingMap[i + LSM_GO_IND];
+        blueMap[j] = lensShadingMap[i + LSM_B_IND];
+    }
+
     status_t err = addGainMap(/*top*/redTop,
                               /*left*/redLeft,
-                              /*bottom*/activeAreaHeight - 1,
-                              /*right*/activeAreaWidth - 1,
+                              /*bottom*/activeAreaHeight,
+                              /*right*/activeAreaWidth,
                               /*plane*/0,
                               /*planes*/1,
                               /*rowPitch*/2,
@@ -163,8 +191,8 @@
 
     err = addGainMap(/*top*/greenEvenTop,
                      /*left*/greenEvenLeft,
-                     /*bottom*/activeAreaHeight - 1,
-                     /*right*/activeAreaWidth - 1,
+                     /*bottom*/activeAreaHeight,
+                     /*right*/activeAreaWidth,
                      /*plane*/0,
                      /*planes*/1,
                      /*rowPitch*/2,
@@ -181,8 +209,8 @@
 
     err = addGainMap(/*top*/greenOddTop,
                      /*left*/greenOddLeft,
-                     /*bottom*/activeAreaHeight - 1,
-                     /*right*/activeAreaWidth - 1,
+                     /*bottom*/activeAreaHeight,
+                     /*right*/activeAreaWidth,
                      /*plane*/0,
                      /*planes*/1,
                      /*rowPitch*/2,
@@ -199,8 +227,8 @@
 
     err = addGainMap(/*top*/blueTop,
                      /*left*/blueLeft,
-                     /*bottom*/activeAreaHeight - 1,
-                     /*right*/activeAreaWidth - 1,
+                     /*bottom*/activeAreaHeight,
+                     /*right*/activeAreaWidth,
                      /*plane*/0,
                      /*planes*/1,
                      /*rowPitch*/2,
@@ -216,6 +244,46 @@
     return err;
 }
 
+status_t OpcodeListBuilder::addMonochromeGainMapsForMetadata(uint32_t lsmWidth,
+                                                   uint32_t lsmHeight,
+                                                   uint32_t activeAreaWidth,
+                                                   uint32_t activeAreaHeight,
+                                                   const float* lensShadingMap) {
+    std::vector<float> mapVector(lsmWidth * lsmHeight);
+    float *map = mapVector.data();
+
+    double spacingV = 1.0 / std::max(1u, lsmHeight - 1);
+    double spacingH = 1.0 / std::max(1u, lsmWidth - 1);
+
+    size_t lsmMapSize = lsmWidth * lsmHeight * 4;
+
+    // Split lens shading map channels into separate arrays
+    size_t j = 0;
+    for (size_t i = 0; i < lsmMapSize; i += 4, ++j) {
+        map[j] = lensShadingMap[i];
+    }
+
+    status_t err = addGainMap(/*top*/0,
+                              /*left*/0,
+                              /*bottom*/activeAreaHeight,
+                              /*right*/activeAreaWidth,
+                              /*plane*/0,
+                              /*planes*/1,
+                              /*rowPitch*/1,
+                              /*colPitch*/1,
+                              /*mapPointsV*/lsmHeight,
+                              /*mapPointsH*/lsmWidth,
+                              /*mapSpacingV*/spacingV,
+                              /*mapSpacingH*/spacingH,
+                              /*mapOriginV*/0,
+                              /*mapOriginH*/0,
+                              /*mapPlanes*/1,
+                              /*mapGains*/map);
+    if (err != OK) return err;
+
+    return err;
+}
+
 status_t OpcodeListBuilder::addGainMap(uint32_t top,
                                        uint32_t left,
                                        uint32_t bottom,
@@ -296,8 +364,8 @@
         return BAD_VALUE;
     }
 
-    double normalizedOCX = opticalCenterX / static_cast<double>(activeArrayWidth - 1);
-    double normalizedOCY = opticalCenterY / static_cast<double>(activeArrayHeight - 1);
+    double normalizedOCX = opticalCenterX / static_cast<double>(activeArrayWidth);
+    double normalizedOCY = opticalCenterY / static_cast<double>(activeArrayHeight);
 
     normalizedOCX = CLAMP(normalizedOCX, 0, 1);
     normalizedOCY = CLAMP(normalizedOCY, 0, 1);
diff --git a/media/libaaudio/Android.bp b/media/libaaudio/Android.bp
index f00f7a8..16958f9 100644
--- a/media/libaaudio/Android.bp
+++ b/media/libaaudio/Android.bp
@@ -32,6 +32,6 @@
 cc_library_headers {
     name: "libaaudio_headers",
     export_include_dirs: ["include"],
+    version_script: "libaaudio.map.txt",
 }
 
-subdirs = ["*"]
diff --git a/media/libaaudio/examples/Android.bp b/media/libaaudio/examples/Android.bp
index 639fab2..49bd5ee 100644
--- a/media/libaaudio/examples/Android.bp
+++ b/media/libaaudio/examples/Android.bp
@@ -1,5 +1,3 @@
-subdirs = ["*"]
-
 cc_library_headers {
     name: "libaaudio_example_utils",
     export_include_dirs: ["utils"],
diff --git a/media/libaaudio/examples/input_monitor/Android.bp b/media/libaaudio/examples/input_monitor/Android.bp
index d8c5843..5d399b5 100644
--- a/media/libaaudio/examples/input_monitor/Android.bp
+++ b/media/libaaudio/examples/input_monitor/Android.bp
@@ -5,6 +5,7 @@
     cflags: ["-Wall", "-Werror"],
     shared_libs: ["libaaudio"],
     header_libs: ["libaaudio_example_utils"],
+    pack_relocations: false,
 }
 
 cc_test {
@@ -14,4 +15,5 @@
     cflags: ["-Wall", "-Werror"],
     shared_libs: ["libaaudio"],
     header_libs: ["libaaudio_example_utils"],
+    pack_relocations: false,
 }
diff --git a/media/libaaudio/examples/input_monitor/jni/Android.mk b/media/libaaudio/examples/input_monitor/jni/Android.mk
deleted file mode 100644
index a0b981c..0000000
--- a/media/libaaudio/examples/input_monitor/jni/Android.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := tests
-LOCAL_C_INCLUDES := \
-    $(call include-path-for, audio-utils) \
-    frameworks/av/media/libaaudio/include \
-    frameworks/av/media/libaaudio/src \
-    frameworks/av/media/libaaudio/examples/utils
-
-# NDK recommends using this kind of relative path instead of an absolute path.
-LOCAL_SRC_FILES:= ../src/input_monitor.cpp
-LOCAL_CFLAGS := -Wall -Werror
-LOCAL_SHARED_LIBRARIES := libaaudio
-LOCAL_MODULE := input_monitor
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := tests
-LOCAL_C_INCLUDES := \
-    $(call include-path-for, audio-utils) \
-    frameworks/av/media/libaaudio/include \
-    frameworks/av/media/libaaudio/examples/utils
-
-LOCAL_SRC_FILES:= ../src/input_monitor_callback.cpp
-LOCAL_CFLAGS := -Wall -Werror
-LOCAL_SHARED_LIBRARIES := libaaudio
-LOCAL_MODULE := input_monitor_callback
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := libaaudio_prebuilt
-LOCAL_SRC_FILES := libaaudio.so
-LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
-include $(PREBUILT_SHARED_LIBRARY)
diff --git a/media/libaaudio/examples/input_monitor/jni/Application.mk b/media/libaaudio/examples/input_monitor/jni/Application.mk
deleted file mode 100644
index e74475c..0000000
--- a/media/libaaudio/examples/input_monitor/jni/Application.mk
+++ /dev/null
@@ -1,3 +0,0 @@
-# TODO remove then when we support other architectures
-APP_ABI := arm64-v8a
-APP_CPPFLAGS += -std=c++11
diff --git a/media/libaaudio/examples/loopback/Android.bp b/media/libaaudio/examples/loopback/Android.bp
index 5b7d956..53e5020 100644
--- a/media/libaaudio/examples/loopback/Android.bp
+++ b/media/libaaudio/examples/loopback/Android.bp
@@ -9,4 +9,5 @@
         "libaudioutils",
         ],
     header_libs: ["libaaudio_example_utils"],
+    pack_relocations: false,
 }
diff --git a/media/libaaudio/examples/loopback/jni/Android.mk b/media/libaaudio/examples/loopback/jni/Android.mk
deleted file mode 100644
index aebe877..0000000
--- a/media/libaaudio/examples/loopback/jni/Android.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := tests
-LOCAL_C_INCLUDES := \
-    $(call include-path-for, audio-utils) \
-    frameworks/av/media/libaaudio/include \
-    frameworks/av/media/libaaudio/examples/utils
-
-# NDK recommends using this kind of relative path instead of an absolute path.
-LOCAL_SRC_FILES:= ../src/loopback.cpp
-LOCAL_CFLAGS := -Wall -Werror
-LOCAL_STATIC_LIBRARIES := libsndfile
-LOCAL_SHARED_LIBRARIES := libaaudio libaudioutils
-LOCAL_MODULE := aaudio_loopback
-include $(BUILD_EXECUTABLE)
diff --git a/media/libaaudio/examples/loopback/jni/Application.mk b/media/libaaudio/examples/loopback/jni/Application.mk
deleted file mode 100644
index ba44f37..0000000
--- a/media/libaaudio/examples/loopback/jni/Application.mk
+++ /dev/null
@@ -1 +0,0 @@
-APP_CPPFLAGS += -std=c++11
diff --git a/media/libaaudio/examples/loopback/src/LoopbackAnalyzer.h b/media/libaaudio/examples/loopback/src/LoopbackAnalyzer.h
index ef9a753..8eb70b1 100644
--- a/media/libaaudio/examples/loopback/src/LoopbackAnalyzer.h
+++ b/media/libaaudio/examples/loopback/src/LoopbackAnalyzer.h
@@ -34,12 +34,123 @@
 
 // Tag for machine readable results as property = value pairs
 #define LOOPBACK_RESULT_TAG      "RESULT: "
-#define LOOPBACK_SAMPLE_RATE     48000
 
-#define MILLIS_PER_SECOND        1000
+constexpr int32_t kDefaultSampleRate = 48000;
+constexpr int32_t kMillisPerSecond   = 1000;
+constexpr int32_t kMinLatencyMillis  = 4;    // arbitrary and very low
+constexpr int32_t kMaxLatencyMillis  = 400;  // arbitrary and generous
+constexpr double  kMaxEchoGain       = 10.0; // based on experiments, otherwise too noisy
+constexpr double  kMinimumConfidence = 0.5;
 
-#define MAX_ZEROTH_PARTIAL_BINS  40
-constexpr double MAX_ECHO_GAIN = 10.0; // based on experiments, otherwise autocorrelation too noisy
+static void printAudioScope(float sample) {
+    const int maxStars = 80; // arbitrary, fits on one line
+    char c = '*';
+    if (sample < -1.0) {
+        sample = -1.0;
+        c = '$';
+    } else if (sample > 1.0) {
+        sample = 1.0;
+        c = '$';
+    }
+    int numSpaces = (int) (((sample + 1.0) * 0.5) * maxStars);
+    for (int i = 0; i < numSpaces; i++) {
+        putchar(' ');
+    }
+    printf("%c\n", c);
+}
+
+/*
+
+FIR filter designed with
+http://t-filter.appspot.com
+
+sampling frequency: 48000 Hz
+
+* 0 Hz - 8000 Hz
+  gain = 1.2
+  desired ripple = 5 dB
+  actual ripple = 5.595266169703693 dB
+
+* 12000 Hz - 20000 Hz
+  gain = 0
+  desired attenuation = -40 dB
+  actual attenuation = -37.58691566571914 dB
+
+*/
+
+#define FILTER_TAP_NUM 11
+
+static const float sFilterTaps8000[FILTER_TAP_NUM] = {
+        -0.05944219353343189f,
+        -0.07303434839503208f,
+        -0.037690487672689066f,
+        0.1870480506596512f,
+        0.3910337357836833f,
+        0.5333672385425637f,
+        0.3910337357836833f,
+        0.1870480506596512f,
+        -0.037690487672689066f,
+        -0.07303434839503208f,
+        -0.05944219353343189f
+};
+
+class LowPassFilter {
+public:
+
+    /*
+     * Filter one input sample.
+     * @return filtered output
+     */
+    float filter(float input) {
+        float output = 0.0f;
+        mX[mCursor] = input;
+        // Index backwards over x.
+        int xIndex = mCursor + FILTER_TAP_NUM;
+        // Write twice so we avoid having to wrap in the middle of the convolution.
+        mX[xIndex] = input;
+        for (int i = 0; i < FILTER_TAP_NUM; i++) {
+            output += sFilterTaps8000[i] * mX[xIndex--];
+        }
+        if (++mCursor >= FILTER_TAP_NUM) {
+            mCursor = 0;
+        }
+        return output;
+    }
+
+    /**
+     * @return true if PASSED
+     */
+    bool test() {
+        // Measure the impulse of the filter at different phases so we exercise
+        // all the wraparound cases in the FIR.
+        for (int offset = 0; offset < (FILTER_TAP_NUM * 2); offset++ ) {
+            // printf("LowPassFilter: cursor = %d\n", mCursor);
+            // Offset by one each time.
+            if (filter(0.0f) != 0.0f) {
+                printf("ERROR: filter should return 0.0 before impulse response\n");
+                return false;
+            }
+            for (int i = 0; i < FILTER_TAP_NUM; i++) {
+                float output = filter((i == 0) ? 1.0f : 0.0f); // impulse
+                if (output != sFilterTaps8000[i]) {
+                    printf("ERROR: filter should return impulse response\n");
+                    return false;
+                }
+            }
+            for (int i = 0; i < FILTER_TAP_NUM; i++) {
+                if (filter(0.0f) != 0.0f) {
+                    printf("ERROR: filter should return 0.0 after impulse response\n");
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+private:
+    float   mX[FILTER_TAP_NUM * 2]{}; // twice as big as needed to avoid wrapping
+    int32_t mCursor = 0;
+};
 
 // A narrow impulse seems to have better immunity against over estimating the
 // latency due to detecting subharmonics by the auto-correlator.
@@ -78,6 +189,12 @@
     int64_t mSeed = 99887766;
 };
 
+
+typedef struct LatencyReport_s {
+    double latencyInFrames;
+    double confidence;
+} LatencyReport;
+
 static double calculateCorrelation(const float *a,
                                    const float *b,
                                    int windowSize)
@@ -101,130 +218,75 @@
     return correlation;
 }
 
-static int calculateCorrelations(const float *haystack, int haystackSize,
-                                 const float *needle, int needleSize,
-                                 float *results, int resultSize)
-{
-    int maxCorrelations = haystackSize - needleSize;
-    int numCorrelations = std::min(maxCorrelations, resultSize);
-
-    for (int ic = 0; ic < numCorrelations; ic++) {
-        double correlation = calculateCorrelation(&haystack[ic], needle, needleSize);
-        results[ic] = correlation;
-    }
-
-    return numCorrelations;
-}
-
-/*==========================================================================================*/
-/**
- * Scan until we get a correlation of a single scan that goes over the tolerance level,
- * peaks then drops back down.
- */
-static double findFirstMatch(const float *haystack, int haystackSize,
-                             const float *needle, int needleSize, double threshold  )
-{
-    int ic;
-    // How many correlations can we calculate?
-    int numCorrelations = haystackSize - needleSize;
-    double maxCorrelation = 0.0;
-    int peakIndex = -1;
-    double location = -1.0;
-    const double backThresholdScaler = 0.5;
-
-    for (ic = 0; ic < numCorrelations; ic++) {
-        double correlation = calculateCorrelation(&haystack[ic], needle, needleSize);
-
-        if( (correlation > maxCorrelation) ) {
-            maxCorrelation = correlation;
-            peakIndex = ic;
-        }
-
-        //printf("PaQa_FindFirstMatch: ic = %4d, correlation = %8f, maxSum = %8f\n",
-        //    ic, correlation, maxSum );
-        // Are we past what we were looking for?
-        if((maxCorrelation > threshold) && (correlation < backThresholdScaler * maxCorrelation)) {
-            location = peakIndex;
-            break;
-        }
-    }
-
-    return location;
-}
-
-typedef struct LatencyReport_s {
-    double latencyInFrames;
-    double confidence;
-} LatencyReport;
-
-// Apply a technique similar to Harmonic Product Spectrum Analysis to find echo fundamental.
-// Using first echo instead of the original impulse for a better match.
-static int measureLatencyFromEchos(const float *haystack, int haystackSize,
-                            const float *needle, int needleSize,
-                            LatencyReport *report) {
-    const double threshold = 0.1;
-    printf("measureLatencyFromEchos: haystackSize = %d, needleSize = %d\n",
-           haystackSize, needleSize);
-
-    // Find first peak
-    int first = (int) (findFirstMatch(haystack,
-                                      haystackSize,
-                                      needle,
-                                      needleSize,
-                                      threshold) + 0.5);
-
-    // Use first echo as the needle for the other echos because
-    // it will be more similar.
-    needle = &haystack[first];
-    int again = (int) (findFirstMatch(haystack,
-                                      haystackSize,
-                                      needle,
-                                      needleSize,
-                                      threshold) + 0.5);
-
-    printf("measureLatencyFromEchos: first = %d, again at %d\n", first, again);
-    first = again;
-
+static int measureLatencyFromEchos(const float *data,
+                                   int32_t numFloats,
+                                   int32_t sampleRate,
+                                   LatencyReport *report) {
     // Allocate results array
-    int remaining = haystackSize - first;
-    const int maxReasonableLatencyFrames = 48000 * 2; // arbitrary but generous value
-    int numCorrelations = std::min(remaining, maxReasonableLatencyFrames);
-    float *correlations = new float[numCorrelations];
-    float *harmonicSums = new float[numCorrelations](); // set to zero
+    const int minReasonableLatencyFrames = sampleRate * kMinLatencyMillis / kMillisPerSecond;
+    const int maxReasonableLatencyFrames = sampleRate * kMaxLatencyMillis / kMillisPerSecond;
+    int32_t maxCorrelationSize = maxReasonableLatencyFrames * 3;
+    int numCorrelations = std::min(numFloats, maxCorrelationSize);
+    float *correlations = new float[numCorrelations]{};
+    float *harmonicSums = new float[numCorrelations]{};
 
-    // Generate correlation for every position.
-    numCorrelations = calculateCorrelations(&haystack[first], remaining,
-                                            needle, needleSize,
-                                            correlations, numCorrelations);
+    // Perform sliding auto-correlation.
+    // Skip first frames to avoid huge peak at zero offset.
+    for (int i = minReasonableLatencyFrames; i < numCorrelations; i++) {
+        int32_t remaining = numFloats - i;
+        float correlation = (float) calculateCorrelation(&data[i], data, remaining);
+        correlations[i] = correlation;
+        // printf("correlation[%d] = %f\n", ic, correlation);
+    }
 
-    // Add higher harmonics mapped onto lower harmonics.
-    // This reinforces the "fundamental" echo.
-    const int numEchoes = 10;
+    // Apply a technique similar to Harmonic Product Spectrum Analysis to find echo fundamental.
+    // Add higher harmonics mapped onto lower harmonics. This reinforces the "fundamental" echo.
+    const int numEchoes = 8;
     for (int partial = 1; partial < numEchoes; partial++) {
-        for (int i = 0; i < numCorrelations; i++) {
+        for (int i = minReasonableLatencyFrames; i < numCorrelations; i++) {
             harmonicSums[i / partial] += correlations[i] / partial;
         }
     }
 
     // Find highest peak in correlation array.
     float maxCorrelation = 0.0;
-    float sumOfPeaks = 0.0;
     int peakIndex = 0;
-    const int skip = MAX_ZEROTH_PARTIAL_BINS; // skip low bins
-    for (int i = skip; i < numCorrelations; i++) {
+    for (int i = 0; i < numCorrelations; i++) {
         if (harmonicSums[i] > maxCorrelation) {
             maxCorrelation = harmonicSums[i];
-            sumOfPeaks += maxCorrelation;
             peakIndex = i;
-            printf("maxCorrelation = %f at %d\n", maxCorrelation, peakIndex);
+            // printf("maxCorrelation = %f at %d\n", maxCorrelation, peakIndex);
         }
     }
-
     report->latencyInFrames = peakIndex;
-    if (sumOfPeaks < 0.0001) {
+/*
+    {
+        int32_t topPeak = peakIndex * 7 / 2;
+        for (int i = 0; i < topPeak; i++) {
+            float sample = harmonicSums[i];
+            printf("%4d: %7.5f ", i, sample);
+            printAudioScope(sample);
+        }
+    }
+*/
+
+    // Calculate confidence.
+    if (maxCorrelation < 0.001) {
         report->confidence = 0.0;
     } else {
-        report->confidence = maxCorrelation / sumOfPeaks;
+        // Compare peak to average value around peak.
+        int32_t numSamples = std::min(numCorrelations, peakIndex * 2);
+        if (numSamples <= 0) {
+            report->confidence = 0.0;
+        } else {
+            double sum = 0.0;
+            for (int i = 0; i < numSamples; i++) {
+                sum += harmonicSums[i];
+            }
+            const double average = sum / numSamples;
+            const double ratio = average / maxCorrelation; // will be < 1.0
+            report->confidence = 1.0 - sqrt(ratio);
+        }
     }
 
     delete[] correlations;
@@ -248,7 +310,7 @@
     }
 
     // Write SHORT data from the first channel.
-    int write(int16_t *inputData, int inputChannelCount, int numFrames) {
+    int32_t write(int16_t *inputData, int32_t inputChannelCount, int32_t numFrames) {
         // stop at end of buffer
         if ((mFrameCounter + numFrames) > mMaxFrames) {
             numFrames = mMaxFrames - mFrameCounter;
@@ -260,7 +322,7 @@
     }
 
     // Write FLOAT data from the first channel.
-    int write(float *inputData, int inputChannelCount, int numFrames) {
+    int32_t write(float *inputData, int32_t inputChannelCount, int32_t numFrames) {
         // stop at end of buffer
         if ((mFrameCounter + numFrames) > mMaxFrames) {
             numFrames = mMaxFrames - mFrameCounter;
@@ -271,7 +333,7 @@
         return numFrames;
     }
 
-    int size() {
+    int32_t size() {
         return mFrameCounter;
     }
 
@@ -320,7 +382,9 @@
         }
 
         assert(info.channels == 1);
+        assert(info.format == SF_FORMAT_FLOAT);
 
+        setSampleRate(info.samplerate);
         allocate(info.frames);
         mFrameCounter = sf_readf_float(sndFile, mData, info.frames);
 
@@ -328,11 +392,49 @@
         return mFrameCounter;
     }
 
+    /**
+     * Square the samples so they are all positive and so the peaks are emphasized.
+     */
+    void square() {
+        for (int i = 0; i < mFrameCounter; i++) {
+            const float sample = mData[i];
+            mData[i] = sample * sample;
+        }
+    }
+
+    /**
+     * Low pass filter the recording using a simple FIR filter.
+     * Note that the lowpass filter cutoff tracks the sample rate.
+     * That is OK because the impulse width is a fixed number of samples.
+     */
+    void lowPassFilter() {
+        for (int i = 0; i < mFrameCounter; i++) {
+            mData[i] = mLowPassFilter.filter(mData[i]);
+        }
+    }
+
+    /**
+     * Remove DC offset using a one-pole one-zero IIR filter.
+     */
+    void dcBlocker() {
+        const float R = 0.996; // narrow notch at zero Hz
+        float x1 = 0.0;
+        float y1 = 0.0;
+        for (int i = 0; i < mFrameCounter; i++) {
+            const float x = mData[i];
+            const float y = x - x1 + (R * y1);
+            mData[i] = y;
+            y1 = y;
+            x1 = x;
+        }
+    }
+
 private:
-    float  *mData = nullptr;
-    int32_t mFrameCounter = 0;
-    int32_t mMaxFrames = 0;
-    int32_t mSampleRate = 48000; // common default
+    float        *mData = nullptr;
+    int32_t       mFrameCounter = 0;
+    int32_t       mMaxFrames = 0;
+    int32_t       mSampleRate = kDefaultSampleRate; // common default
+    LowPassFilter mLowPassFilter;
 };
 
 // ====================================================================================
@@ -341,9 +443,14 @@
     virtual ~LoopbackProcessor() = default;
 
 
+    enum process_result {
+        PROCESS_RESULT_OK,
+        PROCESS_RESULT_GLITCH
+    };
+
     virtual void reset() {}
 
-    virtual void process(float *inputData, int inputChannelCount,
+    virtual process_result process(float *inputData, int inputChannelCount,
                  float *outputData, int outputChannelCount,
                  int numFrames) = 0;
 
@@ -352,8 +459,12 @@
 
     virtual void printStatus() {};
 
-    virtual int getResult() {
-        return -1;
+    int32_t getResult() {
+        return mResult;
+    }
+
+    void setResult(int32_t result) {
+        mResult = result;
     }
 
     virtual bool isDone() {
@@ -382,7 +493,7 @@
     static float measurePeakAmplitude(float *inputData, int inputChannelCount, int numFrames) {
         float peak = 0.0f;
         for (int i = 0; i < numFrames; i++) {
-            float pos = fabs(*inputData);
+            const float pos = fabs(*inputData);
             if (pos > peak) {
                 peak = pos;
             }
@@ -393,7 +504,8 @@
 
 
 private:
-    int32_t mSampleRate = LOOPBACK_SAMPLE_RATE;
+    int32_t mSampleRate = kDefaultSampleRate;
+    int32_t mResult = 0;
 };
 
 class PeakDetector {
@@ -412,24 +524,6 @@
     float  mPrevious = 0.0f;
 };
 
-
-static void printAudioScope(float sample) {
-    const int maxStars = 80; // arbitrary, fits on one line
-    char c = '*';
-    if (sample < -1.0) {
-        sample = -1.0;
-        c = '$';
-    } else if (sample > 1.0) {
-        sample = 1.0;
-        c = '$';
-    }
-    int numSpaces = (int) (((sample + 1.0) * 0.5) * maxStars);
-    for (int i = 0; i < numSpaces; i++) {
-        putchar(' ');
-    }
-    printf("%c\n", c);
-}
-
 // ====================================================================================
 /**
  * Measure latency given a loopback stream data.
@@ -450,17 +544,13 @@
     }
 
     void reset() override {
-        mDownCounter = 200;
+        mDownCounter = getSampleRate() / 2;
         mLoopCounter = 0;
         mMeasuredLoopGain = 0.0f;
         mEchoGain = 1.0f;
         mState = STATE_INITIAL_SILENCE;
     }
 
-    virtual int getResult() {
-        return mState == STATE_DONE ? 0 : -1;
-    }
-
     virtual bool isDone() {
         return mState == STATE_DONE || mState == STATE_FAILED;
     }
@@ -473,27 +563,57 @@
         return mEchoGain;
     }
 
-    void report() override {
+    bool testLowPassFilter() {
+        LowPassFilter filter;
+        return filter.test();
+    }
 
+    void report() override {
         printf("EchoAnalyzer ---------------\n");
-        printf(LOOPBACK_RESULT_TAG "measured.gain          = %f\n", mMeasuredLoopGain);
-        printf(LOOPBACK_RESULT_TAG "echo.gain              = %f\n", mEchoGain);
-        printf(LOOPBACK_RESULT_TAG "test.state             = %d\n", mState);
-        if (mMeasuredLoopGain >= 0.9999) {
+        if (getResult() != 0) {
+            printf(LOOPBACK_RESULT_TAG "result          = %d\n", getResult());
+            return;
+        }
+
+        // printf("LowPassFilter test %s\n", testLowPassFilter() ? "PASSED" : "FAILED");
+
+        printf(LOOPBACK_RESULT_TAG "measured.gain          = %8f\n", mMeasuredLoopGain);
+        printf(LOOPBACK_RESULT_TAG "echo.gain              = %8f\n", mEchoGain);
+        printf(LOOPBACK_RESULT_TAG "test.state             = %8d\n", mState);
+        printf(LOOPBACK_RESULT_TAG "test.state.name        = %8s\n", convertStateToText(mState));
+
+        if (mState == STATE_WAITING_FOR_SILENCE) {
+            printf("WARNING - Stuck waiting for silence. Input may be too noisy!\n");
+            setResult(ERROR_NOISY);
+        } else if (mMeasuredLoopGain >= 0.9999) {
             printf("   ERROR - clipping, turn down volume slightly\n");
+            setResult(ERROR_CLIPPING);
+        } else if (mState != STATE_DONE && mState != STATE_GATHERING_ECHOS) {
+            printf("WARNING - Bad state. Check volume on device.\n");
+            setResult(ERROR_INVALID_STATE);
         } else {
-            const float *needle = s_Impulse;
-            int needleSize = (int) (sizeof(s_Impulse) / sizeof(float));
-            float *haystack = mAudioRecording.getData();
-            int haystackSize = mAudioRecording.size();
-            measureLatencyFromEchos(haystack, haystackSize, needle, needleSize, &mLatencyReport);
-            if (mLatencyReport.confidence < 0.01) {
-                printf("   ERROR - confidence too low = %f\n", mLatencyReport.confidence);
-            } else {
-                double latencyMillis = 1000.0 * mLatencyReport.latencyInFrames / getSampleRate();
-                printf(LOOPBACK_RESULT_TAG "latency.frames        = %8.2f\n", mLatencyReport.latencyInFrames);
-                printf(LOOPBACK_RESULT_TAG "latency.msec          = %8.2f\n", latencyMillis);
-                printf(LOOPBACK_RESULT_TAG "latency.confidence    = %8.6f\n", mLatencyReport.confidence);
+            // Cleanup the signal to improve the auto-correlation.
+            mAudioRecording.dcBlocker();
+            mAudioRecording.square();
+            mAudioRecording.lowPassFilter();
+
+            printf("Please wait several seconds for auto-correlation to complete.\n");
+            measureLatencyFromEchos(mAudioRecording.getData(),
+                                    mAudioRecording.size(),
+                                    getSampleRate(),
+                                    &mLatencyReport);
+
+            double latencyMillis = kMillisPerSecond * (double) mLatencyReport.latencyInFrames
+                                   / getSampleRate();
+            printf(LOOPBACK_RESULT_TAG "latency.frames         = %8.2f\n",
+                   mLatencyReport.latencyInFrames);
+            printf(LOOPBACK_RESULT_TAG "latency.msec           = %8.2f\n",
+                   latencyMillis);
+            printf(LOOPBACK_RESULT_TAG "latency.confidence     = %8.6f\n",
+                   mLatencyReport.confidence);
+            if (mLatencyReport.confidence < kMinimumConfidence) {
+                printf("   ERROR - confidence too low!\n");
+                setResult(ERROR_CONFIDENCE);
             }
         }
     }
@@ -519,7 +639,12 @@
         sendImpulses(outputData, outputChannelCount, kImpulseSizeInFrames);
     }
 
-    void process(float *inputData, int inputChannelCount,
+    // @return number of frames for a typical block of processing
+    int32_t getBlockFrames() {
+        return getSampleRate() / 8;
+    }
+
+    process_result process(float *inputData, int inputChannelCount,
                  float *outputData, int outputChannelCount,
                  int numFrames) override {
         int channelsValid = std::min(inputChannelCount, outputChannelCount);
@@ -527,7 +652,7 @@
         int numWritten;
         int numSamples;
 
-        echo_state_t nextState = mState;
+        echo_state nextState = mState;
 
         switch (mState) {
             case STATE_INITIAL_SILENCE:
@@ -536,10 +661,11 @@
                 for (int i = 0; i < numSamples; i++) {
                     outputData[i] = 0;
                 }
-                if (mDownCounter-- <= 0) {
+                mDownCounter -= numFrames;
+                if (mDownCounter <= 0) {
                     nextState = STATE_MEASURING_GAIN;
                     //printf("%5d: switch to STATE_MEASURING_GAIN\n", mLoopCounter);
-                    mDownCounter = 8;
+                    mDownCounter = getBlockFrames() * 2;
                 }
                 break;
 
@@ -548,14 +674,16 @@
                 peak = measurePeakAmplitude(inputData, inputChannelCount, numFrames);
                 // If we get several in a row then go to next state.
                 if (peak > mPulseThreshold) {
-                    if (mDownCounter-- <= 0) {
+                    mDownCounter -= numFrames;
+                    if (mDownCounter <= 0) {
                         //printf("%5d: switch to STATE_WAITING_FOR_SILENCE, measured peak = %f\n",
                         //       mLoopCounter, peak);
-                        mDownCounter = 8;
+                        mDownCounter = getBlockFrames();
                         mMeasuredLoopGain = peak;  // assumes original pulse amplitude is one
+                        mSilenceThreshold = peak * 0.1; // scale silence to measured pulse
                         // Calculate gain that will give us a nice decaying echo.
                         mEchoGain = mDesiredEchoGain / mMeasuredLoopGain;
-                        if (mEchoGain > MAX_ECHO_GAIN) {
+                        if (mEchoGain > kMaxEchoGain) {
                             printf("ERROR - loop gain too low. Increase the volume.\n");
                             nextState = STATE_FAILED;
                         } else {
@@ -563,7 +691,7 @@
                         }
                     }
                 } else if (numFrames > kImpulseSizeInFrames){ // ignore short callbacks
-                    mDownCounter = 8;
+                    mDownCounter = getBlockFrames();
                 }
                 break;
 
@@ -576,13 +704,14 @@
                 peak = measurePeakAmplitude(inputData, inputChannelCount, numFrames);
                 // If we get several in a row then go to next state.
                 if (peak < mSilenceThreshold) {
-                    if (mDownCounter-- <= 0) {
+                    mDownCounter -= numFrames;
+                    if (mDownCounter <= 0) {
                         nextState = STATE_SENDING_PULSE;
                         //printf("%5d: switch to STATE_SENDING_PULSE\n", mLoopCounter);
-                        mDownCounter = 8;
+                        mDownCounter = getBlockFrames();
                     }
                 } else {
-                    mDownCounter = 8;
+                    mDownCounter = getBlockFrames();
                 }
                 break;
 
@@ -615,17 +744,18 @@
                 }
                 if (numWritten  < numFrames) {
                     nextState = STATE_DONE;
-                    //printf("%5d: switch to STATE_DONE\n", mLoopCounter);
                 }
                 break;
 
             case STATE_DONE:
+            case STATE_FAILED:
             default:
                 break;
         }
 
         mState = nextState;
         mLoopCounter++;
+        return PROCESS_RESULT_OK;
     }
 
     int save(const char *fileName) override {
@@ -633,12 +763,23 @@
     }
 
     int load(const char *fileName) override {
-        return mAudioRecording.load(fileName);
+        int result = mAudioRecording.load(fileName);
+        setSampleRate(mAudioRecording.getSampleRate());
+        mState = STATE_DONE;
+        return result;
     }
 
 private:
 
-    enum echo_state_t {
+    enum error_code {
+        ERROR_OK = 0,
+        ERROR_NOISY = -99,
+        ERROR_CLIPPING,
+        ERROR_CONFIDENCE,
+        ERROR_INVALID_STATE
+    };
+
+    enum echo_state {
         STATE_INITIAL_SILENCE,
         STATE_MEASURING_GAIN,
         STATE_WAITING_FOR_SILENCE,
@@ -648,6 +789,35 @@
         STATE_FAILED
     };
 
+    const char *convertStateToText(echo_state state) {
+        const char *result = "Unknown";
+        switch(state) {
+            case STATE_INITIAL_SILENCE:
+                result = "INIT";
+                break;
+            case STATE_MEASURING_GAIN:
+                result = "GAIN";
+                break;
+            case STATE_WAITING_FOR_SILENCE:
+                result = "SILENCE";
+                break;
+            case STATE_SENDING_PULSE:
+                result = "PULSE";
+                break;
+            case STATE_GATHERING_ECHOS:
+                result = "ECHOS";
+                break;
+            case STATE_DONE:
+                result = "DONE";
+                break;
+            case STATE_FAILED:
+                result = "FAILED";
+                break;
+        }
+        return result;
+    }
+
+
     int32_t         mDownCounter = 500;
     int32_t         mLoopCounter = 0;
     int32_t         mSampleIndex = 0;
@@ -656,7 +826,7 @@
     float           mMeasuredLoopGain = 0.0f;
     float           mDesiredEchoGain = 0.95f;
     float           mEchoGain = 1.0f;
-    echo_state_t    mState = STATE_INITIAL_SILENCE;
+    echo_state      mState = STATE_INITIAL_SILENCE;
 
     AudioRecording  mAudioRecording; // contains only the input after the gain detection burst
     LatencyReport   mLatencyReport;
@@ -674,27 +844,38 @@
 class SineAnalyzer : public LoopbackProcessor {
 public:
 
-    virtual int getResult() {
-        return mState == STATE_LOCKED ? 0 : -1;
-    }
-
     void report() override {
         printf("SineAnalyzer ------------------\n");
-        printf(LOOPBACK_RESULT_TAG "peak.amplitude     = %7.5f\n", mPeakAmplitude);
-        printf(LOOPBACK_RESULT_TAG "sine.magnitude     = %7.5f\n", mMagnitude);
-        printf(LOOPBACK_RESULT_TAG "phase.offset       = %7.5f\n", mPhaseOffset);
-        printf(LOOPBACK_RESULT_TAG "ref.phase          = %7.5f\n", mPhase);
-        printf(LOOPBACK_RESULT_TAG "frames.accumulated = %6d\n", mFramesAccumulated);
-        printf(LOOPBACK_RESULT_TAG "sine.period        = %6d\n", mSinePeriod);
-        printf(LOOPBACK_RESULT_TAG "test.state         = %6d\n", mState);
-        printf(LOOPBACK_RESULT_TAG "frame.count        = %6d\n", mFrameCounter);
+        printf(LOOPBACK_RESULT_TAG "peak.amplitude     = %8f\n", mPeakAmplitude);
+        printf(LOOPBACK_RESULT_TAG "sine.magnitude     = %8f\n", mMagnitude);
+        printf(LOOPBACK_RESULT_TAG "peak.noise         = %8f\n", mPeakNoise);
+        printf(LOOPBACK_RESULT_TAG "rms.noise          = %8f\n", mRootMeanSquareNoise);
+        float amplitudeRatio = mMagnitude / mPeakNoise;
+        float signalToNoise = amplitudeRatio * amplitudeRatio;
+        printf(LOOPBACK_RESULT_TAG "signal.to.noise    = %8.2f\n", signalToNoise);
+        float signalToNoiseDB = 10.0 * log(signalToNoise);
+        printf(LOOPBACK_RESULT_TAG "signal.to.noise.db = %8.2f\n", signalToNoiseDB);
+        if (signalToNoiseDB < MIN_SNRATIO_DB) {
+            printf("ERROR - signal to noise ratio is too low! < %d dB. Adjust volume.\n", MIN_SNRATIO_DB);
+            setResult(ERROR_NOISY);
+        }
+        printf(LOOPBACK_RESULT_TAG "frames.accumulated = %8d\n", mFramesAccumulated);
+        printf(LOOPBACK_RESULT_TAG "sine.period        = %8d\n", mSinePeriod);
+        printf(LOOPBACK_RESULT_TAG "test.state         = %8d\n", mState);
+        printf(LOOPBACK_RESULT_TAG "frame.count        = %8d\n", mFrameCounter);
         // Did we ever get a lock?
         bool gotLock = (mState == STATE_LOCKED) || (mGlitchCount > 0);
         if (!gotLock) {
             printf("ERROR - failed to lock on reference sine tone\n");
+            setResult(ERROR_NO_LOCK);
         } else {
             // Only print if meaningful.
-            printf(LOOPBACK_RESULT_TAG "glitch.count       = %6d\n", mGlitchCount);
+            printf(LOOPBACK_RESULT_TAG "glitch.count       = %8d\n", mGlitchCount);
+            printf(LOOPBACK_RESULT_TAG "max.glitch         = %8f\n", mMaxGlitchDelta);
+            if (mGlitchCount > 0) {
+                printf("ERROR - number of glitches > 0\n");
+                setResult(ERROR_GLITCHES);
+            }
         }
     }
 
@@ -721,9 +902,10 @@
      * @param inputData contains microphone data with sine signal feedback
      * @param outputData contains the reference sine wave
      */
-    void process(float *inputData, int inputChannelCount,
+    process_result process(float *inputData, int inputChannelCount,
                  float *outputData, int outputChannelCount,
                  int numFrames) override {
+        process_result result = PROCESS_RESULT_OK;
         mProcessCount++;
 
         float peak = measurePeakAmplitude(inputData, inputChannelCount, numFrames);
@@ -732,15 +914,48 @@
         }
 
         for (int i = 0; i < numFrames; i++) {
+            bool sineEnabled = true;
             float sample = inputData[i * inputChannelCount];
 
             float sinOut = sinf(mPhase);
 
             switch (mState) {
                 case STATE_IDLE:
-                case STATE_IMMUNE:
-                case STATE_WAITING_FOR_SIGNAL:
+                    sineEnabled = false;
+                    mDownCounter--;
+                    if (mDownCounter <= 0) {
+                        mState = STATE_MEASURE_NOISE;
+                        mDownCounter = NOISE_FRAME_COUNT;
+                    }
                     break;
+                case STATE_MEASURE_NOISE:
+                    sineEnabled = false;
+                    mPeakNoise = std::max(abs(sample), mPeakNoise);
+                    mNoiseSumSquared += sample * sample;
+                    mDownCounter--;
+                    if (mDownCounter <= 0) {
+                        mState = STATE_WAITING_FOR_SIGNAL;
+                        mRootMeanSquareNoise = sqrt(mNoiseSumSquared / NOISE_FRAME_COUNT);
+                        mTolerance = std::max(MIN_TOLERANCE, mPeakNoise * 2.0f);
+                        mPhase = 0.0; // prevent spike at start
+                    }
+                    break;
+
+                case STATE_IMMUNE:
+                    mDownCounter--;
+                    if (mDownCounter <= 0) {
+                        mState = STATE_WAITING_FOR_SIGNAL;
+                    }
+                    break;
+
+                case STATE_WAITING_FOR_SIGNAL:
+                    if (peak > mThreshold) {
+                        mState = STATE_WAITING_FOR_LOCK;
+                        //printf("%5d: switch to STATE_WAITING_FOR_LOCK\n", mFrameCounter);
+                        resetAccumulator();
+                    }
+                    break;
+
                 case STATE_WAITING_FOR_LOCK:
                     mSinAccumulator += sample * sinOut;
                     mCosAccumulator += sample * cosf(mPhase);
@@ -766,13 +981,15 @@
                     // printf("    predicted = %f, actual = %f\n", predicted, sample);
 
                     float diff = predicted - sample;
-                    if (fabs(diff) > mTolerance) {
+                    float absDiff = fabs(diff);
+                    mMaxGlitchDelta = std::max(mMaxGlitchDelta, absDiff);
+                    if (absDiff > mTolerance) {
                         mGlitchCount++;
+                        result = PROCESS_RESULT_GLITCH;
                         //printf("%5d: Got a glitch # %d, predicted = %f, actual = %f\n",
                         //       mFrameCounter, mGlitchCount, predicted, sample);
                         mState = STATE_IMMUNE;
-                        //printf("%5d: switch to STATE_IMMUNE\n", mFrameCounter);
-                        mDownCounter = mSinePeriod;  // Set duration of IMMUNE state.
+                        mDownCounter = mSinePeriod * PERIODS_IMMUNE;
                     }
 
                     // Track incoming signal and slowly adjust magnitude to account
@@ -792,44 +1009,24 @@
                 } break;
             }
 
+            float output = 0.0f;
             // Output sine wave so we can measure it.
-            outputData[i * outputChannelCount] = (sinOut * mOutputAmplitude)
-                    + (mWhiteNoise.nextRandomDouble() * mNoiseAmplitude);
-            // printf("%5d: sin(%f) = %f, %f\n", i, mPhase, sinOut,  mPhaseIncrement);
-
-            // advance and wrap phase
-            mPhase += mPhaseIncrement;
-            if (mPhase > M_PI) {
-                mPhase -= (2.0 * M_PI);
+            if (sineEnabled) {
+                output = (sinOut * mOutputAmplitude)
+                         + (mWhiteNoise.nextRandomDouble() * mNoiseAmplitude);
+                // printf("%5d: sin(%f) = %f, %f\n", i, mPhase, sinOut,  mPhaseIncrement);
+                // advance and wrap phase
+                mPhase += mPhaseIncrement;
+                if (mPhase > M_PI) {
+                    mPhase -= (2.0 * M_PI);
+                }
             }
+            outputData[i * outputChannelCount] = output;
+
 
             mFrameCounter++;
         }
-
-        // Do these once per buffer.
-        switch (mState) {
-            case STATE_IDLE:
-                mState = STATE_IMMUNE; // so we can tell when
-                break;
-            case STATE_IMMUNE:
-                mDownCounter -= numFrames;
-                if (mDownCounter <= 0) {
-                    mState = STATE_WAITING_FOR_SIGNAL;
-                    //printf("%5d: switch to STATE_WAITING_FOR_SIGNAL\n", mFrameCounter);
-                }
-                break;
-            case STATE_WAITING_FOR_SIGNAL:
-                if (peak > mThreshold) {
-                    mState = STATE_WAITING_FOR_LOCK;
-                    //printf("%5d: switch to STATE_WAITING_FOR_LOCK\n", mFrameCounter);
-                    resetAccumulator();
-                }
-                break;
-            case STATE_WAITING_FOR_LOCK:
-            case STATE_LOCKED:
-                break;
-        }
-
+        return result;
     }
 
     void resetAccumulator() {
@@ -840,18 +1037,31 @@
 
     void reset() override {
         mGlitchCount = 0;
-        mState = STATE_IMMUNE;
-        mDownCounter = IMMUNE_FRAME_COUNT;
+        mState = STATE_IDLE;
+        mDownCounter = IDLE_FRAME_COUNT;
         mPhaseIncrement = 2.0 * M_PI / mSinePeriod;
         printf("phaseInc = %f for period %d\n", mPhaseIncrement, mSinePeriod);
         resetAccumulator();
         mProcessCount = 0;
+        mPeakNoise = 0.0f;
+        mNoiseSumSquared = 0.0;
+        mRootMeanSquareNoise = 0.0;
+        mPhase = 0.0f;
+        mMaxGlitchDelta = 0.0;
     }
 
 private:
 
+    enum error_code {
+        OK,
+        ERROR_NO_LOCK = -80,
+        ERROR_GLITCHES,
+        ERROR_NOISY
+    };
+
     enum sine_state_t {
         STATE_IDLE,
+        STATE_MEASURE_NOISE,
         STATE_IMMUNE,
         STATE_WAITING_FOR_SIGNAL,
         STATE_WAITING_FOR_LOCK,
@@ -859,10 +1069,16 @@
     };
 
     enum constants {
-        IMMUNE_FRAME_COUNT = 48 * 500,
-        PERIODS_NEEDED_FOR_LOCK = 8
+        // Arbitrary durations, assuming 48000 Hz
+        IDLE_FRAME_COUNT = 48 * 100,
+        NOISE_FRAME_COUNT = 48 * 600,
+        PERIODS_NEEDED_FOR_LOCK = 8,
+        PERIODS_IMMUNE = 2,
+        MIN_SNRATIO_DB = 65
     };
 
+    static constexpr float MIN_TOLERANCE = 0.01;
+
     int     mSinePeriod = 79;
     double  mPhaseIncrement = 0.0;
     double  mPhase = 0.0;
@@ -870,25 +1086,29 @@
     double  mPreviousPhaseOffset = 0.0;
     double  mMagnitude = 0.0;
     double  mThreshold = 0.005;
-    double  mTolerance = 0.01;
+    double  mTolerance = MIN_TOLERANCE;
     int32_t mFramesAccumulated = 0;
     int32_t mProcessCount = 0;
     double  mSinAccumulator = 0.0;
     double  mCosAccumulator = 0.0;
+    float   mMaxGlitchDelta = 0.0f;
     int32_t mGlitchCount = 0;
     double  mPeakAmplitude = 0.0;
-    int     mDownCounter = IMMUNE_FRAME_COUNT;
+    int     mDownCounter = IDLE_FRAME_COUNT;
     int32_t mFrameCounter = 0;
     float   mOutputAmplitude = 0.75;
 
+    // measure background noise
+    float   mPeakNoise = 0.0f;
+    double  mNoiseSumSquared = 0.0;
+    double  mRootMeanSquareNoise = 0.0;
+
     PseudoRandom  mWhiteNoise;
     float   mNoiseAmplitude = 0.00; // Used to experiment with warbling caused by DRC.
 
     sine_state_t  mState = STATE_IDLE;
 };
 
-
-#undef LOOPBACK_SAMPLE_RATE
 #undef LOOPBACK_RESULT_TAG
 
 #endif /* AAUDIO_EXAMPLES_LOOPBACK_ANALYSER_H */
diff --git a/media/libaaudio/examples/loopback/src/loopback.cpp b/media/libaaudio/examples/loopback/src/loopback.cpp
index 91ebf73..49d921f 100644
--- a/media/libaaudio/examples/loopback/src/loopback.cpp
+++ b/media/libaaudio/examples/loopback/src/loopback.cpp
@@ -34,21 +34,32 @@
 #include "AAudioSimpleRecorder.h"
 #include "AAudioExampleUtils.h"
 #include "LoopbackAnalyzer.h"
+#include "../../utils/AAudioExampleUtils.h"
+
+// V0.4.00 = rectify and low-pass filter the echos, auto-correlate entire echo
+// V0.4.01 = add -h hang option
+//           fix -n option to set output buffer for -tm
+//           plot first glitch
+// V0.4.02 = allow -n0 for minimal buffer size
+#define APP_VERSION             "0.4.02"
 
 // Tag for machine readable results as property = value pairs
 #define RESULT_TAG              "RESULT: "
-#define NUM_SECONDS             5
-#define PERIOD_MILLIS           1000
-#define NUM_INPUT_CHANNELS      1
 #define FILENAME_ALL            "/data/loopback_all.wav"
 #define FILENAME_ECHOS          "/data/loopback_echos.wav"
-#define APP_VERSION             "0.2.04"
+#define FILENAME_PROCESSED      "/data/loopback_processed.wav"
 
+constexpr int kLogPeriodMillis       = 1000;
+constexpr int kNumInputChannels      = 1;
 constexpr int kNumCallbacksToDrain   = 20;
+constexpr int kNumCallbacksToNotRead = 0; // let input fill back up
 constexpr int kNumCallbacksToDiscard = 20;
+constexpr int kDefaultHangTimeMillis = 50;
+constexpr int kMaxGlitchEventsToSave = 32;
 
 struct LoopbackData {
     AAudioStream      *inputStream = nullptr;
+    AAudioStream      *outputStream = nullptr;
     int32_t            inputFramesMaximum = 0;
     int16_t           *inputShortData = nullptr;
     float             *inputFloatData = nullptr;
@@ -56,6 +67,7 @@
     int32_t            actualInputChannelCount = 0;
     int32_t            actualOutputChannelCount = 0;
     int32_t            numCallbacksToDrain = kNumCallbacksToDrain;
+    int32_t            numCallbacksToNotRead = kNumCallbacksToNotRead;
     int32_t            numCallbacksToDiscard = kNumCallbacksToDiscard;
     int32_t            minNumFrames = INT32_MAX;
     int32_t            maxNumFrames = 0;
@@ -63,6 +75,9 @@
     int32_t            insufficientReadFrames = 0;
     int32_t            framesReadTotal = 0;
     int32_t            framesWrittenTotal = 0;
+    int32_t            hangPeriodMillis = 5 * 1000; // time between hangs
+    int32_t            hangCountdownFrames = 5 * 48000; // frames til next hang
+    int32_t            hangTimeMillis = 0; // 0 for no hang
     bool               isDone = false;
 
     aaudio_result_t    inputError = AAUDIO_OK;
@@ -72,6 +87,29 @@
     EchoAnalyzer       echoAnalyzer;
     AudioRecording     audioRecording;
     LoopbackProcessor *loopbackProcessor;
+
+    int32_t            glitchFrames[kMaxGlitchEventsToSave];
+    int32_t            numGlitchEvents = 0;
+
+    void hangIfRequested(int32_t numFrames) {
+        if (hangTimeMillis > 0) {
+            hangCountdownFrames -= numFrames;
+            if (hangCountdownFrames <= 0) {
+                const int64_t startNanos = getNanoseconds();
+                usleep(hangTimeMillis * 1000);
+                const int64_t endNanos = getNanoseconds();
+                const int32_t elapsedMicros = (int32_t)
+                        ((endNanos - startNanos) / 1000);
+                printf("callback hanging for %d millis, actual = %d micros\n",
+                       hangTimeMillis, elapsedMicros);
+                hangCountdownFrames = (int64_t) hangPeriodMillis
+                        * AAudioStream_getSampleRate(outputStream)
+                        / 1000;
+            }
+        }
+
+
+    }
 };
 
 static void convertPcm16ToFloat(const int16_t *source,
@@ -103,9 +141,14 @@
         assert(false);
     }
     if (framesRead < 0) {
-        myData->inputError = framesRead;
-        printf("ERROR in read = %d = %s\n", framesRead,
-               AAudio_convertResultToText(framesRead));
+        // Expect INVALID_STATE if STATE_STARTING
+        if (myData->framesReadTotal > 0) {
+            myData->inputError = framesRead;
+            printf("ERROR in read = %d = %s\n", framesRead,
+                   AAudio_convertResultToText(framesRead));
+        } else {
+            framesRead = 0;
+        }
     } else {
         myData->framesReadTotal += framesRead;
     }
@@ -147,8 +190,10 @@
         int32_t totalFramesRead = 0;
         do {
             actualFramesRead = readFormattedData(myData, numFrames);
-            if (actualFramesRead) {
+            if (actualFramesRead > 0) {
                 totalFramesRead += actualFramesRead;
+            } else if (actualFramesRead < 0) {
+                result = AAUDIO_CALLBACK_RESULT_STOP;
             }
             // Ignore errors because input stream may not be started yet.
         } while (actualFramesRead > 0);
@@ -157,6 +202,9 @@
             myData->numCallbacksToDrain--;
         }
 
+    } else if (myData->numCallbacksToNotRead > 0) {
+        // Let the input fill up a bit so we are not so close to the write pointer.
+        myData->numCallbacksToNotRead--;
     } else if (myData->numCallbacksToDiscard > 0) {
         // Ignore. Allow the input to fill back up to equilibrium with the output.
         actualFramesRead = readFormattedData(myData, numFrames);
@@ -166,6 +214,7 @@
         myData->numCallbacksToDiscard--;
 
     } else {
+        myData->hangIfRequested(numFrames);
 
         int32_t numInputBytes = numFrames * myData->actualInputChannelCount * sizeof(float);
         memset(myData->inputFloatData, 0 /* value */, numInputBytes);
@@ -174,14 +223,15 @@
         int64_t inputFramesWritten = AAudioStream_getFramesWritten(myData->inputStream);
         int64_t inputFramesRead = AAudioStream_getFramesRead(myData->inputStream);
         int64_t framesAvailable = inputFramesWritten - inputFramesRead;
-        actualFramesRead = readFormattedData(myData, numFrames);
+
+        actualFramesRead = readFormattedData(myData, numFrames); // READ
         if (actualFramesRead < 0) {
             result = AAUDIO_CALLBACK_RESULT_STOP;
         } else {
 
             if (actualFramesRead < numFrames) {
                 if(actualFramesRead < (int32_t) framesAvailable) {
-                    printf("insufficient but numFrames = %d"
+                    printf("insufficient for no reason, numFrames = %d"
                                    ", actualFramesRead = %d"
                                    ", inputFramesWritten = %d"
                                    ", inputFramesRead = %d"
@@ -194,6 +244,7 @@
                 }
                 myData->insufficientReadCount++;
                 myData->insufficientReadFrames += numFrames - actualFramesRead; // deficit
+                // printf("Error insufficientReadCount = %d\n",(int)myData->insufficientReadCount);
             }
 
             int32_t numSamples = actualFramesRead * myData->actualInputChannelCount;
@@ -201,16 +252,25 @@
             if (myData->actualInputFormat == AAUDIO_FORMAT_PCM_I16) {
                 convertPcm16ToFloat(myData->inputShortData, myData->inputFloatData, numSamples);
             }
-            // Save for later.
-            myData->audioRecording.write(myData->inputFloatData,
-                                         myData->actualInputChannelCount,
-                                         numFrames);
+
             // Analyze the data.
-            myData->loopbackProcessor->process(myData->inputFloatData,
+            LoopbackProcessor::process_result procResult = myData->loopbackProcessor->process(myData->inputFloatData,
                                                myData->actualInputChannelCount,
                                                outputData,
                                                myData->actualOutputChannelCount,
                                                numFrames);
+
+            if (procResult == LoopbackProcessor::PROCESS_RESULT_GLITCH) {
+                if (myData->numGlitchEvents < kMaxGlitchEventsToSave) {
+                    myData->glitchFrames[myData->numGlitchEvents++] = myData->audioRecording.size();
+                }
+            }
+
+            // Save for later.
+            myData->audioRecording.write(myData->inputFloatData,
+                                         myData->actualInputChannelCount,
+                                         actualFramesRead);
+
             myData->isDone = myData->loopbackProcessor->isDone();
             if (myData->isDone) {
                 result = AAUDIO_CALLBACK_RESULT_STOP;
@@ -236,8 +296,10 @@
     AAudioArgsParser::usage();
     printf("      -B{frames}        input capacity in frames\n");
     printf("      -C{channels}      number of input channels\n");
+    printf("      -D{deviceId}      input device ID\n");
     printf("      -F{0,1,2}         input format, 1=I16, 2=FLOAT\n");
     printf("      -g{gain}          recirculating loopback gain\n");
+    printf("      -h{hangMillis}    occasionally hang in the callback\n");
     printf("      -P{inPerf}        set input AAUDIO_PERFORMANCE_MODE*\n");
     printf("          n for _NONE\n");
     printf("          l for _LATENCY\n");
@@ -296,9 +358,7 @@
     return testMode;
 }
 
-void printAudioGraph(AudioRecording &recording, int numSamples) {
-    int32_t start = recording.size() / 2;
-    int32_t end = start + numSamples;
+void printAudioGraphRegion(AudioRecording &recording, int32_t start, int32_t end) {
     if (end >= recording.size()) {
         end = recording.size() - 1;
     }
@@ -335,13 +395,14 @@
     AAudioStream         *outputStream               = nullptr;
 
     aaudio_result_t       result = AAUDIO_OK;
+    int32_t               requestedInputDeviceId     = AAUDIO_UNSPECIFIED;
     aaudio_sharing_mode_t requestedInputSharingMode  = AAUDIO_SHARING_MODE_SHARED;
-    int                   requestedInputChannelCount = NUM_INPUT_CHANNELS;
+    int                   requestedInputChannelCount = kNumInputChannels;
     aaudio_format_t       requestedInputFormat       = AAUDIO_FORMAT_UNSPECIFIED;
-    int32_t               requestedInputCapacity     = -1;
+    int32_t               requestedInputCapacity     = AAUDIO_UNSPECIFIED;
     aaudio_performance_mode_t inputPerformanceLevel  = AAUDIO_PERFORMANCE_MODE_LOW_LATENCY;
 
-    int32_t               outputFramesPerBurst = 0;
+    int32_t               outputFramesPerBurst       = 0;
 
     aaudio_format_t       actualOutputFormat         = AAUDIO_FORMAT_INVALID;
     int32_t               actualSampleRate           = 0;
@@ -349,6 +410,7 @@
 
     int                   testMode                   = TEST_ECHO_LATENCY;
     double                gain                       = 1.0;
+    int                   hangTimeMillis             = 0;
 
     // Make printf print immediately so that debug info is not stuck
     // in a buffer if we hang or crash.
@@ -356,6 +418,9 @@
 
     printf("%s - Audio loopback using AAudio V" APP_VERSION "\n", argv[0]);
 
+    // Use LOW_LATENCY as the default to match input default.
+    argParser.setPerformanceMode(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
+
     for (int i = 1; i < argc; i++) {
         const char *arg = argv[i];
         if (argParser.parseArg(arg)) {
@@ -369,12 +434,24 @@
                     case 'C':
                         requestedInputChannelCount = atoi(&arg[2]);
                         break;
+                    case 'D':
+                        requestedInputDeviceId = atoi(&arg[2]);
+                        break;
                     case 'F':
                         requestedInputFormat = atoi(&arg[2]);
                         break;
                     case 'g':
                         gain = atof(&arg[2]);
                         break;
+                    case 'h':
+                        // Was there a number after the "-h"?
+                        if (arg[2]) {
+                            hangTimeMillis = atoi(&arg[2]);
+                        } else {
+                            // If no number then use the default.
+                            hangTimeMillis = kDefaultHangTimeMillis;
+                        }
+                        break;
                     case 'P':
                         inputPerformanceLevel = parsePerformanceMode(arg[2]);
                         break;
@@ -404,10 +481,12 @@
     }
 
     int32_t requestedDuration = argParser.getDurationSeconds();
-    int32_t requestedDurationMillis = requestedDuration * MILLIS_PER_SECOND;
+    int32_t requestedDurationMillis = requestedDuration * kMillisPerSecond;
     int32_t timeMillis = 0;
     int32_t recordingDuration = std::min(60 * 5, requestedDuration);
 
+    int32_t requestedOutputBursts = argParser.getNumberOfBursts();
+
     switch(testMode) {
         case TEST_SINE_MAGNITUDE:
             loopbackData.loopbackProcessor = &loopbackData.sineAnalyzer;
@@ -421,9 +500,11 @@
 
             loopbackData.loopbackProcessor = &loopbackData.echoAnalyzer;
             int read = loopbackData.loopbackProcessor->load(FILENAME_ECHOS);
-            printf("main() read %d mono samples from %s on Android device\n", read, FILENAME_ECHOS);
+            printf("main() read %d mono samples from %s on Android device, rate = %d\n",
+                   read, FILENAME_ECHOS,
+                   loopbackData.loopbackProcessor->getSampleRate());
             loopbackData.loopbackProcessor->report();
-            return 0;
+            goto report_result;
         }
             break;
         default:
@@ -437,7 +518,7 @@
         fprintf(stderr, "ERROR -  player.open() returned %d\n", result);
         exit(1);
     }
-    outputStream = player.getStream();
+    outputStream = loopbackData.outputStream = player.getStream();
 
     actualOutputFormat = AAudioStream_getFormat(outputStream);
     if (actualOutputFormat != AAUDIO_FORMAT_PCM_FLOAT) {
@@ -454,20 +535,16 @@
 
     printf("INPUT  stream ----------------------------------------\n");
     // Use different parameters for the input.
-    argParser.setNumberOfBursts(AAUDIO_UNSPECIFIED);
+    argParser.setDeviceId(requestedInputDeviceId);
+    argParser.setNumberOfBursts(AAudioParameters::kDefaultNumberOfBursts);
     argParser.setFormat(requestedInputFormat);
     argParser.setPerformanceMode(inputPerformanceLevel);
     argParser.setChannelCount(requestedInputChannelCount);
     argParser.setSharingMode(requestedInputSharingMode);
-
-    // Make sure the input buffer has plenty of capacity.
-    // Extra capacity on input should not increase latency if we keep it drained.
-    int32_t inputBufferCapacity = requestedInputCapacity;
-    if (inputBufferCapacity < 0) {
-        int32_t outputBufferCapacity = AAudioStream_getBufferCapacityInFrames(outputStream);
-        inputBufferCapacity = 2 * outputBufferCapacity;
+    if (requestedInputCapacity != AAUDIO_UNSPECIFIED) {
+        printf("Warning! If you set input capacity then maybe no FAST track on Legacy path!\n");
     }
-    argParser.setBufferCapacity(inputBufferCapacity);
+    argParser.setBufferCapacity(requestedInputCapacity);
 
     result = recorder.open(argParser);
     if (result != AAUDIO_OK) {
@@ -478,24 +555,29 @@
 
     {
         int32_t actualCapacity = AAudioStream_getBufferCapacityInFrames(inputStream);
-        result = AAudioStream_setBufferSizeInFrames(inputStream, actualCapacity);
-        if (result < 0) {
-            fprintf(stderr, "ERROR -  AAudioStream_setBufferSizeInFrames() returned %d\n", result);
-            goto finish;
-        } else {}
-    }
+        (void) AAudioStream_setBufferSizeInFrames(inputStream, actualCapacity);
 
-    argParser.compareWithStream(inputStream);
+        if (testMode == TEST_SINE_MAGNITUDE
+                && requestedOutputBursts == AAUDIO_UNSPECIFIED) {
+            result = AAudioStream_setBufferSizeInFrames(outputStream, actualCapacity);
+            if (result < 0) {
+                fprintf(stderr, "ERROR -  AAudioStream_setBufferSizeInFrames(output) returned %d\n",
+                        result);
+                goto finish;
+            } else {
+                printf("Output buffer size set to match input capacity = %d frames!\n", result);
+            }
+        }
 
-    // If the input stream is too small then we cannot satisfy the output callback.
-    {
-        int32_t actualCapacity = AAudioStream_getBufferCapacityInFrames(inputStream);
+        // If the input stream is too small then we cannot satisfy the output callback.
         if (actualCapacity < 2 * outputFramesPerBurst) {
             fprintf(stderr, "ERROR - input capacity < 2 * outputFramesPerBurst\n");
             goto finish;
         }
     }
 
+    argParser.compareWithStream(inputStream);
+
     // ------- Setup loopbackData -----------------------------
     loopbackData.actualInputFormat = AAudioStream_getFormat(inputStream);
 
@@ -514,18 +596,16 @@
 
     loopbackData.loopbackProcessor->reset();
 
+    loopbackData.hangTimeMillis = hangTimeMillis;
+
     // Start OUTPUT first so INPUT does not overflow.
     result = player.start();
     if (result != AAUDIO_OK) {
-        printf("ERROR - AAudioStream_requestStart(output) returned %d = %s\n",
-               result, AAudio_convertResultToText(result));
         goto finish;
     }
 
     result = recorder.start();
     if (result != AAUDIO_OK) {
-        printf("ERROR - AAudioStream_requestStart(input) returned %d = %s\n",
-               result, AAudio_convertResultToText(result));
         goto finish;
     }
 
@@ -568,7 +648,7 @@
                    AAudioStream_getXRunCount(outputStream)
             );
         }
-        int32_t periodMillis = (timeMillis < 2000) ? PERIOD_MILLIS / 4 : PERIOD_MILLIS;
+        int32_t periodMillis = (timeMillis < 2000) ? kLogPeriodMillis / 4 : kLogPeriodMillis;
         usleep(periodMillis * 1000);
         timeMillis += periodMillis;
     }
@@ -590,45 +670,6 @@
     printf("input error = %d = %s\n",
            loopbackData.inputError, AAudio_convertResultToText(loopbackData.inputError));
 
-    if (loopbackData.inputError == AAUDIO_OK) {
-        if (testMode == TEST_SINE_MAGNITUDE) {
-            printAudioGraph(loopbackData.audioRecording, 200);
-        }
-        // Print again so we don't have to scroll past waveform.
-        printf("OUTPUT Stream ----------------------------------------\n");
-        argParser.compareWithStream(outputStream);
-        printf("INPUT  Stream ----------------------------------------\n");
-        argParser.compareWithStream(inputStream);
-
-        loopbackData.loopbackProcessor->report();
-    }
-
-    {
-        int32_t framesRead = AAudioStream_getFramesRead(inputStream);
-        int32_t framesWritten = AAudioStream_getFramesWritten(inputStream);
-        printf("Callback Results ---------------------------------------- INPUT\n");
-        printf("  input overruns   = %d\n", AAudioStream_getXRunCount(inputStream));
-        printf("  framesWritten    = %8d\n", framesWritten);
-        printf("  framesRead       = %8d\n", framesRead);
-        printf("  myFramesRead     = %8d\n", (int) loopbackData.framesReadTotal);
-        printf("  written - read   = %8d\n", (int) (framesWritten - framesRead));
-        printf("  insufficient #   = %8d\n", (int) loopbackData.insufficientReadCount);
-        if (loopbackData.insufficientReadCount > 0) {
-            printf("  insufficient frames = %8d\n", (int) loopbackData.insufficientReadFrames);
-        }
-    }
-    {
-        int32_t framesRead = AAudioStream_getFramesRead(outputStream);
-        int32_t framesWritten = AAudioStream_getFramesWritten(outputStream);
-        printf("Callback Results ---------------------------------------- OUTPUT\n");
-        printf("  output underruns = %d\n", AAudioStream_getXRunCount(outputStream));
-        printf("  myFramesWritten  = %8d\n", (int) loopbackData.framesWrittenTotal);
-        printf("  framesWritten    = %8d\n", framesWritten);
-        printf("  framesRead       = %8d\n", framesRead);
-        printf("  min numFrames    = %8d\n", (int) loopbackData.minNumFrames);
-        printf("  max numFrames    = %8d\n", (int) loopbackData.maxNumFrames);
-    }
-
     written = loopbackData.loopbackProcessor->save(FILENAME_ECHOS);
     if (written > 0) {
         printf("main() wrote %8d mono samples to \"%s\" on Android device\n",
@@ -641,10 +682,56 @@
                written, FILENAME_ALL);
     }
 
-    if (loopbackData.loopbackProcessor->getResult() < 0) {
-        printf("ERROR: LOOPBACK PROCESSING FAILED. Maybe because the volume was too low.\n");
-        result = loopbackData.loopbackProcessor->getResult();
+    if (loopbackData.inputError == AAUDIO_OK) {
+        if (testMode == TEST_SINE_MAGNITUDE) {
+            if (loopbackData.numGlitchEvents > 0) {
+                // Graph around the first glitch if there is one.
+                const int32_t start = loopbackData.glitchFrames[0] - 8;
+                const int32_t end = start + outputFramesPerBurst + 8 + 8;
+                printAudioGraphRegion(loopbackData.audioRecording, start, end);
+            } else {
+                // Or graph the middle of the signal.
+                const int32_t start = loopbackData.audioRecording.size() / 2;
+                const int32_t end = start + 200;
+                printAudioGraphRegion(loopbackData.audioRecording, start, end);
+            }
+        }
+
+        loopbackData.loopbackProcessor->report();
     }
+
+    {
+        int32_t framesRead = AAudioStream_getFramesRead(inputStream);
+        int32_t framesWritten = AAudioStream_getFramesWritten(inputStream);
+        const int64_t framesAvailable = framesWritten - framesRead;
+        printf("Callback Results ---------------------------------------- INPUT\n");
+        printf("  input overruns   = %8d\n", AAudioStream_getXRunCount(inputStream));
+        printf("  framesWritten    = %8d\n", framesWritten);
+        printf("  framesRead       = %8d\n", framesRead);
+        printf("  myFramesRead     = %8d\n", (int) loopbackData.framesReadTotal);
+        printf("  written - read   = %8d\n", (int) framesAvailable);
+        printf("  insufficient #   = %8d\n", (int) loopbackData.insufficientReadCount);
+        if (loopbackData.insufficientReadCount > 0) {
+            printf("  insuffic. frames = %8d\n", (int) loopbackData.insufficientReadFrames);
+        }
+        int32_t actualInputCapacity = AAudioStream_getBufferCapacityInFrames(inputStream);
+        if (framesAvailable > 2 * actualInputCapacity) {
+            printf("  WARNING: written - read > 2*capacity !\n");
+        }
+    }
+
+    {
+        int32_t framesRead = AAudioStream_getFramesRead(outputStream);
+        int32_t framesWritten = AAudioStream_getFramesWritten(outputStream);
+        printf("Callback Results ---------------------------------------- OUTPUT\n");
+        printf("  output underruns = %8d\n", AAudioStream_getXRunCount(outputStream));
+        printf("  myFramesWritten  = %8d\n", (int) loopbackData.framesWrittenTotal);
+        printf("  framesWritten    = %8d\n", framesWritten);
+        printf("  framesRead       = %8d\n", framesRead);
+        printf("  min numFrames    = %8d\n", (int) loopbackData.minNumFrames);
+        printf("  max numFrames    = %8d\n", (int) loopbackData.maxNumFrames);
+    }
+
     if (loopbackData.insufficientReadCount > 3) {
         printf("ERROR: LOOPBACK PROCESSING FAILED. insufficientReadCount too high\n");
         result = AAUDIO_ERROR_UNAVAILABLE;
@@ -656,14 +743,28 @@
     delete[] loopbackData.inputFloatData;
     delete[] loopbackData.inputShortData;
 
+report_result:
+
+    for (int i = 0; i < loopbackData.numGlitchEvents; i++) {
+        printf("  glitch at frame %d\n", loopbackData.glitchFrames[i]);
+    }
+
+    written = loopbackData.loopbackProcessor->save(FILENAME_PROCESSED);
+    if (written > 0) {
+        printf("main() wrote %8d processed samples to \"%s\" on Android device\n",
+               written, FILENAME_PROCESSED);
+    }
+
+    if (loopbackData.loopbackProcessor->getResult() < 0) {
+        result = loopbackData.loopbackProcessor->getResult();
+    }
     printf(RESULT_TAG "result = %d \n", result); // machine readable
     printf("result is %s\n", AAudio_convertResultToText(result)); // human readable
     if (result != AAUDIO_OK) {
-        printf("FAILURE\n");
+        printf("TEST FAILED\n");
         return EXIT_FAILURE;
     } else {
-        printf("SUCCESS\n");
+        printf("TEST PASSED\n");
         return EXIT_SUCCESS;
     }
 }
-
diff --git a/media/libaaudio/examples/utils/AAudioArgsParser.h b/media/libaaudio/examples/utils/AAudioArgsParser.h
index 88d7401..9115778 100644
--- a/media/libaaudio/examples/utils/AAudioArgsParser.h
+++ b/media/libaaudio/examples/utils/AAudioArgsParser.h
@@ -36,11 +36,14 @@
                                 aaudio_content_type_t contentType) = nullptr;
 static void (*s_setInputPreset)(AAudioStreamBuilder* builder,
                                 aaudio_input_preset_t inputPreset) = nullptr;
+static void (*s_setAllowedCapturePolicy)(AAudioStreamBuilder* builder,
+                                          aaudio_allowed_capture_policy_t usage) = nullptr;
 
 static bool s_loadAttempted = false;
 static aaudio_usage_t (*s_getUsage)(AAudioStream *stream) = nullptr;
 static aaudio_content_type_t (*s_getContentType)(AAudioStream *stream) = nullptr;
 static aaudio_input_preset_t (*s_getInputPreset)(AAudioStream *stream) = nullptr;
+static aaudio_allowed_capture_policy_t (*s_getAllowedCapturePolicy)(AAudioStream *stream) = nullptr;
 
 // Link to test functions in shared library.
 static void loadFutureFunctions() {
@@ -61,6 +64,10 @@
                 dlsym(handle, "AAudioStreamBuilder_setInputPreset");
         if (s_setInputPreset == nullptr) goto error;
 
+        s_setAllowedCapturePolicy = (void (*)(AAudioStreamBuilder *, aaudio_input_preset_t))
+                dlsym(handle, "AAudioStreamBuilder_setAllowedCapturePolicy");
+        if (s_setAllowedCapturePolicy == nullptr) goto error;
+
         s_getUsage = (aaudio_usage_t (*)(AAudioStream *))
                 dlsym(handle, "AAudioStream_getUsage");
         if (s_getUsage == nullptr) goto error;
@@ -72,6 +79,10 @@
         s_getInputPreset = (aaudio_input_preset_t (*)(AAudioStream *))
                 dlsym(handle, "AAudioStream_getInputPreset");
         if (s_getInputPreset == nullptr) goto error;
+
+        s_getAllowedCapturePolicy = (aaudio_input_preset_t (*)(AAudioStream *))
+                dlsym(handle, "AAudioStream_getAllowedCapturePolicy");
+        if (s_getAllowedCapturePolicy == nullptr) goto error;
     }
     return;
 
@@ -169,6 +180,14 @@
         mInputPreset = inputPreset;
     }
 
+    aaudio_allowed_capture_policy_t getAllowedCapturePolicy() const {
+        return mAllowedCapturePolicy;
+    }
+
+    void setAllowedCapturePolicy(aaudio_allowed_capture_policy_t policy) {
+        mAllowedCapturePolicy = policy;
+    }
+
     int32_t getDeviceId() const {
         return mDeviceId;
     }
@@ -185,18 +204,26 @@
         mNumberOfBursts = numBursts;
     }
 
+    int32_t getFramesPerCallback() const {
+        return mFramesPerCallback;
+    }
+    void setFramesPerCallback(int32_t size) {
+        mFramesPerCallback = size;
+    }
+
     /**
      * Apply these parameters to a stream builder.
      * @param builder
      */
     void applyParameters(AAudioStreamBuilder *builder) const {
+        AAudioStreamBuilder_setBufferCapacityInFrames(builder, getBufferCapacity());
         AAudioStreamBuilder_setChannelCount(builder, mChannelCount);
-        AAudioStreamBuilder_setFormat(builder, mFormat);
-        AAudioStreamBuilder_setSampleRate(builder, mSampleRate);
-        AAudioStreamBuilder_setBufferCapacityInFrames(builder, mBufferCapacity);
         AAudioStreamBuilder_setDeviceId(builder, mDeviceId);
-        AAudioStreamBuilder_setSharingMode(builder, mSharingMode);
+        AAudioStreamBuilder_setFormat(builder, mFormat);
+        AAudioStreamBuilder_setFramesPerDataCallback(builder, mFramesPerCallback);
         AAudioStreamBuilder_setPerformanceMode(builder, mPerformanceMode);
+        AAudioStreamBuilder_setSampleRate(builder, mSampleRate);
+        AAudioStreamBuilder_setSharingMode(builder, mSharingMode);
 
         // Call P functions if supported.
         loadFutureFunctions();
@@ -215,8 +242,17 @@
         } else if (mUsage != AAUDIO_UNSPECIFIED){
             printf("WARNING: setInputPreset not supported");
         }
+
+        // Call Q functions if supported.
+        if (s_setAllowedCapturePolicy != nullptr) {
+            s_setAllowedCapturePolicy(builder, mAllowedCapturePolicy);
+        } else if (mAllowedCapturePolicy != AAUDIO_UNSPECIFIED){
+            printf("WARNING: setAllowedCapturePolicy not supported");
+        }
     }
 
+    static constexpr int32_t   kDefaultNumberOfBursts = 2;
+
 private:
     int32_t                    mChannelCount    = AAUDIO_UNSPECIFIED;
     aaudio_format_t            mFormat          = AAUDIO_FORMAT_UNSPECIFIED;
@@ -230,8 +266,10 @@
     aaudio_usage_t             mUsage           = AAUDIO_UNSPECIFIED;
     aaudio_content_type_t      mContentType     = AAUDIO_UNSPECIFIED;
     aaudio_input_preset_t      mInputPreset     = AAUDIO_UNSPECIFIED;
+    aaudio_allowed_capture_policy_t mAllowedCapturePolicy     = AAUDIO_UNSPECIFIED;
 
-    int32_t                    mNumberOfBursts  = AAUDIO_UNSPECIFIED;
+    int32_t                    mNumberOfBursts  = kDefaultNumberOfBursts;
+    int32_t                    mFramesPerCallback = AAUDIO_UNSPECIFIED;
 };
 
 class AAudioArgsParser : public AAudioParameters {
@@ -258,6 +296,9 @@
                 case 'c':
                     setChannelCount(atoi(&arg[2]));
                     break;
+                case 'C':
+                    setAllowedCapturePolicy(parseAllowedCapturePolicy(arg[2]));
+                    break;
                 case 'd':
                     setDeviceId(atoi(&arg[2]));
                     break;
@@ -272,7 +313,9 @@
                     if (strlen(arg) > 2) {
                         policy = atoi(&arg[2]);
                     }
-                    AAudio_setMMapPolicy(policy);
+                    if (AAudio_setMMapPolicy(policy) != AAUDIO_OK) {
+                        printf("ERROR: invalid MMAP policy mode %i\n", policy);
+                    }
                 } break;
                 case 'n':
                     setNumberOfBursts(atoi(&arg[2]));
@@ -295,6 +338,9 @@
                 case 'y':
                     setContentType(atoi(&arg[2]));
                     break;
+                case 'z':
+                    setFramesPerCallback(atoi(&arg[2]));
+                    break;
                 default:
                     unrecognized = true;
                     break;
@@ -327,6 +373,10 @@
         printf("      Default values are UNSPECIFIED unless otherwise stated.\n");
         printf("      -b{bufferCapacity} frames\n");
         printf("      -c{channels} for example 2 for stereo\n");
+        printf("      -C{a|s|n} set playback capture policy\n");
+        printf("          a = _ALL (default)\n");
+        printf("          s = _SYSTEM\n");
+        printf("          n = _NONE\n");
         printf("      -d{deviceId} default is %d\n", AAUDIO_UNSPECIFIED);
         printf("      -f{0|1|2} set format\n");
         printf("          0 = UNSPECIFIED\n");
@@ -338,7 +388,7 @@
         printf("          1 = _NEVER, never use MMAP\n");
         printf("          2 = _AUTO, use MMAP if available, default for -m with no number\n");
         printf("          3 = _ALWAYS, use MMAP or fail\n");
-        printf("      -n{numberOfBursts} for setBufferSize\n");
+        printf("      -n{numberOfBursts} for setBufferSize, default %d\n", kDefaultNumberOfBursts);
         printf("      -p{performanceMode} set output AAUDIO_PERFORMANCE_MODE*, default NONE\n");
         printf("          n for _NONE\n");
         printf("          l for _LATENCY\n");
@@ -348,6 +398,26 @@
         printf("      -u{usage} eg. 14 for AAUDIO_USAGE_GAME\n");
         printf("      -x to use EXCLUSIVE mode\n");
         printf("      -y{contentType} eg. 1 for AAUDIO_CONTENT_TYPE_SPEECH\n");
+        printf("      -z{callbackSize} or block size, in frames, default = 0\n");
+    }
+
+    static aaudio_performance_mode_t parseAllowedCapturePolicy(char c) {
+        aaudio_allowed_capture_policy_t policy = AAUDIO_ALLOW_CAPTURE_BY_ALL;
+        switch (c) {
+            case 'a':
+                policy = AAUDIO_ALLOW_CAPTURE_BY_ALL;
+                break;
+            case 's':
+                policy = AAUDIO_ALLOW_CAPTURE_BY_SYSTEM;
+                break;
+            case 'n':
+                policy = AAUDIO_ALLOW_CAPTURE_BY_NONE;
+                break;
+            default:
+                printf("ERROR: invalid playback capture policy %c\n", c);
+                break;
+        }
+        return policy;
     }
 
     static aaudio_performance_mode_t parsePerformanceMode(char c) {
@@ -363,7 +433,7 @@
                 mode = AAUDIO_PERFORMANCE_MODE_POWER_SAVING;
                 break;
             default:
-                printf("ERROR invalid performance mode %c\n", c);
+                printf("ERROR: invalid performance mode %c\n", c);
                 break;
         }
         return mode;
@@ -392,17 +462,31 @@
                getFormat(), AAudioStream_getFormat(stream));
 
         int32_t framesPerBurst = AAudioStream_getFramesPerBurst(stream);
-        int32_t sizeFrames = AAudioStream_getBufferSizeInFrames(stream);
         printf("  Buffer:       burst     = %d\n", framesPerBurst);
+
+        int32_t sizeFrames = AAudioStream_getBufferSizeInFrames(stream);
         if (framesPerBurst > 0) {
-            printf("  Buffer:       size      = %d = (%d * %d) + %d\n",
+            int32_t requestedSize = getNumberOfBursts() * framesPerBurst;
+            printf("  BufferSize:   requested = %4d, actual = %4d = (%d * %d) + %d\n",
+                   requestedSize,
                    sizeFrames,
                    (sizeFrames / framesPerBurst),
                    framesPerBurst,
                    (sizeFrames % framesPerBurst));
+        } else {
+             printf("  BufferSize:    %d\n", sizeFrames);
         }
-        printf("  Capacity:     requested = %d, actual = %d\n", getBufferCapacity(),
-               AAudioStream_getBufferCapacityInFrames(stream));
+
+        int32_t capacityFrames = AAudioStream_getBufferCapacityInFrames(stream);
+        printf("  Capacity:     requested = %4d, actual = %4d = (%d * %d) + %d\n",
+               getBufferCapacity(),
+               capacityFrames,
+               (capacityFrames / framesPerBurst),
+               framesPerBurst,
+               (capacityFrames % framesPerBurst));
+
+        printf("  CallbackSize: requested = %d, actual = %d\n", getFramesPerCallback(),
+               AAudioStream_getFramesPerDataCallback(stream));
 
         printf("  SharingMode:  requested = %s, actual = %s\n",
                getSharingModeText(getSharingMode()),
@@ -431,6 +515,11 @@
         printf("  Is MMAP used? %s\n", AAudioStream_isMMapUsed(stream)
                ? "yes" : "no");
 
+        if (s_getAllowedCapturePolicy != nullptr) {
+            printf("  ContentType:  requested = %d, actual = %d\n",
+                   getAllowedCapturePolicy(), s_getAllowedCapturePolicy(stream));
+        }
+
     }
 
     int32_t getDurationSeconds() const {
diff --git a/media/libaaudio/examples/utils/AAudioSimplePlayer.h b/media/libaaudio/examples/utils/AAudioSimplePlayer.h
index 54b77ba..fd1fc45 100644
--- a/media/libaaudio/examples/utils/AAudioSimplePlayer.h
+++ b/media/libaaudio/examples/utils/AAudioSimplePlayer.h
@@ -32,8 +32,6 @@
 
 // Arbitrary period for glitches
 #define FORCED_UNDERRUN_PERIOD_FRAMES    (2 * 48000)
-// How long to sleep in a callback to cause an intentional glitch. For testing.
-#define FORCED_UNDERRUN_SLEEP_MICROS     (10 * 1000)
 
 #define MAX_TIMESTAMPS                   16
 
@@ -122,10 +120,9 @@
 
         if (result == AAUDIO_OK) {
             int32_t sizeInBursts = parameters.getNumberOfBursts();
-            if (sizeInBursts > 0) {
-                int32_t framesPerBurst = AAudioStream_getFramesPerBurst(mStream);
-                AAudioStream_setBufferSizeInFrames(mStream, sizeInBursts * framesPerBurst);
-            }
+            int32_t framesPerBurst = AAudioStream_getFramesPerBurst(mStream);
+            int32_t bufferSizeFrames = sizeInBursts * framesPerBurst;
+            AAudioStream_setBufferSizeInFrames(mStream, bufferSizeFrames);
         }
 
         AAudioStreamBuilder_delete(builder);
@@ -193,7 +190,7 @@
      aaudio_result_t start() {
         aaudio_result_t result = AAudioStream_requestStart(mStream);
         if (result != AAUDIO_OK) {
-            printf("ERROR - AAudioStream_requestStart() returned %d %s\n",
+            printf("ERROR - AAudioStream_requestStart(output) returned %d %s\n",
                     result, AAudio_convertResultToText(result));
         }
         return result;
@@ -203,7 +200,7 @@
     aaudio_result_t stop() {
         aaudio_result_t result = AAudioStream_requestStop(mStream);
         if (result != AAUDIO_OK) {
-            printf("ERROR - AAudioStream_requestStop() returned %d %s\n",
+            printf("ERROR - AAudioStream_requestStop(output) returned %d %s\n",
                    result, AAudio_convertResultToText(result));
         }
         int32_t xRunCount = AAudioStream_getXRunCount(mStream);
@@ -215,7 +212,7 @@
     aaudio_result_t pause() {
         aaudio_result_t result = AAudioStream_requestPause(mStream);
         if (result != AAUDIO_OK) {
-            printf("ERROR - AAudioStream_requestPause() returned %d %s\n",
+            printf("ERROR - AAudioStream_requestPause(output) returned %d %s\n",
                    result, AAudio_convertResultToText(result));
         }
         int32_t xRunCount = AAudioStream_getXRunCount(mStream);
@@ -223,11 +220,27 @@
         return result;
     }
 
+    aaudio_result_t waitUntilPaused() {
+        aaudio_result_t result = AAUDIO_OK;
+        aaudio_stream_state_t currentState = AAudioStream_getState(mStream);
+        aaudio_stream_state_t inputState = AAUDIO_STREAM_STATE_PAUSING;
+        while (result == AAUDIO_OK && currentState == AAUDIO_STREAM_STATE_PAUSING) {
+            result = AAudioStream_waitForStateChange(mStream, inputState,
+                                                     &currentState, NANOS_PER_SECOND);
+            inputState = currentState;
+        }
+        if (result != AAUDIO_OK) {
+            return result;
+        }
+        return (currentState == AAUDIO_STREAM_STATE_PAUSED)
+               ? AAUDIO_OK : AAUDIO_ERROR_INVALID_STATE;
+    }
+
     // Flush the stream. AAudio will stop calling your callback function.
     aaudio_result_t flush() {
         aaudio_result_t result = AAudioStream_requestFlush(mStream);
         if (result != AAUDIO_OK) {
-            printf("ERROR - AAudioStream_requestFlush() returned %d %s\n",
+            printf("ERROR - AAudioStream_requestFlush(output) returned %d %s\n",
                    result, AAudio_convertResultToText(result));
         }
         return result;
@@ -259,7 +272,7 @@
 
     int                scheduler = 0;
     bool               schedulerChecked = false;
-    bool               forceUnderruns = false;
+    int32_t            hangTimeMSec = 0;
 
     AAudioSimplePlayer simplePlayer;
     int32_t            callbackCount = 0;
@@ -311,10 +324,12 @@
         sineData->setupSineSweeps();
     }
 
-    if (sineData->forceUnderruns) {
+    if (sineData->hangTimeMSec > 0) {
         if (sineData->framesTotal > sineData->nextFrameToGlitch) {
-            usleep(FORCED_UNDERRUN_SLEEP_MICROS);
-            printf("Simulate glitch at %lld\n", (long long) sineData->framesTotal);
+            usleep(sineData->hangTimeMSec * 1000);
+            printf("Hang callback at %lld frames for %d msec\n",
+                    (long long) sineData->framesTotal,
+                   sineData->hangTimeMSec);
             sineData->nextFrameToGlitch += FORCED_UNDERRUN_PERIOD_FRAMES;
         }
     }
diff --git a/media/libaaudio/examples/utils/AAudioSimpleRecorder.h b/media/libaaudio/examples/utils/AAudioSimpleRecorder.h
index 869fad0..246e2d7 100644
--- a/media/libaaudio/examples/utils/AAudioSimpleRecorder.h
+++ b/media/libaaudio/examples/utils/AAudioSimpleRecorder.h
@@ -201,8 +201,10 @@
      aaudio_result_t start() {
         aaudio_result_t result = AAudioStream_requestStart(mStream);
         if (result != AAUDIO_OK) {
-            fprintf(stderr, "ERROR - AAudioStream_requestStart() returned %d %s\n",
+            fprintf(stderr, "ERROR - AAudioStream_requestStart(input) returned %d %s\n",
                     result, AAudio_convertResultToText(result));
+            fprintf(stderr, "        Did you remember to enter:   adb root    ????\n");
+
         }
         return result;
     }
@@ -211,8 +213,9 @@
     aaudio_result_t stop() {
         aaudio_result_t result = AAudioStream_requestStop(mStream);
         if (result != AAUDIO_OK) {
-            fprintf(stderr, "ERROR - AAudioStream_requestStop() returned %d %s\n",
+            fprintf(stderr, "ERROR - AAudioStream_requestStop(input) returned %d %s\n",
                     result, AAudio_convertResultToText(result));
+
         }
         return result;
     }
@@ -221,7 +224,7 @@
     aaudio_result_t pause() {
         aaudio_result_t result = AAudioStream_requestPause(mStream);
         if (result != AAUDIO_OK) {
-            fprintf(stderr, "ERROR - AAudioStream_requestPause() returned %d %s\n",
+            fprintf(stderr, "ERROR - AAudioStream_requestPause(input) returned %d %s\n",
                     result, AAudio_convertResultToText(result));
         }
         return result;
diff --git a/media/libaaudio/examples/write_sine/Android.bp b/media/libaaudio/examples/write_sine/Android.bp
index aa25e67..cc80861 100644
--- a/media/libaaudio/examples/write_sine/Android.bp
+++ b/media/libaaudio/examples/write_sine/Android.bp
@@ -4,6 +4,7 @@
     cflags: ["-Wall", "-Werror"],
     shared_libs: ["libaaudio"],
     header_libs: ["libaaudio_example_utils"],
+    pack_relocations: false,
 }
 
 cc_test {
@@ -12,4 +13,5 @@
     cflags: ["-Wall", "-Werror"],
     shared_libs: ["libaaudio"],
     header_libs: ["libaaudio_example_utils"],
+    pack_relocations: false,
 }
diff --git a/media/libaaudio/examples/write_sine/jni/Android.mk b/media/libaaudio/examples/write_sine/jni/Android.mk
deleted file mode 100644
index 1a1bd43..0000000
--- a/media/libaaudio/examples/write_sine/jni/Android.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := tests
-LOCAL_C_INCLUDES := \
-    $(call include-path-for, audio-utils) \
-    frameworks/av/media/libaaudio/include \
-    frameworks/av/media/libaaudio/src \
-    frameworks/av/media/libaaudio/examples/utils
-
-# NDK recommends using this kind of relative path instead of an absolute path.
-LOCAL_SRC_FILES:= ../src/write_sine.cpp
-LOCAL_CFLAGS := -Wall -Werror
-LOCAL_SHARED_LIBRARIES := libaaudio
-LOCAL_MODULE := write_sine
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := tests
-LOCAL_C_INCLUDES := \
-    $(call include-path-for, audio-utils) \
-    frameworks/av/media/libaaudio/include \
-    frameworks/av/media/libaaudio/examples/utils
-
-LOCAL_SRC_FILES:= ../src/write_sine_callback.cpp
-LOCAL_CFLAGS := -Wall -Werror
-LOCAL_SHARED_LIBRARIES := libaaudio
-LOCAL_MODULE := write_sine_callback
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := libaaudio_prebuilt
-LOCAL_SRC_FILES := libaaudio.so
-LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
-include $(PREBUILT_SHARED_LIBRARY)
diff --git a/media/libaaudio/examples/write_sine/jni/Application.mk b/media/libaaudio/examples/write_sine/jni/Application.mk
deleted file mode 100644
index ba44f37..0000000
--- a/media/libaaudio/examples/write_sine/jni/Application.mk
+++ /dev/null
@@ -1 +0,0 @@
-APP_CPPFLAGS += -std=c++11
diff --git a/media/libaaudio/examples/write_sine/src/write_sine_callback.cpp b/media/libaaudio/examples/write_sine/src/write_sine_callback.cpp
index e33e9f8..ca60233 100644
--- a/media/libaaudio/examples/write_sine/src/write_sine_callback.cpp
+++ b/media/libaaudio/examples/write_sine/src/write_sine_callback.cpp
@@ -26,10 +26,15 @@
 #include <string.h>
 #include <time.h>
 #include <aaudio/AAudio.h>
+
 #include "AAudioExampleUtils.h"
 #include "AAudioSimplePlayer.h"
 #include "AAudioArgsParser.h"
 
+#define APP_VERSION  "0.1.7"
+
+constexpr int32_t kDefaultHangTimeMSec = 10;
+
 /**
  * Open stream, play some sine waves, then close the stream.
  *
@@ -39,7 +44,7 @@
 static aaudio_result_t testOpenPlayClose(AAudioArgsParser &argParser,
                                          int32_t loopCount,
                                          int32_t prefixToneMsec,
-                                         bool forceUnderruns)
+                                         int32_t hangTimeMSec)
 {
     SineThreadedData_t myData;
     AAudioSimplePlayer &player = myData.simplePlayer;
@@ -51,10 +56,12 @@
     printf("----------------------- run complete test --------------------------\n");
     myData.schedulerChecked = false;
     myData.callbackCount = 0;
-    myData.forceUnderruns = forceUnderruns; // test AAudioStream_getXRunCount()
+    myData.hangTimeMSec = hangTimeMSec; // test AAudioStream_getXRunCount()
 
     result = player.open(argParser,
-                         SimplePlayerDataCallbackProc, SimplePlayerErrorCallbackProc, &myData);
+                         SimplePlayerDataCallbackProc,
+                         SimplePlayerErrorCallbackProc,
+                         &myData);
     if (result != AAUDIO_OK) {
         fprintf(stderr, "ERROR -  player.open() returned %s\n",
                 AAudio_convertResultToText(result));
@@ -109,16 +116,21 @@
         startedAtNanos = getNanoseconds(CLOCK_MONOTONIC);
         for (int second = 0; second < durationSeconds; second++) {
             // Sleep a while. Wake up early if there is an error, for example a DISCONNECT.
-            long ret = myData.waker.wait(AAUDIO_OK, NANOS_PER_SECOND);
+            myData.waker.wait(AAUDIO_OK, NANOS_PER_SECOND);
             int64_t millis =
                     (getNanoseconds(CLOCK_MONOTONIC) - startedAtNanos) / NANOS_PER_MILLISECOND;
             result = myData.waker.get();
-            printf("wait() returns %ld, aaudio_result = %d, at %6d millis"
-                           ", second = %3d, framesWritten = %8d, underruns = %d\n",
-                   ret, result, (int) millis,
+            const int32_t framesWritten = (int32_t) AAudioStream_getFramesWritten(player.getStream());
+            const int32_t framesRead = (int32_t) AAudioStream_getFramesRead(player.getStream());
+            const int32_t xruns = AAudioStream_getXRunCount(player.getStream());
+            printf(" waker result = %d, at %6d millis"
+                           ", second = %3d, frames written %8d - read %8d = %8d, underruns = %d\n",
+                   result, (int) millis,
                    second,
-                   (int) AAudioStream_getFramesWritten(player.getStream()),
-                   (int) AAudioStream_getXRunCount(player.getStream()));
+                   framesWritten,
+                   framesRead,
+                   framesWritten - framesRead,
+                   xruns);
             if (result != AAUDIO_OK) {
                 disconnected = (result == AAUDIO_ERROR_DISCONNECTED);
                 bailOut = true;
@@ -138,6 +150,10 @@
             if (result != AAUDIO_OK) {
                 goto error;
             }
+            result = player.waitUntilPaused();
+            if (result != AAUDIO_OK) {
+                goto error;
+            }
             result = player.flush();
         }
         if (result != AAUDIO_OK) {
@@ -204,7 +220,9 @@
     AAudioArgsParser::usage();
     printf("      -l{count} loopCount start/stop, every other one is silent\n");
     printf("      -t{msec}  play a high pitched tone at the beginning\n");
-    printf("      -z        force periodic underruns by sleeping in callback\n");
+    printf("      -h{msec}  force periodic underruns by hanging in callback\n");
+    printf("                If no value specified then %d used.\n",
+            kDefaultHangTimeMSec);
 }
 
 int main(int argc, const char **argv)
@@ -213,13 +231,14 @@
     aaudio_result_t    result;
     int32_t            loopCount = 1;
     int32_t            prefixToneMsec = 0;
-    bool               forceUnderruns = false;
+    int32_t            hangTimeMSec = 0;
 
     // Make printf print immediately so that debug info is not stuck
     // in a buffer if we hang or crash.
     setvbuf(stdout, nullptr, _IONBF, (size_t) 0);
 
-    printf("%s - Play a sine sweep using an AAudio callback V0.1.4\n", argv[0]);
+    printf("%s - Play a sine sweep using an AAudio callback V%s\n",
+        argv[0], APP_VERSION);
 
     for (int i = 1; i < argc; i++) {
         const char *arg = argv[i];
@@ -234,8 +253,10 @@
                     case 't':
                         prefixToneMsec = atoi(&arg[2]);
                         break;
-                    case 'z':
-                        forceUnderruns = true;  // Zzzzzzz
+                    case 'h':
+                        hangTimeMSec = (arg[2]) // value specified?
+                                ? atoi(&arg[2])
+                                : kDefaultHangTimeMSec;
                         break;
                     default:
                         usage();
@@ -251,7 +272,8 @@
     }
 
     // Keep looping until we can complete the test without disconnecting.
-    while((result = testOpenPlayClose(argParser, loopCount, prefixToneMsec, forceUnderruns))
+    while((result = testOpenPlayClose(argParser, loopCount,
+            prefixToneMsec, hangTimeMSec))
             == AAUDIO_ERROR_DISCONNECTED);
 
     return (result) ? EXIT_FAILURE : EXIT_SUCCESS;
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index 5b29419..ee5d089 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -37,7 +37,7 @@
 
 /**
  * This is used to represent a value that has not been specified.
- * For example, an application could use AAUDIO_UNSPECIFIED to indicate
+ * For example, an application could use {@link #AAUDIO_UNSPECIFIED} to indicate
  * that is did not not care what the specific value of a parameter was
  * and would accept whatever it was given.
  */
@@ -232,7 +232,8 @@
  * This information is used by certain platforms or routing policies
  * to make more refined volume or routing decisions.
  *
- * Note that these match the equivalent values in AudioAttributes in the Android Java API.
+ * Note that these match the equivalent values in {@link android.media.AudioAttributes}
+ * in the Android Java API.
  *
  * Added in API level 28.
  */
@@ -303,12 +304,13 @@
 /**
  * The CONTENT_TYPE attribute describes "what" you are playing.
  * It expresses the general category of the content. This information is optional.
- * But in case it is known (for instance {@link #AAUDIO_CONTENT_TYPE_MOVIE} for a
- * movie streaming service or {@link #AAUDIO_CONTENT_TYPE_SPEECH} for
+ * But in case it is known (for instance AAUDIO_CONTENT_TYPE_MOVIE for a
+ * movie streaming service or AAUDIO_CONTENT_TYPE_SPEECH for
  * an audio book application) this information might be used by the audio framework to
  * enforce audio focus.
  *
- * Note that these match the equivalent values in AudioAttributes in the Android Java API.
+ * Note that these match the equivalent values in {@link android.media.AudioAttributes}
+ * in the Android Java API.
  *
  * Added in API level 28.
  */
@@ -373,10 +375,59 @@
      * so the recorded volume may be very low.
      */
     AAUDIO_INPUT_PRESET_UNPROCESSED = 9,
+
+    /**
+     * Use this preset for capturing audio meant to be processed in real time
+     * and played back for live performance (e.g karaoke).
+     * The capture path will minimize latency and coupling with playback path.
+     */
+    AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE = 10,
 };
 typedef int32_t aaudio_input_preset_t;
 
 /**
+ * Specifying if audio may or may not be captured by other apps or the system.
+ *
+ * Note that these match the equivalent values in {@link android.media.AudioAttributes}
+ * in the Android Java API.
+ *
+ * Added in API level 29.
+ */
+enum {
+    /**
+     * Indicates that the audio may be captured by any app.
+     *
+     * For privacy, the following usages can not be recorded: AAUDIO_VOICE_COMMUNICATION*,
+     * AAUDIO_USAGE_NOTIFICATION*, AAUDIO_USAGE_ASSISTANCE* and {@link #AAUDIO_USAGE_ASSISTANT}.
+     *
+     * On {@link android.os.Build.VERSION_CODES#Q}, this means only {@link #AAUDIO_USAGE_MEDIA}
+     * and {@link #AAUDIO_USAGE_GAME} may be captured.
+     *
+     * See {@link android.media.AudioAttributes#ALLOW_CAPTURE_BY_ALL}.
+     */
+    AAUDIO_ALLOW_CAPTURE_BY_ALL = 1,
+    /**
+     * Indicates that the audio may only be captured by system apps.
+     *
+     * System apps can capture for many purposes like accessibility, user guidance...
+     * but have strong restriction. See
+     * {@link android.media.AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM} for what the system apps
+     * can do with the capture audio.
+     */
+    AAUDIO_ALLOW_CAPTURE_BY_SYSTEM = 2,
+    /**
+     * Indicates that the audio may not be recorded by any app, even if it is a system app.
+     *
+     * It is encouraged to use {@link #AAUDIO_ALLOW_CAPTURE_BY_SYSTEM} instead of this value as system apps
+     * provide significant and useful features for the user (eg. accessibility).
+     * See {@link android.media.AudioAttributes#ALLOW_CAPTURE_BY_NONE}.
+     */
+    AAUDIO_ALLOW_CAPTURE_BY_NONE = 3,
+};
+
+typedef int32_t aaudio_allowed_capture_policy_t;
+
+/**
  * These may be used with AAudioStreamBuilder_setSessionId().
  *
  * Added in API level 28.
@@ -423,7 +474,7 @@
  *
  * @return pointer to a text representation of an AAudio result code.
  */
-AAUDIO_API const char * AAudio_convertResultToText(aaudio_result_t returnCode);
+AAUDIO_API const char * AAudio_convertResultToText(aaudio_result_t returnCode) __INTRODUCED_IN(26);
 
 /**
  * The text is the ASCII symbol corresponding to the stream state,
@@ -433,7 +484,8 @@
  *
  * @return pointer to a text representation of an AAudio state.
  */
-AAUDIO_API const char * AAudio_convertStreamStateToText(aaudio_stream_state_t state);
+AAUDIO_API const char * AAudio_convertStreamStateToText(aaudio_stream_state_t state)
+        __INTRODUCED_IN(26);
 
 // ============================================================
 // StreamBuilder
@@ -444,32 +496,33 @@
  *
  * The deviceId is initially unspecified, meaning that the current default device will be used.
  *
- * The default direction is AAUDIO_DIRECTION_OUTPUT.
- * The default sharing mode is AAUDIO_SHARING_MODE_SHARED.
+ * The default direction is {@link #AAUDIO_DIRECTION_OUTPUT}.
+ * The default sharing mode is {@link #AAUDIO_SHARING_MODE_SHARED}.
  * The data format, samplesPerFrames and sampleRate are unspecified and will be
  * chosen by the device when it is opened.
  *
  * AAudioStreamBuilder_delete() must be called when you are done using the builder.
  */
-AAUDIO_API aaudio_result_t AAudio_createStreamBuilder(AAudioStreamBuilder** builder);
+AAUDIO_API aaudio_result_t AAudio_createStreamBuilder(AAudioStreamBuilder** builder)
+        __INTRODUCED_IN(26);
 
 /**
  * Request an audio device identified device using an ID.
  * On Android, for example, the ID could be obtained from the Java AudioManager.
  *
- * The default, if you do not call this function, is AAUDIO_UNSPECIFIED,
+ * The default, if you do not call this function, is {@link #AAUDIO_UNSPECIFIED},
  * in which case the primary device will be used.
  *
  * @param builder reference provided by AAudio_createStreamBuilder()
- * @param deviceId device identifier or AAUDIO_UNSPECIFIED
+ * @param deviceId device identifier or {@link #AAUDIO_UNSPECIFIED}
  */
 AAUDIO_API void AAudioStreamBuilder_setDeviceId(AAudioStreamBuilder* builder,
-                                                     int32_t deviceId);
+                                                int32_t deviceId) __INTRODUCED_IN(26);
 
 /**
  * Request a sample rate in Hertz.
  *
- * The default, if you do not call this function, is AAUDIO_UNSPECIFIED.
+ * The default, if you do not call this function, is {@link #AAUDIO_UNSPECIFIED}.
  * An optimal value will then be chosen when the stream is opened.
  * After opening a stream with an unspecified value, the application must
  * query for the actual value, which may vary by device.
@@ -481,12 +534,12 @@
  * @param sampleRate frames per second. Common rates include 44100 and 48000 Hz.
  */
 AAUDIO_API void AAudioStreamBuilder_setSampleRate(AAudioStreamBuilder* builder,
-                                                       int32_t sampleRate);
+                                                  int32_t sampleRate) __INTRODUCED_IN(26);
 
 /**
  * Request a number of channels for the stream.
  *
- * The default, if you do not call this function, is AAUDIO_UNSPECIFIED.
+ * The default, if you do not call this function, is {@link #AAUDIO_UNSPECIFIED}.
  * An optimal value will then be chosen when the stream is opened.
  * After opening a stream with an unspecified value, the application must
  * query for the actual value, which may vary by device.
@@ -498,7 +551,7 @@
  * @param channelCount Number of channels desired.
  */
 AAUDIO_API void AAudioStreamBuilder_setChannelCount(AAudioStreamBuilder* builder,
-                                                   int32_t channelCount);
+                                                    int32_t channelCount) __INTRODUCED_IN(26);
 
 /**
  * Identical to AAudioStreamBuilder_setChannelCount().
@@ -507,12 +560,12 @@
  * @param samplesPerFrame Number of samples in a frame.
  */
 AAUDIO_API void AAudioStreamBuilder_setSamplesPerFrame(AAudioStreamBuilder* builder,
-                                                       int32_t samplesPerFrame);
+                                                       int32_t samplesPerFrame) __INTRODUCED_IN(26);
 
 /**
- * Request a sample data format, for example AAUDIO_FORMAT_PCM_I16.
+ * Request a sample data format, for example {@link #AAUDIO_FORMAT_PCM_I16}.
  *
- * The default, if you do not call this function, is AAUDIO_UNSPECIFIED.
+ * The default, if you do not call this function, is {@link #AAUDIO_UNSPECIFIED}.
  * An optimal value will then be chosen when the stream is opened.
  * After opening a stream with an unspecified value, the application must
  * query for the actual value, which may vary by device.
@@ -521,64 +574,66 @@
  * If a stream cannot be opened with the specified value then the open will fail.
  *
  * @param builder reference provided by AAudio_createStreamBuilder()
- * @param format common formats are AAUDIO_FORMAT_PCM_FLOAT and AAUDIO_FORMAT_PCM_I16.
+ * @param format common formats are {@link #AAUDIO_FORMAT_PCM_FLOAT} and
+ *               {@link #AAUDIO_FORMAT_PCM_I16}.
  */
 AAUDIO_API void AAudioStreamBuilder_setFormat(AAudioStreamBuilder* builder,
-                                                   aaudio_format_t format);
+                                              aaudio_format_t format) __INTRODUCED_IN(26);
 
 /**
  * Request a mode for sharing the device.
  *
- * The default, if you do not call this function, is AAUDIO_SHARING_MODE_SHARED.
+ * The default, if you do not call this function, is {@link #AAUDIO_SHARING_MODE_SHARED}.
  *
  * The requested sharing mode may not be available.
  * The application can query for the actual mode after the stream is opened.
  *
  * @param builder reference provided by AAudio_createStreamBuilder()
- * @param sharingMode AAUDIO_SHARING_MODE_SHARED or AAUDIO_SHARING_MODE_EXCLUSIVE
+ * @param sharingMode {@link #AAUDIO_SHARING_MODE_SHARED} or {@link #AAUDIO_SHARING_MODE_EXCLUSIVE}
  */
 AAUDIO_API void AAudioStreamBuilder_setSharingMode(AAudioStreamBuilder* builder,
-                                                        aaudio_sharing_mode_t sharingMode);
+        aaudio_sharing_mode_t sharingMode) __INTRODUCED_IN(26);
 
 /**
  * Request the direction for a stream.
  *
- * The default, if you do not call this function, is AAUDIO_DIRECTION_OUTPUT.
+ * The default, if you do not call this function, is {@link #AAUDIO_DIRECTION_OUTPUT}.
  *
  * @param builder reference provided by AAudio_createStreamBuilder()
- * @param direction AAUDIO_DIRECTION_OUTPUT or AAUDIO_DIRECTION_INPUT
+ * @param direction {@link #AAUDIO_DIRECTION_OUTPUT} or {@link #AAUDIO_DIRECTION_INPUT}
  */
 AAUDIO_API void AAudioStreamBuilder_setDirection(AAudioStreamBuilder* builder,
-                                                            aaudio_direction_t direction);
+        aaudio_direction_t direction) __INTRODUCED_IN(26);
 
 /**
  * Set the requested buffer capacity in frames.
  * The final AAudioStream capacity may differ, but will probably be at least this big.
  *
- * The default, if you do not call this function, is AAUDIO_UNSPECIFIED.
+ * The default, if you do not call this function, is {@link #AAUDIO_UNSPECIFIED}.
  *
  * @param builder reference provided by AAudio_createStreamBuilder()
- * @param numFrames the desired buffer capacity in frames or AAUDIO_UNSPECIFIED
+ * @param numFrames the desired buffer capacity in frames or {@link #AAUDIO_UNSPECIFIED}
  */
 AAUDIO_API void AAudioStreamBuilder_setBufferCapacityInFrames(AAudioStreamBuilder* builder,
-                                                                 int32_t numFrames);
+        int32_t numFrames) __INTRODUCED_IN(26);
 
 /**
  * Set the requested performance mode.
  *
- * Supported modes are AAUDIO_PERFORMANCE_MODE_NONE, AAUDIO_PERFORMANCE_MODE_POWER_SAVING
- * and AAUDIO_PERFORMANCE_MODE_LOW_LATENCY.
+ * Supported modes are {@link #AAUDIO_PERFORMANCE_MODE_NONE},
+ * {@link #AAUDIO_PERFORMANCE_MODE_POWER_SAVING} * and {@link #AAUDIO_PERFORMANCE_MODE_LOW_LATENCY}.
  *
- * The default, if you do not call this function, is AAUDIO_PERFORMANCE_MODE_NONE.
+ * The default, if you do not call this function, is {@link #AAUDIO_PERFORMANCE_MODE_NONE}.
  *
  * You may not get the mode you requested.
- * You can call AAudioStream_getPerformanceMode() to find out the final mode for the stream.
+ * You can call AAudioStream_getPerformanceMode()
+ * to find out the final mode for the stream.
  *
  * @param builder reference provided by AAudio_createStreamBuilder()
- * @param mode the desired performance mode, eg. AAUDIO_PERFORMANCE_MODE_LOW_LATENCY
+ * @param mode the desired performance mode, eg. {@link #AAUDIO_PERFORMANCE_MODE_LOW_LATENCY}
  */
 AAUDIO_API void AAudioStreamBuilder_setPerformanceMode(AAudioStreamBuilder* builder,
-                                                aaudio_performance_mode_t mode);
+        aaudio_performance_mode_t mode) __INTRODUCED_IN(26);
 
 /**
  * Set the intended use case for the stream.
@@ -587,15 +642,15 @@
  * behavior of the stream.
  * This could, for example, affect how volume and focus is handled for the stream.
  *
- * The default, if you do not call this function, is AAUDIO_USAGE_MEDIA.
+ * The default, if you do not call this function, is {@link #AAUDIO_USAGE_MEDIA}.
  *
  * Added in API level 28.
  *
  * @param builder reference provided by AAudio_createStreamBuilder()
- * @param usage the desired usage, eg. AAUDIO_USAGE_GAME
+ * @param usage the desired usage, eg. {@link #AAUDIO_USAGE_GAME}
  */
 AAUDIO_API void AAudioStreamBuilder_setUsage(AAudioStreamBuilder* builder,
-                                                       aaudio_usage_t usage);
+        aaudio_usage_t usage) __INTRODUCED_IN(28);
 
 /**
  * Set the type of audio data that the stream will carry.
@@ -604,15 +659,15 @@
  * behavior of the stream.
  * This could, for example, affect whether a stream is paused when a notification occurs.
  *
- * The default, if you do not call this function, is AAUDIO_CONTENT_TYPE_MUSIC.
+ * The default, if you do not call this function, is {@link #AAUDIO_CONTENT_TYPE_MUSIC}.
  *
  * Added in API level 28.
  *
  * @param builder reference provided by AAudio_createStreamBuilder()
- * @param contentType the type of audio data, eg. AAUDIO_CONTENT_TYPE_SPEECH
+ * @param contentType the type of audio data, eg. {@link #AAUDIO_CONTENT_TYPE_SPEECH}
  */
 AAUDIO_API void AAudioStreamBuilder_setContentType(AAudioStreamBuilder* builder,
-                                             aaudio_content_type_t contentType);
+        aaudio_content_type_t contentType) __INTRODUCED_IN(28);
 
 /**
  * Set the input (capture) preset for the stream.
@@ -622,7 +677,7 @@
  * This could, for example, affect which microphones are used and how the
  * recorded data is processed.
  *
- * The default, if you do not call this function, is AAUDIO_INPUT_PRESET_VOICE_RECOGNITION.
+ * The default, if you do not call this function, is {@link #AAUDIO_INPUT_PRESET_VOICE_RECOGNITION}.
  * That is because VOICE_RECOGNITION is the preset with the lowest latency
  * on many platforms.
  *
@@ -632,16 +687,32 @@
  * @param inputPreset the desired configuration for recording
  */
 AAUDIO_API void AAudioStreamBuilder_setInputPreset(AAudioStreamBuilder* builder,
-                                                   aaudio_input_preset_t inputPreset);
+        aaudio_input_preset_t inputPreset) __INTRODUCED_IN(28);
+
+/**
+ * Specify whether this stream audio may or may not be captured by other apps or the system.
+ *
+ * The default is {@link #AAUDIO_ALLOW_CAPTURE_BY_ALL}.
+ *
+ * Note that an application can also set its global policy, in which case the most restrictive
+ * policy is always applied. See {@link android.media.AudioAttributes#setAllowedCapturePolicy(int)}
+ *
+ * Added in API level 29.
+ *
+ * @param builder reference provided by AAudio_createStreamBuilder()
+ * @param inputPreset the desired level of opt-out from being captured.
+ */
+AAUDIO_API void AAudioStreamBuilder_setAllowedCapturePolicy(AAudioStreamBuilder* builder,
+        aaudio_allowed_capture_policy_t capturePolicy) __INTRODUCED_IN(29);
 
 /** Set the requested session ID.
  *
  * The session ID can be used to associate a stream with effects processors.
  * The effects are controlled using the Android AudioEffect Java API.
  *
- * The default, if you do not call this function, is AAUDIO_SESSION_ID_NONE.
+ * The default, if you do not call this function, is {@link #AAUDIO_SESSION_ID_NONE}.
  *
- * If set to AAUDIO_SESSION_ID_ALLOCATE then a session ID will be allocated
+ * If set to {@link #AAUDIO_SESSION_ID_ALLOCATE} then a session ID will be allocated
  * when the stream is opened.
  *
  * The allocated session ID can be obtained by calling AAudioStream_getSessionId()
@@ -659,10 +730,10 @@
  * Added in API level 28.
  *
  * @param builder reference provided by AAudio_createStreamBuilder()
- * @param sessionId an allocated sessionID or AAUDIO_SESSION_ID_ALLOCATE
+ * @param sessionId an allocated sessionID or {@link #AAUDIO_SESSION_ID_ALLOCATE}
  */
 AAUDIO_API void AAudioStreamBuilder_setSessionId(AAudioStreamBuilder* builder,
-                                                aaudio_session_id_t sessionId);
+        aaudio_session_id_t sessionId) __INTRODUCED_IN(28);
 
 /**
  * Return one of these values from the data callback function.
@@ -742,15 +813,16 @@
  *
  * Note that when using this callback, the audio data will be passed in or out
  * of the function as an argument.
- * So you cannot call AAudioStream_write() or AAudioStream_read() on the same stream
- * that has an active data callback.
+ * So you cannot call AAudioStream_write() or AAudioStream_read()
+ * on the same stream that has an active data callback.
  *
- * The callback function will start being called after AAudioStream_requestStart() is called.
+ * The callback function will start being called after AAudioStream_requestStart()
+ * is called.
  * It will stop being called after AAudioStream_requestPause() or
  * AAudioStream_requestStop() is called.
  *
  * This callback function will be called on a real-time thread owned by AAudio. See
- * {@link AAudioStream_dataCallback} for more information.
+ * {@link #AAudioStream_dataCallback} for more information.
  *
  * Note that the AAudio callbacks will never be called simultaneously from multiple threads.
  *
@@ -760,14 +832,13 @@
  *          to the callback functions.
  */
 AAUDIO_API void AAudioStreamBuilder_setDataCallback(AAudioStreamBuilder* builder,
-                                                 AAudioStream_dataCallback callback,
-                                                 void *userData);
+        AAudioStream_dataCallback callback, void *userData) __INTRODUCED_IN(26);
 
 /**
  * Set the requested data callback buffer size in frames.
- * See {@link AAudioStream_dataCallback}.
+ * See {@link #AAudioStream_dataCallback}.
  *
- * The default, if you do not call this function, is AAUDIO_UNSPECIFIED.
+ * The default, if you do not call this function, is {@link #AAUDIO_UNSPECIFIED}.
  *
  * For the lowest possible latency, do not call this function. AAudio will then
  * call the dataProc callback function with whatever size is optimal.
@@ -784,10 +855,10 @@
  * half the buffer capacity, to allow double buffering.
  *
  * @param builder reference provided by AAudio_createStreamBuilder()
- * @param numFrames the desired buffer size in frames or AAUDIO_UNSPECIFIED
+ * @param numFrames the desired buffer size in frames or {@link #AAUDIO_UNSPECIFIED}
  */
 AAUDIO_API void AAudioStreamBuilder_setFramesPerDataCallback(AAudioStreamBuilder* builder,
-                                                             int32_t numFrames);
+                                                             int32_t numFrames) __INTRODUCED_IN(26);
 
 /**
  * Prototype for the callback function that is passed to
@@ -840,29 +911,29 @@
  *          to the callback functions.
  */
 AAUDIO_API void AAudioStreamBuilder_setErrorCallback(AAudioStreamBuilder* builder,
-                                                AAudioStream_errorCallback callback,
-                                                void *userData);
+        AAudioStream_errorCallback callback, void *userData) __INTRODUCED_IN(26);
 
 /**
  * Open a stream based on the options in the StreamBuilder.
  *
- * AAudioStream_close must be called when finished with the stream to recover
+ * AAudioStream_close() must be called when finished with the stream to recover
  * the memory and to free the associated resources.
  *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param stream pointer to a variable to receive the new stream reference
- * @return AAUDIO_OK or a negative error.
+ * @return {@link #AAUDIO_OK} or a negative error.
  */
 AAUDIO_API aaudio_result_t  AAudioStreamBuilder_openStream(AAudioStreamBuilder* builder,
-                                                     AAudioStream** stream);
+        AAudioStream** stream) __INTRODUCED_IN(26);
 
 /**
  * Delete the resources associated with the StreamBuilder.
  *
  * @param builder reference provided by AAudio_createStreamBuilder()
- * @return AAUDIO_OK or a negative error.
+ * @return {@link #AAUDIO_OK} or a negative error.
  */
-AAUDIO_API aaudio_result_t  AAudioStreamBuilder_delete(AAudioStreamBuilder* builder);
+AAUDIO_API aaudio_result_t  AAudioStreamBuilder_delete(AAudioStreamBuilder* builder)
+    __INTRODUCED_IN(26);
 
 // ============================================================
 // Stream Control
@@ -872,70 +943,74 @@
  * Free the resources associated with a stream created by AAudioStreamBuilder_openStream()
  *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
- * @return AAUDIO_OK or a negative error.
+ * @return {@link #AAUDIO_OK} or a negative error.
  */
-AAUDIO_API aaudio_result_t  AAudioStream_close(AAudioStream* stream);
+AAUDIO_API aaudio_result_t  AAudioStream_close(AAudioStream* stream) __INTRODUCED_IN(26);
 
 /**
  * Asynchronously request to start playing the stream. For output streams, one should
  * write to the stream to fill the buffer before starting.
  * Otherwise it will underflow.
- * After this call the state will be in AAUDIO_STREAM_STATE_STARTING or AAUDIO_STREAM_STATE_STARTED.
+ * After this call the state will be in {@link #AAUDIO_STREAM_STATE_STARTING} or
+ * {@link #AAUDIO_STREAM_STATE_STARTED}.
  *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
- * @return AAUDIO_OK or a negative error.
+ * @return {@link #AAUDIO_OK} or a negative error.
  */
-AAUDIO_API aaudio_result_t  AAudioStream_requestStart(AAudioStream* stream);
+AAUDIO_API aaudio_result_t  AAudioStream_requestStart(AAudioStream* stream) __INTRODUCED_IN(26);
 
 /**
  * Asynchronous request for the stream to pause.
  * Pausing a stream will freeze the data flow but not flush any buffers.
- * Use AAudioStream_Start() to resume playback after a pause.
- * After this call the state will be in AAUDIO_STREAM_STATE_PAUSING or AAUDIO_STREAM_STATE_PAUSED.
+ * Use AAudioStream_requestStart() to resume playback after a pause.
+ * After this call the state will be in {@link #AAUDIO_STREAM_STATE_PAUSING} or
+ * {@link #AAUDIO_STREAM_STATE_PAUSED}.
  *
- * This will return AAUDIO_ERROR_UNIMPLEMENTED for input streams.
+ * This will return {@link #AAUDIO_ERROR_UNIMPLEMENTED} for input streams.
  * For input streams use AAudioStream_requestStop().
  *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
- * @return AAUDIO_OK or a negative error.
+ * @return {@link #AAUDIO_OK} or a negative error.
  */
-AAUDIO_API aaudio_result_t  AAudioStream_requestPause(AAudioStream* stream);
+AAUDIO_API aaudio_result_t  AAudioStream_requestPause(AAudioStream* stream) __INTRODUCED_IN(26);
 
 /**
  * Asynchronous request for the stream to flush.
  * Flushing will discard any pending data.
  * This call only works if the stream is pausing or paused. TODO review
  * Frame counters are not reset by a flush. They may be advanced.
- * After this call the state will be in AAUDIO_STREAM_STATE_FLUSHING or AAUDIO_STREAM_STATE_FLUSHED.
+ * After this call the state will be in {@link #AAUDIO_STREAM_STATE_FLUSHING} or
+ * {@link #AAUDIO_STREAM_STATE_FLUSHED}.
  *
- * This will return AAUDIO_ERROR_UNIMPLEMENTED for input streams.
+ * This will return {@link #AAUDIO_ERROR_UNIMPLEMENTED} for input streams.
  *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
- * @return AAUDIO_OK or a negative error.
+ * @return {@link #AAUDIO_OK} or a negative error.
  */
-AAUDIO_API aaudio_result_t  AAudioStream_requestFlush(AAudioStream* stream);
+AAUDIO_API aaudio_result_t  AAudioStream_requestFlush(AAudioStream* stream) __INTRODUCED_IN(26);
 
 /**
  * Asynchronous request for the stream to stop.
  * The stream will stop after all of the data currently buffered has been played.
- * After this call the state will be in AAUDIO_STREAM_STATE_STOPPING or AAUDIO_STREAM_STATE_STOPPED.
+ * After this call the state will be in {@link #AAUDIO_STREAM_STATE_STOPPING} or
+ * {@link #AAUDIO_STREAM_STATE_STOPPED}.
  *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
- * @return AAUDIO_OK or a negative error.
+ * @return {@link #AAUDIO_OK} or a negative error.
  */
-AAUDIO_API aaudio_result_t  AAudioStream_requestStop(AAudioStream* stream);
+AAUDIO_API aaudio_result_t  AAudioStream_requestStop(AAudioStream* stream) __INTRODUCED_IN(26);
 
 /**
- * Query the current state of the client, eg. AAUDIO_STREAM_STATE_PAUSING
+ * Query the current state of the client, eg. {@link #AAUDIO_STREAM_STATE_PAUSING}
  *
  * This function will immediately return the state without updating the state.
  * If you want to update the client state based on the server state then
  * call AAudioStream_waitForStateChange() with currentState
- * set to AAUDIO_STREAM_STATE_UNKNOWN and a zero timeout.
+ * set to {@link #AAUDIO_STREAM_STATE_UNKNOWN} and a zero timeout.
  *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  */
-AAUDIO_API aaudio_stream_state_t AAudioStream_getState(AAudioStream* stream);
+AAUDIO_API aaudio_stream_state_t AAudioStream_getState(AAudioStream* stream) __INTRODUCED_IN(26);
 
 /**
  * Wait until the current state no longer matches the input state.
@@ -957,12 +1032,11 @@
  * @param inputState The state we want to avoid.
  * @param nextState Pointer to a variable that will be set to the new state.
  * @param timeoutNanoseconds Maximum number of nanoseconds to wait for completion.
- * @return AAUDIO_OK or a negative error.
+ * @return {@link #AAUDIO_OK} or a negative error.
  */
 AAUDIO_API aaudio_result_t AAudioStream_waitForStateChange(AAudioStream* stream,
-                                            aaudio_stream_state_t inputState,
-                                            aaudio_stream_state_t *nextState,
-                                            int64_t timeoutNanoseconds);
+        aaudio_stream_state_t inputState, aaudio_stream_state_t *nextState,
+        int64_t timeoutNanoseconds) __INTRODUCED_IN(26);
 
 // ============================================================
 // Stream I/O
@@ -989,9 +1063,7 @@
  * @return The number of frames actually read or a negative error.
  */
 AAUDIO_API aaudio_result_t AAudioStream_read(AAudioStream* stream,
-                               void *buffer,
-                               int32_t numFrames,
-                               int64_t timeoutNanoseconds);
+        void *buffer, int32_t numFrames, int64_t timeoutNanoseconds) __INTRODUCED_IN(26);
 
 /**
  * Write data to the stream.
@@ -1014,9 +1086,7 @@
  * @return The number of frames actually written or a negative error.
  */
 AAUDIO_API aaudio_result_t AAudioStream_write(AAudioStream* stream,
-                               const void *buffer,
-                               int32_t numFrames,
-                               int64_t timeoutNanoseconds);
+        const void *buffer, int32_t numFrames, int64_t timeoutNanoseconds) __INTRODUCED_IN(26);
 
 // ============================================================
 // Stream - queries
@@ -1039,7 +1109,7 @@
  * @return actual buffer size in frames or a negative error
  */
 AAUDIO_API aaudio_result_t AAudioStream_setBufferSizeInFrames(AAudioStream* stream,
-                                                      int32_t numFrames);
+        int32_t numFrames) __INTRODUCED_IN(26);
 
 /**
  * Query the maximum number of frames that can be filled without blocking.
@@ -1047,7 +1117,7 @@
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return buffer size in frames.
  */
-AAUDIO_API int32_t AAudioStream_getBufferSizeInFrames(AAudioStream* stream);
+AAUDIO_API int32_t AAudioStream_getBufferSizeInFrames(AAudioStream* stream) __INTRODUCED_IN(26);
 
 /**
  * Query the number of frames that the application should read or write at
@@ -1062,7 +1132,7 @@
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return burst size
  */
-AAUDIO_API int32_t AAudioStream_getFramesPerBurst(AAudioStream* stream);
+AAUDIO_API int32_t AAudioStream_getFramesPerBurst(AAudioStream* stream) __INTRODUCED_IN(26);
 
 /**
  * Query maximum buffer capacity in frames.
@@ -1070,7 +1140,7 @@
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return  buffer capacity in frames
  */
-AAUDIO_API int32_t AAudioStream_getBufferCapacityInFrames(AAudioStream* stream);
+AAUDIO_API int32_t AAudioStream_getBufferCapacityInFrames(AAudioStream* stream) __INTRODUCED_IN(26);
 
 /**
  * Query the size of the buffer that will be passed to the dataProc callback
@@ -1079,19 +1149,19 @@
  * This call can be used if the application needs to know the value of numFrames before
  * the stream is started. This is not normally necessary.
  *
- * If a specific size was requested by calling AAudioStreamBuilder_setFramesPerDataCallback()
- * then this will be the same size.
+ * If a specific size was requested by calling
+ * AAudioStreamBuilder_setFramesPerDataCallback() then this will be the same size.
  *
  * If AAudioStreamBuilder_setFramesPerDataCallback() was not called then this will
- * return the size chosen by AAudio, or AAUDIO_UNSPECIFIED.
+ * return the size chosen by AAudio, or {@link #AAUDIO_UNSPECIFIED}.
  *
- * AAUDIO_UNSPECIFIED indicates that the callback buffer size for this stream
+ * {@link #AAUDIO_UNSPECIFIED} indicates that the callback buffer size for this stream
  * may vary from one dataProc callback to the next.
  *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
- * @return callback buffer size in frames or AAUDIO_UNSPECIFIED
+ * @return callback buffer size in frames or {@link #AAUDIO_UNSPECIFIED}
  */
-AAUDIO_API int32_t AAudioStream_getFramesPerDataCallback(AAudioStream* stream);
+AAUDIO_API int32_t AAudioStream_getFramesPerDataCallback(AAudioStream* stream) __INTRODUCED_IN(26);
 
 /**
  * An XRun is an Underrun or an Overrun.
@@ -1108,13 +1178,13 @@
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return the underrun or overrun count
  */
-AAUDIO_API int32_t AAudioStream_getXRunCount(AAudioStream* stream);
+AAUDIO_API int32_t AAudioStream_getXRunCount(AAudioStream* stream) __INTRODUCED_IN(26);
 
 /**
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return actual sample rate
  */
-AAUDIO_API int32_t AAudioStream_getSampleRate(AAudioStream* stream);
+AAUDIO_API int32_t AAudioStream_getSampleRate(AAudioStream* stream) __INTRODUCED_IN(26);
 
 /**
  * A stream has one or more channels of data.
@@ -1123,7 +1193,7 @@
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return actual number of channels
  */
-AAUDIO_API int32_t AAudioStream_getChannelCount(AAudioStream* stream);
+AAUDIO_API int32_t AAudioStream_getChannelCount(AAudioStream* stream) __INTRODUCED_IN(26);
 
 /**
  * Identical to AAudioStream_getChannelCount().
@@ -1131,39 +1201,41 @@
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return actual number of samples frame
  */
-AAUDIO_API int32_t AAudioStream_getSamplesPerFrame(AAudioStream* stream);
+AAUDIO_API int32_t AAudioStream_getSamplesPerFrame(AAudioStream* stream) __INTRODUCED_IN(26);
 
 /**
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return actual device ID
  */
-AAUDIO_API int32_t AAudioStream_getDeviceId(AAudioStream* stream);
+AAUDIO_API int32_t AAudioStream_getDeviceId(AAudioStream* stream) __INTRODUCED_IN(26);
 
 /**
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return actual data format
  */
-AAUDIO_API aaudio_format_t AAudioStream_getFormat(AAudioStream* stream);
+AAUDIO_API aaudio_format_t AAudioStream_getFormat(AAudioStream* stream) __INTRODUCED_IN(26);
 
 /**
  * Provide actual sharing mode.
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return  actual sharing mode
  */
-AAUDIO_API aaudio_sharing_mode_t AAudioStream_getSharingMode(AAudioStream* stream);
+AAUDIO_API aaudio_sharing_mode_t AAudioStream_getSharingMode(AAudioStream* stream)
+        __INTRODUCED_IN(26);
 
 /**
  * Get the performance mode used by the stream.
  *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  */
-AAUDIO_API aaudio_performance_mode_t AAudioStream_getPerformanceMode(AAudioStream* stream);
+AAUDIO_API aaudio_performance_mode_t AAudioStream_getPerformanceMode(AAudioStream* stream)
+        __INTRODUCED_IN(26);
 
 /**
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return direction
  */
-AAUDIO_API aaudio_direction_t AAudioStream_getDirection(AAudioStream* stream);
+AAUDIO_API aaudio_direction_t AAudioStream_getDirection(AAudioStream* stream) __INTRODUCED_IN(26);
 
 /**
  * Passes back the number of frames that have been written since the stream was created.
@@ -1176,7 +1248,7 @@
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return frames written
  */
-AAUDIO_API int64_t AAudioStream_getFramesWritten(AAudioStream* stream);
+AAUDIO_API int64_t AAudioStream_getFramesWritten(AAudioStream* stream) __INTRODUCED_IN(26);
 
 /**
  * Passes back the number of frames that have been read since the stream was created.
@@ -1189,7 +1261,7 @@
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return frames read
  */
-AAUDIO_API int64_t AAudioStream_getFramesRead(AAudioStream* stream);
+AAUDIO_API int64_t AAudioStream_getFramesRead(AAudioStream* stream) __INTRODUCED_IN(26);
 
 /**
  * Passes back the session ID associated with this stream.
@@ -1197,34 +1269,35 @@
  * The session ID can be used to associate a stream with effects processors.
  * The effects are controlled using the Android AudioEffect Java API.
  *
- * If AAudioStreamBuilder_setSessionId() was called with AAUDIO_SESSION_ID_ALLOCATE
+ * If AAudioStreamBuilder_setSessionId() was
+ * called with {@link #AAUDIO_SESSION_ID_ALLOCATE}
  * then a new session ID should be allocated once when the stream is opened.
  *
  * If AAudioStreamBuilder_setSessionId() was called with a previously allocated
  * session ID then that value should be returned.
  *
  * If AAudioStreamBuilder_setSessionId() was not called then this function should
- * return AAUDIO_SESSION_ID_NONE.
+ * return {@link #AAUDIO_SESSION_ID_NONE}.
  *
  * The sessionID for a stream should not change once the stream has been opened.
  *
  * Added in API level 28.
  *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
- * @return session ID or AAUDIO_SESSION_ID_NONE
+ * @return session ID or {@link #AAUDIO_SESSION_ID_NONE}
  */
-AAUDIO_API aaudio_session_id_t AAudioStream_getSessionId(AAudioStream* stream);
+AAUDIO_API aaudio_session_id_t AAudioStream_getSessionId(AAudioStream* stream) __INTRODUCED_IN(28);
 
 /**
  * Passes back the time at which a particular frame was presented.
  * This can be used to synchronize audio with video or MIDI.
  * It can also be used to align a recorded stream with a playback stream.
  *
- * Timestamps are only valid when the stream is in AAUDIO_STREAM_STATE_STARTED.
- * AAUDIO_ERROR_INVALID_STATE will be returned if the stream is not started.
+ * Timestamps are only valid when the stream is in {@link #AAUDIO_STREAM_STATE_STARTED}.
+ * {@link #AAUDIO_ERROR_INVALID_STATE} will be returned if the stream is not started.
  * Note that because requestStart() is asynchronous, timestamps will not be valid until
  * a short time after calling requestStart().
- * So AAUDIO_ERROR_INVALID_STATE should not be considered a fatal error.
+ * So {@link #AAUDIO_ERROR_INVALID_STATE} should not be considered a fatal error.
  * Just try calling again later.
  *
  * If an error occurs, then the position and time will not be modified.
@@ -1235,12 +1308,10 @@
  * @param clockid CLOCK_MONOTONIC or CLOCK_BOOTTIME
  * @param framePosition pointer to a variable to receive the position
  * @param timeNanoseconds pointer to a variable to receive the time
- * @return AAUDIO_OK or a negative error
+ * @return {@link #AAUDIO_OK} or a negative error
  */
 AAUDIO_API aaudio_result_t AAudioStream_getTimestamp(AAudioStream* stream,
-                                      clockid_t clockid,
-                                      int64_t *framePosition,
-                                      int64_t *timeNanoseconds);
+        clockid_t clockid, int64_t *framePosition, int64_t *timeNanoseconds) __INTRODUCED_IN(26);
 
 /**
  * Return the use case for the stream.
@@ -1250,7 +1321,7 @@
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return frames read
  */
-AAUDIO_API aaudio_usage_t AAudioStream_getUsage(AAudioStream* stream);
+AAUDIO_API aaudio_usage_t AAudioStream_getUsage(AAudioStream* stream) __INTRODUCED_IN(28);
 
 /**
  * Return the content type for the stream.
@@ -1258,9 +1329,10 @@
  * Added in API level 28.
  *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
- * @return content type, for example AAUDIO_CONTENT_TYPE_MUSIC
+ * @return content type, for example {@link #AAUDIO_CONTENT_TYPE_MUSIC}
  */
-AAUDIO_API aaudio_content_type_t AAudioStream_getContentType(AAudioStream* stream);
+AAUDIO_API aaudio_content_type_t AAudioStream_getContentType(AAudioStream* stream)
+        __INTRODUCED_IN(28);
 
 /**
  * Return the input preset for the stream.
@@ -1268,9 +1340,22 @@
  * Added in API level 28.
  *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
- * @return input preset, for example AAUDIO_INPUT_PRESET_CAMCORDER
+ * @return input preset, for example {@link #AAUDIO_INPUT_PRESET_CAMCORDER}
  */
-AAUDIO_API aaudio_input_preset_t AAudioStream_getInputPreset(AAudioStream* stream);
+AAUDIO_API aaudio_input_preset_t AAudioStream_getInputPreset(AAudioStream* stream)
+        __INTRODUCED_IN(28);
+
+/**
+ * Return the policy that determines whether the audio may or may not be captured
+ * by other apps or the system.
+ *
+ * Added in API level 29.
+ *
+ * @param stream reference provided by AAudioStreamBuilder_openStream()
+ * @return the allowed capture policy, for example {@link #AAUDIO_ALLOW_CAPTURE_BY_ALL}
+ */
+AAUDIO_API aaudio_allowed_capture_policy_t AAudioStream_getAllowedCapturePolicy(
+        AAudioStream* stream) __INTRODUCED_IN(29);
 
 #ifdef __cplusplus
 }
diff --git a/media/libaaudio/libaaudio.map.txt b/media/libaaudio/libaaudio.map.txt
index cbf5921..a87ede3 100644
--- a/media/libaaudio/libaaudio.map.txt
+++ b/media/libaaudio/libaaudio.map.txt
@@ -20,6 +20,7 @@
     AAudioStreamBuilder_setUsage;       # introduced=28
     AAudioStreamBuilder_setContentType; # introduced=28
     AAudioStreamBuilder_setInputPreset; # introduced=28
+    AAudioStreamBuilder_setAllowedCapturePolicy; # introduced=29
     AAudioStreamBuilder_setSessionId;   # introduced=28
     AAudioStreamBuilder_openStream;
     AAudioStreamBuilder_delete;
@@ -49,6 +50,7 @@
     AAudioStream_getUsage;       # introduced=28
     AAudioStream_getContentType; # introduced=28
     AAudioStream_getInputPreset; # introduced=28
+    AAudioStream_getAllowedCapturePolicy; # introduced=29
     AAudioStream_getFramesWritten;
     AAudioStream_getFramesRead;
     AAudioStream_getSessionId;   # introduced=28
diff --git a/media/libaaudio/src/Android.bp b/media/libaaudio/src/Android.bp
index b9e28a0..4090286 100644
--- a/media/libaaudio/src/Android.bp
+++ b/media/libaaudio/src/Android.bp
@@ -6,6 +6,7 @@
         "client",
         "core",
         "fifo",
+        "flowgraph",
         "legacy",
         "utility",
     ],
@@ -25,9 +26,9 @@
         "utility/FixedBlockAdapter.cpp",
         "utility/FixedBlockReader.cpp",
         "utility/FixedBlockWriter.cpp",
-        "utility/LinearRamp.cpp",
         "fifo/FifoBuffer.cpp",
         "fifo/FifoControllerBase.cpp",
+        "client/AAudioFlowGraph.cpp",
         "client/AudioEndpoint.cpp",
         "client/AudioStreamInternal.cpp",
         "client/AudioStreamInternalCapture.cpp",
@@ -42,6 +43,16 @@
         "binding/RingBufferParcelable.cpp",
         "binding/SharedMemoryParcelable.cpp",
         "binding/SharedRegionParcelable.cpp",
+        "flowgraph/AudioProcessorBase.cpp",
+        "flowgraph/ClipToRange.cpp",
+        "flowgraph/MonoToMultiConverter.cpp",
+        "flowgraph/RampLinear.cpp",
+        "flowgraph/SinkFloat.cpp",
+        "flowgraph/SinkI16.cpp",
+        "flowgraph/SinkI24.cpp",
+        "flowgraph/SourceFloat.cpp",
+        "flowgraph/SourceI16.cpp",
+        "flowgraph/SourceI24.cpp",
     ],
 
     cflags: [
diff --git a/media/libaaudio/src/binding/AAudioBinderClient.cpp b/media/libaaudio/src/binding/AAudioBinderClient.cpp
index dd620e3..7b0d31f 100644
--- a/media/libaaudio/src/binding/AAudioBinderClient.cpp
+++ b/media/libaaudio/src/binding/AAudioBinderClient.cpp
@@ -97,8 +97,7 @@
                 status_t status = binder->linkToDeath(mAAudioClient);
                 // TODO review what we should do if this fails
                 if (status != NO_ERROR) {
-                    ALOGE("getAAudioService: linkToDeath(mAAudioClient = %p) returned %d",
-                          mAAudioClient.get(), status);
+                    ALOGE("%s() - linkToDeath() returned %d", __func__, status);
                 }
                 mAAudioService = interface_cast<IAAudioService>(binder);
                 needToRegister = true;
diff --git a/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp b/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
index 959db61..a987fab 100644
--- a/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
+++ b/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
@@ -14,6 +14,10 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "AAudioStreamConfiguration"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
 #include <stdint.h>
 
 #include <sys/mman.h>
@@ -36,6 +40,7 @@
 
 status_t AAudioStreamConfiguration::writeToParcel(Parcel* parcel) const {
     status_t status;
+
     status = parcel->writeInt32(getDeviceId());
     if (status != NO_ERROR) goto error;
     status = parcel->writeInt32(getSampleRate());
@@ -46,6 +51,7 @@
     if (status != NO_ERROR) goto error;
     status = parcel->writeInt32((int32_t) getFormat());
     if (status != NO_ERROR) goto error;
+
     status = parcel->writeInt32((int32_t) getDirection());
     if (status != NO_ERROR) goto error;
     status = parcel->writeInt32(getBufferCapacity());
@@ -56,11 +62,13 @@
     if (status != NO_ERROR) goto error;
     status = parcel->writeInt32((int32_t) getInputPreset());
     if (status != NO_ERROR) goto error;
+    status = parcel->writeInt32((int32_t) getAllowedCapturePolicy());
+    if (status != NO_ERROR) goto error;
     status = parcel->writeInt32(getSessionId());
     if (status != NO_ERROR) goto error;
     return NO_ERROR;
 error:
-    ALOGE("AAudioStreamConfiguration.writeToParcel(): write failed = %d", status);
+    ALOGE("%s(): write failed = %d", __func__, status);
     return status;
 }
 
@@ -80,7 +88,8 @@
     setSharingMode((aaudio_sharing_mode_t) value);
     status = parcel->readInt32(&value);
     if (status != NO_ERROR) goto error;
-    setFormat((aaudio_format_t) value);
+    setFormat((audio_format_t) value);
+
     status = parcel->readInt32(&value);
     if (status != NO_ERROR) goto error;
     setDirection((aaudio_direction_t) value);
@@ -98,9 +107,13 @@
     setInputPreset((aaudio_input_preset_t) value);
     status = parcel->readInt32(&value);
     if (status != NO_ERROR) goto error;
+    setAllowedCapturePolicy((aaudio_allowed_capture_policy_t) value);
+    status = parcel->readInt32(&value);
+    if (status != NO_ERROR) goto error;
     setSessionId(value);
+
     return NO_ERROR;
 error:
-    ALOGE("AAudioStreamConfiguration.readFromParcel(): read failed = %d", status);
+    ALOGE("%s(): read failed = %d", __func__, status);
     return status;
 }
diff --git a/media/libaaudio/src/binding/IAAudioService.cpp b/media/libaaudio/src/binding/IAAudioService.cpp
index 620edc7..97ad2b0 100644
--- a/media/libaaudio/src/binding/IAAudioService.cpp
+++ b/media/libaaudio/src/binding/IAAudioService.cpp
@@ -72,7 +72,6 @@
             ALOGE("BpAAudioService::client transact(OPEN_STREAM) readInt %d", err);
             return AAudioConvert_androidToAAudioResult(err);
         } else if (stream < 0) {
-            ALOGE("BpAAudioService::client OPEN_STREAM passed stream %d", stream);
             return stream;
         }
         err = configurationOutput.readFromParcel(&reply);
@@ -252,8 +251,15 @@
             CHECK_INTERFACE(IAAudioService, data, reply);
             sp<IAAudioClient> client = interface_cast<IAAudioClient>(
                     data.readStrongBinder());
-            registerClient(client);
-            return NO_ERROR;
+            // readStrongBinder() can return null
+            if (client.get() == nullptr) {
+                ALOGE("BnAAudioService::%s(REGISTER_CLIENT) client is NULL!", __func__);
+                android_errorWriteLog(0x534e4554, "116230453");
+                return DEAD_OBJECT;
+            } else {
+                registerClient(client);
+                return NO_ERROR;
+            }
         } break;
 
         case OPEN_STREAM: {
diff --git a/media/libaaudio/src/binding/SharedMemoryParcelable.cpp b/media/libaaudio/src/binding/SharedMemoryParcelable.cpp
index 0b0cf77..b6e8472 100644
--- a/media/libaaudio/src/binding/SharedMemoryParcelable.cpp
+++ b/media/libaaudio/src/binding/SharedMemoryParcelable.cpp
@@ -43,7 +43,7 @@
 
 void SharedMemoryParcelable::setup(const unique_fd& fd, int32_t sizeInBytes) {
     mFd.reset(dup(fd.get())); // store a duplicate fd
-    ALOGV("setup(%d -> %d, %d) this = %p\n", fd.get(), mFd.get(), sizeInBytes, this);
+    ALOGV("setup(fd = %d -> %d, size = %d) this = %p\n", fd.get(), mFd.get(), sizeInBytes, this);
     mSizeInBytes = sizeInBytes;
 }
 
@@ -104,7 +104,8 @@
     mResolvedAddress = (uint8_t *) mmap(0, mSizeInBytes, PROT_READ | PROT_WRITE,
                                         MAP_SHARED, fd.get(), 0);
     if (mResolvedAddress == MMAP_UNRESOLVED_ADDRESS) {
-        ALOGE("mmap() failed for fd = %d, errno = %s", fd.get(), strerror(errno));
+        ALOGE("mmap() failed for fd = %d, nBytes = %d, errno = %s",
+              fd.get(), mSizeInBytes, strerror(errno));
         return AAUDIO_ERROR_INTERNAL;
     }
     return AAUDIO_OK;
@@ -156,5 +157,4 @@
 void SharedMemoryParcelable::dump() {
     ALOGD("mFd = %d", mFd.get());
     ALOGD("mSizeInBytes = %d", mSizeInBytes);
-    ALOGD("mResolvedAddress = %p", mResolvedAddress);
 }
diff --git a/media/libaaudio/src/binding/SharedMemoryParcelable.h b/media/libaaudio/src/binding/SharedMemoryParcelable.h
index 82c2240..4ec38c5 100644
--- a/media/libaaudio/src/binding/SharedMemoryParcelable.h
+++ b/media/libaaudio/src/binding/SharedMemoryParcelable.h
@@ -70,8 +70,8 @@
     aaudio_result_t resolveSharedMemory(const android::base::unique_fd& fd);
 
     android::base::unique_fd   mFd;
-    int32_t     mSizeInBytes = 0;
-    uint8_t    *mResolvedAddress = MMAP_UNRESOLVED_ADDRESS;
+    int32_t                    mSizeInBytes = 0;
+    uint8_t                   *mResolvedAddress = MMAP_UNRESOLVED_ADDRESS;
 
 private:
 
diff --git a/media/libaaudio/src/client/AAudioFlowGraph.cpp b/media/libaaudio/src/client/AAudioFlowGraph.cpp
new file mode 100644
index 0000000..8f2c488
--- /dev/null
+++ b/media/libaaudio/src/client/AAudioFlowGraph.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AAudioFlowGraph"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+#include "AAudioFlowGraph.h"
+
+#include <flowgraph/ClipToRange.h>
+#include <flowgraph/MonoToMultiConverter.h>
+#include <flowgraph/RampLinear.h>
+#include <flowgraph/SinkFloat.h>
+#include <flowgraph/SinkI16.h>
+#include <flowgraph/SinkI24.h>
+#include <flowgraph/SourceFloat.h>
+#include <flowgraph/SourceI16.h>
+#include <flowgraph/SourceI24.h>
+
+using namespace flowgraph;
+
+aaudio_result_t AAudioFlowGraph::configure(audio_format_t sourceFormat,
+                          int32_t sourceChannelCount,
+                          audio_format_t sinkFormat,
+                          int32_t sinkChannelCount) {
+    AudioFloatOutputPort *lastOutput = nullptr;
+
+    ALOGV("%s() source format = 0x%08x, channels = %d, sink format = 0x%08x, channels = %d",
+          __func__, sourceFormat, sourceChannelCount, sinkFormat, sinkChannelCount);
+
+    switch (sourceFormat) {
+        case AUDIO_FORMAT_PCM_FLOAT:
+            mSource = std::make_unique<SourceFloat>(sourceChannelCount);
+            break;
+        case AUDIO_FORMAT_PCM_16_BIT:
+            mSource = std::make_unique<SourceI16>(sourceChannelCount);
+            break;
+        case AUDIO_FORMAT_PCM_24_BIT_PACKED:
+            mSource = std::make_unique<SourceI24>(sourceChannelCount);
+            break;
+        default: // TODO add I32
+            ALOGE("%s() Unsupported source format = %d", __func__, sourceFormat);
+            return AAUDIO_ERROR_UNIMPLEMENTED;
+    }
+    lastOutput = &mSource->output;
+
+    // Apply volume as a ramp to avoid pops.
+    mVolumeRamp = std::make_unique<RampLinear>(sourceChannelCount);
+    lastOutput->connect(&mVolumeRamp->input);
+    lastOutput = &mVolumeRamp->output;
+
+    // For a pure float graph, there is chance that the data range may be very large.
+    // So we should clip to a reasonable value that allows a little headroom.
+    if (sourceFormat == AUDIO_FORMAT_PCM_FLOAT && sinkFormat == AUDIO_FORMAT_PCM_FLOAT) {
+        mClipper = std::make_unique<ClipToRange>(sourceChannelCount);
+        lastOutput->connect(&mClipper->input);
+        lastOutput = &mClipper->output;
+    }
+
+    // Expand the number of channels if required.
+    if (sourceChannelCount == 1 && sinkChannelCount > 1) {
+        mChannelConverter = std::make_unique<MonoToMultiConverter>(sinkChannelCount);
+        lastOutput->connect(&mChannelConverter->input);
+        lastOutput = &mChannelConverter->output;
+    } else if (sourceChannelCount != sinkChannelCount) {
+        ALOGE("%s() Channel reduction not supported.", __func__);
+        return AAUDIO_ERROR_UNIMPLEMENTED;
+    }
+
+    switch (sinkFormat) {
+        case AUDIO_FORMAT_PCM_FLOAT:
+            mSink = std::make_unique<SinkFloat>(sinkChannelCount);
+            break;
+        case AUDIO_FORMAT_PCM_16_BIT:
+            mSink = std::make_unique<SinkI16>(sinkChannelCount);
+            break;
+        case AUDIO_FORMAT_PCM_24_BIT_PACKED:
+            mSink = std::make_unique<SinkI24>(sinkChannelCount);
+            break;
+        default: // TODO add I32
+            ALOGE("%s() Unsupported sink format = %d", __func__, sinkFormat);
+            return AAUDIO_ERROR_UNIMPLEMENTED;
+    }
+    lastOutput->connect(&mSink->input);
+
+    return AAUDIO_OK;
+}
+
+void AAudioFlowGraph::process(const void *source, void *destination, int32_t numFrames) {
+    mSource->setData(source, numFrames);
+    mSink->read(destination, numFrames);
+}
+
+/**
+ * @param volume between 0.0 and 1.0
+ */
+void AAudioFlowGraph::setTargetVolume(float volume) {
+    mVolumeRamp->setTarget(volume);
+}
+
+void AAudioFlowGraph::setRampLengthInFrames(int32_t numFrames) {
+    mVolumeRamp->setLengthInFrames(numFrames);
+}
diff --git a/media/libaaudio/src/client/AAudioFlowGraph.h b/media/libaaudio/src/client/AAudioFlowGraph.h
new file mode 100644
index 0000000..a49f64e
--- /dev/null
+++ b/media/libaaudio/src/client/AAudioFlowGraph.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_AAUDIO_FLOW_GRAPH_H
+#define ANDROID_AAUDIO_FLOW_GRAPH_H
+
+#include <memory>
+#include <stdint.h>
+#include <sys/types.h>
+#include <system/audio.h>
+
+#include <aaudio/AAudio.h>
+#include <flowgraph/ClipToRange.h>
+#include <flowgraph/MonoToMultiConverter.h>
+#include <flowgraph/RampLinear.h>
+
+class AAudioFlowGraph {
+public:
+    /** Connect several modules together to convert from source to sink.
+     * This should only be called once for each instance.
+     *
+     * @param sourceFormat
+     * @param sourceChannelCount
+     * @param sinkFormat
+     * @param sinkChannelCount
+     * @return
+     */
+    aaudio_result_t configure(audio_format_t sourceFormat,
+                              int32_t sourceChannelCount,
+                              audio_format_t sinkFormat,
+                              int32_t sinkChannelCount);
+
+    void process(const void *source, void *destination, int32_t numFrames);
+
+    /**
+     * @param volume between 0.0 and 1.0
+     */
+    void setTargetVolume(float volume);
+
+    void setRampLengthInFrames(int32_t numFrames);
+
+private:
+    std::unique_ptr<flowgraph::AudioSource>          mSource;
+    std::unique_ptr<flowgraph::RampLinear>           mVolumeRamp;
+    std::unique_ptr<flowgraph::ClipToRange>          mClipper;
+    std::unique_ptr<flowgraph::MonoToMultiConverter> mChannelConverter;
+    std::unique_ptr<flowgraph::AudioSink>            mSink;
+};
+
+
+#endif //ANDROID_AAUDIO_FLOW_GRAPH_H
diff --git a/media/libaaudio/src/client/AudioEndpoint.cpp b/media/libaaudio/src/client/AudioEndpoint.cpp
index f8e34d1..214f888 100644
--- a/media/libaaudio/src/client/AudioEndpoint.cpp
+++ b/media/libaaudio/src/client/AudioEndpoint.cpp
@@ -196,7 +196,7 @@
 
 int32_t AudioEndpoint::getEmptyFramesAvailable()
 {
-    return mDataQueue->getFifoControllerBase()->getEmptyFramesAvailable();
+    return mDataQueue->getEmptyFramesAvailable();
 }
 
 int32_t AudioEndpoint::getFullFramesAvailable(WrappingBuffer *wrappingBuffer)
@@ -206,15 +206,15 @@
 
 int32_t AudioEndpoint::getFullFramesAvailable()
 {
-    return mDataQueue->getFifoControllerBase()->getFullFramesAvailable();
+    return mDataQueue->getFullFramesAvailable();
 }
 
 void AudioEndpoint::advanceWriteIndex(int32_t deltaFrames) {
-    mDataQueue->getFifoControllerBase()->advanceWriteIndex(deltaFrames);
+    mDataQueue->advanceWriteIndex(deltaFrames);
 }
 
 void AudioEndpoint::advanceReadIndex(int32_t deltaFrames) {
-    mDataQueue->getFifoControllerBase()->advanceReadIndex(deltaFrames);
+    mDataQueue->advanceReadIndex(deltaFrames);
 }
 
 void AudioEndpoint::setDataReadCounter(fifo_counter_t framesRead)
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index 9204824..52eadd4 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -39,7 +39,6 @@
 #include "core/AudioStreamBuilder.h"
 #include "fifo/FifoBuffer.h"
 #include "utility/AudioClock.h"
-#include "utility/LinearRamp.h"
 
 #include "AudioStreamInternal.h"
 
@@ -63,7 +62,7 @@
         , mServiceStreamHandle(AAUDIO_HANDLE_INVALID)
         , mInService(inService)
         , mServiceInterface(serviceInterface)
-        , mAtomicTimestamp()
+        , mAtomicInternalTimestamp()
         , mWakeupDelayNanos(AAudioProperty_getWakeupDelayMicros() * AAUDIO_NANOS_PER_MICROSECOND)
         , mMinimumSleepNanos(AAudioProperty_getMinimumSleepMicros() * AAUDIO_NANOS_PER_MICROSECOND)
         {
@@ -77,6 +76,7 @@
     aaudio_result_t result = AAUDIO_OK;
     int32_t capacity;
     int32_t framesPerBurst;
+    int32_t framesPerHardwareBurst;
     AAudioStreamRequest request;
     AAudioStreamConfiguration configurationOutput;
 
@@ -91,12 +91,15 @@
         return result;
     }
 
+    const int32_t burstMinMicros = AAudioProperty_getHardwareBurstMinMicros();
+    int32_t burstMicros = 0;
+
     // We have to do volume scaling. So we prefer FLOAT format.
-    if (getFormat() == AAUDIO_FORMAT_UNSPECIFIED) {
-        setFormat(AAUDIO_FORMAT_PCM_FLOAT);
+    if (getFormat() == AUDIO_FORMAT_DEFAULT) {
+        setFormat(AUDIO_FORMAT_PCM_FLOAT);
     }
     // Request FLOAT for the shared mixer.
-    request.getConfiguration().setFormat(AAUDIO_FORMAT_PCM_FLOAT);
+    request.getConfiguration().setFormat(AUDIO_FORMAT_PCM_FLOAT);
 
     // Build the request to send to the server.
     request.setUserId(getuid());
@@ -126,13 +129,12 @@
         // if that failed then try switching from mono to stereo if OUTPUT.
         // Only do this in the client. Otherwise we end up with a mono mixer in the service
         // that writes to a stereo MMAP stream.
-        ALOGD("%s - openStream() returned %d, try switching from MONO to STEREO",
+        ALOGD("%s() - openStream() returned %d, try switching from MONO to STEREO",
               __func__, mServiceStreamHandle);
         request.getConfiguration().setSamplesPerFrame(2); // stereo
         mServiceStreamHandle = mServiceInterface.openStream(request, configurationOutput);
     }
     if (mServiceStreamHandle < 0) {
-        ALOGE("%s - openStream() returned %d", __func__, mServiceStreamHandle);
         return mServiceStreamHandle;
     }
 
@@ -175,8 +177,22 @@
         goto error;
     }
 
-    // Validate result from server.
-    framesPerBurst = mEndpointDescriptor.dataQueueDescriptor.framesPerBurst;
+    framesPerHardwareBurst = mEndpointDescriptor.dataQueueDescriptor.framesPerBurst;
+
+    // Scale up the burst size to meet the minimum equivalent in microseconds.
+    // This is to avoid waking the CPU too often when the HW burst is very small
+    // or at high sample rates.
+    framesPerBurst = framesPerHardwareBurst;
+    do {
+        if (burstMicros > 0) {  // skip first loop
+            framesPerBurst *= 2;
+        }
+        burstMicros = framesPerBurst * static_cast<int64_t>(1000000) / getSampleRate();
+    } while (burstMicros < burstMinMicros);
+    ALOGD("%s() original HW burst = %d, minMicros = %d => SW burst = %d\n",
+          __func__, framesPerHardwareBurst, burstMinMicros, framesPerBurst);
+
+    // Validate final burst size.
     if (framesPerBurst < MIN_FRAMES_PER_BURST || framesPerBurst > MAX_FRAMES_PER_BURST) {
         ALOGE("%s - framesPerBurst out of range = %d", __func__, framesPerBurst);
         result = AAUDIO_ERROR_OUT_OF_RANGE;
@@ -192,18 +208,18 @@
     }
 
     mClockModel.setSampleRate(getSampleRate());
-    mClockModel.setFramesPerBurst(mFramesPerBurst);
+    mClockModel.setFramesPerBurst(framesPerHardwareBurst);
 
     if (isDataCallbackSet()) {
         mCallbackFrames = builder.getFramesPerDataCallback();
         if (mCallbackFrames > getBufferCapacity() / 2) {
-            ALOGE("%s - framesPerCallback too big = %d, capacity = %d",
+            ALOGW("%s - framesPerCallback too big = %d, capacity = %d",
                   __func__, mCallbackFrames, getBufferCapacity());
             result = AAUDIO_ERROR_OUT_OF_RANGE;
             goto error;
 
         } else if (mCallbackFrames < 0) {
-            ALOGE("%s - framesPerCallback negative", __func__);
+            ALOGW("%s - framesPerCallback negative", __func__);
             result = AAUDIO_ERROR_OUT_OF_RANGE;
             goto error;
 
@@ -212,9 +228,7 @@
             mCallbackFrames = mFramesPerBurst;
         }
 
-        int32_t bytesPerFrame = getSamplesPerFrame()
-                                * AAudioConvert_formatToSizeInBytes(getFormat());
-        int32_t callbackBufferSize = mCallbackFrames * bytesPerFrame;
+        const int32_t callbackBufferSize = mCallbackFrames * getBytesPerFrame();
         mCallbackBuffer = new uint8_t[callbackBufferSize];
     }
 
@@ -227,22 +241,18 @@
     return result;
 }
 
+// This must be called under mStreamLock.
 aaudio_result_t AudioStreamInternal::close() {
     aaudio_result_t result = AAUDIO_OK;
-    ALOGD("%s(): mServiceStreamHandle = 0x%08X", __func__, mServiceStreamHandle);
+    ALOGV("%s(): mServiceStreamHandle = 0x%08X", __func__, mServiceStreamHandle);
     if (mServiceStreamHandle != AAUDIO_HANDLE_INVALID) {
         // Don't close a stream while it is running.
         aaudio_stream_state_t currentState = getState();
-        if (isActive()) {
+        // Don't close a stream while it is running. Stop it first.
+        // If DISCONNECTED then we should still try to stop in case the
+        // error callback is still running.
+        if (isActive() || currentState == AAUDIO_STREAM_STATE_DISCONNECTED) {
             requestStop();
-            aaudio_stream_state_t nextState;
-            int64_t timeoutNanoseconds = MIN_TIMEOUT_NANOS;
-            result = waitForStateChange(currentState, &nextState,
-                                                       timeoutNanoseconds);
-            if (result != AAUDIO_OK) {
-                ALOGE("%s() waitForStateChange() returned %d %s",
-                __func__, result, AAudio_convertResultToText(result));
-            }
         }
         setState(AAUDIO_STREAM_STATE_CLOSING);
         aaudio_handle_t serviceStreamHandle = mServiceStreamHandle;
@@ -287,17 +297,17 @@
 {
     int64_t startTime;
     if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
-        ALOGE("requestStart() mServiceStreamHandle invalid");
+        ALOGD("requestStart() mServiceStreamHandle invalid");
         return AAUDIO_ERROR_INVALID_STATE;
     }
     if (isActive()) {
-        ALOGE("requestStart() already active");
+        ALOGD("requestStart() already active");
         return AAUDIO_ERROR_INVALID_STATE;
     }
 
     aaudio_stream_state_t originalState = getState();
     if (originalState == AAUDIO_STREAM_STATE_DISCONNECTED) {
-        ALOGE("requestStart() but DISCONNECTED");
+        ALOGD("requestStart() but DISCONNECTED");
         return AAUDIO_ERROR_DISCONNECTED;
     }
     setState(AAUDIO_STREAM_STATE_STARTING);
@@ -343,39 +353,48 @@
     return calculateReasonableTimeout(getFramesPerBurst());
 }
 
+// This must be called under mStreamLock.
 aaudio_result_t AudioStreamInternal::stopCallback()
 {
-    if (isDataCallbackActive()) {
+    if (isDataCallbackSet()
+            && (isActive() || getState() == AAUDIO_STREAM_STATE_DISCONNECTED)) {
         mCallbackEnabled.store(false);
-        return joinThread(NULL);
+        return joinThread(NULL); // may temporarily unlock mStreamLock
     } else {
         return AAUDIO_OK;
     }
 }
 
-aaudio_result_t AudioStreamInternal::requestStop()
-{
+// This must be called under mStreamLock.
+aaudio_result_t AudioStreamInternal::requestStop() {
     aaudio_result_t result = stopCallback();
     if (result != AAUDIO_OK) {
         return result;
     }
+    // The stream may have been unlocked temporarily to let a callback finish
+    // and the callback may have stopped the stream.
+    // Check to make sure the stream still needs to be stopped.
+    // See also AudioStream::safeStop().
+    if (!(isActive() || getState() == AAUDIO_STREAM_STATE_DISCONNECTED)) {
+        return AAUDIO_OK;
+    }
 
     if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
-        ALOGE("requestStopInternal() mServiceStreamHandle invalid = 0x%08X",
-              mServiceStreamHandle);
+        ALOGW("%s() mServiceStreamHandle invalid = 0x%08X",
+              __func__, mServiceStreamHandle);
         return AAUDIO_ERROR_INVALID_STATE;
     }
 
     mClockModel.stop(AudioClock::getNanoseconds());
     setState(AAUDIO_STREAM_STATE_STOPPING);
-    mAtomicTimestamp.clear();
+    mAtomicInternalTimestamp.clear();
 
     return mServiceInterface.stopStream(mServiceStreamHandle);
 }
 
 aaudio_result_t AudioStreamInternal::registerThread() {
     if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
-        ALOGE("registerThread() mServiceStreamHandle invalid");
+        ALOGW("%s() mServiceStreamHandle invalid", __func__);
         return AAUDIO_ERROR_INVALID_STATE;
     }
     return mServiceInterface.registerAudioThread(mServiceStreamHandle,
@@ -385,7 +404,7 @@
 
 aaudio_result_t AudioStreamInternal::unregisterThread() {
     if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
-        ALOGE("unregisterThread() mServiceStreamHandle invalid");
+        ALOGW("%s() mServiceStreamHandle invalid", __func__);
         return AAUDIO_ERROR_INVALID_STATE;
     }
     return mServiceInterface.unregisterAudioThread(mServiceStreamHandle, gettid());
@@ -417,8 +436,8 @@
                            int64_t *framePosition,
                            int64_t *timeNanoseconds) {
     // Generated in server and passed to client. Return latest.
-    if (mAtomicTimestamp.isValid()) {
-        Timestamp timestamp = mAtomicTimestamp.read();
+    if (mAtomicInternalTimestamp.isValid()) {
+        Timestamp timestamp = mAtomicInternalTimestamp.read();
         int64_t position = timestamp.getPosition() + mFramesOffsetFromService;
         if (position >= 0) {
             *framePosition = position;
@@ -465,7 +484,7 @@
 
 aaudio_result_t AudioStreamInternal::onTimestampHardware(AAudioServiceMessage *message) {
     Timestamp timestamp(message->timestamp.position, message->timestamp.timestamp);
-    mAtomicTimestamp.write(timestamp);
+    mAtomicInternalTimestamp.write(timestamp);
     return AAUDIO_OK;
 }
 
@@ -696,7 +715,6 @@
     }
 
     aaudio_result_t result = mAudioEndpoint.setBufferSizeInFrames(adjustedFrames, &actualFrames);
-    ALOGD("setBufferSize() req = %d => %d", requestedFrames, actualFrames);
     if (result < 0) {
         return result;
     } else {
@@ -716,6 +734,11 @@
     return mFramesPerBurst;
 }
 
+// This must be called under mStreamLock.
 aaudio_result_t AudioStreamInternal::joinThread(void** returnArg) {
     return AudioStream::joinThread(returnArg, calculateReasonableTimeout(getFramesPerBurst()));
 }
+
+bool AudioStreamInternal::isClockModelInControl() const {
+    return isActive() && mAudioEndpoint.isFreeRunning() && mClockModel.isRunning();
+}
diff --git a/media/libaaudio/src/client/AudioStreamInternal.h b/media/libaaudio/src/client/AudioStreamInternal.h
index 0425cd5..86c4698 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.h
+++ b/media/libaaudio/src/client/AudioStreamInternal.h
@@ -27,7 +27,6 @@
 #include "client/AudioEndpoint.h"
 #include "core/AudioStream.h"
 #include "utility/AudioClock.h"
-#include "utility/LinearRamp.h"
 
 using android::sp;
 using android::IAAudioService;
@@ -145,6 +144,14 @@
      */
     bool isInService() const { return mInService; }
 
+    /**
+     * Is the service FIFO position currently controlled by the AAudio service or HAL,
+     * or set based on the Clock Model.
+     *
+     * @return true if the ClockModel is currently determining the FIFO position
+     */
+    bool isClockModelInControl() const;
+
     IsochronousClockModel    mClockModel;      // timing model for chasing the HAL
 
     AudioEndpoint            mAudioEndpoint;   // source for reads or sink for writes
@@ -164,7 +171,7 @@
 
     AAudioServiceInterface  &mServiceInterface;   // abstract interface to the service
 
-    SimpleDoubleBuffer<Timestamp>  mAtomicTimestamp;
+    SimpleDoubleBuffer<Timestamp>  mAtomicInternalTimestamp;
 
     AtomicRequestor          mNeedCatchUp;   // Ask read() or write() to sync on first timestamp.
 
@@ -193,6 +200,8 @@
 
     int64_t                  mServiceLatencyNanos = 0;
 
+    // Sometimes the hardware is operating with a different channel count from the app.
+    // Then we require conversion in AAudio.
     int32_t                  mDeviceChannelCount = 0;
 };
 
diff --git a/media/libaaudio/src/client/AudioStreamInternalCapture.cpp b/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
index 0719fe1..a6cc45b 100644
--- a/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
@@ -20,6 +20,7 @@
 #include <utils/Log.h>
 
 #include <algorithm>
+#include <audio_utils/primitives.h>
 #include <aaudio/AAudio.h>
 
 #include "client/AudioStreamInternalCapture.h"
@@ -165,35 +166,36 @@
     // Read data in one or two parts.
     for (int partIndex = 0; framesLeft > 0 && partIndex < WrappingBuffer::SIZE; partIndex++) {
         int32_t framesToProcess = framesLeft;
-        int32_t framesAvailable = wrappingBuffer.numFrames[partIndex];
+        const int32_t framesAvailable = wrappingBuffer.numFrames[partIndex];
         if (framesAvailable <= 0) break;
 
         if (framesToProcess > framesAvailable) {
             framesToProcess = framesAvailable;
         }
 
-        int32_t numBytes = getBytesPerFrame() * framesToProcess;
-        int32_t numSamples = framesToProcess * getSamplesPerFrame();
+        const int32_t numBytes = getBytesPerFrame() * framesToProcess;
+        const int32_t numSamples = framesToProcess * getSamplesPerFrame();
 
+        const audio_format_t sourceFormat = getDeviceFormat();
+        const audio_format_t destinationFormat = getFormat();
         // TODO factor this out into a utility function
-        if (getDeviceFormat() == getFormat()) {
+        if (sourceFormat == destinationFormat) {
             memcpy(destination, wrappingBuffer.data[partIndex], numBytes);
-        } else if (getDeviceFormat() == AAUDIO_FORMAT_PCM_I16
-                   && getFormat() == AAUDIO_FORMAT_PCM_FLOAT) {
-            AAudioConvert_pcm16ToFloat(
-                    (const int16_t *) wrappingBuffer.data[partIndex],
+        } else if (sourceFormat == AUDIO_FORMAT_PCM_16_BIT
+                   && destinationFormat == AUDIO_FORMAT_PCM_FLOAT) {
+            memcpy_to_float_from_i16(
                     (float *) destination,
-                    numSamples,
-                    1.0f);
-        } else if (getDeviceFormat() == AAUDIO_FORMAT_PCM_FLOAT
-                   && getFormat() == AAUDIO_FORMAT_PCM_I16) {
-            AAudioConvert_floatToPcm16(
-                    (const float *) wrappingBuffer.data[partIndex],
+                    (const int16_t *) wrappingBuffer.data[partIndex],
+                    numSamples);
+        } else if (sourceFormat == AUDIO_FORMAT_PCM_FLOAT
+                   && destinationFormat == AUDIO_FORMAT_PCM_16_BIT) {
+            memcpy_to_i16_from_float(
                     (int16_t *) destination,
-                    numSamples,
-                    1.0f);
+                    (const float *) wrappingBuffer.data[partIndex],
+                    numSamples);
         } else {
-            ALOGE("Format conversion not supported!");
+            ALOGE("%s() - Format conversion not supported! audio_format_t source = %u, dest = %u",
+                __func__, sourceFormat, destinationFormat);
             return AAUDIO_ERROR_INVALID_FORMAT;
         }
         destination += numBytes;
@@ -208,17 +210,12 @@
 }
 
 int64_t AudioStreamInternalCapture::getFramesWritten() {
-    int64_t framesWrittenHardware;
-    if (isActive()) {
-        framesWrittenHardware = mClockModel.convertTimeToPosition(AudioClock::getNanoseconds());
-    } else {
-        framesWrittenHardware = mAudioEndpoint.getDataWriteCounter();
-    }
-    // Prevent retrograde motion.
+    const int64_t framesWrittenHardware = isClockModelInControl()
+            ? mClockModel.convertTimeToPosition(AudioClock::getNanoseconds())
+            : mAudioEndpoint.getDataWriteCounter();
+    // Add service offset and prevent retrograde motion.
     mLastFramesWritten = std::max(mLastFramesWritten,
                                   framesWrittenHardware + mFramesOffsetFromService);
-    //ALOGD("getFramesWritten() returns %lld",
-    //      (long long)mLastFramesWritten);
     return mLastFramesWritten;
 }
 
@@ -256,7 +253,8 @@
         callbackResult = maybeCallDataCallback(mCallbackBuffer, mCallbackFrames);
 
         if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
-            ALOGD("callback returned AAUDIO_CALLBACK_RESULT_STOP");
+            ALOGD("%s(): callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
+            result = systemStopFromCallback();
             break;
         }
     }
diff --git a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
index 795ba2c..b8ef247 100644
--- a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
@@ -43,13 +43,22 @@
 aaudio_result_t AudioStreamInternalPlay::open(const AudioStreamBuilder &builder) {
     aaudio_result_t result = AudioStreamInternal::open(builder);
     if (result == AAUDIO_OK) {
+        result = mFlowGraph.configure(getFormat(),
+                             getSamplesPerFrame(),
+                             getDeviceFormat(),
+                             getDeviceChannelCount());
+
+        if (result != AAUDIO_OK) {
+            close();
+        }
         // Sample rate is constrained to common values by now and should not overflow.
         int32_t numFrames = kRampMSec * getSampleRate() / AAUDIO_MILLIS_PER_SECOND;
-        mVolumeRamp.setLengthInFrames(numFrames);
+        mFlowGraph.setRampLengthInFrames(numFrames);
     }
     return result;
 }
 
+// This must be called under mStreamLock.
 aaudio_result_t AudioStreamInternalPlay::requestPause()
 {
     aaudio_result_t result = stopCallback();
@@ -57,19 +66,19 @@
         return result;
     }
     if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
-        ALOGE("%s() mServiceStreamHandle invalid", __func__);
+        ALOGW("%s() mServiceStreamHandle invalid", __func__);
         return AAUDIO_ERROR_INVALID_STATE;
     }
 
     mClockModel.stop(AudioClock::getNanoseconds());
     setState(AAUDIO_STREAM_STATE_PAUSING);
-    mAtomicTimestamp.clear();
+    mAtomicInternalTimestamp.clear();
     return mServiceInterface.pauseStream(mServiceStreamHandle);
 }
 
 aaudio_result_t AudioStreamInternalPlay::requestFlush() {
     if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
-        ALOGE("%s() mServiceStreamHandle invalid", __func__);
+        ALOGW("%s() mServiceStreamHandle invalid", __func__);
         return AAUDIO_ERROR_INVALID_STATE;
     }
 
@@ -216,22 +225,10 @@
             }
 
             int32_t numBytes = getBytesPerFrame() * framesToWrite;
-            // Data conversion.
-            float levelFrom;
-            float levelTo;
-            mVolumeRamp.nextSegment(framesToWrite, &levelFrom, &levelTo);
 
-            AAudioDataConverter::FormattedData source(
-                    (void *)byteBuffer,
-                    getFormat(),
-                    getSamplesPerFrame());
-            AAudioDataConverter::FormattedData destination(
-                    wrappingBuffer.data[partIndex],
-                    getDeviceFormat(),
-                    getDeviceChannelCount());
-
-            AAudioDataConverter::convert(source, destination, framesToWrite,
-                                         levelFrom, levelTo);
+            mFlowGraph.process((void *)byteBuffer,
+                               wrappingBuffer.data[partIndex],
+                               framesToWrite);
 
             byteBuffer += numBytes;
             framesLeft -= framesToWrite;
@@ -246,27 +243,17 @@
     return framesWritten;
 }
 
-int64_t AudioStreamInternalPlay::getFramesRead()
-{
-    int64_t framesReadHardware;
-    if (isActive()) {
-        framesReadHardware = mClockModel.convertTimeToPosition(AudioClock::getNanoseconds());
-    } else {
-        framesReadHardware = mAudioEndpoint.getDataReadCounter();
-    }
-    int64_t framesRead = framesReadHardware + mFramesOffsetFromService;
-    // Prevent retrograde motion.
-    if (framesRead < mLastFramesRead) {
-        framesRead = mLastFramesRead;
-    } else {
-        mLastFramesRead = framesRead;
-    }
-    return framesRead;
+int64_t AudioStreamInternalPlay::getFramesRead() {
+    const int64_t framesReadHardware = isClockModelInControl()
+            ? mClockModel.convertTimeToPosition(AudioClock::getNanoseconds())
+            : mAudioEndpoint.getDataReadCounter();
+    // Add service offset and prevent retrograde motion.
+    mLastFramesRead = std::max(mLastFramesRead, framesReadHardware + mFramesOffsetFromService);
+    return mLastFramesRead;
 }
 
-int64_t AudioStreamInternalPlay::getFramesWritten()
-{
-    int64_t framesWritten = mAudioEndpoint.getDataWriteCounter()
+int64_t AudioStreamInternalPlay::getFramesWritten() {
+    const int64_t framesWritten = mAudioEndpoint.getDataWriteCounter()
                                + mFramesOffsetFromService;
     return framesWritten;
 }
@@ -297,7 +284,8 @@
                 break;
             }
         } else if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
-            ALOGV("%s(): callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
+            ALOGD("%s(): callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
+            result = systemStopFromCallback();
             break;
         }
     }
@@ -313,6 +301,6 @@
     float combinedVolume = mStreamVolume * getDuckAndMuteVolume();
     ALOGD("%s() mStreamVolume * duckAndMuteVolume = %f * %f = %f",
           __func__, mStreamVolume, getDuckAndMuteVolume(), combinedVolume);
-    mVolumeRamp.setTarget(combinedVolume);
+    mFlowGraph.setTargetVolume(combinedVolume);
     return android::NO_ERROR;
 }
diff --git a/media/libaaudio/src/client/AudioStreamInternalPlay.h b/media/libaaudio/src/client/AudioStreamInternalPlay.h
index 977a909..cab2942 100644
--- a/media/libaaudio/src/client/AudioStreamInternalPlay.h
+++ b/media/libaaudio/src/client/AudioStreamInternalPlay.h
@@ -21,6 +21,7 @@
 #include <aaudio/AAudio.h>
 
 #include "binding/AAudioServiceInterface.h"
+#include "client/AAudioFlowGraph.h"
 #include "client/AudioStreamInternal.h"
 
 using android::sp;
@@ -93,7 +94,7 @@
 
     int64_t                  mLastFramesRead = 0; // used to prevent retrograde motion
 
-    LinearRamp               mVolumeRamp;
+    AAudioFlowGraph          mFlowGraph;
 
 };
 
diff --git a/media/libaaudio/src/client/IsochronousClockModel.cpp b/media/libaaudio/src/client/IsochronousClockModel.cpp
index 95b52be..747d0e1 100644
--- a/media/libaaudio/src/client/IsochronousClockModel.cpp
+++ b/media/libaaudio/src/client/IsochronousClockModel.cpp
@@ -60,10 +60,14 @@
     mState = STATE_STOPPED;
 }
 
-bool IsochronousClockModel::isStarting() {
+bool IsochronousClockModel::isStarting() const {
     return mState == STATE_STARTING;
 }
 
+bool IsochronousClockModel::isRunning() const {
+    return mState == STATE_RUNNING;
+}
+
 void IsochronousClockModel::processTimestamp(int64_t framePosition, int64_t nanoTime) {
 //    ALOGD("processTimestamp() - framePosition = %lld at nanoTime %llu",
 //         (long long)framePosition,
diff --git a/media/libaaudio/src/client/IsochronousClockModel.h b/media/libaaudio/src/client/IsochronousClockModel.h
index 7182376..46ca48e 100644
--- a/media/libaaudio/src/client/IsochronousClockModel.h
+++ b/media/libaaudio/src/client/IsochronousClockModel.h
@@ -36,7 +36,15 @@
     void start(int64_t nanoTime);
     void stop(int64_t nanoTime);
 
-    bool isStarting();
+    /**
+     * @return true if the model is starting up
+     */
+    bool isStarting() const;
+
+    /**
+     * @return true if the model is running and producing valid results
+     */
+    bool isRunning() const;
 
     void processTimestamp(int64_t framePosition, int64_t nanoTime);
 
diff --git a/media/libaaudio/src/core/AAudioAudio.cpp b/media/libaaudio/src/core/AAudioAudio.cpp
index df0db79..44d5122 100644
--- a/media/libaaudio/src/core/AAudioAudio.cpp
+++ b/media/libaaudio/src/core/AAudioAudio.cpp
@@ -146,14 +146,14 @@
 AAUDIO_API void AAudioStreamBuilder_setChannelCount(AAudioStreamBuilder* builder,
                                                     int32_t channelCount)
 {
-    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
-    streamBuilder->setSamplesPerFrame(channelCount);
+    AAudioStreamBuilder_setSamplesPerFrame(builder, channelCount);
 }
 
 AAUDIO_API void AAudioStreamBuilder_setSamplesPerFrame(AAudioStreamBuilder* builder,
-                                                       int32_t channelCount)
+                                                       int32_t samplesPerFrame)
 {
-    AAudioStreamBuilder_setChannelCount(builder, channelCount);
+    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
+    streamBuilder->setSamplesPerFrame(samplesPerFrame);
 }
 
 AAUDIO_API void AAudioStreamBuilder_setDirection(AAudioStreamBuilder* builder,
@@ -167,7 +167,9 @@
                                                    aaudio_format_t format)
 {
     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
-    streamBuilder->setFormat(format);
+    // Use audio_format_t everywhere internally.
+    const audio_format_t internalFormat = AAudioConvert_aaudioToAndroidDataFormat(format);
+    streamBuilder->setFormat(internalFormat);
 }
 
 AAUDIO_API void AAudioStreamBuilder_setSharingMode(AAudioStreamBuilder* builder,
@@ -202,6 +204,12 @@
     streamBuilder->setBufferCapacity(frames);
 }
 
+AAUDIO_API void AAudioStreamBuilder_setAllowedCapturePolicy(
+        AAudioStreamBuilder* builder, aaudio_allowed_capture_policy_t policy) {
+    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
+    streamBuilder->setAllowedCapturePolicy(policy);
+}
+
 AAUDIO_API void AAudioStreamBuilder_setSessionId(AAudioStreamBuilder* builder,
                                                  aaudio_session_id_t sessionId)
 {
@@ -238,18 +246,20 @@
                                                      AAudioStream** streamPtr)
 {
     AudioStream *audioStream = nullptr;
+    aaudio_stream_id_t id = 0;
     // Please leave these logs because they are very helpful when debugging.
-    ALOGD("AAudioStreamBuilder_openStream() called ----------------------------------------");
+    ALOGI("%s() called ----------------------------------------", __func__);
     AudioStreamBuilder *streamBuilder = COMMON_GET_FROM_BUILDER_OR_RETURN(streamPtr);
     aaudio_result_t result = streamBuilder->build(&audioStream);
-    ALOGD("AAudioStreamBuilder_openStream() returns %d = %s for (%p) ----------------",
-          result, AAudio_convertResultToText(result), audioStream);
     if (result == AAUDIO_OK) {
         audioStream->registerPlayerBase();
         *streamPtr = (AAudioStream*) audioStream;
+        id = audioStream->getId();
     } else {
         *streamPtr = nullptr;
     }
+    ALOGI("%s() returns %d = %s for s#%u ----------------",
+        __func__, result, AAudio_convertResultToText(result), id);
     return result;
 }
 
@@ -267,8 +277,9 @@
 {
     aaudio_result_t result = AAUDIO_ERROR_NULL;
     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
-    ALOGD("AAudioStream_close(%p) called ---------------", stream);
     if (audioStream != nullptr) {
+        aaudio_stream_id_t id = audioStream->getId();
+        ALOGD("%s(s#%u) called ---------------", __func__, id);
         result = audioStream->safeClose();
         // Close will only fail if called illegally, for example, from a callback.
         // That would result in deleting an active stream, which would cause a crash.
@@ -278,43 +289,40 @@
         } else {
             ALOGW("%s attempt to close failed. Close it from another thread.", __func__);
         }
+        ALOGD("%s(s#%u) returned %d ---------", __func__, id, result);
     }
-    // We're potentially freeing `stream` above, so its use here makes some
-    // static analysis tools unhappy. Casting to uintptr_t helps assure
-    // said tools that we're not doing anything bad here.
-    ALOGD("AAudioStream_close(%#" PRIxPTR ") returned %d ---------",
-          reinterpret_cast<uintptr_t>(stream), result);
     return result;
 }
 
 AAUDIO_API aaudio_result_t  AAudioStream_requestStart(AAudioStream* stream)
 {
     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
-    ALOGD("AAudioStream_requestStart(%p) called --------------", stream);
+    aaudio_stream_id_t id = audioStream->getId();
+    ALOGD("%s(s#%u) called --------------", __func__, id);
     aaudio_result_t result = audioStream->systemStart();
-    ALOGD("AAudioStream_requestStart(%p) returned %d ---------", stream, result);
+    ALOGD("%s(s#%u) returned %d ---------", __func__, id, result);
     return result;
 }
 
 AAUDIO_API aaudio_result_t  AAudioStream_requestPause(AAudioStream* stream)
 {
     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
-    ALOGD("AAudioStream_requestPause(%p)", stream);
+    ALOGD("%s(s#%u) called", __func__, audioStream->getId());
     return audioStream->systemPause();
 }
 
 AAUDIO_API aaudio_result_t  AAudioStream_requestFlush(AAudioStream* stream)
 {
     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
-    ALOGD("AAudioStream_requestFlush(%p)", stream);
+    ALOGD("%s(s#%u) called", __func__, audioStream->getId());
     return audioStream->safeFlush();
 }
 
 AAUDIO_API aaudio_result_t  AAudioStream_requestStop(AAudioStream* stream)
 {
     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
-    ALOGD("AAudioStream_requestStop(%p)", stream);
-    return audioStream->systemStop();
+    ALOGD("%s(s#%u) called", __func__, audioStream->getId());
+    return audioStream->systemStopFromApp();
 }
 
 AAUDIO_API aaudio_result_t AAudioStream_waitForStateChange(AAudioStream* stream,
@@ -363,7 +371,7 @@
 
     // Don't allow writes when playing with a callback.
     if (audioStream->isDataCallbackActive()) {
-        ALOGE("Cannot write to a callback stream when running.");
+        ALOGD("Cannot write to a callback stream when running.");
         return AAUDIO_ERROR_INVALID_STATE;
     }
 
@@ -408,7 +416,9 @@
 AAUDIO_API aaudio_format_t AAudioStream_getFormat(AAudioStream* stream)
 {
     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
-    return audioStream->getFormat();
+    // Use audio_format_t internally.
+    audio_format_t internalFormat = audioStream->getFormat();
+    return AAudioConvert_androidToAAudioDataFormat(internalFormat);
 }
 
 AAUDIO_API aaudio_result_t AAudioStream_setBufferSizeInFrames(AAudioStream* stream,
@@ -490,6 +500,13 @@
     return audioStream->getInputPreset();
 }
 
+AAUDIO_API aaudio_allowed_capture_policy_t AAudioStream_getAllowedCapturePolicy(
+        AAudioStream* stream)
+{
+    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
+    return audioStream->getAllowedCapturePolicy();
+}
+
 AAUDIO_API int32_t AAudioStream_getSessionId(AAudioStream* stream)
 {
     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
diff --git a/media/libaaudio/src/core/AAudioStreamParameters.cpp b/media/libaaudio/src/core/AAudioStreamParameters.cpp
index d56701b..c9711da 100644
--- a/media/libaaudio/src/core/AAudioStreamParameters.cpp
+++ b/media/libaaudio/src/core/AAudioStreamParameters.cpp
@@ -35,28 +35,43 @@
 AAudioStreamParameters::~AAudioStreamParameters() {}
 
 void AAudioStreamParameters::copyFrom(const AAudioStreamParameters &other) {
-    mSamplesPerFrame = other.mSamplesPerFrame;
-    mSampleRate      = other.mSampleRate;
-    mDeviceId        = other.mDeviceId;
-    mSessionId       = other.mSessionId;
-    mSharingMode     = other.mSharingMode;
-    mAudioFormat     = other.mAudioFormat;
-    mDirection       = other.mDirection;
-    mBufferCapacity  = other.mBufferCapacity;
-    mUsage           = other.mUsage;
-    mContentType     = other.mContentType;
-    mInputPreset     = other.mInputPreset;
+    mSamplesPerFrame      = other.mSamplesPerFrame;
+    mSampleRate           = other.mSampleRate;
+    mDeviceId             = other.mDeviceId;
+    mSessionId            = other.mSessionId;
+    mSharingMode          = other.mSharingMode;
+    mAudioFormat          = other.mAudioFormat;
+    mDirection            = other.mDirection;
+    mBufferCapacity       = other.mBufferCapacity;
+    mUsage                = other.mUsage;
+    mContentType          = other.mContentType;
+    mInputPreset          = other.mInputPreset;
+    mAllowedCapturePolicy = other.mAllowedCapturePolicy;
+}
+
+static aaudio_result_t isFormatValid(audio_format_t format) {
+    switch (format) {
+        case AUDIO_FORMAT_DEFAULT:
+        case AUDIO_FORMAT_PCM_16_BIT:
+        case AUDIO_FORMAT_PCM_FLOAT:
+            break; // valid
+        default:
+            ALOGD("audioFormat not valid, audio_format_t = 0x%08x", format);
+            return AAUDIO_ERROR_INVALID_FORMAT;
+            // break;
+    }
+    return AAUDIO_OK;
 }
 
 aaudio_result_t AAudioStreamParameters::validate() const {
     if (mSamplesPerFrame != AAUDIO_UNSPECIFIED
         && (mSamplesPerFrame < SAMPLES_PER_FRAME_MIN || mSamplesPerFrame > SAMPLES_PER_FRAME_MAX)) {
-        ALOGE("channelCount out of range = %d", mSamplesPerFrame);
+        ALOGD("channelCount out of range = %d", mSamplesPerFrame);
         return AAUDIO_ERROR_OUT_OF_RANGE;
     }
 
     if (mDeviceId < 0) {
-        ALOGE("deviceId out of range = %d", mDeviceId);
+        ALOGD("deviceId out of range = %d", mDeviceId);
         return AAUDIO_ERROR_OUT_OF_RANGE;
     }
 
@@ -74,30 +89,22 @@
         case AAUDIO_SHARING_MODE_SHARED:
             break;
         default:
-            ALOGE("illegal sharingMode = %d", mSharingMode);
+            ALOGD("illegal sharingMode = %d", mSharingMode);
             return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
             // break;
     }
 
-    switch (mAudioFormat) {
-        case AAUDIO_FORMAT_UNSPECIFIED:
-        case AAUDIO_FORMAT_PCM_I16:
-        case AAUDIO_FORMAT_PCM_FLOAT:
-            break; // valid
-        default:
-            ALOGE("audioFormat not valid = %d", mAudioFormat);
-            return AAUDIO_ERROR_INVALID_FORMAT;
-            // break;
-    }
+    aaudio_result_t result = isFormatValid (mAudioFormat);
+    if (result != AAUDIO_OK) return result;
 
     if (mSampleRate != AAUDIO_UNSPECIFIED
         && (mSampleRate < SAMPLE_RATE_HZ_MIN || mSampleRate > SAMPLE_RATE_HZ_MAX)) {
-        ALOGE("sampleRate out of range = %d", mSampleRate);
+        ALOGD("sampleRate out of range = %d", mSampleRate);
         return AAUDIO_ERROR_INVALID_RATE;
     }
 
     if (mBufferCapacity < 0) {
-        ALOGE("bufferCapacity out of range = %d", mBufferCapacity);
+        ALOGD("bufferCapacity out of range = %d", mBufferCapacity);
         return AAUDIO_ERROR_OUT_OF_RANGE;
     }
 
@@ -106,7 +113,7 @@
         case AAUDIO_DIRECTION_OUTPUT:
             break; // valid
         default:
-            ALOGE("direction not valid = %d", mDirection);
+            ALOGD("direction not valid = %d", mDirection);
             return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
             // break;
     }
@@ -127,7 +134,7 @@
         case AAUDIO_USAGE_ASSISTANT:
             break; // valid
         default:
-            ALOGE("usage not valid = %d", mUsage);
+            ALOGD("usage not valid = %d", mUsage);
             return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
             // break;
     }
@@ -140,7 +147,7 @@
         case AAUDIO_CONTENT_TYPE_SPEECH:
             break; // valid
         default:
-            ALOGE("content type not valid = %d", mContentType);
+            ALOGD("content type not valid = %d", mContentType);
             return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
             // break;
     }
@@ -152,9 +159,22 @@
         case AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION:
         case AAUDIO_INPUT_PRESET_VOICE_RECOGNITION:
         case AAUDIO_INPUT_PRESET_UNPROCESSED:
+        case AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE:
             break; // valid
         default:
-            ALOGE("input preset not valid = %d", mInputPreset);
+            ALOGD("input preset not valid = %d", mInputPreset);
+            return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
+            // break;
+    }
+
+    switch (mAllowedCapturePolicy) {
+        case AAUDIO_UNSPECIFIED:
+        case AAUDIO_ALLOW_CAPTURE_BY_ALL:
+        case AAUDIO_ALLOW_CAPTURE_BY_SYSTEM:
+        case AAUDIO_ALLOW_CAPTURE_BY_NONE:
+            break; // valid
+        default:
+            ALOGD("allowed capture policy not valid = %d", mAllowedCapturePolicy);
             return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
             // break;
     }
@@ -163,15 +183,16 @@
 }
 
 void AAudioStreamParameters::dump() const {
-    ALOGD("mDeviceId        = %6d", mDeviceId);
-    ALOGD("mSessionId       = %6d", mSessionId);
-    ALOGD("mSampleRate      = %6d", mSampleRate);
-    ALOGD("mSamplesPerFrame = %6d", mSamplesPerFrame);
-    ALOGD("mSharingMode     = %6d", (int)mSharingMode);
-    ALOGD("mAudioFormat     = %6d", (int)mAudioFormat);
-    ALOGD("mDirection       = %6d", mDirection);
-    ALOGD("mBufferCapacity  = %6d", mBufferCapacity);
-    ALOGD("mUsage           = %6d", mUsage);
-    ALOGD("mContentType     = %6d", mContentType);
-    ALOGD("mInputPreset     = %6d", mInputPreset);
+    ALOGD("mDeviceId             = %6d", mDeviceId);
+    ALOGD("mSessionId            = %6d", mSessionId);
+    ALOGD("mSampleRate           = %6d", mSampleRate);
+    ALOGD("mSamplesPerFrame      = %6d", mSamplesPerFrame);
+    ALOGD("mSharingMode          = %6d", (int)mSharingMode);
+    ALOGD("mAudioFormat          = %6d", (int)mAudioFormat);
+    ALOGD("mDirection            = %6d", mDirection);
+    ALOGD("mBufferCapacity       = %6d", mBufferCapacity);
+    ALOGD("mUsage                = %6d", mUsage);
+    ALOGD("mContentType          = %6d", mContentType);
+    ALOGD("mInputPreset          = %6d", mInputPreset);
+    ALOGD("mAllowedCapturePolicy = %6d", mAllowedCapturePolicy);
 }
diff --git a/media/libaaudio/src/core/AAudioStreamParameters.h b/media/libaaudio/src/core/AAudioStreamParameters.h
index ce5dacd..2e21a8d 100644
--- a/media/libaaudio/src/core/AAudioStreamParameters.h
+++ b/media/libaaudio/src/core/AAudioStreamParameters.h
@@ -56,11 +56,11 @@
         mSamplesPerFrame = samplesPerFrame;
     }
 
-    aaudio_format_t getFormat() const {
+    audio_format_t getFormat() const {
         return mAudioFormat;
     }
 
-    void setFormat(aaudio_format_t audioFormat) {
+    void setFormat(audio_format_t audioFormat) {
         mAudioFormat = audioFormat;
     }
 
@@ -112,6 +112,14 @@
         mInputPreset = inputPreset;
     }
 
+    aaudio_allowed_capture_policy_t getAllowedCapturePolicy() const {
+        return mAllowedCapturePolicy;
+    }
+
+    void setAllowedCapturePolicy(aaudio_allowed_capture_policy_t policy) {
+        mAllowedCapturePolicy = policy;
+    }
+
     aaudio_session_id_t getSessionId() const {
         return mSessionId;
     }
@@ -120,8 +128,11 @@
         mSessionId = sessionId;
     }
 
+    /**
+     * @return bytes per frame of getFormat()
+     */
     int32_t calculateBytesPerFrame() const {
-        return getSamplesPerFrame() * AAudioConvert_formatToSizeInBytes(getFormat());
+        return getSamplesPerFrame() * audio_bytes_per_sample(getFormat());
     }
 
     /**
@@ -135,17 +146,18 @@
     void dump() const;
 
 private:
-    int32_t                    mSamplesPerFrame = AAUDIO_UNSPECIFIED;
-    int32_t                    mSampleRate      = AAUDIO_UNSPECIFIED;
-    int32_t                    mDeviceId        = AAUDIO_UNSPECIFIED;
-    aaudio_sharing_mode_t      mSharingMode     = AAUDIO_SHARING_MODE_SHARED;
-    aaudio_format_t            mAudioFormat     = AAUDIO_FORMAT_UNSPECIFIED;
-    aaudio_direction_t         mDirection       = AAUDIO_DIRECTION_OUTPUT;
-    aaudio_usage_t             mUsage           = AAUDIO_UNSPECIFIED;
-    aaudio_content_type_t      mContentType     = AAUDIO_UNSPECIFIED;
-    aaudio_input_preset_t      mInputPreset     = AAUDIO_UNSPECIFIED;
-    int32_t                    mBufferCapacity  = AAUDIO_UNSPECIFIED;
-    aaudio_session_id_t        mSessionId       = AAUDIO_SESSION_ID_NONE;
+    int32_t                         mSamplesPerFrame      = AAUDIO_UNSPECIFIED;
+    int32_t                         mSampleRate           = AAUDIO_UNSPECIFIED;
+    int32_t                         mDeviceId             = AAUDIO_UNSPECIFIED;
+    aaudio_sharing_mode_t           mSharingMode          = AAUDIO_SHARING_MODE_SHARED;
+    audio_format_t                  mAudioFormat          = AUDIO_FORMAT_DEFAULT;
+    aaudio_direction_t              mDirection            = AAUDIO_DIRECTION_OUTPUT;
+    aaudio_usage_t                  mUsage                = AAUDIO_UNSPECIFIED;
+    aaudio_content_type_t           mContentType          = AAUDIO_UNSPECIFIED;
+    aaudio_input_preset_t           mInputPreset          = AAUDIO_UNSPECIFIED;
+    int32_t                         mBufferCapacity       = AAUDIO_UNSPECIFIED;
+    aaudio_allowed_capture_policy_t mAllowedCapturePolicy = AAUDIO_UNSPECIFIED;
+    aaudio_session_id_t             mSessionId            = AAUDIO_SESSION_ID_NONE;
 };
 
 } /* namespace aaudio */
diff --git a/media/libaaudio/src/core/AudioStream.cpp b/media/libaaudio/src/core/AudioStream.cpp
index 358021b..9b77223 100644
--- a/media/libaaudio/src/core/AudioStream.cpp
+++ b/media/libaaudio/src/core/AudioStream.cpp
@@ -28,16 +28,23 @@
 
 using namespace aaudio;
 
+
+// Sequential number assigned to streams solely for debugging purposes.
+static aaudio_stream_id_t AAudio_getNextStreamId() {
+    static std::atomic <aaudio_stream_id_t> nextStreamId{1};
+    return nextStreamId++;
+}
+
 AudioStream::AudioStream()
         : mPlayerBase(new MyPlayerBase(this))
-{
+        , mStreamId(AAudio_getNextStreamId())
+        {
     // mThread is a pthread_t of unknown size so we need memset.
     memset(&mThread, 0, sizeof(mThread));
     setPeriodNanoseconds(0);
 }
 
 AudioStream::~AudioStream() {
-    ALOGD("destroying %p, state = %s", this, AAudio_convertStreamStateToText(getState()));
     // If the stream is deleted when OPEN or in use then audio resources will leak.
     // This would indicate an internal error. So we want to find this ASAP.
     LOG_ALWAYS_FATAL_IF(!(getState() == AAUDIO_STREAM_STATE_CLOSED
@@ -49,22 +56,6 @@
     mPlayerBase->clearParentReference(); // remove reference to this AudioStream
 }
 
-static const char *AudioStream_convertSharingModeToShortText(aaudio_sharing_mode_t sharingMode) {
-    const char *result;
-    switch (sharingMode) {
-        case AAUDIO_SHARING_MODE_EXCLUSIVE:
-            result = "EX";
-            break;
-        case AAUDIO_SHARING_MODE_SHARED:
-            result = "SH";
-            break;
-        default:
-            result = "?!";
-            break;
-    }
-    return result;
-}
-
 aaudio_result_t AudioStream::open(const AudioStreamBuilder& builder)
 {
     // Call here as well because the AAudioService will call this without calling build().
@@ -95,6 +86,10 @@
     if (mInputPreset == AAUDIO_UNSPECIFIED) {
         mInputPreset = AAUDIO_INPUT_PRESET_VOICE_RECOGNITION;
     }
+    mAllowedCapturePolicy = builder.getAllowedCapturePolicy();
+    if (mAllowedCapturePolicy == AAUDIO_UNSPECIFIED) {
+        mAllowedCapturePolicy = AAUDIO_ALLOW_CAPTURE_BY_ALL;
+    }
 
     // callbacks
     mFramesPerDataCallback = builder.getFramesPerDataCallback();
@@ -103,38 +98,32 @@
     mDataCallbackUserData = builder.getDataCallbackUserData();
     mErrorCallbackUserData = builder.getErrorCallbackUserData();
 
-    // This is very helpful for debugging in the future. Please leave it in.
-    ALOGI("open() rate   = %d, channels    = %d, format   = %d, sharing = %s, dir = %s",
-          mSampleRate, mSamplesPerFrame, mFormat,
-          AudioStream_convertSharingModeToShortText(mSharingMode),
-          (getDirection() == AAUDIO_DIRECTION_OUTPUT) ? "OUTPUT" : "INPUT");
-    ALOGI("open() device = %d, sessionId   = %d, perfMode = %d, callback: %s with frames = %d",
-          mDeviceId,
-          mSessionId,
-          mPerformanceMode,
-          (isDataCallbackSet() ? "ON" : "OFF"),
-          mFramesPerDataCallback);
-    ALOGI("open() usage  = %d, contentType = %d, inputPreset = %d",
-          mUsage, mContentType, mInputPreset);
-
     return AAUDIO_OK;
 }
 
-aaudio_result_t AudioStream::safeStart() {
+aaudio_result_t AudioStream::systemStart() {
     std::lock_guard<std::mutex> lock(mStreamLock);
+
     if (collidesWithCallback()) {
         ALOGE("%s cannot be called from a callback!", __func__);
         return AAUDIO_ERROR_INVALID_STATE;
     }
-    return requestStart();
+
+    aaudio_result_t result = requestStart();
+    if (result == AAUDIO_OK) {
+        // We only call this for logging in "dumpsys audio". So ignore return code.
+        (void) mPlayerBase->start();
+    }
+    return result;
 }
 
-aaudio_result_t AudioStream::safePause() {
+aaudio_result_t AudioStream::systemPause() {
+    std::lock_guard<std::mutex> lock(mStreamLock);
+
     if (!isPauseSupported()) {
         return AAUDIO_ERROR_UNIMPLEMENTED;
     }
 
-    std::lock_guard<std::mutex> lock(mStreamLock);
     if (collidesWithCallback()) {
         ALOGE("%s cannot be called from a callback!", __func__);
         return AAUDIO_ERROR_INVALID_STATE;
@@ -170,7 +159,12 @@
             return AAUDIO_ERROR_INVALID_STATE;
     }
 
-    return requestPause();
+    aaudio_result_t result = requestPause();
+    if (result == AAUDIO_OK) {
+        // We only call this for logging in "dumpsys audio". So ignore return code.
+        (void) mPlayerBase->pause();
+    }
+    return result;
 }
 
 aaudio_result_t AudioStream::safeFlush() {
@@ -193,12 +187,32 @@
     return requestFlush();
 }
 
-aaudio_result_t AudioStream::safeStop() {
+aaudio_result_t AudioStream::systemStopFromCallback() {
+    std::lock_guard<std::mutex> lock(mStreamLock);
+    aaudio_result_t result = safeStop();
+    if (result == AAUDIO_OK) {
+        // We only call this for logging in "dumpsys audio". So ignore return code.
+        (void) mPlayerBase->stop();
+    }
+    return result;
+}
+
+aaudio_result_t AudioStream::systemStopFromApp() {
     std::lock_guard<std::mutex> lock(mStreamLock);
     if (collidesWithCallback()) {
-        ALOGE("stream cannot be stopped from a callback!");
+        ALOGE("stream cannot be stopped by calling from a callback!");
         return AAUDIO_ERROR_INVALID_STATE;
     }
+    aaudio_result_t result = safeStop();
+    if (result == AAUDIO_OK) {
+        // We only call this for logging in "dumpsys audio". So ignore return code.
+        (void) mPlayerBase->stop();
+    }
+    return result;
+}
+
+// This must be called under mStreamLock.
+aaudio_result_t AudioStream::safeStop() {
 
     switch (getState()) {
         // Proceed with stopping.
@@ -225,7 +239,7 @@
         case AAUDIO_STREAM_STATE_CLOSING:
         case AAUDIO_STREAM_STATE_CLOSED:
         default:
-            ALOGW("requestStop() stream not running, state = %s",
+            ALOGW("%s() stream not running, state = %s", __func__,
                   AAudio_convertStreamStateToText(getState()));
             return AAUDIO_ERROR_INVALID_STATE;
     }
@@ -234,6 +248,7 @@
 }
 
 aaudio_result_t AudioStream::safeClose() {
+    // This get temporarily unlocked in the close when joining callback threads.
     std::lock_guard<std::mutex> lock(mStreamLock);
     if (collidesWithCallback()) {
         ALOGE("%s cannot be called from a callback!", __func__);
@@ -243,15 +258,15 @@
 }
 
 void AudioStream::setState(aaudio_stream_state_t state) {
-    ALOGV("%s(%p) from %d to %d", __func__, this, mState, state);
+    ALOGV("%s(%d) from %d to %d", __func__, getId(), mState, state);
     // CLOSED is a final state
     if (mState == AAUDIO_STREAM_STATE_CLOSED) {
-        ALOGE("%s(%p) tried to set to %d but already CLOSED", __func__, this, state);
+        ALOGE("%s(%d) tried to set to %d but already CLOSED", __func__, getId(), state);
 
     // Once DISCONNECTED, we can only move to CLOSED state.
     } else if (mState == AAUDIO_STREAM_STATE_DISCONNECTED
                && state != AAUDIO_STREAM_STATE_CLOSED) {
-        ALOGE("%s(%p) tried to set to %d but already DISCONNECTED", __func__, this, state);
+        ALOGE("%s(%d) tried to set to %d but already DISCONNECTED", __func__, getId(), state);
 
     } else {
         mState = state;
@@ -350,21 +365,37 @@
     }
 }
 
-aaudio_result_t AudioStream::joinThread(void** returnArg, int64_t timeoutNanoseconds)
+// This must be called under mStreamLock.
+aaudio_result_t AudioStream::joinThread(void** returnArg, int64_t timeoutNanoseconds __unused)
 {
     if (!mHasThread) {
         ALOGE("joinThread() - but has no thread");
         return AAUDIO_ERROR_INVALID_STATE;
     }
+    aaudio_result_t result = AAUDIO_OK;
+    // If the callback is stopping the stream because the app passed back STOP
+    // then we don't need to join(). The thread is already about to exit.
+    if (pthread_self() != mThread) {
+        // Called from an app thread. Not the callback.
+        // Unlock because the callback may be trying to stop the stream but is blocked.
+        mStreamLock.unlock();
 #if 0
-    // TODO implement equivalent of pthread_timedjoin_np()
-    struct timespec abstime;
-    int err = pthread_timedjoin_np(mThread, returnArg, &abstime);
+        // TODO implement equivalent of pthread_timedjoin_np()
+        struct timespec abstime;
+        int err = pthread_timedjoin_np(mThread, returnArg, &abstime);
 #else
-    int err = pthread_join(mThread, returnArg);
+        int err = pthread_join(mThread, returnArg);
 #endif
+        mStreamLock.lock();
+        if (err) {
+            ALOGE("%s() pthread_join() returns err = %d", __func__, err);
+            result = AAudioConvert_androidToAAudioResult(-err);
+        }
+    }
+    // This must be set false so that the callback thread can be created
+    // when the stream is restarted.
     mHasThread = false;
-    return err ? AAudioConvert_androidToAAudioResult(-errno) : mThreadRegistrationResult;
+    return (result != AAUDIO_OK) ? result : mThreadRegistrationResult;
 }
 
 aaudio_data_callback_result_t AudioStream::maybeCallDataCallback(void *audioData,
@@ -438,7 +469,6 @@
 }
 
 AudioStream::MyPlayerBase::~MyPlayerBase() {
-    ALOGV("MyPlayerBase::~MyPlayerBase(%p) deleted", this);
 }
 
 void AudioStream::MyPlayerBase::registerWithAudioManager() {
diff --git a/media/libaaudio/src/core/AudioStream.h b/media/libaaudio/src/core/AudioStream.h
index 31b895c..044c979 100644
--- a/media/libaaudio/src/core/AudioStream.h
+++ b/media/libaaudio/src/core/AudioStream.h
@@ -36,6 +36,7 @@
 namespace aaudio {
 
 typedef void *(*aaudio_audio_thread_proc_t)(void *);
+typedef uint32_t aaudio_stream_id_t;
 
 class AudioStreamBuilder;
 
@@ -51,21 +52,6 @@
 
     virtual ~AudioStream();
 
-    /**
-     * Lock a mutex and make sure we are not calling from a callback function.
-     * @return result of requestStart();
-     */
-    aaudio_result_t safeStart();
-
-    aaudio_result_t safePause();
-
-    aaudio_result_t safeFlush();
-
-    aaudio_result_t safeStop();
-
-    aaudio_result_t safeClose();
-
-    // =========== Begin ABSTRACT methods ===========================
 protected:
 
     /* Asynchronous requests.
@@ -74,7 +60,7 @@
     virtual aaudio_result_t requestStart() = 0;
 
     /**
-     * Check the state to see if Pause if currently legal.
+     * Check the state to see if Pause is currently legal.
      *
      * @param result pointer to return code
      * @return true if OK to continue, if false then return result
@@ -136,6 +122,12 @@
         return AAUDIO_OK;
     }
 
+    // This is only used to identify a stream in the logs without
+    // revealing any pointers.
+    aaudio_stream_id_t getId() {
+        return mStreamId;
+    }
+
     virtual aaudio_result_t setBufferSize(int32_t requestedFrames) = 0;
 
     virtual aaudio_result_t createThread(int64_t periodNanoseconds,
@@ -192,7 +184,7 @@
         return mSampleRate;
     }
 
-    aaudio_format_t getFormat()  const {
+    audio_format_t getFormat()  const {
         return mFormat;
     }
 
@@ -234,6 +226,10 @@
         return mInputPreset;
     }
 
+    aaudio_allowed_capture_policy_t getAllowedCapturePolicy() const {
+        return mAllowedCapturePolicy;
+    }
+
     int32_t getSessionId() const {
         return mSessionId;
     }
@@ -249,21 +245,14 @@
      * This is only valid after setFormat() has been called.
      */
     int32_t getBytesPerSample() const {
-        return AAudioConvert_formatToSizeInBytes(mFormat);
+        return audio_bytes_per_sample(mFormat);
     }
 
     /**
      * This is only valid after setSamplesPerFrame() and setDeviceFormat() have been called.
      */
     int32_t getBytesPerDeviceFrame() const {
-        return mSamplesPerFrame * getBytesPerDeviceSample();
-    }
-
-    /**
-     * This is only valid after setDeviceFormat() has been called.
-     */
-    int32_t getBytesPerDeviceSample() const {
-        return AAudioConvert_formatToSizeInBytes(getDeviceFormat());
+        return getSamplesPerFrame() * audio_bytes_per_sample(getDeviceFormat());
     }
 
     virtual int64_t getFramesWritten() = 0;
@@ -363,33 +352,28 @@
         mPlayerBase->unregisterWithAudioManager();
     }
 
-    // Pass start request through PlayerBase for tracking.
-    aaudio_result_t systemStart() {
-        mPlayerBase->start();
-        // Pass aaudio_result_t around the PlayerBase interface, which uses status__t.
-        return mPlayerBase->getResult();
-    }
+    aaudio_result_t systemStart();
 
-    // Pass pause request through PlayerBase for tracking.
-    aaudio_result_t systemPause() {
-        mPlayerBase->pause();
-        return mPlayerBase->getResult();
-    }
+    aaudio_result_t systemPause();
 
-    // Pass stop request through PlayerBase for tracking.
-    aaudio_result_t systemStop() {
-        mPlayerBase->stop();
-        return mPlayerBase->getResult();
-    }
+    aaudio_result_t safeFlush();
+
+    /**
+     * This is called when an app calls AAudioStream_requestStop();
+     * It prevents calls from a callback.
+     */
+    aaudio_result_t systemStopFromApp();
+
+    /**
+     * This is called internally when an app callback returns AAUDIO_CALLBACK_RESULT_STOP.
+     */
+    aaudio_result_t systemStopFromCallback();
+
+    aaudio_result_t safeClose();
 
 protected:
 
-    // PlayerBase allows the system to control the stream.
-    // Calling through PlayerBase->start() notifies the AudioManager of the player state.
-    // The AudioManager also can start/stop a stream by calling mPlayerBase->playerStart().
-    // systemStart() ==> mPlayerBase->start()   mPlayerBase->playerStart() ==> requestStart()
-    //                        \                           /
-    //                         ------ AudioManager -------
+    // PlayerBase allows the system to control the stream volume.
     class MyPlayerBase : public android::PlayerBase {
     public:
         explicit MyPlayerBase(AudioStream *parent);
@@ -413,20 +397,19 @@
 
         void clearParentReference() { mParent = nullptr; }
 
+        // Just a stub. The ability to start audio through PlayerBase is being deprecated.
         android::status_t playerStart() override {
-            // mParent should NOT be null. So go ahead and crash if it is.
-            mResult = mParent->safeStart();
-            return AAudioConvert_aaudioToAndroidStatus(mResult);
+            return android::NO_ERROR;
         }
 
+        // Just a stub. The ability to pause audio through PlayerBase is being deprecated.
         android::status_t playerPause() override {
-            mResult = mParent->safePause();
-            return AAudioConvert_aaudioToAndroidStatus(mResult);
+            return android::NO_ERROR;
         }
 
+        // Just a stub. The ability to stop audio through PlayerBase is being deprecated.
         android::status_t playerStop() override {
-            mResult = mParent->safeStop();
-            return AAudioConvert_aaudioToAndroidStatus(mResult);
+            return android::NO_ERROR;
         }
 
         android::status_t playerSetVolume() override {
@@ -478,18 +461,18 @@
     /**
      * This should not be called after the open() call.
      */
-    void setFormat(aaudio_format_t format) {
+    void setFormat(audio_format_t format) {
         mFormat = format;
     }
 
     /**
      * This should not be called after the open() call.
      */
-    void setDeviceFormat(aaudio_format_t format) {
+    void setDeviceFormat(audio_format_t format) {
         mDeviceFormat = format;
     }
 
-    aaudio_format_t getDeviceFormat() const {
+    audio_format_t getDeviceFormat() const {
         return mDeviceFormat;
     }
 
@@ -553,8 +536,17 @@
         mInputPreset = inputPreset;
     }
 
+    /**
+     * This should not be called after the open() call.
+     */
+    void setAllowedCapturePolicy(aaudio_allowed_capture_policy_t policy) {
+        mAllowedCapturePolicy = policy;
+    }
+
 private:
 
+    aaudio_result_t safeStop();
+
     std::mutex                 mStreamLock;
 
     const android::sp<MyPlayerBase>   mPlayerBase;
@@ -565,19 +557,20 @@
     int32_t                     mDeviceId = AAUDIO_UNSPECIFIED;
     aaudio_sharing_mode_t       mSharingMode = AAUDIO_SHARING_MODE_SHARED;
     bool                        mSharingModeMatchRequired = false; // must match sharing mode requested
-    aaudio_format_t             mFormat = AAUDIO_FORMAT_UNSPECIFIED;
+    audio_format_t              mFormat = AUDIO_FORMAT_DEFAULT;
     aaudio_stream_state_t       mState = AAUDIO_STREAM_STATE_UNINITIALIZED;
     aaudio_performance_mode_t   mPerformanceMode = AAUDIO_PERFORMANCE_MODE_NONE;
 
     aaudio_usage_t              mUsage           = AAUDIO_UNSPECIFIED;
     aaudio_content_type_t       mContentType     = AAUDIO_UNSPECIFIED;
     aaudio_input_preset_t       mInputPreset     = AAUDIO_UNSPECIFIED;
+    aaudio_allowed_capture_policy_t mAllowedCapturePolicy = AAUDIO_ALLOW_CAPTURE_BY_ALL;
 
     int32_t                     mSessionId = AAUDIO_UNSPECIFIED;
 
     // Sometimes the hardware is operating with a different format from the app.
     // Then we require conversion in AAudio.
-    aaudio_format_t             mDeviceFormat = AAUDIO_FORMAT_UNSPECIFIED;
+    audio_format_t              mDeviceFormat = AUDIO_FORMAT_INVALID;
 
     // callback ----------------------------------
 
@@ -601,6 +594,8 @@
     void                       *mThreadArg = nullptr;
     aaudio_result_t             mThreadRegistrationResult = AAUDIO_OK;
 
+    const aaudio_stream_id_t    mStreamId;
+
 };
 
 } /* namespace aaudio */
diff --git a/media/libaaudio/src/core/AudioStreamBuilder.cpp b/media/libaaudio/src/core/AudioStreamBuilder.cpp
index 3a7a578..08f4958 100644
--- a/media/libaaudio/src/core/AudioStreamBuilder.cpp
+++ b/media/libaaudio/src/core/AudioStreamBuilder.cpp
@@ -104,6 +104,8 @@
     }
     *streamPtr = nullptr;
 
+    logParameters();
+
     aaudio_result_t result = validate();
     if (result != AAUDIO_OK) {
         return result;
@@ -150,6 +152,11 @@
         allowMMap = false;
     }
 
+    if (!allowMMap && !allowLegacy) {
+        ALOGE("%s() no backend available: neither MMAP nor legacy path are allowed", __func__);
+        return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
+    }
+
     result = builder_createStream(getDirection(), sharingMode, allowMMap, &audioStream);
     if (result == AAUDIO_OK) {
         // Open the stream using the parameters from the builder.
@@ -212,3 +219,41 @@
 
     return AAUDIO_OK;
 }
+
+static const char *AAudio_convertSharingModeToShortText(aaudio_sharing_mode_t sharingMode) {
+    switch (sharingMode) {
+        case AAUDIO_SHARING_MODE_EXCLUSIVE:
+            return "EX";
+        case AAUDIO_SHARING_MODE_SHARED:
+            return "SH";
+        default:
+            return "?!";
+    }
+}
+
+static const char *AAudio_convertDirectionToText(aaudio_direction_t direction) {
+    switch (direction) {
+        case AAUDIO_DIRECTION_OUTPUT:
+            return "OUTPUT";
+        case AAUDIO_DIRECTION_INPUT:
+            return "INPUT";
+        default:
+            return "?!";
+    }
+}
+
+void AudioStreamBuilder::logParameters() const {
+    // This is very helpful for debugging in the future. Please leave it in.
+    ALOGI("rate   = %6d, channels  = %d, format   = %d, sharing = %s, dir = %s",
+          getSampleRate(), getSamplesPerFrame(), getFormat(),
+          AAudio_convertSharingModeToShortText(getSharingMode()),
+          AAudio_convertDirectionToText(getDirection()));
+    ALOGI("device = %6d, sessionId = %d, perfMode = %d, callback: %s with frames = %d",
+          getDeviceId(),
+          getSessionId(),
+          getPerformanceMode(),
+          ((getDataCallbackProc() != nullptr) ? "ON" : "OFF"),
+          mFramesPerDataCallback);
+    ALOGI("usage  = %6d, contentType = %d, inputPreset = %d, allowedCapturePolicy = %d",
+          getUsage(), getContentType(), getInputPreset(), getAllowedCapturePolicy());
+}
diff --git a/media/libaaudio/src/core/AudioStreamBuilder.h b/media/libaaudio/src/core/AudioStreamBuilder.h
index a43cfa8..8149af2 100644
--- a/media/libaaudio/src/core/AudioStreamBuilder.h
+++ b/media/libaaudio/src/core/AudioStreamBuilder.h
@@ -102,6 +102,8 @@
 
     virtual aaudio_result_t validate() const override;
 
+    void logParameters() const;
+
 private:
     bool                       mSharingModeMatchRequired = false; // must match sharing mode requested
     aaudio_performance_mode_t  mPerformanceMode = AAUDIO_PERFORMANCE_MODE_NONE;
diff --git a/media/libaaudio/src/fifo/FifoBuffer.cpp b/media/libaaudio/src/fifo/FifoBuffer.cpp
index b09258e..f5113f2 100644
--- a/media/libaaudio/src/fifo/FifoBuffer.cpp
+++ b/media/libaaudio/src/fifo/FifoBuffer.cpp
@@ -23,30 +23,26 @@
 #include <utils/Log.h>
 
 #include <algorithm>
+#include <memory>
 
 #include "FifoControllerBase.h"
 #include "FifoController.h"
 #include "FifoControllerIndirect.h"
 #include "FifoBuffer.h"
 
-using namespace android; // TODO just import names needed
+using android::FifoBuffer;
+using android::fifo_frames_t;
 
 FifoBuffer::FifoBuffer(int32_t bytesPerFrame, fifo_frames_t capacityInFrames)
-        : mFrameCapacity(capacityInFrames)
-        , mBytesPerFrame(bytesPerFrame)
-        , mStorage(nullptr)
-        , mFramesReadCount(0)
-        , mFramesUnderrunCount(0)
-        , mUnderrunCount(0)
+        : mBytesPerFrame(bytesPerFrame)
 {
-    // TODO Handle possible failures to allocate. Move out of constructor?
-    mFifo = new FifoController(capacityInFrames, capacityInFrames);
+    mFifo = std::make_unique<FifoController>(capacityInFrames, capacityInFrames);
     // allocate buffer
     int32_t bytesPerBuffer = bytesPerFrame * capacityInFrames;
     mStorage = new uint8_t[bytesPerBuffer];
     mStorageOwned = true;
-    ALOGV("capacityInFrames = %d, bytesPerFrame = %d",
-          capacityInFrames, bytesPerFrame);
+    ALOGV("%s() capacityInFrames = %d, bytesPerFrame = %d",
+          __func__, capacityInFrames, bytesPerFrame);
 }
 
 FifoBuffer::FifoBuffer( int32_t   bytesPerFrame,
@@ -55,14 +51,10 @@
                         fifo_counter_t *  writeIndexAddress,
                         void *  dataStorageAddress
                         )
-        : mFrameCapacity(capacityInFrames)
-        , mBytesPerFrame(bytesPerFrame)
+        : mBytesPerFrame(bytesPerFrame)
         , mStorage(static_cast<uint8_t *>(dataStorageAddress))
-        , mFramesReadCount(0)
-        , mFramesUnderrunCount(0)
-        , mUnderrunCount(0)
 {
-    mFifo = new FifoControllerIndirect(capacityInFrames,
+    mFifo = std::make_unique<FifoControllerIndirect>(capacityInFrames,
                                        capacityInFrames,
                                        readIndexAddress,
                                        writeIndexAddress);
@@ -73,10 +65,8 @@
     if (mStorageOwned) {
         delete[] mStorage;
     }
-    delete mFifo;
 }
 
-
 int32_t FifoBuffer::convertFramesToBytes(fifo_frames_t frames) {
     return frames * mBytesPerFrame;
 }
@@ -87,11 +77,12 @@
     wrappingBuffer->data[1] = nullptr;
     wrappingBuffer->numFrames[1] = 0;
     if (framesAvailable > 0) {
+        fifo_frames_t capacity = mFifo->getCapacity();
         uint8_t *source = &mStorage[convertFramesToBytes(startIndex)];
         // Does the available data cross the end of the FIFO?
-        if ((startIndex + framesAvailable) > mFrameCapacity) {
+        if ((startIndex + framesAvailable) > capacity) {
             wrappingBuffer->data[0] = source;
-            fifo_frames_t firstFrames = mFrameCapacity - startIndex;
+            fifo_frames_t firstFrames = capacity - startIndex;
             wrappingBuffer->numFrames[0] = firstFrames;
             wrappingBuffer->data[1] = &mStorage[0];
             wrappingBuffer->numFrames[1] = framesAvailable - firstFrames;
@@ -107,7 +98,8 @@
 
 fifo_frames_t FifoBuffer::getFullDataAvailable(WrappingBuffer *wrappingBuffer) {
     // The FIFO might be overfull so clip to capacity.
-    fifo_frames_t framesAvailable = std::min(mFifo->getFullFramesAvailable(), mFrameCapacity);
+    fifo_frames_t framesAvailable = std::min(mFifo->getFullFramesAvailable(),
+                                             mFifo->getCapacity());
     fifo_frames_t startIndex = mFifo->getReadIndex();
     fillWrappingBuffer(wrappingBuffer, framesAvailable, startIndex);
     return framesAvailable;
@@ -115,7 +107,8 @@
 
 fifo_frames_t FifoBuffer::getEmptyRoomAvailable(WrappingBuffer *wrappingBuffer) {
     // The FIFO might have underrun so clip to capacity.
-    fifo_frames_t framesAvailable = std::min(mFifo->getEmptyFramesAvailable(), mFrameCapacity);
+    fifo_frames_t framesAvailable = std::min(mFifo->getEmptyFramesAvailable(),
+                                             mFifo->getCapacity());
     fifo_frames_t startIndex = mFifo->getWriteIndex();
     fillWrappingBuffer(wrappingBuffer, framesAvailable, startIndex);
     return framesAvailable;
@@ -183,23 +176,6 @@
     return framesWritten;
 }
 
-fifo_frames_t FifoBuffer::readNow(void *buffer, fifo_frames_t numFrames) {
-    mLastReadSize = numFrames;
-    fifo_frames_t framesLeft = numFrames;
-    fifo_frames_t framesRead = read(buffer, numFrames);
-    framesLeft -= framesRead;
-    mFramesReadCount += framesRead;
-    mFramesUnderrunCount += framesLeft;
-    // Zero out any samples we could not set.
-    if (framesLeft > 0) {
-        mUnderrunCount++;
-        int32_t bytesToZero = convertFramesToBytes(framesLeft);
-        memset(buffer, 0, bytesToZero);
-    }
-
-    return framesRead;
-}
-
 fifo_frames_t FifoBuffer::getThreshold() {
     return mFifo->getThreshold();
 }
diff --git a/media/libaaudio/src/fifo/FifoBuffer.h b/media/libaaudio/src/fifo/FifoBuffer.h
index f5a9e27..0d188c4 100644
--- a/media/libaaudio/src/fifo/FifoBuffer.h
+++ b/media/libaaudio/src/fifo/FifoBuffer.h
@@ -17,6 +17,7 @@
 #ifndef FIFO_FIFO_BUFFER_H
 #define FIFO_FIFO_BUFFER_H
 
+#include <memory>
 #include <stdint.h>
 
 #include "FifoControllerBase.h"
@@ -77,24 +78,12 @@
      */
     fifo_frames_t getEmptyRoomAvailable(WrappingBuffer *wrappingBuffer);
 
-    /**
-     * Copy data from the FIFO into the buffer.
-     * @param buffer
-     * @param numFrames
-     * @return
-     */
-    fifo_frames_t readNow(void *buffer, fifo_frames_t numFrames);
-
-    int64_t getNextReadTime(int32_t frameRate);
-
-    int32_t getUnderrunCount() const { return mUnderrunCount; }
-
-    FifoControllerBase *getFifoControllerBase() { return mFifo; }
-
     int32_t getBytesPerFrame() {
         return mBytesPerFrame;
     }
 
+    // Proxy methods for the internal FifoController
+
     fifo_counter_t getReadCounter() {
         return mFifo->getReadCounter();
     }
@@ -111,6 +100,22 @@
         mFifo->setWriteCounter(n);
     }
 
+    void advanceReadIndex(fifo_frames_t numFrames) {
+        mFifo->advanceReadIndex(numFrames);
+    }
+
+    void advanceWriteIndex(fifo_frames_t numFrames) {
+        mFifo->advanceWriteIndex(numFrames);
+    }
+
+    fifo_frames_t getEmptyFramesAvailable() {
+        return mFifo->getEmptyFramesAvailable();
+    }
+
+    fifo_frames_t getFullFramesAvailable() {
+        return mFifo->getFullFramesAvailable();
+    }
+
     /*
      * This is generally only called before or after the buffer is used.
      */
@@ -121,15 +126,12 @@
     void fillWrappingBuffer(WrappingBuffer *wrappingBuffer,
                             int32_t framesAvailable, int32_t startIndex);
 
-    const fifo_frames_t mFrameCapacity;
-    const int32_t mBytesPerFrame;
-    uint8_t *mStorage;
-    bool mStorageOwned; // did this object allocate the storage?
-    FifoControllerBase *mFifo;
-    fifo_counter_t mFramesReadCount;
-    fifo_counter_t mFramesUnderrunCount;
-    int32_t mUnderrunCount; // need? just use frames
-    int32_t mLastReadSize;
+    const int32_t             mBytesPerFrame;
+    // We do not use a std::unique_ptr for mStorage because it is often a pointer to
+    // memory shared between processes and cannot be deleted trivially.
+    uint8_t                  *mStorage = nullptr;
+    bool                      mStorageOwned = false; // did this object allocate the storage?
+    std::unique_ptr<FifoControllerBase> mFifo{};
 };
 
 }  // android
diff --git a/media/libaaudio/src/fifo/FifoController.h b/media/libaaudio/src/fifo/FifoController.h
index 79d98a1..057a94e 100644
--- a/media/libaaudio/src/fifo/FifoController.h
+++ b/media/libaaudio/src/fifo/FifoController.h
@@ -30,7 +30,7 @@
 class FifoController : public FifoControllerBase
 {
 public:
-    FifoController(fifo_counter_t bufferSize, fifo_counter_t threshold)
+    FifoController(fifo_frames_t bufferSize, fifo_frames_t threshold)
     : FifoControllerBase(bufferSize, threshold)
     , mReadCounter(0)
     , mWriteCounter(0)
diff --git a/media/libaaudio/src/fifo/FifoControllerBase.cpp b/media/libaaudio/src/fifo/FifoControllerBase.cpp
index 51a8e34..66e247f 100644
--- a/media/libaaudio/src/fifo/FifoControllerBase.cpp
+++ b/media/libaaudio/src/fifo/FifoControllerBase.cpp
@@ -59,5 +59,10 @@
 }
 
 void FifoControllerBase::setThreshold(fifo_frames_t threshold) {
+    if (threshold > mCapacity) {
+        threshold = mCapacity;
+    } else if (threshold < 0) {
+        threshold = 0;
+    }
     mThreshold = threshold;
 }
diff --git a/media/libaaudio/src/fifo/FifoControllerBase.h b/media/libaaudio/src/fifo/FifoControllerBase.h
index 64af777..1edb8a3 100644
--- a/media/libaaudio/src/fifo/FifoControllerBase.h
+++ b/media/libaaudio/src/fifo/FifoControllerBase.h
@@ -102,6 +102,9 @@
     /**
      * You can request that the buffer not be filled above a maximum
      * number of frames.
+     *
+     * The threshold will be clipped between zero and the buffer capacity.
+     *
      * @param threshold effective size of the buffer
      */
     void setThreshold(fifo_frames_t threshold);
diff --git a/media/libaaudio/src/flowgraph/AudioProcessorBase.cpp b/media/libaaudio/src/flowgraph/AudioProcessorBase.cpp
new file mode 100644
index 0000000..5667fdb
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/AudioProcessorBase.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <sys/types.h>
+#include "AudioProcessorBase.h"
+
+using namespace flowgraph;
+
+/***************************************************************************/
+int32_t AudioProcessorBase::pullData(int64_t framePosition, int32_t numFrames) {
+    if (framePosition > mLastFramePosition) {
+        mLastFramePosition = framePosition;
+        mFramesValid = onProcess(framePosition, numFrames);
+    }
+    return mFramesValid;
+}
+
+/***************************************************************************/
+AudioFloatBlockPort::AudioFloatBlockPort(AudioProcessorBase &parent,
+                               int32_t samplesPerFrame,
+                               int32_t framesPerBlock)
+        : AudioPort(parent, samplesPerFrame)
+        , mFramesPerBlock(framesPerBlock)
+        , mSampleBlock(NULL) {
+    int32_t numFloats = framesPerBlock * getSamplesPerFrame();
+    mSampleBlock = new float[numFloats]{0.0f};
+}
+
+AudioFloatBlockPort::~AudioFloatBlockPort() {
+    delete[] mSampleBlock;
+}
+
+/***************************************************************************/
+int32_t AudioFloatOutputPort::pullData(int64_t framePosition, int32_t numFrames) {
+    numFrames = std::min(getFramesPerBlock(), numFrames);
+    return mParent.pullData(framePosition, numFrames);
+}
+
+// These need to be in the .cpp file because of forward cross references.
+void AudioFloatOutputPort::connect(AudioFloatInputPort *port) {
+    port->connect(this);
+}
+
+void AudioFloatOutputPort::disconnect(AudioFloatInputPort *port) {
+    port->disconnect(this);
+}
+
+/***************************************************************************/
+int32_t AudioFloatInputPort::pullData(int64_t framePosition, int32_t numFrames) {
+    return (mConnected == NULL)
+            ? std::min(getFramesPerBlock(), numFrames)
+            : mConnected->pullData(framePosition, numFrames);
+}
+
+float *AudioFloatInputPort::getBlock() {
+    if (mConnected == NULL) {
+        return AudioFloatBlockPort::getBlock(); // loaded using setValue()
+    } else {
+        return mConnected->getBlock();
+    }
+}
+
+/***************************************************************************/
+int32_t AudioSink::pull(int32_t numFrames) {
+    int32_t actualFrames = input.pullData(mFramePosition, numFrames);
+    mFramePosition += actualFrames;
+    return actualFrames;
+}
\ No newline at end of file
diff --git a/media/libaaudio/src/flowgraph/AudioProcessorBase.h b/media/libaaudio/src/flowgraph/AudioProcessorBase.h
new file mode 100644
index 0000000..eda46ae
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/AudioProcessorBase.h
@@ -0,0 +1,293 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * AudioProcessorBase.h
+ *
+ * Audio processing node and ports that can be used in a simple data flow graph.
+ */
+
+#ifndef FLOWGRAPH_AUDIO_PROCESSOR_BASE_H
+#define FLOWGRAPH_AUDIO_PROCESSOR_BASE_H
+
+#include <cassert>
+#include <cstring>
+#include <math.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+// TODO consider publishing all header files under "include/libaaudio/FlowGraph.h"
+
+namespace flowgraph {
+
+// Default block size that can be overridden when the AudioFloatBlockPort is created.
+// If it is too small then we will have too much overhead from switching between nodes.
+// If it is too high then we will thrash the caches.
+constexpr int kDefaultBlockSize = 8; // arbitrary
+
+class AudioFloatInputPort;
+
+/***************************************************************************/
+class AudioProcessorBase {
+public:
+    virtual ~AudioProcessorBase() = default;
+
+    /**
+     * Perform custom function.
+     *
+     * @param framePosition index of first frame to be processed
+     * @param numFrames maximum number of frames requested for processing
+     * @return number of frames actually processed
+     */
+    virtual int32_t onProcess(int64_t framePosition, int32_t numFrames) = 0;
+
+    /**
+     * If the framePosition is at or after the last frame position then call onProcess().
+     * This prevents infinite recursion in case of cyclic graphs.
+     * It also prevents nodes upstream from a branch from being executed twice.
+     *
+     * @param framePosition
+     * @param numFrames
+     * @return
+     */
+    int32_t pullData(int64_t framePosition, int32_t numFrames);
+
+protected:
+    int64_t  mLastFramePosition = -1; // Start at -1 so that the first pull works.
+
+private:
+    int32_t  mFramesValid = 0; // num valid frames in the block
+};
+
+/***************************************************************************/
+/**
+  * This is a connector that allows data to flow between modules.
+  */
+class AudioPort {
+public:
+    AudioPort(AudioProcessorBase &parent, int32_t samplesPerFrame)
+            : mParent(parent)
+            , mSamplesPerFrame(samplesPerFrame) {
+    }
+
+    // Ports are often declared public. So let's make them non-copyable.
+    AudioPort(const AudioPort&) = delete;
+    AudioPort& operator=(const AudioPort&) = delete;
+
+    int32_t getSamplesPerFrame() const {
+        return mSamplesPerFrame;
+    }
+
+protected:
+    AudioProcessorBase &mParent;
+
+private:
+    const int32_t    mSamplesPerFrame = 1;
+};
+
+/***************************************************************************/
+/**
+ * This port contains a float type buffer.
+ * The size is framesPerBlock * samplesPerFrame).
+ */
+class AudioFloatBlockPort  : public AudioPort {
+public:
+    AudioFloatBlockPort(AudioProcessorBase &mParent,
+                   int32_t samplesPerFrame,
+                   int32_t framesPerBlock = kDefaultBlockSize
+                );
+
+    virtual ~AudioFloatBlockPort();
+
+    int32_t getFramesPerBlock() const {
+        return mFramesPerBlock;
+    }
+
+protected:
+
+    /**
+     * @return buffer internal to the port or from a connected port
+     */
+    virtual float *getBlock() {
+        return mSampleBlock;
+    }
+
+
+private:
+    const int32_t    mFramesPerBlock = 1;
+    float           *mSampleBlock = nullptr; // allocated in constructor
+};
+
+/***************************************************************************/
+/**
+  * The results of a module are stored in the buffer of the output ports.
+  */
+class AudioFloatOutputPort : public AudioFloatBlockPort {
+public:
+    AudioFloatOutputPort(AudioProcessorBase &parent, int32_t samplesPerFrame)
+            : AudioFloatBlockPort(parent, samplesPerFrame) {
+    }
+
+    virtual ~AudioFloatOutputPort() = default;
+
+    using AudioFloatBlockPort::getBlock;
+
+    /**
+     * Call the parent module's onProcess() method.
+     * That may pull data from its inputs and recursively
+     * process the entire graph.
+     * @return number of frames actually pulled
+     */
+    int32_t pullData(int64_t framePosition, int32_t numFrames);
+
+    /**
+     * Connect to the input of another module.
+     * An input port can only have one connection.
+     * An output port can have multiple connections.
+     * If you connect a second output port to an input port
+     * then it overwrites the previous connection.
+     *
+     * This not thread safe. Do not modify the graph topology form another thread while running.
+     */
+    void connect(AudioFloatInputPort *port);
+
+    /**
+     * Disconnect from the input of another module.
+     * This not thread safe.
+     */
+    void disconnect(AudioFloatInputPort *port);
+};
+
+/***************************************************************************/
+class AudioFloatInputPort : public AudioFloatBlockPort {
+public:
+    AudioFloatInputPort(AudioProcessorBase &parent, int32_t samplesPerFrame)
+            : AudioFloatBlockPort(parent, samplesPerFrame) {
+    }
+
+    virtual ~AudioFloatInputPort() = default;
+
+    /**
+     * If connected to an output port then this will return
+     * that output ports buffers.
+     * If not connected then it returns the input ports own buffer
+     * which can be loaded using setValue().
+     */
+    float *getBlock() override;
+
+    /**
+     * Pull data from any output port that is connected.
+     */
+    int32_t pullData(int64_t framePosition, int32_t numFrames);
+
+    /**
+     * Write every value of the float buffer.
+     * This value will be ignored if an output port is connected
+     * to this port.
+     */
+    void setValue(float value) {
+        int numFloats = kDefaultBlockSize * getSamplesPerFrame();
+        float *buffer = getBlock();
+        for (int i = 0; i < numFloats; i++) {
+            *buffer++ = value;
+        }
+    }
+
+    /**
+     * Connect to the output of another module.
+     * An input port can only have one connection.
+     * An output port can have multiple connections.
+     * This not thread safe.
+     */
+    void connect(AudioFloatOutputPort *port) {
+        assert(getSamplesPerFrame() == port->getSamplesPerFrame());
+        mConnected = port;
+    }
+
+    void disconnect(AudioFloatOutputPort *port) {
+        assert(mConnected == port);
+        (void) port;
+        mConnected = nullptr;
+    }
+
+    void disconnect() {
+        mConnected = nullptr;
+    }
+
+private:
+    AudioFloatOutputPort *mConnected = nullptr;
+};
+
+/***************************************************************************/
+class AudioSource : public AudioProcessorBase {
+public:
+    explicit AudioSource(int32_t channelCount)
+            : output(*this, channelCount) {
+    }
+
+    virtual ~AudioSource() = default;
+
+    AudioFloatOutputPort output;
+
+    void setData(const void *data, int32_t numFrames) {
+        mData = data;
+        mSizeInFrames = numFrames;
+        mFrameIndex = 0;
+    }
+
+protected:
+    const void *mData = nullptr;
+    int32_t     mSizeInFrames = 0; // number of frames in mData
+    int32_t     mFrameIndex = 0; // index of next frame to be processed
+};
+
+/***************************************************************************/
+class AudioSink : public AudioProcessorBase {
+public:
+    explicit AudioSink(int32_t channelCount)
+            : input(*this, channelCount) {
+    }
+
+    virtual ~AudioSink() = default;
+
+    AudioFloatInputPort input;
+
+    /**
+     * Dummy processor. The work happens in the read() method.
+     *
+     * @param framePosition index of first frame to be processed
+     * @param numFrames
+     * @return number of frames actually processed
+     */
+    int32_t onProcess(int64_t framePosition, int32_t numFrames) override {
+        (void) framePosition;
+        (void) numFrames;
+        return 0;
+    };
+
+    virtual int32_t read(void *data, int32_t numFrames) = 0;
+
+protected:
+    int32_t pull(int32_t numFrames);
+
+private:
+    int64_t mFramePosition = 0;
+};
+
+} /* namespace flowgraph */
+
+#endif /* FLOWGRAPH_AUDIO_PROCESSOR_BASE_H */
diff --git a/media/libaaudio/src/flowgraph/ClipToRange.cpp b/media/libaaudio/src/flowgraph/ClipToRange.cpp
new file mode 100644
index 0000000..bd9c22a
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/ClipToRange.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <unistd.h>
+#include "AudioProcessorBase.h"
+#include "ClipToRange.h"
+
+using namespace flowgraph;
+
+ClipToRange::ClipToRange(int32_t channelCount)
+        : input(*this, channelCount)
+        , output(*this, channelCount) {
+}
+
+int32_t ClipToRange::onProcess(int64_t framePosition, int32_t numFrames) {
+    int32_t framesToProcess = input.pullData(framePosition, numFrames);
+    const float *inputBuffer = input.getBlock();
+    float *outputBuffer = output.getBlock();
+
+    int32_t numSamples = framesToProcess * output.getSamplesPerFrame();
+    for (int32_t i = 0; i < numSamples; i++) {
+        *outputBuffer++ = std::min(mMaximum, std::max(mMinimum, *inputBuffer++));
+    }
+
+    return framesToProcess;
+}
diff --git a/media/libaaudio/src/flowgraph/ClipToRange.h b/media/libaaudio/src/flowgraph/ClipToRange.h
new file mode 100644
index 0000000..9eef254
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/ClipToRange.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FLOWGRAPH_CLIP_TO_RANGE_H
+#define FLOWGRAPH_CLIP_TO_RANGE_H
+
+#include <atomic>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "AudioProcessorBase.h"
+
+namespace flowgraph {
+
+// This is 3 dB, (10^(3/20)), to match the maximum headroom in AudioTrack for float data.
+// It is designed to allow occasional transient peaks.
+constexpr float kDefaultMaxHeadroom = 1.41253754f;
+constexpr float kDefaultMinHeadroom = -kDefaultMaxHeadroom;
+
+class ClipToRange : public AudioProcessorBase {
+public:
+    explicit ClipToRange(int32_t channelCount);
+
+    virtual ~ClipToRange() = default;
+
+    int32_t onProcess(int64_t framePosition, int32_t numFrames) override;
+
+    void setMinimum(float min) {
+        mMinimum = min;
+    }
+
+    float getMinimum() const {
+        return mMinimum;
+    }
+
+    void setMaximum(float min) {
+        mMaximum = min;
+    }
+
+    float getMaximum() const {
+        return mMaximum;
+    }
+
+    AudioFloatInputPort input;
+    AudioFloatOutputPort output;
+
+private:
+    float mMinimum = kDefaultMinHeadroom;
+    float mMaximum = kDefaultMaxHeadroom;
+};
+
+} /* namespace flowgraph */
+
+#endif //FLOWGRAPH_CLIP_TO_RANGE_H
diff --git a/media/libaaudio/src/flowgraph/MonoToMultiConverter.cpp b/media/libaaudio/src/flowgraph/MonoToMultiConverter.cpp
new file mode 100644
index 0000000..78aad52
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/MonoToMultiConverter.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <unistd.h>
+#include "AudioProcessorBase.h"
+#include "MonoToMultiConverter.h"
+
+using namespace flowgraph;
+
+MonoToMultiConverter::MonoToMultiConverter(int32_t channelCount)
+        : input(*this, 1)
+        , output(*this, channelCount) {
+}
+
+MonoToMultiConverter::~MonoToMultiConverter() { }
+
+int32_t MonoToMultiConverter::onProcess(int64_t framePosition, int32_t numFrames) {
+    int32_t framesToProcess = input.pullData(framePosition, numFrames);
+
+    const float *inputBuffer = input.getBlock();
+    float *outputBuffer = output.getBlock();
+    int32_t channelCount = output.getSamplesPerFrame();
+    // TODO maybe move to audio_util as audio_mono_to_multi()
+    for (int i = 0; i < framesToProcess; i++) {
+        // read one, write many
+        float sample = *inputBuffer++;
+        for (int channel = 0; channel < channelCount; channel++) {
+            *outputBuffer++ = sample;
+        }
+    }
+    return framesToProcess;
+}
+
diff --git a/media/libaaudio/src/flowgraph/MonoToMultiConverter.h b/media/libaaudio/src/flowgraph/MonoToMultiConverter.h
new file mode 100644
index 0000000..34d53c7
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/MonoToMultiConverter.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef FLOWGRAPH_MONO_TO_MULTI_CONVERTER_H
+#define FLOWGRAPH_MONO_TO_MULTI_CONVERTER_H
+
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "AudioProcessorBase.h"
+
+namespace flowgraph {
+
+class MonoToMultiConverter : public AudioProcessorBase {
+public:
+    explicit MonoToMultiConverter(int32_t channelCount);
+
+    virtual ~MonoToMultiConverter();
+
+    int32_t onProcess(int64_t framePosition, int32_t numFrames) override;
+
+    AudioFloatInputPort input;
+    AudioFloatOutputPort output;
+};
+
+} /* namespace flowgraph */
+
+#endif //FLOWGRAPH_MONO_TO_MULTI_CONVERTER_H
diff --git a/media/libaaudio/src/flowgraph/RampLinear.cpp b/media/libaaudio/src/flowgraph/RampLinear.cpp
new file mode 100644
index 0000000..a260828
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/RampLinear.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "RampLinear"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+#include <algorithm>
+#include <unistd.h>
+#include "AudioProcessorBase.h"
+#include "RampLinear.h"
+
+using namespace flowgraph;
+
+RampLinear::RampLinear(int32_t channelCount)
+        : input(*this, channelCount)
+        , output(*this, channelCount) {
+    mTarget.store(1.0f);
+}
+
+void RampLinear::setLengthInFrames(int32_t frames) {
+    mLengthInFrames = frames;
+}
+
+void RampLinear::setTarget(float target) {
+    mTarget.store(target);
+}
+
+float RampLinear::interpolateCurrent() {
+    return mLevelTo - (mRemaining * mScaler);
+}
+
+int32_t RampLinear::onProcess(int64_t framePosition, int32_t numFrames) {
+    int32_t framesToProcess = input.pullData(framePosition, numFrames);
+    const float *inputBuffer = input.getBlock();
+    float *outputBuffer = output.getBlock();
+    int32_t channelCount = output.getSamplesPerFrame();
+
+    float target = getTarget();
+    if (target != mLevelTo) {
+        // Start new ramp. Continue from previous level.
+        mLevelFrom = interpolateCurrent();
+        mLevelTo = target;
+        mRemaining = mLengthInFrames;
+        ALOGV("%s() mLevelFrom = %f, mLevelTo = %f, mRemaining = %d, mScaler = %f",
+              __func__, mLevelFrom, mLevelTo, mRemaining, mScaler);
+        mScaler = (mLevelTo - mLevelFrom) / mLengthInFrames; // for interpolation
+    }
+
+    int32_t framesLeft = framesToProcess;
+
+    if (mRemaining > 0) { // Ramping? This doesn't happen very often.
+        int32_t framesToRamp = std::min(framesLeft, mRemaining);
+        framesLeft -= framesToRamp;
+        while (framesToRamp > 0) {
+            float currentLevel = interpolateCurrent();
+            for (int ch = 0; ch < channelCount; ch++) {
+                *outputBuffer++ = *inputBuffer++ * currentLevel;
+            }
+            mRemaining--;
+            framesToRamp--;
+        }
+    }
+
+    // Process any frames after the ramp.
+    int32_t samplesLeft = framesLeft * channelCount;
+    for (int i = 0; i < samplesLeft; i++) {
+        *outputBuffer++ = *inputBuffer++ * mLevelTo;
+    }
+
+    return framesToProcess;
+}
diff --git a/media/libaaudio/src/flowgraph/RampLinear.h b/media/libaaudio/src/flowgraph/RampLinear.h
new file mode 100644
index 0000000..bdc8f41
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/RampLinear.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FLOWGRAPH_RAMP_LINEAR_H
+#define FLOWGRAPH_RAMP_LINEAR_H
+
+#include <atomic>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "AudioProcessorBase.h"
+
+namespace flowgraph {
+
+class RampLinear : public AudioProcessorBase {
+public:
+    explicit RampLinear(int32_t channelCount);
+
+    virtual ~RampLinear() = default;
+
+    int32_t onProcess(int64_t framePosition, int32_t numFrames) override;
+
+    /**
+     * This is used for the next ramp.
+     * Calling this does not affect a ramp that is in progress.
+     */
+    void setLengthInFrames(int32_t frames);
+
+    int32_t getLengthInFrames() const {
+        return mLengthInFrames;
+    }
+
+    /**
+     * This may be safely called by another thread.
+     * @param target
+     */
+    void setTarget(float target);
+
+    float getTarget() const {
+        return mTarget.load();
+    }
+
+    /**
+     * Force the nextSegment to start from this level.
+     *
+     * WARNING: this can cause a discontinuity if called while the ramp is being used.
+     * Only call this when setting the initial ramp.
+     *
+     * @param level
+     */
+    void forceCurrent(float level) {
+        mLevelFrom = level;
+        mLevelTo = level;
+    }
+
+    AudioFloatInputPort input;
+    AudioFloatOutputPort output;
+
+private:
+
+    float interpolateCurrent();
+
+    std::atomic<float>  mTarget;
+
+    int32_t             mLengthInFrames  = 48000.0f / 100.0f ; // 10 msec at 48000 Hz;
+    int32_t             mRemaining       = 0;
+    float               mScaler          = 0.0f;
+    float               mLevelFrom       = 0.0f;
+    float               mLevelTo         = 0.0f;
+};
+
+} /* namespace flowgraph */
+
+#endif //FLOWGRAPH_RAMP_LINEAR_H
diff --git a/media/libaaudio/src/flowgraph/SinkFloat.cpp b/media/libaaudio/src/flowgraph/SinkFloat.cpp
new file mode 100644
index 0000000..fb3dcbc
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/SinkFloat.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <unistd.h>
+#include "AudioProcessorBase.h"
+#include "SinkFloat.h"
+
+using namespace flowgraph;
+
+SinkFloat::SinkFloat(int32_t channelCount)
+        : AudioSink(channelCount) {
+}
+
+int32_t SinkFloat::read(void *data, int32_t numFrames) {
+    float *floatData = (float *) data;
+    int32_t channelCount = input.getSamplesPerFrame();
+
+    int32_t framesLeft = numFrames;
+    while (framesLeft > 0) {
+        // Run the graph and pull data through the input port.
+        int32_t framesRead = pull(framesLeft);
+        if (framesRead <= 0) {
+            break;
+        }
+        const float *signal = input.getBlock();
+        int32_t numSamples = framesRead * channelCount;
+        memcpy(floatData, signal, numSamples * sizeof(float));
+        floatData += numSamples;
+        framesLeft -= framesRead;
+    }
+    return numFrames - framesLeft;
+}
diff --git a/media/libaaudio/src/flowgraph/SinkFloat.h b/media/libaaudio/src/flowgraph/SinkFloat.h
new file mode 100644
index 0000000..7775c08
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/SinkFloat.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef FLOWGRAPH_SINK_FLOAT_H
+#define FLOWGRAPH_SINK_FLOAT_H
+
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "AudioProcessorBase.h"
+
+namespace flowgraph {
+
+class SinkFloat : public AudioSink {
+public:
+    explicit SinkFloat(int32_t channelCount);
+
+    int32_t read(void *data, int32_t numFrames) override;
+
+};
+
+} /* namespace flowgraph */
+
+#endif //FLOWGRAPH_SINK_FLOAT_H
diff --git a/media/libaaudio/src/flowgraph/SinkI16.cpp b/media/libaaudio/src/flowgraph/SinkI16.cpp
new file mode 100644
index 0000000..ffec8f5
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/SinkI16.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <unistd.h>
+
+#ifdef __ANDROID__
+#include <audio_utils/primitives.h>
+#endif
+
+#include "AudioProcessorBase.h"
+#include "SinkI16.h"
+
+using namespace flowgraph;
+
+SinkI16::SinkI16(int32_t channelCount)
+        : AudioSink(channelCount) {}
+
+int32_t SinkI16::read(void *data, int32_t numFrames) {
+    int16_t *shortData = (int16_t *) data;
+    const int32_t channelCount = input.getSamplesPerFrame();
+
+    int32_t framesLeft = numFrames;
+    while (framesLeft > 0) {
+        // Run the graph and pull data through the input port.
+        int32_t framesRead = pull(framesLeft);
+        if (framesRead <= 0) {
+            break;
+        }
+        const float *signal = input.getBlock();
+        int32_t numSamples = framesRead * channelCount;
+#ifdef __ANDROID__
+        memcpy_to_i16_from_float(shortData, signal, numSamples);
+        shortData += numSamples;
+        signal += numSamples;
+#else
+        for (int i = 0; i < numSamples; i++) {
+            int32_t n = (int32_t) (*signal++ * 32768.0f);
+            *shortData++ = std::min(INT16_MAX, std::max(INT16_MIN, n)); // clip
+        }
+#endif
+        framesLeft -= framesRead;
+    }
+    return numFrames - framesLeft;
+}
diff --git a/media/libaaudio/src/flowgraph/SinkI16.h b/media/libaaudio/src/flowgraph/SinkI16.h
new file mode 100644
index 0000000..6d86266
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/SinkI16.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FLOWGRAPH_SINK_I16_H
+#define FLOWGRAPH_SINK_I16_H
+
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "AudioProcessorBase.h"
+
+namespace flowgraph {
+
+class SinkI16 : public AudioSink {
+public:
+    explicit SinkI16(int32_t channelCount);
+
+    int32_t read(void *data, int32_t numFrames) override;
+};
+
+} /* namespace flowgraph */
+
+#endif //FLOWGRAPH_SINK_I16_H
diff --git a/media/libaaudio/src/flowgraph/SinkI24.cpp b/media/libaaudio/src/flowgraph/SinkI24.cpp
new file mode 100644
index 0000000..6592828
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/SinkI24.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <unistd.h>
+
+#ifdef __ANDROID__
+#include <audio_utils/primitives.h>
+#endif
+
+#include "AudioProcessorBase.h"
+#include "SinkI24.h"
+
+using namespace flowgraph;
+
+
+SinkI24::SinkI24(int32_t channelCount)
+        : AudioSink(channelCount) {}
+
+int32_t SinkI24::read(void *data, int32_t numFrames) {
+    uint8_t *byteData = (uint8_t *) data;
+    const int32_t channelCount = input.getSamplesPerFrame();
+
+    int32_t framesLeft = numFrames;
+    while (framesLeft > 0) {
+        // Run the graph and pull data through the input port.
+        int32_t framesRead = pull(framesLeft);
+        if (framesRead <= 0) {
+            break;
+        }
+        const float *floatData = input.getBlock();
+        int32_t numSamples = framesRead * channelCount;
+#ifdef __ANDROID__
+        memcpy_to_p24_from_float(byteData, floatData, numSamples);
+        static const int kBytesPerI24Packed = 3;
+        byteData += numSamples * kBytesPerI24Packed;
+        floatData += numSamples;
+#else
+        const int32_t kI24PackedMax = 0x007FFFFF;
+        const int32_t kI24PackedMin = 0xFF800000;
+        for (int i = 0; i < numSamples; i++) {
+            int32_t n = (int32_t) (*floatData++ * 0x00800000);
+            n = std::min(kI24PackedMax, std::max(kI24PackedMin, n)); // clip
+            // Write as a packed 24-bit integer in Little Endian format.
+            *byteData++ = (uint8_t) n;
+            *byteData++ = (uint8_t) (n >> 8);
+            *byteData++ = (uint8_t) (n >> 16);
+        }
+#endif
+        framesLeft -= framesRead;
+    }
+    return numFrames - framesLeft;
+}
diff --git a/media/libaaudio/src/flowgraph/SinkI24.h b/media/libaaudio/src/flowgraph/SinkI24.h
new file mode 100644
index 0000000..5b9b505
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/SinkI24.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FLOWGRAPH_SINK_I24_H
+#define FLOWGRAPH_SINK_I24_H
+
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "AudioProcessorBase.h"
+
+namespace flowgraph {
+
+class SinkI24 : public AudioSink {
+public:
+    explicit SinkI24(int32_t channelCount);
+
+    int32_t read(void *data, int32_t numFrames) override;
+};
+
+} /* namespace flowgraph */
+
+#endif //FLOWGRAPH_SINK_I24_H
diff --git a/media/libaaudio/src/flowgraph/SourceFloat.cpp b/media/libaaudio/src/flowgraph/SourceFloat.cpp
new file mode 100644
index 0000000..4bb674f
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/SourceFloat.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <unistd.h>
+#include "AudioProcessorBase.h"
+#include "SourceFloat.h"
+
+using namespace flowgraph;
+
+SourceFloat::SourceFloat(int32_t channelCount)
+        : AudioSource(channelCount) {
+}
+
+int32_t SourceFloat::onProcess(int64_t framePosition, int32_t numFrames) {
+
+    float *outputBuffer = output.getBlock();
+    int32_t channelCount = output.getSamplesPerFrame();
+
+    int32_t framesLeft = mSizeInFrames - mFrameIndex;
+    int32_t framesToProcess = std::min(numFrames, framesLeft);
+    int32_t numSamples = framesToProcess * channelCount;
+
+    const float *floatBase = (float *) mData;
+    const float *floatData = &floatBase[mFrameIndex * channelCount];
+    memcpy(outputBuffer, floatData, numSamples * sizeof(float));
+    mFrameIndex += framesToProcess;
+    return framesToProcess;
+}
+
diff --git a/media/libaaudio/src/flowgraph/SourceFloat.h b/media/libaaudio/src/flowgraph/SourceFloat.h
new file mode 100644
index 0000000..e6eed9f
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/SourceFloat.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FLOWGRAPH_SOURCE_FLOAT_H
+#define FLOWGRAPH_SOURCE_FLOAT_H
+
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "AudioProcessorBase.h"
+
+namespace flowgraph {
+
+class SourceFloat : public AudioSource {
+public:
+    explicit SourceFloat(int32_t channelCount);
+
+    int32_t onProcess(int64_t framePosition, int32_t numFrames) override;
+};
+
+} /* namespace flowgraph */
+
+#endif //FLOWGRAPH_SOURCE_FLOAT_H
diff --git a/media/libaaudio/src/flowgraph/SourceI16.cpp b/media/libaaudio/src/flowgraph/SourceI16.cpp
new file mode 100644
index 0000000..c3fcec2
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/SourceI16.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <unistd.h>
+
+#ifdef __ANDROID__
+#include <audio_utils/primitives.h>
+#endif
+
+#include "AudioProcessorBase.h"
+#include "SourceI16.h"
+
+using namespace flowgraph;
+
+SourceI16::SourceI16(int32_t channelCount)
+        : AudioSource(channelCount) {
+}
+
+int32_t SourceI16::onProcess(int64_t framePosition, int32_t numFrames) {
+    float *floatData = output.getBlock();
+    int32_t channelCount = output.getSamplesPerFrame();
+
+    int32_t framesLeft = mSizeInFrames - mFrameIndex;
+    int32_t framesToProcess = std::min(numFrames, framesLeft);
+    int32_t numSamples = framesToProcess * channelCount;
+
+    const int16_t *shortBase = static_cast<const int16_t *>(mData);
+    const int16_t *shortData = &shortBase[mFrameIndex * channelCount];
+
+#ifdef __ANDROID__
+    memcpy_to_float_from_i16(floatData, shortData, numSamples);
+#else
+    for (int i = 0; i < numSamples; i++) {
+        *floatData++ = *shortData++ * (1.0f / 32768);
+    }
+#endif
+
+    mFrameIndex += framesToProcess;
+    return framesToProcess;
+}
\ No newline at end of file
diff --git a/media/libaaudio/src/flowgraph/SourceI16.h b/media/libaaudio/src/flowgraph/SourceI16.h
new file mode 100644
index 0000000..2b116cf
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/SourceI16.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FLOWGRAPH_SOURCE_I16_H
+#define FLOWGRAPH_SOURCE_I16_H
+
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "AudioProcessorBase.h"
+
+namespace flowgraph {
+
+class SourceI16 : public AudioSource {
+public:
+    explicit SourceI16(int32_t channelCount);
+
+    int32_t onProcess(int64_t framePosition, int32_t numFrames) override;
+};
+
+} /* namespace flowgraph */
+
+#endif //FLOWGRAPH_SOURCE_I16_H
diff --git a/media/libaaudio/src/flowgraph/SourceI24.cpp b/media/libaaudio/src/flowgraph/SourceI24.cpp
new file mode 100644
index 0000000..f319880
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/SourceI24.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <unistd.h>
+
+#ifdef __ANDROID__
+#include <audio_utils/primitives.h>
+#endif
+
+#include "AudioProcessorBase.h"
+#include "SourceI24.h"
+
+using namespace flowgraph;
+
+constexpr int kBytesPerI24Packed = 3;
+
+SourceI24::SourceI24(int32_t channelCount)
+        : AudioSource(channelCount) {
+}
+
+int32_t SourceI24::onProcess(int64_t framePosition, int32_t numFrames) {
+    float *floatData = output.getBlock();
+    int32_t channelCount = output.getSamplesPerFrame();
+
+    int32_t framesLeft = mSizeInFrames - mFrameIndex;
+    int32_t framesToProcess = std::min(numFrames, framesLeft);
+    int32_t numSamples = framesToProcess * channelCount;
+
+    const uint8_t *byteBase = (uint8_t *) mData;
+    const uint8_t *byteData = &byteBase[mFrameIndex * channelCount * kBytesPerI24Packed];
+
+#ifdef __ANDROID__
+    memcpy_to_float_from_p24(floatData, byteData, numSamples);
+#else
+    static const float scale = 1. / (float)(1UL << 31);
+    for (int i = 0; i < numSamples; i++) {
+        // Assemble the data assuming Little Endian format.
+        int32_t pad = byteData[2];
+        pad <<= 8;
+        pad |= byteData[1];
+        pad <<= 8;
+        pad |= byteData[0];
+        pad <<= 8; // Shift to 32 bit data so the sign is correct.
+        byteData += kBytesPerI24Packed;
+        *floatData++ = pad * scale; // scale to range -1.0 to 1.0
+    }
+#endif
+
+    mFrameIndex += framesToProcess;
+    return framesToProcess;
+}
\ No newline at end of file
diff --git a/media/libaaudio/src/flowgraph/SourceI24.h b/media/libaaudio/src/flowgraph/SourceI24.h
new file mode 100644
index 0000000..39f14da
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/SourceI24.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FLOWGRAPH_SOURCE_I24_H
+#define FLOWGRAPH_SOURCE_I24_H
+
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "AudioProcessorBase.h"
+
+namespace flowgraph {
+
+class SourceI24 : public AudioSource {
+public:
+    explicit SourceI24(int32_t channelCount);
+
+    int32_t onProcess(int64_t framePosition, int32_t numFrames) override;
+};
+
+} /* namespace flowgraph */
+
+#endif //FLOWGRAPH_SOURCE_I24_H
diff --git a/media/libaaudio/src/legacy/AudioStreamLegacy.cpp b/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
index a6b9f5d..91d2eff 100644
--- a/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
@@ -78,8 +78,9 @@
 
 void AudioStreamLegacy::processCallbackCommon(aaudio_callback_operation_t opcode, void *info) {
     aaudio_data_callback_result_t callbackResult;
-    // This illegal size can be used to tell AudioFlinger to stop calling us.
-    // This takes advantage of AudioFlinger killing the stream.
+    // This illegal size can be used to tell AudioRecord or AudioTrack to stop calling us.
+    // This takes advantage of them killing the stream when they see a size out of range.
+    // That is an undocumented behavior.
     // TODO add to API in AudioRecord and AudioTrack
     const size_t SIZE_STOP_CALLBACKS = SIZE_MAX;
 
@@ -95,7 +96,7 @@
                 ALOGW("processCallbackCommon() data, stream disconnected");
                 audioBuffer->size = SIZE_STOP_CALLBACKS;
             } else if (!mCallbackEnabled.load()) {
-                ALOGW("processCallbackCommon() stopping because callback disabled");
+                ALOGW("processCallbackCommon() no data because callback disabled");
                 audioBuffer->size = SIZE_STOP_CALLBACKS;
             } else {
                 if (audioBuffer->frameCount == 0) {
@@ -115,10 +116,16 @@
                 }
                 if (callbackResult == AAUDIO_CALLBACK_RESULT_CONTINUE) {
                     audioBuffer->size = audioBuffer->frameCount * getBytesPerDeviceFrame();
-                } else { // STOP or invalid result
-                    ALOGW("%s() callback requested stop, fake an error", __func__);
-                    audioBuffer->size = SIZE_STOP_CALLBACKS;
-                    // Disable the callback just in case AudioFlinger keeps trying to call us.
+                } else {
+                    if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
+                        ALOGD("%s() callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
+                    } else {
+                        ALOGW("%s() callback returned invalid result = %d",
+                              __func__, callbackResult);
+                    }
+                    audioBuffer->size = 0;
+                    systemStopFromCallback();
+                    // Disable the callback just in case the system keeps trying to call us.
                     mCallbackEnabled.store(false);
                 }
 
@@ -199,7 +206,9 @@
 
 void AudioStreamLegacy::onAudioDeviceUpdate(audio_port_handle_t deviceId)
 {
-    ALOGD("onAudioDeviceUpdate() deviceId %d", (int)deviceId);
+    // Device routing is a common source of errors and DISCONNECTS.
+    // Please leave this log in place.
+    ALOGD("%s() devId %d => %d", __func__, (int) getDeviceId(), (int)deviceId);
     if (getDeviceId() != AAUDIO_UNSPECIFIED && getDeviceId() != deviceId &&
             getState() != AAUDIO_STREAM_STATE_DISCONNECTED) {
         // Note that isDataCallbackActive() is affected by state so call it before DISCONNECTING.
diff --git a/media/libaaudio/src/legacy/AudioStreamLegacy.h b/media/libaaudio/src/legacy/AudioStreamLegacy.h
index 494edbc..8e78554 100644
--- a/media/libaaudio/src/legacy/AudioStreamLegacy.h
+++ b/media/libaaudio/src/legacy/AudioStreamLegacy.h
@@ -77,7 +77,6 @@
 
     virtual int64_t incrementClientFrameCounter(int32_t frames)  = 0;
 
-
     virtual int64_t getFramesWritten() override {
         return mFramesWritten.get();
     }
diff --git a/media/libaaudio/src/legacy/AudioStreamRecord.cpp b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
index 505f2ee..71efc30 100644
--- a/media/libaaudio/src/legacy/AudioStreamRecord.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
@@ -57,32 +57,41 @@
 
     // Try to create an AudioRecord
 
+    const aaudio_session_id_t requestedSessionId = builder.getSessionId();
+    const audio_session_t sessionId = AAudioConvert_aaudioToAndroidSessionId(requestedSessionId);
+
     // TODO Support UNSPECIFIED in AudioRecord. For now, use stereo if unspecified.
     int32_t samplesPerFrame = (getSamplesPerFrame() == AAUDIO_UNSPECIFIED)
                               ? 2 : getSamplesPerFrame();
-    audio_channel_mask_t channelMask = audio_channel_in_mask_from_count(samplesPerFrame);
+    audio_channel_mask_t channelMask = samplesPerFrame <= 2 ?
+                               audio_channel_in_mask_from_count(samplesPerFrame) :
+                               audio_channel_mask_for_index_assignment_from_count(samplesPerFrame);
 
     size_t frameCount = (builder.getBufferCapacity() == AAUDIO_UNSPECIFIED) ? 0
                         : builder.getBufferCapacity();
 
 
-    audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE;
+    audio_input_flags_t flags;
     aaudio_performance_mode_t perfMode = getPerformanceMode();
     switch (perfMode) {
         case AAUDIO_PERFORMANCE_MODE_LOW_LATENCY:
-            flags = (audio_input_flags_t) (AUDIO_INPUT_FLAG_FAST | AUDIO_INPUT_FLAG_RAW);
+            // If the app asks for a sessionId then it means they want to use effects.
+            // So don't use RAW flag.
+            flags = (audio_input_flags_t) ((requestedSessionId == AAUDIO_SESSION_ID_NONE)
+                    ? (AUDIO_INPUT_FLAG_FAST | AUDIO_INPUT_FLAG_RAW)
+                    : (AUDIO_INPUT_FLAG_FAST));
             break;
 
         case AAUDIO_PERFORMANCE_MODE_POWER_SAVING:
         case AAUDIO_PERFORMANCE_MODE_NONE:
         default:
-            // No flags.
+            flags = AUDIO_INPUT_FLAG_NONE;
             break;
     }
 
     // Preserve behavior of API 26
-    if (getFormat() == AAUDIO_FORMAT_UNSPECIFIED) {
-        setFormat(AAUDIO_FORMAT_PCM_FLOAT);
+    if (getFormat() == AUDIO_FORMAT_DEFAULT) {
+        setFormat(AUDIO_FORMAT_PCM_FLOAT);
     }
 
     // Maybe change device format to get a FAST path.
@@ -99,12 +108,12 @@
     // We just may not get a FAST track.
     // But we wouldn't have anyway without this hack.
     constexpr int32_t kMostLikelySampleRateForFast = 48000;
-    if (getFormat() == AAUDIO_FORMAT_PCM_FLOAT
+    if (getFormat() == AUDIO_FORMAT_PCM_FLOAT
             && perfMode == AAUDIO_PERFORMANCE_MODE_LOW_LATENCY
             && (samplesPerFrame <= 2) // FAST only for mono and stereo
             && (getSampleRate() == kMostLikelySampleRateForFast
                 || getSampleRate() == AAUDIO_UNSPECIFIED)) {
-        setDeviceFormat(AAUDIO_FORMAT_PCM_I16);
+        setDeviceFormat(AUDIO_FORMAT_PCM_16_BIT);
     } else {
         setDeviceFormat(getFormat());
     }
@@ -141,14 +150,10 @@
             .tags = ""
     };
 
-    aaudio_session_id_t requestedSessionId = builder.getSessionId();
-    audio_session_t sessionId = AAudioConvert_aaudioToAndroidSessionId(requestedSessionId);
-
     // ----------- open the AudioRecord ---------------------
     // Might retry, but never more than once.
     for (int i = 0; i < 2; i ++) {
-        audio_format_t requestedInternalFormat =
-                AAudioConvert_aaudioToAndroidDataFormat(getDeviceFormat());
+        const audio_format_t requestedInternalFormat = getDeviceFormat();
 
         mAudioRecord = new AudioRecord(
                 mOpPackageName // const String16& opPackageName TODO does not compile
@@ -214,8 +219,8 @@
     }
 
     // Allocate format conversion buffer if needed.
-    if (getDeviceFormat() == AAUDIO_FORMAT_PCM_I16
-        && getFormat() == AAUDIO_FORMAT_PCM_FLOAT) {
+    if (getDeviceFormat() == AUDIO_FORMAT_PCM_16_BIT
+        && getFormat() == AUDIO_FORMAT_PCM_FLOAT) {
 
         if (builder.getDataCallbackProc() != nullptr) {
             // If we have a callback then we need to convert the data into an internal float
@@ -323,16 +328,13 @@
     if (mAudioRecord.get() == nullptr) {
         return AAUDIO_ERROR_INVALID_STATE;
     }
-    // Get current position so we can detect when the track is recording.
-    status_t err = mAudioRecord->getPosition(&mPositionWhenStarting);
-    if (err != OK) {
-        return AAudioConvert_androidToAAudioResult(err);
-    }
 
-    // Enable callback before starting AudioTrack to avoid shutting
+    // Enable callback before starting AudioRecord to avoid shutting
     // down because of a race condition.
     mCallbackEnabled.store(true);
-    err = mAudioRecord->start();
+    mFramesWritten.reset32(); // service writes frames
+    mTimestampPosition.reset32();
+    status_t err = mAudioRecord->start(); // resets position to zero
     if (err != OK) {
         return AAudioConvert_androidToAAudioResult(err);
     } else {
@@ -346,12 +348,10 @@
         return AAUDIO_ERROR_INVALID_STATE;
     }
     setState(AAUDIO_STREAM_STATE_STOPPING);
-    incrementFramesWritten(getFramesRead() - getFramesWritten()); // TODO review
-    mTimestampPosition.set(getFramesRead());
+    mFramesWritten.catchUpTo(getFramesRead());
+    mTimestampPosition.catchUpTo(getFramesRead());
     mAudioRecord->stop();
     mCallbackEnabled.store(false);
-    mFramesWritten.reset32(); // service writes frames, service position reset on flush
-    mTimestampPosition.reset32();
     // Pass false to prevent errorCallback from being called after disconnect
     // when app has already requested a stop().
     return checkForDisconnectRequest(false);
@@ -365,10 +365,12 @@
     switch (getState()) {
     // TODO add better state visibility to AudioRecord
     case AAUDIO_STREAM_STATE_STARTING:
+        // When starting, the position will begin at zero and then go positive.
+        // The position can wrap but by that time the state will not be STARTING.
         err = mAudioRecord->getPosition(&position);
         if (err != OK) {
             result = AAudioConvert_androidToAAudioResult(err);
-        } else if (position != mPositionWhenStarting) {
+        } else if (position > 0) {
             setState(AAUDIO_STREAM_STATE_STARTED);
         }
         break;
@@ -483,6 +485,9 @@
                                                int64_t *framePosition,
                                                int64_t *timeNanoseconds) {
     ExtendedTimestamp extendedTimestamp;
+    if (getState() != AAUDIO_STREAM_STATE_STARTED) {
+        return AAUDIO_ERROR_INVALID_STATE;
+    }
     status_t status = mAudioRecord->getTimestamp(&extendedTimestamp);
     if (status == WOULD_BLOCK) {
         return AAUDIO_ERROR_INVALID_STATE;
@@ -498,12 +503,12 @@
     switch (getState()) {
         case AAUDIO_STREAM_STATE_STARTING:
         case AAUDIO_STREAM_STATE_STARTED:
-        case AAUDIO_STREAM_STATE_STOPPING:
             result = mAudioRecord->getPosition(&position);
             if (result == OK) {
                 mFramesWritten.update32(position);
             }
             break;
+        case AAUDIO_STREAM_STATE_STOPPING:
         default:
             break;
     }
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index 505cd77..094cdd1 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -59,18 +59,27 @@
         return result;
     }
 
+    const aaudio_session_id_t requestedSessionId = builder.getSessionId();
+    const audio_session_t sessionId = AAudioConvert_aaudioToAndroidSessionId(requestedSessionId);
+
     // Try to create an AudioTrack
     // Use stereo if unspecified.
     int32_t samplesPerFrame = (getSamplesPerFrame() == AAUDIO_UNSPECIFIED)
                               ? 2 : getSamplesPerFrame();
-    audio_channel_mask_t channelMask = audio_channel_out_mask_from_count(samplesPerFrame);
+    audio_channel_mask_t channelMask = samplesPerFrame <= 2 ?
+                            audio_channel_out_mask_from_count(samplesPerFrame) :
+                            audio_channel_mask_for_index_assignment_from_count(samplesPerFrame);
 
-    audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE;
+    audio_output_flags_t flags;
     aaudio_performance_mode_t perfMode = getPerformanceMode();
     switch(perfMode) {
         case AAUDIO_PERFORMANCE_MODE_LOW_LATENCY:
             // Bypass the normal mixer and go straight to the FAST mixer.
-            flags = (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_RAW);
+            // If the app asks for a sessionId then it means they want to use effects.
+            // So don't use RAW flag.
+            flags = (audio_output_flags_t) ((requestedSessionId == AAUDIO_SESSION_ID_NONE)
+                    ? (AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_RAW)
+                    : (AUDIO_OUTPUT_FLAG_FAST));
             break;
 
         case AAUDIO_PERFORMANCE_MODE_POWER_SAVING:
@@ -81,6 +90,7 @@
         case AAUDIO_PERFORMANCE_MODE_NONE:
         default:
             // No flags. Use a normal mixer in front of the FAST mixer.
+            flags = AUDIO_OUTPUT_FLAG_NONE;
             break;
     }
 
@@ -88,9 +98,9 @@
 
     int32_t notificationFrames = 0;
 
-    audio_format_t format = (getFormat() == AAUDIO_FORMAT_UNSPECIFIED)
+    const audio_format_t format = (getFormat() == AUDIO_FORMAT_DEFAULT)
             ? AUDIO_FORMAT_PCM_FLOAT
-            : AAudioConvert_aaudioToAndroidDataFormat(getFormat());
+            : getFormat();
 
     // Setup the callback if there is one.
     AudioTrack::callback_t callback = nullptr;
@@ -126,20 +136,17 @@
             AAudioConvert_contentTypeToInternal(builder.getContentType());
     const audio_usage_t usage =
             AAudioConvert_usageToInternal(builder.getUsage());
+    const audio_flags_mask_t attributesFlags =
+        AAudioConvert_allowCapturePolicyToAudioFlagsMask(builder.getAllowedCapturePolicy());
 
     const audio_attributes_t attributes = {
             .content_type = contentType,
             .usage = usage,
             .source = AUDIO_SOURCE_DEFAULT, // only used for recording
-            .flags = AUDIO_FLAG_NONE, // Different than the AUDIO_OUTPUT_FLAGS
+            .flags = attributesFlags,
             .tags = ""
     };
 
-    static_assert(AAUDIO_UNSPECIFIED == AUDIO_SESSION_ALLOCATE, "Session IDs should match");
-
-    aaudio_session_id_t requestedSessionId = builder.getSessionId();
-    audio_session_t sessionId = AAudioConvert_aaudioToAndroidSessionId(requestedSessionId);
-
     mAudioTrack = new AudioTrack();
     mAudioTrack->set(
             AUDIO_STREAM_DEFAULT,  // ignored because we pass attributes below
@@ -178,10 +185,8 @@
 
     // Get the actual values from the AudioTrack.
     setSamplesPerFrame(mAudioTrack->channelCount());
-    aaudio_format_t aaudioFormat =
-            AAudioConvert_androidToAAudioDataFormat(mAudioTrack->format());
-    setFormat(aaudioFormat);
-    setDeviceFormat(aaudioFormat);
+    setFormat(mAudioTrack->format());
+    setDeviceFormat(mAudioTrack->format());
 
     int32_t actualSampleRate = mAudioTrack->getSampleRate();
     ALOGW_IF(actualSampleRate != getSampleRate(),
@@ -287,7 +292,7 @@
 
 aaudio_result_t AudioStreamTrack::requestPause() {
     if (mAudioTrack.get() == nullptr) {
-        ALOGE("requestPause() no AudioTrack");
+        ALOGE("%s() no AudioTrack", __func__);
         return AAUDIO_ERROR_INVALID_STATE;
     }
 
@@ -303,7 +308,7 @@
 
 aaudio_result_t AudioStreamTrack::requestFlush() {
     if (mAudioTrack.get() == nullptr) {
-        ALOGE("requestFlush() no AudioTrack");
+        ALOGE("%s() no AudioTrack", __func__);
         return AAUDIO_ERROR_INVALID_STATE;
     }
 
@@ -317,13 +322,13 @@
 
 aaudio_result_t AudioStreamTrack::requestStop() {
     if (mAudioTrack.get() == nullptr) {
-        ALOGE("requestStop() no AudioTrack");
+        ALOGE("%s() no AudioTrack", __func__);
         return AAUDIO_ERROR_INVALID_STATE;
     }
 
     setState(AAUDIO_STREAM_STATE_STOPPING);
-    incrementFramesRead(getFramesWritten() - getFramesRead()); // TODO review
-    mTimestampPosition.set(getFramesWritten());
+    mFramesRead.catchUpTo(getFramesWritten());
+    mTimestampPosition.catchUpTo(getFramesWritten());
     mFramesRead.reset32(); // service reads frames, service position reset on stop
     mTimestampPosition.reset32();
     mAudioTrack->stop();
@@ -419,6 +424,10 @@
 
 aaudio_result_t AudioStreamTrack::setBufferSize(int32_t requestedFrames)
 {
+    // Do not ask for less than one burst.
+    if (requestedFrames < getFramesPerBurst()) {
+        requestedFrames = getFramesPerBurst();
+    }
     ssize_t result = mAudioTrack->setBufferSizeInFrames(requestedFrames);
     if (result < 0) {
         return AAudioConvert_androidToAAudioResult(result);
diff --git a/media/libaaudio/src/utility/AAudioUtilities.cpp b/media/libaaudio/src/utility/AAudioUtilities.cpp
index 40ebb76..96ed56a 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.cpp
+++ b/media/libaaudio/src/utility/AAudioUtilities.cpp
@@ -33,395 +33,6 @@
 
 using namespace android;
 
-// This is 3 dB, (10^(3/20)), to match the maximum headroom in AudioTrack for float data.
-// It is designed to allow occasional transient peaks.
-#define MAX_HEADROOM (1.41253754f)
-#define MIN_HEADROOM (0 - MAX_HEADROOM)
-
-int32_t AAudioConvert_formatToSizeInBytes(aaudio_format_t format) {
-    int32_t size = AAUDIO_ERROR_ILLEGAL_ARGUMENT;
-    switch (format) {
-        case AAUDIO_FORMAT_PCM_I16:
-            size = sizeof(int16_t);
-            break;
-        case AAUDIO_FORMAT_PCM_FLOAT:
-            size = sizeof(float);
-            break;
-        default:
-            break;
-    }
-    return size;
-}
-
-// TODO expose and call clamp16_from_float function in primitives.h
-static inline int16_t clamp16_from_float(float f) {
-    static const float scale = 1 << 15;
-    return (int16_t) roundf(fmaxf(fminf(f * scale, scale - 1.f), -scale));
-}
-
-// Clip to valid range of a float sample to prevent excessive volume.
-// By using fmin and fmax we also protect against NaN.
-static float clipToMinMaxHeadroom(float input) {
-    return fmin(MAX_HEADROOM, fmax(MIN_HEADROOM, input));
-}
-
-static float clipAndClampFloatToPcm16(float sample, float scaler) {
-    // Clip to valid range of a float sample to prevent excessive volume.
-    sample = clipToMinMaxHeadroom(sample);
-
-    // Scale and convert to a short.
-    float fval = sample * scaler;
-    return clamp16_from_float(fval);
-}
-
-void AAudioConvert_floatToPcm16(const float *source,
-                                int16_t *destination,
-                                int32_t numSamples,
-                                float amplitude) {
-    const float scaler = amplitude;
-    for (int i = 0; i < numSamples; i++) {
-        float sample = *source++;
-        *destination++ = clipAndClampFloatToPcm16(sample, scaler);
-    }
-}
-
-void AAudioConvert_floatToPcm16(const float *source,
-                                int16_t *destination,
-                                int32_t numFrames,
-                                int32_t samplesPerFrame,
-                                float amplitude1,
-                                float amplitude2) {
-    float scaler = amplitude1;
-    // divide by numFrames so that we almost reach amplitude2
-    float delta = (amplitude2 - amplitude1) / numFrames;
-    for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) {
-        for (int sampleIndex = 0; sampleIndex < samplesPerFrame; sampleIndex++) {
-            float sample = *source++;
-            *destination++ = clipAndClampFloatToPcm16(sample, scaler);
-        }
-        scaler += delta;
-    }
-}
-
-#define SHORT_SCALE  32768
-
-void AAudioConvert_pcm16ToFloat(const int16_t *source,
-                                float *destination,
-                                int32_t numSamples,
-                                float amplitude) {
-    const float scaler = amplitude / SHORT_SCALE;
-    for (int i = 0; i < numSamples; i++) {
-        destination[i] = source[i] * scaler;
-    }
-}
-
-// This code assumes amplitude1 and amplitude2 are between 0.0 and 1.0
-void AAudioConvert_pcm16ToFloat(const int16_t *source,
-                                float *destination,
-                                int32_t numFrames,
-                                int32_t samplesPerFrame,
-                                float amplitude1,
-                                float amplitude2) {
-    float scaler = amplitude1 / SHORT_SCALE;
-    const float delta = (amplitude2 - amplitude1) / (SHORT_SCALE * (float) numFrames);
-    for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) {
-        for (int sampleIndex = 0; sampleIndex < samplesPerFrame; sampleIndex++) {
-            *destination++ = *source++ * scaler;
-        }
-        scaler += delta;
-    }
-}
-
-
-// This code assumes amplitude1 and amplitude2 are between 0.0 and 1.0
-void AAudio_linearRamp(const float *source,
-                       float *destination,
-                       int32_t numFrames,
-                       int32_t samplesPerFrame,
-                       float amplitude1,
-                       float amplitude2) {
-    float scaler = amplitude1;
-    const float delta = (amplitude2 - amplitude1) / numFrames;
-    for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) {
-        for (int sampleIndex = 0; sampleIndex < samplesPerFrame; sampleIndex++) {
-            float sample = *source++;
-            // Clip to valid range of a float sample to prevent excessive volume.
-            sample = clipToMinMaxHeadroom(sample);
-
-            *destination++ = sample * scaler;
-        }
-        scaler += delta;
-    }
-}
-
-// This code assumes amplitude1 and amplitude2 are between 0.0 and 1.0
-void AAudio_linearRamp(const int16_t *source,
-                       int16_t *destination,
-                       int32_t numFrames,
-                       int32_t samplesPerFrame,
-                       float amplitude1,
-                       float amplitude2) {
-    // Because we are converting from int16 to 1nt16, we do not have to scale by 1/32768.
-    float scaler = amplitude1;
-    const float delta = (amplitude2 - amplitude1) / numFrames;
-    for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) {
-        for (int sampleIndex = 0; sampleIndex < samplesPerFrame; sampleIndex++) {
-            // No need to clip because int16_t range is inherently limited.
-            float sample =  *source++ * scaler;
-            *destination++ = (int16_t) roundf(sample);
-        }
-        scaler += delta;
-    }
-}
-
-// *************************************************************************************
-// Convert Mono To Stereo at the same time as converting format.
-void AAudioConvert_formatMonoToStereo(const float *source,
-                                      int16_t *destination,
-                                      int32_t numFrames,
-                                      float amplitude) {
-    const float scaler = amplitude;
-    for (int i = 0; i < numFrames; i++) {
-        float sample = *source++;
-        int16_t sample16 = clipAndClampFloatToPcm16(sample, scaler);
-        *destination++ = sample16;
-        *destination++ = sample16;
-    }
-}
-
-void AAudioConvert_formatMonoToStereo(const float *source,
-                                      int16_t *destination,
-                                      int32_t numFrames,
-                                      float amplitude1,
-                                      float amplitude2) {
-    // divide by numFrames so that we almost reach amplitude2
-    const float delta = (amplitude2 - amplitude1) / numFrames;
-    for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) {
-        const float scaler = amplitude1 + (frameIndex * delta);
-        const float sample = *source++;
-        int16_t sample16 = clipAndClampFloatToPcm16(sample, scaler);
-        *destination++ = sample16;
-        *destination++ = sample16;
-    }
-}
-
-void AAudioConvert_formatMonoToStereo(const int16_t *source,
-                                      float *destination,
-                                      int32_t numFrames,
-                                      float amplitude) {
-    const float scaler = amplitude / SHORT_SCALE;
-    for (int i = 0; i < numFrames; i++) {
-        float sample = source[i] * scaler;
-        *destination++ = sample;
-        *destination++ = sample;
-    }
-}
-
-// This code assumes amplitude1 and amplitude2 are between 0.0 and 1.0
-void AAudioConvert_formatMonoToStereo(const int16_t *source,
-                                      float *destination,
-                                      int32_t numFrames,
-                                      float amplitude1,
-                                      float amplitude2) {
-    const float scaler1 = amplitude1 / SHORT_SCALE;
-    const float delta = (amplitude2 - amplitude1) / (SHORT_SCALE * (float) numFrames);
-    for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) {
-        float scaler = scaler1 + (frameIndex * delta);
-        float sample = source[frameIndex] * scaler;
-        *destination++ = sample;
-        *destination++ = sample;
-    }
-}
-
-// This code assumes amplitude1 and amplitude2 are between 0.0 and 1.0
-void AAudio_linearRampMonoToStereo(const float *source,
-                                   float *destination,
-                                   int32_t numFrames,
-                                   float amplitude1,
-                                   float amplitude2) {
-    const float delta = (amplitude2 - amplitude1) / numFrames;
-    for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) {
-        float sample = *source++;
-
-        // Clip to valid range of a float sample to prevent excessive volume.
-        sample = clipToMinMaxHeadroom(sample);
-
-        const float scaler = amplitude1 + (frameIndex * delta);
-        float sampleScaled = sample * scaler;
-        *destination++ = sampleScaled;
-        *destination++ = sampleScaled;
-    }
-}
-
-// This code assumes amplitude1 and amplitude2 are between 0.0 and 1.0
-void AAudio_linearRampMonoToStereo(const int16_t *source,
-                                   int16_t *destination,
-                                   int32_t numFrames,
-                                   float amplitude1,
-                                   float amplitude2) {
-    // Because we are converting from int16 to 1nt16, we do not have to scale by 1/32768.
-    const float delta = (amplitude2 - amplitude1) / numFrames;
-    for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) {
-        const float scaler = amplitude1 + (frameIndex * delta);
-        // No need to clip because int16_t range is inherently limited.
-        const float sample =  *source++ * scaler;
-        int16_t sample16 = (int16_t) roundf(sample);
-        *destination++ = sample16;
-        *destination++ = sample16;
-    }
-}
-
-// *************************************************************************************
-void AAudioDataConverter::convert(
-        const FormattedData &source,
-        const FormattedData &destination,
-        int32_t numFrames,
-        float levelFrom,
-        float levelTo) {
-
-    if (source.channelCount == 1 && destination.channelCount == 2) {
-        convertMonoToStereo(source,
-                            destination,
-                            numFrames,
-                            levelFrom,
-                            levelTo);
-    } else {
-        // We only support mono to stereo conversion. Otherwise source and destination
-        // must match.
-        assert(source.channelCount == destination.channelCount);
-        convertChannelsMatch(source,
-                             destination,
-                             numFrames,
-                             levelFrom,
-                             levelTo);
-    }
-}
-
-void AAudioDataConverter::convertMonoToStereo(
-        const FormattedData &source,
-        const FormattedData &destination,
-        int32_t numFrames,
-        float levelFrom,
-        float levelTo) {
-
-    // The formats are validated when the stream is opened so we do not have to
-    // check for illegal combinations here.
-    if (source.format == AAUDIO_FORMAT_PCM_FLOAT) {
-        if (destination.format == AAUDIO_FORMAT_PCM_FLOAT) {
-            AAudio_linearRampMonoToStereo(
-                    (const float *) source.data,
-                    (float *) destination.data,
-                    numFrames,
-                    levelFrom,
-                    levelTo);
-        } else if (destination.format == AAUDIO_FORMAT_PCM_I16) {
-            if (levelFrom != levelTo) {
-                AAudioConvert_formatMonoToStereo(
-                        (const float *) source.data,
-                        (int16_t *) destination.data,
-                        numFrames,
-                        levelFrom,
-                        levelTo);
-            } else {
-                AAudioConvert_formatMonoToStereo(
-                        (const float *) source.data,
-                        (int16_t *) destination.data,
-                        numFrames,
-                        levelTo);
-            }
-        }
-    } else if (source.format == AAUDIO_FORMAT_PCM_I16) {
-        if (destination.format == AAUDIO_FORMAT_PCM_FLOAT) {
-            if (levelFrom != levelTo) {
-                AAudioConvert_formatMonoToStereo(
-                        (const int16_t *) source.data,
-                        (float *) destination.data,
-                        numFrames,
-                        levelFrom,
-                        levelTo);
-            } else {
-                AAudioConvert_formatMonoToStereo(
-                        (const int16_t *) source.data,
-                        (float *) destination.data,
-                        numFrames,
-                        levelTo);
-            }
-        } else if (destination.format == AAUDIO_FORMAT_PCM_I16) {
-            AAudio_linearRampMonoToStereo(
-                    (const int16_t *) source.data,
-                    (int16_t *) destination.data,
-                    numFrames,
-                    levelFrom,
-                    levelTo);
-        }
-    }
-}
-
-void AAudioDataConverter::convertChannelsMatch(
-        const FormattedData &source,
-        const FormattedData &destination,
-        int32_t numFrames,
-        float levelFrom,
-        float levelTo) {
-    const int32_t numSamples = numFrames * source.channelCount;
-
-    // The formats are validated when the stream is opened so we do not have to
-    // check for illegal combinations here.
-    if (source.format == AAUDIO_FORMAT_PCM_FLOAT) {
-        if (destination.format == AAUDIO_FORMAT_PCM_FLOAT) {
-            AAudio_linearRamp(
-                    (const float *) source.data,
-                    (float *) destination.data,
-                    numFrames,
-                    source.channelCount,
-                    levelFrom,
-                    levelTo);
-        } else if (destination.format == AAUDIO_FORMAT_PCM_I16) {
-            if (levelFrom != levelTo) {
-                AAudioConvert_floatToPcm16(
-                        (const float *) source.data,
-                        (int16_t *) destination.data,
-                        numFrames,
-                        source.channelCount,
-                        levelFrom,
-                        levelTo);
-            } else {
-                AAudioConvert_floatToPcm16(
-                        (const float *) source.data,
-                        (int16_t *) destination.data,
-                        numSamples,
-                        levelTo);
-            }
-        }
-    } else if (source.format == AAUDIO_FORMAT_PCM_I16) {
-        if (destination.format == AAUDIO_FORMAT_PCM_FLOAT) {
-            if (levelFrom != levelTo) {
-                AAudioConvert_pcm16ToFloat(
-                        (const int16_t *) source.data,
-                        (float *) destination.data,
-                        numFrames,
-                        source.channelCount,
-                        levelFrom,
-                        levelTo);
-            } else {
-                AAudioConvert_pcm16ToFloat(
-                        (const int16_t *) source.data,
-                        (float *) destination.data,
-                        numSamples,
-                        levelTo);
-            }
-        } else if (destination.format == AAUDIO_FORMAT_PCM_I16) {
-            AAudio_linearRamp(
-                    (const int16_t *) source.data,
-                    (int16_t *) destination.data,
-                    numFrames,
-                    source.channelCount,
-                    levelFrom,
-                    levelTo);
-        }
-    }
-}
-
 status_t AAudioConvert_aaudioToAndroidStatus(aaudio_result_t result) {
     // This covers the case for AAUDIO_OK and for positive results.
     if (result >= 0) {
@@ -513,6 +124,9 @@
 audio_format_t AAudioConvert_aaudioToAndroidDataFormat(aaudio_format_t aaudioFormat) {
     audio_format_t androidFormat;
     switch (aaudioFormat) {
+    case AAUDIO_FORMAT_UNSPECIFIED:
+        androidFormat = AUDIO_FORMAT_DEFAULT;
+        break;
     case AAUDIO_FORMAT_PCM_I16:
         androidFormat = AUDIO_FORMAT_PCM_16_BIT;
         break;
@@ -520,16 +134,19 @@
         androidFormat = AUDIO_FORMAT_PCM_FLOAT;
         break;
     default:
-        androidFormat = AUDIO_FORMAT_DEFAULT;
-        ALOGE("AAudioConvert_aaudioToAndroidDataFormat 0x%08X unrecognized", aaudioFormat);
+        androidFormat = AUDIO_FORMAT_INVALID;
+        ALOGE("%s() 0x%08X unrecognized", __func__, aaudioFormat);
         break;
     }
     return androidFormat;
 }
 
 aaudio_format_t AAudioConvert_androidToAAudioDataFormat(audio_format_t androidFormat) {
-    aaudio_format_t aaudioFormat = AAUDIO_FORMAT_INVALID;
+    aaudio_format_t aaudioFormat;
     switch (androidFormat) {
+    case AUDIO_FORMAT_DEFAULT:
+        aaudioFormat = AAUDIO_FORMAT_UNSPECIFIED;
+        break;
     case AUDIO_FORMAT_PCM_16_BIT:
         aaudioFormat = AAUDIO_FORMAT_PCM_I16;
         break;
@@ -538,7 +155,7 @@
         break;
     default:
         aaudioFormat = AAUDIO_FORMAT_INVALID;
-        ALOGE("AAudioConvert_androidToAAudioDataFormat 0x%08X unrecognized", androidFormat);
+        ALOGE("%s() 0x%08X unrecognized", __func__, androidFormat);
         break;
     }
     return aaudioFormat;
@@ -593,12 +210,29 @@
     STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_RECOGNITION == AUDIO_SOURCE_VOICE_RECOGNITION);
     STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION == AUDIO_SOURCE_VOICE_COMMUNICATION);
     STATIC_ASSERT(AAUDIO_INPUT_PRESET_UNPROCESSED == AUDIO_SOURCE_UNPROCESSED);
+    STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE == AUDIO_SOURCE_VOICE_PERFORMANCE);
     if (preset == AAUDIO_UNSPECIFIED) {
         preset = AAUDIO_INPUT_PRESET_VOICE_RECOGNITION;
     }
     return (audio_source_t) preset; // same value
 }
 
+audio_flags_mask_t AAudioConvert_allowCapturePolicyToAudioFlagsMask(
+        aaudio_allowed_capture_policy_t policy) {
+    switch (policy) {
+        case AAUDIO_UNSPECIFIED:
+        case AAUDIO_ALLOW_CAPTURE_BY_ALL:
+            return AUDIO_FLAG_NONE;
+        case AAUDIO_ALLOW_CAPTURE_BY_SYSTEM:
+            return AUDIO_FLAG_NO_MEDIA_PROJECTION;
+        case AAUDIO_ALLOW_CAPTURE_BY_NONE:
+            return AUDIO_FLAG_NO_MEDIA_PROJECTION | AUDIO_FLAG_NO_SYSTEM_CAPTURE;
+        default:
+            ALOGE("%s() 0x%08X unrecognized", __func__, policy);
+            return AUDIO_FLAG_NONE; //
+    }
+}
+
 int32_t AAudioConvert_framesToBytes(int32_t numFrames,
                                     int32_t bytesPerFrame,
                                     int32_t *sizeInBytes) {
diff --git a/media/libaaudio/src/utility/AAudioUtilities.h b/media/libaaudio/src/utility/AAudioUtilities.h
index 4b975e8..76d0457 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.h
+++ b/media/libaaudio/src/utility/AAudioUtilities.h
@@ -45,156 +45,6 @@
 audio_session_t AAudioConvert_aaudioToAndroidSessionId(aaudio_session_id_t sessionId);
 
 /**
- * Convert an array of floats to an array of int16_t.
- *
- * @param source
- * @param destination
- * @param numSamples number of values in the array
- * @param amplitude level between 0.0 and 1.0
- */
-void AAudioConvert_floatToPcm16(const float *source,
-                                int16_t *destination,
-                                int32_t numSamples,
-                                float amplitude);
-
-/**
- * Convert floats to int16_t and scale by a linear ramp.
- *
- * The ramp stops just short of reaching amplitude2 so that the next
- * ramp can start at amplitude2 without causing a discontinuity.
- *
- * @param source
- * @param destination
- * @param numFrames
- * @param samplesPerFrame AKA number of channels
- * @param amplitude1 level at start of ramp, between 0.0 and 1.0
- * @param amplitude2 level past end of ramp, between 0.0 and 1.0
- */
-void AAudioConvert_floatToPcm16(const float *source,
-                                int16_t *destination,
-                                int32_t numFrames,
-                                int32_t samplesPerFrame,
-                                float amplitude1,
-                                float amplitude2);
-
-/**
- * Convert int16_t array to float array ranging from -1.0 to +1.0.
- * @param source
- * @param destination
- * @param numSamples
- */
-//void AAudioConvert_pcm16ToFloat(const int16_t *source, int32_t numSamples,
-//                                float *destination);
-
-/**
- *
- * Convert int16_t array to float array ranging from +/- amplitude.
- * @param source
- * @param destination
- * @param numSamples
- * @param amplitude
- */
-void AAudioConvert_pcm16ToFloat(const int16_t *source,
-                                float *destination,
-                                int32_t numSamples,
-                                float amplitude);
-
-/**
- * Convert floats to int16_t and scale by a linear ramp.
- *
- * The ramp stops just short of reaching amplitude2 so that the next
- * ramp can start at amplitude2 without causing a discontinuity.
- *
- * @param source
- * @param destination
- * @param numFrames
- * @param samplesPerFrame AKA number of channels
- * @param amplitude1 level at start of ramp, between 0.0 and 1.0
- * @param amplitude2 level at end of ramp, between 0.0 and 1.0
- */
-void AAudioConvert_pcm16ToFloat(const int16_t *source,
-                                float *destination,
-                                int32_t numFrames,
-                                int32_t samplesPerFrame,
-                                float amplitude1,
-                                float amplitude2);
-
-/**
- * Scale floats by a linear ramp.
- *
- * The ramp stops just short of reaching amplitude2 so that the next
- * ramp can start at amplitude2 without causing a discontinuity.
- *
- * @param source
- * @param destination
- * @param numFrames
- * @param samplesPerFrame
- * @param amplitude1
- * @param amplitude2
- */
-void AAudio_linearRamp(const float *source,
-                       float *destination,
-                       int32_t numFrames,
-                       int32_t samplesPerFrame,
-                       float amplitude1,
-                       float amplitude2);
-
-/**
- * Scale int16_t's by a linear ramp.
- *
- * The ramp stops just short of reaching amplitude2 so that the next
- * ramp can start at amplitude2 without causing a discontinuity.
- *
- * @param source
- * @param destination
- * @param numFrames
- * @param samplesPerFrame
- * @param amplitude1
- * @param amplitude2
- */
-void AAudio_linearRamp(const int16_t *source,
-                       int16_t *destination,
-                       int32_t numFrames,
-                       int32_t samplesPerFrame,
-                       float amplitude1,
-                       float amplitude2);
-
-class AAudioDataConverter {
-public:
-
-    struct FormattedData {
-
-        FormattedData(void *data, aaudio_format_t format, int32_t channelCount)
-            : data(data)
-            , format(format)
-            , channelCount(channelCount) {}
-
-        const void            *data = nullptr;
-        const aaudio_format_t  format = AAUDIO_FORMAT_UNSPECIFIED;
-        const int32_t          channelCount = 1;
-    };
-
-    static void convert(const FormattedData &source,
-                        const FormattedData &destination,
-                        int32_t numFrames,
-                        float levelFrom,
-                        float levelTo);
-
-private:
-    static void convertMonoToStereo(const FormattedData &source,
-                                    const FormattedData &destination,
-                                    int32_t numFrames,
-                                    float levelFrom,
-                                    float levelTo);
-
-    static void convertChannelsMatch(const FormattedData &source,
-                                     const FormattedData &destination,
-                                     int32_t numFrames,
-                                     float levelFrom,
-                                     float levelTo);
-};
-
-/**
  * Calculate the number of bytes and prevent numeric overflow.
  * The *sizeInBytes will be set to zero if there is an error.
  *
@@ -235,10 +85,12 @@
 audio_source_t AAudioConvert_inputPresetToAudioSource(aaudio_input_preset_t preset);
 
 /**
- * @return the size of a sample of the given format in bytes or AAUDIO_ERROR_ILLEGAL_ARGUMENT
+ * Note that this function does not validate the passed in value.
+ * That is done somewhere else.
+ * @return internal audio flags mask
  */
-int32_t AAudioConvert_formatToSizeInBytes(aaudio_format_t format);
-
+audio_flags_mask_t AAudioConvert_allowCapturePolicyToAudioFlagsMask(
+        aaudio_allowed_capture_policy_t policy);
 
 // Note that this code may be replaced by Settings or by some other system configuration tool.
 
diff --git a/media/libaaudio/src/utility/LinearRamp.cpp b/media/libaaudio/src/utility/LinearRamp.cpp
deleted file mode 100644
index 1714bbf..0000000
--- a/media/libaaudio/src/utility/LinearRamp.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "LinearRamp.h"
-
-bool LinearRamp::isRamping() {
-    float target = mTarget.load();
-    if (target != mLevelTo) {
-        // Update target. Continue from previous level.
-        mLevelTo = target;
-        mRemaining = mLengthInFrames;
-        return true;
-    } else {
-        return mRemaining > 0;
-    }
-}
-
-bool LinearRamp::nextSegment(int32_t frames, float *levelFrom, float *levelTo) {
-    bool ramping = isRamping();
-    *levelFrom = mLevelFrom;
-    if (ramping) {
-        float level;
-        if (frames >= mRemaining) {
-            level = mLevelTo;
-            mRemaining = 0;
-        } else {
-            // Interpolate to a point along the full ramp.
-            level = mLevelFrom + (frames * (mLevelTo - mLevelFrom) / mRemaining);
-            mRemaining -= frames;
-        }
-        mLevelFrom = level; // for next ramp
-        *levelTo = level;
-    } else {
-        *levelTo = mLevelTo;
-    }
-    return ramping;
-}
\ No newline at end of file
diff --git a/media/libaaudio/src/utility/LinearRamp.h b/media/libaaudio/src/utility/LinearRamp.h
deleted file mode 100644
index 2b1b8e0..0000000
--- a/media/libaaudio/src/utility/LinearRamp.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef AAUDIO_LINEAR_RAMP_H
-#define AAUDIO_LINEAR_RAMP_H
-
-#include <atomic>
-#include <stdint.h>
-
-/**
- * Generate segments along a linear ramp.
- * The ramp target can be updated from another thread.
- * When the target is updated, a new ramp is started from the current position.
- *
- * The first ramp starts at 0.0.
- *
- */
-class LinearRamp {
-public:
-    LinearRamp() {
-        mTarget.store(1.0f);
-    }
-
-    void setLengthInFrames(int32_t frames) {
-        mLengthInFrames = frames;
-    }
-
-    int32_t getLengthInFrames() {
-        return mLengthInFrames;
-    }
-
-    /**
-     * This may be called by another thread.
-     * @param target
-     */
-    void setTarget(float target) {
-        mTarget.store(target);
-    }
-
-    float getTarget() {
-        return mTarget.load();
-    }
-
-    /**
-     * Force the nextSegment to start from this level.
-     *
-     * WARNING: this can cause a discontinuity if called while the ramp is being used.
-     * Only call this when setting the initial ramp.
-     *
-     * @param level
-     */
-    void forceCurrent(float level) {
-        mLevelFrom = level;
-        mLevelTo = level; // forces a ramp if it does not match target
-    }
-
-    float getCurrent() {
-        return mLevelFrom;
-    }
-
-    /**
-     * Get levels for next ramp segment.
-     *
-     * @param frames number of frames in the segment
-     * @param levelFrom pointer to starting amplitude
-     * @param levelTo pointer to ending amplitude
-     * @return true if ramp is still moving towards the target
-     */
-    bool nextSegment(int32_t frames, float *levelFrom, float *levelTo);
-
-private:
-
-    bool isRamping();
-
-    std::atomic<float>   mTarget;
-
-    int32_t mLengthInFrames  = 48000 / 100; // 10 msec at 48000 Hz
-    int32_t mRemaining       = 0;
-    float   mLevelFrom       = 0.0f;
-    float   mLevelTo         = 0.0f;
-};
-
-
-#endif //AAUDIO_LINEAR_RAMP_H
diff --git a/media/libaaudio/src/utility/MonotonicCounter.h b/media/libaaudio/src/utility/MonotonicCounter.h
index 5833eab..63add4e 100644
--- a/media/libaaudio/src/utility/MonotonicCounter.h
+++ b/media/libaaudio/src/utility/MonotonicCounter.h
@@ -41,10 +41,12 @@
     }
 
     /**
-     * set the current value of the counter
+     * advance the current value to match the counter
      */
-    void set(int64_t counter) {
-        mCounter64 = counter;
+    void catchUpTo(int64_t counter) {
+        if ((counter - mCounter64) > 0) {
+            mCounter64 = counter;
+        }
     }
 
     /**
diff --git a/media/libaaudio/tests/Android.bp b/media/libaaudio/tests/Android.bp
index 68194db..6101e99 100644
--- a/media/libaaudio/tests/Android.bp
+++ b/media/libaaudio/tests/Android.bp
@@ -19,6 +19,18 @@
 }
 
 cc_test {
+    name: "test_clock_model",
+    defaults: ["libaaudio_tests_defaults"],
+    srcs: ["test_clock_model.cpp"],
+    shared_libs: [
+        "libaaudio",
+        "libaudioutils",
+        "libcutils",
+        "libutils",
+    ],
+}
+
+cc_test {
     name: "test_block_adapter",
     defaults: ["libaaudio_tests_defaults"],
     srcs: ["test_block_adapter.cpp"],
@@ -34,13 +46,6 @@
 }
 
 cc_test {
-    name: "test_linear_ramp",
-    defaults: ["libaaudio_tests_defaults"],
-    srcs: ["test_linear_ramp.cpp"],
-    shared_libs: ["libaaudio"],
-}
-
-cc_test {
     name: "test_open_params",
     defaults: ["libaaudio_tests_defaults"],
     srcs: ["test_open_params.cpp"],
@@ -167,3 +172,46 @@
     srcs: ["test_atomic_fifo.cpp"],
     shared_libs: ["libaaudio"],
 }
+
+cc_test {
+    name: "test_flowgraph",
+    defaults: ["libaaudio_tests_defaults"],
+    srcs: ["test_flowgraph.cpp"],
+    shared_libs: [
+        "libaaudio",
+        "libbinder",
+        "libcutils",
+        "libutils",
+    ],
+}
+
+cc_test {
+    name: "test_return_stop",
+    defaults: ["libaaudio_tests_defaults"],
+    srcs: ["test_return_stop.cpp"],
+    shared_libs: [
+        "libaaudio",
+        "libbinder",
+        "libcutils",
+        "libutils",
+    ],
+}
+
+cc_test {
+    name: "test_stop_hang",
+    defaults: ["libaaudio_tests_defaults"],
+    srcs: ["test_stop_hang.cpp"],
+    shared_libs: [
+        "libaaudio",
+        "libbinder",
+        "libcutils",
+        "libutils",
+    ],
+}
+
+cc_test {
+    name: "test_full_queue",
+    defaults: ["libaaudio_tests_defaults"],
+    srcs: ["test_full_queue.cpp"],
+    shared_libs: ["libaaudio"],
+}
diff --git a/media/libaaudio/tests/test_atomic_fifo.cpp b/media/libaaudio/tests/test_atomic_fifo.cpp
index 0edfebe..130ef43 100644
--- a/media/libaaudio/tests/test_atomic_fifo.cpp
+++ b/media/libaaudio/tests/test_atomic_fifo.cpp
@@ -158,14 +158,14 @@
         // Does the sum of the two parts match the available value returned?
         // For EmptyRoom
         fifo_frames_t framesAvailable =
-                mFifoBuffer.getFifoControllerBase()->getEmptyFramesAvailable();
+                mFifoBuffer.getEmptyFramesAvailable();
         fifo_frames_t wrapAvailable = mFifoBuffer.getEmptyRoomAvailable(&wrappingBuffer);
         EXPECT_EQ(framesAvailable, wrapAvailable);
         fifo_frames_t bothAvailable = wrappingBuffer.numFrames[0] + wrappingBuffer.numFrames[1];
         EXPECT_EQ(framesAvailable, bothAvailable);
         // For FullData
         framesAvailable =
-                mFifoBuffer.getFifoControllerBase()->getFullFramesAvailable();
+                mFifoBuffer.getFullFramesAvailable();
         wrapAvailable = mFifoBuffer.getFullDataAvailable(&wrappingBuffer);
         EXPECT_EQ(framesAvailable, wrapAvailable);
         bothAvailable = wrappingBuffer.numFrames[0] + wrappingBuffer.numFrames[1];
@@ -198,7 +198,7 @@
     // Write data but do not overflow.
     void writeMultipleDataFrames(fifo_frames_t numFrames) {
         fifo_frames_t framesAvailable =
-                mFifoBuffer.getFifoControllerBase()->getEmptyFramesAvailable();
+                mFifoBuffer.getEmptyFramesAvailable();
         fifo_frames_t framesToWrite = std::min(framesAvailable, numFrames);
         for (int i = 0; i < framesToWrite; i++) {
             mData[i] = mNextWriteIndex++;
@@ -210,7 +210,7 @@
     // Read whatever data is available, Do not underflow.
     void verifyMultipleDataFrames(fifo_frames_t numFrames) {
         fifo_frames_t framesAvailable =
-                mFifoBuffer.getFifoControllerBase()->getFullFramesAvailable();
+                mFifoBuffer.getFullFramesAvailable();
         fifo_frames_t framesToRead = std::min(framesAvailable, numFrames);
         fifo_frames_t actual = mFifoBuffer.read(mData, framesToRead);
         ASSERT_EQ(framesToRead, actual);
@@ -222,7 +222,7 @@
     // Read specified number of frames
     void verifyRequestedData(fifo_frames_t numFrames) {
         fifo_frames_t framesAvailable =
-                mFifoBuffer.getFifoControllerBase()->getFullFramesAvailable();
+                mFifoBuffer.getFullFramesAvailable();
         ASSERT_LE(numFrames, framesAvailable);
         fifo_frames_t framesToRead = std::min(framesAvailable, numFrames);
         fifo_frames_t actual = mFifoBuffer.read(mData, framesToRead);
@@ -282,12 +282,12 @@
     void checkRandomWriteRead() {
         for (int i = 0; i < 20; i++) {
             fifo_frames_t framesEmpty =
-                    mFifoBuffer.getFifoControllerBase()->getEmptyFramesAvailable();
+                    mFifoBuffer.getEmptyFramesAvailable();
             fifo_frames_t numFrames = (fifo_frames_t)(drand48() * framesEmpty);
             writeMultipleDataFrames(numFrames);
 
             fifo_frames_t framesFull =
-                    mFifoBuffer.getFifoControllerBase()->getFullFramesAvailable();
+                    mFifoBuffer.getFullFramesAvailable();
             numFrames = (fifo_frames_t)(drand48() * framesFull);
             verifyMultipleDataFrames(numFrames);
         }
diff --git a/media/libaaudio/tests/test_attributes.cpp b/media/libaaudio/tests/test_attributes.cpp
index b01af25..32ee2a3 100644
--- a/media/libaaudio/tests/test_attributes.cpp
+++ b/media/libaaudio/tests/test_attributes.cpp
@@ -32,6 +32,7 @@
                             aaudio_usage_t usage,
                             aaudio_content_type_t contentType,
                             aaudio_input_preset_t preset = DONT_SET,
+                            aaudio_allowed_capture_policy_t capturePolicy = DONT_SET,
                             aaudio_direction_t direction = AAUDIO_DIRECTION_OUTPUT) {
 
     float *buffer = new float[kNumFrames * kChannelCount];
@@ -56,6 +57,9 @@
     if (preset != DONT_SET) {
         AAudioStreamBuilder_setInputPreset(aaudioBuilder, preset);
     }
+    if (capturePolicy != DONT_SET) {
+        AAudioStreamBuilder_setAllowedCapturePolicy(aaudioBuilder, capturePolicy);
+    }
 
     // Create an AAudioStream using the Builder.
     ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
@@ -80,6 +84,12 @@
             : preset;
     EXPECT_EQ(expectedPreset, AAudioStream_getInputPreset(aaudioStream));
 
+    aaudio_allowed_capture_policy_t expectedCapturePolicy =
+            (capturePolicy == DONT_SET || capturePolicy == AAUDIO_UNSPECIFIED)
+            ? AAUDIO_ALLOW_CAPTURE_BY_ALL // default
+            : preset;
+    EXPECT_EQ(expectedCapturePolicy, AAudioStream_getAllowedCapturePolicy(aaudioStream));
+
     EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream));
 
     if (direction == AAUDIO_DIRECTION_INPUT) {
@@ -130,6 +140,15 @@
     AAUDIO_INPUT_PRESET_VOICE_RECOGNITION,
     AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION,
     AAUDIO_INPUT_PRESET_UNPROCESSED,
+    AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE,
+};
+
+static const aaudio_input_preset_t sAllowCapturePolicies[] = {
+    DONT_SET,
+    AAUDIO_UNSPECIFIED,
+    AAUDIO_ALLOW_CAPTURE_BY_ALL,
+    AAUDIO_ALLOW_CAPTURE_BY_SYSTEM,
+    AAUDIO_ALLOW_CAPTURE_BY_NONE,
 };
 
 static void checkAttributesUsage(aaudio_performance_mode_t perfMode) {
@@ -138,7 +157,7 @@
     }
 }
 
-static void checkAttributesContentType(aaudio_input_preset_t perfMode) {
+static void checkAttributesContentType(aaudio_performance_mode_t perfMode) {
     for (aaudio_content_type_t contentType : sContentypes) {
         checkAttributes(perfMode, DONT_SET, contentType);
     }
@@ -150,6 +169,18 @@
                         DONT_SET,
                         DONT_SET,
                         inputPreset,
+                        DONT_SET,
+                        AAUDIO_DIRECTION_INPUT);
+    }
+}
+
+static void checkAttributesAllowedCapturePolicy(aaudio_performance_mode_t perfMode) {
+    for (aaudio_allowed_capture_policy_t policy : sAllowCapturePolicies) {
+        checkAttributes(perfMode,
+                        DONT_SET,
+                        DONT_SET,
+                        DONT_SET,
+                        policy,
                         AAUDIO_DIRECTION_INPUT);
     }
 }
@@ -166,6 +197,10 @@
     checkAttributesInputPreset(AAUDIO_PERFORMANCE_MODE_NONE);
 }
 
+TEST(test_attributes, aaudio_allowed_capture_policy_perfnone) {
+    checkAttributesAllowedCapturePolicy(AAUDIO_PERFORMANCE_MODE_NONE);
+}
+
 TEST(test_attributes, aaudio_usage_lowlat) {
     checkAttributesUsage(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
 }
@@ -177,3 +212,7 @@
 TEST(test_attributes, aaudio_input_preset_lowlat) {
     checkAttributesInputPreset(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
 }
+
+TEST(test_attributes, aaudio_allowed_capture_policy_lowlat) {
+    checkAttributesAllowedCapturePolicy(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
+}
diff --git a/media/libaaudio/tests/test_clock_model.cpp b/media/libaaudio/tests/test_clock_model.cpp
new file mode 100644
index 0000000..7f7abbd
--- /dev/null
+++ b/media/libaaudio/tests/test_clock_model.cpp
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Unit tests for Isochronous Clock Model
+
+#include <math.h>
+#include <stdlib.h>
+
+
+#include <aaudio/AAudio.h>
+#include <audio_utils/clock.h>
+#include <client/IsochronousClockModel.h>
+#include <gtest/gtest.h>
+
+using namespace aaudio;
+
+// We can use arbitrary values here because we are not opening a real audio stream.
+#define SAMPLE_RATE             48000
+#define HW_FRAMES_PER_BURST     48
+#define NANOS_PER_BURST         (NANOS_PER_SECOND * HW_FRAMES_PER_BURST / SAMPLE_RATE)
+
+class ClockModelTestFixture: public ::testing::Test {
+public:
+    ClockModelTestFixture() {
+    }
+
+    void SetUp() {
+        model.setSampleRate(SAMPLE_RATE);
+        model.setFramesPerBurst(HW_FRAMES_PER_BURST);
+    }
+
+    void TearDown() {
+    }
+
+    ~ClockModelTestFixture()  {
+        // cleanup any pending stuff, but no exceptions allowed
+    }
+
+    // Test processing of timestamps when the hardware may be slightly off from
+    // the expected sample rate.
+    void checkDriftingClock(double hardwareFramesPerSecond, int numLoops) {
+        const int64_t startTimeNanos = 500000000; // arbitrary
+        model.start(startTimeNanos);
+
+        const int64_t startPositionFrames = HW_FRAMES_PER_BURST; // hardware
+        // arbitrary time for first burst
+        const int64_t markerTime = startTimeNanos + NANOS_PER_MILLISECOND
+                + (200 * NANOS_PER_MICROSECOND);
+
+        // Should set initial marker.
+        model.processTimestamp(startPositionFrames, markerTime);
+        ASSERT_EQ(startPositionFrames, model.convertTimeToPosition(markerTime));
+
+        double elapsedTimeSeconds = startTimeNanos / (double) NANOS_PER_SECOND;
+        for (int i = 0; i < numLoops; i++) {
+            // Calculate random delay over several bursts.
+            const double timeDelaySeconds = 10.0 * drand48() * NANOS_PER_BURST / NANOS_PER_SECOND;
+            elapsedTimeSeconds += timeDelaySeconds;
+            const int64_t elapsedTimeNanos = (int64_t)(elapsedTimeSeconds * NANOS_PER_SECOND);
+            const int64_t currentTimeNanos = startTimeNanos + elapsedTimeNanos;
+            // Simulate DSP running at the specified rate.
+            const int64_t currentTimeFrames = startPositionFrames +
+                                        (int64_t)(hardwareFramesPerSecond * elapsedTimeSeconds);
+            const int64_t numBursts = currentTimeFrames / HW_FRAMES_PER_BURST;
+            const int64_t alignedPosition = startPositionFrames + (numBursts * HW_FRAMES_PER_BURST);
+
+            // Apply drifting timestamp.
+            model.processTimestamp(alignedPosition, currentTimeNanos);
+
+            ASSERT_EQ(alignedPosition, model.convertTimeToPosition(currentTimeNanos));
+        }
+    }
+
+    IsochronousClockModel model;
+};
+
+// Check default setup.
+TEST_F(ClockModelTestFixture, clock_setup) {
+    ASSERT_EQ(SAMPLE_RATE, model.getSampleRate());
+    ASSERT_EQ(HW_FRAMES_PER_BURST, model.getFramesPerBurst());
+}
+
+// Test delta calculations.
+TEST_F(ClockModelTestFixture, clock_deltas) {
+    int64_t position = model.convertDeltaTimeToPosition(NANOS_PER_SECOND);
+    ASSERT_EQ(SAMPLE_RATE, position);
+
+    // Deltas are not quantized.
+    // Compare time to the equivalent position in frames.
+    constexpr int64_t kNanosPerBurst = HW_FRAMES_PER_BURST * NANOS_PER_SECOND / SAMPLE_RATE;
+    position = model.convertDeltaTimeToPosition(NANOS_PER_SECOND + (kNanosPerBurst / 2));
+    ASSERT_EQ(SAMPLE_RATE + (HW_FRAMES_PER_BURST / 2), position);
+
+    int64_t time = model.convertDeltaPositionToTime(SAMPLE_RATE);
+    ASSERT_EQ(NANOS_PER_SECOND, time);
+
+    // Compare position in frames to the equivalent time.
+    time = model.convertDeltaPositionToTime(SAMPLE_RATE + (HW_FRAMES_PER_BURST / 2));
+    ASSERT_EQ(NANOS_PER_SECOND + (kNanosPerBurst / 2), time);
+}
+
+// start() should force the internal markers
+TEST_F(ClockModelTestFixture, clock_start) {
+    const int64_t startTime = 100000;
+    model.start(startTime);
+
+    int64_t position = model.convertTimeToPosition(startTime);
+    EXPECT_EQ(0, position);
+
+    int64_t time = model.convertPositionToTime(position);
+    EXPECT_EQ(startTime, time);
+
+    time = startTime + (500 * NANOS_PER_MICROSECOND);
+    position = model.convertTimeToPosition(time);
+    EXPECT_EQ(0, position);
+}
+
+// timestamps moves the window if outside the bounds
+TEST_F(ClockModelTestFixture, clock_timestamp) {
+    const int64_t startTime = 100000000;
+    model.start(startTime);
+
+    const int64_t position = HW_FRAMES_PER_BURST; // hardware
+    int64_t markerTime = startTime + NANOS_PER_MILLISECOND + (200 * NANOS_PER_MICROSECOND);
+
+    // Should set marker.
+    model.processTimestamp(position, markerTime);
+    EXPECT_EQ(position, model.convertTimeToPosition(markerTime));
+
+    // convertTimeToPosition rounds down
+    EXPECT_EQ(position, model.convertTimeToPosition(markerTime + (73 * NANOS_PER_MICROSECOND)));
+
+    // convertPositionToTime rounds up
+    EXPECT_EQ(markerTime + NANOS_PER_BURST, model.convertPositionToTime(position + 17));
+}
+
+#define NUM_LOOPS_DRIFT   10000
+
+// test nudging the window by using a drifting HW clock
+TEST_F(ClockModelTestFixture, clock_no_drift) {
+    checkDriftingClock(SAMPLE_RATE, NUM_LOOPS_DRIFT);
+}
+
+// These slow drift rates caused errors when I disabled the code that handles
+// drifting in the clock model. So I think the test is valid.
+// It is unlikely that real hardware would be off by more than this amount.
+TEST_F(ClockModelTestFixture, clock_slow_drift) {
+    checkDriftingClock(0.998 * SAMPLE_RATE, NUM_LOOPS_DRIFT);
+}
+
+TEST_F(ClockModelTestFixture, clock_fast_drift) {
+    checkDriftingClock(1.002 * SAMPLE_RATE, NUM_LOOPS_DRIFT);
+}
\ No newline at end of file
diff --git a/media/libaaudio/tests/test_flowgraph.cpp b/media/libaaudio/tests/test_flowgraph.cpp
new file mode 100644
index 0000000..d563a7e
--- /dev/null
+++ b/media/libaaudio/tests/test_flowgraph.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Test FlowGraph
+ */
+
+#include <iostream>
+
+#include <gtest/gtest.h>
+
+#include "flowgraph/ClipToRange.h"
+#include "flowgraph/MonoToMultiConverter.h"
+#include "flowgraph/SourceFloat.h"
+#include "flowgraph/RampLinear.h"
+#include "flowgraph/SinkFloat.h"
+#include "flowgraph/SinkI16.h"
+#include "flowgraph/SinkI24.h"
+#include "flowgraph/SourceI16.h"
+#include "flowgraph/SourceI24.h"
+
+using namespace flowgraph;
+
+constexpr int kBytesPerI24Packed = 3;
+
+TEST(test_flowgraph, module_sinki16) {
+    static const float input[] = {1.0f, 0.5f, -0.25f, -1.0f, 0.0f, 53.9f, -87.2f};
+    static const int16_t expected[] = {32767, 16384, -8192, -32768, 0, 32767, -32768};
+    int16_t output[20];
+    SourceFloat sourceFloat{1};
+    SinkI16 sinkI16{1};
+
+    int numInputFrames = sizeof(input) / sizeof(input[0]);
+    sourceFloat.setData(input, numInputFrames);
+    sourceFloat.output.connect(&sinkI16.input);
+
+    int numOutputFrames = sizeof(output) / sizeof(int16_t);
+    int32_t numRead = sinkI16.read(output, numOutputFrames);
+    ASSERT_EQ(numInputFrames, numRead);
+    for (int i = 0; i < numRead; i++) {
+        EXPECT_EQ(expected[i], output[i]);
+    }
+}
+
+TEST(test_flowgraph, module_mono_to_stereo) {
+    static const float input[] = {1.0f, 2.0f, 3.0f};
+    float output[100] = {};
+    SourceFloat sourceFloat{1};
+    MonoToMultiConverter monoToStereo{2};
+    SinkFloat sinkFloat{2};
+
+    sourceFloat.setData(input, 3);
+
+    sourceFloat.output.connect(&monoToStereo.input);
+    monoToStereo.output.connect(&sinkFloat.input);
+
+    int32_t numRead = sinkFloat.read(output, 8);
+    ASSERT_EQ(3, numRead);
+    EXPECT_EQ(input[0], output[0]);
+    EXPECT_EQ(input[0], output[1]);
+    EXPECT_EQ(input[1], output[2]);
+    EXPECT_EQ(input[1], output[3]);
+}
+
+TEST(test_flowgraph, module_ramp_linear) {
+    constexpr int rampSize = 5;
+    constexpr int numOutput = 100;
+    constexpr float value = 1.0f;
+    constexpr float target = 100.0f;
+    float output[numOutput] = {};
+    RampLinear rampLinear{1};
+    SinkFloat sinkFloat{1};
+
+    rampLinear.input.setValue(value);
+    rampLinear.setLengthInFrames(rampSize);
+    rampLinear.setTarget(target);
+    rampLinear.forceCurrent(0.0f);
+
+    rampLinear.output.connect(&sinkFloat.input);
+
+    int32_t numRead = sinkFloat.read(output, numOutput);
+    ASSERT_EQ(numOutput, numRead);
+    constexpr float tolerance = 0.0001f; // arbitrary
+    int i = 0;
+    for (; i < rampSize; i++) {
+        float expected = i * value * target / rampSize;
+        EXPECT_NEAR(expected, output[i], tolerance);
+    }
+    for (; i < numOutput; i++) {
+        float expected = value * target;
+        EXPECT_NEAR(expected, output[i], tolerance);
+    }
+}
+
+// It is easiest to represent packed 24-bit data as a byte array.
+// This test will read from input, convert to float, then write
+// back to output as bytes.
+TEST(test_flowgraph, module_packed_24) {
+    static const uint8_t input[] = {0x01, 0x23, 0x45,
+                                    0x67, 0x89, 0xAB,
+                                    0xCD, 0xEF, 0x5A};
+    uint8_t output[99] = {};
+    SourceI24 sourceI24{1};
+    SinkI24 sinkI24{1};
+
+    int numInputFrames = sizeof(input) / kBytesPerI24Packed;
+    sourceI24.setData(input, numInputFrames);
+    sourceI24.output.connect(&sinkI24.input);
+
+    int32_t numRead = sinkI24.read(output, sizeof(output) / kBytesPerI24Packed);
+    ASSERT_EQ(numInputFrames, numRead);
+    for (size_t i = 0; i < sizeof(input); i++) {
+        EXPECT_EQ(input[i], output[i]);
+    }
+}
+
+TEST(test_flowgraph, module_clip_to_range) {
+    constexpr float myMin = -2.0f;
+    constexpr float myMax = 1.5f;
+
+    static const float input[] = {-9.7, 0.5f, -0.25, 1.0f, 12.3};
+    static const float expected[] = {myMin, 0.5f, -0.25, 1.0f, myMax};
+    float output[100];
+    SourceFloat sourceFloat{1};
+    ClipToRange clipper{1};
+    SinkFloat sinkFloat{1};
+
+    int numInputFrames = sizeof(input) / sizeof(input[0]);
+    sourceFloat.setData(input, numInputFrames);
+
+    clipper.setMinimum(myMin);
+    clipper.setMaximum(myMax);
+
+    sourceFloat.output.connect(&clipper.input);
+    clipper.output.connect(&sinkFloat.input);
+
+    int numOutputFrames = sizeof(output) / sizeof(output[0]);
+    int32_t numRead = sinkFloat.read(output, numOutputFrames);
+    ASSERT_EQ(numInputFrames, numRead);
+    constexpr float tolerance = 0.000001f; // arbitrary
+    for (int i = 0; i < numRead; i++) {
+        EXPECT_NEAR(expected[i], output[i], tolerance);
+    }
+}
diff --git a/media/libaaudio/tests/test_full_queue.cpp b/media/libaaudio/tests/test_full_queue.cpp
new file mode 100644
index 0000000..12d4fa3
--- /dev/null
+++ b/media/libaaudio/tests/test_full_queue.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Test whether a stream dies if it is written to after a delay.
+// Maybe because the message queue from the AAudio service fills up.
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <aaudio/AAudio.h>
+#include <gtest/gtest.h>
+
+constexpr int64_t kNanosPerSecond = 1000000000;
+constexpr int64_t kTimeoutNanos = kNanosPerSecond / 2;
+constexpr int kNumFrames = 256;
+constexpr int kChannelCount = 2;
+
+static void checkFullQueue(aaudio_performance_mode_t perfMode,
+                           int32_t sleepMillis) {
+    std::unique_ptr<float[]> buffer = std::make_unique<float[]>(
+            kNumFrames * kChannelCount);
+
+    AAudioStreamBuilder *aaudioBuilder = nullptr;
+
+    // Use an AAudioStreamBuilder to contain requested parameters.
+    ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
+
+    AAudioStreamBuilder_setChannelCount(aaudioBuilder, kChannelCount);
+
+    // Request stream properties.
+    AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
+
+    // Create an AAudioStream using the Builder.
+    AAudioStream *aaudioStream = nullptr;
+    ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder,
+            &aaudioStream));
+    AAudioStreamBuilder_delete(aaudioBuilder);
+
+    EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream));
+
+    // Sleep for awhile. This might kill the stream.
+    usleep(sleepMillis * 1000); // 1000 millis in a microsecond
+
+    for (int i = 0; i < 10; i++) {
+        const aaudio_result_t result = AAudioStream_write(aaudioStream,
+                buffer.get(),
+                kNumFrames,
+                kTimeoutNanos);
+        EXPECT_EQ(kNumFrames, result);
+        if (kNumFrames != result) break;
+    }
+
+    EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
+
+    EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
+}
+
+TEST(test_full_queue, aaudio_full_queue_perf_none_50) {
+    checkFullQueue(AAUDIO_PERFORMANCE_MODE_NONE, 50 /* sleepMillis */);
+}
+
+TEST(test_full_queue, aaudio_full_queue_perf_none_200) {
+    checkFullQueue(AAUDIO_PERFORMANCE_MODE_NONE, 200 /* sleepMillis */);
+}
+
+TEST(test_full_queue, aaudio_full_queue_perf_none_1000) {
+    checkFullQueue(AAUDIO_PERFORMANCE_MODE_NONE, 1000 /* sleepMillis */);
+}
+
+TEST(test_full_queue, aaudio_full_queue_low_latency_50) {
+    checkFullQueue(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, 50 /* sleepMillis */);
+}
+
+TEST(test_full_queue, aaudio_full_queue_low_latency_200) {
+    checkFullQueue(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, 200 /* sleepMillis */);
+}
+
+TEST(test_full_queue, aaudio_full_queue_low_latency_1000) {
+    checkFullQueue(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, 1000 /* sleepMillis */);
+}
diff --git a/media/libaaudio/tests/test_linear_ramp.cpp b/media/libaaudio/tests/test_linear_ramp.cpp
deleted file mode 100644
index 93226ba..0000000
--- a/media/libaaudio/tests/test_linear_ramp.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <iostream>
-#include <math.h>
-
-#include <gtest/gtest.h>
-
-#include "utility/AAudioUtilities.h"
-#include "utility/LinearRamp.h"
-
-TEST(test_linear_ramp, linear_ramp_segments) {
-    LinearRamp ramp;
-    const float source[4] = {1.0f, 1.0f, 1.0f, 1.0f };
-    float destination[4] = {1.0f, 1.0f, 1.0f, 1.0f };
-
-    float levelFrom = -1.0f;
-    float levelTo = -1.0f;
-    ramp.setLengthInFrames(8);
-    ramp.setTarget(8.0f);
-
-    EXPECT_EQ(8, ramp.getLengthInFrames());
-
-    bool ramping = ramp.nextSegment(4, &levelFrom, &levelTo);
-    EXPECT_EQ(1, ramping);
-    EXPECT_EQ(0.0f, levelFrom);
-    EXPECT_EQ(4.0f, levelTo);
-
-    AAudio_linearRamp(source, destination, 4, 1, levelFrom, levelTo);
-    EXPECT_EQ(0.0f, destination[0]);
-    EXPECT_EQ(1.0f, destination[1]);
-    EXPECT_EQ(2.0f, destination[2]);
-    EXPECT_EQ(3.0f, destination[3]);
-
-    ramping = ramp.nextSegment(4, &levelFrom, &levelTo);
-    EXPECT_EQ(1, ramping);
-    EXPECT_EQ(4.0f, levelFrom);
-    EXPECT_EQ(8.0f, levelTo);
-
-    AAudio_linearRamp(source, destination, 4, 1, levelFrom, levelTo);
-    EXPECT_EQ(4.0f, destination[0]);
-    EXPECT_EQ(5.0f, destination[1]);
-    EXPECT_EQ(6.0f, destination[2]);
-    EXPECT_EQ(7.0f, destination[3]);
-
-    ramping = ramp.nextSegment(4, &levelFrom, &levelTo);
-    EXPECT_EQ(0, ramping);
-    EXPECT_EQ(8.0f, levelFrom);
-    EXPECT_EQ(8.0f, levelTo);
-
-    AAudio_linearRamp(source, destination, 4, 1, levelFrom, levelTo);
-    EXPECT_EQ(8.0f, destination[0]);
-    EXPECT_EQ(8.0f, destination[1]);
-    EXPECT_EQ(8.0f, destination[2]);
-    EXPECT_EQ(8.0f, destination[3]);
-
-};
-
-
-TEST(test_linear_ramp, linear_ramp_forced) {
-    LinearRamp ramp;
-    const float source[4] = {1.0f, 1.0f, 1.0f, 1.0f };
-    float destination[4] = {1.0f, 1.0f, 1.0f, 1.0f };
-
-    float levelFrom = -1.0f;
-    float levelTo = -1.0f;
-    ramp.setLengthInFrames(4);
-    ramp.setTarget(8.0f);
-    ramp.forceCurrent(4.0f);
-    EXPECT_EQ(4.0f, ramp.getCurrent());
-
-    bool ramping = ramp.nextSegment(4, &levelFrom, &levelTo);
-    EXPECT_EQ(1, ramping);
-    EXPECT_EQ(4.0f, levelFrom);
-    EXPECT_EQ(8.0f, levelTo);
-
-    AAudio_linearRamp(source, destination, 4, 1, levelFrom, levelTo);
-    EXPECT_EQ(4.0f, destination[0]);
-    EXPECT_EQ(5.0f, destination[1]);
-    EXPECT_EQ(6.0f, destination[2]);
-    EXPECT_EQ(7.0f, destination[3]);
-
-    ramping = ramp.nextSegment(4, &levelFrom, &levelTo);
-    EXPECT_EQ(0, ramping);
-    EXPECT_EQ(8.0f, levelFrom);
-    EXPECT_EQ(8.0f, levelTo);
-
-    AAudio_linearRamp(source, destination, 4, 1, levelFrom, levelTo);
-    EXPECT_EQ(8.0f, destination[0]);
-    EXPECT_EQ(8.0f, destination[1]);
-    EXPECT_EQ(8.0f, destination[2]);
-    EXPECT_EQ(8.0f, destination[3]);
-
-};
-
-constexpr int16_t kMaxI16 = INT16_MAX;
-constexpr int16_t kMinI16 = INT16_MIN;
-constexpr int16_t kHalfI16 = 16384;
-constexpr int16_t kTenthI16 = 3277;
-
-//void AAudioConvert_floatToPcm16(const float *source,
-//                                int16_t *destination,
-//                                int32_t numSamples,
-//                                float amplitude);
-TEST(test_linear_ramp, float_to_i16) {
-    const float source[] = {12345.6f, 1.0f, 0.5f, 0.1f, 0.0f, -0.1f, -0.5f, -1.0f, -12345.6f};
-    constexpr size_t count = sizeof(source) / sizeof(source[0]);
-    int16_t destination[count];
-    const int16_t expected[count] = {kMaxI16, kMaxI16, kHalfI16, kTenthI16, 0,
-                                     -kTenthI16, -kHalfI16, kMinI16, kMinI16};
-
-    AAudioConvert_floatToPcm16(source, destination, count, 1.0f);
-    for (size_t i = 0; i < count; i++) {
-        EXPECT_EQ(expected[i], destination[i]);
-    }
-
-}
-
-//void AAudioConvert_pcm16ToFloat(const int16_t *source,
-//                                float *destination,
-//                                int32_t numSamples,
-//                                float amplitude);
-TEST(test_linear_ramp, i16_to_float) {
-    const int16_t source[] = {kMaxI16, kHalfI16, kTenthI16, 0,
-                              -kTenthI16, -kHalfI16, kMinI16};
-    constexpr size_t count = sizeof(source) / sizeof(source[0]);
-    float destination[count];
-    const float expected[count] = {(32767.0f / 32768.0f), 0.5f, 0.1f, 0.0f, -0.1f, -0.5f, -1.0f};
-
-    AAudioConvert_pcm16ToFloat(source, destination, count, 1.0f);
-    for (size_t i = 0; i < count; i++) {
-        EXPECT_NEAR(expected[i], destination[i], 0.0001f);
-    }
-
-}
-
-//void AAudio_linearRamp(const int16_t *source,
-//                       int16_t *destination,
-//                       int32_t numFrames,
-//                       int32_t samplesPerFrame,
-//                       float amplitude1,
-//                       float amplitude2);
-TEST(test_linear_ramp, ramp_i16_to_i16) {
-    const int16_t source[] = {1, 1, 1, 1, 1, 1, 1, 1};
-    constexpr size_t count = sizeof(source) / sizeof(source[0]);
-    int16_t destination[count];
-    // Ramp will sweep from -1 to almost +1
-    const int16_t expected[count] = {
-            -1, // from -1.00
-            -1, // from -0.75
-            -1, // from -0.55, round away from zero
-            0,  // from -0.25, round up to zero
-            0,  // from  0.00
-            0,  // from  0.25, round down to zero
-            1,  // from  0.50, round away from zero
-            1   // from  0.75
-    };
-
-    // sweep across zero to test symmetry
-    constexpr float amplitude1 = -1.0;
-    constexpr float amplitude2 = 1.0;
-    AAudio_linearRamp(source, destination, count, 1, amplitude1, amplitude2);
-    for (size_t i = 0; i < count; i++) {
-        EXPECT_EQ(expected[i], destination[i]);
-    }
-
-}
diff --git a/media/libaaudio/tests/test_return_stop.cpp b/media/libaaudio/tests/test_return_stop.cpp
new file mode 100644
index 0000000..1252dd3
--- /dev/null
+++ b/media/libaaudio/tests/test_return_stop.cpp
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Return stop from the callback.
+ * Expect the callback to cease.
+ * Check the logcat for bad behavior.
+ */
+
+#include <stdio.h>
+#include <thread>
+#include <unistd.h>
+
+#include <aaudio/AAudio.h>
+
+#define DEFAULT_TIMEOUT_NANOS  ((int64_t)1000000000)
+#define STOP_AT_MSEC          1000
+#define LOOP_DURATION_MSEC    4000
+#define SLEEP_DURATION_MSEC    200
+
+static void s_myErrorCallbackProc(
+        AAudioStream *stream,
+        void *userData,
+        aaudio_result_t error);
+
+struct AudioEngine {
+    AAudioStreamBuilder *builder = nullptr;
+    AAudioStream        *stream = nullptr;
+    std::thread         *thread = nullptr;
+    int32_t              stopAtFrame = 0;
+    bool                 stopped = false;
+    // These counters are read and written by the callback and the main thread.
+    std::atomic<int32_t> framesRead{};
+    std::atomic<int32_t> startingFramesRead{};
+    std::atomic<int32_t> framesCalled{};
+    std::atomic<int32_t> callbackCount{};
+    std::atomic<int32_t> callbackCountAfterStop{};
+
+    void reset() {
+        framesRead.store(0);
+        startingFramesRead.store(0);
+        framesCalled.store(0);
+        callbackCount.store(0);
+        callbackCountAfterStop.store(0);
+        stopped = false;
+    }
+};
+
+// Callback function that fills the audio output buffer.
+static aaudio_data_callback_result_t s_myDataCallbackProc(
+        AAudioStream *stream,
+        void *userData,
+        void *audioData,
+        int32_t numFrames
+) {
+    (void) audioData;
+    (void) numFrames;
+    AudioEngine *engine = (struct AudioEngine *)userData;
+    engine->callbackCount++;
+    if (engine->stopped) {
+        engine->callbackCountAfterStop++;
+    }
+
+    engine->framesRead = (int32_t)AAudioStream_getFramesRead(stream);
+    if (engine->startingFramesRead == 0) {
+        engine->startingFramesRead.store(engine->framesRead.load());
+    }
+    engine->framesCalled += numFrames;
+    if (engine->framesCalled >= engine->stopAtFrame) {
+        engine->stopped = true;
+        return AAUDIO_CALLBACK_RESULT_STOP;
+    } else {
+        return AAUDIO_CALLBACK_RESULT_CONTINUE;
+    }
+}
+
+static aaudio_result_t s_OpenAudioStream(struct AudioEngine *engine,
+                                         aaudio_direction_t direction,
+                                         aaudio_sharing_mode_t sharingMode,
+                                         aaudio_performance_mode_t perfMode) {
+    // Use an AAudioStreamBuilder to contain requested parameters.
+    aaudio_result_t result = AAudio_createStreamBuilder(&engine->builder);
+    if (result != AAUDIO_OK) {
+        printf("AAudio_createStreamBuilder returned %s",
+               AAudio_convertResultToText(result));
+        return result;
+    }
+
+    // Request stream properties.
+    AAudioStreamBuilder_setFormat(engine->builder, AAUDIO_FORMAT_PCM_FLOAT);
+    AAudioStreamBuilder_setPerformanceMode(engine->builder, perfMode);
+    AAudioStreamBuilder_setSharingMode(engine->builder, sharingMode);
+    AAudioStreamBuilder_setDirection(engine->builder, direction);
+    AAudioStreamBuilder_setDataCallback(engine->builder, s_myDataCallbackProc, engine);
+    AAudioStreamBuilder_setErrorCallback(engine->builder, s_myErrorCallbackProc, engine);
+
+    // Create an AAudioStream using the Builder.
+    result = AAudioStreamBuilder_openStream(engine->builder, &engine->stream);
+    if (result != AAUDIO_OK) {
+        printf("AAudioStreamBuilder_openStream returned %s",
+               AAudio_convertResultToText(result));
+        return result;
+    }
+
+    return result;
+}
+
+static aaudio_result_t s_CloseAudioStream(struct AudioEngine *engine) {
+    aaudio_result_t result = AAUDIO_OK;
+    if (engine->stream != nullptr) {
+        result = AAudioStream_close(engine->stream);
+        if (result != AAUDIO_OK) {
+            printf("AAudioStream_close returned %s\n",
+                   AAudio_convertResultToText(result));
+        }
+        engine->stream = nullptr;
+    }
+    AAudioStreamBuilder_delete(engine->builder);
+    engine->builder = nullptr;
+    return result;
+}
+
+static void s_myErrorCallbackProc(
+        AAudioStream *stream __unused,
+        void *userData __unused,
+        aaudio_result_t error) {
+    printf("%s() - error = %d\n", __func__, error);
+}
+
+static void s_usage() {
+    printf("test_return_stop [-i] [-x] [-n] [-c]\n");
+    printf("     -i direction INPUT, otherwise OUTPUT\n");
+    printf("     -x sharing mode EXCLUSIVE, otherwise SHARED\n");
+    printf("     -n performance mode NONE, otherwise LOW_LATENCY\n");
+    printf("     -c always return CONTINUE from callback, not STOP\n");
+}
+
+/**
+ * @return 0 is OK, -1 for error
+ */
+static int s_checkEnginePositions(AudioEngine *engine) {
+    const int64_t framesRead = AAudioStream_getFramesRead(engine->stream);
+    const int64_t framesWritten = AAudioStream_getFramesWritten(engine->stream);
+    const int32_t delta = (int32_t)(framesWritten - framesRead);
+    printf("playing framesRead = %7d, framesWritten = %7d"
+           ", delta = %4d, framesCalled = %6d, callbackCount = %4d\n",
+           (int32_t) framesRead,
+           (int32_t) framesWritten,
+           delta,
+           engine->framesCalled.load(),
+           engine->callbackCount.load()
+    );
+    if (delta > AAudioStream_getBufferCapacityInFrames(engine->stream)) {
+        printf("ERROR - delta > capacity\n");
+        return -1;
+    }
+    return 0;
+}
+
+int main(int argc, char **argv) {
+    (void) argc;
+    (void) argv;
+    struct AudioEngine engine;
+    aaudio_sharing_mode_t sharingMode = AAUDIO_SHARING_MODE_SHARED;
+    aaudio_performance_mode_t perfMode = AAUDIO_PERFORMANCE_MODE_LOW_LATENCY;
+    aaudio_direction_t direction = AAUDIO_DIRECTION_OUTPUT;
+    aaudio_result_t result = AAUDIO_OK;
+    bool alwaysContinue = false;
+    int errorCount = 0;
+    int callbackResult = EXIT_SUCCESS;
+
+    // Make printf print immediately so that debug info is not stuck
+    // in a buffer if we hang or crash.
+    setvbuf(stdout, nullptr, _IONBF, (size_t) 0);
+
+    printf("Test Return Stop V1.0\n");
+    printf("Wait for a few seconds.\n");
+    printf("You should see callbackCount and framesRead stop advancing\n");
+    printf("when callbackCount reaches %d msec\n", STOP_AT_MSEC);
+    printf("\n");
+
+    for (int i = 1; i < argc; i++) {
+        const char *arg = argv[i];
+        if (arg[0] == '-') {
+            char option = arg[1];
+            switch (option) {
+                case 'c':
+                    alwaysContinue = true;
+                    break;
+                case 'i':
+                    direction = AAUDIO_DIRECTION_INPUT;
+                    break;
+                case 'n':
+                    perfMode = AAUDIO_PERFORMANCE_MODE_NONE;
+                    break;
+                case 'x':
+                    sharingMode = AAUDIO_SHARING_MODE_EXCLUSIVE;
+                    break;
+                default:
+                    s_usage();
+                    exit(EXIT_FAILURE);
+                    break;
+            }
+        } else {
+            s_usage();
+            exit(EXIT_FAILURE);
+            break;
+        }
+    }
+
+    result = s_OpenAudioStream(&engine, direction, sharingMode, perfMode);
+    if (result != AAUDIO_OK) {
+        printf("s_OpenAudioStream returned %s\n",
+               AAudio_convertResultToText(result));
+        errorCount++;
+    }
+
+    int32_t framesPerBurst = AAudioStream_getFramesPerBurst(engine.stream);
+    // Use double buffered stream.
+    const int32_t bufferSize = AAudioStream_setBufferSizeInFrames(engine.stream, 2 * framesPerBurst);
+    if (bufferSize < 0) {
+        printf("AAudioStream_setBufferSizeInFrames returned %s\n",
+               AAudio_convertResultToText(bufferSize));
+        errorCount++;
+    }
+
+    // Check to see what kind of stream we actually got.
+    int32_t deviceId = AAudioStream_getDeviceId(engine.stream);
+    aaudio_performance_mode_t actualPerfMode = AAudioStream_getPerformanceMode(engine.stream);
+    printf("-------- opened: deviceId = %3d, framesPerBurst = %3d, perfMode = %d\n",
+           deviceId, framesPerBurst, actualPerfMode);
+
+    // Calculate how many callbacks needed.
+    if (alwaysContinue) {
+        engine.stopAtFrame = INT32_MAX;
+    } else {
+        int32_t sampleRate = AAudioStream_getSampleRate(engine.stream);
+        engine.stopAtFrame = STOP_AT_MSEC * sampleRate / 1000;
+    }
+
+    for (int loops = 0; loops < 2 && result == AAUDIO_OK; loops++) {
+        engine.reset();
+
+        // Start stream.
+        result = AAudioStream_requestStart(engine.stream);
+        printf("AAudioStream_requestStart() returned %d >>>>>>>>>>>>>>>>>>>>>>\n", result);
+        if (result != AAUDIO_OK) {
+            errorCount++;
+            break;
+        }
+
+        if (result == AAUDIO_OK) {
+            const int watchLoops = LOOP_DURATION_MSEC / SLEEP_DURATION_MSEC;
+            for (int i = watchLoops; i > 0; i--) {
+                errorCount += s_checkEnginePositions(&engine) ? 1 : 0;
+                usleep(SLEEP_DURATION_MSEC * 1000);
+            }
+        }
+
+        if (engine.stopAtFrame != INT32_MAX) {
+            callbackResult = (engine.callbackCountAfterStop == 0) ? EXIT_SUCCESS
+                                                                  : EXIT_FAILURE;
+            if (callbackResult) {
+                printf("ERROR - Callback count after STOP = %d\n",
+                       engine.callbackCountAfterStop.load());
+                errorCount++;
+            }
+        }
+
+        if (engine.startingFramesRead.load() == engine.framesRead.load()) {
+            printf("ERROR - framesRead did not advance across callbacks\n");
+            errorCount++;
+        }
+
+        result = AAudioStream_requestStop(engine.stream);
+        printf("AAudioStream_requestStop() returned %d <<<<<<<<<<<<<<<<<<<<<\n", result);
+        if (result != AAUDIO_OK) {
+            errorCount++;
+        }
+        usleep(SLEEP_DURATION_MSEC * 1000);
+        errorCount += s_checkEnginePositions(&engine) ? 1 : 0;
+    }
+
+    s_CloseAudioStream(&engine);
+
+    printf("aaudio result = %d = %s\n", result, AAudio_convertResultToText(result));
+    printf("test %s\n", errorCount ? "FAILED" : "PASSED");
+
+    return errorCount ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/media/libaaudio/tests/test_stop_hang.cpp b/media/libaaudio/tests/test_stop_hang.cpp
new file mode 100644
index 0000000..2397b6c
--- /dev/null
+++ b/media/libaaudio/tests/test_stop_hang.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Return stop from the callback
+ * and then close the stream immediately.
+ */
+
+#include <atomic>
+#include <mutex>
+#include <stdio.h>
+#include <thread>
+#include <unistd.h>
+
+#include <aaudio/AAudio.h>
+
+#define DURATION_SECONDS   5
+
+struct AudioEngine {
+    AAudioStreamBuilder *builder = nullptr;
+    AAudioStream        *stream = nullptr;
+    std::thread         *thread = nullptr;
+
+    std::atomic<bool>   started{false};
+    std::mutex          doneLock; // Use a mutex so we can sleep on it while join()ing.
+    std::atomic<bool>   done{false};
+
+    aaudio_result_t join() {
+        aaudio_result_t result = AAUDIO_ERROR_INVALID_STATE;
+        if (stream != nullptr) {
+            while (true) {
+                {
+                    // Will block if the thread is running.
+                    // This mutex is used to close() immediately after the callback returns
+                    // and before the requestStop() is called.
+                    std::lock_guard<std::mutex> lock(doneLock);
+                    if (done) break;
+                }
+                printf("join() got mutex but stream not done!");
+                usleep(10 * 1000); // sleep then check again
+            }
+            result = AAudioStream_close(stream);
+            stream = nullptr;
+        }
+        return result;
+    }
+};
+
+// Callback function that fills the audio output buffer.
+static aaudio_data_callback_result_t s_myDataCallbackProc(
+        AAudioStream *stream,
+        void *userData,
+        void *audioData,
+        int32_t numFrames
+) {
+    (void) stream;
+    (void) audioData;
+    (void) numFrames;
+    AudioEngine *engine = (struct AudioEngine *)userData;
+    std::lock_guard<std::mutex> lock(engine->doneLock);
+    engine->started = true;
+    usleep(DURATION_SECONDS * 1000 * 1000); // Mimic SynthMark procedure.
+    engine->done = true;
+    return AAUDIO_CALLBACK_RESULT_STOP;
+}
+
+static void s_myErrorCallbackProc(
+    AAudioStream *stream __unused,
+    void *userData __unused,
+    aaudio_result_t error) {
+    printf("%s() - error = %d\n", __func__, error);
+}
+
+static aaudio_result_t s_OpenAudioStream(struct AudioEngine *engine) {
+    // Use an AAudioStreamBuilder to contain requested parameters.
+    aaudio_result_t result = AAudio_createStreamBuilder(&engine->builder);
+    if (result != AAUDIO_OK) {
+        printf("AAudio_createStreamBuilder returned %s",
+               AAudio_convertResultToText(result));
+        return result;
+    }
+
+    // Request stream properties.
+    AAudioStreamBuilder_setPerformanceMode(engine->builder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
+    AAudioStreamBuilder_setDataCallback(engine->builder, s_myDataCallbackProc, engine);
+    AAudioStreamBuilder_setErrorCallback(engine->builder, s_myErrorCallbackProc, engine);
+
+    // Create an AAudioStream using the Builder.
+    result = AAudioStreamBuilder_openStream(engine->builder, &engine->stream);
+    if (result != AAUDIO_OK) {
+        printf("AAudioStreamBuilder_openStream returned %s",
+               AAudio_convertResultToText(result));
+        return result;
+    }
+
+    return result;
+}
+
+int main(int argc, char **argv) {
+    (void) argc;
+    (void) argv;
+    struct AudioEngine engine;
+    aaudio_result_t result = AAUDIO_OK;
+    int errorCount = 0;
+
+    // Make printf print immediately so that debug info is not stuck
+    // in a buffer if we hang or crash.
+    setvbuf(stdout, nullptr, _IONBF, (size_t) 0);
+
+    printf("Test Return Stop Hang V1.0\n");
+
+    result = s_OpenAudioStream(&engine);
+    if (result != AAUDIO_OK) {
+        printf("s_OpenAudioStream returned %s\n",
+               AAudio_convertResultToText(result));
+        errorCount++;
+    }
+
+    // Check to see what kind of stream we actually got.
+    int32_t deviceId = AAudioStream_getDeviceId(engine.stream);
+    aaudio_performance_mode_t actualPerfMode = AAudioStream_getPerformanceMode(engine.stream);
+    printf("-------- opened: deviceId = %3d, perfMode = %d\n", deviceId, actualPerfMode);
+
+    // Start stream.
+    result = AAudioStream_requestStart(engine.stream);
+    printf("AAudioStream_requestStart() returned %d >>>>>>>>>>>>>>>>>>>>>>\n", result);
+    if (result != AAUDIO_OK) {
+        errorCount++;
+    } else {
+        int counter = 0;
+        while (!engine.started) {
+            printf("Waiting for stream to start, %d\n", counter++);
+            usleep(5 * 1000);
+        }
+        printf("You should see more messages %d seconds after this. If not then the test failed!\n",
+               DURATION_SECONDS);
+        result = engine.join(); // This might hang!
+        AAudioStreamBuilder_delete(engine.builder);
+        engine.builder = nullptr;
+    }
+
+    printf("aaudio result = %d = %s\n", result, AAudio_convertResultToText(result));
+    printf("test %s\n", errorCount ? "FAILED" : "PASSED");
+
+    return errorCount ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/media/libaaudio/tests/test_timestamps.cpp b/media/libaaudio/tests/test_timestamps.cpp
index dfa7815..7b1dfd3 100644
--- a/media/libaaudio/tests/test_timestamps.cpp
+++ b/media/libaaudio/tests/test_timestamps.cpp
@@ -35,6 +35,7 @@
 
 #define NUM_SECONDS             1
 #define NUM_LOOPS               4
+#define MAX_TESTS               20
 
 typedef struct TimestampInfo {
     int64_t         framesTotal;
@@ -53,6 +54,49 @@
     bool           forceUnderruns = false;
 } TimestampCallbackData_t;
 
+struct TimeStampTestLog {
+    aaudio_policy_t           isMmap;
+    aaudio_sharing_mode_t     sharingMode;
+    aaudio_performance_mode_t performanceMode;
+    aaudio_direction_t        direction;
+    aaudio_result_t           result;
+};
+
+static int s_numTests = 0;
+// Use a plain old array because we reference this from the callback and do not want any
+// automatic memory allocation.
+static TimeStampTestLog s_testLogs[MAX_TESTS]{};
+
+static void logTestResult(bool isMmap,
+                          aaudio_sharing_mode_t sharingMode,
+                          aaudio_performance_mode_t performanceMode,
+                          aaudio_direction_t direction,
+                          aaudio_result_t result) {
+    if(s_numTests >= MAX_TESTS) {
+        printf("ERROR - MAX_TESTS too small = %d\n", MAX_TESTS);
+        return;
+    }
+    s_testLogs[s_numTests].isMmap = isMmap;
+    s_testLogs[s_numTests].sharingMode = sharingMode;
+    s_testLogs[s_numTests].performanceMode = performanceMode;
+    s_testLogs[s_numTests].direction = direction;
+    s_testLogs[s_numTests].result = result;
+    s_numTests++;
+}
+
+static void printTestResults() {
+    for (int i = 0; i < s_numTests; i++) {
+        TimeStampTestLog *log = &s_testLogs[i];
+        printf("%2d: mmap = %3s, sharing = %9s, perf = %11s, dir = %6s ---- %4s\n",
+               i,
+               log->isMmap ? "yes" : "no",
+               getSharingModeText(log->sharingMode),
+               getPerformanceModeText(log->performanceMode),
+               getDirectionText(log->direction),
+               log->result ? "FAIL" : "pass");
+    }
+}
+
 // Callback function that fills the audio output buffer.
 aaudio_data_callback_result_t timestampDataCallbackProc(
         AAudioStream *stream,
@@ -115,6 +159,7 @@
     int32_t originalBufferSize = 0;
     int32_t requestedBufferSize = 0;
     int32_t finalBufferSize = 0;
+    bool    isMmap = false;
     aaudio_format_t actualDataFormat = AAUDIO_FORMAT_PCM_FLOAT;
     aaudio_sharing_mode_t actualSharingMode = AAUDIO_SHARING_MODE_SHARED;
     aaudio_sharing_mode_t actualPerformanceMode = AAUDIO_PERFORMANCE_MODE_NONE;
@@ -124,7 +169,8 @@
 
     memset(&sTimestampData, 0, sizeof(sTimestampData));
 
-    printf("------------ testTimeStamps(policy = %d, sharing = %s, perf = %s, dir = %s) -----------\n",
+    printf("\n=================================================================================\n");
+    printf("--------- testTimeStamps(policy = %d, sharing = %s, perf = %s, dir = %s) --------\n",
            mmapPolicy,
            getSharingModeText(sharingMode),
            getPerformanceModeText(performanceMode),
@@ -177,8 +223,8 @@
 
     printf("    chans = %3d, rate = %6d format = %d\n",
            actualChannelCount, actualSampleRate, actualDataFormat);
-    printf("    Is MMAP used? %s\n", AAudioStream_isMMapUsed(aaudioStream)
-                                     ? "yes" : "no");
+    isMmap = AAudioStream_isMMapUsed(aaudioStream);
+    printf("    Is MMAP used? %s\n", isMmap ? "yes" : "no");
 
     // This is the number of frames that are read in one chunk by a DMA controller
     // or a DSP or a mixer.
@@ -218,7 +264,7 @@
 
         for (int second = 0; second < NUM_SECONDS; second++) {
             // Give AAudio callback time to run in the background.
-            sleep(1);
+            usleep(200 * 1000);
 
             // Periodically print the progress so we know it hasn't died.
             printf("framesWritten = %d, XRuns = %d\n",
@@ -234,18 +280,25 @@
         }
 
         printf("timestampCount = %d\n", sTimestampData.timestampCount);
-        int printed = 0;
-        for (int i = 0; i < sTimestampData.timestampCount; i++) {
+        int printedGood = 0;
+        int printedBad = 0;
+        for (int i = 1; i < sTimestampData.timestampCount; i++) {
             TimestampInfo *timestamp = &sTimestampData.timestamps[i];
-            bool posChanged = (timestamp->timestampPosition != (timestamp - 1)->timestampPosition);
-            bool timeChanged = (timestamp->timestampNanos != (timestamp - 1)->timestampNanos);
-            if ((printed < 20) && ((i < 10) || posChanged || timeChanged)) {
-                printf("  %3d : frames %8lld, xferd %8lld", i,
-                       (long long) timestamp->framesTotal,
-                       (long long) timestamp->appPosition);
-                if (timestamp->result != AAUDIO_OK) {
-                    printf(", result = %s\n", AAudio_convertResultToText(timestamp->result));
-                } else {
+            if (timestamp->result != AAUDIO_OK) {
+                if (printedBad < 5) {
+                    printf("  %3d : frames %8lld, xferd %8lld, result = %s\n",
+                           i,
+                           (long long) timestamp->framesTotal,
+                           (long long) timestamp->appPosition,
+                           AAudio_convertResultToText(timestamp->result));
+                    printedBad++;
+                }
+            } else {
+                const bool posChanged = (timestamp->timestampPosition !=
+                                   (timestamp - 1)->timestampPosition);
+                const bool timeChanged = (timestamp->timestampNanos
+                        != (timestamp - 1)->timestampNanos);
+                if ((printedGood < 20) && (posChanged || timeChanged)) {
                     bool negative = timestamp->timestampPosition < 0;
                     bool retro = (i > 0 && (timestamp->timestampPosition <
                                             (timestamp - 1)->timestampPosition));
@@ -253,17 +306,39 @@
                                                    : (retro ? "  <= RETROGRADE!" : "");
 
                     double latency = calculateLatencyMillis(timestamp->timestampPosition,
-                                             timestamp->timestampNanos,
-                                             timestamp->appPosition,
-                                             timestamp->appNanoseconds,
-                                             actualSampleRate);
-                    printf(", STAMP: pos = %8lld, nanos = %8lld, lat = %7.1f msec %s\n",
+                                                            timestamp->timestampNanos,
+                                                            timestamp->appPosition,
+                                                            timestamp->appNanoseconds,
+                                                            actualSampleRate);
+                    printf("  %3d : frames %8lld, xferd %8lld",
+                           i,
+                           (long long) timestamp->framesTotal,
+                           (long long) timestamp->appPosition);
+                    printf(" STAMP: pos = %8lld, nanos = %8lld, lat = %7.1f msec %s\n",
                            (long long) timestamp->timestampPosition,
                            (long long) timestamp->timestampNanos,
                            latency,
                            message);
+                    printedGood++;
                 }
-                printed++;
+            }
+        }
+
+        if (printedGood == 0) {
+            printf("ERROR - AAudioStream_getTimestamp() never gave us a valid timestamp\n");
+            result = AAUDIO_ERROR_INTERNAL;
+        } else {
+            // Make sure we do not get timestamps when stopped.
+            int64_t position;
+            int64_t time;
+            aaudio_result_t tempResult = AAudioStream_getTimestamp(aaudioStream,
+                                                                   CLOCK_MONOTONIC,
+                                                                   &position, &time);
+            if (tempResult != AAUDIO_ERROR_INVALID_STATE) {
+                printf("ERROR - AAudioStream_getTimestamp() should return"
+                       " INVALID_STATE when stopped! %s\n",
+                       AAudio_convertResultToText(tempResult));
+                result = AAUDIO_ERROR_INTERNAL;
             }
         }
 
@@ -273,12 +348,14 @@
     }
 
 finish:
+
+    logTestResult(isMmap, sharingMode, performanceMode, direction, result);
+
     if (aaudioStream != nullptr) {
         AAudioStream_close(aaudioStream);
     }
     AAudioStreamBuilder_delete(aaudioBuilder);
     printf("result = %d = %s\n", result, AAudio_convertResultToText(result));
-
     return result;
 }
 
@@ -292,7 +369,7 @@
     // in a buffer if we hang or crash.
     setvbuf(stdout, nullptr, _IONBF, (size_t) 0);
 
-    printf("Test Timestamps V0.1.3\n");
+    printf("Test Timestamps V0.1.4\n");
 
     // Legacy
     aaudio_policy_t policy = AAUDIO_POLICY_NEVER;
@@ -332,5 +409,7 @@
                             AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
                             AAUDIO_DIRECTION_OUTPUT);
 
+    printTestResults();
+
     return (result == AAUDIO_OK) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 2df37a8..03bd6ce 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -5,6 +5,29 @@
 }
 
 cc_library_shared {
+    name: "libaudiopolicy",
+    srcs: [
+        "AudioAttributes.cpp",
+        "AudioPolicy.cpp",
+        "AudioProductStrategy.cpp",
+        "AudioVolumeGroup.cpp",
+    ],
+    shared_libs: [
+        "libaudioutils",
+        "libbinder",
+        "libcutils",
+        "liblog",
+        "libutils",
+    ],
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+    include_dirs: ["system/media/audio_utils/include"],
+    export_include_dirs: ["include"],
+}
+
+cc_library_shared {
     name: "libaudioclient",
 
     aidl: {
@@ -23,7 +46,6 @@
         ":libaudioclient_aidl",
 
         "AudioEffect.cpp",
-        "AudioPolicy.cpp",
         "AudioRecord.cpp",
         "AudioSystem.cpp",
         "AudioTrack.cpp",
@@ -37,23 +59,32 @@
         "IEffectClient.cpp",
         "ToneGenerator.cpp",
         "PlayerBase.cpp",
+        "RecordingActivityTracker.cpp",
         "TrackPlayerBase.cpp",
     ],
     shared_libs: [
-        "liblog",
-        "libcutils",
-        "libutils",
-        "libbinder",
-        "libdl",
         "libaudioutils",
+        "libaudiopolicy",
         "libaudiomanager",
+        "libbinder",
+        "libcutils",
+        "libdl",
+        "liblog",
         "libmedia_helper",
         "libmediametrics",
+        "libmediautils",
+        "libnblog",
+        "libprocessgroup",
+        "libutils",
+        "libvibrator",
     ],
     export_shared_lib_headers: ["libbinder"],
 
     local_include_dirs: ["include/media", "aidl"],
-    header_libs: ["libaudioclient_headers"],
+    header_libs: [
+        "libaudioclient_headers",
+        "libbase_headers",
+    ],
     export_header_lib_headers: ["libaudioclient_headers"],
 
     // for memory heap analysis
diff --git a/media/libaudioclient/AudioAttributes.cpp b/media/libaudioclient/AudioAttributes.cpp
new file mode 100644
index 0000000..1ee6930
--- /dev/null
+++ b/media/libaudioclient/AudioAttributes.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AudioAttributes"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+#include <binder/Parcel.h>
+
+#include <media/AudioAttributes.h>
+
+namespace android {
+
+status_t AudioAttributes::readFromParcel(const Parcel *parcel)
+{
+    status_t ret = NO_ERROR;
+    mAttributes.content_type = static_cast<audio_content_type_t>(parcel->readInt32());
+    mAttributes.usage = static_cast<audio_usage_t>(parcel->readInt32());
+    mAttributes.source = static_cast<audio_source_t>(parcel->readInt32());
+    mAttributes.flags = static_cast<audio_flags_mask_t>(parcel->readInt32());
+    const bool hasFlattenedTag = (parcel->readInt32() == 1);
+    if (hasFlattenedTag) {
+        std::string tags;
+        ret = parcel->readUtf8FromUtf16(&tags);
+        if (ret != NO_ERROR) {
+            return ret;
+        }
+        std::strncpy(mAttributes.tags, tags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1);
+    } else {
+        strcpy(mAttributes.tags, "");
+    }
+    mStreamType = static_cast<audio_stream_type_t>(parcel->readInt32());
+    mGroupId = static_cast<volume_group_t>(parcel->readUint32());
+    return NO_ERROR;
+}
+
+status_t AudioAttributes::writeToParcel(Parcel *parcel) const
+{
+    parcel->writeInt32(static_cast<int32_t>(mAttributes.content_type));
+    parcel->writeInt32(static_cast<int32_t>(mAttributes.usage));
+    parcel->writeInt32(static_cast<int32_t>(mAttributes.source));
+    parcel->writeInt32(static_cast<int32_t>(mAttributes.flags));
+    if (strlen(mAttributes.tags) == 0) {
+        parcel->writeInt32(0);
+    } else {
+        parcel->writeInt32(1);
+        parcel->writeUtf8AsUtf16(mAttributes.tags);
+    }
+    parcel->writeInt32(static_cast<int32_t>(mStreamType));
+    parcel->writeUint32(static_cast<uint32_t>(mGroupId));
+    return NO_ERROR;
+}
+
+} // namespace android
diff --git a/media/libaudioclient/AudioEffect.cpp b/media/libaudioclient/AudioEffect.cpp
index b1cb0e7..cf11936 100644
--- a/media/libaudioclient/AudioEffect.cpp
+++ b/media/libaudioclient/AudioEffect.cpp
@@ -52,6 +52,7 @@
                 )
     : mStatus(NO_INIT), mOpPackageName(opPackageName)
 {
+    AutoMutex lock(mConstructLock);
     mStatus = set(type, uuid, priority, cbf, user, sessionId, io);
 }
 
@@ -85,6 +86,7 @@
         }
     }
 
+    AutoMutex lock(mConstructLock);
     mStatus = set(pType, pUuid, priority, cbf, user, sessionId, io);
 }
 
@@ -430,14 +432,15 @@
 }
 
 status_t AudioEffect::getEffectDescriptor(const effect_uuid_t *uuid,
-        effect_descriptor_t *descriptor) /*const*/
+                                          const effect_uuid_t *type,
+                                          uint32_t preferredTypeFlag,
+                                          effect_descriptor_t *descriptor)
 {
     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
     if (af == 0) return PERMISSION_DENIED;
-    return af->getEffectDescriptor(uuid, descriptor);
+    return af->getEffectDescriptor(uuid, type, preferredTypeFlag, descriptor);
 }
 
-
 status_t AudioEffect::queryDefaultPreProcessing(audio_session_t audioSession,
                                           effect_descriptor_t *descriptors,
                                           uint32_t *count)
@@ -446,6 +449,95 @@
     if (aps == 0) return PERMISSION_DENIED;
     return aps->queryDefaultPreProcessing(audioSession, descriptors, count);
 }
+
+status_t AudioEffect::newEffectUniqueId(audio_unique_id_t* id)
+{
+    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+    if (af == 0) return PERMISSION_DENIED;
+    *id = af->newAudioUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT);
+    return NO_ERROR;
+}
+
+status_t AudioEffect::addSourceDefaultEffect(const char *typeStr,
+                                             const String16& opPackageName,
+                                             const char *uuidStr,
+                                             int32_t priority,
+                                             audio_source_t source,
+                                             audio_unique_id_t *id)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+
+    if (typeStr == NULL && uuidStr == NULL) return BAD_VALUE;
+
+    // Convert type & uuid from string to effect_uuid_t.
+    effect_uuid_t type;
+    if (typeStr != NULL) {
+        status_t res = stringToGuid(typeStr, &type);
+        if (res != OK) return res;
+    } else {
+        type = *EFFECT_UUID_NULL;
+    }
+
+    effect_uuid_t uuid;
+    if (uuidStr != NULL) {
+        status_t res = stringToGuid(uuidStr, &uuid);
+        if (res != OK) return res;
+    } else {
+        uuid = *EFFECT_UUID_NULL;
+    }
+
+    return aps->addSourceDefaultEffect(&type, opPackageName, &uuid, priority, source, id);
+}
+
+status_t AudioEffect::addStreamDefaultEffect(const char *typeStr,
+                                             const String16& opPackageName,
+                                             const char *uuidStr,
+                                             int32_t priority,
+                                             audio_usage_t usage,
+                                             audio_unique_id_t *id)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+
+    if (typeStr == NULL && uuidStr == NULL) return BAD_VALUE;
+
+    // Convert type & uuid from string to effect_uuid_t.
+    effect_uuid_t type;
+    if (typeStr != NULL) {
+        status_t res = stringToGuid(typeStr, &type);
+        if (res != OK) return res;
+    } else {
+        type = *EFFECT_UUID_NULL;
+    }
+
+    effect_uuid_t uuid;
+    if (uuidStr != NULL) {
+        status_t res = stringToGuid(uuidStr, &uuid);
+        if (res != OK) return res;
+    } else {
+        uuid = *EFFECT_UUID_NULL;
+    }
+
+    return aps->addStreamDefaultEffect(&type, opPackageName, &uuid, priority, usage, id);
+}
+
+status_t AudioEffect::removeSourceDefaultEffect(audio_unique_id_t id)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+
+    return aps->removeSourceDefaultEffect(id);
+}
+
+status_t AudioEffect::removeStreamDefaultEffect(audio_unique_id_t id)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+
+    return aps->removeStreamDefaultEffect(id);
+}
+
 // -------------------------------------------------------------------------
 
 status_t AudioEffect::stringToGuid(const char *str, effect_uuid_t *guid)
diff --git a/media/libaudioclient/AudioPolicy.cpp b/media/libaudioclient/AudioPolicy.cpp
index d1f7525..3cdf095 100644
--- a/media/libaudioclient/AudioPolicy.cpp
+++ b/media/libaudioclient/AudioPolicy.cpp
@@ -22,6 +22,22 @@
 namespace android {
 
 //
+//  AudioDeviceTypeAddr implementation
+//
+status_t AudioDeviceTypeAddr::readFromParcel(Parcel *parcel) {
+    mType = (audio_devices_t) parcel->readInt32();
+    mAddress = parcel->readString8();
+    return NO_ERROR;
+}
+
+status_t AudioDeviceTypeAddr::writeToParcel(Parcel *parcel) const {
+    parcel->writeInt32((int32_t) mType);
+    parcel->writeString8(mAddress);
+    return NO_ERROR;
+}
+
+
+//
 //  AudioMixMatchCriterion implementation
 //
 AudioMixMatchCriterion::AudioMixMatchCriterion(audio_usage_t usage,
@@ -40,11 +56,22 @@
 status_t AudioMixMatchCriterion::readFromParcel(Parcel *parcel)
 {
     mRule = parcel->readInt32();
-    if (mRule == RULE_MATCH_ATTRIBUTE_USAGE ||
-            mRule == RULE_EXCLUDE_ATTRIBUTE_USAGE) {
-        mValue.mUsage = (audio_usage_t)parcel->readInt32();
-    } else {
-        mValue.mSource = (audio_source_t)parcel->readInt32();
+    switch (mRule) {
+    case RULE_MATCH_ATTRIBUTE_USAGE:
+    case RULE_EXCLUDE_ATTRIBUTE_USAGE:
+        mValue.mUsage = (audio_usage_t) parcel->readInt32();
+        break;
+    case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET:
+    case RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET:
+        mValue.mSource = (audio_source_t) parcel->readInt32();
+        break;
+    case RULE_MATCH_UID:
+    case RULE_EXCLUDE_UID:
+        mValue.mUid = (uid_t) parcel->readInt32();
+        break;
+    default:
+        ALOGE("Trying to build AudioMixMatchCriterion from unknown rule %d", mRule);
+        return BAD_VALUE;
     }
     return NO_ERROR;
 }
@@ -70,6 +97,7 @@
     mDeviceType = (audio_devices_t) parcel->readInt32();
     mDeviceAddress = parcel->readString8();
     mCbFlags = (uint32_t)parcel->readInt32();
+    mAllowPrivilegedPlaybackCapture = parcel->readBool();
     size_t size = (size_t)parcel->readInt32();
     if (size > MAX_CRITERIA_PER_MIX) {
         size = MAX_CRITERIA_PER_MIX;
@@ -93,6 +121,7 @@
     parcel->writeInt32(mDeviceType);
     parcel->writeString8(mDeviceAddress);
     parcel->writeInt32(mCbFlags);
+    parcel->writeBool(mAllowPrivilegedPlaybackCapture);
     size_t size = mCriteria.size();
     if (size > MAX_CRITERIA_PER_MIX) {
         size = MAX_CRITERIA_PER_MIX;
@@ -116,4 +145,43 @@
     return NO_ERROR;
 }
 
+void AudioMix::setExcludeUid(uid_t uid) const {
+    AudioMixMatchCriterion crit;
+    crit.mRule = RULE_EXCLUDE_UID;
+    crit.mValue.mUid = uid;
+    mCriteria.add(crit);
+}
+
+void AudioMix::setMatchUid(uid_t uid) const {
+    AudioMixMatchCriterion crit;
+    crit.mRule = RULE_MATCH_UID;
+    crit.mValue.mUid = uid;
+    mCriteria.add(crit);
+}
+
+bool AudioMix::hasUidRule(bool match, uid_t uid) const {
+    const uint32_t rule = match ? RULE_MATCH_UID : RULE_EXCLUDE_UID;
+    for (size_t i = 0; i < mCriteria.size(); i++) {
+        if (mCriteria[i].mRule == rule
+                && mCriteria[i].mValue.mUid == uid) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool AudioMix::hasMatchUidRule() const {
+    for (size_t i = 0; i < mCriteria.size(); i++) {
+        if (mCriteria[i].mRule == RULE_MATCH_UID) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool AudioMix::isDeviceAffinityCompatible() const {
+    return ((mMixType == MIX_TYPE_PLAYERS)
+            && (mRouteFlags == MIX_ROUTE_FLAG_RENDER));
+}
+
 } // namespace android
diff --git a/media/libaudioclient/AudioProductStrategy.cpp b/media/libaudioclient/AudioProductStrategy.cpp
new file mode 100644
index 0000000..0e1dfac
--- /dev/null
+++ b/media/libaudioclient/AudioProductStrategy.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AudioProductStrategy"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+#include <media/AudioProductStrategy.h>
+#include <media/AudioAttributes.h>
+#include <media/AudioSystem.h>
+
+namespace android {
+
+status_t AudioProductStrategy::readFromParcel(const Parcel *parcel)
+{
+    mId = static_cast<product_strategy_t>(parcel->readInt32());
+    status_t ret = parcel->readUtf8FromUtf16(&mName);
+    if (ret != NO_ERROR) {
+        return ret;
+    }
+    size_t size = static_cast<size_t>(parcel->readInt32());
+    for (size_t i = 0; i < size; i++) {
+        AudioAttributes attribute;
+        ret = attribute.readFromParcel(parcel);
+        if (ret != NO_ERROR) {
+            mAudioAttributes.clear();
+            return ret;
+        }
+        mAudioAttributes.push_back(attribute);
+    }
+    return NO_ERROR;
+}
+
+status_t AudioProductStrategy::writeToParcel(Parcel *parcel) const
+{
+    parcel->writeInt32(static_cast<int32_t>(mId));
+    parcel->writeUtf8AsUtf16(mName);
+    size_t size = mAudioAttributes.size();
+    size_t sizePosition = parcel->dataPosition();
+    parcel->writeInt32(size);
+    size_t finalSize = size;
+
+    for (size_t i = 0; i < size; i++) {
+        size_t position = parcel->dataPosition();
+        AudioAttributes attribute(mAudioAttributes[i]);
+        status_t ret = attribute.writeToParcel(parcel);
+        if (ret != NO_ERROR) {
+            parcel->setDataPosition(position);
+            finalSize--;
+        }
+    }
+    if (size != finalSize) {
+        size_t position = parcel->dataPosition();
+        parcel->setDataPosition(sizePosition);
+        parcel->writeInt32(finalSize);
+        parcel->setDataPosition(position);
+    }
+    return NO_ERROR;
+}
+
+bool AudioProductStrategy::attributesMatches(const audio_attributes_t refAttributes,
+                                        const audio_attributes_t clientAttritubes)
+{
+    if (refAttributes == AUDIO_ATTRIBUTES_INITIALIZER) {
+        // The default product strategy is the strategy that holds default attributes by convention.
+        // All attributes that fail to match will follow the default strategy for routing.
+        // Choosing the default must be done as a fallback, the attributes match shall not
+        // select the default.
+        return false;
+    }
+    return ((refAttributes.usage == AUDIO_USAGE_UNKNOWN) ||
+            (clientAttritubes.usage == refAttributes.usage)) &&
+            ((refAttributes.content_type == AUDIO_CONTENT_TYPE_UNKNOWN) ||
+             (clientAttritubes.content_type == refAttributes.content_type)) &&
+            ((refAttributes.flags == AUDIO_FLAG_NONE) ||
+             (clientAttritubes.flags != AUDIO_FLAG_NONE &&
+            (clientAttritubes.flags & refAttributes.flags) == refAttributes.flags)) &&
+            ((strlen(refAttributes.tags) == 0) ||
+             (std::strcmp(clientAttritubes.tags, refAttributes.tags) == 0));
+}
+
+} // namespace android
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index f9df5b1..a1b04ca 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -19,12 +19,18 @@
 #define LOG_TAG "AudioRecord"
 
 #include <inttypes.h>
+#include <android-base/macros.h>
 #include <sys/resource.h>
 
+#include <audiomanager/AudioManager.h>
+#include <audiomanager/IAudioManager.h>
+#include <binder/Binder.h>
 #include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
 #include <media/AudioRecord.h>
 #include <utils/Log.h>
 #include <private/media/AudioTrackShared.h>
+#include <processgroup/sched_policy.h>
 #include <media/IAudioFlinger.h>
 #include <media/MediaAnalyticsItem.h>
 #include <media/TypeConverter.h>
@@ -48,8 +54,9 @@
     size_t size;
     status_t status = AudioSystem::getInputBufferSize(sampleRate, format, channelMask, &size);
     if (status != NO_ERROR) {
-        ALOGE("AudioSystem could not query the input buffer size for sampleRate %u, format %#x, "
-              "channelMask %#x; status %d", sampleRate, format, channelMask, status);
+        ALOGE("%s(): AudioSystem could not query the input buffer size for"
+              " sampleRate %u, format %#x, channelMask %#x; status %d",
+               __func__, sampleRate, format, channelMask, status);
         return status;
     }
 
@@ -57,8 +64,8 @@
     // Assumes audio_is_linear_pcm(format)
     if ((*frameCount = (size * 2) / (audio_channel_count_from_in_mask(channelMask) *
             audio_bytes_per_sample(format))) == 0) {
-        ALOGE("Unsupported configuration: sampleRate %u, format %#x, channelMask %#x",
-            sampleRate, format, channelMask);
+        ALOGE("%s(): Unsupported configuration: sampleRate %u, format %#x, channelMask %#x",
+                __func__, sampleRate, format, channelMask);
         return BAD_VALUE;
     }
 
@@ -67,70 +74,34 @@
 
 // ---------------------------------------------------------------------------
 
-static std::string audioFormatTypeString(audio_format_t value) {
-    std::string formatType;
-    if (FormatConverter::toString(value, formatType)) {
-        return formatType;
-    }
-    char rawbuffer[16];  // room for "%d"
-    snprintf(rawbuffer, sizeof(rawbuffer), "%d", value);
-    return rawbuffer;
-}
-
-static std::string audioSourceString(audio_source_t value) {
-    std::string source;
-    if (SourceTypeConverter::toString(value, source)) {
-        return source;
-    }
-    char rawbuffer[16];  // room for "%d"
-    snprintf(rawbuffer, sizeof(rawbuffer), "%d", value);
-    return rawbuffer;
-}
-
 void AudioRecord::MediaMetrics::gather(const AudioRecord *record)
 {
-    // key for media statistics is defined in the header
-    // attrs for media statistics
-    // NB: these are matched with public Java API constants defined
-    // in frameworks/base/media/java/android/media/AudioRecord.java
-    // These must be kept synchronized with the constants there.
-    static constexpr char kAudioRecordEncoding[] = "android.media.audiorecord.encoding";
-    static constexpr char kAudioRecordSource[] = "android.media.audiorecord.source";
-    static constexpr char kAudioRecordLatency[] = "android.media.audiorecord.latency";
-    static constexpr char kAudioRecordSampleRate[] = "android.media.audiorecord.samplerate";
-    static constexpr char kAudioRecordChannelCount[] = "android.media.audiorecord.channels";
-    static constexpr char kAudioRecordCreated[] = "android.media.audiorecord.createdMs";
-    static constexpr char kAudioRecordDuration[] = "android.media.audiorecord.durationMs";
-    static constexpr char kAudioRecordCount[] = "android.media.audiorecord.n";
-    static constexpr char kAudioRecordError[] = "android.media.audiorecord.errcode";
-    static constexpr char kAudioRecordErrorFunction[] = "android.media.audiorecord.errfunc";
+#define MM_PREFIX "android.media.audiorecord." // avoid cut-n-paste errors.
 
-    // constructor guarantees mAnalyticsItem is valid
+    // Java API 28 entries, do not change.
+    mAnalyticsItem->setCString(MM_PREFIX "encoding", toString(record->mFormat).c_str());
+    mAnalyticsItem->setCString(MM_PREFIX "source", toString(record->mAttributes.source).c_str());
+    mAnalyticsItem->setInt32(MM_PREFIX "latency", (int32_t)record->mLatency); // bad estimate.
+    mAnalyticsItem->setInt32(MM_PREFIX "samplerate", (int32_t)record->mSampleRate);
+    mAnalyticsItem->setInt32(MM_PREFIX "channels", (int32_t)record->mChannelCount);
 
-    mAnalyticsItem->setInt32(kAudioRecordLatency, record->mLatency);
-    mAnalyticsItem->setInt32(kAudioRecordSampleRate, record->mSampleRate);
-    mAnalyticsItem->setInt32(kAudioRecordChannelCount, record->mChannelCount);
-    mAnalyticsItem->setCString(kAudioRecordEncoding,
-                               audioFormatTypeString(record->mFormat).c_str());
-    mAnalyticsItem->setCString(kAudioRecordSource,
-                               audioSourceString(record->mAttributes.source).c_str());
+    // Non-API entries, these can change.
+    mAnalyticsItem->setInt32(MM_PREFIX "portId", (int32_t)record->mPortId);
+    mAnalyticsItem->setInt32(MM_PREFIX "frameCount", (int32_t)record->mFrameCount);
+    mAnalyticsItem->setCString(MM_PREFIX "attributes", toString(record->mAttributes).c_str());
+    mAnalyticsItem->setInt64(MM_PREFIX "channelMask", (int64_t)record->mChannelMask);
 
-    // log total duration recording, including anything currently running [and count].
-    nsecs_t active = 0;
+    // log total duration recording, including anything currently running.
+    int64_t activeNs = 0;
     if (mStartedNs != 0) {
-        active = systemTime() - mStartedNs;
+        activeNs = systemTime() - mStartedNs;
     }
-    mAnalyticsItem->setInt64(kAudioRecordDuration, (mDurationNs + active) / (1000 * 1000));
-    mAnalyticsItem->setInt32(kAudioRecordCount, mCount);
-
-    // XXX I don't know that this adds a lot of value, long term
-    if (mCreatedNs != 0) {
-        mAnalyticsItem->setInt64(kAudioRecordCreated, mCreatedNs / (1000 * 1000));
-    }
+    mAnalyticsItem->setDouble(MM_PREFIX "durationMs", (mDurationNs + activeNs) * 1e-6);
+    mAnalyticsItem->setInt64(MM_PREFIX "startCount", (int64_t)mCount);
 
     if (mLastError != NO_ERROR) {
-        mAnalyticsItem->setInt32(kAudioRecordError, mLastError);
-        mAnalyticsItem->setCString(kAudioRecordErrorFunction, mLastErrorFunc.c_str());
+        mAnalyticsItem->setInt32(MM_PREFIX "lastError.code", (int32_t)mLastError);
+        mAnalyticsItem->setCString(MM_PREFIX "lastError.at", mLastErrorFunc.c_str());
     }
 }
 
@@ -150,7 +121,9 @@
     : mActive(false), mStatus(NO_INIT), mOpPackageName(opPackageName),
       mSessionId(AUDIO_SESSION_ALLOCATE),
       mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT),
-      mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE), mRoutedDeviceId(AUDIO_PORT_HANDLE_NONE)
+      mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE), mRoutedDeviceId(AUDIO_PORT_HANDLE_NONE),
+      mSelectedMicDirection(MIC_DIRECTION_UNSPECIFIED),
+      mSelectedMicFieldDimension(MIC_FIELD_DIMENSION_DEFAULT)
 {
 }
 
@@ -170,7 +143,9 @@
         uid_t uid,
         pid_t pid,
         const audio_attributes_t* pAttributes,
-        audio_port_handle_t selectedDeviceId)
+        audio_port_handle_t selectedDeviceId,
+        audio_microphone_direction_t selectedMicDirection,
+        float microphoneFieldDimension)
     : mActive(false),
       mStatus(NO_INIT),
       mOpPackageName(opPackageName),
@@ -181,7 +156,8 @@
 {
     (void)set(inputSource, sampleRate, format, channelMask, frameCount, cbf, user,
             notificationFrames, false /*threadCanCallJava*/, sessionId, transferType, flags,
-            uid, pid, pAttributes, selectedDeviceId);
+            uid, pid, pAttributes, selectedDeviceId,
+            selectedMicDirection, microphoneFieldDimension);
 }
 
 AudioRecord::~AudioRecord()
@@ -201,15 +177,15 @@
         }
         // No lock here: worst case we remove a NULL callback which will be a nop
         if (mDeviceCallback != 0 && mInput != AUDIO_IO_HANDLE_NONE) {
-            AudioSystem::removeAudioDeviceCallback(this, mInput);
+            AudioSystem::removeAudioDeviceCallback(this, mInput, mPortId);
         }
         IInterface::asBinder(mAudioRecord)->unlinkToDeath(mDeathNotifier, this);
         mAudioRecord.clear();
         mCblkMemory.clear();
         mBufferMemory.clear();
         IPCThreadState::self()->flushCommands();
-        ALOGV("~AudioRecord, releasing session id %d",
-                mSessionId);
+        ALOGV("%s(%d): releasing session id %d",
+                __func__, mPortId, mSessionId);
         AudioSystem::releaseAudioSessionId(mSessionId, -1 /*pid*/);
     }
 }
@@ -230,20 +206,28 @@
         uid_t uid,
         pid_t pid,
         const audio_attributes_t* pAttributes,
-        audio_port_handle_t selectedDeviceId)
+        audio_port_handle_t selectedDeviceId,
+        audio_microphone_direction_t selectedMicDirection,
+        float microphoneFieldDimension)
 {
     status_t status = NO_ERROR;
     uint32_t channelCount;
     pid_t callingPid;
     pid_t myPid;
 
-    ALOGV("set(): inputSource %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
+    // Note mPortId is not valid until the track is created, so omit mPortId in ALOG for set.
+    ALOGV("%s(): inputSource %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
           "notificationFrames %u, sessionId %d, transferType %d, flags %#x, opPackageName %s "
           "uid %d, pid %d",
+          __func__,
           inputSource, sampleRate, format, channelMask, frameCount, notificationFrames,
           sessionId, transferType, flags, String8(mOpPackageName).string(), uid, pid);
 
+    mTracker.reset(new RecordingActivityTracker());
+
     mSelectedDeviceId = selectedDeviceId;
+    mSelectedMicDirection = selectedMicDirection;
+    mSelectedMicFieldDimension = microphoneFieldDimension;
 
     switch (transferType) {
     case TRANSFER_DEFAULT:
@@ -255,7 +239,7 @@
         break;
     case TRANSFER_CALLBACK:
         if (cbf == NULL) {
-            ALOGE("Transfer type TRANSFER_CALLBACK but cbf == NULL");
+            ALOGE("%s(): Transfer type TRANSFER_CALLBACK but cbf == NULL", __func__);
             status = BAD_VALUE;
             goto exit;
         }
@@ -264,7 +248,7 @@
     case TRANSFER_SYNC:
         break;
     default:
-        ALOGE("Invalid transfer type %d", transferType);
+        ALOGE("%s(): Invalid transfer type %d", __func__, transferType);
         status = BAD_VALUE;
         goto exit;
     }
@@ -272,7 +256,7 @@
 
     // invariant that mAudioRecord != 0 is true only after set() returns successfully
     if (mAudioRecord != 0) {
-        ALOGE("Track already in use");
+        ALOGE("%s(): Track already in use", __func__);
         status = INVALID_OPERATION;
         goto exit;
     }
@@ -283,8 +267,8 @@
     } else {
         // stream type shouldn't be looked at, this track has audio attributes
         memcpy(&mAttributes, pAttributes, sizeof(audio_attributes_t));
-        ALOGV("Building AudioRecord with attributes: source=%d flags=0x%x tags=[%s]",
-              mAttributes.source, mAttributes.flags, mAttributes.tags);
+        ALOGV("%s(): Building AudioRecord with attributes: source=%d flags=0x%x tags=[%s]",
+                __func__, mAttributes.source, mAttributes.flags, mAttributes.tags);
     }
 
     mSampleRate = sampleRate;
@@ -297,14 +281,14 @@
     // validate parameters
     // AudioFlinger capture only supports linear PCM
     if (!audio_is_valid_format(format) || !audio_is_linear_pcm(format)) {
-        ALOGE("Format %#x is not linear pcm", format);
+        ALOGE("%s(): Format %#x is not linear pcm", __func__, format);
         status = BAD_VALUE;
         goto exit;
     }
     mFormat = format;
 
     if (!audio_is_input_channel(channelMask)) {
-        ALOGE("Invalid channel mask %#x", channelMask);
+        ALOGE("%s(): Invalid channel mask %#x", __func__, channelMask);
         status = BAD_VALUE;
         goto exit;
     }
@@ -325,7 +309,7 @@
     // mNotificationFramesAct is initialized in createRecord_l
 
     mSessionId = sessionId;
-    ALOGV("set(): mSessionId %d", mSessionId);
+    ALOGV("%s(): mSessionId %d", __func__, mSessionId);
 
     callingPid = IPCThreadState::self()->getCallingPid();
     myPid = getpid();
@@ -344,13 +328,18 @@
     mCbf = cbf;
 
     if (cbf != NULL) {
-        mAudioRecordThread = new AudioRecordThread(*this, threadCanCallJava);
+        mAudioRecordThread = new AudioRecordThread(*this);
         mAudioRecordThread->run("AudioRecord", ANDROID_PRIORITY_AUDIO);
         // thread begins in paused state, and will not reference us until start()
     }
 
     // create the IAudioRecord
-    status = createRecord_l(0 /*epoch*/, mOpPackageName);
+    {
+        AutoMutex lock(mLock);
+        status = createRecord_l(0 /*epoch*/, mOpPackageName);
+    }
+
+    ALOGV("%s(%d): status %d", __func__, mPortId, status);
 
     if (status != NO_ERROR) {
         if (mAudioRecordThread != 0) {
@@ -387,7 +376,7 @@
 
 status_t AudioRecord::start(AudioSystem::sync_event_t event, audio_session_t triggerSession)
 {
-    ALOGV("start, sync event %d trigger session %d", event, triggerSession);
+    ALOGV("%s(%d): sync event %d trigger session %d", __func__, mPortId, event, triggerSession);
 
     AutoMutex lock(mLock);
     if (mActive) {
@@ -413,6 +402,7 @@
     // This is legacy behavior.  This is not done in stop() to avoid a race condition
     // where the last marker event is issued twice.
     mMarkerReached = false;
+    // mActive is checked by restoreRecord_l
     mActive = true;
 
     status_t status = NO_ERROR;
@@ -426,10 +416,16 @@
         status = restoreRecord_l("start");
     }
 
+    // Call these directly because we are already holding the lock.
+    mAudioRecord->setPreferredMicrophoneDirection(mSelectedMicDirection);
+    mAudioRecord->setPreferredMicrophoneFieldDimension(mSelectedMicFieldDimension);
+
     if (status != NO_ERROR) {
         mActive = false;
-        ALOGE("start() status %d", status);
+        ALOGE("%s(%d): status %d", __func__, mPortId, status);
+        mMediaMetrics.markError(status, __FUNCTION__);
     } else {
+        mTracker->recordingStarted();
         sp<AudioRecordThread> t = mAudioRecordThread;
         if (t != 0) {
             t->resume();
@@ -442,16 +438,13 @@
         // we've successfully started, log that time
         mMediaMetrics.logStart(systemTime());
     }
-
-    if (status != NO_ERROR) {
-        mMediaMetrics.markError(status, __FUNCTION__);
-    }
     return status;
 }
 
 void AudioRecord::stop()
 {
     AutoMutex lock(mLock);
+    ALOGV("%s(%d): mActive:%d\n", __func__, mPortId, mActive);
     if (!mActive) {
         return;
     }
@@ -459,6 +452,7 @@
     mActive = false;
     mProxy->interrupt();
     mAudioRecord->stop();
+    mTracker->recordingStopped();
 
     // Note: legacy handling - stop does not clear record marker and
     // periodic update position; we update those on start().
@@ -630,8 +624,8 @@
     String8 result;
 
     result.append(" AudioRecord::dump\n");
-    result.appendFormat("  status(%d), active(%d), session Id(%d)\n",
-                        mStatus, mActive, mSessionId);
+    result.appendFormat("  id(%d) status(%d), active(%d), session Id(%d)\n",
+                        mPortId, mStatus, mActive, mSessionId);
     result.appendFormat("  flags(%#x), req. flags(%#x), audio source(%d)\n",
                         mFlags, mOrigFlags, mAttributes.source);
     result.appendFormat("  format(%#x), channel mask(%#x), channel count(%u), sample rate(%u)\n",
@@ -642,6 +636,8 @@
              mNotificationFramesAct, mNotificationFramesReq);
     result.appendFormat("  input(%d), latency(%u), selected device Id(%d), routed device Id(%d)\n",
                         mInput, mLatency, mSelectedDeviceId, mRoutedDeviceId);
+    result.appendFormat("  mic direction(%d) mic field dimension(%f)",
+                        mSelectedMicDirection, mSelectedMicFieldDimension);
     ::write(fd, result.string(), result.size());
     return NO_ERROR;
 }
@@ -673,7 +669,7 @@
     status_t status;
 
     if (audioFlinger == 0) {
-        ALOGE("Could not get audioflinger");
+        ALOGE("%s(%d): Could not get audioflinger", __func__, mPortId);
         status = NO_INIT;
         goto exit;
     }
@@ -700,7 +696,8 @@
             // use case 3: obtain/release mode
             (mTransfer == TRANSFER_OBTAIN);
         if (!useCaseAllowed) {
-            ALOGW("AUDIO_INPUT_FLAG_FAST denied, incompatible transfer = %s",
+            ALOGW("%s(%d): AUDIO_INPUT_FLAG_FAST denied, incompatible transfer = %s",
+                  __func__, mPortId,
                   convertTransferToText(mTransfer));
             mFlags = (audio_input_flags_t) (mFlags & ~(AUDIO_INPUT_FLAG_FAST |
                     AUDIO_INPUT_FLAG_RAW));
@@ -720,6 +717,7 @@
         }
     }
     input.opPackageName = opPackageName;
+    input.riid = mTracker->getRiid();
 
     input.flags = mFlags;
     // The notification frame count is the period between callbacks, as suggested by the client
@@ -735,7 +733,8 @@
                                                               &status);
 
     if (status != NO_ERROR) {
-        ALOGE("AudioFlinger could not create record track, status: %d", status);
+        ALOGE("%s(%d): AudioFlinger could not create record track, status: %d",
+              __func__, mPortId, status);
         goto exit;
     }
     ALOG_ASSERT(record != 0);
@@ -745,7 +744,8 @@
 
     mAwaitBoost = false;
     if (output.flags & AUDIO_INPUT_FLAG_FAST) {
-        ALOGI("AUDIO_INPUT_FLAG_FAST successful; frameCount %zu -> %zu",
+        ALOGI("%s(%d): AUDIO_INPUT_FLAG_FAST successful; frameCount %zu -> %zu",
+              __func__, mPortId,
               mReqFrameCount, output.frameCount);
         mAwaitBoost = true;
     }
@@ -755,13 +755,13 @@
     mSampleRate = output.sampleRate;
 
     if (output.cblk == 0) {
-        ALOGE("Could not get control block");
+        ALOGE("%s(%d): Could not get control block", __func__, mPortId);
         status = NO_INIT;
         goto exit;
     }
     iMemPointer = output.cblk ->pointer();
     if (iMemPointer == NULL) {
-        ALOGE("Could not get control block pointer");
+        ALOGE("%s(%d): Could not get control block pointer", __func__, mPortId);
         status = NO_INIT;
         goto exit;
     }
@@ -776,7 +776,7 @@
     } else {
         buffers = output.buffers->pointer();
         if (buffers == NULL) {
-            ALOGE("Could not get buffer pointer");
+            ALOGE("%s(%d): Could not get buffer pointer", __func__, mPortId);
             status = NO_INIT;
             goto exit;
         }
@@ -795,26 +795,29 @@
     mCblk = cblk;
     // note that output.frameCount is the (possibly revised) value of mReqFrameCount
     if (output.frameCount < mReqFrameCount || (mReqFrameCount == 0 && output.frameCount == 0)) {
-        ALOGW("Requested frameCount %zu but received frameCount %zu",
+        ALOGW("%s(%d): Requested frameCount %zu but received frameCount %zu",
+              __func__, output.portId,
               mReqFrameCount,  output.frameCount);
     }
 
     // Make sure that application is notified with sufficient margin before overrun.
     // The computation is done on server side.
     if (mNotificationFramesReq > 0 && output.notificationFrameCount != mNotificationFramesReq) {
-        ALOGW("Server adjusted notificationFrames from %u to %zu for frameCount %zu",
+        ALOGW("%s(%d): Server adjusted notificationFrames from %u to %zu for frameCount %zu",
+                __func__, output.portId,
                 mNotificationFramesReq, output.notificationFrameCount, output.frameCount);
     }
     mNotificationFramesAct = (uint32_t)output.notificationFrameCount;
 
     //mInput != input includes the case where mInput == AUDIO_IO_HANDLE_NONE for first creation
-    if (mDeviceCallback != 0 && mInput != output.inputId) {
+    if (mDeviceCallback != 0) {
         if (mInput != AUDIO_IO_HANDLE_NONE) {
-            AudioSystem::removeAudioDeviceCallback(this, mInput);
+            AudioSystem::removeAudioDeviceCallback(this, mInput, mPortId);
         }
-        AudioSystem::addAudioDeviceCallback(this, output.inputId);
+        AudioSystem::addAudioDeviceCallback(this, output.inputId, output.portId);
     }
 
+    mPortId = output.portId;
     // We retain a copy of the I/O handle, but don't own the reference
     mInput = output.inputId;
     mRefreshRemaining = true;
@@ -865,12 +868,12 @@
     } else if (waitCount == 0) {
         requested = &ClientProxy::kNonBlocking;
     } else if (waitCount > 0) {
-        long long ms = WAIT_PERIOD_MS * (long long) waitCount;
+        time_t ms = WAIT_PERIOD_MS * (time_t) waitCount;
         timeout.tv_sec = ms / 1000;
-        timeout.tv_nsec = (int) (ms % 1000) * 1000000;
+        timeout.tv_nsec = (long) (ms % 1000) * 1000000;
         requested = &timeout;
     } else {
-        ALOGE("%s invalid waitCount %d", __func__, waitCount);
+        ALOGE("%s(%d): invalid waitCount %d", __func__, mPortId, waitCount);
         requested = NULL;
     }
     return obtainBuffer(audioBuffer, requested, NULL /*elapsed*/, nonContig);
@@ -979,7 +982,8 @@
     if (ssize_t(userSize) < 0 || (buffer == NULL && userSize != 0)) {
         // sanity-check. user is most-likely passing an error code, and it would
         // make the return value ambiguous (actualSize vs error).
-        ALOGE("AudioRecord::read(buffer=%p, size=%zu (%zu)", buffer, userSize, userSize);
+        ALOGE("%s(%d) (buffer=%p, size=%zu (%zu)",
+                __func__, mPortId, buffer, userSize, userSize);
         return BAD_VALUE;
     }
 
@@ -1036,7 +1040,7 @@
             pollUs <<= 1;
         } while (tryCounter-- > 0);
         if (tryCounter < 0) {
-            ALOGE("did not receive expected priority boost on time");
+            ALOGE("%s(%d): did not receive expected priority boost on time", __func__, mPortId);
         }
         // Run again immediately
         return 0;
@@ -1159,7 +1163,8 @@
     if (ns != NS_WHENEVER) {
         timeout.tv_sec = ns / 1000000000LL;
         timeout.tv_nsec = ns % 1000000000LL;
-        ALOGV("timeout %ld.%03d", timeout.tv_sec, (int) timeout.tv_nsec / 1000000);
+        ALOGV("%s(%d): timeout %ld.%03d",
+                __func__, mPortId, timeout.tv_sec, (int) timeout.tv_nsec / 1000000);
         requested = &timeout;
     }
 
@@ -1171,16 +1176,18 @@
         size_t nonContig;
         status_t err = obtainBuffer(&audioBuffer, requested, NULL, &nonContig);
         LOG_ALWAYS_FATAL_IF((err != NO_ERROR) != (audioBuffer.frameCount == 0),
-                "obtainBuffer() err=%d frameCount=%zu", err, audioBuffer.frameCount);
+                "%s(%d): obtainBuffer() err=%d frameCount=%zu",
+                __func__, mPortId, err, audioBuffer.frameCount);
         requested = &ClientProxy::kNonBlocking;
         size_t avail = audioBuffer.frameCount + nonContig;
-        ALOGV("obtainBuffer(%u) returned %zu = %zu + %zu err %d",
-                mRemainingFrames, avail, audioBuffer.frameCount, nonContig, err);
+        ALOGV("%s(%d): obtainBuffer(%u) returned %zu = %zu + %zu err %d",
+                __func__, mPortId, mRemainingFrames, avail, audioBuffer.frameCount, nonContig, err);
         if (err != NO_ERROR) {
             if (err == TIMED_OUT || err == WOULD_BLOCK || err == -EINTR) {
                 break;
             }
-            ALOGE("Error %d obtaining an audio buffer, giving up.", err);
+            ALOGE("%s(%d): Error %d obtaining an audio buffer, giving up.",
+                    __func__, mPortId, err);
             return NS_NEVER;
         }
 
@@ -1202,8 +1209,8 @@
 
         // Sanity check on returned size
         if (ssize_t(readSize) < 0 || readSize > reqSize) {
-            ALOGE("EVENT_MORE_DATA requested %zu bytes but callback returned %zd bytes",
-                    reqSize, ssize_t(readSize));
+            ALOGE("%s(%d):  EVENT_MORE_DATA requested %zu bytes but callback returned %zd bytes",
+                    __func__, mPortId, reqSize, ssize_t(readSize));
             return NS_NEVER;
         }
 
@@ -1263,7 +1270,7 @@
 
 status_t AudioRecord::restoreRecord_l(const char *from)
 {
-    ALOGW("dead IAudioRecord, creating a new one from %s()", from);
+    ALOGW("%s(%d): dead IAudioRecord, creating a new one from %s()", __func__, mPortId, from);
     ++mSequence;
 
     const int INITIAL_RETRIES = 3;
@@ -1283,10 +1290,7 @@
     mNewPosition = position + mUpdatePeriod;
     status_t result = createRecord_l(position, mOpPackageName);
 
-    if (result != NO_ERROR) {
-        ALOGW("%s(): createRecord_l failed, do not retry", __func__);
-        retries = 0;
-    } else {
+    if (result == NO_ERROR) {
         if (mActive) {
             // callback thread or sync event hasn't changed
             // FIXME this fails if we have a new AudioFlinger instance
@@ -1297,15 +1301,17 @@
     }
 
     if (result != NO_ERROR) {
-        ALOGW("%s() failed status %d, retries %d", __func__, result, retries);
+        ALOGW("%s(%d): failed status %d, retries %d", __func__, mPortId, result, retries);
         if (--retries > 0) {
+            // leave time for an eventual race condition to clear before retrying
+            usleep(500000);
             goto retry;
         }
-    }
-
-    if (result != NO_ERROR) {
-        ALOGW("restoreRecord_l() failed status %d", result);
-        mActive = false;
+        // if no retries left, set invalid bit to force restoring at next occasion
+        // and avoid inconsistent active state on client and server sides
+        if (mCblk != nullptr) {
+            android_atomic_or(CBLK_INVALID, &mCblk->mFlags);
+        }
     }
 
     return result;
@@ -1314,21 +1320,21 @@
 status_t AudioRecord::addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback)
 {
     if (callback == 0) {
-        ALOGW("%s adding NULL callback!", __FUNCTION__);
+        ALOGW("%s(%d): adding NULL callback!", __func__, mPortId);
         return BAD_VALUE;
     }
     AutoMutex lock(mLock);
     if (mDeviceCallback.unsafe_get() == callback.get()) {
-        ALOGW("%s adding same callback!", __FUNCTION__);
+        ALOGW("%s(%d): adding same callback!", __func__, mPortId);
         return INVALID_OPERATION;
     }
     status_t status = NO_ERROR;
     if (mInput != AUDIO_IO_HANDLE_NONE) {
         if (mDeviceCallback != 0) {
-            ALOGW("%s callback already present!", __FUNCTION__);
-            AudioSystem::removeAudioDeviceCallback(this, mInput);
+            ALOGW("%s(%d): callback already present!", __func__, mPortId);
+            AudioSystem::removeAudioDeviceCallback(this, mInput, mPortId);
         }
-        status = AudioSystem::addAudioDeviceCallback(this, mInput);
+        status = AudioSystem::addAudioDeviceCallback(this, mInput, mPortId);
     }
     mDeviceCallback = callback;
     return status;
@@ -1338,17 +1344,17 @@
         const sp<AudioSystem::AudioDeviceCallback>& callback)
 {
     if (callback == 0) {
-        ALOGW("%s removing NULL callback!", __FUNCTION__);
+        ALOGW("%s(%d): removing NULL callback!", __func__, mPortId);
         return BAD_VALUE;
     }
     AutoMutex lock(mLock);
     if (mDeviceCallback.unsafe_get() != callback.get()) {
-        ALOGW("%s removing different callback!", __FUNCTION__);
+        ALOGW("%s(%d): removing different callback!", __func__, mPortId);
         return INVALID_OPERATION;
     }
     mDeviceCallback.clear();
     if (mInput != AUDIO_IO_HANDLE_NONE) {
-        AudioSystem::removeAudioDeviceCallback(this, mInput);
+        AudioSystem::removeAudioDeviceCallback(this, mInput, mPortId);
     }
     return NO_ERROR;
 }
@@ -1382,6 +1388,39 @@
     return mAudioRecord->getActiveMicrophones(activeMicrophones).transactionError();
 }
 
+status_t AudioRecord::setPreferredMicrophoneDirection(audio_microphone_direction_t direction)
+{
+    AutoMutex lock(mLock);
+    if (mSelectedMicDirection == direction) {
+        // NOP
+        return OK;
+    }
+
+    mSelectedMicDirection = direction;
+    if (mAudioRecord == 0) {
+        // the internal AudioRecord hasn't be created yet, so just stash the attribute.
+        return OK;
+    } else {
+        return mAudioRecord->setPreferredMicrophoneDirection(direction).transactionError();
+    }
+}
+
+status_t AudioRecord::setPreferredMicrophoneFieldDimension(float zoom) {
+    AutoMutex lock(mLock);
+    if (mSelectedMicFieldDimension == zoom) {
+        // NOP
+        return OK;
+    }
+
+    mSelectedMicFieldDimension = zoom;
+    if (mAudioRecord == 0) {
+        // the internal AudioRecord hasn't be created yet, so just stash the attribute.
+        return OK;
+    } else {
+        return mAudioRecord->setPreferredMicrophoneFieldDimension(zoom).transactionError();
+    }
+}
+
 // =========================================================================
 
 void AudioRecord::DeathNotifier::binderDied(const wp<IBinder>& who __unused)
@@ -1395,8 +1434,9 @@
 
 // =========================================================================
 
-AudioRecord::AudioRecordThread::AudioRecordThread(AudioRecord& receiver, bool bCanCallJava)
-    : Thread(bCanCallJava), mReceiver(receiver), mPaused(true), mPausedInt(false), mPausedNs(0LL),
+AudioRecord::AudioRecordThread::AudioRecordThread(AudioRecord& receiver)
+    : Thread(true /* bCanCallJava */)  // binder recursion on restoreRecord_l() may call Java.
+    , mReceiver(receiver), mPaused(true), mPausedInt(false), mPausedNs(0LL),
       mIgnoreNextPausedInt(false)
 {
 }
@@ -1446,9 +1486,9 @@
     case NS_WHENEVER:
         // Event driven: call wake() when callback notifications conditions change.
         ns = INT64_MAX;
-        // fall through
+        FALLTHROUGH_INTENDED;
     default:
-        LOG_ALWAYS_FATAL_IF(ns < 0, "processAudioBuffer() returned %" PRId64, ns);
+        LOG_ALWAYS_FATAL_IF(ns < 0, "%s() returned %lld", __func__, (long long)ns);
         pauseInternal(ns);
         return true;
     }
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index c072901..02dc516 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -25,6 +25,7 @@
 #include <media/AudioSystem.h>
 #include <media/IAudioFlinger.h>
 #include <media/IAudioPolicyService.h>
+#include <media/TypeConverter.h>
 #include <math.h>
 
 #include <system/audio.h>
@@ -427,6 +428,7 @@
 
 audio_unique_id_t AudioSystem::newAudioUniqueId(audio_unique_id_use_t use)
 {
+    // Must not use AF as IDs will re-roll on audioserver restart, b/130369529.
     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
     if (af == 0) return AUDIO_UNIQUE_ID_ALLOCATE;
     return af->newAudioUniqueId(use);
@@ -521,10 +523,10 @@
     if (ioDesc == 0 || ioDesc->mIoHandle == AUDIO_IO_HANDLE_NONE) return;
 
     audio_port_handle_t deviceId = AUDIO_PORT_HANDLE_NONE;
-    Vector < wp<AudioDeviceCallback> > callbacks;
-
+    std::vector<sp<AudioDeviceCallback>> callbacksToCall;
     {
         Mutex::Autolock _l(mLock);
+        auto callbacks = std::map<audio_port_handle_t, wp<AudioDeviceCallback>>();
 
         switch (event) {
         case AUDIO_OUTPUT_OPENED:
@@ -542,9 +544,9 @@
             if (ioDesc->getDeviceId() != AUDIO_PORT_HANDLE_NONE) {
                 deviceId = ioDesc->getDeviceId();
                 if (event == AUDIO_OUTPUT_OPENED || event == AUDIO_INPUT_OPENED) {
-                    ssize_t ioIndex = mAudioDeviceCallbacks.indexOfKey(ioDesc->mIoHandle);
-                    if (ioIndex >= 0) {
-                        callbacks = mAudioDeviceCallbacks.valueAt(ioIndex);
+                    auto it = mAudioDeviceCallbacks.find(ioDesc->mIoHandle);
+                    if (it != mAudioDeviceCallbacks.end()) {
+                        callbacks = it->second;
                     }
                 }
             }
@@ -568,7 +570,7 @@
                   event == AUDIO_OUTPUT_CLOSED ? "output" : "input", ioDesc->mIoHandle);
 
             mIoDescriptors.removeItem(ioDesc->mIoHandle);
-            mAudioDeviceCallbacks.removeItem(ioDesc->mIoHandle);
+            mAudioDeviceCallbacks.erase(ioDesc->mIoHandle);
             } break;
 
         case AUDIO_OUTPUT_CONFIG_CHANGED:
@@ -584,9 +586,9 @@
 
             if (deviceId != ioDesc->getDeviceId()) {
                 deviceId = ioDesc->getDeviceId();
-                ssize_t ioIndex = mAudioDeviceCallbacks.indexOfKey(ioDesc->mIoHandle);
-                if (ioIndex >= 0) {
-                    callbacks = mAudioDeviceCallbacks.valueAt(ioIndex);
+                auto it = mAudioDeviceCallbacks.find(ioDesc->mIoHandle);
+                if (it != mAudioDeviceCallbacks.end()) {
+                    callbacks = it->second;
                 }
             }
             ALOGV("ioConfigChanged() new config for %s %d samplingRate %u, format %#x "
@@ -597,25 +599,40 @@
                     ioDesc->getDeviceId());
 
         } break;
+        case AUDIO_CLIENT_STARTED: {
+            sp<AudioIoDescriptor> oldDesc = getIoDescriptor_l(ioDesc->mIoHandle);
+            if (oldDesc == 0) {
+                ALOGW("ioConfigChanged() start client on unknown io! %d", ioDesc->mIoHandle);
+                break;
+            }
+            ALOGV("ioConfigChanged() AUDIO_CLIENT_STARTED  io %d port %d num callbacks %zu",
+                ioDesc->mIoHandle, ioDesc->mPortId, mAudioDeviceCallbacks.size());
+            oldDesc->mPatch = ioDesc->mPatch;
+            auto it = mAudioDeviceCallbacks.find(ioDesc->mIoHandle);
+            if (it != mAudioDeviceCallbacks.end()) {
+                auto cbks = it->second;
+                auto it2 = cbks.find(ioDesc->mPortId);
+                if (it2 != cbks.end()) {
+                   callbacks.emplace(ioDesc->mPortId, it2->second);
+                   deviceId = oldDesc->getDeviceId();
+                }
+            }
+        } break;
+        }
+
+        for (auto wpCbk : callbacks) {
+            sp<AudioDeviceCallback> spCbk = wpCbk.second.promote();
+            if (spCbk != nullptr) {
+                callbacksToCall.push_back(spCbk);
+            }
         }
     }
-    bool callbackRemoved = false;
-    // callbacks.size() != 0 =>  ioDesc->mIoHandle and deviceId are valid
-    for (size_t i = 0; i < callbacks.size(); ) {
-        sp<AudioDeviceCallback> callback = callbacks[i].promote();
-        if (callback.get() != nullptr) {
-            callback->onAudioDeviceUpdate(ioDesc->mIoHandle, deviceId);
-            i++;
-        } else {
-            callbacks.removeAt(i);
-            callbackRemoved = true;
-        }
-    }
-    // clean up callback list while we are here if some clients have disappeared without
-    // unregistering their callback
-    if (callbackRemoved) {
-        Mutex::Autolock _l(mLock);
-        mAudioDeviceCallbacks.replaceValueFor(ioDesc->mIoHandle, callbacks);
+
+    // Callbacks must be called without mLock held. May lead to dead lock if calling for
+    // example getRoutedDevice that updates the device and tries to acquire mLock.
+    for (auto cb  : callbacksToCall) {
+        // If callbacksToCall is not empty, it implies ioDesc->mIoHandle and deviceId are valid
+        cb->onAudioDeviceUpdate(ioDesc->mIoHandle, deviceId);
     }
 }
 
@@ -668,50 +685,34 @@
 }
 
 status_t AudioSystem::AudioFlingerClient::addAudioDeviceCallback(
-        const wp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo)
+        const wp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo,
+        audio_port_handle_t portId)
 {
+    ALOGV("%s audioIo %d portId %d", __func__, audioIo, portId);
     Mutex::Autolock _l(mLock);
-    Vector < wp<AudioDeviceCallback> > callbacks;
-    ssize_t ioIndex = mAudioDeviceCallbacks.indexOfKey(audioIo);
-    if (ioIndex >= 0) {
-        callbacks = mAudioDeviceCallbacks.valueAt(ioIndex);
+    auto& callbacks = mAudioDeviceCallbacks.emplace(audioIo, std::map<audio_port_handle_t, wp<AudioDeviceCallback>>()).first->second;
+    auto result = callbacks.try_emplace(portId, callback);
+    if (!result.second) {
+        return INVALID_OPERATION;
     }
-
-    for (size_t cbIndex = 0; cbIndex < callbacks.size(); cbIndex++) {
-        if (callbacks[cbIndex].unsafe_get() == callback.unsafe_get()) {
-            return INVALID_OPERATION;
-        }
-    }
-    callbacks.add(callback);
-
-    mAudioDeviceCallbacks.replaceValueFor(audioIo, callbacks);
     return NO_ERROR;
 }
 
 status_t AudioSystem::AudioFlingerClient::removeAudioDeviceCallback(
-        const wp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo)
+        const wp<AudioDeviceCallback>& callback __unused, audio_io_handle_t audioIo,
+        audio_port_handle_t portId)
 {
+    ALOGV("%s audioIo %d portId %d", __func__, audioIo, portId);
     Mutex::Autolock _l(mLock);
-    ssize_t ioIndex = mAudioDeviceCallbacks.indexOfKey(audioIo);
-    if (ioIndex < 0) {
+    auto it = mAudioDeviceCallbacks.find(audioIo);
+    if (it == mAudioDeviceCallbacks.end()) {
         return INVALID_OPERATION;
     }
-    Vector < wp<AudioDeviceCallback> > callbacks = mAudioDeviceCallbacks.valueAt(ioIndex);
-
-    size_t cbIndex;
-    for (cbIndex = 0; cbIndex < callbacks.size(); cbIndex++) {
-        if (callbacks[cbIndex].unsafe_get() == callback.unsafe_get()) {
-            break;
-        }
-    }
-    if (cbIndex == callbacks.size()) {
+    if (it->second.erase(portId) == 0) {
         return INVALID_OPERATION;
     }
-    callbacks.removeAt(cbIndex);
-    if (callbacks.size() != 0) {
-        mAudioDeviceCallbacks.replaceValueFor(audioIo, callbacks);
-    } else {
-        mAudioDeviceCallbacks.removeItem(audioIo);
+    if (it->second.size() == 0) {
+        mAudioDeviceCallbacks.erase(audioIo);
     }
     return NO_ERROR;
 }
@@ -773,6 +774,7 @@
         int64_t token = IPCThreadState::self()->clearCallingIdentity();
         ap->registerClient(apc);
         ap->setAudioPortCallbacksEnabled(apc->isAudioPortCbEnabled());
+        ap->setAudioVolumeGroupCallbacksEnabled(apc->isAudioVolumeGroupCbEnabled());
         IPCThreadState::self()->restoreCallingIdentity(token);
     }
 
@@ -784,7 +786,8 @@
 status_t AudioSystem::setDeviceConnectionState(audio_devices_t device,
                                                audio_policy_dev_state_t state,
                                                const char *device_address,
-                                               const char *device_name)
+                                               const char *device_name,
+                                               audio_format_t encodedFormat)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     const char *address = "";
@@ -798,7 +801,7 @@
     if (device_name != NULL) {
         name = device_name;
     }
-    return aps->setDeviceConnectionState(device, state, address, name);
+    return aps->setDeviceConnectionState(device, state, address, name, encodedFormat);
 }
 
 audio_policy_dev_state_t AudioSystem::getDeviceConnectionState(audio_devices_t device,
@@ -812,7 +815,8 @@
 
 status_t AudioSystem::handleDeviceConfigChange(audio_devices_t device,
                                                const char *device_address,
-                                               const char *device_name)
+                                               const char *device_name,
+                                               audio_format_t encodedFormat)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     const char *address = "";
@@ -826,7 +830,7 @@
     if (device_name != NULL) {
         name = device_name;
     }
-    return aps->handleDeviceConfigChange(device, address, name);
+    return aps->handleDeviceConfigChange(device, address, name, encodedFormat);
 }
 
 status_t AudioSystem::setPhoneState(audio_mode_t state)
@@ -860,7 +864,7 @@
     return aps->getOutput(stream);
 }
 
-status_t AudioSystem::getOutputForAttr(const audio_attributes_t *attr,
+status_t AudioSystem::getOutputForAttr(audio_attributes_t *attr,
                                         audio_io_handle_t *output,
                                         audio_session_t session,
                                         audio_stream_type_t *stream,
@@ -869,44 +873,40 @@
                                         const audio_config_t *config,
                                         audio_output_flags_t flags,
                                         audio_port_handle_t *selectedDeviceId,
-                                        audio_port_handle_t *portId)
+                                        audio_port_handle_t *portId,
+                                        std::vector<audio_io_handle_t> *secondaryOutputs)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return NO_INIT;
     return aps->getOutputForAttr(attr, output, session, stream, pid, uid,
                                  config,
-                                 flags, selectedDeviceId, portId);
+                                 flags, selectedDeviceId, portId, secondaryOutputs);
 }
 
-status_t AudioSystem::startOutput(audio_io_handle_t output,
-                                  audio_stream_type_t stream,
-                                  audio_session_t session)
+status_t AudioSystem::startOutput(audio_port_handle_t portId)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return PERMISSION_DENIED;
-    return aps->startOutput(output, stream, session);
+    return aps->startOutput(portId);
 }
 
-status_t AudioSystem::stopOutput(audio_io_handle_t output,
-                                 audio_stream_type_t stream,
-                                 audio_session_t session)
+status_t AudioSystem::stopOutput(audio_port_handle_t portId)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return PERMISSION_DENIED;
-    return aps->stopOutput(output, stream, session);
+    return aps->stopOutput(portId);
 }
 
-void AudioSystem::releaseOutput(audio_io_handle_t output,
-                                audio_stream_type_t stream,
-                                audio_session_t session)
+void AudioSystem::releaseOutput(audio_port_handle_t portId)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return;
-    aps->releaseOutput(output, stream, session);
+    aps->releaseOutput(portId);
 }
 
 status_t AudioSystem::getInputForAttr(const audio_attributes_t *attr,
                                 audio_io_handle_t *input,
+                                audio_unique_id_t riid,
                                 audio_session_t session,
                                 pid_t pid,
                                 uid_t uid,
@@ -919,15 +919,15 @@
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return NO_INIT;
     return aps->getInputForAttr(
-            attr, input, session, pid, uid, opPackageName,
+            attr, input, riid, session, pid, uid, opPackageName,
             config, flags, selectedDeviceId, portId);
 }
 
-status_t AudioSystem::startInput(audio_port_handle_t portId, bool *silenced)
+status_t AudioSystem::startInput(audio_port_handle_t portId)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return PERMISSION_DENIED;
-    return aps->startInput(portId, silenced);
+    return aps->startInput(portId);
 }
 
 status_t AudioSystem::stopInput(audio_port_handle_t portId)
@@ -971,10 +971,42 @@
     return aps->getStreamVolumeIndex(stream, index, device);
 }
 
+status_t AudioSystem::setVolumeIndexForAttributes(const audio_attributes_t &attr,
+                                                  int index,
+                                                  audio_devices_t device)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+    return aps->setVolumeIndexForAttributes(attr, index, device);
+}
+
+status_t AudioSystem::getVolumeIndexForAttributes(const audio_attributes_t &attr,
+                                                  int &index,
+                                                  audio_devices_t device)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+    return aps->getVolumeIndexForAttributes(attr, index, device);
+}
+
+status_t AudioSystem::getMaxVolumeIndexForAttributes(const audio_attributes_t &attr, int &index)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+    return aps->getMaxVolumeIndexForAttributes(attr, index);
+}
+
+status_t AudioSystem::getMinVolumeIndexForAttributes(const audio_attributes_t &attr, int &index)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+    return aps->getMinVolumeIndexForAttributes(attr, index);
+}
+
 uint32_t AudioSystem::getStrategyForStream(audio_stream_type_t stream)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
-    if (aps == 0) return 0;
+    if (aps == 0) return PRODUCT_STRATEGY_NONE;
     return aps->getStrategyForStream(stream);
 }
 
@@ -1018,6 +1050,13 @@
     return aps->setEffectEnabled(id, enabled);
 }
 
+status_t AudioSystem::moveEffectsToIo(const std::vector<int>& ids, audio_io_handle_t io)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+    return aps->moveEffectsToIo(ids, io);
+}
+
 status_t AudioSystem::isStreamActive(audio_stream_type_t stream, bool* state, uint32_t inPastMs)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
@@ -1084,6 +1123,12 @@
     }
 }
 
+status_t AudioSystem::setAllowedCapturePolicy(uid_t uid, audio_flags_mask_t flags) {
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == nullptr) return PERMISSION_DENIED;
+    return aps->setAllowedCapturePolicy(uid, flags);
+}
+
 bool AudioSystem::isOffloadSupported(const audio_offload_info_t& info)
 {
     ALOGV("isOffloadSupported()");
@@ -1174,14 +1219,47 @@
     return (ret < 0) ? INVALID_OPERATION : NO_ERROR;
 }
 
+status_t AudioSystem::addAudioVolumeGroupCallback(const sp<AudioVolumeGroupCallback>& callback)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+
+    Mutex::Autolock _l(gLockAPS);
+    if (gAudioPolicyServiceClient == 0) {
+        return NO_INIT;
+    }
+    int ret = gAudioPolicyServiceClient->addAudioVolumeGroupCallback(callback);
+    if (ret == 1) {
+        aps->setAudioVolumeGroupCallbacksEnabled(true);
+    }
+    return (ret < 0) ? INVALID_OPERATION : NO_ERROR;
+}
+
+status_t AudioSystem::removeAudioVolumeGroupCallback(const sp<AudioVolumeGroupCallback>& callback)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+
+    Mutex::Autolock _l(gLockAPS);
+    if (gAudioPolicyServiceClient == 0) {
+        return NO_INIT;
+    }
+    int ret = gAudioPolicyServiceClient->removeAudioVolumeGroupCallback(callback);
+    if (ret == 0) {
+        aps->setAudioVolumeGroupCallbacksEnabled(false);
+    }
+    return (ret < 0) ? INVALID_OPERATION : NO_ERROR;
+}
+
 status_t AudioSystem::addAudioDeviceCallback(
-        const wp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo)
+        const wp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo,
+        audio_port_handle_t portId)
 {
     const sp<AudioFlingerClient> afc = getAudioFlingerClient();
     if (afc == 0) {
         return NO_INIT;
     }
-    status_t status = afc->addAudioDeviceCallback(callback, audioIo);
+    status_t status = afc->addAudioDeviceCallback(callback, audioIo, portId);
     if (status == NO_ERROR) {
         const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
         if (af != 0) {
@@ -1192,13 +1270,14 @@
 }
 
 status_t AudioSystem::removeAudioDeviceCallback(
-        const wp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo)
+        const wp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo,
+        audio_port_handle_t portId)
 {
     const sp<AudioFlingerClient> afc = getAudioFlingerClient();
     if (afc == 0) {
         return NO_INIT;
     }
-    return afc->removeAudioDeviceCallback(callback, audioIo);
+    return afc->removeAudioDeviceCallback(callback, audioIo, portId);
 }
 
 audio_port_handle_t AudioSystem::getDeviceIdForIo(audio_io_handle_t audioIo)
@@ -1242,20 +1321,33 @@
     return aps->registerPolicyMixes(mixes, registration);
 }
 
-status_t AudioSystem::startAudioSource(const struct audio_port_config *source,
-                                       const audio_attributes_t *attributes,
-                                       audio_patch_handle_t *handle)
+status_t AudioSystem::setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return PERMISSION_DENIED;
-    return aps->startAudioSource(source, attributes, handle);
+    return aps->setUidDeviceAffinities(uid, devices);
 }
 
-status_t AudioSystem::stopAudioSource(audio_patch_handle_t handle)
+status_t AudioSystem::removeUidDeviceAffinities(uid_t uid) {
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+    return aps->removeUidDeviceAffinities(uid);
+}
+
+status_t AudioSystem::startAudioSource(const struct audio_port_config *source,
+                                       const audio_attributes_t *attributes,
+                                       audio_port_handle_t *portId)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return PERMISSION_DENIED;
-    return aps->stopAudioSource(handle);
+    return aps->startAudioSource(source, attributes, portId);
+}
+
+status_t AudioSystem::stopAudioSource(audio_port_handle_t portId)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+    return aps->stopAudioSource(portId);
 }
 
 status_t AudioSystem::setMasterMono(bool mono)
@@ -1272,6 +1364,20 @@
     return aps->getMasterMono(mono);
 }
 
+status_t AudioSystem::setMasterBalance(float balance)
+{
+    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+    if (af == 0) return PERMISSION_DENIED;
+    return af->setMasterBalance(balance);
+}
+
+status_t AudioSystem::getMasterBalance(float *balance)
+{
+    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+    if (af == 0) return PERMISSION_DENIED;
+    return af->getMasterBalance(balance);
+}
+
 float AudioSystem::getStreamVolumeDB(audio_stream_type_t stream, int index, audio_devices_t device)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
@@ -1304,6 +1410,115 @@
     return aps->setSurroundFormatEnabled(audioFormat, enabled);
 }
 
+status_t AudioSystem::setAssistantUid(uid_t uid)
+{
+    const sp <IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+
+    return aps->setAssistantUid(uid);
+}
+
+status_t AudioSystem::setA11yServicesUids(const std::vector<uid_t>& uids)
+{
+    const sp <IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+
+    return aps->setA11yServicesUids(uids);
+}
+
+bool AudioSystem::isHapticPlaybackSupported()
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return false;
+    return aps->isHapticPlaybackSupported();
+}
+
+status_t AudioSystem::getHwOffloadEncodingFormatsSupportedForA2DP(
+                                std::vector<audio_format_t> *formats) {
+    const sp <IAudioPolicyService>
+        & aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+    return aps->getHwOffloadEncodingFormatsSupportedForA2DP(formats);
+}
+
+status_t AudioSystem::listAudioProductStrategies(AudioProductStrategyVector &strategies)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+    return aps->listAudioProductStrategies(strategies);
+}
+
+audio_attributes_t AudioSystem::streamTypeToAttributes(audio_stream_type_t stream)
+{
+    AudioProductStrategyVector strategies;
+    listAudioProductStrategies(strategies);
+    for (const auto &strategy : strategies) {
+        auto attrVect = strategy.getAudioAttributes();
+        auto iter = std::find_if(begin(attrVect), end(attrVect), [&stream](const auto &attributes) {
+                         return attributes.getStreamType() == stream; });
+        if (iter != end(attrVect)) {
+            return iter->getAttributes();
+        }
+    }
+    ALOGE("invalid stream type %s when converting to attributes",  toString(stream).c_str());
+    return AUDIO_ATTRIBUTES_INITIALIZER;
+}
+
+audio_stream_type_t AudioSystem::attributesToStreamType(const audio_attributes_t &attr)
+{
+    product_strategy_t psId;
+    status_t ret = AudioSystem::getProductStrategyFromAudioAttributes(AudioAttributes(attr), psId);
+    if (ret != NO_ERROR) {
+        ALOGE("no strategy found for attributes %s",  toString(attr).c_str());
+        return AUDIO_STREAM_MUSIC;
+    }
+    AudioProductStrategyVector strategies;
+    listAudioProductStrategies(strategies);
+    for (const auto &strategy : strategies) {
+        if (strategy.getId() == psId) {
+            auto attrVect = strategy.getAudioAttributes();
+            auto iter = std::find_if(begin(attrVect), end(attrVect), [&attr](const auto &refAttr) {
+                             return AudioProductStrategy::attributesMatches(
+                                 refAttr.getAttributes(), attr); });
+            if (iter != end(attrVect)) {
+                return iter->getStreamType();
+            }
+        }
+    }
+    ALOGE("invalid attributes %s when converting to stream",  toString(attr).c_str());
+    return AUDIO_STREAM_MUSIC;
+}
+
+status_t AudioSystem::getProductStrategyFromAudioAttributes(const AudioAttributes &aa,
+                                                            product_strategy_t &productStrategy)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+    return aps->getProductStrategyFromAudioAttributes(aa,productStrategy);
+}
+
+status_t AudioSystem::listAudioVolumeGroups(AudioVolumeGroupVector &groups)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+    return aps->listAudioVolumeGroups(groups);
+}
+
+status_t AudioSystem::getVolumeGroupFromAudioAttributes(const AudioAttributes &aa,
+                                                        volume_group_t &volumeGroup)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+    return aps->getVolumeGroupFromAudioAttributes(aa, volumeGroup);
+}
+
+status_t AudioSystem::setRttEnabled(bool enabled)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+    return aps->setRttEnabled(enabled);
+}
+
 // ---------------------------------------------------------------------------
 
 int AudioSystem::AudioPolicyServiceClient::addAudioPortCallback(
@@ -1353,6 +1568,47 @@
     }
 }
 
+// ----------------------------------------------------------------------------
+int AudioSystem::AudioPolicyServiceClient::addAudioVolumeGroupCallback(
+        const sp<AudioVolumeGroupCallback>& callback)
+{
+    Mutex::Autolock _l(mLock);
+    for (size_t i = 0; i < mAudioVolumeGroupCallback.size(); i++) {
+        if (mAudioVolumeGroupCallback[i] == callback) {
+            return -1;
+        }
+    }
+    mAudioVolumeGroupCallback.add(callback);
+    return mAudioVolumeGroupCallback.size();
+}
+
+int AudioSystem::AudioPolicyServiceClient::removeAudioVolumeGroupCallback(
+        const sp<AudioVolumeGroupCallback>& callback)
+{
+    Mutex::Autolock _l(mLock);
+    size_t i;
+    for (i = 0; i < mAudioVolumeGroupCallback.size(); i++) {
+        if (mAudioVolumeGroupCallback[i] == callback) {
+            break;
+        }
+    }
+    if (i == mAudioVolumeGroupCallback.size()) {
+        return -1;
+    }
+    mAudioVolumeGroupCallback.removeAt(i);
+    return mAudioVolumeGroupCallback.size();
+}
+
+void AudioSystem::AudioPolicyServiceClient::onAudioVolumeGroupChanged(volume_group_t group,
+                                                                      int flags)
+{
+    Mutex::Autolock _l(mLock);
+    for (size_t i = 0; i < mAudioVolumeGroupCallback.size(); i++) {
+        mAudioVolumeGroupCallback[i]->onAudioVolumeGroupChanged(group, flags);
+    }
+}
+// ----------------------------------------------------------------------------
+
 void AudioSystem::AudioPolicyServiceClient::onDynamicPolicyMixStateUpdate(
         String8 regId, int32_t state)
 {
@@ -1369,9 +1625,14 @@
 }
 
 void AudioSystem::AudioPolicyServiceClient::onRecordingConfigurationUpdate(
-        int event, const record_client_info_t *clientInfo,
-        const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
-        audio_patch_handle_t patchHandle) {
+                                                int event,
+                                                const record_client_info_t *clientInfo,
+                                                const audio_config_base_t *clientConfig,
+                                                std::vector<effect_descriptor_t> clientEffects,
+                                                const audio_config_base_t *deviceConfig,
+                                                std::vector<effect_descriptor_t> effects,
+                                                audio_patch_handle_t patchHandle,
+                                                audio_source_t source) {
     record_config_callback cb = NULL;
     {
         Mutex::Autolock _l(AudioSystem::gLock);
@@ -1379,7 +1640,8 @@
     }
 
     if (cb != NULL) {
-        cb(event, clientInfo, clientConfig, deviceConfig, patchHandle);
+        cb(event, clientInfo, clientConfig, clientEffects,
+           deviceConfig, effects, patchHandle, source);
     }
 }
 
@@ -1390,6 +1652,9 @@
         for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) {
             mAudioPortCallbacks[i]->onServiceDied();
         }
+        for (size_t i = 0; i < mAudioVolumeGroupCallback.size(); i++) {
+            mAudioVolumeGroupCallback[i]->onServiceDied();
+        }
     }
     {
         Mutex::Autolock _l(gLockAPS);
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index ab9efe8..4a80cd3 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -22,16 +22,19 @@
 #include <math.h>
 #include <sys/resource.h>
 
+#include <android-base/macros.h>
 #include <audio_utils/clock.h>
 #include <audio_utils/primitives.h>
 #include <binder/IPCThreadState.h>
 #include <media/AudioTrack.h>
 #include <utils/Log.h>
 #include <private/media/AudioTrackShared.h>
+#include <processgroup/sched_policy.h>
 #include <media/IAudioFlinger.h>
+#include <media/IAudioPolicyService.h>
 #include <media/AudioParameter.h>
-#include <media/AudioPolicyHelper.h>
 #include <media/AudioResamplerPublic.h>
+#include <media/AudioSystem.h>
 #include <media/MediaAnalyticsItem.h>
 #include <media/TypeConverter.h>
 
@@ -63,7 +66,7 @@
 
 static int64_t convertTimespecToUs(const struct timespec &tv)
 {
-    return tv.tv_sec * 1000000ll + tv.tv_nsec / 1000;
+    return tv.tv_sec * 1000000LL + tv.tv_nsec / 1000;
 }
 
 // TODO move to audio_utils.
@@ -119,22 +122,22 @@
     status_t status;
     status = AudioSystem::getOutputSamplingRate(&afSampleRate, streamType);
     if (status != NO_ERROR) {
-        ALOGE("Unable to query output sample rate for stream type %d; status %d",
-                streamType, status);
+        ALOGE("%s(): Unable to query output sample rate for stream type %d; status %d",
+                __func__, streamType, status);
         return status;
     }
     size_t afFrameCount;
     status = AudioSystem::getOutputFrameCount(&afFrameCount, streamType);
     if (status != NO_ERROR) {
-        ALOGE("Unable to query output frame count for stream type %d; status %d",
-                streamType, status);
+        ALOGE("%s(): Unable to query output frame count for stream type %d; status %d",
+                __func__, streamType, status);
         return status;
     }
     uint32_t afLatency;
     status = AudioSystem::getOutputLatency(&afLatency, streamType);
     if (status != NO_ERROR) {
-        ALOGE("Unable to query output latency for stream type %d; status %d",
-                streamType, status);
+        ALOGE("%s(): Unable to query output latency for stream type %d; status %d",
+                __func__, streamType, status);
         return status;
     }
 
@@ -147,85 +150,52 @@
     // AudioTrack.SAMPLE_RATE_HZ_MIN <= sampleRate <= AudioTrack.SAMPLE_RATE_HZ_MAX.
     // Return error in the unlikely event that it does not, as that's part of the API contract.
     if (*frameCount == 0) {
-        ALOGE("AudioTrack::getMinFrameCount failed for streamType %d, sampleRate %u",
-                streamType, sampleRate);
+        ALOGE("%s(): failed for streamType %d, sampleRate %u",
+                __func__, streamType, sampleRate);
         return BAD_VALUE;
     }
-    ALOGV("getMinFrameCount=%zu: afFrameCount=%zu, afSampleRate=%u, afLatency=%u",
-            *frameCount, afFrameCount, afSampleRate, afLatency);
+    ALOGV("%s(): getMinFrameCount=%zu: afFrameCount=%zu, afSampleRate=%u, afLatency=%u",
+            __func__, *frameCount, afFrameCount, afSampleRate, afLatency);
     return NO_ERROR;
 }
 
+// static
+bool AudioTrack::isDirectOutputSupported(const audio_config_base_t& config,
+                                         const audio_attributes_t& attributes) {
+    ALOGV("%s()", __FUNCTION__);
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return false;
+    return aps->isDirectOutputSupported(config, attributes);
+}
+
 // ---------------------------------------------------------------------------
 
-static std::string audioContentTypeString(audio_content_type_t value) {
-    std::string contentType;
-    if (AudioContentTypeConverter::toString(value, contentType)) {
-        return contentType;
-    }
-    char rawbuffer[16];  // room for "%d"
-    snprintf(rawbuffer, sizeof(rawbuffer), "%d", value);
-    return rawbuffer;
-}
-
-static std::string audioUsageString(audio_usage_t value) {
-    std::string usage;
-    if (UsageTypeConverter::toString(value, usage)) {
-        return usage;
-    }
-    char rawbuffer[16];  // room for "%d"
-    snprintf(rawbuffer, sizeof(rawbuffer), "%d", value);
-    return rawbuffer;
-}
-
 void AudioTrack::MediaMetrics::gather(const AudioTrack *track)
 {
-
-    // key for media statistics is defined in the header
-    // attrs for media statistics
-    // NB: these are matched with public Java API constants defined
-    // in frameworks/base/media/java/android/media/AudioTrack.java
-    // These must be kept synchronized with the constants there.
-    static constexpr char kAudioTrackStreamType[] = "android.media.audiotrack.streamtype";
-    static constexpr char kAudioTrackContentType[] = "android.media.audiotrack.type";
-    static constexpr char kAudioTrackUsage[] = "android.media.audiotrack.usage";
-    static constexpr char kAudioTrackSampleRate[] = "android.media.audiotrack.samplerate";
-    static constexpr char kAudioTrackChannelMask[] = "android.media.audiotrack.channelmask";
-
-    // NB: These are not yet exposed as public Java API constants.
-    static constexpr char kAudioTrackUnderrunFrames[] = "android.media.audiotrack.underrunframes";
-    static constexpr char kAudioTrackStartupGlitch[] = "android.media.audiotrack.glitch.startup";
-
     // only if we're in a good state...
     // XXX: shall we gather alternative info if failing?
     const status_t lstatus = track->initCheck();
     if (lstatus != NO_ERROR) {
-        ALOGD("no metrics gathered, track status=%d", (int) lstatus);
+        ALOGD("%s(): no metrics gathered, track status=%d", __func__, (int) lstatus);
         return;
     }
 
-    // constructor guarantees mAnalyticsItem is valid
+#define MM_PREFIX "android.media.audiotrack." // avoid cut-n-paste errors.
 
-    const int32_t underrunFrames = track->getUnderrunFrames();
-    if (underrunFrames != 0) {
-        mAnalyticsItem->setInt32(kAudioTrackUnderrunFrames, underrunFrames);
-    }
+    // Java API 28 entries, do not change.
+    mAnalyticsItem->setCString(MM_PREFIX "streamtype", toString(track->streamType()).c_str());
+    mAnalyticsItem->setCString(MM_PREFIX "type",
+            toString(track->mAttributes.content_type).c_str());
+    mAnalyticsItem->setCString(MM_PREFIX "usage", toString(track->mAttributes.usage).c_str());
 
-    if (track->mTimestampStartupGlitchReported) {
-        mAnalyticsItem->setInt32(kAudioTrackStartupGlitch, 1);
-    }
-
-    if (track->mStreamType != -1) {
-        // deprecated, but this will tell us who still uses it.
-        mAnalyticsItem->setInt32(kAudioTrackStreamType, track->mStreamType);
-    }
-    // XXX: consider including from mAttributes: source type
-    mAnalyticsItem->setCString(kAudioTrackContentType,
-                               audioContentTypeString(track->mAttributes.content_type).c_str());
-    mAnalyticsItem->setCString(kAudioTrackUsage,
-                               audioUsageString(track->mAttributes.usage).c_str());
-    mAnalyticsItem->setInt32(kAudioTrackSampleRate, track->mSampleRate);
-    mAnalyticsItem->setInt64(kAudioTrackChannelMask, track->mChannelMask);
+    // Non-API entries, these can change due to a Java string mistake.
+    mAnalyticsItem->setInt32(MM_PREFIX "sampleRate", (int32_t)track->mSampleRate);
+    mAnalyticsItem->setInt64(MM_PREFIX "channelMask", (int64_t)track->mChannelMask);
+    // Non-API entries, these can change.
+    mAnalyticsItem->setInt32(MM_PREFIX "portId", (int32_t)track->mPortId);
+    mAnalyticsItem->setCString(MM_PREFIX "encoding", toString(track->mFormat).c_str());
+    mAnalyticsItem->setInt32(MM_PREFIX "frameCount", (int32_t)track->mFrameCount);
+    mAnalyticsItem->setCString(MM_PREFIX "attributes", toString(track->mAttributes).c_str());
 }
 
 // hand the user a snapshot of the metrics.
@@ -280,6 +250,8 @@
       mPreviousSchedulingGroup(SP_DEFAULT),
       mPausedPosition(0)
 {
+    mAttributes = AUDIO_ATTRIBUTES_INITIALIZER;
+
     (void)set(streamType, sampleRate, format, channelMask,
             frameCount, flags, cbf, user, notificationFrames,
             0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType,
@@ -311,6 +283,8 @@
       mPausedPosition(0),
       mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE)
 {
+    mAttributes = AUDIO_ATTRIBUTES_INITIALIZER;
+
     (void)set(streamType, sampleRate, format, channelMask,
             0 /*frameCount*/, flags, cbf, user, notificationFrames,
             sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo,
@@ -335,14 +309,15 @@
         }
         // No lock here: worst case we remove a NULL callback which will be a nop
         if (mDeviceCallback != 0 && mOutput != AUDIO_IO_HANDLE_NONE) {
-            AudioSystem::removeAudioDeviceCallback(this, mOutput);
+            AudioSystem::removeAudioDeviceCallback(this, mOutput, mPortId);
         }
         IInterface::asBinder(mAudioTrack)->unlinkToDeath(mDeathNotifier, this);
         mAudioTrack.clear();
         mCblkMemory.clear();
         mSharedBuffer.clear();
         IPCThreadState::self()->flushCommands();
-        ALOGV("~AudioTrack, releasing session id %d from %d on behalf of %d",
+        ALOGV("%s(%d), releasing session id %d from %d on behalf of %d",
+                __func__, mPortId,
                 mSessionId, IPCThreadState::self()->getCallingPid(), mClientPid);
         AudioSystem::releaseAudioSessionId(mSessionId, mClientPid);
     }
@@ -375,8 +350,10 @@
     pid_t callingPid;
     pid_t myPid;
 
-    ALOGV("set(): streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
+    // Note mPortId is not valid until the track is created, so omit mPortId in ALOG for set.
+    ALOGV("%s(): streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
           "flags #%x, notificationFrames %d, sessionId %d, transferType %d, uid %d, pid %d",
+          __func__,
           streamType, sampleRate, format, channelMask, frameCount, flags, notificationFrames,
           sessionId, transferType, uid, pid);
 
@@ -395,8 +372,10 @@
         }
         break;
     case TRANSFER_CALLBACK:
+    case TRANSFER_SYNC_NOTIF_CALLBACK:
         if (cbf == NULL || sharedBuffer != 0) {
-            ALOGE("Transfer type TRANSFER_CALLBACK but cbf == NULL || sharedBuffer != 0");
+            ALOGE("%s(): Transfer type %s but cbf == NULL || sharedBuffer != 0",
+                    convertTransferToText(transferType), __func__);
             status = BAD_VALUE;
             goto exit;
         }
@@ -404,20 +383,21 @@
     case TRANSFER_OBTAIN:
     case TRANSFER_SYNC:
         if (sharedBuffer != 0) {
-            ALOGE("Transfer type TRANSFER_OBTAIN but sharedBuffer != 0");
+            ALOGE("%s(): Transfer type TRANSFER_OBTAIN but sharedBuffer != 0", __func__);
             status = BAD_VALUE;
             goto exit;
         }
         break;
     case TRANSFER_SHARED:
         if (sharedBuffer == 0) {
-            ALOGE("Transfer type TRANSFER_SHARED but sharedBuffer == 0");
+            ALOGE("%s(): Transfer type TRANSFER_SHARED but sharedBuffer == 0", __func__);
             status = BAD_VALUE;
             goto exit;
         }
         break;
     default:
-        ALOGE("Invalid transfer type %d", transferType);
+        ALOGE("%s(): Invalid transfer type %d",
+                __func__, transferType);
         status = BAD_VALUE;
         goto exit;
     }
@@ -425,14 +405,15 @@
     mTransfer = transferType;
     mDoNotReconnect = doNotReconnect;
 
-    ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %zu", sharedBuffer->pointer(),
-            sharedBuffer->size());
+    ALOGV_IF(sharedBuffer != 0, "%s(): sharedBuffer: %p, size: %zu",
+            __func__, sharedBuffer->pointer(), sharedBuffer->size());
 
-    ALOGV("set() streamType %d frameCount %zu flags %04x", streamType, frameCount, flags);
+    ALOGV("%s(): streamType %d frameCount %zu flags %04x",
+            __func__, streamType, frameCount, flags);
 
     // invariant that mAudioTrack != 0 is true only after set() returns successfully
     if (mAudioTrack != 0) {
-        ALOGE("Track already in use");
+        ALOGE("%s(): Track already in use", __func__);
         status = INVALID_OPERATION;
         goto exit;
     }
@@ -443,7 +424,7 @@
     }
     if (pAttributes == NULL) {
         if (uint32_t(streamType) >= AUDIO_STREAM_PUBLIC_CNT) {
-            ALOGE("Invalid stream type %d", streamType);
+            ALOGE("%s(): Invalid stream type %d", __func__, streamType);
             status = BAD_VALUE;
             goto exit;
         }
@@ -452,19 +433,12 @@
     } else {
         // stream type shouldn't be looked at, this track has audio attributes
         memcpy(&mAttributes, pAttributes, sizeof(audio_attributes_t));
-        ALOGV("Building AudioTrack with attributes: usage=%d content=%d flags=0x%x tags=[%s]",
-                mAttributes.usage, mAttributes.content_type, mAttributes.flags, mAttributes.tags);
+        ALOGV("%s(): Building AudioTrack with attributes:"
+                " usage=%d content=%d flags=0x%x tags=[%s]",
+                __func__,
+                 mAttributes.usage, mAttributes.content_type, mAttributes.flags, mAttributes.tags);
         mStreamType = AUDIO_STREAM_DEFAULT;
-        if ((mAttributes.flags & AUDIO_FLAG_HW_AV_SYNC) != 0) {
-            flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_HW_AV_SYNC);
-        }
-        if ((mAttributes.flags & AUDIO_FLAG_LOW_LATENCY) != 0) {
-            flags = (audio_output_flags_t) (flags | AUDIO_OUTPUT_FLAG_FAST);
-        }
-        // check deep buffer after flags have been modified above
-        if (flags == AUDIO_OUTPUT_FLAG_NONE && (mAttributes.flags & AUDIO_FLAG_DEEP_BUFFER) != 0) {
-            flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
-        }
+        audio_flags_to_audio_output_flags(mAttributes.flags, &flags);
     }
 
     // these below should probably come from the audioFlinger too...
@@ -476,14 +450,14 @@
 
     // validate parameters
     if (!audio_is_valid_format(format)) {
-        ALOGE("Invalid format %#x", format);
+        ALOGE("%s(): Invalid format %#x", __func__, format);
         status = BAD_VALUE;
         goto exit;
     }
     mFormat = format;
 
     if (!audio_is_output_channel(channelMask)) {
-        ALOGE("Invalid channel mask %#x", channelMask);
+        ALOGE("%s(): Invalid channel mask %#x",  __func__, channelMask);
         status = BAD_VALUE;
         goto exit;
     }
@@ -496,8 +470,9 @@
     if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)
             || !audio_is_linear_pcm(format)) {
         ALOGV( (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)
-                    ? "Offload request, forcing to Direct Output"
-                    : "Not linear PCM, forcing to Direct Output");
+                    ? "%s(): Offload request, forcing to Direct Output"
+                    : "%s(): Not linear PCM, forcing to Direct Output",
+                    __func__);
         flags = (audio_output_flags_t)
                 // FIXME why can't we allow direct AND fast?
                 ((flags | AUDIO_OUTPUT_FLAG_DIRECT) & ~AUDIO_OUTPUT_FLAG_FAST);
@@ -553,14 +528,14 @@
         mNotificationsPerBufferReq = 0;
     } else {
         if (!(flags & AUDIO_OUTPUT_FLAG_FAST)) {
-            ALOGE("notificationFrames=%d not permitted for non-fast track",
-                    notificationFrames);
+            ALOGE("%s(): notificationFrames=%d not permitted for non-fast track",
+                    __func__, notificationFrames);
             status = BAD_VALUE;
             goto exit;
         }
         if (frameCount > 0) {
-            ALOGE("notificationFrames=%d not permitted with non-zero frameCount=%zu",
-                    notificationFrames, frameCount);
+            ALOGE("%s(): notificationFrames=%d not permitted with non-zero frameCount=%zu",
+                    __func__, notificationFrames, frameCount);
             status = BAD_VALUE;
             goto exit;
         }
@@ -570,7 +545,8 @@
         mNotificationsPerBufferReq = min(maxNotificationsPerBuffer,
                 max((uint32_t) -notificationFrames, minNotificationsPerBuffer));
         ALOGW_IF(mNotificationsPerBufferReq != (uint32_t) -notificationFrames,
-                "notificationFrames=%d clamped to the range -%u to -%u",
+                "%s(): notificationFrames=%d clamped to the range -%u to -%u",
+                __func__,
                 notificationFrames, minNotificationsPerBuffer, maxNotificationsPerBuffer);
     }
     mNotificationFramesAct = 0;
@@ -591,14 +567,16 @@
     mCbf = cbf;
 
     if (cbf != NULL) {
-        mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava);
+        mAudioTrackThread = new AudioTrackThread(*this);
         mAudioTrackThread->run("AudioTrack", ANDROID_PRIORITY_AUDIO, 0 /*stack*/);
         // thread begins in paused state, and will not reference us until start()
     }
 
     // create the IAudioTrack
-    status = createTrack_l();
-
+    {
+        AutoMutex lock(mLock);
+        status = createTrack_l();
+    }
     if (status != NO_ERROR) {
         if (mAudioTrackThread != 0) {
             mAudioTrackThread->requestExit();   // see comment in AudioTrack.h
@@ -627,7 +605,10 @@
     mInUnderrun = false;
     mPreviousTimestampValid = false;
     mTimestampStartupGlitchReported = false;
-    mRetrogradeMotionReported = false;
+    mTimestampRetrogradePositionReported = false;
+    mTimestampRetrogradeTimeReported = false;
+    mTimestampStallReported = false;
+    mTimestampStaleTimeReported = false;
     mPreviousLocation = ExtendedTimestamp::LOCATION_INVALID;
     mStartTs.mPosition = 0;
     mUnderrunCountOffset = 0;
@@ -646,6 +627,7 @@
 status_t AudioTrack::start()
 {
     AutoMutex lock(mLock);
+    ALOGV("%s(%d): prior state:%s", __func__, mPortId, stateToString(mState));
 
     if (mState == STATE_ACTIVE) {
         return INVALID_OPERATION;
@@ -677,7 +659,10 @@
         mPosition = 0;
         mPreviousTimestampValid = false;
         mTimestampStartupGlitchReported = false;
-        mRetrogradeMotionReported = false;
+        mTimestampRetrogradePositionReported = false;
+        mTimestampRetrogradeTimeReported = false;
+        mTimestampStallReported = false;
+        mTimestampStaleTimeReported = false;
         mPreviousLocation = ExtendedTimestamp::LOCATION_INVALID;
 
         if (!isOffloadedOrDirect_l()
@@ -685,7 +670,8 @@
             // Server side has consumed something, but is it finished consuming?
             // It is possible since flush and stop are asynchronous that the server
             // is still active at this point.
-            ALOGV("start: server read:%lld  cumulative flushed:%lld  client written:%lld",
+            ALOGV("%s(%d): server read:%lld  cumulative flushed:%lld  client written:%lld",
+                    __func__, mPortId,
                     (long long)(mFramesWrittenServerOffset
                             + mStartEts.mPosition[ExtendedTimestamp::LOCATION_SERVER]),
                     (long long)mStartEts.mFlushed,
@@ -706,6 +692,13 @@
         // force refresh of remaining frames by processAudioBuffer() as last
         // write before stop could be partial.
         mRefreshRemaining = true;
+
+        // for static track, clear the old flags when starting from stopped state
+        if (mSharedBuffer != 0) {
+            android_atomic_and(
+            ~(CBLK_LOOP_CYCLE | CBLK_LOOP_FINAL | CBLK_BUFFER_END),
+            &mCblk->mFlags);
+        }
     }
     mNewPosition = mPosition + mUpdatePeriod;
     int32_t flags = android_atomic_and(~(CBLK_STREAM_END_DONE | CBLK_DISABLED), &mCblk->mFlags);
@@ -739,7 +732,7 @@
         // Start our local VolumeHandler for restoration purposes.
         mVolumeHandler->setStarted();
     } else {
-        ALOGE("start() status %d", status);
+        ALOGE("%s(%d): status %d", __func__, mPortId, status);
         mState = previousState;
         if (t != 0) {
             if (previousState != STATE_STOPPING) {
@@ -757,6 +750,8 @@
 void AudioTrack::stop()
 {
     AutoMutex lock(mLock);
+    ALOGV("%s(%d): prior state:%s", __func__, mPortId, stateToString(mState));
+
     if (mState != STATE_ACTIVE && mState != STATE_PAUSED) {
         return;
     }
@@ -766,7 +761,7 @@
     } else {
         mState = STATE_STOPPED;
         ALOGD_IF(mSharedBuffer == nullptr,
-                "stop() called with %u frames delivered", mReleased.value());
+                "%s(%d): called with %u frames delivered", __func__, mPortId, mReleased.value());
         mReleased = 0;
     }
 
@@ -787,6 +782,10 @@
     if (t != 0) {
         if (!isOffloaded_l()) {
             t->pause();
+        } else if (mTransfer == TRANSFER_SYNC_NOTIF_CALLBACK) {
+            // causes wake up of the playback thread, that will callback the client for
+            // EVENT_STREAM_END in processAudioBuffer()
+            t->wake();
         }
     } else {
         setpriority(PRIO_PROCESS, 0, mPreviousPriority);
@@ -802,10 +801,12 @@
 
 void AudioTrack::flush()
 {
+    AutoMutex lock(mLock);
+    ALOGV("%s(%d): prior state:%s", __func__, mPortId, stateToString(mState));
+
     if (mSharedBuffer != 0) {
         return;
     }
-    AutoMutex lock(mLock);
     if (mState == STATE_ACTIVE) {
         return;
     }
@@ -834,6 +835,8 @@
 void AudioTrack::pause()
 {
     AutoMutex lock(mLock);
+    ALOGV("%s(%d): prior state:%s", __func__, mPortId, stateToString(mState));
+
     if (mState == STATE_ACTIVE) {
         mState = STATE_PAUSED;
     } else if (mState == STATE_STOPPING) {
@@ -859,7 +862,8 @@
 
             uint32_t halFrames;
             AudioSystem::getRenderPosition(mOutput, &halFrames, &mPausedPosition);
-            ALOGV("AudioTrack::pause for offload, cache current position %u", mPausedPosition);
+            ALOGV("%s(%d): for offload, cache current position %u",
+                    __func__, mPortId, mPausedPosition);
         }
     }
 }
@@ -913,10 +917,13 @@
 status_t AudioTrack::setSampleRate(uint32_t rate)
 {
     AutoMutex lock(mLock);
+    ALOGV("%s(%d): prior state:%s rate:%u", __func__, mPortId, stateToString(mState), rate);
+
     if (rate == mSampleRate) {
         return NO_ERROR;
     }
-    if (isOffloadedOrDirect_l() || (mFlags & AUDIO_OUTPUT_FLAG_FAST)) {
+    if (isOffloadedOrDirect_l() || (mFlags & AUDIO_OUTPUT_FLAG_FAST)
+            || (mChannelMask & AUDIO_CHANNEL_HAPTIC_ALL)) {
         return INVALID_OPERATION;
     }
     if (mOutput == AUDIO_IO_HANDLE_NONE) {
@@ -978,8 +985,8 @@
         return INVALID_OPERATION;
     }
 
-    ALOGV("setPlaybackRate (input): mSampleRate:%u  mSpeed:%f  mPitch:%f",
-            mSampleRate, playbackRate.mSpeed, playbackRate.mPitch);
+    ALOGV("%s(%d): mSampleRate:%u  mSpeed:%f  mPitch:%f",
+            __func__, mPortId, mSampleRate, playbackRate.mSpeed, playbackRate.mPitch);
     // pitch is emulated by adjusting speed and sampleRate
     const uint32_t effectiveRate = adjustSampleRate(mSampleRate, playbackRate.mPitch);
     const float effectiveSpeed = adjustSpeed(playbackRate.mSpeed, playbackRate.mPitch);
@@ -988,32 +995,32 @@
     playbackRateTemp.mSpeed = effectiveSpeed;
     playbackRateTemp.mPitch = effectivePitch;
 
-    ALOGV("setPlaybackRate (effective): mSampleRate:%u  mSpeed:%f  mPitch:%f",
-            effectiveRate, effectiveSpeed, effectivePitch);
+    ALOGV("%s(%d) (effective) mSampleRate:%u  mSpeed:%f  mPitch:%f",
+            __func__, mPortId, effectiveRate, effectiveSpeed, effectivePitch);
 
     if (!isAudioPlaybackRateValid(playbackRateTemp)) {
-        ALOGW("setPlaybackRate(%f, %f) failed (effective rate out of bounds)",
-                playbackRate.mSpeed, playbackRate.mPitch);
+        ALOGW("%s(%d) (%f, %f) failed (effective rate out of bounds)",
+                __func__, mPortId, playbackRate.mSpeed, playbackRate.mPitch);
         return BAD_VALUE;
     }
     // Check if the buffer size is compatible.
     if (!isSampleRateSpeedAllowed_l(effectiveRate, effectiveSpeed)) {
-        ALOGW("setPlaybackRate(%f, %f) failed (buffer size)",
-                playbackRate.mSpeed, playbackRate.mPitch);
+        ALOGW("%s(%d) (%f, %f) failed (buffer size)",
+                __func__, mPortId, playbackRate.mSpeed, playbackRate.mPitch);
         return BAD_VALUE;
     }
 
     // Check resampler ratios are within bounds
     if ((uint64_t)effectiveRate > (uint64_t)mSampleRate *
             (uint64_t)AUDIO_RESAMPLER_DOWN_RATIO_MAX) {
-        ALOGW("setPlaybackRate(%f, %f) failed. Resample rate exceeds max accepted value",
-                playbackRate.mSpeed, playbackRate.mPitch);
+        ALOGW("%s(%d) (%f, %f) failed. Resample rate exceeds max accepted value",
+                __func__, mPortId, playbackRate.mSpeed, playbackRate.mPitch);
         return BAD_VALUE;
     }
 
     if ((uint64_t)effectiveRate * (uint64_t)AUDIO_RESAMPLER_UP_RATIO_MAX < (uint64_t)mSampleRate) {
-        ALOGW("setPlaybackRate(%f, %f) failed. Resample rate below min accepted value",
-                        playbackRate.mSpeed, playbackRate.mPitch);
+        ALOGW("%s(%d) (%f, %f) failed. Resample rate below min accepted value",
+                __func__, mPortId, playbackRate.mSpeed, playbackRate.mPitch);
         return BAD_VALUE;
     }
     mPlaybackRate = playbackRate;
@@ -1214,7 +1221,8 @@
         uint32_t dspFrames = 0;
 
         if (isOffloaded_l() && ((mState == STATE_PAUSED) || (mState == STATE_PAUSED_STOPPING))) {
-            ALOGV("getPosition called in paused state, return cached position %u", mPausedPosition);
+            ALOGV("%s(%d): called in paused state, return cached position %u",
+                __func__, mPortId, mPausedPosition);
             *position = mPausedPosition;
             return NO_ERROR;
         }
@@ -1341,7 +1349,7 @@
 audio_stream_type_t AudioTrack::streamType() const
 {
     if (mStreamType == AUDIO_STREAM_DEFAULT) {
-        return audio_attributes_to_stream_type(&mAttributes);
+        return AudioSystem::attributesToStreamType(mAttributes);
     }
     return mStreamType;
 }
@@ -1360,7 +1368,7 @@
 {
     status_t status = AudioSystem::getLatency(mOutput, &mAfLatency);
     if (status != NO_ERROR) {
-        ALOGW("getLatency(%d) failed status %d", mOutput, status);
+        ALOGW("%s(%d): getLatency(%d) failed status %d", __func__, mPortId, mOutput, status);
     } else {
         // FIXME don't believe this lie
         mLatency = mAfLatency + (1000LL * mFrameCount) / mSampleRate;
@@ -1376,6 +1384,7 @@
         MEDIA_CASE_ENUM(TRANSFER_OBTAIN);
         MEDIA_CASE_ENUM(TRANSFER_SYNC);
         MEDIA_CASE_ENUM(TRANSFER_SHARED);
+        MEDIA_CASE_ENUM(TRANSFER_SYNC_NOTIF_CALLBACK);
         default:
             return "UNRECOGNIZED";
     }
@@ -1388,7 +1397,8 @@
 
     const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
     if (audioFlinger == 0) {
-        ALOGE("Could not get audioflinger");
+        ALOGE("%s(%d): Could not get audioflinger",
+                __func__, mPortId);
         status = NO_INIT;
         goto exit;
     }
@@ -1407,11 +1417,14 @@
             // use case 3: obtain/release mode
             (mTransfer == TRANSFER_OBTAIN) ||
             // use case 4: synchronous write
-            ((mTransfer == TRANSFER_SYNC) && mThreadCanCallJava);
+            ((mTransfer == TRANSFER_SYNC || mTransfer == TRANSFER_SYNC_NOTIF_CALLBACK)
+                    && mThreadCanCallJava);
 
         bool fastAllowed = sharedBuffer || transferAllowed;
         if (!fastAllowed) {
-            ALOGW("AUDIO_OUTPUT_FLAG_FAST denied by client, not shared buffer and transfer = %s",
+            ALOGW("%s(%d): AUDIO_OUTPUT_FLAG_FAST denied by client,"
+                  " not shared buffer and transfer = %s",
+                  __func__, mPortId,
                   convertTransferToText(mTransfer));
             mFlags = (audio_output_flags_t) (mFlags & ~AUDIO_OUTPUT_FLAG_FAST);
         }
@@ -1419,7 +1432,7 @@
 
     IAudioFlinger::CreateTrackInput input;
     if (mStreamType != AUDIO_STREAM_DEFAULT) {
-        stream_type_to_audio_attributes(mStreamType, &input.attr);
+        input.attr = AudioSystem::streamTypeToAttributes(mStreamType);
     } else {
         input.attr = mAttributes;
     }
@@ -1460,7 +1473,8 @@
                                                       &status);
 
     if (status != NO_ERROR || output.outputId == AUDIO_IO_HANDLE_NONE) {
-        ALOGE("AudioFlinger could not create track, status: %d output %d", status, output.outputId);
+        ALOGE("%s(%d): AudioFlinger could not create track, status: %d output %d",
+                __func__, mPortId, status, output.outputId);
         if (status == NO_ERROR) {
             status = NO_INIT;
         }
@@ -1490,13 +1504,13 @@
     // FIXME compare to AudioRecord
     sp<IMemory> iMem = track->getCblk();
     if (iMem == 0) {
-        ALOGE("Could not get control block");
+        ALOGE("%s(%d): Could not get control block", __func__, mPortId);
         status = NO_INIT;
         goto exit;
     }
     void *iMemPointer = iMem->pointer();
     if (iMemPointer == NULL) {
-        ALOGE("Could not get control block pointer");
+        ALOGE("%s(%d): Could not get control block pointer", __func__, mPortId);
         status = NO_INIT;
         goto exit;
     }
@@ -1515,27 +1529,28 @@
     mAwaitBoost = false;
     if (mFlags & AUDIO_OUTPUT_FLAG_FAST) {
         if (output.flags & AUDIO_OUTPUT_FLAG_FAST) {
-            ALOGI("AUDIO_OUTPUT_FLAG_FAST successful; frameCount %zu -> %zu",
-                  mReqFrameCount, mFrameCount);
+            ALOGI("%s(%d): AUDIO_OUTPUT_FLAG_FAST successful; frameCount %zu -> %zu",
+                  __func__, mPortId, mReqFrameCount, mFrameCount);
             if (!mThreadCanCallJava) {
                 mAwaitBoost = true;
             }
         } else {
-            ALOGW("AUDIO_OUTPUT_FLAG_FAST denied by server; frameCount %zu -> %zu", mReqFrameCount,
-                  mFrameCount);
+            ALOGW("%s(%d): AUDIO_OUTPUT_FLAG_FAST denied by server; frameCount %zu -> %zu",
+                  __func__, mPortId, mReqFrameCount, mFrameCount);
         }
     }
     mFlags = output.flags;
 
     //mOutput != output includes the case where mOutput == AUDIO_IO_HANDLE_NONE for first creation
-    if (mDeviceCallback != 0 && mOutput != output.outputId) {
+    if (mDeviceCallback != 0) {
         if (mOutput != AUDIO_IO_HANDLE_NONE) {
-            AudioSystem::removeAudioDeviceCallback(this, mOutput);
+            AudioSystem::removeAudioDeviceCallback(this, mOutput, mPortId);
         }
-        AudioSystem::addAudioDeviceCallback(this, output.outputId);
+        AudioSystem::addAudioDeviceCallback(this, output.outputId, output.portId);
         callbackAdded = true;
     }
 
+    mPortId = output.portId;
     // We retain a copy of the I/O handle, but don't own the reference
     mOutput = output.outputId;
     mRefreshRemaining = true;
@@ -1550,7 +1565,7 @@
     } else {
         buffers = mSharedBuffer->pointer();
         if (buffers == NULL) {
-            ALOGE("Could not get buffer pointer");
+            ALOGE("%s(%d): Could not get buffer pointer", __func__, mPortId);
             status = NO_INIT;
             goto exit;
         }
@@ -1600,7 +1615,7 @@
 exit:
     if (status != NO_ERROR && callbackAdded) {
         // note: mOutput is always valid is callbackAdded is true
-        AudioSystem::removeAudioDeviceCallback(this, mOutput);
+        AudioSystem::removeAudioDeviceCallback(this, mOutput, mPortId);
     }
 
     mStatus = status;
@@ -1634,12 +1649,12 @@
     } else if (waitCount == 0) {
         requested = &ClientProxy::kNonBlocking;
     } else if (waitCount > 0) {
-        long long ms = WAIT_PERIOD_MS * (long long) waitCount;
+        time_t ms = WAIT_PERIOD_MS * (time_t) waitCount;
         timeout.tv_sec = ms / 1000;
-        timeout.tv_nsec = (int) (ms % 1000) * 1000000;
+        timeout.tv_nsec = (long) (ms % 1000) * 1000000;
         requested = &timeout;
     } else {
-        ALOGE("%s invalid waitCount %d", __func__, waitCount);
+        ALOGE("%s(%d): invalid waitCount %d", __func__, mPortId, waitCount);
         requested = NULL;
     }
     return obtainBuffer(audioBuffer, requested, NULL /*elapsed*/, nonContig);
@@ -1749,7 +1764,8 @@
 {
     int32_t flags = android_atomic_and(~CBLK_DISABLED, &mCblk->mFlags);
     if ((mState == STATE_ACTIVE) && (flags & CBLK_DISABLED)) {
-        ALOGW("releaseBuffer() track %p disabled due to previous underrun, restarting", this);
+        ALOGW("%s(%d): releaseBuffer() track %p disabled due to previous underrun, restarting",
+                __func__, mPortId, this);
         // FIXME ignoring status
         mAudioTrack->start();
     }
@@ -1759,7 +1775,7 @@
 
 ssize_t AudioTrack::write(const void* buffer, size_t userSize, bool blocking)
 {
-    if (mTransfer != TRANSFER_SYNC) {
+    if (mTransfer != TRANSFER_SYNC && mTransfer != TRANSFER_SYNC_NOTIF_CALLBACK) {
         return INVALID_OPERATION;
     }
 
@@ -1776,7 +1792,8 @@
     if (ssize_t(userSize) < 0 || (buffer == NULL && userSize != 0)) {
         // Sanity-check: user is most-likely passing an error code, and it would
         // make the return value ambiguous (actualSize vs error).
-        ALOGE("AudioTrack::write(buffer=%p, size=%zu (%zd)", buffer, userSize, userSize);
+        ALOGE("%s(%d): AudioTrack::write(buffer=%p, size=%zu (%zd)",
+                __func__, mPortId, buffer, userSize, userSize);
         return BAD_VALUE;
     }
 
@@ -1809,7 +1826,17 @@
 
     if (written > 0) {
         mFramesWritten += written / mFrameSize;
+
+        if (mTransfer == TRANSFER_SYNC_NOTIF_CALLBACK) {
+            const sp<AudioTrackThread> t = mAudioTrackThread;
+            if (t != 0) {
+                // causes wake up of the playback thread, that will callback the client for
+                // more data (with EVENT_CAN_WRITE_MORE_DATA) in processAudioBuffer()
+                t->wake();
+            }
+        }
     }
+
     return written;
 }
 
@@ -1838,7 +1865,8 @@
             pollUs <<= 1;
         } while (tryCounter-- > 0);
         if (tryCounter < 0) {
-            ALOGE("did not receive expected priority boost on time");
+            ALOGE("%s(%d): did not receive expected priority boost on time",
+                    __func__, mPortId);
         }
         // Run again immediately
         return 0;
@@ -2062,8 +2090,8 @@
         if (ns < 0) ns = 0;
     }
 
-    // If not supplying data by EVENT_MORE_DATA, then we're done
-    if (mTransfer != TRANSFER_CALLBACK) {
+    // If not supplying data by EVENT_MORE_DATA or EVENT_CAN_WRITE_MORE_DATA, then we're done
+    if (mTransfer != TRANSFER_CALLBACK && mTransfer != TRANSFER_SYNC_NOTIF_CALLBACK) {
         return ns;
     }
 
@@ -2079,7 +2107,8 @@
     if (ns != NS_WHENEVER) {
         timeout.tv_sec = ns / 1000000000LL;
         timeout.tv_nsec = ns % 1000000000LL;
-        ALOGV("timeout %ld.%03d", timeout.tv_sec, (int) timeout.tv_nsec / 1000000);
+        ALOGV("%s(%d): timeout %ld.%03d",
+                __func__, mPortId, timeout.tv_sec, (int) timeout.tv_nsec / 1000000);
         requested = &timeout;
     }
 
@@ -2091,18 +2120,20 @@
         size_t nonContig;
         status_t err = obtainBuffer(&audioBuffer, requested, NULL, &nonContig);
         LOG_ALWAYS_FATAL_IF((err != NO_ERROR) != (audioBuffer.frameCount == 0),
-                "obtainBuffer() err=%d frameCount=%zu", err, audioBuffer.frameCount);
+                "%s(%d): obtainBuffer() err=%d frameCount=%zu",
+                 __func__, mPortId, err, audioBuffer.frameCount);
         requested = &ClientProxy::kNonBlocking;
         size_t avail = audioBuffer.frameCount + nonContig;
-        ALOGV("obtainBuffer(%u) returned %zu = %zu + %zu err %d",
-                mRemainingFrames, avail, audioBuffer.frameCount, nonContig, err);
+        ALOGV("%s(%d): obtainBuffer(%u) returned %zu = %zu + %zu err %d",
+                __func__, mPortId, mRemainingFrames, avail, audioBuffer.frameCount, nonContig, err);
         if (err != NO_ERROR) {
             if (err == TIMED_OUT || err == WOULD_BLOCK || err == -EINTR ||
                     (isOffloaded() && (err == DEAD_OBJECT))) {
                 // FIXME bug 25195759
                 return 1000000;
             }
-            ALOGE("Error %d obtaining an audio buffer, giving up.", err);
+            ALOGE("%s(%d): Error %d obtaining an audio buffer, giving up.",
+                    __func__, mPortId, err);
             return NS_NEVER;
         }
 
@@ -2113,26 +2144,58 @@
                     const nsecs_t timeNow = systemTime();
                     ns = max((nsecs_t)0, ns - (timeNow - timeAfterCallbacks));
                 }
-                nsecs_t myns = framesToNanoseconds(mRemainingFrames - avail, sampleRate, speed);
-                if (ns < 0 /* NS_WHENEVER */ || myns < ns) {
-                    ns = myns;
+
+                // delayNs is first computed by the additional frames required in the buffer.
+                nsecs_t delayNs = framesToNanoseconds(
+                        mRemainingFrames - avail, sampleRate, speed);
+
+                // afNs is the AudioFlinger mixer period in ns.
+                const nsecs_t afNs = framesToNanoseconds(mAfFrameCount, mAfSampleRate, speed);
+
+                // If the AudioTrack is double buffered based on the AudioFlinger mixer period,
+                // we may have a race if we wait based on the number of frames desired.
+                // This is a possible issue with resampling and AAudio.
+                //
+                // The granularity of audioflinger processing is one mixer period; if
+                // our wait time is less than one mixer period, wait at most half the period.
+                if (delayNs < afNs) {
+                    delayNs = std::min(delayNs, afNs / 2);
+                }
+
+                // adjust our ns wait by delayNs.
+                if (ns < 0 /* NS_WHENEVER */ || delayNs < ns) {
+                    ns = delayNs;
                 }
                 return ns;
             }
         }
 
         size_t reqSize = audioBuffer.size;
-        mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer);
+        if (mTransfer == TRANSFER_SYNC_NOTIF_CALLBACK) {
+            // when notifying client it can write more data, pass the total size that can be
+            // written in the next write() call, since it's not passed through the callback
+            audioBuffer.size += nonContig;
+        }
+        mCbf(mTransfer == TRANSFER_CALLBACK ? EVENT_MORE_DATA : EVENT_CAN_WRITE_MORE_DATA,
+                mUserData, &audioBuffer);
         size_t writtenSize = audioBuffer.size;
 
         // Sanity check on returned size
         if (ssize_t(writtenSize) < 0 || writtenSize > reqSize) {
-            ALOGE("EVENT_MORE_DATA requested %zu bytes but callback returned %zd bytes",
-                    reqSize, ssize_t(writtenSize));
+            ALOGE("%s(%d): EVENT_MORE_DATA requested %zu bytes but callback returned %zd bytes",
+                    __func__, mPortId, reqSize, ssize_t(writtenSize));
             return NS_NEVER;
         }
 
         if (writtenSize == 0) {
+            if (mTransfer == TRANSFER_SYNC_NOTIF_CALLBACK) {
+                // The callback EVENT_CAN_WRITE_MORE_DATA was processed in the JNI of
+                // android.media.AudioTrack. The JNI is not using the callback to provide data,
+                // it only signals to the Java client that it can provide more data, which
+                // this track is read to accept now.
+                // The playback thread will be awaken at the next ::write()
+                return NS_WHENEVER;
+            }
             // The callback is done filling buffers
             // Keep this thread going to handle timed events and
             // still try to get more data in intervals of WAIT_PERIOD_MS
@@ -2223,8 +2286,8 @@
 
 status_t AudioTrack::restoreTrack_l(const char *from)
 {
-    ALOGW("dead IAudioTrack, %s, creating a new one from %s()",
-          isOffloadedOrDirect_l() ? "Offloaded or Direct" : "PCM", from);
+    ALOGW("%s(%d): dead IAudioTrack, %s, creating a new one from %s()",
+            __func__, mPortId, isOffloadedOrDirect_l() ? "Offloaded or Direct" : "PCM", from);
     ++mSequence;
 
     // refresh the audio configuration cache in this process to make sure we get new
@@ -2267,10 +2330,7 @@
     // If a new IAudioTrack cannot be created, the previous (dead) instance will be left intact.
     status_t result = createTrack_l();
 
-    if (result != NO_ERROR) {
-        ALOGW("%s(): createTrack_l failed, do not retry", __func__);
-        retries = 0;
-    } else {
+    if (result == NO_ERROR) {
         // take the frames that will be lost by track recreation into account in saved position
         // For streaming tracks, this is the amount we obtained from the user/client
         // (not the number actually consumed at the server - those are already lost).
@@ -2285,7 +2345,7 @@
             } else {
                 mStaticProxy->setBufferPosition(bufferPosition);
                 if (bufferPosition == mFrameCount) {
-                    ALOGD("restoring track at end of static buffer");
+                    ALOGD("%s(%d): restoring track at end of static buffer", __func__, mPortId);
                 }
             }
         }
@@ -2315,14 +2375,18 @@
         mFramesWrittenAtRestore = mFramesWrittenServerOffset;
     }
     if (result != NO_ERROR) {
-        ALOGW("%s() failed status %d, retries %d", __func__, result, retries);
+        ALOGW("%s(%d): failed status %d, retries %d", __func__, mPortId, result, retries);
         if (--retries > 0) {
+            // leave time for an eventual race condition to clear before retrying
+            usleep(500000);
             goto retry;
         }
-        mState = STATE_STOPPED;
-        mReleased = 0;
+        // if no retries left, set invalid bit to force restoring at next occasion
+        // and avoid inconsistent active state on client and server sides
+        if (mCblk != nullptr) {
+            android_atomic_or(CBLK_INVALID, &mCblk->mFlags);
+        }
     }
-
     return result;
 }
 
@@ -2340,8 +2404,8 @@
     //      unless the server has more than 2^31 frames in its buffer,
     //      in which case the use of uint32_t for these counters has bigger issues.
     ALOGE_IF(delta < 0,
-            "detected illegal retrograde motion by the server: mServer advanced by %d",
-            delta);
+            "%s(%d): detected illegal retrograde motion by the server: mServer advanced by %d",
+            __func__, mPortId, delta);
     mServer = newServer;
     if (delta > 0) { // avoid retrograde
         mPosition += delta;
@@ -2361,9 +2425,10 @@
                                             sampleRate, speed /*, 0 mNotificationsPerBufferReq*/);
     const bool allowed = mFrameCount >= minFrameCount;
     ALOGD_IF(!allowed,
-            "isSampleRateSpeedAllowed_l denied "
+            "%s(%d): denied "
             "mAfLatency:%u  mAfFrameCount:%zu  mAfSampleRate:%u  sampleRate:%u  speed:%f "
             "mFrameCount:%zu < minFrameCount:%zu",
+            __func__, mPortId,
             mAfLatency, mAfFrameCount, mAfSampleRate, sampleRate, speed,
             mFrameCount, minFrameCount);
     return allowed;
@@ -2381,7 +2446,8 @@
     AudioParameter param = AudioParameter();
     param.addInt(String8(AudioParameter::keyPresentationId), presentationId);
     param.addInt(String8(AudioParameter::keyProgramId), programId);
-    ALOGV("PresentationId/ProgramId[%s]",param.toString().string());
+    ALOGV("%s(%d): PresentationId/ProgramId[%s]",
+            __func__, mPortId, param.toString().string());
 
     return mAudioTrack->setParameters(param.toString());
 }
@@ -2408,7 +2474,7 @@
     } else {
         // warn only if not an expected restore failure.
         ALOGW_IF(!((isOffloadedOrDirect_l() || mDoNotReconnect) && status == DEAD_OBJECT),
-                "applyVolumeShaper failed: %d", status);
+                "%s(%d): applyVolumeShaper failed: %d", __func__, mPortId, status);
     }
     return status;
 }
@@ -2449,7 +2515,8 @@
         return INVALID_OPERATION; // not supported
     }
     status_t status = mProxy->getTimestamp(timestamp);
-    LOG_ALWAYS_FATAL_IF(status != OK, "status %d not allowed from proxy getTimestamp", status);
+    LOG_ALWAYS_FATAL_IF(status != OK, "%s(%d): status %d not allowed from proxy getTimestamp",
+            __func__, mPortId, status);
     bool found = false;
     timestamp->mPosition[ExtendedTimestamp::LOCATION_CLIENT] = mFramesWritten;
     timestamp->mTimeNs[ExtendedTimestamp::LOCATION_CLIENT] = 0;
@@ -2492,7 +2559,8 @@
         }
         break; // offloaded tracks handled below
     default:
-        LOG_ALWAYS_FATAL("Invalid mState in getTimestamp(): %d", mState);
+        LOG_ALWAYS_FATAL("%s(%d): Invalid mState in getTimestamp(): %d",
+               __func__, mPortId, mState);
         break;
     }
 
@@ -2526,7 +2594,8 @@
                 // In this case we adjust the position from the previous computed latency.
                 if (location == ExtendedTimestamp::LOCATION_SERVER) {
                     ALOGW_IF(mPreviousLocation == ExtendedTimestamp::LOCATION_KERNEL,
-                            "getTimestamp() location moved from kernel to server");
+                            "%s(%d): location moved from kernel to server",
+                            __func__, mPortId);
                     // check that the last kernel OK time info exists and the positions
                     // are valid (if they predate the current track, the positions may
                     // be zero or negative).
@@ -2541,8 +2610,8 @@
                             :
                             (ets.mPosition[ExtendedTimestamp::LOCATION_SERVER_LASTKERNELOK]
                             - ets.mPosition[ExtendedTimestamp::LOCATION_KERNEL_LASTKERNELOK]);
-                    ALOGV("frame adjustment:%lld  timestamp:%s",
-                            (long long)frames, ets.toString().c_str());
+                    ALOGV("%s(%d): frame adjustment:%lld  timestamp:%s",
+                            __func__, mPortId, (long long)frames, ets.toString().c_str());
                     if (frames >= ets.mPosition[location]) {
                         timestamp.mPosition = 0;
                     } else {
@@ -2550,7 +2619,27 @@
                     }
                 } else if (location == ExtendedTimestamp::LOCATION_KERNEL) {
                     ALOGV_IF(mPreviousLocation == ExtendedTimestamp::LOCATION_SERVER,
-                            "getTimestamp() location moved from server to kernel");
+                            "%s(%d): location moved from server to kernel",
+                            __func__, mPortId);
+
+                    if (ets.mPosition[ExtendedTimestamp::LOCATION_SERVER] ==
+                            ets.mPosition[ExtendedTimestamp::LOCATION_KERNEL]) {
+                        // In Q, we don't return errors as an invalid time
+                        // but instead we leave the last kernel good timestamp alone.
+                        //
+                        // If server is identical to kernel, the device data pipeline is idle.
+                        // A better start time is now.  The retrograde check ensures
+                        // timestamp monotonicity.
+                        const int64_t nowNs = systemTime();
+                        if (!mTimestampStallReported) {
+                            ALOGD("%s(%d): device stall time corrected using current time %lld",
+                                    __func__, mPortId, (long long)nowNs);
+                            mTimestampStallReported = true;
+                        }
+                        timestamp.mTime = convertNsToTimespec(nowNs);
+                    }  else {
+                        mTimestampStallReported = false;
+                    }
                 }
 
                 // We update the timestamp time even when paused.
@@ -2574,7 +2663,7 @@
                 mPreviousLocation = location;
             } else {
                 // right after AudioTrack is started, one may not find a timestamp
-                ALOGV("getBestTimestamp did not find timestamp");
+                ALOGV("%s(%d): getBestTimestamp did not find timestamp", __func__, mPortId);
             }
         }
         if (status == INVALID_OPERATION) {
@@ -2584,7 +2673,8 @@
             // to be zero we convert this to WOULD_BLOCK (with the implicit meaning of
             // "zero" for NuPlayer).  We don't convert for track restoration as position
             // does not reset.
-            ALOGV("timestamp server offset:%lld restore frames:%lld",
+            ALOGV("%s(%d): timestamp server offset:%lld restore frames:%lld",
+                    __func__, mPortId,
                     (long long)mFramesWrittenServerOffset, (long long)mFramesWrittenAtRestore);
             if (mFramesWrittenServerOffset != mFramesWrittenAtRestore) {
                 status = WOULD_BLOCK;
@@ -2592,7 +2682,7 @@
         }
     }
     if (status != NO_ERROR) {
-        ALOGV_IF(status != WOULD_BLOCK, "getTimestamp error:%#x", status);
+        ALOGV_IF(status != WOULD_BLOCK, "%s(%d): getTimestamp error:%#x", __func__, mPortId, status);
         return status;
     }
     if (isOffloadedOrDirect_l()) {
@@ -2631,8 +2721,9 @@
                     // since the start time.  If greater, then that means we may have failed
                     // to completely flush or stop the previous playing track.
                     ALOGW_IF(!mTimestampStartupGlitchReported,
-                            "getTimestamp startup glitch detected"
+                            "%s(%d): startup glitch detected"
                             " deltaTimeUs(%lld) deltaPositionUs(%lld) tsmPosition(%u)",
+                            __func__, mPortId,
                             (long long)deltaTimeUs, (long long)deltaPositionByUs,
                             timestamp.mPosition);
                     mTimestampStartupGlitchReported = true;
@@ -2686,33 +2777,49 @@
     // Prevent retrograde motion in timestamp.
     // This is sometimes caused by erratic reports of the available space in the ALSA drivers.
     if (status == NO_ERROR) {
+        // Fix stale time when checking timestamp right after start().
+        // The position is at the last reported location but the time can be stale
+        // due to pause or standby or cold start latency.
+        //
+        // We keep advancing the time (but not the position) to ensure that the
+        // stale value does not confuse the application.
+        //
+        // For offload compatibility, use a default lag value here.
+        // Any time discrepancy between this update and the pause timestamp is handled
+        // by the retrograde check afterwards.
+        int64_t currentTimeNanos = audio_utils_ns_from_timespec(&timestamp.mTime);
+        const int64_t lagNs = int64_t(mAfLatency * 1000000LL);
+        const int64_t limitNs = mStartNs - lagNs;
+        if (currentTimeNanos < limitNs) {
+            if (!mTimestampStaleTimeReported) {
+                ALOGD("%s(%d): stale timestamp time corrected, "
+                        "currentTimeNanos: %lld < limitNs: %lld < mStartNs: %lld",
+                        __func__, mPortId,
+                        (long long)currentTimeNanos, (long long)limitNs, (long long)mStartNs);
+                mTimestampStaleTimeReported = true;
+            }
+            timestamp.mTime = convertNsToTimespec(limitNs);
+            currentTimeNanos = limitNs;
+        } else {
+            mTimestampStaleTimeReported = false;
+        }
+
         // previousTimestampValid is set to false when starting after a stop or flush.
         if (previousTimestampValid) {
             const int64_t previousTimeNanos =
                     audio_utils_ns_from_timespec(&mPreviousTimestamp.mTime);
-            int64_t currentTimeNanos = audio_utils_ns_from_timespec(&timestamp.mTime);
-
-            // Fix stale time when checking timestamp right after start().
-            //
-            // For offload compatibility, use a default lag value here.
-            // Any time discrepancy between this update and the pause timestamp is handled
-            // by the retrograde check afterwards.
-            const int64_t lagNs = int64_t(mAfLatency * 1000000LL);
-            const int64_t limitNs = mStartNs - lagNs;
-            if (currentTimeNanos < limitNs) {
-                ALOGD("correcting timestamp time for pause, "
-                        "currentTimeNanos: %lld < limitNs: %lld < mStartNs: %lld",
-                        (long long)currentTimeNanos, (long long)limitNs, (long long)mStartNs);
-                timestamp.mTime = convertNsToTimespec(limitNs);
-                currentTimeNanos = limitNs;
-            }
 
             // retrograde check
             if (currentTimeNanos < previousTimeNanos) {
-                ALOGW("retrograde timestamp time corrected, %lld < %lld",
-                        (long long)currentTimeNanos, (long long)previousTimeNanos);
+                if (!mTimestampRetrogradeTimeReported) {
+                    ALOGW("%s(%d): retrograde timestamp time corrected, %lld < %lld",
+                            __func__, mPortId,
+                            (long long)currentTimeNanos, (long long)previousTimeNanos);
+                    mTimestampRetrogradeTimeReported = true;
+                }
                 timestamp.mTime = mPreviousTimestamp.mTime;
-                // currentTimeNanos not used below.
+            } else {
+                mTimestampRetrogradeTimeReported = false;
             }
 
             // Looking at signed delta will work even when the timestamps
@@ -2721,15 +2828,16 @@
                     - mPreviousTimestamp.mPosition).signedValue();
             if (deltaPosition < 0) {
                 // Only report once per position instead of spamming the log.
-                if (!mRetrogradeMotionReported) {
-                    ALOGW("retrograde timestamp position corrected, %d = %u - %u",
+                if (!mTimestampRetrogradePositionReported) {
+                    ALOGW("%s(%d): retrograde timestamp position corrected, %d = %u - %u",
+                            __func__, mPortId,
                             deltaPosition,
                             timestamp.mPosition,
                             mPreviousTimestamp.mPosition);
-                    mRetrogradeMotionReported = true;
+                    mTimestampRetrogradePositionReported = true;
                 }
             } else {
-                mRetrogradeMotionReported = false;
+                mTimestampRetrogradePositionReported = false;
             }
             if (deltaPosition < 0) {
                 timestamp.mPosition = mPreviousTimestamp.mPosition;
@@ -2742,7 +2850,8 @@
             if (deltaTime != 0) {
                 const int64_t computedSampleRate =
                         deltaPosition * (long long)NANOS_PER_SECOND / deltaTime;
-                ALOGD("computedSampleRate:%u  sampleRate:%u",
+                ALOGD("%s(%d): computedSampleRate:%u  sampleRate:%u",
+                        __func__, mPortId,
                         (unsigned)computedSampleRate, mSampleRate);
             }
 #endif
@@ -2788,11 +2897,12 @@
     String8 result;
 
     result.append(" AudioTrack::dump\n");
-    result.appendFormat("  status(%d), state(%d), session Id(%d), flags(%#x)\n",
-                        mStatus, mState, mSessionId, mFlags);
+    result.appendFormat("  id(%d) status(%d), state(%d), session Id(%d), flags(%#x)\n",
+                        mPortId, mStatus, mState, mSessionId, mFlags);
     result.appendFormat("  stream type(%d), left - right volume(%f, %f)\n",
                         (mStreamType == AUDIO_STREAM_DEFAULT) ?
-                                audio_attributes_to_stream_type(&mAttributes) : mStreamType,
+                            AudioSystem::attributesToStreamType(mAttributes) :
+                            mStreamType,
                         mVolume[AUDIO_INTERLEAVE_LEFT], mVolume[AUDIO_INTERLEAVE_RIGHT]);
     result.appendFormat("  format(%#x), channel mask(%#x), channel count(%u)\n",
                   mFormat, mChannelMask, mChannelCount);
@@ -2830,22 +2940,23 @@
 
 status_t AudioTrack::addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback)
 {
+
     if (callback == 0) {
-        ALOGW("%s adding NULL callback!", __FUNCTION__);
+        ALOGW("%s(%d): adding NULL callback!", __func__, mPortId);
         return BAD_VALUE;
     }
     AutoMutex lock(mLock);
     if (mDeviceCallback.unsafe_get() == callback.get()) {
-        ALOGW("%s adding same callback!", __FUNCTION__);
+        ALOGW("%s(%d): adding same callback!", __func__, mPortId);
         return INVALID_OPERATION;
     }
     status_t status = NO_ERROR;
     if (mOutput != AUDIO_IO_HANDLE_NONE) {
         if (mDeviceCallback != 0) {
-            ALOGW("%s callback already present!", __FUNCTION__);
-            AudioSystem::removeAudioDeviceCallback(this, mOutput);
+            ALOGW("%s(%d): callback already present!", __func__, mPortId);
+            AudioSystem::removeAudioDeviceCallback(this, mOutput, mPortId);
         }
-        status = AudioSystem::addAudioDeviceCallback(this, mOutput);
+        status = AudioSystem::addAudioDeviceCallback(this, mOutput, mPortId);
     }
     mDeviceCallback = callback;
     return status;
@@ -2855,7 +2966,7 @@
         const sp<AudioSystem::AudioDeviceCallback>& callback)
 {
     if (callback == 0) {
-        ALOGW("%s removing NULL callback!", __FUNCTION__);
+        ALOGW("%s(%d): removing NULL callback!", __func__, mPortId);
         return BAD_VALUE;
     }
     AutoMutex lock(mLock);
@@ -2865,7 +2976,7 @@
     }
     mDeviceCallback.clear();
     if (mOutput != AUDIO_IO_HANDLE_NONE) {
-        AudioSystem::removeAudioDeviceCallback(this, mOutput);
+        AudioSystem::removeAudioDeviceCallback(this, mOutput, mPortId);
     }
     return NO_ERROR;
 }
@@ -2887,6 +2998,7 @@
             mRoutedDeviceId = deviceId;
         }
     }
+
     if (callback.get() != nullptr) {
         callback->onAudioDeviceUpdate(mOutput, mRoutedDeviceId);
     }
@@ -2957,7 +3069,7 @@
         if (mProxy->getStreamEndDone()) {
             return true;
         }
-        // fall through
+        FALLTHROUGH_INTENDED;
     case STATE_ACTIVE:
     case STATE_STOPPING:
         break;
@@ -2966,7 +3078,7 @@
     case STATE_FLUSHED:
         return false;  // we're not active
     default:
-        LOG_ALWAYS_FATAL("Invalid mState in hasStarted(): %d", mState);
+        LOG_ALWAYS_FATAL("%s(%d): Invalid mState in hasStarted(): %d", __func__, mPortId, mState);
         break;
     }
 
@@ -2982,7 +3094,8 @@
         } else if (status == OK) {
             wait = (ts.mPosition == 0 || ts.mPosition == mStartTs.mPosition);
         }
-        ALOGV("hasStarted wait:%d  ts:%u  start position:%lld",
+        ALOGV("%s(%d): hasStarted wait:%d  ts:%u  start position:%lld",
+                __func__, mPortId,
                 (int)wait,
                 ts.mPosition,
                 (long long)mStartTs.mPosition);
@@ -3003,7 +3116,8 @@
                 break;
             }
         }
-        ALOGV("hasStarted wait:%d  ets:%lld  start position:%lld",
+        ALOGV("%s(%d): hasStarted wait:%d  ets:%lld  start position:%lld",
+                __func__, mPortId,
                 (int)wait,
                 (long long)ets.mPosition[location],
                 (long long)mStartEts.mPosition[location]);
@@ -3024,8 +3138,9 @@
 
 // =========================================================================
 
-AudioTrack::AudioTrackThread::AudioTrackThread(AudioTrack& receiver, bool bCanCallJava)
-    : Thread(bCanCallJava), mReceiver(receiver), mPaused(true), mPausedInt(false), mPausedNs(0LL),
+AudioTrack::AudioTrackThread::AudioTrackThread(AudioTrack& receiver)
+    : Thread(true /* bCanCallJava */)  // binder recursion on restoreTrack_l() may call Java.
+    , mReceiver(receiver), mPaused(true), mPausedInt(false), mPausedNs(0LL),
       mIgnoreNextPausedInt(false)
 {
 }
@@ -3076,9 +3191,10 @@
     case NS_WHENEVER:
         // Event driven: call wake() when callback notifications conditions change.
         ns = INT64_MAX;
-        // fall through
+        FALLTHROUGH_INTENDED;
     default:
-        LOG_ALWAYS_FATAL_IF(ns < 0, "processAudioBuffer() returned %" PRId64, ns);
+        LOG_ALWAYS_FATAL_IF(ns < 0, "%s(%d): processAudioBuffer() returned %lld",
+                __func__, mReceiver.mPortId, (long long)ns);
         pauseInternal(ns);
         return true;
     }
diff --git a/media/libaudioclient/AudioTrackShared.cpp b/media/libaudioclient/AudioTrackShared.cpp
index dced3c4..ee6c335 100644
--- a/media/libaudioclient/AudioTrackShared.cpp
+++ b/media/libaudioclient/AudioTrackShared.cpp
@@ -17,8 +17,10 @@
 #define LOG_TAG "AudioTrackShared"
 //#define LOG_NDEBUG 0
 
+#include <android-base/macros.h>
 #include <private/media/AudioTrackShared.h>
 #include <utils/Log.h>
+#include <audio_utils/safe_math.h>
 
 #include <linux/futex.h>
 #include <sys/syscall.h>
@@ -185,7 +187,7 @@
             front = cblk->u.mStreaming.mFront;
         }
         // write to rear, read from front
-        ssize_t filled = rear - front;
+        ssize_t filled = audio_utils::safe_sub_overflow(rear, front);
         // pipe should not be overfull
         if (!(0 <= filled && (size_t) filled <= mFrameCount)) {
             if (mIsOut) {
@@ -247,7 +249,7 @@
                 ts = requested;
                 break;
             }
-            // fall through
+            FALLTHROUGH_INTENDED;
         case TIMEOUT_CONTINUE:
             // FIXME we do not retry if requested < 10ms? needs documentation on this state machine
             if (!measure || requested->tv_sec < total.tv_sec ||
@@ -286,7 +288,8 @@
                 struct timespec after;
                 clock_gettime(CLOCK_MONOTONIC, &after);
                 total.tv_sec += after.tv_sec - before.tv_sec;
-                long deltaNs = after.tv_nsec - before.tv_nsec;
+                // Use auto instead of long to avoid the google-runtime-int warning.
+                auto deltaNs = after.tv_nsec - before.tv_nsec;
                 if (deltaNs < 0) {
                     deltaNs += 1000000000;
                     total.tv_sec--;
@@ -504,7 +507,7 @@
                 ts = requested;
                 break;
             }
-            // fall through
+            FALLTHROUGH_INTENDED;
         case TIMEOUT_CONTINUE:
             // FIXME we do not retry if requested < 10ms? needs documentation on this state machine
             if (requested->tv_sec < total.tv_sec ||
@@ -682,7 +685,7 @@
         const size_t overflowBit = mFrameCountP2 << 1;
         const size_t mask = overflowBit - 1;
         int32_t newFront = (front & ~mask) | (flush & mask);
-        ssize_t filled = rear - newFront;
+        ssize_t filled = audio_utils::safe_sub_overflow(rear, newFront);
         if (filled >= (ssize_t)overflowBit) {
             // front and rear offsets span the overflow bit of the p2 mask
             // so rebasing newFront on the front offset is off by the overflow bit.
@@ -724,7 +727,7 @@
         const size_t overflowBit = mFrameCountP2 << 1;
         const size_t mask = overflowBit - 1;
         int32_t newRear = (rear & ~mask) | (stop & mask);
-        ssize_t filled = newRear - front;
+        ssize_t filled = audio_utils::safe_sub_overflow(newRear, front);
         // overflowBit is unsigned, so cast to signed for comparison.
         if (filled >= (ssize_t)overflowBit) {
             // front and rear offsets span the overflow bit of the p2 mask
@@ -776,7 +779,7 @@
         front = android_atomic_acquire_load(&cblk->u.mStreaming.mFront);
         rear = cblk->u.mStreaming.mRear;
     }
-    ssize_t filled = rear - front;
+    ssize_t filled = audio_utils::safe_sub_overflow(rear, front);
     // pipe should not already be overfull
     if (!(0 <= filled && (size_t) filled <= mFrameCount)) {
         ALOGE("Shared memory control block is corrupt (filled=%zd, mFrameCount=%zu); shutting down",
@@ -903,7 +906,7 @@
         return mFrameCount;
     }
     const int32_t rear = getRear();
-    ssize_t filled = rear - cblk->u.mStreaming.mFront;
+    ssize_t filled = audio_utils::safe_sub_overflow(rear, cblk->u.mStreaming.mFront);
     // pipe should not already be overfull
     if (!(0 <= filled && (size_t) filled <= mFrameCount)) {
         ALOGE("Shared memory control block is corrupt (filled=%zd, mFrameCount=%zu); shutting down",
@@ -929,7 +932,7 @@
         return mFrameCount;
     }
     const int32_t rear = getRear();
-    const ssize_t filled = rear - cblk->u.mStreaming.mFront;
+    const ssize_t filled = audio_utils::safe_sub_overflow(rear, cblk->u.mStreaming.mFront);
     if (!(0 <= filled && (size_t) filled <= mFrameCount)) {
         return 0; // error condition, silently return 0.
     }
@@ -1231,6 +1234,21 @@
     return 0;
 }
 
+__attribute__((no_sanitize("integer")))
+size_t AudioRecordServerProxy::framesReadySafe() const
+{
+    if (mIsShutdown) {
+        return 0;
+    }
+    const int32_t front = android_atomic_acquire_load(&mCblk->u.mStreaming.mFront);
+    const int32_t rear = mCblk->u.mStreaming.mRear;
+    const ssize_t filled = audio_utils::safe_sub_overflow(rear, front);
+    if (!(0 <= filled && (size_t) filled <= mFrameCount)) {
+        return 0; // error condition, silently return 0.
+    }
+    return filled;
+}
+
 // ---------------------------------------------------------------------------
 
 }   // namespace android
diff --git a/media/libaudioclient/AudioVolumeGroup.cpp b/media/libaudioclient/AudioVolumeGroup.cpp
new file mode 100644
index 0000000..e79a362
--- /dev/null
+++ b/media/libaudioclient/AudioVolumeGroup.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AudioVolumeGroup"
+
+//#define LOG_NDEBUG 0
+
+#include <utils/Log.h>
+#include <binder/Parcel.h>
+
+#include <media/AudioVolumeGroup.h>
+#include <media/AudioAttributes.h>
+
+namespace android {
+
+status_t AudioVolumeGroup::readFromParcel(const Parcel *parcel)
+{
+    status_t ret = parcel->readUtf8FromUtf16(&mName);
+    if (ret != NO_ERROR) {
+        return ret;
+    }
+    mGroupId = static_cast<volume_group_t>(parcel->readInt32());
+    size_t size = static_cast<size_t>(parcel->readInt32());
+    for (size_t i = 0; i < size; i++) {
+        AudioAttributes attribute;
+        attribute.readFromParcel(parcel);
+        if (ret != NO_ERROR) {
+            mAudioAttributes.clear();
+            return ret;
+        }
+        mAudioAttributes.push_back(attribute.getAttributes());
+    }
+    size = static_cast<size_t>(parcel->readInt32());
+    for (size_t i = 0; i < size; i++) {
+        audio_stream_type_t stream = static_cast<audio_stream_type_t>(parcel->readInt32());
+        mStreams.push_back(stream);
+    }
+    return NO_ERROR;
+}
+
+status_t AudioVolumeGroup::writeToParcel(Parcel *parcel) const
+{
+    parcel->writeUtf8AsUtf16(mName);
+    parcel->writeInt32(static_cast<int32_t>(mGroupId));
+    size_t size = mAudioAttributes.size();
+    size_t sizePosition = parcel->dataPosition();
+    parcel->writeInt32(size);
+    size_t finalSize = size;
+    for (const auto &attributes : mAudioAttributes) {
+        size_t position = parcel->dataPosition();
+        AudioAttributes attribute(attributes);
+        status_t ret = attribute.writeToParcel(parcel);
+        if (ret != NO_ERROR) {
+            parcel->setDataPosition(position);
+            finalSize--;
+        }
+    }
+    if (size != finalSize) {
+        size_t position = parcel->dataPosition();
+        parcel->setDataPosition(sizePosition);
+        parcel->writeInt32(finalSize);
+        parcel->setDataPosition(position);
+    }
+    parcel->writeInt32(mStreams.size());
+    for (const auto &stream : mStreams) {
+        parcel->writeInt32(static_cast<int32_t>(stream));
+    }
+    return NO_ERROR;
+}
+
+} // namespace android
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 9f3b742..dd95e34 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -24,10 +24,8 @@
 
 #include <binder/IPCThreadState.h>
 #include <binder/Parcel.h>
-#include <cutils/multiuser.h>
 #include <media/TimeCheck.h>
-#include <private/android_filesystem_config.h>
-
+#include <mediautils/ServiceUtilities.h>
 #include "IAudioFlinger.h"
 
 namespace android {
@@ -89,6 +87,9 @@
     SYSTEM_READY,
     FRAME_COUNT_HAL,
     GET_MICROPHONES,
+    SET_MASTER_BALANCE,
+    GET_MASTER_BALANCE,
+    SET_EFFECT_SUSPENDED,
 };
 
 #define MAX_ITEMS_PER_LIST 1024
@@ -244,6 +245,34 @@
         return reply.readInt32();
     }
 
+    status_t setMasterBalance(float balance) override
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+        data.writeFloat(balance);
+        status_t status = remote()->transact(SET_MASTER_BALANCE, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        return reply.readInt32();
+    }
+
+    status_t getMasterBalance(float *balance) const override
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+        status_t status = remote()->transact(GET_MASTER_BALANCE, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        status = (status_t)reply.readInt32();
+        if (status != NO_ERROR) {
+            return status;
+        }
+        *balance = reply.readFloat();
+        return NO_ERROR;
+    }
+
     virtual status_t setStreamVolume(audio_stream_type_t stream, float value,
             audio_io_handle_t output)
     {
@@ -600,14 +629,18 @@
     }
 
     virtual status_t getEffectDescriptor(const effect_uuid_t *pUuid,
-            effect_descriptor_t *pDescriptor) const
+                                         const effect_uuid_t *pType,
+                                         uint32_t preferredTypeFlag,
+                                         effect_descriptor_t *pDescriptor) const
     {
-        if (pUuid == NULL || pDescriptor == NULL) {
+        if (pUuid == NULL || pType == NULL || pDescriptor == NULL) {
             return BAD_VALUE;
         }
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
         data.write(pUuid, sizeof(effect_uuid_t));
+        data.write(pType, sizeof(effect_uuid_t));
+        data.writeUint32(preferredTypeFlag);
         status_t status = remote()->transact(GET_EFFECT_DESCRIPTOR, data, &reply);
         if (status != NO_ERROR) {
             return status;
@@ -636,10 +669,10 @@
         sp<IEffect> effect;
 
         if (pDesc == NULL) {
-            return effect;
             if (status != NULL) {
                 *status = BAD_VALUE;
             }
+            return effect;
         }
 
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
@@ -686,6 +719,18 @@
         return reply.readInt32();
     }
 
+    virtual void setEffectSuspended(int effectId,
+                                    audio_session_t sessionId,
+                                    bool suspended)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+        data.writeInt32(effectId);
+        data.writeInt32(sessionId);
+        data.writeInt32(suspended ? 1 : 0);
+        remote()->transact(SET_EFFECT_SUSPENDED, data, &reply);
+    }
+
     virtual audio_module_handle_t loadHwModule(const char *name)
     {
         Parcel data, reply;
@@ -881,6 +926,7 @@
         case INVALIDATE_STREAM:
         case SET_VOICE_VOLUME:
         case MOVE_EFFECTS:
+        case SET_EFFECT_SUSPENDED:
         case LOAD_HW_MODULE:
         case LIST_AUDIO_PORTS:
         case GET_AUDIO_PORT:
@@ -894,6 +940,7 @@
             // return status only for non void methods
             switch (code) {
                 case SET_RECORD_SILENCED:
+                case SET_EFFECT_SUSPENDED:
                     break;
                 default:
                     reply->writeInt32(static_cast<int32_t> (INVALID_OPERATION));
@@ -912,7 +959,7 @@
         case SET_MIC_MUTE:
         case SET_LOW_RAM_DEVICE:
         case SYSTEM_READY: {
-            if (multiuser_get_app_id(IPCThreadState::self()->getCallingUid()) >= AID_APP_START) {
+            if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
                 ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
                       __func__, code, IPCThreadState::self()->getCallingPid(),
                       IPCThreadState::self()->getCallingUid());
@@ -951,9 +998,8 @@
             break;
     }
 
-    char timeCheckString[64];
-    snprintf(timeCheckString, sizeof(timeCheckString), "IAudioFlinger: %d", code);
-    TimeCheck check(timeCheckString);
+    std::string tag("IAudioFlinger command " + std::to_string(code));
+    TimeCheck check(tag.c_str());
 
     switch (code) {
         case CREATE_TRACK: {
@@ -1049,6 +1095,21 @@
             reply->writeInt32( masterMute() );
             return NO_ERROR;
         } break;
+        case SET_MASTER_BALANCE: {
+            CHECK_INTERFACE(IAudioFlinger, data, reply);
+            reply->writeInt32( setMasterBalance(data.readFloat()) );
+            return NO_ERROR;
+        } break;
+        case GET_MASTER_BALANCE: {
+            CHECK_INTERFACE(IAudioFlinger, data, reply);
+            float f;
+            const status_t status = getMasterBalance(&f);
+            reply->writeInt32((int32_t)status);
+            if (status == NO_ERROR) {
+                (void)reply->writeFloat(f);
+            }
+            return NO_ERROR;
+        } break;
         case SET_STREAM_VOLUME: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             int stream = data.readInt32();
@@ -1280,8 +1341,11 @@
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             effect_uuid_t uuid;
             data.read(&uuid, sizeof(effect_uuid_t));
+            effect_uuid_t type;
+            data.read(&type, sizeof(effect_uuid_t));
+            uint32_t preferredTypeFlag = data.readUint32();
             effect_descriptor_t desc = {};
-            status_t status = getEffectDescriptor(&uuid, &desc);
+            status_t status = getEffectDescriptor(&uuid, &type, preferredTypeFlag, &desc);
             reply->writeInt32(status);
             if (status == NO_ERROR) {
                 reply->write(&desc, sizeof(effect_descriptor_t));
@@ -1322,6 +1386,14 @@
             reply->writeInt32(moveEffects(session, srcOutput, dstOutput));
             return NO_ERROR;
         } break;
+        case SET_EFFECT_SUSPENDED: {
+            CHECK_INTERFACE(IAudioFlinger, data, reply);
+            int effectId = data.readInt32();
+            audio_session_t sessionId = (audio_session_t) data.readInt32();
+            bool suspended = data.readInt32() == 1;
+            setEffectSuspended(effectId, sessionId, suspended);
+            return NO_ERROR;
+        } break;
         case LOAD_HW_MODULE: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             reply->writeInt32(loadHwModule(data.readCString()));
diff --git a/media/libaudioclient/IAudioFlingerClient.cpp b/media/libaudioclient/IAudioFlingerClient.cpp
index b2dbc4c..47eb7dc 100644
--- a/media/libaudioclient/IAudioFlingerClient.cpp
+++ b/media/libaudioclient/IAudioFlingerClient.cpp
@@ -52,6 +52,7 @@
         data.writeInt64(ioDesc->mFrameCount);
         data.writeInt64(ioDesc->mFrameCountHAL);
         data.writeInt32(ioDesc->mLatency);
+        data.writeInt32(ioDesc->mPortId);
         remote()->transact(IO_CONFIG_CHANGED, data, &reply, IBinder::FLAG_ONEWAY);
     }
 };
@@ -76,6 +77,7 @@
             ioDesc->mFrameCount = data.readInt64();
             ioDesc->mFrameCountHAL = data.readInt64();
             ioDesc->mLatency = data.readInt32();
+            ioDesc->mPortId = data.readInt32();
             ioConfigChanged(event, ioDesc);
             return NO_ERROR;
         } break;
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index 8cd4a85..64f0aca 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -24,11 +24,10 @@
 
 #include <binder/IPCThreadState.h>
 #include <binder/Parcel.h>
-#include <cutils/multiuser.h>
 #include <media/AudioEffect.h>
 #include <media/IAudioPolicyService.h>
 #include <media/TimeCheck.h>
-#include <private/android_filesystem_config.h>
+#include <mediautils/ServiceUtilities.h>
 #include <system/audio.h>
 
 namespace android {
@@ -52,6 +51,10 @@
     INIT_STREAM_VOLUME,
     SET_STREAM_VOLUME,
     GET_STREAM_VOLUME,
+    SET_VOLUME_ATTRIBUTES,
+    GET_VOLUME_ATTRIBUTES,
+    GET_MIN_VOLUME_FOR_ATTRIBUTES,
+    GET_MAX_VOLUME_FOR_ATTRIBUTES,
     GET_STRATEGY_FOR_STREAM,
     GET_OUTPUT_FOR_EFFECT,
     REGISTER_EFFECT,
@@ -63,6 +66,7 @@
     SET_EFFECT_ENABLED,
     IS_STREAM_ACTIVE_REMOTELY,
     IS_OFFLOAD_SUPPORTED,
+    IS_DIRECT_OUTPUT_SUPPORTED,
     LIST_AUDIO_PORTS,
     GET_AUDIO_PORT,
     CREATE_AUDIO_PATCH,
@@ -78,11 +82,29 @@
     START_AUDIO_SOURCE,
     STOP_AUDIO_SOURCE,
     SET_AUDIO_PORT_CALLBACK_ENABLED,
+    SET_AUDIO_VOLUME_GROUP_CALLBACK_ENABLED,
     SET_MASTER_MONO,
     GET_MASTER_MONO,
     GET_STREAM_VOLUME_DB,
     GET_SURROUND_FORMATS,
-    SET_SURROUND_FORMAT_ENABLED
+    SET_SURROUND_FORMAT_ENABLED,
+    ADD_STREAM_DEFAULT_EFFECT,
+    REMOVE_STREAM_DEFAULT_EFFECT,
+    ADD_SOURCE_DEFAULT_EFFECT,
+    REMOVE_SOURCE_DEFAULT_EFFECT,
+    SET_ASSISTANT_UID,
+    SET_A11Y_SERVICES_UIDS,
+    IS_HAPTIC_PLAYBACK_SUPPORTED,
+    SET_UID_DEVICE_AFFINITY,
+    REMOVE_UID_DEVICE_AFFINITY,
+    GET_OFFLOAD_FORMATS_A2DP,
+    LIST_AUDIO_PRODUCT_STRATEGIES,
+    GET_STRATEGY_FOR_ATTRIBUTES,
+    LIST_AUDIO_VOLUME_GROUPS,
+    GET_VOLUME_GROUP_FOR_ATTRIBUTES,
+    SET_ALLOWED_CAPTURE_POLICY,
+    MOVE_EFFECTS_TO_IO,
+    SET_RTT_ENABLED
 };
 
 #define MAX_ITEMS_PER_LIST 1024
@@ -99,7 +121,8 @@
                                     audio_devices_t device,
                                     audio_policy_dev_state_t state,
                                     const char *device_address,
-                                    const char *device_name)
+                                    const char *device_name,
+                                    audio_format_t encodedFormat)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
@@ -107,6 +130,7 @@
         data.writeInt32(static_cast <uint32_t>(state));
         data.writeCString(device_address);
         data.writeCString(device_name);
+        data.writeInt32(static_cast <uint32_t>(encodedFormat));
         remote()->transact(SET_DEVICE_CONNECTION_STATE, data, &reply);
         return static_cast <status_t> (reply.readInt32());
     }
@@ -125,13 +149,15 @@
 
     virtual status_t handleDeviceConfigChange(audio_devices_t device,
                                               const char *device_address,
-                                              const char *device_name)
+                                              const char *device_name,
+                                              audio_format_t encodedFormat)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
         data.writeInt32(static_cast <uint32_t>(device));
         data.writeCString(device_address);
         data.writeCString(device_name);
+        data.writeInt32(static_cast <uint32_t>(encodedFormat));
         remote()->transact(HANDLE_DEVICE_CONFIG_CHANGE, data, &reply);
         return static_cast <status_t> (reply.readInt32());
     }
@@ -173,47 +199,41 @@
         return static_cast <audio_io_handle_t> (reply.readInt32());
     }
 
-    virtual status_t getOutputForAttr(const audio_attributes_t *attr,
-                                        audio_io_handle_t *output,
-                                        audio_session_t session,
-                                        audio_stream_type_t *stream,
-                                        pid_t pid,
-                                        uid_t uid,
-                                        const audio_config_t *config,
-                                        audio_output_flags_t flags,
-                                        audio_port_handle_t *selectedDeviceId,
-                                        audio_port_handle_t *portId)
+    status_t getOutputForAttr(audio_attributes_t *attr,
+                              audio_io_handle_t *output,
+                              audio_session_t session,
+                              audio_stream_type_t *stream,
+                              pid_t pid,
+                              uid_t uid,
+                              const audio_config_t *config,
+                              audio_output_flags_t flags,
+                              audio_port_handle_t *selectedDeviceId,
+                              audio_port_handle_t *portId,
+                              std::vector<audio_io_handle_t> *secondaryOutputs) override
         {
             Parcel data, reply;
             data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
-            if (attr == NULL) {
-                if (stream == NULL) {
-                    ALOGE("getOutputForAttr(): NULL audio attributes and stream type");
-                    return BAD_VALUE;
-                }
-                if (*stream == AUDIO_STREAM_DEFAULT) {
-                    ALOGE("getOutputForAttr unspecified stream type");
-                    return BAD_VALUE;
-                }
-            }
-            if (output == NULL) {
-                ALOGE("getOutputForAttr NULL output - shouldn't happen");
+            if (attr == nullptr) {
+                ALOGE("%s NULL audio attributes", __func__);
                 return BAD_VALUE;
             }
-            if (selectedDeviceId == NULL) {
-                ALOGE("getOutputForAttr NULL selectedDeviceId - shouldn't happen");
+            if (output == nullptr) {
+                ALOGE("%s NULL output - shouldn't happen", __func__);
                 return BAD_VALUE;
             }
-            if (portId == NULL) {
-                ALOGE("getOutputForAttr NULL portId - shouldn't happen");
+            if (selectedDeviceId == nullptr) {
+                ALOGE("%s NULL selectedDeviceId - shouldn't happen", __func__);
                 return BAD_VALUE;
             }
-            if (attr == NULL) {
-                data.writeInt32(0);
-            } else {
-                data.writeInt32(1);
-                data.write(attr, sizeof(audio_attributes_t));
+            if (portId == nullptr) {
+                ALOGE("%s NULL portId - shouldn't happen", __func__);
+                return BAD_VALUE;
             }
+            if (secondaryOutputs == nullptr) {
+                ALOGE("%s NULL secondaryOutputs - shouldn't happen", __func__);
+                return BAD_VALUE;
+            }
+            data.write(attr, sizeof(audio_attributes_t));
             data.writeInt32(session);
             if (stream == NULL) {
                 data.writeInt32(0);
@@ -235,6 +255,10 @@
             if (status != NO_ERROR) {
                 return status;
             }
+            status = (status_t)reply.read(&attr, sizeof(audio_attributes_t));
+            if (status != NO_ERROR) {
+                return status;
+            }
             *output = (audio_io_handle_t)reply.readInt32();
             audio_stream_type_t lStream = (audio_stream_type_t)reply.readInt32();
             if (stream != NULL) {
@@ -242,49 +266,40 @@
             }
             *selectedDeviceId = (audio_port_handle_t)reply.readInt32();
             *portId = (audio_port_handle_t)reply.readInt32();
-            return status;
+            secondaryOutputs->resize(reply.readInt32());
+            return reply.read(secondaryOutputs->data(),
+                              secondaryOutputs->size() * sizeof(audio_io_handle_t));
         }
 
-    virtual status_t startOutput(audio_io_handle_t output,
-                                 audio_stream_type_t stream,
-                                 audio_session_t session)
+    virtual status_t startOutput(audio_port_handle_t portId)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
-        data.writeInt32(output);
-        data.writeInt32((int32_t) stream);
-        data.writeInt32((int32_t) session);
+        data.writeInt32((int32_t)portId);
         remote()->transact(START_OUTPUT, data, &reply);
         return static_cast <status_t> (reply.readInt32());
     }
 
-    virtual status_t stopOutput(audio_io_handle_t output,
-                                audio_stream_type_t stream,
-                                audio_session_t session)
+    virtual status_t stopOutput(audio_port_handle_t portId)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
-        data.writeInt32(output);
-        data.writeInt32((int32_t) stream);
-        data.writeInt32((int32_t) session);
+        data.writeInt32((int32_t)portId);
         remote()->transact(STOP_OUTPUT, data, &reply);
         return static_cast <status_t> (reply.readInt32());
     }
 
-    virtual void releaseOutput(audio_io_handle_t output,
-                               audio_stream_type_t stream,
-                               audio_session_t session)
+    virtual void releaseOutput(audio_port_handle_t portId)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
-        data.writeInt32(output);
-        data.writeInt32((int32_t)stream);
-        data.writeInt32((int32_t)session);
+        data.writeInt32((int32_t)portId);
         remote()->transact(RELEASE_OUTPUT, data, &reply);
     }
 
     virtual status_t getInputForAttr(const audio_attributes_t *attr,
                                      audio_io_handle_t *input,
+                                     audio_unique_id_t riid,
                                      audio_session_t session,
                                      pid_t pid,
                                      uid_t uid,
@@ -314,6 +329,7 @@
         }
         data.write(attr, sizeof(audio_attributes_t));
         data.writeInt32(*input);
+        data.writeInt32(riid);
         data.writeInt32(session);
         data.writeInt32(pid);
         data.writeInt32(uid);
@@ -336,16 +352,13 @@
         return NO_ERROR;
     }
 
-    virtual status_t startInput(audio_port_handle_t portId,
-                                bool *silenced)
+    virtual status_t startInput(audio_port_handle_t portId)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
         data.writeInt32(portId);
-        data.writeInt32(*silenced ? 1 : 0);
         remote()->transact(START_INPUT, data, &reply);
         status_t status = static_cast <status_t> (reply.readInt32());
-        *silenced = reply.readInt32() == 1;
         return status;
     }
 
@@ -407,13 +420,77 @@
         return static_cast <status_t> (reply.readInt32());
     }
 
+    virtual status_t setVolumeIndexForAttributes(const audio_attributes_t &attr, int index,
+                                                 audio_devices_t device)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.write(&attr, sizeof(audio_attributes_t));
+        data.writeInt32(index);
+        data.writeInt32(static_cast <uint32_t>(device));
+        status_t status = remote()->transact(SET_VOLUME_ATTRIBUTES, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        return static_cast <status_t> (reply.readInt32());
+    }
+    virtual status_t getVolumeIndexForAttributes(const audio_attributes_t &attr, int &index,
+                                                 audio_devices_t device)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.write(&attr, sizeof(audio_attributes_t));
+        data.writeInt32(static_cast <uint32_t>(device));
+        status_t status = remote()->transact(GET_VOLUME_ATTRIBUTES, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        status = static_cast <status_t> (reply.readInt32());
+        if (status != NO_ERROR) {
+            return status;
+        }
+        index = reply.readInt32();
+        return NO_ERROR;
+    }
+    virtual status_t getMinVolumeIndexForAttributes(const audio_attributes_t &attr, int &index)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.write(&attr, sizeof(audio_attributes_t));
+        status_t status = remote()->transact(GET_MIN_VOLUME_FOR_ATTRIBUTES, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        status = static_cast <status_t> (reply.readInt32());
+        if (status != NO_ERROR) {
+            return status;
+        }
+        index = reply.readInt32();
+        return NO_ERROR;
+    }
+    virtual status_t getMaxVolumeIndexForAttributes(const audio_attributes_t &attr, int &index)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.write(&attr, sizeof(audio_attributes_t));
+        status_t status = remote()->transact(GET_MAX_VOLUME_FOR_ATTRIBUTES, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        status = static_cast <status_t> (reply.readInt32());
+        if (status != NO_ERROR) {
+            return status;
+        }
+        index = reply.readInt32();
+        return NO_ERROR;
+    }
     virtual uint32_t getStrategyForStream(audio_stream_type_t stream)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
         data.writeInt32(static_cast <uint32_t>(stream));
         remote()->transact(GET_STRATEGY_FOR_STREAM, data, &reply);
-        return reply.readInt32();
+        return reply.readUint32();
     }
 
     virtual audio_devices_t getDevicesForStream(audio_stream_type_t stream)
@@ -470,6 +547,22 @@
         return static_cast <status_t> (reply.readInt32());
     }
 
+    status_t moveEffectsToIo(const std::vector<int>& ids, audio_io_handle_t io) override
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.writeInt32(ids.size());
+        for (auto id : ids) {
+            data.writeInt32(id);
+        }
+        data.writeInt32(io);
+        status_t status = remote()->transact(MOVE_EFFECTS_TO_IO, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        return static_cast <status_t> (reply.readInt32());
+    }
+
     virtual bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
     {
         Parcel data, reply;
@@ -524,6 +617,15 @@
         return status;
     }
 
+    status_t setAllowedCapturePolicy(uid_t uid, audio_flags_mask_t flags) override {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.writeInt32(uid);
+        data.writeInt32(flags);
+        remote()->transact(SET_ALLOWED_CAPTURE_POLICY, data, &reply);
+        return reply.readInt32();
+    }
+
     virtual bool isOffloadSupported(const audio_offload_info_t& info)
     {
         Parcel data, reply;
@@ -533,6 +635,16 @@
         return reply.readInt32();
     }
 
+    virtual bool isDirectOutputSupported(const audio_config_base_t& config,
+                                         const audio_attributes_t& attributes) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.write(&config, sizeof(audio_config_base_t));
+        data.write(&attributes, sizeof(audio_attributes_t));
+        status_t status = remote()->transact(IS_DIRECT_OUTPUT_SUPPORTED, data, &reply);
+        return status == NO_ERROR ? static_cast<bool>(reply.readInt32()) : false;
+    }
+
     virtual status_t listAudioPorts(audio_port_role_t role,
                                     audio_port_type_t type,
                                     unsigned int *num_ports,
@@ -674,6 +786,14 @@
         remote()->transact(SET_AUDIO_PORT_CALLBACK_ENABLED, data, &reply);
     }
 
+    virtual void setAudioVolumeGroupCallbacksEnabled(bool enabled)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.writeInt32(enabled ? 1 : 0);
+        remote()->transact(SET_AUDIO_VOLUME_GROUP_CALLBACK_ENABLED, data, &reply);
+    }
+
     virtual status_t acquireSoundTriggerSession(audio_session_t *session,
                                             audio_io_handle_t *ioHandle,
                                             audio_devices_t *device)
@@ -753,11 +873,11 @@
 
     virtual status_t startAudioSource(const struct audio_port_config *source,
                                       const audio_attributes_t *attributes,
-                                      audio_patch_handle_t *handle)
+                                      audio_port_handle_t *portId)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
-        if (source == NULL || attributes == NULL || handle == NULL) {
+        if (source == NULL || attributes == NULL || portId == NULL) {
             return BAD_VALUE;
         }
         data.write(source, sizeof(struct audio_port_config));
@@ -770,15 +890,15 @@
         if (status != NO_ERROR) {
             return status;
         }
-        *handle = (audio_patch_handle_t)reply.readInt32();
+        *portId = (audio_port_handle_t)reply.readInt32();
         return status;
     }
 
-    virtual status_t stopAudioSource(audio_patch_handle_t handle)
+    virtual status_t stopAudioSource(audio_port_handle_t portId)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
-        data.writeInt32(handle);
+        data.writeInt32(portId);
         status_t status = remote()->transact(STOP_AUDIO_SOURCE, data, &reply);
         if (status != NO_ERROR) {
             return status;
@@ -879,6 +999,291 @@
         }
         return reply.readInt32();
     }
+
+    virtual status_t getHwOffloadEncodingFormatsSupportedForA2DP(
+                std::vector<audio_format_t> *formats)
+    {
+        if (formats == NULL) {
+            return BAD_VALUE;
+        }
+
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        status_t status = remote()->transact(GET_OFFLOAD_FORMATS_A2DP, data, &reply);
+        if (status != NO_ERROR || (status = (status_t)reply.readInt32()) != NO_ERROR) {
+            return status;
+        }
+
+        size_t list_size = reply.readUint32();
+
+        for (size_t i = 0; i < list_size; i++) {
+            formats->push_back(static_cast<audio_format_t>(reply.readInt32()));
+        }
+        return NO_ERROR;
+    }
+
+
+     virtual status_t addStreamDefaultEffect(const effect_uuid_t *type,
+                                            const String16& opPackageName,
+                                            const effect_uuid_t *uuid,
+                                            int32_t priority,
+                                            audio_usage_t usage,
+                                            audio_unique_id_t* id)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.write(type, sizeof(effect_uuid_t));
+        data.writeString16(opPackageName);
+        data.write(uuid, sizeof(effect_uuid_t));
+        data.writeInt32(priority);
+        data.writeInt32((int32_t) usage);
+        status_t status = remote()->transact(ADD_STREAM_DEFAULT_EFFECT, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        status = static_cast <status_t> (reply.readInt32());
+        *id = reply.readInt32();
+        return status;
+    }
+
+    virtual status_t removeStreamDefaultEffect(audio_unique_id_t id)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.writeInt32(id);
+        status_t status = remote()->transact(REMOVE_STREAM_DEFAULT_EFFECT, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        return static_cast <status_t> (reply.readInt32());
+    }
+
+    virtual status_t addSourceDefaultEffect(const effect_uuid_t *type,
+                                            const String16& opPackageName,
+                                            const effect_uuid_t *uuid,
+                                            int32_t priority,
+                                            audio_source_t source,
+                                            audio_unique_id_t* id)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.write(type, sizeof(effect_uuid_t));
+        data.writeString16(opPackageName);
+        data.write(uuid, sizeof(effect_uuid_t));
+        data.writeInt32(priority);
+        data.writeInt32((int32_t) source);
+        status_t status = remote()->transact(ADD_SOURCE_DEFAULT_EFFECT, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        status = static_cast <status_t> (reply.readInt32());
+        *id = reply.readInt32();
+        return status;
+    }
+
+    virtual status_t removeSourceDefaultEffect(audio_unique_id_t id)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.writeInt32(id);
+        status_t status = remote()->transact(REMOVE_SOURCE_DEFAULT_EFFECT, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        return static_cast <status_t> (reply.readInt32());
+    }
+
+    virtual status_t setAssistantUid(uid_t uid)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.writeInt32(uid);
+        status_t status = remote()->transact(SET_ASSISTANT_UID, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        return static_cast <status_t> (reply.readInt32());
+    }
+
+    virtual status_t setA11yServicesUids(const std::vector<uid_t>& uids)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.writeInt32(uids.size());
+        for (auto uid : uids) {
+            data.writeInt32(uid);
+        }
+        status_t status = remote()->transact(SET_A11Y_SERVICES_UIDS, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        return static_cast <status_t> (reply.readInt32());
+    }
+
+    virtual bool isHapticPlaybackSupported()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        status_t status = remote()->transact(IS_HAPTIC_PLAYBACK_SUPPORTED, data, &reply);
+        if (status != NO_ERROR) {
+            return false;
+        }
+        return reply.readBool();
+    }
+
+    virtual status_t setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+
+        data.writeInt32((int32_t) uid);
+        size_t size = devices.size();
+        size_t sizePosition = data.dataPosition();
+        data.writeInt32((int32_t) size);
+        size_t finalSize = size;
+        for (size_t i = 0; i < size; i++) {
+            size_t position = data.dataPosition();
+            if (devices[i].writeToParcel(&data) != NO_ERROR) {
+                data.setDataPosition(position);
+                finalSize--;
+            }
+        }
+        if (size != finalSize) {
+            size_t position = data.dataPosition();
+            data.setDataPosition(sizePosition);
+            data.writeInt32(finalSize);
+            data.setDataPosition(position);
+        }
+
+        status_t status = remote()->transact(SET_UID_DEVICE_AFFINITY, data, &reply);
+        if (status == NO_ERROR) {
+            status = (status_t)reply.readInt32();
+        }
+        return status;
+    }
+
+    virtual status_t removeUidDeviceAffinities(uid_t uid) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+
+        data.writeInt32((int32_t) uid);
+
+        status_t status =
+            remote()->transact(REMOVE_UID_DEVICE_AFFINITY, data, &reply);
+        if (status == NO_ERROR) {
+            status = (status_t) reply.readInt32();
+        }
+        return status;
+    }
+
+    virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+
+        status_t status = remote()->transact(LIST_AUDIO_PRODUCT_STRATEGIES, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGE("%s: permission denied", __func__);
+            return status;
+        }
+        status = static_cast<status_t>(reply.readInt32());
+        if (status != NO_ERROR) {
+            return status;
+        }
+        uint32_t numStrategies = static_cast<uint32_t>(reply.readInt32());
+        for (size_t i = 0; i < numStrategies; i++) {
+            AudioProductStrategy strategy;
+            status = strategy.readFromParcel(&reply);
+            if (status != NO_ERROR) {
+                ALOGE("%s: failed to read strategies", __FUNCTION__);
+                strategies.clear();
+                return status;
+            }
+            strategies.push_back(strategy);
+        }
+        return NO_ERROR;
+    }
+
+    virtual status_t getProductStrategyFromAudioAttributes(const AudioAttributes &aa,
+                                                           product_strategy_t &productStrategy)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        status_t status = aa.writeToParcel(&data);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        status = remote()->transact(GET_STRATEGY_FOR_ATTRIBUTES, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        status = static_cast<status_t>(reply.readInt32());
+        if (status != NO_ERROR) {
+            return status;
+        }
+        productStrategy = static_cast<product_strategy_t>(reply.readInt32());
+        return NO_ERROR;
+    }
+
+    virtual status_t listAudioVolumeGroups(AudioVolumeGroupVector &groups)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+
+        status_t status = remote()->transact(LIST_AUDIO_VOLUME_GROUPS, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        status = static_cast<status_t>(reply.readInt32());
+        if (status != NO_ERROR) {
+            return status;
+        }
+        uint32_t numGroups = static_cast<uint32_t>(reply.readInt32());
+        for (size_t i = 0; i < numGroups; i++) {
+            AudioVolumeGroup group;
+            status = group.readFromParcel(&reply);
+            if (status != NO_ERROR) {
+                ALOGE("%s: failed to read volume groups", __FUNCTION__);
+                groups.clear();
+                return status;
+            }
+            groups.push_back(group);
+        }
+        return NO_ERROR;
+    }
+
+    virtual status_t getVolumeGroupFromAudioAttributes(const AudioAttributes &aa,
+                                                       volume_group_t &volumeGroup)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        status_t status = aa.writeToParcel(&data);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        status = remote()->transact(GET_VOLUME_GROUP_FOR_ATTRIBUTES, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        status = static_cast<status_t>(reply.readInt32());
+        if (status != NO_ERROR) {
+            return status;
+        }
+        volumeGroup = static_cast<volume_group_t>(reply.readInt32());
+        return NO_ERROR;
+    }
+
+    virtual status_t setRttEnabled(bool enabled)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.writeInt32(static_cast<int32_t>(enabled));
+        status_t status = remote()->transact(SET_RTT_ENABLED, data, &reply);
+        if (status != NO_ERROR) {
+           return status;
+        }
+        return static_cast<status_t>(reply.readInt32());
+    }
 };
 
 IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService");
@@ -897,7 +1302,6 @@
         case START_INPUT:
         case STOP_INPUT:
         case RELEASE_INPUT:
-        case GET_STRATEGY_FOR_STREAM:
         case GET_OUTPUT_FOR_EFFECT:
         case REGISTER_EFFECT:
         case UNREGISTER_EFFECT:
@@ -905,6 +1309,7 @@
         case GET_OUTPUT_FOR_ATTR:
         case ACQUIRE_SOUNDTRIGGER_SESSION:
         case RELEASE_SOUNDTRIGGER_SESSION:
+        case MOVE_EFFECTS_TO_IO:
             ALOGW("%s: transaction %d received from PID %d",
                   __func__, code, IPCThreadState::self()->getCallingPid());
             // return status only for non void methods
@@ -932,11 +1337,17 @@
         case SET_STREAM_VOLUME:
         case REGISTER_POLICY_MIXES:
         case SET_MASTER_MONO:
-        case START_AUDIO_SOURCE:
-        case STOP_AUDIO_SOURCE:
         case GET_SURROUND_FORMATS:
-        case SET_SURROUND_FORMAT_ENABLED: {
-            if (multiuser_get_app_id(IPCThreadState::self()->getCallingUid()) >= AID_APP_START) {
+        case SET_SURROUND_FORMAT_ENABLED:
+        case SET_ASSISTANT_UID:
+        case SET_A11Y_SERVICES_UIDS:
+        case SET_UID_DEVICE_AFFINITY:
+        case REMOVE_UID_DEVICE_AFFINITY:
+        case GET_OFFLOAD_FORMATS_A2DP:
+        case LIST_AUDIO_VOLUME_GROUPS:
+        case GET_VOLUME_GROUP_FOR_ATTRIBUTES:
+        case SET_RTT_ENABLED: {
+            if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
                 ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
                       __func__, code, IPCThreadState::self()->getCallingPid(),
                       IPCThreadState::self()->getCallingUid());
@@ -948,9 +1359,8 @@
             break;
     }
 
-    char timeCheckString[64];
-    snprintf(timeCheckString, sizeof(timeCheckString), "IAudioPolicyService: %d", code);
-    TimeCheck check(timeCheckString);
+    std::string tag("IAudioPolicyService command " + std::to_string(code));
+    TimeCheck check(tag.c_str());
 
     switch (code) {
         case SET_DEVICE_CONNECTION_STATE: {
@@ -961,6 +1371,7 @@
                     static_cast <audio_policy_dev_state_t>(data.readInt32());
             const char *device_address = data.readCString();
             const char *device_name = data.readCString();
+            audio_format_t codecFormat = static_cast <audio_format_t>(data.readInt32());
             if (device_address == nullptr || device_name == nullptr) {
                 ALOGE("Bad Binder transaction: SET_DEVICE_CONNECTION_STATE for device %u", device);
                 reply->writeInt32(static_cast<int32_t> (BAD_VALUE));
@@ -968,7 +1379,8 @@
                 reply->writeInt32(static_cast<uint32_t> (setDeviceConnectionState(device,
                                                                                   state,
                                                                                   device_address,
-                                                                                  device_name)));
+                                                                                  device_name,
+                                                                                  codecFormat)));
             }
             return NO_ERROR;
         } break;
@@ -994,13 +1406,16 @@
                     static_cast <audio_devices_t>(data.readInt32());
             const char *device_address = data.readCString();
             const char *device_name = data.readCString();
+            audio_format_t codecFormat =
+                    static_cast <audio_format_t>(data.readInt32());
             if (device_address == nullptr || device_name == nullptr) {
                 ALOGE("Bad Binder transaction: HANDLE_DEVICE_CONFIG_CHANGE for device %u", device);
                 reply->writeInt32(static_cast<int32_t> (BAD_VALUE));
             } else {
                 reply->writeInt32(static_cast<uint32_t> (handleDeviceConfigChange(device,
                                                                                   device_address,
-                                                                                  device_name)));
+                                                                                  device_name,
+                                                                                  codecFormat)));
             }
             return NO_ERROR;
         } break;
@@ -1041,12 +1456,12 @@
 
         case GET_OUTPUT_FOR_ATTR: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
-            audio_attributes_t attr = {};
-            bool hasAttributes = data.readInt32() != 0;
-            if (hasAttributes) {
-                data.read(&attr, sizeof(audio_attributes_t));
-                sanetizeAudioAttributes(&attr);
+            audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
+            status_t status = data.read(&attr, sizeof(audio_attributes_t));
+            if (status != NO_ERROR) {
+                return status;
             }
+            sanetizeAudioAttributes(&attr);
             audio_session_t session = (audio_session_t)data.readInt32();
             audio_stream_type_t stream = AUDIO_STREAM_DEFAULT;
             bool hasStream = data.readInt32() != 0;
@@ -1063,48 +1478,43 @@
             audio_port_handle_t selectedDeviceId = data.readInt32();
             audio_port_handle_t portId = (audio_port_handle_t)data.readInt32();
             audio_io_handle_t output = 0;
-            status_t status = getOutputForAttr(hasAttributes ? &attr : NULL,
+            std::vector<audio_io_handle_t> secondaryOutputs;
+            status = getOutputForAttr(&attr,
                     &output, session, &stream, pid, uid,
                     &config,
-                    flags, &selectedDeviceId, &portId);
+                    flags, &selectedDeviceId, &portId, &secondaryOutputs);
             reply->writeInt32(status);
+            status = reply->write(&attr, sizeof(audio_attributes_t));
+            if (status != NO_ERROR) {
+                return status;
+            }
             reply->writeInt32(output);
             reply->writeInt32(stream);
             reply->writeInt32(selectedDeviceId);
             reply->writeInt32(portId);
-            return NO_ERROR;
+            reply->writeInt32(secondaryOutputs.size());
+            return reply->write(secondaryOutputs.data(),
+                                secondaryOutputs.size() * sizeof(audio_io_handle_t));
         } break;
 
         case START_OUTPUT: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
-            audio_io_handle_t output = static_cast <audio_io_handle_t>(data.readInt32());
-            audio_stream_type_t stream =
-                                static_cast <audio_stream_type_t>(data.readInt32());
-            audio_session_t session = (audio_session_t)data.readInt32();
-            reply->writeInt32(static_cast <uint32_t>(startOutput(output,
-                                                                 stream,
-                                                                 session)));
+            const audio_port_handle_t portId = static_cast <audio_port_handle_t>(data.readInt32());
+            reply->writeInt32(static_cast <uint32_t>(startOutput(portId)));
             return NO_ERROR;
         } break;
 
         case STOP_OUTPUT: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
-            audio_io_handle_t output = static_cast <audio_io_handle_t>(data.readInt32());
-            audio_stream_type_t stream =
-                                static_cast <audio_stream_type_t>(data.readInt32());
-            audio_session_t session = (audio_session_t)data.readInt32();
-            reply->writeInt32(static_cast <uint32_t>(stopOutput(output,
-                                                                stream,
-                                                                session)));
+            const audio_port_handle_t portId = static_cast <audio_port_handle_t>(data.readInt32());
+            reply->writeInt32(static_cast <uint32_t>(stopOutput(portId)));
             return NO_ERROR;
         } break;
 
         case RELEASE_OUTPUT: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
-            audio_io_handle_t output = static_cast <audio_io_handle_t>(data.readInt32());
-            audio_stream_type_t stream = (audio_stream_type_t)data.readInt32();
-            audio_session_t session = (audio_session_t)data.readInt32();
-            releaseOutput(output, stream, session);
+            const audio_port_handle_t portId = static_cast <audio_port_handle_t>(data.readInt32());
+            releaseOutput(portId);
             return NO_ERROR;
         } break;
 
@@ -1114,6 +1524,7 @@
             data.read(&attr, sizeof(audio_attributes_t));
             sanetizeAudioAttributes(&attr);
             audio_io_handle_t input = (audio_io_handle_t)data.readInt32();
+            audio_unique_id_t riid = (audio_unique_id_t)data.readInt32();
             audio_session_t session = (audio_session_t)data.readInt32();
             pid_t pid = (pid_t)data.readInt32();
             uid_t uid = (uid_t)data.readInt32();
@@ -1124,7 +1535,7 @@
             audio_input_flags_t flags = (audio_input_flags_t) data.readInt32();
             audio_port_handle_t selectedDeviceId = (audio_port_handle_t) data.readInt32();
             audio_port_handle_t portId = (audio_port_handle_t)data.readInt32();
-            status_t status = getInputForAttr(&attr, &input, session, pid, uid,
+            status_t status = getInputForAttr(&attr, &input, riid, session, pid, uid,
                                               opPackageName, &config,
                                               flags, &selectedDeviceId, &portId);
             reply->writeInt32(status);
@@ -1139,10 +1550,8 @@
         case START_INPUT: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
             audio_port_handle_t portId = static_cast <audio_port_handle_t>(data.readInt32());
-            bool silenced = data.readInt32() == 1;
-            status_t status = startInput(portId, &silenced);
+            status_t status = startInput(portId);
             reply->writeInt32(static_cast <uint32_t>(status));
-            reply->writeInt32(silenced ? 1 : 0);
             return NO_ERROR;
         } break;
 
@@ -1198,7 +1607,74 @@
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
             audio_stream_type_t stream =
                     static_cast <audio_stream_type_t>(data.readInt32());
-            reply->writeInt32(getStrategyForStream(stream));
+            reply->writeUint32(getStrategyForStream(stream));
+            return NO_ERROR;
+        } break;
+
+        case SET_VOLUME_ATTRIBUTES: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            audio_attributes_t attributes = {};
+            status_t status = data.read(&attributes, sizeof(audio_attributes_t));
+            if (status != NO_ERROR) {
+                return status;
+            }
+            int index = data.readInt32();
+            audio_devices_t device = static_cast <audio_devices_t>(data.readInt32());
+
+            reply->writeInt32(static_cast <uint32_t>(setVolumeIndexForAttributes(attributes,
+                                                                                 index, device)));
+            return NO_ERROR;
+        } break;
+
+        case GET_VOLUME_ATTRIBUTES: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            audio_attributes_t attributes = {};
+            status_t status = data.read(&attributes, sizeof(audio_attributes_t));
+            if (status != NO_ERROR) {
+                return status;
+            }
+            audio_devices_t device = static_cast <audio_devices_t>(data.readInt32());
+
+            int index = 0;
+            status = getVolumeIndexForAttributes(attributes, index, device);
+            reply->writeInt32(static_cast <uint32_t>(status));
+            if (status == NO_ERROR) {
+                reply->writeInt32(index);
+            }
+            return NO_ERROR;
+        } break;
+
+        case GET_MIN_VOLUME_FOR_ATTRIBUTES: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            audio_attributes_t attributes = {};
+            status_t status = data.read(&attributes, sizeof(audio_attributes_t));
+            if (status != NO_ERROR) {
+                return status;
+            }
+
+            int index = 0;
+            status = getMinVolumeIndexForAttributes(attributes, index);
+            reply->writeInt32(static_cast <uint32_t>(status));
+            if (status == NO_ERROR) {
+                reply->writeInt32(index);
+            }
+            return NO_ERROR;
+        } break;
+
+        case GET_MAX_VOLUME_FOR_ATTRIBUTES: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            audio_attributes_t attributes = {};
+            status_t status = data.read(&attributes, sizeof(audio_attributes_t));
+            if (status != NO_ERROR) {
+                return status;
+            }
+
+            int index = 0;
+            status = getMaxVolumeIndexForAttributes(attributes, index);
+            reply->writeInt32(static_cast <uint32_t>(status));
+            if (status == NO_ERROR) {
+                reply->writeInt32(index);
+            }
             return NO_ERROR;
         } break;
 
@@ -1256,6 +1732,31 @@
             return NO_ERROR;
         } break;
 
+        case MOVE_EFFECTS_TO_IO: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            std::vector<int> ids;
+            int32_t size;
+            status_t status = data.readInt32(&size);
+            if (status != NO_ERROR) {
+                return status;
+            }
+            if (size > MAX_ITEMS_PER_LIST) {
+                return BAD_VALUE;
+            }
+            for (int32_t i = 0; i < size; i++) {
+                int id;
+                status =  data.readInt32(&id);
+                if (status != NO_ERROR) {
+                    return status;
+                }
+                ids.push_back(id);
+            }
+
+            audio_io_handle_t io = data.readInt32();
+            reply->writeInt32(static_cast <int32_t>(moveEffectsToIo(ids, io)));
+            return NO_ERROR;
+        } break;
+
         case IS_STREAM_ACTIVE: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
             audio_stream_type_t stream = (audio_stream_type_t) data.readInt32();
@@ -1313,6 +1814,18 @@
             return NO_ERROR;
         }
 
+        case IS_DIRECT_OUTPUT_SUPPORTED: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            audio_config_base_t config = {};
+            audio_attributes_t attributes = {};
+            status_t status = data.read(&config, sizeof(audio_config_base_t));
+            if (status != NO_ERROR) return status;
+            status = data.read(&attributes, sizeof(audio_attributes_t));
+            if (status != NO_ERROR) return status;
+            reply->writeInt32(isDirectOutputSupported(config, attributes));
+            return NO_ERROR;
+        }
+
         case LIST_AUDIO_PORTS: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
             audio_port_role_t role = (audio_port_role_t)data.readInt32();
@@ -1438,6 +1951,12 @@
             return NO_ERROR;
         } break;
 
+        case SET_AUDIO_VOLUME_GROUP_CALLBACK_ENABLED: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            setAudioVolumeGroupCallbacksEnabled(data.readInt32() == 1);
+            return NO_ERROR;
+        } break;
+
         case ACQUIRE_SOUNDTRIGGER_SESSION: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
             sp<IAudioPolicyServiceClient> client = interface_cast<IAudioPolicyServiceClient>(
@@ -1498,17 +2017,17 @@
             audio_attributes_t attributes = {};
             data.read(&attributes, sizeof(audio_attributes_t));
             sanetizeAudioAttributes(&attributes);
-            audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
-            status_t status = startAudioSource(&source, &attributes, &handle);
+            audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
+            status_t status = startAudioSource(&source, &attributes, &portId);
             reply->writeInt32(status);
-            reply->writeInt32(handle);
+            reply->writeInt32(portId);
             return NO_ERROR;
         } break;
 
         case STOP_AUDIO_SOURCE: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
-            audio_patch_handle_t handle = (audio_patch_handle_t) data.readInt32();
-            status_t status = stopAudioSource(handle);
+            audio_port_handle_t portId = (audio_port_handle_t) data.readInt32();
+            status_t status = stopAudioSource(portId);
             reply->writeInt32(status);
             return NO_ERROR;
         } break;
@@ -1587,6 +2106,269 @@
             return NO_ERROR;
         }
 
+        case GET_OFFLOAD_FORMATS_A2DP: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            std::vector<audio_format_t> encodingFormats;
+            status_t status = getHwOffloadEncodingFormatsSupportedForA2DP(&encodingFormats);
+            reply->writeInt32(status);
+            if (status != NO_ERROR) {
+                return NO_ERROR;
+            }
+            reply->writeUint32(static_cast<uint32_t>(encodingFormats.size()));
+            for (size_t i = 0; i < encodingFormats.size(); i++)
+                reply->writeInt32(static_cast<int32_t>(encodingFormats[i]));
+            return NO_ERROR;
+        }
+
+
+        case ADD_STREAM_DEFAULT_EFFECT: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            effect_uuid_t type;
+            status_t status = data.read(&type, sizeof(effect_uuid_t));
+            if (status != NO_ERROR) {
+                return status;
+            }
+            String16 opPackageName;
+            status = data.readString16(&opPackageName);
+            if (status != NO_ERROR) {
+                return status;
+            }
+            effect_uuid_t uuid;
+            status = data.read(&uuid, sizeof(effect_uuid_t));
+            if (status != NO_ERROR) {
+                return status;
+            }
+            int32_t priority = data.readInt32();
+            audio_usage_t usage = (audio_usage_t) data.readInt32();
+            audio_unique_id_t id = 0;
+            reply->writeInt32(static_cast <int32_t>(addStreamDefaultEffect(&type,
+                                                                           opPackageName,
+                                                                           &uuid,
+                                                                           priority,
+                                                                           usage,
+                                                                           &id)));
+            reply->writeInt32(id);
+            return NO_ERROR;
+        }
+
+        case REMOVE_STREAM_DEFAULT_EFFECT: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            audio_unique_id_t id = static_cast<audio_unique_id_t>(data.readInt32());
+            reply->writeInt32(static_cast <int32_t>(removeStreamDefaultEffect(id)));
+            return NO_ERROR;
+        }
+
+        case ADD_SOURCE_DEFAULT_EFFECT: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            effect_uuid_t type;
+            status_t status = data.read(&type, sizeof(effect_uuid_t));
+            if (status != NO_ERROR) {
+                return status;
+            }
+            String16 opPackageName;
+            status = data.readString16(&opPackageName);
+            if (status != NO_ERROR) {
+                return status;
+            }
+            effect_uuid_t uuid;
+            status = data.read(&uuid, sizeof(effect_uuid_t));
+            if (status != NO_ERROR) {
+                return status;
+            }
+            int32_t priority = data.readInt32();
+            audio_source_t source = (audio_source_t) data.readInt32();
+            audio_unique_id_t id = 0;
+            reply->writeInt32(static_cast <int32_t>(addSourceDefaultEffect(&type,
+                                                                           opPackageName,
+                                                                           &uuid,
+                                                                           priority,
+                                                                           source,
+                                                                           &id)));
+            reply->writeInt32(id);
+            return NO_ERROR;
+        }
+
+        case REMOVE_SOURCE_DEFAULT_EFFECT: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            audio_unique_id_t id = static_cast<audio_unique_id_t>(data.readInt32());
+            reply->writeInt32(static_cast <int32_t>(removeSourceDefaultEffect(id)));
+            return NO_ERROR;
+        }
+
+        case SET_ASSISTANT_UID: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            int32_t uid;
+            status_t status = data.readInt32(&uid);
+            if (status != NO_ERROR) {
+                return status;
+            }
+            status = setAssistantUid(uid);
+            reply->writeInt32(static_cast <int32_t>(status));
+            return NO_ERROR;
+        }
+
+        case SET_A11Y_SERVICES_UIDS: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            std::vector<uid_t> uids;
+            int32_t size;
+            status_t status = data.readInt32(&size);
+            if (status != NO_ERROR) {
+                return status;
+            }
+            if (size > MAX_ITEMS_PER_LIST) {
+                size = MAX_ITEMS_PER_LIST;
+            }
+            for (int32_t i = 0; i < size; i++) {
+                int32_t uid;
+                status =  data.readInt32(&uid);
+                if (status != NO_ERROR) {
+                    return status;
+                }
+                uids.push_back(uid);
+            }
+            status = setA11yServicesUids(uids);
+            reply->writeInt32(static_cast <int32_t>(status));
+            return NO_ERROR;
+        }
+
+        case IS_HAPTIC_PLAYBACK_SUPPORTED: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            bool isSupported = isHapticPlaybackSupported();
+            reply->writeBool(isSupported);
+            return NO_ERROR;
+        }
+
+        case SET_UID_DEVICE_AFFINITY: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            const uid_t uid = (uid_t) data.readInt32();
+            Vector<AudioDeviceTypeAddr> devices;
+            size_t size = (size_t)data.readInt32();
+            for (size_t i = 0; i < size; i++) {
+                AudioDeviceTypeAddr device;
+                if (device.readFromParcel((Parcel*)&data) == NO_ERROR) {
+                    devices.add(device);
+                }
+            }
+            status_t status = setUidDeviceAffinities(uid, devices);
+            reply->writeInt32(status);
+            return NO_ERROR;
+        }
+
+        case REMOVE_UID_DEVICE_AFFINITY: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            const uid_t uid = (uid_t) data.readInt32();
+            status_t status = removeUidDeviceAffinities(uid);
+            reply->writeInt32(status);
+            return NO_ERROR;
+        }
+
+        case LIST_AUDIO_PRODUCT_STRATEGIES: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            AudioProductStrategyVector strategies;
+            status_t status = listAudioProductStrategies(strategies);
+            reply->writeInt32(status);
+            if (status != NO_ERROR) {
+                return NO_ERROR;
+            }
+            size_t size = strategies.size();
+            size_t sizePosition = reply->dataPosition();
+            reply->writeInt32(size);
+            size_t finalSize = size;
+            for (size_t i = 0; i < size; i++) {
+                size_t position = reply->dataPosition();
+                if (strategies[i].writeToParcel(reply) != NO_ERROR) {
+                    reply->setDataPosition(position);
+                    finalSize--;
+                }
+            }
+            if (size != finalSize) {
+                size_t position = reply->dataPosition();
+                reply->setDataPosition(sizePosition);
+                reply->writeInt32(finalSize);
+                reply->setDataPosition(position);
+            }
+            return NO_ERROR;
+        }
+
+        case GET_STRATEGY_FOR_ATTRIBUTES: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            AudioAttributes attributes;
+            status_t status = attributes.readFromParcel(&data);
+            if (status != NO_ERROR) {
+                return status;
+            }
+            product_strategy_t strategy;
+            status = getProductStrategyFromAudioAttributes(attributes, strategy);
+            reply->writeInt32(status);
+            if (status != NO_ERROR) {
+                return NO_ERROR;
+            }
+            reply->writeUint32(static_cast<int>(strategy));
+            return NO_ERROR;
+        }
+
+        case LIST_AUDIO_VOLUME_GROUPS: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            AudioVolumeGroupVector groups;
+            status_t status = listAudioVolumeGroups(groups);
+            reply->writeInt32(status);
+            if (status != NO_ERROR) {
+                return NO_ERROR;
+            }
+            size_t size = groups.size();
+            size_t sizePosition = reply->dataPosition();
+            reply->writeInt32(size);
+            size_t finalSize = size;
+            for (size_t i = 0; i < size; i++) {
+                size_t position = reply->dataPosition();
+                if (groups[i].writeToParcel(reply) != NO_ERROR) {
+                    reply->setDataPosition(position);
+                    finalSize--;
+                }
+            }
+            if (size != finalSize) {
+                size_t position = reply->dataPosition();
+                reply->setDataPosition(sizePosition);
+                reply->writeInt32(finalSize);
+                reply->setDataPosition(position);
+            }
+            return NO_ERROR;
+        }
+
+        case GET_VOLUME_GROUP_FOR_ATTRIBUTES: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            AudioAttributes attributes;
+            status_t status = attributes.readFromParcel(&data);
+            if (status != NO_ERROR) {
+                return status;
+            }
+            volume_group_t group;
+            status = getVolumeGroupFromAudioAttributes(attributes, group);
+            reply->writeInt32(status);
+            if (status != NO_ERROR) {
+                return NO_ERROR;
+            }
+            reply->writeUint32(static_cast<int>(group));
+            return NO_ERROR;
+        }
+
+        case SET_ALLOWED_CAPTURE_POLICY: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            uid_t uid = data.readInt32();
+            audio_flags_mask_t flags = data.readInt32();
+            status_t status = setAllowedCapturePolicy(uid, flags);
+            reply->writeInt32(status);
+            return NO_ERROR;
+        }
+
+        case SET_RTT_ENABLED: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            bool enabled = static_cast<bool>(data.readInt32());
+            status_t status = setRttEnabled(enabled);
+            reply->writeInt32(status);
+            return NO_ERROR;
+        }
+
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/media/libaudioclient/IAudioPolicyServiceClient.cpp b/media/libaudioclient/IAudioPolicyServiceClient.cpp
index ad7f1de..0f9580c 100644
--- a/media/libaudioclient/IAudioPolicyServiceClient.cpp
+++ b/media/libaudioclient/IAudioPolicyServiceClient.cpp
@@ -31,7 +31,8 @@
     PORT_LIST_UPDATE = IBinder::FIRST_CALL_TRANSACTION,
     PATCH_LIST_UPDATE,
     MIX_STATE_UPDATE,
-    RECORDING_CONFIGURATION_UPDATE
+    RECORDING_CONFIGURATION_UPDATE,
+    VOLUME_GROUP_CHANGED,
 };
 
 // ----------------------------------------------------------------------
@@ -49,15 +50,42 @@
 }
 
 inline void readRecordClientInfoFromParcel(const Parcel& data, record_client_info_t *clientInfo) {
+    clientInfo->riid = (audio_unique_id_t) data.readInt32();
     clientInfo->uid = (uid_t) data.readUint32();
     clientInfo->session = (audio_session_t) data.readInt32();
     clientInfo->source = (audio_source_t) data.readInt32();
+    data.read(&clientInfo->port_id, sizeof(audio_port_handle_t));
+    clientInfo->silenced = data.readBool();
 }
 
-inline void writeRecordClientInfoFromParcel(Parcel& data, const record_client_info_t *clientInfo) {
+inline void writeRecordClientInfoToParcel(Parcel& data, const record_client_info_t *clientInfo) {
+    data.writeInt32((int32_t) clientInfo->riid);
     data.writeUint32((uint32_t) clientInfo->uid);
     data.writeInt32((int32_t) clientInfo->session);
     data.writeInt32((int32_t) clientInfo->source);
+    data.write(&clientInfo->port_id, sizeof(audio_port_handle_t));
+    data.writeBool(clientInfo->silenced);
+}
+
+inline void readEffectVectorFromParcel(const Parcel& data,
+                                       std::vector<effect_descriptor_t> *effects) {
+    int32_t numEffects = data.readInt32();
+    for (int32_t i = 0; i < numEffects; i++) {
+        effect_descriptor_t effect;
+        if (data.read(&effect, sizeof(effect_descriptor_t)) != NO_ERROR) {
+            break;
+        }
+        (*effects).push_back(effect);
+    }
+}
+
+inline void writeEffectVectorToParcel(Parcel& data, std::vector<effect_descriptor_t> effects) {
+    data.writeUint32((uint32_t) effects.size());
+    for (const auto& effect : effects) {
+        if (data.write(&effect, sizeof(effect_descriptor_t)) != NO_ERROR) {
+            break;
+        }
+    }
 }
 
 // ----------------------------------------------------------------------
@@ -83,6 +111,15 @@
         remote()->transact(PATCH_LIST_UPDATE, data, &reply, IBinder::FLAG_ONEWAY);
     }
 
+    void onAudioVolumeGroupChanged(volume_group_t group, int flags)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyServiceClient::getInterfaceDescriptor());
+        data.writeUint32(group);
+        data.writeInt32(flags);
+        remote()->transact(VOLUME_GROUP_CHANGED, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+
     void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state)
     {
         Parcel data, reply;
@@ -92,16 +129,24 @@
         remote()->transact(MIX_STATE_UPDATE, data, &reply, IBinder::FLAG_ONEWAY);
     }
 
-    void onRecordingConfigurationUpdate(int event, const record_client_info_t *clientInfo,
-            const audio_config_base_t *clientConfig,
-            const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle) {
+    void onRecordingConfigurationUpdate(int event,
+                                        const record_client_info_t *clientInfo,
+                                        const audio_config_base_t *clientConfig,
+                                        std::vector<effect_descriptor_t> clientEffects,
+                                        const audio_config_base_t *deviceConfig,
+                                        std::vector<effect_descriptor_t> effects,
+                                        audio_patch_handle_t patchHandle,
+                                        audio_source_t source) {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioPolicyServiceClient::getInterfaceDescriptor());
         data.writeInt32(event);
-        writeRecordClientInfoFromParcel(data, clientInfo);
+        writeRecordClientInfoToParcel(data, clientInfo);
         writeAudioConfigBaseToParcel(data, clientConfig);
+        writeEffectVectorToParcel(data, clientEffects);
         writeAudioConfigBaseToParcel(data, deviceConfig);
+        writeEffectVectorToParcel(data, effects);
         data.writeInt32(patchHandle);
+        data.writeInt32((int32_t) source);
         remote()->transact(RECORDING_CONFIGURATION_UPDATE, data, &reply, IBinder::FLAG_ONEWAY);
     }
 };
@@ -124,6 +169,13 @@
             onAudioPatchListUpdate();
             return NO_ERROR;
         } break;
+    case VOLUME_GROUP_CHANGED: {
+            CHECK_INTERFACE(IAudioPolicyServiceClient, data, reply);
+            volume_group_t group = static_cast<volume_group_t>(data.readUint32());
+            int flags = data.readInt32();
+            onAudioVolumeGroupChanged(group, flags);
+            return NO_ERROR;
+        } break;
     case MIX_STATE_UPDATE: {
             CHECK_INTERFACE(IAudioPolicyServiceClient, data, reply);
             String8 regId = data.readString8();
@@ -139,10 +191,15 @@
             audio_config_base_t deviceConfig;
             readRecordClientInfoFromParcel(data, &clientInfo);
             readAudioConfigBaseFromParcel(data, &clientConfig);
+            std::vector<effect_descriptor_t> clientEffects;
+            readEffectVectorFromParcel(data, &clientEffects);
             readAudioConfigBaseFromParcel(data, &deviceConfig);
+            std::vector<effect_descriptor_t> effects;
+            readEffectVectorFromParcel(data, &effects);
             audio_patch_handle_t patchHandle = (audio_patch_handle_t) data.readInt32();
-            onRecordingConfigurationUpdate(event, &clientInfo, &clientConfig, &deviceConfig,
-                    patchHandle);
+            audio_source_t source = (audio_source_t) data.readInt32();
+            onRecordingConfigurationUpdate(event, &clientInfo, &clientConfig, clientEffects,
+                                           &deviceConfig, effects, patchHandle, source);
             return NO_ERROR;
         } break;
     default:
diff --git a/media/libaudioclient/IAudioTrack.cpp b/media/libaudioclient/IAudioTrack.cpp
index adff057..83a568a 100644
--- a/media/libaudioclient/IAudioTrack.cpp
+++ b/media/libaudioclient/IAudioTrack.cpp
@@ -39,6 +39,7 @@
     PAUSE,
     ATTACH_AUX_EFFECT,
     SET_PARAMETERS,
+    SELECT_PRESENTATION,
     GET_TIMESTAMP,
     SIGNAL,
     APPLY_VOLUME_SHAPER,
@@ -127,6 +128,19 @@
         return status;
     }
 
+    /* Selects the presentation (if available) */
+    virtual status_t selectPresentation(int presentationId, int programId) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
+        data.writeInt32(presentationId);
+        data.writeInt32(programId);
+        status_t status = remote()->transact(SELECT_PRESENTATION, data, &reply);
+        if (status == NO_ERROR) {
+            status = reply.readInt32();
+        }
+        return status;
+    }
+
     virtual status_t getTimestamp(AudioTimestamp& timestamp) {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
@@ -239,6 +253,11 @@
             reply->writeInt32(setParameters(keyValuePairs));
             return NO_ERROR;
         } break;
+        case SELECT_PRESENTATION: {
+            CHECK_INTERFACE(IAudioTrack, data, reply);
+            reply->writeInt32(selectPresentation(data.readInt32(), data.readInt32()));
+            return NO_ERROR;
+        } break;
         case GET_TIMESTAMP: {
             CHECK_INTERFACE(IAudioTrack, data, reply);
             AudioTimestamp timestamp;
diff --git a/media/libaudioclient/RecordingActivityTracker.cpp b/media/libaudioclient/RecordingActivityTracker.cpp
new file mode 100644
index 0000000..42d4361
--- /dev/null
+++ b/media/libaudioclient/RecordingActivityTracker.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <audiomanager/AudioManager.h>
+#include <audiomanager/IAudioManager.h>
+#include <binder/Binder.h>
+#include <binder/IServiceManager.h>
+#include <media/RecordingActivityTracker.h>
+
+namespace android {
+
+RecordingActivityTracker::RecordingActivityTracker()
+        : mRIId(RECORD_RIID_INVALID), mToken(new BBinder())
+{
+    // use checkService() to avoid blocking if audio service is not up yet
+    sp<IBinder> binder = defaultServiceManager()->checkService(String16("audio"));
+    if (binder != 0) {
+        mAudioManager = interface_cast<IAudioManager>(binder);
+    } else {
+        ALOGE("RecordingActivityTracker(): binding to audio service failed, service up?");
+    }
+}
+
+RecordingActivityTracker::~RecordingActivityTracker()
+{
+    if (mRIId != RECORD_RIID_INVALID && mAudioManager) {
+        mAudioManager->releaseRecorder(mRIId);
+    }
+}
+
+audio_unique_id_t RecordingActivityTracker::getRiid()
+{
+    if (mRIId == RECORD_RIID_INVALID && mAudioManager) {
+        mRIId = mAudioManager->trackRecorder(mToken);
+    }
+    return mRIId;
+}
+
+void RecordingActivityTracker::recordingStarted()
+{
+    if (getRiid() != RECORD_RIID_INVALID && mAudioManager) {
+        mAudioManager->recorderEvent(mRIId, RECORDER_STATE_STARTED);
+    }
+}
+
+void RecordingActivityTracker::recordingStopped()
+{
+    if (getRiid() != RECORD_RIID_INVALID && mAudioManager) {
+        mAudioManager->recorderEvent(mRIId, RECORDER_STATE_STOPPED);
+    }
+}
+
+} // namespace android
diff --git a/media/libaudioclient/ToneGenerator.cpp b/media/libaudioclient/ToneGenerator.cpp
index d846d79..536b00d 100644
--- a/media/libaudioclient/ToneGenerator.cpp
+++ b/media/libaudioclient/ToneGenerator.cpp
@@ -20,7 +20,6 @@
 #include <math.h>
 #include <utils/Log.h>
 #include <cutils/properties.h>
-#include <media/AudioPolicyHelper.h>
 #include "media/ToneGenerator.h"
 
 
@@ -1176,13 +1175,13 @@
             // This is needed in case of cold start of the output stream.
             if ((mStartTime.tv_sec != 0) && (clock_gettime(CLOCK_MONOTONIC, &stopTime) == 0)) {
                 time_t sec = stopTime.tv_sec - mStartTime.tv_sec;
-                long nsec = stopTime.tv_nsec - mStartTime.tv_nsec;
+                auto nsec = stopTime.tv_nsec - mStartTime.tv_nsec;
                 if (nsec < 0) {
                     --sec;
                     nsec += 1000000000;
                 }
 
-                if ((sec + 1) > ((long)(INT_MAX / mSamplingRate))) {
+                if ((sec + 1) > ((time_t)(INT_MAX / mSamplingRate))) {
                     mMaxSmp = sec * mSamplingRate;
                 } else {
                     // mSamplingRate is always > 1000
@@ -1242,7 +1241,7 @@
     if (mStreamType == AUDIO_STREAM_VOICE_CALL) {
         streamType = AUDIO_STREAM_DTMF;
     }
-    stream_type_to_audio_attributes(streamType, &attr);
+    attr = AudioSystem::streamTypeToAttributes(streamType);
 
     const size_t frameCount = mProcessSize;
     status_t status = mpAudioTrack->set(
@@ -1297,8 +1296,8 @@
 
     AudioTrack::Buffer *buffer = static_cast<AudioTrack::Buffer *>(info);
     ToneGenerator *lpToneGen = static_cast<ToneGenerator *>(user);
-    short *lpOut = buffer->i16;
-    unsigned int lNumSmp = buffer->size/sizeof(short);
+    int16_t *lpOut = buffer->i16;
+    unsigned int lNumSmp = buffer->size/sizeof(int16_t);
     const ToneDescriptor *lpToneDesc = lpToneGen->mpToneDesc;
 
     if (buffer->size == 0) return;
@@ -1369,7 +1368,7 @@
             if (lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[0] != 0) {
                 lWaveCmd = WaveGenerator::WAVEGEN_STOP;
                 unsigned int lFreqIdx = 0;
-                unsigned short lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[lFreqIdx];
+                uint16_t lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[lFreqIdx];
 
                 while (lFrequency != 0) {
                     WaveGenerator *lpWaveGen = lpToneGen->mWaveGens.valueFor(lFrequency);
@@ -1419,16 +1418,18 @@
                         lWaveCmd = WaveGenerator::WAVEGEN_START;
                     }
 
-                    ALOGV("New segment %d, Next Time: %d", lpToneGen->mCurSegment,
-                            (lpToneGen->mNextSegSmp*1000)/lpToneGen->mSamplingRate);
+                    ALOGV("New segment %d, Next Time: %lld", lpToneGen->mCurSegment,
+                            ((long long)(lpToneGen->mNextSegSmp)*1000)/lpToneGen->mSamplingRate);
+
 
                 } else {
                     lGenSmp = 0;
                     ALOGV("End repeat, time: %d", (unsigned int)(systemTime()/1000000));
                 }
             } else {
-                ALOGV("New segment %d, Next Time: %d", lpToneGen->mCurSegment,
-                        (lpToneGen->mNextSegSmp*1000)/lpToneGen->mSamplingRate);
+                ALOGV("New segment %d, Next Time: %lld", lpToneGen->mCurSegment,
+                        ((long long)(lpToneGen->mNextSegSmp)*1000)/lpToneGen->mSamplingRate);
+
                 if (lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[0] != 0) {
                     // If next segment is not silent,  OFF -> ON transition : reset wave generator
                     lWaveCmd = WaveGenerator::WAVEGEN_START;
@@ -1455,7 +1456,7 @@
         if (lGenSmp) {
             // If samples must be generated, call all active wave generators and acumulate waves in lpOut
             unsigned int lFreqIdx = 0;
-            unsigned short lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[lFreqIdx];
+            uint16_t lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[lFreqIdx];
 
             while (lFrequency != 0) {
                 WaveGenerator *lpWaveGen = lpToneGen->mWaveGens.valueFor(lFrequency);
@@ -1694,17 +1695,17 @@
 //
 ////////////////////////////////////////////////////////////////////////////////
 ToneGenerator::WaveGenerator::WaveGenerator(uint32_t samplingRate,
-        unsigned short frequency, float volume) {
+        uint16_t frequency, float volume) {
     double d0;
     double F_div_Fs;  // frequency / samplingRate
 
     F_div_Fs = frequency / (double)samplingRate;
     d0 = - (float)GEN_AMP * sin(2 * M_PI * F_div_Fs);
-    mS2_0 = (short)d0;
+    mS2_0 = (int16_t)d0;
     mS1 = 0;
     mS2 = mS2_0;
 
-    mAmplitude_Q15 = (short)(32767. * 32767. * volume / GEN_AMP);
+    mAmplitude_Q15 = (int16_t)(32767. * 32767. * volume / GEN_AMP);
     // take some margin for amplitude fluctuation
     if (mAmplitude_Q15 > 32500)
         mAmplitude_Q15 = 32500;
@@ -1712,7 +1713,7 @@
     d0 = 32768.0 * cos(2 * M_PI * F_div_Fs);  // Q14*2*cos()
     if (d0 > 32767)
         d0 = 32767;
-    mA1_Q14 = (short) d0;
+    mA1_Q14 = (int16_t) d0;
 
     ALOGV("WaveGenerator init, mA1_Q14: %d, mS2_0: %d, mAmplitude_Q15: %d",
             mA1_Q14, mS2_0, mAmplitude_Q15);
@@ -1750,7 +1751,7 @@
 //        none
 //
 ////////////////////////////////////////////////////////////////////////////////
-void ToneGenerator::WaveGenerator::getSamples(short *outBuffer,
+void ToneGenerator::WaveGenerator::getSamples(int16_t *outBuffer,
         unsigned int count, unsigned int command) {
     long lS1, lS2;
     long lA1, lAmplitude;
@@ -1781,7 +1782,7 @@
             lS2 = lS1;
             lS1 = Sample;
             Sample = ((lAmplitude>>16) * Sample) >> S_Q15;
-            *(outBuffer++) += (short)Sample;  // put result in buffer
+            *(outBuffer++) += (int16_t)Sample;  // put result in buffer
             lAmplitude -= dec;
         }
     } else {
@@ -1793,7 +1794,7 @@
             lS2 = lS1;
             lS1 = Sample;
             Sample = (lAmplitude * Sample) >> S_Q15;
-            *(outBuffer++) += (short)Sample;  // put result in buffer
+            *(outBuffer++) += (int16_t)Sample;  // put result in buffer
         }
     }
 
diff --git a/media/libaudioclient/aidl/android/media/IAudioRecord.aidl b/media/libaudioclient/aidl/android/media/IAudioRecord.aidl
index 01e0a71..ecf58b6 100644
--- a/media/libaudioclient/aidl/android/media/IAudioRecord.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioRecord.aidl
@@ -36,4 +36,12 @@
   /* Get a list of current active microphones.
    */
   void getActiveMicrophones(out MicrophoneInfo[] activeMicrophones);
+
+  /* Set the microphone direction (for processing).
+   */
+  void setPreferredMicrophoneDirection(int /*audio_microphone_direction_t*/ direction);
+
+  /* Set the microphone zoom (for processing).
+   */
+  void setPreferredMicrophoneFieldDimension(float zoom);
 }
diff --git a/media/libaudioclient/include/media/AudioAttributes.h b/media/libaudioclient/include/media/AudioAttributes.h
new file mode 100644
index 0000000..0a35e9e
--- /dev/null
+++ b/media/libaudioclient/include/media/AudioAttributes.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#pragma once
+
+#include <media/AudioCommonTypes.h>
+#include <system/audio.h>
+#include <system/audio_policy.h>
+#include <binder/Parcelable.h>
+
+namespace android {
+
+class AudioAttributes : public Parcelable
+{
+public:
+    AudioAttributes() = default;
+    AudioAttributes(const audio_attributes_t &attributes) : mAttributes(attributes) {}
+    AudioAttributes(volume_group_t groupId,
+                    audio_stream_type_t stream,
+                    const audio_attributes_t &attributes) :
+         mAttributes(attributes), mStreamType(stream), mGroupId(groupId) {}
+
+    audio_attributes_t getAttributes() const { return mAttributes; }
+
+    status_t readFromParcel(const Parcel *parcel) override;
+    status_t writeToParcel(Parcel *parcel) const override;
+
+    audio_stream_type_t getStreamType() const { return mStreamType; }
+    volume_group_t getGroupId() const { return mGroupId; }
+
+private:
+    audio_attributes_t mAttributes = AUDIO_ATTRIBUTES_INITIALIZER;
+    /**
+     * @brief mStreamType: for legacy volume management, we need to be able to convert an attribute
+     * to a given stream type.
+     */
+    audio_stream_type_t mStreamType = AUDIO_STREAM_DEFAULT;
+
+    /**
+     * @brief mGroupId: for future volume management, define groups within a strategy that follows
+     * the same curves of volume (extension of stream types to manage volume)
+     */
+    volume_group_t mGroupId = VOLUME_GROUP_NONE;
+};
+
+} // namespace android
diff --git a/media/libaudioclient/include/media/AudioCommonTypes.h b/media/libaudioclient/include/media/AudioCommonTypes.h
new file mode 100644
index 0000000..8e446ea
--- /dev/null
+++ b/media/libaudioclient/include/media/AudioCommonTypes.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#pragma once
+
+#include <system/audio.h>
+#include <system/audio_policy.h>
+#include <binder/Parcelable.h>
+
+namespace android {
+
+enum product_strategy_t : uint32_t;
+const product_strategy_t PRODUCT_STRATEGY_NONE = static_cast<product_strategy_t>(-1);
+
+using AttributesVector = std::vector<audio_attributes_t>;
+using StreamTypeVector = std::vector<audio_stream_type_t>;
+
+constexpr bool operator==(const audio_attributes_t &lhs, const audio_attributes_t &rhs)
+{
+    return lhs.usage == rhs.usage && lhs.content_type == rhs.content_type &&
+            lhs.flags == rhs.flags && (std::strcmp(lhs.tags, rhs.tags) == 0);
+}
+constexpr bool operator!=(const audio_attributes_t &lhs, const audio_attributes_t &rhs)
+{
+    return !(lhs==rhs);
+}
+
+enum volume_group_t : uint32_t;
+static const volume_group_t VOLUME_GROUP_NONE = static_cast<volume_group_t>(-1);
+
+} // namespace android
+
diff --git a/media/libaudioclient/include/media/AudioEffect.h b/media/libaudioclient/include/media/AudioEffect.h
index bfc068b..6bd4137 100644
--- a/media/libaudioclient/include/media/AudioEffect.h
+++ b/media/libaudioclient/include/media/AudioEffect.h
@@ -90,27 +90,34 @@
      */
     static status_t queryEffect(uint32_t index, effect_descriptor_t *descriptor);
 
-
     /*
-     * Returns the descriptor for the specified effect uuid.
+     * Returns a descriptor for the specified effect uuid or type.
+     *
+     * Lookup an effect by uuid, or if that's unspecified (EFFECT_UUID_NULL),
+     * do so by type and preferred flags instead.
      *
      * Parameters:
      *      uuid:       pointer to effect uuid.
+     *      type:       pointer to effect type uuid.
+     *      preferredTypeFlags: if multiple effects of the given type exist,
+     *                  one with a matching type flag will be chosen over one without.
+     *                  Use EFFECT_FLAG_TYPE_MASK to indicate no preference.
      *      descriptor: address where the effect descriptor should be returned.
      *
      * Returned status (from utils/Errors.h) can be:
      *      NO_ERROR        successful operation.
      *      PERMISSION_DENIED could not get AudioFlinger interface
      *      NO_INIT         effect library failed to initialize
-     *      BAD_VALUE       invalid uuid or descriptor pointers
+     *      BAD_VALUE       invalid type or descriptor pointers
      *      NAME_NOT_FOUND  no effect with this uuid found
      *
      * Returned value
      *   *descriptor updated with effect descriptor
      */
     static status_t getEffectDescriptor(const effect_uuid_t *uuid,
-                                        effect_descriptor_t *descriptor) /*const*/;
-
+                                        const effect_uuid_t *type,
+                                        uint32_t preferredTypeFlag,
+                                        effect_descriptor_t *descriptor);
 
     /*
      * Returns a list of descriptors corresponding to the pre processings enabled by default
@@ -144,6 +151,132 @@
                                               uint32_t *count);
 
     /*
+     * Gets a new system-wide unique effect id.
+     *
+     * Parameters:
+     *      id: The address to return the generated id.
+     *
+     * Returned status (from utils/Errors.h) can be:
+     *      NO_ERROR        successful operation.
+     *      PERMISSION_DENIED could not get AudioFlinger interface
+     *                        or caller lacks required permissions.
+     * Returned value
+     *   *id:  The new unique system-wide effect id.
+     */
+    static status_t newEffectUniqueId(audio_unique_id_t* id);
+
+    /*
+     * Static methods for adding/removing system-wide effects.
+     */
+
+    /*
+     * Adds an effect to the list of default output effects for a given source type.
+     *
+     * If the effect is no longer available when a source of the given type
+     * is created, the system will continue without adding it.
+     *
+     * Parameters:
+     *   typeStr:  Type uuid of effect to be a default: can be null if uuidStr is specified.
+     *             This may correspond to the OpenSL ES interface implemented by this effect,
+     *             or could be some vendor-defined type.
+     *   opPackageName: The package name used for app op checks.
+     *   uuidStr:  Uuid of effect to be a default: can be null if type is specified.
+     *             This uuid corresponds to a particular implementation of an effect type.
+     *             Note if both uuidStr and typeStr are specified, typeStr is ignored.
+     *   priority: Requested priority for effect control: the priority level corresponds to the
+     *             value of priority parameter: negative values indicate lower priorities, positive
+     *             values higher priorities, 0 being the normal priority.
+     *   source:   The source this effect should be a default for.
+     *   id:       Address where the system-wide unique id of the default effect should be returned.
+     *
+     * Returned status (from utils/Errors.h) can be:
+     *      NO_ERROR        successful operation.
+     *      PERMISSION_DENIED could not get AudioFlinger interface
+     *                        or caller lacks required permissions.
+     *      NO_INIT         effect library failed to initialize.
+     *      BAD_VALUE       invalid source, type uuid or implementation uuid.
+     *      NAME_NOT_FOUND  no effect with this uuid or type found.
+     *
+     * Returned value
+     *   *id:  The system-wide unique id of the added default effect.
+     */
+    static status_t addSourceDefaultEffect(const char* typeStr,
+                                           const String16& opPackageName,
+                                           const char* uuidStr,
+                                           int32_t priority,
+                                           audio_source_t source,
+                                           audio_unique_id_t* id);
+
+    /*
+     * Adds an effect to the list of default output effects for a given stream type.
+     *
+     * If the effect is no longer available when a stream of the given type
+     * is created, the system will continue without adding it.
+     *
+     * Parameters:
+     *   typeStr:  Type uuid of effect to be a default: can be null if uuidStr is specified.
+     *             This may correspond to the OpenSL ES interface implemented by this effect,
+     *             or could be some vendor-defined type.
+     *   opPackageName: The package name used for app op checks.
+     *   uuidStr:  Uuid of effect to be a default: can be null if type is specified.
+     *             This uuid corresponds to a particular implementation of an effect type.
+     *             Note if both uuidStr and typeStr are specified, typeStr is ignored.
+     *   priority: Requested priority for effect control: the priority level corresponds to the
+     *             value of priority parameter: negative values indicate lower priorities, positive
+     *             values higher priorities, 0 being the normal priority.
+     *   usage:    The usage this effect should be a default for. Unrecognized values will be
+     *             treated as AUDIO_USAGE_UNKNOWN.
+     *   id:       Address where the system-wide unique id of the default effect should be returned.
+     *
+     * Returned status (from utils/Errors.h) can be:
+     *      NO_ERROR        successful operation.
+     *      PERMISSION_DENIED could not get AudioFlinger interface
+     *                        or caller lacks required permissions.
+     *      NO_INIT         effect library failed to initialize.
+     *      BAD_VALUE       invalid type uuid or implementation uuid.
+     *      NAME_NOT_FOUND  no effect with this uuid or type found.
+     *
+     * Returned value
+     *   *id:  The system-wide unique id of the added default effect.
+     */
+    static status_t addStreamDefaultEffect(const char* typeStr,
+                                           const String16& opPackageName,
+                                           const char* uuidStr,
+                                           int32_t priority,
+                                           audio_usage_t usage,
+                                           audio_unique_id_t* id);
+
+    /*
+     * Removes an effect from the list of default output effects for a given source type.
+     *
+     * Parameters:
+     *      id: The system-wide unique id of the effect that should no longer be a default.
+     *
+     * Returned status (from utils/Errors.h) can be:
+     *      NO_ERROR        successful operation.
+     *      PERMISSION_DENIED could not get AudioFlinger interface
+     *                        or caller lacks required permissions.
+     *      NO_INIT         effect library failed to initialize.
+     *      BAD_VALUE       invalid id.
+     */
+    static status_t removeSourceDefaultEffect(audio_unique_id_t id);
+
+    /*
+     * Removes an effect from the list of default output effects for a given stream type.
+     *
+     * Parameters:
+     *      id: The system-wide unique id of the effect that should no longer be a default.
+     *
+     * Returned status (from utils/Errors.h) can be:
+     *      NO_ERROR        successful operation.
+     *      PERMISSION_DENIED could not get AudioFlinger interface
+     *                        or caller lacks required permissions.
+     *      NO_INIT         effect library failed to initialize.
+     *      BAD_VALUE       invalid id.
+     */
+    static status_t removeStreamDefaultEffect(audio_unique_id_t id);
+
+    /*
      * Events used by callback function (effect_callback_t).
      */
     enum event_type {
@@ -414,6 +547,7 @@
      effect_descriptor_t     mDescriptor;        // effect descriptor
      int32_t                 mId;                // system wide unique effect engine instance ID
      Mutex                   mLock;              // Mutex for mEnabled access
+     Mutex                   mConstructLock;     // Mutex for integrality construction
 
      String16                mOpPackageName;     // The package name used for app op checks.
 
@@ -440,12 +574,22 @@
         virtual void controlStatusChanged(bool controlGranted) {
             sp<AudioEffect> effect = mEffect.promote();
             if (effect != 0) {
+                {
+                    // Got the mConstructLock means the construction of AudioEffect
+                    // has finished, we should release the mConstructLock immediately.
+                    AutoMutex lock(effect->mConstructLock);
+                }
                 effect->controlStatusChanged(controlGranted);
             }
         }
         virtual void enableStatusChanged(bool enabled) {
             sp<AudioEffect> effect = mEffect.promote();
             if (effect != 0) {
+                {
+                    // Got the mConstructLock means the construction of AudioEffect
+                    // has finished, we should release the mConstructLock immediately.
+                    AutoMutex lock(effect->mConstructLock);
+                }
                 effect->enableStatusChanged(enabled);
             }
         }
@@ -456,6 +600,11 @@
                                      void *pReplyData) {
             sp<AudioEffect> effect = mEffect.promote();
             if (effect != 0) {
+                {
+                    // Got the mConstructLock means the construction of AudioEffect
+                    // has finished, we should release the mConstructLock immediately.
+                    AutoMutex lock(effect->mConstructLock);
+                }
                 effect->commandExecuted(
                     cmdCode, cmdSize, pCmdData, replySize, pReplyData);
             }
@@ -465,6 +614,11 @@
         virtual void binderDied(const wp<IBinder>& /*who*/) {
             sp<AudioEffect> effect = mEffect.promote();
             if (effect != 0) {
+                {
+                    // Got the mConstructLock means the construction of AudioEffect
+                    // has finished, we should release the mConstructLock immediately.
+                    AutoMutex lock(effect->mConstructLock);
+                }
                 effect->binderDied();
             }
         }
diff --git a/media/libaudioclient/include/media/AudioIoDescriptor.h b/media/libaudioclient/include/media/AudioIoDescriptor.h
index 859f1a9..981d33a 100644
--- a/media/libaudioclient/include/media/AudioIoDescriptor.h
+++ b/media/libaudioclient/include/media/AudioIoDescriptor.h
@@ -28,6 +28,7 @@
     AUDIO_INPUT_OPENED,
     AUDIO_INPUT_CLOSED,
     AUDIO_INPUT_CONFIG_CHANGED,
+    AUDIO_CLIENT_STARTED,
 };
 
 // audio input/output descriptor used to cache output configurations in client process to avoid
@@ -37,7 +38,7 @@
     AudioIoDescriptor() :
         mIoHandle(AUDIO_IO_HANDLE_NONE),
         mSamplingRate(0), mFormat(AUDIO_FORMAT_DEFAULT), mChannelMask(AUDIO_CHANNEL_NONE),
-        mFrameCount(0), mFrameCountHAL(0), mLatency(0)
+        mFrameCount(0), mFrameCountHAL(0), mLatency(0), mPortId(AUDIO_PORT_HANDLE_NONE)
     {
         memset(&mPatch, 0, sizeof(struct audio_patch));
     }
@@ -66,6 +67,7 @@
     size_t                  mFrameCount;
     size_t                  mFrameCountHAL;
     uint32_t                mLatency;   // only valid for output
+    audio_port_handle_t     mPortId;    // valid for event AUDIO_CLIENT_STARTED
 };
 
 
diff --git a/media/libaudioclient/include/media/AudioMixer.h b/media/libaudioclient/include/media/AudioMixer.h
index cf7d90f..783eef3 100644
--- a/media/libaudioclient/include/media/AudioMixer.h
+++ b/media/libaudioclient/include/media/AudioMixer.h
@@ -18,17 +18,19 @@
 #ifndef ANDROID_AUDIO_MIXER_H
 #define ANDROID_AUDIO_MIXER_H
 
+#include <map>
 #include <pthread.h>
 #include <sstream>
 #include <stdint.h>
 #include <sys/types.h>
 #include <unordered_map>
+#include <vector>
 
+#include <android/os/IExternalVibratorService.h>
 #include <media/AudioBufferProvider.h>
 #include <media/AudioResampler.h>
 #include <media/AudioResamplerPublic.h>
 #include <media/BufferProviders.h>
-#include <media/nblog/NBLog.h>
 #include <system/audio.h>
 #include <utils/Compat.h>
 #include <utils/threads.h>
@@ -41,6 +43,10 @@
 
 namespace android {
 
+namespace NBLog {
+class Writer;
+}   // namespace NBLog
+
 // ----------------------------------------------------------------------------
 
 class AudioMixer
@@ -73,6 +79,9 @@
         DOWNMIX_TYPE    = 0X4004,
         MIXER_FORMAT    = 0x4005, // AUDIO_FORMAT_PCM_(FLOAT|16_BIT)
         MIXER_CHANNEL_MASK = 0x4006, // Channel mask for mixer output
+        // for haptic
+        HAPTIC_ENABLED  = 0x4007, // Set haptic data from this track should be played or not.
+        HAPTIC_INTENSITY = 0x4008, // Set the intensity to play haptic data.
         // for target RESAMPLE
         SAMPLE_RATE     = 0x4100, // Configure sample rate conversion on this track name;
                                   // parameter 'value' is the new sample rate in Hz.
@@ -95,6 +104,32 @@
                                   // parameter 'value' is a pointer to the new playback rate.
     };
 
+    typedef enum { // Haptic intensity, should keep consistent with VibratorService
+        HAPTIC_SCALE_MUTE = os::IExternalVibratorService::SCALE_MUTE,
+        HAPTIC_SCALE_VERY_LOW = os::IExternalVibratorService::SCALE_VERY_LOW,
+        HAPTIC_SCALE_LOW = os::IExternalVibratorService::SCALE_LOW,
+        HAPTIC_SCALE_NONE = os::IExternalVibratorService::SCALE_NONE,
+        HAPTIC_SCALE_HIGH = os::IExternalVibratorService::SCALE_HIGH,
+        HAPTIC_SCALE_VERY_HIGH = os::IExternalVibratorService::SCALE_VERY_HIGH,
+    } haptic_intensity_t;
+    static constexpr float HAPTIC_SCALE_VERY_LOW_RATIO = 2.0f / 3.0f;
+    static constexpr float HAPTIC_SCALE_LOW_RATIO = 3.0f / 4.0f;
+    static const constexpr float HAPTIC_MAX_AMPLITUDE_FLOAT = 1.0f;
+
+    static inline bool isValidHapticIntensity(haptic_intensity_t hapticIntensity) {
+        switch (hapticIntensity) {
+        case HAPTIC_SCALE_MUTE:
+        case HAPTIC_SCALE_VERY_LOW:
+        case HAPTIC_SCALE_LOW:
+        case HAPTIC_SCALE_NONE:
+        case HAPTIC_SCALE_HIGH:
+        case HAPTIC_SCALE_VERY_HIGH:
+            return true;
+        default:
+            return false;
+        }
+    }
+
     AudioMixer(size_t frameCount, uint32_t sampleRate)
         : mSampleRate(sampleRate)
         , mFrameCount(frameCount) {
@@ -132,7 +167,15 @@
     void        setBufferProvider(int name, AudioBufferProvider* bufferProvider);
 
     void        process() {
+        for (const auto &pair : mTracks) {
+            // Clear contracted buffer before processing if contracted channels are saved
+            const std::shared_ptr<Track> &t = pair.second;
+            if (t->mKeepContractedChannels) {
+                t->clearContractedBuffer();
+            }
+        }
         (this->*mHook)();
+        processHapticData();
     }
 
     size_t      getUnreleasedFrames(int name) const;
@@ -230,6 +273,8 @@
             mPostDownmixReformatBufferProvider.reset(nullptr);
             mDownmixerBufferProvider.reset(nullptr);
             mReformatBufferProvider.reset(nullptr);
+            mContractChannelsNonDestructiveBufferProvider.reset(nullptr);
+            mAdjustChannelsBufferProvider.reset(nullptr);
         }
 
         bool        needsRamp() { return (volumeInc[0] | volumeInc[1] | auxInc) != 0; }
@@ -244,6 +289,11 @@
         void        unprepareForDownmix();
         status_t    prepareForReformat();
         void        unprepareForReformat();
+        status_t    prepareForAdjustChannels();
+        void        unprepareForAdjustChannels();
+        status_t    prepareForAdjustChannelsNonDestructive(size_t frames);
+        void        unprepareForAdjustChannelsNonDestructive();
+        void        clearContractedBuffer();
         bool        setPlaybackRate(const AudioPlaybackRate &playbackRate);
         void        reconfigureBufferProviders();
 
@@ -297,17 +347,27 @@
          * all pre-mixer track buffer conversions outside the AudioMixer class.
          *
          * 1) mInputBufferProvider: The AudioTrack buffer provider.
-         * 2) mReformatBufferProvider: If not NULL, performs the audio reformat to
+         * 2) mAdjustChannelsBufferProvider: Expands or contracts sample data from one interleaved
+         *    channel format to another. Expanded channels are filled with zeros and put at the end
+         *    of each audio frame. Contracted channels are copied to the end of the buffer.
+         * 3) mContractChannelsNonDestructiveBufferProvider: Non-destructively contract sample data.
+         *    This is currently using at audio-haptic coupled playback to separate audio and haptic
+         *    data. Contracted channels could be written to given buffer.
+         * 4) mReformatBufferProvider: If not NULL, performs the audio reformat to
          *    match either mMixerInFormat or mDownmixRequiresFormat, if the downmixer
          *    requires reformat. For example, it may convert floating point input to
          *    PCM_16_bit if that's required by the downmixer.
-         * 3) mDownmixerBufferProvider: If not NULL, performs the channel remixing to match
+         * 5) mDownmixerBufferProvider: If not NULL, performs the channel remixing to match
          *    the number of channels required by the mixer sink.
-         * 4) mPostDownmixReformatBufferProvider: If not NULL, performs reformatting from
+         * 6) mPostDownmixReformatBufferProvider: If not NULL, performs reformatting from
          *    the downmixer requirements to the mixer engine input requirements.
-         * 5) mTimestretchBufferProvider: Adds timestretching for playback rate
+         * 7) mTimestretchBufferProvider: Adds timestretching for playback rate
          */
         AudioBufferProvider*     mInputBufferProvider;    // externally provided buffer provider.
+        // TODO: combine mAdjustChannelsBufferProvider and
+        // mContractChannelsNonDestructiveBufferProvider
+        std::unique_ptr<PassthruBufferProvider> mAdjustChannelsBufferProvider;
+        std::unique_ptr<PassthruBufferProvider> mContractChannelsNonDestructiveBufferProvider;
         std::unique_ptr<PassthruBufferProvider> mReformatBufferProvider;
         std::unique_ptr<PassthruBufferProvider> mDownmixerBufferProvider;
         std::unique_ptr<PassthruBufferProvider> mPostDownmixReformatBufferProvider;
@@ -336,6 +396,51 @@
 
         AudioPlaybackRate    mPlaybackRate;
 
+        // Haptic
+        bool                 mHapticPlaybackEnabled;
+        haptic_intensity_t   mHapticIntensity;
+        audio_channel_mask_t mHapticChannelMask;
+        uint32_t             mHapticChannelCount;
+        audio_channel_mask_t mMixerHapticChannelMask;
+        uint32_t             mMixerHapticChannelCount;
+        uint32_t             mAdjustInChannelCount;
+        uint32_t             mAdjustOutChannelCount;
+        uint32_t             mAdjustNonDestructiveInChannelCount;
+        uint32_t             mAdjustNonDestructiveOutChannelCount;
+        bool                 mKeepContractedChannels;
+
+        float getHapticScaleGamma() const {
+        // Need to keep consistent with the value in VibratorService.
+        switch (mHapticIntensity) {
+        case HAPTIC_SCALE_VERY_LOW:
+            return 2.0f;
+        case HAPTIC_SCALE_LOW:
+            return 1.5f;
+        case HAPTIC_SCALE_HIGH:
+            return 0.5f;
+        case HAPTIC_SCALE_VERY_HIGH:
+            return 0.25f;
+        default:
+            return 1.0f;
+        }
+        }
+
+        float getHapticMaxAmplitudeRatio() const {
+        // Need to keep consistent with the value in VibratorService.
+        switch (mHapticIntensity) {
+        case HAPTIC_SCALE_VERY_LOW:
+            return HAPTIC_SCALE_VERY_LOW_RATIO;
+        case HAPTIC_SCALE_LOW:
+            return HAPTIC_SCALE_LOW_RATIO;
+        case HAPTIC_SCALE_NONE:
+        case HAPTIC_SCALE_HIGH:
+        case HAPTIC_SCALE_VERY_HIGH:
+            return 1.0f;
+        default:
+            return 0.0f;
+        }
+        }
+
     private:
         // hooks
         void track__genericResample(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
@@ -372,6 +477,8 @@
     template <int MIXTYPE, typename TO, typename TI, typename TA>
     void process__noResampleOneTrack();
 
+    void processHapticData();
+
     static process_hook_t getProcessHook(int processType, uint32_t channelCount,
             audio_format_t mixerInFormat, audio_format_t mixerOutFormat);
 
diff --git a/media/libaudioclient/include/media/AudioParameter.h b/media/libaudioclient/include/media/AudioParameter.h
index 967d895..24837e3 100644
--- a/media/libaudioclient/include/media/AudioParameter.h
+++ b/media/libaudioclient/include/media/AudioParameter.h
@@ -64,6 +64,9 @@
     static const char * const keyPresentationId;
     static const char * const keyProgramId;
 
+    //  keyAudioLanguagePreferred: Preferred audio language
+    static const char * const keyAudioLanguagePreferred;
+
     //  keyStreamConnect / Disconnect: value is an int in audio_devices_t
     static const char * const keyStreamConnect;
     static const char * const keyStreamDisconnect;
diff --git a/media/libaudioclient/include/media/AudioPolicy.h b/media/libaudioclient/include/media/AudioPolicy.h
index 8da0069..ef39fd1 100644
--- a/media/libaudioclient/include/media/AudioPolicy.h
+++ b/media/libaudioclient/include/media/AudioPolicy.h
@@ -49,13 +49,30 @@
 #define MIX_STATE_IDLE 0
 #define MIX_STATE_MIXING 1
 
+/** Control to which device some audio is rendered */
 #define MIX_ROUTE_FLAG_RENDER 0x1
+/** Loop back some audio instead of rendering it */
 #define MIX_ROUTE_FLAG_LOOP_BACK (0x1 << 1)
+/** Loop back some audio while it is rendered */
+#define MIX_ROUTE_FLAG_LOOP_BACK_AND_RENDER (MIX_ROUTE_FLAG_RENDER | MIX_ROUTE_FLAG_LOOP_BACK)
 #define MIX_ROUTE_FLAG_ALL (MIX_ROUTE_FLAG_RENDER | MIX_ROUTE_FLAG_LOOP_BACK)
 
 #define MAX_MIXES_PER_POLICY 10
 #define MAX_CRITERIA_PER_MIX 20
 
+class AudioDeviceTypeAddr {
+public:
+    AudioDeviceTypeAddr() {}
+    AudioDeviceTypeAddr(audio_devices_t type, String8 address) :
+        mType(type), mAddress(address) {}
+
+    status_t readFromParcel(Parcel *parcel);
+    status_t writeToParcel(Parcel *parcel) const;
+
+    audio_devices_t mType;
+    String8 mAddress;
+};
+
 class AudioMixMatchCriterion {
 public:
     AudioMixMatchCriterion() {}
@@ -87,21 +104,37 @@
     status_t readFromParcel(Parcel *parcel);
     status_t writeToParcel(Parcel *parcel) const;
 
-    Vector<AudioMixMatchCriterion> mCriteria;
+    void setExcludeUid(uid_t uid) const;
+    void setMatchUid(uid_t uid) const;
+    /** returns true if this mix has a rule to match or exclude the given uid */
+    bool hasUidRule(bool match, uid_t uid) const;
+    /** returns true if this mix has a rule for uid match (any uid) */
+    bool hasMatchUidRule() const;
+    /** returns true if this mix can be used for uid-device affinity routing */
+    bool isDeviceAffinityCompatible() const;
+
+    mutable Vector<AudioMixMatchCriterion> mCriteria;
     uint32_t        mMixType;
     audio_config_t  mFormat;
     uint32_t        mRouteFlags;
     audio_devices_t mDeviceType;
     String8         mDeviceAddress;
     uint32_t        mCbFlags; // flags indicating which callbacks to use, see kCbFlag*
+    /** Ignore the AUDIO_FLAG_NO_MEDIA_PROJECTION */
+    bool            mAllowPrivilegedPlaybackCapture = false;
 };
 
 
-// definitions for audio recording configuration updates
-// which update type is reported
-#define RECORD_CONFIG_EVENT_NONE -1
-#define RECORD_CONFIG_EVENT_START 1
-#define RECORD_CONFIG_EVENT_STOP  0
+// definitions for audio recording configuration updates;
+// keep in sync with AudioManager.java for values used from native code
+#define RECORD_CONFIG_EVENT_START  0
+#define RECORD_CONFIG_EVENT_STOP   1
+#define RECORD_CONFIG_EVENT_UPDATE 2
+
+static inline bool is_mix_loopback_render(uint32_t routeFlags) {
+    return (routeFlags & MIX_ROUTE_FLAG_LOOP_BACK_AND_RENDER)
+           == MIX_ROUTE_FLAG_LOOP_BACK_AND_RENDER;
+}
 
 }; // namespace android
 
diff --git a/media/libaudioclient/include/media/AudioPolicyHelper.h b/media/libaudioclient/include/media/AudioPolicyHelper.h
deleted file mode 100644
index 73ee0a7..0000000
--- a/media/libaudioclient/include/media/AudioPolicyHelper.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef AUDIO_POLICY_HELPER_H_
-#define AUDIO_POLICY_HELPER_H_
-
-#include <system/audio.h>
-
-static inline
-audio_stream_type_t audio_attributes_to_stream_type(const audio_attributes_t *attr)
-{
-    // flags to stream type mapping
-    if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
-        return AUDIO_STREAM_ENFORCED_AUDIBLE;
-    }
-    if ((attr->flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) {
-        return AUDIO_STREAM_BLUETOOTH_SCO;
-    }
-
-    // usage to stream type mapping
-    switch (attr->usage) {
-    case AUDIO_USAGE_MEDIA:
-    case AUDIO_USAGE_GAME:
-    case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
-    case AUDIO_USAGE_ASSISTANT:
-        return AUDIO_STREAM_MUSIC;
-    case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
-        return AUDIO_STREAM_ACCESSIBILITY;
-    case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
-        return AUDIO_STREAM_SYSTEM;
-    case AUDIO_USAGE_VOICE_COMMUNICATION:
-        return AUDIO_STREAM_VOICE_CALL;
-
-    case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
-        return AUDIO_STREAM_DTMF;
-
-    case AUDIO_USAGE_ALARM:
-        return AUDIO_STREAM_ALARM;
-    case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
-        return AUDIO_STREAM_RING;
-
-    case AUDIO_USAGE_NOTIFICATION:
-    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
-    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
-    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
-    case AUDIO_USAGE_NOTIFICATION_EVENT:
-        return AUDIO_STREAM_NOTIFICATION;
-
-    case AUDIO_USAGE_UNKNOWN:
-    default:
-        return AUDIO_STREAM_MUSIC;
-    }
-}
-
-static inline
-void stream_type_to_audio_attributes(audio_stream_type_t streamType,
-                                     audio_attributes_t *attr) {
-    memset(attr, 0, sizeof(audio_attributes_t));
-
-    switch (streamType) {
-    case AUDIO_STREAM_DEFAULT:
-    case AUDIO_STREAM_MUSIC:
-        attr->content_type = AUDIO_CONTENT_TYPE_MUSIC;
-        attr->usage = AUDIO_USAGE_MEDIA;
-        break;
-    case AUDIO_STREAM_VOICE_CALL:
-        attr->content_type = AUDIO_CONTENT_TYPE_SPEECH;
-        attr->usage = AUDIO_USAGE_VOICE_COMMUNICATION;
-        break;
-    case AUDIO_STREAM_ENFORCED_AUDIBLE:
-        attr->flags  |= AUDIO_FLAG_AUDIBILITY_ENFORCED;
-        // intended fall through, attributes in common with STREAM_SYSTEM
-    case AUDIO_STREAM_SYSTEM:
-        attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
-        attr->usage = AUDIO_USAGE_ASSISTANCE_SONIFICATION;
-        break;
-    case AUDIO_STREAM_RING:
-        attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
-        attr->usage = AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
-        break;
-    case AUDIO_STREAM_ALARM:
-        attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
-        attr->usage = AUDIO_USAGE_ALARM;
-        break;
-    case AUDIO_STREAM_NOTIFICATION:
-        attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
-        attr->usage = AUDIO_USAGE_NOTIFICATION;
-        break;
-    case AUDIO_STREAM_BLUETOOTH_SCO:
-        attr->content_type = AUDIO_CONTENT_TYPE_SPEECH;
-        attr->usage = AUDIO_USAGE_VOICE_COMMUNICATION;
-        attr->flags |= AUDIO_FLAG_SCO;
-        break;
-    case AUDIO_STREAM_DTMF:
-        attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
-        attr->usage = AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING;
-        break;
-    case AUDIO_STREAM_TTS:
-        attr->content_type = AUDIO_CONTENT_TYPE_SPEECH;
-        attr->usage = AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY;
-        break;
-    default:
-        ALOGE("invalid stream type %d when converting to attributes", streamType);
-    }
-}
-
-#endif //AUDIO_POLICY_HELPER_H_
diff --git a/media/libaudioclient/include/media/AudioProductStrategy.h b/media/libaudioclient/include/media/AudioProductStrategy.h
new file mode 100644
index 0000000..7441095
--- /dev/null
+++ b/media/libaudioclient/include/media/AudioProductStrategy.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#pragma once
+
+#include <media/AudioCommonTypes.h>
+#include <media/AudioAttributes.h>
+#include <system/audio.h>
+#include <system/audio_policy.h>
+#include <binder/Parcelable.h>
+
+namespace android {
+
+class AudioProductStrategy : public Parcelable
+{
+public:
+    AudioProductStrategy() {}
+    AudioProductStrategy(const std::string &name, const std::vector<AudioAttributes> &attributes,
+                         product_strategy_t id) :
+        mName(name), mAudioAttributes(attributes), mId(id) {}
+
+    const std::string &getName() const { return mName; }
+    std::vector<AudioAttributes> getAudioAttributes() const { return mAudioAttributes; }
+    product_strategy_t getId() const { return mId; }
+
+    status_t readFromParcel(const Parcel *parcel) override;
+    status_t writeToParcel(Parcel *parcel) const override;
+
+    /**
+     * @brief attributesMatches: checks if client attributes matches with a reference attributes
+     * "matching" means the usage shall match if reference attributes has a defined usage, AND
+     * content type shall match if reference attributes has a defined content type AND
+     * flags shall match if reference attributes has defined flags AND
+     * tags shall match if reference attributes has defined tags.
+     * Reference attributes "default" shall not be considered as a "true" case. This convention
+     * is used to identify the default strategy.
+     * @param refAttributes to be considered
+     * @param clientAttritubes to be considered
+     * @return true if matching, false otherwise
+     */
+    static bool attributesMatches(const audio_attributes_t refAttributes,
+                                  const audio_attributes_t clientAttritubes);
+private:
+    std::string mName;
+    std::vector<AudioAttributes> mAudioAttributes;
+    product_strategy_t mId;
+};
+
+using AudioProductStrategyVector = std::vector<AudioProductStrategy>;
+
+} // namespace android
+
diff --git a/media/libaudioclient/include/media/AudioRecord.h b/media/libaudioclient/include/media/AudioRecord.h
index cf446a5..a3c0fe4 100644
--- a/media/libaudioclient/include/media/AudioRecord.h
+++ b/media/libaudioclient/include/media/AudioRecord.h
@@ -17,6 +17,9 @@
 #ifndef ANDROID_AUDIORECORD_H
 #define ANDROID_AUDIORECORD_H
 
+#include <memory>
+#include <vector>
+
 #include <binder/IMemory.h>
 #include <cutils/sched_policy.h>
 #include <media/AudioSystem.h>
@@ -24,9 +27,9 @@
 #include <media/MediaAnalyticsItem.h>
 #include <media/Modulo.h>
 #include <media/MicrophoneInfo.h>
+#include <media/RecordingActivityTracker.h>
 #include <utils/RefBase.h>
 #include <utils/threads.h>
-#include <vector>
 
 #include "android/media/IAudioRecord.h"
 
@@ -85,7 +88,7 @@
 
         union {
             void*       raw;
-            short*      i16;        // signed 16-bit
+            int16_t*    i16;        // signed 16-bit
             int8_t*     i8;         // unsigned 8-bit, offset by 0x80
                                     // input to obtainBuffer(): unused, output: pointer to buffer
         };
@@ -189,7 +192,10 @@
                                     uid_t uid = AUDIO_UID_INVALID,
                                     pid_t pid = -1,
                                     const audio_attributes_t* pAttributes = NULL,
-                                    audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE);
+                                    audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE,
+                                    audio_microphone_direction_t
+                                        selectedMicDirection = MIC_DIRECTION_UNSPECIFIED,
+                                    float selectedMicFieldDimension = MIC_FIELD_DIMENSION_DEFAULT);
 
     /* Terminates the AudioRecord and unregisters it from AudioFlinger.
      * Also destroys all resources associated with the AudioRecord.
@@ -228,7 +234,10 @@
                             uid_t uid = AUDIO_UID_INVALID,
                             pid_t pid = -1,
                             const audio_attributes_t* pAttributes = NULL,
-                            audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE);
+                            audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE,
+                            audio_microphone_direction_t
+                                selectedMicDirection = MIC_DIRECTION_UNSPECIFIED,
+                            float selectedMicFieldDimension = MIC_FIELD_DIMENSION_DEFAULT);
 
     /* Result of constructing the AudioRecord. This must be checked for successful initialization
      * before using any AudioRecord API (except for set()), because using
@@ -534,9 +543,23 @@
      */
             status_t    getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones);
 
-    /*
-     * Dumps the state of an audio record.
+    /* Set the Microphone direction (for processing purposes).
      */
+            status_t    setPreferredMicrophoneDirection(audio_microphone_direction_t direction);
+
+    /* Set the Microphone zoom factor (for processing purposes).
+     */
+            status_t    setPreferredMicrophoneFieldDimension(float zoom);
+
+     /* Get the unique port ID assigned to this AudioRecord instance by audio policy manager.
+      * The ID is unique across all audioserver clients and can change during the life cycle
+      * of a given AudioRecord instance if the connection to audioserver is restored.
+      */
+            audio_port_handle_t getPortId() const { return mPortId; };
+
+     /*
+      * Dumps the state of an audio record.
+      */
             status_t    dump(int fd, const Vector<String16>& args) const;
 
 private:
@@ -548,7 +571,7 @@
     class AudioRecordThread : public Thread
     {
     public:
-        AudioRecordThread(AudioRecord& receiver, bool bCanCallJava = false);
+        AudioRecordThread(AudioRecord& receiver);
 
         // Do not call Thread::requestExitAndWait() without first calling requestExit().
         // Thread::requestExitAndWait() is not virtual, and the implementation doesn't do enough.
@@ -598,6 +621,8 @@
     sp<AudioRecordThread>   mAudioRecordThread;
     mutable Mutex           mLock;
 
+    std::unique_ptr<RecordingActivityTracker> mTracker;
+
     // Current client state:  false = stopped, true = active.  Protected by mLock.  If more states
     // are added, consider changing this to enum State { ... } mState as in AudioTrack.
     bool                    mActive;
@@ -654,6 +679,7 @@
     audio_input_flags_t     mOrigFlags;             // as specified in constructor or set(), const
 
     audio_session_t         mSessionId;
+    audio_port_handle_t     mPortId;                    // Id from Audio Policy Manager
     transfer_type           mTransfer;
 
     // Next 5 fields may be changed if IAudioRecord is re-created, but always != 0
@@ -662,7 +688,7 @@
     sp<IMemory>             mCblkMemory;
     audio_track_cblk_t*     mCblk;              // re-load after mLock.unlock()
     sp<IMemory>             mBufferMemory;
-    audio_io_handle_t       mInput;             // returned by AudioSystem::getInput()
+    audio_io_handle_t       mInput = AUDIO_IO_HANDLE_NONE; // from AudioSystem::getInputforAttr()
 
     int                     mPreviousPriority;  // before start()
     SchedPolicy             mPreviousSchedulingGroup;
@@ -701,10 +727,13 @@
                                               // activity and connected devices
     wp<AudioSystem::AudioDeviceCallback> mDeviceCallback;
 
+    audio_microphone_direction_t mSelectedMicDirection;
+    float mSelectedMicFieldDimension;
+
 private:
     class MediaMetrics {
       public:
-        MediaMetrics() : mAnalyticsItem(new MediaAnalyticsItem("audiorecord")),
+        MediaMetrics() : mAnalyticsItem(MediaAnalyticsItem::create("audiorecord")),
                          mCreatedNs(systemTime(SYSTEM_TIME_REALTIME)),
                          mStartedNs(0), mDurationNs(0), mCount(0),
                          mLastError(NO_ERROR) {
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 4c0f796..09e80b2 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -20,6 +20,8 @@
 #include <sys/types.h>
 
 #include <media/AudioPolicy.h>
+#include <media/AudioProductStrategy.h>
+#include <media/AudioVolumeGroup.h>
 #include <media/AudioIoDescriptor.h>
 #include <media/IAudioFlingerClient.h>
 #include <media/IAudioPolicyServiceClient.h>
@@ -35,9 +37,14 @@
 
 typedef void (*audio_error_callback)(status_t err);
 typedef void (*dynamic_policy_callback)(int event, String8 regId, int val);
-typedef void (*record_config_callback)(int event, const record_client_info_t *clientInfo,
-                const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
-                audio_patch_handle_t patchHandle);
+typedef void (*record_config_callback)(int event,
+                                       const record_client_info_t *clientInfo,
+                                       const audio_config_base_t *clientConfig,
+                                       std::vector<effect_descriptor_t> clientEffects,
+                                       const audio_config_base_t *deviceConfig,
+                                       std::vector<effect_descriptor_t> effects,
+                                       audio_patch_handle_t patchHandle,
+                                       audio_source_t source);
 
 class IAudioFlinger;
 class IAudioPolicyService;
@@ -204,17 +211,19 @@
     // IAudioPolicyService interface (see AudioPolicyInterface for method descriptions)
     //
     static status_t setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state,
-                                             const char *device_address, const char *device_name);
+                                             const char *device_address, const char *device_name,
+                                             audio_format_t encodedFormat);
     static audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
                                                                 const char *device_address);
     static status_t handleDeviceConfigChange(audio_devices_t device,
                                              const char *device_address,
-                                             const char *device_name);
+                                             const char *device_name,
+                                             audio_format_t encodedFormat);
     static status_t setPhoneState(audio_mode_t state);
     static status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
     static audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage);
 
-    static status_t getOutputForAttr(const audio_attributes_t *attr,
+    static status_t getOutputForAttr(audio_attributes_t *attr,
                                      audio_io_handle_t *output,
                                      audio_session_t session,
                                      audio_stream_type_t *stream,
@@ -223,21 +232,17 @@
                                      const audio_config_t *config,
                                      audio_output_flags_t flags,
                                      audio_port_handle_t *selectedDeviceId,
-                                     audio_port_handle_t *portId);
-    static status_t startOutput(audio_io_handle_t output,
-                                audio_stream_type_t stream,
-                                audio_session_t session);
-    static status_t stopOutput(audio_io_handle_t output,
-                               audio_stream_type_t stream,
-                               audio_session_t session);
-    static void releaseOutput(audio_io_handle_t output,
-                              audio_stream_type_t stream,
-                              audio_session_t session);
+                                     audio_port_handle_t *portId,
+                                     std::vector<audio_io_handle_t> *secondaryOutputs);
+    static status_t startOutput(audio_port_handle_t portId);
+    static status_t stopOutput(audio_port_handle_t portId);
+    static void releaseOutput(audio_port_handle_t portId);
 
     // Client must successfully hand off the handle reference to AudioFlinger via createRecord(),
     // or release it with releaseInput().
     static status_t getInputForAttr(const audio_attributes_t *attr,
                                     audio_io_handle_t *input,
+                                    audio_unique_id_t riid,
                                     audio_session_t session,
                                     pid_t pid,
                                     uid_t uid,
@@ -247,8 +252,7 @@
                                     audio_port_handle_t *selectedDeviceId,
                                     audio_port_handle_t *portId);
 
-    static status_t startInput(audio_port_handle_t portId,
-                               bool *silenced);
+    static status_t startInput(audio_port_handle_t portId);
     static status_t stopInput(audio_port_handle_t portId);
     static void releaseInput(audio_port_handle_t portId);
     static status_t initStreamVolume(audio_stream_type_t stream,
@@ -261,6 +265,17 @@
                                          int *index,
                                          audio_devices_t device);
 
+    static status_t setVolumeIndexForAttributes(const audio_attributes_t &attr,
+                                                int index,
+                                                audio_devices_t device);
+    static status_t getVolumeIndexForAttributes(const audio_attributes_t &attr,
+                                                int &index,
+                                                audio_devices_t device);
+
+    static status_t getMaxVolumeIndexForAttributes(const audio_attributes_t &attr, int &index);
+
+    static status_t getMinVolumeIndexForAttributes(const audio_attributes_t &attr, int &index);
+
     static uint32_t getStrategyForStream(audio_stream_type_t stream);
     static audio_devices_t getDevicesForStream(audio_stream_type_t stream);
 
@@ -272,6 +287,7 @@
                                     int id);
     static status_t unregisterEffect(int id);
     static status_t setEffectEnabled(int id, bool enabled);
+    static status_t moveEffectsToIo(const std::vector<int>& ids, audio_io_handle_t io);
 
     // clear stream to output mapping cache (gStreamOutputMap)
     // and output configuration cache (gOutputs)
@@ -285,6 +301,8 @@
 
     static status_t setLowRamDevice(bool isLowRamDevice, int64_t totalMemory);
 
+    static status_t setAllowedCapturePolicy(uid_t uid, audio_flags_mask_t flags);
+
     // Check if hw offload is possible for given format, stream type, sample rate,
     // bit rate, duration, video and streaming or offload property is enabled
     static bool isOffloadSupported(const audio_offload_info_t& info);
@@ -327,19 +345,29 @@
 
     static status_t registerPolicyMixes(const Vector<AudioMix>& mixes, bool registration);
 
+    static status_t setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices);
+
+    static status_t removeUidDeviceAffinities(uid_t uid);
+
     static status_t startAudioSource(const struct audio_port_config *source,
-                                      const audio_attributes_t *attributes,
-                                      audio_patch_handle_t *handle);
-    static status_t stopAudioSource(audio_patch_handle_t handle);
+                                     const audio_attributes_t *attributes,
+                                     audio_port_handle_t *portId);
+    static status_t stopAudioSource(audio_port_handle_t portId);
 
     static status_t setMasterMono(bool mono);
     static status_t getMasterMono(bool *mono);
 
+    static status_t setMasterBalance(float balance);
+    static status_t getMasterBalance(float *balance);
+
     static float    getStreamVolumeDB(
             audio_stream_type_t stream, int index, audio_devices_t device);
 
     static status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
 
+    static status_t getHwOffloadEncodingFormatsSupportedForA2DP(
+                                    std::vector<audio_format_t> *formats);
+
     // numSurroundFormats holds the maximum number of formats and bool value allowed in the array.
     // When numSurroundFormats is 0, surroundFormats and surroundFormatsEnabled will not be
     // populated. The actual number of surround formats should be returned at numSurroundFormats.
@@ -349,8 +377,42 @@
                                        bool reported);
     static status_t setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled);
 
+    static status_t setAssistantUid(uid_t uid);
+    static status_t setA11yServicesUids(const std::vector<uid_t>& uids);
+
+    static bool     isHapticPlaybackSupported();
+
+    static status_t listAudioProductStrategies(AudioProductStrategyVector &strategies);
+    static status_t getProductStrategyFromAudioAttributes(const AudioAttributes &aa,
+                                                        product_strategy_t &productStrategy);
+
+    static audio_attributes_t streamTypeToAttributes(audio_stream_type_t stream);
+    static audio_stream_type_t attributesToStreamType(const audio_attributes_t &attr);
+
+    static status_t listAudioVolumeGroups(AudioVolumeGroupVector &groups);
+
+    static status_t getVolumeGroupFromAudioAttributes(const AudioAttributes &aa,
+                                                      volume_group_t &volumeGroup);
+
+    static status_t setRttEnabled(bool enabled);
+
     // ----------------------------------------------------------------------------
 
+    class AudioVolumeGroupCallback : public RefBase
+    {
+    public:
+
+        AudioVolumeGroupCallback() {}
+        virtual ~AudioVolumeGroupCallback() {}
+
+        virtual void onAudioVolumeGroupChanged(volume_group_t group, int flags) = 0;
+        virtual void onServiceDied() = 0;
+
+    };
+
+    static status_t addAudioVolumeGroupCallback(const sp<AudioVolumeGroupCallback>& callback);
+    static status_t removeAudioVolumeGroupCallback(const sp<AudioVolumeGroupCallback>& callback);
+
     class AudioPortCallback : public RefBase
     {
     public:
@@ -379,9 +441,11 @@
     };
 
     static status_t addAudioDeviceCallback(const wp<AudioDeviceCallback>& callback,
-                                           audio_io_handle_t audioIo);
+                                           audio_io_handle_t audioIo,
+                                           audio_port_handle_t portId);
     static status_t removeAudioDeviceCallback(const wp<AudioDeviceCallback>& callback,
-                                              audio_io_handle_t audioIo);
+                                              audio_io_handle_t audioIo,
+                                              audio_port_handle_t portId);
 
     static audio_port_handle_t getDeviceIdForIo(audio_io_handle_t audioIo);
 
@@ -412,17 +476,20 @@
 
 
         status_t addAudioDeviceCallback(const wp<AudioDeviceCallback>& callback,
-                                               audio_io_handle_t audioIo);
+                                               audio_io_handle_t audioIo,
+                                               audio_port_handle_t portId);
         status_t removeAudioDeviceCallback(const wp<AudioDeviceCallback>& callback,
-                                           audio_io_handle_t audioIo);
+                                           audio_io_handle_t audioIo,
+                                           audio_port_handle_t portId);
 
         audio_port_handle_t getDeviceIdForIo(audio_io_handle_t audioIo);
 
     private:
         Mutex                               mLock;
         DefaultKeyedVector<audio_io_handle_t, sp<AudioIoDescriptor> >   mIoDescriptors;
-        DefaultKeyedVector<audio_io_handle_t, Vector < wp<AudioDeviceCallback> > >
-                                                                        mAudioDeviceCallbacks;
+
+        std::map<audio_io_handle_t, std::map<audio_port_handle_t, wp<AudioDeviceCallback>>>
+                mAudioDeviceCallbacks;
         // cached values for recording getInputBufferSize() queries
         size_t                              mInBuffSize;    // zero indicates cache is invalid
         uint32_t                            mInSamplingRate;
@@ -442,21 +509,31 @@
         int removeAudioPortCallback(const sp<AudioPortCallback>& callback);
         bool isAudioPortCbEnabled() const { return (mAudioPortCallbacks.size() != 0); }
 
+        int addAudioVolumeGroupCallback(const sp<AudioVolumeGroupCallback>& callback);
+        int removeAudioVolumeGroupCallback(const sp<AudioVolumeGroupCallback>& callback);
+        bool isAudioVolumeGroupCbEnabled() const { return (mAudioVolumeGroupCallback.size() != 0); }
+
         // DeathRecipient
         virtual void binderDied(const wp<IBinder>& who);
 
         // IAudioPolicyServiceClient
         virtual void onAudioPortListUpdate();
         virtual void onAudioPatchListUpdate();
+        virtual void onAudioVolumeGroupChanged(volume_group_t group, int flags);
         virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state);
         virtual void onRecordingConfigurationUpdate(int event,
-                        const record_client_info_t *clientInfo,
-                        const audio_config_base_t *clientConfig,
-                        const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle);
+                                                    const record_client_info_t *clientInfo,
+                                                    const audio_config_base_t *clientConfig,
+                                                    std::vector<effect_descriptor_t> clientEffects,
+                                                    const audio_config_base_t *deviceConfig,
+                                                    std::vector<effect_descriptor_t> effects,
+                                                    audio_patch_handle_t patchHandle,
+                                                    audio_source_t source);
 
     private:
         Mutex                               mLock;
         Vector <sp <AudioPortCallback> >    mAudioPortCallbacks;
+        Vector <sp <AudioVolumeGroupCallback> > mAudioVolumeGroupCallback;
     };
 
     static audio_io_handle_t getOutput(audio_stream_type_t stream);
diff --git a/media/libaudioclient/include/media/AudioTimestamp.h b/media/libaudioclient/include/media/AudioTimestamp.h
index 498de8e..e5925dd 100644
--- a/media/libaudioclient/include/media/AudioTimestamp.h
+++ b/media/libaudioclient/include/media/AudioTimestamp.h
@@ -135,8 +135,23 @@
         return INVALID_OPERATION;
     }
 
+    double getOutputServerLatencyMs(uint32_t sampleRate) const {
+        return getLatencyMs(sampleRate, LOCATION_SERVER, LOCATION_KERNEL);
+    }
+
+    double getLatencyMs(uint32_t sampleRate, Location location1, Location location2) const {
+        if (sampleRate > 0 && mTimeNs[location1] > 0 && mTimeNs[location2] > 0) {
+            const int64_t frameDifference =
+                    mPosition[location1] - mPosition[location2];
+            const int64_t timeDifferenceNs =
+                    mTimeNs[location1] - mTimeNs[location2];
+            return ((double)frameDifference * 1e9 / sampleRate - timeDifferenceNs) * 1e-6;
+        }
+        return 0.;
+    }
+
     // convert fields to a printable string
-    std::string toString() {
+    std::string toString() const {
         std::stringstream ss;
 
         ss << "BOOTTIME offset " << mTimebaseOffset[TIMEBASE_BOOTTIME] << "\n";
diff --git a/media/libaudioclient/include/media/AudioTrack.h b/media/libaudioclient/include/media/AudioTrack.h
index 3eb627d..df5eabc 100644
--- a/media/libaudioclient/include/media/AudioTrack.h
+++ b/media/libaudioclient/include/media/AudioTrack.h
@@ -74,6 +74,8 @@
                                     // in the mapping from frame position to presentation time.
                                     // See AudioTimestamp for the information included with event.
 #endif
+        EVENT_CAN_WRITE_MORE_DATA = 9,// Notification that more data can be given by write()
+                                    // This event only occurs for TRANSFER_SYNC_NOTIF_CALLBACK.
     };
 
     /* Client should declare a Buffer and pass the address to obtainBuffer()
@@ -102,7 +104,7 @@
 
         union {
             void*       raw;
-            short*      i16;      // signed 16-bit
+            int16_t*    i16;      // signed 16-bit
             int8_t*     i8;       // unsigned 8-bit, offset by 0x80
         };                        // input to obtainBuffer(): unused, output: pointer to buffer
     };
@@ -145,6 +147,12 @@
                                      audio_stream_type_t streamType,
                                      uint32_t sampleRate);
 
+    /* Check if direct playback is possible for the given audio configuration and attributes.
+     * Return true if output is possible for the given parameters. Otherwise returns false.
+     */
+    static bool isDirectOutputSupported(const audio_config_base_t& config,
+                                        const audio_attributes_t& attributes);
+
     /* How data is transferred to AudioTrack
      */
     enum transfer_type {
@@ -153,6 +161,7 @@
         TRANSFER_OBTAIN,    // call obtainBuffer() and releaseBuffer()
         TRANSFER_SYNC,      // synchronous write()
         TRANSFER_SHARED,    // shared memory
+        TRANSFER_SYNC_NOTIF_CALLBACK, // synchronous write(), notif EVENT_CAN_WRITE_MORE_DATA
     };
 
     /* Constructs an uninitialized AudioTrack. No connection with
@@ -295,6 +304,8 @@
      * Parameters not listed in the AudioTrack constructors above:
      *
      * threadCanCallJava:  Whether callbacks are made from an attached thread and thus can call JNI.
+     *      Only set to true when AudioTrack object is used for a java android.media.AudioTrack
+     *      in its JNI code.
      *
      * Internal state post condition:
      *      (mStreamType == AUDIO_STREAM_DEFAULT) implies this AudioTrack has valid attributes
@@ -907,7 +918,14 @@
                 AutoMutex lock(mLock);
                 return mState == STATE_ACTIVE || mState == STATE_STOPPING;
             }
-protected:
+
+    /* Get the unique port ID assigned to this AudioTrack instance by audio policy manager.
+     * The ID is unique across all audioserver clients and can change during the life cycle
+     * of a given AudioTrack instance if the connection to audioserver is restored.
+     */
+            audio_port_handle_t getPortId() const { return mPortId; };
+
+ protected:
     /* copying audio tracks is not allowed */
                         AudioTrack(const AudioTrack& other);
             AudioTrack& operator = (const AudioTrack& other);
@@ -916,7 +934,7 @@
     class AudioTrackThread : public Thread
     {
     public:
-        AudioTrackThread(AudioTrack& receiver, bool bCanCallJava = false);
+        AudioTrackThread(AudioTrack& receiver);
 
         // Do not call Thread::requestExitAndWait() without first calling requestExit().
         // Thread::requestExitAndWait() is not virtual, and the implementation doesn't do enough.
@@ -1003,7 +1021,7 @@
     sp<IAudioTrack>         mAudioTrack;
     sp<IMemory>             mCblkMemory;
     audio_track_cblk_t*     mCblk;                  // re-load after mLock.unlock()
-    audio_io_handle_t       mOutput;                // returned by AudioSystem::getOutputForAttr()
+    audio_io_handle_t       mOutput = AUDIO_IO_HANDLE_NONE; // from AudioSystem::getOutputForAttr()
 
     sp<AudioTrackThread>    mAudioTrackThread;
     bool                    mThreadCanCallJava;
@@ -1058,6 +1076,19 @@
         STATE_STOPPING,
     }                       mState;
 
+    static constexpr const char *stateToString(State state)
+    {
+        switch (state) {
+        case STATE_ACTIVE:          return "STATE_ACTIVE";
+        case STATE_STOPPED:         return "STATE_STOPPED";
+        case STATE_PAUSED:          return "STATE_PAUSED";
+        case STATE_PAUSED_STOPPING: return "STATE_PAUSED_STOPPING";
+        case STATE_FLUSHED:         return "STATE_FLUSHED";
+        case STATE_STOPPING:        return "STATE_STOPPING";
+        default:                    return "UNKNOWN";
+        }
+    }
+
     // for client callback handler
     callback_t              mCbf;                   // callback handler for events, or NULL
     void*                   mUserData;
@@ -1120,8 +1151,11 @@
                                                     // AudioTracks.
 
     bool                    mPreviousTimestampValid;// true if mPreviousTimestamp is valid
-    bool                    mTimestampStartupGlitchReported; // reduce log spam
-    bool                    mRetrogradeMotionReported; // reduce log spam
+    bool                    mTimestampStartupGlitchReported;      // reduce log spam
+    bool                    mTimestampRetrogradePositionReported; // reduce log spam
+    bool                    mTimestampRetrogradeTimeReported;     // reduce log spam
+    bool                    mTimestampStallReported;              // reduce log spam
+    bool                    mTimestampStaleTimeReported;          // reduce log spam
     AudioTimestamp          mPreviousTimestamp;     // used to detect retrograde motion
     ExtendedTimestamp::Location mPreviousLocation;  // location used for previous timestamp
 
@@ -1148,6 +1182,7 @@
 
     audio_session_t         mSessionId;
     int                     mAuxEffectId;
+    audio_port_handle_t     mPortId;                    // Id from Audio Policy Manager
 
     mutable Mutex           mLock;
 
@@ -1195,7 +1230,7 @@
 private:
     class MediaMetrics {
       public:
-        MediaMetrics() : mAnalyticsItem(new MediaAnalyticsItem("audiotrack")) {
+        MediaMetrics() : mAnalyticsItem(MediaAnalyticsItem::create("audiotrack")) {
         }
         ~MediaMetrics() {
             // mAnalyticsItem alloc failure will be flagged in the constructor
diff --git a/media/libaudioclient/include/media/AudioVolumeGroup.h b/media/libaudioclient/include/media/AudioVolumeGroup.h
new file mode 100644
index 0000000..9a6ea07
--- /dev/null
+++ b/media/libaudioclient/include/media/AudioVolumeGroup.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#pragma once
+
+#include <media/AudioProductStrategy.h>
+#include <system/audio.h>
+#include <system/audio_policy.h>
+#include <binder/Parcelable.h>
+
+namespace android {
+
+class AudioVolumeGroup : public Parcelable
+{
+public:
+    AudioVolumeGroup() {}
+    AudioVolumeGroup(const std::string &name,
+                     volume_group_t group,
+                     const AttributesVector &attributes,
+                     const StreamTypeVector &streams) :
+        mName(name), mGroupId(group), mAudioAttributes(attributes), mStreams(streams) {}
+
+    const std::string &getName() const { return mName; }
+    volume_group_t getId() const { return mGroupId; }
+    AttributesVector getAudioAttributes() const { return mAudioAttributes; }
+    StreamTypeVector getStreamTypes() const { return mStreams; }
+
+    status_t readFromParcel(const Parcel *parcel) override;
+    status_t writeToParcel(Parcel *parcel) const override;
+
+private:
+    std::string mName;
+    volume_group_t mGroupId = VOLUME_GROUP_NONE;
+    AttributesVector mAudioAttributes;
+    StreamTypeVector mStreams;
+};
+
+using AudioVolumeGroupVector = std::vector<AudioVolumeGroup>;
+
+} // namespace android
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index e6bf72f..8ec8931 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -146,6 +146,7 @@
             afSampleRate = parcel->readInt64();
             afLatencyMs = parcel->readInt32();
             (void)parcel->read(&outputId, sizeof(audio_io_handle_t));
+            (void)parcel->read(&portId, sizeof(audio_port_handle_t));
             return NO_ERROR;
         }
 
@@ -163,6 +164,7 @@
             (void)parcel->writeInt64(afSampleRate);
             (void)parcel->writeInt32(afLatencyMs);
             (void)parcel->write(&outputId, sizeof(audio_io_handle_t));
+            (void)parcel->write(&portId, sizeof(audio_port_handle_t));
             return NO_ERROR;
         }
 
@@ -179,6 +181,7 @@
         uint32_t afSampleRate;
         uint32_t afLatencyMs;
         audio_io_handle_t outputId;
+        audio_port_handle_t portId;
     };
 
     /* CreateRecordInput contains all input arguments sent by AudioRecord to AudioFlinger
@@ -202,6 +205,9 @@
                 return DEAD_OBJECT;
             }
             opPackageName = parcel->readString16();
+            if (parcel->read(&riid, sizeof(audio_unique_id_t)) != NO_ERROR) {
+                return DEAD_OBJECT;
+            }
 
             /* input/output arguments*/
             (void)parcel->read(&flags, sizeof(audio_input_flags_t));
@@ -218,6 +224,7 @@
             (void)parcel->write(&config, sizeof(audio_config_base_t));
             (void)clientInfo.writeToParcel(parcel);
             (void)parcel->writeString16(opPackageName);
+            (void)parcel->write(&riid, sizeof(audio_unique_id_t));
 
             /* input/output arguments*/
             (void)parcel->write(&flags, sizeof(audio_input_flags_t));
@@ -233,6 +240,7 @@
         audio_config_base_t config;
         AudioClient clientInfo;
         String16 opPackageName;
+        audio_unique_id_t riid;
 
         /* input/output */
         audio_input_flags_t flags;
@@ -271,6 +279,7 @@
                     return BAD_VALUE;
                 }
             }
+            (void)parcel->read(&portId, sizeof(audio_port_handle_t));
             return NO_ERROR;
         }
 
@@ -297,6 +306,7 @@
             } else {
                 (void)parcel->writeInt32(0);
             }
+            (void)parcel->write(&portId, sizeof(audio_port_handle_t));
 
             return NO_ERROR;
         }
@@ -313,6 +323,7 @@
         audio_io_handle_t inputId;
         sp<IMemory> cblk;
         sp<IMemory> buffers;
+        audio_port_handle_t portId;
     };
 
     // invariant on exit for all APIs that return an sp<>:
@@ -353,6 +364,9 @@
     virtual     float       masterVolume() const = 0;
     virtual     bool        masterMute() const = 0;
 
+    virtual     status_t    setMasterBalance(float balance) = 0;
+    virtual     status_t    getMasterBalance(float *balance) const = 0;
+
     /* set/get stream type state. This will probably be used by
      * the preference panel, mostly.
      */
@@ -428,7 +442,9 @@
     virtual status_t queryEffect(uint32_t index, effect_descriptor_t *pDescriptor) const = 0;
 
     virtual status_t getEffectDescriptor(const effect_uuid_t *pEffectUUID,
-                                        effect_descriptor_t *pDescriptor) const = 0;
+                                         const effect_uuid_t *pTypeUUID,
+                                         uint32_t preferredTypeFlag,
+                                         effect_descriptor_t *pDescriptor) const = 0;
 
     virtual sp<IEffect> createEffect(
                                     effect_descriptor_t *pDesc,
@@ -446,6 +462,10 @@
     virtual status_t moveEffects(audio_session_t session, audio_io_handle_t srcOutput,
                                     audio_io_handle_t dstOutput) = 0;
 
+    virtual void setEffectSuspended(int effectId,
+                                    audio_session_t sessionId,
+                                    bool suspended) = 0;
+
     virtual audio_module_handle_t loadHwModule(const char *name) = 0;
 
     // helpers for android.media.AudioManager.getProperty(), see description there for meaning
diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
index c3876af..32275cf 100644
--- a/media/libaudioclient/include/media/IAudioPolicyService.h
+++ b/media/libaudioclient/include/media/IAudioPolicyService.h
@@ -20,15 +20,14 @@
 #include <stdint.h>
 #include <sys/types.h>
 #include <unistd.h>
-
 #include <utils/RefBase.h>
 #include <utils/Errors.h>
 #include <binder/IInterface.h>
 #include <media/AudioSystem.h>
 #include <media/AudioPolicy.h>
 #include <media/IAudioPolicyServiceClient.h>
-
 #include <system/audio_policy.h>
+#include <vector>
 
 namespace android {
 
@@ -45,18 +44,20 @@
     virtual status_t setDeviceConnectionState(audio_devices_t device,
                                               audio_policy_dev_state_t state,
                                               const char *device_address,
-                                              const char *device_name) = 0;
+                                              const char *device_name,
+                                              audio_format_t encodedFormat) = 0;
     virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
                                                                   const char *device_address) = 0;
     virtual status_t handleDeviceConfigChange(audio_devices_t device,
                                               const char *device_address,
-                                              const char *device_name) = 0;
+                                              const char *device_name,
+                                              audio_format_t encodedFormat) = 0;
     virtual status_t setPhoneState(audio_mode_t state) = 0;
     virtual status_t setForceUse(audio_policy_force_use_t usage,
                                     audio_policy_forced_cfg_t config) = 0;
     virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) = 0;
     virtual audio_io_handle_t getOutput(audio_stream_type_t stream) = 0;
-    virtual status_t getOutputForAttr(const audio_attributes_t *attr,
+    virtual status_t getOutputForAttr(audio_attributes_t *attr,
                                       audio_io_handle_t *output,
                                       audio_session_t session,
                                       audio_stream_type_t *stream,
@@ -65,18 +66,14 @@
                                       const audio_config_t *config,
                                       audio_output_flags_t flags,
                                       audio_port_handle_t *selectedDeviceId,
-                                      audio_port_handle_t *portId) = 0;
-    virtual status_t startOutput(audio_io_handle_t output,
-                                 audio_stream_type_t stream,
-                                 audio_session_t session) = 0;
-    virtual status_t stopOutput(audio_io_handle_t output,
-                                audio_stream_type_t stream,
-                                audio_session_t session) = 0;
-    virtual void releaseOutput(audio_io_handle_t output,
-                               audio_stream_type_t stream,
-                               audio_session_t session) = 0;
+                                      audio_port_handle_t *portId,
+                                      std::vector<audio_io_handle_t> *secondaryOutputs) = 0;
+    virtual status_t startOutput(audio_port_handle_t portId) = 0;
+    virtual status_t stopOutput(audio_port_handle_t portId) = 0;
+    virtual void releaseOutput(audio_port_handle_t portId) = 0;
     virtual status_t  getInputForAttr(const audio_attributes_t *attr,
                               audio_io_handle_t *input,
+                              audio_unique_id_t riid,
                               audio_session_t session,
                               pid_t pid,
                               uid_t uid,
@@ -85,8 +82,7 @@
                               audio_input_flags_t flags,
                               audio_port_handle_t *selectedDeviceId,
                               audio_port_handle_t *portId) = 0;
-    virtual status_t startInput(audio_port_handle_t portId,
-                                bool *silenced) = 0;
+    virtual status_t startInput(audio_port_handle_t portId) = 0;
     virtual status_t stopInput(audio_port_handle_t portId) = 0;
     virtual void releaseInput(audio_port_handle_t portId) = 0;
     virtual status_t initStreamVolume(audio_stream_type_t stream,
@@ -98,6 +94,17 @@
     virtual status_t getStreamVolumeIndex(audio_stream_type_t stream,
                                           int *index,
                                           audio_devices_t device) = 0;
+
+    virtual status_t setVolumeIndexForAttributes(const audio_attributes_t &attr,
+                                                 int index,
+                                                 audio_devices_t device) = 0;
+    virtual status_t getVolumeIndexForAttributes(const audio_attributes_t &attr,
+                                                 int &index,
+                                                 audio_devices_t device) = 0;
+    virtual status_t getMaxVolumeIndexForAttributes(const audio_attributes_t &attr, int &index) = 0;
+
+    virtual status_t getMinVolumeIndexForAttributes(const audio_attributes_t &attr, int &index) = 0;
+
     virtual uint32_t getStrategyForStream(audio_stream_type_t stream) = 0;
     virtual audio_devices_t getDevicesForStream(audio_stream_type_t stream) = 0;
     virtual audio_io_handle_t getOutputForEffect(const effect_descriptor_t *desc) = 0;
@@ -108,6 +115,7 @@
                                     int id) = 0;
     virtual status_t unregisterEffect(int id) = 0;
     virtual status_t setEffectEnabled(int id, bool enabled) = 0;
+    virtual status_t moveEffectsToIo(const std::vector<int>& ids, audio_io_handle_t io) = 0;
     virtual bool     isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const = 0;
     virtual bool     isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs = 0)
                              const = 0;
@@ -115,10 +123,29 @@
     virtual status_t queryDefaultPreProcessing(audio_session_t audioSession,
                                               effect_descriptor_t *descriptors,
                                               uint32_t *count) = 0;
+    virtual status_t addSourceDefaultEffect(const effect_uuid_t *type,
+                                            const String16& opPackageName,
+                                            const effect_uuid_t *uuid,
+                                            int32_t priority,
+                                            audio_source_t source,
+                                            audio_unique_id_t* id) = 0;
+    virtual status_t addStreamDefaultEffect(const effect_uuid_t *type,
+                                            const String16& opPackageName,
+                                            const effect_uuid_t *uuid,
+                                            int32_t priority,
+                                            audio_usage_t usage,
+                                            audio_unique_id_t* id) = 0;
+    virtual status_t removeSourceDefaultEffect(audio_unique_id_t id) = 0;
+    virtual status_t removeStreamDefaultEffect(audio_unique_id_t id) = 0;
+    virtual status_t setAllowedCapturePolicy(uid_t uid, audio_flags_mask_t flags) = 0;
    // Check if offload is possible for given format, stream type, sample rate,
     // bit rate, duration, video and streaming or offload property is enabled
     virtual bool isOffloadSupported(const audio_offload_info_t& info) = 0;
 
+    // Check if direct playback is possible for given format, sample rate, channel mask and flags.
+    virtual bool isDirectOutputSupported(const audio_config_base_t& config,
+                                         const audio_attributes_t& attributes) = 0;
+
     /* List available audio ports and their attributes */
     virtual status_t listAudioPorts(audio_port_role_t role,
                                     audio_port_type_t type,
@@ -147,6 +174,8 @@
 
     virtual void setAudioPortCallbacksEnabled(bool enabled) = 0;
 
+    virtual void setAudioVolumeGroupCallbacksEnabled(bool enabled) = 0;
+
     virtual status_t acquireSoundTriggerSession(audio_session_t *session,
                                            audio_io_handle_t *ioHandle,
                                            audio_devices_t *device) = 0;
@@ -157,10 +186,15 @@
 
     virtual status_t registerPolicyMixes(const Vector<AudioMix>& mixes, bool registration) = 0;
 
+    virtual status_t setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices)
+            = 0;
+
+    virtual status_t removeUidDeviceAffinities(uid_t uid) = 0;
+
     virtual status_t startAudioSource(const struct audio_port_config *source,
                                       const audio_attributes_t *attributes,
-                                      audio_patch_handle_t *handle) = 0;
-    virtual status_t stopAudioSource(audio_patch_handle_t handle) = 0;
+                                      audio_port_handle_t *portId) = 0;
+    virtual status_t stopAudioSource(audio_port_handle_t portId) = 0;
 
     virtual status_t setMasterMono(bool mono) = 0;
     virtual status_t getMasterMono(bool *mono) = 0;
@@ -171,7 +205,23 @@
                                         audio_format_t *surroundFormats,
                                         bool *surroundFormatsEnabled,
                                         bool reported) = 0;
+    virtual status_t getHwOffloadEncodingFormatsSupportedForA2DP(
+                                        std::vector<audio_format_t> *formats) = 0;
     virtual status_t setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled) = 0;
+
+    virtual status_t setAssistantUid(uid_t uid) = 0;
+    virtual status_t setA11yServicesUids(const std::vector<uid_t>& uids) = 0;
+
+    virtual bool     isHapticPlaybackSupported() = 0;
+    virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies) = 0;
+    virtual status_t getProductStrategyFromAudioAttributes(const AudioAttributes &aa,
+                                                           product_strategy_t &productStrategy) = 0;
+
+    virtual status_t listAudioVolumeGroups(AudioVolumeGroupVector &groups) = 0;
+    virtual status_t getVolumeGroupFromAudioAttributes(const AudioAttributes &aa,
+                                                       volume_group_t &volumeGroup) = 0;
+
+    virtual status_t setRttEnabled(bool enabled) = 0;
 };
 
 
diff --git a/media/libaudioclient/include/media/IAudioPolicyServiceClient.h b/media/libaudioclient/include/media/IAudioPolicyServiceClient.h
index e0d2495..47b31ee 100644
--- a/media/libaudioclient/include/media/IAudioPolicyServiceClient.h
+++ b/media/libaudioclient/include/media/IAudioPolicyServiceClient.h
@@ -17,19 +17,26 @@
 #ifndef ANDROID_IAUDIOPOLICYSERVICECLIENT_H
 #define ANDROID_IAUDIOPOLICYSERVICECLIENT_H
 
+#include <vector>
 
 #include <utils/RefBase.h>
 #include <binder/IInterface.h>
 #include <system/audio.h>
+#include <system/audio_effect.h>
+#include <media/AudioPolicy.h>
+#include <media/AudioVolumeGroup.h>
 
 namespace android {
 
 // ----------------------------------------------------------------------------
 
 struct record_client_info {
+    audio_unique_id_t riid;
     uid_t uid;
     audio_session_t session;
     audio_source_t source;
+    audio_port_handle_t port_id;
+    bool silenced;
 };
 
 typedef struct record_client_info record_client_info_t;
@@ -41,6 +48,8 @@
 public:
     DECLARE_META_INTERFACE(AudioPolicyServiceClient);
 
+    // Notifies a change of volume group
+    virtual void onAudioVolumeGroupChanged(volume_group_t group, int flags) = 0;
     // Notifies a change of audio port configuration.
     virtual void onAudioPortListUpdate() = 0;
     // Notifies a change of audio patch configuration.
@@ -51,8 +60,11 @@
     virtual void onRecordingConfigurationUpdate(int event,
             const record_client_info_t *clientInfo,
             const audio_config_base_t *clientConfig,
+            std::vector<effect_descriptor_t> clientEffects,
             const audio_config_base_t *deviceConfig,
-            audio_patch_handle_t patchHandle) = 0;
+            std::vector<effect_descriptor_t> effects,
+            audio_patch_handle_t patchHandle,
+            audio_source_t source) = 0;
 };
 
 
diff --git a/media/libaudioclient/include/media/IAudioTrack.h b/media/libaudioclient/include/media/IAudioTrack.h
index 94afe3c..06e786d 100644
--- a/media/libaudioclient/include/media/IAudioTrack.h
+++ b/media/libaudioclient/include/media/IAudioTrack.h
@@ -70,6 +70,9 @@
     /* Send parameters to the audio hardware */
     virtual status_t    setParameters(const String8& keyValuePairs) = 0;
 
+    /* Selects the presentation (if available) */
+    virtual status_t    selectPresentation(int presentationId, int programId) = 0;
+
     /* Return NO_ERROR if timestamp is valid.  timestamp is undefined otherwise. */
     virtual status_t    getTimestamp(AudioTimestamp& timestamp) = 0;
 
diff --git a/media/libaudioclient/include/media/RecordingActivityTracker.h b/media/libaudioclient/include/media/RecordingActivityTracker.h
new file mode 100644
index 0000000..9891a70
--- /dev/null
+++ b/media/libaudioclient/include/media/RecordingActivityTracker.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __ANDROID_RECORDING_ACTIVITY_TRACKER_H__
+#define __ANDROID_RECORDING_ACTIVITY_TRACKER_H__
+
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+class IAudioManager;
+class IBinder;
+
+class RecordingActivityTracker
+{
+public:
+    RecordingActivityTracker();
+    ~RecordingActivityTracker();
+    audio_unique_id_t getRiid();
+    void recordingStarted();
+    void recordingStopped();
+
+private:
+    sp<IAudioManager> mAudioManager;
+    audio_unique_id_t mRIId;
+    sp<IBinder>       mToken;
+};
+
+} // namespace android
+
+#endif // __ANDROID_RECORDING_ACTIVITY_TRACKER_H__
diff --git a/media/libaudioclient/include/media/ToneGenerator.h b/media/libaudioclient/include/media/ToneGenerator.h
index 7ae6aa6..5b0689a9 100644
--- a/media/libaudioclient/include/media/ToneGenerator.h
+++ b/media/libaudioclient/include/media/ToneGenerator.h
@@ -263,9 +263,9 @@
     class ToneSegment {
     public:
         unsigned int duration;
-        unsigned short waveFreq[TONEGEN_MAX_WAVES+1];
-        unsigned short loopCnt;
-        unsigned short loopIndx;
+        uint16_t waveFreq[TONEGEN_MAX_WAVES+1];
+        uint16_t loopCnt;
+        uint16_t loopIndx;
     };
 
     class ToneDescriptor {
@@ -286,14 +286,14 @@
     unsigned int mMaxSmp;  // Maximum number of audio samples played (maximun tone duration)
     int mDurationMs;  // Maximum tone duration in ms
 
-    unsigned short mCurSegment;  // Current segment index in ToneDescriptor segments[]
-    unsigned short mCurCount;  // Current sequence repeat count
-    volatile unsigned short mState;  // ToneGenerator state (tone_state)
-    unsigned short mRegion;
+    uint16_t mCurSegment;  // Current segment index in ToneDescriptor segments[]
+    uint16_t mCurCount;  // Current sequence repeat count
+    volatile uint16_t mState;  // ToneGenerator state (tone_state)
+    uint16_t mRegion;
     const ToneDescriptor *mpToneDesc;  // pointer to active tone descriptor
     const ToneDescriptor *mpNewToneDesc;  // pointer to next active tone descriptor
 
-    unsigned short mLoopCounter; // Current tone loopback count
+    uint16_t mLoopCounter; // Current tone loopback count
 
     uint32_t mSamplingRate;  // AudioFlinger Sampling rate
     sp<AudioTrack> mpAudioTrack;  // Pointer to audio track used for playback
@@ -321,26 +321,26 @@
             WAVEGEN_STOP  // Stop wave on zero crossing
         };
 
-        WaveGenerator(uint32_t samplingRate, unsigned short frequency,
+        WaveGenerator(uint32_t samplingRate, uint16_t frequency,
                 float volume);
         ~WaveGenerator();
 
-        void getSamples(short *outBuffer, unsigned int count,
+        void getSamples(int16_t *outBuffer, unsigned int count,
                 unsigned int command);
 
     private:
-        static const short GEN_AMP = 32000;  // amplitude of generator
-        static const short S_Q14 = 14;  // shift for Q14
-        static const short S_Q15 = 15;  // shift for Q15
+        static const int16_t GEN_AMP = 32000;  // amplitude of generator
+        static const int16_t S_Q14 = 14;  // shift for Q14
+        static const int16_t S_Q15 = 15;  // shift for Q15
 
-        short mA1_Q14;  // Q14 coefficient
+        int16_t mA1_Q14;  // Q14 coefficient
         // delay line of full amplitude generator
         long mS1, mS2;  // delay line S2 oldest
-        short mS2_0;  // saved value for reinitialisation
-        short mAmplitude_Q15;  // Q15 amplitude
+        int16_t mS2_0;  // saved value for reinitialisation
+        int16_t mAmplitude_Q15;  // Q15 amplitude
     };
 
-    KeyedVector<unsigned short, WaveGenerator *> mWaveGens;  // list of active wave generators.
+    KeyedVector<uint16_t, WaveGenerator *> mWaveGens;  // list of active wave generators.
 };
 
 }
diff --git a/media/libaudiohal/2.0/Android.bp b/media/libaudiohal/2.0/Android.bp
deleted file mode 100644
index 574b435..0000000
--- a/media/libaudiohal/2.0/Android.bp
+++ /dev/null
@@ -1,54 +0,0 @@
-cc_library_shared {
-    name: "libaudiohal@2.0",
-
-    srcs: [
-        "DeviceHalLocal.cpp",
-        "DevicesFactoryHalHybrid.cpp",
-        "DevicesFactoryHalLocal.cpp",
-        "StreamHalLocal.cpp",
-
-        "ConversionHelperHidl.cpp",
-        "DeviceHalHidl.cpp",
-        "DevicesFactoryHalHidl.cpp",
-        "EffectBufferHalHidl.cpp",
-        "EffectHalHidl.cpp",
-        "EffectsFactoryHalHidl.cpp",
-        "StreamHalHidl.cpp",
-    ],
-
-    export_include_dirs: ["."],
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-    shared_libs: [
-        "libaudiohal_deathhandler",
-        "libaudioutils",
-        "libcutils",
-        "liblog",
-        "libutils",
-        "libhardware",
-        "libbase",
-        "libfmq",
-        "libhwbinder",
-        "libhidlbase",
-        "libhidlmemory",
-        "libhidltransport",
-        "android.hardware.audio@2.0",
-        "android.hardware.audio.common@2.0",
-        "android.hardware.audio.common@2.0-util",
-        "android.hardware.audio.effect@2.0",
-        "android.hidl.allocator@1.0",
-        "android.hidl.memory@1.0",
-        "libmedia_helper",
-        "libmediautils",
-    ],
-    header_libs: [
-        "libaudiohal_headers"
-    ],
-
-    export_shared_lib_headers: [
-        "libfmq",
-    ],
-}
diff --git a/media/libaudiohal/2.0/ConversionHelperHidl.cpp b/media/libaudiohal/2.0/ConversionHelperHidl.cpp
deleted file mode 100644
index f60bf8b..0000000
--- a/media/libaudiohal/2.0/ConversionHelperHidl.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <string.h>
-
-#define LOG_TAG "HalHidl"
-#include <media/AudioParameter.h>
-#include <utils/Log.h>
-
-#include "ConversionHelperHidl.h"
-
-using ::android::hardware::audio::V2_0::Result;
-
-namespace android {
-
-// static
-status_t ConversionHelperHidl::keysFromHal(const String8& keys, hidl_vec<hidl_string> *hidlKeys) {
-    AudioParameter halKeys(keys);
-    if (halKeys.size() == 0) return BAD_VALUE;
-    hidlKeys->resize(halKeys.size());
-    //FIXME:  keyStreamSupportedChannels and keyStreamSupportedSamplingRates come with a
-    // "keyFormat=<value>" pair. We need to transform it into a single key string so that it is
-    // carried over to the legacy HAL via HIDL.
-    String8 value;
-    bool keepFormatValue = halKeys.size() == 2 &&
-         (halKeys.get(String8(AudioParameter::keyStreamSupportedChannels), value) == NO_ERROR ||
-         halKeys.get(String8(AudioParameter::keyStreamSupportedSamplingRates), value) == NO_ERROR);
-
-    for (size_t i = 0; i < halKeys.size(); ++i) {
-        String8 key;
-        status_t status = halKeys.getAt(i, key);
-        if (status != OK) return status;
-        if (keepFormatValue && key == AudioParameter::keyFormat) {
-            AudioParameter formatParam;
-            halKeys.getAt(i, key, value);
-            formatParam.add(key, value);
-            key = formatParam.toString();
-        }
-        (*hidlKeys)[i] = key.string();
-    }
-    return OK;
-}
-
-// static
-status_t ConversionHelperHidl::parametersFromHal(
-        const String8& kvPairs, hidl_vec<ParameterValue> *hidlParams) {
-    AudioParameter params(kvPairs);
-    if (params.size() == 0) return BAD_VALUE;
-    hidlParams->resize(params.size());
-    for (size_t i = 0; i < params.size(); ++i) {
-        String8 key, value;
-        status_t status = params.getAt(i, key, value);
-        if (status != OK) return status;
-        (*hidlParams)[i].key = key.string();
-        (*hidlParams)[i].value = value.string();
-    }
-    return OK;
-}
-
-// static
-void ConversionHelperHidl::parametersToHal(
-        const hidl_vec<ParameterValue>& parameters, String8 *values) {
-    AudioParameter params;
-    for (size_t i = 0; i < parameters.size(); ++i) {
-        params.add(String8(parameters[i].key.c_str()), String8(parameters[i].value.c_str()));
-    }
-    values->setTo(params.toString());
-}
-
-ConversionHelperHidl::ConversionHelperHidl(const char* className)
-        : mClassName(className) {
-}
-
-// static
-status_t ConversionHelperHidl::analyzeResult(const Result& result) {
-    switch (result) {
-        case Result::OK: return OK;
-        case Result::INVALID_ARGUMENTS: return BAD_VALUE;
-        case Result::INVALID_STATE: return NOT_ENOUGH_DATA;
-        case Result::NOT_INITIALIZED: return NO_INIT;
-        case Result::NOT_SUPPORTED: return INVALID_OPERATION;
-        default: return NO_INIT;
-    }
-}
-
-void ConversionHelperHidl::emitError(const char* funcName, const char* description) {
-    ALOGE("%s %p %s: %s (from rpc)", mClassName, this, funcName, description);
-}
-
-}  // namespace android
diff --git a/media/libaudiohal/2.0/ConversionHelperHidl.h b/media/libaudiohal/2.0/ConversionHelperHidl.h
deleted file mode 100644
index c356f37..0000000
--- a/media/libaudiohal/2.0/ConversionHelperHidl.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_CONVERSION_HELPER_HIDL_H
-#define ANDROID_HARDWARE_CONVERSION_HELPER_HIDL_H
-
-#include <android/hardware/audio/2.0/types.h>
-#include <hidl/HidlSupport.h>
-#include <utils/String8.h>
-
-using ::android::hardware::audio::V2_0::ParameterValue;
-using ::android::hardware::Return;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-
-namespace android {
-
-class ConversionHelperHidl {
-  protected:
-    static status_t keysFromHal(const String8& keys, hidl_vec<hidl_string> *hidlKeys);
-    static status_t parametersFromHal(const String8& kvPairs, hidl_vec<ParameterValue> *hidlParams);
-    static void parametersToHal(const hidl_vec<ParameterValue>& parameters, String8 *values);
-
-    ConversionHelperHidl(const char* className);
-
-    template<typename R, typename T>
-    status_t processReturn(const char* funcName, const Return<R>& ret, T *retval) {
-        if (ret.isOk()) {
-            // This way it also works for enum class to unscoped enum conversion.
-            *retval = static_cast<T>(static_cast<R>(ret));
-            return OK;
-        }
-        return processReturn(funcName, ret);
-    }
-
-    template<typename T>
-    status_t processReturn(const char* funcName, const Return<T>& ret) {
-        if (!ret.isOk()) {
-            emitError(funcName, ret.description().c_str());
-        }
-        return ret.isOk() ? OK : FAILED_TRANSACTION;
-    }
-
-    status_t processReturn(const char* funcName, const Return<hardware::audio::V2_0::Result>& ret) {
-        if (!ret.isOk()) {
-            emitError(funcName, ret.description().c_str());
-        }
-        return ret.isOk() ? analyzeResult(ret) : FAILED_TRANSACTION;
-    }
-
-    template<typename T>
-    status_t processReturn(
-            const char* funcName, const Return<T>& ret, hardware::audio::V2_0::Result retval) {
-        if (!ret.isOk()) {
-            emitError(funcName, ret.description().c_str());
-        }
-        return ret.isOk() ? analyzeResult(retval) : FAILED_TRANSACTION;
-    }
-
-  private:
-    const char* mClassName;
-
-    static status_t analyzeResult(const hardware::audio::V2_0::Result& result);
-
-    void emitError(const char* funcName, const char* description);
-};
-
-}  // namespace android
-
-#endif // ANDROID_HARDWARE_CONVERSION_HELPER_HIDL_H
diff --git a/media/libaudiohal/2.0/DeviceHalHidl.cpp b/media/libaudiohal/2.0/DeviceHalHidl.cpp
deleted file mode 100644
index 5b99d70..0000000
--- a/media/libaudiohal/2.0/DeviceHalHidl.cpp
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-
-#define LOG_TAG "DeviceHalHidl"
-//#define LOG_NDEBUG 0
-
-#include <android/hardware/audio/2.0/IPrimaryDevice.h>
-#include <cutils/native_handle.h>
-#include <hwbinder/IPCThreadState.h>
-#include <utils/Log.h>
-
-#include "DeviceHalHidl.h"
-#include "HidlUtils.h"
-#include "StreamHalHidl.h"
-
-using ::android::hardware::audio::common::V2_0::AudioConfig;
-using ::android::hardware::audio::common::V2_0::AudioDevice;
-using ::android::hardware::audio::common::V2_0::AudioInputFlag;
-using ::android::hardware::audio::common::V2_0::AudioOutputFlag;
-using ::android::hardware::audio::common::V2_0::AudioPatchHandle;
-using ::android::hardware::audio::common::V2_0::AudioPort;
-using ::android::hardware::audio::common::V2_0::AudioPortConfig;
-using ::android::hardware::audio::common::V2_0::AudioMode;
-using ::android::hardware::audio::common::V2_0::AudioSource;
-using ::android::hardware::audio::common::V2_0::HidlUtils;
-using ::android::hardware::audio::V2_0::DeviceAddress;
-using ::android::hardware::audio::V2_0::IPrimaryDevice;
-using ::android::hardware::audio::V2_0::ParameterValue;
-using ::android::hardware::audio::V2_0::Result;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-
-namespace android {
-
-namespace {
-
-status_t deviceAddressFromHal(
-        audio_devices_t device, const char* halAddress, DeviceAddress* address) {
-    address->device = AudioDevice(device);
-
-    if (halAddress == nullptr || strnlen(halAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
-        return OK;
-    }
-    const bool isInput = (device & AUDIO_DEVICE_BIT_IN) != 0;
-    if (isInput) device &= ~AUDIO_DEVICE_BIT_IN;
-    if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_A2DP) != 0)
-            || (isInput && (device & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0)) {
-        int status = sscanf(halAddress,
-                "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX",
-                &address->address.mac[0], &address->address.mac[1], &address->address.mac[2],
-                &address->address.mac[3], &address->address.mac[4], &address->address.mac[5]);
-        return status == 6 ? OK : BAD_VALUE;
-    } else if ((!isInput && (device & AUDIO_DEVICE_OUT_IP) != 0)
-            || (isInput && (device & AUDIO_DEVICE_IN_IP) != 0)) {
-        int status = sscanf(halAddress,
-                "%hhu.%hhu.%hhu.%hhu",
-                &address->address.ipv4[0], &address->address.ipv4[1],
-                &address->address.ipv4[2], &address->address.ipv4[3]);
-        return status == 4 ? OK : BAD_VALUE;
-    } else if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_USB)) != 0
-            || (isInput && (device & AUDIO_DEVICE_IN_ALL_USB)) != 0) {
-        int status = sscanf(halAddress,
-                "card=%d;device=%d",
-                &address->address.alsa.card, &address->address.alsa.device);
-        return status == 2 ? OK : BAD_VALUE;
-    } else if ((!isInput && (device & AUDIO_DEVICE_OUT_BUS) != 0)
-            || (isInput && (device & AUDIO_DEVICE_IN_BUS) != 0)) {
-        if (halAddress != NULL) {
-            address->busAddress = halAddress;
-            return OK;
-        }
-        return BAD_VALUE;
-    } else if ((!isInput && (device & AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) != 0
-            || (isInput && (device & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0)) {
-        if (halAddress != NULL) {
-            address->rSubmixAddress = halAddress;
-            return OK;
-        }
-        return BAD_VALUE;
-    }
-    return OK;
-}
-
-}  // namespace
-
-DeviceHalHidl::DeviceHalHidl(const sp<IDevice>& device)
-        : ConversionHelperHidl("Device"), mDevice(device),
-          mPrimaryDevice(IPrimaryDevice::castFrom(device)) {
-}
-
-DeviceHalHidl::~DeviceHalHidl() {
-    if (mDevice != 0) {
-        mDevice.clear();
-        hardware::IPCThreadState::self()->flushCommands();
-    }
-}
-
-status_t DeviceHalHidl::getSupportedDevices(uint32_t*) {
-    // Obsolete.
-    return INVALID_OPERATION;
-}
-
-status_t DeviceHalHidl::initCheck() {
-    if (mDevice == 0) return NO_INIT;
-    return processReturn("initCheck", mDevice->initCheck());
-}
-
-status_t DeviceHalHidl::setVoiceVolume(float volume) {
-    if (mDevice == 0) return NO_INIT;
-    if (mPrimaryDevice == 0) return INVALID_OPERATION;
-    return processReturn("setVoiceVolume", mPrimaryDevice->setVoiceVolume(volume));
-}
-
-status_t DeviceHalHidl::setMasterVolume(float volume) {
-    if (mDevice == 0) return NO_INIT;
-    if (mPrimaryDevice == 0) return INVALID_OPERATION;
-    return processReturn("setMasterVolume", mPrimaryDevice->setMasterVolume(volume));
-}
-
-status_t DeviceHalHidl::getMasterVolume(float *volume) {
-    if (mDevice == 0) return NO_INIT;
-    if (mPrimaryDevice == 0) return INVALID_OPERATION;
-    Result retval;
-    Return<void> ret = mPrimaryDevice->getMasterVolume(
-            [&](Result r, float v) {
-                retval = r;
-                if (retval == Result::OK) {
-                    *volume = v;
-                }
-            });
-    return processReturn("getMasterVolume", ret, retval);
-}
-
-status_t DeviceHalHidl::setMode(audio_mode_t mode) {
-    if (mDevice == 0) return NO_INIT;
-    if (mPrimaryDevice == 0) return INVALID_OPERATION;
-    return processReturn("setMode", mPrimaryDevice->setMode(AudioMode(mode)));
-}
-
-status_t DeviceHalHidl::setMicMute(bool state) {
-    if (mDevice == 0) return NO_INIT;
-    return processReturn("setMicMute", mDevice->setMicMute(state));
-}
-
-status_t DeviceHalHidl::getMicMute(bool *state) {
-    if (mDevice == 0) return NO_INIT;
-    Result retval;
-    Return<void> ret = mDevice->getMicMute(
-            [&](Result r, bool mute) {
-                retval = r;
-                if (retval == Result::OK) {
-                    *state = mute;
-                }
-            });
-    return processReturn("getMicMute", ret, retval);
-}
-
-status_t DeviceHalHidl::setMasterMute(bool state) {
-    if (mDevice == 0) return NO_INIT;
-    return processReturn("setMasterMute", mDevice->setMasterMute(state));
-}
-
-status_t DeviceHalHidl::getMasterMute(bool *state) {
-    if (mDevice == 0) return NO_INIT;
-    Result retval;
-    Return<void> ret = mDevice->getMasterMute(
-            [&](Result r, bool mute) {
-                retval = r;
-                if (retval == Result::OK) {
-                    *state = mute;
-                }
-            });
-    return processReturn("getMasterMute", ret, retval);
-}
-
-status_t DeviceHalHidl::setParameters(const String8& kvPairs) {
-    if (mDevice == 0) return NO_INIT;
-    hidl_vec<ParameterValue> hidlParams;
-    status_t status = parametersFromHal(kvPairs, &hidlParams);
-    if (status != OK) return status;
-    return processReturn("setParameters", mDevice->setParameters(hidlParams));
-}
-
-status_t DeviceHalHidl::getParameters(const String8& keys, String8 *values) {
-    values->clear();
-    if (mDevice == 0) return NO_INIT;
-    hidl_vec<hidl_string> hidlKeys;
-    status_t status = keysFromHal(keys, &hidlKeys);
-    if (status != OK) return status;
-    Result retval;
-    Return<void> ret = mDevice->getParameters(
-            hidlKeys,
-            [&](Result r, const hidl_vec<ParameterValue>& parameters) {
-                retval = r;
-                if (retval == Result::OK) {
-                    parametersToHal(parameters, values);
-                }
-            });
-    return processReturn("getParameters", ret, retval);
-}
-
-status_t DeviceHalHidl::getInputBufferSize(
-        const struct audio_config *config, size_t *size) {
-    if (mDevice == 0) return NO_INIT;
-    AudioConfig hidlConfig;
-    HidlUtils::audioConfigFromHal(*config, &hidlConfig);
-    Result retval;
-    Return<void> ret = mDevice->getInputBufferSize(
-            hidlConfig,
-            [&](Result r, uint64_t bufferSize) {
-                retval = r;
-                if (retval == Result::OK) {
-                    *size = static_cast<size_t>(bufferSize);
-                }
-            });
-    return processReturn("getInputBufferSize", ret, retval);
-}
-
-status_t DeviceHalHidl::openOutputStream(
-        audio_io_handle_t handle,
-        audio_devices_t devices,
-        audio_output_flags_t flags,
-        struct audio_config *config,
-        const char *address,
-        sp<StreamOutHalInterface> *outStream) {
-    if (mDevice == 0) return NO_INIT;
-    DeviceAddress hidlDevice;
-    status_t status = deviceAddressFromHal(devices, address, &hidlDevice);
-    if (status != OK) return status;
-    AudioConfig hidlConfig;
-    HidlUtils::audioConfigFromHal(*config, &hidlConfig);
-    Result retval = Result::NOT_INITIALIZED;
-    Return<void> ret = mDevice->openOutputStream(
-            handle,
-            hidlDevice,
-            hidlConfig,
-            AudioOutputFlag(flags),
-            [&](Result r, const sp<IStreamOut>& result, const AudioConfig& suggestedConfig) {
-                retval = r;
-                if (retval == Result::OK) {
-                    *outStream = new StreamOutHalHidl(result);
-                }
-                HidlUtils::audioConfigToHal(suggestedConfig, config);
-            });
-    return processReturn("openOutputStream", ret, retval);
-}
-
-status_t DeviceHalHidl::openInputStream(
-        audio_io_handle_t handle,
-        audio_devices_t devices,
-        struct audio_config *config,
-        audio_input_flags_t flags,
-        const char *address,
-        audio_source_t source,
-        sp<StreamInHalInterface> *inStream) {
-    if (mDevice == 0) return NO_INIT;
-    DeviceAddress hidlDevice;
-    status_t status = deviceAddressFromHal(devices, address, &hidlDevice);
-    if (status != OK) return status;
-    AudioConfig hidlConfig;
-    HidlUtils::audioConfigFromHal(*config, &hidlConfig);
-    Result retval = Result::NOT_INITIALIZED;
-    Return<void> ret = mDevice->openInputStream(
-            handle,
-            hidlDevice,
-            hidlConfig,
-            AudioInputFlag(flags),
-            AudioSource(source),
-            [&](Result r, const sp<IStreamIn>& result, const AudioConfig& suggestedConfig) {
-                retval = r;
-                if (retval == Result::OK) {
-                    *inStream = new StreamInHalHidl(result);
-                }
-                HidlUtils::audioConfigToHal(suggestedConfig, config);
-            });
-    return processReturn("openInputStream", ret, retval);
-}
-
-status_t DeviceHalHidl::supportsAudioPatches(bool *supportsPatches) {
-    if (mDevice == 0) return NO_INIT;
-    return processReturn("supportsAudioPatches", mDevice->supportsAudioPatches(), supportsPatches);
-}
-
-status_t DeviceHalHidl::createAudioPatch(
-        unsigned int num_sources,
-        const struct audio_port_config *sources,
-        unsigned int num_sinks,
-        const struct audio_port_config *sinks,
-        audio_patch_handle_t *patch) {
-    if (mDevice == 0) return NO_INIT;
-    hidl_vec<AudioPortConfig> hidlSources, hidlSinks;
-    HidlUtils::audioPortConfigsFromHal(num_sources, sources, &hidlSources);
-    HidlUtils::audioPortConfigsFromHal(num_sinks, sinks, &hidlSinks);
-    Result retval;
-    Return<void> ret = mDevice->createAudioPatch(
-            hidlSources, hidlSinks,
-            [&](Result r, AudioPatchHandle hidlPatch) {
-                retval = r;
-                if (retval == Result::OK) {
-                    *patch = static_cast<audio_patch_handle_t>(hidlPatch);
-                }
-            });
-    return processReturn("createAudioPatch", ret, retval);
-}
-
-status_t DeviceHalHidl::releaseAudioPatch(audio_patch_handle_t patch) {
-    if (mDevice == 0) return NO_INIT;
-    return processReturn("releaseAudioPatch", mDevice->releaseAudioPatch(patch));
-}
-
-status_t DeviceHalHidl::getAudioPort(struct audio_port *port) {
-    if (mDevice == 0) return NO_INIT;
-    AudioPort hidlPort;
-    HidlUtils::audioPortFromHal(*port, &hidlPort);
-    Result retval;
-    Return<void> ret = mDevice->getAudioPort(
-            hidlPort,
-            [&](Result r, const AudioPort& p) {
-                retval = r;
-                if (retval == Result::OK) {
-                    HidlUtils::audioPortToHal(p, port);
-                }
-            });
-    return processReturn("getAudioPort", ret, retval);
-}
-
-status_t DeviceHalHidl::setAudioPortConfig(const struct audio_port_config *config) {
-    if (mDevice == 0) return NO_INIT;
-    AudioPortConfig hidlConfig;
-    HidlUtils::audioPortConfigFromHal(*config, &hidlConfig);
-    return processReturn("setAudioPortConfig", mDevice->setAudioPortConfig(hidlConfig));
-}
-
-status_t DeviceHalHidl::getMicrophones(
-        std::vector<media::MicrophoneInfo> *microphonesInfo __unused) {
-    if (mDevice == 0) return NO_INIT;
-    return INVALID_OPERATION;
-}
-
-status_t DeviceHalHidl::dump(int fd) {
-    if (mDevice == 0) return NO_INIT;
-    native_handle_t* hidlHandle = native_handle_create(1, 0);
-    hidlHandle->data[0] = fd;
-    Return<void> ret = mDevice->debugDump(hidlHandle);
-    native_handle_delete(hidlHandle);
-    return processReturn("dump", ret);
-}
-
-} // namespace android
diff --git a/media/libaudiohal/2.0/DeviceHalHidl.h b/media/libaudiohal/2.0/DeviceHalHidl.h
deleted file mode 100644
index 3c1cb594..0000000
--- a/media/libaudiohal/2.0/DeviceHalHidl.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_DEVICE_HAL_HIDL_H
-#define ANDROID_HARDWARE_DEVICE_HAL_HIDL_H
-
-#include <android/hardware/audio/2.0/IDevice.h>
-#include <android/hardware/audio/2.0/IPrimaryDevice.h>
-#include <media/audiohal/DeviceHalInterface.h>
-
-#include "ConversionHelperHidl.h"
-
-using ::android::hardware::audio::V2_0::IDevice;
-using ::android::hardware::audio::V2_0::IPrimaryDevice;
-using ::android::hardware::Return;
-
-namespace android {
-
-class DeviceHalHidl : public DeviceHalInterface, public ConversionHelperHidl
-{
-  public:
-    // Sets the value of 'devices' to a bitmask of 1 or more values of audio_devices_t.
-    virtual status_t getSupportedDevices(uint32_t *devices);
-
-    // Check to see if the audio hardware interface has been initialized.
-    virtual status_t initCheck();
-
-    // Set the audio volume of a voice call. Range is between 0.0 and 1.0.
-    virtual status_t setVoiceVolume(float volume);
-
-    // Set the audio volume for all audio activities other than voice call.
-    virtual status_t setMasterVolume(float volume);
-
-    // Get the current master volume value for the HAL.
-    virtual status_t getMasterVolume(float *volume);
-
-    // Called when the audio mode changes.
-    virtual status_t setMode(audio_mode_t mode);
-
-    // Muting control.
-    virtual status_t setMicMute(bool state);
-    virtual status_t getMicMute(bool *state);
-    virtual status_t setMasterMute(bool state);
-    virtual status_t getMasterMute(bool *state);
-
-    // Set global audio parameters.
-    virtual status_t setParameters(const String8& kvPairs);
-
-    // Get global audio parameters.
-    virtual status_t getParameters(const String8& keys, String8 *values);
-
-    // Returns audio input buffer size according to parameters passed.
-    virtual status_t getInputBufferSize(const struct audio_config *config,
-            size_t *size);
-
-    // Creates and opens the audio hardware output stream. The stream is closed
-    // by releasing all references to the returned object.
-    virtual status_t openOutputStream(
-            audio_io_handle_t handle,
-            audio_devices_t devices,
-            audio_output_flags_t flags,
-            struct audio_config *config,
-            const char *address,
-            sp<StreamOutHalInterface> *outStream);
-
-    // Creates and opens the audio hardware input stream. The stream is closed
-    // by releasing all references to the returned object.
-    virtual status_t openInputStream(
-            audio_io_handle_t handle,
-            audio_devices_t devices,
-            struct audio_config *config,
-            audio_input_flags_t flags,
-            const char *address,
-            audio_source_t source,
-            sp<StreamInHalInterface> *inStream);
-
-    // Returns whether createAudioPatch and releaseAudioPatch operations are supported.
-    virtual status_t supportsAudioPatches(bool *supportsPatches);
-
-    // Creates an audio patch between several source and sink ports.
-    virtual status_t createAudioPatch(
-            unsigned int num_sources,
-            const struct audio_port_config *sources,
-            unsigned int num_sinks,
-            const struct audio_port_config *sinks,
-            audio_patch_handle_t *patch);
-
-    // Releases an audio patch.
-    virtual status_t releaseAudioPatch(audio_patch_handle_t patch);
-
-    // Fills the list of supported attributes for a given audio port.
-    virtual status_t getAudioPort(struct audio_port *port);
-
-    // Set audio port configuration.
-    virtual status_t setAudioPortConfig(const struct audio_port_config *config);
-
-    // List microphones
-    virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
-
-    virtual status_t dump(int fd);
-
-  private:
-    friend class DevicesFactoryHalHidl;
-    sp<IDevice> mDevice;
-    sp<IPrimaryDevice> mPrimaryDevice;  // Null if it's not a primary device.
-
-    // Can not be constructed directly by clients.
-    explicit DeviceHalHidl(const sp<IDevice>& device);
-
-    // The destructor automatically closes the device.
-    virtual ~DeviceHalHidl();
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_DEVICE_HAL_HIDL_H
diff --git a/media/libaudiohal/2.0/DeviceHalLocal.cpp b/media/libaudiohal/2.0/DeviceHalLocal.cpp
deleted file mode 100644
index ec3bf78..0000000
--- a/media/libaudiohal/2.0/DeviceHalLocal.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "DeviceHalLocal"
-//#define LOG_NDEBUG 0
-
-#include <utils/Log.h>
-
-#include "DeviceHalLocal.h"
-#include "StreamHalLocal.h"
-
-namespace android {
-
-DeviceHalLocal::DeviceHalLocal(audio_hw_device_t *dev)
-        : mDev(dev) {
-}
-
-DeviceHalLocal::~DeviceHalLocal() {
-    int status = audio_hw_device_close(mDev);
-    ALOGW_IF(status, "Error closing audio hw device %p: %s", mDev, strerror(-status));
-    mDev = 0;
-}
-
-status_t DeviceHalLocal::getSupportedDevices(uint32_t *devices) {
-    if (mDev->get_supported_devices == NULL) return INVALID_OPERATION;
-    *devices = mDev->get_supported_devices(mDev);
-    return OK;
-}
-
-status_t DeviceHalLocal::initCheck() {
-    return mDev->init_check(mDev);
-}
-
-status_t DeviceHalLocal::setVoiceVolume(float volume) {
-    return mDev->set_voice_volume(mDev, volume);
-}
-
-status_t DeviceHalLocal::setMasterVolume(float volume) {
-    if (mDev->set_master_volume == NULL) return INVALID_OPERATION;
-    return mDev->set_master_volume(mDev, volume);
-}
-
-status_t DeviceHalLocal::getMasterVolume(float *volume) {
-    if (mDev->get_master_volume == NULL) return INVALID_OPERATION;
-    return mDev->get_master_volume(mDev, volume);
-}
-
-status_t DeviceHalLocal::setMode(audio_mode_t mode) {
-    return mDev->set_mode(mDev, mode);
-}
-
-status_t DeviceHalLocal::setMicMute(bool state) {
-    return mDev->set_mic_mute(mDev, state);
-}
-
-status_t DeviceHalLocal::getMicMute(bool *state) {
-    return mDev->get_mic_mute(mDev, state);
-}
-
-status_t DeviceHalLocal::setMasterMute(bool state) {
-    if (mDev->set_master_mute == NULL) return INVALID_OPERATION;
-    return mDev->set_master_mute(mDev, state);
-}
-
-status_t DeviceHalLocal::getMasterMute(bool *state) {
-    if (mDev->get_master_mute == NULL) return INVALID_OPERATION;
-    return mDev->get_master_mute(mDev, state);
-}
-
-status_t DeviceHalLocal::setParameters(const String8& kvPairs) {
-    return mDev->set_parameters(mDev, kvPairs.string());
-}
-
-status_t DeviceHalLocal::getParameters(const String8& keys, String8 *values) {
-    char *halValues = mDev->get_parameters(mDev, keys.string());
-    if (halValues != NULL) {
-        values->setTo(halValues);
-        free(halValues);
-    } else {
-        values->clear();
-    }
-    return OK;
-}
-
-status_t DeviceHalLocal::getInputBufferSize(
-        const struct audio_config *config, size_t *size) {
-    *size = mDev->get_input_buffer_size(mDev, config);
-    return OK;
-}
-
-status_t DeviceHalLocal::openOutputStream(
-        audio_io_handle_t handle,
-        audio_devices_t devices,
-        audio_output_flags_t flags,
-        struct audio_config *config,
-        const char *address,
-        sp<StreamOutHalInterface> *outStream) {
-    audio_stream_out_t *halStream;
-    ALOGV("open_output_stream handle: %d devices: %x flags: %#x"
-            "srate: %d format %#x channels %x address %s",
-            handle, devices, flags,
-            config->sample_rate, config->format, config->channel_mask,
-            address);
-    int openResut = mDev->open_output_stream(
-            mDev, handle, devices, flags, config, &halStream, address);
-    if (openResut == OK) {
-        *outStream = new StreamOutHalLocal(halStream, this);
-    }
-    ALOGV("open_output_stream status %d stream %p", openResut, halStream);
-    return openResut;
-}
-
-status_t DeviceHalLocal::openInputStream(
-        audio_io_handle_t handle,
-        audio_devices_t devices,
-        struct audio_config *config,
-        audio_input_flags_t flags,
-        const char *address,
-        audio_source_t source,
-        sp<StreamInHalInterface> *inStream) {
-    audio_stream_in_t *halStream;
-    ALOGV("open_input_stream handle: %d devices: %x flags: %#x "
-            "srate: %d format %#x channels %x address %s source %d",
-            handle, devices, flags,
-            config->sample_rate, config->format, config->channel_mask,
-            address, source);
-    int openResult = mDev->open_input_stream(
-            mDev, handle, devices, config, &halStream, flags, address, source);
-    if (openResult == OK) {
-        *inStream = new StreamInHalLocal(halStream, this);
-    }
-    ALOGV("open_input_stream status %d stream %p", openResult, inStream);
-    return openResult;
-}
-
-status_t DeviceHalLocal::supportsAudioPatches(bool *supportsPatches) {
-    *supportsPatches = version() >= AUDIO_DEVICE_API_VERSION_3_0;
-    return OK;
-}
-
-status_t DeviceHalLocal::createAudioPatch(
-        unsigned int num_sources,
-        const struct audio_port_config *sources,
-        unsigned int num_sinks,
-        const struct audio_port_config *sinks,
-        audio_patch_handle_t *patch) {
-    if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
-        return mDev->create_audio_patch(
-                mDev, num_sources, sources, num_sinks, sinks, patch);
-    } else {
-        return INVALID_OPERATION;
-    }
-}
-
-status_t DeviceHalLocal::releaseAudioPatch(audio_patch_handle_t patch) {
-    if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
-        return mDev->release_audio_patch(mDev, patch);
-    } else {
-        return INVALID_OPERATION;
-    }
-}
-
-status_t DeviceHalLocal::getAudioPort(struct audio_port *port) {
-    return mDev->get_audio_port(mDev, port);
-}
-
-status_t DeviceHalLocal::setAudioPortConfig(const struct audio_port_config *config) {
-    if (version() >= AUDIO_DEVICE_API_VERSION_3_0)
-        return mDev->set_audio_port_config(mDev, config);
-    else
-        return INVALID_OPERATION;
-}
-
-status_t DeviceHalLocal::getMicrophones(
-        std::vector<media::MicrophoneInfo> *microphones __unused) {
-    return INVALID_OPERATION;
-}
-
-status_t DeviceHalLocal::dump(int fd) {
-    return mDev->dump(mDev, fd);
-}
-
-void DeviceHalLocal::closeOutputStream(struct audio_stream_out *stream_out) {
-    mDev->close_output_stream(mDev, stream_out);
-}
-
-void DeviceHalLocal::closeInputStream(struct audio_stream_in *stream_in) {
-    mDev->close_input_stream(mDev, stream_in);
-}
-
-} // namespace android
diff --git a/media/libaudiohal/2.0/DeviceHalLocal.h b/media/libaudiohal/2.0/DeviceHalLocal.h
deleted file mode 100644
index aec201a..0000000
--- a/media/libaudiohal/2.0/DeviceHalLocal.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_DEVICE_HAL_LOCAL_H
-#define ANDROID_HARDWARE_DEVICE_HAL_LOCAL_H
-
-#include <hardware/audio.h>
-#include <media/audiohal/DeviceHalInterface.h>
-
-namespace android {
-
-class DeviceHalLocal : public DeviceHalInterface
-{
-  public:
-    // Sets the value of 'devices' to a bitmask of 1 or more values of audio_devices_t.
-    virtual status_t getSupportedDevices(uint32_t *devices);
-
-    // Check to see if the audio hardware interface has been initialized.
-    virtual status_t initCheck();
-
-    // Set the audio volume of a voice call. Range is between 0.0 and 1.0.
-    virtual status_t setVoiceVolume(float volume);
-
-    // Set the audio volume for all audio activities other than voice call.
-    virtual status_t setMasterVolume(float volume);
-
-    // Get the current master volume value for the HAL.
-    virtual status_t getMasterVolume(float *volume);
-
-    // Called when the audio mode changes.
-    virtual status_t setMode(audio_mode_t mode);
-
-    // Muting control.
-    virtual status_t setMicMute(bool state);
-    virtual status_t getMicMute(bool *state);
-    virtual status_t setMasterMute(bool state);
-    virtual status_t getMasterMute(bool *state);
-
-    // Set global audio parameters.
-    virtual status_t setParameters(const String8& kvPairs);
-
-    // Get global audio parameters.
-    virtual status_t getParameters(const String8& keys, String8 *values);
-
-    // Returns audio input buffer size according to parameters passed.
-    virtual status_t getInputBufferSize(const struct audio_config *config,
-            size_t *size);
-
-    // Creates and opens the audio hardware output stream. The stream is closed
-    // by releasing all references to the returned object.
-    virtual status_t openOutputStream(
-            audio_io_handle_t handle,
-            audio_devices_t devices,
-            audio_output_flags_t flags,
-            struct audio_config *config,
-            const char *address,
-            sp<StreamOutHalInterface> *outStream);
-
-    // Creates and opens the audio hardware input stream. The stream is closed
-    // by releasing all references to the returned object.
-    virtual status_t openInputStream(
-            audio_io_handle_t handle,
-            audio_devices_t devices,
-            struct audio_config *config,
-            audio_input_flags_t flags,
-            const char *address,
-            audio_source_t source,
-            sp<StreamInHalInterface> *inStream);
-
-    // Returns whether createAudioPatch and releaseAudioPatch operations are supported.
-    virtual status_t supportsAudioPatches(bool *supportsPatches);
-
-    // Creates an audio patch between several source and sink ports.
-    virtual status_t createAudioPatch(
-            unsigned int num_sources,
-            const struct audio_port_config *sources,
-            unsigned int num_sinks,
-            const struct audio_port_config *sinks,
-            audio_patch_handle_t *patch);
-
-    // Releases an audio patch.
-    virtual status_t releaseAudioPatch(audio_patch_handle_t patch);
-
-    // Fills the list of supported attributes for a given audio port.
-    virtual status_t getAudioPort(struct audio_port *port);
-
-    // Set audio port configuration.
-    virtual status_t setAudioPortConfig(const struct audio_port_config *config);
-
-    // List microphones
-    virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
-
-    virtual status_t dump(int fd);
-
-    void closeOutputStream(struct audio_stream_out *stream_out);
-    void closeInputStream(struct audio_stream_in *stream_in);
-
-  private:
-    audio_hw_device_t *mDev;
-
-    friend class DevicesFactoryHalLocal;
-
-    // Can not be constructed directly by clients.
-    explicit DeviceHalLocal(audio_hw_device_t *dev);
-
-    // The destructor automatically closes the device.
-    virtual ~DeviceHalLocal();
-
-    uint32_t version() const { return mDev->common.version; }
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_DEVICE_HAL_LOCAL_H
diff --git a/media/libaudiohal/2.0/DevicesFactoryHalHidl.cpp b/media/libaudiohal/2.0/DevicesFactoryHalHidl.cpp
deleted file mode 100644
index 5b33592..0000000
--- a/media/libaudiohal/2.0/DevicesFactoryHalHidl.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <string.h>
-
-#define LOG_TAG "DevicesFactoryHalHidl"
-//#define LOG_NDEBUG 0
-
-#include <android/hardware/audio/2.0/IDevice.h>
-#include <media/audiohal/hidl/HalDeathHandler.h>
-#include <utils/Log.h>
-
-#include "ConversionHelperHidl.h"
-#include "DeviceHalHidl.h"
-#include "DevicesFactoryHalHidl.h"
-
-using ::android::hardware::audio::V2_0::IDevice;
-using ::android::hardware::audio::V2_0::Result;
-using ::android::hardware::Return;
-
-namespace android {
-
-DevicesFactoryHalHidl::DevicesFactoryHalHidl() {
-    mDevicesFactory = IDevicesFactory::getService();
-    if (mDevicesFactory != 0) {
-        // It is assumed that DevicesFactory is owned by AudioFlinger
-        // and thus have the same lifespan.
-        mDevicesFactory->linkToDeath(HalDeathHandler::getInstance(), 0 /*cookie*/);
-    } else {
-        ALOGE("Failed to obtain IDevicesFactory service, terminating process.");
-        exit(1);
-    }
-    // The MSD factory is optional
-    mDevicesFactoryMsd = IDevicesFactory::getService(AUDIO_HAL_SERVICE_NAME_MSD);
-    // TODO: Register death handler, and add 'restart' directive to audioserver.rc
-}
-
-DevicesFactoryHalHidl::~DevicesFactoryHalHidl() {
-}
-
-// static
-status_t DevicesFactoryHalHidl::nameFromHal(const char *name, IDevicesFactory::Device *device) {
-    if (strcmp(name, AUDIO_HARDWARE_MODULE_ID_PRIMARY) == 0) {
-        *device = IDevicesFactory::Device::PRIMARY;
-        return OK;
-    } else if(strcmp(name, AUDIO_HARDWARE_MODULE_ID_A2DP) == 0) {
-        *device = IDevicesFactory::Device::A2DP;
-        return OK;
-    } else if(strcmp(name, AUDIO_HARDWARE_MODULE_ID_USB) == 0) {
-        *device = IDevicesFactory::Device::USB;
-        return OK;
-    } else if(strcmp(name, AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX) == 0) {
-        *device = IDevicesFactory::Device::R_SUBMIX;
-        return OK;
-    } else if(strcmp(name, AUDIO_HARDWARE_MODULE_ID_STUB) == 0) {
-        *device = IDevicesFactory::Device::STUB;
-        return OK;
-    }
-    ALOGE("Invalid device name %s", name);
-    return BAD_VALUE;
-}
-
-status_t DevicesFactoryHalHidl::openDevice(const char *name, sp<DeviceHalInterface> *device) {
-    if (mDevicesFactory == 0) return NO_INIT;
-    IDevicesFactory::Device hidlDevice;
-    status_t status = nameFromHal(name, &hidlDevice);
-    if (status != OK) return status;
-    Result retval = Result::NOT_INITIALIZED;
-    Return<void> ret = mDevicesFactory->openDevice(
-            hidlDevice,
-            [&](Result r, const sp<IDevice>& result) {
-                retval = r;
-                if (retval == Result::OK) {
-                    *device = new DeviceHalHidl(result);
-                }
-            });
-    if (ret.isOk()) {
-        if (retval == Result::OK) return OK;
-        else if (retval == Result::INVALID_ARGUMENTS) return BAD_VALUE;
-        else return NO_INIT;
-    }
-    return FAILED_TRANSACTION;
-}
-
-} // namespace android
diff --git a/media/libaudiohal/2.0/DevicesFactoryHalHidl.h b/media/libaudiohal/2.0/DevicesFactoryHalHidl.h
deleted file mode 100644
index 0748849..0000000
--- a/media/libaudiohal/2.0/DevicesFactoryHalHidl.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_DEVICES_FACTORY_HAL_HIDL_H
-#define ANDROID_HARDWARE_DEVICES_FACTORY_HAL_HIDL_H
-
-#include <android/hardware/audio/2.0/IDevicesFactory.h>
-#include <media/audiohal/DevicesFactoryHalInterface.h>
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-
-#include "DeviceHalHidl.h"
-
-using ::android::hardware::audio::V2_0::IDevicesFactory;
-
-namespace android {
-
-class DevicesFactoryHalHidl : public DevicesFactoryHalInterface
-{
-  public:
-    // Opens a device with the specified name. To close the device, it is
-    // necessary to release references to the returned object.
-    virtual status_t openDevice(const char *name, sp<DeviceHalInterface> *device);
-
-  private:
-    friend class DevicesFactoryHalHybrid;
-
-    sp<IDevicesFactory> mDevicesFactory;
-    sp<IDevicesFactory> mDevicesFactoryMsd;
-
-    static status_t nameFromHal(const char *name, IDevicesFactory::Device *device);
-
-    // Can not be constructed directly by clients.
-    DevicesFactoryHalHidl();
-
-    virtual ~DevicesFactoryHalHidl();
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_DEVICES_FACTORY_HAL_HIDL_H
diff --git a/media/libaudiohal/2.0/DevicesFactoryHalHybrid.cpp b/media/libaudiohal/2.0/DevicesFactoryHalHybrid.cpp
deleted file mode 100644
index 1c4be74..0000000
--- a/media/libaudiohal/2.0/DevicesFactoryHalHybrid.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "DevicesFactoryHalHybrid"
-//#define LOG_NDEBUG 0
-
-#include "DevicesFactoryHalHybrid.h"
-#include "DevicesFactoryHalLocal.h"
-#include "DevicesFactoryHalHidl.h"
-
-namespace android {
-
-DevicesFactoryHalHybrid::DevicesFactoryHalHybrid()
-        : mLocalFactory(new DevicesFactoryHalLocal()),
-          mHidlFactory(new DevicesFactoryHalHidl()) {
-}
-
-DevicesFactoryHalHybrid::~DevicesFactoryHalHybrid() {
-}
-
-status_t DevicesFactoryHalHybrid::openDevice(const char *name, sp<DeviceHalInterface> *device) {
-    if (mHidlFactory != 0 && strcmp(AUDIO_HARDWARE_MODULE_ID_A2DP, name) != 0 &&
-        strcmp(AUDIO_HARDWARE_MODULE_ID_HEARING_AID, name) != 0) {
-        return mHidlFactory->openDevice(name, device);
-    }
-    return mLocalFactory->openDevice(name, device);
-}
-
-} // namespace android
diff --git a/media/libaudiohal/2.0/DevicesFactoryHalHybrid.h b/media/libaudiohal/2.0/DevicesFactoryHalHybrid.h
deleted file mode 100644
index abd57d6..0000000
--- a/media/libaudiohal/2.0/DevicesFactoryHalHybrid.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_DEVICES_FACTORY_HAL_HYBRID_H
-#define ANDROID_HARDWARE_DEVICES_FACTORY_HAL_HYBRID_H
-
-#include <media/audiohal/DevicesFactoryHalInterface.h>
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-
-namespace android {
-
-class DevicesFactoryHalHybrid : public DevicesFactoryHalInterface
-{
-  public:
-    // Opens a device with the specified name. To close the device, it is
-    // necessary to release references to the returned object.
-    virtual status_t openDevice(const char *name, sp<DeviceHalInterface> *device);
-
-  private:
-    friend class DevicesFactoryHalInterface;
-
-    // Can not be constructed directly by clients.
-    DevicesFactoryHalHybrid();
-
-    virtual ~DevicesFactoryHalHybrid();
-
-    sp<DevicesFactoryHalInterface> mLocalFactory;
-    sp<DevicesFactoryHalInterface> mHidlFactory;
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_DEVICES_FACTORY_HAL_HYBRID_H
diff --git a/media/libaudiohal/2.0/DevicesFactoryHalLocal.cpp b/media/libaudiohal/2.0/DevicesFactoryHalLocal.cpp
deleted file mode 100644
index 13a9acd..0000000
--- a/media/libaudiohal/2.0/DevicesFactoryHalLocal.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "DevicesFactoryHalLocal"
-//#define LOG_NDEBUG 0
-
-#include <string.h>
-
-#include <hardware/audio.h>
-#include <utils/Log.h>
-
-#include "DeviceHalLocal.h"
-#include "DevicesFactoryHalLocal.h"
-
-namespace android {
-
-static status_t load_audio_interface(const char *if_name, audio_hw_device_t **dev)
-{
-    const hw_module_t *mod;
-    int rc;
-
-    rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
-    if (rc) {
-        ALOGE("%s couldn't load audio hw module %s.%s (%s)", __func__,
-                AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
-        goto out;
-    }
-    rc = audio_hw_device_open(mod, dev);
-    if (rc) {
-        ALOGE("%s couldn't open audio hw device in %s.%s (%s)", __func__,
-                AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
-        goto out;
-    }
-    if ((*dev)->common.version < AUDIO_DEVICE_API_VERSION_MIN) {
-        ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version);
-        rc = BAD_VALUE;
-        audio_hw_device_close(*dev);
-        goto out;
-    }
-    return OK;
-
-out:
-    *dev = NULL;
-    return rc;
-}
-
-status_t DevicesFactoryHalLocal::openDevice(const char *name, sp<DeviceHalInterface> *device) {
-    audio_hw_device_t *dev;
-    status_t rc = load_audio_interface(name, &dev);
-    if (rc == OK) {
-        *device = new DeviceHalLocal(dev);
-    }
-    return rc;
-}
-
-} // namespace android
diff --git a/media/libaudiohal/2.0/DevicesFactoryHalLocal.h b/media/libaudiohal/2.0/DevicesFactoryHalLocal.h
deleted file mode 100644
index b9d18ab..0000000
--- a/media/libaudiohal/2.0/DevicesFactoryHalLocal.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_DEVICES_FACTORY_HAL_LOCAL_H
-#define ANDROID_HARDWARE_DEVICES_FACTORY_HAL_LOCAL_H
-
-#include <media/audiohal/DevicesFactoryHalInterface.h>
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-
-#include "DeviceHalLocal.h"
-
-namespace android {
-
-class DevicesFactoryHalLocal : public DevicesFactoryHalInterface
-{
-  public:
-    // Opens a device with the specified name. To close the device, it is
-    // necessary to release references to the returned object.
-    virtual status_t openDevice(const char *name, sp<DeviceHalInterface> *device);
-
-  private:
-    friend class DevicesFactoryHalHybrid;
-
-    // Can not be constructed directly by clients.
-    DevicesFactoryHalLocal() {}
-
-    virtual ~DevicesFactoryHalLocal() {}
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_DEVICES_FACTORY_HAL_LOCAL_H
diff --git a/media/libaudiohal/2.0/EffectBufferHalHidl.cpp b/media/libaudiohal/2.0/EffectBufferHalHidl.cpp
deleted file mode 100644
index 226a500..0000000
--- a/media/libaudiohal/2.0/EffectBufferHalHidl.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <atomic>
-
-#define LOG_TAG "EffectBufferHalHidl"
-//#define LOG_NDEBUG 0
-
-#include <android/hidl/allocator/1.0/IAllocator.h>
-#include <hidlmemory/mapping.h>
-#include <utils/Log.h>
-
-#include "ConversionHelperHidl.h"
-#include "EffectBufferHalHidl.h"
-
-using ::android::hardware::Return;
-using ::android::hidl::allocator::V1_0::IAllocator;
-
-namespace android {
-
-// static
-uint64_t EffectBufferHalHidl::makeUniqueId() {
-    static std::atomic<uint64_t> counter{1};
-    return counter++;
-}
-
-status_t EffectBufferHalHidl::allocate(
-        size_t size, sp<EffectBufferHalInterface>* buffer) {
-    return mirror(nullptr, size, buffer);
-}
-
-status_t EffectBufferHalHidl::mirror(
-        void* external, size_t size, sp<EffectBufferHalInterface>* buffer) {
-    sp<EffectBufferHalInterface> tempBuffer = new EffectBufferHalHidl(size);
-    status_t result = static_cast<EffectBufferHalHidl*>(tempBuffer.get())->init();
-    if (result == OK) {
-        tempBuffer->setExternalData(external);
-        *buffer = tempBuffer;
-    }
-    return result;
-}
-
-EffectBufferHalHidl::EffectBufferHalHidl(size_t size)
-        : mBufferSize(size), mFrameCountChanged(false),
-          mExternalData(nullptr), mAudioBuffer{0, {nullptr}} {
-    mHidlBuffer.id = makeUniqueId();
-    mHidlBuffer.frameCount = 0;
-}
-
-EffectBufferHalHidl::~EffectBufferHalHidl() {
-}
-
-status_t EffectBufferHalHidl::init() {
-    sp<IAllocator> ashmem = IAllocator::getService("ashmem");
-    if (ashmem == 0) {
-        ALOGE("Failed to retrieve ashmem allocator service");
-        return NO_INIT;
-    }
-    status_t retval = NO_MEMORY;
-    Return<void> result = ashmem->allocate(
-            mBufferSize,
-            [&](bool success, const hidl_memory& memory) {
-                if (success) {
-                    mHidlBuffer.data = memory;
-                    retval = OK;
-                }
-            });
-    if (result.isOk() && retval == OK) {
-        mMemory = hardware::mapMemory(mHidlBuffer.data);
-        if (mMemory != 0) {
-            mMemory->update();
-            mAudioBuffer.raw = static_cast<void*>(mMemory->getPointer());
-            memset(mAudioBuffer.raw, 0, mMemory->getSize());
-            mMemory->commit();
-        } else {
-            ALOGE("Failed to map allocated ashmem");
-            retval = NO_MEMORY;
-        }
-    } else {
-        ALOGE("Failed to allocate %d bytes from ashmem", (int)mBufferSize);
-    }
-    return result.isOk() ? retval : FAILED_TRANSACTION;
-}
-
-audio_buffer_t* EffectBufferHalHidl::audioBuffer() {
-    return &mAudioBuffer;
-}
-
-void* EffectBufferHalHidl::externalData() const {
-    return mExternalData;
-}
-
-void EffectBufferHalHidl::setFrameCount(size_t frameCount) {
-    mHidlBuffer.frameCount = frameCount;
-    mAudioBuffer.frameCount = frameCount;
-    mFrameCountChanged = true;
-}
-
-bool EffectBufferHalHidl::checkFrameCountChange() {
-    bool result = mFrameCountChanged;
-    mFrameCountChanged = false;
-    return result;
-}
-
-void EffectBufferHalHidl::setExternalData(void* external) {
-    mExternalData = external;
-}
-
-void EffectBufferHalHidl::update() {
-    update(mBufferSize);
-}
-
-void EffectBufferHalHidl::commit() {
-    commit(mBufferSize);
-}
-
-void EffectBufferHalHidl::update(size_t size) {
-    if (mExternalData == nullptr) return;
-    mMemory->update();
-    if (size > mBufferSize) size = mBufferSize;
-    memcpy(mAudioBuffer.raw, mExternalData, size);
-    mMemory->commit();
-}
-
-void EffectBufferHalHidl::commit(size_t size) {
-    if (mExternalData == nullptr) return;
-    if (size > mBufferSize) size = mBufferSize;
-    memcpy(mExternalData, mAudioBuffer.raw, size);
-}
-
-} // namespace android
diff --git a/media/libaudiohal/2.0/EffectBufferHalHidl.h b/media/libaudiohal/2.0/EffectBufferHalHidl.h
deleted file mode 100644
index 31e0087..0000000
--- a/media/libaudiohal/2.0/EffectBufferHalHidl.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_EFFECT_BUFFER_HAL_HIDL_H
-#define ANDROID_HARDWARE_EFFECT_BUFFER_HAL_HIDL_H
-
-#include <android/hardware/audio/effect/2.0/types.h>
-#include <android/hidl/memory/1.0/IMemory.h>
-#include <hidl/HidlSupport.h>
-#include <media/audiohal/EffectBufferHalInterface.h>
-#include <system/audio_effect.h>
-
-using android::hardware::audio::effect::V2_0::AudioBuffer;
-using android::hardware::hidl_memory;
-using android::hidl::memory::V1_0::IMemory;
-
-namespace android {
-
-class EffectBufferHalHidl : public EffectBufferHalInterface
-{
-  public:
-    static status_t allocate(size_t size, sp<EffectBufferHalInterface>* buffer);
-    static status_t mirror(void* external, size_t size, sp<EffectBufferHalInterface>* buffer);
-
-    virtual audio_buffer_t* audioBuffer();
-    virtual void* externalData() const;
-
-    virtual size_t getSize() const override { return mBufferSize; }
-
-    virtual void setExternalData(void* external);
-    virtual void setFrameCount(size_t frameCount);
-    virtual bool checkFrameCountChange();
-
-    virtual void update();
-    virtual void commit();
-    virtual void update(size_t size);
-    virtual void commit(size_t size);
-
-    const AudioBuffer& hidlBuffer() const { return mHidlBuffer; }
-
-  private:
-    friend class EffectBufferHalInterface;
-
-    static uint64_t makeUniqueId();
-
-    const size_t mBufferSize;
-    bool mFrameCountChanged;
-    void* mExternalData;
-    AudioBuffer mHidlBuffer;
-    sp<IMemory> mMemory;
-    audio_buffer_t mAudioBuffer;
-
-    // Can not be constructed directly by clients.
-    explicit EffectBufferHalHidl(size_t size);
-
-    virtual ~EffectBufferHalHidl();
-
-    status_t init();
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_EFFECT_BUFFER_HAL_HIDL_H
diff --git a/media/libaudiohal/2.0/EffectHalHidl.cpp b/media/libaudiohal/2.0/EffectHalHidl.cpp
deleted file mode 100644
index 4fb032c..0000000
--- a/media/libaudiohal/2.0/EffectHalHidl.cpp
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "EffectHalHidl"
-//#define LOG_NDEBUG 0
-
-#include <hwbinder/IPCThreadState.h>
-#include <media/EffectsFactoryApi.h>
-#include <utils/Log.h>
-
-#include "ConversionHelperHidl.h"
-#include "EffectBufferHalHidl.h"
-#include "EffectHalHidl.h"
-#include "HidlUtils.h"
-
-using ::android::hardware::audio::effect::V2_0::AudioBuffer;
-using ::android::hardware::audio::effect::V2_0::EffectBufferAccess;
-using ::android::hardware::audio::effect::V2_0::EffectConfigParameters;
-using ::android::hardware::audio::effect::V2_0::MessageQueueFlagBits;
-using ::android::hardware::audio::effect::V2_0::Result;
-using ::android::hardware::audio::common::V2_0::HidlUtils;
-using ::android::hardware::audio::common::V2_0::AudioChannelMask;
-using ::android::hardware::audio::common::V2_0::AudioFormat;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::MQDescriptorSync;
-using ::android::hardware::Return;
-
-namespace android {
-
-EffectHalHidl::EffectHalHidl(const sp<IEffect>& effect, uint64_t effectId)
-        : mEffect(effect), mEffectId(effectId), mBuffersChanged(true), mEfGroup(nullptr) {
-}
-
-EffectHalHidl::~EffectHalHidl() {
-    if (mEffect != 0) {
-        close();
-        mEffect.clear();
-        hardware::IPCThreadState::self()->flushCommands();
-    }
-    if (mEfGroup) {
-        EventFlag::deleteEventFlag(&mEfGroup);
-    }
-}
-
-// static
-void EffectHalHidl::effectDescriptorToHal(
-        const EffectDescriptor& descriptor, effect_descriptor_t* halDescriptor) {
-    HidlUtils::uuidToHal(descriptor.type, &halDescriptor->type);
-    HidlUtils::uuidToHal(descriptor.uuid, &halDescriptor->uuid);
-    halDescriptor->flags = static_cast<uint32_t>(descriptor.flags);
-    halDescriptor->cpuLoad = descriptor.cpuLoad;
-    halDescriptor->memoryUsage = descriptor.memoryUsage;
-    memcpy(halDescriptor->name, descriptor.name.data(), descriptor.name.size());
-    memcpy(halDescriptor->implementor,
-            descriptor.implementor.data(), descriptor.implementor.size());
-}
-
-// TODO(mnaganov): These buffer conversion functions should be shared with Effect wrapper
-// via HidlUtils. Move them there when hardware/interfaces will get un-frozen again.
-
-// static
-void EffectHalHidl::effectBufferConfigFromHal(
-        const buffer_config_t& halConfig, EffectBufferConfig* config) {
-    config->samplingRateHz = halConfig.samplingRate;
-    config->channels = AudioChannelMask(halConfig.channels);
-    config->format = AudioFormat(halConfig.format);
-    config->accessMode = EffectBufferAccess(halConfig.accessMode);
-    config->mask = EffectConfigParameters(halConfig.mask);
-}
-
-// static
-void EffectHalHidl::effectBufferConfigToHal(
-        const EffectBufferConfig& config, buffer_config_t* halConfig) {
-    halConfig->buffer.frameCount = 0;
-    halConfig->buffer.raw = NULL;
-    halConfig->samplingRate = config.samplingRateHz;
-    halConfig->channels = static_cast<uint32_t>(config.channels);
-    halConfig->bufferProvider.cookie = NULL;
-    halConfig->bufferProvider.getBuffer = NULL;
-    halConfig->bufferProvider.releaseBuffer = NULL;
-    halConfig->format = static_cast<uint8_t>(config.format);
-    halConfig->accessMode = static_cast<uint8_t>(config.accessMode);
-    halConfig->mask = static_cast<uint8_t>(config.mask);
-}
-
-// static
-void EffectHalHidl::effectConfigFromHal(const effect_config_t& halConfig, EffectConfig* config) {
-    effectBufferConfigFromHal(halConfig.inputCfg, &config->inputCfg);
-    effectBufferConfigFromHal(halConfig.outputCfg, &config->outputCfg);
-}
-
-// static
-void EffectHalHidl::effectConfigToHal(const EffectConfig& config, effect_config_t* halConfig) {
-    effectBufferConfigToHal(config.inputCfg, &halConfig->inputCfg);
-    effectBufferConfigToHal(config.outputCfg, &halConfig->outputCfg);
-}
-
-// static
-status_t EffectHalHidl::analyzeResult(const Result& result) {
-    switch (result) {
-        case Result::OK: return OK;
-        case Result::INVALID_ARGUMENTS: return BAD_VALUE;
-        case Result::INVALID_STATE: return NOT_ENOUGH_DATA;
-        case Result::NOT_INITIALIZED: return NO_INIT;
-        case Result::NOT_SUPPORTED: return INVALID_OPERATION;
-        case Result::RESULT_TOO_BIG: return NO_MEMORY;
-        default: return NO_INIT;
-    }
-}
-
-status_t EffectHalHidl::setInBuffer(const sp<EffectBufferHalInterface>& buffer) {
-    if (!mBuffersChanged) {
-        if (buffer.get() == nullptr || mInBuffer.get() == nullptr) {
-            mBuffersChanged = buffer.get() != mInBuffer.get();
-        } else {
-            mBuffersChanged = buffer->audioBuffer() != mInBuffer->audioBuffer();
-        }
-    }
-    mInBuffer = buffer;
-    return OK;
-}
-
-status_t EffectHalHidl::setOutBuffer(const sp<EffectBufferHalInterface>& buffer) {
-    if (!mBuffersChanged) {
-        if (buffer.get() == nullptr || mOutBuffer.get() == nullptr) {
-            mBuffersChanged = buffer.get() != mOutBuffer.get();
-        } else {
-            mBuffersChanged = buffer->audioBuffer() != mOutBuffer->audioBuffer();
-        }
-    }
-    mOutBuffer = buffer;
-    return OK;
-}
-
-status_t EffectHalHidl::process() {
-    return processImpl(static_cast<uint32_t>(MessageQueueFlagBits::REQUEST_PROCESS));
-}
-
-status_t EffectHalHidl::processReverse() {
-    return processImpl(static_cast<uint32_t>(MessageQueueFlagBits::REQUEST_PROCESS_REVERSE));
-}
-
-status_t EffectHalHidl::prepareForProcessing() {
-    std::unique_ptr<StatusMQ> tempStatusMQ;
-    Result retval;
-    Return<void> ret = mEffect->prepareForProcessing(
-            [&](Result r, const MQDescriptorSync<Result>& statusMQ) {
-                retval = r;
-                if (retval == Result::OK) {
-                    tempStatusMQ.reset(new StatusMQ(statusMQ));
-                    if (tempStatusMQ->isValid() && tempStatusMQ->getEventFlagWord()) {
-                        EventFlag::createEventFlag(tempStatusMQ->getEventFlagWord(), &mEfGroup);
-                    }
-                }
-            });
-    if (!ret.isOk() || retval != Result::OK) {
-        return ret.isOk() ? analyzeResult(retval) : FAILED_TRANSACTION;
-    }
-    if (!tempStatusMQ || !tempStatusMQ->isValid() || !mEfGroup) {
-        ALOGE_IF(!tempStatusMQ, "Failed to obtain status message queue for effects");
-        ALOGE_IF(tempStatusMQ && !tempStatusMQ->isValid(),
-                "Status message queue for effects is invalid");
-        ALOGE_IF(!mEfGroup, "Event flag creation for effects failed");
-        return NO_INIT;
-    }
-    mStatusMQ = std::move(tempStatusMQ);
-    return OK;
-}
-
-bool EffectHalHidl::needToResetBuffers() {
-    if (mBuffersChanged) return true;
-    bool inBufferFrameCountUpdated = mInBuffer->checkFrameCountChange();
-    bool outBufferFrameCountUpdated = mOutBuffer->checkFrameCountChange();
-    return inBufferFrameCountUpdated || outBufferFrameCountUpdated;
-}
-
-status_t EffectHalHidl::processImpl(uint32_t mqFlag) {
-    if (mEffect == 0 || mInBuffer == 0 || mOutBuffer == 0) return NO_INIT;
-    status_t status;
-    if (!mStatusMQ && (status = prepareForProcessing()) != OK) {
-        return status;
-    }
-    if (needToResetBuffers() && (status = setProcessBuffers()) != OK) {
-        return status;
-    }
-    // The data is already in the buffers, just need to flush it and wake up the server side.
-    std::atomic_thread_fence(std::memory_order_release);
-    mEfGroup->wake(mqFlag);
-    uint32_t efState = 0;
-retry:
-    status_t ret = mEfGroup->wait(
-            static_cast<uint32_t>(MessageQueueFlagBits::DONE_PROCESSING), &efState);
-    if (efState & static_cast<uint32_t>(MessageQueueFlagBits::DONE_PROCESSING)) {
-        Result retval = Result::NOT_INITIALIZED;
-        mStatusMQ->read(&retval);
-        if (retval == Result::OK || retval == Result::INVALID_STATE) {
-            // Sync back the changed contents of the buffer.
-            std::atomic_thread_fence(std::memory_order_acquire);
-        }
-        return analyzeResult(retval);
-    }
-    if (ret == -EAGAIN || ret == -EINTR) {
-        // Spurious wakeup. This normally retries no more than once.
-        goto retry;
-    }
-    return ret;
-}
-
-status_t EffectHalHidl::setProcessBuffers() {
-    Return<Result> ret = mEffect->setProcessBuffers(
-            static_cast<EffectBufferHalHidl*>(mInBuffer.get())->hidlBuffer(),
-            static_cast<EffectBufferHalHidl*>(mOutBuffer.get())->hidlBuffer());
-    if (ret.isOk() && ret == Result::OK) {
-        mBuffersChanged = false;
-        return OK;
-    }
-    return ret.isOk() ? analyzeResult(ret) : FAILED_TRANSACTION;
-}
-
-status_t EffectHalHidl::command(uint32_t cmdCode, uint32_t cmdSize, void *pCmdData,
-        uint32_t *replySize, void *pReplyData) {
-    if (mEffect == 0) return NO_INIT;
-
-    // Special cases.
-    if (cmdCode == EFFECT_CMD_SET_CONFIG || cmdCode == EFFECT_CMD_SET_CONFIG_REVERSE) {
-        return setConfigImpl(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
-    } else if (cmdCode == EFFECT_CMD_GET_CONFIG || cmdCode == EFFECT_CMD_GET_CONFIG_REVERSE) {
-        return getConfigImpl(cmdCode, replySize, pReplyData);
-    }
-
-    // Common case.
-    hidl_vec<uint8_t> hidlData;
-    if (pCmdData != nullptr && cmdSize > 0) {
-        hidlData.setToExternal(reinterpret_cast<uint8_t*>(pCmdData), cmdSize);
-    }
-    status_t status;
-    uint32_t replySizeStub = 0;
-    if (replySize == nullptr || pReplyData == nullptr) replySize = &replySizeStub;
-    Return<void> ret = mEffect->command(cmdCode, hidlData, *replySize,
-            [&](int32_t s, const hidl_vec<uint8_t>& result) {
-                status = s;
-                if (status == 0) {
-                    if (*replySize > result.size()) *replySize = result.size();
-                    if (pReplyData != nullptr && *replySize > 0) {
-                        memcpy(pReplyData, &result[0], *replySize);
-                    }
-                }
-            });
-    return ret.isOk() ? status : FAILED_TRANSACTION;
-}
-
-status_t EffectHalHidl::getDescriptor(effect_descriptor_t *pDescriptor) {
-    if (mEffect == 0) return NO_INIT;
-    Result retval = Result::NOT_INITIALIZED;
-    Return<void> ret = mEffect->getDescriptor(
-            [&](Result r, const EffectDescriptor& result) {
-                retval = r;
-                if (retval == Result::OK) {
-                    effectDescriptorToHal(result, pDescriptor);
-                }
-            });
-    return ret.isOk() ? analyzeResult(retval) : FAILED_TRANSACTION;
-}
-
-status_t EffectHalHidl::close() {
-    if (mEffect == 0) return NO_INIT;
-    Return<Result> ret = mEffect->close();
-    return ret.isOk() ? analyzeResult(ret) : FAILED_TRANSACTION;
-}
-
-status_t EffectHalHidl::getConfigImpl(
-        uint32_t cmdCode, uint32_t *replySize, void *pReplyData) {
-    if (replySize == NULL || *replySize != sizeof(effect_config_t) || pReplyData == NULL) {
-        return BAD_VALUE;
-    }
-    status_t result = FAILED_TRANSACTION;
-    Return<void> ret;
-    if (cmdCode == EFFECT_CMD_GET_CONFIG) {
-        ret = mEffect->getConfig([&] (Result r, const EffectConfig &hidlConfig) {
-            result = analyzeResult(r);
-            if (r == Result::OK) {
-                effectConfigToHal(hidlConfig, static_cast<effect_config_t*>(pReplyData));
-            }
-        });
-    } else {
-        ret = mEffect->getConfigReverse([&] (Result r, const EffectConfig &hidlConfig) {
-            result = analyzeResult(r);
-            if (r == Result::OK) {
-                effectConfigToHal(hidlConfig, static_cast<effect_config_t*>(pReplyData));
-            }
-        });
-    }
-    if (!ret.isOk()) {
-        result = FAILED_TRANSACTION;
-    }
-    return result;
-}
-
-status_t EffectHalHidl::setConfigImpl(
-        uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, uint32_t *replySize, void *pReplyData) {
-    if (pCmdData == NULL || cmdSize != sizeof(effect_config_t) ||
-            replySize == NULL || *replySize != sizeof(int32_t) || pReplyData == NULL) {
-        return BAD_VALUE;
-    }
-    const effect_config_t *halConfig = static_cast<effect_config_t*>(pCmdData);
-    if (halConfig->inputCfg.bufferProvider.getBuffer != NULL ||
-            halConfig->inputCfg.bufferProvider.releaseBuffer != NULL ||
-            halConfig->outputCfg.bufferProvider.getBuffer != NULL ||
-            halConfig->outputCfg.bufferProvider.releaseBuffer != NULL) {
-        ALOGE("Buffer provider callbacks are not supported");
-    }
-    EffectConfig hidlConfig;
-    effectConfigFromHal(*halConfig, &hidlConfig);
-    Return<Result> ret = cmdCode == EFFECT_CMD_SET_CONFIG ?
-            mEffect->setConfig(hidlConfig, nullptr, nullptr) :
-            mEffect->setConfigReverse(hidlConfig, nullptr, nullptr);
-    status_t result = FAILED_TRANSACTION;
-    if (ret.isOk()) {
-        result = analyzeResult(ret);
-        *static_cast<int32_t*>(pReplyData) = result;
-    }
-    return result;
-}
-
-} // namespace android
diff --git a/media/libaudiohal/2.0/EffectHalHidl.h b/media/libaudiohal/2.0/EffectHalHidl.h
deleted file mode 100644
index 6ffdaf1..0000000
--- a/media/libaudiohal/2.0/EffectHalHidl.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_EFFECT_HAL_HIDL_H
-#define ANDROID_HARDWARE_EFFECT_HAL_HIDL_H
-
-#include <android/hardware/audio/effect/2.0/IEffect.h>
-#include <media/audiohal/EffectHalInterface.h>
-#include <fmq/EventFlag.h>
-#include <fmq/MessageQueue.h>
-#include <system/audio_effect.h>
-
-using ::android::hardware::audio::effect::V2_0::EffectBufferConfig;
-using ::android::hardware::audio::effect::V2_0::EffectConfig;
-using ::android::hardware::audio::effect::V2_0::EffectDescriptor;
-using ::android::hardware::audio::effect::V2_0::IEffect;
-using ::android::hardware::EventFlag;
-using ::android::hardware::MessageQueue;
-
-namespace android {
-
-class EffectHalHidl : public EffectHalInterface
-{
-  public:
-    // Set the input buffer.
-    virtual status_t setInBuffer(const sp<EffectBufferHalInterface>& buffer);
-
-    // Set the output buffer.
-    virtual status_t setOutBuffer(const sp<EffectBufferHalInterface>& buffer);
-
-    // Effect process function.
-    virtual status_t process();
-
-    // Process reverse stream function. This function is used to pass
-    // a reference stream to the effect engine.
-    virtual status_t processReverse();
-
-    // Send a command and receive a response to/from effect engine.
-    virtual status_t command(uint32_t cmdCode, uint32_t cmdSize, void *pCmdData,
-            uint32_t *replySize, void *pReplyData);
-
-    // Returns the effect descriptor.
-    virtual status_t getDescriptor(effect_descriptor_t *pDescriptor);
-
-    // Free resources on the remote side.
-    virtual status_t close();
-
-    // Whether it's a local implementation.
-    virtual bool isLocal() const { return false; }
-
-    uint64_t effectId() const { return mEffectId; }
-
-    static void effectDescriptorToHal(
-            const EffectDescriptor& descriptor, effect_descriptor_t* halDescriptor);
-
-  private:
-    friend class EffectsFactoryHalHidl;
-    typedef MessageQueue<
-        hardware::audio::effect::V2_0::Result, hardware::kSynchronizedReadWrite> StatusMQ;
-
-    sp<IEffect> mEffect;
-    const uint64_t mEffectId;
-    sp<EffectBufferHalInterface> mInBuffer;
-    sp<EffectBufferHalInterface> mOutBuffer;
-    bool mBuffersChanged;
-    std::unique_ptr<StatusMQ> mStatusMQ;
-    EventFlag* mEfGroup;
-
-    static status_t analyzeResult(const hardware::audio::effect::V2_0::Result& result);
-    static void effectBufferConfigFromHal(
-            const buffer_config_t& halConfig, EffectBufferConfig* config);
-    static void effectBufferConfigToHal(
-            const EffectBufferConfig& config, buffer_config_t* halConfig);
-    static void effectConfigFromHal(const effect_config_t& halConfig, EffectConfig* config);
-    static void effectConfigToHal(const EffectConfig& config, effect_config_t* halConfig);
-
-    // Can not be constructed directly by clients.
-    EffectHalHidl(const sp<IEffect>& effect, uint64_t effectId);
-
-    // The destructor automatically releases the effect.
-    virtual ~EffectHalHidl();
-
-    status_t getConfigImpl(uint32_t cmdCode, uint32_t *replySize, void *pReplyData);
-    status_t prepareForProcessing();
-    bool needToResetBuffers();
-    status_t processImpl(uint32_t mqFlag);
-    status_t setConfigImpl(
-            uint32_t cmdCode, uint32_t cmdSize, void *pCmdData,
-            uint32_t *replySize, void *pReplyData);
-    status_t setProcessBuffers();
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_EFFECT_HAL_HIDL_H
diff --git a/media/libaudiohal/2.0/EffectsFactoryHalHidl.cpp b/media/libaudiohal/2.0/EffectsFactoryHalHidl.cpp
deleted file mode 100644
index 0d40e6d..0000000
--- a/media/libaudiohal/2.0/EffectsFactoryHalHidl.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "EffectsFactoryHalHidl"
-//#define LOG_NDEBUG 0
-
-#include <cutils/native_handle.h>
-
-#include "ConversionHelperHidl.h"
-#include "EffectBufferHalHidl.h"
-#include "EffectHalHidl.h"
-#include "EffectsFactoryHalHidl.h"
-#include "HidlUtils.h"
-
-using ::android::hardware::audio::common::V2_0::HidlUtils;
-using ::android::hardware::audio::common::V2_0::Uuid;
-using ::android::hardware::audio::effect::V2_0::IEffect;
-using ::android::hardware::audio::effect::V2_0::Result;
-using ::android::hardware::Return;
-
-namespace android {
-
-EffectsFactoryHalHidl::EffectsFactoryHalHidl() : ConversionHelperHidl("EffectsFactory") {
-    mEffectsFactory = IEffectsFactory::getService();
-    if (mEffectsFactory == 0) {
-        ALOGE("Failed to obtain IEffectsFactory service, terminating process.");
-        exit(1);
-    }
-}
-
-EffectsFactoryHalHidl::~EffectsFactoryHalHidl() {
-}
-
-status_t EffectsFactoryHalHidl::queryAllDescriptors() {
-    if (mEffectsFactory == 0) return NO_INIT;
-    Result retval = Result::NOT_INITIALIZED;
-    Return<void> ret = mEffectsFactory->getAllDescriptors(
-            [&](Result r, const hidl_vec<EffectDescriptor>& result) {
-                retval = r;
-                if (retval == Result::OK) {
-                    mLastDescriptors = result;
-                }
-            });
-    if (ret.isOk()) {
-        return retval == Result::OK ? OK : NO_INIT;
-    }
-    mLastDescriptors.resize(0);
-    return processReturn(__FUNCTION__, ret);
-}
-
-status_t EffectsFactoryHalHidl::queryNumberEffects(uint32_t *pNumEffects) {
-    status_t queryResult = queryAllDescriptors();
-    if (queryResult == OK) {
-        *pNumEffects = mLastDescriptors.size();
-    }
-    return queryResult;
-}
-
-status_t EffectsFactoryHalHidl::getDescriptor(
-        uint32_t index, effect_descriptor_t *pDescriptor) {
-    // TODO: We need somehow to track the changes on the server side
-    // or figure out how to convert everybody to query all the descriptors at once.
-    // TODO: check for nullptr
-    if (mLastDescriptors.size() == 0) {
-        status_t queryResult = queryAllDescriptors();
-        if (queryResult != OK) return queryResult;
-    }
-    if (index >= mLastDescriptors.size()) return NAME_NOT_FOUND;
-    EffectHalHidl::effectDescriptorToHal(mLastDescriptors[index], pDescriptor);
-    return OK;
-}
-
-status_t EffectsFactoryHalHidl::getDescriptor(
-        const effect_uuid_t *pEffectUuid, effect_descriptor_t *pDescriptor) {
-    // TODO: check for nullptr
-    if (mEffectsFactory == 0) return NO_INIT;
-    Uuid hidlUuid;
-    HidlUtils::uuidFromHal(*pEffectUuid, &hidlUuid);
-    Result retval = Result::NOT_INITIALIZED;
-    Return<void> ret = mEffectsFactory->getDescriptor(hidlUuid,
-            [&](Result r, const EffectDescriptor& result) {
-                retval = r;
-                if (retval == Result::OK) {
-                    EffectHalHidl::effectDescriptorToHal(result, pDescriptor);
-                }
-            });
-    if (ret.isOk()) {
-        if (retval == Result::OK) return OK;
-        else if (retval == Result::INVALID_ARGUMENTS) return NAME_NOT_FOUND;
-        else return NO_INIT;
-    }
-    return processReturn(__FUNCTION__, ret);
-}
-
-status_t EffectsFactoryHalHidl::createEffect(
-        const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t ioId,
-        sp<EffectHalInterface> *effect) {
-    if (mEffectsFactory == 0) return NO_INIT;
-    Uuid hidlUuid;
-    HidlUtils::uuidFromHal(*pEffectUuid, &hidlUuid);
-    Result retval = Result::NOT_INITIALIZED;
-    Return<void> ret = mEffectsFactory->createEffect(
-            hidlUuid, sessionId, ioId,
-            [&](Result r, const sp<IEffect>& result, uint64_t effectId) {
-                retval = r;
-                if (retval == Result::OK) {
-                    *effect = new EffectHalHidl(result, effectId);
-                }
-            });
-    if (ret.isOk()) {
-        if (retval == Result::OK) return OK;
-        else if (retval == Result::INVALID_ARGUMENTS) return NAME_NOT_FOUND;
-        else return NO_INIT;
-    }
-    return processReturn(__FUNCTION__, ret);
-}
-
-status_t EffectsFactoryHalHidl::dumpEffects(int fd) {
-    if (mEffectsFactory == 0) return NO_INIT;
-    native_handle_t* hidlHandle = native_handle_create(1, 0);
-    hidlHandle->data[0] = fd;
-    Return<void> ret = mEffectsFactory->debugDump(hidlHandle);
-    native_handle_delete(hidlHandle);
-    return processReturn(__FUNCTION__, ret);
-}
-
-status_t EffectsFactoryHalHidl::allocateBuffer(size_t size, sp<EffectBufferHalInterface>* buffer) {
-    return EffectBufferHalHidl::allocate(size, buffer);
-}
-
-status_t EffectsFactoryHalHidl::mirrorBuffer(void* external, size_t size,
-                          sp<EffectBufferHalInterface>* buffer) {
-    return EffectBufferHalHidl::mirror(external, size, buffer);
-}
-
-
-} // namespace android
diff --git a/media/libaudiohal/2.0/EffectsFactoryHalHidl.h b/media/libaudiohal/2.0/EffectsFactoryHalHidl.h
deleted file mode 100644
index 82b5481..0000000
--- a/media/libaudiohal/2.0/EffectsFactoryHalHidl.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_EFFECTS_FACTORY_HAL_HIDL_H
-#define ANDROID_HARDWARE_EFFECTS_FACTORY_HAL_HIDL_H
-
-#include <android/hardware/audio/effect/2.0/IEffectsFactory.h>
-#include <android/hardware/audio/effect/2.0/types.h>
-#include <media/audiohal/EffectsFactoryHalInterface.h>
-
-#include "ConversionHelperHidl.h"
-
-namespace android {
-
-using ::android::hardware::audio::effect::V2_0::EffectDescriptor;
-using ::android::hardware::audio::effect::V2_0::IEffectsFactory;
-using ::android::hardware::hidl_vec;
-
-class EffectsFactoryHalHidl : public EffectsFactoryHalInterface, public ConversionHelperHidl
-{
-  public:
-    // Returns the number of different effects in all loaded libraries.
-    virtual status_t queryNumberEffects(uint32_t *pNumEffects);
-
-    // Returns a descriptor of the next available effect.
-    virtual status_t getDescriptor(uint32_t index,
-            effect_descriptor_t *pDescriptor);
-
-    virtual status_t getDescriptor(const effect_uuid_t *pEffectUuid,
-            effect_descriptor_t *pDescriptor);
-
-    // Creates an effect engine of the specified type.
-    // To release the effect engine, it is necessary to release references
-    // to the returned effect object.
-    virtual status_t createEffect(const effect_uuid_t *pEffectUuid,
-            int32_t sessionId, int32_t ioId,
-            sp<EffectHalInterface> *effect);
-
-    virtual status_t dumpEffects(int fd);
-
-    status_t allocateBuffer(size_t size, sp<EffectBufferHalInterface>* buffer) override;
-    status_t mirrorBuffer(void* external, size_t size,
-                          sp<EffectBufferHalInterface>* buffer) override;
-
-  private:
-    friend class EffectsFactoryHalInterface;
-
-    sp<IEffectsFactory> mEffectsFactory;
-    hidl_vec<EffectDescriptor> mLastDescriptors;
-
-    // Can not be constructed directly by clients.
-    EffectsFactoryHalHidl();
-    virtual ~EffectsFactoryHalHidl();
-
-    status_t queryAllDescriptors();
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_EFFECTS_FACTORY_HAL_HIDL_H
diff --git a/media/libaudiohal/2.0/StreamHalHidl.cpp b/media/libaudiohal/2.0/StreamHalHidl.cpp
deleted file mode 100644
index 9869cd2..0000000
--- a/media/libaudiohal/2.0/StreamHalHidl.cpp
+++ /dev/null
@@ -1,768 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "StreamHalHidl"
-//#define LOG_NDEBUG 0
-
-#include <android/hardware/audio/2.0/IStreamOutCallback.h>
-#include <hwbinder/IPCThreadState.h>
-#include <mediautils/SchedulingPolicyService.h>
-#include <utils/Log.h>
-
-#include "DeviceHalHidl.h"
-#include "EffectHalHidl.h"
-#include "StreamHalHidl.h"
-
-using ::android::hardware::audio::common::V2_0::AudioChannelMask;
-using ::android::hardware::audio::common::V2_0::AudioFormat;
-using ::android::hardware::audio::common::V2_0::ThreadInfo;
-using ::android::hardware::audio::V2_0::AudioDrain;
-using ::android::hardware::audio::V2_0::IStreamOutCallback;
-using ::android::hardware::audio::V2_0::MessageQueueFlagBits;
-using ::android::hardware::audio::V2_0::MmapBufferInfo;
-using ::android::hardware::audio::V2_0::MmapPosition;
-using ::android::hardware::audio::V2_0::ParameterValue;
-using ::android::hardware::audio::V2_0::Result;
-using ::android::hardware::audio::V2_0::TimeSpec;
-using ::android::hardware::MQDescriptorSync;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ReadCommand = ::android::hardware::audio::V2_0::IStreamIn::ReadCommand;
-
-namespace android {
-
-StreamHalHidl::StreamHalHidl(IStream *stream)
-        : ConversionHelperHidl("Stream"),
-          mStream(stream),
-          mHalThreadPriority(HAL_THREAD_PRIORITY_DEFAULT),
-          mCachedBufferSize(0){
-
-    // Instrument audio signal power logging.
-    // Note: This assumes channel mask, format, and sample rate do not change after creation.
-    if (mStream != nullptr && mStreamPowerLog.isUserDebugOrEngBuild()) {
-        // Obtain audio properties (see StreamHalHidl::getAudioProperties() below).
-        Return<void> ret = mStream->getAudioProperties(
-                [&](uint32_t sr, AudioChannelMask m, AudioFormat f) {
-                mStreamPowerLog.init(sr,
-                        static_cast<audio_channel_mask_t>(m),
-                        static_cast<audio_format_t>(f));
-            });
-    }
-}
-
-StreamHalHidl::~StreamHalHidl() {
-    mStream = nullptr;
-}
-
-status_t StreamHalHidl::getSampleRate(uint32_t *rate) {
-    if (!mStream) return NO_INIT;
-    return processReturn("getSampleRate", mStream->getSampleRate(), rate);
-}
-
-status_t StreamHalHidl::getBufferSize(size_t *size) {
-    if (!mStream) return NO_INIT;
-    status_t status = processReturn("getBufferSize", mStream->getBufferSize(), size);
-    if (status == OK) {
-        mCachedBufferSize = *size;
-    }
-    return status;
-}
-
-status_t StreamHalHidl::getChannelMask(audio_channel_mask_t *mask) {
-    if (!mStream) return NO_INIT;
-    return processReturn("getChannelMask", mStream->getChannelMask(), mask);
-}
-
-status_t StreamHalHidl::getFormat(audio_format_t *format) {
-    if (!mStream) return NO_INIT;
-    return processReturn("getFormat", mStream->getFormat(), format);
-}
-
-status_t StreamHalHidl::getAudioProperties(
-        uint32_t *sampleRate, audio_channel_mask_t *mask, audio_format_t *format) {
-    if (!mStream) return NO_INIT;
-    Return<void> ret = mStream->getAudioProperties(
-            [&](uint32_t sr, AudioChannelMask m, AudioFormat f) {
-                *sampleRate = sr;
-                *mask = static_cast<audio_channel_mask_t>(m);
-                *format = static_cast<audio_format_t>(f);
-            });
-    return processReturn("getAudioProperties", ret);
-}
-
-status_t StreamHalHidl::setParameters(const String8& kvPairs) {
-    if (!mStream) return NO_INIT;
-    hidl_vec<ParameterValue> hidlParams;
-    status_t status = parametersFromHal(kvPairs, &hidlParams);
-    if (status != OK) return status;
-    return processReturn("setParameters", mStream->setParameters(hidlParams));
-}
-
-status_t StreamHalHidl::getParameters(const String8& keys, String8 *values) {
-    values->clear();
-    if (!mStream) return NO_INIT;
-    hidl_vec<hidl_string> hidlKeys;
-    status_t status = keysFromHal(keys, &hidlKeys);
-    if (status != OK) return status;
-    Result retval;
-    Return<void> ret = mStream->getParameters(
-            hidlKeys,
-            [&](Result r, const hidl_vec<ParameterValue>& parameters) {
-                retval = r;
-                if (retval == Result::OK) {
-                    parametersToHal(parameters, values);
-                }
-            });
-    return processReturn("getParameters", ret, retval);
-}
-
-status_t StreamHalHidl::addEffect(sp<EffectHalInterface> effect) {
-    if (!mStream) return NO_INIT;
-    return processReturn("addEffect", mStream->addEffect(
-                    static_cast<EffectHalHidl*>(effect.get())->effectId()));
-}
-
-status_t StreamHalHidl::removeEffect(sp<EffectHalInterface> effect) {
-    if (!mStream) return NO_INIT;
-    return processReturn("removeEffect", mStream->removeEffect(
-                    static_cast<EffectHalHidl*>(effect.get())->effectId()));
-}
-
-status_t StreamHalHidl::standby() {
-    if (!mStream) return NO_INIT;
-    return processReturn("standby", mStream->standby());
-}
-
-status_t StreamHalHidl::dump(int fd) {
-    if (!mStream) return NO_INIT;
-    native_handle_t* hidlHandle = native_handle_create(1, 0);
-    hidlHandle->data[0] = fd;
-    Return<void> ret = mStream->debugDump(hidlHandle);
-    native_handle_delete(hidlHandle);
-    mStreamPowerLog.dump(fd);
-    return processReturn("dump", ret);
-}
-
-status_t StreamHalHidl::start() {
-    if (!mStream) return NO_INIT;
-    return processReturn("start", mStream->start());
-}
-
-status_t StreamHalHidl::stop() {
-    if (!mStream) return NO_INIT;
-    return processReturn("stop", mStream->stop());
-}
-
-status_t StreamHalHidl::createMmapBuffer(int32_t minSizeFrames,
-                                  struct audio_mmap_buffer_info *info) {
-    Result retval;
-    Return<void> ret = mStream->createMmapBuffer(
-            minSizeFrames,
-            [&](Result r, const MmapBufferInfo& hidlInfo) {
-                retval = r;
-                if (retval == Result::OK) {
-                    const native_handle *handle = hidlInfo.sharedMemory.handle();
-                    if (handle->numFds > 0) {
-                        info->shared_memory_fd = handle->data[0];
-                        info->buffer_size_frames = hidlInfo.bufferSizeFrames;
-                        info->burst_size_frames = hidlInfo.burstSizeFrames;
-                        // info->shared_memory_address is not needed in HIDL context
-                        info->shared_memory_address = NULL;
-                    } else {
-                        retval = Result::NOT_INITIALIZED;
-                    }
-                }
-            });
-    return processReturn("createMmapBuffer", ret, retval);
-}
-
-status_t StreamHalHidl::getMmapPosition(struct audio_mmap_position *position) {
-    Result retval;
-    Return<void> ret = mStream->getMmapPosition(
-            [&](Result r, const MmapPosition& hidlPosition) {
-                retval = r;
-                if (retval == Result::OK) {
-                    position->time_nanoseconds = hidlPosition.timeNanoseconds;
-                    position->position_frames = hidlPosition.positionFrames;
-                }
-            });
-    return processReturn("getMmapPosition", ret, retval);
-}
-
-status_t StreamHalHidl::setHalThreadPriority(int priority) {
-    mHalThreadPriority = priority;
-    return OK;
-}
-
-status_t StreamHalHidl::getCachedBufferSize(size_t *size) {
-    if (mCachedBufferSize != 0) {
-        *size = mCachedBufferSize;
-        return OK;
-    }
-    return getBufferSize(size);
-}
-
-bool StreamHalHidl::requestHalThreadPriority(pid_t threadPid, pid_t threadId) {
-    if (mHalThreadPriority == HAL_THREAD_PRIORITY_DEFAULT) {
-        return true;
-    }
-    int err = requestPriority(
-            threadPid, threadId,
-            mHalThreadPriority, false /*isForApp*/, true /*asynchronous*/);
-    ALOGE_IF(err, "failed to set priority %d for pid %d tid %d; error %d",
-            mHalThreadPriority, threadPid, threadId, err);
-    // Audio will still work, but latency will be higher and sometimes unacceptable.
-    return err == 0;
-}
-
-namespace {
-
-/* Notes on callback ownership.
-
-This is how (Hw)Binder ownership model looks like. The server implementation
-is owned by Binder framework (via sp<>). Proxies are owned by clients.
-When the last proxy disappears, Binder framework releases the server impl.
-
-Thus, it is not needed to keep any references to StreamOutCallback (this is
-the server impl) -- it will live as long as HAL server holds a strong ref to
-IStreamOutCallback proxy. We clear that reference by calling 'clearCallback'
-from the destructor of StreamOutHalHidl.
-
-The callback only keeps a weak reference to the stream. The stream is owned
-by AudioFlinger.
-
-*/
-
-struct StreamOutCallback : public IStreamOutCallback {
-    StreamOutCallback(const wp<StreamOutHalHidl>& stream) : mStream(stream) {}
-
-    // IStreamOutCallback implementation
-    Return<void> onWriteReady()  override {
-        sp<StreamOutHalHidl> stream = mStream.promote();
-        if (stream != 0) {
-            stream->onWriteReady();
-        }
-        return Void();
-    }
-
-    Return<void> onDrainReady()  override {
-        sp<StreamOutHalHidl> stream = mStream.promote();
-        if (stream != 0) {
-            stream->onDrainReady();
-        }
-        return Void();
-    }
-
-    Return<void> onError()  override {
-        sp<StreamOutHalHidl> stream = mStream.promote();
-        if (stream != 0) {
-            stream->onError();
-        }
-        return Void();
-    }
-
-  private:
-    wp<StreamOutHalHidl> mStream;
-};
-
-}  // namespace
-
-StreamOutHalHidl::StreamOutHalHidl(const sp<IStreamOut>& stream)
-        : StreamHalHidl(stream.get()), mStream(stream), mWriterClient(0), mEfGroup(nullptr) {
-}
-
-StreamOutHalHidl::~StreamOutHalHidl() {
-    if (mStream != 0) {
-        if (mCallback.unsafe_get()) {
-            processReturn("clearCallback", mStream->clearCallback());
-        }
-        processReturn("close", mStream->close());
-        mStream.clear();
-    }
-    mCallback.clear();
-    hardware::IPCThreadState::self()->flushCommands();
-    if (mEfGroup) {
-        EventFlag::deleteEventFlag(&mEfGroup);
-    }
-}
-
-status_t StreamOutHalHidl::getFrameSize(size_t *size) {
-    if (mStream == 0) return NO_INIT;
-    return processReturn("getFrameSize", mStream->getFrameSize(), size);
-}
-
-status_t StreamOutHalHidl::getLatency(uint32_t *latency) {
-    if (mStream == 0) return NO_INIT;
-    if (mWriterClient == gettid() && mCommandMQ) {
-        return callWriterThread(
-                WriteCommand::GET_LATENCY, "getLatency", nullptr, 0,
-                [&](const WriteStatus& writeStatus) {
-                    *latency = writeStatus.reply.latencyMs;
-                });
-    } else {
-        return processReturn("getLatency", mStream->getLatency(), latency);
-    }
-}
-
-status_t StreamOutHalHidl::setVolume(float left, float right) {
-    if (mStream == 0) return NO_INIT;
-    return processReturn("setVolume", mStream->setVolume(left, right));
-}
-
-status_t StreamOutHalHidl::write(const void *buffer, size_t bytes, size_t *written) {
-    if (mStream == 0) return NO_INIT;
-    *written = 0;
-
-    if (bytes == 0 && !mDataMQ) {
-        // Can't determine the size for the MQ buffer. Wait for a non-empty write request.
-        ALOGW_IF(mCallback.unsafe_get(), "First call to async write with 0 bytes");
-        return OK;
-    }
-
-    status_t status;
-    if (!mDataMQ) {
-        // In case if playback starts close to the end of a compressed track, the bytes
-        // that need to be written is less than the actual buffer size. Need to use
-        // full buffer size for the MQ since otherwise after seeking back to the middle
-        // data will be truncated.
-        size_t bufferSize;
-        if ((status = getCachedBufferSize(&bufferSize)) != OK) {
-            return status;
-        }
-        if (bytes > bufferSize) bufferSize = bytes;
-        if ((status = prepareForWriting(bufferSize)) != OK) {
-            return status;
-        }
-    }
-
-    status = callWriterThread(
-            WriteCommand::WRITE, "write", static_cast<const uint8_t*>(buffer), bytes,
-            [&] (const WriteStatus& writeStatus) {
-                *written = writeStatus.reply.written;
-                // Diagnostics of the cause of b/35813113.
-                ALOGE_IF(*written > bytes,
-                        "hal reports more bytes written than asked for: %lld > %lld",
-                        (long long)*written, (long long)bytes);
-            });
-    mStreamPowerLog.log(buffer, *written);
-    return status;
-}
-
-status_t StreamOutHalHidl::callWriterThread(
-        WriteCommand cmd, const char* cmdName,
-        const uint8_t* data, size_t dataSize, StreamOutHalHidl::WriterCallback callback) {
-    if (!mCommandMQ->write(&cmd)) {
-        ALOGE("command message queue write failed for \"%s\"", cmdName);
-        return -EAGAIN;
-    }
-    if (data != nullptr) {
-        size_t availableToWrite = mDataMQ->availableToWrite();
-        if (dataSize > availableToWrite) {
-            ALOGW("truncating write data from %lld to %lld due to insufficient data queue space",
-                    (long long)dataSize, (long long)availableToWrite);
-            dataSize = availableToWrite;
-        }
-        if (!mDataMQ->write(data, dataSize)) {
-            ALOGE("data message queue write failed for \"%s\"", cmdName);
-        }
-    }
-    mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY));
-
-    // TODO: Remove manual event flag handling once blocking MQ is implemented. b/33815422
-    uint32_t efState = 0;
-retry:
-    status_t ret = mEfGroup->wait(static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL), &efState);
-    if (efState & static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL)) {
-        WriteStatus writeStatus;
-        writeStatus.retval = Result::NOT_INITIALIZED;
-        if (!mStatusMQ->read(&writeStatus)) {
-            ALOGE("status message read failed for \"%s\"", cmdName);
-        }
-        if (writeStatus.retval == Result::OK) {
-            ret = OK;
-            callback(writeStatus);
-        } else {
-            ret = processReturn(cmdName, writeStatus.retval);
-        }
-        return ret;
-    }
-    if (ret == -EAGAIN || ret == -EINTR) {
-        // Spurious wakeup. This normally retries no more than once.
-        goto retry;
-    }
-    return ret;
-}
-
-status_t StreamOutHalHidl::prepareForWriting(size_t bufferSize) {
-    std::unique_ptr<CommandMQ> tempCommandMQ;
-    std::unique_ptr<DataMQ> tempDataMQ;
-    std::unique_ptr<StatusMQ> tempStatusMQ;
-    Result retval;
-    pid_t halThreadPid, halThreadTid;
-    Return<void> ret = mStream->prepareForWriting(
-            1, bufferSize,
-            [&](Result r,
-                    const CommandMQ::Descriptor& commandMQ,
-                    const DataMQ::Descriptor& dataMQ,
-                    const StatusMQ::Descriptor& statusMQ,
-                    const ThreadInfo& halThreadInfo) {
-                retval = r;
-                if (retval == Result::OK) {
-                    tempCommandMQ.reset(new CommandMQ(commandMQ));
-                    tempDataMQ.reset(new DataMQ(dataMQ));
-                    tempStatusMQ.reset(new StatusMQ(statusMQ));
-                    if (tempDataMQ->isValid() && tempDataMQ->getEventFlagWord()) {
-                        EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &mEfGroup);
-                    }
-                    halThreadPid = halThreadInfo.pid;
-                    halThreadTid = halThreadInfo.tid;
-                }
-            });
-    if (!ret.isOk() || retval != Result::OK) {
-        return processReturn("prepareForWriting", ret, retval);
-    }
-    if (!tempCommandMQ || !tempCommandMQ->isValid() ||
-            !tempDataMQ || !tempDataMQ->isValid() ||
-            !tempStatusMQ || !tempStatusMQ->isValid() ||
-            !mEfGroup) {
-        ALOGE_IF(!tempCommandMQ, "Failed to obtain command message queue for writing");
-        ALOGE_IF(tempCommandMQ && !tempCommandMQ->isValid(),
-                "Command message queue for writing is invalid");
-        ALOGE_IF(!tempDataMQ, "Failed to obtain data message queue for writing");
-        ALOGE_IF(tempDataMQ && !tempDataMQ->isValid(), "Data message queue for writing is invalid");
-        ALOGE_IF(!tempStatusMQ, "Failed to obtain status message queue for writing");
-        ALOGE_IF(tempStatusMQ && !tempStatusMQ->isValid(),
-                "Status message queue for writing is invalid");
-        ALOGE_IF(!mEfGroup, "Event flag creation for writing failed");
-        return NO_INIT;
-    }
-    requestHalThreadPriority(halThreadPid, halThreadTid);
-
-    mCommandMQ = std::move(tempCommandMQ);
-    mDataMQ = std::move(tempDataMQ);
-    mStatusMQ = std::move(tempStatusMQ);
-    mWriterClient = gettid();
-    return OK;
-}
-
-status_t StreamOutHalHidl::getRenderPosition(uint32_t *dspFrames) {
-    if (mStream == 0) return NO_INIT;
-    Result retval;
-    Return<void> ret = mStream->getRenderPosition(
-            [&](Result r, uint32_t d) {
-                retval = r;
-                if (retval == Result::OK) {
-                    *dspFrames = d;
-                }
-            });
-    return processReturn("getRenderPosition", ret, retval);
-}
-
-status_t StreamOutHalHidl::getNextWriteTimestamp(int64_t *timestamp) {
-    if (mStream == 0) return NO_INIT;
-    Result retval;
-    Return<void> ret = mStream->getNextWriteTimestamp(
-            [&](Result r, int64_t t) {
-                retval = r;
-                if (retval == Result::OK) {
-                    *timestamp = t;
-                }
-            });
-    return processReturn("getRenderPosition", ret, retval);
-}
-
-status_t StreamOutHalHidl::setCallback(wp<StreamOutHalInterfaceCallback> callback) {
-    if (mStream == 0) return NO_INIT;
-    status_t status = processReturn(
-            "setCallback", mStream->setCallback(new StreamOutCallback(this)));
-    if (status == OK) {
-        mCallback = callback;
-    }
-    return status;
-}
-
-status_t StreamOutHalHidl::supportsPauseAndResume(bool *supportsPause, bool *supportsResume) {
-    if (mStream == 0) return NO_INIT;
-    Return<void> ret = mStream->supportsPauseAndResume(
-            [&](bool p, bool r) {
-                *supportsPause = p;
-                *supportsResume = r;
-            });
-    return processReturn("supportsPauseAndResume", ret);
-}
-
-status_t StreamOutHalHidl::pause() {
-    if (mStream == 0) return NO_INIT;
-    return processReturn("pause", mStream->pause());
-}
-
-status_t StreamOutHalHidl::resume() {
-    if (mStream == 0) return NO_INIT;
-    return processReturn("pause", mStream->resume());
-}
-
-status_t StreamOutHalHidl::supportsDrain(bool *supportsDrain) {
-    if (mStream == 0) return NO_INIT;
-    return processReturn("supportsDrain", mStream->supportsDrain(), supportsDrain);
-}
-
-status_t StreamOutHalHidl::drain(bool earlyNotify) {
-    if (mStream == 0) return NO_INIT;
-    return processReturn(
-            "drain", mStream->drain(earlyNotify ? AudioDrain::EARLY_NOTIFY : AudioDrain::ALL));
-}
-
-status_t StreamOutHalHidl::flush() {
-    if (mStream == 0) return NO_INIT;
-    return processReturn("pause", mStream->flush());
-}
-
-status_t StreamOutHalHidl::getPresentationPosition(uint64_t *frames, struct timespec *timestamp) {
-    if (mStream == 0) return NO_INIT;
-    if (mWriterClient == gettid() && mCommandMQ) {
-        return callWriterThread(
-                WriteCommand::GET_PRESENTATION_POSITION, "getPresentationPosition", nullptr, 0,
-                [&](const WriteStatus& writeStatus) {
-                    *frames = writeStatus.reply.presentationPosition.frames;
-                    timestamp->tv_sec = writeStatus.reply.presentationPosition.timeStamp.tvSec;
-                    timestamp->tv_nsec = writeStatus.reply.presentationPosition.timeStamp.tvNSec;
-                });
-    } else {
-        Result retval;
-        Return<void> ret = mStream->getPresentationPosition(
-                [&](Result r, uint64_t hidlFrames, const TimeSpec& hidlTimeStamp) {
-                    retval = r;
-                    if (retval == Result::OK) {
-                        *frames = hidlFrames;
-                        timestamp->tv_sec = hidlTimeStamp.tvSec;
-                        timestamp->tv_nsec = hidlTimeStamp.tvNSec;
-                    }
-                });
-        return processReturn("getPresentationPosition", ret, retval);
-    }
-}
-
-status_t StreamOutHalHidl::updateSourceMetadata(const SourceMetadata& /* sourceMetadata */) {
-    // Audio HAL V2.0 does not support propagating source metadata
-    return INVALID_OPERATION;
-}
-
-void StreamOutHalHidl::onWriteReady() {
-    sp<StreamOutHalInterfaceCallback> callback = mCallback.promote();
-    if (callback == 0) return;
-    ALOGV("asyncCallback onWriteReady");
-    callback->onWriteReady();
-}
-
-void StreamOutHalHidl::onDrainReady() {
-    sp<StreamOutHalInterfaceCallback> callback = mCallback.promote();
-    if (callback == 0) return;
-    ALOGV("asyncCallback onDrainReady");
-    callback->onDrainReady();
-}
-
-void StreamOutHalHidl::onError() {
-    sp<StreamOutHalInterfaceCallback> callback = mCallback.promote();
-    if (callback == 0) return;
-    ALOGV("asyncCallback onError");
-    callback->onError();
-}
-
-
-StreamInHalHidl::StreamInHalHidl(const sp<IStreamIn>& stream)
-        : StreamHalHidl(stream.get()), mStream(stream), mReaderClient(0), mEfGroup(nullptr) {
-}
-
-StreamInHalHidl::~StreamInHalHidl() {
-    if (mStream != 0) {
-        processReturn("close", mStream->close());
-        mStream.clear();
-        hardware::IPCThreadState::self()->flushCommands();
-    }
-    if (mEfGroup) {
-        EventFlag::deleteEventFlag(&mEfGroup);
-    }
-}
-
-status_t StreamInHalHidl::getFrameSize(size_t *size) {
-    if (mStream == 0) return NO_INIT;
-    return processReturn("getFrameSize", mStream->getFrameSize(), size);
-}
-
-status_t StreamInHalHidl::setGain(float gain) {
-    if (mStream == 0) return NO_INIT;
-    return processReturn("setGain", mStream->setGain(gain));
-}
-
-status_t StreamInHalHidl::read(void *buffer, size_t bytes, size_t *read) {
-    if (mStream == 0) return NO_INIT;
-    *read = 0;
-
-    if (bytes == 0 && !mDataMQ) {
-        // Can't determine the size for the MQ buffer. Wait for a non-empty read request.
-        return OK;
-    }
-
-    status_t status;
-    if (!mDataMQ && (status = prepareForReading(bytes)) != OK) {
-        return status;
-    }
-
-    ReadParameters params;
-    params.command = ReadCommand::READ;
-    params.params.read = bytes;
-    status = callReaderThread(params, "read",
-            [&](const ReadStatus& readStatus) {
-                const size_t availToRead = mDataMQ->availableToRead();
-                if (!mDataMQ->read(static_cast<uint8_t*>(buffer), std::min(bytes, availToRead))) {
-                    ALOGE("data message queue read failed for \"read\"");
-                }
-                ALOGW_IF(availToRead != readStatus.reply.read,
-                        "HAL read report inconsistent: mq = %d, status = %d",
-                        (int32_t)availToRead, (int32_t)readStatus.reply.read);
-                *read = readStatus.reply.read;
-            });
-    mStreamPowerLog.log(buffer, *read);
-    return status;
-}
-
-status_t StreamInHalHidl::callReaderThread(
-        const ReadParameters& params, const char* cmdName,
-        StreamInHalHidl::ReaderCallback callback) {
-    if (!mCommandMQ->write(&params)) {
-        ALOGW("command message queue write failed");
-        return -EAGAIN;
-    }
-    mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL));
-
-    // TODO: Remove manual event flag handling once blocking MQ is implemented. b/33815422
-    uint32_t efState = 0;
-retry:
-    status_t ret = mEfGroup->wait(static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY), &efState);
-    if (efState & static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY)) {
-        ReadStatus readStatus;
-        readStatus.retval = Result::NOT_INITIALIZED;
-        if (!mStatusMQ->read(&readStatus)) {
-            ALOGE("status message read failed for \"%s\"", cmdName);
-        }
-         if (readStatus.retval == Result::OK) {
-            ret = OK;
-            callback(readStatus);
-        } else {
-            ret = processReturn(cmdName, readStatus.retval);
-        }
-        return ret;
-    }
-    if (ret == -EAGAIN || ret == -EINTR) {
-        // Spurious wakeup. This normally retries no more than once.
-        goto retry;
-    }
-    return ret;
-}
-
-status_t StreamInHalHidl::prepareForReading(size_t bufferSize) {
-    std::unique_ptr<CommandMQ> tempCommandMQ;
-    std::unique_ptr<DataMQ> tempDataMQ;
-    std::unique_ptr<StatusMQ> tempStatusMQ;
-    Result retval;
-    pid_t halThreadPid, halThreadTid;
-    Return<void> ret = mStream->prepareForReading(
-            1, bufferSize,
-            [&](Result r,
-                    const CommandMQ::Descriptor& commandMQ,
-                    const DataMQ::Descriptor& dataMQ,
-                    const StatusMQ::Descriptor& statusMQ,
-                    const ThreadInfo& halThreadInfo) {
-                retval = r;
-                if (retval == Result::OK) {
-                    tempCommandMQ.reset(new CommandMQ(commandMQ));
-                    tempDataMQ.reset(new DataMQ(dataMQ));
-                    tempStatusMQ.reset(new StatusMQ(statusMQ));
-                    if (tempDataMQ->isValid() && tempDataMQ->getEventFlagWord()) {
-                        EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &mEfGroup);
-                    }
-                    halThreadPid = halThreadInfo.pid;
-                    halThreadTid = halThreadInfo.tid;
-                }
-            });
-    if (!ret.isOk() || retval != Result::OK) {
-        return processReturn("prepareForReading", ret, retval);
-    }
-    if (!tempCommandMQ || !tempCommandMQ->isValid() ||
-            !tempDataMQ || !tempDataMQ->isValid() ||
-            !tempStatusMQ || !tempStatusMQ->isValid() ||
-            !mEfGroup) {
-        ALOGE_IF(!tempCommandMQ, "Failed to obtain command message queue for writing");
-        ALOGE_IF(tempCommandMQ && !tempCommandMQ->isValid(),
-                "Command message queue for writing is invalid");
-        ALOGE_IF(!tempDataMQ, "Failed to obtain data message queue for reading");
-        ALOGE_IF(tempDataMQ && !tempDataMQ->isValid(), "Data message queue for reading is invalid");
-        ALOGE_IF(!tempStatusMQ, "Failed to obtain status message queue for reading");
-        ALOGE_IF(tempStatusMQ && !tempStatusMQ->isValid(),
-                "Status message queue for reading is invalid");
-        ALOGE_IF(!mEfGroup, "Event flag creation for reading failed");
-        return NO_INIT;
-    }
-    requestHalThreadPriority(halThreadPid, halThreadTid);
-
-    mCommandMQ = std::move(tempCommandMQ);
-    mDataMQ = std::move(tempDataMQ);
-    mStatusMQ = std::move(tempStatusMQ);
-    mReaderClient = gettid();
-    return OK;
-}
-
-status_t StreamInHalHidl::getInputFramesLost(uint32_t *framesLost) {
-    if (mStream == 0) return NO_INIT;
-    return processReturn("getInputFramesLost", mStream->getInputFramesLost(), framesLost);
-}
-
-status_t StreamInHalHidl::getCapturePosition(int64_t *frames, int64_t *time) {
-    if (mStream == 0) return NO_INIT;
-    if (mReaderClient == gettid() && mCommandMQ) {
-        ReadParameters params;
-        params.command = ReadCommand::GET_CAPTURE_POSITION;
-        return callReaderThread(params, "getCapturePosition",
-                [&](const ReadStatus& readStatus) {
-                    *frames = readStatus.reply.capturePosition.frames;
-                    *time = readStatus.reply.capturePosition.time;
-                });
-    } else {
-        Result retval;
-        Return<void> ret = mStream->getCapturePosition(
-                [&](Result r, uint64_t hidlFrames, uint64_t hidlTime) {
-                    retval = r;
-                    if (retval == Result::OK) {
-                        *frames = hidlFrames;
-                        *time = hidlTime;
-                    }
-                });
-        return processReturn("getCapturePosition", ret, retval);
-    }
-}
-
-status_t StreamInHalHidl::getActiveMicrophones(
-        std::vector<media::MicrophoneInfo> *microphones __unused) {
-    if (mStream == 0) return NO_INIT;
-    return INVALID_OPERATION;
-}
-
-status_t StreamInHalHidl::updateSinkMetadata(const SinkMetadata& /* sinkMetadata */) {
-    // Audio HAL V2.0 does not support propagating sink metadata
-    return INVALID_OPERATION;
-}
-
-} // namespace android
diff --git a/media/libaudiohal/2.0/StreamHalHidl.h b/media/libaudiohal/2.0/StreamHalHidl.h
deleted file mode 100644
index ebad8ae..0000000
--- a/media/libaudiohal/2.0/StreamHalHidl.h
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_STREAM_HAL_HIDL_H
-#define ANDROID_HARDWARE_STREAM_HAL_HIDL_H
-
-#include <atomic>
-
-#include <android/hardware/audio/2.0/IStream.h>
-#include <android/hardware/audio/2.0/IStreamIn.h>
-#include <android/hardware/audio/2.0/IStreamOut.h>
-#include <fmq/EventFlag.h>
-#include <fmq/MessageQueue.h>
-#include <media/audiohal/StreamHalInterface.h>
-
-#include "ConversionHelperHidl.h"
-#include "StreamPowerLog.h"
-
-using ::android::hardware::audio::V2_0::IStream;
-using ::android::hardware::audio::V2_0::IStreamIn;
-using ::android::hardware::audio::V2_0::IStreamOut;
-using ::android::hardware::EventFlag;
-using ::android::hardware::MessageQueue;
-using ::android::hardware::Return;
-using ReadParameters = ::android::hardware::audio::V2_0::IStreamIn::ReadParameters;
-using ReadStatus = ::android::hardware::audio::V2_0::IStreamIn::ReadStatus;
-using WriteCommand = ::android::hardware::audio::V2_0::IStreamOut::WriteCommand;
-using WriteStatus = ::android::hardware::audio::V2_0::IStreamOut::WriteStatus;
-
-namespace android {
-
-class DeviceHalHidl;
-
-class StreamHalHidl : public virtual StreamHalInterface, public ConversionHelperHidl
-{
-  public:
-    // Return the sampling rate in Hz - eg. 44100.
-    virtual status_t getSampleRate(uint32_t *rate);
-
-    // Return size of input/output buffer in bytes for this stream - eg. 4800.
-    virtual status_t getBufferSize(size_t *size);
-
-    // Return the channel mask.
-    virtual status_t getChannelMask(audio_channel_mask_t *mask);
-
-    // Return the audio format - e.g. AUDIO_FORMAT_PCM_16_BIT.
-    virtual status_t getFormat(audio_format_t *format);
-
-    // Convenience method.
-    virtual status_t getAudioProperties(
-            uint32_t *sampleRate, audio_channel_mask_t *mask, audio_format_t *format);
-
-    // Set audio stream parameters.
-    virtual status_t setParameters(const String8& kvPairs);
-
-    // Get audio stream parameters.
-    virtual status_t getParameters(const String8& keys, String8 *values);
-
-    // Add or remove the effect on the stream.
-    virtual status_t addEffect(sp<EffectHalInterface> effect);
-    virtual status_t removeEffect(sp<EffectHalInterface> effect);
-
-    // Put the audio hardware input/output into standby mode.
-    virtual status_t standby();
-
-    virtual status_t dump(int fd);
-
-    // Start a stream operating in mmap mode.
-    virtual status_t start();
-
-    // Stop a stream operating in mmap mode.
-    virtual status_t stop();
-
-    // Retrieve information on the data buffer in mmap mode.
-    virtual status_t createMmapBuffer(int32_t minSizeFrames,
-                                      struct audio_mmap_buffer_info *info);
-
-    // Get current read/write position in the mmap buffer
-    virtual status_t getMmapPosition(struct audio_mmap_position *position);
-
-    // Set the priority of the thread that interacts with the HAL
-    // (must match the priority of the audioflinger's thread that calls 'read' / 'write')
-    virtual status_t setHalThreadPriority(int priority);
-
-  protected:
-    // Subclasses can not be constructed directly by clients.
-    explicit StreamHalHidl(IStream *stream);
-
-    // The destructor automatically closes the stream.
-    virtual ~StreamHalHidl();
-
-    status_t getCachedBufferSize(size_t *size);
-
-    bool requestHalThreadPriority(pid_t threadPid, pid_t threadId);
-
-    // mStreamPowerLog is used for audio signal power logging.
-    StreamPowerLog mStreamPowerLog;
-
-  private:
-    const int HAL_THREAD_PRIORITY_DEFAULT = -1;
-    IStream *mStream;
-    int mHalThreadPriority;
-    size_t mCachedBufferSize;
-};
-
-class StreamOutHalHidl : public StreamOutHalInterface, public StreamHalHidl {
-  public:
-    // Return the frame size (number of bytes per sample) of a stream.
-    virtual status_t getFrameSize(size_t *size);
-
-    // Return the audio hardware driver estimated latency in milliseconds.
-    virtual status_t getLatency(uint32_t *latency);
-
-    // Use this method in situations where audio mixing is done in the hardware.
-    virtual status_t setVolume(float left, float right);
-
-    // Write audio buffer to driver.
-    virtual status_t write(const void *buffer, size_t bytes, size_t *written);
-
-    // Return the number of audio frames written by the audio dsp to DAC since
-    // the output has exited standby.
-    virtual status_t getRenderPosition(uint32_t *dspFrames);
-
-    // Get the local time at which the next write to the audio driver will be presented.
-    virtual status_t getNextWriteTimestamp(int64_t *timestamp);
-
-    // Set the callback for notifying completion of non-blocking write and drain.
-    virtual status_t setCallback(wp<StreamOutHalInterfaceCallback> callback);
-
-    // Returns whether pause and resume operations are supported.
-    virtual status_t supportsPauseAndResume(bool *supportsPause, bool *supportsResume);
-
-    // Notifies to the audio driver to resume playback following a pause.
-    virtual status_t pause();
-
-    // Notifies to the audio driver to resume playback following a pause.
-    virtual status_t resume();
-
-    // Returns whether drain operation is supported.
-    virtual status_t supportsDrain(bool *supportsDrain);
-
-    // Requests notification when data buffered by the driver/hardware has been played.
-    virtual status_t drain(bool earlyNotify);
-
-    // Notifies to the audio driver to flush the queued data.
-    virtual status_t flush();
-
-    // Return a recent count of the number of audio frames presented to an external observer.
-    virtual status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp);
-
-    // Called when the metadata of the stream's source has been changed.
-    status_t updateSourceMetadata(const SourceMetadata& sourceMetadata) override;
-
-    // Methods used by StreamOutCallback (HIDL).
-    void onWriteReady();
-    void onDrainReady();
-    void onError();
-
-  private:
-    friend class DeviceHalHidl;
-    typedef MessageQueue<WriteCommand, hardware::kSynchronizedReadWrite> CommandMQ;
-    typedef MessageQueue<uint8_t, hardware::kSynchronizedReadWrite> DataMQ;
-    typedef MessageQueue<WriteStatus, hardware::kSynchronizedReadWrite> StatusMQ;
-
-    wp<StreamOutHalInterfaceCallback> mCallback;
-    sp<IStreamOut> mStream;
-    std::unique_ptr<CommandMQ> mCommandMQ;
-    std::unique_ptr<DataMQ> mDataMQ;
-    std::unique_ptr<StatusMQ> mStatusMQ;
-    std::atomic<pid_t> mWriterClient;
-    EventFlag* mEfGroup;
-
-    // Can not be constructed directly by clients.
-    StreamOutHalHidl(const sp<IStreamOut>& stream);
-
-    virtual ~StreamOutHalHidl();
-
-    using WriterCallback = std::function<void(const WriteStatus& writeStatus)>;
-    status_t callWriterThread(
-            WriteCommand cmd, const char* cmdName,
-            const uint8_t* data, size_t dataSize, WriterCallback callback);
-    status_t prepareForWriting(size_t bufferSize);
-};
-
-class StreamInHalHidl : public StreamInHalInterface, public StreamHalHidl {
-  public:
-    // Return the frame size (number of bytes per sample) of a stream.
-    virtual status_t getFrameSize(size_t *size);
-
-    // Set the input gain for the audio driver.
-    virtual status_t setGain(float gain);
-
-    // Read audio buffer in from driver.
-    virtual status_t read(void *buffer, size_t bytes, size_t *read);
-
-    // Return the amount of input frames lost in the audio driver.
-    virtual status_t getInputFramesLost(uint32_t *framesLost);
-
-    // Return a recent count of the number of audio frames received and
-    // the clock time associated with that frame count.
-    virtual status_t getCapturePosition(int64_t *frames, int64_t *time);
-
-    // Get active microphones
-    virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones);
-
-    // Called when the metadata of the stream's sink has been changed.
-    status_t updateSinkMetadata(const SinkMetadata& sinkMetadata) override;
-
-  private:
-    friend class DeviceHalHidl;
-    typedef MessageQueue<ReadParameters, hardware::kSynchronizedReadWrite> CommandMQ;
-    typedef MessageQueue<uint8_t, hardware::kSynchronizedReadWrite> DataMQ;
-    typedef MessageQueue<ReadStatus, hardware::kSynchronizedReadWrite> StatusMQ;
-
-    sp<IStreamIn> mStream;
-    std::unique_ptr<CommandMQ> mCommandMQ;
-    std::unique_ptr<DataMQ> mDataMQ;
-    std::unique_ptr<StatusMQ> mStatusMQ;
-    std::atomic<pid_t> mReaderClient;
-    EventFlag* mEfGroup;
-
-    // Can not be constructed directly by clients.
-    StreamInHalHidl(const sp<IStreamIn>& stream);
-
-    virtual ~StreamInHalHidl();
-
-    using ReaderCallback = std::function<void(const ReadStatus& readStatus)>;
-    status_t callReaderThread(
-            const ReadParameters& params, const char* cmdName, ReaderCallback callback);
-    status_t prepareForReading(size_t bufferSize);
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_STREAM_HAL_HIDL_H
diff --git a/media/libaudiohal/2.0/StreamHalLocal.cpp b/media/libaudiohal/2.0/StreamHalLocal.cpp
deleted file mode 100644
index 98107e5..0000000
--- a/media/libaudiohal/2.0/StreamHalLocal.cpp
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "StreamHalLocal"
-//#define LOG_NDEBUG 0
-
-#include <hardware/audio.h>
-#include <utils/Log.h>
-
-#include "DeviceHalLocal.h"
-#include "StreamHalLocal.h"
-
-namespace android {
-
-StreamHalLocal::StreamHalLocal(audio_stream_t *stream, sp<DeviceHalLocal> device)
-        : mDevice(device),
-          mStream(stream) {
-    // Instrument audio signal power logging.
-    // Note: This assumes channel mask, format, and sample rate do not change after creation.
-    if (mStream != nullptr && mStreamPowerLog.isUserDebugOrEngBuild()) {
-        mStreamPowerLog.init(mStream->get_sample_rate(mStream),
-                mStream->get_channels(mStream),
-                mStream->get_format(mStream));
-    }
-}
-
-StreamHalLocal::~StreamHalLocal() {
-    mStream = 0;
-    mDevice.clear();
-}
-
-status_t StreamHalLocal::getSampleRate(uint32_t *rate) {
-    *rate = mStream->get_sample_rate(mStream);
-    return OK;
-}
-
-status_t StreamHalLocal::getBufferSize(size_t *size) {
-    *size = mStream->get_buffer_size(mStream);
-    return OK;
-}
-
-status_t StreamHalLocal::getChannelMask(audio_channel_mask_t *mask) {
-    *mask = mStream->get_channels(mStream);
-    return OK;
-}
-
-status_t StreamHalLocal::getFormat(audio_format_t *format) {
-    *format = mStream->get_format(mStream);
-    return OK;
-}
-
-status_t StreamHalLocal::getAudioProperties(
-        uint32_t *sampleRate, audio_channel_mask_t *mask, audio_format_t *format) {
-    *sampleRate = mStream->get_sample_rate(mStream);
-    *mask = mStream->get_channels(mStream);
-    *format = mStream->get_format(mStream);
-    return OK;
-}
-
-status_t StreamHalLocal::setParameters(const String8& kvPairs) {
-    return mStream->set_parameters(mStream, kvPairs.string());
-}
-
-status_t StreamHalLocal::getParameters(const String8& keys, String8 *values) {
-    char *halValues = mStream->get_parameters(mStream, keys.string());
-    if (halValues != NULL) {
-        values->setTo(halValues);
-        free(halValues);
-    } else {
-        values->clear();
-    }
-    return OK;
-}
-
-status_t StreamHalLocal::addEffect(sp<EffectHalInterface>) {
-    LOG_ALWAYS_FATAL("Local streams can not have effects");
-    return INVALID_OPERATION;
-}
-
-status_t StreamHalLocal::removeEffect(sp<EffectHalInterface>) {
-    LOG_ALWAYS_FATAL("Local streams can not have effects");
-    return INVALID_OPERATION;
-}
-
-status_t StreamHalLocal::standby() {
-    return mStream->standby(mStream);
-}
-
-status_t StreamHalLocal::dump(int fd) {
-    status_t status = mStream->dump(mStream, fd);
-    mStreamPowerLog.dump(fd);
-    return status;
-}
-
-status_t StreamHalLocal::setHalThreadPriority(int) {
-    // Don't need to do anything as local hal is executed by audioflinger directly
-    // on the same thread.
-    return OK;
-}
-
-StreamOutHalLocal::StreamOutHalLocal(audio_stream_out_t *stream, sp<DeviceHalLocal> device)
-        : StreamHalLocal(&stream->common, device), mStream(stream) {
-}
-
-StreamOutHalLocal::~StreamOutHalLocal() {
-    mCallback.clear();
-    mDevice->closeOutputStream(mStream);
-    mStream = 0;
-}
-
-status_t StreamOutHalLocal::getFrameSize(size_t *size) {
-    *size = audio_stream_out_frame_size(mStream);
-    return OK;
-}
-
-status_t StreamOutHalLocal::getLatency(uint32_t *latency) {
-    *latency = mStream->get_latency(mStream);
-    return OK;
-}
-
-status_t StreamOutHalLocal::setVolume(float left, float right) {
-    if (mStream->set_volume == NULL) return INVALID_OPERATION;
-    return mStream->set_volume(mStream, left, right);
-}
-
-status_t StreamOutHalLocal::write(const void *buffer, size_t bytes, size_t *written) {
-    ssize_t writeResult = mStream->write(mStream, buffer, bytes);
-    if (writeResult > 0) {
-        *written = writeResult;
-        mStreamPowerLog.log(buffer, *written);
-        return OK;
-    } else {
-        *written = 0;
-        return writeResult;
-    }
-}
-
-status_t StreamOutHalLocal::getRenderPosition(uint32_t *dspFrames) {
-    return mStream->get_render_position(mStream, dspFrames);
-}
-
-status_t StreamOutHalLocal::getNextWriteTimestamp(int64_t *timestamp) {
-    if (mStream->get_next_write_timestamp == NULL) return INVALID_OPERATION;
-    return mStream->get_next_write_timestamp(mStream, timestamp);
-}
-
-status_t StreamOutHalLocal::setCallback(wp<StreamOutHalInterfaceCallback> callback) {
-    if (mStream->set_callback == NULL) return INVALID_OPERATION;
-    status_t result = mStream->set_callback(mStream, StreamOutHalLocal::asyncCallback, this);
-    if (result == OK) {
-        mCallback = callback;
-    }
-    return result;
-}
-
-// static
-int StreamOutHalLocal::asyncCallback(stream_callback_event_t event, void*, void *cookie) {
-    // We act as if we gave a wp<StreamOutHalLocal> to HAL. This way we should handle
-    // correctly the case when the callback is invoked while StreamOutHalLocal's destructor is
-    // already running, because the destructor is invoked after the refcount has been atomically
-    // decremented.
-    wp<StreamOutHalLocal> weakSelf(static_cast<StreamOutHalLocal*>(cookie));
-    sp<StreamOutHalLocal> self = weakSelf.promote();
-    if (self == 0) return 0;
-    sp<StreamOutHalInterfaceCallback> callback = self->mCallback.promote();
-    if (callback == 0) return 0;
-    ALOGV("asyncCallback() event %d", event);
-    switch (event) {
-        case STREAM_CBK_EVENT_WRITE_READY:
-            callback->onWriteReady();
-            break;
-        case STREAM_CBK_EVENT_DRAIN_READY:
-            callback->onDrainReady();
-            break;
-        case STREAM_CBK_EVENT_ERROR:
-            callback->onError();
-            break;
-        default:
-            ALOGW("asyncCallback() unknown event %d", event);
-            break;
-    }
-    return 0;
-}
-
-status_t StreamOutHalLocal::supportsPauseAndResume(bool *supportsPause, bool *supportsResume) {
-    *supportsPause = mStream->pause != NULL;
-    *supportsResume = mStream->resume != NULL;
-    return OK;
-}
-
-status_t StreamOutHalLocal::pause() {
-    if (mStream->pause == NULL) return INVALID_OPERATION;
-    return mStream->pause(mStream);
-}
-
-status_t StreamOutHalLocal::resume() {
-    if (mStream->resume == NULL) return INVALID_OPERATION;
-    return mStream->resume(mStream);
-}
-
-status_t StreamOutHalLocal::supportsDrain(bool *supportsDrain) {
-    *supportsDrain = mStream->drain != NULL;
-    return OK;
-}
-
-status_t StreamOutHalLocal::drain(bool earlyNotify) {
-    if (mStream->drain == NULL) return INVALID_OPERATION;
-    return mStream->drain(mStream, earlyNotify ? AUDIO_DRAIN_EARLY_NOTIFY : AUDIO_DRAIN_ALL);
-}
-
-status_t StreamOutHalLocal::flush() {
-    if (mStream->flush == NULL) return INVALID_OPERATION;
-    return mStream->flush(mStream);
-}
-
-status_t StreamOutHalLocal::getPresentationPosition(uint64_t *frames, struct timespec *timestamp) {
-    if (mStream->get_presentation_position == NULL) return INVALID_OPERATION;
-    return mStream->get_presentation_position(mStream, frames, timestamp);
-}
-
-status_t StreamOutHalLocal::updateSourceMetadata(const SourceMetadata& sourceMetadata) {
-    if (mStream->update_source_metadata == nullptr) {
-        return INVALID_OPERATION;
-    }
-    const source_metadata_t metadata {
-        .track_count = sourceMetadata.tracks.size(),
-        // const cast is fine as it is in a const structure
-        .tracks = const_cast<playback_track_metadata*>(sourceMetadata.tracks.data()),
-    };
-    mStream->update_source_metadata(mStream, &metadata);
-    return OK;
-}
-
-status_t StreamOutHalLocal::start() {
-    if (mStream->start == NULL) return INVALID_OPERATION;
-    return mStream->start(mStream);
-}
-
-status_t StreamOutHalLocal::stop() {
-    if (mStream->stop == NULL) return INVALID_OPERATION;
-    return mStream->stop(mStream);
-}
-
-status_t StreamOutHalLocal::createMmapBuffer(int32_t minSizeFrames,
-                                  struct audio_mmap_buffer_info *info) {
-    if (mStream->create_mmap_buffer == NULL) return INVALID_OPERATION;
-    return mStream->create_mmap_buffer(mStream, minSizeFrames, info);
-}
-
-status_t StreamOutHalLocal::getMmapPosition(struct audio_mmap_position *position) {
-    if (mStream->get_mmap_position == NULL) return INVALID_OPERATION;
-    return mStream->get_mmap_position(mStream, position);
-}
-
-StreamInHalLocal::StreamInHalLocal(audio_stream_in_t *stream, sp<DeviceHalLocal> device)
-        : StreamHalLocal(&stream->common, device), mStream(stream) {
-}
-
-StreamInHalLocal::~StreamInHalLocal() {
-    mDevice->closeInputStream(mStream);
-    mStream = 0;
-}
-
-status_t StreamInHalLocal::getFrameSize(size_t *size) {
-    *size = audio_stream_in_frame_size(mStream);
-    return OK;
-}
-
-status_t StreamInHalLocal::setGain(float gain) {
-    return mStream->set_gain(mStream, gain);
-}
-
-status_t StreamInHalLocal::read(void *buffer, size_t bytes, size_t *read) {
-    ssize_t readResult = mStream->read(mStream, buffer, bytes);
-    if (readResult > 0) {
-        *read = readResult;
-        mStreamPowerLog.log( buffer, *read);
-        return OK;
-    } else {
-        *read = 0;
-        return readResult;
-    }
-}
-
-status_t StreamInHalLocal::getInputFramesLost(uint32_t *framesLost) {
-    *framesLost = mStream->get_input_frames_lost(mStream);
-    return OK;
-}
-
-status_t StreamInHalLocal::getCapturePosition(int64_t *frames, int64_t *time) {
-    if (mStream->get_capture_position == NULL) return INVALID_OPERATION;
-    return mStream->get_capture_position(mStream, frames, time);
-}
-
-status_t StreamInHalLocal::updateSinkMetadata(const SinkMetadata& sinkMetadata) {
-    if (mStream->update_sink_metadata == nullptr) {
-        return INVALID_OPERATION;
-    }
-    const sink_metadata_t metadata {
-        .track_count = sinkMetadata.tracks.size(),
-        // const cast is fine as it is in a const structure
-        .tracks = const_cast<record_track_metadata*>(sinkMetadata.tracks.data()),
-    };
-    mStream->update_sink_metadata(mStream, &metadata);
-    return OK;
-}
-
-status_t StreamInHalLocal::start() {
-    if (mStream->start == NULL) return INVALID_OPERATION;
-    return mStream->start(mStream);
-}
-
-status_t StreamInHalLocal::stop() {
-    if (mStream->stop == NULL) return INVALID_OPERATION;
-    return mStream->stop(mStream);
-}
-
-status_t StreamInHalLocal::createMmapBuffer(int32_t minSizeFrames,
-                                  struct audio_mmap_buffer_info *info) {
-    if (mStream->create_mmap_buffer == NULL) return INVALID_OPERATION;
-    return mStream->create_mmap_buffer(mStream, minSizeFrames, info);
-}
-
-status_t StreamInHalLocal::getMmapPosition(struct audio_mmap_position *position) {
-    if (mStream->get_mmap_position == NULL) return INVALID_OPERATION;
-    return mStream->get_mmap_position(mStream, position);
-}
-
-status_t StreamInHalLocal::getActiveMicrophones(
-        std::vector<media::MicrophoneInfo> *microphones __unused) {
-    return INVALID_OPERATION;
-}
-
-} // namespace android
diff --git a/media/libaudiohal/2.0/StreamHalLocal.h b/media/libaudiohal/2.0/StreamHalLocal.h
deleted file mode 100644
index cda8d0c..0000000
--- a/media/libaudiohal/2.0/StreamHalLocal.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_STREAM_HAL_LOCAL_H
-#define ANDROID_HARDWARE_STREAM_HAL_LOCAL_H
-
-#include <media/audiohal/StreamHalInterface.h>
-#include "StreamPowerLog.h"
-
-namespace android {
-
-class DeviceHalLocal;
-
-class StreamHalLocal : public virtual StreamHalInterface
-{
-  public:
-    // Return the sampling rate in Hz - eg. 44100.
-    virtual status_t getSampleRate(uint32_t *rate);
-
-    // Return size of input/output buffer in bytes for this stream - eg. 4800.
-    virtual status_t getBufferSize(size_t *size);
-
-    // Return the channel mask.
-    virtual status_t getChannelMask(audio_channel_mask_t *mask);
-
-    // Return the audio format - e.g. AUDIO_FORMAT_PCM_16_BIT.
-    virtual status_t getFormat(audio_format_t *format);
-
-    // Convenience method.
-    virtual status_t getAudioProperties(
-            uint32_t *sampleRate, audio_channel_mask_t *mask, audio_format_t *format);
-
-    // Set audio stream parameters.
-    virtual status_t setParameters(const String8& kvPairs);
-
-    // Get audio stream parameters.
-    virtual status_t getParameters(const String8& keys, String8 *values);
-
-    // Add or remove the effect on the stream.
-    virtual status_t addEffect(sp<EffectHalInterface> effect);
-    virtual status_t removeEffect(sp<EffectHalInterface> effect);
-
-    // Put the audio hardware input/output into standby mode.
-    virtual status_t standby();
-
-    virtual status_t dump(int fd);
-
-    // Start a stream operating in mmap mode.
-    virtual status_t start() = 0;
-
-    // Stop a stream operating in mmap mode.
-    virtual status_t stop() = 0;
-
-    // Retrieve information on the data buffer in mmap mode.
-    virtual status_t createMmapBuffer(int32_t minSizeFrames,
-                                      struct audio_mmap_buffer_info *info) = 0;
-
-    // Get current read/write position in the mmap buffer
-    virtual status_t getMmapPosition(struct audio_mmap_position *position) = 0;
-
-    // Set the priority of the thread that interacts with the HAL
-    // (must match the priority of the audioflinger's thread that calls 'read' / 'write')
-    virtual status_t setHalThreadPriority(int priority);
-
-  protected:
-    // Subclasses can not be constructed directly by clients.
-    StreamHalLocal(audio_stream_t *stream, sp<DeviceHalLocal> device);
-
-    // The destructor automatically closes the stream.
-    virtual ~StreamHalLocal();
-
-    sp<DeviceHalLocal> mDevice;
-
-    // mStreamPowerLog is used for audio signal power logging.
-    StreamPowerLog mStreamPowerLog;
-
-  private:
-    audio_stream_t *mStream;
-};
-
-class StreamOutHalLocal : public StreamOutHalInterface, public StreamHalLocal {
-  public:
-    // Return the frame size (number of bytes per sample) of a stream.
-    virtual status_t getFrameSize(size_t *size);
-
-    // Return the audio hardware driver estimated latency in milliseconds.
-    virtual status_t getLatency(uint32_t *latency);
-
-    // Use this method in situations where audio mixing is done in the hardware.
-    virtual status_t setVolume(float left, float right);
-
-    // Write audio buffer to driver.
-    virtual status_t write(const void *buffer, size_t bytes, size_t *written);
-
-    // Return the number of audio frames written by the audio dsp to DAC since
-    // the output has exited standby.
-    virtual status_t getRenderPosition(uint32_t *dspFrames);
-
-    // Get the local time at which the next write to the audio driver will be presented.
-    virtual status_t getNextWriteTimestamp(int64_t *timestamp);
-
-    // Set the callback for notifying completion of non-blocking write and drain.
-    virtual status_t setCallback(wp<StreamOutHalInterfaceCallback> callback);
-
-    // Returns whether pause and resume operations are supported.
-    virtual status_t supportsPauseAndResume(bool *supportsPause, bool *supportsResume);
-
-    // Notifies to the audio driver to resume playback following a pause.
-    virtual status_t pause();
-
-    // Notifies to the audio driver to resume playback following a pause.
-    virtual status_t resume();
-
-    // Returns whether drain operation is supported.
-    virtual status_t supportsDrain(bool *supportsDrain);
-
-    // Requests notification when data buffered by the driver/hardware has been played.
-    virtual status_t drain(bool earlyNotify);
-
-    // Notifies to the audio driver to flush the queued data.
-    virtual status_t flush();
-
-    // Return a recent count of the number of audio frames presented to an external observer.
-    virtual status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp);
-
-    // Start a stream operating in mmap mode.
-    virtual status_t start();
-
-    // Stop a stream operating in mmap mode.
-    virtual status_t stop();
-
-    // Retrieve information on the data buffer in mmap mode.
-    virtual status_t createMmapBuffer(int32_t minSizeFrames,
-                                      struct audio_mmap_buffer_info *info);
-
-    // Get current read/write position in the mmap buffer
-    virtual status_t getMmapPosition(struct audio_mmap_position *position);
-
-    // Called when the metadata of the stream's source has been changed.
-    status_t updateSourceMetadata(const SourceMetadata& sourceMetadata) override;
-
-  private:
-    audio_stream_out_t *mStream;
-    wp<StreamOutHalInterfaceCallback> mCallback;
-
-    friend class DeviceHalLocal;
-
-    // Can not be constructed directly by clients.
-    StreamOutHalLocal(audio_stream_out_t *stream, sp<DeviceHalLocal> device);
-
-    virtual ~StreamOutHalLocal();
-
-    static int asyncCallback(stream_callback_event_t event, void *param, void *cookie);
-};
-
-class StreamInHalLocal : public StreamInHalInterface, public StreamHalLocal {
-  public:
-    // Return the frame size (number of bytes per sample) of a stream.
-    virtual status_t getFrameSize(size_t *size);
-
-    // Set the input gain for the audio driver.
-    virtual status_t setGain(float gain);
-
-    // Read audio buffer in from driver.
-    virtual status_t read(void *buffer, size_t bytes, size_t *read);
-
-    // Return the amount of input frames lost in the audio driver.
-    virtual status_t getInputFramesLost(uint32_t *framesLost);
-
-    // Return a recent count of the number of audio frames received and
-    // the clock time associated with that frame count.
-    virtual status_t getCapturePosition(int64_t *frames, int64_t *time);
-
-    // Start a stream operating in mmap mode.
-    virtual status_t start();
-
-    // Stop a stream operating in mmap mode.
-    virtual status_t stop();
-
-    // Retrieve information on the data buffer in mmap mode.
-    virtual status_t createMmapBuffer(int32_t minSizeFrames,
-                                      struct audio_mmap_buffer_info *info);
-
-    // Get current read/write position in the mmap buffer
-    virtual status_t getMmapPosition(struct audio_mmap_position *position);
-
-    // Get active microphones
-    virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones);
-
-    // Called when the metadata of the stream's sink has been changed.
-    status_t updateSinkMetadata(const SinkMetadata& sinkMetadata) override;
-
-  private:
-    audio_stream_in_t *mStream;
-
-    friend class DeviceHalLocal;
-
-    // Can not be constructed directly by clients.
-    StreamInHalLocal(audio_stream_in_t *stream, sp<DeviceHalLocal> device);
-
-    virtual ~StreamInHalLocal();
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_STREAM_HAL_LOCAL_H
diff --git a/media/libaudiohal/2.0/StreamPowerLog.h b/media/libaudiohal/2.0/StreamPowerLog.h
deleted file mode 100644
index a78b1aa..0000000
--- a/media/libaudiohal/2.0/StreamPowerLog.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_STREAM_POWER_LOG_H
-#define ANDROID_HARDWARE_STREAM_POWER_LOG_H
-
-#include <audio_utils/clock.h>
-#include <audio_utils/PowerLog.h>
-#include <cutils/properties.h>
-#include <system/audio.h>
-
-namespace android {
-
-class StreamPowerLog {
-public:
-    StreamPowerLog() :
-        mIsUserDebugOrEngBuild(is_userdebug_or_eng_build()),
-        mPowerLog(nullptr),
-        mFrameSize(0) {
-        // use init() to set up the power log.
-    }
-
-    ~StreamPowerLog() {
-        power_log_destroy(mPowerLog); // OK for null mPowerLog
-        mPowerLog = nullptr;
-    }
-
-    // A one-time initialization (do not call twice) before using StreamPowerLog.
-    void init(uint32_t sampleRate, audio_channel_mask_t channelMask, audio_format_t format) {
-        if (mPowerLog == nullptr) {
-            // Note: A way to get channel count for both input and output channel masks
-            // but does not check validity of the channel mask.
-            const uint32_t channelCount = popcount(audio_channel_mask_get_bits(channelMask));
-            mFrameSize = channelCount * audio_bytes_per_sample(format);
-            if (mFrameSize > 0) {
-                const size_t kPowerLogFramesPerEntry =
-                        (long long)sampleRate * kPowerLogSamplingIntervalMs / 1000;
-                mPowerLog = power_log_create(
-                        sampleRate,
-                        channelCount,
-                        format,
-                        kPowerLogEntries,
-                        kPowerLogFramesPerEntry);
-            }
-        }
-        // mPowerLog may be NULL (not the right build, format not accepted, etc.).
-    }
-
-    // Dump the power log to fd.
-    void dump(int fd) const {
-        // OK for null mPowerLog
-        (void)power_log_dump(
-                mPowerLog, fd, "      " /* prefix */, kPowerLogLines, 0 /* limit_ns */);
-    }
-
-    // Log the audio data contained in buffer.
-    void log(const void *buffer, size_t sizeInBytes) const {
-        if (mPowerLog != nullptr) { // mFrameSize is always nonzero if mPowerLog exists.
-            power_log_log(
-                    mPowerLog, buffer, sizeInBytes / mFrameSize, audio_utils_get_real_time_ns());
-        }
-    }
-
-    bool isUserDebugOrEngBuild() const {
-        return mIsUserDebugOrEngBuild;
-    }
-
-private:
-
-    static inline bool is_userdebug_or_eng_build() {
-        char value[PROPERTY_VALUE_MAX];
-        (void)property_get("ro.build.type", value, "unknown"); // ignore actual length
-        return strcmp(value, "userdebug") == 0 || strcmp(value, "eng") == 0;
-    }
-
-    // Audio signal power log configuration.
-    static const size_t kPowerLogLines = 40;
-    static const size_t kPowerLogSamplingIntervalMs = 50;
-    static const size_t kPowerLogEntries = (1 /* minutes */ * 60 /* seconds */ * 1000 /* msec */
-            / kPowerLogSamplingIntervalMs);
-
-    const bool mIsUserDebugOrEngBuild;
-    power_log_t *mPowerLog;
-    size_t mFrameSize;
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_STREAM_POWER_LOG_H
diff --git a/media/libaudiohal/4.0/Android.bp b/media/libaudiohal/4.0/Android.bp
deleted file mode 100644
index 833defa..0000000
--- a/media/libaudiohal/4.0/Android.bp
+++ /dev/null
@@ -1,58 +0,0 @@
-cc_library_shared {
-    name: "libaudiohal@4.0",
-
-    srcs: [
-        "DeviceHalLocal.cpp",
-        "DevicesFactoryHalHybrid.cpp",
-        "DevicesFactoryHalLocal.cpp",
-        "StreamHalLocal.cpp",
-
-        "ConversionHelperHidl.cpp",
-        "DeviceHalHidl.cpp",
-        "DevicesFactoryHalHidl.cpp",
-        "EffectBufferHalHidl.cpp",
-        "EffectHalHidl.cpp",
-        "EffectsFactoryHalHidl.cpp",
-        "StreamHalHidl.cpp",
-    ],
-
-    export_include_dirs: ["include"],
-
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-    ],
-    shared_libs: [
-        "libaudiohal_deathhandler",
-        "libaudioutils",
-        "libbinder",
-        "libcutils",
-        "liblog",
-        "libutils",
-        "libhardware",
-        "libbase",
-        "libfmq",
-        "libhwbinder",
-        "libhidlbase",
-        "libhidlmemory",
-        "libhidltransport",
-        "android.hardware.audio@4.0",
-        "android.hardware.audio.common-util",
-        "android.hardware.audio.common@4.0",
-        "android.hardware.audio.common@4.0-util",
-        "android.hardware.audio.effect@4.0",
-        "android.hidl.allocator@1.0",
-        "android.hidl.memory@1.0",
-        "libmedia_helper",
-        "libmediautils",
-    ],
-    header_libs: [
-        "android.hardware.audio.common.util@all-versions",
-        "libaudiohal_headers"
-    ],
-
-    export_shared_lib_headers: [
-        "libfmq",
-    ],
-}
diff --git a/media/libaudiohal/4.0/ConversionHelperHidl.cpp b/media/libaudiohal/4.0/ConversionHelperHidl.cpp
deleted file mode 100644
index fe27504..0000000
--- a/media/libaudiohal/4.0/ConversionHelperHidl.cpp
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <string.h>
-
-#define LOG_TAG "HalHidl"
-#include <media/AudioParameter.h>
-#include <utils/Log.h>
-
-#include "ConversionHelperHidl.h"
-
-using ::android::hardware::audio::V4_0::AudioMicrophoneChannelMapping;
-using ::android::hardware::audio::V4_0::AudioMicrophoneDirectionality;
-using ::android::hardware::audio::V4_0::AudioMicrophoneLocation;
-using ::android::hardware::audio::V4_0::DeviceAddress;
-using ::android::hardware::audio::V4_0::MicrophoneInfo;
-using ::android::hardware::audio::V4_0::Result;
-
-namespace android {
-namespace V4_0 {
-
-// static
-status_t ConversionHelperHidl::keysFromHal(const String8& keys, hidl_vec<hidl_string> *hidlKeys) {
-    AudioParameter halKeys(keys);
-    if (halKeys.size() == 0) return BAD_VALUE;
-    hidlKeys->resize(halKeys.size());
-    //FIXME:  keyStreamSupportedChannels and keyStreamSupportedSamplingRates come with a
-    // "keyFormat=<value>" pair. We need to transform it into a single key string so that it is
-    // carried over to the legacy HAL via HIDL.
-    String8 value;
-    bool keepFormatValue = halKeys.size() == 2 &&
-         (halKeys.get(String8(AudioParameter::keyStreamSupportedChannels), value) == NO_ERROR ||
-         halKeys.get(String8(AudioParameter::keyStreamSupportedSamplingRates), value) == NO_ERROR);
-
-    for (size_t i = 0; i < halKeys.size(); ++i) {
-        String8 key;
-        status_t status = halKeys.getAt(i, key);
-        if (status != OK) return status;
-        if (keepFormatValue && key == AudioParameter::keyFormat) {
-            AudioParameter formatParam;
-            halKeys.getAt(i, key, value);
-            formatParam.add(key, value);
-            key = formatParam.toString();
-        }
-        (*hidlKeys)[i] = key.string();
-    }
-    return OK;
-}
-
-// static
-status_t ConversionHelperHidl::parametersFromHal(
-        const String8& kvPairs, hidl_vec<ParameterValue> *hidlParams) {
-    AudioParameter params(kvPairs);
-    if (params.size() == 0) return BAD_VALUE;
-    hidlParams->resize(params.size());
-    for (size_t i = 0; i < params.size(); ++i) {
-        String8 key, value;
-        status_t status = params.getAt(i, key, value);
-        if (status != OK) return status;
-        (*hidlParams)[i].key = key.string();
-        (*hidlParams)[i].value = value.string();
-    }
-    return OK;
-}
-
-// static
-void ConversionHelperHidl::parametersToHal(
-        const hidl_vec<ParameterValue>& parameters, String8 *values) {
-    AudioParameter params;
-    for (size_t i = 0; i < parameters.size(); ++i) {
-        params.add(String8(parameters[i].key.c_str()), String8(parameters[i].value.c_str()));
-    }
-    values->setTo(params.toString());
-}
-
-ConversionHelperHidl::ConversionHelperHidl(const char* className)
-        : mClassName(className) {
-}
-
-// static
-status_t ConversionHelperHidl::analyzeResult(const Result& result) {
-    switch (result) {
-        case Result::OK: return OK;
-        case Result::INVALID_ARGUMENTS: return BAD_VALUE;
-        case Result::INVALID_STATE: return NOT_ENOUGH_DATA;
-        case Result::NOT_INITIALIZED: return NO_INIT;
-        case Result::NOT_SUPPORTED: return INVALID_OPERATION;
-        default: return NO_INIT;
-    }
-}
-
-void ConversionHelperHidl::emitError(const char* funcName, const char* description) {
-    ALOGE("%s %p %s: %s (from rpc)", mClassName, this, funcName, description);
-}
-
-// TODO: Use the same implementation in the hal when it moves to a util library.
-std::string deviceAddressToHal(const DeviceAddress& address) {
-    // HAL assumes that the address is NUL-terminated.
-    char halAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN];
-    memset(halAddress, 0, sizeof(halAddress));
-    audio_devices_t halDevice = static_cast<audio_devices_t>(address.device);
-    const bool isInput = (halDevice & AUDIO_DEVICE_BIT_IN) != 0;
-    if (isInput) halDevice &= ~AUDIO_DEVICE_BIT_IN;
-    if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != 0) ||
-        (isInput && (halDevice & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0)) {
-        snprintf(halAddress, sizeof(halAddress), "%02X:%02X:%02X:%02X:%02X:%02X",
-                 address.address.mac[0], address.address.mac[1], address.address.mac[2],
-                 address.address.mac[3], address.address.mac[4], address.address.mac[5]);
-    } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_IP) != 0) ||
-               (isInput && (halDevice & AUDIO_DEVICE_IN_IP) != 0)) {
-        snprintf(halAddress, sizeof(halAddress), "%d.%d.%d.%d", address.address.ipv4[0],
-                 address.address.ipv4[1], address.address.ipv4[2], address.address.ipv4[3]);
-    } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_ALL_USB) != 0) ||
-               (isInput && (halDevice & AUDIO_DEVICE_IN_ALL_USB) != 0)) {
-        snprintf(halAddress, sizeof(halAddress), "card=%d;device=%d", address.address.alsa.card,
-                 address.address.alsa.device);
-    } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_BUS) != 0) ||
-               (isInput && (halDevice & AUDIO_DEVICE_IN_BUS) != 0)) {
-        snprintf(halAddress, sizeof(halAddress), "%s", address.busAddress.c_str());
-    } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) != 0 ||
-               (isInput && (halDevice & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0)) {
-        snprintf(halAddress, sizeof(halAddress), "%s", address.rSubmixAddress.c_str());
-    } else {
-        snprintf(halAddress, sizeof(halAddress), "%s", address.busAddress.c_str());
-    }
-    return halAddress;
-}
-
-//local conversion helpers
-
-audio_microphone_channel_mapping_t  channelMappingToHal(AudioMicrophoneChannelMapping mapping) {
-    switch (mapping) {
-        case AudioMicrophoneChannelMapping::UNUSED:
-            return AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED;
-        case AudioMicrophoneChannelMapping::DIRECT:
-            return AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT;
-        case AudioMicrophoneChannelMapping::PROCESSED:
-            return AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED;
-        default:
-            LOG_ALWAYS_FATAL("Unknown channelMappingToHal conversion %d", mapping);
-    }
-}
-
-audio_microphone_location_t locationToHal(AudioMicrophoneLocation location) {
-    switch (location) {
-        case AudioMicrophoneLocation::UNKNOWN:
-            return AUDIO_MICROPHONE_LOCATION_UNKNOWN;
-        case AudioMicrophoneLocation::MAINBODY:
-            return AUDIO_MICROPHONE_LOCATION_MAINBODY;
-        case AudioMicrophoneLocation::MAINBODY_MOVABLE:
-            return AUDIO_MICROPHONE_LOCATION_MAINBODY_MOVABLE;
-        case AudioMicrophoneLocation::PERIPHERAL:
-            return AUDIO_MICROPHONE_LOCATION_PERIPHERAL;
-        default:
-            LOG_ALWAYS_FATAL("Unknown locationToHal conversion %d", location);
-    }
-}
-audio_microphone_directionality_t directionalityToHal(AudioMicrophoneDirectionality dir) {
-    switch (dir) {
-        case AudioMicrophoneDirectionality::UNKNOWN:
-            return AUDIO_MICROPHONE_DIRECTIONALITY_UNKNOWN;
-        case AudioMicrophoneDirectionality::OMNI:
-            return AUDIO_MICROPHONE_DIRECTIONALITY_OMNI;
-        case AudioMicrophoneDirectionality::BI_DIRECTIONAL:
-            return AUDIO_MICROPHONE_DIRECTIONALITY_BI_DIRECTIONAL;
-        case AudioMicrophoneDirectionality::CARDIOID:
-            return AUDIO_MICROPHONE_DIRECTIONALITY_CARDIOID;
-        case AudioMicrophoneDirectionality::HYPER_CARDIOID:
-            return AUDIO_MICROPHONE_DIRECTIONALITY_HYPER_CARDIOID;
-        case AudioMicrophoneDirectionality::SUPER_CARDIOID:
-            return AUDIO_MICROPHONE_DIRECTIONALITY_SUPER_CARDIOID;
-        default:
-            LOG_ALWAYS_FATAL("Unknown directionalityToHal conversion %d", dir);
-    }
-}
-
-// static
-void ConversionHelperHidl::microphoneInfoToHal(const MicrophoneInfo& src,
-                                                     audio_microphone_characteristic_t *pDst) {
-    if (pDst != NULL) {
-        snprintf(pDst->device_id, sizeof(pDst->device_id),
-                 "%s", src.deviceId.c_str());
-        pDst->device = static_cast<audio_devices_t>(src.deviceAddress.device);
-        snprintf(pDst->address, sizeof(pDst->address),
-                 "%s", deviceAddressToHal(src.deviceAddress).c_str());
-        if (src.channelMapping.size() > AUDIO_CHANNEL_COUNT_MAX) {
-            ALOGW("microphoneInfoToStruct found %zu channelMapping elements. Max expected is %d",
-                  src.channelMapping.size(), AUDIO_CHANNEL_COUNT_MAX);
-        }
-        size_t ch;
-        for (ch = 0; ch < src.channelMapping.size() && ch < AUDIO_CHANNEL_COUNT_MAX; ch++) {
-            pDst->channel_mapping[ch] = channelMappingToHal(src.channelMapping[ch]);
-        }
-        for (; ch < AUDIO_CHANNEL_COUNT_MAX; ch++) {
-            pDst->channel_mapping[ch] = AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED;
-        }
-        pDst->location = locationToHal(src.location);
-        pDst->group = (audio_microphone_group_t)src.group;
-        pDst->index_in_the_group = (unsigned int)src.indexInTheGroup;
-        pDst->sensitivity = src.sensitivity;
-        pDst->max_spl = src.maxSpl;
-        pDst->min_spl = src.minSpl;
-        pDst->directionality = directionalityToHal(src.directionality);
-        pDst->num_frequency_responses = (unsigned int)src.frequencyResponse.size();
-        if (pDst->num_frequency_responses > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
-            ALOGW("microphoneInfoToStruct found %d frequency responses. Max expected is %d",
-                  pDst->num_frequency_responses, AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES);
-            pDst->num_frequency_responses = AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES;
-        }
-        for (size_t k = 0; k < pDst->num_frequency_responses; k++) {
-            pDst->frequency_responses[0][k] = src.frequencyResponse[k].frequency;
-            pDst->frequency_responses[1][k] = src.frequencyResponse[k].level;
-        }
-        pDst->geometric_location.x = src.position.x;
-        pDst->geometric_location.y = src.position.y;
-        pDst->geometric_location.z = src.position.z;
-        pDst->orientation.x = src.orientation.x;
-        pDst->orientation.y = src.orientation.y;
-        pDst->orientation.z = src.orientation.z;
-    }
-}
-
-}  // namespace V4_0
-}  // namespace android
diff --git a/media/libaudiohal/4.0/ConversionHelperHidl.h b/media/libaudiohal/4.0/ConversionHelperHidl.h
deleted file mode 100644
index 8823a8d..0000000
--- a/media/libaudiohal/4.0/ConversionHelperHidl.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_CONVERSION_HELPER_HIDL_4_0_H
-#define ANDROID_HARDWARE_CONVERSION_HELPER_HIDL_4_0_H
-
-#include <android/hardware/audio/4.0/types.h>
-#include <hidl/HidlSupport.h>
-#include <system/audio.h>
-#include <utils/String8.h>
-
-using ::android::hardware::audio::V4_0::ParameterValue;
-using ::android::hardware::audio::V4_0::MicrophoneInfo;
-using ::android::hardware::Return;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-
-namespace android {
-namespace V4_0 {
-
-class ConversionHelperHidl {
-  protected:
-    static status_t keysFromHal(const String8& keys, hidl_vec<hidl_string> *hidlKeys);
-    static status_t parametersFromHal(const String8& kvPairs, hidl_vec<ParameterValue> *hidlParams);
-    static void parametersToHal(const hidl_vec<ParameterValue>& parameters, String8 *values);
-    static void microphoneInfoToHal(const MicrophoneInfo& src,
-                                    audio_microphone_characteristic_t *pDst);
-
-    ConversionHelperHidl(const char* className);
-
-    template<typename R, typename T>
-    status_t processReturn(const char* funcName, const Return<R>& ret, T *retval) {
-        if (ret.isOk()) {
-            // This way it also works for enum class to unscoped enum conversion.
-            *retval = static_cast<T>(static_cast<R>(ret));
-            return OK;
-        }
-        return processReturn(funcName, ret);
-    }
-
-    template<typename T>
-    status_t processReturn(const char* funcName, const Return<T>& ret) {
-        if (!ret.isOk()) {
-            emitError(funcName, ret.description().c_str());
-        }
-        return ret.isOk() ? OK : FAILED_TRANSACTION;
-    }
-
-    status_t processReturn(const char* funcName, const Return<hardware::audio::V4_0::Result>& ret) {
-        if (!ret.isOk()) {
-            emitError(funcName, ret.description().c_str());
-        }
-        return ret.isOk() ? analyzeResult(ret) : FAILED_TRANSACTION;
-    }
-
-    template<typename T>
-    status_t processReturn(
-            const char* funcName, const Return<T>& ret, hardware::audio::V4_0::Result retval) {
-        if (!ret.isOk()) {
-            emitError(funcName, ret.description().c_str());
-        }
-        return ret.isOk() ? analyzeResult(retval) : FAILED_TRANSACTION;
-    }
-
-  private:
-    const char* mClassName;
-
-    static status_t analyzeResult(const hardware::audio::V4_0::Result& result);
-
-    void emitError(const char* funcName, const char* description);
-};
-
-}  // namespace V4_0
-}  // namespace android
-
-#endif // ANDROID_HARDWARE_CONVERSION_HELPER_HIDL_4_0_H
diff --git a/media/libaudiohal/4.0/DeviceHalHidl.cpp b/media/libaudiohal/4.0/DeviceHalHidl.cpp
deleted file mode 100644
index 6facca9..0000000
--- a/media/libaudiohal/4.0/DeviceHalHidl.cpp
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-
-#define LOG_TAG "DeviceHalHidl"
-//#define LOG_NDEBUG 0
-
-#include <android/hardware/audio/4.0/IPrimaryDevice.h>
-#include <cutils/native_handle.h>
-#include <hwbinder/IPCThreadState.h>
-#include <utils/Log.h>
-
-#include <common/all-versions/VersionUtils.h>
-
-#include "DeviceHalHidl.h"
-#include "HidlUtils.h"
-#include "StreamHalHidl.h"
-#include "VersionUtils.h"
-
-using ::android::hardware::audio::common::V4_0::AudioConfig;
-using ::android::hardware::audio::common::V4_0::AudioDevice;
-using ::android::hardware::audio::common::V4_0::AudioInputFlag;
-using ::android::hardware::audio::common::V4_0::AudioOutputFlag;
-using ::android::hardware::audio::common::V4_0::AudioPatchHandle;
-using ::android::hardware::audio::common::V4_0::AudioPort;
-using ::android::hardware::audio::common::V4_0::AudioPortConfig;
-using ::android::hardware::audio::common::V4_0::AudioMode;
-using ::android::hardware::audio::common::V4_0::AudioSource;
-using ::android::hardware::audio::common::V4_0::HidlUtils;
-using ::android::hardware::audio::common::utils::mkEnumConverter;
-using ::android::hardware::audio::V4_0::DeviceAddress;
-using ::android::hardware::audio::V4_0::IPrimaryDevice;
-using ::android::hardware::audio::V4_0::ParameterValue;
-using ::android::hardware::audio::V4_0::Result;
-using ::android::hardware::audio::V4_0::SinkMetadata;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-
-namespace android {
-namespace V4_0 {
-
-namespace {
-
-status_t deviceAddressFromHal(
-        audio_devices_t device, const char* halAddress, DeviceAddress* address) {
-    address->device = AudioDevice(device);
-
-    if (halAddress == nullptr || strnlen(halAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
-        return OK;
-    }
-    const bool isInput = (device & AUDIO_DEVICE_BIT_IN) != 0;
-    if (isInput) device &= ~AUDIO_DEVICE_BIT_IN;
-    if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_A2DP) != 0)
-            || (isInput && (device & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0)) {
-        int status = sscanf(halAddress,
-                "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX",
-                &address->address.mac[0], &address->address.mac[1], &address->address.mac[2],
-                &address->address.mac[3], &address->address.mac[4], &address->address.mac[5]);
-        return status == 6 ? OK : BAD_VALUE;
-    } else if ((!isInput && (device & AUDIO_DEVICE_OUT_IP) != 0)
-            || (isInput && (device & AUDIO_DEVICE_IN_IP) != 0)) {
-        int status = sscanf(halAddress,
-                "%hhu.%hhu.%hhu.%hhu",
-                &address->address.ipv4[0], &address->address.ipv4[1],
-                &address->address.ipv4[2], &address->address.ipv4[3]);
-        return status == 4 ? OK : BAD_VALUE;
-    } else if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_USB)) != 0
-            || (isInput && (device & AUDIO_DEVICE_IN_ALL_USB)) != 0) {
-        int status = sscanf(halAddress,
-                "card=%d;device=%d",
-                &address->address.alsa.card, &address->address.alsa.device);
-        return status == 2 ? OK : BAD_VALUE;
-    } else if ((!isInput && (device & AUDIO_DEVICE_OUT_BUS) != 0)
-            || (isInput && (device & AUDIO_DEVICE_IN_BUS) != 0)) {
-        if (halAddress != NULL) {
-            address->busAddress = halAddress;
-            return OK;
-        }
-        return BAD_VALUE;
-    } else if ((!isInput && (device & AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) != 0
-            || (isInput && (device & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0)) {
-        if (halAddress != NULL) {
-            address->rSubmixAddress = halAddress;
-            return OK;
-        }
-        return BAD_VALUE;
-    }
-    return OK;
-}
-
-}  // namespace
-
-DeviceHalHidl::DeviceHalHidl(const sp<IDevice>& device)
-        : ConversionHelperHidl("Device"), mDevice(device),
-          mPrimaryDevice(IPrimaryDevice::castFrom(device)) {
-}
-
-DeviceHalHidl::~DeviceHalHidl() {
-    if (mDevice != 0) {
-        mDevice.clear();
-        hardware::IPCThreadState::self()->flushCommands();
-    }
-}
-
-status_t DeviceHalHidl::getSupportedDevices(uint32_t*) {
-    // Obsolete.
-    return INVALID_OPERATION;
-}
-
-status_t DeviceHalHidl::initCheck() {
-    if (mDevice == 0) return NO_INIT;
-    return processReturn("initCheck", mDevice->initCheck());
-}
-
-status_t DeviceHalHidl::setVoiceVolume(float volume) {
-    if (mDevice == 0) return NO_INIT;
-    if (mPrimaryDevice == 0) return INVALID_OPERATION;
-    return processReturn("setVoiceVolume", mPrimaryDevice->setVoiceVolume(volume));
-}
-
-status_t DeviceHalHidl::setMasterVolume(float volume) {
-    if (mDevice == 0) return NO_INIT;
-    if (mPrimaryDevice == 0) return INVALID_OPERATION;
-    return processReturn("setMasterVolume", mPrimaryDevice->setMasterVolume(volume));
-}
-
-status_t DeviceHalHidl::getMasterVolume(float *volume) {
-    if (mDevice == 0) return NO_INIT;
-    if (mPrimaryDevice == 0) return INVALID_OPERATION;
-    Result retval;
-    Return<void> ret = mPrimaryDevice->getMasterVolume(
-            [&](Result r, float v) {
-                retval = r;
-                if (retval == Result::OK) {
-                    *volume = v;
-                }
-            });
-    return processReturn("getMasterVolume", ret, retval);
-}
-
-status_t DeviceHalHidl::setMode(audio_mode_t mode) {
-    if (mDevice == 0) return NO_INIT;
-    if (mPrimaryDevice == 0) return INVALID_OPERATION;
-    return processReturn("setMode", mPrimaryDevice->setMode(AudioMode(mode)));
-}
-
-status_t DeviceHalHidl::setMicMute(bool state) {
-    if (mDevice == 0) return NO_INIT;
-    return processReturn("setMicMute", mDevice->setMicMute(state));
-}
-
-status_t DeviceHalHidl::getMicMute(bool *state) {
-    if (mDevice == 0) return NO_INIT;
-    Result retval;
-    Return<void> ret = mDevice->getMicMute(
-            [&](Result r, bool mute) {
-                retval = r;
-                if (retval == Result::OK) {
-                    *state = mute;
-                }
-            });
-    return processReturn("getMicMute", ret, retval);
-}
-
-status_t DeviceHalHidl::setMasterMute(bool state) {
-    if (mDevice == 0) return NO_INIT;
-    return processReturn("setMasterMute", mDevice->setMasterMute(state));
-}
-
-status_t DeviceHalHidl::getMasterMute(bool *state) {
-    if (mDevice == 0) return NO_INIT;
-    Result retval;
-    Return<void> ret = mDevice->getMasterMute(
-            [&](Result r, bool mute) {
-                retval = r;
-                if (retval == Result::OK) {
-                    *state = mute;
-                }
-            });
-    return processReturn("getMasterMute", ret, retval);
-}
-
-status_t DeviceHalHidl::setParameters(const String8& kvPairs) {
-    if (mDevice == 0) return NO_INIT;
-    hidl_vec<ParameterValue> hidlParams;
-    status_t status = parametersFromHal(kvPairs, &hidlParams);
-    if (status != OK) return status;
-    // TODO: change the API so that context and kvPairs are separated
-    return processReturn("setParameters",
-                         utils::setParameters(mDevice, {} /* context */, hidlParams));
-}
-
-status_t DeviceHalHidl::getParameters(const String8& keys, String8 *values) {
-    values->clear();
-    if (mDevice == 0) return NO_INIT;
-    hidl_vec<hidl_string> hidlKeys;
-    status_t status = keysFromHal(keys, &hidlKeys);
-    if (status != OK) return status;
-    Result retval;
-    Return<void> ret = utils::getParameters(mDevice,
-            {} /* context */,
-            hidlKeys,
-            [&](Result r, const hidl_vec<ParameterValue>& parameters) {
-                retval = r;
-                if (retval == Result::OK) {
-                    parametersToHal(parameters, values);
-                }
-            });
-    return processReturn("getParameters", ret, retval);
-}
-
-status_t DeviceHalHidl::getInputBufferSize(
-        const struct audio_config *config, size_t *size) {
-    if (mDevice == 0) return NO_INIT;
-    AudioConfig hidlConfig;
-    HidlUtils::audioConfigFromHal(*config, &hidlConfig);
-    Result retval;
-    Return<void> ret = mDevice->getInputBufferSize(
-            hidlConfig,
-            [&](Result r, uint64_t bufferSize) {
-                retval = r;
-                if (retval == Result::OK) {
-                    *size = static_cast<size_t>(bufferSize);
-                }
-            });
-    return processReturn("getInputBufferSize", ret, retval);
-}
-
-status_t DeviceHalHidl::openOutputStream(
-        audio_io_handle_t handle,
-        audio_devices_t devices,
-        audio_output_flags_t flags,
-        struct audio_config *config,
-        const char *address,
-        sp<StreamOutHalInterface> *outStream) {
-    if (mDevice == 0) return NO_INIT;
-    DeviceAddress hidlDevice;
-    status_t status = deviceAddressFromHal(devices, address, &hidlDevice);
-    if (status != OK) return status;
-    AudioConfig hidlConfig;
-    HidlUtils::audioConfigFromHal(*config, &hidlConfig);
-    Result retval = Result::NOT_INITIALIZED;
-    Return<void> ret = mDevice->openOutputStream(
-            handle,
-            hidlDevice,
-            hidlConfig,
-            mkEnumConverter<AudioOutputFlag>(flags),
-            {} /* metadata */,
-            [&](Result r, const sp<IStreamOut>& result, const AudioConfig& suggestedConfig) {
-                retval = r;
-                if (retval == Result::OK) {
-                    *outStream = new StreamOutHalHidl(result);
-                }
-                HidlUtils::audioConfigToHal(suggestedConfig, config);
-            });
-    return processReturn("openOutputStream", ret, retval);
-}
-
-status_t DeviceHalHidl::openInputStream(
-        audio_io_handle_t handle,
-        audio_devices_t devices,
-        struct audio_config *config,
-        audio_input_flags_t flags,
-        const char *address,
-        audio_source_t source,
-        sp<StreamInHalInterface> *inStream) {
-    if (mDevice == 0) return NO_INIT;
-    DeviceAddress hidlDevice;
-    status_t status = deviceAddressFromHal(devices, address, &hidlDevice);
-    if (status != OK) return status;
-    AudioConfig hidlConfig;
-    HidlUtils::audioConfigFromHal(*config, &hidlConfig);
-    Result retval = Result::NOT_INITIALIZED;
-    // TODO: correctly propagate the tracks sources and volume
-    //       for now, only send the main source at 1dbfs
-    SinkMetadata metadata = {{{AudioSource(source), 1}}};
-    Return<void> ret = mDevice->openInputStream(
-            handle,
-            hidlDevice,
-            hidlConfig,
-            flags,
-            metadata,
-            [&](Result r, const sp<IStreamIn>& result, const AudioConfig& suggestedConfig) {
-                retval = r;
-                if (retval == Result::OK) {
-                    *inStream = new StreamInHalHidl(result);
-                }
-                HidlUtils::audioConfigToHal(suggestedConfig, config);
-            });
-    return processReturn("openInputStream", ret, retval);
-}
-
-status_t DeviceHalHidl::supportsAudioPatches(bool *supportsPatches) {
-    if (mDevice == 0) return NO_INIT;
-    return processReturn("supportsAudioPatches", mDevice->supportsAudioPatches(), supportsPatches);
-}
-
-status_t DeviceHalHidl::createAudioPatch(
-        unsigned int num_sources,
-        const struct audio_port_config *sources,
-        unsigned int num_sinks,
-        const struct audio_port_config *sinks,
-        audio_patch_handle_t *patch) {
-    if (mDevice == 0) return NO_INIT;
-    hidl_vec<AudioPortConfig> hidlSources, hidlSinks;
-    HidlUtils::audioPortConfigsFromHal(num_sources, sources, &hidlSources);
-    HidlUtils::audioPortConfigsFromHal(num_sinks, sinks, &hidlSinks);
-    Result retval;
-    Return<void> ret = mDevice->createAudioPatch(
-            hidlSources, hidlSinks,
-            [&](Result r, AudioPatchHandle hidlPatch) {
-                retval = r;
-                if (retval == Result::OK) {
-                    *patch = static_cast<audio_patch_handle_t>(hidlPatch);
-                }
-            });
-    return processReturn("createAudioPatch", ret, retval);
-}
-
-status_t DeviceHalHidl::releaseAudioPatch(audio_patch_handle_t patch) {
-    if (mDevice == 0) return NO_INIT;
-    return processReturn("releaseAudioPatch", mDevice->releaseAudioPatch(patch));
-}
-
-status_t DeviceHalHidl::getAudioPort(struct audio_port *port) {
-    if (mDevice == 0) return NO_INIT;
-    AudioPort hidlPort;
-    HidlUtils::audioPortFromHal(*port, &hidlPort);
-    Result retval;
-    Return<void> ret = mDevice->getAudioPort(
-            hidlPort,
-            [&](Result r, const AudioPort& p) {
-                retval = r;
-                if (retval == Result::OK) {
-                    HidlUtils::audioPortToHal(p, port);
-                }
-            });
-    return processReturn("getAudioPort", ret, retval);
-}
-
-status_t DeviceHalHidl::setAudioPortConfig(const struct audio_port_config *config) {
-    if (mDevice == 0) return NO_INIT;
-    AudioPortConfig hidlConfig;
-    HidlUtils::audioPortConfigFromHal(*config, &hidlConfig);
-    return processReturn("setAudioPortConfig", mDevice->setAudioPortConfig(hidlConfig));
-}
-
-status_t DeviceHalHidl::getMicrophones(std::vector<media::MicrophoneInfo> *microphonesInfo) {
-    if (mDevice == 0) return NO_INIT;
-    Result retval;
-    Return<void> ret = mDevice->getMicrophones(
-            [&](Result r, hidl_vec<MicrophoneInfo> micArrayHal) {
-        retval = r;
-        for (size_t k = 0; k < micArrayHal.size(); k++) {
-            audio_microphone_characteristic_t dst;
-            //convert
-            microphoneInfoToHal(micArrayHal[k], &dst);
-            media::MicrophoneInfo microphone = media::MicrophoneInfo(dst);
-            microphonesInfo->push_back(microphone);
-        }
-    });
-    return processReturn("getMicrophones", ret, retval);
-}
-
-status_t DeviceHalHidl::dump(int fd) {
-    if (mDevice == 0) return NO_INIT;
-    native_handle_t* hidlHandle = native_handle_create(1, 0);
-    hidlHandle->data[0] = fd;
-    Return<void> ret = mDevice->debug(hidlHandle, {} /* options */);
-    native_handle_delete(hidlHandle);
-    return processReturn("dump", ret);
-}
-
-} // namespace V4_0
-} // namespace android
diff --git a/media/libaudiohal/4.0/DeviceHalHidl.h b/media/libaudiohal/4.0/DeviceHalHidl.h
deleted file mode 100644
index 0bd2175..0000000
--- a/media/libaudiohal/4.0/DeviceHalHidl.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_DEVICE_HAL_HIDL_4_0_H
-#define ANDROID_HARDWARE_DEVICE_HAL_HIDL_4_0_H
-
-#include <android/hardware/audio/4.0/IDevice.h>
-#include <android/hardware/audio/4.0/IPrimaryDevice.h>
-#include <media/audiohal/DeviceHalInterface.h>
-
-#include "ConversionHelperHidl.h"
-
-using ::android::hardware::audio::V4_0::IDevice;
-using ::android::hardware::audio::V4_0::IPrimaryDevice;
-using ::android::hardware::Return;
-
-namespace android {
-namespace V4_0 {
-
-class DeviceHalHidl : public DeviceHalInterface, public ConversionHelperHidl
-{
-  public:
-    // Sets the value of 'devices' to a bitmask of 1 or more values of audio_devices_t.
-    virtual status_t getSupportedDevices(uint32_t *devices);
-
-    // Check to see if the audio hardware interface has been initialized.
-    virtual status_t initCheck();
-
-    // Set the audio volume of a voice call. Range is between 0.0 and 1.0.
-    virtual status_t setVoiceVolume(float volume);
-
-    // Set the audio volume for all audio activities other than voice call.
-    virtual status_t setMasterVolume(float volume);
-
-    // Get the current master volume value for the HAL.
-    virtual status_t getMasterVolume(float *volume);
-
-    // Called when the audio mode changes.
-    virtual status_t setMode(audio_mode_t mode);
-
-    // Muting control.
-    virtual status_t setMicMute(bool state);
-    virtual status_t getMicMute(bool *state);
-    virtual status_t setMasterMute(bool state);
-    virtual status_t getMasterMute(bool *state);
-
-    // Set global audio parameters.
-    virtual status_t setParameters(const String8& kvPairs);
-
-    // Get global audio parameters.
-    virtual status_t getParameters(const String8& keys, String8 *values);
-
-    // Returns audio input buffer size according to parameters passed.
-    virtual status_t getInputBufferSize(const struct audio_config *config,
-            size_t *size);
-
-    // Creates and opens the audio hardware output stream. The stream is closed
-    // by releasing all references to the returned object.
-    virtual status_t openOutputStream(
-            audio_io_handle_t handle,
-            audio_devices_t devices,
-            audio_output_flags_t flags,
-            struct audio_config *config,
-            const char *address,
-            sp<StreamOutHalInterface> *outStream);
-
-    // Creates and opens the audio hardware input stream. The stream is closed
-    // by releasing all references to the returned object.
-    virtual status_t openInputStream(
-            audio_io_handle_t handle,
-            audio_devices_t devices,
-            struct audio_config *config,
-            audio_input_flags_t flags,
-            const char *address,
-            audio_source_t source,
-            sp<StreamInHalInterface> *inStream);
-
-    // Returns whether createAudioPatch and releaseAudioPatch operations are supported.
-    virtual status_t supportsAudioPatches(bool *supportsPatches);
-
-    // Creates an audio patch between several source and sink ports.
-    virtual status_t createAudioPatch(
-            unsigned int num_sources,
-            const struct audio_port_config *sources,
-            unsigned int num_sinks,
-            const struct audio_port_config *sinks,
-            audio_patch_handle_t *patch);
-
-    // Releases an audio patch.
-    virtual status_t releaseAudioPatch(audio_patch_handle_t patch);
-
-    // Fills the list of supported attributes for a given audio port.
-    virtual status_t getAudioPort(struct audio_port *port);
-
-    // Set audio port configuration.
-    virtual status_t setAudioPortConfig(const struct audio_port_config *config);
-
-    // List microphones
-    virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
-
-    virtual status_t dump(int fd);
-
-  private:
-    friend class DevicesFactoryHalHidl;
-    sp<IDevice> mDevice;
-    sp<IPrimaryDevice> mPrimaryDevice;  // Null if it's not a primary device.
-
-    // Can not be constructed directly by clients.
-    explicit DeviceHalHidl(const sp<IDevice>& device);
-
-    // The destructor automatically closes the device.
-    virtual ~DeviceHalHidl();
-};
-
-} // namespace V4_0
-} // namespace android
-
-#endif // ANDROID_HARDWARE_DEVICE_HAL_HIDL_4_0_H
diff --git a/media/libaudiohal/4.0/DeviceHalLocal.cpp b/media/libaudiohal/4.0/DeviceHalLocal.cpp
deleted file mode 100644
index a245dd9..0000000
--- a/media/libaudiohal/4.0/DeviceHalLocal.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "DeviceHalLocal"
-//#define LOG_NDEBUG 0
-
-#include <utils/Log.h>
-
-#include "DeviceHalLocal.h"
-#include "StreamHalLocal.h"
-
-namespace android {
-namespace V4_0 {
-
-DeviceHalLocal::DeviceHalLocal(audio_hw_device_t *dev)
-        : mDev(dev) {
-}
-
-DeviceHalLocal::~DeviceHalLocal() {
-    int status = audio_hw_device_close(mDev);
-    ALOGW_IF(status, "Error closing audio hw device %p: %s", mDev, strerror(-status));
-    mDev = 0;
-}
-
-status_t DeviceHalLocal::getSupportedDevices(uint32_t *devices) {
-    if (mDev->get_supported_devices == NULL) return INVALID_OPERATION;
-    *devices = mDev->get_supported_devices(mDev);
-    return OK;
-}
-
-status_t DeviceHalLocal::initCheck() {
-    return mDev->init_check(mDev);
-}
-
-status_t DeviceHalLocal::setVoiceVolume(float volume) {
-    return mDev->set_voice_volume(mDev, volume);
-}
-
-status_t DeviceHalLocal::setMasterVolume(float volume) {
-    if (mDev->set_master_volume == NULL) return INVALID_OPERATION;
-    return mDev->set_master_volume(mDev, volume);
-}
-
-status_t DeviceHalLocal::getMasterVolume(float *volume) {
-    if (mDev->get_master_volume == NULL) return INVALID_OPERATION;
-    return mDev->get_master_volume(mDev, volume);
-}
-
-status_t DeviceHalLocal::setMode(audio_mode_t mode) {
-    return mDev->set_mode(mDev, mode);
-}
-
-status_t DeviceHalLocal::setMicMute(bool state) {
-    return mDev->set_mic_mute(mDev, state);
-}
-
-status_t DeviceHalLocal::getMicMute(bool *state) {
-    return mDev->get_mic_mute(mDev, state);
-}
-
-status_t DeviceHalLocal::setMasterMute(bool state) {
-    if (mDev->set_master_mute == NULL) return INVALID_OPERATION;
-    return mDev->set_master_mute(mDev, state);
-}
-
-status_t DeviceHalLocal::getMasterMute(bool *state) {
-    if (mDev->get_master_mute == NULL) return INVALID_OPERATION;
-    return mDev->get_master_mute(mDev, state);
-}
-
-status_t DeviceHalLocal::setParameters(const String8& kvPairs) {
-    return mDev->set_parameters(mDev, kvPairs.string());
-}
-
-status_t DeviceHalLocal::getParameters(const String8& keys, String8 *values) {
-    char *halValues = mDev->get_parameters(mDev, keys.string());
-    if (halValues != NULL) {
-        values->setTo(halValues);
-        free(halValues);
-    } else {
-        values->clear();
-    }
-    return OK;
-}
-
-status_t DeviceHalLocal::getInputBufferSize(
-        const struct audio_config *config, size_t *size) {
-    *size = mDev->get_input_buffer_size(mDev, config);
-    return OK;
-}
-
-status_t DeviceHalLocal::openOutputStream(
-        audio_io_handle_t handle,
-        audio_devices_t devices,
-        audio_output_flags_t flags,
-        struct audio_config *config,
-        const char *address,
-        sp<StreamOutHalInterface> *outStream) {
-    audio_stream_out_t *halStream;
-    ALOGV("open_output_stream handle: %d devices: %x flags: %#x"
-            "srate: %d format %#x channels %x address %s",
-            handle, devices, flags,
-            config->sample_rate, config->format, config->channel_mask,
-            address);
-    int openResut = mDev->open_output_stream(
-            mDev, handle, devices, flags, config, &halStream, address);
-    if (openResut == OK) {
-        *outStream = new StreamOutHalLocal(halStream, this);
-    }
-    ALOGV("open_output_stream status %d stream %p", openResut, halStream);
-    return openResut;
-}
-
-status_t DeviceHalLocal::openInputStream(
-        audio_io_handle_t handle,
-        audio_devices_t devices,
-        struct audio_config *config,
-        audio_input_flags_t flags,
-        const char *address,
-        audio_source_t source,
-        sp<StreamInHalInterface> *inStream) {
-    audio_stream_in_t *halStream;
-    ALOGV("open_input_stream handle: %d devices: %x flags: %#x "
-            "srate: %d format %#x channels %x address %s source %d",
-            handle, devices, flags,
-            config->sample_rate, config->format, config->channel_mask,
-            address, source);
-    int openResult = mDev->open_input_stream(
-            mDev, handle, devices, config, &halStream, flags, address, source);
-    if (openResult == OK) {
-        *inStream = new StreamInHalLocal(halStream, this);
-    }
-    ALOGV("open_input_stream status %d stream %p", openResult, inStream);
-    return openResult;
-}
-
-status_t DeviceHalLocal::supportsAudioPatches(bool *supportsPatches) {
-    *supportsPatches = version() >= AUDIO_DEVICE_API_VERSION_3_0;
-    return OK;
-}
-
-status_t DeviceHalLocal::createAudioPatch(
-        unsigned int num_sources,
-        const struct audio_port_config *sources,
-        unsigned int num_sinks,
-        const struct audio_port_config *sinks,
-        audio_patch_handle_t *patch) {
-    if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
-        return mDev->create_audio_patch(
-                mDev, num_sources, sources, num_sinks, sinks, patch);
-    } else {
-        return INVALID_OPERATION;
-    }
-}
-
-status_t DeviceHalLocal::releaseAudioPatch(audio_patch_handle_t patch) {
-    if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
-        return mDev->release_audio_patch(mDev, patch);
-    } else {
-        return INVALID_OPERATION;
-    }
-}
-
-status_t DeviceHalLocal::getAudioPort(struct audio_port *port) {
-    return mDev->get_audio_port(mDev, port);
-}
-
-status_t DeviceHalLocal::setAudioPortConfig(const struct audio_port_config *config) {
-    if (version() >= AUDIO_DEVICE_API_VERSION_3_0)
-        return mDev->set_audio_port_config(mDev, config);
-    else
-        return INVALID_OPERATION;
-}
-
-status_t DeviceHalLocal::getMicrophones(std::vector<media::MicrophoneInfo> *microphones) {
-    if (mDev->get_microphones == NULL) return INVALID_OPERATION;
-    size_t actual_mics = AUDIO_MICROPHONE_MAX_COUNT;
-    audio_microphone_characteristic_t mic_array[AUDIO_MICROPHONE_MAX_COUNT];
-    status_t status = mDev->get_microphones(mDev, &mic_array[0], &actual_mics);
-    for (size_t i = 0; i < actual_mics; i++) {
-        media::MicrophoneInfo microphoneInfo = media::MicrophoneInfo(mic_array[i]);
-        microphones->push_back(microphoneInfo);
-    }
-    return status;
-}
-
-status_t DeviceHalLocal::dump(int fd) {
-    return mDev->dump(mDev, fd);
-}
-
-void DeviceHalLocal::closeOutputStream(struct audio_stream_out *stream_out) {
-    mDev->close_output_stream(mDev, stream_out);
-}
-
-void DeviceHalLocal::closeInputStream(struct audio_stream_in *stream_in) {
-    mDev->close_input_stream(mDev, stream_in);
-}
-
-} // namespace V4_0
-} // namespace android
diff --git a/media/libaudiohal/4.0/DeviceHalLocal.h b/media/libaudiohal/4.0/DeviceHalLocal.h
deleted file mode 100644
index 08341a4..0000000
--- a/media/libaudiohal/4.0/DeviceHalLocal.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_DEVICE_HAL_LOCAL_4_0_H
-#define ANDROID_HARDWARE_DEVICE_HAL_LOCAL_4_0_H
-
-#include <hardware/audio.h>
-#include <media/audiohal/DeviceHalInterface.h>
-
-namespace android {
-namespace V4_0 {
-
-class DeviceHalLocal : public DeviceHalInterface
-{
-  public:
-    // Sets the value of 'devices' to a bitmask of 1 or more values of audio_devices_t.
-    virtual status_t getSupportedDevices(uint32_t *devices);
-
-    // Check to see if the audio hardware interface has been initialized.
-    virtual status_t initCheck();
-
-    // Set the audio volume of a voice call. Range is between 0.0 and 1.0.
-    virtual status_t setVoiceVolume(float volume);
-
-    // Set the audio volume for all audio activities other than voice call.
-    virtual status_t setMasterVolume(float volume);
-
-    // Get the current master volume value for the HAL.
-    virtual status_t getMasterVolume(float *volume);
-
-    // Called when the audio mode changes.
-    virtual status_t setMode(audio_mode_t mode);
-
-    // Muting control.
-    virtual status_t setMicMute(bool state);
-    virtual status_t getMicMute(bool *state);
-    virtual status_t setMasterMute(bool state);
-    virtual status_t getMasterMute(bool *state);
-
-    // Set global audio parameters.
-    virtual status_t setParameters(const String8& kvPairs);
-
-    // Get global audio parameters.
-    virtual status_t getParameters(const String8& keys, String8 *values);
-
-    // Returns audio input buffer size according to parameters passed.
-    virtual status_t getInputBufferSize(const struct audio_config *config,
-            size_t *size);
-
-    // Creates and opens the audio hardware output stream. The stream is closed
-    // by releasing all references to the returned object.
-    virtual status_t openOutputStream(
-            audio_io_handle_t handle,
-            audio_devices_t devices,
-            audio_output_flags_t flags,
-            struct audio_config *config,
-            const char *address,
-            sp<StreamOutHalInterface> *outStream);
-
-    // Creates and opens the audio hardware input stream. The stream is closed
-    // by releasing all references to the returned object.
-    virtual status_t openInputStream(
-            audio_io_handle_t handle,
-            audio_devices_t devices,
-            struct audio_config *config,
-            audio_input_flags_t flags,
-            const char *address,
-            audio_source_t source,
-            sp<StreamInHalInterface> *inStream);
-
-    // Returns whether createAudioPatch and releaseAudioPatch operations are supported.
-    virtual status_t supportsAudioPatches(bool *supportsPatches);
-
-    // Creates an audio patch between several source and sink ports.
-    virtual status_t createAudioPatch(
-            unsigned int num_sources,
-            const struct audio_port_config *sources,
-            unsigned int num_sinks,
-            const struct audio_port_config *sinks,
-            audio_patch_handle_t *patch);
-
-    // Releases an audio patch.
-    virtual status_t releaseAudioPatch(audio_patch_handle_t patch);
-
-    // Fills the list of supported attributes for a given audio port.
-    virtual status_t getAudioPort(struct audio_port *port);
-
-    // Set audio port configuration.
-    virtual status_t setAudioPortConfig(const struct audio_port_config *config);
-
-    // List microphones
-    virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
-
-    virtual status_t dump(int fd);
-
-    void closeOutputStream(struct audio_stream_out *stream_out);
-    void closeInputStream(struct audio_stream_in *stream_in);
-
-  private:
-    audio_hw_device_t *mDev;
-
-    friend class DevicesFactoryHalLocal;
-
-    // Can not be constructed directly by clients.
-    explicit DeviceHalLocal(audio_hw_device_t *dev);
-
-    // The destructor automatically closes the device.
-    virtual ~DeviceHalLocal();
-
-    uint32_t version() const { return mDev->common.version; }
-};
-
-} // namespace V4_0
-} // namespace android
-
-#endif // ANDROID_HARDWARE_DEVICE_HAL_LOCAL_4_0_H
diff --git a/media/libaudiohal/4.0/DevicesFactoryHalHidl.cpp b/media/libaudiohal/4.0/DevicesFactoryHalHidl.cpp
deleted file mode 100644
index c83194e..0000000
--- a/media/libaudiohal/4.0/DevicesFactoryHalHidl.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <string.h>
-
-#define LOG_TAG "DevicesFactoryHalHidl"
-//#define LOG_NDEBUG 0
-
-#include <android/hardware/audio/4.0/IDevice.h>
-#include <media/audiohal/hidl/HalDeathHandler.h>
-#include <utils/Log.h>
-
-#include "ConversionHelperHidl.h"
-#include "DeviceHalHidl.h"
-#include "DevicesFactoryHalHidl.h"
-
-using ::android::hardware::audio::V4_0::IDevice;
-using ::android::hardware::audio::V4_0::Result;
-using ::android::hardware::Return;
-
-namespace android {
-namespace V4_0 {
-
-DevicesFactoryHalHidl::DevicesFactoryHalHidl() {
-    mDevicesFactory = IDevicesFactory::getService();
-    if (mDevicesFactory != 0) {
-        // It is assumed that DevicesFactory is owned by AudioFlinger
-        // and thus have the same lifespan.
-        mDevicesFactory->linkToDeath(HalDeathHandler::getInstance(), 0 /*cookie*/);
-    } else {
-        ALOGE("Failed to obtain IDevicesFactory service, terminating process.");
-        exit(1);
-    }
-    // The MSD factory is optional
-    mDevicesFactoryMsd = IDevicesFactory::getService(AUDIO_HAL_SERVICE_NAME_MSD);
-    // TODO: Register death handler, and add 'restart' directive to audioserver.rc
-}
-
-DevicesFactoryHalHidl::~DevicesFactoryHalHidl() {
-}
-
-status_t DevicesFactoryHalHidl::openDevice(const char *name, sp<DeviceHalInterface> *device) {
-    if (mDevicesFactory == 0) return NO_INIT;
-    Result retval = Result::NOT_INITIALIZED;
-    Return<void> ret = mDevicesFactory->openDevice(
-            name,
-            [&](Result r, const sp<IDevice>& result) {
-                retval = r;
-                if (retval == Result::OK) {
-                    *device = new DeviceHalHidl(result);
-                }
-            });
-    if (ret.isOk()) {
-        if (retval == Result::OK) return OK;
-        else if (retval == Result::INVALID_ARGUMENTS) return BAD_VALUE;
-        else return NO_INIT;
-    }
-    return FAILED_TRANSACTION;
-}
-
-} // namespace V4_0
-} // namespace android
diff --git a/media/libaudiohal/4.0/DevicesFactoryHalHidl.h b/media/libaudiohal/4.0/DevicesFactoryHalHidl.h
deleted file mode 100644
index 114889b..0000000
--- a/media/libaudiohal/4.0/DevicesFactoryHalHidl.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_DEVICES_FACTORY_HAL_HIDL_4_0_H
-#define ANDROID_HARDWARE_DEVICES_FACTORY_HAL_HIDL_4_0_H
-
-#include <android/hardware/audio/4.0/IDevicesFactory.h>
-#include <media/audiohal/DevicesFactoryHalInterface.h>
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-
-#include "DeviceHalHidl.h"
-
-using ::android::hardware::audio::V4_0::IDevicesFactory;
-
-namespace android {
-namespace V4_0 {
-
-class DevicesFactoryHalHidl : public DevicesFactoryHalInterface
-{
-  public:
-    // Opens a device with the specified name. To close the device, it is
-    // necessary to release references to the returned object.
-    virtual status_t openDevice(const char *name, sp<DeviceHalInterface> *device);
-
-  private:
-    friend class DevicesFactoryHalHybrid;
-
-    sp<IDevicesFactory> mDevicesFactory;
-    sp<IDevicesFactory> mDevicesFactoryMsd;
-
-    // Can not be constructed directly by clients.
-    DevicesFactoryHalHidl();
-
-    virtual ~DevicesFactoryHalHidl();
-};
-
-} // namespace V4_0
-} // namespace android
-
-#endif // ANDROID_HARDWARE_DEVICES_FACTORY_HAL_HIDL_4_0_H
diff --git a/media/libaudiohal/4.0/DevicesFactoryHalHybrid.cpp b/media/libaudiohal/4.0/DevicesFactoryHalHybrid.cpp
deleted file mode 100644
index 7ff1ec7d..0000000
--- a/media/libaudiohal/4.0/DevicesFactoryHalHybrid.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "DevicesFactoryHalHybrid"
-//#define LOG_NDEBUG 0
-
-#include <libaudiohal/4.0/DevicesFactoryHalHybrid.h>
-#include "DevicesFactoryHalLocal.h"
-#include "DevicesFactoryHalHidl.h"
-
-namespace android {
-namespace V4_0 {
-
-DevicesFactoryHalHybrid::DevicesFactoryHalHybrid()
-        : mLocalFactory(new DevicesFactoryHalLocal()),
-          mHidlFactory(new DevicesFactoryHalHidl()) {
-}
-
-DevicesFactoryHalHybrid::~DevicesFactoryHalHybrid() {
-}
-
-status_t DevicesFactoryHalHybrid::openDevice(const char *name, sp<DeviceHalInterface> *device) {
-    if (mHidlFactory != 0 && strcmp(AUDIO_HARDWARE_MODULE_ID_A2DP, name) != 0 &&
-        strcmp(AUDIO_HARDWARE_MODULE_ID_HEARING_AID, name) != 0) {
-        return mHidlFactory->openDevice(name, device);
-    }
-    return mLocalFactory->openDevice(name, device);
-}
-
-} // namespace V4_0
-} // namespace android
diff --git a/media/libaudiohal/4.0/DevicesFactoryHalLocal.cpp b/media/libaudiohal/4.0/DevicesFactoryHalLocal.cpp
deleted file mode 100644
index e54edd4..0000000
--- a/media/libaudiohal/4.0/DevicesFactoryHalLocal.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "DevicesFactoryHalLocal"
-//#define LOG_NDEBUG 0
-
-#include <string.h>
-
-#include <hardware/audio.h>
-#include <utils/Log.h>
-
-#include "DeviceHalLocal.h"
-#include "DevicesFactoryHalLocal.h"
-
-namespace android {
-namespace V4_0 {
-
-static status_t load_audio_interface(const char *if_name, audio_hw_device_t **dev)
-{
-    const hw_module_t *mod;
-    int rc;
-
-    rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
-    if (rc) {
-        ALOGE("%s couldn't load audio hw module %s.%s (%s)", __func__,
-                AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
-        goto out;
-    }
-    rc = audio_hw_device_open(mod, dev);
-    if (rc) {
-        ALOGE("%s couldn't open audio hw device in %s.%s (%s)", __func__,
-                AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
-        goto out;
-    }
-    if ((*dev)->common.version < AUDIO_DEVICE_API_VERSION_MIN) {
-        ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version);
-        rc = BAD_VALUE;
-        audio_hw_device_close(*dev);
-        goto out;
-    }
-    return OK;
-
-out:
-    *dev = NULL;
-    return rc;
-}
-
-status_t DevicesFactoryHalLocal::openDevice(const char *name, sp<DeviceHalInterface> *device) {
-    audio_hw_device_t *dev;
-    status_t rc = load_audio_interface(name, &dev);
-    if (rc == OK) {
-        *device = new DeviceHalLocal(dev);
-    }
-    return rc;
-}
-
-} // namespace V4_0
-} // namespace android
diff --git a/media/libaudiohal/4.0/DevicesFactoryHalLocal.h b/media/libaudiohal/4.0/DevicesFactoryHalLocal.h
deleted file mode 100644
index bc1c521..0000000
--- a/media/libaudiohal/4.0/DevicesFactoryHalLocal.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_DEVICES_FACTORY_HAL_LOCAL_4_0_H
-#define ANDROID_HARDWARE_DEVICES_FACTORY_HAL_LOCAL_4_0_H
-
-#include <media/audiohal/DevicesFactoryHalInterface.h>
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-
-#include "DeviceHalLocal.h"
-
-namespace android {
-namespace V4_0 {
-
-class DevicesFactoryHalLocal : public DevicesFactoryHalInterface
-{
-  public:
-    // Opens a device with the specified name. To close the device, it is
-    // necessary to release references to the returned object.
-    virtual status_t openDevice(const char *name, sp<DeviceHalInterface> *device);
-
-  private:
-    friend class DevicesFactoryHalHybrid;
-
-    // Can not be constructed directly by clients.
-    DevicesFactoryHalLocal() {}
-
-    virtual ~DevicesFactoryHalLocal() {}
-};
-
-} // namespace V4_0
-} // namespace android
-
-#endif // ANDROID_HARDWARE_DEVICES_FACTORY_HAL_LOCAL_4_0_H
diff --git a/media/libaudiohal/4.0/EffectBufferHalHidl.cpp b/media/libaudiohal/4.0/EffectBufferHalHidl.cpp
deleted file mode 100644
index 957c89f..0000000
--- a/media/libaudiohal/4.0/EffectBufferHalHidl.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <atomic>
-
-#define LOG_TAG "EffectBufferHalHidl"
-//#define LOG_NDEBUG 0
-
-#include <android/hidl/allocator/1.0/IAllocator.h>
-#include <hidlmemory/mapping.h>
-#include <utils/Log.h>
-
-#include "ConversionHelperHidl.h"
-#include "EffectBufferHalHidl.h"
-
-using ::android::hardware::Return;
-using ::android::hidl::allocator::V1_0::IAllocator;
-
-namespace android {
-namespace V4_0 {
-
-// static
-uint64_t EffectBufferHalHidl::makeUniqueId() {
-    static std::atomic<uint64_t> counter{1};
-    return counter++;
-}
-
-status_t EffectBufferHalHidl::allocate(
-        size_t size, sp<EffectBufferHalInterface>* buffer) {
-    return mirror(nullptr, size, buffer);
-}
-
-status_t EffectBufferHalHidl::mirror(
-        void* external, size_t size, sp<EffectBufferHalInterface>* buffer) {
-    sp<EffectBufferHalInterface> tempBuffer = new EffectBufferHalHidl(size);
-    status_t result = static_cast<EffectBufferHalHidl*>(tempBuffer.get())->init();
-    if (result == OK) {
-        tempBuffer->setExternalData(external);
-        *buffer = tempBuffer;
-    }
-    return result;
-}
-
-EffectBufferHalHidl::EffectBufferHalHidl(size_t size)
-        : mBufferSize(size), mFrameCountChanged(false),
-          mExternalData(nullptr), mAudioBuffer{0, {nullptr}} {
-    mHidlBuffer.id = makeUniqueId();
-    mHidlBuffer.frameCount = 0;
-}
-
-EffectBufferHalHidl::~EffectBufferHalHidl() {
-}
-
-status_t EffectBufferHalHidl::init() {
-    sp<IAllocator> ashmem = IAllocator::getService("ashmem");
-    if (ashmem == 0) {
-        ALOGE("Failed to retrieve ashmem allocator service");
-        return NO_INIT;
-    }
-    status_t retval = NO_MEMORY;
-    Return<void> result = ashmem->allocate(
-            mBufferSize,
-            [&](bool success, const hidl_memory& memory) {
-                if (success) {
-                    mHidlBuffer.data = memory;
-                    retval = OK;
-                }
-            });
-    if (result.isOk() && retval == OK) {
-        mMemory = hardware::mapMemory(mHidlBuffer.data);
-        if (mMemory != 0) {
-            mMemory->update();
-            mAudioBuffer.raw = static_cast<void*>(mMemory->getPointer());
-            memset(mAudioBuffer.raw, 0, mMemory->getSize());
-            mMemory->commit();
-        } else {
-            ALOGE("Failed to map allocated ashmem");
-            retval = NO_MEMORY;
-        }
-    } else {
-        ALOGE("Failed to allocate %d bytes from ashmem", (int)mBufferSize);
-    }
-    return result.isOk() ? retval : FAILED_TRANSACTION;
-}
-
-audio_buffer_t* EffectBufferHalHidl::audioBuffer() {
-    return &mAudioBuffer;
-}
-
-void* EffectBufferHalHidl::externalData() const {
-    return mExternalData;
-}
-
-void EffectBufferHalHidl::setFrameCount(size_t frameCount) {
-    mHidlBuffer.frameCount = frameCount;
-    mAudioBuffer.frameCount = frameCount;
-    mFrameCountChanged = true;
-}
-
-bool EffectBufferHalHidl::checkFrameCountChange() {
-    bool result = mFrameCountChanged;
-    mFrameCountChanged = false;
-    return result;
-}
-
-void EffectBufferHalHidl::setExternalData(void* external) {
-    mExternalData = external;
-}
-
-void EffectBufferHalHidl::update() {
-    update(mBufferSize);
-}
-
-void EffectBufferHalHidl::commit() {
-    commit(mBufferSize);
-}
-
-void EffectBufferHalHidl::update(size_t size) {
-    if (mExternalData == nullptr) return;
-    mMemory->update();
-    if (size > mBufferSize) size = mBufferSize;
-    memcpy(mAudioBuffer.raw, mExternalData, size);
-    mMemory->commit();
-}
-
-void EffectBufferHalHidl::commit(size_t size) {
-    if (mExternalData == nullptr) return;
-    if (size > mBufferSize) size = mBufferSize;
-    memcpy(mExternalData, mAudioBuffer.raw, size);
-}
-
-} // namespace V4_0
-} // namespace android
diff --git a/media/libaudiohal/4.0/EffectBufferHalHidl.h b/media/libaudiohal/4.0/EffectBufferHalHidl.h
deleted file mode 100644
index 6d578c6..0000000
--- a/media/libaudiohal/4.0/EffectBufferHalHidl.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_EFFECT_BUFFER_HAL_HIDL_4_0_H
-#define ANDROID_HARDWARE_EFFECT_BUFFER_HAL_HIDL_4_0_H
-
-#include <android/hardware/audio/effect/4.0/types.h>
-#include <android/hidl/memory/1.0/IMemory.h>
-#include <hidl/HidlSupport.h>
-#include <media/audiohal/EffectBufferHalInterface.h>
-#include <system/audio_effect.h>
-
-using android::hardware::audio::effect::V4_0::AudioBuffer;
-using android::hardware::hidl_memory;
-using android::hidl::memory::V1_0::IMemory;
-
-namespace android {
-namespace V4_0 {
-
-class EffectBufferHalHidl : public EffectBufferHalInterface
-{
-  public:
-    static status_t allocate(size_t size, sp<EffectBufferHalInterface>* buffer);
-    static status_t mirror(void* external, size_t size, sp<EffectBufferHalInterface>* buffer);
-
-    virtual audio_buffer_t* audioBuffer();
-    virtual void* externalData() const;
-
-    virtual size_t getSize() const override { return mBufferSize; }
-
-    virtual void setExternalData(void* external);
-    virtual void setFrameCount(size_t frameCount);
-    virtual bool checkFrameCountChange();
-
-    virtual void update();
-    virtual void commit();
-    virtual void update(size_t size);
-    virtual void commit(size_t size);
-
-    const AudioBuffer& hidlBuffer() const { return mHidlBuffer; }
-
-  private:
-    friend class EffectBufferHalInterface;
-
-    static uint64_t makeUniqueId();
-
-    const size_t mBufferSize;
-    bool mFrameCountChanged;
-    void* mExternalData;
-    AudioBuffer mHidlBuffer;
-    sp<IMemory> mMemory;
-    audio_buffer_t mAudioBuffer;
-
-    // Can not be constructed directly by clients.
-    explicit EffectBufferHalHidl(size_t size);
-
-    virtual ~EffectBufferHalHidl();
-
-    status_t init();
-};
-
-} // namespace V4_0
-} // namespace android
-
-#endif // ANDROID_HARDWARE_EFFECT_BUFFER_HAL_HIDL_4_0_H
diff --git a/media/libaudiohal/4.0/EffectHalHidl.cpp b/media/libaudiohal/4.0/EffectHalHidl.cpp
deleted file mode 100644
index c99c4c8..0000000
--- a/media/libaudiohal/4.0/EffectHalHidl.cpp
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "EffectHalHidl"
-//#define LOG_NDEBUG 0
-
-#include <common/all-versions/VersionUtils.h>
-#include <hwbinder/IPCThreadState.h>
-#include <media/EffectsFactoryApi.h>
-#include <utils/Log.h>
-
-#include "ConversionHelperHidl.h"
-#include "EffectBufferHalHidl.h"
-#include "EffectHalHidl.h"
-#include "HidlUtils.h"
-
-using ::android::hardware::audio::effect::V4_0::AudioBuffer;
-using ::android::hardware::audio::effect::V4_0::EffectBufferAccess;
-using ::android::hardware::audio::effect::V4_0::EffectConfigParameters;
-using ::android::hardware::audio::effect::V4_0::MessageQueueFlagBits;
-using ::android::hardware::audio::effect::V4_0::Result;
-using ::android::hardware::audio::common::V4_0::HidlUtils;
-using ::android::hardware::audio::common::V4_0::AudioChannelMask;
-using ::android::hardware::audio::common::V4_0::AudioFormat;
-using ::android::hardware::audio::common::utils::mkEnumConverter;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::MQDescriptorSync;
-using ::android::hardware::Return;
-
-namespace android {
-namespace V4_0 {
-
-EffectHalHidl::EffectHalHidl(const sp<IEffect>& effect, uint64_t effectId)
-        : mEffect(effect), mEffectId(effectId), mBuffersChanged(true), mEfGroup(nullptr) {
-}
-
-EffectHalHidl::~EffectHalHidl() {
-    if (mEffect != 0) {
-        close();
-        mEffect.clear();
-        hardware::IPCThreadState::self()->flushCommands();
-    }
-    if (mEfGroup) {
-        EventFlag::deleteEventFlag(&mEfGroup);
-    }
-}
-
-// static
-void EffectHalHidl::effectDescriptorToHal(
-        const EffectDescriptor& descriptor, effect_descriptor_t* halDescriptor) {
-    HidlUtils::uuidToHal(descriptor.type, &halDescriptor->type);
-    HidlUtils::uuidToHal(descriptor.uuid, &halDescriptor->uuid);
-    halDescriptor->flags = static_cast<uint32_t>(descriptor.flags);
-    halDescriptor->cpuLoad = descriptor.cpuLoad;
-    halDescriptor->memoryUsage = descriptor.memoryUsage;
-    memcpy(halDescriptor->name, descriptor.name.data(), descriptor.name.size());
-    memcpy(halDescriptor->implementor,
-            descriptor.implementor.data(), descriptor.implementor.size());
-}
-
-// TODO(mnaganov): These buffer conversion functions should be shared with Effect wrapper
-// via HidlUtils. Move them there when hardware/interfaces will get un-frozen again.
-
-// static
-void EffectHalHidl::effectBufferConfigFromHal(
-        const buffer_config_t& halConfig, EffectBufferConfig* config) {
-    config->samplingRateHz = halConfig.samplingRate;
-    config->channels = mkEnumConverter<AudioChannelMask>(halConfig.channels);
-    config->format = AudioFormat(halConfig.format);
-    config->accessMode = EffectBufferAccess(halConfig.accessMode);
-    config->mask = mkEnumConverter<EffectConfigParameters>(halConfig.mask);
-}
-
-// static
-void EffectHalHidl::effectBufferConfigToHal(
-        const EffectBufferConfig& config, buffer_config_t* halConfig) {
-    halConfig->buffer.frameCount = 0;
-    halConfig->buffer.raw = NULL;
-    halConfig->samplingRate = config.samplingRateHz;
-    halConfig->channels = static_cast<uint32_t>(config.channels);
-    halConfig->bufferProvider.cookie = NULL;
-    halConfig->bufferProvider.getBuffer = NULL;
-    halConfig->bufferProvider.releaseBuffer = NULL;
-    halConfig->format = static_cast<uint8_t>(config.format);
-    halConfig->accessMode = static_cast<uint8_t>(config.accessMode);
-    halConfig->mask = static_cast<uint8_t>(config.mask);
-}
-
-// static
-void EffectHalHidl::effectConfigFromHal(const effect_config_t& halConfig, EffectConfig* config) {
-    effectBufferConfigFromHal(halConfig.inputCfg, &config->inputCfg);
-    effectBufferConfigFromHal(halConfig.outputCfg, &config->outputCfg);
-}
-
-// static
-void EffectHalHidl::effectConfigToHal(const EffectConfig& config, effect_config_t* halConfig) {
-    effectBufferConfigToHal(config.inputCfg, &halConfig->inputCfg);
-    effectBufferConfigToHal(config.outputCfg, &halConfig->outputCfg);
-}
-
-// static
-status_t EffectHalHidl::analyzeResult(const Result& result) {
-    switch (result) {
-        case Result::OK: return OK;
-        case Result::INVALID_ARGUMENTS: return BAD_VALUE;
-        case Result::INVALID_STATE: return NOT_ENOUGH_DATA;
-        case Result::NOT_INITIALIZED: return NO_INIT;
-        case Result::NOT_SUPPORTED: return INVALID_OPERATION;
-        case Result::RESULT_TOO_BIG: return NO_MEMORY;
-        default: return NO_INIT;
-    }
-}
-
-status_t EffectHalHidl::setInBuffer(const sp<EffectBufferHalInterface>& buffer) {
-    if (!mBuffersChanged) {
-        if (buffer.get() == nullptr || mInBuffer.get() == nullptr) {
-            mBuffersChanged = buffer.get() != mInBuffer.get();
-        } else {
-            mBuffersChanged = buffer->audioBuffer() != mInBuffer->audioBuffer();
-        }
-    }
-    mInBuffer = buffer;
-    return OK;
-}
-
-status_t EffectHalHidl::setOutBuffer(const sp<EffectBufferHalInterface>& buffer) {
-    if (!mBuffersChanged) {
-        if (buffer.get() == nullptr || mOutBuffer.get() == nullptr) {
-            mBuffersChanged = buffer.get() != mOutBuffer.get();
-        } else {
-            mBuffersChanged = buffer->audioBuffer() != mOutBuffer->audioBuffer();
-        }
-    }
-    mOutBuffer = buffer;
-    return OK;
-}
-
-status_t EffectHalHidl::process() {
-    return processImpl(static_cast<uint32_t>(MessageQueueFlagBits::REQUEST_PROCESS));
-}
-
-status_t EffectHalHidl::processReverse() {
-    return processImpl(static_cast<uint32_t>(MessageQueueFlagBits::REQUEST_PROCESS_REVERSE));
-}
-
-status_t EffectHalHidl::prepareForProcessing() {
-    std::unique_ptr<StatusMQ> tempStatusMQ;
-    Result retval;
-    Return<void> ret = mEffect->prepareForProcessing(
-            [&](Result r, const MQDescriptorSync<Result>& statusMQ) {
-                retval = r;
-                if (retval == Result::OK) {
-                    tempStatusMQ.reset(new StatusMQ(statusMQ));
-                    if (tempStatusMQ->isValid() && tempStatusMQ->getEventFlagWord()) {
-                        EventFlag::createEventFlag(tempStatusMQ->getEventFlagWord(), &mEfGroup);
-                    }
-                }
-            });
-    if (!ret.isOk() || retval != Result::OK) {
-        return ret.isOk() ? analyzeResult(retval) : FAILED_TRANSACTION;
-    }
-    if (!tempStatusMQ || !tempStatusMQ->isValid() || !mEfGroup) {
-        ALOGE_IF(!tempStatusMQ, "Failed to obtain status message queue for effects");
-        ALOGE_IF(tempStatusMQ && !tempStatusMQ->isValid(),
-                "Status message queue for effects is invalid");
-        ALOGE_IF(!mEfGroup, "Event flag creation for effects failed");
-        return NO_INIT;
-    }
-    mStatusMQ = std::move(tempStatusMQ);
-    return OK;
-}
-
-bool EffectHalHidl::needToResetBuffers() {
-    if (mBuffersChanged) return true;
-    bool inBufferFrameCountUpdated = mInBuffer->checkFrameCountChange();
-    bool outBufferFrameCountUpdated = mOutBuffer->checkFrameCountChange();
-    return inBufferFrameCountUpdated || outBufferFrameCountUpdated;
-}
-
-status_t EffectHalHidl::processImpl(uint32_t mqFlag) {
-    if (mEffect == 0 || mInBuffer == 0 || mOutBuffer == 0) return NO_INIT;
-    status_t status;
-    if (!mStatusMQ && (status = prepareForProcessing()) != OK) {
-        return status;
-    }
-    if (needToResetBuffers() && (status = setProcessBuffers()) != OK) {
-        return status;
-    }
-    // The data is already in the buffers, just need to flush it and wake up the server side.
-    std::atomic_thread_fence(std::memory_order_release);
-    mEfGroup->wake(mqFlag);
-    uint32_t efState = 0;
-retry:
-    status_t ret = mEfGroup->wait(
-            static_cast<uint32_t>(MessageQueueFlagBits::DONE_PROCESSING), &efState);
-    if (efState & static_cast<uint32_t>(MessageQueueFlagBits::DONE_PROCESSING)) {
-        Result retval = Result::NOT_INITIALIZED;
-        mStatusMQ->read(&retval);
-        if (retval == Result::OK || retval == Result::INVALID_STATE) {
-            // Sync back the changed contents of the buffer.
-            std::atomic_thread_fence(std::memory_order_acquire);
-        }
-        return analyzeResult(retval);
-    }
-    if (ret == -EAGAIN || ret == -EINTR) {
-        // Spurious wakeup. This normally retries no more than once.
-        goto retry;
-    }
-    return ret;
-}
-
-status_t EffectHalHidl::setProcessBuffers() {
-    Return<Result> ret = mEffect->setProcessBuffers(
-            static_cast<EffectBufferHalHidl*>(mInBuffer.get())->hidlBuffer(),
-            static_cast<EffectBufferHalHidl*>(mOutBuffer.get())->hidlBuffer());
-    if (ret.isOk() && ret == Result::OK) {
-        mBuffersChanged = false;
-        return OK;
-    }
-    return ret.isOk() ? analyzeResult(ret) : FAILED_TRANSACTION;
-}
-
-status_t EffectHalHidl::command(uint32_t cmdCode, uint32_t cmdSize, void *pCmdData,
-        uint32_t *replySize, void *pReplyData) {
-    if (mEffect == 0) return NO_INIT;
-
-    // Special cases.
-    if (cmdCode == EFFECT_CMD_SET_CONFIG || cmdCode == EFFECT_CMD_SET_CONFIG_REVERSE) {
-        return setConfigImpl(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
-    } else if (cmdCode == EFFECT_CMD_GET_CONFIG || cmdCode == EFFECT_CMD_GET_CONFIG_REVERSE) {
-        return getConfigImpl(cmdCode, replySize, pReplyData);
-    }
-
-    // Common case.
-    hidl_vec<uint8_t> hidlData;
-    if (pCmdData != nullptr && cmdSize > 0) {
-        hidlData.setToExternal(reinterpret_cast<uint8_t*>(pCmdData), cmdSize);
-    }
-    status_t status;
-    uint32_t replySizeStub = 0;
-    if (replySize == nullptr || pReplyData == nullptr) replySize = &replySizeStub;
-    Return<void> ret = mEffect->command(cmdCode, hidlData, *replySize,
-            [&](int32_t s, const hidl_vec<uint8_t>& result) {
-                status = s;
-                if (status == 0) {
-                    if (*replySize > result.size()) *replySize = result.size();
-                    if (pReplyData != nullptr && *replySize > 0) {
-                        memcpy(pReplyData, &result[0], *replySize);
-                    }
-                }
-            });
-    return ret.isOk() ? status : FAILED_TRANSACTION;
-}
-
-status_t EffectHalHidl::getDescriptor(effect_descriptor_t *pDescriptor) {
-    if (mEffect == 0) return NO_INIT;
-    Result retval = Result::NOT_INITIALIZED;
-    Return<void> ret = mEffect->getDescriptor(
-            [&](Result r, const EffectDescriptor& result) {
-                retval = r;
-                if (retval == Result::OK) {
-                    effectDescriptorToHal(result, pDescriptor);
-                }
-            });
-    return ret.isOk() ? analyzeResult(retval) : FAILED_TRANSACTION;
-}
-
-status_t EffectHalHidl::close() {
-    if (mEffect == 0) return NO_INIT;
-    Return<Result> ret = mEffect->close();
-    return ret.isOk() ? analyzeResult(ret) : FAILED_TRANSACTION;
-}
-
-status_t EffectHalHidl::getConfigImpl(
-        uint32_t cmdCode, uint32_t *replySize, void *pReplyData) {
-    if (replySize == NULL || *replySize != sizeof(effect_config_t) || pReplyData == NULL) {
-        return BAD_VALUE;
-    }
-    status_t result = FAILED_TRANSACTION;
-    Return<void> ret;
-    if (cmdCode == EFFECT_CMD_GET_CONFIG) {
-        ret = mEffect->getConfig([&] (Result r, const EffectConfig &hidlConfig) {
-            result = analyzeResult(r);
-            if (r == Result::OK) {
-                effectConfigToHal(hidlConfig, static_cast<effect_config_t*>(pReplyData));
-            }
-        });
-    } else {
-        ret = mEffect->getConfigReverse([&] (Result r, const EffectConfig &hidlConfig) {
-            result = analyzeResult(r);
-            if (r == Result::OK) {
-                effectConfigToHal(hidlConfig, static_cast<effect_config_t*>(pReplyData));
-            }
-        });
-    }
-    if (!ret.isOk()) {
-        result = FAILED_TRANSACTION;
-    }
-    return result;
-}
-
-status_t EffectHalHidl::setConfigImpl(
-        uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, uint32_t *replySize, void *pReplyData) {
-    if (pCmdData == NULL || cmdSize != sizeof(effect_config_t) ||
-            replySize == NULL || *replySize != sizeof(int32_t) || pReplyData == NULL) {
-        return BAD_VALUE;
-    }
-    const effect_config_t *halConfig = static_cast<effect_config_t*>(pCmdData);
-    if (halConfig->inputCfg.bufferProvider.getBuffer != NULL ||
-            halConfig->inputCfg.bufferProvider.releaseBuffer != NULL ||
-            halConfig->outputCfg.bufferProvider.getBuffer != NULL ||
-            halConfig->outputCfg.bufferProvider.releaseBuffer != NULL) {
-        ALOGE("Buffer provider callbacks are not supported");
-    }
-    EffectConfig hidlConfig;
-    effectConfigFromHal(*halConfig, &hidlConfig);
-    Return<Result> ret = cmdCode == EFFECT_CMD_SET_CONFIG ?
-            mEffect->setConfig(hidlConfig, nullptr, nullptr) :
-            mEffect->setConfigReverse(hidlConfig, nullptr, nullptr);
-    status_t result = FAILED_TRANSACTION;
-    if (ret.isOk()) {
-        result = analyzeResult(ret);
-        *static_cast<int32_t*>(pReplyData) = result;
-    }
-    return result;
-}
-
-} // namespace V4_0
-} // namespace android
diff --git a/media/libaudiohal/4.0/EffectHalHidl.h b/media/libaudiohal/4.0/EffectHalHidl.h
deleted file mode 100644
index 5a4dab1..0000000
--- a/media/libaudiohal/4.0/EffectHalHidl.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_EFFECT_HAL_HIDL_4_0_H
-#define ANDROID_HARDWARE_EFFECT_HAL_HIDL_4_0_H
-
-#include <android/hardware/audio/effect/4.0/IEffect.h>
-#include <media/audiohal/EffectHalInterface.h>
-#include <fmq/EventFlag.h>
-#include <fmq/MessageQueue.h>
-#include <system/audio_effect.h>
-
-using ::android::hardware::audio::effect::V4_0::EffectBufferConfig;
-using ::android::hardware::audio::effect::V4_0::EffectConfig;
-using ::android::hardware::audio::effect::V4_0::EffectDescriptor;
-using ::android::hardware::audio::effect::V4_0::IEffect;
-using ::android::hardware::EventFlag;
-using ::android::hardware::MessageQueue;
-
-namespace android {
-namespace V4_0 {
-
-class EffectHalHidl : public EffectHalInterface
-{
-  public:
-    // Set the input buffer.
-    virtual status_t setInBuffer(const sp<EffectBufferHalInterface>& buffer);
-
-    // Set the output buffer.
-    virtual status_t setOutBuffer(const sp<EffectBufferHalInterface>& buffer);
-
-    // Effect process function.
-    virtual status_t process();
-
-    // Process reverse stream function. This function is used to pass
-    // a reference stream to the effect engine.
-    virtual status_t processReverse();
-
-    // Send a command and receive a response to/from effect engine.
-    virtual status_t command(uint32_t cmdCode, uint32_t cmdSize, void *pCmdData,
-            uint32_t *replySize, void *pReplyData);
-
-    // Returns the effect descriptor.
-    virtual status_t getDescriptor(effect_descriptor_t *pDescriptor);
-
-    // Free resources on the remote side.
-    virtual status_t close();
-
-    // Whether it's a local implementation.
-    virtual bool isLocal() const { return false; }
-
-    uint64_t effectId() const { return mEffectId; }
-
-    static void effectDescriptorToHal(
-            const EffectDescriptor& descriptor, effect_descriptor_t* halDescriptor);
-
-  private:
-    friend class EffectsFactoryHalHidl;
-    typedef MessageQueue<
-        hardware::audio::effect::V4_0::Result, hardware::kSynchronizedReadWrite> StatusMQ;
-
-    sp<IEffect> mEffect;
-    const uint64_t mEffectId;
-    sp<EffectBufferHalInterface> mInBuffer;
-    sp<EffectBufferHalInterface> mOutBuffer;
-    bool mBuffersChanged;
-    std::unique_ptr<StatusMQ> mStatusMQ;
-    EventFlag* mEfGroup;
-
-    static status_t analyzeResult(const hardware::audio::effect::V4_0::Result& result);
-    static void effectBufferConfigFromHal(
-            const buffer_config_t& halConfig, EffectBufferConfig* config);
-    static void effectBufferConfigToHal(
-            const EffectBufferConfig& config, buffer_config_t* halConfig);
-    static void effectConfigFromHal(const effect_config_t& halConfig, EffectConfig* config);
-    static void effectConfigToHal(const EffectConfig& config, effect_config_t* halConfig);
-
-    // Can not be constructed directly by clients.
-    EffectHalHidl(const sp<IEffect>& effect, uint64_t effectId);
-
-    // The destructor automatically releases the effect.
-    virtual ~EffectHalHidl();
-
-    status_t getConfigImpl(uint32_t cmdCode, uint32_t *replySize, void *pReplyData);
-    status_t prepareForProcessing();
-    bool needToResetBuffers();
-    status_t processImpl(uint32_t mqFlag);
-    status_t setConfigImpl(
-            uint32_t cmdCode, uint32_t cmdSize, void *pCmdData,
-            uint32_t *replySize, void *pReplyData);
-    status_t setProcessBuffers();
-};
-
-} // namespace V4_0
-} // namespace android
-
-#endif // ANDROID_HARDWARE_EFFECT_HAL_HIDL_4_0_H
diff --git a/media/libaudiohal/4.0/EffectsFactoryHalHidl.cpp b/media/libaudiohal/4.0/EffectsFactoryHalHidl.cpp
deleted file mode 100644
index dfed784..0000000
--- a/media/libaudiohal/4.0/EffectsFactoryHalHidl.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "EffectsFactoryHalHidl"
-//#define LOG_NDEBUG 0
-
-#include <cutils/native_handle.h>
-#include <libaudiohal/4.0/EffectsFactoryHalHidl.h>
-
-#include "ConversionHelperHidl.h"
-#include "EffectBufferHalHidl.h"
-#include "EffectHalHidl.h"
-#include "HidlUtils.h"
-
-using ::android::hardware::audio::common::V4_0::HidlUtils;
-using ::android::hardware::audio::common::V4_0::Uuid;
-using ::android::hardware::audio::effect::V4_0::IEffect;
-using ::android::hardware::audio::effect::V4_0::Result;
-using ::android::hardware::Return;
-
-namespace android {
-namespace V4_0 {
-
-EffectsFactoryHalHidl::EffectsFactoryHalHidl() : ConversionHelperHidl("EffectsFactory") {
-    mEffectsFactory = IEffectsFactory::getService();
-    if (mEffectsFactory == 0) {
-        ALOGE("Failed to obtain IEffectsFactory service, terminating process.");
-        exit(1);
-    }
-}
-
-EffectsFactoryHalHidl::~EffectsFactoryHalHidl() {
-}
-
-status_t EffectsFactoryHalHidl::queryAllDescriptors() {
-    if (mEffectsFactory == 0) return NO_INIT;
-    Result retval = Result::NOT_INITIALIZED;
-    Return<void> ret = mEffectsFactory->getAllDescriptors(
-            [&](Result r, const hidl_vec<EffectDescriptor>& result) {
-                retval = r;
-                if (retval == Result::OK) {
-                    mLastDescriptors = result;
-                }
-            });
-    if (ret.isOk()) {
-        return retval == Result::OK ? OK : NO_INIT;
-    }
-    mLastDescriptors.resize(0);
-    return processReturn(__FUNCTION__, ret);
-}
-
-status_t EffectsFactoryHalHidl::queryNumberEffects(uint32_t *pNumEffects) {
-    status_t queryResult = queryAllDescriptors();
-    if (queryResult == OK) {
-        *pNumEffects = mLastDescriptors.size();
-    }
-    return queryResult;
-}
-
-status_t EffectsFactoryHalHidl::getDescriptor(
-        uint32_t index, effect_descriptor_t *pDescriptor) {
-    // TODO: We need somehow to track the changes on the server side
-    // or figure out how to convert everybody to query all the descriptors at once.
-    // TODO: check for nullptr
-    if (mLastDescriptors.size() == 0) {
-        status_t queryResult = queryAllDescriptors();
-        if (queryResult != OK) return queryResult;
-    }
-    if (index >= mLastDescriptors.size()) return NAME_NOT_FOUND;
-    EffectHalHidl::effectDescriptorToHal(mLastDescriptors[index], pDescriptor);
-    return OK;
-}
-
-status_t EffectsFactoryHalHidl::getDescriptor(
-        const effect_uuid_t *pEffectUuid, effect_descriptor_t *pDescriptor) {
-    // TODO: check for nullptr
-    if (mEffectsFactory == 0) return NO_INIT;
-    Uuid hidlUuid;
-    HidlUtils::uuidFromHal(*pEffectUuid, &hidlUuid);
-    Result retval = Result::NOT_INITIALIZED;
-    Return<void> ret = mEffectsFactory->getDescriptor(hidlUuid,
-            [&](Result r, const EffectDescriptor& result) {
-                retval = r;
-                if (retval == Result::OK) {
-                    EffectHalHidl::effectDescriptorToHal(result, pDescriptor);
-                }
-            });
-    if (ret.isOk()) {
-        if (retval == Result::OK) return OK;
-        else if (retval == Result::INVALID_ARGUMENTS) return NAME_NOT_FOUND;
-        else return NO_INIT;
-    }
-    return processReturn(__FUNCTION__, ret);
-}
-
-status_t EffectsFactoryHalHidl::createEffect(
-        const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t ioId,
-        sp<EffectHalInterface> *effect) {
-    if (mEffectsFactory == 0) return NO_INIT;
-    Uuid hidlUuid;
-    HidlUtils::uuidFromHal(*pEffectUuid, &hidlUuid);
-    Result retval = Result::NOT_INITIALIZED;
-    Return<void> ret = mEffectsFactory->createEffect(
-            hidlUuid, sessionId, ioId,
-            [&](Result r, const sp<IEffect>& result, uint64_t effectId) {
-                retval = r;
-                if (retval == Result::OK) {
-                    *effect = new EffectHalHidl(result, effectId);
-                }
-            });
-    if (ret.isOk()) {
-        if (retval == Result::OK) return OK;
-        else if (retval == Result::INVALID_ARGUMENTS) return NAME_NOT_FOUND;
-        else return NO_INIT;
-    }
-    return processReturn(__FUNCTION__, ret);
-}
-
-status_t EffectsFactoryHalHidl::dumpEffects(int fd) {
-    if (mEffectsFactory == 0) return NO_INIT;
-    native_handle_t* hidlHandle = native_handle_create(1, 0);
-    hidlHandle->data[0] = fd;
-    Return<void> ret = mEffectsFactory->debug(hidlHandle, {} /* options */);
-    native_handle_delete(hidlHandle);
-    return processReturn(__FUNCTION__, ret);
-}
-
-status_t EffectsFactoryHalHidl::allocateBuffer(size_t size, sp<EffectBufferHalInterface>* buffer) {
-    return EffectBufferHalHidl::allocate(size, buffer);
-}
-
-status_t EffectsFactoryHalHidl::mirrorBuffer(void* external, size_t size,
-                          sp<EffectBufferHalInterface>* buffer) {
-    return EffectBufferHalHidl::mirror(external, size, buffer);
-}
-
-
-} // namespace V4_0
-} // namespace android
diff --git a/media/libaudiohal/4.0/StreamHalHidl.cpp b/media/libaudiohal/4.0/StreamHalHidl.cpp
deleted file mode 100644
index 1c2fdb0..0000000
--- a/media/libaudiohal/4.0/StreamHalHidl.cpp
+++ /dev/null
@@ -1,817 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "StreamHalHidl"
-//#define LOG_NDEBUG 0
-
-#include <android/hardware/audio/4.0/IStreamOutCallback.h>
-#include <hwbinder/IPCThreadState.h>
-#include <mediautils/SchedulingPolicyService.h>
-#include <utils/Log.h>
-
-#include "DeviceHalHidl.h"
-#include "EffectHalHidl.h"
-#include "StreamHalHidl.h"
-#include "VersionUtils.h"
-
-using ::android::hardware::audio::common::V4_0::AudioChannelMask;
-using ::android::hardware::audio::common::V4_0::AudioContentType;
-using ::android::hardware::audio::common::V4_0::AudioFormat;
-using ::android::hardware::audio::common::V4_0::AudioSource;
-using ::android::hardware::audio::common::V4_0::AudioUsage;
-using ::android::hardware::audio::common::V4_0::ThreadInfo;
-using ::android::hardware::audio::V4_0::AudioDrain;
-using ::android::hardware::audio::V4_0::IStreamOutCallback;
-using ::android::hardware::audio::V4_0::MessageQueueFlagBits;
-using ::android::hardware::audio::V4_0::MicrophoneInfo;
-using ::android::hardware::audio::V4_0::MmapBufferInfo;
-using ::android::hardware::audio::V4_0::MmapPosition;
-using ::android::hardware::audio::V4_0::ParameterValue;
-using ::android::hardware::audio::V4_0::PlaybackTrackMetadata;
-using ::android::hardware::audio::V4_0::RecordTrackMetadata;
-using ::android::hardware::audio::V4_0::Result;
-using ::android::hardware::audio::V4_0::TimeSpec;
-using ::android::hardware::MQDescriptorSync;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ReadCommand = ::android::hardware::audio::V4_0::IStreamIn::ReadCommand;
-
-namespace android {
-namespace V4_0 {
-
-StreamHalHidl::StreamHalHidl(IStream *stream)
-        : ConversionHelperHidl("Stream"),
-          mStream(stream),
-          mHalThreadPriority(HAL_THREAD_PRIORITY_DEFAULT),
-          mCachedBufferSize(0){
-
-    // Instrument audio signal power logging.
-    // Note: This assumes channel mask, format, and sample rate do not change after creation.
-    if (mStream != nullptr && mStreamPowerLog.isUserDebugOrEngBuild()) {
-        // Obtain audio properties (see StreamHalHidl::getAudioProperties() below).
-        Return<void> ret = mStream->getAudioProperties(
-                [&](auto sr, auto m, auto f) {
-                mStreamPowerLog.init(sr,
-                        static_cast<audio_channel_mask_t>(m),
-                        static_cast<audio_format_t>(f));
-            });
-    }
-}
-
-StreamHalHidl::~StreamHalHidl() {
-    mStream = nullptr;
-}
-
-status_t StreamHalHidl::getSampleRate(uint32_t *rate) {
-    if (!mStream) return NO_INIT;
-    return processReturn("getSampleRate", mStream->getSampleRate(), rate);
-}
-
-status_t StreamHalHidl::getBufferSize(size_t *size) {
-    if (!mStream) return NO_INIT;
-    status_t status = processReturn("getBufferSize", mStream->getBufferSize(), size);
-    if (status == OK) {
-        mCachedBufferSize = *size;
-    }
-    return status;
-}
-
-status_t StreamHalHidl::getChannelMask(audio_channel_mask_t *mask) {
-    if (!mStream) return NO_INIT;
-    return processReturn("getChannelMask", mStream->getChannelMask(), mask);
-}
-
-status_t StreamHalHidl::getFormat(audio_format_t *format) {
-    if (!mStream) return NO_INIT;
-    return processReturn("getFormat", mStream->getFormat(), format);
-}
-
-status_t StreamHalHidl::getAudioProperties(
-        uint32_t *sampleRate, audio_channel_mask_t *mask, audio_format_t *format) {
-    if (!mStream) return NO_INIT;
-    Return<void> ret = mStream->getAudioProperties(
-            [&](uint32_t sr, auto m, auto f) {
-                *sampleRate = sr;
-                *mask = static_cast<audio_channel_mask_t>(m);
-                *format = static_cast<audio_format_t>(f);
-            });
-    return processReturn("getAudioProperties", ret);
-}
-
-status_t StreamHalHidl::setParameters(const String8& kvPairs) {
-    if (!mStream) return NO_INIT;
-    hidl_vec<ParameterValue> hidlParams;
-    status_t status = parametersFromHal(kvPairs, &hidlParams);
-    if (status != OK) return status;
-    return processReturn("setParameters",
-                         utils::setParameters(mStream, hidlParams, {} /* options */));
-}
-
-status_t StreamHalHidl::getParameters(const String8& keys, String8 *values) {
-    values->clear();
-    if (!mStream) return NO_INIT;
-    hidl_vec<hidl_string> hidlKeys;
-    status_t status = keysFromHal(keys, &hidlKeys);
-    if (status != OK) return status;
-    Result retval;
-    Return<void> ret = utils::getParameters(
-            mStream,
-            {} /* context */,
-            hidlKeys,
-            [&](Result r, const hidl_vec<ParameterValue>& parameters) {
-                retval = r;
-                if (retval == Result::OK) {
-                    parametersToHal(parameters, values);
-                }
-            });
-    return processReturn("getParameters", ret, retval);
-}
-
-status_t StreamHalHidl::addEffect(sp<EffectHalInterface> effect) {
-    if (!mStream) return NO_INIT;
-    return processReturn("addEffect", mStream->addEffect(
-                    static_cast<EffectHalHidl*>(effect.get())->effectId()));
-}
-
-status_t StreamHalHidl::removeEffect(sp<EffectHalInterface> effect) {
-    if (!mStream) return NO_INIT;
-    return processReturn("removeEffect", mStream->removeEffect(
-                    static_cast<EffectHalHidl*>(effect.get())->effectId()));
-}
-
-status_t StreamHalHidl::standby() {
-    if (!mStream) return NO_INIT;
-    return processReturn("standby", mStream->standby());
-}
-
-status_t StreamHalHidl::dump(int fd) {
-    if (!mStream) return NO_INIT;
-    native_handle_t* hidlHandle = native_handle_create(1, 0);
-    hidlHandle->data[0] = fd;
-    Return<void> ret = mStream->debug(hidlHandle, {} /* options */);
-    native_handle_delete(hidlHandle);
-    mStreamPowerLog.dump(fd);
-    return processReturn("dump", ret);
-}
-
-status_t StreamHalHidl::start() {
-    if (!mStream) return NO_INIT;
-    return processReturn("start", mStream->start());
-}
-
-status_t StreamHalHidl::stop() {
-    if (!mStream) return NO_INIT;
-    return processReturn("stop", mStream->stop());
-}
-
-status_t StreamHalHidl::createMmapBuffer(int32_t minSizeFrames,
-                                  struct audio_mmap_buffer_info *info) {
-    Result retval;
-    Return<void> ret = mStream->createMmapBuffer(
-            minSizeFrames,
-            [&](Result r, const MmapBufferInfo& hidlInfo) {
-                retval = r;
-                if (retval == Result::OK) {
-                    const native_handle *handle = hidlInfo.sharedMemory.handle();
-                    if (handle->numFds > 0) {
-                        info->shared_memory_fd = handle->data[0];
-                        info->buffer_size_frames = hidlInfo.bufferSizeFrames;
-                        info->burst_size_frames = hidlInfo.burstSizeFrames;
-                        // info->shared_memory_address is not needed in HIDL context
-                        info->shared_memory_address = NULL;
-                    } else {
-                        retval = Result::NOT_INITIALIZED;
-                    }
-                }
-            });
-    return processReturn("createMmapBuffer", ret, retval);
-}
-
-status_t StreamHalHidl::getMmapPosition(struct audio_mmap_position *position) {
-    Result retval;
-    Return<void> ret = mStream->getMmapPosition(
-            [&](Result r, const MmapPosition& hidlPosition) {
-                retval = r;
-                if (retval == Result::OK) {
-                    position->time_nanoseconds = hidlPosition.timeNanoseconds;
-                    position->position_frames = hidlPosition.positionFrames;
-                }
-            });
-    return processReturn("getMmapPosition", ret, retval);
-}
-
-status_t StreamHalHidl::setHalThreadPriority(int priority) {
-    mHalThreadPriority = priority;
-    return OK;
-}
-
-status_t StreamHalHidl::getCachedBufferSize(size_t *size) {
-    if (mCachedBufferSize != 0) {
-        *size = mCachedBufferSize;
-        return OK;
-    }
-    return getBufferSize(size);
-}
-
-bool StreamHalHidl::requestHalThreadPriority(pid_t threadPid, pid_t threadId) {
-    if (mHalThreadPriority == HAL_THREAD_PRIORITY_DEFAULT) {
-        return true;
-    }
-    int err = requestPriority(
-            threadPid, threadId,
-            mHalThreadPriority, false /*isForApp*/, true /*asynchronous*/);
-    ALOGE_IF(err, "failed to set priority %d for pid %d tid %d; error %d",
-            mHalThreadPriority, threadPid, threadId, err);
-    // Audio will still work, but latency will be higher and sometimes unacceptable.
-    return err == 0;
-}
-
-namespace {
-
-/* Notes on callback ownership.
-
-This is how (Hw)Binder ownership model looks like. The server implementation
-is owned by Binder framework (via sp<>). Proxies are owned by clients.
-When the last proxy disappears, Binder framework releases the server impl.
-
-Thus, it is not needed to keep any references to StreamOutCallback (this is
-the server impl) -- it will live as long as HAL server holds a strong ref to
-IStreamOutCallback proxy. We clear that reference by calling 'clearCallback'
-from the destructor of StreamOutHalHidl.
-
-The callback only keeps a weak reference to the stream. The stream is owned
-by AudioFlinger.
-
-*/
-
-struct StreamOutCallback : public IStreamOutCallback {
-    StreamOutCallback(const wp<StreamOutHalHidl>& stream) : mStream(stream) {}
-
-    // IStreamOutCallback implementation
-    Return<void> onWriteReady()  override {
-        sp<StreamOutHalHidl> stream = mStream.promote();
-        if (stream != 0) {
-            stream->onWriteReady();
-        }
-        return Void();
-    }
-
-    Return<void> onDrainReady()  override {
-        sp<StreamOutHalHidl> stream = mStream.promote();
-        if (stream != 0) {
-            stream->onDrainReady();
-        }
-        return Void();
-    }
-
-    Return<void> onError()  override {
-        sp<StreamOutHalHidl> stream = mStream.promote();
-        if (stream != 0) {
-            stream->onError();
-        }
-        return Void();
-    }
-
-  private:
-    wp<StreamOutHalHidl> mStream;
-};
-
-}  // namespace
-
-StreamOutHalHidl::StreamOutHalHidl(const sp<IStreamOut>& stream)
-        : StreamHalHidl(stream.get()), mStream(stream), mWriterClient(0), mEfGroup(nullptr) {
-}
-
-StreamOutHalHidl::~StreamOutHalHidl() {
-    if (mStream != 0) {
-        if (mCallback.unsafe_get()) {
-            processReturn("clearCallback", mStream->clearCallback());
-        }
-        processReturn("close", mStream->close());
-        mStream.clear();
-    }
-    mCallback.clear();
-    hardware::IPCThreadState::self()->flushCommands();
-    if (mEfGroup) {
-        EventFlag::deleteEventFlag(&mEfGroup);
-    }
-}
-
-status_t StreamOutHalHidl::getFrameSize(size_t *size) {
-    if (mStream == 0) return NO_INIT;
-    return processReturn("getFrameSize", mStream->getFrameSize(), size);
-}
-
-status_t StreamOutHalHidl::getLatency(uint32_t *latency) {
-    if (mStream == 0) return NO_INIT;
-    if (mWriterClient == gettid() && mCommandMQ) {
-        return callWriterThread(
-                WriteCommand::GET_LATENCY, "getLatency", nullptr, 0,
-                [&](const WriteStatus& writeStatus) {
-                    *latency = writeStatus.reply.latencyMs;
-                });
-    } else {
-        return processReturn("getLatency", mStream->getLatency(), latency);
-    }
-}
-
-status_t StreamOutHalHidl::setVolume(float left, float right) {
-    if (mStream == 0) return NO_INIT;
-    return processReturn("setVolume", mStream->setVolume(left, right));
-}
-
-status_t StreamOutHalHidl::write(const void *buffer, size_t bytes, size_t *written) {
-    if (mStream == 0) return NO_INIT;
-    *written = 0;
-
-    if (bytes == 0 && !mDataMQ) {
-        // Can't determine the size for the MQ buffer. Wait for a non-empty write request.
-        ALOGW_IF(mCallback.unsafe_get(), "First call to async write with 0 bytes");
-        return OK;
-    }
-
-    status_t status;
-    if (!mDataMQ) {
-        // In case if playback starts close to the end of a compressed track, the bytes
-        // that need to be written is less than the actual buffer size. Need to use
-        // full buffer size for the MQ since otherwise after seeking back to the middle
-        // data will be truncated.
-        size_t bufferSize;
-        if ((status = getCachedBufferSize(&bufferSize)) != OK) {
-            return status;
-        }
-        if (bytes > bufferSize) bufferSize = bytes;
-        if ((status = prepareForWriting(bufferSize)) != OK) {
-            return status;
-        }
-    }
-
-    status = callWriterThread(
-            WriteCommand::WRITE, "write", static_cast<const uint8_t*>(buffer), bytes,
-            [&] (const WriteStatus& writeStatus) {
-                *written = writeStatus.reply.written;
-                // Diagnostics of the cause of b/35813113.
-                ALOGE_IF(*written > bytes,
-                        "hal reports more bytes written than asked for: %lld > %lld",
-                        (long long)*written, (long long)bytes);
-            });
-    mStreamPowerLog.log(buffer, *written);
-    return status;
-}
-
-status_t StreamOutHalHidl::callWriterThread(
-        WriteCommand cmd, const char* cmdName,
-        const uint8_t* data, size_t dataSize, StreamOutHalHidl::WriterCallback callback) {
-    if (!mCommandMQ->write(&cmd)) {
-        ALOGE("command message queue write failed for \"%s\"", cmdName);
-        return -EAGAIN;
-    }
-    if (data != nullptr) {
-        size_t availableToWrite = mDataMQ->availableToWrite();
-        if (dataSize > availableToWrite) {
-            ALOGW("truncating write data from %lld to %lld due to insufficient data queue space",
-                    (long long)dataSize, (long long)availableToWrite);
-            dataSize = availableToWrite;
-        }
-        if (!mDataMQ->write(data, dataSize)) {
-            ALOGE("data message queue write failed for \"%s\"", cmdName);
-        }
-    }
-    mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY));
-
-    // TODO: Remove manual event flag handling once blocking MQ is implemented. b/33815422
-    uint32_t efState = 0;
-retry:
-    status_t ret = mEfGroup->wait(static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL), &efState);
-    if (efState & static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL)) {
-        WriteStatus writeStatus;
-        writeStatus.retval = Result::NOT_INITIALIZED;
-        if (!mStatusMQ->read(&writeStatus)) {
-            ALOGE("status message read failed for \"%s\"", cmdName);
-        }
-        if (writeStatus.retval == Result::OK) {
-            ret = OK;
-            callback(writeStatus);
-        } else {
-            ret = processReturn(cmdName, writeStatus.retval);
-        }
-        return ret;
-    }
-    if (ret == -EAGAIN || ret == -EINTR) {
-        // Spurious wakeup. This normally retries no more than once.
-        goto retry;
-    }
-    return ret;
-}
-
-status_t StreamOutHalHidl::prepareForWriting(size_t bufferSize) {
-    std::unique_ptr<CommandMQ> tempCommandMQ;
-    std::unique_ptr<DataMQ> tempDataMQ;
-    std::unique_ptr<StatusMQ> tempStatusMQ;
-    Result retval;
-    pid_t halThreadPid, halThreadTid;
-    Return<void> ret = mStream->prepareForWriting(
-            1, bufferSize,
-            [&](Result r,
-                    const CommandMQ::Descriptor& commandMQ,
-                    const DataMQ::Descriptor& dataMQ,
-                    const StatusMQ::Descriptor& statusMQ,
-                    const ThreadInfo& halThreadInfo) {
-                retval = r;
-                if (retval == Result::OK) {
-                    tempCommandMQ.reset(new CommandMQ(commandMQ));
-                    tempDataMQ.reset(new DataMQ(dataMQ));
-                    tempStatusMQ.reset(new StatusMQ(statusMQ));
-                    if (tempDataMQ->isValid() && tempDataMQ->getEventFlagWord()) {
-                        EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &mEfGroup);
-                    }
-                    halThreadPid = halThreadInfo.pid;
-                    halThreadTid = halThreadInfo.tid;
-                }
-            });
-    if (!ret.isOk() || retval != Result::OK) {
-        return processReturn("prepareForWriting", ret, retval);
-    }
-    if (!tempCommandMQ || !tempCommandMQ->isValid() ||
-            !tempDataMQ || !tempDataMQ->isValid() ||
-            !tempStatusMQ || !tempStatusMQ->isValid() ||
-            !mEfGroup) {
-        ALOGE_IF(!tempCommandMQ, "Failed to obtain command message queue for writing");
-        ALOGE_IF(tempCommandMQ && !tempCommandMQ->isValid(),
-                "Command message queue for writing is invalid");
-        ALOGE_IF(!tempDataMQ, "Failed to obtain data message queue for writing");
-        ALOGE_IF(tempDataMQ && !tempDataMQ->isValid(), "Data message queue for writing is invalid");
-        ALOGE_IF(!tempStatusMQ, "Failed to obtain status message queue for writing");
-        ALOGE_IF(tempStatusMQ && !tempStatusMQ->isValid(),
-                "Status message queue for writing is invalid");
-        ALOGE_IF(!mEfGroup, "Event flag creation for writing failed");
-        return NO_INIT;
-    }
-    requestHalThreadPriority(halThreadPid, halThreadTid);
-
-    mCommandMQ = std::move(tempCommandMQ);
-    mDataMQ = std::move(tempDataMQ);
-    mStatusMQ = std::move(tempStatusMQ);
-    mWriterClient = gettid();
-    return OK;
-}
-
-status_t StreamOutHalHidl::getRenderPosition(uint32_t *dspFrames) {
-    if (mStream == 0) return NO_INIT;
-    Result retval;
-    Return<void> ret = mStream->getRenderPosition(
-            [&](Result r, uint32_t d) {
-                retval = r;
-                if (retval == Result::OK) {
-                    *dspFrames = d;
-                }
-            });
-    return processReturn("getRenderPosition", ret, retval);
-}
-
-status_t StreamOutHalHidl::getNextWriteTimestamp(int64_t *timestamp) {
-    if (mStream == 0) return NO_INIT;
-    Result retval;
-    Return<void> ret = mStream->getNextWriteTimestamp(
-            [&](Result r, int64_t t) {
-                retval = r;
-                if (retval == Result::OK) {
-                    *timestamp = t;
-                }
-            });
-    return processReturn("getRenderPosition", ret, retval);
-}
-
-status_t StreamOutHalHidl::setCallback(wp<StreamOutHalInterfaceCallback> callback) {
-    if (mStream == 0) return NO_INIT;
-    status_t status = processReturn(
-            "setCallback", mStream->setCallback(new StreamOutCallback(this)));
-    if (status == OK) {
-        mCallback = callback;
-    }
-    return status;
-}
-
-status_t StreamOutHalHidl::supportsPauseAndResume(bool *supportsPause, bool *supportsResume) {
-    if (mStream == 0) return NO_INIT;
-    Return<void> ret = mStream->supportsPauseAndResume(
-            [&](bool p, bool r) {
-                *supportsPause = p;
-                *supportsResume = r;
-            });
-    return processReturn("supportsPauseAndResume", ret);
-}
-
-status_t StreamOutHalHidl::pause() {
-    if (mStream == 0) return NO_INIT;
-    return processReturn("pause", mStream->pause());
-}
-
-status_t StreamOutHalHidl::resume() {
-    if (mStream == 0) return NO_INIT;
-    return processReturn("pause", mStream->resume());
-}
-
-status_t StreamOutHalHidl::supportsDrain(bool *supportsDrain) {
-    if (mStream == 0) return NO_INIT;
-    return processReturn("supportsDrain", mStream->supportsDrain(), supportsDrain);
-}
-
-status_t StreamOutHalHidl::drain(bool earlyNotify) {
-    if (mStream == 0) return NO_INIT;
-    return processReturn(
-            "drain", mStream->drain(earlyNotify ? AudioDrain::EARLY_NOTIFY : AudioDrain::ALL));
-}
-
-status_t StreamOutHalHidl::flush() {
-    if (mStream == 0) return NO_INIT;
-    return processReturn("pause", mStream->flush());
-}
-
-status_t StreamOutHalHidl::getPresentationPosition(uint64_t *frames, struct timespec *timestamp) {
-    if (mStream == 0) return NO_INIT;
-    if (mWriterClient == gettid() && mCommandMQ) {
-        return callWriterThread(
-                WriteCommand::GET_PRESENTATION_POSITION, "getPresentationPosition", nullptr, 0,
-                [&](const WriteStatus& writeStatus) {
-                    *frames = writeStatus.reply.presentationPosition.frames;
-                    timestamp->tv_sec = writeStatus.reply.presentationPosition.timeStamp.tvSec;
-                    timestamp->tv_nsec = writeStatus.reply.presentationPosition.timeStamp.tvNSec;
-                });
-    } else {
-        Result retval;
-        Return<void> ret = mStream->getPresentationPosition(
-                [&](Result r, uint64_t hidlFrames, const TimeSpec& hidlTimeStamp) {
-                    retval = r;
-                    if (retval == Result::OK) {
-                        *frames = hidlFrames;
-                        timestamp->tv_sec = hidlTimeStamp.tvSec;
-                        timestamp->tv_nsec = hidlTimeStamp.tvNSec;
-                    }
-                });
-        return processReturn("getPresentationPosition", ret, retval);
-    }
-}
-
-/** Transform a standard collection to an HIDL vector. */
-template <class Values, class ElementConverter>
-static auto transformToHidlVec(const Values& values, ElementConverter converter) {
-    hidl_vec<decltype(converter(*values.begin()))> result{values.size()};
-    using namespace std;
-    transform(begin(values), end(values), begin(result), converter);
-    return result;
-}
-
-status_t StreamOutHalHidl::updateSourceMetadata(const SourceMetadata& sourceMetadata) {
-    hardware::audio::V4_0::SourceMetadata halMetadata = {
-        .tracks = transformToHidlVec(sourceMetadata.tracks,
-              [](const playback_track_metadata& metadata) -> PlaybackTrackMetadata {
-                  return {
-                    .usage=static_cast<AudioUsage>(metadata.usage),
-                    .contentType=static_cast<AudioContentType>(metadata.content_type),
-                    .gain=metadata.gain,
-                  };
-              })};
-    return processReturn("updateSourceMetadata", mStream->updateSourceMetadata(halMetadata));
-}
-
-void StreamOutHalHidl::onWriteReady() {
-    sp<StreamOutHalInterfaceCallback> callback = mCallback.promote();
-    if (callback == 0) return;
-    ALOGV("asyncCallback onWriteReady");
-    callback->onWriteReady();
-}
-
-void StreamOutHalHidl::onDrainReady() {
-    sp<StreamOutHalInterfaceCallback> callback = mCallback.promote();
-    if (callback == 0) return;
-    ALOGV("asyncCallback onDrainReady");
-    callback->onDrainReady();
-}
-
-void StreamOutHalHidl::onError() {
-    sp<StreamOutHalInterfaceCallback> callback = mCallback.promote();
-    if (callback == 0) return;
-    ALOGV("asyncCallback onError");
-    callback->onError();
-}
-
-
-StreamInHalHidl::StreamInHalHidl(const sp<IStreamIn>& stream)
-        : StreamHalHidl(stream.get()), mStream(stream), mReaderClient(0), mEfGroup(nullptr) {
-}
-
-StreamInHalHidl::~StreamInHalHidl() {
-    if (mStream != 0) {
-        processReturn("close", mStream->close());
-        mStream.clear();
-        hardware::IPCThreadState::self()->flushCommands();
-    }
-    if (mEfGroup) {
-        EventFlag::deleteEventFlag(&mEfGroup);
-    }
-}
-
-status_t StreamInHalHidl::getFrameSize(size_t *size) {
-    if (mStream == 0) return NO_INIT;
-    return processReturn("getFrameSize", mStream->getFrameSize(), size);
-}
-
-status_t StreamInHalHidl::setGain(float gain) {
-    if (mStream == 0) return NO_INIT;
-    return processReturn("setGain", mStream->setGain(gain));
-}
-
-status_t StreamInHalHidl::read(void *buffer, size_t bytes, size_t *read) {
-    if (mStream == 0) return NO_INIT;
-    *read = 0;
-
-    if (bytes == 0 && !mDataMQ) {
-        // Can't determine the size for the MQ buffer. Wait for a non-empty read request.
-        return OK;
-    }
-
-    status_t status;
-    if (!mDataMQ && (status = prepareForReading(bytes)) != OK) {
-        return status;
-    }
-
-    ReadParameters params;
-    params.command = ReadCommand::READ;
-    params.params.read = bytes;
-    status = callReaderThread(params, "read",
-            [&](const ReadStatus& readStatus) {
-                const size_t availToRead = mDataMQ->availableToRead();
-                if (!mDataMQ->read(static_cast<uint8_t*>(buffer), std::min(bytes, availToRead))) {
-                    ALOGE("data message queue read failed for \"read\"");
-                }
-                ALOGW_IF(availToRead != readStatus.reply.read,
-                        "HAL read report inconsistent: mq = %d, status = %d",
-                        (int32_t)availToRead, (int32_t)readStatus.reply.read);
-                *read = readStatus.reply.read;
-            });
-    mStreamPowerLog.log(buffer, *read);
-    return status;
-}
-
-status_t StreamInHalHidl::callReaderThread(
-        const ReadParameters& params, const char* cmdName,
-        StreamInHalHidl::ReaderCallback callback) {
-    if (!mCommandMQ->write(&params)) {
-        ALOGW("command message queue write failed");
-        return -EAGAIN;
-    }
-    mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL));
-
-    // TODO: Remove manual event flag handling once blocking MQ is implemented. b/33815422
-    uint32_t efState = 0;
-retry:
-    status_t ret = mEfGroup->wait(static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY), &efState);
-    if (efState & static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY)) {
-        ReadStatus readStatus;
-        readStatus.retval = Result::NOT_INITIALIZED;
-        if (!mStatusMQ->read(&readStatus)) {
-            ALOGE("status message read failed for \"%s\"", cmdName);
-        }
-         if (readStatus.retval == Result::OK) {
-            ret = OK;
-            callback(readStatus);
-        } else {
-            ret = processReturn(cmdName, readStatus.retval);
-        }
-        return ret;
-    }
-    if (ret == -EAGAIN || ret == -EINTR) {
-        // Spurious wakeup. This normally retries no more than once.
-        goto retry;
-    }
-    return ret;
-}
-
-status_t StreamInHalHidl::prepareForReading(size_t bufferSize) {
-    std::unique_ptr<CommandMQ> tempCommandMQ;
-    std::unique_ptr<DataMQ> tempDataMQ;
-    std::unique_ptr<StatusMQ> tempStatusMQ;
-    Result retval;
-    pid_t halThreadPid, halThreadTid;
-    Return<void> ret = mStream->prepareForReading(
-            1, bufferSize,
-            [&](Result r,
-                    const CommandMQ::Descriptor& commandMQ,
-                    const DataMQ::Descriptor& dataMQ,
-                    const StatusMQ::Descriptor& statusMQ,
-                    const ThreadInfo& halThreadInfo) {
-                retval = r;
-                if (retval == Result::OK) {
-                    tempCommandMQ.reset(new CommandMQ(commandMQ));
-                    tempDataMQ.reset(new DataMQ(dataMQ));
-                    tempStatusMQ.reset(new StatusMQ(statusMQ));
-                    if (tempDataMQ->isValid() && tempDataMQ->getEventFlagWord()) {
-                        EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &mEfGroup);
-                    }
-                    halThreadPid = halThreadInfo.pid;
-                    halThreadTid = halThreadInfo.tid;
-                }
-            });
-    if (!ret.isOk() || retval != Result::OK) {
-        return processReturn("prepareForReading", ret, retval);
-    }
-    if (!tempCommandMQ || !tempCommandMQ->isValid() ||
-            !tempDataMQ || !tempDataMQ->isValid() ||
-            !tempStatusMQ || !tempStatusMQ->isValid() ||
-            !mEfGroup) {
-        ALOGE_IF(!tempCommandMQ, "Failed to obtain command message queue for writing");
-        ALOGE_IF(tempCommandMQ && !tempCommandMQ->isValid(),
-                "Command message queue for writing is invalid");
-        ALOGE_IF(!tempDataMQ, "Failed to obtain data message queue for reading");
-        ALOGE_IF(tempDataMQ && !tempDataMQ->isValid(), "Data message queue for reading is invalid");
-        ALOGE_IF(!tempStatusMQ, "Failed to obtain status message queue for reading");
-        ALOGE_IF(tempStatusMQ && !tempStatusMQ->isValid(),
-                "Status message queue for reading is invalid");
-        ALOGE_IF(!mEfGroup, "Event flag creation for reading failed");
-        return NO_INIT;
-    }
-    requestHalThreadPriority(halThreadPid, halThreadTid);
-
-    mCommandMQ = std::move(tempCommandMQ);
-    mDataMQ = std::move(tempDataMQ);
-    mStatusMQ = std::move(tempStatusMQ);
-    mReaderClient = gettid();
-    return OK;
-}
-
-status_t StreamInHalHidl::getInputFramesLost(uint32_t *framesLost) {
-    if (mStream == 0) return NO_INIT;
-    return processReturn("getInputFramesLost", mStream->getInputFramesLost(), framesLost);
-}
-
-status_t StreamInHalHidl::getCapturePosition(int64_t *frames, int64_t *time) {
-    if (mStream == 0) return NO_INIT;
-    if (mReaderClient == gettid() && mCommandMQ) {
-        ReadParameters params;
-        params.command = ReadCommand::GET_CAPTURE_POSITION;
-        return callReaderThread(params, "getCapturePosition",
-                [&](const ReadStatus& readStatus) {
-                    *frames = readStatus.reply.capturePosition.frames;
-                    *time = readStatus.reply.capturePosition.time;
-                });
-    } else {
-        Result retval;
-        Return<void> ret = mStream->getCapturePosition(
-                [&](Result r, uint64_t hidlFrames, uint64_t hidlTime) {
-                    retval = r;
-                    if (retval == Result::OK) {
-                        *frames = hidlFrames;
-                        *time = hidlTime;
-                    }
-                });
-        return processReturn("getCapturePosition", ret, retval);
-    }
-}
-
-
-status_t StreamInHalHidl::getActiveMicrophones(
-        std::vector<media::MicrophoneInfo> *microphonesInfo) {
-    if (!mStream) return NO_INIT;
-    Result retval;
-    Return<void> ret = mStream->getActiveMicrophones(
-            [&](Result r, hidl_vec<MicrophoneInfo> micArrayHal) {
-        retval = r;
-        for (size_t k = 0; k < micArrayHal.size(); k++) {
-            audio_microphone_characteristic_t dst;
-            // convert
-            microphoneInfoToHal(micArrayHal[k], &dst);
-            media::MicrophoneInfo microphone = media::MicrophoneInfo(dst);
-            microphonesInfo->push_back(microphone);
-        }
-    });
-    return processReturn("getActiveMicrophones", ret, retval);
-}
-
-status_t StreamInHalHidl::updateSinkMetadata(const SinkMetadata& sinkMetadata) {
-    hardware::audio::V4_0::SinkMetadata halMetadata = {
-        .tracks = transformToHidlVec(sinkMetadata.tracks,
-              [](const record_track_metadata& metadata) -> RecordTrackMetadata {
-                  return {
-                    .source=static_cast<AudioSource>(metadata.source),
-                    .gain=metadata.gain,
-                  };
-              })};
-    return processReturn("updateSinkMetadata", mStream->updateSinkMetadata(halMetadata));
-}
-
-} // namespace V4_0
-} // namespace android
diff --git a/media/libaudiohal/4.0/StreamHalHidl.h b/media/libaudiohal/4.0/StreamHalHidl.h
deleted file mode 100644
index 2dda0f8..0000000
--- a/media/libaudiohal/4.0/StreamHalHidl.h
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_STREAM_HAL_HIDL_4_0_H
-#define ANDROID_HARDWARE_STREAM_HAL_HIDL_4_0_H
-
-#include <atomic>
-
-#include <android/hardware/audio/4.0/IStream.h>
-#include <android/hardware/audio/4.0/IStreamIn.h>
-#include <android/hardware/audio/4.0/IStreamOut.h>
-#include <fmq/EventFlag.h>
-#include <fmq/MessageQueue.h>
-#include <media/audiohal/StreamHalInterface.h>
-
-#include "ConversionHelperHidl.h"
-#include "StreamPowerLog.h"
-
-using ::android::hardware::audio::V4_0::IStream;
-using ::android::hardware::audio::V4_0::IStreamIn;
-using ::android::hardware::audio::V4_0::IStreamOut;
-using ::android::hardware::EventFlag;
-using ::android::hardware::MessageQueue;
-using ::android::hardware::Return;
-using ReadParameters = ::android::hardware::audio::V4_0::IStreamIn::ReadParameters;
-using ReadStatus = ::android::hardware::audio::V4_0::IStreamIn::ReadStatus;
-using WriteCommand = ::android::hardware::audio::V4_0::IStreamOut::WriteCommand;
-using WriteStatus = ::android::hardware::audio::V4_0::IStreamOut::WriteStatus;
-
-namespace android {
-namespace V4_0 {
-
-class DeviceHalHidl;
-
-class StreamHalHidl : public virtual StreamHalInterface, public ConversionHelperHidl
-{
-  public:
-    // Return the sampling rate in Hz - eg. 44100.
-    virtual status_t getSampleRate(uint32_t *rate);
-
-    // Return size of input/output buffer in bytes for this stream - eg. 4800.
-    virtual status_t getBufferSize(size_t *size);
-
-    // Return the channel mask.
-    virtual status_t getChannelMask(audio_channel_mask_t *mask);
-
-    // Return the audio format - e.g. AUDIO_FORMAT_PCM_16_BIT.
-    virtual status_t getFormat(audio_format_t *format);
-
-    // Convenience method.
-    virtual status_t getAudioProperties(
-            uint32_t *sampleRate, audio_channel_mask_t *mask, audio_format_t *format);
-
-    // Set audio stream parameters.
-    virtual status_t setParameters(const String8& kvPairs);
-
-    // Get audio stream parameters.
-    virtual status_t getParameters(const String8& keys, String8 *values);
-
-    // Add or remove the effect on the stream.
-    virtual status_t addEffect(sp<EffectHalInterface> effect);
-    virtual status_t removeEffect(sp<EffectHalInterface> effect);
-
-    // Put the audio hardware input/output into standby mode.
-    virtual status_t standby();
-
-    virtual status_t dump(int fd);
-
-    // Start a stream operating in mmap mode.
-    virtual status_t start();
-
-    // Stop a stream operating in mmap mode.
-    virtual status_t stop();
-
-    // Retrieve information on the data buffer in mmap mode.
-    virtual status_t createMmapBuffer(int32_t minSizeFrames,
-                                      struct audio_mmap_buffer_info *info);
-
-    // Get current read/write position in the mmap buffer
-    virtual status_t getMmapPosition(struct audio_mmap_position *position);
-
-    // Set the priority of the thread that interacts with the HAL
-    // (must match the priority of the audioflinger's thread that calls 'read' / 'write')
-    virtual status_t setHalThreadPriority(int priority);
-
-  protected:
-    // Subclasses can not be constructed directly by clients.
-    explicit StreamHalHidl(IStream *stream);
-
-    // The destructor automatically closes the stream.
-    virtual ~StreamHalHidl();
-
-    status_t getCachedBufferSize(size_t *size);
-
-    bool requestHalThreadPriority(pid_t threadPid, pid_t threadId);
-
-    // mStreamPowerLog is used for audio signal power logging.
-    StreamPowerLog mStreamPowerLog;
-
-  private:
-    const int HAL_THREAD_PRIORITY_DEFAULT = -1;
-    IStream *mStream;
-    int mHalThreadPriority;
-    size_t mCachedBufferSize;
-};
-
-class StreamOutHalHidl : public StreamOutHalInterface, public StreamHalHidl {
-  public:
-    // Return the frame size (number of bytes per sample) of a stream.
-    virtual status_t getFrameSize(size_t *size);
-
-    // Return the audio hardware driver estimated latency in milliseconds.
-    virtual status_t getLatency(uint32_t *latency);
-
-    // Use this method in situations where audio mixing is done in the hardware.
-    virtual status_t setVolume(float left, float right);
-
-    // Write audio buffer to driver.
-    virtual status_t write(const void *buffer, size_t bytes, size_t *written);
-
-    // Return the number of audio frames written by the audio dsp to DAC since
-    // the output has exited standby.
-    virtual status_t getRenderPosition(uint32_t *dspFrames);
-
-    // Get the local time at which the next write to the audio driver will be presented.
-    virtual status_t getNextWriteTimestamp(int64_t *timestamp);
-
-    // Set the callback for notifying completion of non-blocking write and drain.
-    virtual status_t setCallback(wp<StreamOutHalInterfaceCallback> callback);
-
-    // Returns whether pause and resume operations are supported.
-    virtual status_t supportsPauseAndResume(bool *supportsPause, bool *supportsResume);
-
-    // Notifies to the audio driver to resume playback following a pause.
-    virtual status_t pause();
-
-    // Notifies to the audio driver to resume playback following a pause.
-    virtual status_t resume();
-
-    // Returns whether drain operation is supported.
-    virtual status_t supportsDrain(bool *supportsDrain);
-
-    // Requests notification when data buffered by the driver/hardware has been played.
-    virtual status_t drain(bool earlyNotify);
-
-    // Notifies to the audio driver to flush the queued data.
-    virtual status_t flush();
-
-    // Return a recent count of the number of audio frames presented to an external observer.
-    virtual status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp);
-
-    // Called when the metadata of the stream's source has been changed.
-    status_t updateSourceMetadata(const SourceMetadata& sourceMetadata) override;
-
-    // Methods used by StreamOutCallback (HIDL).
-    void onWriteReady();
-    void onDrainReady();
-    void onError();
-
-  private:
-    friend class DeviceHalHidl;
-    typedef MessageQueue<WriteCommand, hardware::kSynchronizedReadWrite> CommandMQ;
-    typedef MessageQueue<uint8_t, hardware::kSynchronizedReadWrite> DataMQ;
-    typedef MessageQueue<WriteStatus, hardware::kSynchronizedReadWrite> StatusMQ;
-
-    wp<StreamOutHalInterfaceCallback> mCallback;
-    sp<IStreamOut> mStream;
-    std::unique_ptr<CommandMQ> mCommandMQ;
-    std::unique_ptr<DataMQ> mDataMQ;
-    std::unique_ptr<StatusMQ> mStatusMQ;
-    std::atomic<pid_t> mWriterClient;
-    EventFlag* mEfGroup;
-
-    // Can not be constructed directly by clients.
-    StreamOutHalHidl(const sp<IStreamOut>& stream);
-
-    virtual ~StreamOutHalHidl();
-
-    using WriterCallback = std::function<void(const WriteStatus& writeStatus)>;
-    status_t callWriterThread(
-            WriteCommand cmd, const char* cmdName,
-            const uint8_t* data, size_t dataSize, WriterCallback callback);
-    status_t prepareForWriting(size_t bufferSize);
-};
-
-class StreamInHalHidl : public StreamInHalInterface, public StreamHalHidl {
-  public:
-    // Return the frame size (number of bytes per sample) of a stream.
-    virtual status_t getFrameSize(size_t *size);
-
-    // Set the input gain for the audio driver.
-    virtual status_t setGain(float gain);
-
-    // Read audio buffer in from driver.
-    virtual status_t read(void *buffer, size_t bytes, size_t *read);
-
-    // Return the amount of input frames lost in the audio driver.
-    virtual status_t getInputFramesLost(uint32_t *framesLost);
-
-    // Return a recent count of the number of audio frames received and
-    // the clock time associated with that frame count.
-    virtual status_t getCapturePosition(int64_t *frames, int64_t *time);
-
-    // Get active microphones
-    virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones);
-
-    // Called when the metadata of the stream's sink has been changed.
-    status_t updateSinkMetadata(const SinkMetadata& sinkMetadata) override;
-
-  private:
-    friend class DeviceHalHidl;
-    typedef MessageQueue<ReadParameters, hardware::kSynchronizedReadWrite> CommandMQ;
-    typedef MessageQueue<uint8_t, hardware::kSynchronizedReadWrite> DataMQ;
-    typedef MessageQueue<ReadStatus, hardware::kSynchronizedReadWrite> StatusMQ;
-
-    sp<IStreamIn> mStream;
-    std::unique_ptr<CommandMQ> mCommandMQ;
-    std::unique_ptr<DataMQ> mDataMQ;
-    std::unique_ptr<StatusMQ> mStatusMQ;
-    std::atomic<pid_t> mReaderClient;
-    EventFlag* mEfGroup;
-
-    // Can not be constructed directly by clients.
-    StreamInHalHidl(const sp<IStreamIn>& stream);
-
-    virtual ~StreamInHalHidl();
-
-    using ReaderCallback = std::function<void(const ReadStatus& readStatus)>;
-    status_t callReaderThread(
-            const ReadParameters& params, const char* cmdName, ReaderCallback callback);
-    status_t prepareForReading(size_t bufferSize);
-};
-
-} // namespace V4_0
-} // namespace android
-
-#endif // ANDROID_HARDWARE_STREAM_HAL_HIDL_4_0_H
diff --git a/media/libaudiohal/4.0/StreamHalLocal.cpp b/media/libaudiohal/4.0/StreamHalLocal.cpp
deleted file mode 100644
index e9d96bf..0000000
--- a/media/libaudiohal/4.0/StreamHalLocal.cpp
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "StreamHalLocal"
-//#define LOG_NDEBUG 0
-
-#include <hardware/audio.h>
-#include <utils/Log.h>
-
-#include "DeviceHalLocal.h"
-#include "StreamHalLocal.h"
-#include "VersionUtils.h"
-
-namespace android {
-namespace V4_0 {
-
-StreamHalLocal::StreamHalLocal(audio_stream_t *stream, sp<DeviceHalLocal> device)
-        : mDevice(device),
-          mStream(stream) {
-    // Instrument audio signal power logging.
-    // Note: This assumes channel mask, format, and sample rate do not change after creation.
-    if (mStream != nullptr && mStreamPowerLog.isUserDebugOrEngBuild()) {
-        mStreamPowerLog.init(mStream->get_sample_rate(mStream),
-                mStream->get_channels(mStream),
-                mStream->get_format(mStream));
-    }
-}
-
-StreamHalLocal::~StreamHalLocal() {
-    mStream = 0;
-    mDevice.clear();
-}
-
-status_t StreamHalLocal::getSampleRate(uint32_t *rate) {
-    *rate = mStream->get_sample_rate(mStream);
-    return OK;
-}
-
-status_t StreamHalLocal::getBufferSize(size_t *size) {
-    *size = mStream->get_buffer_size(mStream);
-    return OK;
-}
-
-status_t StreamHalLocal::getChannelMask(audio_channel_mask_t *mask) {
-    *mask = mStream->get_channels(mStream);
-    return OK;
-}
-
-status_t StreamHalLocal::getFormat(audio_format_t *format) {
-    *format = mStream->get_format(mStream);
-    return OK;
-}
-
-status_t StreamHalLocal::getAudioProperties(
-        uint32_t *sampleRate, audio_channel_mask_t *mask, audio_format_t *format) {
-    *sampleRate = mStream->get_sample_rate(mStream);
-    *mask = mStream->get_channels(mStream);
-    *format = mStream->get_format(mStream);
-    return OK;
-}
-
-status_t StreamHalLocal::setParameters(const String8& kvPairs) {
-    return mStream->set_parameters(mStream, kvPairs.string());
-}
-
-status_t StreamHalLocal::getParameters(const String8& keys, String8 *values) {
-    char *halValues = mStream->get_parameters(mStream, keys.string());
-    if (halValues != NULL) {
-        values->setTo(halValues);
-        free(halValues);
-    } else {
-        values->clear();
-    }
-    return OK;
-}
-
-status_t StreamHalLocal::addEffect(sp<EffectHalInterface>) {
-    LOG_ALWAYS_FATAL("Local streams can not have effects");
-    return INVALID_OPERATION;
-}
-
-status_t StreamHalLocal::removeEffect(sp<EffectHalInterface>) {
-    LOG_ALWAYS_FATAL("Local streams can not have effects");
-    return INVALID_OPERATION;
-}
-
-status_t StreamHalLocal::standby() {
-    return mStream->standby(mStream);
-}
-
-status_t StreamHalLocal::dump(int fd) {
-    status_t status = mStream->dump(mStream, fd);
-    mStreamPowerLog.dump(fd);
-    return status;
-}
-
-status_t StreamHalLocal::setHalThreadPriority(int) {
-    // Don't need to do anything as local hal is executed by audioflinger directly
-    // on the same thread.
-    return OK;
-}
-
-StreamOutHalLocal::StreamOutHalLocal(audio_stream_out_t *stream, sp<DeviceHalLocal> device)
-        : StreamHalLocal(&stream->common, device), mStream(stream) {
-}
-
-StreamOutHalLocal::~StreamOutHalLocal() {
-    mCallback.clear();
-    mDevice->closeOutputStream(mStream);
-    mStream = 0;
-}
-
-status_t StreamOutHalLocal::getFrameSize(size_t *size) {
-    *size = audio_stream_out_frame_size(mStream);
-    return OK;
-}
-
-status_t StreamOutHalLocal::getLatency(uint32_t *latency) {
-    *latency = mStream->get_latency(mStream);
-    return OK;
-}
-
-status_t StreamOutHalLocal::setVolume(float left, float right) {
-    if (mStream->set_volume == NULL) return INVALID_OPERATION;
-    return mStream->set_volume(mStream, left, right);
-}
-
-status_t StreamOutHalLocal::write(const void *buffer, size_t bytes, size_t *written) {
-    ssize_t writeResult = mStream->write(mStream, buffer, bytes);
-    if (writeResult > 0) {
-        *written = writeResult;
-        mStreamPowerLog.log(buffer, *written);
-        return OK;
-    } else {
-        *written = 0;
-        return writeResult;
-    }
-}
-
-status_t StreamOutHalLocal::getRenderPosition(uint32_t *dspFrames) {
-    return mStream->get_render_position(mStream, dspFrames);
-}
-
-status_t StreamOutHalLocal::getNextWriteTimestamp(int64_t *timestamp) {
-    if (mStream->get_next_write_timestamp == NULL) return INVALID_OPERATION;
-    return mStream->get_next_write_timestamp(mStream, timestamp);
-}
-
-status_t StreamOutHalLocal::setCallback(wp<StreamOutHalInterfaceCallback> callback) {
-    if (mStream->set_callback == NULL) return INVALID_OPERATION;
-    status_t result = mStream->set_callback(mStream, StreamOutHalLocal::asyncCallback, this);
-    if (result == OK) {
-        mCallback = callback;
-    }
-    return result;
-}
-
-// static
-int StreamOutHalLocal::asyncCallback(stream_callback_event_t event, void*, void *cookie) {
-    // We act as if we gave a wp<StreamOutHalLocal> to HAL. This way we should handle
-    // correctly the case when the callback is invoked while StreamOutHalLocal's destructor is
-    // already running, because the destructor is invoked after the refcount has been atomically
-    // decremented.
-    wp<StreamOutHalLocal> weakSelf(static_cast<StreamOutHalLocal*>(cookie));
-    sp<StreamOutHalLocal> self = weakSelf.promote();
-    if (self == 0) return 0;
-    sp<StreamOutHalInterfaceCallback> callback = self->mCallback.promote();
-    if (callback == 0) return 0;
-    ALOGV("asyncCallback() event %d", event);
-    switch (event) {
-        case STREAM_CBK_EVENT_WRITE_READY:
-            callback->onWriteReady();
-            break;
-        case STREAM_CBK_EVENT_DRAIN_READY:
-            callback->onDrainReady();
-            break;
-        case STREAM_CBK_EVENT_ERROR:
-            callback->onError();
-            break;
-        default:
-            ALOGW("asyncCallback() unknown event %d", event);
-            break;
-    }
-    return 0;
-}
-
-status_t StreamOutHalLocal::supportsPauseAndResume(bool *supportsPause, bool *supportsResume) {
-    *supportsPause = mStream->pause != NULL;
-    *supportsResume = mStream->resume != NULL;
-    return OK;
-}
-
-status_t StreamOutHalLocal::pause() {
-    if (mStream->pause == NULL) return INVALID_OPERATION;
-    return mStream->pause(mStream);
-}
-
-status_t StreamOutHalLocal::resume() {
-    if (mStream->resume == NULL) return INVALID_OPERATION;
-    return mStream->resume(mStream);
-}
-
-status_t StreamOutHalLocal::supportsDrain(bool *supportsDrain) {
-    *supportsDrain = mStream->drain != NULL;
-    return OK;
-}
-
-status_t StreamOutHalLocal::drain(bool earlyNotify) {
-    if (mStream->drain == NULL) return INVALID_OPERATION;
-    return mStream->drain(mStream, earlyNotify ? AUDIO_DRAIN_EARLY_NOTIFY : AUDIO_DRAIN_ALL);
-}
-
-status_t StreamOutHalLocal::flush() {
-    if (mStream->flush == NULL) return INVALID_OPERATION;
-    return mStream->flush(mStream);
-}
-
-status_t StreamOutHalLocal::getPresentationPosition(uint64_t *frames, struct timespec *timestamp) {
-    if (mStream->get_presentation_position == NULL) return INVALID_OPERATION;
-    return mStream->get_presentation_position(mStream, frames, timestamp);
-}
-
-status_t StreamOutHalLocal::updateSourceMetadata(const SourceMetadata& sourceMetadata) {
-    if (mStream->update_source_metadata == nullptr) {
-        return INVALID_OPERATION;
-    }
-    const source_metadata_t metadata {
-        .track_count = sourceMetadata.tracks.size(),
-        // const cast is fine as it is in a const structure
-        .tracks = const_cast<playback_track_metadata*>(sourceMetadata.tracks.data()),
-    };
-    mStream->update_source_metadata(mStream, &metadata);
-    return OK;
-}
-
-status_t StreamOutHalLocal::start() {
-    if (mStream->start == NULL) return INVALID_OPERATION;
-    return mStream->start(mStream);
-}
-
-status_t StreamOutHalLocal::stop() {
-    if (mStream->stop == NULL) return INVALID_OPERATION;
-    return mStream->stop(mStream);
-}
-
-status_t StreamOutHalLocal::createMmapBuffer(int32_t minSizeFrames,
-                                  struct audio_mmap_buffer_info *info) {
-    if (mStream->create_mmap_buffer == NULL) return INVALID_OPERATION;
-    return mStream->create_mmap_buffer(mStream, minSizeFrames, info);
-}
-
-status_t StreamOutHalLocal::getMmapPosition(struct audio_mmap_position *position) {
-    if (mStream->get_mmap_position == NULL) return INVALID_OPERATION;
-    return mStream->get_mmap_position(mStream, position);
-}
-
-StreamInHalLocal::StreamInHalLocal(audio_stream_in_t *stream, sp<DeviceHalLocal> device)
-        : StreamHalLocal(&stream->common, device), mStream(stream) {
-}
-
-StreamInHalLocal::~StreamInHalLocal() {
-    mDevice->closeInputStream(mStream);
-    mStream = 0;
-}
-
-status_t StreamInHalLocal::getFrameSize(size_t *size) {
-    *size = audio_stream_in_frame_size(mStream);
-    return OK;
-}
-
-status_t StreamInHalLocal::setGain(float gain) {
-    return mStream->set_gain(mStream, gain);
-}
-
-status_t StreamInHalLocal::read(void *buffer, size_t bytes, size_t *read) {
-    ssize_t readResult = mStream->read(mStream, buffer, bytes);
-    if (readResult > 0) {
-        *read = readResult;
-        mStreamPowerLog.log( buffer, *read);
-        return OK;
-    } else {
-        *read = 0;
-        return readResult;
-    }
-}
-
-status_t StreamInHalLocal::getInputFramesLost(uint32_t *framesLost) {
-    *framesLost = mStream->get_input_frames_lost(mStream);
-    return OK;
-}
-
-status_t StreamInHalLocal::getCapturePosition(int64_t *frames, int64_t *time) {
-    if (mStream->get_capture_position == NULL) return INVALID_OPERATION;
-    return mStream->get_capture_position(mStream, frames, time);
-}
-
-status_t StreamInHalLocal::updateSinkMetadata(const SinkMetadata& sinkMetadata) {
-    if (mStream->update_sink_metadata == nullptr) {
-        return INVALID_OPERATION;
-    }
-    const sink_metadata_t metadata {
-        .track_count = sinkMetadata.tracks.size(),
-        // const cast is fine as it is in a const structure
-        .tracks = const_cast<record_track_metadata*>(sinkMetadata.tracks.data()),
-    };
-    mStream->update_sink_metadata(mStream, &metadata);
-    return OK;
-}
-
-status_t StreamInHalLocal::start() {
-    if (mStream->start == NULL) return INVALID_OPERATION;
-    return mStream->start(mStream);
-}
-
-status_t StreamInHalLocal::stop() {
-    if (mStream->stop == NULL) return INVALID_OPERATION;
-    return mStream->stop(mStream);
-}
-
-status_t StreamInHalLocal::createMmapBuffer(int32_t minSizeFrames,
-                                  struct audio_mmap_buffer_info *info) {
-    if (mStream->create_mmap_buffer == NULL) return INVALID_OPERATION;
-    return mStream->create_mmap_buffer(mStream, minSizeFrames, info);
-}
-
-status_t StreamInHalLocal::getMmapPosition(struct audio_mmap_position *position) {
-    if (mStream->get_mmap_position == NULL) return INVALID_OPERATION;
-    return mStream->get_mmap_position(mStream, position);
-}
-
-status_t StreamInHalLocal::getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones) {
-    if (mStream->get_active_microphones == NULL) return INVALID_OPERATION;
-    size_t actual_mics = AUDIO_MICROPHONE_MAX_COUNT;
-    audio_microphone_characteristic_t mic_array[AUDIO_MICROPHONE_MAX_COUNT];
-    status_t status = mStream->get_active_microphones(mStream, &mic_array[0], &actual_mics);
-    for (size_t i = 0; i < actual_mics; i++) {
-        media::MicrophoneInfo microphoneInfo = media::MicrophoneInfo(mic_array[i]);
-        microphones->push_back(microphoneInfo);
-    }
-    return status;
-}
-
-} // namespace V4_0
-} // namespace android
diff --git a/media/libaudiohal/4.0/StreamHalLocal.h b/media/libaudiohal/4.0/StreamHalLocal.h
deleted file mode 100644
index 7237509..0000000
--- a/media/libaudiohal/4.0/StreamHalLocal.h
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_STREAM_HAL_LOCAL_4_0_H
-#define ANDROID_HARDWARE_STREAM_HAL_LOCAL_4_0_H
-
-#include <media/audiohal/StreamHalInterface.h>
-#include "StreamPowerLog.h"
-
-namespace android {
-namespace V4_0 {
-
-class DeviceHalLocal;
-
-class StreamHalLocal : public virtual StreamHalInterface
-{
-  public:
-    // Return the sampling rate in Hz - eg. 44100.
-    virtual status_t getSampleRate(uint32_t *rate);
-
-    // Return size of input/output buffer in bytes for this stream - eg. 4800.
-    virtual status_t getBufferSize(size_t *size);
-
-    // Return the channel mask.
-    virtual status_t getChannelMask(audio_channel_mask_t *mask);
-
-    // Return the audio format - e.g. AUDIO_FORMAT_PCM_16_BIT.
-    virtual status_t getFormat(audio_format_t *format);
-
-    // Convenience method.
-    virtual status_t getAudioProperties(
-            uint32_t *sampleRate, audio_channel_mask_t *mask, audio_format_t *format);
-
-    // Set audio stream parameters.
-    virtual status_t setParameters(const String8& kvPairs);
-
-    // Get audio stream parameters.
-    virtual status_t getParameters(const String8& keys, String8 *values);
-
-    // Add or remove the effect on the stream.
-    virtual status_t addEffect(sp<EffectHalInterface> effect);
-    virtual status_t removeEffect(sp<EffectHalInterface> effect);
-
-    // Put the audio hardware input/output into standby mode.
-    virtual status_t standby();
-
-    virtual status_t dump(int fd);
-
-    // Start a stream operating in mmap mode.
-    virtual status_t start() = 0;
-
-    // Stop a stream operating in mmap mode.
-    virtual status_t stop() = 0;
-
-    // Retrieve information on the data buffer in mmap mode.
-    virtual status_t createMmapBuffer(int32_t minSizeFrames,
-                                      struct audio_mmap_buffer_info *info) = 0;
-
-    // Get current read/write position in the mmap buffer
-    virtual status_t getMmapPosition(struct audio_mmap_position *position) = 0;
-
-    // Set the priority of the thread that interacts with the HAL
-    // (must match the priority of the audioflinger's thread that calls 'read' / 'write')
-    virtual status_t setHalThreadPriority(int priority);
-
-  protected:
-    // Subclasses can not be constructed directly by clients.
-    StreamHalLocal(audio_stream_t *stream, sp<DeviceHalLocal> device);
-
-    // The destructor automatically closes the stream.
-    virtual ~StreamHalLocal();
-
-    sp<DeviceHalLocal> mDevice;
-
-    // mStreamPowerLog is used for audio signal power logging.
-    StreamPowerLog mStreamPowerLog;
-
-  private:
-    audio_stream_t *mStream;
-};
-
-class StreamOutHalLocal : public StreamOutHalInterface, public StreamHalLocal {
-  public:
-    // Return the frame size (number of bytes per sample) of a stream.
-    virtual status_t getFrameSize(size_t *size);
-
-    // Return the audio hardware driver estimated latency in milliseconds.
-    virtual status_t getLatency(uint32_t *latency);
-
-    // Use this method in situations where audio mixing is done in the hardware.
-    virtual status_t setVolume(float left, float right);
-
-    // Write audio buffer to driver.
-    virtual status_t write(const void *buffer, size_t bytes, size_t *written);
-
-    // Return the number of audio frames written by the audio dsp to DAC since
-    // the output has exited standby.
-    virtual status_t getRenderPosition(uint32_t *dspFrames);
-
-    // Get the local time at which the next write to the audio driver will be presented.
-    virtual status_t getNextWriteTimestamp(int64_t *timestamp);
-
-    // Set the callback for notifying completion of non-blocking write and drain.
-    virtual status_t setCallback(wp<StreamOutHalInterfaceCallback> callback);
-
-    // Returns whether pause and resume operations are supported.
-    virtual status_t supportsPauseAndResume(bool *supportsPause, bool *supportsResume);
-
-    // Notifies to the audio driver to resume playback following a pause.
-    virtual status_t pause();
-
-    // Notifies to the audio driver to resume playback following a pause.
-    virtual status_t resume();
-
-    // Returns whether drain operation is supported.
-    virtual status_t supportsDrain(bool *supportsDrain);
-
-    // Requests notification when data buffered by the driver/hardware has been played.
-    virtual status_t drain(bool earlyNotify);
-
-    // Notifies to the audio driver to flush the queued data.
-    virtual status_t flush();
-
-    // Return a recent count of the number of audio frames presented to an external observer.
-    virtual status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp);
-
-    // Start a stream operating in mmap mode.
-    virtual status_t start();
-
-    // Stop a stream operating in mmap mode.
-    virtual status_t stop();
-
-    // Retrieve information on the data buffer in mmap mode.
-    virtual status_t createMmapBuffer(int32_t minSizeFrames,
-                                      struct audio_mmap_buffer_info *info);
-
-    // Get current read/write position in the mmap buffer
-    virtual status_t getMmapPosition(struct audio_mmap_position *position);
-
-    // Called when the metadata of the stream's source has been changed.
-    status_t updateSourceMetadata(const SourceMetadata& sourceMetadata) override;
-
-  private:
-    audio_stream_out_t *mStream;
-    wp<StreamOutHalInterfaceCallback> mCallback;
-
-    friend class DeviceHalLocal;
-
-    // Can not be constructed directly by clients.
-    StreamOutHalLocal(audio_stream_out_t *stream, sp<DeviceHalLocal> device);
-
-    virtual ~StreamOutHalLocal();
-
-    static int asyncCallback(stream_callback_event_t event, void *param, void *cookie);
-};
-
-class StreamInHalLocal : public StreamInHalInterface, public StreamHalLocal {
-  public:
-    // Return the frame size (number of bytes per sample) of a stream.
-    virtual status_t getFrameSize(size_t *size);
-
-    // Set the input gain for the audio driver.
-    virtual status_t setGain(float gain);
-
-    // Read audio buffer in from driver.
-    virtual status_t read(void *buffer, size_t bytes, size_t *read);
-
-    // Return the amount of input frames lost in the audio driver.
-    virtual status_t getInputFramesLost(uint32_t *framesLost);
-
-    // Return a recent count of the number of audio frames received and
-    // the clock time associated with that frame count.
-    virtual status_t getCapturePosition(int64_t *frames, int64_t *time);
-
-    // Start a stream operating in mmap mode.
-    virtual status_t start();
-
-    // Stop a stream operating in mmap mode.
-    virtual status_t stop();
-
-    // Retrieve information on the data buffer in mmap mode.
-    virtual status_t createMmapBuffer(int32_t minSizeFrames,
-                                      struct audio_mmap_buffer_info *info);
-
-    // Get current read/write position in the mmap buffer
-    virtual status_t getMmapPosition(struct audio_mmap_position *position);
-
-    // Get active microphones
-    virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones);
-
-    // Called when the metadata of the stream's sink has been changed.
-    status_t updateSinkMetadata(const SinkMetadata& sinkMetadata) override;
-
-  private:
-    audio_stream_in_t *mStream;
-
-    friend class DeviceHalLocal;
-
-    // Can not be constructed directly by clients.
-    StreamInHalLocal(audio_stream_in_t *stream, sp<DeviceHalLocal> device);
-
-    virtual ~StreamInHalLocal();
-};
-
-} // namespace V4_0
-} // namespace android
-
-#endif // ANDROID_HARDWARE_STREAM_HAL_LOCAL_4_0_H
diff --git a/media/libaudiohal/4.0/StreamPowerLog.h b/media/libaudiohal/4.0/StreamPowerLog.h
deleted file mode 100644
index 57b7201..0000000
--- a/media/libaudiohal/4.0/StreamPowerLog.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_STREAM_POWER_LOG_4_0_H
-#define ANDROID_HARDWARE_STREAM_POWER_LOG_4_0_H
-
-#include <audio_utils/clock.h>
-#include <audio_utils/PowerLog.h>
-#include <cutils/properties.h>
-#include <system/audio.h>
-
-namespace android {
-namespace V4_0 {
-
-class StreamPowerLog {
-public:
-    StreamPowerLog() :
-        mIsUserDebugOrEngBuild(is_userdebug_or_eng_build()),
-        mPowerLog(nullptr),
-        mFrameSize(0) {
-        // use init() to set up the power log.
-    }
-
-    ~StreamPowerLog() {
-        power_log_destroy(mPowerLog); // OK for null mPowerLog
-        mPowerLog = nullptr;
-    }
-
-    // A one-time initialization (do not call twice) before using StreamPowerLog.
-    void init(uint32_t sampleRate, audio_channel_mask_t channelMask, audio_format_t format) {
-        if (mPowerLog == nullptr) {
-            // Note: A way to get channel count for both input and output channel masks
-            // but does not check validity of the channel mask.
-            const uint32_t channelCount = popcount(audio_channel_mask_get_bits(channelMask));
-            mFrameSize = channelCount * audio_bytes_per_sample(format);
-            if (mFrameSize > 0) {
-                const size_t kPowerLogFramesPerEntry =
-                        (long long)sampleRate * kPowerLogSamplingIntervalMs / 1000;
-                mPowerLog = power_log_create(
-                        sampleRate,
-                        channelCount,
-                        format,
-                        kPowerLogEntries,
-                        kPowerLogFramesPerEntry);
-            }
-        }
-        // mPowerLog may be NULL (not the right build, format not accepted, etc.).
-    }
-
-    // Dump the power log to fd.
-    void dump(int fd) const {
-        // OK for null mPowerLog
-        (void)power_log_dump(
-                mPowerLog, fd, "      " /* prefix */, kPowerLogLines, 0 /* limit_ns */);
-    }
-
-    // Log the audio data contained in buffer.
-    void log(const void *buffer, size_t sizeInBytes) const {
-        if (mPowerLog != nullptr) { // mFrameSize is always nonzero if mPowerLog exists.
-            power_log_log(
-                    mPowerLog, buffer, sizeInBytes / mFrameSize, audio_utils_get_real_time_ns());
-        }
-    }
-
-    bool isUserDebugOrEngBuild() const {
-        return mIsUserDebugOrEngBuild;
-    }
-
-private:
-
-    static inline bool is_userdebug_or_eng_build() {
-        char value[PROPERTY_VALUE_MAX];
-        (void)property_get("ro.build.type", value, "unknown"); // ignore actual length
-        return strcmp(value, "userdebug") == 0 || strcmp(value, "eng") == 0;
-    }
-
-    // Audio signal power log configuration.
-    static const size_t kPowerLogLines = 40;
-    static const size_t kPowerLogSamplingIntervalMs = 50;
-    static const size_t kPowerLogEntries = (1 /* minutes */ * 60 /* seconds */ * 1000 /* msec */
-            / kPowerLogSamplingIntervalMs);
-
-    const bool mIsUserDebugOrEngBuild;
-    power_log_t *mPowerLog;
-    size_t mFrameSize;
-};
-
-} // namespace V4_0
-} // namespace android
-
-#endif // ANDROID_HARDWARE_STREAM_POWER_LOG_4_0_H
diff --git a/media/libaudiohal/4.0/VersionUtils.h b/media/libaudiohal/4.0/VersionUtils.h
deleted file mode 100644
index 1246c2e..0000000
--- a/media/libaudiohal/4.0/VersionUtils.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_VERSION_UTILS_4_0_H
-#define ANDROID_HARDWARE_VERSION_UTILS_4_0_H
-
-#include <android/hardware/audio/4.0/types.h>
-#include <hidl/HidlSupport.h>
-
-using ::android::hardware::audio::V4_0::ParameterValue;
-using ::android::hardware::audio::V4_0::Result;
-using ::android::hardware::Return;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::hidl_string;
-
-namespace android {
-namespace V4_0 {
-namespace utils {
-
-template <class T, class Callback>
-Return<void> getParameters(T& object, hidl_vec<ParameterValue> context,
-                           hidl_vec<hidl_string> keys, Callback callback) {
-    return object->getParameters(context, keys, callback);
-}
-
-template <class T>
-Return<Result> setParameters(T& object, hidl_vec<ParameterValue> context,
-                             hidl_vec<ParameterValue> keys) {
-    return object->setParameters(context, keys);
-}
-
-} // namespace utils
-} // namespace V4_0
-} // namespace android
-
-#endif // ANDROID_HARDWARE_VERSION_UTILS_4_0_H
diff --git a/media/libaudiohal/4.0/include/libaudiohal/4.0/DevicesFactoryHalHybrid.h b/media/libaudiohal/4.0/include/libaudiohal/4.0/DevicesFactoryHalHybrid.h
deleted file mode 100644
index abf6de0..0000000
--- a/media/libaudiohal/4.0/include/libaudiohal/4.0/DevicesFactoryHalHybrid.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_DEVICES_FACTORY_HAL_HYBRID_4_0_H
-#define ANDROID_HARDWARE_DEVICES_FACTORY_HAL_HYBRID_4_0_H
-
-#include <media/audiohal/DevicesFactoryHalInterface.h>
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-
-namespace android {
-namespace V4_0 {
-
-class DevicesFactoryHalHybrid : public DevicesFactoryHalInterface
-{
-  public:
-    // Opens a device with the specified name. To close the device, it is
-    // necessary to release references to the returned object.
-    virtual status_t openDevice(const char *name, sp<DeviceHalInterface> *device);
-
-  private:
-    friend class DevicesFactoryHalInterface;
-
-    // Can not be constructed directly by clients.
-    DevicesFactoryHalHybrid();
-
-    virtual ~DevicesFactoryHalHybrid();
-
-    sp<DevicesFactoryHalInterface> mLocalFactory;
-    sp<DevicesFactoryHalInterface> mHidlFactory;
-};
-
-} // namespace V4_0
-} // namespace android
-
-#endif // ANDROID_HARDWARE_DEVICES_FACTORY_HAL_HYBRID_4_0_H
diff --git a/media/libaudiohal/4.0/include/libaudiohal/4.0/EffectsFactoryHalHidl.h b/media/libaudiohal/4.0/include/libaudiohal/4.0/EffectsFactoryHalHidl.h
deleted file mode 100644
index 680b7a1..0000000
--- a/media/libaudiohal/4.0/include/libaudiohal/4.0/EffectsFactoryHalHidl.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_EFFECTS_FACTORY_HAL_HIDL_4_0_H
-#define ANDROID_HARDWARE_EFFECTS_FACTORY_HAL_HIDL_4_0_H
-
-#include <android/hardware/audio/effect/4.0/IEffectsFactory.h>
-#include <android/hardware/audio/effect/4.0/types.h>
-#include <media/audiohal/EffectsFactoryHalInterface.h>
-
-#include "ConversionHelperHidl.h"
-
-namespace android {
-namespace V4_0 {
-
-using ::android::hardware::audio::effect::V4_0::EffectDescriptor;
-using ::android::hardware::audio::effect::V4_0::IEffectsFactory;
-using ::android::hardware::hidl_vec;
-
-class EffectsFactoryHalHidl : public EffectsFactoryHalInterface, public ConversionHelperHidl
-{
-  public:
-    // Returns the number of different effects in all loaded libraries.
-    virtual status_t queryNumberEffects(uint32_t *pNumEffects);
-
-    // Returns a descriptor of the next available effect.
-    virtual status_t getDescriptor(uint32_t index,
-            effect_descriptor_t *pDescriptor);
-
-    virtual status_t getDescriptor(const effect_uuid_t *pEffectUuid,
-            effect_descriptor_t *pDescriptor);
-
-    // Creates an effect engine of the specified type.
-    // To release the effect engine, it is necessary to release references
-    // to the returned effect object.
-    virtual status_t createEffect(const effect_uuid_t *pEffectUuid,
-            int32_t sessionId, int32_t ioId,
-            sp<EffectHalInterface> *effect);
-
-    virtual status_t dumpEffects(int fd);
-
-    status_t allocateBuffer(size_t size, sp<EffectBufferHalInterface>* buffer) override;
-    status_t mirrorBuffer(void* external, size_t size,
-                          sp<EffectBufferHalInterface>* buffer) override;
-
-  private:
-    friend class EffectsFactoryHalInterface;
-
-    sp<IEffectsFactory> mEffectsFactory;
-    hidl_vec<EffectDescriptor> mLastDescriptors;
-
-    // Can not be constructed directly by clients.
-    EffectsFactoryHalHidl();
-    virtual ~EffectsFactoryHalHidl();
-
-    status_t queryAllDescriptors();
-};
-
-} // namespace V4_0
-} // namespace android
-
-#endif // ANDROID_HARDWARE_EFFECTS_FACTORY_HAL_HIDL_4_0_H
diff --git a/media/libaudiohal/Android.bp b/media/libaudiohal/Android.bp
index 3a5df27..584c2c0 100644
--- a/media/libaudiohal/Android.bp
+++ b/media/libaudiohal/Android.bp
@@ -8,16 +8,20 @@
 
     cflags: [
         "-Wall",
+        "-Wextra",
         "-Werror",
     ],
 
     shared_libs: [
         "android.hardware.audio.effect@2.0",
         "android.hardware.audio.effect@4.0",
+        "android.hardware.audio.effect@5.0",
         "android.hardware.audio@2.0",
         "android.hardware.audio@4.0",
+        "android.hardware.audio@5.0",
         "libaudiohal@2.0",
         "libaudiohal@4.0",
+        "libaudiohal@5.0",
         "libutils",
     ],
 
diff --git a/media/libaudiohal/DevicesFactoryHalInterface.cpp b/media/libaudiohal/DevicesFactoryHalInterface.cpp
index 4c8eaf6..f86009c 100644
--- a/media/libaudiohal/DevicesFactoryHalInterface.cpp
+++ b/media/libaudiohal/DevicesFactoryHalInterface.cpp
@@ -16,19 +16,22 @@
 
 #include <android/hardware/audio/2.0/IDevicesFactory.h>
 #include <android/hardware/audio/4.0/IDevicesFactory.h>
+#include <android/hardware/audio/5.0/IDevicesFactory.h>
 
-#include <DevicesFactoryHalHybrid.h>
-#include <libaudiohal/4.0/DevicesFactoryHalHybrid.h>
+#include <libaudiohal/FactoryHalHidl.h>
 
 namespace android {
 
 // static
 sp<DevicesFactoryHalInterface> DevicesFactoryHalInterface::create() {
+    if (hardware::audio::V5_0::IDevicesFactory::getService() != nullptr) {
+        return V5_0::createDevicesFactoryHal();
+    }
     if (hardware::audio::V4_0::IDevicesFactory::getService() != nullptr) {
-        return new V4_0::DevicesFactoryHalHybrid();
+        return V4_0::createDevicesFactoryHal();
     }
     if (hardware::audio::V2_0::IDevicesFactory::getService() != nullptr) {
-        return new DevicesFactoryHalHybrid();
+        return V2_0::createDevicesFactoryHal();
     }
     return nullptr;
 }
diff --git a/media/libaudiohal/EffectsFactoryHalInterface.cpp b/media/libaudiohal/EffectsFactoryHalInterface.cpp
index ead1fa2..bd3ef61 100644
--- a/media/libaudiohal/EffectsFactoryHalInterface.cpp
+++ b/media/libaudiohal/EffectsFactoryHalInterface.cpp
@@ -16,20 +16,22 @@
 
 #include <android/hardware/audio/effect/2.0/IEffectsFactory.h>
 #include <android/hardware/audio/effect/4.0/IEffectsFactory.h>
+#include <android/hardware/audio/effect/5.0/IEffectsFactory.h>
 
-#include <EffectsFactoryHalHidl.h>
-#include <libaudiohal/4.0/EffectsFactoryHalHidl.h>
-
+#include <libaudiohal/FactoryHalHidl.h>
 
 namespace android {
 
 // static
 sp<EffectsFactoryHalInterface> EffectsFactoryHalInterface::create() {
+    if (hardware::audio::effect::V5_0::IEffectsFactory::getService() != nullptr) {
+        return effect::V5_0::createEffectsFactoryHal();
+    }
     if (hardware::audio::effect::V4_0::IEffectsFactory::getService() != nullptr) {
-        return new V4_0::EffectsFactoryHalHidl();
+        return effect::V4_0::createEffectsFactoryHal();
     }
     if (hardware::audio::effect::V2_0::IEffectsFactory::getService() != nullptr) {
-        return new EffectsFactoryHalHidl();
+        return effect::V2_0::createEffectsFactoryHal();
     }
     return nullptr;
 }
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
new file mode 100644
index 0000000..88533da
--- /dev/null
+++ b/media/libaudiohal/impl/Android.bp
@@ -0,0 +1,102 @@
+cc_defaults {
+    name: "libaudiohal_default",
+
+    srcs: [
+        "DeviceHalLocal.cpp",
+        "DevicesFactoryHalHybrid.cpp",
+        "DevicesFactoryHalLocal.cpp",
+        "StreamHalLocal.cpp",
+
+        "ConversionHelperHidl.cpp",
+        "DeviceHalHidl.cpp",
+        "DevicesFactoryHalHidl.cpp",
+        "EffectBufferHalHidl.cpp",
+        "EffectHalHidl.cpp",
+        "EffectsFactoryHalHidl.cpp",
+        "StreamHalHidl.cpp",
+    ],
+
+    export_include_dirs: ["include"],
+
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+    ],
+    shared_libs: [
+        "android.hardware.audio.common-util",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
+        "libaudiohal_deathhandler",
+        "libaudioutils",
+        "libbase",
+        "libbinder",
+        "libcutils",
+        "libfmq",
+        "libhardware",
+        "libhidlbase",
+        "libhidlmemory",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libmedia_helper",
+        "libmediautils",
+        "libutils",
+    ],
+    header_libs: [
+        "android.hardware.audio.common.util@all-versions",
+        "libaudiohal_headers"
+    ],
+
+    export_shared_lib_headers: [
+        "libfmq",
+    ],
+}
+
+cc_library_shared {
+    name: "libaudiohal@2.0",
+    defaults: ["libaudiohal_default"],
+    shared_libs: [
+        "android.hardware.audio.common@2.0",
+        "android.hardware.audio.common@2.0-util",
+        "android.hardware.audio.effect@2.0",
+        "android.hardware.audio@2.0",
+    ],
+    cflags: [
+        "-DMAJOR_VERSION=2",
+        "-DMINOR_VERSION=0",
+        "-include common/all-versions/VersionMacro.h",
+    ]
+}
+
+cc_library_shared {
+    name: "libaudiohal@4.0",
+    defaults: ["libaudiohal_default"],
+    shared_libs: [
+        "android.hardware.audio.common@4.0",
+        "android.hardware.audio.common@4.0-util",
+        "android.hardware.audio.effect@4.0",
+        "android.hardware.audio@4.0",
+    ],
+    cflags: [
+        "-DMAJOR_VERSION=4",
+        "-DMINOR_VERSION=0",
+        "-include common/all-versions/VersionMacro.h",
+    ]
+}
+
+cc_library_shared {
+    name: "libaudiohal@5.0",
+    defaults: ["libaudiohal_default"],
+    shared_libs: [
+        "android.hardware.audio.common@5.0",
+        "android.hardware.audio.common@5.0-util",
+        "android.hardware.audio.effect@5.0",
+        "android.hardware.audio@5.0",
+    ],
+    cflags: [
+        "-DMAJOR_VERSION=5",
+        "-DMINOR_VERSION=0",
+        "-include common/all-versions/VersionMacro.h",
+    ]
+}
diff --git a/media/libaudiohal/impl/ConversionHelperHidl.cpp b/media/libaudiohal/impl/ConversionHelperHidl.cpp
new file mode 100644
index 0000000..9f8a520
--- /dev/null
+++ b/media/libaudiohal/impl/ConversionHelperHidl.cpp
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+
+#define LOG_TAG "HalHidl"
+#include <media/AudioParameter.h>
+#include <utils/Log.h>
+
+#include "ConversionHelperHidl.h"
+
+namespace android {
+namespace CPP_VERSION {
+
+using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::CPP_VERSION;
+
+// static
+status_t ConversionHelperHidl::keysFromHal(const String8& keys, hidl_vec<hidl_string> *hidlKeys) {
+    AudioParameter halKeys(keys);
+    if (halKeys.size() == 0) return BAD_VALUE;
+    hidlKeys->resize(halKeys.size());
+    //FIXME:  keyStreamSupportedChannels and keyStreamSupportedSamplingRates come with a
+    // "keyFormat=<value>" pair. We need to transform it into a single key string so that it is
+    // carried over to the legacy HAL via HIDL.
+    String8 value;
+    bool keepFormatValue = halKeys.size() == 2 &&
+         (halKeys.get(String8(AudioParameter::keyStreamSupportedChannels), value) == NO_ERROR ||
+         halKeys.get(String8(AudioParameter::keyStreamSupportedSamplingRates), value) == NO_ERROR);
+
+    for (size_t i = 0; i < halKeys.size(); ++i) {
+        String8 key;
+        status_t status = halKeys.getAt(i, key);
+        if (status != OK) return status;
+        if (keepFormatValue && key == AudioParameter::keyFormat) {
+            AudioParameter formatParam;
+            halKeys.getAt(i, key, value);
+            formatParam.add(key, value);
+            key = formatParam.toString();
+        }
+        (*hidlKeys)[i] = key.string();
+    }
+    return OK;
+}
+
+// static
+status_t ConversionHelperHidl::parametersFromHal(
+        const String8& kvPairs, hidl_vec<ParameterValue> *hidlParams) {
+    AudioParameter params(kvPairs);
+    if (params.size() == 0) return BAD_VALUE;
+    hidlParams->resize(params.size());
+    for (size_t i = 0; i < params.size(); ++i) {
+        String8 key, value;
+        status_t status = params.getAt(i, key, value);
+        if (status != OK) return status;
+        (*hidlParams)[i].key = key.string();
+        (*hidlParams)[i].value = value.string();
+    }
+    return OK;
+}
+
+// static
+void ConversionHelperHidl::parametersToHal(
+        const hidl_vec<ParameterValue>& parameters, String8 *values) {
+    AudioParameter params;
+    for (size_t i = 0; i < parameters.size(); ++i) {
+        params.add(String8(parameters[i].key.c_str()), String8(parameters[i].value.c_str()));
+    }
+    values->setTo(params.toString());
+}
+
+ConversionHelperHidl::ConversionHelperHidl(const char* className)
+        : mClassName(className) {
+}
+
+// static
+status_t ConversionHelperHidl::analyzeResult(const Result& result) {
+    switch (result) {
+        case Result::OK: return OK;
+        case Result::INVALID_ARGUMENTS: return BAD_VALUE;
+        case Result::INVALID_STATE: return NOT_ENOUGH_DATA;
+        case Result::NOT_INITIALIZED: return NO_INIT;
+        case Result::NOT_SUPPORTED: return INVALID_OPERATION;
+        default: return NO_INIT;
+    }
+}
+
+void ConversionHelperHidl::emitError(const char* funcName, const char* description) {
+    ALOGE("%s %p %s: %s (from rpc)", mClassName, this, funcName, description);
+}
+
+#if MAJOR_VERSION >= 4
+// TODO: Use the same implementation in the hal when it moves to a util library.
+static std::string deviceAddressToHal(const DeviceAddress& address) {
+    // HAL assumes that the address is NUL-terminated.
+    char halAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN];
+    memset(halAddress, 0, sizeof(halAddress));
+    audio_devices_t halDevice = static_cast<audio_devices_t>(address.device);
+    const bool isInput = (halDevice & AUDIO_DEVICE_BIT_IN) != 0;
+    if (isInput) halDevice &= ~AUDIO_DEVICE_BIT_IN;
+    if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != 0) ||
+        (isInput && (halDevice & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0)) {
+        snprintf(halAddress, sizeof(halAddress), "%02X:%02X:%02X:%02X:%02X:%02X",
+                 address.address.mac[0], address.address.mac[1], address.address.mac[2],
+                 address.address.mac[3], address.address.mac[4], address.address.mac[5]);
+    } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_IP) != 0) ||
+               (isInput && (halDevice & AUDIO_DEVICE_IN_IP) != 0)) {
+        snprintf(halAddress, sizeof(halAddress), "%d.%d.%d.%d", address.address.ipv4[0],
+                 address.address.ipv4[1], address.address.ipv4[2], address.address.ipv4[3]);
+    } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_ALL_USB) != 0) ||
+               (isInput && (halDevice & AUDIO_DEVICE_IN_ALL_USB) != 0)) {
+        snprintf(halAddress, sizeof(halAddress), "card=%d;device=%d", address.address.alsa.card,
+                 address.address.alsa.device);
+    } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_BUS) != 0) ||
+               (isInput && (halDevice & AUDIO_DEVICE_IN_BUS) != 0)) {
+        snprintf(halAddress, sizeof(halAddress), "%s", address.busAddress.c_str());
+    } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) != 0 ||
+               (isInput && (halDevice & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0)) {
+        snprintf(halAddress, sizeof(halAddress), "%s", address.rSubmixAddress.c_str());
+    } else {
+        snprintf(halAddress, sizeof(halAddress), "%s", address.busAddress.c_str());
+    }
+    return halAddress;
+}
+
+//local conversion helpers
+
+static audio_microphone_channel_mapping_t  channelMappingToHal(AudioMicrophoneChannelMapping mapping) {
+    switch (mapping) {
+        case AudioMicrophoneChannelMapping::UNUSED:
+            return AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED;
+        case AudioMicrophoneChannelMapping::DIRECT:
+            return AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT;
+        case AudioMicrophoneChannelMapping::PROCESSED:
+            return AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED;
+        default:
+            LOG_ALWAYS_FATAL("Unknown channelMappingToHal conversion %d", mapping);
+    }
+}
+
+static audio_microphone_location_t locationToHal(AudioMicrophoneLocation location) {
+    switch (location) {
+        case AudioMicrophoneLocation::UNKNOWN:
+            return AUDIO_MICROPHONE_LOCATION_UNKNOWN;
+        case AudioMicrophoneLocation::MAINBODY:
+            return AUDIO_MICROPHONE_LOCATION_MAINBODY;
+        case AudioMicrophoneLocation::MAINBODY_MOVABLE:
+            return AUDIO_MICROPHONE_LOCATION_MAINBODY_MOVABLE;
+        case AudioMicrophoneLocation::PERIPHERAL:
+            return AUDIO_MICROPHONE_LOCATION_PERIPHERAL;
+        default:
+            LOG_ALWAYS_FATAL("Unknown locationToHal conversion %d", location);
+    }
+}
+static audio_microphone_directionality_t directionalityToHal(AudioMicrophoneDirectionality dir) {
+    switch (dir) {
+        case AudioMicrophoneDirectionality::UNKNOWN:
+            return AUDIO_MICROPHONE_DIRECTIONALITY_UNKNOWN;
+        case AudioMicrophoneDirectionality::OMNI:
+            return AUDIO_MICROPHONE_DIRECTIONALITY_OMNI;
+        case AudioMicrophoneDirectionality::BI_DIRECTIONAL:
+            return AUDIO_MICROPHONE_DIRECTIONALITY_BI_DIRECTIONAL;
+        case AudioMicrophoneDirectionality::CARDIOID:
+            return AUDIO_MICROPHONE_DIRECTIONALITY_CARDIOID;
+        case AudioMicrophoneDirectionality::HYPER_CARDIOID:
+            return AUDIO_MICROPHONE_DIRECTIONALITY_HYPER_CARDIOID;
+        case AudioMicrophoneDirectionality::SUPER_CARDIOID:
+            return AUDIO_MICROPHONE_DIRECTIONALITY_SUPER_CARDIOID;
+        default:
+            LOG_ALWAYS_FATAL("Unknown directionalityToHal conversion %d", dir);
+    }
+}
+
+void microphoneInfoToHal(const MicrophoneInfo& src,
+                         audio_microphone_characteristic_t *pDst) {
+    if (pDst != NULL) {
+        snprintf(pDst->device_id, sizeof(pDst->device_id),
+                 "%s", src.deviceId.c_str());
+        pDst->device = static_cast<audio_devices_t>(src.deviceAddress.device);
+        snprintf(pDst->address, sizeof(pDst->address),
+                 "%s", deviceAddressToHal(src.deviceAddress).c_str());
+        if (src.channelMapping.size() > AUDIO_CHANNEL_COUNT_MAX) {
+            ALOGW("microphoneInfoToStruct found %zu channelMapping elements. Max expected is %d",
+                  src.channelMapping.size(), AUDIO_CHANNEL_COUNT_MAX);
+        }
+        size_t ch;
+        for (ch = 0; ch < src.channelMapping.size() && ch < AUDIO_CHANNEL_COUNT_MAX; ch++) {
+            pDst->channel_mapping[ch] = channelMappingToHal(src.channelMapping[ch]);
+        }
+        for (; ch < AUDIO_CHANNEL_COUNT_MAX; ch++) {
+            pDst->channel_mapping[ch] = AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED;
+        }
+        pDst->location = locationToHal(src.location);
+        pDst->group = (audio_microphone_group_t)src.group;
+        pDst->index_in_the_group = (unsigned int)src.indexInTheGroup;
+        pDst->sensitivity = src.sensitivity;
+        pDst->max_spl = src.maxSpl;
+        pDst->min_spl = src.minSpl;
+        pDst->directionality = directionalityToHal(src.directionality);
+        pDst->num_frequency_responses = (unsigned int)src.frequencyResponse.size();
+        if (pDst->num_frequency_responses > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
+            ALOGW("microphoneInfoToStruct found %d frequency responses. Max expected is %d",
+                  pDst->num_frequency_responses, AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES);
+            pDst->num_frequency_responses = AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES;
+        }
+        for (size_t k = 0; k < pDst->num_frequency_responses; k++) {
+            pDst->frequency_responses[0][k] = src.frequencyResponse[k].frequency;
+            pDst->frequency_responses[1][k] = src.frequencyResponse[k].level;
+        }
+        pDst->geometric_location.x = src.position.x;
+        pDst->geometric_location.y = src.position.y;
+        pDst->geometric_location.z = src.position.z;
+        pDst->orientation.x = src.orientation.x;
+        pDst->orientation.y = src.orientation.y;
+        pDst->orientation.z = src.orientation.z;
+    }
+}
+#endif
+
+}  // namespace CPP_VERSION
+}  // namespace android
diff --git a/media/libaudiohal/impl/ConversionHelperHidl.h b/media/libaudiohal/impl/ConversionHelperHidl.h
new file mode 100644
index 0000000..fb3bb9d
--- /dev/null
+++ b/media/libaudiohal/impl/ConversionHelperHidl.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_CONVERSION_HELPER_HIDL_H
+#define ANDROID_HARDWARE_CONVERSION_HELPER_HIDL_H
+
+#include PATH(android/hardware/audio/FILE_VERSION/types.h)
+#include <hidl/HidlSupport.h>
+#include <system/audio.h>
+#include <utils/String8.h>
+
+using ::android::hardware::audio::CPP_VERSION::ParameterValue;
+using CoreResult = ::android::hardware::audio::CPP_VERSION::Result;
+
+using ::android::hardware::Return;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+
+namespace android {
+namespace CPP_VERSION {
+
+class ConversionHelperHidl {
+  protected:
+    static status_t keysFromHal(const String8& keys, hidl_vec<hidl_string> *hidlKeys);
+    static status_t parametersFromHal(const String8& kvPairs, hidl_vec<ParameterValue> *hidlParams);
+    static void parametersToHal(const hidl_vec<ParameterValue>& parameters, String8 *values);
+
+    ConversionHelperHidl(const char* className);
+
+    template<typename R, typename T>
+    status_t processReturn(const char* funcName, const Return<R>& ret, T *retval) {
+        if (ret.isOk()) {
+            // This way it also works for enum class to unscoped enum conversion.
+            *retval = static_cast<T>(static_cast<R>(ret));
+            return OK;
+        }
+        return processReturn(funcName, ret);
+    }
+
+    template<typename T>
+    status_t processReturn(const char* funcName, const Return<T>& ret) {
+        if (!ret.isOk()) {
+            emitError(funcName, ret.description().c_str());
+        }
+        return ret.isOk() ? OK : FAILED_TRANSACTION;
+    }
+
+    status_t processReturn(const char* funcName, const Return<CoreResult>& ret) {
+        if (!ret.isOk()) {
+            emitError(funcName, ret.description().c_str());
+        }
+        return ret.isOk() ? analyzeResult(ret) : FAILED_TRANSACTION;
+    }
+
+    template<typename T>
+    status_t processReturn(
+            const char* funcName, const Return<T>& ret, CoreResult retval) {
+        if (!ret.isOk()) {
+            emitError(funcName, ret.description().c_str());
+        }
+        return ret.isOk() ? analyzeResult(retval) : FAILED_TRANSACTION;
+    }
+
+  private:
+    const char* mClassName;
+
+    static status_t analyzeResult(const CoreResult& result);
+
+    void emitError(const char* funcName, const char* description);
+};
+
+#if MAJOR_VERSION >= 4
+using ::android::hardware::audio::CPP_VERSION::MicrophoneInfo;
+void microphoneInfoToHal(const MicrophoneInfo& src,
+                         audio_microphone_characteristic_t *pDst);
+#endif
+
+}  // namespace CPP_VERSION
+}  // namespace android
+
+#endif // ANDROID_HARDWARE_CONVERSION_HELPER_HIDL_H
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
new file mode 100644
index 0000000..b25f82e
--- /dev/null
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -0,0 +1,403 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+
+#define LOG_TAG "DeviceHalHidl"
+//#define LOG_NDEBUG 0
+
+#include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
+#include <cutils/native_handle.h>
+#include <hwbinder/IPCThreadState.h>
+#include <utils/Log.h>
+
+#include <common/all-versions/VersionUtils.h>
+
+#include "DeviceHalHidl.h"
+#include "HidlUtils.h"
+#include "StreamHalHidl.h"
+#include "VersionUtils.h"
+
+using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::common::utils::EnumBitfield;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+
+namespace android {
+namespace CPP_VERSION {
+
+using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::CPP_VERSION;
+
+namespace {
+
+status_t deviceAddressFromHal(
+        audio_devices_t device, const char* halAddress, DeviceAddress* address) {
+    address->device = AudioDevice(device);
+
+    if (halAddress == nullptr || strnlen(halAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
+        return OK;
+    }
+    const bool isInput = (device & AUDIO_DEVICE_BIT_IN) != 0;
+    if (isInput) device &= ~AUDIO_DEVICE_BIT_IN;
+    if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_A2DP) != 0)
+            || (isInput && (device & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0)) {
+        int status = sscanf(halAddress,
+                "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX",
+                &address->address.mac[0], &address->address.mac[1], &address->address.mac[2],
+                &address->address.mac[3], &address->address.mac[4], &address->address.mac[5]);
+        return status == 6 ? OK : BAD_VALUE;
+    } else if ((!isInput && (device & AUDIO_DEVICE_OUT_IP) != 0)
+            || (isInput && (device & AUDIO_DEVICE_IN_IP) != 0)) {
+        int status = sscanf(halAddress,
+                "%hhu.%hhu.%hhu.%hhu",
+                &address->address.ipv4[0], &address->address.ipv4[1],
+                &address->address.ipv4[2], &address->address.ipv4[3]);
+        return status == 4 ? OK : BAD_VALUE;
+    } else if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_USB)) != 0
+            || (isInput && (device & AUDIO_DEVICE_IN_ALL_USB)) != 0) {
+        int status = sscanf(halAddress,
+                "card=%d;device=%d",
+                &address->address.alsa.card, &address->address.alsa.device);
+        return status == 2 ? OK : BAD_VALUE;
+    } else if ((!isInput && (device & AUDIO_DEVICE_OUT_BUS) != 0)
+            || (isInput && (device & AUDIO_DEVICE_IN_BUS) != 0)) {
+        if (halAddress != NULL) {
+            address->busAddress = halAddress;
+            return OK;
+        }
+        return BAD_VALUE;
+    } else if ((!isInput && (device & AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) != 0
+            || (isInput && (device & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0)) {
+        if (halAddress != NULL) {
+            address->rSubmixAddress = halAddress;
+            return OK;
+        }
+        return BAD_VALUE;
+    }
+    return OK;
+}
+
+}  // namespace
+
+DeviceHalHidl::DeviceHalHidl(const sp<IDevice>& device)
+        : ConversionHelperHidl("Device"), mDevice(device),
+          mPrimaryDevice(IPrimaryDevice::castFrom(device)) {
+}
+
+DeviceHalHidl::~DeviceHalHidl() {
+    if (mDevice != 0) {
+        mDevice.clear();
+        hardware::IPCThreadState::self()->flushCommands();
+    }
+}
+
+status_t DeviceHalHidl::getSupportedDevices(uint32_t*) {
+    // Obsolete.
+    return INVALID_OPERATION;
+}
+
+status_t DeviceHalHidl::initCheck() {
+    if (mDevice == 0) return NO_INIT;
+    return processReturn("initCheck", mDevice->initCheck());
+}
+
+status_t DeviceHalHidl::setVoiceVolume(float volume) {
+    if (mDevice == 0) return NO_INIT;
+    if (mPrimaryDevice == 0) return INVALID_OPERATION;
+    return processReturn("setVoiceVolume", mPrimaryDevice->setVoiceVolume(volume));
+}
+
+status_t DeviceHalHidl::setMasterVolume(float volume) {
+    if (mDevice == 0) return NO_INIT;
+    return processReturn("setMasterVolume", mDevice->setMasterVolume(volume));
+}
+
+status_t DeviceHalHidl::getMasterVolume(float *volume) {
+    if (mDevice == 0) return NO_INIT;
+    Result retval;
+    Return<void> ret = mDevice->getMasterVolume(
+            [&](Result r, float v) {
+                retval = r;
+                if (retval == Result::OK) {
+                    *volume = v;
+                }
+            });
+    return processReturn("getMasterVolume", ret, retval);
+}
+
+status_t DeviceHalHidl::setMode(audio_mode_t mode) {
+    if (mDevice == 0) return NO_INIT;
+    if (mPrimaryDevice == 0) return INVALID_OPERATION;
+    return processReturn("setMode", mPrimaryDevice->setMode(AudioMode(mode)));
+}
+
+status_t DeviceHalHidl::setMicMute(bool state) {
+    if (mDevice == 0) return NO_INIT;
+    return processReturn("setMicMute", mDevice->setMicMute(state));
+}
+
+status_t DeviceHalHidl::getMicMute(bool *state) {
+    if (mDevice == 0) return NO_INIT;
+    Result retval;
+    Return<void> ret = mDevice->getMicMute(
+            [&](Result r, bool mute) {
+                retval = r;
+                if (retval == Result::OK) {
+                    *state = mute;
+                }
+            });
+    return processReturn("getMicMute", ret, retval);
+}
+
+status_t DeviceHalHidl::setMasterMute(bool state) {
+    if (mDevice == 0) return NO_INIT;
+    return processReturn("setMasterMute", mDevice->setMasterMute(state));
+}
+
+status_t DeviceHalHidl::getMasterMute(bool *state) {
+    if (mDevice == 0) return NO_INIT;
+    Result retval;
+    Return<void> ret = mDevice->getMasterMute(
+            [&](Result r, bool mute) {
+                retval = r;
+                if (retval == Result::OK) {
+                    *state = mute;
+                }
+            });
+    return processReturn("getMasterMute", ret, retval);
+}
+
+status_t DeviceHalHidl::setParameters(const String8& kvPairs) {
+    if (mDevice == 0) return NO_INIT;
+    hidl_vec<ParameterValue> hidlParams;
+    status_t status = parametersFromHal(kvPairs, &hidlParams);
+    if (status != OK) return status;
+    // TODO: change the API so that context and kvPairs are separated
+    return processReturn("setParameters",
+                         utils::setParameters(mDevice, {} /* context */, hidlParams));
+}
+
+status_t DeviceHalHidl::getParameters(const String8& keys, String8 *values) {
+    values->clear();
+    if (mDevice == 0) return NO_INIT;
+    hidl_vec<hidl_string> hidlKeys;
+    status_t status = keysFromHal(keys, &hidlKeys);
+    if (status != OK) return status;
+    Result retval;
+    Return<void> ret = utils::getParameters(mDevice,
+            {} /* context */,
+            hidlKeys,
+            [&](Result r, const hidl_vec<ParameterValue>& parameters) {
+                retval = r;
+                if (retval == Result::OK) {
+                    parametersToHal(parameters, values);
+                }
+            });
+    return processReturn("getParameters", ret, retval);
+}
+
+status_t DeviceHalHidl::getInputBufferSize(
+        const struct audio_config *config, size_t *size) {
+    if (mDevice == 0) return NO_INIT;
+    AudioConfig hidlConfig;
+    HidlUtils::audioConfigFromHal(*config, &hidlConfig);
+    Result retval;
+    Return<void> ret = mDevice->getInputBufferSize(
+            hidlConfig,
+            [&](Result r, uint64_t bufferSize) {
+                retval = r;
+                if (retval == Result::OK) {
+                    *size = static_cast<size_t>(bufferSize);
+                }
+            });
+    return processReturn("getInputBufferSize", ret, retval);
+}
+
+status_t DeviceHalHidl::openOutputStream(
+        audio_io_handle_t handle,
+        audio_devices_t devices,
+        audio_output_flags_t flags,
+        struct audio_config *config,
+        const char *address,
+        sp<StreamOutHalInterface> *outStream) {
+    if (mDevice == 0) return NO_INIT;
+    DeviceAddress hidlDevice;
+    status_t status = deviceAddressFromHal(devices, address, &hidlDevice);
+    if (status != OK) return status;
+    AudioConfig hidlConfig;
+    HidlUtils::audioConfigFromHal(*config, &hidlConfig);
+    Result retval = Result::NOT_INITIALIZED;
+    Return<void> ret = mDevice->openOutputStream(
+            handle,
+            hidlDevice,
+            hidlConfig,
+            EnumBitfield<AudioOutputFlag>(flags),
+#if MAJOR_VERSION >= 4
+            {} /* metadata */,
+#endif
+            [&](Result r, const sp<IStreamOut>& result, const AudioConfig& suggestedConfig) {
+                retval = r;
+                if (retval == Result::OK) {
+                    *outStream = new StreamOutHalHidl(result);
+                }
+                HidlUtils::audioConfigToHal(suggestedConfig, config);
+            });
+    return processReturn("openOutputStream", ret, retval);
+}
+
+status_t DeviceHalHidl::openInputStream(
+        audio_io_handle_t handle,
+        audio_devices_t devices,
+        struct audio_config *config,
+        audio_input_flags_t flags,
+        const char *address,
+        audio_source_t source,
+        audio_devices_t outputDevice,
+        const char *outputDeviceAddress,
+        sp<StreamInHalInterface> *inStream) {
+    if (mDevice == 0) return NO_INIT;
+    DeviceAddress hidlDevice;
+    status_t status = deviceAddressFromHal(devices, address, &hidlDevice);
+    if (status != OK) return status;
+    AudioConfig hidlConfig;
+    HidlUtils::audioConfigFromHal(*config, &hidlConfig);
+    Result retval = Result::NOT_INITIALIZED;
+#if MAJOR_VERSION == 2
+    auto sinkMetadata = AudioSource(source);
+#elif MAJOR_VERSION >= 4
+    // TODO: correctly propagate the tracks sources and volume
+    //       for now, only send the main source at 1dbfs
+    SinkMetadata sinkMetadata = {{{ .source = AudioSource(source), .gain = 1 }}};
+#endif
+#if MAJOR_VERSION < 5
+    (void)outputDevice;
+    (void)outputDeviceAddress;
+#else
+    if (outputDevice != AUDIO_DEVICE_NONE) {
+        DeviceAddress hidlOutputDevice;
+        status = deviceAddressFromHal(outputDevice, outputDeviceAddress, &hidlOutputDevice);
+        if (status != OK) return status;
+        sinkMetadata.tracks[0].destination.device(std::move(hidlOutputDevice));
+    }
+#endif
+    Return<void> ret = mDevice->openInputStream(
+            handle,
+            hidlDevice,
+            hidlConfig,
+            EnumBitfield<AudioInputFlag>(flags),
+            sinkMetadata,
+            [&](Result r, const sp<IStreamIn>& result, const AudioConfig& suggestedConfig) {
+                retval = r;
+                if (retval == Result::OK) {
+                    *inStream = new StreamInHalHidl(result);
+                }
+                HidlUtils::audioConfigToHal(suggestedConfig, config);
+            });
+    return processReturn("openInputStream", ret, retval);
+}
+
+status_t DeviceHalHidl::supportsAudioPatches(bool *supportsPatches) {
+    if (mDevice == 0) return NO_INIT;
+    return processReturn("supportsAudioPatches", mDevice->supportsAudioPatches(), supportsPatches);
+}
+
+status_t DeviceHalHidl::createAudioPatch(
+        unsigned int num_sources,
+        const struct audio_port_config *sources,
+        unsigned int num_sinks,
+        const struct audio_port_config *sinks,
+        audio_patch_handle_t *patch) {
+    if (mDevice == 0) return NO_INIT;
+    hidl_vec<AudioPortConfig> hidlSources, hidlSinks;
+    HidlUtils::audioPortConfigsFromHal(num_sources, sources, &hidlSources);
+    HidlUtils::audioPortConfigsFromHal(num_sinks, sinks, &hidlSinks);
+    Result retval;
+    Return<void> ret = mDevice->createAudioPatch(
+            hidlSources, hidlSinks,
+            [&](Result r, AudioPatchHandle hidlPatch) {
+                retval = r;
+                if (retval == Result::OK) {
+                    *patch = static_cast<audio_patch_handle_t>(hidlPatch);
+                }
+            });
+    return processReturn("createAudioPatch", ret, retval);
+}
+
+status_t DeviceHalHidl::releaseAudioPatch(audio_patch_handle_t patch) {
+    if (mDevice == 0) return NO_INIT;
+    return processReturn("releaseAudioPatch", mDevice->releaseAudioPatch(patch));
+}
+
+status_t DeviceHalHidl::getAudioPort(struct audio_port *port) {
+    if (mDevice == 0) return NO_INIT;
+    AudioPort hidlPort;
+    HidlUtils::audioPortFromHal(*port, &hidlPort);
+    Result retval;
+    Return<void> ret = mDevice->getAudioPort(
+            hidlPort,
+            [&](Result r, const AudioPort& p) {
+                retval = r;
+                if (retval == Result::OK) {
+                    HidlUtils::audioPortToHal(p, port);
+                }
+            });
+    return processReturn("getAudioPort", ret, retval);
+}
+
+status_t DeviceHalHidl::setAudioPortConfig(const struct audio_port_config *config) {
+    if (mDevice == 0) return NO_INIT;
+    AudioPortConfig hidlConfig;
+    HidlUtils::audioPortConfigFromHal(*config, &hidlConfig);
+    return processReturn("setAudioPortConfig", mDevice->setAudioPortConfig(hidlConfig));
+}
+
+#if MAJOR_VERSION == 2
+status_t DeviceHalHidl::getMicrophones(
+        std::vector<media::MicrophoneInfo> *microphonesInfo __unused) {
+    if (mDevice == 0) return NO_INIT;
+    return INVALID_OPERATION;
+}
+#elif MAJOR_VERSION >= 4
+status_t DeviceHalHidl::getMicrophones(std::vector<media::MicrophoneInfo> *microphonesInfo) {
+    if (mDevice == 0) return NO_INIT;
+    Result retval;
+    Return<void> ret = mDevice->getMicrophones(
+            [&](Result r, hidl_vec<MicrophoneInfo> micArrayHal) {
+        retval = r;
+        for (size_t k = 0; k < micArrayHal.size(); k++) {
+            audio_microphone_characteristic_t dst;
+            //convert
+            microphoneInfoToHal(micArrayHal[k], &dst);
+            media::MicrophoneInfo microphone = media::MicrophoneInfo(dst);
+            microphonesInfo->push_back(microphone);
+        }
+    });
+    return processReturn("getMicrophones", ret, retval);
+}
+#endif
+
+status_t DeviceHalHidl::dump(int fd) {
+    if (mDevice == 0) return NO_INIT;
+    native_handle_t* hidlHandle = native_handle_create(1, 0);
+    hidlHandle->data[0] = fd;
+    Return<void> ret = mDevice->debug(hidlHandle, {} /* options */);
+    native_handle_delete(hidlHandle);
+    return processReturn("dump", ret);
+}
+
+} // namespace CPP_VERSION
+} // namespace android
diff --git a/media/libaudiohal/impl/DeviceHalHidl.h b/media/libaudiohal/impl/DeviceHalHidl.h
new file mode 100644
index 0000000..f7d465f
--- /dev/null
+++ b/media/libaudiohal/impl/DeviceHalHidl.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_DEVICE_HAL_HIDL_H
+#define ANDROID_HARDWARE_DEVICE_HAL_HIDL_H
+
+#include PATH(android/hardware/audio/FILE_VERSION/IDevice.h)
+#include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
+#include <media/audiohal/DeviceHalInterface.h>
+
+#include "ConversionHelperHidl.h"
+
+using ::android::hardware::audio::CPP_VERSION::IDevice;
+using ::android::hardware::audio::CPP_VERSION::IPrimaryDevice;
+using ::android::hardware::Return;
+
+namespace android {
+namespace CPP_VERSION {
+
+class DeviceHalHidl : public DeviceHalInterface, public ConversionHelperHidl
+{
+  public:
+    // Sets the value of 'devices' to a bitmask of 1 or more values of audio_devices_t.
+    virtual status_t getSupportedDevices(uint32_t *devices);
+
+    // Check to see if the audio hardware interface has been initialized.
+    virtual status_t initCheck();
+
+    // Set the audio volume of a voice call. Range is between 0.0 and 1.0.
+    virtual status_t setVoiceVolume(float volume);
+
+    // Set the audio volume for all audio activities other than voice call.
+    virtual status_t setMasterVolume(float volume);
+
+    // Get the current master volume value for the HAL.
+    virtual status_t getMasterVolume(float *volume);
+
+    // Called when the audio mode changes.
+    virtual status_t setMode(audio_mode_t mode);
+
+    // Muting control.
+    virtual status_t setMicMute(bool state);
+    virtual status_t getMicMute(bool *state);
+    virtual status_t setMasterMute(bool state);
+    virtual status_t getMasterMute(bool *state);
+
+    // Set global audio parameters.
+    virtual status_t setParameters(const String8& kvPairs);
+
+    // Get global audio parameters.
+    virtual status_t getParameters(const String8& keys, String8 *values);
+
+    // Returns audio input buffer size according to parameters passed.
+    virtual status_t getInputBufferSize(const struct audio_config *config,
+            size_t *size);
+
+    // Creates and opens the audio hardware output stream. The stream is closed
+    // by releasing all references to the returned object.
+    virtual status_t openOutputStream(
+            audio_io_handle_t handle,
+            audio_devices_t devices,
+            audio_output_flags_t flags,
+            struct audio_config *config,
+            const char *address,
+            sp<StreamOutHalInterface> *outStream);
+
+    // Creates and opens the audio hardware input stream. The stream is closed
+    // by releasing all references to the returned object.
+    virtual status_t openInputStream(
+            audio_io_handle_t handle,
+            audio_devices_t devices,
+            struct audio_config *config,
+            audio_input_flags_t flags,
+            const char *address,
+            audio_source_t source,
+            audio_devices_t outputDevice,
+            const char *outputDeviceAddress,
+            sp<StreamInHalInterface> *inStream);
+
+    // Returns whether createAudioPatch and releaseAudioPatch operations are supported.
+    virtual status_t supportsAudioPatches(bool *supportsPatches);
+
+    // Creates an audio patch between several source and sink ports.
+    virtual status_t createAudioPatch(
+            unsigned int num_sources,
+            const struct audio_port_config *sources,
+            unsigned int num_sinks,
+            const struct audio_port_config *sinks,
+            audio_patch_handle_t *patch);
+
+    // Releases an audio patch.
+    virtual status_t releaseAudioPatch(audio_patch_handle_t patch);
+
+    // Fills the list of supported attributes for a given audio port.
+    virtual status_t getAudioPort(struct audio_port *port);
+
+    // Set audio port configuration.
+    virtual status_t setAudioPortConfig(const struct audio_port_config *config);
+
+    // List microphones
+    virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+
+    virtual status_t dump(int fd);
+
+  private:
+    friend class DevicesFactoryHalHidl;
+    sp<IDevice> mDevice;
+    sp<IPrimaryDevice> mPrimaryDevice;  // Null if it's not a primary device.
+
+    // Can not be constructed directly by clients.
+    explicit DeviceHalHidl(const sp<IDevice>& device);
+
+    // The destructor automatically closes the device.
+    virtual ~DeviceHalHidl();
+};
+
+} // namespace CPP_VERSION
+} // namespace android
+
+#endif // ANDROID_HARDWARE_DEVICE_HAL_HIDL_H
diff --git a/media/libaudiohal/impl/DeviceHalLocal.cpp b/media/libaudiohal/impl/DeviceHalLocal.cpp
new file mode 100644
index 0000000..ee68252
--- /dev/null
+++ b/media/libaudiohal/impl/DeviceHalLocal.cpp
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "DeviceHalLocal"
+//#define LOG_NDEBUG 0
+
+#include <utils/Log.h>
+
+#include "DeviceHalLocal.h"
+#include "StreamHalLocal.h"
+
+namespace android {
+namespace CPP_VERSION {
+
+DeviceHalLocal::DeviceHalLocal(audio_hw_device_t *dev)
+        : mDev(dev) {
+}
+
+DeviceHalLocal::~DeviceHalLocal() {
+    int status = audio_hw_device_close(mDev);
+    ALOGW_IF(status, "Error closing audio hw device %p: %s", mDev, strerror(-status));
+    mDev = 0;
+}
+
+status_t DeviceHalLocal::getSupportedDevices(uint32_t *devices) {
+    if (mDev->get_supported_devices == NULL) return INVALID_OPERATION;
+    *devices = mDev->get_supported_devices(mDev);
+    return OK;
+}
+
+status_t DeviceHalLocal::initCheck() {
+    return mDev->init_check(mDev);
+}
+
+status_t DeviceHalLocal::setVoiceVolume(float volume) {
+    return mDev->set_voice_volume(mDev, volume);
+}
+
+status_t DeviceHalLocal::setMasterVolume(float volume) {
+    if (mDev->set_master_volume == NULL) return INVALID_OPERATION;
+    return mDev->set_master_volume(mDev, volume);
+}
+
+status_t DeviceHalLocal::getMasterVolume(float *volume) {
+    if (mDev->get_master_volume == NULL) return INVALID_OPERATION;
+    return mDev->get_master_volume(mDev, volume);
+}
+
+status_t DeviceHalLocal::setMode(audio_mode_t mode) {
+    return mDev->set_mode(mDev, mode);
+}
+
+status_t DeviceHalLocal::setMicMute(bool state) {
+    return mDev->set_mic_mute(mDev, state);
+}
+
+status_t DeviceHalLocal::getMicMute(bool *state) {
+    return mDev->get_mic_mute(mDev, state);
+}
+
+status_t DeviceHalLocal::setMasterMute(bool state) {
+    if (mDev->set_master_mute == NULL) return INVALID_OPERATION;
+    return mDev->set_master_mute(mDev, state);
+}
+
+status_t DeviceHalLocal::getMasterMute(bool *state) {
+    if (mDev->get_master_mute == NULL) return INVALID_OPERATION;
+    return mDev->get_master_mute(mDev, state);
+}
+
+status_t DeviceHalLocal::setParameters(const String8& kvPairs) {
+    return mDev->set_parameters(mDev, kvPairs.string());
+}
+
+status_t DeviceHalLocal::getParameters(const String8& keys, String8 *values) {
+    char *halValues = mDev->get_parameters(mDev, keys.string());
+    if (halValues != NULL) {
+        values->setTo(halValues);
+        free(halValues);
+    } else {
+        values->clear();
+    }
+    return OK;
+}
+
+status_t DeviceHalLocal::getInputBufferSize(
+        const struct audio_config *config, size_t *size) {
+    *size = mDev->get_input_buffer_size(mDev, config);
+    return OK;
+}
+
+status_t DeviceHalLocal::openOutputStream(
+        audio_io_handle_t handle,
+        audio_devices_t devices,
+        audio_output_flags_t flags,
+        struct audio_config *config,
+        const char *address,
+        sp<StreamOutHalInterface> *outStream) {
+    audio_stream_out_t *halStream;
+    ALOGV("open_output_stream handle: %d devices: %x flags: %#x"
+            "srate: %d format %#x channels %x address %s",
+            handle, devices, flags,
+            config->sample_rate, config->format, config->channel_mask,
+            address);
+    int openResut = mDev->open_output_stream(
+            mDev, handle, devices, flags, config, &halStream, address);
+    if (openResut == OK) {
+        *outStream = new StreamOutHalLocal(halStream, this);
+    }
+    ALOGV("open_output_stream status %d stream %p", openResut, halStream);
+    return openResut;
+}
+
+status_t DeviceHalLocal::openInputStream(
+        audio_io_handle_t handle,
+        audio_devices_t devices,
+        struct audio_config *config,
+        audio_input_flags_t flags,
+        const char *address,
+        audio_source_t source,
+        audio_devices_t /*outputDevice*/,
+        const char */*outputDeviceAddress*/,
+        sp<StreamInHalInterface> *inStream) {
+    audio_stream_in_t *halStream;
+    ALOGV("open_input_stream handle: %d devices: %x flags: %#x "
+            "srate: %d format %#x channels %x address %s source %d",
+            handle, devices, flags,
+            config->sample_rate, config->format, config->channel_mask,
+            address, source);
+    int openResult = mDev->open_input_stream(
+            mDev, handle, devices, config, &halStream, flags, address, source);
+    if (openResult == OK) {
+        *inStream = new StreamInHalLocal(halStream, this);
+    }
+    ALOGV("open_input_stream status %d stream %p", openResult, inStream);
+    return openResult;
+}
+
+status_t DeviceHalLocal::supportsAudioPatches(bool *supportsPatches) {
+    *supportsPatches = version() >= AUDIO_DEVICE_API_VERSION_3_0;
+    return OK;
+}
+
+status_t DeviceHalLocal::createAudioPatch(
+        unsigned int num_sources,
+        const struct audio_port_config *sources,
+        unsigned int num_sinks,
+        const struct audio_port_config *sinks,
+        audio_patch_handle_t *patch) {
+    if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
+        return mDev->create_audio_patch(
+                mDev, num_sources, sources, num_sinks, sinks, patch);
+    } else {
+        return INVALID_OPERATION;
+    }
+}
+
+status_t DeviceHalLocal::releaseAudioPatch(audio_patch_handle_t patch) {
+    if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
+        return mDev->release_audio_patch(mDev, patch);
+    } else {
+        return INVALID_OPERATION;
+    }
+}
+
+status_t DeviceHalLocal::getAudioPort(struct audio_port *port) {
+    return mDev->get_audio_port(mDev, port);
+}
+
+status_t DeviceHalLocal::setAudioPortConfig(const struct audio_port_config *config) {
+    if (version() >= AUDIO_DEVICE_API_VERSION_3_0)
+        return mDev->set_audio_port_config(mDev, config);
+    else
+        return INVALID_OPERATION;
+}
+
+#if MAJOR_VERSION == 2
+status_t DeviceHalLocal::getMicrophones(
+        std::vector<media::MicrophoneInfo> *microphones __unused) {
+    return INVALID_OPERATION;
+}
+#elif MAJOR_VERSION >= 4
+status_t DeviceHalLocal::getMicrophones(std::vector<media::MicrophoneInfo> *microphones) {
+    if (mDev->get_microphones == NULL) return INVALID_OPERATION;
+    size_t actual_mics = AUDIO_MICROPHONE_MAX_COUNT;
+    audio_microphone_characteristic_t mic_array[AUDIO_MICROPHONE_MAX_COUNT];
+    status_t status = mDev->get_microphones(mDev, &mic_array[0], &actual_mics);
+    for (size_t i = 0; i < actual_mics; i++) {
+        media::MicrophoneInfo microphoneInfo = media::MicrophoneInfo(mic_array[i]);
+        microphones->push_back(microphoneInfo);
+    }
+    return status;
+}
+#endif
+
+status_t DeviceHalLocal::dump(int fd) {
+    return mDev->dump(mDev, fd);
+}
+
+void DeviceHalLocal::closeOutputStream(struct audio_stream_out *stream_out) {
+    mDev->close_output_stream(mDev, stream_out);
+}
+
+void DeviceHalLocal::closeInputStream(struct audio_stream_in *stream_in) {
+    mDev->close_input_stream(mDev, stream_in);
+}
+
+} // namespace CPP_VERSION
+} // namespace android
diff --git a/media/libaudiohal/impl/DeviceHalLocal.h b/media/libaudiohal/impl/DeviceHalLocal.h
new file mode 100644
index 0000000..36db72e
--- /dev/null
+++ b/media/libaudiohal/impl/DeviceHalLocal.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_DEVICE_HAL_LOCAL_H
+#define ANDROID_HARDWARE_DEVICE_HAL_LOCAL_H
+
+#include <hardware/audio.h>
+#include <media/audiohal/DeviceHalInterface.h>
+
+namespace android {
+namespace CPP_VERSION {
+
+class DeviceHalLocal : public DeviceHalInterface
+{
+  public:
+    // Sets the value of 'devices' to a bitmask of 1 or more values of audio_devices_t.
+    virtual status_t getSupportedDevices(uint32_t *devices);
+
+    // Check to see if the audio hardware interface has been initialized.
+    virtual status_t initCheck();
+
+    // Set the audio volume of a voice call. Range is between 0.0 and 1.0.
+    virtual status_t setVoiceVolume(float volume);
+
+    // Set the audio volume for all audio activities other than voice call.
+    virtual status_t setMasterVolume(float volume);
+
+    // Get the current master volume value for the HAL.
+    virtual status_t getMasterVolume(float *volume);
+
+    // Called when the audio mode changes.
+    virtual status_t setMode(audio_mode_t mode);
+
+    // Muting control.
+    virtual status_t setMicMute(bool state);
+    virtual status_t getMicMute(bool *state);
+    virtual status_t setMasterMute(bool state);
+    virtual status_t getMasterMute(bool *state);
+
+    // Set global audio parameters.
+    virtual status_t setParameters(const String8& kvPairs);
+
+    // Get global audio parameters.
+    virtual status_t getParameters(const String8& keys, String8 *values);
+
+    // Returns audio input buffer size according to parameters passed.
+    virtual status_t getInputBufferSize(const struct audio_config *config,
+            size_t *size);
+
+    // Creates and opens the audio hardware output stream. The stream is closed
+    // by releasing all references to the returned object.
+    virtual status_t openOutputStream(
+            audio_io_handle_t handle,
+            audio_devices_t devices,
+            audio_output_flags_t flags,
+            struct audio_config *config,
+            const char *address,
+            sp<StreamOutHalInterface> *outStream);
+
+    // Creates and opens the audio hardware input stream. The stream is closed
+    // by releasing all references to the returned object.
+    virtual status_t openInputStream(
+            audio_io_handle_t handle,
+            audio_devices_t devices,
+            struct audio_config *config,
+            audio_input_flags_t flags,
+            const char *address,
+            audio_source_t source,
+            audio_devices_t outputDevice,
+            const char *outputDeviceAddress,
+            sp<StreamInHalInterface> *inStream);
+
+    // Returns whether createAudioPatch and releaseAudioPatch operations are supported.
+    virtual status_t supportsAudioPatches(bool *supportsPatches);
+
+    // Creates an audio patch between several source and sink ports.
+    virtual status_t createAudioPatch(
+            unsigned int num_sources,
+            const struct audio_port_config *sources,
+            unsigned int num_sinks,
+            const struct audio_port_config *sinks,
+            audio_patch_handle_t *patch);
+
+    // Releases an audio patch.
+    virtual status_t releaseAudioPatch(audio_patch_handle_t patch);
+
+    // Fills the list of supported attributes for a given audio port.
+    virtual status_t getAudioPort(struct audio_port *port);
+
+    // Set audio port configuration.
+    virtual status_t setAudioPortConfig(const struct audio_port_config *config);
+
+    // List microphones
+    virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+
+    virtual status_t dump(int fd);
+
+    void closeOutputStream(struct audio_stream_out *stream_out);
+    void closeInputStream(struct audio_stream_in *stream_in);
+
+  private:
+    audio_hw_device_t *mDev;
+
+    friend class DevicesFactoryHalLocal;
+
+    // Can not be constructed directly by clients.
+    explicit DeviceHalLocal(audio_hw_device_t *dev);
+
+    // The destructor automatically closes the device.
+    virtual ~DeviceHalLocal();
+
+    uint32_t version() const { return mDev->common.version; }
+};
+
+} // namespace CPP_VERSION
+} // namespace android
+
+#endif // ANDROID_HARDWARE_DEVICE_HAL_LOCAL_H
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp b/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
new file mode 100644
index 0000000..5e01e42
--- /dev/null
+++ b/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include <vector>
+
+#define LOG_TAG "DevicesFactoryHalHidl"
+//#define LOG_NDEBUG 0
+
+#include PATH(android/hardware/audio/FILE_VERSION/IDevice.h)
+#include <media/audiohal/hidl/HalDeathHandler.h>
+#include <utils/Log.h>
+
+#include "ConversionHelperHidl.h"
+#include "DeviceHalHidl.h"
+#include "DevicesFactoryHalHidl.h"
+
+using ::android::hardware::audio::CPP_VERSION::IDevice;
+using ::android::hardware::audio::CPP_VERSION::Result;
+using ::android::hardware::Return;
+
+namespace android {
+namespace CPP_VERSION {
+
+DevicesFactoryHalHidl::DevicesFactoryHalHidl() {
+    sp<IDevicesFactory> defaultFactory{IDevicesFactory::getService()};
+    if (!defaultFactory) {
+        ALOGE("Failed to obtain IDevicesFactory/default service, terminating process.");
+        exit(1);
+    }
+    mDeviceFactories.push_back(defaultFactory);
+    if (MAJOR_VERSION >= 4) {
+        // The MSD factory is optional and only available starting at HAL 4.0
+        sp<IDevicesFactory> msdFactory{IDevicesFactory::getService(AUDIO_HAL_SERVICE_NAME_MSD)};
+        if (msdFactory) {
+            mDeviceFactories.push_back(msdFactory);
+        }
+    }
+    for (const auto& factory : mDeviceFactories) {
+        // It is assumed that the DevicesFactoryHalInterface instance is owned
+        // by AudioFlinger and thus have the same lifespan.
+        factory->linkToDeath(HalDeathHandler::getInstance(), 0 /*cookie*/);
+    }
+}
+
+
+#if MAJOR_VERSION == 2
+static IDevicesFactory::Device idFromHal(const char *name, status_t* status) {
+    *status = OK;
+    if (strcmp(name, AUDIO_HARDWARE_MODULE_ID_PRIMARY) == 0) {
+        return IDevicesFactory::Device::PRIMARY;
+    } else if(strcmp(name, AUDIO_HARDWARE_MODULE_ID_A2DP) == 0) {
+        return IDevicesFactory::Device::A2DP;
+    } else if(strcmp(name, AUDIO_HARDWARE_MODULE_ID_USB) == 0) {
+        return IDevicesFactory::Device::USB;
+    } else if(strcmp(name, AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX) == 0) {
+        return IDevicesFactory::Device::R_SUBMIX;
+    } else if(strcmp(name, AUDIO_HARDWARE_MODULE_ID_STUB) == 0) {
+        return IDevicesFactory::Device::STUB;
+    }
+    ALOGE("Invalid device name %s", name);
+    *status = BAD_VALUE;
+    return {};
+}
+#elif MAJOR_VERSION >= 4
+static const char* idFromHal(const char *name, status_t* status) {
+    *status = OK;
+    return name;
+}
+#endif
+
+status_t DevicesFactoryHalHidl::openDevice(const char *name, sp<DeviceHalInterface> *device) {
+    if (mDeviceFactories.empty()) return NO_INIT;
+    status_t status;
+    auto hidlId = idFromHal(name, &status);
+    if (status != OK) return status;
+    Result retval = Result::NOT_INITIALIZED;
+    for (const auto& factory : mDeviceFactories) {
+        Return<void> ret = factory->openDevice(
+                hidlId,
+                [&](Result r, const sp<IDevice>& result) {
+                    retval = r;
+                    if (retval == Result::OK) {
+                        *device = new DeviceHalHidl(result);
+                    }
+                });
+        if (!ret.isOk()) return FAILED_TRANSACTION;
+        switch (retval) {
+            // Device was found and was initialized successfully.
+            case Result::OK: return OK;
+            // Device was found but failed to initalize.
+            case Result::NOT_INITIALIZED: return NO_INIT;
+            // Otherwise continue iterating.
+            default: ;
+        }
+    }
+    ALOGW("The specified device name is not recognized: \"%s\"", name);
+    return BAD_VALUE;
+}
+
+} // namespace CPP_VERSION
+} // namespace android
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHidl.h b/media/libaudiohal/impl/DevicesFactoryHalHidl.h
new file mode 100644
index 0000000..27e0649
--- /dev/null
+++ b/media/libaudiohal/impl/DevicesFactoryHalHidl.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_DEVICES_FACTORY_HAL_HIDL_H
+#define ANDROID_HARDWARE_DEVICES_FACTORY_HAL_HIDL_H
+
+#include PATH(android/hardware/audio/FILE_VERSION/IDevicesFactory.h)
+#include <media/audiohal/DevicesFactoryHalInterface.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+#include "DeviceHalHidl.h"
+
+using ::android::hardware::audio::CPP_VERSION::IDevicesFactory;
+
+namespace android {
+namespace CPP_VERSION {
+
+class DevicesFactoryHalHidl : public DevicesFactoryHalInterface
+{
+  public:
+    // Opens a device with the specified name. To close the device, it is
+    // necessary to release references to the returned object.
+    virtual status_t openDevice(const char *name, sp<DeviceHalInterface> *device);
+
+  private:
+    friend class DevicesFactoryHalHybrid;
+
+    std::vector<sp<IDevicesFactory>> mDeviceFactories;
+
+    // Can not be constructed directly by clients.
+    DevicesFactoryHalHidl();
+
+    virtual ~DevicesFactoryHalHidl() = default;
+};
+
+} // namespace CPP_VERSION
+} // namespace android
+
+#endif // ANDROID_HARDWARE_DEVICES_FACTORY_HAL_HIDL_H
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp b/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp
new file mode 100644
index 0000000..f337a8b
--- /dev/null
+++ b/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "DevicesFactoryHalHybrid"
+//#define LOG_NDEBUG 0
+
+#include "DevicesFactoryHalHybrid.h"
+#include "DevicesFactoryHalLocal.h"
+#include "DevicesFactoryHalHidl.h"
+
+namespace android {
+namespace CPP_VERSION {
+
+DevicesFactoryHalHybrid::DevicesFactoryHalHybrid()
+        : mLocalFactory(new DevicesFactoryHalLocal()),
+          mHidlFactory(new DevicesFactoryHalHidl()) {
+}
+
+status_t DevicesFactoryHalHybrid::openDevice(const char *name, sp<DeviceHalInterface> *device) {
+    if (mHidlFactory != 0 && strcmp(AUDIO_HARDWARE_MODULE_ID_A2DP, name) != 0 &&
+        strcmp(AUDIO_HARDWARE_MODULE_ID_HEARING_AID, name) != 0) {
+        return mHidlFactory->openDevice(name, device);
+    }
+    return mLocalFactory->openDevice(name, device);
+}
+
+} // namespace CPP_VERSION
+} // namespace android
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHybrid.h b/media/libaudiohal/impl/DevicesFactoryHalHybrid.h
new file mode 100644
index 0000000..5ac0d0d
--- /dev/null
+++ b/media/libaudiohal/impl/DevicesFactoryHalHybrid.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_DEVICES_FACTORY_HAL_HYBRID_H
+#define ANDROID_HARDWARE_DEVICES_FACTORY_HAL_HYBRID_H
+
+#include <media/audiohal/DevicesFactoryHalInterface.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+namespace android {
+namespace CPP_VERSION {
+
+class DevicesFactoryHalHybrid : public DevicesFactoryHalInterface
+{
+  public:
+    DevicesFactoryHalHybrid();
+
+    // Opens a device with the specified name. To close the device, it is
+    // necessary to release references to the returned object.
+    virtual status_t openDevice(const char *name, sp<DeviceHalInterface> *device);
+
+  private:
+    sp<DevicesFactoryHalInterface> mLocalFactory;
+    sp<DevicesFactoryHalInterface> mHidlFactory;
+};
+
+sp<DevicesFactoryHalInterface> createDevicesFactoryHal() {
+    return new DevicesFactoryHalHybrid();
+}
+
+} // namespace CPP_VERSION
+} // namespace android
+
+#endif // ANDROID_HARDWARE_DEVICES_FACTORY_HAL_HYBRID_H
diff --git a/media/libaudiohal/impl/DevicesFactoryHalLocal.cpp b/media/libaudiohal/impl/DevicesFactoryHalLocal.cpp
new file mode 100644
index 0000000..af67ff5
--- /dev/null
+++ b/media/libaudiohal/impl/DevicesFactoryHalLocal.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "DevicesFactoryHalLocal"
+//#define LOG_NDEBUG 0
+
+#include <string.h>
+
+#include <hardware/audio.h>
+#include <utils/Log.h>
+
+#include "DeviceHalLocal.h"
+#include "DevicesFactoryHalLocal.h"
+
+namespace android {
+namespace CPP_VERSION {
+
+static status_t load_audio_interface(const char *if_name, audio_hw_device_t **dev)
+{
+    const hw_module_t *mod;
+    int rc;
+
+    rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
+    if (rc) {
+        ALOGE("%s couldn't load audio hw module %s.%s (%s)", __func__,
+                AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
+        goto out;
+    }
+    rc = audio_hw_device_open(mod, dev);
+    if (rc) {
+        ALOGE("%s couldn't open audio hw device in %s.%s (%s)", __func__,
+                AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
+        goto out;
+    }
+    if ((*dev)->common.version < AUDIO_DEVICE_API_VERSION_MIN) {
+        ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version);
+        rc = BAD_VALUE;
+        audio_hw_device_close(*dev);
+        goto out;
+    }
+    return OK;
+
+out:
+    *dev = NULL;
+    return rc;
+}
+
+status_t DevicesFactoryHalLocal::openDevice(const char *name, sp<DeviceHalInterface> *device) {
+    audio_hw_device_t *dev;
+    status_t rc = load_audio_interface(name, &dev);
+    if (rc == OK) {
+        *device = new DeviceHalLocal(dev);
+    }
+    return rc;
+}
+
+} // namespace CPP_VERSION
+} // namespace android
diff --git a/media/libaudiohal/impl/DevicesFactoryHalLocal.h b/media/libaudiohal/impl/DevicesFactoryHalLocal.h
new file mode 100644
index 0000000..5d108dd
--- /dev/null
+++ b/media/libaudiohal/impl/DevicesFactoryHalLocal.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_DEVICES_FACTORY_HAL_LOCAL_H
+#define ANDROID_HARDWARE_DEVICES_FACTORY_HAL_LOCAL_H
+
+#include <media/audiohal/DevicesFactoryHalInterface.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+#include "DeviceHalLocal.h"
+
+namespace android {
+namespace CPP_VERSION {
+
+class DevicesFactoryHalLocal : public DevicesFactoryHalInterface
+{
+  public:
+    // Opens a device with the specified name. To close the device, it is
+    // necessary to release references to the returned object.
+    virtual status_t openDevice(const char *name, sp<DeviceHalInterface> *device);
+
+  private:
+    friend class DevicesFactoryHalHybrid;
+
+    // Can not be constructed directly by clients.
+    DevicesFactoryHalLocal() {}
+
+    virtual ~DevicesFactoryHalLocal() {}
+};
+
+} // namespace CPP_VERSION
+} // namespace android
+
+#endif // ANDROID_HARDWARE_DEVICES_FACTORY_HAL_LOCAL_H
diff --git a/media/libaudiohal/impl/EffectBufferHalHidl.cpp b/media/libaudiohal/impl/EffectBufferHalHidl.cpp
new file mode 100644
index 0000000..5367972
--- /dev/null
+++ b/media/libaudiohal/impl/EffectBufferHalHidl.cpp
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <atomic>
+
+#define LOG_TAG "EffectBufferHalHidl"
+//#define LOG_NDEBUG 0
+
+#include <android/hidl/allocator/1.0/IAllocator.h>
+#include <hidlmemory/mapping.h>
+#include <utils/Log.h>
+
+#include "ConversionHelperHidl.h"
+#include "EffectBufferHalHidl.h"
+
+using ::android::hardware::Return;
+using ::android::hidl::allocator::V1_0::IAllocator;
+
+namespace android {
+namespace effect {
+namespace CPP_VERSION {
+
+// static
+uint64_t EffectBufferHalHidl::makeUniqueId() {
+    static std::atomic<uint64_t> counter{1};
+    return counter++;
+}
+
+status_t EffectBufferHalHidl::allocate(
+        size_t size, sp<EffectBufferHalInterface>* buffer) {
+    return mirror(nullptr, size, buffer);
+}
+
+status_t EffectBufferHalHidl::mirror(
+        void* external, size_t size, sp<EffectBufferHalInterface>* buffer) {
+    sp<EffectBufferHalInterface> tempBuffer = new EffectBufferHalHidl(size);
+    status_t result = static_cast<EffectBufferHalHidl*>(tempBuffer.get())->init();
+    if (result == OK) {
+        tempBuffer->setExternalData(external);
+        *buffer = tempBuffer;
+    }
+    return result;
+}
+
+EffectBufferHalHidl::EffectBufferHalHidl(size_t size)
+        : mBufferSize(size), mFrameCountChanged(false),
+          mExternalData(nullptr), mAudioBuffer{0, {nullptr}} {
+    mHidlBuffer.id = makeUniqueId();
+    mHidlBuffer.frameCount = 0;
+}
+
+EffectBufferHalHidl::~EffectBufferHalHidl() {
+}
+
+status_t EffectBufferHalHidl::init() {
+    sp<IAllocator> ashmem = IAllocator::getService("ashmem");
+    if (ashmem == 0) {
+        ALOGE("Failed to retrieve ashmem allocator service");
+        return NO_INIT;
+    }
+    status_t retval = NO_MEMORY;
+    Return<void> result = ashmem->allocate(
+            mBufferSize,
+            [&](bool success, const hidl_memory& memory) {
+                if (success) {
+                    mHidlBuffer.data = memory;
+                    retval = OK;
+                }
+            });
+    if (result.isOk() && retval == OK) {
+        mMemory = hardware::mapMemory(mHidlBuffer.data);
+        if (mMemory != 0) {
+            mMemory->update();
+            mAudioBuffer.raw = static_cast<void*>(mMemory->getPointer());
+            memset(mAudioBuffer.raw, 0, mMemory->getSize());
+            mMemory->commit();
+        } else {
+            ALOGE("Failed to map allocated ashmem");
+            retval = NO_MEMORY;
+        }
+    } else {
+        ALOGE("Failed to allocate %d bytes from ashmem", (int)mBufferSize);
+    }
+    return result.isOk() ? retval : FAILED_TRANSACTION;
+}
+
+audio_buffer_t* EffectBufferHalHidl::audioBuffer() {
+    return &mAudioBuffer;
+}
+
+void* EffectBufferHalHidl::externalData() const {
+    return mExternalData;
+}
+
+void EffectBufferHalHidl::setFrameCount(size_t frameCount) {
+    mHidlBuffer.frameCount = frameCount;
+    mAudioBuffer.frameCount = frameCount;
+    mFrameCountChanged = true;
+}
+
+bool EffectBufferHalHidl::checkFrameCountChange() {
+    bool result = mFrameCountChanged;
+    mFrameCountChanged = false;
+    return result;
+}
+
+void EffectBufferHalHidl::setExternalData(void* external) {
+    mExternalData = external;
+}
+
+void EffectBufferHalHidl::update() {
+    update(mBufferSize);
+}
+
+void EffectBufferHalHidl::commit() {
+    commit(mBufferSize);
+}
+
+void EffectBufferHalHidl::update(size_t size) {
+    if (mExternalData == nullptr) return;
+    mMemory->update();
+    if (size > mBufferSize) size = mBufferSize;
+    memcpy(mAudioBuffer.raw, mExternalData, size);
+    mMemory->commit();
+}
+
+void EffectBufferHalHidl::commit(size_t size) {
+    if (mExternalData == nullptr) return;
+    if (size > mBufferSize) size = mBufferSize;
+    memcpy(mExternalData, mAudioBuffer.raw, size);
+}
+
+} // namespace effect
+} // namespace CPP_VERSION
+} // namespace android
diff --git a/media/libaudiohal/impl/EffectBufferHalHidl.h b/media/libaudiohal/impl/EffectBufferHalHidl.h
new file mode 100644
index 0000000..4826813
--- /dev/null
+++ b/media/libaudiohal/impl/EffectBufferHalHidl.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_EFFECT_BUFFER_HAL_HIDL_H
+#define ANDROID_HARDWARE_EFFECT_BUFFER_HAL_HIDL_H
+
+#include PATH(android/hardware/audio/effect/FILE_VERSION/types.h)
+#include <android/hidl/memory/1.0/IMemory.h>
+#include <hidl/HidlSupport.h>
+#include <media/audiohal/EffectBufferHalInterface.h>
+#include <system/audio_effect.h>
+
+using android::hardware::hidl_memory;
+using android::hidl::memory::V1_0::IMemory;
+
+namespace android {
+namespace effect {
+namespace CPP_VERSION {
+
+using namespace ::android::hardware::audio::effect::CPP_VERSION;
+
+class EffectBufferHalHidl : public EffectBufferHalInterface
+{
+  public:
+    static status_t allocate(size_t size, sp<EffectBufferHalInterface>* buffer);
+    static status_t mirror(void* external, size_t size, sp<EffectBufferHalInterface>* buffer);
+
+    virtual audio_buffer_t* audioBuffer();
+    virtual void* externalData() const;
+
+    virtual size_t getSize() const override { return mBufferSize; }
+
+    virtual void setExternalData(void* external);
+    virtual void setFrameCount(size_t frameCount);
+    virtual bool checkFrameCountChange();
+
+    virtual void update();
+    virtual void commit();
+    virtual void update(size_t size);
+    virtual void commit(size_t size);
+
+    const AudioBuffer& hidlBuffer() const { return mHidlBuffer; }
+
+  private:
+    friend class EffectBufferHalInterface;
+
+    static uint64_t makeUniqueId();
+
+    const size_t mBufferSize;
+    bool mFrameCountChanged;
+    void* mExternalData;
+    AudioBuffer mHidlBuffer;
+    sp<IMemory> mMemory;
+    audio_buffer_t mAudioBuffer;
+
+    // Can not be constructed directly by clients.
+    explicit EffectBufferHalHidl(size_t size);
+
+    virtual ~EffectBufferHalHidl();
+
+    status_t init();
+};
+
+} // namespace CPP_VERSION
+} // namespace effect
+} // namespace android
+
+#endif // ANDROID_HARDWARE_EFFECT_BUFFER_HAL_HIDL_H
diff --git a/media/libaudiohal/impl/EffectHalHidl.cpp b/media/libaudiohal/impl/EffectHalHidl.cpp
new file mode 100644
index 0000000..caf575c
--- /dev/null
+++ b/media/libaudiohal/impl/EffectHalHidl.cpp
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "EffectHalHidl"
+//#define LOG_NDEBUG 0
+
+#include <common/all-versions/VersionUtils.h>
+#include <cutils/native_handle.h>
+#include <hwbinder/IPCThreadState.h>
+#include <media/EffectsFactoryApi.h>
+#include <utils/Log.h>
+
+#include "EffectBufferHalHidl.h"
+#include "EffectHalHidl.h"
+#include "HidlUtils.h"
+
+using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::common::utils::EnumBitfield;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::MQDescriptorSync;
+using ::android::hardware::Return;
+
+namespace android {
+namespace effect {
+namespace CPP_VERSION {
+
+using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::effect::CPP_VERSION;
+
+EffectHalHidl::EffectHalHidl(const sp<IEffect>& effect, uint64_t effectId)
+        : mEffect(effect), mEffectId(effectId), mBuffersChanged(true), mEfGroup(nullptr) {
+}
+
+EffectHalHidl::~EffectHalHidl() {
+    if (mEffect != 0) {
+        close();
+        mEffect.clear();
+        hardware::IPCThreadState::self()->flushCommands();
+    }
+    if (mEfGroup) {
+        EventFlag::deleteEventFlag(&mEfGroup);
+    }
+}
+
+// static
+void EffectHalHidl::effectDescriptorToHal(
+        const EffectDescriptor& descriptor, effect_descriptor_t* halDescriptor) {
+    HidlUtils::uuidToHal(descriptor.type, &halDescriptor->type);
+    HidlUtils::uuidToHal(descriptor.uuid, &halDescriptor->uuid);
+    halDescriptor->flags = static_cast<uint32_t>(descriptor.flags);
+    halDescriptor->cpuLoad = descriptor.cpuLoad;
+    halDescriptor->memoryUsage = descriptor.memoryUsage;
+    memcpy(halDescriptor->name, descriptor.name.data(), descriptor.name.size());
+    memcpy(halDescriptor->implementor,
+            descriptor.implementor.data(), descriptor.implementor.size());
+}
+
+// TODO(mnaganov): These buffer conversion functions should be shared with Effect wrapper
+// via HidlUtils. Move them there when hardware/interfaces will get un-frozen again.
+
+// static
+void EffectHalHidl::effectBufferConfigFromHal(
+        const buffer_config_t& halConfig, EffectBufferConfig* config) {
+    config->samplingRateHz = halConfig.samplingRate;
+    config->channels = EnumBitfield<AudioChannelMask>(halConfig.channels);
+    config->format = AudioFormat(halConfig.format);
+    config->accessMode = EffectBufferAccess(halConfig.accessMode);
+    config->mask = EnumBitfield<EffectConfigParameters>(halConfig.mask);
+}
+
+// static
+void EffectHalHidl::effectBufferConfigToHal(
+        const EffectBufferConfig& config, buffer_config_t* halConfig) {
+    halConfig->buffer.frameCount = 0;
+    halConfig->buffer.raw = NULL;
+    halConfig->samplingRate = config.samplingRateHz;
+    halConfig->channels = static_cast<uint32_t>(config.channels);
+    halConfig->bufferProvider.cookie = NULL;
+    halConfig->bufferProvider.getBuffer = NULL;
+    halConfig->bufferProvider.releaseBuffer = NULL;
+    halConfig->format = static_cast<uint8_t>(config.format);
+    halConfig->accessMode = static_cast<uint8_t>(config.accessMode);
+    halConfig->mask = static_cast<uint8_t>(config.mask);
+}
+
+// static
+void EffectHalHidl::effectConfigFromHal(const effect_config_t& halConfig, EffectConfig* config) {
+    effectBufferConfigFromHal(halConfig.inputCfg, &config->inputCfg);
+    effectBufferConfigFromHal(halConfig.outputCfg, &config->outputCfg);
+}
+
+// static
+void EffectHalHidl::effectConfigToHal(const EffectConfig& config, effect_config_t* halConfig) {
+    effectBufferConfigToHal(config.inputCfg, &halConfig->inputCfg);
+    effectBufferConfigToHal(config.outputCfg, &halConfig->outputCfg);
+}
+
+// static
+status_t EffectHalHidl::analyzeResult(const Result& result) {
+    switch (result) {
+        case Result::OK: return OK;
+        case Result::INVALID_ARGUMENTS: return BAD_VALUE;
+        case Result::INVALID_STATE: return NOT_ENOUGH_DATA;
+        case Result::NOT_INITIALIZED: return NO_INIT;
+        case Result::NOT_SUPPORTED: return INVALID_OPERATION;
+        case Result::RESULT_TOO_BIG: return NO_MEMORY;
+        default: return NO_INIT;
+    }
+}
+
+status_t EffectHalHidl::setInBuffer(const sp<EffectBufferHalInterface>& buffer) {
+    if (!mBuffersChanged) {
+        if (buffer.get() == nullptr || mInBuffer.get() == nullptr) {
+            mBuffersChanged = buffer.get() != mInBuffer.get();
+        } else {
+            mBuffersChanged = buffer->audioBuffer() != mInBuffer->audioBuffer();
+        }
+    }
+    mInBuffer = buffer;
+    return OK;
+}
+
+status_t EffectHalHidl::setOutBuffer(const sp<EffectBufferHalInterface>& buffer) {
+    if (!mBuffersChanged) {
+        if (buffer.get() == nullptr || mOutBuffer.get() == nullptr) {
+            mBuffersChanged = buffer.get() != mOutBuffer.get();
+        } else {
+            mBuffersChanged = buffer->audioBuffer() != mOutBuffer->audioBuffer();
+        }
+    }
+    mOutBuffer = buffer;
+    return OK;
+}
+
+status_t EffectHalHidl::process() {
+    return processImpl(static_cast<uint32_t>(MessageQueueFlagBits::REQUEST_PROCESS));
+}
+
+status_t EffectHalHidl::processReverse() {
+    return processImpl(static_cast<uint32_t>(MessageQueueFlagBits::REQUEST_PROCESS_REVERSE));
+}
+
+status_t EffectHalHidl::prepareForProcessing() {
+    std::unique_ptr<StatusMQ> tempStatusMQ;
+    Result retval;
+    Return<void> ret = mEffect->prepareForProcessing(
+            [&](Result r, const MQDescriptorSync<Result>& statusMQ) {
+                retval = r;
+                if (retval == Result::OK) {
+                    tempStatusMQ.reset(new StatusMQ(statusMQ));
+                    if (tempStatusMQ->isValid() && tempStatusMQ->getEventFlagWord()) {
+                        EventFlag::createEventFlag(tempStatusMQ->getEventFlagWord(), &mEfGroup);
+                    }
+                }
+            });
+    if (!ret.isOk() || retval != Result::OK) {
+        return ret.isOk() ? analyzeResult(retval) : FAILED_TRANSACTION;
+    }
+    if (!tempStatusMQ || !tempStatusMQ->isValid() || !mEfGroup) {
+        ALOGE_IF(!tempStatusMQ, "Failed to obtain status message queue for effects");
+        ALOGE_IF(tempStatusMQ && !tempStatusMQ->isValid(),
+                "Status message queue for effects is invalid");
+        ALOGE_IF(!mEfGroup, "Event flag creation for effects failed");
+        return NO_INIT;
+    }
+    mStatusMQ = std::move(tempStatusMQ);
+    return OK;
+}
+
+bool EffectHalHidl::needToResetBuffers() {
+    if (mBuffersChanged) return true;
+    bool inBufferFrameCountUpdated = mInBuffer->checkFrameCountChange();
+    bool outBufferFrameCountUpdated = mOutBuffer->checkFrameCountChange();
+    return inBufferFrameCountUpdated || outBufferFrameCountUpdated;
+}
+
+status_t EffectHalHidl::processImpl(uint32_t mqFlag) {
+    if (mEffect == 0 || mInBuffer == 0 || mOutBuffer == 0) return NO_INIT;
+    status_t status;
+    if (!mStatusMQ && (status = prepareForProcessing()) != OK) {
+        return status;
+    }
+    if (needToResetBuffers() && (status = setProcessBuffers()) != OK) {
+        return status;
+    }
+    // The data is already in the buffers, just need to flush it and wake up the server side.
+    std::atomic_thread_fence(std::memory_order_release);
+    mEfGroup->wake(mqFlag);
+    uint32_t efState = 0;
+retry:
+    status_t ret = mEfGroup->wait(
+            static_cast<uint32_t>(MessageQueueFlagBits::DONE_PROCESSING), &efState);
+    if (efState & static_cast<uint32_t>(MessageQueueFlagBits::DONE_PROCESSING)) {
+        Result retval = Result::NOT_INITIALIZED;
+        mStatusMQ->read(&retval);
+        if (retval == Result::OK || retval == Result::INVALID_STATE) {
+            // Sync back the changed contents of the buffer.
+            std::atomic_thread_fence(std::memory_order_acquire);
+        }
+        return analyzeResult(retval);
+    }
+    if (ret == -EAGAIN || ret == -EINTR) {
+        // Spurious wakeup. This normally retries no more than once.
+        goto retry;
+    }
+    return ret;
+}
+
+status_t EffectHalHidl::setProcessBuffers() {
+    Return<Result> ret = mEffect->setProcessBuffers(
+            static_cast<EffectBufferHalHidl*>(mInBuffer.get())->hidlBuffer(),
+            static_cast<EffectBufferHalHidl*>(mOutBuffer.get())->hidlBuffer());
+    if (ret.isOk() && ret == Result::OK) {
+        mBuffersChanged = false;
+        return OK;
+    }
+    return ret.isOk() ? analyzeResult(ret) : FAILED_TRANSACTION;
+}
+
+status_t EffectHalHidl::command(uint32_t cmdCode, uint32_t cmdSize, void *pCmdData,
+        uint32_t *replySize, void *pReplyData) {
+    if (mEffect == 0) return NO_INIT;
+
+    // Special cases.
+    if (cmdCode == EFFECT_CMD_SET_CONFIG || cmdCode == EFFECT_CMD_SET_CONFIG_REVERSE) {
+        return setConfigImpl(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
+    } else if (cmdCode == EFFECT_CMD_GET_CONFIG || cmdCode == EFFECT_CMD_GET_CONFIG_REVERSE) {
+        return getConfigImpl(cmdCode, replySize, pReplyData);
+    }
+
+    // Common case.
+    hidl_vec<uint8_t> hidlData;
+    if (pCmdData != nullptr && cmdSize > 0) {
+        hidlData.setToExternal(reinterpret_cast<uint8_t*>(pCmdData), cmdSize);
+    }
+    status_t status;
+    uint32_t replySizeStub = 0;
+    if (replySize == nullptr || pReplyData == nullptr) replySize = &replySizeStub;
+    Return<void> ret = mEffect->command(cmdCode, hidlData, *replySize,
+            [&](int32_t s, const hidl_vec<uint8_t>& result) {
+                status = s;
+                if (status == 0) {
+                    if (*replySize > result.size()) *replySize = result.size();
+                    if (pReplyData != nullptr && *replySize > 0) {
+                        memcpy(pReplyData, &result[0], *replySize);
+                    }
+                }
+            });
+    return ret.isOk() ? status : FAILED_TRANSACTION;
+}
+
+status_t EffectHalHidl::getDescriptor(effect_descriptor_t *pDescriptor) {
+    if (mEffect == 0) return NO_INIT;
+    Result retval = Result::NOT_INITIALIZED;
+    Return<void> ret = mEffect->getDescriptor(
+            [&](Result r, const EffectDescriptor& result) {
+                retval = r;
+                if (retval == Result::OK) {
+                    effectDescriptorToHal(result, pDescriptor);
+                }
+            });
+    return ret.isOk() ? analyzeResult(retval) : FAILED_TRANSACTION;
+}
+
+status_t EffectHalHidl::close() {
+    if (mEffect == 0) return NO_INIT;
+    Return<Result> ret = mEffect->close();
+    return ret.isOk() ? analyzeResult(ret) : FAILED_TRANSACTION;
+}
+
+status_t EffectHalHidl::dump(int fd) {
+    if (mEffect == 0) return NO_INIT;
+    native_handle_t* hidlHandle = native_handle_create(1, 0);
+    hidlHandle->data[0] = fd;
+    Return<void> ret = mEffect->debug(hidlHandle, {} /* options */);
+    native_handle_delete(hidlHandle);
+    return ret.isOk() ? OK : FAILED_TRANSACTION;
+}
+
+status_t EffectHalHidl::getConfigImpl(
+        uint32_t cmdCode, uint32_t *replySize, void *pReplyData) {
+    if (replySize == NULL || *replySize != sizeof(effect_config_t) || pReplyData == NULL) {
+        return BAD_VALUE;
+    }
+    status_t result = FAILED_TRANSACTION;
+    Return<void> ret;
+    if (cmdCode == EFFECT_CMD_GET_CONFIG) {
+        ret = mEffect->getConfig([&] (Result r, const EffectConfig &hidlConfig) {
+            result = analyzeResult(r);
+            if (r == Result::OK) {
+                effectConfigToHal(hidlConfig, static_cast<effect_config_t*>(pReplyData));
+            }
+        });
+    } else {
+        ret = mEffect->getConfigReverse([&] (Result r, const EffectConfig &hidlConfig) {
+            result = analyzeResult(r);
+            if (r == Result::OK) {
+                effectConfigToHal(hidlConfig, static_cast<effect_config_t*>(pReplyData));
+            }
+        });
+    }
+    if (!ret.isOk()) {
+        result = FAILED_TRANSACTION;
+    }
+    return result;
+}
+
+status_t EffectHalHidl::setConfigImpl(
+        uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, uint32_t *replySize, void *pReplyData) {
+    if (pCmdData == NULL || cmdSize != sizeof(effect_config_t) ||
+            replySize == NULL || *replySize != sizeof(int32_t) || pReplyData == NULL) {
+        return BAD_VALUE;
+    }
+    const effect_config_t *halConfig = static_cast<effect_config_t*>(pCmdData);
+    if (halConfig->inputCfg.bufferProvider.getBuffer != NULL ||
+            halConfig->inputCfg.bufferProvider.releaseBuffer != NULL ||
+            halConfig->outputCfg.bufferProvider.getBuffer != NULL ||
+            halConfig->outputCfg.bufferProvider.releaseBuffer != NULL) {
+        ALOGE("Buffer provider callbacks are not supported");
+    }
+    EffectConfig hidlConfig;
+    effectConfigFromHal(*halConfig, &hidlConfig);
+    Return<Result> ret = cmdCode == EFFECT_CMD_SET_CONFIG ?
+            mEffect->setConfig(hidlConfig, nullptr, nullptr) :
+            mEffect->setConfigReverse(hidlConfig, nullptr, nullptr);
+    status_t result = FAILED_TRANSACTION;
+    if (ret.isOk()) {
+        result = analyzeResult(ret);
+        *static_cast<int32_t*>(pReplyData) = result;
+    }
+    return result;
+}
+
+} // namespace CPP_VERSION
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/EffectHalHidl.h b/media/libaudiohal/impl/EffectHalHidl.h
new file mode 100644
index 0000000..1f238c0
--- /dev/null
+++ b/media/libaudiohal/impl/EffectHalHidl.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_EFFECT_HAL_HIDL_H
+#define ANDROID_HARDWARE_EFFECT_HAL_HIDL_H
+
+#include PATH(android/hardware/audio/effect/FILE_VERSION/IEffect.h)
+#include <media/audiohal/EffectHalInterface.h>
+#include <fmq/EventFlag.h>
+#include <fmq/MessageQueue.h>
+#include <system/audio_effect.h>
+
+using ::android::hardware::EventFlag;
+using ::android::hardware::MessageQueue;
+
+namespace android {
+namespace effect {
+namespace CPP_VERSION {
+
+using namespace ::android::hardware::audio::effect::CPP_VERSION;
+
+class EffectHalHidl : public EffectHalInterface
+{
+  public:
+    // Set the input buffer.
+    virtual status_t setInBuffer(const sp<EffectBufferHalInterface>& buffer);
+
+    // Set the output buffer.
+    virtual status_t setOutBuffer(const sp<EffectBufferHalInterface>& buffer);
+
+    // Effect process function.
+    virtual status_t process();
+
+    // Process reverse stream function. This function is used to pass
+    // a reference stream to the effect engine.
+    virtual status_t processReverse();
+
+    // Send a command and receive a response to/from effect engine.
+    virtual status_t command(uint32_t cmdCode, uint32_t cmdSize, void *pCmdData,
+            uint32_t *replySize, void *pReplyData);
+
+    // Returns the effect descriptor.
+    virtual status_t getDescriptor(effect_descriptor_t *pDescriptor);
+
+    // Free resources on the remote side.
+    virtual status_t close();
+
+    // Whether it's a local implementation.
+    virtual bool isLocal() const { return false; }
+
+    virtual status_t dump(int fd);
+
+    uint64_t effectId() const { return mEffectId; }
+
+    static void effectDescriptorToHal(
+            const EffectDescriptor& descriptor, effect_descriptor_t* halDescriptor);
+
+  private:
+    friend class EffectsFactoryHalHidl;
+    typedef MessageQueue<Result, hardware::kSynchronizedReadWrite> StatusMQ;
+
+    sp<IEffect> mEffect;
+    const uint64_t mEffectId;
+    sp<EffectBufferHalInterface> mInBuffer;
+    sp<EffectBufferHalInterface> mOutBuffer;
+    bool mBuffersChanged;
+    std::unique_ptr<StatusMQ> mStatusMQ;
+    EventFlag* mEfGroup;
+
+    static status_t analyzeResult(const Result& result);
+    static void effectBufferConfigFromHal(
+            const buffer_config_t& halConfig, EffectBufferConfig* config);
+    static void effectBufferConfigToHal(
+            const EffectBufferConfig& config, buffer_config_t* halConfig);
+    static void effectConfigFromHal(const effect_config_t& halConfig, EffectConfig* config);
+    static void effectConfigToHal(const EffectConfig& config, effect_config_t* halConfig);
+
+    // Can not be constructed directly by clients.
+    EffectHalHidl(const sp<IEffect>& effect, uint64_t effectId);
+
+    // The destructor automatically releases the effect.
+    virtual ~EffectHalHidl();
+
+    status_t getConfigImpl(uint32_t cmdCode, uint32_t *replySize, void *pReplyData);
+    status_t prepareForProcessing();
+    bool needToResetBuffers();
+    status_t processImpl(uint32_t mqFlag);
+    status_t setConfigImpl(
+            uint32_t cmdCode, uint32_t cmdSize, void *pCmdData,
+            uint32_t *replySize, void *pReplyData);
+    status_t setProcessBuffers();
+};
+
+} // namespace CPP_VERSION
+} // namespace effect
+} // namespace android
+
+#endif // ANDROID_HARDWARE_EFFECT_HAL_HIDL_H
diff --git a/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
new file mode 100644
index 0000000..7fd6bde
--- /dev/null
+++ b/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "EffectsFactoryHalHidl"
+//#define LOG_NDEBUG 0
+
+#include <cutils/native_handle.h>
+
+#include "EffectsFactoryHalHidl.h"
+#include "ConversionHelperHidl.h"
+#include "EffectBufferHalHidl.h"
+#include "EffectHalHidl.h"
+#include "HidlUtils.h"
+
+using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::Return;
+
+namespace android {
+namespace effect {
+namespace CPP_VERSION {
+
+using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::effect::CPP_VERSION;
+
+EffectsFactoryHalHidl::EffectsFactoryHalHidl() : ConversionHelperHidl("EffectsFactory") {
+    mEffectsFactory = IEffectsFactory::getService();
+    if (mEffectsFactory == 0) {
+        ALOGE("Failed to obtain IEffectsFactory service, terminating process.");
+        exit(1);
+    }
+}
+
+status_t EffectsFactoryHalHidl::queryAllDescriptors() {
+    if (mEffectsFactory == 0) return NO_INIT;
+    Result retval = Result::NOT_INITIALIZED;
+    Return<void> ret = mEffectsFactory->getAllDescriptors(
+            [&](Result r, const hidl_vec<EffectDescriptor>& result) {
+                retval = r;
+                if (retval == Result::OK) {
+                    mLastDescriptors = result;
+                }
+            });
+    if (ret.isOk()) {
+        return retval == Result::OK ? OK : NO_INIT;
+    }
+    mLastDescriptors.resize(0);
+    return processReturn(__FUNCTION__, ret);
+}
+
+status_t EffectsFactoryHalHidl::queryNumberEffects(uint32_t *pNumEffects) {
+    status_t queryResult = queryAllDescriptors();
+    if (queryResult == OK) {
+        *pNumEffects = mLastDescriptors.size();
+    }
+    return queryResult;
+}
+
+status_t EffectsFactoryHalHidl::getDescriptor(
+        uint32_t index, effect_descriptor_t *pDescriptor) {
+    // TODO: We need somehow to track the changes on the server side
+    // or figure out how to convert everybody to query all the descriptors at once.
+    // TODO: check for nullptr
+    if (mLastDescriptors.size() == 0) {
+        status_t queryResult = queryAllDescriptors();
+        if (queryResult != OK) return queryResult;
+    }
+    if (index >= mLastDescriptors.size()) return NAME_NOT_FOUND;
+    EffectHalHidl::effectDescriptorToHal(mLastDescriptors[index], pDescriptor);
+    return OK;
+}
+
+status_t EffectsFactoryHalHidl::getDescriptor(
+        const effect_uuid_t *pEffectUuid, effect_descriptor_t *pDescriptor) {
+    // TODO: check for nullptr
+    if (mEffectsFactory == 0) return NO_INIT;
+    Uuid hidlUuid;
+    HidlUtils::uuidFromHal(*pEffectUuid, &hidlUuid);
+    Result retval = Result::NOT_INITIALIZED;
+    Return<void> ret = mEffectsFactory->getDescriptor(hidlUuid,
+            [&](Result r, const EffectDescriptor& result) {
+                retval = r;
+                if (retval == Result::OK) {
+                    EffectHalHidl::effectDescriptorToHal(result, pDescriptor);
+                }
+            });
+    if (ret.isOk()) {
+        if (retval == Result::OK) return OK;
+        else if (retval == Result::INVALID_ARGUMENTS) return NAME_NOT_FOUND;
+        else return NO_INIT;
+    }
+    return processReturn(__FUNCTION__, ret);
+}
+
+status_t EffectsFactoryHalHidl::createEffect(
+        const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t ioId,
+        sp<EffectHalInterface> *effect) {
+    if (mEffectsFactory == 0) return NO_INIT;
+    Uuid hidlUuid;
+    HidlUtils::uuidFromHal(*pEffectUuid, &hidlUuid);
+    Result retval = Result::NOT_INITIALIZED;
+    Return<void> ret = mEffectsFactory->createEffect(
+            hidlUuid, sessionId, ioId,
+            [&](Result r, const sp<IEffect>& result, uint64_t effectId) {
+                retval = r;
+                if (retval == Result::OK) {
+                    *effect = new EffectHalHidl(result, effectId);
+                }
+            });
+    if (ret.isOk()) {
+        if (retval == Result::OK) return OK;
+        else if (retval == Result::INVALID_ARGUMENTS) return NAME_NOT_FOUND;
+        else return NO_INIT;
+    }
+    return processReturn(__FUNCTION__, ret);
+}
+
+status_t EffectsFactoryHalHidl::dumpEffects(int fd) {
+    if (mEffectsFactory == 0) return NO_INIT;
+    native_handle_t* hidlHandle = native_handle_create(1, 0);
+    hidlHandle->data[0] = fd;
+    Return<void> ret = mEffectsFactory->debug(hidlHandle, {} /* options */);
+    native_handle_delete(hidlHandle);
+    return processReturn(__FUNCTION__, ret);
+}
+
+status_t EffectsFactoryHalHidl::allocateBuffer(size_t size, sp<EffectBufferHalInterface>* buffer) {
+    return EffectBufferHalHidl::allocate(size, buffer);
+}
+
+status_t EffectsFactoryHalHidl::mirrorBuffer(void* external, size_t size,
+                          sp<EffectBufferHalInterface>* buffer) {
+    return EffectBufferHalHidl::mirror(external, size, buffer);
+}
+
+} // namespace CPP_VERSION
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/EffectsFactoryHalHidl.h b/media/libaudiohal/impl/EffectsFactoryHalHidl.h
new file mode 100644
index 0000000..01178ff
--- /dev/null
+++ b/media/libaudiohal/impl/EffectsFactoryHalHidl.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_EFFECTS_FACTORY_HAL_HIDL_H
+#define ANDROID_HARDWARE_EFFECTS_FACTORY_HAL_HIDL_H
+
+#include PATH(android/hardware/audio/effect/FILE_VERSION/IEffectsFactory.h)
+#include PATH(android/hardware/audio/effect/FILE_VERSION/types.h)
+#include <media/audiohal/EffectsFactoryHalInterface.h>
+
+#include "ConversionHelperHidl.h"
+
+namespace android {
+namespace effect {
+namespace CPP_VERSION {
+
+using ::android::hardware::hidl_vec;
+using ::android::CPP_VERSION::ConversionHelperHidl;
+using namespace ::android::hardware::audio::effect::CPP_VERSION;
+
+class EffectsFactoryHalHidl : public EffectsFactoryHalInterface, public ConversionHelperHidl
+{
+  public:
+    EffectsFactoryHalHidl();
+
+    // Returns the number of different effects in all loaded libraries.
+    virtual status_t queryNumberEffects(uint32_t *pNumEffects);
+
+    // Returns a descriptor of the next available effect.
+    virtual status_t getDescriptor(uint32_t index,
+            effect_descriptor_t *pDescriptor);
+
+    virtual status_t getDescriptor(const effect_uuid_t *pEffectUuid,
+            effect_descriptor_t *pDescriptor);
+
+    // Creates an effect engine of the specified type.
+    // To release the effect engine, it is necessary to release references
+    // to the returned effect object.
+    virtual status_t createEffect(const effect_uuid_t *pEffectUuid,
+            int32_t sessionId, int32_t ioId,
+            sp<EffectHalInterface> *effect);
+
+    virtual status_t dumpEffects(int fd);
+
+    status_t allocateBuffer(size_t size, sp<EffectBufferHalInterface>* buffer) override;
+    status_t mirrorBuffer(void* external, size_t size,
+                          sp<EffectBufferHalInterface>* buffer) override;
+
+  private:
+    sp<IEffectsFactory> mEffectsFactory;
+    hidl_vec<EffectDescriptor> mLastDescriptors;
+
+    status_t queryAllDescriptors();
+};
+
+sp<EffectsFactoryHalInterface> createEffectsFactoryHal() {
+    return new EffectsFactoryHalHidl();
+}
+
+} // namespace CPP_VERSION
+} // namespace effect
+} // namespace android
+
+#endif // ANDROID_HARDWARE_EFFECTS_FACTORY_HAL_HIDL_H
diff --git a/media/libaudiohal/impl/StreamHalHidl.cpp b/media/libaudiohal/impl/StreamHalHidl.cpp
new file mode 100644
index 0000000..c08dddb
--- /dev/null
+++ b/media/libaudiohal/impl/StreamHalHidl.cpp
@@ -0,0 +1,883 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "StreamHalHidl"
+//#define LOG_NDEBUG 0
+
+#include PATH(android/hardware/audio/FILE_VERSION/IStreamOutCallback.h)
+#include <hwbinder/IPCThreadState.h>
+#include <media/AudioParameter.h>
+#include <mediautils/SchedulingPolicyService.h>
+#include <utils/Log.h>
+
+#include "DeviceHalHidl.h"
+#include "EffectHalHidl.h"
+#include "StreamHalHidl.h"
+#include "VersionUtils.h"
+
+using ::android::hardware::MQDescriptorSync;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+namespace android {
+namespace CPP_VERSION {
+
+using EffectHalHidl = ::android::effect::CPP_VERSION::EffectHalHidl;
+using ReadCommand = ::android::hardware::audio::CPP_VERSION::IStreamIn::ReadCommand;
+
+using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::CPP_VERSION;
+
+StreamHalHidl::StreamHalHidl(IStream *stream)
+        : ConversionHelperHidl("Stream"),
+          mStream(stream),
+          mHalThreadPriority(HAL_THREAD_PRIORITY_DEFAULT),
+          mCachedBufferSize(0){
+
+    // Instrument audio signal power logging.
+    // Note: This assumes channel mask, format, and sample rate do not change after creation.
+    if (mStream != nullptr /* && mStreamPowerLog.isUserDebugOrEngBuild() */) {
+        // Obtain audio properties (see StreamHalHidl::getAudioProperties() below).
+        Return<void> ret = mStream->getAudioProperties(
+                [&](auto sr, auto m, auto f) {
+                mStreamPowerLog.init(sr,
+                        static_cast<audio_channel_mask_t>(m),
+                        static_cast<audio_format_t>(f));
+            });
+    }
+}
+
+StreamHalHidl::~StreamHalHidl() {
+    mStream = nullptr;
+}
+
+status_t StreamHalHidl::getSampleRate(uint32_t *rate) {
+    if (!mStream) return NO_INIT;
+    return processReturn("getSampleRate", mStream->getSampleRate(), rate);
+}
+
+status_t StreamHalHidl::getBufferSize(size_t *size) {
+    if (!mStream) return NO_INIT;
+    status_t status = processReturn("getBufferSize", mStream->getBufferSize(), size);
+    if (status == OK) {
+        mCachedBufferSize = *size;
+    }
+    return status;
+}
+
+status_t StreamHalHidl::getChannelMask(audio_channel_mask_t *mask) {
+    if (!mStream) return NO_INIT;
+    return processReturn("getChannelMask", mStream->getChannelMask(), mask);
+}
+
+status_t StreamHalHidl::getFormat(audio_format_t *format) {
+    if (!mStream) return NO_INIT;
+    return processReturn("getFormat", mStream->getFormat(), format);
+}
+
+status_t StreamHalHidl::getAudioProperties(
+        uint32_t *sampleRate, audio_channel_mask_t *mask, audio_format_t *format) {
+    if (!mStream) return NO_INIT;
+    Return<void> ret = mStream->getAudioProperties(
+            [&](uint32_t sr, auto m, auto f) {
+                *sampleRate = sr;
+                *mask = static_cast<audio_channel_mask_t>(m);
+                *format = static_cast<audio_format_t>(f);
+            });
+    return processReturn("getAudioProperties", ret);
+}
+
+status_t StreamHalHidl::setParameters(const String8& kvPairs) {
+    if (!mStream) return NO_INIT;
+    hidl_vec<ParameterValue> hidlParams;
+    status_t status = parametersFromHal(kvPairs, &hidlParams);
+    if (status != OK) return status;
+    return processReturn("setParameters",
+                         utils::setParameters(mStream, {} /* context */, hidlParams));
+}
+
+status_t StreamHalHidl::getParameters(const String8& keys, String8 *values) {
+    values->clear();
+    if (!mStream) return NO_INIT;
+    hidl_vec<hidl_string> hidlKeys;
+    status_t status = keysFromHal(keys, &hidlKeys);
+    if (status != OK) return status;
+    Result retval;
+    Return<void> ret = utils::getParameters(
+            mStream,
+            {} /* context */,
+            hidlKeys,
+            [&](Result r, const hidl_vec<ParameterValue>& parameters) {
+                retval = r;
+                if (retval == Result::OK) {
+                    parametersToHal(parameters, values);
+                }
+            });
+    return processReturn("getParameters", ret, retval);
+}
+
+status_t StreamHalHidl::addEffect(sp<EffectHalInterface> effect) {
+    if (!mStream) return NO_INIT;
+    return processReturn("addEffect", mStream->addEffect(
+                    static_cast<EffectHalHidl*>(effect.get())->effectId()));
+}
+
+status_t StreamHalHidl::removeEffect(sp<EffectHalInterface> effect) {
+    if (!mStream) return NO_INIT;
+    return processReturn("removeEffect", mStream->removeEffect(
+                    static_cast<EffectHalHidl*>(effect.get())->effectId()));
+}
+
+status_t StreamHalHidl::standby() {
+    if (!mStream) return NO_INIT;
+    return processReturn("standby", mStream->standby());
+}
+
+status_t StreamHalHidl::dump(int fd) {
+    if (!mStream) return NO_INIT;
+    native_handle_t* hidlHandle = native_handle_create(1, 0);
+    hidlHandle->data[0] = fd;
+    Return<void> ret = mStream->debug(hidlHandle, {} /* options */);
+    native_handle_delete(hidlHandle);
+    mStreamPowerLog.dump(fd);
+    return processReturn("dump", ret);
+}
+
+status_t StreamHalHidl::start() {
+    if (!mStream) return NO_INIT;
+    return processReturn("start", mStream->start());
+}
+
+status_t StreamHalHidl::stop() {
+    if (!mStream) return NO_INIT;
+    return processReturn("stop", mStream->stop());
+}
+
+status_t StreamHalHidl::createMmapBuffer(int32_t minSizeFrames,
+                                  struct audio_mmap_buffer_info *info) {
+    Result retval;
+    Return<void> ret = mStream->createMmapBuffer(
+            minSizeFrames,
+            [&](Result r, const MmapBufferInfo& hidlInfo) {
+                retval = r;
+                if (retval == Result::OK) {
+                    const native_handle *handle = hidlInfo.sharedMemory.handle();
+                    if (handle->numFds > 0) {
+                        info->shared_memory_fd = handle->data[0];
+#if MAJOR_VERSION >= 4
+                        info->flags = audio_mmap_buffer_flag(hidlInfo.flags);
+#endif
+                        info->buffer_size_frames = hidlInfo.bufferSizeFrames;
+                        // Negative buffer size frame was a hack in O and P to
+                        // indicate that the buffer is shareable to applications
+                        if (info->buffer_size_frames < 0) {
+                            info->buffer_size_frames *= -1;
+                            info->flags = audio_mmap_buffer_flag(
+                                    info->flags | AUDIO_MMAP_APPLICATION_SHAREABLE);
+                        }
+                        info->burst_size_frames = hidlInfo.burstSizeFrames;
+                        // info->shared_memory_address is not needed in HIDL context
+                        info->shared_memory_address = NULL;
+                    } else {
+                        retval = Result::NOT_INITIALIZED;
+                    }
+                }
+            });
+    return processReturn("createMmapBuffer", ret, retval);
+}
+
+status_t StreamHalHidl::getMmapPosition(struct audio_mmap_position *position) {
+    Result retval;
+    Return<void> ret = mStream->getMmapPosition(
+            [&](Result r, const MmapPosition& hidlPosition) {
+                retval = r;
+                if (retval == Result::OK) {
+                    position->time_nanoseconds = hidlPosition.timeNanoseconds;
+                    position->position_frames = hidlPosition.positionFrames;
+                }
+            });
+    return processReturn("getMmapPosition", ret, retval);
+}
+
+status_t StreamHalHidl::setHalThreadPriority(int priority) {
+    mHalThreadPriority = priority;
+    return OK;
+}
+
+status_t StreamHalHidl::getCachedBufferSize(size_t *size) {
+    if (mCachedBufferSize != 0) {
+        *size = mCachedBufferSize;
+        return OK;
+    }
+    return getBufferSize(size);
+}
+
+bool StreamHalHidl::requestHalThreadPriority(pid_t threadPid, pid_t threadId) {
+    if (mHalThreadPriority == HAL_THREAD_PRIORITY_DEFAULT) {
+        return true;
+    }
+    int err = requestPriority(
+            threadPid, threadId,
+            mHalThreadPriority, false /*isForApp*/, true /*asynchronous*/);
+    ALOGE_IF(err, "failed to set priority %d for pid %d tid %d; error %d",
+            mHalThreadPriority, threadPid, threadId, err);
+    // Audio will still work, but latency will be higher and sometimes unacceptable.
+    return err == 0;
+}
+
+namespace {
+
+/* Notes on callback ownership.
+
+This is how (Hw)Binder ownership model looks like. The server implementation
+is owned by Binder framework (via sp<>). Proxies are owned by clients.
+When the last proxy disappears, Binder framework releases the server impl.
+
+Thus, it is not needed to keep any references to StreamOutCallback (this is
+the server impl) -- it will live as long as HAL server holds a strong ref to
+IStreamOutCallback proxy. We clear that reference by calling 'clearCallback'
+from the destructor of StreamOutHalHidl.
+
+The callback only keeps a weak reference to the stream. The stream is owned
+by AudioFlinger.
+
+*/
+
+struct StreamOutCallback : public IStreamOutCallback {
+    StreamOutCallback(const wp<StreamOutHalHidl>& stream) : mStream(stream) {}
+
+    // IStreamOutCallback implementation
+    Return<void> onWriteReady()  override {
+        sp<StreamOutHalHidl> stream = mStream.promote();
+        if (stream != 0) {
+            stream->onWriteReady();
+        }
+        return Void();
+    }
+
+    Return<void> onDrainReady()  override {
+        sp<StreamOutHalHidl> stream = mStream.promote();
+        if (stream != 0) {
+            stream->onDrainReady();
+        }
+        return Void();
+    }
+
+    Return<void> onError()  override {
+        sp<StreamOutHalHidl> stream = mStream.promote();
+        if (stream != 0) {
+            stream->onError();
+        }
+        return Void();
+    }
+
+  private:
+    wp<StreamOutHalHidl> mStream;
+};
+
+}  // namespace
+
+StreamOutHalHidl::StreamOutHalHidl(const sp<IStreamOut>& stream)
+        : StreamHalHidl(stream.get()), mStream(stream), mWriterClient(0), mEfGroup(nullptr) {
+}
+
+StreamOutHalHidl::~StreamOutHalHidl() {
+    if (mStream != 0) {
+        if (mCallback.unsafe_get()) {
+            processReturn("clearCallback", mStream->clearCallback());
+        }
+        processReturn("close", mStream->close());
+        mStream.clear();
+    }
+    mCallback.clear();
+    hardware::IPCThreadState::self()->flushCommands();
+    if (mEfGroup) {
+        EventFlag::deleteEventFlag(&mEfGroup);
+    }
+}
+
+status_t StreamOutHalHidl::getFrameSize(size_t *size) {
+    if (mStream == 0) return NO_INIT;
+    return processReturn("getFrameSize", mStream->getFrameSize(), size);
+}
+
+status_t StreamOutHalHidl::getLatency(uint32_t *latency) {
+    if (mStream == 0) return NO_INIT;
+    if (mWriterClient == gettid() && mCommandMQ) {
+        return callWriterThread(
+                WriteCommand::GET_LATENCY, "getLatency", nullptr, 0,
+                [&](const WriteStatus& writeStatus) {
+                    *latency = writeStatus.reply.latencyMs;
+                });
+    } else {
+        return processReturn("getLatency", mStream->getLatency(), latency);
+    }
+}
+
+status_t StreamOutHalHidl::setVolume(float left, float right) {
+    if (mStream == 0) return NO_INIT;
+    return processReturn("setVolume", mStream->setVolume(left, right));
+}
+
+#if MAJOR_VERSION == 2
+status_t StreamOutHalHidl::selectPresentation(int presentationId, int programId) {
+    if (mStream == 0) return NO_INIT;
+    std::vector<ParameterValue> parameters;
+    String8 halParameters;
+    parameters.push_back({AudioParameter::keyPresentationId, std::to_string(presentationId)});
+    parameters.push_back({AudioParameter::keyProgramId, std::to_string(programId)});
+    parametersToHal(hidl_vec<ParameterValue>(parameters), &halParameters);
+    return setParameters(halParameters);
+}
+#elif MAJOR_VERSION >= 4
+status_t StreamOutHalHidl::selectPresentation(int presentationId, int programId) {
+    if (mStream == 0) return NO_INIT;
+    return processReturn("selectPresentation",
+            mStream->selectPresentation(presentationId, programId));
+}
+#endif
+
+status_t StreamOutHalHidl::write(const void *buffer, size_t bytes, size_t *written) {
+    if (mStream == 0) return NO_INIT;
+    *written = 0;
+
+    if (bytes == 0 && !mDataMQ) {
+        // Can't determine the size for the MQ buffer. Wait for a non-empty write request.
+        ALOGW_IF(mCallback.unsafe_get(), "First call to async write with 0 bytes");
+        return OK;
+    }
+
+    status_t status;
+    if (!mDataMQ) {
+        // In case if playback starts close to the end of a compressed track, the bytes
+        // that need to be written is less than the actual buffer size. Need to use
+        // full buffer size for the MQ since otherwise after seeking back to the middle
+        // data will be truncated.
+        size_t bufferSize;
+        if ((status = getCachedBufferSize(&bufferSize)) != OK) {
+            return status;
+        }
+        if (bytes > bufferSize) bufferSize = bytes;
+        if ((status = prepareForWriting(bufferSize)) != OK) {
+            return status;
+        }
+    }
+
+    status = callWriterThread(
+            WriteCommand::WRITE, "write", static_cast<const uint8_t*>(buffer), bytes,
+            [&] (const WriteStatus& writeStatus) {
+                *written = writeStatus.reply.written;
+                // Diagnostics of the cause of b/35813113.
+                ALOGE_IF(*written > bytes,
+                        "hal reports more bytes written than asked for: %lld > %lld",
+                        (long long)*written, (long long)bytes);
+            });
+    mStreamPowerLog.log(buffer, *written);
+    return status;
+}
+
+status_t StreamOutHalHidl::callWriterThread(
+        WriteCommand cmd, const char* cmdName,
+        const uint8_t* data, size_t dataSize, StreamOutHalHidl::WriterCallback callback) {
+    if (!mCommandMQ->write(&cmd)) {
+        ALOGE("command message queue write failed for \"%s\"", cmdName);
+        return -EAGAIN;
+    }
+    if (data != nullptr) {
+        size_t availableToWrite = mDataMQ->availableToWrite();
+        if (dataSize > availableToWrite) {
+            ALOGW("truncating write data from %lld to %lld due to insufficient data queue space",
+                    (long long)dataSize, (long long)availableToWrite);
+            dataSize = availableToWrite;
+        }
+        if (!mDataMQ->write(data, dataSize)) {
+            ALOGE("data message queue write failed for \"%s\"", cmdName);
+        }
+    }
+    mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY));
+
+    // TODO: Remove manual event flag handling once blocking MQ is implemented. b/33815422
+    uint32_t efState = 0;
+retry:
+    status_t ret = mEfGroup->wait(static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL), &efState);
+    if (efState & static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL)) {
+        WriteStatus writeStatus;
+        writeStatus.retval = Result::NOT_INITIALIZED;
+        if (!mStatusMQ->read(&writeStatus)) {
+            ALOGE("status message read failed for \"%s\"", cmdName);
+        }
+        if (writeStatus.retval == Result::OK) {
+            ret = OK;
+            callback(writeStatus);
+        } else {
+            ret = processReturn(cmdName, writeStatus.retval);
+        }
+        return ret;
+    }
+    if (ret == -EAGAIN || ret == -EINTR) {
+        // Spurious wakeup. This normally retries no more than once.
+        goto retry;
+    }
+    return ret;
+}
+
+status_t StreamOutHalHidl::prepareForWriting(size_t bufferSize) {
+    std::unique_ptr<CommandMQ> tempCommandMQ;
+    std::unique_ptr<DataMQ> tempDataMQ;
+    std::unique_ptr<StatusMQ> tempStatusMQ;
+    Result retval;
+    pid_t halThreadPid, halThreadTid;
+    Return<void> ret = mStream->prepareForWriting(
+            1, bufferSize,
+            [&](Result r,
+                    const CommandMQ::Descriptor& commandMQ,
+                    const DataMQ::Descriptor& dataMQ,
+                    const StatusMQ::Descriptor& statusMQ,
+                    const ThreadInfo& halThreadInfo) {
+                retval = r;
+                if (retval == Result::OK) {
+                    tempCommandMQ.reset(new CommandMQ(commandMQ));
+                    tempDataMQ.reset(new DataMQ(dataMQ));
+                    tempStatusMQ.reset(new StatusMQ(statusMQ));
+                    if (tempDataMQ->isValid() && tempDataMQ->getEventFlagWord()) {
+                        EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &mEfGroup);
+                    }
+                    halThreadPid = halThreadInfo.pid;
+                    halThreadTid = halThreadInfo.tid;
+                }
+            });
+    if (!ret.isOk() || retval != Result::OK) {
+        return processReturn("prepareForWriting", ret, retval);
+    }
+    if (!tempCommandMQ || !tempCommandMQ->isValid() ||
+            !tempDataMQ || !tempDataMQ->isValid() ||
+            !tempStatusMQ || !tempStatusMQ->isValid() ||
+            !mEfGroup) {
+        ALOGE_IF(!tempCommandMQ, "Failed to obtain command message queue for writing");
+        ALOGE_IF(tempCommandMQ && !tempCommandMQ->isValid(),
+                "Command message queue for writing is invalid");
+        ALOGE_IF(!tempDataMQ, "Failed to obtain data message queue for writing");
+        ALOGE_IF(tempDataMQ && !tempDataMQ->isValid(), "Data message queue for writing is invalid");
+        ALOGE_IF(!tempStatusMQ, "Failed to obtain status message queue for writing");
+        ALOGE_IF(tempStatusMQ && !tempStatusMQ->isValid(),
+                "Status message queue for writing is invalid");
+        ALOGE_IF(!mEfGroup, "Event flag creation for writing failed");
+        return NO_INIT;
+    }
+    requestHalThreadPriority(halThreadPid, halThreadTid);
+
+    mCommandMQ = std::move(tempCommandMQ);
+    mDataMQ = std::move(tempDataMQ);
+    mStatusMQ = std::move(tempStatusMQ);
+    mWriterClient = gettid();
+    return OK;
+}
+
+status_t StreamOutHalHidl::getRenderPosition(uint32_t *dspFrames) {
+    if (mStream == 0) return NO_INIT;
+    Result retval;
+    Return<void> ret = mStream->getRenderPosition(
+            [&](Result r, uint32_t d) {
+                retval = r;
+                if (retval == Result::OK) {
+                    *dspFrames = d;
+                }
+            });
+    return processReturn("getRenderPosition", ret, retval);
+}
+
+status_t StreamOutHalHidl::getNextWriteTimestamp(int64_t *timestamp) {
+    if (mStream == 0) return NO_INIT;
+    Result retval;
+    Return<void> ret = mStream->getNextWriteTimestamp(
+            [&](Result r, int64_t t) {
+                retval = r;
+                if (retval == Result::OK) {
+                    *timestamp = t;
+                }
+            });
+    return processReturn("getRenderPosition", ret, retval);
+}
+
+status_t StreamOutHalHidl::setCallback(wp<StreamOutHalInterfaceCallback> callback) {
+    if (mStream == 0) return NO_INIT;
+    status_t status = processReturn(
+            "setCallback", mStream->setCallback(new StreamOutCallback(this)));
+    if (status == OK) {
+        mCallback = callback;
+    }
+    return status;
+}
+
+status_t StreamOutHalHidl::supportsPauseAndResume(bool *supportsPause, bool *supportsResume) {
+    if (mStream == 0) return NO_INIT;
+    Return<void> ret = mStream->supportsPauseAndResume(
+            [&](bool p, bool r) {
+                *supportsPause = p;
+                *supportsResume = r;
+            });
+    return processReturn("supportsPauseAndResume", ret);
+}
+
+status_t StreamOutHalHidl::pause() {
+    if (mStream == 0) return NO_INIT;
+    return processReturn("pause", mStream->pause());
+}
+
+status_t StreamOutHalHidl::resume() {
+    if (mStream == 0) return NO_INIT;
+    return processReturn("pause", mStream->resume());
+}
+
+status_t StreamOutHalHidl::supportsDrain(bool *supportsDrain) {
+    if (mStream == 0) return NO_INIT;
+    return processReturn("supportsDrain", mStream->supportsDrain(), supportsDrain);
+}
+
+status_t StreamOutHalHidl::drain(bool earlyNotify) {
+    if (mStream == 0) return NO_INIT;
+    return processReturn(
+            "drain", mStream->drain(earlyNotify ? AudioDrain::EARLY_NOTIFY : AudioDrain::ALL));
+}
+
+status_t StreamOutHalHidl::flush() {
+    if (mStream == 0) return NO_INIT;
+    return processReturn("pause", mStream->flush());
+}
+
+status_t StreamOutHalHidl::getPresentationPosition(uint64_t *frames, struct timespec *timestamp) {
+    if (mStream == 0) return NO_INIT;
+    if (mWriterClient == gettid() && mCommandMQ) {
+        return callWriterThread(
+                WriteCommand::GET_PRESENTATION_POSITION, "getPresentationPosition", nullptr, 0,
+                [&](const WriteStatus& writeStatus) {
+                    *frames = writeStatus.reply.presentationPosition.frames;
+                    timestamp->tv_sec = writeStatus.reply.presentationPosition.timeStamp.tvSec;
+                    timestamp->tv_nsec = writeStatus.reply.presentationPosition.timeStamp.tvNSec;
+                });
+    } else {
+        Result retval;
+        Return<void> ret = mStream->getPresentationPosition(
+                [&](Result r, uint64_t hidlFrames, const TimeSpec& hidlTimeStamp) {
+                    retval = r;
+                    if (retval == Result::OK) {
+                        *frames = hidlFrames;
+                        timestamp->tv_sec = hidlTimeStamp.tvSec;
+                        timestamp->tv_nsec = hidlTimeStamp.tvNSec;
+                    }
+                });
+        return processReturn("getPresentationPosition", ret, retval);
+    }
+}
+
+#if MAJOR_VERSION == 2
+status_t StreamOutHalHidl::updateSourceMetadata(
+        const StreamOutHalInterface::SourceMetadata& /* sourceMetadata */) {
+    // Audio HAL V2.0 does not support propagating source metadata
+    return INVALID_OPERATION;
+}
+#elif MAJOR_VERSION >= 4
+/** Transform a standard collection to an HIDL vector. */
+template <class Values, class ElementConverter>
+static auto transformToHidlVec(const Values& values, ElementConverter converter) {
+    hidl_vec<decltype(converter(*values.begin()))> result{values.size()};
+    using namespace std;
+    transform(begin(values), end(values), begin(result), converter);
+    return result;
+}
+
+status_t StreamOutHalHidl::updateSourceMetadata(
+        const StreamOutHalInterface::SourceMetadata& sourceMetadata) {
+    CPP_VERSION::SourceMetadata halMetadata = {
+        .tracks = transformToHidlVec(sourceMetadata.tracks,
+              [](const playback_track_metadata& metadata) -> PlaybackTrackMetadata {
+                  return {
+                    .usage=static_cast<AudioUsage>(metadata.usage),
+                    .contentType=static_cast<AudioContentType>(metadata.content_type),
+                    .gain=metadata.gain,
+                  };
+              })};
+    return processReturn("updateSourceMetadata", mStream->updateSourceMetadata(halMetadata));
+}
+#endif
+
+void StreamOutHalHidl::onWriteReady() {
+    sp<StreamOutHalInterfaceCallback> callback = mCallback.promote();
+    if (callback == 0) return;
+    ALOGV("asyncCallback onWriteReady");
+    callback->onWriteReady();
+}
+
+void StreamOutHalHidl::onDrainReady() {
+    sp<StreamOutHalInterfaceCallback> callback = mCallback.promote();
+    if (callback == 0) return;
+    ALOGV("asyncCallback onDrainReady");
+    callback->onDrainReady();
+}
+
+void StreamOutHalHidl::onError() {
+    sp<StreamOutHalInterfaceCallback> callback = mCallback.promote();
+    if (callback == 0) return;
+    ALOGV("asyncCallback onError");
+    callback->onError();
+}
+
+
+StreamInHalHidl::StreamInHalHidl(const sp<IStreamIn>& stream)
+        : StreamHalHidl(stream.get()), mStream(stream), mReaderClient(0), mEfGroup(nullptr) {
+}
+
+StreamInHalHidl::~StreamInHalHidl() {
+    if (mStream != 0) {
+        processReturn("close", mStream->close());
+        mStream.clear();
+        hardware::IPCThreadState::self()->flushCommands();
+    }
+    if (mEfGroup) {
+        EventFlag::deleteEventFlag(&mEfGroup);
+    }
+}
+
+status_t StreamInHalHidl::getFrameSize(size_t *size) {
+    if (mStream == 0) return NO_INIT;
+    return processReturn("getFrameSize", mStream->getFrameSize(), size);
+}
+
+status_t StreamInHalHidl::setGain(float gain) {
+    if (mStream == 0) return NO_INIT;
+    return processReturn("setGain", mStream->setGain(gain));
+}
+
+status_t StreamInHalHidl::read(void *buffer, size_t bytes, size_t *read) {
+    if (mStream == 0) return NO_INIT;
+    *read = 0;
+
+    if (bytes == 0 && !mDataMQ) {
+        // Can't determine the size for the MQ buffer. Wait for a non-empty read request.
+        return OK;
+    }
+
+    status_t status;
+    if (!mDataMQ && (status = prepareForReading(bytes)) != OK) {
+        return status;
+    }
+
+    ReadParameters params;
+    params.command = ReadCommand::READ;
+    params.params.read = bytes;
+    status = callReaderThread(params, "read",
+            [&](const ReadStatus& readStatus) {
+                const size_t availToRead = mDataMQ->availableToRead();
+                if (!mDataMQ->read(static_cast<uint8_t*>(buffer), std::min(bytes, availToRead))) {
+                    ALOGE("data message queue read failed for \"read\"");
+                }
+                ALOGW_IF(availToRead != readStatus.reply.read,
+                        "HAL read report inconsistent: mq = %d, status = %d",
+                        (int32_t)availToRead, (int32_t)readStatus.reply.read);
+                *read = readStatus.reply.read;
+            });
+    mStreamPowerLog.log(buffer, *read);
+    return status;
+}
+
+status_t StreamInHalHidl::callReaderThread(
+        const ReadParameters& params, const char* cmdName,
+        StreamInHalHidl::ReaderCallback callback) {
+    if (!mCommandMQ->write(&params)) {
+        ALOGW("command message queue write failed");
+        return -EAGAIN;
+    }
+    mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL));
+
+    // TODO: Remove manual event flag handling once blocking MQ is implemented. b/33815422
+    uint32_t efState = 0;
+retry:
+    status_t ret = mEfGroup->wait(static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY), &efState);
+    if (efState & static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY)) {
+        ReadStatus readStatus;
+        readStatus.retval = Result::NOT_INITIALIZED;
+        if (!mStatusMQ->read(&readStatus)) {
+            ALOGE("status message read failed for \"%s\"", cmdName);
+        }
+         if (readStatus.retval == Result::OK) {
+            ret = OK;
+            callback(readStatus);
+        } else {
+            ret = processReturn(cmdName, readStatus.retval);
+        }
+        return ret;
+    }
+    if (ret == -EAGAIN || ret == -EINTR) {
+        // Spurious wakeup. This normally retries no more than once.
+        goto retry;
+    }
+    return ret;
+}
+
+status_t StreamInHalHidl::prepareForReading(size_t bufferSize) {
+    std::unique_ptr<CommandMQ> tempCommandMQ;
+    std::unique_ptr<DataMQ> tempDataMQ;
+    std::unique_ptr<StatusMQ> tempStatusMQ;
+    Result retval;
+    pid_t halThreadPid, halThreadTid;
+    Return<void> ret = mStream->prepareForReading(
+            1, bufferSize,
+            [&](Result r,
+                    const CommandMQ::Descriptor& commandMQ,
+                    const DataMQ::Descriptor& dataMQ,
+                    const StatusMQ::Descriptor& statusMQ,
+                    const ThreadInfo& halThreadInfo) {
+                retval = r;
+                if (retval == Result::OK) {
+                    tempCommandMQ.reset(new CommandMQ(commandMQ));
+                    tempDataMQ.reset(new DataMQ(dataMQ));
+                    tempStatusMQ.reset(new StatusMQ(statusMQ));
+                    if (tempDataMQ->isValid() && tempDataMQ->getEventFlagWord()) {
+                        EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &mEfGroup);
+                    }
+                    halThreadPid = halThreadInfo.pid;
+                    halThreadTid = halThreadInfo.tid;
+                }
+            });
+    if (!ret.isOk() || retval != Result::OK) {
+        return processReturn("prepareForReading", ret, retval);
+    }
+    if (!tempCommandMQ || !tempCommandMQ->isValid() ||
+            !tempDataMQ || !tempDataMQ->isValid() ||
+            !tempStatusMQ || !tempStatusMQ->isValid() ||
+            !mEfGroup) {
+        ALOGE_IF(!tempCommandMQ, "Failed to obtain command message queue for writing");
+        ALOGE_IF(tempCommandMQ && !tempCommandMQ->isValid(),
+                "Command message queue for writing is invalid");
+        ALOGE_IF(!tempDataMQ, "Failed to obtain data message queue for reading");
+        ALOGE_IF(tempDataMQ && !tempDataMQ->isValid(), "Data message queue for reading is invalid");
+        ALOGE_IF(!tempStatusMQ, "Failed to obtain status message queue for reading");
+        ALOGE_IF(tempStatusMQ && !tempStatusMQ->isValid(),
+                "Status message queue for reading is invalid");
+        ALOGE_IF(!mEfGroup, "Event flag creation for reading failed");
+        return NO_INIT;
+    }
+    requestHalThreadPriority(halThreadPid, halThreadTid);
+
+    mCommandMQ = std::move(tempCommandMQ);
+    mDataMQ = std::move(tempDataMQ);
+    mStatusMQ = std::move(tempStatusMQ);
+    mReaderClient = gettid();
+    return OK;
+}
+
+status_t StreamInHalHidl::getInputFramesLost(uint32_t *framesLost) {
+    if (mStream == 0) return NO_INIT;
+    return processReturn("getInputFramesLost", mStream->getInputFramesLost(), framesLost);
+}
+
+status_t StreamInHalHidl::getCapturePosition(int64_t *frames, int64_t *time) {
+    if (mStream == 0) return NO_INIT;
+    if (mReaderClient == gettid() && mCommandMQ) {
+        ReadParameters params;
+        params.command = ReadCommand::GET_CAPTURE_POSITION;
+        return callReaderThread(params, "getCapturePosition",
+                [&](const ReadStatus& readStatus) {
+                    *frames = readStatus.reply.capturePosition.frames;
+                    *time = readStatus.reply.capturePosition.time;
+                });
+    } else {
+        Result retval;
+        Return<void> ret = mStream->getCapturePosition(
+                [&](Result r, uint64_t hidlFrames, uint64_t hidlTime) {
+                    retval = r;
+                    if (retval == Result::OK) {
+                        *frames = hidlFrames;
+                        *time = hidlTime;
+                    }
+                });
+        return processReturn("getCapturePosition", ret, retval);
+    }
+}
+
+#if MAJOR_VERSION == 2
+status_t StreamInHalHidl::getActiveMicrophones(
+        std::vector<media::MicrophoneInfo> *microphones __unused) {
+    if (mStream == 0) return NO_INIT;
+    return INVALID_OPERATION;
+}
+
+status_t StreamInHalHidl::updateSinkMetadata(
+        const StreamInHalInterface::SinkMetadata& /* sinkMetadata */) {
+    // Audio HAL V2.0 does not support propagating sink metadata
+    return INVALID_OPERATION;
+}
+
+#elif MAJOR_VERSION >= 4
+status_t StreamInHalHidl::getActiveMicrophones(
+        std::vector<media::MicrophoneInfo> *microphonesInfo) {
+    if (!mStream) return NO_INIT;
+    Result retval;
+    Return<void> ret = mStream->getActiveMicrophones(
+            [&](Result r, hidl_vec<MicrophoneInfo> micArrayHal) {
+        retval = r;
+        for (size_t k = 0; k < micArrayHal.size(); k++) {
+            audio_microphone_characteristic_t dst;
+            // convert
+            microphoneInfoToHal(micArrayHal[k], &dst);
+            media::MicrophoneInfo microphone = media::MicrophoneInfo(dst);
+            microphonesInfo->push_back(microphone);
+        }
+    });
+    return processReturn("getActiveMicrophones", ret, retval);
+}
+
+status_t StreamInHalHidl::updateSinkMetadata(const
+        StreamInHalInterface::SinkMetadata& sinkMetadata) {
+    CPP_VERSION::SinkMetadata halMetadata = {
+        .tracks = transformToHidlVec(sinkMetadata.tracks,
+              [](const record_track_metadata& metadata) -> RecordTrackMetadata {
+                  return {
+                    .source=static_cast<AudioSource>(metadata.source),
+                    .gain=metadata.gain,
+                  };
+              })};
+    return processReturn("updateSinkMetadata", mStream->updateSinkMetadata(halMetadata));
+}
+#endif
+
+#if MAJOR_VERSION < 5
+status_t StreamInHalHidl::setPreferredMicrophoneDirection(
+            audio_microphone_direction_t direction __unused) {
+    if (mStream == 0) return NO_INIT;
+    return INVALID_OPERATION;
+}
+
+status_t StreamInHalHidl::setPreferredMicrophoneFieldDimension(float zoom __unused) {
+    if (mStream == 0) return NO_INIT;
+    return INVALID_OPERATION;
+}
+#else
+status_t StreamInHalHidl::setPreferredMicrophoneDirection(audio_microphone_direction_t direction) {
+    if (!mStream) return NO_INIT;
+    return processReturn("setPreferredMicrophoneDirection",
+        mStream->setMicrophoneDirection(static_cast<MicrophoneDirection>(direction)));
+}
+
+status_t StreamInHalHidl::setPreferredMicrophoneFieldDimension(float zoom) {
+    if (!mStream) return NO_INIT;
+    return processReturn("setPreferredMicrophoneFieldDimension",
+                mStream->setMicrophoneFieldDimension(zoom));
+}
+#endif
+
+} // namespace CPP_VERSION
+} // namespace android
diff --git a/media/libaudiohal/impl/StreamHalHidl.h b/media/libaudiohal/impl/StreamHalHidl.h
new file mode 100644
index 0000000..f587889
--- /dev/null
+++ b/media/libaudiohal/impl/StreamHalHidl.h
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_STREAM_HAL_HIDL_H
+#define ANDROID_HARDWARE_STREAM_HAL_HIDL_H
+
+#include <atomic>
+
+#include PATH(android/hardware/audio/FILE_VERSION/IStream.h)
+#include PATH(android/hardware/audio/FILE_VERSION/IStreamIn.h)
+#include PATH(android/hardware/audio/FILE_VERSION/IStreamOut.h)
+#include <fmq/EventFlag.h>
+#include <fmq/MessageQueue.h>
+#include <media/audiohal/StreamHalInterface.h>
+
+#include "ConversionHelperHidl.h"
+#include "StreamPowerLog.h"
+
+using ::android::hardware::audio::CPP_VERSION::IStream;
+using ::android::hardware::audio::CPP_VERSION::IStreamIn;
+using ::android::hardware::audio::CPP_VERSION::IStreamOut;
+using ::android::hardware::EventFlag;
+using ::android::hardware::MessageQueue;
+using ::android::hardware::Return;
+using ReadParameters = ::android::hardware::audio::CPP_VERSION::IStreamIn::ReadParameters;
+using ReadStatus = ::android::hardware::audio::CPP_VERSION::IStreamIn::ReadStatus;
+using WriteCommand = ::android::hardware::audio::CPP_VERSION::IStreamOut::WriteCommand;
+using WriteStatus = ::android::hardware::audio::CPP_VERSION::IStreamOut::WriteStatus;
+
+namespace android {
+namespace CPP_VERSION {
+
+class DeviceHalHidl;
+
+class StreamHalHidl : public virtual StreamHalInterface, public ConversionHelperHidl
+{
+  public:
+    // Return the sampling rate in Hz - eg. 44100.
+    virtual status_t getSampleRate(uint32_t *rate);
+
+    // Return size of input/output buffer in bytes for this stream - eg. 4800.
+    virtual status_t getBufferSize(size_t *size);
+
+    // Return the channel mask.
+    virtual status_t getChannelMask(audio_channel_mask_t *mask);
+
+    // Return the audio format - e.g. AUDIO_FORMAT_PCM_16_BIT.
+    virtual status_t getFormat(audio_format_t *format);
+
+    // Convenience method.
+    virtual status_t getAudioProperties(
+            uint32_t *sampleRate, audio_channel_mask_t *mask, audio_format_t *format);
+
+    // Set audio stream parameters.
+    virtual status_t setParameters(const String8& kvPairs);
+
+    // Get audio stream parameters.
+    virtual status_t getParameters(const String8& keys, String8 *values);
+
+    // Add or remove the effect on the stream.
+    virtual status_t addEffect(sp<EffectHalInterface> effect);
+    virtual status_t removeEffect(sp<EffectHalInterface> effect);
+
+    // Put the audio hardware input/output into standby mode.
+    virtual status_t standby();
+
+    virtual status_t dump(int fd);
+
+    // Start a stream operating in mmap mode.
+    virtual status_t start();
+
+    // Stop a stream operating in mmap mode.
+    virtual status_t stop();
+
+    // Retrieve information on the data buffer in mmap mode.
+    virtual status_t createMmapBuffer(int32_t minSizeFrames,
+                                      struct audio_mmap_buffer_info *info);
+
+    // Get current read/write position in the mmap buffer
+    virtual status_t getMmapPosition(struct audio_mmap_position *position);
+
+    // Set the priority of the thread that interacts with the HAL
+    // (must match the priority of the audioflinger's thread that calls 'read' / 'write')
+    virtual status_t setHalThreadPriority(int priority);
+
+  protected:
+    // Subclasses can not be constructed directly by clients.
+    explicit StreamHalHidl(IStream *stream);
+
+    // The destructor automatically closes the stream.
+    virtual ~StreamHalHidl();
+
+    status_t getCachedBufferSize(size_t *size);
+
+    bool requestHalThreadPriority(pid_t threadPid, pid_t threadId);
+
+    // mStreamPowerLog is used for audio signal power logging.
+    StreamPowerLog mStreamPowerLog;
+
+  private:
+    const int HAL_THREAD_PRIORITY_DEFAULT = -1;
+    IStream *mStream;
+    int mHalThreadPriority;
+    size_t mCachedBufferSize;
+};
+
+class StreamOutHalHidl : public StreamOutHalInterface, public StreamHalHidl {
+  public:
+    // Return the frame size (number of bytes per sample) of a stream.
+    virtual status_t getFrameSize(size_t *size);
+
+    // Return the audio hardware driver estimated latency in milliseconds.
+    virtual status_t getLatency(uint32_t *latency);
+
+    // Use this method in situations where audio mixing is done in the hardware.
+    virtual status_t setVolume(float left, float right);
+
+    // Selects the audio presentation (if available).
+    virtual status_t selectPresentation(int presentationId, int programId);
+
+    // Write audio buffer to driver.
+    virtual status_t write(const void *buffer, size_t bytes, size_t *written);
+
+    // Return the number of audio frames written by the audio dsp to DAC since
+    // the output has exited standby.
+    virtual status_t getRenderPosition(uint32_t *dspFrames);
+
+    // Get the local time at which the next write to the audio driver will be presented.
+    virtual status_t getNextWriteTimestamp(int64_t *timestamp);
+
+    // Set the callback for notifying completion of non-blocking write and drain.
+    virtual status_t setCallback(wp<StreamOutHalInterfaceCallback> callback);
+
+    // Returns whether pause and resume operations are supported.
+    virtual status_t supportsPauseAndResume(bool *supportsPause, bool *supportsResume);
+
+    // Notifies to the audio driver to resume playback following a pause.
+    virtual status_t pause();
+
+    // Notifies to the audio driver to resume playback following a pause.
+    virtual status_t resume();
+
+    // Returns whether drain operation is supported.
+    virtual status_t supportsDrain(bool *supportsDrain);
+
+    // Requests notification when data buffered by the driver/hardware has been played.
+    virtual status_t drain(bool earlyNotify);
+
+    // Notifies to the audio driver to flush the queued data.
+    virtual status_t flush();
+
+    // Return a recent count of the number of audio frames presented to an external observer.
+    virtual status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp);
+
+    // Called when the metadata of the stream's source has been changed.
+    status_t updateSourceMetadata(const SourceMetadata& sourceMetadata) override;
+
+    // Methods used by StreamOutCallback (HIDL).
+    void onWriteReady();
+    void onDrainReady();
+    void onError();
+
+  private:
+    friend class DeviceHalHidl;
+    typedef MessageQueue<WriteCommand, hardware::kSynchronizedReadWrite> CommandMQ;
+    typedef MessageQueue<uint8_t, hardware::kSynchronizedReadWrite> DataMQ;
+    typedef MessageQueue<WriteStatus, hardware::kSynchronizedReadWrite> StatusMQ;
+
+    wp<StreamOutHalInterfaceCallback> mCallback;
+    sp<IStreamOut> mStream;
+    std::unique_ptr<CommandMQ> mCommandMQ;
+    std::unique_ptr<DataMQ> mDataMQ;
+    std::unique_ptr<StatusMQ> mStatusMQ;
+    std::atomic<pid_t> mWriterClient;
+    EventFlag* mEfGroup;
+
+    // Can not be constructed directly by clients.
+    StreamOutHalHidl(const sp<IStreamOut>& stream);
+
+    virtual ~StreamOutHalHidl();
+
+    using WriterCallback = std::function<void(const WriteStatus& writeStatus)>;
+    status_t callWriterThread(
+            WriteCommand cmd, const char* cmdName,
+            const uint8_t* data, size_t dataSize, WriterCallback callback);
+    status_t prepareForWriting(size_t bufferSize);
+};
+
+class StreamInHalHidl : public StreamInHalInterface, public StreamHalHidl {
+  public:
+    // Return the frame size (number of bytes per sample) of a stream.
+    virtual status_t getFrameSize(size_t *size);
+
+    // Set the input gain for the audio driver.
+    virtual status_t setGain(float gain);
+
+    // Read audio buffer in from driver.
+    virtual status_t read(void *buffer, size_t bytes, size_t *read);
+
+    // Return the amount of input frames lost in the audio driver.
+    virtual status_t getInputFramesLost(uint32_t *framesLost);
+
+    // Return a recent count of the number of audio frames received and
+    // the clock time associated with that frame count.
+    virtual status_t getCapturePosition(int64_t *frames, int64_t *time);
+
+    // Get active microphones
+    virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+
+    // Set microphone direction (for processing)
+    virtual status_t setPreferredMicrophoneDirection(
+                            audio_microphone_direction_t direction) override;
+
+    // Set microphone zoom (for processing)
+    virtual status_t setPreferredMicrophoneFieldDimension(float zoom) override;
+
+    // Called when the metadata of the stream's sink has been changed.
+    status_t updateSinkMetadata(const SinkMetadata& sinkMetadata) override;
+
+  private:
+    friend class DeviceHalHidl;
+    typedef MessageQueue<ReadParameters, hardware::kSynchronizedReadWrite> CommandMQ;
+    typedef MessageQueue<uint8_t, hardware::kSynchronizedReadWrite> DataMQ;
+    typedef MessageQueue<ReadStatus, hardware::kSynchronizedReadWrite> StatusMQ;
+
+    sp<IStreamIn> mStream;
+    std::unique_ptr<CommandMQ> mCommandMQ;
+    std::unique_ptr<DataMQ> mDataMQ;
+    std::unique_ptr<StatusMQ> mStatusMQ;
+    std::atomic<pid_t> mReaderClient;
+    EventFlag* mEfGroup;
+
+    // Can not be constructed directly by clients.
+    StreamInHalHidl(const sp<IStreamIn>& stream);
+
+    virtual ~StreamInHalHidl();
+
+    using ReaderCallback = std::function<void(const ReadStatus& readStatus)>;
+    status_t callReaderThread(
+            const ReadParameters& params, const char* cmdName, ReaderCallback callback);
+    status_t prepareForReading(size_t bufferSize);
+};
+
+} // namespace CPP_VERSION
+} // namespace android
+
+#endif // ANDROID_HARDWARE_STREAM_HAL_HIDL_H
diff --git a/media/libaudiohal/impl/StreamHalLocal.cpp b/media/libaudiohal/impl/StreamHalLocal.cpp
new file mode 100644
index 0000000..4818fd8
--- /dev/null
+++ b/media/libaudiohal/impl/StreamHalLocal.cpp
@@ -0,0 +1,396 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "StreamHalLocal"
+//#define LOG_NDEBUG 0
+
+#include <hardware/audio.h>
+#include <media/AudioParameter.h>
+#include <utils/Log.h>
+
+#include "DeviceHalLocal.h"
+#include "StreamHalLocal.h"
+#include "VersionUtils.h"
+
+namespace android {
+namespace CPP_VERSION {
+
+StreamHalLocal::StreamHalLocal(audio_stream_t *stream, sp<DeviceHalLocal> device)
+        : mDevice(device),
+          mStream(stream) {
+    // Instrument audio signal power logging.
+    // Note: This assumes channel mask, format, and sample rate do not change after creation.
+    if (mStream != nullptr /* && mStreamPowerLog.isUserDebugOrEngBuild() */) {
+        mStreamPowerLog.init(mStream->get_sample_rate(mStream),
+                mStream->get_channels(mStream),
+                mStream->get_format(mStream));
+    }
+}
+
+StreamHalLocal::~StreamHalLocal() {
+    mStream = 0;
+    mDevice.clear();
+}
+
+status_t StreamHalLocal::getSampleRate(uint32_t *rate) {
+    *rate = mStream->get_sample_rate(mStream);
+    return OK;
+}
+
+status_t StreamHalLocal::getBufferSize(size_t *size) {
+    *size = mStream->get_buffer_size(mStream);
+    return OK;
+}
+
+status_t StreamHalLocal::getChannelMask(audio_channel_mask_t *mask) {
+    *mask = mStream->get_channels(mStream);
+    return OK;
+}
+
+status_t StreamHalLocal::getFormat(audio_format_t *format) {
+    *format = mStream->get_format(mStream);
+    return OK;
+}
+
+status_t StreamHalLocal::getAudioProperties(
+        uint32_t *sampleRate, audio_channel_mask_t *mask, audio_format_t *format) {
+    *sampleRate = mStream->get_sample_rate(mStream);
+    *mask = mStream->get_channels(mStream);
+    *format = mStream->get_format(mStream);
+    return OK;
+}
+
+status_t StreamHalLocal::setParameters(const String8& kvPairs) {
+    return mStream->set_parameters(mStream, kvPairs.string());
+}
+
+status_t StreamHalLocal::getParameters(const String8& keys, String8 *values) {
+    char *halValues = mStream->get_parameters(mStream, keys.string());
+    if (halValues != NULL) {
+        values->setTo(halValues);
+        free(halValues);
+    } else {
+        values->clear();
+    }
+    return OK;
+}
+
+status_t StreamHalLocal::addEffect(sp<EffectHalInterface>) {
+    LOG_ALWAYS_FATAL("Local streams can not have effects");
+    return INVALID_OPERATION;
+}
+
+status_t StreamHalLocal::removeEffect(sp<EffectHalInterface>) {
+    LOG_ALWAYS_FATAL("Local streams can not have effects");
+    return INVALID_OPERATION;
+}
+
+status_t StreamHalLocal::standby() {
+    return mStream->standby(mStream);
+}
+
+status_t StreamHalLocal::dump(int fd) {
+    status_t status = mStream->dump(mStream, fd);
+    mStreamPowerLog.dump(fd);
+    return status;
+}
+
+status_t StreamHalLocal::setHalThreadPriority(int) {
+    // Don't need to do anything as local hal is executed by audioflinger directly
+    // on the same thread.
+    return OK;
+}
+
+StreamOutHalLocal::StreamOutHalLocal(audio_stream_out_t *stream, sp<DeviceHalLocal> device)
+        : StreamHalLocal(&stream->common, device), mStream(stream) {
+}
+
+StreamOutHalLocal::~StreamOutHalLocal() {
+    mCallback.clear();
+    mDevice->closeOutputStream(mStream);
+    mStream = 0;
+}
+
+status_t StreamOutHalLocal::getFrameSize(size_t *size) {
+    *size = audio_stream_out_frame_size(mStream);
+    return OK;
+}
+
+status_t StreamOutHalLocal::getLatency(uint32_t *latency) {
+    *latency = mStream->get_latency(mStream);
+    return OK;
+}
+
+status_t StreamOutHalLocal::setVolume(float left, float right) {
+    if (mStream->set_volume == NULL) return INVALID_OPERATION;
+    return mStream->set_volume(mStream, left, right);
+}
+
+status_t StreamOutHalLocal::selectPresentation(int presentationId, int programId) {
+    AudioParameter param;
+    param.addInt(String8(AudioParameter::keyPresentationId), presentationId);
+    param.addInt(String8(AudioParameter::keyProgramId), programId);
+    return setParameters(param.toString());
+}
+
+status_t StreamOutHalLocal::write(const void *buffer, size_t bytes, size_t *written) {
+    ssize_t writeResult = mStream->write(mStream, buffer, bytes);
+    if (writeResult > 0) {
+        *written = writeResult;
+        mStreamPowerLog.log(buffer, *written);
+        return OK;
+    } else {
+        *written = 0;
+        return writeResult;
+    }
+}
+
+status_t StreamOutHalLocal::getRenderPosition(uint32_t *dspFrames) {
+    return mStream->get_render_position(mStream, dspFrames);
+}
+
+status_t StreamOutHalLocal::getNextWriteTimestamp(int64_t *timestamp) {
+    if (mStream->get_next_write_timestamp == NULL) return INVALID_OPERATION;
+    return mStream->get_next_write_timestamp(mStream, timestamp);
+}
+
+status_t StreamOutHalLocal::setCallback(wp<StreamOutHalInterfaceCallback> callback) {
+    if (mStream->set_callback == NULL) return INVALID_OPERATION;
+    status_t result = mStream->set_callback(mStream, StreamOutHalLocal::asyncCallback, this);
+    if (result == OK) {
+        mCallback = callback;
+    }
+    return result;
+}
+
+// static
+int StreamOutHalLocal::asyncCallback(stream_callback_event_t event, void*, void *cookie) {
+    // We act as if we gave a wp<StreamOutHalLocal> to HAL. This way we should handle
+    // correctly the case when the callback is invoked while StreamOutHalLocal's destructor is
+    // already running, because the destructor is invoked after the refcount has been atomically
+    // decremented.
+    wp<StreamOutHalLocal> weakSelf(static_cast<StreamOutHalLocal*>(cookie));
+    sp<StreamOutHalLocal> self = weakSelf.promote();
+    if (self == 0) return 0;
+    sp<StreamOutHalInterfaceCallback> callback = self->mCallback.promote();
+    if (callback == 0) return 0;
+    ALOGV("asyncCallback() event %d", event);
+    switch (event) {
+        case STREAM_CBK_EVENT_WRITE_READY:
+            callback->onWriteReady();
+            break;
+        case STREAM_CBK_EVENT_DRAIN_READY:
+            callback->onDrainReady();
+            break;
+        case STREAM_CBK_EVENT_ERROR:
+            callback->onError();
+            break;
+        default:
+            ALOGW("asyncCallback() unknown event %d", event);
+            break;
+    }
+    return 0;
+}
+
+status_t StreamOutHalLocal::supportsPauseAndResume(bool *supportsPause, bool *supportsResume) {
+    *supportsPause = mStream->pause != NULL;
+    *supportsResume = mStream->resume != NULL;
+    return OK;
+}
+
+status_t StreamOutHalLocal::pause() {
+    if (mStream->pause == NULL) return INVALID_OPERATION;
+    return mStream->pause(mStream);
+}
+
+status_t StreamOutHalLocal::resume() {
+    if (mStream->resume == NULL) return INVALID_OPERATION;
+    return mStream->resume(mStream);
+}
+
+status_t StreamOutHalLocal::supportsDrain(bool *supportsDrain) {
+    *supportsDrain = mStream->drain != NULL;
+    return OK;
+}
+
+status_t StreamOutHalLocal::drain(bool earlyNotify) {
+    if (mStream->drain == NULL) return INVALID_OPERATION;
+    return mStream->drain(mStream, earlyNotify ? AUDIO_DRAIN_EARLY_NOTIFY : AUDIO_DRAIN_ALL);
+}
+
+status_t StreamOutHalLocal::flush() {
+    if (mStream->flush == NULL) return INVALID_OPERATION;
+    return mStream->flush(mStream);
+}
+
+status_t StreamOutHalLocal::getPresentationPosition(uint64_t *frames, struct timespec *timestamp) {
+    if (mStream->get_presentation_position == NULL) return INVALID_OPERATION;
+    return mStream->get_presentation_position(mStream, frames, timestamp);
+}
+
+status_t StreamOutHalLocal::updateSourceMetadata(const SourceMetadata& sourceMetadata) {
+    if (mStream->update_source_metadata == nullptr) {
+        return INVALID_OPERATION;
+    }
+    const source_metadata_t metadata {
+        .track_count = sourceMetadata.tracks.size(),
+        // const cast is fine as it is in a const structure
+        .tracks = const_cast<playback_track_metadata*>(sourceMetadata.tracks.data()),
+    };
+    mStream->update_source_metadata(mStream, &metadata);
+    return OK;
+}
+
+status_t StreamOutHalLocal::start() {
+    if (mStream->start == NULL) return INVALID_OPERATION;
+    return mStream->start(mStream);
+}
+
+status_t StreamOutHalLocal::stop() {
+    if (mStream->stop == NULL) return INVALID_OPERATION;
+    return mStream->stop(mStream);
+}
+
+status_t StreamOutHalLocal::createMmapBuffer(int32_t minSizeFrames,
+                                  struct audio_mmap_buffer_info *info) {
+    if (mStream->create_mmap_buffer == NULL) return INVALID_OPERATION;
+    return mStream->create_mmap_buffer(mStream, minSizeFrames, info);
+}
+
+status_t StreamOutHalLocal::getMmapPosition(struct audio_mmap_position *position) {
+    if (mStream->get_mmap_position == NULL) return INVALID_OPERATION;
+    return mStream->get_mmap_position(mStream, position);
+}
+
+StreamInHalLocal::StreamInHalLocal(audio_stream_in_t *stream, sp<DeviceHalLocal> device)
+        : StreamHalLocal(&stream->common, device), mStream(stream) {
+}
+
+StreamInHalLocal::~StreamInHalLocal() {
+    mDevice->closeInputStream(mStream);
+    mStream = 0;
+}
+
+status_t StreamInHalLocal::getFrameSize(size_t *size) {
+    *size = audio_stream_in_frame_size(mStream);
+    return OK;
+}
+
+status_t StreamInHalLocal::setGain(float gain) {
+    return mStream->set_gain(mStream, gain);
+}
+
+status_t StreamInHalLocal::read(void *buffer, size_t bytes, size_t *read) {
+    ssize_t readResult = mStream->read(mStream, buffer, bytes);
+    if (readResult > 0) {
+        *read = readResult;
+        mStreamPowerLog.log( buffer, *read);
+        return OK;
+    } else {
+        *read = 0;
+        return readResult;
+    }
+}
+
+status_t StreamInHalLocal::getInputFramesLost(uint32_t *framesLost) {
+    *framesLost = mStream->get_input_frames_lost(mStream);
+    return OK;
+}
+
+status_t StreamInHalLocal::getCapturePosition(int64_t *frames, int64_t *time) {
+    if (mStream->get_capture_position == NULL) return INVALID_OPERATION;
+    return mStream->get_capture_position(mStream, frames, time);
+}
+
+status_t StreamInHalLocal::updateSinkMetadata(const SinkMetadata& sinkMetadata) {
+    if (mStream->update_sink_metadata == nullptr) {
+        return INVALID_OPERATION;
+    }
+    const sink_metadata_t metadata {
+        .track_count = sinkMetadata.tracks.size(),
+        // const cast is fine as it is in a const structure
+        .tracks = const_cast<record_track_metadata*>(sinkMetadata.tracks.data()),
+    };
+    mStream->update_sink_metadata(mStream, &metadata);
+    return OK;
+}
+
+status_t StreamInHalLocal::start() {
+    if (mStream->start == NULL) return INVALID_OPERATION;
+    return mStream->start(mStream);
+}
+
+status_t StreamInHalLocal::stop() {
+    if (mStream->stop == NULL) return INVALID_OPERATION;
+    return mStream->stop(mStream);
+}
+
+status_t StreamInHalLocal::createMmapBuffer(int32_t minSizeFrames,
+                                  struct audio_mmap_buffer_info *info) {
+    if (mStream->create_mmap_buffer == NULL) return INVALID_OPERATION;
+    return mStream->create_mmap_buffer(mStream, minSizeFrames, info);
+}
+
+status_t StreamInHalLocal::getMmapPosition(struct audio_mmap_position *position) {
+    if (mStream->get_mmap_position == NULL) return INVALID_OPERATION;
+    return mStream->get_mmap_position(mStream, position);
+}
+
+#if MAJOR_VERSION == 2
+status_t StreamInHalLocal::getActiveMicrophones(
+        std::vector<media::MicrophoneInfo> *microphones __unused) {
+    return INVALID_OPERATION;
+}
+#elif MAJOR_VERSION >= 4
+status_t StreamInHalLocal::getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones) {
+    if (mStream->get_active_microphones == NULL) return INVALID_OPERATION;
+    size_t actual_mics = AUDIO_MICROPHONE_MAX_COUNT;
+    audio_microphone_characteristic_t mic_array[AUDIO_MICROPHONE_MAX_COUNT];
+    status_t status = mStream->get_active_microphones(mStream, &mic_array[0], &actual_mics);
+    for (size_t i = 0; i < actual_mics; i++) {
+        media::MicrophoneInfo microphoneInfo = media::MicrophoneInfo(mic_array[i]);
+        microphones->push_back(microphoneInfo);
+    }
+    return status;
+}
+#endif
+
+#if MAJOR_VERSION < 5
+status_t StreamInHalLocal::setPreferredMicrophoneDirection(
+            audio_microphone_direction_t direction __unused) {
+    return INVALID_OPERATION;
+}
+
+status_t StreamInHalLocal::setPreferredMicrophoneFieldDimension(float zoom __unused) {
+    return INVALID_OPERATION;
+}
+#else
+status_t StreamInHalLocal::setPreferredMicrophoneDirection(audio_microphone_direction_t direction) {
+    if (mStream->set_microphone_direction == NULL) return INVALID_OPERATION;
+    return mStream->set_microphone_direction(mStream, direction);
+}
+
+status_t StreamInHalLocal::setPreferredMicrophoneFieldDimension(float zoom) {
+    if (mStream->set_microphone_field_dimension == NULL) return INVALID_OPERATION;
+    return mStream->set_microphone_field_dimension(mStream, zoom);
+
+}
+#endif
+
+} // namespace CPP_VERSION
+} // namespace android
+
+
diff --git a/media/libaudiohal/impl/StreamHalLocal.h b/media/libaudiohal/impl/StreamHalLocal.h
new file mode 100644
index 0000000..34f2bd8
--- /dev/null
+++ b/media/libaudiohal/impl/StreamHalLocal.h
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_STREAM_HAL_LOCAL_H
+#define ANDROID_HARDWARE_STREAM_HAL_LOCAL_H
+
+#include <media/audiohal/StreamHalInterface.h>
+#include "StreamPowerLog.h"
+
+namespace android {
+namespace CPP_VERSION {
+
+class DeviceHalLocal;
+
+class StreamHalLocal : public virtual StreamHalInterface
+{
+  public:
+    // Return the sampling rate in Hz - eg. 44100.
+    virtual status_t getSampleRate(uint32_t *rate);
+
+    // Return size of input/output buffer in bytes for this stream - eg. 4800.
+    virtual status_t getBufferSize(size_t *size);
+
+    // Return the channel mask.
+    virtual status_t getChannelMask(audio_channel_mask_t *mask);
+
+    // Return the audio format - e.g. AUDIO_FORMAT_PCM_16_BIT.
+    virtual status_t getFormat(audio_format_t *format);
+
+    // Convenience method.
+    virtual status_t getAudioProperties(
+            uint32_t *sampleRate, audio_channel_mask_t *mask, audio_format_t *format);
+
+    // Set audio stream parameters.
+    virtual status_t setParameters(const String8& kvPairs);
+
+    // Get audio stream parameters.
+    virtual status_t getParameters(const String8& keys, String8 *values);
+
+    // Add or remove the effect on the stream.
+    virtual status_t addEffect(sp<EffectHalInterface> effect);
+    virtual status_t removeEffect(sp<EffectHalInterface> effect);
+
+    // Put the audio hardware input/output into standby mode.
+    virtual status_t standby();
+
+    virtual status_t dump(int fd);
+
+    // Start a stream operating in mmap mode.
+    virtual status_t start() = 0;
+
+    // Stop a stream operating in mmap mode.
+    virtual status_t stop() = 0;
+
+    // Retrieve information on the data buffer in mmap mode.
+    virtual status_t createMmapBuffer(int32_t minSizeFrames,
+                                      struct audio_mmap_buffer_info *info) = 0;
+
+    // Get current read/write position in the mmap buffer
+    virtual status_t getMmapPosition(struct audio_mmap_position *position) = 0;
+
+    // Set the priority of the thread that interacts with the HAL
+    // (must match the priority of the audioflinger's thread that calls 'read' / 'write')
+    virtual status_t setHalThreadPriority(int priority);
+
+  protected:
+    // Subclasses can not be constructed directly by clients.
+    StreamHalLocal(audio_stream_t *stream, sp<DeviceHalLocal> device);
+
+    // The destructor automatically closes the stream.
+    virtual ~StreamHalLocal();
+
+    sp<DeviceHalLocal> mDevice;
+
+    // mStreamPowerLog is used for audio signal power logging.
+    StreamPowerLog mStreamPowerLog;
+
+  private:
+    audio_stream_t *mStream;
+};
+
+class StreamOutHalLocal : public StreamOutHalInterface, public StreamHalLocal {
+  public:
+    // Return the frame size (number of bytes per sample) of a stream.
+    virtual status_t getFrameSize(size_t *size);
+
+    // Return the audio hardware driver estimated latency in milliseconds.
+    virtual status_t getLatency(uint32_t *latency);
+
+    // Use this method in situations where audio mixing is done in the hardware.
+    virtual status_t setVolume(float left, float right);
+
+    // Selects the audio presentation (if available).
+    virtual status_t selectPresentation(int presentationId, int programId);
+
+    // Write audio buffer to driver.
+    virtual status_t write(const void *buffer, size_t bytes, size_t *written);
+
+    // Return the number of audio frames written by the audio dsp to DAC since
+    // the output has exited standby.
+    virtual status_t getRenderPosition(uint32_t *dspFrames);
+
+    // Get the local time at which the next write to the audio driver will be presented.
+    virtual status_t getNextWriteTimestamp(int64_t *timestamp);
+
+    // Set the callback for notifying completion of non-blocking write and drain.
+    virtual status_t setCallback(wp<StreamOutHalInterfaceCallback> callback);
+
+    // Returns whether pause and resume operations are supported.
+    virtual status_t supportsPauseAndResume(bool *supportsPause, bool *supportsResume);
+
+    // Notifies to the audio driver to resume playback following a pause.
+    virtual status_t pause();
+
+    // Notifies to the audio driver to resume playback following a pause.
+    virtual status_t resume();
+
+    // Returns whether drain operation is supported.
+    virtual status_t supportsDrain(bool *supportsDrain);
+
+    // Requests notification when data buffered by the driver/hardware has been played.
+    virtual status_t drain(bool earlyNotify);
+
+    // Notifies to the audio driver to flush the queued data.
+    virtual status_t flush();
+
+    // Return a recent count of the number of audio frames presented to an external observer.
+    virtual status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp);
+
+    // Start a stream operating in mmap mode.
+    virtual status_t start();
+
+    // Stop a stream operating in mmap mode.
+    virtual status_t stop();
+
+    // Retrieve information on the data buffer in mmap mode.
+    virtual status_t createMmapBuffer(int32_t minSizeFrames,
+                                      struct audio_mmap_buffer_info *info);
+
+    // Get current read/write position in the mmap buffer
+    virtual status_t getMmapPosition(struct audio_mmap_position *position);
+
+    // Called when the metadata of the stream's source has been changed.
+    status_t updateSourceMetadata(const SourceMetadata& sourceMetadata) override;
+
+  private:
+    audio_stream_out_t *mStream;
+    wp<StreamOutHalInterfaceCallback> mCallback;
+
+    friend class DeviceHalLocal;
+
+    // Can not be constructed directly by clients.
+    StreamOutHalLocal(audio_stream_out_t *stream, sp<DeviceHalLocal> device);
+
+    virtual ~StreamOutHalLocal();
+
+    static int asyncCallback(stream_callback_event_t event, void *param, void *cookie);
+};
+
+class StreamInHalLocal : public StreamInHalInterface, public StreamHalLocal {
+  public:
+    // Return the frame size (number of bytes per sample) of a stream.
+    virtual status_t getFrameSize(size_t *size);
+
+    // Set the input gain for the audio driver.
+    virtual status_t setGain(float gain);
+
+    // Read audio buffer in from driver.
+    virtual status_t read(void *buffer, size_t bytes, size_t *read);
+
+    // Return the amount of input frames lost in the audio driver.
+    virtual status_t getInputFramesLost(uint32_t *framesLost);
+
+    // Return a recent count of the number of audio frames received and
+    // the clock time associated with that frame count.
+    virtual status_t getCapturePosition(int64_t *frames, int64_t *time);
+
+    // Start a stream operating in mmap mode.
+    virtual status_t start();
+
+    // Stop a stream operating in mmap mode.
+    virtual status_t stop();
+
+    // Retrieve information on the data buffer in mmap mode.
+    virtual status_t createMmapBuffer(int32_t minSizeFrames,
+                                      struct audio_mmap_buffer_info *info);
+
+    // Get current read/write position in the mmap buffer
+    virtual status_t getMmapPosition(struct audio_mmap_position *position);
+
+    // Get active microphones
+    virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+
+    // Sets microphone direction (for processing)
+    virtual status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction);
+
+    // Sets microphone zoom (for processing)
+    virtual status_t setPreferredMicrophoneFieldDimension(float zoom);
+
+    // Called when the metadata of the stream's sink has been changed.
+    status_t updateSinkMetadata(const SinkMetadata& sinkMetadata) override;
+
+  private:
+    audio_stream_in_t *mStream;
+
+    friend class DeviceHalLocal;
+
+    // Can not be constructed directly by clients.
+    StreamInHalLocal(audio_stream_in_t *stream, sp<DeviceHalLocal> device);
+
+    virtual ~StreamInHalLocal();
+};
+
+} // namespace CPP_VERSION
+} // namespace android
+
+#endif // ANDROID_HARDWARE_STREAM_HAL_LOCAL_H
diff --git a/media/libaudiohal/impl/StreamPowerLog.h b/media/libaudiohal/impl/StreamPowerLog.h
new file mode 100644
index 0000000..5fd3912
--- /dev/null
+++ b/media/libaudiohal/impl/StreamPowerLog.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_STREAM_POWER_LOG_H
+#define ANDROID_HARDWARE_STREAM_POWER_LOG_H
+
+#include <audio_utils/clock.h>
+#include <audio_utils/PowerLog.h>
+#include <cutils/properties.h>
+#include <system/audio.h>
+
+namespace android {
+namespace CPP_VERSION {
+
+class StreamPowerLog {
+public:
+    StreamPowerLog() :
+        mIsUserDebugOrEngBuild(is_userdebug_or_eng_build()),
+        mPowerLog(nullptr),
+        mFrameSize(0) {
+        // use init() to set up the power log.
+    }
+
+    ~StreamPowerLog() {
+        power_log_destroy(mPowerLog); // OK for null mPowerLog
+        mPowerLog = nullptr;
+    }
+
+    // A one-time initialization (do not call twice) before using StreamPowerLog.
+    void init(uint32_t sampleRate, audio_channel_mask_t channelMask, audio_format_t format) {
+        if (mPowerLog == nullptr) {
+            // Note: A way to get channel count for both input and output channel masks
+            // but does not check validity of the channel mask.
+            const uint32_t channelCount = popcount(audio_channel_mask_get_bits(channelMask));
+            mFrameSize = channelCount * audio_bytes_per_sample(format);
+            if (mFrameSize > 0) {
+                const size_t kPowerLogFramesPerEntry =
+                        (long long)sampleRate * kPowerLogSamplingIntervalMs / 1000;
+                mPowerLog = power_log_create(
+                        sampleRate,
+                        channelCount,
+                        format,
+                        kPowerLogEntries,
+                        kPowerLogFramesPerEntry);
+            }
+        }
+        // mPowerLog may be NULL (not the right build, format not accepted, etc.).
+    }
+
+    // Dump the power log to fd.
+    void dump(int fd) const {
+        // OK for null mPowerLog
+        (void)power_log_dump(
+                mPowerLog, fd, "      " /* prefix */, kPowerLogLines, 0 /* limit_ns */);
+    }
+
+    // Log the audio data contained in buffer.
+    void log(const void *buffer, size_t sizeInBytes) const {
+        if (mPowerLog != nullptr) { // mFrameSize is always nonzero if mPowerLog exists.
+            power_log_log(
+                    mPowerLog, buffer, sizeInBytes / mFrameSize, audio_utils_get_real_time_ns());
+        }
+    }
+
+    bool isUserDebugOrEngBuild() const {
+        return mIsUserDebugOrEngBuild;
+    }
+
+private:
+
+    static inline bool is_userdebug_or_eng_build() {
+        char value[PROPERTY_VALUE_MAX];
+        (void)property_get("ro.build.type", value, "unknown"); // ignore actual length
+        return strcmp(value, "userdebug") == 0 || strcmp(value, "eng") == 0;
+    }
+
+    // Audio signal power log configuration.
+    static const size_t kPowerLogLines = 40;
+    static const size_t kPowerLogSamplingIntervalMs = 50;
+    static const size_t kPowerLogEntries = (1 /* minutes */ * 60 /* seconds */ * 1000 /* msec */
+            / kPowerLogSamplingIntervalMs);
+
+    const bool mIsUserDebugOrEngBuild;
+    power_log_t *mPowerLog;
+    size_t mFrameSize;
+};
+
+} // namespace CPP_VERSION
+} // namespace android
+
+#endif // ANDROID_HARDWARE_STREAM_POWER_LOG_H
diff --git a/media/libaudiohal/impl/VersionUtils.h b/media/libaudiohal/impl/VersionUtils.h
new file mode 100644
index 0000000..eb0a42a
--- /dev/null
+++ b/media/libaudiohal/impl/VersionUtils.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_VERSION_UTILS_H
+#define ANDROID_HARDWARE_VERSION_UTILS_H
+
+#include PATH(android/hardware/audio/FILE_VERSION/types.h)
+#include <hidl/HidlSupport.h>
+
+using ::android::hardware::audio::CPP_VERSION::ParameterValue;
+using ::android::hardware::audio::CPP_VERSION::Result;
+using ::android::hardware::Return;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+
+namespace android {
+namespace CPP_VERSION {
+namespace utils {
+
+#if MAJOR_VERSION == 2
+template <class T, class Callback>
+Return<void> getParameters(T& object, hidl_vec<ParameterValue> /*context*/,
+                           hidl_vec<hidl_string> keys, Callback callback) {
+    return object->getParameters(keys, callback);
+}
+
+template <class T>
+Return<Result> setParameters(T& object, hidl_vec<ParameterValue> /*context*/,
+                             hidl_vec<ParameterValue> keys) {
+    return object->setParameters(keys);
+}
+#elif MAJOR_VERSION >= 4
+template <class T, class Callback>
+Return<void> getParameters(T& object, hidl_vec<ParameterValue> context,
+                           hidl_vec<hidl_string> keys, Callback callback) {
+    return object->getParameters(context, keys, callback);
+}
+
+template <class T>
+Return<Result> setParameters(T& object, hidl_vec<ParameterValue> context,
+                             hidl_vec<ParameterValue> keys) {
+    return object->setParameters(context, keys);
+}
+#endif
+
+} // namespace utils
+} // namespace CPP_VERSION
+} // namespace android
+
+#endif // ANDROID_HARDWARE_VERSION_UTILS_H
diff --git a/media/libaudiohal/impl/include/libaudiohal/FactoryHalHidl.h b/media/libaudiohal/impl/include/libaudiohal/FactoryHalHidl.h
new file mode 100644
index 0000000..c7319d0
--- /dev/null
+++ b/media/libaudiohal/impl/include/libaudiohal/FactoryHalHidl.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_FACTORY_HAL_HIDL_H
+#define ANDROID_HARDWARE_FACTORY_HAL_HIDL_H
+
+/** @file Library entry points to create the HAL factories. */
+
+#include <media/audiohal/DevicesFactoryHalInterface.h>
+#include <media/audiohal/EffectsFactoryHalInterface.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+namespace effect {
+namespace V2_0 {
+sp<EffectsFactoryHalInterface> createEffectsFactoryHal();
+} // namespace V2_0
+
+namespace V4_0 {
+sp<EffectsFactoryHalInterface> createEffectsFactoryHal();
+} // namespace V4_0
+
+namespace V5_0 {
+sp<EffectsFactoryHalInterface> createEffectsFactoryHal();
+} // namespace V5_0
+} // namespace effect
+
+namespace V2_0 {
+sp<DevicesFactoryHalInterface> createDevicesFactoryHal();
+} // namespace V2_0
+
+namespace V4_0 {
+sp<DevicesFactoryHalInterface> createDevicesFactoryHal();
+} // namespace V4_0
+
+namespace V5_0 {
+sp<DevicesFactoryHalInterface> createDevicesFactoryHal();
+} // namespace V5_0
+
+} // namespace android
+
+#endif // ANDROID_HARDWARE_FACTORY_HAL_HIDL_H
diff --git a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
index 7de8eb3..e565237 100644
--- a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
@@ -84,6 +84,8 @@
             audio_input_flags_t flags,
             const char *address,
             audio_source_t source,
+            audio_devices_t outputDevice,
+            const char *outputDeviceAddress,
             sp<StreamInHalInterface> *inStream) = 0;
 
     // Returns whether createAudioPatch and releaseAudioPatch operations are supported.
diff --git a/media/libaudiohal/include/media/audiohal/EffectHalInterface.h b/media/libaudiohal/include/media/audiohal/EffectHalInterface.h
index 92622aa..03165bd 100644
--- a/media/libaudiohal/include/media/audiohal/EffectHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/EffectHalInterface.h
@@ -55,6 +55,8 @@
     // Whether it's a local implementation.
     virtual bool isLocal() const = 0;
 
+    virtual status_t dump(int fd) = 0;
+
   protected:
     // Subclasses can not be constructed directly by clients.
     EffectHalInterface() {}
diff --git a/media/libaudiohal/include/media/audiohal/StreamHalInterface.h b/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
index c969e28..6c3b21c 100644
--- a/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
@@ -109,6 +109,9 @@
     // Use this method in situations where audio mixing is done in the hardware.
     virtual status_t setVolume(float left, float right) = 0;
 
+    // Selects the audio presentation (if available).
+    virtual status_t selectPresentation(int presentationId, int programId) = 0;
+
     // Write audio buffer to driver.
     virtual status_t write(const void *buffer, size_t bytes, size_t *written) = 0;
 
@@ -176,6 +179,12 @@
     // Get active microphones
     virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones) = 0;
 
+    // Set direction for capture processing
+    virtual status_t setPreferredMicrophoneDirection(audio_microphone_direction_t) = 0;
+
+    // Set zoom factor for capture stream
+    virtual status_t setPreferredMicrophoneFieldDimension(float zoom) = 0;
+
     struct SinkMetadata {
         std::vector<record_track_metadata_t> tracks;
     };
diff --git a/media/libaudioprocessing/Android.bp b/media/libaudioprocessing/Android.bp
new file mode 100644
index 0000000..cb78063
--- /dev/null
+++ b/media/libaudioprocessing/Android.bp
@@ -0,0 +1,59 @@
+cc_defaults {
+    name: "libaudioprocessing_defaults",
+
+    export_include_dirs: ["include"],
+
+    shared_libs: [
+        "libaudiohal",
+        "libaudioutils",
+        "libcutils",
+        "liblog",
+        "libnbaio",
+        "libnblog",
+        "libsonic",
+        "libutils",
+        "libvibrator",
+    ],
+
+    header_libs: [
+        "libbase_headers",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+
+        // uncomment to disable NEON on architectures that actually do support NEON, for benchmarking
+        // "-DUSE_NEON=false",
+    ],
+}
+
+cc_library_shared {
+    name: "libaudioprocessing",
+    defaults: ["libaudioprocessing_defaults"],
+
+    srcs: [
+        "BufferProviders.cpp",
+        "RecordBufferConverter.cpp",
+    ],
+    whole_static_libs: ["libaudioprocessing_arm"],
+}
+
+cc_library_static {
+    name: "libaudioprocessing_arm",
+    defaults: ["libaudioprocessing_defaults"],
+
+    srcs: [
+        "AudioMixer.cpp",
+        "AudioResampler.cpp",
+        "AudioResamplerCubic.cpp",
+        "AudioResamplerSinc.cpp",
+        "AudioResamplerDyn.cpp",
+    ],
+
+    arch: {
+        arm: {
+            instruction_set: "arm",
+        },
+    },
+}
diff --git a/media/libaudioprocessing/Android.mk b/media/libaudioprocessing/Android.mk
deleted file mode 100644
index da1ecc2..0000000
--- a/media/libaudioprocessing/Android.mk
+++ /dev/null
@@ -1,40 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-    AudioMixer.cpp.arm \
-    AudioResampler.cpp.arm \
-    AudioResamplerCubic.cpp.arm \
-    AudioResamplerSinc.cpp.arm \
-    AudioResamplerDyn.cpp.arm \
-    BufferProviders.cpp \
-    RecordBufferConverter.cpp \
-
-LOCAL_C_INCLUDES := \
-    $(TOP) \
-    $(call include-path-for, audio-utils) \
-    $(LOCAL_PATH)/include \
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-
-LOCAL_SHARED_LIBRARIES := \
-    libaudiohal \
-    libaudioutils \
-    libcutils \
-    liblog \
-    libnbaio \
-    libnblog \
-    libsonic \
-    libutils \
-
-LOCAL_MODULE := libaudioprocessing
-
-LOCAL_CFLAGS := -Werror -Wall
-
-# uncomment to disable NEON on architectures that actually do support NEON, for benchmarking
-#LOCAL_CFLAGS += -DUSE_NEON=false
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/media/libaudioprocessing/AudioMixer.cpp b/media/libaudioprocessing/AudioMixer.cpp
index f6f817a..f7cc096 100644
--- a/media/libaudioprocessing/AudioMixer.cpp
+++ b/media/libaudioprocessing/AudioMixer.cpp
@@ -113,10 +113,10 @@
         // Integer volume.
         // Currently integer volume is kept for the legacy integer mixer.
         // Will be removed when the legacy mixer path is removed.
-        t->volume[0] = UNITY_GAIN_INT;
-        t->volume[1] = UNITY_GAIN_INT;
-        t->prevVolume[0] = UNITY_GAIN_INT << 16;
-        t->prevVolume[1] = UNITY_GAIN_INT << 16;
+        t->volume[0] = 0;
+        t->volume[1] = 0;
+        t->prevVolume[0] = 0 << 16;
+        t->prevVolume[1] = 0 << 16;
         t->volumeInc[0] = 0;
         t->volumeInc[1] = 0;
         t->auxLevel = 0;
@@ -124,10 +124,10 @@
         t->prevAuxLevel = 0;
 
         // Floating point volume.
-        t->mVolume[0] = UNITY_GAIN_FLOAT;
-        t->mVolume[1] = UNITY_GAIN_FLOAT;
-        t->mPrevVolume[0] = UNITY_GAIN_FLOAT;
-        t->mPrevVolume[1] = UNITY_GAIN_FLOAT;
+        t->mVolume[0] = 0.f;
+        t->mVolume[1] = 0.f;
+        t->mPrevVolume[0] = 0.f;
+        t->mPrevVolume[1] = 0.f;
         t->mVolumeInc[0] = 0.;
         t->mVolumeInc[1] = 0.;
         t->mAuxLevel = 0.;
@@ -136,6 +136,9 @@
 
         // no initialization needed
         // t->frameCount
+        t->mHapticChannelMask = channelMask & AUDIO_CHANNEL_HAPTIC_ALL;
+        t->mHapticChannelCount = audio_channel_count_from_out_mask(t->mHapticChannelMask);
+        channelMask &= ~AUDIO_CHANNEL_HAPTIC_ALL;
         t->channelCount = audio_channel_count_from_out_mask(channelMask);
         t->enabled = false;
         ALOGV_IF(audio_channel_mask_get_bits(channelMask) != AUDIO_CHANNEL_OUT_STEREO,
@@ -162,6 +165,16 @@
                 AUDIO_CHANNEL_REPRESENTATION_POSITION, AUDIO_CHANNEL_OUT_STEREO);
         t->mMixerChannelCount = audio_channel_count_from_out_mask(t->mMixerChannelMask);
         t->mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
+        // haptic
+        t->mHapticPlaybackEnabled = false;
+        t->mHapticIntensity = HAPTIC_SCALE_NONE;
+        t->mMixerHapticChannelMask = AUDIO_CHANNEL_NONE;
+        t->mMixerHapticChannelCount = 0;
+        t->mAdjustInChannelCount = t->channelCount + t->mHapticChannelCount;
+        t->mAdjustOutChannelCount = t->channelCount + t->mMixerHapticChannelCount;
+        t->mAdjustNonDestructiveInChannelCount = t->mAdjustOutChannelCount;
+        t->mAdjustNonDestructiveOutChannelCount = t->channelCount;
+        t->mKeepContractedChannels = false;
         // Check the downmixing (or upmixing) requirements.
         status_t status = t->prepareForDownmix();
         if (status != OK) {
@@ -171,6 +184,8 @@
         // prepareForDownmix() may change mDownmixRequiresFormat
         ALOGVV("mMixerFormat:%#x  mMixerInFormat:%#x\n", t->mMixerFormat, t->mMixerInFormat);
         t->prepareForReformat();
+        t->prepareForAdjustChannelsNonDestructive(mFrameCount);
+        t->prepareForAdjustChannels();
 
         mTracks[name] = t;
         return OK;
@@ -185,13 +200,20 @@
     LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
     const std::shared_ptr<Track> &track = mTracks[name];
 
-    if (trackChannelMask == track->channelMask
-            && mixerChannelMask == track->mMixerChannelMask) {
+    if (trackChannelMask == (track->channelMask | track->mHapticChannelMask)
+            && mixerChannelMask == (track->mMixerChannelMask | track->mMixerHapticChannelMask)) {
         return false;  // no need to change
     }
+    const audio_channel_mask_t hapticChannelMask = trackChannelMask & AUDIO_CHANNEL_HAPTIC_ALL;
+    trackChannelMask &= ~AUDIO_CHANNEL_HAPTIC_ALL;
+    const audio_channel_mask_t mixerHapticChannelMask = mixerChannelMask & AUDIO_CHANNEL_HAPTIC_ALL;
+    mixerChannelMask &= ~AUDIO_CHANNEL_HAPTIC_ALL;
     // always recompute for both channel masks even if only one has changed.
     const uint32_t trackChannelCount = audio_channel_count_from_out_mask(trackChannelMask);
     const uint32_t mixerChannelCount = audio_channel_count_from_out_mask(mixerChannelMask);
+    const uint32_t hapticChannelCount = audio_channel_count_from_out_mask(hapticChannelMask);
+    const uint32_t mixerHapticChannelCount =
+            audio_channel_count_from_out_mask(mixerHapticChannelMask);
 
     ALOG_ASSERT((trackChannelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX)
             && trackChannelCount
@@ -200,6 +222,24 @@
     track->channelCount = trackChannelCount;
     track->mMixerChannelMask = mixerChannelMask;
     track->mMixerChannelCount = mixerChannelCount;
+    track->mHapticChannelMask = hapticChannelMask;
+    track->mHapticChannelCount = hapticChannelCount;
+    track->mMixerHapticChannelMask = mixerHapticChannelMask;
+    track->mMixerHapticChannelCount = mixerHapticChannelCount;
+
+    if (track->mHapticChannelCount > 0) {
+        track->mAdjustInChannelCount = track->channelCount + track->mHapticChannelCount;
+        track->mAdjustOutChannelCount = track->channelCount + track->mMixerHapticChannelCount;
+        track->mAdjustNonDestructiveInChannelCount = track->mAdjustOutChannelCount;
+        track->mAdjustNonDestructiveOutChannelCount = track->channelCount;
+        track->mKeepContractedChannels = track->mHapticPlaybackEnabled;
+    } else {
+        track->mAdjustInChannelCount = 0;
+        track->mAdjustOutChannelCount = 0;
+        track->mAdjustNonDestructiveInChannelCount = 0;
+        track->mAdjustNonDestructiveOutChannelCount = 0;
+        track->mKeepContractedChannels = false;
+    }
 
     // channel masks have changed, does this track need a downmixer?
     // update to try using our desired format (if we aren't already using it)
@@ -212,6 +252,9 @@
     // do it after downmix since track format may change!
     track->prepareForReformat();
 
+    track->prepareForAdjustChannelsNonDestructive(mFrameCount);
+    track->prepareForAdjustChannels();
+
     if (track->mResampler.get() != nullptr) {
         // resampler channels may have changed.
         const uint32_t resetToSampleRate = track->sampleRate;
@@ -260,14 +303,19 @@
     if (audio_channel_mask_get_representation(channelMask)
                 == AUDIO_CHANNEL_REPRESENTATION_POSITION
             && DownmixerBufferProvider::isMultichannelCapable()) {
-        mDownmixerBufferProvider.reset(new DownmixerBufferProvider(channelMask,
-                mMixerChannelMask,
-                AUDIO_FORMAT_PCM_16_BIT /* TODO: use mMixerInFormat, now only PCM 16 */,
-                sampleRate, sessionId, kCopyBufferFrameCount));
-        if (static_cast<DownmixerBufferProvider *>(mDownmixerBufferProvider.get())->isValid()) {
-            mDownmixRequiresFormat = AUDIO_FORMAT_PCM_16_BIT; // PCM 16 bit required for downmix
-            reconfigureBufferProviders();
-            return NO_ERROR;
+
+        // Check if we have a float or int16 downmixer, in that order.
+        for (const audio_format_t format : { AUDIO_FORMAT_PCM_FLOAT, AUDIO_FORMAT_PCM_16_BIT }) {
+            mDownmixerBufferProvider.reset(new DownmixerBufferProvider(
+                    channelMask, mMixerChannelMask,
+                    format,
+                    sampleRate, sessionId, kCopyBufferFrameCount));
+            if (static_cast<DownmixerBufferProvider *>(mDownmixerBufferProvider.get())
+                    ->isValid()) {
+                mDownmixRequiresFormat = format;
+                reconfigureBufferProviders();
+                return NO_ERROR;
+            }
         }
         // mDownmixerBufferProvider reset below.
     }
@@ -335,9 +383,82 @@
     return NO_ERROR;
 }
 
+void AudioMixer::Track::unprepareForAdjustChannels()
+{
+    ALOGV("AUDIOMIXER::unprepareForAdjustChannels");
+    if (mAdjustChannelsBufferProvider.get() != nullptr) {
+        mAdjustChannelsBufferProvider.reset(nullptr);
+        reconfigureBufferProviders();
+    }
+}
+
+status_t AudioMixer::Track::prepareForAdjustChannels()
+{
+    ALOGV("AudioMixer::prepareForAdjustChannels(%p) with inChannelCount: %u, outChannelCount: %u",
+            this, mAdjustInChannelCount, mAdjustOutChannelCount);
+    unprepareForAdjustChannels();
+    if (mAdjustInChannelCount != mAdjustOutChannelCount) {
+        mAdjustChannelsBufferProvider.reset(new AdjustChannelsBufferProvider(
+                mFormat, mAdjustInChannelCount, mAdjustOutChannelCount, kCopyBufferFrameCount));
+        reconfigureBufferProviders();
+    }
+    return NO_ERROR;
+}
+
+void AudioMixer::Track::unprepareForAdjustChannelsNonDestructive()
+{
+    ALOGV("AUDIOMIXER::unprepareForAdjustChannelsNonDestructive");
+    if (mContractChannelsNonDestructiveBufferProvider.get() != nullptr) {
+        mContractChannelsNonDestructiveBufferProvider.reset(nullptr);
+        reconfigureBufferProviders();
+    }
+}
+
+status_t AudioMixer::Track::prepareForAdjustChannelsNonDestructive(size_t frames)
+{
+    ALOGV("AudioMixer::prepareForAdjustChannelsNonDestructive(%p) with inChannelCount: %u, "
+          "outChannelCount: %u, keepContractedChannels: %d",
+            this, mAdjustNonDestructiveInChannelCount, mAdjustNonDestructiveOutChannelCount,
+            mKeepContractedChannels);
+    unprepareForAdjustChannelsNonDestructive();
+    if (mAdjustNonDestructiveInChannelCount != mAdjustNonDestructiveOutChannelCount) {
+        uint8_t* buffer = mKeepContractedChannels
+                ? (uint8_t*)mainBuffer + frames * audio_bytes_per_frame(
+                        mMixerChannelCount, mMixerFormat)
+                : NULL;
+        mContractChannelsNonDestructiveBufferProvider.reset(
+                new AdjustChannelsBufferProvider(
+                        mFormat,
+                        mAdjustNonDestructiveInChannelCount,
+                        mAdjustNonDestructiveOutChannelCount,
+                        frames,
+                        mKeepContractedChannels ? mMixerFormat : AUDIO_FORMAT_INVALID,
+                        buffer));
+        reconfigureBufferProviders();
+    }
+    return NO_ERROR;
+}
+
+void AudioMixer::Track::clearContractedBuffer()
+{
+    if (mContractChannelsNonDestructiveBufferProvider.get() != nullptr) {
+        static_cast<AdjustChannelsBufferProvider*>(
+                mContractChannelsNonDestructiveBufferProvider.get())->clearContractedFrames();
+    }
+}
+
 void AudioMixer::Track::reconfigureBufferProviders()
 {
+    // configure from upstream to downstream buffer providers.
     bufferProvider = mInputBufferProvider;
+    if (mAdjustChannelsBufferProvider.get() != nullptr) {
+        mAdjustChannelsBufferProvider->setBufferProvider(bufferProvider);
+        bufferProvider = mAdjustChannelsBufferProvider.get();
+    }
+    if (mContractChannelsNonDestructiveBufferProvider.get() != nullptr) {
+        mContractChannelsNonDestructiveBufferProvider->setBufferProvider(bufferProvider);
+        bufferProvider = mContractChannelsNonDestructiveBufferProvider.get();
+    }
     if (mReformatBufferProvider.get() != nullptr) {
         mReformatBufferProvider->setBufferProvider(bufferProvider);
         bufferProvider = mReformatBufferProvider.get();
@@ -532,7 +653,8 @@
         case CHANNEL_MASK: {
             const audio_channel_mask_t trackChannelMask =
                 static_cast<audio_channel_mask_t>(valueInt);
-            if (setChannelMasks(name, trackChannelMask, track->mMixerChannelMask)) {
+            if (setChannelMasks(name, trackChannelMask,
+                    (track->mMixerChannelMask | track->mMixerHapticChannelMask))) {
                 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", trackChannelMask);
                 invalidate();
             }
@@ -541,6 +663,9 @@
             if (track->mainBuffer != valueBuf) {
                 track->mainBuffer = valueBuf;
                 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
+                if (track->mKeepContractedChannels) {
+                    track->prepareForAdjustChannelsNonDestructive(mFrameCount);
+                }
                 invalidate();
             }
             break;
@@ -570,16 +695,35 @@
             if (track->mMixerFormat != format) {
                 track->mMixerFormat = format;
                 ALOGV("setParameter(TRACK, MIXER_FORMAT, %#x)", format);
+                if (track->mKeepContractedChannels) {
+                    track->prepareForAdjustChannelsNonDestructive(mFrameCount);
+                }
             }
             } break;
         case MIXER_CHANNEL_MASK: {
             const audio_channel_mask_t mixerChannelMask =
                     static_cast<audio_channel_mask_t>(valueInt);
-            if (setChannelMasks(name, track->channelMask, mixerChannelMask)) {
+            if (setChannelMasks(name, track->channelMask | track->mHapticChannelMask,
+                    mixerChannelMask)) {
                 ALOGV("setParameter(TRACK, MIXER_CHANNEL_MASK, %#x)", mixerChannelMask);
                 invalidate();
             }
             } break;
+        case HAPTIC_ENABLED: {
+            const bool hapticPlaybackEnabled = static_cast<bool>(valueInt);
+            if (track->mHapticPlaybackEnabled != hapticPlaybackEnabled) {
+                track->mHapticPlaybackEnabled = hapticPlaybackEnabled;
+                track->mKeepContractedChannels = hapticPlaybackEnabled;
+                track->prepareForAdjustChannelsNonDestructive(mFrameCount);
+                track->prepareForAdjustChannels();
+            }
+            } break;
+        case HAPTIC_INTENSITY: {
+            const haptic_intensity_t hapticIntensity = static_cast<haptic_intensity_t>(valueInt);
+            if (track->mHapticIntensity != hapticIntensity) {
+                track->mHapticIntensity = hapticIntensity;
+            }
+            } break;
         default:
             LOG_ALWAYS_FATAL("setParameter track: bad param %d", param);
         }
@@ -813,14 +957,19 @@
     if (track->mInputBufferProvider == bufferProvider) {
         return; // don't reset any buffer providers if identical.
     }
-    if (track->mReformatBufferProvider.get() != nullptr) {
-        track->mReformatBufferProvider->reset();
-    } else if (track->mDownmixerBufferProvider != nullptr) {
-        track->mDownmixerBufferProvider->reset();
+    // reset order from downstream to upstream buffer providers.
+    if (track->mTimestretchBufferProvider.get() != nullptr) {
+        track->mTimestretchBufferProvider->reset();
     } else if (track->mPostDownmixReformatBufferProvider.get() != nullptr) {
         track->mPostDownmixReformatBufferProvider->reset();
-    } else if (track->mTimestretchBufferProvider.get() != nullptr) {
-        track->mTimestretchBufferProvider->reset();
+    } else if (track->mDownmixerBufferProvider != nullptr) {
+        track->mDownmixerBufferProvider->reset();
+    } else if (track->mReformatBufferProvider.get() != nullptr) {
+        track->mReformatBufferProvider->reset();
+    } else if (track->mContractChannelsNonDestructiveBufferProvider.get() != nullptr) {
+        track->mContractChannelsNonDestructiveBufferProvider->reset();
+    } else if (track->mAdjustChannelsBufferProvider.get() != nullptr) {
+        track->mAdjustChannelsBufferProvider->reset();
     }
 
     track->mInputBufferProvider = bufferProvider;
@@ -875,7 +1024,7 @@
                 t->hook = Track::getTrackHook(TRACKTYPE_RESAMPLE, t->mMixerChannelCount,
                         t->mMixerInFormat, t->mMixerFormat);
                 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
-                        "Track %d needs downmix + resample", i);
+                        "Track %d needs downmix + resample", name);
             } else {
                 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
                     t->hook = Track::getTrackHook(
@@ -890,7 +1039,7 @@
                     t->hook = Track::getTrackHook(TRACKTYPE_NORESAMPLE, t->mMixerChannelCount,
                             t->mMixerInFormat, t->mMixerFormat);
                     ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
-                            "Track %d needs downmix", i);
+                            "Track %d needs downmix", name);
                 }
             }
         }
@@ -1264,8 +1413,8 @@
 
         const std::shared_ptr<Track> &t = mTracks[group[0]];
         memset(t->mainBuffer, 0,
-                mFrameCount * t->mMixerChannelCount
-                * audio_bytes_per_sample(t->mMixerFormat));
+                mFrameCount * audio_bytes_per_frame(
+                        t->mMixerChannelCount + t->mMixerHapticChannelCount, t->mMixerFormat));
 
         // now consume data
         for (const int name : group) {
@@ -1704,6 +1853,40 @@
     }
 }
 
+void AudioMixer::processHapticData()
+{
+    // Need to keep consistent with VibrationEffect.scale(int, float, int)
+    for (const auto &pair : mGroups) {
+        // process by group of tracks with same output main buffer.
+        const auto &group = pair.second;
+        for (const int name : group) {
+            const std::shared_ptr<Track> &t = mTracks[name];
+            if (t->mHapticPlaybackEnabled) {
+                size_t sampleCount = mFrameCount * t->mMixerHapticChannelCount;
+                float gamma = t->getHapticScaleGamma();
+                float maxAmplitudeRatio = t->getHapticMaxAmplitudeRatio();
+                uint8_t* buffer = (uint8_t*)pair.first + mFrameCount * audio_bytes_per_frame(
+                        t->mMixerChannelCount, t->mMixerFormat);
+                switch (t->mMixerFormat) {
+                // Mixer format should be AUDIO_FORMAT_PCM_FLOAT.
+                case AUDIO_FORMAT_PCM_FLOAT: {
+                    float* fout = (float*) buffer;
+                    for (size_t i = 0; i < sampleCount; i++) {
+                        float mul = fout[i] >= 0 ? 1.0 : -1.0;
+                        fout[i] = powf(fabsf(fout[i] / HAPTIC_MAX_AMPLITUDE_FLOAT), gamma)
+                                * maxAmplitudeRatio * HAPTIC_MAX_AMPLITUDE_FLOAT * mul;
+                    }
+                } break;
+                default:
+                    LOG_ALWAYS_FATAL("bad mMixerFormat: %#x", t->mMixerFormat);
+                    break;
+                }
+                break;
+            }
+        }
+    }
+}
+
 /* This track hook is called to do resampling then mixing,
  * pulling from the track's upstream AudioBufferProvider.
  *
diff --git a/media/libaudioprocessing/AudioResamplerDyn.cpp b/media/libaudioprocessing/AudioResamplerDyn.cpp
index eeeecce..ec56b00 100644
--- a/media/libaudioprocessing/AudioResamplerDyn.cpp
+++ b/media/libaudioprocessing/AudioResamplerDyn.cpp
@@ -201,6 +201,8 @@
             "ro.audio.resampler.psd.stopband", mPropertyStopbandAttenuation);
     mPropertyCutoffPercent = property_get_int32(
             "ro.audio.resampler.psd.cutoff_percent", mPropertyCutoffPercent);
+    mPropertyTransitionBandwidthCheat = property_get_int32(
+            "ro.audio.resampler.psd.tbwcheat", mPropertyTransitionBandwidthCheat);
 }
 
 template<typename TC, typename TI, typename TO>
@@ -243,7 +245,7 @@
 {
     // compute the normalized transition bandwidth
     const double tbw = firKaiserTbw(c.mHalfNumCoefs, stopBandAtten);
-    const double halfbw = tbw / 2.;
+    const double halfbw = tbw * 0.5;
 
     double fcr; // compute fcr, the 3 dB amplitude cut-off.
     if (inSampleRate < outSampleRate) { // upsample
@@ -290,7 +292,7 @@
 
 #if 0
     // Keep this debug code in case an app causes resampler design issues.
-    const double halfbw = tbw / 2.;
+    const double halfbw = tbw * 0.5;
     // print basic filter stats
     ALOGD("L:%d  hnc:%d  stopBandAtten:%lf  fcr:%lf  atten:%lf  tbw:%lf\n",
             c.mL, c.mHalfNumCoefs, stopBandAtten, fcr, attenuation, tbw);
@@ -305,7 +307,7 @@
 
     const int32_t passSteps = 1000;
 
-    testFir(coefs, c.mL, c.mHalfNumCoefs, fp, fs, passSteps, passSteps * c.ML /*stopSteps*/,
+    testFir(coefs, c.mL, c.mHalfNumCoefs, fp, fs, passSteps, passSteps * c.mL /*stopSteps*/,
             passMin, passMax, passRipple, stopMax, stopRipple);
     ALOGD("passband(%lf, %lf): %.8lf %.8lf %.8lf\n", 0., fp, passMin, passMax, passRipple);
     ALOGD("stopband(%lf, %lf): %.8lf %.3lf\n", fs, 0.5, stopMax, stopRipple);
@@ -379,12 +381,28 @@
             halfLength = mPropertyHalfFilterLength;
             stopBandAtten = mPropertyStopbandAttenuation;
             useS32 = true;
-            fcr = mInSampleRate <= mSampleRate
-                    ? 0.5 : 0.5 * mSampleRate / mInSampleRate;
-            fcr *= mPropertyCutoffPercent / 100.;
+
+            // Use either the stopband location for design (tbwCheat)
+            // or use the 3dB cutoff location for design (fcr).
+            // This choice is exclusive and based on whether fcr > 0.
+            if (mPropertyTransitionBandwidthCheat != 0) {
+                tbwCheat = mPropertyTransitionBandwidthCheat / 100.;
+            } else {
+                fcr = mInSampleRate <= mSampleRate
+                        ? 0.5 : 0.5 * mSampleRate / mInSampleRate;
+                fcr *= mPropertyCutoffPercent / 100.;
+            }
         } else {
+            // Voice quality devices have lower sampling rates
+            // (and may be a consequence of downstream AMR-WB / G.722 codecs).
+            // For these devices, we ensure a wider resampler passband
+            // at the expense of aliasing noise (stopband attenuation
+            // and stopband frequency).
+            //
+            constexpr uint32_t kVoiceDeviceSampleRate = 16000;
+
             if (mFilterQuality == DYN_HIGH_QUALITY) {
-                // 32b coefficients, 64 length
+                // float or 32b coefficients
                 useS32 = true;
                 stopBandAtten = 98.;
                 if (inSampleRate >= mSampleRate * 4) {
@@ -394,8 +412,18 @@
                 } else {
                     halfLength = 32;
                 }
+
+                if (mSampleRate <= kVoiceDeviceSampleRate) {
+                    if (inSampleRate >= mSampleRate * 2) {
+                        halfLength += 16;
+                    } else {
+                        halfLength += 8;
+                    }
+                    stopBandAtten = 84.;
+                    tbwCheat = 1.05;
+                }
             } else if (mFilterQuality == DYN_LOW_QUALITY) {
-                // 16b coefficients, 16-32 length
+                // float or 16b coefficients
                 useS32 = false;
                 stopBandAtten = 80.;
                 if (inSampleRate >= mSampleRate * 4) {
@@ -405,13 +433,18 @@
                 } else {
                     halfLength = 8;
                 }
-                if (inSampleRate <= mSampleRate) {
+                if (mSampleRate <= kVoiceDeviceSampleRate) {
+                    if (inSampleRate >= mSampleRate * 2) {
+                        halfLength += 8;
+                    }
+                    tbwCheat = 1.05;
+                } else if (inSampleRate <= mSampleRate) {
                     tbwCheat = 1.05;
                 } else {
                     tbwCheat = 1.03;
                 }
             } else { // DYN_MED_QUALITY
-                // 16b coefficients, 32-64 length
+                // float or 16b coefficients
                 // note: > 64 length filters with 16b coefs can have quantization noise problems
                 useS32 = false;
                 stopBandAtten = 84.;
@@ -422,7 +455,15 @@
                 } else {
                     halfLength = 16;
                 }
-                if (inSampleRate <= mSampleRate) {
+
+                if (mSampleRate <= kVoiceDeviceSampleRate) {
+                    if (inSampleRate >= mSampleRate * 2) {
+                        halfLength += 16;
+                    } else {
+                        halfLength += 8;
+                    }
+                    tbwCheat = 1.05;
+                } else if (inSampleRate <= mSampleRate) {
                     tbwCheat = 1.03;
                 } else {
                     tbwCheat = 1.01;
@@ -430,6 +471,19 @@
             }
         }
 
+        if (fcr > 0.) {
+            ALOGV("%s: mFilterQuality:%d inSampleRate:%d mSampleRate:%d halfLength:%d "
+                    "stopBandAtten:%lf fcr:%lf",
+                    __func__, mFilterQuality, inSampleRate, mSampleRate, halfLength,
+                    stopBandAtten, fcr);
+        } else {
+            ALOGV("%s: mFilterQuality:%d inSampleRate:%d mSampleRate:%d halfLength:%d "
+                    "stopBandAtten:%lf tbwCheat:%lf",
+                    __func__, mFilterQuality, inSampleRate, mSampleRate, halfLength,
+                    stopBandAtten, tbwCheat);
+        }
+
+
         // determine the number of polyphases in the filterbank.
         // for 16b, it is desirable to have 2^(16/2) = 256 phases.
         // https://ccrma.stanford.edu/~jos/resample/Relation_Interpolation_Error_Quantization.html
diff --git a/media/libaudioprocessing/AudioResamplerDyn.h b/media/libaudioprocessing/AudioResamplerDyn.h
index 92144d0..82b9505 100644
--- a/media/libaudioprocessing/AudioResamplerDyn.h
+++ b/media/libaudioprocessing/AudioResamplerDyn.h
@@ -55,6 +55,11 @@
     virtual size_t resample(int32_t* out, size_t outFrameCount,
             AudioBufferProvider* provider);
 
+    void reset() override {
+        AudioResampler::reset();
+        mInBuffer.reset();
+    }
+
     // Make available key design criteria for testing
     int getHalfLength() const {
         return mConstants.mHalfNumCoefs;
@@ -188,6 +193,13 @@
               int32_t mPropertyCutoffPercent = 100;
                       // "ro.audio.resampler.psd.cutoff_percent"
 
+              // Specify the transition bandwidth extension beyond Nyquist.
+              // If this is nonzero then mPropertyCutoffPercent is ignored.
+              // A value of 100 or greater is typically used, where 100 means the
+              // stopband is at Nyquist (this is a typical design).
+              int32_t mPropertyTransitionBandwidthCheat = 0;
+                      // "ro.audio.resampler.psd.tbwcheat"
+
     // Filter creation design parameters, see setSampleRate()
              double mStopbandAttenuationDb = 0.;
              double mPassbandRippleDb = 0.;
diff --git a/media/libaudioprocessing/AudioResamplerFirGen.h b/media/libaudioprocessing/AudioResamplerFirGen.h
index 39cafeb..100baa3 100644
--- a/media/libaudioprocessing/AudioResamplerFirGen.h
+++ b/media/libaudioprocessing/AudioResamplerFirGen.h
@@ -547,8 +547,8 @@
         wstart += wstep;
     }
     // renormalize - this is needed for integer filter types, use 1 for float or double.
-    constexpr int64_t integralShift = std::is_integral<T>::value ? (sizeof(T) * 8 - 1) : 0;
-    const double norm = 1. / (L << integralShift);
+    constexpr int integralShift = std::is_integral<T>::value ? (sizeof(T) * CHAR_BIT - 1) : 0;
+    const double norm = 1. / (int64_t{L} << integralShift);
 
     firMin = fmin * norm;
     firMax = fmax * norm;
diff --git a/media/libaudioprocessing/AudioResamplerFirProcess.h b/media/libaudioprocessing/AudioResamplerFirProcess.h
index a741677..9b70a1c 100644
--- a/media/libaudioprocessing/AudioResamplerFirProcess.h
+++ b/media/libaudioprocessing/AudioResamplerFirProcess.h
@@ -90,7 +90,7 @@
         Accumulator<CHANNELS-1, TO>::acc(coef, data);
     }
     inline void volume(TO*& out, TO gain) {
-        *out++ = volumeAdjust(value, gain);
+        *out++ += volumeAdjust(value, gain);
         Accumulator<CHANNELS-1, TO>::volume(out, gain);
     }
 
diff --git a/media/libaudioprocessing/AudioResamplerSinc.cpp b/media/libaudioprocessing/AudioResamplerSinc.cpp
index 320b8cf..5a03a0d 100644
--- a/media/libaudioprocessing/AudioResamplerSinc.cpp
+++ b/media/libaudioprocessing/AudioResamplerSinc.cpp
@@ -19,6 +19,7 @@
 
 #define __STDC_CONSTANT_MACROS
 #include <malloc.h>
+#include <pthread.h>
 #include <string.h>
 #include <stdlib.h>
 #include <dlfcn.h>
diff --git a/media/libaudioprocessing/BufferProviders.cpp b/media/libaudioprocessing/BufferProviders.cpp
index 2d9e1cb..21d25e1 100644
--- a/media/libaudioprocessing/BufferProviders.cpp
+++ b/media/libaudioprocessing/BufferProviders.cpp
@@ -17,9 +17,12 @@
 #define LOG_TAG "BufferProvider"
 //#define LOG_NDEBUG 0
 
+#include <algorithm>
+
 #include <audio_utils/primitives.h>
 #include <audio_utils/format.h>
-#include <external/sonic/sonic.h>
+#include <audio_utils/channels.h>
+#include <sonic.h>
 #include <media/audiohal/EffectBufferHalInterface.h>
 #include <media/audiohal/EffectHalInterface.h>
 #include <media/audiohal/EffectsFactoryHalInterface.h>
@@ -35,13 +38,6 @@
 namespace android {
 
 // ----------------------------------------------------------------------------
-
-template <typename T>
-static inline T min(const T& a, const T& b)
-{
-    return a < b ? a : b;
-}
-
 CopyBufferProvider::CopyBufferProvider(size_t inputFrameSize,
         size_t outputFrameSize, size_t bufferFrameCount) :
         mInputFrameSize(inputFrameSize),
@@ -63,7 +59,8 @@
 
 CopyBufferProvider::~CopyBufferProvider()
 {
-    ALOGV("~CopyBufferProvider(%p)", this);
+    ALOGV("%s(%p) %zu %p %p",
+           __func__, this, mBuffer.frameCount, mTrackBufferProvider, mLocalBufferData);
     if (mBuffer.frameCount != 0) {
         mTrackBufferProvider->releaseBuffer(&mBuffer);
     }
@@ -98,8 +95,8 @@
         mConsumed = 0;
     }
     ALOG_ASSERT(mConsumed < mBuffer.frameCount);
-    size_t count = min(mLocalBufferFrameCount, mBuffer.frameCount - mConsumed);
-    count = min(count, pBuffer->frameCount);
+    size_t count = std::min(mLocalBufferFrameCount, mBuffer.frameCount - mConsumed);
+    count = std::min(count, pBuffer->frameCount);
     pBuffer->raw = mLocalBufferData;
     pBuffer->frameCount = count;
     copyFrames(pBuffer->raw, (uint8_t*)mBuffer.raw + mConsumed * mInputFrameSize,
@@ -133,6 +130,16 @@
     mConsumed = 0;
 }
 
+void CopyBufferProvider::setBufferProvider(AudioBufferProvider *p) {
+    ALOGV("%s(%p): mTrackBufferProvider:%p  mBuffer.frameCount:%zu",
+            __func__, p, mTrackBufferProvider, mBuffer.frameCount);
+    if (mTrackBufferProvider == p) {
+        return;
+    }
+    mBuffer.frameCount = 0;
+    PassthruBufferProvider::setBufferProvider(p);
+}
+
 DownmixerBufferProvider::DownmixerBufferProvider(
         audio_channel_mask_t inputChannelMask,
         audio_channel_mask_t outputChannelMask, audio_format_t format,
@@ -479,7 +486,7 @@
         }
 
         // time-stretch the data
-        dstAvailable = min(mLocalBufferFrameCount - mRemaining, outputDesired);
+        dstAvailable = std::min(mLocalBufferFrameCount - mRemaining, outputDesired);
         size_t srcAvailable = mBuffer.frameCount;
         processFrames((uint8_t*)mLocalBufferData + mRemaining * mFrameSize, &dstAvailable,
                 mBuffer.raw, &srcAvailable);
@@ -528,6 +535,16 @@
     mRemaining = 0;
 }
 
+void TimestretchBufferProvider::setBufferProvider(AudioBufferProvider *p) {
+    ALOGV("%s(%p): mTrackBufferProvider:%p  mBuffer.frameCount:%zu",
+            __func__, p, mTrackBufferProvider, mBuffer.frameCount);
+    if (mTrackBufferProvider == p) {
+        return;
+    }
+    mBuffer.frameCount = 0;
+    PassthruBufferProvider::setBufferProvider(p);
+}
+
 status_t TimestretchBufferProvider::setPlaybackRate(const AudioPlaybackRate &playbackRate)
 {
     mPlaybackRate = playbackRate;
@@ -567,7 +584,7 @@
                   } else {
                       // cyclically repeat the source.
                       for (size_t count = 0; count < *dstFrames; count += *srcFrames) {
-                          size_t remaining = min(*srcFrames, *dstFrames - count);
+                          size_t remaining = std::min(*srcFrames, *dstFrames - count);
                           memcpy((uint8_t*)dstBuffer + mFrameSize * count,
                                   srcBuffer, mFrameSize * remaining);
                       }
@@ -609,5 +626,72 @@
         }
     }
 }
+
+AdjustChannelsBufferProvider::AdjustChannelsBufferProvider(
+        audio_format_t format, size_t inChannelCount, size_t outChannelCount,
+        size_t frameCount, audio_format_t contractedFormat, void* contractedBuffer) :
+        CopyBufferProvider(
+                audio_bytes_per_frame(inChannelCount, format),
+                audio_bytes_per_frame(std::max(inChannelCount, outChannelCount), format),
+                frameCount),
+        mFormat(format),
+        mInChannelCount(inChannelCount),
+        mOutChannelCount(outChannelCount),
+        mSampleSizeInBytes(audio_bytes_per_sample(format)),
+        mFrameCount(frameCount),
+        mContractedChannelCount(inChannelCount - outChannelCount),
+        mContractedFormat(contractedFormat),
+        mContractedBuffer(contractedBuffer),
+        mContractedWrittenFrames(0)
+{
+    ALOGV("AdjustChannelsBufferProvider(%p)(%#x, %zu, %zu, %zu, %#x, %p)", this, format,
+            inChannelCount, outChannelCount, frameCount, contractedFormat, contractedBuffer);
+    if (mContractedFormat != AUDIO_FORMAT_INVALID && mInChannelCount > mOutChannelCount) {
+        mContractedFrameSize = audio_bytes_per_frame(mContractedChannelCount, mContractedFormat);
+    }
+}
+
+status_t AdjustChannelsBufferProvider::getNextBuffer(AudioBufferProvider::Buffer* pBuffer)
+{
+    if (mContractedBuffer != nullptr) {
+        // Restrict frame count only when it is needed to save contracted frames.
+        const size_t outFramesLeft = mFrameCount - mContractedWrittenFrames;
+        if (outFramesLeft < pBuffer->frameCount) {
+            // Restrict the frame count so that we don't write over the size of the output buffer.
+            pBuffer->frameCount = outFramesLeft;
+        }
+    }
+    return CopyBufferProvider::getNextBuffer(pBuffer);
+}
+
+void AdjustChannelsBufferProvider::copyFrames(void *dst, const void *src, size_t frames)
+{
+    if (mInChannelCount > mOutChannelCount) {
+        // For case multi to mono, adjust_channels has special logic that will mix first two input
+        // channels into a single output channel. In that case, use adjust_channels_non_destructive
+        // to keep only one channel data even when contracting to mono.
+        adjust_channels_non_destructive(src, mInChannelCount, dst, mOutChannelCount,
+                mSampleSizeInBytes, frames * mInChannelCount * mSampleSizeInBytes);
+        if (mContractedFormat != AUDIO_FORMAT_INVALID
+            && mContractedBuffer != nullptr) {
+            const size_t contractedIdx = frames * mOutChannelCount * mSampleSizeInBytes;
+            memcpy_by_audio_format(
+                    (uint8_t*) mContractedBuffer + mContractedWrittenFrames * mContractedFrameSize,
+                    mContractedFormat, (uint8_t*) dst + contractedIdx, mFormat,
+                    mContractedChannelCount * frames);
+            mContractedWrittenFrames += frames;
+        }
+    } else {
+        // Prefer expanding data from the end of each audio frame.
+        adjust_channels(src, mInChannelCount, dst, mOutChannelCount,
+                mSampleSizeInBytes, frames * mInChannelCount * mSampleSizeInBytes);
+    }
+}
+
+void AdjustChannelsBufferProvider::reset()
+{
+    mContractedWrittenFrames = 0;
+    CopyBufferProvider::reset();
+}
 // ----------------------------------------------------------------------------
 } // namespace android
diff --git a/media/libaudioprocessing/RecordBufferConverter.cpp b/media/libaudioprocessing/RecordBufferConverter.cpp
index 54151f5..7d6fe72 100644
--- a/media/libaudioprocessing/RecordBufferConverter.cpp
+++ b/media/libaudioprocessing/RecordBufferConverter.cpp
@@ -117,6 +117,11 @@
         // format convert to destination buffer
         convertResampler(dst, mBuf, frames);
     }
+    // Release unused frames in the InputConverterProvider buffer so that
+    // the RecordThread is able to properly account for consumed frames.
+    if (mInputConverterProvider != nullptr) {
+        mInputConverterProvider->reset();
+    }
     return frames;
 }
 
diff --git a/media/libaudioprocessing/audio-resampler/Android.bp b/media/libaudioprocessing/audio-resampler/Android.bp
new file mode 100644
index 0000000..dc70310
--- /dev/null
+++ b/media/libaudioprocessing/audio-resampler/Android.bp
@@ -0,0 +1,15 @@
+cc_library_shared {
+    name: "libaudio-resampler",
+
+    srcs: ["AudioResamplerCoefficients.cpp"],
+
+    shared_libs: [
+        "libutils",
+        "liblog",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+}
diff --git a/media/libaudioprocessing/audio-resampler/Android.mk b/media/libaudioprocessing/audio-resampler/Android.mk
deleted file mode 100644
index bb2807c..0000000
--- a/media/libaudioprocessing/audio-resampler/Android.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-    AudioResamplerCoefficients.cpp
-
-LOCAL_MODULE := libaudio-resampler
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SHARED_LIBRARIES  := libutils liblog
-
-LOCAL_CFLAGS += -Werror -Wall
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libaudioprocessing/include/media/AudioResamplerPublic.h b/media/libaudioprocessing/include/media/AudioResamplerPublic.h
index 055f724..50ca33d 100644
--- a/media/libaudioprocessing/include/media/AudioResamplerPublic.h
+++ b/media/libaudioprocessing/include/media/AudioResamplerPublic.h
@@ -104,8 +104,8 @@
         const AudioPlaybackRate &pr2) {
     return fabs(pr1.mSpeed - pr2.mSpeed) < AUDIO_TIMESTRETCH_SPEED_MIN_DELTA &&
            fabs(pr1.mPitch - pr2.mPitch) < AUDIO_TIMESTRETCH_PITCH_MIN_DELTA &&
-           pr2.mStretchMode == pr2.mStretchMode &&
-           pr2.mFallbackMode == pr2.mFallbackMode;
+           pr1.mStretchMode == pr2.mStretchMode &&
+           pr1.mFallbackMode == pr2.mFallbackMode;
 }
 
 static inline bool isAudioPlaybackRateValid(const AudioPlaybackRate &playbackRate) {
diff --git a/media/libaudioprocessing/tests/Android.bp b/media/libaudioprocessing/tests/Android.bp
new file mode 100644
index 0000000..d990111
--- /dev/null
+++ b/media/libaudioprocessing/tests/Android.bp
@@ -0,0 +1,52 @@
+// Build the unit tests for libaudioprocessing
+
+cc_defaults {
+    name: "libaudioprocessing_test_defaults",
+
+    header_libs: ["libbase_headers"],
+    shared_libs: [
+        "libaudioprocessing",
+        "libaudioutils",
+        "libcutils",
+        "liblog",
+        "libutils",
+        "libvibrator",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+}
+
+//
+// resampler unit test
+//
+cc_test {
+    name: "resampler_tests",
+    defaults: ["libaudioprocessing_test_defaults"],
+
+    srcs: ["resampler_tests.cpp"],
+}
+
+//
+// audio mixer test tool
+//
+cc_binary {
+    name: "test-mixer",
+    defaults: ["libaudioprocessing_test_defaults"],
+
+    srcs: ["test-mixer.cpp"],
+    static_libs: ["libsndfile"],
+}
+
+//
+// build audio resampler test tool
+//
+cc_binary {
+    name: "test-resampler",
+    defaults: ["libaudioprocessing_test_defaults"],
+
+    srcs: ["test-resampler.cpp"],
+    static_libs: ["libsndfile"],
+}
diff --git a/media/libaudioprocessing/tests/Android.mk b/media/libaudioprocessing/tests/Android.mk
deleted file mode 100644
index 23e1c3a..0000000
--- a/media/libaudioprocessing/tests/Android.mk
+++ /dev/null
@@ -1,87 +0,0 @@
-# Build the unit tests for libaudioprocessing
-
-LOCAL_PATH := $(call my-dir)
-
-#
-# resampler unit test
-#
-include $(CLEAR_VARS)
-
-LOCAL_SHARED_LIBRARIES := \
-    libaudioutils \
-    libaudioprocessing \
-    libcutils \
-    liblog \
-    libutils \
-
-LOCAL_C_INCLUDES := \
-    $(call include-path-for, audio-utils) \
-
-LOCAL_SRC_FILES := \
-    resampler_tests.cpp
-
-LOCAL_MODULE := resampler_tests
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_CFLAGS := -Werror -Wall
-
-include $(BUILD_NATIVE_TEST)
-
-#
-# audio mixer test tool
-#
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-    test-mixer.cpp \
-
-LOCAL_C_INCLUDES := \
-    $(call include-path-for, audio-utils) \
-
-LOCAL_STATIC_LIBRARIES := \
-    libsndfile \
-
-LOCAL_SHARED_LIBRARIES := \
-    libaudioprocessing \
-    libaudioutils \
-    libcutils \
-    liblog \
-    libutils \
-
-LOCAL_MODULE := test-mixer
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_CFLAGS := -Werror -Wall
-
-include $(BUILD_EXECUTABLE)
-
-#
-# build audio resampler test tool
-#
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-    test-resampler.cpp \
-
-LOCAL_C_INCLUDES := \
-    $(call include-path-for, audio-utils) \
-
-LOCAL_STATIC_LIBRARIES := \
-    libsndfile \
-
-LOCAL_SHARED_LIBRARIES := \
-    libaudioprocessing \
-    libaudioutils \
-    libcutils \
-    liblog \
-    libutils \
-
-LOCAL_MODULE := test-resampler
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_CFLAGS := -Werror -Wall
-
-include $(BUILD_EXECUTABLE)
diff --git a/media/libaudioprocessing/tests/resampler_tests.cpp b/media/libaudioprocessing/tests/resampler_tests.cpp
index e1623f7..8292291 100644
--- a/media/libaudioprocessing/tests/resampler_tests.cpp
+++ b/media/libaudioprocessing/tests/resampler_tests.cpp
@@ -246,7 +246,8 @@
 }
 
 void testFilterResponse(
-        size_t channels, unsigned inputFreq, unsigned outputFreq)
+        size_t channels, unsigned inputFreq, unsigned outputFreq,
+        android::AudioResampler::src_quality quality = android::AudioResampler::DYN_HIGH_QUALITY)
 {
     // create resampler
     using ResamplerType = android::AudioResamplerDyn<float, float, float>;
@@ -256,7 +257,7 @@
                             AUDIO_FORMAT_PCM_FLOAT,
                             channels,
                             outputFreq,
-                            android::AudioResampler::DYN_HIGH_QUALITY)));
+                            quality)));
     rdyn->setSampleRate(inputFreq);
 
     // get design parameters
@@ -268,17 +269,20 @@
     const double attenuation = rdyn->getFilterAttenuation();
     const double stopbandDb = rdyn->getStopbandAttenuationDb();
     const double passbandDb = rdyn->getPassbandRippleDb();
-    const double fp = fcr - tbw / 2;
-    const double fs = fcr + tbw / 2;
+    const double fp = fcr - tbw * 0.5;
+    const double fs = fcr + tbw * 0.5;
+    const double idealfs = inputFreq <= outputFreq
+        ? 0.5                            // upsample
+        : 0.5 * outputFreq  / inputFreq; // downsample
 
-    printf("inputFreq:%d outputFreq:%d design"
+    printf("inputFreq:%d outputFreq:%d design quality %d"
             " phases:%d halfLength:%d"
-            " fcr:%lf fp:%lf fs:%lf tbw:%lf"
+            " fcr:%lf fp:%lf fs:%lf tbw:%lf fcrp:%lf"
             " attenuation:%lf stopRipple:%.lf passRipple:%lf"
             "\n",
-            inputFreq, outputFreq,
+            inputFreq, outputFreq, quality,
             phases, halfLength,
-            fcr, fp, fs, tbw,
+            fcr, fp, fs, tbw, fcr * 100. / idealfs,
             attenuation, stopbandDb, passbandDb);
 
     // verify design parameters
@@ -541,8 +545,36 @@
     }
 }
 
-TEST(audioflinger_resampler, filterresponse) {
-    std::vector<int> inSampleRates{
+// Selected downsampling responses for various frequencies relating to hearing aid.
+TEST(audioflinger_resampler, downsamplingresponse) {
+    static constexpr android::AudioResampler::src_quality qualities[] = {
+        android::AudioResampler::DYN_LOW_QUALITY,
+        android::AudioResampler::DYN_MED_QUALITY,
+        android::AudioResampler::DYN_HIGH_QUALITY,
+    };
+    static constexpr int inSampleRates[] = {
+        32000,
+        44100,
+        48000,
+    };
+    static constexpr int outSampleRates[] = {
+        16000,
+        24000,
+    };
+
+    for (auto quality : qualities) {
+        for (int outSampleRate : outSampleRates) {
+            for (int inSampleRate : inSampleRates) {
+                testFilterResponse(2 /* channels */, inSampleRate, outSampleRate, quality);
+            }
+        }
+    }
+}
+
+// General responses for typical output device scenarios - 44.1, 48, 96 kHz
+// (48, 96 are part of the same resampler generation family).
+TEST(audioflinger_resampler, generalresponse) {
+    static constexpr int inSampleRates[] = {
         8000,
         11025,
         12000,
@@ -557,7 +589,8 @@
         176400,
         192000,
     };
-    std::vector<int> outSampleRates{
+    static constexpr int outSampleRates[] = {
+        44100,
         48000,
         96000,
     };
diff --git a/media/libaudioprocessing/tests/test-resampler.cpp b/media/libaudioprocessing/tests/test-resampler.cpp
index fbc9326..f178bde 100644
--- a/media/libaudioprocessing/tests/test-resampler.cpp
+++ b/media/libaudioprocessing/tests/test-resampler.cpp
@@ -27,6 +27,7 @@
 #include <math.h>
 #include <audio_utils/primitives.h>
 #include <audio_utils/sndfile.h>
+#include <android-base/macros.h>
 #include <utils/Vector.h>
 #include <media/AudioBufferProvider.h>
 #include <media/AudioResampler.h>
@@ -87,14 +88,14 @@
                 }
                 return numValues;
             }
-            // fall through
+            FALLTHROUGH_INTENDED;
         case ',':
             if (hadDigit) {
                 hadDigit = false;
                 numValues++;
                 break;
             }
-            // fall through
+            FALLTHROUGH_INTENDED;
         default:
             return -1;
         }
diff --git a/media/libaudioprocessing/tests/test_utils.h b/media/libaudioprocessing/tests/test_utils.h
index b61a929..21f5862 100644
--- a/media/libaudioprocessing/tests/test_utils.h
+++ b/media/libaudioprocessing/tests/test_utils.h
@@ -23,6 +23,7 @@
 
 #include <log/log.h>
 
+#include <android-base/macros.h>
 #include <audio_utils/sndfile.h>
 
 #ifndef ARRAY_SIZE
@@ -77,14 +78,14 @@
                 }
                 return numValues;
             }
-            // fall through
+            FALLTHROUGH_INTENDED;
         case ',':
             if (hadDigit) {
                 hadDigit = false;
                 numValues++;
                 break;
             }
-            // fall through
+            FALLTHROUGH_INTENDED;
         default:
             return -1;
         }
diff --git a/media/libeffects/Android.bp b/media/libeffects/Android.bp
deleted file mode 100644
index 0dd3f17..0000000
--- a/media/libeffects/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["factory", "config"]
diff --git a/media/libeffects/config/src/EffectsConfig.cpp b/media/libeffects/config/src/EffectsConfig.cpp
index 351b1ee..f39eb0c 100644
--- a/media/libeffects/config/src/EffectsConfig.cpp
+++ b/media/libeffects/config/src/EffectsConfig.cpp
@@ -115,6 +115,7 @@
         {AUDIO_SOURCE_VOICE_RECOGNITION, "voice_recognition"},
         {AUDIO_SOURCE_VOICE_COMMUNICATION, "voice_communication"},
         {AUDIO_SOURCE_UNPROCESSED, "unprocessed"},
+        {AUDIO_SOURCE_VOICE_PERFORMANCE, "voice_performance"},
 };
 
 /** Find the stream type enum corresponding to the stream type name or return false */
@@ -305,7 +306,7 @@
         return parseWithPath(path);
     }
 
-    for (std::string location : DEFAULT_LOCATIONS) {
+    for (const std::string& location : DEFAULT_LOCATIONS) {
         std::string defaultPath = location + '/' + DEFAULT_NAME;
         if (access(defaultPath.c_str(), R_OK) != 0) {
             continue;
diff --git a/media/libeffects/downmix/Android.bp b/media/libeffects/downmix/Android.bp
new file mode 100644
index 0000000..9c82b1d
--- /dev/null
+++ b/media/libeffects/downmix/Android.bp
@@ -0,0 +1,27 @@
+// Multichannel downmix effect library
+cc_library_shared {
+    name: "libdownmix",
+
+    vendor: true,
+    srcs: ["EffectDownmix.c"],
+
+    shared_libs: [
+        "libcutils",
+        "liblog",
+    ],
+
+    relative_install_path: "soundfx",
+
+    cflags: [
+        "-DBUILD_FLOAT",
+        "-fvisibility=hidden",
+        "-Wall",
+        "-Werror",
+    ],
+
+    header_libs: [
+        "libaudioeffects",
+        "libhardware_headers",
+    ],
+    static_libs: ["libaudioutils" ],
+}
diff --git a/media/libeffects/downmix/Android.mk b/media/libeffects/downmix/Android.mk
deleted file mode 100644
index a5fbf14..0000000
--- a/media/libeffects/downmix/Android.mk
+++ /dev/null
@@ -1,28 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-# Multichannel downmix effect library
-include $(CLEAR_VARS)
-
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES:= \
-	EffectDownmix.c
-
-LOCAL_SHARED_LIBRARIES := \
-	libcutils liblog
-
-LOCAL_MODULE:= libdownmix
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_RELATIVE_PATH := soundfx
-
-LOCAL_C_INCLUDES := \
-	$(call include-path-for, audio-effects) \
-	$(call include-path-for, audio-utils)
-
-#-DBUILD_FLOAT
-LOCAL_CFLAGS += -fvisibility=hidden
-LOCAL_CFLAGS += -Wall -Werror
-
-LOCAL_HEADER_LIBRARIES += libhardware_headers
-include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libeffects/downmix/EffectDownmix.c b/media/libeffects/downmix/EffectDownmix.c
index b4a1d77..99ac4f5 100644
--- a/media/libeffects/downmix/EffectDownmix.c
+++ b/media/libeffects/downmix/EffectDownmix.c
@@ -31,10 +31,12 @@
 // Do not submit with DOWNMIX_ALWAYS_USE_GENERIC_DOWNMIXER defined, strictly for testing
 //#define DOWNMIX_ALWAYS_USE_GENERIC_DOWNMIXER 0
 
-#define MINUS_3_DB_IN_Q19_12 2896 // -3dB = 0.707 * 2^12 = 2896
-
 #ifdef BUILD_FLOAT
 #define MINUS_3_DB_IN_FLOAT 0.70710678f // -3dB = 0.70710678f
+const audio_format_t gTargetFormat = AUDIO_FORMAT_PCM_FLOAT;
+#else
+#define MINUS_3_DB_IN_Q19_12 2896 // -3dB = 0.707 * 2^12 = 2896
+const audio_format_t gTargetFormat = AUDIO_FORMAT_PCM_16_BIT;
 #endif
 
 // subset of possible audio_channel_mask_t values, and AUDIO_CHANNEL_OUT_* renamed to CHANNEL_MASK_*
@@ -703,7 +705,7 @@
     memset(&pDwmModule->context, 0, sizeof(downmix_object_t));
 
     pDwmModule->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
-    pDwmModule->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
+    pDwmModule->config.inputCfg.format = gTargetFormat;
     pDwmModule->config.inputCfg.channels = AUDIO_CHANNEL_OUT_7POINT1;
     pDwmModule->config.inputCfg.bufferProvider.getBuffer = NULL;
     pDwmModule->config.inputCfg.bufferProvider.releaseBuffer = NULL;
@@ -715,7 +717,7 @@
 
     // set a default value for the access mode, but should be overwritten by caller
     pDwmModule->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
-    pDwmModule->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
+    pDwmModule->config.outputCfg.format = gTargetFormat;
     pDwmModule->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
     pDwmModule->config.outputCfg.bufferProvider.getBuffer = NULL;
     pDwmModule->config.outputCfg.bufferProvider.releaseBuffer = NULL;
@@ -762,8 +764,8 @@
     // Check configuration compatibility with build options, and effect capabilities
     if (pConfig->inputCfg.samplingRate != pConfig->outputCfg.samplingRate
         || pConfig->outputCfg.channels != DOWNMIX_OUTPUT_CHANNELS
-        || pConfig->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT
-        || pConfig->outputCfg.format != AUDIO_FORMAT_PCM_16_BIT) {
+        || pConfig->inputCfg.format != gTargetFormat
+        || pConfig->outputCfg.format != gTargetFormat) {
         ALOGE("Downmix_Configure error: invalid config");
         return -EINVAL;
     }
@@ -1185,8 +1187,8 @@
     if (accumulate) {
         while (numFrames) {
             // centerPlusLfeContrib = FC(-3dB) + LFE(-3dB)
-            centerPlusLfeContrib = (pSrc[2] * MINUS_3_DB_IN_Q19_12)
-                    + (pSrc[3] * MINUS_3_DB_IN_Q19_12);
+            centerPlusLfeContrib = (pSrc[2] * MINUS_3_DB_IN_FLOAT)
+                    + (pSrc[3] * MINUS_3_DB_IN_FLOAT);
             // FL + centerPlusLfeContrib + SL + RL
             lt = pSrc[0] + centerPlusLfeContrib + pSrc[6] + pSrc[4];
             // FR + centerPlusLfeContrib + SR + RR
@@ -1427,4 +1429,4 @@
     }
     return true;
 }
-#endif
\ No newline at end of file
+#endif
diff --git a/media/libeffects/downmix/tests/Android.bp b/media/libeffects/downmix/tests/Android.bp
new file mode 100644
index 0000000..63afc54
--- /dev/null
+++ b/media/libeffects/downmix/tests/Android.bp
@@ -0,0 +1,30 @@
+// Build testbench for downmix module.
+cc_test {
+    name:"downmixtest",
+    host_supported: false,
+    proprietary: true,
+    include_dirs: [
+        "frameworks/av/media/libeffects/downmix",
+    ],
+
+    header_libs: [
+        "libaudioeffects",
+    ],
+
+    shared_libs: [
+        "libaudioutils",
+        "libdownmix",
+        "liblog",
+    ],
+
+    relative_install_path: "soundfx",
+
+    srcs: [
+        "downmixtest.cpp",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wextra",
+    ],
+}
diff --git a/media/libeffects/downmix/tests/build_and_run_all_unit_tests.sh b/media/libeffects/downmix/tests/build_and_run_all_unit_tests.sh
new file mode 100755
index 0000000..d0faebe
--- /dev/null
+++ b/media/libeffects/downmix/tests/build_and_run_all_unit_tests.sh
@@ -0,0 +1,69 @@
+#!/bin/bash
+#
+#Run tests in this directory.
+#
+
+if [ -z "$ANDROID_BUILD_TOP" ]; then
+    echo "Android build environment not set"
+    exit -1
+fi
+#ensure we have mm
+. $ANDROID_BUILD_TOP/build/envsetup.sh
+
+mm -j
+
+echo "waiting for device"
+
+adb root && adb wait-for-device remount
+
+#location of test files
+testdir="/data/local/tmp/downmixtest"
+
+fs_arr=(
+    8000
+    11025
+    12000
+    16000
+    22050
+    24000
+    32000
+    44100
+    48000
+    88200
+    96000
+    176400
+    192000
+)
+
+echo "========================================"
+echo "testing Downmix"
+adb shell mkdir $testdir
+
+adb push $ANDROID_BUILD_TOP/cts/tests/tests/media/res/raw/sinesweepraw.raw \
+$testdir
+adb push $OUT/testcases/downmixtest/arm64/downmixtest $testdir
+
+#run the downmix test application for test.
+for fs in ${fs_arr[*]}
+do
+    for f_ch in {1..8}
+    do
+        for ch_fmt in {0..4}
+        do
+            adb shell  LD_LIBRARY_PATH=/vendor/lib64/soundfx \
+            $testdir/downmixtest $testdir/sinesweepraw.raw \
+            $testdir/sinesweep_fmt_$((ch_fmt))_fch_$((f_ch))_$((fs)).raw \
+            -ch_fmt:$ch_fmt -fch:$f_ch -fs:$fs
+
+            # Implementation dependent test:
+            # check that higher frequencies match 8 kHz result.
+            if [ $fs != 8000 ]
+            then
+                adb shell cmp \
+                $testdir/sinesweep_fmt_$((ch_fmt))_fch_$((f_ch))_8000.raw \
+                $testdir/sinesweep_fmt_$((ch_fmt))_fch_$((f_ch))_$((fs)).raw
+            fi
+        done
+    done
+done
+adb shell rm -r $testdir
diff --git a/media/libeffects/downmix/tests/downmixtest.cpp b/media/libeffects/downmix/tests/downmixtest.cpp
new file mode 100644
index 0000000..71f83e5
--- /dev/null
+++ b/media/libeffects/downmix/tests/downmixtest.cpp
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <inttypes.h>
+#include <stdlib.h>
+#include <string.h>
+#include <vector>
+
+#include <audio_effects/effect_downmix.h>
+#include <audio_utils/channels.h>
+#include <audio_utils/primitives.h>
+#include <log/log.h>
+#include <system/audio.h>
+
+#include "EffectDownmix.h"
+#define FRAME_LENGTH 256
+#define MAX_NUM_CHANNELS 8
+
+struct downmix_cntxt_s {
+  effect_descriptor_t desc;
+  effect_handle_t handle;
+  effect_config_t config;
+
+  int numFileChannels;
+  int numProcessChannels;
+};
+
+extern audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM;
+
+void printUsage() {
+  printf("\nUsage:");
+  printf("\n     downmixtest <input_file> <out_file> [options]\n");
+  printf("\nwhere,");
+  printf("\n     <input_file>  is the input file name");
+  printf("\n                  on which LVM effects are applied");
+  printf("\n     <output_file> processed output file");
+  printf("\n     and options are mentioned below");
+  printf("\n");
+  printf("\n      -h");
+  printf("\n           Prints this usage information");
+  printf("\n");
+  printf("\n     -ch_fmt:<format_of_input_audio>");
+  printf("\n         0:AUDIO_CHANNEL_OUT_7POINT1(default)");
+  printf("\n         1:AUDIO_CHANNEL_OUT_5POINT1_SIDE");
+  printf("\n         2:AUDIO_CHANNEL_OUT_5POINT1_BACK");
+  printf("\n         3:AUDIO_CHANNEL_OUT_QUAD_SIDE");
+  printf("\n         4:AUDIO_CHANNEL_OUT_QUAD_BACK");
+  printf("\n");
+  printf("\n     -fch:<file_channels> (1 through 8)");
+  printf("\n");
+}
+
+int32_t DownmixDefaultConfig(effect_config_t *pConfig) {
+  pConfig->inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
+  pConfig->inputCfg.format = AUDIO_FORMAT_PCM_FLOAT;
+  pConfig->inputCfg.channels = AUDIO_CHANNEL_OUT_7POINT1;
+  pConfig->inputCfg.bufferProvider.getBuffer = nullptr;
+  pConfig->inputCfg.bufferProvider.releaseBuffer = nullptr;
+  pConfig->inputCfg.bufferProvider.cookie = nullptr;
+  pConfig->inputCfg.mask = EFFECT_CONFIG_ALL;
+
+  pConfig->inputCfg.samplingRate = 44100;
+  pConfig->outputCfg.samplingRate = pConfig->inputCfg.samplingRate;
+
+  // set a default value for the access mode, but should be overwritten by caller
+  pConfig->outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE;
+  pConfig->outputCfg.format = AUDIO_FORMAT_PCM_FLOAT;
+  pConfig->outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+  pConfig->outputCfg.bufferProvider.getBuffer = nullptr;
+  pConfig->outputCfg.bufferProvider.releaseBuffer = nullptr;
+  pConfig->outputCfg.bufferProvider.cookie = nullptr;
+  pConfig->outputCfg.mask = EFFECT_CONFIG_ALL;
+
+  return 0;
+}
+
+int32_t DownmixConfiureAndEnable(downmix_cntxt_s *pDescriptor) {
+  effect_handle_t *effectHandle = &pDescriptor->handle;
+  downmix_module_t *downmixEffectHandle = (downmix_module_t *)*effectHandle;
+  const struct effect_interface_s *Downmix_api = downmixEffectHandle->itfe;
+  int32_t err = 0;
+  uint32_t replySize = (uint32_t)sizeof(err);
+
+  err = (Downmix_api->command)(*effectHandle, EFFECT_CMD_SET_CONFIG,
+                               sizeof(effect_config_t), &(pDescriptor->config),
+                               &replySize, &err);
+  if (err != 0) {
+    ALOGE("Downmix command to configure returned an error %d", err);
+    return err;
+  }
+
+  err = ((Downmix_api->command))(*effectHandle, EFFECT_CMD_ENABLE, 0, nullptr,
+                                 &replySize, &err);
+  if (err != 0) {
+    ALOGE("Downmix command to enable effect returned an error %d", err);
+    return err;
+  }
+  return 0;
+}
+
+int32_t DownmixExecute(downmix_cntxt_s *pDescriptor, FILE *finp,
+                       FILE *fout) {
+  effect_handle_t *effectHandle = &pDescriptor->handle;
+  downmix_module_t *downmixEffectHandle = (downmix_module_t *)*effectHandle;
+  const struct effect_interface_s *Downmix_api = downmixEffectHandle->itfe;
+
+  const int numFileChannels = pDescriptor->numFileChannels;
+  const int numProcessChannels = pDescriptor->numProcessChannels;
+  const int fileFrameSize = numFileChannels * sizeof(short);
+  const unsigned int outputChannels =
+      audio_channel_count_from_out_mask(AUDIO_CHANNEL_OUT_STEREO);
+
+  std::vector<float> outFloat(FRAME_LENGTH * MAX_NUM_CHANNELS);
+  std::vector<float> inFloat(FRAME_LENGTH * MAX_NUM_CHANNELS);
+
+  audio_buffer_t inbuffer, outbuffer;
+  inbuffer.f32 = inFloat.data();
+  outbuffer.f32 = outFloat.data();
+  inbuffer.frameCount = FRAME_LENGTH;
+  outbuffer.frameCount = FRAME_LENGTH;
+
+  audio_buffer_t *pinbuf, *poutbuf;
+  pinbuf = &inbuffer;
+  poutbuf = &outbuffer;
+
+  int frameCounter = 0;
+  std::vector<short> inS16(FRAME_LENGTH * MAX_NUM_CHANNELS);
+  std::vector<short> outS16(FRAME_LENGTH * MAX_NUM_CHANNELS);
+
+  while (fread(inS16.data(), fileFrameSize, FRAME_LENGTH, finp) ==
+         FRAME_LENGTH) {
+    if (numFileChannels != numProcessChannels) {
+      adjust_channels(inS16.data(), numFileChannels, inS16.data(),
+                      numProcessChannels, sizeof(short),
+                      FRAME_LENGTH * fileFrameSize);
+    }
+
+    memcpy_to_float_from_i16(inFloat.data(), inS16.data(),
+                             FRAME_LENGTH * numProcessChannels);
+
+    const int32_t err = (Downmix_api->process)(*effectHandle, pinbuf, poutbuf);
+    if (err != 0) {
+      ALOGE("DownmixProcess returned an error %d", err);
+      return -1;
+    }
+
+    memcpy_to_i16_from_float(outS16.data(), outFloat.data(),
+                             FRAME_LENGTH * outputChannels);
+    fwrite(outS16.data(), sizeof(short), (FRAME_LENGTH * outputChannels),
+           fout);
+    frameCounter++;
+  }
+  printf("frameCounter: [%d]\n", frameCounter);
+  return 0;
+}
+
+int32_t DowmixMainProcess(downmix_cntxt_s *pDescriptor, FILE *finp,
+                          FILE *fout) {
+  effect_handle_t *effectHandle = &pDescriptor->handle;
+  int32_t sessionId = 0, ioId = 0;
+  const effect_uuid_t downmix_uuid = {
+      0x93f04452, 0xe4fe, 0x41cc, 0x91f9, {0xe4, 0x75, 0xb6, 0xd1, 0xd6, 0x9f}};
+
+  int32_t err = AUDIO_EFFECT_LIBRARY_INFO_SYM.create_effect(
+      &downmix_uuid, sessionId, ioId,
+      effectHandle);
+  if (err != 0) {
+    ALOGE("DownmixLib_Create returned an error %d", err);
+    return -1;
+  }
+
+  // Passing the init config for time being.
+  err = DownmixConfiureAndEnable(pDescriptor);
+  if (err != 0) {
+    ALOGE("DownmixConfigureAndEnable returned an error %d", err);
+    return -1;
+  }
+  // execute call for downmix.
+  err = DownmixExecute(pDescriptor, finp, fout);
+  if (err != 0) {
+    ALOGE("DownmixExecute returned an error %d", err);
+    return -1;
+  }
+  // Release the library function.
+  err = AUDIO_EFFECT_LIBRARY_INFO_SYM.release_effect(*effectHandle);
+  if (err != 0) {
+    ALOGE("DownmixRelease returned an error %d", err);
+    return -1;
+  }
+  return 0;
+}
+
+int main(int argc, const char *argv[]) {
+  int numFileChannels = 1, numProcessChannels = 8;
+  downmix_cntxt_s descriptor = {};
+  DownmixDefaultConfig(&(descriptor.config));
+
+  const char *infile = nullptr;
+  const char *outfile = nullptr;
+  for (int i = 1; i < argc; i++) {
+    printf("%s ", argv[i]);
+    if (argv[i][0] != '-') {
+      if (infile == nullptr) {
+        infile = argv[i];
+      } else if (outfile == nullptr) {
+        outfile = argv[i];
+      } else {
+        printUsage();
+        return -1;
+      }
+    } else if (!strncmp(argv[i], "-fs:", 4)) {
+      // Add a check for all the supported streams.
+      const int samplingFreq = atoi(argv[i] + 4);
+      if (samplingFreq != 8000 && samplingFreq != 11025 &&
+          samplingFreq != 12000 && samplingFreq != 16000 &&
+          samplingFreq != 22050 && samplingFreq != 24000 &&
+          samplingFreq != 32000 && samplingFreq != 44100 &&
+          samplingFreq != 48000 && samplingFreq != 88200 &&
+          samplingFreq != 96000 && samplingFreq != 176400 &&
+          samplingFreq != 192000) {
+        printf("Unsupported Sampling Frequency : %d", samplingFreq);
+        printUsage();
+        return -1;
+      }
+
+      descriptor.config.inputCfg.samplingRate = samplingFreq;
+      descriptor.config.outputCfg.samplingRate = samplingFreq;
+    } else if (!strncmp(argv[i], "-ch_fmt:", 8)) {
+      const int format = atoi(argv[i] + 8);
+      uint32_t *audioType = &descriptor.config.inputCfg.channels;
+      switch (format) {
+        case 0:
+          *audioType = AUDIO_CHANNEL_OUT_7POINT1;
+          break;
+        case 1:
+          *audioType = AUDIO_CHANNEL_OUT_5POINT1_SIDE;
+          break;
+        case 2:
+          *audioType = AUDIO_CHANNEL_OUT_5POINT1_BACK;
+          break;
+        case 3:
+          *audioType = AUDIO_CHANNEL_OUT_QUAD_SIDE;
+          break;
+        case 4:
+          *audioType = AUDIO_CHANNEL_OUT_QUAD_BACK;
+          break;
+        default:
+          *audioType = AUDIO_CHANNEL_OUT_7POINT1;
+          break;
+      }
+      descriptor.numProcessChannels =
+          audio_channel_count_from_out_mask(*audioType);
+    } else if (!strncmp(argv[i], "-fch:", 5)) {
+      const int fChannels = atoi(argv[i] + 5);
+      if (fChannels > 8 || fChannels < 1) {
+        printf("Unsupported number of file channels : %d", fChannels);
+        printUsage();
+        return -1;
+      }
+      descriptor.numFileChannels = fChannels;
+
+    } else if (!strncmp(argv[i], "-h", 2)) {
+      printUsage();
+      return 0;
+    }
+  }
+
+  if (/*infile == nullptr || */ outfile == nullptr) {
+    printUsage();
+    return -1;
+  }
+
+  FILE *finp = fopen(infile, "rb");
+  if (finp == nullptr) {
+    printf("Cannot open input file %s", infile);
+    return -1;
+  }
+  FILE *fout = fopen(outfile, "wb");
+  if (fout == nullptr) {
+    printf("Cannot open output file %s", outfile);
+    fclose(finp);
+    return -1;
+  }
+
+  const int err = DowmixMainProcess(&descriptor, finp, fout);
+  // close input and output files.
+  fclose(finp);
+  fclose(fout);
+  if (err != 0) {
+    printf("Error: %d\n", err);
+  }
+  return err;
+}
diff --git a/media/libeffects/dynamicsproc/Android.bp b/media/libeffects/dynamicsproc/Android.bp
new file mode 100644
index 0000000..eafc483
--- /dev/null
+++ b/media/libeffects/dynamicsproc/Android.bp
@@ -0,0 +1,46 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// DynamicsProcessing library
+cc_library_shared {
+    name: "libdynproc",
+
+    vendor: true,
+
+    srcs: [
+        "EffectDynamicsProcessing.cpp",
+        "dsp/DPBase.cpp",
+        "dsp/DPFrequency.cpp",
+    ],
+
+    cflags: [
+        "-O2",
+        "-fvisibility=hidden",
+
+        "-Wall",
+        "-Werror",
+    ],
+
+    shared_libs: [
+        "libcutils",
+        "liblog",
+    ],
+
+    relative_install_path: "soundfx",
+
+    header_libs: [
+        "libaudioeffects",
+        "libeigen",
+    ],
+}
diff --git a/media/libeffects/dynamicsproc/Android.mk b/media/libeffects/dynamicsproc/Android.mk
deleted file mode 100644
index 7be0c49..0000000
--- a/media/libeffects/dynamicsproc/Android.mk
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-# DynamicsProcessing library
-include $(CLEAR_VARS)
-
-LOCAL_VENDOR_MODULE := true
-
-EIGEN_PATH := external/eigen
-LOCAL_C_INCLUDES += $(EIGEN_PATH)
-
-LOCAL_SRC_FILES:= \
-    EffectDynamicsProcessing.cpp \
-    dsp/DPBase.cpp \
-    dsp/DPFrequency.cpp
-
-LOCAL_CFLAGS+= -O2 -fvisibility=hidden
-LOCAL_CFLAGS += -Wall -Werror
-
-LOCAL_SHARED_LIBRARIES := \
-    libcutils \
-    liblog \
-
-LOCAL_MODULE_RELATIVE_PATH := soundfx
-LOCAL_MODULE:= libdynproc
-
-LOCAL_HEADER_LIBRARIES := \
-    libaudioeffects
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libeffects/dynamicsproc/EffectDynamicsProcessing.cpp b/media/libeffects/dynamicsproc/EffectDynamicsProcessing.cpp
index 0b883f1..c03c6ed 100644
--- a/media/libeffects/dynamicsproc/EffectDynamicsProcessing.cpp
+++ b/media/libeffects/dynamicsproc/EffectDynamicsProcessing.cpp
@@ -25,6 +25,7 @@
 #include <new>
 
 #include <log/log.h>
+#include <sys/param.h>
 
 #include <audio_effects/effect_dynamicsprocessing.h>
 #include <dsp/DPBase.h>
@@ -225,10 +226,6 @@
     } //switch
 }
 
-static inline bool isPowerOf2(unsigned long n) {
-    return (n & (n - 1)) == 0;
-}
-
 void DP_configureVariant(DynamicsProcessingContext *pContext, int newVariant) {
     ALOGV("DP_configureVariant %d", newVariant);
     switch(newVariant) {
@@ -242,7 +239,7 @@
                 desiredBlock);
         if (desiredBlock < minBlockSize) {
             currentBlock = minBlockSize;
-        } else if (!isPowerOf2(desiredBlock)) {
+        } else if (!powerof2(desiredBlock)) {
             //find next highest power of 2.
             currentBlock = 1 << (32 - __builtin_clz(desiredBlock));
         }
@@ -1297,4 +1294,3 @@
 };
 
 }; // extern "C"
-
diff --git a/media/libeffects/dynamicsproc/dsp/DPFrequency.cpp b/media/libeffects/dynamicsproc/dsp/DPFrequency.cpp
index d06fd70..ae5c020 100644
--- a/media/libeffects/dynamicsproc/dsp/DPFrequency.cpp
+++ b/media/libeffects/dynamicsproc/dsp/DPFrequency.cpp
@@ -20,6 +20,7 @@
 #include <log/log.h>
 #include "DPFrequency.h"
 #include <algorithm>
+#include <sys/param.h>
 
 namespace dp_fx {
 
@@ -30,10 +31,6 @@
 #define CIRCULAR_BUFFER_UPSAMPLE 4  //4 times buffer size
 
 static constexpr float MIN_ENVELOPE = 1e-6f; //-120 dB
-//helper functionS
-static inline bool isPowerOf2(unsigned long n) {
-    return (n & (n - 1)) == 0;
-}
 static constexpr float EPSILON = 0.0000001f;
 
 static inline bool isZero(float f) {
@@ -65,11 +62,6 @@
     cBInput.resize(mBlockSize * CIRCULAR_BUFFER_UPSAMPLE);
     cBOutput.resize(mBlockSize * CIRCULAR_BUFFER_UPSAMPLE);
 
-    //fill input with half block size...
-    for (unsigned int k = 0; k < mBlockSize/2; k++) {
-        cBInput.write(0);
-    }
-
     //temp vectors
     input.resize(mBlockSize);
     output.resize(mBlockSize);
@@ -151,7 +143,7 @@
     } else if (mBlockSize < MIN_BLOCKSIZE) {
         mBlockSize = MIN_BLOCKSIZE;
     } else {
-        if (!isPowerOf2(blockSize)) {
+        if (!powerof2(blockSize)) {
             //find next highest power of 2.
             mBlockSize = 1 << (32 - __builtin_clz(blockSize));
         }
@@ -173,6 +165,11 @@
 
     fill_window(mVWindow, RDSP_WINDOW_HANNING_FLAT_TOP, mBlockSize, mOverlapSize);
 
+    //split window into analysis and synthesis. Both are the sqrt() of original
+    //window
+    Eigen::Map<Eigen::VectorXf> eWindow(&mVWindow[0], mVWindow.size());
+    eWindow = eWindow.array().sqrt();
+
     //compute window rms for energy compensation
     mWindowRms = 0;
     for (size_t i = 0; i < mVWindow.size(); i++) {
@@ -669,6 +666,11 @@
     //##ifft directly to output.
     Eigen::Map<Eigen::VectorXf> eOutput(&cb.output[0], cb.output.size());
     mFftServer.inv(eOutput, cb.complexTemp);
+
+    //apply rest of window for resynthesis
+    Eigen::Map<Eigen::VectorXf> eWindow(&mVWindow[0], mVWindow.size());
+    eOutput = eOutput.cwiseProduct(eWindow);
+
     return mBlockSize;
 }
 
diff --git a/media/libeffects/loudness/Android.bp b/media/libeffects/loudness/Android.bp
new file mode 100644
index 0000000..5a13af6
--- /dev/null
+++ b/media/libeffects/loudness/Android.bp
@@ -0,0 +1,27 @@
+// LoudnessEnhancer library
+cc_library_shared {
+    name: "libldnhncr",
+
+    vendor: true,
+    srcs: [
+        "EffectLoudnessEnhancer.cpp",
+        "dsp/core/dynamic_range_compression.cpp",
+    ],
+
+    cflags: [
+        "-O2",
+        "-fvisibility=hidden",
+
+        "-Wall",
+        "-Werror",
+    ],
+
+    shared_libs: [
+        "libcutils",
+        "liblog",
+    ],
+
+    relative_install_path: "soundfx",
+
+    header_libs: ["libaudioeffects"],
+}
diff --git a/media/libeffects/loudness/Android.mk b/media/libeffects/loudness/Android.mk
deleted file mode 100644
index 712cbd5..0000000
--- a/media/libeffects/loudness/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-# LoudnessEnhancer library
-include $(CLEAR_VARS)
-
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES:= \
-    EffectLoudnessEnhancer.cpp \
-    dsp/core/dynamic_range_compression.cpp
-
-LOCAL_CFLAGS+= -O2 -fvisibility=hidden
-LOCAL_CFLAGS += -Wall -Werror
-
-LOCAL_SHARED_LIBRARIES := \
-    libcutils \
-    liblog \
-
-LOCAL_MODULE_RELATIVE_PATH := soundfx
-LOCAL_MODULE:= libldnhncr
-
-LOCAL_HEADER_LIBRARIES := \
-    libaudioeffects
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libeffects/loudness/EffectLoudnessEnhancer.cpp b/media/libeffects/loudness/EffectLoudnessEnhancer.cpp
index 9d29cf1..d61efd3 100644
--- a/media/libeffects/loudness/EffectLoudnessEnhancer.cpp
+++ b/media/libeffects/loudness/EffectLoudnessEnhancer.cpp
@@ -30,6 +30,26 @@
 #include <audio_effects/effect_loudnessenhancer.h>
 #include "dsp/core/dynamic_range_compression.h"
 
+// BUILD_FLOAT targets building a float effect instead of the legacy int16_t effect.
+#define BUILD_FLOAT
+
+#ifdef BUILD_FLOAT
+
+static constexpr audio_format_t kProcessFormat = AUDIO_FORMAT_PCM_FLOAT;
+
+#else
+
+static constexpr audio_format_t kProcessFormat = AUDIO_FORMAT_PCM_16_BIT;
+
+static inline int16_t clamp16(int32_t sample)
+{
+    if ((sample>>15) ^ (sample>>31))
+        sample = 0x7FFF ^ (sample>>31);
+    return sample;
+}
+
+#endif // BUILD_FLOAT
+
 extern "C" {
 
 // effect_handle_t interface implementation for LE effect
@@ -80,13 +100,6 @@
     }
 }
 
-static inline int16_t clamp16(int32_t sample)
-{
-    if ((sample>>15) ^ (sample>>31))
-        sample = 0x7FFF ^ (sample>>31);
-    return sample;
-}
-
 //----------------------------------------------------------------------------
 // LE_setConfig()
 //----------------------------------------------------------------------------
@@ -111,7 +124,7 @@
     if (pConfig->inputCfg.channels != AUDIO_CHANNEL_OUT_STEREO) return -EINVAL;
     if (pConfig->outputCfg.accessMode != EFFECT_BUFFER_ACCESS_WRITE &&
             pConfig->outputCfg.accessMode != EFFECT_BUFFER_ACCESS_ACCUMULATE) return -EINVAL;
-    if (pConfig->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL;
+    if (pConfig->inputCfg.format != kProcessFormat) return -EINVAL;
 
     pContext->mConfig = *pConfig;
 
@@ -159,7 +172,7 @@
 
     pContext->mConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
     pContext->mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
-    pContext->mConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
+    pContext->mConfig.inputCfg.format = kProcessFormat;
     pContext->mConfig.inputCfg.samplingRate = 44100;
     pContext->mConfig.inputCfg.bufferProvider.getBuffer = NULL;
     pContext->mConfig.inputCfg.bufferProvider.releaseBuffer = NULL;
@@ -167,7 +180,7 @@
     pContext->mConfig.inputCfg.mask = EFFECT_CONFIG_ALL;
     pContext->mConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
     pContext->mConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
-    pContext->mConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
+    pContext->mConfig.outputCfg.format = kProcessFormat;
     pContext->mConfig.outputCfg.samplingRate = 44100;
     pContext->mConfig.outputCfg.bufferProvider.getBuffer = NULL;
     pContext->mConfig.outputCfg.bufferProvider.releaseBuffer = NULL;
@@ -284,18 +297,41 @@
 
     //ALOGV("LE about to process %d samples", inBuffer->frameCount);
     uint16_t inIdx;
+#ifdef BUILD_FLOAT
+    constexpr float scale = 1 << 15; // power of 2 is lossless conversion to int16_t range
+    constexpr float inverseScale = 1.f / scale;
+    const float inputAmp = pow(10, pContext->mTargetGainmB/2000.0f) * scale;
+#else
     float inputAmp = pow(10, pContext->mTargetGainmB/2000.0f);
+#endif
     float leftSample, rightSample;
     for (inIdx = 0 ; inIdx < inBuffer->frameCount ; inIdx++) {
         // makeup gain is applied on the input of the compressor
+#ifdef BUILD_FLOAT
+        leftSample  = inputAmp * inBuffer->f32[2*inIdx];
+        rightSample = inputAmp * inBuffer->f32[2*inIdx +1];
+        pContext->mCompressor->Compress(&leftSample, &rightSample);
+        inBuffer->f32[2*inIdx]    = leftSample * inverseScale;
+        inBuffer->f32[2*inIdx +1] = rightSample * inverseScale;
+#else
         leftSample  = inputAmp * (float)inBuffer->s16[2*inIdx];
         rightSample = inputAmp * (float)inBuffer->s16[2*inIdx +1];
         pContext->mCompressor->Compress(&leftSample, &rightSample);
         inBuffer->s16[2*inIdx]    = (int16_t) leftSample;
         inBuffer->s16[2*inIdx +1] = (int16_t) rightSample;
+#endif // BUILD_FLOAT
     }
 
     if (inBuffer->raw != outBuffer->raw) {
+#ifdef BUILD_FLOAT
+        if (pContext->mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
+            for (size_t i = 0; i < outBuffer->frameCount*2; i++) {
+                outBuffer->f32[i] += inBuffer->f32[i];
+            }
+        } else {
+            memcpy(outBuffer->raw, inBuffer->raw, outBuffer->frameCount * 2 * sizeof(float));
+        }
+#else
         if (pContext->mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
             for (size_t i = 0; i < outBuffer->frameCount*2; i++) {
                 outBuffer->s16[i] = clamp16(outBuffer->s16[i] + inBuffer->s16[i]);
@@ -303,6 +339,7 @@
         } else {
             memcpy(outBuffer->raw, inBuffer->raw, outBuffer->frameCount * 2 * sizeof(int16_t));
         }
+#endif // BUILD_FLOAT
     }
     if (pContext->mState != LOUDNESS_ENHANCER_STATE_ACTIVE) {
         return -ENODATA;
diff --git a/media/libeffects/lvm/lib/Android.bp b/media/libeffects/lvm/lib/Android.bp
new file mode 100644
index 0000000..d150f18
--- /dev/null
+++ b/media/libeffects/lvm/lib/Android.bp
@@ -0,0 +1,217 @@
+// Music bundle
+cc_library_static {
+    name: "libmusicbundle",
+
+    arch: {
+        arm: {
+            instruction_set: "arm",
+        },
+    },
+
+    vendor: true,
+    srcs: [
+        "StereoWidening/src/LVCS_BypassMix.c",
+        "StereoWidening/src/LVCS_Control.c",
+        "StereoWidening/src/LVCS_Equaliser.c",
+        "StereoWidening/src/LVCS_Init.c",
+        "StereoWidening/src/LVCS_Process.c",
+        "StereoWidening/src/LVCS_ReverbGenerator.c",
+        "StereoWidening/src/LVCS_StereoEnhancer.c",
+        "StereoWidening/src/LVCS_Tables.c",
+        "Bass/src/LVDBE_Control.c",
+        "Bass/src/LVDBE_Init.c",
+        "Bass/src/LVDBE_Process.c",
+        "Bass/src/LVDBE_Tables.c",
+        "Bundle/src/LVM_API_Specials.c",
+        "Bundle/src/LVM_Buffers.c",
+        "Bundle/src/LVM_Init.c",
+        "Bundle/src/LVM_Process.c",
+        "Bundle/src/LVM_Tables.c",
+        "Bundle/src/LVM_Control.c",
+        "SpectrumAnalyzer/src/LVPSA_Control.c",
+        "SpectrumAnalyzer/src/LVPSA_Init.c",
+        "SpectrumAnalyzer/src/LVPSA_Memory.c",
+        "SpectrumAnalyzer/src/LVPSA_Process.c",
+        "SpectrumAnalyzer/src/LVPSA_QPD_Init.c",
+        "SpectrumAnalyzer/src/LVPSA_QPD_Process.c",
+        "SpectrumAnalyzer/src/LVPSA_Tables.c",
+        "Eq/src/LVEQNB_CalcCoef.c",
+        "Eq/src/LVEQNB_Control.c",
+        "Eq/src/LVEQNB_Init.c",
+        "Eq/src/LVEQNB_Process.c",
+        "Eq/src/LVEQNB_Tables.c",
+        "Common/src/InstAlloc.c",
+        "Common/src/DC_2I_D16_TRC_WRA_01.c",
+        "Common/src/DC_2I_D16_TRC_WRA_01_Init.c",
+        "Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.c",
+        "Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.c",
+        "Common/src/FO_1I_D16F16C15_TRC_WRA_01.c",
+        "Common/src/FO_1I_D16F16Css_TRC_WRA_01_Init.c",
+        "Common/src/BP_1I_D16F32C30_TRC_WRA_01.c",
+        "Common/src/BP_1I_D16F16C14_TRC_WRA_01.c",
+        "Common/src/BP_1I_D32F32C30_TRC_WRA_02.c",
+        "Common/src/BP_1I_D16F16Css_TRC_WRA_01_Init.c",
+        "Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Init.c",
+        "Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Init.c",
+        "Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Init.c",
+        "Common/src/BQ_2I_D32F32C30_TRC_WRA_01.c",
+        "Common/src/BQ_2I_D16F32C15_TRC_WRA_01.c",
+        "Common/src/BQ_2I_D16F32C14_TRC_WRA_01.c",
+        "Common/src/BQ_2I_D16F32C13_TRC_WRA_01.c",
+        "Common/src/BQ_2I_D16F32Css_TRC_WRA_01_init.c",
+        "Common/src/BQ_2I_D16F16C15_TRC_WRA_01.c",
+        "Common/src/BQ_2I_D16F16C14_TRC_WRA_01.c",
+        "Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Init.c",
+        "Common/src/BQ_1I_D16F16C15_TRC_WRA_01.c",
+        "Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Init.c",
+        "Common/src/BQ_1I_D16F32C14_TRC_WRA_01.c",
+        "Common/src/BQ_1I_D16F32Css_TRC_WRA_01_init.c",
+        "Common/src/PK_2I_D32F32C30G11_TRC_WRA_01.c",
+        "Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.c",
+        "Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.c",
+        "Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Init.c",
+        "Common/src/Int16LShiftToInt32_16x32.c",
+        "Common/src/From2iToMono_16.c",
+        "Common/src/Copy_16.c",
+        "Common/src/MonoTo2I_16.c",
+        "Common/src/MonoTo2I_32.c",
+        "Common/src/LoadConst_16.c",
+        "Common/src/LoadConst_32.c",
+        "Common/src/dB_to_Lin32.c",
+        "Common/src/Shift_Sat_v16xv16.c",
+        "Common/src/Shift_Sat_v32xv32.c",
+        "Common/src/Abs_32.c",
+        "Common/src/Int32RShiftToInt16_Sat_32x16.c",
+        "Common/src/From2iToMono_32.c",
+        "Common/src/mult3s_16x16.c",
+        "Common/src/Mult3s_32x16.c",
+        "Common/src/NonLinComp_D16.c",
+        "Common/src/DelayMix_16x16.c",
+        "Common/src/MSTo2i_Sat_16x16.c",
+        "Common/src/From2iToMS_16x16.c",
+        "Common/src/Mac3s_Sat_16x16.c",
+        "Common/src/Mac3s_Sat_32x16.c",
+        "Common/src/Add2_Sat_16x16.c",
+        "Common/src/Add2_Sat_32x32.c",
+        "Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.c",
+        "Common/src/LVC_MixSoft_1St_D16C31_SAT.c",
+        "Common/src/LVC_Mixer_VarSlope_SetTimeConstant.c",
+        "Common/src/LVC_Mixer_SetTimeConstant.c",
+        "Common/src/LVC_Mixer_SetTarget.c",
+        "Common/src/LVC_Mixer_GetTarget.c",
+        "Common/src/LVC_Mixer_Init.c",
+        "Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.c",
+        "Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.c",
+        "Common/src/LVC_Core_MixInSoft_D16C31_SAT.c",
+        "Common/src/LVC_Mixer_GetCurrent.c",
+        "Common/src/LVC_MixSoft_2St_D16C31_SAT.c",
+        "Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.c",
+        "Common/src/LVC_Core_MixHard_2St_D16C31_SAT.c",
+        "Common/src/LVC_MixInSoft_D16C31_SAT.c",
+        "Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.c",
+        "Common/src/LVM_Timer.c",
+        "Common/src/LVM_Timer_Init.c",
+    ],
+
+    local_include_dirs: [
+        "Eq/lib",
+        "Eq/src",
+        "Bass/lib",
+        "Bass/src",
+        "Common/src",
+        "Bundle/src",
+        "SpectrumAnalyzer/lib",
+        "SpectrumAnalyzer/src",
+        "StereoWidening/src",
+        "StereoWidening/lib",
+    ],
+    export_include_dirs: [
+        "Common/lib",
+        "Bundle/lib",
+    ],
+    shared_libs: [
+        "liblog",
+    ],
+    header_libs: [
+        "libhardware_headers"
+    ],
+    cflags: [
+        "-fvisibility=hidden",
+        "-DBUILD_FLOAT",
+        "-DHIGHER_FS",
+        "-DSUPPORT_MC",
+
+        "-Wall",
+        "-Werror",
+    ],
+
+}
+
+// Reverb library
+cc_library_static {
+    name: "libreverb",
+
+    arch: {
+        arm: {
+            instruction_set: "arm",
+        },
+    },
+
+    vendor: true,
+    srcs: [
+        "Reverb/src/LVREV_ApplyNewSettings.c",
+        "Reverb/src/LVREV_ClearAudioBuffers.c",
+        "Reverb/src/LVREV_GetControlParameters.c",
+        "Reverb/src/LVREV_GetInstanceHandle.c",
+        "Reverb/src/LVREV_GetMemoryTable.c",
+        "Reverb/src/LVREV_Process.c",
+        "Reverb/src/LVREV_SetControlParameters.c",
+        "Reverb/src/LVREV_Tables.c",
+        "Common/src/Abs_32.c",
+        "Common/src/InstAlloc.c",
+        "Common/src/LoadConst_16.c",
+        "Common/src/LoadConst_32.c",
+        "Common/src/From2iToMono_32.c",
+        "Common/src/Mult3s_32x16.c",
+        "Common/src/FO_1I_D32F32C31_TRC_WRA_01.c",
+        "Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.c",
+        "Common/src/DelayAllPass_Sat_32x16To32.c",
+        "Common/src/Copy_16.c",
+        "Common/src/Mac3s_Sat_32x16.c",
+        "Common/src/DelayWrite_32.c",
+        "Common/src/Shift_Sat_v32xv32.c",
+        "Common/src/Add2_Sat_32x32.c",
+        "Common/src/JoinTo2i_32x32.c",
+        "Common/src/MonoTo2I_32.c",
+        "Common/src/LVM_FO_HPF.c",
+        "Common/src/LVM_FO_LPF.c",
+        "Common/src/LVM_Polynomial.c",
+        "Common/src/LVM_Power10.c",
+        "Common/src/LVM_GetOmega.c",
+        "Common/src/MixSoft_2St_D32C31_SAT.c",
+        "Common/src/MixSoft_1St_D32C31_WRA.c",
+        "Common/src/MixInSoft_D32C31_SAT.c",
+        "Common/src/LVM_Mixer_TimeConstant.c",
+        "Common/src/Core_MixHard_2St_D32C31_SAT.c",
+        "Common/src/Core_MixSoft_1St_D32C31_WRA.c",
+        "Common/src/Core_MixInSoft_D32C31_SAT.c",
+    ],
+
+    local_include_dirs: [
+        "Reverb/src",
+        "Common/src",
+    ],
+    export_include_dirs: [
+        "Reverb/lib",
+        "Common/lib",
+    ],
+
+    cflags: [
+        "-fvisibility=hidden",
+        "-DBUILD_FLOAT",
+        "-DHIGHER_FS",
+
+        "-Wall",
+        "-Werror",
+    ],
+}
diff --git a/media/libeffects/lvm/lib/Android.mk b/media/libeffects/lvm/lib/Android.mk
deleted file mode 100644
index 941eb3e..0000000
--- a/media/libeffects/lvm/lib/Android.mk
+++ /dev/null
@@ -1,191 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-# Music bundle
-
-include $(CLEAR_VARS)
-
-LOCAL_ARM_MODE := arm
-
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES:= \
-    StereoWidening/src/LVCS_BypassMix.c \
-    StereoWidening/src/LVCS_Control.c \
-    StereoWidening/src/LVCS_Equaliser.c \
-    StereoWidening/src/LVCS_Init.c \
-    StereoWidening/src/LVCS_Process.c \
-    StereoWidening/src/LVCS_ReverbGenerator.c \
-    StereoWidening/src/LVCS_StereoEnhancer.c \
-    StereoWidening/src/LVCS_Tables.c \
-    Bass/src/LVDBE_Control.c \
-    Bass/src/LVDBE_Init.c \
-    Bass/src/LVDBE_Process.c \
-    Bass/src/LVDBE_Tables.c \
-    Bundle/src/LVM_API_Specials.c \
-    Bundle/src/LVM_Buffers.c \
-    Bundle/src/LVM_Init.c \
-    Bundle/src/LVM_Process.c \
-    Bundle/src/LVM_Tables.c \
-    Bundle/src/LVM_Control.c \
-    SpectrumAnalyzer/src/LVPSA_Control.c \
-    SpectrumAnalyzer/src/LVPSA_Init.c \
-    SpectrumAnalyzer/src/LVPSA_Memory.c \
-    SpectrumAnalyzer/src/LVPSA_Process.c \
-    SpectrumAnalyzer/src/LVPSA_QPD_Init.c \
-    SpectrumAnalyzer/src/LVPSA_QPD_Process.c \
-    SpectrumAnalyzer/src/LVPSA_Tables.c \
-    Eq/src/LVEQNB_CalcCoef.c \
-    Eq/src/LVEQNB_Control.c \
-    Eq/src/LVEQNB_Init.c \
-    Eq/src/LVEQNB_Process.c \
-    Eq/src/LVEQNB_Tables.c \
-    Common/src/InstAlloc.c \
-    Common/src/DC_2I_D16_TRC_WRA_01.c \
-    Common/src/DC_2I_D16_TRC_WRA_01_Init.c \
-    Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.c \
-    Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.c \
-    Common/src/FO_1I_D16F16C15_TRC_WRA_01.c \
-    Common/src/FO_1I_D16F16Css_TRC_WRA_01_Init.c \
-    Common/src/BP_1I_D16F32C30_TRC_WRA_01.c \
-    Common/src/BP_1I_D16F16C14_TRC_WRA_01.c \
-    Common/src/BP_1I_D32F32C30_TRC_WRA_02.c \
-    Common/src/BP_1I_D16F16Css_TRC_WRA_01_Init.c \
-    Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Init.c \
-    Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Init.c \
-    Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Init.c \
-    Common/src/BQ_2I_D32F32C30_TRC_WRA_01.c \
-    Common/src/BQ_2I_D16F32C15_TRC_WRA_01.c \
-    Common/src/BQ_2I_D16F32C14_TRC_WRA_01.c \
-    Common/src/BQ_2I_D16F32C13_TRC_WRA_01.c \
-    Common/src/BQ_2I_D16F32Css_TRC_WRA_01_init.c \
-    Common/src/BQ_2I_D16F16C15_TRC_WRA_01.c \
-    Common/src/BQ_2I_D16F16C14_TRC_WRA_01.c \
-    Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Init.c \
-    Common/src/BQ_1I_D16F16C15_TRC_WRA_01.c \
-    Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Init.c \
-    Common/src/BQ_1I_D16F32C14_TRC_WRA_01.c \
-    Common/src/BQ_1I_D16F32Css_TRC_WRA_01_init.c \
-    Common/src/PK_2I_D32F32C30G11_TRC_WRA_01.c \
-    Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.c \
-    Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.c \
-    Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Init.c \
-    Common/src/Int16LShiftToInt32_16x32.c \
-    Common/src/From2iToMono_16.c \
-    Common/src/Copy_16.c \
-    Common/src/MonoTo2I_16.c \
-    Common/src/MonoTo2I_32.c \
-    Common/src/LoadConst_16.c \
-    Common/src/LoadConst_32.c \
-    Common/src/dB_to_Lin32.c \
-    Common/src/Shift_Sat_v16xv16.c \
-    Common/src/Shift_Sat_v32xv32.c \
-    Common/src/Abs_32.c \
-    Common/src/Int32RShiftToInt16_Sat_32x16.c \
-    Common/src/From2iToMono_32.c \
-    Common/src/mult3s_16x16.c \
-    Common/src/Mult3s_32x16.c \
-    Common/src/NonLinComp_D16.c \
-    Common/src/DelayMix_16x16.c \
-    Common/src/MSTo2i_Sat_16x16.c \
-    Common/src/From2iToMS_16x16.c \
-    Common/src/Mac3s_Sat_16x16.c \
-    Common/src/Mac3s_Sat_32x16.c \
-    Common/src/Add2_Sat_16x16.c \
-    Common/src/Add2_Sat_32x32.c \
-    Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.c \
-    Common/src/LVC_MixSoft_1St_D16C31_SAT.c \
-    Common/src/LVC_Mixer_VarSlope_SetTimeConstant.c \
-    Common/src/LVC_Mixer_SetTimeConstant.c \
-    Common/src/LVC_Mixer_SetTarget.c \
-    Common/src/LVC_Mixer_GetTarget.c \
-    Common/src/LVC_Mixer_Init.c \
-    Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.c \
-    Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.c \
-    Common/src/LVC_Core_MixInSoft_D16C31_SAT.c \
-    Common/src/LVC_Mixer_GetCurrent.c \
-    Common/src/LVC_MixSoft_2St_D16C31_SAT.c \
-    Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.c \
-    Common/src/LVC_Core_MixHard_2St_D16C31_SAT.c \
-    Common/src/LVC_MixInSoft_D16C31_SAT.c \
-    Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.c \
-    Common/src/LVM_Timer.c \
-    Common/src/LVM_Timer_Init.c
-
-LOCAL_MODULE:= libmusicbundle
-
-LOCAL_C_INCLUDES += \
-    $(LOCAL_PATH)/Eq/lib \
-    $(LOCAL_PATH)/Eq/src \
-    $(LOCAL_PATH)/Bass/lib \
-    $(LOCAL_PATH)/Bass/src \
-    $(LOCAL_PATH)/Common/lib \
-    $(LOCAL_PATH)/Common/src \
-    $(LOCAL_PATH)/Bundle/lib \
-    $(LOCAL_PATH)/Bundle/src \
-    $(LOCAL_PATH)/SpectrumAnalyzer/lib \
-    $(LOCAL_PATH)/SpectrumAnalyzer/src \
-    $(LOCAL_PATH)/StereoWidening/src \
-    $(LOCAL_PATH)/StereoWidening/lib
-
-LOCAL_CFLAGS += -fvisibility=hidden -DBUILD_FLOAT -DHIGHER_FS
-LOCAL_CFLAGS += -Wall -Werror
-
-include $(BUILD_STATIC_LIBRARY)
-
-
-
-# Reverb library
-include $(CLEAR_VARS)
-
-LOCAL_ARM_MODE := arm
-
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES:= \
-    Reverb/src/LVREV_ApplyNewSettings.c \
-    Reverb/src/LVREV_ClearAudioBuffers.c \
-    Reverb/src/LVREV_GetControlParameters.c \
-    Reverb/src/LVREV_GetInstanceHandle.c \
-    Reverb/src/LVREV_GetMemoryTable.c \
-    Reverb/src/LVREV_Process.c \
-    Reverb/src/LVREV_SetControlParameters.c \
-    Reverb/src/LVREV_Tables.c \
-    Common/src/Abs_32.c \
-    Common/src/InstAlloc.c \
-    Common/src/LoadConst_16.c \
-    Common/src/LoadConst_32.c \
-    Common/src/From2iToMono_32.c \
-    Common/src/Mult3s_32x16.c \
-    Common/src/FO_1I_D32F32C31_TRC_WRA_01.c \
-    Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.c \
-    Common/src/DelayAllPass_Sat_32x16To32.c \
-    Common/src/Copy_16.c \
-    Common/src/Mac3s_Sat_32x16.c \
-    Common/src/DelayWrite_32.c \
-    Common/src/Shift_Sat_v32xv32.c \
-    Common/src/Add2_Sat_32x32.c \
-    Common/src/JoinTo2i_32x32.c \
-    Common/src/MonoTo2I_32.c \
-    Common/src/LVM_FO_HPF.c \
-    Common/src/LVM_FO_LPF.c \
-    Common/src/LVM_Polynomial.c \
-    Common/src/LVM_Power10.c \
-    Common/src/LVM_GetOmega.c \
-    Common/src/MixSoft_2St_D32C31_SAT.c \
-    Common/src/MixSoft_1St_D32C31_WRA.c \
-    Common/src/MixInSoft_D32C31_SAT.c \
-    Common/src/LVM_Mixer_TimeConstant.c \
-    Common/src/Core_MixHard_2St_D32C31_SAT.c \
-    Common/src/Core_MixSoft_1St_D32C31_WRA.c \
-    Common/src/Core_MixInSoft_D32C31_SAT.c
-
-LOCAL_MODULE:= libreverb
-
-LOCAL_C_INCLUDES += \
-    $(LOCAL_PATH)/Reverb/lib \
-    $(LOCAL_PATH)/Reverb/src \
-    $(LOCAL_PATH)/Common/lib \
-    $(LOCAL_PATH)/Common/src
-
-LOCAL_CFLAGS += -fvisibility=hidden -DBUILD_FLOAT -DHIGHER_FS
-LOCAL_CFLAGS += -Wall -Werror
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/media/libeffects/lvm/lib/Bass/lib/LVDBE.h b/media/libeffects/lvm/lib/Bass/lib/LVDBE.h
index 4c2b954..cc066b0 100644
--- a/media/libeffects/lvm/lib/Bass/lib/LVDBE.h
+++ b/media/libeffects/lvm/lib/Bass/lib/LVDBE.h
@@ -199,8 +199,10 @@
 #define LVDBE_CAP_FS_44100               128
 #define LVDBE_CAP_FS_48000               256
 #if defined(BUILD_FLOAT) && defined(HIGHER_FS)
-#define LVDBE_CAP_FS_96000               512
-#define LVDBE_CAP_FS_192000              1024
+#define LVDBE_CAP_FS_88200               512
+#define LVDBE_CAP_FS_96000               1024
+#define LVDBE_CAP_FS_176400              2048
+#define LVDBE_CAP_FS_192000              4096
 #endif
 
 typedef enum
@@ -215,8 +217,10 @@
     LVDBE_FS_44100 = 7,
     LVDBE_FS_48000 = 8,
 #if defined(BUILD_FLOAT) && defined(HIGHER_FS)
-    LVDBE_FS_96000 = 9,
-    LVDBE_FS_192000 = 10,
+    LVDBE_FS_88200 = 9,
+    LVDBE_FS_96000 = 10,
+    LVDBE_FS_176400 = 11,
+    LVDBE_FS_192000 = 12,
 #endif
     LVDBE_FS_MAX   = LVM_MAXINT_32
 } LVDBE_Fs_en;
@@ -256,6 +260,9 @@
     LVDBE_Volume_en         VolumeControl;
     LVM_INT16               VolumedB;
     LVM_INT16               HeadroomdB;
+#ifdef SUPPORT_MC
+    LVM_INT16               NrChannels;
+#endif
 
 } LVDBE_Params_t;
 
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Coeffs.h b/media/libeffects/lvm/lib/Bass/src/LVDBE_Coeffs.h
index 4ecaf14..8f058e8 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Coeffs.h
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Coeffs.h
@@ -580,12 +580,24 @@
 #define HPF_Fs48000_Fc55_B2                       0.989882f
 
 #ifdef HIGHER_FS
+#define HPF_Fs88200_Fc55_A0                       0.985818f
+#define HPF_Fs88200_Fc55_A1                       (-1.971636f)
+#define HPF_Fs88200_Fc55_A2                       0.985818f
+#define HPF_Fs88200_Fc55_B1                       (-1.994466f)
+#define HPF_Fs88200_Fc55_B2                       0.994481f
+
 #define HPF_Fs96000_Fc55_A0                       0.986040f
 #define HPF_Fs96000_Fc55_A1                       (-1.972080f)
 #define HPF_Fs96000_Fc55_A2                       0.986040f
 #define HPF_Fs96000_Fc55_B1                       (-1.994915f)
 #define HPF_Fs96000_Fc55_B2                       0.994928f
 
+#define HPF_Fs176400_Fc55_A0                      0.987183f
+#define HPF_Fs176400_Fc55_A1                      (-1.974366f)
+#define HPF_Fs176400_Fc55_A2                      0.987183f
+#define HPF_Fs176400_Fc55_B1                      (-1.997233f)
+#define HPF_Fs176400_Fc55_B2                      0.997237f
+
 #define HPF_Fs192000_Fc55_A0                      0.987294f
 #define HPF_Fs192000_Fc55_A1                      (-1.974588f)
 #define HPF_Fs192000_Fc55_A2                      0.987294f
@@ -642,12 +654,24 @@
 #define HPF_Fs48000_Fc66_B2                       0.987871f
 
 #ifdef HIGHER_FS
+#define HPF_Fs88200_Fc66_A0                       0.985273f
+#define HPF_Fs88200_Fc66_A1                       (-1.970546f)
+#define HPF_Fs88200_Fc66_A2                       0.985273f
+#define HPF_Fs88200_Fc66_B1                       (-1.993359f)
+#define HPF_Fs88200_Fc66_B2                       0.993381f
+
 #define HPF_Fs96000_Fc66_A0                       0.985539f
 #define HPF_Fs96000_Fc66_A1                       (-1.971077f)
 #define HPF_Fs96000_Fc66_A2                       0.985539f
 #define HPF_Fs96000_Fc66_B1                       (-1.993898f)
 #define HPF_Fs96000_Fc66_B2                       0.993917f
 
+#define HPF_Fs176400_Fc66_A0                      0.986910f
+#define HPF_Fs176400_Fc66_A1                      (-1.973820f)
+#define HPF_Fs176400_Fc66_A2                      0.986910f
+#define HPF_Fs176400_Fc66_B1                      (-1.996679f)
+#define HPF_Fs176400_Fc66_B2                      0.996685f
+
 #define HPF_Fs192000_Fc66_A0                      0.987043f
 #define HPF_Fs192000_Fc66_A1                      (-1.974086f)
 #define HPF_Fs192000_Fc66_A2                      0.987043f
@@ -703,12 +727,24 @@
 #define HPF_Fs48000_Fc78_B2                       0.985681f
 
 #ifdef HIGHER_FS
+#define HPF_Fs88200_Fc78_A0                       0.984678f
+#define HPF_Fs88200_Fc78_A1                       (-1.969356f)
+#define HPF_Fs88200_Fc78_A2                       0.984678f
+#define HPF_Fs88200_Fc78_B1                       (-1.992151f)
+#define HPF_Fs88200_Fc78_B2                       0.992182f
+
 #define HPF_Fs96000_Fc78_A0                       0.984992f
 #define HPF_Fs96000_Fc78_A1                       (-1.969984f)
 #define HPF_Fs96000_Fc78_A2                       0.984992f
 #define HPF_Fs96000_Fc78_B1                       (-1.992789f)
 #define HPF_Fs96000_Fc78_B2                       0.992815f
 
+#define HPF_Fs176400_Fc78_A0                      0.986612f
+#define HPF_Fs176400_Fc78_A1                      (-1.973224f)
+#define HPF_Fs176400_Fc78_A2                      0.986612f
+#define HPF_Fs176400_Fc78_B1                      (-1.996076f)
+#define HPF_Fs176400_Fc78_B2                      0.996083f
+
 #define HPF_Fs192000_Fc78_A0                      0.986769f
 #define HPF_Fs192000_Fc78_A1                      (-1.973539f)
 #define HPF_Fs192000_Fc78_A2                      0.986769f
@@ -764,12 +800,24 @@
 #define HPF_Fs48000_Fc90_B2                      0.983497f
 
 #ifdef HIGHER_FS
+#define HPF_Fs88200_Fc90_A0                       0.984084f
+#define HPF_Fs88200_Fc90_A1                       (-1.968168f)
+#define HPF_Fs88200_Fc90_A2                       0.984084f
+#define HPF_Fs88200_Fc90_B1                       (-1.990944f)
+#define HPF_Fs88200_Fc90_B2                       0.990985f
+
 #define HPF_Fs96000_Fc90_A0                       0.984446f
 #define HPF_Fs96000_Fc90_A1                       (-1.968892f)
 #define HPF_Fs96000_Fc90_A2                       0.984446f
 #define HPF_Fs96000_Fc90_B1                       (-1.991680f)
 #define HPF_Fs96000_Fc90_B2                       0.991714f
 
+#define HPF_Fs176400_Fc90_A0                      0.986314f
+#define HPF_Fs176400_Fc90_A1                      (-1.972629f)
+#define HPF_Fs176400_Fc90_A2                      0.986314f
+#define HPF_Fs176400_Fc90_B1                      (-1.995472f)
+#define HPF_Fs176400_Fc90_B2                      0.995482f
+
 #define HPF_Fs192000_Fc90_A0                      0.986496f
 #define HPF_Fs192000_Fc90_A1                      (-1.972992f)
 #define HPF_Fs192000_Fc90_A2                      0.986496f
@@ -831,12 +879,24 @@
 #define BPF_Fs48000_Fc55_B2                      0.996875f
 
 #ifdef HIGHER_FS
+#define BPF_Fs88200_Fc55_A0                      0.000831f
+#define BPF_Fs88200_Fc55_A1                      0.000000f
+#define BPF_Fs88200_Fc55_A2                      (-0.000831f)
+#define BPF_Fs88200_Fc55_B1                      (-1.998321f)
+#define BPF_Fs88200_Fc55_B2                      0.998338f
+
 #define BPF_Fs96000_Fc55_A0                      0.000762f
 #define BPF_Fs96000_Fc55_A1                      0.000000f
 #define BPF_Fs96000_Fc55_A2                      (-0.000762f)
 #define BPF_Fs96000_Fc55_B1                      (-1.998461f)
 #define BPF_Fs96000_Fc55_B2                      0.998477f
 
+#define BPF_Fs176400_Fc55_A0                     0.000416f
+#define BPF_Fs176400_Fc55_A1                     0.000000f
+#define BPF_Fs176400_Fc55_A2                     (-0.000416f)
+#define BPF_Fs176400_Fc55_B1                     (-1.999164f)
+#define BPF_Fs176400_Fc55_B2                     0.999169f
+
 #define BPF_Fs192000_Fc55_A0                     0.000381f
 #define BPF_Fs192000_Fc55_A1                     0.000000f
 #define BPF_Fs192000_Fc55_A2                     (-0.000381f)
@@ -892,12 +952,24 @@
 #define BPF_Fs48000_Fc66_B2                     0.995690f
 
 #ifdef HIGHER_FS
+#define BPF_Fs88200_Fc66_A0                     0.001146f
+#define BPF_Fs88200_Fc66_A1                     0.000000f
+#define BPF_Fs88200_Fc66_A2                     (-0.001146f)
+#define BPF_Fs88200_Fc66_B1                     (-1.997684f)
+#define BPF_Fs88200_Fc66_B2                     0.997708f
+
 #define BPF_Fs96000_Fc66_A0                     0.001055f
 #define BPF_Fs96000_Fc66_A1                     0.000000f
 #define BPF_Fs96000_Fc66_A2                     (-0.001055f)
 #define BPF_Fs96000_Fc66_B1                     (-1.997868f)
 #define BPF_Fs96000_Fc66_B2                     0.997891f
 
+#define BPF_Fs176400_Fc66_A0                    0.000573f
+#define BPF_Fs176400_Fc66_A1                    0.000000f
+#define BPF_Fs176400_Fc66_A2                    (-0.000573f)
+#define BPF_Fs176400_Fc66_B1                    (-1.998847f)
+#define BPF_Fs176400_Fc66_B2                    0.998853f
+
 #define BPF_Fs192000_Fc66_A0                    0.000528f
 #define BPF_Fs192000_Fc66_A1                    0.000000f
 #define BPF_Fs192000_Fc66_A2                   (-0.000528f)
@@ -953,12 +1025,24 @@
 #define BPF_Fs48000_Fc78_B2                     0.993639f
 
 #ifdef HIGHER_FS
+#define BPF_Fs88200_Fc78_A0                    0.001693f
+#define BPF_Fs88200_Fc78_A1                    0.000000f
+#define BPF_Fs88200_Fc78_A2                    (-0.001693f)
+#define BPF_Fs88200_Fc78_B1                    (-1.996582f)
+#define BPF_Fs88200_Fc78_B2                    0.996615f
+
 #define BPF_Fs96000_Fc78_A0                     0.001555f
 #define BPF_Fs96000_Fc78_A1                     0.000000f
 #define BPF_Fs96000_Fc78_A2                    (-0.0015555f)
 #define BPF_Fs96000_Fc78_B1                    (-1.996860f)
 #define BPF_Fs96000_Fc78_B2                     0.996891f
 
+#define BPF_Fs176400_Fc78_A0                    0.000847f
+#define BPF_Fs176400_Fc78_A1                    0.000000f
+#define BPF_Fs176400_Fc78_A2                    (-0.000847f)
+#define BPF_Fs176400_Fc78_B1                    (-1.998298f)
+#define BPF_Fs176400_Fc78_B2                    0.998306f
+
 #define BPF_Fs192000_Fc78_A0                    0.000778f
 #define BPF_Fs192000_Fc78_A1                    0.000000f
 #define BPF_Fs192000_Fc78_A2                   (-0.000778f)
@@ -1014,12 +1098,24 @@
 #define BPF_Fs48000_Fc90_B2                      0.992177f
 
 #ifdef HIGHER_FS
+#define BPF_Fs88200_Fc90_A0                      0.002083f
+#define BPF_Fs88200_Fc90_A1                      0.000000f
+#define BPF_Fs88200_Fc90_A2                      (-0.002083f)
+#define BPF_Fs88200_Fc90_B1                      (-1.995791f)
+#define BPF_Fs88200_Fc90_B2                      0.995835f
+
 #define BPF_Fs96000_Fc90_A0                      0.001913f
 #define BPF_Fs96000_Fc90_A1                      0.000000f
 #define BPF_Fs96000_Fc90_A2                     (-0.001913f)
 #define BPF_Fs96000_Fc90_B1                     (-1.996134f)
 #define BPF_Fs96000_Fc90_B2                      0.996174f
 
+#define BPF_Fs176400_Fc90_A0                     0.001042f
+#define BPF_Fs176400_Fc90_A1                     0.000000f
+#define BPF_Fs176400_Fc90_A2                     (-0.001042f)
+#define BPF_Fs176400_Fc90_B1                     (-1.997904f)
+#define BPF_Fs176400_Fc90_B2                     0.997915f
+
 #define BPF_Fs192000_Fc90_A0                     0.000958f
 #define BPF_Fs192000_Fc90_A1                     0.000000f
 #define BPF_Fs192000_Fc90_A2                    (-0.000958f)
@@ -1045,7 +1141,9 @@
 #define AGC_ATTACK_Fs48000                            0.971628f
 
 #ifdef HIGHER_FS
+#define AGC_ATTACK_Fs88200                             0.984458f
 #define AGC_ATTACK_Fs96000                             0.985712f
+#define AGC_ATTACK_Fs176400                            0.992199f
 #define AGC_ATTACK_Fs192000                            0.992830f
 #endif
 
@@ -1062,7 +1160,9 @@
 #define AGC_DECAY_Fs48000                             0.000007f
 
 #ifdef HIGHER_FS
+#define AGC_DECAY_Fs88200                            0.0000038f
 #define AGC_DECAY_FS96000                            0.0000035f
+#define AGC_DECAY_Fs176400                          0.00000188f
 #define AGC_DECAY_FS192000                          0.00000175f
 #endif
 
@@ -1125,7 +1225,9 @@
 #define VOL_TC_Fs44100                                  0.004525f
 #define VOL_TC_Fs48000                                  0.004158f
 #ifdef HIGHER_FS
+#define VOL_TC_Fs88200                                  0.002263f
 #define VOL_TC_Fs96000                                  0.002079f
+#define VOL_TC_Fs176400                                 0.001131f
 #define VOL_TC_Fs192000                                 0.001039f
 #endif
 #define MIX_TC_Fs8000                                   29365         /* Floating point value 0.896151 */
@@ -1138,9 +1240,13 @@
 #define MIX_TC_Fs44100                                  32097         /* Floating point value 0.979515 */
 #define MIX_TC_Fs48000                                  32150         /* Floating point value 0.981150 */
 #ifdef HIGHER_FS
+/* Floating point value 0.989704 */
+#define MIX_TC_Fs88200                                  32430
 #define MIX_TC_Fs96000                                  32456         /* Floating point value 0.990530 */
+/* Floating point value 0.994838 */
+#define MIX_TC_Fs176400                                 32598
 #define MIX_TC_Fs192000                                 32611         /* Floating point value 0.992524 */
 #endif
 
 #endif /*BUILD_FLOAT*/
-#endif
\ No newline at end of file
+#endif
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.c b/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.c
index fd4016b..0ba2c86 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.c
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.c
@@ -118,7 +118,7 @@
      * Calculate the table offsets
      */
     LVM_UINT16 Offset = (LVM_UINT16)((LVM_UINT16)pParams->SampleRate + \
-                                    (LVM_UINT16)(pParams->CentreFrequency * (1+LVDBE_FS_48000)));    
+                                    (LVM_UINT16)(pParams->CentreFrequency * (1+LVDBE_FS_48000)));
 #endif
 
     /*
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.c b/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.c
index 3fff2a2..2946734 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.c
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.c
@@ -95,7 +95,7 @@
 #ifdef BUILD_FLOAT
         pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Size   = sizeof(LVDBE_Coef_FLOAT_t);
 #else
-        pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Size         = sizeof(LVDBE_Coef_t);   
+        pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Size         = sizeof(LVDBE_Coef_t);
 #endif
         pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Alignment    = LVDBE_PERSISTENT_COEF_ALIGN;
         pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Type         = LVDBE_PERSISTENT_COEF;
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h b/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h
index 4e5207f..4225a30 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h
@@ -64,7 +64,12 @@
 #define LVDBE_PERSISTENT_COEF_ALIGN      4       /* 32-bit alignment for coef */
 #define LVDBE_SCRATCH_ALIGN              4       /* 32-bit alignment for long data */
 
+#ifdef SUPPORT_MC
+/* Number of buffers required for inplace processing */
+#define LVDBE_SCRATCHBUFFERS_INPLACE     (LVM_MAX_CHANNELS * 3)
+#else
 #define LVDBE_SCRATCHBUFFERS_INPLACE     6       /* Number of buffers required for inplace processing */
+#endif
 
 #define LVDBE_MIXER_TC                   5       /* Mixer time  */
 #define LVDBE_BYPASS_MIXER_TC            100     /* Bypass mixer time */
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.c b/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.c
index 10ea700..c4d3403 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.c
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.c
@@ -21,11 +21,13 @@
 /*                                                                                      */
 /****************************************************************************************/
 
+#include <string.h> // memset
 #include "LVDBE.h"
 #include "LVDBE_Private.h"
 #include "VectorArithmetic.h"
 #include "AGC.h"
 #include "LVDBE_Coeffs.h"               /* Filter coefficients */
+#include <log/log.h>
 
 /********************************************************************************************/
 /*                                                                                          */
@@ -187,42 +189,49 @@
 LVDBE_ReturnStatus_en LVDBE_Process(LVDBE_Handle_t hInstance,
     const LVM_FLOAT *pInData,
     LVM_FLOAT *pOutData,
-    LVM_UINT16 NumSamples)
+    const LVM_UINT16 NrFrames) // updated to use samples = frames * channels.
 {
-
   LVDBE_Instance_t *pInstance =(LVDBE_Instance_t *)hInstance;
-  LVM_FLOAT *pScratch_in = (LVM_FLOAT *)pInstance->MemoryTable.Region
-  [LVDBE_MEMREGION_SCRATCH].pBaseAddress;
-  LVM_FLOAT *pScratch = pScratch_in + 2 * NumSamples;
-  LVM_FLOAT *pMono;
-  LVM_INT32 ii = 0;
 
-  /* Scratch for Volume Control starts at offset of 4*NumSamples float values from pScratch */
-  LVM_FLOAT           *pScratchVol = (LVM_FLOAT *)(&pScratch_in[4 * NumSamples]);
-//  LVM_INT16 *pScratchVol_int = (LVM_INT16 *)(pScratchVol);
+  /*Extract number of Channels info*/
+#ifdef SUPPORT_MC
+  // Mono passed in as stereo
+  const LVM_INT32 NrChannels = pInstance->Params.NrChannels == 1
+      ? 2 : pInstance->Params.NrChannels;
+#else
+  const LVM_INT32 NrChannels = 2; // FCC_2
+#endif
+  const LVM_INT32 NrSamples = NrChannels * NrFrames;
 
-  /* Scratch for Mono path starts at offset of 6*NumSamples 32-bit values from pScratch */
-  pMono = &pScratch_in[4 * NumSamples];
+  /* Space to store DBE path computation */
+  LVM_FLOAT * const pScratch =
+          (LVM_FLOAT *)pInstance->MemoryTable.Region[LVDBE_MEMREGION_SCRATCH].pBaseAddress;
 
   /*
-   * Check the number of samples is not too large
+   * Scratch for Mono path starts at offset of
+   * NrSamples float values from pScratch.
    */
-  if (NumSamples > pInstance->Capabilities.MaxBlockSize)
+  LVM_FLOAT * const pMono = pScratch + NrSamples;
+
+  /*
+   * TRICKY: pMono is used and discarded by the DBE path.
+   *         so it is available for use for the pScratchVol
+   *         path which is computed afterwards.
+   *
+   * Space to store Volume Control path computation.
+   * This is identical to pMono (see TRICKY comment).
+   */
+  LVM_FLOAT * const pScratchVol = pMono;
+
+  /*
+   * Check the number of frames is not too large
+   */
+  if (NrFrames > pInstance->Capabilities.MaxBlockSize)
   {
-    return(LVDBE_TOOMANYSAMPLES);
+    return LVDBE_TOOMANYSAMPLES;
   }
 
   /*
-   * Convert 16-bit samples to Float
-   */
-  Copy_Float(pInData, /* Source 16-bit data    */
-      pScratch_in, /* Dest. 32-bit data     */
-      (LVM_INT16)(2 * NumSamples)); /* Left and right        */
-
-  for (ii = 0; ii < 2 * NumSamples; ii++) {
-    pScratch[ii] = pScratch_in[ii];
-  }
-  /*
    * Check if the algorithm is enabled
    */
   /* DBE path is processed when DBE is ON or during On/Off transitions */
@@ -230,50 +239,81 @@
       (LVC_Mixer_GetCurrent(&pInstance->pData->BypassMixer.MixerStream[0])
           !=LVC_Mixer_GetTarget(&pInstance->pData->BypassMixer.MixerStream[0])))
   {
+    // make copy of input data
+    Copy_Float(pInData,
+        pScratch,
+        (LVM_INT16)NrSamples);
 
     /*
      * Apply the high pass filter if selected
      */
     if (pInstance->Params.HPFSelect == LVDBE_HPF_ON)
     {
+#ifdef SUPPORT_MC
+      BQ_MC_D32F32C30_TRC_WRA_01(&pInstance->pCoef->HPFInstance, /* Filter instance      */
+          pScratch, /* Source               */
+          pScratch, /* Destination          */
+          (LVM_INT16)NrFrames,
+          (LVM_INT16)NrChannels);
+#else
       BQ_2I_D32F32C30_TRC_WRA_01(&pInstance->pCoef->HPFInstance,/* Filter instance      */
-          (LVM_FLOAT *)pScratch, /* Source               */
-          (LVM_FLOAT *)pScratch, /* Destination          */
-          (LVM_INT16)NumSamples); /* Number of samples    */
+          pScratch, /* Source               */
+          pScratch, /* Destination          */
+          (LVM_INT16)NrFrames);
+#endif
     }
 
     /*
      * Create the mono stream
      */
-    From2iToMono_Float((LVM_FLOAT *)pScratch, /* Stereo source         */
+#ifdef SUPPORT_MC
+    FromMcToMono_Float(pScratch, /* Source */
+        pMono, /* Mono destination */
+        (LVM_INT16)NrFrames,  /* Number of frames */
+        (LVM_INT16)NrChannels);
+#else
+    From2iToMono_Float(pScratch, /* Stereo source         */
         pMono, /* Mono destination      */
-        (LVM_INT16)NumSamples); /* Number of samples     */
+        (LVM_INT16)NrFrames);
+#endif
 
     /*
      * Apply the band pass filter
      */
     BP_1I_D32F32C30_TRC_WRA_02(&pInstance->pCoef->BPFInstance, /* Filter instance       */
-        (LVM_FLOAT *)pMono, /* Source                */
-        (LVM_FLOAT *)pMono, /* Destination           */
-        (LVM_INT16)NumSamples); /* Number of samples     */
+        pMono, /* Source                */
+        pMono, /* Destination           */
+        (LVM_INT16)NrFrames);
 
     /*
      * Apply the AGC and mix
      */
+#ifdef SUPPORT_MC
+    AGC_MIX_VOL_Mc1Mon_D32_WRA(&pInstance->pData->AGCInstance, /* Instance pointer      */
+        pScratch, /* Source         */
+        pMono, /* Mono band pass source */
+        pScratch, /* Destination    */
+        NrFrames, /* Number of frames     */
+        NrChannels); /* Number of channels     */
+#else
     AGC_MIX_VOL_2St1Mon_D32_WRA(&pInstance->pData->AGCInstance, /* Instance pointer      */
         pScratch, /* Stereo source         */
         pMono, /* Mono band pass source */
         pScratch, /* Stereo destination    */
-        NumSamples); /* Number of samples     */
+        NrFrames);
+#endif
 
-    for (ii = 0; ii < 2 * NumSamples; ii++) {
+    for (LVM_INT32 ii = 0; ii < NrSamples; ++ii) {
       //TODO: replace with existing clamping function
-      if(pScratch[ii] < -1.0) {
+      if (pScratch[ii] < -1.0) {
         pScratch[ii] = -1.0;
-      } else if(pScratch[ii] > 1.0) {
+      } else if (pScratch[ii] > 1.0) {
         pScratch[ii] = 1.0;
       }
     }
+  } else {
+    // clear DBE processed path
+    memset(pScratch, 0, sizeof(*pScratch) * NrSamples);
   }
 
   /* Bypass Volume path is processed when DBE is OFF or during On/Off transitions */
@@ -286,21 +326,40 @@
      * The algorithm is disabled but volume management is required to compensate for
      * headroom and volume (if enabled)
      */
-    LVC_MixSoft_1St_D16C31_SAT(&pInstance->pData->BypassVolume,
-        pScratch_in,
+#ifdef SUPPORT_MC
+    LVC_MixSoft_Mc_D16C31_SAT(&pInstance->pData->BypassVolume,
+        pInData,
         pScratchVol,
-        (LVM_INT16)(2 * NumSamples)); /* Left and right */
+        (LVM_INT16)NrFrames,
+        (LVM_INT16)NrChannels);
+#else
+    LVC_MixSoft_1St_D16C31_SAT(&pInstance->pData->BypassVolume,
+        pInData,
+        pScratchVol,
+        (LVM_INT16)NrSamples); /* Left and right, really # samples */
+#endif
+  } else {
+    // clear bypass volume path
+    memset(pScratchVol, 0, sizeof(*pScratchVol) * NrSamples);
   }
 
   /*
    * Mix DBE processed path and bypass volume path
    */
+#ifdef SUPPORT_MC
+  LVC_MixSoft_2Mc_D16C31_SAT(&pInstance->pData->BypassMixer,
+      pScratch,
+      pScratchVol,
+      pOutData,
+      (LVM_INT16)NrFrames,
+      (LVM_INT16)NrChannels);
+#else
   LVC_MixSoft_2St_D16C31_SAT(&pInstance->pData->BypassMixer,
       pScratch,
       pScratchVol,
       pOutData,
-      (LVM_INT16)(2 * NumSamples));
-
-  return(LVDBE_SUCCESS);
+      (LVM_INT16)NrSamples);
+#endif
+  return LVDBE_SUCCESS;
 }
 #endif
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.c b/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.c
index c4a9b14..a2ce404 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.c
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.c
@@ -88,11 +88,21 @@
      -HPF_Fs48000_Fc55_B2,
      -HPF_Fs48000_Fc55_B1},
 #ifdef HIGHER_FS
+    {HPF_Fs88200_Fc55_A2,                /* 88kS/s coefficients */
+     HPF_Fs88200_Fc55_A1,
+     HPF_Fs88200_Fc55_A0,
+     -HPF_Fs88200_Fc55_B2,
+     -HPF_Fs88200_Fc55_B1},
     {HPF_Fs96000_Fc55_A2,                /* 96kS/s coefficients */
      HPF_Fs96000_Fc55_A1,
      HPF_Fs96000_Fc55_A0,
      -HPF_Fs96000_Fc55_B2,
      -HPF_Fs96000_Fc55_B1},
+    {HPF_Fs176400_Fc55_A2,                /* 176kS/s coefficients */
+     HPF_Fs176400_Fc55_A1,
+     HPF_Fs176400_Fc55_A0,
+     -HPF_Fs176400_Fc55_B2,
+     -HPF_Fs176400_Fc55_B1},
     {HPF_Fs192000_Fc55_A2,                /* 192kS/s coefficients */
      HPF_Fs192000_Fc55_A1,
      HPF_Fs192000_Fc55_A0,
@@ -147,11 +157,21 @@
      -HPF_Fs48000_Fc66_B2,
      -HPF_Fs48000_Fc66_B1},
 #ifdef HIGHER_FS
+    {HPF_Fs88200_Fc66_A2,                /* 88kS/s coefficients */
+     HPF_Fs88200_Fc66_A1,
+     HPF_Fs88200_Fc66_A0,
+     -HPF_Fs88200_Fc66_B2,
+     -HPF_Fs88200_Fc66_B1},
     {HPF_Fs96000_Fc66_A2,                /* 96kS/s coefficients */
      HPF_Fs96000_Fc66_A1,
      HPF_Fs96000_Fc66_A0,
      -HPF_Fs96000_Fc66_B2,
      -HPF_Fs96000_Fc66_B1},
+    {HPF_Fs176400_Fc66_A2,                /* 176kS/s coefficients */
+     HPF_Fs176400_Fc66_A1,
+     HPF_Fs176400_Fc66_A0,
+     -HPF_Fs176400_Fc66_B2,
+     -HPF_Fs176400_Fc66_B1},
     {HPF_Fs192000_Fc66_A2,                /* 192kS/s coefficients */
      HPF_Fs192000_Fc66_A1,
      HPF_Fs192000_Fc66_A0,
@@ -207,11 +227,21 @@
      -HPF_Fs48000_Fc78_B2,
      -HPF_Fs48000_Fc78_B1},
 #ifdef HIGHER_FS
+    {HPF_Fs88200_Fc78_A2,                /* 88kS/s coefficients */
+     HPF_Fs88200_Fc78_A1,
+     HPF_Fs88200_Fc78_A0,
+     -HPF_Fs88200_Fc78_B2,
+     -HPF_Fs88200_Fc78_B1},
     {HPF_Fs96000_Fc78_A2,                /* 96kS/s coefficients */
      HPF_Fs96000_Fc78_A1,
      HPF_Fs96000_Fc78_A0,
      -HPF_Fs96000_Fc78_B2,
      -HPF_Fs96000_Fc78_B1},
+    {HPF_Fs176400_Fc78_A2,                /* 176kS/s coefficients */
+     HPF_Fs176400_Fc78_A1,
+     HPF_Fs176400_Fc78_A0,
+     -HPF_Fs176400_Fc78_B2,
+     -HPF_Fs176400_Fc78_B1},
     {HPF_Fs192000_Fc78_A2,                /* 192kS/s coefficients */
      HPF_Fs192000_Fc78_A1,
      HPF_Fs192000_Fc78_A0,
@@ -269,11 +299,21 @@
 
 #ifdef HIGHER_FS
     ,
+    {HPF_Fs88200_Fc90_A2,                /* 88kS/s coefficients */
+     HPF_Fs88200_Fc90_A1,
+     HPF_Fs88200_Fc90_A0,
+     -HPF_Fs88200_Fc90_B2,
+     -HPF_Fs88200_Fc90_B1},
     {HPF_Fs96000_Fc90_A2,                /* 96kS/s coefficients */
      HPF_Fs96000_Fc90_A1,
      HPF_Fs96000_Fc90_A0,
      -HPF_Fs96000_Fc90_B2,
      -HPF_Fs96000_Fc90_B1},
+    {HPF_Fs176400_Fc90_A2,                /* 176kS/s coefficients */
+     HPF_Fs176400_Fc90_A1,
+     HPF_Fs176400_Fc90_A0,
+     -HPF_Fs176400_Fc90_B2,
+     -HPF_Fs176400_Fc90_B1},
     {HPF_Fs192000_Fc90_A2,                /* 192kS/s coefficients */
      HPF_Fs192000_Fc90_A1,
      HPF_Fs192000_Fc90_A0,
@@ -320,9 +360,15 @@
      -BPF_Fs48000_Fc55_B2,
      -BPF_Fs48000_Fc55_B1},
 #ifdef HIGHER_FS
+     {BPF_Fs88200_Fc55_A0,                /* 88kS/s coefficients */
+      -BPF_Fs88200_Fc55_B2,
+      -BPF_Fs88200_Fc55_B1},
      {BPF_Fs96000_Fc55_A0,                /* 96kS/s coefficients */
      -BPF_Fs96000_Fc55_B2,
      -BPF_Fs96000_Fc55_B1},
+     {BPF_Fs176400_Fc55_A0,                /* 176kS/s coefficients */
+      -BPF_Fs176400_Fc55_B2,
+      -BPF_Fs176400_Fc55_B1},
      {BPF_Fs192000_Fc55_A0,                /* 192kS/s coefficients */
      -BPF_Fs192000_Fc55_B2,
      -BPF_Fs192000_Fc55_B1},
@@ -357,9 +403,15 @@
      -BPF_Fs48000_Fc66_B2,
      -BPF_Fs48000_Fc66_B1},
 #ifdef HIGHER_FS
+    {BPF_Fs88200_Fc66_A0,                /* 88kS/s coefficients */
+     -BPF_Fs88200_Fc66_B2,
+     -BPF_Fs88200_Fc66_B1},
     {BPF_Fs96000_Fc66_A0,                /* 96kS/s coefficients */
      -BPF_Fs96000_Fc66_B2,
      -BPF_Fs96000_Fc66_B1},
+    {BPF_Fs176400_Fc66_A0,                /* 176kS/s coefficients */
+     -BPF_Fs176400_Fc66_B2,
+     -BPF_Fs176400_Fc66_B1},
     {BPF_Fs192000_Fc66_A0,                /* 192kS/s coefficients */
      -BPF_Fs192000_Fc66_B2,
      -BPF_Fs192000_Fc66_B1},
@@ -394,9 +446,15 @@
      -BPF_Fs48000_Fc78_B2,
      -BPF_Fs48000_Fc78_B1},
 #ifdef HIGHER_FS
+    {BPF_Fs88200_Fc66_A0,                /* 88kS/s coefficients */
+     -BPF_Fs88200_Fc66_B2,
+     -BPF_Fs88200_Fc66_B1},
     {BPF_Fs96000_Fc78_A0,                /* 96kS/s coefficients */
      -BPF_Fs96000_Fc78_B2,
      -BPF_Fs96000_Fc78_B1},
+    {BPF_Fs176400_Fc66_A0,                /* 176kS/s coefficients */
+     -BPF_Fs176400_Fc66_B2,
+     -BPF_Fs176400_Fc66_B1},
     {BPF_Fs192000_Fc78_A0,                /* 192kS/s coefficients */
      -BPF_Fs192000_Fc78_B2,
      -BPF_Fs192000_Fc78_B1},
@@ -432,9 +490,15 @@
      -BPF_Fs48000_Fc90_B1}
 #ifdef HIGHER_FS
     ,
+    {BPF_Fs88200_Fc90_A0,                /* 88kS/s coefficients */
+     -BPF_Fs88200_Fc90_B2,
+     -BPF_Fs88200_Fc90_B1},
     {BPF_Fs96000_Fc90_A0,                /* 96kS/s coefficients */
      -BPF_Fs96000_Fc90_B2,
      -BPF_Fs96000_Fc90_B1},
+    {BPF_Fs176400_Fc90_A0,                /* 176kS/s coefficients */
+     -BPF_Fs176400_Fc90_B2,
+     -BPF_Fs176400_Fc90_B1},
     {BPF_Fs192000_Fc90_A0,                /* 192kS/s coefficients */
      -BPF_Fs192000_Fc90_B2,
      -BPF_Fs192000_Fc90_B1}
@@ -466,7 +530,9 @@
     AGC_ATTACK_Fs44100,
     AGC_ATTACK_Fs48000
 #ifdef HIGHER_FS
+    ,AGC_ATTACK_Fs88200
     ,AGC_ATTACK_Fs96000
+    ,AGC_ATTACK_Fs176400
     ,AGC_ATTACK_Fs192000
 #endif
 
@@ -488,7 +554,9 @@
     AGC_DECAY_Fs44100,
     AGC_DECAY_Fs48000
 #ifdef HIGHER_FS
+    ,AGC_DECAY_Fs88200
     ,AGC_DECAY_FS96000
+    ,AGC_DECAY_Fs176400
     ,AGC_DECAY_FS192000
 #endif
 
@@ -583,7 +651,9 @@
     VOL_TC_Fs44100,
     VOL_TC_Fs48000
 #ifdef HIGHER_FS
+    ,VOL_TC_Fs88200
     ,VOL_TC_Fs96000
+    ,VOL_TC_Fs176400
     ,VOL_TC_Fs192000
 #endif
 };
@@ -602,7 +672,9 @@
     MIX_TC_Fs44100,
     MIX_TC_Fs48000
 #ifdef HIGHER_FS
+    ,MIX_TC_Fs88200
     ,MIX_TC_Fs96000
+    ,MIX_TC_Fs176400
     ,MIX_TC_Fs192000
 #endif
 
diff --git a/media/libeffects/lvm/lib/Bundle/lib/LVM.h b/media/libeffects/lvm/lib/Bundle/lib/LVM.h
index 9b6da31..5082a53 100644
--- a/media/libeffects/lvm/lib/Bundle/lib/LVM.h
+++ b/media/libeffects/lvm/lib/Bundle/lib/LVM.h
@@ -296,6 +296,10 @@
     /* Spectrum Analyzer parameters Control */
     LVM_PSA_Mode_en             PSA_Enable;
     LVM_PSA_DecaySpeed_en       PSA_PeakDecayRate;      /* Peak value decay rate*/
+#ifdef SUPPORT_MC
+    LVM_INT32                   NrChannels;
+    LVM_INT32                   ChMask;
+#endif
 
 } LVM_ControlParams_t;
 
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Buffers.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Buffers.c
index 0a3c30e..bdca5e3 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Buffers.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Buffers.c
@@ -25,6 +25,8 @@
 #include "LVM_Private.h"
 #include "VectorArithmetic.h"
 
+#include <log/log.h>
+
 /****************************************************************************************/
 /*                                                                                      */
 /* FUNCTION:                 LVM_BufferManagedIn                                        */
@@ -62,8 +64,11 @@
     LVM_Instance_t   *pInstance = (LVM_Instance_t  *)hInstance;
     LVM_Buffer_t     *pBuffer;
     LVM_FLOAT        *pDest;
+#ifdef SUPPORT_MC
+    LVM_INT16        NumChannels = pInstance->NrChannels;
+#else
     LVM_INT16        NumChannels = 2;
-
+#endif
 
     /*
      * Set the processing address pointers
@@ -207,8 +212,7 @@
     LVM_Instance_t   *pInstance = (LVM_Instance_t  *)hInstance;
     LVM_Buffer_t     *pBuffer;
     LVM_INT16        *pDest;
-    LVM_INT16        NumChannels =2;
-
+    LVM_INT16        NumChannels = 2;
 
     /*
      * Set the processing address pointers
@@ -499,7 +503,7 @@
         if (pBuffer->OutDelaySamples != 0)
         {
             Copy_16(&pBuffer->OutDelayBuffer[0],                    /* Source */
-                    pDest,                                          /* Detsination */
+                    pDest,                                          /* Destination */
                     (LVM_INT16)(2*pBuffer->OutDelaySamples));       /* Number of delay samples */
             pDest += 2 * pBuffer->OutDelaySamples;                  /* Update the output pointer */
             pBuffer->SamplesToOutput = (LVM_INT16)(pBuffer->SamplesToOutput - pBuffer->OutDelaySamples); /* Update the numbr of samples to output */
@@ -750,7 +754,11 @@
     LVM_INT16       NumSamples;
     LVM_FLOAT       *pStart;
     LVM_FLOAT       *pDest;
-
+#ifdef SUPPORT_MC
+    LVM_INT32       NrChannels = pInstance->NrChannels;
+#define NrFrames NumSamples  // alias for clarity
+#define FrameCount SampleCount
+#endif
 
     /*
      * Set the pointers
@@ -758,7 +766,6 @@
     NumSamples = pBuffer->SamplesToOutput;
     pStart     = pBuffer->pScratch;
 
-
     /*
      * check if it is the first call of a block
       */
@@ -786,14 +793,25 @@
             /*
              * Copy all output delay samples to the output
              */
+#ifdef SUPPORT_MC
             Copy_Float(&pBuffer->OutDelayBuffer[0],                /* Source */
-                       pDest,                                      /* Detsination */
+                       pDest,                                      /* Destination */
+                       /* Number of delay samples */
+                       (LVM_INT16)(NrChannels * pBuffer->OutDelaySamples));
+#else
+            Copy_Float(&pBuffer->OutDelayBuffer[0],                /* Source */
+                       pDest,                                      /* Destination */
                        (LVM_INT16)(2 * pBuffer->OutDelaySamples)); /* Number of delay samples */
+#endif
 
             /*
              * Update the pointer and sample counts
              */
+#ifdef SUPPORT_MC
+            pDest += NrChannels * pBuffer->OutDelaySamples; /* Output sample pointer */
+#else
             pDest += 2 * pBuffer->OutDelaySamples; /* Output sample pointer */
+#endif
             NumSamples = (LVM_INT16)(NumSamples - pBuffer->OutDelaySamples); /* Samples left \
                                                                                 to send */
             pBuffer->OutDelaySamples = 0; /* No samples left in the buffer */
@@ -803,23 +821,40 @@
             /*
              * Copy only some of the ouput delay samples to the output
              */
+#ifdef SUPPORT_MC
             Copy_Float(&pBuffer->OutDelayBuffer[0],                    /* Source */
-                       pDest,                                          /* Detsination */
+                       pDest,                                          /* Destination */
+                       (LVM_INT16)(NrChannels * NrFrames));       /* Number of delay samples */
+#else
+            Copy_Float(&pBuffer->OutDelayBuffer[0],                    /* Source */
+                       pDest,                                          /* Destination */
                        (LVM_INT16)(2 * NumSamples));       /* Number of delay samples */
+#endif
 
             /*
              * Update the pointer and sample counts
              */
+#ifdef SUPPORT_MC
+            pDest += NrChannels * NrFrames; /* Output sample pointer */
+#else
             pDest += 2 * NumSamples; /* Output sample pointer */
+#endif
             /* No samples left in the buffer */
             pBuffer->OutDelaySamples = (LVM_INT16)(pBuffer->OutDelaySamples - NumSamples);
 
             /*
              * Realign the delay buffer data to avoid using circular buffer management
              */
+#ifdef SUPPORT_MC
+            Copy_Float(&pBuffer->OutDelayBuffer[NrChannels * NrFrames],         /* Source */
+                       &pBuffer->OutDelayBuffer[0],                    /* Destination */
+                       /* Number of samples to move */
+                       (LVM_INT16)(NrChannels * pBuffer->OutDelaySamples));
+#else
             Copy_Float(&pBuffer->OutDelayBuffer[2 * NumSamples],         /* Source */
                        &pBuffer->OutDelayBuffer[0],                    /* Destination */
                        (LVM_INT16)(2 * pBuffer->OutDelaySamples)); /* Number of samples to move */
+#endif
             NumSamples = 0;                                /* Samples left to send */
         }
     }
@@ -836,13 +871,23 @@
             /*
              * Copy all processed samples to the output
              */
+#ifdef SUPPORT_MC
             Copy_Float(pStart,                                      /* Source */
-                       pDest,                                       /* Detsination */
+                       pDest,                                       /* Destination */
+                       (LVM_INT16)(NrChannels * FrameCount)); /* Number of processed samples */
+#else
+            Copy_Float(pStart,                                      /* Source */
+                       pDest,                                       /* Destination */
                        (LVM_INT16)(2 * SampleCount)); /* Number of processed samples */
+#endif
             /*
              * Update the pointer and sample counts
              */
+#ifdef SUPPORT_MC
+            pDest      += NrChannels * FrameCount;                 /* Output sample pointer */
+#else
             pDest      += 2 * SampleCount;                          /* Output sample pointer */
+#endif
             NumSamples  = (LVM_INT16)(NumSamples - SampleCount);    /* Samples left to send */
             SampleCount = 0; /* No samples left in the buffer */
         }
@@ -851,14 +896,25 @@
             /*
              * Copy only some processed samples to the output
              */
+#ifdef SUPPORT_MC
+            Copy_Float(pStart,                                         /* Source */
+                       pDest,                                          /* Destination */
+                       (LVM_INT16)(NrChannels * NrFrames));  /* Number of processed samples */
+#else
             Copy_Float(pStart,                                         /* Source */
                        pDest,                                          /* Destination */
                        (LVM_INT16)(2 * NumSamples));     /* Number of processed samples */
+#endif
             /*
              * Update the pointers and sample counts
                */
+#ifdef SUPPORT_MC
+            pStart      += NrChannels * NrFrames;               /* Processed sample pointer */
+            pDest       += NrChannels * NrFrames;               /* Output sample pointer */
+#else
             pStart      += 2 * NumSamples;                        /* Processed sample pointer */
             pDest       += 2 * NumSamples;                        /* Output sample pointer */
+#endif
             SampleCount  = (LVM_INT16)(SampleCount - NumSamples); /* Processed samples left */
             NumSamples   = 0;                                     /* Clear the sample count */
         }
@@ -870,9 +926,16 @@
      */
     if (SampleCount != 0)
     {
+#ifdef SUPPORT_MC
+        Copy_Float(pStart,                                                 /* Source */
+                   /* Destination */
+                   &pBuffer->OutDelayBuffer[NrChannels * pBuffer->OutDelaySamples],
+                   (LVM_INT16)(NrChannels * FrameCount));      /* Number of processed samples */
+#else
         Copy_Float(pStart,                                                 /* Source */
                    &pBuffer->OutDelayBuffer[2 * pBuffer->OutDelaySamples], /* Destination */
                    (LVM_INT16)(2 * SampleCount));               /* Number of processed samples */
+#endif
         /* Update the buffer count */
         pBuffer->OutDelaySamples = (LVM_INT16)(pBuffer->OutDelaySamples + SampleCount);
     }
@@ -1063,14 +1126,29 @@
 {
 
     LVM_Instance_t      *pInstance  = (LVM_Instance_t  *)hInstance;
-    LVM_INT16           NumChannels =2;
+#ifdef SUPPORT_MC
+    LVM_INT16           NumChannels = pInstance->NrChannels;
+    if (NumChannels == 1)
+    {
+        /* Mono input is processed as stereo by LVM module */
+        NumChannels = 2;
+    }
+#undef NrFrames
+#define NrFrames (*pNumSamples) // alias for clarity
+#else
+    LVM_INT16           NumChannels = 2;
+#endif
 
 
     /*
      * Update sample counts
      */
     pInstance->pInputSamples    += (LVM_INT16)(*pNumSamples * NumChannels); /* Update the I/O pointers */
+#ifdef SUPPORT_MC
+    pInstance->pOutputSamples   += (LVM_INT16)(NrFrames * NumChannels);
+#else
     pInstance->pOutputSamples   += (LVM_INT16)(*pNumSamples * 2);
+#endif
     pInstance->SamplesToProcess  = (LVM_INT16)(pInstance->SamplesToProcess - *pNumSamples); /* Update the sample count */
 
     /*
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Coeffs.h b/media/libeffects/lvm/lib/Bundle/src/LVM_Coeffs.h
index 8c04847..bab4049 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Coeffs.h
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Coeffs.h
@@ -487,6 +487,97 @@
 #define HPF_Fs48000_Gain15_B2                         0.000000
 
 #ifdef HIGHER_FS
+/* Coefficients for sample rate 88200 */
+/* Gain = 1.000000 dB */
+#define HPF_Fs88200_Gain1_A0                          1.094374f
+#define HPF_Fs88200_Gain1_A1                          (-0.641256f)
+#define HPF_Fs88200_Gain1_A2                          0.000000f
+#define HPF_Fs88200_Gain1_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain1_B2                          0.000000f
+/* Gain = 2.000000 dB */
+#define HPF_Fs88200_Gain2_A0                          1.200264f
+#define HPF_Fs88200_Gain2_A1                          (-0.747146f)
+#define HPF_Fs88200_Gain2_A2                          0.000000f
+#define HPF_Fs88200_Gain2_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain2_B2                          0.000000f
+/* Gain = 3.000000 dB */
+#define HPF_Fs88200_Gain3_A0                          1.319074f
+#define HPF_Fs88200_Gain3_A1                          (-0.865956f)
+#define HPF_Fs88200_Gain3_A2                          0.000000f
+#define HPF_Fs88200_Gain3_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain3_B2                          0.000000f
+/* Gain = 4.000000 dB */
+#define HPF_Fs88200_Gain4_A0                          1.452380f
+#define HPF_Fs88200_Gain4_A1                          (-0.999263f)
+#define HPF_Fs88200_Gain4_A2                          0.000000f
+#define HPF_Fs88200_Gain4_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain4_B2                          0.000000f
+/* Gain = 5.000000 dB */
+#define HPF_Fs88200_Gain5_A0                          1.601953f
+#define HPF_Fs88200_Gain5_A1                          (-1.148836f)
+#define HPF_Fs88200_Gain5_A2                          0.000000f
+#define HPF_Fs88200_Gain5_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain5_B2                          0.000000f
+/* Gain = 6.000000 dB */
+#define HPF_Fs88200_Gain6_A0                          1.769777f
+#define HPF_Fs88200_Gain6_A1                          (-1.316659f)
+#define HPF_Fs88200_Gain6_A2                          0.000000f
+#define HPF_Fs88200_Gain6_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain6_B2                          0.000000f
+/* Gain = 7.000000 dB */
+#define HPF_Fs88200_Gain7_A0                          1.958078f
+#define HPF_Fs88200_Gain7_A1                          (-1.504960f)
+#define HPF_Fs88200_Gain7_A2                          0.000000f
+#define HPF_Fs88200_Gain7_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain7_B2                          0.000000f
+/* Gain = 8.000000 dB */
+#define HPF_Fs88200_Gain8_A0                          2.169355f
+#define HPF_Fs88200_Gain8_A1                          (-1.716238f)
+#define HPF_Fs88200_Gain8_A2                          0.000000f
+#define HPF_Fs88200_Gain8_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain8_B2                          0.000000f
+/* Gain = 9.000000 dB */
+#define HPF_Fs88200_Gain9_A0                          2.406412f
+#define HPF_Fs88200_Gain9_A1                          (-1.953295f)
+#define HPF_Fs88200_Gain9_A2                          0.000000f
+#define HPF_Fs88200_Gain9_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain9_B2                          0.000000f
+/* Gain = 10.000000 dB */
+#define HPF_Fs88200_Gain10_A0                          2.672395f
+#define HPF_Fs88200_Gain10_A1                          (-2.219277f)
+#define HPF_Fs88200_Gain10_A2                          0.000000f
+#define HPF_Fs88200_Gain10_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain10_B2                          0.000000f
+/* Gain = 11.000000 dB */
+#define HPF_Fs88200_Gain11_A0                          2.970832f
+#define HPF_Fs88200_Gain11_A1                          (-2.517714f)
+#define HPF_Fs88200_Gain11_A2                          0.000000f
+#define HPF_Fs88200_Gain11_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain11_B2                          0.000000f
+/* Gain = 12.000000 dB */
+#define HPF_Fs88200_Gain12_A0                          3.305684f
+#define HPF_Fs88200_Gain12_A1                          (-2.852566f)
+#define HPF_Fs88200_Gain12_A2                          0.000000f
+#define HPF_Fs88200_Gain12_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain12_B2                          0.000000f
+/* Gain = 13.000000 dB */
+#define HPF_Fs88200_Gain13_A0                          3.681394f
+#define HPF_Fs88200_Gain13_A1                          (-3.228276f)
+#define HPF_Fs88200_Gain13_A2                          0.000000f
+#define HPF_Fs88200_Gain13_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain13_B2                          0.000000f
+/* Gain = 14.000000 dB */
+#define HPF_Fs88200_Gain14_A0                          4.102947f
+#define HPF_Fs88200_Gain14_A1                          (-3.649830f)
+#define HPF_Fs88200_Gain14_A2                          0.000000f
+#define HPF_Fs88200_Gain14_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain14_B2                          0.000000f
+/* Gain = 15.000000 dB */
+#define HPF_Fs88200_Gain15_A0                          4.575938f
+#define HPF_Fs88200_Gain15_A1                          (-4.122820f)
+#define HPF_Fs88200_Gain15_A2                          0.000000f
+#define HPF_Fs88200_Gain15_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain15_B2                          0.000000f
 
 /* Coefficients for sample rate 96000Hz */
                                                                  /* Gain =  1.000000 dB */
@@ -580,6 +671,98 @@
 #define HPF_Fs96000_Gain15_B1                         (-0.577350)
 #define HPF_Fs96000_Gain15_B2                         0.000000
 
+/* Coefficients for sample rate 176400 */
+/* Gain = 1.000000 dB */
+#define HPF_Fs176400_Gain1_A0                          1.106711f
+#define HPF_Fs176400_Gain1_A1                          (-0.855807f)
+#define HPF_Fs176400_Gain1_A2                          0.000000f
+#define HPF_Fs176400_Gain1_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain1_B2                          0.000000f
+/* Gain = 2.000000 dB */
+#define HPF_Fs176400_Gain2_A0                          1.226443f
+#define HPF_Fs176400_Gain2_A1                          (-0.975539f)
+#define HPF_Fs176400_Gain2_A2                          0.000000f
+#define HPF_Fs176400_Gain2_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain2_B2                          0.000000f
+/* Gain = 3.000000 dB */
+#define HPF_Fs176400_Gain3_A0                          1.360784f
+#define HPF_Fs176400_Gain3_A1                          (-1.109880f)
+#define HPF_Fs176400_Gain3_A2                          0.000000f
+#define HPF_Fs176400_Gain3_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain3_B2                          0.000000f
+/* Gain = 4.000000 dB */
+#define HPF_Fs176400_Gain4_A0                          1.511517f
+#define HPF_Fs176400_Gain4_A1                          (-1.260613f)
+#define HPF_Fs176400_Gain4_A2                          0.000000f
+#define HPF_Fs176400_Gain4_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain4_B2                          0.000000f
+/* Gain = 5.000000 dB */
+#define HPF_Fs176400_Gain5_A0                          1.680643f
+#define HPF_Fs176400_Gain5_A1                          (-1.429739f)
+#define HPF_Fs176400_Gain5_A2                          0.000000f
+#define HPF_Fs176400_Gain5_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain5_B2                          0.000000f
+/* Gain = 6.000000 dB */
+#define HPF_Fs176400_Gain6_A0                          1.870405f
+#define HPF_Fs176400_Gain6_A1                          (-1.619501f)
+#define HPF_Fs176400_Gain6_A2                          0.000000f
+#define HPF_Fs176400_Gain6_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain6_B2                          0.000000f
+/* Gain = 7.000000 dB */
+#define HPF_Fs176400_Gain7_A0                          2.083321f
+#define HPF_Fs176400_Gain7_A1                          (-1.832417f)
+#define HPF_Fs176400_Gain7_A2                          0.000000f
+#define HPF_Fs176400_Gain7_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain7_B2                          0.000000f
+/* Gain = 8.000000 dB */
+#define HPF_Fs176400_Gain8_A0                          2.322217f
+#define HPF_Fs176400_Gain8_A1                          (-2.071313f)
+#define HPF_Fs176400_Gain8_A2                          0.000000f
+#define HPF_Fs176400_Gain8_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain8_B2                          0.000000f
+/* Gain = 9.000000 dB */
+#define HPF_Fs176400_Gain9_A0                          2.590263f
+#define HPF_Fs176400_Gain9_A1                          (-2.339359f)
+#define HPF_Fs176400_Gain9_A2                          0.000000f
+#define HPF_Fs176400_Gain9_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain9_B2                          0.000000f
+/* Gain = 10.000000 dB */
+#define HPF_Fs176400_Gain10_A0                          2.891016f
+#define HPF_Fs176400_Gain10_A1                          (-2.640112f)
+#define HPF_Fs176400_Gain10_A2                          0.000000f
+#define HPF_Fs176400_Gain10_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain10_B2                          0.000000f
+/* Gain = 11.000000 dB */
+#define HPF_Fs176400_Gain11_A0                          3.228465f
+#define HPF_Fs176400_Gain11_A1                          (-2.977561f)
+#define HPF_Fs176400_Gain11_A2                          0.000000f
+#define HPF_Fs176400_Gain11_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain11_B2                          0.000000f
+/* Gain = 12.000000 dB */
+#define HPF_Fs176400_Gain12_A0                          3.607090f
+#define HPF_Fs176400_Gain12_A1                          (-3.356186f)
+#define HPF_Fs176400_Gain12_A2                          0.000000f
+#define HPF_Fs176400_Gain12_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain12_B2                          0.000000f
+/* Gain = 13.000000 dB */
+#define HPF_Fs176400_Gain13_A0                          4.031914f
+#define HPF_Fs176400_Gain13_A1                          (-3.781010f)
+#define HPF_Fs176400_Gain13_A2                          0.000000f
+#define HPF_Fs176400_Gain13_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain13_B2                          0.000000f
+/* Gain = 14.000000 dB */
+#define HPF_Fs176400_Gain14_A0                          4.508575f
+#define HPF_Fs176400_Gain14_A1                          (-4.257671f)
+#define HPF_Fs176400_Gain14_A2                          0.000000f
+#define HPF_Fs176400_Gain14_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain14_B2                          0.000000f
+/* Gain = 15.000000 dB */
+#define HPF_Fs176400_Gain15_A0                          5.043397f
+#define HPF_Fs176400_Gain15_A1                          (-4.792493f)
+#define HPF_Fs176400_Gain15_A2                          0.000000f
+#define HPF_Fs176400_Gain15_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain15_B2                          0.000000f
+
 /* Coefficients for sample rate 192000Hz */
                                                                   /* Gain =  1.000000 dB */
 #define HPF_Fs192000_Gain1_A0                          1.107823
@@ -1216,4 +1399,4 @@
 
 
 #endif
-#endif
\ No newline at end of file
+#endif
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c
index cfe53b8..1b27cb4 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c
@@ -28,6 +28,8 @@
 #include "LVM_Tables.h"
 #include "LVM_Private.h"
 
+#include <log/log.h>
+
 /****************************************************************************************/
 /*                                                                                      */
 /* FUNCTION:           LVM_SetControlParameters                                         */
@@ -69,18 +71,30 @@
     ((pParams->SampleRate != LVM_FS_8000) && (pParams->SampleRate != LVM_FS_11025) && (pParams->SampleRate != LVM_FS_12000)       &&
      (pParams->SampleRate != LVM_FS_16000) && (pParams->SampleRate != LVM_FS_22050) && (pParams->SampleRate != LVM_FS_24000)      &&
      (pParams->SampleRate != LVM_FS_32000) && (pParams->SampleRate != LVM_FS_44100) && (pParams->SampleRate != LVM_FS_48000)      &&
-     (pParams->SampleRate != LVM_FS_96000) && (pParams->SampleRate != LVM_FS_192000))      ||
+     (pParams->SampleRate != LVM_FS_88200) && (pParams->SampleRate != LVM_FS_96000) &&
+     (pParams->SampleRate != LVM_FS_176400) && (pParams->SampleRate != LVM_FS_192000))      ||
 #else
         ((pParams->SampleRate != LVM_FS_8000) && (pParams->SampleRate != LVM_FS_11025) && (pParams->SampleRate != LVM_FS_12000)       &&
         (pParams->SampleRate != LVM_FS_16000) && (pParams->SampleRate != LVM_FS_22050) && (pParams->SampleRate != LVM_FS_24000)       &&
         (pParams->SampleRate != LVM_FS_32000) && (pParams->SampleRate != LVM_FS_44100) && (pParams->SampleRate != LVM_FS_48000))      ||
 #endif
+#ifdef SUPPORT_MC
+        ((pParams->SourceFormat != LVM_STEREO) &&
+         (pParams->SourceFormat != LVM_MONOINSTEREO) &&
+         (pParams->SourceFormat != LVM_MONO) &&
+         (pParams->SourceFormat != LVM_MULTICHANNEL)) ||
+#else
         ((pParams->SourceFormat != LVM_STEREO) && (pParams->SourceFormat != LVM_MONOINSTEREO) && (pParams->SourceFormat != LVM_MONO)) ||
+#endif
         (pParams->SpeakerType > LVM_EX_HEADPHONES))
     {
         return (LVM_OUTOFRANGE);
     }
 
+#ifdef SUPPORT_MC
+    pInstance->Params.NrChannels = pParams->NrChannels;
+    pInstance->Params.ChMask     = pParams->ChMask;
+#endif
     /*
      * Cinema Sound parameters
      */
@@ -569,6 +583,11 @@
     } while ((pInstance->ControlPending != LVM_FALSE) &&
              (Count > 0));
 
+#ifdef SUPPORT_MC
+    pInstance->NrChannels = LocalParams.NrChannels;
+    pInstance->ChMask = LocalParams.ChMask;
+#endif
+
     /* Clear all internal data if format change*/
     if(LocalParams.SourceFormat != pInstance->Params.SourceFormat)
     {
@@ -719,6 +738,9 @@
         DBE_Params.HeadroomdB       = 0;
         DBE_Params.VolumeControl    = LVDBE_VOLUME_OFF;
         DBE_Params.VolumedB         = 0;
+#ifdef SUPPORT_MC
+        DBE_Params.NrChannels         = LocalParams.NrChannels;
+#endif
 
         /*
          * Make the changes
@@ -771,11 +793,22 @@
         {
             EQNB_Params.SourceFormat = LVEQNB_STEREO;
         }
+#ifdef SUPPORT_MC
+        /* Note: Currently SourceFormat field of EQNB is not been
+         *       used by the module.
+         */
+        else if (LocalParams.SourceFormat == LVM_MULTICHANNEL)
+        {
+            EQNB_Params.SourceFormat = LVEQNB_MULTICHANNEL;
+        }
+#endif
         else
         {
             EQNB_Params.SourceFormat = LVEQNB_MONOINSTEREO;     /* Force to Mono-in-Stereo mode */
         }
-
+#ifdef SUPPORT_MC
+        EQNB_Params.NrChannels         = LocalParams.NrChannels;
+#endif
 
         /*
          * Set the control flag
@@ -838,7 +871,16 @@
             CS_Params.SpeakerType  = LVCS_HEADPHONES;
         }
 
+#ifdef SUPPORT_MC
+        /* Concert sound module processes only the left and right channels
+         * data. So the Source Format is set to LVCS_STEREO for multichannel
+         * input also.
+         */
+        if (LocalParams.SourceFormat == LVM_STEREO ||
+            LocalParams.SourceFormat == LVM_MULTICHANNEL)
+#else
         if (LocalParams.SourceFormat == LVM_STEREO)    /* Mono format not supported */
+#endif
         {
             CS_Params.SourceFormat = LVCS_STEREO;
         }
@@ -849,7 +891,9 @@
         CS_Params.SampleRate  = LocalParams.SampleRate;
         CS_Params.ReverbLevel = LocalParams.VirtualizerReverbLevel;
         CS_Params.EffectLevel = LocalParams.CS_EffectLevel;
-
+#ifdef SUPPORT_MC
+        CS_Params.NrChannels  = LocalParams.NrChannels;
+#endif
 
         /*
          * Set the control flag
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Init.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Init.c
index 26c1c4f..c57498e 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Init.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Init.c
@@ -61,6 +61,72 @@
 /*                                                                                      */
 /****************************************************************************************/
 
+/*
+ * 4 Types of Memory Regions of LVM
+ * TODO: Allocate on the fly.
+ * i)   LVM_MEMREGION_PERSISTENT_SLOW_DATA - For Instance Handles
+ * ii)  LVM_MEMREGION_PERSISTENT_FAST_DATA - Persistent Buffers
+ * iii) LVM_MEMREGION_PERSISTENT_FAST_COEF - For Holding Structure values
+ * iv)  LVM_MEMREGION_TEMPORARY_FAST       - For Holding Structure values
+ *
+ * LVM_MEMREGION_PERSISTENT_SLOW_DATA:
+ *   Total Memory size:
+ *     sizeof(LVM_Instance_t) + \
+ *     sizeof(LVM_Buffer_t) + \
+ *     sizeof(LVPSA_InstancePr_t) + \
+ *     sizeof(LVM_Buffer_t) - needed if buffer mode is LVM_MANAGED_BUFFER
+ *
+ * LVM_MEMREGION_PERSISTENT_FAST_DATA:
+ *   Total Memory size:
+ *     sizeof(LVM_TE_Data_t) + \
+ *     2 * pInstParams->EQNB_NumBands * sizeof(LVM_EQNB_BandDef_t) + \
+ *     sizeof(LVCS_Data_t) + \
+ *     sizeof(LVDBE_Data_FLOAT_t) + \
+ *     sizeof(Biquad_2I_Order2_FLOAT_Taps_t) + \
+ *     sizeof(Biquad_2I_Order2_FLOAT_Taps_t) + \
+ *     pInstParams->EQNB_NumBands * sizeof(Biquad_2I_Order2_FLOAT_Taps_t) + \
+ *     pInstParams->EQNB_NumBands * sizeof(LVEQNB_BandDef_t) + \
+ *     pInstParams->EQNB_NumBands * sizeof(LVEQNB_BiquadType_en) + \
+ *     2 * LVM_HEADROOM_MAX_NBANDS * sizeof(LVM_HeadroomBandDef_t) + \
+ *     PSA_InitParams.nBands * sizeof(Biquad_1I_Order2_Taps_t) + \
+ *     PSA_InitParams.nBands * sizeof(QPD_Taps_t)
+ *
+ * LVM_MEMREGION_PERSISTENT_FAST_COEF:
+ *   Total Memory size:
+ *     sizeof(LVM_TE_Coefs_t) + \
+ *     sizeof(LVCS_Coefficient_t) + \
+ *     sizeof(LVDBE_Coef_FLOAT_t) + \
+ *     sizeof(Biquad_FLOAT_Instance_t) + \
+ *     sizeof(Biquad_FLOAT_Instance_t) + \
+ *     pInstParams->EQNB_NumBands * sizeof(Biquad_FLOAT_Instance_t) + \
+ *     PSA_InitParams.nBands * sizeof(Biquad_Instance_t) + \
+ *     PSA_InitParams.nBands * sizeof(QPD_State_t)
+ *
+ * LVM_MEMREGION_TEMPORARY_FAST (Scratch):
+ *   Total Memory Size:
+ *     BundleScratchSize + \
+ *     MAX_INTERNAL_BLOCKSIZE * sizeof(LVM_FLOAT) + \
+ *     MaxScratchOf (CS, EQNB, DBE, PSA)
+ *
+ *     a)BundleScratchSize:
+ *         3 * LVM_MAX_CHANNELS \
+ *         * (MIN_INTERNAL_BLOCKSIZE + InternalBlockSize) * sizeof(LVM_FLOAT)
+ *       This Memory is allocated only when Buffer mode is LVM_MANAGED_BUFFER.
+ *     b)MaxScratchOf (CS, EQNB, DBE, PSA)
+ *       This Memory is needed for scratch usage for CS, EQNB, DBE, PSA.
+ *       CS   = (LVCS_SCRATCHBUFFERS * sizeof(LVM_FLOAT)
+ *               * pCapabilities->MaxBlockSize)
+ *       EQNB = (LVEQNB_SCRATCHBUFFERS * sizeof(LVM_FLOAT)
+ *               * pCapabilities->MaxBlockSize)
+ *       DBE  = (LVDBE_SCRATCHBUFFERS_INPLACE*sizeof(LVM_FLOAT)
+ *               * pCapabilities->MaxBlockSize)
+ *       PSA  = (2 * pInitParams->MaxInputBlockSize * sizeof(LVM_FLOAT))
+ *              one MaxInputBlockSize for input and another for filter output
+ *     c)MAX_INTERNAL_BLOCKSIZE
+ *       This Memory is needed for PSAInput - Temp memory to store output
+ *       from McToMono block and given as input to PSA block
+ */
+
 LVM_ReturnStatus_en LVM_GetMemoryTable(LVM_Handle_t         hInstance,
                                        LVM_MemTab_t         *pMemoryTable,
                                        LVM_InstParams_t     *pInstParams)
@@ -168,7 +234,13 @@
     AlgScratchSize    = 0;
     if (pInstParams->BufferMode == LVM_MANAGED_BUFFERS)
     {
+#ifdef BUILD_FLOAT
+        BundleScratchSize = 3 * LVM_MAX_CHANNELS \
+                            * (MIN_INTERNAL_BLOCKSIZE + InternalBlockSize) \
+                            * sizeof(LVM_FLOAT);
+#else
         BundleScratchSize = 6 * (MIN_INTERNAL_BLOCKSIZE + InternalBlockSize) * sizeof(LVM_INT16);
+#endif
         InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_TEMPORARY_FAST],        /* Scratch buffer */
                             BundleScratchSize);
         InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_SLOW_DATA],
@@ -233,7 +305,13 @@
          * Set the capabilities
          */
 #if defined(BUILD_FLOAT) && defined(HIGHER_FS)
-        DBE_Capabilities.SampleRate      = LVDBE_CAP_FS_8000 | LVDBE_CAP_FS_11025 | LVDBE_CAP_FS_12000 | LVDBE_CAP_FS_16000 | LVDBE_CAP_FS_22050 | LVDBE_CAP_FS_24000 | LVDBE_CAP_FS_32000 | LVDBE_CAP_FS_44100 | LVDBE_CAP_FS_48000 | LVDBE_CAP_FS_96000 | LVDBE_CAP_FS_192000;
+        DBE_Capabilities.SampleRate      = LVDBE_CAP_FS_8000 | LVDBE_CAP_FS_11025 |
+                                           LVDBE_CAP_FS_12000 | LVDBE_CAP_FS_16000 |
+                                           LVDBE_CAP_FS_22050 | LVDBE_CAP_FS_24000 |
+                                           LVDBE_CAP_FS_32000 | LVDBE_CAP_FS_44100 |
+                                           LVDBE_CAP_FS_48000 | LVDBE_CAP_FS_88200 |
+                                           LVDBE_CAP_FS_96000 | LVDBE_CAP_FS_176400 |
+                                           LVDBE_CAP_FS_192000;
 #else
         DBE_Capabilities.SampleRate      = LVDBE_CAP_FS_8000 | LVDBE_CAP_FS_11025 | LVDBE_CAP_FS_12000 | LVDBE_CAP_FS_16000 | LVDBE_CAP_FS_22050 | LVDBE_CAP_FS_24000 | LVDBE_CAP_FS_32000 | LVDBE_CAP_FS_44100 | LVDBE_CAP_FS_48000;
 #endif
@@ -270,7 +348,13 @@
          * Set the capabilities
          */
 #if defined(BUILD_FLOAT) && defined(HIGHER_FS)
-        EQNB_Capabilities.SampleRate   = LVEQNB_CAP_FS_8000 | LVEQNB_CAP_FS_11025 | LVEQNB_CAP_FS_12000 | LVEQNB_CAP_FS_16000 | LVEQNB_CAP_FS_22050 | LVEQNB_CAP_FS_24000 | LVEQNB_CAP_FS_32000 | LVEQNB_CAP_FS_44100 | LVEQNB_CAP_FS_48000 | LVEQNB_CAP_FS_96000 | LVEQNB_CAP_FS_192000;
+        EQNB_Capabilities.SampleRate   = LVEQNB_CAP_FS_8000 | LVEQNB_CAP_FS_11025 |
+                                         LVEQNB_CAP_FS_12000 | LVEQNB_CAP_FS_16000 |
+                                         LVEQNB_CAP_FS_22050 | LVEQNB_CAP_FS_24000 |
+                                         LVEQNB_CAP_FS_32000 | LVEQNB_CAP_FS_44100 |
+                                         LVEQNB_CAP_FS_48000 | LVEQNB_CAP_FS_88200 |
+                                         LVEQNB_CAP_FS_96000 | LVEQNB_CAP_FS_176400 |
+                                         LVEQNB_CAP_FS_192000;
 #else
         EQNB_Capabilities.SampleRate   = LVEQNB_CAP_FS_8000 | LVEQNB_CAP_FS_11025 | LVEQNB_CAP_FS_12000 | LVEQNB_CAP_FS_16000 | LVEQNB_CAP_FS_22050 | LVEQNB_CAP_FS_24000 | LVEQNB_CAP_FS_32000 | LVEQNB_CAP_FS_44100 | LVEQNB_CAP_FS_48000;
 #endif
@@ -357,8 +441,13 @@
                 PSA_MemTab.Region[LVM_PERSISTENT_FAST_COEF].Size);
 
             /* Fast Temporary */
+#ifdef BUILD_FLOAT
+            InstAlloc_AddMember(&AllocMem[LVM_TEMPORARY_FAST],
+                                MAX_INTERNAL_BLOCKSIZE * sizeof(LVM_FLOAT));
+#else
             InstAlloc_AddMember(&AllocMem[LVM_TEMPORARY_FAST],
                                 MAX_INTERNAL_BLOCKSIZE * sizeof(LVM_INT16));
+#endif
 
             if (PSA_MemTab.Region[LVM_TEMPORARY_FAST].Size > AlgScratchSize)
             {
@@ -547,13 +636,20 @@
          */
         pInstance->pBufferManagement = InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_SLOW_DATA],
                                                            sizeof(LVM_Buffer_t));
+#ifdef BUILD_FLOAT
+        BundleScratchSize = (LVM_INT32)
+                            (3 * LVM_MAX_CHANNELS \
+                             * (MIN_INTERNAL_BLOCKSIZE + InternalBlockSize) \
+                             * sizeof(LVM_FLOAT));
+#else
         BundleScratchSize = (LVM_INT32)(6 * (MIN_INTERNAL_BLOCKSIZE + InternalBlockSize) * sizeof(LVM_INT16));
+#endif
         pInstance->pBufferManagement->pScratch = InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_TEMPORARY_FAST],   /* Scratch 1 buffer */
                                                                      (LVM_UINT32)BundleScratchSize);
 #ifdef BUILD_FLOAT
         LoadConst_Float(0,                                   /* Clear the input delay buffer */
                         (LVM_FLOAT *)&pInstance->pBufferManagement->InDelayBuffer,
-                        (LVM_INT16)(2 * MIN_INTERNAL_BLOCKSIZE));
+                        (LVM_INT16)(LVM_MAX_CHANNELS * MIN_INTERNAL_BLOCKSIZE));
 #else
         LoadConst_16(0,                                                        /* Clear the input delay buffer */
                      (LVM_INT16 *)&pInstance->pBufferManagement->InDelayBuffer,
@@ -584,8 +680,11 @@
     /*
      * DC removal filter
      */
+#ifdef SUPPORT_MC
+    DC_Mc_D16_TRC_WRA_01_Init(&pInstance->DC_RemovalInstance);
+#else
     DC_2I_D16_TRC_WRA_01_Init(&pInstance->DC_RemovalInstance);
-
+#endif
 
     /*
      * Treble Enhancement
@@ -744,7 +843,13 @@
          * Set the initialisation capabilities
          */
 #if defined(BUILD_FLOAT) && defined(HIGHER_FS)
-        DBE_Capabilities.SampleRate      = LVDBE_CAP_FS_8000 | LVDBE_CAP_FS_11025 | LVDBE_CAP_FS_12000 | LVDBE_CAP_FS_16000 | LVDBE_CAP_FS_22050 | LVDBE_CAP_FS_24000 | LVDBE_CAP_FS_32000 | LVDBE_CAP_FS_44100 | LVDBE_CAP_FS_48000 | LVDBE_CAP_FS_96000 | LVDBE_CAP_FS_192000;
+        DBE_Capabilities.SampleRate      = LVDBE_CAP_FS_8000 | LVDBE_CAP_FS_11025 |
+                                           LVDBE_CAP_FS_12000 | LVDBE_CAP_FS_16000 |
+                                           LVDBE_CAP_FS_22050 | LVDBE_CAP_FS_24000 |
+                                           LVDBE_CAP_FS_32000 | LVDBE_CAP_FS_44100 |
+                                           LVDBE_CAP_FS_48000 | LVDBE_CAP_FS_88200 |
+                                           LVDBE_CAP_FS_96000 | LVDBE_CAP_FS_176400 |
+                                           LVDBE_CAP_FS_192000;
 #else
         DBE_Capabilities.SampleRate      = LVDBE_CAP_FS_8000 | LVDBE_CAP_FS_11025 | LVDBE_CAP_FS_12000 | LVDBE_CAP_FS_16000 | LVDBE_CAP_FS_22050 | LVDBE_CAP_FS_24000 | LVDBE_CAP_FS_32000 | LVDBE_CAP_FS_44100 | LVDBE_CAP_FS_48000;
 #endif
@@ -802,7 +907,13 @@
          * Set the initialisation capabilities
          */
 #if defined(BUILD_FLOAT) && defined(HIGHER_FS)
-        EQNB_Capabilities.SampleRate      = LVEQNB_CAP_FS_8000 | LVEQNB_CAP_FS_11025 | LVEQNB_CAP_FS_12000 | LVEQNB_CAP_FS_16000 | LVEQNB_CAP_FS_22050 | LVEQNB_CAP_FS_24000 | LVEQNB_CAP_FS_32000 | LVEQNB_CAP_FS_44100 | LVEQNB_CAP_FS_48000 | LVEQNB_CAP_FS_96000 | LVEQNB_CAP_FS_192000;
+        EQNB_Capabilities.SampleRate      = LVEQNB_CAP_FS_8000 | LVEQNB_CAP_FS_11025 |
+                                            LVEQNB_CAP_FS_12000 | LVEQNB_CAP_FS_16000 |
+                                            LVEQNB_CAP_FS_22050 | LVEQNB_CAP_FS_24000 |
+                                            LVEQNB_CAP_FS_32000 | LVEQNB_CAP_FS_44100 |
+                                            LVEQNB_CAP_FS_48000 | LVEQNB_CAP_FS_88200 |
+                                            LVEQNB_CAP_FS_96000 | LVEQNB_CAP_FS_176400 |
+                                            LVEQNB_CAP_FS_192000;
 #else
         EQNB_Capabilities.SampleRate      = LVEQNB_CAP_FS_8000 | LVEQNB_CAP_FS_11025 | LVEQNB_CAP_FS_12000 | LVEQNB_CAP_FS_16000 | LVEQNB_CAP_FS_22050 | LVEQNB_CAP_FS_24000 | LVEQNB_CAP_FS_32000 | LVEQNB_CAP_FS_44100 | LVEQNB_CAP_FS_48000;
 #endif
@@ -1039,7 +1150,11 @@
     LVM_SetHeadroomParams(hInstance, &HeadroomParams);
 
     /* DC removal filter */
+#ifdef SUPPORT_MC
+    DC_Mc_D16_TRC_WRA_01_Init(&pInstance->DC_RemovalInstance);
+#else
     DC_2I_D16_TRC_WRA_01_Init(&pInstance->DC_RemovalInstance);
+#endif
 
     return LVM_SUCCESS;
 }
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h b/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h
index b453222..cdd3134 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h
@@ -144,12 +144,19 @@
     LVM_FLOAT               *pScratch;          /* Bundle scratch buffer */
 
     LVM_INT16               BufferState;        /* Buffer status */
+#ifdef SUPPORT_MC
+    LVM_FLOAT               InDelayBuffer[3 * LVM_MAX_CHANNELS * MIN_INTERNAL_BLOCKSIZE];
+#else
     LVM_FLOAT               InDelayBuffer[6 * MIN_INTERNAL_BLOCKSIZE]; /* Input buffer delay line, \
                                                                            left and right */
+#endif
     LVM_INT16               InDelaySamples;     /* Number of samples in the input delay buffer */
-
+#ifdef SUPPORT_MC
+    LVM_FLOAT               OutDelayBuffer[LVM_MAX_CHANNELS * MIN_INTERNAL_BLOCKSIZE];
+#else
     LVM_FLOAT               OutDelayBuffer[2 * MIN_INTERNAL_BLOCKSIZE]; /* Output buffer delay \
                                                                                       line */
+#endif
     LVM_INT16               OutDelaySamples;    /* Number of samples in the output delay buffer, \
                                                                              left and right */
     LVM_INT16               SamplesToOutput;    /* Samples to write to the output */
@@ -282,6 +289,11 @@
 
     LVM_INT16              NoSmoothVolume;      /* Enable or disable smooth volume changes*/
 
+#ifdef SUPPORT_MC
+    LVM_INT16              NrChannels;
+    LVM_INT32              ChMask;
+#endif
+
 } LVM_Instance_t;
 
 
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Process.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Process.c
index 4a19a13..bc666a9 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Process.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Process.c
@@ -21,6 +21,7 @@
 /*  Includes                                                                            */
 /*                                                                                      */
 /****************************************************************************************/
+#include <system/audio.h>
 
 #include "LVM_Private.h"
 #include "VectorArithmetic.h"
@@ -65,6 +66,11 @@
     LVM_FLOAT           *pToProcess = (LVM_FLOAT *)pInData;
     LVM_FLOAT           *pProcessed = pOutData;
     LVM_ReturnStatus_en  Status;
+#ifdef SUPPORT_MC
+    LVM_INT32           NrChannels  = pInstance->NrChannels;
+    LVM_INT32           ChMask      = pInstance->ChMask;
+#define NrFrames SampleCount  // alias for clarity
+#endif
 
     /*
      * Check if the number of samples is zero
@@ -112,6 +118,11 @@
     if (pInstance->ControlPending == LVM_TRUE)
     {
         Status = LVM_ApplyNewSettings(hInstance);
+#ifdef SUPPORT_MC
+        /* Update the local variable NrChannels from pInstance->NrChannels value */
+        NrChannels = pInstance->NrChannels;
+        ChMask     = pInstance->ChMask;
+#endif
 
         if(Status != LVM_SUCCESS)
         {
@@ -130,6 +141,10 @@
                        (LVM_INT16)NumSamples);                 /* Number of input samples */
         pInput     = pOutData;
         pToProcess = pOutData;
+#ifdef SUPPORT_MC
+        NrChannels = 2;
+        ChMask     = AUDIO_CHANNEL_OUT_STEREO;
+#endif
     }
 
 
@@ -153,7 +168,6 @@
          */
         if (SampleCount != 0)
         {
-
             /*
              * Apply ConcertSound if required
              */
@@ -171,10 +185,18 @@
              */
             if (pInstance->VC_Active!=0)
             {
+#ifdef SUPPORT_MC
+                LVC_MixSoft_Mc_D16C31_SAT(&pInstance->VC_Volume,
+                                       pToProcess,
+                                       pProcessed,
+                                       (LVM_INT16)(NrFrames),
+                                       NrChannels);
+#else
                 LVC_MixSoft_1St_D16C31_SAT(&pInstance->VC_Volume,
                                        pToProcess,
                                        pProcessed,
                                        (LVM_INT16)(2 * SampleCount));     /* Left and right*/
+#endif
                 pToProcess = pProcessed;
             }
 
@@ -208,9 +230,15 @@
              */
             if (pToProcess != pProcessed)
             {
+#ifdef SUPPORT_MC
+                Copy_Float(pToProcess,                             /* Source */
+                           pProcessed,                             /* Destination */
+                           (LVM_INT16)(NrChannels * NrFrames));    /* Copy all samples */
+#else
                 Copy_Float(pToProcess,                             /* Source */
                            pProcessed,                             /* Destination */
                            (LVM_INT16)(2 * SampleCount));          /* Left and right */
+#endif
             }
 
             /*
@@ -221,20 +249,39 @@
                 /*
                  * Apply the filter
                  */
+#ifdef SUPPORT_MC
+                FO_Mc_D16F32C15_LShx_TRC_WRA_01(&pInstance->pTE_State->TrebleBoost_State,
+                                           pProcessed,
+                                           pProcessed,
+                                           (LVM_INT16)NrFrames,
+                                           (LVM_INT16)NrChannels);
+#else
                 FO_2I_D16F32C15_LShx_TRC_WRA_01(&pInstance->pTE_State->TrebleBoost_State,
                                            pProcessed,
                                            pProcessed,
                                            (LVM_INT16)SampleCount);
+#endif
 
             }
-
+#ifdef SUPPORT_MC
+            /*
+             * Volume balance
+             */
+            LVC_MixSoft_1St_MC_float_SAT(&pInstance->VC_BalanceMix,
+                                          pProcessed,
+                                          pProcessed,
+                                          NrFrames,
+                                          NrChannels,
+                                          ChMask);
+#else
             /*
              * Volume balance
              */
             LVC_MixSoft_1St_2i_D16C31_SAT(&pInstance->VC_BalanceMix,
-                                            pProcessed,
-                                            pProcessed,
-                                            SampleCount);
+                                          pProcessed,
+                                          pProcessed,
+                                          SampleCount);
+#endif
 
             /*
              * Perform Parametric Spectum Analysis
@@ -242,28 +289,39 @@
             if ((pInstance->Params.PSA_Enable == LVM_PSA_ON) &&
                                             (pInstance->InstParams.PSA_Included == LVM_PSA_ON))
             {
-                    From2iToMono_Float(pProcessed,
-                                       pInstance->pPSAInput,
-                                       (LVM_INT16)(SampleCount));
+#ifdef SUPPORT_MC
+                FromMcToMono_Float(pProcessed,
+                                   pInstance->pPSAInput,
+                                   (LVM_INT16)(NrFrames),
+                                   NrChannels);
+#else
+                From2iToMono_Float(pProcessed,
+                                   pInstance->pPSAInput,
+                                   (LVM_INT16)(SampleCount));
+#endif
 
-                    LVPSA_Process(pInstance->hPSAInstance,
-                            pInstance->pPSAInput,
-                            (LVM_UINT16)(SampleCount),
-                            AudioTime);
+                LVPSA_Process(pInstance->hPSAInstance,
+                        pInstance->pPSAInput,
+                        (LVM_UINT16)(SampleCount),
+                        AudioTime);
             }
 
-
             /*
              * DC removal
              */
+#ifdef SUPPORT_MC
+            DC_Mc_D16_TRC_WRA_01(&pInstance->DC_RemovalInstance,
+                                 pProcessed,
+                                 pProcessed,
+                                 (LVM_INT16)NrFrames,
+                                 NrChannels);
+#else
             DC_2I_D16_TRC_WRA_01(&pInstance->DC_RemovalInstance,
                                  pProcessed,
                                  pProcessed,
                                  (LVM_INT16)SampleCount);
-
-
+#endif
         }
-
         /*
          * Manage the output buffer
          */
@@ -497,4 +555,4 @@
 
     return(LVM_SUCCESS);
 }
-#endif
\ No newline at end of file
+#endif
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.c
index 199ddde..a5356d2 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.c
@@ -269,6 +269,53 @@
                      -HPF_Fs48000_Gain15_B1}
 #ifdef HIGHER_FS
                     ,
+                    /* 88kHz Sampling rate */
+                    {HPF_Fs88200_Gain1_A1,             /* Gain Setting  1 */
+                    HPF_Fs88200_Gain1_A0,
+                    -HPF_Fs88200_Gain1_B1},
+                    {HPF_Fs88200_Gain2_A1,             /* Gain Setting  2 */
+                    HPF_Fs88200_Gain2_A0,
+                    -HPF_Fs88200_Gain2_B1},
+                    {HPF_Fs88200_Gain3_A1,             /* Gain Setting  3 */
+                    HPF_Fs88200_Gain3_A0,
+                    -HPF_Fs88200_Gain3_B1},
+                    {HPF_Fs88200_Gain4_A1,             /* Gain Setting  4 */
+                    HPF_Fs88200_Gain4_A0,
+                    -HPF_Fs88200_Gain4_B1},
+                    {HPF_Fs88200_Gain5_A1,             /* Gain Setting  5 */
+                    HPF_Fs88200_Gain5_A0,
+                    -HPF_Fs88200_Gain5_B1},
+                    {HPF_Fs88200_Gain6_A1,             /* Gain Setting  6 */
+                    HPF_Fs88200_Gain6_A0,
+                    -HPF_Fs88200_Gain6_B1},
+                    {HPF_Fs88200_Gain7_A1,             /* Gain Setting  7 */
+                    HPF_Fs88200_Gain7_A0,
+                    -HPF_Fs88200_Gain7_B1},
+                    {HPF_Fs88200_Gain8_A1,             /* Gain Setting  8 */
+                    HPF_Fs88200_Gain8_A0,
+                    -HPF_Fs88200_Gain8_B1},
+                    {HPF_Fs88200_Gain9_A1,             /* Gain Setting  9 */
+                    HPF_Fs88200_Gain9_A0,
+                    -HPF_Fs88200_Gain9_B1},
+                    {HPF_Fs88200_Gain10_A1,             /* Gain Setting  10 */
+                    HPF_Fs88200_Gain10_A0,
+                    -HPF_Fs88200_Gain10_B1},
+                    {HPF_Fs88200_Gain11_A1,             /* Gain Setting  11 */
+                    HPF_Fs88200_Gain11_A0,
+                    -HPF_Fs88200_Gain11_B1},
+                    {HPF_Fs88200_Gain12_A1,             /* Gain Setting  12 */
+                    HPF_Fs88200_Gain12_A0,
+                    -HPF_Fs88200_Gain12_B1},
+                    {HPF_Fs88200_Gain13_A1,             /* Gain Setting  13 */
+                    HPF_Fs88200_Gain13_A0,
+                    -HPF_Fs88200_Gain13_B1},
+                    {HPF_Fs88200_Gain14_A1,             /* Gain Setting  14 */
+                    HPF_Fs88200_Gain14_A0,
+                    -HPF_Fs88200_Gain14_B1},
+                    {HPF_Fs88200_Gain15_A1,             /* Gain Setting  15 */
+                    HPF_Fs88200_Gain15_A0,
+                    -HPF_Fs88200_Gain15_B1},
+
                     /* 96kHz sampling rate */
                     {HPF_Fs96000_Gain1_A1,             /* Gain setting 1 */
                     HPF_Fs96000_Gain1_A0,
@@ -316,6 +363,53 @@
                     HPF_Fs96000_Gain15_A0,
                     -HPF_Fs96000_Gain15_B1},
 
+                    /* 176kHz Sampling rate */
+                    {HPF_Fs176400_Gain1_A1,             /* Gain Setting  1 */
+                    HPF_Fs176400_Gain1_A0,
+                    -HPF_Fs176400_Gain1_B1},
+                    {HPF_Fs176400_Gain2_A1,             /* Gain Setting  2 */
+                    HPF_Fs176400_Gain2_A0,
+                    -HPF_Fs176400_Gain2_B1},
+                    {HPF_Fs176400_Gain3_A1,             /* Gain Setting  3 */
+                    HPF_Fs176400_Gain3_A0,
+                    -HPF_Fs176400_Gain3_B1},
+                    {HPF_Fs176400_Gain4_A1,             /* Gain Setting  4 */
+                    HPF_Fs176400_Gain4_A0,
+                    -HPF_Fs176400_Gain4_B1},
+                    {HPF_Fs176400_Gain5_A1,             /* Gain Setting  5 */
+                    HPF_Fs176400_Gain5_A0,
+                    -HPF_Fs176400_Gain5_B1},
+                    {HPF_Fs176400_Gain6_A1,             /* Gain Setting  6 */
+                    HPF_Fs176400_Gain6_A0,
+                    -HPF_Fs176400_Gain6_B1},
+                    {HPF_Fs176400_Gain7_A1,             /* Gain Setting  7 */
+                    HPF_Fs176400_Gain7_A0,
+                    -HPF_Fs176400_Gain7_B1},
+                    {HPF_Fs176400_Gain8_A1,             /* Gain Setting  8 */
+                    HPF_Fs176400_Gain8_A0,
+                    -HPF_Fs176400_Gain8_B1},
+                    {HPF_Fs176400_Gain9_A1,             /* Gain Setting  9 */
+                    HPF_Fs176400_Gain9_A0,
+                    -HPF_Fs176400_Gain9_B1},
+                    {HPF_Fs176400_Gain10_A1,             /* Gain Setting  10 */
+                    HPF_Fs176400_Gain10_A0,
+                    -HPF_Fs176400_Gain10_B1},
+                    {HPF_Fs176400_Gain11_A1,             /* Gain Setting  11 */
+                    HPF_Fs176400_Gain11_A0,
+                    -HPF_Fs176400_Gain11_B1},
+                    {HPF_Fs176400_Gain12_A1,             /* Gain Setting  12 */
+                    HPF_Fs176400_Gain12_A0,
+                    -HPF_Fs176400_Gain12_B1},
+                    {HPF_Fs176400_Gain13_A1,             /* Gain Setting  13 */
+                    HPF_Fs176400_Gain13_A0,
+                    -HPF_Fs176400_Gain13_B1},
+                    {HPF_Fs176400_Gain14_A1,             /* Gain Setting  14 */
+                    HPF_Fs176400_Gain14_A0,
+                    -HPF_Fs176400_Gain14_B1},
+                    {HPF_Fs176400_Gain15_A1,             /* Gain Setting  15 */
+                    HPF_Fs176400_Gain15_A0,
+                    -HPF_Fs176400_Gain15_B1},
+
                     /* 192kHz sampling rate */
                     {HPF_Fs192000_Gain1_A1,             /* Gain setting 1 */
                     HPF_Fs192000_Gain1_A0,
diff --git a/media/libeffects/lvm/lib/Common/lib/AGC.h b/media/libeffects/lvm/lib/Common/lib/AGC.h
index 9a3d35d..06e742e 100644
--- a/media/libeffects/lvm/lib/Common/lib/AGC.h
+++ b/media/libeffects/lvm/lib/Common/lib/AGC.h
@@ -78,6 +78,15 @@
                                  const LVM_FLOAT            *pMonoSrc,      /* Mono source */
                                  LVM_FLOAT                  *pDst,          /* Stereo destination */
                                  LVM_UINT16                 n);             /* Number of samples */
+#ifdef SUPPORT_MC
+void AGC_MIX_VOL_Mc1Mon_D32_WRA(AGC_MIX_VOL_2St1Mon_FLOAT_t  *pInstance,  /* Instance pointer */
+                                 const LVM_FLOAT            *pStSrc,      /* Source */
+                                 const LVM_FLOAT            *pMonoSrc,    /* Mono source */
+                                 LVM_FLOAT                  *pDst,        /* Destination */
+                                 LVM_UINT16                 NrFrames,     /* Number of frames */
+                                 LVM_UINT16                 NrChannels);  /* Number of channels */
+#endif
+
 #else
 void AGC_MIX_VOL_2St1Mon_D32_WRA(AGC_MIX_VOL_2St1Mon_D32_t  *pInstance,     /* Instance pointer */
                                  const LVM_INT32            *pStSrc,        /* Stereo source */
diff --git a/media/libeffects/lvm/lib/Common/lib/BIQUAD.h b/media/libeffects/lvm/lib/Common/lib/BIQUAD.h
index 3ee7f63..01539b2 100644
--- a/media/libeffects/lvm/lib/Common/lib/BIQUAD.h
+++ b/media/libeffects/lvm/lib/Common/lib/BIQUAD.h
@@ -30,8 +30,17 @@
 #ifdef BUILD_FLOAT
 typedef struct
 {
+#ifdef SUPPORT_MC
+    /* The memory region created by this structure instance is typecast
+     * into another structure containing a pointer and an array of filter
+     * coefficients. In one case this memory region is used for storing
+     * DC component of channels
+     */
+    LVM_FLOAT *pStorage;
+    LVM_FLOAT Storage[LVM_MAX_CHANNELS];
+#else
     LVM_FLOAT Storage[6];
-
+#endif
 } Biquad_FLOAT_Instance_t;
 #else
 typedef struct
@@ -179,7 +188,12 @@
 
 typedef struct
 {
-    LVM_FLOAT Storage[ (2 * 2) ];  /* Two channels, two taps of size LVM_INT32 */
+#ifdef SUPPORT_MC
+    /* LVM_MAX_CHANNELS channels, two taps of size LVM_FLOAT */
+    LVM_FLOAT Storage[ (LVM_MAX_CHANNELS * 2) ];
+#else
+    LVM_FLOAT Storage[ (2 * 2) ];  /* Two channels, two taps of size LVM_FLOAT */
+#endif
 } Biquad_2I_Order1_FLOAT_Taps_t;
 #else
 typedef struct
@@ -197,12 +211,17 @@
 #ifdef BUILD_FLOAT
 typedef struct
 {
-    LVM_FLOAT Storage[ (1 * 4) ];  /* One channel, four taps of size LVM_INT32 */
+    LVM_FLOAT Storage[ (1 * 4) ];  /* One channel, four taps of size LVM_FLOAT */
 } Biquad_1I_Order2_FLOAT_Taps_t;
 
 typedef struct
 {
-    LVM_FLOAT Storage[ (2 * 4) ];  /* Two channels, four taps of size LVM_INT32 */
+#ifdef SUPPORT_MC
+    /* LVM_MAX_CHANNELS, four taps of size LVM_FLOAT */
+    LVM_FLOAT Storage[ (LVM_MAX_CHANNELS * 4) ];
+#else
+    LVM_FLOAT Storage[ (2 * 4) ];  /* Two channels, four taps of size LVM_FLOAT */
+#endif
 } Biquad_2I_Order2_FLOAT_Taps_t;
 #else
 typedef struct
@@ -366,6 +385,13 @@
                                             LVM_FLOAT                    *pDataIn,
                                             LVM_FLOAT                    *pDataOut,
                                             LVM_INT16                 NrSamples);
+#ifdef SUPPORT_MC
+void BQ_MC_D32F32C30_TRC_WRA_01 (           Biquad_FLOAT_Instance_t      *pInstance,
+                                            LVM_FLOAT                    *pDataIn,
+                                            LVM_FLOAT                    *pDataOut,
+                                            LVM_INT16                    NrFrames,
+                                            LVM_INT16                    NrChannels);
+#endif
 #else
 void BQ_2I_D32F32Cll_TRC_WRA_01_Init (      Biquad_Instance_t       *pInstance,
                                             Biquad_2I_Order2_Taps_t *pTaps,
@@ -434,6 +460,13 @@
                                  LVM_FLOAT                     *pDataIn,
                                  LVM_FLOAT                     *pDataOut,
                                  LVM_INT16                     NrSamples);
+#ifdef SUPPORT_MC
+void FO_Mc_D16F32C15_LShx_TRC_WRA_01(Biquad_FLOAT_Instance_t  *pInstance,
+                                     LVM_FLOAT                *pDataIn,
+                                     LVM_FLOAT                *pDataOut,
+                                     LVM_INT16                NrFrames,
+                                     LVM_INT16                NrChannels);
+#endif
 #else
 void FO_1I_D32F32Cll_TRC_WRA_01_Init(       Biquad_Instance_t       *pInstance,
                                             Biquad_1I_Order1_Taps_t *pTaps,
@@ -527,6 +560,13 @@
                                     LVM_FLOAT               *pDataIn,
                                     LVM_FLOAT               *pDataOut,
                                     LVM_INT16               NrSamples);
+#ifdef SUPPORT_MC
+void PK_Mc_D32F32C14G11_TRC_WRA_01(Biquad_FLOAT_Instance_t       *pInstance,
+                                   LVM_FLOAT               *pDataIn,
+                                   LVM_FLOAT               *pDataOut,
+                                   LVM_INT16               NrFrames,
+                                   LVM_INT16               NrChannels);
+#endif
 #else
 void PK_2I_D32F32C14G11_TRC_WRA_01 (        Biquad_Instance_t       *pInstance,
                                             LVM_INT32                    *pDataIn,
@@ -540,12 +580,22 @@
 
 /*** 16 bit data path STEREO ******************************************************/
 #ifdef BUILD_FLOAT
+#ifdef SUPPORT_MC
+void DC_Mc_D16_TRC_WRA_01_Init     (        Biquad_FLOAT_Instance_t       *pInstance);
+
+void DC_Mc_D16_TRC_WRA_01          (        Biquad_FLOAT_Instance_t       *pInstance,
+                                            LVM_FLOAT               *pDataIn,
+                                            LVM_FLOAT               *pDataOut,
+                                            LVM_INT16               NrFrames,
+                                            LVM_INT16               NrChannels);
+#else
 void DC_2I_D16_TRC_WRA_01_Init     (        Biquad_FLOAT_Instance_t       *pInstance);
 
 void DC_2I_D16_TRC_WRA_01          (        Biquad_FLOAT_Instance_t       *pInstance,
                                             LVM_FLOAT               *pDataIn,
                                             LVM_FLOAT               *pDataOut,
                                             LVM_INT16               NrSamples);
+#endif
 #else
 void DC_2I_D16_TRC_WRA_01_Init     (        Biquad_Instance_t       *pInstance);
 
diff --git a/media/libeffects/lvm/lib/Common/lib/LVM_Timer.h b/media/libeffects/lvm/lib/Common/lib/LVM_Timer.h
index 81e288c..a76354d 100644
--- a/media/libeffects/lvm/lib/Common/lib/LVM_Timer.h
+++ b/media/libeffects/lvm/lib/Common/lib/LVM_Timer.h
@@ -44,7 +44,15 @@
 
 typedef struct
 {
-    LVM_INT32 Storage[6];
+    /*
+     * The memory area created using this structure is internally
+     * typecast to LVM_Timer_Instance_Private_t and used.
+     * The LVM_Timer_Instance_Private_t structure has 3 pointer type elements
+     * 2 elements of type LVM_INT32 and one element of type LVM_INT16.
+     * Inorder to cater both 32 and 64 bit builds, Storage array should
+     * have a minimum of 9 elements of type LVM_INT32.
+     */
+    LVM_INT32 Storage[9];
 
 } LVM_Timer_Instance_t;
 
diff --git a/media/libeffects/lvm/lib/Common/lib/LVM_Types.h b/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
index ea16072..fbfdd4d 100644
--- a/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
+++ b/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
@@ -94,6 +94,7 @@
 
 typedef     int32_t             LVM_INT32;          /* Signed 32-bit word */
 typedef     uint32_t            LVM_UINT32;         /* Unsigned 32-bit word */
+typedef     int64_t             LVM_INT64;          /* Signed 64-bit word */
 
 #ifdef BUILD_FLOAT
 
@@ -122,6 +123,12 @@
 
 #endif // NATIVE_FLOAT_BUFFER
 
+#ifdef SUPPORT_MC
+#define LVM_MAX_CHANNELS 8 // FCC_8
+#else
+#define LVM_MAX_CHANNELS 2 // FCC_2
+#endif
+
 /****************************************************************************************/
 /*                                                                                      */
 /*  Standard Enumerated types                                                           */
@@ -143,6 +150,9 @@
     LVM_STEREO          = 0,
     LVM_MONOINSTEREO    = 1,
     LVM_MONO            = 2,
+#ifdef SUPPORT_MC
+    LVM_MULTICHANNEL    = 3,
+#endif
     LVM_SOURCE_DUMMY    = LVM_MAXENUM
 } LVM_Format_en;
 
@@ -160,8 +170,10 @@
     LVM_FS_44100 = 7,
     LVM_FS_48000 = 8,
 #ifdef HIGHER_FS
-    LVM_FS_96000 = 9,
-    LVM_FS_192000 = 10,
+    LVM_FS_88200 = 9,
+    LVM_FS_96000 = 10,
+    LVM_FS_176400 = 11,
+    LVM_FS_192000 = 12,
 #endif
     LVM_FS_INVALID = LVM_MAXENUM-1,
     LVM_FS_DUMMY = LVM_MAXENUM
diff --git a/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h b/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
index 0ba20a3..7468a90 100644
--- a/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
+++ b/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
@@ -47,6 +47,16 @@
 void Copy_Float(                 const LVM_FLOAT *src,
                                  LVM_FLOAT *dst,
                                  LVM_INT16 n );
+#ifdef SUPPORT_MC
+void Copy_Float_Mc_Stereo(       const LVM_FLOAT *src,
+                                 LVM_FLOAT *dst,
+                                 LVM_INT16 NrFrames,
+                                 LVM_INT32 NrChannels);
+void Copy_Float_Stereo_Mc(       const LVM_FLOAT *src,
+                                 LVM_FLOAT *dst,
+                                 LVM_INT16 NrFrames,
+                                 LVM_INT32 NrChannels);
+#endif
 #else
 void Copy_16(                 const LVM_INT16 *src,
                                     LVM_INT16 *dst,
@@ -181,6 +191,12 @@
 void From2iToMono_Float(         const LVM_FLOAT  *src,
                                  LVM_FLOAT  *dst,
                                  LVM_INT16 n);
+#ifdef SUPPORT_MC
+void FromMcToMono_Float(const LVM_FLOAT *src,
+                        LVM_FLOAT *dst,
+                        LVM_INT16 NrFrames,
+                        LVM_INT16 NrChannels);
+#endif
 #else
 void From2iToMono_32(         const LVM_INT32  *src,
                                     LVM_INT32  *dst,
diff --git a/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.c b/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.c
index fa9f01f..5c8655f 100644
--- a/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.c
+++ b/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.c
@@ -305,4 +305,150 @@
 
     return;
 }
+#ifdef SUPPORT_MC
+/****************************************************************************************/
+/*                                                                                      */
+/* FUNCTION:                  AGC_MIX_VOL_Mc1Mon_D32_WRA                                */
+/*                                                                                      */
+/* DESCRIPTION:                                                                         */
+/*    Apply AGC and mix signals                                                         */
+/*                                                                                      */
+/*                                                                                      */
+/*  McSrc   ------------------|                                                         */
+/*                            |                                                         */
+/*              ______       _|_        ________                                        */
+/*             |      |     |   |      |        |                                       */
+/*  MonoSrc -->| AGC  |---->| + |----->| Volume |------------------------------+--->    */
+/*             | Gain |     |___|      | Gain   |                              |        */
+/*             |______|                |________|                              |        */
+/*                /|\                               __________     ________    |        */
+/*                 |                               |          |   |        |   |        */
+/*                 |-------------------------------| AGC Gain |<--| Peak   |<--|        */
+/*                                                 | Update   |   | Detect |            */
+/*                                                 |__________|   |________|            */
+/*                                                                                      */
+/*                                                                                      */
+/* PARAMETERS:                                                                          */
+/*  pInstance               Instance pointer                                            */
+/*  pMcSrc                  Multichannel source                                         */
+/*  pMonoSrc                Mono band pass source                                       */
+/*  pDst                    Multichannel destination                                    */
+/*  NrFrames                Number of frames                                            */
+/*  NrChannels              Number of channels                                          */
+/*                                                                                      */
+/* RETURNS:                                                                             */
+/*  Void                                                                                */
+/*                                                                                      */
+/* NOTES:                                                                               */
+/*                                                                                      */
+/****************************************************************************************/
+void AGC_MIX_VOL_Mc1Mon_D32_WRA(AGC_MIX_VOL_2St1Mon_FLOAT_t  *pInstance,
+                                 const LVM_FLOAT            *pMcSrc,
+                                 const LVM_FLOAT            *pMonoSrc,
+                                 LVM_FLOAT                  *pDst,
+                                 LVM_UINT16                 NrFrames,
+                                 LVM_UINT16                 NrChannels)
+{
+
+    /*
+     * General variables
+     */
+    LVM_UINT16      i, jj;                                      /* Sample index */
+    LVM_FLOAT       SampleVal;                                  /* Sample value */
+    LVM_FLOAT       Mono;                                       /* Mono sample */
+    LVM_FLOAT       AbsPeak;                                    /* Absolute peak signal */
+    LVM_FLOAT       AGC_Mult;                                   /* Short AGC gain */
+    LVM_FLOAT       Vol_Mult;                                   /* Short volume */
+
+
+    /*
+     * Instance control variables
+     */
+    LVM_FLOAT      AGC_Gain      = pInstance->AGC_Gain;         /* Get the current AGC gain */
+    LVM_FLOAT      AGC_MaxGain   = pInstance->AGC_MaxGain;      /* Get maximum AGC gain */
+    LVM_FLOAT      AGC_Attack    = pInstance->AGC_Attack;       /* Attack scaler */
+    /* Decay scaler */
+    LVM_FLOAT      AGC_Decay     = (pInstance->AGC_Decay * (1 << (DECAY_SHIFT)));
+    LVM_FLOAT      AGC_Target    = pInstance->AGC_Target;       /* Get the target level */
+    LVM_FLOAT      Vol_Current   = pInstance->Volume;           /* Actual volume setting */
+    LVM_FLOAT      Vol_Target    = pInstance->Target;           /* Target volume setting */
+    LVM_FLOAT      Vol_TC        = pInstance->VolumeTC;         /* Time constant */
+
+
+    /*
+     * Process on a sample by sample basis
+     */
+    for (i = 0; i < NrFrames; i++)                                  /* For each frame */
+    {
+
+        /*
+         * Get the scalers
+         */
+        AGC_Mult    = (LVM_FLOAT)(AGC_Gain);              /* Get the AGC gain */
+        Vol_Mult    = (LVM_FLOAT)(Vol_Current);           /* Get the volume gain */
+
+        AbsPeak = 0.0f;
+        /*
+         * Get the input samples
+         */
+        for (jj = 0; jj < NrChannels; jj++)
+        {
+            SampleVal  = *pMcSrc++;                       /* Get the sample value of jj Channel*/
+            Mono       = *pMonoSrc;                       /* Get the mono sample */
+
+            /*
+             * Apply the AGC gain to the mono input and mix with the input signal
+             */
+            SampleVal  += (Mono * AGC_Mult);                        /* Mix in the mono signal */
+
+            /*
+             * Apply the volume and write to the output stream
+             */
+            SampleVal  = SampleVal  * Vol_Mult;
+
+            *pDst++ = SampleVal;                                         /* Save the results */
+
+            /*
+             * Update the AGC gain
+             */
+            AbsPeak = Abs_Float(SampleVal) > AbsPeak ? Abs_Float(SampleVal) : AbsPeak;
+        }
+        if (AbsPeak > AGC_Target)
+        {
+            /*
+             * The signal is too large so decrease the gain
+             */
+            AGC_Gain = AGC_Gain * AGC_Attack;
+        }
+        else
+        {
+            /*
+             * The signal is too small so increase the gain
+             */
+            if (AGC_Gain > AGC_MaxGain)
+            {
+                AGC_Gain -= (AGC_Decay);
+            }
+            else
+            {
+                AGC_Gain += (AGC_Decay);
+            }
+        }
+        pMonoSrc++;
+        /*
+         * Update the gain
+         */
+        Vol_Current +=  (Vol_Target - Vol_Current) * ((LVM_FLOAT)Vol_TC / VOL_TC_FLOAT);
+    }
+
+
+    /*
+     * Update the parameters
+     */
+    pInstance->Volume = Vol_Current;                            /* Actual volume setting */
+    pInstance->AGC_Gain = AGC_Gain;
+
+    return;
+}
+#endif /*SUPPORT_MC*/
 #endif /*BUILD_FLOAT*/
diff --git a/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.c b/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.c
index e3edccc..66d6adb 100644
--- a/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.c
+++ b/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.c
@@ -43,11 +43,11 @@
         {
             if(a<0)
             {
-                c=0x80000000l;
+                c=0x80000000L;
             }
             else
             {
-                c=0x7FFFFFFFl;
+                c=0x7FFFFFFFL;
             }
         }
 
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.c
index 960de79..d63365c 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.c
@@ -123,6 +123,87 @@
         }
 
     }
+
+#ifdef SUPPORT_MC
+/**************************************************************************
+ ASSUMPTIONS:
+ COEFS-
+ pBiquadState->coefs[0] is A2, pBiquadState->coefs[1] is A1
+ pBiquadState->coefs[2] is A0, pBiquadState->coefs[3] is -B2
+ pBiquadState->coefs[4] is -B1
+
+ DELAYS-
+ pBiquadState->pDelays[0] to
+ pBiquadState->pDelays[NrChannels - 1] is x(n-1) for all NrChannels
+
+ pBiquadState->pDelays[NrChannels] to
+ pBiquadState->pDelays[2*NrChannels - 1] is x(n-2) for all NrChannels
+
+ pBiquadState->pDelays[2*NrChannels] to
+ pBiquadState->pDelays[3*NrChannels - 1] is y(n-1) for all NrChannels
+
+ pBiquadState->pDelays[3*NrChannels] to
+ pBiquadState->pDelays[4*NrChannels - 1] is y(n-2) for all NrChannels
+***************************************************************************/
+void BQ_MC_D32F32C30_TRC_WRA_01 (           Biquad_FLOAT_Instance_t      *pInstance,
+                                            LVM_FLOAT                    *pDataIn,
+                                            LVM_FLOAT                    *pDataOut,
+                                            LVM_INT16                    NrFrames,
+                                            LVM_INT16                    NrChannels)
+
+
+    {
+        LVM_FLOAT yn, temp;
+        LVM_INT16 ii, jj;
+        PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+
+         for (ii = NrFrames; ii != 0; ii--)
+         {
+            /**************************************************************************
+                            PROCESSING CHANNEL-WISE
+            ***************************************************************************/
+            for (jj = 0; jj < NrChannels; jj++)
+            {
+                /* yn= (A2  * x(n-2)) */
+                yn = pBiquadState->coefs[0] * pBiquadState->pDelays[NrChannels + jj];
+
+                /* yn+= (A1  * x(n-1)) */
+                temp = pBiquadState->coefs[1] * pBiquadState->pDelays[jj];
+                yn += temp;
+
+                /* yn+= (A0  * x(n)) */
+                temp = pBiquadState->coefs[2] * (*pDataIn);
+                yn += temp;
+
+                 /* yn+= (-B2  * y(n-2)) */
+                temp = pBiquadState->coefs[3] * pBiquadState->pDelays[NrChannels*3 + jj];
+                yn += temp;
+
+                /* yn+= (-B1  * y(n-1)) */
+                temp = pBiquadState->coefs[4] * pBiquadState->pDelays[NrChannels*2 + jj];
+                yn += temp;
+
+                /**************************************************************************
+                                UPDATING THE DELAYS
+                ***************************************************************************/
+                pBiquadState->pDelays[NrChannels * 3 + jj] =
+                    pBiquadState->pDelays[NrChannels * 2 + jj]; /* y(n-2)=y(n-1)*/
+                pBiquadState->pDelays[NrChannels * 1 + jj] =
+                    pBiquadState->pDelays[jj]; /* x(n-2)=x(n-1)*/
+                pBiquadState->pDelays[NrChannels * 2 + jj] = (LVM_FLOAT)yn; /* Update y(n-1)*/
+                pBiquadState->pDelays[jj] = (*pDataIn); /* Update x(n-1)*/
+                pDataIn++;
+                /**************************************************************************
+                                WRITING THE OUTPUT
+                ***************************************************************************/
+                *pDataOut = (LVM_FLOAT)yn; /* Write jj Channel output */
+                pDataOut++;
+            }
+        }
+
+    }
+#endif /*SUPPORT_MC*/
+
 #else
 void BQ_2I_D32F32C30_TRC_WRA_01 (           Biquad_Instance_t       *pInstance,
                                             LVM_INT32                    *pDataIn,
diff --git a/media/libeffects/lvm/lib/Common/src/Copy_16.c b/media/libeffects/lvm/lib/Common/src/Copy_16.c
index e489031..3858450 100644
--- a/media/libeffects/lvm/lib/Common/src/Copy_16.c
+++ b/media/libeffects/lvm/lib/Common/src/Copy_16.c
@@ -84,5 +84,65 @@
 
     return;
 }
+#ifdef SUPPORT_MC
+// Extract out the stereo channel pair from multichannel source.
+void Copy_Float_Mc_Stereo(const LVM_FLOAT *src,
+                 LVM_FLOAT *dst,
+                 LVM_INT16 NrFrames, /* Number of frames */
+                 LVM_INT32 NrChannels)
+{
+    LVM_INT16 ii;
+
+    if (NrChannels >= 2)
+    {
+        for (ii = NrFrames; ii != 0; ii--)
+        {
+            dst[0] = src[0];
+            dst[1] = src[1];
+            dst += 2;
+            src += NrChannels;
+        }
+    }
+    else if (NrChannels == 1)
+    {   // not expected to occur, provided for completeness.
+        src += (NrFrames - 1);
+        dst += 2 * (NrFrames - 1);
+        for (ii = NrFrames; ii != 0; ii--)
+        {
+            dst[0] = src[0];
+            dst[1] = src[0];
+            dst -= 2;
+            src --;
+        }
+    }
+}
+
+// Merge a multichannel source with stereo contained in dst, to dst.
+void Copy_Float_Stereo_Mc(const LVM_FLOAT *src,
+                 LVM_FLOAT *dst,
+                 LVM_INT16 NrFrames, /* Number of frames*/
+                 LVM_INT32 NrChannels)
+{
+    LVM_INT16 ii, jj;
+    LVM_FLOAT *src_st = dst + 2 * (NrFrames - 1);
+
+    // repack dst which carries stereo information
+    // together with the upper channels of src.
+    dst += NrChannels * (NrFrames - 1);
+    src += NrChannels * (NrFrames - 1);
+    for (ii = NrFrames; ii != 0; ii--)
+    {
+        dst[1] = src_st[1];
+        dst[0] = src_st[0]; // copy 1 before 0 is required for NrChannels == 3.
+        for (jj = 2; jj < NrChannels; jj++)
+        {
+            dst[jj] = src[jj];
+        }
+        dst    -= NrChannels;
+        src    -= NrChannels;
+        src_st -= 2;
+    }
+}
+#endif
 #endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.c
index d261c9e..13fac5e 100644
--- a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.c
@@ -33,7 +33,7 @@
         RightDC = pBiquadState->RightDC;
         for(j = NrSamples-1; j >= 0; j--)
         {
-            /* Subtract DC an saturate */
+            /* Subtract DC and saturate */
             Diff =* (pDataIn++) - (LeftDC);
             if (Diff > 1.0f) {
                 Diff = 1.0f; }
@@ -64,6 +64,58 @@
 
 
     }
+#ifdef SUPPORT_MC
+/*
+ * FUNCTION:       DC_Mc_D16_TRC_WRA_01
+ *
+ * DESCRIPTION:
+ *  DC removal from all channels of a multichannel input
+ *
+ * PARAMETERS:
+ *  pInstance      Instance pointer
+ *  pDataIn        Input/Source
+ *  pDataOut       Output/Destination
+ *  NrFrames       Number of frames
+ *  NrChannels     Number of channels
+ *
+ * RETURNS:
+ *  void
+ *
+ */
+void DC_Mc_D16_TRC_WRA_01(Biquad_FLOAT_Instance_t       *pInstance,
+                          LVM_FLOAT               *pDataIn,
+                          LVM_FLOAT               *pDataOut,
+                          LVM_INT16               NrFrames,
+                          LVM_INT16               NrChannels)
+    {
+        LVM_FLOAT *ChDC;
+        LVM_FLOAT Diff;
+        LVM_INT32 j;
+        LVM_INT32 i;
+        PFilter_FLOAT_State_Mc pBiquadState = (PFilter_FLOAT_State_Mc) pInstance;
+
+        ChDC = &pBiquadState->ChDC[0];
+        for (j = NrFrames - 1; j >= 0; j--)
+        {
+            /* Subtract DC and saturate */
+            for (i = NrChannels - 1; i >= 0; i--)
+            {
+                Diff = *(pDataIn++) - (ChDC[i]);
+                if (Diff > 1.0f) {
+                    Diff = 1.0f;
+                } else if (Diff < -1.0f) {
+                    Diff = -1.0f; }
+                *(pDataOut++) = (LVM_FLOAT)Diff;
+                if (Diff < 0) {
+                    ChDC[i] -= DC_FLOAT_STEP;
+                } else {
+                    ChDC[i] += DC_FLOAT_STEP; }
+            }
+
+        }
+
+    }
+#endif
 #else
 void DC_2I_D16_TRC_WRA_01( Biquad_Instance_t       *pInstance,
                            LVM_INT16               *pDataIn,
diff --git a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.c
index 4f4fcd8..0f941a0 100644
--- a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.c
@@ -24,6 +24,17 @@
     pBiquadState->LeftDC        = 0.0f;
     pBiquadState->RightDC       = 0.0f;
 }
+#ifdef SUPPORT_MC
+void  DC_Mc_D16_TRC_WRA_01_Init(Biquad_FLOAT_Instance_t   *pInstance)
+{
+    PFilter_FLOAT_State_Mc pBiquadState  = (PFilter_FLOAT_State_Mc) pInstance;
+    LVM_INT32 i;
+    for (i = 0; i < LVM_MAX_CHANNELS; i++)
+    {
+        pBiquadState->ChDC[i] = 0.0f;
+    }
+}
+#endif
 #else
 void  DC_2I_D16_TRC_WRA_01_Init(Biquad_Instance_t   *pInstance)
 {
diff --git a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Private.h
index fa6b729..db3a6d3 100644
--- a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Private.h
@@ -34,6 +34,13 @@
     LVM_FLOAT  RightDC;    /* RightDC  */
 }Filter_FLOAT_State;
 typedef Filter_FLOAT_State * PFilter_FLOAT_State ;
+#ifdef SUPPORT_MC
+typedef struct _Filter_FLOAT_State_Mc_
+{
+    LVM_FLOAT  ChDC[LVM_MAX_CHANNELS];     /* ChannelDC  */
+} Filter_FLOAT_State_Mc;
+typedef Filter_FLOAT_State_Mc * PFilter_FLOAT_State_Mc ;
+#endif
 #else
 typedef struct _Filter_State_
 {
diff --git a/media/libeffects/lvm/lib/Common/src/DelayAllPass_Sat_32x16To32.c b/media/libeffects/lvm/lib/Common/src/DelayAllPass_Sat_32x16To32.c
index 2e20d79..b04e98e 100644
--- a/media/libeffects/lvm/lib/Common/src/DelayAllPass_Sat_32x16To32.c
+++ b/media/libeffects/lvm/lib/Common/src/DelayAllPass_Sat_32x16To32.c
@@ -53,11 +53,11 @@
         {
             if(a < 0)
             {
-                c = 0x80000000l;
+                c = 0x80000000L;
             }
             else
             {
-                c = 0x7FFFFFFFl;
+                c = 0x7FFFFFFFL;
             }
         }
         *dst = c;
@@ -72,11 +72,11 @@
         {
             if(a < 0)
             {
-                c = 0x80000000l;
+                c = 0x80000000L;
             }
             else
             {
-                c = 0x7FFFFFFFl;
+                c = 0x7FFFFFFFL;
             }
         }
         delay[AllPassOffset] = c;
diff --git a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.c
index 192927c..2a50f18 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.c
@@ -117,6 +117,93 @@
         }
 
     }
+#ifdef SUPPORT_MC
+/**************************************************************************
+ASSUMPTIONS:
+COEFS-
+pBiquadState->coefs[0] is A1,
+pBiquadState->coefs[1] is A0,
+pBiquadState->coefs[2] is -B1,
+DELAYS-
+pBiquadState->pDelays[2*ch + 0] is x(n-1) of the 'ch' - channel
+pBiquadState->pDelays[2*ch + 1] is y(n-1) of the 'ch' - channel
+The index 'ch' runs from 0 to (NrChannels - 1)
+
+PARAMETERS:
+ pInstance        Pointer Instance
+ pDataIn          Input/Source
+ pDataOut         Output/Destination
+ NrFrames         Number of frames
+ NrChannels       Number of channels
+
+RETURNS:
+ void
+***************************************************************************/
+void FO_Mc_D16F32C15_LShx_TRC_WRA_01(Biquad_FLOAT_Instance_t *pInstance,
+                                     LVM_FLOAT               *pDataIn,
+                                     LVM_FLOAT               *pDataOut,
+                                     LVM_INT16               NrFrames,
+                                     LVM_INT16               NrChannels)
+    {
+        LVM_FLOAT   yn;
+        LVM_FLOAT   Temp;
+        LVM_INT16   ii;
+        LVM_INT16   ch;
+        PFilter_Float_State pBiquadState = (PFilter_Float_State) pInstance;
+
+        LVM_FLOAT   *pDelays = pBiquadState->pDelays;
+        LVM_FLOAT   *pCoefs  = &pBiquadState->coefs[0];
+        LVM_FLOAT   A0 = pCoefs[1];
+        LVM_FLOAT   A1 = pCoefs[0];
+        LVM_FLOAT   B1 = pCoefs[2];
+
+
+
+
+        for (ii = NrFrames; ii != 0; ii--)
+        {
+
+            /**************************************************************************
+                            PROCESSING OF THE CHANNELS
+            ***************************************************************************/
+            for (ch = 0; ch < NrChannels; ch++)
+            {
+                // yn =A1  * x(n-1)
+                yn = (LVM_FLOAT)A1 * pDelays[0];
+
+                // yn+=A0  * x(n)
+                yn += (LVM_FLOAT)A0 * (*pDataIn);
+
+                // yn +=  (-B1  * y(n-1))
+                Temp = B1 * pDelays[1];
+                yn += Temp;
+
+
+                /**************************************************************************
+                                UPDATING THE DELAYS
+                ***************************************************************************/
+                pDelays[1] = yn; // Update y(n-1)
+                pDelays[0] = (*pDataIn++); // Update x(n-1)
+
+                /**************************************************************************
+                                WRITING THE OUTPUT
+                ***************************************************************************/
+
+                /*Saturate results*/
+                if (yn > 1.0f)
+                {
+                    yn = 1.0f;
+                } else if (yn < -1.0f) {
+                    yn = -1.0f;
+                }
+
+                *pDataOut++ = (LVM_FLOAT)yn;
+                pDelays += 2;
+            }
+            pDelays -= NrChannels * 2;
+        }
+    }
+#endif
 #else
 void FO_2I_D16F32C15_LShx_TRC_WRA_01(Biquad_Instance_t       *pInstance,
                                      LVM_INT16               *pDataIn,
diff --git a/media/libeffects/lvm/lib/Common/src/From2iToMono_32.c b/media/libeffects/lvm/lib/Common/src/From2iToMono_32.c
index ac1eea8..d02af88 100644
--- a/media/libeffects/lvm/lib/Common/src/From2iToMono_32.c
+++ b/media/libeffects/lvm/lib/Common/src/From2iToMono_32.c
@@ -68,5 +68,47 @@
 
     return;
 }
+#ifdef SUPPORT_MC
+/*
+ * FUNCTION:       FromMcToMono_Float
+ *
+ * DESCRIPTION:
+ *  Creates a mono stream from a multichannel input taking the avergae of
+ *  sample values of all channels
+ *
+ * PARAMETERS:
+ *  src            Source
+ *  dst            Destination
+ *  NrFrames       Number of frames
+ *  NrChannels     Number of channels
+ *
+ * RETURNS:
+ *  void
+ *
+ */
+void FromMcToMono_Float(const LVM_FLOAT *src,
+                        LVM_FLOAT *dst,
+                        LVM_INT16 NrFrames,
+                        LVM_INT16 NrChannels)
+{
+    LVM_INT16 ii, jj;
+    LVM_FLOAT Temp;
+
+    for (ii = NrFrames; ii != 0; ii--)
+    {
+        Temp = 0.0f;
+        for (jj = NrChannels; jj !=0; jj--)
+        {
+            Temp += (*src);
+            src++;
+        }
+        *dst = Temp / NrChannels;
+        dst++;
+    }
+
+    return;
+}
+#endif
+
 #endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.c
index eb5755e..db76cd1 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.c
@@ -59,6 +59,31 @@
 
 
 }
+#ifdef SUPPORT_MC
+void LVC_Core_MixHard_1St_MC_float_SAT (Mix_Private_FLOAT_st **ptrInstance,
+                                         const LVM_FLOAT      *src,
+                                         LVM_FLOAT            *dst,
+                                         LVM_INT16            NrFrames,
+                                         LVM_INT16            NrChannels)
+{
+    LVM_FLOAT  Temp;
+    LVM_INT16 ii, jj;
+    for (ii = NrFrames; ii != 0; ii--)
+    {
+        for (jj = 0; jj < NrChannels; jj++)
+        {
+            Mix_Private_FLOAT_st  *pInstance1 = (Mix_Private_FLOAT_st *)(ptrInstance[jj]);
+            Temp = ((LVM_FLOAT)*(src++) * (LVM_FLOAT)pInstance1->Current);
+            if (Temp > 1.0f)
+                *dst++ = 1.0f;
+            else if (Temp < -1.0f)
+                *dst++ = -1.0f;
+            else
+                *dst++ = (LVM_FLOAT)Temp;
+        }
+    }
+}
+#endif
 #else
 void LVC_Core_MixHard_1St_2i_D16C31_SAT( LVMixer3_st        *ptrInstance1,
                                          LVMixer3_st        *ptrInstance2,
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.c
index d2694cc..419c7c5 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.c
@@ -26,10 +26,10 @@
    FUNCTION LVCore_MIXSOFT_1ST_D16C31_WRA
 ***********************************************************************************/
 #ifdef BUILD_FLOAT
-void LVC_Core_MixInSoft_D16C31_SAT( LVMixer3_FLOAT_st *ptrInstance,
-                                    const LVM_FLOAT     *src,
-                                          LVM_FLOAT     *dst,
-                                          LVM_INT16     n)
+void LVC_Core_MixInSoft_D16C31_SAT(LVMixer3_FLOAT_st *ptrInstance,
+                                   const LVM_FLOAT   *src,
+                                         LVM_FLOAT   *dst,
+                                         LVM_INT16   n)
 {
 
     LVM_INT16   OutLoop;
@@ -114,6 +114,139 @@
     }
     pInstance->Current = Current;
 }
+#ifdef SUPPORT_MC
+/*
+ * FUNCTION:       LVC_Core_MixInSoft_Mc_D16C31_SAT
+ *
+ * DESCRIPTION:
+ *  Mixer function with support for processing multichannel input.
+ *
+ * PARAMETERS:
+ *  ptrInstance    Instance pointer
+ *  src            Source
+ *  dst            Destination
+ *  NrFrames       Number of frames
+ *  NrChannels     Number of channels
+ *
+ * RETURNS:
+ *  void
+ *
+ */
+void LVC_Core_MixInSoft_Mc_D16C31_SAT(LVMixer3_FLOAT_st *ptrInstance,
+                                      const LVM_FLOAT   *src,
+                                            LVM_FLOAT   *dst,
+                                            LVM_INT16   NrFrames,
+                                            LVM_INT16   NrChannels)
+{
+
+    LVM_INT16   OutLoop;
+    LVM_INT16   InLoop;
+    LVM_INT32   ii, jj;
+    Mix_Private_FLOAT_st  *pInstance = (Mix_Private_FLOAT_st *)(ptrInstance->PrivateParams);
+    LVM_FLOAT   Delta = pInstance->Delta;
+    LVM_FLOAT   Current = pInstance->Current;
+    LVM_FLOAT   Target = pInstance->Target;
+    LVM_FLOAT   Temp;
+
+    /*
+     * Same operation is performed on consecutive frames.
+     * So two frames are processed in one iteration and
+     * the loop will run only for half the NrFrames value times.
+     */
+    InLoop = (LVM_INT16)(NrFrames >> 1);
+    /* OutLoop is calculated to handle cases where NrFrames value can be odd.*/
+    OutLoop = (LVM_INT16)(NrFrames - (InLoop << 1));
+
+    if (Current < Target) {
+        if (OutLoop) {
+            Temp = Current + Delta;
+            Current = Temp;
+            if (Current > Target)
+                Current = Target;
+
+           for (ii = OutLoop*NrChannels; ii != 0; ii--) {
+                Temp = (*dst) + (*(src++) * Current);
+                if (Temp > 1.0f)
+                    *dst++ = 1.0f;
+                else if (Temp < -1.0f)
+                    *dst++ = -1.0f;
+                else
+                    *dst++ = Temp;
+            }
+        }
+
+        for (ii = InLoop; ii != 0; ii--) {
+            Temp = Current + Delta;
+            Current = Temp;
+            if (Current > Target)
+                Current = Target;
+
+            for (jj = NrChannels; jj != 0 ; jj--) {
+                Temp = (*dst) + (*(src++) * Current);
+                if (Temp > 1.0f)
+                    *dst++ = 1.0f;
+                else if (Temp < -1.0f)
+                    *dst++ = -1.0f;
+                else
+                    *dst++ = Temp;
+
+                Temp = (*dst) + (*(src++) * Current);
+                if (Temp > 1.0f)
+                    *dst++ = 1.0f;
+                else if (Temp < -1.0f)
+                    *dst++ = -1.0f;
+                else
+                    *dst++ = Temp;
+
+            }
+        }
+    }
+    else{
+        if (OutLoop) {
+            Current -= Delta;
+            if (Current < Target)
+                Current = Target;
+
+            for (ii = OutLoop*NrChannels; ii != 0; ii--) {
+                Temp = (*dst) + (*(src++) * Current);
+                if (Temp > 1.0f)
+                    *dst++ = 1.0f;
+                else if (Temp < -1.0f)
+                    *dst++ = -1.0f;
+                else
+                    *dst++ = Temp;
+            }
+        }
+
+        for (ii = InLoop; ii != 0; ii--) {
+            Current -= Delta;
+            if (Current < Target)
+                Current = Target;
+
+            for (jj = NrChannels; jj != 0 ; jj--) {
+                Temp = (*dst) + (*(src++) * Current);
+                if (Temp > 1.0f)
+                    *dst++ = 1.0f;
+                else if (Temp < -1.0f)
+                    *dst++ = -1.0f;
+                else
+                    *dst++ = Temp;
+
+                Temp = (*dst) + (*(src++) * Current);
+                if (Temp > 1.0f)
+                    *dst++ = 1.0f;
+                else if (Temp < -1.0f)
+                    *dst++ = -1.0f;
+                else
+                    *dst++ = Temp;
+
+            }
+        }
+    }
+    pInstance->Current = Current;
+}
+
+#endif
 #else
 void LVC_Core_MixInSoft_D16C31_SAT( LVMixer3_st *ptrInstance,
                                     const LVM_INT16     *src,
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.c b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.c
index 656a117..56b5dae 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.c
@@ -146,6 +146,51 @@
     pInstanceR->Current = CurrentR;
 
 }
+#ifdef SUPPORT_MC
+void LVC_Core_MixSoft_1St_MC_float_WRA (Mix_Private_FLOAT_st **ptrInstance,
+                                         const LVM_FLOAT      *src,
+                                         LVM_FLOAT            *dst,
+                                         LVM_INT16            NrFrames,
+                                         LVM_INT16            NrChannels)
+{
+    LVM_INT32   ii, ch;
+    LVM_FLOAT   Temp =0.0f;
+    LVM_FLOAT   tempCurrent[NrChannels];
+    for (ch = 0; ch < NrChannels; ch++)
+    {
+        tempCurrent[ch] = ptrInstance[ch]->Current;
+    }
+    for (ii = NrFrames; ii > 0; ii--)
+    {
+        for (ch = 0; ch < NrChannels; ch++)
+        {
+            Mix_Private_FLOAT_st *pInstance = ptrInstance[ch];
+            const LVM_FLOAT   Delta = pInstance->Delta;
+            LVM_FLOAT         Current = tempCurrent[ch];
+            const LVM_FLOAT   Target = pInstance->Target;
+            if (Current < Target)
+            {
+                ADD2_SAT_FLOAT(Current, Delta, Temp);
+                Current = Temp;
+                if (Current > Target)
+                    Current = Target;
+            }
+            else
+            {
+                Current -= Delta;
+                if (Current < Target)
+                    Current = Target;
+            }
+            *dst++ = *src++ * Current;
+            tempCurrent[ch] = Current;
+        }
+    }
+    for (ch = 0; ch < NrChannels; ch++)
+    {
+        ptrInstance[ch]->Current = tempCurrent[ch];
+    }
+}
+#endif
 #else
 void LVC_Core_MixSoft_1St_2i_D16C31_WRA( LVMixer3_st        *ptrInstance1,
                                          LVMixer3_st        *ptrInstance2,
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.c b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.c
index b5e7f5c..5bfdad8 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.c
@@ -27,10 +27,10 @@
    FUNCTION LVCore_MIXSOFT_1ST_D16C31_WRA
 ***********************************************************************************/
 #ifdef BUILD_FLOAT
-void LVC_Core_MixSoft_1St_D16C31_WRA( LVMixer3_FLOAT_st *ptrInstance,
-                                    const LVM_FLOAT     *src,
-                                          LVM_FLOAT     *dst,
-                                          LVM_INT16     n)
+void LVC_Core_MixSoft_1St_D16C31_WRA(LVMixer3_FLOAT_st *ptrInstance,
+                                     const LVM_FLOAT   *src,
+                                           LVM_FLOAT   *dst,
+                                           LVM_INT16   n)
 {
     LVM_INT16   OutLoop;
     LVM_INT16   InLoop;
@@ -105,6 +105,119 @@
     }
     pInstance->Current=Current;
 }
+
+
+#ifdef SUPPORT_MC
+/*
+ * FUNCTION:       LVC_Core_MixSoft_Mc_D16C31_WRA
+ *
+ * DESCRIPTION:
+ *  Mixer function with support for processing multichannel input
+ *
+ * PARAMETERS:
+ *  ptrInstance    Instance pointer
+ *  src            Source
+ *  dst            Destination
+ *  NrFrames       Number of frames
+ *  NrChannels     Number of channels
+ *
+ * RETURNS:
+ *  void
+ *
+ */
+void LVC_Core_MixSoft_Mc_D16C31_WRA(LVMixer3_FLOAT_st *ptrInstance,
+                                    const LVM_FLOAT   *src,
+                                          LVM_FLOAT   *dst,
+                                          LVM_INT16   NrFrames,
+                                          LVM_INT16   NrChannels)
+{
+    LVM_INT16   OutLoop;
+    LVM_INT16   InLoop;
+    LVM_INT32   ii, jj;
+    Mix_Private_FLOAT_st  *pInstance=(Mix_Private_FLOAT_st *)(ptrInstance->PrivateParams);
+    LVM_FLOAT   Delta= (LVM_FLOAT)pInstance->Delta;
+    LVM_FLOAT   Current = (LVM_FLOAT)pInstance->Current;
+    LVM_FLOAT   Target= (LVM_FLOAT)pInstance->Target;
+    LVM_FLOAT   Temp;
+
+    /*
+     * Same operation is performed on consecutive frames.
+     * So two frames are processed in one iteration and
+     * the loop will run only for half the NrFrames value times.
+     */
+    InLoop = (LVM_INT16)(NrFrames >> 1);
+    /* OutLoop is calculated to handle cases where NrFrames value can be odd.*/
+    OutLoop = (LVM_INT16)(NrFrames - (InLoop << 1));
+
+    if (Current<Target) {
+        if (OutLoop) {
+
+            Temp = Current + Delta;
+            if (Temp > 1.0f)
+                Temp = 1.0f;
+            else if (Temp < -1.0f)
+                Temp = -1.0f;
+
+            Current=Temp;
+            if (Current > Target)
+                Current = Target;
+
+            for (ii = OutLoop; ii != 0; ii--) {
+                for (jj = NrChannels; jj !=0; jj--) {
+                    *(dst++) = (((LVM_FLOAT)*(src++) * (LVM_FLOAT)Current));
+                }
+            }
+        }
+
+        for (ii = InLoop; ii != 0; ii--) {
+
+            Temp = Current + Delta;
+
+            if (Temp > 1.0f)
+                Temp = 1.0f;
+            else if (Temp < -1.0f)
+                Temp = -1.0f;
+
+            Current=Temp;
+            if (Current > Target)
+                Current = Target;
+
+            for (jj = NrChannels; jj != 0 ; jj--)
+            {
+                *(dst++) = (((LVM_FLOAT)*(src++) * Current));
+                *(dst++) = (((LVM_FLOAT)*(src++) * Current));
+            }
+        }
+    }
+    else{
+        if (OutLoop) {
+            Current -= Delta;
+            if (Current < Target)
+                Current = Target;
+
+            for (ii = OutLoop; ii != 0; ii--) {
+                for (jj = NrChannels; jj !=0; jj--) {
+                    *(dst++) = (((LVM_FLOAT)*(src++) * (LVM_FLOAT)Current));
+                }
+            }
+        }
+
+        for (ii = InLoop; ii != 0; ii--) {
+            Current -= Delta;
+            if (Current < Target)
+                Current = Target;
+
+            for (jj = NrChannels; jj != 0 ; jj--)
+            {
+                *(dst++) = (((LVM_FLOAT)*(src++) * Current));
+                *(dst++) = (((LVM_FLOAT)*(src++) * Current));
+            }
+        }
+    }
+    pInstance->Current=Current;
+}
+#endif
+
 #else
 void LVC_Core_MixSoft_1St_D16C31_WRA( LVMixer3_st *ptrInstance,
                                     const LVM_INT16     *src,
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_MixInSoft_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_MixInSoft_D16C31_SAT.c
index 192f126..65956f7 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_MixInSoft_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_MixInSoft_D16C31_SAT.c
@@ -34,10 +34,10 @@
    FUNCTION MIXINSOFT_D16C31_SAT
 ***********************************************************************************/
 #ifdef BUILD_FLOAT
-void LVC_MixInSoft_D16C31_SAT( LVMixer3_1St_FLOAT_st *ptrInstance,
-                               LVM_FLOAT             *src,
-                               LVM_FLOAT             *dst,
-                               LVM_INT16             n)
+void LVC_MixInSoft_D16C31_SAT(LVMixer3_1St_FLOAT_st *ptrInstance,
+                              const LVM_FLOAT       *src,
+                                    LVM_FLOAT       *dst,
+                                    LVM_INT16       n)
 {
     char        HardMixing = TRUE;
     LVM_FLOAT   TargetGain;
@@ -106,6 +106,110 @@
     }
 
 }
+
+
+
+#ifdef SUPPORT_MC
+/*
+ * FUNCTION:       LVC_MixInSoft_Mc_D16C31_SAT
+ *
+ * DESCRIPTION:
+ *  Mixer function with support for processing multichannel input
+ *
+ * PARAMETERS:
+ *  ptrInstance    Instance pointer
+ *  src            Source
+ *  dst            Destination
+ *  NrFrames       Number of frames
+ *  NrChannels     Number of channels
+ *
+ * RETURNS:
+ *  void
+ *
+ */
+void LVC_MixInSoft_Mc_D16C31_SAT(LVMixer3_1St_FLOAT_st *ptrInstance,
+                                 const LVM_FLOAT       *src,
+                                       LVM_FLOAT       *dst,
+                                       LVM_INT16       NrFrames,
+                                       LVM_INT16       NrChannels)
+{
+    char        HardMixing = TRUE;
+    LVM_FLOAT   TargetGain;
+    Mix_Private_FLOAT_st  *pInstance = \
+                             (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[0].PrivateParams);
+
+    if (NrFrames <= 0)    return;
+
+    /******************************************************************************
+       SOFT MIXING
+    *******************************************************************************/
+    if (pInstance->Current != pInstance->Target)
+    {
+        if (pInstance->Delta == 1.0f) {
+            pInstance->Current = pInstance->Target;
+            TargetGain = pInstance->Target;
+            LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
+        }else if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta) {
+            pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
+                                                       Make them equal. */
+            TargetGain = pInstance->Target;
+            LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
+        }else{
+            /* Soft mixing has to be applied */
+            HardMixing = FALSE;
+            LVC_Core_MixInSoft_Mc_D16C31_SAT(&(ptrInstance->MixerStream[0]),
+                                             src,
+                                             dst,
+                                             NrFrames,
+                                             NrChannels);
+        }
+    }
+
+    /******************************************************************************
+       HARD MIXING
+    *******************************************************************************/
+
+    if (HardMixing) {
+        if (pInstance->Target != 0) { /* Nothing to do in case Target = 0 */
+            if ((pInstance->Target) == 1.0f) {
+                Add2_Sat_Float(src, dst, NrFrames*NrChannels);
+            }
+            else{
+                Mac3s_Sat_Float(src,
+                                (pInstance->Target),
+                                dst,
+                                NrFrames * NrChannels);
+                /* In case the LVCore function would have changed the Current value */
+                pInstance->Current = pInstance->Target;
+            }
+        }
+    }
+
+
+    /******************************************************************************
+       CALL BACK
+    *******************************************************************************/
+
+    if (ptrInstance->MixerStream[0].CallbackSet) {
+        if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta) {
+            pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
+                                                       Make them equal. */
+            TargetGain = pInstance->Target;
+            LVC_Mixer_SetTarget(ptrInstance->MixerStream, TargetGain);
+            ptrInstance->MixerStream[0].CallbackSet = FALSE;
+            if (ptrInstance->MixerStream[0].pCallBack != 0) {
+                (*ptrInstance->MixerStream[0].pCallBack) (\
+                                                ptrInstance->MixerStream[0].pCallbackHandle,
+                                                ptrInstance->MixerStream[0].pGeneralPurpose,
+                                                ptrInstance->MixerStream[0].CallbackParam);
+            }
+        }
+    }
+
+}
+#endif
+
+
 #else
 void LVC_MixInSoft_D16C31_SAT( LVMixer3_1St_st *ptrInstance,
                                     LVM_INT16             *src,
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.c
index bd5a925..a4682d3 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.c
@@ -19,6 +19,8 @@
    INCLUDE FILES
 ***********************************************************************************/
 
+#include <system/audio.h>
+
 #include "LVC_Mixer_Private.h"
 #include "VectorArithmetic.h"
 #include "ScalarArithmetic.h"
@@ -30,10 +32,207 @@
 #define TRUE          1
 #define FALSE         0
 
+#define ARRAY_SIZE(a) ((sizeof(a)) / (sizeof(*(a))))
+
 /**********************************************************************************
    FUNCTION LVC_MixSoft_1St_2i_D16C31_SAT
 ***********************************************************************************/
 #ifdef BUILD_FLOAT
+#ifdef SUPPORT_MC
+/* This threshold is used to decide on the processing to be applied on
+ * front center and back center channels
+ */
+#define LVM_VOL_BAL_THR (0.000016f)
+void LVC_MixSoft_1St_MC_float_SAT (LVMixer3_2St_FLOAT_st *ptrInstance,
+                                    const LVM_FLOAT       *src,
+                                    LVM_FLOAT             *dst,
+                                    LVM_INT16             NrFrames,
+                                    LVM_INT32             NrChannels,
+                                    LVM_INT32             ChMask)
+{
+    char        HardMixing = TRUE;
+    LVM_FLOAT   TargetGain;
+    Mix_Private_FLOAT_st  Target_lfe = {LVM_MAXFLOAT, LVM_MAXFLOAT, LVM_MAXFLOAT};
+    Mix_Private_FLOAT_st  Target_ctr = {LVM_MAXFLOAT, LVM_MAXFLOAT, LVM_MAXFLOAT};
+    Mix_Private_FLOAT_st  *pInstance1 = \
+                              (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[0].PrivateParams);
+    Mix_Private_FLOAT_st  *pInstance2 = \
+                              (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[1].PrivateParams);
+    Mix_Private_FLOAT_st  *pMixPrivInst[4] = {pInstance1, pInstance2, &Target_ctr, &Target_lfe};
+    Mix_Private_FLOAT_st  *pInstance[NrChannels];
+
+    if (audio_channel_mask_get_representation(ChMask)
+            == AUDIO_CHANNEL_REPRESENTATION_INDEX)
+    {
+        for (int i = 0; i < 2; i++)
+        {
+            pInstance[i] = pMixPrivInst[i];
+        }
+        for (int i = 2; i < NrChannels; i++)
+        {
+            pInstance[i] = pMixPrivInst[2];
+        }
+    }
+    else
+    {
+        // TODO: Combine with system/media/audio_utils/Balance.cpp
+        // Constants in system/media/audio/include/system/audio-base.h
+        // 'mixInstIdx' is used to map the appropriate mixer instance for each channel.
+        const int mixInstIdx[] = {
+            0, // AUDIO_CHANNEL_OUT_FRONT_LEFT            = 0x1u,
+            1, // AUDIO_CHANNEL_OUT_FRONT_RIGHT           = 0x2u,
+            2, // AUDIO_CHANNEL_OUT_FRONT_CENTER          = 0x4u,
+            3, // AUDIO_CHANNEL_OUT_LOW_FREQUENCY         = 0x8u,
+            0, // AUDIO_CHANNEL_OUT_BACK_LEFT             = 0x10u,
+            1, // AUDIO_CHANNEL_OUT_BACK_RIGHT            = 0x20u,
+            0, // AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER  = 0x40u,
+            1, // AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = 0x80u,
+            2, // AUDIO_CHANNEL_OUT_BACK_CENTER           = 0x100u,
+            0, // AUDIO_CHANNEL_OUT_SIDE_LEFT             = 0x200u,
+            1, // AUDIO_CHANNEL_OUT_SIDE_RIGHT            = 0x400u,
+            2, // AUDIO_CHANNEL_OUT_TOP_CENTER            = 0x800u,
+            0, // AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT        = 0x1000u,
+            2, // AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER      = 0x2000u,
+            1, // AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT       = 0x4000u,
+            0, // AUDIO_CHANNEL_OUT_TOP_BACK_LEFT         = 0x8000u,
+            2, // AUDIO_CHANNEL_OUT_TOP_BACK_CENTER       = 0x10000u,
+            1, // AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT        = 0x20000u,
+            0, // AUDIO_CHANNEL_OUT_TOP_SIDE_LEFT         = 0x40000u,
+            1, // AUDIO_CHANNEL_OUT_TOP_SIDE_RIGHT        = 0x80000u
+        };
+        if (pInstance1->Target <= LVM_VOL_BAL_THR ||
+            pInstance2->Target <= LVM_VOL_BAL_THR)
+        {
+            Target_ctr.Target  = 0.0f;
+            Target_ctr.Current = 0.0f;
+            Target_ctr.Delta   = 0.0f;
+        }
+        const unsigned int idxArrSize = ARRAY_SIZE(mixInstIdx);
+        for (unsigned int i = 0, channel = ChMask; channel !=0 ; ++i)
+        {
+            const unsigned int idx = __builtin_ctz(channel);
+            if (idx < idxArrSize)
+            {
+                pInstance[i] = pMixPrivInst[mixInstIdx[idx]];
+            }
+            else
+            {
+                pInstance[i] = pMixPrivInst[2];
+            }
+            channel &= ~(1 << idx);
+        }
+    }
+
+    if (NrFrames <= 0)    return;
+
+    /******************************************************************************
+       SOFT MIXING
+    *******************************************************************************/
+
+    if ((pInstance1->Current != pInstance1->Target) ||
+        (pInstance2->Current != pInstance2->Target))
+    {
+        // TODO: combine similar checks below.
+        if (pInstance1->Delta == LVM_MAXFLOAT
+                || Abs_Float(pInstance1->Current - pInstance1->Target) < pInstance1->Delta)
+        {
+            /* Difference is not significant anymore. Make them equal. */
+            pInstance1->Current = pInstance1->Target;
+            TargetGain = pInstance1->Target;
+            LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
+        }
+        else
+        {
+            /* Soft mixing has to be applied */
+            HardMixing = FALSE;
+        }
+
+        if (HardMixing == TRUE)
+        {
+            if (pInstance2->Delta == LVM_MAXFLOAT
+                    || Abs_Float(pInstance2->Current - pInstance2->Target) < pInstance2->Delta)
+            {
+                /* Difference is not significant anymore. Make them equal. */
+                pInstance2->Current = pInstance2->Target;
+                TargetGain = pInstance2->Target;
+                LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[1]), TargetGain);
+            }
+            else
+            {
+                /* Soft mixing has to be applied */
+                HardMixing = FALSE;
+            }
+        }
+
+        if (HardMixing == FALSE)
+        {
+             LVC_Core_MixSoft_1St_MC_float_WRA (&pInstance[0],
+                                                 src, dst, NrFrames, NrChannels);
+        }
+    }
+
+    /******************************************************************************
+       HARD MIXING
+    *******************************************************************************/
+
+    if (HardMixing == TRUE)
+    {
+        if ((pInstance1->Target == LVM_MAXFLOAT) && (pInstance2->Target == LVM_MAXFLOAT))
+        {
+            if (src != dst)
+            {
+                Copy_Float(src, dst, NrFrames*NrChannels);
+            }
+        }
+        else
+        {
+            LVC_Core_MixHard_1St_MC_float_SAT(&(pInstance[0]),
+                                               src, dst, NrFrames, NrChannels);
+        }
+    }
+
+    /******************************************************************************
+       CALL BACK
+    *******************************************************************************/
+
+    if (ptrInstance->MixerStream[0].CallbackSet)
+    {
+        if (Abs_Float(pInstance1->Current - pInstance1->Target) < pInstance1->Delta)
+        {
+            pInstance1->Current = pInstance1->Target; /* Difference is not significant anymore. \
+                                                         Make them equal. */
+            TargetGain = pInstance1->Target;
+            LVC_Mixer_SetTarget(&ptrInstance->MixerStream[0], TargetGain);
+            ptrInstance->MixerStream[0].CallbackSet = FALSE;
+            if (ptrInstance->MixerStream[0].pCallBack != 0)
+            {
+                (*ptrInstance->MixerStream[0].pCallBack) (\
+                    ptrInstance->MixerStream[0].pCallbackHandle,
+                    ptrInstance->MixerStream[0].pGeneralPurpose,
+                    ptrInstance->MixerStream[0].CallbackParam);
+            }
+        }
+    }
+    if (ptrInstance->MixerStream[1].CallbackSet)
+    {
+        if (Abs_Float(pInstance2->Current - pInstance2->Target) < pInstance2->Delta)
+        {
+            pInstance2->Current = pInstance2->Target; /* Difference is not significant anymore.
+                                                         Make them equal. */
+            TargetGain = pInstance2->Target;
+            LVC_Mixer_SetTarget(&ptrInstance->MixerStream[1], TargetGain);
+            ptrInstance->MixerStream[1].CallbackSet = FALSE;
+            if (ptrInstance->MixerStream[1].pCallBack != 0)
+            {
+                (*ptrInstance->MixerStream[1].pCallBack) (\
+                    ptrInstance->MixerStream[1].pCallbackHandle,
+                    ptrInstance->MixerStream[1].pGeneralPurpose,
+                    ptrInstance->MixerStream[1].CallbackParam);
+            }
+        }
+    }
+}
+#endif
 void LVC_MixSoft_1St_2i_D16C31_SAT( LVMixer3_2St_FLOAT_st *ptrInstance,
                                     const LVM_FLOAT             *src,
                                     LVM_FLOAT             *dst,
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_D16C31_SAT.c
index 1017de3..0678ae0 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_D16C31_SAT.c
@@ -103,6 +103,101 @@
         }
     }
 }
+#ifdef SUPPORT_MC
+/*
+ * FUNCTION:       LVC_MixSoft_Mc_D16C31_SAT
+ *
+ * DESCRIPTION:
+ *  Mixer function with support for processing multichannel input
+ *
+ * PARAMETERS:
+ *  ptrInstance    Instance pointer
+ *  src            Source
+ *  dst            Destination
+ *  NrFrames       Number of Frames
+ *  NrChannels     Number of channels
+ *
+ * RETURNS:
+ *  void
+ *
+ */
+void LVC_MixSoft_Mc_D16C31_SAT(LVMixer3_1St_FLOAT_st *ptrInstance,
+                                  const LVM_FLOAT      *src,
+                                        LVM_FLOAT      *dst,
+                                        LVM_INT16      NrFrames,
+                                        LVM_INT16      NrChannels)
+{
+    char        HardMixing = TRUE;
+    LVM_FLOAT   TargetGain;
+    Mix_Private_FLOAT_st  *pInstance = \
+                          (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[0].PrivateParams);
+
+    if (NrFrames <= 0)    return;
+
+    /******************************************************************************
+       SOFT MIXING
+    *******************************************************************************/
+    if (pInstance->Current != pInstance->Target)
+    {
+        if (pInstance->Delta == 1.0f) {
+            pInstance->Current = pInstance->Target;
+            TargetGain = pInstance->Target;
+            LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
+        }else if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta) {
+            pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
+                                                       Make them equal. */
+            TargetGain = pInstance->Target;
+            LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
+        }else{
+            /* Soft mixing has to be applied */
+            HardMixing = FALSE;
+            LVC_Core_MixSoft_Mc_D16C31_WRA(&(ptrInstance->MixerStream[0]),
+                                           src,
+                                           dst,
+                                           NrFrames,
+                                           NrChannels);
+        }
+    }
+
+    /******************************************************************************
+       HARD MIXING
+    *******************************************************************************/
+
+    if (HardMixing) {
+        if (pInstance->Target == 0)
+            LoadConst_Float(0.0, dst, NrFrames * NrChannels);
+        else {
+            if ((pInstance->Target) != 1.0f)
+                Mult3s_Float(src, (pInstance->Target), dst, NrFrames * NrChannels);
+            else if (src != dst)
+                Copy_Float(src, dst, NrFrames * NrChannels);
+        }
+
+    }
+
+    /******************************************************************************
+       CALL BACK
+    *******************************************************************************/
+
+    if (ptrInstance->MixerStream[0].CallbackSet) {
+        if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta) {
+            pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
+                                                       Make them equal. */
+            TargetGain = pInstance->Target;
+            LVC_Mixer_SetTarget(ptrInstance->MixerStream, TargetGain);
+            ptrInstance->MixerStream[0].CallbackSet = FALSE;
+            if (ptrInstance->MixerStream[0].pCallBack != 0) {
+                (*ptrInstance->MixerStream[0].pCallBack) (\
+                                                ptrInstance->MixerStream[0].pCallbackHandle,
+                                                ptrInstance->MixerStream[0].pGeneralPurpose,
+                                                ptrInstance->MixerStream[0].CallbackParam);
+            }
+        }
+    }
+}
+
+#endif
+
 #else
 void LVC_MixSoft_1St_D16C31_SAT( LVMixer3_1St_st *ptrInstance,
                                   const LVM_INT16             *src,
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_2St_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_2St_D16C31_SAT.c
index 3c90071..8a89de1 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_2St_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_2St_D16C31_SAT.c
@@ -26,11 +26,11 @@
    FUNCTION LVC_MixSoft_2St_D16C31_SAT.c
 ***********************************************************************************/
 #ifdef BUILD_FLOAT
-void LVC_MixSoft_2St_D16C31_SAT( LVMixer3_2St_FLOAT_st *ptrInstance,
-                                 const   LVM_FLOAT       *src1,
-                                 LVM_FLOAT       *src2,
-                                 LVM_FLOAT       *dst,
-                                 LVM_INT16       n)
+void LVC_MixSoft_2St_D16C31_SAT(LVMixer3_2St_FLOAT_st *ptrInstance,
+                                const LVM_FLOAT       *src1,
+                                const LVM_FLOAT       *src2,
+                                      LVM_FLOAT       *dst,
+                                      LVM_INT16       n)
 {
     Mix_Private_FLOAT_st  *pInstance1 = \
                              (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[0].PrivateParams);
@@ -67,6 +67,70 @@
                                          src1, src2, dst, n);
     }
 }
+
+#ifdef SUPPORT_MC
+/*
+ * FUNCTION:       LVC_MixSoft_2Mc_D16C31_SAT
+ *
+ * DESCRIPTION:
+ *  2 stream Mixer function with support for processing multichannel input
+ *
+ * PARAMETERS:
+ *  ptrInstance    Instance pointer
+ *  src1           First multichannel source
+ *  src2           Second multichannel source
+ *  dst            Destination
+ *  NrFrames       Number of frames
+ *  NrChannels     Number of channels
+ *
+ * RETURNS:
+ *  void
+ *
+ */
+void LVC_MixSoft_2Mc_D16C31_SAT(LVMixer3_2St_FLOAT_st *ptrInstance,
+                                const LVM_FLOAT       *src1,
+                                const LVM_FLOAT       *src2,
+                                      LVM_FLOAT       *dst,
+                                      LVM_INT16       NrFrames,
+                                      LVM_INT16       NrChannels)
+{
+    Mix_Private_FLOAT_st  *pInstance1 = \
+                             (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[0].PrivateParams);
+    Mix_Private_FLOAT_st  *pInstance2 = \
+                             (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[1].PrivateParams);
+
+    if (NrFrames <= 0)    return;
+
+    /******************************************************************************
+       SOFT MIXING
+    *******************************************************************************/
+    if ((pInstance1->Current == pInstance1->Target) && (pInstance1->Current == 0)) {
+        LVC_MixSoft_Mc_D16C31_SAT((LVMixer3_1St_FLOAT_st *)(&ptrInstance->MixerStream[1]),
+                                    src2, dst, NrFrames, NrChannels);
+    }
+    else if ((pInstance2->Current == pInstance2->Target) && (pInstance2->Current == 0)) {
+        LVC_MixSoft_Mc_D16C31_SAT((LVMixer3_1St_FLOAT_st *)(&ptrInstance->MixerStream[0]),
+                                    src1, dst, NrFrames, NrChannels);
+    }
+    else if ((pInstance1->Current != pInstance1->Target) || \
+                                    (pInstance2->Current != pInstance2->Target))
+    {
+        LVC_MixSoft_Mc_D16C31_SAT((LVMixer3_1St_FLOAT_st *)(&ptrInstance->MixerStream[0]),
+                                   src1, dst, NrFrames, NrChannels);
+        LVC_MixInSoft_Mc_D16C31_SAT((LVMixer3_1St_FLOAT_st *)(&ptrInstance->MixerStream[1]),
+                                   src2, dst, NrFrames, NrChannels);
+    }
+    else{
+        /******************************************************************************
+           HARD MIXING
+        *******************************************************************************/
+        LVC_Core_MixHard_2St_D16C31_SAT(&ptrInstance->MixerStream[0],
+                                        &ptrInstance->MixerStream[1],
+                                        src1, src2, dst, NrFrames * NrChannels);
+    }
+}
+#endif
+
 #else
 void LVC_MixSoft_2St_D16C31_SAT( LVMixer3_2St_st *ptrInstance,
                                     const   LVM_INT16       *src1,
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h b/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h
index f904915..199d529 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h
@@ -157,10 +157,18 @@
 /*** 16 bit functions *************************************************************/
 
 #ifdef BUILD_FLOAT
-void LVC_MixSoft_1St_D16C31_SAT( LVMixer3_1St_FLOAT_st *pInstance,
-                                 const LVM_FLOAT           *src,
-                                 LVM_FLOAT           *dst,
-                                 LVM_INT16           n);
+void LVC_MixSoft_1St_D16C31_SAT(LVMixer3_1St_FLOAT_st *pInstance,
+                                const LVM_FLOAT       *src,
+                                      LVM_FLOAT       *dst,
+                                      LVM_INT16       n);
+#ifdef SUPPORT_MC
+void LVC_MixSoft_Mc_D16C31_SAT(LVMixer3_1St_FLOAT_st *pInstance,
+                               const LVM_FLOAT       *src,
+                                     LVM_FLOAT       *dst,
+                                     LVM_INT16       NrFrames,
+                                     LVM_INT16       NrChannels);
+#endif
+
 #else
 void LVC_MixSoft_1St_D16C31_SAT( LVMixer3_1St_st *pInstance,
                                   const LVM_INT16           *src,
@@ -169,10 +177,18 @@
 #endif
 
 #ifdef BUILD_FLOAT
-void LVC_MixInSoft_D16C31_SAT( LVMixer3_1St_FLOAT_st *pInstance,
-                               LVM_FLOAT           *src,
-                               LVM_FLOAT           *dst,
-                               LVM_INT16           n);
+void LVC_MixInSoft_D16C31_SAT(LVMixer3_1St_FLOAT_st *pInstance,
+                              const LVM_FLOAT       *src,
+                                    LVM_FLOAT       *dst,
+                                    LVM_INT16       n);
+#ifdef SUPPORT_MC
+void LVC_MixInSoft_Mc_D16C31_SAT(LVMixer3_1St_FLOAT_st *pInstance,
+                                 const LVM_FLOAT       *src,
+                                       LVM_FLOAT       *dst,
+                                       LVM_INT16       NrFrames,
+                                       LVM_INT16       NrChannels);
+#endif
+
 #else
 void LVC_MixInSoft_D16C31_SAT( LVMixer3_1St_st *pInstance,
                                         LVM_INT16           *src,
@@ -181,11 +197,19 @@
 #endif
 
 #ifdef BUILD_FLOAT
-void LVC_MixSoft_2St_D16C31_SAT( LVMixer3_2St_FLOAT_st *pInstance,
-                                 const LVM_FLOAT             *src1,
-                                 LVM_FLOAT             *src2,
-                                 LVM_FLOAT             *dst,  /* dst cannot be equal to src2 */
-                                 LVM_INT16             n);
+void LVC_MixSoft_2St_D16C31_SAT(LVMixer3_2St_FLOAT_st *pInstance,
+                                const LVM_FLOAT       *src1,
+                                const LVM_FLOAT       *src2,
+                                LVM_FLOAT             *dst,  /* dst cannot be equal to src2 */
+                                LVM_INT16             n);
+#ifdef SUPPORT_MC
+void LVC_MixSoft_2Mc_D16C31_SAT(LVMixer3_2St_FLOAT_st *pInstance,
+                                const LVM_FLOAT       *src1,
+                                const LVM_FLOAT       *src2,
+                                LVM_FLOAT             *dst,  /* dst cannot be equal to src2 */
+                                LVM_INT16             NrFrames,
+                                LVM_INT16             NrChannels);
+#endif
 #else
 void LVC_MixSoft_2St_D16C31_SAT( LVMixer3_2St_st *pInstance,
                                 const LVM_INT16             *src1,
@@ -200,10 +224,18 @@
 /* Gain values should not be more that 1.0                                        */
 /**********************************************************************************/
 #ifdef BUILD_FLOAT
-void LVC_MixSoft_1St_2i_D16C31_SAT( LVMixer3_2St_FLOAT_st         *pInstance,
-                                    const   LVM_FLOAT           *src,
-                                    LVM_FLOAT           *dst,   /* dst can be equal to src */
-                                    LVM_INT16           n);     /* Number of stereo samples */
+#ifdef SUPPORT_MC
+void LVC_MixSoft_1St_MC_float_SAT(LVMixer3_2St_FLOAT_st *pInstance,
+                                   const   LVM_FLOAT     *src,
+                                   LVM_FLOAT             *dst,   /* dst can be equal to src */
+                                   LVM_INT16             NrFrames,
+                                   LVM_INT32             NrChannels,
+                                   LVM_INT32             ChMask);
+#endif
+void LVC_MixSoft_1St_2i_D16C31_SAT(LVMixer3_2St_FLOAT_st *pInstance,
+                                   const   LVM_FLOAT     *src,
+                                   LVM_FLOAT             *dst,   /* dst can be equal to src */
+                                   LVM_INT16             n);     /* Number of stereo samples */
 #else
 void LVC_MixSoft_1St_2i_D16C31_SAT( LVMixer3_2St_st         *pInstance,
                                 const   LVM_INT16           *src,
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetTarget.c b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetTarget.c
index c67455a..507eefa 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetTarget.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetTarget.c
@@ -35,7 +35,7 @@
 {
     LVM_FLOAT       TargetGain;
     Mix_Private_FLOAT_st  *pInstance = (Mix_Private_FLOAT_st *)pStream->PrivateParams;
-    
+
     TargetGain = pInstance->Target;  // TargetGain
     return TargetGain;
 }
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h
index d0d0e1f..453a6a5 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h
@@ -62,6 +62,13 @@
                                     const LVM_FLOAT     *src,
                                     LVM_FLOAT     *dst,
                                     LVM_INT16     n);
+#ifdef SUPPORT_MC
+void LVC_Core_MixInSoft_Mc_D16C31_SAT(LVMixer3_FLOAT_st *ptrInstance,
+                                    const LVM_FLOAT     *src,
+                                          LVM_FLOAT     *dst,
+                                          LVM_INT16     NrFrames,
+                                          LVM_INT16     NrChannels);
+#endif
 #else
 void LVC_Core_MixInSoft_D16C31_SAT( LVMixer3_st *pInstance,
                                     const LVM_INT16     *src,
@@ -73,6 +80,13 @@
                                       const LVM_FLOAT     *src,
                                       LVM_FLOAT     *dst,
                                       LVM_INT16     n);
+#ifdef SUPPORT_MC
+void LVC_Core_MixSoft_Mc_D16C31_WRA(LVMixer3_FLOAT_st *ptrInstance,
+                                    const LVM_FLOAT     *src,
+                                          LVM_FLOAT     *dst,
+                                          LVM_INT16     NrFrames,
+                                          LVM_INT16     NrChannels);
+#endif
 #else
 void LVC_Core_MixSoft_1St_D16C31_WRA( LVMixer3_st *pInstance,
                                     const LVM_INT16     *src,
@@ -102,6 +116,13 @@
 /* Gain values should not be more that 1.0                                        */
 /**********************************************************************************/
 #ifdef BUILD_FLOAT
+#ifdef SUPPORT_MC
+void LVC_Core_MixSoft_1St_MC_float_WRA(Mix_Private_FLOAT_st **ptrInstance,
+                                         const LVM_FLOAT      *src,
+                                         LVM_FLOAT            *dst,
+                                         LVM_INT16            NrFrames,
+                                         LVM_INT16            NrChannels);
+#endif
 void LVC_Core_MixSoft_1St_2i_D16C31_WRA( LVMixer3_FLOAT_st        *ptrInstance1,
                                          LVMixer3_FLOAT_st        *ptrInstance2,
                                          const LVM_FLOAT    *src,
@@ -122,6 +143,13 @@
 /* Gain values should not be more that 1.0                                        */
 /**********************************************************************************/
 #ifdef BUILD_FLOAT
+#ifdef SUPPORT_MC
+void LVC_Core_MixHard_1St_MC_float_SAT(Mix_Private_FLOAT_st **ptrInstance,
+                                         const LVM_FLOAT      *src,
+                                         LVM_FLOAT            *dst,
+                                         LVM_INT16            NrFrames,
+                                         LVM_INT16            NrChannels);
+#endif
 void LVC_Core_MixHard_1St_2i_D16C31_SAT( LVMixer3_FLOAT_st        *ptrInstance1,
                                          LVMixer3_FLOAT_st        *ptrInstance2,
                                          const LVM_FLOAT    *src,
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTimeConstant.c b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTimeConstant.c
index 48f5d54..9d3ee88 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTimeConstant.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTimeConstant.c
@@ -51,7 +51,7 @@
                                LVM_INT16           NumChannels)
 {
 #ifdef HIGHER_FS
-    LVM_FLOAT   DeltaTable[11] = {0.500000f,/*8000*/
+    LVM_FLOAT   DeltaTable[13] = {0.500000f,/*8000*/
                                   0.362812f,/*11025*/
                                   0.333333f,/*12000*/
                                   0.250000f,/*16000*/
@@ -60,7 +60,9 @@
                                   0.125000f,/*32000*/
                                   0.090703f,/*44100*/
                                   0.083333f,/*48000*/
+                                  0.045352f,/*88200*/
                                   0.041667f,/*96000*/
+                                  0.022676f,/*176400*/
                                   0.020833f};/*192000*/
 #else
     LVM_FLOAT   DeltaTable[9] = {0.500000f,/*8000*/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_VarSlope_SetTimeConstant.c b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_VarSlope_SetTimeConstant.c
index 9dc7d21..0e0acf1 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_VarSlope_SetTimeConstant.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_VarSlope_SetTimeConstant.c
@@ -52,7 +52,7 @@
                                          LVM_INT16           NumChannels)
 {
 #ifdef HIGHER_FS
-     LVM_FLOAT   DeltaTable[11] = {0.500000f,/*8000*/
+     LVM_FLOAT   DeltaTable[13] = {0.500000f,/*8000*/
                                    0.362812f,/*11025*/
                                    0.333333f,/*12000*/
                                    0.250000f,/*16000*/
@@ -61,7 +61,9 @@
                                    0.125000f,/*32000*/
                                    0.090703f,/*44100*/
                                    0.083333f,/*48000*/
+                                   0.045352f,/*88200*/
                                    0.041666f,/*96000*/
+                                   0.022676f,/*176400*/
                                    0.020833f};/*192000*/
 #else
     LVM_FLOAT   DeltaTable[9] = {0.500000f,/*8000*/
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_GetOmega.c b/media/libeffects/lvm/lib/Common/src/LVM_GetOmega.c
index 7846ca0..6307e68 100644
--- a/media/libeffects/lvm/lib/Common/src/LVM_GetOmega.c
+++ b/media/libeffects/lvm/lib/Common/src/LVM_GetOmega.c
@@ -53,7 +53,9 @@
 #define LVVDL_2PiBy_48000_f       0.000130900f
 
 #ifdef HIGHER_FS
+#define LVVDL_2PiBy_88200_f       0.000071238f
 #define LVVDL_2PiBy_96000_f       0.000065450f
+#define LVVDL_2PiBy_176400_f      0.000035619f
 #define LVVDL_2PiBy_192000_f      0.000032725f
 #endif
 const LVM_FLOAT     LVVDL_2PiOnFsTable[] =  {LVVDL_2PiBy_8000_f,
@@ -66,7 +68,9 @@
                                              LVVDL_2PiBy_44100_f,
                                              LVVDL_2PiBy_48000_f
 #ifdef HIGHER_FS
+                                            ,LVVDL_2PiBy_88200_f
                                             ,LVVDL_2PiBy_96000_f
+                                            ,LVVDL_2PiBy_176400_f
                                             ,LVVDL_2PiBy_192000_f
 #endif
                                            };
diff --git a/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.c b/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.c
index e3fb40d..17fd833 100644
--- a/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.c
+++ b/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.c
@@ -50,11 +50,11 @@
         {
             if(temp<0)
             {
-                dOutVal=0x80000000l;
+                dOutVal=0x80000000L;
             }
             else
             {
-                dOutVal=0x7FFFFFFFl;
+                dOutVal=0x7FFFFFFFL;
             }
         }
 
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.c
index 9c17a05..6c8b2db 100644
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.c
@@ -119,6 +119,80 @@
         }
 
     }
+
+#ifdef SUPPORT_MC
+/**************************************************************************
+DELAYS-
+pBiquadState->pDelays[0] to
+pBiquadState->pDelays[NrChannels - 1] is x(n-1) for all NrChannels
+
+pBiquadState->pDelays[NrChannels] to
+pBiquadState->pDelays[2*NrChannels - 1] is x(n-2) for all NrChannels
+
+pBiquadState->pDelays[2*NrChannels] to
+pBiquadState->pDelays[3*NrChannels - 1] is y(n-1) for all NrChannels
+
+pBiquadState->pDelays[3*NrChannels] to
+pBiquadState->pDelays[4*NrChannels - 1] is y(n-2) for all NrChannels
+***************************************************************************/
+
+void PK_Mc_D32F32C14G11_TRC_WRA_01 (Biquad_FLOAT_Instance_t       *pInstance,
+                                    LVM_FLOAT               *pDataIn,
+                                    LVM_FLOAT               *pDataOut,
+                                    LVM_INT16               NrFrames,
+                                    LVM_INT16               NrChannels)
+    {
+        LVM_FLOAT yn, ynO, temp;
+        LVM_INT16 ii, jj;
+        PFilter_State_Float pBiquadState = (PFilter_State_Float) pInstance;
+
+         for (ii = NrFrames; ii != 0; ii--)
+         {
+
+            for (jj = 0; jj < NrChannels; jj++)
+            {
+                /**************************************************************************
+                                PROCESSING OF THE jj CHANNEL
+                ***************************************************************************/
+                /* yn= (A0  * (x(n) - x(n-2)))*/
+                temp = (*pDataIn) - pBiquadState->pDelays[NrChannels + jj];
+                yn = temp * pBiquadState->coefs[0];
+
+                /* yn+= ((-B2  * y(n-2))) */
+                temp = pBiquadState->pDelays[NrChannels*3 + jj] * pBiquadState->coefs[1];
+                yn += temp;
+
+                /* yn+= ((-B1 * y(n-1))) */
+                temp = pBiquadState->pDelays[NrChannels*2 + jj] * pBiquadState->coefs[2];
+                yn += temp;
+
+                /* ynO= ((Gain * yn)) */
+                ynO = yn * pBiquadState->coefs[3];
+
+                /* ynO=(ynO + x(n))*/
+                ynO += (*pDataIn);
+
+                /**************************************************************************
+                                UPDATING THE DELAYS
+                ***************************************************************************/
+                pBiquadState->pDelays[NrChannels * 3 + jj] =
+                    pBiquadState->pDelays[NrChannels * 2 + jj]; /* y(n-2)=y(n-1)*/
+                pBiquadState->pDelays[NrChannels * 1 + jj] =
+                    pBiquadState->pDelays[jj]; /* x(n-2)=x(n-1)*/
+                pBiquadState->pDelays[NrChannels * 2 + jj] = yn; /* Update y(n-1) */
+                pBiquadState->pDelays[jj] = (*pDataIn); /* Update x(n-1)*/
+                pDataIn++;
+
+                /**************************************************************************
+                                WRITING THE OUTPUT
+                ***************************************************************************/
+                *pDataOut = ynO; /* Write output*/
+                pDataOut++;
+            }
+        }
+
+    }
+#endif
 #else
 void PK_2I_D32F32C14G11_TRC_WRA_01 ( Biquad_Instance_t       *pInstance,
                                      LVM_INT32               *pDataIn,
diff --git a/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h b/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h
index 8e0b738..804f1bf 100644
--- a/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h
+++ b/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h
@@ -184,6 +184,9 @@
 {
     LVEQNB_STEREO       = 0,
     LVEQNB_MONOINSTEREO = 1,
+#ifdef SUPPORT_MC
+    LVEQNB_MULTICHANNEL = 2,
+#endif
     LVEQNB_SOURCE_MAX   = LVM_MAXINT_32
 } LVEQNB_SourceFormat_en;
 
@@ -201,8 +204,10 @@
 #define LVEQNB_CAP_FS_44100                128
 #define LVEQNB_CAP_FS_48000                256
 #if defined(BUILD_FLOAT) && defined(HIGHER_FS)
-#define LVEQNB_CAP_FS_96000                512
-#define LVEQNB_CAP_FS_192000               1024
+#define LVEQNB_CAP_FS_88200                512
+#define LVEQNB_CAP_FS_96000                1024
+#define LVEQNB_CAP_FS_176400               2048
+#define LVEQNB_CAP_FS_192000               4096
 #endif
 
 typedef enum
@@ -217,8 +222,10 @@
     LVEQNB_FS_44100 = 7,
     LVEQNB_FS_48000 = 8,
 #ifdef HIGHER_FS
-    LVEQNB_FS_96000 = 9,
-    LVEQNB_FS_192000 = 10,
+    LVEQNB_FS_88200 = 9,
+    LVEQNB_FS_96000 = 10,
+    LVEQNB_FS_176400 = 11,
+    LVEQNB_FS_192000 = 12,
 #endif
     LVEQNB_FS_MAX   = LVM_MAXINT_32
 } LVEQNB_Fs_en;
@@ -267,7 +274,9 @@
     /* Equaliser parameters */
     LVM_UINT16                  NBands;                 /* Number of bands */
     LVEQNB_BandDef_t            *pBandDefinition;       /* Pointer to equaliser definitions */
-
+#ifdef SUPPORT_MC
+    LVM_INT16                   NrChannels;
+#endif
 } LVEQNB_Params_t;
 
 
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Coeffs.h b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Coeffs.h
index 42ea46f..755141e 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Coeffs.h
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Coeffs.h
@@ -109,7 +109,9 @@
 #define LVEQNB_2PiOn_48000                               0.000131f
 
 #ifdef HIGHER_FS
+#define LVEQNB_2PiOn_88200                               0.000071f
 #define LVEQNB_2PiOn_96000                               0.000065f
+#define LVEQNB_2PiOn_176400                              0.000036f
 #define LVEQNB_2PiOn_192000                              0.000033f
 #endif
 
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h
index 56b02e0..a9cd5fd 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h
@@ -46,7 +46,12 @@
 #define LVEQNB_INSTANCE_ALIGN       4                   /* 32-bit alignment for instance structures */
 #define LVEQNB_DATA_ALIGN           4                   /* 32-bit alignment for structures */
 #define LVEQNB_COEF_ALIGN           4                   /* 32-bit alignment for long words */
+#ifdef SUPPORT_MC
+/* Number of buffers required for inplace processing */
+#define LVEQNB_SCRATCHBUFFERS       (LVM_MAX_CHANNELS * 2)
+#else
 #define LVEQNB_SCRATCHBUFFERS       4                   /* Number of buffers required for inplace processing */
+#endif
 #define LVEQNB_SCRATCH_ALIGN        4                   /* 32-bit alignment for long data */
 
 #define LVEQNB_BYPASS_MIXER_TC      100                 /* Bypass Mixer TC */
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.c b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.c
index 6328181..d188c0e 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.c
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.c
@@ -26,6 +26,7 @@
 #include "VectorArithmetic.h"
 #include "BIQUAD.h"
 
+#include <log/log.h>
 
 /****************************************************************************************/
 /*                                                                                      */
@@ -61,14 +62,18 @@
 LVEQNB_ReturnStatus_en LVEQNB_Process(LVEQNB_Handle_t       hInstance,
                                       const LVM_FLOAT       *pInData,
                                       LVM_FLOAT             *pOutData,
-                                      LVM_UINT16            NumSamples)
-{
-
-    LVM_UINT16          i;
-    Biquad_FLOAT_Instance_t   *pBiquad;
+                                      const LVM_UINT16      NrFrames)
+{                                     // updated to use samples = frames * channels.
     LVEQNB_Instance_t   *pInstance = (LVEQNB_Instance_t  *)hInstance;
-    LVM_FLOAT           *pScratch;
 
+#ifdef SUPPORT_MC
+    // Mono passed in as stereo
+    const LVM_INT32 NrChannels = pInstance->Params.NrChannels == 1
+        ? 2 : pInstance->Params.NrChannels;
+#else
+    const LVM_INT32 NrChannels = 2; // FCC_2
+#endif
+    const LVM_INT32 NrSamples = NrChannels * NrFrames;
 
      /* Check for NULL pointers */
     if((hInstance == LVM_NULL) || (pInData == LVM_NULL) || (pOutData == LVM_NULL))
@@ -82,14 +87,14 @@
         return LVEQNB_ALIGNMENTERROR;
     }
 
-    pScratch  = (LVM_FLOAT *)pInstance->pFastTemporary;
+    LVM_FLOAT * const pScratch = (LVM_FLOAT *)pInstance->pFastTemporary;
 
     /*
-    * Check the number of samples is not too large
+    * Check the number of frames is not too large
     */
-    if (NumSamples > pInstance->Capabilities.MaxBlockSize)
+    if (NrFrames > pInstance->Capabilities.MaxBlockSize)
     {
-        return(LVEQNB_TOOMANYSAMPLES);
+        return LVEQNB_TOOMANYSAMPLES;
     }
 
     if (pInstance->Params.OperatingMode == LVEQNB_ON)
@@ -97,16 +102,16 @@
         /*
          * Copy input data in to scratch buffer
          */
+        Copy_Float(pInData,     /* Source */
+                   pScratch,    /* Destination */
+                   (LVM_INT16)NrSamples);
 
-        Copy_Float((LVM_FLOAT *)pInData,      /* Source */
-                   pScratch,                  /* Destination */
-                   (LVM_INT16)(2 * NumSamples)); /* Left and Right */
         /*
          * For each section execte the filter unless the gain is 0dB
          */
         if (pInstance->NBands != 0)
         {
-            for (i = 0; i < pInstance->NBands; i++)
+            for (LVM_UINT16 i = 0; i < pInstance->NBands; i++)
             {
                 /*
                  * Check if band is non-zero dB gain
@@ -116,7 +121,7 @@
                     /*
                      * Get the address of the biquad instance
                      */
-                    pBiquad = &pInstance->pEQNB_FilterState_Float[i];
+                    Biquad_FLOAT_Instance_t *pBiquad = &pInstance->pEQNB_FilterState_Float[i];
 
 
                     /*
@@ -126,10 +131,18 @@
                     {
                         case LVEQNB_SinglePrecision_Float:
                         {
+#ifdef SUPPORT_MC
+                            PK_Mc_D32F32C14G11_TRC_WRA_01(pBiquad,
+                                                          pScratch,
+                                                          pScratch,
+                                                          (LVM_INT16)NrFrames,
+                                                          (LVM_INT16)NrChannels);
+#else
                             PK_2I_D32F32C14G11_TRC_WRA_01(pBiquad,
-                                                          (LVM_FLOAT *)pScratch,
-                                                          (LVM_FLOAT *)pScratch,
-                                                          (LVM_INT16)NumSamples);
+                                                          pScratch,
+                                                          pScratch,
+                                                          (LVM_INT16)NrFrames);
+#endif
                             break;
                         }
                         default:
@@ -141,19 +154,29 @@
 
 
         if(pInstance->bInOperatingModeTransition == LVM_TRUE){
+#ifdef SUPPORT_MC
+            LVC_MixSoft_2Mc_D16C31_SAT(&pInstance->BypassMixer,
+                                       pScratch,
+                                       pInData,
+                                       pScratch,
+                                       (LVM_INT16)NrFrames,
+                                       (LVM_INT16)NrChannels);
+#else
             LVC_MixSoft_2St_D16C31_SAT(&pInstance->BypassMixer,
-                                       (LVM_FLOAT *)pScratch,
-                                       (LVM_FLOAT *)pInData,
-                                       (LVM_FLOAT *)pScratch,
-                                       (LVM_INT16)(2 * NumSamples));
-            Copy_Float((LVM_FLOAT*)pScratch,                           /* Source */
-                       pOutData,                                       /* Destination */
-                       (LVM_INT16)(2 * NumSamples));                     /* Left and Right samples */
+                                       pScratch,
+                                       pInData,
+                                       pScratch,
+                                       (LVM_INT16)NrSamples);
+#endif
+            // duplicate with else clause(s)
+            Copy_Float(pScratch,                         /* Source */
+                       pOutData,                         /* Destination */
+                       (LVM_INT16)NrSamples);            /* All channel samples */
         }
         else{
             Copy_Float(pScratch,              /* Source */
                        pOutData,              /* Destination */
-                       (LVM_INT16 )(2 * NumSamples)); /* Left and Right */
+                       (LVM_INT16)NrSamples); /* All channel samples */
         }
     }
     else
@@ -163,12 +186,12 @@
          */
         if (pInData != pOutData)
         {
-            Copy_Float(pInData,                                    /* Source */
-                       pOutData,                                   /* Destination */
-                       (LVM_INT16)(2 * NumSamples));                 /* Left and Right samples */
+            Copy_Float(pInData,                          /* Source */
+                       pOutData,                         /* Destination */
+                       (LVM_INT16)NrSamples);            /* All channel samples */
         }
     }
-    return(LVEQNB_SUCCESS);
+    return LVEQNB_SUCCESS;
 
 }
 #else
@@ -312,4 +335,4 @@
     return(LVEQNB_SUCCESS);
 
 }
-#endif
\ No newline at end of file
+#endif
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Tables.c b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Tables.c
index 563181c..453c42d 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Tables.c
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Tables.c
@@ -46,7 +46,9 @@
                                               32000,
                                               44100,
                                               48000,
+                                              88200,
                                               96000,
+                                              176400,
                                               192000
 };
 #else
@@ -82,7 +84,9 @@
                                                LVEQNB_2PiOn_44100,
                                                LVEQNB_2PiOn_48000
 #ifdef HIGHER_FS
+                                              ,LVEQNB_2PiOn_88200
                                               ,LVEQNB_2PiOn_96000
+                                              ,LVEQNB_2PiOn_176400
                                               ,LVEQNB_2PiOn_192000
 #endif
                                                };
@@ -249,30 +253,4 @@
                                           16586,                       /* a2 */
                                           -44};                        /* a3 */
 
-/************************************************************************************/
-/*                                                                                  */
-/*  Bypass mixer time constants (100ms)                                             */
-/*                                                                                  */
-/************************************************************************************/
 
-#define LVEQNB_MIX_TC_Fs8000    32580         /* Floating point value 0.994262695 */
-#define LVEQNB_MIX_TC_Fs11025   32632         /* Floating point value 0.995849609 */
-#define LVEQNB_MIX_TC_Fs12000   32643         /* Floating point value 0.996185303 */
-#define LVEQNB_MIX_TC_Fs16000   32674         /* Floating point value 0.997131348 */
-#define LVEQNB_MIX_TC_Fs22050   32700         /* Floating point value 0.997924805 */
-#define LVEQNB_MIX_TC_Fs24000   32705         /* Floating point value 0.998077393 */
-#define LVEQNB_MIX_TC_Fs32000   32721         /* Floating point value 0.998565674 */
-#define LVEQNB_MIX_TC_Fs44100   32734         /* Floating point value 0.998962402 */
-#define LVEQNB_MIX_TC_Fs48000   32737         /* Floating point value 0.999053955 */
-
-
-const LVM_INT16 LVEQNB_MixerTCTable[] = {
-    LVEQNB_MIX_TC_Fs8000,
-    LVEQNB_MIX_TC_Fs11025,
-    LVEQNB_MIX_TC_Fs12000,
-    LVEQNB_MIX_TC_Fs16000,
-    LVEQNB_MIX_TC_Fs22050,
-    LVEQNB_MIX_TC_Fs24000,
-    LVEQNB_MIX_TC_Fs32000,
-    LVEQNB_MIX_TC_Fs44100,
-    LVEQNB_MIX_TC_Fs48000};
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h b/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
index ff7475e..c915ac0 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
@@ -123,7 +123,7 @@
 #ifndef HIGHER_FS
 #define LVREV_NUM_FS                        9           /* Number of supported sample rates */
 #else
-#define LVREV_NUM_FS                       11           /* Number of supported sample rates */
+#define LVREV_NUM_FS                       13           /* Number of supported sample rates */
 #endif
 
 #define LVREV_MAXBLKSIZE_LIMIT             64           /* Maximum block size low limit */
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.c
index 566d84f..1d1283e 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.c
@@ -579,7 +579,7 @@
                                pTemp,
                                pTemp,
                                (LVM_INT16)NumSamples);
-    
+
     /*
      *  Process all delay lines
      */
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.c
index a719053..dfed28e 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.c
@@ -64,12 +64,22 @@
         (
         (pNewParams->SampleRate != LVM_FS_8000) && (pNewParams->SampleRate != LVM_FS_11025) && (pNewParams->SampleRate != LVM_FS_12000)       &&
         (pNewParams->SampleRate != LVM_FS_16000) && (pNewParams->SampleRate != LVM_FS_22050) && (pNewParams->SampleRate != LVM_FS_24000)       &&
-        (pNewParams->SampleRate != LVM_FS_32000) && (pNewParams->SampleRate != LVM_FS_44100) && (pNewParams->SampleRate != LVM_FS_48000)      
+        (pNewParams->SampleRate != LVM_FS_32000) &&
+        (pNewParams->SampleRate != LVM_FS_44100) &&
+        (pNewParams->SampleRate != LVM_FS_48000)
 #ifdef HIGHER_FS
-        && (pNewParams->SampleRate != LVM_FS_96000) && (pNewParams->SampleRate != LVM_FS_192000)
+        && (pNewParams->SampleRate != LVM_FS_88200) && (pNewParams->SampleRate != LVM_FS_96000)
+        && (pNewParams->SampleRate != LVM_FS_176400) && (pNewParams->SampleRate != LVM_FS_192000)
 #endif
         )
+#ifdef SUPPORT_MC
+        || ((pNewParams->SourceFormat != LVM_STEREO)       &&
+            (pNewParams->SourceFormat != LVM_MONOINSTEREO) &&
+            (pNewParams->SourceFormat != LVM_MONO)         &&
+            (pNewParams->SourceFormat != LVM_MULTICHANNEL)))
+#else
         || ((pNewParams->SourceFormat != LVM_STEREO) && (pNewParams->SourceFormat != LVM_MONOINSTEREO) && (pNewParams->SourceFormat != LVM_MONO)) )
+#endif
     {
         return (LVREV_OUTOFRANGE);
     }
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.c
index b3edc60..1058740 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.c
@@ -52,7 +52,9 @@
     32000,
     44100,
     48000,
+    88200,
     96000,
+    176400,
     192000
 };
 #endif
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
index a750bb0..ee07e2e 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
@@ -46,7 +46,7 @@
 #ifndef HIGHER_FS
 #define LVPSA_NR_SUPPORTED_RATE          9      /* From 8000Hz to 48000Hz*/
 #else
-#define LVPSA_NR_SUPPORTED_RATE          11      /* From 8000Hz to 192000Hz*/
+#define LVPSA_NR_SUPPORTED_RATE          13      /* From 8000Hz to 192000Hz*/
 #endif
 #define LVPSA_NR_SUPPORTED_SPEED         3      /* LOW, MEDIUM, HIGH                                                */
 
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.c
index ea5f74a..61899fe 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.c
@@ -22,6 +22,17 @@
 
 #define LVM_MININT_32   0x80000000
 
+static LVM_INT32 mult32x32in32_shiftr(LVM_INT32 a, LVM_INT32 b, LVM_INT32 c) {
+  LVM_INT64 result = ((LVM_INT64)a * b) >> c;
+
+  if (result >= INT32_MAX) {
+    return INT32_MAX;
+  } else if (result <= INT32_MIN) {
+    return INT32_MIN;
+  } else {
+    return (LVM_INT32)result;
+  }
+}
 
 /************************************************************************************/
 /*                                                                                  */
@@ -123,10 +134,10 @@
 
     if(pLVPSA_Inst->pSpectralDataBufferWritePointer != pWrite_Save)
     {
-        MUL32x32INTO32((AudioTime + (LVM_INT32)((LVM_INT32)pLVPSA_Inst->LocalSamplesCount*1000)),
-                        (LVM_INT32)LVPSA_SampleRateInvTab[pLVPSA_Inst->CurrentParams.Fs],
-                        AudioTimeInc,
-                        LVPSA_FsInvertShift)
+        AudioTimeInc = mult32x32in32_shiftr(
+                (AudioTime + ((LVM_INT32)pLVPSA_Inst->LocalSamplesCount * 1000)),
+                (LVM_INT32)LVPSA_SampleRateInvTab[pLVPSA_Inst->CurrentParams.Fs],
+                LVPSA_FsInvertShift);
         pLVPSA_Inst->SpectralDataBufferAudioTime = AudioTime + AudioTimeInc;
     }
 
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Tables.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Tables.c
index 1287503..f8af496 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Tables.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Tables.c
@@ -54,7 +54,9 @@
                                                 32000,
                                                 44100,
                                                 48000,
+                                                88200,
                                                 96000,
+                                               176400,
                                                192000};                  /* 192kS/s */
 #endif
 
@@ -78,7 +80,9 @@
                                                     48696,
                                                     44739
 #ifdef HIGHER_FS
+                                                    ,24348
                                                     ,22369
+                                                    ,12174
                                                     ,11185                  /* 192kS/s */
 #endif
                                                };
@@ -105,7 +109,9 @@
                                                         882,
                                                         960
 #ifdef HIGHER_FS
+                                                        ,1764
                                                         ,1920
+                                                        ,3528
                                                         ,3840                  /* 192kS/s */
 #endif
                                                     };
@@ -128,7 +134,9 @@
                                                         30,                   /* 44100 S/s  */
                                                         32                    /* 48000 S/s  */
 #ifdef HIGHER_FS
+                                                       ,60                   /* 88200 S/s  */
                                                        ,64                   /* 96000 S/s  */
+                                                       ,120                  /* 176400 S/s  */
                                                        ,128                  /*192000 S/s  */
 #endif
                                                   };
@@ -153,7 +161,9 @@
                                                  4781,
                                                  4392
 #ifdef HIGHER_FS
+                                                ,2390
                                                 ,2196
+                                                ,1195
                                                 ,1098    /* 192kS/s */
 #endif
                                              };
@@ -169,7 +179,9 @@
                                                       0.1459089f,
                                                       0.1340372f
 #ifdef HIGHER_FS
+                                                     ,0.0729476f
                                                      ,0.0670186f
+                                                     ,0.0364738f
                                                      ,0.0335093f    /* 192kS/s */
 #endif
                                                    };
@@ -352,7 +364,9 @@
                                           /* 48kS/s */
                                          {-0.9932638457976282f,0.0066249934025109f},
 #ifdef HIGHER_FS
+                                         {-0.9931269618682563f,0.0067592649720609f},
                                          {-0.9932638457976282f,0.0066249934025109f},
+                                         {-0.9931269618682563f,0.0067592649720609f},
                                          {-0.9932638457976282f,0.0066249934025109f},
 #endif
                                          /* 8kS/s  */    /* LVPSA_SPEED_MEDIUM      */
@@ -368,7 +382,9 @@
                                           /* 48kS/s */
                                          {-0.9540119562298059f,0.0445343819446862f},
 #ifdef HIGHER_FS
+                                         {-0.9531011912040412f,0.0453995238058269f},
                                          {-0.9540119562298059f,0.0445343819446862f},
+                                         {-0.9531011912040412f,0.0453995238058269f},
                                          {-0.9540119562298059f,0.0445343819446862f},
 #endif
                                           /* 8kS/s  */   /* LVPSA_SPEED_HIGH      */
@@ -383,7 +399,9 @@
                                            /* 48kS/s */
                                          {-0.7274807319045067f,0.2356666540727019f}
 #ifdef HIGHER_FS
+                                        ,{-0.7229706319049001f,0.2388987224549055f}
                                         ,{-0.7274807319045067f,0.2356666540727019f}
+                                        ,{-0.7229706319049001f,0.2388987224549055f}
                                         ,{-0.7274807319045067f,0.2356666540727019f}
 #endif
                                         };
diff --git a/media/libeffects/lvm/lib/StereoWidening/lib/LVCS.h b/media/libeffects/lvm/lib/StereoWidening/lib/LVCS.h
index e75695e..e507a7c 100644
--- a/media/libeffects/lvm/lib/StereoWidening/lib/LVCS.h
+++ b/media/libeffects/lvm/lib/StereoWidening/lib/LVCS.h
@@ -205,6 +205,9 @@
     LVM_Fs_en               SampleRate;             /* Sampling rate */
     LVM_INT16               EffectLevel;            /* Effect level */
     LVM_UINT16              ReverbLevel;            /* Reverb level in % */
+#ifdef SUPPORT_MC
+    LVM_INT32               NrChannels;
+#endif
 } LVCS_Params_t;
 
 
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Headphone_Coeffs.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Headphone_Coeffs.h
index 0c2fe53..ba05577 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Headphone_Coeffs.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Headphone_Coeffs.h
@@ -152,6 +152,24 @@
 #define CS_SIDE_48000_SCALE                          14
 
 #ifdef HIGHER_FS
+/* Coefficients for 88200Hz sample rate.
+ * The filter coefficients are obtained by carrying out
+ * state-space analysis using the coefficients available
+ * for 44100Hz.
+ */
+#define CS_MIDDLE_88200_A0                     0.233846f
+#define CS_MIDDLE_88200_A1                     (-0.232657f)
+#define CS_MIDDLE_88200_A2                     0.000000f
+#define CS_MIDDLE_88200_B1                     (-0.992747f)
+#define CS_MIDDLE_88200_B2                     0.000000f
+#define CS_MIDDLE_88200_SCALE                  15
+#define CS_SIDE_88200_A0                       0.231541f
+#define CS_SIDE_88200_A1                       (-0.289586f)
+#define CS_SIDE_88200_A2                       0.058045f
+#define CS_SIDE_88200_B1                       (-1.765300f)
+#define CS_SIDE_88200_B2                       0.769816f
+#define CS_SIDE_88200_SCALE                    14
+
 /* Stereo Enhancer coefficients for 96000Hz sample rate, scaled with  0.165*/
 /* high pass filter with cutoff frequency 102.18 Hz*/
 #define CS_MIDDLE_96000_A0                     0.235532
@@ -160,13 +178,33 @@
 #define CS_MIDDLE_96000_B1                    (-0.993334)
 #define CS_MIDDLE_96000_B2                     0.000000
 #define CS_MIDDLE_96000_SCALE                        15
-/* bandpass filter with fc1 270 and fc2 3703, designed using 2nd order butterworth */
-#define CS_SIDE_96000_A0                     0.016727
-#define CS_SIDE_96000_A1                     0.000000
-#define CS_SIDE_96000_A2                    (-0.016727)
-#define CS_SIDE_96000_B1                    (-1.793372)
-#define CS_SIDE_96000_B2                     0.797236
-#define CS_SIDE_96000_SCALE                        14
+/* Coefficients calculated using tf2ss and ss2tf functions based on
+ * coefficients available for 48000Hz sampling frequency
+ */
+#define CS_SIDE_96000_A0                     0.224326f
+#define CS_SIDE_96000_A1                     (-0.294937f)
+#define CS_SIDE_96000_A2                     0.070611f
+#define CS_SIDE_96000_B1                     (-1.792166f)
+#define CS_SIDE_96000_B2                     0.795830f
+#define CS_SIDE_96000_SCALE                  14
+
+/* Stereo Enhancer coefficients for 176400Hz sample rate.
+ * The filter coefficients are obtained by carrying out
+ * state-space analysis using the coefficients available
+ * for 44100Hz.
+ */
+#define CS_MIDDLE_176400_A0                     0.233973f
+#define CS_MIDDLE_176400_A1                     (-0.233378f)
+#define CS_MIDDLE_176400_A2                     0.000000f
+#define CS_MIDDLE_176400_B1                     (-0.996367f)
+#define CS_MIDDLE_176400_B2                     0.000000f
+#define CS_MIDDLE_176400_SCALE                  15
+#define CS_SIDE_176400_A0                       0.199836f
+#define CS_SIDE_176400_A1                       (-0.307544f)
+#define CS_SIDE_176400_A2                       0.107708f
+#define CS_SIDE_176400_B1                       (-1.876572f)
+#define CS_SIDE_176400_B2                       0.877771f
+#define CS_SIDE_176400_SCALE                    14
 
 /* Stereo Enhancer coefficients for 192000Hz sample rate, scaled with  0.1689*/
 #define CS_MIDDLE_192000_A0                     0.241219
@@ -175,13 +213,15 @@
 #define CS_MIDDLE_192000_B1                    (-0.996661)
 #define CS_MIDDLE_192000_B2                     0.000000
 #define CS_MIDDLE_192000_SCALE                        15
-/* bandpass filter with fc1 270 and fc2 3703, designed using 2nd order butterworth */
-#define CS_SIDE_192000_A0                     0.008991
-#define CS_SIDE_192000_A1                    (-0.000000)
-#define CS_SIDE_192000_A2                    (-0.008991)
-#define CS_SIDE_192000_B1                    (-1.892509)
-#define CS_SIDE_192000_B2                     0.893524
-#define CS_SIDE_192000_SCALE                       14
+/* Coefficients calculated using tf2ss and ss2tf functions based on
+ * coefficients available for 48000Hz sampling frequency
+ */
+#define CS_SIDE_192000_A0                    0.196039f
+#define CS_SIDE_192000_A1                    (-0.311027f)
+#define CS_SIDE_192000_A2                    0.114988f
+#define CS_SIDE_192000_B1                    (-1.891380f)
+#define CS_SIDE_192000_B2                    0.8923460f
+#define CS_SIDE_192000_SCALE                 14
 #endif
 
 /************************************************************************************/
@@ -199,7 +239,12 @@
 #define LVCS_STEREODELAY_CS_24KHZ                   279         /* Sample rate 24kS/s */
 #define LVCS_STEREODELAY_CS_32KHZ                   372         /* Sample rate 32kS/s */
 #define LVCS_STEREODELAY_CS_44KHZ                   512         /* Sample rate 44kS/s */
-#define LVCS_STEREODELAY_CS_48KHZ                   512         /* Sample rate 48kS/s */
+#define LVCS_STEREODELAY_CS_48KHZ                   557         /* Sample rate 48kS/s */
+#define LVCS_STEREODELAY_CS_88KHZ                   1024        /* Sample rate 88.2kS/s */
+#define LVCS_STEREODELAY_CS_96KHZ                   1115        /* Sample rate 96kS/s */
+#define LVCS_STEREODELAY_CS_176KHZ                  2048        /* Sample rate 176.4kS/s */
+#define LVCS_STEREODELAY_CS_192KHZ                  2229        /* Sample rate 196kS/s */
+#define LVCS_STEREODELAY_CS_MAX_VAL                 LVCS_STEREODELAY_CS_192KHZ
 
 /* Reverb coefficients for 8000 Hz sample rate, scaled with 1.038030 */
 #define CS_REVERB_8000_A0                          0.667271
@@ -275,6 +320,14 @@
 #define CS_REVERB_48000_SCALE                        14
 
 #ifdef HIGHER_FS
+/* Reverb coefficients for 88200Hz sample rate, scaled with 0.8 */
+/* Band pass filter with fc1=500 and fc2=8000 */
+#define CS_REVERB_88200_A0                       0.171901f
+#define CS_REVERB_88200_A1                       0.000000f
+#define CS_REVERB_88200_A2                      (-0.171901f)
+#define CS_REVERB_88200_B1                      (-1.553948f)
+#define CS_REVERB_88200_B2                      (0.570248f)
+#define CS_REVERB_88200_SCALE                      14
 /* Reverb coefficients for 96000Hz sample rate, scaled with 0.8 */
 /* Band pass filter with fc1=500 and fc2=8000*/
 #define CS_REVERB_96000_A0                       0.1602488
@@ -284,6 +337,14 @@
 #define CS_REVERB_96000_B2                       0.599377
 #define CS_REVERB_96000_SCALE                        14
 
+/* Reverb coefficients for 176400Hz sample rate, scaled with 0.8 */
+/* Band pass filter with fc1=500 and fc2=8000 */
+#define CS_REVERB_176400_A0                       0.094763f
+#define CS_REVERB_176400_A1                       0.000000f
+#define CS_REVERB_176400_A2                      (-0.094763f)
+#define CS_REVERB_176400_B1                      (-1.758593f)
+#define CS_REVERB_176400_B2                      (0.763091f)
+#define CS_REVERB_176400_SCALE                      14
 /* Reverb coefficients for 192000Hz sample rate, scaled with 0.8 */
 /* Band pass filter with fc1=500 and fc2=8000*/
 #define CS_REVERB_192000_A0                       0.0878369
@@ -446,6 +507,24 @@
 
 
 #ifdef HIGHER_FS
+/* Equaliser coefficients for 88200Hz sample rate.
+ * The filter coefficients are obtained by carrying out
+ * state-space analysis using the coefficients available
+ * for 44100Hz.
+ */
+#define CS_EQUALISER_88200_A0                   1.771899f
+#define CS_EQUALISER_88200_A1                   (-2.930762f)
+#define CS_EQUALISER_88200_A2                   1.172175f
+#define CS_EQUALISER_88200_B1                   (-1.438349f)
+#define CS_EQUALISER_88200_B2                   0.442520f
+#define CS_EQUALISER_88200_SCALE                13
+#define CSEX_EQUALISER_88200_A0                 2.675241f
+#define CSEX_EQUALISER_88200_A1                 (-4.466154f)
+#define CSEX_EQUALISER_88200_A2                 1.810305f
+#define CSEX_EQUALISER_88200_B1                 (-0.925350f)
+#define CSEX_EQUALISER_88200_B2                 (-0.066616f)
+#define CSEX_EQUALISER_88200_SCALE              13
+
 #define CS_EQUALISER_96000_A0                    1.784497
 #define CS_EQUALISER_96000_A1                   (-3.001435)
 #define CS_EQUALISER_96000_A2                    1.228422
@@ -458,6 +537,23 @@
 #define CSEX_EQUALISER_96000_B1                 (-0.971718)
 #define CSEX_EQUALISER_96000_B2                 (-0.021216)
 #define CSEX_EQUALISER_96000_SCALE                   13
+/* Equaliser coefficients for 176400Hz sample rate.
+ * The filter coefficients are obtained by carrying out
+ * state-space analysis using the coefficients available
+ * for 44100Hz.
+ */
+#define CS_EQUALISER_176400_A0                  1.883440f
+#define CS_EQUALISER_176400_A1                  (-3.414272f)
+#define CS_EQUALISER_176400_A2                  1.534702f
+#define CS_EQUALISER_176400_B1                  (-1.674614f)
+#define CS_EQUALISER_176400_B2                  0.675827f
+#define CS_EQUALISER_176400_SCALE               13
+#define CSEX_EQUALISER_176400_A0                3.355068f
+#define CSEX_EQUALISER_176400_A1                (-6.112578f)
+#define CSEX_EQUALISER_176400_A2                2.764135f
+#define CSEX_EQUALISER_176400_B1                (-1.268533f)
+#define CSEX_EQUALISER_176400_B2                0.271277f
+#define CSEX_EQUALISER_176400_SCALE             13
 
 #define CS_EQUALISER_192000_A0                    1.889582
 #define CS_EQUALISER_192000_A1                   (-3.456140)
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
index a97e4f0..ab8ccd1 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
@@ -61,6 +61,15 @@
 
 /* Memory */
 #define LVCS_SCRATCHBUFFERS              6      /* Number of buffers required for inplace processing */
+#ifdef SUPPORT_MC
+/*
+ * The Concert Surround module applies processing only on the first two
+ * channels of a multichannel input. The data of first two channels is copied
+ * from the multichannel input into scratch buffer. The buffers added here
+ * are used for this purpose
+ */
+#define LVCS_MC_SCRATCHBUFFERS           2
+#endif
 
 /* General */
 #define LVCS_INVALID                0xFFFF      /* Invalid init parameter */
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.c
index 3956d4d..ef1d9eb 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.c
@@ -76,6 +76,22 @@
     LVCS_Instance_t     *pInstance = (LVCS_Instance_t  *)hInstance;
     LVM_FLOAT           *pScratch;
     LVCS_ReturnStatus_en err;
+#ifdef SUPPORT_MC
+    LVM_FLOAT           *pStIn;
+    LVM_INT32           channels = pInstance->Params.NrChannels;
+#define NrFrames NumSamples  // alias for clarity
+
+    /*In case of mono processing, stereo input is created from mono
+     *and stored in pInData before applying any of the effects.
+     *However we do not update the value pInstance->Params.NrChannels
+     *at this point.
+     *So to treat the pInData as stereo we are setting channels to 2
+     */
+    if (channels == 1)
+    {
+        channels = 2;
+    }
+#endif
 
     pScratch  = (LVM_FLOAT *) \
                   pInstance->MemoryTable.Region[LVCS_MEMREGION_TEMPORARY_FAST].pBaseAddress;
@@ -83,6 +99,25 @@
     /*
      * Check if the processing is inplace
      */
+#ifdef SUPPORT_MC
+    /*
+     * The pInput buffer holds the first 2 (Left, Right) channels information.
+     * Hence the memory required by this buffer is 2 * NumFrames.
+     * The Concert Surround module carries out processing only on L, R.
+     */
+    pInput = pScratch + (2 * NrFrames);
+    pStIn  = pScratch + (LVCS_SCRATCHBUFFERS * NrFrames);
+    /* The first two channel data is extracted from the input data and
+     * copied into pInput buffer
+     */
+    Copy_Float_Mc_Stereo((LVM_FLOAT *)pInData,
+                         (LVM_FLOAT *)pInput,
+                         NrFrames,
+                         channels);
+    Copy_Float((LVM_FLOAT *)pInput,
+               (LVM_FLOAT *)pStIn,
+               (LVM_INT16)(2 * NrFrames));
+#else
     if (pInData == pOutData)
     {
         /* Processing inplace */
@@ -96,14 +131,21 @@
         /* Processing outplace */
         pInput = pInData;
     }
-
+#endif
     /*
      * Call the stereo enhancer
      */
+#ifdef SUPPORT_MC
+    err = LVCS_StereoEnhancer(hInstance,              /* Instance handle */
+                              pStIn,                  /* Pointer to the input data */
+                              pOutData,               /* Pointer to the output data */
+                              NrFrames);              /* Number of frames to process */
+#else
     err = LVCS_StereoEnhancer(hInstance,              /* Instance handle */
                               pInData,                    /* Pointer to the input data */
                               pOutData,                   /* Pointer to the output data */
                               NumSamples);                /* Number of samples to process */
+#endif
 
     /*
      * Call the reverb generator
@@ -112,7 +154,7 @@
                                pOutData,                  /* Pointer to the input data */
                                pOutData,                  /* Pointer to the output data */
                                NumSamples);               /* Number of samples to process */
-    
+
     /*
      * Call the equaliser
      */
@@ -239,7 +281,15 @@
 
     LVCS_Instance_t *pInstance = (LVCS_Instance_t  *)hInstance;
     LVCS_ReturnStatus_en err;
-
+#ifdef SUPPORT_MC
+    /*Extract number of Channels info*/
+    LVM_INT32 channels = pInstance->Params.NrChannels;
+#define NrFrames NumSamples  // alias for clarity
+    if (channels == 1)
+    {
+        channels = 2;
+    }
+#endif
     /*
      * Check the number of samples is not too large
      */
@@ -260,8 +310,8 @@
                                   pInData,
                                   pOutData,
                                   NumSamples);
-            
-            
+
+
         /*
          * Compress to reduce expansion effect of Concert Sound and correct volume
          * differences for difference settings. Not applied in test modes
@@ -376,17 +426,32 @@
                             (LVM_INT16)NumSamples);
             }
         }
+#ifdef SUPPORT_MC
+        Copy_Float_Stereo_Mc(pInData,
+                             pOutData,
+                             NrFrames,
+                             channels);
+#endif
     }
     else
     {
         if (pInData != pOutData)
         {
+#ifdef SUPPORT_MC
+            /*
+             * The algorithm is disabled so just copy the data
+             */
+            Copy_Float((LVM_FLOAT *)pInData,               /* Source */
+                       (LVM_FLOAT *)pOutData,                  /* Destination */
+                       (LVM_INT16)(channels * NrFrames));    /* All Channels*/
+#else
             /*
              * The algorithm is disabled so just copy the data
              */
             Copy_Float((LVM_FLOAT *)pInData,               /* Source */
                        (LVM_FLOAT *)pOutData,                  /* Destination */
                        (LVM_INT16)(2 * NumSamples));             /* Left and right */
+#endif
         }
     }
 
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.h
index 69892b6..f94d4e4 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.h
@@ -65,7 +65,7 @@
     /* Filter */
     void                        (*pBiquadCallBack) (Biquad_Instance_t*, LVM_INT16*, LVM_INT16*, LVM_INT16);
 #else
-    LVM_FLOAT                   StereoSamples[2 * LVCS_STEREODELAY_CS_48KHZ];
+    LVM_FLOAT                   StereoSamples[2 * LVCS_STEREODELAY_CS_MAX_VAL];
     /* Reverb Level */
     LVM_FLOAT                   ReverbLevel;
     /* Filter */
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.c
index e154e29..a1fb48f 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.c
@@ -74,10 +74,18 @@
      (LVM_UINT16 )CS_MIDDLE_48000_SCALE}
 #ifdef HIGHER_FS
     ,
+    {CS_MIDDLE_88200_A0,        /* 88kS/s coefficients */
+     CS_MIDDLE_88200_A1,
+     CS_MIDDLE_88200_B1,
+     (LVM_UINT16)CS_MIDDLE_88200_SCALE},
     {CS_MIDDLE_96000_A0,        /* 96kS/s coefficients */
      CS_MIDDLE_96000_A1,
      CS_MIDDLE_96000_B1,
      (LVM_UINT16 )CS_MIDDLE_96000_SCALE},
+    {CS_MIDDLE_176400_A0,        /* 176kS/s coefficients */
+     CS_MIDDLE_176400_A1,
+     CS_MIDDLE_176400_B1,
+     (LVM_UINT16)CS_MIDDLE_176400_SCALE},
     {CS_MIDDLE_192000_A0,        /* 192kS/s coefficients */
      CS_MIDDLE_192000_A1,
      CS_MIDDLE_192000_B1,
@@ -144,12 +152,24 @@
      (LVM_UINT16 )CS_SIDE_48000_SCALE}
 #ifdef HIGHER_FS
      ,
+    {CS_SIDE_88200_A0,          /* 88kS/s coefficients */
+     CS_SIDE_88200_A1,
+     CS_SIDE_88200_A2,
+     CS_SIDE_88200_B1,
+     CS_SIDE_88200_B2,
+     (LVM_UINT16)CS_SIDE_88200_SCALE},
      {CS_SIDE_96000_A0,          /* 96kS/s coefficients */
      CS_SIDE_96000_A1,
      CS_SIDE_96000_A2,
      CS_SIDE_96000_B1,
      CS_SIDE_96000_B2,
      (LVM_UINT16 )CS_SIDE_96000_SCALE},
+    {CS_SIDE_176400_A0,          /*176kS/s coefficients */
+     CS_SIDE_176400_A1,
+     CS_SIDE_176400_A2,
+     CS_SIDE_176400_B1,
+     CS_SIDE_176400_B2,
+     (LVM_UINT16)CS_SIDE_176400_SCALE},
      {CS_SIDE_192000_A0,          /* 192kS/s coefficients */
      CS_SIDE_192000_A1,
      CS_SIDE_192000_A2,
@@ -223,12 +243,24 @@
      CS_EQUALISER_48000_B2,
      (LVM_UINT16 )CS_EQUALISER_48000_SCALE},
 #ifdef HIGHER_FS
+    {CS_EQUALISER_88200_A0,     /* 88kS/s coeffieients */
+     CS_EQUALISER_88200_A1,
+     CS_EQUALISER_88200_A2,
+     CS_EQUALISER_88200_B1,
+     CS_EQUALISER_88200_B2,
+     (LVM_UINT16)CS_EQUALISER_88200_SCALE},
     {CS_EQUALISER_96000_A0,     /* 96kS/s coefficients */
      CS_EQUALISER_96000_A1,
      CS_EQUALISER_96000_A2,
      CS_EQUALISER_96000_B1,
      CS_EQUALISER_96000_B2,
      (LVM_UINT16 )CS_EQUALISER_96000_SCALE},
+    {CS_EQUALISER_176400_A0,     /* 176kS/s coefficients */
+     CS_EQUALISER_176400_A1,
+     CS_EQUALISER_176400_A2,
+     CS_EQUALISER_176400_B1,
+     CS_EQUALISER_176400_B2,
+     (LVM_UINT16)CS_EQUALISER_176400_SCALE},
     {CS_EQUALISER_192000_A0,     /* 192kS/s coefficients */
      CS_EQUALISER_192000_A1,
      CS_EQUALISER_192000_A2,
@@ -294,12 +326,24 @@
      (LVM_UINT16 )CSEX_EQUALISER_48000_SCALE}
 #ifdef HIGHER_FS
     ,
+    {CSEX_EQUALISER_88200_A0,   /* 88kS/s coefficients */
+     CSEX_EQUALISER_88200_A1,
+     CSEX_EQUALISER_88200_A2,
+     CSEX_EQUALISER_88200_B1,
+     CSEX_EQUALISER_88200_B2,
+     (LVM_UINT16)CSEX_EQUALISER_88200_SCALE},
     {CSEX_EQUALISER_96000_A0,   /* 96kS/s coefficients */
      CSEX_EQUALISER_96000_A1,
      CSEX_EQUALISER_96000_A2,
      CSEX_EQUALISER_96000_B1,
      CSEX_EQUALISER_96000_B2,
      (LVM_UINT16 )CSEX_EQUALISER_96000_SCALE},
+    {CSEX_EQUALISER_176400_A0,   /* 176kS/s coefficients */
+     CSEX_EQUALISER_176400_A1,
+     CSEX_EQUALISER_176400_A2,
+     CSEX_EQUALISER_176400_B1,
+     CSEX_EQUALISER_176400_B2,
+     (LVM_UINT16)CSEX_EQUALISER_176400_SCALE},
      {CSEX_EQUALISER_192000_A0,   /* 192kS/s coefficients */
      CSEX_EQUALISER_192000_A1,
      CSEX_EQUALISER_192000_A2,
@@ -326,7 +370,12 @@
     LVCS_STEREODELAY_CS_24KHZ,
     LVCS_STEREODELAY_CS_32KHZ,
     LVCS_STEREODELAY_CS_44KHZ,
-    LVCS_STEREODELAY_CS_48KHZ};
+    LVCS_STEREODELAY_CS_48KHZ,
+    LVCS_STEREODELAY_CS_88KHZ,
+    LVCS_STEREODELAY_CS_96KHZ,
+    LVCS_STEREODELAY_CS_176KHZ,
+    LVCS_STEREODELAY_CS_192KHZ,
+};
 
 /************************************************************************************/
 /*                                                                                  */
@@ -392,12 +441,24 @@
      (LVM_UINT16 )CS_REVERB_48000_SCALE}
 #ifdef HIGHER_FS
     ,
+    {CS_REVERB_88200_A0,            /* 88kS/s coefficients */
+     CS_REVERB_88200_A1,
+     CS_REVERB_88200_A2,
+     CS_REVERB_88200_B1,
+     CS_REVERB_88200_B2,
+     (LVM_UINT16)CS_REVERB_88200_SCALE},
     {CS_REVERB_96000_A0,            /* 96kS/s coefficients */
      CS_REVERB_96000_A1,
      CS_REVERB_96000_A2,
      CS_REVERB_96000_B1,
      CS_REVERB_96000_B2,
      (LVM_UINT16 )CS_REVERB_96000_SCALE},
+    {CS_REVERB_176400_A0,            /* 176kS/s coefficients */
+     CS_REVERB_176400_A1,
+     CS_REVERB_176400_A2,
+     CS_REVERB_176400_B1,
+     CS_REVERB_176400_B2,
+     (LVM_UINT16)CS_REVERB_176400_SCALE},
      {CS_REVERB_192000_A0,            /* 192kS/s coefficients */
      CS_REVERB_192000_A1,
      CS_REVERB_192000_A2,
@@ -509,22 +570,26 @@
 #define LVCS_VOL_TC_Fs44100     32734       /* Floating point value 0.998962402 */
 #define LVCS_VOL_TC_Fs48000     32737       /* Floating point value 0.999053955 */
 #if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+#define LVCS_VOL_TC_Fs88200     32751       /* Floating point value 0.999481066 */
 #define LVCS_VOL_TC_Fs96000     32751       /* Floating point value 0.999511703 */   /* Todo @ need to re check this value*/
+#define LVCS_VOL_TC_Fs176400    32759       /* Floating point value 0.999740499 */
 #define LVCS_VOL_TC_Fs192000    32763       /* Floating point value 0.999877925 */  /* Todo @ need to re check this value*/
 #endif
 
 #if defined(BUILD_FLOAT) && defined(HIGHER_FS)
-const LVM_INT16 LVCS_VolumeTCTable[11] = {LVCS_VOL_TC_Fs8000,
-		                                  LVCS_VOL_TC_Fs11025,
-										  LVCS_VOL_TC_Fs12000,
-										  LVCS_VOL_TC_Fs16000,
-										  LVCS_VOL_TC_Fs22050,
-										  LVCS_VOL_TC_Fs24000,
-										  LVCS_VOL_TC_Fs32000,
-										  LVCS_VOL_TC_Fs44100,
-										  LVCS_VOL_TC_Fs48000,
-										  LVCS_VOL_TC_Fs96000,
-										  LVCS_VOL_TC_Fs192000
+const LVM_INT16 LVCS_VolumeTCTable[13] = {LVCS_VOL_TC_Fs8000,
+                                          LVCS_VOL_TC_Fs11025,
+                                          LVCS_VOL_TC_Fs12000,
+                                          LVCS_VOL_TC_Fs16000,
+                                          LVCS_VOL_TC_Fs22050,
+                                          LVCS_VOL_TC_Fs24000,
+                                          LVCS_VOL_TC_Fs32000,
+                                          LVCS_VOL_TC_Fs44100,
+                                          LVCS_VOL_TC_Fs48000,
+                                          LVCS_VOL_TC_Fs88200,
+                                          LVCS_VOL_TC_Fs96000,
+                                          LVCS_VOL_TC_Fs176400,
+                                          LVCS_VOL_TC_Fs192000
 };
 #else
 const LVM_INT16 LVCS_VolumeTCTable[9] = {LVCS_VOL_TC_Fs8000,
@@ -545,17 +610,19 @@
 /*                                                                                  */
 /************************************************************************************/
 #if defined(BUILD_FLOAT) && defined(HIGHER_FS)
-const LVM_INT32   LVCS_SampleRateTable[11] = {8000,
-		                                      11025,
-											  12000,
-											  16000,
-											  22050,
-											  24000,
-											  32000,
-											  44100,
-											  48000,
-											  96000,
-											  192000
+const LVM_INT32   LVCS_SampleRateTable[13] = {8000,
+                                              11025,
+                                              12000,
+                                              16000,
+                                              22050,
+                                              24000,
+                                              32000,
+                                              44100,
+                                              48000,
+                                              88200,
+                                              96000,
+                                              176400,
+                                              192000
 };
 #else
 const LVM_INT16   LVCS_SampleRateTable[9] = {8000,
diff --git a/media/libeffects/lvm/tests/Android.bp b/media/libeffects/lvm/tests/Android.bp
new file mode 100644
index 0000000..003ce9e
--- /dev/null
+++ b/media/libeffects/lvm/tests/Android.bp
@@ -0,0 +1,59 @@
+// Build the unit tests for effects
+
+cc_test {
+    name: "lvmtest",
+    host_supported: false,
+    proprietary: true,
+
+    include_dirs: [
+        "frameworks/av/media/libeffects/lvm/lib/Bass/lib",
+        "frameworks/av/media/libeffects/lvm/lib/Bass/src",
+        "frameworks/av/media/libeffects/lvm/lib/Bundle/src",
+        "frameworks/av/media/libeffects/lvm/lib/Common/src",
+        "frameworks/av/media/libeffects/lvm/lib/Eq/lib",
+        "frameworks/av/media/libeffects/lvm/lib/Eq/src",
+        "frameworks/av/media/libeffects/lvm/lib/SpectrumAnalyzer/lib",
+        "frameworks/av/media/libeffects/lvm/lib/SpectrumAnalyzer/src",
+        "frameworks/av/media/libeffects/lvm/lib/StereoWidening/lib",
+        "frameworks/av/media/libeffects/lvm/lib/StereoWidening/src",
+        "frameworks/av/media/libeffects/lvm/wrapper/Bundle",
+    ],
+
+    header_libs: [
+        "libaudioeffects",
+    ],
+
+    shared_libs: [
+        "libaudioutils",
+        "liblog",
+    ],
+
+    static_libs: [
+        "libmusicbundle",
+    ],
+
+    srcs: ["lvmtest.cpp"],
+
+    cflags: [
+        "-DBUILD_FLOAT",
+        "-DHIGHER_FS",
+        "-DSUPPORT_MC",
+
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+    ],
+}
+
+cc_test {
+    name: "snr",
+    host_supported: false,
+
+    srcs: ["snr.cpp"],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+    ],
+}
diff --git a/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh b/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh
new file mode 100755
index 0000000..a97acc9
--- /dev/null
+++ b/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh
@@ -0,0 +1,132 @@
+#!/bin/bash
+#
+# Run tests in this directory.
+#
+
+if [ -z "$ANDROID_BUILD_TOP" ]; then
+    echo "Android build environment not set"
+    exit -1
+fi
+
+# ensure we have mm
+. $ANDROID_BUILD_TOP/build/envsetup.sh
+
+mm -j
+
+echo "waiting for device"
+
+adb root && adb wait-for-device remount
+
+# location of test files
+testdir="/data/local/tmp/lvmTest"
+
+echo "========================================"
+echo "testing lvm"
+adb shell mkdir -p $testdir
+adb push $ANDROID_BUILD_TOP/cts/tests/tests/media/res/raw/sinesweepraw.raw $testdir
+adb push $OUT/testcases/snr/arm64/snr $testdir
+
+E_VAL=1
+if [ -z "$1" ]
+then
+    cmds=("adb push $OUT/testcases/lvmtest/arm64/lvmtest $testdir"
+          "adb push $OUT/testcases/lvmtest/arm/lvmtest $testdir"
+         )
+elif [ "$1" == "32" ]
+then
+    cmds="adb push $OUT/testcases/lvmtest/arm/lvmtest $testdir"
+elif [ "$1" == "64" ]
+then
+    cmds="adb push $OUT/testcases/lvmtest/arm64/lvmtest $testdir"
+else
+    echo ""
+    echo "Invalid \"val\""
+    echo "Usage:"
+    echo "      "$0" [val]"
+    echo "      where, val can be either 32 or 64."
+    echo ""
+    echo "      If val is not specified then both 32 bit and 64 bit binaries"
+    echo "      are tested."
+    exit $E_VAL
+fi
+
+flags_arr=(
+    "-csE"
+    "-eqE"
+    "-tE"
+    "-csE -tE -eqE"
+    "-bE -M"
+    "-csE -tE"
+    "-csE -eqE" "-tE -eqE"
+    "-csE -tE -bE -M -eqE"
+    "-tE -eqE -vcBal:96 -M"
+    "-tE -eqE -vcBal:-96 -M"
+    "-tE -eqE -vcBal:0 -M"
+    "-tE -eqE -bE -vcBal:30 -M"
+)
+
+fs_arr=(
+    8000
+    11025
+    12000
+    16000
+    22050
+    24000
+    32000
+    44100
+    48000
+    88200
+    96000
+    176400
+    192000
+)
+
+# run multichannel effects at different configs, saving only the stereo channel
+# pair.
+error_count=0
+for cmd in "${cmds[@]}"
+do
+    $cmd
+    for flags in "${flags_arr[@]}"
+    do
+        for fs in ${fs_arr[*]}
+        do
+            for chMask in {0..22}
+            do
+                adb shell $testdir/lvmtest -i:$testdir/sinesweepraw.raw \
+                    -o:$testdir/sinesweep_$((chMask))_$((fs)).raw -chMask:$chMask -fs:$fs $flags
+
+                shell_ret=$?
+                if [ $shell_ret -ne 0 ]; then
+                    echo "error: $shell_ret"
+                    ((++error_count))
+                fi
+
+
+                # two channel files should be identical to higher channel
+                # computation (first 2 channels).
+                # Do not compare cases where -bE is in flags (due to mono computation)
+                if [[ $flags != *"-bE"* ]] && [[ "$chMask" -gt 1 ]]
+                then
+                    adb shell cmp $testdir/sinesweep_1_$((fs)).raw \
+                        $testdir/sinesweep_$((chMask))_$((fs)).raw
+                elif [[ $flags == *"-bE"* ]] && [[ "$chMask" -gt 1 ]]
+                then
+                    adb shell $testdir/snr $testdir/sinesweep_1_$((fs)).raw \
+                        $testdir/sinesweep_$((chMask))_$((fs)).raw -thr:90.308998
+                fi
+
+                # both cmp and snr return EXIT_FAILURE on mismatch.
+                shell_ret=$?
+                if [ $shell_ret -ne 0 ]; then
+                    echo "error: $shell_ret"
+                    ((++error_count))
+                fi
+            done
+        done
+    done
+done
+
+adb shell rm -r $testdir
+echo "$error_count errors"
+exit $error_count
diff --git a/media/libeffects/lvm/tests/lvmtest.cpp b/media/libeffects/lvm/tests/lvmtest.cpp
new file mode 100644
index 0000000..5b58dd1
--- /dev/null
+++ b/media/libeffects/lvm/tests/lvmtest.cpp
@@ -0,0 +1,828 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <assert.h>
+#include <inttypes.h>
+#include <iterator>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <vector>
+
+#include <audio_utils/channels.h>
+#include <audio_utils/primitives.h>
+#include <log/log.h>
+#include <system/audio.h>
+
+#include "EffectBundle.h"
+#include "LVM_Private.h"
+
+#ifdef VERY_VERY_VERBOSE_LOGGING
+#define ALOGVV ALOGV
+#else
+#define ALOGVV(a...) \
+  do {               \
+  } while (false)
+#endif
+
+#define CHECK_ARG(cond)                                \
+  {                                                    \
+    if (!(cond)) {                                     \
+      ALOGE("\tLVM_ERROR : Invalid argument: " #cond); \
+      return -EINVAL;                                  \
+    }                                                  \
+  \
+}
+
+#define LVM_ERROR_CHECK(LvmStatus, callingFunc, calledFunc)     \
+  {                                                             \
+    if ((LvmStatus) == LVM_NULLADDRESS) {                       \
+      ALOGE(                                                    \
+          "\tLVM_ERROR : Parameter error - "                    \
+          "null pointer returned by %s in %s\n\n\n\n",          \
+          callingFunc, calledFunc);                             \
+    }                                                           \
+    if ((LvmStatus) == LVM_ALIGNMENTERROR) {                    \
+      ALOGE(                                                    \
+          "\tLVM_ERROR : Parameter error - "                    \
+          "bad alignment returned by %s in %s\n\n\n\n",         \
+          callingFunc, calledFunc);                             \
+    }                                                           \
+    if ((LvmStatus) == LVM_INVALIDNUMSAMPLES) {                 \
+      ALOGE(                                                    \
+          "\tLVM_ERROR : Parameter error - "                    \
+          "bad number of samples returned by %s in %s\n\n\n\n", \
+          callingFunc, calledFunc);                             \
+    }                                                           \
+    if ((LvmStatus) == LVM_OUTOFRANGE) {                        \
+      ALOGE(                                                    \
+          "\tLVM_ERROR : Parameter error - "                    \
+          "out of range returned by %s in %s\n",                \
+          callingFunc, calledFunc);                             \
+    }                                                           \
+  }
+
+struct lvmConfigParams_t {
+  int              samplingFreq    = 44100;
+  int              nrChannels      = 2;
+  int              chMask          = AUDIO_CHANNEL_OUT_STEREO;
+  int              vcBal           = 0;
+  int              fChannels       = 2;
+  bool             monoMode        = false;
+  int              bassEffectLevel = 0;
+  int              eqPresetLevel   = 0;
+  int              frameLength     = 256;
+  LVM_BE_Mode_en   bassEnable      = LVM_BE_OFF;
+  LVM_TE_Mode_en   trebleEnable    = LVM_TE_OFF;
+  LVM_EQNB_Mode_en eqEnable        = LVM_EQNB_OFF;
+  LVM_Mode_en      csEnable        = LVM_MODE_OFF;
+};
+
+constexpr audio_channel_mask_t lvmConfigChMask[] = {
+    AUDIO_CHANNEL_OUT_MONO,
+    AUDIO_CHANNEL_OUT_STEREO,
+    AUDIO_CHANNEL_OUT_2POINT1,
+    AUDIO_CHANNEL_OUT_2POINT0POINT2,
+    AUDIO_CHANNEL_OUT_QUAD,
+    AUDIO_CHANNEL_OUT_QUAD_BACK,
+    AUDIO_CHANNEL_OUT_QUAD_SIDE,
+    AUDIO_CHANNEL_OUT_SURROUND,
+    (1 << 4) - 1,
+    AUDIO_CHANNEL_OUT_2POINT1POINT2,
+    AUDIO_CHANNEL_OUT_3POINT0POINT2,
+    AUDIO_CHANNEL_OUT_PENTA,
+    (1 << 5) - 1,
+    AUDIO_CHANNEL_OUT_3POINT1POINT2,
+    AUDIO_CHANNEL_OUT_5POINT1,
+    AUDIO_CHANNEL_OUT_5POINT1_BACK,
+    AUDIO_CHANNEL_OUT_5POINT1_SIDE,
+    (1 << 6) - 1,
+    AUDIO_CHANNEL_OUT_6POINT1,
+    (1 << 7) - 1,
+    AUDIO_CHANNEL_OUT_5POINT1POINT2,
+    AUDIO_CHANNEL_OUT_7POINT1,
+    (1 << 8) - 1,
+};
+
+
+void printUsage() {
+  printf("\nUsage: ");
+  printf("\n     <executable> -i:<input_file> -o:<out_file> [options]\n");
+  printf("\nwhere, \n     <inputfile>  is the input file name");
+  printf("\n                  on which LVM effects are applied");
+  printf("\n     <outputfile> processed output file");
+  printf("\n     and options are mentioned below");
+  printf("\n");
+  printf("\n     -help (or) -h");
+  printf("\n           Prints this usage information");
+  printf("\n");
+  printf("\n     -chMask:<channel_mask>\n");
+  printf("\n         0  - AUDIO_CHANNEL_OUT_MONO");
+  printf("\n         1  - AUDIO_CHANNEL_OUT_STEREO");
+  printf("\n         2  - AUDIO_CHANNEL_OUT_2POINT1");
+  printf("\n         3  - AUDIO_CHANNEL_OUT_2POINT0POINT2");
+  printf("\n         4  - AUDIO_CHANNEL_OUT_QUAD");
+  printf("\n         5  - AUDIO_CHANNEL_OUT_QUAD_BACK");
+  printf("\n         6  - AUDIO_CHANNEL_OUT_QUAD_SIDE");
+  printf("\n         7  - AUDIO_CHANNEL_OUT_SURROUND");
+  printf("\n         8  - canonical channel index mask for 4 ch: (1 << 4) - 1");
+  printf("\n         9  - AUDIO_CHANNEL_OUT_2POINT1POINT2");
+  printf("\n         10 - AUDIO_CHANNEL_OUT_3POINT0POINT2");
+  printf("\n         11 - AUDIO_CHANNEL_OUT_PENTA");
+  printf("\n         12 - canonical channel index mask for 5 ch: (1 << 5) - 1");
+  printf("\n         13 - AUDIO_CHANNEL_OUT_3POINT1POINT2");
+  printf("\n         14 - AUDIO_CHANNEL_OUT_5POINT1");
+  printf("\n         15 - AUDIO_CHANNEL_OUT_5POINT1_BACK");
+  printf("\n         16 - AUDIO_CHANNEL_OUT_5POINT1_SIDE");
+  printf("\n         17 - canonical channel index mask for 6 ch: (1 << 6) - 1");
+  printf("\n         18 - AUDIO_CHANNEL_OUT_6POINT1");
+  printf("\n         19 - canonical channel index mask for 7 ch: (1 << 7) - 1");
+  printf("\n         20 - AUDIO_CHANNEL_OUT_5POINT1POINT2");
+  printf("\n         21 - AUDIO_CHANNEL_OUT_7POINT1");
+  printf("\n         22 - canonical channel index mask for 8 ch: (1 << 8) - 1");
+  printf("\n         default 0");
+  printf("\n     -vcBal:<Left Right Balance control in dB [-96 to 96 dB]>");
+  printf("\n            -ve values reduce Right channel while +ve value reduces Left channel");
+  printf("\n                 default 0");
+  printf("\n     -fch:<file_channels> (1 through 8)\n\n");
+  printf("\n     -M");
+  printf("\n           Mono mode (force all input audio channels to be identical)");
+  printf("\n     -basslvl:<effect_level>");
+  printf("\n           A value that ranges between %d - %d default 0", LVM_BE_MIN_EFFECTLEVEL,
+    LVM_BE_MAX_EFFECTLEVEL);
+  printf("\n");
+  printf("\n     -eqPreset:<preset Value>");
+  const size_t numPresetLvls  = std::size(gEqualizerPresets);
+  for (size_t i = 0; i < numPresetLvls; ++i) {
+    printf("\n           %zu - %s", i, gEqualizerPresets[i].name);
+  }
+  printf("\n           default - 0");
+  printf("\n     -bE ");
+  printf("\n           Enable Dynamic Bass Enhancement");
+  printf("\n");
+  printf("\n     -tE ");
+  printf("\n           Enable Treble Boost");
+  printf("\n");
+  printf("\n     -csE ");
+  printf("\n           Enable Concert Surround");
+  printf("\n");
+  printf("\n     -eqE ");
+  printf("\n           Enable Equalizer");
+}
+
+//----------------------------------------------------------------------------
+// LvmEffect_free()
+//----------------------------------------------------------------------------
+// Purpose: Free all memory associated with the Bundle.
+//
+// Inputs:
+//  pContext:   effect engine context
+//
+// Outputs:
+//
+//----------------------------------------------------------------------------
+
+void LvmEffect_free(struct EffectContext *pContext) {
+  LVM_ReturnStatus_en LvmStatus = LVM_SUCCESS; /* Function call status */
+  LVM_MemTab_t MemTab;
+
+  /* Free the algorithm memory */
+  LvmStatus = LVM_GetMemoryTable(pContext->pBundledContext->hInstance, &MemTab,
+                                 LVM_NULL);
+
+  LVM_ERROR_CHECK(LvmStatus, "LVM_GetMemoryTable", "LvmEffect_free")
+
+  for (int i = 0; i < LVM_NR_MEMORY_REGIONS; i++) {
+    if (MemTab.Region[i].Size != 0) {
+      if (MemTab.Region[i].pBaseAddress != NULL) {
+        ALOGV("\tLvmEffect_free - START freeing %" PRIu32
+              " bytes for region %u at %p\n",
+              MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
+
+        free(MemTab.Region[i].pBaseAddress);
+
+        ALOGV("\tLvmEffect_free - END   freeing %" PRIu32
+              " bytes for region %u at %p\n",
+              MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
+      } else {
+        ALOGE(
+            "\tLVM_ERROR : LvmEffect_free - trying to free with NULL pointer "
+            "%" PRIu32 " bytes for region %u at %p ERROR\n",
+            MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
+      }
+    }
+  }
+} /* end LvmEffect_free */
+
+//----------------------------------------------------------------------------
+// LvmBundle_init()
+//----------------------------------------------------------------------------
+// Purpose: Initialize engine with default configuration, creates instance
+// with all effects disabled.
+//
+// Inputs:
+//  pContext:   effect engine context
+//
+// Outputs:
+//
+//----------------------------------------------------------------------------
+
+int LvmBundle_init(struct EffectContext *pContext, LVM_ControlParams_t *params) {
+  ALOGV("\tLvmBundle_init start");
+
+  pContext->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
+  pContext->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+  pContext->config.inputCfg.format = EFFECT_BUFFER_FORMAT;
+  pContext->config.inputCfg.samplingRate = 44100;
+  pContext->config.inputCfg.bufferProvider.getBuffer = NULL;
+  pContext->config.inputCfg.bufferProvider.releaseBuffer = NULL;
+  pContext->config.inputCfg.bufferProvider.cookie = NULL;
+  pContext->config.inputCfg.mask = EFFECT_CONFIG_ALL;
+  pContext->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
+  pContext->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+  pContext->config.outputCfg.format = EFFECT_BUFFER_FORMAT;
+  pContext->config.outputCfg.samplingRate = 44100;
+  pContext->config.outputCfg.bufferProvider.getBuffer = NULL;
+  pContext->config.outputCfg.bufferProvider.releaseBuffer = NULL;
+  pContext->config.outputCfg.bufferProvider.cookie = NULL;
+  pContext->config.outputCfg.mask = EFFECT_CONFIG_ALL;
+
+  if (pContext->pBundledContext->hInstance != NULL) {
+    ALOGV(
+        "\tLvmBundle_init pContext->pBassBoost != NULL "
+        "-> Calling pContext->pBassBoost->free()");
+
+    LvmEffect_free(pContext);
+
+    ALOGV(
+        "\tLvmBundle_init pContext->pBassBoost != NULL "
+        "-> Called pContext->pBassBoost->free()");
+  }
+
+  LVM_ReturnStatus_en LvmStatus = LVM_SUCCESS; /* Function call status */
+  LVM_InstParams_t InstParams;                 /* Instance parameters */
+  LVM_EQNB_BandDef_t BandDefs[MAX_NUM_BANDS];  /* Equaliser band definitions */
+  LVM_HeadroomParams_t HeadroomParams;         /* Headroom parameters */
+  LVM_HeadroomBandDef_t HeadroomBandDef[LVM_HEADROOM_MAX_NBANDS];
+  LVM_MemTab_t MemTab; /* Memory allocation table */
+  bool bMallocFailure = LVM_FALSE;
+
+  /* Set the capabilities */
+  InstParams.BufferMode = LVM_UNMANAGED_BUFFERS;
+  InstParams.MaxBlockSize = MAX_CALL_SIZE;
+  InstParams.EQNB_NumBands = MAX_NUM_BANDS;
+  InstParams.PSA_Included = LVM_PSA_ON;
+
+  /* Allocate memory, forcing alignment */
+  LvmStatus = LVM_GetMemoryTable(LVM_NULL, &MemTab, &InstParams);
+
+  LVM_ERROR_CHECK(LvmStatus, "LVM_GetMemoryTable", "LvmBundle_init");
+  if (LvmStatus != LVM_SUCCESS) return -EINVAL;
+
+  ALOGV("\tCreateInstance Succesfully called LVM_GetMemoryTable\n");
+
+  /* Allocate memory */
+  for (int i = 0; i < LVM_NR_MEMORY_REGIONS; i++) {
+    if (MemTab.Region[i].Size != 0) {
+      MemTab.Region[i].pBaseAddress = malloc(MemTab.Region[i].Size);
+
+      if (MemTab.Region[i].pBaseAddress == LVM_NULL) {
+        ALOGE(
+            "\tLVM_ERROR :LvmBundle_init CreateInstance Failed to allocate "
+            "%" PRIu32 " bytes for region %u\n",
+            MemTab.Region[i].Size, i);
+        bMallocFailure = LVM_TRUE;
+        break;
+      } else {
+        ALOGV("\tLvmBundle_init CreateInstance allocated %" PRIu32
+              " bytes for region %u at %p\n",
+              MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
+      }
+    }
+  }
+
+  /* If one or more of the memory regions failed to allocate, free the regions
+   * that were
+   * succesfully allocated and return with an error
+   */
+  if (bMallocFailure == LVM_TRUE) {
+    for (int i = 0; i < LVM_NR_MEMORY_REGIONS; i++) {
+      if (MemTab.Region[i].pBaseAddress == LVM_NULL) {
+        ALOGE(
+            "\tLVM_ERROR :LvmBundle_init CreateInstance Failed to allocate "
+            "%" PRIu32 " bytes for region %u Not freeing\n",
+            MemTab.Region[i].Size, i);
+      } else {
+        ALOGE(
+            "\tLVM_ERROR :LvmBundle_init CreateInstance Failed: but allocated "
+            "%" PRIu32 " bytes for region %u at %p- free\n",
+            MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
+        free(MemTab.Region[i].pBaseAddress);
+      }
+    }
+    return -EINVAL;
+  }
+  ALOGV("\tLvmBundle_init CreateInstance Succesfully malloc'd memory\n");
+
+  /* Initialise */
+  pContext->pBundledContext->hInstance = LVM_NULL;
+
+  /* Init sets the instance handle */
+  LvmStatus = LVM_GetInstanceHandle(&pContext->pBundledContext->hInstance,
+                                    &MemTab, &InstParams);
+
+  LVM_ERROR_CHECK(LvmStatus, "LVM_GetInstanceHandle", "LvmBundle_init");
+  if (LvmStatus != LVM_SUCCESS) return -EINVAL;
+
+  ALOGV(
+      "\tLvmBundle_init CreateInstance Succesfully called "
+      "LVM_GetInstanceHandle\n");
+
+  /* Set the initial process parameters */
+  /* General parameters */
+  params->OperatingMode = LVM_MODE_ON;
+  params->SampleRate = LVM_FS_44100;
+  params->SourceFormat = LVM_STEREO;
+  params->ChMask       = AUDIO_CHANNEL_OUT_STEREO;
+  params->SpeakerType = LVM_HEADPHONES;
+
+  pContext->pBundledContext->SampleRate = LVM_FS_44100;
+
+  /* Concert Sound parameters */
+  params->VirtualizerOperatingMode = LVM_MODE_OFF;
+  params->VirtualizerType = LVM_CONCERTSOUND;
+  params->VirtualizerReverbLevel = 100;
+  params->CS_EffectLevel = LVM_CS_EFFECT_NONE;
+
+  /* N-Band Equaliser parameters */
+  params->EQNB_OperatingMode = LVM_EQNB_ON;
+  params->EQNB_NBands = FIVEBAND_NUMBANDS;
+  params->pEQNB_BandDefinition = &BandDefs[0];
+
+  for (int i = 0; i < FIVEBAND_NUMBANDS; i++) {
+    BandDefs[i].Frequency = EQNB_5BandPresetsFrequencies[i];
+    BandDefs[i].QFactor = EQNB_5BandPresetsQFactors[i];
+    BandDefs[i].Gain = EQNB_5BandSoftPresets[i];
+  }
+
+  /* Volume Control parameters */
+  params->VC_EffectLevel = 0;
+  params->VC_Balance = 0;
+
+  /* Treble Enhancement parameters */
+  params->TE_OperatingMode = LVM_TE_OFF;
+  params->TE_EffectLevel = 0;
+
+  /* PSA Control parameters */
+  params->PSA_Enable = LVM_PSA_OFF;
+  params->PSA_PeakDecayRate = (LVM_PSA_DecaySpeed_en)0;
+
+  /* Bass Enhancement parameters */
+  params->BE_OperatingMode = LVM_BE_ON;
+  params->BE_EffectLevel = 0;
+  params->BE_CentreFreq = LVM_BE_CENTRE_90Hz;
+  params->BE_HPF = LVM_BE_HPF_ON;
+
+  /* PSA Control parameters */
+  params->PSA_Enable = LVM_PSA_OFF;
+  params->PSA_PeakDecayRate = LVM_PSA_SPEED_MEDIUM;
+
+  /* TE Control parameters */
+  params->TE_OperatingMode = LVM_TE_OFF;
+  params->TE_EffectLevel = 0;
+
+  /* Activate the initial settings */
+  LvmStatus =
+      LVM_SetControlParameters(pContext->pBundledContext->hInstance, params);
+
+  LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "LvmBundle_init");
+  if (LvmStatus != LVM_SUCCESS) return -EINVAL;
+
+  ALOGV(
+      "\tLvmBundle_init CreateInstance Succesfully called "
+      "LVM_SetControlParameters\n");
+
+  /* Set the headroom parameters */
+  HeadroomBandDef[0].Limit_Low = 20;
+  HeadroomBandDef[0].Limit_High = 4999;
+  HeadroomBandDef[0].Headroom_Offset = 0;
+  HeadroomBandDef[1].Limit_Low = 5000;
+  HeadroomBandDef[1].Limit_High = 24000;
+  HeadroomBandDef[1].Headroom_Offset = 0;
+  HeadroomParams.pHeadroomDefinition = &HeadroomBandDef[0];
+  HeadroomParams.Headroom_OperatingMode = LVM_HEADROOM_ON;
+  HeadroomParams.NHeadroomBands = 2;
+
+  LvmStatus = LVM_SetHeadroomParams(pContext->pBundledContext->hInstance,
+                                    &HeadroomParams);
+
+  LVM_ERROR_CHECK(LvmStatus, "LVM_SetHeadroomParams", "LvmBundle_init");
+  if (LvmStatus != LVM_SUCCESS) return -EINVAL;
+
+  ALOGV(
+      "\tLvmBundle_init CreateInstance Succesfully called "
+      "LVM_SetHeadroomParams\n");
+  ALOGV("\tLvmBundle_init End");
+  return 0;
+} /* end LvmBundle_init */
+
+int lvmCreate(struct EffectContext *pContext,
+              lvmConfigParams_t    *plvmConfigParams,
+              LVM_ControlParams_t  *params) {
+  int ret = 0;
+  pContext->pBundledContext = NULL;
+  pContext->pBundledContext = (BundledEffectContext *)malloc(sizeof(struct BundledEffectContext));
+  if (NULL == pContext->pBundledContext) {
+    return -EINVAL;
+  }
+
+  pContext->pBundledContext->SessionNo = 0;
+  pContext->pBundledContext->SessionId = 0;
+  pContext->pBundledContext->hInstance = NULL;
+  pContext->pBundledContext->bVolumeEnabled = LVM_FALSE;
+  pContext->pBundledContext->bEqualizerEnabled = LVM_FALSE;
+  pContext->pBundledContext->bBassEnabled = LVM_FALSE;
+  pContext->pBundledContext->bBassTempDisabled = LVM_FALSE;
+  pContext->pBundledContext->bVirtualizerEnabled = LVM_FALSE;
+  pContext->pBundledContext->bVirtualizerTempDisabled = LVM_FALSE;
+  pContext->pBundledContext->nOutputDevice = AUDIO_DEVICE_NONE;
+  pContext->pBundledContext->nVirtualizerForcedDevice = AUDIO_DEVICE_NONE;
+  pContext->pBundledContext->NumberEffectsEnabled = 0;
+  pContext->pBundledContext->NumberEffectsCalled = 0;
+  pContext->pBundledContext->firstVolume = LVM_TRUE;
+  pContext->pBundledContext->volume = 0;
+
+  /* Saved strength is used to return the exact strength that was used in the
+   * set to the get
+   * because we map the original strength range of 0:1000 to 1:15, and this will
+   * avoid
+   * quantisation like effect when returning
+   */
+  pContext->pBundledContext->BassStrengthSaved = 0;
+  pContext->pBundledContext->VirtStrengthSaved = 0;
+  pContext->pBundledContext->CurPreset = PRESET_CUSTOM;
+  pContext->pBundledContext->levelSaved = 0;
+  pContext->pBundledContext->bMuteEnabled = LVM_FALSE;
+  pContext->pBundledContext->bStereoPositionEnabled = LVM_FALSE;
+  pContext->pBundledContext->positionSaved = 0;
+  pContext->pBundledContext->workBuffer = NULL;
+  pContext->pBundledContext->frameCount = -1;
+  pContext->pBundledContext->SamplesToExitCountVirt = 0;
+  pContext->pBundledContext->SamplesToExitCountBb = 0;
+  pContext->pBundledContext->SamplesToExitCountEq = 0;
+#if defined(BUILD_FLOAT) && !defined(NATIVE_FLOAT_BUFFER)
+  pContext->pBundledContext->pInputBuffer = NULL;
+  pContext->pBundledContext->pOutputBuffer = NULL;
+#endif
+  for (int i = 0; i < FIVEBAND_NUMBANDS; i++) {
+    pContext->pBundledContext->bandGaindB[i] = EQNB_5BandSoftPresets[i];
+  }
+  pContext->config.inputCfg.channels = plvmConfigParams->nrChannels;
+  ALOGV("\tEffectCreate - Calling LvmBundle_init");
+  ret = LvmBundle_init(pContext, params);
+
+  if (ret < 0) {
+    ALOGE("\tLVM_ERROR : lvmCreate() Bundle init failed");
+    return ret;
+  }
+  return 0;
+}
+
+int lvmControl(struct EffectContext *pContext,
+               lvmConfigParams_t    *plvmConfigParams,
+               LVM_ControlParams_t  *params) {
+  LVM_ReturnStatus_en LvmStatus = LVM_SUCCESS; /* Function call status */
+
+  /* Set the initial process parameters */
+  /* General parameters */
+  params->OperatingMode = LVM_MODE_ON;
+  params->SpeakerType = LVM_HEADPHONES;
+
+  params->ChMask     = plvmConfigParams->chMask;
+  params->NrChannels = plvmConfigParams->nrChannels;
+  if (params->NrChannels == 1) {
+    params->SourceFormat = LVM_MONO;
+  } else if (params->NrChannels == 2) {
+    params->SourceFormat = LVM_STEREO;
+  } else if (params->NrChannels > 2 && params->NrChannels <= 8) { // FCC_2 FCC_8
+    params->SourceFormat = LVM_MULTICHANNEL;
+  } else {
+      return -EINVAL;
+  }
+
+  LVM_Fs_en sampleRate;
+  switch (plvmConfigParams->samplingFreq) {
+    case 8000:
+      sampleRate = LVM_FS_8000;
+      break;
+    case 11025:
+      sampleRate = LVM_FS_11025;
+      break;
+    case 12000:
+      sampleRate = LVM_FS_12000;
+      break;
+    case 16000:
+      sampleRate = LVM_FS_16000;
+      break;
+    case 22050:
+      sampleRate = LVM_FS_22050;
+      break;
+    case 24000:
+      sampleRate = LVM_FS_24000;
+      break;
+    case 32000:
+      sampleRate = LVM_FS_32000;
+      break;
+    case 44100:
+      sampleRate = LVM_FS_44100;
+      break;
+    case 48000:
+      sampleRate = LVM_FS_48000;
+      break;
+    case 88200:
+      sampleRate = LVM_FS_88200;
+      break;
+    case 96000:
+      sampleRate = LVM_FS_96000;
+      break;
+    case 176400:
+      sampleRate = LVM_FS_176400;
+      break;
+    case 192000:
+      sampleRate = LVM_FS_192000;
+      break;
+    default:
+      return -EINVAL;
+  }
+  params->SampleRate = sampleRate;
+
+  /* Concert Sound parameters */
+  params->VirtualizerOperatingMode = plvmConfigParams->csEnable;
+  params->VirtualizerType = LVM_CONCERTSOUND;
+  params->VirtualizerReverbLevel = 100;
+  params->CS_EffectLevel = LVM_CS_EFFECT_NONE;
+
+  /* N-Band Equaliser parameters */
+  const int eqPresetLevel = plvmConfigParams->eqPresetLevel;
+  LVM_EQNB_BandDef_t BandDefs[MAX_NUM_BANDS];  /* Equaliser band definitions */
+  for (int i = 0; i < FIVEBAND_NUMBANDS; i++) {
+    BandDefs[i].Frequency = EQNB_5BandPresetsFrequencies[i];
+    BandDefs[i].QFactor = EQNB_5BandPresetsQFactors[i];
+    BandDefs[i].Gain =
+        EQNB_5BandSoftPresets[(FIVEBAND_NUMBANDS * eqPresetLevel) + i];
+  }
+  params->EQNB_OperatingMode = plvmConfigParams->eqEnable;
+ // Caution: raw pointer to stack data, stored in instance by LVM_SetControlParameters.
+  params->pEQNB_BandDefinition = &BandDefs[0];
+
+  /* Volume Control parameters */
+  params->VC_EffectLevel = 0;
+  params->VC_Balance = plvmConfigParams->vcBal;
+
+  /* Treble Enhancement parameters */
+  params->TE_OperatingMode = plvmConfigParams->trebleEnable;
+
+  /* PSA Control parameters */
+  params->PSA_Enable = LVM_PSA_ON;
+
+  /* Bass Enhancement parameters */
+  params->BE_OperatingMode = plvmConfigParams->bassEnable;
+
+  /* Activate the initial settings */
+  LvmStatus =
+      LVM_SetControlParameters(pContext->pBundledContext->hInstance, params);
+
+  LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "LvmBundle_init");
+  if (LvmStatus != LVM_SUCCESS) return -EINVAL;
+
+  LvmStatus = LVM_ApplyNewSettings(pContext->pBundledContext->hInstance);
+
+  if (LvmStatus != LVM_SUCCESS) return -EINVAL;
+
+  return 0;
+}
+
+int lvmExecute(float *floatIn, float *floatOut, struct EffectContext *pContext,
+               lvmConfigParams_t *plvmConfigParams) {
+  const int frameLength = plvmConfigParams->frameLength;
+  return
+      LVM_Process(pContext->pBundledContext->hInstance, /* Instance handle */
+                  floatIn,                              /* Input buffer */
+                  floatOut,                             /* Output buffer */
+                  (LVM_UINT16)frameLength, /* Number of samples to read */
+                  0);                      /* Audio Time */
+}
+
+int lvmMainProcess(EffectContext *pContext,
+                   LVM_ControlParams_t *pParams,
+                   lvmConfigParams_t *plvmConfigParams,
+                   FILE *finp,
+                   FILE *fout) {
+  int errCode = lvmControl(pContext, plvmConfigParams, pParams);
+  if (errCode) {
+    ALOGE("Error: lvmControl returned with %d\n", errCode);
+    return errCode;
+  }
+
+  const int channelCount = plvmConfigParams->nrChannels;
+  const int frameLength = plvmConfigParams->frameLength;
+  const int frameSize = channelCount * sizeof(float);  // processing size
+  const int ioChannelCount = plvmConfigParams->fChannels;
+  const int ioFrameSize = ioChannelCount * sizeof(short); // file load size
+  const int maxChannelCount = std::max(channelCount, ioChannelCount);
+  /*
+   * Mono input will be converted to 2 channels internally in the process call
+   * by copying the same data into the second channel.
+   * Hence when channelCount is 1, output buffer should be allocated for
+   * 2 channels. The memAllocChCount takes care of allocation of sufficient
+   * memory for the output buffer.
+   */
+  const int memAllocChCount = (channelCount == 1 ? 2 : channelCount);
+
+  std::vector<short> in(frameLength * maxChannelCount);
+  std::vector<short> out(frameLength * maxChannelCount);
+  std::vector<float> floatIn(frameLength * channelCount);
+  std::vector<float> floatOut(frameLength * memAllocChCount);
+
+  int frameCounter = 0;
+  while (fread(in.data(), ioFrameSize, frameLength, finp) == (size_t)frameLength) {
+    if (ioChannelCount != channelCount) {
+        adjust_channels(in.data(), ioChannelCount, in.data(), channelCount,
+               sizeof(short), frameLength * ioFrameSize);
+    }
+    memcpy_to_float_from_i16(floatIn.data(), in.data(), frameLength * channelCount);
+
+    // Mono mode will replicate the first channel to all other channels.
+    // This ensures all audio channels are identical. This is useful for testing
+    // Bass Boost, which extracts a mono signal for processing.
+    if (plvmConfigParams->monoMode && channelCount > 1) {
+        for (int i = 0; i < frameLength; ++i) {
+            auto *fp = &floatIn[i * channelCount];
+            std::fill(fp + 1, fp + channelCount, *fp); // replicate ch 0
+        }
+    }
+#ifndef BYPASS_EXEC
+    errCode = lvmExecute(floatIn.data(), floatOut.data(), pContext, plvmConfigParams);
+    if (errCode) {
+      printf("\nError: lvmExecute returned with %d\n", errCode);
+      return errCode;
+    }
+
+    (void)frameSize; // eliminate warning
+#else
+    memcpy(floatOut.data(), floatIn.data(), frameLength * frameSize);
+#endif
+    memcpy_to_i16_from_float(out.data(), floatOut.data(), frameLength * channelCount);
+    if (ioChannelCount != channelCount) {
+        adjust_channels(out.data(), channelCount, out.data(), ioChannelCount,
+               sizeof(short), frameLength * channelCount * sizeof(short));
+    }
+    (void) fwrite(out.data(), ioFrameSize, frameLength, fout);
+    frameCounter += frameLength;
+  }
+  printf("frameCounter: [%d]\n", frameCounter);
+  return 0;
+}
+
+int main(int argc, const char *argv[]) {
+  if (argc == 1) {
+    printUsage();
+    return -1;
+  }
+
+  lvmConfigParams_t lvmConfigParams{}; // default initialize
+  const char *infile = nullptr;
+  const char *outfile = nullptr;
+
+  for (int i = 1; i < argc; i++) {
+    printf("%s ", argv[i]);
+    if (!strncmp(argv[i], "-i:", 3)) {
+      infile = argv[i] + 3;
+    } else if (!strncmp(argv[i], "-o:", 3)) {
+      outfile = argv[i] + 3;
+    } else if (!strncmp(argv[i], "-fs:", 4)) {
+      const int samplingFreq = atoi(argv[i] + 4);
+      if (samplingFreq != 8000 && samplingFreq != 11025 &&
+          samplingFreq != 12000 && samplingFreq != 16000 &&
+          samplingFreq != 22050 && samplingFreq != 24000 &&
+          samplingFreq != 32000 && samplingFreq != 44100 &&
+          samplingFreq != 48000 && samplingFreq != 88200 &&
+          samplingFreq != 96000 && samplingFreq != 176400 &&
+          samplingFreq != 192000) {
+        printf("Error: Unsupported Sampling Frequency : %d\n", samplingFreq);
+        return -1;
+      }
+      lvmConfigParams.samplingFreq = samplingFreq;
+    } else if (!strncmp(argv[i], "-chMask:", 8)) {
+      const int chMaskConfigIdx = atoi(argv[i] + 8);
+      if (chMaskConfigIdx < 0 || (size_t)chMaskConfigIdx >= std::size(lvmConfigChMask)) {
+        ALOGE("\nError: Unsupported Channel Mask : %d\n", chMaskConfigIdx);
+        return -1;
+      }
+      const audio_channel_mask_t chMask = lvmConfigChMask[chMaskConfigIdx];
+      lvmConfigParams.chMask = chMask;
+      lvmConfigParams.nrChannels = audio_channel_count_from_out_mask(chMask);
+    } else if (!strncmp(argv[i], "-vcBal:", 7)) {
+      const int vcBalance = atoi(argv[i] + 7);
+      if (vcBalance > 96 || vcBalance < -96) {
+        ALOGE("\nError: Unsupported volume balance value: %d\n", vcBalance);
+      }
+      lvmConfigParams.vcBal = vcBalance;
+    } else if (!strncmp(argv[i], "-fch:", 5)) {
+      const int fChannels = atoi(argv[i] + 5);
+      if (fChannels > 8 || fChannels < 1) {
+             printf("Error: Unsupported number of file channels : %d\n", fChannels);
+             return -1;
+           }
+           lvmConfigParams.fChannels = fChannels;
+    } else if (!strcmp(argv[i],"-M")) {
+          lvmConfigParams.monoMode = true;
+    } else if (!strncmp(argv[i], "-basslvl:", 9)) {
+      const int bassEffectLevel = atoi(argv[i] + 9);
+      if (bassEffectLevel > LVM_BE_MAX_EFFECTLEVEL || bassEffectLevel < LVM_BE_MIN_EFFECTLEVEL) {
+        printf("Error: Unsupported Bass Effect Level : %d\n",
+               bassEffectLevel);
+        printUsage();
+        return -1;
+      }
+      lvmConfigParams.bassEffectLevel = bassEffectLevel;
+    } else if (!strncmp(argv[i], "-eqPreset:", 10)) {
+      const int eqPresetLevel = atoi(argv[i] + 10);
+      const int numPresetLvls = std::size(gEqualizerPresets);
+      if (eqPresetLevel >= numPresetLvls || eqPresetLevel < 0) {
+        printf("Error: Unsupported Equalizer Preset : %d\n", eqPresetLevel);
+        printUsage();
+        return -1;
+      }
+      lvmConfigParams.eqPresetLevel = eqPresetLevel;
+    } else if (!strcmp(argv[i], "-bE")) {
+      lvmConfigParams.bassEnable = LVM_BE_ON;
+    } else if (!strcmp(argv[i], "-eqE")) {
+      lvmConfigParams.eqEnable = LVM_EQNB_ON;
+    } else if (!strcmp(argv[i], "-tE")) {
+      lvmConfigParams.trebleEnable = LVM_TE_ON;
+    } else if (!strcmp(argv[i], "-csE")) {
+      lvmConfigParams.csEnable = LVM_MODE_ON;
+    } else if (!strcmp(argv[i], "-h")) {
+      printUsage();
+      return 0;
+    }
+  }
+
+  if (infile == nullptr || outfile == nullptr) {
+    printf("Error: missing input/output files\n");
+    printUsage();
+    return -1;
+  }
+
+  FILE *finp = fopen(infile, "rb");
+  if (finp == nullptr) {
+    printf("Cannot open input file %s", infile);
+    return -1;
+  }
+
+  FILE *fout = fopen(outfile, "wb");
+  if (fout == nullptr) {
+    printf("Cannot open output file %s", outfile);
+    fclose(finp);
+    return -1;
+  }
+
+  EffectContext context;
+  LVM_ControlParams_t params;
+  int errCode = lvmCreate(&context, &lvmConfigParams, &params);
+  if (errCode == 0) {
+    errCode = lvmMainProcess(&context, &params, &lvmConfigParams, finp, fout);
+    if (errCode != 0) {
+      printf("Error: lvmMainProcess returned with the error: %d",errCode);
+    }
+  } else {
+    printf("Error: lvmCreate returned with the error: %d", errCode);
+  }
+  fclose(finp);
+  fclose(fout);
+  /* Free the allocated buffers */
+  if (context.pBundledContext != nullptr) {
+    if (context.pBundledContext->hInstance != nullptr) {
+      LvmEffect_free(&context);
+    }
+    free(context.pBundledContext);
+  }
+
+  if (errCode) {
+    return -1;
+  }
+  return 0;
+}
diff --git a/media/libeffects/lvm/tests/snr.cpp b/media/libeffects/lvm/tests/snr.cpp
new file mode 100644
index 0000000..885994c
--- /dev/null
+++ b/media/libeffects/lvm/tests/snr.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <assert.h>
+#include <inttypes.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <vector>
+
+template <typename T, typename A = float>
+std::pair<A, A> getSignalNoise(FILE *finp, FILE *fref) {
+  constexpr size_t framesize = 256;
+  std::vector<T> in(framesize);
+  std::vector<T> ref(framesize);
+  A signal{};
+  A noise{};
+
+  for (;;) {
+    size_t read_samples_in = fread(&in[0], sizeof(T), framesize, finp);
+    const size_t read_samples_ref = fread(&ref[0], sizeof(T), framesize, fref);
+    if (read_samples_in != read_samples_ref) {
+      printf("file sizes do not match (last %zu %zu)", read_samples_in, read_samples_ref);
+      read_samples_in = std::min(read_samples_in, read_samples_ref);
+    }
+    if (read_samples_in == 0) {
+        return { signal, noise };
+    }
+    for (size_t i = 0; i < read_samples_in; ++i) {
+       const A value(ref[i]);
+       const A diff(A(in[i]) - value);
+       signal += value * value;
+       noise += diff * diff;
+    }
+  }
+}
+
+void printUsage() {
+  printf("\nUsage: ");
+  printf("\n     snr <ref_file> <test_file> [options]\n");
+  printf("\nwhere, \n     <ref_file>  is the reference file name");
+  printf("\n                  on which will be taken as pure signal");
+  printf("\n     <test_file> is test file for snr calculation");
+  printf("\n     and options are mentioned below");
+  printf("\n");
+  printf("\n     -pcm_format:<pcm format of input files>");
+  printf("\n           0 - 16 bit pcm");
+  printf("\n           1 - 32 bit float");
+  printf("\n           default 0");
+  printf("\n     -thr:<threshold value>");
+  printf("\n           default - negative infinity\n\n");
+}
+
+int main(int argc, const char *argv[]) {
+  if (argc < 3) {
+    printUsage();
+    return -1;
+  }
+  int pcm_format = 0;
+  float thr = - std::numeric_limits<float>::infinity();
+  FILE *fref = fopen(argv[1], "rb");
+  FILE *finp = fopen(argv[2], "rb");
+  for (int i = 3; i < argc; i++) {
+    if (!strncmp(argv[i], "-pcm_format:", 12)) {
+      pcm_format = atoi(argv[i] + 12);
+    } else if (!strncmp(argv[i], "-thr:", 5)) {
+      thr = atof(argv[i] + 5);
+    }
+  }
+  if (finp == nullptr || fref == nullptr) {
+    printf("\nError: missing input/reference files\n");
+    return -1;
+  }
+  int ret = EXIT_SUCCESS;
+  auto sn = pcm_format == 0
+      ? getSignalNoise<short>(finp, fref)
+      : getSignalNoise<float>(finp, fref);
+  if (sn.first > 0.f && sn.second > 0.f) {
+    float snr = 10.f * log(sn.first / sn.second);
+    // compare the measured snr value with threshold
+    if (snr < thr) {
+      printf("%.6f less than threshold %.6f\n", snr, thr);
+      ret = EXIT_FAILURE;
+    } else {
+      printf("%.6f\n", snr);
+    }
+  }
+  fclose(finp);
+  fclose(fref);
+
+  return ret;
+}
diff --git a/media/libeffects/lvm/wrapper/Android.bp b/media/libeffects/lvm/wrapper/Android.bp
new file mode 100644
index 0000000..16fa126
--- /dev/null
+++ b/media/libeffects/lvm/wrapper/Android.bp
@@ -0,0 +1,89 @@
+// The wrapper -DBUILD_FLOAT needs to match
+// the lvm library -DBUILD_FLOAT.
+
+// music bundle wrapper
+cc_library_shared {
+    name: "libbundlewrapper",
+
+    arch: {
+        arm: {
+            instruction_set: "arm",
+        },
+    },
+
+    vendor: true,
+    srcs: ["Bundle/EffectBundle.cpp"],
+
+    cflags: [
+        "-fvisibility=hidden",
+        "-DBUILD_FLOAT",
+        "-DHIGHER_FS",
+        "-DSUPPORT_MC",
+
+        "-Wall",
+        "-Werror",
+    ],
+
+    relative_install_path: "soundfx",
+
+    static_libs: ["libmusicbundle"],
+
+    shared_libs: [
+        "libaudioutils",
+        "libcutils",
+        "libdl",
+        "liblog",
+    ],
+
+    local_include_dirs: ["Bundle"],
+
+    header_libs: [
+        "libhardware_headers",
+        "libaudioeffects",
+    ],
+}
+
+// reverb wrapper
+cc_library_shared {
+    name: "libreverbwrapper",
+
+    arch: {
+        arm: {
+            instruction_set: "arm",
+        },
+    },
+
+    vendor: true,
+    srcs: ["Reverb/EffectReverb.cpp"],
+
+    cflags: [
+        "-fvisibility=hidden",
+        "-DBUILD_FLOAT",
+        "-DHIGHER_FS",
+
+        "-Wall",
+        "-Werror",
+    ],
+
+    relative_install_path: "soundfx",
+
+    static_libs: ["libreverb"],
+
+    shared_libs: [
+        "libaudioutils",
+        "libcutils",
+        "libdl",
+        "liblog",
+    ],
+
+    local_include_dirs: ["Reverb"],
+
+    header_libs: [
+        "libhardware_headers",
+        "libaudioeffects",
+    ],
+
+    sanitize: {
+        integer_overflow: true,
+    },
+}
diff --git a/media/libeffects/lvm/wrapper/Android.mk b/media/libeffects/lvm/wrapper/Android.mk
deleted file mode 100644
index 341dbc2..0000000
--- a/media/libeffects/lvm/wrapper/Android.mk
+++ /dev/null
@@ -1,77 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-# The wrapper -DBUILD_FLOAT needs to match
-# the lvm library -DBUILD_FLOAT.
-
-# music bundle wrapper
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_ARM_MODE := arm
-
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES:= \
-	Bundle/EffectBundle.cpp
-
-LOCAL_CFLAGS += -fvisibility=hidden -DBUILD_FLOAT -DHIGHER_FS
-LOCAL_CFLAGS += -Wall -Werror
-
-LOCAL_MODULE:= libbundlewrapper
-
-LOCAL_MODULE_RELATIVE_PATH := soundfx
-
-LOCAL_STATIC_LIBRARIES += libmusicbundle
-
-LOCAL_SHARED_LIBRARIES := \
-     libaudioutils \
-     libcutils \
-     libdl \
-     liblog \
-
-LOCAL_C_INCLUDES += \
-	$(LOCAL_PATH)/Bundle \
-	$(LOCAL_PATH)/../lib/Common/lib/ \
-	$(LOCAL_PATH)/../lib/Bundle/lib/ \
-	$(call include-path-for, audio-effects) \
-	$(call include-path-for, audio-utils) \
-
-LOCAL_HEADER_LIBRARIES += libhardware_headers
-include $(BUILD_SHARED_LIBRARY)
-
-
-# reverb wrapper
-include $(CLEAR_VARS)
-
-LOCAL_ARM_MODE := arm
-
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES:= \
-    Reverb/EffectReverb.cpp
-
-LOCAL_CFLAGS += -fvisibility=hidden -DBUILD_FLOAT -DHIGHER_FS
-LOCAL_CFLAGS += -Wall -Werror
-
-LOCAL_MODULE:= libreverbwrapper
-
-LOCAL_MODULE_RELATIVE_PATH := soundfx
-
-LOCAL_STATIC_LIBRARIES += libreverb
-
-LOCAL_SHARED_LIBRARIES := \
-     libaudioutils \
-     libcutils \
-     libdl \
-     liblog \
-
-LOCAL_C_INCLUDES += \
-    $(LOCAL_PATH)/Reverb \
-    $(LOCAL_PATH)/../lib/Common/lib/ \
-    $(LOCAL_PATH)/../lib/Reverb/lib/ \
-    $(call include-path-for, audio-effects) \
-    $(call include-path-for, audio-utils) \
-
-LOCAL_HEADER_LIBRARIES += libhardware_headers
-
-LOCAL_SANITIZE := integer_overflow
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index 04c2692..3fbbc09 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -435,7 +435,7 @@
             (pSessionContext->bEqualizerInstantiated ==LVM_FALSE) &&
             (pSessionContext->bVirtualizerInstantiated==LVM_FALSE))
     {
-        #ifdef LVM_PCM
+#ifdef LVM_PCM
         if (pContext->pBundledContext->PcmInPtr != NULL) {
             fclose(pContext->pBundledContext->PcmInPtr);
             pContext->pBundledContext->PcmInPtr = NULL;
@@ -444,7 +444,7 @@
             fclose(pContext->pBundledContext->PcmOutPtr);
             pContext->pBundledContext->PcmOutPtr = NULL;
         }
-        #endif
+#endif
 
 
         // Clear the SessionIndex
@@ -650,6 +650,9 @@
     params.SpeakerType            = LVM_HEADPHONES;
 
     pContext->pBundledContext->SampleRate = LVM_FS_44100;
+#ifdef SUPPORT_MC
+    pContext->pBundledContext->ChMask = AUDIO_CHANNEL_OUT_STEREO;
+#endif
 
     /* Concert Sound parameters */
     params.VirtualizerOperatingMode   = LVM_MODE_OFF;
@@ -695,6 +698,11 @@
     params.TE_OperatingMode       = LVM_TE_OFF;
     params.TE_EffectLevel         = 0;
 
+#ifdef SUPPORT_MC
+    params.NrChannels             =
+        audio_channel_count_from_out_mask(AUDIO_CHANNEL_OUT_STEREO);
+    params.ChMask                 = AUDIO_CHANNEL_OUT_STEREO;
+#endif
     /* Activate the initial settings */
     LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance,
                                          &params);
@@ -751,19 +759,21 @@
 
     LVM_ReturnStatus_en     LvmStatus = LVM_SUCCESS;                /* Function call status */
     effect_buffer_t         *pOutTmp;
+    const LVM_INT32 NrChannels =
+        audio_channel_count_from_out_mask(pContext->config.inputCfg.channels);
 #ifndef NATIVE_FLOAT_BUFFER
     if (pContext->pBundledContext->pInputBuffer == nullptr ||
             pContext->pBundledContext->frameCount < frameCount) {
         free(pContext->pBundledContext->pInputBuffer);
         pContext->pBundledContext->pInputBuffer =
-                (LVM_FLOAT *)calloc(frameCount, sizeof(LVM_FLOAT) * FCC_2);
+                (LVM_FLOAT *)calloc(frameCount, sizeof(LVM_FLOAT) * NrChannels);
     }
 
     if (pContext->pBundledContext->pOutputBuffer == nullptr ||
             pContext->pBundledContext->frameCount < frameCount) {
         free(pContext->pBundledContext->pOutputBuffer);
         pContext->pBundledContext->pOutputBuffer =
-                (LVM_FLOAT *)calloc(frameCount, sizeof(LVM_FLOAT) * FCC_2);
+                (LVM_FLOAT *)calloc(frameCount, sizeof(LVM_FLOAT) * NrChannels);
     }
 
     if (pContext->pBundledContext->pInputBuffer == nullptr ||
@@ -784,7 +794,7 @@
                 free(pContext->pBundledContext->workBuffer);
             }
             pContext->pBundledContext->workBuffer =
-                    (effect_buffer_t *)calloc(frameCount, sizeof(effect_buffer_t) * FCC_2);
+                    (effect_buffer_t *)calloc(frameCount, sizeof(effect_buffer_t) * NrChannels);
             if (pContext->pBundledContext->workBuffer == NULL) {
                 return -ENOMEM;
             }
@@ -798,13 +808,15 @@
 
 #ifdef LVM_PCM
     fwrite(pIn,
-            frameCount*sizeof(effect_buffer_t) * FCC_2, 1, pContext->pBundledContext->PcmInPtr);
+           frameCount * sizeof(effect_buffer_t) * NrChannels,
+           1,
+           pContext->pBundledContext->PcmInPtr);
     fflush(pContext->pBundledContext->PcmInPtr);
 #endif
 
 #ifndef NATIVE_FLOAT_BUFFER
     /* Converting input data from fixed point to float point */
-    memcpy_to_float_from_i16(pInputBuff, pIn, frameCount * FCC_2);
+    memcpy_to_float_from_i16(pInputBuff, pIn, frameCount * NrChannels);
 
     /* Process the samples */
     LvmStatus = LVM_Process(pContext->pBundledContext->hInstance, /* Instance handle */
@@ -814,7 +826,7 @@
                             0);                                   /* Audio Time */
 
     /* Converting output data from float point to fixed point */
-    memcpy_to_i16_from_float(pOutTmp, pOutputBuff, frameCount * FCC_2);
+    memcpy_to_i16_from_float(pOutTmp, pOutputBuff, frameCount * NrChannels);
 
 #else
     /* Process the samples */
@@ -829,12 +841,14 @@
 
 #ifdef LVM_PCM
     fwrite(pOutTmp,
-            frameCount*sizeof(effect_buffer_t) * FCC_2, 1, pContext->pBundledContext->PcmOutPtr);
+           frameCount * sizeof(effect_buffer_t) * NrChannels,
+           1,
+           pContext->pBundledContext->PcmOutPtr);
     fflush(pContext->pBundledContext->PcmOutPtr);
 #endif
 
     if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE){
-        for (int i = 0; i < frameCount * FCC_2; i++) {
+        for (int i = 0; i < frameCount * NrChannels; i++) {
 #ifndef NATIVE_FLOAT_BUFFER
             pOut[i] = clamp16((LVM_INT32)pOut[i] + (LVM_INT32)pOutTmp[i]);
 #else
@@ -1198,13 +1212,7 @@
     for (int i=0; i<LVM_NR_MEMORY_REGIONS; i++){
         if (MemTab.Region[i].Size != 0){
             if (MemTab.Region[i].pBaseAddress != NULL){
-                ALOGV("\tLvmEffect_free - START freeing %" PRIu32 " bytes for region %u at %p\n",
-                        MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
-
                 free(MemTab.Region[i].pBaseAddress);
-
-                ALOGV("\tLvmEffect_free - END   freeing %" PRIu32 " bytes for region %u at %p\n",
-                        MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
             }else{
                 ALOGV("\tLVM_ERROR : LvmEffect_free - trying to free with NULL pointer %" PRIu32
                         " bytes for region %u at %p ERROR\n",
@@ -1238,45 +1246,58 @@
     CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate);
     CHECK_ARG(pConfig->inputCfg.channels == pConfig->outputCfg.channels);
     CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format);
+#ifdef SUPPORT_MC
+    CHECK_ARG(audio_channel_count_from_out_mask(pConfig->inputCfg.channels) <= LVM_MAX_CHANNELS);
+#else
     CHECK_ARG(pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO);
+#endif
     CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE
               || pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE);
     CHECK_ARG(pConfig->inputCfg.format == EFFECT_BUFFER_FORMAT);
     pContext->config = *pConfig;
+    const LVM_INT16 NrChannels = audio_channel_count_from_out_mask(pConfig->inputCfg.channels);
 
     switch (pConfig->inputCfg.samplingRate) {
     case 8000:
         SampleRate = LVM_FS_8000;
-        pContext->pBundledContext->SamplesPerSecond = 8000*2; // 2 secs Stereo
+        pContext->pBundledContext->SamplesPerSecond = 8000 * NrChannels;
         break;
     case 16000:
         SampleRate = LVM_FS_16000;
-        pContext->pBundledContext->SamplesPerSecond = 16000*2; // 2 secs Stereo
+        pContext->pBundledContext->SamplesPerSecond = 16000 * NrChannels;
         break;
     case 22050:
         SampleRate = LVM_FS_22050;
-        pContext->pBundledContext->SamplesPerSecond = 22050*2; // 2 secs Stereo
+        pContext->pBundledContext->SamplesPerSecond = 22050 * NrChannels;
         break;
     case 32000:
         SampleRate = LVM_FS_32000;
-        pContext->pBundledContext->SamplesPerSecond = 32000*2; // 2 secs Stereo
+        pContext->pBundledContext->SamplesPerSecond = 32000 * NrChannels;
         break;
     case 44100:
         SampleRate = LVM_FS_44100;
-        pContext->pBundledContext->SamplesPerSecond = 44100*2; // 2 secs Stereo
+        pContext->pBundledContext->SamplesPerSecond = 44100 * NrChannels;
         break;
     case 48000:
         SampleRate = LVM_FS_48000;
-        pContext->pBundledContext->SamplesPerSecond = 48000*2; // 2 secs Stereo
+        pContext->pBundledContext->SamplesPerSecond = 48000 * NrChannels;
         break;
 #if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+    case 88200:
+        SampleRate = LVM_FS_88200;
+        pContext->pBundledContext->SamplesPerSecond = 88200 * NrChannels;
+        break;
     case 96000:
         SampleRate = LVM_FS_96000;
-        pContext->pBundledContext->SamplesPerSecond = 96000*2; // 2 secs Stereo
+        pContext->pBundledContext->SamplesPerSecond = 96000 * NrChannels;
+        break;
+    case 176400:
+        SampleRate = LVM_FS_176400;
+        pContext->pBundledContext->SamplesPerSecond = 176400 * NrChannels;
         break;
     case 192000:
         SampleRate = LVM_FS_192000;
-        pContext->pBundledContext->SamplesPerSecond = 192000*2; // 2 secs Stereo
+        pContext->pBundledContext->SamplesPerSecond = 192000 * NrChannels;
         break;
 #endif
     default:
@@ -1284,7 +1305,12 @@
         return -EINVAL;
     }
 
+#ifdef SUPPORT_MC
+    if (pContext->pBundledContext->SampleRate != SampleRate ||
+        pContext->pBundledContext->ChMask != pConfig->inputCfg.channels) {
+#else
     if(pContext->pBundledContext->SampleRate != SampleRate){
+#endif
 
         LVM_ControlParams_t     ActiveParams;
         LVM_ReturnStatus_en     LvmStatus = LVM_SUCCESS;
@@ -1300,11 +1326,19 @@
 
         ActiveParams.SampleRate = SampleRate;
 
+#ifdef SUPPORT_MC
+        ActiveParams.NrChannels = NrChannels;
+        ActiveParams.ChMask = pConfig->inputCfg.channels;
+#endif
+
         LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
 
         LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "Effect_setConfig")
         ALOGV("\tEffect_setConfig Succesfully called LVM_SetControlParameters\n");
         pContext->pBundledContext->SampleRate = SampleRate;
+#ifdef SUPPORT_MC
+        pContext->pBundledContext->ChMask = pConfig->inputCfg.channels;
+#endif
 
         LvmEffect_limitLevel(pContext);
 
@@ -1504,6 +1538,7 @@
     case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
     case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
     case AUDIO_DEVICE_OUT_USB_HEADSET:
+    // case AUDIO_DEVICE_OUT_USB_DEVICE:  // For USB testing of the virtualizer only.
         return 0;
     default :
         return -EINVAL;
@@ -1526,10 +1561,9 @@
 int VirtualizerIsConfigurationSupported(audio_channel_mask_t channelMask,
         audio_devices_t deviceType) {
     uint32_t channelCount = audio_channel_count_from_out_mask(channelMask);
-    if ((channelCount == 0) || (channelCount > 2)) {
+    if (channelCount < 1 || channelCount > FCC_2) { // TODO: update to 8 channels when supported.
         return -EINVAL;
     }
-
     return VirtualizerIsDeviceSupported(deviceType);
 }
 
@@ -3222,6 +3256,7 @@
     EffectContext * pContext = (EffectContext *) self;
     int    status = 0;
     int    processStatus = 0;
+    const int NrChannels = audio_channel_count_from_out_mask(pContext->config.inputCfg.channels);
 
 //ALOGV("\tEffect_process Start : Enabled = %d     Called = %d (%8d %8d %8d)",
 //pContext->pBundledContext->NumberEffectsEnabled,pContext->pBundledContext->NumberEffectsCalled,
@@ -3252,7 +3287,7 @@
         (pContext->EffectType == LVM_BASS_BOOST)){
         //ALOGV("\tEffect_process() LVM_BASS_BOOST Effect is not enabled");
         if(pContext->pBundledContext->SamplesToExitCountBb > 0){
-            pContext->pBundledContext->SamplesToExitCountBb -= outBuffer->frameCount * 2; // STEREO
+            pContext->pBundledContext->SamplesToExitCountBb -= outBuffer->frameCount * NrChannels;
             //ALOGV("\tEffect_process: Waiting to turn off BASS_BOOST, %d samples left",
             //    pContext->pBundledContext->SamplesToExitCountBb);
         }
@@ -3272,7 +3307,7 @@
         (pContext->EffectType == LVM_EQUALIZER)){
         //ALOGV("\tEffect_process() LVM_EQUALIZER Effect is not enabled");
         if(pContext->pBundledContext->SamplesToExitCountEq > 0){
-            pContext->pBundledContext->SamplesToExitCountEq -= outBuffer->frameCount * 2; // STEREO
+            pContext->pBundledContext->SamplesToExitCountEq -= outBuffer->frameCount * NrChannels;
             //ALOGV("\tEffect_process: Waiting to turn off EQUALIZER, %d samples left",
             //    pContext->pBundledContext->SamplesToExitCountEq);
         }
@@ -3286,7 +3321,8 @@
         (pContext->EffectType == LVM_VIRTUALIZER)){
         //ALOGV("\tEffect_process() LVM_VIRTUALIZER Effect is not enabled");
         if(pContext->pBundledContext->SamplesToExitCountVirt > 0){
-            pContext->pBundledContext->SamplesToExitCountVirt -= outBuffer->frameCount * 2;// STEREO
+            pContext->pBundledContext->SamplesToExitCountVirt -=
+                outBuffer->frameCount * NrChannels;
             //ALOGV("\tEffect_process: Waiting for to turn off VIRTUALIZER, %d samples left",
             //    pContext->pBundledContext->SamplesToExitCountVirt);
         }
@@ -3337,7 +3373,7 @@
         //pContext->pBundledContext->NumberEffectsCalled, pContext->EffectType);
 
         if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
-            for (size_t i = 0; i < outBuffer->frameCount * FCC_2; ++i){
+            for (size_t i = 0; i < outBuffer->frameCount * NrChannels; ++i) {
 #ifdef NATIVE_FLOAT_BUFFER
                 outBuffer->f32[i] += inBuffer->f32[i];
 #else
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
index 6bf045d..6af4554 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
@@ -107,6 +107,9 @@
     LVM_FLOAT                       *pInputBuffer;
     LVM_FLOAT                       *pOutputBuffer;
 #endif
+#ifdef SUPPORT_MC
+    LVM_INT32                       ChMask;
+#endif
 };
 
 /* SessionContext : One session */
diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
index e1c03f9..602f607 100644
--- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
@@ -612,13 +612,7 @@
     for (int i=0; i<LVM_NR_MEMORY_REGIONS; i++){
         if (MemTab.Region[i].Size != 0){
             if (MemTab.Region[i].pBaseAddress != NULL){
-                ALOGV("\tfree() - START freeing %" PRIu32 " bytes for region %u at %p\n",
-                        MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
-
                 free(MemTab.Region[i].pBaseAddress);
-
-                ALOGV("\tfree() - END   freeing %" PRIu32 " bytes for region %u at %p\n",
-                        MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
             }else{
                 ALOGV("\tLVM_ERROR : free() - trying to free with NULL pointer %" PRIu32 " bytes "
                         "for region %u at %p ERROR\n",
@@ -681,9 +675,15 @@
         SampleRate = LVM_FS_48000;
         break;
 #if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+    case 88200:
+        SampleRate = LVM_FS_88200;
+        break;
     case 96000:
         SampleRate = LVM_FS_96000;
         break;
+    case 176400:
+        SampleRate = LVM_FS_176400;
+        break;
     case 192000:
         SampleRate = LVM_FS_192000;
         break;
@@ -1757,15 +1757,14 @@
             //        *(int16_t *)pValue);
             break;
         case REVERB_PARAM_DENSITY:
-            *(uint16_t *)pValue = 0;
             *(int16_t *)pValue = ReverbGetDensity(pContext);
             //ALOGV("\tReverb_getParameter() REVERB_PARAM_DENSITY Value is %d",
             //        *(uint32_t *)pValue);
             break;
         case REVERB_PARAM_REFLECTIONS_LEVEL:
             *(uint16_t *)pValue = 0;
+            break;
         case REVERB_PARAM_REFLECTIONS_DELAY:
-            *(uint32_t *)pValue = 0;
         case REVERB_PARAM_REVERB_DELAY:
             *(uint32_t *)pValue = 0;
             break;
diff --git a/media/libeffects/preprocessing/Android.bp b/media/libeffects/preprocessing/Android.bp
new file mode 100644
index 0000000..c87635f
--- /dev/null
+++ b/media/libeffects/preprocessing/Android.bp
@@ -0,0 +1,35 @@
+// audio preprocessing wrapper
+cc_library_shared {
+    name: "libaudiopreprocessing",
+
+    vendor: true,
+
+    relative_install_path: "soundfx",
+
+    srcs: ["PreProcessing.cpp"],
+
+    include_dirs: [
+        "external/webrtc",
+        "external/webrtc/webrtc/modules/include",
+        "external/webrtc/webrtc/modules/audio_processing/include",
+    ],
+
+    shared_libs: [
+        "libwebrtc_audio_preprocessing",
+        "libspeexresampler",
+        "libutils",
+        "liblog",
+    ],
+
+    cflags: [
+        "-DWEBRTC_POSIX",
+        "-fvisibility=hidden",
+        "-Wall",
+        "-Werror",
+    ],
+
+    header_libs: [
+        "libaudioeffects",
+        "libhardware_headers",
+    ],
+}
diff --git a/media/libeffects/preprocessing/Android.mk b/media/libeffects/preprocessing/Android.mk
deleted file mode 100644
index 358da8b..0000000
--- a/media/libeffects/preprocessing/Android.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-# audio preprocessing wrapper
-include $(CLEAR_VARS)
-
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE:= libaudiopreprocessing
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_RELATIVE_PATH := soundfx
-
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES:= \
-    PreProcessing.cpp
-
-LOCAL_C_INCLUDES += \
-    external/webrtc \
-    external/webrtc/webrtc/modules/include \
-    external/webrtc/webrtc/modules/audio_processing/include \
-    $(call include-path-for, audio-effects)
-
-LOCAL_SHARED_LIBRARIES := \
-    libwebrtc_audio_preprocessing \
-    libspeexresampler \
-    libutils \
-    liblog
-
-LOCAL_SHARED_LIBRARIES += libdl
-
-LOCAL_CFLAGS += \
-    -DWEBRTC_POSIX
-
-LOCAL_CFLAGS += -fvisibility=hidden
-LOCAL_CFLAGS += -Wall -Werror
-
-LOCAL_HEADER_LIBRARIES += libhardware_headers
-include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libeffects/preprocessing/PreProcessing.cpp b/media/libeffects/preprocessing/PreProcessing.cpp
index f2844ed..5fab5be 100644
--- a/media/libeffects/preprocessing/PreProcessing.cpp
+++ b/media/libeffects/preprocessing/PreProcessing.cpp
@@ -698,6 +698,7 @@
         case PREPROC_EFFECT_STATE_ACTIVE:
             effect->ops->disable(effect);
             Session_SetProcEnabled(effect->session, effect->procId, false);
+            break;
         case PREPROC_EFFECT_STATE_CONFIG:
         case PREPROC_EFFECT_STATE_CREATED:
         case PREPROC_EFFECT_STATE_INIT:
@@ -889,7 +890,7 @@
         delete session->procFrame;
         session->procFrame = NULL;
         delete session->apm;
-        session->apm = NULL;
+        session->apm = NULL; // NOLINT(clang-analyzer-cplusplus.NewDelete)
     }
     return status;
 }
@@ -925,7 +926,7 @@
         delete session->revBuf;
         session->revBuf = NULL;
 
-        session->io = 0;
+        session->id = 0;
     }
 
     return 0;
@@ -1154,7 +1155,7 @@
 {
     size_t i;
     for (i = 0; i < PREPROC_NUM_SESSIONS; i++) {
-        if (sSessions[i].io == ioId) {
+        if (sSessions[i].id == sessionId) {
             if (sSessions[i].createdMsk & (1 << procId)) {
                 return NULL;
             }
@@ -1162,7 +1163,7 @@
         }
     }
     for (i = 0; i < PREPROC_NUM_SESSIONS; i++) {
-        if (sSessions[i].io == 0) {
+        if (sSessions[i].id == 0) {
             sSessions[i].id = sessionId;
             sSessions[i].io = ioId;
             return &sSessions[i];
@@ -1914,7 +1915,7 @@
     status = Session_CreateEffect(session, procId, pInterface);
 
     if (status < 0 && session->createdMsk == 0) {
-        session->io = 0;
+        session->id = 0;
     }
     return status;
 }
@@ -1928,7 +1929,7 @@
 
     preproc_effect_t *fx = (preproc_effect_t *)interface;
 
-    if (fx->session->io == 0) {
+    if (fx->session->id == 0) {
         return -EINVAL;
     }
     return Session_ReleaseEffect(fx->session, fx);
diff --git a/media/libeffects/proxy/Android.bp b/media/libeffects/proxy/Android.bp
new file mode 100644
index 0000000..c6abb9e
--- /dev/null
+++ b/media/libeffects/proxy/Android.bp
@@ -0,0 +1,38 @@
+// Copyright 2013 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library_shared {
+    name: "libeffectproxy",
+    relative_install_path: "soundfx",
+
+    vendor: true,
+    srcs: ["EffectProxy.cpp"],
+
+    cflags: [
+        "-fvisibility=hidden",
+        "-Wall",
+        "-Werror",
+    ],
+
+    include_dirs: ["frameworks/av/media/libeffects/factory"],
+
+    header_libs: ["libaudioeffects"],
+    shared_libs: [
+        "liblog",
+        "libcutils",
+        "libutils",
+        "libdl",
+        "libeffects",
+    ],
+}
diff --git a/media/libeffects/proxy/Android.mk b/media/libeffects/proxy/Android.mk
deleted file mode 100644
index c4de30d..0000000
--- a/media/libeffects/proxy/Android.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-LOCAL_MODULE:= libeffectproxy
-LOCAL_MODULE_RELATIVE_PATH := soundfx
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := \
-        EffectProxy.cpp
-
-LOCAL_CFLAGS+= -fvisibility=hidden
-LOCAL_CFLAGS += -Wall -Werror
-
-LOCAL_SHARED_LIBRARIES := liblog libcutils libutils libdl libeffects
-
-LOCAL_C_INCLUDES := \
-        system/media/audio_effects/include \
-        frameworks/av/media/libeffects/factory
-
-include $(BUILD_SHARED_LIBRARY)
-
diff --git a/media/libeffects/visualizer/Android.mk b/media/libeffects/visualizer/Android.mk
index 70409de..35e2f3d 100644
--- a/media/libeffects/visualizer/Android.mk
+++ b/media/libeffects/visualizer/Android.mk
@@ -9,6 +9,7 @@
 
 LOCAL_CFLAGS+= -O2 -fvisibility=hidden
 LOCAL_CFLAGS += -Wall -Werror
+LOCAL_CFLAGS += -DBUILD_FLOAT -DSUPPORT_MC
 
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
@@ -19,7 +20,8 @@
 LOCAL_MODULE:= libvisualizer
 
 LOCAL_C_INCLUDES := \
-	$(call include-path-for, audio-effects)
+	$(call include-path-for, audio-effects) \
+	$(call include-path-for, audio-utils)
 
 
 LOCAL_HEADER_LIBRARIES += libhardware_headers
diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp
index 807f24d..f838892 100644
--- a/media/libeffects/visualizer/EffectVisualizer.cpp
+++ b/media/libeffects/visualizer/EffectVisualizer.cpp
@@ -24,11 +24,23 @@
 #include <string.h>
 #include <time.h>
 
+#include <algorithm> // max
 #include <new>
 
 #include <log/log.h>
 
 #include <audio_effects/effect_visualizer.h>
+#include <audio_utils/primitives.h>
+
+#ifdef BUILD_FLOAT
+
+static constexpr audio_format_t kProcessFormat = AUDIO_FORMAT_PCM_FLOAT;
+
+#else
+
+static constexpr audio_format_t kProcessFormat = AUDIO_FORMAT_PCM_16_BIT;
+
+#endif // BUILD_FLOAT
 
 extern "C" {
 
@@ -143,10 +155,15 @@
     if (pConfig->inputCfg.samplingRate != pConfig->outputCfg.samplingRate) return -EINVAL;
     if (pConfig->inputCfg.channels != pConfig->outputCfg.channels) return -EINVAL;
     if (pConfig->inputCfg.format != pConfig->outputCfg.format) return -EINVAL;
-    if (pConfig->inputCfg.channels != AUDIO_CHANNEL_OUT_STEREO) return -EINVAL;
+    const uint32_t channelCount = audio_channel_count_from_out_mask(pConfig->inputCfg.channels);
+#ifdef SUPPORT_MC
+    if (channelCount < 1 || channelCount > FCC_8) return -EINVAL;
+#else
+    if (channelCount != FCC_2) return -EINVAL;
+#endif
     if (pConfig->outputCfg.accessMode != EFFECT_BUFFER_ACCESS_WRITE &&
             pConfig->outputCfg.accessMode != EFFECT_BUFFER_ACCESS_ACCUMULATE) return -EINVAL;
-    if (pConfig->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL;
+    if (pConfig->inputCfg.format != kProcessFormat) return -EINVAL;
 
     pContext->mConfig = *pConfig;
 
@@ -192,7 +209,7 @@
 {
     pContext->mConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
     pContext->mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
-    pContext->mConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
+    pContext->mConfig.inputCfg.format = kProcessFormat;
     pContext->mConfig.inputCfg.samplingRate = 44100;
     pContext->mConfig.inputCfg.bufferProvider.getBuffer = NULL;
     pContext->mConfig.inputCfg.bufferProvider.releaseBuffer = NULL;
@@ -200,7 +217,7 @@
     pContext->mConfig.inputCfg.mask = EFFECT_CONFIG_ALL;
     pContext->mConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
     pContext->mConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
-    pContext->mConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
+    pContext->mConfig.outputCfg.format = kProcessFormat;
     pContext->mConfig.outputCfg.samplingRate = 44100;
     pContext->mConfig.outputCfg.bufferProvider.getBuffer = NULL;
     pContext->mConfig.outputCfg.bufferProvider.releaseBuffer = NULL;
@@ -301,15 +318,8 @@
 //--- Effect Control Interface Implementation
 //
 
-static inline int16_t clamp16(int32_t sample)
-{
-    if ((sample>>15) ^ (sample>>31))
-        sample = 0x7FFF ^ (sample>>31);
-    return sample;
-}
-
 int Visualizer_process(
-        effect_handle_t self,audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
+        effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
 {
     VisualizerContext * pContext = (VisualizerContext *)self;
 
@@ -324,71 +334,118 @@
         return -EINVAL;
     }
 
+    const size_t sampleLen = inBuffer->frameCount * pContext->mChannelCount;
+
     // perform measurements if needed
     if (pContext->mMeasurementMode & MEASUREMENT_MODE_PEAK_RMS) {
         // find the peak and RMS squared for the new buffer
-        uint32_t inIdx;
-        int16_t maxSample = 0;
         float rmsSqAcc = 0;
-        for (inIdx = 0 ; inIdx < inBuffer->frameCount * pContext->mChannelCount ; inIdx++) {
-            if (inBuffer->s16[inIdx] > maxSample) {
-                maxSample = inBuffer->s16[inIdx];
-            } else if (-inBuffer->s16[inIdx] > maxSample) {
-                maxSample = -inBuffer->s16[inIdx];
-            }
-            rmsSqAcc += (inBuffer->s16[inIdx] * inBuffer->s16[inIdx]);
+
+#ifdef BUILD_FLOAT
+        float maxSample = 0.f;
+        for (size_t inIdx = 0; inIdx < sampleLen; ++inIdx) {
+            maxSample = fmax(maxSample, fabs(inBuffer->f32[inIdx]));
+            rmsSqAcc += inBuffer->f32[inIdx] * inBuffer->f32[inIdx];
         }
+        maxSample *= 1 << 15; // scale to int16_t, with exactly 1 << 15 representing positive num.
+        rmsSqAcc *= 1 << 30; // scale to int16_t * 2
+#else
+        int maxSample = 0;
+        for (size_t inIdx = 0; inIdx < sampleLen; ++inIdx) {
+            maxSample = std::max(maxSample, std::abs(int32_t(inBuffer->s16[inIdx])));
+            rmsSqAcc += inBuffer->s16[inIdx] * inBuffer->s16[inIdx];
+        }
+#endif
         // store the measurement
         pContext->mPastMeasurements[pContext->mMeasurementBufferIdx].mPeakU16 = (uint16_t)maxSample;
         pContext->mPastMeasurements[pContext->mMeasurementBufferIdx].mRmsSquared =
-                rmsSqAcc / (inBuffer->frameCount * pContext->mChannelCount);
+                rmsSqAcc / sampleLen;
         pContext->mPastMeasurements[pContext->mMeasurementBufferIdx].mIsValid = true;
         if (++pContext->mMeasurementBufferIdx >= pContext->mMeasurementWindowSizeInBuffers) {
             pContext->mMeasurementBufferIdx = 0;
         }
     }
 
-    // all code below assumes stereo 16 bit PCM output and input
+#ifdef BUILD_FLOAT
+    float fscale; // multiplicative scale
+#else
     int32_t shift;
+#endif // BUILD_FLOAT
 
     if (pContext->mScalingMode == VISUALIZER_SCALING_MODE_NORMALIZED) {
         // derive capture scaling factor from peak value in current buffer
         // this gives more interesting captures for display.
-        shift = 32;
-        int len = inBuffer->frameCount * 2;
-        for (int i = 0; i < len; i++) {
+
+#ifdef BUILD_FLOAT
+        float maxSample = 0.f;
+        for (size_t inIdx = 0; inIdx < sampleLen; ) {
+            // we reconstruct the actual summed value to ensure proper normalization
+            // for multichannel outputs (channels > 2 may often be 0).
+            float smp = 0.f;
+            for (int i = 0; i < pContext->mChannelCount; ++i) {
+                smp += inBuffer->f32[inIdx++];
+            }
+            maxSample = fmax(maxSample, fabs(smp));
+        }
+        if (maxSample > 0.f) {
+            fscale = 0.99f / maxSample;
+            int exp; // unused
+            const float significand = frexp(fscale, &exp);
+            if (significand == 0.5f) {
+                fscale *= 255.f / 256.f; // avoid returning unaltered PCM signal
+            }
+        } else {
+            // scale doesn't matter, the values are all 0.
+            fscale = 1.f;
+        }
+#else
+        int32_t orAccum = 0;
+        for (size_t i = 0; i < sampleLen; ++i) {
             int32_t smp = inBuffer->s16[i];
             if (smp < 0) smp = -smp - 1; // take care to keep the max negative in range
-            int32_t clz = __builtin_clz(smp);
-            if (shift > clz) shift = clz;
+            orAccum |= smp;
         }
+
         // A maximum amplitude signal will have 17 leading zeros, which we want to
         // translate to a shift of 8 (for converting 16 bit to 8 bit)
-        shift = 25 - shift;
+        shift = 25 - __builtin_clz(orAccum);
+
         // Never scale by less than 8 to avoid returning unaltered PCM signal.
         if (shift < 3) {
             shift = 3;
         }
         // add one to combine the division by 2 needed after summing left and right channels below
         shift++;
+#endif // BUILD_FLOAT
     } else {
         assert(pContext->mScalingMode == VISUALIZER_SCALING_MODE_AS_PLAYED);
+#ifdef BUILD_FLOAT
+        // Note: if channels are uncorrelated, 1/sqrt(N) could be used at the risk of clipping.
+        fscale = 1.f / pContext->mChannelCount;  // account for summing all the channels together.
+#else
         shift = 9;
+#endif // BUILD_FLOAT
     }
 
     uint32_t captIdx;
     uint32_t inIdx;
     uint8_t *buf = pContext->mCaptureBuf;
     for (inIdx = 0, captIdx = pContext->mCaptureIdx;
-         inIdx < inBuffer->frameCount;
-         inIdx++, captIdx++) {
-        if (captIdx >= CAPTURE_BUF_SIZE) {
-            // wrap around
-            captIdx = 0;
+         inIdx < sampleLen;
+         captIdx++) {
+        if (captIdx >= CAPTURE_BUF_SIZE) captIdx = 0; // wrap
+
+#ifdef BUILD_FLOAT
+        float smp = 0.f;
+        for (uint32_t i = 0; i < pContext->mChannelCount; ++i) {
+            smp += inBuffer->f32[inIdx++];
         }
-        int32_t smp = inBuffer->s16[2 * inIdx] + inBuffer->s16[2 * inIdx + 1];
-        smp = smp >> shift;
+        buf[captIdx] = clamp8_from_float(smp * fscale);
+#else
+        const int32_t smp = (inBuffer->s16[inIdx] + inBuffer->s16[inIdx + 1]) >> shift;
+        inIdx += FCC_2;  // integer supports stereo only.
         buf[captIdx] = ((uint8_t)smp)^0x80;
+#endif // BUILD_FLOAT
     }
 
     // XXX the following two should really be atomic, though it probably doesn't
@@ -400,6 +457,15 @@
     }
 
     if (inBuffer->raw != outBuffer->raw) {
+#ifdef BUILD_FLOAT
+        if (pContext->mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
+            for (size_t i = 0; i < sampleLen; ++i) {
+                outBuffer->f32[i] += inBuffer->f32[i];
+            }
+        } else {
+            memcpy(outBuffer->raw, inBuffer->raw, sampleLen * sizeof(float));
+        }
+#else
         if (pContext->mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
             for (size_t i = 0; i < outBuffer->frameCount*2; i++) {
                 outBuffer->s16[i] = clamp16(outBuffer->s16[i] + inBuffer->s16[i]);
@@ -407,6 +473,7 @@
         } else {
             memcpy(outBuffer->raw, inBuffer->raw, outBuffer->frameCount * 2 * sizeof(int16_t));
         }
+#endif // BUILD_FLOAT
     }
     if (pContext->mState != VISUALIZER_STATE_ACTIVE) {
         return -ENODATA;
diff --git a/media/libheif/HeifDecoderImpl.cpp b/media/libheif/HeifDecoderImpl.cpp
index 01f014f..a977300 100644
--- a/media/libheif/HeifDecoderImpl.cpp
+++ b/media/libheif/HeifDecoderImpl.cpp
@@ -86,7 +86,7 @@
     sp<IMemory> mMemory;
     std::unique_ptr<HeifStream> mStream;
     bool mEOS;
-    std::unique_ptr<uint8_t> mCache;
+    std::unique_ptr<uint8_t[]> mCache;
     off64_t mCachedOffset;
     size_t mCachedSize;
     size_t mCacheBufferSize;
@@ -165,7 +165,7 @@
         // it's reaching max cache buffer size, need to roll window, and possibly
         // expand the cache buffer.
         size_t newCacheBufferSize = mCacheBufferSize;
-        std::unique_ptr<uint8_t> newCache;
+        std::unique_ptr<uint8_t[]> newCache;
         uint8_t* dst = mCache.get();
         if (newCacheBufferSize < kMaxCacheBufferSize) {
             newCacheBufferSize = kMaxCacheBufferSize;
diff --git a/media/libheif/include/HeifDecoderAPI.h b/media/libheif/include/HeifDecoderAPI.h
index 5183c39..aa10f33 100644
--- a/media/libheif/include/HeifDecoderAPI.h
+++ b/media/libheif/include/HeifDecoderAPI.h
@@ -74,7 +74,7 @@
     int32_t  mRotationAngle;           // Rotation angle, clockwise, should be multiple of 90
     uint32_t mBytesPerPixel;           // Number of bytes for one pixel
     uint32_t mIccSize;                 // Number of bytes in mIccData
-    std::unique_ptr<uint8_t> mIccData; // Actual ICC data, memory is owned by this structure
+    std::unique_ptr<uint8_t[]> mIccData; // Actual ICC data, memory is owned by this structure
 };
 
 /*
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 1a1d6b3..1d33590 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -1,8 +1,16 @@
+cc_defaults {
+    name: "libmedia_defaults",
+    include_dirs: [
+        "bionic/libc/private",
+    ],
+}
+
 cc_library_headers {
     name: "libmedia_headers",
     vendor_available: true,
     export_include_dirs: ["include"],
     header_libs:[
+        "libbase_headers",
         "libgui_headers",
         "libstagefright_headers",
         "media_plugin_headers",
@@ -20,7 +28,8 @@
     vndk: {
         enabled: true,
     },
-    srcs: ["AudioParameter.cpp", "TypeConverter.cpp", "TimeCheck.cpp"],
+    double_loadable: true,
+    srcs: ["AudioParameter.cpp", "TypeConverter.cpp"],
     cflags: [
         "-Werror",
         "-Wno-error=deprecated-declarations",
@@ -32,6 +41,9 @@
         "libaudioclient_headers",
         "libaudio_system_headers",
     ],
+    export_header_lib_headers: [
+        "libmedia_headers",
+    ],
     clang: true,
 }
 
@@ -41,6 +53,7 @@
     vndk: {
         enabled: true,
     },
+    double_loadable: true,
 
     srcs: [
         "aidl/android/IGraphicBufferSource.aidl",
@@ -52,7 +65,6 @@
         "MediaCodecInfo.cpp",
         "OMXBuffer.cpp",
         "omx/1.0/WGraphicBufferSource.cpp",
-        "omx/1.0/WOmx.cpp",
         "omx/1.0/WOmxBufferSource.cpp",
         "omx/1.0/WOmxNode.cpp",
         "omx/1.0/WOmxObserver.cpp",
@@ -62,13 +74,16 @@
         local_include_dirs: ["aidl"],
         export_aidl_headers: true,
     },
+    
+    local_include_dirs: [
+        "include",
+    ],
 
     shared_libs: [
         "android.hidl.token@1.0-utils",
         "android.hardware.media.omx@1.0",
         "libbinder",
         "libcutils",
-        "libgui",
         "libhidlbase",
         "libhidltransport",
         "liblog",
@@ -85,15 +100,18 @@
     ],
 
     header_libs: [
-        "libmedia_headers",
+        "libstagefright_headers",
+        "media_plugin_headers",
     ],
 
     export_header_lib_headers: [
-        "libmedia_headers",
+        "libstagefright_headers",
+        "media_plugin_headers",
     ],
 
     export_include_dirs: [
         "aidl",
+        "include",
     ],
 
     cflags: [
@@ -108,9 +126,67 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
+    },
+}
+
+
+cc_library_shared {
+    name: "libmedia_omx_client",
+
+    srcs: [
+        "omx/1.0/WOmx.cpp",
+    ],
+
+    local_include_dirs: [
+        "include",
+    ],
+
+    shared_libs: [
+        "libbinder",
+        "libcutils",
+        "libgui",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libmedia_omx",
+        "libstagefright_foundation",
+        "libui",
+        "libutils",
+    ],
+
+    export_shared_lib_headers: [
+        "libgui",
+        "libmedia_omx",
+        "libstagefright_foundation",
+        "libui",
+    ],
+
+    header_libs: [
+        "libstagefright_headers",
+        "media_plugin_headers",
+    ],
+
+    export_header_lib_headers: [
+        "libstagefright_headers",
+        "media_plugin_headers",
+    ],
+
+    export_include_dirs: [
+        "include",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wno-error=deprecated-declarations",
+        "-Wall",
+    ],
+
+    sanitize: {
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+        cfi: true,
     },
 }
 
@@ -123,6 +199,10 @@
         "libsonivox",
     ],
 
+    header_libs: [
+        "media_ndk_headers",
+    ],
+
     cflags: [
         "-Werror",
         "-Wno-error=deprecated-declarations",
@@ -135,24 +215,15 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 }
 
-filegroup {
-    name: "mediaupdateservice_aidl",
-    srcs: [
-        "aidl/android/media/IMediaExtractorUpdateService.aidl",
-    ],
-}
-
 cc_library {
     name: "libmedia",
 
+    defaults: [ "libmedia_defaults" ],
+
     srcs: [
-        ":mediaupdateservice_aidl",
         "IDataSource.cpp",
         "BufferingSettings.cpp",
         "mediaplayer.cpp",
@@ -187,6 +258,8 @@
         "MediaResourcePolicy.cpp",
         "Visualizer.cpp",
         "StringArray.cpp",
+        "NdkMediaFormatPriv.cpp",
+        "NdkMediaErrorPriv.cpp",
     ],
 
     aidl: {
@@ -196,25 +269,26 @@
 
     header_libs: [
         "libstagefright_headers",
+        "media_ndk_headers",
     ],
 
     export_header_lib_headers: [
         "libstagefright_headers",
+        "media_ndk_headers",
     ],
 
     shared_libs: [
         "android.hidl.token@1.0-utils",
         "liblog",
         "libcutils",
+        "libprocessgroup",
         "libutils",
         "libbinder",
         "libsonivox",
-        "libicuuc",
-        "libicui18n",
+        "libandroidicu",
         "libexpat",
         "libcamera_client",
         "libstagefright_foundation",
-        "libmediaextractor",
         "libgui",
         "libdl",
         "libaudioutils",
@@ -225,8 +299,7 @@
     export_shared_lib_headers: [
         "libaudioclient",
         "libbinder",
-        "libicuuc",
-        "libicui18n",
+        "libandroidicu",
         "libsonivox",
         "libmedia_omx",
     ],
@@ -254,24 +327,19 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 }
 
-cc_library {
+cc_library_static {
     name: "libmedia_player2_util",
 
+    defaults: [ "libmedia_defaults" ],
+
     srcs: [
+        "AudioParameter.cpp",
         "BufferingSettings.cpp",
         "DataSourceDesc.cpp",
-        "IDataSource.cpp",
-        "IMediaExtractor.cpp",
-        "IMediaExtractorService.cpp",
-        "IMediaSource.cpp",
         "MediaCodecBuffer.cpp",
-        "MediaUtils.cpp",
         "Metadata.cpp",
         "NdkWrapper.cpp",
     ],
@@ -280,9 +348,9 @@
         "libbinder",
         "libcutils",
         "liblog",
-        "libmediaextractor",
         "libmediandk",
         "libnativewindow",
+        "libmediandk_utils",
         "libstagefright_foundation",
         "libui",
         "libutils",
@@ -297,6 +365,10 @@
         "media_plugin_headers",
     ],
 
+    include_dirs: [
+        "frameworks/av/media/ndk",
+    ],
+
     static_libs: [
         "libstagefright_rtsp",
         "libstagefright_timedtext",
@@ -318,8 +390,5 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 }
diff --git a/media/libmedia/AudioParameter.cpp b/media/libmedia/AudioParameter.cpp
index 034f7c2..1c95e27 100644
--- a/media/libmedia/AudioParameter.cpp
+++ b/media/libmedia/AudioParameter.cpp
@@ -36,6 +36,8 @@
 const char * const AudioParameter::keyHwAvSync = AUDIO_PARAMETER_HW_AV_SYNC;
 const char * const AudioParameter::keyPresentationId = AUDIO_PARAMETER_STREAM_PRESENTATION_ID;
 const char * const AudioParameter::keyProgramId = AUDIO_PARAMETER_STREAM_PROGRAM_ID;
+const char * const AudioParameter::keyAudioLanguagePreferred =
+        AUDIO_PARAMETER_KEY_AUDIO_LANGUAGE_PREFERRED;
 const char * const AudioParameter::keyMonoOutput = AUDIO_PARAMETER_MONO_OUTPUT;
 const char * const AudioParameter::keyStreamHwAvSync = AUDIO_PARAMETER_STREAM_HW_AV_SYNC;
 const char * const AudioParameter::keyStreamConnect = AUDIO_PARAMETER_DEVICE_CONNECT;
diff --git a/media/libmedia/BufferingSettings.cpp b/media/libmedia/BufferingSettings.cpp
index 271a238..1cc30c2 100644
--- a/media/libmedia/BufferingSettings.cpp
+++ b/media/libmedia/BufferingSettings.cpp
@@ -27,26 +27,6 @@
         : mInitialMarkMs(kNoMark),
           mResumePlaybackMarkMs(kNoMark) { }
 
-status_t BufferingSettings::readFromParcel(const Parcel* parcel) {
-    if (parcel == nullptr) {
-        return BAD_VALUE;
-    }
-    mInitialMarkMs = parcel->readInt32();
-    mResumePlaybackMarkMs = parcel->readInt32();
-
-    return OK;
-}
-
-status_t BufferingSettings::writeToParcel(Parcel* parcel) const {
-    if (parcel == nullptr) {
-        return BAD_VALUE;
-    }
-    parcel->writeInt32(mInitialMarkMs);
-    parcel->writeInt32(mResumePlaybackMarkMs);
-
-    return OK;
-}
-
 String8 BufferingSettings::toString() const {
     String8 s;
     s.appendFormat(
diff --git a/media/libmedia/CharacterEncodingDetector.cpp b/media/libmedia/CharacterEncodingDetector.cpp
index 990d260..5c6b981 100644
--- a/media/libmedia/CharacterEncodingDetector.cpp
+++ b/media/libmedia/CharacterEncodingDetector.cpp
@@ -28,6 +28,8 @@
 #include <unicode/ucsdet.h>
 #include <unicode/ustring.h>
 
+#include <cutils/properties.h>
+
 namespace android {
 
 CharacterEncodingDetector::CharacterEncodingDetector() {
@@ -38,6 +40,26 @@
         ALOGE("could not create UConverter for UTF-8");
         mUtf8Conv = NULL;
     }
+
+    // Read system locale setting from system property and map to ICU encoding names.
+    mLocaleEnc = NULL;
+    char locale_value[PROPERTY_VALUE_MAX] = "";
+    if (property_get("persist.sys.locale", locale_value, NULL) > 0) {
+        const size_t len = strnlen(locale_value, sizeof(locale_value));
+
+        if (len == 3 && !strncmp(locale_value, "und", 3)) {
+            // Undetermined
+        } else if (!strncmp(locale_value, "th", 2)) { // Thai
+            mLocaleEnc = "windows-874-2000";
+        }
+        if (mLocaleEnc != NULL) {
+            ALOGV("System locale encoding = %s", mLocaleEnc);
+        } else {
+            ALOGV("Didn't recognize system locale setting, defaulting to en_US");
+        }
+    } else {
+        ALOGV("Couldn't read system locale setting, assuming en_US");
+    }
 }
 
 CharacterEncodingDetector::~CharacterEncodingDetector() {
@@ -157,7 +179,11 @@
                 }
             }
 
-            if (bestCombinedMatch != NULL) {
+            if (mLocaleEnc != NULL && !goodmatch && highest < 50) {
+                combinedenc = mLocaleEnc;
+                ALOGV("confidence is low but we have recognized predefined encoding, "
+                        "so try this (%s) instead", mLocaleEnc);
+            } else if (bestCombinedMatch != NULL) {
                 combinedenc = ucsdet_getName(bestCombinedMatch, &status);
             } else {
                 combinedenc = "ISO-8859-1";
diff --git a/media/libmedia/IMediaExtractor.cpp b/media/libmedia/IMediaExtractor.cpp
index e9a6230..fb6d3a2 100644
--- a/media/libmedia/IMediaExtractor.cpp
+++ b/media/libmedia/IMediaExtractor.cpp
@@ -19,6 +19,7 @@
 #include <utils/Log.h>
 
 #include <stdint.h>
+#include <time.h>
 #include <sys/types.h>
 
 #include <binder/IPCThreadState.h>
@@ -219,10 +220,16 @@
     Vector<wp<IMediaSource>> tracks;
     Vector<String8> trackDescriptions;
     String8 toString() const;
+    time_t when;
 } ExtractorInstance;
 
 String8 ExtractorInstance::toString() const {
-    String8 str = name;
+    String8 str;
+    char timeString[32];
+    strftime(timeString, sizeof(timeString), "%m-%d %T", localtime(&when));
+    str.append(timeString);
+    str.append(": ");
+    str.append(name);
     str.append(" for mime ");
     str.append(mime);
     str.append(", source ");
@@ -287,6 +294,7 @@
     ex.sourceDescription = source->toString();
     ex.owner = IPCThreadState::self()->getCallingPid();
     ex.extractor = extractor;
+    ex.when = time(NULL);
 
     {
         Mutex::Autolock lock(sExtractorsLock);
diff --git a/media/libmedia/IMediaExtractorService.cpp b/media/libmedia/IMediaExtractorService.cpp
index d7533ca..243b09d 100644
--- a/media/libmedia/IMediaExtractorService.cpp
+++ b/media/libmedia/IMediaExtractorService.cpp
@@ -23,13 +23,13 @@
 #include <sys/types.h>
 #include <binder/Parcel.h>
 #include <media/IMediaExtractorService.h>
-#include <media/MediaExtractor.h>
 
 namespace android {
 
 enum {
     MAKE_EXTRACTOR = IBinder::FIRST_CALL_TRANSACTION,
     MAKE_IDATA_SOURCE_FD,
+    GET_SUPPORTED_TYPES,
 };
 
 class BpMediaExtractorService : public BpInterface<IMediaExtractorService>
@@ -69,6 +69,24 @@
         }
         return nullptr;
     }
+
+    virtual std::unordered_set<std::string> getSupportedTypes() {
+        std::unordered_set<std::string> supportedTypes;
+        Parcel data, reply;
+        data.writeInterfaceToken(IMediaExtractorService::getInterfaceDescriptor());
+        status_t ret = remote()->transact(GET_SUPPORTED_TYPES, data, &reply);
+        if (ret == NO_ERROR) {
+            // process reply
+            while(true) {
+                const char *ext = reply.readCString();
+                if (!ext) {
+                    break;
+                }
+                supportedTypes.insert(std::string(ext));
+            }
+        }
+        return supportedTypes;
+    }
 };
 
 IMPLEMENT_META_INTERFACE(MediaExtractorService, "android.media.IMediaExtractorService");
@@ -114,6 +132,15 @@
             return NO_ERROR;
         }
 
+        case GET_SUPPORTED_TYPES:
+        {
+            CHECK_INTERFACE(IMediaExtractorService, data, reply);
+            std::unordered_set<std::string> supportedTypes = getSupportedTypes();
+            for (auto it = supportedTypes.begin(); it != supportedTypes.end(); ++it) {
+                reply->writeCString((*it).c_str());
+            }
+            return NO_ERROR;
+        }
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/media/libmedia/IMediaMetadataRetriever.cpp b/media/libmedia/IMediaMetadataRetriever.cpp
index 590ba1a..f9fa86e 100644
--- a/media/libmedia/IMediaMetadataRetriever.cpp
+++ b/media/libmedia/IMediaMetadataRetriever.cpp
@@ -23,6 +23,7 @@
 #include <media/IDataSource.h>
 #include <media/IMediaHTTPService.h>
 #include <media/IMediaMetadataRetriever.h>
+#include <processgroup/sched_policy.h>
 #include <utils/String8.h>
 #include <utils/KeyedVector.h>
 
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp
index e2eccdd..ea06665 100644
--- a/media/libmedia/IMediaPlayer.cpp
+++ b/media/libmedia/IMediaPlayer.cpp
@@ -179,7 +179,8 @@
     {
         Parcel data, reply;
         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
-        buffering.writeToParcel(&data);
+        data.writeInt32(buffering.mInitialMarkMs);
+        data.writeInt32(buffering.mResumePlaybackMarkMs);
         remote()->transact(SET_BUFFERING_SETTINGS, data, &reply);
         return reply.readInt32();
     }
@@ -194,7 +195,8 @@
         remote()->transact(GET_BUFFERING_SETTINGS, data, &reply);
         status_t err = reply.readInt32();
         if (err == OK) {
-            err = buffering->readFromParcel(&reply);
+            buffering->mInitialMarkMs = reply.readInt32();
+            buffering->mResumePlaybackMarkMs = reply.readInt32();
         }
         return err;
     }
@@ -696,7 +698,8 @@
         case SET_BUFFERING_SETTINGS: {
             CHECK_INTERFACE(IMediaPlayer, data, reply);
             BufferingSettings buffering;
-            buffering.readFromParcel(&data);
+            buffering.mInitialMarkMs = data.readInt32();
+            buffering.mResumePlaybackMarkMs = data.readInt32();
             reply->writeInt32(setBufferingSettings(buffering));
             return NO_ERROR;
         } break;
@@ -706,7 +709,8 @@
             status_t err = getBufferingSettings(&buffering);
             reply->writeInt32(err);
             if (err == OK) {
-                buffering.writeToParcel(reply);
+                reply->writeInt32(buffering.mInitialMarkMs);
+                reply->writeInt32(buffering.mResumePlaybackMarkMs);
             }
             return NO_ERROR;
         } break;
diff --git a/media/libmedia/IMediaPlayerService.cpp b/media/libmedia/IMediaPlayerService.cpp
index aca7ad9..bd18a40 100644
--- a/media/libmedia/IMediaPlayerService.cpp
+++ b/media/libmedia/IMediaPlayerService.cpp
@@ -23,6 +23,7 @@
 #include <media/IMediaCodecList.h>
 #include <media/IMediaHTTPService.h>
 #include <media/IMediaPlayerService.h>
+#include <media/IMediaPlayer.h>
 #include <media/IMediaRecorder.h>
 #include <media/IOMX.h>
 #include <media/IRemoteDisplay.h>
diff --git a/media/libmedia/IMediaRecorder.cpp b/media/libmedia/IMediaRecorder.cpp
index b2c91c4..a354ce1 100644
--- a/media/libmedia/IMediaRecorder.cpp
+++ b/media/libmedia/IMediaRecorder.cpp
@@ -65,7 +65,9 @@
     GET_ROUTED_DEVICE_ID,
     ENABLE_AUDIO_DEVICE_CALLBACK,
     GET_ACTIVE_MICROPHONES,
-
+    GET_PORT_ID,
+    SET_PREFERRED_MICROPHONE_DIRECTION,
+    SET_PREFERRED_MICROPHONE_FIELD_DIMENSION
 };
 
 class BpMediaRecorder: public BpInterface<IMediaRecorder>
@@ -407,6 +409,41 @@
         return status;
     }
 
+    status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction) {
+        ALOGV("setPreferredMicrophoneDirection(%d)", direction);
+        Parcel data, reply;
+        data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
+        data.writeInt32(direction);
+        status_t status = remote()->transact(SET_PREFERRED_MICROPHONE_DIRECTION, data, &reply);
+        return status == NO_ERROR ? (status_t)reply.readInt32() : status;
+    }
+
+    status_t setPreferredMicrophoneFieldDimension(float zoom) {
+        ALOGV("setPreferredMicrophoneFieldDimension(%f)", zoom);
+        Parcel data, reply;
+        data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
+        data.writeFloat(zoom);
+        status_t status = remote()->transact(SET_PREFERRED_MICROPHONE_FIELD_DIMENSION, data, &reply);
+        return status == NO_ERROR ? (status_t)reply.readInt32() : status;
+    }
+
+    status_t getPortId(audio_port_handle_t *portId)
+    {
+        ALOGV("getPortId");
+        if (portId == nullptr) {
+            return BAD_VALUE;
+        }
+        Parcel data, reply;
+        data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
+        status_t status = remote()->transact(GET_PORT_ID, data, &reply);
+        if (status != OK
+                || (status = (status_t)reply.readInt32()) != NO_ERROR) {
+            *portId = AUDIO_PORT_HANDLE_NONE;
+            return status;
+        }
+        *portId = (audio_port_handle_t)reply.readInt32();
+        return NO_ERROR;
+    }
 };
 
 IMPLEMENT_META_INTERFACE(MediaRecorder, "android.media.IMediaRecorder");
@@ -661,6 +698,34 @@
             return NO_ERROR;
 
         }
+        case GET_PORT_ID: {
+            ALOGV("GET_PORT_ID");
+            CHECK_INTERFACE(IMediaRecorder, data, reply);
+            audio_port_handle_t portId;
+            status_t status = getPortId(&portId);
+            reply->writeInt32(status);
+            if (status == NO_ERROR) {
+                reply->writeInt32(portId);
+            }
+            return NO_ERROR;
+        }
+        case SET_PREFERRED_MICROPHONE_DIRECTION: {
+            ALOGV("SET_PREFERRED_MICROPHONE_DIRECTION");
+            CHECK_INTERFACE(IMediaRecorder, data, reply);
+            int direction = data.readInt32();
+            status_t status = setPreferredMicrophoneDirection(
+                    static_cast<audio_microphone_direction_t>(direction));
+            reply->writeInt32(status);
+            return NO_ERROR;
+        }
+        case SET_PREFERRED_MICROPHONE_FIELD_DIMENSION: {
+            ALOGV("SET_MICROPHONE_FIELD_DIMENSION");
+            CHECK_INTERFACE(IMediaRecorder, data, reply);
+            float zoom = data.readFloat();
+            status_t status = setPreferredMicrophoneFieldDimension(zoom);
+            reply->writeInt32(status);
+            return NO_ERROR;
+        }
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/media/libmedia/IMediaSource.cpp b/media/libmedia/IMediaSource.cpp
index f185fd4..50826c5 100644
--- a/media/libmedia/IMediaSource.cpp
+++ b/media/libmedia/IMediaSource.cpp
@@ -107,6 +107,7 @@
         data.writeInterfaceToken(BpMediaSource::getInterfaceDescriptor());
         status_t ret = remote()->transact(GETFORMAT, data, &reply);
         if (ret == NO_ERROR) {
+            AutoMutex _l(mLock);
             mMetaData = MetaData::createFromParcel(reply);
             return mMetaData;
         }
@@ -186,6 +187,9 @@
         ret = reply.readInt32();
         ALOGV("readMultiple status %d, bufferCount %u, sinceStop %u",
                 ret, bufferCount, mBuffersSinceStop);
+        if (bufferCount && ret == WOULD_BLOCK) {
+            ret = OK;
+        }
         return ret;
     }
 
@@ -219,6 +223,8 @@
     // NuPlayer passes pointers-to-metadata around, so we use this to keep the metadata alive
     // XXX: could we use this for caching, or does metadata change on the fly?
     sp<MetaData> mMetaData;
+    // ensure synchronize access to mMetaData
+    Mutex mLock;
 
     // Cache all IMemory objects received from MediaExtractor.
     // We gc IMemory objects that are no longer active (referenced by a MediaBuffer).
@@ -362,13 +368,13 @@
                         ALOGV("Use shared memory: %zu", length);
                         transferBuf = buf;
                     } else {
-                        ALOGD("Large buffer %zu without IMemory!", length);
+                        ALOGV("Large buffer %zu without IMemory!", length);
                         ret = mGroup->acquire_buffer(
                                 (MediaBufferBase **)&transferBuf, false /* nonBlocking */, length);
                         if (ret != OK
                                 || transferBuf == nullptr
                                 || transferBuf->mMemory == nullptr) {
-                            ALOGW("Failed to acquire shared memory, size %zu, ret %d",
+                            ALOGV("Failed to acquire shared memory, size %zu, ret %d",
                                     length, ret);
                             if (transferBuf != nullptr) {
                                 transferBuf->release();
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index a073081..bc0c2cd 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -27,7 +27,6 @@
 #include <media/openmax/OMX_IndexExt.h>
 #include <media/OMXBuffer.h>
 #include <utils/NativeHandle.h>
-#include <gui/IGraphicBufferProducer.h>
 
 #include <media/omx/1.0/WOmxNode.h>
 #include <android/IGraphicBufferSource.h>
@@ -62,79 +61,6 @@
     SET_QUIRKS,
 };
 
-class BpOMX : public BpInterface<IOMX> {
-public:
-    explicit BpOMX(const sp<IBinder> &impl)
-        : BpInterface<IOMX>(impl) {
-    }
-
-    virtual status_t listNodes(List<ComponentInfo> *list) {
-        list->clear();
-
-        Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        remote()->transact(LIST_NODES, data, &reply);
-
-        int32_t n = reply.readInt32();
-        for (int32_t i = 0; i < n; ++i) {
-            list->push_back(ComponentInfo());
-            ComponentInfo &info = *--list->end();
-
-            info.mName = reply.readString8();
-            int32_t numRoles = reply.readInt32();
-            for (int32_t j = 0; j < numRoles; ++j) {
-                info.mRoles.push_back(reply.readString8());
-            }
-        }
-
-        return OK;
-    }
-
-    virtual status_t allocateNode(
-            const char *name, const sp<IOMXObserver> &observer,
-            sp<IOMXNode> *omxNode) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeCString(name);
-        data.writeStrongBinder(IInterface::asBinder(observer));
-        remote()->transact(ALLOCATE_NODE, data, &reply);
-
-        status_t err = reply.readInt32();
-        if (err == OK) {
-            *omxNode = IOMXNode::asInterface(reply.readStrongBinder());
-        } else {
-            omxNode->clear();
-        }
-
-        return err;
-    }
-
-    virtual status_t createInputSurface(
-            sp<IGraphicBufferProducer> *bufferProducer,
-            sp<IGraphicBufferSource> *bufferSource) {
-        Parcel data, reply;
-        status_t err;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        err = remote()->transact(CREATE_INPUT_SURFACE, data, &reply);
-        if (err != OK) {
-            ALOGW("binder transaction failed: %d", err);
-            return err;
-        }
-
-        err = reply.readInt32();
-        if (err != OK) {
-            return err;
-        }
-
-        *bufferProducer = IGraphicBufferProducer::asInterface(
-                reply.readStrongBinder());
-        *bufferSource = IGraphicBufferSource::asInterface(
-                reply.readStrongBinder());
-
-        return err;
-    }
-};
-
 class BpOMXNode : public BpInterface<IOMXNode> {
 public:
     explicit BpOMXNode(const sp<IBinder> &impl)
@@ -551,8 +477,7 @@
     }
 };
 
-IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX");
-IMPLEMENT_HYBRID_META_INTERFACE(OMXNode, IOmxNode, "android.hardware.IOMXNode");
+IMPLEMENT_HYBRID_META_INTERFACE(OMXNode, "android.hardware.IOMXNode");
 
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -562,82 +487,6 @@
             return PERMISSION_DENIED; \
         } } while (0)
 
-status_t BnOMX::onTransact(
-    uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
-    switch (code) {
-        case LIST_NODES:
-        {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
-
-            List<ComponentInfo> list;
-            listNodes(&list);
-
-            reply->writeInt32(list.size());
-            for (List<ComponentInfo>::iterator it = list.begin();
-                 it != list.end(); ++it) {
-                ComponentInfo &cur = *it;
-
-                reply->writeString8(cur.mName);
-                reply->writeInt32(cur.mRoles.size());
-                for (List<String8>::iterator role_it = cur.mRoles.begin();
-                     role_it != cur.mRoles.end(); ++role_it) {
-                    reply->writeString8(*role_it);
-                }
-            }
-
-            return NO_ERROR;
-        }
-
-        case ALLOCATE_NODE:
-        {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
-
-            const char *name = data.readCString();
-
-            sp<IOMXObserver> observer =
-                interface_cast<IOMXObserver>(data.readStrongBinder());
-
-            if (name == NULL || observer == NULL) {
-                ALOGE("b/26392700");
-                reply->writeInt32(INVALID_OPERATION);
-                return NO_ERROR;
-            }
-
-            sp<IOMXNode> omxNode;
-
-            status_t err = allocateNode(name, observer, &omxNode);
-
-            reply->writeInt32(err);
-            if (err == OK) {
-                reply->writeStrongBinder(IInterface::asBinder(omxNode));
-            }
-
-            return NO_ERROR;
-        }
-
-        case CREATE_INPUT_SURFACE:
-        {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
-
-            sp<IGraphicBufferProducer> bufferProducer;
-            sp<IGraphicBufferSource> bufferSource;
-            status_t err = createInputSurface(&bufferProducer, &bufferSource);
-
-            reply->writeInt32(err);
-
-            if (err == OK) {
-                reply->writeStrongBinder(IInterface::asBinder(bufferProducer));
-                reply->writeStrongBinder(IInterface::asBinder(bufferSource));
-            }
-
-            return NO_ERROR;
-        }
-
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
-    }
-}
-
 status_t BnOMXNode::onTransact(
     uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
     switch (code) {
diff --git a/media/libmedia/MediaCodecInfo.cpp b/media/libmedia/MediaCodecInfo.cpp
index 5308e1c..86ad997 100644
--- a/media/libmedia/MediaCodecInfo.cpp
+++ b/media/libmedia/MediaCodecInfo.cpp
@@ -28,6 +28,15 @@
 
 namespace android {
 
+/** This redundant redeclaration is needed for C++ pre 14 */
+constexpr char MediaCodecInfo::Capabilities::FEATURE_ADAPTIVE_PLAYBACK[];
+constexpr char MediaCodecInfo::Capabilities::FEATURE_DYNAMIC_TIMESTAMP[];
+constexpr char MediaCodecInfo::Capabilities::FEATURE_FRAME_PARSING[];
+constexpr char MediaCodecInfo::Capabilities::FEATURE_INTRA_REFRESH[];
+constexpr char MediaCodecInfo::Capabilities::FEATURE_MULTIPLE_FRAMES[];
+constexpr char MediaCodecInfo::Capabilities::FEATURE_SECURE_PLAYBACK[];
+constexpr char MediaCodecInfo::Capabilities::FEATURE_TUNNELED_PLAYBACK[];
+
 void MediaCodecInfo::Capabilities::getSupportedProfileLevels(
         Vector<ProfileLevel> *profileLevels) const {
     profileLevels->clear();
@@ -40,16 +49,11 @@
     colorFormats->appendVector(mColorFormats);
 }
 
-uint32_t MediaCodecInfo::Capabilities::getFlags() const {
-    return mFlags;
-}
-
 const sp<AMessage> MediaCodecInfo::Capabilities::getDetails() const {
     return mDetails;
 }
 
-MediaCodecInfo::Capabilities::Capabilities()
-  : mFlags(0) {
+MediaCodecInfo::Capabilities::Capabilities() {
     mDetails = new AMessage;
 }
 
@@ -73,12 +77,10 @@
             caps->mColorFormats.push_back(color);
         }
     }
-    uint32_t flags = static_cast<uint32_t>(parcel.readInt32());
     sp<AMessage> details = AMessage::FromParcel(parcel);
     if (details == NULL)
         return NULL;
     if (caps != NULL) {
-        caps->mFlags = flags;
         caps->mDetails = details;
     }
     return caps;
@@ -96,7 +98,6 @@
     for (size_t i = 0; i < mColorFormats.size(); i++) {
         parcel->writeInt32(mColorFormats.itemAt(i));
     }
-    parcel->writeInt32(mFlags);
     mDetails->writeToParcel(parcel);
     return OK;
 }
@@ -111,6 +112,14 @@
     mCap->mDetails->setInt32(key, value);
 }
 
+void MediaCodecInfo::CapabilitiesWriter::removeDetail(const char* key) {
+    if (mCap->mDetails->removeEntryAt(mCap->mDetails->findEntryByName(key)) == OK) {
+        ALOGD("successfully removed detail %s", key);
+    } else {
+        ALOGD("detail %s wasn't present to remove", key);
+    }
+}
+
 void MediaCodecInfo::CapabilitiesWriter::addProfileLevel(
         uint32_t profile, uint32_t level) {
     ProfileLevel profileLevel;
@@ -129,32 +138,32 @@
     }
 }
 
-void MediaCodecInfo::CapabilitiesWriter::addFlags(uint32_t flags) {
-    mCap->mFlags |= flags;
-}
-
 MediaCodecInfo::CapabilitiesWriter::CapabilitiesWriter(
         MediaCodecInfo::Capabilities* cap) : mCap(cap) {
 }
 
-bool MediaCodecInfo::isEncoder() const {
-    return mIsEncoder;
+MediaCodecInfo::Attributes MediaCodecInfo::getAttributes() const {
+    return mAttributes;
 }
 
-uint32_t MediaCodecInfo::rank() const {
+uint32_t MediaCodecInfo::getRank() const {
     return mRank;
 }
 
-void MediaCodecInfo::getSupportedMimes(Vector<AString> *mimes) const {
-    mimes->clear();
+void MediaCodecInfo::getAliases(Vector<AString> *aliases) const {
+    *aliases = mAliases;
+}
+
+void MediaCodecInfo::getSupportedMediaTypes(Vector<AString> *mediaTypes) const {
+    mediaTypes->clear();
     for (size_t ix = 0; ix < mCaps.size(); ix++) {
-        mimes->push_back(mCaps.keyAt(ix));
+        mediaTypes->push_back(mCaps.keyAt(ix));
     }
 }
 
 const sp<MediaCodecInfo::Capabilities>
-MediaCodecInfo::getCapabilitiesFor(const char *mime) const {
-    ssize_t ix = getCapabilityIndex(mime);
+MediaCodecInfo::getCapabilitiesFor(const char *mediaType) const {
+    ssize_t ix = getCapabilityIndex(mediaType);
     if (ix >= 0) {
         return mCaps.valueAt(ix);
     }
@@ -173,21 +182,26 @@
 sp<MediaCodecInfo> MediaCodecInfo::FromParcel(const Parcel &parcel) {
     AString name = AString::FromParcel(parcel);
     AString owner = AString::FromParcel(parcel);
-    bool isEncoder = static_cast<bool>(parcel.readInt32());
+    Attributes attributes = static_cast<Attributes>(parcel.readInt32());
     uint32_t rank = parcel.readUint32();
     sp<MediaCodecInfo> info = new MediaCodecInfo;
     info->mName = name;
     info->mOwner = owner;
-    info->mIsEncoder = isEncoder;
+    info->mAttributes = attributes;
     info->mRank = rank;
+    size_t numAliases = static_cast<size_t>(parcel.readInt32());
+    for (size_t i = 0; i < numAliases; i++) {
+        AString alias = AString::FromParcel(parcel);
+        info->mAliases.add(alias);
+    }
     size_t size = static_cast<size_t>(parcel.readInt32());
     for (size_t i = 0; i < size; i++) {
-        AString mime = AString::FromParcel(parcel);
+        AString mediaType = AString::FromParcel(parcel);
         sp<Capabilities> caps = Capabilities::FromParcel(parcel);
         if (caps == NULL)
             return NULL;
         if (info != NULL) {
-            info->mCaps.add(mime, caps);
+            info->mCaps.add(mediaType, caps);
         }
     }
     return info;
@@ -196,8 +210,12 @@
 status_t MediaCodecInfo::writeToParcel(Parcel *parcel) const {
     mName.writeToParcel(parcel);
     mOwner.writeToParcel(parcel);
-    parcel->writeInt32(mIsEncoder);
+    parcel->writeInt32(mAttributes);
     parcel->writeUint32(mRank);
+    parcel->writeInt32(mAliases.size());
+    for (const AString &alias : mAliases) {
+        alias.writeToParcel(parcel);
+    }
     parcel->writeInt32(mCaps.size());
     for (size_t i = 0; i < mCaps.size(); i++) {
         mCaps.keyAt(i).writeToParcel(parcel);
@@ -206,10 +224,10 @@
     return OK;
 }
 
-ssize_t MediaCodecInfo::getCapabilityIndex(const char *mime) const {
-    if (mime) {
+ssize_t MediaCodecInfo::getCapabilityIndex(const char *mediaType) const {
+    if (mediaType) {
         for (size_t ix = 0; ix < mCaps.size(); ix++) {
-            if (mCaps.keyAt(ix).equalsIgnoreCase(mime)) {
+            if (mCaps.keyAt(ix).equalsIgnoreCase(mediaType)) {
                 return ix;
             }
         }
@@ -217,19 +235,26 @@
     return -1;
 }
 
-MediaCodecInfo::MediaCodecInfo() : mRank(0x100) {
+MediaCodecInfo::MediaCodecInfo()
+    : mAttributes((MediaCodecInfo::Attributes)0),
+      mRank(0x100) {
 }
 
 void MediaCodecInfoWriter::setName(const char* name) {
     mInfo->mName = name;
 }
 
+void MediaCodecInfoWriter::addAlias(const char* name) {
+    mInfo->mAliases.add(name);
+}
+
 void MediaCodecInfoWriter::setOwner(const char* owner) {
     mInfo->mOwner = owner;
 }
 
-void MediaCodecInfoWriter::setEncoder(bool isEncoder) {
-    mInfo->mIsEncoder = isEncoder;
+void MediaCodecInfoWriter::setAttributes(
+        typename std::underlying_type<MediaCodecInfo::Attributes>::type attributes) {
+    mInfo->mAttributes = (MediaCodecInfo::Attributes)attributes;
 }
 
 void MediaCodecInfoWriter::setRank(uint32_t rank) {
@@ -237,21 +262,21 @@
 }
 
 std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>
-        MediaCodecInfoWriter::addMime(const char *mime) {
-    ssize_t ix = mInfo->getCapabilityIndex(mime);
+        MediaCodecInfoWriter::addMediaType(const char *mediaType) {
+    ssize_t ix = mInfo->getCapabilityIndex(mediaType);
     if (ix >= 0) {
         return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>(
                 new MediaCodecInfo::CapabilitiesWriter(
                 mInfo->mCaps.valueAt(ix).get()));
     }
     sp<MediaCodecInfo::Capabilities> caps = new MediaCodecInfo::Capabilities();
-    mInfo->mCaps.add(AString(mime), caps);
+    mInfo->mCaps.add(AString(mediaType), caps);
     return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>(
             new MediaCodecInfo::CapabilitiesWriter(caps.get()));
 }
 
-bool MediaCodecInfoWriter::removeMime(const char *mime) {
-    ssize_t ix = mInfo->getCapabilityIndex(mime);
+bool MediaCodecInfoWriter::removeMediaType(const char *mediaType) {
+    ssize_t ix = mInfo->getCapabilityIndex(mediaType);
     if (ix >= 0) {
         mInfo->mCaps.removeItemsAt(ix);
         return true;
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index aade69a..98c5497 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -48,7 +48,8 @@
     {"amrwb",  AUDIO_ENCODER_AMR_WB},
     {"aac",    AUDIO_ENCODER_AAC},
     {"heaac",  AUDIO_ENCODER_HE_AAC},
-    {"aaceld", AUDIO_ENCODER_AAC_ELD}
+    {"aaceld", AUDIO_ENCODER_AAC_ELD}, 
+    {"opus",   AUDIO_ENCODER_OPUS}
 };
 
 const MediaProfiles::NameToTagMap MediaProfiles::sFileFormatMap[] = {
@@ -91,6 +92,19 @@
     {"highspeed720p", CAMCORDER_QUALITY_HIGH_SPEED_720P},
     {"highspeed1080p", CAMCORDER_QUALITY_HIGH_SPEED_1080P},
     {"highspeed2160p", CAMCORDER_QUALITY_HIGH_SPEED_2160P},
+
+    // Vendor-specific profiles
+    {"vga", CAMCORDER_QUALITY_VGA},
+    {"4kdci", CAMCORDER_QUALITY_4KDCI},
+    {"timelapsevga", CAMCORDER_QUALITY_TIME_LAPSE_VGA},
+    {"timelapse4kdci", CAMCORDER_QUALITY_TIME_LAPSE_4KDCI},
+    {"highspeedcif", CAMCORDER_QUALITY_HIGH_SPEED_CIF},
+    {"highspeedvga", CAMCORDER_QUALITY_HIGH_SPEED_VGA},
+    {"highspeed4kdci", CAMCORDER_QUALITY_HIGH_SPEED_4KDCI},
+    {"qhd", CAMCORDER_QUALITY_QHD},
+    {"2k", CAMCORDER_QUALITY_2k},
+    {"timelapseqhd", CAMCORDER_QUALITY_TIME_LAPSE_QHD},
+    {"timelapse2k", CAMCORDER_QUALITY_TIME_LAPSE_2k},
 };
 
 #if LOG_NDEBUG
@@ -546,8 +560,8 @@
 
             if (info->mHasRefProfile) {
 
-                CamcorderProfile *profile =
-                    new CamcorderProfile(
+                std::unique_ptr<CamcorderProfile> profile =
+                    std::make_unique<CamcorderProfile>(
                             *mCamcorderProfiles[info->mRefProfileIndex]);
 
                 // Overwrite the quality
@@ -581,7 +595,7 @@
                         mCamcorderProfiles[info->mRefProfileIndex]->mQuality,
                         profile->mQuality, cameraId);
 
-                mCamcorderProfiles.add(profile);
+                mCamcorderProfiles.add(profile.release());
             }
         }
     }
diff --git a/media/libmedia/MediaUtils.cpp b/media/libmedia/MediaUtils.cpp
index bcdc3bd..31972fa 100644
--- a/media/libmedia/MediaUtils.cpp
+++ b/media/libmedia/MediaUtils.cpp
@@ -22,22 +22,16 @@
 #include <sys/resource.h>
 #include <unistd.h>
 
+#include <bionic_malloc.h>
+
 #include "MediaUtils.h"
 
-extern "C" size_t __cfi_shadow_size();
+extern "C" void __scudo_set_rss_limit(size_t, int) __attribute__((weak));
 
 namespace android {
 
-void limitProcessMemory(
-    const char *property,
-    size_t numberOfBytes,
-    size_t percentageOfTotalMem) {
-
-    if (running_with_asan()) {
-        ALOGW("Running with ASan, skip enforcing memory limitations.");
-        return;
-    }
-
+void limitProcessMemory(const char *property, size_t numberOfBytes,
+                        size_t percentageOfTotalMem) {
     long pageSize = sysconf(_SC_PAGESIZE);
     long numPages = sysconf(_SC_PHYS_PAGES);
     size_t maxMem = SIZE_MAX;
@@ -65,30 +59,17 @@
         maxMem = propVal;
     }
 
-    // Increase by the size of the CFI shadow mapping. Most of the shadow is not
-    // backed with physical pages, and it is possible for the result to be
-    // higher than total physical memory. This is fine for RLIMIT_AS.
-    size_t cfi_size = __cfi_shadow_size();
-    if (cfi_size) {
-      ALOGV("cfi shadow size: %zu", cfi_size);
-      if (maxMem <= SIZE_MAX - cfi_size) {
-        maxMem += cfi_size;
-      } else {
-        maxMem = SIZE_MAX;
-      }
+    // If Scudo is in use, enforce the hard RSS limit (in MB).
+    if (maxMem != SIZE_MAX && &__scudo_set_rss_limit != 0) {
+      __scudo_set_rss_limit(maxMem >> 20, 1);
+      ALOGV("Scudo hard RSS limit set to %zu MB", maxMem >> 20);
+      return;
     }
-    ALOGV("actual limit: %zu", maxMem);
 
-    struct rlimit limit;
-    getrlimit(RLIMIT_AS, &limit);
-    ALOGV("original limits: %lld/%lld", (long long)limit.rlim_cur, (long long)limit.rlim_max);
-    limit.rlim_cur = maxMem;
-    setrlimit(RLIMIT_AS, &limit);
-    limit.rlim_cur = -1;
-    limit.rlim_max = -1;
-    getrlimit(RLIMIT_AS, &limit);
-    ALOGV("new limits: %lld/%lld", (long long)limit.rlim_cur, (long long)limit.rlim_max);
-
+    if (!android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &maxMem,
+                         sizeof(maxMem))) {
+      ALOGW("couldn't set allocation limit");
+    }
 }
 
 } // namespace android
diff --git a/media/libmedia/MediaUtils.h b/media/libmedia/MediaUtils.h
index a678bcc..f80dd30 100644
--- a/media/libmedia/MediaUtils.h
+++ b/media/libmedia/MediaUtils.h
@@ -19,12 +19,6 @@
 
 namespace android {
 
-extern "C" void __asan_init(void) __attribute__((weak));
-
-static inline int running_with_asan() {
-    return &__asan_init != 0;
-}
-
 /**
    Limit the amount of memory a process can allocate using setrlimit(RLIMIT_AS).
    The value to use will be read from the specified system property, or if the
diff --git a/media/libmedia/MidiIoWrapper.cpp b/media/libmedia/MidiIoWrapper.cpp
index 5ca3b48..d8ef9cf 100644
--- a/media/libmedia/MidiIoWrapper.cpp
+++ b/media/libmedia/MidiIoWrapper.cpp
@@ -23,6 +23,7 @@
 #include <fcntl.h>
 
 #include <media/MidiIoWrapper.h>
+#include <media/MediaExtractorPluginApi.h>
 
 static int readAt(void *handle, void *buffer, int pos, int size) {
     return ((android::MidiIoWrapper*)handle)->readAt(buffer, pos, size);
@@ -49,10 +50,47 @@
     mDataSource = nullptr;
 }
 
-MidiIoWrapper::MidiIoWrapper(DataSourceBase *source) {
-    ALOGV("MidiIoWrapper(DataSource)");
+class DataSourceUnwrapper : public DataSourceBase {
+
+public:
+    explicit DataSourceUnwrapper(CDataSource *csource) {
+        mSource = csource;
+    }
+
+    virtual ~DataSourceUnwrapper() {}
+
+    virtual status_t initCheck() const { return OK; }
+
+    // Returns the number of bytes read, or -1 on failure. It's not an error if
+    // this returns zero; it just means the given offset is equal to, or
+    // beyond, the end of the source.
+    virtual ssize_t readAt(off64_t offset, void *data, size_t size) {
+        return mSource->readAt(mSource->handle, offset, data, size);
+    }
+
+    // May return ERROR_UNSUPPORTED.
+    virtual status_t getSize(off64_t *size) {
+        return mSource->getSize(mSource->handle, size);
+    }
+
+    virtual bool getUri(char * /*uriString*/, size_t /*bufferSize*/) {
+        return false;
+    }
+
+    virtual uint32_t flags() {
+        return 0;
+    }
+
+    virtual void close() {};
+private:
+    CDataSource *mSource;
+};
+
+MidiIoWrapper::MidiIoWrapper(CDataSource *csource) {
+    ALOGV("MidiIoWrapper(CDataSource)");
     mFd = -1;
-    mDataSource = source;
+    mBase = 0;
+    mDataSource = new DataSourceUnwrapper(csource);
     off64_t l;
     if (mDataSource->getSize(&l) == OK) {
         mLength = l;
@@ -66,6 +104,7 @@
     if (mFd >= 0) {
         close(mFd);
     }
+    delete mDataSource;
 }
 
 int MidiIoWrapper::readAt(void *buffer, int offset, int size) {
diff --git a/media/libmedia/NdkMediaErrorPriv.cpp b/media/libmedia/NdkMediaErrorPriv.cpp
new file mode 100644
index 0000000..ba3b919
--- /dev/null
+++ b/media/libmedia/NdkMediaErrorPriv.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <media/NdkMediaError.h>
+#include <media/stagefright/MediaErrors.h>
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+using namespace android;
+
+media_status_t translate_error(status_t err) {
+
+    if (err == OK) {
+        return AMEDIA_OK;
+    } else if (err == ERROR_END_OF_STREAM) {
+        return AMEDIA_ERROR_END_OF_STREAM;
+    } else if (err == ERROR_IO) {
+        return AMEDIA_ERROR_IO;
+    } else if (err == ERROR_MALFORMED) {
+        return AMEDIA_ERROR_MALFORMED;
+    } else if (err == INVALID_OPERATION) {
+        return AMEDIA_ERROR_INVALID_OPERATION;
+    } else if (err == UNKNOWN_ERROR) {
+        return AMEDIA_ERROR_UNKNOWN;
+    }
+
+    ALOGE("sf error code: %d", err);
+    return AMEDIA_ERROR_UNKNOWN;
+}
+
+status_t reverse_translate_error(media_status_t err) {
+
+    if (err == AMEDIA_OK) {
+        return OK;
+    } else if (err == AMEDIA_ERROR_END_OF_STREAM) {
+        return ERROR_END_OF_STREAM;
+    } else if (err == AMEDIA_ERROR_IO) {
+        return ERROR_IO;
+    } else if (err == AMEDIA_ERROR_WOULD_BLOCK) {
+        return WOULD_BLOCK;
+    } else if (err == AMEDIA_ERROR_MALFORMED) {
+        return ERROR_MALFORMED;
+    } else if (err == AMEDIA_ERROR_INVALID_OPERATION) {
+        return INVALID_OPERATION;
+    } else if (err == AMEDIA_ERROR_UNKNOWN) {
+        return UNKNOWN_ERROR;
+    }
+
+    ALOGE("ndk error code: %d", err);
+    return UNKNOWN_ERROR;
+}
diff --git a/media/libmedia/NdkMediaFormatPriv.cpp b/media/libmedia/NdkMediaFormatPriv.cpp
new file mode 100644
index 0000000..3a9fb8b
--- /dev/null
+++ b/media/libmedia/NdkMediaFormatPriv.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "NdkMediaFormat"
+
+#include <inttypes.h>
+
+#include <utils/Log.h>
+#include <utils/StrongPointer.h>
+#include <media/NdkMediaFormatPriv.h>
+#include <media/stagefright/foundation/AMessage.h>
+
+#include <jni.h>
+
+using namespace android;
+
+namespace android {
+
+// private functions for conversion to/from AMessage
+AMediaFormat* AMediaFormat_fromMsg(sp<AMessage> *data) {
+    ALOGV("private ctor");
+    AMediaFormat* mData = new AMediaFormat();
+    mData->mFormat = *data;
+    if (mData->mFormat == NULL) {
+        ALOGW("got NULL format");
+        mData->mFormat = new AMessage;
+    }
+    return mData;
+}
+
+void AMediaFormat_getFormat(const AMediaFormat* mData, sp<AMessage> *dest) {
+    *dest = mData->mFormat;
+}
+
+} // namespace android
+
+
diff --git a/media/libmedia/NdkWrapper.cpp b/media/libmedia/NdkWrapper.cpp
index 272bc30..c150407 100644
--- a/media/libmedia/NdkWrapper.cpp
+++ b/media/libmedia/NdkWrapper.cpp
@@ -31,17 +31,7 @@
 #include <media/stagefright/foundation/AMessage.h>
 #include <utils/Errors.h>
 
-// TODO: remove forward declaration when AMediaExtractor_disconnect is offcially added to NDK
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-media_status_t AMediaExtractor_disconnect(AMediaExtractor *);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
+#include "NdkMediaDataSourceCallbacksPriv.h"
 
 namespace android {
 
@@ -67,9 +57,15 @@
     AMEDIAFORMAT_KEY_COLOR_STANDARD,
     AMEDIAFORMAT_KEY_COLOR_TRANSFER,
     AMEDIAFORMAT_KEY_COMPLEXITY,
+    AMEDIAFORMAT_KEY_CREATE_INPUT_SURFACE_SUSPENDED,
+    AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE,
+    AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK,
+    AMEDIAFORMAT_KEY_CRYPTO_MODE,
+    AMEDIAFORMAT_KEY_CRYPTO_SKIP_BYTE_BLOCK,
     AMEDIAFORMAT_KEY_FLAC_COMPRESSION_LEVEL,
     AMEDIAFORMAT_KEY_GRID_COLUMNS,
     AMEDIAFORMAT_KEY_GRID_ROWS,
+    AMEDIAFORMAT_KEY_HAPTIC_CHANNEL_COUNT,
     AMEDIAFORMAT_KEY_HEIGHT,
     AMEDIAFORMAT_KEY_INTRA_REFRESH_PERIOD,
     AMEDIAFORMAT_KEY_IS_ADTS,
@@ -101,6 +97,7 @@
 
 static const char *AMediaFormatKeyGroupInt64[] = {
     AMEDIAFORMAT_KEY_DURATION,
+    AMEDIAFORMAT_KEY_MAX_PTS_GAP_TO_ENCODER,
     AMEDIAFORMAT_KEY_REPEAT_PREVIOUS_FRAME_AFTER,
     AMEDIAFORMAT_KEY_TIME_US,
 };
@@ -112,6 +109,8 @@
 };
 
 static const char *AMediaFormatKeyGroupBuffer[] = {
+    AMEDIAFORMAT_KEY_CRYPTO_IV,
+    AMEDIAFORMAT_KEY_CRYPTO_KEY,
     AMEDIAFORMAT_KEY_HDR_STATIC_INFO,
     AMEDIAFORMAT_KEY_SEI,
     AMEDIAFORMAT_KEY_MPEG_USER_DATA,
@@ -130,6 +129,7 @@
 static const char *AMediaFormatKeyGroupFloatInt32[] = {
     AMEDIAFORMAT_KEY_FRAME_RATE,
     AMEDIAFORMAT_KEY_I_FRAME_INTERVAL,
+    AMEDIAFORMAT_KEY_MAX_FPS_TO_ENCODER,
     AMEDIAFORMAT_KEY_OPERATING_RATE,
 };
 
@@ -1080,14 +1080,6 @@
     return OK;
 }
 
-status_t AMediaExtractorWrapper::disconnect() {
-    if (mAMediaExtractor != NULL) {
-        media_status_t err = AMediaExtractor_disconnect(mAMediaExtractor);
-        return translateErrorCode(err);
-    }
-    return DEAD_OBJECT;
-}
-
 AMediaExtractor *AMediaExtractorWrapper::getAMediaExtractor() const {
     return mAMediaExtractor;
 }
@@ -1261,40 +1253,28 @@
     if (mAMediaExtractor == NULL) {
         return NULL;
     }
-    return new AMediaCodecCryptoInfoWrapper(AMediaExtractor_getSampleCryptoInfo(mAMediaExtractor));
-}
-
-ssize_t AMediaDataSourceWrapper::AMediaDataSourceWrapper_getSize(void *userdata) {
-    DataSource *source = static_cast<DataSource *>(userdata);
-    off64_t size = -1;
-    source->getSize(&size);
-    return size;
-}
-
-ssize_t AMediaDataSourceWrapper::AMediaDataSourceWrapper_readAt(void *userdata, off64_t offset, void * buf, size_t size) {
-    DataSource *source = static_cast<DataSource *>(userdata);
-    return source->readAt(offset, buf, size);
-}
-
-void AMediaDataSourceWrapper::AMediaDataSourceWrapper_close(void *userdata) {
-    DataSource *source = static_cast<DataSource *>(userdata);
-    source->close();
+    AMediaCodecCryptoInfo *cryptoInfo = AMediaExtractor_getSampleCryptoInfo(mAMediaExtractor);
+    if (cryptoInfo == NULL) {
+        return NULL;
+    }
+    return new AMediaCodecCryptoInfoWrapper(cryptoInfo);
 }
 
 AMediaDataSourceWrapper::AMediaDataSourceWrapper(const sp<DataSource> &dataSource)
     : mDataSource(dataSource),
-      mAMediaDataSource(AMediaDataSource_new()) {
-    ALOGV("setDataSource (source: %p)", dataSource.get());
-    AMediaDataSource_setUserdata(mAMediaDataSource, dataSource.get());
-    AMediaDataSource_setReadAt(mAMediaDataSource, AMediaDataSourceWrapper_readAt);
-    AMediaDataSource_setGetSize(mAMediaDataSource, AMediaDataSourceWrapper_getSize);
-    AMediaDataSource_setClose(mAMediaDataSource, AMediaDataSourceWrapper_close);
+      mAMediaDataSource(convertDataSourceToAMediaDataSource(dataSource)) {
+}
+
+AMediaDataSourceWrapper::AMediaDataSourceWrapper(AMediaDataSource *aDataSource)
+    : mDataSource(NULL),
+      mAMediaDataSource(aDataSource) {
 }
 
 AMediaDataSourceWrapper::~AMediaDataSourceWrapper() {
     if (mAMediaDataSource == NULL) {
         return;
     }
+    AMediaDataSource_close(mAMediaDataSource);
     AMediaDataSource_delete(mAMediaDataSource);
     mAMediaDataSource = NULL;
 }
@@ -1303,4 +1283,8 @@
     return mAMediaDataSource;
 }
 
+void AMediaDataSourceWrapper::close() {
+    AMediaDataSource_close(mAMediaDataSource);
+}
+
 }  // namespace android
diff --git a/media/libmedia/OMXBuffer.cpp b/media/libmedia/OMXBuffer.cpp
index 6d54a13..30dc22d 100644
--- a/media/libmedia/OMXBuffer.cpp
+++ b/media/libmedia/OMXBuffer.cpp
@@ -172,7 +172,7 @@
     return OK;
 }
 
-OMXBuffer& OMXBuffer::operator=(OMXBuffer&& source) {
+OMXBuffer& OMXBuffer::operator=(OMXBuffer&& source) noexcept {
     mBufferType = std::move(source.mBufferType);
     mRangeOffset = std::move(source.mRangeOffset);
     mRangeLength = std::move(source.mRangeLength);
diff --git a/media/libmedia/TimeCheck.cpp b/media/libmedia/TimeCheck.cpp
deleted file mode 100644
index dab5d4f..0000000
--- a/media/libmedia/TimeCheck.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include <media/TimeCheck.h>
-
-namespace android {
-
-/* static */
-sp<TimeCheck::TimeCheckThread> TimeCheck::getTimeCheckThread()
-{
-    static sp<TimeCheck::TimeCheckThread> sTimeCheckThread = new TimeCheck::TimeCheckThread();
-    return sTimeCheckThread;
-}
-
-TimeCheck::TimeCheck(const char *tag, uint32_t timeoutMs)
-    : mEndTimeNs(getTimeCheckThread()->startMonitoring(tag, timeoutMs))
-{
-}
-
-TimeCheck::~TimeCheck() {
-    getTimeCheckThread()->stopMonitoring(mEndTimeNs);
-}
-
-TimeCheck::TimeCheckThread::~TimeCheckThread()
-{
-    AutoMutex _l(mMutex);
-    requestExit();
-    mMonitorRequests.clear();
-    mCond.signal();
-}
-
-nsecs_t TimeCheck::TimeCheckThread::startMonitoring(const char *tag, uint32_t timeoutMs) {
-    Mutex::Autolock _l(mMutex);
-    nsecs_t endTimeNs = systemTime() + milliseconds(timeoutMs);
-    for (; mMonitorRequests.indexOfKey(endTimeNs) >= 0; ++endTimeNs);
-    mMonitorRequests.add(endTimeNs, tag);
-    mCond.signal();
-    return endTimeNs;
-}
-
-void TimeCheck::TimeCheckThread::stopMonitoring(nsecs_t endTimeNs) {
-    Mutex::Autolock _l(mMutex);
-    mMonitorRequests.removeItem(endTimeNs);
-    mCond.signal();
-}
-
-bool TimeCheck::TimeCheckThread::threadLoop()
-{
-    status_t status = TIMED_OUT;
-    const char *tag;
-    {
-        AutoMutex _l(mMutex);
-
-        if (exitPending()) {
-            return false;
-        }
-
-        nsecs_t endTimeNs = INT64_MAX;
-        // KeyedVector mMonitorRequests is ordered so take first entry as next timeout
-        if (mMonitorRequests.size() != 0) {
-            endTimeNs = mMonitorRequests.keyAt(0);
-            tag = mMonitorRequests.valueAt(0);
-        }
-
-        const nsecs_t waitTimeNs = endTimeNs - systemTime();
-        if (waitTimeNs > 0) {
-            status = mCond.waitRelative(mMutex, waitTimeNs);
-        }
-    }
-    LOG_ALWAYS_FATAL_IF(status != NO_ERROR, "TimeCheck timeout for %s", tag);
-    return true;
-}
-
-}; // namespace android
diff --git a/media/libmedia/TypeConverter.cpp b/media/libmedia/TypeConverter.cpp
index a3db754..5be78d1 100644
--- a/media/libmedia/TypeConverter.cpp
+++ b/media/libmedia/TypeConverter.cpp
@@ -74,6 +74,7 @@
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_WIRED_HEADSET),
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_AUX_DIGITAL),
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_HDMI),
+    MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_HDMI_ARC),
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_TELEPHONY_RX),
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_VOICE_CALL),
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BACK_MIC),
@@ -93,6 +94,8 @@
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BUS),
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_PROXY),
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_USB_HEADSET),
+    MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_BLE),
+    MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_ECHO_REFERENCE),
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_DEFAULT),
     // STUB must be after DEFAULT, so the latter is picked up by toString first.
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_STUB),
@@ -132,6 +135,7 @@
     MAKE_STRING_FROM_ENUM(AUDIO_INPUT_FLAG_MMAP_NOIRQ),
     MAKE_STRING_FROM_ENUM(AUDIO_INPUT_FLAG_VOIP_TX),
     MAKE_STRING_FROM_ENUM(AUDIO_INPUT_FLAG_HW_AV_SYNC),
+    MAKE_STRING_FROM_ENUM(AUDIO_INPUT_FLAG_DIRECT),
     TERMINATOR
 };
 
@@ -205,6 +209,15 @@
     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_MAT_1_0),
     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_MAT_2_0),
     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_MAT_2_1),
+    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_LATM),
+    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_LATM_LC),
+    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_LATM_HE_V1),
+    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_LATM_HE_V2),
+    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_CELT),
+    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_APTX_ADAPTIVE),
+    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_LHDC),
+    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_LHDC_LL),
+    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_APTX_TWSP),
     TERMINATOR
 };
 
@@ -216,6 +229,9 @@
     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_2POINT1),
     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_2POINT0POINT2),
     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_2POINT1POINT2),
+    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_TRI),
+    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_TRI_BACK),
+    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_3POINT1),
     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_3POINT0POINT2),
     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_3POINT1POINT2),
     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_QUAD),
@@ -232,6 +248,12 @@
     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_7POINT1POINT2),
     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_7POINT1POINT4),
+    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_HAPTIC_A),
+    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_MONO_HAPTIC_A),
+    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A),
+    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_HAPTIC_AB),
+    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_MONO_HAPTIC_AB),
+    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_STEREO_HAPTIC_AB),
     TERMINATOR
 };
 
@@ -278,6 +300,7 @@
 
 template <>
 const StreamTypeConverter::Table StreamTypeConverter::mTable[] = {
+    MAKE_STRING_FROM_ENUM(AUDIO_STREAM_DEFAULT),
     MAKE_STRING_FROM_ENUM(AUDIO_STREAM_VOICE_CALL),
     MAKE_STRING_FROM_ENUM(AUDIO_STREAM_SYSTEM),
     MAKE_STRING_FROM_ENUM(AUDIO_STREAM_RING),
@@ -349,11 +372,31 @@
     MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_VOICE_COMMUNICATION),
     MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_REMOTE_SUBMIX),
     MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_UNPROCESSED),
+    MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_VOICE_PERFORMANCE),
+    MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_ECHO_REFERENCE),
     MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_FM_TUNER),
     MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_HOTWORD),
     TERMINATOR
 };
 
+template <>
+const AudioFlagConverter::Table AudioFlagConverter::mTable[] = {
+    MAKE_STRING_FROM_ENUM(AUDIO_FLAG_NONE),
+    MAKE_STRING_FROM_ENUM(AUDIO_FLAG_AUDIBILITY_ENFORCED),
+    MAKE_STRING_FROM_ENUM(AUDIO_FLAG_SECURE),
+    MAKE_STRING_FROM_ENUM(AUDIO_FLAG_SCO),
+    MAKE_STRING_FROM_ENUM(AUDIO_FLAG_BEACON),
+    MAKE_STRING_FROM_ENUM(AUDIO_FLAG_HW_AV_SYNC),
+    MAKE_STRING_FROM_ENUM(AUDIO_FLAG_HW_HOTWORD),
+    MAKE_STRING_FROM_ENUM(AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY),
+    MAKE_STRING_FROM_ENUM(AUDIO_FLAG_BYPASS_MUTE),
+    MAKE_STRING_FROM_ENUM(AUDIO_FLAG_LOW_LATENCY),
+    MAKE_STRING_FROM_ENUM(AUDIO_FLAG_DEEP_BUFFER),
+    MAKE_STRING_FROM_ENUM(AUDIO_FLAG_NO_MEDIA_PROJECTION),
+    MAKE_STRING_FROM_ENUM(AUDIO_FLAG_NO_SYSTEM_CAPTURE),
+    TERMINATOR
+};
+
 template class TypeConverter<OutputDeviceTraits>;
 template class TypeConverter<InputDeviceTraits>;
 template class TypeConverter<OutputFlagTraits>;
@@ -367,20 +410,13 @@
 template class TypeConverter<AudioModeTraits>;
 template class TypeConverter<UsageTraits>;
 template class TypeConverter<SourceTraits>;
+template class TypeConverter<AudioFlagTraits>;
 
 bool deviceFromString(const std::string& literalDevice, audio_devices_t& device) {
     return InputDeviceConverter::fromString(literalDevice, device) ||
             OutputDeviceConverter::fromString(literalDevice, device);
 }
 
-bool deviceToString(audio_devices_t device, std::string& literalDevice) {
-    if (device & AUDIO_DEVICE_BIT_IN) {
-        return InputDeviceConverter::toString(device, literalDevice);
-    } else {
-        return OutputDeviceConverter::toString(device, literalDevice);
-    }
-}
-
 SampleRateTraits::Collection samplingRatesFromString(
         const std::string &samplingRates, const char *del)
 {
diff --git a/media/libmedia/aidl/android/media/IMediaExtractorUpdateService.aidl b/media/libmedia/aidl/android/media/IMediaExtractorUpdateService.aidl
deleted file mode 100644
index 57b1bc9..0000000
--- a/media/libmedia/aidl/android/media/IMediaExtractorUpdateService.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-/**
- * Service to reload extractor plugins when update package is installed/uninstalled.
- * @hide
- */
-interface IMediaExtractorUpdateService {
-    void loadPlugins(@utf8InCpp String apkPath);
-}
diff --git a/media/libmedia/exports.lds b/media/libmedia/exports.lds
index b09fbce..904a7f7 100644
--- a/media/libmedia/exports.lds
+++ b/media/libmedia/exports.lds
@@ -3,5 +3,5 @@
         *;
     local:
         _ZN7android13MidiIoWrapper*;
-        _ZTVN7android13MidiIoWrapperE;
+        _ZTVN7android13MidiIoWrapperE*;
 };
diff --git a/media/libmedia/include/media/BufferProviders.h b/media/libmedia/include/media/BufferProviders.h
index d6a9cfb..b038854 100644
--- a/media/libmedia/include/media/BufferProviders.h
+++ b/media/libmedia/include/media/BufferProviders.h
@@ -78,6 +78,7 @@
 
     // Overrides PassthruBufferProvider
     virtual void reset();
+    void setBufferProvider(AudioBufferProvider *p) override;
 
     // this function should be supplied by the derived class.  It converts
     // #frames in the *src pointer to the *dst pointer.  It is public because
@@ -186,6 +187,7 @@
 
     // Overrides PassthruBufferProvider
     virtual void reset();
+    void setBufferProvider(AudioBufferProvider *p) override;
 
     virtual status_t setPlaybackRate(const AudioPlaybackRate &playbackRate);
 
@@ -216,6 +218,41 @@
     bool                 mAudioPlaybackRateValid; // flag for current parameters validity
 };
 
+// AdjustChannelsBufferProvider derives from CopyBufferProvider to adjust sample data.
+// Expands or contracts sample data from one interleaved channel format to another.
+// Extra expanded channels are filled with zeros and put at the end of each audio frame.
+// Contracted channels are copied to the end of the output buffer(storage should be
+// allocated appropriately).
+// Contracted channels could be written to output buffer.
+class AdjustChannelsBufferProvider : public CopyBufferProvider {
+public:
+    AdjustChannelsBufferProvider(audio_format_t format, size_t inChannelCount,
+            size_t outChannelCount, size_t frameCount) : AdjustChannelsBufferProvider(
+                    format, inChannelCount, outChannelCount,
+                    frameCount, AUDIO_FORMAT_INVALID, nullptr) { }
+    // Contracted data is converted to contractedFormat and put into contractedBuffer.
+    AdjustChannelsBufferProvider(audio_format_t format, size_t inChannelCount,
+            size_t outChannelCount, size_t frameCount, audio_format_t contractedFormat,
+            void* contractedBuffer);
+    //Overrides
+    status_t getNextBuffer(Buffer* pBuffer) override;
+    void copyFrames(void *dst, const void *src, size_t frames) override;
+    void reset() override;
+
+    void clearContractedFrames() { mContractedWrittenFrames = 0; }
+
+protected:
+    const audio_format_t mFormat;
+    const size_t         mInChannelCount;
+    const size_t         mOutChannelCount;
+    const size_t         mSampleSizeInBytes;
+    const size_t         mFrameCount;
+    const size_t         mContractedChannelCount;
+    const audio_format_t mContractedFormat;
+    void                *mContractedBuffer;
+    size_t               mContractedWrittenFrames;
+    size_t               mContractedFrameSize;
+};
 // ----------------------------------------------------------------------------
 } // namespace android
 
diff --git a/media/libmedia/include/media/BufferingSettings.h b/media/libmedia/include/media/BufferingSettings.h
index d2a3e40..d97cc00 100644
--- a/media/libmedia/include/media/BufferingSettings.h
+++ b/media/libmedia/include/media/BufferingSettings.h
@@ -17,11 +17,11 @@
 #ifndef ANDROID_BUFFERING_SETTINGS_H
 #define ANDROID_BUFFERING_SETTINGS_H
 
-#include <binder/Parcelable.h>
+#include <utils/String8.h>
 
 namespace android {
 
-struct BufferingSettings : public Parcelable {
+struct BufferingSettings {
     static const int kNoMark = -1;
 
     int mInitialMarkMs;
@@ -32,9 +32,6 @@
 
     BufferingSettings();
 
-    status_t writeToParcel(Parcel* parcel) const override;
-    status_t readFromParcel(const Parcel* parcel) override;
-
     String8 toString() const;
 };
 
diff --git a/media/libmedia/include/media/CharacterEncodingDetector.h b/media/libmedia/include/media/CharacterEncodingDetector.h
index deaa377..62564b1 100644
--- a/media/libmedia/include/media/CharacterEncodingDetector.h
+++ b/media/libmedia/include/media/CharacterEncodingDetector.h
@@ -54,6 +54,7 @@
         StringArray     mValues;
 
         UConverter*     mUtf8Conv;
+        const char*     mLocaleEnc;
 };
 
 
diff --git a/media/libmedia/include/media/Crypto.h b/media/libmedia/include/media/Crypto.h
deleted file mode 100644
index b68413d..0000000
--- a/media/libmedia/include/media/Crypto.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef CRYPTO_H_
-
-#define CRYPTO_H_
-
-#include <media/ICrypto.h>
-#include <utils/threads.h>
-#include <utils/KeyedVector.h>
-
-#include "SharedLibrary.h"
-
-namespace android {
-
-struct CryptoFactory;
-struct CryptoPlugin;
-
-struct Crypto : public BnCrypto {
-    Crypto();
-    virtual ~Crypto();
-
-    virtual status_t initCheck() const;
-
-    virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]);
-
-    virtual status_t createPlugin(
-            const uint8_t uuid[16], const void *data, size_t size);
-
-    virtual status_t destroyPlugin();
-
-    virtual bool requiresSecureDecoderComponent(
-            const char *mime) const;
-
-    virtual void notifyResolution(uint32_t width, uint32_t height);
-
-    virtual status_t setMediaDrmSession(const Vector<uint8_t> &sessionId);
-
-    virtual ssize_t decrypt(const uint8_t key[16], const uint8_t iv[16],
-            CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
-            const sp<IMemory> &source, size_t offset,
-            const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
-            const DestinationBuffer &destination, AString *errorDetailMsg);
-
-    virtual void setHeap(const sp<IMemoryHeap>&) {}
-    virtual void unsetHeap(const sp<IMemoryHeap>&) {}
-
-private:
-    mutable Mutex mLock;
-
-    status_t mInitCheck;
-    sp<SharedLibrary> mLibrary;
-    CryptoFactory *mFactory;
-    CryptoPlugin *mPlugin;
-
-    static KeyedVector<Vector<uint8_t>, String8> mUUIDToLibraryPathMap;
-    static KeyedVector<String8, wp<SharedLibrary> > mLibraryPathToOpenLibraryMap;
-    static Mutex mMapLock;
-
-    void findFactoryForScheme(const uint8_t uuid[16]);
-    bool loadLibraryForScheme(const String8 &path, const uint8_t uuid[16]);
-    void closeFactory();
-
-    DISALLOW_EVIL_CONSTRUCTORS(Crypto);
-};
-
-}  // namespace android
-
-#endif  // CRYPTO_H_
diff --git a/media/libmedia/include/media/CryptoHal.h b/media/libmedia/include/media/CryptoHal.h
index ff8789d..73c029f 100644
--- a/media/libmedia/include/media/CryptoHal.h
+++ b/media/libmedia/include/media/CryptoHal.h
@@ -21,6 +21,7 @@
 #include <android/hardware/drm/1.0/ICryptoFactory.h>
 #include <android/hardware/drm/1.0/ICryptoPlugin.h>
 #include <android/hardware/drm/1.1/ICryptoFactory.h>
+#include <android/hardware/drm/1.2/ICryptoPlugin.h>
 
 #include <mediadrm/ICrypto.h>
 #include <utils/KeyedVector.h>
@@ -72,6 +73,7 @@
 
     const Vector<sp<ICryptoFactory>> mFactories;
     sp<ICryptoPlugin> mPlugin;
+    sp<drm::V1_2::ICryptoPlugin> mPluginV1_2;
 
     /**
      * mInitCheck is:
diff --git a/media/libmedia/include/media/DataSourceDesc.h b/media/libmedia/include/media/DataSourceDesc.h
index c190261..4336767 100644
--- a/media/libmedia/include/media/DataSourceDesc.h
+++ b/media/libmedia/include/media/DataSourceDesc.h
@@ -30,6 +30,11 @@
 // A binder interface for implementing a stagefright DataSource remotely.
 struct DataSourceDesc : public RefBase {
 public:
+    // intentionally less than INT64_MAX
+    // keep consistent with JAVA code
+    static const int64_t kMaxTimeMs = 0x7ffffffffffffffll / 1000;
+    static const int64_t kMaxTimeUs = kMaxTimeMs * 1000;
+
     enum {
         /* No data source has been set yet */
         TYPE_NONE     = 0,
diff --git a/media/libmedia/include/media/Drm.h b/media/libmedia/include/media/Drm.h
deleted file mode 100644
index fc869cc..0000000
--- a/media/libmedia/include/media/Drm.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef DRM_H_
-
-#define DRM_H_
-
-#include "SharedLibrary.h"
-
-#include <media/IDrm.h>
-#include <media/IDrmClient.h>
-#include <utils/threads.h>
-
-namespace android {
-
-class DrmFactory;
-class DrmPlugin;
-struct DrmSessionClientInterface;
-
-struct Drm : public BnDrm,
-             public IBinder::DeathRecipient,
-             public DrmPluginListener {
-    Drm();
-    virtual ~Drm();
-
-    virtual status_t initCheck() const;
-
-    virtual bool isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType);
-
-    virtual status_t createPlugin(const uint8_t uuid[16], const String8 &appPackageName);
-
-    virtual status_t destroyPlugin();
-
-    virtual status_t openSession(Vector<uint8_t> &sessionId);
-
-    virtual status_t closeSession(Vector<uint8_t> const &sessionId);
-
-    virtual status_t
-        getKeyRequest(Vector<uint8_t> const &sessionId,
-                      Vector<uint8_t> const &initData,
-                      String8 const &mimeType, DrmPlugin::KeyType keyType,
-                      KeyedVector<String8, String8> const &optionalParameters,
-                      Vector<uint8_t> &request, String8 &defaultUrl,
-                      DrmPlugin::KeyRequestType *keyRequestType);
-
-    virtual status_t provideKeyResponse(Vector<uint8_t> const &sessionId,
-                                        Vector<uint8_t> const &response,
-                                        Vector<uint8_t> &keySetId);
-
-    virtual status_t removeKeys(Vector<uint8_t> const &keySetId);
-
-    virtual status_t restoreKeys(Vector<uint8_t> const &sessionId,
-                                 Vector<uint8_t> const &keySetId);
-
-    virtual status_t queryKeyStatus(Vector<uint8_t> const &sessionId,
-                                    KeyedVector<String8, String8> &infoMap) const;
-
-    virtual status_t getProvisionRequest(String8 const &certType,
-                                         String8 const &certAuthority,
-                                         Vector<uint8_t> &request,
-                                         String8 &defaulUrl);
-
-    virtual status_t provideProvisionResponse(Vector<uint8_t> const &response,
-                                              Vector<uint8_t> &certificate,
-                                              Vector<uint8_t> &wrappedKey);
-
-    virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops);
-    virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop);
-
-    virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease);
-    virtual status_t releaseAllSecureStops();
-
-    virtual status_t getPropertyString(String8 const &name, String8 &value ) const;
-    virtual status_t getPropertyByteArray(String8 const &name,
-                                          Vector<uint8_t> &value ) const;
-    virtual status_t setPropertyString(String8 const &name, String8 const &value ) const;
-    virtual status_t setPropertyByteArray(String8 const &name,
-                                          Vector<uint8_t> const &value ) const;
-
-    virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
-                                        String8 const &algorithm);
-
-    virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId,
-                                     String8 const &algorithm);
-
-    virtual status_t encrypt(Vector<uint8_t> const &sessionId,
-                             Vector<uint8_t> const &keyId,
-                             Vector<uint8_t> const &input,
-                             Vector<uint8_t> const &iv,
-                             Vector<uint8_t> &output);
-
-    virtual status_t decrypt(Vector<uint8_t> const &sessionId,
-                             Vector<uint8_t> const &keyId,
-                             Vector<uint8_t> const &input,
-                             Vector<uint8_t> const &iv,
-                             Vector<uint8_t> &output);
-
-    virtual status_t sign(Vector<uint8_t> const &sessionId,
-                          Vector<uint8_t> const &keyId,
-                          Vector<uint8_t> const &message,
-                          Vector<uint8_t> &signature);
-
-    virtual status_t verify(Vector<uint8_t> const &sessionId,
-                            Vector<uint8_t> const &keyId,
-                            Vector<uint8_t> const &message,
-                            Vector<uint8_t> const &signature,
-                            bool &match);
-
-    virtual status_t signRSA(Vector<uint8_t> const &sessionId,
-                             String8 const &algorithm,
-                             Vector<uint8_t> const &message,
-                             Vector<uint8_t> const &wrappedKey,
-                             Vector<uint8_t> &signature);
-
-    virtual status_t setListener(const sp<IDrmClient>& listener);
-
-    virtual void sendEvent(DrmPlugin::EventType eventType, int extra,
-                           Vector<uint8_t> const *sessionId,
-                           Vector<uint8_t> const *data);
-
-    virtual void sendExpirationUpdate(Vector<uint8_t> const *sessionId,
-                                      int64_t expiryTimeInMS);
-
-    virtual void sendKeysChange(Vector<uint8_t> const *sessionId,
-                                Vector<DrmPlugin::KeyStatus> const *keyStatusList,
-                                bool hasNewUsableKey);
-
-    virtual void binderDied(const wp<IBinder> &the_late_who);
-
-private:
-    static Mutex mLock;
-
-    status_t mInitCheck;
-
-    sp<DrmSessionClientInterface> mDrmSessionClient;
-
-    sp<IDrmClient> mListener;
-    mutable Mutex mEventLock;
-    mutable Mutex mNotifyLock;
-
-    sp<SharedLibrary> mLibrary;
-    DrmFactory *mFactory;
-    DrmPlugin *mPlugin;
-
-    static KeyedVector<Vector<uint8_t>, String8> mUUIDToLibraryPathMap;
-    static KeyedVector<String8, wp<SharedLibrary> > mLibraryPathToOpenLibraryMap;
-    static Mutex mMapLock;
-
-    void findFactoryForScheme(const uint8_t uuid[16]);
-    bool loadLibraryForScheme(const String8 &path, const uint8_t uuid[16]);
-    void closeFactory();
-    void writeByteArray(Parcel &obj, Vector<uint8_t> const *array);
-
-    DISALLOW_EVIL_CONSTRUCTORS(Drm);
-};
-
-}  // namespace android
-
-#endif  // CRYPTO_H_
diff --git a/media/libmedia/include/media/DrmHal.h b/media/libmedia/include/media/DrmHal.h
index f267f76..bdf1b30 100644
--- a/media/libmedia/include/media/DrmHal.h
+++ b/media/libmedia/include/media/DrmHal.h
@@ -20,9 +20,11 @@
 
 #include <android/hardware/drm/1.0/IDrmFactory.h>
 #include <android/hardware/drm/1.0/IDrmPlugin.h>
-#include <android/hardware/drm/1.0/IDrmPluginListener.h>
 #include <android/hardware/drm/1.1/IDrmFactory.h>
 #include <android/hardware/drm/1.1/IDrmPlugin.h>
+#include <android/hardware/drm/1.2/IDrmFactory.h>
+#include <android/hardware/drm/1.2/IDrmPlugin.h>
+#include <android/hardware/drm/1.2/IDrmPluginListener.h>
 
 #include <media/MediaAnalyticsItem.h>
 #include <mediadrm/DrmMetrics.h>
@@ -35,11 +37,16 @@
 using drm::V1_0::IDrmFactory;
 using drm::V1_0::IDrmPlugin;
 using drm::V1_0::IDrmPluginListener;
-using drm::V1_0::KeyStatus;
+using drm::V1_1::SecurityLevel;
+using drm::V1_2::KeyStatus;
+using drm::V1_2::OfflineLicenseState;
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
 
+typedef drm::V1_2::IDrmPluginListener IDrmPluginListener_V1_2;
+typedef drm::V1_0::KeyStatus KeyStatus_V1_0;
+
 namespace android {
 
 struct DrmSessionClientInterface;
@@ -50,14 +57,17 @@
 }
 
 struct DrmHal : public BnDrm,
-             public IBinder::DeathRecipient,
-             public IDrmPluginListener {
+                public IBinder::DeathRecipient,
+                public IDrmPluginListener_V1_2 {
     DrmHal();
     virtual ~DrmHal();
 
     virtual status_t initCheck() const;
 
-    virtual bool isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType);
+    virtual status_t isCryptoSchemeSupported(const uint8_t uuid[16],
+                                             const String8& mimeType,
+                                             DrmPlugin::SecurityLevel level,
+                                             bool *isSupported);
 
     virtual status_t createPlugin(const uint8_t uuid[16],
                                   const String8 &appPackageName);
@@ -113,6 +123,11 @@
     virtual status_t getSecurityLevel(Vector<uint8_t> const &sessionId,
             DrmPlugin::SecurityLevel *level) const;
 
+    virtual status_t getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const;
+    virtual status_t removeOfflineLicense(Vector<uint8_t> const &keySetId);
+    virtual status_t getOfflineLicenseState(Vector<uint8_t> const &keySetId,
+            DrmPlugin::OfflineLicenseState *licenseState) const;
+
     virtual status_t getPropertyString(String8 const &name, String8 &value ) const;
     virtual status_t getPropertyByteArray(String8 const &name,
                                           Vector<uint8_t> &value ) const;
@@ -166,8 +181,13 @@
             int64_t expiryTimeInMS);
 
     Return<void> sendKeysChange(const hidl_vec<uint8_t>& sessionId,
+            const hidl_vec<KeyStatus_V1_0>& keyStatusList, bool hasNewUsableKey);
+
+    Return<void> sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId,
             const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey);
 
+    Return<void> sendSessionLostState(const hidl_vec<uint8_t>& sessionId);
+
     virtual void binderDied(const wp<IBinder> &the_late_who);
 
 private:
@@ -182,6 +202,7 @@
     const Vector<sp<IDrmFactory>> mFactories;
     sp<IDrmPlugin> mPlugin;
     sp<drm::V1_1::IDrmPlugin> mPluginV1_1;
+    sp<drm::V1_2::IDrmPlugin> mPluginV1_2;
     String8 mAppPackageName;
 
     // Mutable to allow modification within GetPropertyByteArray.
@@ -210,6 +231,11 @@
     status_t getPropertyStringInternal(String8 const &name, String8 &value) const;
     status_t getPropertyByteArrayInternal(String8 const &name,
                                           Vector<uint8_t> &value) const;
+    status_t matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> &factory,
+                                           const uint8_t uuid[16],
+                                           const String8 &mimeType,
+                                           DrmPlugin::SecurityLevel level,
+                                           bool *isSupported);
 
     DISALLOW_EVIL_CONSTRUCTORS(DrmHal);
 };
diff --git a/media/libmedia/include/media/DrmMetrics.h b/media/libmedia/include/media/DrmMetrics.h
index 261998f..6f132bf 100644
--- a/media/libmedia/include/media/DrmMetrics.h
+++ b/media/libmedia/include/media/DrmMetrics.h
@@ -21,6 +21,7 @@
 
 #include <android/hardware/drm/1.0/types.h>
 #include <android/hardware/drm/1.1/types.h>
+#include <android/hardware/drm/1.2/types.h>
 #include <binder/PersistableBundle.h>
 #include <media/CounterMetric.h>
 #include <media/EventMetric.h>
@@ -50,7 +51,7 @@
   CounterMetric<status_t> mProvideProvisionResponseCounter;
 
   // Count of key status events broken out by status type.
-  CounterMetric<::android::hardware::drm::V1_0::KeyStatusType>
+  CounterMetric<::android::hardware::drm::V1_2::KeyStatusType>
       mKeyStatusChangeCounter;
   // Count of events broken out by event type
   CounterMetric<::android::hardware::drm::V1_0::EventType> mEventCounter;
diff --git a/media/libmedia/include/media/IDrm.h b/media/libmedia/include/media/IDrm.h
index 8e9eb3a..fbe80c6 100644
--- a/media/libmedia/include/media/IDrm.h
+++ b/media/libmedia/include/media/IDrm.h
@@ -34,7 +34,10 @@
 
     virtual status_t initCheck() const = 0;
 
-    virtual bool isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) = 0;
+    virtual status_t isCryptoSchemeSupported(const uint8_t uuid[16],
+                                             const String8 &mimeType,
+                                             DrmPlugin::SecurityLevel securityLevel,
+                                             bool *result) = 0;
 
     virtual status_t createPlugin(const uint8_t uuid[16],
                                   const String8 &appPackageName) = 0;
@@ -75,8 +78,8 @@
                                               Vector<uint8_t> &certificate,
                                               Vector<uint8_t> &wrappedKey) = 0;
 
-    virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) = 0;
-    virtual status_t getSecureStopIds(List<Vector<uint8_t> > &secureStopIds) = 0;
+    virtual status_t getSecureStops(List<Vector<uint8_t>> &secureStops) = 0;
+    virtual status_t getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) = 0;
     virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) = 0;
 
     virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) = 0;
@@ -91,6 +94,11 @@
     virtual status_t getSecurityLevel(Vector<uint8_t> const &sessionId,
             DrmPlugin::SecurityLevel *level) const = 0;
 
+    virtual status_t getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const = 0;
+    virtual status_t removeOfflineLicense(Vector<uint8_t> const &keySetId) = 0;
+    virtual status_t getOfflineLicenseState(Vector<uint8_t> const &keySetId,
+            DrmPlugin::OfflineLicenseState *licenseState) const = 0;
+
     virtual status_t getPropertyString(String8 const &name, String8 &value) const = 0;
     virtual status_t getPropertyByteArray(String8 const &name,
                                           Vector<uint8_t> &value) const = 0;
diff --git a/media/libmedia/include/media/IMediaExtractorService.h b/media/libmedia/include/media/IMediaExtractorService.h
index 45e9620..5ce2cdb 100644
--- a/media/libmedia/include/media/IMediaExtractorService.h
+++ b/media/libmedia/include/media/IMediaExtractorService.h
@@ -17,6 +17,8 @@
 #ifndef ANDROID_IMEDIAEXTRACTORSERVICE_H
 #define ANDROID_IMEDIAEXTRACTORSERVICE_H
 
+#include <unordered_set>
+
 #include <binder/IInterface.h>
 #include <binder/IMemory.h>
 #include <binder/Parcel.h>
@@ -33,6 +35,8 @@
     virtual sp<IMediaExtractor> makeExtractor(const sp<IDataSource> &source, const char *mime) = 0;
 
     virtual sp<IDataSource> makeIDataSource(int fd, int64_t offset, int64_t length) = 0;
+
+    virtual std::unordered_set<std::string> getSupportedTypes() = 0;
 };
 
 class BnMediaExtractorService: public BnInterface<IMediaExtractorService>
diff --git a/media/libmedia/include/media/IMediaPlayerService.h b/media/libmedia/include/media/IMediaPlayerService.h
index 217de14..f2e2060 100644
--- a/media/libmedia/include/media/IMediaPlayerService.h
+++ b/media/libmedia/include/media/IMediaPlayerService.h
@@ -26,11 +26,11 @@
 #include <system/audio.h>
 
 #include <media/IMediaPlayerClient.h>
-#include <media/IMediaPlayer.h>
 #include <media/IMediaMetadataRetriever.h>
 
 namespace android {
 
+class IMediaPlayer;
 class IMediaCodecList;
 struct IMediaHTTPService;
 class IMediaRecorder;
diff --git a/media/libmedia/include/media/IMediaRecorder.h b/media/libmedia/include/media/IMediaRecorder.h
index 379000e..f9c557c 100644
--- a/media/libmedia/include/media/IMediaRecorder.h
+++ b/media/libmedia/include/media/IMediaRecorder.h
@@ -73,7 +73,9 @@
     virtual status_t enableAudioDeviceCallback(bool enabled) = 0;
     virtual status_t getActiveMicrophones(
                         std::vector<media::MicrophoneInfo>* activeMicrophones) = 0;
-
+    virtual status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction) = 0;
+    virtual status_t setPreferredMicrophoneFieldDimension(float zoom) = 0;
+    virtual status_t getPortId(audio_port_handle_t *portId) = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/media/libmedia/include/media/IMediaSource.h b/media/libmedia/include/media/IMediaSource.h
index 7a4b1b9..381df24 100644
--- a/media/libmedia/include/media/IMediaSource.h
+++ b/media/libmedia/include/media/IMediaSource.h
@@ -124,10 +124,11 @@
         return false;
     }
 
-    static const size_t kBinderMediaBuffers = 4; // buffers managed by BnMediaSource
+    // align buffer count with video request size in NuMediaExtractor::selectTrack()
+    static const size_t kBinderMediaBuffers = 8; // buffers managed by BnMediaSource
     static const size_t kTransferSharedAsSharedThreshold = 4 * 1024;  // if >= shared, else inline
-    static const size_t kTransferInlineAsSharedThreshold = 64 * 1024; // if >= shared, else inline
-    static const size_t kInlineMaxTransfer = 256 * 1024; // Binder size limited to BINDER_VM_SIZE.
+    static const size_t kTransferInlineAsSharedThreshold = 8 * 1024; // if >= shared, else inline
+    static const size_t kInlineMaxTransfer = 64 * 1024; // Binder size limited to BINDER_VM_SIZE.
 
 protected:
     virtual ~BnMediaSource();
diff --git a/media/libmedia/include/media/IOMX.h b/media/libmedia/include/media/IOMX.h
index e69c02d..7e7c2d2 100644
--- a/media/libmedia/include/media/IOMX.h
+++ b/media/libmedia/include/media/IOMX.h
@@ -47,9 +47,8 @@
 
 using hardware::media::omx::V1_0::IOmxNode;
 
-class IOMX : public IInterface {
+class IOMX : public RefBase {
 public:
-    DECLARE_META_INTERFACE(OMX);
 
     typedef uint32_t buffer_id;
 
@@ -224,14 +223,6 @@
 };
 
 ////////////////////////////////////////////////////////////////////////////////
-
-class BnOMX : public BnInterface<IOMX> {
-public:
-    virtual status_t onTransact(
-            uint32_t code, const Parcel &data, Parcel *reply,
-            uint32_t flags = 0);
-};
-
 class BnOMXNode : public BnInterface<IOMXNode> {
 public:
     virtual status_t onTransact(
diff --git a/media/libmedia/include/media/JAudioAttributes.h b/media/libmedia/include/media/JAudioAttributes.h
index fb11435..ea0aaa3 100644
--- a/media/libmedia/include/media/JAudioAttributes.h
+++ b/media/libmedia/include/media/JAudioAttributes.h
@@ -26,8 +26,7 @@
 public:
     /* Creates a Java AudioAttributes object. */
     static jobject createAudioAttributesObj(JNIEnv *env,
-                                            const audio_attributes_t* pAttributes,
-                                            audio_stream_type_t streamType) {
+                                            const audio_attributes_t* pAttributes) {
 
         jclass jBuilderCls = env->FindClass("android/media/AudioAttributes$Builder");
         jmethodID jBuilderCtor = env->GetMethodID(jBuilderCls, "<init>", "()V");
@@ -58,11 +57,6 @@
             // TODO: Handle the 'tags' (char[] to HashSet<String>).
             // How to parse the char[]? Is there any example of it?
             // Also, the addTags() method is hidden.
-        } else {
-            // Call AudioAttributes.Builder.setLegacyStreamType().build()
-            jmethodID jSetLegacyStreamType = env->GetMethodID(jBuilderCls, "setLegacyStreamType",
-                    "(I)Landroid/media/AudioAttributes$Builder;");
-            jBuilderObj = env->CallObjectMethod(jBuilderObj, jSetLegacyStreamType, streamType);
         }
 
         jmethodID jBuild = env->GetMethodID(jBuilderCls, "build",
diff --git a/media/libmedia/include/media/MediaCodecInfo.h b/media/libmedia/include/media/MediaCodecInfo.h
index b3777d3..54f565a 100644
--- a/media/libmedia/include/media/MediaCodecInfo.h
+++ b/media/libmedia/include/media/MediaCodecInfo.h
@@ -30,6 +30,8 @@
 #include <utils/Vector.h>
 #include <utils/StrongPointer.h>
 
+#include <type_traits>
+
 namespace android {
 
 struct AMessage;
@@ -51,21 +53,47 @@
 
     struct CapabilitiesWriter;
 
+    enum Attributes : int32_t {
+        // attribute flags
+        kFlagIsEncoder = 1 << 0,
+        kFlagIsVendor = 1 << 1,
+        kFlagIsSoftwareOnly = 1 << 2,
+        kFlagIsHardwareAccelerated = 1 << 3,
+    };
+
     struct Capabilities : public RefBase {
-        enum {
-            // decoder flags
-            kFlagSupportsAdaptivePlayback = 1 << 0,
-            kFlagSupportsSecurePlayback = 1 << 1,
-            kFlagSupportsTunneledPlayback = 1 << 2,
+        constexpr static char FEATURE_ADAPTIVE_PLAYBACK[] = "feature-adaptive-playback";
+        constexpr static char FEATURE_DYNAMIC_TIMESTAMP[] = "feature-dynamic-timestamp";
+        constexpr static char FEATURE_FRAME_PARSING[] = "feature-frame-parsing";
+        constexpr static char FEATURE_INTRA_REFRESH[] = "feature-frame-parsing";
+        constexpr static char FEATURE_MULTIPLE_FRAMES[] = "feature-multiple-frames";
+        constexpr static char FEATURE_SECURE_PLAYBACK[] = "feature-secure-playback";
+        constexpr static char FEATURE_TUNNELED_PLAYBACK[] = "feature-tunneled-playback";
 
-            // encoder flags
-            kFlagSupportsIntraRefresh = 1 << 0,
-
-        };
-
+        /**
+         * Returns the supported levels for each supported profile in a target array.
+         *
+         * @param profileLevels target array for the profile levels.
+         */
         void getSupportedProfileLevels(Vector<ProfileLevel> *profileLevels) const;
+
+        /**
+         * Returns the supported color formats in a target array. Only used for video/image
+         * components.
+         *
+         * @param colorFormats target array for the color formats.
+         */
         void getSupportedColorFormats(Vector<uint32_t> *colorFormats) const;
-        uint32_t getFlags() const;
+
+        /**
+         * Returns metadata associated with this codec capability.
+         *
+         * This contains:
+         * - features,
+         * - performance data.
+         *
+         * TODO: expose this as separate API-s and wrap here.
+         */
         const sp<AMessage> getDetails() const;
 
     protected:
@@ -73,7 +101,6 @@
         SortedVector<ProfileLevel> mProfileLevelsSorted;
         Vector<uint32_t> mColorFormats;
         SortedVector<uint32_t> mColorFormatsSorted;
-        uint32_t mFlags;
         sp<AMessage> mDetails;
 
         Capabilities();
@@ -93,8 +120,7 @@
     /**
      * This class is used for modifying information inside a `Capabilities`
      * object. An object of type `CapabilitiesWriter` can be obtained by calling
-     * `MediaCodecInfoWriter::addMime()` or
-     * `MediaCodecInfoWriter::updateMime()`.
+     * `MediaCodecInfoWriter::addMediaType()`.
      */
     struct CapabilitiesWriter {
         /**
@@ -122,6 +148,13 @@
          */
         void addDetail(const char* key, int32_t value);
         /**
+         * Removes a key-value pair from the list of details. If the key is not
+         * present, this call does nothing.
+         *
+         * @param key The key.
+         */
+        void removeDetail(const char* key);
+        /**
          * Add a profile-level pair. If this profile-level pair already exists,
          * it will be ignored.
          *
@@ -136,13 +169,7 @@
          * @param format The color format.
          */
         void addColorFormat(uint32_t format);
-        /**
-         * Add flags. The underlying operation is bitwise-or. In other words,
-         * bits that have already been set will be ignored.
-         *
-         * @param flags The additional flags.
-         */
-        void addFlags(uint32_t flags);
+
     private:
         /**
          * The associated `Capabilities` object.
@@ -158,19 +185,42 @@
         friend MediaCodecInfoWriter;
     };
 
-    bool isEncoder() const;
-    void getSupportedMimes(Vector<AString> *mimes) const;
-    const sp<Capabilities> getCapabilitiesFor(const char *mime) const;
+    inline bool isEncoder() const {
+        return getAttributes() & kFlagIsEncoder;
+    }
+
+    Attributes getAttributes() const;
+    void getSupportedMediaTypes(Vector<AString> *mediaTypes) const;
+    const sp<Capabilities> getCapabilitiesFor(const char *mediaType) const;
     const char *getCodecName() const;
 
     /**
+     * Returns a vector containing alternate names for the codec.
+     *
+     * \param aliases the destination array for the aliases. This is cleared.
+     *
+     * Multiple codecs may share alternate names as long as their supported media types are
+     * distinct; however, these will result in different aliases for the MediaCodec user as
+     * the canonical codec has to be resolved without knowing the media type in
+     * MediaCodec::CreateByComponentName.
+     */
+    void getAliases(Vector<AString> *aliases) const;
+
+    /**
      * Return the name of the service that hosts the codec. This value is not
      * visible at the Java level.
      *
      * Currently, this is the "instance name" of the IOmx service.
      */
     const char *getOwnerName() const;
-    uint32_t rank() const;
+
+    /**
+     * Returns the rank of the component.
+     *
+     * Technically this is defined to be per media type, but that makes ordering the MediaCodecList
+     * impossible as MediaCodecList is ordered by codec name.
+     */
+    uint32_t getRank() const;
 
     /**
      * Serialization over Binder
@@ -181,11 +231,12 @@
 private:
     AString mName;
     AString mOwner;
-    bool mIsEncoder;
+    Attributes mAttributes;
     KeyedVector<AString, sp<Capabilities> > mCaps;
+    Vector<AString> mAliases;
     uint32_t mRank;
 
-    ssize_t getCapabilityIndex(const char *mime) const;
+    ssize_t getCapabilityIndex(const char *mediaType) const;
 
     /**
      * Construct an `MediaCodecInfo` object. After the construction, its
@@ -219,6 +270,13 @@
      */
     void setName(const char* name);
     /**
+     * Adds an alias (alternate name) for the codec. Multiple codecs can share an alternate name
+     * as long as their supported media types are distinct.
+     *
+     * @param name an alternate name.
+     */
+    void addAlias(const char* name);
+    /**
      * Set the owner name of the codec.
      *
      * This "owner name" is the name of the `IOmx` instance that supports this
@@ -228,32 +286,32 @@
      */
     void setOwner(const char* owner);
     /**
-     * Set whether this codec is an encoder or a decoder.
+     * Sets codec attributes.
      *
-     * @param isEncoder Whether this codec is an encoder or a decoder.
+     * @param attributes Codec attributes.
      */
-    void setEncoder(bool isEncoder = true);
+    void setAttributes(typename std::underlying_type<MediaCodecInfo::Attributes>::type attributes);
     /**
-     * Add a mime to an indexed list and return a `CapabilitiesWriter` object
+     * Add a media type to an indexed list and return a `CapabilitiesWriter` object
      * that can be used for modifying the associated `Capabilities`.
      *
-     * If the mime already exists, this function will return the
-     * `CapabilitiesWriter` associated with the mime.
+     * If the media type already exists, this function will return the
+     * `CapabilitiesWriter` associated with the media type.
      *
-     * @param[in] mime The name of a new mime to add.
+     * @param[in] mediaType The name of a new media type to add.
      * @return writer The `CapabilitiesWriter` object for modifying the
-     * `Capabilities` associated with the mime. `writer` will be valid
-     * regardless of whether `mime` already exists or not.
+     * `Capabilities` associated with the media type. `writer` will be valid
+     * regardless of whether `mediaType` already exists or not.
      */
-    std::unique_ptr<MediaCodecInfo::CapabilitiesWriter> addMime(
-            const char* mime);
+    std::unique_ptr<MediaCodecInfo::CapabilitiesWriter> addMediaType(
+            const char* mediaType);
     /**
-     * Remove a mime.
+     * Remove a media type.
      *
-     * @param mime The name of the mime to remove.
-     * @return `true` if `mime` is removed; `false` if `mime` is not found.
+     * @param mediaType The name of the media type to remove.
+     * @return `true` if `mediaType` is removed; `false` if `mediaType` is not found.
      */
-    bool removeMime(const char* mime);
+    bool removeMediaType(const char* mediaType);
     /**
      * Set rank of the codec. MediaCodecList will stable-sort the list according
      * to rank in non-descending order.
diff --git a/media/libmedia/include/media/MediaProfiles.h b/media/libmedia/include/media/MediaProfiles.h
index 0feb4f3..3e8e7c8 100644
--- a/media/libmedia/include/media/MediaProfiles.h
+++ b/media/libmedia/include/media/MediaProfiles.h
@@ -34,7 +34,11 @@
     CAMCORDER_QUALITY_1080P = 6,
     CAMCORDER_QUALITY_QVGA = 7,
     CAMCORDER_QUALITY_2160P = 8,
-    CAMCORDER_QUALITY_LIST_END = 8,
+    CAMCORDER_QUALITY_VGA = 9,
+    CAMCORDER_QUALITY_4KDCI = 10,
+    CAMCORDER_QUALITY_QHD = 11,
+    CAMCORDER_QUALITY_2k = 12,
+    CAMCORDER_QUALITY_LIST_END = 12,
 
     CAMCORDER_QUALITY_TIME_LAPSE_LIST_START = 1000,
     CAMCORDER_QUALITY_TIME_LAPSE_LOW  = 1000,
@@ -46,7 +50,11 @@
     CAMCORDER_QUALITY_TIME_LAPSE_1080P = 1006,
     CAMCORDER_QUALITY_TIME_LAPSE_QVGA = 1007,
     CAMCORDER_QUALITY_TIME_LAPSE_2160P = 1008,
-    CAMCORDER_QUALITY_TIME_LAPSE_LIST_END = 1008,
+    CAMCORDER_QUALITY_TIME_LAPSE_VGA = 1009,
+    CAMCORDER_QUALITY_TIME_LAPSE_4KDCI = 1010,
+    CAMCORDER_QUALITY_TIME_LAPSE_QHD = 1011,
+    CAMCORDER_QUALITY_TIME_LAPSE_2k = 1012,
+    CAMCORDER_QUALITY_TIME_LAPSE_LIST_END = 1012,
 
     CAMCORDER_QUALITY_HIGH_SPEED_LIST_START = 2000,
     CAMCORDER_QUALITY_HIGH_SPEED_LOW  = 2000,
@@ -55,7 +63,10 @@
     CAMCORDER_QUALITY_HIGH_SPEED_720P = 2003,
     CAMCORDER_QUALITY_HIGH_SPEED_1080P = 2004,
     CAMCORDER_QUALITY_HIGH_SPEED_2160P = 2005,
-    CAMCORDER_QUALITY_HIGH_SPEED_LIST_END = 2005,
+    CAMCORDER_QUALITY_HIGH_SPEED_CIF = 2006,
+    CAMCORDER_QUALITY_HIGH_SPEED_VGA = 2007,
+    CAMCORDER_QUALITY_HIGH_SPEED_4KDCI = 2008,
+    CAMCORDER_QUALITY_HIGH_SPEED_LIST_END = 2008,
 };
 
 enum video_decoder {
diff --git a/media/libmedia/include/media/MediaRecorderBase.h b/media/libmedia/include/media/MediaRecorderBase.h
index 5340dde..a2dff31 100644
--- a/media/libmedia/include/media/MediaRecorderBase.h
+++ b/media/libmedia/include/media/MediaRecorderBase.h
@@ -72,6 +72,9 @@
     virtual status_t enableAudioDeviceCallback(bool enabled) = 0;
     virtual status_t getActiveMicrophones(
                         std::vector<media::MicrophoneInfo>* activeMicrophones) = 0;
+    virtual status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction) = 0;
+    virtual status_t setPreferredMicrophoneFieldDimension(float zoom) = 0;
+    virtual status_t getPortId(audio_port_handle_t *portId) const = 0;
 
 
 
diff --git a/media/libmedia/include/media/MidiIoWrapper.h b/media/libmedia/include/media/MidiIoWrapper.h
index b5e565e..b19d49e 100644
--- a/media/libmedia/include/media/MidiIoWrapper.h
+++ b/media/libmedia/include/media/MidiIoWrapper.h
@@ -23,11 +23,14 @@
 
 namespace android {
 
+struct CDataSource;
+class DataSourceUnwrapper;
+
 class MidiIoWrapper {
 public:
     explicit MidiIoWrapper(const char *path);
     explicit MidiIoWrapper(int fd, off64_t offset, int64_t size);
-    explicit MidiIoWrapper(DataSourceBase *source);
+    explicit MidiIoWrapper(CDataSource *csource);
 
     ~MidiIoWrapper();
 
@@ -40,7 +43,7 @@
     int mFd;
     off64_t mBase;
     int64_t  mLength;
-    DataSourceBase *mDataSource;
+    DataSourceUnwrapper *mDataSource;
     EAS_FILE mEasFile;
 };
 
diff --git a/media/libmedia/include/media/NdkWrapper.h b/media/libmedia/include/media/NdkWrapper.h
index c97d171..8a417f6 100644
--- a/media/libmedia/include/media/NdkWrapper.h
+++ b/media/libmedia/include/media/NdkWrapper.h
@@ -278,6 +278,25 @@
     DISALLOW_EVIL_CONSTRUCTORS(AMediaCodecWrapper);
 };
 
+struct AMediaDataSourceWrapper : public RefBase {
+
+    AMediaDataSourceWrapper(const sp<DataSource>&);
+    AMediaDataSourceWrapper(AMediaDataSource*);
+
+    AMediaDataSource *getAMediaDataSource();
+
+    void close();
+
+protected:
+    virtual ~AMediaDataSourceWrapper();
+
+private:
+    sp<DataSource> mDataSource;
+    AMediaDataSource *mAMediaDataSource;
+
+    DISALLOW_EVIL_CONSTRUCTORS(AMediaDataSourceWrapper);
+};
+
 struct AMediaExtractorWrapper : public RefBase {
 
     AMediaExtractorWrapper(AMediaExtractor *aMediaExtractor);
@@ -287,8 +306,6 @@
 
     status_t release();
 
-    status_t disconnect();
-
     status_t setDataSource(int fd, off64_t offset, off64_t length);
 
     status_t setDataSource(const char *location);
@@ -339,31 +356,6 @@
     DISALLOW_EVIL_CONSTRUCTORS(AMediaExtractorWrapper);
 };
 
-struct AMediaDataSourceWrapper : public RefBase {
-
-    static status_t translate_error(media_status_t err);
-
-    static ssize_t AMediaDataSourceWrapper_getSize(void *userdata);
-
-    static ssize_t AMediaDataSourceWrapper_readAt(void *userdata, off64_t offset, void * buf, size_t size);
-
-    static void AMediaDataSourceWrapper_close(void *userdata);
-
-    AMediaDataSourceWrapper(const sp<DataSource> &dataSource);
-
-    AMediaDataSource *getAMediaDataSource();
-
-protected:
-    virtual ~AMediaDataSourceWrapper();
-
-private:
-    sp<DataSource> mDataSource;
-
-    AMediaDataSource *mAMediaDataSource;
-
-    DISALLOW_EVIL_CONSTRUCTORS(AMediaDataSourceWrapper);
-};
-
 }  // namespace android
 
 #endif  // NDK_WRAPPER_H_
diff --git a/media/libmedia/include/media/OMXBuffer.h b/media/libmedia/include/media/OMXBuffer.h
index 9c9f5e7..4abe9e6 100644
--- a/media/libmedia/include/media/OMXBuffer.h
+++ b/media/libmedia/include/media/OMXBuffer.h
@@ -137,7 +137,7 @@
     hidl_memory mHidlMemory;
 
     // Move assignment
-    OMXBuffer &operator=(OMXBuffer&&);
+    OMXBuffer &operator=(OMXBuffer&&) noexcept;
 
     // Deleted copy constructor and assignment.
     OMXBuffer(const OMXBuffer&) = delete;
diff --git a/media/libmedia/include/media/PatchBuilder.h b/media/libmedia/include/media/PatchBuilder.h
new file mode 100644
index 0000000..f2722a6
--- /dev/null
+++ b/media/libmedia/include/media/PatchBuilder.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_PATCH_BUILDER_H
+#define ANDROID_PATCH_BUILDER_H
+
+#include <functional>
+#include <utility>
+
+#include <system/audio.h>
+#include <utils/StrongPointer.h>
+
+// This is a header-only utility.
+
+namespace android {
+
+class PatchBuilder {
+  public:
+    using mix_usecase_t = decltype(audio_port_config_mix_ext::usecase);
+
+    PatchBuilder() = default;
+
+    // All existing methods operating on audio patches take a pointer to const.
+    // It's OK to construct a temporary PatchBuilder while preparing a parameter
+    // to such a function because the Builder will be kept alive until the code
+    // execution reaches the function call statement semicolon.
+    const struct audio_patch* patch() const { return &mPatch; }
+
+    template<typename T, typename... S>
+    PatchBuilder& addSink(T&& t, S&&... s) {
+        sinks().add(std::forward<T>(t), std::forward<S>(s)...);
+        return *this;
+    }
+    // Explicit type of the second parameter allows clients to provide the struct inline.
+    template<typename T>
+    PatchBuilder& addSink(T&& t, const mix_usecase_t& update) {
+        sinks().add(std::forward<T>(t), update);
+        return *this;
+    }
+    template<typename T, typename... S>
+    PatchBuilder& addSource(T&& t, S&&... s) {
+        sources().add(std::forward<T>(t), std::forward<S>(s)...);
+        return *this;
+    }
+    // Explicit type of the second parameter allows clients to provide the struct inline.
+    template<typename T>
+    PatchBuilder& addSource(T&& t, const mix_usecase_t& update) {
+        sources().add(std::forward<T>(t), update);
+        return *this;
+    }
+
+  private:
+    struct PortCfgs {
+        PortCfgs(unsigned int *countPtr, struct audio_port_config *portCfgs)
+                : mCountPtr(countPtr), mPortCfgs(portCfgs) {}
+        audio_port_config& add(const audio_port_config& portCfg) {
+            return *advance() = portCfg;
+        }
+        template<typename T>
+        audio_port_config& add(const sp<T>& entity) {
+            audio_port_config* added = advance();
+            entity->toAudioPortConfig(added);
+            return *added;
+        }
+        template<typename T>
+        void add(const sp<T>& entity, const mix_usecase_t& usecaseUpdate) {
+            add(entity).ext.mix.usecase = usecaseUpdate;
+        }
+        template<typename T>
+        void add(const sp<T>& entity,
+                std::function<mix_usecase_t(const mix_usecase_t&)> usecaseUpdater) {
+            mix_usecase_t* usecase = &add(entity).ext.mix.usecase;
+            *usecase = usecaseUpdater(*usecase);
+        }
+        struct audio_port_config* advance() {
+            return &mPortCfgs[(*mCountPtr)++];
+        }
+        unsigned int *mCountPtr;
+        struct audio_port_config *mPortCfgs;
+    };
+
+    PortCfgs sinks() { return PortCfgs(&mPatch.num_sinks, mPatch.sinks); }
+    PortCfgs sources() { return PortCfgs(&mPatch.num_sources, mPatch.sources); }
+
+    struct audio_patch mPatch = {};
+};
+
+}  // namespace android
+
+#endif  // ANDROID_PATCH_BUILDER_H
diff --git a/media/libmedia/include/media/SingleStateQueue.h b/media/libmedia/include/media/SingleStateQueue.h
index d423962..c2761cb 100644
--- a/media/libmedia/include/media/SingleStateQueue.h
+++ b/media/libmedia/include/media/SingleStateQueue.h
@@ -99,6 +99,13 @@
             return mShared->mAck - sequence >= 0;
         }
 
+        // returns the last value written (or the contents of the shared buffer after initialization
+        // if no value was written).
+        T last() const
+        {   // assume no sequence check required - we are the writer.
+            return mShared->mValue;
+        }
+
     private:
         int32_t     mSequence;
         Shared * const mShared;
diff --git a/media/libmedia/include/media/TypeConverter.h b/media/libmedia/include/media/TypeConverter.h
index 86f0d4c..2f8c209 100644
--- a/media/libmedia/include/media/TypeConverter.h
+++ b/media/libmedia/include/media/TypeConverter.h
@@ -20,6 +20,7 @@
 #include <string>
 #include <string.h>
 
+#include <vector>
 #include <system/audio.h>
 #include <utils/Log.h>
 #include <utils/Vector.h>
@@ -30,77 +31,55 @@
 
 namespace android {
 
-struct SampleRateTraits
-{
-    typedef uint32_t Type;
-    typedef SortedVector<Type> Collection;
-};
-struct DeviceTraits
-{
-    typedef audio_devices_t Type;
-    typedef Vector<Type> Collection;
-};
-struct OutputDeviceTraits : public DeviceTraits {};
-struct InputDeviceTraits : public DeviceTraits {};
-struct OutputFlagTraits
-{
-    typedef audio_output_flags_t Type;
-    typedef Vector<Type> Collection;
-};
-struct InputFlagTraits
-{
-    typedef audio_input_flags_t Type;
-    typedef Vector<Type> Collection;
-};
-struct FormatTraits
-{
-    typedef audio_format_t Type;
-    typedef Vector<Type> Collection;
-};
-struct ChannelTraits
-{
-    typedef audio_channel_mask_t Type;
-    typedef SortedVector<Type> Collection;
-};
-struct OutputChannelTraits : public ChannelTraits {};
-struct InputChannelTraits : public ChannelTraits {};
-struct ChannelIndexTraits : public ChannelTraits {};
-struct GainModeTraits
-{
-    typedef audio_gain_mode_t Type;
-    typedef Vector<Type> Collection;
-};
-struct StreamTraits
-{
-    typedef audio_stream_type_t Type;
-    typedef Vector<Type> Collection;
-};
-struct AudioModeTraits
-{
-    typedef audio_mode_t Type;
-    typedef Vector<Type> Collection;
-};
-struct AudioContentTraits
-{
-    typedef audio_content_type_t Type;
-    typedef Vector<Type> Collection;
-};
-struct UsageTraits
-{
-    typedef audio_usage_t Type;
-    typedef Vector<Type> Collection;
-};
-struct SourceTraits
-{
-    typedef audio_source_t Type;
-    typedef Vector<Type> Collection;
-};
 template <typename T>
 struct DefaultTraits
 {
     typedef T Type;
-    typedef Vector<Type> Collection;
+    typedef std::vector<Type> Collection;
+    static void add(Collection &collection, Type value)
+    {
+        collection.push_back(value);
+    }
 };
+template <typename T>
+struct VectorTraits
+{
+    typedef T Type;
+    typedef Vector<Type> Collection;
+    static void add(Collection &collection, Type value)
+    {
+        collection.add(value);
+    }
+};
+template <typename T>
+struct SortedVectorTraits
+{
+    typedef T Type;
+    typedef SortedVector<Type> Collection;
+    static void add(Collection &collection, Type value)
+    {
+        collection.add(value);
+    }
+};
+
+using SampleRateTraits = SortedVectorTraits<uint32_t>;
+using DeviceTraits = DefaultTraits<audio_devices_t>;
+struct OutputDeviceTraits : public DeviceTraits {};
+struct InputDeviceTraits : public DeviceTraits {};
+using ChannelTraits = SortedVectorTraits<audio_channel_mask_t>;
+struct OutputChannelTraits : public ChannelTraits {};
+struct InputChannelTraits : public ChannelTraits {};
+struct ChannelIndexTraits : public ChannelTraits {};
+using InputFlagTraits = DefaultTraits<audio_input_flags_t>;
+using OutputFlagTraits = DefaultTraits<audio_output_flags_t>;
+using FormatTraits = VectorTraits<audio_format_t>;
+using GainModeTraits = DefaultTraits<audio_gain_mode_t>;
+using StreamTraits = DefaultTraits<audio_stream_type_t>;
+using AudioModeTraits = DefaultTraits<audio_mode_t>;
+using AudioContentTraits = DefaultTraits<audio_content_type_t>;
+using UsageTraits = DefaultTraits<audio_usage_t>;
+using SourceTraits = DefaultTraits<audio_source_t>;
+struct AudioFlagTraits : public DefaultTraits<audio_flags_mask_t> {};
 
 template <class Traits>
 static void collectionFromString(const std::string &str, typename Traits::Collection &collection,
@@ -110,7 +89,7 @@
     for (const char *cstr = strtok(literal, del); cstr != NULL; cstr = strtok(NULL, del)) {
         typename Traits::Type value;
         if (utilities::convertTo<std::string, typename Traits::Type >(cstr, value)) {
-            collection.add(value);
+            Traits::add(collection, value);
         }
     }
     free(literal);
@@ -181,7 +160,7 @@
     for (const char *cstr = strtok(literal, del); cstr != NULL; cstr = strtok(NULL, del)) {
         typename Traits::Type value;
         if (fromString(cstr, value)) {
-            collection.add(value);
+            Traits::add(collection, value);
         }
     }
     free(literal);
@@ -234,6 +213,7 @@
 typedef TypeConverter<AudioContentTraits> AudioContentTypeConverter;
 typedef TypeConverter<UsageTraits> UsageTypeConverter;
 typedef TypeConverter<SourceTraits> SourceTypeConverter;
+typedef TypeConverter<AudioFlagTraits> AudioFlagConverter;
 
 template<> const OutputDeviceConverter::Table OutputDeviceConverter::mTable[];
 template<> const InputDeviceConverter::Table InputDeviceConverter::mTable[];
@@ -249,11 +229,10 @@
 template<> const AudioContentTypeConverter::Table AudioContentTypeConverter::mTable[];
 template<> const UsageTypeConverter::Table UsageTypeConverter::mTable[];
 template<> const SourceTypeConverter::Table SourceTypeConverter::mTable[];
+template<> const AudioFlagConverter::Table AudioFlagConverter::mTable[];
 
 bool deviceFromString(const std::string& literalDevice, audio_devices_t& device);
 
-bool deviceToString(audio_devices_t device, std::string& literalDevice);
-
 SampleRateTraits::Collection samplingRatesFromString(
         const std::string &samplingRates, const char *del = AudioParameter::valueListSeparator);
 
@@ -274,6 +253,65 @@
 OutputChannelTraits::Collection outputChannelMasksFromString(
         const std::string &outChannels, const char *del = AudioParameter::valueListSeparator);
 
+// counting enumerations
+template <typename T, std::enable_if_t<std::is_same<T, audio_content_type_t>::value
+                                    || std::is_same<T, audio_mode_t>::value
+                                    || std::is_same<T, audio_source_t>::value
+                                    || std::is_same<T, audio_stream_type_t>::value
+                                    || std::is_same<T, audio_usage_t>::value
+                                    , int> = 0>
+static inline std::string toString(const T& value)
+{
+    std::string result;
+    return TypeConverter<DefaultTraits<T>>::toString(value, result)
+            ? result : std::to_string(static_cast<int>(value));
+
+}
+
+// flag enumerations
+template <typename T, std::enable_if_t<std::is_same<T, audio_gain_mode_t>::value
+                                    || std::is_same<T, audio_input_flags_t>::value
+                                    || std::is_same<T, audio_output_flags_t>::value
+                                    , int> = 0>
+static inline std::string toString(const T& value)
+{
+    std::string result;
+    TypeConverter<DefaultTraits<T>>::maskToString(value, result);
+    return result;
+}
+
+static inline std::string toString(const audio_devices_t& devices)
+{
+    std::string result;
+    if ((devices & AUDIO_DEVICE_BIT_IN) != 0) {
+        InputDeviceConverter::maskToString(devices, result);
+    } else {
+        OutputDeviceConverter::maskToString(devices, result);
+    }
+    return result;
+}
+
+// TODO: Remove when FormatTraits uses DefaultTraits.
+static inline std::string toString(const audio_format_t& format)
+{
+    std::string result;
+    return TypeConverter<VectorTraits<audio_format_t>>::toString(format, result)
+            ? result : std::to_string(static_cast<int>(format));
+}
+
+static inline std::string toString(const audio_attributes_t& attributes)
+{
+    std::ostringstream result;
+    result << "{ Content type: " << toString(attributes.content_type)
+           << " Usage: " << toString(attributes.usage)
+           << " Source: " << toString(attributes.source)
+           << std::hex << " Flags: 0x" << attributes.flags
+           << std::dec << " Tags: " << attributes.tags
+           << " }";
+
+    return result.str();
+}
+
 }; // namespace android
 
 #endif  /*ANDROID_TYPE_CONVERTER_H_*/
diff --git a/media/libmedia/include/media/mediametadataretriever.h b/media/libmedia/include/media/mediametadataretriever.h
index cdef637..d29e97d 100644
--- a/media/libmedia/include/media/mediametadataretriever.h
+++ b/media/libmedia/include/media/mediametadataretriever.h
@@ -68,6 +68,11 @@
     METADATA_KEY_VIDEO_FRAME_COUNT  = 32,
     METADATA_KEY_EXIF_OFFSET     = 33,
     METADATA_KEY_EXIF_LENGTH     = 34,
+    METADATA_KEY_COLOR_STANDARD  = 35,
+    METADATA_KEY_COLOR_TRANSFER  = 36,
+    METADATA_KEY_COLOR_RANGE     = 37,
+    METADATA_KEY_SAMPLERATE      = 38,
+    METADATA_KEY_BITS_PER_SAMPLE = 39,
 
     // Add more here...
 };
diff --git a/media/libmedia/include/media/mediarecorder.h b/media/libmedia/include/media/mediarecorder.h
index d8b0fe7..2dd4b7f 100644
--- a/media/libmedia/include/media/mediarecorder.h
+++ b/media/libmedia/include/media/mediarecorder.h
@@ -67,7 +67,7 @@
     OUTPUT_FORMAT_AAC_ADTS = 6,
 
     OUTPUT_FORMAT_AUDIO_ONLY_END = 7, // Used in validating the output format.  Should be the
-                                      //  at the end of the audio only output formats.
+                                      // at the end of the audio only output formats.
 
     /* Stream over a socket, limited to a single stream */
     OUTPUT_FORMAT_RTP_AVP = 7,
@@ -81,6 +81,9 @@
     /* HEIC data in a HEIF container */
     OUTPUT_FORMAT_HEIF = 10,
 
+    /* Opus data in a OGG container */
+    OUTPUT_FORMAT_OGG = 11,
+
     OUTPUT_FORMAT_LIST_END // must be last - used to validate format type
 };
 
@@ -92,6 +95,7 @@
     AUDIO_ENCODER_HE_AAC = 4,
     AUDIO_ENCODER_AAC_ELD = 5,
     AUDIO_ENCODER_VORBIS = 6,
+    AUDIO_ENCODER_OPUS = 7,
 
     AUDIO_ENCODER_LIST_END // must be the last - used to validate the audio encoder type
 };
@@ -111,9 +115,6 @@
  * The state machine of the media_recorder.
  */
 enum media_recorder_states {
-    // Error state.
-    MEDIA_RECORDER_ERROR                 =      0,
-
     // Recorder was just created.
     MEDIA_RECORDER_IDLE                  = 1 << 0,
 
@@ -128,6 +129,9 @@
 
     // Recording is in progress.
     MEDIA_RECORDER_RECORDING             = 1 << 4,
+
+    // Error state.
+    MEDIA_RECORDER_ERROR                 = 1 << 5,
 };
 
 // The "msg" code passed to the listener in notify.
@@ -260,6 +264,10 @@
     status_t    getRoutedDeviceId(audio_port_handle_t *deviceId);
     status_t    enableAudioDeviceCallback(bool enabled);
     status_t    getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones);
+    status_t    setPreferredMicrophoneDirection(audio_microphone_direction_t direction);
+    status_t    setPreferredMicrophoneFieldDimension(float zoom);
+
+    status_t    getPortId(audio_port_handle_t *portId) const;
 
 private:
     void                    doCleanUp();
diff --git a/media/libmedia/include/media/omx/1.0/Conversion.h b/media/libmedia/include/media/omx/1.0/Conversion.h
index 3700a23..6dc46b7 100644
--- a/media/libmedia/include/media/omx/1.0/Conversion.h
+++ b/media/libmedia/include/media/omx/1.0/Conversion.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HARDWARE_MEDIA_OMX_V1_0__CONVERSION_H
-#define ANDROID_HARDWARE_MEDIA_OMX_V1_0__CONVERSION_H
+#ifndef ANDROID_HARDWARE_MEDIA_OMX_V1_0_UTILS_CONVERSION_H
+#define ANDROID_HARDWARE_MEDIA_OMX_V1_0_UTILS_CONVERSION_H
 
 #include <vector>
 #include <list>
@@ -31,12 +31,12 @@
 #include <ui/FenceTime.h>
 #include <cutils/native_handle.h>
 
+#include <ui/BufferQueueDefs.h>
 #include <ui/GraphicBuffer.h>
 #include <media/OMXFenceParcelable.h>
 #include <media/OMXBuffer.h>
 #include <media/hardware/VideoAPI.h>
 #include <media/stagefright/MediaErrors.h>
-#include <gui/IGraphicBufferProducer.h>
 
 #include <android/hardware/media/omx/1.0/types.h>
 #include <android/hardware/media/omx/1.0/IOmx.h>
@@ -258,7 +258,12 @@
  */
 // convert: Status -> status_t
 inline status_t toStatusT(Return<Status> const& t) {
-    return t.isOk() ? toStatusT(static_cast<Status>(t)) : UNKNOWN_ERROR;
+    if (t.isOk()) {
+        return toStatusT(static_cast<Status>(t));
+    } else if (t.isDeadObject()) {
+        return DEAD_OBJECT;
+    }
+    return UNKNOWN_ERROR;
 }
 
 /**
@@ -282,8 +287,8 @@
     case TIMED_OUT:
     case ERROR_UNSUPPORTED:
     case UNKNOWN_ERROR:
-    case IGraphicBufferProducer::RELEASE_ALL_BUFFERS:
-    case IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION:
+    case BufferQueueDefs::RELEASE_ALL_BUFFERS:
+    case BufferQueueDefs::BUFFER_NEEDS_REALLOCATION:
         return static_cast<Status>(l);
     case NOT_ENOUGH_DATA:
         return Status::BUFFER_NEEDS_REALLOCATION;
@@ -620,8 +625,18 @@
 // convert: AnwBuffer -> GraphicBuffer
 // Ref: frameworks/native/libs/ui/GraphicBuffer.cpp: GraphicBuffer::flatten
 inline bool convertTo(GraphicBuffer* l, AnwBuffer const& t) {
-    native_handle_t* handle = t.nativeHandle == nullptr ?
-            nullptr : native_handle_clone(t.nativeHandle);
+    native_handle_t* handle = nullptr;
+
+    if (t.nativeHandle != nullptr) {
+        handle = native_handle_clone(t.nativeHandle);
+        if (handle == nullptr) {
+            ALOGE("Failed to clone handle: numFds=%d, data[0]=%d, data[1]=%d",
+                    t.nativeHandle->numFds,
+                    (t.nativeHandle->numFds > 0) ? t.nativeHandle->data[0] : -1,
+                    (t.nativeHandle->numFds > 1) ? t.nativeHandle->data[1] : -1);
+            return false;
+        }
+    }
 
     size_t const numInts = 12 + (handle ? handle->numInts : 0);
     int32_t* ints = new int32_t[numInts];
@@ -751,7 +766,12 @@
                 return true;
             }
             AnwBuffer anwBuffer;
-            anwBuffer.nativeHandle = t.nativeHandle;
+            // Explicitly get the native_handle_t* (in stead of assigning t.nativeHandle)
+            // so that we don't do an extra native_handle_clone() in this step, as the
+            // convertion to GraphicBuffer below will do a clone regardless.
+            // If we encounter an invalid handle, the convertTo() below would fail (while
+            // the assigning of hidl_handle would abort and cause a crash).
+            anwBuffer.nativeHandle = t.nativeHandle.getNativeHandle();
             anwBuffer.attr = t.attr.anwBuffer;
             sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
             if (!convertTo(graphicBuffer.get(), anwBuffer)) {
@@ -938,4 +958,4 @@
 }  // namespace hardware
 }  // namespace android
 
-#endif  // ANDROID_HARDWARE_MEDIA_OMX_V1_0__CONVERSION_H
+#endif  // ANDROID_HARDWARE_MEDIA_OMX_V1_0_UTILS_CONVERSION_H
diff --git a/media/libmedia/include/media/omx/1.0/WOmx.h b/media/libmedia/include/media/omx/1.0/WOmx.h
index f13546e..0680eec 100644
--- a/media/libmedia/include/media/omx/1.0/WOmx.h
+++ b/media/libmedia/include/media/omx/1.0/WOmx.h
@@ -47,7 +47,6 @@
 
 using ::android::List;
 using ::android::IOMX;
-using ::android::BnOMX;
 
 /**
  * Wrapper classes for conversion
@@ -58,7 +57,7 @@
  * - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
  */
 
-struct LWOmx : public BnOMX {
+struct LWOmx : public IOMX {
     sp<IOmx> mBase;
     LWOmx(sp<IOmx> const& base);
     status_t listNodes(List<IOMX::ComponentInfo>* list) override;
diff --git a/media/libmedia/include/media/omx/1.0/WOmxNode.h b/media/libmedia/include/media/omx/1.0/WOmxNode.h
index eebc8c6..1db4248 100644
--- a/media/libmedia/include/media/omx/1.0/WOmxNode.h
+++ b/media/libmedia/include/media/omx/1.0/WOmxNode.h
@@ -59,7 +59,7 @@
  * - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
  */
 
-struct LWOmxNode : public H2BConverter<IOmxNode, IOMXNode, BnOMXNode> {
+struct LWOmxNode : public H2BConverter<IOmxNode, BnOMXNode> {
     LWOmxNode(sp<IOmxNode> const& base) : CBase(base) {}
     status_t freeNode() override;
     status_t sendCommand(
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index 721a043..4570af9 100644
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -20,6 +20,7 @@
 
 #include <inttypes.h>
 
+#include <android-base/macros.h>
 #include <utils/Log.h>
 #include <media/mediarecorder.h>
 #include <binder/IServiceManager.h>
@@ -597,7 +598,8 @@
             if (OK != ret) {
                 return ret;  // No need to continue
             }
-        }  // Intentional fall through
+            FALLTHROUGH_INTENDED;
+        }
         case MEDIA_RECORDER_INITIALIZED:
             ret = close();
             break;
@@ -840,4 +842,25 @@
     return mMediaRecorder->getActiveMicrophones(activeMicrophones);
 }
 
+status_t MediaRecorder::setPreferredMicrophoneDirection(audio_microphone_direction_t direction) {
+    ALOGV("setPreferredMicrophoneDirection(%d)", direction);
+    return mMediaRecorder->setPreferredMicrophoneDirection(direction);
+}
+
+status_t MediaRecorder::setPreferredMicrophoneFieldDimension(float zoom) {
+    ALOGV("setPreferredMicrophoneFieldDimension(%f)", zoom);
+    return mMediaRecorder->setPreferredMicrophoneFieldDimension(zoom);
+}
+
+status_t MediaRecorder::getPortId(audio_port_handle_t *portId) const
+{
+    ALOGV("getPortId");
+
+    if (mMediaRecorder == NULL) {
+        ALOGE("media recorder is not initialized yet");
+        return INVALID_OPERATION;
+    }
+    return mMediaRecorder->getPortId(portId);
+}
+
 } // namespace android
diff --git a/media/libmedia/omx/1.0/WGraphicBufferSource.cpp b/media/libmedia/omx/1.0/WGraphicBufferSource.cpp
index 31d1df9..1ed1d07 100644
--- a/media/libmedia/omx/1.0/WGraphicBufferSource.cpp
+++ b/media/libmedia/omx/1.0/WGraphicBufferSource.cpp
@@ -32,7 +32,7 @@
 
 BnStatus LWGraphicBufferSource::configure(
         const sp<IOMXNode>& omxNode, int32_t dataSpace) {
-    sp<IOmxNode> hOmxNode = omxNode->getHalInterface();
+    sp<IOmxNode> hOmxNode = omxNode->getHalInterface<IOmxNode>();
     return toBinderStatus(mBase->configure(
             hOmxNode == nullptr ? new TWOmxNode(omxNode) : hOmxNode,
             toHardwareDataspace(dataSpace)));
diff --git a/media/libmedia/xsd/Android.bp b/media/libmedia/xsd/Android.bp
new file mode 100644
index 0000000..1635f70
--- /dev/null
+++ b/media/libmedia/xsd/Android.bp
@@ -0,0 +1,21 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+xsd_config {
+    name: "media_profiles",
+    srcs: ["media_profiles.xsd"],
+    package_name: "media.profiles",
+}
diff --git a/media/libmedia/xsd/api/current.txt b/media/libmedia/xsd/api/current.txt
new file mode 100644
index 0000000..73b5f8d
--- /dev/null
+++ b/media/libmedia/xsd/api/current.txt
@@ -0,0 +1,147 @@
+// Signature format: 2.0
+package media.profiles {
+
+  public class Audio {
+    ctor public Audio();
+    method public int getBitRate();
+    method public int getChannels();
+    method public String getCodec();
+    method public int getSampleRate();
+    method public void setBitRate(int);
+    method public void setChannels(int);
+    method public void setCodec(String);
+    method public void setSampleRate(int);
+  }
+
+  public class AudioDecoderCap {
+    ctor public AudioDecoderCap();
+    method public boolean getEnabled();
+    method public String getName();
+    method public void setEnabled(boolean);
+    method public void setName(String);
+  }
+
+  public class AudioEncoderCap {
+    ctor public AudioEncoderCap();
+    method public boolean getEnabled();
+    method public int getMaxBitRate();
+    method public int getMaxChannels();
+    method public int getMaxSampleRate();
+    method public int getMinBitRate();
+    method public int getMinChannels();
+    method public int getMinSampleRate();
+    method public String getName();
+    method public void setEnabled(boolean);
+    method public void setMaxBitRate(int);
+    method public void setMaxChannels(int);
+    method public void setMaxSampleRate(int);
+    method public void setMinBitRate(int);
+    method public void setMinChannels(int);
+    method public void setMinSampleRate(int);
+    method public void setName(String);
+  }
+
+  public class CamcorderProfiles {
+    ctor public CamcorderProfiles();
+    method public int getCameraId();
+    method public java.util.List<media.profiles.EncoderProfile> getEncoderProfile_optional();
+    method public java.util.List<media.profiles.CamcorderProfiles.ImageDecodingOptional> getImageDecoding_optional();
+    method public java.util.List<media.profiles.CamcorderProfiles.ImageEncodingOptional> getImageEncoding_optional();
+    method public void setCameraId(int);
+  }
+
+  public static class CamcorderProfiles.ImageDecodingOptional {
+    ctor public CamcorderProfiles.ImageDecodingOptional();
+    method public int getMemCap();
+    method public void setMemCap(int);
+  }
+
+  public static class CamcorderProfiles.ImageEncodingOptional {
+    ctor public CamcorderProfiles.ImageEncodingOptional();
+    method public int getQuality();
+    method public void setQuality(int);
+  }
+
+  public class EncoderProfile {
+    ctor public EncoderProfile();
+    method public java.util.List<media.profiles.Audio> getAudio();
+    method public int getDuration();
+    method public String getFileFormat();
+    method public String getQuality();
+    method public java.util.List<media.profiles.Video> getVideo();
+    method public void setDuration(int);
+    method public void setFileFormat(String);
+    method public void setQuality(String);
+  }
+
+  public class MediaSettings {
+    ctor public MediaSettings();
+    method public java.util.List<media.profiles.AudioDecoderCap> getAudioDecoderCap();
+    method public java.util.List<media.profiles.AudioEncoderCap> getAudioEncoderCap();
+    method public java.util.List<media.profiles.CamcorderProfiles> getCamcorderProfiles();
+    method public java.util.List<media.profiles.MediaSettings.EncoderOutputFileFormat> getEncoderOutputFileFormat();
+    method public java.util.List<media.profiles.VideoDecoderCap> getVideoDecoderCap();
+    method public java.util.List<media.profiles.VideoEncoderCap> getVideoEncoderCap();
+  }
+
+  public static class MediaSettings.EncoderOutputFileFormat {
+    ctor public MediaSettings.EncoderOutputFileFormat();
+    method public String getName();
+    method public void setName(String);
+  }
+
+  public class Video {
+    ctor public Video();
+    method public int getBitRate();
+    method public String getCodec();
+    method public int getFrameRate();
+    method public int getHeight();
+    method public int getWidth();
+    method public void setBitRate(int);
+    method public void setCodec(String);
+    method public void setFrameRate(int);
+    method public void setHeight(int);
+    method public void setWidth(int);
+  }
+
+  public class VideoDecoderCap {
+    ctor public VideoDecoderCap();
+    method public boolean getEnabled();
+    method public String getName();
+    method public void setEnabled(boolean);
+    method public void setName(String);
+  }
+
+  public class VideoEncoderCap {
+    ctor public VideoEncoderCap();
+    method public boolean getEnabled();
+    method public int getMaxBitRate();
+    method public int getMaxFrameHeight();
+    method public int getMaxFrameRate();
+    method public int getMaxFrameWidth();
+    method public int getMinBitRate();
+    method public int getMinFrameHeight();
+    method public int getMinFrameRate();
+    method public int getMinFrameWidth();
+    method public String getName();
+    method public void setEnabled(boolean);
+    method public void setMaxBitRate(int);
+    method public void setMaxFrameHeight(int);
+    method public void setMaxFrameRate(int);
+    method public void setMaxFrameWidth(int);
+    method public void setMinBitRate(int);
+    method public void setMinFrameHeight(int);
+    method public void setMinFrameRate(int);
+    method public void setMinFrameWidth(int);
+    method public void setName(String);
+  }
+
+  public class XmlParser {
+    ctor public XmlParser();
+    method public static media.profiles.MediaSettings read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+  }
+
+}
+
diff --git a/media/common_time/MODULE_LICENSE_APACHE2 b/media/libmedia/xsd/api/last_current.txt
similarity index 100%
copy from media/common_time/MODULE_LICENSE_APACHE2
copy to media/libmedia/xsd/api/last_current.txt
diff --git a/media/common_time/MODULE_LICENSE_APACHE2 b/media/libmedia/xsd/api/last_removed.txt
similarity index 100%
copy from media/common_time/MODULE_LICENSE_APACHE2
copy to media/libmedia/xsd/api/last_removed.txt
diff --git a/media/libmedia/xsd/api/removed.txt b/media/libmedia/xsd/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/media/libmedia/xsd/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/media/libmedia/xsd/media_profiles.xsd b/media/libmedia/xsd/media_profiles.xsd
new file mode 100644
index 0000000..9664456
--- /dev/null
+++ b/media/libmedia/xsd/media_profiles.xsd
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+         Licensed under the Apache License, Version 2.0 (the "License");
+         you may not use this file except in compliance with the License.
+         You may obtain a copy of the License at
+
+                    http://www.apache.org/licenses/LICENSE-2.0
+
+         Unless required by applicable law or agreed to in writing, software
+         distributed under the License is distributed on an "AS IS" BASIS,
+         WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+         See the License for the specific language governing permissions and
+         limitations under the License.
+-->
+<!-- TODO: define a targetNamespace. Note that it will break retrocompatibility -->
+<xs:schema version="2.0"
+           elementFormDefault="qualified"
+           attributeFormDefault="unqualified"
+           xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <xs:element name="MediaSettings">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="CamcorderProfiles" type="CamcorderProfiles" minOccurs="0" maxOccurs="unbounded"/>
+                <xs:element name="EncoderOutputFileFormat" minOccurs="0" maxOccurs="unbounded">
+                    <xs:complexType>
+                        <xs:attribute name="name" type="xs:string"/>
+                    </xs:complexType>
+                </xs:element>
+                <xs:element name="VideoEncoderCap" type="VideoEncoderCap" minOccurs="0" maxOccurs="unbounded"/>
+                <xs:element name="AudioEncoderCap" type="AudioEncoderCap" minOccurs="0" maxOccurs="unbounded"/>
+                <xs:element name="VideoDecoderCap" type="VideoDecoderCap" minOccurs="0" maxOccurs="unbounded"/>
+                <xs:element name="AudioDecoderCap" type="AudioDecoderCap" minOccurs="0" maxOccurs="unbounded"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+    <xs:complexType name="CamcorderProfiles">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+            <xs:element name="EncoderProfile" type="EncoderProfile"/>
+            <xs:element name="ImageEncoding">
+                <xs:complexType>
+                    <xs:attribute name="quality" type="xs:int"/>
+                </xs:complexType>
+            </xs:element>
+            <xs:element name="ImageDecoding">
+                <xs:complexType>
+                    <xs:attribute name="memCap" type="xs:int"/>
+                </xs:complexType>
+            </xs:element>
+        </xs:choice>
+        <xs:attribute name="cameraId" type="xs:int"/>
+    </xs:complexType>
+    <xs:complexType name="EncoderProfile">
+        <xs:sequence>
+            <xs:element name="Video" type="Video" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="Audio" type="Audio" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+        <xs:attribute name="quality" type="xs:string"/>
+        <xs:attribute name="fileFormat" type="xs:string"/>
+        <xs:attribute name="duration" type="xs:int"/>
+    </xs:complexType>
+    <xs:complexType name="Video">
+        <xs:attribute name="codec" type="xs:string"/>
+        <xs:attribute name="bitRate" type="xs:int"/>
+        <xs:attribute name="width" type="xs:int"/>
+        <xs:attribute name="height" type="xs:int"/>
+        <xs:attribute name="frameRate" type="xs:int"/>
+    </xs:complexType>
+    <xs:complexType name="Audio">
+        <xs:attribute name="codec" type="xs:string"/>
+        <xs:attribute name="bitRate" type="xs:int"/>
+        <xs:attribute name="sampleRate" type="xs:int"/>
+        <xs:attribute name="channels" type="xs:int"/>
+    </xs:complexType>
+    <xs:complexType name="VideoEncoderCap">
+        <xs:attribute name="name" type="xs:string"/>
+        <xs:attribute name="enabled" type="xs:boolean"/>
+        <xs:attribute name="minBitRate" type="xs:int"/>
+        <xs:attribute name="maxBitRate" type="xs:int"/>
+        <xs:attribute name="minFrameWidth" type="xs:int"/>
+        <xs:attribute name="maxFrameWidth" type="xs:int"/>
+        <xs:attribute name="minFrameHeight" type="xs:int"/>
+        <xs:attribute name="maxFrameHeight" type="xs:int"/>
+        <xs:attribute name="minFrameRate" type="xs:int"/>
+        <xs:attribute name="maxFrameRate" type="xs:int"/>
+    </xs:complexType>
+    <xs:complexType name="AudioEncoderCap">
+        <xs:attribute name="name" type="xs:string"/>
+        <xs:attribute name="enabled" type="xs:boolean"/>
+        <xs:attribute name="minBitRate" type="xs:int"/>
+        <xs:attribute name="maxBitRate" type="xs:int"/>
+        <xs:attribute name="minSampleRate" type="xs:int"/>
+        <xs:attribute name="maxSampleRate" type="xs:int"/>
+        <xs:attribute name="minChannels" type="xs:int"/>
+        <xs:attribute name="maxChannels" type="xs:int"/>
+    </xs:complexType>
+    <xs:complexType name="VideoDecoderCap">
+        <xs:attribute name="name" type="xs:string"/>
+        <xs:attribute name="enabled" type="xs:boolean"/>
+    </xs:complexType>
+    <xs:complexType name="AudioDecoderCap">
+        <xs:attribute name="name" type="xs:string"/>
+        <xs:attribute name="enabled" type="xs:boolean"/>
+    </xs:complexType>
+</xs:schema>
diff --git a/media/libmedia/xsd/vts/Android.bp b/media/libmedia/xsd/vts/Android.bp
new file mode 100644
index 0000000..4739504
--- /dev/null
+++ b/media/libmedia/xsd/vts/Android.bp
@@ -0,0 +1,34 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+    name: "vts_mediaProfiles_validate_test",
+    srcs: [
+        "ValidateMediaProfiles.cpp"
+    ],
+    static_libs: [
+        "android.hardware.audio.common.test.utility",
+        "libxml2",
+    ],
+    shared_libs: [
+        "libbase",
+        "liblog",
+    ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+}
diff --git a/media/libmedia/xsd/vts/Android.mk b/media/libmedia/xsd/vts/Android.mk
new file mode 100644
index 0000000..52c3779
--- /dev/null
+++ b/media/libmedia/xsd/vts/Android.mk
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := VtsValidateMediaProfiles
+include test/vts/tools/build/Android.host_config.mk
diff --git a/media/libmedia/xsd/vts/AndroidTest.xml b/media/libmedia/xsd/vts/AndroidTest.xml
new file mode 100644
index 0000000..e68721b
--- /dev/null
+++ b/media/libmedia/xsd/vts/AndroidTest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for VTS VtsValidateMediaProfiles.">
+    <option name="config-descriptor:metadata" key="plan" value="vts-treble" />
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
+        <option name="abort-on-push-failure" value="false"/>
+        <option name="push-group" value="HostDrivenTest.push"/>
+        <option name="push" value="DATA/etc/media_profiles.xsd->/data/local/tmp/media_profiles.xsd"/>
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
+        <option name="test-module-name" value="VtsValidateMediaProfiles"/>
+        <option name="binary-test-source" value="_32bit::DATA/nativetest/vts_mediaProfiles_validate_test/vts_mediaProfiles_validate_test" />
+        <option name="binary-test-source" value="_64bit::DATA/nativetest64/vts_mediaProfiles_validate_test/vts_mediaProfiles_validate_test" />
+        <option name="binary-test-type" value="gtest"/>
+        <option name="test-timeout" value="30s"/>
+    </test>
+</configuration>
diff --git a/media/libmedia/xsd/vts/ValidateMediaProfiles.cpp b/media/libmedia/xsd/vts/ValidateMediaProfiles.cpp
new file mode 100644
index 0000000..7729d52
--- /dev/null
+++ b/media/libmedia/xsd/vts/ValidateMediaProfiles.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+
+#include <android-base/file.h>
+#include <android-base/properties.h>
+#include "utility/ValidateXml.h"
+
+TEST(CheckConfig, mediaProfilesValidation) {
+    RecordProperty("description",
+                   "Verify that the media profiles file "
+                   "is valid according to the schema");
+
+    std::string mediaSettingsPath = android::base::GetProperty("media.settings.xml", "");
+    if (mediaSettingsPath.empty()) {
+        mediaSettingsPath.assign("/vendor/etc/media_profiles_V1_0.xml");
+    }
+
+    EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS(android::base::Basename(mediaSettingsPath).c_str(),
+                                            {android::base::Dirname(mediaSettingsPath).c_str()},
+                                            "/data/local/tmp/media_profiles.xsd");
+}
diff --git a/media/libmediaextractor/Android.bp b/media/libmediaextractor/Android.bp
deleted file mode 100644
index b9b47cd..0000000
--- a/media/libmediaextractor/Android.bp
+++ /dev/null
@@ -1,50 +0,0 @@
-cc_library {
-    name: "libmediaextractor",
-
-    include_dirs: [
-        "frameworks/av/include",
-        "frameworks/av/media/libmediaextractor/include",
-    ],
-
-    export_include_dirs: ["include"],
-
-    cflags: [
-        "-Wno-multichar",
-        "-Werror",
-        "-Wall",
-    ],
-
-    shared_libs: [
-        "libbinder",
-        "libstagefright_foundation",
-        "libutils",
-        "libcutils",
-        "liblog",
-    ],
-
-    srcs: [
-        "DataSourceBase.cpp",
-        "MediaBuffer.cpp",
-        "MediaBufferBase.cpp",
-        "MediaBufferGroup.cpp",
-        "MediaSource.cpp",
-        "MediaTrack.cpp",
-        "MediaExtractor.cpp",
-        "MetaData.cpp",
-        "MetaDataBase.cpp",
-        "VorbisComment.cpp",
-    ],
-
-    clang: true,
-
-    sanitize: {
-        misc_undefined: [
-            "unsigned-integer-overflow",
-            "signed-integer-overflow",
-        ],
-        cfi: true,
-        diag: {
-            cfi: true,
-        },
-    },
-}
diff --git a/media/libmediaextractor/DataSourceBase.cpp b/media/libmediaextractor/DataSourceBase.cpp
deleted file mode 100644
index 8f47ee5..0000000
--- a/media/libmediaextractor/DataSourceBase.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-//#define LOG_NDEBUG 0
-#define LOG_TAG "DataSourceBase"
-
-#include <media/DataSourceBase.h>
-#include <media/stagefright/foundation/ByteUtils.h>
-#include <media/stagefright/MediaErrors.h>
-#include <utils/String8.h>
-
-namespace android {
-
-bool DataSourceBase::getUInt16(off64_t offset, uint16_t *x) {
-    *x = 0;
-
-    uint8_t byte[2];
-    if (readAt(offset, byte, 2) != 2) {
-        return false;
-    }
-
-    *x = (byte[0] << 8) | byte[1];
-
-    return true;
-}
-
-bool DataSourceBase::getUInt24(off64_t offset, uint32_t *x) {
-    *x = 0;
-
-    uint8_t byte[3];
-    if (readAt(offset, byte, 3) != 3) {
-        return false;
-    }
-
-    *x = (byte[0] << 16) | (byte[1] << 8) | byte[2];
-
-    return true;
-}
-
-bool DataSourceBase::getUInt32(off64_t offset, uint32_t *x) {
-    *x = 0;
-
-    uint32_t tmp;
-    if (readAt(offset, &tmp, 4) != 4) {
-        return false;
-    }
-
-    *x = ntohl(tmp);
-
-    return true;
-}
-
-bool DataSourceBase::getUInt64(off64_t offset, uint64_t *x) {
-    *x = 0;
-
-    uint64_t tmp;
-    if (readAt(offset, &tmp, 8) != 8) {
-        return false;
-    }
-
-    *x = ntoh64(tmp);
-
-    return true;
-}
-
-bool DataSourceBase::getUInt16Var(off64_t offset, uint16_t *x, size_t size) {
-    if (size == 2) {
-        return getUInt16(offset, x);
-    }
-    if (size == 1) {
-        uint8_t tmp;
-        if (readAt(offset, &tmp, 1) == 1) {
-            *x = tmp;
-            return true;
-        }
-    }
-    return false;
-}
-
-bool DataSourceBase::getUInt32Var(off64_t offset, uint32_t *x, size_t size) {
-    if (size == 4) {
-        return getUInt32(offset, x);
-    }
-    if (size == 2) {
-        uint16_t tmp;
-        if (getUInt16(offset, &tmp)) {
-            *x = tmp;
-            return true;
-        }
-    }
-    return false;
-}
-
-bool DataSourceBase::getUInt64Var(off64_t offset, uint64_t *x, size_t size) {
-    if (size == 8) {
-        return getUInt64(offset, x);
-    }
-    if (size == 4) {
-        uint32_t tmp;
-        if (getUInt32(offset, &tmp)) {
-            *x = tmp;
-            return true;
-        }
-    }
-    return false;
-}
-
-status_t DataSourceBase::getSize(off64_t *size) {
-    *size = 0;
-
-    return ERROR_UNSUPPORTED;
-}
-
-bool DataSourceBase::getUri(char *uriString __unused, size_t bufferSize __unused) {
-    return false;
-}
-
-}  // namespace android
diff --git a/media/libmediaextractor/MediaBuffer.cpp b/media/libmediaextractor/MediaBuffer.cpp
deleted file mode 100644
index 39f8d6e..0000000
--- a/media/libmediaextractor/MediaBuffer.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "MediaBuffer"
-#include <utils/Log.h>
-
-#include <errno.h>
-#include <pthread.h>
-#include <stdlib.h>
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/MetaData.h>
-
-namespace android {
-
-/* static */
-std::atomic_int_least32_t MediaBuffer::mUseSharedMemory(0);
-
-MediaBuffer::MediaBuffer(void *data, size_t size)
-    : mObserver(NULL),
-      mRefCount(0),
-      mData(data),
-      mSize(size),
-      mRangeOffset(0),
-      mRangeLength(size),
-      mOwnsData(false),
-      mMetaData(new MetaData),
-      mOriginal(NULL) {
-}
-
-MediaBuffer::MediaBuffer(size_t size)
-    : mObserver(NULL),
-      mRefCount(0),
-      mData(NULL),
-      mSize(size),
-      mRangeOffset(0),
-      mRangeLength(size),
-      mOwnsData(true),
-      mMetaData(new MetaData),
-      mOriginal(NULL) {
-    if (size < kSharedMemThreshold
-            || std::atomic_load_explicit(&mUseSharedMemory, std::memory_order_seq_cst) == 0) {
-        mData = malloc(size);
-    } else {
-        ALOGV("creating memoryDealer");
-        sp<MemoryDealer> memoryDealer =
-                new MemoryDealer(size + sizeof(SharedControl), "MediaBuffer");
-        mMemory = memoryDealer->allocate(size + sizeof(SharedControl));
-        if (mMemory == NULL) {
-            ALOGW("Failed to allocate shared memory, trying regular allocation!");
-            mData = malloc(size);
-            if (mData == NULL) {
-                ALOGE("Out of memory");
-            }
-        } else {
-            getSharedControl()->clear();
-            mData = (uint8_t *)mMemory->pointer() + sizeof(SharedControl);
-            ALOGV("Allocated shared mem buffer of size %zu @ %p", size, mData);
-        }
-    }
-}
-
-MediaBuffer::MediaBuffer(const sp<ABuffer> &buffer)
-    : mObserver(NULL),
-      mRefCount(0),
-      mData(buffer->data()),
-      mSize(buffer->size()),
-      mRangeOffset(0),
-      mRangeLength(mSize),
-      mBuffer(buffer),
-      mOwnsData(false),
-      mMetaData(new MetaData),
-      mOriginal(NULL) {
-}
-
-void MediaBuffer::release() {
-    if (mObserver == NULL) {
-        // Legacy contract for MediaBuffer without a MediaBufferGroup.
-        CHECK_EQ(mRefCount, 0);
-        delete this;
-        return;
-    }
-
-    int prevCount = __sync_fetch_and_sub(&mRefCount, 1);
-    if (prevCount == 1) {
-        if (mObserver == NULL) {
-            delete this;
-            return;
-        }
-
-        mObserver->signalBufferReturned(this);
-    }
-    CHECK(prevCount > 0);
-}
-
-void MediaBuffer::claim() {
-    CHECK(mObserver != NULL);
-    CHECK_EQ(mRefCount, 1);
-
-    mRefCount = 0;
-}
-
-void MediaBuffer::add_ref() {
-    (void) __sync_fetch_and_add(&mRefCount, 1);
-}
-
-void *MediaBuffer::data() const {
-    return mData;
-}
-
-size_t MediaBuffer::size() const {
-    return mSize;
-}
-
-size_t MediaBuffer::range_offset() const {
-    return mRangeOffset;
-}
-
-size_t MediaBuffer::range_length() const {
-    return mRangeLength;
-}
-
-void MediaBuffer::set_range(size_t offset, size_t length) {
-    if (offset + length > mSize) {
-        ALOGE("offset = %zu, length = %zu, mSize = %zu", offset, length, mSize);
-    }
-    CHECK(offset + length <= mSize);
-
-    mRangeOffset = offset;
-    mRangeLength = length;
-}
-
-MetaDataBase& MediaBuffer::meta_data() {
-    return *mMetaData;
-}
-
-void MediaBuffer::reset() {
-    mMetaData->clear();
-    set_range(0, mSize);
-}
-
-MediaBuffer::~MediaBuffer() {
-    CHECK(mObserver == NULL);
-
-    if (mOwnsData && mData != NULL && mMemory == NULL) {
-        free(mData);
-        mData = NULL;
-    }
-
-    if (mOriginal != NULL) {
-        mOriginal->release();
-        mOriginal = NULL;
-    }
-
-   if (mMemory.get() != nullptr) {
-       getSharedControl()->setDeadObject();
-   }
-   delete mMetaData;
-}
-
-void MediaBuffer::setObserver(MediaBufferObserver *observer) {
-    CHECK(observer == NULL || mObserver == NULL);
-    mObserver = observer;
-}
-
-MediaBufferBase *MediaBuffer::clone() {
-    MediaBuffer *buffer = new MediaBuffer(mData, mSize);
-    buffer->set_range(mRangeOffset, mRangeLength);
-    buffer->mMetaData = new MetaDataBase(*mMetaData);
-
-    add_ref();
-    buffer->mOriginal = this;
-
-    return buffer;
-}
-
-}  // namespace android
diff --git a/media/libmediaextractor/MediaBufferGroup.cpp b/media/libmediaextractor/MediaBufferGroup.cpp
deleted file mode 100644
index 2a8dd41..0000000
--- a/media/libmediaextractor/MediaBufferGroup.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "MediaBufferGroup"
-#include <utils/Log.h>
-
-#include <list>
-
-#include <binder/MemoryDealer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/MediaBufferGroup.h>
-#include <utils/threads.h>
-
-namespace android {
-
-// std::min is not constexpr in C++11
-template<typename T>
-constexpr T MIN(const T &a, const T &b) { return a <= b ? a : b; }
-
-// MediaBufferGroup may create shared memory buffers at a
-// smaller threshold than an isolated new MediaBuffer.
-static const size_t kSharedMemoryThreshold = MIN(
-        (size_t)MediaBuffer::kSharedMemThreshold, (size_t)(4 * 1024));
-
-struct MediaBufferGroup::InternalData {
-    Mutex mLock;
-    Condition mCondition;
-    size_t mGrowthLimit;  // Do not automatically grow group larger than this.
-    std::list<MediaBufferBase *> mBuffers;
-};
-
-MediaBufferGroup::MediaBufferGroup(size_t growthLimit)
-    : mInternal(new InternalData()) {
-    mInternal->mGrowthLimit = growthLimit;
-}
-
-MediaBufferGroup::MediaBufferGroup(size_t buffers, size_t buffer_size, size_t growthLimit)
-    : mInternal(new InternalData()) {
-    mInternal->mGrowthLimit = growthLimit;
-
-    if (mInternal->mGrowthLimit > 0 && buffers > mInternal->mGrowthLimit) {
-        ALOGW("Preallocated buffers %zu > growthLimit %zu, increasing growthLimit",
-                buffers, mInternal->mGrowthLimit);
-        mInternal->mGrowthLimit = buffers;
-    }
-
-    if (buffer_size >= kSharedMemoryThreshold) {
-        ALOGD("creating MemoryDealer");
-        // Using a single MemoryDealer is efficient for a group of shared memory objects.
-        // This loop guarantees that we use shared memory (no fallback to malloc).
-
-        size_t alignment = MemoryDealer::getAllocationAlignment();
-        size_t augmented_size = buffer_size + sizeof(MediaBuffer::SharedControl);
-        size_t total = (augmented_size + alignment - 1) / alignment * alignment * buffers;
-        sp<MemoryDealer> memoryDealer = new MemoryDealer(total, "MediaBufferGroup");
-
-        for (size_t i = 0; i < buffers; ++i) {
-            sp<IMemory> mem = memoryDealer->allocate(augmented_size);
-            if (mem.get() == nullptr || mem->pointer() == nullptr) {
-                ALOGW("Only allocated %zu shared buffers of size %zu", i, buffer_size);
-                break;
-            }
-            MediaBuffer *buffer = new MediaBuffer(mem);
-            buffer->getSharedControl()->clear();
-            add_buffer(buffer);
-        }
-        return;
-    }
-
-    // Non-shared memory allocation.
-    for (size_t i = 0; i < buffers; ++i) {
-        MediaBuffer *buffer = new MediaBuffer(buffer_size);
-        if (buffer->data() == nullptr) {
-            delete buffer; // don't call release, it's not properly formed
-            ALOGW("Only allocated %zu malloc buffers of size %zu", i, buffer_size);
-            break;
-        }
-        add_buffer(buffer);
-    }
-}
-
-MediaBufferGroup::~MediaBufferGroup() {
-    for (MediaBufferBase *buffer : mInternal->mBuffers) {
-        if (buffer->refcount() != 0) {
-            const int localRefcount = buffer->localRefcount();
-            const int remoteRefcount = buffer->remoteRefcount();
-
-            // Fatal if we have a local refcount.
-            LOG_ALWAYS_FATAL_IF(localRefcount != 0,
-                    "buffer(%p) localRefcount %d != 0, remoteRefcount %d",
-                    buffer, localRefcount, remoteRefcount);
-
-            // Log an error if we have a remaining remote refcount,
-            // as the remote process may have died or may have inappropriate behavior.
-            // The shared memory associated with the MediaBuffer will
-            // automatically be reclaimed when there are no remaining fds
-            // associated with it.
-            ALOGE("buffer(%p) has residual remoteRefcount %d",
-                    buffer, remoteRefcount);
-        }
-        // gracefully delete.
-        buffer->setObserver(nullptr);
-        buffer->release();
-    }
-    delete mInternal;
-}
-
-void MediaBufferGroup::add_buffer(MediaBufferBase *buffer) {
-    Mutex::Autolock autoLock(mInternal->mLock);
-
-    // if we're above our growth limit, release buffers if we can
-    for (auto it = mInternal->mBuffers.begin();
-            mInternal->mGrowthLimit > 0
-            && mInternal->mBuffers.size() >= mInternal->mGrowthLimit
-            && it != mInternal->mBuffers.end();) {
-        if ((*it)->refcount() == 0) {
-            (*it)->setObserver(nullptr);
-            (*it)->release();
-            it = mInternal->mBuffers.erase(it);
-        } else {
-            ++it;
-        }
-    }
-
-    buffer->setObserver(this);
-    mInternal->mBuffers.emplace_back(buffer);
-}
-
-bool MediaBufferGroup::has_buffers() {
-    if (mInternal->mBuffers.size() < mInternal->mGrowthLimit) {
-        return true; // We can add more buffers internally.
-    }
-    for (MediaBufferBase *buffer : mInternal->mBuffers) {
-        if (buffer->refcount() == 0) {
-            return true;
-        }
-    }
-    return false;
-}
-
-status_t MediaBufferGroup::acquire_buffer(
-        MediaBufferBase **out, bool nonBlocking, size_t requestedSize) {
-    Mutex::Autolock autoLock(mInternal->mLock);
-    for (;;) {
-        size_t smallest = requestedSize;
-        MediaBufferBase *buffer = nullptr;
-        auto free = mInternal->mBuffers.end();
-        for (auto it = mInternal->mBuffers.begin(); it != mInternal->mBuffers.end(); ++it) {
-            if ((*it)->refcount() == 0) {
-                const size_t size = (*it)->size();
-                if (size >= requestedSize) {
-                    buffer = *it;
-                    break;
-                }
-                if (size < smallest) {
-                    smallest = size; // always free the smallest buf
-                    free = it;
-                }
-            }
-        }
-        if (buffer == nullptr
-                && (free != mInternal->mBuffers.end()
-                    || mInternal->mBuffers.size() < mInternal->mGrowthLimit)) {
-            // We alloc before we free so failure leaves group unchanged.
-            const size_t allocateSize = requestedSize < SIZE_MAX / 3 * 2 /* NB: ordering */ ?
-                    requestedSize * 3 / 2 : requestedSize;
-            buffer = new MediaBuffer(allocateSize);
-            if (buffer->data() == nullptr) {
-                ALOGE("Allocation failure for size %zu", allocateSize);
-                delete buffer; // Invalid alloc, prefer not to call release.
-                buffer = nullptr;
-            } else {
-                buffer->setObserver(this);
-                if (free != mInternal->mBuffers.end()) {
-                    ALOGV("reallocate buffer, requested size %zu vs available %zu",
-                            requestedSize, (*free)->size());
-                    (*free)->setObserver(nullptr);
-                    (*free)->release();
-                    *free = buffer; // in-place replace
-                } else {
-                    ALOGV("allocate buffer, requested size %zu", requestedSize);
-                    mInternal->mBuffers.emplace_back(buffer);
-                }
-            }
-        }
-        if (buffer != nullptr) {
-            buffer->add_ref();
-            buffer->reset();
-            *out = buffer;
-            return OK;
-        }
-        if (nonBlocking) {
-            *out = nullptr;
-            return WOULD_BLOCK;
-        }
-        // All buffers are in use, block until one of them is returned.
-        mInternal->mCondition.wait(mInternal->mLock);
-    }
-    // Never gets here.
-}
-
-size_t MediaBufferGroup::buffers() const {
-    return mInternal->mBuffers.size();
-}
-
-void MediaBufferGroup::signalBufferReturned(MediaBufferBase *) {
-    Mutex::Autolock autoLock(mInternal->mLock);
-    mInternal->mCondition.signal();
-}
-
-}  // namespace android
diff --git a/media/libmediaextractor/MediaExtractor.cpp b/media/libmediaextractor/MediaExtractor.cpp
deleted file mode 100644
index a6b3dc9..0000000
--- a/media/libmediaextractor/MediaExtractor.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "MediaExtractor"
-#include <utils/Log.h>
-#include <pwd.h>
-
-#include <media/MediaExtractor.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/MetaData.h>
-
-namespace android {
-
-MediaExtractor::MediaExtractor() {
-    if (!LOG_NDEBUG) {
-        uid_t uid = getuid();
-        struct passwd *pw = getpwuid(uid);
-        ALOGV("extractor created in uid: %d (%s)", getuid(), pw->pw_name);
-    }
-}
-
-MediaExtractor::~MediaExtractor() {}
-
-uint32_t MediaExtractor::flags() const {
-    return CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_PAUSE | CAN_SEEK;
-}
-
-}  // namespace android
diff --git a/media/libmediaextractor/MediaTrack.cpp b/media/libmediaextractor/MediaTrack.cpp
deleted file mode 100644
index 4963f58..0000000
--- a/media/libmediaextractor/MediaTrack.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <media/MediaTrack.h>
-
-namespace android {
-
-MediaTrack::MediaTrack() {}
-
-MediaTrack::~MediaTrack() {}
-
-////////////////////////////////////////////////////////////////////////////////
-
-MediaTrack::ReadOptions::ReadOptions() {
-    reset();
-}
-
-void MediaTrack::ReadOptions::reset() {
-    mOptions = 0;
-    mSeekTimeUs = 0;
-    mNonBlocking = false;
-}
-
-void MediaTrack::ReadOptions::setNonBlocking() {
-    mNonBlocking = true;
-}
-
-void MediaTrack::ReadOptions::clearNonBlocking() {
-    mNonBlocking = false;
-}
-
-bool MediaTrack::ReadOptions::getNonBlocking() const {
-    return mNonBlocking;
-}
-
-void MediaTrack::ReadOptions::setSeekTo(int64_t time_us, SeekMode mode) {
-    mOptions |= kSeekTo_Option;
-    mSeekTimeUs = time_us;
-    mSeekMode = mode;
-}
-
-void MediaTrack::ReadOptions::clearSeekTo() {
-    mOptions &= ~kSeekTo_Option;
-    mSeekTimeUs = 0;
-    mSeekMode = SEEK_CLOSEST_SYNC;
-}
-
-bool MediaTrack::ReadOptions::getSeekTo(
-        int64_t *time_us, SeekMode *mode) const {
-    *time_us = mSeekTimeUs;
-    *mode = mSeekMode;
-    return (mOptions & kSeekTo_Option) != 0;
-}
-
-}  // namespace android
diff --git a/media/libmediaextractor/VorbisComment.cpp b/media/libmediaextractor/VorbisComment.cpp
deleted file mode 100644
index fabaf51..0000000
--- a/media/libmediaextractor/VorbisComment.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "VorbisComment"
-#include <utils/Log.h>
-
-#include "media/VorbisComment.h"
-
-#include <media/stagefright/foundation/base64.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/AString.h>
-#include <media/stagefright/foundation/ByteUtils.h>
-#include <media/stagefright/MetaDataBase.h>
-
-namespace android {
-
-static void extractAlbumArt(
-        MetaDataBase *fileMeta, const void *data, size_t size) {
-    ALOGV("extractAlbumArt from '%s'", (const char *)data);
-
-    sp<ABuffer> flacBuffer = decodeBase64(AString((const char *)data, size));
-    if (flacBuffer == NULL) {
-        ALOGE("malformed base64 encoded data.");
-        return;
-    }
-
-    size_t flacSize = flacBuffer->size();
-    uint8_t *flac = flacBuffer->data();
-    ALOGV("got flac of size %zu", flacSize);
-
-    uint32_t picType;
-    uint32_t typeLen;
-    uint32_t descLen;
-    uint32_t dataLen;
-    char type[128];
-
-    if (flacSize < 8) {
-        return;
-    }
-
-    picType = U32_AT(flac);
-
-    if (picType != 3) {
-        // This is not a front cover.
-        return;
-    }
-
-    typeLen = U32_AT(&flac[4]);
-    if (typeLen > sizeof(type) - 1) {
-        return;
-    }
-
-    // we've already checked above that flacSize >= 8
-    if (flacSize - 8 < typeLen) {
-        return;
-    }
-
-    memcpy(type, &flac[8], typeLen);
-    type[typeLen] = '\0';
-
-    ALOGV("picType = %d, type = '%s'", picType, type);
-
-    if (!strcmp(type, "-->")) {
-        // This is not inline cover art, but an external url instead.
-        return;
-    }
-
-    if (flacSize < 32 || flacSize - 32 < typeLen) {
-        return;
-    }
-
-    descLen = U32_AT(&flac[8 + typeLen]);
-    if (flacSize - 32 - typeLen < descLen) {
-        return;
-    }
-
-    dataLen = U32_AT(&flac[8 + typeLen + 4 + descLen + 16]);
-
-    // we've already checked above that (flacSize - 32 - typeLen - descLen) >= 0
-    if (flacSize - 32 - typeLen - descLen < dataLen) {
-        return;
-    }
-
-    ALOGV("got image data, %zu trailing bytes",
-         flacSize - 32 - typeLen - descLen - dataLen);
-
-    fileMeta->setData(
-            kKeyAlbumArt, 0, &flac[8 + typeLen + 4 + descLen + 20], dataLen);
-
-    fileMeta->setCString(kKeyAlbumArtMIME, type);
-}
-
-void parseVorbisComment(
-        MetaDataBase *fileMeta, const char *comment, size_t commentLength)
-{
-    struct {
-        const char *const mTag;
-        uint32_t mKey;
-    } kMap[] = {
-        { "TITLE", kKeyTitle },
-        { "ARTIST", kKeyArtist },
-        { "ALBUMARTIST", kKeyAlbumArtist },
-        { "ALBUM ARTIST", kKeyAlbumArtist },
-        { "COMPILATION", kKeyCompilation },
-        { "ALBUM", kKeyAlbum },
-        { "COMPOSER", kKeyComposer },
-        { "GENRE", kKeyGenre },
-        { "AUTHOR", kKeyAuthor },
-        { "TRACKNUMBER", kKeyCDTrackNumber },
-        { "DISCNUMBER", kKeyDiscNumber },
-        { "DATE", kKeyDate },
-        { "YEAR", kKeyYear },
-        { "LYRICIST", kKeyWriter },
-        { "METADATA_BLOCK_PICTURE", kKeyAlbumArt },
-        { "ANDROID_LOOP", kKeyAutoLoop },
-    };
-
-        for (size_t j = 0; j < sizeof(kMap) / sizeof(kMap[0]); ++j) {
-            size_t tagLen = strlen(kMap[j].mTag);
-            if (!strncasecmp(kMap[j].mTag, comment, tagLen)
-                    && comment[tagLen] == '=') {
-                if (kMap[j].mKey == kKeyAlbumArt) {
-                    extractAlbumArt(
-                            fileMeta,
-                            &comment[tagLen + 1],
-                            commentLength - tagLen - 1);
-                } else if (kMap[j].mKey == kKeyAutoLoop) {
-                    if (!strcasecmp(&comment[tagLen + 1], "true")) {
-                        fileMeta->setInt32(kKeyAutoLoop, true);
-                    }
-                } else {
-                    fileMeta->setCString(kMap[j].mKey, &comment[tagLen + 1]);
-                }
-            }
-        }
-
-}
-
-}  // namespace android
diff --git a/media/libmediaextractor/include/media/DataSource.h b/media/libmediaextractor/include/media/DataSource.h
deleted file mode 100644
index 0e59f39..0000000
--- a/media/libmediaextractor/include/media/DataSource.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef DATA_SOURCE_H_
-
-#define DATA_SOURCE_H_
-
-#include <sys/types.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/DataSourceBase.h>
-#include <media/IDataSource.h>
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-#include <utils/threads.h>
-#include <drm/DrmManagerClient.h>
-
-
-namespace android {
-
-class String8;
-
-class DataSource : public DataSourceBase, public virtual RefBase {
-public:
-    DataSource() {}
-
-    // returns a pointer to IDataSource if it is wrapped.
-    virtual sp<IDataSource> getIDataSource() const {
-        return nullptr;
-    }
-
-    virtual String8 toString() {
-        return String8("<unspecified>");
-    }
-
-    virtual status_t reconnectAtOffset(off64_t /*offset*/) {
-        return ERROR_UNSUPPORTED;
-    }
-
-    ////////////////////////////////////////////////////////////////////////////
-
-    // for DRM
-    virtual sp<DecryptHandle> DrmInitialization(const char * /*mime*/ = NULL) {
-        return NULL;
-    }
-
-    virtual String8 getUri() {
-        return String8();
-    }
-
-    virtual bool getUri(char *uriString, size_t bufferSize) final {
-        int ret = snprintf(uriString, bufferSize, "%s", getUri().c_str());
-        return ret >= 0 && static_cast<size_t>(ret) < bufferSize;
-    }
-
-    virtual String8 getMIMEType() const {
-        return String8("application/octet-stream");
-    }
-
-protected:
-    virtual ~DataSource() {}
-
-private:
-    DataSource(const DataSource &);
-    DataSource &operator=(const DataSource &);
-};
-
-}  // namespace android
-
-#endif  // DATA_SOURCE_H_
diff --git a/media/libmediaextractor/include/media/DataSourceBase.h b/media/libmediaextractor/include/media/DataSourceBase.h
deleted file mode 100644
index 51993da..0000000
--- a/media/libmediaextractor/include/media/DataSourceBase.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef DATA_SOURCE_BASE_H_
-
-#define DATA_SOURCE_BASE_H_
-
-#include <sys/types.h>
-#include <utils/Errors.h>
-
-namespace android {
-
-class String8;
-
-class DataSourceBase {
-public:
-    enum Flags {
-        kWantsPrefetching      = 1,
-        kStreamedFromLocalHost = 2,
-        kIsCachingDataSource   = 4,
-        kIsHTTPBasedSource     = 8,
-        kIsLocalFileSource     = 16,
-    };
-
-    DataSourceBase() {}
-
-    virtual status_t initCheck() const = 0;
-
-    // Returns the number of bytes read, or -1 on failure. It's not an error if
-    // this returns zero; it just means the given offset is equal to, or
-    // beyond, the end of the source.
-    virtual ssize_t readAt(off64_t offset, void *data, size_t size) = 0;
-
-    // Convenience methods:
-    bool getUInt16(off64_t offset, uint16_t *x);
-    bool getUInt24(off64_t offset, uint32_t *x); // 3 byte int, returned as a 32-bit int
-    bool getUInt32(off64_t offset, uint32_t *x);
-    bool getUInt64(off64_t offset, uint64_t *x);
-
-    // read either int<N> or int<2N> into a uint<2N>_t, size is the int size in bytes.
-    bool getUInt16Var(off64_t offset, uint16_t *x, size_t size);
-    bool getUInt32Var(off64_t offset, uint32_t *x, size_t size);
-    bool getUInt64Var(off64_t offset, uint64_t *x, size_t size);
-
-    // May return ERROR_UNSUPPORTED.
-    virtual status_t getSize(off64_t *size);
-
-    virtual bool getUri(char *uriString, size_t bufferSize);
-
-    virtual uint32_t flags() {
-        return 0;
-    }
-
-    virtual void close() {};
-
-protected:
-    virtual ~DataSourceBase() {}
-
-private:
-    DataSourceBase(const DataSourceBase &);
-    DataSourceBase &operator=(const DataSourceBase &);
-};
-
-}  // namespace android
-
-#endif  // DATA_SOURCE_BASE_H_
diff --git a/media/libmediaextractor/include/media/MediaExtractor.h b/media/libmediaextractor/include/media/MediaExtractor.h
deleted file mode 100644
index 4ba98da..0000000
--- a/media/libmediaextractor/include/media/MediaExtractor.h
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MEDIA_EXTRACTOR_H_
-
-#define MEDIA_EXTRACTOR_H_
-
-#include <stdio.h>
-#include <vector>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-#include <utils/RefBase.h>
-
-namespace android {
-
-class DataSourceBase;
-class MetaDataBase;
-struct MediaTrack;
-
-
-class ExtractorAllocTracker {
-public:
-    ExtractorAllocTracker() {
-        ALOGD("extractor allocated: %p", this);
-    }
-    virtual ~ExtractorAllocTracker() {
-        ALOGD("extractor freed: %p", this);
-    }
-};
-
-
-class MediaExtractor
-// : public ExtractorAllocTracker
-{
-public:
-    virtual ~MediaExtractor();
-    virtual size_t countTracks() = 0;
-    virtual MediaTrack *getTrack(size_t index) = 0;
-
-    enum GetTrackMetaDataFlags {
-        kIncludeExtensiveMetaData = 1
-    };
-    virtual status_t getTrackMetaData(
-            MetaDataBase& meta,
-            size_t index, uint32_t flags = 0) = 0;
-
-    // Return container specific meta-data. The default implementation
-    // returns an empty metadata object.
-    virtual status_t getMetaData(MetaDataBase& meta) = 0;
-
-    enum Flags {
-        CAN_SEEK_BACKWARD  = 1,  // the "seek 10secs back button"
-        CAN_SEEK_FORWARD   = 2,  // the "seek 10secs forward button"
-        CAN_PAUSE          = 4,
-        CAN_SEEK           = 8,  // the "seek bar"
-    };
-
-    // If subclasses do _not_ override this, the default is
-    // CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK | CAN_PAUSE
-    virtual uint32_t flags() const;
-
-    virtual status_t setMediaCas(const uint8_t* /*casToken*/, size_t /*size*/) {
-        return INVALID_OPERATION;
-    }
-
-    virtual const char * name() { return "<unspecified>"; }
-
-    typedef MediaExtractor* (*CreatorFunc)(
-            DataSourceBase *source, void *meta);
-    typedef void (*FreeMetaFunc)(void *meta);
-
-    // The sniffer can optionally fill in an opaque object, "meta", that helps
-    // the corresponding extractor initialize its state without duplicating
-    // effort already exerted by the sniffer. If "freeMeta" is given, it will be
-    // called against the opaque object when it is no longer used.
-    typedef CreatorFunc (*SnifferFunc)(
-            DataSourceBase *source, float *confidence,
-            void **meta, FreeMetaFunc *freeMeta);
-
-    typedef struct {
-        const uint8_t b[16];
-    } uuid_t;
-
-    typedef struct {
-        // version number of this structure
-        const uint32_t def_version;
-
-        // A unique identifier for this extractor.
-        // See below for a convenience macro to create this from a string.
-        uuid_t extractor_uuid;
-
-        // Version number of this extractor. When two extractors with the same
-        // uuid are encountered, the one with the largest version number will
-        // be used.
-        const uint32_t extractor_version;
-
-        // a human readable name
-        const char *extractor_name;
-
-        // the sniffer function
-        const SnifferFunc sniff;
-    } ExtractorDef;
-
-    static const uint32_t EXTRACTORDEF_VERSION = 1;
-
-    typedef ExtractorDef (*GetExtractorDef)();
-
-protected:
-    MediaExtractor();
-
-private:
-    MediaExtractor(const MediaExtractor &);
-    MediaExtractor &operator=(const MediaExtractor &);
-};
-
-// purposely not defined anywhere so that this will fail to link if
-// expressions below are not evaluated at compile time
-int invalid_uuid_string(const char *);
-
-template <typename T, size_t N>
-constexpr uint8_t _digitAt_(const T (&s)[N], const size_t n) {
-    return s[n] >= '0' && s[n] <= '9' ? s[n] - '0'
-            : s[n] >= 'a' && s[n] <= 'f' ? s[n] - 'a' + 10
-                    : s[n] >= 'A' && s[n] <= 'F' ? s[n] - 'A' + 10
-                            : invalid_uuid_string("uuid: bad digits");
-}
-
-template <typename T, size_t N>
-constexpr uint8_t _hexByteAt_(const T (&s)[N], size_t n) {
-    return (_digitAt_(s, n) << 4) + _digitAt_(s, n + 1);
-}
-
-constexpr bool _assertIsDash_(char c) {
-    return c == '-' ? true : invalid_uuid_string("Wrong format");
-}
-
-template <size_t N>
-constexpr MediaExtractor::uuid_t constUUID(const char (&s) [N]) {
-    static_assert(N == 37, "uuid: wrong length");
-    return
-            _assertIsDash_(s[8]),
-            _assertIsDash_(s[13]),
-            _assertIsDash_(s[18]),
-            _assertIsDash_(s[23]),
-            MediaExtractor::uuid_t {{
-                _hexByteAt_(s, 0),
-                _hexByteAt_(s, 2),
-                _hexByteAt_(s, 4),
-                _hexByteAt_(s, 6),
-                _hexByteAt_(s, 9),
-                _hexByteAt_(s, 11),
-                _hexByteAt_(s, 14),
-                _hexByteAt_(s, 16),
-                _hexByteAt_(s, 19),
-                _hexByteAt_(s, 21),
-                _hexByteAt_(s, 24),
-                _hexByteAt_(s, 26),
-                _hexByteAt_(s, 28),
-                _hexByteAt_(s, 30),
-                _hexByteAt_(s, 32),
-                _hexByteAt_(s, 34),
-            }};
-}
-// Convenience macro to create a uuid_t from a string literal, which should
-// be formatted as "12345678-1234-1234-1234-123456789abc", as generated by
-// e.g. https://www.uuidgenerator.net/ or the 'uuidgen' linux command.
-// Hex digits may be upper or lower case.
-//
-// The macro call is otherwise equivalent to specifying the structure directly
-// (e.g. UUID("7d613858-5837-4a38-84c5-332d1cddee27") is the same as
-//       {{0x7d, 0x61, 0x38, 0x58, 0x58, 0x37, 0x4a, 0x38,
-//         0x84, 0xc5, 0x33, 0x2d, 0x1c, 0xdd, 0xee, 0x27}})
-
-#define UUID(str) []{ constexpr MediaExtractor::uuid_t uuid = constUUID(str); return uuid; }()
-
-
-
-}  // namespace android
-
-#endif  // MEDIA_EXTRACTOR_H_
diff --git a/media/libmediaextractor/include/media/MediaTrack.h b/media/libmediaextractor/include/media/MediaTrack.h
deleted file mode 100644
index adea61a..0000000
--- a/media/libmediaextractor/include/media/MediaTrack.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MEDIA_SOURCE_BASE_H_
-
-#define MEDIA_SOURCE_BASE_H_
-
-#include <sys/types.h>
-
-#include <binder/IMemory.h>
-#include <binder/MemoryDealer.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/MetaData.h>
-#include <utils/Log.h>
-#include <utils/RefBase.h>
-#include <utils/Vector.h>
-
-namespace android {
-
-class MediaBufferBase;
-
-class SourceBaseAllocTracker {
-public:
-    SourceBaseAllocTracker() {
-        ALOGD("sourcebase allocated: %p", this);
-    }
-    virtual ~SourceBaseAllocTracker() {
-        ALOGD("sourcebase freed: %p", this);
-    }
-};
-
-struct MediaTrack
-//    : public SourceBaseAllocTracker
-{
-    MediaTrack();
-
-    // To be called before any other methods on this object, except
-    // getFormat().
-    virtual status_t start(MetaDataBase *params = NULL) = 0;
-
-    // Any blocking read call returns immediately with a result of NO_INIT.
-    // It is an error to call any methods other than start after this call
-    // returns. Any buffers the object may be holding onto at the time of
-    // the stop() call are released.
-    // Also, it is imperative that any buffers output by this object and
-    // held onto by callers be released before a call to stop() !!!
-    virtual status_t stop() = 0;
-
-    // Returns the format of the data output by this media track.
-    virtual status_t getFormat(MetaDataBase& format) = 0;
-
-    // Options that modify read() behaviour. The default is to
-    // a) not request a seek
-    // b) not be late, i.e. lateness_us = 0
-    struct ReadOptions {
-        enum SeekMode : int32_t {
-            SEEK_PREVIOUS_SYNC,
-            SEEK_NEXT_SYNC,
-            SEEK_CLOSEST_SYNC,
-            SEEK_CLOSEST,
-            SEEK_FRAME_INDEX,
-        };
-
-        ReadOptions();
-
-        // Reset everything back to defaults.
-        void reset();
-
-        void setSeekTo(int64_t time_us, SeekMode mode = SEEK_CLOSEST_SYNC);
-        void clearSeekTo();
-        bool getSeekTo(int64_t *time_us, SeekMode *mode) const;
-
-        void setNonBlocking();
-        void clearNonBlocking();
-        bool getNonBlocking() const;
-
-        // Used to clear all non-persistent options for multiple buffer reads.
-        void clearNonPersistent() {
-            clearSeekTo();
-        }
-
-    private:
-        enum Options {
-            kSeekTo_Option      = 1,
-        };
-
-        uint32_t mOptions;
-        int64_t mSeekTimeUs;
-        SeekMode mSeekMode;
-        bool mNonBlocking;
-    } __attribute__((packed)); // sent through Binder
-
-    // Returns a new buffer of data. Call blocks until a
-    // buffer is available, an error is encountered of the end of the stream
-    // is reached.
-    // End of stream is signalled by a result of ERROR_END_OF_STREAM.
-    // A result of INFO_FORMAT_CHANGED indicates that the format of this
-    // MediaSource has changed mid-stream, the client can continue reading
-    // but should be prepared for buffers of the new configuration.
-    virtual status_t read(
-            MediaBufferBase **buffer, const ReadOptions *options = NULL) = 0;
-
-    virtual ~MediaTrack();
-
-private:
-    MediaTrack(const MediaTrack &);
-    MediaTrack &operator=(const MediaTrack &);
-};
-
-}  // namespace android
-
-#endif  // MEDIA_SOURCE_BASE_H_
diff --git a/media/libmediaextractor/include/media/VorbisComment.h b/media/libmediaextractor/include/media/VorbisComment.h
deleted file mode 100644
index 8ba3295..0000000
--- a/media/libmediaextractor/include/media/VorbisComment.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef VORBIS_COMMENT_H_
-#define VORBIS_COMMENT_H_
-
-namespace android {
-
-class MetaDataBase;
-
-void parseVorbisComment(
-        MetaDataBase *fileMeta, const char *comment, size_t commentLength);
-
-}  // namespace android
-
-#endif // VORBIS_COMMENT_H_
diff --git a/media/libmediaextractor/include/media/stagefright/MediaBuffer.h b/media/libmediaextractor/include/media/stagefright/MediaBuffer.h
deleted file mode 100644
index f944d51..0000000
--- a/media/libmediaextractor/include/media/stagefright/MediaBuffer.h
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MEDIA_BUFFER_H_
-
-#define MEDIA_BUFFER_H_
-
-#include <atomic>
-#include <list>
-
-#include <pthread.h>
-
-#include <binder/MemoryDealer.h>
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-#include <media/stagefright/MediaBufferBase.h>
-
-namespace android {
-
-struct ABuffer;
-class MediaBuffer;
-class MediaBufferObserver;
-class MetaDataBase;
-
-class MediaBuffer : public MediaBufferBase {
-public:
-    // allocations larger than or equal to this will use shared memory.
-    static const size_t kSharedMemThreshold = 64 * 1024;
-
-    // The underlying data remains the responsibility of the caller!
-    MediaBuffer(void *data, size_t size);
-
-    explicit MediaBuffer(size_t size);
-
-    explicit MediaBuffer(const sp<ABuffer> &buffer);
-
-    MediaBuffer(const sp<IMemory> &mem) :
-        MediaBuffer((uint8_t *)mem->pointer() + sizeof(SharedControl), mem->size()) {
-        // delegate and override mMemory
-        mMemory = mem;
-    }
-
-    // If MediaBufferGroup is set, decrement the local reference count;
-    // if the local reference count drops to 0, return the buffer to the
-    // associated MediaBufferGroup.
-    //
-    // If no MediaBufferGroup is set, the local reference count must be zero
-    // when called, whereupon the MediaBuffer is deleted.
-    virtual void release();
-
-    // Increments the local reference count.
-    // Use only when MediaBufferGroup is set.
-    virtual void add_ref();
-
-    virtual void *data() const;
-    virtual size_t size() const;
-
-    virtual size_t range_offset() const;
-    virtual size_t range_length() const;
-
-    virtual void set_range(size_t offset, size_t length);
-
-    MetaDataBase& meta_data();
-
-    // Clears meta data and resets the range to the full extent.
-    virtual void reset();
-
-    virtual void setObserver(MediaBufferObserver *group);
-
-    // Returns a clone of this MediaBuffer increasing its reference count.
-    // The clone references the same data but has its own range and
-    // MetaData.
-    virtual MediaBufferBase *clone();
-
-    // sum of localRefcount() and remoteRefcount()
-    virtual int refcount() const {
-        return localRefcount() + remoteRefcount();
-    }
-
-    virtual int localRefcount() const {
-        return mRefCount;
-    }
-
-    virtual int remoteRefcount() const {
-        if (mMemory.get() == nullptr || mMemory->pointer() == nullptr) return 0;
-        int32_t remoteRefcount =
-                reinterpret_cast<SharedControl *>(mMemory->pointer())->getRemoteRefcount();
-        // Sanity check so that remoteRefCount() is non-negative.
-        return remoteRefcount >= 0 ? remoteRefcount : 0; // do not allow corrupted data.
-    }
-
-    // returns old value
-    int addRemoteRefcount(int32_t value) {
-        if (mMemory.get() == nullptr || mMemory->pointer() == nullptr) return 0;
-        return reinterpret_cast<SharedControl *>(mMemory->pointer())->addRemoteRefcount(value);
-    }
-
-    bool isDeadObject() const {
-        return isDeadObject(mMemory);
-    }
-
-    static bool isDeadObject(const sp<IMemory> &memory) {
-        if (memory.get() == nullptr || memory->pointer() == nullptr) return false;
-        return reinterpret_cast<SharedControl *>(memory->pointer())->isDeadObject();
-    }
-
-    // Sticky on enabling of shared memory MediaBuffers. By default we don't use
-    // shared memory for MediaBuffers, but we enable this for those processes
-    // that export MediaBuffers.
-    static void useSharedMemory() {
-        std::atomic_store_explicit(
-                &mUseSharedMemory, (int_least32_t)1, std::memory_order_seq_cst);
-    }
-
-protected:
-    // true if MediaBuffer is observed (part of a MediaBufferGroup).
-    inline bool isObserved() const {
-        return mObserver != nullptr;
-    }
-
-    virtual ~MediaBuffer();
-
-    sp<IMemory> mMemory;
-
-private:
-    friend class MediaBufferGroup;
-    friend class OMXDecoder;
-    friend class BnMediaSource;
-    friend class BpMediaSource;
-
-    // For use by OMXDecoder, reference count must be 1, drop reference
-    // count to 0 without signalling the observer.
-    void claim();
-
-    MediaBufferObserver *mObserver;
-    int mRefCount;
-
-    void *mData;
-    size_t mSize, mRangeOffset, mRangeLength;
-    sp<ABuffer> mBuffer;
-
-    bool mOwnsData;
-
-    MetaDataBase* mMetaData;
-
-    MediaBuffer *mOriginal;
-
-    static std::atomic_int_least32_t mUseSharedMemory;
-
-    MediaBuffer(const MediaBuffer &);
-    MediaBuffer &operator=(const MediaBuffer &);
-
-    // SharedControl block at the start of IMemory.
-    struct SharedControl {
-        enum {
-            FLAG_DEAD_OBJECT = (1 << 0),
-        };
-
-        // returns old value
-        inline int32_t addRemoteRefcount(int32_t value) {
-            return std::atomic_fetch_add_explicit(
-                    &mRemoteRefcount, (int_least32_t)value, std::memory_order_seq_cst);
-        }
-
-        inline int32_t getRemoteRefcount() const {
-            return std::atomic_load_explicit(&mRemoteRefcount, std::memory_order_seq_cst);
-        }
-
-        inline void setRemoteRefcount(int32_t value) {
-            std::atomic_store_explicit(
-                    &mRemoteRefcount, (int_least32_t)value, std::memory_order_seq_cst);
-        }
-
-        inline bool isDeadObject() const {
-            return (std::atomic_load_explicit(
-                    &mFlags, std::memory_order_seq_cst) & FLAG_DEAD_OBJECT) != 0;
-        }
-
-        inline void setDeadObject() {
-            (void)std::atomic_fetch_or_explicit(
-                    &mFlags, (int_least32_t)FLAG_DEAD_OBJECT, std::memory_order_seq_cst);
-        }
-
-        inline void clear() {
-            std::atomic_store_explicit(
-                    &mFlags, (int_least32_t)0, std::memory_order_seq_cst);
-            std::atomic_store_explicit(
-                    &mRemoteRefcount, (int_least32_t)0, std::memory_order_seq_cst);
-        }
-
-    private:
-        // Caution: atomic_int_fast32_t is 64 bits on LP64.
-        std::atomic_int_least32_t mFlags;
-        std::atomic_int_least32_t mRemoteRefcount;
-        int32_t unused[6] __attribute__((__unused__)); // additional buffer space
-    };
-
-    inline SharedControl *getSharedControl() const {
-         return reinterpret_cast<SharedControl *>(mMemory->pointer());
-     }
-};
-
-}  // namespace android
-
-#endif  // MEDIA_BUFFER_H_
diff --git a/media/libmediaextractor/include/media/stagefright/MediaBufferBase.h b/media/libmediaextractor/include/media/stagefright/MediaBufferBase.h
deleted file mode 100644
index 6c8d94a..0000000
--- a/media/libmediaextractor/include/media/stagefright/MediaBufferBase.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MEDIA_BUFFER_BASE_H_
-
-#define MEDIA_BUFFER_BASE_H_
-
-namespace android {
-
-class MediaBufferBase;
-class MetaDataBase;
-
-class MediaBufferObserver {
-public:
-    MediaBufferObserver() {}
-    virtual ~MediaBufferObserver() {}
-
-    virtual void signalBufferReturned(MediaBufferBase *buffer) = 0;
-
-private:
-    MediaBufferObserver(const MediaBufferObserver &);
-    MediaBufferObserver &operator=(const MediaBufferObserver &);
-};
-
-class MediaBufferBase {
-public:
-    static MediaBufferBase *Create(size_t size);
-
-    // If MediaBufferGroup is set, decrement the local reference count;
-    // if the local reference count drops to 0, return the buffer to the
-    // associated MediaBufferGroup.
-    //
-    // If no MediaBufferGroup is set, the local reference count must be zero
-    // when called, whereupon the MediaBuffer is deleted.
-    virtual void release() = 0;
-
-    // Increments the local reference count.
-    // Use only when MediaBufferGroup is set.
-    virtual void add_ref() = 0;
-
-    virtual void *data() const = 0;
-    virtual size_t size() const = 0;
-
-    virtual size_t range_offset() const = 0;
-    virtual size_t range_length() const = 0;
-
-    virtual void set_range(size_t offset, size_t length) = 0;
-
-    virtual MetaDataBase& meta_data() = 0;
-
-    // Clears meta data and resets the range to the full extent.
-    virtual void reset() = 0;
-
-    virtual void setObserver(MediaBufferObserver *group) = 0;
-
-    // Returns a clone of this MediaBufferBase increasing its reference
-    // count. The clone references the same data but has its own range and
-    // MetaData.
-    virtual MediaBufferBase *clone() = 0;
-
-    virtual int refcount() const = 0;
-
-    virtual int localRefcount() const = 0;
-    virtual int remoteRefcount() const = 0;
-
-    virtual ~MediaBufferBase() {};
-};
-
-}  // namespace android
-
-#endif  // MEDIA_BUFFER_BASE_H_
diff --git a/media/libmediaextractor/include/media/stagefright/MediaBufferGroup.h b/media/libmediaextractor/include/media/stagefright/MediaBufferGroup.h
deleted file mode 100644
index 75d5df7..0000000
--- a/media/libmediaextractor/include/media/stagefright/MediaBufferGroup.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MEDIA_BUFFER_GROUP_H_
-
-#define MEDIA_BUFFER_GROUP_H_
-
-#include <list>
-
-#include <media/stagefright/MediaBufferBase.h>
-#include <utils/Errors.h>
-#include <utils/threads.h>
-
-namespace android {
-
-class MediaBufferBase;
-
-class MediaBufferGroup : public MediaBufferObserver {
-public:
-    MediaBufferGroup(size_t growthLimit = 0);
-
-    // create a media buffer group with preallocated buffers
-    MediaBufferGroup(size_t buffers, size_t buffer_size, size_t growthLimit = 0);
-
-    ~MediaBufferGroup();
-
-    void add_buffer(MediaBufferBase *buffer);
-
-    bool has_buffers();
-
-    // If nonBlocking is false, it blocks until a buffer is available and
-    // passes it to the caller in *buffer, while returning OK.
-    // The returned buffer will have a reference count of 1.
-    // If nonBlocking is true and a buffer is not immediately available,
-    // buffer is set to NULL and it returns WOULD_BLOCK.
-    // If requestedSize is 0, any free MediaBuffer will be returned.
-    // If requestedSize is > 0, the returned MediaBuffer should have buffer
-    // size of at least requstedSize.
-    status_t acquire_buffer(
-            MediaBufferBase **buffer, bool nonBlocking = false, size_t requestedSize = 0);
-
-    size_t buffers() const;
-
-    // If buffer is nullptr, have acquire_buffer() check for remote release.
-    virtual void signalBufferReturned(MediaBufferBase *buffer);
-
-private:
-    struct InternalData;
-    InternalData *mInternal;
-
-    MediaBufferGroup(const MediaBufferGroup &);
-    MediaBufferGroup &operator=(const MediaBufferGroup &);
-};
-
-}  // namespace android
-
-#endif  // MEDIA_BUFFER_GROUP_H_
diff --git a/media/libmediaextractor/include/media/stagefright/MetaDataBase.h b/media/libmediaextractor/include/media/stagefright/MetaDataBase.h
deleted file mode 100644
index dfe34e8..0000000
--- a/media/libmediaextractor/include/media/stagefright/MetaDataBase.h
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef META_DATA_BASE_H_
-
-#define META_DATA_BASE_H_
-
-#include <sys/types.h>
-
-#include <stdint.h>
-
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-
-namespace android {
-
-// The following keys map to int32_t data unless indicated otherwise.
-enum {
-    kKeyMIMEType          = 'mime',  // cstring
-    kKeyWidth             = 'widt',  // int32_t, image pixel
-    kKeyHeight            = 'heig',  // int32_t, image pixel
-    kKeyDisplayWidth      = 'dWid',  // int32_t, display/presentation
-    kKeyDisplayHeight     = 'dHgt',  // int32_t, display/presentation
-    kKeySARWidth          = 'sarW',  // int32_t, sampleAspectRatio width
-    kKeySARHeight         = 'sarH',  // int32_t, sampleAspectRatio height
-    kKeyThumbnailWidth    = 'thbW',  // int32_t, thumbnail width
-    kKeyThumbnailHeight   = 'thbH',  // int32_t, thumbnail height
-
-    // a rectangle, if absent assumed to be (0, 0, width - 1, height - 1)
-    kKeyCropRect          = 'crop',
-
-    kKeyRotation          = 'rotA',  // int32_t (angle in degrees)
-    kKeyIFramesInterval   = 'ifiv',  // int32_t
-    kKeyStride            = 'strd',  // int32_t
-    kKeySliceHeight       = 'slht',  // int32_t
-    kKeyChannelCount      = '#chn',  // int32_t
-    kKeyChannelMask       = 'chnm',  // int32_t
-    kKeySampleRate        = 'srte',  // int32_t (audio sampling rate Hz)
-    kKeyPcmEncoding       = 'PCMe',  // int32_t (audio encoding enum)
-    kKeyFrameRate         = 'frmR',  // int32_t (video frame rate fps)
-    kKeyBitRate           = 'brte',  // int32_t (bps)
-    kKeyMaxBitRate        = 'mxBr',  // int32_t (bps)
-    kKeyStreamHeader      = 'stHd',  // raw data
-    kKeyESDS              = 'esds',  // raw data
-    kKeyAACProfile        = 'aacp',  // int32_t
-    kKeyAVCC              = 'avcc',  // raw data
-    kKeyHVCC              = 'hvcc',  // raw data
-    kKeyThumbnailHVCC     = 'thvc',  // raw data
-    kKeyD263              = 'd263',  // raw data
-    kKeyVorbisInfo        = 'vinf',  // raw data
-    kKeyVorbisBooks       = 'vboo',  // raw data
-    kKeyOpusHeader        = 'ohdr',  // raw data
-    kKeyOpusCodecDelay    = 'ocod',  // uint64_t (codec delay in ns)
-    kKeyOpusSeekPreRoll   = 'ospr',  // uint64_t (seek preroll in ns)
-    kKeyFlacMetadata      = 'flMd',  // raw data
-    kKeyVp9CodecPrivate   = 'vp9p',  // raw data (vp9 csd information)
-    kKeyWantsNALFragments = 'NALf',
-    kKeyIsSyncFrame       = 'sync',  // int32_t (bool)
-    kKeyIsCodecConfig     = 'conf',  // int32_t (bool)
-    kKeyIsMuxerData       = 'muxd',  // int32_t (bool)
-    kKeyTime              = 'time',  // int64_t (usecs)
-    kKeyDecodingTime      = 'decT',  // int64_t (decoding timestamp in usecs)
-    kKeyNTPTime           = 'ntpT',  // uint64_t (ntp-timestamp)
-    kKeyTargetTime        = 'tarT',  // int64_t (usecs)
-    kKeyDriftTime         = 'dftT',  // int64_t (usecs)
-    kKeyAnchorTime        = 'ancT',  // int64_t (usecs)
-    kKeyDuration          = 'dura',  // int64_t (usecs)
-    kKeyPixelFormat       = 'pixf',  // int32_t
-    kKeyColorFormat       = 'colf',  // int32_t
-    kKeyColorSpace        = 'cols',  // int32_t
-    kKeyPlatformPrivate   = 'priv',  // pointer
-    kKeyDecoderComponent  = 'decC',  // cstring
-    kKeyBufferID          = 'bfID',
-    kKeyMaxInputSize      = 'inpS',
-    kKeyMaxWidth          = 'maxW',
-    kKeyMaxHeight         = 'maxH',
-    kKeyThumbnailTime     = 'thbT',  // int64_t (usecs)
-    kKeyTrackID           = 'trID',
-    kKeyIsDRM             = 'idrm',  // int32_t (bool)
-    kKeyEncoderDelay      = 'encd',  // int32_t (frames)
-    kKeyEncoderPadding    = 'encp',  // int32_t (frames)
-
-    kKeyAlbum             = 'albu',  // cstring
-    kKeyArtist            = 'arti',  // cstring
-    kKeyAlbumArtist       = 'aart',  // cstring
-    kKeyComposer          = 'comp',  // cstring
-    kKeyGenre             = 'genr',  // cstring
-    kKeyTitle             = 'titl',  // cstring
-    kKeyYear              = 'year',  // cstring
-    kKeyAlbumArt          = 'albA',  // compressed image data
-    kKeyAlbumArtMIME      = 'alAM',  // cstring
-    kKeyAuthor            = 'auth',  // cstring
-    kKeyCDTrackNumber     = 'cdtr',  // cstring
-    kKeyDiscNumber        = 'dnum',  // cstring
-    kKeyDate              = 'date',  // cstring
-    kKeyWriter            = 'writ',  // cstring
-    kKeyCompilation       = 'cpil',  // cstring
-    kKeyLocation          = 'loc ',  // cstring
-    kKeyTimeScale         = 'tmsl',  // int32_t
-    kKeyCaptureFramerate  = 'capF',  // float (capture fps)
-
-    // video profile and level
-    kKeyVideoProfile      = 'vprf',  // int32_t
-    kKeyVideoLevel        = 'vlev',  // int32_t
-
-    // Set this key to enable authoring files in 64-bit offset
-    kKey64BitFileOffset   = 'fobt',  // int32_t (bool)
-    kKey2ByteNalLength    = '2NAL',  // int32_t (bool)
-
-    // Identify the file output format for authoring
-    // Please see <media/mediarecorder.h> for the supported
-    // file output formats.
-    kKeyFileType          = 'ftyp',  // int32_t
-
-    // Track authoring progress status
-    // kKeyTrackTimeStatus is used to track progress in elapsed time
-    kKeyTrackTimeStatus   = 'tktm',  // int64_t
-
-    kKeyRealTimeRecording = 'rtrc',  // bool (int32_t)
-    kKeyNumBuffers        = 'nbbf',  // int32_t
-
-    // Ogg files can be tagged to be automatically looping...
-    kKeyAutoLoop          = 'autL',  // bool (int32_t)
-
-    kKeyValidSamples      = 'valD',  // int32_t
-
-    kKeyIsUnreadable      = 'unre',  // bool (int32_t)
-
-    // An indication that a video buffer has been rendered.
-    kKeyRendered          = 'rend',  // bool (int32_t)
-
-    // The language code for this media
-    kKeyMediaLanguage     = 'lang',  // cstring
-
-    // To store the timed text format data
-    kKeyTextFormatData    = 'text',  // raw data
-
-    kKeyRequiresSecureBuffers = 'secu',  // bool (int32_t)
-
-    kKeyIsADTS            = 'adts',  // bool (int32_t)
-    kKeyAACAOT            = 'aaot',  // int32_t
-
-    // If a MediaBuffer's data represents (at least partially) encrypted
-    // data, the following fields aid in decryption.
-    // The data can be thought of as pairs of plain and encrypted data
-    // fragments, i.e. plain and encrypted data alternate.
-    // The first fragment is by convention plain data (if that's not the
-    // case, simply specify plain fragment size of 0).
-    // kKeyEncryptedSizes and kKeyPlainSizes each map to an array of
-    // size_t values. The sum total of all size_t values of both arrays
-    // must equal the amount of data (i.e. MediaBuffer's range_length()).
-    // If both arrays are present, they must be of the same size.
-    // If only encrypted sizes are present it is assumed that all
-    // plain sizes are 0, i.e. all fragments are encrypted.
-    // To programmatically set these array, use the MetaDataBase::setData API, i.e.
-    // const size_t encSizes[];
-    // meta->setData(
-    //  kKeyEncryptedSizes, 0 /* type */, encSizes, sizeof(encSizes));
-    // A plain sizes array by itself makes no sense.
-    kKeyEncryptedSizes    = 'encr',  // size_t[]
-    kKeyPlainSizes        = 'plai',  // size_t[]
-    kKeyCryptoKey         = 'cryK',  // uint8_t[16]
-    kKeyCryptoIV          = 'cryI',  // uint8_t[16]
-    kKeyCryptoMode        = 'cryM',  // int32_t
-
-    kKeyCryptoDefaultIVSize = 'cryS',  // int32_t
-
-    kKeyPssh              = 'pssh',  // raw data
-    kKeyCASystemID        = 'caid',  // int32_t
-    kKeyCASessionID       = 'seid',  // raw data
-
-    kKeyEncryptedByteBlock = 'cblk',  // uint8_t
-    kKeySkipByteBlock     = 'sblk',  // uint8_t
-
-    // Please see MediaFormat.KEY_IS_AUTOSELECT.
-    kKeyTrackIsAutoselect = 'auto', // bool (int32_t)
-    // Please see MediaFormat.KEY_IS_DEFAULT.
-    kKeyTrackIsDefault    = 'dflt', // bool (int32_t)
-    // Similar to MediaFormat.KEY_IS_FORCED_SUBTITLE but pertains to av tracks as well.
-    kKeyTrackIsForced     = 'frcd', // bool (int32_t)
-
-    // H264 supplemental enhancement information offsets/sizes
-    kKeySEI               = 'sei ', // raw data
-
-    // MPEG user data offsets
-    kKeyMpegUserData      = 'mpud', // size_t[]
-
-    // Size of NALU length in mkv/mp4
-    kKeyNalLengthSize     = 'nals', // int32_t
-
-    // HDR related
-    kKeyHdrStaticInfo    = 'hdrS', // HDRStaticInfo
-
-    // color aspects
-    kKeyColorRange       = 'cRng', // int32_t, color range, value defined by ColorAspects.Range
-    kKeyColorPrimaries   = 'cPrm', // int32_t,
-                                   // color Primaries, value defined by ColorAspects.Primaries
-    kKeyTransferFunction = 'tFun', // int32_t,
-                                   // transfer Function, value defined by ColorAspects.Transfer.
-    kKeyColorMatrix      = 'cMtx', // int32_t,
-                                   // color Matrix, value defined by ColorAspects.MatrixCoeffs.
-    kKeyTemporalLayerId  = 'iLyr', // int32_t, temporal layer-id. 0-based (0 => base layer)
-    kKeyTemporalLayerCount = 'cLyr', // int32_t, number of temporal layers encoded
-
-    kKeyTileWidth        = 'tilW', // int32_t, HEIF tile width
-    kKeyTileHeight       = 'tilH', // int32_t, HEIF tile height
-    kKeyGridRows         = 'grdR', // int32_t, HEIF grid rows
-    kKeyGridCols         = 'grdC', // int32_t, HEIF grid columns
-    kKeyIccProfile       = 'prof', // raw data, ICC profile data
-    kKeyIsPrimaryImage   = 'prim', // bool (int32_t), image track is the primary image
-    kKeyFrameCount       = 'nfrm', // int32_t, total number of frame in video track
-    kKeyExifOffset       = 'exof', // int64_t, Exif data offset
-    kKeyExifSize         = 'exsz', // int64_t, Exif data size
-    kKeyIsExif           = 'exif', // bool (int32_t) buffer contains exif data block
-};
-
-enum {
-    kTypeESDS        = 'esds',
-    kTypeAVCC        = 'avcc',
-    kTypeHVCC        = 'hvcc',
-    kTypeD263        = 'd263',
-};
-
-enum {
-    kCryptoModeUnencrypted = 0,
-    kCryptoModeAesCtr      = 1,
-    kCryptoModeAesCbc      = 2,
-};
-
-class Parcel;
-
-class MetaDataBase {
-public:
-    MetaDataBase();
-    MetaDataBase(const MetaDataBase &from);
-    MetaDataBase& operator = (const MetaDataBase &);
-
-    virtual ~MetaDataBase();
-
-    enum Type {
-        TYPE_NONE     = 'none',
-        TYPE_C_STRING = 'cstr',
-        TYPE_INT32    = 'in32',
-        TYPE_INT64    = 'in64',
-        TYPE_FLOAT    = 'floa',
-        TYPE_POINTER  = 'ptr ',
-        TYPE_RECT     = 'rect',
-    };
-
-    void clear();
-    bool remove(uint32_t key);
-
-    bool setCString(uint32_t key, const char *value);
-    bool setInt32(uint32_t key, int32_t value);
-    bool setInt64(uint32_t key, int64_t value);
-    bool setFloat(uint32_t key, float value);
-    bool setPointer(uint32_t key, void *value);
-
-    bool setRect(
-            uint32_t key,
-            int32_t left, int32_t top,
-            int32_t right, int32_t bottom);
-
-    bool findCString(uint32_t key, const char **value) const;
-    bool findInt32(uint32_t key, int32_t *value) const;
-    bool findInt64(uint32_t key, int64_t *value) const;
-    bool findFloat(uint32_t key, float *value) const;
-    bool findPointer(uint32_t key, void **value) const;
-
-    bool findRect(
-            uint32_t key,
-            int32_t *left, int32_t *top,
-            int32_t *right, int32_t *bottom) const;
-
-    bool setData(uint32_t key, uint32_t type, const void *data, size_t size);
-
-    bool findData(uint32_t key, uint32_t *type,
-                  const void **data, size_t *size) const;
-
-    bool hasData(uint32_t key) const;
-
-    String8 toString() const;
-    void dumpToLog() const;
-
-private:
-    friend class BpMediaSource;
-    friend class BnMediaSource;
-    friend class BnMediaExtractor;
-    friend class MetaData;
-
-    struct typed_data;
-    struct Rect;
-    struct MetaDataInternal;
-    MetaDataInternal *mInternalData;
-    status_t writeToParcel(Parcel &parcel);
-    status_t updateFromParcel(const Parcel &parcel);
-};
-
-}  // namespace android
-
-#endif  // META_DATA_H_
diff --git a/media/libmediametrics/Android.bp b/media/libmediametrics/Android.bp
index 07e124b..15ea578 100644
--- a/media/libmediametrics/Android.bp
+++ b/media/libmediametrics/Android.bp
@@ -1,20 +1,17 @@
-// TODO: change it back to cc_library_shared when there is a way to
-// expose media metrics as stable API.
-cc_library {
+cc_library_shared {
     name: "libmediametrics",
 
     srcs: [
         "IMediaAnalyticsService.cpp",
         "MediaAnalyticsItem.cpp",
+        "MediaMetrics.cpp",
     ],
 
     shared_libs: [
-        "liblog",
-        "libcutils",
-        "libutils",
         "libbinder",
-        "libstagefright_foundation",
-        "libbase",
+        "libcutils",
+        "liblog",
+        "libutils",
     ],
 
     export_include_dirs: ["include"],
@@ -31,8 +28,15 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
+    },
+
+    // enumerate stable entry points, for apex use
+    stubs: {
+        symbol_file: "libmediametrics.map.txt",
+        versions: [
+            "1" ,
+        ]
     },
 }
+
+
diff --git a/media/libmediametrics/IMediaAnalyticsService.cpp b/media/libmediametrics/IMediaAnalyticsService.cpp
index 28a7746..9114927 100644
--- a/media/libmediametrics/IMediaAnalyticsService.cpp
+++ b/media/libmediametrics/IMediaAnalyticsService.cpp
@@ -142,7 +142,7 @@
             CHECK_INTERFACE(IMediaAnalyticsService, data, reply);
 
             bool forcenew;
-            MediaAnalyticsItem *item = new MediaAnalyticsItem;
+            MediaAnalyticsItem *item = MediaAnalyticsItem::create();
 
             data.readBool(&forcenew);
             item->readFromParcel(data);
diff --git a/media/libmediametrics/MediaAnalyticsItem.cpp b/media/libmediametrics/MediaAnalyticsItem.cpp
index 135c9b6..02c23b1 100644
--- a/media/libmediametrics/MediaAnalyticsItem.cpp
+++ b/media/libmediametrics/MediaAnalyticsItem.cpp
@@ -52,6 +52,17 @@
 const char * const MediaAnalyticsItem::EnabledPropertyPersist  = "persist.media.metrics.enabled";
 const int MediaAnalyticsItem::EnabledProperty_default  = 1;
 
+// So caller doesn't need to know size of allocated space
+MediaAnalyticsItem *MediaAnalyticsItem::create()
+{
+    return MediaAnalyticsItem::create(kKeyNone);
+}
+
+MediaAnalyticsItem *MediaAnalyticsItem::create(MediaAnalyticsItem::Key key)
+{
+    MediaAnalyticsItem *item = new MediaAnalyticsItem(key);
+    return item;
+}
 
 // access functions for the class
 MediaAnalyticsItem::MediaAnalyticsItem()
@@ -478,7 +489,7 @@
 // caller responsible for the returned string
 bool MediaAnalyticsItem::getCString(MediaAnalyticsItem::Attr name, char **value) {
     Prop *prop = findProp(name);
-    if (prop == NULL || prop->mType != kTypeDouble) {
+    if (prop == NULL || prop->mType != kTypeCString) {
         return false;
     }
     if (value != NULL) {
@@ -487,6 +498,18 @@
     return true;
 }
 
+bool MediaAnalyticsItem::getString(MediaAnalyticsItem::Attr name, std::string *value) {
+    Prop *prop = findProp(name);
+    if (prop == NULL || prop->mType != kTypeCString) {
+        return false;
+    }
+    if (value != NULL) {
+        // std::string makes a copy for us
+        *value = prop->u.CStringValue;
+    }
+    return true;
+}
+
 // remove indicated keys and their values
 // return value is # keys removed
 int32_t MediaAnalyticsItem::filter(int n, MediaAnalyticsItem::Attr attrs[]) {
@@ -630,6 +653,19 @@
 //
 
 int32_t MediaAnalyticsItem::readFromParcel(const Parcel& data) {
+    int32_t version = data.readInt32();
+
+    switch(version) {
+        case 0:
+          return readFromParcel0(data);
+          break;
+        default:
+          ALOGE("Unsupported MediaAnalyticsItem Parcel version: %d", version);
+          return -1;
+    }
+}
+
+int32_t MediaAnalyticsItem::readFromParcel0(const Parcel& data) {
     // into 'this' object
     // .. we make a copy of the string to put away.
     mKey = data.readCString();
@@ -679,8 +715,23 @@
 }
 
 int32_t MediaAnalyticsItem::writeToParcel(Parcel *data) {
+
     if (data == NULL) return -1;
 
+    int32_t version = 0;
+    data->writeInt32(version);
+
+    switch(version) {
+        case 0:
+          return writeToParcel0(data);
+          break;
+        default:
+          ALOGE("Unsupported MediaAnalyticsItem Parcel version: %d", version);
+          return -1;
+    }
+}
+
+int32_t MediaAnalyticsItem::writeToParcel0(Parcel *data) {
 
     data->writeCString(mKey.c_str());
     data->writeInt32(mPid);
@@ -725,6 +776,14 @@
     return 0;
 }
 
+const char *MediaAnalyticsItem::toCString() {
+   return toCString(PROTO_LAST);
+}
+
+const char * MediaAnalyticsItem::toCString(int version) {
+    std::string val = toString(version);
+    return strdup(val.c_str());
+}
 
 std::string MediaAnalyticsItem::toString() {
    return toString(PROTO_LAST);
@@ -855,8 +914,6 @@
         }
         return true;
     } else {
-        std::string p = this->toString();
-        ALOGW("Unable to record: %s [forcenew=%d]", p.c_str(), forcenew);
         return false;
     }
 }
@@ -1014,5 +1071,170 @@
     return true;
 }
 
+// a byte array; contents are
+// overall length (uint32) including the length field itself
+// encoding version (uint32)
+// count of properties (uint32)
+// N copies of:
+//     property name as length(int16), bytes
+//         the bytes WILL include the null terminator of the name
+//     type (uint8 -- 1 byte)
+//     size of value field (int16 -- 2 bytes)
+//     value (size based on type)
+//       int32, int64, double -- little endian 4/8/8 bytes respectively
+//       cstring -- N bytes of value [WITH terminator]
+
+enum { kInt32 = 0, kInt64, kDouble, kRate, kCString};
+
+bool MediaAnalyticsItem::dumpAttributes(char **pbuffer, size_t *plength) {
+
+    char *build = NULL;
+
+    if (pbuffer == NULL || plength == NULL)
+        return false;
+
+    // consistency for the caller, who owns whatever comes back in this pointer.
+    *pbuffer = NULL;
+
+    // first, let's calculate sizes
+    int32_t goal = 0;
+    int32_t version = 0;
+
+    goal += sizeof(uint32_t);   // overall length, including the length field
+    goal += sizeof(uint32_t);   // encoding version
+    goal += sizeof(uint32_t);   // # properties
+
+    int32_t count = mPropCount;
+    for (int i = 0 ; i < count; i++ ) {
+        Prop *prop = &mProps[i];
+        goal += sizeof(uint16_t);           // name length
+        goal += strlen(prop->mName) + 1;    // string + null
+        goal += sizeof(uint8_t);            // type
+        goal += sizeof(uint16_t);           // size of value
+        switch (prop->mType) {
+            case MediaAnalyticsItem::kTypeInt32:
+                    goal += sizeof(uint32_t);
+                    break;
+            case MediaAnalyticsItem::kTypeInt64:
+                    goal += sizeof(uint64_t);
+                    break;
+            case MediaAnalyticsItem::kTypeDouble:
+                    goal += sizeof(double);
+                    break;
+            case MediaAnalyticsItem::kTypeRate:
+                    goal += 2 * sizeof(uint64_t);
+                    break;
+            case MediaAnalyticsItem::kTypeCString:
+                    // length + actual string + null
+                    goal += strlen(prop->u.CStringValue) + 1;
+                    break;
+            default:
+                    ALOGE("found bad Prop type: %d, idx %d, name %s",
+                          prop->mType, i, prop->mName);
+                    return false;
+        }
+    }
+
+    // now that we have a size... let's allocate and fill
+    build = (char *)malloc(goal);
+    if (build == NULL)
+        return false;
+
+    memset(build, 0, goal);
+
+    char *filling = build;
+
+#define _INSERT(val, size) \
+    { memcpy(filling, &(val), (size)); filling += (size);}
+#define _INSERTSTRING(val, size) \
+    { memcpy(filling, (val), (size)); filling += (size);}
+
+    _INSERT(goal, sizeof(int32_t));
+    _INSERT(version, sizeof(int32_t));
+    _INSERT(count, sizeof(int32_t));
+
+    for (int i = 0 ; i < count; i++ ) {
+        Prop *prop = &mProps[i];
+        int16_t attrNameLen = strlen(prop->mName) + 1;
+        _INSERT(attrNameLen, sizeof(int16_t));
+        _INSERTSTRING(prop->mName, attrNameLen);    // termination included
+        int8_t elemtype;
+        int16_t elemsize;
+        switch (prop->mType) {
+            case MediaAnalyticsItem::kTypeInt32:
+                {
+                    elemtype = kInt32;
+                    _INSERT(elemtype, sizeof(int8_t));
+                    elemsize = sizeof(int32_t);
+                    _INSERT(elemsize, sizeof(int16_t));
+
+                    _INSERT(prop->u.int32Value, sizeof(int32_t));
+                    break;
+                }
+            case MediaAnalyticsItem::kTypeInt64:
+                {
+                    elemtype = kInt64;
+                    _INSERT(elemtype, sizeof(int8_t));
+                    elemsize = sizeof(int64_t);
+                    _INSERT(elemsize, sizeof(int16_t));
+
+                    _INSERT(prop->u.int64Value, sizeof(int64_t));
+                    break;
+                }
+            case MediaAnalyticsItem::kTypeDouble:
+                {
+                    elemtype = kDouble;
+                    _INSERT(elemtype, sizeof(int8_t));
+                    elemsize = sizeof(double);
+                    _INSERT(elemsize, sizeof(int16_t));
+
+                    _INSERT(prop->u.doubleValue, sizeof(double));
+                    break;
+                }
+            case MediaAnalyticsItem::kTypeRate:
+                {
+                    elemtype = kRate;
+                    _INSERT(elemtype, sizeof(int8_t));
+                    elemsize = 2 * sizeof(uint64_t);
+                    _INSERT(elemsize, sizeof(int16_t));
+
+                    _INSERT(prop->u.rate.count, sizeof(uint64_t));
+                    _INSERT(prop->u.rate.duration, sizeof(uint64_t));
+                    break;
+                }
+            case MediaAnalyticsItem::kTypeCString:
+                {
+                    elemtype = kCString;
+                    _INSERT(elemtype, sizeof(int8_t));
+                    elemsize = strlen(prop->u.CStringValue) + 1;
+                    _INSERT(elemsize, sizeof(int16_t));
+
+                    _INSERTSTRING(prop->u.CStringValue, elemsize);
+                    break;
+                }
+            default:
+                    // error if can't encode; warning if can't decode
+                    ALOGE("found bad Prop type: %d, idx %d, name %s",
+                          prop->mType, i, prop->mName);
+                    goto badness;
+        }
+    }
+
+    if (build + goal != filling) {
+        ALOGE("problems populating; wrote=%d planned=%d",
+              (int)(filling-build), goal);
+        goto badness;
+    }
+
+    *pbuffer = build;
+    *plength = goal;
+
+    return true;
+
+  badness:
+    free(build);
+    return false;
+}
+
 } // namespace android
 
diff --git a/media/libmediametrics/MediaMetrics.cpp b/media/libmediametrics/MediaMetrics.cpp
new file mode 100644
index 0000000..6109190
--- /dev/null
+++ b/media/libmediametrics/MediaMetrics.cpp
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "MediaMetrics"
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include <media/MediaAnalyticsItem.h>
+#include <media/MediaMetrics.h>
+
+//
+// provide a C-ish interface that is easier to stabilize than the existing C++
+// interface
+//
+// ALL functions returning a char * give responsibility for the allocated buffer
+// to the caller. The caller is responsible to call free() on that pointer.
+//
+
+// manage the overall record
+mediametrics_handle_t mediametrics_create(mediametricskey_t key) {
+    android::MediaAnalyticsItem *item = android::MediaAnalyticsItem::create(key);
+    return (mediametrics_handle_t) item;
+}
+
+void mediametrics_delete(mediametrics_handle_t handle) {
+    android::MediaAnalyticsItem *item = (android::MediaAnalyticsItem *) handle;
+    if (item == NULL) return;
+    delete item;
+}
+
+mediametricskey_t mediametrics_getKey(mediametrics_handle_t handle) {
+    android::MediaAnalyticsItem *item = (android::MediaAnalyticsItem *) handle;
+    if (item == NULL) return NULL;
+    return strdup(item->getKey().c_str());
+}
+
+// nuplayer, et al use it when acting as proxies
+void mediametrics_setUid(mediametrics_handle_t handle, uid_t uid) {
+    android::MediaAnalyticsItem *item = (android::MediaAnalyticsItem *) handle;
+    if (item != NULL) item->setUid(uid);
+}
+
+// set attributes
+//
+
+void mediametrics_setInt32(mediametrics_handle_t handle, attr_t attr,
+                                int32_t value) {
+    android::MediaAnalyticsItem *item = (android::MediaAnalyticsItem *) handle;
+    if (item != NULL) item->setInt32(attr, value);
+}
+
+void mediametrics_setInt64(mediametrics_handle_t handle, attr_t attr,
+                                int64_t value) {
+    android::MediaAnalyticsItem *item = (android::MediaAnalyticsItem *) handle;
+    if (item != NULL) item->setInt64(attr, value);
+}
+
+void mediametrics_setDouble(mediametrics_handle_t handle, attr_t attr,
+                                 double value) {
+    android::MediaAnalyticsItem *item = (android::MediaAnalyticsItem *) handle;
+    if (item != NULL) item->setDouble(attr, value);
+}
+
+void mediametrics_setRate(mediametrics_handle_t handle, attr_t attr,
+                               int64_t count, int64_t duration) {
+    android::MediaAnalyticsItem *item = (android::MediaAnalyticsItem *) handle;
+    if (item != NULL) item->setRate(attr, count, duration);
+}
+
+void mediametrics_setCString(mediametrics_handle_t handle, attr_t attr,
+                                 const char *value) {
+    android::MediaAnalyticsItem *item = (android::MediaAnalyticsItem *) handle;
+    if (item != NULL) item->setCString(attr, value);
+}
+
+// fused get/add/set; if attr wasn't there, it's a simple set.
+//
+
+void mediametrics_addInt32(mediametrics_handle_t handle, attr_t attr,
+                                int32_t value) {
+    android::MediaAnalyticsItem *item = (android::MediaAnalyticsItem *) handle;
+    if (item != NULL) item->addInt32(attr, value);
+}
+
+void mediametrics_addInt64(mediametrics_handle_t handle, attr_t attr,
+                                int64_t value) {
+    android::MediaAnalyticsItem *item = (android::MediaAnalyticsItem *) handle;
+    if (item != NULL) item->addInt64(attr, value);
+}
+
+void mediametrics_addDouble(mediametrics_handle_t handle, attr_t attr,
+                                 double value) {
+    android::MediaAnalyticsItem *item = (android::MediaAnalyticsItem *) handle;
+    if (item != NULL) item->addDouble(attr, value);
+}
+
+void mediametrics_addRate(mediametrics_handle_t handle, attr_t attr,
+                               int64_t count, int64_t duration) {
+    android::MediaAnalyticsItem *item = (android::MediaAnalyticsItem *) handle;
+    if (item != NULL) item->addRate(attr, count, duration);
+}
+
+// find & extract values
+// return indicates whether attr exists (and thus whether value filled in)
+// NULL parameter value suppresses storage of value.
+//
+
+bool mediametrics_getInt32(mediametrics_handle_t handle, attr_t attr,
+                                int32_t * value) {
+    android::MediaAnalyticsItem *item = (android::MediaAnalyticsItem *) handle;
+    if (item == NULL) return false;
+    return item->getInt32(attr, value);
+}
+
+bool mediametrics_getInt64(mediametrics_handle_t handle, attr_t attr,
+                                int64_t * value) {
+    android::MediaAnalyticsItem *item = (android::MediaAnalyticsItem *) handle;
+    if (item == NULL) return false;
+    return item->getInt64(attr, value);
+}
+
+bool mediametrics_getDouble(mediametrics_handle_t handle, attr_t attr,
+                                 double *value) {
+    android::MediaAnalyticsItem *item = (android::MediaAnalyticsItem *) handle;
+    if (item == NULL) return false;
+    return item->getDouble(attr, value);
+}
+
+bool mediametrics_getRate(mediametrics_handle_t handle, attr_t attr,
+                               int64_t * count, int64_t * duration, double *rate) {
+    android::MediaAnalyticsItem *item = (android::MediaAnalyticsItem *) handle;
+    if (item == NULL) return false;
+    return item->getRate(attr, count, duration, rate);
+}
+
+// NB: caller owns the string that comes back, is responsible for freeing it
+bool mediametrics_getCString(mediametrics_handle_t handle, attr_t attr,
+                                 char **value) {
+    android::MediaAnalyticsItem *item = (android::MediaAnalyticsItem *) handle;
+    if (item == NULL) return false;
+
+    return item->getCString(attr, value);
+}
+
+// to release strings returned via getCString()
+void mediametrics_freeCString(char *value) {
+    free(value);
+}
+
+bool mediametrics_selfRecord(mediametrics_handle_t handle) {
+    android::MediaAnalyticsItem *item = (android::MediaAnalyticsItem *) handle;
+    if (item == NULL) return false;
+    return item->selfrecord();
+}
+
+
+const char *mediametrics_readable(mediametrics_handle_t handle) {
+    android::MediaAnalyticsItem *item = (android::MediaAnalyticsItem *) handle;
+    if (item == NULL) return "";
+    return item->toCString();
+}
+
+int32_t mediametrics_count(mediametrics_handle_t handle) {
+    android::MediaAnalyticsItem *item = (android::MediaAnalyticsItem *) handle;
+    if (item == NULL) return 0;
+    return item->count();
+}
+
+bool mediametrics_isEnabled() {
+    // static, so doesn't need an instance
+    return android::MediaAnalyticsItem::isEnabled();
+}
+
+bool mediametrics_getAttributes(mediametrics_handle_t handle, char **buffer, size_t *length) {
+    android::MediaAnalyticsItem *item = (android::MediaAnalyticsItem *) handle;
+    if (item == NULL) return false;
+    return item->dumpAttributes(buffer, length);
+
+}
diff --git a/media/libmediametrics/include/MediaAnalyticsItem.h b/media/libmediametrics/include/MediaAnalyticsItem.h
index 263cde7..4a36f6a 100644
--- a/media/libmediametrics/include/MediaAnalyticsItem.h
+++ b/media/libmediametrics/include/MediaAnalyticsItem.h
@@ -17,9 +17,10 @@
 #ifndef ANDROID_MEDIA_MEDIAANALYTICSITEM_H
 #define ANDROID_MEDIA_MEDIAANALYTICSITEM_H
 
-#include <cutils/properties.h>
 #include <string>
 #include <sys/types.h>
+
+#include <cutils/properties.h>
 #include <utils/Errors.h>
 #include <utils/KeyedVector.h>
 #include <utils/RefBase.h>
@@ -81,12 +82,19 @@
             PROTO_LAST = PROTO_V1,
         };
 
+    private:
+        // use the ::create() method instead
+        MediaAnalyticsItem();
+        MediaAnalyticsItem(Key);
+        MediaAnalyticsItem(const MediaAnalyticsItem&);
+        MediaAnalyticsItem &operator=(const MediaAnalyticsItem&);
 
     public:
 
+        static MediaAnalyticsItem* create(Key key);
+        static MediaAnalyticsItem* create();
+
         // access functions for the class
-        MediaAnalyticsItem();
-        MediaAnalyticsItem(Key);
         ~MediaAnalyticsItem();
 
         // SessionID ties multiple submissions for same key together
@@ -134,6 +142,7 @@
         bool getRate(Attr, int64_t *count, int64_t *duration, double *rate);
         // Caller owns the returned string
         bool getCString(Attr, char **value);
+        bool getString(Attr, std::string *value);
 
         // parameter indicates whether to close any existing open
         // record with same key before establishing a new record
@@ -174,12 +183,22 @@
         int32_t writeToParcel(Parcel *);
         int32_t readFromParcel(const Parcel&);
 
+        // supports the stable interface
+        bool dumpAttributes(char **pbuffer, size_t *plength);
+
         std::string toString();
         std::string toString(int version);
+        const char *toCString();
+        const char *toCString(int version);
 
         // are we collecting analytics data
         static bool isEnabled();
 
+    private:
+        // handle Parcel version 0
+        int32_t writeToParcel0(Parcel *);
+        int32_t readFromParcel0(const Parcel&);
+
     protected:
 
         // merge fields from arg into this
diff --git a/media/libmediametrics/include/MediaMetrics.h b/media/libmediametrics/include/MediaMetrics.h
new file mode 100644
index 0000000..a4e1ed2
--- /dev/null
+++ b/media/libmediametrics/include/MediaMetrics.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_MEDIA_MEDIAMETRICS_H
+#define ANDROID_MEDIA_MEDIAMETRICS_H
+
+//
+// define a C interface to the media metrics functionality
+//
+// All functions that return a char * or const char * also give responsibility
+// for that string to the caller. The caller is responsible for calling free()
+// on that pointer when done using the value.
+
+__BEGIN_DECLS
+
+// internally re-cast to the behind-the-scenes C++ class instance
+typedef int64_t mediametrics_handle_t;
+typedef const char *mediametricskey_t;
+typedef const char *attr_t;
+
+mediametrics_handle_t mediametrics_create(mediametricskey_t key);
+void mediametrics_delete(mediametrics_handle_t handle);
+
+mediametricskey_t mediametrics_getKey(mediametrics_handle_t handle);
+
+
+// set
+void mediametrics_setInt32(mediametrics_handle_t handle, attr_t attr,
+                           int32_t value);
+void mediametrics_setInt64(mediametrics_handle_t handle, attr_t attr,
+                           int64_t value);
+void mediametrics_setDouble(mediametrics_handle_t handle, attr_t attr,
+                            double value);
+void mediametrics_setRate(mediametrics_handle_t handle, attr_t attr,
+                          int64_t count, int64_t duration);
+void mediametrics_setCString(mediametrics_handle_t handle, attr_t attr,
+                            const char * value);
+
+// fused get/add/set; if attr wasn't there, it's a simple set.
+// these do not provide atomicity or mutual exclusion, only simpler code sequences.
+void mediametrics_addInt32(mediametrics_handle_t handle, attr_t attr,
+                           int32_t value);
+void mediametrics_addInt64(mediametrics_handle_t handle, attr_t attr,
+                           int64_t value);
+void mediametrics_addDouble(mediametrics_handle_t handle, attr_t attr,
+                            double value);
+void mediametrics_addRate(mediametrics_handle_t handle, attr_t attr,
+                          int64_t count, int64_t duration);
+
+// find & extract values
+// return indicates whether attr exists (and thus whether value filled in)
+// NULL parameter value suppresses storage of value.
+bool mediametrics_getInt32(mediametrics_handle_t handle, attr_t attr,
+                           int32_t * value);
+bool mediametrics_getInt64(mediametrics_handle_t handle, attr_t attr,
+                           int64_t * value);
+bool mediametrics_getDouble(mediametrics_handle_t handle, attr_t attr,
+                            double *value);
+bool mediametrics_getRate(mediametrics_handle_t handle, attr_t attr,
+                          int64_t * count, int64_t * duration, double *rate);
+bool mediametrics_getCString(mediametrics_handle_t handle, attr_t attr,
+                            char **value);
+// to release strings returned via getCString()
+void mediametrics_freeCString(char *value);
+
+// # of attributes set within this record.
+int32_t mediametrics_count(mediametrics_handle_t handle);
+
+bool mediametrics_selfRecord(mediametrics_handle_t handle);
+
+const char *mediametrics_readable(mediametrics_handle_t handle);
+void mediametrics_setUid(mediametrics_handle_t handle, uid_t uid);
+bool mediametrics_isEnabled();
+
+// serialized copy of the attributes/values, mostly for upstream getMetrics() calls
+// caller owns the buffer allocated as part of this call.
+bool mediametrics_getAttributes(mediametrics_handle_t handle, char **buffer, size_t *length);
+
+__END_DECLS
+
+#endif
diff --git a/media/libmediametrics/libmediametrics.map.txt b/media/libmediametrics/libmediametrics.map.txt
new file mode 100644
index 0000000..c46281a
--- /dev/null
+++ b/media/libmediametrics/libmediametrics.map.txt
@@ -0,0 +1,29 @@
+LIBMEDIAMETRICS_1 {
+  global:
+    mediametrics_addDouble; # apex
+    mediametrics_addInt32; # apex
+    mediametrics_addInt64; # apex
+    mediametrics_addRate; # apex
+    mediametrics_count; # apex
+    mediametrics_create; # apex
+    mediametrics_delete; # apex
+    mediametrics_freeCString; # apex
+    mediametrics_getAttributes; # apex
+    mediametrics_getCString; # apex
+    mediametrics_getDouble; # apex
+    mediametrics_getInt32; # apex
+    mediametrics_getInt64; # apex
+    mediametrics_getKey; # apex
+    mediametrics_getRate; # apex
+    mediametrics_isEnabled; # apex
+    mediametrics_readable; # apex
+    mediametrics_selfRecord; # apex
+    mediametrics_setCString; # apex
+    mediametrics_setDouble; # apex
+    mediametrics_setInt32; # apex
+    mediametrics_setInt64; # apex
+    mediametrics_setRate; # apex
+    mediametrics_setUid; # apex
+  local:
+    *;
+};
diff --git a/media/libmediaplayer2/Android.bp b/media/libmediaplayer2/Android.bp
index 1fa8789..dca6bb6 100644
--- a/media/libmediaplayer2/Android.bp
+++ b/media/libmediaplayer2/Android.bp
@@ -4,11 +4,10 @@
     export_include_dirs: ["include"],
 }
 
-cc_library {
+cc_library_static {
     name: "libmediaplayer2",
 
     srcs: [
-        "JAudioTrack.cpp",
         "MediaPlayer2AudioOutput.cpp",
         "mediaplayer2.cpp",
     ],
@@ -17,31 +16,29 @@
         "libandroid_runtime",
         "libaudioclient",
         "libbinder",
+        "libbinder_ndk",
         "libcutils",
         "libgui",
         "liblog",
         "libmedia_omx",
-        "libmedia_player2_util",
-        "libmediaextractor",
-        "libstagefright_foundation",
         "libui",
         "libutils",
 
         "libcrypto",
-        "libmediadrm",
         "libmediametrics",
         "libmediandk",
+        "libmediandk_utils",
         "libmediautils",
         "libmemunreachable",
         "libnativewindow",
         "libpowermanager",
         "libstagefright_httplive",
-        "libstagefright_player2",
     ],
 
     export_shared_lib_headers: [
         "libaudioclient",
         "libbinder",
+        "libgui",
         "libmedia_omx",
     ],
 
@@ -49,11 +46,21 @@
         "media_plugin_headers",
     ],
 
+    include_dirs: [
+        "frameworks/base/core/jni",
+    ],
+
     static_libs: [
         "libmedia_helper",
+        "libmediaplayer2-protos",
+        "libmedia_player2_util",
+        "libprotobuf-cpp-lite",
+        "libstagefright_foundation_without_imemory",
         "libstagefright_nuplayer2",
+        "libstagefright_player2",
         "libstagefright_rtsp",
-        "libstagefright_timedtext",
+        "libstagefright_timedtext2",
+        "libmedia2_jni_core",
     ],
 
     export_include_dirs: [
@@ -72,8 +79,51 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 }
+
+cc_library {
+    name: "libmedia2_jni_core",
+
+    srcs: [
+        "JavaVMHelper.cpp",
+        "JAudioTrack.cpp",
+        "JMedia2HTTPService.cpp",
+        "JMedia2HTTPConnection.cpp",
+    ],
+
+    header_libs: [
+        "libbinder_headers",
+        "libnativehelper_header_only",
+    ],
+
+    shared_libs: [
+        "liblog",
+        "libutils",
+        "libdl",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/libmedia/include",
+        "frameworks/base/core/jni",
+    ],
+
+    export_include_dirs: [
+        "include",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wno-error=deprecated-declarations",
+        "-Wall",
+    ],
+
+    sanitize: {
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+        cfi: true,
+    },
+
+}
diff --git a/media/libmediaplayer2/JAudioTrack.cpp b/media/libmediaplayer2/JAudioTrack.cpp
index ac0cc57..fab6c64 100644
--- a/media/libmediaplayer2/JAudioTrack.cpp
+++ b/media/libmediaplayer2/JAudioTrack.cpp
@@ -21,27 +21,28 @@
 #include "mediaplayer2/JAudioTrack.h"
 
 #include <android_media_AudioErrors.h>
-#include <android_runtime/AndroidRuntime.h>
+#include <mediaplayer2/JavaVMHelper.h>
 
 namespace android {
 
 // TODO: Store Java class/methodID as a member variable in the class.
 // TODO: Add NULL && Exception checks after every JNI call.
 JAudioTrack::JAudioTrack(                             // < Usages of the arguments are below >
-        audio_stream_type_t streamType,               // AudioAudioAttributes
         uint32_t sampleRate,                          // AudioFormat && bufferSizeInBytes
         audio_format_t format,                        // AudioFormat && bufferSizeInBytes
         audio_channel_mask_t channelMask,             // AudioFormat && bufferSizeInBytes
         callback_t cbf,                               // Offload
         void* user,                                   // Offload
         size_t frameCount,                            // bufferSizeInBytes
-        audio_session_t sessionId,                    // AudioTrack
-        const audio_attributes_t* pAttributes,        // AudioAttributes
+        int32_t sessionId,                            // AudioTrack
+        const jobject attributes,                     // AudioAttributes
         float maxRequiredSpeed) {                     // bufferSizeInBytes
 
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
+
     jclass jAudioTrackCls = env->FindClass("android/media/AudioTrack");
-    mAudioTrackCls = (jclass) env->NewGlobalRef(jAudioTrackCls);
+    mAudioTrackCls = reinterpret_cast<jclass>(env->NewGlobalRef(jAudioTrackCls));
+    env->DeleteLocalRef(jAudioTrackCls);
 
     maxRequiredSpeed = std::min(std::max(maxRequiredSpeed, 1.0f), AUDIO_TIMESTRETCH_SPEED_MAX);
 
@@ -64,10 +65,19 @@
     jmethodID jBuilderCtor = env->GetMethodID(jBuilderCls, "<init>", "()V");
     jobject jBuilderObj = env->NewObject(jBuilderCls, jBuilderCtor);
 
-    jmethodID jSetAudioAttributes = env->GetMethodID(jBuilderCls, "setAudioAttributes",
-            "(Landroid/media/AudioAttributes;)Landroid/media/AudioTrack$Builder;");
-    jBuilderObj = env->CallObjectMethod(jBuilderObj, jSetAudioAttributes,
-            JAudioAttributes::createAudioAttributesObj(env, pAttributes, streamType));
+    {
+        sp<JObjectHolder> audioAttributesObj;
+        if (attributes != NULL) {
+            audioAttributesObj = new JObjectHolder(attributes);
+        } else {
+            audioAttributesObj = new JObjectHolder(
+                    JAudioAttributes::createAudioAttributesObj(env, NULL));
+        }
+        jmethodID jSetAudioAttributes = env->GetMethodID(jBuilderCls, "setAudioAttributes",
+                "(Landroid/media/AudioAttributes;)Landroid/media/AudioTrack$Builder;");
+        jBuilderObj = env->CallObjectMethod(jBuilderObj,
+                jSetAudioAttributes, audioAttributesObj->getJObject());
+    }
 
     jmethodID jSetAudioFormat = env->GetMethodID(jBuilderCls, "setAudioFormat",
             "(Landroid/media/AudioFormat;)Landroid/media/AudioTrack$Builder;");
@@ -92,6 +102,7 @@
         jBuilderObj = env->CallObjectMethod(jBuilderObj, jSetSessionId, sessionId);
     }
 
+    mFlags = AUDIO_OUTPUT_FLAG_NONE;
     if (cbf != NULL) {
         jmethodID jSetOffloadedPlayback = env->GetMethodID(jBuilderCls, "setOffloadedPlayback",
                 "(Z)Landroid/media/AudioTrack$Builder;");
@@ -100,7 +111,9 @@
     }
 
     jmethodID jBuild = env->GetMethodID(jBuilderCls, "build", "()Landroid/media/AudioTrack;");
-    mAudioTrackObj = env->CallObjectMethod(jBuilderObj, jBuild);
+    jobject jAudioTrackObj = env->CallObjectMethod(jBuilderObj, jBuild);
+    mAudioTrackObj = reinterpret_cast<jobject>(env->NewGlobalRef(jAudioTrackObj));
+    env->DeleteLocalRef(jBuilderObj);
 
     if (cbf != NULL) {
         // Set offload mode callback
@@ -116,19 +129,20 @@
 }
 
 JAudioTrack::~JAudioTrack() {
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
     env->DeleteGlobalRef(mAudioTrackCls);
+    env->DeleteGlobalRef(mAudioTrackObj);
 }
 
 size_t JAudioTrack::frameCount() {
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
     jmethodID jGetBufferSizeInFrames = env->GetMethodID(
             mAudioTrackCls, "getBufferSizeInFrames", "()I");
     return env->CallIntMethod(mAudioTrackObj, jGetBufferSizeInFrames);
 }
 
 size_t JAudioTrack::channelCount() {
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
     jmethodID jGetChannelCount = env->GetMethodID(mAudioTrackCls, "getChannelCount", "()I");
     return env->CallIntMethod(mAudioTrackObj, jGetChannelCount);
 }
@@ -143,7 +157,7 @@
         return BAD_VALUE;
     }
 
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
     jmethodID jGetPlaybackHeadPosition = env->GetMethodID(
             mAudioTrackCls, "getPlaybackHeadPosition", "()I");
     *position = env->CallIntMethod(mAudioTrackObj, jGetPlaybackHeadPosition);
@@ -151,21 +165,21 @@
     return NO_ERROR;
 }
 
-bool JAudioTrack::getTimestamp(AudioTimestamp& timestamp) {
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+status_t JAudioTrack::getTimestamp(AudioTimestamp& timestamp) {
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
 
     jclass jAudioTimeStampCls = env->FindClass("android/media/AudioTimestamp");
     jobject jAudioTimeStampObj = env->AllocObject(jAudioTimeStampCls);
 
-    jfieldID jFramePosition = env->GetFieldID(jAudioTimeStampCls, "framePosition", "L");
-    jfieldID jNanoTime = env->GetFieldID(jAudioTimeStampCls, "nanoTime", "L");
+    jfieldID jFramePosition = env->GetFieldID(jAudioTimeStampCls, "framePosition", "J");
+    jfieldID jNanoTime = env->GetFieldID(jAudioTimeStampCls, "nanoTime", "J");
 
     jmethodID jGetTimestamp = env->GetMethodID(mAudioTrackCls,
-            "getTimestamp", "(Landroid/media/AudioTimestamp)B");
+            "getTimestamp", "(Landroid/media/AudioTimestamp;)Z");
     bool success = env->CallBooleanMethod(mAudioTrackObj, jGetTimestamp, jAudioTimeStampObj);
 
     if (!success) {
-        return false;
+        return NO_INIT;
     }
 
     long long framePosition = env->GetLongField(jAudioTimeStampObj, jFramePosition);
@@ -178,7 +192,7 @@
     timestamp.mTime = ts;
     timestamp.mPosition = (uint32_t) framePosition;
 
-    return true;
+    return NO_ERROR;
 }
 
 status_t JAudioTrack::getTimestamp(ExtendedTimestamp *timestamp __unused) {
@@ -189,7 +203,7 @@
 status_t JAudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate) {
     // TODO: existing native AudioTrack returns INVALID_OPERATION on offload/direct/fast tracks.
     // Should we do the same thing?
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
 
     jclass jPlaybackParamsCls = env->FindClass("android/media/PlaybackParams");
     jmethodID jPlaybackParamsCtor = env->GetMethodID(jPlaybackParamsCls, "<init>", "()V");
@@ -224,7 +238,7 @@
 }
 
 const AudioPlaybackRate JAudioTrack::getPlaybackRate() {
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
 
     jmethodID jGetPlaybackParams = env->GetMethodID(
             mAudioTrackCls, "getPlaybackParams", "()Landroid/media/PlaybackParams;");
@@ -266,7 +280,7 @@
         return media::VolumeShaper::Status(BAD_VALUE);
     }
 
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
 
     jmethodID jCreateVolumeShaper = env->GetMethodID(mAudioTrackCls, "createVolumeShaper",
             "(Landroid/media/VolumeShaper$Configuration;)Landroid/media/VolumeShaper;");
@@ -282,7 +296,7 @@
 }
 
 status_t JAudioTrack::setAuxEffectSendLevel(float level) {
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
     jmethodID jSetAuxEffectSendLevel = env->GetMethodID(
             mAudioTrackCls, "setAuxEffectSendLevel", "(F)I");
     int result = env->CallIntMethod(mAudioTrackObj, jSetAuxEffectSendLevel, level);
@@ -290,14 +304,14 @@
 }
 
 status_t JAudioTrack::attachAuxEffect(int effectId) {
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
     jmethodID jAttachAuxEffect = env->GetMethodID(mAudioTrackCls, "attachAuxEffect", "(I)I");
     int result = env->CallIntMethod(mAudioTrackObj, jAttachAuxEffect, effectId);
     return javaToNativeStatus(result);
 }
 
 status_t JAudioTrack::setVolume(float left, float right) {
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
     // TODO: Java setStereoVolume is deprecated. Do we really need this method?
     jmethodID jSetStereoVolume = env->GetMethodID(mAudioTrackCls, "setStereoVolume", "(FF)I");
     int result = env->CallIntMethod(mAudioTrackObj, jSetStereoVolume, left, right);
@@ -305,14 +319,14 @@
 }
 
 status_t JAudioTrack::setVolume(float volume) {
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
     jmethodID jSetVolume = env->GetMethodID(mAudioTrackCls, "setVolume", "(F)I");
     int result = env->CallIntMethod(mAudioTrackObj, jSetVolume, volume);
     return javaToNativeStatus(result);
 }
 
 status_t JAudioTrack::start() {
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
     jmethodID jPlay = env->GetMethodID(mAudioTrackCls, "play", "()V");
     // TODO: Should we catch the Java IllegalStateException from play()?
     env->CallVoidMethod(mAudioTrackObj, jPlay);
@@ -324,7 +338,7 @@
         return BAD_VALUE;
     }
 
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
     jbyteArray jAudioData = env->NewByteArray(size);
     env->SetByteArrayRegion(jAudioData, 0, size, (jbyte *) buffer);
 
@@ -353,7 +367,7 @@
 }
 
 void JAudioTrack::stop() {
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
     jmethodID jStop = env->GetMethodID(mAudioTrackCls, "stop", "()V");
     env->CallVoidMethod(mAudioTrackObj, jStop);
     // TODO: Should we catch IllegalStateException?
@@ -365,20 +379,20 @@
 }
 
 void JAudioTrack::flush() {
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
     jmethodID jFlush = env->GetMethodID(mAudioTrackCls, "flush", "()V");
     env->CallVoidMethod(mAudioTrackObj, jFlush);
 }
 
 void JAudioTrack::pause() {
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
     jmethodID jPause = env->GetMethodID(mAudioTrackCls, "pause", "()V");
     env->CallVoidMethod(mAudioTrackObj, jPause);
     // TODO: Should we catch IllegalStateException?
 }
 
 bool JAudioTrack::isPlaying() const {
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
     jmethodID jGetPlayState = env->GetMethodID(mAudioTrackCls, "getPlayState", "()I");
     int currentPlayState = env->CallIntMethod(mAudioTrackObj, jGetPlayState);
 
@@ -393,7 +407,7 @@
 }
 
 uint32_t JAudioTrack::getSampleRate() {
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
     jmethodID jGetSampleRate = env->GetMethodID(mAudioTrackCls, "getSampleRate", "()I");
     return env->CallIntMethod(mAudioTrackObj, jGetSampleRate);
 }
@@ -403,7 +417,7 @@
         return BAD_VALUE;
     }
 
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
     jmethodID jGetBufferSizeInFrames = env->GetMethodID(
             mAudioTrackCls, "getBufferSizeInFrames", "()I");
     int bufferSizeInFrames = env->CallIntMethod(mAudioTrackObj, jGetBufferSizeInFrames);
@@ -417,12 +431,26 @@
 }
 
 audio_format_t JAudioTrack::format() {
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
     jmethodID jGetAudioFormat = env->GetMethodID(mAudioTrackCls, "getAudioFormat", "()I");
     int javaFormat = env->CallIntMethod(mAudioTrackObj, jGetAudioFormat);
     return audioFormatToNative(javaFormat);
 }
 
+size_t JAudioTrack::frameSize() {
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
+    jmethodID jGetFormat = env->GetMethodID(mAudioTrackCls,
+            "getFormat", "()Landroid/media/AudioFormat;");
+    jobject jAudioFormatObj = env->CallObjectMethod(mAudioTrackObj, jGetFormat);
+
+    jclass jAudioFormatCls = env->FindClass("android/media/AudioFormat");
+    jmethodID jGetFrameSizeInBytes = env->GetMethodID(
+            jAudioFormatCls, "getFrameSizeInBytes", "()I");
+    jint javaFrameSizeInBytes = env->CallIntMethod(jAudioFormatObj, jGetFrameSizeInBytes);
+
+    return (size_t)javaFrameSizeInBytes;
+}
+
 status_t JAudioTrack::dump(int fd, const Vector<String16>& args __unused) const
 {
     String8 result;
@@ -432,10 +460,6 @@
     // TODO: Remove logs that includes unavailable information from below.
 //    result.appendFormat("  status(%d), state(%d), session Id(%d), flags(%#x)\n",
 //                        mStatus, mState, mSessionId, mFlags);
-//    result.appendFormat("  stream type(%d), left - right volume(%f, %f)\n",
-//                        (mStreamType == AUDIO_STREAM_DEFAULT) ?
-//                                audio_attributes_to_stream_type(&mAttributes) : mStreamType,
-//                        mVolume[AUDIO_INTERLEAVE_LEFT], mVolume[AUDIO_INTERLEAVE_RIGHT]);
 //    result.appendFormat("  format(%#x), channel mask(%#x), channel count(%u)\n",
 //                  format(), mChannelMask, channelCount());
 //    result.appendFormat("  sample rate(%u), original sample rate(%u), speed(%f)\n",
@@ -453,38 +477,40 @@
     return NO_ERROR;
 }
 
-audio_port_handle_t JAudioTrack::getRoutedDeviceId() {
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+jobject JAudioTrack::getRoutedDevice() {
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
     jmethodID jGetRoutedDevice = env->GetMethodID(mAudioTrackCls, "getRoutedDevice",
             "()Landroid/media/AudioDeviceInfo;");
-    jobject jAudioDeviceInfoObj = env->CallObjectMethod(mAudioTrackObj, jGetRoutedDevice);
-    if (env->IsSameObject(jAudioDeviceInfoObj, NULL)) {
-        return AUDIO_PORT_HANDLE_NONE;
-    }
-
-    jclass jAudioDeviceInfoCls = env->FindClass("Landroid/media/AudioDeviceInfo");
-    jmethodID jGetId = env->GetMethodID(jAudioDeviceInfoCls, "getId", "()I");
-    jint routedDeviceId = env->CallIntMethod(jAudioDeviceInfoObj, jGetId);
-    return routedDeviceId;
+    return env->CallObjectMethod(mAudioTrackObj, jGetRoutedDevice);
 }
 
-audio_session_t JAudioTrack::getAudioSessionId() {
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+int32_t JAudioTrack::getAudioSessionId() {
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
     jmethodID jGetAudioSessionId = env->GetMethodID(mAudioTrackCls, "getAudioSessionId", "()I");
     jint sessionId = env->CallIntMethod(mAudioTrackObj, jGetAudioSessionId);
-    return (audio_session_t) sessionId;
+    return sessionId;
 }
 
-status_t JAudioTrack::setOutputDevice(audio_port_handle_t deviceId) {
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
-    jclass jMP2ImplCls = env->FindClass("android/media/MediaPlayer2Impl");
-    jmethodID jSetAudioOutputDeviceById = env->GetMethodID(
-            jMP2ImplCls, "setAudioOutputDeviceById", "(Landroid/media/AudioTrack;I)Z");
-    jboolean result = env->CallStaticBooleanMethod(
-            jMP2ImplCls, jSetAudioOutputDeviceById, mAudioTrackObj, deviceId);
+status_t JAudioTrack::setPreferredDevice(jobject device) {
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
+    jmethodID jSetPreferredDeviceId = env->GetMethodID(mAudioTrackCls, "setPreferredDevice",
+            "(Landroid/media/AudioDeviceInfo;)Z");
+    jboolean result = env->CallBooleanMethod(mAudioTrackObj, jSetPreferredDeviceId, device);
     return result == true ? NO_ERROR : BAD_VALUE;
 }
 
+audio_stream_type_t JAudioTrack::getAudioStreamType() {
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
+    jmethodID jGetAudioAttributes = env->GetMethodID(mAudioTrackCls, "getAudioAttributes",
+            "()Landroid/media/AudioAttributes;");
+    jobject jAudioAttributes = env->CallObjectMethod(mAudioTrackObj, jGetAudioAttributes);
+    jclass jAudioAttributesCls = env->FindClass("android/media/AudioAttributes");
+    jmethodID jGetVolumeControlStream = env->GetMethodID(jAudioAttributesCls,
+            "getVolumeControlStream", "()I");
+    int javaAudioStreamType = env->CallIntMethod(jAudioAttributes, jGetVolumeControlStream);
+    return (audio_stream_type_t)javaAudioStreamType;
+}
+
 status_t JAudioTrack::pendingDuration(int32_t *msec) {
     if (msec == nullptr) {
         return BAD_VALUE;
@@ -526,18 +552,72 @@
     return NO_ERROR;
 }
 
-status_t JAudioTrack::addAudioDeviceCallback(
-        const sp<AudioSystem::AudioDeviceCallback>& callback __unused) {
-    // TODO: Implement this after appropriate Java AudioTrack method is available.
+status_t JAudioTrack::addAudioDeviceCallback(jobject listener, jobject handler) {
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
+    jmethodID jAddOnRoutingChangedListener = env->GetMethodID(mAudioTrackCls,
+            "addOnRoutingChangedListener",
+            "(Landroid/media/AudioRouting$OnRoutingChangedListener;Landroid/os/Handler;)V");
+    env->CallVoidMethod(mAudioTrackObj, jAddOnRoutingChangedListener, listener, handler);
     return NO_ERROR;
 }
 
-status_t JAudioTrack::removeAudioDeviceCallback(
-        const sp<AudioSystem::AudioDeviceCallback>& callback __unused) {
-    // TODO: Implement this after appropriate Java AudioTrack method is available.
+status_t JAudioTrack::removeAudioDeviceCallback(jobject listener) {
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
+    jmethodID jRemoveOnRoutingChangedListener = env->GetMethodID(mAudioTrackCls,
+            "removeOnRoutingChangedListener",
+            "(Landroid/media/AudioRouting$OnRoutingChangedListener;)V");
+    env->CallVoidMethod(mAudioTrackObj, jRemoveOnRoutingChangedListener, listener);
     return NO_ERROR;
 }
 
+void JAudioTrack::registerRoutingDelegates(
+        Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& routingDelegates) {
+    for (auto it = routingDelegates.begin(); it != routingDelegates.end(); it++) {
+        addAudioDeviceCallback(it->second->getJObject(), getHandler(it->second->getJObject()));
+    }
+}
+
+/////////////////////////////////////////////////////////////
+///                Static methods begin                   ///
+/////////////////////////////////////////////////////////////
+jobject JAudioTrack::getListener(const jobject routingDelegateObj) {
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
+    jclass jRoutingDelegateCls = env->FindClass("android/media/RoutingDelegate");
+    jmethodID jGetListener = env->GetMethodID(jRoutingDelegateCls,
+            "getListener", "()Landroid/media/AudioRouting$OnRoutingChangedListener;");
+    return env->CallObjectMethod(routingDelegateObj, jGetListener);
+}
+
+jobject JAudioTrack::getHandler(const jobject routingDelegateObj) {
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
+    jclass jRoutingDelegateCls = env->FindClass("android/media/RoutingDelegate");
+    jmethodID jGetHandler = env->GetMethodID(jRoutingDelegateCls,
+        "getHandler", "()Landroid/os/Handler;");
+    return env->CallObjectMethod(routingDelegateObj, jGetHandler);
+}
+
+jobject JAudioTrack::findByKey(
+        Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& mp, const jobject key) {
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
+    for (auto it = mp.begin(); it != mp.end(); it++) {
+        if (env->IsSameObject(it->first->getJObject(), key)) {
+            return it->second->getJObject();
+        }
+    }
+    return nullptr;
+}
+
+void JAudioTrack::eraseByKey(
+        Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& mp, const jobject key) {
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
+    for (auto it = mp.begin(); it != mp.end(); it++) {
+        if (env->IsSameObject(it->first->getJObject(), key)) {
+            mp.erase(it);
+            return;
+        }
+    }
+}
+
 /////////////////////////////////////////////////////////////
 ///                Private method begins                  ///
 /////////////////////////////////////////////////////////////
@@ -550,7 +630,7 @@
         return NULL;
     }
 
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
 
     // Referenced "android_media_VolumeShaper.h".
     jfloatArray xarray = nullptr;
@@ -595,7 +675,7 @@
 jobject JAudioTrack::createVolumeShaperOperationObj(
         const sp<media::VolumeShaper::Operation>& operation) {
 
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
 
     jclass jBuilderCls = env->FindClass("android/media/VolumeShaper$Operation$Builder");
     jmethodID jBuilderCtor = env->GetMethodID(jBuilderCls, "<init>", "()V");
@@ -647,15 +727,15 @@
 }
 
 jobject JAudioTrack::createStreamEventCallback(callback_t cbf, void* user) {
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
-    jclass jCallbackCls = env->FindClass("android/media/MediaPlayer2Impl$StreamEventCallback");
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
+    jclass jCallbackCls = env->FindClass("android/media/MediaPlayer2$StreamEventCallback");
     jmethodID jCallbackCtor = env->GetMethodID(jCallbackCls, "<init>", "(JJJ)V");
     jobject jCallbackObj = env->NewObject(jCallbackCls, jCallbackCtor, this, cbf, user);
     return jCallbackObj;
 }
 
 jobject JAudioTrack::createCallbackExecutor() {
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
     jclass jExecutorsCls = env->FindClass("java/util/concurrent/Executors");
     jmethodID jNewSingleThreadExecutor = env->GetStaticMethodID(jExecutorsCls,
             "newSingleThreadExecutor", "()Ljava/util/concurrent/ExecutorService;");
diff --git a/media/libmediaplayer2/JMedia2HTTPConnection.cpp b/media/libmediaplayer2/JMedia2HTTPConnection.cpp
new file mode 100644
index 0000000..e1baa10
--- /dev/null
+++ b/media/libmediaplayer2/JMedia2HTTPConnection.cpp
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "JMedia2HTTPConnection"
+#include <utils/Log.h>
+
+#include <mediaplayer2/JavaVMHelper.h>
+#include <mediaplayer2/JMedia2HTTPConnection.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <nativehelper/scoped_local_ref.h>
+
+#include "log/log.h"
+#include "jni.h"
+
+namespace android {
+
+static const size_t kBufferSize = 32768;
+
+JMedia2HTTPConnection::JMedia2HTTPConnection(JNIEnv *env, jobject thiz) {
+    mMedia2HTTPConnectionObj = env->NewGlobalRef(thiz);
+    CHECK(mMedia2HTTPConnectionObj != NULL);
+
+    ScopedLocalRef<jclass> media2HTTPConnectionClass(
+            env, env->GetObjectClass(mMedia2HTTPConnectionObj));
+    CHECK(media2HTTPConnectionClass.get() != NULL);
+
+    mConnectMethod = env->GetMethodID(
+            media2HTTPConnectionClass.get(),
+            "connect",
+            "(Ljava/lang/String;Ljava/lang/String;)Z");
+    CHECK(mConnectMethod != NULL);
+
+    mDisconnectMethod = env->GetMethodID(
+            media2HTTPConnectionClass.get(),
+            "disconnect",
+            "()V");
+    CHECK(mDisconnectMethod != NULL);
+
+    mReadAtMethod = env->GetMethodID(
+            media2HTTPConnectionClass.get(),
+            "readAt",
+            "(J[BI)I");
+    CHECK(mReadAtMethod != NULL);
+
+    mGetSizeMethod = env->GetMethodID(
+            media2HTTPConnectionClass.get(),
+            "getSize",
+            "()J");
+    CHECK(mGetSizeMethod != NULL);
+
+    mGetMIMETypeMethod = env->GetMethodID(
+            media2HTTPConnectionClass.get(),
+            "getMIMEType",
+            "()Ljava/lang/String;");
+    CHECK(mGetMIMETypeMethod != NULL);
+
+    mGetUriMethod = env->GetMethodID(
+            media2HTTPConnectionClass.get(),
+            "getUri",
+            "()Ljava/lang/String;");
+    CHECK(mGetUriMethod != NULL);
+
+    ScopedLocalRef<jbyteArray> tmp(
+        env, env->NewByteArray(kBufferSize));
+    mByteArrayObj = (jbyteArray)env->NewGlobalRef(tmp.get());
+    CHECK(mByteArrayObj != NULL);
+}
+
+JMedia2HTTPConnection::~JMedia2HTTPConnection() {
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
+    env->DeleteGlobalRef(mMedia2HTTPConnectionObj);
+    env->DeleteGlobalRef(mByteArrayObj);
+}
+
+bool JMedia2HTTPConnection::connect(
+        const char *uri, const KeyedVector<String8, String8> *headers) {
+    String8 tmp("");
+    if (headers != NULL) {
+        for (size_t i = 0; i < headers->size(); ++i) {
+            tmp.append(headers->keyAt(i));
+            tmp.append(String8(": "));
+            tmp.append(headers->valueAt(i));
+            tmp.append(String8("\r\n"));
+        }
+    }
+
+    JNIEnv* env = JavaVMHelper::getJNIEnv();
+    jstring juri = env->NewStringUTF(uri);
+    jstring jheaders = env->NewStringUTF(tmp.string());
+
+    jboolean ret =
+        env->CallBooleanMethod(mMedia2HTTPConnectionObj, mConnectMethod, juri, jheaders);
+
+    env->DeleteLocalRef(juri);
+    env->DeleteLocalRef(jheaders);
+
+    return (bool)ret;
+}
+
+void JMedia2HTTPConnection::disconnect() {
+    JNIEnv* env = JavaVMHelper::getJNIEnv();
+    env->CallVoidMethod(mMedia2HTTPConnectionObj, mDisconnectMethod);
+}
+
+ssize_t JMedia2HTTPConnection::readAt(off64_t offset, void *data, size_t size) {
+    JNIEnv* env = JavaVMHelper::getJNIEnv();
+
+    if (size > kBufferSize) {
+        size = kBufferSize;
+    }
+
+    jint n = env->CallIntMethod(
+            mMedia2HTTPConnectionObj, mReadAtMethod, (jlong)offset, mByteArrayObj, (jint)size);
+
+    if (n > 0) {
+        env->GetByteArrayRegion(
+                mByteArrayObj,
+                0,
+                n,
+                (jbyte *)data);
+    }
+
+    return n;
+}
+
+off64_t JMedia2HTTPConnection::getSize() {
+    JNIEnv* env = JavaVMHelper::getJNIEnv();
+    return (off64_t)(env->CallLongMethod(mMedia2HTTPConnectionObj, mGetSizeMethod));
+}
+
+status_t JMedia2HTTPConnection::getMIMEType(String8 *mimeType) {
+    JNIEnv* env = JavaVMHelper::getJNIEnv();
+    jstring jmime = (jstring)env->CallObjectMethod(mMedia2HTTPConnectionObj, mGetMIMETypeMethod);
+    jboolean flag = env->ExceptionCheck();
+    if (flag) {
+        env->ExceptionClear();
+        return UNKNOWN_ERROR;
+    }
+
+    const char *str = env->GetStringUTFChars(jmime, 0);
+    if (str != NULL) {
+        *mimeType = String8(str);
+    } else {
+        *mimeType = "application/octet-stream";
+    }
+    env->ReleaseStringUTFChars(jmime, str);
+    return OK;
+}
+
+status_t JMedia2HTTPConnection::getUri(String8 *uri) {
+    JNIEnv* env = JavaVMHelper::getJNIEnv();
+    jstring juri = (jstring)env->CallObjectMethod(mMedia2HTTPConnectionObj, mGetUriMethod);
+    jboolean flag = env->ExceptionCheck();
+    if (flag) {
+        env->ExceptionClear();
+        return UNKNOWN_ERROR;
+    }
+
+    const char *str = env->GetStringUTFChars(juri, 0);
+    *uri = String8(str);
+    env->ReleaseStringUTFChars(juri, str);
+    return OK;
+}
+
+}  // namespace android
diff --git a/media/libmediaplayer2/JMedia2HTTPService.cpp b/media/libmediaplayer2/JMedia2HTTPService.cpp
new file mode 100644
index 0000000..20e3573
--- /dev/null
+++ b/media/libmediaplayer2/JMedia2HTTPService.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "JMedia2HTTPService"
+#include <utils/Log.h>
+
+#include <jni.h>
+
+#include <mediaplayer2/JavaVMHelper.h>
+#include <mediaplayer2/JMedia2HTTPService.h>
+#include <mediaplayer2/JMedia2HTTPConnection.h>
+#include <media/stagefright/foundation/ADebug.h>
+
+#include <nativehelper/scoped_local_ref.h>
+
+namespace android {
+
+JMedia2HTTPService::JMedia2HTTPService(JNIEnv *env, jobject thiz) {
+    mMedia2HTTPServiceObj = env->NewGlobalRef(thiz);
+    CHECK(mMedia2HTTPServiceObj != NULL);
+
+    ScopedLocalRef<jclass> media2HTTPServiceClass(env, env->GetObjectClass(mMedia2HTTPServiceObj));
+    CHECK(media2HTTPServiceClass.get() != NULL);
+
+    mMakeHTTPConnectionMethod = env->GetMethodID(
+            media2HTTPServiceClass.get(),
+            "makeHTTPConnection",
+            "()Landroid/media/Media2HTTPConnection;");
+    CHECK(mMakeHTTPConnectionMethod != NULL);
+}
+
+JMedia2HTTPService::~JMedia2HTTPService() {
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
+    env->DeleteGlobalRef(mMedia2HTTPServiceObj);
+}
+
+sp<MediaHTTPConnection> JMedia2HTTPService::makeHTTPConnection() {
+    JNIEnv* env = JavaVMHelper::getJNIEnv();
+    jobject media2HTTPConnectionObj =
+        env->CallObjectMethod(mMedia2HTTPServiceObj, mMakeHTTPConnectionMethod);
+
+    return new JMedia2HTTPConnection(env, media2HTTPConnectionObj);
+}
+
+}  // namespace android
diff --git a/media/libmediaplayer2/JavaVMHelper.cpp b/media/libmediaplayer2/JavaVMHelper.cpp
new file mode 100644
index 0000000..8d03ed0
--- /dev/null
+++ b/media/libmediaplayer2/JavaVMHelper.cpp
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "JavaVMHelper"
+
+#include "mediaplayer2/JavaVMHelper.h"
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <utils/threads.h>
+
+#include <stdlib.h>
+
+namespace android {
+
+// static
+std::atomic<JavaVM *> JavaVMHelper::sJavaVM(NULL);
+
+/*
+ * Makes the current thread visible to the VM.
+ *
+ * The JNIEnv pointer returned is only valid for the current thread, and
+ * thus must be tucked into thread-local storage.
+ */
+static int javaAttachThread(const char* threadName, JNIEnv** pEnv) {
+    JavaVMAttachArgs args;
+    JavaVM* vm;
+    jint result;
+
+    vm = JavaVMHelper::getJavaVM();
+    if (vm == NULL) {
+        return JNI_ERR;
+    }
+
+    args.version = JNI_VERSION_1_4;
+    args.name = (char*) threadName;
+    args.group = NULL;
+
+    result = vm->AttachCurrentThread(pEnv, (void*) &args);
+    if (result != JNI_OK) {
+        ALOGI("NOTE: attach of thread '%s' failed\n", threadName);
+    }
+
+    return result;
+}
+
+/*
+ * Detach the current thread from the set visible to the VM.
+ */
+static int javaDetachThread(void) {
+    JavaVM* vm;
+    jint result;
+
+    vm = JavaVMHelper::getJavaVM();
+    if (vm == NULL) {
+        return JNI_ERR;
+    }
+
+    result = vm->DetachCurrentThread();
+    if (result != JNI_OK) {
+        ALOGE("ERROR: thread detach failed\n");
+    }
+    return result;
+}
+
+/*
+ * When starting a native thread that will be visible from the VM, we
+ * bounce through this to get the right attach/detach action.
+ * Note that this function calls free(args)
+ */
+static int javaThreadShell(void* args) {
+    void* start = ((void**)args)[0];
+    void* userData = ((void **)args)[1];
+    char* name = (char*) ((void **)args)[2];        // we own this storage
+    free(args);
+    JNIEnv* env;
+    int result;
+
+    /* hook us into the VM */
+    if (javaAttachThread(name, &env) != JNI_OK) {
+        return -1;
+    }
+
+    /* start the thread running */
+    result = (*(android_thread_func_t)start)(userData);
+
+    /* unhook us */
+    javaDetachThread();
+    free(name);
+
+    return result;
+}
+
+/*
+ * This is invoked from androidCreateThreadEtc() via the callback
+ * set with androidSetCreateThreadFunc().
+ *
+ * We need to create the new thread in such a way that it gets hooked
+ * into the VM before it really starts executing.
+ */
+static int javaCreateThreadEtc(
+        android_thread_func_t entryFunction,
+        void* userData,
+        const char* threadName,
+        int32_t threadPriority,
+        size_t threadStackSize,
+        android_thread_id_t* threadId) {
+    void** args = (void**) malloc(3 * sizeof(void*));   // javaThreadShell must free
+    int result;
+
+    LOG_ALWAYS_FATAL_IF(threadName == nullptr, "threadName not provided to javaCreateThreadEtc");
+
+    args[0] = (void*) entryFunction;
+    args[1] = userData;
+    args[2] = (void*) strdup(threadName);   // javaThreadShell must free
+
+    result = androidCreateRawThreadEtc(javaThreadShell, args,
+        threadName, threadPriority, threadStackSize, threadId);
+    return result;
+}
+
+// static
+JNIEnv *JavaVMHelper::getJNIEnv() {
+    JNIEnv *env;
+    JavaVM *vm = sJavaVM.load();
+    CHECK(vm != NULL);
+
+    if (vm->GetEnv((void **)&env, JNI_VERSION_1_4) != JNI_OK) {
+        return NULL;
+    }
+
+    return env;
+}
+
+//static
+JavaVM *JavaVMHelper::getJavaVM() {
+    return sJavaVM.load();
+}
+
+// static
+void JavaVMHelper::setJavaVM(JavaVM *vm) {
+    sJavaVM.store(vm);
+
+    // Ensure that Thread(/*canCallJava*/ true) in libutils is attached to the VM.
+    // This is supposed to be done by runtime, but when libutils is used with linker
+    // namespace, CreateThreadFunc should be initialized separately within the namespace.
+    androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
+}
+
+}  // namespace android
diff --git a/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp b/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
index a8e1d1f..b4fa0c1 100644
--- a/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
+++ b/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
@@ -22,8 +22,6 @@
 #include <cutils/properties.h> // for property_get
 #include <utils/Log.h>
 
-#include <media/AudioPolicyHelper.h>
-#include <media/AudioTrack.h>
 #include <media/stagefright/foundation/ADebug.h>
 
 namespace {
@@ -44,31 +42,28 @@
     String8 result;
 
     result.append(" MediaPlayer2AudioOutput\n");
-    snprintf(buffer, 255, "  stream type(%d), left - right volume(%f, %f)\n",
-            mStreamType, mLeftVolume, mRightVolume);
+    snprintf(buffer, 255, "  volume(%f)\n", mVolume);
     result.append(buffer);
     snprintf(buffer, 255, "  msec per frame(%f), latency (%d)\n",
-            mMsecsPerFrame, (mTrack != 0) ? mTrack->latency() : -1);
+            mMsecsPerFrame, (mJAudioTrack != nullptr) ? mJAudioTrack->latency() : -1);
     result.append(buffer);
     snprintf(buffer, 255, "  aux effect id(%d), send level (%f)\n",
             mAuxEffectId, mSendLevel);
     result.append(buffer);
 
     ::write(fd, result.string(), result.size());
-    if (mTrack != 0) {
-        mTrack->dump(fd, args);
+    if (mJAudioTrack != nullptr) {
+        mJAudioTrack->dump(fd, args);
     }
     return NO_ERROR;
 }
 
-MediaPlayer2AudioOutput::MediaPlayer2AudioOutput(audio_session_t sessionId, uid_t uid, int pid,
-        const audio_attributes_t* attr, const sp<AudioSystem::AudioDeviceCallback>& deviceCallback)
-    : mCallback(NULL),
-      mCallbackCookie(NULL),
-      mCallbackData(NULL),
-      mStreamType(AUDIO_STREAM_MUSIC),
-      mLeftVolume(1.0),
-      mRightVolume(1.0),
+MediaPlayer2AudioOutput::MediaPlayer2AudioOutput(int32_t sessionId, uid_t uid, int pid,
+        const jobject attributes)
+    : mCallback(nullptr),
+      mCallbackCookie(nullptr),
+      mCallbackData(nullptr),
+      mVolume(1.0),
       mPlaybackRate(AUDIO_PLAYBACK_RATE_DEFAULT),
       mSampleRateHz(0),
       mMsecsPerFrame(0),
@@ -78,28 +73,19 @@
       mPid(pid),
       mSendLevel(0.0),
       mAuxEffectId(0),
-      mFlags(AUDIO_OUTPUT_FLAG_NONE),
-      mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
-      mRoutedDeviceId(AUDIO_PORT_HANDLE_NONE),
-      mDeviceCallbackEnabled(false),
-      mDeviceCallback(deviceCallback) {
+      mFlags(AUDIO_OUTPUT_FLAG_NONE) {
     ALOGV("MediaPlayer2AudioOutput(%d)", sessionId);
-    if (attr != NULL) {
-        mAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
-        if (mAttributes != NULL) {
-            memcpy(mAttributes, attr, sizeof(audio_attributes_t));
-            mStreamType = audio_attributes_to_stream_type(attr);
-        }
-    } else {
-        mAttributes = NULL;
+
+    if (attributes != nullptr) {
+        mAttributes = new JObjectHolder(attributes);
     }
 
     setMinBufferCount();
+    mRoutingDelegates.clear();
 }
 
 MediaPlayer2AudioOutput::~MediaPlayer2AudioOutput() {
     close();
-    free(mAttributes);
     delete mCallbackData;
 }
 
@@ -126,31 +112,31 @@
 
 ssize_t MediaPlayer2AudioOutput::bufferSize() const {
     Mutex::Autolock lock(mLock);
-    if (mTrack == 0) {
+    if (mJAudioTrack == nullptr) {
         return NO_INIT;
     }
-    return mTrack->frameCount() * mFrameSize;
+    return mJAudioTrack->frameCount() * mFrameSize;
 }
 
 ssize_t MediaPlayer2AudioOutput::frameCount() const {
     Mutex::Autolock lock(mLock);
-    if (mTrack == 0) {
+    if (mJAudioTrack == nullptr) {
         return NO_INIT;
     }
-    return mTrack->frameCount();
+    return mJAudioTrack->frameCount();
 }
 
 ssize_t MediaPlayer2AudioOutput::channelCount() const {
     Mutex::Autolock lock(mLock);
-    if (mTrack == 0) {
+    if (mJAudioTrack == nullptr) {
         return NO_INIT;
     }
-    return mTrack->channelCount();
+    return mJAudioTrack->channelCount();
 }
 
 ssize_t MediaPlayer2AudioOutput::frameSize() const {
     Mutex::Autolock lock(mLock);
-    if (mTrack == 0) {
+    if (mJAudioTrack == nullptr) {
         return NO_INIT;
     }
     return mFrameSize;
@@ -158,10 +144,10 @@
 
 uint32_t MediaPlayer2AudioOutput::latency () const {
     Mutex::Autolock lock(mLock);
-    if (mTrack == 0) {
+    if (mJAudioTrack == nullptr) {
         return 0;
     }
-    return mTrack->latency();
+    return mJAudioTrack->latency();
 }
 
 float MediaPlayer2AudioOutput::msecsPerFrame() const {
@@ -171,18 +157,18 @@
 
 status_t MediaPlayer2AudioOutput::getPosition(uint32_t *position) const {
     Mutex::Autolock lock(mLock);
-    if (mTrack == 0) {
+    if (mJAudioTrack == nullptr) {
         return NO_INIT;
     }
-    return mTrack->getPosition(position);
+    return mJAudioTrack->getPosition(position);
 }
 
 status_t MediaPlayer2AudioOutput::getTimestamp(AudioTimestamp &ts) const {
     Mutex::Autolock lock(mLock);
-    if (mTrack == 0) {
+    if (mJAudioTrack == nullptr) {
         return NO_INIT;
     }
-    return mTrack->getTimestamp(ts);
+    return mJAudioTrack->getTimestamp(ts);
 }
 
 // TODO: Remove unnecessary calls to getPlayedOutDurationUs()
@@ -195,7 +181,7 @@
 // Calculate duration of played samples if played at normal rate (i.e., 1.0).
 int64_t MediaPlayer2AudioOutput::getPlayedOutDurationUs(int64_t nowUs) const {
     Mutex::Autolock lock(mLock);
-    if (mTrack == 0 || mSampleRateHz == 0) {
+    if (mJAudioTrack == nullptr || mSampleRateHz == 0) {
         return 0;
     }
 
@@ -203,22 +189,18 @@
     int64_t numFramesPlayedAtUs;
     AudioTimestamp ts;
 
-    status_t res = mTrack->getTimestamp(ts);
+    status_t res = mJAudioTrack->getTimestamp(ts);
+
     if (res == OK) {                 // case 1: mixing audio tracks and offloaded tracks.
         numFramesPlayed = ts.mPosition;
         numFramesPlayedAtUs = ts.mTime.tv_sec * 1000000LL + ts.mTime.tv_nsec / 1000;
         //ALOGD("getTimestamp: OK %d %lld", numFramesPlayed, (long long)numFramesPlayedAtUs);
-    } else if (res == WOULD_BLOCK) { // case 2: transitory state on start of a new track
+    } else {                         // case 2: transitory state on start of a new track
+                                     // case 3: transitory at new track or audio fast tracks.
         numFramesPlayed = 0;
         numFramesPlayedAtUs = nowUs;
         //ALOGD("getTimestamp: WOULD_BLOCK %d %lld",
         //        numFramesPlayed, (long long)numFramesPlayedAtUs);
-    } else {                         // case 3: transitory at new track or audio fast tracks.
-        res = mTrack->getPosition(&numFramesPlayed);
-        CHECK_EQ(res, (status_t)OK);
-        numFramesPlayedAtUs = nowUs;
-        numFramesPlayedAtUs += 1000LL * mTrack->latency() / 2; /* XXX */
-        //ALOGD("getPosition: %u %lld", numFramesPlayed, (long long)numFramesPlayedAtUs);
     }
 
     // CHECK_EQ(numFramesPlayed & (1 << 31), 0);  // can't be negative until 12.4 hrs, test
@@ -244,108 +226,55 @@
 
 status_t MediaPlayer2AudioOutput::getFramesWritten(uint32_t *frameswritten) const {
     Mutex::Autolock lock(mLock);
-    if (mTrack == 0) {
+    if (mJAudioTrack == nullptr) {
         return NO_INIT;
     }
     ExtendedTimestamp ets;
-    status_t status = mTrack->getTimestamp(&ets);
+    status_t status = mJAudioTrack->getTimestamp(&ets);
     if (status == OK || status == WOULD_BLOCK) {
         *frameswritten = (uint32_t)ets.mPosition[ExtendedTimestamp::LOCATION_CLIENT];
     }
     return status;
 }
 
-status_t MediaPlayer2AudioOutput::setParameters(const String8& keyValuePairs) {
+void MediaPlayer2AudioOutput::setAudioAttributes(const jobject attributes) {
     Mutex::Autolock lock(mLock);
-    if (mTrack == 0) {
-        return NO_INIT;
-    }
-    return mTrack->setParameters(keyValuePairs);
+    mAttributes = (attributes == nullptr) ? nullptr : new JObjectHolder(attributes);
 }
 
-String8  MediaPlayer2AudioOutput::getParameters(const String8& keys) {
+audio_stream_type_t MediaPlayer2AudioOutput::getAudioStreamType() const {
+    ALOGV("getAudioStreamType");
     Mutex::Autolock lock(mLock);
-    if (mTrack == 0) {
-        return String8::empty();
+    if (mJAudioTrack == nullptr) {
+        return AUDIO_STREAM_DEFAULT;
     }
-    return mTrack->getParameters(keys);
-}
-
-void MediaPlayer2AudioOutput::setAudioAttributes(const audio_attributes_t * attributes) {
-    Mutex::Autolock lock(mLock);
-    if (attributes == NULL) {
-        free(mAttributes);
-        mAttributes = NULL;
-    } else {
-        if (mAttributes == NULL) {
-            mAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
-        }
-        memcpy(mAttributes, attributes, sizeof(audio_attributes_t));
-        mStreamType = audio_attributes_to_stream_type(attributes);
-    }
-}
-
-void MediaPlayer2AudioOutput::setAudioStreamType(audio_stream_type_t streamType) {
-    Mutex::Autolock lock(mLock);
-    // do not allow direct stream type modification if attributes have been set
-    if (mAttributes == NULL) {
-        mStreamType = streamType;
-    }
+    return mJAudioTrack->getAudioStreamType();
 }
 
 void MediaPlayer2AudioOutput::close_l() {
-    mTrack.clear();
+    mJAudioTrack.clear();
 }
 
 status_t MediaPlayer2AudioOutput::open(
         uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
-        audio_format_t format, int bufferCount,
+        audio_format_t format,
         AudioCallback cb, void *cookie,
         audio_output_flags_t flags,
         const audio_offload_info_t *offloadInfo,
-        bool doNotReconnect,
         uint32_t suggestedFrameCount) {
-    ALOGV("open(%u, %d, 0x%x, 0x%x, %d, %d 0x%x)", sampleRate, channelCount, channelMask,
-                format, bufferCount, mSessionId, flags);
+    ALOGV("open(%u, %d, 0x%x, 0x%x, %d 0x%x)", sampleRate, channelCount, channelMask,
+                format, mSessionId, flags);
 
     // offloading is only supported in callback mode for now.
     // offloadInfo must be present if offload flag is set
     if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) &&
-            ((cb == NULL) || (offloadInfo == NULL))) {
+            ((cb == nullptr) || (offloadInfo == nullptr))) {
         return BAD_VALUE;
     }
 
     // compute frame count for the AudioTrack internal buffer
-    size_t frameCount;
-    if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
-        frameCount = 0; // AudioTrack will get frame count from AudioFlinger
-    } else {
-        // try to estimate the buffer processing fetch size from AudioFlinger.
-        // framesPerBuffer is approximate and generally correct, except when it's not :-).
-        uint32_t afSampleRate;
-        size_t afFrameCount;
-        if (AudioSystem::getOutputFrameCount(&afFrameCount, mStreamType) != NO_ERROR) {
-            return NO_INIT;
-        }
-        if (AudioSystem::getOutputSamplingRate(&afSampleRate, mStreamType) != NO_ERROR) {
-            return NO_INIT;
-        }
-        const size_t framesPerBuffer =
-                (unsigned long long)sampleRate * afFrameCount / afSampleRate;
-
-        if (bufferCount == 0) {
-            // use suggestedFrameCount
-            bufferCount = (suggestedFrameCount + framesPerBuffer - 1) / framesPerBuffer;
-        }
-        // Check argument bufferCount against the mininum buffer count
-        if (bufferCount != 0 && bufferCount < mMinBufferCount) {
-            ALOGV("bufferCount (%d) increased to %d", bufferCount, mMinBufferCount);
-            bufferCount = mMinBufferCount;
-        }
-        // if frameCount is 0, then AudioTrack will get frame count from AudioFlinger
-        // which will be the minimum size permitted.
-        frameCount = bufferCount * framesPerBuffer;
-    }
+    const size_t frameCount =
+           ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) ? 0 : suggestedFrameCount;
 
     if (channelMask == CHANNEL_MASK_USE_CHANNEL_ORDER) {
         channelMask = audio_channel_out_mask_from_count(channelCount);
@@ -359,32 +288,23 @@
     mCallback = cb;
     mCallbackCookie = cookie;
 
-    sp<AudioTrack> t;
-    CallbackData *newcbd = NULL;
+    sp<JAudioTrack> jT;
+    CallbackData *newcbd = nullptr;
 
-    ALOGV("creating new AudioTrack");
+    ALOGV("creating new JAudioTrack");
 
-    if (mCallback != NULL) {
+    if (mCallback != nullptr) {
         newcbd = new CallbackData(this);
-        t = new AudioTrack(
-                mStreamType,
-                sampleRate,
-                format,
-                channelMask,
-                frameCount,
-                flags,
-                CallbackWrapper,
-                newcbd,
-                0,  // notification frames
-                mSessionId,
-                AudioTrack::TRANSFER_CALLBACK,
-                offloadInfo,
-                mUid,
-                mPid,
-                mAttributes,
-                doNotReconnect,
-                1.0f,  // default value for maxRequiredSpeed
-                mSelectedDeviceId);
+        jT = new JAudioTrack(
+                 sampleRate,
+                 format,
+                 channelMask,
+                 CallbackWrapper,
+                 newcbd,
+                 frameCount,
+                 mSessionId,
+                 mAttributes != nullptr ? mAttributes->getJObject() : nullptr,
+                 1.0f);  // default value for maxRequiredSpeed
     } else {
         // TODO: Due to buffer memory concerns, we use a max target playback speed
         // based on mPlaybackRate at the time of open (instead of kMaxRequiredSpeed),
@@ -394,73 +314,62 @@
         ALOGW_IF(targetSpeed != mPlaybackRate.mSpeed,
                 "track target speed:%f clamped from playback speed:%f",
                 targetSpeed, mPlaybackRate.mSpeed);
-        t = new AudioTrack(
-                mStreamType,
-                sampleRate,
-                format,
-                channelMask,
-                frameCount,
-                flags,
-                NULL, // callback
-                NULL, // user data
-                0, // notification frames
-                mSessionId,
-                AudioTrack::TRANSFER_DEFAULT,
-                NULL, // offload info
-                mUid,
-                mPid,
-                mAttributes,
-                doNotReconnect,
-                targetSpeed,
-                mSelectedDeviceId);
+        jT = new JAudioTrack(
+                 sampleRate,
+                 format,
+                 channelMask,
+                 nullptr,
+                 nullptr,
+                 frameCount,
+                 mSessionId,
+                 mAttributes != nullptr ? mAttributes->getJObject() : nullptr,
+                 targetSpeed);
     }
 
-    if ((t == 0) || (t->initCheck() != NO_ERROR)) {
+    if (jT == 0) {
         ALOGE("Unable to create audio track");
         delete newcbd;
         // t goes out of scope, so reference count drops to zero
         return NO_INIT;
-    } else {
-        // successful AudioTrack initialization implies a legacy stream type was generated
-        // from the audio attributes
-        mStreamType = t->streamType();
     }
 
-    CHECK((t != NULL) && ((mCallback == NULL) || (newcbd != NULL)));
+    CHECK((jT != nullptr) && ((mCallback == nullptr) || (newcbd != nullptr)));
 
     mCallbackData = newcbd;
     ALOGV("setVolume");
-    t->setVolume(mLeftVolume, mRightVolume);
+    jT->setVolume(mVolume);
 
     mSampleRateHz = sampleRate;
     mFlags = flags;
     mMsecsPerFrame = 1E3f / (mPlaybackRate.mSpeed * sampleRate);
-    mFrameSize = t->frameSize();
-    mTrack = t;
+    mFrameSize = jT->frameSize();
+    mJAudioTrack = jT;
 
     return updateTrack_l();
 }
 
 status_t MediaPlayer2AudioOutput::updateTrack_l() {
-    if (mTrack == NULL) {
+    if (mJAudioTrack == nullptr) {
         return NO_ERROR;
     }
 
     status_t res = NO_ERROR;
     // Note some output devices may give us a direct track even though we don't specify it.
     // Example: Line application b/17459982.
-    if ((mTrack->getFlags()
+    if ((mJAudioTrack->getFlags()
             & (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD | AUDIO_OUTPUT_FLAG_DIRECT)) == 0) {
-        res = mTrack->setPlaybackRate(mPlaybackRate);
+        res = mJAudioTrack->setPlaybackRate(mPlaybackRate);
         if (res == NO_ERROR) {
-            mTrack->setAuxEffectSendLevel(mSendLevel);
-            res = mTrack->attachAuxEffect(mAuxEffectId);
+            mJAudioTrack->setAuxEffectSendLevel(mSendLevel);
+            res = mJAudioTrack->attachAuxEffect(mAuxEffectId);
         }
     }
-    mTrack->setOutputDevice(mSelectedDeviceId);
-    if (mDeviceCallbackEnabled) {
-        mTrack->addAudioDeviceCallback(mDeviceCallback.promote());
+    if (mPreferredDevice != nullptr) {
+        mJAudioTrack->setPreferredDevice(mPreferredDevice->getJObject());
     }
+
+    mJAudioTrack->registerRoutingDelegates(mRoutingDelegates);
+
     ALOGV("updateTrack_l() DONE status %d", res);
     return res;
 }
@@ -468,13 +377,13 @@
 status_t MediaPlayer2AudioOutput::start() {
     ALOGV("start");
     Mutex::Autolock lock(mLock);
-    if (mCallbackData != NULL) {
+    if (mCallbackData != nullptr) {
         mCallbackData->endTrackSwitch();
     }
-    if (mTrack != 0) {
-        mTrack->setVolume(mLeftVolume, mRightVolume);
-        mTrack->setAuxEffectSendLevel(mSendLevel);
-        status_t status = mTrack->start();
+    if (mJAudioTrack != nullptr) {
+        mJAudioTrack->setVolume(mVolume);
+        mJAudioTrack->setAuxEffectSendLevel(mSendLevel);
+        status_t status = mJAudioTrack->start();
         return status;
     }
     return NO_INIT;
@@ -482,11 +391,11 @@
 
 ssize_t MediaPlayer2AudioOutput::write(const void* buffer, size_t size, bool blocking) {
     Mutex::Autolock lock(mLock);
-    LOG_ALWAYS_FATAL_IF(mCallback != NULL, "Don't call write if supplying a callback.");
+    LOG_ALWAYS_FATAL_IF(mCallback != nullptr, "Don't call write if supplying a callback.");
 
     //ALOGV("write(%p, %u)", buffer, size);
-    if (mTrack != 0) {
-        return mTrack->write(buffer, size, blocking);
+    if (mJAudioTrack != nullptr) {
+        return mJAudioTrack->write(buffer, size, blocking);
     }
     return NO_INIT;
 }
@@ -494,45 +403,44 @@
 void MediaPlayer2AudioOutput::stop() {
     ALOGV("stop");
     Mutex::Autolock lock(mLock);
-    if (mTrack != 0) {
-        mTrack->stop();
+    if (mJAudioTrack != nullptr) {
+        mJAudioTrack->stop();
     }
 }
 
 void MediaPlayer2AudioOutput::flush() {
     ALOGV("flush");
     Mutex::Autolock lock(mLock);
-    if (mTrack != 0) {
-        mTrack->flush();
+    if (mJAudioTrack != nullptr) {
+        mJAudioTrack->flush();
     }
 }
 
 void MediaPlayer2AudioOutput::pause() {
     ALOGV("pause");
     Mutex::Autolock lock(mLock);
-    if (mTrack != 0) {
-        mTrack->pause();
+    if (mJAudioTrack != nullptr) {
+        mJAudioTrack->pause();
     }
 }
 
 void MediaPlayer2AudioOutput::close() {
     ALOGV("close");
-    sp<AudioTrack> track;
+    sp<JAudioTrack> track;
     {
         Mutex::Autolock lock(mLock);
-        track = mTrack;
-        close_l(); // clears mTrack
+        track = mJAudioTrack;
+        close_l(); // clears mJAudioTrack
     }
     // destruction of the track occurs outside of mutex.
 }
 
-void MediaPlayer2AudioOutput::setVolume(float left, float right) {
-    ALOGV("setVolume(%f, %f)", left, right);
+void MediaPlayer2AudioOutput::setVolume(float volume) {
+    ALOGV("setVolume(%f)", volume);
     Mutex::Autolock lock(mLock);
-    mLeftVolume = left;
-    mRightVolume = right;
-    if (mTrack != 0) {
-        mTrack->setVolume(left, right);
+    mVolume = volume;
+    if (mJAudioTrack != nullptr) {
+        mJAudioTrack->setVolume(volume);
     }
 }
 
@@ -540,12 +448,12 @@
     ALOGV("setPlaybackRate(%f %f %d %d)",
                 rate.mSpeed, rate.mPitch, rate.mFallbackMode, rate.mStretchMode);
     Mutex::Autolock lock(mLock);
-    if (mTrack == 0) {
+    if (mJAudioTrack == 0) {
         // remember rate so that we can set it when the track is opened
         mPlaybackRate = rate;
         return OK;
     }
-    status_t res = mTrack->setPlaybackRate(rate);
+    status_t res = mJAudioTrack->setPlaybackRate(rate);
     if (res != NO_ERROR) {
         return res;
     }
@@ -559,12 +467,12 @@
 }
 
 status_t MediaPlayer2AudioOutput::getPlaybackRate(AudioPlaybackRate *rate) {
-    ALOGV("setPlaybackRate");
+    ALOGV("getPlaybackRate");
     Mutex::Autolock lock(mLock);
-    if (mTrack == 0) {
+    if (mJAudioTrack == 0) {
         return NO_INIT;
     }
-    *rate = mTrack->getPlaybackRate();
+    *rate = mJAudioTrack->getPlaybackRate();
     return NO_ERROR;
 }
 
@@ -572,8 +480,8 @@
     ALOGV("setAuxEffectSendLevel(%f)", level);
     Mutex::Autolock lock(mLock);
     mSendLevel = level;
-    if (mTrack != 0) {
-        return mTrack->setAuxEffectSendLevel(level);
+    if (mJAudioTrack != nullptr) {
+        return mJAudioTrack->setAuxEffectSendLevel(level);
     }
     return NO_ERROR;
 }
@@ -582,44 +490,63 @@
     ALOGV("attachAuxEffect(%d)", effectId);
     Mutex::Autolock lock(mLock);
     mAuxEffectId = effectId;
-    if (mTrack != 0) {
-        return mTrack->attachAuxEffect(effectId);
+    if (mJAudioTrack != nullptr) {
+        return mJAudioTrack->attachAuxEffect(effectId);
     }
     return NO_ERROR;
 }
 
-status_t MediaPlayer2AudioOutput::setOutputDevice(audio_port_handle_t deviceId) {
-    ALOGV("setOutputDevice(%d)", deviceId);
+status_t MediaPlayer2AudioOutput::setPreferredDevice(jobject device) {
+    ALOGV("setPreferredDevice");
     Mutex::Autolock lock(mLock);
-    mSelectedDeviceId = deviceId;
-    if (mTrack != 0) {
-        return mTrack->setOutputDevice(deviceId);
+    status_t ret = NO_ERROR;
+    if (mJAudioTrack != nullptr) {
+        ret = mJAudioTrack->setPreferredDevice(device);
     }
-    return NO_ERROR;
+    if (ret == NO_ERROR) {
+        mPreferredDevice = new JObjectHolder(device);
+    }
+    return ret;
 }
 
-status_t MediaPlayer2AudioOutput::getRoutedDeviceId(audio_port_handle_t* deviceId) {
-    ALOGV("getRoutedDeviceId");
+jobject MediaPlayer2AudioOutput::getRoutedDevice() {
+    ALOGV("getRoutedDevice");
     Mutex::Autolock lock(mLock);
-    if (mTrack != 0) {
-        mRoutedDeviceId = mTrack->getRoutedDeviceId();
+    if (mJAudioTrack != nullptr) {
+        return mJAudioTrack->getRoutedDevice();
     }
-    *deviceId = mRoutedDeviceId;
-    return NO_ERROR;
+    return nullptr;
 }
 
-status_t MediaPlayer2AudioOutput::enableAudioDeviceCallback(bool enabled) {
-    ALOGV("enableAudioDeviceCallback, %d", enabled);
+status_t MediaPlayer2AudioOutput::addAudioDeviceCallback(jobject jRoutingDelegate) {
+    ALOGV("addAudioDeviceCallback");
     Mutex::Autolock lock(mLock);
-    mDeviceCallbackEnabled = enabled;
-    if (mTrack != 0) {
-        status_t status;
-        if (enabled) {
-            status = mTrack->addAudioDeviceCallback(mDeviceCallback.promote());
-        } else {
-            status = mTrack->removeAudioDeviceCallback(mDeviceCallback.promote());
+    jobject listener = JAudioTrack::getListener(jRoutingDelegate);
+    if (JAudioTrack::findByKey(mRoutingDelegates, listener) == nullptr) {
+        sp<JObjectHolder> listenerHolder = new JObjectHolder(listener);
+        jobject handler = JAudioTrack::getHandler(jRoutingDelegate);
+        sp<JObjectHolder> routingDelegateHolder = new JObjectHolder(jRoutingDelegate);
+
+        mRoutingDelegates.push_back(std::pair<sp<JObjectHolder>, sp<JObjectHolder>>(
+                listenerHolder, routingDelegateHolder));
+
+        if (mJAudioTrack != nullptr) {
+            return mJAudioTrack->addAudioDeviceCallback(
+                    routingDelegateHolder->getJObject(), handler);
         }
-        return status;
+    }
+    return NO_ERROR;
+}
+
+status_t MediaPlayer2AudioOutput::removeAudioDeviceCallback(jobject listener) {
+    ALOGV("removeAudioDeviceCallback");
+    Mutex::Autolock lock(mLock);
+    jobject routingDelegate = nullptr;
+    if ((routingDelegate = JAudioTrack::findByKey(mRoutingDelegates, listener)) != nullptr) {
+        if (mJAudioTrack != nullptr) {
+            mJAudioTrack->removeAudioDeviceCallback(routingDelegate);
+        }
+        JAudioTrack::eraseByKey(mRoutingDelegates, listener);
     }
     return NO_ERROR;
 }
@@ -632,21 +559,21 @@
     // lock to ensure we aren't caught in the middle of a track switch.
     data->lock();
     MediaPlayer2AudioOutput *me = data->getOutput();
-    AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
-    if (me == NULL) {
+    JAudioTrack::Buffer *buffer = (JAudioTrack::Buffer *)info;
+    if (me == nullptr) {
         // no output set, likely because the track was scheduled to be reused
         // by another player, but the format turned out to be incompatible.
         data->unlock();
-        if (buffer != NULL) {
-            buffer->size = 0;
+        if (buffer != nullptr) {
+            buffer->mSize = 0;
         }
         return;
     }
 
     switch(event) {
-    case AudioTrack::EVENT_MORE_DATA: {
+    case JAudioTrack::EVENT_MORE_DATA: {
         size_t actualSize = (*me->mCallback)(
-                me, buffer->raw, buffer->size, me->mCallbackCookie,
+                me, buffer->mData, buffer->mSize, me->mCallbackCookie,
                 CB_EVENT_FILL_BUFFER);
 
         // Log when no data is returned from the callback.
@@ -658,25 +585,25 @@
         // This is a benign busy-wait, with the next data request generated 10 ms or more later;
         // nevertheless for power reasons, we don't want to see too many of these.
 
-        ALOGV_IF(actualSize == 0 && buffer->size > 0, "callbackwrapper: empty buffer returned");
+        ALOGV_IF(actualSize == 0 && buffer->mSize > 0, "callbackwrapper: empty buffer returned");
 
-        buffer->size = actualSize;
+        buffer->mSize = actualSize;
         } break;
 
-    case AudioTrack::EVENT_STREAM_END:
+    case JAudioTrack::EVENT_STREAM_END:
         // currently only occurs for offloaded callbacks
         ALOGV("callbackwrapper: deliver EVENT_STREAM_END");
-        (*me->mCallback)(me, NULL /* buffer */, 0 /* size */,
+        (*me->mCallback)(me, nullptr /* buffer */, 0 /* size */,
                 me->mCallbackCookie, CB_EVENT_STREAM_END);
         break;
 
-    case AudioTrack::EVENT_NEW_IAUDIOTRACK :
+    case JAudioTrack::EVENT_NEW_IAUDIOTRACK :
         ALOGV("callbackwrapper: deliver EVENT_TEAR_DOWN");
-        (*me->mCallback)(me,  NULL /* buffer */, 0 /* size */,
+        (*me->mCallback)(me,  nullptr /* buffer */, 0 /* size */,
                 me->mCallbackCookie, CB_EVENT_TEAR_DOWN);
         break;
 
-    case AudioTrack::EVENT_UNDERRUN:
+    case JAudioTrack::EVENT_UNDERRUN:
         // This occurs when there is no data available, typically
         // when there is a failure to supply data to the AudioTrack.  It can also
         // occur in non-offloaded mode when the audio device comes out of standby.
@@ -696,29 +623,31 @@
     data->unlock();
 }
 
-audio_session_t MediaPlayer2AudioOutput::getSessionId() const
-{
+int32_t MediaPlayer2AudioOutput::getSessionId() const {
     Mutex::Autolock lock(mLock);
     return mSessionId;
 }
 
-uint32_t MediaPlayer2AudioOutput::getSampleRate() const
-{
+void MediaPlayer2AudioOutput::setSessionId(const int32_t sessionId) {
     Mutex::Autolock lock(mLock);
-    if (mTrack == 0) {
-        return 0;
-    }
-    return mTrack->getSampleRate();
+    mSessionId = sessionId;
 }
 
-int64_t MediaPlayer2AudioOutput::getBufferDurationInUs() const
-{
+uint32_t MediaPlayer2AudioOutput::getSampleRate() const {
     Mutex::Autolock lock(mLock);
-    if (mTrack == 0) {
+    if (mJAudioTrack == 0) {
+        return 0;
+    }
+    return mJAudioTrack->getSampleRate();
+}
+
+int64_t MediaPlayer2AudioOutput::getBufferDurationInUs() const {
+    Mutex::Autolock lock(mLock);
+    if (mJAudioTrack == 0) {
         return 0;
     }
     int64_t duration;
-    if (mTrack->getBufferDurationInUs(&duration) != OK) {
+    if (mJAudioTrack->getBufferDurationInUs(&duration) != OK) {
         return 0;
     }
     return duration;
diff --git a/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h b/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h
index 301825b..2ed4632 100644
--- a/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h
+++ b/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h
@@ -17,19 +17,21 @@
 #ifndef ANDROID_JAUDIOTRACK_H
 #define ANDROID_JAUDIOTRACK_H
 
+#include <utility>
 #include <jni.h>
 #include <media/AudioResamplerPublic.h>
 #include <media/AudioSystem.h>
 #include <media/VolumeShaper.h>
 #include <system/audio.h>
 #include <utils/Errors.h>
-
+#include <utils/Vector.h>
+#include <mediaplayer2/JObjectHolder.h>
 #include <media/AudioTimestamp.h>   // It has dependency on audio.h/Errors.h, but doesn't
                                     // include them in it. Therefore it is included here at last.
 
 namespace android {
 
-class JAudioTrack {
+class JAudioTrack : public RefBase {
 public:
 
     /* Events used by AudioTrack callback function (callback_t).
@@ -37,6 +39,8 @@
      */
     enum event_type {
         EVENT_MORE_DATA = 0,        // Request to write more data to buffer.
+        EVENT_UNDERRUN = 1,         // Buffer underrun occurred. This will not occur for
+                                    // static tracks.
         EVENT_NEW_IAUDIOTRACK = 6,  // IAudioTrack was re-created, either due to re-routing and
                                     // voluntary invalidation by mediaserver, or mediaserver crash.
         EVENT_STREAM_END = 7,       // Sent after all the buffers queued in AF and HW are played
@@ -104,15 +108,14 @@
      *
      * TODO: Revive removed arguments after offload mode is supported.
      */
-    JAudioTrack(audio_stream_type_t streamType,
-                uint32_t sampleRate,
+    JAudioTrack(uint32_t sampleRate,
                 audio_format_t format,
                 audio_channel_mask_t channelMask,
                 callback_t cbf,
                 void* user,
                 size_t frameCount = 0,
-                audio_session_t sessionId  = AUDIO_SESSION_ALLOCATE,
-                const audio_attributes_t* pAttributes = NULL,
+                int32_t sessionId  = AUDIO_SESSION_ALLOCATE,
+                const jobject pAttributes = NULL,
                 float maxRequiredSpeed = 1.0f);
 
     /*
@@ -158,10 +161,10 @@
      * Caution: calling this method too often may be inefficient;
      * if you need a high resolution mapping between frame position and presentation time,
      * consider implementing that at application level, based on the low resolution timestamps.
-     * Returns true if timestamp is valid.
-     * The timestamp parameter is undefined on return, if false is returned.
+     * Returns NO_ERROR if timestamp is valid.
+     *         NO_INIT if finds error, and timestamp parameter will be undefined on return.
      */
-    bool getTimestamp(AudioTimestamp& timestamp);
+    status_t getTimestamp(AudioTimestamp& timestamp);
 
     // TODO: This doc is just copied from AudioTrack.h. Revise it after implemenation.
     /* Return the extended timestamp, with additional timebase info and improved drain behavior.
@@ -324,37 +327,43 @@
 
     audio_format_t format();
 
+    size_t frameSize();
+
     /*
      * Dumps the state of an audio track.
      * Not a general-purpose API; intended only for use by media player service to dump its tracks.
      */
     status_t dump(int fd, const Vector<String16>& args) const;
 
-    /* Returns the ID of the audio device actually used by the output to which this AudioTrack is
-     * attached. When the AudioTrack is inactive, it will return AUDIO_PORT_HANDLE_NONE.
+    /* Returns the AudioDeviceInfo used by the output to which this AudioTrack is
+     * attached.
      */
-    audio_port_handle_t getRoutedDeviceId();
+    jobject getRoutedDevice();
 
     /* Returns the ID of the audio session this AudioTrack belongs to. */
-    audio_session_t getAudioSessionId();
+    int32_t getAudioSessionId();
 
-    /* Selects the audio device to use for output of this AudioTrack. A value of
-     * AUDIO_PORT_HANDLE_NONE indicates default routing.
+    /* Sets the preferred audio device to use for output of this AudioTrack.
      *
      * Parameters:
-     *  The device ID of the selected device (as returned by the AudioDevicesManager API).
+     * Device: an AudioDeviceInfo object.
      *
      * Returned value:
      *  - NO_ERROR: successful operation
-     *  - BAD_VALUE: failed to find the valid output device with given device Id.
+     *  - BAD_VALUE: failed to set the device
      */
-    status_t setOutputDevice(audio_port_handle_t deviceId);
+    status_t setPreferredDevice(jobject device);
 
     // TODO: Add AUDIO_OUTPUT_FLAG_DIRECT when it is possible to check.
     // TODO: Add AUDIO_FLAG_HW_AV_SYNC when it is possible to check.
     /* Returns the flags */
     audio_output_flags_t getFlags() const { return mFlags; }
 
+    /* We don't keep stream type here,
+     * instead, we keep attributes and call getVolumeControlStream() to get stream type
+     */
+    audio_stream_type_t getAudioStreamType();
+
     /* Obtain the pending duration in milliseconds for playback of pure PCM data remaining in
      * AudioTrack.
      *
@@ -369,27 +378,60 @@
      * Replaces any previously installed callback.
      *
      * Parameters:
-     *
-     * callback: The callback interface
+     * Listener: the listener to receive notification of rerouting events.
+     * Handler: the handler to handler the rerouting events.
      *
      * Returns NO_ERROR if successful.
-     *         INVALID_OPERATION if the same callback is already installed.
-     *         NO_INIT or PREMISSION_DENIED if AudioFlinger service is not reachable
-     *         BAD_VALUE if the callback is NULL
+     *         (TODO) INVALID_OPERATION if the same callback is already installed.
+     *         (TODO) NO_INIT or PREMISSION_DENIED if AudioFlinger service is not reachable
+     *         (TODO) BAD_VALUE if the callback is NULL
      */
-    status_t addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback);
+    status_t addAudioDeviceCallback(jobject listener, jobject rd);
 
     /* Removes an AudioDeviceCallback.
      *
      * Parameters:
-     *
-     * callback: The callback interface
+     * Listener: the listener to receive notification of rerouting events.
      *
      * Returns NO_ERROR if successful.
-     *         INVALID_OPERATION if the callback is not installed
-     *         BAD_VALUE if the callback is NULL
+     *         (TODO) INVALID_OPERATION if the callback is not installed
+     *         (TODO) BAD_VALUE if the callback is NULL
      */
-    status_t removeAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback);
+    status_t removeAudioDeviceCallback(jobject listener);
+
+    /* Register all backed-up routing delegates.
+     *
+     * Parameters:
+     * routingDelegates: backed-up routing delegates
+     *
+     */
+    void registerRoutingDelegates(
+            Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& routingDelegates);
+
+    /* get listener from RoutingDelegate object
+     */
+    static jobject getListener(const jobject routingDelegateObj);
+
+    /* get handler from RoutingDelegate object
+     */
+    static jobject getHandler(const jobject routingDelegateObj);
+
+    /*
+     * Parameters:
+     * map and key
+     *
+     * Returns value if key is in the map
+     *         nullptr if key is not in the map
+     */
+    static jobject findByKey(
+            Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& mp, const jobject key);
+
+    /*
+     * Parameters:
+     * map and key
+     */
+    static void eraseByKey(
+            Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& mp, const jobject key);
 
 private:
     audio_output_flags_t mFlags;
diff --git a/media/libmediaplayer2/include/mediaplayer2/JMedia2HTTPConnection.h b/media/libmediaplayer2/include/mediaplayer2/JMedia2HTTPConnection.h
new file mode 100644
index 0000000..15f7f83
--- /dev/null
+++ b/media/libmediaplayer2/include/mediaplayer2/JMedia2HTTPConnection.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _J_MEDIA2_HTTP_CONNECTION_H_
+#define _J_MEDIA2_HTTP_CONNECTION_H_
+
+#include "jni.h"
+
+#include <media/MediaHTTPConnection.h>
+#include <media/stagefright/foundation/ABase.h>
+
+namespace android {
+
+struct JMedia2HTTPConnection : public MediaHTTPConnection {
+    JMedia2HTTPConnection(JNIEnv *env, jobject thiz);
+
+    virtual bool connect(
+            const char *uri, const KeyedVector<String8, String8> *headers) override;
+
+    virtual void disconnect() override;
+    virtual ssize_t readAt(off64_t offset, void *data, size_t size) override;
+    virtual off64_t getSize() override;
+    virtual status_t getMIMEType(String8 *mimeType) override;
+    virtual status_t getUri(String8 *uri) override;
+
+protected:
+    virtual ~JMedia2HTTPConnection();
+
+private:
+    jobject mMedia2HTTPConnectionObj;
+    jmethodID mConnectMethod;
+    jmethodID mDisconnectMethod;
+    jmethodID mReadAtMethod;
+    jmethodID mGetSizeMethod;
+    jmethodID mGetMIMETypeMethod;
+    jmethodID mGetUriMethod;
+
+    jbyteArray mByteArrayObj;
+
+    DISALLOW_EVIL_CONSTRUCTORS(JMedia2HTTPConnection);
+};
+
+}  // namespace android
+
+#endif  // _J_MEDIA2_HTTP_CONNECTION_H_
diff --git a/media/libmediaplayer2/include/mediaplayer2/JMedia2HTTPService.h b/media/libmediaplayer2/include/mediaplayer2/JMedia2HTTPService.h
new file mode 100644
index 0000000..bf61a7f
--- /dev/null
+++ b/media/libmediaplayer2/include/mediaplayer2/JMedia2HTTPService.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _J_MEDIA2_HTTP_SERVICE_H_
+#define _J_MEDIA2_HTTP_SERVICE_H_
+
+#include <jni.h>
+#include <utils/RefBase.h>
+
+#include <media/MediaHTTPService.h>
+#include <media/MediaHTTPConnection.h>
+#include <media/stagefright/foundation/ABase.h>
+
+namespace android {
+
+struct JMedia2HTTPService : public MediaHTTPService {
+    JMedia2HTTPService(JNIEnv *env, jobject thiz);
+
+    virtual sp<MediaHTTPConnection> makeHTTPConnection() override;
+
+protected:
+    virtual ~JMedia2HTTPService();
+
+private:
+    jobject mMedia2HTTPServiceObj;
+
+    jmethodID mMakeHTTPConnectionMethod;
+
+    DISALLOW_EVIL_CONSTRUCTORS(JMedia2HTTPService);
+};
+
+}  // namespace android
+
+#endif  // _J_MEDIA2_HTTP_SERVICE_H_
diff --git a/media/libmediaplayer2/include/mediaplayer2/JObjectHolder.h b/media/libmediaplayer2/include/mediaplayer2/JObjectHolder.h
new file mode 100644
index 0000000..93d8b40
--- /dev/null
+++ b/media/libmediaplayer2/include/mediaplayer2/JObjectHolder.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef JOBJECT_HOLDER_H_
+
+#define JOBJECT_HOLDER_H_
+
+#include "jni.h"
+#include <mediaplayer2/JavaVMHelper.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+// Helper class for managing global reference of jobject.
+struct JObjectHolder : public RefBase {
+    JObjectHolder(jobject obj) {
+        JNIEnv *env = JavaVMHelper::getJNIEnv();
+        mJObject = reinterpret_cast<jobject>(env->NewGlobalRef(obj));
+    }
+
+    virtual ~JObjectHolder() {
+        JNIEnv *env = JavaVMHelper::getJNIEnv();
+        env->DeleteGlobalRef(mJObject);
+    }
+
+    jobject getJObject() { return mJObject; }
+
+private:
+    jobject mJObject;
+};
+
+}  //" android
+
+#endif  // JOBJECT_HOLDER_H_
diff --git a/media/libmediaplayer2/include/mediaplayer2/JavaVMHelper.h b/media/libmediaplayer2/include/mediaplayer2/JavaVMHelper.h
new file mode 100644
index 0000000..4b56aca
--- /dev/null
+++ b/media/libmediaplayer2/include/mediaplayer2/JavaVMHelper.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef JAVA_VM_HELPER_H_
+
+#define JAVA_VM_HELPER_H_
+
+#include "jni.h"
+
+#include <atomic>
+
+namespace android {
+
+struct JavaVMHelper {
+    static JNIEnv *getJNIEnv();
+    static JavaVM *getJavaVM();
+    static void setJavaVM(JavaVM *vm);
+
+private:
+    // Once a valid JavaVM has been set, it should never be reset or changed.
+    // However, as it may be accessed from multiple threads, access needs to be
+    // synchronized.
+    static std::atomic<JavaVM *> sJavaVM;
+};
+
+}  // namespace android
+
+#endif  // JAVA_VM_HELPER_H_
diff --git a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h
index 5d5b8e4..f38b7cc 100644
--- a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h
+++ b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h
@@ -19,10 +19,15 @@
 #define ANDROID_MEDIAPLAYER2AUDIOOUTPUT_H
 
 #include <mediaplayer2/MediaPlayer2Interface.h>
+#include <mediaplayer2/JAudioTrack.h>
+#include <mediaplayer2/JObjectHolder.h>
 
+#include <utility>
 #include <utils/String16.h>
 #include <utils/Vector.h>
 
+#include "jni.h"
+
 namespace android {
 
 class AudioTrack;
@@ -32,15 +37,14 @@
     class CallbackData;
 
 public:
-    MediaPlayer2AudioOutput(audio_session_t sessionId,
+    MediaPlayer2AudioOutput(int32_t sessionId,
                             uid_t uid,
                             int pid,
-                            const audio_attributes_t * attr,
-                            const sp<AudioSystem::AudioDeviceCallback>& deviceCallback);
+                            const jobject attributes);
     virtual ~MediaPlayer2AudioOutput();
 
     virtual bool ready() const {
-        return mTrack != 0;
+        return mJAudioTrack != nullptr;
     }
     virtual ssize_t bufferSize() const;
     virtual ssize_t frameCount() const;
@@ -52,17 +56,17 @@
     virtual status_t getTimestamp(AudioTimestamp &ts) const;
     virtual int64_t getPlayedOutDurationUs(int64_t nowUs) const;
     virtual status_t getFramesWritten(uint32_t *frameswritten) const;
-    virtual audio_session_t getSessionId() const;
+    virtual int32_t getSessionId() const;
+    virtual void setSessionId(const int32_t id);
     virtual uint32_t getSampleRate() const;
     virtual int64_t getBufferDurationInUs() const;
 
     virtual status_t open(
             uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
-            audio_format_t format, int bufferCount,
+            audio_format_t format,
             AudioCallback cb, void *cookie,
             audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
             const audio_offload_info_t *offloadInfo = NULL,
-            bool doNotReconnect = false,
             uint32_t suggestedFrameCount = 0);
 
     virtual status_t start();
@@ -71,13 +75,10 @@
     virtual void flush();
     virtual void pause();
     virtual void close();
-    void setAudioStreamType(audio_stream_type_t streamType);
-    virtual audio_stream_type_t getAudioStreamType() const {
-        return mStreamType;
-    }
-    void setAudioAttributes(const audio_attributes_t * attributes);
+    void setAudioAttributes(const jobject attributes);
+    virtual audio_stream_type_t getAudioStreamType() const;
 
-    void setVolume(float left, float right);
+    void setVolume(float volume);
     virtual status_t setPlaybackRate(const AudioPlaybackRate& rate);
     virtual status_t getPlaybackRate(AudioPlaybackRate* rate /* nonnull */);
 
@@ -92,13 +93,11 @@
         // TODO: return correct value.
         //return mNextOutput == NULL;
     }
-    virtual status_t setParameters(const String8& keyValuePairs);
-    virtual String8 getParameters(const String8& keys);
-
     // AudioRouting
-    virtual status_t setOutputDevice(audio_port_handle_t deviceId);
-    virtual status_t getRoutedDeviceId(audio_port_handle_t* deviceId);
-    virtual status_t enableAudioDeviceCallback(bool enabled);
+    virtual status_t setPreferredDevice(jobject device);
+    virtual jobject getRoutedDevice();
+    virtual status_t addAudioDeviceCallback(jobject routingDelegate);
+    virtual status_t removeAudioDeviceCallback(jobject listener);
 
 private:
     static void setMinBufferCount();
@@ -107,30 +106,28 @@
     void close_l();
     status_t updateTrack_l();
 
-    sp<AudioTrack>          mTrack;
+    sp<JAudioTrack>         mJAudioTrack;
     AudioCallback           mCallback;
     void *                  mCallbackCookie;
     CallbackData *          mCallbackData;
-    audio_stream_type_t     mStreamType;
-    audio_attributes_t *    mAttributes;
-    float                   mLeftVolume;
-    float                   mRightVolume;
+    sp<JObjectHolder>       mAttributes;
+    float                   mVolume;
     AudioPlaybackRate       mPlaybackRate;
     uint32_t                mSampleRateHz; // sample rate of the content, as set in open()
     float                   mMsecsPerFrame;
     size_t                  mFrameSize;
-    audio_session_t         mSessionId;
+    int32_t                 mSessionId;
     uid_t                   mUid;
     int                     mPid;
     float                   mSendLevel;
     int                     mAuxEffectId;
     audio_output_flags_t    mFlags;
-    audio_port_handle_t     mSelectedDeviceId;
-    audio_port_handle_t     mRoutedDeviceId;
-    bool                    mDeviceCallbackEnabled;
-    wp<AudioSystem::AudioDeviceCallback>        mDeviceCallback;
+    sp<JObjectHolder>       mPreferredDevice;
     mutable Mutex           mLock;
 
+    // <listener, routingDelegate>
+    Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>> mRoutingDelegates;
+
     // static variables below not protected by mutex
     static bool             mIsOnEmulator;
     static int              mMinBufferCount;  // 12 for emulator; otherwise 4
diff --git a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Interface.h b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Interface.h
index 02bf891..7804a62 100644
--- a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Interface.h
+++ b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Interface.h
@@ -23,16 +23,21 @@
 #include <utils/Errors.h>
 #include <utils/String8.h>
 #include <utils/RefBase.h>
+#include <jni.h>
 
 #include <media/AVSyncSettings.h>
 #include <media/AudioResamplerPublic.h>
 #include <media/AudioSystem.h>
 #include <media/AudioTimestamp.h>
 #include <media/BufferingSettings.h>
-#include <media/Metadata.h>
 #include <media/stagefright/foundation/AHandler.h>
 #include <mediaplayer2/MediaPlayer2Types.h>
 
+#include "jni.h"
+#include "mediaplayer2.pb.h"
+
+using android::media::MediaPlayer2Proto::PlayerMessage;
+
 // Fwd decl to make sure everyone agrees that the scope of struct sockaddr_in is
 // global, and not in android::
 struct sockaddr_in;
@@ -43,7 +48,6 @@
 class Parcel;
 struct ANativeWindowWrapper;
 
-#define DEFAULT_AUDIOSINK_BUFFERCOUNT 4
 #define DEFAULT_AUDIOSINK_BUFFERSIZE 1200
 #define DEFAULT_AUDIOSINK_SAMPLERATE 44100
 
@@ -56,7 +60,8 @@
 class MediaPlayer2InterfaceListener: public RefBase
 {
 public:
-    virtual void notify(int64_t srcId, int msg, int ext1, int ext2, const Parcel *obj) = 0;
+    virtual void notify(int64_t srcId, int msg, int ext1, int ext2,
+           const PlayerMessage *obj) = 0;
 };
 
 class MediaPlayer2Interface : public AHandler {
@@ -88,7 +93,7 @@
         virtual status_t getTimestamp(AudioTimestamp &ts) const = 0;
         virtual int64_t getPlayedOutDurationUs(int64_t nowUs) const = 0;
         virtual status_t getFramesWritten(uint32_t *frameswritten) const = 0;
-        virtual audio_session_t getSessionId() const = 0;
+        virtual int32_t getSessionId() const = 0;
         virtual audio_stream_type_t getAudioStreamType() const = 0;
         virtual uint32_t getSampleRate() const = 0;
         virtual int64_t getBufferDurationInUs() const = 0;
@@ -98,12 +103,10 @@
         virtual status_t open(
                 uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
                 audio_format_t format=AUDIO_FORMAT_PCM_16_BIT,
-                int bufferCount=DEFAULT_AUDIOSINK_BUFFERCOUNT,
                 AudioCallback cb = NULL,
                 void *cookie = NULL,
                 audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
                 const audio_offload_info_t *offloadInfo = NULL,
-                bool doNotReconnect = false,
                 uint32_t suggestedFrameCount = 0) = 0;
 
         virtual status_t start() = 0;
@@ -139,9 +142,10 @@
         }
 
         // AudioRouting
-        virtual status_t    setOutputDevice(audio_port_handle_t deviceId);
-        virtual status_t    getRoutedDeviceId(audio_port_handle_t* deviceId);
-        virtual status_t    enableAudioDeviceCallback(bool enabled);
+        virtual status_t    setPreferredDevice(jobject device);
+        virtual jobject     getRoutedDevice();
+        virtual status_t    addAudioDeviceCallback(jobject routingDelegate);
+        virtual status_t    removeAudioDeviceCallback(jobject listener);
     };
 
     MediaPlayer2Interface() : mListener(NULL) { }
@@ -171,7 +175,6 @@
 
     virtual status_t prepareAsync() = 0;
     virtual status_t start() = 0;
-    virtual status_t stop() = 0;
     virtual status_t pause() = 0;
     virtual bool isPlaying() = 0;
     virtual status_t setPlaybackSettings(const AudioPlaybackRate& rate) {
@@ -211,6 +214,8 @@
     virtual status_t setParameter(int key, const Parcel &request) = 0;
     virtual status_t getParameter(int key, Parcel *reply) = 0;
 
+    virtual status_t getMetrics(char **buffer, size_t *length) = 0;
+
     // Invoke a generic method on the player by using opaque parcels
     // for the request and reply.
     //
@@ -218,26 +223,14 @@
     //                data sent by the java layer.
     // @param[out] reply Parcel to hold the reply data. Cannot be null.
     // @return OK if the call was successful.
-    virtual status_t invoke(const Parcel& request, Parcel *reply) = 0;
-
-    // The Client in the MetadataPlayerService calls this method on
-    // the native player to retrieve all or a subset of metadata.
-    //
-    // @param ids SortedList of metadata ID to be fetch. If empty, all
-    //            the known metadata should be returned.
-    // @param[inout] records Parcel where the player appends its metadata.
-    // @return OK if the call was successful.
-    virtual status_t getMetadata(const media::Metadata::Filter& /* ids */,
-                                 Parcel* /* records */) {
-        return INVALID_OPERATION;
-    };
+    virtual status_t invoke(const PlayerMessage &request, PlayerMessage *reply) = 0;
 
     void setListener(const sp<MediaPlayer2InterfaceListener> &listener) {
         Mutex::Autolock autoLock(mListenerLock);
         mListener = listener;
     }
 
-    void sendEvent(int64_t srcId, int msg, int ext1=0, int ext2=0, const Parcel *obj=NULL) {
+    void sendEvent(int64_t srcId, int msg, int ext1=0, int ext2=0, const PlayerMessage *obj=NULL) {
         sp<MediaPlayer2InterfaceListener> listener;
         {
             Mutex::Autolock autoLock(mListenerLock);
@@ -256,11 +249,11 @@
     virtual void onMessageReceived(const sp<AMessage> & /* msg */) override { }
 
     // Modular DRM
-    virtual status_t prepareDrm(const uint8_t /* uuid */[16],
+    virtual status_t prepareDrm(int64_t /*srcId*/, const uint8_t /* uuid */[16],
                                 const Vector<uint8_t>& /* drmSessionId */) {
         return INVALID_OPERATION;
     }
-    virtual status_t releaseDrm() {
+    virtual status_t releaseDrm(int64_t /*srcId*/) {
         return INVALID_OPERATION;
     }
 
diff --git a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Types.h b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Types.h
index 3905b55..2430289 100644
--- a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Types.h
+++ b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Types.h
@@ -34,8 +34,7 @@
     MEDIA2_SET_VIDEO_SIZE    = 5,
     MEDIA2_STARTED           = 6,
     MEDIA2_PAUSED            = 7,
-    MEDIA2_STOPPED           = 8,
-    MEDIA2_SKIPPED           = 9,
+    MEDIA2_SKIPPED           = 8,
     MEDIA2_NOTIFY_TIME       = 98,
     MEDIA2_TIMED_TEXT        = 99,
     MEDIA2_ERROR             = 100,
@@ -43,7 +42,6 @@
     MEDIA2_SUBTITLE_DATA     = 201,
     MEDIA2_META_DATA         = 202,
     MEDIA2_DRM_INFO          = 210,
-    MEDIA2_AUDIO_ROUTING_CHANGED = 10000,
 };
 
 // Generic error codes for the media player framework.  Errors are fatal, the
@@ -96,17 +94,20 @@
 enum media2_info_type {
     // 0xx
     MEDIA2_INFO_UNKNOWN = 1,
-    // The player was started because it was used as the next player for another
-    // player, which just completed playback
-    MEDIA2_INFO_STARTED_AS_NEXT = 2,
+    // The player just started the playback of this data source.
+    MEDIA2_INFO_DATA_SOURCE_START = 2,
     // The player just pushed the very first video frame for rendering
     MEDIA2_INFO_VIDEO_RENDERING_START = 3,
     // The player just pushed the very first audio frame for rendering
     MEDIA2_INFO_AUDIO_RENDERING_START = 4,
     // The player just completed the playback of this data source
-    MEDIA2_INFO_PLAYBACK_COMPLETE = 5,
-    // The player just completed the playback of the full play list
-    MEDIA2_INFO_PLAYLIST_END = 6,
+    MEDIA2_INFO_DATA_SOURCE_END = 5,
+    // The player just completed the playback of all data sources.
+    // But this is not visible in native code. Just keep this entry for completeness.
+    MEDIA2_INFO_DATA_SOURCE_LIST_END = 6,
+    // The player just completed an iteration of playback loop. This event is sent only when
+    // looping is enabled.
+    MEDIA2_INFO_DATA_SOURCE_REPEAT = 7,
 
     //1xx
     // The player just prepared a data source.
@@ -150,11 +151,11 @@
 
 // Do not change these values without updating their counterparts in MediaPlayer2.java
 enum mediaplayer2_states {
-    MEDIAPLAYER2_STATE_IDLE         = 1,
-    MEDIAPLAYER2_STATE_PREPARED     = 2,
-    MEDIAPLAYER2_STATE_PLAYING      = 3,
-    MEDIAPLAYER2_STATE_PAUSED       = 4,
-    MEDIAPLAYER2_STATE_ERROR        = 5,
+    MEDIAPLAYER2_STATE_IDLE         = 1001,
+    MEDIAPLAYER2_STATE_PREPARED     = 1002,
+    MEDIAPLAYER2_STATE_PAUSED       = 1003,
+    MEDIAPLAYER2_STATE_PLAYING      = 1004,
+    MEDIAPLAYER2_STATE_ERROR        = 1005,
 };
 
 enum media_player2_internal_states {
@@ -165,8 +166,7 @@
     MEDIA_PLAYER2_PREPARED           = 1 << 3,
     MEDIA_PLAYER2_STARTED            = 1 << 4,
     MEDIA_PLAYER2_PAUSED             = 1 << 5,
-    MEDIA_PLAYER2_STOPPED            = 1 << 6,
-    MEDIA_PLAYER2_PLAYBACK_COMPLETE  = 1 << 7
+    MEDIA_PLAYER2_PLAYBACK_COMPLETE  = 1 << 6
 };
 
 // Keep KEY_PARAMETER_* in sync with MediaPlayer2.java.
diff --git a/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h b/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
index d586192..1e8a1d5 100644
--- a/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
+++ b/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
@@ -20,11 +20,12 @@
 #include <media/AVSyncSettings.h>
 #include <media/AudioResamplerPublic.h>
 #include <media/BufferingSettings.h>
-#include <media/Metadata.h>
 #include <media/mediaplayer_common.h>
 #include <mediaplayer2/MediaPlayer2Interface.h>
 #include <mediaplayer2/MediaPlayer2Types.h>
+#include <mediaplayer2/JObjectHolder.h>
 
+#include <jni.h>
 #include <utils/Errors.h>
 #include <utils/Mutex.h>
 #include <utils/RefBase.h>
@@ -32,6 +33,8 @@
 #include <utils/Vector.h>
 #include <system/audio-base.h>
 
+#include "jni.h"
+
 namespace android {
 
 struct ANativeWindowWrapper;
@@ -42,7 +45,8 @@
 class MediaPlayer2Listener: virtual public RefBase
 {
 public:
-    virtual void notify(int64_t srcId, int msg, int ext1, int ext2, const Parcel *obj) = 0;
+    virtual void notify(int64_t srcId, int msg, int ext1, int ext2,
+            const PlayerMessage *obj = NULL) = 0;
 };
 
 class MediaPlayer2 : public MediaPlayer2InterfaceListener
@@ -50,7 +54,7 @@
 public:
     ~MediaPlayer2();
 
-    static sp<MediaPlayer2> Create();
+    static sp<MediaPlayer2> Create(int32_t sessionId, jobject context);
     static status_t DumpAll(int fd, const Vector<String16>& args);
 
             void            disconnect();
@@ -65,10 +69,9 @@
             status_t        setBufferingSettings(const BufferingSettings& buffering);
             status_t        prepareAsync();
             status_t        start();
-            status_t        stop();
             status_t        pause();
             bool            isPlaying();
-            mediaplayer2_states getMediaPlayer2State();
+            mediaplayer2_states getState();
             status_t        setPlaybackSettings(const AudioPlaybackRate& rate);
             status_t        getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */);
             status_t        setSyncSettings(const AVSyncSettings& sync, float videoFpsHint);
@@ -82,60 +85,53 @@
                     MediaPlayer2SeekMode mode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC);
             status_t        notifyAt(int64_t mediaTimeUs);
             status_t        getCurrentPosition(int64_t *msec);
-            status_t        getDuration(int64_t *msec);
+            status_t        getDuration(int64_t srcId, int64_t *msec);
             status_t        reset();
             status_t        setAudioStreamType(audio_stream_type_t type);
             status_t        getAudioStreamType(audio_stream_type_t *type);
             status_t        setLooping(int loop);
             bool            isLooping();
-            status_t        setVolume(float leftVolume, float rightVolume);
+            status_t        setVolume(float volume);
             void            notify(int64_t srcId, int msg, int ext1, int ext2,
-                                   const Parcel *obj = NULL);
-            status_t        invoke(const Parcel& request, Parcel *reply);
-            status_t        setMetadataFilter(const Parcel& filter);
-            status_t        getMetadata(bool update_only, bool apply_filter, Parcel *metadata);
-            status_t        setAudioSessionId(audio_session_t sessionId);
-            audio_session_t getAudioSessionId();
+                                   const PlayerMessage *obj = NULL);
+            status_t        invoke(const PlayerMessage &request, PlayerMessage *reply);
+            status_t        setAudioSessionId(int32_t sessionId);
+            int32_t         getAudioSessionId();
             status_t        setAuxEffectSendLevel(float level);
             status_t        attachAuxEffect(int effectId);
-            status_t        setParameter(int key, const Parcel& request);
+            status_t        setAudioAttributes(const jobject attributes);
+            jobject         getAudioAttributes();
             status_t        getParameter(int key, Parcel* reply);
+            status_t        getMetrics(char **buffer, size_t *length);
 
             // Modular DRM
-            status_t        prepareDrm(const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId);
-            status_t        releaseDrm();
+            status_t        prepareDrm(int64_t srcId,
+                                       const uint8_t uuid[16],
+                                       const Vector<uint8_t>& drmSessionId);
+            status_t        releaseDrm(int64_t srcId);
             // AudioRouting
-            status_t        setOutputDevice(audio_port_handle_t deviceId);
-            audio_port_handle_t getRoutedDeviceId();
-            status_t        enableAudioDeviceCallback(bool enabled);
+            status_t        setPreferredDevice(jobject device);
+            jobject         getRoutedDevice();
+            status_t        addAudioDeviceCallback(jobject routingDelegate);
+            status_t        removeAudioDeviceCallback(jobject listener);
 
             status_t        dump(int fd, const Vector<String16>& args);
 
 private:
-    MediaPlayer2();
+    MediaPlayer2(int32_t sessionId, jobject context);
     bool init();
 
-    // @param type Of the metadata to be tested.
-    // @return true if the metadata should be dropped according to
-    //              the filters.
-    bool shouldDropMetadata(media::Metadata::Type type) const;
-
-    // Add a new element to the set of metadata updated. Noop if
-    // the element exists already.
-    // @param type Of the metadata to be recorded.
-    void addNewMetadataUpdate(media::Metadata::Type type);
-
     // Disconnect from the currently connected ANativeWindow.
     void disconnectNativeWindow_l();
 
-    status_t setAudioAttributes_l(const Parcel &request);
+    status_t setAudioAttributes_l(const jobject attributes);
 
     void clear_l();
     status_t seekTo_l(int64_t msec, MediaPlayer2SeekMode mode);
     status_t prepareAsync_l();
     status_t getDuration_l(int64_t *msec);
     status_t reset_l();
-    status_t checkStateForKeySet_l(int key);
+    status_t checkState_l();
 
     pid_t                       mPid;
     uid_t                       mUid;
@@ -147,32 +143,21 @@
     Mutex                       mNotifyLock;
     sp<MediaPlayer2Listener>    mListener;
     media_player2_internal_states mCurrentState;
+    bool                        mTransitionToNext;
     int64_t                     mCurrentPosition;
     MediaPlayer2SeekMode        mCurrentSeekMode;
     int64_t                     mSeekPosition;
     MediaPlayer2SeekMode        mSeekMode;
     audio_stream_type_t         mStreamType;
-    Parcel*                     mAudioAttributesParcel;
     bool                        mLoop;
-    float                       mLeftVolume;
-    float                       mRightVolume;
+    float                       mVolume;
     int                         mVideoWidth;
     int                         mVideoHeight;
-    audio_session_t             mAudioSessionId;
-    audio_attributes_t *        mAudioAttributes;
+    int32_t                     mAudioSessionId;
+    sp<JObjectHolder>           mAudioAttributes;
+    sp<JObjectHolder>           mContext;
     float                       mSendLevel;
-
     sp<ANativeWindowWrapper>    mConnectedWindow;
-
-    // Metadata filters.
-    media::Metadata::Filter mMetadataAllow;  // protected by mLock
-    media::Metadata::Filter mMetadataDrop;  // protected by mLock
-
-    // Metadata updated. For each MEDIA_INFO_METADATA_UPDATE
-    // notification we try to update mMetadataUpdated which is a
-    // set: no duplicate.
-    // getMetadata clears this set.
-    media::Metadata::Filter mMetadataUpdated;  // protected by mLock
 };
 
 }; // namespace android
diff --git a/media/libmediaplayer2/mediaplayer2.cpp b/media/libmediaplayer2/mediaplayer2.cpp
index e5567dc..de65f8d 100644
--- a/media/libmediaplayer2/mediaplayer2.cpp
+++ b/media/libmediaplayer2/mediaplayer2.cpp
@@ -18,14 +18,10 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "MediaPlayer2Native"
 
-#include <binder/IServiceManager.h>
-#include <binder/IPCThreadState.h>
-
+#include <android/binder_ibinder.h>
 #include <media/AudioSystem.h>
 #include <media/DataSourceDesc.h>
-#include <media/MediaAnalyticsItem.h>
 #include <media/MemoryLeakTrackUtil.h>
-#include <media/Metadata.h>
 #include <media/NdkWrapper.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ALooperRoster.h>
@@ -53,169 +49,6 @@
 const int kDumpLockRetries = 50;
 const int kDumpLockSleepUs = 20000;
 
-// Max number of entries in the filter.
-const int kMaxFilterSize = 64;  // I pulled that out of thin air.
-
-// FIXME: Move all the metadata related function in the Metadata.cpp
-
-// Unmarshall a filter from a Parcel.
-// Filter format in a parcel:
-//
-//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// |                       number of entries (n)                   |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// |                       metadata type 1                         |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// |                       metadata type 2                         |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-//  ....
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// |                       metadata type n                         |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-//
-// @param p Parcel that should start with a filter.
-// @param[out] filter On exit contains the list of metadata type to be
-//                    filtered.
-// @param[out] status On exit contains the status code to be returned.
-// @return true if the parcel starts with a valid filter.
-bool unmarshallFilter(const Parcel& p,
-                      media::Metadata::Filter *filter,
-                      status_t *status) {
-    int32_t val;
-    if (p.readInt32(&val) != OK) {
-        ALOGE("Failed to read filter's length");
-        *status = NOT_ENOUGH_DATA;
-        return false;
-    }
-
-    if (val > kMaxFilterSize || val < 0) {
-        ALOGE("Invalid filter len %d", val);
-        *status = BAD_VALUE;
-        return false;
-    }
-
-    const size_t num = val;
-
-    filter->clear();
-    filter->setCapacity(num);
-
-    size_t size = num * sizeof(media::Metadata::Type);
-
-
-    if (p.dataAvail() < size) {
-        ALOGE("Filter too short expected %zu but got %zu", size, p.dataAvail());
-        *status = NOT_ENOUGH_DATA;
-        return false;
-    }
-
-    const media::Metadata::Type *data =
-        static_cast<const media::Metadata::Type*>(p.readInplace(size));
-
-    if (NULL == data) {
-        ALOGE("Filter had no data");
-        *status = BAD_VALUE;
-        return false;
-    }
-
-    // TODO: The stl impl of vector would be more efficient here
-    // because it degenerates into a memcpy on pod types. Try to
-    // replace later or use stl::set.
-    for (size_t i = 0; i < num; ++i) {
-        filter->add(*data);
-        ++data;
-    }
-    *status = OK;
-    return true;
-}
-
-// @param filter Of metadata type.
-// @param val To be searched.
-// @return true if a match was found.
-bool findMetadata(const media::Metadata::Filter& filter, const int32_t val) {
-    // Deal with empty and ANY right away
-    if (filter.isEmpty()) {
-        return false;
-    }
-    if (filter[0] == media::Metadata::kAny) {
-        return true;
-    }
-
-    return filter.indexOf(val) >= 0;
-}
-
-// marshalling tag indicating flattened utf16 tags
-// keep in sync with frameworks/base/media/java/android/media/AudioAttributes.java
-const int32_t kAudioAttributesMarshallTagFlattenTags = 1;
-
-// Audio attributes format in a parcel:
-//
-//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// |                       usage                                   |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// |                       content_type                            |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// |                       source                                  |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// |                       flags                                   |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// |                       kAudioAttributesMarshallTagFlattenTags  | // ignore tags if not found
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// |                       flattened tags in UTF16                 |
-// |                         ...                                   |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-//
-// @param p Parcel that contains audio attributes.
-// @param[out] attributes On exit points to an initialized audio_attributes_t structure
-// @param[out] status On exit contains the status code to be returned.
-void unmarshallAudioAttributes(const Parcel& parcel, audio_attributes_t *attributes) {
-    attributes->usage = (audio_usage_t) parcel.readInt32();
-    attributes->content_type = (audio_content_type_t) parcel.readInt32();
-    attributes->source = (audio_source_t) parcel.readInt32();
-    attributes->flags = (audio_flags_mask_t) parcel.readInt32();
-    const bool hasFlattenedTag = (parcel.readInt32() == kAudioAttributesMarshallTagFlattenTags);
-    if (hasFlattenedTag) {
-        // the tags are UTF16, convert to UTF8
-        String16 tags = parcel.readString16();
-        ssize_t realTagSize = utf16_to_utf8_length(tags.string(), tags.size());
-        if (realTagSize <= 0) {
-            strcpy(attributes->tags, "");
-        } else {
-            // copy the flattened string into the attributes as the destination for the conversion:
-            // copying array size -1, array for tags was calloc'd, no need to NULL-terminate it
-            size_t tagSize = realTagSize > AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 ?
-                    AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 : realTagSize;
-            utf16_to_utf8(tags.string(), tagSize, attributes->tags,
-                    sizeof(attributes->tags) / sizeof(attributes->tags[0]));
-        }
-    } else {
-        ALOGE("unmarshallAudioAttributes() received unflattened tags, ignoring tag values");
-        strcpy(attributes->tags, "");
-    }
-}
-
-class AudioDeviceUpdatedNotifier: public AudioSystem::AudioDeviceCallback {
-public:
-    AudioDeviceUpdatedNotifier(const sp<MediaPlayer2Interface>& listener)
-        : mListener(listener) { }
-
-    ~AudioDeviceUpdatedNotifier() { }
-
-    virtual void onAudioDeviceUpdate(audio_io_handle_t audioIo,
-                                     audio_port_handle_t deviceId) override {
-        sp<MediaPlayer2Interface> listener = mListener.promote();
-        if (listener != NULL) {
-            listener->sendEvent(0, MEDIA2_AUDIO_ROUTING_CHANGED, audioIo, deviceId);
-        } else {
-            ALOGW("listener for process %d death is gone", MEDIA2_AUDIO_ROUTING_CHANGED);
-        }
-    }
-
-private:
-    wp<MediaPlayer2Interface> mListener;
-};
-
 class proxyListener : public MediaPlayer2InterfaceListener {
 public:
     proxyListener(const wp<MediaPlayer2> &player)
@@ -223,7 +56,8 @@
 
     ~proxyListener() { };
 
-    virtual void notify(int64_t srcId, int msg, int ext1, int ext2, const Parcel *obj) override {
+    virtual void notify(int64_t srcId, int msg, int ext1, int ext2,
+            const PlayerMessage *obj) override {
         sp<MediaPlayer2> player = mPlayer.promote();
         if (player != NULL) {
             player->notify(srcId, msg, ext1, ext2, obj);
@@ -265,114 +99,110 @@
     String8 result;
     SortedVector< sp<MediaPlayer2> > players; //to serialise the mutex unlock & client destruction.
 
-    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
-        snprintf(buffer, SIZE, "Permission Denial: can't dump MediaPlayer2\n");
-        result.append(buffer);
+    {
+        Mutex::Autolock lock(sRecordLock);
+        ensureInit_l();
+        for (int i = 0, n = sPlayers->size(); i < n; ++i) {
+            sp<MediaPlayer2> p = (*sPlayers)[i].promote();
+            if (p != 0) {
+                p->dump(fd, args);
+            }
+            players.add(p);
+        }
+    }
+
+    result.append(" Files opened and/or mapped:\n");
+    snprintf(buffer, SIZE, "/proc/%d/maps", getpid());
+    FILE *f = fopen(buffer, "r");
+    if (f) {
+        while (!feof(f)) {
+            fgets(buffer, SIZE, f);
+            if (strstr(buffer, " /storage/") ||
+                strstr(buffer, " /system/sounds/") ||
+                strstr(buffer, " /data/") ||
+                strstr(buffer, " /system/media/")) {
+                result.append("  ");
+                result.append(buffer);
+            }
+        }
+        fclose(f);
     } else {
-        {
-            Mutex::Autolock lock(sRecordLock);
-            ensureInit_l();
-            for (int i = 0, n = sPlayers->size(); i < n; ++i) {
-                sp<MediaPlayer2> p = (*sPlayers)[i].promote();
-                if (p != 0) {
-                    p->dump(fd, args);
-                }
-                players.add(p);
-            }
-        }
+        result.append("couldn't open ");
+        result.append(buffer);
+        result.append("\n");
+    }
 
-        result.append(" Files opened and/or mapped:\n");
-        snprintf(buffer, SIZE, "/proc/%d/maps", getpid());
-        FILE *f = fopen(buffer, "r");
-        if (f) {
-            while (!feof(f)) {
-                fgets(buffer, SIZE, f);
-                if (strstr(buffer, " /storage/") ||
-                    strstr(buffer, " /system/sounds/") ||
-                    strstr(buffer, " /data/") ||
-                    strstr(buffer, " /system/media/")) {
-                    result.append("  ");
-                    result.append(buffer);
-                }
-            }
-            fclose(f);
-        } else {
-            result.append("couldn't open ");
-            result.append(buffer);
-            result.append("\n");
-        }
-
-        snprintf(buffer, SIZE, "/proc/%d/fd", getpid());
-        DIR *d = opendir(buffer);
-        if (d) {
-            struct dirent *ent;
-            while((ent = readdir(d)) != NULL) {
-                if (strcmp(ent->d_name,".") && strcmp(ent->d_name,"..")) {
-                    snprintf(buffer, SIZE, "/proc/%d/fd/%s", getpid(), ent->d_name);
-                    struct stat s;
-                    if (lstat(buffer, &s) == 0) {
-                        if ((s.st_mode & S_IFMT) == S_IFLNK) {
-                            char linkto[256];
-                            int len = readlink(buffer, linkto, sizeof(linkto));
-                            if(len > 0) {
-                                if(len > 255) {
-                                    linkto[252] = '.';
-                                    linkto[253] = '.';
-                                    linkto[254] = '.';
-                                    linkto[255] = 0;
-                                } else {
-                                    linkto[len] = 0;
-                                }
-                                if (strstr(linkto, "/storage/") == linkto ||
-                                    strstr(linkto, "/system/sounds/") == linkto ||
-                                    strstr(linkto, "/data/") == linkto ||
-                                    strstr(linkto, "/system/media/") == linkto) {
-                                    result.append("  ");
-                                    result.append(buffer);
-                                    result.append(" -> ");
-                                    result.append(linkto);
-                                    result.append("\n");
-                                }
+    snprintf(buffer, SIZE, "/proc/%d/fd", getpid());
+    DIR *d = opendir(buffer);
+    if (d) {
+        struct dirent *ent;
+        while((ent = readdir(d)) != NULL) {
+            if (strcmp(ent->d_name,".") && strcmp(ent->d_name,"..")) {
+                snprintf(buffer, SIZE, "/proc/%d/fd/%s", getpid(), ent->d_name);
+                struct stat s;
+                if (lstat(buffer, &s) == 0) {
+                    if ((s.st_mode & S_IFMT) == S_IFLNK) {
+                        char linkto[256];
+                        int len = readlink(buffer, linkto, sizeof(linkto));
+                        if(len > 0) {
+                            if(len > 255) {
+                                linkto[252] = '.';
+                                linkto[253] = '.';
+                                linkto[254] = '.';
+                                linkto[255] = 0;
+                            } else {
+                                linkto[len] = 0;
                             }
-                        } else {
-                            result.append("  unexpected type for ");
-                            result.append(buffer);
-                            result.append("\n");
+                            if (strstr(linkto, "/storage/") == linkto ||
+                                strstr(linkto, "/system/sounds/") == linkto ||
+                                strstr(linkto, "/data/") == linkto ||
+                                strstr(linkto, "/system/media/") == linkto) {
+                                result.append("  ");
+                                result.append(buffer);
+                                result.append(" -> ");
+                                result.append(linkto);
+                                result.append("\n");
+                            }
                         }
+                    } else {
+                        result.append("  unexpected type for ");
+                        result.append(buffer);
+                        result.append("\n");
                     }
                 }
             }
-            closedir(d);
-        } else {
-            result.append("couldn't open ");
-            result.append(buffer);
-            result.append("\n");
         }
+        closedir(d);
+    } else {
+        result.append("couldn't open ");
+        result.append(buffer);
+        result.append("\n");
+    }
 
-        gLooperRoster.dump(fd, args);
+    gLooperRoster.dump(fd, args);
 
-        bool dumpMem = false;
-        bool unreachableMemory = false;
-        for (size_t i = 0; i < args.size(); i++) {
-            if (args[i] == String16("-m")) {
-                dumpMem = true;
-            } else if (args[i] == String16("--unreachable")) {
-                unreachableMemory = true;
-            }
-        }
-        if (dumpMem) {
-            result.append("\nDumping memory:\n");
-            std::string s = dumpMemoryAddresses(100 /* limit */);
-            result.append(s.c_str(), s.size());
-        }
-        if (unreachableMemory) {
-            result.append("\nDumping unreachable memory:\n");
-            // TODO - should limit be an argument parameter?
-            // TODO: enable GetUnreachableMemoryString if it's part of stable API
-            //std::string s = GetUnreachableMemoryString(true /* contents */, 10000 /* limit */);
-            //result.append(s.c_str(), s.size());
+    bool dumpMem = false;
+    bool unreachableMemory = false;
+    for (size_t i = 0; i < args.size(); i++) {
+        if (args[i] == String16("-m")) {
+            dumpMem = true;
+        } else if (args[i] == String16("--unreachable")) {
+            unreachableMemory = true;
         }
     }
+    if (dumpMem) {
+        result.append("\nDumping memory:\n");
+        std::string s = dumpMemoryAddresses(100 /* limit */);
+        result.append(s.c_str(), s.size());
+    }
+    if (unreachableMemory) {
+        result.append("\nDumping unreachable memory:\n");
+        // TODO - should limit be an argument parameter?
+        // TODO: enable GetUnreachableMemoryString if it's part of stable API
+        //std::string s = GetUnreachableMemoryString(true /* contents */, 10000 /* limit */);
+        //result.append(s.c_str(), s.size());
+    }
+
     write(fd, result.string(), result.size());
     return NO_ERROR;
 }
@@ -380,8 +210,8 @@
 }  // anonymous namespace
 
 //static
-sp<MediaPlayer2> MediaPlayer2::Create() {
-    sp<MediaPlayer2> player = new MediaPlayer2();
+sp<MediaPlayer2> MediaPlayer2::Create(int32_t sessionId, jobject context) {
+    sp<MediaPlayer2> player = new MediaPlayer2(sessionId, context);
 
     if (!player->init()) {
         return NULL;
@@ -398,44 +228,35 @@
     return dumpPlayers(fd, args);
 }
 
-MediaPlayer2::MediaPlayer2() {
+MediaPlayer2::MediaPlayer2(int32_t sessionId, jobject context) {
     ALOGV("constructor");
     mSrcId = 0;
     mLockThreadId = 0;
     mListener = NULL;
     mStreamType = AUDIO_STREAM_MUSIC;
-    mAudioAttributesParcel = NULL;
+    mAudioAttributes = NULL;
+    mContext = new JObjectHolder(context);
     mCurrentPosition = -1;
     mCurrentSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
     mSeekPosition = -1;
     mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
     mCurrentState = MEDIA_PLAYER2_IDLE;
+    mTransitionToNext = false;
     mLoop = false;
-    mLeftVolume = mRightVolume = 1.0;
+    mVolume = 1.0;
     mVideoWidth = mVideoHeight = 0;
-    mAudioSessionId = (audio_session_t) AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
-    AudioSystem::acquireAudioSessionId(mAudioSessionId, -1);
     mSendLevel = 0;
 
-    // TODO: get pid and uid from JAVA
-    mPid = IPCThreadState::self()->getCallingPid();
-    mUid = IPCThreadState::self()->getCallingUid();
+    mPid = AIBinder_getCallingPid();
+    mUid = AIBinder_getCallingUid();
 
-    mAudioAttributes = NULL;
+    mAudioOutput = new MediaPlayer2AudioOutput(sessionId, mUid, mPid, NULL /*attributes*/);
 }
 
 MediaPlayer2::~MediaPlayer2() {
     ALOGV("destructor");
-    if (mAudioAttributesParcel != NULL) {
-        delete mAudioAttributesParcel;
-        mAudioAttributesParcel = NULL;
-    }
-    AudioSystem::releaseAudioSessionId(mAudioSessionId, -1);
     disconnect();
     removePlayer(this);
-    if (mAudioAttributes != NULL) {
-        free(mAudioAttributes);
-    }
 }
 
 bool MediaPlayer2::init() {
@@ -493,19 +314,28 @@
     if (dsd == NULL) {
         return BAD_VALUE;
     }
+    // Microsecond is used in NuPlayer2.
+    if (dsd->mStartPositionMs > DataSourceDesc::kMaxTimeMs) {
+        dsd->mStartPositionMs = DataSourceDesc::kMaxTimeMs;
+        ALOGW("setDataSource, start poistion clamped to %lld ms", (long long)dsd->mStartPositionMs);
+    }
+    if (dsd->mEndPositionMs > DataSourceDesc::kMaxTimeMs) {
+        dsd->mEndPositionMs = DataSourceDesc::kMaxTimeMs;
+        ALOGW("setDataSource, end poistion clamped to %lld ms", (long long)dsd->mStartPositionMs);
+    }
     ALOGV("setDataSource type(%d), srcId(%lld)", dsd->mType, (long long)dsd->mId);
 
     sp<MediaPlayer2Interface> oldPlayer;
 
-    Mutex::Autolock _l(mLock);
     {
+        Mutex::Autolock _l(mLock);
         if (!((mCurrentState & MEDIA_PLAYER2_IDLE)
               || mCurrentState == MEDIA_PLAYER2_STATE_ERROR)) {
             ALOGE("setDataSource called in wrong state %d", mCurrentState);
             return INVALID_OPERATION;
         }
 
-        sp<MediaPlayer2Interface> player = new NuPlayer2Driver(mPid, mUid);
+        sp<MediaPlayer2Interface> player = new NuPlayer2Driver(mPid, mUid, mContext);
         status_t err = player->initCheck();
         if (err != NO_ERROR) {
             ALOGE("Failed to create player object, initCheck failed(%d)", err);
@@ -515,8 +345,6 @@
         clear_l();
 
         player->setListener(new proxyListener(this));
-        mAudioOutput = new MediaPlayer2AudioOutput(mAudioSessionId, mUid,
-                mPid, mAudioAttributes, new AudioDeviceUpdatedNotifier(player));
         player->setAudioSink(mAudioOutput);
 
         err = player->setDataSource(dsd);
@@ -562,82 +390,22 @@
         return INVALID_OPERATION;
     }
     mSrcId = srcId;
+    mTransitionToNext = true;
     return mPlayer->playNextDataSource(srcId);
 }
 
-status_t MediaPlayer2::invoke(const Parcel& request, Parcel *reply) {
+status_t MediaPlayer2::invoke(const PlayerMessage &request, PlayerMessage *reply) {
     Mutex::Autolock _l(mLock);
     const bool hasBeenInitialized =
             (mCurrentState != MEDIA_PLAYER2_STATE_ERROR) &&
             ((mCurrentState & MEDIA_PLAYER2_IDLE) != MEDIA_PLAYER2_IDLE);
     if ((mPlayer == NULL) || !hasBeenInitialized) {
-        ALOGE("invoke failed: wrong state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
+        ALOGE("invoke() failed: wrong state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
         return INVALID_OPERATION;
     }
-    ALOGV("invoke %zu", request.dataSize());
     return mPlayer->invoke(request, reply);
 }
 
-// This call doesn't need to access the native player.
-status_t MediaPlayer2::setMetadataFilter(const Parcel& filter) {
-    ALOGD("setMetadataFilter");
-
-    status_t status;
-    media::Metadata::Filter allow, drop;
-
-    if (unmarshallFilter(filter, &allow, &status) &&
-        unmarshallFilter(filter, &drop, &status)) {
-        Mutex::Autolock lock(mLock);
-
-        mMetadataAllow = allow;
-        mMetadataDrop = drop;
-    }
-    return status;
-}
-
-status_t MediaPlayer2::getMetadata(bool update_only, bool /* apply_filter */, Parcel *reply) {
-    ALOGD("getMetadata");
-    sp<MediaPlayer2Interface> player;
-    media::Metadata::Filter ids;
-    Mutex::Autolock lock(mLock);
-    {
-        if (mPlayer == NULL) {
-            return NO_INIT;
-        }
-
-        player = mPlayer;
-        // Placeholder for the return code, updated by the caller.
-        reply->writeInt32(-1);
-
-        // We don't block notifications while we fetch the data. We clear
-        // mMetadataUpdated first so we don't lose notifications happening
-        // during the rest of this call.
-        if (update_only) {
-            ids = mMetadataUpdated;
-        }
-        mMetadataUpdated.clear();
-    }
-
-    media::Metadata metadata(reply);
-
-    metadata.appendHeader();
-    status_t status = player->getMetadata(ids, reply);
-
-    if (status != OK) {
-        metadata.resetParcel();
-        ALOGE("getMetadata failed %d", status);
-        return status;
-    }
-
-    // FIXME: ement filtering on the result. Not critical since
-    // filtering takes place on the update notifications already. This
-    // would be when all the metadata are fetch and a filter is set.
-
-    // Everything is fine, update the metadata length.
-    metadata.updateLength();
-    return OK;
-}
-
 void MediaPlayer2::disconnectNativeWindow_l() {
     if (mConnectedWindow != NULL && mConnectedWindow->getANativeWindow() != NULL) {
         status_t err = native_window_api_disconnect(
@@ -727,22 +495,9 @@
     return mPlayer->setBufferingSettings(buffering);
 }
 
-status_t MediaPlayer2::setAudioAttributes_l(const Parcel &parcel) {
-    if (mAudioAttributes != NULL) {
-        free(mAudioAttributes);
-    }
-    mAudioAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
-    if (mAudioAttributes == NULL) {
-        return NO_MEMORY;
-    }
-    unmarshallAudioAttributes(parcel, mAudioAttributes);
-
-    ALOGV("setAudioAttributes_l() usage=%d content=%d flags=0x%x tags=%s",
-            mAudioAttributes->usage, mAudioAttributes->content_type, mAudioAttributes->flags,
-            mAudioAttributes->tags);
-
-    if (mAudioOutput != 0) {
-        mAudioOutput->setAudioAttributes(mAudioAttributes);
+status_t MediaPlayer2::setAudioAttributes_l(const jobject attributes) {
+    if (mAudioOutput != NULL) {
+        mAudioOutput->setAudioAttributes(attributes);
     }
     return NO_ERROR;
 }
@@ -750,14 +505,12 @@
 status_t MediaPlayer2::prepareAsync() {
     ALOGV("prepareAsync");
     Mutex::Autolock _l(mLock);
-    if ((mPlayer != 0) && (mCurrentState & (MEDIA_PLAYER2_INITIALIZED | MEDIA_PLAYER2_STOPPED))) {
-        if (mAudioAttributesParcel != NULL) {
-            status_t err = setAudioAttributes_l(*mAudioAttributesParcel);
+    if ((mPlayer != 0) && (mCurrentState & MEDIA_PLAYER2_INITIALIZED)) {
+        if (mAudioAttributes != NULL) {
+            status_t err = setAudioAttributes_l(mAudioAttributes->getJObject());
             if (err != OK) {
                 return err;
             }
-        } else if (mAudioOutput != 0) {
-            mAudioOutput->setAudioStreamType(mStreamType);
         }
         mCurrentState = MEDIA_PLAYER2_PREPARING;
         return mPlayer->prepareAsync();
@@ -781,7 +534,7 @@
         mPlayer->setLooping(mLoop);
 
         if (mAudioOutput != 0) {
-            mAudioOutput->setVolume(mLeftVolume, mRightVolume);
+            mAudioOutput->setVolume(mVolume);
         }
 
         if (mAudioOutput != 0) {
@@ -806,35 +559,18 @@
     return ret;
 }
 
-status_t MediaPlayer2::stop() {
-    ALOGV("stop");
-    Mutex::Autolock _l(mLock);
-    if (mCurrentState & MEDIA_PLAYER2_STOPPED) return NO_ERROR;
-    if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER2_STARTED | MEDIA_PLAYER2_PREPARED |
-                    MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE ) ) ) {
-        status_t ret = mPlayer->stop();
-        if (ret != NO_ERROR) {
-            mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
-        } else {
-            mCurrentState = MEDIA_PLAYER2_STOPPED;
-        }
-        return ret;
-    }
-    ALOGE("stop called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
-    return INVALID_OPERATION;
-}
-
 status_t MediaPlayer2::pause() {
     ALOGV("pause");
     Mutex::Autolock _l(mLock);
     if (mCurrentState & (MEDIA_PLAYER2_PAUSED|MEDIA_PLAYER2_PLAYBACK_COMPLETE))
         return NO_ERROR;
-    if ((mPlayer != 0) && (mCurrentState & MEDIA_PLAYER2_STARTED)) {
+    if ((mPlayer != 0) && (mCurrentState & (MEDIA_PLAYER2_STARTED | MEDIA_PLAYER2_PREPARED))) {
         status_t ret = mPlayer->pause();
         if (ret != NO_ERROR) {
             mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
         } else {
             mCurrentState = MEDIA_PLAYER2_PAUSED;
+            mTransitionToNext = false;
         }
         return ret;
     }
@@ -860,7 +596,7 @@
     return false;
 }
 
-mediaplayer2_states MediaPlayer2::getMediaPlayer2State() {
+mediaplayer2_states MediaPlayer2::getState() {
     Mutex::Autolock _l(mLock);
     if (mCurrentState & MEDIA_PLAYER2_STATE_ERROR) {
         return MEDIAPLAYER2_STATE_ERROR;
@@ -873,8 +609,7 @@
     if (mCurrentState & MEDIA_PLAYER2_STARTED) {
         return MEDIAPLAYER2_STATE_PLAYING;
     }
-    if (mCurrentState
-        & (MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_STOPPED | MEDIA_PLAYER2_PLAYBACK_COMPLETE)) {
+    if (mCurrentState & (MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE)) {
         return MEDIAPLAYER2_STATE_PAUSED;
     }
     // now only mCurrentState & MEDIA_PLAYER2_PREPARED is true
@@ -890,7 +625,7 @@
         return BAD_VALUE;
     }
     Mutex::Autolock _l(mLock);
-    if (mPlayer == 0 || (mCurrentState & MEDIA_PLAYER2_STOPPED)) {
+    if (mPlayer == 0) {
         return INVALID_OPERATION;
     }
 
@@ -978,11 +713,18 @@
     return ret;
 }
 
-status_t MediaPlayer2::getDuration(int64_t *msec) {
+status_t MediaPlayer2::getDuration(int64_t srcId, int64_t *msec) {
     Mutex::Autolock _l(mLock);
+    // TODO: cache duration for currentSrcId and nextSrcId, and return correct
+    // value for nextSrcId.
+    if (srcId != mSrcId) {
+        *msec = -1;
+        return OK;
+    }
+
     ALOGV("getDuration_l");
     bool isValidState = (mCurrentState & (MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
-            MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_STOPPED | MEDIA_PLAYER2_PLAYBACK_COMPLETE));
+            MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE));
     if (mPlayer == 0 || !isValidState) {
         ALOGE("Attempt to call getDuration in wrong state: mPlayer=%p, mCurrentState=%u",
                 mPlayer.get(), mCurrentState);
@@ -1076,6 +818,7 @@
         } else {
             mPlayer->setListener(NULL);
             mCurrentState = MEDIA_PLAYER2_IDLE;
+            mTransitionToNext = false;
         }
         // setDataSource has to be called again to create a
         // new mediaplayer.
@@ -1138,18 +881,17 @@
     return false;
 }
 
-status_t MediaPlayer2::setVolume(float leftVolume, float rightVolume) {
-    ALOGV("MediaPlayer2::setVolume(%f, %f)", leftVolume, rightVolume);
+status_t MediaPlayer2::setVolume(float volume) {
+    ALOGV("MediaPlayer2::setVolume(%f)", volume);
     Mutex::Autolock _l(mLock);
-    mLeftVolume = leftVolume;
-    mRightVolume = rightVolume;
+    mVolume = volume;
     if (mAudioOutput != 0) {
-        mAudioOutput->setVolume(leftVolume, rightVolume);
+        mAudioOutput->setVolume(volume);
     }
     return OK;
 }
 
-status_t MediaPlayer2::setAudioSessionId(audio_session_t sessionId) {
+status_t MediaPlayer2::setAudioSessionId(int32_t sessionId) {
     ALOGV("MediaPlayer2::setAudioSessionId(%d)", sessionId);
     Mutex::Autolock _l(mLock);
     if (!(mCurrentState & MEDIA_PLAYER2_IDLE)) {
@@ -1159,17 +901,18 @@
     if (sessionId < 0) {
         return BAD_VALUE;
     }
-    if (sessionId != mAudioSessionId) {
-        AudioSystem::acquireAudioSessionId(sessionId, -1);
-        AudioSystem::releaseAudioSessionId(mAudioSessionId, -1);
-        mAudioSessionId = sessionId;
+    if (mAudioOutput != NULL && sessionId != mAudioOutput->getSessionId()) {
+        mAudioOutput->setSessionId(sessionId);
     }
     return NO_ERROR;
 }
 
-audio_session_t MediaPlayer2::getAudioSessionId() {
+int32_t MediaPlayer2::getAudioSessionId() {
     Mutex::Autolock _l(mLock);
-    return mAudioSessionId;
+    if (mAudioOutput != NULL) {
+        return mAudioOutput->getSessionId();
+    }
+    return 0;
 }
 
 status_t MediaPlayer2::setAuxEffectSendLevel(float level) {
@@ -1196,67 +939,37 @@
 }
 
 // always call with lock held
-status_t MediaPlayer2::checkStateForKeySet_l(int key) {
-    switch(key) {
-    case MEDIA2_KEY_PARAMETER_AUDIO_ATTRIBUTES:
-        if (mCurrentState & ( MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
-                MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE) ) {
-            // Can't change the audio attributes after prepare
-            ALOGE("trying to set audio attributes called in state %d", mCurrentState);
-            return INVALID_OPERATION;
-        }
-        break;
-    default:
-        // parameter doesn't require player state check
-        break;
+status_t MediaPlayer2::checkState_l() {
+    if (mCurrentState & ( MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
+            MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE) ) {
+        // Can't change the audio attributes after prepare
+        ALOGE("trying to set audio attributes called in state %d", mCurrentState);
+        return INVALID_OPERATION;
     }
     return OK;
 }
 
-status_t MediaPlayer2::setParameter(int key, const Parcel& request) {
-    ALOGV("MediaPlayer2::setParameter(%d)", key);
+status_t MediaPlayer2::setAudioAttributes(const jobject attributes) {
+    ALOGV("MediaPlayer2::setAudioAttributes");
     status_t status = INVALID_OPERATION;
     Mutex::Autolock _l(mLock);
-    if (checkStateForKeySet_l(key) != OK) {
+    if (checkState_l() != OK) {
         return status;
     }
-    switch (key) {
-    case MEDIA2_KEY_PARAMETER_AUDIO_ATTRIBUTES:
-        // save the marshalled audio attributes
-        if (mAudioAttributesParcel != NULL) {
-            delete mAudioAttributesParcel;
-        }
-        mAudioAttributesParcel = new Parcel();
-        mAudioAttributesParcel->appendFrom(&request, 0, request.dataSize());
-        status = setAudioAttributes_l(request);
-        if (status != OK) {
-            return status;
-        }
-        break;
-    default:
-        ALOGV_IF(mPlayer == NULL, "setParameter: no active player");
-        break;
-    }
-
-    if (mPlayer != NULL) {
-        status = mPlayer->setParameter(key, request);
-    }
+    mAudioAttributes = new JObjectHolder(attributes);
+    status = setAudioAttributes_l(attributes);
     return status;
 }
 
+jobject MediaPlayer2::getAudioAttributes() {
+    ALOGV("MediaPlayer2::getAudioAttributes)");
+    Mutex::Autolock _l(mLock);
+    return mAudioAttributes != NULL ? mAudioAttributes->getJObject() : NULL;
+}
+
 status_t MediaPlayer2::getParameter(int key, Parcel *reply) {
     ALOGV("MediaPlayer2::getParameter(%d)", key);
     Mutex::Autolock _l(mLock);
-    if (key == MEDIA2_KEY_PARAMETER_AUDIO_ATTRIBUTES) {
-        if (reply == NULL) {
-            return BAD_VALUE;
-        }
-        if (mAudioAttributesParcel != NULL) {
-            reply->appendFrom(mAudioAttributesParcel, 0, mAudioAttributesParcel->dataSize());
-        }
-        return OK;
-    }
-
     if (mPlayer == NULL) {
         ALOGV("getParameter: no active player");
         return INVALID_OPERATION;
@@ -1269,44 +982,26 @@
     return status;
 }
 
-bool MediaPlayer2::shouldDropMetadata(media::Metadata::Type code) const {
-    Mutex::Autolock lock(mLock);
-
-    if (findMetadata(mMetadataDrop, code)) {
-        return true;
+// for mediametrics
+status_t MediaPlayer2::getMetrics(char **buffer, size_t *length) {
+    ALOGD("MediaPlayer2::getMetrics()");
+    Mutex::Autolock _l(mLock);
+    if (mPlayer == NULL) {
+        ALOGV("getMetrics: no active player");
+        return INVALID_OPERATION;
     }
 
-    if (mMetadataAllow.isEmpty() || findMetadata(mMetadataAllow, code)) {
-        return false;
-    } else {
-        return true;
+    status_t status =  mPlayer->getMetrics(buffer, length);
+    if (status != OK) {
+        ALOGD("getMetrics returns %d", status);
     }
+    return status;
 }
 
-
-void MediaPlayer2::addNewMetadataUpdate(media::Metadata::Type metadata_type) {
-    Mutex::Autolock lock(mLock);
-    if (mMetadataUpdated.indexOf(metadata_type) < 0) {
-        mMetadataUpdated.add(metadata_type);
-    }
-}
-
-void MediaPlayer2::notify(int64_t srcId, int msg, int ext1, int ext2, const Parcel *obj) {
+void MediaPlayer2::notify(int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *obj) {
     ALOGV("message received srcId=%lld, msg=%d, ext1=%d, ext2=%d",
           (long long)srcId, msg, ext1, ext2);
 
-    if (MEDIA2_INFO == msg && MEDIA2_INFO_METADATA_UPDATE == ext1) {
-        const media::Metadata::Type metadata_type = ext2;
-
-        if(shouldDropMetadata(metadata_type)) {
-            return;
-        }
-
-        // Update the list of metadata that have changed. getMetadata
-        // also access mMetadataUpdated and clears it.
-        addNewMetadataUpdate(metadata_type);
-    }
-
     bool send = true;
     bool locked = false;
 
@@ -1335,8 +1030,10 @@
     case MEDIA2_NOP: // interface test message
         break;
     case MEDIA2_PREPARED:
-        ALOGV("MediaPlayer2::notify() prepared");
-        mCurrentState = MEDIA_PLAYER2_PREPARED;
+        ALOGV("MediaPlayer2::notify() prepared, srcId=%lld", (long long)srcId);
+        if (srcId == mSrcId) {
+            mCurrentState = MEDIA_PLAYER2_PREPARED;
+        }
         break;
     case MEDIA2_DRM_INFO:
         ALOGV("MediaPlayer2::notify() MEDIA2_DRM_INFO(%lld, %d, %d, %d, %p)",
@@ -1347,7 +1044,7 @@
         if (mCurrentState == MEDIA_PLAYER2_IDLE) {
             ALOGE("playback complete in idle state");
         }
-        if (!mLoop) {
+        if (!mLoop && srcId == mSrcId) {
             mCurrentState = MEDIA_PLAYER2_PLAYBACK_COMPLETE;
         }
         break;
@@ -1363,6 +1060,11 @@
         // ext2: Implementation dependant error code.
         if (ext1 != MEDIA2_INFO_VIDEO_TRACK_LAGGING) {
             ALOGW("info/warning (%d, %d)", ext1, ext2);
+
+            if (ext1 == MEDIA2_INFO_DATA_SOURCE_START && srcId == mSrcId && mTransitionToNext) {
+                mCurrentState = MEDIA_PLAYER2_STARTED;
+                mTransitionToNext = false;
+            }
         }
         break;
     case MEDIA2_SEEK_COMPLETE:
@@ -1418,7 +1120,8 @@
 }
 
 // Modular DRM
-status_t MediaPlayer2::prepareDrm(const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId) {
+status_t MediaPlayer2::prepareDrm(
+        int64_t srcId, const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId) {
     // TODO change to ALOGV
     ALOGD("prepareDrm: uuid: %p  drmSessionId: %p(%zu)", uuid,
             drmSessionId.array(), drmSessionId.size());
@@ -1432,8 +1135,10 @@
     // completed) so the state change to "prepared" might not have happened yet (e.g., buffering).
     // Still, we can allow prepareDrm for the use case of being called in OnDrmInfoListener.
     if (!(mCurrentState & (MEDIA_PLAYER2_PREPARING | MEDIA_PLAYER2_PREPARED))) {
-        ALOGE("prepareDrm is called in the wrong state (%d).", mCurrentState);
-        return INVALID_OPERATION;
+        ALOGW("prepareDrm(%lld) called in non-prepare state(%d)", (long long)srcId, mCurrentState);
+        if (srcId == mSrcId) {
+            return INVALID_OPERATION;
+        }
     }
 
     if (drmSessionId.isEmpty()) {
@@ -1442,7 +1147,7 @@
     }
 
     // Passing down to mediaserver mainly for creating the crypto
-    status_t status = mPlayer->prepareDrm(uuid, drmSessionId);
+    status_t status = mPlayer->prepareDrm(srcId, uuid, drmSessionId);
     ALOGE_IF(status != OK, "prepareDrm: Failed at mediaserver with ret: %d", status);
 
     // TODO change to ALOGV
@@ -1451,7 +1156,7 @@
     return status;
 }
 
-status_t MediaPlayer2::releaseDrm() {
+status_t MediaPlayer2::releaseDrm(int64_t srcId) {
     Mutex::Autolock _l(mLock);
     if (mPlayer == NULL) {
         return NO_INIT;
@@ -1466,7 +1171,7 @@
         return INVALID_OPERATION;
     }
 
-    status_t status = mPlayer->releaseDrm();
+    status_t status = mPlayer->releaseDrm(srcId);
     // TODO change to ALOGV
     ALOGD("releaseDrm: mediaserver::releaseDrm ret: %d", status);
     if (status != OK) {
@@ -1479,36 +1184,40 @@
     return status;
 }
 
-status_t MediaPlayer2::setOutputDevice(audio_port_handle_t deviceId) {
+status_t MediaPlayer2::setPreferredDevice(jobject device) {
     Mutex::Autolock _l(mLock);
     if (mAudioOutput == NULL) {
-        ALOGV("setOutputDevice: audio sink not init");
+        ALOGV("setPreferredDevice: audio sink not init");
         return NO_INIT;
     }
-    return mAudioOutput->setOutputDevice(deviceId);
+    return mAudioOutput->setPreferredDevice(device);
 }
 
-audio_port_handle_t MediaPlayer2::getRoutedDeviceId() {
+jobject MediaPlayer2::getRoutedDevice() {
     Mutex::Autolock _l(mLock);
     if (mAudioOutput == NULL) {
-        ALOGV("getRoutedDeviceId: audio sink not init");
-        return AUDIO_PORT_HANDLE_NONE;
+        ALOGV("getRoutedDevice: audio sink not init");
+        return nullptr;
     }
-    audio_port_handle_t deviceId;
-    status_t status = mAudioOutput->getRoutedDeviceId(&deviceId);
-    if (status != NO_ERROR) {
-        return AUDIO_PORT_HANDLE_NONE;
-    }
-    return deviceId;
+    return mAudioOutput->getRoutedDevice();
 }
 
-status_t MediaPlayer2::enableAudioDeviceCallback(bool enabled) {
+status_t MediaPlayer2::addAudioDeviceCallback(jobject routingDelegate) {
     Mutex::Autolock _l(mLock);
     if (mAudioOutput == NULL) {
         ALOGV("addAudioDeviceCallback: player not init");
         return NO_INIT;
     }
-    return mAudioOutput->enableAudioDeviceCallback(enabled);
+    return mAudioOutput->addAudioDeviceCallback(routingDelegate);
+}
+
+status_t MediaPlayer2::removeAudioDeviceCallback(jobject listener) {
+    Mutex::Autolock _l(mLock);
+    if (mAudioOutput == NULL) {
+        ALOGV("addAudioDeviceCallback: player not init");
+        return NO_INIT;
+    }
+    return mAudioOutput->removeAudioDeviceCallback(listener);
 }
 
 status_t MediaPlayer2::dump(int fd, const Vector<String16>& args) {
diff --git a/media/libmediaplayer2/nuplayer2/Android.bp b/media/libmediaplayer2/nuplayer2/Android.bp
index c40b361..0f69b2e 100644
--- a/media/libmediaplayer2/nuplayer2/Android.bp
+++ b/media/libmediaplayer2/nuplayer2/Android.bp
@@ -1,6 +1,7 @@
 cc_library_static {
 
     srcs: [
+        "JMediaPlayer2Utils.cpp",
         "JWakeLock.cpp",
         "GenericSource2.cpp",
         "HTTPLiveSource2.cpp",
@@ -16,6 +17,7 @@
     ],
 
     header_libs: [
+        "libbase_headers",
         "libmediaplayer2_headers",
         "media_plugin_headers",
     ],
@@ -27,6 +29,8 @@
         "frameworks/av/media/libstagefright/mpeg2ts",
         "frameworks/av/media/libstagefright/rtsp",
         "frameworks/av/media/libstagefright/timedtext",
+        "frameworks/av/media/ndk",
+        "frameworks/base/core/jni",
     ],
 
     cflags: [
@@ -47,24 +51,22 @@
         "libui",
         "libgui",
         "libmedia",
-        "libmediadrm",
+        "libmediametrics",
         "libmediandk",
+        "libmediandk_utils",
         "libpowermanager",
     ],
 
     static_libs: [
         "libmedia_helper",
+        "libmediaplayer2-protos",
+        "libmedia2_jni_core",
     ],
 
     name: "libstagefright_nuplayer2",
 
-    tags: ["eng"],
-
     sanitize: {
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
 }
diff --git a/media/libmediaplayer2/nuplayer2/GenericSource2.cpp b/media/libmediaplayer2/nuplayer2/GenericSource2.cpp
index 196b103..9552580 100644
--- a/media/libmediaplayer2/nuplayer2/GenericSource2.cpp
+++ b/media/libmediaplayer2/nuplayer2/GenericSource2.cpp
@@ -21,30 +21,19 @@
 #include "NuPlayer2Drm.h"
 
 #include "AnotherPacketSource.h"
-#include <binder/IServiceManager.h>
 #include <cutils/properties.h>
 #include <media/DataSource.h>
 #include <media/MediaBufferHolder.h>
-#include <media/IMediaExtractorService.h>
-#include <media/IMediaSource.h>
-#include <media/MediaHTTPService.h>
-#include <media/MediaExtractor.h>
-#include <media/MediaSource.h>
 #include <media/NdkWrapper.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/DataSourceFactory.h>
-#include <media/stagefright/InterfaceUtils.h>
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MediaClock.h>
 #include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaExtractorFactory.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/NdkUtils.h>
 #include <media/stagefright/Utils.h>
-#include "../../libstagefright/include/NuCachedSource2.h"
-#include "../../libstagefright/include/HTTPBase.h"
 
 namespace android {
 
@@ -89,8 +78,6 @@
 void NuPlayer2::GenericSource2::resetDataSource() {
     ALOGV("resetDataSource");
 
-    mHTTPService.clear();
-    mHttpSource.clear();
     mDisconnected = false;
     mUri.clear();
     mUriHeaders.clear();
@@ -110,7 +97,6 @@
 }
 
 status_t NuPlayer2::GenericSource2::setDataSource(
-        const sp<MediaHTTPService> &httpService,
         const char *url,
         const KeyedVector<String8, String8> *headers) {
     Mutex::Autolock _l(mLock);
@@ -118,7 +104,6 @@
 
     resetDataSource();
 
-    mHTTPService = httpService;
     mUri = url;
 
     if (headers) {
@@ -151,7 +136,7 @@
     ALOGV("setDataSource (source: %p)", source.get());
 
     resetDataSource();
-    mDataSource = source;
+    mDataSourceWrapper = new AMediaDataSourceWrapper(source);
     return OK;
 }
 
@@ -162,24 +147,21 @@
 
 status_t NuPlayer2::GenericSource2::initFromDataSource() {
     mExtractor = new AMediaExtractorWrapper(AMediaExtractor_new());
-    CHECK(mDataSource != NULL || mFd != -1);
-    sp<DataSource> dataSource = mDataSource;
+    CHECK(mFd >=0 || mDataSourceWrapper != NULL);
+    sp<AMediaDataSourceWrapper> aSourceWrapper = mDataSourceWrapper;
     const int fd = mFd;
-    const int64_t offset = mOffset;
-    const int64_t length = mLength;
 
     mLock.unlock();
     // This might take long time if data source is not reliable.
     status_t err;
-    if (dataSource != nullptr) {
-        mDataSourceWrapper = new AMediaDataSourceWrapper(dataSource);
-        err = mExtractor->setDataSource(mDataSourceWrapper->getAMediaDataSource());
+    if (aSourceWrapper != NULL) {
+        err = mExtractor->setDataSource(aSourceWrapper->getAMediaDataSource());
     } else {
-        err = mExtractor->setDataSource(fd, offset, length);
+        err = mExtractor->setDataSource(fd, mOffset, mLength);
     }
 
     if (err != OK) {
-        ALOGE("initFromDataSource, failed to create data source!");
+        ALOGE("initFromDataSource, failed to set extractor data source!");
         mLock.lock();
         return UNKNOWN_ERROR;
     }
@@ -191,10 +173,8 @@
         return UNKNOWN_ERROR;
     }
 
-    mLock.lock();
-    mFd = -1;
-    mDataSource = dataSource;
     mFileMeta = convertMediaFormatWrapperToMetaData(mExtractor->getFormat());
+    mLock.lock();
     if (mFileMeta != NULL) {
         int64_t duration;
         if (mFileMeta->findInt64(kKeyDuration, &duration)) {
@@ -215,10 +195,10 @@
         }
 
         sp<AMediaExtractorWrapper> trackExtractor = new AMediaExtractorWrapper(AMediaExtractor_new());
-        if (mDataSourceWrapper != nullptr) {
-            err = trackExtractor->setDataSource(mDataSourceWrapper->getAMediaDataSource());
+        if (aSourceWrapper != NULL) {
+            trackExtractor->setDataSource(aSourceWrapper->getAMediaDataSource());
         } else {
-            err = trackExtractor->setDataSource(fd, offset, length);
+            trackExtractor->setDataSource(fd, mOffset, mLength);
         }
 
         const char *mime;
@@ -330,19 +310,19 @@
         mLooper->unregisterHandler(id());
         mLooper->stop();
     }
-    if (mDataSource != NULL) {
-        mDataSource->close();
+    if (mDataSourceWrapper != NULL) {
+        mDataSourceWrapper->close();
     }
     resetDataSource();
 }
 
-void NuPlayer2::GenericSource2::prepareAsync() {
+void NuPlayer2::GenericSource2::prepareAsync(int64_t startTimeUs) {
     Mutex::Autolock _l(mLock);
     ALOGV("prepareAsync: (looper: %d)", (mLooper != NULL));
 
     if (mLooper == NULL) {
         mLooper = new ALooper;
-        mLooper->setName("generic");
+        mLooper->setName("generic2");
         mLooper->start(false, /* runOnCallingThread */
                        true,  /* canCallJava */
                        PRIORITY_DEFAULT);
@@ -351,59 +331,45 @@
     }
 
     sp<AMessage> msg = new AMessage(kWhatPrepareAsync, this);
+    msg->setInt64("startTimeUs", startTimeUs);
+
     msg->post();
 }
 
-void NuPlayer2::GenericSource2::onPrepareAsync() {
-    ALOGV("onPrepareAsync: mDataSource: %d", (mDataSource != NULL));
+void NuPlayer2::GenericSource2::onPrepareAsync(int64_t startTimeUs) {
+    ALOGV("onPrepareAsync: mFd %d mUri %s mDataSourceWrapper: %p",
+            mFd, mUri.c_str(), mDataSourceWrapper.get());
 
-    // delayed data source creation
-    if (mDataSource == NULL) {
-        // set to false first, if the extractor
-        // comes back as secure, set it to true then.
-        mIsSecure = false;
-
-        if (!mUri.empty()) {
-            const char* uri = mUri.c_str();
-            String8 contentType;
-
-            if (!strncasecmp("http://", uri, 7) || !strncasecmp("https://", uri, 8)) {
-                mHttpSource = DataSourceFactory::CreateMediaHTTP(mHTTPService);
-                if (mHttpSource == NULL) {
-                    ALOGE("Failed to create http source!");
-                    notifyPreparedAndCleanup(UNKNOWN_ERROR);
-                    return;
-                }
-            }
-
-            mLock.unlock();
-            // This might take long time if connection has some issue.
-            sp<DataSource> dataSource = DataSourceFactory::CreateFromURI(
-                   mHTTPService, uri, &mUriHeaders, &contentType,
-                   static_cast<HTTPBase *>(mHttpSource.get()));
-            mLock.lock();
-            if (!mDisconnected) {
-                mDataSource = dataSource;
-            }
+    if (!mUri.empty()) {
+        const char* uri = mUri.c_str();
+        size_t numheaders = mUriHeaders.size();
+        const char **key_values = numheaders ? new const char *[numheaders * 2] : NULL;
+        for (size_t i = 0; i < numheaders; ++i) {
+            key_values[i * 2] = mUriHeaders.keyAt(i).c_str();
+            key_values[i * 2 + 1] =  mUriHeaders.valueAt(i).c_str();
         }
-
-        if (mFd == -1 && mDataSource == NULL) {
-            ALOGE("Failed to create data source!");
-            notifyPreparedAndCleanup(UNKNOWN_ERROR);
-            return;
-        }
+        mLock.unlock();
+        AMediaDataSource *aSource = AMediaDataSource_newUri(uri, numheaders, key_values);
+        mLock.lock();
+        mDataSourceWrapper = aSource ? new AMediaDataSourceWrapper(aSource) : NULL;
+        delete[] key_values;
+        // For cached streaming cases, we need to wait for enough
+        // buffering before reporting prepared.
+        mIsStreaming = !strncasecmp("http://", uri, 7) || !strncasecmp("https://", uri, 8);
     }
 
-    if (mDataSource != nullptr && mDataSource->flags() & DataSource::kIsCachingDataSource) {
-        mCachedSource = static_cast<NuCachedSource2 *>(mDataSource.get());
+    if (mDisconnected || (mFd < 0 && mDataSourceWrapper == NULL)) {
+        ALOGE("mDisconnected(%d) or Failed to create data source!", mDisconnected);
+        notifyPreparedAndCleanup(UNKNOWN_ERROR);
+        return;
     }
 
-    // For cached streaming cases, we need to wait for enough
-    // buffering before reporting prepared.
-    mIsStreaming = (mCachedSource != NULL);
-
     // init extractor from data source
     status_t err = initFromDataSource();
+    if (mFd >= 0) {
+        close(mFd);
+        mFd = -1;
+    }
 
     if (err != OK) {
         ALOGE("Failed to init from data source!");
@@ -430,6 +396,7 @@
             FLAG_CAN_SEEK_FORWARD |
             FLAG_CAN_SEEK);
 
+    doSeek(startTimeUs, MediaPlayer2SeekMode::SEEK_CLOSEST);
     finishPrepareAsync();
 
     ALOGV("onPrepareAsync: Done");
@@ -439,8 +406,8 @@
     ALOGV("finishPrepareAsync");
 
     if (mIsStreaming) {
-        mCachedSource->resumeFetchingIfNecessary();
         mPreparing = true;
+        ++mPollBufferingGeneration;
         schedulePollBuffering();
     } else {
         notifyPrepared();
@@ -457,9 +424,7 @@
 
 void NuPlayer2::GenericSource2::notifyPreparedAndCleanup(status_t err) {
     if (err != OK) {
-        mDataSource.clear();
-        mCachedSource.clear();
-        mHttpSource.clear();
+        mDataSourceWrapper.clear();
 
         mBitrate = -1;
         mPrevBufferPercentage = -1;
@@ -499,53 +464,27 @@
 }
 
 void NuPlayer2::GenericSource2::disconnect() {
-    sp<DataSource> dataSource, httpSource;
     {
         Mutex::Autolock _l(mLock);
-        dataSource = mDataSource;
-        httpSource = mHttpSource;
         mDisconnected = true;
     }
-
-    if (dataSource != NULL) {
-        // disconnect data source
-        if (dataSource->flags() & DataSource::kIsCachingDataSource) {
-            static_cast<NuCachedSource2 *>(dataSource.get())->disconnect();
-        }
-    } else if (httpSource != NULL) {
-        static_cast<HTTPBase *>(httpSource.get())->disconnect();
+    if (mDataSourceWrapper != NULL) {
+        mDataSourceWrapper->close();
     }
-
-    mDataSourceWrapper = NULL;
-
 }
 
 status_t NuPlayer2::GenericSource2::feedMoreTSData() {
     return OK;
 }
 
-void NuPlayer2::GenericSource2::sendCacheStats() {
-    int32_t kbps = 0;
-    status_t err = UNKNOWN_ERROR;
-
-    if (mCachedSource != NULL) {
-        err = mCachedSource->getEstimatedBandwidthKbps(&kbps);
-    }
-
-    if (err == OK) {
-        sp<AMessage> notify = dupNotify();
-        notify->setInt32("what", kWhatCacheStats);
-        notify->setInt32("bandwidth", kbps);
-        notify->post();
-    }
-}
-
 void NuPlayer2::GenericSource2::onMessageReceived(const sp<AMessage> &msg) {
     Mutex::Autolock _l(mLock);
     switch (msg->what()) {
       case kWhatPrepareAsync:
       {
-          onPrepareAsync();
+          int64_t startTimeUs;
+          CHECK(msg->findInt64("startTimeUs", &startTimeUs));
+          onPrepareAsync(startTimeUs);
           break;
       }
       case kWhatFetchSubtitleData:
@@ -835,8 +774,6 @@
             }
             if (track->mPackets->getAvailableBufferCount(&finalResult) < 2
                 && !mSentPauseOnBuffering && !mPreparing) {
-                mCachedSource->resumeFetchingIfNecessary();
-                sendCacheStats();
                 mSentPauseOnBuffering = true;
                 sp<AMessage> notify = dupNotify();
                 notify->setInt32("what", kWhatPauseOnBufferingStart);
@@ -1349,6 +1286,11 @@
             mVideoTimeUs = timeUs;
         }
 
+        sp<AMediaCodecCryptoInfoWrapper> cryptInfo = extractor->getSampleCryptoInfo();
+        if (cryptInfo != NULL) {
+            meta->setObject("cryptInfo", cryptInfo);
+        }
+
         queueDiscontinuityIfNeeded(seeking, formatChange, trackType, track);
 
         if (numBuffers == 0 && actualTimeUs != nullptr) {
@@ -1392,7 +1334,6 @@
                         notifyPrepared();
                         mPreparing = false;
                     } else {
-                        sendCacheStats();
                         mSentPauseOnBuffering = false;
                         sp<AMessage> notify = dupNotify();
                         notify->setInt32("what", kWhatResumeOnBufferingEnd);
@@ -1444,47 +1385,31 @@
 }
 
 void NuPlayer2::GenericSource2::schedulePollBuffering() {
-    sp<AMessage> msg = new AMessage(kWhatPollBuffering, this);
-    msg->setInt32("generation", mPollBufferingGeneration);
-    // Enquires buffering status every second.
-    msg->post(1000000ll);
+    if (mIsStreaming) {
+        sp<AMessage> msg = new AMessage(kWhatPollBuffering, this);
+        msg->setInt32("generation", mPollBufferingGeneration);
+        // Enquires buffering status every second.
+        msg->post(1000000ll);
+    }
 }
 
 void NuPlayer2::GenericSource2::onPollBuffering() {
-    status_t finalStatus = UNKNOWN_ERROR;
     int64_t cachedDurationUs = -1ll;
-    ssize_t cachedDataRemaining = -1;
 
-    if (mCachedSource != NULL) {
-        cachedDataRemaining = mCachedSource->approxDataRemaining(&finalStatus);
-
-        if (finalStatus == OK) {
-            off64_t size;
-            int64_t bitrate = 0ll;
-            if (mDurationUs > 0 && mCachedSource->getSize(&size) == OK) {
-                // |bitrate| uses bits/second unit, while size is number of bytes.
-                bitrate = size * 8000000ll / mDurationUs;
-            } else if (mBitrate > 0) {
-                bitrate = mBitrate;
-            }
-            if (bitrate > 0) {
-                cachedDurationUs = cachedDataRemaining * 8000000ll / bitrate;
-            }
-        }
+    sp<AMediaExtractorWrapper> extractor;
+    if (mVideoTrack.mExtractor != NULL) {
+        extractor = mVideoTrack.mExtractor;
+    } else if (mAudioTrack.mExtractor != NULL) {
+        extractor = mAudioTrack.mExtractor;
     }
 
-    if (finalStatus != OK) {
-        ALOGV("onPollBuffering: EOS (finalStatus = %d)", finalStatus);
-
-        if (finalStatus == ERROR_END_OF_STREAM) {
-            notifyBufferingUpdate(100);
-        }
-
-        return;
+    if (extractor != NULL) {
+        cachedDurationUs = extractor->getCachedDuration();
     }
 
     if (cachedDurationUs >= 0ll) {
-        if (mDurationUs > 0ll) {
+        ssize_t sampleSize = extractor->getSampleSize();
+        if (sampleSize >= 0ll) {
             int64_t cachedPosUs = getLastReadPosition() + cachedDurationUs;
             int percentage = 100.0 * cachedPosUs / mDurationUs;
             if (percentage > 100) {
@@ -1492,9 +1417,11 @@
             }
 
             notifyBufferingUpdate(percentage);
+            ALOGV("onPollBuffering: cachedDurationUs %.1f sec", cachedDurationUs / 1000000.0f);
+        } else {
+            notifyBufferingUpdate(100);
+            ALOGV("onPollBuffering: EOS");
         }
-
-        ALOGV("onPollBuffering: cachedDurationUs %.1f sec", cachedDurationUs / 1000000.0f);
     }
 
     schedulePollBuffering();
@@ -1591,15 +1518,20 @@
         return OK; // source without DRM info
     }
 
-    sp<ABuffer> drmInfoBuffer = NuPlayer2Drm::retrieveDrmInfo(psshInfo);
-    ALOGV("checkDrmInfo: MEDIA_DRM_INFO PSSH drm info size: %d", (int)drmInfoBuffer->size());
+    PlayerMessage playerMsg;
+    status_t ret = NuPlayer2Drm::retrieveDrmInfo(psshInfo, &playerMsg);
+    ALOGV("checkDrmInfo: MEDIA_DRM_INFO PSSH drm info size: %d", (int)playerMsg.ByteSize());
 
-    if (drmInfoBuffer->size() == 0) {
-        ALOGE("checkDrmInfo: Unexpected parcel size: 0");
+    if (ret != OK) {
+        ALOGE("checkDrmInfo: failed to retrive DrmInfo %d", ret);
         return UNKNOWN_ERROR;
     }
 
-    notifyDrmInfo(drmInfoBuffer);
+    int size = playerMsg.ByteSize();
+    sp<ABuffer> drmInfoBuf = new ABuffer(size);
+    playerMsg.SerializeToArray(drmInfoBuf->data(), size);
+    drmInfoBuf->setRange(0, size);
+    notifyDrmInfo(drmInfoBuf);
 
     return OK;
 }
diff --git a/media/libmediaplayer2/nuplayer2/GenericSource2.h b/media/libmediaplayer2/nuplayer2/GenericSource2.h
index 9bc5182..ade1aa3 100644
--- a/media/libmediaplayer2/nuplayer2/GenericSource2.h
+++ b/media/libmediaplayer2/nuplayer2/GenericSource2.h
@@ -37,11 +37,9 @@
 class DataSource;
 class IDataSource;
 class IMediaSource;
-struct MediaHTTPService;
 struct MediaSource;
 class MediaBuffer;
 struct MediaClock;
-struct NuCachedSource2;
 
 struct NuPlayer2::GenericSource2 : public NuPlayer2::Source,
                                    public MediaBufferObserver // Modular DRM
@@ -50,7 +48,6 @@
                    const sp<MediaClock> &mediaClock);
 
     status_t setDataSource(
-            const sp<MediaHTTPService> &httpService,
             const char *url,
             const KeyedVector<String8, String8> *headers);
 
@@ -62,7 +59,7 @@
             BufferingSettings* buffering /* nonnull */) override;
     virtual status_t setBufferingSettings(const BufferingSettings& buffering) override;
 
-    virtual void prepareAsync();
+    virtual void prepareAsync(int64_t startTimeUs);
 
     virtual void start();
     virtual void stop();
@@ -151,7 +148,6 @@
     bool mIsStreaming;
     uid_t mUID;
     const sp<MediaClock> mMediaClock;
-    sp<MediaHTTPService> mHTTPService;
     AString mUri;
     KeyedVector<String8, String8> mUriHeaders;
     int mFd;
@@ -159,9 +155,6 @@
     int64_t mLength;
 
     bool mDisconnected;
-    sp<DataSource> mDataSource;
-    sp<NuCachedSource2> mCachedSource;
-    sp<DataSource> mHttpSource;
     sp<MetaData> mFileMeta;
     sp<AMediaDataSourceWrapper> mDataSourceWrapper;
     sp<AMediaExtractorWrapper> mExtractor;
@@ -194,7 +187,7 @@
     void onSeek(const sp<AMessage>& msg);
     status_t doSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode);
 
-    void onPrepareAsync();
+    void onPrepareAsync(int64_t startTimeUs);
 
     void fetchTextData(
             uint32_t what, media_track_type type,
@@ -232,8 +225,6 @@
     void onPollBuffering();
     void notifyBufferingUpdate(int32_t percentage);
 
-    void sendCacheStats();
-
     sp<AMessage> getFormat_l(bool audio);
     sp<MetaData> getFormatMeta_l(bool audio);
     int32_t getDataGeneration(media_track_type type) const;
diff --git a/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.cpp b/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.cpp
index a61cacd..e53900b 100644
--- a/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.cpp
+++ b/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.cpp
@@ -99,10 +99,11 @@
     return OK;
 }
 
-void NuPlayer2::HTTPLiveSource2::prepareAsync() {
+// TODO: fetch data starting from |startTimeUs|
+void NuPlayer2::HTTPLiveSource2::prepareAsync(int64_t /* startTimeUs */) {
     if (mLiveLooper == NULL) {
         mLiveLooper = new ALooper;
-        mLiveLooper->setName("http live");
+        mLiveLooper->setName("http live2");
         mLiveLooper->start(false, /* runOnCallingThread */
                            true /* canCallJava */);
 
@@ -272,10 +273,10 @@
 
         if (fetchType == LiveSession::STREAMTYPE_SUBTITLES) {
             notify->post();
-            msg->post(delayUs > 0ll ? delayUs : 0ll);
+            msg->post(delayUs > 0LL ? delayUs : 0LL);
             return;
         } else if (fetchType == LiveSession::STREAMTYPE_METADATA) {
-            if (delayUs < -1000000ll) { // 1 second
+            if (delayUs < -1000000LL) { // 1 second
                 continue;
             }
             notify->post();
@@ -287,7 +288,7 @@
     }
 
     // try again in 1 second
-    msg->post(1000000ll);
+    msg->post(1000000LL);
 }
 
 void NuPlayer2::HTTPLiveSource2::onMessageReceived(const sp<AMessage> &msg) {
diff --git a/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.h b/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.h
index 97d3653..8fc71e2 100644
--- a/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.h
+++ b/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.h
@@ -38,7 +38,7 @@
             BufferingSettings* buffering /* nonnull */) override;
     virtual status_t setBufferingSettings(const BufferingSettings& buffering) override;
 
-    virtual void prepareAsync();
+    virtual void prepareAsync(int64_t startTimeUs);
     virtual void start();
 
     virtual status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit);
diff --git a/media/libmediaplayer2/nuplayer2/JMediaPlayer2Utils.cpp b/media/libmediaplayer2/nuplayer2/JMediaPlayer2Utils.cpp
new file mode 100644
index 0000000..89703de
--- /dev/null
+++ b/media/libmediaplayer2/nuplayer2/JMediaPlayer2Utils.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "JMediaPlayer2Utils"
+
+#include "JMediaPlayer2Utils.h"
+#include <mediaplayer2/JavaVMHelper.h>
+
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/Utils.h>
+#include <utils/Log.h>
+
+#include "log/log.h"
+
+namespace android {
+
+static const int64_t kOffloadMinDurationSec = 60;
+
+// static
+bool JMediaPlayer2Utils::isOffloadedAudioPlaybackSupported(
+        const sp<MetaData>& meta, bool hasVideo, bool isStreaming, audio_stream_type_t streamType)
+{
+    if (hasVideo || streamType != AUDIO_STREAM_MUSIC) {
+        return false;
+    }
+
+    audio_offload_info_t info = AUDIO_INFO_INITIALIZER;
+    if (OK != getAudioOffloadInfo(meta, hasVideo, isStreaming, streamType, &info)) {
+        return false;
+    }
+
+    if (info.duration_us < kOffloadMinDurationSec * 1000000) {
+        return false;
+    }
+
+    int32_t audioFormat = audioFormatFromNative(info.format);
+    int32_t channelMask = outChannelMaskFromNative(info.channel_mask);
+    if (audioFormat == ENCODING_INVALID || channelMask == CHANNEL_INVALID) {
+        return false;
+    }
+
+    JNIEnv* env = JavaVMHelper::getJNIEnv();
+    jclass jMP2UtilsCls = env->FindClass("android/media/MediaPlayer2Utils");
+    jmethodID jSetAudioOutputDeviceById = env->GetStaticMethodID(
+            jMP2UtilsCls, "isOffloadedAudioPlaybackSupported", "(III)Z");
+    jboolean result = env->CallStaticBooleanMethod(
+            jMP2UtilsCls, jSetAudioOutputDeviceById, audioFormat, info.sample_rate, channelMask);
+    return result;
+}
+
+}  // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/JMediaPlayer2Utils.h b/media/libmediaplayer2/nuplayer2/JMediaPlayer2Utils.h
new file mode 100644
index 0000000..fcbd43c
--- /dev/null
+++ b/media/libmediaplayer2/nuplayer2/JMediaPlayer2Utils.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _J_MEDIAPLAYER2_UTILS2_H_
+#define _J_MEDIAPLAYER2_UTILS2_H_
+
+#include <media/stagefright/MetaData.h>
+
+#include "jni.h"
+#include "android_media_AudioFormat.h"
+
+namespace android {
+
+struct JMediaPlayer2Utils {
+    static bool isOffloadedAudioPlaybackSupported(
+            const sp<MetaData>& meta, bool hasVideo, bool isStreaming,
+            audio_stream_type_t streamType);
+};
+
+}  // namespace android
+
+#endif  // _J_MEDIAPLAYER2_UTILS2_H_
diff --git a/media/libmediaplayer2/nuplayer2/JWakeLock.cpp b/media/libmediaplayer2/nuplayer2/JWakeLock.cpp
index c9a1071..983d77e 100644
--- a/media/libmediaplayer2/nuplayer2/JWakeLock.cpp
+++ b/media/libmediaplayer2/nuplayer2/JWakeLock.cpp
@@ -20,55 +20,50 @@
 
 #include "JWakeLock.h"
 
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
 #include <media/stagefright/foundation/ADebug.h>
-#include <powermanager/PowerManager.h>
-
 
 namespace android {
 
-//TODO: use JAVA PowerManager, instead of binder
-JWakeLock::JWakeLock() :
-    mPowerManager(NULL),
-    mWakeLockToken(NULL),
+JWakeLock::JWakeLock(const sp<JObjectHolder> &context) :
     mWakeLockCount(0),
-    mDeathRecipient(new PMDeathRecipient(this)) {}
+    mWakeLock(NULL),
+    mContext(context) {}
 
 JWakeLock::~JWakeLock() {
-    if (mPowerManager != NULL) {
-        sp<IBinder> binder = IInterface::asBinder(mPowerManager);
-        binder->unlinkToDeath(mDeathRecipient);
-    }
-    clearPowerManager();
+    clearJavaWakeLock();
 }
 
 bool JWakeLock::acquire() {
     if (mWakeLockCount == 0) {
-        CHECK(mWakeLockToken == NULL);
-        if (mPowerManager == NULL) {
-            // use checkService() to avoid blocking if power service is not up yet
-            sp<IBinder> binder =
-                defaultServiceManager()->checkService(String16("power"));
-            if (binder == NULL) {
-                ALOGW("could not get the power manager service");
-            } else {
-                mPowerManager = interface_cast<IPowerManager>(binder);
-                binder->linkToDeath(mDeathRecipient);
-            }
+        if (mWakeLock == NULL) {
+            JNIEnv *env = JavaVMHelper::getJNIEnv();
+            jclass jContextCls = env->FindClass("android/content/Context");
+            jclass jPowerManagerCls = env->FindClass("android/os/PowerManager");
+
+            jmethodID jGetSystemService = env->GetMethodID(jContextCls,
+                    "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
+            jobject javaPowerManagerObj = env->CallObjectMethod(mContext->getJObject(),
+                    jGetSystemService, env->NewStringUTF("power"));
+
+            jfieldID jPARTIAL_WAKE_LOCK = env->GetStaticFieldID(jPowerManagerCls,
+                    "PARTIAL_WAKE_LOCK", "I");
+            jint PARTIAL_WAKE_LOCK = env->GetStaticIntField(jPowerManagerCls, jPARTIAL_WAKE_LOCK);
+
+            jmethodID jNewWakeLock = env->GetMethodID(jPowerManagerCls,
+                    "newWakeLock", "(ILjava/lang/String;)Landroid/os/PowerManager$WakeLock;");
+            jobject javaWakeLock = env->CallObjectMethod(javaPowerManagerObj,
+                    jNewWakeLock, PARTIAL_WAKE_LOCK, env->NewStringUTF("JWakeLock"));
+            mWakeLock = new JObjectHolder(javaWakeLock);
+            env->DeleteLocalRef(javaPowerManagerObj);
+            env->DeleteLocalRef(javaWakeLock);
         }
-        if (mPowerManager != NULL) {
-            sp<IBinder> binder = new BBinder();
-            int64_t token = IPCThreadState::self()->clearCallingIdentity();
-            status_t status = mPowerManager->acquireWakeLock(
-                    POWERMANAGER_PARTIAL_WAKE_LOCK,
-                    binder, String16("JWakeLock"), String16("media"));
-            IPCThreadState::self()->restoreCallingIdentity(token);
-            if (status == NO_ERROR) {
-                mWakeLockToken = binder;
-                mWakeLockCount++;
-                return true;
-            }
+        if (mWakeLock != NULL) {
+            JNIEnv *env = JavaVMHelper::getJNIEnv();
+            jclass wakeLockCls = env->FindClass("android/os/PowerManager$WakeLock");
+            jmethodID jAcquire = env->GetMethodID(wakeLockCls, "acquire", "()V");
+            env->CallVoidMethod(mWakeLock->getJObject(), jAcquire);
+            mWakeLockCount++;
+            return true;
         }
     } else {
         mWakeLockCount++;
@@ -86,25 +81,17 @@
         mWakeLockCount = 1;
     }
     if (--mWakeLockCount == 0) {
-        CHECK(mWakeLockToken != NULL);
-        if (mPowerManager != NULL) {
-            int64_t token = IPCThreadState::self()->clearCallingIdentity();
-            mPowerManager->releaseWakeLock(mWakeLockToken, 0 /* flags */);
-            IPCThreadState::self()->restoreCallingIdentity(token);
+        if (mWakeLock != NULL) {
+            JNIEnv *env = JavaVMHelper::getJNIEnv();
+            jclass wakeLockCls = env->FindClass("android/os/PowerManager$WakeLock");
+            jmethodID jRelease = env->GetMethodID(wakeLockCls, "release", "()V");
+            env->CallVoidMethod(mWakeLock->getJObject(), jRelease);
         }
-        mWakeLockToken.clear();
     }
 }
 
-void JWakeLock::clearPowerManager() {
+void JWakeLock::clearJavaWakeLock() {
     release(true);
-    mPowerManager.clear();
-}
-
-void JWakeLock::PMDeathRecipient::binderDied(const wp<IBinder>& who __unused) {
-    if (mWakeLock != NULL) {
-        mWakeLock->clearPowerManager();
-    }
 }
 
 }  // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/JWakeLock.h b/media/libmediaplayer2/nuplayer2/JWakeLock.h
index eace87e..36c542e 100644
--- a/media/libmediaplayer2/nuplayer2/JWakeLock.h
+++ b/media/libmediaplayer2/nuplayer2/JWakeLock.h
@@ -18,7 +18,7 @@
 #define J_WAKELOCK_H_
 
 #include <media/stagefright/foundation/ABase.h>
-#include <powermanager/IPowerManager.h>
+#include <mediaplayer2/JObjectHolder.h>
 #include <utils/RefBase.h>
 
 namespace android {
@@ -26,7 +26,7 @@
 class JWakeLock : public RefBase {
 
 public:
-    JWakeLock();
+    JWakeLock(const sp<JObjectHolder> &context);
 
     // NOTE: acquire and release are not thread safe
 
@@ -37,28 +37,11 @@
     virtual ~JWakeLock();
 
 private:
-    sp<IPowerManager> mPowerManager;
-    sp<IBinder>       mWakeLockToken;
-    uint32_t          mWakeLockCount;
+    uint32_t                mWakeLockCount;
+    sp<JObjectHolder>       mWakeLock;
+    const sp<JObjectHolder> mContext;
 
-    class PMDeathRecipient : public IBinder::DeathRecipient {
-    public:
-        explicit PMDeathRecipient(JWakeLock *wakeLock) : mWakeLock(wakeLock) {}
-        virtual ~PMDeathRecipient() {}
-
-        // IBinder::DeathRecipient
-        virtual void binderDied(const wp<IBinder> &who);
-
-    private:
-        PMDeathRecipient(const PMDeathRecipient&);
-        PMDeathRecipient& operator= (const PMDeathRecipient&);
-
-        JWakeLock *mWakeLock;
-    };
-
-    const sp<PMDeathRecipient> mDeathRecipient;
-
-    void clearPowerManager();
+    void clearJavaWakeLock();
 
     DISALLOW_EVIL_CONSTRUCTORS(JWakeLock);
 };
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
index 060b698..d608d4a 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
@@ -24,6 +24,7 @@
 #include "NuPlayer2.h"
 
 #include "HTTPLiveSource2.h"
+#include "JMediaPlayer2Utils.h"
 #include "NuPlayer2CCDecoder.h"
 #include "NuPlayer2Decoder.h"
 #include "NuPlayer2DecoderBase.h"
@@ -33,7 +34,7 @@
 #include "NuPlayer2Source.h"
 #include "RTSPSource2.h"
 #include "GenericSource2.h"
-#include "TextDescriptions.h"
+#include "TextDescriptions2.h"
 
 #include "ATSParser.h"
 
@@ -208,15 +209,16 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-NuPlayer2::NuPlayer2(pid_t pid, uid_t uid, const sp<MediaClock> &mediaClock)
+NuPlayer2::NuPlayer2(
+        pid_t pid, uid_t uid, const sp<MediaClock> &mediaClock, const sp<JObjectHolder> &context)
     : mPID(pid),
       mUID(uid),
       mMediaClock(mediaClock),
-      mSourceFlags(0),
       mOffloadAudio(false),
       mAudioDecoderGeneration(0),
       mVideoDecoderGeneration(0),
       mRendererGeneration(0),
+      mEOSMonitorGeneration(0),
       mLastStartedPlayingTimeNs(0),
       mPreviousSeekTimeUs(0),
       mAudioEOS(false),
@@ -240,8 +242,7 @@
       mPaused(false),
       mPausedByClient(true),
       mPausedForBuffering(false),
-      mIsDrmProtected(false),
-      mDataSourceType(DATA_SOURCE_TYPE_NONE) {
+      mContext(context) {
     CHECK(mediaClock != NULL);
     clearFlushComplete();
 }
@@ -309,7 +310,7 @@
                 sp<GenericSource2> genericSource =
                         new GenericSource2(notify, mUID, mMediaClock);
 
-                err = genericSource->setDataSource(httpService, url, headers);
+                err = genericSource->setDataSource(url, headers);
 
                 if (err == OK) {
                     *source = genericSource;
@@ -393,11 +394,13 @@
     // Now, source != NULL.
     */
 
-    mDataSourceType = dataSourceType;
+    mCurrentSourceInfo.mDataSourceType = dataSourceType;
 
     sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
     msg->setObject("source", source);
     msg->setInt64("srcId", dsd->mId);
+    msg->setInt64("startTimeUs", dsd->mStartPositionMs * 1000);
+    msg->setInt64("endTimeUs", dsd->mEndPositionMs * 1000);
     msg->post();
 }
 
@@ -415,11 +418,13 @@
     // Now, source != NULL.
     */
 
-    mNextDataSourceType = dataSourceType;
+    mNextSourceInfo.mDataSourceType = dataSourceType;
 
     sp<AMessage> msg = new AMessage(kWhatPrepareNextDataSource, this);
     msg->setObject("source", source);
     msg->setInt64("srcId", dsd->mId);
+    msg->setInt64("startTimeUs", dsd->mStartPositionMs * 1000);
+    msg->setInt64("endTimeUs", dsd->mEndPositionMs * 1000);
     msg->post();
 }
 
@@ -487,7 +492,7 @@
 status_t NuPlayer2::setPlaybackSettings(const AudioPlaybackRate &rate) {
     // do some cursory validation of the settings here. audio modes are
     // only validated when set on the audiosink.
-     if ((rate.mSpeed != 0.f && rate.mSpeed < AUDIO_TIMESTRETCH_SPEED_MIN)
+     if (rate.mSpeed < AUDIO_TIMESTRETCH_SPEED_MIN
             || rate.mSpeed > AUDIO_TIMESTRETCH_SPEED_MAX
             || rate.mPitch < AUDIO_TIMESTRETCH_SPEED_MIN
             || rate.mPitch > AUDIO_TIMESTRETCH_SPEED_MAX) {
@@ -554,7 +559,7 @@
     sp<Source> source;
     {
         Mutex::Autolock autoLock(mSourceLock);
-        source = mSource;
+        source = mCurrentSourceInfo.mSource;
     }
 
     if (source != NULL) {
@@ -584,9 +589,13 @@
     msg->post();
 }
 
+void NuPlayer2::rewind() {
+    sp<AMessage> msg = new AMessage(kWhatRewind, this);
+    msg->post();
+}
 
 void NuPlayer2::writeTrackInfo(
-        Parcel* reply, const sp<AMessage>& format) const {
+        PlayerMessage* reply, const sp<AMessage>& format) const {
     if (format == NULL) {
         ALOGE("NULL format");
         return;
@@ -619,10 +628,9 @@
         return;
     }
 
-    reply->writeInt32(2); // write something non-zero
-    reply->writeInt32(trackType);
-    reply->writeString16(String16(mime.c_str()));
-    reply->writeString16(String16(lang.c_str()));
+    reply->add_values()->set_int32_value(trackType);
+    reply->add_values()->set_string_value(mime.c_str());
+    reply->add_values()->set_string_value(lang.c_str());
 
     if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
         int32_t isAuto, isDefault, isForced;
@@ -630,27 +638,30 @@
         CHECK(format->findInt32("default", &isDefault));
         CHECK(format->findInt32("forced", &isForced));
 
-        reply->writeInt32(isAuto);
-        reply->writeInt32(isDefault);
-        reply->writeInt32(isForced);
+        reply->add_values()->set_int32_value(isAuto);
+        reply->add_values()->set_int32_value(isDefault);
+        reply->add_values()->set_int32_value(isForced);
     }
 }
 
 void NuPlayer2::onMessageReceived(const sp<AMessage> &msg) {
+
     switch (msg->what()) {
         case kWhatSetDataSource:
         {
             ALOGV("kWhatSetDataSource");
 
-            CHECK(mSource == NULL);
+            CHECK(mCurrentSourceInfo.mSource == NULL);
 
             status_t err = OK;
             sp<RefBase> obj;
             CHECK(msg->findObject("source", &obj));
             if (obj != NULL) {
                 Mutex::Autolock autoLock(mSourceLock);
-                CHECK(msg->findInt64("srcId", &mSrcId));
-                mSource = static_cast<Source *>(obj.get());
+                CHECK(msg->findInt64("srcId", &mCurrentSourceInfo.mSrcId));
+                CHECK(msg->findInt64("startTimeUs", &mCurrentSourceInfo.mStartTimeUs));
+                CHECK(msg->findInt64("endTimeUs", &mCurrentSourceInfo.mEndTimeUs));
+                mCurrentSourceInfo.mSource = static_cast<Source *>(obj.get());
             } else {
                 err = UNKNOWN_ERROR;
                 ALOGE("kWhatSetDataSource, source should not be NULL");
@@ -659,7 +670,7 @@
             CHECK(mDriver != NULL);
             sp<NuPlayer2Driver> driver = mDriver.promote();
             if (driver != NULL) {
-                driver->notifySetDataSourceCompleted(mSrcId, err);
+                driver->notifySetDataSourceCompleted(mCurrentSourceInfo.mSrcId, err);
             }
             break;
         }
@@ -673,9 +684,11 @@
             CHECK(msg->findObject("source", &obj));
             if (obj != NULL) {
                 Mutex::Autolock autoLock(mSourceLock);
-                CHECK(msg->findInt64("srcId", &mNextSrcId));
-                mNextSource = static_cast<Source *>(obj.get());
-                mNextSource->prepareAsync();
+                CHECK(msg->findInt64("srcId", &mNextSourceInfo.mSrcId));
+                CHECK(msg->findInt64("startTimeUs", &mNextSourceInfo.mStartTimeUs));
+                CHECK(msg->findInt64("endTimeUs", &mNextSourceInfo.mEndTimeUs));
+                mNextSourceInfo.mSource = static_cast<Source *>(obj.get());
+                mNextSourceInfo.mSource->prepareAsync(mNextSourceInfo.mStartTimeUs);
             } else {
                 err = UNKNOWN_ERROR;
             }
@@ -688,7 +701,7 @@
             ALOGV("kWhatPlayNextDataSource");
             int64_t srcId;
             CHECK(msg->findInt64("srcId", &srcId));
-            if (srcId != mNextSrcId) {
+            if (srcId != mNextSourceInfo.mSrcId) {
                 notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, 0);
                 return;
             }
@@ -709,6 +722,22 @@
             break;
         }
 
+        case kWhatEOSMonitor:
+        {
+            int32_t generation;
+            CHECK(msg->findInt32("generation", &generation));
+            int32_t reason;
+            CHECK(msg->findInt32("reason", &reason));
+
+            if (generation != mEOSMonitorGeneration || reason != MediaClock::TIMER_REASON_REACHED) {
+                break;  // stale or reset
+            }
+
+            ALOGV("kWhatEOSMonitor");
+            notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
+            break;
+        }
+
         case kWhatGetBufferingSettings:
         {
             sp<AReplyToken> replyID;
@@ -717,8 +746,8 @@
             ALOGV("kWhatGetBufferingSettings");
             BufferingSettings buffering;
             status_t err = OK;
-            if (mSource != NULL) {
-                err = mSource->getBufferingSettings(&buffering);
+            if (mCurrentSourceInfo.mSource != NULL) {
+                err = mCurrentSourceInfo.mSource->getBufferingSettings(&buffering);
             } else {
                 err = INVALID_OPERATION;
             }
@@ -740,8 +769,8 @@
             BufferingSettings buffering;
             readFromAMessage(msg, &buffering);
             status_t err = OK;
-            if (mSource != NULL) {
-                err = mSource->setBufferingSettings(buffering);
+            if (mCurrentSourceInfo.mSource != NULL) {
+                err = mCurrentSourceInfo.mSource->setBufferingSettings(buffering);
             } else {
                 err = INVALID_OPERATION;
             }
@@ -755,7 +784,7 @@
         {
             ALOGV("onMessageReceived kWhatPrepare");
 
-            mSource->prepareAsync();
+            mCurrentSourceInfo.mSource->prepareAsync(mCurrentSourceInfo.mStartTimeUs);
             break;
         }
 
@@ -764,12 +793,16 @@
             sp<AReplyToken> replyID;
             CHECK(msg->senderAwaitsResponse(&replyID));
 
-            Parcel* reply;
+            int64_t srcId;
+            CHECK(msg->findInt64("srcId", (int64_t*)&srcId));
+
+            PlayerMessage* reply;
             CHECK(msg->findPointer("reply", (void**)&reply));
 
+            // TODO: use correct source info based on srcId.
             size_t inbandTracks = 0;
-            if (mSource != NULL) {
-                inbandTracks = mSource->getTrackCount();
+            if (mCurrentSourceInfo.mSource != NULL) {
+                inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
             }
 
             size_t ccTracks = 0;
@@ -778,11 +811,11 @@
             }
 
             // total track count
-            reply->writeInt32(inbandTracks + ccTracks);
+            reply->add_values()->set_int32_value(inbandTracks + ccTracks);
 
             // write inband tracks
             for (size_t i = 0; i < inbandTracks; ++i) {
-                writeTrackInfo(reply, mSource->getTrackInfo(i));
+                writeTrackInfo(reply, mCurrentSourceInfo.mSource->getTrackInfo(i));
             }
 
             // write CC track
@@ -797,20 +830,35 @@
 
         case kWhatGetSelectedTrack:
         {
+            int64_t srcId;
+            CHECK(msg->findInt64("srcId", (int64_t*)&srcId));
+
+            int32_t type32;
+            CHECK(msg->findInt32("type", (int32_t*)&type32));
+            media_track_type type = (media_track_type)type32;
+
+            // TODO: use correct source info based on srcId.
+            size_t inbandTracks = 0;
             status_t err = INVALID_OPERATION;
-            if (mSource != NULL) {
+            ssize_t selectedTrack = -1;
+            if (mCurrentSourceInfo.mSource != NULL) {
                 err = OK;
-
-                int32_t type32;
-                CHECK(msg->findInt32("type", (int32_t*)&type32));
-                media_track_type type = (media_track_type)type32;
-                ssize_t selectedTrack = mSource->getSelectedTrack(type);
-
-                Parcel* reply;
-                CHECK(msg->findPointer("reply", (void**)&reply));
-                reply->writeInt32(selectedTrack);
+                inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
+                selectedTrack = mCurrentSourceInfo.mSource->getSelectedTrack(type);
             }
 
+            if (selectedTrack == -1 && mCCDecoder != NULL) {
+                err = OK;
+                selectedTrack = mCCDecoder->getSelectedTrack(type);
+                if (selectedTrack != -1) {
+                    selectedTrack += inbandTracks;
+                }
+            }
+
+            PlayerMessage* reply;
+            CHECK(msg->findPointer("reply", (void**)&reply));
+            reply->add_values()->set_int32_value(selectedTrack);
+
             sp<AMessage> response = new AMessage;
             response->setInt32("err", err);
 
@@ -825,18 +873,21 @@
             sp<AReplyToken> replyID;
             CHECK(msg->senderAwaitsResponse(&replyID));
 
+            int64_t srcId;
             size_t trackIndex;
             int32_t select;
             int64_t timeUs;
+            CHECK(msg->findInt64("srcId", (int64_t*)&srcId));
             CHECK(msg->findSize("trackIndex", &trackIndex));
             CHECK(msg->findInt32("select", &select));
             CHECK(msg->findInt64("timeUs", &timeUs));
 
             status_t err = INVALID_OPERATION;
 
+            // TODO: use correct source info based on srcId.
             size_t inbandTracks = 0;
-            if (mSource != NULL) {
-                inbandTracks = mSource->getTrackCount();
+            if (mCurrentSourceInfo.mSource != NULL) {
+                inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
             }
             size_t ccTracks = 0;
             if (mCCDecoder != NULL) {
@@ -844,11 +895,11 @@
             }
 
             if (trackIndex < inbandTracks) {
-                err = mSource->selectTrack(trackIndex, select, timeUs);
+                err = mCurrentSourceInfo.mSource->selectTrack(trackIndex, select, timeUs);
 
                 if (!select && err == OK) {
                     int32_t type;
-                    sp<AMessage> info = mSource->getTrackInfo(trackIndex);
+                    sp<AMessage> info = mCurrentSourceInfo.mSource->getTrackInfo(trackIndex);
                     if (info != NULL
                             && info->findInt32("type", &type)
                             && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
@@ -881,14 +932,14 @@
             }
 
             int64_t durationUs;
-            if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
+            if (mDriver != NULL && mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
                 sp<NuPlayer2Driver> driver = mDriver.promote();
                 if (driver != NULL) {
-                    driver->notifyDuration(mSrcId, durationUs);
+                    driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
                 }
             }
 
-            msg->post(1000000ll);  // poll again in a second.
+            msg->post(1000000LL);  // poll again in a second.
             break;
         }
 
@@ -901,13 +952,15 @@
 
             ALOGD("onSetVideoSurface(%p, %s video decoder)",
                     (nww == NULL ? NULL : nww->getANativeWindow()),
-                    (mSource != NULL && mStarted && mSource->getFormat(false /* audio */) != NULL
+                    (mCurrentSourceInfo.mSource != NULL && mStarted
+                            && mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL
                             && mVideoDecoder != NULL) ? "have" : "no");
 
-            // Need to check mStarted before calling mSource->getFormat because NuPlayer2 might
-            // be in preparing state and it could take long time.
-            // When mStarted is true, mSource must have been set.
-            if (mSource == NULL || !mStarted || mSource->getFormat(false /* audio */) == NULL
+            // Need to check mStarted before calling mCurrentSourceInfo.mSource->getFormat
+            // because NuPlayer2 might be in preparing state and it could take long time.
+            // When mStarted is true, mCurrentSourceInfo.mSource must have been set.
+            if (mCurrentSourceInfo.mSource == NULL || !mStarted
+                    || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
                     // NOTE: mVideoDecoder's mNativeWindow is always non-null
                     || (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(nww) == OK)) {
                 performSetSurface(nww);
@@ -971,10 +1024,10 @@
                     onResume();
                 }
             } else {
-                onStart();
+                onStart(true /* play */);
             }
             mPausedByClient = false;
-            notifyListener(mSrcId, MEDIA2_STARTED, 0, 0);
+            notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
             break;
         }
 
@@ -988,8 +1041,7 @@
             if (mRenderer != NULL) {
                 // AudioSink allows only 1.f and 0.f for offload mode.
                 // For other speed, switch to non-offload mode.
-                if (mOffloadAudio && ((rate.mSpeed != 0.f && rate.mSpeed != 1.f)
-                        || rate.mPitch != 1.f)) {
+                if (mOffloadAudio && (rate.mSpeed != 1.f || rate.mPitch != 1.f)) {
                     int64_t currentPositionUs;
                     if (getCurrentPosition(&currentPositionUs) != OK) {
                         currentPositionUs = mPreviousSeekTimeUs;
@@ -1012,36 +1064,15 @@
                 err = mRenderer->setPlaybackSettings(rate);
             }
             if (err == OK) {
-                if (rate.mSpeed == 0.f) {
-                    onPause();
-                    notifyListener(mSrcId, MEDIA2_PAUSED, 0, 0);
-                    mPausedByClient = true;
-                    // save all other settings (using non-paused speed)
-                    // so we can restore them on start
-                    AudioPlaybackRate newRate = rate;
-                    newRate.mSpeed = mPlaybackSettings.mSpeed;
-                    mPlaybackSettings = newRate;
-                } else { /* rate.mSpeed != 0.f */
-                    mPlaybackSettings = rate;
-                    if (mStarted) {
-                        // do not resume yet if the source is still buffering
-                        if (!mPausedForBuffering) {
-                            onResume();
-                        }
-                    } else if (mPrepared) {
-                        onStart();
-                    }
+                mPlaybackSettings = rate;
 
-                    mPausedByClient = false;
+                if (mVideoDecoder != NULL) {
+                    sp<AMessage> params = new AMessage();
+                    params->setFloat("playback-speed", mPlaybackSettings.mSpeed);
+                    mVideoDecoder->setParameters(params);
                 }
             }
 
-            if (mVideoDecoder != NULL) {
-                sp<AMessage> params = new AMessage();
-                params->setFloat("playback-speed", mPlaybackSettings.mSpeed);
-                mVideoDecoder->setParameters(params);
-            }
-
             sp<AMessage> response = new AMessage;
             response->setInt32("err", err);
             response->postReply(replyID);
@@ -1061,9 +1092,6 @@
                 // get playback settings used by renderer, as it may be
                 // slightly off due to audiosink not taking small changes.
                 mPlaybackSettings = rate;
-                if (mPaused) {
-                    rate.mSpeed = 0.f;
-                }
             }
             sp<AMessage> response = new AMessage;
             if (err == OK) {
@@ -1157,28 +1185,29 @@
                     && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
                 // This is the first time we've found anything playable.
 
-                if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
+                if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
                     schedulePollDuration();
                 }
             }
 
             status_t err;
-            if ((err = mSource->feedMoreTSData()) != OK) {
+            if ((err = mCurrentSourceInfo.mSource->feedMoreTSData()) != OK) {
                 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
                     // We're not currently decoding anything (no audio or
                     // video tracks found) and we just ran out of input data.
 
                     if (err == ERROR_END_OF_STREAM) {
-                        notifyListener(mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
+                        notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
                     } else {
-                        notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
+                        notifyListener(
+                                mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
                     }
                 }
                 break;
             }
 
             if (rescan) {
-                msg->post(100000ll);
+                msg->post(100000LL);
                 mScanSourcesPending = true;
             }
             break;
@@ -1253,13 +1282,14 @@
                 CHECK(msg->findMessage("format", &format));
 
                 sp<AMessage> inputFormat =
-                        mSource->getFormat(false /* audio */);
+                        mCurrentSourceInfo.mSource->getFormat(false /* audio */);
 
                 setVideoScalingMode(mVideoScalingMode);
-                updateVideoSize(mSrcId, inputFormat, format);
+                updateVideoSize(mCurrentSourceInfo.mSrcId, inputFormat, format);
             } else if (what == DecoderBase::kWhatShutdownCompleted) {
                 ALOGV("%s shutdown completed", audio ? "audio" : "video");
                 if (audio) {
+                    Mutex::Autolock autoLock(mDecoderLock);
                     mAudioDecoder.clear();
                     mAudioDecoderError = false;
                     ++mAudioDecoderGeneration;
@@ -1267,6 +1297,7 @@
                     CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
                     mFlushingAudio = SHUT_DOWN;
                 } else {
+                    Mutex::Autolock autoLock(mDecoderLock);
                     mVideoDecoder.clear();
                     mVideoDecoderError = false;
                     ++mVideoDecoderGeneration;
@@ -1323,28 +1354,39 @@
                         finishFlushIfPossible();  // Should not occur.
                         break;                    // Finish anyways.
                 }
-                if (mSource != nullptr) {
+                if (mCurrentSourceInfo.mSource != nullptr) {
                     if (audio) {
-                        if (mVideoDecoderError || mSource->getFormat(false /* audio */) == NULL
-                                || mNativeWindow == NULL || mNativeWindow->getANativeWindow() == NULL
+                        if (mVideoDecoderError
+                                || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
+                                || mNativeWindow == NULL
+                                || mNativeWindow->getANativeWindow() == NULL
                                 || mVideoDecoder == NULL) {
                             // When both audio and video have error, or this stream has only audio
                             // which has error, notify client of error.
-                            notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
+                            notifyListener(
+                                    mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
+                                    MEDIA2_ERROR_UNKNOWN, err);
                         } else {
                             // Only audio track has error. Video track could be still good to play.
-                            notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_PLAY_AUDIO_ERROR, err);
+                            notifyListener(
+                                    mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
+                                    MEDIA2_INFO_PLAY_AUDIO_ERROR, err);
                         }
                         mAudioDecoderError = true;
                     } else {
-                        if (mAudioDecoderError || mSource->getFormat(true /* audio */) == NULL
+                        if (mAudioDecoderError
+                                || mCurrentSourceInfo.mSource->getFormat(true /* audio */) == NULL
                                 || mAudioSink == NULL || mAudioDecoder == NULL) {
                             // When both audio and video have error, or this stream has only video
                             // which has error, notify client of error.
-                            notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
+                            notifyListener(
+                                    mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
+                                    MEDIA2_ERROR_UNKNOWN, err);
                         } else {
                             // Only video track has error. Audio track could be still good to play.
-                            notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_PLAY_VIDEO_ERROR, err);
+                            notifyListener(
+                                    mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
+                                    MEDIA2_INFO_PLAY_VIDEO_ERROR, err);
                         }
                         mVideoDecoderError = true;
                     }
@@ -1394,12 +1436,13 @@
                          audio ? "audio" : "video", finalResult);
 
                     notifyListener(
-                            mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, finalResult);
+                            mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
+                            MEDIA2_ERROR_UNKNOWN, finalResult);
                 }
 
                 if ((mAudioEOS || mAudioDecoder == NULL)
                         && (mVideoEOS || mVideoDecoder == NULL)) {
-                    notifyListener(mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
+                    notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
                 }
             } else if (what == Renderer::kWhatFlushComplete) {
                 int32_t audio;
@@ -1420,10 +1463,11 @@
                 handleFlushComplete(audio, false /* isDecoder */);
                 finishFlushIfPossible();
             } else if (what == Renderer::kWhatVideoRenderingStart) {
-                notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_VIDEO_RENDERING_START, 0);
+                notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
+                               MEDIA2_INFO_VIDEO_RENDERING_START, 0);
             } else if (what == Renderer::kWhatMediaRenderingStart) {
                 ALOGV("media rendering started");
-                notifyListener(mSrcId, MEDIA2_STARTED, 0, 0);
+                notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
             } else if (what == Renderer::kWhatAudioTearDown) {
                 int32_t reason;
                 CHECK(msg->findInt32("reason", &reason));
@@ -1476,7 +1520,7 @@
             int64_t timerUs;
             CHECK(msg->findInt64("timerUs", &timerUs));
 
-            notifyListener(mSrcId, MEDIA2_NOTIFY_TIME, timerUs, 0);
+            notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_NOTIFY_TIME, timerUs, 0);
             break;
         }
 
@@ -1495,20 +1539,20 @@
             if (!mStarted) {
                 if (!mSourceStarted) {
                     mSourceStarted = true;
-                    mSource->start();
+                    mCurrentSourceInfo.mSource->start();
                 }
                 if (seekTimeUs > 0) {
                     performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
                 }
 
                 if (needNotify) {
-                    notifyDriverSeekComplete(mSrcId);
+                    notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
                 }
                 break;
             }
 
             // seeks can take a while, so we essentially paused
-            notifyListener(mSrcId, MEDIA2_PAUSED, 0, 0);
+            notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
 
             mDeferredActions.push_back(
                     new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
@@ -1527,10 +1571,49 @@
             break;
         }
 
+        case kWhatRewind:
+        {
+            ALOGV("kWhatRewind");
+
+            int64_t seekTimeUs = mCurrentSourceInfo.mStartTimeUs;
+            int32_t mode = MediaPlayer2SeekMode::SEEK_CLOSEST;
+
+            if (!mStarted) {
+                if (!mSourceStarted) {
+                    mSourceStarted = true;
+                    mCurrentSourceInfo.mSource->start();
+                }
+                performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
+                break;
+            }
+
+            // seeks can take a while, so we essentially paused
+            notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
+
+            mDeferredActions.push_back(
+                    new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
+                                           FLUSH_CMD_FLUSH /* video */));
+
+            mDeferredActions.push_back(
+                    new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
+
+            // After a flush without shutdown, decoder is paused.
+            // Don't resume it until source seek is done, otherwise it could
+            // start pulling stale data too soon.
+            mDeferredActions.push_back(
+                    new ResumeDecoderAction(false /* needNotify */));
+
+            processDeferredActions();
+            break;
+        }
+
         case kWhatPause:
         {
+            if (!mStarted) {
+                onStart(false /* play */);
+            }
             onPause();
-            notifyListener(mSrcId, MEDIA2_PAUSED, 0, 0);
+            notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
             mPausedByClient = true;
             break;
         }
@@ -1561,7 +1644,7 @@
 
         case kWhatReleaseDrm:
         {
-            status_t status = onReleaseDrm();
+            status_t status = onReleaseDrm(msg);
 
             sp<AMessage> response = new AMessage;
             response->setInt32("status", status);
@@ -1583,8 +1666,8 @@
         return;
     }
     mPaused = false;
-    if (mSource != NULL) {
-        mSource->resume();
+    if (mCurrentSourceInfo.mSource != NULL) {
+        mCurrentSourceInfo.mSource->resume();
     } else {
         ALOGW("resume called when source is gone or not set");
     }
@@ -1602,12 +1685,12 @@
     startPlaybackTimer("onresume");
 }
 
-void NuPlayer2::onStart() {
-    ALOGV("onStart: mCrypto: %p", mCrypto.get());
+void NuPlayer2::onStart(bool play) {
+    ALOGV("onStart: mCrypto: %p", mCurrentSourceInfo.mCrypto.get());
 
     if (!mSourceStarted) {
         mSourceStarted = true;
-        mSource->start();
+        mCurrentSourceInfo.mSource->start();
     }
 
     mOffloadAudio = false;
@@ -1618,22 +1701,23 @@
 
     uint32_t flags = 0;
 
-    if (mSource->isRealTime()) {
+    if (mCurrentSourceInfo.mSource->isRealTime()) {
         flags |= Renderer::FLAG_REAL_TIME;
     }
 
-    bool hasAudio = (mSource->getFormat(true /* audio */) != NULL);
-    bool hasVideo = (mSource->getFormat(false /* audio */) != NULL);
+    bool hasAudio = (mCurrentSourceInfo.mSource->getFormat(true /* audio */) != NULL);
+    bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL);
     if (!hasAudio && !hasVideo) {
         ALOGE("no metadata for either audio or video source");
-        mSource->stop();
+        mCurrentSourceInfo.mSource->stop();
         mSourceStarted = false;
-        notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_MALFORMED);
+        notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
+                       MEDIA2_ERROR_UNKNOWN, ERROR_MALFORMED);
         return;
     }
     ALOGV_IF(!hasAudio, "no metadata for audio source");  // video only stream
 
-    sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
+    sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
 
     audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
     if (mAudioSink != NULL) {
@@ -1641,11 +1725,12 @@
     }
 
     mOffloadAudio =
-        canOffloadStream(audioMeta, hasVideo, mSource->isStreaming(), streamType)
+        JMediaPlayer2Utils::isOffloadedAudioPlaybackSupported(
+                audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
                 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
 
     // Modular DRM: Disabling audio offload if the source is protected
-    if (mOffloadAudio && mIsDrmProtected) {
+    if (mOffloadAudio && mCurrentSourceInfo.mIsDrmProtected) {
         mOffloadAudio = false;
         ALOGV("onStart: Disabling mOffloadAudio now that the source is protected.");
     }
@@ -1657,17 +1742,17 @@
     sp<AMessage> notify = new AMessage(kWhatRendererNotify, this);
     ++mRendererGeneration;
     notify->setInt32("generation", mRendererGeneration);
-    mRenderer = new Renderer(mAudioSink, mMediaClock, notify, flags);
+    mRenderer = new Renderer(mAudioSink, mMediaClock, notify, mContext, flags);
     mRendererLooper = new ALooper;
-    mRendererLooper->setName("NuPlayerRenderer");
-    mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
+    mRendererLooper->setName("NuPlayer2Renderer");
+    mRendererLooper->start(false, true, ANDROID_PRIORITY_AUDIO);
     mRendererLooper->registerHandler(mRenderer);
 
     status_t err = mRenderer->setPlaybackSettings(mPlaybackSettings);
     if (err != OK) {
-        mSource->stop();
+        mCurrentSourceInfo.mSource->stop();
         mSourceStarted = false;
-        notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
+        notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
         return;
     }
 
@@ -1676,6 +1761,12 @@
         mRenderer->setVideoFrameRate(rate);
     }
 
+    addEndTimeMonitor();
+    // Renderer is created in paused state.
+    if (play) {
+        mRenderer->resume();
+    }
+
     if (mVideoDecoder != NULL) {
         mVideoDecoder->setRenderer(mRenderer);
     }
@@ -1684,10 +1775,23 @@
     }
 
     startPlaybackTimer("onstart");
+    notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
 
     postScanSources();
 }
 
+void NuPlayer2::addEndTimeMonitor() {
+    ++mEOSMonitorGeneration;
+
+    if (mCurrentSourceInfo.mEndTimeUs == DataSourceDesc::kMaxTimeUs) {
+        return;
+    }
+
+    sp<AMessage> msg = new AMessage(kWhatEOSMonitor, this);
+    msg->setInt32("generation", mEOSMonitorGeneration);
+    mMediaClock->addTimer(msg, mCurrentSourceInfo.mEndTimeUs);
+}
+
 void NuPlayer2::startPlaybackTimer(const char *where) {
     Mutex::Autolock autoLock(mPlayingTimeLock);
     if (mLastStartedPlayingTimeNs == 0) {
@@ -1709,7 +1813,7 @@
             ALOGV("stopPlaybackTimer()  log  %20" PRId64 "", played);
 
             if (played > 0) {
-                driver->notifyMorePlayingTimeUs(mSrcId, (played+500)/1000);
+                driver->notifyMorePlayingTimeUs(mCurrentSourceInfo.mSrcId, (played+500)/1000);
             }
         }
         mLastStartedPlayingTimeNs = 0;
@@ -1727,7 +1831,8 @@
 void NuPlayer2::stopRebufferingTimer(bool exitingPlayback) {
     Mutex::Autolock autoLock(mPlayingTimeLock);
 
-    ALOGV("stopRebufferTimer()  time %20" PRId64 " (exiting %d)", mLastStartedRebufferingTimeNs, exitingPlayback);
+    ALOGV("stopRebufferTimer()  time %20" PRId64 " (exiting %d)",
+          mLastStartedRebufferingTimeNs, exitingPlayback);
 
     if (mLastStartedRebufferingTimeNs != 0) {
         sp<NuPlayer2Driver> driver = mDriver.promote();
@@ -1737,9 +1842,10 @@
             ALOGV("stopRebufferingTimer()  log  %20" PRId64 "", rebuffered);
 
             if (rebuffered > 0) {
-                driver->notifyMoreRebufferingTimeUs(mSrcId, (rebuffered+500)/1000);
+                driver->notifyMoreRebufferingTimeUs(
+                        mCurrentSourceInfo.mSrcId, (rebuffered+500)/1000);
                 if (exitingPlayback) {
-                    driver->notifyRebufferingWhenExit(mSrcId, true);
+                    driver->notifyRebufferingWhenExit(mCurrentSourceInfo.mSrcId, true);
                 }
             }
         }
@@ -1755,8 +1861,8 @@
         return;
     }
     mPaused = true;
-    if (mSource != NULL) {
-        mSource->pause();
+    if (mCurrentSourceInfo.mSource != NULL) {
+        mCurrentSourceInfo.mSource->pause();
     } else {
         ALOGW("pause called when source is gone or not set");
     }
@@ -1846,7 +1952,7 @@
 
     status_t err = mRenderer->openAudioSink(
             format, true /* offloadOnly */, hasVideo,
-            AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mSource->isStreaming());
+            AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mCurrentSourceInfo.mSource->isStreaming());
     if (err != OK) {
         // Any failure we turn off mOffloadAudio.
         mOffloadAudio = false;
@@ -1863,6 +1969,7 @@
         int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder) {
     if (mAudioDecoder != NULL) {
         mAudioDecoder->pause();
+        Mutex::Autolock autoLock(mDecoderLock);
         mAudioDecoder.clear();
         mAudioDecoderError = false;
         ++mAudioDecoderGeneration;
@@ -1884,11 +1991,21 @@
     closeAudioSink();
     mRenderer->flush(true /* audio */, false /* notifyComplete */);
     if (mVideoDecoder != NULL) {
-        mRenderer->flush(false /* audio */, false /* notifyComplete */);
+        mDeferredActions.push_back(
+                new FlushDecoderAction(FLUSH_CMD_NONE /* audio */,
+                                       FLUSH_CMD_FLUSH /* video */));
+        mDeferredActions.push_back(
+                new SeekAction(currentPositionUs,
+                MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */));
+        // After a flush without shutdown, decoder is paused.
+        // Don't resume it until source seek is done, otherwise it could
+        // start pulling stale data too soon.
+        mDeferredActions.push_back(new ResumeDecoderAction(false));
+        processDeferredActions();
+    } else {
+        performSeek(currentPositionUs, MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */);
     }
 
-    performSeek(currentPositionUs, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */);
-
     if (forceNonOffload) {
         mRenderer->signalDisableOffloadAudio();
         mOffloadAudio = false;
@@ -1899,7 +2016,7 @@
 }
 
 void NuPlayer2::determineAudioModeChange(const sp<AMessage> &audioFormat) {
-    if (mSource == NULL || mAudioSink == NULL) {
+    if (mCurrentSourceInfo.mSource == NULL || mAudioSink == NULL) {
         return;
     }
 
@@ -1909,16 +2026,16 @@
         return;
     }
 
-    sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
-    sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
+    sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
+    sp<AMessage> videoFormat = mCurrentSourceInfo.mSource->getFormat(false /* audio */);
     audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
     const bool hasVideo = (videoFormat != NULL);
-    bool canOffload = canOffloadStream(
-            audioMeta, hasVideo, mSource->isStreaming(), streamType)
+    bool canOffload = JMediaPlayer2Utils::isOffloadedAudioPlaybackSupported(
+            audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
                     && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
 
     // Modular DRM: Disabling audio offload if the source is protected
-    if (canOffload && mIsDrmProtected) {
+    if (canOffload && mCurrentSourceInfo.mIsDrmProtected) {
         canOffload = false;
         ALOGV("determineAudioModeChange: Disabling mOffloadAudio b/c the source is protected.");
     }
@@ -1945,7 +2062,7 @@
         return OK;
     }
 
-    sp<AMessage> format = mSource->getFormat(audio);
+    sp<AMessage> format = mCurrentSourceInfo.mSource->getFormat(audio);
 
     if (format == NULL) {
         return UNKNOWN_ERROR;
@@ -1967,11 +2084,11 @@
             mCCDecoder = new CCDecoder(ccNotify);
         }
 
-        if (mSourceFlags & Source::FLAG_SECURE) {
+        if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) {
             format->setInt32("secure", true);
         }
 
-        if (mSourceFlags & Source::FLAG_PROTECTED) {
+        if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_PROTECTED) {
             format->setInt32("protected", true);
         }
 
@@ -1981,6 +2098,8 @@
         }
     }
 
+    Mutex::Autolock autoLock(mDecoderLock);
+
     if (audio) {
         sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
         ++mAudioDecoderGeneration;
@@ -1990,16 +2109,16 @@
             determineAudioModeChange(format);
         }
         if (mOffloadAudio) {
-            mSource->setOffloadAudio(true /* offload */);
+            mCurrentSourceInfo.mSource->setOffloadAudio(true /* offload */);
 
-            const bool hasVideo = (mSource->getFormat(false /*audio */) != NULL);
+            const bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /*audio */) != NULL);
             format->setInt32("has-video", hasVideo);
-            *decoder = new DecoderPassThrough(notify, mSource, mRenderer);
+            *decoder = new DecoderPassThrough(notify, mCurrentSourceInfo.mSource, mRenderer);
             ALOGV("instantiateDecoder audio DecoderPassThrough  hasVideo: %d", hasVideo);
         } else {
-            mSource->setOffloadAudio(false /* offload */);
+            mCurrentSourceInfo.mSource->setOffloadAudio(false /* offload */);
 
-            *decoder = new Decoder(notify, mSource, mPID, mUID, mRenderer);
+            *decoder = new Decoder(notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer);
             ALOGV("instantiateDecoder audio Decoder");
         }
         mAudioDecoderError = false;
@@ -2009,7 +2128,8 @@
         notify->setInt32("generation", mVideoDecoderGeneration);
 
         *decoder = new Decoder(
-                notify, mSource, mPID, mUID, mRenderer, mNativeWindow, mCCDecoder);
+                notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer, mNativeWindow,
+                mCCDecoder);
         mVideoDecoderError = false;
 
         // enable FRC if high-quality AV sync is requested, even if not
@@ -2024,10 +2144,11 @@
     (*decoder)->init();
 
     // Modular DRM
-    if (mIsDrmProtected) {
-        format->setObject("crypto", mCrypto);
-        ALOGV("instantiateDecoder: mCrypto: %p isSecure: %d", mCrypto.get(),
-                (mSourceFlags & Source::FLAG_SECURE) != 0);
+    if (mCurrentSourceInfo.mIsDrmProtected) {
+        format->setObject("crypto", mCurrentSourceInfo.mCrypto);
+        ALOGV("instantiateDecoder: mCrypto: %p isSecure: %d",
+                mCurrentSourceInfo.mCrypto.get(),
+                (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) != 0);
     }
 
     (*decoder)->configure(format);
@@ -2146,7 +2267,8 @@
             displayHeight);
 }
 
-void NuPlayer2::notifyListener(int64_t srcId, int msg, int ext1, int ext2, const Parcel *in) {
+void NuPlayer2::notifyListener(
+        int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in) {
     if (mDriver == NULL) {
         return;
     }
@@ -2230,8 +2352,9 @@
     return OK;
 }
 
-status_t NuPlayer2::getTrackInfo(Parcel* reply) const {
+status_t NuPlayer2::getTrackInfo(int64_t srcId, PlayerMessage* reply) const {
     sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
+    msg->setInt64("srcId", srcId);
     msg->setPointer("reply", reply);
 
     sp<AMessage> response;
@@ -2239,9 +2362,10 @@
     return err;
 }
 
-status_t NuPlayer2::getSelectedTrack(int32_t type, Parcel* reply) const {
+status_t NuPlayer2::getSelectedTrack(int64_t srcId, int32_t type, PlayerMessage* reply) const {
     sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
     msg->setPointer("reply", reply);
+    msg->setInt64("srcId", srcId);
     msg->setInt32("type", type);
 
     sp<AMessage> response;
@@ -2252,8 +2376,9 @@
     return err;
 }
 
-status_t NuPlayer2::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
+status_t NuPlayer2::selectTrack(int64_t srcId, size_t trackIndex, bool select, int64_t timeUs) {
     sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
+    msg->setInt64("srcId", srcId);
     msg->setSize("trackIndex", trackIndex);
     msg->setInt32("select", select);
     msg->setInt64("timeUs", timeUs);
@@ -2285,6 +2410,8 @@
     CHECK(mTrackStats != NULL);
 
     mTrackStats->clear();
+
+    Mutex::Autolock autoLock(mDecoderLock);
     if (mVideoDecoder != NULL) {
         mTrackStats->push_back(mVideoDecoder->getStats());
     }
@@ -2294,11 +2421,11 @@
 }
 
 sp<MetaData> NuPlayer2::getFileMeta() {
-    return mSource->getFileFormatMeta();
+    return mCurrentSourceInfo.mSource->getFileFormatMeta();
 }
 
 float NuPlayer2::getFrameRate() {
-    sp<MetaData> meta = mSource->getFormatMeta(false /* audio */);
+    sp<MetaData> meta = mCurrentSourceInfo.mSource->getFormatMeta(false /* audio */);
     if (meta == NULL) {
         return 0;
     }
@@ -2356,16 +2483,16 @@
     ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), mode=%d",
           (long long)seekTimeUs, seekTimeUs / 1E6, mode);
 
-    if (mSource == NULL) {
+    if (mCurrentSourceInfo.mSource == NULL) {
         // This happens when reset occurs right before the loop mode
         // asynchronously seeks to the start of the stream.
         LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
-                "mSource is NULL and decoders not NULL audio(%p) video(%p)",
+                "mCurrentSourceInfo.mSource is NULL and decoders not NULL audio(%p) video(%p)",
                 mAudioDecoder.get(), mVideoDecoder.get());
         return;
     }
     mPreviousSeekTimeUs = seekTimeUs;
-    mSource->seekTo(seekTimeUs, mode);
+    mCurrentSourceInfo.mSource->seekTo(seekTimeUs, mode);
     ++mTimedTextGeneration;
 
     // everything's flushed, continue playback.
@@ -2412,17 +2539,13 @@
     mRenderer.clear();
     ++mRendererGeneration;
 
-    if (mSource != NULL) {
-        mSource->stop();
-
-        Mutex::Autolock autoLock(mSourceLock);
-        mSource.clear();
-    }
+    resetSourceInfo(mCurrentSourceInfo);
+    resetSourceInfo(mNextSourceInfo);
 
     if (mDriver != NULL) {
         sp<NuPlayer2Driver> driver = mDriver.promote();
         if (driver != NULL) {
-            driver->notifyResetComplete(mSrcId);
+            driver->notifyResetComplete(mCurrentSourceInfo.mSrcId);
         }
     }
 
@@ -2431,14 +2554,6 @@
     mResetting = false;
     mSourceStarted = false;
 
-    // Modular DRM
-    if (mCrypto != NULL) {
-        // decoders will be flushed before this so their mCrypto would go away on their own
-        // TODO change to ALOGV
-        ALOGD("performReset mCrypto: %p", mCrypto.get());
-        mCrypto.clear();
-    }
-    mIsDrmProtected = false;
 }
 
 void NuPlayer2::performPlayNextDataSource() {
@@ -2457,25 +2572,31 @@
 
     ++mRendererGeneration;
 
-    if (mSource != NULL) {
-        mSource->stop();
+    if (mCurrentSourceInfo.mSource != NULL) {
+        mCurrentSourceInfo.mSource->stop();
     }
 
     long previousSrcId;
     {
         Mutex::Autolock autoLock(mSourceLock);
-        mSource = mNextSource;
-        mNextSource = NULL;
-        previousSrcId = mSrcId;
-        mSrcId = mNextSrcId;
-        ++mNextSrcId;  // to distinguish the two sources.
+        previousSrcId = mCurrentSourceInfo.mSrcId;
+
+        mCurrentSourceInfo = mNextSourceInfo;
+        mNextSourceInfo = SourceInfo();
+        mNextSourceInfo.mSrcId = ~mCurrentSourceInfo.mSrcId;  // to distinguish the two sources.
     }
 
     if (mDriver != NULL) {
         sp<NuPlayer2Driver> driver = mDriver.promote();
         if (driver != NULL) {
-            notifyListener(previousSrcId, MEDIA2_INFO, MEDIA2_INFO_PLAYBACK_COMPLETE, 0);
-            notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_STARTED_AS_NEXT, 0);
+            notifyListener(previousSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_END, 0);
+
+            int64_t durationUs;
+            if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
+                driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
+            }
+            notifyListener(
+                    mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
         }
     }
 
@@ -2484,22 +2605,15 @@
     mResetting = false;
     mSourceStarted = false;
 
-    // Modular DRM
-    if (mCrypto != NULL) {
-        // decoders will be flushed before this so their mCrypto would go away on their own
-        // TODO change to ALOGV
-        ALOGD("performReset mCrypto: %p", mCrypto.get());
-        mCrypto.clear();
-    }
-    mIsDrmProtected = false;
+    addEndTimeMonitor();
 
     if (mRenderer != NULL) {
         mRenderer->resume();
     }
 
-    onStart();
+    onStart(true /* play */);
     mPausedByClient = false;
-    notifyListener(mSrcId, MEDIA2_STARTED, 0, 0);
+    notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
 }
 
 void NuPlayer2::performScanSources() {
@@ -2525,7 +2639,7 @@
     if (mDriver != NULL) {
         sp<NuPlayer2Driver> driver = mDriver.promote();
         if (driver != NULL) {
-            driver->notifySetSurfaceComplete(mSrcId);
+            driver->notifySetSurfaceComplete(mCurrentSourceInfo.mSrcId);
         }
     }
 }
@@ -2557,7 +2671,7 @@
 void NuPlayer2::finishResume() {
     if (mResumePending) {
         mResumePending = false;
-        notifyDriverSeekComplete(mSrcId);
+        notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
     }
 }
 
@@ -2579,36 +2693,50 @@
     switch (what) {
         case Source::kWhatPrepared:
         {
-            ALOGV("NuPlayer2::onSourceNotify Source::kWhatPrepared source: %p", mSource.get());
-            if (mSource == NULL) {
-                // This is a stale notification from a source that was
-                // asynchronously preparing when the client called reset().
-                // We handled the reset, the source is gone.
-                break;
-            }
-
-            int32_t err;
-            CHECK(msg->findInt32("err", &err));
-
-            if (err != OK) {
-                // shut down potential secure codecs in case client never calls reset
-                mDeferredActions.push_back(
-                        new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
-                                               FLUSH_CMD_SHUTDOWN /* video */));
-                processDeferredActions();
-            } else {
-                mPrepared = true;
-            }
-
-            sp<NuPlayer2Driver> driver = mDriver.promote();
-            if (driver != NULL) {
-                // notify duration first, so that it's definitely set when
-                // the app received the "prepare complete" callback.
-                int64_t durationUs;
-                if (mSource->getDuration(&durationUs) == OK) {
-                    driver->notifyDuration(srcId, durationUs);
+            ALOGV("NuPlayer2::onSourceNotify Source::kWhatPrepared source:%p, Id(%lld)",
+                  mCurrentSourceInfo.mSource.get(), (long long)srcId);
+            if (srcId == mCurrentSourceInfo.mSrcId) {
+                if (mCurrentSourceInfo.mSource == NULL) {
+                    // This is a stale notification from a source that was
+                    // asynchronously preparing when the client called reset().
+                    // We handled the reset, the source is gone.
+                    break;
                 }
-                driver->notifyPrepareCompleted(srcId, err);
+
+                int32_t err;
+                CHECK(msg->findInt32("err", &err));
+
+                if (err != OK) {
+                    // shut down potential secure codecs in case client never calls reset
+                    mDeferredActions.push_back(
+                            new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
+                                                   FLUSH_CMD_SHUTDOWN /* video */));
+                    processDeferredActions();
+                } else {
+                    mPrepared = true;
+                }
+
+                sp<NuPlayer2Driver> driver = mDriver.promote();
+                if (driver != NULL) {
+                    // notify duration first, so that it's definitely set when
+                    // the app received the "prepare complete" callback.
+                    int64_t durationUs;
+                    if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
+                        driver->notifyDuration(srcId, durationUs);
+                    }
+                    driver->notifyPrepareCompleted(srcId, err);
+                }
+            } else if (srcId == mNextSourceInfo.mSrcId) {
+                if (mNextSourceInfo.mSource == NULL) {
+                    break;  // stale
+                }
+
+                sp<NuPlayer2Driver> driver = mDriver.promote();
+                if (driver != NULL) {
+                    int32_t err;
+                    CHECK(msg->findInt32("err", &err));
+                    driver->notifyPrepareCompleted(srcId, err);
+                }
             }
 
             break;
@@ -2617,15 +2745,15 @@
         // Modular DRM
         case Source::kWhatDrmInfo:
         {
-            Parcel parcel;
+            PlayerMessage playerMsg;
             sp<ABuffer> drmInfo;
             CHECK(msg->findBuffer("drmInfo", &drmInfo));
-            parcel.setData(drmInfo->data(), drmInfo->size());
+            playerMsg.ParseFromArray(drmInfo->data(), drmInfo->size());
 
-            ALOGV("onSourceNotify() kWhatDrmInfo MEDIA2_DRM_INFO drmInfo: %p  parcel size: %zu",
-                    drmInfo.get(), parcel.dataSize());
+            ALOGV("onSourceNotify() kWhatDrmInfo MEDIA2_DRM_INFO drmInfo: %p  playerMsg size: %d",
+                    drmInfo.get(), playerMsg.ByteSize());
 
-            notifyListener(srcId, MEDIA2_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &parcel);
+            notifyListener(srcId, MEDIA2_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &playerMsg);
 
             break;
         }
@@ -2654,19 +2782,26 @@
                     driver->notifyListener(
                             srcId, MEDIA2_INFO, MEDIA2_INFO_NOT_SEEKABLE, 0);
                 }
-                driver->notifyFlagsChanged(srcId, flags);
+                if (srcId == mCurrentSourceInfo.mSrcId) {
+                    driver->notifyFlagsChanged(srcId, flags);
+                }
             }
 
-            if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
-                    && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
-                cancelPollDuration();
-            } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
-                    && (flags & Source::FLAG_DYNAMIC_DURATION)
-                    && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
-                schedulePollDuration();
-            }
+            if (srcId == mCurrentSourceInfo.mSrcId) {
+                if ((mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
+                        && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
+                    cancelPollDuration();
+                } else if (!(mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
+                        && (flags & Source::FLAG_DYNAMIC_DURATION)
+                        && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
+                    schedulePollDuration();
+                }
 
-            mSourceFlags = flags;
+                mCurrentSourceInfo.mSourceFlags = flags;
+            } else if (srcId == mNextSourceInfo.mSrcId) {
+                // TODO: handle duration polling for next source.
+                mNextSourceInfo.mSourceFlags = flags;
+            }
             break;
         }
 
@@ -2768,7 +2903,7 @@
             int64_t posMs;
             int64_t timeUs, posUs;
             driver->getCurrentPosition(&posMs);
-            posUs = posMs * 1000ll;
+            posUs = posMs * 1000LL;
             CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
 
             if (posUs < timeUs) {
@@ -2817,8 +2952,8 @@
             CHECK(msg->findBuffer("buffer", &buffer));
 
             size_t inbandTracks = 0;
-            if (mSource != NULL) {
-                inbandTracks = mSource->getTrackCount();
+            if (mCurrentSourceInfo.mSource != NULL) {
+                inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
             }
 
             sendSubtitleData(buffer, inbandTracks);
@@ -2827,7 +2962,7 @@
 
         case NuPlayer2::CCDecoder::kWhatTrackAdded:
         {
-            notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
+            notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
 
             break;
         }
@@ -2846,35 +2981,31 @@
     CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
     CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
 
-    Parcel in;
-    in.writeInt32(trackIndex + baseIndex);
-    in.writeInt64(timeUs);
-    in.writeInt64(durationUs);
-    in.writeInt32(buffer->size());
-    in.writeInt32(buffer->size());
-    in.write(buffer->data(), buffer->size());
+    PlayerMessage playerMsg;
+    playerMsg.add_values()->set_int32_value(trackIndex + baseIndex);
+    playerMsg.add_values()->set_int64_value(timeUs);
+    playerMsg.add_values()->set_int64_value(durationUs);
+    playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
 
-    notifyListener(mSrcId, MEDIA2_SUBTITLE_DATA, 0, 0, &in);
+    notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_SUBTITLE_DATA, 0, 0, &playerMsg);
 }
 
 void NuPlayer2::sendTimedMetaData(const sp<ABuffer> &buffer) {
     int64_t timeUs;
     CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
 
-    Parcel in;
-    in.writeInt64(timeUs);
-    in.writeInt32(buffer->size());
-    in.writeInt32(buffer->size());
-    in.write(buffer->data(), buffer->size());
+    PlayerMessage playerMsg;
+    playerMsg.add_values()->set_int64_value(timeUs);
+    playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
 
-    notifyListener(mSrcId, MEDIA2_META_DATA, 0, 0, &in);
+    notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_META_DATA, 0, 0, &playerMsg);
 }
 
 void NuPlayer2::sendTimedTextData(const sp<ABuffer> &buffer) {
     const void *data;
     size_t size = 0;
     int64_t timeUs;
-    int32_t flag = TextDescriptions::IN_BAND_TEXT_3GPP;
+    int32_t flag = TextDescriptions2::IN_BAND_TEXT_3GPP;
 
     AString mime;
     CHECK(buffer->meta()->findString("mime", &mime));
@@ -2883,28 +3014,28 @@
     data = buffer->data();
     size = buffer->size();
 
-    Parcel parcel;
+    PlayerMessage playerMsg;
     if (size > 0) {
         CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
         int32_t global = 0;
         if (buffer->meta()->findInt32("global", &global) && global) {
-            flag |= TextDescriptions::GLOBAL_DESCRIPTIONS;
+            flag |= TextDescriptions2::GLOBAL_DESCRIPTIONS;
         } else {
-            flag |= TextDescriptions::LOCAL_DESCRIPTIONS;
+            flag |= TextDescriptions2::LOCAL_DESCRIPTIONS;
         }
-        TextDescriptions::getParcelOfDescriptions(
-                (const uint8_t *)data, size, flag, timeUs / 1000, &parcel);
+        TextDescriptions2::getPlayerMessageOfDescriptions(
+                (const uint8_t *)data, size, flag, timeUs / 1000, &playerMsg);
     }
 
-    if ((parcel.dataSize() > 0)) {
-        notifyListener(mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &parcel);
+    if (playerMsg.values_size() > 0) {
+        notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &playerMsg);
     } else {  // send an empty timed text
-        notifyListener(mSrcId, MEDIA2_TIMED_TEXT, 0, 0);
+        notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0);
     }
 }
 
 const char *NuPlayer2::getDataSourceType() {
-    switch (mDataSourceType) {
+    switch (mCurrentSourceInfo.mDataSourceType) {
         case DATA_SOURCE_TYPE_HTTP_LIVE:
             return "HTTPLive";
 
@@ -2926,8 +3057,34 @@
     }
  }
 
+NuPlayer2::SourceInfo* NuPlayer2::getSourceInfoByIdInMsg(const sp<AMessage> &msg) {
+    int64_t srcId;
+    CHECK(msg->findInt64("srcId", &srcId));
+    if (mCurrentSourceInfo.mSrcId == srcId) {
+        return &mCurrentSourceInfo;
+    } else if (mNextSourceInfo.mSrcId == srcId) {
+        return &mNextSourceInfo;
+    } else {
+        return NULL;
+    }
+}
+
+void NuPlayer2::resetSourceInfo(NuPlayer2::SourceInfo &srcInfo) {
+    if (srcInfo.mSource != NULL) {
+        srcInfo.mSource->stop();
+
+        Mutex::Autolock autoLock(mSourceLock);
+        srcInfo.mSource.clear();
+    }
+    // Modular DRM
+    ALOGD("performReset mCrypto: %p", srcInfo.mCrypto.get());
+    srcInfo.mCrypto.clear();
+    srcInfo.mIsDrmProtected = false;
+}
+
 // Modular DRM begin
-status_t NuPlayer2::prepareDrm(const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
+status_t NuPlayer2::prepareDrm(
+        int64_t srcId, const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
 {
     ALOGV("prepareDrm ");
 
@@ -2937,6 +3094,7 @@
     uint8_t UUID[16];
     memcpy(UUID, uuid, sizeof(UUID));
     Vector<uint8_t> sessionId = drmSessionId;
+    msg->setInt64("srcId", srcId);
     msg->setPointer("uuid", (void*)UUID);
     msg->setPointer("drmSessionId", (void*)&sessionId);
 
@@ -2953,11 +3111,12 @@
     return status;
 }
 
-status_t NuPlayer2::releaseDrm()
+status_t NuPlayer2::releaseDrm(int64_t srcId)
 {
     ALOGV("releaseDrm ");
 
     sp<AMessage> msg = new AMessage(kWhatReleaseDrm, this);
+    msg->setInt64("srcId", srcId);
 
     sp<AMessage> response;
     status_t status = msg->postAndAwaitResponse(&response);
@@ -2978,8 +3137,15 @@
     ALOGD("onPrepareDrm ");
 
     status_t status = INVALID_OPERATION;
-    if (mSource == NULL) {
-        ALOGE("onPrepareDrm: No source. onPrepareDrm failed with %d.", status);
+    SourceInfo *srcInfo = getSourceInfoByIdInMsg(msg);
+    if (srcInfo == NULL) {
+        return status;
+    }
+
+    int64_t srcId = srcInfo->mSrcId;
+    if (srcInfo->mSource == NULL) {
+        ALOGE("onPrepareDrm: srcInfo(%lld) No source. onPrepareDrm failed with %d.",
+                (long long)srcId, status);
         return status;
     }
 
@@ -2991,42 +3157,50 @@
     status = OK;
     sp<AMediaCryptoWrapper> crypto = NULL;
 
-    status = mSource->prepareDrm(uuid, *drmSessionId, &crypto);
+    status = srcInfo->mSource->prepareDrm(uuid, *drmSessionId, &crypto);
     if (crypto == NULL) {
-        ALOGE("onPrepareDrm: mSource->prepareDrm failed. status: %d", status);
+        ALOGE("onPrepareDrm: srcInfo(%lld).mSource->prepareDrm failed. status: %d",
+                (long long)srcId, status);
         return status;
     }
-    ALOGV("onPrepareDrm: mSource->prepareDrm succeeded");
+    ALOGV("onPrepareDrm: srcInfo(%lld).mSource->prepareDrm succeeded", (long long)srcId);
 
-    if (mCrypto != NULL) {
-        ALOGE("onPrepareDrm: Unexpected. Already having mCrypto: %p", mCrypto.get());
-        mCrypto.clear();
+    if (srcInfo->mCrypto != NULL) {
+        ALOGE("onPrepareDrm: srcInfo(%lld) Unexpected. Already having mCrypto: %p",
+                (long long)srcId, srcInfo->mCrypto.get());
+        srcInfo->mCrypto.clear();
     }
 
-    mCrypto = crypto;
-    mIsDrmProtected = true;
+    srcInfo->mCrypto = crypto;
+    srcInfo->mIsDrmProtected = true;
     // TODO change to ALOGV
-    ALOGD("onPrepareDrm: mCrypto: %p", mCrypto.get());
+    ALOGD("onPrepareDrm: mCrypto: %p", srcInfo->mCrypto.get());
 
     return status;
 }
 
-status_t NuPlayer2::onReleaseDrm()
+status_t NuPlayer2::onReleaseDrm(const sp<AMessage> &msg)
 {
     // TODO change to ALOGV
     ALOGD("onReleaseDrm ");
-
-    if (!mIsDrmProtected) {
-        ALOGW("onReleaseDrm: Unexpected. mIsDrmProtected is already false.");
+    SourceInfo *srcInfo = getSourceInfoByIdInMsg(msg);;
+    if (srcInfo == NULL) {
+        return INVALID_OPERATION;
     }
 
-    mIsDrmProtected = false;
+    int64_t srcId = srcInfo->mSrcId;
+    if (!srcInfo->mIsDrmProtected) {
+        ALOGW("onReleaseDrm: srcInfo(%lld) Unexpected. mIsDrmProtected is already false.",
+                (long long)srcId);
+    }
+
+    srcInfo->mIsDrmProtected = false;
 
     status_t status;
-    if (mCrypto != NULL) {
+    if (srcInfo->mCrypto != NULL) {
         // notifying the source first before removing crypto from codec
-        if (mSource != NULL) {
-            mSource->releaseDrm();
+        if (srcInfo->mSource != NULL) {
+            srcInfo->mSource->releaseDrm();
         }
 
         status=OK;
@@ -3047,9 +3221,9 @@
         }
 
         // TODO change to ALOGV
-        ALOGD("onReleaseDrm: mCrypto: %p", mCrypto.get());
-        mCrypto.clear();
-    } else {   // mCrypto == NULL
+        ALOGD("onReleaseDrm: mCrypto: %p", srcInfo->mCrypto.get());
+        srcInfo->mCrypto.clear();
+    } else {   // srcInfo->mCrypto == NULL
         ALOGE("onReleaseDrm: Unexpected. There is no crypto.");
         status = INVALID_OPERATION;
     }
@@ -3111,4 +3285,24 @@
     TRESPASS();
 }
 
+NuPlayer2::SourceInfo::SourceInfo()
+    : mDataSourceType(DATA_SOURCE_TYPE_NONE),
+      mSrcId(0),
+      mSourceFlags(0),
+      mStartTimeUs(0),
+      mEndTimeUs(DataSourceDesc::kMaxTimeUs) {
+}
+
+NuPlayer2::SourceInfo & NuPlayer2::SourceInfo::operator=(const NuPlayer2::SourceInfo &other) {
+    mSource = other.mSource;
+    mCrypto = other.mCrypto;
+    mDataSourceType = (DATA_SOURCE_TYPE)other.mDataSourceType;
+    mSrcId = other.mSrcId;
+    mSourceFlags = other.mSourceFlags;
+    mStartTimeUs = other.mStartTimeUs;
+    mEndTimeUs = other.mEndTimeUs;
+    mIsDrmProtected = other.mIsDrmProtected;
+    return *this;
+}
+
 }  // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2.h b/media/libmediaplayer2/nuplayer2/NuPlayer2.h
index 96f85f9..b8fb988 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2.h
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2.h
@@ -22,6 +22,11 @@
 #include <media/stagefright/foundation/AHandler.h>
 
 #include <mediaplayer2/MediaPlayer2Interface.h>
+#include <mediaplayer2/JObjectHolder.h>
+
+#include "mediaplayer2.pb.h"
+
+using android::media::MediaPlayer2Proto::PlayerMessage;
 
 namespace android {
 
@@ -38,7 +43,8 @@
 struct NuPlayer2Driver;
 
 struct NuPlayer2 : public AHandler {
-    explicit NuPlayer2(pid_t pid, uid_t uid, const sp<MediaClock> &mediaClock);
+    explicit NuPlayer2(pid_t pid, uid_t uid,
+            const sp<MediaClock> &mediaClock, const sp<JObjectHolder> &context);
 
     void setDriver(const wp<NuPlayer2Driver> &driver);
 
@@ -75,11 +81,12 @@
             int64_t seekTimeUs,
             MediaPlayer2SeekMode mode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC,
             bool needNotify = false);
+    void rewind();
 
     status_t setVideoScalingMode(int32_t mode);
-    status_t getTrackInfo(Parcel* reply) const;
-    status_t getSelectedTrack(int32_t type, Parcel* reply) const;
-    status_t selectTrack(size_t trackIndex, bool select, int64_t timeUs);
+    status_t getTrackInfo(int64_t srcId, PlayerMessage* reply) const;
+    status_t getSelectedTrack(int64_t srcId, int32_t type, PlayerMessage* reply) const;
+    status_t selectTrack(int64_t srcId, size_t trackIndex, bool select, int64_t timeUs);
     status_t getCurrentPosition(int64_t *mediaUs);
     void getStats(Vector<sp<AMessage> > *mTrackStats);
 
@@ -87,8 +94,8 @@
     float getFrameRate();
 
     // Modular DRM
-    status_t prepareDrm(const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId);
-    status_t releaseDrm();
+    status_t prepareDrm(int64_t srcId, const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId);
+    status_t releaseDrm(int64_t srcId);
 
     const char *getDataSourceType();
 
@@ -150,6 +157,32 @@
         kWhatSetBufferingSettings       = 'sBuS',
         kWhatPrepareDrm                 = 'pDrm',
         kWhatReleaseDrm                 = 'rDrm',
+        kWhatRewind                     = 'reWd',
+        kWhatEOSMonitor                 = 'eosM',
+    };
+
+    typedef enum {
+        DATA_SOURCE_TYPE_NONE,
+        DATA_SOURCE_TYPE_HTTP_LIVE,
+        DATA_SOURCE_TYPE_RTSP,
+        DATA_SOURCE_TYPE_GENERIC_URL,
+        DATA_SOURCE_TYPE_GENERIC_FD,
+        DATA_SOURCE_TYPE_MEDIA,
+    } DATA_SOURCE_TYPE;
+
+    struct SourceInfo {
+        SourceInfo();
+        SourceInfo &operator=(const SourceInfo &);
+
+        sp<Source> mSource;
+        std::atomic<DATA_SOURCE_TYPE> mDataSourceType;
+        int64_t mSrcId;
+        uint32_t mSourceFlags;
+        int64_t mStartTimeUs;
+        int64_t mEndTimeUs;
+        // Modular DRM
+        sp<AMediaCryptoWrapper> mCrypto;
+        bool mIsDrmProtected = false;
     };
 
     wp<NuPlayer2Driver> mDriver;
@@ -157,23 +190,21 @@
     uid_t mUID;
     const sp<MediaClock> mMediaClock;
     Mutex mSourceLock;  // guard |mSource|.
-    sp<Source> mSource;
-    int64_t mSrcId;
-    uint32_t mSourceFlags;
-    sp<Source> mNextSource;
-    int64_t mNextSrcId;
-    uint32_t mNextSourceFlags;
+    SourceInfo mCurrentSourceInfo;
+    SourceInfo mNextSourceInfo;
     sp<ANativeWindowWrapper> mNativeWindow;
     sp<MediaPlayer2Interface::AudioSink> mAudioSink;
     sp<DecoderBase> mVideoDecoder;
     bool mOffloadAudio;
     sp<DecoderBase> mAudioDecoder;
+    Mutex mDecoderLock;  // guard |mAudioDecoder| and |mVideoDecoder|.
     sp<CCDecoder> mCCDecoder;
     sp<Renderer> mRenderer;
     sp<ALooper> mRendererLooper;
     int32_t mAudioDecoderGeneration;
     int32_t mVideoDecoderGeneration;
     int32_t mRendererGeneration;
+    int32_t mEOSMonitorGeneration;
 
     Mutex mPlayingTimeLock;
     int64_t mLastStartedPlayingTimeNs;
@@ -244,21 +275,8 @@
     // Pause state as requested by source (internally) due to buffering
     bool mPausedForBuffering;
 
-    // Modular DRM
-    sp<AMediaCryptoWrapper> mCrypto;
-    bool mIsDrmProtected;
-
-    typedef enum {
-        DATA_SOURCE_TYPE_NONE,
-        DATA_SOURCE_TYPE_HTTP_LIVE,
-        DATA_SOURCE_TYPE_RTSP,
-        DATA_SOURCE_TYPE_GENERIC_URL,
-        DATA_SOURCE_TYPE_GENERIC_FD,
-        DATA_SOURCE_TYPE_MEDIA,
-    } DATA_SOURCE_TYPE;
-
-    std::atomic<DATA_SOURCE_TYPE> mDataSourceType;
-    std::atomic<DATA_SOURCE_TYPE> mNextDataSourceType;
+    // Passed from JAVA
+    const sp<JObjectHolder> mContext;
 
     inline const sp<DecoderBase> &getDecoder(bool audio) {
         return audio ? mAudioDecoder : mVideoDecoder;
@@ -292,12 +310,14 @@
             const sp<AMessage> &inputFormat,
             const sp<AMessage> &outputFormat = NULL);
 
-    void notifyListener(int64_t srcId, int msg, int ext1, int ext2, const Parcel *in = NULL);
+    void notifyListener(int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in = NULL);
+
+    void addEndTimeMonitor();
 
     void handleFlushComplete(bool audio, bool isDecoder);
     void finishFlushIfPossible();
 
-    void onStart();
+    void onStart(bool play);
     void onResume();
     void onPause();
 
@@ -333,10 +353,13 @@
     void sendTimedMetaData(const sp<ABuffer> &buffer);
     void sendTimedTextData(const sp<ABuffer> &buffer);
 
-    void writeTrackInfo(Parcel* reply, const sp<AMessage>& format) const;
+    void writeTrackInfo(PlayerMessage* reply, const sp<AMessage>& format) const;
 
     status_t onPrepareDrm(const sp<AMessage> &msg);
-    status_t onReleaseDrm();
+    status_t onReleaseDrm(const sp<AMessage> &msg);
+
+    SourceInfo* getSourceInfoByIdInMsg(const sp<AMessage> &msg);
+    void resetSourceInfo(SourceInfo &srcInfo);
 
     DISALLOW_EVIL_CONSTRUCTORS(NuPlayer2);
 };
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.cpp
index e215965..98c3403 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.cpp
@@ -199,6 +199,18 @@
     return OK;
 }
 
+ssize_t NuPlayer2::CCDecoder::getSelectedTrack(media_track_type type) const {
+    if (mSelectedTrack != -1) {
+        CCTrack track = mTracks[mSelectedTrack];
+        if (track.mTrackType == kTrackTypeCEA608 || track.mTrackType == kTrackTypeCEA708) {
+            return (type == MEDIA_TRACK_TYPE_SUBTITLE ? mSelectedTrack : -1);
+        }
+        return (type == MEDIA_TRACK_TYPE_UNKNOWN ? mSelectedTrack : -1);
+    }
+
+    return -1;
+}
+
 bool NuPlayer2::CCDecoder::isSelected() const {
     return mSelectedTrack >= 0 && mSelectedTrack < (int32_t)getTrackCount();
 }
@@ -555,7 +567,7 @@
 
         ccBuf->meta()->setInt32(AMEDIAFORMAT_KEY_TRACK_INDEX, mSelectedTrack);
         ccBuf->meta()->setInt64("timeUs", timeUs);
-        ccBuf->meta()->setInt64("durationUs", 0ll);
+        ccBuf->meta()->setInt64("durationUs", 0LL);
 
         sp<AMessage> msg = mNotify->dup();
         msg->setInt32("what", kWhatClosedCaptionData);
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.h b/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.h
index 57d5ea2..97834d1 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.h
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.h
@@ -38,6 +38,7 @@
     size_t getTrackCount() const;
     sp<AMessage> getTrackInfo(size_t index) const;
     status_t selectTrack(size_t index, bool select);
+    ssize_t getSelectedTrack(media_track_type type) const;
     bool isSelected() const;
     void decode(const sp<ABuffer> &accessUnit);
     void display(int64_t timeUs);
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Decoder.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2Decoder.cpp
index 645138a..66bfae5 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Decoder.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2Decoder.cpp
@@ -71,10 +71,10 @@
       mCCDecoder(ccDecoder),
       mPid(pid),
       mUid(uid),
-      mSkipRenderingUntilMediaTimeUs(-1ll),
-      mNumFramesTotal(0ll),
-      mNumInputFramesDropped(0ll),
-      mNumOutputFramesDropped(0ll),
+      mSkipRenderingUntilMediaTimeUs(-1LL),
+      mNumFramesTotal(0LL),
+      mNumInputFramesDropped(0LL),
+      mNumOutputFramesDropped(0LL),
       mVideoWidth(0),
       mVideoHeight(0),
       mIsAudio(true),
@@ -107,7 +107,12 @@
     mStats->setInt64("frames-total", mNumFramesTotal);
     mStats->setInt64("frames-dropped-input", mNumInputFramesDropped);
     mStats->setInt64("frames-dropped-output", mNumOutputFramesDropped);
-    return mStats;
+    mStats->setFloat("frame-rate-total", mFrameRateTotal);
+
+    // i'm mutexed right now.
+    // make our own copy, so we aren't victim to any later changes.
+    sp<AMessage> copiedStats = mStats->dup();
+    return copiedStats;
 }
 
 status_t NuPlayer2::Decoder::setVideoSurface(const sp<ANativeWindowWrapper> &nww) {
@@ -428,10 +433,10 @@
         // TODO: For now, layer fps is calculated for some specific architectures.
         // But it really should be extracted from the stream.
         mVideoTemporalLayerAggregateFps[0] =
-            mFrameRateTotal / (float)(1ll << (mNumVideoTemporalLayerTotal - 1));
+            mFrameRateTotal / (float)(1LL << (mNumVideoTemporalLayerTotal - 1));
         for (int32_t i = 1; i < mNumVideoTemporalLayerTotal; ++i) {
             mVideoTemporalLayerAggregateFps[i] =
-                mFrameRateTotal / (float)(1ll << (mNumVideoTemporalLayerTotal - i))
+                mFrameRateTotal / (float)(1LL << (mNumVideoTemporalLayerTotal - i))
                 + mVideoTemporalLayerAggregateFps[i - 1];
         }
     }
@@ -952,7 +957,7 @@
 
             int32_t layerId = 0;
             bool haveLayerId = accessUnit->meta()->findInt32("temporal-layer-id", &layerId);
-            if (mRenderer->getVideoLateByUs() > 100000ll
+            if (mRenderer->getVideoLateByUs() > 100000LL
                     && mIsVideoAVC
                     && !IsAVCReferenceFrame(accessUnit)) {
                 dropAccessUnit = true;
@@ -1088,6 +1093,12 @@
                         static_cast<MediaBufferHolder*>(holder.get())->mediaBuffer() : nullptr;
                 }
                 if (mediaBuf != NULL) {
+                    if (mediaBuf->size() > codecBuffer->capacity()) {
+                        handleError(ERROR_BUFFER_TOO_SMALL);
+                        mDequeuedInputBuffers.push_back(bufferIx);
+                        return false;
+                    }
+
                     codecBuffer->setRange(0, mediaBuf->size());
                     memcpy(codecBuffer->data(), mediaBuf->data(), mediaBuf->size());
 
@@ -1102,6 +1113,11 @@
             } // buffer->data()
         } // needsCopy
 
+        sp<RefBase> cryptInfoObj;
+        if (buffer->meta()->findObject("cryptInfo", &cryptInfoObj)) {
+            cryptInfo = static_cast<AMediaCodecCryptoInfoWrapper *>(cryptInfoObj.get());
+        }
+
         status_t err;
         if (cryptInfo != NULL) {
             err = mCodec->queueSecureInputBuffer(
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderBase.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderBase.cpp
index 9c1988f..914f29f 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderBase.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderBase.cpp
@@ -38,7 +38,7 @@
     // Every decoder has its own looper because MediaCodec operations
     // are blocking, but NuPlayer2 needs asynchronous operations.
     mDecoderLooper = new ALooper;
-    mDecoderLooper->setName("NPDecoder");
+    mDecoderLooper->setName("NP2Decoder");
     mDecoderLooper->start(false, /* runOnCallingThread */
                           true,  /* canCallJava */
                           ANDROID_PRIORITY_AUDIO);
@@ -122,7 +122,7 @@
         mRequestInputBuffersPending = true;
 
         sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, this);
-        msg->post(10 * 1000ll);
+        msg->post(10 * 1000LL);
     }
 }
 
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderPassThrough.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderPassThrough.cpp
index 0e0c1d8..0514e88 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderPassThrough.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderPassThrough.cpp
@@ -46,7 +46,7 @@
     : DecoderBase(notify),
       mSource(source),
       mRenderer(renderer),
-      mSkipRenderingUntilMediaTimeUs(-1ll),
+      mSkipRenderingUntilMediaTimeUs(-1LL),
       mReachedEOS(true),
       mPendingAudioErr(OK),
       mPendingBuffersToDrain(0),
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
index 03d17a5..1876496 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
@@ -17,6 +17,7 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "NuPlayer2Driver"
 #include <inttypes.h>
+#include <android-base/macros.h>
 #include <utils/Log.h>
 #include <cutils/properties.h>
 
@@ -36,49 +37,51 @@
 
 #include <media/IMediaAnalyticsService.h>
 
+using google::protobuf::RepeatedPtrField;
+using android::media::MediaPlayer2Proto::Value;
+
 static const int kDumpLockRetries = 50;
 static const int kDumpLockSleepUs = 20000;
 
 namespace android {
 
-struct ParcelWrapper : public RefBase {
-    static sp<ParcelWrapper> Create(const Parcel *p) {
+struct PlayerMessageWrapper : public RefBase {
+    static sp<PlayerMessageWrapper> Create(const PlayerMessage *p) {
         if (p != NULL) {
-            sp<ParcelWrapper> pw = new ParcelWrapper();
-            if (pw->appendFrom(p) == OK) {
-                return pw;
-            }
+            sp<PlayerMessageWrapper> pw = new PlayerMessageWrapper();
+            pw->copyFrom(p);
+            return pw;
         }
         return NULL;
     }
 
-    const Parcel *getParcel() {
-        return mParcel;
+    const PlayerMessage *getPlayerMessage() {
+        return mPlayerMessage;
     }
 
 protected:
-    virtual ~ParcelWrapper() {
-        if (mParcel != NULL) {
-            delete mParcel;
+    virtual ~PlayerMessageWrapper() {
+        if (mPlayerMessage != NULL) {
+            delete mPlayerMessage;
         }
     }
 
 private:
-    ParcelWrapper()
-        : mParcel(NULL) { }
+    PlayerMessageWrapper()
+        : mPlayerMessage(NULL) { }
 
-    status_t appendFrom(const Parcel *p) {
-        if (mParcel == NULL) {
-            mParcel = new Parcel;
+    void copyFrom(const PlayerMessage *p) {
+        if (mPlayerMessage == NULL) {
+            mPlayerMessage = new PlayerMessage;
         }
-        return mParcel->appendFrom(p, 0 /* start */, p->dataSize());
+        mPlayerMessage->CopyFrom(*p);
     }
 
-    Parcel *mParcel;
+    PlayerMessage *mPlayerMessage;
 };
 
 // key for media statistics
-static const char *kKeyPlayer = "nuplayer";
+static const char *kKeyPlayer = "nuplayer2";
 // attrs for media statistics
     // NB: these are matched with public Java API constants defined
     // in frameworks/base/media/java/android/media/MediaPlayer2.java
@@ -89,6 +92,7 @@
 static const char *kPlayerHeight = "android.media.mediaplayer.height";
 static const char *kPlayerFrames = "android.media.mediaplayer.frames";
 static const char *kPlayerFramesDropped = "android.media.mediaplayer.dropped";
+static const char *kPlayerFrameRate = "android.media.mediaplayer.fps";
 static const char *kPlayerAMime = "android.media.mediaplayer.audio.mime";
 static const char *kPlayerACodec = "android.media.mediaplayer.audio.codec";
 static const char *kPlayerDuration = "android.media.mediaplayer.durationMs";
@@ -104,8 +108,10 @@
 static const char *kPlayerRebufferingCount = "android.media.mediaplayer.rebuffers";
 static const char *kPlayerRebufferingAtExit = "android.media.mediaplayer.rebufferExit";
 
+static const char *kPlayerVersion = "android.media.mediaplayer.version";
 
-NuPlayer2Driver::NuPlayer2Driver(pid_t pid, uid_t uid)
+
+NuPlayer2Driver::NuPlayer2Driver(pid_t pid, uid_t uid, const sp<JObjectHolder> &context)
     : mState(STATE_IDLE),
       mAsyncResult(UNKNOWN_ERROR),
       mSrcId(0),
@@ -120,9 +126,10 @@
       mLooper(new ALooper),
       mNuPlayer2Looper(new ALooper),
       mMediaClock(new MediaClock),
-      mPlayer(new NuPlayer2(pid, uid, mMediaClock)),
+      mPlayer(new NuPlayer2(pid, uid, mMediaClock, context)),
       mPlayerFlags(0),
-      mAnalyticsItem(NULL),
+      mMetricsHandle(0),
+      mPlayerVersion(0),
       mClientUid(uid),
       mAtEOS(false),
       mLooping(false),
@@ -133,9 +140,13 @@
 
     mMediaClock->init();
 
-    // set up an analytics record
-    mAnalyticsItem = new MediaAnalyticsItem(kKeyPlayer);
-    mAnalyticsItem->setUid(mClientUid);
+    // XXX: what version are we?
+    // Ideally, this ticks with the apk version info for the APEX packaging
+
+    // set up media metrics record
+    mMetricsHandle = mediametrics_create(kKeyPlayer);
+    mediametrics_setUid(mMetricsHandle, mClientUid);
+    mediametrics_setInt64(mMetricsHandle, kPlayerVersion, mPlayerVersion);
 
     mNuPlayer2Looper->start(
             false, /* runOnCallingThread */
@@ -156,10 +167,7 @@
     updateMetrics("destructor");
     logMetrics("destructor");
 
-    if (mAnalyticsItem != NULL) {
-        delete mAnalyticsItem;
-        mAnalyticsItem = NULL;
-    }
+    mediametrics_delete(mMetricsHandle);
 }
 
 status_t NuPlayer2Driver::initCheck() {
@@ -272,13 +280,6 @@
             mState = STATE_PREPARING;
             mPlayer->prepareAsync();
             return OK;
-        case STATE_STOPPED:
-            // this is really just paused. handle as seek to start
-            mAtEOS = false;
-            mState = STATE_STOPPED_AND_PREPARING;
-            mPlayer->seekToAsync(0, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */,
-                    true /* needNotify */);
-            return OK;
         default:
             return INVALID_OPERATION;
     };
@@ -293,18 +294,16 @@
 status_t NuPlayer2Driver::start_l() {
     switch (mState) {
         case STATE_PAUSED:
-        case STATE_STOPPED_AND_PREPARED:
         case STATE_PREPARED:
         {
             mPlayer->start();
-
-            // fall through
+            FALLTHROUGH_INTENDED;
         }
 
         case STATE_RUNNING:
         {
             if (mAtEOS) {
-                mPlayer->seekToAsync(0);
+                mPlayer->rewind();
                 mAtEOS = false;
                 mPositionUs = -1;
             }
@@ -320,34 +319,6 @@
     return OK;
 }
 
-status_t NuPlayer2Driver::stop() {
-    ALOGD("stop(%p)", this);
-    Mutex::Autolock autoLock(mLock);
-
-    switch (mState) {
-        case STATE_RUNNING:
-            mPlayer->pause();
-            // fall through
-
-        case STATE_PAUSED:
-            mState = STATE_STOPPED;
-            //notifyListener_l(MEDIA2_STOPPED);
-            break;
-
-        case STATE_PREPARED:
-        case STATE_STOPPED:
-        case STATE_STOPPED_AND_PREPARING:
-        case STATE_STOPPED_AND_PREPARED:
-            mState = STATE_STOPPED;
-            break;
-
-        default:
-            return INVALID_OPERATION;
-    }
-
-    return OK;
-}
-
 status_t NuPlayer2Driver::pause() {
     ALOGD("pause(%p)", this);
     // The NuPlayerRenderer may get flushed if pause for long enough, e.g. the pause timeout tear
@@ -361,9 +332,9 @@
 
     switch (mState) {
         case STATE_PAUSED:
-        case STATE_PREPARED:
             return OK;
 
+        case STATE_PREPARED:
         case STATE_RUNNING:
             mState = STATE_PAUSED;
             mPlayer->pause();
@@ -386,15 +357,6 @@
         // try to update position
         int64_t unused;
         getCurrentPosition(&unused);
-        Mutex::Autolock autoLock(mLock);
-        if (rate.mSpeed == 0.f && mState == STATE_RUNNING) {
-            mState = STATE_PAUSED;
-        } else if (rate.mSpeed != 0.f
-                && (mState == STATE_PAUSED
-                    || mState == STATE_STOPPED_AND_PREPARED
-                    || mState == STATE_PREPARED)) {
-            err = start_l();
-        }
     }
     return err;
 }
@@ -415,11 +377,10 @@
     ALOGD("seekTo(%p) (%lld ms, %d) at state %d", this, (long long)msec, mode, mState);
     Mutex::Autolock autoLock(mLock);
 
-    int64_t seekTimeUs = msec * 1000ll;
+    int64_t seekTimeUs = msec * 1000LL;
 
     switch (mState) {
         case STATE_PREPARED:
-        case STATE_STOPPED_AND_PREPARED:
         case STATE_PAUSED:
         case STATE_RUNNING:
         {
@@ -470,7 +431,7 @@
         return UNKNOWN_ERROR;
     }
 
-    *msec = (mDurationUs + 500ll) / 1000;
+    *msec = (mDurationUs + 500LL) / 1000;
 
     return OK;
 }
@@ -497,15 +458,15 @@
 
             if (mime.startsWith("video/")) {
                 int32_t width, height;
-                mAnalyticsItem->setCString(kPlayerVMime, mime.c_str());
+                mediametrics_setCString(mMetricsHandle, kPlayerVMime, mime.c_str());
                 if (!name.empty()) {
-                    mAnalyticsItem->setCString(kPlayerVCodec, name.c_str());
+                    mediametrics_setCString(mMetricsHandle, kPlayerVCodec, name.c_str());
                 }
 
                 if (stats->findInt32("width", &width)
                         && stats->findInt32("height", &height)) {
-                    mAnalyticsItem->setInt32(kPlayerWidth, width);
-                    mAnalyticsItem->setInt32(kPlayerHeight, height);
+                    mediametrics_setInt32(mMetricsHandle, kPlayerWidth, width);
+                    mediametrics_setInt32(mMetricsHandle, kPlayerHeight, height);
                 }
 
                 int64_t numFramesTotal = 0;
@@ -513,14 +474,18 @@
                 stats->findInt64("frames-total", &numFramesTotal);
                 stats->findInt64("frames-dropped-output", &numFramesDropped);
 
-                mAnalyticsItem->setInt64(kPlayerFrames, numFramesTotal);
-                mAnalyticsItem->setInt64(kPlayerFramesDropped, numFramesDropped);
+                mediametrics_setInt64(mMetricsHandle, kPlayerFrames, numFramesTotal);
+                mediametrics_setInt64(mMetricsHandle, kPlayerFramesDropped, numFramesDropped);
 
+                float frameRate = 0;
+                if (stats->findFloat("frame-rate-output", &frameRate)) {
+                    mediametrics_setInt64(mMetricsHandle, kPlayerFrameRate, frameRate);
+                }
 
             } else if (mime.startsWith("audio/")) {
-                mAnalyticsItem->setCString(kPlayerAMime, mime.c_str());
+                mediametrics_setCString(mMetricsHandle, kPlayerAMime, mime.c_str());
                 if (!name.empty()) {
-                    mAnalyticsItem->setCString(kPlayerACodec, name.c_str());
+                    mediametrics_setCString(mMetricsHandle, kPlayerACodec, name.c_str());
                 }
             }
         }
@@ -531,17 +496,17 @@
     // getDuration() uses mLock for mutex -- careful where we use it.
     int64_t duration_ms = -1;
     getDuration(&duration_ms);
-    mAnalyticsItem->setInt64(kPlayerDuration, duration_ms);
+    mediametrics_setInt64(mMetricsHandle, kPlayerDuration, duration_ms);
 
-    mAnalyticsItem->setInt64(kPlayerPlaying, (mPlayingTimeUs+500)/1000 );
+    mediametrics_setInt64(mMetricsHandle, kPlayerPlaying, (mPlayingTimeUs+500)/1000 );
 
     if (mRebufferingEvents != 0) {
-        mAnalyticsItem->setInt64(kPlayerRebuffering, (mRebufferingTimeUs+500)/1000 );
-        mAnalyticsItem->setInt32(kPlayerRebufferingCount, mRebufferingEvents);
-        mAnalyticsItem->setInt32(kPlayerRebufferingAtExit, mRebufferingAtExit);
+        mediametrics_setInt64(mMetricsHandle, kPlayerRebuffering, (mRebufferingTimeUs+500)/1000 );
+        mediametrics_setInt32(mMetricsHandle, kPlayerRebufferingCount, mRebufferingEvents);
+        mediametrics_setInt32(mMetricsHandle, kPlayerRebufferingAtExit, mRebufferingAtExit);
     }
 
-    mAnalyticsItem->setCString(kPlayerDataSourceType, mPlayer->getDataSourceType());
+    mediametrics_setCString(mMetricsHandle, kPlayerDataSourceType, mPlayer->getDataSourceType());
 }
 
 
@@ -551,7 +516,7 @@
     }
     ALOGV("logMetrics(%p) from %s at state %d", this, where, mState);
 
-    if (mAnalyticsItem == NULL || mAnalyticsItem->isEnabled() == false) {
+    if (mMetricsHandle == 0 || mediametrics_isEnabled() == false) {
         return;
     }
 
@@ -560,16 +525,13 @@
     // and that always injects 3 fields (duration, playing time, and
     // datasource) into the record.
     // So the canonical "empty" record has 3 elements in it.
-    if (mAnalyticsItem->count() > 3) {
-
-        mAnalyticsItem->selfrecord();
-
+    if (mediametrics_count(mMetricsHandle) > 3) {
+        mediametrics_selfRecord(mMetricsHandle);
         // re-init in case we prepare() and start() again.
-        delete mAnalyticsItem ;
-        mAnalyticsItem = new MediaAnalyticsItem(kKeyPlayer);
-        if (mAnalyticsItem) {
-            mAnalyticsItem->setUid(mClientUid);
-        }
+        mediametrics_delete(mMetricsHandle);
+        mMetricsHandle = mediametrics_create(kKeyPlayer);
+        mediametrics_setUid(mMetricsHandle, mClientUid);
+        mediametrics_setInt64(mMetricsHandle, kPlayerVersion, mPlayerVersion);
     } else {
         ALOGV("did not have anything to record");
     }
@@ -601,10 +563,6 @@
             break;
     }
 
-    if (mState != STATE_STOPPED) {
-        // notifyListener_l(MEDIA2_STOPPED);
-    }
-
     mState = STATE_RESET_IN_PROGRESS;
     mPlayer->resetAsync();
 
@@ -633,50 +591,51 @@
     return OK;
 }
 
-status_t NuPlayer2Driver::invoke(const Parcel &request, Parcel *reply) {
-    if (reply == NULL) {
+status_t NuPlayer2Driver::invoke(const PlayerMessage &request, PlayerMessage *response) {
+    if (response == NULL) {
         ALOGE("reply is a NULL pointer");
         return BAD_VALUE;
     }
 
-    int32_t methodId;
-    status_t ret = request.readInt32(&methodId);
-    if (ret != OK) {
-        ALOGE("Failed to retrieve the requested method to invoke, err(%d)", ret);
-        return ret;
-    }
+    RepeatedPtrField<const Value>::const_iterator it = request.values().cbegin();
+    int32_t methodId = (it++)->int32_value();
 
     switch (methodId) {
         case MEDIA_PLAYER2_INVOKE_ID_SET_VIDEO_SCALING_MODE:
         {
-            int mode = request.readInt32();
+            int mode = (it++)->int32_value();
             return mPlayer->setVideoScalingMode(mode);
         }
 
         case MEDIA_PLAYER2_INVOKE_ID_GET_TRACK_INFO:
         {
-            return mPlayer->getTrackInfo(reply);
+            int64_t srcId = (it++)->int64_value();
+            return mPlayer->getTrackInfo(srcId, response);
         }
 
         case MEDIA_PLAYER2_INVOKE_ID_SELECT_TRACK:
         {
-            int trackIndex = request.readInt32();
+            int64_t srcId = (it++)->int64_value();
+            int trackIndex = (it++)->int32_value();
             int64_t msec = 0;
             // getCurrentPosition should always return OK
             getCurrentPosition(&msec);
-            return mPlayer->selectTrack(trackIndex, true /* select */, msec * 1000ll);
+            return mPlayer->selectTrack(srcId, trackIndex, true /* select */, msec * 1000LL);
         }
 
         case MEDIA_PLAYER2_INVOKE_ID_UNSELECT_TRACK:
         {
-            int trackIndex = request.readInt32();
-            return mPlayer->selectTrack(trackIndex, false /* select */, 0xdeadbeef /* not used */);
+            int64_t srcId = (it++)->int64_value();
+            int trackIndex = (it++)->int32_value();
+            return mPlayer->selectTrack(
+                    srcId, trackIndex, false /* select */, 0xdeadbeef /* not used */);
         }
 
         case MEDIA_PLAYER2_INVOKE_ID_GET_SELECTED_TRACK:
         {
-            int32_t type = request.readInt32();
-            return mPlayer->getSelectedTrack(type, reply);
+            int64_t srcId = (it++)->int64_value();
+            int32_t type = (it++)->int32_value();
+            return mPlayer->getSelectedTrack(srcId, type, response);
         }
 
         default:
@@ -696,44 +655,16 @@
     return INVALID_OPERATION;
 }
 
-status_t NuPlayer2Driver::getParameter(int key, Parcel *reply) {
-
-    if (key == FOURCC('m','t','r','X')) {
-        // mtrX -- a play on 'metrics' (not matrix)
-        // gather current info all together, parcel it, and send it back
-        updateMetrics("api");
-        mAnalyticsItem->writeToParcel(reply);
-        return OK;
-    }
-
+status_t NuPlayer2Driver::getParameter(int key __unused, Parcel *reply __unused) {
     return INVALID_OPERATION;
 }
 
-status_t NuPlayer2Driver::getMetadata(
-        const media::Metadata::Filter& /* ids */, Parcel *records) {
-    Mutex::Autolock autoLock(mLock);
-
-    using media::Metadata;
-
-    Metadata meta(records);
-
-    meta.appendBool(
-            Metadata::kPauseAvailable,
-            mPlayerFlags & NuPlayer2::Source::FLAG_CAN_PAUSE);
-
-    meta.appendBool(
-            Metadata::kSeekBackwardAvailable,
-            mPlayerFlags & NuPlayer2::Source::FLAG_CAN_SEEK_BACKWARD);
-
-    meta.appendBool(
-            Metadata::kSeekForwardAvailable,
-            mPlayerFlags & NuPlayer2::Source::FLAG_CAN_SEEK_FORWARD);
-
-    meta.appendBool(
-            Metadata::kSeekAvailable,
-            mPlayerFlags & NuPlayer2::Source::FLAG_CAN_SEEK);
-
-    return OK;
+status_t NuPlayer2Driver::getMetrics(char **buffer, size_t *length) {
+    updateMetrics("api");
+    if (mediametrics_getAttributes(mMetricsHandle, buffer, length))
+        return OK;
+    else
+        return FAILED_TRANSACTION;
 }
 
 void NuPlayer2Driver::notifyResetComplete(int64_t /* srcId */) {
@@ -780,20 +711,7 @@
     ALOGV("notifySeekComplete(%p)", this);
     Mutex::Autolock autoLock(mLock);
     mSeekInProgress = false;
-    notifySeekComplete_l(srcId);
-}
-
-void NuPlayer2Driver::notifySeekComplete_l(int64_t srcId) {
-    bool wasSeeking = true;
-    if (mState == STATE_STOPPED_AND_PREPARING) {
-        wasSeeking = false;
-        mState = STATE_STOPPED_AND_PREPARED;
-        mCondition.broadcast();
-    } else if (mState == STATE_STOPPED) {
-        // no need to notify listener
-        return;
-    }
-    notifyListener_l(srcId, wasSeeking ? MEDIA2_SEEK_COMPLETE : MEDIA2_PREPARED);
+    notifyListener_l(srcId, MEDIA2_SEEK_COMPLETE);
 }
 
 status_t NuPlayer2Driver::dump(
@@ -884,12 +802,12 @@
             CHECK(msg->findInt32("messageId", &msgId));
             msg->findInt32("ext1", &ext1);
             msg->findInt32("ext2", &ext2);
-            sp<ParcelWrapper> in;
+            sp<PlayerMessageWrapper> in;
             sp<RefBase> obj;
-            if (msg->findObject("parcel", &obj) && obj != NULL) {
-                in = static_cast<ParcelWrapper *>(obj.get());
+            if (msg->findObject("obj", &obj) && obj != NULL) {
+                in = static_cast<PlayerMessageWrapper *>(obj.get());
             }
-            sendEvent(srcId, msgId, ext1, ext2, (in == NULL ? NULL : in->getParcel()));
+            sendEvent(srcId, msgId, ext1, ext2, (in == NULL ? NULL : in->getPlayerMessage()));
             break;
         }
         default:
@@ -898,16 +816,16 @@
 }
 
 void NuPlayer2Driver::notifyListener(
-        int64_t srcId, int msg, int ext1, int ext2, const Parcel *in) {
+        int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in) {
     Mutex::Autolock autoLock(mLock);
     notifyListener_l(srcId, msg, ext1, ext2, in);
 }
 
 void NuPlayer2Driver::notifyListener_l(
-        int64_t srcId, int msg, int ext1, int ext2, const Parcel *in) {
+        int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in) {
     ALOGD("notifyListener_l(%p), (%lld, %d, %d, %d, %d), loop setting(%d, %d)",
             this, (long long)srcId, msg, ext1, ext2,
-            (in == NULL ? -1 : (int)in->dataSize()), mAutoLoop, mLooping);
+            (in == NULL ? -1 : (int)in->ByteSize()), mAutoLoop, mLooping);
     if (srcId == mSrcId) {
         switch (msg) {
             case MEDIA2_PLAYBACK_COMPLETE:
@@ -924,13 +842,18 @@
                         }
                     }
                     if (mLooping || mAutoLoop) {
-                        mPlayer->seekToAsync(0);
+                        mPlayer->rewind();
                         if (mAudioSink != NULL) {
                             // The renderer has stopped the sink at the end in order to play out
                             // the last little bit of audio. In looping mode, we need to restart it.
                             mAudioSink->start();
                         }
-                        // don't send completion event when looping
+
+                        sp<AMessage> notify = new AMessage(kWhatNotifyListener, this);
+                        notify->setInt64("srcId", srcId);
+                        notify->setInt32("messageId", MEDIA2_INFO);
+                        notify->setInt32("ext1", MEDIA2_INFO_DATA_SOURCE_REPEAT);
+                        notify->post();
                         return;
                     }
                     if (property_get_bool("persist.debug.sf.stats", false)) {
@@ -940,7 +863,7 @@
                     mPlayer->pause();
                     mState = STATE_PAUSED;
                 }
-                // fall through
+                FALLTHROUGH_INTENDED;
             }
 
             case MEDIA2_ERROR:
@@ -949,11 +872,11 @@
                 // ext1 is our primary 'error type' value. Only add ext2 when non-zero.
                 // [test against msg is due to fall through from previous switch value]
                 if (msg == MEDIA2_ERROR) {
-                    mAnalyticsItem->setInt32(kPlayerError, ext1);
+                    mediametrics_setInt32(mMetricsHandle, kPlayerError, ext1);
                     if (ext2 != 0) {
-                        mAnalyticsItem->setInt32(kPlayerErrorCode, ext2);
+                        mediametrics_setInt32(mMetricsHandle, kPlayerErrorCode, ext2);
                     }
-                    mAnalyticsItem->setCString(kPlayerErrorState, stateString(mState).c_str());
+                    mediametrics_setCString(mMetricsHandle, kPlayerErrorState, stateString(mState).c_str());
                 }
                 mAtEOS = true;
                 break;
@@ -969,7 +892,7 @@
     notify->setInt32("messageId", msg);
     notify->setInt32("ext1", ext1);
     notify->setInt32("ext2", ext2);
-    notify->setObject("parcel", ParcelWrapper::Create(in));
+    notify->setObject("obj", PlayerMessageWrapper::Create((PlayerMessage*)in));
     notify->post();
 }
 
@@ -1036,24 +959,25 @@
 }
 
 // Modular DRM
-status_t NuPlayer2Driver::prepareDrm(const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
+status_t NuPlayer2Driver::prepareDrm(
+        int64_t srcId, const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
 {
     ALOGV("prepareDrm(%p) state: %d", this, mState);
 
     // leaving the state verification for mediaplayer.cpp
-    status_t ret = mPlayer->prepareDrm(uuid, drmSessionId);
+    status_t ret = mPlayer->prepareDrm(srcId, uuid, drmSessionId);
 
     ALOGV("prepareDrm ret: %d", ret);
 
     return ret;
 }
 
-status_t NuPlayer2Driver::releaseDrm()
+status_t NuPlayer2Driver::releaseDrm(int64_t srcId)
 {
     ALOGV("releaseDrm(%p) state: %d", this, mState);
 
     // leaving the state verification for mediaplayer.cpp
-    status_t ret = mPlayer->releaseDrm();
+    status_t ret = mPlayer->releaseDrm(srcId);
 
     ALOGV("releaseDrm ret: %d", ret);
 
@@ -1073,9 +997,6 @@
         case STATE_RUNNING: rval = "RUNNING"; break;
         case STATE_PAUSED: rval = "PAUSED"; break;
         case STATE_RESET_IN_PROGRESS: rval = "RESET_IN_PROGRESS"; break;
-        case STATE_STOPPED: rval = "STOPPED"; break;
-        case STATE_STOPPED_AND_PREPARING: rval = "STOPPED_AND_PREPARING"; break;
-        case STATE_STOPPED_AND_PREPARED: rval = "STOPPED_AND_PREPARED"; break;
         default:
             // yes, this buffer is shared and vulnerable to races
             snprintf(rawbuffer, sizeof(rawbuffer), "%d", state);
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.h b/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.h
index 4da2566..c97e247 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.h
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.h
@@ -16,8 +16,9 @@
 
 #include <mediaplayer2/MediaPlayer2Interface.h>
 
-#include <media/MediaAnalyticsItem.h>
+#include <media/MediaMetrics.h>
 #include <media/stagefright/foundation/ABase.h>
+#include <mediaplayer2/JObjectHolder.h>
 
 namespace android {
 
@@ -26,7 +27,7 @@
 struct NuPlayer2;
 
 struct NuPlayer2Driver : public MediaPlayer2Interface {
-    explicit NuPlayer2Driver(pid_t pid, uid_t uid);
+    explicit NuPlayer2Driver(pid_t pid, uid_t uid, const sp<JObjectHolder> &context);
 
     virtual status_t initCheck() override;
 
@@ -40,31 +41,29 @@
             BufferingSettings* buffering /* nonnull */) override;
     virtual status_t setBufferingSettings(const BufferingSettings& buffering) override;
 
-    virtual status_t prepareAsync();
-    virtual status_t start();
-    virtual status_t stop();
-    virtual status_t pause();
-    virtual bool isPlaying();
-    virtual status_t setPlaybackSettings(const AudioPlaybackRate &rate);
-    virtual status_t getPlaybackSettings(AudioPlaybackRate *rate);
-    virtual status_t setSyncSettings(const AVSyncSettings &sync, float videoFpsHint);
-    virtual status_t getSyncSettings(AVSyncSettings *sync, float *videoFps);
+    virtual status_t prepareAsync() override;
+    virtual status_t start() override;
+    virtual status_t pause() override;
+    virtual bool isPlaying() override;
+    virtual status_t setPlaybackSettings(const AudioPlaybackRate &rate) override;
+    virtual status_t getPlaybackSettings(AudioPlaybackRate *rate) override;
+    virtual status_t setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) override;
+    virtual status_t getSyncSettings(AVSyncSettings *sync, float *videoFps) override;
     virtual status_t seekTo(
-            int64_t msec, MediaPlayer2SeekMode mode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC);
-    virtual status_t getCurrentPosition(int64_t *msec);
-    virtual status_t getDuration(int64_t *msec);
-    virtual status_t reset();
+            int64_t msec,
+            MediaPlayer2SeekMode mode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC) override;
+    virtual status_t getCurrentPosition(int64_t *msec) override;
+    virtual status_t getDuration(int64_t *msec) override;
+    virtual status_t reset() override;
     virtual status_t notifyAt(int64_t mediaTimeUs) override;
-    virtual status_t setLooping(int loop);
-    virtual status_t invoke(const Parcel &request, Parcel *reply);
-    virtual void setAudioSink(const sp<AudioSink> &audioSink);
-    virtual status_t setParameter(int key, const Parcel &request);
-    virtual status_t getParameter(int key, Parcel *reply);
+    virtual status_t setLooping(int loop) override;
+    virtual status_t invoke(const PlayerMessage &request, PlayerMessage *response) override;
+    virtual void setAudioSink(const sp<AudioSink> &audioSink) override;
+    virtual status_t setParameter(int key, const Parcel &request) override;
+    virtual status_t getParameter(int key, Parcel *reply) override;
+    virtual status_t getMetrics(char **buf, size_t *length) override;
 
-    virtual status_t getMetadata(
-            const media::Metadata::Filter& ids, Parcel *records);
-
-    virtual status_t dump(int fd, const Vector<String16> &args) const;
+    virtual status_t dump(int fd, const Vector<String16> &args) const override;
 
     virtual void onMessageReceived(const sp<AMessage> &msg) override;
 
@@ -77,14 +76,14 @@
     void notifyMoreRebufferingTimeUs(int64_t srcId, int64_t timeUs);
     void notifyRebufferingWhenExit(int64_t srcId, bool status);
     void notifySeekComplete(int64_t srcId);
-    void notifySeekComplete_l(int64_t srcId);
     void notifyListener(int64_t srcId, int msg, int ext1 = 0, int ext2 = 0,
-                        const Parcel *in = NULL);
+                        const PlayerMessage *in = NULL);
     void notifyFlagsChanged(int64_t srcId, uint32_t flags);
 
     // Modular DRM
-    virtual status_t prepareDrm(const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId);
-    virtual status_t releaseDrm();
+    virtual status_t prepareDrm(
+            int64_t srcId, const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId);
+    virtual status_t releaseDrm(int64_t srcId);
 
 protected:
     virtual ~NuPlayer2Driver();
@@ -99,9 +98,6 @@
         STATE_RUNNING,
         STATE_PAUSED,
         STATE_RESET_IN_PROGRESS,
-        STATE_STOPPED,                  // equivalent to PAUSED
-        STATE_STOPPED_AND_PREPARING,    // equivalent to PAUSED, but seeking
-        STATE_STOPPED_AND_PREPARED,     // equivalent to PAUSED, but seek complete
     };
 
     std::string stateString(State state);
@@ -137,7 +133,8 @@
     sp<AudioSink> mAudioSink;
     uint32_t mPlayerFlags;
 
-    MediaAnalyticsItem *mAnalyticsItem;
+    mediametrics_handle_t mMetricsHandle;
+    int64_t mPlayerVersion;
     uid_t mClientUid;
 
     bool mAtEOS;
@@ -149,7 +146,7 @@
 
     status_t start_l();
     void notifyListener_l(int64_t srcId, int msg, int ext1 = 0, int ext2 = 0,
-                          const Parcel *in = NULL);
+                          const PlayerMessage *in = NULL);
 
     DISALLOW_EVIL_CONSTRUCTORS(NuPlayer2Driver);
 };
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Drm.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2Drm.cpp
index 4853ae1..f41a431 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Drm.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2Drm.cpp
@@ -133,9 +133,8 @@
     return drmInfoBuffer;
 }
 
-sp<ABuffer> NuPlayer2Drm::retrieveDrmInfo(PsshInfo *psshInfo)
+status_t NuPlayer2Drm::retrieveDrmInfo(PsshInfo *psshInfo, PlayerMessage *playerMsg)
 {
-
     std::ostringstream pssh, drmInfo;
 
     // 0) Generate PSSH bytes
@@ -148,27 +147,26 @@
     }
 
     uint32_t psshSize = pssh.tellp();
-    const uint8_t* psshPtr = reinterpret_cast<const uint8_t*>(pssh.str().c_str());
-    const char *psshHex = DrmUUID::arrayToHex(psshPtr, psshSize).string();
-    ALOGV("retrieveDrmInfo: MEDIA_DRM_INFO  PSSH: size: %u %s", psshSize, psshHex);
+    std::string psshBase = pssh.str();
+    const auto* psshPtr = reinterpret_cast<const uint8_t*>(psshBase.c_str());
+    ALOGV("retrieveDrmInfo: MEDIA_DRM_INFO  PSSH: size: %u %s", psshSize,
+            DrmUUID::arrayToHex(psshPtr, psshSize).string());
 
     // 1) Write PSSH bytes
-    drmInfo.write(reinterpret_cast<const char *>(&psshSize), sizeof(psshSize));
-    drmInfo.write(reinterpret_cast<const char *>(pssh.str().c_str()), psshSize);
+    playerMsg->add_values()->set_bytes_value(
+            reinterpret_cast<const char *>(pssh.str().c_str()), psshSize);
 
     // 2) Write supportedDRMs
     uint32_t numentries = psshInfo->numentries;
-    drmInfo.write(reinterpret_cast<const char *>(&numentries), sizeof(numentries));
+    playerMsg->add_values()->set_int32_value(numentries);
     for (size_t i = 0; i < numentries; i++) {
         PsshEntry *entry = &psshInfo->entries[i];
-        drmInfo.write(reinterpret_cast<const char *>(&entry->uuid), sizeof(entry->uuid));
+        playerMsg->add_values()->set_bytes_value(
+                reinterpret_cast<const char *>(&entry->uuid), sizeof(entry->uuid));
         ALOGV("retrieveDrmInfo: MEDIA_DRM_INFO  supportedScheme[%zu] %s", i,
                 DrmUUID::arrayToHex((const uint8_t*)&entry->uuid, sizeof(AMediaUUID)).string());
     }
-
-    sp<ABuffer> drmInfoBuf = ABuffer::CreateAsCopy(drmInfo.str().c_str(), drmInfo.tellp());
-    drmInfoBuf->setRange(0, drmInfo.tellp());
-    return drmInfoBuf;
+    return OK;
 }
 
 }   // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Drm.h b/media/libmediaplayer2/nuplayer2/NuPlayer2Drm.h
index 99d2415..968d1be 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Drm.h
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2Drm.h
@@ -23,6 +23,10 @@
 #include <utils/String8.h>
 #include <utils/Vector.h>
 
+#include "mediaplayer2.pb.h"
+
+using android::media::MediaPlayer2Proto::PlayerMessage;
+
 namespace android {
 
     struct DrmUUID {
@@ -80,7 +84,7 @@
 
     public:
         static sp<ABuffer> retrieveDrmInfo(const void *pssh, uint32_t psshsize);
-        static sp<ABuffer> retrieveDrmInfo(PsshInfo *);
+        static status_t retrieveDrmInfo(PsshInfo *, PlayerMessage *);
 
     };  // NuPlayer2Drm
 
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.cpp
index a0bd900..fd459df 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.cpp
@@ -26,9 +26,11 @@
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/foundation/AUtils.h>
 #include <media/stagefright/MediaClock.h>
+#include <media/stagefright/MediaCodecConstants.h>
+#include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/Utils.h>
-#include <media/stagefright/VideoFrameScheduler.h>
+#include <media/stagefright/VideoFrameScheduler2.h>
 #include <media/MediaCodecBuffer.h>
 
 #include <inttypes.h>
@@ -67,13 +69,17 @@
 
 // Maximum time in paused state when offloading audio decompression. When elapsed, the AudioSink
 // is closed to allow the audio DSP to power down.
-static const int64_t kOffloadPauseMaxUs = 10000000ll;
+static const int64_t kOffloadPauseMaxUs = 10000000LL;
 
 // Maximum allowed delay from AudioSink, 1.5 seconds.
-static const int64_t kMaxAllowedAudioSinkDelayUs = 1500000ll;
+static const int64_t kMaxAllowedAudioSinkDelayUs = 1500000LL;
 
 static const int64_t kMinimumAudioClockUpdatePeriodUs = 20 /* msec */ * 1000;
 
+// Default video frame display duration when only video exists.
+// Used to set max media time in MediaClock.
+static const int64_t kDefaultVideoFrameIntervalUs = 100000LL;
+
 // static
 const NuPlayer2::Renderer::PcmInfo NuPlayer2::Renderer::AUDIO_PCMINFO_INITIALIZER = {
         AUDIO_CHANNEL_NONE,
@@ -84,12 +90,27 @@
 };
 
 // static
-const int64_t NuPlayer2::Renderer::kMinPositionUpdateDelayUs = 100000ll;
+const int64_t NuPlayer2::Renderer::kMinPositionUpdateDelayUs = 100000LL;
+
+static audio_format_t constexpr audioFormatFromEncoding(int32_t pcmEncoding) {
+    switch (pcmEncoding) {
+    case kAudioEncodingPcmFloat:
+        return AUDIO_FORMAT_PCM_FLOAT;
+    case kAudioEncodingPcm16bit:
+        return AUDIO_FORMAT_PCM_16_BIT;
+    case kAudioEncodingPcm8bit:
+        return AUDIO_FORMAT_PCM_8_BIT;  // TODO: do we want to support this?
+    default:
+        ALOGE("%s: Invalid encoding: %d", __func__, pcmEncoding);
+        return AUDIO_FORMAT_INVALID;
+    }
+}
 
 NuPlayer2::Renderer::Renderer(
         const sp<MediaPlayer2Interface::AudioSink> &sink,
         const sp<MediaClock> &mediaClock,
         const sp<AMessage> &notify,
+        const sp<JObjectHolder> &context,
         uint32_t flags)
     : mAudioSink(sink),
       mUseVirtualAudioSink(false),
@@ -108,14 +129,14 @@
       mAudioFirstAnchorTimeMediaUs(-1),
       mAnchorTimeMediaUs(-1),
       mAnchorNumFramesWritten(-1),
-      mVideoLateByUs(0ll),
+      mVideoLateByUs(0LL),
       mNextVideoTimeMediaUs(-1),
       mHasAudio(false),
       mHasVideo(false),
       mNotifyCompleteAudio(false),
       mNotifyCompleteVideo(false),
       mSyncQueues(false),
-      mPaused(false),
+      mPaused(true),
       mPauseDrainAudioAllowedUs(0),
       mVideoSampleReceived(false),
       mVideoRenderingStarted(false),
@@ -131,10 +152,9 @@
       mTotalBuffersQueued(0),
       mLastAudioBufferDrained(0),
       mUseAudioCallback(false),
-      mWakeLock(new JWakeLock()) {
+      mWakeLock(new JWakeLock(context)) {
     CHECK(mediaClock != NULL);
-    mPlaybackRate = mPlaybackSettings.mSpeed;
-    mMediaClock->setPlaybackRate(mPlaybackRate);
+    mMediaClock->setPlaybackRate(mPlaybackSettings.mSpeed);
 }
 
 NuPlayer2::Renderer::~Renderer() {
@@ -190,26 +210,20 @@
 }
 
 status_t NuPlayer2::Renderer::onConfigPlayback(const AudioPlaybackRate &rate /* sanitized */) {
-    if (rate.mSpeed == 0.f) {
-        onPause();
-        // don't call audiosink's setPlaybackRate if pausing, as pitch does not
-        // have to correspond to the any non-0 speed (e.g old speed). Keep
-        // settings nonetheless, using the old speed, in case audiosink changes.
-        AudioPlaybackRate newRate = rate;
-        newRate.mSpeed = mPlaybackSettings.mSpeed;
-        mPlaybackSettings = newRate;
-        return OK;
+    if (rate.mSpeed <= 0.f) {
+        ALOGW("playback rate cannot be %f", rate.mSpeed);
+        return BAD_VALUE;
     }
 
     if (mAudioSink != NULL && mAudioSink->ready()) {
         status_t err = mAudioSink->setPlaybackRate(rate);
         if (err != OK) {
+            ALOGW("failed to get playback rate from audio sink, err(%d)", err);
             return err;
         }
     }
     mPlaybackSettings = rate;
-    mPlaybackRate = rate.mSpeed;
-    mMediaClock->setPlaybackRate(mPlaybackRate);
+    mMediaClock->setPlaybackRate(mPlaybackSettings.mSpeed);
     return OK;
 }
 
@@ -231,14 +245,12 @@
         status_t err = mAudioSink->getPlaybackRate(rate);
         if (err == OK) {
             if (!isAudioPlaybackRateEqual(*rate, mPlaybackSettings)) {
-                ALOGW("correcting mismatch in internal/external playback rate");
+                ALOGW("correcting mismatch in internal/external playback rate, %f vs %f",
+                      rate->mSpeed, mPlaybackSettings.mSpeed);
             }
             // get playback settings used by audiosink, as it may be
             // slightly off due to audiosink not taking small changes.
             mPlaybackSettings = *rate;
-            if (mPaused) {
-                rate->mSpeed = 0.f;
-            }
         }
         return err;
     }
@@ -297,11 +309,11 @@
             mNotifyCompleteVideo |= notifyComplete;
             ++mVideoQueueGeneration;
             ++mVideoDrainGeneration;
+            mNextVideoTimeMediaUs = -1;
         }
 
         mMediaClock->clearAnchor();
         mVideoLateByUs = 0;
-        mNextVideoTimeMediaUs = -1;
         mSyncQueues = false;
     }
 
@@ -560,8 +572,8 @@
                 int64_t delayUs =
                     mAudioSink->msecsPerFrame()
                         * numFramesPendingPlayout * 1000ll;
-                if (mPlaybackRate > 1.0f) {
-                    delayUs /= mPlaybackRate;
+                if (mPlaybackSettings.mSpeed > 1.0f) {
+                    delayUs /= mPlaybackSettings.mSpeed;
                 }
 
                 // Let's give it more data after about half that time
@@ -1140,8 +1152,7 @@
         ALOGE("sampleRate is 0 in %s mode", offloadingAudio() ? "offload" : "non-offload");
         return 0;
     }
-    // TODO: remove the (int32_t) casting below as it may overflow at 12.4 hours.
-    return (int64_t)((int32_t)numFrames * 1000000LL / sampleRate);
+    return (int64_t)(numFrames * 1000000LL / sampleRate);
 }
 
 // Calculate duration of pending samples if played at normal rate (i.e., 1.0).
@@ -1151,7 +1162,7 @@
         int64_t nowUs = ALooper::GetNowUs();
         int64_t mediaUs;
         if (mMediaClock->getMediaTime(nowUs, &mediaUs) != OK) {
-            return 0ll;
+            return 0LL;
         } else {
             return writtenAudioDurationUs - (mediaUs - mAudioFirstAnchorTimeMediaUs);
         }
@@ -1278,10 +1289,10 @@
             mAnchorTimeMediaUs = mediaTimeUs;
         }
     }
-    mNextVideoTimeMediaUs = mediaTimeUs + 100000;
+    mNextVideoTimeMediaUs = mediaTimeUs;
     if (!mHasAudio) {
         // smooth out videos >= 10fps
-        mMediaClock->updateMaxTimeMedia(mNextVideoTimeMediaUs);
+        mMediaClock->updateMaxTimeMedia(mediaTimeUs + kDefaultVideoFrameIntervalUs);
     }
 
     if (!mVideoSampleReceived || mediaTimeUs < mAudioFirstAnchorTimeMediaUs) {
@@ -1348,7 +1359,7 @@
                     && mediaTimeUs > mLastAudioMediaTimeUs) {
                 // If audio ends before video, video continues to drive media clock.
                 // Also smooth out videos >= 10fps.
-                mMediaClock->updateMaxTimeMedia(mediaTimeUs + 100000);
+                mMediaClock->updateMaxTimeMedia(mediaTimeUs + kDefaultVideoFrameIntervalUs);
             }
         }
     } else {
@@ -1366,7 +1377,7 @@
         tooLate = false;
     }
 
-    entry->mNotifyConsumed->setInt64("timestampNs", realTimeUs * 1000ll);
+    entry->mNotifyConsumed->setInt64("timestampNs", realTimeUs * 1000LL);
     entry->mNotifyConsumed->setInt32("render", !tooLate);
     entry->mNotifyConsumed->post();
     mVideoQueue.erase(mVideoQueue.begin());
@@ -1415,9 +1426,16 @@
         mHasAudio = false;
         if (mNextVideoTimeMediaUs >= 0) {
             int64_t mediaUs = 0;
-            mMediaClock->getMediaTime(ALooper::GetNowUs(), &mediaUs);
-            if (mNextVideoTimeMediaUs > mediaUs) {
-                mMediaClock->updateMaxTimeMedia(mNextVideoTimeMediaUs);
+            int64_t nowUs = ALooper::GetNowUs();
+            status_t result = mMediaClock->getMediaTime(nowUs, &mediaUs);
+            if (result == OK) {
+                if (mNextVideoTimeMediaUs > mediaUs) {
+                    mMediaClock->updateMaxTimeMedia(mNextVideoTimeMediaUs);
+                }
+            } else {
+                mMediaClock->updateAnchor(
+                        mNextVideoTimeMediaUs, nowUs,
+                        mNextVideoTimeMediaUs + kDefaultVideoFrameIntervalUs);
             }
         }
     }
@@ -1445,7 +1463,7 @@
 
     if (mHasVideo) {
         if (mVideoScheduler == NULL) {
-            mVideoScheduler = new VideoFrameScheduler();
+            mVideoScheduler = new VideoFrameScheduler2();
             mVideoScheduler->init();
         }
     }
@@ -1498,7 +1516,7 @@
 
     ALOGV("queueDiff = %.2f secs", diff / 1E6);
 
-    if (diff > 100000ll) {
+    if (diff > 100000LL) {
         // Audio data starts More than 0.1 secs before video.
         // Drop some audio.
 
@@ -1570,9 +1588,18 @@
             notifyComplete = mNotifyCompleteAudio;
             mNotifyCompleteAudio = false;
             mLastAudioMediaTimeUs = -1;
+
+            mHasAudio = false;
+            if (mNextVideoTimeMediaUs >= 0) {
+                int64_t nowUs = ALooper::GetNowUs();
+                mMediaClock->updateAnchor(
+                        mNextVideoTimeMediaUs, nowUs,
+                        mNextVideoTimeMediaUs + kDefaultVideoFrameIntervalUs);
+            }
         } else {
             notifyComplete = mNotifyCompleteVideo;
             mNotifyCompleteVideo = false;
+            mVideoRenderingStarted = false;
         }
 
         // If we're currently syncing the queues, i.e. dropping audio while
@@ -1773,7 +1800,7 @@
             mAudioSink->setPlaybackRate(mPlaybackSettings);
         }
 
-        mMediaClock->setPlaybackRate(mPlaybackRate);
+        mMediaClock->setPlaybackRate(mPlaybackSettings.mSpeed);
 
         if (!mAudioQueue.empty()) {
             postDrainAudioQueue_l();
@@ -1787,7 +1814,7 @@
 
 void NuPlayer2::Renderer::onSetVideoFrameRate(float fps) {
     if (mVideoScheduler == NULL) {
-        mVideoScheduler = new VideoFrameScheduler();
+        mVideoScheduler = new VideoFrameScheduler2();
     }
     mVideoScheduler->init(fps);
 }
@@ -1857,6 +1884,7 @@
         bool isStreaming) {
     ALOGV("openAudioSink: offloadOnly(%d) offloadingAudio(%d)",
             offloadOnly, offloadingAudio());
+
     bool audioSinkChanged = false;
 
     int32_t numChannels;
@@ -1871,8 +1899,13 @@
     int32_t sampleRate;
     CHECK(format->findInt32("sample-rate", &sampleRate));
 
+    // read pcm encoding from MediaCodec output format, if available
+    int32_t pcmEncoding;
+    audio_format_t audioFormat =
+            format->findInt32(KEY_PCM_ENCODING, &pcmEncoding) ?
+                    audioFormatFromEncoding(pcmEncoding) : AUDIO_FORMAT_PCM_16_BIT;
+
     if (offloadingAudio()) {
-        audio_format_t audioFormat = AUDIO_FORMAT_PCM_16_BIT;
         AString mime;
         CHECK(format->findString("mime", &mime));
         status_t err = mapMimeToAudioFormat(audioFormat, mime.c_str());
@@ -1928,7 +1961,6 @@
                     numChannels,
                     (audio_channel_mask_t)channelMask,
                     audioFormat,
-                    0 /* bufferCount - unused */,
                     &NuPlayer2::Renderer::AudioSinkCallback,
                     this,
                     (audio_output_flags_t)offloadFlags,
@@ -1974,7 +2006,7 @@
         const PcmInfo info = {
                 (audio_channel_mask_t)channelMask,
                 (audio_output_flags_t)pcmFlags,
-                AUDIO_FORMAT_PCM_16_BIT, // TODO: change to audioFormat
+                audioFormat,
                 numChannels,
                 sampleRate
         };
@@ -1999,13 +2031,6 @@
         const uint32_t frameCount =
                 (unsigned long long)sampleRate * getAudioSinkPcmMsSetting() / 1000;
 
-        // The doNotReconnect means AudioSink will signal back and let NuPlayer2 to re-construct
-        // AudioSink. We don't want this when there's video because it will cause a video seek to
-        // the previous I frame. But we do want this when there's only audio because it will give
-        // NuPlayer2 a chance to switch from non-offload mode to offload mode.
-        // So we only set doNotReconnect when there's no video.
-        const bool doNotReconnect = !hasVideo;
-
         // We should always be able to set our playback settings if the sink is closed.
         LOG_ALWAYS_FATAL_IF(mAudioSink->setPlaybackRate(mPlaybackSettings) != OK,
                 "onOpenAudioSink: can't set playback rate on closed sink");
@@ -2013,13 +2038,11 @@
                     sampleRate,
                     numChannels,
                     (audio_channel_mask_t)channelMask,
-                    AUDIO_FORMAT_PCM_16_BIT,
-                    0 /* bufferCount - unused */,
+                    audioFormat,
                     mUseAudioCallback ? &NuPlayer2::Renderer::AudioSinkCallback : NULL,
                     mUseAudioCallback ? this : NULL,
                     (audio_output_flags_t)pcmFlags,
                     NULL,
-                    doNotReconnect,
                     frameCount);
         if (err != OK) {
             ALOGW("openAudioSink: non offloaded open failed status: %d", err);
@@ -2071,4 +2094,3 @@
 }
 
 }  // namespace android
-
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.h b/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.h
index 62cf0d8..d065dee 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.h
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.h
@@ -20,6 +20,7 @@
 
 #include <media/AudioResamplerPublic.h>
 #include <media/AVSyncSettings.h>
+#include <mediaplayer2/JObjectHolder.h>
 
 #include "NuPlayer2.h"
 
@@ -28,7 +29,7 @@
 class  JWakeLock;
 struct MediaClock;
 class MediaCodecBuffer;
-struct VideoFrameScheduler;
+struct VideoFrameSchedulerBase;
 
 struct NuPlayer2::Renderer : public AHandler {
     enum Flags {
@@ -38,6 +39,7 @@
     Renderer(const sp<MediaPlayer2Interface::AudioSink> &sink,
              const sp<MediaClock> &mediaClock,
              const sp<AMessage> &notify,
+             const sp<JObjectHolder> &context,
              uint32_t flags = 0);
 
     static size_t AudioSinkCallback(
@@ -156,7 +158,7 @@
     List<QueueEntry> mAudioQueue;
     List<QueueEntry> mVideoQueue;
     uint32_t mNumFramesWritten;
-    sp<VideoFrameScheduler> mVideoScheduler;
+    sp<VideoFrameSchedulerBase> mVideoScheduler;
 
     bool mDrainAudioQueuePending;
     bool mDrainVideoQueuePending;
@@ -167,7 +169,6 @@
     int32_t mAudioEOSGeneration;
 
     const sp<MediaClock> mMediaClock;
-    float mPlaybackRate; // audio track rate
 
     AudioPlaybackRate mPlaybackSettings;
     AVSyncSettings mSyncSettings;
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Source.h b/media/libmediaplayer2/nuplayer2/NuPlayer2Source.h
index 662235f..9298a99 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Source.h
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2Source.h
@@ -69,7 +69,7 @@
             BufferingSettings* buffering /* nonnull */) = 0;
     virtual status_t setBufferingSettings(const BufferingSettings& buffering) = 0;
 
-    virtual void prepareAsync() = 0;
+    virtual void prepareAsync(int64_t startTimeUs) = 0;
 
     virtual void start() = 0;
     virtual void stop() {}
diff --git a/media/libmediaplayer2/nuplayer2/RTSPSource2.cpp b/media/libmediaplayer2/nuplayer2/RTSPSource2.cpp
index 1dfe383..a70269e 100644
--- a/media/libmediaplayer2/nuplayer2/RTSPSource2.cpp
+++ b/media/libmediaplayer2/nuplayer2/RTSPSource2.cpp
@@ -30,7 +30,7 @@
 
 namespace android {
 
-const int64_t kNearEOSTimeoutUs = 2000000ll; // 2 secs
+const int64_t kNearEOSTimeoutUs = 2000000LL; // 2 secs
 
 // Default Buffer Underflow/Prepare/StartServer/Overflow Marks
 static const int kUnderflowMarkMs   =  1000;  // 1 second
@@ -96,7 +96,8 @@
     return OK;
 }
 
-void NuPlayer2::RTSPSource2::prepareAsync() {
+// TODO: fetch data starting from |startTimeUs|
+void NuPlayer2::RTSPSource2::prepareAsync(int64_t /* startTimeUs */) {
     if (mIsSDP && mHTTPService == NULL) {
         notifyPrepared(BAD_VALUE);
         return;
@@ -104,7 +105,7 @@
 
     if (mLooper == NULL) {
         mLooper = new ALooper;
-        mLooper->setName("rtsp");
+        mLooper->setName("rtsp2");
         mLooper->start();
 
         mLooper->registerHandler(this);
@@ -167,7 +168,7 @@
     // We're going to buffer at least 2 secs worth data on all tracks before
     // starting playback (both at startup and after a seek).
 
-    static const int64_t kMinDurationUs = 2000000ll;
+    static const int64_t kMinDurationUs = 2000000LL;
 
     int64_t mediaDurationUs = 0;
     getDuration(&mediaDurationUs);
@@ -271,7 +272,7 @@
 }
 
 status_t NuPlayer2::RTSPSource2::getDuration(int64_t *durationUs) {
-    *durationUs = -1ll;
+    *durationUs = -1LL;
 
     int64_t audioDurationUs;
     if (mAudioTrack != NULL
@@ -320,7 +321,7 @@
 
 void NuPlayer2::RTSPSource2::schedulePollBuffering() {
     sp<AMessage> msg = new AMessage(kWhatPollBuffering, this);
-    msg->post(1000000ll); // 1 second intervals
+    msg->post(1000000LL); // 1 second intervals
 }
 
 void NuPlayer2::RTSPSource2::checkBuffering(
@@ -344,10 +345,10 @@
         int64_t maxRebufferingMarkUs;
         {
             Mutex::Autolock _l(mBufferingSettingsLock);
-            initialMarkUs = mBufferingSettings.mInitialMarkMs * 1000ll;
+            initialMarkUs = mBufferingSettings.mInitialMarkMs * 1000LL;
             // TODO: maxRebufferingMarkUs could be larger than
             // mBufferingSettings.mResumePlaybackMarkMs * 1000ll.
-            maxRebufferingMarkUs = mBufferingSettings.mResumePlaybackMarkMs * 1000ll;
+            maxRebufferingMarkUs = mBufferingSettings.mResumePlaybackMarkMs * 1000LL;
         }
         // isFinished when duration is 0 checks for EOS result only
         if (bufferedDurationUs > initialMarkUs
@@ -367,7 +368,7 @@
                 ++overflowCount;
             }
             int64_t startServerMarkUs =
-                    (kUnderflowMarkMs * 1000ll + maxRebufferingMarkUs) / 2;
+                    (kUnderflowMarkMs * 1000LL + maxRebufferingMarkUs) / 2;
             if (bufferedDurationUs < startServerMarkUs) {
                 ++startCount;
             }
@@ -638,7 +639,7 @@
                 int64_t nptUs =
                     ((double)rtpTime - (double)info->mRTPTime)
                         / info->mTimeScale
-                        * 1000000ll
+                        * 1000000LL
                         + info->mNormalPlaytimeUs;
 
                 accessUnit->meta()->setInt64("timeUs", nptUs);
@@ -746,7 +747,7 @@
         TrackInfo info;
         info.mTimeScale = timeScale;
         info.mRTPTime = 0;
-        info.mNormalPlaytimeUs = 0ll;
+        info.mNormalPlaytimeUs = 0LL;
         info.mNPTMappingValid = false;
 
         if ((isAudio && mAudioTrack == NULL)
diff --git a/media/libmediaplayer2/nuplayer2/RTSPSource2.h b/media/libmediaplayer2/nuplayer2/RTSPSource2.h
index 712c3e5..e5f1716 100644
--- a/media/libmediaplayer2/nuplayer2/RTSPSource2.h
+++ b/media/libmediaplayer2/nuplayer2/RTSPSource2.h
@@ -43,7 +43,7 @@
             BufferingSettings* buffering /* nonnull */) override;
     virtual status_t setBufferingSettings(const BufferingSettings& buffering) override;
 
-    virtual void prepareAsync();
+    virtual void prepareAsync(int64_t startTimeUs);
     virtual void start();
     virtual void stop();
 
diff --git a/media/libmediaplayerservice/Android.bp b/media/libmediaplayerservice/Android.bp
index a37973b..6709585 100644
--- a/media/libmediaplayerservice/Android.bp
+++ b/media/libmediaplayerservice/Android.bp
@@ -2,6 +2,7 @@
 
     srcs: [
         "ActivityManager.cpp",
+        "DeathNotifier.cpp",
         "MediaPlayerFactory.cpp",
         "MediaPlayerService.cpp",
         "MediaRecorderClient.cpp",
@@ -11,24 +12,26 @@
     ],
 
     shared_libs: [
+        "android.hardware.media.c2@1.0",
         "android.hardware.media.omx@1.0",
+        "libbase",
         "libaudioclient",
         "libbinder",
         "libcamera_client",
+        "libcodec2_client",
         "libcrypto",
         "libcutils",
         "libdl",
         "libgui",
         "libhidlbase",
-        "libhidlmemory",
         "liblog",
         "libmedia",
         "libmedia_omx",
-        "libmediaextractor",
         "libmediadrm",
         "libmediametrics",
         "libmediautils",
         "libmemunreachable",
+        "libnetd_client",
         "libpowermanager",
         "libstagefright",
         "libstagefright_foundation",
@@ -63,16 +66,9 @@
 
     name: "libmediaplayerservice",
 
-    compile_multilib: "32",
-
     sanitize: {
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
 }
 
-subdirs = ["*"]
-
diff --git a/media/libmediaplayerservice/DeathNotifier.cpp b/media/libmediaplayerservice/DeathNotifier.cpp
new file mode 100644
index 0000000..d13bdf5
--- /dev/null
+++ b/media/libmediaplayerservice/DeathNotifier.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "MediaPlayerService-DeathNotifier"
+#include <android-base/logging.h>
+
+#include "DeathNotifier.h"
+
+namespace android {
+
+class DeathNotifier::DeathRecipient :
+        public IBinder::DeathRecipient,
+        public hardware::hidl_death_recipient {
+public:
+    using Notify = DeathNotifier::Notify;
+
+    DeathRecipient(Notify const& notify): mNotify{notify} {
+    }
+
+    virtual void binderDied(wp<IBinder> const&) override {
+        mNotify();
+    }
+
+    virtual void serviceDied(uint64_t, wp<HBase> const&) override {
+        mNotify();
+    }
+
+private:
+    Notify mNotify;
+};
+
+DeathNotifier::DeathNotifier(sp<IBinder> const& service, Notify const& notify)
+      : mService{std::in_place_index<1>, service},
+        mDeathRecipient{new DeathRecipient(notify)} {
+    service->linkToDeath(mDeathRecipient);
+}
+
+DeathNotifier::DeathNotifier(sp<HBase> const& service, Notify const& notify)
+      : mService{std::in_place_index<2>, service},
+        mDeathRecipient{new DeathRecipient(notify)} {
+    service->linkToDeath(mDeathRecipient, 0);
+}
+
+DeathNotifier::DeathNotifier(DeathNotifier&& other)
+      : mService{other.mService}, mDeathRecipient{other.mDeathRecipient} {
+    other.mService.emplace<0>();
+    other.mDeathRecipient = nullptr;
+}
+
+DeathNotifier::~DeathNotifier() {
+    switch (mService.index()) {
+    case 0:
+        break;
+    case 1:
+        std::get<1>(mService)->unlinkToDeath(mDeathRecipient);
+        break;
+    case 2:
+        std::get<2>(mService)->unlinkToDeath(mDeathRecipient);
+        break;
+    default:
+        CHECK(false) << "Corrupted service type during destruction.";
+    }
+}
+
+} // namespace android
+
diff --git a/media/libmediaplayerservice/DeathNotifier.h b/media/libmediaplayerservice/DeathNotifier.h
new file mode 100644
index 0000000..7bc2611
--- /dev/null
+++ b/media/libmediaplayerservice/DeathNotifier.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_MEDIASERVICE_DEATHNOTIFIER_H
+#define ANDROID_MEDIASERVICE_DEATHNOTIFIER_H
+
+#include <android/hidl/base/1.0/IBase.h>
+#include <binder/Binder.h>
+#include <hidl/HidlSupport.h>
+
+#include <variant>
+
+namespace android {
+
+class DeathNotifier {
+public:
+    using HBase = hidl::base::V1_0::IBase;
+    using Notify = std::function<void()>;
+
+    DeathNotifier(sp<IBinder> const& service, Notify const& notify);
+    DeathNotifier(sp<HBase> const& service, Notify const& notify);
+    DeathNotifier(DeathNotifier&& other);
+    ~DeathNotifier();
+
+private:
+    std::variant<std::monostate, sp<IBinder>, sp<HBase>> mService;
+
+    class DeathRecipient;
+    sp<DeathRecipient> mDeathRecipient;
+};
+
+} // namespace android
+
+#endif // ANDROID_MEDIASERVICE_DEATHNOTIFIER_H
+
diff --git a/media/libmediaplayerservice/DeathRecipient.h b/media/libmediaplayerservice/DeathRecipient.h
new file mode 100644
index 0000000..bf5ae5c
--- /dev/null
+++ b/media/libmediaplayerservice/DeathRecipient.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_MEDIASERVICE_DEATHRECIPIENT_H
+#define ANDROID_MEDIASERVICE_DEATHRECIPIENT_H
+
+#include <binder/binder.h>
+#include <hidl/HidlSupport.h>
+
+#include <variant>
+
+class DeathNotifier :
+        public IBinder::DeathRecipient,
+        public ::android::hardware::hidl_death_recipient {
+public:
+    using Service = std::variant<
+            sp<IBinder> const&,
+            sp<android::hidl::base::V1_0::IBase> const&>;
+
+    DeathNotifier(std::variant<sp<IBinder> const&, 
+            const sp<IBinder>& service,
+            const sp<MediaPlayerBase>& listener,
+            int which,
+            const std::string& name);
+    DeathNotifier(
+            const sp<android::hidl::base::V1_0::IBase>& hService,
+            const sp<MediaPlayerBase>& listener,
+            int which,
+            const std::string& name);
+    virtual ~DeathNotifier() = default;
+    virtual void binderDied(const wp<IBinder>& who);
+    virtual void serviceDied(
+            uint64_t cookie,
+            const wp<::android::hidl::base::V1_0::IBase>& who);
+    void unlinkToDeath();
+
+private:
+    sp<IBinder> mService;
+    sp<android::hidl::base::V1_0::IBase> mHService; // HIDL service
+    wp<MediaPlayerBase> mListener;
+    int mWhich;
+    std::string mName;
+};
+
+#endif // ANDROID_MEDIASERVICE_DEATHRECIPIENT_H
+
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 9bcfc83..dfd3933 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -34,6 +34,8 @@
 
 #include <utils/misc.h>
 
+#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <android/hardware/media/c2/1.0/IComponentStore.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 #include <binder/MemoryHeapBase.h>
@@ -45,7 +47,7 @@
 #include <utils/Timers.h>
 #include <utils/Vector.h>
 
-#include <media/AudioPolicyHelper.h>
+#include <codec2/hidl/client.h>
 #include <media/IMediaHTTPService.h>
 #include <media/IRemoteDisplay.h>
 #include <media/IRemoteDisplayClient.h>
@@ -590,7 +592,6 @@
     if (mAudioAttributes != NULL) {
         free(mAudioAttributes);
     }
-    clearDeathNotifiers_l();
     mAudioDeviceUpdatedListener.clear();
 }
 
@@ -646,59 +647,6 @@
     return p;
 }
 
-MediaPlayerService::Client::ServiceDeathNotifier::ServiceDeathNotifier(
-        const sp<IBinder>& service,
-        const sp<MediaPlayerBase>& listener,
-        int which) {
-    mService = service;
-    mOmx = nullptr;
-    mListener = listener;
-    mWhich = which;
-}
-
-MediaPlayerService::Client::ServiceDeathNotifier::ServiceDeathNotifier(
-        const sp<IOmx>& omx,
-        const sp<MediaPlayerBase>& listener,
-        int which) {
-    mService = nullptr;
-    mOmx = omx;
-    mListener = listener;
-    mWhich = which;
-}
-
-MediaPlayerService::Client::ServiceDeathNotifier::~ServiceDeathNotifier() {
-}
-
-void MediaPlayerService::Client::ServiceDeathNotifier::binderDied(const wp<IBinder>& /*who*/) {
-    sp<MediaPlayerBase> listener = mListener.promote();
-    if (listener != NULL) {
-        listener->sendEvent(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, mWhich);
-    } else {
-        ALOGW("listener for process %d death is gone", mWhich);
-    }
-}
-
-void MediaPlayerService::Client::ServiceDeathNotifier::serviceDied(
-        uint64_t /* cookie */,
-        const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
-    sp<MediaPlayerBase> listener = mListener.promote();
-    if (listener != NULL) {
-        listener->sendEvent(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, mWhich);
-    } else {
-        ALOGW("listener for process %d death is gone", mWhich);
-    }
-}
-
-void MediaPlayerService::Client::ServiceDeathNotifier::unlinkToDeath() {
-    if (mService != nullptr) {
-        mService->unlinkToDeath(this);
-        mService = nullptr;
-    } else if (mOmx != nullptr) {
-        mOmx->unlinkToDeath(this);
-        mOmx = nullptr;
-    }
-}
-
 void MediaPlayerService::Client::AudioDeviceUpdatedNotifier::onAudioDeviceUpdate(
         audio_io_handle_t audioIo,
         audio_port_handle_t deviceId) {
@@ -710,17 +658,6 @@
     }
 }
 
-void MediaPlayerService::Client::clearDeathNotifiers_l() {
-    if (mExtractorDeathListener != nullptr) {
-        mExtractorDeathListener->unlinkToDeath();
-        mExtractorDeathListener = nullptr;
-    }
-    if (mCodecDeathListener != nullptr) {
-        mCodecDeathListener->unlinkToDeath();
-        mCodecDeathListener = nullptr;
-    }
-}
-
 sp<MediaPlayerBase> MediaPlayerService::Client::setDataSource_pre(
         player_type playerType)
 {
@@ -732,30 +669,83 @@
         return p;
     }
 
+    std::vector<DeathNotifier> deathNotifiers;
+
+    // Listen to death of media.extractor service
     sp<IServiceManager> sm = defaultServiceManager();
     sp<IBinder> binder = sm->getService(String16("media.extractor"));
     if (binder == NULL) {
         ALOGE("extractor service not available");
         return NULL;
     }
-    sp<ServiceDeathNotifier> extractorDeathListener =
-            new ServiceDeathNotifier(binder, p, MEDIAEXTRACTOR_PROCESS_DEATH);
-    binder->linkToDeath(extractorDeathListener);
+    deathNotifiers.emplace_back(
+            binder, [l = wp<MediaPlayerBase>(p)]() {
+        sp<MediaPlayerBase> listener = l.promote();
+        if (listener) {
+            ALOGI("media.extractor died. Sending death notification.");
+            listener->sendEvent(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
+                                MEDIAEXTRACTOR_PROCESS_DEATH);
+        } else {
+            ALOGW("media.extractor died without a death handler.");
+        }
+    });
 
-    sp<IOmx> omx = IOmx::getService();
-    if (omx == nullptr) {
-        ALOGE("IOmx service is not available");
-        return NULL;
+    {
+        using ::android::hidl::base::V1_0::IBase;
+
+        // Listen to death of OMX service
+        {
+            sp<IBase> base = ::android::hardware::media::omx::V1_0::
+                    IOmx::getService();
+            if (base == nullptr) {
+                ALOGD("OMX service is not available");
+            } else {
+                deathNotifiers.emplace_back(
+                        base, [l = wp<MediaPlayerBase>(p)]() {
+                    sp<MediaPlayerBase> listener = l.promote();
+                    if (listener) {
+                        ALOGI("OMX service died. "
+                              "Sending death notification.");
+                        listener->sendEvent(
+                                MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
+                                MEDIACODEC_PROCESS_DEATH);
+                    } else {
+                        ALOGW("OMX service died without a death handler.");
+                    }
+                });
+            }
+        }
+
+        // Listen to death of Codec2 services
+        {
+            for (std::shared_ptr<Codec2Client> const& client :
+                    Codec2Client::CreateFromAllServices()) {
+                sp<IBase> base = client->getBase();
+                deathNotifiers.emplace_back(
+                        base, [l = wp<MediaPlayerBase>(p),
+                               name = std::string(client->getServiceName())]() {
+                    sp<MediaPlayerBase> listener = l.promote();
+                    if (listener) {
+                        ALOGI("Codec2 service \"%s\" died. "
+                              "Sending death notification.",
+                              name.c_str());
+                        listener->sendEvent(
+                                MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
+                                MEDIACODEC_PROCESS_DEATH);
+                    } else {
+                        ALOGW("Codec2 service \"%s\" died "
+                              "without a death handler.",
+                              name.c_str());
+                    }
+                });
+            }
+        }
     }
-    sp<ServiceDeathNotifier> codecDeathListener =
-            new ServiceDeathNotifier(omx, p, MEDIACODEC_PROCESS_DEATH);
-    omx->linkToDeath(codecDeathListener, 0);
 
     Mutex::Autolock lock(mLock);
 
-    clearDeathNotifiers_l();
-    mExtractorDeathListener = extractorDeathListener;
-    mCodecDeathListener = codecDeathListener;
+    mDeathNotifiers.clear();
+    mDeathNotifiers.swap(deathNotifiers);
     mAudioDeviceUpdatedListener = new AudioDeviceUpdatedNotifier(p);
 
     if (!p->hardwareOutput()) {
@@ -1627,7 +1617,7 @@
         mAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
         if (mAttributes != NULL) {
             memcpy(mAttributes, attr, sizeof(audio_attributes_t));
-            mStreamType = audio_attributes_to_stream_type(attr);
+            mStreamType = AudioSystem::attributesToStreamType(*attr);
         }
     } else {
         mAttributes = NULL;
@@ -1816,7 +1806,7 @@
             mAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
         }
         memcpy(mAttributes, attributes, sizeof(audio_attributes_t));
-        mStreamType = audio_attributes_to_stream_type(attributes);
+        mStreamType = AudioSystem::attributesToStreamType(*attributes);
     }
 }
 
@@ -1906,10 +1896,16 @@
         if (AudioSystem::getOutputSamplingRate(&afSampleRate, mStreamType) != NO_ERROR) {
             return NO_INIT;
         }
+        if (afSampleRate == 0) {
+            return NO_INIT;
+        }
         const size_t framesPerBuffer =
                 (unsigned long long)sampleRate * afFrameCount / afSampleRate;
 
         if (bufferCount == 0) {
+            if (framesPerBuffer == 0) {
+                return NO_INIT;
+            }
             // use suggestedFrameCount
             bufferCount = (suggestedFrameCount + framesPerBuffer - 1) / framesPerBuffer;
         }
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index bfb7cc2..49688ce 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -30,8 +30,6 @@
 #include <media/Metadata.h>
 #include <media/stagefright/foundation/ABase.h>
 
-#include <android/hardware/media/omx/1.0/IOmx.h>
-
 #include <system/audio.h>
 
 namespace android {
@@ -39,10 +37,10 @@
 struct AudioPlaybackRate;
 class AudioTrack;
 struct AVSyncSettings;
+class DeathNotifier;
 class IDataSource;
 class IMediaRecorder;
 class IMediaMetadataRetriever;
-class IOMX;
 class IRemoteDisplay;
 class IRemoteDisplayClient;
 class MediaRecorderClient;
@@ -70,7 +68,6 @@
 class MediaPlayerService : public BnMediaPlayerService
 {
     class Client;
-    typedef ::android::hardware::media::omx::V1_0::IOmx IOmx;
 
     class AudioOutput : public MediaPlayerBase::AudioSink
     {
@@ -390,33 +387,6 @@
         virtual status_t enableAudioDeviceCallback(bool enabled);
 
     private:
-        class ServiceDeathNotifier:
-                public IBinder::DeathRecipient,
-                public ::android::hardware::hidl_death_recipient
-        {
-        public:
-            ServiceDeathNotifier(
-                    const sp<IBinder>& service,
-                    const sp<MediaPlayerBase>& listener,
-                    int which);
-            ServiceDeathNotifier(
-                    const sp<IOmx>& omx,
-                    const sp<MediaPlayerBase>& listener,
-                    int which);
-            virtual ~ServiceDeathNotifier();
-            virtual void binderDied(const wp<IBinder>& who);
-            virtual void serviceDied(
-                    uint64_t cookie,
-                    const wp<::android::hidl::base::V1_0::IBase>& who);
-            void unlinkToDeath();
-
-        private:
-            int mWhich;
-            sp<IBinder> mService;
-            sp<IOmx> mOmx;
-            wp<MediaPlayerBase> mListener;
-        };
-
         class AudioDeviceUpdatedNotifier: public AudioSystem::AudioDeviceCallback
         {
         public:
@@ -432,8 +402,6 @@
             wp<MediaPlayerBase> mListener;
         };
 
-        void clearDeathNotifiers_l();
-
         friend class MediaPlayerService;
                                 Client( const sp<MediaPlayerService>& service,
                                         pid_t pid,
@@ -508,8 +476,7 @@
         // getMetadata clears this set.
         media::Metadata::Filter mMetadataUpdated;  // protected by mLock
 
-        sp<ServiceDeathNotifier> mExtractorDeathListener;
-        sp<ServiceDeathNotifier> mCodecDeathListener;
+        std::vector<DeathNotifier> mDeathNotifiers;
         sp<AudioDeviceUpdatedNotifier> mAudioDeviceUpdatedListener;
 #if CALLBACK_ANTAGONIZER
                     Antagonizer*                  mAntagonizer;
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index 4206647..703da4b 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -18,27 +18,28 @@
 #define LOG_TAG "MediaRecorderService"
 #include <utils/Log.h>
 
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <string.h>
-#include <cutils/atomic.h>
-#include <cutils/properties.h> // for property_get
+#include "MediaRecorderClient.h"
+#include "MediaPlayerService.h"
+#include "StagefrightRecorder.h"
+
+#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <android/hardware/media/c2/1.0/IComponentStore.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 #include <binder/MemoryHeapBase.h>
 #include <binder/MemoryBase.h>
-
+#include <codec2/hidl/client.h>
+#include <cutils/atomic.h>
+#include <cutils/properties.h> // for property_get
+#include <gui/IGraphicBufferProducer.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <system/audio.h>
 #include <utils/String16.h>
 
-#include <system/audio.h>
-
-#include "MediaRecorderClient.h"
-#include "MediaPlayerService.h"
-
-#include "StagefrightRecorder.h"
-#include <gui/IGraphicBufferProducer.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <string.h>
 
 namespace android {
 
@@ -339,7 +340,7 @@
         wp<MediaRecorderClient> client(this);
         mMediaPlayerService->removeMediaRecorderClient(client);
     }
-    clearDeathNotifiers_l();
+    mDeathNotifiers.clear();
     return NO_ERROR;
 }
 
@@ -358,59 +359,6 @@
     release();
 }
 
-MediaRecorderClient::ServiceDeathNotifier::ServiceDeathNotifier(
-        const sp<IBinder>& service,
-        const sp<IMediaRecorderClient>& listener,
-        int which) {
-    mService = service;
-    mOmx = nullptr;
-    mListener = listener;
-    mWhich = which;
-}
-
-MediaRecorderClient::ServiceDeathNotifier::ServiceDeathNotifier(
-        const sp<IOmx>& omx,
-        const sp<IMediaRecorderClient>& listener,
-        int which) {
-    mService = nullptr;
-    mOmx = omx;
-    mListener = listener;
-    mWhich = which;
-}
-
-MediaRecorderClient::ServiceDeathNotifier::~ServiceDeathNotifier() {
-}
-
-void MediaRecorderClient::ServiceDeathNotifier::binderDied(const wp<IBinder>& /*who*/) {
-    sp<IMediaRecorderClient> listener = mListener.promote();
-    if (listener != NULL) {
-        listener->notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, mWhich);
-    } else {
-        ALOGW("listener for process %d death is gone", mWhich);
-    }
-}
-
-void MediaRecorderClient::ServiceDeathNotifier::serviceDied(
-        uint64_t /* cookie */,
-        const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
-    sp<IMediaRecorderClient> listener = mListener.promote();
-    if (listener != NULL) {
-        listener->notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, mWhich);
-    } else {
-        ALOGW("listener for process %d death is gone", mWhich);
-    }
-}
-
-void MediaRecorderClient::ServiceDeathNotifier::unlinkToDeath() {
-    if (mService != nullptr) {
-        mService->unlinkToDeath(this);
-        mService = nullptr;
-    } else if (mOmx != nullptr) {
-        mOmx->unlinkToDeath(this);
-        mOmx = nullptr;
-    }
-}
-
 MediaRecorderClient::AudioDeviceUpdatedNotifier::AudioDeviceUpdatedNotifier(
         const sp<IMediaRecorderClient>& listener) {
     mListener = listener;
@@ -430,22 +378,11 @@
     }
 }
 
-void MediaRecorderClient::clearDeathNotifiers_l() {
-    if (mCameraDeathListener != nullptr) {
-        mCameraDeathListener->unlinkToDeath();
-        mCameraDeathListener = nullptr;
-    }
-    if (mCodecDeathListener != nullptr) {
-        mCodecDeathListener->unlinkToDeath();
-        mCodecDeathListener = nullptr;
-    }
-}
-
 status_t MediaRecorderClient::setListener(const sp<IMediaRecorderClient>& listener)
 {
     ALOGV("setListener");
     Mutex::Autolock lock(mLock);
-    clearDeathNotifiers_l();
+    mDeathNotifiers.clear();
     if (mRecorder == NULL) {
         ALOGE("recorder is not initialized");
         return NO_INIT;
@@ -463,20 +400,73 @@
     // If the device does not have a camera, do not create a death listener for it.
     if (binder != NULL) {
         sCameraVerified = true;
-        mCameraDeathListener = new ServiceDeathNotifier(binder, listener,
-                MediaPlayerService::CAMERA_PROCESS_DEATH);
-        binder->linkToDeath(mCameraDeathListener);
+        mDeathNotifiers.emplace_back(
+                binder, [l = wp<IMediaRecorderClient>(listener)](){
+            sp<IMediaRecorderClient> listener = l.promote();
+            if (listener) {
+                ALOGV("media.camera service died. "
+                      "Sending death notification.");
+                listener->notify(
+                        MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
+                        MediaPlayerService::CAMERA_PROCESS_DEATH);
+            } else {
+                ALOGW("media.camera service died without a death handler.");
+            }
+        });
     }
     sCameraChecked = true;
 
-    sp<IOmx> omx = IOmx::getService();
-    if (omx == nullptr) {
-        ALOGE("IOmx service is not available");
-        return NO_INIT;
+    {
+        using ::android::hidl::base::V1_0::IBase;
+
+        // Listen to OMX's IOmxStore/default
+        {
+            sp<IBase> base = ::android::hardware::media::omx::V1_0::
+                    IOmx::getService();
+            if (base == nullptr) {
+                ALOGD("OMX service is not available");
+            } else {
+                mDeathNotifiers.emplace_back(
+                        base, [l = wp<IMediaRecorderClient>(listener)](){
+                    sp<IMediaRecorderClient> listener = l.promote();
+                    if (listener) {
+                        ALOGV("OMX service died. "
+                              "Sending death notification.");
+                        listener->notify(
+                                MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
+                                MediaPlayerService::MEDIACODEC_PROCESS_DEATH);
+                    } else {
+                        ALOGW("OMX service died without a death handler.");
+                    }
+                });
+            }
+        }
+
+        // Listen to Codec2's IComponentStore instances
+        {
+            for (std::shared_ptr<Codec2Client> const& client :
+                    Codec2Client::CreateFromAllServices()) {
+                sp<IBase> base = client->getBase();
+                mDeathNotifiers.emplace_back(
+                        base, [l = wp<IMediaRecorderClient>(listener),
+                               name = std::string(client->getServiceName())]() {
+                    sp<IMediaRecorderClient> listener = l.promote();
+                    if (listener) {
+                        ALOGV("Codec2 service \"%s\" died. "
+                              "Sending death notification",
+                              name.c_str());
+                        listener->notify(
+                                MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
+                                MediaPlayerService::MEDIACODEC_PROCESS_DEATH);
+                    } else {
+                        ALOGW("Codec2 service \"%s\" died "
+                              "without a death handler",
+                              name.c_str());
+                    }
+                });
+            }
+        }
     }
-    mCodecDeathListener = new ServiceDeathNotifier(omx, listener,
-            MediaPlayerService::MEDIACODEC_PROCESS_DEATH);
-    omx->linkToDeath(mCodecDeathListener, 0);
 
     mAudioDeviceUpdatedNotifier = new AudioDeviceUpdatedNotifier(listener);
     mRecorder->setAudioDeviceCallback(mAudioDeviceUpdatedNotifier);
@@ -537,4 +527,30 @@
     }
     return NO_INIT;
 }
+
+status_t MediaRecorderClient::setPreferredMicrophoneDirection(
+            audio_microphone_direction_t direction) {
+    ALOGV("setPreferredMicrophoneDirection(%d)", direction);
+    if (mRecorder != NULL) {
+        return mRecorder->setPreferredMicrophoneDirection(direction);
+    }
+    return NO_INIT;
+}
+
+status_t MediaRecorderClient::setPreferredMicrophoneFieldDimension(float zoom) {
+    ALOGV("setPreferredMicrophoneFieldDimension(%f)", zoom);
+    if (mRecorder != NULL) {
+        return mRecorder->setPreferredMicrophoneFieldDimension(zoom);
+    }
+    return NO_INIT;
+}
+
+status_t MediaRecorderClient::getPortId(audio_port_handle_t *portId) {
+    ALOGV("getPortId");
+    Mutex::Autolock lock(mLock);
+    if (mRecorder != NULL) {
+        return mRecorder->getPortId(portId);
+    }
+    return NO_INIT;
+}
 }; // namespace android
diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h
index d2e681f..9e0f877 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.h
+++ b/media/libmediaplayerservice/MediaRecorderClient.h
@@ -18,10 +18,12 @@
 #ifndef ANDROID_MEDIARECORDERCLIENT_H
 #define ANDROID_MEDIARECORDERCLIENT_H
 
+#include "DeathNotifier.h"
+
 #include <media/AudioSystem.h>
 #include <media/IMediaRecorder.h>
 
-#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <vector>
 
 namespace android {
 
@@ -31,34 +33,6 @@
 
 class MediaRecorderClient : public BnMediaRecorder
 {
-    typedef ::android::hardware::media::omx::V1_0::IOmx IOmx;
-
-    class ServiceDeathNotifier :
-            public IBinder::DeathRecipient,
-            public ::android::hardware::hidl_death_recipient
-    {
-    public:
-        ServiceDeathNotifier(
-                const sp<IBinder>& service,
-                const sp<IMediaRecorderClient>& listener,
-                int which);
-        ServiceDeathNotifier(
-                const sp<IOmx>& omx,
-                const sp<IMediaRecorderClient>& listener,
-                int which);
-        virtual ~ServiceDeathNotifier();
-        virtual void binderDied(const wp<IBinder>& who);
-        virtual void serviceDied(
-                uint64_t cookie,
-                const wp<::android::hidl::base::V1_0::IBase>& who);
-        void unlinkToDeath();
-    private:
-        int mWhich;
-        sp<IBinder> mService;
-        sp<IOmx> mOmx;
-        wp<IMediaRecorderClient> mListener;
-    };
-
     class AudioDeviceUpdatedNotifier: public AudioSystem::AudioDeviceCallback
     {
     public:
@@ -71,8 +45,6 @@
         wp<IMediaRecorderClient> mListener;
     };
 
-    void clearDeathNotifiers_l();
-
 public:
     virtual     status_t   setCamera(const sp<hardware::ICamera>& camera,
                                     const sp<ICameraRecordingProxy>& proxy);
@@ -109,6 +81,9 @@
     virtual     status_t   enableAudioDeviceCallback(bool enabled);
     virtual     status_t   getActiveMicrophones(
                               std::vector<media::MicrophoneInfo>* activeMicrophones);
+    virtual     status_t   setPreferredMicrophoneDirection(audio_microphone_direction_t direction);
+    virtual     status_t   setPreferredMicrophoneFieldDimension(float zoom);
+                status_t   getPortId(audio_port_handle_t *portId) override;
 
 private:
     friend class           MediaPlayerService;  // for accessing private constructor
@@ -119,8 +94,7 @@
                                                                const String16& opPackageName);
     virtual                ~MediaRecorderClient();
 
-    sp<ServiceDeathNotifier> mCameraDeathListener;
-    sp<ServiceDeathNotifier> mCodecDeathListener;
+    std::vector<DeathNotifier> mDeathNotifiers;
     sp<AudioDeviceUpdatedNotifier> mAudioDeviceUpdatedNotifier;
 
     pid_t                  mPid;
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 30c0b1c..63681fa 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -24,6 +24,7 @@
 
 #include <algorithm>
 
+#include <android-base/properties.h>
 #include <android/hardware/ICamera.h>
 
 #include <binder/IPCThreadState.h>
@@ -46,6 +47,7 @@
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/MediaCodecSource.h>
+#include <media/stagefright/OggWriter.h>
 #include <media/stagefright/PersistentSurface.h>
 #include <media/MediaProfiles.h>
 #include <camera/CameraParameters.h>
@@ -116,7 +118,9 @@
       mVideoSource(VIDEO_SOURCE_LIST_END),
       mStarted(false),
       mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
-      mDeviceCallbackEnabled(false) {
+      mDeviceCallbackEnabled(false),
+      mSelectedMicDirection(MIC_DIRECTION_UNSPECIFIED),
+      mSelectedMicFieldDimension(MIC_FIELD_DIMENSION_NORMAL) {
 
     ALOGV("Constructor");
 
@@ -160,9 +164,12 @@
     mAnalyticsItem->setInt32(kRecorderVideoIframeInterval, mIFramesIntervalSec);
     // TBD mAudioSourceNode = 0;
     // TBD mUse64BitFileOffset = false;
-    mAnalyticsItem->setInt32(kRecorderMovieTimescale, mMovieTimeScale);
-    mAnalyticsItem->setInt32(kRecorderAudioTimescale, mAudioTimeScale);
-    mAnalyticsItem->setInt32(kRecorderVideoTimescale, mVideoTimeScale);
+    if (mMovieTimeScale != -1)
+        mAnalyticsItem->setInt32(kRecorderMovieTimescale, mMovieTimeScale);
+    if (mAudioTimeScale != -1)
+        mAnalyticsItem->setInt32(kRecorderAudioTimescale, mAudioTimeScale);
+    if (mVideoTimeScale != -1)
+        mAnalyticsItem->setInt32(kRecorderVideoTimescale, mVideoTimeScale);
     // TBD mCameraId        = 0;
     // TBD mStartTimeOffsetMs = -1;
     mAnalyticsItem->setInt32(kRecorderVideoProfile, mVideoEncoderProfile);
@@ -201,7 +208,7 @@
     }
     mAnalyticsDirty = false;
     if (reinitialize) {
-        mAnalyticsItem = new MediaAnalyticsItem(kKeyRecorder);
+        mAnalyticsItem = MediaAnalyticsItem::create(kKeyRecorder);
     }
 }
 
@@ -396,14 +403,15 @@
         return -EBADF;
     }
 
-    // start with a clean, empty file
-    ftruncate(fd, 0);
-    int nextFd = dup(fd);
-    if (mWriter == NULL) {
+    if (mWriter == nullptr) {
         ALOGE("setNextOutputFile failed. Writer has been freed");
         return INVALID_OPERATION;
     }
-    return mWriter->setNextFd(nextFd);
+
+    // start with a clean, empty file
+    ftruncate(fd, 0);
+
+    return mWriter->setNextFd(fd);
 }
 
 // Attempt to parse an float literal optionally surrounded by whitespace,
@@ -948,6 +956,10 @@
             status = setupMPEG2TSRecording();
             break;
 
+        case OUTPUT_FORMAT_OGG:
+            status = setupOggRecording();
+            break;
+
         default:
             ALOGE("Unsupported output file format: %d", mOutputFormat);
             status = UNKNOWN_ERROR;
@@ -1013,6 +1025,7 @@
         case OUTPUT_FORMAT_AAC_ADTS:
         case OUTPUT_FORMAT_RTP_AVP:
         case OUTPUT_FORMAT_MPEG2TS:
+        case OUTPUT_FORMAT_OGG:
         {
             sp<MetaData> meta = new MetaData;
             int64_t startTimeUs = systemTime() / 1000;
@@ -1083,7 +1096,9 @@
                 mSampleRate,
                 mClientUid,
                 mClientPid,
-                mSelectedDeviceId);
+                mSelectedDeviceId,
+                mSelectedMicDirection,
+                mSelectedMicFieldDimension);
 
     status_t err = audioSource->initCheck();
 
@@ -1113,6 +1128,9 @@
             format->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
             format->setInt32("aac-profile", OMX_AUDIO_AACObjectELD);
             break;
+        case AUDIO_ENCODER_OPUS:
+            format->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
+            break;
 
         default:
             ALOGE("Unknown audio encoder: %d", mAudioEncoder);
@@ -1169,6 +1187,13 @@
     return setupRawAudioRecording();
 }
 
+status_t StagefrightRecorder::setupOggRecording() {
+    CHECK_EQ(mOutputFormat, OUTPUT_FORMAT_OGG);
+
+    mWriter = new OggWriter(mOutputFd);
+    return setupRawAudioRecording();
+}
+
 status_t StagefrightRecorder::setupAMRRecording() {
     CHECK(mOutputFormat == OUTPUT_FORMAT_AMR_NB ||
           mOutputFormat == OUTPUT_FORMAT_AMR_WB);
@@ -1745,13 +1770,26 @@
         }
     }
 
+    // Enable temporal layering if the expected (max) playback frame rate is greater than ~11% of
+    // the minimum display refresh rate on a typical device. Add layers until the base layer falls
+    // under this limit. Allow device manufacturers to override this limit.
+
+    // TODO: make this configurable by the application
+    std::string maxBaseLayerFpsProperty =
+        ::android::base::GetProperty("ro.media.recorder-max-base-layer-fps", "");
+    float maxBaseLayerFps = (float)::atof(maxBaseLayerFpsProperty.c_str());
+    // TRICKY: use !> to fix up any NaN values
+    if (!(maxBaseLayerFps >= kMinTypicalDisplayRefreshingRate / 0.9)) {
+        maxBaseLayerFps = kMinTypicalDisplayRefreshingRate / 0.9;
+    }
+
     for (uint32_t tryLayers = 1; tryLayers <= kMaxNumVideoTemporalLayers; ++tryLayers) {
         if (tryLayers > tsLayers) {
             tsLayers = tryLayers;
         }
         // keep going until the base layer fps falls below the typical display refresh rate
         float baseLayerFps = maxPlaybackFps / (1 << (tryLayers - 1));
-        if (baseLayerFps < kMinTypicalDisplayRefreshingRate / 0.9) {
+        if (baseLayerFps < maxBaseLayerFps) {
             break;
         }
     }
@@ -1813,6 +1851,7 @@
         case AUDIO_ENCODER_AAC:
         case AUDIO_ENCODER_HE_AAC:
         case AUDIO_ENCODER_AAC_ELD:
+        case AUDIO_ENCODER_OPUS:
             break;
 
         default:
@@ -1863,19 +1902,18 @@
         mTotalBitRate += mVideoBitRate;
     }
 
-    if (mOutputFormat != OUTPUT_FORMAT_WEBM) {
-        // Audio source is added at the end if it exists.
-        // This help make sure that the "recoding" sound is suppressed for
-        // camcorder applications in the recorded files.
-        // TODO Audio source is currently unsupported for webm output; vorbis encoder needed.
-        // disable audio for time lapse recording
-        bool disableAudio = mCaptureFpsEnable && mCaptureFps < mFrameRate;
-        if (!disableAudio && mAudioSource != AUDIO_SOURCE_CNT) {
-            err = setupAudioEncoder(writer);
-            if (err != OK) return err;
-            mTotalBitRate += mAudioBitRate;
-        }
+    // Audio source is added at the end if it exists.
+    // This help make sure that the "recoding" sound is suppressed for
+    // camcorder applications in the recorded files.
+    // disable audio for time lapse recording
+    const bool disableAudio = mCaptureFpsEnable && mCaptureFps < mFrameRate;
+    if (!disableAudio && mAudioSource != AUDIO_SOURCE_CNT) {
+        err = setupAudioEncoder(writer);
+        if (err != OK) return err;
+        mTotalBitRate += mAudioBitRate;
+    }
 
+    if (mOutputFormat != OUTPUT_FORMAT_WEBM) {
         if (mCaptureFpsEnable) {
             mp4writer->setCaptureRate(mCaptureFps);
         }
@@ -1996,7 +2034,7 @@
         mTotalPausedDurationUs += resumeStartTimeUs - mPauseStartTimeUs - 30000;
     }
     double timeOffset = -mTotalPausedDurationUs;
-    if (mCaptureFpsEnable) {
+    if (mCaptureFpsEnable && (mVideoSource == VIDEO_SOURCE_CAMERA)) {
         timeOffset *= mCaptureFps / mFrameRate;
     }
     sp<MetaData> meta = new MetaData;
@@ -2175,7 +2213,7 @@
 }
 
 status_t StagefrightRecorder::getMetrics(Parcel *reply) {
-    ALOGD("StagefrightRecorder::getMetrics");
+    ALOGV("StagefrightRecorder::getMetrics");
 
     if (reply == NULL) {
         ALOGE("Null pointer argument");
@@ -2239,6 +2277,30 @@
     return NO_INIT;
 }
 
+status_t StagefrightRecorder::setPreferredMicrophoneDirection(audio_microphone_direction_t direction) {
+    ALOGV("setPreferredMicrophoneDirection(%d)", direction);
+    mSelectedMicDirection = direction;
+    if (mAudioSourceNode != 0) {
+        return mAudioSourceNode->setPreferredMicrophoneDirection(direction);
+    }
+    return NO_INIT;
+}
+
+status_t StagefrightRecorder::setPreferredMicrophoneFieldDimension(float zoom) {
+    ALOGV("setPreferredMicrophoneFieldDimension(%f)", zoom);
+    mSelectedMicFieldDimension = zoom;
+    if (mAudioSourceNode != 0) {
+        return mAudioSourceNode->setPreferredMicrophoneFieldDimension(zoom);
+    }
+    return NO_INIT;
+}
+
+status_t StagefrightRecorder::getPortId(audio_port_handle_t *portId) const {
+    if (mAudioSourceNode != 0) {
+        return mAudioSourceNode->getPortId(portId);
+    }
+    return NO_INIT;
+}
 
 status_t StagefrightRecorder::dump(
         int fd, const Vector<String16>& args) const {
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index faa2e59..8bf083a 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -77,7 +77,9 @@
     virtual void setAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback);
     virtual status_t enableAudioDeviceCallback(bool enabled);
     virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones);
-
+    virtual status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction);
+    virtual status_t setPreferredMicrophoneFieldDimension(float zoom);
+            status_t getPortId(audio_port_handle_t *portId) const override;
 
 private:
     mutable Mutex mLock;
@@ -159,6 +161,9 @@
     bool mDeviceCallbackEnabled;
     wp<AudioSystem::AudioDeviceCallback> mAudioDeviceCallback;
 
+    audio_microphone_direction_t mSelectedMicDirection;
+    float mSelectedMicFieldDimension;
+
     static const int kMaxHighSpeedFps = 1000;
 
     status_t prepareInternal();
@@ -166,6 +171,7 @@
     void setupMPEG4orWEBMMetaData(sp<MetaData> *meta);
     status_t setupAMRRecording();
     status_t setupAACRecording();
+    status_t setupOggRecording();
     status_t setupRawAudioRecording();
     status_t setupRTPRecording();
     status_t setupMPEG2TSRecording();
diff --git a/media/libmediaplayerservice/include/MediaPlayerInterface.h b/media/libmediaplayerservice/include/MediaPlayerInterface.h
index 3119950..0ad4d04 100644
--- a/media/libmediaplayerservice/include/MediaPlayerInterface.h
+++ b/media/libmediaplayerservice/include/MediaPlayerInterface.h
@@ -151,13 +151,13 @@
 
         virtual media::VolumeShaper::Status applyVolumeShaper(
                                     const sp<media::VolumeShaper::Configuration>& configuration,
-                                    const sp<media::VolumeShaper::Operation>& operation);
-        virtual sp<media::VolumeShaper::State> getVolumeShaperState(int id);
+                                    const sp<media::VolumeShaper::Operation>& operation) = 0;
+        virtual sp<media::VolumeShaper::State> getVolumeShaperState(int id) = 0;
 
         // AudioRouting
-        virtual status_t    setOutputDevice(audio_port_handle_t deviceId);
-        virtual status_t    getRoutedDeviceId(audio_port_handle_t* deviceId);
-        virtual status_t    enableAudioDeviceCallback(bool enabled);
+        virtual status_t    setOutputDevice(audio_port_handle_t deviceId) = 0;
+        virtual status_t    getRoutedDeviceId(audio_port_handle_t* deviceId) = 0;
+        virtual status_t    enableAudioDeviceCallback(bool enabled) = 0;
     };
 
                         MediaPlayerBase() {}
diff --git a/media/libmediaplayerservice/nuplayer/Android.bp b/media/libmediaplayerservice/nuplayer/Android.bp
index 645bb7a..23a19e7 100644
--- a/media/libmediaplayerservice/nuplayer/Android.bp
+++ b/media/libmediaplayerservice/nuplayer/Android.bp
@@ -54,13 +54,8 @@
 
     name: "libstagefright_nuplayer",
 
-    tags: ["eng"],
-
     sanitize: {
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
 }
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 23d66bb..4653711 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -25,7 +25,6 @@
 #include <cutils/properties.h>
 #include <media/DataSource.h>
 #include <media/MediaBufferHolder.h>
-#include <media/MediaExtractor.h>
 #include <media/MediaSource.h>
 #include <media/IMediaExtractorService.h>
 #include <media/IMediaHTTPService.h>
@@ -38,6 +37,7 @@
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MediaClock.h>
 #include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaExtractor.h>
 #include <media/stagefright/MediaExtractorFactory.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/Utils.h>
@@ -68,7 +68,7 @@
       mVideoDataGeneration(0),
       mFetchSubtitleDataGeneration(0),
       mFetchTimedTextDataGeneration(0),
-      mDurationUs(-1ll),
+      mDurationUs(-1LL),
       mAudioIsVorbis(false),
       mIsSecure(false),
       mIsStreaming(false),
@@ -76,7 +76,7 @@
       mUID(uid),
       mMediaClock(mediaClock),
       mFd(-1),
-      mBitrate(-1ll),
+      mBitrate(-1LL),
       mPendingReadBufferTypes(0) {
     ALOGV("GenericSource");
     CHECK(mediaClock != NULL);
@@ -90,10 +90,14 @@
     ALOGV("resetDataSource");
 
     mHTTPService.clear();
-    mHttpSource.clear();
-    mDisconnected = false;
+    {
+        Mutex::Autolock _l_d(mDisconnectLock);
+        mHttpSource.clear();
+        mDisconnected = false;
+    }
     mUri.clear();
     mUriHeaders.clear();
+    mSources.clear();
     if (mFd >= 0) {
         close(mFd);
         mFd = -1;
@@ -151,7 +155,10 @@
     ALOGV("setDataSource (source: %p)", source.get());
 
     resetDataSource();
-    mDataSource = source;
+    {
+        Mutex::Autolock _l_d(mDisconnectLock);
+        mDataSource = source;
+    }
     return OK;
 }
 
@@ -162,8 +169,12 @@
 
 status_t NuPlayer::GenericSource::initFromDataSource() {
     sp<IMediaExtractor> extractor;
-    CHECK(mDataSource != NULL);
-    sp<DataSource> dataSource = mDataSource;
+    sp<DataSource> dataSource;
+    {
+        Mutex::Autolock _l_d(mDisconnectLock);
+        dataSource = mDataSource;
+    }
+    CHECK(dataSource != NULL);
 
     mLock.unlock();
     // This might take long time if data source is not reliable.
@@ -171,6 +182,7 @@
 
     if (extractor == NULL) {
         ALOGE("initFromDataSource, cannot create extractor!");
+        mLock.lock();
         return UNKNOWN_ERROR;
     }
 
@@ -179,6 +191,7 @@
     size_t numtracks = extractor->countTracks();
     if (numtracks == 0) {
         ALOGE("initFromDataSource, source has no track!");
+        mLock.lock();
         return UNKNOWN_ERROR;
     }
 
@@ -356,6 +369,7 @@
 }
 
 void NuPlayer::GenericSource::onPrepareAsync() {
+    mDisconnectLock.lock();
     ALOGV("onPrepareAsync: mDataSource: %d", (mDataSource != NULL));
 
     // delayed data source creation
@@ -369,19 +383,28 @@
             String8 contentType;
 
             if (!strncasecmp("http://", uri, 7) || !strncasecmp("https://", uri, 8)) {
-                mHttpSource = DataSourceFactory::CreateMediaHTTP(mHTTPService);
-                if (mHttpSource == NULL) {
+                sp<DataSource> httpSource;
+                mDisconnectLock.unlock();
+                httpSource = DataSourceFactory::CreateMediaHTTP(mHTTPService);
+                if (httpSource == NULL) {
                     ALOGE("Failed to create http source!");
                     notifyPreparedAndCleanup(UNKNOWN_ERROR);
                     return;
                 }
+                mDisconnectLock.lock();
+
+                if (!mDisconnected) {
+                    mHttpSource = httpSource;
+                }
             }
 
             mLock.unlock();
+            mDisconnectLock.unlock();
             // This might take long time if connection has some issue.
             sp<DataSource> dataSource = DataSourceFactory::CreateFromURI(
                    mHTTPService, uri, &mUriHeaders, &contentType,
                    static_cast<HTTPBase *>(mHttpSource.get()));
+            mDisconnectLock.lock();
             mLock.lock();
             if (!mDisconnected) {
                 mDataSource = dataSource;
@@ -425,6 +448,7 @@
 
         if (mDataSource == NULL) {
             ALOGE("Failed to create data source!");
+            mDisconnectLock.unlock();
             notifyPreparedAndCleanup(UNKNOWN_ERROR);
             return;
         }
@@ -434,6 +458,8 @@
         mCachedSource = static_cast<NuCachedSource2 *>(mDataSource.get());
     }
 
+    mDisconnectLock.unlock();
+
     // For cached streaming cases, we need to wait for enough
     // buffering before reporting prepared.
     mIsStreaming = (mCachedSource != NULL);
@@ -500,9 +526,13 @@
 
 void NuPlayer::GenericSource::notifyPreparedAndCleanup(status_t err) {
     if (err != OK) {
-        mDataSource.clear();
+        {
+            Mutex::Autolock _l_d(mDisconnectLock);
+            mDataSource.clear();
+            mHttpSource.clear();
+        }
+
         mCachedSource.clear();
-        mHttpSource.clear();
 
         mBitrate = -1;
         mPrevBufferPercentage = -1;
@@ -544,7 +574,7 @@
 void NuPlayer::GenericSource::disconnect() {
     sp<DataSource> dataSource, httpSource;
     {
-        Mutex::Autolock _l(mLock);
+        Mutex::Autolock _l_d(mDisconnectLock);
         dataSource = mDataSource;
         httpSource = mHttpSource;
         mDisconnected = true;
@@ -727,7 +757,7 @@
     }
 
     if (msg->what() == kWhatFetchSubtitleData) {
-        subTimeUs -= 1000000ll;  // send subtile data one second earlier
+        subTimeUs -= 1000000LL;  // send subtile data one second earlier
     }
     sp<AMessage> msg2 = new AMessage(sendWhat, this);
     msg2->setInt32("generation", msgGeneration);
@@ -764,7 +794,7 @@
         notify->post();
 
         if (msg->what() == kWhatSendSubtitleData) {
-            nextSubTimeUs -= 1000000ll;  // send subtile data one second earlier
+            nextSubTimeUs -= 1000000LL;  // send subtile data one second earlier
         }
         mMediaClock->addTimer(msg, nextSubTimeUs);
     }
@@ -855,7 +885,7 @@
         // TODO: maxRebufferingMarkMs could be larger than
         // mBufferingSettings.mResumePlaybackMarkMs
         int64_t restartBufferingMarkUs =
-             mBufferingSettings.mResumePlaybackMarkMs * 1000ll / 2;
+             mBufferingSettings.mResumePlaybackMarkMs * 1000LL / 2;
         if (finalResult == OK) {
             if (durationUs < restartBufferingMarkUs) {
                 postReadBuffer(audio? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO);
@@ -1446,7 +1476,7 @@
         // TODO: maxRebufferingMarkMs could be larger than
         // mBufferingSettings.mResumePlaybackMarkMs
         int64_t markUs = (mPreparing ? mBufferingSettings.mInitialMarkMs
-            : mBufferingSettings.mResumePlaybackMarkMs) * 1000ll;
+            : mBufferingSettings.mResumePlaybackMarkMs) * 1000LL;
         if (finalResult == ERROR_END_OF_STREAM || durationUs >= markUs) {
             if (mPreparing || mSentPauseOnBuffering) {
                 Track *counterTrack =
@@ -1514,12 +1544,12 @@
     sp<AMessage> msg = new AMessage(kWhatPollBuffering, this);
     msg->setInt32("generation", mPollBufferingGeneration);
     // Enquires buffering status every second.
-    msg->post(1000000ll);
+    msg->post(1000000LL);
 }
 
 void NuPlayer::GenericSource::onPollBuffering() {
     status_t finalStatus = UNKNOWN_ERROR;
-    int64_t cachedDurationUs = -1ll;
+    int64_t cachedDurationUs = -1LL;
     ssize_t cachedDataRemaining = -1;
 
     if (mCachedSource != NULL) {
@@ -1527,15 +1557,15 @@
 
         if (finalStatus == OK) {
             off64_t size;
-            int64_t bitrate = 0ll;
+            int64_t bitrate = 0LL;
             if (mDurationUs > 0 && mCachedSource->getSize(&size) == OK) {
                 // |bitrate| uses bits/second unit, while size is number of bytes.
-                bitrate = size * 8000000ll / mDurationUs;
+                bitrate = size * 8000000LL / mDurationUs;
             } else if (mBitrate > 0) {
                 bitrate = mBitrate;
             }
             if (bitrate > 0) {
-                cachedDurationUs = cachedDataRemaining * 8000000ll / bitrate;
+                cachedDurationUs = cachedDataRemaining * 8000000LL / bitrate;
             }
         }
     }
@@ -1547,11 +1577,21 @@
             notifyBufferingUpdate(100);
         }
 
+        if (mPreparing) {
+            notifyPreparedAndCleanup(finalStatus == ERROR_END_OF_STREAM ? OK : finalStatus);
+            mPreparing = false;
+        } else if (mSentPauseOnBuffering) {
+            sendCacheStats();
+            mSentPauseOnBuffering = false;
+            sp<AMessage> notify = dupNotify();
+            notify->setInt32("what", kWhatResumeOnBufferingEnd);
+            notify->post();
+        }
         return;
     }
 
-    if (cachedDurationUs >= 0ll) {
-        if (mDurationUs > 0ll) {
+    if (cachedDurationUs >= 0LL) {
+        if (mDurationUs > 0LL) {
             int64_t cachedPosUs = getLastReadPosition() + cachedDurationUs;
             int percentage = 100.0 * cachedPosUs / mDurationUs;
             if (percentage > 100) {
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h
index 065cac1..4d1905d 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.h
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.h
@@ -170,6 +170,7 @@
     sp<ABuffer> mGlobalTimedText;
 
     mutable Mutex mLock;
+    mutable Mutex mDisconnectLock; // Protects mDataSource, mHttpSource and mDisconnected
 
     sp<ALooper> mLooper;
 
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
index 11f1bfd..77e7885 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
@@ -271,10 +271,10 @@
 
         if (fetchType == LiveSession::STREAMTYPE_SUBTITLES) {
             notify->post();
-            msg->post(delayUs > 0ll ? delayUs : 0ll);
+            msg->post(delayUs > 0LL ? delayUs : 0LL);
             return;
         } else if (fetchType == LiveSession::STREAMTYPE_METADATA) {
-            if (delayUs < -1000000ll) { // 1 second
+            if (delayUs < -1000000LL) { // 1 second
                 continue;
             }
             notify->post();
@@ -286,7 +286,7 @@
     }
 
     // try again in 1 second
-    msg->post(1000000ll);
+    msg->post(1000000LL);
 }
 
 void NuPlayer::HTTPLiveSource::onMessageReceived(const sp<AMessage> &msg) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 0784939..3388097 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -659,20 +659,31 @@
 
         case kWhatGetSelectedTrack:
         {
+            int32_t type32;
+            CHECK(msg->findInt32("type", (int32_t*)&type32));
+            media_track_type type = (media_track_type)type32;
+
+            size_t inbandTracks = 0;
             status_t err = INVALID_OPERATION;
+            ssize_t selectedTrack = -1;
             if (mSource != NULL) {
                 err = OK;
-
-                int32_t type32;
-                CHECK(msg->findInt32("type", (int32_t*)&type32));
-                media_track_type type = (media_track_type)type32;
-                ssize_t selectedTrack = mSource->getSelectedTrack(type);
-
-                Parcel* reply;
-                CHECK(msg->findPointer("reply", (void**)&reply));
-                reply->writeInt32(selectedTrack);
+                inbandTracks = mSource->getTrackCount();
+                selectedTrack = mSource->getSelectedTrack(type);
             }
 
+            if (selectedTrack == -1 && mCCDecoder != NULL) {
+                err = OK;
+                selectedTrack = mCCDecoder->getSelectedTrack(type);
+                if (selectedTrack != -1) {
+                    selectedTrack += inbandTracks;
+                }
+            }
+
+            Parcel* reply;
+            CHECK(msg->findPointer("reply", (void**)&reply));
+            reply->writeInt32(selectedTrack);
+
             sp<AMessage> response = new AMessage;
             response->setInt32("err", err);
 
@@ -750,7 +761,7 @@
                 }
             }
 
-            msg->post(1000000ll);  // poll again in a second.
+            msg->post(1000000LL);  // poll again in a second.
             break;
         }
 
@@ -1038,7 +1049,7 @@
             }
 
             if (rescan) {
-                msg->post(100000ll);
+                msg->post(100000LL);
                 mScanSourcesPending = true;
             }
             break;
@@ -1818,11 +1829,21 @@
     closeAudioSink();
     mRenderer->flush(true /* audio */, false /* notifyComplete */);
     if (mVideoDecoder != NULL) {
-        mRenderer->flush(false /* audio */, false /* notifyComplete */);
+        mDeferredActions.push_back(
+                new FlushDecoderAction(FLUSH_CMD_NONE /* audio */,
+                                       FLUSH_CMD_FLUSH /* video */));
+        mDeferredActions.push_back(
+                new SeekAction(currentPositionUs,
+                MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */));
+        // After a flush without shutdown, decoder is paused.
+        // Don't resume it until source seek is done, otherwise it could
+        // start pulling stale data too soon.
+        mDeferredActions.push_back(new ResumeDecoderAction(false));
+        processDeferredActions();
+    } else {
+        performSeek(currentPositionUs, MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */);
     }
 
-    performSeek(currentPositionUs, MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */);
-
     if (forceNonOffload) {
         mRenderer->signalDisableOffloadAudio();
         mOffloadAudio = false;
@@ -2659,7 +2680,7 @@
             int posMs;
             int64_t timeUs, posUs;
             driver->getCurrentPosition(&posMs);
-            posUs = (int64_t) posMs * 1000ll;
+            posUs = (int64_t) posMs * 1000LL;
             CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
 
             if (posUs < timeUs) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp
index 7b2b6fb..a2cc13e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp
@@ -200,6 +200,18 @@
     return OK;
 }
 
+ssize_t NuPlayer::CCDecoder::getSelectedTrack(media_track_type type) const {
+    if (mSelectedTrack != -1) {
+        CCTrack track = mTracks[mSelectedTrack];
+        if (track.mTrackType == kTrackTypeCEA608 || track.mTrackType == kTrackTypeCEA708) {
+            return (type == MEDIA_TRACK_TYPE_SUBTITLE ? mSelectedTrack : -1);
+        }
+        return (type == MEDIA_TRACK_TYPE_UNKNOWN ? mSelectedTrack : -1);
+    }
+
+    return -1;
+}
+
 bool NuPlayer::CCDecoder::isSelected() const {
     return mSelectedTrack >= 0 && mSelectedTrack < (int32_t)getTrackCount();
 }
@@ -564,7 +576,7 @@
 
         ccBuf->meta()->setInt32("track-index", mSelectedTrack);
         ccBuf->meta()->setInt64("timeUs", timeUs);
-        ccBuf->meta()->setInt64("durationUs", 0ll);
+        ccBuf->meta()->setInt64("durationUs", 0LL);
 
         sp<AMessage> msg = mNotify->dup();
         msg->setInt32("what", kWhatClosedCaptionData);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.h
index f310f37..37b8230 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.h
@@ -38,6 +38,7 @@
     size_t getTrackCount() const;
     sp<AMessage> getTrackInfo(size_t index) const;
     status_t selectTrack(size_t index, bool select);
+    ssize_t getSelectedTrack(media_track_type type) const;
     bool isSelected() const;
     void decode(const sp<ABuffer> &accessUnit);
     void display(int64_t timeUs);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 69cd82e..2f0da2d 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -71,10 +71,10 @@
       mCCDecoder(ccDecoder),
       mPid(pid),
       mUid(uid),
-      mSkipRenderingUntilMediaTimeUs(-1ll),
-      mNumFramesTotal(0ll),
-      mNumInputFramesDropped(0ll),
-      mNumOutputFramesDropped(0ll),
+      mSkipRenderingUntilMediaTimeUs(-1LL),
+      mNumFramesTotal(0LL),
+      mNumInputFramesDropped(0LL),
+      mNumOutputFramesDropped(0LL),
       mVideoWidth(0),
       mVideoHeight(0),
       mIsAudio(true),
@@ -107,10 +107,16 @@
 }
 
 sp<AMessage> NuPlayer::Decoder::getStats() const {
+
     mStats->setInt64("frames-total", mNumFramesTotal);
     mStats->setInt64("frames-dropped-input", mNumInputFramesDropped);
     mStats->setInt64("frames-dropped-output", mNumOutputFramesDropped);
-    return mStats;
+    mStats->setFloat("frame-rate-total", mFrameRateTotal);
+
+    // i'm mutexed right now.
+    // make our own copy, so we aren't victim to any later changes.
+    sp<AMessage> copiedStats = mStats->dup();
+    return copiedStats;
 }
 
 status_t NuPlayer::Decoder::setVideoSurface(const sp<Surface> &surface) {
@@ -408,10 +414,10 @@
         // TODO: For now, layer fps is calculated for some specific architectures.
         // But it really should be extracted from the stream.
         mVideoTemporalLayerAggregateFps[0] =
-            mFrameRateTotal / (float)(1ll << (mNumVideoTemporalLayerTotal - 1));
+            mFrameRateTotal / (float)(1LL << (mNumVideoTemporalLayerTotal - 1));
         for (int32_t i = 1; i < mNumVideoTemporalLayerTotal; ++i) {
             mVideoTemporalLayerAggregateFps[i] =
-                mFrameRateTotal / (float)(1ll << (mNumVideoTemporalLayerTotal - i))
+                mFrameRateTotal / (float)(1LL << (mNumVideoTemporalLayerTotal - i))
                 + mVideoTemporalLayerAggregateFps[i - 1];
         }
     }
@@ -677,7 +683,7 @@
         msg->setSize("buffer-ix", index);
 
         sp<ABuffer> buffer = mCSDsToSubmit.itemAt(0);
-        ALOGI("[%s] resubmitting CSD", mComponentName.c_str());
+        ALOGV("[%s] resubmitting CSD", mComponentName.c_str());
         msg->setBuffer("buffer", buffer);
         mCSDsToSubmit.removeAt(0);
         if (!onInputBufferFetched(msg)) {
@@ -748,7 +754,7 @@
     reply->setSize("size", size);
 
     if (eos) {
-        ALOGI("[%s] saw output EOS", mIsAudio ? "audio" : "video");
+        ALOGV("[%s] saw output EOS", mIsAudio ? "audio" : "video");
 
         buffer->meta()->setInt32("eos", true);
         reply->setInt32("eos", true);
@@ -933,7 +939,7 @@
 
             int32_t layerId = 0;
             bool haveLayerId = accessUnit->meta()->findInt32("temporal-layer-id", &layerId);
-            if (mRenderer->getVideoLateByUs() > 100000ll
+            if (mRenderer->getVideoLateByUs() > 100000LL
                     && mIsVideoAVC
                     && !IsAVCReferenceFrame(accessUnit)) {
                 dropAccessUnit = true;
@@ -1028,7 +1034,7 @@
             int64_t resumeAtMediaTimeUs;
             if (extra->findInt64(
                         "resume-at-mediaTimeUs", &resumeAtMediaTimeUs)) {
-                ALOGI("[%s] suppressing rendering until %lld us",
+                ALOGV("[%s] suppressing rendering until %lld us",
                         mComponentName.c_str(), (long long)resumeAtMediaTimeUs);
                 mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs;
             }
@@ -1069,6 +1075,12 @@
                         static_cast<MediaBufferHolder*>(holder.get())->mediaBuffer() : nullptr;
                 }
                 if (mediaBuf != NULL) {
+                    if (mediaBuf->size() > codecBuffer->capacity()) {
+                        handleError(ERROR_BUFFER_TOO_SMALL);
+                        mDequeuedInputBuffers.push_back(bufferIx);
+                        return false;
+                    }
+
                     codecBuffer->setRange(0, mediaBuf->size());
                     memcpy(codecBuffer->data(), mediaBuf->data(), mediaBuf->size());
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp
index d0de7b0..3e96d27 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp
@@ -120,7 +120,7 @@
         mRequestInputBuffersPending = true;
 
         sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, this);
-        msg->post(10 * 1000ll);
+        msg->post(10 * 1000LL);
     }
 }
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
index 6b05b53..0997e7d 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
@@ -47,7 +47,7 @@
     : DecoderBase(notify),
       mSource(source),
       mRenderer(renderer),
-      mSkipRenderingUntilMediaTimeUs(-1ll),
+      mSkipRenderingUntilMediaTimeUs(-1LL),
       mReachedEOS(true),
       mPendingAudioErr(OK),
       mPendingBuffersToDrain(0),
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index fc8d2ca..000881b 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -17,6 +17,7 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "NuPlayerDriver"
 #include <inttypes.h>
+#include <android-base/macros.h>
 #include <utils/Log.h>
 #include <cutils/properties.h>
 
@@ -52,6 +53,7 @@
 static const char *kPlayerHeight = "android.media.mediaplayer.height";
 static const char *kPlayerFrames = "android.media.mediaplayer.frames";
 static const char *kPlayerFramesDropped = "android.media.mediaplayer.dropped";
+static const char *kPlayerFrameRate = "android.media.mediaplayer.fps";
 static const char *kPlayerAMime = "android.media.mediaplayer.audio.mime";
 static const char *kPlayerACodec = "android.media.mediaplayer.audio.codec";
 static const char *kPlayerDuration = "android.media.mediaplayer.durationMs";
@@ -95,7 +97,7 @@
     mMediaClock->init();
 
     // set up an analytics record
-    mAnalyticsItem = new MediaAnalyticsItem(kKeyPlayer);
+    mAnalyticsItem = MediaAnalyticsItem::create(kKeyPlayer);
 
     mLooper->start(
             false, /* runOnCallingThread */
@@ -330,7 +332,7 @@
 }
 
 status_t NuPlayerDriver::start() {
-    ALOGD("start(%p), state is %d, eos is %d", this, mState, mAtEOS);
+    ALOGV("start(%p), state is %d, eos is %d", this, mState, mAtEOS);
     Mutex::Autolock autoLock(mLock);
     return start_l();
 }
@@ -347,7 +349,7 @@
 
             CHECK_EQ(mState, STATE_PREPARED);
 
-            // fall through
+            FALLTHROUGH_INTENDED;
         }
 
         case STATE_PAUSED:
@@ -356,7 +358,7 @@
         {
             mPlayer->start();
 
-            // fall through
+            FALLTHROUGH_INTENDED;
         }
 
         case STATE_RUNNING:
@@ -385,7 +387,7 @@
     switch (mState) {
         case STATE_RUNNING:
             mPlayer->pause();
-            // fall through
+            FALLTHROUGH_INTENDED;
 
         case STATE_PAUSED:
             mState = STATE_STOPPED;
@@ -472,10 +474,10 @@
 }
 
 status_t NuPlayerDriver::seekTo(int msec, MediaPlayerSeekMode mode) {
-    ALOGD("seekTo(%p) (%d ms, %d) at state %d", this, msec, mode, mState);
+    ALOGV("seekTo(%p) (%d ms, %d) at state %d", this, msec, mode, mState);
     Mutex::Autolock autoLock(mLock);
 
-    int64_t seekTimeUs = msec * 1000ll;
+    int64_t seekTimeUs = msec * 1000LL;
 
     switch (mState) {
         case STATE_PREPARED:
@@ -532,7 +534,7 @@
         return UNKNOWN_ERROR;
     }
 
-    *msec = (mDurationUs + 500ll) / 1000;
+    *msec = (mDurationUs + 500LL) / 1000;
 
     return OK;
 }
@@ -569,19 +571,18 @@
 
     // finish the rest of the gathering holding mLock;
     // some of the fields we read are updated under mLock.
-    // we also avoid any races within mMetricsItem machinery
+    // we also avoid any races within mAnalyticsItem machinery
     Mutex::Autolock autoLock(mMetricsLock);
 
     mAnalyticsItem->setInt64(kPlayerDuration, duration_ms);
 
-    // these update under mLock, we'll read them under mLock
     mAnalyticsItem->setInt64(kPlayerPlaying, (playingTimeUs+500)/1000 );
 
-    if (rebufferingEvents != 0) {
+    if (mRebufferingEvents != 0) {
         mAnalyticsItem->setInt64(kPlayerRebuffering, (rebufferingTimeUs+500)/1000 );
         mAnalyticsItem->setInt32(kPlayerRebufferingCount, rebufferingEvents);
         mAnalyticsItem->setInt32(kPlayerRebufferingAtExit, rebufferingAtExit);
-    }
+     }
 
     mAnalyticsItem->setCString(kPlayerDataSourceType, mPlayer->getDataSourceType());
 
@@ -616,6 +617,10 @@
                 mAnalyticsItem->setInt64(kPlayerFrames, numFramesTotal);
                 mAnalyticsItem->setInt64(kPlayerFramesDropped, numFramesDropped);
 
+                float frameRate = 0;
+                if (stats->findFloat("frame-rate-total", &frameRate)) {
+                    mAnalyticsItem->setDouble(kPlayerFrameRate, (double) frameRate);
+                }
 
             } else if (mime.startsWith("audio/")) {
                 mAnalyticsItem->setCString(kPlayerAMime, mime.c_str());
@@ -625,7 +630,6 @@
             }
         }
     }
-
 }
 
 
@@ -653,7 +657,7 @@
 
         // re-init in case we prepare() and start() again.
         delete mAnalyticsItem ;
-        mAnalyticsItem = new MediaAnalyticsItem("nuplayer");
+        mAnalyticsItem = MediaAnalyticsItem::create(kKeyPlayer);
         if (mAnalyticsItem) {
             mAnalyticsItem->setUid(mClientUid);
         }
@@ -762,7 +766,7 @@
             int msec = 0;
             // getCurrentPosition should always return OK
             getCurrentPosition(&msec);
-            return mPlayer->selectTrack(trackIndex, true /* select */, msec * 1000ll);
+            return mPlayer->selectTrack(trackIndex, true /* select */, msec * 1000LL);
         }
 
         case INVOKE_ID_UNSELECT_TRACK:
@@ -801,9 +805,11 @@
         // gather current info all together, parcel it, and send it back
         updateMetrics("api");
 
-        // make sure that the stats are static while we're writing to the parcel
+        // ensure mAnalyticsItem stability while writing to parcel
         Mutex::Autolock autoLock(mMetricsLock);
-        mAnalyticsItem->writeToParcel(reply);
+        if (mAnalyticsItem != NULL) {
+            mAnalyticsItem->writeToParcel(reply);
+        }
         return OK;
     }
 
@@ -986,7 +992,7 @@
 
 void NuPlayerDriver::notifyListener_l(
         int msg, int ext1, int ext2, const Parcel *in) {
-    ALOGD("notifyListener_l(%p), (%d, %d, %d, %d), loop setting(%d, %d)",
+    ALOGV("notifyListener_l(%p), (%d, %d, %d, %d), loop setting(%d, %d)",
             this, msg, ext1, ext2, (in == NULL ? -1 : (int)in->dataSize()), mAutoLoop, mLooping);
     switch (msg) {
         case MEDIA_PLAYBACK_COMPLETE:
@@ -1019,7 +1025,7 @@
                 mPlayer->pause();
                 mState = STATE_PAUSED;
             }
-            // fall through
+            FALLTHROUGH_INTENDED;
         }
 
         case MEDIA_ERROR:
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp
index bde0862..2d0c9e0 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp
@@ -159,8 +159,12 @@
     if (drm != NULL) {
         for (size_t i = 0; i < psshDRMs.size(); i++) {
             DrmUUID uuid = psshDRMs[i];
-            if (drm->isCryptoSchemeSupported(uuid.ptr(), String8()))
+            bool isSupported = false;
+            status = drm->isCryptoSchemeSupported(uuid.ptr(), String8(),
+                    DrmPlugin::kSecurityLevelUnknown, &isSupported);
+            if (status == OK && isSupported) {
                 supportedDRMs.add(uuid);
+            }
         }
 
         drm.clear();
@@ -239,8 +243,14 @@
         size_t *encryptedbytes)
 {
     // size needed to store all the crypto data
-    size_t cryptosize = sizeof(CryptoInfo) +
-                        sizeof(CryptoPlugin::SubSample) * numSubSamples;
+    size_t cryptosize;
+    // sizeof(CryptoInfo) + sizeof(CryptoPlugin::SubSample) * numSubSamples;
+    if (__builtin_mul_overflow(sizeof(CryptoPlugin::SubSample), numSubSamples, &cryptosize) ||
+            __builtin_add_overflow(cryptosize, sizeof(CryptoInfo), &cryptosize)) {
+        ALOGE("crypto size overflow");
+        return NULL;
+    }
+
     CryptoInfo *ret = (CryptoInfo*) malloc(cryptosize);
     if (ret == NULL) {
         ALOGE("couldn't allocate %zu bytes", cryptosize);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 3a28bbd..39be40d 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -26,6 +26,8 @@
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/foundation/AUtils.h>
 #include <media/stagefright/MediaClock.h>
+#include <media/stagefright/MediaCodecConstants.h>
+#include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/Utils.h>
@@ -68,13 +70,17 @@
 
 // Maximum time in paused state when offloading audio decompression. When elapsed, the AudioSink
 // is closed to allow the audio DSP to power down.
-static const int64_t kOffloadPauseMaxUs = 10000000ll;
+static const int64_t kOffloadPauseMaxUs = 10000000LL;
 
 // Maximum allowed delay from AudioSink, 1.5 seconds.
-static const int64_t kMaxAllowedAudioSinkDelayUs = 1500000ll;
+static const int64_t kMaxAllowedAudioSinkDelayUs = 1500000LL;
 
 static const int64_t kMinimumAudioClockUpdatePeriodUs = 20 /* msec */ * 1000;
 
+// Default video frame display duration when only video exists.
+// Used to set max media time in MediaClock.
+static const int64_t kDefaultVideoFrameIntervalUs = 100000LL;
+
 // static
 const NuPlayer::Renderer::PcmInfo NuPlayer::Renderer::AUDIO_PCMINFO_INITIALIZER = {
         AUDIO_CHANNEL_NONE,
@@ -87,6 +93,20 @@
 // static
 const int64_t NuPlayer::Renderer::kMinPositionUpdateDelayUs = 100000ll;
 
+static audio_format_t constexpr audioFormatFromEncoding(int32_t pcmEncoding) {
+    switch (pcmEncoding) {
+    case kAudioEncodingPcmFloat:
+        return AUDIO_FORMAT_PCM_FLOAT;
+    case kAudioEncodingPcm16bit:
+        return AUDIO_FORMAT_PCM_16_BIT;
+    case kAudioEncodingPcm8bit:
+        return AUDIO_FORMAT_PCM_8_BIT; // TODO: do we want to support this?
+    default:
+        ALOGE("%s: Invalid encoding: %d", __func__, pcmEncoding);
+        return AUDIO_FORMAT_INVALID;
+    }
+}
+
 NuPlayer::Renderer::Renderer(
         const sp<MediaPlayerBase::AudioSink> &sink,
         const sp<MediaClock> &mediaClock,
@@ -109,7 +129,7 @@
       mAudioFirstAnchorTimeMediaUs(-1),
       mAnchorTimeMediaUs(-1),
       mAnchorNumFramesWritten(-1),
-      mVideoLateByUs(0ll),
+      mVideoLateByUs(0LL),
       mNextVideoTimeMediaUs(-1),
       mHasAudio(false),
       mHasVideo(false),
@@ -298,11 +318,11 @@
             mNotifyCompleteVideo |= notifyComplete;
             ++mVideoQueueGeneration;
             ++mVideoDrainGeneration;
+            mNextVideoTimeMediaUs = -1;
         }
 
         mMediaClock->clearAnchor();
         mVideoLateByUs = 0;
-        mNextVideoTimeMediaUs = -1;
         mSyncQueues = false;
     }
 
@@ -358,8 +378,12 @@
 
         // AudioSink has rendered some frames.
         int64_t nowUs = ALooper::GetNowUs();
-        int64_t nowMediaUs = mAudioSink->getPlayedOutDurationUs(nowUs)
-                + mAudioFirstAnchorTimeMediaUs;
+        int64_t playedOutDurationUs = mAudioSink->getPlayedOutDurationUs(nowUs);
+        if (playedOutDurationUs == 0) {
+            *mediaUs = mAudioFirstAnchorTimeMediaUs;
+            return OK;
+        }
+        int64_t nowMediaUs = playedOutDurationUs + mAudioFirstAnchorTimeMediaUs;
         mMediaClock->updateAnchor(nowMediaUs, nowUs, -1);
     }
 
@@ -560,7 +584,7 @@
                 // play back.
                 int64_t delayUs =
                     mAudioSink->msecsPerFrame()
-                        * numFramesPendingPlayout * 1000ll;
+                        * numFramesPendingPlayout * 1000LL;
                 if (mPlaybackRate > 1.0f) {
                     delayUs /= mPlaybackRate;
                 }
@@ -1141,8 +1165,8 @@
         ALOGE("sampleRate is 0 in %s mode", offloadingAudio() ? "offload" : "non-offload");
         return 0;
     }
-    // TODO: remove the (int32_t) casting below as it may overflow at 12.4 hours.
-    return (int64_t)((int32_t)numFrames * 1000000LL / sampleRate);
+
+    return (int64_t)(numFrames * 1000000LL / sampleRate);
 }
 
 // Calculate duration of pending samples if played at normal rate (i.e., 1.0).
@@ -1152,7 +1176,7 @@
         int64_t nowUs = ALooper::GetNowUs();
         int64_t mediaUs;
         if (mMediaClock->getMediaTime(nowUs, &mediaUs) != OK) {
-            return 0ll;
+            return 0LL;
         } else {
             return writtenAudioDurationUs - (mediaUs - mAudioFirstAnchorTimeMediaUs);
         }
@@ -1279,10 +1303,10 @@
             mAnchorTimeMediaUs = mediaTimeUs;
         }
     }
-    mNextVideoTimeMediaUs = mediaTimeUs + 100000;
+    mNextVideoTimeMediaUs = mediaTimeUs;
     if (!mHasAudio) {
         // smooth out videos >= 10fps
-        mMediaClock->updateMaxTimeMedia(mNextVideoTimeMediaUs);
+        mMediaClock->updateMaxTimeMedia(mediaTimeUs + kDefaultVideoFrameIntervalUs);
     }
 
     if (!mVideoSampleReceived || mediaTimeUs < mAudioFirstAnchorTimeMediaUs) {
@@ -1349,7 +1373,7 @@
                     && mediaTimeUs > mLastAudioMediaTimeUs) {
                 // If audio ends before video, video continues to drive media clock.
                 // Also smooth out videos >= 10fps.
-                mMediaClock->updateMaxTimeMedia(mediaTimeUs + 100000);
+                mMediaClock->updateMaxTimeMedia(mediaTimeUs + kDefaultVideoFrameIntervalUs);
             }
         }
     } else {
@@ -1367,7 +1391,7 @@
         tooLate = false;
     }
 
-    entry->mNotifyConsumed->setInt64("timestampNs", realTimeUs * 1000ll);
+    entry->mNotifyConsumed->setInt64("timestampNs", realTimeUs * 1000LL);
     entry->mNotifyConsumed->setInt32("render", !tooLate);
     entry->mNotifyConsumed->post();
     mVideoQueue.erase(mVideoQueue.begin());
@@ -1416,9 +1440,16 @@
         mHasAudio = false;
         if (mNextVideoTimeMediaUs >= 0) {
             int64_t mediaUs = 0;
-            mMediaClock->getMediaTime(ALooper::GetNowUs(), &mediaUs);
-            if (mNextVideoTimeMediaUs > mediaUs) {
-                mMediaClock->updateMaxTimeMedia(mNextVideoTimeMediaUs);
+            int64_t nowUs = ALooper::GetNowUs();
+            status_t result = mMediaClock->getMediaTime(nowUs, &mediaUs);
+            if (result == OK) {
+                if (mNextVideoTimeMediaUs > mediaUs) {
+                    mMediaClock->updateMaxTimeMedia(mNextVideoTimeMediaUs);
+                }
+            } else {
+                mMediaClock->updateAnchor(
+                        mNextVideoTimeMediaUs, nowUs,
+                        mNextVideoTimeMediaUs + kDefaultVideoFrameIntervalUs);
             }
         }
     }
@@ -1499,7 +1530,7 @@
 
     ALOGV("queueDiff = %.2f secs", diff / 1E6);
 
-    if (diff > 100000ll) {
+    if (diff > 100000LL) {
         // Audio data starts More than 0.1 secs before video.
         // Drop some audio.
 
@@ -1571,6 +1602,14 @@
             notifyComplete = mNotifyCompleteAudio;
             mNotifyCompleteAudio = false;
             mLastAudioMediaTimeUs = -1;
+
+            mHasAudio = false;
+            if (mNextVideoTimeMediaUs >= 0) {
+                int64_t nowUs = ALooper::GetNowUs();
+                mMediaClock->updateAnchor(
+                        mNextVideoTimeMediaUs, nowUs,
+                        mNextVideoTimeMediaUs + kDefaultVideoFrameIntervalUs);
+            }
         } else {
             notifyComplete = mNotifyCompleteVideo;
             mNotifyCompleteVideo = false;
@@ -1873,8 +1912,13 @@
     int32_t sampleRate;
     CHECK(format->findInt32("sample-rate", &sampleRate));
 
+    // read pcm encoding from MediaCodec output format, if available
+    int32_t pcmEncoding;
+    audio_format_t audioFormat =
+            format->findInt32(KEY_PCM_ENCODING, &pcmEncoding) ?
+                    audioFormatFromEncoding(pcmEncoding) : AUDIO_FORMAT_PCM_16_BIT;
+
     if (offloadingAudio()) {
-        audio_format_t audioFormat = AUDIO_FORMAT_PCM_16_BIT;
         AString mime;
         CHECK(format->findString("mime", &mime));
         status_t err = mapMimeToAudioFormat(audioFormat, mime.c_str());
@@ -1976,7 +2020,7 @@
         const PcmInfo info = {
                 (audio_channel_mask_t)channelMask,
                 (audio_output_flags_t)pcmFlags,
-                AUDIO_FORMAT_PCM_16_BIT, // TODO: change to audioFormat
+                audioFormat,
                 numChannels,
                 sampleRate
         };
@@ -2015,7 +2059,7 @@
                     sampleRate,
                     numChannels,
                     (audio_channel_mask_t)channelMask,
-                    AUDIO_FORMAT_PCM_16_BIT,
+                    audioFormat,
                     0 /* bufferCount - unused */,
                     mUseAudioCallback ? &NuPlayer::Renderer::AudioSinkCallback : NULL,
                     mUseAudioCallback ? this : NULL,
@@ -2073,4 +2117,3 @@
 }
 
 }  // namespace android
-
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index a047975..a521f62 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -28,7 +28,7 @@
 class  AWakeLock;
 struct MediaClock;
 class MediaCodecBuffer;
-struct VideoFrameScheduler;
+struct VideoFrameSchedulerBase;
 
 struct NuPlayer::Renderer : public AHandler {
     enum Flags {
@@ -156,7 +156,7 @@
     List<QueueEntry> mAudioQueue;
     List<QueueEntry> mVideoQueue;
     uint32_t mNumFramesWritten;
-    sp<VideoFrameScheduler> mVideoScheduler;
+    sp<VideoFrameSchedulerBase> mVideoScheduler;
 
     bool mDrainAudioQueuePending;
     bool mDrainVideoQueuePending;
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
index 851217b..bf14ec2 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
@@ -30,7 +30,7 @@
 
 namespace android {
 
-const int64_t kNearEOSTimeoutUs = 2000000ll; // 2 secs
+const int64_t kNearEOSTimeoutUs = 2000000LL; // 2 secs
 
 // Default Buffer Underflow/Prepare/StartServer/Overflow Marks
 static const int kUnderflowMarkMs   =  1000;  // 1 second
@@ -169,7 +169,7 @@
     // We're going to buffer at least 2 secs worth data on all tracks before
     // starting playback (both at startup and after a seek).
 
-    static const int64_t kMinDurationUs = 2000000ll;
+    static const int64_t kMinDurationUs = 2000000LL;
 
     int64_t mediaDurationUs = 0;
     getDuration(&mediaDurationUs);
@@ -273,7 +273,7 @@
 }
 
 status_t NuPlayer::RTSPSource::getDuration(int64_t *durationUs) {
-    *durationUs = -1ll;
+    *durationUs = -1LL;
 
     int64_t audioDurationUs;
     if (mAudioTrack != NULL
@@ -322,7 +322,7 @@
 
 void NuPlayer::RTSPSource::schedulePollBuffering() {
     sp<AMessage> msg = new AMessage(kWhatPollBuffering, this);
-    msg->post(1000000ll); // 1 second intervals
+    msg->post(1000000LL); // 1 second intervals
 }
 
 void NuPlayer::RTSPSource::checkBuffering(
@@ -346,10 +346,10 @@
         int64_t maxRebufferingMarkUs;
         {
             Mutex::Autolock _l(mBufferingSettingsLock);
-            initialMarkUs = mBufferingSettings.mInitialMarkMs * 1000ll;
+            initialMarkUs = mBufferingSettings.mInitialMarkMs * 1000LL;
             // TODO: maxRebufferingMarkUs could be larger than
             // mBufferingSettings.mResumePlaybackMarkMs * 1000ll.
-            maxRebufferingMarkUs = mBufferingSettings.mResumePlaybackMarkMs * 1000ll;
+            maxRebufferingMarkUs = mBufferingSettings.mResumePlaybackMarkMs * 1000LL;
         }
         // isFinished when duration is 0 checks for EOS result only
         if (bufferedDurationUs > initialMarkUs
@@ -369,7 +369,7 @@
                 ++overflowCount;
             }
             int64_t startServerMarkUs =
-                    (kUnderflowMarkMs * 1000ll + maxRebufferingMarkUs) / 2;
+                    (kUnderflowMarkMs * 1000LL + maxRebufferingMarkUs) / 2;
             if (bufferedDurationUs < startServerMarkUs) {
                 ++startCount;
             }
@@ -640,7 +640,7 @@
                 int64_t nptUs =
                     ((double)rtpTime - (double)info->mRTPTime)
                         / info->mTimeScale
-                        * 1000000ll
+                        * 1000000LL
                         + info->mNormalPlaytimeUs;
 
                 accessUnit->meta()->setInt64("timeUs", nptUs);
@@ -748,7 +748,7 @@
         TrackInfo info;
         info.mTimeScale = timeScale;
         info.mRTPTime = 0;
-        info.mNormalPlaytimeUs = 0ll;
+        info.mNormalPlaytimeUs = 0LL;
         info.mNPTMappingValid = false;
 
         if ((isAudio && mAudioTrack == NULL)
diff --git a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
index 88fc782..ea64f98 100644
--- a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
@@ -187,7 +187,7 @@
     // We're going to buffer at least 2 secs worth data on all tracks before
     // starting playback (both at startup and after a seek).
 
-    static const int64_t kMinDurationUs = 2000000ll;
+    static const int64_t kMinDurationUs = 2000000LL;
 
     sp<AnotherPacketSource> audioTrack = getSource(true /*audio*/);
     sp<AnotherPacketSource> videoTrack = getSource(false /*audio*/);
diff --git a/media/libmediaplayerservice/tests/Android.bp b/media/libmediaplayerservice/tests/Android.bp
index e936bdd..f8c89e5 100644
--- a/media/libmediaplayerservice/tests/Android.bp
+++ b/media/libmediaplayerservice/tests/Android.bp
@@ -2,8 +2,6 @@
 
     name: "DrmSessionManager_test",
 
-    tags: ["tests"],
-
     srcs: ["DrmSessionManager_test.cpp"],
 
     shared_libs: [
@@ -13,10 +11,9 @@
         "libutils",
         "android.hardware.drm@1.0",
         "android.hardware.drm@1.1",
+        "android.hardware.drm@1.2",
     ],
 
-    compile_multilib: "32",
-
     cflags: [
         "-Werror",
         "-Wall",
diff --git a/media/libnblog/Android.bp b/media/libnblog/Android.bp
index 74aaf77..1188320 100644
--- a/media/libnblog/Android.bp
+++ b/media/libnblog/Android.bp
@@ -3,9 +3,13 @@
     name: "libnblog",
 
     srcs: [
-        "NBLog.cpp",
+        "Entry.cpp",
+        "Merger.cpp",
         "PerformanceAnalysis.cpp",
+        "Reader.cpp",
         "ReportPerformance.cpp",
+        "Timeline.cpp",
+        "Writer.cpp",
     ],
 
     shared_libs: [
@@ -13,9 +17,14 @@
         "libbinder",
         "libcutils",
         "liblog",
+        "libmediametrics",
         "libutils",
     ],
 
+    static_libs: [
+        "libjsoncpp",
+    ],
+
     cflags: [
         "-Werror",
         "-Wall",
diff --git a/media/libnblog/Entry.cpp b/media/libnblog/Entry.cpp
new file mode 100644
index 0000000..e875639
--- /dev/null
+++ b/media/libnblog/Entry.cpp
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "NBLog"
+//#define LOG_NDEBUG 0
+
+#include <memory>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <audio_utils/fifo.h>
+#include <media/nblog/Entry.h>
+#include <media/nblog/Events.h>
+#include <utils/Log.h>
+
+namespace android {
+namespace NBLog {
+
+int Entry::copyEntryDataAt(size_t offset) const
+{
+    // FIXME This is too slow
+    if (offset == 0) {
+        return mEvent;
+    } else if (offset == 1) {
+        return mLength;
+    } else if (offset < (size_t) (mLength + 2)) {
+        return (int) ((char *) mData)[offset - 2];
+    } else if (offset == (size_t) (mLength + 2)) {
+        return mLength;
+    } else {
+        return 0;   // FIXME is this an error?
+    }
+}
+
+EntryIterator::EntryIterator()   // Dummy initialization.
+    : mPtr(nullptr)
+{
+}
+
+EntryIterator::EntryIterator(const uint8_t *entry)
+    : mPtr(entry)
+{
+}
+
+EntryIterator::EntryIterator(const EntryIterator &other)
+    : mPtr(other.mPtr)
+{
+}
+
+const entry& EntryIterator::operator*() const
+{
+    return *(entry*) mPtr;
+}
+
+const entry* EntryIterator::operator->() const
+{
+    return (entry*) mPtr;
+}
+
+EntryIterator& EntryIterator::operator++()
+{
+    mPtr += mPtr[offsetof(entry, length)] + Entry::kOverhead;
+    return *this;
+}
+
+EntryIterator& EntryIterator::operator--()
+{
+    mPtr -= mPtr[Entry::kPreviousLengthOffset] + Entry::kOverhead;
+    return *this;
+}
+
+EntryIterator EntryIterator::next() const
+{
+    EntryIterator aux(*this);
+    return ++aux;
+}
+
+EntryIterator EntryIterator::prev() const
+{
+    EntryIterator aux(*this);
+    return --aux;
+}
+
+bool EntryIterator::operator!=(const EntryIterator &other) const
+{
+    return mPtr != other.mPtr;
+}
+
+int EntryIterator::operator-(const EntryIterator &other) const
+{
+    return mPtr - other.mPtr;
+}
+
+bool EntryIterator::hasConsistentLength() const
+{
+    return mPtr[offsetof(entry, length)] == mPtr[mPtr[offsetof(entry, length)] +
+        Entry::kOverhead + Entry::kPreviousLengthOffset];
+}
+
+void EntryIterator::copyTo(std::unique_ptr<audio_utils_fifo_writer> &dst) const
+{
+    size_t length = mPtr[offsetof(entry, length)] + Entry::kOverhead;
+    dst->write(mPtr, length);
+}
+
+void EntryIterator::copyData(uint8_t *dst) const
+{
+    memcpy((void*) dst, mPtr + offsetof(entry, data), mPtr[offsetof(entry, length)]);
+}
+
+// ---------------------------------------------------------------------------
+
+std::unique_ptr<AbstractEntry> AbstractEntry::buildEntry(const uint8_t *ptr)
+{
+    if (ptr == nullptr) {
+        return nullptr;
+    }
+    const uint8_t type = EntryIterator(ptr)->type;
+    switch (type) {
+    case EVENT_FMT_START:
+        return std::make_unique<FormatEntry>(FormatEntry(ptr));
+    case EVENT_AUDIO_STATE:
+    case EVENT_HISTOGRAM_ENTRY_TS:
+        return std::make_unique<HistogramEntry>(HistogramEntry(ptr));
+    default:
+        ALOGW("Tried to create AbstractEntry of type %d", type);
+        return nullptr;
+    }
+}
+
+EntryIterator FormatEntry::begin() const
+{
+    return EntryIterator(mEntry);
+}
+
+const char *FormatEntry::formatString() const
+{
+    return (const char*) mEntry + offsetof(entry, data);
+}
+
+size_t FormatEntry::formatStringLength() const
+{
+    return mEntry[offsetof(entry, length)];
+}
+
+EntryIterator FormatEntry::args() const
+{
+    auto it = begin();
+    ++it; // skip start fmt
+    ++it; // skip timestamp
+    ++it; // skip hash
+    // Skip author if present
+    if (it->type == EVENT_FMT_AUTHOR) {
+        ++it;
+    }
+    return it;
+}
+
+int64_t FormatEntry::timestamp() const
+{
+    auto it = begin();
+    ++it; // skip start fmt
+    return it.payload<int64_t>();
+}
+
+log_hash_t FormatEntry::hash() const
+{
+    auto it = begin();
+    ++it; // skip start fmt
+    ++it; // skip timestamp
+    // unaligned 64-bit read not supported
+    log_hash_t hash;
+    memcpy(&hash, it->data, sizeof(hash));
+    return hash;
+}
+
+int FormatEntry::author() const
+{
+    auto it = begin();
+    ++it; // skip start fmt
+    ++it; // skip timestamp
+    ++it; // skip hash
+    // if there is an author entry, return it, return -1 otherwise
+    return it->type == EVENT_FMT_AUTHOR ? it.payload<int>() : -1;
+}
+
+EntryIterator FormatEntry::copyWithAuthor(
+        std::unique_ptr<audio_utils_fifo_writer> &dst, int author) const
+{
+    auto it = begin();
+    it.copyTo(dst);     // copy fmt start entry
+    (++it).copyTo(dst); // copy timestamp
+    (++it).copyTo(dst); // copy hash
+    // insert author entry
+    size_t authorEntrySize = Entry::kOverhead + sizeof(author);
+    uint8_t authorEntry[authorEntrySize];
+    authorEntry[offsetof(entry, type)] = EVENT_FMT_AUTHOR;
+    authorEntry[offsetof(entry, length)] =
+        authorEntry[authorEntrySize + Entry::kPreviousLengthOffset] =
+        sizeof(author);
+    *(int*) (&authorEntry[offsetof(entry, data)]) = author;
+    dst->write(authorEntry, authorEntrySize);
+    // copy rest of entries
+    while ((++it)->type != EVENT_FMT_END) {
+        it.copyTo(dst);
+    }
+    it.copyTo(dst);
+    ++it;
+    return it;
+}
+
+int64_t HistogramEntry::timestamp() const
+{
+    return EntryIterator(mEntry).payload<HistTsEntry>().ts;
+}
+
+log_hash_t HistogramEntry::hash() const
+{
+    return EntryIterator(mEntry).payload<HistTsEntry>().hash;
+}
+
+int HistogramEntry::author() const
+{
+    EntryIterator it(mEntry);
+    return it->length == sizeof(HistTsEntryWithAuthor)
+            ? it.payload<HistTsEntryWithAuthor>().author : -1;
+}
+
+EntryIterator HistogramEntry::copyWithAuthor(
+        std::unique_ptr<audio_utils_fifo_writer> &dst, int author) const
+{
+    // Current histogram entry has {type, length, struct HistTsEntry, length}.
+    // We now want {type, length, struct HistTsEntryWithAuthor, length}
+    uint8_t buffer[Entry::kOverhead + sizeof(HistTsEntryWithAuthor)];
+    // Copy content until the point we want to add the author
+    memcpy(buffer, mEntry, sizeof(entry) + sizeof(HistTsEntry));
+    // Copy the author
+    *(int*) (buffer + sizeof(entry) + sizeof(HistTsEntry)) = author;
+    // Update lengths
+    buffer[offsetof(entry, length)] = sizeof(HistTsEntryWithAuthor);
+    buffer[offsetof(entry, data) + sizeof(HistTsEntryWithAuthor) + offsetof(ending, length)]
+        = sizeof(HistTsEntryWithAuthor);
+    // Write new buffer into FIFO
+    dst->write(buffer, sizeof(buffer));
+    return EntryIterator(mEntry).next();
+}
+
+}   // namespace NBLog
+}   // namespace android
diff --git a/media/libnblog/Merger.cpp b/media/libnblog/Merger.cpp
new file mode 100644
index 0000000..3ad6d6b
--- /dev/null
+++ b/media/libnblog/Merger.cpp
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "NBLog"
+//#define LOG_NDEBUG 0
+
+#include <memory>
+#include <queue>
+#include <stddef.h>
+#include <stdint.h>
+#include <vector>
+
+#include <audio_utils/fifo.h>
+#include <json/json.h>
+#include <media/nblog/Merger.h>
+#include <media/nblog/PerformanceAnalysis.h>
+#include <media/nblog/ReportPerformance.h>
+#include <media/nblog/Reader.h>
+#include <media/nblog/Timeline.h>
+#include <utils/Condition.h>
+#include <utils/Log.h>
+#include <utils/Mutex.h>
+#include <utils/RefBase.h>
+#include <utils/String16.h>
+#include <utils/String8.h>
+#include <utils/Thread.h>
+#include <utils/Timers.h>
+#include <utils/Vector.h>
+
+namespace android {
+namespace NBLog {
+
+Merger::Merger(const void *shared, size_t size):
+      mShared((Shared *) shared),
+      mFifo(mShared != NULL ?
+        new audio_utils_fifo(size, sizeof(uint8_t),
+            mShared->mBuffer, mShared->mRear, NULL /*throttlesFront*/) : NULL),
+      mFifoWriter(mFifo != NULL ? new audio_utils_fifo_writer(*mFifo) : NULL)
+{
+}
+
+void Merger::addReader(const sp<Reader> &reader)
+{
+    // FIXME This is called by binder thread in MediaLogService::registerWriter
+    //       but the access to shared variable mReaders is not yet protected by a lock.
+    mReaders.push_back(reader);
+}
+
+// items placed in priority queue during merge
+// composed by a timestamp and the index of the snapshot where the timestamp came from
+struct MergeItem
+{
+    int64_t ts;
+    int index;
+    MergeItem(int64_t ts, int index): ts(ts), index(index) {}
+};
+
+bool operator>(const struct MergeItem &i1, const struct MergeItem &i2)
+{
+    return i1.ts > i2.ts || (i1.ts == i2.ts && i1.index > i2.index);
+}
+
+// Merge registered readers, sorted by timestamp, and write data to a single FIFO in local memory
+void Merger::merge()
+{
+    if (true) return; // Merging is not necessary at the moment, so this is to disable it
+                      // and bypass compiler warnings about member variables not being used.
+    const int nLogs = mReaders.size();
+    std::vector<std::unique_ptr<Snapshot>> snapshots(nLogs);
+    std::vector<EntryIterator> offsets;
+    offsets.reserve(nLogs);
+    for (int i = 0; i < nLogs; ++i) {
+        snapshots[i] = mReaders[i]->getSnapshot();
+        offsets.push_back(snapshots[i]->begin());
+    }
+    // initialize offsets
+    // TODO custom heap implementation could allow to update top, improving performance
+    // for bursty buffers
+    std::priority_queue<MergeItem, std::vector<MergeItem>, std::greater<MergeItem>> timestamps;
+    for (int i = 0; i < nLogs; ++i)
+    {
+        if (offsets[i] != snapshots[i]->end()) {
+            std::unique_ptr<AbstractEntry> abstractEntry = AbstractEntry::buildEntry(offsets[i]);
+            if (abstractEntry == nullptr) {
+                continue;
+            }
+            timestamps.emplace(abstractEntry->timestamp(), i);
+        }
+    }
+
+    while (!timestamps.empty()) {
+        int index = timestamps.top().index;     // find minimum timestamp
+        // copy it to the log, increasing offset
+        offsets[index] = AbstractEntry::buildEntry(offsets[index])->
+            copyWithAuthor(mFifoWriter, index);
+        // update data structures
+        timestamps.pop();
+        if (offsets[index] != snapshots[index]->end()) {
+            int64_t ts = AbstractEntry::buildEntry(offsets[index])->timestamp();
+            timestamps.emplace(ts, index);
+        }
+    }
+}
+
+const std::vector<sp<Reader>>& Merger::getReaders() const
+{
+    //AutoMutex _l(mLock);
+    return mReaders;
+}
+
+// ---------------------------------------------------------------------------
+
+MergeReader::MergeReader(const void *shared, size_t size, Merger &merger)
+    : Reader(shared, size, "MergeReader"), mReaders(merger.getReaders())
+{
+}
+
+// Takes raw content of the local merger FIFO, processes log entries, and
+// writes the data to a map of class PerformanceAnalysis, based on their thread ID.
+void MergeReader::processSnapshot(Snapshot &snapshot, int author)
+{
+    ReportPerformance::PerformanceData& data = mThreadPerformanceData[author];
+    // We don't do "auto it" because it reduces readability in this case.
+    for (EntryIterator it = snapshot.begin(); it != snapshot.end(); ++it) {
+        switch (it->type) {
+        case EVENT_HISTOGRAM_ENTRY_TS: {
+            const HistTsEntry payload = it.payload<HistTsEntry>();
+            // TODO: hash for histogram ts and audio state need to match
+            // and correspond to audio production source file location
+            mThreadPerformanceAnalysis[author][0 /*hash*/].logTsEntry(payload.ts);
+        } break;
+        case EVENT_AUDIO_STATE: {
+            mThreadPerformanceAnalysis[author][0 /*hash*/].handleStateChange();
+        } break;
+        case EVENT_THREAD_INFO: {
+            const thread_info_t info = it.payload<thread_info_t>();
+            data.threadInfo = info;
+        } break;
+        case EVENT_THREAD_PARAMS: {
+            const thread_params_t params = it.payload<thread_params_t>();
+            data.threadParams = params;
+        } break;
+        case EVENT_LATENCY: {
+            const double latencyMs = it.payload<double>();
+            data.latencyHist.add(latencyMs);
+        } break;
+        case EVENT_WORK_TIME: {
+            const int64_t monotonicNs = it.payload<int64_t>();
+            const double monotonicMs = monotonicNs * 1e-6;
+            data.workHist.add(monotonicMs);
+            data.active += monotonicNs;
+        } break;
+        case EVENT_WARMUP_TIME: {
+            const double timeMs = it.payload<double>();
+            data.warmupHist.add(timeMs);
+        } break;
+        case EVENT_UNDERRUN: {
+            const int64_t ts = it.payload<int64_t>();
+            data.underruns++;
+            data.snapshots.emplace_front(EVENT_UNDERRUN, ts);
+            // TODO have a data structure to automatically handle resizing
+            if (data.snapshots.size() > ReportPerformance::PerformanceData::kMaxSnapshotsToStore) {
+                data.snapshots.pop_back();
+            }
+        } break;
+        case EVENT_OVERRUN: {
+            const int64_t ts = it.payload<int64_t>();
+            data.overruns++;
+            data.snapshots.emplace_front(EVENT_UNDERRUN, ts);
+            // TODO have a data structure to automatically handle resizing
+            if (data.snapshots.size() > ReportPerformance::PerformanceData::kMaxSnapshotsToStore) {
+                data.snapshots.pop_back();
+            }
+        } break;
+        case EVENT_RESERVED:
+        case EVENT_UPPER_BOUND:
+            ALOGW("warning: unexpected event %d", it->type);
+            break;
+        default:
+            break;
+        }
+    }
+}
+
+void MergeReader::getAndProcessSnapshot()
+{
+    // get a snapshot of each reader and process them
+    // TODO insert lock here
+    const size_t nLogs = mReaders.size();
+    std::vector<std::unique_ptr<Snapshot>> snapshots(nLogs);
+    for (size_t i = 0; i < nLogs; i++) {
+        snapshots[i] = mReaders[i]->getSnapshot();
+    }
+    // TODO unlock lock here
+    for (size_t i = 0; i < nLogs; i++) {
+        if (snapshots[i] != nullptr) {
+            processSnapshot(*(snapshots[i]), i);
+        }
+    }
+    checkPushToMediaMetrics();
+}
+
+void MergeReader::checkPushToMediaMetrics()
+{
+    const nsecs_t now = systemTime();
+    for (auto& item : mThreadPerformanceData) {
+        ReportPerformance::PerformanceData& data = item.second;
+        if (now - data.start >= kPeriodicMediaMetricsPush) {
+            (void)ReportPerformance::sendToMediaMetrics(data);
+            data.reset();   // data is persistent per thread
+        }
+    }
+}
+
+void MergeReader::dump(int fd, const Vector<String16>& args)
+{
+    // TODO: add a mutex around media.log dump
+    // Options for dumpsys
+    bool pa = false, json = false, plots = false, retro = false;
+    for (const auto &arg : args) {
+        if (arg == String16("--pa")) {
+            pa = true;
+        } else if (arg == String16("--json")) {
+            json = true;
+        } else if (arg == String16("--plots")) {
+            plots = true;
+        } else if (arg == String16("--retro")) {
+            retro = true;
+        }
+    }
+    if (pa) {
+        ReportPerformance::dump(fd, 0 /*indent*/, mThreadPerformanceAnalysis);
+    }
+    if (json) {
+        ReportPerformance::dumpJson(fd, mThreadPerformanceData);
+    }
+    if (plots) {
+        ReportPerformance::dumpPlots(fd, mThreadPerformanceData);
+    }
+    if (retro) {
+        ReportPerformance::dumpRetro(fd, mThreadPerformanceData);
+    }
+}
+
+void MergeReader::handleAuthor(const AbstractEntry &entry, String8 *body)
+{
+    int author = entry.author();
+    if (author == -1) {
+        return;
+    }
+    // FIXME Needs a lock
+    const char* name = mReaders[author]->name().c_str();
+    body->appendFormat("%s: ", name);
+}
+
+// ---------------------------------------------------------------------------
+
+MergeThread::MergeThread(Merger &merger, MergeReader &mergeReader)
+    : mMerger(merger),
+      mMergeReader(mergeReader),
+      mTimeoutUs(0)
+{
+}
+
+MergeThread::~MergeThread()
+{
+    // set exit flag, set timeout to 0 to force threadLoop to exit and wait for the thread to join
+    requestExit();
+    setTimeoutUs(0);
+    join();
+}
+
+bool MergeThread::threadLoop()
+{
+    bool doMerge;
+    {
+        AutoMutex _l(mMutex);
+        // If mTimeoutUs is negative, wait on the condition variable until it's positive.
+        // If it's positive, merge. The minimum period between waking the condition variable
+        // is handled in AudioFlinger::MediaLogNotifier::threadLoop().
+        mCond.wait(mMutex);
+        doMerge = mTimeoutUs > 0;
+        mTimeoutUs -= kThreadSleepPeriodUs;
+    }
+    if (doMerge) {
+        // Merge data from all the readers
+        mMerger.merge();
+        // Process the data collected by mMerger and write it to PerformanceAnalysis
+        // FIXME: decide whether to call getAndProcessSnapshot every time
+        // or whether to have a separate thread that calls it with a lower frequency
+        mMergeReader.getAndProcessSnapshot();
+    }
+    return true;
+}
+
+void MergeThread::wakeup()
+{
+    setTimeoutUs(kThreadWakeupPeriodUs);
+}
+
+void MergeThread::setTimeoutUs(int time)
+{
+    AutoMutex _l(mMutex);
+    mTimeoutUs = time;
+    mCond.signal();
+}
+
+}   // namespace NBLog
+}   // namespace android
diff --git a/media/libnblog/NBLog.cpp b/media/libnblog/NBLog.cpp
deleted file mode 100644
index d6fa3e3..0000000
--- a/media/libnblog/NBLog.cpp
+++ /dev/null
@@ -1,1157 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *
- */
-
-#define LOG_TAG "NBLog"
-
-#include <algorithm>
-#include <climits>
-#include <deque>
-#include <fstream>
-#include <iostream>
-#include <math.h>
-#include <numeric>
-#include <vector>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/prctl.h>
-#include <time.h>
-#include <new>
-#include <audio_utils/roundup.h>
-#include <media/nblog/NBLog.h>
-#include <media/nblog/PerformanceAnalysis.h>
-#include <media/nblog/ReportPerformance.h>
-#include <utils/CallStack.h>
-#include <utils/Log.h>
-#include <utils/String8.h>
-
-#include <queue>
-#include <utility>
-
-namespace android {
-
-int NBLog::Entry::copyEntryDataAt(size_t offset) const
-{
-    // FIXME This is too slow
-    if (offset == 0)
-        return mEvent;
-    else if (offset == 1)
-        return mLength;
-    else if (offset < (size_t) (mLength + 2))
-        return ((char *) mData)[offset - 2];
-    else if (offset == (size_t) (mLength + 2))
-        return mLength;
-    else
-        return 0;
-}
-
-// ---------------------------------------------------------------------------
-
-/*static*/
-std::unique_ptr<NBLog::AbstractEntry> NBLog::AbstractEntry::buildEntry(const uint8_t *ptr) {
-    const uint8_t type = EntryIterator(ptr)->type;
-    switch (type) {
-    case EVENT_START_FMT:
-        return std::make_unique<FormatEntry>(FormatEntry(ptr));
-    case EVENT_AUDIO_STATE:
-    case EVENT_HISTOGRAM_ENTRY_TS:
-        return std::make_unique<HistogramEntry>(HistogramEntry(ptr));
-    default:
-        ALOGW("Tried to create AbstractEntry of type %d", type);
-        return nullptr;
-    }
-}
-
-NBLog::AbstractEntry::AbstractEntry(const uint8_t *entry) : mEntry(entry) {
-}
-
-// ---------------------------------------------------------------------------
-
-NBLog::EntryIterator NBLog::FormatEntry::begin() const {
-    return EntryIterator(mEntry);
-}
-
-const char *NBLog::FormatEntry::formatString() const {
-    return (const char*) mEntry + offsetof(entry, data);
-}
-
-size_t NBLog::FormatEntry::formatStringLength() const {
-    return mEntry[offsetof(entry, length)];
-}
-
-NBLog::EntryIterator NBLog::FormatEntry::args() const {
-    auto it = begin();
-    // skip start fmt
-    ++it;
-    // skip timestamp
-    ++it;
-    // skip hash
-    ++it;
-    // Skip author if present
-    if (it->type == EVENT_AUTHOR) {
-        ++it;
-    }
-    return it;
-}
-
-int64_t NBLog::FormatEntry::timestamp() const {
-    auto it = begin();
-    // skip start fmt
-    ++it;
-    return it.payload<int64_t>();
-}
-
-NBLog::log_hash_t NBLog::FormatEntry::hash() const {
-    auto it = begin();
-    // skip start fmt
-    ++it;
-    // skip timestamp
-    ++it;
-    // unaligned 64-bit read not supported
-    log_hash_t hash;
-    memcpy(&hash, it->data, sizeof(hash));
-    return hash;
-}
-
-int NBLog::FormatEntry::author() const {
-    auto it = begin();
-    // skip start fmt
-    ++it;
-    // skip timestamp
-    ++it;
-    // skip hash
-    ++it;
-    // if there is an author entry, return it, return -1 otherwise
-    if (it->type == EVENT_AUTHOR) {
-        return it.payload<int>();
-    }
-    return -1;
-}
-
-NBLog::EntryIterator NBLog::FormatEntry::copyWithAuthor(
-        std::unique_ptr<audio_utils_fifo_writer> &dst, int author) const {
-    auto it = begin();
-    // copy fmt start entry
-    it.copyTo(dst);
-    // copy timestamp
-    (++it).copyTo(dst);    // copy hash
-    (++it).copyTo(dst);
-    // insert author entry
-    size_t authorEntrySize = NBLog::Entry::kOverhead + sizeof(author);
-    uint8_t authorEntry[authorEntrySize];
-    authorEntry[offsetof(entry, type)] = EVENT_AUTHOR;
-    authorEntry[offsetof(entry, length)] =
-        authorEntry[authorEntrySize + NBLog::Entry::kPreviousLengthOffset] =
-        sizeof(author);
-    *(int*) (&authorEntry[offsetof(entry, data)]) = author;
-    dst->write(authorEntry, authorEntrySize);
-    // copy rest of entries
-    while ((++it)->type != EVENT_END_FMT) {
-        it.copyTo(dst);
-    }
-    it.copyTo(dst);
-    ++it;
-    return it;
-}
-
-void NBLog::EntryIterator::copyTo(std::unique_ptr<audio_utils_fifo_writer> &dst) const {
-    size_t length = ptr[offsetof(entry, length)] + NBLog::Entry::kOverhead;
-    dst->write(ptr, length);
-}
-
-void NBLog::EntryIterator::copyData(uint8_t *dst) const {
-    memcpy((void*) dst, ptr + offsetof(entry, data), ptr[offsetof(entry, length)]);
-}
-
-NBLog::EntryIterator::EntryIterator()
-    : ptr(nullptr) {}
-
-NBLog::EntryIterator::EntryIterator(const uint8_t *entry)
-    : ptr(entry) {}
-
-NBLog::EntryIterator::EntryIterator(const NBLog::EntryIterator &other)
-    : ptr(other.ptr) {}
-
-const NBLog::entry& NBLog::EntryIterator::operator*() const {
-    return *(entry*) ptr;
-}
-
-const NBLog::entry* NBLog::EntryIterator::operator->() const {
-    return (entry*) ptr;
-}
-
-NBLog::EntryIterator& NBLog::EntryIterator::operator++() {
-    ptr += ptr[offsetof(entry, length)] + NBLog::Entry::kOverhead;
-    return *this;
-}
-
-NBLog::EntryIterator& NBLog::EntryIterator::operator--() {
-    ptr -= ptr[NBLog::Entry::kPreviousLengthOffset] + NBLog::Entry::kOverhead;
-    return *this;
-}
-
-NBLog::EntryIterator NBLog::EntryIterator::next() const {
-    EntryIterator aux(*this);
-    return ++aux;
-}
-
-NBLog::EntryIterator NBLog::EntryIterator::prev() const {
-    EntryIterator aux(*this);
-    return --aux;
-}
-
-int NBLog::EntryIterator::operator-(const NBLog::EntryIterator &other) const {
-    return ptr - other.ptr;
-}
-
-bool NBLog::EntryIterator::operator!=(const EntryIterator &other) const {
-    return ptr != other.ptr;
-}
-
-bool NBLog::EntryIterator::hasConsistentLength() const {
-    return ptr[offsetof(entry, length)] == ptr[ptr[offsetof(entry, length)] +
-        NBLog::Entry::kOverhead + NBLog::Entry::kPreviousLengthOffset];
-}
-
-// ---------------------------------------------------------------------------
-
-int64_t NBLog::HistogramEntry::timestamp() const {
-    return EntryIterator(mEntry).payload<HistTsEntry>().ts;
-}
-
-NBLog::log_hash_t NBLog::HistogramEntry::hash() const {
-    return EntryIterator(mEntry).payload<HistTsEntry>().hash;
-}
-
-int NBLog::HistogramEntry::author() const {
-    EntryIterator it(mEntry);
-    if (it->length == sizeof(HistTsEntryWithAuthor)) {
-        return it.payload<HistTsEntryWithAuthor>().author;
-    } else {
-        return -1;
-    }
-}
-
-NBLog::EntryIterator NBLog::HistogramEntry::copyWithAuthor(
-        std::unique_ptr<audio_utils_fifo_writer> &dst, int author) const {
-    // Current histogram entry has {type, length, struct HistTsEntry, length}.
-    // We now want {type, length, struct HistTsEntryWithAuthor, length}
-    uint8_t buffer[Entry::kOverhead + sizeof(HistTsEntryWithAuthor)];
-    // Copy content until the point we want to add the author
-    memcpy(buffer, mEntry, sizeof(entry) + sizeof(HistTsEntry));
-    // Copy the author
-    *(int*) (buffer + sizeof(entry) + sizeof(HistTsEntry)) = author;
-    // Update lengths
-    buffer[offsetof(entry, length)] = sizeof(HistTsEntryWithAuthor);
-    buffer[offsetof(entry, data) + sizeof(HistTsEntryWithAuthor) + offsetof(ending, length)]
-        = sizeof(HistTsEntryWithAuthor);
-    // Write new buffer into FIFO
-    dst->write(buffer, sizeof(buffer));
-    return EntryIterator(mEntry).next();
-}
-
-// ---------------------------------------------------------------------------
-
-#if 0   // FIXME see note in NBLog.h
-NBLog::Timeline::Timeline(size_t size, void *shared)
-    : mSize(roundup(size)), mOwn(shared == NULL),
-      mShared((Shared *) (mOwn ? new char[sharedSize(size)] : shared))
-{
-    new (mShared) Shared;
-}
-
-NBLog::Timeline::~Timeline()
-{
-    mShared->~Shared();
-    if (mOwn) {
-        delete[] (char *) mShared;
-    }
-}
-#endif
-
-/*static*/
-size_t NBLog::Timeline::sharedSize(size_t size)
-{
-    // TODO fifo now supports non-power-of-2 buffer sizes, so could remove the roundup
-    return sizeof(Shared) + roundup(size);
-}
-
-// ---------------------------------------------------------------------------
-
-NBLog::Writer::Writer()
-    : mShared(NULL), mFifo(NULL), mFifoWriter(NULL), mEnabled(false), mPidTag(NULL), mPidTagSize(0)
-{
-}
-
-NBLog::Writer::Writer(void *shared, size_t size)
-    : mShared((Shared *) shared),
-      mFifo(mShared != NULL ?
-        new audio_utils_fifo(size, sizeof(uint8_t),
-            mShared->mBuffer, mShared->mRear, NULL /*throttlesFront*/) : NULL),
-      mFifoWriter(mFifo != NULL ? new audio_utils_fifo_writer(*mFifo) : NULL),
-      mEnabled(mFifoWriter != NULL)
-{
-    // caching pid and process name
-    pid_t id = ::getpid();
-    char procName[16];
-    int status = prctl(PR_GET_NAME, procName);
-    if (status) {  // error getting process name
-        procName[0] = '\0';
-    }
-    size_t length = strlen(procName);
-    mPidTagSize = length + sizeof(pid_t);
-    mPidTag = new char[mPidTagSize];
-    memcpy(mPidTag, &id, sizeof(pid_t));
-    memcpy(mPidTag + sizeof(pid_t), procName, length);
-}
-
-NBLog::Writer::Writer(const sp<IMemory>& iMemory, size_t size)
-    : Writer(iMemory != 0 ? (Shared *) iMemory->pointer() : NULL, size)
-{
-    mIMemory = iMemory;
-}
-
-NBLog::Writer::~Writer()
-{
-    delete mFifoWriter;
-    delete mFifo;
-    delete[] mPidTag;
-}
-
-void NBLog::Writer::log(const char *string)
-{
-    if (!mEnabled) {
-        return;
-    }
-    LOG_ALWAYS_FATAL_IF(string == NULL, "Attempted to log NULL string");
-    size_t length = strlen(string);
-    if (length > Entry::kMaxLength) {
-        length = Entry::kMaxLength;
-    }
-    log(EVENT_STRING, string, length);
-}
-
-void NBLog::Writer::logf(const char *fmt, ...)
-{
-    if (!mEnabled) {
-        return;
-    }
-    va_list ap;
-    va_start(ap, fmt);
-    Writer::logvf(fmt, ap);     // the Writer:: is needed to avoid virtual dispatch for LockedWriter
-    va_end(ap);
-}
-
-void NBLog::Writer::logvf(const char *fmt, va_list ap)
-{
-    if (!mEnabled) {
-        return;
-    }
-    char buffer[Entry::kMaxLength + 1 /*NUL*/];
-    int length = vsnprintf(buffer, sizeof(buffer), fmt, ap);
-    if (length >= (int) sizeof(buffer)) {
-        length = sizeof(buffer) - 1;
-        // NUL termination is not required
-        // buffer[length] = '\0';
-    }
-    if (length >= 0) {
-        log(EVENT_STRING, buffer, length);
-    }
-}
-
-void NBLog::Writer::logTimestamp()
-{
-    if (!mEnabled) {
-        return;
-    }
-    int64_t ts = get_monotonic_ns();
-    if (ts > 0) {
-        log(EVENT_TIMESTAMP, &ts, sizeof(ts));
-    } else {
-        ALOGE("Failed to get timestamp");
-    }
-}
-
-void NBLog::Writer::logTimestamp(const int64_t ts)
-{
-    if (!mEnabled) {
-        return;
-    }
-    log(EVENT_TIMESTAMP, &ts, sizeof(ts));
-}
-
-void NBLog::Writer::logInteger(const int x)
-{
-    if (!mEnabled) {
-        return;
-    }
-    log(EVENT_INTEGER, &x, sizeof(x));
-}
-
-void NBLog::Writer::logFloat(const float x)
-{
-    if (!mEnabled) {
-        return;
-    }
-    log(EVENT_FLOAT, &x, sizeof(x));
-}
-
-void NBLog::Writer::logPID()
-{
-    if (!mEnabled) {
-        return;
-    }
-    log(EVENT_PID, mPidTag, mPidTagSize);
-}
-
-void NBLog::Writer::logStart(const char *fmt)
-{
-    if (!mEnabled) {
-        return;
-    }
-    size_t length = strlen(fmt);
-    if (length > Entry::kMaxLength) {
-        length = Entry::kMaxLength;
-    }
-    log(EVENT_START_FMT, fmt, length);
-}
-
-void NBLog::Writer::logEnd()
-{
-    if (!mEnabled) {
-        return;
-    }
-    Entry entry = Entry(EVENT_END_FMT, NULL, 0);
-    log(&entry, true);
-}
-
-void NBLog::Writer::logHash(log_hash_t hash)
-{
-    if (!mEnabled) {
-        return;
-    }
-    log(EVENT_HASH, &hash, sizeof(hash));
-}
-
-void NBLog::Writer::logEventHistTs(Event event, log_hash_t hash)
-{
-    if (!mEnabled) {
-        return;
-    }
-    HistTsEntry data;
-    data.hash = hash;
-    data.ts = get_monotonic_ns();
-    if (data.ts > 0) {
-        log(event, &data, sizeof(data));
-    } else {
-        ALOGE("Failed to get timestamp");
-    }
-}
-
-void NBLog::Writer::logFormat(const char *fmt, log_hash_t hash, ...)
-{
-    if (!mEnabled) {
-        return;
-    }
-
-    va_list ap;
-    va_start(ap, hash);
-    Writer::logVFormat(fmt, hash, ap);
-    va_end(ap);
-}
-
-void NBLog::Writer::logVFormat(const char *fmt, log_hash_t hash, va_list argp)
-{
-    if (!mEnabled) {
-        return;
-    }
-    Writer::logStart(fmt);
-    int i;
-    double f;
-    char* s;
-    int64_t t;
-    Writer::logTimestamp();
-    Writer::logHash(hash);
-    for (const char *p = fmt; *p != '\0'; p++) {
-        // TODO: implement more complex formatting such as %.3f
-        if (*p != '%') {
-            continue;
-        }
-        switch(*++p) {
-        case 's': // string
-            s = va_arg(argp, char *);
-            Writer::log(s);
-            break;
-
-        case 't': // timestamp
-            t = va_arg(argp, int64_t);
-            Writer::logTimestamp(t);
-            break;
-
-        case 'd': // integer
-            i = va_arg(argp, int);
-            Writer::logInteger(i);
-            break;
-
-        case 'f': // float
-            f = va_arg(argp, double); // float arguments are promoted to double in vararg lists
-            Writer::logFloat((float)f);
-            break;
-
-        case 'p': // pid
-            Writer::logPID();
-            break;
-
-        // the "%\0" case finishes parsing
-        case '\0':
-            --p;
-            break;
-
-        case '%':
-            break;
-
-        default:
-            ALOGW("NBLog Writer parsed invalid format specifier: %c", *p);
-            break;
-        }
-    }
-    Writer::logEnd();
-}
-
-void NBLog::Writer::log(Event event, const void *data, size_t length)
-{
-    if (!mEnabled) {
-        return;
-    }
-    if (data == NULL || length > Entry::kMaxLength) {
-        // TODO Perhaps it makes sense to display truncated data or at least a
-        //      message that the data is too long?  The current behavior can create
-        //      a confusion for a programmer debugging their code.
-        return;
-    }
-    // Ignore if invalid event
-    if (event == EVENT_RESERVED || event >= EVENT_UPPER_BOUND) {
-        return;
-    }
-    Entry etr(event, data, length);
-    log(&etr, true /*trusted*/);
-}
-
-void NBLog::Writer::log(const NBLog::Entry *etr, bool trusted)
-{
-    if (!mEnabled) {
-        return;
-    }
-    if (!trusted) {
-        log(etr->mEvent, etr->mData, etr->mLength);
-        return;
-    }
-    size_t need = etr->mLength + Entry::kOverhead;    // mEvent, mLength, data[mLength], mLength
-                                                      // need = number of bytes written to FIFO
-
-    // FIXME optimize this using memcpy for the data part of the Entry.
-    // The Entry could have a method copyTo(ptr, offset, size) to optimize the copy.
-    // checks size of a single log Entry: type, length, data pointer and ending
-    uint8_t temp[Entry::kMaxLength + Entry::kOverhead];
-    // write this data to temp array
-    for (size_t i = 0; i < need; i++) {
-        temp[i] = etr->copyEntryDataAt(i);
-    }
-    // write to circular buffer
-    mFifoWriter->write(temp, need);
-}
-
-bool NBLog::Writer::isEnabled() const
-{
-    return mEnabled;
-}
-
-bool NBLog::Writer::setEnabled(bool enabled)
-{
-    bool old = mEnabled;
-    mEnabled = enabled && mShared != NULL;
-    return old;
-}
-
-// ---------------------------------------------------------------------------
-
-NBLog::LockedWriter::LockedWriter()
-    : Writer()
-{
-}
-
-NBLog::LockedWriter::LockedWriter(void *shared, size_t size)
-    : Writer(shared, size)
-{
-}
-
-void NBLog::LockedWriter::log(const char *string)
-{
-    Mutex::Autolock _l(mLock);
-    Writer::log(string);
-}
-
-void NBLog::LockedWriter::logf(const char *fmt, ...)
-{
-    // FIXME should not take the lock until after formatting is done
-    Mutex::Autolock _l(mLock);
-    va_list ap;
-    va_start(ap, fmt);
-    Writer::logvf(fmt, ap);
-    va_end(ap);
-}
-
-void NBLog::LockedWriter::logvf(const char *fmt, va_list ap)
-{
-    // FIXME should not take the lock until after formatting is done
-    Mutex::Autolock _l(mLock);
-    Writer::logvf(fmt, ap);
-}
-
-void NBLog::LockedWriter::logTimestamp()
-{
-    // FIXME should not take the lock until after the clock_gettime() syscall
-    Mutex::Autolock _l(mLock);
-    Writer::logTimestamp();
-}
-
-void NBLog::LockedWriter::logTimestamp(const int64_t ts)
-{
-    Mutex::Autolock _l(mLock);
-    Writer::logTimestamp(ts);
-}
-
-void NBLog::LockedWriter::logInteger(const int x)
-{
-    Mutex::Autolock _l(mLock);
-    Writer::logInteger(x);
-}
-
-void NBLog::LockedWriter::logFloat(const float x)
-{
-    Mutex::Autolock _l(mLock);
-    Writer::logFloat(x);
-}
-
-void NBLog::LockedWriter::logPID()
-{
-    Mutex::Autolock _l(mLock);
-    Writer::logPID();
-}
-
-void NBLog::LockedWriter::logStart(const char *fmt)
-{
-    Mutex::Autolock _l(mLock);
-    Writer::logStart(fmt);
-}
-
-
-void NBLog::LockedWriter::logEnd()
-{
-    Mutex::Autolock _l(mLock);
-    Writer::logEnd();
-}
-
-void NBLog::LockedWriter::logHash(log_hash_t hash)
-{
-    Mutex::Autolock _l(mLock);
-    Writer::logHash(hash);
-}
-
-bool NBLog::LockedWriter::isEnabled() const
-{
-    Mutex::Autolock _l(mLock);
-    return Writer::isEnabled();
-}
-
-bool NBLog::LockedWriter::setEnabled(bool enabled)
-{
-    Mutex::Autolock _l(mLock);
-    return Writer::setEnabled(enabled);
-}
-
-// ---------------------------------------------------------------------------
-
-const std::set<NBLog::Event> NBLog::Reader::startingTypes {NBLog::Event::EVENT_START_FMT,
-        NBLog::Event::EVENT_HISTOGRAM_ENTRY_TS,
-        NBLog::Event::EVENT_AUDIO_STATE};
-const std::set<NBLog::Event> NBLog::Reader::endingTypes   {NBLog::Event::EVENT_END_FMT,
-        NBLog::Event::EVENT_HISTOGRAM_ENTRY_TS,
-        NBLog::Event::EVENT_AUDIO_STATE};
-
-NBLog::Reader::Reader(const void *shared, size_t size)
-    : mFd(-1), mIndent(0), mLost(0),
-      mShared((/*const*/ Shared *) shared), /*mIMemory*/
-      mFifo(mShared != NULL ?
-        new audio_utils_fifo(size, sizeof(uint8_t),
-            mShared->mBuffer, mShared->mRear, NULL /*throttlesFront*/) : NULL),
-      mFifoReader(mFifo != NULL ? new audio_utils_fifo_reader(*mFifo) : NULL)
-{
-}
-
-NBLog::Reader::Reader(const sp<IMemory>& iMemory, size_t size)
-    : Reader(iMemory != 0 ? (Shared *) iMemory->pointer() : NULL, size)
-{
-    mIMemory = iMemory;
-}
-
-NBLog::Reader::~Reader()
-{
-    delete mFifoReader;
-    delete mFifo;
-}
-
-const uint8_t *NBLog::Reader::findLastEntryOfTypes(const uint8_t *front, const uint8_t *back,
-                                            const std::set<Event> &types) {
-    while (back + Entry::kPreviousLengthOffset >= front) {
-        const uint8_t *prev = back - back[Entry::kPreviousLengthOffset] - Entry::kOverhead;
-        if (prev < front || prev + prev[offsetof(entry, length)] +
-                            Entry::kOverhead != back) {
-
-            // prev points to an out of limits or inconsistent entry
-            return nullptr;
-        }
-        if (types.find((const Event) prev[offsetof(entry, type)]) != types.end()) {
-            return prev;
-        }
-        back = prev;
-    }
-    return nullptr; // no entry found
-}
-
-// Copies content of a Reader FIFO into its Snapshot
-// The Snapshot has the same raw data, but represented as a sequence of entries
-// and an EntryIterator making it possible to process the data.
-std::unique_ptr<NBLog::Reader::Snapshot> NBLog::Reader::getSnapshot()
-{
-    if (mFifoReader == NULL) {
-        return std::unique_ptr<NBLog::Reader::Snapshot>(new Snapshot());
-    }
-    // make a copy to avoid race condition with writer
-    size_t capacity = mFifo->capacity();
-
-    // This emulates the behaviour of audio_utils_fifo_reader::read, but without incrementing the
-    // reader index. The index is incremented after handling corruption, to after the last complete
-    // entry of the buffer
-    size_t lost;
-    audio_utils_iovec iovec[2];
-    ssize_t availToRead = mFifoReader->obtain(iovec, capacity, NULL /*timeout*/, &lost);
-    if (availToRead <= 0) {
-        return std::unique_ptr<NBLog::Reader::Snapshot>(new Snapshot());
-    }
-
-    std::unique_ptr<Snapshot> snapshot(new Snapshot(availToRead));
-    memcpy(snapshot->mData, (const char *) mFifo->buffer() + iovec[0].mOffset, iovec[0].mLength);
-    if (iovec[1].mLength > 0) {
-        memcpy(snapshot->mData + (iovec[0].mLength),
-            (const char *) mFifo->buffer() + iovec[1].mOffset, iovec[1].mLength);
-    }
-
-    // Handle corrupted buffer
-    // Potentially, a buffer has corrupted data on both beginning (due to overflow) and end
-    // (due to incomplete format entry). But even if the end format entry is incomplete,
-    // it ends in a complete entry (which is not an END_FMT). So is safe to traverse backwards.
-    // TODO: handle client corruption (in the middle of a buffer)
-
-    const uint8_t *back = snapshot->mData + availToRead;
-    const uint8_t *front = snapshot->mData;
-
-    // Find last END_FMT. <back> is sitting on an entry which might be the middle of a FormatEntry.
-    // We go backwards until we find an EVENT_END_FMT.
-    const uint8_t *lastEnd = findLastEntryOfTypes(front, back, endingTypes);
-    if (lastEnd == nullptr) {
-        snapshot->mEnd = snapshot->mBegin = EntryIterator(front);
-    } else {
-        // end of snapshot points to after last END_FMT entry
-        snapshot->mEnd = EntryIterator(lastEnd).next();
-        // find first START_FMT
-        const uint8_t *firstStart = nullptr;
-        const uint8_t *firstStartTmp = snapshot->mEnd;
-        while ((firstStartTmp = findLastEntryOfTypes(front, firstStartTmp, startingTypes))
-                != nullptr) {
-            firstStart = firstStartTmp;
-        }
-        // firstStart is null if no START_FMT entry was found before lastEnd
-        if (firstStart == nullptr) {
-            snapshot->mBegin = snapshot->mEnd;
-        } else {
-            snapshot->mBegin = EntryIterator(firstStart);
-        }
-    }
-
-    // advance fifo reader index to after last entry read.
-    mFifoReader->release(snapshot->mEnd - front);
-
-    snapshot->mLost = lost;
-    return snapshot;
-
-}
-
-// Takes raw content of the local merger FIFO, processes log entries, and
-// writes the data to a map of class PerformanceAnalysis, based on their thread ID.
-void NBLog::MergeReader::getAndProcessSnapshot(NBLog::Reader::Snapshot &snapshot)
-{
-    String8 timestamp, body;
-
-    for (auto entry = snapshot.begin(); entry != snapshot.end();) {
-        switch (entry->type) {
-        case EVENT_START_FMT:
-            entry = handleFormat(FormatEntry(entry), &timestamp, &body);
-            break;
-        case EVENT_HISTOGRAM_ENTRY_TS: {
-            HistTsEntryWithAuthor *data = (HistTsEntryWithAuthor *) (entry->data);
-            // TODO This memcpies are here to avoid unaligned memory access crash.
-            // There's probably a more efficient way to do it
-            log_hash_t hash;
-            memcpy(&hash, &(data->hash), sizeof(hash));
-            int64_t ts;
-            memcpy(&ts, &data->ts, sizeof(ts));
-            // TODO: hash for histogram ts and audio state need to match
-            // and correspond to audio production source file location
-            mThreadPerformanceAnalysis[data->author][0 /*hash*/].logTsEntry(ts);
-            ++entry;
-            break;
-        }
-        case EVENT_AUDIO_STATE: {
-            HistTsEntryWithAuthor *data = (HistTsEntryWithAuthor *) (entry->data);
-            // TODO This memcpies are here to avoid unaligned memory access crash.
-            // There's probably a more efficient way to do it
-            log_hash_t hash;
-            memcpy(&hash, &(data->hash), sizeof(hash));
-            // TODO: remove ts if unused
-            int64_t ts;
-            memcpy(&ts, &data->ts, sizeof(ts));
-            mThreadPerformanceAnalysis[data->author][0 /*hash*/].handleStateChange();
-            ++entry;
-            break;
-        }
-        case EVENT_END_FMT:
-            body.appendFormat("warning: got to end format event");
-            ++entry;
-            break;
-        case EVENT_RESERVED:
-        default:
-            body.appendFormat("warning: unexpected event %d", entry->type);
-            ++entry;
-            break;
-        }
-    }
-    // FIXME: decide whether to print the warnings here or elsewhere
-    if (!body.isEmpty()) {
-        dumpLine(timestamp, body);
-    }
-}
-
-void NBLog::MergeReader::getAndProcessSnapshot()
-{
-    // get a snapshot, process it
-    std::unique_ptr<Snapshot> snap = getSnapshot();
-    getAndProcessSnapshot(*snap);
-}
-
-void NBLog::MergeReader::dump(int fd, int indent) {
-    // TODO: add a mutex around media.log dump
-    ReportPerformance::dump(fd, indent, mThreadPerformanceAnalysis);
-}
-
-// Writes a string to the console
-void NBLog::Reader::dumpLine(const String8 &timestamp, String8 &body)
-{
-    if (mFd >= 0) {
-        dprintf(mFd, "%.*s%s %s\n", mIndent, "", timestamp.string(), body.string());
-    } else {
-        ALOGI("%.*s%s %s", mIndent, "", timestamp.string(), body.string());
-    }
-    body.clear();
-}
-
-bool NBLog::Reader::isIMemory(const sp<IMemory>& iMemory) const
-{
-    return iMemory != 0 && mIMemory != 0 && iMemory->pointer() == mIMemory->pointer();
-}
-
-// ---------------------------------------------------------------------------
-
-void NBLog::appendTimestamp(String8 *body, const void *data) {
-    int64_t ts;
-    memcpy(&ts, data, sizeof(ts));
-    body->appendFormat("[%d.%03d]", (int) (ts / (1000 * 1000 * 1000)),
-                    (int) ((ts / (1000 * 1000)) % 1000));
-}
-
-void NBLog::appendInt(String8 *body, const void *data) {
-    int x = *((int*) data);
-    body->appendFormat("<%d>", x);
-}
-
-void NBLog::appendFloat(String8 *body, const void *data) {
-    float f;
-    memcpy(&f, data, sizeof(float));
-    body->appendFormat("<%f>", f);
-}
-
-void NBLog::appendPID(String8 *body, const void* data, size_t length) {
-    pid_t id = *((pid_t*) data);
-    char * name = &((char*) data)[sizeof(pid_t)];
-    body->appendFormat("<PID: %d, name: %.*s>", id, (int) (length - sizeof(pid_t)), name);
-}
-
-String8 NBLog::bufferDump(const uint8_t *buffer, size_t size)
-{
-    String8 str;
-    str.append("[ ");
-    for(size_t i = 0; i < size; i++)
-    {
-        str.appendFormat("%d ", buffer[i]);
-    }
-    str.append("]");
-    return str;
-}
-
-String8 NBLog::bufferDump(const EntryIterator &it)
-{
-    return bufferDump(it, it->length + Entry::kOverhead);
-}
-
-NBLog::EntryIterator NBLog::Reader::handleFormat(const FormatEntry &fmtEntry,
-                                                         String8 *timestamp,
-                                                         String8 *body) {
-    // log timestamp
-    int64_t ts = fmtEntry.timestamp();
-    timestamp->clear();
-    timestamp->appendFormat("[%d.%03d]", (int) (ts / (1000 * 1000 * 1000)),
-                    (int) ((ts / (1000 * 1000)) % 1000));
-
-    // log unique hash
-    log_hash_t hash = fmtEntry.hash();
-    // print only lower 16bit of hash as hex and line as int to reduce spam in the log
-    body->appendFormat("%.4X-%d ", (int)(hash >> 16) & 0xFFFF, (int) hash & 0xFFFF);
-
-    // log author (if present)
-    handleAuthor(fmtEntry, body);
-
-    // log string
-    NBLog::EntryIterator arg = fmtEntry.args();
-
-    const char* fmt = fmtEntry.formatString();
-    size_t fmt_length = fmtEntry.formatStringLength();
-
-    for (size_t fmt_offset = 0; fmt_offset < fmt_length; ++fmt_offset) {
-        if (fmt[fmt_offset] != '%') {
-            body->append(&fmt[fmt_offset], 1); // TODO optimize to write consecutive strings at once
-            continue;
-        }
-        // case "%%""
-        if (fmt[++fmt_offset] == '%') {
-            body->append("%");
-            continue;
-        }
-        // case "%\0"
-        if (fmt_offset == fmt_length) {
-            continue;
-        }
-
-        NBLog::Event event = (NBLog::Event) arg->type;
-        size_t length = arg->length;
-
-        // TODO check length for event type is correct
-
-        if (event == EVENT_END_FMT) {
-            break;
-        }
-
-        // TODO: implement more complex formatting such as %.3f
-        const uint8_t *datum = arg->data; // pointer to the current event args
-        switch(fmt[fmt_offset])
-        {
-        case 's': // string
-            ALOGW_IF(event != EVENT_STRING,
-                "NBLog Reader incompatible event for string specifier: %d", event);
-            body->append((const char*) datum, length);
-            break;
-
-        case 't': // timestamp
-            ALOGW_IF(event != EVENT_TIMESTAMP,
-                "NBLog Reader incompatible event for timestamp specifier: %d", event);
-            appendTimestamp(body, datum);
-            break;
-
-        case 'd': // integer
-            ALOGW_IF(event != EVENT_INTEGER,
-                "NBLog Reader incompatible event for integer specifier: %d", event);
-            appendInt(body, datum);
-            break;
-
-        case 'f': // float
-            ALOGW_IF(event != EVENT_FLOAT,
-                "NBLog Reader incompatible event for float specifier: %d", event);
-            appendFloat(body, datum);
-            break;
-
-        case 'p': // pid
-            ALOGW_IF(event != EVENT_PID,
-                "NBLog Reader incompatible event for pid specifier: %d", event);
-            appendPID(body, datum, length);
-            break;
-
-        default:
-            ALOGW("NBLog Reader encountered unknown character %c", fmt[fmt_offset]);
-        }
-        ++arg;
-    }
-    ALOGW_IF(arg->type != EVENT_END_FMT, "Expected end of format, got %d", arg->type);
-    ++arg;
-    return arg;
-}
-
-NBLog::Merger::Merger(const void *shared, size_t size):
-      mShared((Shared *) shared),
-      mFifo(mShared != NULL ?
-        new audio_utils_fifo(size, sizeof(uint8_t),
-            mShared->mBuffer, mShared->mRear, NULL /*throttlesFront*/) : NULL),
-      mFifoWriter(mFifo != NULL ? new audio_utils_fifo_writer(*mFifo) : NULL)
-      {}
-
-void NBLog::Merger::addReader(const NBLog::NamedReader &reader) {
-
-    // FIXME This is called by binder thread in MediaLogService::registerWriter
-    //       but the access to shared variable mNamedReaders is not yet protected by a lock.
-    mNamedReaders.push_back(reader);
-}
-
-// items placed in priority queue during merge
-// composed by a timestamp and the index of the snapshot where the timestamp came from
-struct MergeItem
-{
-    int64_t ts;
-    int index;
-    MergeItem(int64_t ts, int index): ts(ts), index(index) {}
-};
-
-// operators needed for priority queue in merge
-// bool operator>(const int64_t &t1, const int64_t &t2) {
-//     return t1.tv_sec > t2.tv_sec || (t1.tv_sec == t2.tv_sec && t1.tv_nsec > t2.tv_nsec);
-// }
-
-bool operator>(const struct MergeItem &i1, const struct MergeItem &i2) {
-    return i1.ts > i2.ts || (i1.ts == i2.ts && i1.index > i2.index);
-}
-
-// Merge registered readers, sorted by timestamp, and write data to a single FIFO in local memory
-void NBLog::Merger::merge() {
-    // FIXME This is called by merge thread
-    //       but the access to shared variable mNamedReaders is not yet protected by a lock.
-    int nLogs = mNamedReaders.size();
-    std::vector<std::unique_ptr<NBLog::Reader::Snapshot>> snapshots(nLogs);
-    std::vector<NBLog::EntryIterator> offsets(nLogs);
-    for (int i = 0; i < nLogs; ++i) {
-        snapshots[i] = mNamedReaders[i].reader()->getSnapshot();
-        offsets[i] = snapshots[i]->begin();
-    }
-    // initialize offsets
-    // TODO custom heap implementation could allow to update top, improving performance
-    // for bursty buffers
-    std::priority_queue<MergeItem, std::vector<MergeItem>, std::greater<MergeItem>> timestamps;
-    for (int i = 0; i < nLogs; ++i)
-    {
-        if (offsets[i] != snapshots[i]->end()) {
-            int64_t ts = AbstractEntry::buildEntry(offsets[i])->timestamp();
-            timestamps.emplace(ts, i);
-        }
-    }
-
-    while (!timestamps.empty()) {
-        // find minimum timestamp
-        int index = timestamps.top().index;
-        // copy it to the log, increasing offset
-        offsets[index] = AbstractEntry::buildEntry(offsets[index])->copyWithAuthor(mFifoWriter,
-                                                                                   index);
-        // update data structures
-        timestamps.pop();
-        if (offsets[index] != snapshots[index]->end()) {
-            int64_t ts = AbstractEntry::buildEntry(offsets[index])->timestamp();
-            timestamps.emplace(ts, index);
-        }
-    }
-}
-
-const std::vector<NBLog::NamedReader>& NBLog::Merger::getNamedReaders() const {
-    // FIXME This is returning a reference to a shared variable that needs a lock
-    return mNamedReaders;
-}
-
-// ---------------------------------------------------------------------------
-
-NBLog::MergeReader::MergeReader(const void *shared, size_t size, Merger &merger)
-    : Reader(shared, size), mNamedReaders(merger.getNamedReaders()) {}
-
-void NBLog::MergeReader::handleAuthor(const NBLog::AbstractEntry &entry, String8 *body) {
-    int author = entry.author();
-    // FIXME Needs a lock
-    const char* name = mNamedReaders[author].name();
-    body->appendFormat("%s: ", name);
-}
-
-// ---------------------------------------------------------------------------
-
-NBLog::MergeThread::MergeThread(NBLog::Merger &merger, NBLog::MergeReader &mergeReader)
-    : mMerger(merger),
-      mMergeReader(mergeReader),
-      mTimeoutUs(0) {}
-
-NBLog::MergeThread::~MergeThread() {
-    // set exit flag, set timeout to 0 to force threadLoop to exit and wait for the thread to join
-    requestExit();
-    setTimeoutUs(0);
-    join();
-}
-
-bool NBLog::MergeThread::threadLoop() {
-    bool doMerge;
-    {
-        AutoMutex _l(mMutex);
-        // If mTimeoutUs is negative, wait on the condition variable until it's positive.
-        // If it's positive, wait kThreadSleepPeriodUs and then merge
-        nsecs_t waitTime = mTimeoutUs > 0 ? kThreadSleepPeriodUs * 1000 : LLONG_MAX;
-        mCond.waitRelative(mMutex, waitTime);
-        doMerge = mTimeoutUs > 0;
-        mTimeoutUs -= kThreadSleepPeriodUs;
-    }
-    if (doMerge) {
-        // Merge data from all the readers
-        mMerger.merge();
-        // Process the data collected by mMerger and write it to PerformanceAnalysis
-        // FIXME: decide whether to call getAndProcessSnapshot every time
-        // or whether to have a separate thread that calls it with a lower frequency
-        mMergeReader.getAndProcessSnapshot();
-    }
-    return true;
-}
-
-void NBLog::MergeThread::wakeup() {
-    setTimeoutUs(kThreadWakeupPeriodUs);
-}
-
-void NBLog::MergeThread::setTimeoutUs(int time) {
-    AutoMutex _l(mMutex);
-    mTimeoutUs = time;
-    mCond.signal();
-}
-
-}   // namespace android
diff --git a/media/libnblog/PerformanceAnalysis.cpp b/media/libnblog/PerformanceAnalysis.cpp
index f09e93d..e91a511 100644
--- a/media/libnblog/PerformanceAnalysis.cpp
+++ b/media/libnblog/PerformanceAnalysis.cpp
@@ -17,13 +17,16 @@
 
 #define LOG_TAG "PerformanceAnalysis"
 // #define LOG_NDEBUG 0
+// #define WRITE_TO_FILE
 
 #include <algorithm>
 #include <climits>
 #include <deque>
-#include <iostream>
+#include <iomanip>
 #include <math.h>
 #include <numeric>
+#include <sstream>
+#include <string>
 #include <vector>
 #include <stdarg.h>
 #include <stdint.h>
@@ -32,20 +35,126 @@
 #include <sys/prctl.h>
 #include <time.h>
 #include <new>
+#include <audio_utils/LogPlot.h>
 #include <audio_utils/roundup.h>
 #include <media/nblog/NBLog.h>
 #include <media/nblog/PerformanceAnalysis.h>
 #include <media/nblog/ReportPerformance.h>
 #include <utils/Log.h>
 #include <utils/String8.h>
+#include <utils/Timers.h>
 
 #include <queue>
 #include <utility>
 
 namespace android {
-
 namespace ReportPerformance {
 
+void Histogram::add(double value)
+{
+    if (mBinSize <= 0 || mBins.size() < 2) {
+        return;
+    }
+    // TODO Handle domain and range error exceptions?
+    const int unboundedIndex = lround((value - mLow) / mBinSize) + 1;
+    // std::clamp is introduced in C++17
+    //const int index = std::clamp(unboundedIndex, 0, (int)(mBins.size() - 1));
+    const int index = std::max(0, std::min((int)(mBins.size() - 1), unboundedIndex));
+    mBins[index]++;
+    mTotalCount++;
+}
+
+void Histogram::clear()
+{
+    std::fill(mBins.begin(), mBins.end(), 0);
+    mTotalCount = 0;
+}
+
+uint64_t Histogram::totalCount() const
+{
+    return mTotalCount;
+}
+
+std::string Histogram::toString() const {
+    std::stringstream ss;
+    static constexpr char kDivider = '|';
+    ss << kVersion << "," << mBinSize << "," << mNumBins << "," << mLow << ",{";
+    bool first = true;
+    for (size_t i = 0; i < mBins.size(); i++) {
+        if (mBins[i] != 0) {
+            if (!first) {
+                ss << ",";
+            }
+            ss << static_cast<int>(i) - 1 << kDivider << mBins[i];
+            first = false;
+        }
+    }
+    ss << "}";
+
+    return ss.str();
+}
+
+std::string Histogram::asciiArtString(size_t indent) const {
+    if (totalCount() == 0 || mBinSize <= 0 || mBins.size() < 2) {
+        return "";
+    }
+
+    static constexpr char kMarker = '-';
+    // One increment is considered one step of a bin's height.
+    static constexpr size_t kMarkersPerIncrement = 2;
+    static constexpr size_t kMaxIncrements = 64 + 1;
+    static constexpr size_t kMaxNumberWidth = 7;
+    static const std::string kMarkers(kMarkersPerIncrement * kMaxIncrements, kMarker);
+    static const std::string kSpaces(kMarkersPerIncrement * kMaxIncrements, ' ');
+    // get the last n characters of s, or the whole string if it is shorter
+    auto getTail = [](const size_t n, const std::string &s) {
+        return s.c_str() + s.size() - std::min(n, s.size());
+    };
+
+    // Since totalCount() > 0, mBins is not empty and maxCount > 0.
+    const unsigned maxCount = *std::max_element(mBins.begin(), mBins.end());
+    const size_t maxIncrements = log2(maxCount) + 1;
+
+    std::stringstream ss;
+
+    // Non-zero bins must exist at this point because totalCount() > 0.
+    size_t firstNonZeroBin = 0;
+    // If firstNonZeroBin reaches mBins.size() - 1, then it must be a nonzero bin.
+    for (; firstNonZeroBin < mBins.size() - 1 && mBins[firstNonZeroBin] == 0; firstNonZeroBin++) {}
+    const size_t firstBinToPrint = firstNonZeroBin == 0 ? 0 : firstNonZeroBin - 1;
+
+    size_t lastNonZeroBin = mBins.size() - 1;
+    // If lastNonZeroBin reaches 0, then it must be a nonzero bin.
+    for (; lastNonZeroBin > 0 && mBins[lastNonZeroBin] == 0; lastNonZeroBin--) {}
+    const size_t lastBinToPrint = lastNonZeroBin == mBins.size() - 1 ? lastNonZeroBin
+            : lastNonZeroBin + 1;
+
+    for (size_t bin = firstBinToPrint; bin <= lastBinToPrint; bin++) {
+        ss << std::setw(indent + kMaxNumberWidth);
+        if (bin == 0) {
+            ss << "<";
+        } else if (bin == mBins.size() - 1) {
+            ss << ">";
+        } else {
+            ss << mLow + (bin - 1) * mBinSize;
+        }
+        ss << " |";
+        size_t increments = 0;
+        const uint64_t binCount = mBins[bin];
+        if (binCount > 0) {
+            increments = log2(binCount) + 1;
+            ss << getTail(increments * kMarkersPerIncrement, kMarkers);
+        }
+        ss << getTail((maxIncrements - increments + 1) * kMarkersPerIncrement, kSpaces)
+                << binCount << "\n";
+    }
+    ss << "\n";
+
+    return ss.str();
+}
+
+//------------------------------------------------------------------------------
+
 // Given an audio processing wakeup timestamp, buckets the time interval
 // since the previous timestamp into a histogram, searches for
 // outliers, analyzes the outlier series for unexpectedly
@@ -208,27 +317,6 @@
     return isOutlier;
 }
 
-static int widthOf(int x) {
-    int width = 0;
-    if (x < 0) {
-        width++;
-        x = x == INT_MIN ? INT_MAX : -x;
-    }
-    // assert (x >= 0)
-    do {
-        ++width;
-        x /= 10;
-    } while (x > 0);
-    return width;
-}
-
-// computes the column width required for a specific histogram value
-inline int numberWidth(double number, int leftPadding) {
-    // Added values account for whitespaces needed around numbers, and for the
-    // dot and decimal digit not accounted for by widthOf
-    return std::max(std::max(widthOf(static_cast<int>(number)) + 3, 2), leftPadding + 1);
-}
-
 // rounds value to precision based on log-distance from mean
 __attribute__((no_sanitize("signed-integer-overflow")))
 inline double logRound(double x, double mean) {
@@ -254,7 +342,7 @@
 // of PerformanceAnalysis
 void PerformanceAnalysis::reportPerformance(String8 *body, int author, log_hash_t hash,
                                             int maxHeight) {
-    if (mHists.empty()) {
+    if (mHists.empty() || body == nullptr) {
         return;
     }
 
@@ -273,69 +361,16 @@
         }
     }
 
-    // underscores and spaces length corresponds to maximum width of histogram
-    static const int kLen = 200;
-    std::string underscores(kLen, '_');
-    std::string spaces(kLen, ' ');
-
-    auto it = buckets.begin();
-    double maxDelta = it->first;
-    int maxCount = it->second;
-    // Compute maximum values
-    while (++it != buckets.end()) {
-        if (it->first > maxDelta) {
-            maxDelta = it->first;
-        }
-        if (it->second > maxCount) {
-            maxCount = it->second;
-        }
-    }
-    int height = log2(maxCount) + 1; // maxCount > 0, safe to call log2
-    const int leftPadding = widthOf(1 << height);
-    const int bucketWidth = numberWidth(maxDelta, leftPadding);
-    int scalingFactor = 1;
-    // scale data if it exceeds maximum height
-    if (height > maxHeight) {
-        scalingFactor = (height + maxHeight) / maxHeight;
-        height /= scalingFactor;
-    }
-    body->appendFormat("\n%*s %3.2f %s", leftPadding + 11,
-            "Occurrences in", (elapsedMs / kMsPerSec), "seconds of audio:");
-    body->appendFormat("\n%*s%d, %lld, %lld\n", leftPadding + 11,
+    static const int SIZE = 128;
+    char title[SIZE];
+    snprintf(title, sizeof(title), "\n%s %3.2f %s\n%s%d, %lld, %lld\n",
+            "Occurrences in", (elapsedMs / kMsPerSec), "seconds of audio:",
             "Thread, hash, starting timestamp: ", author,
-            static_cast<long long int>(hash), static_cast<long long int>(startingTs));
-    // write histogram label line with bucket values
-    body->appendFormat("\n%s", " ");
-    body->appendFormat("%*s", leftPadding, " ");
-    for (auto const &x : buckets) {
-        const int colWidth = numberWidth(x.first, leftPadding);
-        body->appendFormat("%*d", colWidth, x.second);
-    }
-    // write histogram ascii art
-    body->appendFormat("\n%s", " ");
-    for (int row = height * scalingFactor; row >= 0; row -= scalingFactor) {
-        const int value = 1 << row;
-        body->appendFormat("%.*s", leftPadding, spaces.c_str());
-        for (auto const &x : buckets) {
-            const int colWidth = numberWidth(x.first, leftPadding);
-            body->appendFormat("%.*s%s", colWidth - 1,
-                               spaces.c_str(), x.second < value ? " " : "|");
-        }
-        body->appendFormat("\n%s", " ");
-    }
-    // print x-axis
-    const int columns = static_cast<int>(buckets.size());
-    body->appendFormat("%*c", leftPadding, ' ');
-    body->appendFormat("%.*s", (columns + 1) * bucketWidth, underscores.c_str());
-    body->appendFormat("\n%s", " ");
+            static_cast<long long>(hash), static_cast<long long>(startingTs));
+    static const char * const kLabel = "ms";
 
-    // write footer with bucket labels
-    body->appendFormat("%*s", leftPadding, " ");
-    for (auto const &x : buckets) {
-        const int colWidth = numberWidth(x.first, leftPadding);
-        body->appendFormat("%*.*f", colWidth, 1, x.first);
-    }
-    body->appendFormat("%.*s%s", bucketWidth, spaces.c_str(), "ms\n");
+    body->appendFormat("%s",
+            audio_utils_plot_histogram(buckets, title, kLabel, maxHeight).c_str());
 
     // Now report glitches
     body->appendFormat("\ntime elapsed between glitches and glitch timestamps:\n");
@@ -350,7 +385,9 @@
 // writes summary of performance into specified file descriptor
 void dump(int fd, int indent, PerformanceAnalysisMap &threadPerformanceAnalysis) {
     String8 body;
+#ifdef WRITE_TO_FILE
     const char* const kDirectory = "/data/misc/audioserver/";
+#endif
     for (auto & thread : threadPerformanceAnalysis) {
         for (auto & hash: thread.second) {
             PerformanceAnalysis& curr = hash.second;
@@ -360,9 +397,11 @@
                 dumpLine(fd, indent, body);
                 body.clear();
             }
-            // write to file
+#ifdef WRITE_TO_FILE
+            // write to file. Enable by uncommenting macro at top of file.
             writeToFile(curr.mHists, curr.mOutlierData, curr.mPeakTimestamps,
                         kDirectory, false, thread.first, hash.first);
+#endif
         }
     }
 }
@@ -374,5 +413,4 @@
 }
 
 } // namespace ReportPerformance
-
 }   // namespace android
diff --git a/media/libnblog/Reader.cpp b/media/libnblog/Reader.cpp
new file mode 100644
index 0000000..f556e37
--- /dev/null
+++ b/media/libnblog/Reader.cpp
@@ -0,0 +1,445 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "NBLog"
+//#define LOG_NDEBUG 0
+
+#include <memory>
+#include <stddef.h>
+#include <string>
+#include <unordered_set>
+
+#include <audio_utils/fifo.h>
+#include <binder/IMemory.h>
+#include <media/nblog/Entry.h>
+#include <media/nblog/Events.h>
+#include <media/nblog/Reader.h>
+#include <media/nblog/Timeline.h>
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+namespace android {
+namespace NBLog {
+
+Reader::Reader(const void *shared, size_t size, const std::string &name)
+    : mName(name),
+      mShared((/*const*/ Shared *) shared), /*mIMemory*/
+      mFifo(mShared != NULL ?
+        new audio_utils_fifo(size, sizeof(uint8_t),
+            mShared->mBuffer, mShared->mRear, NULL /*throttlesFront*/) : NULL),
+      mFifoReader(mFifo != NULL ? new audio_utils_fifo_reader(*mFifo) : NULL)
+{
+}
+
+Reader::Reader(const sp<IMemory>& iMemory, size_t size, const std::string &name)
+    : Reader(iMemory != 0 ? (Shared *) iMemory->pointer() : NULL, size, name)
+{
+    mIMemory = iMemory;
+}
+
+Reader::~Reader()
+{
+    delete mFifoReader;
+    delete mFifo;
+}
+
+// Copies content of a Reader FIFO into its Snapshot
+// The Snapshot has the same raw data, but represented as a sequence of entries
+// and an EntryIterator making it possible to process the data.
+std::unique_ptr<Snapshot> Reader::getSnapshot(bool flush)
+{
+    if (mFifoReader == NULL) {
+        return std::unique_ptr<Snapshot>(new Snapshot());
+    }
+
+    // This emulates the behaviour of audio_utils_fifo_reader::read, but without incrementing the
+    // reader index. The index is incremented after handling corruption, to after the last complete
+    // entry of the buffer
+    size_t lost = 0;
+    audio_utils_iovec iovec[2];
+    const size_t capacity = mFifo->capacity();
+    ssize_t availToRead;
+    // A call to audio_utils_fifo_reader::obtain() places the read pointer one buffer length
+    // before the writer's pointer (since mFifoReader was constructed with flush=false). The
+    // do while loop is an attempt to read all of the FIFO's contents regardless of how behind
+    // the reader is with respect to the writer. However, the following scheduling sequence is
+    // possible and can lead to a starvation situation:
+    // - Writer T1 writes, overrun with respect to Reader T2
+    // - T2 calls obtain() and gets EOVERFLOW, T2 ptr placed one buffer size behind T1 ptr
+    // - T1 write, overrun
+    // - T2 obtain(), EOVERFLOW (and so on...)
+    // To address this issue, we limit the number of tries for the reader to catch up with
+    // the writer.
+    int tries = 0;
+    size_t lostTemp;
+    do {
+        availToRead = mFifoReader->obtain(iovec, capacity, NULL /*timeout*/, &lostTemp);
+        lost += lostTemp;
+    } while (availToRead < 0 || ++tries <= kMaxObtainTries);
+
+    if (availToRead <= 0) {
+        ALOGW_IF(availToRead < 0, "NBLog Reader %s failed to catch up with Writer", mName.c_str());
+        return std::unique_ptr<Snapshot>(new Snapshot());
+    }
+
+    // Change to #if 1 for debugging. This statement is useful for checking buffer fullness levels
+    // (as seen by reader) and how much data was lost. If you find that the fullness level is
+    // getting close to full, or that data loss is happening to often, then you should
+    // probably try some of the following:
+    // - log less data
+    // - log less often
+    // - increase the initial shared memory allocation for the buffer
+#if 0
+    ALOGD("getSnapshot name=%s, availToRead=%zd, capacity=%zu, fullness=%.3f, lost=%zu",
+            name().c_str(), availToRead, capacity, (double)availToRead / (double)capacity, lost);
+#endif
+    std::unique_ptr<Snapshot> snapshot(new Snapshot(availToRead));
+    memcpy(snapshot->mData, (const char *) mFifo->buffer() + iovec[0].mOffset, iovec[0].mLength);
+    if (iovec[1].mLength > 0) {
+        memcpy(snapshot->mData + (iovec[0].mLength),
+                (const char *) mFifo->buffer() + iovec[1].mOffset, iovec[1].mLength);
+    }
+
+    // Handle corrupted buffer
+    // Potentially, a buffer has corrupted data on both beginning (due to overflow) and end
+    // (due to incomplete format entry). But even if the end format entry is incomplete,
+    // it ends in a complete entry (which is not an FMT_END). So is safe to traverse backwards.
+    // TODO: handle client corruption (in the middle of a buffer)
+
+    const uint8_t *back = snapshot->mData + availToRead;
+    const uint8_t *front = snapshot->mData;
+
+    // Find last FMT_END. <back> is sitting on an entry which might be the middle of a FormatEntry.
+    // We go backwards until we find an EVENT_FMT_END.
+    const uint8_t *lastEnd = findLastValidEntry(front, back, invalidEndTypes);
+    if (lastEnd == nullptr) {
+        snapshot->mEnd = snapshot->mBegin = EntryIterator(front);
+    } else {
+        // end of snapshot points to after last FMT_END entry
+        snapshot->mEnd = EntryIterator(lastEnd).next();
+        // find first FMT_START
+        const uint8_t *firstStart = nullptr;
+        const uint8_t *firstStartTmp = snapshot->mEnd;
+        while ((firstStartTmp = findLastValidEntry(front, firstStartTmp, invalidBeginTypes))
+                != nullptr) {
+            firstStart = firstStartTmp;
+        }
+        // firstStart is null if no FMT_START entry was found before lastEnd
+        if (firstStart == nullptr) {
+            snapshot->mBegin = snapshot->mEnd;
+        } else {
+            snapshot->mBegin = EntryIterator(firstStart);
+        }
+    }
+
+    // advance fifo reader index to after last entry read.
+    if (flush) {
+        mFifoReader->release(snapshot->mEnd - front);
+    }
+
+    snapshot->mLost = lost;
+    return snapshot;
+}
+
+bool Reader::isIMemory(const sp<IMemory>& iMemory) const
+{
+    return iMemory != 0 && mIMemory != 0 && iMemory->pointer() == mIMemory->pointer();
+}
+
+// We make a set of the invalid types rather than the valid types when aligning
+// Snapshot EntryIterators to valid entries during log corruption checking.
+// This is done in order to avoid the maintenance overhead of adding a new Event
+// type to the two sets below whenever a new Event type is created, as it is
+// very likely that new types added will be valid types.
+// Currently, invalidBeginTypes and invalidEndTypes are used to handle the special
+// case of a Format Entry, which consists of a variable number of simple log entries.
+// If a new Event is added that consists of a variable number of simple log entries,
+// then these sets need to be updated.
+
+// We want the beginning of a Snapshot to point to an entry that is not in
+// the middle of a formatted entry and not an FMT_END.
+const std::unordered_set<Event> Reader::invalidBeginTypes {
+    EVENT_FMT_AUTHOR,
+    EVENT_FMT_END,
+    EVENT_FMT_FLOAT,
+    EVENT_FMT_HASH,
+    EVENT_FMT_INTEGER,
+    EVENT_FMT_PID,
+    EVENT_FMT_STRING,
+    EVENT_FMT_TIMESTAMP,
+};
+
+// We want the end of a Snapshot to point to an entry that is not in
+// the middle of a formatted entry and not a FMT_START.
+const std::unordered_set<Event> Reader::invalidEndTypes {
+    EVENT_FMT_AUTHOR,
+    EVENT_FMT_FLOAT,
+    EVENT_FMT_HASH,
+    EVENT_FMT_INTEGER,
+    EVENT_FMT_PID,
+    EVENT_FMT_START,
+    EVENT_FMT_STRING,
+    EVENT_FMT_TIMESTAMP,
+};
+
+const uint8_t *Reader::findLastValidEntry(const uint8_t *front, const uint8_t *back,
+                                          const std::unordered_set<Event> &invalidTypes) {
+    if (front == nullptr || back == nullptr) {
+        return nullptr;
+    }
+    while (back + Entry::kPreviousLengthOffset >= front) {
+        const uint8_t *prev = back - back[Entry::kPreviousLengthOffset] - Entry::kOverhead;
+        const Event type = (const Event)prev[offsetof(entry, type)];
+        if (prev < front
+                || prev + prev[offsetof(entry, length)] + Entry::kOverhead != back
+                || type <= EVENT_RESERVED || type >= EVENT_UPPER_BOUND) {
+            // prev points to an out of limits or inconsistent entry
+            return nullptr;
+        }
+        // if invalidTypes does not contain the type, then the type is valid.
+        if (invalidTypes.find(type) == invalidTypes.end()) {
+            return prev;
+        }
+        back = prev;
+    }
+    return nullptr; // no entry found
+}
+
+// TODO for future compatibility, would prefer to have a dump() go to string, and then go
+// to fd only when invoked through binder.
+void DumpReader::dump(int fd, size_t indent)
+{
+    if (fd < 0) return;
+    std::unique_ptr<Snapshot> snapshot = getSnapshot(false /*flush*/);
+    if (snapshot == nullptr) {
+        return;
+    }
+    String8 timestamp, body;
+
+    // TODO all logged types should have a printable format.
+    // TODO can we make the printing generic?
+    for (EntryIterator it = snapshot->begin(); it != snapshot->end(); ++it) {
+        switch (it->type) {
+        case EVENT_FMT_START:
+            it = handleFormat(FormatEntry(it), &timestamp, &body);
+            break;
+        case EVENT_LATENCY: {
+            const double latencyMs = it.payload<double>();
+            body.appendFormat("EVENT_LATENCY,%.3f", latencyMs);
+        } break;
+        case EVENT_OVERRUN: {
+            const int64_t ts = it.payload<int64_t>();
+            body.appendFormat("EVENT_OVERRUN,%lld", static_cast<long long>(ts));
+        } break;
+        case EVENT_THREAD_INFO: {
+            const thread_info_t info = it.payload<thread_info_t>();
+            body.appendFormat("EVENT_THREAD_INFO,%d,%s", static_cast<int>(info.id),
+                    threadTypeToString(info.type));
+        } break;
+        case EVENT_UNDERRUN: {
+            const int64_t ts = it.payload<int64_t>();
+            body.appendFormat("EVENT_UNDERRUN,%lld", static_cast<long long>(ts));
+        } break;
+        case EVENT_WARMUP_TIME: {
+            const double timeMs = it.payload<double>();
+            body.appendFormat("EVENT_WARMUP_TIME,%.3f", timeMs);
+        } break;
+        case EVENT_WORK_TIME: {
+            const int64_t monotonicNs = it.payload<int64_t>();
+            body.appendFormat("EVENT_WORK_TIME,%lld", static_cast<long long>(monotonicNs));
+        } break;
+        case EVENT_THREAD_PARAMS: {
+            const thread_params_t params = it.payload<thread_params_t>();
+            body.appendFormat("EVENT_THREAD_PARAMS,%zu,%u", params.frameCount, params.sampleRate);
+        } break;
+        case EVENT_FMT_END:
+        case EVENT_RESERVED:
+        case EVENT_UPPER_BOUND:
+            body.appendFormat("warning: unexpected event %d", it->type);
+            break;
+        default:
+            break;
+        }
+        if (!body.isEmpty()) {
+            dprintf(fd, "%.*s%s %s\n", (int)indent, "", timestamp.string(), body.string());
+            body.clear();
+        }
+        timestamp.clear();
+    }
+}
+
+EntryIterator DumpReader::handleFormat(const FormatEntry &fmtEntry,
+        String8 *timestamp, String8 *body)
+{
+    String8 timestampLocal;
+    String8 bodyLocal;
+    if (timestamp == nullptr) {
+        timestamp = &timestampLocal;
+    }
+    if (body == nullptr) {
+        body = &bodyLocal;
+    }
+
+    // log timestamp
+    const int64_t ts = fmtEntry.timestamp();
+    timestamp->clear();
+    timestamp->appendFormat("[%d.%03d]", (int) (ts / (1000 * 1000 * 1000)),
+                    (int) ((ts / (1000 * 1000)) % 1000));
+
+    // log unique hash
+    log_hash_t hash = fmtEntry.hash();
+    // print only lower 16bit of hash as hex and line as int to reduce spam in the log
+    body->appendFormat("%.4X-%d ", (int)(hash >> 16) & 0xFFFF, (int) hash & 0xFFFF);
+
+    // log author (if present)
+    handleAuthor(fmtEntry, body);
+
+    // log string
+    EntryIterator arg = fmtEntry.args();
+
+    const char* fmt = fmtEntry.formatString();
+    size_t fmt_length = fmtEntry.formatStringLength();
+
+    for (size_t fmt_offset = 0; fmt_offset < fmt_length; ++fmt_offset) {
+        if (fmt[fmt_offset] != '%') {
+            body->append(&fmt[fmt_offset], 1); // TODO optimize to write consecutive strings at once
+            continue;
+        }
+        // case "%%""
+        if (fmt[++fmt_offset] == '%') {
+            body->append("%");
+            continue;
+        }
+        // case "%\0"
+        if (fmt_offset == fmt_length) {
+            continue;
+        }
+
+        Event event = (Event) arg->type;
+        size_t length = arg->length;
+
+        // TODO check length for event type is correct
+
+        if (event == EVENT_FMT_END) {
+            break;
+        }
+
+        // TODO: implement more complex formatting such as %.3f
+        const uint8_t *datum = arg->data; // pointer to the current event args
+        switch(fmt[fmt_offset])
+        {
+        case 's': // string
+            ALOGW_IF(event != EVENT_FMT_STRING,
+                "NBLog Reader incompatible event for string specifier: %d", event);
+            body->append((const char*) datum, length);
+            break;
+
+        case 't': // timestamp
+            ALOGW_IF(event != EVENT_FMT_TIMESTAMP,
+                "NBLog Reader incompatible event for timestamp specifier: %d", event);
+            appendTimestamp(body, datum);
+            break;
+
+        case 'd': // integer
+            ALOGW_IF(event != EVENT_FMT_INTEGER,
+                "NBLog Reader incompatible event for integer specifier: %d", event);
+            appendInt(body, datum);
+            break;
+
+        case 'f': // float
+            ALOGW_IF(event != EVENT_FMT_FLOAT,
+                "NBLog Reader incompatible event for float specifier: %d", event);
+            appendFloat(body, datum);
+            break;
+
+        case 'p': // pid
+            ALOGW_IF(event != EVENT_FMT_PID,
+                "NBLog Reader incompatible event for pid specifier: %d", event);
+            appendPID(body, datum, length);
+            break;
+
+        default:
+            ALOGW("NBLog Reader encountered unknown character %c", fmt[fmt_offset]);
+        }
+        ++arg;
+    }
+    ALOGW_IF(arg->type != EVENT_FMT_END, "Expected end of format, got %d", arg->type);
+    return arg;
+}
+
+void DumpReader::appendInt(String8 *body, const void *data)
+{
+    if (body == nullptr || data == nullptr) {
+        return;
+    }
+    //int x = *((int*) data);
+    int x;
+    memcpy(&x, data, sizeof(x));
+    body->appendFormat("<%d>", x);
+}
+
+void DumpReader::appendFloat(String8 *body, const void *data)
+{
+    if (body == nullptr || data == nullptr) {
+        return;
+    }
+    float f;
+    memcpy(&f, data, sizeof(f));
+    body->appendFormat("<%f>", f);
+}
+
+void DumpReader::appendPID(String8 *body, const void* data, size_t length)
+{
+    if (body == nullptr || data == nullptr) {
+        return;
+    }
+    pid_t id = *((pid_t*) data);
+    char * name = &((char*) data)[sizeof(pid_t)];
+    body->appendFormat("<PID: %d, name: %.*s>", id, (int) (length - sizeof(pid_t)), name);
+}
+
+void DumpReader::appendTimestamp(String8 *body, const void *data)
+{
+    if (body == nullptr || data == nullptr) {
+        return;
+    }
+    int64_t ts;
+    memcpy(&ts, data, sizeof(ts));
+    body->appendFormat("[%d.%03d]", (int) (ts / (1000 * 1000 * 1000)),
+                    (int) ((ts / (1000 * 1000)) % 1000));
+}
+
+String8 DumpReader::bufferDump(const uint8_t *buffer, size_t size)
+{
+    String8 str;
+    if (buffer == nullptr) {
+        return str;
+    }
+    str.append("[ ");
+    for(size_t i = 0; i < size; i++) {
+        str.appendFormat("%d ", buffer[i]);
+    }
+    str.append("]");
+    return str;
+}
+
+String8 DumpReader::bufferDump(const EntryIterator &it)
+{
+    return bufferDump(it, it->length + Entry::kOverhead);
+}
+
+}   // namespace NBLog
+}   // namespace android
diff --git a/media/libnblog/ReportPerformance.cpp b/media/libnblog/ReportPerformance.cpp
index 827e731..b050b83 100644
--- a/media/libnblog/ReportPerformance.cpp
+++ b/media/libnblog/ReportPerformance.cpp
@@ -15,9 +15,11 @@
  */
 
 #define LOG_TAG "ReportPerformance"
+//#define LOG_NDEBUG 0
 
 #include <fstream>
 #include <iostream>
+#include <memory>
 #include <queue>
 #include <stdarg.h>
 #include <stdint.h>
@@ -27,23 +29,195 @@
 #include <sys/prctl.h>
 #include <sys/time.h>
 #include <utility>
-#include <media/nblog/NBLog.h>
+#include <json/json.h>
+#include <media/MediaAnalyticsItem.h>
+#include <media/nblog/Events.h>
 #include <media/nblog/PerformanceAnalysis.h>
 #include <media/nblog/ReportPerformance.h>
 #include <utils/Log.h>
 #include <utils/String8.h>
 
 namespace android {
-
 namespace ReportPerformance {
 
+static std::unique_ptr<Json::Value> dumpToJson(const PerformanceData& data)
+{
+    std::unique_ptr<Json::Value> rootPtr = std::make_unique<Json::Value>(Json::objectValue);
+    Json::Value& root = *rootPtr;
+    root["ioHandle"] = data.threadInfo.id;
+    root["type"] = NBLog::threadTypeToString(data.threadInfo.type);
+    root["frameCount"] = (Json::Value::Int)data.threadParams.frameCount;
+    root["sampleRate"] = (Json::Value::Int)data.threadParams.sampleRate;
+    root["workMsHist"] = data.workHist.toString();
+    root["latencyMsHist"] = data.latencyHist.toString();
+    root["warmupMsHist"] = data.warmupHist.toString();
+    root["underruns"] = (Json::Value::Int64)data.underruns;
+    root["overruns"] = (Json::Value::Int64)data.overruns;
+    root["activeMs"] = (Json::Value::Int64)ns2ms(data.active);
+    root["durationMs"] = (Json::Value::Int64)ns2ms(systemTime() - data.start);
+    return rootPtr;
+}
+
+static std::string dumpHistogramsToString(const PerformanceData& data)
+{
+    std::stringstream ss;
+    ss << "==========================================\n";
+    ss << "Thread type=" << NBLog::threadTypeToString(data.threadInfo.type)
+            << " handle=" << data.threadInfo.id
+            << " sampleRate=" << data.threadParams.sampleRate
+            << " frameCount=" << data.threadParams.frameCount << "\n";
+    ss << "  Thread work times in ms:\n" << data.workHist.asciiArtString(4 /*indent*/);
+    ss << "  Thread latencies in ms:\n" << data.latencyHist.asciiArtString(4 /*indent*/);
+    ss << "  Thread warmup times in ms:\n" << data.warmupHist.asciiArtString(4 /*indent*/);
+    return ss.str();
+}
+
+void dumpJson(int fd, const std::map<int, PerformanceData>& threadDataMap)
+{
+    if (fd < 0) {
+        return;
+    }
+
+    Json::Value root(Json::arrayValue);
+    for (const auto& item : threadDataMap) {
+        const ReportPerformance::PerformanceData& data = item.second;
+        // Skip threads that do not have performance data recorded yet.
+        if (data.empty()) {
+            continue;
+        }
+        std::unique_ptr<Json::Value> dataJson = ReportPerformance::dumpToJson(data);
+        if (dataJson == nullptr) {
+            continue;
+        }
+        (*dataJson)["threadNum"] = item.first;
+        root.append(*dataJson);
+    }
+    Json::StyledWriter writer;
+    std::string rootStr = writer.write(root);
+    write(fd, rootStr.c_str(), rootStr.size());
+}
+
+void dumpPlots(int fd, const std::map<int, PerformanceData>& threadDataMap)
+{
+    if (fd < 0) {
+        return;
+    }
+
+    for (const auto &item : threadDataMap) {
+        const ReportPerformance::PerformanceData& data = item.second;
+        if (data.empty()) {
+            continue;
+        }
+        std::string hists = ReportPerformance::dumpHistogramsToString(data);
+        write(fd, hists.c_str(), hists.size());
+    }
+}
+
+static std::string dumpRetroString(const PerformanceData& data, int64_t now)
+{
+    std::stringstream ss;
+    ss << NBLog::threadTypeToString(data.threadInfo.type) << "," << data.threadInfo.id << "\n";
+    for (const auto &item : data.snapshots) {
+        // TODO use an enum to string conversion method. One good idea:
+        // https://stackoverflow.com/a/238157
+        if (item.first == NBLog::EVENT_UNDERRUN) {
+            ss << "EVENT_UNDERRUN,";
+        } else if (item.first == NBLog::EVENT_OVERRUN) {
+            ss << "EVENT_OVERRUN,";
+        }
+        ss << now - item.second << "\n";
+    }
+    ss << "\n";
+    return ss.str();
+}
+
+void dumpRetro(int fd, const std::map<int, PerformanceData>& threadDataMap)
+{
+    if (fd < 0) {
+        return;
+    }
+
+    const nsecs_t now = systemTime();
+    for (const auto &item : threadDataMap) {
+        const ReportPerformance::PerformanceData& data = item.second;
+        if (data.snapshots.empty()) {
+            continue;
+        }
+        const std::string retroStr = dumpRetroString(data, now);
+        write(fd, retroStr.c_str(), retroStr.size());
+    }
+}
+
+bool sendToMediaMetrics(const PerformanceData& data)
+{
+    // See documentation for these metrics here:
+    // docs.google.com/document/d/11--6dyOXVOpacYQLZiaOY5QVtQjUyqNx2zT9cCzLKYE/edit?usp=sharing
+    static constexpr char kThreadType[] = "android.media.audiothread.type";
+    static constexpr char kThreadFrameCount[] = "android.media.audiothread.framecount";
+    static constexpr char kThreadSampleRate[] = "android.media.audiothread.samplerate";
+    static constexpr char kThreadWorkHist[] = "android.media.audiothread.workMs.hist";
+    static constexpr char kThreadLatencyHist[] = "android.media.audiothread.latencyMs.hist";
+    static constexpr char kThreadWarmupHist[] = "android.media.audiothread.warmupMs.hist";
+    static constexpr char kThreadUnderruns[] = "android.media.audiothread.underruns";
+    static constexpr char kThreadOverruns[] = "android.media.audiothread.overruns";
+    static constexpr char kThreadActive[] = "android.media.audiothread.activeMs";
+    static constexpr char kThreadDuration[] = "android.media.audiothread.durationMs";
+
+    // Currently, we only allow FastMixer thread data to be sent to Media Metrics.
+    if (data.threadInfo.type != NBLog::FASTMIXER) {
+        return false;
+    }
+
+    std::unique_ptr<MediaAnalyticsItem> item(MediaAnalyticsItem::create("audiothread"));
+
+    const Histogram &workHist = data.workHist;
+    if (workHist.totalCount() > 0) {
+        item->setCString(kThreadWorkHist, workHist.toString().c_str());
+    }
+
+    const Histogram &latencyHist = data.latencyHist;
+    if (latencyHist.totalCount() > 0) {
+        item->setCString(kThreadLatencyHist, latencyHist.toString().c_str());
+    }
+
+    const Histogram &warmupHist = data.warmupHist;
+    if (warmupHist.totalCount() > 0) {
+        item->setCString(kThreadWarmupHist, warmupHist.toString().c_str());
+    }
+
+    if (data.underruns > 0) {
+        item->setInt64(kThreadUnderruns, data.underruns);
+    }
+
+    if (data.overruns > 0) {
+        item->setInt64(kThreadOverruns, data.overruns);
+    }
+
+    // Send to Media Metrics if the record is not empty.
+    // The thread and time info are added inside the if statement because
+    // we want to send them only if there are performance metrics to send.
+    if (item->count() > 0) {
+        // Add thread info fields.
+        const char * const typeString = NBLog::threadTypeToString(data.threadInfo.type);
+        item->setCString(kThreadType, typeString);
+        item->setInt32(kThreadFrameCount, data.threadParams.frameCount);
+        item->setInt32(kThreadSampleRate, data.threadParams.sampleRate);
+        // Add time info fields.
+        item->setInt64(kThreadActive, data.active / 1000000);
+        item->setInt64(kThreadDuration, (systemTime() - data.start) / 1000000);
+        return item->selfrecord();
+    }
+    return false;
+}
+
+//------------------------------------------------------------------------------
 
 // TODO: use a function like this to extract logic from writeToFile
 // https://stackoverflow.com/a/9279620
 
 // Writes outlier intervals, timestamps, and histograms spanning long time intervals to file.
 // TODO: write data in binary format
-void writeToFile(const std::deque<std::pair<timestamp, Histogram>> &hists,
+void writeToFile(const std::deque<std::pair<timestamp, Hist>> &hists,
                  const std::deque<std::pair<msInterval, timestamp>> &outlierData,
                  const std::deque<timestamp> &peakTimestamps,
                  const char * directory, bool append, int author, log_hash_t hash) {
@@ -128,6 +302,5 @@
     pfs.close();
 }
 
-} // namespace ReportPerformance
-
+}   // namespace ReportPerformance
 }   // namespace android
diff --git a/media/libnblog/Timeline.cpp b/media/libnblog/Timeline.cpp
new file mode 100644
index 0000000..c09b03b
--- /dev/null
+++ b/media/libnblog/Timeline.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stddef.h>
+
+#include <audio_utils/roundup.h>
+#include <media/nblog/Timeline.h>
+
+namespace android {
+namespace NBLog {
+
+#if 0   // FIXME see note in Timeline.h
+NBLog::Timeline::Timeline(size_t size, void *shared)
+    : mSize(roundup(size)), mOwn(shared == NULL),
+      mShared((Shared *) (mOwn ? new char[sharedSize(size)] : shared))
+{
+    new (mShared) Shared;
+}
+
+NBLog::Timeline::~Timeline()
+{
+    mShared->~Shared();
+    if (mOwn) {
+        delete[] (char *) mShared;
+    }
+}
+#endif
+
+/*static*/
+size_t Timeline::sharedSize(size_t size)
+{
+    // TODO fifo now supports non-power-of-2 buffer sizes, so could remove the roundup
+    return sizeof(Shared) + roundup(size);
+}
+
+}   // namespace NBLog
+}   // namespace android
diff --git a/media/libnblog/Writer.cpp b/media/libnblog/Writer.cpp
new file mode 100644
index 0000000..da3bd52
--- /dev/null
+++ b/media/libnblog/Writer.cpp
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "NBLog"
+//#define LOG_NDEBUG 0
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <sys/prctl.h>
+
+#include <audio_utils/fifo.h>
+#include <binder/IMemory.h>
+#include <media/nblog/Entry.h>
+#include <media/nblog/Events.h>
+#include <media/nblog/Timeline.h>
+#include <media/nblog/Writer.h>
+#include <utils/Log.h>
+#include <utils/Mutex.h>
+
+namespace android {
+namespace NBLog {
+
+Writer::Writer(void *shared, size_t size)
+    : mShared((Shared *) shared),
+      mFifo(mShared != NULL ?
+        new audio_utils_fifo(size, sizeof(uint8_t),
+            mShared->mBuffer, mShared->mRear, NULL /*throttlesFront*/) : NULL),
+      mFifoWriter(mFifo != NULL ? new audio_utils_fifo_writer(*mFifo) : NULL),
+      mEnabled(mFifoWriter != NULL)
+{
+    // caching pid and process name
+    pid_t id = ::getpid();
+    char procName[16];
+    int status = prctl(PR_GET_NAME, procName);
+    if (status) {  // error getting process name
+        procName[0] = '\0';
+    }
+    size_t length = strlen(procName);
+    mPidTagSize = length + sizeof(pid_t);
+    mPidTag = new char[mPidTagSize];
+    memcpy(mPidTag, &id, sizeof(pid_t));
+    memcpy(mPidTag + sizeof(pid_t), procName, length);
+}
+
+Writer::Writer(const sp<IMemory>& iMemory, size_t size)
+    : Writer(iMemory != 0 ? (Shared *) iMemory->pointer() : NULL, size)
+{
+    mIMemory = iMemory;
+}
+
+Writer::~Writer()
+{
+    delete mFifoWriter;
+    delete mFifo;
+    delete[] mPidTag;
+}
+
+void Writer::log(const char *string)
+{
+    if (!mEnabled) {
+        return;
+    }
+    LOG_ALWAYS_FATAL_IF(string == NULL, "Attempted to log NULL string");
+    size_t length = strlen(string);
+    if (length > Entry::kMaxLength) {
+        length = Entry::kMaxLength;
+    }
+    log(EVENT_STRING, string, length);
+}
+
+void Writer::logf(const char *fmt, ...)
+{
+    if (!mEnabled) {
+        return;
+    }
+    va_list ap;
+    va_start(ap, fmt);
+    Writer::logvf(fmt, ap);     // the Writer:: is needed to avoid virtual dispatch for LockedWriter
+    va_end(ap);
+}
+
+void Writer::logTimestamp()
+{
+    if (!mEnabled) {
+        return;
+    }
+    struct timespec ts;
+    if (!clock_gettime(CLOCK_MONOTONIC, &ts)) {
+        log(EVENT_TIMESTAMP, &ts, sizeof(ts));
+    }
+}
+
+void Writer::logFormat(const char *fmt, log_hash_t hash, ...)
+{
+    if (!mEnabled) {
+        return;
+    }
+    va_list ap;
+    va_start(ap, hash);
+    Writer::logVFormat(fmt, hash, ap);
+    va_end(ap);
+}
+
+void Writer::logEventHistTs(Event event, log_hash_t hash)
+{
+    if (!mEnabled) {
+        return;
+    }
+    HistTsEntry data;
+    data.hash = hash;
+    data.ts = systemTime();
+    if (data.ts > 0) {
+        log(event, &data, sizeof(data));
+    } else {
+        ALOGE("Failed to get timestamp");
+    }
+}
+
+bool Writer::isEnabled() const
+{
+    return mEnabled;
+}
+
+bool Writer::setEnabled(bool enabled)
+{
+    bool old = mEnabled;
+    mEnabled = enabled && mShared != NULL;
+    return old;
+}
+
+void Writer::log(const Entry &etr, bool trusted)
+{
+    if (!mEnabled) {
+        return;
+    }
+    if (!trusted) {
+        log(etr.mEvent, etr.mData, etr.mLength);
+        return;
+    }
+    const size_t need = etr.mLength + Entry::kOverhead; // mEvent, mLength, data[mLength], mLength
+                                                        // need = number of bytes written to FIFO
+
+    // FIXME optimize this using memcpy for the data part of the Entry.
+    // The Entry could have a method copyTo(ptr, offset, size) to optimize the copy.
+    // checks size of a single log Entry: type, length, data pointer and ending
+    uint8_t temp[Entry::kMaxLength + Entry::kOverhead];
+    // write this data to temp array
+    for (size_t i = 0; i < need; i++) {
+        temp[i] = etr.copyEntryDataAt(i);
+    }
+    // write to circular buffer
+    mFifoWriter->write(temp, need);
+}
+
+void Writer::log(Event event, const void *data, size_t length)
+{
+    if (!mEnabled) {
+        return;
+    }
+    if (data == NULL || length > Entry::kMaxLength) {
+        // TODO Perhaps it makes sense to display truncated data or at least a
+        //      message that the data is too long?  The current behavior can create
+        //      a confusion for a programmer debugging their code.
+        return;
+    }
+    // Ignore if invalid event
+    if (event == EVENT_RESERVED || event >= EVENT_UPPER_BOUND) {
+        return;
+    }
+    Entry etr(event, data, length);
+    log(etr, true /*trusted*/);
+}
+
+void Writer::logvf(const char *fmt, va_list ap)
+{
+    if (!mEnabled) {
+        return;
+    }
+    char buffer[Entry::kMaxLength + 1 /*NUL*/];
+    int length = vsnprintf(buffer, sizeof(buffer), fmt, ap);
+    if (length >= (int) sizeof(buffer)) {
+        length = sizeof(buffer) - 1;
+        // NUL termination is not required
+        // buffer[length] = '\0';
+    }
+    if (length >= 0) {
+        log(EVENT_STRING, buffer, length);
+    }
+}
+
+void Writer::logStart(const char *fmt)
+{
+    if (!mEnabled) {
+        return;
+    }
+    size_t length = strlen(fmt);
+    if (length > Entry::kMaxLength) {
+        length = Entry::kMaxLength;
+    }
+    log(EVENT_FMT_START, fmt, length);
+}
+
+void Writer::logTimestampFormat()
+{
+    if (!mEnabled) {
+        return;
+    }
+    const nsecs_t ts = systemTime();
+    if (ts > 0) {
+        log(EVENT_FMT_TIMESTAMP, &ts, sizeof(ts));
+    } else {
+        ALOGE("Failed to get timestamp");
+    }
+}
+
+void Writer::logVFormat(const char *fmt, log_hash_t hash, va_list argp)
+{
+    if (!mEnabled) {
+        return;
+    }
+    Writer::logStart(fmt);
+    int i;
+    double d;
+    float f;
+    char* s;
+    size_t length;
+    int64_t t;
+    Writer::logTimestampFormat();
+    log(EVENT_FMT_HASH, &hash, sizeof(hash));
+    for (const char *p = fmt; *p != '\0'; p++) {
+        // TODO: implement more complex formatting such as %.3f
+        if (*p != '%') {
+            continue;
+        }
+        switch(*++p) {
+        case 's': // string
+            s = va_arg(argp, char *);
+            length = strlen(s);
+            if (length > Entry::kMaxLength) {
+                length = Entry::kMaxLength;
+            }
+            log(EVENT_FMT_STRING, s, length);
+            break;
+
+        case 't': // timestamp
+            t = va_arg(argp, int64_t);
+            log(EVENT_FMT_TIMESTAMP, &t, sizeof(t));
+            break;
+
+        case 'd': // integer
+            i = va_arg(argp, int);
+            log(EVENT_FMT_INTEGER, &i, sizeof(i));
+            break;
+
+        case 'f': // float
+            d = va_arg(argp, double); // float arguments are promoted to double in vararg lists
+            f = (float)d;
+            log(EVENT_FMT_FLOAT, &f, sizeof(f));
+            break;
+
+        case 'p': // pid
+            log(EVENT_FMT_PID, mPidTag, mPidTagSize);
+            break;
+
+        // the "%\0" case finishes parsing
+        case '\0':
+            --p;
+            break;
+
+        case '%':
+            break;
+
+        default:
+            ALOGW("NBLog Writer parsed invalid format specifier: %c", *p);
+            break;
+        }
+    }
+    Entry etr(EVENT_FMT_END, nullptr, 0);
+    log(etr, true);
+}
+
+// ---------------------------------------------------------------------------
+
+LockedWriter::LockedWriter(void *shared, size_t size)
+    : Writer(shared, size)
+{
+}
+
+bool LockedWriter::isEnabled() const
+{
+    Mutex::Autolock _l(mLock);
+    return Writer::isEnabled();
+}
+
+bool LockedWriter::setEnabled(bool enabled)
+{
+    Mutex::Autolock _l(mLock);
+    return Writer::setEnabled(enabled);
+}
+
+void LockedWriter::log(const Entry &entry, bool trusted) {
+    Mutex::Autolock _l(mLock);
+    Writer::log(entry, trusted);
+}
+
+}   // namespace NBLog
+}   // namespace android
diff --git a/media/libnblog/include/media/nblog/Entry.h b/media/libnblog/include/media/nblog/Entry.h
new file mode 100644
index 0000000..53f00b6
--- /dev/null
+++ b/media/libnblog/include/media/nblog/Entry.h
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_MEDIA_NBLOG_ENTRY_H
+#define ANDROID_MEDIA_NBLOG_ENTRY_H
+
+#include <memory>
+#include <stddef.h>
+#include <stdint.h>
+#include <type_traits>
+
+#include <media/nblog/Events.h>
+
+class audio_utils_fifo_writer;
+
+namespace android {
+namespace NBLog {
+
+// entry representation in memory
+struct entry {
+    const uint8_t type;
+    const uint8_t length;
+    const uint8_t data[0];
+};
+
+// entry tail representation (after data)
+struct ending {
+    uint8_t length;
+    uint8_t next[0];
+};
+
+// representation of a single log entry in shared memory
+//  byte[0]             mEvent
+//  byte[1]             mLength
+//  byte[2]             mData[0]
+//  ...
+//  byte[2+i]           mData[i]
+//  ...
+//  byte[2+mLength-1]   mData[mLength-1]
+//  byte[2+mLength]     duplicate copy of mLength to permit reverse scan
+//  byte[3+mLength]     start of next log entry
+class Entry {
+public:
+    Entry(Event event, const void *data, size_t length)
+        : mEvent(event), mLength(length), mData(data) {}
+    ~Entry() {}
+
+    // used during writing to format Entry information as follows:
+    // [type][length][data ... ][length]
+    int     copyEntryDataAt(size_t offset) const;
+
+private:
+    friend class Writer;
+    Event       mEvent;     // event type
+    uint8_t     mLength;    // length of additional data, 0 <= mLength <= kMaxLength
+    const void *mData;      // event type-specific data
+    static const size_t kMaxLength = 255;
+public:
+    // mEvent, mLength, mData[...], duplicate mLength
+    static const size_t kOverhead = sizeof(entry) + sizeof(ending);
+    // endind length of previous entry
+    static const ssize_t kPreviousLengthOffset = - sizeof(ending) +
+        offsetof(ending, length);
+};
+
+// entry iterator
+class EntryIterator {
+public:
+    // Used for dummy initialization. Performing operations on a default-constructed
+    // EntryIterator other than assigning it to another valid EntryIterator
+    // is undefined behavior.
+    EntryIterator();
+    // Caller's responsibility to make sure entry is not nullptr.
+    // Passing in nullptr can result in undefined behavior.
+    explicit EntryIterator(const uint8_t *entry);
+    EntryIterator(const EntryIterator &other);
+
+    // dereference underlying entry
+    const entry&    operator*() const;
+    const entry*    operator->() const;
+    // advance to next entry
+    EntryIterator&  operator++(); // ++i
+    // back to previous entry
+    EntryIterator&  operator--(); // --i
+    // returns an EntryIterator corresponding to the next entry
+    EntryIterator   next() const;
+    // returns an EntryIterator corresponding to the previous entry
+    EntryIterator   prev() const;
+    bool            operator!=(const EntryIterator &other) const;
+    int             operator-(const EntryIterator &other) const;
+
+    bool            hasConsistentLength() const;
+    void            copyTo(std::unique_ptr<audio_utils_fifo_writer> &dst) const;
+    void            copyData(uint8_t *dst) const;
+
+    // memcpy preferred to reinterpret_cast to avoid potentially unsupported
+    // unaligned memory access.
+#if 0
+    template<typename T>
+    inline const T& payload() {
+        return *reinterpret_cast<const T *>(mPtr + offsetof(entry, data));
+    }
+#else
+    template<typename T>
+    inline T payload() const {
+        static_assert(std::is_trivially_copyable<T>::value
+                && !std::is_pointer<T>::value,
+                "NBLog::EntryIterator payload must be trivially copyable, non-pointer type.");
+        T payload;
+        memcpy(&payload, mPtr + offsetof(entry, data), sizeof(payload));
+        return payload;
+    }
+#endif
+
+    inline operator const uint8_t*() const {
+        return mPtr;
+    }
+
+private:
+    const uint8_t  *mPtr;   // Should not be nullptr except for dummy initialization
+};
+
+// ---------------------------------------------------------------------------
+// The following classes are used for merging into the Merger's buffer.
+
+class AbstractEntry {
+public:
+    virtual ~AbstractEntry() {}
+
+    // build concrete entry of appropriate class from ptr.
+    static std::unique_ptr<AbstractEntry> buildEntry(const uint8_t *ptr);
+
+    // get format entry timestamp
+    virtual int64_t       timestamp() const = 0;
+
+    // get format entry's unique id
+    virtual log_hash_t    hash() const = 0;
+
+    // entry's author index (-1 if none present)
+    // a Merger has a vector of Readers, author simply points to the index of the
+    // Reader that originated the entry
+    // TODO consider changing to uint32_t
+    virtual int           author() const = 0;
+
+    // copy entry, adding author before timestamp, returns iterator to end of entry
+    virtual EntryIterator copyWithAuthor(std::unique_ptr<audio_utils_fifo_writer> &dst,
+                                            int author) const = 0;
+
+protected:
+    // Entry starting in the given pointer, which shall not be nullptr.
+    explicit AbstractEntry(const uint8_t *entry) : mEntry(entry) {}
+    // copies ordinary entry from src to dst, and returns length of entry
+    // size_t      copyEntry(audio_utils_fifo_writer *dst, const iterator &it);
+    const uint8_t * const mEntry;
+};
+
+// API for handling format entry operations
+
+// a formatted entry has the following structure:
+//    * FMT_START entry, containing the format string
+//    * TIMESTAMP entry
+//    * HASH entry
+//    * author entry of the thread that generated it (optional, present in merged log)
+//    * format arg1
+//    * format arg2
+//    * ...
+//    * FMT_END entry
+class FormatEntry : public AbstractEntry {
+public:
+    // explicit FormatEntry(const EntryIterator &it);
+    explicit FormatEntry(const uint8_t *ptr) : AbstractEntry(ptr) {}
+    ~FormatEntry() override = default;
+
+    EntryIterator begin() const;
+
+    // Entry's format string
+    const char*   formatString() const;
+
+    // Enrty's format string length
+    size_t        formatStringLength() const;
+
+    // Format arguments (excluding format string, timestamp and author)
+    EntryIterator args() const;
+
+    // get format entry timestamp
+    int64_t       timestamp() const override;
+
+    // get format entry's unique id
+    log_hash_t    hash() const override;
+
+    // entry's author index (-1 if none present)
+    // a Merger has a vector of Readers, author simply points to the index of the
+    // Reader that originated the entry
+    int           author() const override;
+
+    // copy entry, adding author before timestamp, returns size of original entry
+    EntryIterator copyWithAuthor(std::unique_ptr<audio_utils_fifo_writer> &dst,
+                                 int author) const override;
+};
+
+class HistogramEntry : public AbstractEntry {
+public:
+    explicit HistogramEntry(const uint8_t *ptr) : AbstractEntry(ptr) {}
+    ~HistogramEntry() override = default;
+
+    int64_t       timestamp() const override;
+
+    log_hash_t    hash() const override;
+
+    int           author() const override;
+
+    EntryIterator copyWithAuthor(std::unique_ptr<audio_utils_fifo_writer> &dst,
+                                 int author) const override;
+};
+
+}   // namespace NBLog
+}   // namespace android
+
+#endif  // ANDROID_MEDIA_NBLOG_ENTRY_H
diff --git a/media/libnblog/include/media/nblog/Events.h b/media/libnblog/include/media/nblog/Events.h
new file mode 100644
index 0000000..aca4fe8
--- /dev/null
+++ b/media/libnblog/include/media/nblog/Events.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_MEDIA_NBLOG_EVENTS_H
+#define ANDROID_MEDIA_NBLOG_EVENTS_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <system/audio.h>
+#include <type_traits>
+
+namespace android {
+namespace NBLog {
+
+// TODO have a comment somewhere explaining the whole process for adding a new EVENT_
+
+// NBLog Event types. The Events are named to provide contextual meaning for what is logged.
+// If adding a new standalone Event here, update the event-to-type mapping by adding a
+// MAP_EVENT_TO_TYPE statement below.
+// XXX Note that as of the current design, Events should not be renumbered (i.e. reordered)
+// if they ever leave memory (for example, written to file, uploaded to cloud, etc.).
+// TODO make some sort of interface to keep these "contract" constants.
+enum Event : uint8_t {
+    EVENT_RESERVED,
+    EVENT_STRING,               // ASCII string, not NUL-terminated
+                                // TODO: make timestamp optional
+    EVENT_TIMESTAMP,            // clock_gettime(CLOCK_MONOTONIC)
+
+    // Types for Format Entry, i.e. formatted entry
+    EVENT_FMT_START,            // logFormat start event: entry includes format string,
+                                // following entries contain format arguments
+    // format arguments
+    EVENT_FMT_AUTHOR,           // author index (present in merged logs) tracks entry's
+                                // original log
+    EVENT_FMT_FLOAT,            // floating point value entry
+    EVENT_FMT_HASH,             // unique HASH of log origin, originates from hash of file name
+                                // and line number
+    EVENT_FMT_INTEGER,          // integer value entry
+    EVENT_FMT_PID,              // process ID and process name
+    EVENT_FMT_STRING,           // string value entry
+    EVENT_FMT_TIMESTAMP,        // timestamp value entry
+    // end of format arguments
+    EVENT_FMT_END,              // end of logFormat argument list
+
+    // Types for wakeup timestamp histograms
+    EVENT_AUDIO_STATE,          // audio on/off event: logged on FastMixer::onStateChange call
+    EVENT_HISTOGRAM_ENTRY_TS,   // single datum for timestamp histogram
+
+    // Types representing audio performance metrics
+    EVENT_LATENCY,              // difference between frames presented by HAL and frames
+                                // written to HAL output sink, divided by sample rate.
+    EVENT_OVERRUN,              // predicted thread overrun event timestamp
+    EVENT_THREAD_INFO,          // see thread_info_t below
+    EVENT_UNDERRUN,             // predicted thread underrun event timestamp
+    EVENT_WARMUP_TIME,          // thread warmup time
+    EVENT_WORK_TIME,            // the time a thread takes to do work, e.g. read, write, etc.
+    EVENT_THREAD_PARAMS,        // see thread_params_t below
+
+    EVENT_UPPER_BOUND,          // to check for invalid events
+};
+
+// NBLog custom-defined structs. Some NBLog Event types map to these structs.
+
+using log_hash_t = uint64_t;
+
+// used for EVENT_HISTOGRAM_ENTRY_TS (not mapped)
+struct HistTsEntry {
+    log_hash_t hash;
+    int64_t ts;
+}; //TODO __attribute__((packed));
+
+// used for EVENT_HISTOGRAM_ENTRY_TS (not mapped)
+struct HistTsEntryWithAuthor {
+    log_hash_t hash;
+    int64_t ts;
+    int author;
+}; //TODO __attribute__((packed));
+
+enum ThreadType {
+    UNKNOWN,
+    MIXER,
+    CAPTURE,
+    FASTMIXER,
+    FASTCAPTURE,
+};
+
+inline const char *threadTypeToString(ThreadType type) {
+    switch (type) {
+    case MIXER:
+        return "MIXER";
+    case CAPTURE:
+        return "CAPTURE";
+    case FASTMIXER:
+        return "FASTMIXER";
+    case FASTCAPTURE:
+        return "FASTCAPTURE";
+    case UNKNOWN:
+    default:
+        return "UNKNOWN";
+    }
+}
+
+// mapped from EVENT_THREAD_INFO
+// These fields always stay the same throughout a thread's lifetime and
+// should only need to be logged once upon thread initialization.
+// There is currently no recovery mechanism if the log event corresponding
+// to this type is lost.
+// TODO add this information when adding a reader to MediaLogService?
+struct thread_info_t {
+    audio_io_handle_t id = -1;      // Thread I/O handle
+    ThreadType type = UNKNOWN;      // See enum ThreadType above
+};
+
+// mapped from EVENT_THREAD_PARAMS
+// These fields are not necessarily constant throughout a thread's lifetime and
+// can be logged whenever a thread receives new configurations or parameters.
+struct thread_params_t {
+    size_t frameCount = 0;          // number of frames per read or write buffer
+    unsigned sampleRate = 0;        // in frames per second
+};
+
+template <Event E> struct get_mapped;
+#define MAP_EVENT_TO_TYPE(E, T) \
+template<> struct get_mapped<E> { \
+    static_assert(std::is_trivially_copyable<T>::value \
+            && !std::is_pointer<T>::value, \
+            "NBLog::Event must map to trivially copyable, non-pointer type."); \
+    typedef T type; \
+}
+
+// Maps an NBLog Event type to a C++ POD type.
+MAP_EVENT_TO_TYPE(EVENT_LATENCY, double);
+MAP_EVENT_TO_TYPE(EVENT_OVERRUN, int64_t);
+MAP_EVENT_TO_TYPE(EVENT_THREAD_INFO, thread_info_t);
+MAP_EVENT_TO_TYPE(EVENT_UNDERRUN, int64_t);
+MAP_EVENT_TO_TYPE(EVENT_WARMUP_TIME, double);
+MAP_EVENT_TO_TYPE(EVENT_WORK_TIME, int64_t);
+MAP_EVENT_TO_TYPE(EVENT_THREAD_PARAMS, thread_params_t);
+
+}   // namespace NBLog
+}   // namespace android
+
+#endif  // ANDROID_MEDIA_NBLOG_EVENTS_H
diff --git a/media/libnblog/include/media/nblog/Merger.h b/media/libnblog/include/media/nblog/Merger.h
new file mode 100644
index 0000000..7da8521
--- /dev/null
+++ b/media/libnblog/include/media/nblog/Merger.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_MEDIA_NBLOG_MERGER_H
+#define ANDROID_MEDIA_NBLOG_MERGER_H
+
+#include <memory>
+#include <stddef.h>
+#include <stdint.h>
+#include <vector>
+
+#include <audio_utils/fifo.h>
+#include <media/nblog/PerformanceAnalysis.h>
+#include <media/nblog/Reader.h>
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
+#include <utils/RefBase.h>
+#include <utils/Thread.h>
+#include <utils/Timers.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+class String16;
+class String8;
+
+namespace NBLog {
+
+struct Shared;
+
+// TODO update comments to reflect current functionalities
+
+// This class is used to read data from each thread's individual FIFO in shared memory
+// and write it to a single FIFO in local memory.
+class Merger : public RefBase {
+public:
+    Merger(const void *shared, size_t size);
+
+    ~Merger() override = default;
+
+    void addReader(const sp<NBLog::Reader> &reader);
+    // TODO add removeReader
+    void merge();
+
+    // FIXME This is returning a reference to a shared variable that needs a lock
+    const std::vector<sp<Reader>>& getReaders() const;
+
+private:
+    // vector of the readers the merger is supposed to merge from.
+    // every reader reads from a writer's buffer
+    // FIXME Needs to be protected by a lock
+    std::vector<sp<Reader>> mReaders;
+
+    Shared * const mShared; // raw pointer to shared memory
+    std::unique_ptr<audio_utils_fifo> mFifo; // FIFO itself
+    std::unique_ptr<audio_utils_fifo_writer> mFifoWriter; // used to write to FIFO
+};
+
+// This class has a pointer to the FIFO in local memory which stores the merged
+// data collected by NBLog::Merger from all Readers. It is used to process
+// this data and write the result to PerformanceAnalysis.
+class MergeReader : public Reader {
+public:
+    MergeReader(const void *shared, size_t size, Merger &merger);
+
+    // process a particular snapshot of the reader
+    void processSnapshot(Snapshot &snap, int author);
+
+    // call getSnapshot of the content of the reader's buffer and process the data
+    void getAndProcessSnapshot();
+
+    // check for periodic push of performance data to media metrics, and perform
+    // the send if it is time to do so.
+    void checkPushToMediaMetrics();
+
+    void dump(int fd, const Vector<String16>& args);
+
+private:
+    // FIXME Needs to be protected by a lock,
+    //       because even though our use of it is read-only there may be asynchronous updates
+    // The object is owned by the Merger class.
+    const std::vector<sp<Reader>>& mReaders;
+
+    // analyzes, compresses and stores the merged data
+    // contains a separate instance for every author (thread), and for every source file
+    // location within each author
+    ReportPerformance::PerformanceAnalysisMap mThreadPerformanceAnalysis;
+
+    // compresses and stores audio performance data from each thread's buffers.
+    // first parameter is author, i.e. thread index.
+    std::map<int, ReportPerformance::PerformanceData> mThreadPerformanceData;
+
+    // how often to push data to Media Metrics
+    static constexpr nsecs_t kPeriodicMediaMetricsPush = s2ns((nsecs_t)2 * 60 * 60); // 2 hours
+
+    // handle author entry by looking up the author's name and appending it to the body
+    // returns number of bytes read from fmtEntry
+    void handleAuthor(const AbstractEntry &fmtEntry, String8 *body);
+};
+
+// MergeThread is a thread that contains a Merger. It works as a retriggerable one-shot:
+// when triggered, it awakes for a lapse of time, during which it periodically merges; if
+// retriggered, the timeout is reset.
+// The thread is triggered on AudioFlinger binder activity.
+class MergeThread : public Thread {
+public:
+    MergeThread(Merger &merger, MergeReader &mergeReader);
+    ~MergeThread() override;
+
+    // Reset timeout and activate thread to merge periodically if it's idle
+    void wakeup();
+
+    // Set timeout period until the merging thread goes idle again
+    void setTimeoutUs(int time);
+
+private:
+    bool threadLoop() override;
+
+    // the merger who actually does the work of merging the logs
+    Merger&      mMerger;
+
+    // the mergereader used to process data merged by mMerger
+    MergeReader& mMergeReader;
+
+    // mutex for the condition variable
+    Mutex        mMutex;
+
+    // condition variable to activate merging on timeout >= 0
+    Condition    mCond;
+
+    // time left until the thread blocks again (in microseconds)
+    int          mTimeoutUs;
+
+    // merging period when the thread is awake
+    static const int  kThreadSleepPeriodUs = 1000000 /*1s*/;
+
+    // initial timeout value when triggered
+    static const int  kThreadWakeupPeriodUs = 3000000 /*3s*/;
+};
+
+}   // namespace NBLog
+}   // namespace android
+
+#endif  // ANDROID_MEDIA_NBLOG_MERGER_H
diff --git a/media/libnblog/include/media/nblog/NBLog.h b/media/libnblog/include/media/nblog/NBLog.h
index fb6f179..fd73538 100644
--- a/media/libnblog/include/media/nblog/NBLog.h
+++ b/media/libnblog/include/media/nblog/NBLog.h
@@ -19,595 +19,10 @@
 #ifndef ANDROID_MEDIA_NBLOG_H
 #define ANDROID_MEDIA_NBLOG_H
 
-#include <deque>
-#include <map>
-#include <set>
-#include <vector>
-
-#include <audio_utils/fifo.h>
-#include <binder/IMemory.h>
-#include <media/nblog/PerformanceAnalysis.h>
-#include <media/nblog/ReportPerformance.h>
-#include <utils/Mutex.h>
-#include <utils/threads.h>
-
-namespace android {
-
-class String8;
-
-class NBLog {
-
-public:
-
-    using log_hash_t = ReportPerformance::log_hash_t;
-
-    // FIXME Everything needed for client (writer API and registration) should be isolated
-    //       from the rest of the implementation.
-    class Writer;
-    class Reader;
-
-    enum Event : uint8_t {
-        EVENT_RESERVED,
-        EVENT_STRING,               // ASCII string, not NUL-terminated
-                                    // TODO: make timestamp optional
-        EVENT_TIMESTAMP,            // clock_gettime(CLOCK_MONOTONIC)
-        EVENT_INTEGER,              // integer value entry
-        EVENT_FLOAT,                // floating point value entry
-        EVENT_PID,                  // process ID and process name
-        EVENT_AUTHOR,               // author index (present in merged logs) tracks entry's
-                                    // original log
-        EVENT_START_FMT,            // logFormat start event: entry includes format string,
-                                    // following entries contain format arguments
-        EVENT_HASH,                 // unique HASH of log origin, originates from hash of file name
-                                    // and line number
-        EVENT_HISTOGRAM_ENTRY_TS,   // single datum for timestamp histogram
-        EVENT_AUDIO_STATE,          // audio on/off event: logged on FastMixer::onStateChange call
-        EVENT_END_FMT,              // end of logFormat argument list
-
-        EVENT_UPPER_BOUND,          // to check for invalid events
-    };
-
-private:
-
-    // ---------------------------------------------------------------------------
-    // API for handling format entry operations
-
-    // a formatted entry has the following structure:
-    //    * START_FMT entry, containing the format string
-    //    * TIMESTAMP entry
-    //    * HASH entry
-    //    * author entry of the thread that generated it (optional, present in merged log)
-    //    * format arg1
-    //    * format arg2
-    //    * ...
-    //    * END_FMT entry
-
-    // entry representation in memory
-    struct entry {
-        const uint8_t type;
-        const uint8_t length;
-        const uint8_t data[0];
-    };
-
-    // entry tail representation (after data)
-    struct ending {
-        uint8_t length;
-        uint8_t next[0];
-    };
-
-    // entry iterator
-    class EntryIterator {
-    public:
-        EntryIterator();
-        explicit EntryIterator(const uint8_t *entry);
-        EntryIterator(const EntryIterator &other);
-
-        // dereference underlying entry
-        const entry&    operator*() const;
-        const entry*    operator->() const;
-        // advance to next entry
-        EntryIterator&       operator++(); // ++i
-        // back to previous entry
-        EntryIterator&       operator--(); // --i
-        EntryIterator        next() const;
-        EntryIterator        prev() const;
-        bool            operator!=(const EntryIterator &other) const;
-        int             operator-(const EntryIterator &other) const;
-
-        bool            hasConsistentLength() const;
-        void            copyTo(std::unique_ptr<audio_utils_fifo_writer> &dst) const;
-        void            copyData(uint8_t *dst) const;
-
-        template<typename T>
-        inline const T& payload() {
-            return *reinterpret_cast<const T *>(ptr + offsetof(entry, data));
-        }
-
-        inline operator const uint8_t*() const {
-            return ptr;
-        }
-
-    private:
-        const uint8_t  *ptr;
-    };
-
-    class AbstractEntry {
-    public:
-
-        // Entry starting in the given pointer
-        explicit AbstractEntry(const uint8_t *entry);
-        virtual ~AbstractEntry() {}
-
-        // build concrete entry of appropriate class from pointer
-        static std::unique_ptr<AbstractEntry> buildEntry(const uint8_t *ptr);
-
-        // get format entry timestamp
-        virtual int64_t      timestamp() const = 0;
-
-        // get format entry's unique id
-        virtual log_hash_t   hash() const = 0;
-
-        // entry's author index (-1 if none present)
-        // a Merger has a vector of Readers, author simply points to the index of the
-        // Reader that originated the entry
-        // TODO consider changing to uint32_t
-        virtual int          author() const = 0;
-
-        // copy entry, adding author before timestamp, returns iterator to end of entry
-        virtual EntryIterator    copyWithAuthor(std::unique_ptr<audio_utils_fifo_writer> &dst,
-                                                int author) const = 0;
-
-    protected:
-        // copies ordinary entry from src to dst, and returns length of entry
-        // size_t      copyEntry(audio_utils_fifo_writer *dst, const iterator &it);
-        const uint8_t  *mEntry;
-    };
-
-    class FormatEntry : public AbstractEntry {
-    public:
-        // explicit FormatEntry(const EntryIterator &it);
-        explicit FormatEntry(const uint8_t *ptr) : AbstractEntry(ptr) {}
-        virtual ~FormatEntry() {}
-
-        EntryIterator begin() const;
-
-        // Entry's format string
-        const   char* formatString() const;
-
-        // Enrty's format string length
-        size_t      formatStringLength() const;
-
-        // Format arguments (excluding format string, timestamp and author)
-        EntryIterator    args() const;
-
-        // get format entry timestamp
-        virtual int64_t     timestamp() const override;
-
-        // get format entry's unique id
-        virtual log_hash_t  hash() const override;
-
-        // entry's author index (-1 if none present)
-        // a Merger has a vector of Readers, author simply points to the index of the
-        // Reader that originated the entry
-        virtual int         author() const override;
-
-        // copy entry, adding author before timestamp, returns size of original entry
-        virtual EntryIterator    copyWithAuthor(std::unique_ptr<audio_utils_fifo_writer> &dst,
-                                                int author) const override;
-
-    };
-
-    class HistogramEntry : public AbstractEntry {
-    public:
-        explicit HistogramEntry(const uint8_t *ptr) : AbstractEntry(ptr) {
-        }
-        virtual ~HistogramEntry() {}
-
-        virtual int64_t     timestamp() const override;
-
-        virtual log_hash_t  hash() const override;
-
-        virtual int         author() const override;
-
-        virtual EntryIterator    copyWithAuthor(std::unique_ptr<audio_utils_fifo_writer> &dst,
-                                                int author) const override;
-
-    };
-
-    // ---------------------------------------------------------------------------
-
-    // representation of a single log entry in private memory
-    struct Entry {
-        Entry(Event event, const void *data, size_t length)
-            : mEvent(event), mLength(length), mData(data) { }
-        /*virtual*/ ~Entry() { }
-
-        // used during writing to format Entry information as follows:
-        // [type][length][data ... ][length]
-        int     copyEntryDataAt(size_t offset) const;
-
-    private:
-        friend class Writer;
-        Event       mEvent;     // event type
-        uint8_t     mLength;    // length of additional data, 0 <= mLength <= kMaxLength
-        const void *mData;      // event type-specific data
-        static const size_t kMaxLength = 255;
-    public:
-        // mEvent, mLength, mData[...], duplicate mLength
-        static const size_t kOverhead = sizeof(entry) + sizeof(ending);
-        // endind length of previous entry
-        static const ssize_t kPreviousLengthOffset = - sizeof(ending) +
-            offsetof(ending, length);
-    };
-
-    struct HistTsEntry {
-        log_hash_t hash;
-        int64_t ts;
-    }; //TODO __attribute__((packed));
-
-    struct HistTsEntryWithAuthor {
-        log_hash_t hash;
-        int64_t ts;
-        int author;
-    }; //TODO __attribute__((packed));
-
-    struct HistIntEntry {
-        log_hash_t hash;
-        int value;
-    }; //TODO __attribute__((packed));
-
-    // representation of a single log entry in shared memory
-    //  byte[0]             mEvent
-    //  byte[1]             mLength
-    //  byte[2]             mData[0]
-    //  ...
-    //  byte[2+i]           mData[i]
-    //  ...
-    //  byte[2+mLength-1]   mData[mLength-1]
-    //  byte[2+mLength]     duplicate copy of mLength to permit reverse scan
-    //  byte[3+mLength]     start of next log entry
-
-    static void    appendInt(String8 *body, const void *data);
-    static void    appendFloat(String8 *body, const void *data);
-    static void    appendPID(String8 *body, const void *data, size_t length);
-    static void    appendTimestamp(String8 *body, const void *data);
-    static size_t  fmtEntryLength(const uint8_t *data);
-    static String8 bufferDump(const uint8_t *buffer, size_t size);
-    static String8 bufferDump(const EntryIterator &it);
-public:
-
-    // Located in shared memory, must be POD.
-    // Exactly one process must explicitly call the constructor or use placement new.
-    // Since this is a POD, the destructor is empty and unnecessary to call it explicitly.
-    struct Shared {
-        Shared() /* mRear initialized via default constructor */ { }
-        /*virtual*/ ~Shared() { }
-
-        audio_utils_fifo_index  mRear;  // index one byte past the end of most recent Entry
-        char    mBuffer[0];             // circular buffer for entries
-    };
-
-public:
-
-    // ---------------------------------------------------------------------------
-
-    // FIXME Timeline was intended to wrap Writer and Reader, but isn't actually used yet.
-    // For now it is just a namespace for sharedSize().
-    class Timeline : public RefBase {
-    public:
-#if 0
-        Timeline(size_t size, void *shared = NULL);
-        virtual ~Timeline();
-#endif
-
-        // Input parameter 'size' is the desired size of the timeline in byte units.
-        // Returns the size rounded up to a power-of-2, plus the constant size overhead for indices.
-        static size_t sharedSize(size_t size);
-
-#if 0
-    private:
-        friend class    Writer;
-        friend class    Reader;
-
-        const size_t    mSize;      // circular buffer size in bytes, must be a power of 2
-        bool            mOwn;       // whether I own the memory at mShared
-        Shared* const   mShared;    // pointer to shared memory
-#endif
-    };
-
-    // ---------------------------------------------------------------------------
-
-    // Writer is thread-safe with respect to Reader, but not with respect to multiple threads
-    // calling Writer methods.  If you need multi-thread safety for writing, use LockedWriter.
-    class Writer : public RefBase {
-    public:
-        Writer();                   // dummy nop implementation without shared memory
-
-        // Input parameter 'size' is the desired size of the timeline in byte units.
-        // The size of the shared memory must be at least Timeline::sharedSize(size).
-        Writer(void *shared, size_t size);
-        Writer(const sp<IMemory>& iMemory, size_t size);
-
-        virtual ~Writer();
-
-        // FIXME needs comments, and some should be private
-        virtual void    log(const char *string);
-        virtual void    logf(const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
-        virtual void    logvf(const char *fmt, va_list ap);
-        virtual void    logTimestamp();
-        virtual void    logTimestamp(const int64_t ts);
-        virtual void    logInteger(const int x);
-        virtual void    logFloat(const float x);
-        virtual void    logPID();
-        virtual void    logFormat(const char *fmt, log_hash_t hash, ...);
-        virtual void    logVFormat(const char *fmt, log_hash_t hash, va_list ap);
-        virtual void    logStart(const char *fmt);
-        virtual void    logEnd();
-        virtual void    logHash(log_hash_t hash);
-        virtual void    logEventHistTs(Event event, log_hash_t hash);
-
-        virtual bool    isEnabled() const;
-
-        // return value for all of these is the previous isEnabled()
-        virtual bool    setEnabled(bool enabled);   // but won't enable if no shared memory
-        bool    enable()    { return setEnabled(true); }
-        bool    disable()   { return setEnabled(false); }
-
-        sp<IMemory>     getIMemory() const  { return mIMemory; }
-
-    private:
-        // 0 <= length <= kMaxLength
-        // writes a single Entry to the FIFO
-        void    log(Event event, const void *data, size_t length);
-        // checks validity of an event before calling log above this one
-        void    log(const Entry *entry, bool trusted = false);
-
-        Shared* const   mShared;    // raw pointer to shared memory
-        sp<IMemory>     mIMemory;   // ref-counted version, initialized in constructor
-                                    // and then const
-        audio_utils_fifo * const mFifo;                 // FIFO itself, non-NULL
-                                                        // unless constructor fails
-        audio_utils_fifo_writer * const mFifoWriter;    // used to write to FIFO, non-NULL
-                                                        // unless dummy constructor used
-        bool            mEnabled;   // whether to actually log
-
-        // cached pid and process name to use in %p format specifier
-        // total tag length is mPidTagSize and process name is not zero terminated
-        char   *mPidTag;
-        size_t  mPidTagSize;
-    };
-
-    // ---------------------------------------------------------------------------
-
-    // Similar to Writer, but safe for multiple threads to call concurrently
-    class LockedWriter : public Writer {
-    public:
-        LockedWriter();
-        LockedWriter(void *shared, size_t size);
-
-        virtual void    log(const char *string);
-        virtual void    logf(const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
-        virtual void    logvf(const char *fmt, va_list ap);
-        virtual void    logTimestamp();
-        virtual void    logTimestamp(const int64_t ts);
-        virtual void    logInteger(const int x);
-        virtual void    logFloat(const float x);
-        virtual void    logPID();
-        virtual void    logStart(const char *fmt);
-        virtual void    logEnd();
-        virtual void    logHash(log_hash_t hash);
-
-        virtual bool    isEnabled() const;
-        virtual bool    setEnabled(bool enabled);
-
-    private:
-        mutable Mutex   mLock;
-    };
-
-    // ---------------------------------------------------------------------------
-
-    class Reader : public RefBase {
-    public:
-        // A snapshot of a readers buffer
-        // This is raw data. No analysis has been done on it
-        class Snapshot {
-        public:
-            Snapshot() : mData(NULL), mLost(0) {}
-
-            Snapshot(size_t bufferSize) : mData(new uint8_t[bufferSize]) {}
-
-            ~Snapshot() { delete[] mData; }
-
-            // copy of the buffer
-            uint8_t *data() const { return mData; }
-
-            // amount of data lost (given by audio_utils_fifo_reader)
-            size_t   lost() const { return mLost; }
-
-            // iterator to beginning of readable segment of snapshot
-            // data between begin and end has valid entries
-            EntryIterator begin() { return mBegin; }
-
-            // iterator to end of readable segment of snapshot
-            EntryIterator end() { return mEnd; }
-
-        private:
-            friend class MergeReader;
-            friend class Reader;
-            uint8_t              *mData;
-            size_t                mLost;
-            EntryIterator mBegin;
-            EntryIterator mEnd;
-        };
-
-        // Input parameter 'size' is the desired size of the timeline in byte units.
-        // The size of the shared memory must be at least Timeline::sharedSize(size).
-        Reader(const void *shared, size_t size);
-        Reader(const sp<IMemory>& iMemory, size_t size);
-
-        virtual ~Reader();
-
-        // get snapshot of readers fifo buffer, effectively consuming the buffer
-        std::unique_ptr<Snapshot> getSnapshot();
-
-        bool     isIMemory(const sp<IMemory>& iMemory) const;
-
-    protected:
-        // print a summary of the performance to the console
-        void    dumpLine(const String8& timestamp, String8& body);
-        EntryIterator   handleFormat(const FormatEntry &fmtEntry,
-                                     String8 *timestamp,
-                                     String8 *body);
-        int mFd;                // file descriptor
-        int mIndent;            // indentation level
-        int mLost;              // bytes of data lost before buffer was read
-
-    private:
-        static const std::set<Event> startingTypes;
-        static const std::set<Event> endingTypes;
-
-        // declared as const because audio_utils_fifo() constructor
-        sp<IMemory> mIMemory;       // ref-counted version, assigned only in constructor
-
-        /*const*/ Shared* const mShared;    // raw pointer to shared memory, actually const but not
-        audio_utils_fifo * const mFifo;                 // FIFO itself,
-        // non-NULL unless constructor fails
-        audio_utils_fifo_reader * const mFifoReader;    // used to read from FIFO,
-        // non-NULL unless constructor fails
-
-        // Searches for the last entry of type <type> in the range [front, back)
-        // back has to be entry-aligned. Returns nullptr if none enconuntered.
-        static const uint8_t *findLastEntryOfTypes(const uint8_t *front, const uint8_t *back,
-                                                   const std::set<Event> &types);
-
-        // dummy method for handling absent author entry
-        virtual void handleAuthor(const AbstractEntry& /*fmtEntry*/, String8* /*body*/) {}
-    };
-
-    // Wrapper for a reader with a name. Contains a pointer to the reader and a pointer to the name
-    class NamedReader {
-    public:
-        NamedReader() { mName[0] = '\0'; } // for Vector
-        NamedReader(const sp<NBLog::Reader>& reader, const char *name) :
-            mReader(reader)
-            { strlcpy(mName, name, sizeof(mName)); }
-        ~NamedReader() { }
-        const sp<NBLog::Reader>&  reader() const { return mReader; }
-        const char*               name() const { return mName; }
-
-    private:
-        sp<NBLog::Reader>   mReader;
-        static const size_t kMaxName = 32;
-        char                mName[kMaxName];
-    };
-
-    // ---------------------------------------------------------------------------
-
-    // This class is used to read data from each thread's individual FIFO in shared memory
-    // and write it to a single FIFO in local memory.
-    class Merger : public RefBase {
-    public:
-        Merger(const void *shared, size_t size);
-
-        virtual ~Merger() {}
-
-        void addReader(const NamedReader &reader);
-        // TODO add removeReader
-        void merge();
-
-        // FIXME This is returning a reference to a shared variable that needs a lock
-        const std::vector<NamedReader>& getNamedReaders() const;
-
-    private:
-        // vector of the readers the merger is supposed to merge from.
-        // every reader reads from a writer's buffer
-        // FIXME Needs to be protected by a lock
-        std::vector<NamedReader> mNamedReaders;
-
-        Shared * const mShared; // raw pointer to shared memory
-        std::unique_ptr<audio_utils_fifo> mFifo; // FIFO itself
-        std::unique_ptr<audio_utils_fifo_writer> mFifoWriter; // used to write to FIFO
-    };
-
-    // This class has a pointer to the FIFO in local memory which stores the merged
-    // data collected by NBLog::Merger from all NamedReaders. It is used to process
-    // this data and write the result to PerformanceAnalysis.
-    class MergeReader : public Reader {
-    public:
-        MergeReader(const void *shared, size_t size, Merger &merger);
-
-        void dump(int fd, int indent = 0);
-        // process a particular snapshot of the reader
-        void getAndProcessSnapshot(Snapshot & snap);
-        // call getSnapshot of the content of the reader's buffer and process the data
-        void getAndProcessSnapshot();
-
-    private:
-        // FIXME Needs to be protected by a lock,
-        //       because even though our use of it is read-only there may be asynchronous updates
-        const std::vector<NamedReader>& mNamedReaders;
-
-        // analyzes, compresses and stores the merged data
-        // contains a separate instance for every author (thread), and for every source file
-        // location within each author
-        ReportPerformance::PerformanceAnalysisMap mThreadPerformanceAnalysis;
-
-        // handle author entry by looking up the author's name and appending it to the body
-        // returns number of bytes read from fmtEntry
-        void handleAuthor(const AbstractEntry &fmtEntry, String8 *body);
-    };
-
-    // MergeThread is a thread that contains a Merger. It works as a retriggerable one-shot:
-    // when triggered, it awakes for a lapse of time, during which it periodically merges; if
-    // retriggered, the timeout is reset.
-    // The thread is triggered on AudioFlinger binder activity.
-    class MergeThread : public Thread {
-    public:
-        MergeThread(Merger &merger, MergeReader &mergeReader);
-        virtual ~MergeThread() override;
-
-        // Reset timeout and activate thread to merge periodically if it's idle
-        void wakeup();
-
-        // Set timeout period until the merging thread goes idle again
-        void setTimeoutUs(int time);
-
-    private:
-        virtual bool threadLoop() override;
-
-        // the merger who actually does the work of merging the logs
-        Merger&     mMerger;
-
-        // the mergereader used to process data merged by mMerger
-        MergeReader& mMergeReader;
-
-        // mutex for the condition variable
-        Mutex       mMutex;
-
-        // condition variable to activate merging on timeout >= 0
-        Condition   mCond;
-
-        // time left until the thread blocks again (in microseconds)
-        int         mTimeoutUs;
-
-        // merging period when the thread is awake
-        static const int  kThreadSleepPeriodUs = 1000000 /*1s*/;
-
-        // initial timeout value when triggered
-        static const int  kThreadWakeupPeriodUs = 3000000 /*3s*/;
-    };
-
-};  // class NBLog
-
-// TODO put somewhere else
-static inline int64_t get_monotonic_ns() {
-    timespec ts;
-    if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
-        return (uint64_t) ts.tv_sec * 1000 * 1000 * 1000 + ts.tv_nsec;
-    }
-    return 0; // should not happen.
-}
-
-}   // namespace android
+#include <media/nblog/Entry.h>
+#include <media/nblog/Events.h>
+#include <media/nblog/Reader.h>
+#include <media/nblog/Timeline.h>
+#include <media/nblog/Writer.h>
 
 #endif  // ANDROID_MEDIA_NBLOG_H
diff --git a/media/libnblog/include/media/nblog/PerformanceAnalysis.h b/media/libnblog/include/media/nblog/PerformanceAnalysis.h
index ddfe9d6..d7c16b6 100644
--- a/media/libnblog/include/media/nblog/PerformanceAnalysis.h
+++ b/media/libnblog/include/media/nblog/PerformanceAnalysis.h
@@ -19,14 +19,176 @@
 
 #include <deque>
 #include <map>
+#include <string>
+#include <utility>
 #include <vector>
 
+#include <media/nblog/Events.h>
 #include <media/nblog/ReportPerformance.h>
+#include <utils/Timers.h>
 
 namespace android {
 
+class String8;
+
 namespace ReportPerformance {
 
+// TODO make this a templated class and put it in a separate file.
+// The templated parameters would be bin size and low limit.
+/*
+ * Histogram provides a way to store numeric data in histogram format and read it as a serialized
+ * string. The terms "bin" and "bucket" are used interchangeably.
+ *
+ * This class is not thread-safe.
+ */
+class Histogram {
+public:
+    struct Config {
+        const double binSize;   // TODO template type
+        const size_t numBins;
+        const double low;       // TODO template type
+    };
+
+    // Histograms are constructed with fixed configuration numbers. Dynamic configuration based
+    // the data is possible but complex because
+    // - data points are added one by one, not processed as a batch.
+    // - Histograms with different configuration parameters are tricky to aggregate, and they
+    //   will need to be aggregated at the Media Metrics cloud side.
+    // - not providing limits theoretically allows for infinite number of buckets.
+
+    /**
+     * \brief Creates a Histogram object.
+     *
+     * \param binSize the width of each bin of the histogram, must be greater than 0.
+     *                Units are whatever data the caller decides to store.
+     * \param numBins the number of bins desired in the histogram range, must be greater than 0.
+     * \param low     the lower bound of the histogram bucket values.
+     *                Units are whatever data the caller decides to store.
+     *                Note that the upper bound can be calculated by the following:
+     *                  upper = lower + binSize * numBins.
+     */
+    Histogram(double binSize, size_t numBins, double low = 0.)
+        : mBinSize(binSize), mNumBins(numBins), mLow(low), mBins(mNumBins + 2) {}
+
+    Histogram(const Config &c)
+        : Histogram(c.binSize, c.numBins, c.low) {}
+
+    /**
+     * \brief Add a data point to the histogram. The value of the data point
+     *        is rounded to the nearest multiple of the bin size (before accounting
+     *        for the lower bound offset, which may not be a multiple of the bin size).
+     *
+     * \param value the value of the data point to add.
+     */
+    void add(double value);
+
+    /**
+     * \brief Removes all data points from the histogram.
+     */
+    void clear();
+
+    /**
+     * \brief Returns the total number of data points added to the histogram.
+     *
+     * \return the total number of data points in the histogram.
+     */
+    uint64_t totalCount() const;
+
+    /**
+     * \brief Serializes the histogram into a string. The format is chosen to be compatible with
+     *        the histogram representation to send to the Media Metrics service.
+     *
+     *        The string is as follows:
+     *          binSize,numBins,low,{-1|lowCount,...,binIndex|count,...,numBins|highCount}
+     *
+     *        - binIndex is an integer with 0 <= binIndex < numBins.
+     *        - count is the number of occurrences of the (rounded) value
+     *          low + binSize * bucketIndex.
+     *        - lowCount is the number of (rounded) values less than low.
+     *        - highCount is the number of (rounded) values greater than or equal to
+     *          low + binSize * numBins.
+     *        - a binIndex may be skipped if its count is 0.
+     *
+     * \return the histogram serialized as a string.
+     */
+    std::string toString() const;
+
+    // Draw log scale sideways histogram as ASCII art and store as a std::string.
+    // Empty string is returned if totalCount() == 0.
+    std::string asciiArtString(size_t indent = 0) const;
+
+private:
+    // Histogram version number.
+    static constexpr int kVersion = 1;
+
+    const double mBinSize;          // Size of each bucket
+    const size_t mNumBins;          // Number of buckets in range (excludes low and high)
+    const double mLow;              // Lower bound of values
+
+    // Data structure to store the actual histogram. Counts of bin values less than mLow
+    // are stored in mBins[0]. Bin index i corresponds to mBins[i+1]. Counts of bin values
+    // >= high are stored in mBins[mNumBins + 1].
+    std::vector<uint64_t> mBins;
+
+    uint64_t mTotalCount = 0;       // Total number of values recorded
+};
+
+// This is essentially the same as class PerformanceAnalysis, but PerformanceAnalysis
+// also does some additional analyzing of data, while the purpose of this struct is
+// to hold data.
+struct PerformanceData {
+    // TODO the Histogram::Config numbers below are for FastMixer.
+    // Specify different numbers for other thread types.
+
+    // Values based on mUnderrunNs and mOverrunNs in FastMixer.cpp for frameCount = 192
+    // and mSampleRate = 48000, which correspond to 2 and 7 seconds.
+    static constexpr Histogram::Config kWorkConfig = { 0.25, 20, 2.};
+
+    // Values based on trial and error logging. Need a better way to determine
+    // bin size and lower/upper limits.
+    static constexpr Histogram::Config kLatencyConfig = { 2., 10, 10.};
+
+    // Values based on trial and error logging. Need a better way to determine
+    // bin size and lower/upper limits.
+    static constexpr Histogram::Config kWarmupConfig = { 5., 10, 10.};
+
+    NBLog::thread_info_t threadInfo{};
+    NBLog::thread_params_t threadParams{};
+
+    // Performance Data
+    Histogram workHist{kWorkConfig};
+    Histogram latencyHist{kLatencyConfig};
+    Histogram warmupHist{kWarmupConfig};
+    int64_t underruns = 0;
+    static constexpr size_t kMaxSnapshotsToStore = 256;
+    std::deque<std::pair<NBLog::Event, int64_t /*timestamp*/>> snapshots;
+    int64_t overruns = 0;
+    nsecs_t active = 0;
+    nsecs_t start{systemTime()};
+
+    // Reset the performance data. This does not represent a thread state change.
+    // Thread info is not reset here because the data is meant to be a continuation of the thread
+    // that struct PerformanceData is associated with.
+    void reset() {
+        workHist.clear();
+        latencyHist.clear();
+        warmupHist.clear();
+        underruns = 0;
+        overruns = 0;
+        active = 0;
+        start = systemTime();
+    }
+
+    // Return true if performance data has not been recorded yet, false otherwise.
+    bool empty() const {
+        return workHist.totalCount() == 0 && latencyHist.totalCount() == 0
+                && warmupHist.totalCount() == 0 && underruns == 0 && overruns == 0
+                && active == 0;
+    }
+};
+
+//------------------------------------------------------------------------------
+
 class PerformanceAnalysis;
 
 // a map of PerformanceAnalysis instances
@@ -80,7 +242,7 @@
     std::deque<timestamp> mPeakTimestamps;
 
     // stores buffer period histograms with timestamp of first sample
-    std::deque<std::pair<timestamp, Histogram>> mHists;
+    std::deque<std::pair<timestamp, Hist>> mHists;
 
     // Parameters used when detecting outliers
     struct BufferPeriod {
@@ -119,8 +281,7 @@
 void dump(int fd, int indent, PerformanceAnalysisMap &threadPerformanceAnalysis);
 void dumpLine(int fd, int indent, const String8 &body);
 
-} // namespace ReportPerformance
-
+}   // namespace ReportPerformance
 }   // namespace android
 
 #endif  // ANDROID_MEDIA_PERFORMANCEANALYSIS_H
diff --git a/media/libnblog/include/media/nblog/Reader.h b/media/libnblog/include/media/nblog/Reader.h
new file mode 100644
index 0000000..2495e8c
--- /dev/null
+++ b/media/libnblog/include/media/nblog/Reader.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_MEDIA_NBLOG_READER_H
+#define ANDROID_MEDIA_NBLOG_READER_H
+
+#include <memory>
+#include <stddef.h>
+#include <string>
+#include <unordered_set>
+
+#include <media/nblog/Entry.h>
+#include <media/nblog/Events.h>
+#include <utils/RefBase.h>
+
+class audio_utils_fifo;
+class audio_utils_fifo_reader;
+
+namespace android {
+
+class IMemory;
+class String8;
+
+namespace NBLog {
+
+struct Shared;
+
+// NBLog Reader API
+
+class Snapshot;     // Forward declaration needed for Reader::getSnapshot()
+
+class Reader : public RefBase {
+public:
+    // Input parameter 'size' is the desired size of the timeline in byte units.
+    // The size of the shared memory must be at least Timeline::sharedSize(size).
+    Reader(const void *shared, size_t size, const std::string &name);
+    Reader(const sp<IMemory>& iMemory, size_t size, const std::string &name);
+    ~Reader() override;
+
+    // get snapshot of readers fifo buffer, effectively consuming the buffer
+    std::unique_ptr<Snapshot> getSnapshot(bool flush = true);
+    bool     isIMemory(const sp<IMemory>& iMemory) const;
+    const std::string &name() const { return mName; }
+
+private:
+    // Amount of tries for reader to catch up with writer in getSnapshot().
+    static constexpr int kMaxObtainTries = 3;
+
+    // invalidBeginTypes and invalidEndTypes are used to align the Snapshot::begin() and
+    // Snapshot::end() EntryIterators to valid entries.
+    static const std::unordered_set<Event> invalidBeginTypes;
+    static const std::unordered_set<Event> invalidEndTypes;
+
+    // declared as const because audio_utils_fifo() constructor
+    sp<IMemory> mIMemory;       // ref-counted version, assigned only in constructor
+
+    const std::string mName;            // name of reader (actually name of writer)
+    /*const*/ Shared* const mShared;    // raw pointer to shared memory, actually const but not
+    audio_utils_fifo * const mFifo;                 // FIFO itself,
+                                                    // non-NULL unless constructor fails
+    audio_utils_fifo_reader * const mFifoReader;    // used to read from FIFO,
+                                                    // non-NULL unless constructor fails
+
+    // Searches for the last valid entry in the range [front, back)
+    // back has to be entry-aligned. Returns nullptr if none enconuntered.
+    static const uint8_t *findLastValidEntry(const uint8_t *front, const uint8_t *back,
+                                               const std::unordered_set<Event> &invalidTypes);
+};
+
+// A snapshot of a readers buffer
+// This is raw data. No analysis has been done on it
+class Snapshot {
+public:
+    ~Snapshot() { delete[] mData; }
+
+    // amount of data lost (given by audio_utils_fifo_reader)
+    size_t lost() const { return mLost; }
+
+    // iterator to beginning of readable segment of snapshot
+    // data between begin and end has valid entries
+    EntryIterator begin() const { return mBegin; }
+
+    // iterator to end of readable segment of snapshot
+    EntryIterator end() const { return mEnd; }
+
+private:
+    Snapshot() = default;
+    explicit Snapshot(size_t bufferSize) : mData(new uint8_t[bufferSize]) {}
+    friend std::unique_ptr<Snapshot> Reader::getSnapshot(bool flush);
+
+    uint8_t * const       mData = nullptr;
+    size_t                mLost = 0;
+    EntryIterator         mBegin;
+    EntryIterator         mEnd;
+};
+
+// TODO move this to MediaLogService?
+class DumpReader : public NBLog::Reader {
+public:
+    DumpReader(const void *shared, size_t size, const std::string &name)
+        : Reader(shared, size, name) {}
+    DumpReader(const sp<IMemory>& iMemory, size_t size, const std::string &name)
+        : Reader(iMemory, size, name) {}
+    void dump(int fd, size_t indent = 0);
+private:
+    void handleAuthor(const AbstractEntry& fmtEntry __unused, String8* body __unused) {}
+    EntryIterator handleFormat(const FormatEntry &fmtEntry, String8 *timestamp, String8 *body);
+
+    static void    appendInt(String8 *body, const void *data);
+    static void    appendFloat(String8 *body, const void *data);
+    static void    appendPID(String8 *body, const void *data, size_t length);
+    static void    appendTimestamp(String8 *body, const void *data);
+
+    // The bufferDump functions are used for debugging only.
+    static String8 bufferDump(const uint8_t *buffer, size_t size);
+    static String8 bufferDump(const EntryIterator &it);
+};
+
+}   // namespace NBLog
+}   // namespace android
+
+#endif  // ANDROID_MEDIA_NBLOG_READER_H
diff --git a/media/libnblog/include/media/nblog/ReportPerformance.h b/media/libnblog/include/media/nblog/ReportPerformance.h
index ec0842f..64a5701 100644
--- a/media/libnblog/include/media/nblog/ReportPerformance.h
+++ b/media/libnblog/include/media/nblog/ReportPerformance.h
@@ -22,19 +22,33 @@
 #include <vector>
 
 namespace android {
-
-// The String8 class is used by reportPerformance function
-class String8;
-
 namespace ReportPerformance {
 
+struct PerformanceData;
+
+// Dumps performance data in a JSON format.
+void dumpJson(int fd, const std::map<int, PerformanceData>& threadDataMap);
+
+//Dumps performance data as visualized plots.
+void dumpPlots(int fd, const std::map<int, PerformanceData>& threadDataMap);
+
+// Dumps snapshots at important events in the past.
+void dumpRetro(int fd, const std::map<int, PerformanceData>& threadDataMap);
+
+// Send one thread's data to media metrics, if the performance data is nontrivial (i.e. not
+// all zero values). Return true if data was sent, false if there is nothing to write
+// or an error occurred while writing.
+bool sendToMediaMetrics(const PerformanceData& data);
+
+//------------------------------------------------------------------------------
+
 constexpr int kMsPerSec = 1000;
 constexpr int kSecPerMin = 60;
 
 constexpr int kJiffyPerMs = 10; // time unit for histogram as a multiple of milliseconds
 
 // stores a histogram: key: observed buffer period (multiple of jiffy). value: count
-using Histogram = std::map<int, int>;
+using Hist = std::map<int, int>;
 
 using msInterval = double;
 using jiffyInterval = double;
@@ -57,13 +71,12 @@
 }
 
 // Writes outlier intervals, timestamps, peaks timestamps, and histograms to a file.
-void writeToFile(const std::deque<std::pair<timestamp, Histogram>> &hists,
+void writeToFile(const std::deque<std::pair<timestamp, Hist>> &hists,
                  const std::deque<std::pair<msInterval, timestamp>> &outlierData,
                  const std::deque<timestamp> &peakTimestamps,
                  const char * kDirectory, bool append, int author, log_hash_t hash);
 
-} // namespace ReportPerformance
-
+}   // namespace ReportPerformance
 }   // namespace android
 
 #endif  // ANDROID_MEDIA_REPORTPERFORMANCE_H
diff --git a/media/libnblog/include/media/nblog/Timeline.h b/media/libnblog/include/media/nblog/Timeline.h
new file mode 100644
index 0000000..d4f0cff
--- /dev/null
+++ b/media/libnblog/include/media/nblog/Timeline.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_MEDIA_NBLOG_TIMELINE_H
+#define ANDROID_MEDIA_NBLOG_TIMELINE_H
+
+#include <stddef.h>
+
+#include <audio_utils/fifo_index.h>
+#include <utils/RefBase.h>
+
+namespace android {
+namespace NBLog {
+
+// Located in shared memory, must be POD.
+// Exactly one process must explicitly call the constructor or use placement new.
+// Since this is a POD, the destructor is empty and unnecessary to call it explicitly.
+struct Shared {
+    Shared() /* mRear initialized via default constructor */ {}
+    ~Shared() {}
+
+    audio_utils_fifo_index  mRear;  // index one byte past the end of most recent Entry
+    char    mBuffer[0];             // circular buffer for entries
+};
+
+// FIXME Timeline was intended to wrap Writer and Reader, but isn't actually used yet.
+// For now it is just a namespace for sharedSize().
+class Timeline : public RefBase {
+public:
+#if 0
+    Timeline(size_t size, void *shared = NULL);
+    virtual ~Timeline();
+#endif
+
+    // Input parameter 'size' is the desired size of the timeline in byte units.
+    // Returns the size rounded up to a power-of-2, plus the constant size overhead for indices.
+    static size_t sharedSize(size_t size);
+
+#if 0
+private:
+    friend class    Writer;
+    friend class    Reader;
+
+    const size_t    mSize;      // circular buffer size in bytes, must be a power of 2
+    bool            mOwn;       // whether I own the memory at mShared
+    Shared* const   mShared;    // pointer to shared memory
+#endif
+};
+
+}   // namespace NBLog
+}   // namespace android
+
+#endif  // ANDROID_MEDIA_NBLOG_TIMELINE_H
diff --git a/media/libnblog/include/media/nblog/Writer.h b/media/libnblog/include/media/nblog/Writer.h
new file mode 100644
index 0000000..7fcd396
--- /dev/null
+++ b/media/libnblog/include/media/nblog/Writer.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_MEDIA_NBLOG_WRITER_H
+#define ANDROID_MEDIA_NBLOG_WRITER_H
+
+#include <stdarg.h>
+#include <stddef.h>
+
+#include <binder/IMemory.h>
+#include <media/nblog/Events.h>
+#include <utils/Mutex.h>
+#include <utils/RefBase.h>
+
+class audio_utils_fifo;
+class audio_utils_fifo_writer;
+
+namespace android {
+
+class IMemory;
+
+namespace NBLog {
+
+class Entry;
+struct Shared;
+
+// NBLog Writer Interface
+
+// Writer is thread-safe with respect to Reader, but not with respect to multiple threads
+// calling Writer methods.  If you need multi-thread safety for writing, use LockedWriter.
+class Writer : public RefBase {
+public:
+    Writer() = default;         // dummy nop implementation without shared memory
+
+    // Input parameter 'size' is the desired size of the timeline in byte units.
+    // The size of the shared memory must be at least Timeline::sharedSize(size).
+    Writer(void *shared, size_t size);
+    Writer(const sp<IMemory>& iMemory, size_t size);
+
+    ~Writer() override;
+
+    // FIXME needs comments, and some should be private
+    void    log(const char *string);
+    void    logf(const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
+    void    logTimestamp();
+    void    logFormat(const char *fmt, log_hash_t hash, ...);
+    void    logEventHistTs(Event event, log_hash_t hash);
+
+    // Log data related to Event E. See the event-to-type mapping for the type of data
+    // corresponding to the event. For example, if you see a mapping statement:
+    //     MAP_TYPE_TO_EVENT(E, T);
+    // then the usage of this method would be:
+    //     T data = doComputation();
+    //     tlNBLogWriter->log<NBLog::E>(data);
+    template<Event E>
+    void    log(typename get_mapped<E>::type data) {
+        log(E, &data, sizeof(data));
+    }
+
+    virtual bool    isEnabled() const;
+
+    // return value for all of these is the previous isEnabled()
+    virtual bool    setEnabled(bool enabled);   // but won't enable if no shared memory
+    bool            enable()  { return setEnabled(true); }
+    bool            disable() { return setEnabled(false); }
+
+    sp<IMemory>     getIMemory() const { return mIMemory; }
+
+    // Public logging function implementations should always use one of the
+    // two log() function calls below to write to shared memory.
+protected:
+    // Writes a single Entry to the FIFO if the writer is enabled.
+    // This is protected and virtual because LockedWriter uses a lock to protect
+    // writing to the FIFO before writing to this function.
+    virtual void log(const Entry &entry, bool trusted = false);
+
+private:
+    // 0 <= length <= kMaxLength
+    // Log a single Entry with corresponding event, data, and length.
+    void    log(Event event, const void *data, size_t length);
+
+    void    logvf(const char *fmt, va_list ap);
+
+    // helper functions for logging parts of a formatted entry
+    void    logStart(const char *fmt);
+    void    logTimestampFormat();
+    void    logVFormat(const char *fmt, log_hash_t hash, va_list ap);
+
+    Shared* const   mShared{};          // raw pointer to shared memory
+    sp<IMemory>     mIMemory{};         // ref-counted version, initialized in constructor
+                                        // and then const
+    audio_utils_fifo * const mFifo{};               // FIFO itself, non-NULL
+                                                    // unless constructor fails
+                                                    // or dummy constructor used
+    audio_utils_fifo_writer * const mFifoWriter{};  // used to write to FIFO, non-NULL
+                                                    // unless dummy constructor used
+    bool            mEnabled = false;   // whether to actually log
+
+    // cached pid and process name to use in %p format specifier
+    // total tag length is mPidTagSize and process name is not zero terminated
+    char   *mPidTag{};
+    size_t  mPidTagSize = 0;
+};
+
+// ---------------------------------------------------------------------------
+
+// Similar to Writer, but safe for multiple threads to call concurrently
+class LockedWriter : public Writer {
+public:
+    LockedWriter() = default;
+    LockedWriter(void *shared, size_t size);
+
+    bool    isEnabled() const override;
+    bool    setEnabled(bool enabled) override;
+
+private:
+    // Lock needs to be obtained before writing to FIFO.
+    void log(const Entry &entry, bool trusted = false) override;
+
+    mutable Mutex   mLock;
+};
+
+}   // namespace NBLog
+}   // namespace android
+
+#endif  // ANDROID_MEDIA_NBLOG_WRITER_H
diff --git a/media/libstagefright/AACWriter.cpp b/media/libstagefright/AACWriter.cpp
index 2ea5fcd..e173974 100644
--- a/media/libstagefright/AACWriter.cpp
+++ b/media/libstagefright/AACWriter.cpp
@@ -85,7 +85,7 @@
     CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC));
     CHECK(meta->findInt32(kKeyChannelCount, &mChannelCount));
     CHECK(meta->findInt32(kKeySampleRate, &mSampleRate));
-    CHECK(mChannelCount >= 1 && mChannelCount <= 2);
+    CHECK(mChannelCount >= 1 && mChannelCount <= 7);
 
     // Optionally, we want to check whether AACProfile is also set.
     if (meta->findInt32(kKeyAACProfile, &mAACProfile)) {
@@ -154,11 +154,11 @@
     mDone = true;
 
     void *dummy;
+    status_t status = mSource->stop();
     pthread_join(mThread, &dummy);
 
     status_t err = static_cast<status_t>(reinterpret_cast<uintptr_t>(dummy));
     {
-        status_t status = mSource->stop();
         if (err == OK &&
             (status != OK && status != ERROR_END_OF_STREAM)) {
             err = status;
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 7f39d10..3d67c91 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -37,6 +37,7 @@
 
 #include <media/stagefright/BufferProducerWrapper.h>
 #include <media/stagefright/MediaCodec.h>
+#include <media/stagefright/MediaCodecConstants.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/OMXClient.h>
 #include <media/stagefright/PersistentSurface.h>
@@ -171,11 +172,7 @@
 }
 
 struct CodecObserver : public BnOMXObserver {
-    CodecObserver() {}
-
-    void setNotificationMessage(const sp<AMessage> &msg) {
-        mNotify = msg;
-    }
+    explicit CodecObserver(const sp<AMessage> &msg) : mNotify(msg) {}
 
     // from IOMXObserver
     virtual void onMessages(const std::list<omx_message> &messages) {
@@ -251,7 +248,7 @@
     virtual ~CodecObserver() {}
 
 private:
-    sp<AMessage> mNotify;
+    const sp<AMessage> mNotify;
 
     DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
 };
@@ -566,16 +563,16 @@
       mDequeueCounter(0),
       mMetadataBuffersToSubmit(0),
       mNumUndequeuedBuffers(0),
-      mRepeatFrameDelayUs(-1ll),
-      mMaxPtsGapUs(0ll),
+      mRepeatFrameDelayUs(-1LL),
+      mMaxPtsGapUs(0LL),
       mMaxFps(-1),
       mFps(-1.0),
       mCaptureFps(-1.0),
       mCreateInputBuffersSuspended(false),
-      mLatency(0),
       mTunneled(false),
       mDescribeColorAspectsIndex((OMX_INDEXTYPE)0),
       mDescribeHDRStaticInfoIndex((OMX_INDEXTYPE)0),
+      mDescribeHDR10PlusInfoIndex((OMX_INDEXTYPE)0),
       mStateGeneration(0),
       mVendorExtensionsStatus(kExtensionsUnchecked) {
     memset(&mLastHDRStaticInfo, 0, sizeof(mLastHDRStaticInfo));
@@ -783,6 +780,9 @@
     // need to enable allocation when attaching
     surface->getIGraphicBufferProducer()->allowAllocation(true);
 
+    // dequeueBuffer cannot time out
+    surface->setDequeueTimeout(-1);
+
     // for meta data mode, we move dequeud buffers to the new surface.
     // for non-meta mode, we must move all registered buffers
     for (size_t i = 0; i < buffers.size(); ++i) {
@@ -1138,6 +1138,8 @@
         return err;
     }
 
+    static_cast<Surface *>(mNativeWindow.get())->setDequeueTimeout(-1);
+
     // Exits here for tunneled video playback codecs -- i.e. skips native window
     // buffer allocation step as this is managed by the tunneled OMX omponent
     // itself and explicitly sets def.nBufferCountActual to 0.
@@ -1247,6 +1249,7 @@
         info.mRenderInfo = NULL;
         info.mGraphicBuffer = graphicBuffer;
         info.mNewGraphicBuffer = false;
+        info.mDequeuedAt = mDequeueCounter;
 
         // TODO: We shouln't need to create MediaCodecBuffer. In metadata mode
         //       OMX doesn't use the shared memory buffer, but some code still
@@ -1619,7 +1622,7 @@
             if (portIndex == kPortIndexOutput && mNativeWindow != NULL) {
                 (void)cancelBufferToNativeWindow(info);
             }
-            // fall through
+            FALLTHROUGH_INTENDED;
 
         case BufferInfo::OWNED_BY_NATIVE_WINDOW:
             err = mOMXNode->freeBuffer(portIndex, info->mBufferID);
@@ -1748,34 +1751,37 @@
     }
 
     int32_t storeMeta;
-    if (encoder
-            && msg->findInt32("android._input-metadata-buffer-type", &storeMeta)
-            && storeMeta != kMetadataBufferTypeInvalid) {
-        IOMX::PortMode mode;
-        if (storeMeta == kMetadataBufferTypeNativeHandleSource) {
-            mode = IOMX::kPortModeDynamicNativeHandle;
-        } else if (storeMeta == kMetadataBufferTypeANWBuffer ||
-                storeMeta == kMetadataBufferTypeGrallocSource) {
-            mode = IOMX::kPortModeDynamicANWBuffer;
-        } else {
-            return BAD_VALUE;
+    if (encoder) {
+        IOMX::PortMode mode = IOMX::kPortModePresetByteBuffer;
+        if (msg->findInt32("android._input-metadata-buffer-type", &storeMeta)
+                && storeMeta != kMetadataBufferTypeInvalid) {
+            if (storeMeta == kMetadataBufferTypeNativeHandleSource) {
+                mode = IOMX::kPortModeDynamicNativeHandle;
+            } else if (storeMeta == kMetadataBufferTypeANWBuffer ||
+                    storeMeta == kMetadataBufferTypeGrallocSource) {
+                mode = IOMX::kPortModeDynamicANWBuffer;
+            } else {
+                return BAD_VALUE;
+            }
         }
         err = setPortMode(kPortIndexInput, mode);
         if (err != OK) {
             return err;
         }
 
-        uint32_t usageBits;
-        if (mOMXNode->getParameter(
-                (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
-                &usageBits, sizeof(usageBits)) == OK) {
-            inputFormat->setInt32(
-                    "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
+        if (mode != IOMX::kPortModePresetByteBuffer) {
+            uint32_t usageBits;
+            if (mOMXNode->getParameter(
+                    (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
+                    &usageBits, sizeof(usageBits)) == OK) {
+                inputFormat->setInt32(
+                        "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
+            }
         }
     }
 
     int32_t prependSPSPPS = 0;
-    if (encoder
+    if (encoder && mIsVideo
             && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
             && prependSPSPPS != 0) {
         OMX_INDEXTYPE index;
@@ -1816,25 +1822,24 @@
         }
 
         if (!msg->findInt64(
-                    "repeat-previous-frame-after",
-                    &mRepeatFrameDelayUs)) {
-            mRepeatFrameDelayUs = -1ll;
+                KEY_REPEAT_PREVIOUS_FRAME_AFTER, &mRepeatFrameDelayUs)) {
+            mRepeatFrameDelayUs = -1LL;
         }
 
         // only allow 32-bit value, since we pass it as U32 to OMX.
-        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
-            mMaxPtsGapUs = 0ll;
+        if (!msg->findInt64(KEY_MAX_PTS_GAP_TO_ENCODER, &mMaxPtsGapUs)) {
+            mMaxPtsGapUs = 0LL;
         } else if (mMaxPtsGapUs > INT32_MAX || mMaxPtsGapUs < INT32_MIN) {
             ALOGW("Unsupported value for max pts gap %lld", (long long) mMaxPtsGapUs);
-            mMaxPtsGapUs = 0ll;
+            mMaxPtsGapUs = 0LL;
         }
 
-        if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
+        if (!msg->findFloat(KEY_MAX_FPS_TO_ENCODER, &mMaxFps)) {
             mMaxFps = -1;
         }
 
         // notify GraphicBufferSource to allow backward frames
-        if (mMaxPtsGapUs < 0ll) {
+        if (mMaxPtsGapUs < 0LL) {
             mMaxFps = -1;
         }
 
@@ -1843,8 +1848,8 @@
         }
 
         if (!msg->findInt32(
-                    "create-input-buffers-suspended",
-                    (int32_t*)&mCreateInputBuffersSuspended)) {
+                KEY_CREATE_INPUT_SURFACE_SUSPENDED,
+                (int32_t*)&mCreateInputBuffersSuspended)) {
             mCreateInputBuffersSuspended = false;
         }
     }
@@ -2088,7 +2093,8 @@
         if (usingSwRenderer) {
             outputFormat->setInt32("using-sw-renderer", 1);
         }
-    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
+    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG) ||
+        !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II)) {
         int32_t numChannels, sampleRate;
         if (!msg->findInt32("channel-count", &numChannels)
                 || !msg->findInt32("sample-rate", &sampleRate)) {
@@ -2179,7 +2185,8 @@
             err = setupG711Codec(encoder, sampleRate, numChannels);
         }
     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
-        int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
+        // numChannels needs to be set to properly communicate PCM values.
+        int32_t numChannels = 2, sampleRate = 44100, compressionLevel = -1;
         if (encoder &&
                 (!msg->findInt32("channel-count", &numChannels)
                         || !msg->findInt32("sample-rate", &sampleRate))) {
@@ -2205,7 +2212,7 @@
                 }
             }
             err = setupFlacCodec(
-                    encoder, numChannels, sampleRate, compressionLevel);
+                    encoder, numChannels, sampleRate, compressionLevel, pcmEncoding);
         }
     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
         int32_t numChannels, sampleRate;
@@ -2234,6 +2241,15 @@
         } else {
             err = setupEAC3Codec(encoder, numChannels, sampleRate);
         }
+     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC4)) {
+        int32_t numChannels;
+        int32_t sampleRate;
+        if (!msg->findInt32("channel-count", &numChannels)
+                || !msg->findInt32("sample-rate", &sampleRate)) {
+            err = INVALID_OPERATION;
+        } else {
+            err = setupAC4Codec(encoder, numChannels, sampleRate);
+        }
     }
 
     if (err != OK) {
@@ -2307,12 +2323,16 @@
             (void)mInputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
             mConverter[kPortIndexInput] = AudioConverter::Create(pcmEncoding, codecPcmEncoding);
             if (mConverter[kPortIndexInput] != NULL) {
+                ALOGD("%s: encoder %s input format pcm encoding converter from %d to %d",
+                        __func__, mComponentName.c_str(), pcmEncoding, codecPcmEncoding);
                 mInputFormat->setInt32("pcm-encoding", pcmEncoding);
             }
         } else {
             (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
             mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
             if (mConverter[kPortIndexOutput] != NULL) {
+                ALOGD("%s: decoder %s output format pcm encoding converter from %d to %d",
+                        __func__, mComponentName.c_str(), codecPcmEncoding, pcmEncoding);
                 mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
             }
         }
@@ -2345,6 +2365,17 @@
     return err;
 }
 
+status_t ACodec::setAudioPresentation(int32_t presentationId, int32_t programId) {
+    OMX_AUDIO_CONFIG_ANDROID_AUDIOPRESENTATION config;
+    InitOMXParams(&config);
+    config.nPresentationId = (OMX_S32)presentationId;
+    config.nProgramId = (OMX_S32)programId;
+    status_t err = mOMXNode->setConfig(
+            (OMX_INDEXTYPE)OMX_IndexConfigAudioPresentation,
+            &config, sizeof(config));
+    return err;
+}
+
 status_t ACodec::setPriority(int32_t priority) {
     if (priority < 0) {
         return BAD_VALUE;
@@ -2551,6 +2582,8 @@
         layerParams.nPLayerCountActual = numLayers - numBLayers;
         layerParams.nBLayerCountActual = numBLayers;
         layerParams.bBitrateRatiosSpecified = OMX_FALSE;
+        layerParams.nLayerCountMax = numLayers;
+        layerParams.nBLayerCountMax = numBLayers;
 
         err = mOMXNode->setParameter(
                 (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
@@ -2890,6 +2923,38 @@
             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, &def, sizeof(def));
 }
 
+status_t ACodec::setupAC4Codec(
+        bool encoder, int32_t numChannels, int32_t sampleRate) {
+    status_t err = setupRawAudioFormat(
+            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
+
+    if (err != OK) {
+        return err;
+    }
+
+    if (encoder) {
+        ALOGW("AC4 encoding is not supported.");
+        return INVALID_OPERATION;
+    }
+
+    OMX_AUDIO_PARAM_ANDROID_AC4TYPE def;
+    InitOMXParams(&def);
+    def.nPortIndex = kPortIndexInput;
+
+    err = mOMXNode->getParameter(
+            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc4, &def, sizeof(def));
+
+    if (err != OK) {
+        return err;
+    }
+
+    def.nChannels = numChannels;
+    def.nSampleRate = sampleRate;
+
+    return mOMXNode->setParameter(
+            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc4, &def, sizeof(def));
+}
+
 static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
         bool isAMRWB, int32_t bps) {
     if (isAMRWB) {
@@ -2973,8 +3038,8 @@
 }
 
 status_t ACodec::setupFlacCodec(
-        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
-
+        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel,
+        AudioEncoding encoding) {
     if (encoder) {
         OMX_AUDIO_PARAM_FLACTYPE def;
         InitOMXParams(&def);
@@ -2997,7 +3062,8 @@
     return setupRawAudioFormat(
             encoder ? kPortIndexInput : kPortIndexOutput,
             sampleRate,
-            numChannels);
+            numChannels,
+            encoding);
 }
 
 status_t ACodec::setupRawAudioFormat(
@@ -3055,6 +3121,7 @@
     pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
 
     if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
+        ALOGE("%s: incorrect numChannels: %d", __func__, numChannels);
         return OMX_ErrorNone;
     }
 
@@ -3710,8 +3777,17 @@
             "OMX.google.android.index.describeHDRStaticInfo", &mDescribeHDRStaticInfoIndex);
     if (err != OK) {
         mDescribeHDRStaticInfoIndex = (OMX_INDEXTYPE)0;
+        return err;
     }
-    return err;
+
+    err = mOMXNode->getExtensionIndex(
+                "OMX.google.android.index.describeHDR10PlusInfo", &mDescribeHDR10PlusInfoIndex);
+    if (err != OK) {
+        mDescribeHDR10PlusInfoIndex = (OMX_INDEXTYPE)0;
+        return err;
+    }
+
+    return OK;
 }
 
 status_t ACodec::setHDRStaticInfo(const DescribeHDRStaticInfoParams &params) {
@@ -4225,24 +4301,27 @@
     int maxDimension = max(width, height);
 
     static const int limits[][5] = {
-        /*   MBps     MB   dim  bitrate        level */
-        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
-        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
-        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
-        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
-        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
-        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
-        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
-        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
-        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
-        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
-        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
-        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
-        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
-        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
-        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
-        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
-        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
+        /*    MBps      MB   dim  bitrate        level */
+        {     1485,     99,   28,     64, OMX_VIDEO_AVCLevel1  },
+        {     1485,     99,   28,    128, OMX_VIDEO_AVCLevel1b },
+        {     3000,    396,   56,    192, OMX_VIDEO_AVCLevel11 },
+        {     6000,    396,   56,    384, OMX_VIDEO_AVCLevel12 },
+        {    11880,    396,   56,    768, OMX_VIDEO_AVCLevel13 },
+        {    11880,    396,   56,   2000, OMX_VIDEO_AVCLevel2  },
+        {    19800,    792,   79,   4000, OMX_VIDEO_AVCLevel21 },
+        {    20250,   1620,  113,   4000, OMX_VIDEO_AVCLevel22 },
+        {    40500,   1620,  113,  10000, OMX_VIDEO_AVCLevel3  },
+        {   108000,   3600,  169,  14000, OMX_VIDEO_AVCLevel31 },
+        {   216000,   5120,  202,  20000, OMX_VIDEO_AVCLevel32 },
+        {   245760,   8192,  256,  20000, OMX_VIDEO_AVCLevel4  },
+        {   245760,   8192,  256,  50000, OMX_VIDEO_AVCLevel41 },
+        {   522240,   8704,  263,  50000, OMX_VIDEO_AVCLevel42 },
+        {   589824,  22080,  420, 135000, OMX_VIDEO_AVCLevel5  },
+        {   983040,  36864,  543, 240000, OMX_VIDEO_AVCLevel51 },
+        {  2073600,  36864,  543, 240000, OMX_VIDEO_AVCLevel52 },
+        {  4177920, 139264, 1055, 240000, OMX_VIDEO_AVCLevel6  },
+        {  8355840, 139264, 1055, 480000, OMX_VIDEO_AVCLevel61 },
+        { 16711680, 139264, 1055, 800000, OMX_VIDEO_AVCLevel62 },
     };
 
     for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
@@ -4352,12 +4431,13 @@
             h264type.eProfile == OMX_VIDEO_AVCProfileHigh) {
         h264type.nSliceHeaderSpacing = 0;
         h264type.bUseHadamard = OMX_TRUE;
-        h264type.nRefFrames = 2;
-        h264type.nBFrames = mLatency == 0 ? 1 : std::min(1U, mLatency - 1);
-
-        // disable B-frames until MPEG4Writer can guarantee finalizing files with B-frames
-        h264type.nRefFrames = 1;
-        h264type.nBFrames = 0;
+        int32_t maxBframes = 0;
+        (void)msg->findInt32(KEY_MAX_B_FRAMES, &maxBframes);
+        h264type.nBFrames = uint32_t(maxBframes);
+        if (mLatency && h264type.nBFrames > *mLatency) {
+            h264type.nBFrames = *mLatency;
+        }
+        h264type.nRefFrames = h264type.nBFrames == 0 ? 1 : 2;
 
         h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
         h264type.nAllowedPictureTypes =
@@ -5019,6 +5099,7 @@
                         }
                     }
                     // Fall through to set up mime.
+                    FALLTHROUGH_INTENDED;
                 }
 
                 default:
@@ -5123,6 +5204,7 @@
                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
                     notify->setInt32("channel-count", params.nChannels);
                     notify->setInt32("sample-rate", params.nSampleRate);
+                    notify->setInt32("bitrate", params.nBitRate);
                     break;
                 }
 
@@ -5241,6 +5323,25 @@
                     break;
                 }
 
+                case OMX_AUDIO_CodingAndroidAC4:
+                {
+                    OMX_AUDIO_PARAM_ANDROID_AC4TYPE params;
+                    InitOMXParams(&params);
+                    params.nPortIndex = portIndex;
+
+                    err = mOMXNode->getParameter(
+                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc4,
+                            &params, sizeof(params));
+                    if (err != OK) {
+                        return err;
+                    }
+
+                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC4);
+                    notify->setInt32("channel-count", params.nChannels);
+                    notify->setInt32("sample-rate", params.nSampleRate);
+                    break;
+                }
+
                 case OMX_AUDIO_CodingAndroidOPUS:
                 {
                     OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
@@ -5321,6 +5422,70 @@
     return getVendorParameters(portIndex, notify);
 }
 
+DescribeHDR10PlusInfoParams* ACodec::getHDR10PlusInfo(size_t paramSizeUsed) {
+    if (mDescribeHDR10PlusInfoIndex == 0) {
+        ALOGE("getHDR10PlusInfo: does not support DescribeHDR10PlusInfoParams");
+        return nullptr;
+    }
+
+    size_t newSize = sizeof(DescribeHDR10PlusInfoParams) - 1 +
+            ((paramSizeUsed > 0) ? paramSizeUsed : 512);
+    if (mHdr10PlusScratchBuffer == nullptr
+            || newSize > mHdr10PlusScratchBuffer->size()) {
+        mHdr10PlusScratchBuffer = new ABuffer(newSize);
+    }
+    DescribeHDR10PlusInfoParams *config =
+            (DescribeHDR10PlusInfoParams *)mHdr10PlusScratchBuffer->data();
+    InitOMXParams(config);
+    config->nSize = mHdr10PlusScratchBuffer->size();
+    config->nPortIndex = 1;
+    size_t paramSize = config->nSize - sizeof(DescribeHDR10PlusInfoParams) + 1;
+    config->nParamSize = paramSize;
+    config->nParamSizeUsed = 0;
+    status_t err = mOMXNode->getConfig(
+            (OMX_INDEXTYPE)mDescribeHDR10PlusInfoIndex,
+            config, config->nSize);
+    if (err != OK) {
+        ALOGE("failed to get DescribeHDR10PlusInfoParams (err %d)", err);
+        return nullptr;
+    }
+    if (config->nParamSize != paramSize) {
+        ALOGE("DescribeHDR10PlusInfoParams alters nParamSize: %u vs %zu",
+                config->nParamSize, paramSize);
+        return nullptr;
+    }
+    if (paramSizeUsed > 0 && config->nParamSizeUsed != paramSizeUsed) {
+        ALOGE("DescribeHDR10PlusInfoParams returns wrong nParamSizeUsed: %u vs %zu",
+                config->nParamSizeUsed, paramSizeUsed);
+        return nullptr;
+    }
+    return config;
+}
+
+void ACodec::onConfigUpdate(OMX_INDEXTYPE configIndex) {
+    if (mDescribeHDR10PlusInfoIndex == 0
+            || configIndex != mDescribeHDR10PlusInfoIndex) {
+        // mDescribeHDR10PlusInfoIndex is the only update we recognize now
+        return;
+    }
+
+    DescribeHDR10PlusInfoParams *config = getHDR10PlusInfo();
+    if (config == nullptr) {
+        return;
+    }
+    if (config->nParamSizeUsed > config->nParamSize) {
+        // try again with the size specified
+        config = getHDR10PlusInfo(config->nParamSizeUsed);
+        if (config == nullptr) {
+            return;
+        }
+    }
+
+    mOutputFormat = mOutputFormat->dup(); // trigger an output format changed event
+    mOutputFormat->setBuffer("hdr10-plus-info",
+            ABuffer::CreateAsCopy(config->nValue, config->nParamSizeUsed));
+}
+
 void ACodec::onDataSpaceChanged(android_dataspace dataSpace, const ColorAspects &aspects) {
     // aspects are normally communicated in ColorAspects
     int32_t range, standard, transfer;
@@ -5383,7 +5548,7 @@
         AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
         (void)mConfigFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
         AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
-        (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
+        (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
 
         mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
         if (mConverter[kPortIndexOutput] != NULL) {
@@ -5556,6 +5721,11 @@
             break;
         }
 
+        case kWhatCheckIfStuck: {
+            ALOGV("No-op by default");
+            break;
+        }
+
         default:
             return false;
     }
@@ -6256,6 +6426,15 @@
             }
         }
 
+        sp<ABuffer> hdr10PlusInfo;
+        if (buffer->format()->findBuffer("hdr10-plus-info", &hdr10PlusInfo)
+                && hdr10PlusInfo != nullptr && hdr10PlusInfo->size() > 0
+                && hdr10PlusInfo != mCodec->mLastHdr10PlusBuffer) {
+            native_window_set_buffers_hdr10_plus_metadata(mCodec->mNativeWindow.get(),
+                    hdr10PlusInfo->size(), hdr10PlusInfo->data());
+            mCodec->mLastHdr10PlusBuffer = hdr10PlusInfo;
+        }
+
         // save buffers sent to the surface so we can get render time when they return
         int64_t mediaTimeUs = -1;
         buffer->meta()->findInt64("timeUs", &mediaTimeUs);
@@ -6364,8 +6543,10 @@
 
     if (mDeathNotifier != NULL) {
         if (mCodec->mOMXNode != NULL) {
-            auto tOmxNode = mCodec->mOMXNode->getHalInterface();
-            tOmxNode->unlinkToDeath(mDeathNotifier);
+            auto tOmxNode = mCodec->mOMXNode->getHalInterface<IOmxNode>();
+            if (tOmxNode) {
+                tOmxNode->unlinkToDeath(mDeathNotifier);
+            }
         }
         mDeathNotifier.clear();
     }
@@ -6452,7 +6633,8 @@
 
     CHECK(mCodec->mOMXNode == NULL);
 
-    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
+    sp<AMessage> notify = new AMessage(kWhatOMXMessageList, mCodec);
+    notify->setInt32("generation", mCodec->mNodeGeneration + 1);
 
     sp<RefBase> obj;
     CHECK(msg->findObject("codecInfo", &obj));
@@ -6467,7 +6649,7 @@
     AString componentName;
     CHECK(msg->findString("componentName", &componentName));
 
-    sp<CodecObserver> observer = new CodecObserver;
+    sp<CodecObserver> observer = new CodecObserver(notify);
     sp<IOMX> omx;
     sp<IOMXNode> omxNode;
 
@@ -6492,15 +6674,13 @@
         return false;
     }
 
-    mDeathNotifier = new DeathNotifier(notify);
-    auto tOmxNode = omxNode->getHalInterface();
-    if (!tOmxNode->linkToDeath(mDeathNotifier, 0)) {
+    mDeathNotifier = new DeathNotifier(new AMessage(kWhatOMXDied, mCodec));
+    auto tOmxNode = omxNode->getHalInterface<IOmxNode>();
+    if (tOmxNode && !tOmxNode->linkToDeath(mDeathNotifier, 0)) {
         mDeathNotifier.clear();
     }
 
-    notify = new AMessage(kWhatOMXMessageList, mCodec);
-    notify->setInt32("generation", ++mCodec->mNodeGeneration);
-    observer->setNotificationMessage(notify);
+    ++mCodec->mNodeGeneration;
 
     mCodec->mComponentName = componentName;
     mCodec->mRenderTracker.setComponentName(componentName);
@@ -6536,7 +6716,7 @@
 
     mCodec->mDequeueCounter = 0;
     mCodec->mMetadataBuffersToSubmit = 0;
-    mCodec->mRepeatFrameDelayUs = -1ll;
+    mCodec->mRepeatFrameDelayUs = -1LL;
     mCodec->mInputFormat.clear();
     mCodec->mOutputFormat.clear();
     mCodec->mBaseOutputFormat.clear();
@@ -6678,7 +6858,7 @@
         return err;
     }
 
-    if (mCodec->mRepeatFrameDelayUs > 0ll) {
+    if (mCodec->mRepeatFrameDelayUs > 0LL) {
         err = statusFromBinderStatus(
                 mCodec->mGraphicBufferSource->setRepeatPreviousFrameDelayUs(
                         mCodec->mRepeatFrameDelayUs));
@@ -6691,7 +6871,7 @@
         }
     }
 
-    if (mCodec->mMaxPtsGapUs != 0ll) {
+    if (mCodec->mMaxPtsGapUs != 0LL) {
         OMX_PARAM_U32TYPE maxPtsGapParams;
         InitOMXParams(&maxPtsGapParams);
         maxPtsGapParams.nPortIndex = kPortIndexInput;
@@ -7258,7 +7438,7 @@
     }
 
     int64_t timeOffsetUs;
-    if (params->findInt64("time-offset-us", &timeOffsetUs)) {
+    if (params->findInt64(PARAMETER_KEY_OFFSET_TIME, &timeOffsetUs)) {
         if (mGraphicBufferSource == NULL) {
             ALOGE("[%s] Invalid to set input buffer time offset without surface",
                     mComponentName.c_str());
@@ -7294,7 +7474,7 @@
     }
 
     int32_t dropInputFrames;
-    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
+    if (params->findInt32(PARAMETER_KEY_SUSPEND, &dropInputFrames)) {
         if (mGraphicBufferSource == NULL) {
             ALOGE("[%s] Invalid to set suspend without surface",
                     mComponentName.c_str());
@@ -7302,7 +7482,7 @@
         }
 
         int64_t suspendStartTimeUs = -1;
-        (void) params->findInt64("drop-start-time-us", &suspendStartTimeUs);
+        (void) params->findInt64(PARAMETER_KEY_SUSPEND_TIME, &suspendStartTimeUs);
         status_t err = statusFromBinderStatus(
                 mGraphicBufferSource->setSuspend(dropInputFrames != 0, suspendStartTimeUs));
 
@@ -7382,12 +7562,57 @@
         }
     }
 
+    int32_t presentationId = -1;
+    if (params->findInt32("audio-presentation-presentation-id", &presentationId)) {
+        int32_t programId = -1;
+        params->findInt32("audio-presentation-program-id", &programId);
+        status_t err = setAudioPresentation(presentationId, programId);
+        if (err != OK) {
+            ALOGI("[%s] failed setAudioPresentation. Failure is fine since this key is optional",
+                    mComponentName.c_str());
+            err = OK;
+        }
+    }
+
+    sp<ABuffer> hdr10PlusInfo;
+    if (params->findBuffer("hdr10-plus-info", &hdr10PlusInfo)
+            && hdr10PlusInfo != nullptr && hdr10PlusInfo->size() > 0) {
+        (void)setHdr10PlusInfo(hdr10PlusInfo);
+    }
+
     // Ignore errors as failure is expected for codecs that aren't video encoders.
     (void)configureTemporalLayers(params, false /* inConfigure */, mOutputFormat);
 
     return setVendorParameters(params);
 }
 
+status_t ACodec::setHdr10PlusInfo(const sp<ABuffer> &hdr10PlusInfo) {
+    if (mDescribeHDR10PlusInfoIndex == 0) {
+        ALOGE("setHdr10PlusInfo: does not support DescribeHDR10PlusInfoParams");
+        return ERROR_UNSUPPORTED;
+    }
+    size_t newSize = sizeof(DescribeHDR10PlusInfoParams) + hdr10PlusInfo->size() - 1;
+    if (mHdr10PlusScratchBuffer == nullptr ||
+            newSize > mHdr10PlusScratchBuffer->size()) {
+        mHdr10PlusScratchBuffer = new ABuffer(newSize);
+    }
+    DescribeHDR10PlusInfoParams *config =
+            (DescribeHDR10PlusInfoParams *)mHdr10PlusScratchBuffer->data();
+    InitOMXParams(config);
+    config->nPortIndex = 0;
+    config->nSize = newSize;
+    config->nParamSize = hdr10PlusInfo->size();
+    config->nParamSizeUsed = hdr10PlusInfo->size();
+    memcpy(config->nValue, hdr10PlusInfo->data(), hdr10PlusInfo->size());
+    status_t err = mOMXNode->setConfig(
+            (OMX_INDEXTYPE)mDescribeHDR10PlusInfoIndex,
+            config, config->nSize);
+    if (err != OK) {
+        ALOGE("failed to set DescribeHDR10PlusInfoParams (err %d)", err);
+    }
+    return OK;
+}
+
 // Removes trailing tags matching |tag| from |key| (e.g. a settings name). |minLength| specifies
 // the minimum number of characters to keep in |key| (even if it has trailing tags).
 // (Used to remove trailing 'value' tags in settings names, e.g. to normalize
@@ -7809,6 +8034,15 @@
             return true;
         }
 
+        case OMX_EventConfigUpdate:
+        {
+            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
+
+            mCodec->onConfigUpdate((OMX_INDEXTYPE)data2);
+
+            return true;
+        }
+
         case OMX_EventBufferFlag:
         {
             return true;
@@ -7849,7 +8083,7 @@
                 msg->setInt32("generation", mCodec->mStateGeneration);
                 msg->post(3000000);
             }
-            // fall-through
+            FALLTHROUGH_INTENDED;
         }
         case kWhatResume:
         case kWhatSetParameters:
@@ -7873,6 +8107,18 @@
             break;
         }
 
+        case kWhatCheckIfStuck:
+        {
+            int32_t generation = 0;
+            CHECK(msg->findInt32("generation", &generation));
+            if (generation == mCodec->mStateGeneration) {
+                mCodec->signalError(OMX_ErrorUndefined, TIMED_OUT);
+            }
+
+            handled = true;
+            break;
+        }
+
         default:
             handled = BaseState::onMessageReceived(msg);
             break;
@@ -7884,6 +8130,11 @@
 void ACodec::OutputPortSettingsChangedState::stateEntered() {
     ALOGV("[%s] Now handling output port settings change",
          mCodec->mComponentName.c_str());
+
+    // If we haven't transitioned after 3 seconds, we're probably stuck.
+    sp<AMessage> msg = new AMessage(ACodec::kWhatCheckIfStuck, mCodec);
+    msg->setInt32("generation", mCodec->mStateGeneration);
+    msg->post(3000000);
 }
 
 bool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered(
@@ -7919,6 +8170,10 @@
                             OMX_CommandPortEnable, kPortIndexOutput);
                 }
 
+                // Clear the RenderQueue in which queued GraphicBuffers hold the
+                // actual buffer references in order to free them early.
+                mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
+
                 if (err == OK) {
                     err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
                     ALOGE_IF(err != OK, "Failed to allocate output port buffers after port "
@@ -8146,6 +8401,11 @@
     ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
 
     mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
+
+    // If we haven't transitioned after 3 seconds, we're probably stuck.
+    sp<AMessage> msg = new AMessage(ACodec::kWhatCheckIfStuck, mCodec);
+    msg->setInt32("generation", mCodec->mStateGeneration);
+    msg->post(3000000);
 }
 
 bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
@@ -8160,6 +8420,7 @@
                 msg->setInt32("generation", mCodec->mStateGeneration);
                 msg->post(3000000);
             }
+            handled = true;
             break;
         }
 
@@ -8180,6 +8441,18 @@
             break;
         }
 
+        case kWhatCheckIfStuck:
+        {
+            int32_t generation = 0;
+            CHECK(msg->findInt32("generation", &generation));
+            if (generation == mCodec->mStateGeneration) {
+                mCodec->signalError(OMX_ErrorUndefined, TIMED_OUT);
+            }
+
+            handled = true;
+            break;
+        }
+
         default:
             handled = BaseState::onMessageReceived(msg);
             break;
@@ -8306,7 +8579,7 @@
     }
 
     sp<IOMX> omx = client.interface();
-    sp<CodecObserver> observer = new CodecObserver;
+    sp<CodecObserver> observer = new CodecObserver(new AMessage);
     sp<IOMXNode> omxNode;
 
     err = omx->allocateNode(name, observer, &omxNode);
@@ -8422,14 +8695,17 @@
         if (omxNode->configureVideoTunnelMode(
                 kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) {
             // tunneled playback includes adaptive playback
-            caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback
-                    | MediaCodecInfo::Capabilities::kFlagSupportsTunneledPlayback);
-        } else if (omxNode->setPortMode(
-                kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer) == OK ||
-                omxNode->prepareForAdaptivePlayback(
-                kPortIndexOutput, OMX_TRUE,
-                1280 /* width */, 720 /* height */) == OK) {
-            caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback);
+        } else {
+            // tunneled playback is not supported
+            caps->removeDetail(MediaCodecInfo::Capabilities::FEATURE_TUNNELED_PLAYBACK);
+            if (omxNode->setPortMode(
+                    kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer) != OK &&
+                    omxNode->prepareForAdaptivePlayback(
+                        kPortIndexOutput, OMX_TRUE,
+                        1280 /* width */, 720 /* height */) != OK) {
+                // adaptive playback is not supported
+                caps->removeDetail(MediaCodecInfo::Capabilities::FEATURE_ADAPTIVE_PLAYBACK);
+            }
         }
     }
 
@@ -8437,11 +8713,20 @@
         OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
         InitOMXParams(&params);
         params.nPortIndex = kPortIndexOutput;
-        // TODO: should we verify if fallback is supported?
+
+        OMX_VIDEO_PARAM_INTRAREFRESHTYPE fallbackParams;
+        InitOMXParams(&fallbackParams);
+        fallbackParams.nPortIndex = kPortIndexOutput;
+        fallbackParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
+
         if (omxNode->getConfig(
                 (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh,
-                &params, sizeof(params)) == OK) {
-            caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsIntraRefresh);
+                &params, sizeof(params)) != OK &&
+                omxNode->getParameter(
+                    OMX_IndexParamVideoIntraRefresh, &fallbackParams,
+                    sizeof(fallbackParams)) != OK) {
+            // intra refresh is not supported
+            caps->removeDetail(MediaCodecInfo::Capabilities::FEATURE_INTRA_REFRESH);
         }
     }
 
diff --git a/media/libstagefright/ACodecBufferChannel.cpp b/media/libstagefright/ACodecBufferChannel.cpp
index 710ae68..266a240 100644
--- a/media/libstagefright/ACodecBufferChannel.cpp
+++ b/media/libstagefright/ACodecBufferChannel.cpp
@@ -129,6 +129,7 @@
         secureHandle = static_cast<native_handle_t *>(secureData->getDestinationPointer());
     }
     ssize_t result = -1;
+    ssize_t codecDataOffset = 0;
     if (mCrypto != NULL) {
         ICrypto::DestinationBuffer destination;
         if (secure) {
@@ -180,9 +181,16 @@
 
         Status status = Status::OK;
         hidl_string detailedError;
+        ScramblingControl sctrl = ScramblingControl::UNSCRAMBLED;
+
+        if (key != NULL) {
+            sctrl = (ScramblingControl)key[0];
+            // Adjust for the PES offset
+            codecDataOffset = key[2] | (key[3] << 8);
+        }
 
         auto returnVoid = mDescrambler->descramble(
-                key != NULL ? (ScramblingControl)key[0] : ScramblingControl::UNSCRAMBLED,
+                sctrl,
                 hidlSubSamples,
                 srcBuffer,
                 0,
@@ -202,6 +210,11 @@
             return UNKNOWN_ERROR;
         }
 
+        if (result < codecDataOffset) {
+            ALOGD("invalid codec data offset: %zd, result %zd", codecDataOffset, result);
+            return BAD_VALUE;
+        }
+
         ALOGV("descramble succeeded, %zd bytes", result);
 
         if (dstBuffer.type == BufferType::SHARED_MEMORY) {
@@ -210,7 +223,7 @@
         }
     }
 
-    it->mCodecBuffer->setRange(0, result);
+    it->mCodecBuffer->setRange(codecDataOffset, result - codecDataOffset);
 
     // Copy metadata from client to codec buffer.
     it->mCodecBuffer->meta()->clear();
diff --git a/media/libstagefright/AHierarchicalStateMachine.cpp b/media/libstagefright/AHierarchicalStateMachine.cpp
new file mode 100644
index 0000000..f89b8b0
--- /dev/null
+++ b/media/libstagefright/AHierarchicalStateMachine.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "AHierarchicalStateMachine"
+#include <utils/Log.h>
+
+#include <media/stagefright/AHierarchicalStateMachine.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+AState::AState(const sp<AState> &parentState)
+    : mParentState(parentState) {
+}
+
+AState::~AState() {
+}
+
+sp<AState> AState::parentState() {
+    return mParentState;
+}
+
+void AState::stateEntered() {
+}
+
+void AState::stateExited() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+AHierarchicalStateMachine::AHierarchicalStateMachine() {
+}
+
+AHierarchicalStateMachine::~AHierarchicalStateMachine() {
+}
+
+void AHierarchicalStateMachine::handleMessage(const sp<AMessage> &msg) {
+    sp<AState> save = mState;
+
+    sp<AState> cur = mState;
+    while (cur != NULL && !cur->onMessageReceived(msg)) {
+        // If you claim not to have handled the message you shouldn't
+        // have called setState...
+        CHECK(save == mState);
+
+        cur = cur->parentState();
+    }
+
+    if (cur != NULL) {
+        return;
+    }
+
+    ALOGW("Warning message %s unhandled in root state.",
+         msg->debugString().c_str());
+}
+
+void AHierarchicalStateMachine::changeState(const sp<AState> &state) {
+    if (state == mState) {
+        // Quick exit for the easy case.
+        return;
+    }
+
+    Vector<sp<AState> > A;
+    sp<AState> cur = mState;
+    for (;;) {
+        A.push(cur);
+        if (cur == NULL) {
+            break;
+        }
+        cur = cur->parentState();
+    }
+
+    Vector<sp<AState> > B;
+    cur = state;
+    for (;;) {
+        B.push(cur);
+        if (cur == NULL) {
+            break;
+        }
+        cur = cur->parentState();
+    }
+
+    // Remove the common tail.
+    while (A.size() > 0 && B.size() > 0 && A.top() == B.top()) {
+        A.pop();
+        B.pop();
+    }
+
+    mState = state;
+
+    for (size_t i = 0; i < A.size(); ++i) {
+        A.editItemAt(i)->stateExited();
+    }
+
+    for (size_t i = B.size(); i > 0;) {
+        i--;
+        B.editItemAt(i)->stateEntered();
+    }
+}
+
+}  // namespace android
diff --git a/media/libstagefright/AMRWriter.cpp b/media/libstagefright/AMRWriter.cpp
index 41106a1..24f6f0b 100644
--- a/media/libstagefright/AMRWriter.cpp
+++ b/media/libstagefright/AMRWriter.cpp
@@ -149,11 +149,11 @@
     mDone = true;
 
     void *dummy;
+    status_t status = mSource->stop();
     pthread_join(mThread, &dummy);
 
     status_t err = static_cast<status_t>(reinterpret_cast<uintptr_t>(dummy));
     {
-        status_t status = mSource->stop();
         if (err == OK &&
             (status != OK && status != ERROR_END_OF_STREAM)) {
             err = status;
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 48e351b..7eab230 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -18,9 +18,6 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
     shared_libs: ["libmedia"],
@@ -40,12 +37,9 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
-    shared_libs: ["libmedia"],
+    shared_libs: ["libmedia", "libmediandk"],
 }
 
 cc_library_shared {
@@ -80,22 +74,54 @@
             "unsigned-integer-overflow",
             "signed-integer-overflow",
         ],
-        diag: {
-            cfi: true,
-        },
     },
 }
 
-cc_library_shared {
+cc_library_static {
+    name: "libstagefright_mpeg2extractor",
+
+    srcs: [
+        "Utils.cpp",
+        "MediaSource.cpp",
+        "HevcUtils.cpp",
+    ],
+
+    shared_libs: [
+        "liblog",
+        "libmedia",
+        "libmedia_omx",
+    ],
+
+    export_include_dirs: [
+        "include",
+    ],
+
+    cflags: [
+        "-Wno-multichar",
+        "-Werror",
+        "-Wno-error=deprecated-declarations",
+        "-Wall",
+    ],
+
+    sanitize: {
+        cfi: true,
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+    },
+}
+
+cc_library {
     name: "libstagefright",
 
     srcs: [
+        "AACWriter.cpp",
         "ACodec.cpp",
         "ACodecBufferChannel.cpp",
-        "AACWriter.cpp",
+        "AHierarchicalStateMachine.cpp",
         "AMRWriter.cpp",
         "AudioPlayer.cpp",
-        "AudioPresentationInfo.cpp",
         "AudioSource.cpp",
         "BufferImpl.cpp",
         "CallbackDataSource.cpp",
@@ -105,6 +131,7 @@
         "DataConverter.cpp",
         "DataSourceFactory.cpp",
         "DataURISource.cpp",
+        "ClearFileSource.cpp",
         "FileSource.cpp",
         "FrameDecoder.cpp",
         "HTTPBase.cpp",
@@ -119,12 +146,17 @@
         "MediaCodecList.cpp",
         "MediaCodecListOverrides.cpp",
         "MediaCodecSource.cpp",
+        "MediaExtractor.cpp",
         "MediaExtractorFactory.cpp",
+        "MediaSource.cpp",
         "MediaSync.cpp",
+        "MediaTrack.cpp",
+        "http/ClearMediaHTTP.cpp",
         "http/MediaHTTP.cpp",
         "MediaMuxer.cpp",
         "NuCachedSource2.cpp",
         "NuMediaExtractor.cpp",
+        "OggWriter.cpp",
         "OMXClient.cpp",
         "OmxInfoBuilder.cpp",
         "RemoteMediaExtractor.cpp",
@@ -137,43 +169,40 @@
         "SurfaceUtils.cpp",
         "Utils.cpp",
         "ThrottledSource.cpp",
+        "VideoFrameSchedulerBase.cpp",
         "VideoFrameScheduler.cpp",
     ],
 
     shared_libs: [
         "libaudioutils",
+        "libbase",
         "libbinder",
         "libcamera_client",
         "libcutils",
         "libdl",
+        "libdl_android",
         "libdrmframework",
         "libgui",
-        "libion",
         "liblog",
         "libmedia",
         "libmedia_omx",
+        "libmedia_omx_client",
         "libaudioclient",
-        "libmediaextractor",
         "libmediametrics",
         "libmediautils",
-        "libnetd_client",
         "libui",
         "libutils",
         "libmedia_helper",
         "libstagefright_codecbase",
         "libstagefright_foundation",
         "libstagefright_omx_utils",
-        "libstagefright_xmlparser",
         "libRScpp",
         "libhidlallocatorutils",
         "libhidlbase",
         "libhidlmemory",
-        "libziparchive",
         "android.hidl.allocator@1.0",
         "android.hardware.cas.native@1.0",
         "android.hardware.media.omx@1.0",
-        "android.hardware.graphics.allocator@2.0",
-        "android.hardware.graphics.mapper@2.0",
     ],
 
     static_libs: [
@@ -182,14 +211,22 @@
         "libstagefright_mediafilter",
         "libstagefright_webm",
         "libstagefright_timedtext",
-        "libvpx",
+        "libogg",
         "libwebm",
         "libstagefright_esds",
         "libstagefright_id3",
         "libFLAC",
     ],
 
+    header_libs:[
+        "libnativeloader-dummy-headers",
+        "libstagefright_xmlparser_headers",
+        "media_ndk_headers",
+    ],
+
     export_shared_lib_headers: [
+        "libgui",
+        "libhidlmemory",
         "libmedia",
         "android.hidl.allocator@1.0",
     ],
@@ -220,64 +257,38 @@
             "unsigned-integer-overflow",
             "signed-integer-overflow",
         ],
-        diag: {
-            cfi: true,
-        },
     },
 }
 
-cc_library {
+cc_library_static {
     name: "libstagefright_player2",
 
     srcs: [
-        "CallbackDataSource.cpp",
-        "CallbackMediaSource.cpp",
-        "DataSourceFactory.cpp",
+        "ClearFileSource.cpp",
         "DataURISource.cpp",
-        "FileSource.cpp",
         "HTTPBase.cpp",
         "HevcUtils.cpp",
-        "InterfaceUtils.cpp",
         "MediaClock.cpp",
-        "MediaExtractorFactory.cpp",
+        "MediaSource.cpp",
         "NdkUtils.cpp",
-        "NuCachedSource2.cpp",
-        "RemoteMediaExtractor.cpp",
-        "RemoteMediaSource.cpp",
         "Utils.cpp",
-        "VideoFrameScheduler.cpp",
-        "http/MediaHTTP.cpp",
+        "VideoFrameSchedulerBase.cpp",
+        "VideoFrameScheduler2.cpp",
+        "http/ClearMediaHTTP.cpp",
     ],
 
     shared_libs: [
-        "libbinder",
-        "libcutils",
-        "libdrmframework",
         "libgui",
         "liblog",
-        "libmedia_player2_util",
-        "libaudioclient",
-        "libmediaextractor",
-        "libmediametrics",
-        "libmediautils",
         "libnetd_client",
-        "libui",
         "libutils",
-        "libmedia_helper",
         "libstagefright_foundation",
-        "libziparchive",
+        "libandroid",
     ],
 
     static_libs: [
-        "libstagefright_esds",
-    ],
-
-    header_libs:[
-        "media_plugin_headers",
-    ],
-
-    export_shared_lib_headers: [
         "libmedia_player2_util",
+        "libmedia2_jni_core",
     ],
 
     export_include_dirs: [
@@ -304,27 +315,6 @@
             "unsigned-integer-overflow",
             "signed-integer-overflow",
         ],
-        diag: {
-            cfi: true,
-        },
     },
 }
 
-subdirs = [
-    "codec2",
-    "codecs/*",
-    "colorconversion",
-    "filters",
-    "flac/dec",
-    "foundation",
-    "http",
-    "httplive",
-    "id3",
-    "mpeg2ts",
-    "omx",
-    "rtsp",
-    "tests",
-    "timedtext",
-    "webm",
-    "xmlparser",
-]
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index a6f0a0b..199b57b 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -118,6 +118,13 @@
     }
 
     sp<MetaData> format = mSource->getFormat();
+
+    if (format == NULL) {
+        ALOGE("No metadata b/118620871");
+        android_errorWriteLog(0x534e4554, "118620871");
+        return BAD_VALUE;
+    }
+
     const char *mime;
     bool success = format->findCString(kKeyMIMEType, &mime);
     CHECK(success);
diff --git a/media/libstagefright/AudioPresentationInfo.cpp b/media/libstagefright/AudioPresentationInfo.cpp
deleted file mode 100644
index 86e1859..0000000
--- a/media/libstagefright/AudioPresentationInfo.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// #define LOG_NDEBUG 0
-#define LOG_TAG "AudioPresentationInfo"
-
-#include <media/AudioPresentationInfo.h>
-
-namespace android {
-
-AudioPresentationInfo::AudioPresentationInfo() {
-}
-
-AudioPresentationInfo::~AudioPresentationInfo() {
-    mPresentations.clear();
-}
-
-void AudioPresentationInfo::addPresentation(sp<AudioPresentation> presentation) {
-    mPresentations.push(presentation);
-}
-
-size_t AudioPresentationInfo::countPresentations() const {
-    return mPresentations.size();
-}
-
-// Returns an AudioPresentation for the given valid index
-// index must be >=0 and < countPresentations()
-const sp<AudioPresentation> AudioPresentationInfo::getPresentation(size_t index) const {
-    return mPresentations[index];
-}
-
-}  // namespace android
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index 2ae3218..d78d729 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -52,7 +52,9 @@
 AudioSource::AudioSource(
         audio_source_t inputSource, const String16 &opPackageName,
         uint32_t sampleRate, uint32_t channelCount, uint32_t outSampleRate,
-        uid_t uid, pid_t pid, audio_port_handle_t selectedDeviceId)
+        uid_t uid, pid_t pid, audio_port_handle_t selectedDeviceId,
+        audio_microphone_direction_t selectedMicDirection,
+        float selectedMicFieldDimension)
     : mStarted(false),
       mSampleRate(sampleRate),
       mOutSampleRate(outSampleRate > 0 ? outSampleRate : sampleRate),
@@ -103,7 +105,9 @@
                     uid,
                     pid,
                     NULL /*pAttributes*/,
-                    selectedDeviceId);
+                    selectedDeviceId,
+                    selectedMicDirection,
+                    selectedMicFieldDimension);
         mInitCheck = mRecord->initCheck();
         if (mInitCheck != OK) {
             mRecord.clear();
@@ -337,7 +341,7 @@
     } else {
         // This should not happen in normal case.
         ALOGW("Failed to get audio timestamp, fallback to use systemclock");
-        timeUs = systemTime() / 1000ll;
+        timeUs = systemTime() / 1000LL;
         // Estimate the real sampling time of the 1st sample in this buffer
         // from AudioRecord's latency. (Apply this adjustment first so that
         // the start time logic is not affected.)
@@ -381,11 +385,11 @@
     }
     mLastFrameTimestampUs = timeUs;
 
-    size_t numLostBytes = 0;
+    uint64_t numLostBytes = 0; // AudioRecord::getInputFramesLost() returns uint32_t
     if (mNumFramesReceived > 0) {  // Ignore earlier frame lost
         // getInputFramesLost() returns the number of lost frames.
         // Convert number of frames lost to number of bytes lost.
-        numLostBytes = mRecord->getInputFramesLost() * mRecord->frameSize();
+        numLostBytes = (uint64_t)mRecord->getInputFramesLost() * mRecord->frameSize();
     }
 
     CHECK_EQ(numLostBytes & 1, 0u);
@@ -393,11 +397,11 @@
     if (numLostBytes > 0) {
         // Loss of audio frames should happen rarely; thus the LOGW should
         // not cause a logging spam
-        ALOGW("Lost audio record data: %zu bytes", numLostBytes);
+        ALOGW("Lost audio record data: %" PRIu64 " bytes", numLostBytes);
     }
 
     while (numLostBytes > 0) {
-        size_t bufferSize = numLostBytes;
+        uint64_t bufferSize = numLostBytes;
         if (numLostBytes > kMaxBufferSize) {
             numLostBytes -= kMaxBufferSize;
             bufferSize = kMaxBufferSize;
@@ -427,19 +431,17 @@
 void AudioSource::queueInputBuffer_l(MediaBuffer *buffer, int64_t timeUs) {
     const size_t bufferSize = buffer->range_length();
     const size_t frameSize = mRecord->frameSize();
-    const int64_t timestampUs =
-                mPrevSampleTimeUs +
-                    ((1000000LL * (bufferSize / frameSize)) +
-                        (mSampleRate >> 1)) / mSampleRate;
-
     if (mNumFramesReceived == 0) {
         buffer->meta_data().setInt64(kKeyAnchorTime, mStartTimeUs);
     }
-
+    mNumFramesReceived += bufferSize / frameSize;
+    const int64_t timestampUs =
+                mStartTimeUs +
+                    ((1000000LL * mNumFramesReceived) +
+                        (mSampleRate >> 1)) / mSampleRate;
     buffer->meta_data().setInt64(kKeyTime, mPrevSampleTimeUs);
     buffer->meta_data().setInt64(kKeyDriftTime, timeUs - mInitialReadTimeUs);
     mPrevSampleTimeUs = timestampUs;
-    mNumFramesReceived += bufferSize / frameSize;
     mBuffersReceived.push_back(buffer);
     mFrameAvailableCondition.signal();
 }
@@ -506,4 +508,27 @@
     return NO_INIT;
 }
 
+status_t AudioSource::setPreferredMicrophoneDirection(audio_microphone_direction_t direction) {
+    ALOGV("setPreferredMicrophoneDirection(%d)", direction);
+    if (mRecord != 0) {
+        return mRecord->setPreferredMicrophoneDirection(direction);
+    }
+    return NO_INIT;
+}
+
+status_t AudioSource::setPreferredMicrophoneFieldDimension(float zoom) {
+    ALOGV("setPreferredMicrophoneFieldDimension(%f)", zoom);
+    if (mRecord != 0) {
+        return mRecord->setPreferredMicrophoneFieldDimension(zoom);
+    }
+    return NO_INIT;
+}
+
+status_t AudioSource::getPortId(audio_port_handle_t *portId) const {
+    if (mRecord != 0) {
+        *portId = mRecord->getPortId();
+        return NO_ERROR;
+    }
+    return NO_INIT;
+}
 }  // namespace android
diff --git a/media/libstagefright/CameraSourceTimeLapse.cpp b/media/libstagefright/CameraSourceTimeLapse.cpp
index 3ad82d9..2a819ad 100644
--- a/media/libstagefright/CameraSourceTimeLapse.cpp
+++ b/media/libstagefright/CameraSourceTimeLapse.cpp
@@ -19,6 +19,7 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "CameraSourceTimeLapse"
 
+#include <media/hardware/HardwareAPI.h>
 #include <binder/IPCThreadState.h>
 #include <binder/MemoryBase.h>
 #include <binder/MemoryHeapBase.h>
@@ -172,8 +173,16 @@
     ALOGV("signalBufferReturned");
     Mutex::Autolock autoLock(mQuickStopLock);
     if (mQuickStop && (buffer == mLastReadBufferCopy)) {
+        if (metaDataStoredInVideoBuffers() == kMetadataBufferTypeNativeHandleSource) {
+            native_handle_t* handle = (
+                (VideoNativeHandleMetadata*)(mLastReadBufferCopy->data()))->pHandle;
+            native_handle_close(handle);
+            native_handle_delete(handle);
+        }
         buffer->setObserver(NULL);
         buffer->release();
+        mLastReadBufferCopy = NULL;
+        mForceRead = true;
     } else {
         return CameraSource::signalBufferReturned(buffer);
     }
@@ -182,7 +191,8 @@
 void createMediaBufferCopy(
         const MediaBufferBase& sourceBuffer,
         int64_t frameTime,
-        MediaBufferBase **newBuffer) {
+        MediaBufferBase **newBuffer,
+        int32_t videoBufferMode) {
 
     ALOGV("createMediaBufferCopy");
     size_t sourceSize = sourceBuffer.size();
@@ -192,13 +202,20 @@
     memcpy((*newBuffer)->data(), sourcePointer, sourceSize);
 
     (*newBuffer)->meta_data().setInt64(kKeyTime, frameTime);
+
+    if (videoBufferMode == kMetadataBufferTypeNativeHandleSource) {
+        ((VideoNativeHandleMetadata*)((*newBuffer)->data()))->pHandle =
+            native_handle_clone(
+                ((VideoNativeHandleMetadata*)(sourceBuffer.data()))->pHandle);
+    }
 }
 
 void CameraSourceTimeLapse::fillLastReadBufferCopy(MediaBufferBase& sourceBuffer) {
     ALOGV("fillLastReadBufferCopy");
     int64_t frameTime;
     CHECK(sourceBuffer.meta_data().findInt64(kKeyTime, &frameTime));
-    createMediaBufferCopy(sourceBuffer, frameTime, &mLastReadBufferCopy);
+    createMediaBufferCopy(sourceBuffer, frameTime, &mLastReadBufferCopy,
+        metaDataStoredInVideoBuffers());
     mLastReadBufferCopy->add_ref();
     mLastReadBufferCopy->setObserver(this);
 }
diff --git a/media/libstagefright/ClearFileSource.cpp b/media/libstagefright/ClearFileSource.cpp
new file mode 100644
index 0000000..e3a2cb7
--- /dev/null
+++ b/media/libstagefright/ClearFileSource.cpp
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ClearFileSource"
+#include <utils/Log.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/ClearFileSource.h>
+#include <media/stagefright/Utils.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+namespace android {
+
+ClearFileSource::ClearFileSource(const char *filename)
+    : mFd(-1),
+      mOffset(0),
+      mLength(-1),
+      mName("<null>") {
+
+    if (filename) {
+        mName = String8::format("FileSource(%s)", filename);
+    }
+    ALOGV("%s", filename);
+    mFd = open(filename, O_LARGEFILE | O_RDONLY);
+
+    if (mFd >= 0) {
+        mLength = lseek64(mFd, 0, SEEK_END);
+    } else {
+        ALOGE("Failed to open file '%s'. (%s)", filename, strerror(errno));
+    }
+}
+
+ClearFileSource::ClearFileSource(int fd, int64_t offset, int64_t length)
+    : mFd(fd),
+      mOffset(offset),
+      mLength(length),
+      mName("<null>") {
+    ALOGV("fd=%d (%s), offset=%lld, length=%lld",
+            fd, nameForFd(fd).c_str(), (long long) offset, (long long) length);
+
+    if (mOffset < 0) {
+        mOffset = 0;
+    }
+    if (mLength < 0) {
+        mLength = 0;
+    }
+    if (mLength > INT64_MAX - mOffset) {
+        mLength = INT64_MAX - mOffset;
+    }
+    struct stat s;
+    if (fstat(fd, &s) == 0) {
+        if (mOffset > s.st_size) {
+            mOffset = s.st_size;
+            mLength = 0;
+        }
+        if (mOffset + mLength > s.st_size) {
+            mLength = s.st_size - mOffset;
+        }
+    }
+    if (mOffset != offset || mLength != length) {
+        ALOGW("offset/length adjusted from %lld/%lld to %lld/%lld",
+                (long long) offset, (long long) length,
+                (long long) mOffset, (long long) mLength);
+    }
+
+    mName = String8::format(
+            "FileSource(fd(%s), %lld, %lld)",
+            nameForFd(fd).c_str(),
+            (long long) mOffset,
+            (long long) mLength);
+
+}
+
+ClearFileSource::~ClearFileSource() {
+    if (mFd >= 0) {
+        ::close(mFd);
+        mFd = -1;
+    }
+}
+
+status_t ClearFileSource::initCheck() const {
+    return mFd >= 0 ? OK : NO_INIT;
+}
+
+ssize_t ClearFileSource::readAt(off64_t offset, void *data, size_t size) {
+    if (mFd < 0) {
+        return NO_INIT;
+    }
+
+    Mutex::Autolock autoLock(mLock);
+    if (mLength >= 0) {
+        if (offset >= mLength) {
+            return 0;  // read beyond EOF.
+        }
+        uint64_t numAvailable = mLength - offset;
+        if ((uint64_t)size > numAvailable) {
+            size = numAvailable;
+        }
+    }
+    return readAt_l(offset, data, size);
+}
+
+ssize_t ClearFileSource::readAt_l(off64_t offset, void *data, size_t size) {
+    off64_t result = lseek64(mFd, offset + mOffset, SEEK_SET);
+    if (result == -1) {
+        ALOGE("seek to %lld failed", (long long)(offset + mOffset));
+        return UNKNOWN_ERROR;
+    }
+
+    return ::read(mFd, data, size);
+}
+
+status_t ClearFileSource::getSize(off64_t *size) {
+    Mutex::Autolock autoLock(mLock);
+
+    if (mFd < 0) {
+        return NO_INIT;
+    }
+
+    *size = mLength;
+
+    return OK;
+}
+
+}  // namespace android
diff --git a/media/libstagefright/DataURISource.cpp b/media/libstagefright/DataURISource.cpp
index 3dc345f..b975b38 100644
--- a/media/libstagefright/DataURISource.cpp
+++ b/media/libstagefright/DataURISource.cpp
@@ -13,7 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 #include <media/stagefright/DataURISource.h>
 
 #include <media/stagefright/foundation/ABuffer.h>
@@ -39,15 +38,27 @@
     AString tmp(&uri[5], commaPos - &uri[5]);
 
     if (tmp.endsWith(";base64")) {
-        AString encoded(commaPos + 1);
 
-        // Strip CR and LF...
-        for (size_t i = encoded.size(); i > 0;) {
-            i--;
-            if (encoded.c_str()[i] == '\r' || encoded.c_str()[i] == '\n') {
-                encoded.erase(i, 1);
+        // strip all CR and LF characters.
+        const char *src = commaPos+1;
+        int len = strlen(src) + 1;
+        char *cleansed = (char *) malloc(len);
+        if (cleansed == NULL) return NULL;
+        char *keeping = cleansed;
+        int left = len;
+        for (int i = 0; i < len ; i++)
+        {
+            const char c = *src++;
+            if (c == '\r' || c == '\n') {
+                continue;
             }
+            *keeping++ = c;
+            left--;
         }
+        memset(keeping, 0, left);
+
+        AString encoded(cleansed);
+        free(cleansed);
 
         buffer = decodeBase64(encoded);
 
diff --git a/media/libstagefright/FileSource.cpp b/media/libstagefright/FileSource.cpp
index eef5314..aee7fd8 100644
--- a/media/libstagefright/FileSource.cpp
+++ b/media/libstagefright/FileSource.cpp
@@ -22,90 +22,28 @@
 #include <media/stagefright/FileSource.h>
 #include <media/stagefright/Utils.h>
 #include <private/android_filesystem_config.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
 
 namespace android {
 
 FileSource::FileSource(const char *filename)
-    : mFd(-1),
-      mOffset(0),
-      mLength(-1),
-      mName("<null>"),
+    : ClearFileSource(filename),
       mDecryptHandle(NULL),
       mDrmManagerClient(NULL),
       mDrmBufOffset(0),
       mDrmBufSize(0),
       mDrmBuf(NULL){
-
-    if (filename) {
-        mName = String8::format("FileSource(%s)", filename);
-    }
-    ALOGV("%s", filename);
-    mFd = open(filename, O_LARGEFILE | O_RDONLY);
-
-    if (mFd >= 0) {
-        mLength = lseek64(mFd, 0, SEEK_END);
-    } else {
-        ALOGE("Failed to open file '%s'. (%s)", filename, strerror(errno));
-    }
 }
 
 FileSource::FileSource(int fd, int64_t offset, int64_t length)
-    : mFd(fd),
-      mOffset(offset),
-      mLength(length),
-      mName("<null>"),
+    : ClearFileSource(fd, offset, length),
       mDecryptHandle(NULL),
       mDrmManagerClient(NULL),
       mDrmBufOffset(0),
       mDrmBufSize(0),
       mDrmBuf(NULL) {
-    ALOGV("fd=%d (%s), offset=%lld, length=%lld",
-            fd, nameForFd(fd).c_str(), (long long) offset, (long long) length);
-
-    if (mOffset < 0) {
-        mOffset = 0;
-    }
-    if (mLength < 0) {
-        mLength = 0;
-    }
-    if (mLength > INT64_MAX - mOffset) {
-        mLength = INT64_MAX - mOffset;
-    }
-    struct stat s;
-    if (fstat(fd, &s) == 0) {
-        if (mOffset > s.st_size) {
-            mOffset = s.st_size;
-            mLength = 0;
-        }
-        if (mOffset + mLength > s.st_size) {
-            mLength = s.st_size - mOffset;
-        }
-    }
-    if (mOffset != offset || mLength != length) {
-        ALOGW("offset/length adjusted from %lld/%lld to %lld/%lld",
-                (long long) offset, (long long) length,
-                (long long) mOffset, (long long) mLength);
-    }
-
-    mName = String8::format(
-            "FileSource(fd(%s), %lld, %lld)",
-            nameForFd(fd).c_str(),
-            (long long) mOffset,
-            (long long) mLength);
-
 }
 
 FileSource::~FileSource() {
-    if (mFd >= 0) {
-        ::close(mFd);
-        mFd = -1;
-    }
-
     if (mDrmBuf != NULL) {
         delete[] mDrmBuf;
         mDrmBuf = NULL;
@@ -124,10 +62,6 @@
     }
 }
 
-status_t FileSource::initCheck() const {
-    return mFd >= 0 ? OK : NO_INIT;
-}
-
 ssize_t FileSource::readAt(off64_t offset, void *data, size_t size) {
     if (mFd < 0) {
         return NO_INIT;
@@ -147,30 +81,12 @@
 
     if (mDecryptHandle != NULL && DecryptApiType::CONTAINER_BASED
             == mDecryptHandle->decryptApiType) {
-        return readAtDRM(offset, data, size);
+        return readAtDRM_l(offset, data, size);
    } else {
-        off64_t result = lseek64(mFd, offset + mOffset, SEEK_SET);
-        if (result == -1) {
-            ALOGE("seek to %lld failed", (long long)(offset + mOffset));
-            return UNKNOWN_ERROR;
-        }
-
-        return ::read(mFd, data, size);
+        return readAt_l(offset, data, size);
     }
 }
 
-status_t FileSource::getSize(off64_t *size) {
-    Mutex::Autolock autoLock(mLock);
-
-    if (mFd < 0) {
-        return NO_INIT;
-    }
-
-    *size = mLength;
-
-    return OK;
-}
-
 sp<DecryptHandle> FileSource::DrmInitialization(const char *mime) {
     if (getuid() == AID_MEDIA_EX) return nullptr; // no DRM in media extractor
     if (mDrmManagerClient == NULL) {
@@ -194,7 +110,7 @@
     return mDecryptHandle;
 }
 
-ssize_t FileSource::readAtDRM(off64_t offset, void *data, size_t size) {
+ssize_t FileSource::readAtDRM_l(off64_t offset, void *data, size_t size) {
     size_t DRM_CACHE_SIZE = 1024;
     if (mDrmBuf == NULL) {
         mDrmBuf = new unsigned char[DRM_CACHE_SIZE];
diff --git a/media/libstagefright/FrameDecoder.cpp b/media/libstagefright/FrameDecoder.cpp
index 6e94517..18a6bd8 100644
--- a/media/libstagefright/FrameDecoder.cpp
+++ b/media/libstagefright/FrameDecoder.cpp
@@ -39,7 +39,7 @@
 
 namespace android {
 
-static const int64_t kBufferTimeOutUs = 10000ll; // 10 msec
+static const int64_t kBufferTimeOutUs = 10000LL; // 10 msec
 static const size_t kRetryCount = 50; // must be >0
 
 sp<IMemory> allocVideoFrame(const sp<MetaData>& trackMeta,
@@ -274,7 +274,7 @@
     size_t retriesLeft = kRetryCount;
     do {
         size_t index;
-        int64_t ptsUs = 0ll;
+        int64_t ptsUs = 0LL;
         uint32_t flags = 0;
 
         // Queue as many inputs as we possibly can, then block on dequeuing
@@ -406,7 +406,7 @@
     : FrameDecoder(componentName, trackMeta, source),
       mIsAvcOrHevc(false),
       mSeekMode(MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC),
-      mTargetTimeUs(-1ll),
+      mTargetTimeUs(-1LL),
       mNumFrames(0),
       mNumFramesDecoded(0) {
 }
@@ -431,7 +431,7 @@
             || !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC);
 
     if (frameTimeUs < 0) {
-        int64_t thumbNailTime;
+        int64_t thumbNailTime = -1ll;
         if (!trackMeta()->findInt64(kKeyThumbnailTime, &thumbNailTime)
                 || thumbNailTime < 0) {
             thumbNailTime = 0;
@@ -487,7 +487,7 @@
         const sp<MediaCodecBuffer> &videoFrameBuffer,
         const sp<AMessage> &outputFormat,
         int64_t timeUs, bool *done) {
-    bool shouldOutput = (mTargetTimeUs < 0ll) || (timeUs >= mTargetTimeUs);
+    bool shouldOutput = (mTargetTimeUs < 0LL) || (timeUs >= mTargetTimeUs);
 
     // If this is not the target frame, skip color convert.
     if (!shouldOutput) {
@@ -501,9 +501,15 @@
         return ERROR_MALFORMED;
     }
 
-    int32_t width, height;
-    CHECK(outputFormat->findInt32("width", &width));
-    CHECK(outputFormat->findInt32("height", &height));
+    int32_t width, height, stride, srcFormat;
+    if (!outputFormat->findInt32("width", &width) ||
+            !outputFormat->findInt32("height", &height) ||
+            !outputFormat->findInt32("stride", &stride) ||
+            !outputFormat->findInt32("color-format", &srcFormat)) {
+        ALOGE("format missing dimension or color: %s",
+                outputFormat->debugString().c_str());
+        return ERROR_MALFORMED;
+    }
 
     int32_t crop_left, crop_top, crop_right, crop_bottom;
     if (!outputFormat->findRect("crop", &crop_left, &crop_top, &crop_right, &crop_bottom)) {
@@ -522,19 +528,27 @@
     addFrame(frameMem);
     VideoFrame* frame = static_cast<VideoFrame*>(frameMem->pointer());
 
-    int32_t srcFormat;
-    CHECK(outputFormat->findInt32("color-format", &srcFormat));
-
     ColorConverter converter((OMX_COLOR_FORMATTYPE)srcFormat, dstFormat());
 
+    uint32_t standard, range, transfer;
+    if (!outputFormat->findInt32("color-standard", (int32_t*)&standard)) {
+        standard = 0;
+    }
+    if (!outputFormat->findInt32("color-range", (int32_t*)&range)) {
+        range = 0;
+    }
+    if (!outputFormat->findInt32("color-transfer", (int32_t*)&transfer)) {
+        transfer = 0;
+    }
+    converter.setSrcColorSpace(standard, range, transfer);
+
     if (converter.isValid()) {
         converter.convert(
                 (const uint8_t *)videoFrameBuffer->data(),
-                width, height,
+                width, height, stride,
                 crop_left, crop_top, crop_right, crop_bottom,
                 frame->getFlattenedData(),
-                frame->mWidth,
-                frame->mHeight,
+                frame->mWidth, frame->mHeight, frame->mRowBytes,
                 crop_left, crop_top, crop_right, crop_bottom);
         return OK;
     }
@@ -681,9 +695,10 @@
         return ERROR_MALFORMED;
     }
 
-    int32_t width, height;
+    int32_t width, height, stride;
     CHECK(outputFormat->findInt32("width", &width));
     CHECK(outputFormat->findInt32("height", &height));
+    CHECK(outputFormat->findInt32("stride", &stride));
 
     if (mFrame == NULL) {
         sp<IMemory> frameMem = allocVideoFrame(
@@ -698,6 +713,18 @@
 
     ColorConverter converter((OMX_COLOR_FORMATTYPE)srcFormat, dstFormat());
 
+    uint32_t standard, range, transfer;
+    if (!outputFormat->findInt32("color-standard", (int32_t*)&standard)) {
+        standard = 0;
+    }
+    if (!outputFormat->findInt32("color-range", (int32_t*)&range)) {
+        range = 0;
+    }
+    if (!outputFormat->findInt32("color-transfer", (int32_t*)&transfer)) {
+        transfer = 0;
+    }
+    converter.setSrcColorSpace(standard, range, transfer);
+
     int32_t dstLeft, dstTop, dstRight, dstBottom;
     dstLeft = mTilesDecoded % mGridCols * width;
     dstTop = mTilesDecoded / mGridCols * height;
@@ -727,11 +754,10 @@
     if (converter.isValid()) {
         converter.convert(
                 (const uint8_t *)videoFrameBuffer->data(),
-                width, height,
+                width, height, stride,
                 crop_left, crop_top, crop_right, crop_bottom,
                 mFrame->getFlattenedData(),
-                mFrame->mWidth,
-                mFrame->mHeight,
+                mFrame->mWidth, mFrame->mHeight, mFrame->mRowBytes,
                 dstLeft, dstTop, dstRight, dstBottom);
         return OK;
     }
diff --git a/media/libstagefright/HTTPBase.cpp b/media/libstagefright/HTTPBase.cpp
index 0f24329..d118e8c 100644
--- a/media/libstagefright/HTTPBase.cpp
+++ b/media/libstagefright/HTTPBase.cpp
@@ -26,8 +26,6 @@
 #include <cutils/properties.h>
 #include <cutils/qtaguid.h>
 
-#include <NetdClient.h>
-
 namespace android {
 
 HTTPBase::HTTPBase()
@@ -114,30 +112,4 @@
     mMaxBandwidthHistoryItems = numHistoryItems;
 }
 
-// static
-void HTTPBase::RegisterSocketUserTag(int sockfd, uid_t uid, uint32_t kTag) {
-    int res = qtaguid_tagSocket(sockfd, kTag, uid);
-    if (res != 0) {
-        ALOGE("Failed tagging socket %d for uid %d (My UID=%d)", sockfd, uid, geteuid());
-    }
-}
-
-// static
-void HTTPBase::UnRegisterSocketUserTag(int sockfd) {
-    int res = qtaguid_untagSocket(sockfd);
-    if (res != 0) {
-        ALOGE("Failed untagging socket %d (My UID=%d)", sockfd, geteuid());
-    }
-}
-
-// static
-void HTTPBase::RegisterSocketUserMark(int sockfd, uid_t uid) {
-    setNetworkForUser(uid, sockfd);
-}
-
-// static
-void HTTPBase::UnRegisterSocketUserMark(int sockfd) {
-    RegisterSocketUserMark(sockfd, geteuid());
-}
-
 }  // namespace android
diff --git a/media/libstagefright/HevcUtils.cpp b/media/libstagefright/HevcUtils.cpp
index f152a38..482a1a7 100644
--- a/media/libstagefright/HevcUtils.cpp
+++ b/media/libstagefright/HevcUtils.cpp
@@ -312,14 +312,23 @@
             for (uint32_t j = 0; j < numPics; ++j) {
                 skipUE(&reader); // delta_poc_s0|1_minus1[i]
                 reader.skipBits(1); // used_by_curr_pic_s0|1_flag[i]
+                if (reader.overRead()) {
+                    return ERROR_MALFORMED;
+                }
             }
         }
+        if (reader.overRead()) {
+            return ERROR_MALFORMED;
+        }
     }
     if (reader.getBitsWithFallback(1, 0)) { // long_term_ref_pics_present_flag
         uint32_t numLongTermRefPicSps = parseUEWithFallback(&reader, 0);
         for (uint32_t i = 0; i < numLongTermRefPicSps; ++i) {
             reader.skipBits(log2MaxPicOrderCntLsb); // lt_ref_pic_poc_lsb_sps[i]
             reader.skipBits(1); // used_by_curr_pic_lt_sps_flag[i]
+            if (reader.overRead()) {
+                return ERROR_MALFORMED;
+            }
         }
     }
     reader.skipBits(1); // sps_temporal_mvp_enabled_flag
@@ -457,8 +466,8 @@
         if (numNalus == 0) {
             continue;
         }
-        // array_completeness set to 0.
-        header[0] = type;
+        // array_completeness set to 1.
+        header[0] = type | 0x80;
         header[1] = (numNalus >> 8) & 0xff;
         header[2] = numNalus & 0xff;
         header += 3;
diff --git a/media/libstagefright/MPEG2TSWriter.cpp b/media/libstagefright/MPEG2TSWriter.cpp
index 770535c..a9715c9 100644
--- a/media/libstagefright/MPEG2TSWriter.cpp
+++ b/media/libstagefright/MPEG2TSWriter.cpp
@@ -240,7 +240,7 @@
         size -= length;
     }
 
-    out->meta()->setInt64("timeUs", 0ll);
+    out->meta()->setInt64("timeUs", 0LL);
 
     sp<AMessage> notify = mNotify->dup();
     notify->setInt32("what", kNotifyBuffer);
@@ -842,7 +842,7 @@
     int64_t timeUs;
     CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
 
-    uint32_t PTS = (timeUs * 9ll) / 100ll;
+    uint32_t PTS = (timeUs * 9LL) / 100LL;
 
     size_t PES_packet_length = accessUnit->size() + 8;
     bool padding = (accessUnit->size() < (188 - 18));
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 6ff3d78..2f13dc9 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -71,6 +71,8 @@
 static const uint8_t kNalUnitTypePicParamSet = 0x08;
 static const int64_t kInitialDelayTimeUs     = 700000LL;
 static const int64_t kMaxMetadataSize = 0x4000000LL;   // 64MB max per-frame metadata size
+static const int64_t kMaxCttsOffsetTimeUs = 30 * 60 * 1000000LL;  // 30 minutes
+static const size_t kESDSScratchBufferSize = 10;  // kMaxAtomSize in Mpeg4Extractor 64MB
 
 static const char kMetaKey_Version[]    = "com.android.version";
 static const char kMetaKey_Manufacturer[]      = "com.android.manufacturer";
@@ -85,7 +87,7 @@
 static const int kTimestampDebugCount = 10;
 static const int kItemIdBase = 10000;
 static const char kExifHeader[] = {'E', 'x', 'i', 'f', '\0', '\0'};
-static const int32_t kTiffHeaderOffset = htonl(sizeof(kExifHeader));
+static const uint8_t kExifApp1Marker[] = {'E', 'x', 'i', 'f', 0xff, 0xe1};
 
 static const uint8_t kMandatoryHevcNalUnitTypes[3] = {
     kHevcNalUnitTypeVps,
@@ -125,7 +127,7 @@
     bool isAudio() const { return mIsAudio; }
     bool isMPEG4() const { return mIsMPEG4; }
     bool usePrefix() const { return mIsAvc || mIsHevc || mIsHeic; }
-    bool isExifData(const MediaBufferBase *buffer) const;
+    bool isExifData(MediaBufferBase *buffer, uint32_t *tiffHdrOffset) const;
     void addChunkOffset(off64_t offset);
     void addItemOffsetAndSize(off64_t offset, size_t size, bool isExif);
     void flushItemRefs();
@@ -136,11 +138,6 @@
     void resetInternal();
 
 private:
-    enum {
-        kMaxCttsOffsetTimeUs = 1000000LL,  // 1 second
-        kSampleArraySize = 1000,
-    };
-
     // A helper class to handle faster write box with table entries
     template<class TYPE, unsigned ENTRY_SIZE>
     // ENTRY_SIZE: # of values in each entry
@@ -317,6 +314,7 @@
     ListTableEntries<uint32_t, 1> *mStssTableEntries;
     ListTableEntries<uint32_t, 2> *mSttsTableEntries;
     ListTableEntries<uint32_t, 2> *mCttsTableEntries;
+    ListTableEntries<uint32_t, 3> *mElstTableEntries; // 3columns: segDuration, mediaTime, mediaRate
 
     int64_t mMinCttsOffsetTimeUs;
     int64_t mMinCttsOffsetTicks;
@@ -361,7 +359,7 @@
 
     Vector<uint16_t> mProperties;
     ItemRefs mDimgRefs;
-    ItemRefs mCdscRefs;
+    Vector<uint16_t> mExifList;
     uint16_t mImageItemId;
     int32_t mIsPrimary;
     int32_t mWidth, mHeight;
@@ -416,6 +414,8 @@
     // Duration is time scale based
     void addOneSttsTableEntry(size_t sampleCount, int32_t timescaledDur);
     void addOneCttsTableEntry(size_t sampleCount, int32_t timescaledDur);
+    void addOneElstTableEntry(uint32_t segmentDuration, int32_t mediaTime,
+        int16_t mediaRate, int16_t mediaRateFraction);
 
     bool isTrackMalFormed() const;
     void sendTrackSummary(bool hasMultipleTracks);
@@ -448,13 +448,14 @@
     void writeVideoFourCCBox();
     void writeMetadataFourCCBox();
     void writeStblBox(bool use32BitOffset);
+    void writeEdtsBox();
 
     Track(const Track &);
     Track &operator=(const Track &);
 };
 
 MPEG4Writer::MPEG4Writer(int fd) {
-    initInternal(fd, true /*isFirstSession*/);
+    initInternal(dup(fd), true /*isFirstSession*/);
 }
 
 MPEG4Writer::~MPEG4Writer() {
@@ -475,14 +476,15 @@
 
 void MPEG4Writer::initInternal(int fd, bool isFirstSession) {
     ALOGV("initInternal");
-    mFd = dup(fd);
+    mFd = fd;
     mNextFd = -1;
     mInitCheck = mFd < 0? NO_INIT: OK;
 
     mInterleaveDurationUs = 1000000;
 
-    mStartTimestampUs = -1ll;
+    mStartTimestampUs = -1LL;
     mStartTimeOffsetMs = -1;
+    mStartTimeOffsetBFramesUs = 0;
     mPaused = false;
     mStarted = false;
     mWriterThreadStarted = false;
@@ -1037,6 +1039,10 @@
 void MPEG4Writer::release() {
     close(mFd);
     mFd = -1;
+    if (mNextFd != -1) {
+        close(mNextFd);
+        mNextFd = -1;
+    }
     mInitCheck = NO_INIT;
     mStarted = false;
     free(mInMemoryCache);
@@ -1272,6 +1278,10 @@
     // Adjust the global start time.
     mStartTimestampUs += minCttsOffsetTimeUs - kMaxCttsOffsetTimeUs;
 
+    // Add mStartTimeOffsetBFramesUs(-ve or zero) to the duration of first entry in STTS.
+    mStartTimeOffsetBFramesUs = minCttsOffsetTimeUs - kMaxCttsOffsetTimeUs;
+    ALOGV("mStartTimeOffsetBFramesUs :%" PRId32, mStartTimeOffsetBFramesUs);
+
     for (List<Track *>::iterator it = mTracks.begin();
         it != mTracks.end(); ++it) {
         if (!(*it)->isHeic()) {
@@ -1357,14 +1367,16 @@
 }
 
 off64_t MPEG4Writer::addSample_l(
-        MediaBuffer *buffer, bool usePrefix, bool isExif, size_t *bytesWritten) {
+        MediaBuffer *buffer, bool usePrefix,
+        uint32_t tiffHdrOffset, size_t *bytesWritten) {
     off64_t old_offset = mOffset;
 
     if (usePrefix) {
         addMultipleLengthPrefixedSamples_l(buffer);
     } else {
-        if (isExif) {
-            ::write(mFd, &kTiffHeaderOffset, 4); // exif_tiff_header_offset field
+        if (tiffHdrOffset > 0) {
+            tiffHdrOffset = htonl(tiffHdrOffset);
+            ::write(mFd, &tiffHdrOffset, 4); // exif_tiff_header_offset field
             mOffset += 4;
         }
 
@@ -1734,7 +1746,7 @@
 
 void MPEG4Writer::setStartTimestampUs(int64_t timeUs) {
     ALOGI("setStartTimestampUs: %" PRId64, timeUs);
-    CHECK_GE(timeUs, 0ll);
+    CHECK_GE(timeUs, 0LL);
     Mutex::Autolock autoLock(mLock);
     if (mStartTimestampUs < 0 || mStartTimestampUs > timeUs) {
         mStartTimestampUs = timeUs;
@@ -1747,6 +1759,11 @@
     return mStartTimestampUs;
 }
 
+int32_t MPEG4Writer::getStartTimeOffsetBFramesUs() {
+    Mutex::Autolock autoLock(mLock);
+    return mStartTimeOffsetBFramesUs;
+}
+
 size_t MPEG4Writer::numTracks() {
     Mutex::Autolock autolock(mLock);
     return mTracks.size();
@@ -1776,6 +1793,7 @@
       mStssTableEntries(new ListTableEntries<uint32_t, 1>(1000)),
       mSttsTableEntries(new ListTableEntries<uint32_t, 2>(1000)),
       mCttsTableEntries(new ListTableEntries<uint32_t, 2>(1000)),
+      mElstTableEntries(new ListTableEntries<uint32_t, 3>(3)), // Reserve 3 rows, a row has 3 items
       mMinCttsOffsetTimeUs(0),
       mMinCttsOffsetTicks(0),
       mMaxCttsOffsetTicks(0),
@@ -1786,7 +1804,6 @@
       mStartTimestampUs(-1),
       mRotation(0),
       mDimgRefs("dimg"),
-      mCdscRefs("cdsc"),
       mImageItemId(0),
       mIsPrimary(0),
       mWidth(0),
@@ -1842,46 +1859,48 @@
 
 // Clear all the internal states except the CSD data.
 void MPEG4Writer::Track::resetInternal() {
-      mDone = false;
-      mPaused = false;
-      mResumed = false;
-      mStarted = false;
-      mGotStartKeyFrame = false;
-      mIsMalformed = false;
-      mTrackDurationUs = 0;
-      mEstimatedTrackSizeBytes = 0;
-      mSamplesHaveSameSize = 0;
-      if (mStszTableEntries != NULL) {
-         delete mStszTableEntries;
-         mStszTableEntries = new ListTableEntries<uint32_t, 1>(1000);
-      }
-
-      if (mStcoTableEntries != NULL) {
-         delete mStcoTableEntries;
-         mStcoTableEntries = new ListTableEntries<uint32_t, 1>(1000);
-      }
-      if (mCo64TableEntries != NULL) {
-         delete mCo64TableEntries;
-         mCo64TableEntries = new ListTableEntries<off64_t, 1>(1000);
-      }
-
-      if (mStscTableEntries != NULL) {
-         delete mStscTableEntries;
-         mStscTableEntries = new ListTableEntries<uint32_t, 3>(1000);
-      }
-      if (mStssTableEntries != NULL) {
-         delete mStssTableEntries;
-         mStssTableEntries = new ListTableEntries<uint32_t, 1>(1000);
-      }
-      if (mSttsTableEntries != NULL) {
-         delete mSttsTableEntries;
-         mSttsTableEntries = new ListTableEntries<uint32_t, 2>(1000);
-      }
-      if (mCttsTableEntries != NULL) {
-         delete mCttsTableEntries;
-         mCttsTableEntries = new ListTableEntries<uint32_t, 2>(1000);
-      }
-      mReachedEOS = false;
+    mDone = false;
+    mPaused = false;
+    mResumed = false;
+    mStarted = false;
+    mGotStartKeyFrame = false;
+    mIsMalformed = false;
+    mTrackDurationUs = 0;
+    mEstimatedTrackSizeBytes = 0;
+    mSamplesHaveSameSize = 0;
+    if (mStszTableEntries != NULL) {
+        delete mStszTableEntries;
+        mStszTableEntries = new ListTableEntries<uint32_t, 1>(1000);
+    }
+    if (mStcoTableEntries != NULL) {
+        delete mStcoTableEntries;
+        mStcoTableEntries = new ListTableEntries<uint32_t, 1>(1000);
+    }
+    if (mCo64TableEntries != NULL) {
+        delete mCo64TableEntries;
+        mCo64TableEntries = new ListTableEntries<off64_t, 1>(1000);
+    }
+    if (mStscTableEntries != NULL) {
+        delete mStscTableEntries;
+        mStscTableEntries = new ListTableEntries<uint32_t, 3>(1000);
+    }
+    if (mStssTableEntries != NULL) {
+        delete mStssTableEntries;
+        mStssTableEntries = new ListTableEntries<uint32_t, 1>(1000);
+    }
+    if (mSttsTableEntries != NULL) {
+        delete mSttsTableEntries;
+        mSttsTableEntries = new ListTableEntries<uint32_t, 2>(1000);
+    }
+    if (mCttsTableEntries != NULL) {
+        delete mCttsTableEntries;
+        mCttsTableEntries = new ListTableEntries<uint32_t, 2>(1000);
+    }
+    if (mElstTableEntries != NULL) {
+        delete mElstTableEntries;
+        mElstTableEntries = new ListTableEntries<uint32_t, 3>(3);
+    }
+    mReachedEOS = false;
 }
 
 void MPEG4Writer::Track::updateTrackSizeEstimate() {
@@ -1900,6 +1919,7 @@
                                     mStssTableEntries->count() * 4 +   // stss box size
                                     mSttsTableEntries->count() * 8 +   // stts box size
                                     mCttsTableEntries->count() * 8 +   // ctts box size
+                                    mElstTableEntries->count() * 12 +   // elst box size
                                     stcoBoxSizeBytes +           // stco box size
                                     stszBoxSizeBytes;            // stsz box size
     }
@@ -1936,6 +1956,16 @@
     mCttsTableEntries->add(htonl(duration));
 }
 
+void MPEG4Writer::Track::addOneElstTableEntry(
+    uint32_t segmentDuration, int32_t mediaTime, int16_t mediaRate, int16_t mediaRateFraction) {
+    ALOGV("segmentDuration:%u, mediaTime:%d", segmentDuration, mediaTime);
+    ALOGV("mediaRate :%" PRId16 ", mediaRateFraction :%" PRId16 ", Ored %u", mediaRate,
+        mediaRateFraction, ((((uint32_t)mediaRate) << 16) | ((uint32_t)mediaRateFraction)));
+    mElstTableEntries->add(htonl(segmentDuration));
+    mElstTableEntries->add(htonl(mediaTime));
+    mElstTableEntries->add(htonl((((uint32_t)mediaRate) << 16) | (uint32_t)mediaRateFraction));
+}
+
 status_t MPEG4Writer::setNextFd(int fd) {
     ALOGV("addNextFd");
     Mutex::Autolock l(mLock);
@@ -1950,15 +1980,38 @@
         // No need to set a new FD yet.
         return INVALID_OPERATION;
     }
-    mNextFd = fd;
+    mNextFd = dup(fd);
     return OK;
 }
 
-bool MPEG4Writer::Track::isExifData(const MediaBufferBase *buffer) const {
-    return mIsHeic
-            && (buffer->range_length() > sizeof(kExifHeader))
-            && !memcmp((uint8_t *)buffer->data() + buffer->range_offset(),
-                    kExifHeader, sizeof(kExifHeader));
+bool MPEG4Writer::Track::isExifData(
+        MediaBufferBase *buffer, uint32_t *tiffHdrOffset) const {
+    if (!mIsHeic) {
+        return false;
+    }
+
+    // Exif block starting with 'Exif\0\0'
+    size_t length = buffer->range_length();
+    uint8_t *data = (uint8_t *)buffer->data() + buffer->range_offset();
+    if ((length > sizeof(kExifHeader))
+        && !memcmp(data, kExifHeader, sizeof(kExifHeader))) {
+        *tiffHdrOffset = sizeof(kExifHeader);
+        return true;
+    }
+
+    // Exif block starting with fourcc 'Exif' followed by APP1 marker
+    if ((length > sizeof(kExifApp1Marker) + 2 + sizeof(kExifHeader))
+            && !memcmp(data, kExifApp1Marker, sizeof(kExifApp1Marker))
+            && !memcmp(data + sizeof(kExifApp1Marker) + 2, kExifHeader, sizeof(kExifHeader))) {
+        // skip 'Exif' fourcc
+        buffer->set_range(4, buffer->range_length() - 4);
+
+        // 2-byte APP1 + 2-byte size followed by kExifHeader
+        *tiffHdrOffset = 2 + 2 + sizeof(kExifHeader);
+        return true;
+    }
+
+    return false;
 }
 
 void MPEG4Writer::Track::addChunkOffset(off64_t offset) {
@@ -1984,7 +2037,7 @@
     }
 
     if (isExif) {
-         mCdscRefs.value.push_back(mOwner->addItem_l({
+         mExifList.push_back(mOwner->addItem_l({
             .itemType = "Exif",
             .isPrimary = false,
             .isHidden = false,
@@ -2087,7 +2140,16 @@
 
     if (mImageItemId > 0) {
         mOwner->addRefs_l(mImageItemId, mDimgRefs);
-        mOwner->addRefs_l(mImageItemId, mCdscRefs);
+
+        if (!mExifList.empty()) {
+            // The "cdsc" ref is from the metadata/exif item to the image item.
+            // So the refs all contain the image item.
+            ItemRefs cdscRefs("cdsc");
+            cdscRefs.value.push_back(mImageItemId);
+            for (uint16_t exifItem : mExifList) {
+                mOwner->addRefs_l(exifItem, cdscRefs);
+            }
+        }
     }
 }
 
@@ -2117,11 +2179,11 @@
     switch (msg->what()) {
         case kWhatSwitch:
         {
-            finishCurrentSession();
             mLock.lock();
             int fd = mNextFd;
             mNextFd = -1;
             mLock.unlock();
+            finishCurrentSession();
             initInternal(fd, false /*isFirstSession*/);
             start(mStartMeta.get());
             mSwitchPending = false;
@@ -2173,6 +2235,7 @@
     delete mSttsTableEntries;
     delete mStssTableEntries;
     delete mCttsTableEntries;
+    delete mElstTableEntries;
 
     mStszTableEntries = NULL;
     mStcoTableEntries = NULL;
@@ -2181,6 +2244,7 @@
     mSttsTableEntries = NULL;
     mStssTableEntries = NULL;
     mCttsTableEntries = NULL;
+    mElstTableEntries = NULL;
 
     if (mCodecSpecificData != NULL) {
         free(mCodecSpecificData);
@@ -2237,14 +2301,16 @@
     while (!chunk->mSamples.empty()) {
         List<MediaBuffer *>::iterator it = chunk->mSamples.begin();
 
-        int32_t isExif;
-        if (!(*it)->meta_data().findInt32(kKeyIsExif, &isExif)) {
-            isExif = 0;
+        uint32_t tiffHdrOffset;
+        if (!(*it)->meta_data().findInt32(
+                kKeyExifTiffOffset, (int32_t*)&tiffHdrOffset)) {
+            tiffHdrOffset = 0;
         }
+        bool isExif = (tiffHdrOffset > 0);
         bool usePrefix = chunk->mTrack->usePrefix() && !isExif;
 
         size_t bytesWritten;
-        off64_t offset = addSample_l(*it, usePrefix, isExif, &bytesWritten);
+        off64_t offset = addSample_l(*it, usePrefix, tiffHdrOffset, &bytesWritten);
 
         if (chunk->mTrack->isHeic()) {
             chunk->mTrack->addItemOffsetAndSize(offset, bytesWritten, isExif);
@@ -2849,14 +2915,18 @@
 }
 
 void MPEG4Writer::Track::dumpTimeStamps() {
-    ALOGE("Dumping %s track's last 10 frames timestamp and frame type ", getTrackType());
-    std::string timeStampString;
-    for (std::list<TimestampDebugHelperEntry>::iterator entry = mTimestampDebugHelper.begin();
-            entry != mTimestampDebugHelper.end(); ++entry) {
-        timeStampString += "(" + std::to_string(entry->pts)+
-                "us, " + std::to_string(entry->dts) + "us " + entry->frameType + ") ";
+    if (!mTimestampDebugHelper.empty()) {
+        std::string timeStampString = "Dumping " + std::string(getTrackType()) + " track's last " +
+                                      std::to_string(mTimestampDebugHelper.size()) +
+                                      " frames' timestamps(pts, dts) and frame type : ";
+        for (const TimestampDebugHelperEntry& entry : mTimestampDebugHelper) {
+            timeStampString += "\n(" + std::to_string(entry.pts) + "us, " +
+                               std::to_string(entry.dts) + "us " + entry.frameType + ") ";
+        }
+        ALOGE("%s", timeStampString.c_str());
+    } else {
+        ALOGE("0 frames to dump timeStamps in %s track ", getTrackType());
     }
-    ALOGE("%s", timeStampString.c_str());
 }
 
 status_t MPEG4Writer::Track::threadEntry() {
@@ -2970,10 +3040,11 @@
         }
 
         bool isExif = false;
+        uint32_t tiffHdrOffset = 0;
         int32_t isMuxerData;
         if (buffer->meta_data().findInt32(kKeyIsMuxerData, &isMuxerData) && isMuxerData) {
             // We only support one type of muxer data, which is Exif data block.
-            isExif = isExifData(buffer);
+            isExif = isExifData(buffer, &tiffHdrOffset);
             if (!isExif) {
                 ALOGW("Ignoring bad Exif data block");
                 buffer->release();
@@ -2995,7 +3066,7 @@
         buffer = NULL;
 
         if (isExif) {
-            copy->meta_data().setInt32(kKeyIsExif, 1);
+            copy->meta_data().setInt32(kKeyExifTiffOffset, tiffHdrOffset);
         }
         bool usePrefix = this->usePrefix() && !isExif;
 
@@ -3060,14 +3131,14 @@
         if (!mIsHeic) {
             if (mStszTableEntries->count() == 0) {
                 mFirstSampleTimeRealUs = systemTime() / 1000;
+                mOwner->setStartTimestampUs(timestampUs);
                 mStartTimestampUs = timestampUs;
-                mOwner->setStartTimestampUs(mStartTimestampUs);
                 previousPausedDurationUs = mStartTimestampUs;
             }
 
             if (mResumed) {
                 int64_t durExcludingEarlierPausesUs = timestampUs - previousPausedDurationUs;
-                if (WARN_UNLESS(durExcludingEarlierPausesUs >= 0ll, "for %s track", trackName)) {
+                if (WARN_UNLESS(durExcludingEarlierPausesUs >= 0LL, "for %s track", trackName)) {
                     copy->release();
                     mSource->stop();
                     mIsMalformed = true;
@@ -3088,7 +3159,7 @@
             TimestampDebugHelperEntry timestampDebugEntry;
             timestampUs -= previousPausedDurationUs;
             timestampDebugEntry.pts = timestampUs;
-            if (WARN_UNLESS(timestampUs >= 0ll, "for %s track", trackName)) {
+            if (WARN_UNLESS(timestampUs >= 0LL, "for %s track", trackName)) {
                 copy->release();
                 mSource->stop();
                 mIsMalformed = true;
@@ -3127,7 +3198,7 @@
 
                 cttsOffsetTimeUs =
                         timestampUs + kMaxCttsOffsetTimeUs - decodingTimeUs;
-                if (WARN_UNLESS(cttsOffsetTimeUs >= 0ll, "for %s track", trackName)) {
+                if (WARN_UNLESS(cttsOffsetTimeUs >= 0LL, "for %s track", trackName)) {
                     copy->release();
                     mSource->stop();
                     mIsMalformed = true;
@@ -3185,7 +3256,7 @@
                 }
             }
 
-            if (WARN_UNLESS(timestampUs >= 0ll, "for %s track", trackName)) {
+            if (WARN_UNLESS(timestampUs >= 0LL, "for %s track", trackName)) {
                 copy->release();
                 mSource->stop();
                 mIsMalformed = true;
@@ -3206,7 +3277,7 @@
             currDurationTicks =
                 ((timestampUs * mTimeScale + 500000LL) / 1000000LL -
                     (lastTimestampUs * mTimeScale + 500000LL) / 1000000LL);
-            if (currDurationTicks < 0ll) {
+            if (currDurationTicks < 0LL) {
                 ALOGE("do not support out of order frames (timestamp: %lld < last: %lld for %s track",
                         (long long)timestampUs, (long long)lastTimestampUs, trackName);
                 copy->release();
@@ -3268,7 +3339,8 @@
         }
         if (!hasMultipleTracks) {
             size_t bytesWritten;
-            off64_t offset = mOwner->addSample_l(copy, usePrefix, isExif, &bytesWritten);
+            off64_t offset = mOwner->addSample_l(
+                    copy, usePrefix, tiffHdrOffset, &bytesWritten);
 
             if (mIsHeic) {
                 addItemOffsetAndSize(offset, bytesWritten, isExif);
@@ -3526,7 +3598,7 @@
 }
 
 int64_t MPEG4Writer::Track::getDurationUs() const {
-    return mTrackDurationUs + getStartTimeOffsetTimeUs();
+    return mTrackDurationUs + getStartTimeOffsetTimeUs() + mOwner->getStartTimeOffsetBFramesUs();
 }
 
 int64_t MPEG4Writer::Track::getEstimatedTrackSizeBytes() const {
@@ -3612,6 +3684,7 @@
     uint32_t now = getMpeg4Time();
     mOwner->beginBox("trak");
         writeTkhdBox(now);
+        writeEdtsBox();
         mOwner->beginBox("mdia");
             writeMdhdBox(now);
             writeHdlrBox();
@@ -3674,6 +3747,29 @@
         TRESPASS();
     }
     mOwner->beginBox(fourcc);    // TextMetaDataSampleEntry
+
+    //  HACK to make the metadata track compliant with the ISO standard.
+    //
+    //  Metadata track is added from API 26 and the original implementation does not
+    //  fully followed the TextMetaDataSampleEntry specified in ISO/IEC 14496-12-2015
+    //  in that only the mime_format is written out. content_encoding and
+    //  data_reference_index have not been written out. This leads to the failure
+    //  when some MP4 parser tries to parse the metadata track according to the
+    //  standard. The hack here will make the metadata track compliant with the
+    //  standard while still maintaining backwards compatibility. This would enable
+    //  Android versions before API 29 to be able to read out the standard compliant
+    //  Metadata track generated with Android API 29 and upward. The trick is based
+    //  on the fact that the Metadata track must start with prefix “application/” and
+    //  those missing fields are not used in Android's Metadata track. By writting
+    //  out the mime_format twice, the first mime_format will be used to fill out the
+    //  missing reserved, data_reference_index and content encoding fields. On the
+    //  parser side, the extracter before API 29  will read out the first mime_format
+    //  correctly and drop the second mime_format. The extractor from API 29 will
+    //  check if the reserved, data_reference_index and content encoding are filled
+    //  with “application” to detect if this is a standard compliant metadata track
+    //  and read out the data accordingly.
+    mOwner->writeCString(mime);
+
     mOwner->writeCString(mime);  // metadata mime_format
     mOwner->endBox(); // mett
 }
@@ -3787,22 +3883,52 @@
     mOwner->endBox();
 }
 
+static void generateEsdsSize(size_t dataLength, size_t* sizeGenerated, uint8_t* buffer) {
+    size_t offset = 0, cur = 0;
+    size_t more = 0x00;
+    *sizeGenerated = 0;
+    /* Start with the LSB(7 bits) of dataLength and build the byte sequence upto MSB.
+     * Continuation flag(most significant bit) will be set on the first N-1 bytes.
+     */
+    do {
+        buffer[cur++] = (dataLength & 0x7f) | more;
+        dataLength >>= 7;
+        more = 0x80;
+        ++(*sizeGenerated);
+    } while (dataLength > 0u);
+    --cur;
+    // Reverse the newly formed byte sequence.
+    while (cur > offset) {
+        uint8_t tmp = buffer[cur];
+        buffer[cur--] = buffer[offset];
+        buffer[offset++] = tmp;
+    }
+}
+
 void MPEG4Writer::Track::writeMp4aEsdsBox() {
-    mOwner->beginBox("esds");
     CHECK(mCodecSpecificData);
     CHECK_GT(mCodecSpecificDataSize, 0u);
 
-    // Make sure all sizes encode to a single byte.
-    CHECK_LT(mCodecSpecificDataSize + 23, 128u);
+    uint8_t sizeESDBuffer[kESDSScratchBufferSize];
+    uint8_t sizeDCDBuffer[kESDSScratchBufferSize];
+    uint8_t sizeDSIBuffer[kESDSScratchBufferSize];
+    size_t sizeESD = 0;
+    size_t sizeDCD = 0;
+    size_t sizeDSI = 0;
+    generateEsdsSize(mCodecSpecificDataSize, &sizeDSI, sizeDSIBuffer);
+    generateEsdsSize(mCodecSpecificDataSize + sizeDSI + 14, &sizeDCD, sizeDCDBuffer);
+    generateEsdsSize(mCodecSpecificDataSize + sizeDSI + sizeDCD + 21, &sizeESD, sizeESDBuffer);
+
+    mOwner->beginBox("esds");
 
     mOwner->writeInt32(0);     // version=0, flags=0
     mOwner->writeInt8(0x03);   // ES_DescrTag
-    mOwner->writeInt8(23 + mCodecSpecificDataSize);
+    mOwner->write(sizeESDBuffer, sizeESD);
     mOwner->writeInt16(0x0000);// ES_ID
     mOwner->writeInt8(0x00);
 
     mOwner->writeInt8(0x04);   // DecoderConfigDescrTag
-    mOwner->writeInt8(15 + mCodecSpecificDataSize);
+    mOwner->write(sizeDCDBuffer, sizeDCD);
     mOwner->writeInt8(0x40);   // objectTypeIndication ISO/IEC 14492-2
     mOwner->writeInt8(0x15);   // streamType AudioStream
 
@@ -3817,7 +3943,7 @@
     mOwner->writeInt32(avgBitrate);
 
     mOwner->writeInt8(0x05);   // DecoderSpecificInfoTag
-    mOwner->writeInt8(mCodecSpecificDataSize);
+    mOwner->write(sizeDSIBuffer, sizeDSI);
     mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
 
     static const uint8_t kData2[] = {
@@ -3834,20 +3960,27 @@
     CHECK(mCodecSpecificData);
     CHECK_GT(mCodecSpecificDataSize, 0u);
 
-    // Make sure all sizes encode to a single byte.
-    CHECK_LT(23 + mCodecSpecificDataSize, 128u);
+    uint8_t sizeESDBuffer[kESDSScratchBufferSize];
+    uint8_t sizeDCDBuffer[kESDSScratchBufferSize];
+    uint8_t sizeDSIBuffer[kESDSScratchBufferSize];
+    size_t sizeESD = 0;
+    size_t sizeDCD = 0;
+    size_t sizeDSI = 0;
+    generateEsdsSize(mCodecSpecificDataSize, &sizeDSI, sizeDSIBuffer);
+    generateEsdsSize(mCodecSpecificDataSize + sizeDSI + 14, &sizeDCD, sizeDCDBuffer);
+    generateEsdsSize(mCodecSpecificDataSize + sizeDSI + sizeDCD + 21, &sizeESD, sizeESDBuffer);
 
     mOwner->beginBox("esds");
 
     mOwner->writeInt32(0);    // version=0, flags=0
 
     mOwner->writeInt8(0x03);  // ES_DescrTag
-    mOwner->writeInt8(23 + mCodecSpecificDataSize);
+    mOwner->write(sizeESDBuffer, sizeESD);
     mOwner->writeInt16(0x0000);  // ES_ID
     mOwner->writeInt8(0x1f);
 
     mOwner->writeInt8(0x04);  // DecoderConfigDescrTag
-    mOwner->writeInt8(15 + mCodecSpecificDataSize);
+    mOwner->write(sizeDCDBuffer, sizeDCD);
     mOwner->writeInt8(0x20);  // objectTypeIndication ISO/IEC 14492-2
     mOwner->writeInt8(0x11);  // streamType VisualStream
 
@@ -3865,7 +3998,7 @@
 
     mOwner->writeInt8(0x05);  // DecoderSpecificInfoTag
 
-    mOwner->writeInt8(mCodecSpecificDataSize);
+    mOwner->write(sizeDSIBuffer, sizeDSI);
     mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
 
     static const uint8_t kData2[] = {
@@ -3959,6 +4092,33 @@
     mOwner->endBox();
 }
 
+void MPEG4Writer::Track::writeEdtsBox(){
+    ALOGV("%s : getStartTimeOffsetTimeUs of track:%" PRId64 " us", getTrackType(),
+        getStartTimeOffsetTimeUs());
+
+    // Prepone video playback.
+    if (mMinCttsOffsetTicks != mMaxCttsOffsetTicks) {
+        int32_t mvhdTimeScale = mOwner->getTimeScale();
+        uint32_t tkhdDuration = (getDurationUs() * mvhdTimeScale + 5E5) / 1E6;
+        int64_t mediaTime = ((kMaxCttsOffsetTimeUs - getMinCttsOffsetTimeUs())
+            * mTimeScale + 5E5) / 1E6;
+        if (tkhdDuration > 0 && mediaTime > 0) {
+            addOneElstTableEntry(tkhdDuration, mediaTime, 1, 0);
+        }
+    }
+
+    if (mElstTableEntries->count() == 0) {
+        return;
+    }
+
+    mOwner->beginBox("edts");
+        mOwner->beginBox("elst");
+            mOwner->writeInt32(0); // version=0, flags=0
+            mElstTableEntries->write(mOwner);
+        mOwner->endBox(); // elst;
+    mOwner->endBox(); // edts
+}
+
 void MPEG4Writer::Track::writeMdhdBox(uint32_t now) {
     int64_t trakDurationUs = getDurationUs();
     int64_t mdhdDuration = (trakDurationUs * mTimeScale + 5E5) / 1E6;
@@ -4095,7 +4255,9 @@
         uint32_t duration;
         CHECK(mSttsTableEntries->get(duration, 1));
         duration = htonl(duration);  // Back to host byte order
-        mSttsTableEntries->set(htonl(duration + getStartTimeOffsetScaledTime()), 1);
+        int32_t startTimeOffsetScaled = (((getStartTimeOffsetTimeUs() +
+            mOwner->getStartTimeOffsetBFramesUs()) * mTimeScale) + 500000LL) / 1000000LL;
+        mSttsTableEntries->set(htonl((int32_t)duration + startTimeOffsetScaled), 1);
     }
     mSttsTableEntries->write(mOwner);
     mOwner->endBox();  // stts
diff --git a/media/libstagefright/MediaClock.cpp b/media/libstagefright/MediaClock.cpp
index 41dbfd4..4f9bc6d 100644
--- a/media/libstagefright/MediaClock.cpp
+++ b/media/libstagefright/MediaClock.cpp
@@ -28,7 +28,7 @@
 
 // Maximum allowed time backwards from anchor change.
 // If larger than this threshold, it's treated as discontinuity.
-static const int64_t kAnchorFluctuationAllowedUs = 10000ll;
+static const int64_t kAnchorFluctuationAllowedUs = 10000LL;
 
 MediaClock::Timer::Timer(const sp<AMessage> &notify, int64_t mediaTimeUs, int64_t adjustRealUs)
     : mNotify(notify),
@@ -110,7 +110,7 @@
     if (mAnchorTimeRealUs != -1) {
         int64_t oldNowMediaUs =
             mAnchorTimeMediaUs + (nowUs - mAnchorTimeRealUs) * (double)mPlaybackRate;
-        if (nowMediaUs < oldNowMediaUs
+        if (nowMediaUs < oldNowMediaUs + kAnchorFluctuationAllowedUs
                 && nowMediaUs > oldNowMediaUs - kAnchorFluctuationAllowedUs) {
             return;
         }
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 353e407..f579e9d 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -550,7 +550,7 @@
 
 void MediaCodec::initAnalyticsItem() {
     if (mAnalyticsItem == NULL) {
-        mAnalyticsItem = new MediaAnalyticsItem(kCodecKeyName);
+        mAnalyticsItem = MediaAnalyticsItem::create(kCodecKeyName);
     }
 
     mLatencyHist.setup(kLatencyHistBuckets, kLatencyHistWidth, kLatencyHistFloor);
@@ -862,9 +862,9 @@
 //static
 sp<CodecBase> MediaCodec::GetCodecBase(const AString &name, const char *owner) {
     if (owner) {
-        if (strncmp(owner, "default", 8) == 0) {
+        if (strcmp(owner, "default") == 0) {
             return new ACodec;
-        } else if (strncmp(owner, "codec2", 7) == 0) {
+        } else if (strncmp(owner, "codec2", 6) == 0) {
             return CreateCCodec();
         }
     }
@@ -911,10 +911,10 @@
             continue;
         }
         mCodecInfo = mcl->getCodecInfo(codecIdx);
-        Vector<AString> mimes;
-        mCodecInfo->getSupportedMimes(&mimes);
-        for (size_t i = 0; i < mimes.size(); i++) {
-            if (mimes[i].startsWith("video/")) {
+        Vector<AString> mediaTypes;
+        mCodecInfo->getSupportedMediaTypes(&mediaTypes);
+        for (size_t i = 0; i < mediaTypes.size(); i++) {
+            if (mediaTypes[i].startsWith("video/")) {
                 mIsVideo = true;
                 break;
             }
@@ -1052,8 +1052,9 @@
         }
 
         // Prevent possible integer overflow in downstream code.
-        if ((uint64_t)mVideoWidth * mVideoHeight > (uint64_t)INT32_MAX / 4) {
-            ALOGE("buffer size is too big, width=%d, height=%d", mVideoWidth, mVideoHeight);
+        if (mVideoWidth < 0 || mVideoHeight < 0 ||
+               (uint64_t)mVideoWidth * mVideoHeight > (uint64_t)INT32_MAX / 4) {
+            ALOGE("Invalid size(s), width=%d, height=%d", mVideoWidth, mVideoHeight);
             return BAD_VALUE;
         }
     }
@@ -1112,6 +1113,7 @@
             break;
         }
     }
+
     return err;
 }
 
@@ -1658,10 +1660,12 @@
         return;
     }
     int32_t colorFormat;
-    if (mSoftRenderer != NULL
-            && mOutputFormat->contains("hdr-static-info")
+    if (mOutputFormat->contains("hdr-static-info")
             && mOutputFormat->findInt32("color-format", &colorFormat)
-            && (colorFormat == OMX_COLOR_FormatYUV420Planar16)) {
+            // check format for OMX only, for C2 the format is always opaque since the
+            // software rendering doesn't go through client
+            && ((mSoftRenderer != NULL && colorFormat == OMX_COLOR_FormatYUV420Planar16)
+                    || mOwnerName.equalsIgnoreCase("codec2::software"))) {
         int32_t left, top, right, bottom, width, height;
         int64_t totalPixel = 0;
         if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
@@ -1829,8 +1833,8 @@
                             // the shutdown complete notification. If we
                             // don't, we'll timeout and force release.
                             sendErrorResponse = false;
+                            FALLTHROUGH_INTENDED;
                         }
-                        // fall-thru
                         case STOPPING:
                         {
                             if (mFlags & kFlagSawMediaServerDie) {
@@ -1933,6 +1937,13 @@
 
                 case kWhatComponentAllocated:
                 {
+                    if (mState == RELEASING || mState == UNINITIALIZED) {
+                        // In case a kWhatError or kWhatRelease message came in and replied,
+                        // we log a warning and ignore.
+                        ALOGW("allocate interrupted by error or release, current state %d",
+                              mState);
+                        break;
+                    }
                     CHECK_EQ(mState, INITIALIZING);
                     setState(INITIALIZED);
                     mFlags |= kFlagIsComponentAllocated;
@@ -1950,6 +1961,7 @@
                     } else {
                         mFlags &= ~kFlagUsesSoftwareRenderer;
                     }
+                    mOwnerName = owner;
 
                     MediaResource::Type resourceType;
                     if (mComponentName.endsWith(".secure")) {
@@ -1973,10 +1985,11 @@
 
                 case kWhatComponentConfigured:
                 {
-                    if (mState == UNINITIALIZED || mState == INITIALIZED) {
-                        // In case a kWhatError message came in and replied with error,
+                    if (mState == RELEASING || mState == UNINITIALIZED || mState == INITIALIZED) {
+                        // In case a kWhatError or kWhatRelease message came in and replied,
                         // we log a warning and ignore.
-                        ALOGW("configure interrupted by error, current state %d", mState);
+                        ALOGW("configure interrupted by error or release, current state %d",
+                              mState);
                         break;
                     }
                     CHECK_EQ(mState, CONFIGURING);
@@ -1986,6 +1999,13 @@
 
                     CHECK(msg->findMessage("input-format", &mInputFormat));
                     CHECK(msg->findMessage("output-format", &mOutputFormat));
+
+                    // limit to confirming the opt-in behavior to minimize any behavioral change
+                    if (mSurface != nullptr && !mAllowFrameDroppingBySurface) {
+                        // signal frame dropping mode in the input format as this may also be
+                        // meaningful and confusing for an encoder in a transcoder scenario
+                        mInputFormat->setInt32("allow-frame-drop", mAllowFrameDroppingBySurface);
+                    }
                     ALOGV("[%s] configured as input format: %s, output format: %s",
                             mComponentName.c_str(),
                             mInputFormat->debugString(4).c_str(),
@@ -2067,6 +2087,13 @@
 
                 case kWhatStartCompleted:
                 {
+                    if (mState == RELEASING || mState == UNINITIALIZED) {
+                        // In case a kWhatRelease message came in and replied,
+                        // we log a warning and ignore.
+                        ALOGW("start interrupted by release, current state %d", mState);
+                        break;
+                    }
+
                     CHECK_EQ(mState, STARTING);
                     if (mIsVideo) {
                         addResource(
@@ -2197,7 +2224,15 @@
                                 }
                             }
 
+                            sp<ABuffer> hdr10PlusInfo;
+                            if (mOutputFormat->findBuffer("hdr10-plus-info", &hdr10PlusInfo)
+                                    && hdr10PlusInfo != nullptr && hdr10PlusInfo->size() > 0) {
+                                native_window_set_buffers_hdr10_plus_metadata(mSurface.get(),
+                                        hdr10PlusInfo->size(), hdr10PlusInfo->data());
+                            }
+
                             if (mime.startsWithIgnoreCase("video/")) {
+                                mSurface->setDequeueTimeout(-1);
                                 mSoftRenderer = new SoftwareRenderer(mSurface, mRotationDegrees);
                             }
                         }
@@ -2403,6 +2438,11 @@
             }
 
             if (obj != NULL) {
+                if (!format->findInt32("allow-frame-drop", &mAllowFrameDroppingBySurface)) {
+                    // allow frame dropping by surface by default
+                    mAllowFrameDroppingBySurface = true;
+                }
+
                 format->setObject("native-window", obj);
                 status_t err = handleSetSurface(static_cast<Surface *>(obj.get()));
                 if (err != OK) {
@@ -2410,6 +2450,9 @@
                     break;
                 }
             } else {
+                // we are not using surface so this variable is not used, but initialize sensibly anyway
+                mAllowFrameDroppingBySurface = false;
+
                 handleSetSurface(NULL);
             }
 
@@ -2485,6 +2528,7 @@
                                             && (mFlags & kFlagPushBlankBuffersOnShutdown)) {
                                         pushBlankBuffersToNativeWindow(mSurface.get());
                                     }
+                                    surface->setDequeueTimeout(-1);
                                     mSoftRenderer = new SoftwareRenderer(surface);
                                     // TODO: check if this was successful
                                 } else {
@@ -2625,11 +2669,12 @@
                 break;
             }
 
-            // If we're flushing, or we're stopping but received a release
-            // request, post the reply for the pending call first, and consider
-            // it done. The reply token will be replaced after this, and we'll
-            // no longer be able to reply.
-            if (mState == FLUSHING || mState == STOPPING) {
+            // If we're flushing, stopping, configuring or starting  but
+            // received a release request, post the reply for the pending call
+            // first, and consider it done. The reply token will be replaced
+            // after this, and we'll no longer be able to reply.
+            if (mState == FLUSHING || mState == STOPPING
+                    || mState == CONFIGURING || mState == STARTING) {
                 (new AMessage)->postReply(mReplyID);
             }
 
@@ -2674,7 +2719,7 @@
             CHECK(msg->senderAwaitsResponse(&replyID));
 
             if (mFlags & kFlagIsAsync) {
-                ALOGE("dequeueOutputBuffer can't be used in async mode");
+                ALOGE("dequeueInputBuffer can't be used in async mode");
                 PostReplyWithError(replyID, INVALID_OPERATION);
                 break;
             }
@@ -2692,7 +2737,7 @@
             int64_t timeoutUs;
             CHECK(msg->findInt64("timeoutUs", &timeoutUs));
 
-            if (timeoutUs == 0ll) {
+            if (timeoutUs == 0LL) {
                 PostReplyWithError(replyID, -EAGAIN);
                 break;
             }
@@ -2700,7 +2745,7 @@
             mFlags |= kFlagDequeueInputPending;
             mDequeueInputReplyID = replyID;
 
-            if (timeoutUs > 0ll) {
+            if (timeoutUs > 0LL) {
                 sp<AMessage> timeoutMsg =
                     new AMessage(kWhatDequeueInputTimedOut, this);
                 timeoutMsg->setInt32(
@@ -2766,7 +2811,7 @@
             int64_t timeoutUs;
             CHECK(msg->findInt64("timeoutUs", &timeoutUs));
 
-            if (timeoutUs == 0ll) {
+            if (timeoutUs == 0LL) {
                 PostReplyWithError(replyID, -EAGAIN);
                 break;
             }
@@ -2774,7 +2819,7 @@
             mFlags |= kFlagDequeueOutputPending;
             mDequeueOutputReplyID = replyID;
 
-            if (timeoutUs > 0ll) {
+            if (timeoutUs > 0LL) {
                 sp<AMessage> timeoutMsg =
                     new AMessage(kWhatDequeueOutputTimedOut, this);
                 timeoutMsg->setInt32(
@@ -3035,7 +3080,7 @@
     msg->setSize("index", bufferIndex);
     msg->setSize("offset", 0);
     msg->setSize("size", csd->size());
-    msg->setInt64("timeUs", 0ll);
+    msg->setInt64("timeUs", 0LL);
     msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
     msg->setPointer("errorDetailMsg", &errorDetailMsg);
 
@@ -3400,6 +3445,10 @@
 
         if (err != OK) {
             ALOGE("nativeWindowConnect returned an error: %s (%d)", strerror(-err), err);
+        } else {
+            if (!mAllowFrameDroppingBySurface) {
+                disableLegacyBufferDropPostQ(surface);
+            }
         }
     }
     // do not return ALREADY_EXISTS unless surfaces are the same
diff --git a/media/libstagefright/MediaCodecList.cpp b/media/libstagefright/MediaCodecList.cpp
index eaff283..3d58d4b 100644
--- a/media/libstagefright/MediaCodecList.cpp
+++ b/media/libstagefright/MediaCodecList.cpp
@@ -77,7 +77,8 @@
     return profilingNeeded;
 }
 
-OmxInfoBuilder sOmxInfoBuilder;
+OmxInfoBuilder sOmxInfoBuilder{true /* allowSurfaceEncoders */};
+OmxInfoBuilder sOmxNoSurfaceEncoderInfoBuilder{false /* allowSurfaceEncoders */};
 
 Mutex sCodec2InfoBuilderMutex;
 std::unique_ptr<MediaCodecListBuilderBase> sCodec2InfoBuilder;
@@ -98,7 +99,11 @@
     sp<PersistentSurface> surfaceTest =
         StagefrightPluginLoader::GetCCodecInstance()->createInputSurface();
     if (surfaceTest == nullptr) {
+        ALOGD("Allowing all OMX codecs");
         builders.push_back(&sOmxInfoBuilder);
+    } else {
+        ALOGD("Allowing only non-surface-encoder OMX codecs");
+        builders.push_back(&sOmxNoSurfaceEncoderInfoBuilder);
     }
     builders.push_back(GetCodec2InfoBuilder());
     return builders;
@@ -215,14 +220,25 @@
             mCodecInfos.begin(),
             mCodecInfos.end(),
             [](const sp<MediaCodecInfo> &info1, const sp<MediaCodecInfo> &info2) {
-                if (info2 == nullptr) {
-                    return false;
-                } else if (info1 == nullptr) {
-                    return true;
-                } else {
-                    return info1->rank() < info2->rank();
-                }
+                // null is lowest
+                return info1 == nullptr
+                        || (info2 != nullptr && info1->getRank() < info2->getRank());
             });
+
+    // remove duplicate entries
+    bool dedupe = property_get_bool("debug.stagefright.dedupe-codecs", true);
+    if (dedupe) {
+        std::set<std::string> codecsSeen;
+        for (auto it = mCodecInfos.begin(); it != mCodecInfos.end(); ) {
+            std::string codecName = (*it)->getCodecName();
+            if (codecsSeen.count(codecName) == 0) {
+                codecsSeen.emplace(codecName);
+                it++;
+            } else {
+                it = mCodecInfos.erase(it);
+            }
+        }
+    }
 }
 
 MediaCodecList::~MediaCodecList() {
@@ -272,10 +288,17 @@
 }
 
 ssize_t MediaCodecList::findCodecByName(const char *name) const {
+    Vector<AString> aliases;
     for (size_t i = 0; i < mCodecInfos.size(); ++i) {
         if (strcmp(mCodecInfos[i]->getCodecName(), name) == 0) {
             return i;
         }
+        mCodecInfos[i]->getAliases(&aliases);
+        for (const AString &alias : aliases) {
+            if (alias == name) {
+                return i;
+            }
+        }
     }
 
     return -ENOENT;
diff --git a/media/libstagefright/MediaCodecListOverrides.cpp b/media/libstagefright/MediaCodecListOverrides.cpp
index cac53f4..dd7c3e6 100644
--- a/media/libstagefright/MediaCodecListOverrides.cpp
+++ b/media/libstagefright/MediaCodecListOverrides.cpp
@@ -228,18 +228,18 @@
             continue;
         }
 
-        Vector<AString> mimes;
-        info->getSupportedMimes(&mimes);
-        for (size_t i = 0; i < mimes.size(); ++i) {
+        Vector<AString> mediaTypes;
+        info->getSupportedMediaTypes(&mediaTypes);
+        for (size_t i = 0; i < mediaTypes.size(); ++i) {
             const sp<MediaCodecInfo::Capabilities> &caps =
-                    info->getCapabilitiesFor(mimes[i].c_str());
+                    info->getCapabilitiesFor(mediaTypes[i].c_str());
             if (!forceToMeasure &&
                 (caps->getDetails()->contains("max-supported-instances") ||
                  caps->getDetails()->contains("max-concurrent-instances"))) {
                 continue;
             }
 
-            size_t max = doProfileCodecs(info->isEncoder(), name, mimes[i], caps);
+            size_t max = doProfileCodecs(info->isEncoder(), name, mediaTypes[i], caps);
             if (max > 0) {
                 CodecSettings settings;
                 char maxStr[32];
@@ -248,7 +248,7 @@
 
                 AString key = name;
                 key.append(" ");
-                key.append(mimes[i]);
+                key.append(mediaTypes[i]);
 
                 if (info->isEncoder()) {
                     encoder_results->add(key, settings);
diff --git a/media/libstagefright/MediaCodecListWriter.cpp b/media/libstagefright/MediaCodecListWriter.cpp
index b32e470..c4fb199 100644
--- a/media/libstagefright/MediaCodecListWriter.cpp
+++ b/media/libstagefright/MediaCodecListWriter.cpp
@@ -37,6 +37,16 @@
             new MediaCodecInfoWriter(info.get()));
 }
 
+std::unique_ptr<MediaCodecInfoWriter>
+        MediaCodecListWriter::findMediaCodecInfo(const char *name) {
+    for (const sp<MediaCodecInfo> &info : mCodecInfos) {
+        if (!strcmp(info->getCodecName(), name)) {
+            return std::unique_ptr<MediaCodecInfoWriter>(new MediaCodecInfoWriter(info.get()));
+        }
+    }
+    return nullptr;
+}
+
 void MediaCodecListWriter::writeGlobalSettings(
         const sp<AMessage> &globalSettings) const {
     for (const std::pair<std::string, std::string> &kv : mGlobalSettings) {
diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp
index 20881a4..50e454c 100644
--- a/media/libstagefright/MediaCodecSource.cpp
+++ b/media/libstagefright/MediaCodecSource.cpp
@@ -32,6 +32,7 @@
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MediaCodec.h>
+#include <media/stagefright/MediaCodecConstants.h>
 #include <media/stagefright/MediaCodecList.h>
 #include <media/stagefright/MediaCodecSource.h>
 #include <media/stagefright/MediaErrors.h>
@@ -362,7 +363,7 @@
 
 status_t MediaCodecSource::setInputBufferTimeOffset(int64_t timeOffsetUs) {
     sp<AMessage> msg = new AMessage(kWhatSetInputBufferTimeOffset, mReflector);
-    msg->setInt64("time-offset-us", timeOffsetUs);
+    msg->setInt64(PARAMETER_KEY_OFFSET_TIME, timeOffsetUs);
     return postSynchronouslyAndReturnError(msg);
 }
 
@@ -372,7 +373,7 @@
     msg->postAndAwaitResponse(&response);
     int64_t timeUs;
     if (!response->findInt64("time-us", &timeUs)) {
-        timeUs = -1ll;
+        timeUs = -1LL;
     }
     return timeUs;
 }
@@ -452,9 +453,9 @@
       mEncoderDataSpace(0),
       mPersistentSurface(persistentSurface),
       mInputBufferTimeOffsetUs(0),
-      mFirstSampleSystemTimeUs(-1ll),
+      mFirstSampleSystemTimeUs(-1LL),
       mPausePending(false),
-      mFirstSampleTimeUs(-1ll),
+      mFirstSampleTimeUs(-1LL),
       mGeneration(0) {
     CHECK(mLooper != NULL);
 
@@ -490,7 +491,7 @@
     mCodecLooper->start();
 
     if (mFlags & FLAG_USE_SURFACE_INPUT) {
-        mOutputFormat->setInt32("create-input-buffers-suspended", 1);
+        mOutputFormat->setInt32(KEY_CREATE_INPUT_SURFACE_SUSPENDED, 1);
     }
 
     AString outputMIME;
@@ -643,6 +644,10 @@
             output->mBufferQueue.clear();
             output->mEncoderReachedEOS = true;
             output->mErrorCode = err;
+            if (!(mFlags & FLAG_USE_SURFACE_INPUT)) {
+                mStopping = true;
+                mPuller->stop();
+            }
             output->mCond.signal();
 
             reachedEOS = true;
@@ -673,9 +678,9 @@
     CHECK(mFlags & FLAG_USE_SURFACE_INPUT);
     if (mEncoder != NULL) {
         sp<AMessage> params = new AMessage;
-        params->setInt32("drop-input-frames", false);
+        params->setInt32(PARAMETER_KEY_SUSPEND, false);
         if (resumeStartTimeUs > 0) {
-            params->setInt64("drop-start-time-us", resumeStartTimeUs);
+            params->setInt64(PARAMETER_KEY_SUSPEND_TIME, resumeStartTimeUs);
         }
         mEncoder->setParameters(params);
     }
@@ -687,13 +692,13 @@
         size_t bufferIndex = *mAvailEncoderInputIndices.begin();
         mAvailEncoderInputIndices.erase(mAvailEncoderInputIndices.begin());
 
-        int64_t timeUs = 0ll;
+        int64_t timeUs = 0LL;
         uint32_t flags = 0;
         size_t size = 0;
 
         if (mbuf != NULL) {
             CHECK(mbuf->meta_data().findInt64(kKeyTime, &timeUs));
-            if (mFirstSampleSystemTimeUs < 0ll) {
+            if (mFirstSampleSystemTimeUs < 0LL) {
                 mFirstSampleSystemTimeUs = systemTime() / 1000;
                 if (mPausePending) {
                     mPausePending = false;
@@ -761,13 +766,13 @@
 }
 
 status_t MediaCodecSource::onStart(MetaData *params) {
-    if (mStopping) {
-        ALOGE("Failed to start while we're stopping");
+    if (mStopping || mOutput.lock()->mEncoderReachedEOS) {
+        ALOGE("Failed to start while we're stopping or encoder already stopped due to EOS error");
         return INVALID_OPERATION;
     }
     int64_t startTimeUs;
     if (params == NULL || !params->findInt64(kKeyTime, &startTimeUs)) {
-        startTimeUs = -1ll;
+        startTimeUs = -1LL;
     }
 
     if (mStarted) {
@@ -795,7 +800,7 @@
     if (mFlags & FLAG_USE_SURFACE_INPUT) {
         if (mEncoder != NULL) {
             sp<AMessage> params = new AMessage;
-            params->setInt32("drop-input-frames", false);
+            params->setInt32(PARAMETER_KEY_SUSPEND, false);
             if (startTimeUs >= 0) {
                 params->setInt64("skip-frames-before", startTimeUs);
             }
@@ -826,10 +831,12 @@
 }
 
 void MediaCodecSource::onPause(int64_t pauseStartTimeUs) {
-    if ((mFlags & FLAG_USE_SURFACE_INPUT) && (mEncoder != NULL)) {
+    if (mStopping || mOutput.lock()->mEncoderReachedEOS) {
+        // Nothing to do
+    } else if ((mFlags & FLAG_USE_SURFACE_INPUT) && (mEncoder != NULL)) {
         sp<AMessage> params = new AMessage;
-        params->setInt32("drop-input-frames", true);
-        params->setInt64("drop-start-time-us", pauseStartTimeUs);
+        params->setInt32(PARAMETER_KEY_SUSPEND, true);
+        params->setInt64(PARAMETER_KEY_SUSPEND_TIME, pauseStartTimeUs);
         mEncoder->setParameters(params);
     } else {
         CHECK(mPuller != NULL);
@@ -914,7 +921,7 @@
                 if (mIsVideo) {
                     int64_t decodingTimeUs;
                     if (mFlags & FLAG_USE_SURFACE_INPUT) {
-                        if (mFirstSampleSystemTimeUs < 0ll) {
+                        if (mFirstSampleSystemTimeUs < 0LL) {
                             mFirstSampleSystemTimeUs = systemTime() / 1000;
                             if (mPausePending) {
                                 mPausePending = false;
@@ -926,7 +933,7 @@
                         // Timestamp offset is already adjusted in GraphicBufferSource.
                         // GraphicBufferSource is supposed to discard samples
                         // queued before start, and offset timeUs by start time
-                        CHECK_GE(timeUs, 0ll);
+                        CHECK_GE(timeUs, 0LL);
                         // TODO:
                         // Decoding time for surface source is unavailable,
                         // use presentation time for now. May need to move
@@ -954,7 +961,7 @@
                 }
                 mbuf->meta_data().setInt64(kKeyTime, timeUs);
             } else {
-                mbuf->meta_data().setInt64(kKeyTime, 0ll);
+                mbuf->meta_data().setInt64(kKeyTime, 0LL);
                 mbuf->meta_data().setInt32(kKeyIsCodecConfig, true);
             }
             if (flags & MediaCodec::BUFFER_FLAG_SYNCFRAME) {
@@ -1081,7 +1088,7 @@
             MetaData *params = static_cast<MetaData *>(obj.get());
             int64_t pauseStartTimeUs = -1;
             if (params == NULL || !params->findInt64(kKeyTime, &pauseStartTimeUs)) {
-                pauseStartTimeUs = -1ll;
+                pauseStartTimeUs = -1LL;
             }
             onPause(pauseStartTimeUs);
         }
@@ -1092,12 +1099,12 @@
         sp<AReplyToken> replyID;
         CHECK(msg->senderAwaitsResponse(&replyID));
         status_t err = OK;
-        CHECK(msg->findInt64("time-offset-us", &mInputBufferTimeOffsetUs));
+        CHECK(msg->findInt64(PARAMETER_KEY_OFFSET_TIME, &mInputBufferTimeOffsetUs));
 
         // Propagate the timestamp offset to GraphicBufferSource.
         if (mFlags & FLAG_USE_SURFACE_INPUT) {
             sp<AMessage> params = new AMessage;
-            params->setInt64("time-offset-us", mInputBufferTimeOffsetUs);
+            params->setInt64(PARAMETER_KEY_OFFSET_TIME, mInputBufferTimeOffsetUs);
             err = mEncoder->setParameters(params);
         }
 
diff --git a/media/libstagefright/MediaExtractor.cpp b/media/libstagefright/MediaExtractor.cpp
new file mode 100644
index 0000000..4ed3382
--- /dev/null
+++ b/media/libstagefright/MediaExtractor.cpp
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "MediaExtractor"
+#include <utils/Log.h>
+#include <pwd.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MediaExtractor.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/Utils.h>
+#include <media/NdkMediaFormatPriv.h>
+#include <media/NdkMediaErrorPriv.h>
+
+namespace android {
+
+MediaExtractor::MediaExtractor() {
+    if (!LOG_NDEBUG) {
+        uid_t uid = getuid();
+        struct passwd *pw = getpwuid(uid);
+        ALOGV("extractor created in uid: %d (%s)", getuid(), pw->pw_name);
+    }
+}
+
+MediaExtractor::~MediaExtractor() {}
+
+uint32_t MediaExtractor::flags() const {
+    return CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_PAUSE | CAN_SEEK;
+}
+
+// --------------------------------------------------------------------------------
+MediaExtractorCUnwrapper::MediaExtractorCUnwrapper(CMediaExtractor *plugin) {
+    this->plugin = plugin;
+}
+
+MediaExtractorCUnwrapper::~MediaExtractorCUnwrapper() {
+    plugin->free(plugin->data);
+    free(plugin);
+}
+
+size_t MediaExtractorCUnwrapper::countTracks() {
+    return plugin->countTracks(plugin->data);
+}
+
+MediaTrack *MediaExtractorCUnwrapper::getTrack(size_t index) {
+    return MediaTrackCUnwrapper::create(plugin->getTrack(plugin->data, index));
+}
+
+status_t MediaExtractorCUnwrapper::getTrackMetaData(
+        MetaDataBase& meta, size_t index, uint32_t flags) {
+    sp<AMessage> msg = new AMessage();
+    AMediaFormat *format =  AMediaFormat_fromMsg(&msg);
+    media_status_t ret = plugin->getTrackMetaData(plugin->data, format, index, flags);
+    sp<MetaData> newMeta = new MetaData();
+    convertMessageToMetaData(msg, newMeta);
+    delete format;
+    meta = *newMeta;
+    return reverse_translate_error(ret);
+}
+
+status_t MediaExtractorCUnwrapper::getMetaData(MetaDataBase& meta) {
+    sp<AMessage> msg = new AMessage();
+    AMediaFormat *format =  AMediaFormat_fromMsg(&msg);
+    media_status_t ret = plugin->getMetaData(plugin->data, format);
+    sp<MetaData> newMeta = new MetaData();
+    convertMessageToMetaData(msg, newMeta);
+    delete format;
+    meta = *newMeta;
+    return reverse_translate_error(ret);
+}
+
+const char * MediaExtractorCUnwrapper::name() {
+    return plugin->name(plugin->data);
+}
+
+uint32_t MediaExtractorCUnwrapper::flags() const {
+    return plugin->flags(plugin->data);
+}
+
+status_t MediaExtractorCUnwrapper::setMediaCas(const uint8_t* casToken, size_t size) {
+    return plugin->setMediaCas(plugin->data, casToken, size);
+}
+
+}  // namespace android
diff --git a/media/libstagefright/MediaExtractorFactory.cpp b/media/libstagefright/MediaExtractorFactory.cpp
index f6c61a0..4c8be1f 100644
--- a/media/libstagefright/MediaExtractorFactory.cpp
+++ b/media/libstagefright/MediaExtractorFactory.cpp
@@ -18,18 +18,21 @@
 #define LOG_TAG "MediaExtractorFactory"
 #include <utils/Log.h>
 
+#include <android/dlext.h>
+#include <android-base/logging.h>
+#include <binder/IPCThreadState.h>
+#include <binder/PermissionCache.h>
 #include <binder/IServiceManager.h>
 #include <media/DataSource.h>
-#include <media/MediaAnalyticsItem.h>
-#include <media/MediaExtractor.h>
-#include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/InterfaceUtils.h>
+#include <media/stagefright/MediaExtractor.h>
 #include <media/stagefright/MediaExtractorFactory.h>
 #include <media/IMediaExtractor.h>
 #include <media/IMediaExtractorService.h>
+#include <nativeloader/dlext_namespaces.h>
+#include <private/android_filesystem_config.h>
 #include <cutils/properties.h>
 #include <utils/String8.h>
-#include <ziparchive/zip_archive.h>
 
 #include <dirent.h>
 #include <dlfcn.h>
@@ -68,49 +71,46 @@
 
     ALOGV("MediaExtractorFactory::CreateFromService %s", mime);
 
-    UpdateExtractors(nullptr);
-
     // initialize source decryption if needed
     source->DrmInitialization(nullptr /* mime */);
 
     void *meta = nullptr;
-    MediaExtractor::CreatorFunc creator = NULL;
-    MediaExtractor::FreeMetaFunc freeMeta = nullptr;
+    void *creator = NULL;
+    FreeMetaFunc freeMeta = nullptr;
     float confidence;
     sp<ExtractorPlugin> plugin;
-    creator = sniff(source.get(), &confidence, &meta, &freeMeta, plugin);
+    uint32_t creatorVersion = 0;
+    creator = sniff(source, &confidence, &meta, &freeMeta, plugin, &creatorVersion);
     if (!creator) {
         ALOGV("FAILED to autodetect media content.");
         return NULL;
     }
 
-    MediaExtractor *ret = creator(source.get(), meta);
-    if (meta != nullptr && freeMeta != nullptr) {
-        freeMeta(meta);
+    MediaExtractor *ex = nullptr;
+    if (creatorVersion == EXTRACTORDEF_VERSION_NDK_V1 ||
+            creatorVersion == EXTRACTORDEF_VERSION_NDK_V2) {
+        CMediaExtractor *ret = ((CreatorFunc)creator)(source->wrap(), meta);
+        if (meta != nullptr && freeMeta != nullptr) {
+            freeMeta(meta);
+        }
+        ex = ret != nullptr ? new MediaExtractorCUnwrapper(ret) : nullptr;
     }
 
     ALOGV("Created an extractor '%s' with confidence %.2f",
-         ret != nullptr ? ret->name() : "<null>", confidence);
+         ex != nullptr ? ex->name() : "<null>", confidence);
 
-    return CreateIMediaExtractorFromMediaExtractor(ret, source, plugin);
-}
-
-//static
-void MediaExtractorFactory::LoadPlugins(const ::std::string& apkPath) {
-    // TODO: Verify apk path with package manager in extractor process.
-    ALOGV("Load plugins from: %s", apkPath.c_str());
-    UpdateExtractors(apkPath.empty() ? nullptr : apkPath.c_str());
+    return CreateIMediaExtractorFromMediaExtractor(ex, source, plugin);
 }
 
 struct ExtractorPlugin : public RefBase {
-    MediaExtractor::ExtractorDef def;
+    ExtractorDef def;
     void *libHandle;
     String8 libPath;
     String8 uuidString;
 
-    ExtractorPlugin(MediaExtractor::ExtractorDef definition, void *handle, String8 &path)
+    ExtractorPlugin(ExtractorDef definition, void *handle, String8 &path)
         : def(definition), libHandle(handle), libPath(path) {
-        for (size_t i = 0; i < sizeof MediaExtractor::ExtractorDef::extractor_uuid; i++) {
+        for (size_t i = 0; i < sizeof ExtractorDef::extractor_uuid; i++) {
             uuidString.appendFormat("%02x", def.extractor_uuid.b[i]);
         }
     }
@@ -123,17 +123,18 @@
 };
 
 Mutex MediaExtractorFactory::gPluginMutex;
-std::shared_ptr<List<sp<ExtractorPlugin>>> MediaExtractorFactory::gPlugins;
+std::shared_ptr<std::list<sp<ExtractorPlugin>>> MediaExtractorFactory::gPlugins;
 bool MediaExtractorFactory::gPluginsRegistered = false;
+bool MediaExtractorFactory::gIgnoreVersion = false;
 
 // static
-MediaExtractor::CreatorFunc MediaExtractorFactory::sniff(
-        DataSourceBase *source, float *confidence, void **meta,
-        MediaExtractor::FreeMetaFunc *freeMeta, sp<ExtractorPlugin> &plugin) {
+void *MediaExtractorFactory::sniff(
+        const sp<DataSource> &source, float *confidence, void **meta,
+        FreeMetaFunc *freeMeta, sp<ExtractorPlugin> &plugin, uint32_t *creatorVersion) {
     *confidence = 0.0f;
     *meta = nullptr;
 
-    std::shared_ptr<List<sp<ExtractorPlugin>>> plugins;
+    std::shared_ptr<std::list<sp<ExtractorPlugin>>> plugins;
     {
         Mutex::Autolock autoLock(gPluginMutex);
         if (!gPluginsRegistered) {
@@ -142,13 +143,23 @@
         plugins = gPlugins;
     }
 
-    MediaExtractor::CreatorFunc curCreator = NULL;
-    MediaExtractor::CreatorFunc bestCreator = NULL;
+    void *bestCreator = NULL;
     for (auto it = plugins->begin(); it != plugins->end(); ++it) {
+        ALOGV("sniffing %s", (*it)->def.extractor_name);
         float newConfidence;
         void *newMeta = nullptr;
-        MediaExtractor::FreeMetaFunc newFreeMeta = nullptr;
-        if ((curCreator = (*it)->def.sniff(source, &newConfidence, &newMeta, &newFreeMeta))) {
+        FreeMetaFunc newFreeMeta = nullptr;
+
+        void *curCreator = NULL;
+        if ((*it)->def.def_version == EXTRACTORDEF_VERSION_NDK_V1) {
+            curCreator = (void*) (*it)->def.u.v2.sniff(
+                    source->wrap(), &newConfidence, &newMeta, &newFreeMeta);
+        } else if ((*it)->def.def_version == EXTRACTORDEF_VERSION_NDK_V2) {
+            curCreator = (void*) (*it)->def.u.v3.sniff(
+                    source->wrap(), &newConfidence, &newMeta, &newFreeMeta);
+        }
+
+        if (curCreator) {
             if (newConfidence > *confidence) {
                 *confidence = newConfidence;
                 if (*meta != nullptr && *freeMeta != nullptr) {
@@ -158,6 +169,7 @@
                 *freeMeta = newFreeMeta;
                 plugin = *it;
                 bestCreator = curCreator;
+                *creatorVersion = (*it)->def.def_version;
             } else {
                 if (newMeta != nullptr && newFreeMeta != nullptr) {
                     newFreeMeta(newMeta);
@@ -171,10 +183,10 @@
 
 // static
 void MediaExtractorFactory::RegisterExtractor(const sp<ExtractorPlugin> &plugin,
-        List<sp<ExtractorPlugin>> &pluginList) {
+        std::list<sp<ExtractorPlugin>> &pluginList) {
     // sanity check check struct version, uuid, name
-    if (plugin->def.def_version == 0
-            || plugin->def.def_version > MediaExtractor::EXTRACTORDEF_VERSION) {
+    if (plugin->def.def_version != EXTRACTORDEF_VERSION_NDK_V1 &&
+            plugin->def.def_version != EXTRACTORDEF_VERSION_NDK_V2) {
         ALOGE("don't understand extractor format %u, ignoring.", plugin->def.def_version);
         return;
     }
@@ -190,7 +202,7 @@
     for (auto it = pluginList.begin(); it != pluginList.end(); ++it) {
         if (memcmp(&((*it)->def.extractor_uuid), &plugin->def.extractor_uuid, 16) == 0) {
             // there's already an extractor with the same uuid
-            if ((*it)->def.extractor_version < plugin->def.extractor_version) {
+            if (gIgnoreVersion || (*it)->def.extractor_version < plugin->def.extractor_version) {
                 // this one is newer, replace the old one
                 ALOGW("replacing extractor '%s' version %u with version %u",
                         plugin->def.extractor_name,
@@ -212,131 +224,154 @@
 }
 
 //static
-void MediaExtractorFactory::RegisterExtractorsInApk(
-        const char *apkPath, List<sp<ExtractorPlugin>> &pluginList) {
-    ALOGV("search for plugins at %s", apkPath);
-    ZipArchiveHandle zipHandle;
-    int32_t ret = OpenArchive(apkPath, &zipHandle);
-    if (ret == 0) {
-        char abi[PROPERTY_VALUE_MAX];
-        property_get("ro.product.cpu.abi", abi, "arm64-v8a");
-        String8 prefix8 = String8::format("lib/%s/", abi);
-        ZipString prefix(prefix8.c_str());
-        ZipString suffix("extractor.so");
-        void* cookie;
-        ret = StartIteration(zipHandle, &cookie, &prefix, &suffix);
-        if (ret == 0) {
-            ZipEntry entry;
-            ZipString name;
-            while (Next(cookie, &entry, &name) == 0) {
-                String8 libPath = String8(apkPath) + "!/" +
-                    String8(reinterpret_cast<const char*>(name.name), name.name_length);
-                // TODO: Open with a linker namespace so that it can be linked with sub-libraries
-                // within the apk instead of system libraries already loaded.
-                void *libHandle = dlopen(libPath.string(), RTLD_NOW | RTLD_LOCAL);
-                if (libHandle) {
-                    MediaExtractor::GetExtractorDef getDef =
-                        (MediaExtractor::GetExtractorDef) dlsym(libHandle, "GETEXTRACTORDEF");
-                    if (getDef) {
-                        ALOGV("registering sniffer for %s", libPath.string());
-                        RegisterExtractor(
-                                new ExtractorPlugin(getDef(), libHandle, libPath), pluginList);
-                    } else {
-                        ALOGW("%s does not contain sniffer", libPath.string());
-                        dlclose(libHandle);
-                    }
-                } else {
-                    ALOGW("couldn't dlopen(%s) %s", libPath.string(), strerror(errno));
-                }
-            }
-            EndIteration(cookie);
-        } else {
-            ALOGW("couldn't find plugins from %s, %d", apkPath, ret);
-        }
-        CloseArchive(zipHandle);
-    } else {
-        ALOGW("couldn't open(%s) %d", apkPath, ret);
-    }
-}
-
-//static
-void MediaExtractorFactory::RegisterExtractorsInSystem(
-        const char *libDirPath, List<sp<ExtractorPlugin>> &pluginList) {
+void MediaExtractorFactory::RegisterExtractors(
+        const char *libDirPath, const android_dlextinfo* dlextinfo,
+        std::list<sp<ExtractorPlugin>> &pluginList) {
     ALOGV("search for plugins at %s", libDirPath);
+
     DIR *libDir = opendir(libDirPath);
     if (libDir) {
         struct dirent* libEntry;
         while ((libEntry = readdir(libDir))) {
-            String8 libPath = String8(libDirPath) + "/" + libEntry->d_name;
-            void *libHandle = dlopen(libPath.string(), RTLD_NOW | RTLD_LOCAL);
-            if (libHandle) {
-                MediaExtractor::GetExtractorDef getDef =
-                    (MediaExtractor::GetExtractorDef) dlsym(libHandle, "GETEXTRACTORDEF");
-                if (getDef) {
-                    ALOGV("registering sniffer for %s", libPath.string());
-                    RegisterExtractor(
-                            new ExtractorPlugin(getDef(), libHandle, libPath), pluginList);
-                } else {
-                    ALOGW("%s does not contain sniffer", libPath.string());
-                    dlclose(libHandle);
-                }
-            } else {
-                ALOGW("couldn't dlopen(%s) %s", libPath.string(), strerror(errno));
+            if (libEntry->d_name[0] == '.') {
+                continue;
             }
-        }
+            String8 libPath = String8(libDirPath) + "/" + libEntry->d_name;
+            if (!libPath.contains("extractor.so")) {
+                continue;
+            }
+            void *libHandle = android_dlopen_ext(
+                    libPath.string(),
+                    RTLD_NOW | RTLD_LOCAL, dlextinfo);
+            CHECK(libHandle != nullptr)
+                    << "couldn't dlopen(" << libPath.string() << ") " << strerror(errno);
 
+            GetExtractorDef getDef =
+                (GetExtractorDef) dlsym(libHandle, "GETEXTRACTORDEF");
+            CHECK(getDef != nullptr)
+                    << libPath.string() << " does not contain sniffer";
+
+            ALOGV("registering sniffer for %s", libPath.string());
+            RegisterExtractor(
+                    new ExtractorPlugin(getDef(), libHandle, libPath), pluginList);
+        }
         closedir(libDir);
     } else {
         ALOGE("couldn't opendir(%s)", libDirPath);
     }
 }
 
+static bool compareFunc(const sp<ExtractorPlugin>& first, const sp<ExtractorPlugin>& second) {
+    return strcmp(first->def.extractor_name, second->def.extractor_name) < 0;
+}
+
+static std::unordered_set<std::string> gSupportedExtensions;
+
 // static
-void MediaExtractorFactory::UpdateExtractors(const char *newUpdateApkPath) {
+void MediaExtractorFactory::LoadExtractors() {
     Mutex::Autolock autoLock(gPluginMutex);
-    if (newUpdateApkPath != nullptr) {
-        gPluginsRegistered = false;
-    }
+
     if (gPluginsRegistered) {
         return;
     }
 
-    std::shared_ptr<List<sp<ExtractorPlugin>>> newList(new List<sp<ExtractorPlugin>>());
+    gIgnoreVersion = property_get_bool("debug.extractor.ignore_version", false);
 
-    RegisterExtractorsInSystem("/system/lib"
+    std::shared_ptr<std::list<sp<ExtractorPlugin>>> newList(new std::list<sp<ExtractorPlugin>>());
+
+    android_namespace_t *mediaNs = android_get_exported_namespace("media");
+    if (mediaNs != NULL) {
+        const android_dlextinfo dlextinfo = {
+            .flags = ANDROID_DLEXT_USE_NAMESPACE,
+            .library_namespace = mediaNs,
+        };
+        RegisterExtractors("/apex/com.android.media/lib"
 #ifdef __LP64__
-            "64"
+                "64"
 #endif
-            "/extractors", *newList);
+                "/extractors", &dlextinfo, *newList);
 
-    RegisterExtractorsInSystem("/vendor/lib"
-#ifdef __LP64__
-            "64"
-#endif
-            "/extractors", *newList);
-
-    if (newUpdateApkPath != nullptr) {
-        RegisterExtractorsInApk(newUpdateApkPath, *newList);
+    } else {
+        ALOGE("couldn't find media namespace.");
     }
 
+    RegisterExtractors("/system/lib"
+#ifdef __LP64__
+            "64"
+#endif
+            "/extractors", NULL, *newList);
+
+    newList->sort(compareFunc);
     gPlugins = newList;
+
+    for (auto it = gPlugins->begin(); it != gPlugins->end(); ++it) {
+        if ((*it)->def.def_version == EXTRACTORDEF_VERSION_NDK_V2) {
+            for (size_t i = 0;; i++) {
+                const char* ext = (*it)->def.u.v3.supported_types[i];
+                if (ext == nullptr) {
+                    break;
+                }
+                gSupportedExtensions.insert(std::string(ext));
+            }
+        }
+    }
+
     gPluginsRegistered = true;
 }
 
+// static
+std::unordered_set<std::string> MediaExtractorFactory::getSupportedTypes() {
+    if (getuid() == AID_MEDIA_EX) {
+        return gSupportedExtensions;
+    }
+    ALOGV("get service manager");
+    sp<IBinder> binder = defaultServiceManager()->getService(String16("media.extractor"));
+
+    if (binder != 0) {
+        sp<IMediaExtractorService> mediaExService(interface_cast<IMediaExtractorService>(binder));
+        return mediaExService->getSupportedTypes();
+    }
+    return std::unordered_set<std::string>();
+}
+
 status_t MediaExtractorFactory::dump(int fd, const Vector<String16>&) {
     Mutex::Autolock autoLock(gPluginMutex);
     String8 out;
-    out.append("Available extractors:\n");
-    if (gPluginsRegistered) {
-        for (auto it = gPlugins->begin(); it != gPlugins->end(); ++it) {
-            out.appendFormat("  %25s: uuid(%s), version(%u), path(%s)\n",
-                    (*it)->def.extractor_name,
-                    (*it)->uuidString.c_str(),
-                    (*it)->def.extractor_version,
-                    (*it)->libPath.c_str());
-        }
+
+    const IPCThreadState* ipc = IPCThreadState::self();
+    const int pid = ipc->getCallingPid();
+    const int uid = ipc->getCallingUid();
+    if (!PermissionCache::checkPermission(String16("android.permission.DUMP"), pid, uid)) {
+        // dumpExtractors() will append the following string.
+        // out.appendFormat("Permission Denial: "
+        //        "can't dump MediaExtractor from pid=%d, uid=%d\n", pid, uid);
+        ALOGE("Permission Denial: can't dump MediaExtractor from pid=%d, uid=%d", pid, uid);
     } else {
-        out.append("  (no plugins registered)\n");
+        out.append("Available extractors:\n");
+        if (gPluginsRegistered) {
+            for (auto it = gPlugins->begin(); it != gPlugins->end(); ++it) {
+                out.appendFormat("  %25s: plugin_version(%d), uuid(%s), version(%u), path(%s)",
+                        (*it)->def.extractor_name,
+                    (*it)->def.def_version,
+                        (*it)->uuidString.c_str(),
+                        (*it)->def.extractor_version,
+                        (*it)->libPath.c_str());
+                if ((*it)->def.def_version == EXTRACTORDEF_VERSION_NDK_V2) {
+                    out.append(", supports: ");
+                    for (size_t i = 0;; i++) {
+                        const char* mime = (*it)->def.u.v3.supported_types[i];
+                        if (mime == nullptr) {
+                            break;
+                        }
+                        out.appendFormat("%s ", mime);
+                    }
+                }
+                out.append("\n");
+            }
+            out.append("\n");
+        } else {
+            out.append("  (no plugins registered)\n");
+        }
     }
     write(fd, out.string(), out.size());
     return OK;
diff --git a/media/libstagefright/MediaMuxer.cpp b/media/libstagefright/MediaMuxer.cpp
index 98f59b5..9ba2add 100644
--- a/media/libstagefright/MediaMuxer.cpp
+++ b/media/libstagefright/MediaMuxer.cpp
@@ -35,6 +35,7 @@
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/MPEG4Writer.h>
+#include <media/stagefright/OggWriter.h>
 #include <media/stagefright/Utils.h>
 
 namespace android {
@@ -52,6 +53,8 @@
         mWriter = new MPEG4Writer(fd);
     } else if (format == OUTPUT_FORMAT_WEBM) {
         mWriter = new WebmWriter(fd);
+    } else if (format == OUTPUT_FORMAT_OGG) {
+        mWriter = new OggWriter(fd);
     }
 
     if (mWriter != NULL) {
@@ -59,6 +62,8 @@
         if (format == OUTPUT_FORMAT_HEIF) {
             // Note that the key uses recorder file types.
             mFileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_HEIF);
+        } else if (format == OUTPUT_FORMAT_OGG) {
+            mFileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_OGG);
         }
         mState = INITIALIZED;
     }
diff --git a/media/libmediaextractor/MediaSource.cpp b/media/libstagefright/MediaSource.cpp
similarity index 100%
rename from media/libmediaextractor/MediaSource.cpp
rename to media/libstagefright/MediaSource.cpp
diff --git a/media/libstagefright/MediaSync.cpp b/media/libstagefright/MediaSync.cpp
index ba14e5d..a3f55da 100644
--- a/media/libstagefright/MediaSync.cpp
+++ b/media/libstagefright/MediaSync.cpp
@@ -36,7 +36,7 @@
 
 // Maximum late time allowed for a video frame to be rendered. When a video
 // frame arrives later than this number, it will be discarded without rendering.
-static const int64_t kMaxAllowedVideoLateTimeUs = 40000ll;
+static const int64_t kMaxAllowedVideoLateTimeUs = 40000LL;
 
 namespace android {
 
diff --git a/media/libstagefright/MediaTrack.cpp b/media/libstagefright/MediaTrack.cpp
new file mode 100644
index 0000000..89c9b25
--- /dev/null
+++ b/media/libstagefright/MediaTrack.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <mutex>
+
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/Utils.h>
+
+#include <media/MediaTrack.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/NdkMediaErrorPriv.h>
+#include <media/NdkMediaFormatPriv.h>
+
+namespace android {
+
+MediaTrack::MediaTrack() {}
+
+MediaTrack::~MediaTrack() {}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void MediaTrack::ReadOptions::setNonBlocking() {
+    mNonBlocking = true;
+}
+
+void MediaTrack::ReadOptions::clearNonBlocking() {
+    mNonBlocking = false;
+}
+
+bool MediaTrack::ReadOptions::getNonBlocking() const {
+    return mNonBlocking;
+}
+
+void MediaTrack::ReadOptions::setSeekTo(int64_t time_us, SeekMode mode) {
+    mOptions |= kSeekTo_Option;
+    mSeekTimeUs = time_us;
+    mSeekMode = mode;
+}
+
+bool MediaTrack::ReadOptions::getSeekTo(
+        int64_t *time_us, SeekMode *mode) const {
+    *time_us = mSeekTimeUs;
+    *mode = mSeekMode;
+    return (mOptions & kSeekTo_Option) != 0;
+}
+
+/* -------------- unwrapper --------------- */
+
+MediaTrackCUnwrapper::MediaTrackCUnwrapper(CMediaTrack *cmediatrack) {
+    wrapper = cmediatrack;
+    bufferGroup = nullptr;
+}
+
+MediaTrackCUnwrapper *MediaTrackCUnwrapper::create(CMediaTrack *cmediatrack) {
+    if (cmediatrack == nullptr) {
+        return nullptr;
+    }
+    return new MediaTrackCUnwrapper(cmediatrack);
+}
+
+MediaTrackCUnwrapper::~MediaTrackCUnwrapper() {
+    wrapper->free(wrapper->data);
+    free(wrapper);
+    delete bufferGroup;
+}
+
+status_t MediaTrackCUnwrapper::start() {
+    if (bufferGroup == nullptr) {
+        bufferGroup = new MediaBufferGroup();
+    }
+    return reverse_translate_error(wrapper->start(wrapper->data, bufferGroup->wrap()));
+}
+
+status_t MediaTrackCUnwrapper::stop() {
+    return reverse_translate_error(wrapper->stop(wrapper->data));
+}
+
+status_t MediaTrackCUnwrapper::getFormat(MetaDataBase& format) {
+    sp<AMessage> msg = new AMessage();
+    AMediaFormat *tmpFormat =  AMediaFormat_fromMsg(&msg);
+    media_status_t ret = wrapper->getFormat(wrapper->data, tmpFormat);
+    sp<MetaData> newMeta = new MetaData();
+    convertMessageToMetaData(msg, newMeta);
+    delete tmpFormat;
+    format = *newMeta;
+    return reverse_translate_error(ret);
+}
+
+status_t MediaTrackCUnwrapper::read(MediaBufferBase **buffer, const ReadOptions *options) {
+
+    uint32_t opts = 0;
+
+    if (options && options->getNonBlocking()) {
+        opts |= CMediaTrackReadOptions::NONBLOCKING;
+    }
+
+    int64_t seekPosition = 0;
+    MediaTrack::ReadOptions::SeekMode seekMode;
+    if (options && options->getSeekTo(&seekPosition, &seekMode)) {
+        opts |= SEEK;
+        opts |= (uint32_t) seekMode;
+    }
+    CMediaBuffer *buf = nullptr;
+    media_status_t ret = wrapper->read(wrapper->data, &buf, opts, seekPosition);
+    if (ret == AMEDIA_OK && buf != nullptr) {
+        *buffer = (MediaBufferBase*)buf->handle;
+        MetaDataBase &meta = (*buffer)->meta_data();
+        AMediaFormat *format = buf->meta_data(buf->handle);
+        // only convert the keys we're actually expecting, as doing
+        // the full convertMessageToMetadata() for every buffer is
+        // too expensive
+        int64_t val64;
+        if (format->mFormat->findInt64("timeUs", &val64)) {
+            meta.setInt64(kKeyTime, val64);
+        }
+        if (format->mFormat->findInt64("durationUs", &val64)) {
+            meta.setInt64(kKeyDuration, val64);
+        }
+        if (format->mFormat->findInt64("target-time", &val64)) {
+            meta.setInt64(kKeyTargetTime, val64);
+        }
+        int32_t val32;
+        if (format->mFormat->findInt32("is-sync-frame", &val32)) {
+            meta.setInt32(kKeyIsSyncFrame, val32);
+        }
+        if (format->mFormat->findInt32("temporal-layer-id", &val32)) {
+            meta.setInt32(kKeyTemporalLayerId, val32);
+        }
+        if (format->mFormat->findInt32("temporal-layer-count", &val32)) {
+            meta.setInt32(kKeyTemporalLayerCount, val32);
+        }
+        if (format->mFormat->findInt32("crypto-default-iv-size", &val32)) {
+            meta.setInt32(kKeyCryptoDefaultIVSize, val32);
+        }
+        if (format->mFormat->findInt32("crypto-mode", &val32)) {
+            meta.setInt32(kKeyCryptoMode, val32);
+        }
+        if (format->mFormat->findInt32("crypto-encrypted-byte-block", &val32)) {
+            meta.setInt32(kKeyEncryptedByteBlock, val32);
+        }
+        if (format->mFormat->findInt32("crypto-skip-byte-block", &val32)) {
+            meta.setInt32(kKeySkipByteBlock, val32);
+        }
+        if (format->mFormat->findInt32("valid-samples", &val32)) {
+            meta.setInt32(kKeyValidSamples, val32);
+        }
+        sp<ABuffer> valbuf;
+        if (format->mFormat->findBuffer("crypto-plain-sizes", &valbuf)) {
+            meta.setData(kKeyPlainSizes,
+                    MetaDataBase::Type::TYPE_NONE, valbuf->data(), valbuf->size());
+        }
+        if (format->mFormat->findBuffer("crypto-encrypted-sizes", &valbuf)) {
+            meta.setData(kKeyEncryptedSizes,
+                    MetaDataBase::Type::TYPE_NONE, valbuf->data(), valbuf->size());
+        }
+        if (format->mFormat->findBuffer("crypto-key", &valbuf)) {
+            meta.setData(kKeyCryptoKey,
+                    MetaDataBase::Type::TYPE_NONE, valbuf->data(), valbuf->size());
+        }
+        if (format->mFormat->findBuffer("crypto-iv", &valbuf)) {
+            meta.setData(kKeyCryptoIV,
+                    MetaDataBase::Type::TYPE_NONE, valbuf->data(), valbuf->size());
+        }
+        if (format->mFormat->findBuffer("sei", &valbuf)) {
+            meta.setData(kKeySEI,
+                    MetaDataBase::Type::TYPE_NONE, valbuf->data(), valbuf->size());
+        }
+        if (format->mFormat->findBuffer("audio-presentation-info", &valbuf)) {
+            meta.setData(kKeyAudioPresentationInfo,
+                    MetaDataBase::Type::TYPE_NONE, valbuf->data(), valbuf->size());
+        }
+    } else {
+        *buffer = nullptr;
+    }
+
+    return reverse_translate_error(ret);
+}
+
+bool MediaTrackCUnwrapper::supportNonblockingRead() {
+    return wrapper->supportsNonBlockingRead(wrapper->data);
+}
+
+}  // namespace android
diff --git a/media/libstagefright/MetaDataUtils.cpp b/media/libstagefright/MetaDataUtils.cpp
index 04f6ade..3f0bc7d 100644
--- a/media/libstagefright/MetaDataUtils.cpp
+++ b/media/libstagefright/MetaDataUtils.cpp
@@ -16,15 +16,25 @@
 
 //#define LOG_NDEBUG 0
 #define LOG_TAG "MetaDataUtils"
+#include <utils/Log.h>
 
 #include <media/stagefright/foundation/avc_utils.h>
+#include <media/stagefright/foundation/base64.h>
+#include <media/stagefright/foundation/ABitReader.h>
 #include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ByteUtils.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MetaDataUtils.h>
+#include <media/stagefright/Utils.h>
+#include <media/NdkMediaFormat.h>
 
 namespace android {
 
 bool MakeAVCCodecSpecificData(MetaDataBase &meta, const uint8_t *data, size_t size) {
+    if (data == nullptr || size == 0) {
+        return false;
+    }
+
     int32_t width;
     int32_t height;
     int32_t sarWidth;
@@ -46,21 +56,86 @@
     return true;
 }
 
+bool MakeAVCCodecSpecificData(AMediaFormat *meta, const uint8_t *data, size_t size) {
+    if (meta == nullptr || data == nullptr || size == 0) {
+        return false;
+    }
+
+    int32_t width;
+    int32_t height;
+    int32_t sarWidth;
+    int32_t sarHeight;
+    sp<ABuffer> accessUnit = new ABuffer((void*)data,  size);
+    sp<ABuffer> csd = MakeAVCCodecSpecificData(accessUnit, &width, &height, &sarWidth, &sarHeight);
+    if (csd == nullptr) {
+        return false;
+    }
+    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_AVC);
+
+    AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CSD_AVC, csd->data(), csd->size());
+    AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_WIDTH, width);
+    AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_HEIGHT, height);
+    if (sarWidth > 0 && sarHeight > 0) {
+        AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_SAR_WIDTH, sarWidth);
+        AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_SAR_HEIGHT, sarHeight);
+    }
+    return true;
+}
+
+bool MakeAACCodecSpecificData(MetaDataBase &meta, const uint8_t *data, size_t size) {
+    if (data == nullptr || size < 7) {
+        return false;
+    }
+
+    ABitReader bits(data, size);
+
+    // adts_fixed_header
+
+    if (bits.getBits(12) != 0xfffu) {
+        ALOGE("Wrong atds_fixed_header");
+        return false;
+    }
+
+    bits.skipBits(4);  // ID, layer, protection_absent
+
+    unsigned profile = bits.getBits(2);
+    if (profile == 3u) {
+        ALOGE("profile should not be 3");
+        return false;
+    }
+    unsigned sampling_freq_index = bits.getBits(4);
+    bits.getBits(1);  // private_bit
+    unsigned channel_configuration = bits.getBits(3);
+    if (channel_configuration == 0u) {
+        ALOGE("channel_config should not be 0");
+        return false;
+    }
+
+    if (!MakeAACCodecSpecificData(
+            meta, profile, sampling_freq_index, channel_configuration)) {
+        return false;
+    }
+
+    meta.setInt32(kKeyIsADTS, true);
+    return true;
+}
+
 bool MakeAACCodecSpecificData(
-        MetaDataBase &meta,
-        unsigned profile, unsigned sampling_freq_index,
-        unsigned channel_configuration) {
+        uint8_t *csd, /* out */
+        size_t *esds_size, /* in/out */
+        unsigned profile, /* in */
+        unsigned sampling_freq_index, /* in */
+        unsigned channel_configuration, /* in */
+        int32_t *sampling_rate /* out */
+) {
     if(sampling_freq_index > 11u) {
         return false;
     }
-    int32_t sampleRate;
-    int32_t channelCount;
     static const int32_t kSamplingFreq[] = {
         96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
         16000, 12000, 11025, 8000
     };
-    sampleRate = kSamplingFreq[sampling_freq_index];
-    channelCount = channel_configuration;
+    *sampling_rate = kSamplingFreq[sampling_freq_index];
 
     static const uint8_t kStaticESDS[] = {
         0x03, 22,
@@ -83,7 +158,9 @@
     };
 
     size_t csdSize = sizeof(kStaticESDS) + 2;
-    uint8_t *csd = new uint8_t[csdSize];
+    if (csdSize > *esds_size) {
+        return false;
+    }
     memcpy(csd, kStaticESDS, sizeof(kStaticESDS));
 
     csd[sizeof(kStaticESDS)] =
@@ -92,14 +169,197 @@
     csd[sizeof(kStaticESDS) + 1] =
         ((sampling_freq_index << 7) & 0x80) | (channel_configuration << 3);
 
+    *esds_size = csdSize;
+    return true;
+}
+
+bool MakeAACCodecSpecificData(AMediaFormat *meta, unsigned profile, unsigned sampling_freq_index,
+        unsigned channel_configuration) {
+
+    if(sampling_freq_index > 11u) {
+        return false;
+    }
+
+    uint8_t csd[2];
+    csd[0] = ((profile + 1) << 3) | (sampling_freq_index >> 1);
+    csd[1] = ((sampling_freq_index << 7) & 0x80) | (channel_configuration << 3);
+
+    static const int32_t kSamplingFreq[] = {
+        96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
+        16000, 12000, 11025, 8000
+    };
+    int32_t sampleRate = kSamplingFreq[sampling_freq_index];
+
+    AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CSD_0, csd, sizeof(csd));
+    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_AAC);
+    AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, sampleRate);
+    AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, channel_configuration);
+
+    return true;
+}
+
+bool MakeAACCodecSpecificData(
+        MetaDataBase &meta,
+        unsigned profile, unsigned sampling_freq_index,
+        unsigned channel_configuration) {
+
+    uint8_t csd[24];
+    size_t csdSize = sizeof(csd);
+    int32_t sampleRate;
+
+    if (!MakeAACCodecSpecificData(csd, &csdSize, profile, sampling_freq_index,
+            channel_configuration, &sampleRate)) {
+        return false;
+    }
+
     meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
 
     meta.setInt32(kKeySampleRate, sampleRate);
-    meta.setInt32(kKeyChannelCount, channelCount);
-
+    meta.setInt32(kKeyChannelCount, channel_configuration);
     meta.setData(kKeyESDS, 0, csd, csdSize);
-    delete [] csd;
     return true;
 }
 
+
+static void extractAlbumArt(
+        AMediaFormat *fileMeta, const void *data, size_t size) {
+    ALOGV("extractAlbumArt from '%s'", (const char *)data);
+
+    size_t inLen = strnlen((const char *)data, size);
+    size_t flacSize = inLen / 4 * 3;
+    uint8_t *flac = new uint8_t[flacSize];
+    if (!decodeBase64(flac, &flacSize, (const char*)data)) {
+        ALOGE("malformed base64 encoded data.");
+        delete[] flac;
+        return;
+    }
+
+    ALOGV("got flac of size %zu", flacSize);
+
+    uint32_t picType;
+    uint32_t typeLen;
+    uint32_t descLen;
+    uint32_t dataLen;
+    char type[128];
+
+    if (flacSize < 8) {
+        delete[] flac;
+        return;
+    }
+
+    picType = U32_AT(flac);
+
+    if (picType != 3) {
+        // This is not a front cover.
+        delete[] flac;
+        return;
+    }
+
+    typeLen = U32_AT(&flac[4]);
+    if (typeLen > sizeof(type) - 1) {
+        delete[] flac;
+        return;
+    }
+
+    // we've already checked above that flacSize >= 8
+    if (flacSize - 8 < typeLen) {
+        delete[] flac;
+        return;
+    }
+
+    memcpy(type, &flac[8], typeLen);
+    type[typeLen] = '\0';
+
+    ALOGV("picType = %d, type = '%s'", picType, type);
+
+    if (!strcmp(type, "-->")) {
+        // This is not inline cover art, but an external url instead.
+        delete[] flac;
+        return;
+    }
+
+    if (flacSize < 32 || flacSize - 32 < typeLen) {
+        delete[] flac;
+        return;
+    }
+
+    descLen = U32_AT(&flac[8 + typeLen]);
+    if (flacSize - 32 - typeLen < descLen) {
+        delete[] flac;
+        return;
+    }
+
+    dataLen = U32_AT(&flac[8 + typeLen + 4 + descLen + 16]);
+
+    // we've already checked above that (flacSize - 32 - typeLen - descLen) >= 0
+    if (flacSize - 32 - typeLen - descLen < dataLen) {
+        delete[] flac;
+        return;
+    }
+
+    ALOGV("got image data, %zu trailing bytes",
+         flacSize - 32 - typeLen - descLen - dataLen);
+
+    AMediaFormat_setBuffer(fileMeta, AMEDIAFORMAT_KEY_ALBUMART,
+            &flac[8 + typeLen + 4 + descLen + 20], dataLen);
+
+    delete[] flac;
+}
+
+void parseVorbisComment(
+        AMediaFormat *fileMeta, const char *comment, size_t commentLength) {
+    // Haptic tag is only kept here as it will only be used in extractor to generate channel mask.
+    struct {
+        const char *const mTag;
+        const char *mKey;
+    } kMap[] = {
+        { "TITLE", AMEDIAFORMAT_KEY_TITLE },
+        { "ARTIST", AMEDIAFORMAT_KEY_ARTIST },
+        { "ALBUMARTIST", AMEDIAFORMAT_KEY_ALBUMARTIST },
+        { "ALBUM ARTIST", AMEDIAFORMAT_KEY_ALBUMARTIST },
+        { "COMPILATION", AMEDIAFORMAT_KEY_COMPILATION },
+        { "ALBUM", AMEDIAFORMAT_KEY_ALBUM },
+        { "COMPOSER", AMEDIAFORMAT_KEY_COMPOSER },
+        { "GENRE", AMEDIAFORMAT_KEY_GENRE },
+        { "AUTHOR", AMEDIAFORMAT_KEY_AUTHOR },
+        { "TRACKNUMBER", AMEDIAFORMAT_KEY_CDTRACKNUMBER },
+        { "DISCNUMBER", AMEDIAFORMAT_KEY_DISCNUMBER },
+        { "DATE", AMEDIAFORMAT_KEY_DATE },
+        { "YEAR", AMEDIAFORMAT_KEY_YEAR },
+        { "LYRICIST", AMEDIAFORMAT_KEY_LYRICIST },
+        { "METADATA_BLOCK_PICTURE", AMEDIAFORMAT_KEY_ALBUMART },
+        { "ANDROID_LOOP", AMEDIAFORMAT_KEY_LOOP },
+        { "ANDROID_HAPTIC", AMEDIAFORMAT_KEY_HAPTIC_CHANNEL_COUNT },
+    };
+
+        for (size_t j = 0; j < sizeof(kMap) / sizeof(kMap[0]); ++j) {
+            size_t tagLen = strlen(kMap[j].mTag);
+            if (!strncasecmp(kMap[j].mTag, comment, tagLen)
+                    && comment[tagLen] == '=') {
+                if (kMap[j].mKey == AMEDIAFORMAT_KEY_ALBUMART) {
+                    extractAlbumArt(
+                            fileMeta,
+                            &comment[tagLen + 1],
+                            commentLength - tagLen - 1);
+                } else if (kMap[j].mKey == AMEDIAFORMAT_KEY_LOOP) {
+                    if (!strcasecmp(&comment[tagLen + 1], "true")) {
+                        AMediaFormat_setInt32(fileMeta, AMEDIAFORMAT_KEY_LOOP, 1);
+                    }
+                } else if (kMap[j].mKey == AMEDIAFORMAT_KEY_HAPTIC_CHANNEL_COUNT) {
+                    char *end;
+                    errno = 0;
+                    const int hapticChannelCount = strtol(&comment[tagLen + 1], &end, 10);
+                    if (errno == 0) {
+                        AMediaFormat_setInt32(fileMeta, kMap[j].mKey, hapticChannelCount);
+                    } else {
+                        ALOGE("Error(%d) when parsing haptic channel count", errno);
+                    }
+                } else {
+                    AMediaFormat_setString(fileMeta, kMap[j].mKey, &comment[tagLen + 1]);
+                }
+            }
+        }
+
+}
+
 }  // namespace android
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index 18f4b12..522c81d 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -256,6 +256,10 @@
     return ERROR_UNSUPPORTED;
 }
 
+void NuCachedSource2::close() {
+    disconnect();
+}
+
 void NuCachedSource2::disconnect() {
     if (mSource->flags() & kIsHTTPBasedSource) {
         ALOGV("disconnecting HTTPBasedSource");
@@ -436,12 +440,12 @@
     if (mFetching) {
         if (mFinalStatus != OK && mNumRetriesLeft > 0) {
             // We failed this time and will try again in 3 seconds.
-            delayUs = 3000000ll;
+            delayUs = 3000000LL;
         } else {
             delayUs = 0;
         }
     } else {
-        delayUs = 100000ll;
+        delayUs = 100000LL;
     }
 
     (new AMessage(kWhatFetchMore, mReflector))->post(delayUs);
@@ -567,12 +571,19 @@
     return mCacheOffset + mCache->totalSize();
 }
 
-size_t NuCachedSource2::approxDataRemaining(status_t *finalStatus) const {
+status_t NuCachedSource2::getAvailableSize(off64_t offset, off64_t *size) {
     Mutex::Autolock autoLock(mLock);
-    return approxDataRemaining_l(finalStatus);
+    status_t finalStatus = UNKNOWN_ERROR;
+    *size = approxDataRemaining_l(offset, &finalStatus);
+    return finalStatus;
 }
 
-size_t NuCachedSource2::approxDataRemaining_l(status_t *finalStatus) const {
+size_t NuCachedSource2::approxDataRemaining(status_t *finalStatus) const {
+    Mutex::Autolock autoLock(mLock);
+    return approxDataRemaining_l(mLastAccessPos, finalStatus);
+}
+
+size_t NuCachedSource2::approxDataRemaining_l(off64_t offset, status_t *finalStatus) const {
     *finalStatus = mFinalStatus;
 
     if (mFinalStatus != OK && mNumRetriesLeft > 0) {
@@ -580,9 +591,10 @@
         *finalStatus = OK;
     }
 
+    offset = offset >= 0 ? offset : mLastAccessPos;
     off64_t lastBytePosCached = mCacheOffset + mCache->totalSize();
-    if (mLastAccessPos < lastBytePosCached) {
-        return lastBytePosCached - mLastAccessPos;
+    if (offset < lastBytePosCached) {
+        return lastBytePosCached - offset;
     }
     return 0;
 }
@@ -728,7 +740,7 @@
     }
 
     if (keepAliveSecs >= 0) {
-        mKeepAliveIntervalUs = keepAliveSecs * 1000000ll;
+        mKeepAliveIntervalUs = keepAliveSecs * 1000000LL;
     } else {
         mKeepAliveIntervalUs = kDefaultKeepAliveIntervalUs;
     }
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index 4a7d6ca..680d426 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -21,10 +21,8 @@
 #include <media/stagefright/NuMediaExtractor.h>
 
 #include "include/ESDS.h"
-#include "include/NuCachedSource2.h"
 
 #include <media/DataSource.h>
-#include <media/MediaExtractor.h>
 #include <media/MediaSource.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
@@ -34,6 +32,7 @@
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MediaExtractor.h>
 #include <media/stagefright/MediaExtractorFactory.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/Utils.h>
@@ -42,7 +41,7 @@
 
 NuMediaExtractor::Sample::Sample()
     : mBuffer(NULL),
-      mSampleTimeUs(-1ll) {
+      mSampleTimeUs(-1LL) {
 }
 
 NuMediaExtractor::Sample::Sample(MediaBufferBase *buffer, int64_t timeUs)
@@ -51,8 +50,8 @@
 }
 
 NuMediaExtractor::NuMediaExtractor()
-    : mTotalBitrate(-1ll),
-      mDurationUs(-1ll) {
+    : mTotalBitrate(-1LL),
+      mDurationUs(-1LL) {
 }
 
 NuMediaExtractor::~NuMediaExtractor() {
@@ -205,22 +204,13 @@
     return OK;
 }
 
-void NuMediaExtractor::disconnect() {
-    if (mDataSource != NULL) {
-        // disconnect data source
-        if (mDataSource->flags() & DataSource::kIsCachingDataSource) {
-            static_cast<NuCachedSource2 *>(mDataSource.get())->disconnect();
-        }
-    }
-}
-
 status_t NuMediaExtractor::updateDurationAndBitrate() {
     if (mImpl->countTracks() > kMaxTrackCount) {
         return ERROR_UNSUPPORTED;
     }
 
-    mTotalBitrate = 0ll;
-    mDurationUs = -1ll;
+    mTotalBitrate = 0LL;
+    mDurationUs = -1LL;
 
     for (size_t i = 0; i < mImpl->countTracks(); ++i) {
         sp<MetaData> meta = mImpl->getTrackMetaData(i);
@@ -235,8 +225,8 @@
             CHECK(meta->findCString(kKeyMIMEType, &mime));
             ALOGV("track of type '%s' does not publish bitrate", mime);
 
-            mTotalBitrate = -1ll;
-        } else if (mTotalBitrate >= 0ll) {
+            mTotalBitrate = -1LL;
+        } else if (mTotalBitrate >= 0LL) {
             mTotalBitrate += bitrate;
         }
 
@@ -440,18 +430,6 @@
     return OK;
 }
 
-void NuMediaExtractor::releaseOneSample(TrackInfo *info) {
-    if (info == NULL || info->mSamples.empty()) {
-        return;
-    }
-
-    auto it = info->mSamples.begin();
-    if (it->mBuffer != NULL) {
-        it->mBuffer->release();
-    }
-    info->mSamples.erase(it);
-}
-
 void NuMediaExtractor::releaseTrackSamples(TrackInfo *info) {
     if (info == NULL) {
         return;
@@ -482,7 +460,7 @@
         fetchTrackSamples(info, seekTimeUs, mode);
 
         status_t err = info->mFinalResult;
-        if (err != OK && err != ERROR_END_OF_STREAM) {
+        if (err != OK && err != ERROR_END_OF_STREAM && info->mSamples.empty()) {
             return err;
         }
 
@@ -513,7 +491,7 @@
     }
 
     MediaSource::ReadOptions options;
-    if (seekTimeUs >= 0ll) {
+    if (seekTimeUs >= 0LL) {
         options.setSeekTo(seekTimeUs, mode);
         info->mFinalResult = OK;
         releaseTrackSamples(info);
@@ -537,14 +515,6 @@
     info->mFinalResult = err;
     if (err != OK && err != ERROR_END_OF_STREAM) {
         ALOGW("read on track %zu failed with error %d", info->mTrackIndex, err);
-        size_t count = mediaBuffers.size();
-        for (size_t id = 0; id < count; ++id) {
-            MediaBufferBase *mbuf = mediaBuffers[id];
-            if (mbuf != NULL) {
-                mbuf->release();
-            }
-        }
-        return;
     }
 
     size_t count = mediaBuffers.size();
@@ -594,8 +564,26 @@
 
     TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
 
-    releaseOneSample(info);
+    if (info == NULL || info->mSamples.empty()) {
+        return ERROR_END_OF_STREAM;
+    }
 
+    auto it = info->mSamples.begin();
+    if (it->mBuffer != NULL) {
+        it->mBuffer->release();
+    }
+    info->mSamples.erase(it);
+
+    if (info->mSamples.empty()) {
+        minIndex = fetchAllTrackSamples();
+        if (minIndex < 0) {
+            return ERROR_END_OF_STREAM;
+        }
+        info = &mSelectedTracks.editItemAt(minIndex);
+        if (info == NULL || info->mSamples.empty()) {
+            return ERROR_END_OF_STREAM;
+        }
+    }
     return OK;
 }
 
@@ -766,6 +754,9 @@
 }
 
 status_t NuMediaExtractor::getMetrics(Parcel *reply) {
+    if (mImpl == NULL) {
+        return -EINVAL;
+    }
     status_t status = mImpl->getMetrics(reply);
     return status;
 }
@@ -778,7 +769,7 @@
 
     off64_t size;
     if (mDurationUs > 0 && mDataSource->getSize(&size) == OK) {
-        *bitrate = size * 8000000ll / mDurationUs;  // in bits/sec
+        *bitrate = size * 8000000LL / mDurationUs;  // in bits/sec
         return true;
     }
 
@@ -790,16 +781,12 @@
         int64_t *durationUs, bool *eos) const {
     Mutex::Autolock autoLock(mLock);
 
+    off64_t cachedDataRemaining = -1;
+    status_t finalStatus = mDataSource->getAvailableSize(-1, &cachedDataRemaining);
+
     int64_t bitrate;
-    if ((mDataSource->flags() & DataSource::kIsCachingDataSource)
+    if (cachedDataRemaining >= 0
             && getTotalBitrate(&bitrate)) {
-        sp<NuCachedSource2> cachedSource =
-            static_cast<NuCachedSource2 *>(mDataSource.get());
-
-        status_t finalStatus;
-        size_t cachedDataRemaining =
-            cachedSource->approxDataRemaining(&finalStatus);
-
         *durationUs = cachedDataRemaining * 8000000ll / bitrate;
         *eos = (finalStatus != OK);
         return true;
@@ -808,4 +795,36 @@
     return false;
 }
 
+// Return OK if we have received an audio presentation info.
+// Return ERROR_END_OF_STREAM if no tracks are available.
+// Return ERROR_UNSUPPORTED if the track has no audio presentation.
+// Return INVALID_OPERATION if audio presentation metadata version does not match.
+status_t NuMediaExtractor::getAudioPresentations(
+        size_t trackIndex, AudioPresentationCollection *presentations) {
+    Mutex::Autolock autoLock(mLock);
+    ssize_t minIndex = fetchAllTrackSamples();
+    if (minIndex < 0) {
+        return ERROR_END_OF_STREAM;
+    }
+    for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
+        TrackInfo *info = &mSelectedTracks.editItemAt(i);
+
+        if (info->mTrackIndex == trackIndex) {
+            sp<MetaData> meta = new MetaData(info->mSamples.begin()->mBuffer->meta_data());
+
+            uint32_t type;
+            const void *data;
+            size_t size;
+            if (meta != NULL && meta->findData(kKeyAudioPresentationInfo, &type, &data, &size)) {
+                std::istringstream inStream(std::string(static_cast<const char*>(data), size));
+                return deserializeAudioPresentations(&inStream, presentations);
+            }
+            ALOGV("Track %zu does not contain any audio presentation", trackIndex);
+            return ERROR_UNSUPPORTED;
+        }
+    }
+    ALOGV("Source does not contain any audio presentation");
+    return ERROR_UNSUPPORTED;
+}
+
 }  // namespace android
diff --git a/media/libstagefright/OggWriter.cpp b/media/libstagefright/OggWriter.cpp
new file mode 100644
index 0000000..b738fef
--- /dev/null
+++ b/media/libstagefright/OggWriter.cpp
@@ -0,0 +1,429 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "OggWriter"
+
+#include <fcntl.h>
+#include <inttypes.h>
+#include <sys/prctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <media/MediaSource.h>
+#include <media/mediarecorder.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/OggWriter.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/OpusHeader.h>
+
+extern "C" {
+#include <ogg/ogg.h>
+}
+
+// store the int32 value in little-endian order.
+static inline void writeint(char *buf, int base, int32_t val) {
+    buf[base + 3] = ((val) >> 24) & 0xff;
+    buf[base + 2] = ((val) >> 16) & 0xff;
+    buf[base + 1] = ((val) >> 8) & 0xff;
+    buf[base] = (val)&0xff;
+}
+
+// linkage between our header OggStreamState and the underlying ogg_stream_state
+// so that consumers of our interface do not require the ogg headers themselves.
+struct OggStreamState : public ogg_stream_state {};
+
+namespace android {
+
+OggWriter::OggWriter(int fd)
+      : mFd(dup(fd)),
+        mHaveAllCodecSpecificData(false),
+        mInitCheck(mFd < 0 ? NO_INIT : OK) {
+    // empty
+}
+
+OggWriter::~OggWriter() {
+    if (mStarted) {
+        reset();
+    }
+
+    if (mFd != -1) {
+        close(mFd);
+        mFd = -1;
+    }
+
+    free(mOs);
+}
+
+status_t OggWriter::initCheck() const {
+    return mInitCheck;
+}
+
+status_t OggWriter::addSource(const sp<MediaSource>& source) {
+    if (mInitCheck != OK) {
+        return mInitCheck;
+    }
+
+    if (mSource != NULL) {
+        return UNKNOWN_ERROR;
+    }
+
+    // Support is limited to single track of Opus audio.
+    const char* mime;
+    source->getFormat()->findCString(kKeyMIMEType, &mime);
+    const char* opus = MEDIA_MIMETYPE_AUDIO_OPUS;
+    if (strncasecmp(mime, opus, strlen(opus))) {
+        ALOGE("Track (%s) other than %s is not supported", mime, opus);
+        return ERROR_UNSUPPORTED;
+    }
+
+    mOs = (OggStreamState*) malloc(sizeof(ogg_stream_state));
+    if (ogg_stream_init((ogg_stream_state*)mOs, rand()) == -1) {
+        ALOGE("ogg stream init failed");
+        return UNKNOWN_ERROR;
+    }
+
+    // Write Ogg headers.
+    int32_t nChannels = 0;
+    if (!source->getFormat()->findInt32(kKeyChannelCount, &nChannels)) {
+        ALOGE("Missing format keys for audio track");
+        source->getFormat()->dumpToLog();
+        return BAD_VALUE;
+    }
+    source->getFormat()->dumpToLog();
+
+    int32_t sampleRate = 0;
+    if (!source->getFormat()->findInt32(kKeySampleRate, &sampleRate)) {
+        ALOGE("Missing format key for sample rate");
+        source->getFormat()->dumpToLog();
+        return UNKNOWN_ERROR;
+    }
+
+    mSampleRate = sampleRate;
+    uint32_t type;
+    const void *header_data = NULL;
+    size_t packet_size = 0;
+
+    if (!source->getFormat()->findData(kKeyOpusHeader, &type, &header_data, &packet_size)) {
+        ALOGV("opus header not found in format");
+    } else if (header_data && packet_size) {
+        writeOggHeaderPackets((unsigned char *)header_data, packet_size);
+    } else {
+        ALOGD("ignoring incomplete opus header data in format");
+    }
+
+    mSource = source;
+    return OK;
+}
+
+status_t OggWriter::writeOggHeaderPackets(unsigned char *buf, size_t size) {
+    ogg_packet op;
+    ogg_page og;
+    op.packet = buf;
+    op.bytes = size;
+    op.b_o_s = 1;
+    op.e_o_s = 0;
+    op.granulepos = 0;
+    op.packetno = 0;
+    ogg_stream_packetin((ogg_stream_state*)mOs, &op);
+
+    int ret;
+    while ((ret = ogg_stream_flush((ogg_stream_state*)mOs, &og))) {
+        if (!ret) break;
+        write(mFd, og.header, og.header_len);
+        write(mFd, og.body, og.body_len);
+    }
+
+
+    const char* vendor_string = "libopus";
+    const int vendor_length = strlen(vendor_string);
+    int user_comment_list_length = 0;
+
+    const int comments_length = 8 + 4 + vendor_length + 4 + user_comment_list_length;
+    char* comments = (char*)malloc(comments_length);
+    if (comments == NULL) {
+        ALOGE("failed to allocate ogg comment buffer");
+        return UNKNOWN_ERROR;
+    }
+    memcpy(comments, "OpusTags", 8);
+    writeint(comments, 8, vendor_length);
+    memcpy(comments + 12, vendor_string, vendor_length);
+    writeint(comments, 12 + vendor_length, user_comment_list_length);
+
+    op.packet = (unsigned char*)comments;
+    op.bytes = comments_length;
+    op.b_o_s = 0;
+    op.e_o_s = 0;
+    op.granulepos = 0;
+    op.packetno = 1;
+    ogg_stream_packetin((ogg_stream_state*)mOs, &op);
+
+    while ((ret = ogg_stream_flush((ogg_stream_state*)mOs, &og))) {
+        if (!ret) break;
+        write(mFd, og.header, og.header_len);
+        write(mFd, og.body, og.body_len);
+    }
+
+    free(comments);
+    mHaveAllCodecSpecificData = true;
+    return OK;
+}
+
+status_t OggWriter::start(MetaData* /* params */) {
+    if (mInitCheck != OK) {
+        return mInitCheck;
+    }
+
+    if (mSource == NULL) {
+        return UNKNOWN_ERROR;
+    }
+
+    if (mStarted && mPaused) {
+        mPaused = false;
+        mResumed = true;
+        return OK;
+    } else if (mStarted) {
+        // Already started, does nothing
+        return OK;
+    }
+
+    status_t err = mSource->start();
+
+    if (err != OK) {
+        return err;
+    }
+
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+
+    mReachedEOS = false;
+    mDone = false;
+
+    pthread_create(&mThread, &attr, ThreadWrapper, this);
+    pthread_attr_destroy(&attr);
+
+    mStarted = true;
+
+    return OK;
+}
+
+status_t OggWriter::pause() {
+    if (!mStarted) {
+        return OK;
+    }
+    mPaused = true;
+    return OK;
+}
+
+status_t OggWriter::reset() {
+    if (!mStarted) {
+        return OK;
+    }
+
+    mDone = true;
+
+    void* dummy;
+    pthread_join(mThread, &dummy);
+
+    status_t err = static_cast<status_t>(reinterpret_cast<uintptr_t>(dummy));
+    {
+        status_t status = mSource->stop();
+        if (err == OK && (status != OK && status != ERROR_END_OF_STREAM)) {
+            err = status;
+        }
+    }
+
+    mStarted = false;
+    return err;
+}
+
+bool OggWriter::exceedsFileSizeLimit() {
+    if (mMaxFileSizeLimitBytes == 0) {
+        return false;
+    }
+    return mEstimatedSizeBytes > mMaxFileSizeLimitBytes;
+}
+
+bool OggWriter::exceedsFileDurationLimit() {
+    if (mMaxFileDurationLimitUs == 0) {
+        return false;
+    }
+    return mEstimatedDurationUs > mMaxFileDurationLimitUs;
+}
+
+// static
+void* OggWriter::ThreadWrapper(void* me) {
+    return (void*)(uintptr_t) static_cast<OggWriter*>(me)->threadFunc();
+}
+
+status_t OggWriter::threadFunc() {
+    mEstimatedDurationUs = 0;
+    mEstimatedSizeBytes = 0;
+    bool stoppedPrematurely = true;
+    int64_t previousPausedDurationUs = 0;
+    int64_t maxTimestampUs = 0;
+    status_t err = OK;
+
+    prctl(PR_SET_NAME, (unsigned long)"OggWriter", 0, 0, 0);
+
+    while (!mDone) {
+        MediaBufferBase* buffer = nullptr;
+        err = mSource->read(&buffer);
+
+        if (err != OK) {
+            ALOGW("failed to read next buffer");
+            break;
+        }
+
+        if (mPaused) {
+            buffer->release();
+            buffer = nullptr;
+            continue;
+        }
+        mEstimatedSizeBytes += buffer->range_length();
+        if (exceedsFileSizeLimit()) {
+            buffer->release();
+            buffer = nullptr;
+            notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0);
+            ALOGW("estimated size(%" PRId64 ") exceeds limit (%" PRId64 ")",
+                  mEstimatedSizeBytes, mMaxFileSizeLimitBytes);
+            break;
+        }
+
+        int32_t isCodecSpecific;
+        if ((buffer->meta_data().findInt32(kKeyIsCodecConfig, &isCodecSpecific)
+             && isCodecSpecific)
+            || IsOpusHeader((uint8_t*)buffer->data() + buffer->range_offset(),
+                         buffer->range_length())) {
+            if (mHaveAllCodecSpecificData == false) {
+                size_t opusHeadSize = 0;
+                size_t codecDelayBufSize = 0;
+                size_t seekPreRollBufSize = 0;
+                void *opusHeadBuf = NULL;
+                void *codecDelayBuf = NULL;
+                void *seekPreRollBuf = NULL;
+                GetOpusHeaderBuffers((uint8_t*)buffer->data() + buffer->range_offset(),
+                                    buffer->range_length(), &opusHeadBuf,
+                                    &opusHeadSize, &codecDelayBuf,
+                                    &codecDelayBufSize, &seekPreRollBuf,
+                                    &seekPreRollBufSize);
+                writeOggHeaderPackets((unsigned char *)opusHeadBuf, opusHeadSize);
+            } else {
+                ALOGV("ignoring later copy of CSD contained in info buffer");
+            }
+            buffer->release();
+            buffer = nullptr;
+            continue;
+        }
+
+        if (mHaveAllCodecSpecificData == false) {
+            ALOGE("Did not get valid opus header before first sample data");
+            buffer->release();
+            buffer = nullptr;
+            err = ERROR_MALFORMED;
+            break;
+        }
+
+        int64_t timestampUs;
+        CHECK(buffer->meta_data().findInt64(kKeyTime, &timestampUs));
+        if (timestampUs > mEstimatedDurationUs) {
+            mEstimatedDurationUs = timestampUs;
+        }
+        if (mResumed) {
+            previousPausedDurationUs += (timestampUs - maxTimestampUs - 20000);
+            mResumed = false;
+        }
+
+        timestampUs -= previousPausedDurationUs;
+
+        ALOGV("time stamp: %" PRId64 ", previous paused duration: %" PRId64, timestampUs,
+              previousPausedDurationUs);
+        if (timestampUs > maxTimestampUs) {
+            maxTimestampUs = timestampUs;
+        }
+
+        if (exceedsFileDurationLimit()) {
+            buffer->release();
+            buffer = nullptr;
+            notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0);
+            ALOGW("estimated duration(%" PRId64 " us) exceeds limit(%" PRId64 " us)",
+                  mEstimatedDurationUs, mMaxFileDurationLimitUs);
+            break;
+        }
+
+        ogg_packet op;
+        ogg_page og;
+        op.packet = (uint8_t*)buffer->data() + buffer->range_offset();
+        op.bytes = (long)buffer->range_length();
+        op.b_o_s = 0;
+        op.e_o_s = mReachedEOS ? 1 : 0;
+        // granulepos is the total number of PCM audio samples @ 48 kHz, up to and
+        // including the current packet.
+        ogg_int64_t granulepos = (48000 * mEstimatedDurationUs) / 1000000;
+        op.granulepos = granulepos;
+
+        // Headers are at packets 0 and 1.
+        op.packetno = 2 + (ogg_int32_t)mCurrentPacketId++;
+        ogg_stream_packetin((ogg_stream_state*)mOs, &op);
+        size_t n = 0;
+
+        while (ogg_stream_flush((ogg_stream_state*)mOs, &og) > 0) {
+            write(mFd, og.header, og.header_len);
+            write(mFd, og.body, og.body_len);
+            n = n + og.header_len + og.body_len;
+        }
+
+        if (n < buffer->range_length()) {
+            buffer->release();
+            buffer = nullptr;
+            err = ERROR_IO;
+            break;
+        }
+
+        if (err != OK) {
+            break;
+        }
+
+        stoppedPrematurely = false;
+
+        buffer->release();
+        buffer = nullptr;
+    }
+
+    // end of stream is an ok thing
+    if (err == ERROR_END_OF_STREAM) {
+        err = OK;
+    }
+
+    if (err == OK && stoppedPrematurely) {
+        err = ERROR_MALFORMED;
+    }
+
+    close(mFd);
+    mFd = -1;
+    mReachedEOS = true;
+
+    return err;
+}
+
+bool OggWriter::reachedEOS() {
+    return mReachedEOS;
+}
+
+}  // namespace android
diff --git a/media/libstagefright/OmxInfoBuilder.cpp b/media/libstagefright/OmxInfoBuilder.cpp
index 96b896b..79ffdeb 100644
--- a/media/libstagefright/OmxInfoBuilder.cpp
+++ b/media/libstagefright/OmxInfoBuilder.cpp
@@ -21,8 +21,8 @@
 #define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
 #endif
 
+#include <android-base/properties.h>
 #include <utils/Log.h>
-#include <cutils/properties.h>
 
 #include <media/stagefright/foundation/MediaDefs.h>
 #include <media/stagefright/OmxInfoBuilder.h>
@@ -53,18 +53,13 @@
 namespace /* unnamed */ {
 
 bool hasPrefix(const hidl_string& s, const char* prefix) {
-    return strncmp(s.c_str(), prefix, strlen(prefix)) == 0;
+    return strncasecmp(s.c_str(), prefix, strlen(prefix)) == 0;
 }
 
 status_t queryCapabilities(
-        const IOmxStore::NodeInfo& node, const char* mime, bool isEncoder,
+        const IOmxStore::NodeInfo& node, const char* mediaType, bool isEncoder,
         MediaCodecInfo::CapabilitiesWriter* caps) {
     sp<ACodec> codec = new ACodec();
-    status_t err = codec->queryCapabilities(
-            node.owner.c_str(), node.name.c_str(), mime, isEncoder, caps);
-    if (err != OK) {
-        return err;
-    }
     for (const auto& attribute : node.attributes) {
         // All features have an int32 value except
         // "feature-bitrate-modes", which has a string value.
@@ -81,12 +76,19 @@
                     attribute.key.c_str(), attribute.value.c_str());
         }
     }
+    // query capabilities may remove capabilities that are not actually supported by the codec
+    status_t err = codec->queryCapabilities(
+            node.owner.c_str(), node.name.c_str(), mediaType, isEncoder, caps);
+    if (err != OK) {
+        return err;
+    }
     return OK;
 }
 
 }  // unnamed namespace
 
-OmxInfoBuilder::OmxInfoBuilder() {
+OmxInfoBuilder::OmxInfoBuilder(bool allowSurfaceEncoders)
+    : mAllowSurfaceEncoders(allowSurfaceEncoders) {
 }
 
 status_t OmxInfoBuilder::buildMediaCodecList(MediaCodecListWriter* writer) {
@@ -134,107 +136,87 @@
     // Convert roles to lists of codecs
 
     // codec name -> index into swCodecs/hwCodecs
-    std::map<hidl_string, std::unique_ptr<MediaCodecInfoWriter>>
-            swCodecName2Info, hwCodecName2Info;
+    std::map<hidl_string, std::unique_ptr<MediaCodecInfoWriter>> codecName2Info;
 
-    char rank[PROPERTY_VALUE_MAX];
-    uint32_t defaultRank = 0x100;
-    if (property_get("debug.stagefright.omx_default_rank", rank, nullptr)) {
-        defaultRank = std::strtoul(rank, nullptr, 10);
-    }
+    uint32_t defaultRank =
+        ::android::base::GetUintProperty("debug.stagefright.omx_default_rank", 0x100u);
+    uint32_t defaultSwAudioRank =
+        ::android::base::GetUintProperty("debug.stagefright.omx_default_rank.sw-audio", 0x10u);
+    uint32_t defaultSwOtherRank =
+        ::android::base::GetUintProperty("debug.stagefright.omx_default_rank.sw-other", 0x210u);
+
     for (const IOmxStore::RoleInfo& role : roles) {
         const hidl_string& typeName = role.type;
         bool isEncoder = role.isEncoder;
-        bool preferPlatformNodes = role.preferPlatformNodes;
-        // If preferPlatformNodes is true, hardware nodes must be added after
-        // platform (software) nodes. hwCodecs is used to hold hardware nodes
-        // that need to be added after software nodes for the same role.
-        std::vector<const IOmxStore::NodeInfo*> hwCodecs;
-        for (const IOmxStore::NodeInfo& node : role.nodes) {
+        bool isAudio = hasPrefix(role.type, "audio/");
+        bool isVideoOrImage = hasPrefix(role.type, "video/") || hasPrefix(role.type, "image/");
+
+        for (const IOmxStore::NodeInfo &node : role.nodes) {
             const hidl_string& nodeName = node.name;
+
+            // currently image and video encoders use surface input
+            if (!mAllowSurfaceEncoders && isVideoOrImage && isEncoder) {
+                ALOGD("disabling %s for media type %s because we are not using OMX input surface",
+                        nodeName.c_str(), role.type.c_str());
+                continue;
+            }
+
             bool isSoftware = hasPrefix(nodeName, "OMX.google");
-            MediaCodecInfoWriter* info;
-            if (isSoftware) {
-                auto c2i = swCodecName2Info.find(nodeName);
-                if (c2i == swCodecName2Info.end()) {
-                    // Create a new MediaCodecInfo for a new node.
-                    c2i = swCodecName2Info.insert(std::make_pair(
-                            nodeName, writer->addMediaCodecInfo())).first;
-                    info = c2i->second.get();
-                    info->setName(nodeName.c_str());
-                    info->setOwner(node.owner.c_str());
-                    info->setEncoder(isEncoder);
-                    info->setRank(defaultRank);
-                } else {
-                    // The node has been seen before. Simply retrieve the
-                    // existing MediaCodecInfoWriter.
-                    info = c2i->second.get();
-                }
-            } else {
-                auto c2i = hwCodecName2Info.find(nodeName);
-                if (c2i == hwCodecName2Info.end()) {
-                    // Create a new MediaCodecInfo for a new node.
-                    if (!preferPlatformNodes) {
-                        c2i = hwCodecName2Info.insert(std::make_pair(
-                                nodeName, writer->addMediaCodecInfo())).first;
-                        info = c2i->second.get();
-                        info->setName(nodeName.c_str());
-                        info->setOwner(node.owner.c_str());
-                        info->setEncoder(isEncoder);
-                        info->setRank(defaultRank);
-                    } else {
-                        // If preferPlatformNodes is true, this node must be
-                        // added after all software nodes.
-                        hwCodecs.push_back(&node);
-                        continue;
+            uint32_t rank = isSoftware
+                    ? (isAudio ? defaultSwAudioRank : defaultSwOtherRank)
+                    : defaultRank;
+            // get rank from IOmxStore via attribute
+            for (const IOmxStore::Attribute& attribute : node.attributes) {
+                if (attribute.key == "rank") {
+                    uint32_t oldRank = rank;
+                    char dummy;
+                    if (sscanf(attribute.value.c_str(), "%u%c", &rank, &dummy) != 1) {
+                        rank = oldRank;
                     }
-                } else {
-                    // The node has been seen before. Simply retrieve the
-                    // existing MediaCodecInfoWriter.
-                    info = c2i->second.get();
+                    break;
                 }
             }
+
+            MediaCodecInfoWriter* info;
+            auto c2i = codecName2Info.find(nodeName);
+            if (c2i == codecName2Info.end()) {
+                // Create a new MediaCodecInfo for a new node.
+                c2i = codecName2Info.insert(std::make_pair(
+                        nodeName, writer->addMediaCodecInfo())).first;
+                info = c2i->second.get();
+                info->setName(nodeName.c_str());
+                info->setOwner(node.owner.c_str());
+                info->setRank(rank);
+
+                typename std::underlying_type<MediaCodecInfo::Attributes>::type attrs = 0;
+                // all OMX codecs are vendor codecs (in the vendor partition), but
+                // treat OMX.google codecs as non-hardware-accelerated and non-vendor
+                if (!isSoftware) {
+                    attrs |= MediaCodecInfo::kFlagIsVendor;
+                    if (!std::count_if(
+                            node.attributes.begin(), node.attributes.end(),
+                            [](const IOmxStore::Attribute &i) -> bool {
+                                return i.key == "attribute::software-codec";
+                                                                      })) {
+                        attrs |= MediaCodecInfo::kFlagIsHardwareAccelerated;
+                    }
+                }
+                if (isEncoder) {
+                    attrs |= MediaCodecInfo::kFlagIsEncoder;
+                }
+                info->setAttributes(attrs);
+            } else {
+                // The node has been seen before. Simply retrieve the
+                // existing MediaCodecInfoWriter.
+                info = c2i->second.get();
+            }
             std::unique_ptr<MediaCodecInfo::CapabilitiesWriter> caps =
-                    info->addMime(typeName.c_str());
+                    info->addMediaType(typeName.c_str());
             if (queryCapabilities(
                     node, typeName.c_str(), isEncoder, caps.get()) != OK) {
-                ALOGW("Fail to add mime %s to codec %s",
+                ALOGW("Fail to add media type %s to codec %s",
                         typeName.c_str(), nodeName.c_str());
-                info->removeMime(typeName.c_str());
-            }
-        }
-
-        // If preferPlatformNodes is true, hardware nodes will not have been
-        // added in the loop above, but rather saved in hwCodecs. They are
-        // going to be added here.
-        if (preferPlatformNodes) {
-            for (const IOmxStore::NodeInfo *node : hwCodecs) {
-                MediaCodecInfoWriter* info;
-                const hidl_string& nodeName = node->name;
-                auto c2i = hwCodecName2Info.find(nodeName);
-                if (c2i == hwCodecName2Info.end()) {
-                    // Create a new MediaCodecInfo for a new node.
-                    c2i = hwCodecName2Info.insert(std::make_pair(
-                            nodeName, writer->addMediaCodecInfo())).first;
-                    info = c2i->second.get();
-                    info->setName(nodeName.c_str());
-                    info->setOwner(node->owner.c_str());
-                    info->setEncoder(isEncoder);
-                    info->setRank(defaultRank);
-                } else {
-                    // The node has been seen before. Simply retrieve the
-                    // existing MediaCodecInfoWriter.
-                    info = c2i->second.get();
-                }
-                std::unique_ptr<MediaCodecInfo::CapabilitiesWriter> caps =
-                        info->addMime(typeName.c_str());
-                if (queryCapabilities(
-                        *node, typeName.c_str(), isEncoder, caps.get()) != OK) {
-                    ALOGW("Fail to add mime %s to codec %s "
-                          "after software codecs",
-                          typeName.c_str(), nodeName.c_str());
-                    info->removeMime(typeName.c_str());
-                }
+                info->removeMediaType(typeName.c_str());
             }
         }
     }
@@ -242,4 +224,3 @@
 }
 
 }  // namespace android
-
diff --git a/media/libstagefright/RemoteMediaExtractor.cpp b/media/libstagefright/RemoteMediaExtractor.cpp
index 9d2c42b..29c3a35 100644
--- a/media/libstagefright/RemoteMediaExtractor.cpp
+++ b/media/libstagefright/RemoteMediaExtractor.cpp
@@ -18,6 +18,7 @@
 #define LOG_TAG "RemoteMediaExtractor"
 #include <utils/Log.h>
 
+#include <binder/IPCThreadState.h>
 #include <media/stagefright/InterfaceUtils.h>
 #include <media/MediaAnalyticsItem.h>
 #include <media/MediaSource.h>
@@ -49,7 +50,12 @@
 
     mAnalyticsItem = nullptr;
     if (MEDIA_LOG) {
-        mAnalyticsItem = new MediaAnalyticsItem(kKeyExtractor);
+        mAnalyticsItem = MediaAnalyticsItem::create(kKeyExtractor);
+
+        // we're in the extractor service, we want to attribute to the app
+        // that invoked us.
+        int uid = IPCThreadState::self()->getCallingUid();
+        mAnalyticsItem->setUid(uid);
 
         // track the container format (mpeg, aac, wvm, etc)
         size_t ntracks = extractor->countTracks();
diff --git a/media/libstagefright/RemoteMediaSource.cpp b/media/libstagefright/RemoteMediaSource.cpp
index d07afec..db31af2 100644
--- a/media/libstagefright/RemoteMediaSource.cpp
+++ b/media/libstagefright/RemoteMediaSource.cpp
@@ -25,25 +25,29 @@
         MediaTrack *source,
         const sp<RefBase> &plugin)
     : mExtractor(extractor),
-      mSource(source),
+      mTrack(source),
       mExtractorPlugin(plugin) {}
 
 RemoteMediaSource::~RemoteMediaSource() {
-    delete mSource;
+    delete mTrack;
     mExtractorPlugin = nullptr;
 }
 
 status_t RemoteMediaSource::start(MetaData *params) {
-    return mSource->start(params);
+    if (params) {
+        ALOGW("dropping start parameters:");
+        params->dumpToLog();
+    }
+    return mTrack->start();
 }
 
 status_t RemoteMediaSource::stop() {
-    return mSource->stop();
+    return mTrack->stop();
 }
 
 sp<MetaData> RemoteMediaSource::getFormat() {
     sp<MetaData> meta = new MetaData();
-    if (mSource->getFormat(*meta.get()) == OK) {
+    if (mTrack->getFormat(*meta.get()) == OK) {
         return meta;
     }
     return nullptr;
@@ -51,7 +55,11 @@
 
 status_t RemoteMediaSource::read(
         MediaBufferBase **buffer, const MediaSource::ReadOptions *options) {
-    return mSource->read(buffer, reinterpret_cast<const MediaSource::ReadOptions*>(options));
+    return mTrack->read(buffer, reinterpret_cast<const MediaSource::ReadOptions*>(options));
+}
+
+bool RemoteMediaSource::supportNonblockingRead() {
+    return mTrack->supportNonblockingRead();
 }
 
 status_t RemoteMediaSource::pause() {
diff --git a/media/libstagefright/SimpleDecodingSource.cpp b/media/libstagefright/SimpleDecodingSource.cpp
index 404c537..babdc7a 100644
--- a/media/libstagefright/SimpleDecodingSource.cpp
+++ b/media/libstagefright/SimpleDecodingSource.cpp
@@ -37,6 +37,7 @@
 
 const int64_t kTimeoutWaitForOutputUs = 500000; // 0.5 seconds
 const int64_t kTimeoutWaitForInputUs = 5000; // 5 milliseconds
+const int kTimeoutMaxRetries = 20;
 
 //static
 sp<SimpleDecodingSource> SimpleDecodingSource::Create(
@@ -242,7 +243,7 @@
         return ERROR_END_OF_STREAM;
     }
 
-    for (int retries = 0; ++retries; ) {
+    for (int retries = 0; retries < kTimeoutMaxRetries; ++retries) {
         // If we fill all available input buffers, we should expect that
         // the codec produces at least one output buffer. Also, the codec
         // should produce an output buffer in at most 1 seconds. Retry a
diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp
index e010b3e..cf4edae 100644
--- a/media/libstagefright/StagefrightMediaScanner.cpp
+++ b/media/libstagefright/StagefrightMediaScanner.cpp
@@ -22,6 +22,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 
+#include <media/stagefright/MediaExtractorFactory.h>
 #include <media/stagefright/StagefrightMediaScanner.h>
 
 #include <media/IMediaHTTPService.h>
@@ -34,25 +35,16 @@
 
 StagefrightMediaScanner::~StagefrightMediaScanner() {}
 
-static bool FileHasAcceptableExtension(const char *extension) {
-    static const char *kValidExtensions[] = {
-        ".mp3", ".mp4", ".m4a", ".3gp", ".3gpp", ".3g2", ".3gpp2",
-        ".mpeg", ".ogg", ".mid", ".smf", ".imy", ".wma", ".aac",
-        ".wav", ".amr", ".midi", ".xmf", ".rtttl", ".rtx", ".ota",
-        ".mkv", ".mka", ".webm", ".ts", ".fl", ".flac", ".mxmf",
-        ".avi", ".mpeg", ".mpg", ".awb", ".mpga", ".mov",
-        ".m4v", ".oga"
-    };
-    static const size_t kNumValidExtensions =
-        sizeof(kValidExtensions) / sizeof(kValidExtensions[0]);
+static std::unordered_set<std::string> gSupportedExtensions;
 
-    for (size_t i = 0; i < kNumValidExtensions; ++i) {
-        if (!strcasecmp(extension, kValidExtensions[i])) {
-            return true;
-        }
+static bool FileHasAcceptableExtension(const char *extension) {
+
+    if (gSupportedExtensions.empty()) {
+        // get the list from the service
+        gSupportedExtensions = MediaExtractorFactory::getSupportedTypes();
     }
 
-    return false;
+    return  gSupportedExtensions.count(std::string(extension + 1)) != 0;
 }
 
 MediaScanResult StagefrightMediaScanner::processFile(
@@ -132,6 +124,11 @@
         { "date", METADATA_KEY_DATE },
         { "width", METADATA_KEY_VIDEO_WIDTH },
         { "height", METADATA_KEY_VIDEO_HEIGHT },
+        { "colorstandard", METADATA_KEY_COLOR_STANDARD },
+        { "colortransfer", METADATA_KEY_COLOR_TRANSFER },
+        { "colorrange", METADATA_KEY_COLOR_RANGE },
+        { "samplerate", METADATA_KEY_SAMPLERATE },
+        { "bitspersample", METADATA_KEY_BITS_PER_SAMPLE },
     };
     static const size_t kNumEntries = sizeof(kKeyMap) / sizeof(kKeyMap[0]);
 
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index e80ec3b..fa3d372 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -20,6 +20,7 @@
 #include <inttypes.h>
 
 #include <utils/Log.h>
+#include <cutils/properties.h>
 
 #include "include/FrameDecoder.h"
 #include "include/StagefrightMetadataRetriever.h"
@@ -32,8 +33,10 @@
 #include <media/stagefright/MediaCodecList.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MediaExtractor.h>
 #include <media/stagefright/MediaExtractorFactory.h>
 #include <media/stagefright/MetaData.h>
+#include <media/stagefright/Utils.h>
 #include <media/CharacterEncodingDetector.h>
 
 namespace android {
@@ -162,6 +165,9 @@
 
     for (i = 0; i < n; ++i) {
         sp<MetaData> meta = mExtractor->getTrackMetaData(i);
+        if (!meta) {
+            continue;
+        }
         ALOGV("getting track %zu of %zu, meta=%s", i, n, meta->toString().c_str());
 
         const char *mime;
@@ -183,6 +189,9 @@
     }
 
     sp<MetaData> trackMeta = mExtractor->getTrackMetaData(i);
+    if (!trackMeta) {
+        return NULL;
+    }
 
     if (metaOnly) {
         return FrameDecoder::getMetadataOnly(trackMeta, colorFormat, thumbnail);
@@ -204,11 +213,14 @@
         trackMeta->setCString(kKeyMIMEType, mime);
     }
 
+    bool preferhw = property_get_bool(
+            "media.stagefright.thumbnail.prefer_hw_codecs", false);
+    uint32_t flags = preferhw ? 0 : MediaCodecList::kPreferSoftwareCodecs;
     Vector<AString> matchingCodecs;
     MediaCodecList::findMatchingCodecs(
             mime,
             false, /* encoder */
-            MediaCodecList::kPreferSoftwareCodecs,
+            flags,
             &matchingCodecs);
 
     for (size_t i = 0; i < matchingCodecs.size(); ++i) {
@@ -270,16 +282,13 @@
         return NO_INIT;
     }
 
-    int32_t drm = 0;
-    if (fileMeta->findInt32(kKeyIsDRM, &drm) && drm != 0) {
-        ALOGE("frame grab not allowed.");
-        return ERROR_DRM_UNKNOWN;
-    }
-
     size_t n = mExtractor->countTracks();
     size_t i;
     for (i = 0; i < n; ++i) {
         sp<MetaData> meta = mExtractor->getTrackMetaData(i);
+        if (!meta) {
+            continue;
+        }
 
         const char *mime;
         CHECK(meta->findCString(kKeyMIMEType, &mime));
@@ -296,6 +305,9 @@
 
     sp<MetaData> trackMeta = mExtractor->getTrackMetaData(
             i, MediaExtractor::kIncludeExtensiveMetaData);
+    if (!trackMeta) {
+        return UNKNOWN_ERROR;
+    }
 
     if (metaOnly) {
         if (outFrame != NULL) {
@@ -325,24 +337,27 @@
     const char *mime;
     CHECK(trackMeta->findCString(kKeyMIMEType, &mime));
 
+    bool preferhw = property_get_bool(
+            "media.stagefright.thumbnail.prefer_hw_codecs", false);
+    uint32_t flags = preferhw ? 0 : MediaCodecList::kPreferSoftwareCodecs;
     Vector<AString> matchingCodecs;
     MediaCodecList::findMatchingCodecs(
             mime,
             false, /* encoder */
-            MediaCodecList::kPreferSoftwareCodecs,
+            flags,
             &matchingCodecs);
 
     for (size_t i = 0; i < matchingCodecs.size(); ++i) {
         const AString &componentName = matchingCodecs[i];
-        VideoFrameDecoder decoder(componentName, trackMeta, source);
-        if (decoder.init(timeUs, numFrames, option, colorFormat) == OK) {
+        sp<VideoFrameDecoder> decoder = new VideoFrameDecoder(componentName, trackMeta, source);
+        if (decoder->init(timeUs, numFrames, option, colorFormat) == OK) {
             if (outFrame != NULL) {
-                *outFrame = decoder.extractFrame();
+                *outFrame = decoder->extractFrame();
                 if (*outFrame != NULL) {
                     return OK;
                 }
             } else if (outFrames != NULL) {
-                status_t err = decoder.extractFrames(outFrames);
+                status_t err = decoder->extractFrames(outFrames);
                 if (err == OK) {
                     return OK;
                 }
@@ -395,6 +410,25 @@
     return mMetaData.valueAt(index).string();
 }
 
+void StagefrightMetadataRetriever::parseColorAspects(const sp<MetaData>& meta) {
+    sp<AMessage> format = new AMessage();
+    if (convertMetaDataToMessage(meta, &format) != OK) {
+        return;
+    }
+
+    int32_t standard, transfer, range;
+    if (format->findInt32("color-standard", &standard)
+            && format->findInt32("color-transfer", &transfer)
+            && format->findInt32("color-range", &range)) {
+        ALOGV("found color aspects : standard=%d, transfer=%d, range=%d",
+                standard, transfer, range);
+
+        mMetaData.add(METADATA_KEY_COLOR_STANDARD, String8::format("%d", standard));
+        mMetaData.add(METADATA_KEY_COLOR_TRANSFER, String8::format("%d", transfer));
+        mMetaData.add(METADATA_KEY_COLOR_RANGE, String8::format("%d", range));
+    }
+}
+
 void StagefrightMetadataRetriever::parseMetaData() {
     sp<MetaData> meta = mExtractor->getMetaData();
 
@@ -507,6 +541,9 @@
     String8 timedTextLang;
     for (size_t i = 0; i < numTracks; ++i) {
         sp<MetaData> trackMeta = mExtractor->getTrackMetaData(i);
+        if (!trackMeta) {
+            continue;
+        }
 
         int64_t durationUs;
         if (trackMeta->findInt64(kKeyDuration, &durationUs)) {
@@ -523,6 +560,19 @@
                 if (!trackMeta->findInt32(kKeyBitRate, &audioBitrate)) {
                     audioBitrate = -1;
                 }
+
+                int32_t bitsPerSample = -1;
+                int32_t sampleRate = -1;
+                trackMeta->findInt32(kKeyBitsPerSample, &bitsPerSample);
+                trackMeta->findInt32(kKeySampleRate, &sampleRate);
+                if (bitsPerSample >= 0) {
+                    sprintf(tmp, "%d", bitsPerSample);
+                    mMetaData.add(METADATA_KEY_BITS_PER_SAMPLE, String8(tmp));
+                }
+                if (sampleRate >= 0) {
+                    sprintf(tmp, "%d", sampleRate);
+                    mMetaData.add(METADATA_KEY_SAMPLERATE, String8(tmp));
+                }
             } else if (!hasVideo && !strncasecmp("video/", mime, 6)) {
                 hasVideo = true;
 
@@ -534,6 +584,8 @@
                 if (!trackMeta->findInt32(kKeyFrameCount, &videoFrameCount)) {
                     videoFrameCount = 0;
                 }
+
+                parseColorAspects(trackMeta);
             } else if (!strncasecmp("image/", mime, 6)) {
                 int32_t isPrimary;
                 if (trackMeta->findInt32(
@@ -630,8 +682,9 @@
                 !strcasecmp(fileMIME, "video/x-matroska")) {
             sp<MetaData> trackMeta = mExtractor->getTrackMetaData(0);
             const char *trackMIME;
-            CHECK(trackMeta->findCString(kKeyMIMEType, &trackMIME));
-
+            if (trackMeta != nullptr) {
+                CHECK(trackMeta->findCString(kKeyMIMEType, &trackMIME));
+            }
             if (!strncasecmp("audio/", trackMIME, 6)) {
                 // The matroska file only contains a single audio track,
                 // rewrite its mime type.
diff --git a/media/libstagefright/StagefrightPluginLoader.cpp b/media/libstagefright/StagefrightPluginLoader.cpp
index 519e870..fb03c5e 100644
--- a/media/libstagefright/StagefrightPluginLoader.cpp
+++ b/media/libstagefright/StagefrightPluginLoader.cpp
@@ -18,6 +18,7 @@
 #define LOG_TAG "StagefrightPluginLoader"
 #include <utils/Log.h>
 
+#include <android-base/properties.h>
 #include <dlfcn.h>
 
 #include "StagefrightPluginLoader.h"
@@ -27,9 +28,17 @@
 /* static */ Mutex StagefrightPluginLoader::sMutex;
 /* static */ std::unique_ptr<StagefrightPluginLoader> StagefrightPluginLoader::sInstance;
 
-StagefrightPluginLoader::StagefrightPluginLoader(const char *libPath)
-    : mCreateCodec(nullptr),
-      mCreateBuilder(nullptr) {
+namespace /* unnamed */ {
+
+constexpr const char kCCodecPluginPath[] = "libsfplugin_ccodec.so";
+
+}  // unnamed namespace
+
+StagefrightPluginLoader::StagefrightPluginLoader(const char *libPath) {
+    if (android::base::GetIntProperty("debug.stagefright.ccodec", 1) == 0) {
+        ALOGD("CCodec is disabled.");
+        return;
+    }
     mLibHandle = dlopen(libPath, RTLD_NOW | RTLD_NODELETE);
     if (mLibHandle == nullptr) {
         ALOGD("Failed to load library: %s (%s)", libPath, dlerror());
@@ -46,7 +55,7 @@
     }
     mCreateInputSurface = (CodecBase::CreateInputSurfaceFunc)dlsym(
             mLibHandle, "CreateInputSurface");
-    if (mCreateBuilder == nullptr) {
+    if (mCreateInputSurface == nullptr) {
         ALOGD("Failed to find symbol: CreateInputSurface (%s)", dlerror());
     }
 }
@@ -87,7 +96,7 @@
     Mutex::Autolock _l(sMutex);
     if (!sInstance) {
         ALOGV("Loading library");
-        sInstance.reset(new StagefrightPluginLoader("libstagefright_ccodec.so"));
+        sInstance.reset(new StagefrightPluginLoader(kCCodecPluginPath));
     }
     return sInstance;
 }
diff --git a/media/libstagefright/StagefrightPluginLoader.h b/media/libstagefright/StagefrightPluginLoader.h
index 999d30c..78effbf 100644
--- a/media/libstagefright/StagefrightPluginLoader.h
+++ b/media/libstagefright/StagefrightPluginLoader.h
@@ -40,10 +40,10 @@
     static Mutex sMutex;
     static std::unique_ptr<StagefrightPluginLoader> sInstance;
 
-    void *mLibHandle;
-    CodecBase::CreateCodecFunc mCreateCodec;
-    MediaCodecListBuilderBase::CreateBuilderFunc mCreateBuilder;
-    CodecBase::CreateInputSurfaceFunc mCreateInputSurface;
+    void *mLibHandle{nullptr};
+    CodecBase::CreateCodecFunc mCreateCodec{nullptr};
+    MediaCodecListBuilderBase::CreateBuilderFunc mCreateBuilder{nullptr};
+    CodecBase::CreateInputSurfaceFunc mCreateInputSurface{nullptr};
 };
 
 }  // namespace android
diff --git a/media/libstagefright/SurfaceUtils.cpp b/media/libstagefright/SurfaceUtils.cpp
index 9e11a94..4c94baa 100644
--- a/media/libstagefright/SurfaceUtils.cpp
+++ b/media/libstagefright/SurfaceUtils.cpp
@@ -18,10 +18,13 @@
 #define LOG_TAG "SurfaceUtils"
 #include <utils/Log.h>
 
+#include <android/api-level.h>
 #include <media/hardware/VideoAPI.h>
 #include <media/stagefright/SurfaceUtils.h>
 #include <gui/Surface.h>
 
+extern "C" int android_get_application_target_sdk_version();
+
 namespace android {
 
 status_t setNativeWindowSizeFormatAndUsage(
@@ -291,5 +294,28 @@
 
     return err;
 }
+
+status_t disableLegacyBufferDropPostQ(const sp<Surface> &surface) {
+    sp<IGraphicBufferProducer> igbp =
+            surface ? surface->getIGraphicBufferProducer() : nullptr;
+    if (igbp) {
+        int targetSdk = android_get_application_target_sdk_version();
+        // When the caller is not an app (e.g. MediaPlayer in mediaserver)
+        // targetSdk is __ANDROID_API_FUTURE__.
+        bool drop =
+                targetSdk < __ANDROID_API_Q__ ||
+                targetSdk == __ANDROID_API_FUTURE__;
+        if (!drop) {
+            status_t err = igbp->setLegacyBufferDrop(false);
+            if (err == NO_ERROR) {
+                ALOGD("legacy buffer drop disabled: target sdk (%d)",
+                      targetSdk);
+            } else {
+                ALOGD("disabling legacy buffer drop failed: %d", err);
+            }
+        }
+    }
+    return NO_ERROR;
+}
 }  // namespace android
 
diff --git a/media/libstagefright/TEST_MAPPING b/media/libstagefright/TEST_MAPPING
new file mode 100644
index 0000000..96818eb
--- /dev/null
+++ b/media/libstagefright/TEST_MAPPING
@@ -0,0 +1,12 @@
+{
+  "postsubmit": [
+    {
+      "name": "CtsMediaTestCases",
+      "options": [
+        {
+          "include-annotation": "android.platform.test.annotations.RequiresDevice"
+        }
+      ]
+    }
+  ]
+}
diff --git a/media/libstagefright/ThrottledSource.cpp b/media/libstagefright/ThrottledSource.cpp
index 7496752..49cea9e 100644
--- a/media/libstagefright/ThrottledSource.cpp
+++ b/media/libstagefright/ThrottledSource.cpp
@@ -51,7 +51,7 @@
     // How long would it have taken to transfer everything we ever
     // transferred given the limited bandwidth.
     int64_t durationUs =
-        mTotalTransferred * 1000000ll / mBandwidthLimitBytesPerSecond;
+        mTotalTransferred * 1000000LL / mBandwidthLimitBytesPerSecond;
 
     int64_t whenUs = mStartTimeUs + durationUs;
 
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index cf5e91e..135151f 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -37,7 +37,9 @@
 #include <media/stagefright/foundation/ALookup.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/foundation/ByteUtils.h>
+#include <media/stagefright/foundation/OpusHeader.h>
 #include <media/stagefright/MetaData.h>
+#include <media/stagefright/MediaCodecConstants.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/AudioSystem.h>
 #include <media/MediaPlayerInterface.h>
@@ -74,7 +76,7 @@
 }
 #endif
 
-static void convertMetaDataToMessageColorAspects(const sp<MetaData> &meta, sp<AMessage> &msg) {
+static void convertMetaDataToMessageColorAspects(const MetaDataBase *meta, sp<AMessage> &msg) {
     // 0 values are unspecified
     int32_t range = 0;
     int32_t primaries = 0;
@@ -119,7 +121,8 @@
     }
 
     // if user/container supplied HDR static info without transfer set, assume true
-    if (format->contains("hdr-static-info") && !format->contains("color-transfer")) {
+    if ((format->contains("hdr-static-info") || format->contains("hdr10-plus-info"))
+            && !format->contains("color-transfer")) {
         return true;
     }
     // otherwise, verify that an HDR transfer function is set
@@ -190,6 +193,9 @@
         { 50, OMX_VIDEO_AVCLevel5  },
         { 51, OMX_VIDEO_AVCLevel51 },
         { 52, OMX_VIDEO_AVCLevel52 },
+        { 60, OMX_VIDEO_AVCLevel6  },
+        { 61, OMX_VIDEO_AVCLevel61 },
+        { 62, OMX_VIDEO_AVCLevel62 },
     };
     const static ALookup<uint8_t, OMX_VIDEO_AVCPROFILETYPE> profiles {
         { 66, OMX_VIDEO_AVCProfileBaseline },
@@ -568,8 +574,254 @@
     }
 }
 
+static void parseAV1ProfileLevelFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) {
+    // Parse CSD structure to extract profile level information
+    // https://aomediacodec.github.io/av1-isobmff/#av1codecconfigurationbox
+    const uint8_t *data = csd->data();
+    size_t remaining = csd->size();
+    if (remaining < 4 || data[0] != 0x81) {  // configurationVersion == 1
+        return;
+    }
+    uint8_t profileData = (data[1] & 0xE0) >> 5;
+    uint8_t levelData = data[1] & 0x1F;
+    uint8_t highBitDepth = (data[2] & 0x40) >> 6;
+
+    const static ALookup<std::pair<uint8_t, uint8_t>, int32_t> profiles {
+        { { 0, 0 }, AV1ProfileMain8 },
+        { { 1, 0 }, AV1ProfileMain10 },
+    };
+
+    int32_t profile;
+    if (profiles.map(std::make_pair(highBitDepth, profileData), &profile)) {
+        // bump to HDR profile
+        if (isHdr(format) && profile == AV1ProfileMain10) {
+            if (format->contains("hdr10-plus-info")) {
+                profile = AV1ProfileMain10HDR10Plus;
+            } else {
+                profile = AV1ProfileMain10HDR10;
+            }
+        }
+        format->setInt32("profile", profile);
+    }
+    const static ALookup<uint8_t, int32_t> levels {
+        { 0, AV1Level2   },
+        { 1, AV1Level21  },
+        { 2, AV1Level22  },
+        { 3, AV1Level23  },
+        { 4, AV1Level3   },
+        { 5, AV1Level31  },
+        { 6, AV1Level32  },
+        { 7, AV1Level33  },
+        { 8, AV1Level4   },
+        { 9, AV1Level41  },
+        { 10, AV1Level42  },
+        { 11, AV1Level43  },
+        { 12, AV1Level5   },
+        { 13, AV1Level51  },
+        { 14, AV1Level52  },
+        { 15, AV1Level53  },
+        { 16, AV1Level6   },
+        { 17, AV1Level61  },
+        { 18, AV1Level62  },
+        { 19, AV1Level63  },
+        { 20, AV1Level7   },
+        { 21, AV1Level71  },
+        { 22, AV1Level72  },
+        { 23, AV1Level73  },
+    };
+
+    int32_t level;
+    if (levels.map(levelData, &level)) {
+        format->setInt32("level", level);
+    }
+}
+
+
+static std::vector<std::pair<const char *, uint32_t>> stringMappings {
+    {
+        { "album", kKeyAlbum },
+        { "albumartist", kKeyAlbumArtist },
+        { "artist", kKeyArtist },
+        { "author", kKeyAuthor },
+        { "cdtracknum", kKeyCDTrackNumber },
+        { "compilation", kKeyCompilation },
+        { "composer", kKeyComposer },
+        { "date", kKeyDate },
+        { "discnum", kKeyDiscNumber },
+        { "genre", kKeyGenre },
+        { "location", kKeyLocation },
+        { "lyricist", kKeyWriter },
+        { "manufacturer", kKeyManufacturer },
+        { "title", kKeyTitle },
+        { "year", kKeyYear },
+    }
+};
+
+static std::vector<std::pair<const char *, uint32_t>> floatMappings {
+    {
+        { "capture-rate", kKeyCaptureFramerate },
+    }
+};
+
+static std::vector<std::pair<const char *, uint32_t>> int64Mappings {
+    {
+        { "exif-offset", kKeyExifOffset },
+        { "exif-size", kKeyExifSize },
+        { "target-time", kKeyTargetTime },
+        { "thumbnail-time", kKeyThumbnailTime },
+        { "timeUs", kKeyTime },
+        { "durationUs", kKeyDuration },
+    }
+};
+
+static std::vector<std::pair<const char *, uint32_t>> int32Mappings {
+    {
+        { "loop", kKeyAutoLoop },
+        { "time-scale", kKeyTimeScale },
+        { "crypto-mode", kKeyCryptoMode },
+        { "crypto-default-iv-size", kKeyCryptoDefaultIVSize },
+        { "crypto-encrypted-byte-block", kKeyEncryptedByteBlock },
+        { "crypto-skip-byte-block", kKeySkipByteBlock },
+        { "frame-count", kKeyFrameCount },
+        { "max-bitrate", kKeyMaxBitRate },
+        { "pcm-big-endian", kKeyPcmBigEndian },
+        { "temporal-layer-count", kKeyTemporalLayerCount },
+        { "temporal-layer-id", kKeyTemporalLayerId },
+        { "thumbnail-width", kKeyThumbnailWidth },
+        { "thumbnail-height", kKeyThumbnailHeight },
+        { "valid-samples", kKeyValidSamples },
+    }
+};
+
+static std::vector<std::pair<const char *, uint32_t>> bufferMappings {
+    {
+        { "albumart", kKeyAlbumArt },
+        { "audio-presentation-info", kKeyAudioPresentationInfo },
+        { "pssh", kKeyPssh },
+        { "crypto-iv", kKeyCryptoIV },
+        { "crypto-key", kKeyCryptoKey },
+        { "crypto-encrypted-sizes", kKeyEncryptedSizes },
+        { "crypto-plain-sizes", kKeyPlainSizes },
+        { "icc-profile", kKeyIccProfile },
+        { "sei", kKeySEI },
+        { "text-format-data", kKeyTextFormatData },
+        { "thumbnail-csd-hevc", kKeyThumbnailHVCC },
+    }
+};
+
+static std::vector<std::pair<const char *, uint32_t>> CSDMappings {
+    {
+        { "csd-0", kKeyOpaqueCSD0 },
+        { "csd-1", kKeyOpaqueCSD1 },
+        { "csd-2", kKeyOpaqueCSD2 },
+    }
+};
+
+void convertMessageToMetaDataFromMappings(const sp<AMessage> &msg, sp<MetaData> &meta) {
+    for (auto elem : stringMappings) {
+        AString value;
+        if (msg->findString(elem.first, &value)) {
+            meta->setCString(elem.second, value.c_str());
+        }
+    }
+
+    for (auto elem : floatMappings) {
+        float value;
+        if (msg->findFloat(elem.first, &value)) {
+            meta->setFloat(elem.second, value);
+        }
+    }
+
+    for (auto elem : int64Mappings) {
+        int64_t value;
+        if (msg->findInt64(elem.first, &value)) {
+            meta->setInt64(elem.second, value);
+        }
+    }
+
+    for (auto elem : int32Mappings) {
+        int32_t value;
+        if (msg->findInt32(elem.first, &value)) {
+            meta->setInt32(elem.second, value);
+        }
+    }
+
+    for (auto elem : bufferMappings) {
+        sp<ABuffer> value;
+        if (msg->findBuffer(elem.first, &value)) {
+            meta->setData(elem.second,
+                    MetaDataBase::Type::TYPE_NONE, value->data(), value->size());
+        }
+    }
+
+    for (auto elem : CSDMappings) {
+        sp<ABuffer> value;
+        if (msg->findBuffer(elem.first, &value)) {
+            meta->setData(elem.second,
+                    MetaDataBase::Type::TYPE_NONE, value->data(), value->size());
+        }
+    }
+}
+
+void convertMetaDataToMessageFromMappings(const MetaDataBase *meta, sp<AMessage> format) {
+    for (auto elem : stringMappings) {
+        const char *value;
+        if (meta->findCString(elem.second, &value)) {
+            format->setString(elem.first, value, strlen(value));
+        }
+    }
+
+    for (auto elem : floatMappings) {
+        float value;
+        if (meta->findFloat(elem.second, &value)) {
+            format->setFloat(elem.first, value);
+        }
+    }
+
+    for (auto elem : int64Mappings) {
+        int64_t value;
+        if (meta->findInt64(elem.second, &value)) {
+            format->setInt64(elem.first, value);
+        }
+    }
+
+    for (auto elem : int32Mappings) {
+        int32_t value;
+        if (meta->findInt32(elem.second, &value)) {
+            format->setInt32(elem.first, value);
+        }
+    }
+
+    for (auto elem : bufferMappings) {
+        uint32_t type;
+        const void* data;
+        size_t size;
+        if (meta->findData(elem.second, &type, &data, &size)) {
+            sp<ABuffer> buf = ABuffer::CreateAsCopy(data, size);
+            format->setBuffer(elem.first, buf);
+        }
+    }
+
+    for (auto elem : CSDMappings) {
+        uint32_t type;
+        const void* data;
+        size_t size;
+        if (meta->findData(elem.second, &type, &data, &size)) {
+            sp<ABuffer> buf = ABuffer::CreateAsCopy(data, size);
+            buf->meta()->setInt32("csd", true);
+            buf->meta()->setInt64("timeUs", 0);
+            format->setBuffer(elem.first, buf);
+        }
+    }
+}
+
 status_t convertMetaDataToMessage(
         const sp<MetaData> &meta, sp<AMessage> *format) {
+    return convertMetaDataToMessage(meta.get(), format);
+}
+
+status_t convertMetaDataToMessage(
+        const MetaDataBase *meta, sp<AMessage> *format) {
 
     format->clear();
 
@@ -586,6 +838,8 @@
     sp<AMessage> msg = new AMessage;
     msg->setString("mime", mime);
 
+    convertMetaDataToMessageFromMappings(meta, msg);
+
     uint32_t type;
     const void *data;
     size_t size;
@@ -599,6 +853,16 @@
         memcpy(buffer->data(), data, size);
     }
 
+    if (meta->findData(kKeyCAPrivateData, &type, &data, &size)) {
+        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
+        if (buffer.get() == NULL || buffer->base() == NULL) {
+            return NO_MEMORY;
+        }
+
+        msg->setBuffer("ca-private-data", buffer);
+        memcpy(buffer->data(), data, size);
+    }
+
     int32_t systemId;
     if (meta->findInt32(kKeyCASystemID, &systemId)) {
         msg->setInt32("ca-system-id", systemId);
@@ -712,6 +976,16 @@
             ColorUtils::setHDRStaticInfoIntoFormat(*(HDRStaticInfo*)data, msg);
         }
 
+        if (meta->findData(kKeyHdr10PlusInfo, &type, &data, &size)
+                && size > 0) {
+            sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
+            if (buffer.get() == NULL || buffer->base() == NULL) {
+                return NO_MEMORY;
+            }
+            memcpy(buffer->data(), data, size);
+            msg->setBuffer("hdr10-plus-info", buffer);
+        }
+
         convertMetaDataToMessageColorAspects(meta, msg);
     } else if (!strncasecmp("audio/", mime, 6)) {
         int32_t numChannels, sampleRate;
@@ -723,6 +997,11 @@
         msg->setInt32("channel-count", numChannels);
         msg->setInt32("sample-rate", sampleRate);
 
+        int32_t bitsPerSample;
+        if (meta->findInt32(kKeyBitsPerSample, &bitsPerSample)) {
+            msg->setInt32("bits-per-sample", bitsPerSample);
+        }
+
         int32_t channelMask;
         if (meta->findInt32(kKeyChannelMask, &channelMask)) {
             msg->setInt32("channel-mask", channelMask);
@@ -751,6 +1030,11 @@
         if (meta->findInt32(kKeyPcmEncoding, &pcmEncoding)) {
             msg->setInt32("pcm-encoding", pcmEncoding);
         }
+
+        int32_t hapticChannelCount;
+        if (meta->findInt32(kKeyHapticChannelCount, &hapticChannelCount)) {
+            msg->setInt32("haptic-channel-count", hapticChannelCount);
+        }
     }
 
     int32_t maxInputSize;
@@ -880,7 +1164,9 @@
     } else if (meta->findData(kKeyHVCC, &type, &data, &size)) {
         const uint8_t *ptr = (const uint8_t *)data;
 
-        if (size < 23 || ptr[0] != 1) {  // configurationVersion == 1
+        if (size < 23 || (ptr[0] != 1 && ptr[0] != 0)) {
+            // configurationVersion == 1 or 0
+            // 1 is what the standard dictates, but some old muxers may have used 0.
             ALOGE("b/23680780");
             return BAD_VALUE;
         }
@@ -950,7 +1236,68 @@
             msg->setInt32("android._is-hdr", (info & hvcc.kInfoIsHdr) != 0);
         }
 
+        uint32_t isoPrimaries, isoTransfer, isoMatrix, isoRange;
+        if (hvcc.findParam32(kColourPrimaries, &isoPrimaries)
+                && hvcc.findParam32(kTransferCharacteristics, &isoTransfer)
+                && hvcc.findParam32(kMatrixCoeffs, &isoMatrix)
+                && hvcc.findParam32(kVideoFullRangeFlag, &isoRange)) {
+            ALOGV("found iso color aspects : primaris=%d, transfer=%d, matrix=%d, range=%d",
+                    isoPrimaries, isoTransfer, isoMatrix, isoRange);
+
+            ColorAspects aspects;
+            ColorUtils::convertIsoColorAspectsToCodecAspects(
+                    isoPrimaries, isoTransfer, isoMatrix, isoRange, aspects);
+
+            if (aspects.mPrimaries == ColorAspects::PrimariesUnspecified) {
+                int32_t primaries;
+                if (meta->findInt32(kKeyColorPrimaries, &primaries)) {
+                    ALOGV("unspecified primaries found, replaced to %d", primaries);
+                    aspects.mPrimaries = static_cast<ColorAspects::Primaries>(primaries);
+                }
+            }
+            if (aspects.mTransfer == ColorAspects::TransferUnspecified) {
+                int32_t transferFunction;
+                if (meta->findInt32(kKeyTransferFunction, &transferFunction)) {
+                    ALOGV("unspecified transfer found, replaced to %d", transferFunction);
+                    aspects.mTransfer = static_cast<ColorAspects::Transfer>(transferFunction);
+                }
+            }
+            if (aspects.mMatrixCoeffs == ColorAspects::MatrixUnspecified) {
+                int32_t colorMatrix;
+                if (meta->findInt32(kKeyColorMatrix, &colorMatrix)) {
+                    ALOGV("unspecified matrix found, replaced to %d", colorMatrix);
+                    aspects.mMatrixCoeffs = static_cast<ColorAspects::MatrixCoeffs>(colorMatrix);
+                }
+            }
+            if (aspects.mRange == ColorAspects::RangeUnspecified) {
+                int32_t range;
+                if (meta->findInt32(kKeyColorRange, &range)) {
+                    ALOGV("unspecified range found, replaced to %d", range);
+                    aspects.mRange = static_cast<ColorAspects::Range>(range);
+                }
+            }
+
+            int32_t standard, transfer, range;
+            if (ColorUtils::convertCodecColorAspectsToPlatformAspects(
+                    aspects, &range, &standard, &transfer) == OK) {
+                msg->setInt32("color-standard", standard);
+                msg->setInt32("color-transfer", transfer);
+                msg->setInt32("color-range", range);
+            }
+        }
+
         parseHevcProfileLevelFromHvcc((const uint8_t *)data, dataSize, msg);
+    } else if (meta->findData(kKeyAV1C, &type, &data, &size)) {
+        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
+        if (buffer.get() == NULL || buffer->base() == NULL) {
+            return NO_MEMORY;
+        }
+        memcpy(buffer->data(), data, size);
+
+        buffer->meta()->setInt32("csd", true);
+        buffer->meta()->setInt64("timeUs", 0);
+        msg->setBuffer("csd-0", buffer);
+        parseAV1ProfileLevelFromCsd(buffer, msg);
     } else if (meta->findData(kKeyESDS, &type, &data, &size)) {
         ESDS esds((const char *)data, size);
         if (esds.InitCheck() != (status_t)OK) {
@@ -998,33 +1345,9 @@
                 msg->setInt32("max-bitrate", (int32_t)maxBitrate);
             }
         }
-    } else if (meta->findData(kTypeD263, &type, &data, &size)) {
+    } else if (meta->findData(kKeyD263, &type, &data, &size)) {
         const uint8_t *ptr = (const uint8_t *)data;
         parseH263ProfileLevelFromD263(ptr, size, msg);
-    } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
-        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
-        if (buffer.get() == NULL || buffer->base() == NULL) {
-            return NO_MEMORY;
-        }
-        memcpy(buffer->data(), data, size);
-
-        buffer->meta()->setInt32("csd", true);
-        buffer->meta()->setInt64("timeUs", 0);
-        msg->setBuffer("csd-0", buffer);
-
-        if (!meta->findData(kKeyVorbisBooks, &type, &data, &size)) {
-            return -EINVAL;
-        }
-
-        buffer = new (std::nothrow) ABuffer(size);
-        if (buffer.get() == NULL || buffer->base() == NULL) {
-            return NO_MEMORY;
-        }
-        memcpy(buffer->data(), data, size);
-
-        buffer->meta()->setInt32("csd", true);
-        buffer->meta()->setInt64("timeUs", 0);
-        msg->setBuffer("csd-1", buffer);
     } else if (meta->findData(kKeyOpusHeader, &type, &data, &size)) {
         sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
         if (buffer.get() == NULL || buffer->base() == NULL) {
@@ -1063,16 +1386,6 @@
         buffer->meta()->setInt32("csd", true);
         buffer->meta()->setInt64("timeUs", 0);
         msg->setBuffer("csd-2", buffer);
-    } else if (meta->findData(kKeyFlacMetadata, &type, &data, &size)) {
-        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
-        if (buffer.get() == NULL || buffer->base() == NULL) {
-            return NO_MEMORY;
-        }
-        memcpy(buffer->data(), data, size);
-
-        buffer->meta()->setInt32("csd", true);
-        buffer->meta()->setInt64("timeUs", 0);
-        msg->setBuffer("csd-0", buffer);
     } else if (meta->findData(kKeyVp9CodecPrivate, &type, &data, &size)) {
         sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
         if (buffer.get() == NULL || buffer->base() == NULL) {
@@ -1085,13 +1398,17 @@
         msg->setBuffer("csd-0", buffer);
 
         parseVp9ProfileLevelFromCsd(buffer, msg);
-    }
-
-    // TODO expose "crypto-key"/kKeyCryptoKey through public api
-    if (meta->findData(kKeyCryptoKey, &type, &data, &size)) {
+    } else if (meta->findData(kKeyAlacMagicCookie, &type, &data, &size)) {
+        ALOGV("convertMetaDataToMessage found kKeyAlacMagicCookie of size %zu\n", size);
         sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
-        msg->setBuffer("crypto-key", buffer);
+        if (buffer.get() == NULL || buffer->base() == NULL) {
+            return NO_MEMORY;
+        }
         memcpy(buffer->data(), data, size);
+
+        buffer->meta()->setInt32("csd", true);
+        buffer->meta()->setInt64("timeUs", 0);
+        msg->setBuffer("csd-0", buffer);
     }
 
     *format = msg;
@@ -1292,6 +1609,21 @@
         ALOGW("did not find mime type");
     }
 
+    convertMessageToMetaDataFromMappings(msg, meta);
+
+    int32_t systemId;
+    if (msg->findInt32("ca-system-id", &systemId)) {
+        meta->setInt32(kKeyCASystemID, systemId);
+
+        sp<ABuffer> caSessionId, caPvtData;
+        if (msg->findBuffer("ca-session-id", &caSessionId)) {
+            meta->setData(kKeyCASessionID, 0, caSessionId->data(), caSessionId->size());
+        }
+        if (msg->findBuffer("ca-private-data", &caPvtData)) {
+            meta->setData(kKeyCAPrivateData, 0, caPvtData->data(), caPvtData->size());
+        }
+    }
+
     int64_t durationUs;
     if (msg->findInt64("durationUs", &durationUs)) {
         meta->setInt64(kKeyDuration, durationUs);
@@ -1323,7 +1655,7 @@
             meta->setInt32(kKeyWidth, width);
             meta->setInt32(kKeyHeight, height);
         } else {
-            ALOGW("did not find width and/or height");
+            ALOGV("did not find width and/or height");
         }
 
         int32_t sarWidth, sarHeight;
@@ -1386,6 +1718,12 @@
             }
         }
 
+        sp<ABuffer> hdr10PlusInfo;
+        if (msg->findBuffer("hdr10-plus-info", &hdr10PlusInfo)) {
+            meta->setData(kKeyHdr10PlusInfo, 0,
+                    hdr10PlusInfo->data(), hdr10PlusInfo->size());
+        }
+
         convertMessageToMetaDataColorAspects(msg, meta);
 
         AString tsSchema;
@@ -1410,6 +1748,10 @@
         if (msg->findInt32("sample-rate", &sampleRate)) {
             meta->setInt32(kKeySampleRate, sampleRate);
         }
+        int32_t bitsPerSample;
+        if (msg->findInt32("bits-per-sample", &bitsPerSample)) {
+            meta->setInt32(kKeyBitsPerSample, bitsPerSample);
+        }
         int32_t channelMask;
         if (msg->findInt32("channel-mask", &channelMask)) {
             meta->setInt32(kKeyChannelMask, channelMask);
@@ -1428,10 +1770,20 @@
             meta->setInt32(kKeyIsADTS, isADTS);
         }
 
+        int32_t aacProfile = -1;
+        if (msg->findInt32("aac-profile", &aacProfile)) {
+            meta->setInt32(kKeyAACAOT, aacProfile);
+        }
+
         int32_t pcmEncoding;
         if (msg->findInt32("pcm-encoding", &pcmEncoding)) {
             meta->setInt32(kKeyPcmEncoding, pcmEncoding);
         }
+
+        int32_t hapticChannelCount;
+        if (msg->findInt32("haptic-channel-count", &hapticChannelCount)) {
+            meta->setInt32(kKeyHapticChannelCount, hapticChannelCount);
+        }
     }
 
     int32_t maxInputSize;
@@ -1468,40 +1820,71 @@
             if (msg->findBuffer("csd-1", &csd1)) {
                 std::vector<char> avcc(csd0size + csd1->size() + 1024);
                 size_t outsize = reassembleAVCC(csd0, csd1, avcc.data());
-                meta->setData(kKeyAVCC, kKeyAVCC, avcc.data(), outsize);
+                meta->setData(kKeyAVCC, kTypeAVCC, avcc.data(), outsize);
             }
-        } else if (mime == MEDIA_MIMETYPE_AUDIO_AAC || mime == MEDIA_MIMETYPE_VIDEO_MPEG4) {
+        } else if (mime == MEDIA_MIMETYPE_AUDIO_AAC ||
+                mime == MEDIA_MIMETYPE_VIDEO_MPEG4 ||
+                mime == MEDIA_MIMETYPE_AUDIO_WMA ||
+                mime == MEDIA_MIMETYPE_AUDIO_MS_ADPCM ||
+                mime == MEDIA_MIMETYPE_AUDIO_DVI_IMA_ADPCM) {
             std::vector<char> esds(csd0size + 31);
             // The written ESDS is actually for an audio stream, but it's enough
             // for transporting the CSD to muxers.
             reassembleESDS(csd0, esds.data());
-            meta->setData(kKeyESDS, kKeyESDS, esds.data(), esds.size());
+            meta->setData(kKeyESDS, kTypeESDS, esds.data(), esds.size());
         } else if (mime == MEDIA_MIMETYPE_VIDEO_HEVC ||
                    mime == MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC) {
             std::vector<uint8_t> hvcc(csd0size + 1024);
             size_t outsize = reassembleHVCC(csd0, hvcc.data(), hvcc.size(), 4);
-            meta->setData(kKeyHVCC, kKeyHVCC, hvcc.data(), outsize);
+            meta->setData(kKeyHVCC, kTypeHVCC, hvcc.data(), outsize);
+        } else if (mime == MEDIA_MIMETYPE_VIDEO_AV1) {
+            meta->setData(kKeyAV1C, 0, csd0->data(), csd0->size());
         } else if (mime == MEDIA_MIMETYPE_VIDEO_VP9) {
             meta->setData(kKeyVp9CodecPrivate, 0, csd0->data(), csd0->size());
         } else if (mime == MEDIA_MIMETYPE_AUDIO_OPUS) {
-            meta->setData(kKeyOpusHeader, 0, csd0->data(), csd0->size());
+            size_t opusHeadSize = csd0->size();
+            size_t codecDelayBufSize = 0;
+            size_t seekPreRollBufSize = 0;
+            void *opusHeadBuf = csd0->data();
+            void *codecDelayBuf = NULL;
+            void *seekPreRollBuf = NULL;
             if (msg->findBuffer("csd-1", &csd1)) {
-                meta->setData(kKeyOpusCodecDelay, 0, csd1->data(), csd1->size());
+                codecDelayBufSize = csd1->size();
+                codecDelayBuf = csd1->data();
             }
             if (msg->findBuffer("csd-2", &csd2)) {
-                meta->setData(kKeyOpusSeekPreRoll, 0, csd2->data(), csd2->size());
+                seekPreRollBufSize = csd2->size();
+                seekPreRollBuf = csd2->data();
             }
-        } else if (mime == MEDIA_MIMETYPE_AUDIO_VORBIS) {
-            meta->setData(kKeyVorbisInfo, 0, csd0->data(), csd0->size());
-            if (msg->findBuffer("csd-1", &csd1)) {
-                meta->setData(kKeyVorbisBooks, 0, csd1->data(), csd1->size());
+            /* Extract codec delay and seek pre roll from csd-0,
+             * if csd-1 and csd-2 are not present */
+            if (!codecDelayBuf && !seekPreRollBuf) {
+                GetOpusHeaderBuffers(csd0->data(), csd0->size(), &opusHeadBuf,
+                                    &opusHeadSize, &codecDelayBuf,
+                                    &codecDelayBufSize, &seekPreRollBuf,
+                                    &seekPreRollBufSize);
             }
+            meta->setData(kKeyOpusHeader, 0, opusHeadBuf, opusHeadSize);
+            if (codecDelayBuf) {
+                meta->setData(kKeyOpusCodecDelay, 0, codecDelayBuf, codecDelayBufSize);
+            }
+            if (seekPreRollBuf) {
+                meta->setData(kKeyOpusSeekPreRoll, 0, seekPreRollBuf, seekPreRollBufSize);
+            }
+        } else if (mime == MEDIA_MIMETYPE_AUDIO_ALAC) {
+            meta->setData(kKeyAlacMagicCookie, 0, csd0->data(), csd0->size());
         }
-    }
-
-    int32_t timeScale;
-    if (msg->findInt32("time-scale", &timeScale)) {
-        meta->setInt32(kKeyTimeScale, timeScale);
+    } else if (mime == MEDIA_MIMETYPE_VIDEO_AVC && msg->findBuffer("csd-avc", &csd0)) {
+        meta->setData(kKeyAVCC, kTypeAVCC, csd0->data(), csd0->size());
+    } else if ((mime == MEDIA_MIMETYPE_VIDEO_HEVC || mime == MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC)
+            && msg->findBuffer("csd-hevc", &csd0)) {
+        meta->setData(kKeyHVCC, kTypeHVCC, csd0->data(), csd0->size());
+    } else if (msg->findBuffer("esds", &csd0)) {
+        meta->setData(kKeyESDS, kTypeESDS, csd0->data(), csd0->size());
+    } else if (msg->findBuffer("mpeg2-stream-header", &csd0)) {
+        meta->setData(kKeyStreamHeader, 'mdat', csd0->data(), csd0->size());
+    } else if (msg->findBuffer("d263", &csd0)) {
+        meta->setData(kKeyD263, kTypeD263, csd0->data(), csd0->size());
     }
 
     // XXX TODO add whatever other keys there are
@@ -1577,7 +1960,11 @@
     { MEDIA_MIMETYPE_AUDIO_VORBIS,      AUDIO_FORMAT_VORBIS },
     { MEDIA_MIMETYPE_AUDIO_OPUS,        AUDIO_FORMAT_OPUS},
     { MEDIA_MIMETYPE_AUDIO_AC3,         AUDIO_FORMAT_AC3},
+    { MEDIA_MIMETYPE_AUDIO_EAC3,        AUDIO_FORMAT_E_AC3},
+    { MEDIA_MIMETYPE_AUDIO_EAC3_JOC,    AUDIO_FORMAT_E_AC3_JOC},
+    { MEDIA_MIMETYPE_AUDIO_AC4,         AUDIO_FORMAT_AC4},
     { MEDIA_MIMETYPE_AUDIO_FLAC,        AUDIO_FORMAT_FLAC},
+    { MEDIA_MIMETYPE_AUDIO_ALAC,        AUDIO_FORMAT_ALAC },
     { 0, AUDIO_FORMAT_INVALID }
 };
 
@@ -1629,46 +2016,46 @@
     return;
 }
 
-bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo,
-                      bool isStreaming, audio_stream_type_t streamType)
+status_t getAudioOffloadInfo(const sp<MetaData>& meta, bool hasVideo,
+        bool isStreaming, audio_stream_type_t streamType, audio_offload_info_t *info)
 {
     const char *mime;
     if (meta == NULL) {
-        return false;
+        return BAD_VALUE;
     }
     CHECK(meta->findCString(kKeyMIMEType, &mime));
 
-    audio_offload_info_t info = AUDIO_INFO_INITIALIZER;
+    (*info) = AUDIO_INFO_INITIALIZER;
 
-    info.format = AUDIO_FORMAT_INVALID;
-    if (mapMimeToAudioFormat(info.format, mime) != OK) {
+    info->format = AUDIO_FORMAT_INVALID;
+    if (mapMimeToAudioFormat(info->format, mime) != OK) {
         ALOGE(" Couldn't map mime type \"%s\" to a valid AudioSystem::audio_format !", mime);
-        return false;
+        return BAD_VALUE;
     } else {
-        ALOGV("Mime type \"%s\" mapped to audio_format %d", mime, info.format);
+        ALOGV("Mime type \"%s\" mapped to audio_format %d", mime, info->format);
     }
 
-    if (AUDIO_FORMAT_INVALID == info.format) {
+    if (AUDIO_FORMAT_INVALID == info->format) {
         // can't offload if we don't know what the source format is
         ALOGE("mime type \"%s\" not a known audio format", mime);
-        return false;
+        return BAD_VALUE;
     }
 
     // Redefine aac format according to its profile
     // Offloading depends on audio DSP capabilities.
     int32_t aacaot = -1;
     if (meta->findInt32(kKeyAACAOT, &aacaot)) {
-        mapAACProfileToAudioFormat(info.format,(OMX_AUDIO_AACPROFILETYPE) aacaot);
+        mapAACProfileToAudioFormat(info->format,(OMX_AUDIO_AACPROFILETYPE) aacaot);
     }
 
     int32_t srate = -1;
     if (!meta->findInt32(kKeySampleRate, &srate)) {
         ALOGV("track of type '%s' does not publish sample rate", mime);
     }
-    info.sample_rate = srate;
+    info->sample_rate = srate;
 
     int32_t cmask = 0;
-    if (!meta->findInt32(kKeyChannelMask, &cmask)) {
+    if (!meta->findInt32(kKeyChannelMask, &cmask) || cmask == CHANNEL_MASK_USE_CHANNEL_ORDER) {
         ALOGV("track of type '%s' does not publish channel mask", mime);
 
         // Try a channel count instead
@@ -1679,25 +2066,34 @@
             cmask = audio_channel_out_mask_from_count(channelCount);
         }
     }
-    info.channel_mask = cmask;
+    info->channel_mask = cmask;
 
     int64_t duration = 0;
     if (!meta->findInt64(kKeyDuration, &duration)) {
         ALOGV("track of type '%s' does not publish duration", mime);
     }
-    info.duration_us = duration;
+    info->duration_us = duration;
 
     int32_t brate = -1;
     if (!meta->findInt32(kKeyBitRate, &brate)) {
         ALOGV("track of type '%s' does not publish bitrate", mime);
     }
-    info.bit_rate = brate;
+    info->bit_rate = brate;
 
 
-    info.stream_type = streamType;
-    info.has_video = hasVideo;
-    info.is_streaming = isStreaming;
+    info->stream_type = streamType;
+    info->has_video = hasVideo;
+    info->is_streaming = isStreaming;
+    return OK;
+}
 
+bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo,
+                      bool isStreaming, audio_stream_type_t streamType)
+{
+    audio_offload_info_t info = AUDIO_INFO_INITIALIZER;
+    if (OK != getAudioOffloadInfo(meta, hasVideo, isStreaming, streamType, &info)) {
+        return false;
+    }
     // Check if offload is possible for given format, stream type, sample rate,
     // bit rate, duration, video and streaming
     return AudioSystem::isOffloadSupported(info);
@@ -1738,7 +2134,7 @@
 
 HLSTime::HLSTime(const sp<AMessage>& meta) :
     mSeq(-1),
-    mTimeUs(-1ll),
+    mTimeUs(-1LL),
     mMeta(meta) {
     if (meta != NULL) {
         CHECK(meta->findInt32("discontinuitySeq", &mSeq));
@@ -1747,7 +2143,7 @@
 }
 
 int64_t HLSTime::getSegmentTimeUs() const {
-    int64_t segmentStartTimeUs = -1ll;
+    int64_t segmentStartTimeUs = -1LL;
     if (mMeta != NULL) {
         CHECK(mMeta->findInt64("segmentStartTimeUs", &segmentStartTimeUs));
 
@@ -1867,4 +2263,3 @@
 }
 
 }  // namespace android
-
diff --git a/media/libstagefright/VideoFrameScheduler.cpp b/media/libstagefright/VideoFrameScheduler.cpp
index 9020fc1..4e5b5e2 100644
--- a/media/libstagefright/VideoFrameScheduler.cpp
+++ b/media/libstagefright/VideoFrameScheduler.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,8 +19,7 @@
 #include <utils/Log.h>
 #define ATRACE_TAG ATRACE_TAG_VIDEO
 #include <utils/Trace.h>
-
-#include <sys/time.h>
+#include <utils/String16.h>
 
 #include <binder/IServiceManager.h>
 #include <gui/ISurfaceComposer.h>
@@ -32,321 +31,14 @@
 
 namespace android {
 
-static const nsecs_t kNanosIn1s = 1000000000;
-
-template<class T>
-static int compare(const T *lhs, const T *rhs) {
-    if (*lhs < *rhs) {
-        return -1;
-    } else if (*lhs > *rhs) {
-        return 1;
-    } else {
-        return 0;
-    }
-}
-
-/* ======================================================================= */
-/*                                   PLL                                   */
-/* ======================================================================= */
-
-static const size_t kMinSamplesToStartPrime = 3;
-static const size_t kMinSamplesToStopPrime = VideoFrameScheduler::kHistorySize;
-static const size_t kMinSamplesToEstimatePeriod = 3;
-static const size_t kMaxSamplesToEstimatePeriod = VideoFrameScheduler::kHistorySize;
-
-static const size_t kPrecision = 12;
-static const int64_t kErrorThreshold = (1 << (kPrecision * 2)) / 10;
-static const int64_t kMultiplesThresholdDiv = 4;            // 25%
-static const int64_t kReFitThresholdDiv = 100;              // 1%
-static const nsecs_t kMaxAllowedFrameSkip = kNanosIn1s;     // 1 sec
-static const nsecs_t kMinPeriod = kNanosIn1s / 120;         // 120Hz
-static const nsecs_t kRefitRefreshPeriod = 10 * kNanosIn1s; // 10 sec
-
-VideoFrameScheduler::PLL::PLL()
-    : mPeriod(-1),
-      mPhase(0),
-      mPrimed(false),
-      mSamplesUsedForPriming(0),
-      mLastTime(-1),
-      mNumSamples(0) {
-}
-
-void VideoFrameScheduler::PLL::reset(float fps) {
-    //test();
-
-    mSamplesUsedForPriming = 0;
-    mLastTime = -1;
-
-    // set up or reset video PLL
-    if (fps <= 0.f) {
-        mPeriod = -1;
-        mPrimed = false;
-    } else {
-        ALOGV("reset at %.1f fps", fps);
-        mPeriod = (nsecs_t)(1e9 / fps + 0.5);
-        mPrimed = true;
-    }
-
-    restart();
-}
-
-// reset PLL but keep previous period estimate
-void VideoFrameScheduler::PLL::restart() {
-    mNumSamples = 0;
-    mPhase = -1;
-}
-
-#if 0
-
-void VideoFrameScheduler::PLL::test() {
-    nsecs_t period = kNanosIn1s / 60;
-    mTimes[0] = 0;
-    mTimes[1] = period;
-    mTimes[2] = period * 3;
-    mTimes[3] = period * 4;
-    mTimes[4] = period * 7;
-    mTimes[5] = period * 8;
-    mTimes[6] = period * 10;
-    mTimes[7] = period * 12;
-    mNumSamples = 8;
-    int64_t a, b, err;
-    fit(0, period * 12 / 7, 8, &a, &b, &err);
-    // a = 0.8(5)+
-    // b = -0.14097(2)+
-    // err = 0.2750578(703)+
-    ALOGD("a=%lld (%.6f), b=%lld (%.6f), err=%lld (%.6f)",
-            (long long)a, (a / (float)(1 << kPrecision)),
-            (long long)b, (b / (float)(1 << kPrecision)),
-            (long long)err, (err / (float)(1 << (kPrecision * 2))));
-}
-
-#endif
-
-bool VideoFrameScheduler::PLL::fit(
-        nsecs_t phase, nsecs_t period, size_t numSamplesToUse,
-        int64_t *a, int64_t *b, int64_t *err) {
-    if (numSamplesToUse > mNumSamples) {
-        numSamplesToUse = mNumSamples;
-    }
-
-    if ((period >> kPrecision) == 0 ) {
-        ALOGW("Period is 0, or after including precision is 0 - would cause div0, returning");
-        return false;
-    }
-
-    int64_t sumX = 0;
-    int64_t sumXX = 0;
-    int64_t sumXY = 0;
-    int64_t sumYY = 0;
-    int64_t sumY = 0;
-
-    int64_t x = 0; // x usually is in [0..numSamplesToUse)
-    nsecs_t lastTime;
-    for (size_t i = 0; i < numSamplesToUse; i++) {
-        size_t ix = (mNumSamples - numSamplesToUse + i) % kHistorySize;
-        nsecs_t time = mTimes[ix];
-        if (i > 0) {
-            x += divRound(time - lastTime, period);
-        }
-        // y is usually in [-numSamplesToUse..numSamplesToUse+kRefitRefreshPeriod/kMinPeriod) << kPrecision
-        //   ideally in [0..numSamplesToUse), but shifted by -numSamplesToUse during
-        //   priming, and possibly shifted by up to kRefitRefreshPeriod/kMinPeriod
-        //   while we are not refitting.
-        int64_t y = divRound(time - phase, period >> kPrecision);
-        sumX += x;
-        sumY += y;
-        sumXX += x * x;
-        sumXY += x * y;
-        sumYY += y * y;
-        lastTime = time;
-    }
-
-    int64_t div   = (int64_t)numSamplesToUse * sumXX - sumX * sumX;
-    if (div == 0) {
-        return false;
-    }
-
-    int64_t a_nom = (int64_t)numSamplesToUse * sumXY - sumX * sumY;
-    int64_t b_nom = sumXX * sumY            - sumX * sumXY;
-    *a = divRound(a_nom, div);
-    *b = divRound(b_nom, div);
-    // don't use a and b directly as the rounding error is significant
-    *err = sumYY - divRound(a_nom * sumXY + b_nom * sumY, div);
-    ALOGV("fitting[%zu] a=%lld (%.6f), b=%lld (%.6f), err=%lld (%.6f)",
-            numSamplesToUse,
-            (long long)*a,   (*a / (float)(1 << kPrecision)),
-            (long long)*b,   (*b / (float)(1 << kPrecision)),
-            (long long)*err, (*err / (float)(1 << (kPrecision * 2))));
-    return true;
-}
-
-void VideoFrameScheduler::PLL::prime(size_t numSamplesToUse) {
-    if (numSamplesToUse > mNumSamples) {
-        numSamplesToUse = mNumSamples;
-    }
-    CHECK(numSamplesToUse >= 3);  // must have at least 3 samples
-
-    // estimate video framerate from deltas between timestamps, and
-    // 2nd order deltas
-    Vector<nsecs_t> deltas;
-    nsecs_t lastTime, firstTime;
-    for (size_t i = 0; i < numSamplesToUse; ++i) {
-        size_t index = (mNumSamples - numSamplesToUse + i) % kHistorySize;
-        nsecs_t time = mTimes[index];
-        if (i > 0) {
-            if (time - lastTime > kMinPeriod) {
-                //ALOGV("delta: %lld", (long long)(time - lastTime));
-                deltas.push(time - lastTime);
-            }
-        } else {
-            firstTime = time;
-        }
-        lastTime = time;
-    }
-    deltas.sort(compare<nsecs_t>);
-    size_t numDeltas = deltas.size();
-    if (numDeltas > 1) {
-        nsecs_t deltaMinLimit = max(deltas[0] / kMultiplesThresholdDiv, kMinPeriod);
-        nsecs_t deltaMaxLimit = deltas[numDeltas / 2] * kMultiplesThresholdDiv;
-        for (size_t i = numDeltas / 2 + 1; i < numDeltas; ++i) {
-            if (deltas[i] > deltaMaxLimit) {
-                deltas.resize(i);
-                numDeltas = i;
-                break;
-            }
-        }
-        for (size_t i = 1; i < numDeltas; ++i) {
-            nsecs_t delta2nd = deltas[i] - deltas[i - 1];
-            if (delta2nd >= deltaMinLimit) {
-                //ALOGV("delta2: %lld", (long long)(delta2nd));
-                deltas.push(delta2nd);
-            }
-        }
-    }
-
-    // use the one that yields the best match
-    int64_t bestScore;
-    for (size_t i = 0; i < deltas.size(); ++i) {
-        nsecs_t delta = deltas[i];
-        int64_t score = 0;
-#if 1
-        // simplest score: number of deltas that are near multiples
-        size_t matches = 0;
-        for (size_t j = 0; j < deltas.size(); ++j) {
-            nsecs_t err = periodicError(deltas[j], delta);
-            if (err < delta / kMultiplesThresholdDiv) {
-                ++matches;
-            }
-        }
-        score = matches;
-#if 0
-        // could be weighed by the (1 - normalized error)
-        if (numSamplesToUse >= kMinSamplesToEstimatePeriod) {
-            int64_t a, b, err;
-            fit(firstTime, delta, numSamplesToUse, &a, &b, &err);
-            err = (1 << (2 * kPrecision)) - err;
-            score *= max(0, err);
-        }
-#endif
-#else
-        // or use the error as a negative score
-        if (numSamplesToUse >= kMinSamplesToEstimatePeriod) {
-            int64_t a, b, err;
-            fit(firstTime, delta, numSamplesToUse, &a, &b, &err);
-            score = -delta * err;
-        }
-#endif
-        if (i == 0 || score > bestScore) {
-            bestScore = score;
-            mPeriod = delta;
-            mPhase = firstTime;
-        }
-    }
-    ALOGV("priming[%zu] phase:%lld period:%lld",
-            numSamplesToUse, (long long)mPhase, (long long)mPeriod);
-}
-
-nsecs_t VideoFrameScheduler::PLL::addSample(nsecs_t time) {
-    if (mLastTime >= 0
-            // if time goes backward, or we skipped rendering
-            && (time > mLastTime + kMaxAllowedFrameSkip || time < mLastTime)) {
-        restart();
-    }
-
-    mLastTime = time;
-    mTimes[mNumSamples % kHistorySize] = time;
-    ++mNumSamples;
-
-    bool doFit = time > mRefitAt;
-    if ((mPeriod <= 0 || !mPrimed) && mNumSamples >= kMinSamplesToStartPrime) {
-        prime(kMinSamplesToStopPrime);
-        ++mSamplesUsedForPriming;
-        doFit = true;
-    }
-    if (mPeriod > 0 && mNumSamples >= kMinSamplesToEstimatePeriod) {
-        if (mPhase < 0) {
-            // initialize phase to the current render time
-            mPhase = time;
-            doFit = true;
-        } else if (!doFit) {
-            int64_t err = periodicError(time - mPhase, mPeriod);
-            doFit = err > mPeriod / kReFitThresholdDiv;
-        }
-
-        if (doFit) {
-            int64_t a, b, err;
-            if (!fit(mPhase, mPeriod, kMaxSamplesToEstimatePeriod, &a, &b, &err)) {
-                // samples are not suitable for fitting.  this means they are
-                // also not suitable for priming.
-                ALOGV("could not fit - keeping old period:%lld", (long long)mPeriod);
-                return mPeriod;
-            }
-
-            mRefitAt = time + kRefitRefreshPeriod;
-
-            mPhase += (mPeriod * b) >> kPrecision;
-            mPeriod = (mPeriod * a) >> kPrecision;
-            ALOGV("new phase:%lld period:%lld", (long long)mPhase, (long long)mPeriod);
-
-            if (err < kErrorThreshold) {
-                if (!mPrimed && mSamplesUsedForPriming >= kMinSamplesToStopPrime) {
-                    mPrimed = true;
-                }
-            } else {
-                mPrimed = false;
-                mSamplesUsedForPriming = 0;
-            }
-        }
-    }
-    return mPeriod;
-}
-
-nsecs_t VideoFrameScheduler::PLL::getPeriod() const {
-    return mPrimed ? mPeriod : 0;
-}
-
-/* ======================================================================= */
-/*                             Frame Scheduler                             */
-/* ======================================================================= */
-
-static const nsecs_t kDefaultVsyncPeriod = kNanosIn1s / 60;  // 60Hz
-static const nsecs_t kVsyncRefreshPeriod = kNanosIn1s;       // 1 sec
-
-VideoFrameScheduler::VideoFrameScheduler()
-    : mVsyncTime(0),
-      mVsyncPeriod(0),
-      mVsyncRefreshAt(0),
-      mLastVsyncTime(-1),
-      mTimeCorrection(0) {
+VideoFrameScheduler::VideoFrameScheduler() : VideoFrameSchedulerBase() {
 }
 
 void VideoFrameScheduler::updateVsync() {
     mVsyncRefreshAt = systemTime(SYSTEM_TIME_MONOTONIC) + kVsyncRefreshPeriod;
-    mVsyncPeriod = 0;
     mVsyncTime = 0;
+    mVsyncPeriod = 0;
 
-    // TODO: schedule frames for the destination surface
-    // For now, surface flinger only schedules frames on the primary display
     if (mComposer == NULL) {
         String16 name("SurfaceFlinger");
         sp<IServiceManager> sm = defaultServiceManager();
@@ -368,136 +60,6 @@
     }
 }
 
-void VideoFrameScheduler::init(float videoFps) {
-    updateVsync();
-
-    mLastVsyncTime = -1;
-    mTimeCorrection = 0;
-
-    mPll.reset(videoFps);
-}
-
-void VideoFrameScheduler::restart() {
-    mLastVsyncTime = -1;
-    mTimeCorrection = 0;
-
-    mPll.restart();
-}
-
-nsecs_t VideoFrameScheduler::getVsyncPeriod() {
-    if (mVsyncPeriod > 0) {
-        return mVsyncPeriod;
-    }
-    return kDefaultVsyncPeriod;
-}
-
-float VideoFrameScheduler::getFrameRate() {
-    nsecs_t videoPeriod = mPll.getPeriod();
-    if (videoPeriod > 0) {
-        return 1e9 / videoPeriod;
-    }
-    return 0.f;
-}
-
-nsecs_t VideoFrameScheduler::schedule(nsecs_t renderTime) {
-    nsecs_t origRenderTime = renderTime;
-
-    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
-    if (now >= mVsyncRefreshAt) {
-        updateVsync();
-    }
-
-    // without VSYNC info, there is nothing to do
-    if (mVsyncPeriod == 0) {
-        ALOGV("no vsync: render=%lld", (long long)renderTime);
-        return renderTime;
-    }
-
-    // ensure vsync time is well before (corrected) render time
-    if (mVsyncTime > renderTime - 4 * mVsyncPeriod) {
-        mVsyncTime -=
-            ((mVsyncTime - renderTime) / mVsyncPeriod + 5) * mVsyncPeriod;
-    }
-
-    // Video presentation takes place at the VSYNC _after_ renderTime.  Adjust renderTime
-    // so this effectively becomes a rounding operation (to the _closest_ VSYNC.)
-    renderTime -= mVsyncPeriod / 2;
-
-    const nsecs_t videoPeriod = mPll.addSample(origRenderTime);
-    if (videoPeriod > 0) {
-        // Smooth out rendering
-        size_t N = 12;
-        nsecs_t fiveSixthDev =
-            abs(((videoPeriod * 5 + mVsyncPeriod) % (mVsyncPeriod * 6)) - mVsyncPeriod)
-                    / (mVsyncPeriod / 100);
-        // use 20 samples if we are doing 5:6 ratio +- 1% (e.g. playing 50Hz on 60Hz)
-        if (fiveSixthDev < 12) {  /* 12% / 6 = 2% */
-            N = 20;
-        }
-
-        nsecs_t offset = 0;
-        nsecs_t edgeRemainder = 0;
-        for (size_t i = 1; i <= N; i++) {
-            offset +=
-                (renderTime + mTimeCorrection + videoPeriod * i - mVsyncTime) % mVsyncPeriod;
-            edgeRemainder += (videoPeriod * i) % mVsyncPeriod;
-        }
-        mTimeCorrection += mVsyncPeriod / 2 - offset / (nsecs_t)N;
-        renderTime += mTimeCorrection;
-        nsecs_t correctionLimit = mVsyncPeriod * 3 / 5;
-        edgeRemainder = abs(edgeRemainder / (nsecs_t)N - mVsyncPeriod / 2);
-        if (edgeRemainder <= mVsyncPeriod / 3) {
-            correctionLimit /= 2;
-        }
-
-        // estimate how many VSYNCs a frame will spend on the display
-        nsecs_t nextVsyncTime =
-            renderTime + mVsyncPeriod - ((renderTime - mVsyncTime) % mVsyncPeriod);
-        if (mLastVsyncTime >= 0) {
-            size_t minVsyncsPerFrame = videoPeriod / mVsyncPeriod;
-            size_t vsyncsForLastFrame = divRound(nextVsyncTime - mLastVsyncTime, mVsyncPeriod);
-            bool vsyncsPerFrameAreNearlyConstant =
-                periodicError(videoPeriod, mVsyncPeriod) / (mVsyncPeriod / 20) == 0;
-
-            if (mTimeCorrection > correctionLimit &&
-                    (vsyncsPerFrameAreNearlyConstant || vsyncsForLastFrame > minVsyncsPerFrame)) {
-                // remove a VSYNC
-                mTimeCorrection -= mVsyncPeriod / 2;
-                renderTime -= mVsyncPeriod / 2;
-                nextVsyncTime -= mVsyncPeriod;
-                if (vsyncsForLastFrame > 0)
-                    --vsyncsForLastFrame;
-            } else if (mTimeCorrection < -correctionLimit &&
-                    (vsyncsPerFrameAreNearlyConstant || vsyncsForLastFrame == minVsyncsPerFrame)) {
-                // add a VSYNC
-                mTimeCorrection += mVsyncPeriod / 2;
-                renderTime += mVsyncPeriod / 2;
-                nextVsyncTime += mVsyncPeriod;
-                if (vsyncsForLastFrame < ULONG_MAX)
-                    ++vsyncsForLastFrame;
-            } else if (mTimeCorrection < -correctionLimit * 2
-                    || mTimeCorrection > correctionLimit * 2) {
-                ALOGW("correction beyond limit: %lld vs %lld (vsyncs for last frame: %zu, min: %zu)"
-                        " restarting. render=%lld",
-                        (long long)mTimeCorrection, (long long)correctionLimit,
-                        vsyncsForLastFrame, minVsyncsPerFrame, (long long)origRenderTime);
-                restart();
-                return origRenderTime;
-            }
-
-            ATRACE_INT("FRAME_VSYNCS", vsyncsForLastFrame);
-        }
-        mLastVsyncTime = nextVsyncTime;
-    }
-
-    // align rendertime to the center between VSYNC edges
-    renderTime -= (renderTime - mVsyncTime) % mVsyncPeriod;
-    renderTime += mVsyncPeriod / 2;
-    ALOGV("adjusting render: %lld => %lld", (long long)origRenderTime, (long long)renderTime);
-    ATRACE_INT("FRAME_FLIP_IN(ms)", (renderTime - now) / 1000000);
-    return renderTime;
-}
-
 void VideoFrameScheduler::release() {
     mComposer.clear();
 }
@@ -507,4 +69,3 @@
 }
 
 } // namespace android
-
diff --git a/media/libstagefright/VideoFrameScheduler2.cpp b/media/libstagefright/VideoFrameScheduler2.cpp
new file mode 100644
index 0000000..23671f2
--- /dev/null
+++ b/media/libstagefright/VideoFrameScheduler2.cpp
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "VideoFrameScheduler2"
+#include <utils/Log.h>
+#define ATRACE_TAG ATRACE_TAG_VIDEO
+#include <utils/Mutex.h>
+#include <utils/Thread.h>
+#include <utils/Trace.h>
+
+#include <algorithm>
+#include <jni.h>
+#include <math.h>
+
+#include <android/choreographer.h>
+#include <android/looper.h>
+#include <media/stagefright/VideoFrameScheduler2.h>
+#include <mediaplayer2/JavaVMHelper.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AUtils.h>
+
+namespace android {
+
+static void getVsyncOffset(nsecs_t* appVsyncOffsetPtr, nsecs_t* sfVsyncOffsetPtr);
+
+/* ======================================================================= */
+/*                               VsyncTracker                              */
+/* ======================================================================= */
+
+class VsyncTracker : public RefBase{
+public:
+    VsyncTracker();
+    ~VsyncTracker() {}
+    nsecs_t getVsyncPeriod();
+    nsecs_t getVsyncTime(nsecs_t periodOffset);
+    void addSample(nsecs_t timestamp);
+
+private:
+    static const int kMaxSamples = 32;
+    static const int kMinSamplesForUpdate = 6;
+    int mNumSamples;
+    int mFirstSample;
+    nsecs_t mReferenceTime;
+    nsecs_t mPhase;
+    nsecs_t mPeriod;
+    nsecs_t mTimestampSamples[kMaxSamples];
+    Mutex mLock;
+
+    void updateModelLocked();
+};
+
+VsyncTracker::VsyncTracker()
+    : mNumSamples(0),
+      mFirstSample(0),
+      mReferenceTime(0),
+      mPhase(0),
+      mPeriod(0) {
+    for (int i = 0; i < kMaxSamples; i++) {
+        mTimestampSamples[i] = 0;
+    }
+}
+
+nsecs_t VsyncTracker::getVsyncPeriod() {
+    Mutex::Autolock dataLock(mLock);
+    return mPeriod;
+}
+
+nsecs_t VsyncTracker::getVsyncTime(nsecs_t periodOffset) {
+    Mutex::Autolock dataLock(mLock);
+    const nsecs_t now = systemTime();
+    nsecs_t phase = mReferenceTime + mPhase;
+
+    // result = (((now - phase) / mPeriod) + periodOffset + 1) * mPeriod + phase
+    // prevent overflow
+    nsecs_t result = (now - phase) / mPeriod;
+    if (result > LONG_LONG_MAX - periodOffset - 1) {
+        return LONG_LONG_MAX;
+    } else {
+        result += periodOffset + 1;
+    }
+    if (result > LONG_LONG_MAX / mPeriod) {
+        return LONG_LONG_MAX;
+    } else {
+        result *= mPeriod;
+    }
+    if (result > LONG_LONG_MAX - phase) {
+        return LONG_LONG_MAX;
+    } else {
+        result += phase;
+    }
+
+    return result;
+}
+
+void VsyncTracker::addSample(nsecs_t timestamp) {
+    Mutex::Autolock dataLock(mLock);
+    if (mNumSamples == 0) {
+        mPhase = 0;
+        mReferenceTime = timestamp;
+    }
+    int idx = (mFirstSample + mNumSamples) % kMaxSamples;
+    mTimestampSamples[idx] = timestamp;
+    if (mNumSamples < kMaxSamples) {
+        mNumSamples++;
+    } else {
+        mFirstSample = (mFirstSample + 1) % kMaxSamples;
+    }
+    updateModelLocked();
+}
+
+void VsyncTracker::updateModelLocked() {
+    if (mNumSamples < kMinSamplesForUpdate) {
+        return;
+    }
+    nsecs_t durationSum = 0;
+    nsecs_t minDuration = LONG_MAX;
+    nsecs_t maxDuration = 0;
+
+    for (int i = 1; i < mNumSamples; i++) {
+        int idx = (mFirstSample + i) % kMaxSamples;
+        int prev = (idx + kMaxSamples - 1) % kMaxSamples;
+        long duration = mTimestampSamples[idx] - mTimestampSamples[prev];
+        durationSum += duration;
+        if (minDuration > duration) { minDuration = duration; }
+        if (maxDuration < duration) { maxDuration = duration; }
+    }
+
+    durationSum -= (minDuration + maxDuration);
+    mPeriod = durationSum / (mNumSamples - 3);
+
+    double sampleAvgX = 0.0;
+    double sampleAvgY = 0.0;
+    double scale = 2.0 * M_PI / (double) mPeriod;
+
+    for (int i = 1; i < mNumSamples; i++) {
+        int idx = (mFirstSample + i) % kMaxSamples;
+        long sample = mTimestampSamples[idx] - mReferenceTime;
+        double samplePhase = (double) (sample % mPeriod) * scale;
+        sampleAvgX += cos(samplePhase);
+        sampleAvgY += sin(samplePhase);
+    }
+
+    sampleAvgX /= (double) mNumSamples - 1.0;
+    sampleAvgY /= (double) mNumSamples - 1.0;
+    mPhase = (long) (atan2(sampleAvgY, sampleAvgX) / scale);
+}
+
+static void frameCallback(int64_t frameTimeNanos, void* data) {
+    if (data == NULL) {
+        return;
+    }
+    sp<VsyncTracker> vsyncTracker(static_cast<VsyncTracker*>(data));
+    vsyncTracker->addSample(frameTimeNanos);
+    AChoreographer_postFrameCallback64(AChoreographer_getInstance(),
+            frameCallback, static_cast<void*>(vsyncTracker.get()));
+}
+
+/* ======================================================================= */
+/*                                   JNI                                   */
+/* ======================================================================= */
+
+static void getVsyncOffset(nsecs_t* appVsyncOffsetPtr, nsecs_t* sfVsyncOffsetPtr) {
+    static const nsecs_t kOneMillisecInNanosec = 1000000;
+    static const nsecs_t kOneSecInNanosec = kOneMillisecInNanosec * 1000;
+
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
+    jclass jDisplayManagerGlobalCls = env->FindClass(
+            "android/hardware/display/DisplayManagerGlobal");
+    jclass jDisplayCls = env->FindClass("android/view/Display");
+
+    jmethodID jGetInstance = env->GetStaticMethodID(jDisplayManagerGlobalCls,
+            "getInstance", "()Landroid/hardware/display/DisplayManagerGlobal;");
+    jobject javaDisplayManagerGlobalObj = env->CallStaticObjectMethod(
+            jDisplayManagerGlobalCls, jGetInstance);
+
+    jfieldID jDEFAULT_DISPLAY = env->GetStaticFieldID(jDisplayCls, "DEFAULT_DISPLAY", "I");
+    jint DEFAULT_DISPLAY = env->GetStaticIntField(jDisplayCls, jDEFAULT_DISPLAY);
+
+    jmethodID jgetRealDisplay = env->GetMethodID(jDisplayManagerGlobalCls,
+            "getRealDisplay", "(I)Landroid/view/Display;");
+    jobject javaDisplayObj = env->CallObjectMethod(
+            javaDisplayManagerGlobalObj, jgetRealDisplay, DEFAULT_DISPLAY);
+
+    jmethodID jGetRefreshRate = env->GetMethodID(jDisplayCls, "getRefreshRate", "()F");
+    jfloat javaRefreshRate = env->CallFloatMethod(javaDisplayObj, jGetRefreshRate);
+    nsecs_t vsyncPeriod = (nsecs_t) (kOneSecInNanosec / (float) javaRefreshRate);
+
+    jmethodID jGetAppVsyncOffsetNanos = env->GetMethodID(
+            jDisplayCls, "getAppVsyncOffsetNanos", "()J");
+    jlong javaAppVsyncOffset = env->CallLongMethod(javaDisplayObj, jGetAppVsyncOffsetNanos);
+    *appVsyncOffsetPtr = (nsecs_t) javaAppVsyncOffset;
+
+    jmethodID jGetPresentationDeadlineNanos = env->GetMethodID(
+            jDisplayCls, "getPresentationDeadlineNanos", "()J");
+    jlong javaPresentationDeadline = env->CallLongMethod(
+            javaDisplayObj, jGetPresentationDeadlineNanos);
+
+    *sfVsyncOffsetPtr = vsyncPeriod - ((nsecs_t) javaPresentationDeadline - kOneMillisecInNanosec);
+}
+
+/* ======================================================================= */
+/*                          Choreographer Thread                           */
+/* ======================================================================= */
+
+struct ChoreographerThread : public Thread {
+    ChoreographerThread(bool canCallJava);
+    status_t init(void* data);
+    virtual status_t readyToRun() override;
+    virtual bool threadLoop() override;
+
+protected:
+    virtual ~ChoreographerThread() {}
+
+private:
+    DISALLOW_EVIL_CONSTRUCTORS(ChoreographerThread);
+    void* mData;
+};
+
+ChoreographerThread::ChoreographerThread(bool canCallJava) : Thread(canCallJava) {
+}
+
+status_t ChoreographerThread::init(void* data) {
+    if (data == NULL) {
+        return NO_INIT;
+    }
+    mData = data;
+    return OK;
+}
+
+status_t ChoreographerThread::readyToRun() {
+    ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
+    if (AChoreographer_getInstance() == NULL) {
+        return NO_INIT;
+    }
+    AChoreographer_postFrameCallback64(AChoreographer_getInstance(), frameCallback, mData);
+    return OK;
+}
+
+bool ChoreographerThread::threadLoop() {
+    ALooper_pollOnce(-1, nullptr, nullptr, nullptr);
+    return true;
+}
+
+/* ======================================================================= */
+/*                             Frame Scheduler                             */
+/* ======================================================================= */
+
+VideoFrameScheduler2::VideoFrameScheduler2() : VideoFrameSchedulerBase() {
+
+    getVsyncOffset(&mAppVsyncOffset, &mSfVsyncOffset);
+
+    Mutex::Autolock threadLock(mLock);
+    mChoreographerThread = new ChoreographerThread(true);
+
+    mVsyncTracker = new VsyncTracker();
+    if (mChoreographerThread->init(static_cast<void*>(mVsyncTracker.get())) != OK) {
+        mChoreographerThread.clear();
+    }
+    if (mChoreographerThread != NULL && mChoreographerThread->run("Choreographer") != OK) {
+        mChoreographerThread.clear();
+    }
+}
+
+void VideoFrameScheduler2::updateVsync() {
+    mVsyncTime = 0;
+    mVsyncPeriod = 0;
+
+    if (mVsyncTracker != NULL) {
+        mVsyncPeriod = mVsyncTracker->getVsyncPeriod();
+        mVsyncTime = mVsyncTracker->getVsyncTime(mSfVsyncOffset - mAppVsyncOffset);
+    }
+    mVsyncRefreshAt = systemTime(SYSTEM_TIME_MONOTONIC) + kVsyncRefreshPeriod;
+}
+
+void VideoFrameScheduler2::release() {
+    // Do not change order
+    {
+        Mutex::Autolock threadLock(mLock);
+        mChoreographerThread->requestExitAndWait();
+        mChoreographerThread.clear();
+    }
+
+    mVsyncTracker.clear();
+}
+
+VideoFrameScheduler2::~VideoFrameScheduler2() {
+    release();
+}
+
+} // namespace android
diff --git a/media/libstagefright/VideoFrameSchedulerBase.cpp b/media/libstagefright/VideoFrameSchedulerBase.cpp
new file mode 100644
index 0000000..0d1517b
--- /dev/null
+++ b/media/libstagefright/VideoFrameSchedulerBase.cpp
@@ -0,0 +1,469 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "VideoFrameSchedulerBase"
+#include <utils/Log.h>
+#define ATRACE_TAG ATRACE_TAG_VIDEO
+#include <utils/Trace.h>
+#include <utils/Vector.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AUtils.h>
+#include <media/stagefright/VideoFrameSchedulerBase.h>
+
+namespace android {
+
+template<class T>
+static int compare(const T *lhs, const T *rhs) {
+    if (*lhs < *rhs) {
+        return -1;
+    } else if (*lhs > *rhs) {
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+/* ======================================================================= */
+/*                                   PLL                                   */
+/* ======================================================================= */
+
+static const size_t kMinSamplesToStartPrime = 3;
+static const size_t kMinSamplesToStopPrime = VideoFrameSchedulerBase::kHistorySize;
+static const size_t kMinSamplesToEstimatePeriod = 3;
+static const size_t kMaxSamplesToEstimatePeriod = VideoFrameSchedulerBase::kHistorySize;
+
+static const size_t kPrecision = 12;
+static const int64_t kErrorThreshold = (1 << (kPrecision * 2)) / 10;
+static const int64_t kMultiplesThresholdDiv = 4;                                     // 25%
+static const int64_t kReFitThresholdDiv = 100;                                       // 1%
+static const nsecs_t kMaxAllowedFrameSkip = VideoFrameSchedulerBase::kNanosIn1s;     // 1 sec
+static const nsecs_t kMinPeriod = VideoFrameSchedulerBase::kNanosIn1s / 120;         // 120Hz
+static const nsecs_t kRefitRefreshPeriod = 10 * VideoFrameSchedulerBase::kNanosIn1s; // 10 sec
+
+VideoFrameSchedulerBase::PLL::PLL()
+    : mPeriod(-1),
+      mPhase(0),
+      mPrimed(false),
+      mSamplesUsedForPriming(0),
+      mLastTime(-1),
+      mNumSamples(0) {
+}
+
+void VideoFrameSchedulerBase::PLL::reset(float fps) {
+    //test();
+
+    mSamplesUsedForPriming = 0;
+    mLastTime = -1;
+
+    // set up or reset video PLL
+    if (fps <= 0.f) {
+        mPeriod = -1;
+        mPrimed = false;
+    } else {
+        ALOGV("reset at %.1f fps", fps);
+        mPeriod = (nsecs_t)(1e9 / fps + 0.5);
+        mPrimed = true;
+    }
+
+    restart();
+}
+
+// reset PLL but keep previous period estimate
+void VideoFrameSchedulerBase::PLL::restart() {
+    mNumSamples = 0;
+    mPhase = -1;
+}
+
+#if 0
+
+void VideoFrameSchedulerBase::PLL::test() {
+    nsecs_t period = VideoFrameSchedulerBase::kNanosIn1s / 60;
+    mTimes[0] = 0;
+    mTimes[1] = period;
+    mTimes[2] = period * 3;
+    mTimes[3] = period * 4;
+    mTimes[4] = period * 7;
+    mTimes[5] = period * 8;
+    mTimes[6] = period * 10;
+    mTimes[7] = period * 12;
+    mNumSamples = 8;
+    int64_t a, b, err;
+    fit(0, period * 12 / 7, 8, &a, &b, &err);
+    // a = 0.8(5)+
+    // b = -0.14097(2)+
+    // err = 0.2750578(703)+
+    ALOGD("a=%lld (%.6f), b=%lld (%.6f), err=%lld (%.6f)",
+            (long long)a, (a / (float)(1 << kPrecision)),
+            (long long)b, (b / (float)(1 << kPrecision)),
+            (long long)err, (err / (float)(1 << (kPrecision * 2))));
+}
+
+#endif
+
+// If overflow happens, the value is already incorrect, and no mater what value we get is OK.
+// And this part of calculation is not important, so it's OK to simply disable overflow check
+// instead of using double which makes code more complicated.
+__attribute__((no_sanitize("integer")))
+bool VideoFrameSchedulerBase::PLL::fit(
+        nsecs_t phase, nsecs_t period, size_t numSamplesToUse,
+        int64_t *a, int64_t *b, int64_t *err) {
+    if (numSamplesToUse > mNumSamples) {
+        numSamplesToUse = mNumSamples;
+    }
+
+    if ((period >> kPrecision) == 0 ) {
+        ALOGW("Period is 0, or after including precision is 0 - would cause div0, returning");
+        return false;
+    }
+
+    int64_t sumX = 0;
+    int64_t sumXX = 0;
+    int64_t sumXY = 0;
+    int64_t sumYY = 0;
+    int64_t sumY = 0;
+
+    int64_t x = 0; // x usually is in [0..numSamplesToUse)
+    nsecs_t lastTime;
+    for (size_t i = 0; i < numSamplesToUse; i++) {
+        size_t ix = (mNumSamples - numSamplesToUse + i) % kHistorySize;
+        nsecs_t time = mTimes[ix];
+        if (i > 0) {
+            x += divRound(time - lastTime, period);
+        }
+        // y is usually in [-numSamplesToUse..numSamplesToUse+kRefitRefreshPeriod/kMinPeriod) << kPrecision
+        //   ideally in [0..numSamplesToUse), but shifted by -numSamplesToUse during
+        //   priming, and possibly shifted by up to kRefitRefreshPeriod/kMinPeriod
+        //   while we are not refitting.
+        int64_t y = divRound(time - phase, period >> kPrecision);
+        sumX += x;
+        sumY += y;
+        sumXX += x * x;
+        sumXY += x * y;
+        sumYY += y * y;
+        lastTime = time;
+    }
+
+    int64_t div   = (int64_t)numSamplesToUse * sumXX - sumX * sumX;
+    if (div == 0) {
+        return false;
+    }
+
+    int64_t a_nom = (int64_t)numSamplesToUse * sumXY - sumX * sumY;
+    int64_t b_nom = sumXX * sumY            - sumX * sumXY;
+    *a = divRound(a_nom, div);
+    *b = divRound(b_nom, div);
+    // don't use a and b directly as the rounding error is significant
+    *err = sumYY - divRound(a_nom * sumXY + b_nom * sumY, div);
+    ALOGV("fitting[%zu] a=%lld (%.6f), b=%lld (%.6f), err=%lld (%.6f)",
+            numSamplesToUse,
+            (long long)*a,   (*a / (float)(1 << kPrecision)),
+            (long long)*b,   (*b / (float)(1 << kPrecision)),
+            (long long)*err, (*err / (float)(1 << (kPrecision * 2))));
+    return true;
+}
+
+void VideoFrameSchedulerBase::PLL::prime(size_t numSamplesToUse) {
+    if (numSamplesToUse > mNumSamples) {
+        numSamplesToUse = mNumSamples;
+    }
+    CHECK(numSamplesToUse >= 3);  // must have at least 3 samples
+
+    // estimate video framerate from deltas between timestamps, and
+    // 2nd order deltas
+    Vector<nsecs_t> deltas;
+    nsecs_t lastTime, firstTime;
+    for (size_t i = 0; i < numSamplesToUse; ++i) {
+        size_t index = (mNumSamples - numSamplesToUse + i) % kHistorySize;
+        nsecs_t time = mTimes[index];
+        if (i > 0) {
+            if (time - lastTime > kMinPeriod) {
+                //ALOGV("delta: %lld", (long long)(time - lastTime));
+                deltas.push(time - lastTime);
+            }
+        } else {
+            firstTime = time;
+        }
+        lastTime = time;
+    }
+    deltas.sort(compare<nsecs_t>);
+    size_t numDeltas = deltas.size();
+    if (numDeltas > 1) {
+        nsecs_t deltaMinLimit = max(deltas[0] / kMultiplesThresholdDiv, kMinPeriod);
+        nsecs_t deltaMaxLimit = deltas[numDeltas / 2] * kMultiplesThresholdDiv;
+        for (size_t i = numDeltas / 2 + 1; i < numDeltas; ++i) {
+            if (deltas[i] > deltaMaxLimit) {
+                deltas.resize(i);
+                numDeltas = i;
+                break;
+            }
+        }
+        for (size_t i = 1; i < numDeltas; ++i) {
+            nsecs_t delta2nd = deltas[i] - deltas[i - 1];
+            if (delta2nd >= deltaMinLimit) {
+                //ALOGV("delta2: %lld", (long long)(delta2nd));
+                deltas.push(delta2nd);
+            }
+        }
+    }
+
+    // use the one that yields the best match
+    int64_t bestScore;
+    for (size_t i = 0; i < deltas.size(); ++i) {
+        nsecs_t delta = deltas[i];
+        int64_t score = 0;
+#if 1
+        // simplest score: number of deltas that are near multiples
+        size_t matches = 0;
+        for (size_t j = 0; j < deltas.size(); ++j) {
+            nsecs_t err = periodicError(deltas[j], delta);
+            if (err < delta / kMultiplesThresholdDiv) {
+                ++matches;
+            }
+        }
+        score = matches;
+#if 0
+        // could be weighed by the (1 - normalized error)
+        if (numSamplesToUse >= kMinSamplesToEstimatePeriod) {
+            int64_t a, b, err;
+            fit(firstTime, delta, numSamplesToUse, &a, &b, &err);
+            err = (1 << (2 * kPrecision)) - err;
+            score *= max(0, err);
+        }
+#endif
+#else
+        // or use the error as a negative score
+        if (numSamplesToUse >= kMinSamplesToEstimatePeriod) {
+            int64_t a, b, err;
+            fit(firstTime, delta, numSamplesToUse, &a, &b, &err);
+            score = -delta * err;
+        }
+#endif
+        if (i == 0 || score > bestScore) {
+            bestScore = score;
+            mPeriod = delta;
+            mPhase = firstTime;
+        }
+    }
+    ALOGV("priming[%zu] phase:%lld period:%lld",
+            numSamplesToUse, (long long)mPhase, (long long)mPeriod);
+}
+
+nsecs_t VideoFrameSchedulerBase::PLL::addSample(nsecs_t time) {
+    if (mLastTime >= 0
+            // if time goes backward, or we skipped rendering
+            && (time > mLastTime + kMaxAllowedFrameSkip || time < mLastTime)) {
+        restart();
+    }
+
+    mLastTime = time;
+    mTimes[mNumSamples % kHistorySize] = time;
+    ++mNumSamples;
+
+    bool doFit = time > mRefitAt;
+    if ((mPeriod <= 0 || !mPrimed) && mNumSamples >= kMinSamplesToStartPrime) {
+        prime(kMinSamplesToStopPrime);
+        ++mSamplesUsedForPriming;
+        doFit = true;
+    }
+    if (mPeriod > 0 && mNumSamples >= kMinSamplesToEstimatePeriod) {
+        if (mPhase < 0) {
+            // initialize phase to the current render time
+            mPhase = time;
+            doFit = true;
+        } else if (!doFit) {
+            int64_t err = periodicError(time - mPhase, mPeriod);
+            doFit = err > mPeriod / kReFitThresholdDiv;
+        }
+
+        if (doFit) {
+            int64_t a, b, err;
+            if (!fit(mPhase, mPeriod, kMaxSamplesToEstimatePeriod, &a, &b, &err)) {
+                // samples are not suitable for fitting.  this means they are
+                // also not suitable for priming.
+                ALOGV("could not fit - keeping old period:%lld", (long long)mPeriod);
+                return mPeriod;
+            }
+
+            mRefitAt = time + kRefitRefreshPeriod;
+
+            mPhase += (mPeriod * b) >> kPrecision;
+            mPeriod = (mPeriod * a) >> kPrecision;
+            ALOGV("new phase:%lld period:%lld", (long long)mPhase, (long long)mPeriod);
+
+            if (err < kErrorThreshold) {
+                if (!mPrimed && mSamplesUsedForPriming >= kMinSamplesToStopPrime) {
+                    mPrimed = true;
+                }
+            } else {
+                mPrimed = false;
+                mSamplesUsedForPriming = 0;
+            }
+        }
+    }
+    return mPeriod;
+}
+
+nsecs_t VideoFrameSchedulerBase::PLL::getPeriod() const {
+    return mPrimed ? mPeriod : 0;
+}
+
+/* ======================================================================= */
+/*                             Frame Scheduler                             */
+/* ======================================================================= */
+
+VideoFrameSchedulerBase::VideoFrameSchedulerBase()
+    : mVsyncTime(0),
+      mVsyncPeriod(0),
+      mVsyncRefreshAt(0),
+      mLastVsyncTime(-1),
+      mTimeCorrection(0) {
+}
+
+void VideoFrameSchedulerBase::init(float videoFps) {
+    updateVsync();
+
+    mLastVsyncTime = -1;
+    mTimeCorrection = 0;
+
+    mPll.reset(videoFps);
+}
+
+void VideoFrameSchedulerBase::restart() {
+    mLastVsyncTime = -1;
+    mTimeCorrection = 0;
+
+    mPll.restart();
+}
+
+nsecs_t VideoFrameSchedulerBase::getVsyncPeriod() {
+    if (mVsyncPeriod > 0) {
+        return mVsyncPeriod;
+    }
+    return kDefaultVsyncPeriod;
+}
+
+float VideoFrameSchedulerBase::getFrameRate() {
+    nsecs_t videoPeriod = mPll.getPeriod();
+    if (videoPeriod > 0) {
+        return 1e9 / videoPeriod;
+    }
+    return 0.f;
+}
+
+nsecs_t VideoFrameSchedulerBase::schedule(nsecs_t renderTime) {
+    nsecs_t origRenderTime = renderTime;
+
+    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+    if (now >= mVsyncRefreshAt) {
+        updateVsync();
+    }
+
+    // without VSYNC info, there is nothing to do
+    if (mVsyncPeriod == 0) {
+        ALOGV("no vsync: render=%lld", (long long)renderTime);
+        return renderTime;
+    }
+
+    // ensure vsync time is well before (corrected) render time
+    if (mVsyncTime > renderTime - 4 * mVsyncPeriod) {
+        mVsyncTime -=
+            ((mVsyncTime - renderTime) / mVsyncPeriod + 5) * mVsyncPeriod;
+    }
+
+    // Video presentation takes place at the VSYNC _after_ renderTime.  Adjust renderTime
+    // so this effectively becomes a rounding operation (to the _closest_ VSYNC.)
+    renderTime -= mVsyncPeriod / 2;
+
+    const nsecs_t videoPeriod = mPll.addSample(origRenderTime);
+    if (videoPeriod > 0) {
+        // Smooth out rendering
+        size_t N = 12;
+        nsecs_t fiveSixthDev =
+            abs(((videoPeriod * 5 + mVsyncPeriod) % (mVsyncPeriod * 6)) - mVsyncPeriod)
+                    / (mVsyncPeriod / 100);
+        // use 20 samples if we are doing 5:6 ratio +- 1% (e.g. playing 50Hz on 60Hz)
+        if (fiveSixthDev < 12) {  /* 12% / 6 = 2% */
+            N = 20;
+        }
+
+        nsecs_t offset = 0;
+        nsecs_t edgeRemainder = 0;
+        for (size_t i = 1; i <= N; i++) {
+            offset +=
+                (renderTime + mTimeCorrection + videoPeriod * i - mVsyncTime) % mVsyncPeriod;
+            edgeRemainder += (videoPeriod * i) % mVsyncPeriod;
+        }
+        mTimeCorrection += mVsyncPeriod / 2 - offset / (nsecs_t)N;
+        renderTime += mTimeCorrection;
+        nsecs_t correctionLimit = mVsyncPeriod * 3 / 5;
+        edgeRemainder = abs(edgeRemainder / (nsecs_t)N - mVsyncPeriod / 2);
+        if (edgeRemainder <= mVsyncPeriod / 3) {
+            correctionLimit /= 2;
+        }
+
+        // estimate how many VSYNCs a frame will spend on the display
+        nsecs_t nextVsyncTime =
+            renderTime + mVsyncPeriod - ((renderTime - mVsyncTime) % mVsyncPeriod);
+        if (mLastVsyncTime >= 0) {
+            size_t minVsyncsPerFrame = videoPeriod / mVsyncPeriod;
+            size_t vsyncsForLastFrame = divRound(nextVsyncTime - mLastVsyncTime, mVsyncPeriod);
+            bool vsyncsPerFrameAreNearlyConstant =
+                periodicError(videoPeriod, mVsyncPeriod) / (mVsyncPeriod / 20) == 0;
+
+            if (mTimeCorrection > correctionLimit &&
+                    (vsyncsPerFrameAreNearlyConstant || vsyncsForLastFrame > minVsyncsPerFrame)) {
+                // remove a VSYNC
+                mTimeCorrection -= mVsyncPeriod / 2;
+                renderTime -= mVsyncPeriod / 2;
+                nextVsyncTime -= mVsyncPeriod;
+                if (vsyncsForLastFrame > 0)
+                    --vsyncsForLastFrame;
+            } else if (mTimeCorrection < -correctionLimit &&
+                    (vsyncsPerFrameAreNearlyConstant || vsyncsForLastFrame == minVsyncsPerFrame)) {
+                // add a VSYNC
+                mTimeCorrection += mVsyncPeriod / 2;
+                renderTime += mVsyncPeriod / 2;
+                nextVsyncTime += mVsyncPeriod;
+                if (vsyncsForLastFrame < ULONG_MAX)
+                    ++vsyncsForLastFrame;
+            } else if (mTimeCorrection < -correctionLimit * 2
+                    || mTimeCorrection > correctionLimit * 2) {
+                ALOGW("correction beyond limit: %lld vs %lld (vsyncs for last frame: %zu, min: %zu)"
+                        " restarting. render=%lld",
+                        (long long)mTimeCorrection, (long long)correctionLimit,
+                        vsyncsForLastFrame, minVsyncsPerFrame, (long long)origRenderTime);
+                restart();
+                return origRenderTime;
+            }
+
+            ATRACE_INT("FRAME_VSYNCS", vsyncsForLastFrame);
+        }
+        mLastVsyncTime = nextVsyncTime;
+    }
+
+    // align rendertime to the center between VSYNC edges
+    renderTime -= (renderTime - mVsyncTime) % mVsyncPeriod;
+    renderTime += mVsyncPeriod / 2;
+    ALOGV("adjusting render: %lld => %lld", (long long)origRenderTime, (long long)renderTime);
+    ATRACE_INT("FRAME_FLIP_IN(ms)", (renderTime - now) / 1000000);
+    return renderTime;
+}
+
+VideoFrameSchedulerBase::~VideoFrameSchedulerBase() {}
+
+} // namespace android
diff --git a/media/libstagefright/bqhelper/Android.bp b/media/libstagefright/bqhelper/Android.bp
index 4f46be7..db67034 100644
--- a/media/libstagefright/bqhelper/Android.bp
+++ b/media/libstagefright/bqhelper/Android.bp
@@ -4,12 +4,10 @@
     vndk: {
         enabled: true,
     },
-
+    double_loadable: true,
     srcs: [
-        "Conversion.cpp",
         "FrameDropper.cpp",
         "GraphicBufferSource.cpp",
-        "WProducerListener.cpp",
     ],
 
     export_include_dirs: [
@@ -25,10 +23,8 @@
     ],
 
     shared_libs: [
-        "libbase",
         "libbinder",
         "libcutils",
-        "libgui",
         "libhidlbase",
         "libhidlmemory",
         "libhidltransport",
@@ -38,14 +34,25 @@
         "libutils",
 
         "android.hardware.graphics.bufferqueue@1.0",
-
-        "libnativewindow", // TODO(b/62923479): use header library
+        // Following libs are from libgui_bufferqueue_static
+        "android.hardware.graphics.bufferqueue@2.0",
+        "android.hidl.token@1.0-utils",
+        "libbase",
+        "libEGL",
+        "libhwbinder",
+        "libnativewindow",
+        "libvndksupport",
+    ],
+    
+    static_libs: [
+        "libgui_bufferqueue_static"
     ],
 
     export_shared_lib_headers: [
-        "libgui",
         "libhidlmemory",
         "libstagefright_foundation",
+        "android.hardware.graphics.bufferqueue@1.0",
+        "android.hardware.graphics.bufferqueue@2.0",
     ],
 
     cflags: [
@@ -61,8 +68,5 @@
             "unsigned-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 }
diff --git a/media/libstagefright/bqhelper/Conversion.cpp b/media/libstagefright/bqhelper/Conversion.cpp
deleted file mode 100644
index ffed005..0000000
--- a/media/libstagefright/bqhelper/Conversion.cpp
+++ /dev/null
@@ -1,1542 +0,0 @@
-/*
- * Copyright 2018, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <media/stagefright/bqhelper/Conversion.h>
-
-namespace android {
-namespace conversion {
-
-// native_handle_t helper functions.
-
-/**
- * \brief Take an fd and create a native handle containing only the given fd.
- * The created handle will need to be deleted manually with
- * `native_handle_delete()`.
- *
- * \param[in] fd The source file descriptor (of type `int`).
- * \return The create `native_handle_t*` that contains the given \p fd. If the
- * supplied \p fd is negative, the created native handle will contain no file
- * descriptors.
- *
- * If the native handle cannot be created, the return value will be
- * `nullptr`.
- *
- * This function does not duplicate the file descriptor.
- */
-native_handle_t* native_handle_create_from_fd(int fd) {
-    if (fd < 2) {
-        return native_handle_create(0, 0);
-    }
-    native_handle_t* nh = native_handle_create(1, 0);
-    if (nh == nullptr) {
-        return nullptr;
-    }
-    nh->data[0] = fd;
-    return nh;
-}
-
-/**
- * \brief Extract a file descriptor from a native handle.
- *
- * \param[in] nh The source `native_handle_t*`.
- * \param[in] index The index of the file descriptor in \p nh to read from. This
- * input has the default value of `0`.
- * \return The `index`-th file descriptor in \p nh. If \p nh does not have
- * enough file descriptors, the returned value will be `-1`.
- *
- * This function does not duplicate the file descriptor.
- */
-int native_handle_read_fd(native_handle_t const* nh, int index) {
-    return ((nh == nullptr) || (nh->numFds == 0) ||
-            (nh->numFds <= index) || (index < 0)) ?
-            -1 : nh->data[index];
-}
-
-/**
- * Conversion functions
- * ====================
- *
- * There are two main directions of conversion:
- * - `inTargetType(...)`: Create a wrapper whose lifetime depends on the
- *   input. The wrapper has type `TargetType`.
- * - `toTargetType(...)`: Create a standalone object of type `TargetType` that
- *   corresponds to the input. The lifetime of the output does not depend on the
- *   lifetime of the input.
- * - `wrapIn(TargetType*, ...)`: Same as `inTargetType()`, but for `TargetType`
- *   that cannot be copied and/or moved efficiently, or when there are multiple
- *   output arguments.
- * - `convertTo(TargetType*, ...)`: Same as `toTargetType()`, but for
- *   `TargetType` that cannot be copied and/or moved efficiently, or when there
- *   are multiple output arguments.
- *
- * `wrapIn()` and `convertTo()` functions will take output arguments before
- * input arguments. Some of these functions might return a value to indicate
- * success or error.
- *
- * In converting or wrapping something as a Treble type that contains a
- * `hidl_handle`, `native_handle_t*` will need to be created and returned as
- * an additional output argument, hence only `wrapIn()` or `convertTo()` would
- * be available. The caller must call `native_handle_delete()` to deallocate the
- * returned native handle when it is no longer needed.
- *
- * For types that contain file descriptors, `inTargetType()` and `wrapAs()` do
- * not perform duplication of file descriptors, while `toTargetType()` and
- * `convertTo()` do.
- */
-
-/**
- * \brief Convert `Return<void>` to `binder::Status`.
- *
- * \param[in] t The source `Return<void>`.
- * \return The corresponding `binder::Status`.
- */
-// convert: Return<void> -> ::android::binder::Status
-::android::binder::Status toBinderStatus(
-        Return<void> const& t) {
-    return ::android::binder::Status::fromExceptionCode(
-            t.isOk() ? OK : UNKNOWN_ERROR,
-            t.description().c_str());
-}
-
-/**
- * \brief Convert `Return<void>` to `status_t`. This is for legacy binder calls.
- *
- * \param[in] t The source `Return<void>`.
- * \return The corresponding `status_t`.
- */
-// convert: Return<void> -> status_t
-status_t toStatusT(Return<void> const& t) {
-    return t.isOk() ? OK : UNKNOWN_ERROR;
-}
-
-/**
- * \brief Wrap `native_handle_t*` in `hidl_handle`.
- *
- * \param[in] nh The source `native_handle_t*`.
- * \return The `hidl_handle` that points to \p nh.
- */
-// wrap: native_handle_t* -> hidl_handle
-hidl_handle inHidlHandle(native_handle_t const* nh) {
-    return hidl_handle(nh);
-}
-
-/**
- * \brief Convert `int32_t` to `Dataspace`.
- *
- * \param[in] l The source `int32_t`.
- * \result The corresponding `Dataspace`.
- */
-// convert: int32_t -> Dataspace
-Dataspace toHardwareDataspace(int32_t l) {
-    return static_cast<Dataspace>(l);
-}
-
-/**
- * \brief Convert `Dataspace` to `int32_t`.
- *
- * \param[in] t The source `Dataspace`.
- * \result The corresponding `int32_t`.
- */
-// convert: Dataspace -> int32_t
-int32_t toRawDataspace(Dataspace const& t) {
-    return static_cast<int32_t>(t);
-}
-
-/**
- * \brief Wrap an opaque buffer inside a `hidl_vec<uint8_t>`.
- *
- * \param[in] l The pointer to the beginning of the opaque buffer.
- * \param[in] size The size of the buffer.
- * \return A `hidl_vec<uint8_t>` that points to the buffer.
- */
-// wrap: void*, size_t -> hidl_vec<uint8_t>
-hidl_vec<uint8_t> inHidlBytes(void const* l, size_t size) {
-    hidl_vec<uint8_t> t;
-    t.setToExternal(static_cast<uint8_t*>(const_cast<void*>(l)), size, false);
-    return t;
-}
-
-/**
- * \brief Create a `hidl_vec<uint8_t>` that is a copy of an opaque buffer.
- *
- * \param[in] l The pointer to the beginning of the opaque buffer.
- * \param[in] size The size of the buffer.
- * \return A `hidl_vec<uint8_t>` that is a copy of the input buffer.
- */
-// convert: void*, size_t -> hidl_vec<uint8_t>
-hidl_vec<uint8_t> toHidlBytes(void const* l, size_t size) {
-    hidl_vec<uint8_t> t;
-    t.resize(size);
-    uint8_t const* src = static_cast<uint8_t const*>(l);
-    std::copy(src, src + size, t.data());
-    return t;
-}
-
-/**
- * \brief Wrap `GraphicBuffer` in `AnwBuffer`.
- *
- * \param[out] t The wrapper of type `AnwBuffer`.
- * \param[in] l The source `GraphicBuffer`.
- */
-// wrap: GraphicBuffer -> AnwBuffer
-void wrapAs(AnwBuffer* t, GraphicBuffer const& l) {
-    t->attr.width = l.getWidth();
-    t->attr.height = l.getHeight();
-    t->attr.stride = l.getStride();
-    t->attr.format = static_cast<PixelFormat>(l.getPixelFormat());
-    t->attr.layerCount = l.getLayerCount();
-    t->attr.usage = l.getUsage();
-    t->attr.id = l.getId();
-    t->attr.generationNumber = l.getGenerationNumber();
-    t->nativeHandle = hidl_handle(l.handle);
-}
-
-/**
- * \brief Convert `AnwBuffer` to `GraphicBuffer`.
- *
- * \param[out] l The destination `GraphicBuffer`.
- * \param[in] t The source `AnwBuffer`.
- *
- * This function will duplicate all file descriptors in \p t.
- */
-// convert: AnwBuffer -> GraphicBuffer
-// Ref: frameworks/native/libs/ui/GraphicBuffer.cpp: GraphicBuffer::flatten
-bool convertTo(GraphicBuffer* l, AnwBuffer const& t) {
-    native_handle_t* handle = t.nativeHandle == nullptr ?
-            nullptr : native_handle_clone(t.nativeHandle);
-
-    size_t const numInts = 12 + (handle ? handle->numInts : 0);
-    int32_t* ints = new int32_t[numInts];
-
-    size_t numFds = static_cast<size_t>(handle ? handle->numFds : 0);
-    int* fds = new int[numFds];
-
-    ints[0] = 'GBFR';
-    ints[1] = static_cast<int32_t>(t.attr.width);
-    ints[2] = static_cast<int32_t>(t.attr.height);
-    ints[3] = static_cast<int32_t>(t.attr.stride);
-    ints[4] = static_cast<int32_t>(t.attr.format);
-    ints[5] = static_cast<int32_t>(t.attr.layerCount);
-    ints[6] = static_cast<int32_t>(t.attr.usage);
-    ints[7] = static_cast<int32_t>(t.attr.id >> 32);
-    ints[8] = static_cast<int32_t>(t.attr.id & 0xFFFFFFFF);
-    ints[9] = static_cast<int32_t>(t.attr.generationNumber);
-    ints[10] = 0;
-    ints[11] = 0;
-    if (handle) {
-        ints[10] = static_cast<int32_t>(handle->numFds);
-        ints[11] = static_cast<int32_t>(handle->numInts);
-        int* intsStart = handle->data + handle->numFds;
-        std::copy(handle->data, intsStart, fds);
-        std::copy(intsStart, intsStart + handle->numInts, &ints[12]);
-    }
-
-    void const* constBuffer = static_cast<void const*>(ints);
-    size_t size = numInts * sizeof(int32_t);
-    int const* constFds = static_cast<int const*>(fds);
-    status_t status = l->unflatten(constBuffer, size, constFds, numFds);
-
-    delete [] fds;
-    delete [] ints;
-    native_handle_delete(handle);
-    return status == NO_ERROR;
-}
-
-/**
- * Conversion functions for types outside media
- * ============================================
- *
- * Some objects in libui and libgui that were made to go through binder calls do
- * not expose ways to read or write their fields to the public. To pass an
- * object of this kind through the HIDL boundary, translation functions need to
- * work around the access restriction by using the publicly available
- * `flatten()` and `unflatten()` functions.
- *
- * All `flatten()` and `unflatten()` overloads follow the same convention as
- * follows:
- *
- *     status_t flatten(ObjectType const& object,
- *                      [OtherType const& other, ...]
- *                      void*& buffer, size_t& size,
- *                      int*& fds, size_t& numFds)
- *
- *     status_t unflatten(ObjectType* object,
- *                        [OtherType* other, ...,]
- *                        void*& buffer, size_t& size,
- *                        int*& fds, size_t& numFds)
- *
- * The number of `other` parameters varies depending on the `ObjectType`. For
- * example, in the process of unflattening an object that contains
- * `hidl_handle`, `other` is needed to hold `native_handle_t` objects that will
- * be created.
- *
- * The last four parameters always work the same way in all overloads of
- * `flatten()` and `unflatten()`:
- * - For `flatten()`, `buffer` is the pointer to the non-fd buffer to be filled,
- *   `size` is the size (in bytes) of the non-fd buffer pointed to by `buffer`,
- *   `fds` is the pointer to the fd buffer to be filled, and `numFds` is the
- *   size (in ints) of the fd buffer pointed to by `fds`.
- * - For `unflatten()`, `buffer` is the pointer to the non-fd buffer to be read
- *   from, `size` is the size (in bytes) of the non-fd buffer pointed to by
- *   `buffer`, `fds` is the pointer to the fd buffer to be read from, and
- *   `numFds` is the size (in ints) of the fd buffer pointed to by `fds`.
- * - After a successful call to `flatten()` or `unflatten()`, `buffer` and `fds`
- *   will be advanced, while `size` and `numFds` will be decreased to reflect
- *   how much storage/data of the two buffers (fd and non-fd) have been used.
- * - After an unsuccessful call, the values of `buffer`, `size`, `fds` and
- *   `numFds` are invalid.
- *
- * The return value of a successful `flatten()` or `unflatten()` call will be
- * `OK` (also aliased as `NO_ERROR`). Any other values indicate a failure.
- *
- * For each object type that supports flattening, there will be two accompanying
- * functions: `getFlattenedSize()` and `getFdCount()`. `getFlattenedSize()` will
- * return the size of the non-fd buffer that the object will need for
- * flattening. `getFdCount()` will return the size of the fd buffer that the
- * object will need for flattening.
- *
- * The set of these four functions, `getFlattenedSize()`, `getFdCount()`,
- * `flatten()` and `unflatten()`, are similar to functions of the same name in
- * the abstract class `Flattenable`. The only difference is that functions in
- * this file are not member functions of the object type. For example, we write
- *
- *     flatten(x, buffer, size, fds, numFds)
- *
- * instead of
- *
- *     x.flatten(buffer, size, fds, numFds)
- *
- * because we cannot modify the type of `x`.
- *
- * There is one exception to the naming convention: `hidl_handle` that
- * represents a fence. The four functions for this "Fence" type have the word
- * "Fence" attched to their names because the object type, which is
- * `hidl_handle`, does not carry the special meaning that the object itself can
- * only contain zero or one file descriptor.
- */
-
-// Ref: frameworks/native/libs/ui/Fence.cpp
-
-/**
- * \brief Return the size of the non-fd buffer required to flatten a fence.
- *
- * \param[in] fence The input fence of type `hidl_handle`.
- * \return The required size of the flat buffer.
- *
- * The current version of this function always returns 4, which is the number of
- * bytes required to store the number of file descriptors contained in the fd
- * part of the flat buffer.
- */
-size_t getFenceFlattenedSize(hidl_handle const& /* fence */) {
-    return 4;
-};
-
-/**
- * \brief Return the number of file descriptors contained in a fence.
- *
- * \param[in] fence The input fence of type `hidl_handle`.
- * \return `0` if \p fence does not contain a valid file descriptor, or `1`
- * otherwise.
- */
-size_t getFenceFdCount(hidl_handle const& fence) {
-    return native_handle_read_fd(fence) == -1 ? 0 : 1;
-}
-
-/**
- * \brief Unflatten `Fence` to `hidl_handle`.
- *
- * \param[out] fence The destination `hidl_handle`.
- * \param[out] nh The underlying native handle.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * If the return value is `NO_ERROR`, \p nh will point to a newly created
- * native handle, which needs to be deleted with `native_handle_delete()`
- * afterwards.
- */
-status_t unflattenFence(hidl_handle* fence, native_handle_t** nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
-    if (size < 4) {
-        return NO_MEMORY;
-    }
-
-    uint32_t numFdsInHandle;
-    FlattenableUtils::read(buffer, size, numFdsInHandle);
-
-    if (numFdsInHandle > 1) {
-        return BAD_VALUE;
-    }
-
-    if (numFds < numFdsInHandle) {
-        return NO_MEMORY;
-    }
-
-    if (numFdsInHandle) {
-        *nh = native_handle_create_from_fd(*fds);
-        if (*nh == nullptr) {
-            return NO_MEMORY;
-        }
-        *fence = *nh;
-        ++fds;
-        --numFds;
-    } else {
-        *nh = nullptr;
-        *fence = hidl_handle();
-    }
-
-    return NO_ERROR;
-}
-
-/**
- * \brief Flatten `hidl_handle` as `Fence`.
- *
- * \param[in] t The source `hidl_handle`.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- */
-status_t flattenFence(hidl_handle const& fence,
-        void*& buffer, size_t& size, int*& fds, size_t& numFds) {
-    if (size < getFenceFlattenedSize(fence) ||
-            numFds < getFenceFdCount(fence)) {
-        return NO_MEMORY;
-    }
-    // Cast to uint32_t since the size of a size_t can vary between 32- and
-    // 64-bit processes
-    FlattenableUtils::write(buffer, size,
-            static_cast<uint32_t>(getFenceFdCount(fence)));
-    int fd = native_handle_read_fd(fence);
-    if (fd != -1) {
-        *fds = fd;
-        ++fds;
-        --numFds;
-    }
-    return NO_ERROR;
-}
-
-/**
- * \brief Wrap `Fence` in `hidl_handle`.
- *
- * \param[out] t The wrapper of type `hidl_handle`.
- * \param[out] nh The native handle pointed to by \p t.
- * \param[in] l The source `Fence`.
- *
- * On success, \p nh will hold a newly created native handle, which must be
- * deleted manually with `native_handle_delete()` afterwards.
- */
-// wrap: Fence -> hidl_handle
-bool wrapAs(hidl_handle* t, native_handle_t** nh, Fence const& l) {
-    size_t const baseSize = l.getFlattenedSize();
-    std::unique_ptr<uint8_t[]> baseBuffer(
-            new (std::nothrow) uint8_t[baseSize]);
-    if (!baseBuffer) {
-        return false;
-    }
-
-    size_t const baseNumFds = l.getFdCount();
-    std::unique_ptr<int[]> baseFds(
-            new (std::nothrow) int[baseNumFds]);
-    if (!baseFds) {
-        return false;
-    }
-
-    void* buffer = static_cast<void*>(baseBuffer.get());
-    size_t size = baseSize;
-    int* fds = static_cast<int*>(baseFds.get());
-    size_t numFds = baseNumFds;
-    if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
-    size = baseSize;
-    int const* constFds = static_cast<int const*>(baseFds.get());
-    numFds = baseNumFds;
-    if (unflattenFence(t, nh, constBuffer, size, constFds, numFds)
-            != NO_ERROR) {
-        return false;
-    }
-
-    return true;
-}
-
-/**
- * \brief Convert `hidl_handle` to `Fence`.
- *
- * \param[out] l The destination `Fence`. `l` must not have been used
- * (`l->isValid()` must return `false`) before this function is called.
- * \param[in] t The source `hidl_handle`.
- *
- * If \p t contains a valid file descriptor, it will be duplicated.
- */
-// convert: hidl_handle -> Fence
-bool convertTo(Fence* l, hidl_handle const& t) {
-    int fd = native_handle_read_fd(t);
-    if (fd != -1) {
-        fd = dup(fd);
-        if (fd == -1) {
-            return false;
-        }
-    }
-    native_handle_t* nh = native_handle_create_from_fd(fd);
-    if (nh == nullptr) {
-        if (fd != -1) {
-            close(fd);
-        }
-        return false;
-    }
-
-    size_t const baseSize = getFenceFlattenedSize(t);
-    std::unique_ptr<uint8_t[]> baseBuffer(
-            new (std::nothrow) uint8_t[baseSize]);
-    if (!baseBuffer) {
-        native_handle_delete(nh);
-        return false;
-    }
-
-    size_t const baseNumFds = getFenceFdCount(t);
-    std::unique_ptr<int[]> baseFds(
-            new (std::nothrow) int[baseNumFds]);
-    if (!baseFds) {
-        native_handle_delete(nh);
-        return false;
-    }
-
-    void* buffer = static_cast<void*>(baseBuffer.get());
-    size_t size = baseSize;
-    int* fds = static_cast<int*>(baseFds.get());
-    size_t numFds = baseNumFds;
-    if (flattenFence(hidl_handle(nh), buffer, size, fds, numFds) != NO_ERROR) {
-        native_handle_delete(nh);
-        return false;
-    }
-    native_handle_delete(nh);
-
-    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
-    size = baseSize;
-    int const* constFds = static_cast<int const*>(baseFds.get());
-    numFds = baseNumFds;
-    if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    return true;
-}
-
-// Ref: frameworks/native/libs/ui/FenceTime.cpp: FenceTime::Snapshot
-
-/**
- * \brief Return the size of the non-fd buffer required to flatten
- * `FenceTimeSnapshot`.
- *
- * \param[in] t The input `FenceTimeSnapshot`.
- * \return The required size of the flat buffer.
- */
-size_t getFlattenedSize(
-        HGraphicBufferProducer::FenceTimeSnapshot const& t) {
-    constexpr size_t min = sizeof(t.state);
-    switch (t.state) {
-        case HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY:
-            return min;
-        case HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE:
-            return min + getFenceFlattenedSize(t.fence);
-        case HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME:
-            return min + sizeof(
-                    ::android::FenceTime::Snapshot::signalTime);
-    }
-    return 0;
-}
-
-/**
- * \brief Return the number of file descriptors contained in
- * `FenceTimeSnapshot`.
- *
- * \param[in] t The input `FenceTimeSnapshot`.
- * \return The number of file descriptors contained in \p snapshot.
- */
-size_t getFdCount(
-        HGraphicBufferProducer::FenceTimeSnapshot const& t) {
-    return t.state ==
-            HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE ?
-            getFenceFdCount(t.fence) : 0;
-}
-
-/**
- * \brief Flatten `FenceTimeSnapshot`.
- *
- * \param[in] t The source `FenceTimeSnapshot`.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * This function will duplicate the file descriptor in `t.fence` if `t.state ==
- * FENCE`.
- */
-status_t flatten(HGraphicBufferProducer::FenceTimeSnapshot const& t,
-        void*& buffer, size_t& size, int*& fds, size_t& numFds) {
-    if (size < getFlattenedSize(t)) {
-        return NO_MEMORY;
-    }
-
-    switch (t.state) {
-        case HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY:
-            FlattenableUtils::write(buffer, size,
-                    ::android::FenceTime::Snapshot::State::EMPTY);
-            return NO_ERROR;
-        case HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE:
-            FlattenableUtils::write(buffer, size,
-                    ::android::FenceTime::Snapshot::State::FENCE);
-            return flattenFence(t.fence, buffer, size, fds, numFds);
-        case HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME:
-            FlattenableUtils::write(buffer, size,
-                    ::android::FenceTime::Snapshot::State::SIGNAL_TIME);
-            FlattenableUtils::write(buffer, size, t.signalTimeNs);
-            return NO_ERROR;
-    }
-    return NO_ERROR;
-}
-
-/**
- * \brief Unflatten `FenceTimeSnapshot`.
- *
- * \param[out] t The destination `FenceTimeSnapshot`.
- * \param[out] nh The underlying native handle.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * If the return value is `NO_ERROR` and the constructed snapshot contains a
- * file descriptor, \p nh will be created to hold that file descriptor. In this
- * case, \p nh needs to be deleted with `native_handle_delete()` afterwards.
- */
-status_t unflatten(
-        HGraphicBufferProducer::FenceTimeSnapshot* t, native_handle_t** nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
-    if (size < sizeof(t->state)) {
-        return NO_MEMORY;
-    }
-
-    *nh = nullptr;
-    ::android::FenceTime::Snapshot::State state;
-    FlattenableUtils::read(buffer, size, state);
-    switch (state) {
-        case ::android::FenceTime::Snapshot::State::EMPTY:
-            t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY;
-            return NO_ERROR;
-        case ::android::FenceTime::Snapshot::State::FENCE:
-            t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE;
-            return unflattenFence(&t->fence, nh, buffer, size, fds, numFds);
-        case ::android::FenceTime::Snapshot::State::SIGNAL_TIME:
-            t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME;
-            if (size < sizeof(t->signalTimeNs)) {
-                return NO_MEMORY;
-            }
-            FlattenableUtils::read(buffer, size, t->signalTimeNs);
-            return NO_ERROR;
-    }
-    return NO_ERROR;
-}
-
-// Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventsDelta
-
-/**
- * \brief Return a lower bound on the size of the non-fd buffer required to
- * flatten `FrameEventsDelta`.
- *
- * \param[in] t The input `FrameEventsDelta`.
- * \return A lower bound on the size of the flat buffer.
- */
-constexpr size_t minFlattenedSize(
-        HGraphicBufferProducer::FrameEventsDelta const& /* t */) {
-    return sizeof(uint64_t) + // mFrameNumber
-            sizeof(uint8_t) + // mIndex
-            sizeof(uint8_t) + // mAddPostCompositeCalled
-            sizeof(uint8_t) + // mAddRetireCalled
-            sizeof(uint8_t) + // mAddReleaseCalled
-            sizeof(nsecs_t) + // mPostedTime
-            sizeof(nsecs_t) + // mRequestedPresentTime
-            sizeof(nsecs_t) + // mLatchTime
-            sizeof(nsecs_t) + // mFirstRefreshStartTime
-            sizeof(nsecs_t); // mLastRefreshStartTime
-}
-
-/**
- * \brief Return the size of the non-fd buffer required to flatten
- * `FrameEventsDelta`.
- *
- * \param[in] t The input `FrameEventsDelta`.
- * \return The required size of the flat buffer.
- */
-size_t getFlattenedSize(
-        HGraphicBufferProducer::FrameEventsDelta const& t) {
-    return minFlattenedSize(t) +
-            getFlattenedSize(t.gpuCompositionDoneFence) +
-            getFlattenedSize(t.displayPresentFence) +
-            getFlattenedSize(t.displayRetireFence) +
-            getFlattenedSize(t.releaseFence);
-};
-
-/**
- * \brief Return the number of file descriptors contained in
- * `FrameEventsDelta`.
- *
- * \param[in] t The input `FrameEventsDelta`.
- * \return The number of file descriptors contained in \p t.
- */
-size_t getFdCount(
-        HGraphicBufferProducer::FrameEventsDelta const& t) {
-    return getFdCount(t.gpuCompositionDoneFence) +
-            getFdCount(t.displayPresentFence) +
-            getFdCount(t.displayRetireFence) +
-            getFdCount(t.releaseFence);
-};
-
-/**
- * \brief Unflatten `FrameEventsDelta`.
- *
- * \param[out] t The destination `FrameEventsDelta`.
- * \param[out] nh The underlying array of native handles.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * If the return value is `NO_ERROR`, \p nh will have length 4, and it will be
- * populated with `nullptr` or newly created handles. Each non-null slot in \p
- * nh will need to be deleted manually with `native_handle_delete()`.
- */
-status_t unflatten(HGraphicBufferProducer::FrameEventsDelta* t,
-        std::vector<native_handle_t*>* nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
-    if (size < minFlattenedSize(*t)) {
-        return NO_MEMORY;
-    }
-    FlattenableUtils::read(buffer, size, t->frameNumber);
-
-    // These were written as uint8_t for alignment.
-    uint8_t temp = 0;
-    FlattenableUtils::read(buffer, size, temp);
-    size_t index = static_cast<size_t>(temp);
-    if (index >= ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
-        return BAD_VALUE;
-    }
-    t->index = static_cast<uint32_t>(index);
-
-    FlattenableUtils::read(buffer, size, temp);
-    t->addPostCompositeCalled = static_cast<bool>(temp);
-    FlattenableUtils::read(buffer, size, temp);
-    t->addRetireCalled = static_cast<bool>(temp);
-    FlattenableUtils::read(buffer, size, temp);
-    t->addReleaseCalled = static_cast<bool>(temp);
-
-    FlattenableUtils::read(buffer, size, t->postedTimeNs);
-    FlattenableUtils::read(buffer, size, t->requestedPresentTimeNs);
-    FlattenableUtils::read(buffer, size, t->latchTimeNs);
-    FlattenableUtils::read(buffer, size, t->firstRefreshStartTimeNs);
-    FlattenableUtils::read(buffer, size, t->lastRefreshStartTimeNs);
-    FlattenableUtils::read(buffer, size, t->dequeueReadyTime);
-
-    // Fences
-    HGraphicBufferProducer::FenceTimeSnapshot* tSnapshot[4];
-    tSnapshot[0] = &t->gpuCompositionDoneFence;
-    tSnapshot[1] = &t->displayPresentFence;
-    tSnapshot[2] = &t->displayRetireFence;
-    tSnapshot[3] = &t->releaseFence;
-    nh->resize(4);
-    for (size_t snapshotIndex = 0; snapshotIndex < 4; ++snapshotIndex) {
-        status_t status = unflatten(
-                tSnapshot[snapshotIndex], &((*nh)[snapshotIndex]),
-                buffer, size, fds, numFds);
-        if (status != NO_ERROR) {
-            while (snapshotIndex > 0) {
-                --snapshotIndex;
-                if ((*nh)[snapshotIndex] != nullptr) {
-                    native_handle_delete((*nh)[snapshotIndex]);
-                }
-            }
-            return status;
-        }
-    }
-    return NO_ERROR;
-}
-
-/**
- * \brief Flatten `FrameEventsDelta`.
- *
- * \param[in] t The source `FrameEventsDelta`.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * This function will duplicate file descriptors contained in \p t.
- */
-// Ref: frameworks/native/libs/gui/FrameTimestamp.cpp:
-//      FrameEventsDelta::flatten
-status_t flatten(HGraphicBufferProducer::FrameEventsDelta const& t,
-        void*& buffer, size_t& size, int*& fds, size_t numFds) {
-    // Check that t.index is within a valid range.
-    if (t.index >= static_cast<uint32_t>(FrameEventHistory::MAX_FRAME_HISTORY)
-            || t.index > std::numeric_limits<uint8_t>::max()) {
-        return BAD_VALUE;
-    }
-
-    FlattenableUtils::write(buffer, size, t.frameNumber);
-
-    // These are static_cast to uint8_t for alignment.
-    FlattenableUtils::write(buffer, size, static_cast<uint8_t>(t.index));
-    FlattenableUtils::write(
-            buffer, size, static_cast<uint8_t>(t.addPostCompositeCalled));
-    FlattenableUtils::write(
-            buffer, size, static_cast<uint8_t>(t.addRetireCalled));
-    FlattenableUtils::write(
-            buffer, size, static_cast<uint8_t>(t.addReleaseCalled));
-
-    FlattenableUtils::write(buffer, size, t.postedTimeNs);
-    FlattenableUtils::write(buffer, size, t.requestedPresentTimeNs);
-    FlattenableUtils::write(buffer, size, t.latchTimeNs);
-    FlattenableUtils::write(buffer, size, t.firstRefreshStartTimeNs);
-    FlattenableUtils::write(buffer, size, t.lastRefreshStartTimeNs);
-    FlattenableUtils::write(buffer, size, t.dequeueReadyTime);
-
-    // Fences
-    HGraphicBufferProducer::FenceTimeSnapshot const* tSnapshot[4];
-    tSnapshot[0] = &t.gpuCompositionDoneFence;
-    tSnapshot[1] = &t.displayPresentFence;
-    tSnapshot[2] = &t.displayRetireFence;
-    tSnapshot[3] = &t.releaseFence;
-    for (size_t snapshotIndex = 0; snapshotIndex < 4; ++snapshotIndex) {
-        status_t status = flatten(
-                *(tSnapshot[snapshotIndex]), buffer, size, fds, numFds);
-        if (status != NO_ERROR) {
-            return status;
-        }
-    }
-    return NO_ERROR;
-}
-
-// Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventHistoryDelta
-
-/**
- * \brief Return the size of the non-fd buffer required to flatten
- * `HGraphicBufferProducer::FrameEventHistoryDelta`.
- *
- * \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`.
- * \return The required size of the flat buffer.
- */
-size_t getFlattenedSize(
-        HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
-    size_t size = 4 + // mDeltas.size()
-            sizeof(t.compositorTiming);
-    for (size_t i = 0; i < t.deltas.size(); ++i) {
-        size += getFlattenedSize(t.deltas[i]);
-    }
-    return size;
-}
-
-/**
- * \brief Return the number of file descriptors contained in
- * `HGraphicBufferProducer::FrameEventHistoryDelta`.
- *
- * \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`.
- * \return The number of file descriptors contained in \p t.
- */
-size_t getFdCount(
-        HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
-    size_t numFds = 0;
-    for (size_t i = 0; i < t.deltas.size(); ++i) {
-        numFds += getFdCount(t.deltas[i]);
-    }
-    return numFds;
-}
-
-/**
- * \brief Unflatten `FrameEventHistoryDelta`.
- *
- * \param[out] t The destination `FrameEventHistoryDelta`.
- * \param[out] nh The underlying array of arrays of native handles.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * If the return value is `NO_ERROR`, \p nh will be populated with `nullptr` or
- * newly created handles. The second dimension of \p nh will be 4. Each non-null
- * slot in \p nh will need to be deleted manually with `native_handle_delete()`.
- */
-status_t unflatten(
-        HGraphicBufferProducer::FrameEventHistoryDelta* t,
-        std::vector<std::vector<native_handle_t*> >* nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
-    if (size < 4) {
-        return NO_MEMORY;
-    }
-
-    FlattenableUtils::read(buffer, size, t->compositorTiming);
-
-    uint32_t deltaCount = 0;
-    FlattenableUtils::read(buffer, size, deltaCount);
-    if (static_cast<size_t>(deltaCount) >
-            ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
-        return BAD_VALUE;
-    }
-    t->deltas.resize(deltaCount);
-    nh->resize(deltaCount);
-    for (size_t deltaIndex = 0; deltaIndex < deltaCount; ++deltaIndex) {
-        status_t status = unflatten(
-                &(t->deltas[deltaIndex]), &((*nh)[deltaIndex]),
-                buffer, size, fds, numFds);
-        if (status != NO_ERROR) {
-            return status;
-        }
-    }
-    return NO_ERROR;
-}
-
-/**
- * \brief Flatten `FrameEventHistoryDelta`.
- *
- * \param[in] t The source `FrameEventHistoryDelta`.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * This function will duplicate file descriptors contained in \p t.
- */
-status_t flatten(
-        HGraphicBufferProducer::FrameEventHistoryDelta const& t,
-        void*& buffer, size_t& size, int*& fds, size_t& numFds) {
-    if (t.deltas.size() > ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
-        return BAD_VALUE;
-    }
-    if (size < getFlattenedSize(t)) {
-        return NO_MEMORY;
-    }
-
-    FlattenableUtils::write(buffer, size, t.compositorTiming);
-
-    FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.deltas.size()));
-    for (size_t deltaIndex = 0; deltaIndex < t.deltas.size(); ++deltaIndex) {
-        status_t status = flatten(t.deltas[deltaIndex], buffer, size, fds, numFds);
-        if (status != NO_ERROR) {
-            return status;
-        }
-    }
-    return NO_ERROR;
-}
-
-/**
- * \brief Wrap `::android::FrameEventHistoryData` in
- * `HGraphicBufferProducer::FrameEventHistoryDelta`.
- *
- * \param[out] t The wrapper of type
- * `HGraphicBufferProducer::FrameEventHistoryDelta`.
- * \param[out] nh The array of array of native handles that are referred to by
- * members of \p t.
- * \param[in] l The source `::android::FrameEventHistoryDelta`.
- *
- * On success, each member of \p nh will be either `nullptr` or a newly created
- * native handle. All the non-`nullptr` elements must be deleted individually
- * with `native_handle_delete()`.
- */
-bool wrapAs(HGraphicBufferProducer::FrameEventHistoryDelta* t,
-        std::vector<std::vector<native_handle_t*> >* nh,
-        ::android::FrameEventHistoryDelta const& l) {
-
-    size_t const baseSize = l.getFlattenedSize();
-    std::unique_ptr<uint8_t[]> baseBuffer(
-            new (std::nothrow) uint8_t[baseSize]);
-    if (!baseBuffer) {
-        return false;
-    }
-
-    size_t const baseNumFds = l.getFdCount();
-    std::unique_ptr<int[]> baseFds(
-            new (std::nothrow) int[baseNumFds]);
-    if (!baseFds) {
-        return false;
-    }
-
-    void* buffer = static_cast<void*>(baseBuffer.get());
-    size_t size = baseSize;
-    int* fds = baseFds.get();
-    size_t numFds = baseNumFds;
-    if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
-    size = baseSize;
-    int const* constFds = static_cast<int const*>(baseFds.get());
-    numFds = baseNumFds;
-    if (unflatten(t, nh, constBuffer, size, constFds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    return true;
-}
-
-/**
- * \brief Convert `HGraphicBufferProducer::FrameEventHistoryDelta` to
- * `::android::FrameEventHistoryDelta`.
- *
- * \param[out] l The destination `::android::FrameEventHistoryDelta`.
- * \param[in] t The source `HGraphicBufferProducer::FrameEventHistoryDelta`.
- *
- * This function will duplicate all file descriptors contained in \p t.
- */
-bool convertTo(
-        ::android::FrameEventHistoryDelta* l,
-        HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
-
-    size_t const baseSize = getFlattenedSize(t);
-    std::unique_ptr<uint8_t[]> baseBuffer(
-            new (std::nothrow) uint8_t[baseSize]);
-    if (!baseBuffer) {
-        return false;
-    }
-
-    size_t const baseNumFds = getFdCount(t);
-    std::unique_ptr<int[]> baseFds(
-            new (std::nothrow) int[baseNumFds]);
-    if (!baseFds) {
-        return false;
-    }
-
-    void* buffer = static_cast<void*>(baseBuffer.get());
-    size_t size = baseSize;
-    int* fds = static_cast<int*>(baseFds.get());
-    size_t numFds = baseNumFds;
-    if (flatten(t, buffer, size, fds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
-    size = baseSize;
-    int const* constFds = static_cast<int const*>(baseFds.get());
-    numFds = baseNumFds;
-    if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    return true;
-}
-
-// Ref: frameworks/native/libs/ui/Region.cpp
-
-/**
- * \brief Return the size of the buffer required to flatten `Region`.
- *
- * \param[in] t The input `Region`.
- * \return The required size of the flat buffer.
- */
-size_t getFlattenedSize(Region const& t) {
-    return sizeof(uint32_t) + t.size() * sizeof(::android::Rect);
-}
-
-/**
- * \brief Unflatten `Region`.
- *
- * \param[out] t The destination `Region`.
- * \param[in,out] buffer The pointer to the flat buffer.
- * \param[in,out] size The size of the flat buffer.
- * \return `NO_ERROR` on success; other value on failure.
- */
-status_t unflatten(Region* t, void const*& buffer, size_t& size) {
-    if (size < sizeof(uint32_t)) {
-        return NO_MEMORY;
-    }
-
-    uint32_t numRects = 0;
-    FlattenableUtils::read(buffer, size, numRects);
-    if (size < numRects * sizeof(Rect)) {
-        return NO_MEMORY;
-    }
-    if (numRects > (UINT32_MAX / sizeof(Rect))) {
-        return NO_MEMORY;
-    }
-
-    t->resize(numRects);
-    for (size_t r = 0; r < numRects; ++r) {
-        ::android::Rect rect(::android::Rect::EMPTY_RECT);
-        status_t status = rect.unflatten(buffer, size);
-        if (status != NO_ERROR) {
-            return status;
-        }
-        FlattenableUtils::advance(buffer, size, sizeof(rect));
-        (*t)[r] = Rect{
-                static_cast<int32_t>(rect.left),
-                static_cast<int32_t>(rect.top),
-                static_cast<int32_t>(rect.right),
-                static_cast<int32_t>(rect.bottom)};
-    }
-    return NO_ERROR;
-}
-
-/**
- * \brief Flatten `Region`.
- *
- * \param[in] t The source `Region`.
- * \param[in,out] buffer The pointer to the flat buffer.
- * \param[in,out] size The size of the flat buffer.
- * \return `NO_ERROR` on success; other value on failure.
- */
-status_t flatten(Region const& t, void*& buffer, size_t& size) {
-    if (size < getFlattenedSize(t)) {
-        return NO_MEMORY;
-    }
-
-    FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.size()));
-    for (size_t r = 0; r < t.size(); ++r) {
-        ::android::Rect rect(
-                static_cast<int32_t>(t[r].left),
-                static_cast<int32_t>(t[r].top),
-                static_cast<int32_t>(t[r].right),
-                static_cast<int32_t>(t[r].bottom));
-        status_t status = rect.flatten(buffer, size);
-        if (status != NO_ERROR) {
-            return status;
-        }
-        FlattenableUtils::advance(buffer, size, sizeof(rect));
-    }
-    return NO_ERROR;
-}
-
-/**
- * \brief Convert `::android::Region` to `Region`.
- *
- * \param[out] t The destination `Region`.
- * \param[in] l The source `::android::Region`.
- */
-// convert: ::android::Region -> Region
-bool convertTo(Region* t, ::android::Region const& l) {
-    size_t const baseSize = l.getFlattenedSize();
-    std::unique_ptr<uint8_t[]> baseBuffer(
-            new (std::nothrow) uint8_t[baseSize]);
-    if (!baseBuffer) {
-        return false;
-    }
-
-    void* buffer = static_cast<void*>(baseBuffer.get());
-    size_t size = baseSize;
-    if (l.flatten(buffer, size) != NO_ERROR) {
-        return false;
-    }
-
-    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
-    size = baseSize;
-    if (unflatten(t, constBuffer, size) != NO_ERROR) {
-        return false;
-    }
-
-    return true;
-}
-
-/**
- * \brief Convert `Region` to `::android::Region`.
- *
- * \param[out] l The destination `::android::Region`.
- * \param[in] t The source `Region`.
- */
-// convert: Region -> ::android::Region
-bool convertTo(::android::Region* l, Region const& t) {
-    size_t const baseSize = getFlattenedSize(t);
-    std::unique_ptr<uint8_t[]> baseBuffer(
-            new (std::nothrow) uint8_t[baseSize]);
-    if (!baseBuffer) {
-        return false;
-    }
-
-    void* buffer = static_cast<void*>(baseBuffer.get());
-    size_t size = baseSize;
-    if (flatten(t, buffer, size) != NO_ERROR) {
-        return false;
-    }
-
-    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
-    size = baseSize;
-    if (l->unflatten(constBuffer, size) != NO_ERROR) {
-        return false;
-    }
-
-    return true;
-}
-
-// Ref: frameworks/native/libs/gui/BGraphicBufferProducer.cpp:
-//      BGraphicBufferProducer::QueueBufferInput
-
-/**
- * \brief Return a lower bound on the size of the buffer required to flatten
- * `HGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
- * \return A lower bound on the size of the flat buffer.
- */
-constexpr size_t minFlattenedSize(
-        HGraphicBufferProducer::QueueBufferInput const& /* t */) {
-    return sizeof(int64_t) + // timestamp
-            sizeof(int) + // isAutoTimestamp
-            sizeof(android_dataspace) + // dataSpace
-            sizeof(::android::Rect) + // crop
-            sizeof(int) + // scalingMode
-            sizeof(uint32_t) + // transform
-            sizeof(uint32_t) + // stickyTransform
-            sizeof(bool); // getFrameTimestamps
-}
-
-/**
- * \brief Return the size of the buffer required to flatten
- * `HGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
- * \return The required size of the flat buffer.
- */
-size_t getFlattenedSize(HGraphicBufferProducer::QueueBufferInput const& t) {
-    return minFlattenedSize(t) +
-            getFenceFlattenedSize(t.fence) +
-            getFlattenedSize(t.surfaceDamage) +
-            sizeof(HdrMetadata::validTypes);
-}
-
-/**
- * \brief Return the number of file descriptors contained in
- * `HGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
- * \return The number of file descriptors contained in \p t.
- */
-size_t getFdCount(
-        HGraphicBufferProducer::QueueBufferInput const& t) {
-    return getFenceFdCount(t.fence);
-}
-
-/**
- * \brief Flatten `HGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[in] t The source `HGraphicBufferProducer::QueueBufferInput`.
- * \param[out] nh The native handle cloned from `t.fence`.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * This function will duplicate the file descriptor in `t.fence`. */
-status_t flatten(HGraphicBufferProducer::QueueBufferInput const& t,
-        native_handle_t** nh,
-        void*& buffer, size_t& size, int*& fds, size_t& numFds) {
-    if (size < getFlattenedSize(t)) {
-        return NO_MEMORY;
-    }
-
-    FlattenableUtils::write(buffer, size, t.timestamp);
-    FlattenableUtils::write(buffer, size, static_cast<int>(t.isAutoTimestamp));
-    FlattenableUtils::write(buffer, size,
-            static_cast<android_dataspace_t>(t.dataSpace));
-    FlattenableUtils::write(buffer, size, ::android::Rect(
-            static_cast<int32_t>(t.crop.left),
-            static_cast<int32_t>(t.crop.top),
-            static_cast<int32_t>(t.crop.right),
-            static_cast<int32_t>(t.crop.bottom)));
-    FlattenableUtils::write(buffer, size, static_cast<int>(t.scalingMode));
-    FlattenableUtils::write(buffer, size, t.transform);
-    FlattenableUtils::write(buffer, size, t.stickyTransform);
-    FlattenableUtils::write(buffer, size, t.getFrameTimestamps);
-
-    *nh = t.fence.getNativeHandle() == nullptr ?
-            nullptr : native_handle_clone(t.fence);
-    status_t status = flattenFence(hidl_handle(*nh), buffer, size, fds, numFds);
-    if (status != NO_ERROR) {
-        return status;
-    }
-    status = flatten(t.surfaceDamage, buffer, size);
-    if (status != NO_ERROR) {
-        return status;
-    }
-    FlattenableUtils::write(buffer, size, decltype(HdrMetadata::validTypes)(0));
-    return NO_ERROR;
-}
-
-/**
- * \brief Unflatten `HGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[out] t The destination `HGraphicBufferProducer::QueueBufferInput`.
- * \param[out] nh The underlying native handle for `t->fence`.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * If the return value is `NO_ERROR` and `t->fence` contains a valid file
- * descriptor, \p nh will be a newly created native handle holding that file
- * descriptor. \p nh needs to be deleted with `native_handle_delete()`
- * afterwards.
- */
-status_t unflatten(
-        HGraphicBufferProducer::QueueBufferInput* t, native_handle_t** nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
-    if (size < minFlattenedSize(*t)) {
-        return NO_MEMORY;
-    }
-
-    FlattenableUtils::read(buffer, size, t->timestamp);
-    int lIsAutoTimestamp;
-    FlattenableUtils::read(buffer, size, lIsAutoTimestamp);
-    t->isAutoTimestamp = static_cast<int32_t>(lIsAutoTimestamp);
-    android_dataspace_t lDataSpace;
-    FlattenableUtils::read(buffer, size, lDataSpace);
-    t->dataSpace = static_cast<Dataspace>(lDataSpace);
-    Rect lCrop;
-    FlattenableUtils::read(buffer, size, lCrop);
-    t->crop = Rect{
-            static_cast<int32_t>(lCrop.left),
-            static_cast<int32_t>(lCrop.top),
-            static_cast<int32_t>(lCrop.right),
-            static_cast<int32_t>(lCrop.bottom)};
-    int lScalingMode;
-    FlattenableUtils::read(buffer, size, lScalingMode);
-    t->scalingMode = static_cast<int32_t>(lScalingMode);
-    FlattenableUtils::read(buffer, size, t->transform);
-    FlattenableUtils::read(buffer, size, t->stickyTransform);
-    FlattenableUtils::read(buffer, size, t->getFrameTimestamps);
-
-    status_t status = unflattenFence(&(t->fence), nh,
-            buffer, size, fds, numFds);
-    if (status != NO_ERROR) {
-        return status;
-    }
-    // HdrMetadata ignored
-    return unflatten(&(t->surfaceDamage), buffer, size);
-}
-
-/**
- * \brief Wrap `BGraphicBufferProducer::QueueBufferInput` in
- * `HGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[out] t The wrapper of type
- * `HGraphicBufferProducer::QueueBufferInput`.
- * \param[out] nh The underlying native handle for `t->fence`.
- * \param[in] l The source `BGraphicBufferProducer::QueueBufferInput`.
- *
- * If the return value is `true` and `t->fence` contains a valid file
- * descriptor, \p nh will be a newly created native handle holding that file
- * descriptor. \p nh needs to be deleted with `native_handle_delete()`
- * afterwards.
- */
-bool wrapAs(
-        HGraphicBufferProducer::QueueBufferInput* t,
-        native_handle_t** nh,
-        BGraphicBufferProducer::QueueBufferInput const& l) {
-
-    size_t const baseSize = l.getFlattenedSize();
-    std::unique_ptr<uint8_t[]> baseBuffer(
-            new (std::nothrow) uint8_t[baseSize]);
-    if (!baseBuffer) {
-        return false;
-    }
-
-    size_t const baseNumFds = l.getFdCount();
-    std::unique_ptr<int[]> baseFds(
-            new (std::nothrow) int[baseNumFds]);
-    if (!baseFds) {
-        return false;
-    }
-
-    void* buffer = static_cast<void*>(baseBuffer.get());
-    size_t size = baseSize;
-    int* fds = baseFds.get();
-    size_t numFds = baseNumFds;
-    if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
-    size = baseSize;
-    int const* constFds = static_cast<int const*>(baseFds.get());
-    numFds = baseNumFds;
-    if (unflatten(t, nh, constBuffer, size, constFds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    return true;
-}
-
-/**
- * \brief Convert `HGraphicBufferProducer::QueueBufferInput` to
- * `BGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[out] l The destination `BGraphicBufferProducer::QueueBufferInput`.
- * \param[in] t The source `HGraphicBufferProducer::QueueBufferInput`.
- *
- * If `t.fence` has a valid file descriptor, it will be duplicated.
- */
-bool convertTo(
-        BGraphicBufferProducer::QueueBufferInput* l,
-        HGraphicBufferProducer::QueueBufferInput const& t) {
-
-    size_t const baseSize = getFlattenedSize(t);
-    std::unique_ptr<uint8_t[]> baseBuffer(
-            new (std::nothrow) uint8_t[baseSize]);
-    if (!baseBuffer) {
-        return false;
-    }
-
-    size_t const baseNumFds = getFdCount(t);
-    std::unique_ptr<int[]> baseFds(
-            new (std::nothrow) int[baseNumFds]);
-    if (!baseFds) {
-        return false;
-    }
-
-    void* buffer = static_cast<void*>(baseBuffer.get());
-    size_t size = baseSize;
-    int* fds = baseFds.get();
-    size_t numFds = baseNumFds;
-    native_handle_t* nh;
-    if (flatten(t, &nh, buffer, size, fds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
-    size = baseSize;
-    int const* constFds = static_cast<int const*>(baseFds.get());
-    numFds = baseNumFds;
-    if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
-        if (nh != nullptr) {
-            native_handle_close(nh);
-            native_handle_delete(nh);
-        }
-        return false;
-    }
-
-    native_handle_delete(nh);
-    return true;
-}
-
-// Ref: frameworks/native/libs/gui/BGraphicBufferProducer.cpp:
-//      BGraphicBufferProducer::QueueBufferOutput
-
-/**
- * \brief Wrap `BGraphicBufferProducer::QueueBufferOutput` in
- * `HGraphicBufferProducer::QueueBufferOutput`.
- *
- * \param[out] t The wrapper of type
- * `HGraphicBufferProducer::QueueBufferOutput`.
- * \param[out] nh The array of array of native handles that are referred to by
- * members of \p t.
- * \param[in] l The source `BGraphicBufferProducer::QueueBufferOutput`.
- *
- * On success, each member of \p nh will be either `nullptr` or a newly created
- * native handle. All the non-`nullptr` elements must be deleted individually
- * with `native_handle_delete()`.
- */
-// wrap: BGraphicBufferProducer::QueueBufferOutput ->
-// HGraphicBufferProducer::QueueBufferOutput
-bool wrapAs(HGraphicBufferProducer::QueueBufferOutput* t,
-        std::vector<std::vector<native_handle_t*> >* nh,
-        BGraphicBufferProducer::QueueBufferOutput const& l) {
-    if (!wrapAs(&(t->frameTimestamps), nh, l.frameTimestamps)) {
-        return false;
-    }
-    t->width = l.width;
-    t->height = l.height;
-    t->transformHint = l.transformHint;
-    t->numPendingBuffers = l.numPendingBuffers;
-    t->nextFrameNumber = l.nextFrameNumber;
-    t->bufferReplaced = l.bufferReplaced;
-    return true;
-}
-
-/**
- * \brief Convert `HGraphicBufferProducer::QueueBufferOutput` to
- * `BGraphicBufferProducer::QueueBufferOutput`.
- *
- * \param[out] l The destination `BGraphicBufferProducer::QueueBufferOutput`.
- * \param[in] t The source `HGraphicBufferProducer::QueueBufferOutput`.
- *
- * This function will duplicate all file descriptors contained in \p t.
- */
-// convert: HGraphicBufferProducer::QueueBufferOutput ->
-// BGraphicBufferProducer::QueueBufferOutput
-bool convertTo(
-        BGraphicBufferProducer::QueueBufferOutput* l,
-        HGraphicBufferProducer::QueueBufferOutput const& t) {
-    if (!convertTo(&(l->frameTimestamps), t.frameTimestamps)) {
-        return false;
-    }
-    l->width = t.width;
-    l->height = t.height;
-    l->transformHint = t.transformHint;
-    l->numPendingBuffers = t.numPendingBuffers;
-    l->nextFrameNumber = t.nextFrameNumber;
-    l->bufferReplaced = t.bufferReplaced;
-    return true;
-}
-
-/**
- * \brief Convert `BGraphicBufferProducer::DisconnectMode` to
- * `HGraphicBufferProducer::DisconnectMode`.
- *
- * \param[in] l The source `BGraphicBufferProducer::DisconnectMode`.
- * \return The corresponding `HGraphicBufferProducer::DisconnectMode`.
- */
-HGraphicBufferProducer::DisconnectMode toHidlDisconnectMode(
-        BGraphicBufferProducer::DisconnectMode l) {
-    switch (l) {
-        case BGraphicBufferProducer::DisconnectMode::Api:
-            return HGraphicBufferProducer::DisconnectMode::API;
-        case BGraphicBufferProducer::DisconnectMode::AllLocal:
-            return HGraphicBufferProducer::DisconnectMode::ALL_LOCAL;
-    }
-    return HGraphicBufferProducer::DisconnectMode::API;
-}
-
-/**
- * \brief Convert `HGraphicBufferProducer::DisconnectMode` to
- * `BGraphicBufferProducer::DisconnectMode`.
- *
- * \param[in] l The source `HGraphicBufferProducer::DisconnectMode`.
- * \return The corresponding `BGraphicBufferProducer::DisconnectMode`.
- */
-BGraphicBufferProducer::DisconnectMode toGuiDisconnectMode(
-        HGraphicBufferProducer::DisconnectMode t) {
-    switch (t) {
-        case HGraphicBufferProducer::DisconnectMode::API:
-            return BGraphicBufferProducer::DisconnectMode::Api;
-        case HGraphicBufferProducer::DisconnectMode::ALL_LOCAL:
-            return BGraphicBufferProducer::DisconnectMode::AllLocal;
-    }
-    return BGraphicBufferProducer::DisconnectMode::Api;
-}
-
-}  // namespace conversion
-}  // namespace android
-
diff --git a/media/libstagefright/bqhelper/FrameDropper.cpp b/media/libstagefright/bqhelper/FrameDropper.cpp
index d2a2473..387ac5a 100644
--- a/media/libstagefright/bqhelper/FrameDropper.cpp
+++ b/media/libstagefright/bqhelper/FrameDropper.cpp
@@ -35,7 +35,7 @@
 
 status_t FrameDropper::setMaxFrameRate(float maxFrameRate) {
     if (maxFrameRate < 0) {
-        mMinIntervalUs = -1ll;
+        mMinIntervalUs = -1LL;
         return OK;
     }
 
diff --git a/media/libstagefright/bqhelper/GraphicBufferSource.cpp b/media/libstagefright/bqhelper/GraphicBufferSource.cpp
index dd03d38..59317e7 100644
--- a/media/libstagefright/bqhelper/GraphicBufferSource.cpp
+++ b/media/libstagefright/bqhelper/GraphicBufferSource.cpp
@@ -32,6 +32,11 @@
 #include <media/hardware/MetadataBufferType.h>
 #include <ui/GraphicBuffer.h>
 #include <gui/BufferItem.h>
+#include <gui/BufferQueue.h>
+#include <gui/bufferqueue/1.0/WGraphicBufferProducer.h>
+#include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h>
+#include <gui/IGraphicBufferProducer.h>
+#include <gui/IGraphicBufferConsumer.h>
 #include <media/hardware/HardwareAPI.h>
 
 #include <inttypes.h>
@@ -281,6 +286,39 @@
     }
 };
 
+struct GraphicBufferSource::ConsumerProxy : public BufferQueue::ConsumerListener {
+    ConsumerProxy(const wp<GraphicBufferSource> &gbs) : mGbs(gbs) {}
+
+    ~ConsumerProxy() = default;
+
+    void onFrameAvailable(const BufferItem& item) override {
+        sp<GraphicBufferSource> gbs = mGbs.promote();
+        if (gbs != nullptr) {
+            gbs->onFrameAvailable(item);
+        }
+    }
+
+    void onBuffersReleased() override {
+        sp<GraphicBufferSource> gbs = mGbs.promote();
+        if (gbs != nullptr) {
+            gbs->onBuffersReleased();
+        }
+    }
+
+    void onSidebandStreamChanged() override {
+        sp<GraphicBufferSource> gbs = mGbs.promote();
+        if (gbs != nullptr) {
+            gbs->onSidebandStreamChanged();
+        }
+    }
+
+private:
+    // Note that GraphicBufferSource is holding an sp to us, we can't hold
+    // an sp back to GraphicBufferSource as the circular dependency will
+    // make both immortal.
+    wp<GraphicBufferSource> mGbs;
+};
+
 GraphicBufferSource::GraphicBufferSource() :
     mInitCheck(UNKNOWN_ERROR),
     mNumAvailableUnacquiredBuffers(0),
@@ -292,20 +330,20 @@
     mSuspended(false),
     mLastFrameTimestampUs(-1),
     mStopTimeUs(-1),
-    mLastActionTimeUs(-1ll),
-    mSkipFramesBeforeNs(-1ll),
-    mFrameRepeatIntervalUs(-1ll),
+    mLastActionTimeUs(-1LL),
+    mSkipFramesBeforeNs(-1LL),
+    mFrameRepeatIntervalUs(-1LL),
     mRepeatLastFrameGeneration(0),
     mOutstandingFrameRepeatCount(0),
     mFrameRepeatBlockedOnCodecBuffer(false),
     mFps(-1.0),
     mCaptureFps(-1.0),
-    mBaseCaptureUs(-1ll),
-    mBaseFrameUs(-1ll),
+    mBaseCaptureUs(-1LL),
+    mBaseFrameUs(-1LL),
     mFrameCount(0),
-    mPrevCaptureUs(-1ll),
-    mPrevFrameUs(-1ll),
-    mInputBufferTimeOffsetUs(0ll) {
+    mPrevCaptureUs(-1LL),
+    mPrevFrameUs(-1LL),
+    mInputBufferTimeOffsetUs(0LL) {
     ALOGV("GraphicBufferSource");
 
     String8 name("GraphicBufferSource");
@@ -313,14 +351,12 @@
     BufferQueue::createBufferQueue(&mProducer, &mConsumer);
     mConsumer->setConsumerName(name);
 
-    // Note that we can't create an sp<...>(this) in a ctor that will not keep a
-    // reference once the ctor ends, as that would cause the refcount of 'this'
-    // dropping to 0 at the end of the ctor.  Since all we need is a wp<...>
-    // that's what we create.
-    wp<BufferQueue::ConsumerListener> listener =
-            static_cast<BufferQueue::ConsumerListener*>(this);
+    // create the consumer listener interface, and hold sp so that this
+    // interface lives as long as the GraphicBufferSource.
+    mConsumerProxy = new ConsumerProxy(this);
+
     sp<IConsumerListener> proxy =
-            new BufferQueue::ProxyConsumerListener(listener);
+            new BufferQueue::ProxyConsumerListener(mConsumerProxy);
 
     mInitCheck = mConsumer->consumerConnect(proxy, false);
     if (mInitCheck != NO_ERROR) {
@@ -357,6 +393,24 @@
     }
 }
 
+sp<IGraphicBufferProducer> GraphicBufferSource::getIGraphicBufferProducer() const {
+    return mProducer;
+}
+
+sp<::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer>
+GraphicBufferSource::getHGraphicBufferProducer_V1_0() const {
+    using TWGraphicBufferProducer = ::android::TWGraphicBufferProducer<
+        ::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer>;
+
+    return new TWGraphicBufferProducer(getIGraphicBufferProducer());
+}
+
+sp<::android::hardware::graphics::bufferqueue::V2_0::IGraphicBufferProducer>
+GraphicBufferSource::getHGraphicBufferProducer() const {
+    return new ::android::hardware::graphics::bufferqueue::V2_0::utils::
+                    B2HGraphicBufferProducer(getIGraphicBufferProducer());
+}
+
 Status GraphicBufferSource::start() {
     Mutex::Autolock autoLock(mMutex);
     ALOGV("--> start; available=%zu, submittable=%zd",
@@ -392,7 +446,7 @@
         submitEndOfInputStream_l();
     }
 
-    if (mFrameRepeatIntervalUs > 0ll && mLooper == NULL) {
+    if (mFrameRepeatIntervalUs > 0LL && mLooper == NULL) {
         mReflector = new AHandlerReflector<GraphicBufferSource>(this);
 
         mLooper = new ALooper;
@@ -655,7 +709,7 @@
 
     // only submit sample if start time is unspecified, or sample
     // is queued after the specified start time
-    if (mSkipFramesBeforeNs < 0ll || item.mTimestampNs >= mSkipFramesBeforeNs) {
+    if (mSkipFramesBeforeNs < 0LL || item.mTimestampNs >= mSkipFramesBeforeNs) {
         // if start time is set, offset time stamp by start time
         if (mSkipFramesBeforeNs > 0) {
             item.mTimestampNs -= mSkipFramesBeforeNs;
@@ -677,7 +731,7 @@
     } else {
         // Don't set the last buffer id if we're not repeating,
         // we'll be holding on to the last buffer for nothing.
-        if (mFrameRepeatIntervalUs > 0ll) {
+        if (mFrameRepeatIntervalUs > 0LL) {
             setLatestBuffer_l(item);
         }
         ALOGV("buffer submitted [slot=%d, useCount=%ld] acquired=%d",
@@ -755,7 +809,7 @@
             && (mFps > 2 * mCaptureFps
             || mCaptureFps > 2 * mFps)) {
         // Time lapse or slow motion mode
-        if (mPrevCaptureUs < 0ll) {
+        if (mPrevCaptureUs < 0LL) {
             // first capture
             mPrevCaptureUs = mBaseCaptureUs = timeUs;
             // adjust the first sample timestamp.
@@ -767,7 +821,7 @@
             double nFrames = (timeUs - mPrevCaptureUs) * mCaptureFps / 1000000;
             if (nFrames < 0.5 - kTimestampFluctuation) {
                 // skip this frame as it's too close to previous capture
-                ALOGV("skipping frame, timeUs %lld", static_cast<long long>(timeUs));
+                ALOGD("skipping frame, timeUs %lld", static_cast<long long>(timeUs));
                 return false;
             }
             if (nFrames <= 1.0) {
@@ -1106,6 +1160,14 @@
         consumerUsage |= GRALLOC_USAGE_HW_VIDEO_ENCODER;
         mConsumer->setConsumerUsageBits(consumerUsage);
 
+        // Set impl. defined format as default. Depending on the usage flags
+        // the device-specific implementation will derive the exact format.
+        err = mConsumer->setDefaultBufferFormat(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
+        if (err != NO_ERROR) {
+            ALOGE("Failed to configure surface default format ret: %d", err);
+            return err;
+        }
+
         // Sets the default buffer data space
         ALOGD("setting dataspace: %#x, acquired=%d", dataSpace, mNumOutstandingAcquires);
         mConsumer->setDefaultBufferDataSpace((android_dataspace)dataSpace);
@@ -1115,19 +1177,19 @@
         mSuspended = false;
         mEndOfStream = false;
         mEndOfStreamSent = false;
-        mSkipFramesBeforeNs = -1ll;
+        mSkipFramesBeforeNs = -1LL;
         mFrameDropper.clear();
-        mFrameRepeatIntervalUs = -1ll;
+        mFrameRepeatIntervalUs = -1LL;
         mRepeatLastFrameGeneration = 0;
         mOutstandingFrameRepeatCount = 0;
         mLatestBuffer.mBuffer.reset();
         mFrameRepeatBlockedOnCodecBuffer = false;
         mFps = -1.0;
         mCaptureFps = -1.0;
-        mBaseCaptureUs = -1ll;
-        mBaseFrameUs = -1ll;
-        mPrevCaptureUs = -1ll;
-        mPrevFrameUs = -1ll;
+        mBaseCaptureUs = -1LL;
+        mBaseFrameUs = -1LL;
+        mPrevCaptureUs = -1LL;
+        mPrevFrameUs = -1LL;
         mFrameCount = 0;
         mInputBufferTimeOffsetUs = 0;
         mStopTimeUs = -1;
@@ -1193,7 +1255,7 @@
 
     Mutex::Autolock autoLock(mMutex);
 
-    if (mExecuting || repeatAfterUs <= 0ll) {
+    if (mExecuting || repeatAfterUs <= 0LL) {
         return INVALID_OPERATION;
     }
 
@@ -1205,7 +1267,7 @@
     Mutex::Autolock autoLock(mMutex);
 
     // timeOffsetUs must be negative for adjustment.
-    if (timeOffsetUs >= 0ll) {
+    if (timeOffsetUs >= 0LL) {
         return INVALID_OPERATION;
     }
 
@@ -1239,7 +1301,7 @@
 
     mSkipFramesBeforeNs =
             (skipFramesBeforeUs > 0 && skipFramesBeforeUs <= INT64_MAX / 1000) ?
-            (skipFramesBeforeUs * 1000) : -1ll;
+            (skipFramesBeforeUs * 1000) : -1LL;
 
     return OK;
 }
diff --git a/media/libstagefright/bqhelper/WProducerListener.cpp b/media/libstagefright/bqhelper/WProducerListener.cpp
deleted file mode 100644
index 2ca13be..0000000
--- a/media/libstagefright/bqhelper/WProducerListener.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <media/stagefright/bqhelper/WProducerListener.h>
-
-namespace android {
-
-// TWProducerListener
-TWProducerListener::TWProducerListener(
-        sp<BProducerListener> const& base):
-    mBase(base) {
-}
-
-Return<void> TWProducerListener::onBufferReleased() {
-    mBase->onBufferReleased();
-    return Void();
-}
-
-Return<bool> TWProducerListener::needsReleaseNotify() {
-    return mBase->needsReleaseNotify();
-}
-
-// LWProducerListener
-LWProducerListener::LWProducerListener(
-        sp<HProducerListener> const& base):
-    mBase(base) {
-}
-
-void LWProducerListener::onBufferReleased() {
-    mBase->onBufferReleased();
-}
-
-bool LWProducerListener::needsReleaseNotify() {
-    return static_cast<bool>(mBase->needsReleaseNotify());
-}
-
-}  // namespace android
diff --git a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/Conversion.h b/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/Conversion.h
deleted file mode 100644
index 60d8c1e..0000000
--- a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/Conversion.h
+++ /dev/null
@@ -1,769 +0,0 @@
-/*
- * Copyright 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MEDIA_STAGEFRIGHT_BQHELPER_CONVERSION_H_
-#define MEDIA_STAGEFRIGHT_BQHELPER_CONVERSION_H_
-
-#include <vector>
-#include <list>
-
-#include <unistd.h>
-
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-#include <hidlmemory/mapping.h>
-
-#include <binder/Binder.h>
-#include <binder/Status.h>
-#include <ui/FenceTime.h>
-#include <cutils/native_handle.h>
-#include <gui/IGraphicBufferProducer.h>
-
-#include <media/hardware/VideoAPI.h>
-
-#include <android/hidl/memory/1.0/IMemory.h>
-#include <android/hardware/graphics/bufferqueue/1.0/IProducerListener.h>
-
-namespace android {
-namespace conversion {
-
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::hidl_handle;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::sp;
-using ::android::status_t;
-
-using ::android::String8;
-
-using ::android::hardware::media::V1_0::Rect;
-using ::android::hardware::media::V1_0::Region;
-
-using ::android::hardware::graphics::common::V1_0::Dataspace;
-
-using ::android::hardware::graphics::common::V1_0::PixelFormat;
-
-using ::android::hardware::media::V1_0::AnwBuffer;
-using ::android::GraphicBuffer;
-
-typedef ::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer
-        HGraphicBufferProducer;
-typedef ::android::IGraphicBufferProducer
-        BGraphicBufferProducer;
-
-// native_handle_t helper functions.
-
-/**
- * \brief Take an fd and create a native handle containing only the given fd.
- * The created handle will need to be deleted manually with
- * `native_handle_delete()`.
- *
- * \param[in] fd The source file descriptor (of type `int`).
- * \return The create `native_handle_t*` that contains the given \p fd. If the
- * supplied \p fd is negative, the created native handle will contain no file
- * descriptors.
- *
- * If the native handle cannot be created, the return value will be
- * `nullptr`.
- *
- * This function does not duplicate the file descriptor.
- */
-native_handle_t* native_handle_create_from_fd(int fd);
-
-/**
- * \brief Extract a file descriptor from a native handle.
- *
- * \param[in] nh The source `native_handle_t*`.
- * \param[in] index The index of the file descriptor in \p nh to read from. This
- * input has the default value of `0`.
- * \return The `index`-th file descriptor in \p nh. If \p nh does not have
- * enough file descriptors, the returned value will be `-1`.
- *
- * This function does not duplicate the file descriptor.
- */
-int native_handle_read_fd(native_handle_t const* nh, int index = 0);
-
-/**
- * Conversion functions
- * ====================
- *
- * There are two main directions of conversion:
- * - `inTargetType(...)`: Create a wrapper whose lifetime depends on the
- *   input. The wrapper has type `TargetType`.
- * - `toTargetType(...)`: Create a standalone object of type `TargetType` that
- *   corresponds to the input. The lifetime of the output does not depend on the
- *   lifetime of the input.
- * - `wrapIn(TargetType*, ...)`: Same as `inTargetType()`, but for `TargetType`
- *   that cannot be copied and/or moved efficiently, or when there are multiple
- *   output arguments.
- * - `convertTo(TargetType*, ...)`: Same as `toTargetType()`, but for
- *   `TargetType` that cannot be copied and/or moved efficiently, or when there
- *   are multiple output arguments.
- *
- * `wrapIn()` and `convertTo()` functions will take output arguments before
- * input arguments. Some of these functions might return a value to indicate
- * success or error.
- *
- * In converting or wrapping something as a Treble type that contains a
- * `hidl_handle`, `native_handle_t*` will need to be created and returned as
- * an additional output argument, hence only `wrapIn()` or `convertTo()` would
- * be available. The caller must call `native_handle_delete()` to deallocate the
- * returned native handle when it is no longer needed.
- *
- * For types that contain file descriptors, `inTargetType()` and `wrapAs()` do
- * not perform duplication of file descriptors, while `toTargetType()` and
- * `convertTo()` do.
- */
-
-/**
- * \brief Convert `Return<void>` to `binder::Status`.
- *
- * \param[in] t The source `Return<void>`.
- * \return The corresponding `binder::Status`.
- */
-// convert: Return<void> -> ::android::binder::Status
-::android::binder::Status toBinderStatus(Return<void> const& t);
-
-/**
- * \brief Convert `Return<void>` to `status_t`. This is for legacy binder calls.
- *
- * \param[in] t The source `Return<void>`.
- * \return The corresponding `status_t`.
- */
-// convert: Return<void> -> status_t
-status_t toStatusT(Return<void> const& t);
-
-/**
- * \brief Wrap `native_handle_t*` in `hidl_handle`.
- *
- * \param[in] nh The source `native_handle_t*`.
- * \return The `hidl_handle` that points to \p nh.
- */
-// wrap: native_handle_t* -> hidl_handle
-hidl_handle inHidlHandle(native_handle_t const* nh);
-
-/**
- * \brief Convert `int32_t` to `Dataspace`.
- *
- * \param[in] l The source `int32_t`.
- * \result The corresponding `Dataspace`.
- */
-// convert: int32_t -> Dataspace
-Dataspace toHardwareDataspace(int32_t l);
-
-/**
- * \brief Convert `Dataspace` to `int32_t`.
- *
- * \param[in] t The source `Dataspace`.
- * \result The corresponding `int32_t`.
- */
-// convert: Dataspace -> int32_t
-int32_t toRawDataspace(Dataspace const& t);
-
-/**
- * \brief Wrap an opaque buffer inside a `hidl_vec<uint8_t>`.
- *
- * \param[in] l The pointer to the beginning of the opaque buffer.
- * \param[in] size The size of the buffer.
- * \return A `hidl_vec<uint8_t>` that points to the buffer.
- */
-// wrap: void*, size_t -> hidl_vec<uint8_t>
-hidl_vec<uint8_t> inHidlBytes(void const* l, size_t size);
-
-/**
- * \brief Create a `hidl_vec<uint8_t>` that is a copy of an opaque buffer.
- *
- * \param[in] l The pointer to the beginning of the opaque buffer.
- * \param[in] size The size of the buffer.
- * \return A `hidl_vec<uint8_t>` that is a copy of the input buffer.
- */
-// convert: void*, size_t -> hidl_vec<uint8_t>
-hidl_vec<uint8_t> toHidlBytes(void const* l, size_t size);
-
-/**
- * \brief Wrap `GraphicBuffer` in `AnwBuffer`.
- *
- * \param[out] t The wrapper of type `AnwBuffer`.
- * \param[in] l The source `GraphicBuffer`.
- */
-// wrap: GraphicBuffer -> AnwBuffer
-void wrapAs(AnwBuffer* t, GraphicBuffer const& l);
-
-/**
- * \brief Convert `AnwBuffer` to `GraphicBuffer`.
- *
- * \param[out] l The destination `GraphicBuffer`.
- * \param[in] t The source `AnwBuffer`.
- *
- * This function will duplicate all file descriptors in \p t.
- */
-// convert: AnwBuffer -> GraphicBuffer
-// Ref: frameworks/native/libs/ui/GraphicBuffer.cpp: GraphicBuffer::flatten
-bool convertTo(GraphicBuffer* l, AnwBuffer const& t);
-
-/**
- * Conversion functions for types outside media
- * ============================================
- *
- * Some objects in libui and libgui that were made to go through binder calls do
- * not expose ways to read or write their fields to the public. To pass an
- * object of this kind through the HIDL boundary, translation functions need to
- * work around the access restriction by using the publicly available
- * `flatten()` and `unflatten()` functions.
- *
- * All `flatten()` and `unflatten()` overloads follow the same convention as
- * follows:
- *
- *     status_t flatten(ObjectType const& object,
- *                      [OtherType const& other, ...]
- *                      void*& buffer, size_t& size,
- *                      int*& fds, size_t& numFds)
- *
- *     status_t unflatten(ObjectType* object,
- *                        [OtherType* other, ...,]
- *                        void*& buffer, size_t& size,
- *                        int*& fds, size_t& numFds)
- *
- * The number of `other` parameters varies depending on the `ObjectType`. For
- * example, in the process of unflattening an object that contains
- * `hidl_handle`, `other` is needed to hold `native_handle_t` objects that will
- * be created.
- *
- * The last four parameters always work the same way in all overloads of
- * `flatten()` and `unflatten()`:
- * - For `flatten()`, `buffer` is the pointer to the non-fd buffer to be filled,
- *   `size` is the size (in bytes) of the non-fd buffer pointed to by `buffer`,
- *   `fds` is the pointer to the fd buffer to be filled, and `numFds` is the
- *   size (in ints) of the fd buffer pointed to by `fds`.
- * - For `unflatten()`, `buffer` is the pointer to the non-fd buffer to be read
- *   from, `size` is the size (in bytes) of the non-fd buffer pointed to by
- *   `buffer`, `fds` is the pointer to the fd buffer to be read from, and
- *   `numFds` is the size (in ints) of the fd buffer pointed to by `fds`.
- * - After a successful call to `flatten()` or `unflatten()`, `buffer` and `fds`
- *   will be advanced, while `size` and `numFds` will be decreased to reflect
- *   how much storage/data of the two buffers (fd and non-fd) have been used.
- * - After an unsuccessful call, the values of `buffer`, `size`, `fds` and
- *   `numFds` are invalid.
- *
- * The return value of a successful `flatten()` or `unflatten()` call will be
- * `OK` (also aliased as `NO_ERROR`). Any other values indicate a failure.
- *
- * For each object type that supports flattening, there will be two accompanying
- * functions: `getFlattenedSize()` and `getFdCount()`. `getFlattenedSize()` will
- * return the size of the non-fd buffer that the object will need for
- * flattening. `getFdCount()` will return the size of the fd buffer that the
- * object will need for flattening.
- *
- * The set of these four functions, `getFlattenedSize()`, `getFdCount()`,
- * `flatten()` and `unflatten()`, are similar to functions of the same name in
- * the abstract class `Flattenable`. The only difference is that functions in
- * this file are not member functions of the object type. For example, we write
- *
- *     flatten(x, buffer, size, fds, numFds)
- *
- * instead of
- *
- *     x.flatten(buffer, size, fds, numFds)
- *
- * because we cannot modify the type of `x`.
- *
- * There is one exception to the naming convention: `hidl_handle` that
- * represents a fence. The four functions for this "Fence" type have the word
- * "Fence" attched to their names because the object type, which is
- * `hidl_handle`, does not carry the special meaning that the object itself can
- * only contain zero or one file descriptor.
- */
-
-// Ref: frameworks/native/libs/ui/Fence.cpp
-
-/**
- * \brief Return the size of the non-fd buffer required to flatten a fence.
- *
- * \param[in] fence The input fence of type `hidl_handle`.
- * \return The required size of the flat buffer.
- *
- * The current version of this function always returns 4, which is the number of
- * bytes required to store the number of file descriptors contained in the fd
- * part of the flat buffer.
- */
-size_t getFenceFlattenedSize(hidl_handle const& fence);
-
-/**
- * \brief Return the number of file descriptors contained in a fence.
- *
- * \param[in] fence The input fence of type `hidl_handle`.
- * \return `0` if \p fence does not contain a valid file descriptor, or `1`
- * otherwise.
- */
-size_t getFenceFdCount(hidl_handle const& fence);
-
-/**
- * \brief Unflatten `Fence` to `hidl_handle`.
- *
- * \param[out] fence The destination `hidl_handle`.
- * \param[out] nh The underlying native handle.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * If the return value is `NO_ERROR`, \p nh will point to a newly created
- * native handle, which needs to be deleted with `native_handle_delete()`
- * afterwards.
- */
-status_t unflattenFence(hidl_handle* fence, native_handle_t** nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds);
-
-/**
- * \brief Flatten `hidl_handle` as `Fence`.
- *
- * \param[in] t The source `hidl_handle`.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- */
-status_t flattenFence(hidl_handle const& fence,
-        void*& buffer, size_t& size, int*& fds, size_t& numFds);
-
-/**
- * \brief Wrap `Fence` in `hidl_handle`.
- *
- * \param[out] t The wrapper of type `hidl_handle`.
- * \param[out] nh The native handle pointed to by \p t.
- * \param[in] l The source `Fence`.
- *
- * On success, \p nh will hold a newly created native handle, which must be
- * deleted manually with `native_handle_delete()` afterwards.
- */
-// wrap: Fence -> hidl_handle
-bool wrapAs(hidl_handle* t, native_handle_t** nh, Fence const& l);
-
-/**
- * \brief Convert `hidl_handle` to `Fence`.
- *
- * \param[out] l The destination `Fence`. `l` must not have been used
- * (`l->isValid()` must return `false`) before this function is called.
- * \param[in] t The source `hidl_handle`.
- *
- * If \p t contains a valid file descriptor, it will be duplicated.
- */
-// convert: hidl_handle -> Fence
-bool convertTo(Fence* l, hidl_handle const& t);
-
-// Ref: frameworks/native/libs/ui/FenceTime.cpp: FenceTime::Snapshot
-
-/**
- * \brief Return the size of the non-fd buffer required to flatten
- * `FenceTimeSnapshot`.
- *
- * \param[in] t The input `FenceTimeSnapshot`.
- * \return The required size of the flat buffer.
- */
-size_t getFlattenedSize(HGraphicBufferProducer::FenceTimeSnapshot const& t);
-
-/**
- * \brief Return the number of file descriptors contained in
- * `FenceTimeSnapshot`.
- *
- * \param[in] t The input `FenceTimeSnapshot`.
- * \return The number of file descriptors contained in \p snapshot.
- */
-size_t getFdCount(HGraphicBufferProducer::FenceTimeSnapshot const& t);
-
-/**
- * \brief Flatten `FenceTimeSnapshot`.
- *
- * \param[in] t The source `FenceTimeSnapshot`.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * This function will duplicate the file descriptor in `t.fence` if `t.state ==
- * FENCE`.
- */
-status_t flatten(HGraphicBufferProducer::FenceTimeSnapshot const& t,
-        void*& buffer, size_t& size, int*& fds, size_t& numFds);
-
-/**
- * \brief Unflatten `FenceTimeSnapshot`.
- *
- * \param[out] t The destination `FenceTimeSnapshot`.
- * \param[out] nh The underlying native handle.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * If the return value is `NO_ERROR` and the constructed snapshot contains a
- * file descriptor, \p nh will be created to hold that file descriptor. In this
- * case, \p nh needs to be deleted with `native_handle_delete()` afterwards.
- */
-status_t unflatten(
-        HGraphicBufferProducer::FenceTimeSnapshot* t, native_handle_t** nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds);
-
-// Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventsDelta
-
-/**
- * \brief Return the size of the non-fd buffer required to flatten
- * `FrameEventsDelta`.
- *
- * \param[in] t The input `FrameEventsDelta`.
- * \return The required size of the flat buffer.
- */
-size_t getFlattenedSize(HGraphicBufferProducer::FrameEventsDelta const& t);
-
-/**
- * \brief Return the number of file descriptors contained in
- * `FrameEventsDelta`.
- *
- * \param[in] t The input `FrameEventsDelta`.
- * \return The number of file descriptors contained in \p t.
- */
-size_t getFdCount(HGraphicBufferProducer::FrameEventsDelta const& t);
-
-/**
- * \brief Unflatten `FrameEventsDelta`.
- *
- * \param[out] t The destination `FrameEventsDelta`.
- * \param[out] nh The underlying array of native handles.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * If the return value is `NO_ERROR`, \p nh will have length 4, and it will be
- * populated with `nullptr` or newly created handles. Each non-null slot in \p
- * nh will need to be deleted manually with `native_handle_delete()`.
- */
-status_t unflatten(HGraphicBufferProducer::FrameEventsDelta* t,
-        std::vector<native_handle_t*>* nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds);
-
-/**
- * \brief Flatten `FrameEventsDelta`.
- *
- * \param[in] t The source `FrameEventsDelta`.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * This function will duplicate file descriptors contained in \p t.
- */
-// Ref: frameworks/native/libs/gui/FrameTimestamp.cpp:
-//      FrameEventsDelta::flatten
-status_t flatten(HGraphicBufferProducer::FrameEventsDelta const& t,
-        void*& buffer, size_t& size, int*& fds, size_t numFds);
-
-// Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventHistoryDelta
-
-/**
- * \brief Return the size of the non-fd buffer required to flatten
- * `HGraphicBufferProducer::FrameEventHistoryDelta`.
- *
- * \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`.
- * \return The required size of the flat buffer.
- */
-size_t getFlattenedSize(
-        HGraphicBufferProducer::FrameEventHistoryDelta const& t);
-
-/**
- * \brief Return the number of file descriptors contained in
- * `HGraphicBufferProducer::FrameEventHistoryDelta`.
- *
- * \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`.
- * \return The number of file descriptors contained in \p t.
- */
-size_t getFdCount(
-        HGraphicBufferProducer::FrameEventHistoryDelta const& t);
-
-/**
- * \brief Unflatten `FrameEventHistoryDelta`.
- *
- * \param[out] t The destination `FrameEventHistoryDelta`.
- * \param[out] nh The underlying array of arrays of native handles.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * If the return value is `NO_ERROR`, \p nh will be populated with `nullptr` or
- * newly created handles. The second dimension of \p nh will be 4. Each non-null
- * slot in \p nh will need to be deleted manually with `native_handle_delete()`.
- */
-status_t unflatten(
-        HGraphicBufferProducer::FrameEventHistoryDelta* t,
-        std::vector<std::vector<native_handle_t*> >* nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds);
-
-/**
- * \brief Flatten `FrameEventHistoryDelta`.
- *
- * \param[in] t The source `FrameEventHistoryDelta`.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * This function will duplicate file descriptors contained in \p t.
- */
-status_t flatten(
-        HGraphicBufferProducer::FrameEventHistoryDelta const& t,
-        void*& buffer, size_t& size, int*& fds, size_t& numFds);
-
-/**
- * \brief Wrap `::android::FrameEventHistoryData` in
- * `HGraphicBufferProducer::FrameEventHistoryDelta`.
- *
- * \param[out] t The wrapper of type
- * `HGraphicBufferProducer::FrameEventHistoryDelta`.
- * \param[out] nh The array of array of native handles that are referred to by
- * members of \p t.
- * \param[in] l The source `::android::FrameEventHistoryDelta`.
- *
- * On success, each member of \p nh will be either `nullptr` or a newly created
- * native handle. All the non-`nullptr` elements must be deleted individually
- * with `native_handle_delete()`.
- */
-bool wrapAs(HGraphicBufferProducer::FrameEventHistoryDelta* t,
-        std::vector<std::vector<native_handle_t*> >* nh,
-        ::android::FrameEventHistoryDelta const& l);
-
-/**
- * \brief Convert `HGraphicBufferProducer::FrameEventHistoryDelta` to
- * `::android::FrameEventHistoryDelta`.
- *
- * \param[out] l The destination `::android::FrameEventHistoryDelta`.
- * \param[in] t The source `HGraphicBufferProducer::FrameEventHistoryDelta`.
- *
- * This function will duplicate all file descriptors contained in \p t.
- */
-bool convertTo(
-        ::android::FrameEventHistoryDelta* l,
-        HGraphicBufferProducer::FrameEventHistoryDelta const& t);
-
-// Ref: frameworks/native/libs/ui/Region.cpp
-
-/**
- * \brief Return the size of the buffer required to flatten `Region`.
- *
- * \param[in] t The input `Region`.
- * \return The required size of the flat buffer.
- */
-size_t getFlattenedSize(Region const& t);
-
-/**
- * \brief Unflatten `Region`.
- *
- * \param[out] t The destination `Region`.
- * \param[in,out] buffer The pointer to the flat buffer.
- * \param[in,out] size The size of the flat buffer.
- * \return `NO_ERROR` on success; other value on failure.
- */
-status_t unflatten(Region* t, void const*& buffer, size_t& size);
-
-/**
- * \brief Flatten `Region`.
- *
- * \param[in] t The source `Region`.
- * \param[in,out] buffer The pointer to the flat buffer.
- * \param[in,out] size The size of the flat buffer.
- * \return `NO_ERROR` on success; other value on failure.
- */
-status_t flatten(Region const& t, void*& buffer, size_t& size);
-
-/**
- * \brief Convert `::android::Region` to `Region`.
- *
- * \param[out] t The destination `Region`.
- * \param[in] l The source `::android::Region`.
- */
-// convert: ::android::Region -> Region
-bool convertTo(Region* t, ::android::Region const& l);
-
-/**
- * \brief Convert `Region` to `::android::Region`.
- *
- * \param[out] l The destination `::android::Region`.
- * \param[in] t The source `Region`.
- */
-// convert: Region -> ::android::Region
-bool convertTo(::android::Region* l, Region const& t);
-
-// Ref: frameworks/native/libs/gui/BGraphicBufferProducer.cpp:
-//      BGraphicBufferProducer::QueueBufferInput
-
-/**
- * \brief Return the size of the buffer required to flatten
- * `HGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
- * \return The required size of the flat buffer.
- */
-size_t getFlattenedSize(HGraphicBufferProducer::QueueBufferInput const& t);
-
-/**
- * \brief Return the number of file descriptors contained in
- * `HGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
- * \return The number of file descriptors contained in \p t.
- */
-size_t getFdCount(
-        HGraphicBufferProducer::QueueBufferInput const& t);
-/**
- * \brief Flatten `HGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[in] t The source `HGraphicBufferProducer::QueueBufferInput`.
- * \param[out] nh The native handle cloned from `t.fence`.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * This function will duplicate the file descriptor in `t.fence`. */
-status_t flatten(HGraphicBufferProducer::QueueBufferInput const& t,
-        native_handle_t** nh,
-        void*& buffer, size_t& size, int*& fds, size_t& numFds);
-
-/**
- * \brief Unflatten `HGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[out] t The destination `HGraphicBufferProducer::QueueBufferInput`.
- * \param[out] nh The underlying native handle for `t->fence`.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * If the return value is `NO_ERROR` and `t->fence` contains a valid file
- * descriptor, \p nh will be a newly created native handle holding that file
- * descriptor. \p nh needs to be deleted with `native_handle_delete()`
- * afterwards.
- */
-status_t unflatten(
-        HGraphicBufferProducer::QueueBufferInput* t, native_handle_t** nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds);
-
-/**
- * \brief Wrap `BGraphicBufferProducer::QueueBufferInput` in
- * `HGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[out] t The wrapper of type
- * `HGraphicBufferProducer::QueueBufferInput`.
- * \param[out] nh The underlying native handle for `t->fence`.
- * \param[in] l The source `BGraphicBufferProducer::QueueBufferInput`.
- *
- * If the return value is `true` and `t->fence` contains a valid file
- * descriptor, \p nh will be a newly created native handle holding that file
- * descriptor. \p nh needs to be deleted with `native_handle_delete()`
- * afterwards.
- */
-bool wrapAs(
-        HGraphicBufferProducer::QueueBufferInput* t,
-        native_handle_t** nh,
-        BGraphicBufferProducer::QueueBufferInput const& l);
-
-/**
- * \brief Convert `HGraphicBufferProducer::QueueBufferInput` to
- * `BGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[out] l The destination `BGraphicBufferProducer::QueueBufferInput`.
- * \param[in] t The source `HGraphicBufferProducer::QueueBufferInput`.
- *
- * If `t.fence` has a valid file descriptor, it will be duplicated.
- */
-bool convertTo(
-        BGraphicBufferProducer::QueueBufferInput* l,
-        HGraphicBufferProducer::QueueBufferInput const& t);
-
-// Ref: frameworks/native/libs/gui/BGraphicBufferProducer.cpp:
-//      BGraphicBufferProducer::QueueBufferOutput
-
-/**
- * \brief Wrap `BGraphicBufferProducer::QueueBufferOutput` in
- * `HGraphicBufferProducer::QueueBufferOutput`.
- *
- * \param[out] t The wrapper of type
- * `HGraphicBufferProducer::QueueBufferOutput`.
- * \param[out] nh The array of array of native handles that are referred to by
- * members of \p t.
- * \param[in] l The source `BGraphicBufferProducer::QueueBufferOutput`.
- *
- * On success, each member of \p nh will be either `nullptr` or a newly created
- * native handle. All the non-`nullptr` elements must be deleted individually
- * with `native_handle_delete()`.
- */
-// wrap: BGraphicBufferProducer::QueueBufferOutput ->
-// HGraphicBufferProducer::QueueBufferOutput
-bool wrapAs(HGraphicBufferProducer::QueueBufferOutput* t,
-        std::vector<std::vector<native_handle_t*> >* nh,
-        BGraphicBufferProducer::QueueBufferOutput const& l);
-
-/**
- * \brief Convert `HGraphicBufferProducer::QueueBufferOutput` to
- * `BGraphicBufferProducer::QueueBufferOutput`.
- *
- * \param[out] l The destination `BGraphicBufferProducer::QueueBufferOutput`.
- * \param[in] t The source `HGraphicBufferProducer::QueueBufferOutput`.
- *
- * This function will duplicate all file descriptors contained in \p t.
- */
-// convert: HGraphicBufferProducer::QueueBufferOutput ->
-// BGraphicBufferProducer::QueueBufferOutput
-bool convertTo(
-        BGraphicBufferProducer::QueueBufferOutput* l,
-        HGraphicBufferProducer::QueueBufferOutput const& t);
-
-/**
- * \brief Convert `BGraphicBufferProducer::DisconnectMode` to
- * `HGraphicBufferProducer::DisconnectMode`.
- *
- * \param[in] l The source `BGraphicBufferProducer::DisconnectMode`.
- * \return The corresponding `HGraphicBufferProducer::DisconnectMode`.
- */
-HGraphicBufferProducer::DisconnectMode toHidlDisconnectMode(
-        BGraphicBufferProducer::DisconnectMode l);
-
-/**
- * \brief Convert `HGraphicBufferProducer::DisconnectMode` to
- * `BGraphicBufferProducer::DisconnectMode`.
- *
- * \param[in] l The source `HGraphicBufferProducer::DisconnectMode`.
- * \return The corresponding `BGraphicBufferProducer::DisconnectMode`.
- */
-BGraphicBufferProducer::DisconnectMode toGuiDisconnectMode(
-        HGraphicBufferProducer::DisconnectMode t);
-
-}  // namespace conversion
-}  // namespace android
-
-#endif  // MEDIA_STAGEFRIGHT_BQHELPER_CONVERSION_H_
diff --git a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/GraphicBufferSource.h b/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/GraphicBufferSource.h
index abc8910..b4c4d4a 100644
--- a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/GraphicBufferSource.h
+++ b/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/GraphicBufferSource.h
@@ -19,8 +19,6 @@
 #define GRAPHIC_BUFFER_SOURCE_H_
 
 #include <binder/Status.h>
-#include <gui/BufferQueue.h>
-#include <gui/IGraphicBufferProducer.h>
 #include <utils/RefBase.h>
 
 #include <media/hardware/VideoAPI.h>
@@ -28,13 +26,17 @@
 #include <media/stagefright/foundation/AHandlerReflector.h>
 #include <media/stagefright/foundation/ALooper.h>
 #include <media/stagefright/bqhelper/ComponentWrapper.h>
+#include <android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer.h>
+#include <android/hardware/graphics/bufferqueue/2.0/IGraphicBufferProducer.h>
 
 namespace android {
 
 using ::android::binder::Status;
 
 struct FrameDropper;
-
+class BufferItem;
+class IGraphicBufferProducer;
+class IGraphicBufferConsumer;
 /*
  * This class is used to feed codecs from a Surface via BufferQueue or
  * HW producer.
@@ -68,7 +70,7 @@
  * (even if it was dropped) to reencode it after an interval if no further
  * frames are sent by the producer.
  */
-class GraphicBufferSource : public BufferQueue::ConsumerListener {
+class GraphicBufferSource : public RefBase {
 public:
     GraphicBufferSource();
 
@@ -82,9 +84,17 @@
 
     // Returns the handle to the producer side of the BufferQueue.  Buffers
     // queued on this will be received by GraphicBufferSource.
-    sp<IGraphicBufferProducer> getIGraphicBufferProducer() const {
-        return mProducer;
-    }
+    sp<IGraphicBufferProducer> getIGraphicBufferProducer() const;
+
+    // Returns the handle to the bufferqueue HAL (V1_0) producer side of the BufferQueue.
+    // Buffers queued on this will be received by GraphicBufferSource.
+    sp<::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer>
+        getHGraphicBufferProducer_V1_0() const;
+
+    // Returns the handle to the bufferqueue HAL producer side of the BufferQueue.
+    // Buffers queued on this will be received by GraphicBufferSource.
+    sp<::android::hardware::graphics::bufferqueue::V2_0::IGraphicBufferProducer>
+        getHGraphicBufferProducer() const;
 
     // This is called when component transitions to running state, which means
     // we can start handing it buffers.  If we already have buffers of data
@@ -190,8 +200,6 @@
     status_t setColorAspects(int32_t aspectsPacked);
 
 protected:
-    // BQ::ConsumerListener interface
-    // ------------------------------
 
     // BufferQueue::ConsumerListener interface, called when a new frame of
     // data is available.  If we're executing and a codec buffer is
@@ -199,19 +207,24 @@
     // into the codec buffer, and call Empty[This]Buffer.  If we're not yet
     // executing or there's no codec buffer available, we just increment
     // mNumFramesAvailable and return.
-    void onFrameAvailable(const BufferItem& item) override;
+    void onFrameAvailable(const BufferItem& item) ;
 
     // BufferQueue::ConsumerListener interface, called when the client has
     // released one or more GraphicBuffers.  We clear out the appropriate
     // set of mBufferSlot entries.
-    void onBuffersReleased() override;
+    void onBuffersReleased() ;
 
     // BufferQueue::ConsumerListener interface, called when the client has
     // changed the sideband stream. GraphicBufferSource doesn't handle sideband
     // streams so this is a no-op (and should never be called).
-    void onSidebandStreamChanged() override;
+    void onSidebandStreamChanged() ;
 
 private:
+    // BQ::ConsumerListener interface
+    // ------------------------------
+    struct ConsumerProxy;
+    sp<ConsumerProxy> mConsumerProxy;
+
     // Lock, covers all member variables.
     mutable Mutex mMutex;
 
diff --git a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/WGraphicBufferProducer.h b/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/WGraphicBufferProducer.h
deleted file mode 100644
index c14a1c2..0000000
--- a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/WGraphicBufferProducer.h
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Copyright 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MEDIA_STAGEFRIGHT_WGRAPHICBUFFERPRODUCER_H_
-#define MEDIA_STAGEFRIGHT_WGRAPHICBUFFERPRODUCER_H_
-
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-
-#include <binder/Binder.h>
-#include <gui/IGraphicBufferProducer.h>
-#include <gui/IProducerListener.h>
-#include <media/stagefright/bqhelper/Conversion.h>
-#include <media/stagefright/bqhelper/WProducerListener.h>
-#include <system/window.h>
-
-#include <android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer.h>
-
-namespace android {
-
-using ::android::hardware::media::V1_0::AnwBuffer;
-using ::android::hidl::base::V1_0::IBase;
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_handle;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::sp;
-
-typedef ::android::hardware::graphics::bufferqueue::V1_0::
-        IGraphicBufferProducer HGraphicBufferProducer;
-typedef ::android::hardware::graphics::bufferqueue::V1_0::
-        IProducerListener HProducerListener;
-
-typedef ::android::IGraphicBufferProducer BGraphicBufferProducer;
-typedef ::android::IProducerListener BProducerListener;
-using ::android::BnGraphicBufferProducer;
-
-#ifndef LOG
-struct LOG_dummy {
-    template <typename T>
-    LOG_dummy& operator<< (const T&) { return *this; }
-};
-
-#define LOG(x)  LOG_dummy()
-#endif
-
-// Instantiate only if HGraphicBufferProducer is base of BASE.
-template <typename BASE,
-          typename = typename std::enable_if<std::is_base_of<HGraphicBufferProducer, BASE>::value>::type>
-struct TWGraphicBufferProducer : public BASE {
-    TWGraphicBufferProducer(sp<BGraphicBufferProducer> const& base) : mBase(base) {}
-    Return<void> requestBuffer(int32_t slot, HGraphicBufferProducer::requestBuffer_cb _hidl_cb) override {
-        sp<GraphicBuffer> buf;
-        status_t status = mBase->requestBuffer(slot, &buf);
-        AnwBuffer anwBuffer{};
-        if (buf != nullptr) {
-            ::android::conversion::wrapAs(&anwBuffer, *buf);
-        }
-        _hidl_cb(static_cast<int32_t>(status), anwBuffer);
-        return Void();
-    }
-
-    Return<int32_t> setMaxDequeuedBufferCount(int32_t maxDequeuedBuffers) override {
-        return static_cast<int32_t>(mBase->setMaxDequeuedBufferCount(
-                static_cast<int>(maxDequeuedBuffers)));
-    }
-
-    Return<int32_t> setAsyncMode(bool async) override {
-        return static_cast<int32_t>(mBase->setAsyncMode(async));
-    }
-
-    Return<void> dequeueBuffer(
-            uint32_t width, uint32_t height,
-            ::android::hardware::graphics::common::V1_0::PixelFormat format, uint32_t usage,
-            bool getFrameTimestamps, HGraphicBufferProducer::dequeueBuffer_cb _hidl_cb) override {
-        int slot{};
-        sp<Fence> fence;
-        ::android::FrameEventHistoryDelta outTimestamps;
-        status_t status = mBase->dequeueBuffer(
-            &slot, &fence, width, height,
-            static_cast<::android::PixelFormat>(format), usage, nullptr,
-            getFrameTimestamps ? &outTimestamps : nullptr);
-        hidl_handle tFence{};
-        HGraphicBufferProducer::FrameEventHistoryDelta tOutTimestamps{};
-
-        native_handle_t* nh = nullptr;
-        if ((fence == nullptr) || !::android::conversion::wrapAs(&tFence, &nh, *fence)) {
-            LOG(ERROR) << "TWGraphicBufferProducer::dequeueBuffer - "
-                    "Invalid output fence";
-            _hidl_cb(static_cast<int32_t>(status),
-                     static_cast<int32_t>(slot),
-                     tFence,
-                     tOutTimestamps);
-            return Void();
-        }
-        std::vector<std::vector<native_handle_t*> > nhAA;
-        if (getFrameTimestamps && !::android::conversion::wrapAs(&tOutTimestamps, &nhAA, outTimestamps)) {
-            LOG(ERROR) << "TWGraphicBufferProducer::dequeueBuffer - "
-                    "Invalid output timestamps";
-            _hidl_cb(static_cast<int32_t>(status),
-                     static_cast<int32_t>(slot),
-                     tFence,
-                     tOutTimestamps);
-            native_handle_delete(nh);
-            return Void();
-        }
-
-        _hidl_cb(static_cast<int32_t>(status),
-                static_cast<int32_t>(slot),
-                tFence,
-                tOutTimestamps);
-        native_handle_delete(nh);
-        if (getFrameTimestamps) {
-            for (auto& nhA : nhAA) {
-                for (auto& handle : nhA) {
-                    native_handle_delete(handle);
-                }
-            }
-        }
-        return Void();
-    }
-
-    Return<int32_t> detachBuffer(int32_t slot) override {
-        return static_cast<int32_t>(mBase->detachBuffer(slot));
-    }
-
-    Return<void> detachNextBuffer(HGraphicBufferProducer::detachNextBuffer_cb _hidl_cb) override {
-        sp<GraphicBuffer> outBuffer;
-        sp<Fence> outFence;
-        status_t status = mBase->detachNextBuffer(&outBuffer, &outFence);
-        AnwBuffer tBuffer{};
-        hidl_handle tFence{};
-
-        if (outBuffer == nullptr) {
-            LOG(ERROR) << "TWGraphicBufferProducer::detachNextBuffer - "
-                    "Invalid output buffer";
-            _hidl_cb(static_cast<int32_t>(status), tBuffer, tFence);
-            return Void();
-        }
-        ::android::conversion::wrapAs(&tBuffer, *outBuffer);
-        native_handle_t* nh = nullptr;
-        if ((outFence != nullptr) && !::android::conversion::wrapAs(&tFence, &nh, *outFence)) {
-            LOG(ERROR) << "TWGraphicBufferProducer::detachNextBuffer - "
-                    "Invalid output fence";
-            _hidl_cb(static_cast<int32_t>(status), tBuffer, tFence);
-            return Void();
-        }
-
-        _hidl_cb(static_cast<int32_t>(status), tBuffer, tFence);
-        native_handle_delete(nh);
-        return Void();
-    }
-
-    Return<void> attachBuffer(const AnwBuffer& buffer, HGraphicBufferProducer::attachBuffer_cb _hidl_cb) override {
-        int outSlot;
-        sp<GraphicBuffer> lBuffer = new GraphicBuffer();
-        if (!::android::conversion::convertTo(lBuffer.get(), buffer)) {
-            LOG(ERROR) << "TWGraphicBufferProducer::attachBuffer - "
-                    "Invalid input native window buffer";
-            _hidl_cb(static_cast<int32_t>(BAD_VALUE), -1);
-            return Void();
-        }
-        status_t status = mBase->attachBuffer(&outSlot, lBuffer);
-
-        _hidl_cb(static_cast<int32_t>(status), static_cast<int32_t>(outSlot));
-        return Void();
-    }
-
-    Return<void> queueBuffer(
-            int32_t slot, const HGraphicBufferProducer::QueueBufferInput& input,
-            HGraphicBufferProducer::queueBuffer_cb _hidl_cb) override {
-        HGraphicBufferProducer::QueueBufferOutput tOutput{};
-        BGraphicBufferProducer::QueueBufferInput lInput(
-                0, false, HAL_DATASPACE_UNKNOWN,
-                ::android::Rect(0, 0, 1, 1),
-                NATIVE_WINDOW_SCALING_MODE_FREEZE,
-                0, ::android::Fence::NO_FENCE);
-        if (!::android::conversion::convertTo(&lInput, input)) {
-            LOG(ERROR) << "TWGraphicBufferProducer::queueBuffer - "
-                    "Invalid input";
-            _hidl_cb(static_cast<int32_t>(BAD_VALUE), tOutput);
-            return Void();
-        }
-        BGraphicBufferProducer::QueueBufferOutput lOutput;
-        status_t status = mBase->queueBuffer(
-                static_cast<int>(slot), lInput, &lOutput);
-
-        std::vector<std::vector<native_handle_t*> > nhAA;
-        if (!::android::conversion::wrapAs(&tOutput, &nhAA, lOutput)) {
-            LOG(ERROR) << "TWGraphicBufferProducer::queueBuffer - "
-                    "Invalid output";
-            _hidl_cb(static_cast<int32_t>(BAD_VALUE), tOutput);
-            return Void();
-        }
-
-        _hidl_cb(static_cast<int32_t>(status), tOutput);
-        for (auto& nhA : nhAA) {
-            for (auto& nh : nhA) {
-                native_handle_delete(nh);
-            }
-        }
-        return Void();
-    }
-
-    Return<int32_t> cancelBuffer(int32_t slot, const hidl_handle& fence) override {
-        sp<Fence> lFence = new Fence();
-        if (!::android::conversion::convertTo(lFence.get(), fence)) {
-            LOG(ERROR) << "TWGraphicBufferProducer::cancelBuffer - "
-                    "Invalid input fence";
-            return static_cast<int32_t>(BAD_VALUE);
-        }
-        return static_cast<int32_t>(mBase->cancelBuffer(static_cast<int>(slot), lFence));
-    }
-
-    Return<void> query(int32_t what, HGraphicBufferProducer::query_cb _hidl_cb) override {
-        int lValue;
-        int lReturn = mBase->query(static_cast<int>(what), &lValue);
-        _hidl_cb(static_cast<int32_t>(lReturn), static_cast<int32_t>(lValue));
-        return Void();
-    }
-
-    Return<void> connect(const sp<HProducerListener>& listener,
-            int32_t api, bool producerControlledByApp,
-            HGraphicBufferProducer::connect_cb _hidl_cb) override {
-        sp<BProducerListener> lListener = listener == nullptr ?
-                nullptr : new LWProducerListener(listener);
-        BGraphicBufferProducer::QueueBufferOutput lOutput;
-        status_t status = mBase->connect(lListener,
-                static_cast<int>(api),
-                producerControlledByApp,
-                &lOutput);
-
-        HGraphicBufferProducer::QueueBufferOutput tOutput{};
-        std::vector<std::vector<native_handle_t*> > nhAA;
-        if (!::android::conversion::wrapAs(&tOutput, &nhAA, lOutput)) {
-            LOG(ERROR) << "TWGraphicBufferProducer::connect - "
-                    "Invalid output";
-            _hidl_cb(static_cast<int32_t>(status), tOutput);
-            return Void();
-        }
-
-        _hidl_cb(static_cast<int32_t>(status), tOutput);
-        for (auto& nhA : nhAA) {
-            for (auto& nh : nhA) {
-                native_handle_delete(nh);
-            }
-        }
-        return Void();
-    }
-
-    Return<int32_t> disconnect(
-            int32_t api,
-            HGraphicBufferProducer::DisconnectMode mode) override {
-        return static_cast<int32_t>(mBase->disconnect(
-                static_cast<int>(api),
-                ::android::conversion::toGuiDisconnectMode(mode)));
-    }
-
-    Return<int32_t> setSidebandStream(const hidl_handle& stream) override {
-        return static_cast<int32_t>(mBase->setSidebandStream(NativeHandle::create(
-                stream ? native_handle_clone(stream) : NULL, true)));
-    }
-
-    Return<void> allocateBuffers(
-            uint32_t width, uint32_t height,
-            ::android::hardware::graphics::common::V1_0::PixelFormat format,
-            uint32_t usage) override {
-        mBase->allocateBuffers(
-                width, height,
-                static_cast<::android::PixelFormat>(format),
-                usage);
-        return Void();
-    }
-
-    Return<int32_t> allowAllocation(bool allow) override {
-        return static_cast<int32_t>(mBase->allowAllocation(allow));
-    }
-
-    Return<int32_t> setGenerationNumber(uint32_t generationNumber) override {
-        return static_cast<int32_t>(mBase->setGenerationNumber(generationNumber));
-    }
-
-    Return<void> getConsumerName(HGraphicBufferProducer::getConsumerName_cb _hidl_cb) override {
-        _hidl_cb(mBase->getConsumerName().string());
-        return Void();
-    }
-
-    Return<int32_t> setSharedBufferMode(bool sharedBufferMode) override {
-        return static_cast<int32_t>(mBase->setSharedBufferMode(sharedBufferMode));
-    }
-
-    Return<int32_t> setAutoRefresh(bool autoRefresh) override {
-        return static_cast<int32_t>(mBase->setAutoRefresh(autoRefresh));
-    }
-
-    Return<int32_t> setDequeueTimeout(int64_t timeoutNs) override {
-        return static_cast<int32_t>(mBase->setDequeueTimeout(timeoutNs));
-    }
-
-    Return<void> getLastQueuedBuffer(HGraphicBufferProducer::getLastQueuedBuffer_cb _hidl_cb) override {
-        sp<GraphicBuffer> lOutBuffer = new GraphicBuffer();
-        sp<Fence> lOutFence = new Fence();
-        float lOutTransformMatrix[16];
-        status_t status = mBase->getLastQueuedBuffer(
-                &lOutBuffer, &lOutFence, lOutTransformMatrix);
-
-        AnwBuffer tOutBuffer{};
-        if (lOutBuffer != nullptr) {
-            ::android::conversion::wrapAs(&tOutBuffer, *lOutBuffer);
-        }
-        hidl_handle tOutFence{};
-        native_handle_t* nh = nullptr;
-        if ((lOutFence == nullptr) || !::android::conversion::wrapAs(&tOutFence, &nh, *lOutFence)) {
-            LOG(ERROR) << "TWGraphicBufferProducer::getLastQueuedBuffer - "
-                    "Invalid output fence";
-            _hidl_cb(static_cast<int32_t>(status),
-                    tOutBuffer,
-                    tOutFence,
-                    hidl_array<float, 16>());
-            return Void();
-        }
-        hidl_array<float, 16> tOutTransformMatrix(lOutTransformMatrix);
-
-        _hidl_cb(static_cast<int32_t>(status), tOutBuffer, tOutFence, tOutTransformMatrix);
-        native_handle_delete(nh);
-        return Void();
-    }
-
-    Return<void> getFrameTimestamps(HGraphicBufferProducer::getFrameTimestamps_cb _hidl_cb) override {
-        ::android::FrameEventHistoryDelta lDelta;
-        mBase->getFrameTimestamps(&lDelta);
-
-        HGraphicBufferProducer::FrameEventHistoryDelta tDelta{};
-        std::vector<std::vector<native_handle_t*> > nhAA;
-        if (!::android::conversion::wrapAs(&tDelta, &nhAA, lDelta)) {
-            LOG(ERROR) << "TWGraphicBufferProducer::getFrameTimestamps - "
-                    "Invalid output frame timestamps";
-            _hidl_cb(tDelta);
-            return Void();
-        }
-
-        _hidl_cb(tDelta);
-        for (auto& nhA : nhAA) {
-            for (auto& nh : nhA) {
-                native_handle_delete(nh);
-            }
-        }
-        return Void();
-    }
-
-    Return<void> getUniqueId(HGraphicBufferProducer::getUniqueId_cb _hidl_cb) override {
-        uint64_t outId{};
-        status_t status = mBase->getUniqueId(&outId);
-        _hidl_cb(static_cast<int32_t>(status), outId);
-        return Void();
-    }
-
-private:
-    sp<BGraphicBufferProducer> mBase;
-};
-
-}  // namespace android
-
-#endif  // MEDIA_STAGEFRIGHT_WGRAPHICBUFFERPRODUCER_H_
diff --git a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/WProducerListener.h b/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/WProducerListener.h
deleted file mode 100644
index febba87..0000000
--- a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/WProducerListener.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MEDIA_STAGEFRIGHT_WPRODUCERLISTENER_H_
-#define MEDIA_STAGEFRIGHT_WPRODUCERLISTENER_H_
-
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-
-#include <binder/IBinder.h>
-#include <gui/IProducerListener.h>
-
-#include <android/hardware/graphics/bufferqueue/1.0/IProducerListener.h>
-
-namespace android {
-
-using ::android::hidl::base::V1_0::IBase;
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::sp;
-
-typedef ::android::hardware::graphics::bufferqueue::V1_0::IProducerListener
-        HProducerListener;
-typedef ::android::IProducerListener
-        BProducerListener;
-using ::android::BnProducerListener;
-
-struct TWProducerListener : public HProducerListener {
-    sp<BProducerListener> mBase;
-    TWProducerListener(sp<BProducerListener> const& base);
-    Return<void> onBufferReleased() override;
-    Return<bool> needsReleaseNotify() override;
-};
-
-class LWProducerListener : public BnProducerListener {
-public:
-    sp<HProducerListener> mBase;
-    LWProducerListener(sp<HProducerListener> const& base);
-    void onBufferReleased() override;
-    bool needsReleaseNotify() override;
-};
-
-}  // namespace android
-
-#endif  // MEDIA_STAGEFRIGHT_WPRODUCERLISTENER_H_
diff --git a/media/libstagefright/codecs/aacdec/Android.bp b/media/libstagefright/codecs/aacdec/Android.bp
index 7352854..46b3b8f 100644
--- a/media/libstagefright/codecs/aacdec/Android.bp
+++ b/media/libstagefright/codecs/aacdec/Android.bp
@@ -1,22 +1,12 @@
 cc_library_shared {
     name: "libstagefright_soft_aacdec",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
+    defaults: ["libstagefright_softomx-defaults"],
 
     srcs: [
         "SoftAAC2.cpp",
         "DrcPresModeWrap.cpp",
     ],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/native/include/media/openmax",
-    ],
-
-    cflags: ["-Werror"],
-
     version_script: "exports.lds",
 
     sanitize: {
@@ -25,19 +15,11 @@
             "unsigned-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
     static_libs: ["libFraunhoferAAC"],
 
     shared_libs: [
-        "libstagefright_omx",
-        "libstagefright_foundation",
-        "libutils",
         "libcutils",
-        "liblog",
     ],
-    compile_multilib: "32",
 }
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index bc0a69f..41bc16c 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -147,7 +147,7 @@
     mEndOfOutput = false;
     mOutputDelayCompensated = 0;
     mOutputDelayRingBufferSize = 2048 * MAX_CHANNEL_COUNT * kNumDelayBlocksMax;
-    mOutputDelayRingBuffer = new short[mOutputDelayRingBufferSize];
+    mOutputDelayRingBuffer = new int16_t[mOutputDelayRingBufferSize];
     mOutputDelayRingBufferWritePos = 0;
     mOutputDelayRingBufferReadPos = 0;
     mOutputDelayRingBufferFilled = 0;
@@ -738,7 +738,7 @@
                 } else {
                     int64_t currentTime = mBufferTimestamps.top();
                     currentTime += mStreamInfo->aacSamplesPerFrame *
-                            1000000ll / mStreamInfo->aacSampleRate;
+                            1000000LL / mStreamInfo->aacSampleRate;
                     mBufferTimestamps.add(currentTime);
                 }
             } else {
@@ -989,7 +989,7 @@
                         // adjust/interpolate next time stamp
                         *currentBufLeft -= decodedSize;
                         *nextTimeStamp += mStreamInfo->aacSamplesPerFrame *
-                                1000000ll / mStreamInfo->aacSampleRate;
+                                1000000LL / mStreamInfo->aacSampleRate;
                         ALOGV("adjusted nextTimeStamp/size to %lld/%d",
                                 (long long) *nextTimeStamp, *currentBufLeft);
                     } else {
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.h b/media/libstagefright/codecs/aacdec/SoftAAC2.h
index 73a3965..5bee710 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.h
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.h
@@ -81,7 +81,7 @@
     bool mEndOfOutput;
     int32_t mOutputDelayCompensated;
     int32_t mOutputDelayRingBufferSize;
-    short *mOutputDelayRingBuffer;
+    int16_t *mOutputDelayRingBuffer;
     int32_t mOutputDelayRingBufferWritePos;
     int32_t mOutputDelayRingBufferReadPos;
     int32_t mOutputDelayRingBufferFilled;
diff --git a/media/libstagefright/codecs/aacenc/Android.bp b/media/libstagefright/codecs/aacenc/Android.bp
index 9342351..bf789c4 100644
--- a/media/libstagefright/codecs/aacenc/Android.bp
+++ b/media/libstagefright/codecs/aacenc/Android.bp
@@ -1,19 +1,9 @@
 cc_library_shared {
     name: "libstagefright_soft_aacenc",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
+    defaults: ["libstagefright_softomx-defaults"],
 
     srcs: ["SoftAACEncoder2.cpp"],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/native/include/media/openmax",
-    ],
-
-    cflags: ["-Werror"],
-
     version_script: "exports.lds",
 
     sanitize: {
@@ -22,18 +12,7 @@
             "unsigned-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
     static_libs: ["libFraunhoferAAC"],
-
-    shared_libs: [
-        "libstagefright_omx",
-        "libstagefright_foundation",
-        "libutils",
-        "liblog",
-    ],
-    compile_multilib: "32",
 }
diff --git a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
index 96e668e..6e437cf 100644
--- a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
+++ b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
@@ -63,7 +63,7 @@
       mInputSize(0),
       mInputFrame(NULL),
       mAllocatedFrameSize(0),
-      mInputTimeUs(-1ll),
+      mInputTimeUs(-1LL),
       mSawInputEOS(false),
       mSignalledError(false) {
     initPorts();
@@ -587,7 +587,7 @@
             // "Time" on the input buffer has in effect advanced by the
             // number of audio frames we just advanced nOffset by.
             inHeader->nTimeStamp +=
-                (copy * 1000000ll / mSampleRate)
+                (copy * 1000000LL / mSampleRate)
                     / (mNumChannels * sizeof(int16_t));
 
             if (inHeader->nFilledLen == 0) {
@@ -725,7 +725,7 @@
     mAllocatedFrameSize = 0;
 
     mSentCodecSpecificData = false;
-    mInputTimeUs = -1ll;
+    mInputTimeUs = -1LL;
     mSawInputEOS = false;
     mSignalledError = false;
 }
diff --git a/media/libstagefright/codecs/amrnb/Android.bp b/media/libstagefright/codecs/amrnb/Android.bp
deleted file mode 100644
index b44c296..0000000
--- a/media/libstagefright/codecs/amrnb/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["*"]
diff --git a/media/libstagefright/codecs/amrnb/common/Android.bp b/media/libstagefright/codecs/amrnb/common/Android.bp
index 5177593..772ebf9 100644
--- a/media/libstagefright/codecs/amrnb/common/Android.bp
+++ b/media/libstagefright/codecs/amrnb/common/Android.bp
@@ -1,9 +1,6 @@
 cc_library_shared {
     name: "libstagefright_amrnb_common",
     vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
 
     srcs: [
         "src/add.cpp",
diff --git a/media/libstagefright/codecs/amrnb/common/src/l_abs.cpp b/media/libstagefright/codecs/amrnb/common/src/l_abs.cpp
index fd1c90d..7e0ae99 100644
--- a/media/libstagefright/codecs/amrnb/common/src/l_abs.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/l_abs.cpp
@@ -176,7 +176,7 @@
 /*----------------------------------------------------------------------------
 ; FUNCTION CODE
 ----------------------------------------------------------------------------*/
-Word32 L_abs(register Word32 L_var1)
+Word32 L_abs(Word32 L_var1)
 {
     /*----------------------------------------------------------------------------
     ; Define all local variables
diff --git a/media/libstagefright/codecs/amrnb/common/src/l_shr_r.cpp b/media/libstagefright/codecs/amrnb/common/src/l_shr_r.cpp
index f609a73..47e1ee8 100644
--- a/media/libstagefright/codecs/amrnb/common/src/l_shr_r.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/l_shr_r.cpp
@@ -190,7 +190,7 @@
 /*----------------------------------------------------------------------------
 ; FUNCTION CODE
 ----------------------------------------------------------------------------*/
-Word32 L_shr_r(register Word32 L_var1, register Word16 var2, Flag *pOverflow)
+Word32 L_shr_r(Word32 L_var1, Word16 var2, Flag *pOverflow)
 {
     Word32 result;
 
diff --git a/media/libstagefright/codecs/amrnb/common/src/lsp.cpp b/media/libstagefright/codecs/amrnb/common/src/lsp.cpp
index 0e3f772..81d9cde 100644
--- a/media/libstagefright/codecs/amrnb/common/src/lsp.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/lsp.cpp
@@ -173,7 +173,7 @@
     *st = NULL;
 
     /* allocate memory */
-    if ((s = (lspState *) malloc(sizeof(lspState))) == NULL)
+    if ((s = (lspState *) calloc(sizeof(lspState), 1)) == NULL)
     {
         /* fprintf(stderr, "lsp_init: can not malloc state structure\n"); */
         return -1;
@@ -182,11 +182,13 @@
     /* Initialize quantization state */
     if (0 != Q_plsf_init(&s->qSt))
     {
+        lsp_exit(&s);
         return -1;
     }
 
     if (0 != lsp_reset(s))
     {
+        lsp_exit(&s);
         return -1;
     }
 
diff --git a/media/libstagefright/codecs/amrnb/common/src/negate.cpp b/media/libstagefright/codecs/amrnb/common/src/negate.cpp
index be58d2b..aa36422 100644
--- a/media/libstagefright/codecs/amrnb/common/src/negate.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/negate.cpp
@@ -161,7 +161,7 @@
 /*----------------------------------------------------------------------------
 ; FUNCTION CODE
 ----------------------------------------------------------------------------*/
-Word16 negate(register Word16 var1)
+Word16 negate(Word16 var1)
 {
     /*----------------------------------------------------------------------------
     ; Define all local variables
diff --git a/media/libstagefright/codecs/amrnb/common/src/round.cpp b/media/libstagefright/codecs/amrnb/common/src/round.cpp
index 71d1702..633a8c9 100644
--- a/media/libstagefright/codecs/amrnb/common/src/round.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/round.cpp
@@ -184,7 +184,7 @@
 /*----------------------------------------------------------------------------
 ; FUNCTION CODE
 ----------------------------------------------------------------------------*/
-Word16 pv_round(register Word32 L_var1, Flag *pOverflow)
+Word16 pv_round(Word32 L_var1, Flag *pOverflow)
 {
     Word16  result;
 
diff --git a/media/libstagefright/codecs/amrnb/common/src/shr_r.cpp b/media/libstagefright/codecs/amrnb/common/src/shr_r.cpp
index 6656f93..cdcc246 100644
--- a/media/libstagefright/codecs/amrnb/common/src/shr_r.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/shr_r.cpp
@@ -193,7 +193,7 @@
 /*----------------------------------------------------------------------------
 ; FUNCTION CODE
 ----------------------------------------------------------------------------*/
-Word16 shr_r(register Word16 var1, register Word16 var2, Flag *pOverflow)
+Word16 shr_r(Word16 var1, Word16 var2, Flag *pOverflow)
 {
     /*----------------------------------------------------------------------------
     ; Define all local variables
diff --git a/media/libstagefright/codecs/amrnb/dec/Android.bp b/media/libstagefright/codecs/amrnb/dec/Android.bp
index 880f161..e18117e 100644
--- a/media/libstagefright/codecs/amrnb/dec/Android.bp
+++ b/media/libstagefright/codecs/amrnb/dec/Android.bp
@@ -40,7 +40,6 @@
         "src/wmf_to_ets.cpp",
     ],
 
-    include_dirs: ["frameworks/av/media/libstagefright/include"],
     export_include_dirs: ["src"],
 
     cflags: [
@@ -68,23 +67,14 @@
 
 cc_library_shared {
     name: "libstagefright_soft_amrdec",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
+    defaults: ["libstagefright_softomx-defaults"],
 
     srcs: ["SoftAMR.cpp"],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/av/media/libstagefright/codecs/amrwb/src",
-        "frameworks/native/include/media/openmax",
-    ],
     local_include_dirs: ["src"],
 
     cflags: [
         "-DOSCL_IMPORT_REF=",
-        "-Werror",
     ],
 
     version_script: "exports.lds",
@@ -102,14 +92,10 @@
     ],
 
     shared_libs: [
-        "libstagefright_omx",
-        "libstagefright_foundation",
-        "libutils",
-        "liblog",
         "libstagefright_amrnb_common",
     ],
-    compile_multilib: "32",
 }
+
 //###############################################################################
 cc_test {
     name: "libstagefright_amrnbdec_test",
diff --git a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
index b7e84ec..34dd011 100644
--- a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
+++ b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
@@ -505,7 +505,7 @@
 
             outHeader->nTimeStamp =
                 mAnchorTimeUs
-                    + (mNumSamplesOutput * 1000000ll) / kSampleRateNB;
+                    + (mNumSamplesOutput * 1000000LL) / kSampleRateNB;
 
             mNumSamplesOutput += kNumSamplesPerFrameNB;
         } else {
@@ -513,7 +513,7 @@
 
             outHeader->nTimeStamp =
                 mAnchorTimeUs
-                    + (mNumSamplesOutput * 1000000ll) / kSampleRateWB;
+                    + (mNumSamplesOutput * 1000000LL) / kSampleRateWB;
 
             mNumSamplesOutput += kNumSamplesPerFrameWB;
         }
diff --git a/media/libstagefright/codecs/amrnb/dec/src/sp_dec.cpp b/media/libstagefright/codecs/amrnb/dec/src/sp_dec.cpp
index 2989b74..49cafff 100644
--- a/media/libstagefright/codecs/amrnb/dec/src/sp_dec.cpp
+++ b/media/libstagefright/codecs/amrnb/dec/src/sp_dec.cpp
@@ -268,13 +268,7 @@
     if (Decoder_amr_init(&s->decoder_amrState)
             || Post_Process_reset(&s->postHP_state))
     {
-        Speech_Decode_FrameState *tmp = s;
-        /*
-         *  dereferencing type-punned pointer avoid
-         *  breaking strict-aliasing rules
-         */
-        void** tempVoid = (void**) tmp;
-        GSMDecodeFrameExit(tempVoid);
+        free(s);
         return (-1);
     }
 
diff --git a/media/libstagefright/codecs/amrnb/dec/test/amrnbdec_test.cpp b/media/libstagefright/codecs/amrnb/dec/test/amrnbdec_test.cpp
index 41a9e98..621fda8 100644
--- a/media/libstagefright/codecs/amrnb/dec/test/amrnbdec_test.cpp
+++ b/media/libstagefright/codecs/amrnb/dec/test/amrnbdec_test.cpp
@@ -67,6 +67,7 @@
     int bytesRead = fread(header, 1, kFileHeaderSize, fpInput);
     if (bytesRead != kFileHeaderSize || memcmp(header, "#!AMR\n", kFileHeaderSize)) {
         fprintf(stderr, "Invalid AMR-NB file\n");
+        fclose(fpInput);
         return 1;
     }
 
@@ -79,6 +80,7 @@
     SNDFILE *handle = sf_open(argv[2], SFM_WRITE, &sfInfo);
     if(!handle){
         fprintf(stderr, "Could not create %s\n", argv[2]);
+        fclose(fpInput);
         return 1;
     }
 
@@ -87,6 +89,8 @@
     int err = GSMInitDecode(&amrHandle, (Word8*)"AMRNBDecoder");
     if(err != 0){
         fprintf(stderr, "Error creating AMR-NB decoder instance\n");
+        fclose(fpInput);
+        sf_close(handle);
         return 1;
     }
 
diff --git a/media/libstagefright/codecs/amrnb/enc/Android.bp b/media/libstagefright/codecs/amrnb/enc/Android.bp
index 19fd4a8..438ed04 100644
--- a/media/libstagefright/codecs/amrnb/enc/Android.bp
+++ b/media/libstagefright/codecs/amrnb/enc/Android.bp
@@ -62,7 +62,7 @@
         "src/ton_stab.cpp",
     ],
 
-    include_dirs: ["frameworks/av/media/libstagefright/include"],
+    header_libs: ["libstagefright_headers"],
     export_include_dirs: ["src"],
 
     cflags: [
@@ -86,21 +86,12 @@
 
 cc_library_shared {
     name: "libstagefright_soft_amrnbenc",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
+    defaults: ["libstagefright_softomx-defaults"],
 
     srcs: ["SoftAMRNBEncoder.cpp"],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/native/include/media/openmax",
-    ],
     local_include_dirs: ["src"],
 
-    cflags: ["-Werror"],
-
     //addressing b/25409744
     //sanitize: {
     //    misc_undefined: [
@@ -111,13 +102,8 @@
     static_libs: ["libstagefright_amrnbenc"],
 
     shared_libs: [
-        "libstagefright_omx",
-        "libstagefright_foundation",
-        "libutils",
-        "liblog",
         "libstagefright_amrnb_common",
     ],
-    compile_multilib: "32",
 }
 
 //###############################################################################
diff --git a/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp b/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp
index f97c44f..85ab64e 100644
--- a/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp
+++ b/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp
@@ -49,7 +49,7 @@
       mBitRate(0),
       mMode(MR475),
       mInputSize(0),
-      mInputTimeUs(-1ll),
+      mInputTimeUs(-1LL),
       mSawInputEOS(false),
       mSignalledError(false) {
     initPorts();
@@ -340,7 +340,7 @@
             // "Time" on the input buffer has in effect advanced by the
             // number of audio frames we just advanced nOffset by.
             inHeader->nTimeStamp +=
-                (copy * 1000000ll / kSampleRate) / sizeof(int16_t);
+                (copy * 1000000LL / kSampleRate) / sizeof(int16_t);
 
             if (inHeader->nFilledLen == 0) {
                 if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
diff --git a/media/libstagefright/codecs/amrwb/Android.bp b/media/libstagefright/codecs/amrwb/Android.bp
index 9fefd81..88cf7f2 100644
--- a/media/libstagefright/codecs/amrwb/Android.bp
+++ b/media/libstagefright/codecs/amrwb/Android.bp
@@ -44,7 +44,7 @@
         "src/weight_amrwb_lpc.cpp",
     ],
 
-    include_dirs: ["frameworks/av/media/libstagefright/include"],
+    header_libs: ["libstagefright_headers"],
 
     export_include_dirs: [
         "src",
diff --git a/media/libstagefright/codecs/amrwb/src/dec_acelp_4p_in_64.cpp b/media/libstagefright/codecs/amrwb/src/dec_acelp_4p_in_64.cpp
index 4868822..36a7393 100644
--- a/media/libstagefright/codecs/amrwb/src/dec_acelp_4p_in_64.cpp
+++ b/media/libstagefright/codecs/amrwb/src/dec_acelp_4p_in_64.cpp
@@ -234,6 +234,7 @@
                 dec_6p_6N_2(L_index, 4, 0, pos);
                 add_pulses(pos, 6, k, code);
             }
+            break;
         default:
             break;
     }
diff --git a/media/libstagefright/codecs/amrwb/src/deemphasis_32.cpp b/media/libstagefright/codecs/amrwb/src/deemphasis_32.cpp
index b80555b..c0e4c51 100644
--- a/media/libstagefright/codecs/amrwb/src/deemphasis_32.cpp
+++ b/media/libstagefright/codecs/amrwb/src/deemphasis_32.cpp
@@ -131,7 +131,7 @@
     int16 lo, hi;
 
     L_tmp  = ((int32)x_hi[0]) << 16;
-    L_tmp += ((int32)x_lo[0]) << 4;
+    L_tmp += (((int32)x_lo[0]) << 4) & 0xFFFF;
     L_tmp  = shl_int32(L_tmp, 3);
 
     L_tmp = fxp_mac_16by16(*mem, mu, L_tmp),
@@ -144,7 +144,7 @@
     for (i = 1; i < L - 1; i++)
     {
         L_tmp  = ((int32)hi) << 16;
-        L_tmp += ((int32)lo) << 4;
+        L_tmp += (((int32)lo) << 4) & 0xFFFF;
         L_tmp  = shl_int32(L_tmp, 3);
         L_tmp  = fxp_mac_16by16(y[i - 1], mu, L_tmp),
                  L_tmp  = shl_int32(L_tmp, 1);           /* saturation can occur here */
@@ -153,7 +153,7 @@
         hi     = x_hi[i+1];
     }
     L_tmp  = ((int32)hi) << 16;
-    L_tmp += ((int32)lo) << 4;
+    L_tmp += (((int32)lo) << 4) & 0xFFFF;
     L_tmp  = shl_int32(L_tmp, 3);
     L_tmp  = fxp_mac_16by16(y[i - 1], mu, L_tmp),
              L_tmp  = shl_int32(L_tmp, 1);           /* saturation can occur here */
diff --git a/media/libstagefright/codecs/amrwb/src/normalize_amr_wb.cpp b/media/libstagefright/codecs/amrwb/src/normalize_amr_wb.cpp
index 0325311..4d1126e 100644
--- a/media/libstagefright/codecs/amrwb/src/normalize_amr_wb.cpp
+++ b/media/libstagefright/codecs/amrwb/src/normalize_amr_wb.cpp
@@ -170,6 +170,7 @@
         case 0x38000000:
         case 0x30000000:
             i++;
+            break;
 
         default:
             ;
diff --git a/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder.cpp b/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder.cpp
index b8cfefa..ddc818e 100644
--- a/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder.cpp
+++ b/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder.cpp
@@ -455,7 +455,7 @@
                              &exc2[i_subfr],
                              0,
                              &synth16k[i_subfr *5/4],
-                             (short) 1,
+                             1,
                              HfIsf,
                              nb_bits,
                              newDTXState,
diff --git a/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder_basic_op_cequivalent.h b/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder_basic_op_cequivalent.h
index 3c7590c..7a86ec2 100644
--- a/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder_basic_op_cequivalent.h
+++ b/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder_basic_op_cequivalent.h
@@ -467,7 +467,12 @@
     __inline  int32 fxp_mac_16by16(int16 var1,  int16 var2, int32 L_add)
     {
 
-        L_add += (int32)var1 * var2;
+        int32 l_orig = L_add;
+        if (__builtin_add_overflow( (int32)var1 * var2, l_orig, &L_add)) {
+            // needs saturation
+            if (l_orig > 0) L_add = MAX_32;
+            else            L_add = MIN_32;
+        }
 
         return L_add;
     }
diff --git a/media/libstagefright/codecs/amrwbenc/Android.bp b/media/libstagefright/codecs/amrwbenc/Android.bp
index 5d479b3..084be0a 100644
--- a/media/libstagefright/codecs/amrwbenc/Android.bp
+++ b/media/libstagefright/codecs/amrwbenc/Android.bp
@@ -135,9 +135,6 @@
     cflags: ["-Werror"],
     sanitize: {
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
 }
@@ -146,20 +143,10 @@
 
 cc_library_shared {
     name: "libstagefright_soft_amrwbenc",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
+    defaults: ["libstagefright_softomx-defaults"],
 
     srcs: ["SoftAMRWBEncoder.cpp"],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/native/include/media/openmax",
-    ],
-
-    cflags: ["-Werror"],
-
     version_script: "exports.lds",
 
     sanitize: {
@@ -167,23 +154,12 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
     static_libs: ["libstagefright_amrwbenc"],
 
     shared_libs: [
-        "libstagefright_omx",
-        "libstagefright_foundation",
-        "libutils",
-        "liblog",
         "libstagefright_enc_common",
     ],
-    compile_multilib: "32",
 }
 
-//###############################################################################
-
-subdirs = ["SampleCode"]
diff --git a/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c b/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c
index 7c094f3..7282de4 100644
--- a/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c
+++ b/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c
@@ -134,14 +134,16 @@
 	if(handle == 0)
 	{
 		printf("open dll error......");
-		return -1;
+		ret = -1;
+		goto safe_exit;
 	}
 
 	pfunc = dlsym(handle, "voGetAMRWBEncAPI");
 	if(pfunc == 0)
 	{
 		printf("open function error......");
-		return -1;
+		ret = -1;
+		goto safe_exit;
 	}
 
 	pGetAPI = (VOGETAUDIOENCAPI)pfunc;
@@ -150,7 +152,8 @@
 	if(returnCode)
 	{
 		printf("get APIs error......");
-		return -1;
+		ret = -1;
+		goto safe_exit;
 	}
 #else
 	ret = voGetAMRWBEncAPI(&AudioAPI);
@@ -253,7 +256,8 @@
 		fclose(fdst);
 
 #ifdef LINUX
-	dlclose(handle);
+	if (handle)
+		dlclose(handle);
 #endif
 
 	return ret;
diff --git a/media/libstagefright/codecs/amrwbenc/SampleCode/Android.bp b/media/libstagefright/codecs/amrwbenc/SampleCode/Android.bp
index 79b37ff..9442fc4 100644
--- a/media/libstagefright/codecs/amrwbenc/SampleCode/Android.bp
+++ b/media/libstagefright/codecs/amrwbenc/SampleCode/Android.bp
@@ -24,8 +24,5 @@
 
     sanitize: {
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 }
diff --git a/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp b/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp
index a644b66..7fb8a4c 100644
--- a/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp
+++ b/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp
@@ -50,7 +50,7 @@
       mBitRate(0),
       mMode(VOAMRWB_MD66),
       mInputSize(0),
-      mInputTimeUs(-1ll),
+      mInputTimeUs(-1LL),
       mSawInputEOS(false),
       mSignalledError(false) {
     initPorts();
@@ -387,7 +387,7 @@
             // "Time" on the input buffer has in effect advanced by the
             // number of audio frames we just advanced nOffset by.
             inHeader->nTimeStamp +=
-                (copy * 1000000ll / kSampleRate) / sizeof(int16_t);
+                (copy * 1000000LL / kSampleRate) / sizeof(int16_t);
 
             if (inHeader->nFilledLen == 0) {
                 if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
diff --git a/media/libstagefright/codecs/avcdec/Android.bp b/media/libstagefright/codecs/avcdec/Android.bp
index cf50a04..0bb6bb0 100644
--- a/media/libstagefright/codecs/avcdec/Android.bp
+++ b/media/libstagefright/codecs/avcdec/Android.bp
@@ -1,44 +1,22 @@
 cc_library_shared {
     name: "libstagefright_soft_avcdec",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
+    defaults: ["libstagefright_softomx-defaults"],
 
     static_libs: ["libavcdec"],
     srcs: ["SoftAVCDec.cpp"],
 
     cflags: [
         "-Wall",
-        "-Werror",
     ],
 
     version_script: "exports.lds",
 
-    include_dirs: [
-        "external/libavc/decoder",
-        "external/libavc/common",
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/native/include/media/openmax",
-    ],
-
-    shared_libs: [
-        "libstagefright_omx",
-        "libstagefright_foundation",
-        "libutils",
-        "liblog",
-    ],
-
     sanitize: {
         misc_undefined: [
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
     ldflags: ["-Wl,-Bsymbolic"],
-    compile_multilib: "32",
 }
diff --git a/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp b/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
index 3924fc2..5a4b2f8 100644
--- a/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
+++ b/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
@@ -580,7 +580,7 @@
             status = ivdec_api_function(mCodecCtx, (void *)&s_dec_ip, (void *)&s_dec_op);
 
             bool unsupportedResolution =
-                (IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED == (s_dec_op.u4_error_code & 0xFF));
+                (IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED == (s_dec_op.u4_error_code & IVD_ERROR_MASK));
 
             /* Check for unsupported dimensions */
             if (unsupportedResolution) {
@@ -590,7 +590,7 @@
                 return;
             }
 
-            bool allocationFailed = (IVD_MEM_ALLOC_FAILED == (s_dec_op.u4_error_code & 0xFF));
+            bool allocationFailed = (IVD_MEM_ALLOC_FAILED == (s_dec_op.u4_error_code & IVD_ERROR_MASK));
             if (allocationFailed) {
                 ALOGE("Allocation failure in decoder");
                 notify(OMX_EventError, OMX_ErrorUnsupportedSetting, 0, NULL);
@@ -598,7 +598,14 @@
                 return;
             }
 
-            bool resChanged = (IVD_RES_CHANGED == (s_dec_op.u4_error_code & 0xFF));
+            if (IS_IVD_FATAL_ERROR(s_dec_op.u4_error_code)) {
+                ALOGE("Fatal Error : 0x%x", s_dec_op.u4_error_code);
+                notify(OMX_EventError, OMX_ErrorUnsupportedSetting, 0, NULL);
+                mSignalledError = true;
+                return;
+            }
+
+            bool resChanged = (IVD_RES_CHANGED == (s_dec_op.u4_error_code & IVD_ERROR_MASK));
 
             getVUIParams();
 
@@ -607,7 +614,7 @@
             timeTaken = mTimeEnd - mTimeStart;
 
             ALOGV("timeTaken=%6lldus delay=%6lldus numBytes=%6d",
-                    (long long) (timeTaken / 1000ll), (long long) (timeDelay / 1000ll),
+                    (long long) (timeTaken / 1000LL), (long long) (timeDelay / 1000LL),
                    s_dec_op.u4_num_bytes_consumed);
             if (s_dec_op.u4_frame_decoded_flag && !mFlushNeeded) {
                 mFlushNeeded = true;
diff --git a/media/libstagefright/codecs/avcenc/Android.bp b/media/libstagefright/codecs/avcenc/Android.bp
index cefe77c..980261c 100644
--- a/media/libstagefright/codecs/avcenc/Android.bp
+++ b/media/libstagefright/codecs/avcenc/Android.bp
@@ -1,46 +1,22 @@
 cc_library_shared {
     name: "libstagefright_soft_avcenc",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
+    defaults: ["libstagefright_softomx-defaults"],
 
     static_libs: ["libavcenc"],
     srcs: ["SoftAVCEnc.cpp"],
 
-    include_dirs: [
-        "external/libavc/encoder",
-        "external/libavc/common",
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/native/include/media/hardware",
-        "frameworks/native/include/media/openmax",
-    ],
-
-    shared_libs: [
-        "libstagefright_foundation",
-        "libstagefright_omx",
-        "libutils",
-        "liblog",
-    ],
-
     sanitize: {
         misc_undefined: [
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
     cflags: [
         "-Wall",
-        "-Werror",
         "-Wno-unused-variable",
     ],
     ldflags: ["-Wl,-Bsymbolic"],
 
     version_script: "exports.lds",
-
-    compile_multilib: "32",
 }
diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
index 379d41e..9db6465 100644
--- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
+++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
@@ -21,8 +21,8 @@
 
 #include "OMX_Video.h"
 
-#include <HardwareAPI.h>
-#include <MetadataBufferType.h>
+#include <media/hardware/HardwareAPI.h>
+#include <media/hardware/MetadataBufferType.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
@@ -1058,8 +1058,8 @@
     }
 }
 
-OMX_ERRORTYPE SoftAVC::setConfig(
-        OMX_INDEXTYPE index, const OMX_PTR _params) {
+OMX_ERRORTYPE SoftAVC::internalSetConfig(
+        OMX_INDEXTYPE index, const OMX_PTR _params, bool *frameConfig) {
     switch ((int)index) {
         case OMX_IndexConfigVideoIntraVOPRefresh:
         {
@@ -1125,7 +1125,7 @@
         }
 
         default:
-            return SimpleSoftOMXComponent::setConfig(index, _params);
+            return SimpleSoftOMXComponent::internalSetConfig(index, _params, frameConfig);
     }
 }
 
diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.h b/media/libstagefright/codecs/avcenc/SoftAVCEnc.h
index a43cdf1..6d2e084 100644
--- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.h
+++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.h
@@ -36,7 +36,7 @@
 #define DEFAULT_MAX_REORDER_FRM     0
 #define DEFAULT_QP_MIN              10
 #define DEFAULT_QP_MAX              40
-#define DEFAULT_MAX_BITRATE         20000000
+#define DEFAULT_MAX_BITRATE         240000000
 #define DEFAULT_MAX_SRCH_RANGE_X    256
 #define DEFAULT_MAX_SRCH_RANGE_Y    256
 #define DEFAULT_MAX_FRAMERATE       120000
@@ -219,8 +219,8 @@
     OMX_ERRORTYPE internalSetBitrateParams(
         const OMX_VIDEO_PARAM_BITRATETYPE *bitrate);
 
-    OMX_ERRORTYPE setConfig(
-        OMX_INDEXTYPE index, const OMX_PTR _params);
+    OMX_ERRORTYPE internalSetConfig(
+        OMX_INDEXTYPE index, const OMX_PTR _params, bool *frameConfig);
 
     OMX_ERRORTYPE getConfig(
         OMX_INDEXTYPE index, const OMX_PTR _params);
diff --git a/media/libstagefright/codecs/common/Android.bp b/media/libstagefright/codecs/common/Android.bp
index 3726922..c5a076a 100644
--- a/media/libstagefright/codecs/common/Android.bp
+++ b/media/libstagefright/codecs/common/Android.bp
@@ -1,9 +1,6 @@
 cc_library {
     name: "libstagefright_enc_common",
     vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
 
     srcs: ["cmnMemory.c"],
 
diff --git a/media/libstagefright/codecs/common/include/voType.h b/media/libstagefright/codecs/common/include/voType.h
index da208d4..73f24d0 100644
--- a/media/libstagefright/codecs/common/include/voType.h
+++ b/media/libstagefright/codecs/common/include/voType.h
@@ -22,6 +22,8 @@
 #ifndef __voType_H__
 #define __voType_H__
 
+#include <stdint.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
@@ -62,28 +64,28 @@
 typedef void VO_VOID;
 
 /** VO_U8 is an 8 bit unsigned quantity that is byte aligned */
-typedef unsigned char VO_U8;
+typedef uint8_t VO_U8;
 
 /** VO_BYTE is an 8 bit unsigned quantity that is byte aligned */
-typedef unsigned char VO_BYTE;
+typedef uint8_t VO_BYTE;
 
 /** VO_S8 is an 8 bit signed quantity that is byte aligned */
-typedef signed char VO_S8;
+typedef int8_t VO_S8;
 
 /** VO_CHAR is an 8 bit signed quantity that is byte aligned */
-typedef char VO_CHAR;
+typedef int8_t VO_CHAR;
 
 /** VO_U16 is a 16 bit unsigned quantity that is 16 bit word aligned */
-typedef unsigned short VO_U16;
+typedef uint16_t VO_U16;
 
 /** VO_S16 is a 16 bit signed quantity that is 16 bit word aligned */
-typedef signed short VO_S16;
+typedef int16_t VO_S16;
 
 /** VO_U32 is a 32 bit unsigned quantity that is 32 bit word aligned */
-typedef unsigned long VO_U32;
+typedef uint32_t VO_U32;
 
 /** VO_S32 is a 32 bit signed quantity that is 32 bit word aligned */
-typedef signed long VO_S32;
+typedef int32_t VO_S32;
 
 /* Users with compilers that cannot accept the "long long" designation should
    define the VO_SKIP64BIT macro.  It should be noted that this may cause
@@ -94,14 +96,14 @@
 #ifndef VO_SKIP64BIT
 #ifdef _MSC_VER
 /** VO_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */
-typedef unsigned __int64  VO_U64;
+typedef uint64_t  VO_U64;
 /** VO_S64 is a 64 bit signed quantity that is 64 bit word aligned */
-typedef signed   __int64  VO_S64;
+typedef int64_t  VO_S64;
 #else // WIN32
 /** VO_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */
-typedef unsigned long long VO_U64;
+typedef uint64_t VO_U64;
 /** VO_S64 is a 64 bit signed quantity that is 64 bit word aligned */
-typedef signed long long VO_S64;
+typedef int64_t VO_S64;
 #endif // WIN32
 #endif // VO_SKIP64BIT
 
diff --git a/media/libstagefright/codecs/flac/Android.bp b/media/libstagefright/codecs/flac/Android.bp
deleted file mode 100644
index b44c296..0000000
--- a/media/libstagefright/codecs/flac/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["*"]
diff --git a/media/libstagefright/codecs/flac/dec/Android.bp b/media/libstagefright/codecs/flac/dec/Android.bp
index 9af086b..4064751 100644
--- a/media/libstagefright/codecs/flac/dec/Android.bp
+++ b/media/libstagefright/codecs/flac/dec/Android.bp
@@ -1,23 +1,11 @@
 cc_library_shared {
     name: "libstagefright_soft_flacdec",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
+    defaults: ["libstagefright_softomx-defaults"],
 
     srcs: [
         "SoftFlacDecoder.cpp",
     ],
 
-    include_dirs: [
-        "external/flac/include",
-        "frameworks/av/media/libstagefright/flac/dec",
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/native/include/media/openmax",
-    ],
-
-    cflags: ["-Werror"],
-
     version_script: "exports.lds",
 
     sanitize: {
@@ -26,18 +14,9 @@
             "unsigned-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
     shared_libs: [
-        "libcutils",
-        "liblog",
         "libstagefright_flacdec",
-        "libstagefright_omx",
-        "libstagefright_foundation",
-        "libutils",
     ],
-    compile_multilib: "32",
 }
diff --git a/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.cpp b/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.cpp
index 2c0f224..842a7ce 100644
--- a/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.cpp
+++ b/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.cpp
@@ -89,12 +89,12 @@
     def.eDir = OMX_DirOutput;
     def.nBufferCountMin = kNumOutputBuffers;
     def.nBufferCountActual = def.nBufferCountMin;
-    def.nBufferSize = 4096 * FLACDecoder::kMaxChannels;
+    def.nBufferSize = kNumSamplesPerFrame * FLACDecoder::kMaxChannels * sizeof(float);
     def.bEnabled = OMX_TRUE;
     def.bPopulated = OMX_FALSE;
     def.eDomain = OMX_PortDomainAudio;
     def.bBuffersContiguous = OMX_FALSE;
-    def.nBufferAlignment = 2;
+    def.nBufferAlignment = sizeof(float);
 
     def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
     def.format.audio.pNativeRender = NULL;
@@ -173,7 +173,7 @@
                 flacParams->nChannels = mStreamInfo.channels;
                 flacParams->nSampleRate = mStreamInfo.sample_rate;
             } else {
-                flacParams->nChannels = 1;
+                flacParams->nChannels = 2;
                 flacParams->nSampleRate = 44100;
             }
 
@@ -195,10 +195,10 @@
                 return OMX_ErrorBadPortIndex;
             }
 
-            pcmParams->eNumData = OMX_NumericalDataSigned;
+            pcmParams->eNumData = mNumericalData;
             pcmParams->eEndian = OMX_EndianBig;
             pcmParams->bInterleaved = OMX_TRUE;
-            pcmParams->nBitPerSample = 16;
+            pcmParams->nBitPerSample = mBitsPerSample;
             pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
             pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
             pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
@@ -211,7 +211,7 @@
                 pcmParams->nChannels = mStreamInfo.channels;
                 pcmParams->nSamplingRate = mStreamInfo.sample_rate;
             } else {
-                pcmParams->nChannels = 1;
+                pcmParams->nChannels = 2;
                 pcmParams->nSamplingRate = 44100;
             }
 
@@ -281,6 +281,19 @@
                 return OMX_ErrorBadPortIndex;
             }
 
+            if (pcmParams->eNumData == OMX_NumericalDataFloat && pcmParams->nBitPerSample == 32) {
+                mNumericalData = OMX_NumericalDataFloat;
+                mBitsPerSample = 32;
+            } else if (pcmParams->eNumData == OMX_NumericalDataSigned
+                     && pcmParams->nBitPerSample == 16) {
+                mNumericalData = OMX_NumericalDataSigned;
+                mBitsPerSample = 16;
+            } else {
+                ALOGE("Invalid eNumData %d, nBitsPerSample %d",
+                        pcmParams->eNumData, pcmParams->nBitPerSample);
+                return OMX_ErrorUndefined;
+            }
+
             return OMX_ErrorNone;
         }
 
@@ -301,11 +314,13 @@
     List<BufferInfo *> &inQueue = getPortQueue(0);
     List<BufferInfo *> &outQueue = getPortQueue(1);
 
+    const bool outputFloat = mNumericalData == OMX_NumericalDataFloat;
+
     ALOGV("onQueueFilled %d/%d:", inQueue.empty(), outQueue.empty());
     while ((!inQueue.empty() || mSawInputEOS) && !outQueue.empty() && !mFinishedDecoder) {
         BufferInfo *outInfo = *outQueue.begin();
         OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
-        short *outBuffer = reinterpret_cast<short *>(outHeader->pBuffer + outHeader->nOffset);
+        void *outBuffer = reinterpret_cast<void *>(outHeader->pBuffer + outHeader->nOffset);
         size_t outBufferSize = outHeader->nAllocLen - outHeader->nOffset;
         int64_t timeStamp = 0;
 
@@ -374,7 +389,7 @@
             }
 
             status_t decoderErr = mFLACDecoder->decodeOneFrame(
-                    inBuffer, inBufferLength, outBuffer, &outBufferSize);
+                    inBuffer, inBufferLength, outBuffer, &outBufferSize, outputFloat);
             if (decoderErr != OK) {
                 ALOGE("onQueueFilled: FLACDecoder decodeOneFrame returns error %d", decoderErr);
                 mSignalledError = true;
@@ -393,7 +408,9 @@
                 continue;
             }
         } else if (mSawInputEOS) {
-            status_t decoderErr = mFLACDecoder->decodeOneFrame(NULL, 0, outBuffer, &outBufferSize);
+            status_t decoderErr = mFLACDecoder->decodeOneFrame(
+                    nullptr /* inBuffer */, 0 /* inBufferLen */,
+                    outBuffer, &outBufferSize, outputFloat);
             mFinishedDecoder = true;
             if (decoderErr != OK) {
                 ALOGE("onQueueFilled: FLACDecoder finish returns error %d", decoderErr);
@@ -456,7 +473,8 @@
             mOutputPortSettingsChange = AWAITING_ENABLED;
             PortInfo *info = editPortInfo(1 /* portIndex */);
             if (!info->mDef.bEnabled) {
-                info->mDef.nBufferSize = mStreamInfo.max_blocksize * mStreamInfo.channels * 2;
+                info->mDef.nBufferSize =
+                        mStreamInfo.max_blocksize * mStreamInfo.channels * sizeof(float);
             }
             break;
         }
diff --git a/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.h b/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.h
index b63f7ad..ba02074 100644
--- a/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.h
+++ b/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.h
@@ -45,10 +45,14 @@
     virtual void onReset() override;
 
 private:
+    static constexpr unsigned int kNumSamplesPerFrame = 2048; // adjusted based on stream.
+
     enum {
         kNumInputBuffers   = 4,
         kNumOutputBuffers  = 4,
     };
+    OMX_NUMERICALDATATYPE mNumericalData = OMX_NumericalDataSigned;
+    OMX_U32 mBitsPerSample = 16;
 
     FLACDecoder *mFLACDecoder;
     FLAC__StreamMetadata_StreamInfo mStreamInfo;
diff --git a/media/libstagefright/codecs/flac/enc/Android.bp b/media/libstagefright/codecs/flac/enc/Android.bp
index 46b974d..d7d871a 100644
--- a/media/libstagefright/codecs/flac/enc/Android.bp
+++ b/media/libstagefright/codecs/flac/enc/Android.bp
@@ -1,15 +1,9 @@
 cc_library_shared {
+    name: "libstagefright_soft_flacenc",
+    defaults: ["libstagefright_softomx-defaults"],
 
     srcs: ["SoftFlacEncoder.cpp"],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/native/include/media/openmax",
-        "external/flac/include",
-    ],
-
-    cflags: ["-Werror"],
-
     version_script: "exports.lds",
 
     sanitize: {
@@ -18,25 +12,11 @@
             "unsigned-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
-    shared_libs: [
-        "libstagefright_omx",
-        "libstagefright_foundation",
-        "libutils",
-        "liblog",
+    header_libs: ["libbase_headers"],
+    static_libs: [
+        "libaudioutils",
+        "libFLAC",
     ],
-
-    static_libs: ["libFLAC"],
-
-    name: "libstagefright_soft_flacenc",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
-
-    compile_multilib: "32",
 }
diff --git a/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp b/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp
index fdc8975..3add006 100644
--- a/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp
+++ b/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp
@@ -16,10 +16,11 @@
 
 //#define LOG_NDEBUG 0
 #define LOG_TAG "SoftFlacEncoder"
+#include <android-base/macros.h>
 #include <utils/Log.h>
 
 #include "SoftFlacEncoder.h"
-
+#include <audio_utils/primitives.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/MediaDefs.h>
 
@@ -74,7 +75,9 @@
     }
 
     if (!mSignalledError) { // no use allocating input buffer if we had an error above
-        mInputBufferPcm32 = (FLAC__int32*) malloc(sizeof(FLAC__int32) * 2 * kMaxNumSamplesPerFrame);
+        // 2x the pcm16 samples can exist with the same size as pcmFloat samples.
+        mInputBufferPcm32 = (FLAC__int32*) malloc(
+                sizeof(FLAC__int32) * kNumSamplesPerFrame * kMaxChannels * 2);
         if (mInputBufferPcm32 == NULL) {
             ALOGE("SoftFlacEncoder::SoftFlacEncoder(name=%s) error allocating internal input buffer", name);
             mSignalledError = true;
@@ -114,14 +117,14 @@
     // configure input port of the encoder
     def.nPortIndex = 0;
     def.eDir = OMX_DirInput;
-    def.nBufferCountMin = kNumBuffers;// TODO verify that 1 is enough
+    def.nBufferCountMin = kNumBuffers;
     def.nBufferCountActual = def.nBufferCountMin;
     def.nBufferSize = kMaxInputBufferSize;
     def.bEnabled = OMX_TRUE;
     def.bPopulated = OMX_FALSE;
     def.eDomain = OMX_PortDomainAudio;
     def.bBuffersContiguous = OMX_FALSE;
-    def.nBufferAlignment = 2;
+    def.nBufferAlignment = sizeof(float);
 
     def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
     def.format.audio.pNativeRender = NULL;
@@ -133,7 +136,7 @@
     // configure output port of the encoder
     def.nPortIndex = 1;
     def.eDir = OMX_DirOutput;
-    def.nBufferCountMin = kNumBuffers;// TODO verify that 1 is enough
+    def.nBufferCountMin = kNumBuffers;
     def.nBufferCountActual = def.nBufferCountMin;
     def.nBufferSize = kMaxOutputBufferSize;
     def.bEnabled = OMX_TRUE;
@@ -192,10 +195,10 @@
                 return OMX_ErrorUndefined;
             }
 
-            pcmParams->eNumData = OMX_NumericalDataSigned;
+            pcmParams->eNumData = mNumericalData;
             pcmParams->eEndian = OMX_EndianBig;
             pcmParams->bInterleaved = OMX_TRUE;
-            pcmParams->nBitPerSample = 16;
+            pcmParams->nBitPerSample = mBitsPerSample;
             pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
             pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
             pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
@@ -269,12 +272,26 @@
                 return OMX_ErrorUndefined;
             }
 
-            if (pcmParams->nChannels < 1 || pcmParams->nChannels > 2) {
+            if (pcmParams->nChannels < 1 || pcmParams->nChannels > kMaxChannels) {
                 return OMX_ErrorUndefined;
             }
 
             mNumChannels = pcmParams->nChannels;
             mSampleRate = pcmParams->nSamplingRate;
+
+            if (pcmParams->eNumData == OMX_NumericalDataFloat && pcmParams->nBitPerSample == 32) {
+                mNumericalData = OMX_NumericalDataFloat;
+                mBitsPerSample = 32;
+            } else if (pcmParams->eNumData == OMX_NumericalDataSigned
+                     && pcmParams->nBitPerSample == 16) {
+                mNumericalData = OMX_NumericalDataSigned;
+                mBitsPerSample = 16;
+            } else {
+                ALOGE("%s: invalid eNumData %d, nBitsPerSample %d",
+                        __func__, pcmParams->eNumData, pcmParams->nBitPerSample);
+                return OMX_ErrorUndefined;
+            }
+
             ALOGV("will encode %d channels at %dHz", mNumChannels, mSampleRate);
 
             return configureEncoder();
@@ -335,7 +352,7 @@
                 }
             }
 
-            // fall through
+            FALLTHROUGH_INTENDED;
         }
 
         default:
@@ -355,6 +372,10 @@
     List<BufferInfo *> &inQueue = getPortQueue(0);
     List<BufferInfo *> &outQueue = getPortQueue(1);
 
+    const bool inputFloat = mNumericalData == OMX_NumericalDataFloat;
+    const size_t sampleSize = inputFloat ? sizeof(float) : sizeof(int16_t);
+    const size_t frameSize = sampleSize * mNumChannels;
+
     FLAC__bool ok = true;
 
     while ((!inQueue.empty() || mSawInputEOS) && !outQueue.empty() && !mSentOutputEOS) {
@@ -380,13 +401,21 @@
             mEncoderReturnedNbBytes = 0;
             mCurrentInputTimeStamp = inHeader->nTimeStamp;
 
-            const unsigned nbInputFrames = inHeader->nFilledLen / (2 * mNumChannels);
-            const unsigned nbInputSamples = inHeader->nFilledLen / 2;
-            const OMX_S16 * const pcm16 = reinterpret_cast<OMX_S16 *>(inHeader->pBuffer);
+            const unsigned nbInputFrames = inHeader->nFilledLen / frameSize;
+            const unsigned nbInputSamples = inHeader->nFilledLen / sampleSize;
 
-            CHECK_LE(nbInputSamples, 2 * kMaxNumSamplesPerFrame);
-            for (unsigned i=0 ; i < nbInputSamples ; i++) {
-                mInputBufferPcm32[i] = (FLAC__int32) pcm16[i];
+            if (inputFloat) {
+                CHECK_LE(nbInputSamples, kNumSamplesPerFrame * kMaxChannels);
+                const float * const pcmFloat = reinterpret_cast<float *>(inHeader->pBuffer);
+                 memcpy_to_q8_23_from_float_with_clamp(
+                         mInputBufferPcm32, pcmFloat, nbInputSamples);
+            } else {
+                // note nbInputSamples may be 2x as large for pcm16 data.
+                CHECK_LE(nbInputSamples, kNumSamplesPerFrame * kMaxChannels * 2);
+                const int16_t * const pcm16 = reinterpret_cast<int16_t *>(inHeader->pBuffer);
+                for (unsigned i = 0; i < nbInputSamples; ++i) {
+                    mInputBufferPcm32[i] = (FLAC__int32) pcm16[i];
+                }
             }
             ALOGV(" about to encode %u samples per channel", nbInputFrames);
             ok = FLAC__stream_encoder_process_interleaved(
@@ -525,10 +554,12 @@
         return OMX_ErrorInvalidState;
     }
 
+    const bool inputFloat = mNumericalData == OMX_NumericalDataFloat;
+    const int codecBitsPerSample = inputFloat ? 24 : 16;
     FLAC__bool ok = true;
     ok = ok && FLAC__stream_encoder_set_channels(mFlacStreamEncoder, mNumChannels);
     ok = ok && FLAC__stream_encoder_set_sample_rate(mFlacStreamEncoder, mSampleRate);
-    ok = ok && FLAC__stream_encoder_set_bits_per_sample(mFlacStreamEncoder, 16);
+    ok = ok && FLAC__stream_encoder_set_bits_per_sample(mFlacStreamEncoder, codecBitsPerSample);
     ok = ok && FLAC__stream_encoder_set_compression_level(mFlacStreamEncoder,
             (unsigned)mCompressionLevel);
     ok = ok && FLAC__stream_encoder_set_verify(mFlacStreamEncoder, false);
diff --git a/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.h b/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.h
index 64a6b1e..722fc13 100644
--- a/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.h
+++ b/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.h
@@ -45,8 +45,10 @@
 
 private:
     const unsigned int kNumBuffers = 2;
-    const unsigned int kMaxNumSamplesPerFrame = 1152;
-    const unsigned int kMaxInputBufferSize = kMaxNumSamplesPerFrame * sizeof(int16_t) * 2;
+    static constexpr unsigned int kMaxChannels = 2;
+    static constexpr unsigned int kNumSamplesPerFrame = 1152;
+    static constexpr unsigned int kMaxInputBufferSize =
+            kNumSamplesPerFrame * kMaxChannels * sizeof(float);
     const unsigned int kMaxOutputBufferSize = 65536;    //TODO check if this can be reduced
 
     bool mSignalledError;
@@ -54,6 +56,8 @@
     OMX_U32 mNumChannels;
     OMX_U32 mSampleRate;
     OMX_U32 mCompressionLevel;
+    OMX_NUMERICALDATATYPE mNumericalData = OMX_NumericalDataSigned;
+    OMX_U32 mBitsPerSample = 16;
 
     // should the data received by the callback be written to the output port
     bool        mEncoderWriteData;
diff --git a/media/libstagefright/codecs/g711/Android.bp b/media/libstagefright/codecs/g711/Android.bp
deleted file mode 100644
index b44c296..0000000
--- a/media/libstagefright/codecs/g711/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["*"]
diff --git a/media/libstagefright/codecs/g711/dec/Android.bp b/media/libstagefright/codecs/g711/dec/Android.bp
index 3d97d8c..f5357f4 100644
--- a/media/libstagefright/codecs/g711/dec/Android.bp
+++ b/media/libstagefright/codecs/g711/dec/Android.bp
@@ -1,26 +1,9 @@
 cc_library_shared {
     name: "libstagefright_soft_g711dec",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
+    defaults: ["libstagefright_softomx-defaults"],
 
     srcs: ["SoftG711.cpp"],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/native/include/media/openmax",
-    ],
-
-    shared_libs: [
-        "libstagefright_foundation",
-        "libstagefright_omx",
-        "libutils",
-        "liblog",
-    ],
-
-    cflags: ["-Werror"],
-
     version_script: "exports.lds",
 
     sanitize: {
@@ -29,9 +12,5 @@
             "unsigned-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
-    compile_multilib: "32",
 }
diff --git a/media/libstagefright/codecs/g711/dec/SoftG711.cpp b/media/libstagefright/codecs/g711/dec/SoftG711.cpp
index 7a4cca9..877cb5a 100644
--- a/media/libstagefright/codecs/g711/dec/SoftG711.cpp
+++ b/media/libstagefright/codecs/g711/dec/SoftG711.cpp
@@ -23,6 +23,8 @@
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/MediaDefs.h>
 
+#define MAX_CHANNEL_COUNT            6  /* maximum number of audio channels that can be decoded */
+
 namespace android {
 
 template<class T>
@@ -184,7 +186,7 @@
                 return OMX_ErrorUndefined;
             }
 
-            if (pcmParams->nChannels < 1 || pcmParams->nChannels > 2) {
+            if (pcmParams->nChannels < 1 || pcmParams->nChannels > MAX_CHANNEL_COUNT) {
                 return OMX_ErrorUndefined;
             }
 
@@ -372,7 +374,7 @@
 
         int32_t step = 4 << segment;
 
-        int32_t abs = (0x80l << exponent) + step * mantissa + step / 2 - 4 * 33;
+        int32_t abs = (0x80L << exponent) + step * mantissa + step / 2 - 4 * 33;
 
         *out++ = (x < 0x80) ? -abs : abs;
     }
diff --git a/media/libstagefright/codecs/gsm/Android.bp b/media/libstagefright/codecs/gsm/Android.bp
deleted file mode 100644
index b44c296..0000000
--- a/media/libstagefright/codecs/gsm/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["*"]
diff --git a/media/libstagefright/codecs/gsm/dec/Android.bp b/media/libstagefright/codecs/gsm/dec/Android.bp
index 1c3208b..5672d89 100644
--- a/media/libstagefright/codecs/gsm/dec/Android.bp
+++ b/media/libstagefright/codecs/gsm/dec/Android.bp
@@ -1,20 +1,9 @@
 cc_library_shared {
     name: "libstagefright_soft_gsmdec",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
+    defaults: ["libstagefright_softomx-defaults"],
 
     srcs: ["SoftGSM.cpp"],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/native/include/media/openmax",
-        "external/libgsm/inc",
-    ],
-
-    cflags: ["-Werror"],
-
     version_script: "exports.lds",
 
     sanitize: {
@@ -23,18 +12,7 @@
             "unsigned-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
-    shared_libs: [
-        "libstagefright_foundation",
-        "libstagefright_omx",
-        "libutils",
-        "liblog",
-    ],
-
     static_libs: ["libgsm"],
-    compile_multilib: "32",
 }
diff --git a/media/libstagefright/codecs/hevcdec/Android.bp b/media/libstagefright/codecs/hevcdec/Android.bp
index 45920e6..ec436ce 100644
--- a/media/libstagefright/codecs/hevcdec/Android.bp
+++ b/media/libstagefright/codecs/hevcdec/Android.bp
@@ -1,48 +1,26 @@
 cc_library_shared {
     name: "libstagefright_soft_hevcdec",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
+    defaults: ["libstagefright_softomx-defaults"],
 
     static_libs: ["libhevcdec"],
     srcs: ["SoftHEVC.cpp"],
 
     cflags: [
         "-Wall",
-        "-Werror",
         "-Wno-unused-variable",
     ],
 
     version_script: "exports.lds",
 
-    include_dirs: [
-        "external/libhevc/decoder",
-        "external/libhevc/common",
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/native/include/media/openmax",
-    ],
-
     sanitize: {
         misc_undefined: [
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
-    shared_libs: [
-        "libstagefright_omx",
-        "libstagefright_foundation",
-        "libutils",
-        "liblog",
-    ],
-
     // We need this because the current asm generates the following link error:
     // requires unsupported dynamic reloc R_ARM_REL32; recompile with -fPIC
     // Bug: 16853291
     ldflags: ["-Wl,-Bsymbolic"],
-    compile_multilib: "32",
 }
diff --git a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
index bb7d361..f6ae1f4 100644
--- a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
+++ b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
@@ -569,7 +569,7 @@
             status = ivdec_api_function(mCodecCtx, (void *)&s_dec_ip, (void *)&s_dec_op);
 
             bool unsupportedResolution =
-                (IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED == (s_dec_op.u4_error_code & 0xFF));
+                (IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED == (s_dec_op.u4_error_code & IVD_ERROR_MASK));
 
             /* Check for unsupported dimensions */
             if (unsupportedResolution) {
@@ -579,7 +579,8 @@
                 return;
             }
 
-            bool allocationFailed = (IVD_MEM_ALLOC_FAILED == (s_dec_op.u4_error_code & 0xFF));
+            bool allocationFailed = 
+                (IVD_MEM_ALLOC_FAILED == (s_dec_op.u4_error_code & IVD_ERROR_MASK));
             if (allocationFailed) {
                 ALOGE("Allocation failure in decoder");
                 notify(OMX_EventError, OMX_ErrorUnsupportedSetting, 0, NULL);
@@ -587,7 +588,14 @@
                 return;
             }
 
-            bool resChanged = (IVD_RES_CHANGED == (s_dec_op.u4_error_code & 0xFF));
+            if (IS_IVD_FATAL_ERROR(s_dec_op.u4_error_code)) {
+                ALOGE("Fatal Error : 0x%x", s_dec_op.u4_error_code);
+                notify(OMX_EventError, OMX_ErrorUnsupportedSetting, 0, NULL);
+                mSignalledError = true;
+                return;
+            }
+
+            bool resChanged = (IVD_RES_CHANGED == (s_dec_op.u4_error_code & IVD_ERROR_MASK));
 
             getVUIParams();
 
diff --git a/media/libstagefright/codecs/m4v_h263/Android.bp b/media/libstagefright/codecs/m4v_h263/Android.bp
deleted file mode 100644
index b44c296..0000000
--- a/media/libstagefright/codecs/m4v_h263/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["*"]
diff --git a/media/libstagefright/codecs/m4v_h263/dec/Android.bp b/media/libstagefright/codecs/m4v_h263/dec/Android.bp
index ca70cc2..6b45ea2 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/Android.bp
+++ b/media/libstagefright/codecs/m4v_h263/dec/Android.bp
@@ -38,9 +38,9 @@
         "src/zigzag_tab.cpp",
     ],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/native/include/media/openmax",
+    header_libs: [
+        "media_plugin_headers",
+        "libstagefright_headers"
     ],
 
     local_include_dirs: ["src"],
@@ -60,9 +60,6 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 }
 
@@ -70,45 +67,23 @@
 
 cc_library_shared {
     name: "libstagefright_soft_mpeg4dec",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
+    defaults: ["libstagefright_softomx-defaults"],
 
     srcs: ["SoftMPEG4.cpp"],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/native/include/media/openmax",
-    ],
-
     local_include_dirs: ["src"],
-    export_include_dirs: ["include"],
 
     cflags: [
         "-DOSCL_EXPORT_REF=",
         "-DOSCL_IMPORT_REF=",
-
-        "-Werror",
     ],
 
     static_libs: ["libstagefright_m4vh263dec"],
 
-    shared_libs: [
-        "libstagefright_omx",
-        "libstagefright_foundation",
-        "libutils",
-        "liblog",
-    ],
-
     sanitize: {
         misc_undefined: [
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
-    compile_multilib: "32",
 }
diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
index fda7028..60750d9 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
@@ -24,7 +24,6 @@
 #include <media/stagefright/foundation/AUtils.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
-#include <media/IOMX.h>
 
 #include "mp4dec_api.h"
 
@@ -118,9 +117,14 @@
                 outHeader->nFlags = OMX_BUFFERFLAG_EOS;
 
                 List<BufferInfo *>::iterator it = outQueue.begin();
-                while ((*it)->mHeader != outHeader) {
+                while (it != outQueue.end() && (*it)->mHeader != outHeader) {
                     ++it;
                 }
+                if (it == outQueue.end()) {
+                    ALOGE("couldn't find port buffer %d in outQueue: b/109891727", mNumSamplesOutput & 1);
+                    android_errorWriteLog(0x534e4554, "109891727");
+                    return;
+                }
 
                 BufferInfo *outInfo = *it;
                 outInfo->mOwnedByUs = false;
@@ -382,6 +386,7 @@
     if (portIndex == 0 && mInitialized) {
         CHECK_EQ((int)PVResetVideoDecoder(mHandle), (int)PV_TRUE);
     }
+    mFramesConfigured = false;
 }
 
 void SoftMPEG4::onReset() {
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/block_idct.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/block_idct.cpp
index a75483a..3d10086 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/block_idct.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/block_idct.cpp
@@ -617,6 +617,7 @@
     return;
 }
 
+__attribute__((no_sanitize("signed-integer-overflow")))
 void idctrow_intra(
     int16 *blk, PIXEL *comp, int width
 )
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
index 8d5d071..9c0fcfa 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
@@ -107,6 +107,7 @@
 #else
         if ((size_t)nLayers > SIZE_MAX / sizeof(Vol *)) {
             status = PV_FALSE;
+            oscl_free(video);
             goto fail;
         }
 
@@ -115,7 +116,8 @@
         if (video->vol == NULL) status = PV_FALSE;
         video->memoryUsage += nLayers * sizeof(Vol *);
 
-
+        /* be sure not to leak any previous state */
+        PVCleanUpVideoDecoder(decCtrl);
         /* we need to setup this pointer for the application to */
         /*    pass it around.                                   */
         decCtrl->videoDecoderData = (void *) video;
@@ -184,8 +186,8 @@
 #ifdef DEC_INTERNAL_MEMORY_OPT
                 video->vol[idx] = IMEM_vol[idx];
                 video->memoryUsage += sizeof(Vol);
-                oscl_memset(video->vol[idx], 0, sizeof(Vol));
                 if (video->vol[idx] == NULL) status = PV_FALSE;
+                else oscl_memset(video->vol[idx], 0, sizeof(Vol));
                 stream = IMEM_BitstreamDecVideo;
 #else
                 video->vol[idx] = (Vol *) oscl_malloc(sizeof(Vol));
@@ -211,6 +213,7 @@
                 else
                 {
                     int32 buffer_size;
+                    oscl_memset(stream, 0, sizeof(BitstreamDecVideo));
                     if ((buffer_size = BitstreamOpen(stream, idx)) < 0)
                     {
                         mp4dec_log("InitVideoDecoder(): Can't allocate bitstream buffer.\n");
@@ -337,27 +340,33 @@
 #ifdef DEC_INTERNAL_MEMORY_OPT
     video->currVop->yChan = IMEM_currVop_yChan; /* Allocate memory for all VOP OKA 3/2/1*/
     if (video->currVop->yChan == NULL) status = PV_FALSE;
-    video->currVop->uChan = video->currVop->yChan + size;
-    video->currVop->vChan = video->currVop->uChan + (size >> 2);
+    else {
+        video->currVop->uChan = video->currVop->yChan + size;
+        video->currVop->vChan = video->currVop->uChan + (size >> 2);
+    }
 
     video->prevVop->yChan = IMEM_prevVop_yChan; /* Allocate memory for all VOP OKA 3/2/1*/
     if (video->prevVop->yChan == NULL) status = PV_FALSE;
-    video->prevVop->uChan = video->prevVop->yChan + size;
-    video->prevVop->vChan = video->prevVop->uChan + (size >> 2);
+    else {
+        video->prevVop->uChan = video->prevVop->yChan + size;
+        video->prevVop->vChan = video->prevVop->uChan + (size >> 2);
+    }
 #else
     if (size > INT32_MAX / 3) {
         return PV_FALSE;
     }
     video->currVop->yChan = (PIXEL *) oscl_malloc(size * 3 / 2); /* Allocate memory for all VOP OKA 3/2/1*/
     if (video->currVop->yChan == NULL) status = PV_FALSE;
-
-    video->currVop->uChan = video->currVop->yChan + size;
-    video->currVop->vChan = video->currVop->uChan + (size >> 2);
+    else {
+        video->currVop->uChan = video->currVop->yChan + size;
+        video->currVop->vChan = video->currVop->uChan + (size >> 2);
+    }
     video->prevVop->yChan = (PIXEL *) oscl_malloc(size * 3 / 2); /* Allocate memory for all VOP OKA 3/2/1*/
     if (video->prevVop->yChan == NULL) status = PV_FALSE;
-
-    video->prevVop->uChan = video->prevVop->yChan + size;
-    video->prevVop->vChan = video->prevVop->uChan + (size >> 2);
+    else {
+        video->prevVop->uChan = video->prevVop->yChan + size;
+        video->prevVop->vChan = video->prevVop->uChan + (size >> 2);
+    }
 #endif
     video->memoryUsage += (size * 3);
 #endif   // MEMORY_POOL
@@ -381,8 +390,10 @@
 
             video->prevEnhcVop->yChan = (PIXEL *) oscl_malloc(size * 3 / 2); /* Allocate memory for all VOP OKA 3/2/1*/
             if (video->prevEnhcVop->yChan == NULL) status = PV_FALSE;
-            video->prevEnhcVop->uChan = video->prevEnhcVop->yChan + size;
-            video->prevEnhcVop->vChan = video->prevEnhcVop->uChan + (size >> 2);
+            else {
+                video->prevEnhcVop->uChan = video->prevEnhcVop->yChan + size;
+                video->prevEnhcVop->vChan = video->prevEnhcVop->uChan + (size >> 2);
+            }
             video->memoryUsage += (3 * size / 2);
 #endif
         }
@@ -429,10 +440,12 @@
 #else
     video->sliceNo = (uint8 *) oscl_malloc(nTotalMB);
     if (video->sliceNo == NULL) status = PV_FALSE;
+    else oscl_memset(video->sliceNo, 0, nTotalMB);
     video->memoryUsage += nTotalMB;
 
     video->acPredFlag = (uint8 *) oscl_malloc(nTotalMB * sizeof(uint8));
     if (video->acPredFlag == NULL) status = PV_FALSE;
+    else oscl_memset(video->acPredFlag, 0, nTotalMB * sizeof(uint8));
     video->memoryUsage += (nTotalMB);
 
     if ((size_t)nTotalMB > SIZE_MAX / sizeof(typeDCStore)) {
@@ -440,6 +453,7 @@
     }
     video->predDC = (typeDCStore *) oscl_malloc(nTotalMB * sizeof(typeDCStore));
     if (video->predDC == NULL) status = PV_FALSE;
+    else oscl_memset(video->predDC, 0, nTotalMB * sizeof(typeDCStore));
     video->memoryUsage += (nTotalMB * sizeof(typeDCStore));
 
     if (nMBPerRow > INT32_MAX - 1
@@ -448,6 +462,7 @@
     }
     video->predDCAC_col = (typeDCACStore *) oscl_malloc((nMBPerRow + 1) * sizeof(typeDCACStore));
     if (video->predDCAC_col == NULL) status = PV_FALSE;
+    else oscl_memset(video->predDCAC_col, 0, (nMBPerRow + 1) * sizeof(typeDCACStore));
     video->memoryUsage += ((nMBPerRow + 1) * sizeof(typeDCACStore));
 
     /* element zero will be used for storing vertical (col) AC coefficients */
@@ -457,9 +472,11 @@
     /* Allocating HeaderInfo structure & Quantizer array */
     video->headerInfo.Mode = (uint8 *) oscl_malloc(nTotalMB);
     if (video->headerInfo.Mode == NULL) status = PV_FALSE;
+    else oscl_memset(video->headerInfo.Mode, 0, nTotalMB);
     video->memoryUsage += nTotalMB;
     video->headerInfo.CBP = (uint8 *) oscl_malloc(nTotalMB);
     if (video->headerInfo.CBP == NULL) status = PV_FALSE;
+    else oscl_memset (video->headerInfo.CBP, 0, nTotalMB);
     video->memoryUsage += nTotalMB;
 
     if ((size_t)nTotalMB > SIZE_MAX / sizeof(int16)) {
@@ -467,6 +484,7 @@
     }
     video->QPMB = (int16 *) oscl_malloc(nTotalMB * sizeof(int16));
     if (video->QPMB == NULL) status = PV_FALSE;
+    else memset(video->QPMB, 0x0, nTotalMB * sizeof(int16));
     video->memoryUsage += (nTotalMB * sizeof(int));
 
     /* Allocating macroblock space */
@@ -487,8 +505,10 @@
     }
     video->motX = (MOT *) oscl_malloc(sizeof(MOT) * 4 * nTotalMB);
     if (video->motX == NULL) status = PV_FALSE;
+    else memset(video->motX, 0, sizeof(MOT) * 4 * nTotalMB);
     video->motY = (MOT *) oscl_malloc(sizeof(MOT) * 4 * nTotalMB);
     if (video->motY == NULL) status = PV_FALSE;
+    else memset(video->motY, 0, sizeof(MOT) * 4 * nTotalMB);
     video->memoryUsage += (sizeof(MOT) * 8 * nTotalMB);
 #endif
 
diff --git a/media/libstagefright/codecs/m4v_h263/enc/Android.bp b/media/libstagefright/codecs/m4v_h263/enc/Android.bp
index 6be4036..2738187 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/Android.bp
+++ b/media/libstagefright/codecs/m4v_h263/enc/Android.bp
@@ -32,10 +32,6 @@
 
     version_script: "exports.lds",
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/native/include/media/openmax",
-    ],
     local_include_dirs: ["src"],
     export_include_dirs: ["include"],
 
@@ -44,9 +40,6 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 }
 
@@ -54,49 +47,27 @@
 
 cc_library_shared {
     name: "libstagefright_soft_mpeg4enc",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
+    defaults: ["libstagefright_softomx-defaults"],
 
     srcs: ["SoftMPEG4Encoder.cpp"],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/native/include/media/openmax",
-        "frameworks/native/include/media/hardware",
-    ],
     local_include_dirs: ["src"],
-    export_include_dirs: ["include"],
 
     cflags: [
         "-DBX_RC",
         "-DOSCL_IMPORT_REF=",
         "-DOSCL_UNUSED_ARG(x)=(void)(x)",
         "-DOSCL_EXPORT_REF=",
-
-        "-Werror",
     ],
 
     static_libs: ["libstagefright_m4vh263enc"],
 
-    shared_libs: [
-        "libstagefright_foundation",
-        "libstagefright_omx",
-        "libutils",
-        "liblog",
-    ],
-
     sanitize: {
         misc_undefined: [
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
-    compile_multilib: "32",
 }
 
 //###############################################################################
@@ -122,9 +93,6 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
     static_libs: ["libstagefright_m4vh263enc"],
diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
index f6a7b0e..fa7db81 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
@@ -22,8 +22,8 @@
 #include "mp4enc_api.h"
 #include "OMX_Video.h"
 
-#include <HardwareAPI.h>
-#include <MetadataBufferType.h>
+#include <media/hardware/HardwareAPI.h>
+#include <media/hardware/MetadataBufferType.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AUtils.h>
 #include <media/stagefright/MediaDefs.h>
diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.h b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.h
index 00f2dd3..71e1170 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.h
+++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.h
@@ -17,7 +17,6 @@
 #ifndef SOFT_MPEG4_ENCODER_H_
 #define SOFT_MPEG4_ENCODER_H_
 
-#include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/foundation/ABase.h>
 #include <media/stagefright/omx/SoftVideoEncoderOMXComponent.h>
 #include "mp4enc_api.h"
diff --git a/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h b/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h
index 9451479..d5a3ff1 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h
+++ b/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h
@@ -18,16 +18,17 @@
 #ifndef _MP4ENC_API_H_
 #define _MP4ENC_API_H_
 
+#include <stdint.h>
 #include <string.h>
 
 #ifndef _PV_TYPES_
 #define _PV_TYPES_
-typedef unsigned char UChar;
-typedef char Char;
+typedef uint8_t UChar;
+typedef int8_t Char;
 typedef unsigned int UInt;
 typedef int Int;
-typedef unsigned short UShort;
-typedef short Short;
+typedef uint16_t UShort;
+typedef int16_t Short;
 typedef unsigned int Bool;
 typedef uint32_t ULong;
 
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/mp4def.h b/media/libstagefright/codecs/m4v_h263/enc/src/mp4def.h
index 2d44482..dbd70dc 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/src/mp4def.h
+++ b/media/libstagefright/codecs/m4v_h263/enc/src/mp4def.h
@@ -52,13 +52,13 @@
 
 #ifndef _PV_TYPES_
 #define _PV_TYPES_
-typedef unsigned char UChar;
-typedef char Char;
+typedef uint8_t UChar;
+typedef int8_t Char;
 typedef unsigned int UInt;
 typedef int Int;
-typedef unsigned short UShort;
-typedef short Short;
-typedef short int SInt;
+typedef uint16_t UShort;
+typedef int16_t Short;
+typedef int16_t SInt;
 typedef unsigned int Bool;
 typedef uint32_t ULong;
 typedef void Void;
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/rate_control.cpp b/media/libstagefright/codecs/m4v_h263/enc/src/rate_control.cpp
index 53149c1..ecc3217 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/src/rate_control.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/src/rate_control.cpp
@@ -377,15 +377,15 @@
 /*  In/out   : Nr, B, Rr                                                    */
 /*  Return   : Void                                                         */
 /*  Modified :                                                              */
+/* Input argument "video" is guaranteed non-null by caller                  */
 /* ======================================================================== */
 
-
 PV_STATUS RC_UpdateBuffer(VideoEncData *video, Int currLayer, Int num_skip)
 {
     rateControl *rc  = video->rc[currLayer];
     MultiPass   *pMP = video->pMP[currLayer];
 
-    if (video == NULL || rc == NULL || pMP == NULL)
+    if (rc == NULL || pMP == NULL)
         return PV_FAIL;
 
     rc->VBV_fullness   -= (Int)(rc->bitrate / rc->framerate * num_skip); //rc[currLayer]->Rp;
@@ -524,6 +524,7 @@
 /*  In/out   : rc->T                                                                */
 /*  Return   : Void                                                                 */
 /*  Modified :                                                                      */
+/* Input argument "input" is guaranteed non-null by caller                          */
 /* ================================================================================ */
 
 void targetBitCalculation(void *input)
@@ -537,7 +538,7 @@
     Int diff_counter_BTsrc, diff_counter_BTdst, prev_counter_diff, curr_counter_diff, bound;
     /* BT = Bit Transfer, for pMP->counter_BTsrc, pMP->counter_BTdst */
 
-    if (video == NULL || currVol == NULL || pMP == NULL || rc == NULL)
+    if (currVol == NULL || pMP == NULL || rc == NULL)
         return;
 
     /* some stuff about frame dropping remained here to be done because pMP cannot be inserted into updateRateControl()*/
@@ -693,6 +694,7 @@
 /*  In/out   : rc->T and rc->Qc                                                     */
 /*  Return   : Void                                                                 */
 /*  Modified :                                                                      */
+/*  Input argument "input" is guaranteed non-null by caller                         */
 /* ================================================================================ */
 
 /* Mad based variable bit allocation + QP calculation with a new quadratic method */
@@ -708,7 +710,7 @@
     float curr_mad, prev_mad, curr_RD, prev_RD, average_mad, aver_QP;
 
 
-    if (video == NULL || currVol == NULL || pMP == NULL || rc == NULL)
+    if (currVol == NULL || pMP == NULL || rc == NULL)
         return;
 
     /* Mad based variable bit allocation */
diff --git a/media/libstagefright/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp b/media/libstagefright/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp
index db2c61a..5554ebd 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp
@@ -183,6 +183,10 @@
     // Initialize the encoder.
     if (!PVInitVideoEncoder(&handle, &encParams)) {
         fprintf(stderr, "Failed to initialize the encoder\n");
+        fclose(fpInput);
+        fclose(fpOutput);
+        free(inputBuf);
+        free(outputBuf);
         return EXIT_FAILURE;
     }
 
@@ -190,6 +194,10 @@
     int32_t headerLength = kOutputBufferSize;
     if (!PVGetVolHeader(&handle, outputBuf, &headerLength, 0)) {
         fprintf(stderr, "Failed to get VOL header\n");
+        fclose(fpInput);
+        fclose(fpOutput);
+        free(inputBuf);
+        free(outputBuf);
         return EXIT_FAILURE;
     }
     fwrite(outputBuf, 1, headerLength, fpOutput);
diff --git a/media/libstagefright/codecs/mp3dec/Android.bp b/media/libstagefright/codecs/mp3dec/Android.bp
index 9fa9a4c..b630524 100644
--- a/media/libstagefright/codecs/mp3dec/Android.bp
+++ b/media/libstagefright/codecs/mp3dec/Android.bp
@@ -59,9 +59,6 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
     include_dirs: ["frameworks/av/media/libstagefright/include"],
@@ -81,24 +78,15 @@
 
 cc_library_shared {
     name: "libstagefright_soft_mp3dec",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
+    defaults: ["libstagefright_softomx-defaults"],
 
     srcs: ["SoftMP3.cpp"],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/native/include/media/openmax",
-    ],
     local_include_dirs: [
         "src",
         "include",
     ],
 
-    cflags: ["-Werror"],
-
     version_script: "exports.lds",
 
     sanitize: {
@@ -106,20 +94,9 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
-    shared_libs: [
-        "libstagefright_omx",
-        "libstagefright_foundation",
-        "libutils",
-        "liblog",
-    ],
-
     static_libs: ["libstagefright_mp3dec"],
-    compile_multilib: "32",
 }
 
 //###############################################################################
@@ -144,9 +121,6 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
     static_libs: [
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
index 2364684..80083f7 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
@@ -114,7 +114,7 @@
     mConfig->crcEnabled = false;
 
     uint32_t memRequirements = pvmp3_decoderMemRequirements();
-    mDecoderBuf = malloc(memRequirements);
+    mDecoderBuf = calloc(1, memRequirements);
 
     pvmp3_InitDecoder(mConfig, mDecoderBuf);
     mIsFirst = true;
@@ -407,7 +407,7 @@
         }
 
         outHeader->nTimeStamp =
-            mAnchorTimeUs + (mNumFramesOutput * 1000000ll) / mSamplingRate;
+            mAnchorTimeUs + (mNumFramesOutput * 1000000LL) / mSamplingRate;
 
         if (inHeader) {
             CHECK_GE((int32_t)inHeader->nFilledLen, mConfig->inputBufferUsedLength);
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_get_side_info.cpp b/media/libstagefright/codecs/mp3dec/src/pvmp3_get_side_info.cpp
index e55c2e7..d644207 100644
--- a/media/libstagefright/codecs/mp3dec/src/pvmp3_get_side_info.cpp
+++ b/media/libstagefright/codecs/mp3dec/src/pvmp3_get_side_info.cpp
@@ -127,13 +127,13 @@
         {
             tmp = getbits_crc(inputStream, 14, crc, info->error_protection);
             si->main_data_begin = (tmp << 18) >> 23;    /* 9 */
-            si->private_bits    = (tmp << 23) >> 27;    /* 5 */
+            si->private_bits    = (tmp << 27) >> 27;    /* 5 */
         }
         else
         {
             tmp = getbits_crc(inputStream, 12, crc, info->error_protection);
             si->main_data_begin = (tmp << 20) >> 23;    /* 9 */
-            si->private_bits    = (tmp << 23) >> 29;    /* 3 */
+            si->private_bits    = (tmp << 29) >> 29;    /* 3 */
 
         }
 
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_normalize.cpp b/media/libstagefright/codecs/mp3dec/src/pvmp3_normalize.cpp
index e579bbd..885ab08 100644
--- a/media/libstagefright/codecs/mp3dec/src/pvmp3_normalize.cpp
+++ b/media/libstagefright/codecs/mp3dec/src/pvmp3_normalize.cpp
@@ -160,6 +160,7 @@
         case 0x38000000:
         case 0x30000000:
             i++;
+            break;
 
         default:
             ;
diff --git a/media/libstagefright/codecs/mpeg2dec/Android.bp b/media/libstagefright/codecs/mpeg2dec/Android.bp
index fb0db8f..e849410 100644
--- a/media/libstagefright/codecs/mpeg2dec/Android.bp
+++ b/media/libstagefright/codecs/mpeg2dec/Android.bp
@@ -1,35 +1,17 @@
 cc_library_shared {
     name: "libstagefright_soft_mpeg2dec",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
+    defaults: ["libstagefright_softomx-defaults"],
 
     static_libs: ["libmpeg2dec"],
     srcs: ["SoftMPEG2.cpp"],
 
     cflags: [
         "-Wall",
-        "-Werror",
         "-Wno-unused-variable",
     ],
 
     version_script: "exports.lds",
 
-    include_dirs: [
-        "external/libmpeg2/decoder",
-        "external/libmpeg2/common",
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/native/include/media/openmax",
-    ],
-
-    shared_libs: [
-        "libstagefright_omx",
-        "libstagefright_foundation",
-        "libutils",
-        "liblog",
-    ],
-
     ldflags: ["-Wl,-Bsymbolic"],
 
     sanitize: {
@@ -37,9 +19,5 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
-    compile_multilib: "32",
 }
diff --git a/media/libstagefright/codecs/on2/Android.bp b/media/libstagefright/codecs/on2/Android.bp
deleted file mode 100644
index b44c296..0000000
--- a/media/libstagefright/codecs/on2/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["*"]
diff --git a/media/libstagefright/codecs/on2/dec/Android.bp b/media/libstagefright/codecs/on2/dec/Android.bp
index 8a9399a..82bb8d1 100644
--- a/media/libstagefright/codecs/on2/dec/Android.bp
+++ b/media/libstagefright/codecs/on2/dec/Android.bp
@@ -1,27 +1,10 @@
 cc_library_shared {
     name: "libstagefright_soft_vpxdec",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
+    defaults: ["libstagefright_softomx-defaults"],
 
     srcs: ["SoftVPX.cpp"],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/native/include/media/openmax",
-    ],
-
-    static_libs: ["libvpx"],
-
-    shared_libs: [
-        "libstagefright_omx",
-        "libstagefright_foundation",
-        "libutils",
-        "liblog",
-    ],
-
-    cflags: ["-Werror"],
+    shared_libs: ["libvpx"],
 
     version_script: "exports.lds",
 
@@ -31,9 +14,5 @@
             "unsigned-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
-    compile_multilib: "32",
 }
diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
index 8d5f3e7..0f2ff17 100644
--- a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
+++ b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
@@ -33,6 +33,7 @@
     { OMX_VIDEO_VP9Profile0, OMX_VIDEO_VP9Level5 },
     { OMX_VIDEO_VP9Profile2, OMX_VIDEO_VP9Level5 },
     { OMX_VIDEO_VP9Profile2HDR, OMX_VIDEO_VP9Level5 },
+    { OMX_VIDEO_VP9Profile2HDR10Plus, OMX_VIDEO_VP9Level5 },
 };
 
 SoftVPX::SoftVPX(
@@ -84,6 +85,10 @@
     return true;
 }
 
+bool SoftVPX::supportDescribeHdr10PlusInfo() {
+    return true;
+}
+
 status_t SoftVPX::initDecoder() {
     mCtx = new vpx_codec_ctx_t;
     vpx_codec_err_t vpx_err;
@@ -167,7 +172,12 @@
         outHeader->nOffset = 0;
         outHeader->nFlags = 0;
         outHeader->nFilledLen = (outputBufferWidth() * outputBufferHeight() * bpp * 3) / 2;
-        outHeader->nTimeStamp = *(OMX_TICKS *)mImg->user_priv;
+        PrivInfo *privInfo = (PrivInfo *)mImg->user_priv;
+        outHeader->nTimeStamp = privInfo->mTimeStamp;
+        if (privInfo->mHdr10PlusInfo != nullptr) {
+            queueOutputFrameConfig(privInfo->mHdr10PlusInfo);
+        }
+
         if (outputBufferSafe(outHeader)) {
             uint8_t *dst = outHeader->pBuffer;
             const uint8_t *srcY = (const uint8_t *)mImg->planes[VPX_PLANE_Y];
@@ -275,7 +285,13 @@
             }
         }
 
-        mTimeStamps[mTimeStampIdx] = inHeader->nTimeStamp;
+        mPrivInfo[mTimeStampIdx].mTimeStamp = inHeader->nTimeStamp;
+
+        if (inInfo->mFrameConfig) {
+            mPrivInfo[mTimeStampIdx].mHdr10PlusInfo = dequeueInputFrameConfig();
+        } else {
+            mPrivInfo[mTimeStampIdx].mHdr10PlusInfo.clear();
+        }
 
         if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
             mEOSStatus = INPUT_EOS_SEEN;
@@ -285,7 +301,7 @@
         if (inHeader->nFilledLen > 0) {
             vpx_codec_err_t err = vpx_codec_decode(
                     (vpx_codec_ctx_t *)mCtx, inHeader->pBuffer + inHeader->nOffset,
-                    inHeader->nFilledLen, &mTimeStamps[mTimeStampIdx], 0);
+                    inHeader->nFilledLen, &mPrivInfo[mTimeStampIdx], 0);
             if (err == VPX_CODEC_OK) {
                 inInfo->mOwnedByUs = false;
                 inQueue.erase(inQueue.begin());
diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.h b/media/libstagefright/codecs/on2/dec/SoftVPX.h
index b62b526..0aa8e9c 100644
--- a/media/libstagefright/codecs/on2/dec/SoftVPX.h
+++ b/media/libstagefright/codecs/on2/dec/SoftVPX.h
@@ -26,6 +26,8 @@
 
 namespace android {
 
+struct ABuffer;
+
 struct SoftVPX : public SoftVideoDecoderOMXComponent {
     SoftVPX(const char *name,
             const char *componentRole,
@@ -41,6 +43,7 @@
     virtual void onPortFlushCompleted(OMX_U32 portIndex);
     virtual void onReset();
     virtual bool supportDescribeHdrStaticInfo();
+    virtual bool supportDescribeHdr10PlusInfo();
 
 private:
     enum {
@@ -60,7 +63,11 @@
 
     void *mCtx;
     bool mFrameParallelMode;  // Frame parallel is only supported by VP9 decoder.
-    OMX_TICKS mTimeStamps[kNumBuffers];
+    struct PrivInfo {
+        OMX_TICKS mTimeStamp;
+        sp<ABuffer> mHdr10PlusInfo;
+    };
+    PrivInfo mPrivInfo[kNumBuffers];
     uint8_t mTimeStampIdx;
     vpx_image_t *mImg;
 
diff --git a/media/libstagefright/codecs/on2/enc/Android.bp b/media/libstagefright/codecs/on2/enc/Android.bp
index 3d9feeb..cd69e0d 100644
--- a/media/libstagefright/codecs/on2/enc/Android.bp
+++ b/media/libstagefright/codecs/on2/enc/Android.bp
@@ -1,9 +1,6 @@
 cc_library_shared {
     name: "libstagefright_soft_vpxenc",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
+    defaults: ["libstagefright_softomx-defaults"],
 
     srcs: [
         "SoftVPXEncoder.cpp",
@@ -11,33 +8,17 @@
         "SoftVP9Encoder.cpp",
     ],
 
-    cflags: ["-Wall", "-Werror"],
+    cflags: ["-Wall"],
 
     version_script: "exports.lds",
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/native/include/media/openmax",
-    ],
-
     sanitize: {
         misc_undefined: [
             "signed-integer-overflow",
             "unsigned-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
-    static_libs: ["libvpx"],
-
-    shared_libs: [
-        "libstagefright_omx",
-        "libstagefright_foundation",
-        "libutils",
-        "liblog",
-    ],
-    compile_multilib: "32",
+    shared_libs: ["libvpx"],
 }
diff --git a/media/libstagefright/codecs/on2/enc/SoftVP8Encoder.h b/media/libstagefright/codecs/on2/enc/SoftVP8Encoder.h
index b4904bfd..c5c2abf 100644
--- a/media/libstagefright/codecs/on2/enc/SoftVP8Encoder.h
+++ b/media/libstagefright/codecs/on2/enc/SoftVP8Encoder.h
@@ -23,8 +23,6 @@
 #include <OMX_VideoExt.h>
 #include <OMX_IndexExt.h>
 
-#include <hardware/gralloc.h>
-
 #include "vpx/vpx_encoder.h"
 #include "vpx/vpx_codec.h"
 #include "vpx/vp8cx.h"
diff --git a/media/libstagefright/codecs/on2/enc/SoftVP9Encoder.h b/media/libstagefright/codecs/on2/enc/SoftVP9Encoder.h
index 85df69a..308a9ac 100644
--- a/media/libstagefright/codecs/on2/enc/SoftVP9Encoder.h
+++ b/media/libstagefright/codecs/on2/enc/SoftVP9Encoder.h
@@ -23,8 +23,6 @@
 #include <OMX_VideoExt.h>
 #include <OMX_IndexExt.h>
 
-#include <hardware/gralloc.h>
-
 #include "vpx/vpx_encoder.h"
 #include "vpx/vpx_codec.h"
 #include "vpx/vp8cx.h"
diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
index f6257b1..d0cb071 100644
--- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
+++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
@@ -21,6 +21,7 @@
 #include "SoftVP8Encoder.h"
 #include "SoftVP9Encoder.h"
 
+#include <android-base/macros.h>
 #include <utils/Log.h>
 #include <utils/misc.h>
 
@@ -400,8 +401,8 @@
     }
 }
 
-OMX_ERRORTYPE SoftVPXEncoder::setConfig(
-        OMX_INDEXTYPE index, const OMX_PTR _params) {
+OMX_ERRORTYPE SoftVPXEncoder::internalSetConfig(
+        OMX_INDEXTYPE index, const OMX_PTR _params, bool *frameConfig) {
     switch (index) {
         case OMX_IndexConfigVideoIntraVOPRefresh:
         {
@@ -441,7 +442,7 @@
         }
 
         default:
-            return SimpleSoftOMXComponent::setConfig(index, _params);
+            return SimpleSoftOMXComponent::internalSetConfig(index, _params, frameConfig);
     }
 }
 
@@ -557,7 +558,7 @@
               break;
           case kTemporalUpdateGoldenWithoutDependency:
               flags |= VP8_EFLAG_NO_REF_GF;
-              // Deliberately no break here.
+              FALLTHROUGH_INTENDED;
           case kTemporalUpdateGolden:
               flags |= VP8_EFLAG_NO_REF_ARF;
               flags |= VP8_EFLAG_NO_UPD_ARF;
@@ -566,14 +567,14 @@
           case kTemporalUpdateAltrefWithoutDependency:
               flags |= VP8_EFLAG_NO_REF_ARF;
               flags |= VP8_EFLAG_NO_REF_GF;
-              // Deliberately no break here.
+              FALLTHROUGH_INTENDED;
           case kTemporalUpdateAltref:
               flags |= VP8_EFLAG_NO_UPD_GF;
               flags |= VP8_EFLAG_NO_UPD_LAST;
               break;
           case kTemporalUpdateNoneNoRefAltref:
               flags |= VP8_EFLAG_NO_REF_ARF;
-              // Deliberately no break here.
+              FALLTHROUGH_INTENDED;
           case kTemporalUpdateNone:
               flags |= VP8_EFLAG_NO_UPD_GF;
               flags |= VP8_EFLAG_NO_UPD_ARF;
diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h
index dd86d36..7208d69 100644
--- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h
+++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h
@@ -23,8 +23,6 @@
 #include <OMX_VideoExt.h>
 #include <OMX_IndexExt.h>
 
-#include <hardware/gralloc.h>
-
 #include "vpx/vpx_encoder.h"
 #include "vpx/vpx_codec.h"
 #include "vpx/vp8cx.h"
@@ -84,8 +82,8 @@
     virtual OMX_ERRORTYPE internalSetParameter(
             OMX_INDEXTYPE index, const OMX_PTR param);
 
-    virtual OMX_ERRORTYPE setConfig(
-            OMX_INDEXTYPE index, const OMX_PTR params);
+    virtual OMX_ERRORTYPE internalSetConfig(
+            OMX_INDEXTYPE index, const OMX_PTR params, bool *frameConfig);
 
     // OMX callback when buffers available
     // Note that both an input and output buffer
diff --git a/media/libstagefright/codecs/opus/Android.bp b/media/libstagefright/codecs/opus/Android.bp
deleted file mode 100644
index b44c296..0000000
--- a/media/libstagefright/codecs/opus/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["*"]
diff --git a/media/libstagefright/codecs/opus/dec/Android.bp b/media/libstagefright/codecs/opus/dec/Android.bp
index 43318f2..71a2a0d 100644
--- a/media/libstagefright/codecs/opus/dec/Android.bp
+++ b/media/libstagefright/codecs/opus/dec/Android.bp
@@ -1,27 +1,13 @@
 cc_library_shared {
     name: "libstagefright_soft_opusdec",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
+    defaults: ["libstagefright_softomx-defaults"],
 
     srcs: ["SoftOpus.cpp"],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/native/include/media/openmax",
-    ],
-
     shared_libs: [
         "libopus",
-        "libstagefright_omx",
-        "libstagefright_foundation",
-        "libutils",
-        "liblog",
     ],
 
-    cflags: ["-Werror"],
-
     version_script: "exports.lds",
 
     sanitize: {
@@ -30,9 +16,5 @@
             "unsigned-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
-    compile_multilib: "32",
 }
diff --git a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
index 813004b..4f61aa8 100644
--- a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
+++ b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
@@ -430,8 +430,17 @@
                 return;
             }
 
+            if (size < sizeof(int64_t)) {
+                // The 2nd and 3rd input buffer are expected to contain
+                //  an int64_t (see below), so make sure we get at least
+                //  that much. The first input buffer must contain 19 bytes,
+                //  but that is checked already.
+                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                return;
+            }
+
             if (mInputBufferCount == 0) {
-                CHECK(mHeader == NULL);
+                delete mHeader;
                 mHeader = new OpusHeader();
                 memset(mHeader, 0, sizeof(*mHeader));
                 if (!ParseOpusHeader(data, size, mHeader)) {
@@ -452,6 +461,9 @@
                 }
 
                 int status = OPUS_INVALID_STATE;
+                if (mDecoder != NULL) {
+                    opus_multistream_decoder_destroy(mDecoder);
+                }
                 mDecoder = opus_multistream_decoder_create(kRate,
                                                            mHeader->channels,
                                                            mHeader->num_streams,
@@ -570,7 +582,7 @@
         outHeader->nFilledLen = numFrames * sizeof(int16_t) * mHeader->channels;
 
         outHeader->nTimeStamp = mAnchorTimeUs +
-                                (mNumFramesOutput * 1000000ll) /
+                                (mNumFramesOutput * 1000000LL) /
                                 kRate;
 
         mNumFramesOutput += numFrames;
diff --git a/media/libstagefright/codecs/raw/Android.bp b/media/libstagefright/codecs/raw/Android.bp
index c8d7d00..fcc7a0a 100644
--- a/media/libstagefright/codecs/raw/Android.bp
+++ b/media/libstagefright/codecs/raw/Android.bp
@@ -1,19 +1,9 @@
 cc_library_shared {
     name: "libstagefright_soft_rawdec",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
+    defaults: ["libstagefright_softomx-defaults"],
 
     srcs: ["SoftRaw.cpp"],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/native/include/media/openmax",
-    ],
-
-    cflags: ["-Werror"],
-
     version_script: "exports.lds",
 
     sanitize: {
@@ -22,16 +12,5 @@
             "unsigned-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
-
-    shared_libs: [
-        "libstagefright_omx",
-        "libstagefright_foundation",
-        "libutils",
-        "liblog",
-    ],
-    compile_multilib: "32",
 }
diff --git a/media/libstagefright/codecs/raw/SoftRaw.cpp b/media/libstagefright/codecs/raw/SoftRaw.cpp
index 1a527b3..0e31804 100644
--- a/media/libstagefright/codecs/raw/SoftRaw.cpp
+++ b/media/libstagefright/codecs/raw/SoftRaw.cpp
@@ -60,7 +60,7 @@
     def.eDir = OMX_DirInput;
     def.nBufferCountMin = kNumBuffers;
     def.nBufferCountActual = def.nBufferCountMin;
-    def.nBufferSize = 64 * 1024;
+    def.nBufferSize = 192 * 1024;
     def.bEnabled = OMX_TRUE;
     def.bPopulated = OMX_FALSE;
     def.eDomain = OMX_PortDomainAudio;
@@ -78,7 +78,7 @@
     def.eDir = OMX_DirOutput;
     def.nBufferCountMin = kNumBuffers;
     def.nBufferCountActual = def.nBufferCountMin;
-    def.nBufferSize = 64 * 1024;
+    def.nBufferSize = 192 * 1024;
     def.bEnabled = OMX_TRUE;
     def.bPopulated = OMX_FALSE;
     def.eDomain = OMX_PortDomainAudio;
diff --git a/media/libstagefright/codecs/vorbis/Android.bp b/media/libstagefright/codecs/vorbis/Android.bp
deleted file mode 100644
index b44c296..0000000
--- a/media/libstagefright/codecs/vorbis/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["*"]
diff --git a/media/libstagefright/codecs/vorbis/dec/Android.bp b/media/libstagefright/codecs/vorbis/dec/Android.bp
index a9265cb..3efb952 100644
--- a/media/libstagefright/codecs/vorbis/dec/Android.bp
+++ b/media/libstagefright/codecs/vorbis/dec/Android.bp
@@ -1,27 +1,13 @@
 cc_library_shared {
     name: "libstagefright_soft_vorbisdec",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
+    defaults: ["libstagefright_softomx-defaults"],
 
     srcs: ["SoftVorbis.cpp"],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/native/include/media/openmax",
-    ],
-
     shared_libs: [
         "libvorbisidec",
-        "libstagefright_omx",
-        "libstagefright_foundation",
-        "libutils",
-        "liblog",
     ],
 
-    cflags: ["-Werror"],
-
     version_script: "exports.lds",
 
     sanitize: {
@@ -30,5 +16,4 @@
             "unsigned-integer-overflow",
         ],
     },
-    compile_multilib: "32",
 }
diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
index 8912f8a..76a400c 100644
--- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
+++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
@@ -357,7 +357,10 @@
         int32_t numPageSamples = 0;
 
         if (inHeader) {
-            if (mInputBufferCount < 2) {
+            // Assume the very first 2 buffers are always codec config (in this case mState is NULL)
+            // After flush, handle CSD
+            if (mInputBufferCount < 2 &&
+                    (mState == NULL || (inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG))) {
                 const uint8_t *data = inHeader->pBuffer + inHeader->nOffset;
                 size_t size = inHeader->nFilledLen;
 
@@ -380,7 +383,24 @@
 
                 makeBitReader((const uint8_t *)data + 7, size - 7, &buf, &ref, &bits);
 
-                if (mInputBufferCount == 0) {
+                // Assume very first frame is identification header - or reset identification
+                // header after flush, but allow only specifying setup header after flush if
+                // identification header was already set up.
+                if (mInputBufferCount == 0 &&
+                        (mVi == NULL || data[0] == 1 /* identification header */)) {
+                    // remove any prior state
+                    if (mVi != NULL) {
+                        // also clear mState as it may refer to the old mVi
+                        if (mState != NULL) {
+                            vorbis_dsp_clear(mState);
+                            delete mState;
+                            mState = NULL;
+                        }
+                        vorbis_info_clear(mVi);
+                        delete mVi;
+                        mVi = NULL;
+                    }
+
                     CHECK(mVi == NULL);
                     mVi = new vorbis_info;
                     vorbis_info_init(mVi);
@@ -392,8 +412,15 @@
                         return;
                     }
                 } else {
+                    // remove any prior state
+                    if (mState != NULL) {
+                        vorbis_dsp_clear(mState);
+                        delete mState;
+                        mState = NULL;
+                    }
+
                     int ret = _vorbis_unpack_books(mVi, &bits);
-                    if (ret != 0) {
+                    if (ret != 0 || mState != NULL) {
                         notify(OMX_EventError, OMX_ErrorUndefined, ret, NULL);
                         mSignalledError = true;
                         return;
@@ -409,6 +436,7 @@
                         notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
                         mOutputPortSettingsChange = AWAITING_DISABLED;
                     }
+                    mInputBufferCount = 1;
                 }
 
                 if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
@@ -526,7 +554,7 @@
 
         outHeader->nTimeStamp =
             mAnchorTimeUs
-                + (mNumFramesOutput * 1000000ll) / mVi->rate;
+                + (mNumFramesOutput * 1000000LL) / mVi->rate;
 
         mNumFramesOutput += numFrames;
 
@@ -548,6 +576,7 @@
         // Make sure that the next buffer output does not still
         // depend on fragments from the last one decoded.
 
+        mInputBufferCount = 0;
         mNumFramesOutput = 0;
         mSawInputEos = false;
         mSignalledOutputEos = false;
diff --git a/media/libstagefright/codecs/xaacdec/Android.bp b/media/libstagefright/codecs/xaacdec/Android.bp
index 7392f1e..5385dbc 100644
--- a/media/libstagefright/codecs/xaacdec/Android.bp
+++ b/media/libstagefright/codecs/xaacdec/Android.bp
@@ -1,18 +1,12 @@
 cc_library_shared {
     name: "libstagefright_soft_xaacdec",
-    vendor_available: true,
+    defaults: ["libstagefright_softomx-defaults"],
 
     srcs: [
         "SoftXAAC.cpp",
     ],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/native/include/media/openmax",
-    ],
-
     cflags: [
-        "-Werror",
         "-DENABLE_MPEG_D_DRC"
     ],
 
@@ -25,12 +19,6 @@
     static_libs: ["libxaacdec"],
 
     shared_libs: [
-        "libstagefright_omx",
-        "libstagefright_foundation",
-        "libutils",
         "libcutils",
-        "liblog",
     ],
-
-    compile_multilib: "32",
 }
diff --git a/media/libstagefright/codecs/xaacdec/SoftXAAC.cpp b/media/libstagefright/codecs/xaacdec/SoftXAAC.cpp
index 06b15b3..da86758 100644
--- a/media/libstagefright/codecs/xaacdec/SoftXAAC.cpp
+++ b/media/libstagefright/codecs/xaacdec/SoftXAAC.cpp
@@ -79,7 +79,7 @@
 
 static const OMX_U32 kSupportedProfiles[] = {
     OMX_AUDIO_AACObjectLC, OMX_AUDIO_AACObjectHE,  OMX_AUDIO_AACObjectHE_PS,
-    OMX_AUDIO_AACObjectLD, OMX_AUDIO_AACObjectELD,
+    OMX_AUDIO_AACObjectLD, OMX_AUDIO_AACObjectELD, OMX_AUDIO_AACObjectXHE
 };
 
 SoftXAAC::SoftXAAC(const char* name, const OMX_CALLBACKTYPE* callbacks, OMX_PTR appData,
@@ -110,15 +110,22 @@
 
 {
     initPorts();
-    CHECK_EQ(initDecoder(), (status_t)OK);
+    mMemoryVec.clear();
+    mDrcMemoryVec.clear();
+
+    CHECK_EQ(initDecoder(), IA_NO_ERROR);
 }
 
 SoftXAAC::~SoftXAAC() {
-    int errCode = deInitXAACDecoder();
-    if (0 != errCode) {
-        ALOGE("deInitXAACDecoder() failed %d", errCode);
+    IA_ERRORCODE err_code = deInitXAACDecoder();
+    if (IA_NO_ERROR != err_code) {
+        ALOGE("deInitXAACDecoder() failed %d", err_code);
     }
 
+    err_code = deInitMPEGDDDrc();
+    if (IA_NO_ERROR != err_code) {
+        ALOGE("deInitMPEGDDDrc() failed %d", err_code);
+    }
     mIsCodecInitialized = false;
     mIsCodecConfigFlushRequired = false;
 }
@@ -164,36 +171,16 @@
     addPort(def);
 }
 
-status_t SoftXAAC::initDecoder() {
-    status_t status = UNKNOWN_ERROR;
-
+IA_ERRORCODE SoftXAAC::initDecoder() {
     int ui_drc_val;
     IA_ERRORCODE err_code = IA_NO_ERROR;
     int loop = 0;
 
     err_code = initXAACDecoder();
     if (err_code != IA_NO_ERROR) {
-        if (NULL == mXheaacCodecHandle) {
-            ALOGE("AAC decoder handle is null");
-        }
-        if (NULL == mMpegDDrcHandle) {
-            ALOGE("MPEG-D DRC decoder handle is null");
-        }
-        for (loop = 1; loop < mMallocCount; loop++) {
-            if (mMemoryArray[loop] == NULL) {
-                ALOGE(" memory allocation error %d\n", loop);
-                break;
-            }
-        }
-        ALOGE("initXAACDecoder Failed");
-
-        for (loop = 0; loop < mMallocCount; loop++) {
-            if (mMemoryArray[loop]) free(mMemoryArray[loop]);
-        }
-        mMallocCount = 0;
-        return status;
-    } else {
-        status = OK;
+        ALOGE("initXAACDecoder failed with error %d", err_code);
+        deInitXAACDecoder();
+        return err_code;
     }
 
     mEndOfInput = false;
@@ -274,7 +261,7 @@
     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE");
 
 #endif
-    return status;
+    return IA_NO_ERROR;
 }
 
 OMX_ERRORTYPE SoftXAAC::internalGetParameter(OMX_INDEXTYPE index, OMX_PTR params) {
@@ -547,9 +534,6 @@
     /* sample currently                                                  */
     if (mIsCodecInitialized) {
         numOutBytes = mOutputFrameLength * (mPcmWdSz / 8) * mNumChannels;
-        if ((mPcmWdSz / 8) != 2) {
-            ALOGE("XAAC assumes 2 bytes per sample! mPcmWdSz %d", mPcmWdSz);
-        }
     }
 
     while ((!inQueue.empty() || mEndOfInput) && !outQueue.empty()) {
@@ -569,8 +553,8 @@
                 inBufferLength = inHeader->nFilledLen;
 
                 /* GA header configuration sent to Decoder! */
-                int err_code = configXAACDecoder(inBuffer, inBufferLength);
-                if (0 != err_code) {
+                IA_ERRORCODE err_code = configXAACDecoder(inBuffer, inBufferLength);
+                if (IA_NO_ERROR != err_code) {
                     ALOGW("configXAACDecoder err_code = %d", err_code);
                     mSignalledError = true;
                     notify(OMX_EventError, OMX_ErrorUndefined, err_code, NULL);
@@ -665,7 +649,7 @@
                     mCurrentTimestamp = inHeader->nTimeStamp;
                     mLastInHeader = inHeader;
                 } else {
-                    mCurrentTimestamp = mPrevTimestamp + mOutputFrameLength * 1000000ll / mSampFreq;
+                    mCurrentTimestamp = mPrevTimestamp + mOutputFrameLength * 1000000LL / mSampFreq;
                 }
             } else {
                 inBuffer = inHeader->pBuffer + inHeader->nOffset;
@@ -682,8 +666,8 @@
             /* which should initialize the codec. Once this state is reached, call the  */
             /* decodeXAACStream API with same frame to decode!                        */
             if (!mIsCodecInitialized) {
-                int err_code = configXAACDecoder(inBuffer, inBufferLength);
-                if (0 != err_code) {
+                IA_ERRORCODE err_code = configXAACDecoder(inBuffer, inBufferLength);
+                if (IA_NO_ERROR != err_code) {
                     ALOGW("configXAACDecoder Failed 2 err_code = %d", err_code);
                     mSignalledError = true;
                     notify(OMX_EventError, OMX_ErrorUndefined, err_code, NULL);
@@ -845,7 +829,7 @@
     }
 }
 
-int SoftXAAC::configflushDecode() {
+IA_ERRORCODE SoftXAAC::configflushDecode() {
     IA_ERRORCODE err_code;
     UWORD32 ui_init_done;
     uint32_t inBufferLength = 8203;
@@ -871,16 +855,13 @@
             "Found Codec with below config---\nsampFreq %d\nnumChannels %d\npcmWdSz "
             "%d\nchannelMask %d\noutputFrameLength %d",
             mSampFreq, mNumChannels, mPcmWdSz, mChannelMask, mOutputFrameLength);
-        if (mNumChannels > MAX_CHANNEL_COUNT) {
-            ALOGE(" No of channels are more than max channels\n");
-            mIsCodecInitialized = false;
-        } else
-            mIsCodecInitialized = true;
+
+        mIsCodecInitialized = true;
     }
-    return err_code;
+    return IA_NO_ERROR;
 }
-int SoftXAAC::drainDecoder() {
-    return 0;
+IA_ERRORCODE SoftXAAC::drainDecoder() {
+    return IA_NO_ERROR;
 }
 
 void SoftXAAC::onReset() {
@@ -921,7 +902,7 @@
     }
 }
 
-int SoftXAAC::initXAACDecoder() {
+IA_ERRORCODE SoftXAAC::initXAACDecoder() {
     LOOPIDX i;
 
     /* Error code */
@@ -939,11 +920,11 @@
     UWORD32 ui_proc_mem_tabs_size;
     /* API size */
     UWORD32 pui_api_size;
+    pVOID pv_alloc_ptr;
 
     mInputBufferSize = 0;
     mInputBuffer = 0;
     mOutputBuffer = 0;
-    mMallocCount = 0;
 
     /* Process struct initing end */
     /* ******************************************************************/
@@ -954,20 +935,13 @@
     err_code = ixheaacd_dec_api(NULL, IA_API_CMD_GET_API_SIZE, 0, &pui_api_size);
     RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_API_SIZE");
 
-    if (mMallocCount == MAX_MEM_ALLOCS) {
-        ALOGE("mMemoryArray is full");
-        return IA_FATAL_ERROR;
-    }
-
     /* Allocate memory for API */
-    mMemoryArray[mMallocCount] = memalign(4, pui_api_size);
-    if (mMemoryArray[mMallocCount] == NULL) {
+    mXheaacCodecHandle = memalign(4, pui_api_size);
+    if (mXheaacCodecHandle == NULL) {
         ALOGE("malloc for pui_api_size + 4 >> %d Failed", pui_api_size + 4);
         return IA_FATAL_ERROR;
     }
-    /* Set API object with the memory allocated */
-    mXheaacCodecHandle = (pVOID)((WORD8*)mMemoryArray[mMallocCount]);
-    mMallocCount++;
+    mMemoryVec.push(mXheaacCodecHandle);
 
     /* Set the config params to default values */
     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT,
@@ -979,23 +953,16 @@
 
     RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_API_SIZE");
 
-    if (mMallocCount == MAX_MEM_ALLOCS) {
-        ALOGE("mMemoryArray is full");
-        return IA_FATAL_ERROR;
-    }
-
     /* Allocate memory for API */
-    mMemoryArray[mMallocCount] = memalign(4, pui_api_size);
+    mMpegDDrcHandle = memalign(4, pui_api_size);
 
-    if (mMemoryArray[mMallocCount] == NULL) {
+    if (mMpegDDrcHandle == NULL) {
         ALOGE("malloc for drc api structure Failed");
         return IA_FATAL_ERROR;
     }
-    memset(mMemoryArray[mMallocCount], 0, pui_api_size);
+    mMemoryVec.push(mMpegDDrcHandle);
 
-    /* Set API object with the memory allocated */
-    mMpegDDrcHandle = (pVOID)((WORD8*)mMemoryArray[mMallocCount]);
-    mMallocCount++;
+    memset(mMpegDDrcHandle, 0, pui_api_size);
 
     /* Set the config params to default values */
     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
@@ -1021,23 +988,17 @@
                                 &ui_proc_mem_tabs_size);
     RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEMTABS_SIZE");
 
-    if (mMallocCount == MAX_MEM_ALLOCS) {
-        ALOGE("mMemoryArray is full");
-        return IA_FATAL_ERROR;
-    }
-
-    mMemoryArray[mMallocCount] = memalign(4, ui_proc_mem_tabs_size);
-    if (mMemoryArray[mMallocCount] == NULL) {
+    pv_alloc_ptr = memalign(4, ui_proc_mem_tabs_size);
+    if (pv_alloc_ptr == NULL) {
         ALOGE("Malloc for size (ui_proc_mem_tabs_size + 4) = %d failed!",
               ui_proc_mem_tabs_size + 4);
         return IA_FATAL_ERROR;
     }
-    mMallocCount++;
-    /* Set pointer for process memory tables    */
-    err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_MEMTABS_PTR, 0,
-                                (pVOID)((WORD8*)mMemoryArray[mMallocCount - 1]));
-    RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEMTABS_PTR");
+    mMemoryVec.push(pv_alloc_ptr);
 
+    /* Set pointer for process memory tables    */
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_MEMTABS_PTR, 0, pv_alloc_ptr);
+    RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEMTABS_PTR");
 
     /* initialize the API, post config, fill memory tables  */
     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT,
@@ -1066,17 +1027,12 @@
         err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_MEM_INFO_TYPE, i, &ui_type);
         RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_TYPE");
 
-        if (mMallocCount == MAX_MEM_ALLOCS) {
-            ALOGE("mMemoryArray is full");
-            return IA_FATAL_ERROR;
-        }
-        mMemoryArray[mMallocCount] = memalign(ui_alignment, ui_size);
-        if (mMemoryArray[mMallocCount] == NULL) {
+        pv_alloc_ptr = memalign(ui_alignment, ui_size);
+        if (pv_alloc_ptr == NULL) {
             ALOGE("Malloc for size (ui_size + ui_alignment) = %d failed!", ui_size + ui_alignment);
             return IA_FATAL_ERROR;
         }
-        pv_alloc_ptr = (pVOID)((WORD8*)mMemoryArray[mMallocCount]);
-        mMallocCount++;
+        mMemoryVec.push(pv_alloc_ptr);
 
         /* Set the buffer pointer */
         err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_MEM_PTR, i, pv_alloc_ptr);
@@ -1095,7 +1051,7 @@
     return IA_NO_ERROR;
 }
 
-int SoftXAAC::configXAACDecoder(uint8_t* inBuffer, uint32_t inBufferLength) {
+IA_ERRORCODE SoftXAAC::configXAACDecoder(uint8_t* inBuffer, uint32_t inBufferLength) {
     UWORD32 ui_init_done;
     int32_t i_bytes_consumed;
 
@@ -1154,14 +1110,76 @@
 
     return IA_NO_ERROR;
 }
-int SoftXAAC::configMPEGDDrc() {
+IA_ERRORCODE SoftXAAC::initMPEGDDDrc() {
+    IA_ERRORCODE err_code = IA_NO_ERROR;
+    int i;
+
+    for (i = 0; i < (WORD32)2; i++) {
+        WORD32 ui_size, ui_alignment, ui_type;
+        pVOID pv_alloc_ptr;
+
+        /* Get memory size */
+        err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_SIZE, i, &ui_size);
+
+        RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_SIZE");
+
+        /* Get memory alignment */
+        err_code =
+            ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_ALIGNMENT, i, &ui_alignment);
+
+        RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_ALIGNMENT");
+
+        /* Get memory type */
+        err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_TYPE, i, &ui_type);
+        RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_TYPE");
+
+        pv_alloc_ptr = memalign(4, ui_size);
+        if (pv_alloc_ptr == NULL) {
+            ALOGE(" Cannot create requested memory  %d", ui_size);
+            return IA_FATAL_ERROR;
+        }
+        mDrcMemoryVec.push(pv_alloc_ptr);
+
+        /* Set the buffer pointer */
+        err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, i, pv_alloc_ptr);
+
+        RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
+    }
+
+    WORD32 ui_size;
+    ui_size = 8192 * 2;
+
+    mDrcInBuf = (int8_t*)memalign(4, ui_size);
+    if (mDrcInBuf == NULL) {
+        ALOGE(" Cannot create requested memory  %d", ui_size);
+        return IA_FATAL_ERROR;
+    }
+    mDrcMemoryVec.push(mDrcInBuf);
+
+    err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, 2, mDrcInBuf);
+    RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
+
+    mDrcOutBuf = (int8_t*)memalign(4, ui_size);
+    if (mDrcOutBuf == NULL) {
+        ALOGE(" Cannot create requested memory  %d", ui_size);
+        return IA_FATAL_ERROR;
+    }
+    mDrcMemoryVec.push(mDrcOutBuf);
+
+    err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, 3, mDrcOutBuf);
+    RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
+
+    return IA_NO_ERROR;
+}
+IA_ERRORCODE SoftXAAC::configMPEGDDrc() {
     IA_ERRORCODE err_code = IA_NO_ERROR;
     int i_effect_type;
     int i_loud_norm;
     int i_target_loudness;
     unsigned int i_sbr_mode;
-    int n_mems;
     int i;
+    int ui_proc_mem_tabs_size = 0;
+    pVOID pv_alloc_ptr = NULL;
 
 #ifdef ENABLE_MPEG_D_DRC
     {
@@ -1212,83 +1230,44 @@
                                     IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE, &i_sbr_mode);
         RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE");
 
+        /* Get memory info tables size */
+        err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEMTABS_SIZE, 0,
+                                  &ui_proc_mem_tabs_size);
+
+        RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEMTABS_SIZE");
+
+        pv_alloc_ptr = memalign(4, ui_proc_mem_tabs_size);
+
+        if (pv_alloc_ptr == NULL) {
+            ALOGE("Cannot create requested memory  %d", ui_proc_mem_tabs_size);
+            return IA_FATAL_ERROR;
+        }
+
+        memset(pv_alloc_ptr, 0, ui_proc_mem_tabs_size);
+
+        mMemoryVec.push(pv_alloc_ptr);
+
+        /* Set pointer for process memory tables */
+        err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEMTABS_PTR, 0,
+                                  pv_alloc_ptr);
+
+        RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEMTABS_PTR");
+
         err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
                                   IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS, NULL);
 
         RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS");
 
-        for (i = 0; i < (WORD32)2; i++) {
-            WORD32 ui_size, ui_alignment, ui_type;
-            pVOID pv_alloc_ptr;
+        /* Free any memory that is allocated for MPEG D Drc so far */
+        deInitMPEGDDDrc();
 
-            /* Get memory size */
-            err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_SIZE, i, &ui_size);
-
-            RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_SIZE");
-
-            /* Get memory alignment */
-            err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_ALIGNMENT, i,
-                                      &ui_alignment);
-
-            RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_ALIGNMENT");
-
-            /* Get memory type */
-            err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_TYPE, i, &ui_type);
-            RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_TYPE");
-            if (mMallocCount == MAX_MEM_ALLOCS) {
-                ALOGE("mMemoryArray is full");
-                return IA_FATAL_ERROR;
-            }
-
-            mMemoryArray[mMallocCount] = memalign(4, ui_size);
-            if (mMemoryArray[mMallocCount] == NULL) {
-                ALOGE(" Cannot create requested memory  %d", ui_size);
-                return IA_FATAL_ERROR;
-            }
-            pv_alloc_ptr = (pVOID)((WORD8*)mMemoryArray[mMallocCount]);
-            mMallocCount++;
-
-            /* Set the buffer pointer */
-            err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, i, pv_alloc_ptr);
-
-            RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
+        err_code = initMPEGDDDrc();
+        if (err_code != IA_NO_ERROR) {
+            ALOGE("initMPEGDDDrc failed with error %d", err_code);
+            deInitMPEGDDDrc();
+            return err_code;
         }
-        {
-            WORD32 ui_size;
-            ui_size = 8192 * 2;
-            if (mMallocCount == MAX_MEM_ALLOCS) {
-                ALOGE("mMemoryArray is full");
-                return IA_FATAL_ERROR;
-            }
 
-            mMemoryArray[mMallocCount] = memalign(4, ui_size);
-            if (mMemoryArray[mMallocCount] == NULL) {
-                ALOGE(" Cannot create requested memory  %d", ui_size);
-                return IA_FATAL_ERROR;
-            }
-
-            mDrcInBuf = (int8_t*)mMemoryArray[mMallocCount];
-            mMallocCount++;
-            err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, 2,
-                                      /*mOutputBuffer*/ mDrcInBuf);
-            RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
-
-            if (mMallocCount == MAX_MEM_ALLOCS) {
-                ALOGE("mMemoryArray is full");
-                return IA_FATAL_ERROR;
-            }
-            mMemoryArray[mMallocCount] = memalign(4, ui_size);
-            if (mMemoryArray[mMallocCount] == NULL) {
-                ALOGE(" Cannot create requested memory  %d", ui_size);
-                return IA_FATAL_ERROR;
-            }
-
-            mDrcOutBuf = (int8_t*)mMemoryArray[mMallocCount];
-            mMallocCount++;
-            err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, 3,
-                                      /*mOutputBuffer*/ mDrcOutBuf);
-            RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
-        }
         /* DRC buffers
             buf[0] - contains extension element pay load loudness related
             buf[1] - contains extension element pay load*/
@@ -1423,10 +1402,10 @@
     }
 #endif
 
-    return err_code;
+    return IA_NO_ERROR;
 }
-int SoftXAAC::decodeXAACStream(uint8_t* inBuffer, uint32_t inBufferLength, int32_t* bytesConsumed,
-                               int32_t* outBytes) {
+IA_ERRORCODE SoftXAAC::decodeXAACStream(uint8_t* inBuffer, uint32_t inBufferLength,
+                                        int32_t* bytesConsumed, int32_t* outBytes) {
     if (mInputBufferSize < inBufferLength) {
         ALOGE("Cannot config AAC, input buffer size %d < inBufferLength %d", mInputBufferSize,
               inBufferLength);
@@ -1516,24 +1495,33 @@
         memcpy(mOutputBuffer, mDrcOutBuf, *outBytes);
     }
 #endif
-    return err_code;
+    return IA_NO_ERROR;
 }
 
-int SoftXAAC::deInitXAACDecoder() {
+IA_ERRORCODE SoftXAAC::deInitXAACDecoder() {
     ALOGI("deInitXAACDecoder");
 
     /* Tell that the input is over in this buffer */
     IA_ERRORCODE err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INPUT_OVER, 0, NULL);
-    RETURN_IF_FATAL(err_code, "IA_API_CMD_INPUT_OVER");
 
-    for (int i = 0; i < mMallocCount; i++) {
-        if (mMemoryArray[i]) free(mMemoryArray[i]);
+    /* Irrespective of error returned in IA_API_CMD_INPUT_OVER, free allocated memory */
+    for (void* buf : mMemoryVec) {
+        free(buf);
     }
-    mMallocCount = 0;
-
+    mMemoryVec.clear();
     return err_code;
 }
 
+IA_ERRORCODE SoftXAAC::deInitMPEGDDDrc() {
+    ALOGI("deInitMPEGDDDrc");
+
+    for (void* buf : mDrcMemoryVec) {
+        free(buf);
+    }
+    mDrcMemoryVec.clear();
+    return IA_NO_ERROR;
+}
+
 IA_ERRORCODE SoftXAAC::getXAACStreamInfo() {
     IA_ERRORCODE err_code = IA_NO_ERROR;
 
@@ -1546,11 +1534,19 @@
     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS, &mNumChannels);
     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS");
+    if (mNumChannels > MAX_CHANNEL_COUNT) {
+        ALOGE(" No of channels are more than max channels\n");
+        return IA_FATAL_ERROR;
+    }
 
     /* PCM word size */
     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ, &mPcmWdSz);
     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ");
+    if ((mPcmWdSz / 8) != 2) {
+        ALOGE("Invalid Number of bytes per sample: %d, Expected is 2", mPcmWdSz);
+        return IA_FATAL_ERROR;
+    }
 
     /* channel mask to tell the arrangement of channels in bit stream */
     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
diff --git a/media/libstagefright/codecs/xaacdec/SoftXAAC.h b/media/libstagefright/codecs/xaacdec/SoftXAAC.h
index 6176082..a62a797 100644
--- a/media/libstagefright/codecs/xaacdec/SoftXAAC.h
+++ b/media/libstagefright/codecs/xaacdec/SoftXAAC.h
@@ -33,8 +33,6 @@
 #include "impd_apicmd_standards.h"
 #include "impd_drc_config_params.h"
 
-#define MAX_MEM_ALLOCS 100
-
 extern "C" IA_ERRORCODE ixheaacd_dec_api(pVOID p_ia_module_obj, WORD32 i_cmd, WORD32 i_idx,
                                          pVOID pv_value);
 extern "C" IA_ERRORCODE ia_drc_dec_api(pVOID p_ia_module_obj, WORD32 i_cmd, WORD32 i_idx,
@@ -80,18 +78,19 @@
     enum { NONE, AWAITING_DISABLED, AWAITING_ENABLED } mOutputPortSettingsChange;
 
     void initPorts();
-    status_t initDecoder();
+    IA_ERRORCODE initDecoder();
     bool isConfigured() const;
-    int drainDecoder();
-    int initXAACDecoder();
-    int deInitXAACDecoder();
+    IA_ERRORCODE drainDecoder();
+    IA_ERRORCODE initXAACDecoder();
+    IA_ERRORCODE deInitXAACDecoder();
+    IA_ERRORCODE initMPEGDDDrc();
+    IA_ERRORCODE deInitMPEGDDDrc();
+    IA_ERRORCODE configXAACDecoder(uint8_t* inBuffer, uint32_t inBufferLength);
+    IA_ERRORCODE configMPEGDDrc();
+    IA_ERRORCODE decodeXAACStream(uint8_t* inBuffer, uint32_t inBufferLength,
+                                  int32_t* bytesConsumed, int32_t* outBytes);
 
-    int configXAACDecoder(uint8_t* inBuffer, uint32_t inBufferLength);
-    int configMPEGDDrc();
-    int decodeXAACStream(uint8_t* inBuffer, uint32_t inBufferLength, int32_t* bytesConsumed,
-                         int32_t* outBytes);
-
-    int configflushDecode();
+    IA_ERRORCODE configflushDecode();
     IA_ERRORCODE getXAACStreamInfo();
     IA_ERRORCODE setXAACDRCInfo(int32_t drcCut, int32_t drcBoost, int32_t drcRefLevel,
                                 int32_t drcHeavyCompression
@@ -120,9 +119,8 @@
     int8_t* mDrcOutBuf;
     int32_t mMpegDDRCPresent;
     int32_t mDRCFlag;
-
-    void* mMemoryArray[MAX_MEM_ALLOCS];
-    int32_t mMallocCount;
+    Vector<void*> mMemoryVec;
+    Vector<void*> mDrcMemoryVec;
 
     DISALLOW_EVIL_CONSTRUCTORS(SoftXAAC);
 };
diff --git a/media/libstagefright/colorconversion/Android.bp b/media/libstagefright/colorconversion/Android.bp
index 16e9ded..ba57497 100644
--- a/media/libstagefright/colorconversion/Android.bp
+++ b/media/libstagefright/colorconversion/Android.bp
@@ -24,8 +24,5 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 }
diff --git a/media/libstagefright/colorconversion/ColorConverter.cpp b/media/libstagefright/colorconversion/ColorConverter.cpp
index 05f4104..d685321 100644
--- a/media/libstagefright/colorconversion/ColorConverter.cpp
+++ b/media/libstagefright/colorconversion/ColorConverter.cpp
@@ -16,14 +16,18 @@
 
 //#define LOG_NDEBUG 0
 #define LOG_TAG "ColorConverter"
+#include <android-base/macros.h>
 #include <utils/Log.h>
 
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/foundation/ColorUtils.h>
 #include <media/stagefright/ColorConverter.h>
 #include <media/stagefright/MediaErrors.h>
 
 #include "libyuv/convert_from.h"
+#include "libyuv/convert_argb.h"
+#include "libyuv/planar_functions.h"
 #include "libyuv/video_common.h"
 #include <functional>
 #include <sys/time.h>
@@ -44,10 +48,28 @@
 
 namespace android {
 
+static bool isRGB(OMX_COLOR_FORMATTYPE colorFormat) {
+    return colorFormat == OMX_COLOR_Format16bitRGB565
+            || colorFormat == OMX_COLOR_Format32BitRGBA8888
+            || colorFormat == OMX_COLOR_Format32bitBGRA8888;
+}
+
+bool ColorConverter::ColorSpace::isBt709() {
+    return (mStandard == ColorUtils::kColorStandardBT709);
+}
+
+
+bool ColorConverter::ColorSpace::isJpeg() {
+    return ((mStandard == ColorUtils::kColorStandardBT601_625)
+            || (mStandard == ColorUtils::kColorStandardBT601_525))
+            && (mRange == ColorUtils::kColorRangeFull);
+}
+
 ColorConverter::ColorConverter(
         OMX_COLOR_FORMATTYPE from, OMX_COLOR_FORMATTYPE to)
     : mSrcFormat(from),
       mDstFormat(to),
+      mSrcColorSpace({0, 0, 0}),
       mClip(NULL) {
 }
 
@@ -62,7 +84,7 @@
             if (mDstFormat == OMX_COLOR_FormatYUV444Y410) {
                 return true;
             }
-            // fall-thru
+            FALLTHROUGH_INTENDED;
         case OMX_COLOR_FormatYUV420Planar:
             return mDstFormat == OMX_COLOR_Format16bitRGB565
                     || mDstFormat == OMX_COLOR_Format32BitRGBA8888
@@ -70,24 +92,46 @@
 
         case OMX_COLOR_FormatCbYCrY:
         case OMX_QCOM_COLOR_FormatYVU420SemiPlanar:
-        case OMX_COLOR_FormatYUV420SemiPlanar:
         case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
             return mDstFormat == OMX_COLOR_Format16bitRGB565;
 
+        case OMX_COLOR_FormatYUV420SemiPlanar:
+#ifdef USE_LIBYUV
+            return mDstFormat == OMX_COLOR_Format16bitRGB565
+                    || mDstFormat == OMX_COLOR_Format32BitRGBA8888;
+#else
+            return mDstFormat == OMX_COLOR_Format16bitRGB565;
+#endif
+
         default:
             return false;
     }
 }
 
 bool ColorConverter::isDstRGB() const {
-    return mDstFormat == OMX_COLOR_Format16bitRGB565
-            || mDstFormat == OMX_COLOR_Format32BitRGBA8888
-            || mDstFormat == OMX_COLOR_Format32bitBGRA8888;
+    return isRGB(mDstFormat);
 }
 
+void ColorConverter::setSrcColorSpace(
+        uint32_t standard, uint32_t range, uint32_t transfer) {
+    if (isRGB(mSrcFormat)) {
+        ALOGW("Can't set color space on RGB source");
+        return;
+    }
+    mSrcColorSpace.mStandard = standard;
+    mSrcColorSpace.mRange = range;
+    mSrcColorSpace.mTransfer = transfer;
+}
+
+/*
+ * If stride is non-zero, client's stride will be used. For planar
+ * or semi-planar YUV formats, stride must be even numbers.
+ * If stride is zero, it will be calculated based on width and bpp
+ * of the format, assuming no padding on the right edge.
+ */
 ColorConverter::BitmapParams::BitmapParams(
         void *bits,
-        size_t width, size_t height,
+        size_t width, size_t height, size_t stride,
         size_t cropLeft, size_t cropTop,
         size_t cropRight, size_t cropBottom,
         OMX_COLOR_FORMATTYPE colorFromat)
@@ -101,6 +145,8 @@
       mCropBottom(cropBottom) {
     switch(mColorFormat) {
     case OMX_COLOR_Format16bitRGB565:
+    case OMX_COLOR_FormatYUV420Planar16:
+    case OMX_COLOR_FormatCbYCrY:
         mBpp = 2;
         mStride = 2 * mWidth;
         break;
@@ -112,13 +158,7 @@
         mStride = 4 * mWidth;
         break;
 
-    case OMX_COLOR_FormatYUV420Planar16:
-        mBpp = 2;
-        mStride = 2 * mWidth;
-        break;
-
     case OMX_COLOR_FormatYUV420Planar:
-    case OMX_COLOR_FormatCbYCrY:
     case OMX_QCOM_COLOR_FormatYVU420SemiPlanar:
     case OMX_COLOR_FormatYUV420SemiPlanar:
     case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
@@ -132,6 +172,10 @@
         mStride = mWidth;
         break;
     }
+    // use client's stride if it's specified.
+    if (stride != 0) {
+        mStride = stride;
+    }
 }
 
 size_t ColorConverter::BitmapParams::cropWidth() const {
@@ -144,21 +188,21 @@
 
 status_t ColorConverter::convert(
         const void *srcBits,
-        size_t srcWidth, size_t srcHeight,
+        size_t srcWidth, size_t srcHeight, size_t srcStride,
         size_t srcCropLeft, size_t srcCropTop,
         size_t srcCropRight, size_t srcCropBottom,
         void *dstBits,
-        size_t dstWidth, size_t dstHeight,
+        size_t dstWidth, size_t dstHeight, size_t dstStride,
         size_t dstCropLeft, size_t dstCropTop,
         size_t dstCropRight, size_t dstCropBottom) {
     BitmapParams src(
             const_cast<void *>(srcBits),
-            srcWidth, srcHeight,
+            srcWidth, srcHeight, srcStride,
             srcCropLeft, srcCropTop, srcCropRight, srcCropBottom, mSrcFormat);
 
     BitmapParams dst(
             dstBits,
-            dstWidth, dstHeight,
+            dstWidth, dstHeight, dstStride,
             dstCropLeft, dstCropTop, dstCropRight, dstCropBottom, mDstFormat);
 
     if (!((src.mCropLeft & 1) == 0
@@ -200,7 +244,11 @@
             break;
 
         case OMX_COLOR_FormatYUV420SemiPlanar:
+#ifdef USE_LIBYUV
+            err = convertYUV420SemiPlanarUseLibYUV(src, dst);
+#else
             err = convertYUV420SemiPlanar(src, dst);
+#endif
             break;
 
         case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
@@ -275,6 +323,13 @@
     return OK;
 }
 
+#define DECLARE_YUV2RGBFUNC(func, rgb) int (*func)(     \
+        const uint8*, int, const uint8*, int,           \
+        const uint8*, int, uint8*, int, int, int)       \
+        = mSrcColorSpace.isBt709() ? libyuv::H420To##rgb \
+        : mSrcColorSpace.isJpeg() ? libyuv::J420To##rgb  \
+        : libyuv::I420To##rgb
+
 status_t ColorConverter::convertYUV420PlanarUseLibYUV(
         const BitmapParams &src, const BitmapParams &dst) {
     uint8_t *dst_ptr = (uint8_t *)dst.mBits
@@ -292,19 +347,28 @@
 
     switch (mDstFormat) {
     case OMX_COLOR_Format16bitRGB565:
-        libyuv::I420ToRGB565(src_y, src.mStride, src_u, src.mStride / 2, src_v, src.mStride / 2,
+    {
+        DECLARE_YUV2RGBFUNC(func, RGB565);
+        (*func)(src_y, src.mStride, src_u, src.mStride / 2, src_v, src.mStride / 2,
                 (uint8 *)dst_ptr, dst.mStride, src.cropWidth(), src.cropHeight());
         break;
+    }
 
     case OMX_COLOR_Format32BitRGBA8888:
-        libyuv::ConvertFromI420(src_y, src.mStride, src_u, src.mStride / 2, src_v, src.mStride / 2,
-                (uint8 *)dst_ptr, dst.mStride, src.cropWidth(), src.cropHeight(), libyuv::FOURCC_ABGR);
+    {
+        DECLARE_YUV2RGBFUNC(func, ABGR);
+        (*func)(src_y, src.mStride, src_u, src.mStride / 2, src_v, src.mStride / 2,
+                (uint8 *)dst_ptr, dst.mStride, src.cropWidth(), src.cropHeight());
         break;
+    }
 
     case OMX_COLOR_Format32bitBGRA8888:
-        libyuv::ConvertFromI420(src_y, src.mStride, src_u, src.mStride / 2, src_v, src.mStride / 2,
-                (uint8 *)dst_ptr, dst.mStride, src.cropWidth(), src.cropHeight(), libyuv::FOURCC_ARGB);
+    {
+        DECLARE_YUV2RGBFUNC(func, ARGB);
+        (*func)(src_y, src.mStride, src_u, src.mStride / 2, src_v, src.mStride / 2,
+                (uint8 *)dst_ptr, dst.mStride, src.cropWidth(), src.cropHeight());
         break;
+    }
 
     default:
         return ERROR_UNSUPPORTED;
@@ -313,6 +377,41 @@
     return OK;
 }
 
+status_t ColorConverter::convertYUV420SemiPlanarUseLibYUV(
+        const BitmapParams &src, const BitmapParams &dst) {
+    uint8_t *dst_ptr = (uint8_t *)dst.mBits
+        + dst.mCropTop * dst.mStride + dst.mCropLeft * dst.mBpp;
+
+    const uint8_t *src_y =
+        (const uint8_t *)src.mBits + src.mCropTop * src.mStride + src.mCropLeft;
+
+    const uint8_t *src_u =
+        (const uint8_t *)src.mBits + src.mStride * src.mHeight
+        + (src.mCropTop / 2) * src.mStride + src.mCropLeft;
+
+    switch (mDstFormat) {
+    case OMX_COLOR_Format16bitRGB565:
+        libyuv::NV12ToRGB565(src_y, src.mStride, src_u, src.mStride, (uint8 *)dst_ptr,
+                dst.mStride, src.cropWidth(), src.cropHeight());
+        break;
+
+    case OMX_COLOR_Format32bitBGRA8888:
+        libyuv::NV12ToARGB(src_y, src.mStride, src_u, src.mStride, (uint8 *)dst_ptr,
+                dst.mStride, src.cropWidth(), src.cropHeight());
+        break;
+
+    case OMX_COLOR_Format32BitRGBA8888:
+        libyuv::NV12ToABGR(src_y, src.mStride, src_u, src.mStride, (uint8 *)dst_ptr,
+                dst.mStride, src.cropWidth(), src.cropHeight());
+        break;
+
+    default:
+        return ERROR_UNSUPPORTED;
+   }
+
+   return OK;
+}
+
 std::function<void (void *, void *, void *, size_t,
                     signed *, signed *, signed *, signed *)>
 getReadFromSrc(OMX_COLOR_FORMATTYPE srcFormat) {
@@ -792,15 +891,15 @@
 
     uint8_t *kAdjustedClip = initClip();
 
-    uint16_t *dst_ptr = (uint16_t *)dst.mBits
-        + dst.mCropTop * dst.mWidth + dst.mCropLeft;
+    uint16_t *dst_ptr = (uint16_t *)((uint8_t *)
+            dst.mBits + dst.mCropTop * dst.mStride + dst.mCropLeft * dst.mBpp);
 
     const uint8_t *src_y =
-        (const uint8_t *)src.mBits + src.mCropTop * src.mWidth + src.mCropLeft;
+        (const uint8_t *)src.mBits + src.mCropTop * src.mStride + src.mCropLeft;
 
     const uint8_t *src_u =
-        (const uint8_t *)src_y + src.mWidth * src.mHeight
-        + src.mCropTop * src.mWidth + src.mCropLeft;
+        (const uint8_t *)src.mBits + src.mHeight * src.mStride +
+        (src.mCropTop / 2) * src.mStride + src.mCropLeft;
 
     for (size_t y = 0; y < src.cropHeight(); ++y) {
         for (size_t x = 0; x < src.cropWidth(); x += 2) {
@@ -842,13 +941,13 @@
             }
         }
 
-        src_y += src.mWidth;
+        src_y += src.mStride;
 
         if (y & 1) {
-            src_u += src.mWidth;
+            src_u += src.mStride;
         }
 
-        dst_ptr += dst.mWidth;
+        dst_ptr = (uint16_t*)((uint8_t*)dst_ptr + dst.mStride);
     }
 
     return OK;
diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
index 657a05b..359df3d 100644
--- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp
+++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
@@ -44,6 +44,7 @@
       mNativeWindow(nativeWindow),
       mWidth(0),
       mHeight(0),
+      mStride(0),
       mCropLeft(0),
       mCropTop(0),
       mCropRight(0),
@@ -67,9 +68,10 @@
     int32_t colorFormatNew;
     CHECK(format->findInt32("color-format", &colorFormatNew));
 
-    int32_t widthNew, heightNew;
-    CHECK(format->findInt32("stride", &widthNew));
+    int32_t widthNew, heightNew, strideNew;
+    CHECK(format->findInt32("width", &widthNew));
     CHECK(format->findInt32("slice-height", &heightNew));
+    CHECK(format->findInt32("stride", &strideNew));
 
     int32_t cropLeftNew, cropTopNew, cropRightNew, cropBottomNew;
     if (!format->findRect(
@@ -106,6 +108,7 @@
     mColorFormat = static_cast<OMX_COLOR_FORMATTYPE>(colorFormatNew);
     mWidth = widthNew;
     mHeight = heightNew;
+    mStride = strideNew;
     mCropLeft = cropLeftNew;
     mCropTop = cropTopNew;
     mCropRight = cropRightNew;
@@ -276,20 +279,15 @@
     if (mConverter) {
         mConverter->convert(
                 data,
-                mWidth, mHeight,
+                mWidth, mHeight, mStride,
                 mCropLeft, mCropTop, mCropRight, mCropBottom,
                 dst,
-                buf->stride, buf->height,
+                buf->stride, buf->height, 0,
                 0, 0, mCropWidth - 1, mCropHeight - 1);
     } else if (mColorFormat == OMX_COLOR_FormatYUV420Planar) {
-        const uint8_t *src_y = (const uint8_t *)data;
-        const uint8_t *src_u =
-                (const uint8_t *)data + mWidth * mHeight;
-        const uint8_t *src_v = src_u + (mWidth / 2 * mHeight / 2);
-
-        src_y +=mCropLeft + mCropTop * mWidth;
-        src_u +=(mCropLeft + mCropTop * mWidth / 2)/2;
-        src_v +=(mCropLeft + mCropTop * mWidth / 2)/2;
+        const uint8_t *src_y = (const uint8_t *)data + mCropTop * mStride + mCropLeft;
+        const uint8_t *src_u = (const uint8_t *)data + mStride * mHeight + mCropTop * mStride / 4;
+        const uint8_t *src_v = (const uint8_t *)src_u + mStride * mHeight / 4;
 
         uint8_t *dst_y = (uint8_t *)dst;
         size_t dst_y_size = buf->stride * buf->height;
@@ -305,7 +303,7 @@
         for (int y = 0; y < mCropHeight; ++y) {
             memcpy(dst_y, src_y, mCropWidth);
 
-            src_y += mWidth;
+            src_y += mStride;
             dst_y += buf->stride;
         }
 
@@ -313,19 +311,15 @@
             memcpy(dst_u, src_u, (mCropWidth + 1) / 2);
             memcpy(dst_v, src_v, (mCropWidth + 1) / 2);
 
-            src_u += mWidth / 2;
-            src_v += mWidth / 2;
+            src_u += mStride / 2;
+            src_v += mStride / 2;
             dst_u += dst_c_stride;
             dst_v += dst_c_stride;
         }
     } else if (mColorFormat == OMX_COLOR_FormatYUV420Planar16) {
-        const uint16_t *src_y = (const uint16_t *)data;
-        const uint16_t *src_u = (const uint16_t *)data + mWidth * mHeight;
-        const uint16_t *src_v = src_u + (mWidth / 2 * mHeight / 2);
-
-        src_y += mCropLeft + mCropTop * mWidth;
-        src_u += (mCropLeft + mCropTop * mWidth / 2) / 2;
-        src_v += (mCropLeft + mCropTop * mWidth / 2) / 2;
+        const uint8_t *src_y = (const uint8_t *)data + mCropTop * mStride + mCropLeft * 2;
+        const uint8_t *src_u = (const uint8_t *)data + mStride * mHeight + mCropTop * mStride / 4;
+        const uint8_t *src_v = (const uint8_t *)src_u + mStride * mHeight / 4;
 
         uint8_t *dst_y = (uint8_t *)dst;
         size_t dst_y_size = buf->stride * buf->height;
@@ -340,21 +334,21 @@
 
         for (int y = 0; y < mCropHeight; ++y) {
             for (int x = 0; x < mCropWidth; ++x) {
-                dst_y[x] = (uint8_t)(src_y[x] >> 2);
+                dst_y[x] = (uint8_t)(((uint16_t *)src_y)[x] >> 2);
             }
 
-            src_y += mWidth;
+            src_y += mStride;
             dst_y += buf->stride;
         }
 
         for (int y = 0; y < (mCropHeight + 1) / 2; ++y) {
             for (int x = 0; x < (mCropWidth + 1) / 2; ++x) {
-                dst_u[x] = (uint8_t)(src_u[x] >> 2);
-                dst_v[x] = (uint8_t)(src_v[x] >> 2);
+                dst_u[x] = (uint8_t)(((uint16_t *)src_u)[x] >> 2);
+                dst_v[x] = (uint8_t)(((uint16_t *)src_v)[x] >> 2);
             }
 
-            src_u += mWidth / 2;
-            src_v += mWidth / 2;
+            src_u += mStride / 2;
+            src_v += mStride / 2;
             dst_u += dst_c_stride;
             dst_v += dst_c_stride;
         }
diff --git a/media/libstagefright/data/Android.bp b/media/libstagefright/data/Android.bp
new file mode 100644
index 0000000..616b4b3
--- /dev/null
+++ b/media/libstagefright/data/Android.bp
@@ -0,0 +1,6 @@
+prebuilt_etc {
+    name: "mediaswcodec.xml",
+    src: "media_codecs_sw.xml",
+    filename: "media_codecs.xml",
+    installable: false,
+}
diff --git a/media/libstagefright/data/media_codecs_google_audio.xml b/media/libstagefright/data/media_codecs_google_audio.xml
index 632088a..8899adc 100644
--- a/media/libstagefright/data/media_codecs_google_audio.xml
+++ b/media/libstagefright/data/media_codecs_google_audio.xml
@@ -58,7 +58,7 @@
         </MediaCodec>
         <MediaCodec name="OMX.google.raw.decoder" type="audio/raw">
             <Limit name="channel-count" max="8" />
-            <Limit name="sample-rate" ranges="8000-96000" />
+            <Limit name="sample-rate" ranges="8000-192000" />
             <Limit name="bitrate" range="1-10000000" />
         </MediaCodec>
         <MediaCodec name="OMX.google.flac.decoder" type="audio/flac">
diff --git a/media/libstagefright/data/media_codecs_google_c2_audio.xml b/media/libstagefright/data/media_codecs_google_c2_audio.xml
index 0b554a2..509f7a9 100644
--- a/media/libstagefright/data/media_codecs_google_c2_audio.xml
+++ b/media/libstagefright/data/media_codecs_google_c2_audio.xml
@@ -17,51 +17,61 @@
 <Included>
     <Decoders>
         <MediaCodec name="c2.android.mp3.decoder" type="audio/mpeg">
+            <Alias name="OMX.google.mp3.decoder" />
             <Limit name="channel-count" max="2" />
             <Limit name="sample-rate" ranges="8000,11025,12000,16000,22050,24000,32000,44100,48000" />
             <Limit name="bitrate" range="8000-320000" />
         </MediaCodec>
         <MediaCodec name="c2.android.amrnb.decoder" type="audio/3gpp">
+            <Alias name="OMX.google.amrnb.decoder" />
             <Limit name="channel-count" max="1" />
             <Limit name="sample-rate" ranges="8000" />
             <Limit name="bitrate" range="4750-12200" />
         </MediaCodec>
         <MediaCodec name="c2.android.amrwb.decoder" type="audio/amr-wb">
+            <Alias name="OMX.google.amrwb.decoder" />
             <Limit name="channel-count" max="1" />
             <Limit name="sample-rate" ranges="16000" />
             <Limit name="bitrate" range="6600-23850" />
         </MediaCodec>
         <MediaCodec name="c2.android.aac.decoder" type="audio/mp4a-latm">
+            <Alias name="OMX.google.aac.decoder" />
             <Limit name="channel-count" max="8" />
             <Limit name="sample-rate" ranges="7350,8000,11025,12000,16000,22050,24000,32000,44100,48000" />
             <Limit name="bitrate" range="8000-960000" />
         </MediaCodec>
         <MediaCodec name="c2.android.g711.alaw.decoder" type="audio/g711-alaw">
+            <Alias name="OMX.google.g711.alaw.decoder" />
             <Limit name="channel-count" max="1" />
             <Limit name="sample-rate" ranges="8000-48000" />
             <Limit name="bitrate" range="64000" />
         </MediaCodec>
         <MediaCodec name="c2.android.g711.mlaw.decoder" type="audio/g711-mlaw">
+            <Alias name="OMX.google.g711.mlaw.decoder" />
             <Limit name="channel-count" max="1" />
             <Limit name="sample-rate" ranges="8000-48000" />
             <Limit name="bitrate" range="64000" />
         </MediaCodec>
         <MediaCodec name="c2.android.vorbis.decoder" type="audio/vorbis">
+            <Alias name="OMX.google.vorbis.decoder" />
             <Limit name="channel-count" max="8" />
             <Limit name="sample-rate" ranges="8000-96000" />
             <Limit name="bitrate" range="32000-500000" />
         </MediaCodec>
         <MediaCodec name="c2.android.opus.decoder" type="audio/opus">
+            <Alias name="OMX.google.opus.decoder" />
             <Limit name="channel-count" max="8" />
             <Limit name="sample-rate" ranges="48000" />
             <Limit name="bitrate" range="6000-510000" />
         </MediaCodec>
         <MediaCodec name="c2.android.raw.decoder" type="audio/raw">
+            <Alias name="OMX.google.raw.decoder" />
             <Limit name="channel-count" max="8" />
-            <Limit name="sample-rate" ranges="8000-96000" />
+            <Limit name="sample-rate" ranges="8000-192000" />
             <Limit name="bitrate" range="1-10000000" />
         </MediaCodec>
         <MediaCodec name="c2.android.flac.decoder" type="audio/flac">
+            <Alias name="OMX.google.flac.decoder" />
             <Limit name="channel-count" max="8" />
             <Limit name="sample-rate" ranges="1-655350" />
             <Limit name="bitrate" range="1-21000000" />
@@ -69,29 +79,40 @@
     </Decoders>
     <Encoders>
         <MediaCodec name="c2.android.aac.encoder" type="audio/mp4a-latm">
+            <Alias name="OMX.google.aac.encoder" />
             <Limit name="channel-count" max="6" />
             <Limit name="sample-rate" ranges="8000,11025,12000,16000,22050,24000,32000,44100,48000" />
             <!-- also may support 64000, 88200  and 96000 Hz -->
             <Limit name="bitrate" range="8000-960000" />
         </MediaCodec>
         <MediaCodec name="c2.android.amrnb.encoder" type="audio/3gpp">
+            <Alias name="OMX.google.amrnb.encoder" />
             <Limit name="channel-count" max="1" />
             <Limit name="sample-rate" ranges="8000" />
             <Limit name="bitrate" range="4750-12200" />
             <Feature name="bitrate-modes" value="CBR" />
         </MediaCodec>
         <MediaCodec name="c2.android.amrwb.encoder" type="audio/amr-wb">
+            <Alias name="OMX.google.amrwb.encoder" />
             <Limit name="channel-count" max="1" />
             <Limit name="sample-rate" ranges="16000" />
             <Limit name="bitrate" range="6600-23850" />
             <Feature name="bitrate-modes" value="CBR" />
         </MediaCodec>
         <MediaCodec name="c2.android.flac.encoder" type="audio/flac">
+            <Alias name="OMX.google.flac.encoder" />
             <Limit name="channel-count" max="2" />
             <Limit name="sample-rate" ranges="1-655350" />
             <Limit name="bitrate" range="1-21000000" />
             <Limit name="complexity" range="0-8"  default="5" />
             <Feature name="bitrate-modes" value="CQ" />
         </MediaCodec>
+        <MediaCodec name="c2.android.opus.encoder" type="audio/opus">
+            <Limit name="channel-count" max="2" />
+            <Limit name="sample-rate" ranges="8000,12000,16000,24000,48000" />
+            <Limit name="bitrate" range="500-512000" />
+            <Limit name="complexity" range="0-10"  default="5" />
+            <Feature name="bitrate-modes" value="CBR" />
+        </MediaCodec>
     </Encoders>
 </Included>
diff --git a/media/libstagefright/data/media_codecs_google_c2_telephony.xml b/media/libstagefright/data/media_codecs_google_c2_telephony.xml
new file mode 100644
index 0000000..950b092
--- /dev/null
+++ b/media/libstagefright/data/media_codecs_google_c2_telephony.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<Included>
+    <Decoders>
+        <MediaCodec name="c2.android.gsm.decoder" type="audio/gsm">
+            <Alias name="OMX.google.gsm.decoder" />
+            <Limit name="channel-count" max="1" />
+            <Limit name="sample-rate" ranges="8000" />
+            <Limit name="bitrate" range="13000" />
+        </MediaCodec>
+    </Decoders>
+</Included>
diff --git a/media/libstagefright/data/media_codecs_google_c2_tv.xml b/media/libstagefright/data/media_codecs_google_c2_tv.xml
new file mode 100644
index 0000000..1b00dc9
--- /dev/null
+++ b/media/libstagefright/data/media_codecs_google_c2_tv.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<Included>
+    <Decoders>
+        <MediaCodec name="c2.android.mpeg2.decoder" type="video/mpeg2">
+            <Alias name="OMX.google.mpeg2.decoder" />
+            <!-- profiles and levels:  ProfileMain : LevelHL -->
+            <Limit name="size" min="16x16" max="1920x1088" />
+            <Limit name="alignment" value="2x2" />
+            <Limit name="block-size" value="16x16" />
+            <Limit name="blocks-per-second" range="1-244800" />
+            <Limit name="bitrate" range="1-20000000" />
+            <Feature name="adaptive-playback" />
+        </MediaCodec>
+    </Decoders>
+</Included>
diff --git a/media/libstagefright/data/media_codecs_google_c2_video.xml b/media/libstagefright/data/media_codecs_google_c2_video.xml
index adb45b3..04041eb 100644
--- a/media/libstagefright/data/media_codecs_google_c2_video.xml
+++ b/media/libstagefright/data/media_codecs_google_c2_video.xml
@@ -17,6 +17,7 @@
 <Included>
     <Decoders>
         <MediaCodec name="c2.android.mpeg4.decoder" type="video/mp4v-es">
+            <Alias name="OMX.google.mpeg4.decoder" />
             <!-- profiles and levels:  ProfileSimple : Level3 -->
             <Limit name="size" min="2x2" max="352x288" />
             <Limit name="alignment" value="2x2" />
@@ -26,6 +27,7 @@
             <Feature name="adaptive-playback" />
         </MediaCodec>
         <MediaCodec name="c2.android.h263.decoder" type="video/3gpp">
+            <Alias name="OMX.google.h263.decoder" />
             <!-- profiles and levels:  ProfileBaseline : Level30, ProfileBaseline : Level45
                     ProfileISWV2 : Level30, ProfileISWV2 : Level45 -->
             <Limit name="size" min="2x2" max="352x288" />
@@ -34,6 +36,7 @@
             <Feature name="adaptive-playback" />
         </MediaCodec>
         <MediaCodec name="c2.android.avc.decoder" type="video/avc">
+            <Alias name="OMX.google.h264.decoder" />
             <!-- profiles and levels:  ProfileHigh : Level52 -->
             <Limit name="size" min="2x2" max="4080x4080" />
             <Limit name="alignment" value="2x2" />
@@ -44,6 +47,7 @@
             <Feature name="adaptive-playback" />
         </MediaCodec>
         <MediaCodec name="c2.android.hevc.decoder" type="video/hevc">
+            <Alias name="OMX.google.hevc.decoder" />
             <!-- profiles and levels:  ProfileMain : MainTierLevel51 -->
             <Limit name="size" min="2x2" max="4096x4096" />
             <Limit name="alignment" value="2x2" />
@@ -54,6 +58,7 @@
             <Feature name="adaptive-playback" />
         </MediaCodec>
         <MediaCodec name="c2.android.vp8.decoder" type="video/x-vnd.on2.vp8">
+            <Alias name="OMX.google.vp8.decoder" />
             <Limit name="size" min="2x2" max="2048x2048" />
             <Limit name="alignment" value="2x2" />
             <Limit name="block-size" value="16x16" />
@@ -63,6 +68,7 @@
             <Feature name="adaptive-playback" />
         </MediaCodec>
         <MediaCodec name="c2.android.vp9.decoder" type="video/x-vnd.on2.vp9">
+            <Alias name="OMX.google.vp9.decoder" />
             <Limit name="size" min="2x2" max="2048x2048" />
             <Limit name="alignment" value="2x2" />
             <Limit name="block-size" value="16x16" />
@@ -71,16 +77,27 @@
             <Limit name="bitrate" range="1-40000000" />
             <Feature name="adaptive-playback" />
         </MediaCodec>
+        <MediaCodec name="c2.android.av1.decoder" type="video/av01">
+            <Limit name="size" min="96x96" max="1920x1080" />
+            <Limit name="alignment" value="2x2" />
+            <Limit name="block-size" value="16x16" />
+            <Limit name="blocks-per-second" min="24" max="2073600" />
+            <Limit name="bitrate" range="1-120000000" />
+            <Limit name="frame-rate" range="1-60" />
+            <Feature name="adaptive-playback" />
+        </MediaCodec>
     </Decoders>
 
     <Encoders>
         <MediaCodec name="c2.android.h263.encoder" type="video/3gpp">
+            <Alias name="OMX.google.h263.encoder" />
             <!-- profiles and levels:  ProfileBaseline : Level45 -->
             <Limit name="size" min="176x144" max="176x144" />
             <Limit name="alignment" value="16x16" />
             <Limit name="bitrate" range="1-128000" />
         </MediaCodec>
         <MediaCodec name="c2.android.avc.encoder" type="video/avc">
+            <Alias name="OMX.google.h264.encoder" />
             <!-- profiles and levels:  ProfileBaseline : Level41 -->
             <Limit name="size" min="16x16" max="2048x2048" />
             <Limit name="alignment" value="2x2" />
@@ -90,7 +107,21 @@
             <Limit name="bitrate" range="1-12000000" />
             <Feature name="intra-refresh" />
         </MediaCodec>
+        <MediaCodec name="c2.android.hevc.encoder" type="video/hevc">
+            <!-- profiles and levels:  ProfileMain : MainTierLevel51 -->
+            <Limit name="size" min="2x2" max="512x512" />
+            <Limit name="alignment" value="2x2" />
+            <Limit name="block-size" value="8x8" />
+            <Limit name="block-count" range="1-4096" /> <!-- max 512x512 -->
+            <Limit name="blocks-per-second" range="1-122880" />
+            <Limit name="frame-rate" range="1-120" />
+            <Limit name="bitrate" range="1-10000000" />
+            <Limit name="complexity" range="0-10"  default="0" />
+            <Limit name="quality" range="0-100"  default="80" />
+            <Feature name="bitrate-modes" value="VBR,CBR,CQ" />
+        </MediaCodec>
         <MediaCodec name="c2.android.mpeg4.encoder" type="video/mp4v-es">
+            <Alias name="OMX.google.mpeg4.encoder" />
             <!-- profiles and levels:  ProfileCore : Level2 -->
             <Limit name="size" min="16x16" max="176x144" />
             <Limit name="alignment" value="16x16" />
@@ -99,6 +130,7 @@
             <Limit name="bitrate" range="1-64000" />
         </MediaCodec>
         <MediaCodec name="c2.android.vp8.encoder" type="video/x-vnd.on2.vp8">
+            <Alias name="OMX.google.vp8.encoder" />
             <!-- profiles and levels:  ProfileMain : Level_Version0-3 -->
             <Limit name="size" min="2x2" max="2048x2048" />
             <Limit name="alignment" value="2x2" />
@@ -109,6 +141,7 @@
             <Feature name="bitrate-modes" value="VBR,CBR" />
         </MediaCodec>
         <MediaCodec name="c2.android.vp9.encoder" type="video/x-vnd.on2.vp9">
+            <Alias name="OMX.google.vp9.encoder" />
             <!-- profiles and levels:  ProfileMain : Level_Version0-3 -->
             <Limit name="size" min="2x2" max="2048x2048" />
             <Limit name="alignment" value="2x2" />
diff --git a/media/libstagefright/data/media_codecs_sw.xml b/media/libstagefright/data/media_codecs_sw.xml
new file mode 100644
index 0000000..67d3f1a
--- /dev/null
+++ b/media/libstagefright/data/media_codecs_sw.xml
@@ -0,0 +1,322 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<MediaCodecs>
+    <Settings>
+        <!-- disable TV and telephony domains by default. These must be opted in by OEMs -->
+        <Domain name="telephony" enabled="false" />
+        <Domain name="tv" enabled="false" />
+        <Variant name="slow-cpu" enabled="false" />
+    </Settings>
+    <Decoders>
+        <MediaCodec name="c2.android.mp3.decoder" type="audio/mpeg">
+            <Alias name="OMX.google.mp3.decoder" />
+            <Limit name="channel-count" max="2" />
+            <Limit name="sample-rate" ranges="8000,11025,12000,16000,22050,24000,32000,44100,48000" />
+            <Limit name="bitrate" range="8000-320000" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.amrnb.decoder" type="audio/3gpp">
+            <Alias name="OMX.google.amrnb.decoder" />
+            <Limit name="channel-count" max="1" />
+            <Limit name="sample-rate" ranges="8000" />
+            <Limit name="bitrate" range="4750-12200" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.amrwb.decoder" type="audio/amr-wb">
+            <Alias name="OMX.google.amrwb.decoder" />
+            <Limit name="channel-count" max="1" />
+            <Limit name="sample-rate" ranges="16000" />
+            <Limit name="bitrate" range="6600-23850" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.aac.decoder" type="audio/mp4a-latm">
+            <Alias name="OMX.google.aac.decoder" />
+            <Limit name="channel-count" max="8" />
+            <Limit name="sample-rate" ranges="7350,8000,11025,12000,16000,22050,24000,32000,44100,48000" />
+            <Limit name="bitrate" range="8000-960000" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.g711.alaw.decoder" type="audio/g711-alaw">
+            <Alias name="OMX.google.g711.alaw.decoder" />
+            <Limit name="channel-count" max="1" />
+            <Limit name="sample-rate" ranges="8000-48000" />
+            <Limit name="bitrate" range="64000" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.g711.mlaw.decoder" type="audio/g711-mlaw">
+            <Alias name="OMX.google.g711.mlaw.decoder" />
+            <Limit name="channel-count" max="1" />
+            <Limit name="sample-rate" ranges="8000-48000" />
+            <Limit name="bitrate" range="64000" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.vorbis.decoder" type="audio/vorbis">
+            <Alias name="OMX.google.vorbis.decoder" />
+            <Limit name="channel-count" max="8" />
+            <Limit name="sample-rate" ranges="8000-96000" />
+            <Limit name="bitrate" range="32000-500000" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.opus.decoder" type="audio/opus">
+            <Alias name="OMX.google.opus.decoder" />
+            <Limit name="channel-count" max="8" />
+            <Limit name="sample-rate" ranges="48000" />
+            <Limit name="bitrate" range="6000-510000" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.raw.decoder" type="audio/raw">
+            <Alias name="OMX.google.raw.decoder" />
+            <Limit name="channel-count" max="8" />
+            <Limit name="sample-rate" ranges="8000-96000" />
+            <Limit name="bitrate" range="1-10000000" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.flac.decoder" type="audio/flac">
+            <Alias name="OMX.google.flac.decoder" />
+            <Limit name="channel-count" max="8" />
+            <Limit name="sample-rate" ranges="1-655350" />
+            <Limit name="bitrate" range="1-21000000" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.gsm.decoder" type="audio/gsm" domain="telephony">
+            <Alias name="OMX.google.gsm.decoder" />
+            <Limit name="channel-count" max="1" />
+            <Limit name="sample-rate" ranges="8000" />
+            <Limit name="bitrate" range="13000" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.mpeg4.decoder" type="video/mp4v-es">
+            <Alias name="OMX.google.mpeg4.decoder" />
+            <!-- profiles and levels:  ProfileSimple : Level3 -->
+            <Limit name="size" min="2x2" max="352x288" />
+            <Limit name="alignment" value="2x2" />
+            <Limit name="block-size" value="16x16" />
+            <Limit name="blocks-per-second" range="12-11880" />
+            <Limit name="bitrate" range="1-384000" />
+            <Feature name="adaptive-playback" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.h263.decoder" type="video/3gpp">
+            <Alias name="OMX.google.h263.decoder" />
+            <!-- profiles and levels:  ProfileBaseline : Level30, ProfileBaseline : Level45
+                    ProfileISWV2 : Level30, ProfileISWV2 : Level45 -->
+            <Limit name="size" min="2x2" max="352x288" />
+            <Limit name="alignment" value="2x2" />
+            <Limit name="bitrate" range="1-384000" />
+            <Feature name="adaptive-playback" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.avc.decoder" type="video/avc" variant="slow-cpu,!slow-cpu">
+            <Alias name="OMX.google.h264.decoder" />
+            <Limit name="alignment" value="2x2" />
+            <Limit name="block-size" value="16x16" />
+            <Variant name="!slow-cpu">
+                <Limit name="size" min="2x2" max="4080x4080" />
+                <!-- profiles and levels:  ProfileHigh : Level52 -->
+                <Limit name="block-count" range="1-32768" /> <!-- max 4096x2048 equivalent -->
+                <Limit name="blocks-per-second" range="1-1966080" />
+                <Limit name="bitrate" range="1-48000000" />
+            </Variant>
+            <Variant name="slow-cpu">
+                <Limit name="size" min="2x2" max="2048x2048" />
+                <!-- profiles and levels:  ProfileHigh : Level51 -->
+                <Limit name="block-count" range="1-16384" />
+                <Limit name="blocks-per-second" range="1-491520" />
+                <Limit name="bitrate" range="1-40000000" />
+            </Variant>
+            <Feature name="adaptive-playback" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.hevc.decoder" type="video/hevc" variant="slow-cpu,!slow-cpu">
+            <Alias name="OMX.google.hevc.decoder" />
+            <Limit name="alignment" value="2x2" />
+            <Limit name="block-size" value="8x8" />
+            <Variant name="!slow-cpu">
+                <Limit name="size" min="2x2" max="4096x4096" />
+                <!-- profiles and levels:  ProfileMain : MainTierLevel51 -->
+                <Limit name="block-count" range="1-196608" /> <!-- max 4096x3072 -->
+                <Limit name="blocks-per-second" range="1-2000000" />
+                <Limit name="bitrate" range="1-10000000" />
+            </Variant>
+            <Variant name="slow-cpu">
+                <Limit name="size" min="2x2" max="2048x2048" />
+                <!-- profiles and levels:  ProfileMain : MainTierLevel51 -->
+                <Limit name="block-count" range="1-65536" />
+                <Limit name="blocks-per-second" range="1-491520" />
+                <Limit name="bitrate" range="1-5000000" />
+            </Variant>
+            <Feature name="adaptive-playback" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.vp8.decoder" type="video/x-vnd.on2.vp8" variant="slow-cpu,!slow-cpu">
+            <Alias name="OMX.google.vp8.decoder" />
+            <Limit name="size" min="2x2" max="2048x2048" />
+            <Limit name="alignment" value="2x2" />
+            <Limit name="block-size" value="16x16" />
+            <Variant name="!slow-cpu">
+                <Limit name="block-count" range="1-16384" />
+                <Limit name="blocks-per-second" range="1-1000000" />
+                <Limit name="bitrate" range="1-40000000" />
+            </Variant>
+            <Variant name="slow-cpu">
+                <Limit name="block-count" range="1-8192" /> <!-- max 2048x1024 -->
+                <Limit name="blocks-per-second" range="1-1000000" />
+                <Limit name="bitrate" range="1-40000000" />
+            </Variant>
+            <Feature name="adaptive-playback" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.vp9.decoder" type="video/x-vnd.on2.vp9" variant="slow-cpu,!slow-cpu">
+            <Alias name="OMX.google.vp9.decoder" />
+            <Limit name="alignment" value="2x2" />
+            <Limit name="block-size" value="16x16" />
+            <Variant name="!slow-cpu">
+                <Limit name="size" min="2x2" max="2048x2048" />
+                <Limit name="block-count" range="1-16384" />
+                <Limit name="blocks-per-second" range="1-500000" />
+                <Limit name="bitrate" range="1-40000000" />
+            </Variant>
+            <Variant name="slow-cpu">
+                <Limit name="size" min="2x2" max="1280x1280" />
+                <Limit name="block-count" range="1-3600" /> <!-- max 1280x720 -->
+                <Limit name="blocks-per-second" range="1-108000" />
+                <Limit name="bitrate" range="1-5000000" />
+            </Variant>
+            <Feature name="adaptive-playback" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.av1.decoder" type="video/av01" variant="!slow-cpu">
+            <Limit name="size" min="2x2" max="1920x1080" />
+            <Limit name="alignment" value="2x2" />
+            <Limit name="block-size" value="16x16" />
+            <Limit name="block-count" range="1-16384" />
+            <Limit name="blocks-per-second" range="1-2073600" />
+            <Limit name="bitrate" range="1-120000000" />
+            <Feature name="adaptive-playback" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.mpeg2.decoder" type="video/mpeg2" domain="tv">
+            <Alias name="OMX.google.mpeg2.decoder" />
+            <!-- profiles and levels:  ProfileMain : LevelHL -->
+            <Limit name="size" min="16x16" max="1920x1088" />
+            <Limit name="alignment" value="2x2" />
+            <Limit name="block-size" value="16x16" />
+            <Limit name="blocks-per-second" range="1-244800" />
+            <Limit name="bitrate" range="1-20000000" />
+            <Feature name="adaptive-playback" />
+        </MediaCodec>
+    </Decoders>
+    <Encoders>
+        <MediaCodec name="c2.android.aac.encoder" type="audio/mp4a-latm">
+            <Alias name="OMX.google.aac.encoder" />
+            <Limit name="channel-count" max="6" />
+            <Limit name="sample-rate" ranges="8000,11025,12000,16000,22050,24000,32000,44100,48000" />
+            <!-- also may support 64000, 88200  and 96000 Hz -->
+            <Limit name="bitrate" range="8000-960000" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.amrnb.encoder" type="audio/3gpp">
+            <Alias name="OMX.google.amrnb.encoder" />
+            <Limit name="channel-count" max="1" />
+            <Limit name="sample-rate" ranges="8000" />
+            <Limit name="bitrate" range="4750-12200" />
+            <Feature name="bitrate-modes" value="CBR" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.amrwb.encoder" type="audio/amr-wb">
+            <Alias name="OMX.google.amrwb.encoder" />
+            <Limit name="channel-count" max="1" />
+            <Limit name="sample-rate" ranges="16000" />
+            <Limit name="bitrate" range="6600-23850" />
+            <Feature name="bitrate-modes" value="CBR" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.flac.encoder" type="audio/flac">
+            <Alias name="OMX.google.flac.encoder" />
+            <Limit name="channel-count" max="2" />
+            <Limit name="sample-rate" ranges="1-655350" />
+            <Limit name="bitrate" range="1-21000000" />
+            <Limit name="complexity" range="0-8"  default="5" />
+            <Feature name="bitrate-modes" value="CQ" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.opus.encoder" type="audio/opus">
+            <Limit name="channel-count" max="2" />
+            <Limit name="sample-rate" ranges="8000,12000,16000,24000,48000" />
+            <Limit name="bitrate" range="500-512000" />
+            <Limit name="complexity" range="0-10"  default="5" />
+            <Feature name="bitrate-modes" value="CBR" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.h263.encoder" type="video/3gpp">
+            <Alias name="OMX.google.h263.encoder" />
+            <!-- profiles and levels:  ProfileBaseline : Level45 -->
+            <Limit name="size" min="176x144" max="176x144" />
+            <Limit name="alignment" value="16x16" />
+            <Limit name="bitrate" range="1-128000" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.mpeg4.encoder" type="video/mp4v-es">
+            <Alias name="OMX.google.mpeg4.encoder" />
+            <!-- profiles and levels:  ProfileCore : Level2 -->
+            <Limit name="size" min="16x16" max="176x144" />
+            <Limit name="alignment" value="16x16" />
+            <Limit name="block-size" value="16x16" />
+            <Limit name="blocks-per-second" range="12-1485" />
+            <Limit name="bitrate" range="1-64000" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.avc.encoder" type="video/avc" variant="slow-cpu,!slow-cpu">
+            <Alias name="OMX.google.h264.encoder" />
+            <Limit name="alignment" value="2x2" />
+            <Limit name="block-size" value="16x16" />
+            <Variant name="!slow-cpu">
+                <Limit name="size" min="16x16" max="2048x2048" />
+                <!-- profiles and levels:  ProfileBaseline : Level41 -->
+                <Limit name="block-count" range="1-8192" /> <!-- max 2048x1024 -->
+                <Limit name="blocks-per-second" range="1-245760" />
+                <Limit name="bitrate" range="1-12000000" />
+            </Variant>
+            <Variant name="slow-cpu">
+                <Limit name="size" min="16x16" max="1808x1808" />
+                <!-- profiles and levels:  ProfileBaseline : Level3 -->
+                <Limit name="block-count" range="1-1620" />
+                <Limit name="blocks-per-second" range="1-40500" />
+                <Limit name="bitrate" range="1-2000000" />
+            </Variant>
+            <Feature name="intra-refresh" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.vp8.encoder" type="video/x-vnd.on2.vp8" variant="slow-cpu,!slow-cpu">
+            <Alias name="OMX.google.vp8.encoder" />
+            <Limit name="alignment" value="2x2" />
+            <Limit name="block-size" value="16x16" />
+            <Variant name="!slow-cpu">
+                <Limit name="size" min="2x2" max="2048x2048" />
+                <!-- profiles and levels:  ProfileMain : Level_Version0-3 -->
+                <!-- 2016 devices can encode at about 10fps at this block count -->
+                <Limit name="block-count" range="1-16384" />
+                <Limit name="bitrate" range="1-40000000" />
+            </Variant>
+            <Variant name="slow-cpu">
+                <Limit name="size" min="2x2" max="1280x1280" />
+                <!-- profiles and levels:  ProfileMain : Level_Version0-3 -->
+                <Limit name="block-count" range="1-3600" /> <!-- max 1280x720 -->
+                <Limit name="bitrate" range="1-20000000" />
+            </Variant>
+            <Feature name="bitrate-modes" value="VBR,CBR" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.hevc.encoder" type="video/hevc" variant="!slow-cpu">
+            <!-- profiles and levels:  ProfileMain : MainTierLevel51 -->
+            <Limit name="size" min="2x2" max="512x512" />
+            <Limit name="alignment" value="2x2" />
+            <Limit name="block-size" value="8x8" />
+            <Limit name="block-count" range="1-4096" /> <!-- max 512x512 -->
+            <Limit name="blocks-per-second" range="1-122880" />
+            <Limit name="frame-rate" range="1-120" />
+            <Limit name="bitrate" range="1-10000000" />
+            <Limit name="complexity" range="0-10"  default="0" />
+            <Limit name="quality" range="0-100"  default="80" />
+            <Feature name="bitrate-modes" value="VBR,CBR,CQ" />
+        </MediaCodec>
+        <MediaCodec name="c2.android.vp9.encoder" type="video/x-vnd.on2.vp9" variant="!slow-cpu">
+            <Alias name="OMX.google.vp9.encoder" />
+            <!-- profiles and levels:  ProfileMain : Level_Version0-3 -->
+            <Limit name="size" min="2x2" max="2048x2048" />
+            <Limit name="alignment" value="2x2" />
+            <Limit name="block-size" value="16x16" />
+            <!-- 2016 devices can encode at about 8fps at this block count -->
+            <Limit name="block-count" range="1-3600" /> <!-- max 1280x720 -->
+            <Limit name="bitrate" range="1-40000000" />
+            <Feature name="bitrate-modes" value="VBR,CBR" />
+        </MediaCodec>
+    </Encoders>
+</MediaCodecs>
diff --git a/media/libstagefright/exports.lds b/media/libstagefright/exports.lds
index 59dfc49..aabc233 100644
--- a/media/libstagefright/exports.lds
+++ b/media/libstagefright/exports.lds
@@ -9,51 +9,51 @@
         _ZN7android16SoftwareRenderer*;
         ABGRToARGB;
         ABGRToI420;
-        ABGRToUVRow_Any_NEON;
+        ABGRToUVRow_Any_NEON*;
         ABGRToUVRow_C;
-        ABGRToUVRow_NEON;
-        ABGRToYRow_Any_NEON;
+        ABGRToUVRow_NEON*;
+        ABGRToYRow_Any_NEON*;
         ABGRToYRow_C;
-        ABGRToYRow_NEON;
+        ABGRToYRow_NEON*;
         Android420ToI420;
         ARGB1555ToARGB;
-        ARGB1555ToARGBRow_Any_NEON;
+        ARGB1555ToARGBRow_Any_NEON*;
         ARGB1555ToARGBRow_C;
-        ARGB1555ToARGBRow_NEON;
+        ARGB1555ToARGBRow_NEON*;
         ARGB1555ToI420;
-        ARGB1555ToUVRow_Any_NEON;
+        ARGB1555ToUVRow_Any_NEON*;
         ARGB1555ToUVRow_C;
-        ARGB1555ToUVRow_NEON;
-        ARGB1555ToYRow_Any_NEON;
+        ARGB1555ToUVRow_NEON*;
+        ARGB1555ToYRow_Any_NEON*;
         ARGB1555ToYRow_C;
-        ARGB1555ToYRow_NEON;
+        ARGB1555ToYRow_NEON*;
         ARGB4444ToARGB;
-        ARGB4444ToARGBRow_Any_NEON;
+        ARGB4444ToARGBRow_Any_NEON*;
         ARGB4444ToARGBRow_C;
-        ARGB4444ToARGBRow_NEON;
+        ARGB4444ToARGBRow_NEON*;
         ARGB4444ToI420;
-        ARGB4444ToUVRow_Any_NEON;
+        ARGB4444ToUVRow_Any_NEON*;
         ARGB4444ToUVRow_C;
-        ARGB4444ToUVRow_NEON;
-        ARGB4444ToYRow_Any_NEON;
+        ARGB4444ToUVRow_NEON*;
+        ARGB4444ToYRow_Any_NEON*;
         ARGB4444ToYRow_C;
-        ARGB4444ToYRow_NEON;
+        ARGB4444ToYRow_NEON*;
         ARGBAdd;
-        ARGBAddRow_Any_NEON;
+        ARGBAddRow_Any_NEON*;
         ARGBAddRow_C;
-        ARGBAddRow_NEON;
+        ARGBAddRow_NEON*;
         ARGBAffineRow_C;
         ARGBAttenuate;
-        ARGBAttenuateRow_Any_NEON;
+        ARGBAttenuateRow_Any_NEON*;
         ARGBAttenuateRow_C;
-        ARGBAttenuateRow_NEON;
+        ARGBAttenuateRow_NEON*;
         ARGBBlend;
         ARGBBlendRow_C;
-        ARGBBlendRow_NEON;
+        ARGBBlendRow_NEON*;
         ARGBBlur;
         ARGBColorMatrix;
         ARGBColorMatrixRow_C;
-        ARGBColorMatrixRow_NEON;
+        ARGBColorMatrixRow_NEON*;
         ARGBColorTable;
         ARGBColorTableRow_C;
         ARGBComputeCumulativeSum;
@@ -63,97 +63,97 @@
         ARGBCopyYToAlpha;
         ARGBCopyYToAlphaRow_C;
         ARGBExtractAlpha;
-        ARGBExtractAlphaRow_Any_NEON;
+        ARGBExtractAlphaRow_Any_NEON*;
         ARGBExtractAlphaRow_C;
-        ARGBExtractAlphaRow_NEON;
+        ARGBExtractAlphaRow_NEON*;
         ARGBGray;
         ARGBGrayRow_C;
-        ARGBGrayRow_NEON;
+        ARGBGrayRow_NEON*;
         ARGBGrayTo;
         ARGBInterpolate;
         ARGBLumaColorTable;
         ARGBLumaColorTableRow_C;
         ARGBMirror;
-        ARGBMirrorRow_Any_NEON;
+        ARGBMirrorRow_Any_NEON*;
         ARGBMirrorRow_C;
-        ARGBMirrorRow_NEON;
+        ARGBMirrorRow_NEON*;
         ARGBMultiply;
-        ARGBMultiplyRow_Any_NEON;
+        ARGBMultiplyRow_Any_NEON*;
         ARGBMultiplyRow_C;
-        ARGBMultiplyRow_NEON;
+        ARGBMultiplyRow_NEON*;
         ARGBPolynomial;
         ARGBPolynomialRow_C;
         ARGBQuantize;
         ARGBQuantizeRow_C;
-        ARGBQuantizeRow_NEON;
+        ARGBQuantizeRow_NEON*;
         ARGBRect;
         ARGBSepia;
         ARGBSepiaRow_C;
-        ARGBSepiaRow_NEON;
-        ARGBSetRow_Any_NEON;
+        ARGBSepiaRow_NEON*;
+        ARGBSetRow_Any_NEON*;
         ARGBSetRow_C;
-        ARGBSetRow_NEON;
+        ARGBSetRow_NEON*;
         ARGBShade;
         ARGBShadeRow_C;
-        ARGBShadeRow_NEON;
+        ARGBShadeRow_NEON*;
         ARGBShuffle;
-        ARGBShuffleRow_Any_NEON;
+        ARGBShuffleRow_Any_NEON*;
         ARGBShuffleRow_C;
-        ARGBShuffleRow_NEON;
+        ARGBShuffleRow_NEON*;
         ARGBSobel;
         ARGBSobelToPlane;
         ARGBSobelXY;
         ARGBSubtract;
-        ARGBSubtractRow_Any_NEON;
+        ARGBSubtractRow_Any_NEON*;
         ARGBSubtractRow_C;
-        ARGBSubtractRow_NEON;
+        ARGBSubtractRow_NEON*;
         ARGBToABGR;
-        ARGBToARGB1555Row_Any_NEON;
+        ARGBToARGB1555Row_Any_NEON*;
         ARGBToARGB1555Row_C;
-        ARGBToARGB1555Row_NEON;
-        ARGBToARGB4444Row_Any_NEON;
+        ARGBToARGB1555Row_NEON*;
+        ARGBToARGB4444Row_Any_NEON*;
         ARGBToARGB4444Row_C;
-        ARGBToARGB4444Row_NEON;
+        ARGBToARGB4444Row_NEON*;
         ARGBToBGRA;
         ARGBToI420;
-        ARGBToRAWRow_Any_NEON;
+        ARGBToRAWRow_Any_NEON*;
         ARGBToRAWRow_C;
-        ARGBToRAWRow_NEON;
-        ARGBToRGB24Row_Any_NEON;
+        ARGBToRAWRow_NEON*;
+        ARGBToRGB24Row_Any_NEON*;
         ARGBToRGB24Row_C;
-        ARGBToRGB24Row_NEON;
-        ARGBToRGB565DitherRow_Any_NEON;
+        ARGBToRGB24Row_NEON*;
+        ARGBToRGB565DitherRow_Any_NEON*;
         ARGBToRGB565DitherRow_C;
-        ARGBToRGB565DitherRow_NEON;
-        ARGBToRGB565Row_Any_NEON;
+        ARGBToRGB565DitherRow_NEON*;
+        ARGBToRGB565Row_Any_NEON*;
         ARGBToRGB565Row_C;
-        ARGBToRGB565Row_NEON;
-        ARGBToUV444Row_Any_NEON;
+        ARGBToRGB565Row_NEON*;
+        ARGBToUV444Row_Any_NEON*;
         ARGBToUV444Row_C;
-        ARGBToUV444Row_NEON;
-        ARGBToUVJRow_Any_NEON;
+        ARGBToUV444Row_NEON*;
+        ARGBToUVJRow_Any_NEON*;
         ARGBToUVJRow_C;
-        ARGBToUVJRow_NEON;
-        ARGBToUVRow_Any_NEON;
+        ARGBToUVJRow_NEON*;
+        ARGBToUVRow_Any_NEON*;
         ARGBToUVRow_C;
-        ARGBToUVRow_NEON;
-        ARGBToYJRow_Any_NEON;
+        ARGBToUVRow_NEON*;
+        ARGBToYJRow_Any_NEON*;
         ARGBToYJRow_C;
-        ARGBToYJRow_NEON;
-        ARGBToYRow_Any_NEON;
+        ARGBToYJRow_NEON*;
+        ARGBToYRow_Any_NEON*;
         ARGBToYRow_C;
-        ARGBToYRow_NEON;
+        ARGBToYRow_NEON*;
         ARGBUnattenuate;
         ARGBUnattenuateRow_C;
-        ArmCpuCaps;
+        ArmCpuCaps*;
         BGRAToARGB;
         BGRAToI420;
-        BGRAToUVRow_Any_NEON;
+        BGRAToUVRow_Any_NEON*;
         BGRAToUVRow_C;
-        BGRAToUVRow_NEON;
-        BGRAToYRow_Any_NEON;
+        BGRAToUVRow_NEON*;
+        BGRAToYRow_Any_NEON*;
         BGRAToYRow_C;
-        BGRAToYRow_NEON;
+        BGRAToYRow_NEON*;
         BlendPlane;
         BlendPlaneRow_C;
         CanonicalFourCC;
@@ -162,11 +162,11 @@
         CopyPlane;
         CopyPlane_16;
         CopyRow_16_C;
-        CopyRow_Any_NEON;
+        CopyRow_Any_NEON*;
         CopyRow_C;
-        CopyRow_NEON;
-        CpuId;
-        cpu_info_;
+        CopyRow_NEON*;
+        CpuId*;
+        cpu_info_*;
         CumulativeSumToAverageRow_C;
         FixedDiv1_C;
         FixedDiv_C;
@@ -176,18 +176,18 @@
         H420ToARGB;
         H422ToABGR;
         H422ToARGB;
-        HalfFloat1Row_Any_NEON;
-        HalfFloat1Row_NEON;
+        HalfFloat1Row_Any_NEON*;
+        HalfFloat1Row_NEON*;
         HalfFloatPlane;
-        HalfFloatRow_Any_NEON;
+        HalfFloatRow_Any_NEON*;
         HalfFloatRow_C;
-        HalfFloatRow_NEON;
+        HalfFloatRow_NEON*;
         I400Copy;
         I400Mirror;
         I400ToARGB;
-        I400ToARGBRow_Any_NEON;
+        I400ToARGBRow_Any_NEON*;
         I400ToARGBRow_C;
-        I400ToARGBRow_NEON;
+        I400ToARGBRow_NEON*;
         I400ToI400;
         I400ToI420;
         I420AlphaToABGR;
@@ -216,59 +216,59 @@
         I420ToRGBA;
         I420ToUYVY;
         I420ToYUY2;
-        I422AlphaToARGBRow_Any_NEON;
+        I422AlphaToARGBRow_Any_NEON*;
         I422AlphaToARGBRow_C;
-        I422AlphaToARGBRow_NEON;
+        I422AlphaToARGBRow_NEON*;
         I422Copy;
         I422ToABGR;
         I422ToARGB;
-        I422ToARGB1555Row_Any_NEON;
+        I422ToARGB1555Row_Any_NEON*;
         I422ToARGB1555Row_C;
-        I422ToARGB1555Row_NEON;
-        I422ToARGB4444Row_Any_NEON;
+        I422ToARGB1555Row_NEON*;
+        I422ToARGB4444Row_Any_NEON*;
         I422ToARGB4444Row_C;
-        I422ToARGB4444Row_NEON;
-        I422ToARGBRow_Any_NEON;
+        I422ToARGB4444Row_NEON*;
+        I422ToARGBRow_Any_NEON*;
         I422ToARGBRow_C;
-        I422ToARGBRow_NEON;
+        I422ToARGBRow_NEON*;
         I422ToBGRA;
         I422ToI420;
-        I422ToRGB24Row_Any_NEON;
+        I422ToRGB24Row_Any_NEON*;
         I422ToRGB24Row_C;
-        I422ToRGB24Row_NEON;
+        I422ToRGB24Row_NEON*;
         I422ToRGB565;
-        I422ToRGB565Row_Any_NEON;
+        I422ToRGB565Row_Any_NEON*;
         I422ToRGB565Row_C;
-        I422ToRGB565Row_NEON;
+        I422ToRGB565Row_NEON*;
         I422ToRGBA;
-        I422ToRGBARow_Any_NEON;
+        I422ToRGBARow_Any_NEON*;
         I422ToRGBARow_C;
-        I422ToRGBARow_NEON;
+        I422ToRGBARow_NEON*;
         I422ToUYVY;
-        I422ToUYVYRow_Any_NEON;
+        I422ToUYVYRow_Any_NEON*;
         I422ToUYVYRow_C;
-        I422ToUYVYRow_NEON;
+        I422ToUYVYRow_NEON*;
         I422ToYUY2;
-        I422ToYUY2Row_Any_NEON;
+        I422ToYUY2Row_Any_NEON*;
         I422ToYUY2Row_C;
-        I422ToYUY2Row_NEON;
+        I422ToYUY2Row_NEON*;
         I444Copy;
         I444ToABGR;
         I444ToARGB;
-        I444ToARGBRow_Any_NEON;
+        I444ToARGBRow_Any_NEON*;
         I444ToARGBRow_C;
-        I444ToARGBRow_NEON;
+        I444ToARGBRow_NEON*;
         I444ToI420;
-        InitCpuFlags;
+        InitCpuFlags*;
         InterpolatePlane;
         InterpolateRow_16_C;
-        InterpolateRow_Any_NEON;
+        InterpolateRow_Any_NEON*;
         InterpolateRow_C;
-        InterpolateRow_NEON;
+        InterpolateRow_NEON*;
         J400ToARGB;
-        J400ToARGBRow_Any_NEON;
+        J400ToARGBRow_Any_NEON*;
         J400ToARGBRow_C;
-        J400ToARGBRow_NEON;
+        J400ToARGBRow_NEON*;
         J420ToABGR;
         J420ToARGB;
         J422ToABGR;
@@ -282,107 +282,107 @@
         kYvuJPEGConstants;
         M420ToARGB;
         M420ToI420;
-        MaskCpuFlags;
+        MaskCpuFlags*;
         MergeUVPlane;
-        MergeUVRow_Any_NEON;
+        MergeUVRow_Any_NEON*;
         MergeUVRow_C;
-        MergeUVRow_NEON;
-        MipsCpuCaps;
+        MergeUVRow_NEON*;
+        MipsCpuCaps*;
         MirrorPlane;
-        MirrorRow_Any_NEON;
+        MirrorRow_Any_NEON*;
         MirrorRow_C;
-        MirrorRow_NEON;
+        MirrorRow_NEON*;
         MirrorUVRow_C;
-        MirrorUVRow_NEON;
-        NV12ToARGBRow_Any_NEON;
+        MirrorUVRow_NEON*;
+        NV12ToARGBRow_Any_NEON*;
         NV12ToARGBRow_C;
-        NV12ToARGBRow_NEON;
+        NV12ToARGBRow_NEON*;
         NV12ToI420;
         NV12ToRGB565;
-        NV12ToRGB565Row_Any_NEON;
+        NV12ToRGB565Row_Any_NEON*;
         NV12ToRGB565Row_C;
-        NV12ToRGB565Row_NEON;
+        NV12ToRGB565Row_NEON*;
         NV21ToARGB;
-        NV21ToARGBRow_Any_NEON;
+        NV21ToARGBRow_Any_NEON*;
         NV21ToARGBRow_C;
-        NV21ToARGBRow_NEON;
+        NV21ToARGBRow_NEON*;
         NV21ToI420;
         RAWToARGB;
-        RAWToARGBRow_Any_NEON;
+        RAWToARGBRow_Any_NEON*;
         RAWToARGBRow_C;
-        RAWToARGBRow_NEON;
+        RAWToARGBRow_NEON*;
         RAWToI420;
         RAWToRGB24;
-        RAWToRGB24Row_Any_NEON;
+        RAWToRGB24Row_Any_NEON*;
         RAWToRGB24Row_C;
-        RAWToRGB24Row_NEON;
-        RAWToUVRow_Any_NEON;
+        RAWToRGB24Row_NEON*;
+        RAWToUVRow_Any_NEON*;
         RAWToUVRow_C;
-        RAWToUVRow_NEON;
-        RAWToYRow_Any_NEON;
+        RAWToUVRow_NEON*;
+        RAWToYRow_Any_NEON*;
         RAWToYRow_C;
-        RAWToYRow_NEON;
+        RAWToYRow_NEON*;
         RGB24ToARGB;
-        RGB24ToARGBRow_Any_NEON;
+        RGB24ToARGBRow_Any_NEON*;
         RGB24ToARGBRow_C;
-        RGB24ToARGBRow_NEON;
+        RGB24ToARGBRow_NEON*;
         RGB24ToI420;
-        RGB24ToUVRow_Any_NEON;
+        RGB24ToUVRow_Any_NEON*;
         RGB24ToUVRow_C;
-        RGB24ToUVRow_NEON;
-        RGB24ToYRow_Any_NEON;
+        RGB24ToUVRow_NEON*;
+        RGB24ToYRow_Any_NEON*;
         RGB24ToYRow_C;
-        RGB24ToYRow_NEON;
+        RGB24ToYRow_NEON*;
         RGB565ToARGB;
-        RGB565ToARGBRow_Any_NEON;
+        RGB565ToARGBRow_Any_NEON*;
         RGB565ToARGBRow_C;
-        RGB565ToARGBRow_NEON;
+        RGB565ToARGBRow_NEON*;
         RGB565ToI420;
-        RGB565ToUVRow_Any_NEON;
+        RGB565ToUVRow_Any_NEON*;
         RGB565ToUVRow_C;
-        RGB565ToUVRow_NEON;
-        RGB565ToYRow_Any_NEON;
+        RGB565ToUVRow_NEON*;
+        RGB565ToYRow_Any_NEON*;
         RGB565ToYRow_C;
-        RGB565ToYRow_NEON;
+        RGB565ToYRow_NEON*;
         RGBAToARGB;
         RGBAToI420;
-        RGBAToUVRow_Any_NEON;
+        RGBAToUVRow_Any_NEON*;
         RGBAToUVRow_C;
-        RGBAToUVRow_NEON;
-        RGBAToYRow_Any_NEON;
+        RGBAToUVRow_NEON*;
+        RGBAToYRow_Any_NEON*;
         RGBAToYRow_C;
-        RGBAToYRow_NEON;
+        RGBAToYRow_NEON*;
         RGBColorMatrix;
         RGBColorTable;
         RGBColorTableRow_C;
         Scale;
         ScaleAddRow_16_C;
         ScaleAddRow_C;
-        ScaleAddRows_NEON;
+        ScaleAddRows_NEON*;
         ScaleARGBCols64_C;
-        ScaleARGBCols_Any_NEON;
+        ScaleARGBCols_Any_NEON*;
         ScaleARGBCols_C;
-        ScaleARGBCols_NEON;
+        ScaleARGBCols_NEON*;
         ScaleARGBColsUp2_C;
         ScaleARGBFilterCols64_C;
-        ScaleARGBFilterCols_Any_NEON;
+        ScaleARGBFilterCols_Any_NEON*;
         ScaleARGBFilterCols_C;
-        ScaleARGBFilterCols_NEON;
-        ScaleARGBRowDown2_Any_NEON;
-        ScaleARGBRowDown2Box_Any_NEON;
+        ScaleARGBFilterCols_NEON*;
+        ScaleARGBRowDown2_Any_NEON*;
+        ScaleARGBRowDown2Box_Any_NEON*;
         ScaleARGBRowDown2Box_C;
-        ScaleARGBRowDown2Box_NEON;
+        ScaleARGBRowDown2Box_NEON*;
         ScaleARGBRowDown2_C;
-        ScaleARGBRowDown2Linear_Any_NEON;
+        ScaleARGBRowDown2Linear_Any_NEON*;
         ScaleARGBRowDown2Linear_C;
-        ScaleARGBRowDown2Linear_NEON;
-        ScaleARGBRowDown2_NEON;
-        ScaleARGBRowDownEven_Any_NEON;
-        ScaleARGBRowDownEvenBox_Any_NEON;
+        ScaleARGBRowDown2Linear_NEON*;
+        ScaleARGBRowDown2_NEON*;
+        ScaleARGBRowDownEven_Any_NEON*;
+        ScaleARGBRowDownEvenBox_Any_NEON*;
         ScaleARGBRowDownEvenBox_C;
-        ScaleARGBRowDownEvenBox_NEON;
+        ScaleARGBRowDownEvenBox_NEON*;
         ScaleARGBRowDownEven_C;
-        ScaleARGBRowDownEven_NEON;
+        ScaleARGBRowDownEven_NEON*;
         ScaleCols_16_C;
         ScaleCols_C;
         ScaleColsUp2_16_C;
@@ -390,11 +390,11 @@
         ScaleFilterCols_16_C;
         ScaleFilterCols64_16_C;
         ScaleFilterCols64_C;
-        ScaleFilterCols_Any_NEON;
+        ScaleFilterCols_Any_NEON*;
         ScaleFilterCols_C;
-        ScaleFilterCols_NEON;
+        ScaleFilterCols_NEON*;
         ScaleFilterReduce;
-        ScaleFilterRows_NEON;
+        ScaleFilterRows_NEON*;
         ScaleOffset;
         ScalePlane;
         ScalePlane_16;
@@ -405,104 +405,104 @@
         ScalePlaneVertical;
         ScalePlaneVertical_16;
         ScaleRowDown2_16_C;
-        ScaleRowDown2_Any_NEON;
+        ScaleRowDown2_Any_NEON*;
         ScaleRowDown2Box_16_C;
-        ScaleRowDown2Box_Any_NEON;
+        ScaleRowDown2Box_Any_NEON*;
         ScaleRowDown2Box_C;
-        ScaleRowDown2Box_NEON;
+        ScaleRowDown2Box_NEON*;
         ScaleRowDown2Box_Odd_C;
-        ScaleRowDown2Box_Odd_NEON;
+        ScaleRowDown2Box_Odd_NEON*;
         ScaleRowDown2_C;
         ScaleRowDown2Linear_16_C;
-        ScaleRowDown2Linear_Any_NEON;
+        ScaleRowDown2Linear_Any_NEON*;
         ScaleRowDown2Linear_C;
-        ScaleRowDown2Linear_NEON;
-        ScaleRowDown2_NEON;
+        ScaleRowDown2Linear_NEON*;
+        ScaleRowDown2_NEON*;
         ScaleRowDown34_0_Box_16_C;
-        ScaleRowDown34_0_Box_Any_NEON;
+        ScaleRowDown34_0_Box_Any_NEON*;
         ScaleRowDown34_0_Box_C;
-        ScaleRowDown34_0_Box_NEON;
+        ScaleRowDown34_0_Box_NEON*;
         ScaleRowDown34_16_C;
         ScaleRowDown34_1_Box_16_C;
-        ScaleRowDown34_1_Box_Any_NEON;
+        ScaleRowDown34_1_Box_Any_NEON*;
         ScaleRowDown34_1_Box_C;
-        ScaleRowDown34_1_Box_NEON;
-        ScaleRowDown34_Any_NEON;
+        ScaleRowDown34_1_Box_NEON*;
+        ScaleRowDown34_Any_NEON*;
         ScaleRowDown34_C;
-        ScaleRowDown34_NEON;
+        ScaleRowDown34_NEON*;
         ScaleRowDown38_16_C;
         ScaleRowDown38_2_Box_16_C;
-        ScaleRowDown38_2_Box_Any_NEON;
+        ScaleRowDown38_2_Box_Any_NEON*;
         ScaleRowDown38_2_Box_C;
-        ScaleRowDown38_2_Box_NEON;
+        ScaleRowDown38_2_Box_NEON*;
         ScaleRowDown38_3_Box_16_C;
-        ScaleRowDown38_3_Box_Any_NEON;
+        ScaleRowDown38_3_Box_Any_NEON*;
         ScaleRowDown38_3_Box_C;
-        ScaleRowDown38_3_Box_NEON;
-        ScaleRowDown38_Any_NEON;
+        ScaleRowDown38_3_Box_NEON*;
+        ScaleRowDown38_Any_NEON*;
         ScaleRowDown38_C;
-        ScaleRowDown38_NEON;
+        ScaleRowDown38_NEON*;
         ScaleRowDown4_16_C;
-        ScaleRowDown4_Any_NEON;
+        ScaleRowDown4_Any_NEON*;
         ScaleRowDown4Box_16_C;
-        ScaleRowDown4Box_Any_NEON;
+        ScaleRowDown4Box_Any_NEON*;
         ScaleRowDown4Box_C;
-        ScaleRowDown4Box_NEON;
+        ScaleRowDown4Box_NEON*;
         ScaleRowDown4_C;
-        ScaleRowDown4_NEON;
+        ScaleRowDown4_NEON*;
         ScaleSlope;
         SetPlane;
-        SetRow_Any_NEON;
+        SetRow_Any_NEON*;
         SetRow_C;
-        SetRow_NEON;
-        SobelRow_Any_NEON;
+        SetRow_NEON*;
+        SobelRow_Any_NEON*;
         SobelRow_C;
-        SobelRow_NEON;
-        SobelToPlaneRow_Any_NEON;
+        SobelRow_NEON*;
+        SobelToPlaneRow_Any_NEON*;
         SobelToPlaneRow_C;
-        SobelToPlaneRow_NEON;
+        SobelToPlaneRow_NEON*;
         SobelXRow_C;
-        SobelXRow_NEON;
-        SobelXYRow_Any_NEON;
+        SobelXRow_NEON*;
+        SobelXYRow_Any_NEON*;
         SobelXYRow_C;
-        SobelXYRow_NEON;
+        SobelXYRow_NEON*;
         SobelYRow_C;
-        SobelYRow_NEON;
+        SobelYRow_NEON*;
         SplitUVPlane;
-        SplitUVRow_Any_NEON;
+        SplitUVRow_Any_NEON*;
         SplitUVRow_C;
-        SplitUVRow_NEON;
+        SplitUVRow_NEON*;
         UYVYToARGB;
-        UYVYToARGBRow_Any_NEON;
+        UYVYToARGBRow_Any_NEON*;
         UYVYToARGBRow_C;
-        UYVYToARGBRow_NEON;
+        UYVYToARGBRow_NEON*;
         UYVYToI420;
         UYVYToI422;
         UYVYToNV12;
-        UYVYToUV422Row_Any_NEON;
+        UYVYToUV422Row_Any_NEON*;
         UYVYToUV422Row_C;
-        UYVYToUV422Row_NEON;
-        UYVYToUVRow_Any_NEON;
+        UYVYToUV422Row_NEON*;
+        UYVYToUVRow_Any_NEON*;
         UYVYToUVRow_C;
-        UYVYToUVRow_NEON;
-        UYVYToYRow_Any_NEON;
+        UYVYToUVRow_NEON*;
+        UYVYToYRow_Any_NEON*;
         UYVYToYRow_C;
-        UYVYToYRow_NEON;
+        UYVYToYRow_NEON*;
         YUY2ToARGB;
-        YUY2ToARGBRow_Any_NEON;
+        YUY2ToARGBRow_Any_NEON*;
         YUY2ToARGBRow_C;
-        YUY2ToARGBRow_NEON;
+        YUY2ToARGBRow_NEON*;
         YUY2ToI420;
         YUY2ToI422;
         YUY2ToNV12;
-        YUY2ToUV422Row_Any_NEON;
+        YUY2ToUV422Row_Any_NEON*;
         YUY2ToUV422Row_C;
-        YUY2ToUV422Row_NEON;
-        YUY2ToUVRow_Any_NEON;
+        YUY2ToUV422Row_NEON*;
+        YUY2ToUVRow_Any_NEON*;
         YUY2ToUVRow_C;
-        YUY2ToUVRow_NEON;
+        YUY2ToUVRow_NEON*;
         YUY2ToY;
-        YUY2ToYRow_Any_NEON;
+        YUY2ToYRow_Any_NEON*;
         YUY2ToYRow_C;
-        YUY2ToYRow_NEON;
+        YUY2ToYRow_NEON*;
 };
diff --git a/media/libstagefright/filters/Android.bp b/media/libstagefright/filters/Android.bp
index e944224..7a67e55 100644
--- a/media/libstagefright/filters/Android.bp
+++ b/media/libstagefright/filters/Android.bp
@@ -31,8 +31,5 @@
 
     sanitize: {
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 }
diff --git a/media/libstagefright/flac/dec/Android.bp b/media/libstagefright/flac/dec/Android.bp
index 8d486cf..b494e16 100644
--- a/media/libstagefright/flac/dec/Android.bp
+++ b/media/libstagefright/flac/dec/Android.bp
@@ -1,9 +1,6 @@
 cc_library {
     name: "libstagefright_flacdec",
     vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
 
     srcs: [
         "FLACDecoder.cpp",
@@ -11,11 +8,6 @@
 
     export_include_dirs: [ "." ],
 
-    include_dirs: [
-        "external/flac/include",
-        "frameworks/av/media/libstagefright/include",
-    ],
-
     cflags: ["-Werror"],
 
     sanitize: {
@@ -24,23 +16,31 @@
             "unsigned-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
     static: {
-        whole_static_libs: ["libFLAC"],
+        whole_static_libs: [
+            "libFLAC",
+            "libaudioutils",
+        ],
     },
 
     shared: {
-        static_libs: ["libFLAC"],
+        static_libs: [
+            "libFLAC",
+            "libaudioutils",
+        ],
+        export_static_lib_headers: [
+            "libFLAC",
+        ],
     },
 
     shared_libs: [
         "liblog",
-        "libstagefright_foundation",
-        "libutils",
     ],
-    header_libs: ["libmedia_headers"],
+
+    header_libs: [
+        "libmedia_headers",
+        "libFLAC-headers",
+    ],
 }
diff --git a/media/libstagefright/flac/dec/FLACDecoder.cpp b/media/libstagefright/flac/dec/FLACDecoder.cpp
index a2b6ab7..cef0bc6 100644
--- a/media/libstagefright/flac/dec/FLACDecoder.cpp
+++ b/media/libstagefright/flac/dec/FLACDecoder.cpp
@@ -20,6 +20,7 @@
 
 #include "FLACDecoder.h"
 
+#include <audio_utils/primitives.h> // float_from_i32
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/hexdump.h>
 #include <media/stagefright/MediaDefs.h>
@@ -117,104 +118,43 @@
     mErrorStatus = status;
 }
 
-// Copy samples from FLAC native 32-bit non-interleaved to 16-bit interleaved.
+// Copy samples from FLAC native 32-bit non-interleaved to 16-bit signed
+// or 32-bit float interleaved.
+// TODO: Consider moving to audio_utils.  See similar code at FLACExtractor.cpp
 // These are candidates for optimization if needed.
-static void copyMono8(
+static void copyTo16Signed(
         short *dst,
-        const int * src[FLACDecoder::kMaxChannels],
+        const int *const *src,
         unsigned nSamples,
-        unsigned /* nChannels */) {
-    for (unsigned i = 0; i < nSamples; ++i) {
-        *dst++ = src[0][i] << 8;
-    }
-}
-
-static void copyStereo8(
-        short *dst,
-        const int * src[FLACDecoder::kMaxChannels],
-        unsigned nSamples,
-        unsigned /* nChannels */) {
-    for (unsigned i = 0; i < nSamples; ++i) {
-        *dst++ = src[0][i] << 8;
-        *dst++ = src[1][i] << 8;
-    }
-}
-
-static void copyMultiCh8(
-        short *dst,
-        const int * src[FLACDecoder::kMaxChannels],
-        unsigned nSamples,
-        unsigned nChannels) {
-    for (unsigned i = 0; i < nSamples; ++i) {
-        for (unsigned c = 0; c < nChannels; ++c) {
-            *dst++ = src[c][i] << 8;
+        unsigned nChannels,
+        unsigned bitsPerSample) {
+    const int leftShift = 16 - (int)bitsPerSample; // cast to int to prevent unsigned overflow.
+    if (leftShift >= 0) {
+        for (unsigned i = 0; i < nSamples; ++i) {
+            for (unsigned c = 0; c < nChannels; ++c) {
+                *dst++ = src[c][i] << leftShift;
+            }
+        }
+    } else {
+        const int rightShift = -leftShift;
+        for (unsigned i = 0; i < nSamples; ++i) {
+            for (unsigned c = 0; c < nChannels; ++c) {
+                *dst++ = src[c][i] >> rightShift;
+            }
         }
     }
 }
 
-static void copyMono16(
-        short *dst,
-        const int * src[FLACDecoder::kMaxChannels],
+static void copyToFloat(
+        float *dst,
+        const int *const *src,
         unsigned nSamples,
-        unsigned /* nChannels */) {
-    for (unsigned i = 0; i < nSamples; ++i) {
-        *dst++ = src[0][i];
-    }
-}
-
-static void copyStereo16(
-        short *dst,
-        const int * src[FLACDecoder::kMaxChannels],
-        unsigned nSamples,
-        unsigned /* nChannels */) {
-    for (unsigned i = 0; i < nSamples; ++i) {
-        *dst++ = src[0][i];
-        *dst++ = src[1][i];
-    }
-}
-
-static void copyMultiCh16(
-        short *dst,
-        const int * src[FLACDecoder::kMaxChannels],
-        unsigned nSamples,
-        unsigned nChannels) {
+        unsigned nChannels,
+        unsigned bitsPerSample) {
+    const unsigned leftShift = 32 - bitsPerSample;
     for (unsigned i = 0; i < nSamples; ++i) {
         for (unsigned c = 0; c < nChannels; ++c) {
-            *dst++ = src[c][i];
-        }
-    }
-}
-
-// TODO: 24-bit versions should do dithering or noise-shaping, here or in AudioFlinger
-static void copyMono24(
-        short *dst,
-        const int * src[FLACDecoder::kMaxChannels],
-        unsigned nSamples,
-        unsigned /* nChannels */) {
-    for (unsigned i = 0; i < nSamples; ++i) {
-        *dst++ = src[0][i] >> 8;
-    }
-}
-
-static void copyStereo24(
-        short *dst,
-        const int * src[FLACDecoder::kMaxChannels],
-        unsigned nSamples,
-        unsigned /* nChannels */) {
-    for (unsigned i = 0; i < nSamples; ++i) {
-        *dst++ = src[0][i] >> 8;
-        *dst++ = src[1][i] >> 8;
-    }
-}
-
-static void copyMultiCh24(
-        short *dst,
-        const int * src[FLACDecoder::kMaxChannels],
-        unsigned nSamples,
-        unsigned nChannels) {
-    for (unsigned i = 0; i < nSamples; ++i) {
-        for (unsigned c = 0; c < nChannels; ++c) {
-            *dst++ = src[c][i] >> 8;
+            *dst++ = float_from_i32(src[c][i] << leftShift);
         }
     }
 }
@@ -238,8 +178,7 @@
       mStreamInfoValid(false),
       mWriteRequested(false),
       mWriteCompleted(false),
-      mErrorStatus((FLAC__StreamDecoderErrorStatus) -1),
-      mCopy(nullptr) {
+      mErrorStatus((FLAC__StreamDecoderErrorStatus) -1) {
     ALOGV("ctor:");
     memset(&mStreamInfo, 0, sizeof(mStreamInfo));
     memset(&mWriteHeader, 0, sizeof(mWriteHeader));
@@ -379,6 +318,7 @@
         case 8:
         case 16:
         case 24:
+        case 32: // generally rare, but is supported in the framework
             break;
 
         default:
@@ -387,31 +327,6 @@
             return ERROR_MALFORMED;
     }
 
-    // configure the appropriate copy function, defaulting to trespass
-    static const struct {
-        unsigned mChannels;
-        unsigned mBitsPerSample;
-        void (*mCopy)(short *dst, const int * src[kMaxChannels],
-                unsigned nSamples, unsigned nChannels);
-    } table[] = {
-        { 1,  8, copyMono8     },
-        { 2,  8, copyStereo8   },
-        { 8,  8, copyMultiCh8  },
-        { 1, 16, copyMono16    },
-        { 2, 16, copyStereo16  },
-        { 8, 16, copyMultiCh16 },
-        { 1, 24, copyMono24    },
-        { 2, 24, copyStereo24  },
-        { 8, 24, copyMultiCh24 },
-    };
-    for (const auto &entry : table) {
-        if (entry.mChannels >= getChannels() &&
-                entry.mBitsPerSample == getBitsPerSample()) {
-            mCopy = entry.mCopy;
-            break;
-        }
-    }
-
     // Now we have all metadata blocks.
     mBufferPos = 0;
     mBufferDataSize = 0;
@@ -420,7 +335,7 @@
 }
 
 status_t FLACDecoder::decodeOneFrame(const uint8_t *inBuffer, size_t inBufferLen,
-        short *outBuffer, size_t *outBufferLen) {
+        void *outBuffer, size_t *outBufferLen, bool outputFloat) {
     ALOGV("decodeOneFrame: input size(%zu)", inBufferLen);
 
     if (!mStreamInfoValid) {
@@ -469,21 +384,33 @@
         return ERROR_MALFORMED;
     }
 
-    size_t bufferSize = blocksize * getChannels() * sizeof(short);
+    const unsigned channels = getChannels();
+    const size_t sampleSize = outputFloat ? sizeof(float) : sizeof(int16_t);
+    const size_t frameSize = channels * sampleSize;
+    size_t bufferSize = blocksize * frameSize;
     if (bufferSize > *outBufferLen) {
         ALOGW("decodeOneFrame: output buffer holds only partial frame %zu:%zu",
                 *outBufferLen, bufferSize);
-        blocksize = *outBufferLen / (getChannels() * sizeof(short));
-        bufferSize = blocksize * getChannels() * sizeof(short);
+        blocksize = *outBufferLen / frameSize;
+        bufferSize = blocksize * frameSize;
     }
 
-    if (mCopy == nullptr) {
-        ALOGE("decodeOneFrame: format is not supported: channels(%d), BitsPerSample(%d)",
-                getChannels(), getBitsPerSample());
-        return ERROR_UNSUPPORTED;
-    }
     // copy PCM from FLAC write buffer to output buffer, with interleaving
-    (*mCopy)(outBuffer, mWriteBuffer, blocksize, getChannels());
+
+    const unsigned bitsPerSample = getBitsPerSample();
+    if (outputFloat) {
+        copyToFloat(reinterpret_cast<float*>(outBuffer),
+                    mWriteBuffer,
+                    blocksize,
+                    channels,
+                    bitsPerSample);
+    } else {
+        copyTo16Signed(reinterpret_cast<short*>(outBuffer),
+                       mWriteBuffer,
+                       blocksize,
+                       channels,
+                       bitsPerSample);
+    }
     *outBufferLen = bufferSize;
     return OK;
 }
diff --git a/media/libstagefright/flac/dec/FLACDecoder.h b/media/libstagefright/flac/dec/FLACDecoder.h
index 1a33cae..694fccb 100644
--- a/media/libstagefright/flac/dec/FLACDecoder.h
+++ b/media/libstagefright/flac/dec/FLACDecoder.h
@@ -41,7 +41,7 @@
 
     status_t parseMetadata(const uint8_t *inBuffer, size_t inBufferLen);
     status_t decodeOneFrame(const uint8_t *inBuffer, size_t inBufferLen,
-            short *outBuffer, size_t *outBufferLen);
+            void *outBuffer, size_t *outBufferLen, bool outputFloat = false);
     void flush();
     virtual ~FLACDecoder();
 
@@ -89,8 +89,6 @@
     // most recent error reported by libFLAC decoder
     FLAC__StreamDecoderErrorStatus mErrorStatus;
 
-    void (*mCopy)(short *dst, const int *src[kMaxChannels], unsigned nSamples, unsigned nChannels);
-
     status_t init();
 
     // FLAC stream decoder callbacks as C++ instance methods
diff --git a/media/libstagefright/foundation/AHierarchicalStateMachine.cpp b/media/libstagefright/foundation/AHierarchicalStateMachine.cpp
deleted file mode 100644
index b837f66..0000000
--- a/media/libstagefright/foundation/AHierarchicalStateMachine.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "AHierarchicalStateMachine"
-#include <utils/Log.h>
-
-#include <media/stagefright/foundation/AHierarchicalStateMachine.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <utils/Vector.h>
-
-namespace android {
-
-AState::AState(const sp<AState> &parentState)
-    : mParentState(parentState) {
-}
-
-AState::~AState() {
-}
-
-sp<AState> AState::parentState() {
-    return mParentState;
-}
-
-void AState::stateEntered() {
-}
-
-void AState::stateExited() {
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-AHierarchicalStateMachine::AHierarchicalStateMachine() {
-}
-
-AHierarchicalStateMachine::~AHierarchicalStateMachine() {
-}
-
-void AHierarchicalStateMachine::handleMessage(const sp<AMessage> &msg) {
-    sp<AState> save = mState;
-
-    sp<AState> cur = mState;
-    while (cur != NULL && !cur->onMessageReceived(msg)) {
-        // If you claim not to have handled the message you shouldn't
-        // have called setState...
-        CHECK(save == mState);
-
-        cur = cur->parentState();
-    }
-
-    if (cur != NULL) {
-        return;
-    }
-
-    ALOGW("Warning message %s unhandled in root state.",
-         msg->debugString().c_str());
-}
-
-void AHierarchicalStateMachine::changeState(const sp<AState> &state) {
-    if (state == mState) {
-        // Quick exit for the easy case.
-        return;
-    }
-
-    Vector<sp<AState> > A;
-    sp<AState> cur = mState;
-    for (;;) {
-        A.push(cur);
-        if (cur == NULL) {
-            break;
-        }
-        cur = cur->parentState();
-    }
-
-    Vector<sp<AState> > B;
-    cur = state;
-    for (;;) {
-        B.push(cur);
-        if (cur == NULL) {
-            break;
-        }
-        cur = cur->parentState();
-    }
-
-    // Remove the common tail.
-    while (A.size() > 0 && B.size() > 0 && A.top() == B.top()) {
-        A.pop();
-        B.pop();
-    }
-
-    mState = state;
-
-    for (size_t i = 0; i < A.size(); ++i) {
-        A.editItemAt(i)->stateExited();
-    }
-
-    for (size_t i = B.size(); i > 0;) {
-        i--;
-        B.editItemAt(i)->stateEntered();
-    }
-}
-
-}  // namespace android
diff --git a/media/libstagefright/foundation/ALooper.cpp b/media/libstagefright/foundation/ALooper.cpp
index 9921636..a276722 100644
--- a/media/libstagefright/foundation/ALooper.cpp
+++ b/media/libstagefright/foundation/ALooper.cpp
@@ -66,7 +66,7 @@
 
 // static
 int64_t ALooper::GetNowUs() {
-    return systemTime(SYSTEM_TIME_MONOTONIC) / 1000ll;
+    return systemTime(SYSTEM_TIME_MONOTONIC) / 1000LL;
 }
 
 ALooper::ALooper()
@@ -170,7 +170,9 @@
 
     int64_t whenUs;
     if (delayUs > 0) {
-        whenUs = GetNowUs() + delayUs;
+        int64_t nowUs = GetNowUs();
+        whenUs = (delayUs > INT64_MAX - nowUs ? INT64_MAX : nowUs + delayUs);
+
     } else {
         whenUs = GetNowUs();
     }
@@ -208,6 +210,9 @@
 
         if (whenUs > nowUs) {
             int64_t delayUs = whenUs - nowUs;
+            if (delayUs > INT64_MAX / 1000) {
+                delayUs = INT64_MAX / 1000;
+            }
             mQueueChangedCondition.waitRelative(mLock, delayUs * 1000ll);
 
             return true;
diff --git a/media/libstagefright/foundation/ANetworkSession.cpp b/media/libstagefright/foundation/ANetworkSession.cpp
deleted file mode 100644
index eafdc37..0000000
--- a/media/libstagefright/foundation/ANetworkSession.cpp
+++ /dev/null
@@ -1,1401 +0,0 @@
-/*
- * Copyright 2012, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "NetworkSession"
-#include <utils/Log.h>
-
-#include "ANetworkSession.h"
-#include "ParsedMessage.h"
-
-#include <arpa/inet.h>
-#include <fcntl.h>
-#include <linux/tcp.h>
-#include <net/if.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/ByteUtils.h>
-#include <media/stagefright/foundation/hexdump.h>
-
-namespace android {
-
-static const size_t kMaxUDPSize = 1500;
-static const int32_t kMaxUDPRetries = 200;
-
-struct ANetworkSession::NetworkThread : public Thread {
-    explicit NetworkThread(ANetworkSession *session);
-
-protected:
-    virtual ~NetworkThread();
-
-private:
-    ANetworkSession *mSession;
-
-    virtual bool threadLoop();
-
-    DISALLOW_EVIL_CONSTRUCTORS(NetworkThread);
-};
-
-struct ANetworkSession::Session : public RefBase {
-    enum Mode {
-        MODE_RTSP,
-        MODE_DATAGRAM,
-        MODE_WEBSOCKET,
-    };
-
-    enum State {
-        CONNECTING,
-        CONNECTED,
-        LISTENING_RTSP,
-        LISTENING_TCP_DGRAMS,
-        DATAGRAM,
-    };
-
-    Session(int32_t sessionID,
-            State state,
-            int s,
-            const sp<AMessage> &notify);
-
-    int32_t sessionID() const;
-    int socket() const;
-    sp<AMessage> getNotificationMessage() const;
-
-    bool isRTSPServer() const;
-    bool isTCPDatagramServer() const;
-
-    bool wantsToRead();
-    bool wantsToWrite();
-
-    status_t readMore();
-    status_t writeMore();
-
-    status_t sendRequest(
-            const void *data, ssize_t size, bool timeValid, int64_t timeUs);
-
-    void setMode(Mode mode);
-
-    status_t switchToWebSocketMode();
-
-protected:
-    virtual ~Session();
-
-private:
-    enum {
-        FRAGMENT_FLAG_TIME_VALID = 1,
-    };
-    struct Fragment {
-        uint32_t mFlags;
-        int64_t mTimeUs;
-        sp<ABuffer> mBuffer;
-    };
-
-    int32_t mSessionID;
-    State mState;
-    Mode mMode;
-    int mSocket;
-    sp<AMessage> mNotify;
-    bool mSawReceiveFailure, mSawSendFailure;
-    int32_t mUDPRetries;
-
-    List<Fragment> mOutFragments;
-
-    AString mInBuffer;
-
-    int64_t mLastStallReportUs;
-
-    void notifyError(bool send, status_t err, const char *detail);
-    void notify(NotificationReason reason);
-
-    void dumpFragmentStats(const Fragment &frag);
-
-    DISALLOW_EVIL_CONSTRUCTORS(Session);
-};
-////////////////////////////////////////////////////////////////////////////////
-
-ANetworkSession::NetworkThread::NetworkThread(ANetworkSession *session)
-    : mSession(session) {
-}
-
-ANetworkSession::NetworkThread::~NetworkThread() {
-}
-
-bool ANetworkSession::NetworkThread::threadLoop() {
-    mSession->threadLoop();
-
-    return true;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-ANetworkSession::Session::Session(
-        int32_t sessionID,
-        State state,
-        int s,
-        const sp<AMessage> &notify)
-    : mSessionID(sessionID),
-      mState(state),
-      mMode(MODE_DATAGRAM),
-      mSocket(s),
-      mNotify(notify),
-      mSawReceiveFailure(false),
-      mSawSendFailure(false),
-      mUDPRetries(kMaxUDPRetries),
-      mLastStallReportUs(-1ll) {
-    if (mState == CONNECTED) {
-        struct sockaddr_in localAddr;
-        socklen_t localAddrLen = sizeof(localAddr);
-
-        int res = getsockname(
-                mSocket, (struct sockaddr *)&localAddr, &localAddrLen);
-        CHECK_GE(res, 0);
-
-        struct sockaddr_in remoteAddr;
-        socklen_t remoteAddrLen = sizeof(remoteAddr);
-
-        res = getpeername(
-                mSocket, (struct sockaddr *)&remoteAddr, &remoteAddrLen);
-        CHECK_GE(res, 0);
-
-        in_addr_t addr = ntohl(localAddr.sin_addr.s_addr);
-        AString localAddrString = AStringPrintf(
-                "%d.%d.%d.%d",
-                (addr >> 24),
-                (addr >> 16) & 0xff,
-                (addr >> 8) & 0xff,
-                addr & 0xff);
-
-        addr = ntohl(remoteAddr.sin_addr.s_addr);
-        AString remoteAddrString = AStringPrintf(
-                "%d.%d.%d.%d",
-                (addr >> 24),
-                (addr >> 16) & 0xff,
-                (addr >> 8) & 0xff,
-                addr & 0xff);
-
-        sp<AMessage> msg = mNotify->dup();
-        msg->setInt32("sessionID", mSessionID);
-        msg->setInt32("reason", kWhatClientConnected);
-        msg->setString("server-ip", localAddrString.c_str());
-        msg->setInt32("server-port", ntohs(localAddr.sin_port));
-        msg->setString("client-ip", remoteAddrString.c_str());
-        msg->setInt32("client-port", ntohs(remoteAddr.sin_port));
-        msg->post();
-    }
-}
-
-ANetworkSession::Session::~Session() {
-    ALOGV("Session %d gone", mSessionID);
-
-    close(mSocket);
-    mSocket = -1;
-}
-
-int32_t ANetworkSession::Session::sessionID() const {
-    return mSessionID;
-}
-
-int ANetworkSession::Session::socket() const {
-    return mSocket;
-}
-
-void ANetworkSession::Session::setMode(Mode mode) {
-    mMode = mode;
-}
-
-status_t ANetworkSession::Session::switchToWebSocketMode() {
-    if (mState != CONNECTED || mMode != MODE_RTSP) {
-        return INVALID_OPERATION;
-    }
-
-    mMode = MODE_WEBSOCKET;
-
-    return OK;
-}
-
-sp<AMessage> ANetworkSession::Session::getNotificationMessage() const {
-    return mNotify;
-}
-
-bool ANetworkSession::Session::isRTSPServer() const {
-    return mState == LISTENING_RTSP;
-}
-
-bool ANetworkSession::Session::isTCPDatagramServer() const {
-    return mState == LISTENING_TCP_DGRAMS;
-}
-
-bool ANetworkSession::Session::wantsToRead() {
-    return !mSawReceiveFailure && mState != CONNECTING;
-}
-
-bool ANetworkSession::Session::wantsToWrite() {
-    return !mSawSendFailure
-        && (mState == CONNECTING
-            || (mState == CONNECTED && !mOutFragments.empty())
-            || (mState == DATAGRAM && !mOutFragments.empty()));
-}
-
-status_t ANetworkSession::Session::readMore() {
-    if (mState == DATAGRAM) {
-        CHECK_EQ(mMode, MODE_DATAGRAM);
-
-        status_t err;
-        do {
-            sp<ABuffer> buf = new ABuffer(kMaxUDPSize);
-
-            struct sockaddr_in remoteAddr;
-            socklen_t remoteAddrLen = sizeof(remoteAddr);
-
-            ssize_t n;
-            do {
-                n = recvfrom(
-                        mSocket, buf->data(), buf->capacity(), 0,
-                        (struct sockaddr *)&remoteAddr, &remoteAddrLen);
-            } while (n < 0 && errno == EINTR);
-
-            err = OK;
-            if (n < 0) {
-                err = -errno;
-            } else if (n == 0) {
-                err = -ECONNRESET;
-            } else {
-                buf->setRange(0, n);
-
-                int64_t nowUs = ALooper::GetNowUs();
-                buf->meta()->setInt64("arrivalTimeUs", nowUs);
-
-                sp<AMessage> notify = mNotify->dup();
-                notify->setInt32("sessionID", mSessionID);
-                notify->setInt32("reason", kWhatDatagram);
-
-                uint32_t ip = ntohl(remoteAddr.sin_addr.s_addr);
-                notify->setString(
-                        "fromAddr",
-                        AStringPrintf(
-                            "%u.%u.%u.%u",
-                            ip >> 24,
-                            (ip >> 16) & 0xff,
-                            (ip >> 8) & 0xff,
-                            ip & 0xff).c_str());
-
-                notify->setInt32("fromPort", ntohs(remoteAddr.sin_port));
-
-                notify->setBuffer("data", buf);
-                notify->post();
-            }
-        } while (err == OK);
-
-        if (err == -EAGAIN) {
-            err = OK;
-        }
-
-        if (err != OK) {
-            if (!mUDPRetries) {
-                notifyError(false /* send */, err, "Recvfrom failed.");
-                mSawReceiveFailure = true;
-            } else {
-                mUDPRetries--;
-                ALOGE("Recvfrom failed, %d/%d retries left",
-                        mUDPRetries, kMaxUDPRetries);
-                err = OK;
-            }
-        } else {
-            mUDPRetries = kMaxUDPRetries;
-        }
-
-        return err;
-    }
-
-    char tmp[512];
-    ssize_t n;
-    do {
-        n = recv(mSocket, tmp, sizeof(tmp), 0);
-    } while (n < 0 && errno == EINTR);
-
-    status_t err = OK;
-
-    if (n > 0) {
-        mInBuffer.append(tmp, n);
-
-#if 0
-        ALOGI("in:");
-        hexdump(tmp, n);
-#endif
-    } else if (n < 0) {
-        err = -errno;
-    } else {
-        err = -ECONNRESET;
-    }
-
-    if (mMode == MODE_DATAGRAM) {
-        // TCP stream carrying 16-bit length-prefixed datagrams.
-
-        while (mInBuffer.size() >= 2) {
-            size_t packetSize = U16_AT((const uint8_t *)mInBuffer.c_str());
-
-            if (mInBuffer.size() < packetSize + 2) {
-                break;
-            }
-
-            sp<ABuffer> packet = new ABuffer(packetSize);
-            memcpy(packet->data(), mInBuffer.c_str() + 2, packetSize);
-
-            int64_t nowUs = ALooper::GetNowUs();
-            packet->meta()->setInt64("arrivalTimeUs", nowUs);
-
-            sp<AMessage> notify = mNotify->dup();
-            notify->setInt32("sessionID", mSessionID);
-            notify->setInt32("reason", kWhatDatagram);
-            notify->setBuffer("data", packet);
-            notify->post();
-
-            mInBuffer.erase(0, packetSize + 2);
-        }
-    } else if (mMode == MODE_RTSP) {
-        for (;;) {
-            size_t length;
-
-            if (mInBuffer.size() > 0 && mInBuffer.c_str()[0] == '$') {
-                if (mInBuffer.size() < 4) {
-                    break;
-                }
-
-                length = U16_AT((const uint8_t *)mInBuffer.c_str() + 2);
-
-                if (mInBuffer.size() < 4 + length) {
-                    break;
-                }
-
-                sp<AMessage> notify = mNotify->dup();
-                notify->setInt32("sessionID", mSessionID);
-                notify->setInt32("reason", kWhatBinaryData);
-                notify->setInt32("channel", mInBuffer.c_str()[1]);
-
-                sp<ABuffer> data = new ABuffer(length);
-                memcpy(data->data(), mInBuffer.c_str() + 4, length);
-
-                int64_t nowUs = ALooper::GetNowUs();
-                data->meta()->setInt64("arrivalTimeUs", nowUs);
-
-                notify->setBuffer("data", data);
-                notify->post();
-
-                mInBuffer.erase(0, 4 + length);
-                continue;
-            }
-
-            sp<ParsedMessage> msg =
-                ParsedMessage::Parse(
-                        mInBuffer.c_str(), mInBuffer.size(), err != OK, &length);
-
-            if (msg == NULL) {
-                break;
-            }
-
-            sp<AMessage> notify = mNotify->dup();
-            notify->setInt32("sessionID", mSessionID);
-            notify->setInt32("reason", kWhatData);
-            notify->setObject("data", msg);
-            notify->post();
-
-#if 1
-            // XXX The (old) dongle sends the wrong content length header on a
-            // SET_PARAMETER request that signals a "wfd_idr_request".
-            // (17 instead of 19).
-            const char *content = msg->getContent();
-            if (content
-                    && !memcmp(content, "wfd_idr_request\r\n", 17)
-                    && length >= 19
-                    && mInBuffer.c_str()[length] == '\r'
-                    && mInBuffer.c_str()[length + 1] == '\n') {
-                length += 2;
-            }
-#endif
-
-            mInBuffer.erase(0, length);
-
-            if (err != OK) {
-                break;
-            }
-        }
-    } else {
-        CHECK_EQ(mMode, MODE_WEBSOCKET);
-
-        const uint8_t *data = (const uint8_t *)mInBuffer.c_str();
-        // hexdump(data, mInBuffer.size());
-
-        while (mInBuffer.size() >= 2) {
-            size_t offset = 2;
-
-            uint64_t payloadLen = data[1] & 0x7f;
-            if (payloadLen == 126) {
-                if (offset + 2 > mInBuffer.size()) {
-                    break;
-                }
-
-                payloadLen = U16_AT(&data[offset]);
-                offset += 2;
-            } else if (payloadLen == 127) {
-                if (offset + 8 > mInBuffer.size()) {
-                    break;
-                }
-
-                payloadLen = U64_AT(&data[offset]);
-                offset += 8;
-            }
-
-            uint32_t mask = 0;
-            if (data[1] & 0x80) {
-                // MASK==1
-                if (offset + 4 > mInBuffer.size()) {
-                    break;
-                }
-
-                mask = U32_AT(&data[offset]);
-                offset += 4;
-            }
-
-            if (payloadLen > mInBuffer.size() || offset > mInBuffer.size() - payloadLen) {
-                break;
-            }
-
-            // We have the full message.
-
-            sp<ABuffer> packet = new ABuffer(payloadLen);
-            memcpy(packet->data(), &data[offset], payloadLen);
-
-            if (mask != 0) {
-                for (size_t i = 0; i < payloadLen; ++i) {
-                    packet->data()[i] =
-                        data[offset + i]
-                            ^ ((mask >> (8 * (3 - (i % 4)))) & 0xff);
-                }
-            }
-
-            sp<AMessage> notify = mNotify->dup();
-            notify->setInt32("sessionID", mSessionID);
-            notify->setInt32("reason", kWhatWebSocketMessage);
-            notify->setBuffer("data", packet);
-            notify->setInt32("headerByte", data[0]);
-            notify->post();
-
-            mInBuffer.erase(0, offset + payloadLen);
-        }
-    }
-
-    if (err != OK) {
-        notifyError(false /* send */, err, "Recv failed.");
-        mSawReceiveFailure = true;
-    }
-
-    return err;
-}
-
-void ANetworkSession::Session::dumpFragmentStats(const Fragment & /* frag */) {
-#if 0
-    int64_t nowUs = ALooper::GetNowUs();
-    int64_t delayMs = (nowUs - frag.mTimeUs) / 1000ll;
-
-    static const int64_t kMinDelayMs = 0;
-    static const int64_t kMaxDelayMs = 300;
-
-    const char *kPattern = "########################################";
-    size_t kPatternSize = strlen(kPattern);
-
-    int n = (kPatternSize * (delayMs - kMinDelayMs))
-                / (kMaxDelayMs - kMinDelayMs);
-
-    if (n < 0) {
-        n = 0;
-    } else if ((size_t)n > kPatternSize) {
-        n = kPatternSize;
-    }
-
-    ALOGI("[%lld]: (%4lld ms) %s\n",
-          frag.mTimeUs / 1000,
-          delayMs,
-          kPattern + kPatternSize - n);
-#endif
-}
-
-status_t ANetworkSession::Session::writeMore() {
-    if (mState == DATAGRAM) {
-        CHECK(!mOutFragments.empty());
-
-        status_t err;
-        do {
-            const Fragment &frag = *mOutFragments.begin();
-            const sp<ABuffer> &datagram = frag.mBuffer;
-
-            int n;
-            do {
-                n = send(mSocket, datagram->data(), datagram->size(), 0);
-            } while (n < 0 && errno == EINTR);
-
-            err = OK;
-
-            if (n > 0) {
-                if (frag.mFlags & FRAGMENT_FLAG_TIME_VALID) {
-                    dumpFragmentStats(frag);
-                }
-
-                mOutFragments.erase(mOutFragments.begin());
-            } else if (n < 0) {
-                err = -errno;
-            } else if (n == 0) {
-                err = -ECONNRESET;
-            }
-        } while (err == OK && !mOutFragments.empty());
-
-        if (err == -EAGAIN) {
-            if (!mOutFragments.empty()) {
-                ALOGI("%zu datagrams remain queued.", mOutFragments.size());
-            }
-            err = OK;
-        }
-
-        if (err != OK) {
-            if (!mUDPRetries) {
-                notifyError(true /* send */, err, "Send datagram failed.");
-                mSawSendFailure = true;
-            } else {
-                mUDPRetries--;
-                ALOGE("Send datagram failed, %d/%d retries left",
-                        mUDPRetries, kMaxUDPRetries);
-                err = OK;
-            }
-        } else {
-            mUDPRetries = kMaxUDPRetries;
-        }
-
-        return err;
-    }
-
-    if (mState == CONNECTING) {
-        int err;
-        socklen_t optionLen = sizeof(err);
-        CHECK_EQ(getsockopt(mSocket, SOL_SOCKET, SO_ERROR, &err, &optionLen), 0);
-        CHECK_EQ(optionLen, (socklen_t)sizeof(err));
-
-        if (err != 0) {
-            notifyError(kWhatError, -err, "Connection failed");
-            mSawSendFailure = true;
-
-            return -err;
-        }
-
-        mState = CONNECTED;
-        notify(kWhatConnected);
-
-        return OK;
-    }
-
-    CHECK_EQ(mState, CONNECTED);
-    CHECK(!mOutFragments.empty());
-
-    ssize_t n = -1;
-    while (!mOutFragments.empty()) {
-        const Fragment &frag = *mOutFragments.begin();
-
-        do {
-            n = send(mSocket, frag.mBuffer->data(), frag.mBuffer->size(), 0);
-        } while (n < 0 && errno == EINTR);
-
-        if (n <= 0) {
-            break;
-        }
-
-        frag.mBuffer->setRange(
-                frag.mBuffer->offset() + n, frag.mBuffer->size() - n);
-
-        if (frag.mBuffer->size() > 0) {
-            break;
-        }
-
-        if (frag.mFlags & FRAGMENT_FLAG_TIME_VALID) {
-            dumpFragmentStats(frag);
-        }
-
-        mOutFragments.erase(mOutFragments.begin());
-    }
-
-    status_t err = OK;
-
-    if (n < 0) {
-        err = -errno;
-    } else if (n == 0) {
-        err = -ECONNRESET;
-    }
-
-    if (err != OK) {
-        notifyError(true /* send */, err, "Send failed.");
-        mSawSendFailure = true;
-    }
-
-#if 0
-    int numBytesQueued;
-    int res = ioctl(mSocket, SIOCOUTQ, &numBytesQueued);
-    if (res == 0 && numBytesQueued > 50 * 1024) {
-        if (numBytesQueued > 409600) {
-            ALOGW("!!! numBytesQueued = %d", numBytesQueued);
-        }
-
-        int64_t nowUs = ALooper::GetNowUs();
-
-        if (mLastStallReportUs < 0ll
-                || nowUs > mLastStallReportUs + 100000ll) {
-            sp<AMessage> msg = mNotify->dup();
-            msg->setInt32("sessionID", mSessionID);
-            msg->setInt32("reason", kWhatNetworkStall);
-            msg->setSize("numBytesQueued", numBytesQueued);
-            msg->post();
-
-            mLastStallReportUs = nowUs;
-        }
-    }
-#endif
-
-    return err;
-}
-
-status_t ANetworkSession::Session::sendRequest(
-        const void *data, ssize_t size, bool timeValid, int64_t timeUs) {
-    CHECK(mState == CONNECTED || mState == DATAGRAM);
-
-    if (size < 0) {
-        size = strlen((const char *)data);
-    }
-
-    if (size == 0) {
-        return OK;
-    }
-
-    sp<ABuffer> buffer;
-
-    if (mState == CONNECTED && mMode == MODE_DATAGRAM) {
-        CHECK_LE(size, 65535);
-
-        buffer = new ABuffer(size + 2);
-        buffer->data()[0] = size >> 8;
-        buffer->data()[1] = size & 0xff;
-        memcpy(buffer->data() + 2, data, size);
-    } else if (mState == CONNECTED && mMode == MODE_WEBSOCKET) {
-        static const bool kUseMask = false;  // Chromium doesn't like it.
-
-        size_t numHeaderBytes = 2 + (kUseMask ? 4 : 0);
-        if (size > 65535) {
-            numHeaderBytes += 8;
-        } else if (size > 125) {
-            numHeaderBytes += 2;
-        }
-
-        buffer = new ABuffer(numHeaderBytes + size);
-        buffer->data()[0] = 0x81;  // FIN==1 | opcode=1 (text)
-        buffer->data()[1] = kUseMask ? 0x80 : 0x00;
-
-        if (size > 65535) {
-            buffer->data()[1] |= 127;
-            buffer->data()[2] = 0x00;
-            buffer->data()[3] = 0x00;
-            buffer->data()[4] = 0x00;
-            buffer->data()[5] = 0x00;
-            buffer->data()[6] = (size >> 24) & 0xff;
-            buffer->data()[7] = (size >> 16) & 0xff;
-            buffer->data()[8] = (size >> 8) & 0xff;
-            buffer->data()[9] = size & 0xff;
-        } else if (size > 125) {
-            buffer->data()[1] |= 126;
-            buffer->data()[2] = (size >> 8) & 0xff;
-            buffer->data()[3] = size & 0xff;
-        } else {
-            buffer->data()[1] |= size;
-        }
-
-        if (kUseMask) {
-            uint32_t mask = rand();
-
-            buffer->data()[numHeaderBytes - 4] = (mask >> 24) & 0xff;
-            buffer->data()[numHeaderBytes - 3] = (mask >> 16) & 0xff;
-            buffer->data()[numHeaderBytes - 2] = (mask >> 8) & 0xff;
-            buffer->data()[numHeaderBytes - 1] = mask & 0xff;
-
-            for (size_t i = 0; i < (size_t)size; ++i) {
-                buffer->data()[numHeaderBytes + i] =
-                    ((const uint8_t *)data)[i]
-                        ^ ((mask >> (8 * (3 - (i % 4)))) & 0xff);
-            }
-        } else {
-            memcpy(buffer->data() + numHeaderBytes, data, size);
-        }
-    } else {
-        buffer = new ABuffer(size);
-        memcpy(buffer->data(), data, size);
-    }
-
-    Fragment frag;
-
-    frag.mFlags = 0;
-    if (timeValid) {
-        frag.mFlags = FRAGMENT_FLAG_TIME_VALID;
-        frag.mTimeUs = timeUs;
-    }
-
-    frag.mBuffer = buffer;
-
-    mOutFragments.push_back(frag);
-
-    return OK;
-}
-
-void ANetworkSession::Session::notifyError(
-        bool send, status_t err, const char *detail) {
-    sp<AMessage> msg = mNotify->dup();
-    msg->setInt32("sessionID", mSessionID);
-    msg->setInt32("reason", kWhatError);
-    msg->setInt32("send", send);
-    msg->setInt32("err", err);
-    msg->setString("detail", detail);
-    msg->post();
-}
-
-void ANetworkSession::Session::notify(NotificationReason reason) {
-    sp<AMessage> msg = mNotify->dup();
-    msg->setInt32("sessionID", mSessionID);
-    msg->setInt32("reason", reason);
-    msg->post();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-ANetworkSession::ANetworkSession()
-    : mNextSessionID(1) {
-    mPipeFd[0] = mPipeFd[1] = -1;
-}
-
-ANetworkSession::~ANetworkSession() {
-    stop();
-}
-
-status_t ANetworkSession::start() {
-    if (mThread != NULL) {
-        return INVALID_OPERATION;
-    }
-
-    int res = pipe(mPipeFd);
-    if (res != 0) {
-        mPipeFd[0] = mPipeFd[1] = -1;
-        return -errno;
-    }
-
-    mThread = new NetworkThread(this);
-
-    status_t err = mThread->run("ANetworkSession", ANDROID_PRIORITY_AUDIO);
-
-    if (err != OK) {
-        mThread.clear();
-
-        close(mPipeFd[0]);
-        close(mPipeFd[1]);
-        mPipeFd[0] = mPipeFd[1] = -1;
-
-        return err;
-    }
-
-    return OK;
-}
-
-status_t ANetworkSession::stop() {
-    if (mThread == NULL) {
-        return INVALID_OPERATION;
-    }
-
-    mThread->requestExit();
-    interrupt();
-    mThread->requestExitAndWait();
-
-    mThread.clear();
-
-    close(mPipeFd[0]);
-    close(mPipeFd[1]);
-    mPipeFd[0] = mPipeFd[1] = -1;
-
-    return OK;
-}
-
-status_t ANetworkSession::createRTSPClient(
-        const char *host, unsigned port, const sp<AMessage> &notify,
-        int32_t *sessionID) {
-    return createClientOrServer(
-            kModeCreateRTSPClient,
-            NULL /* addr */,
-            0 /* port */,
-            host,
-            port,
-            notify,
-            sessionID);
-}
-
-status_t ANetworkSession::createRTSPServer(
-        const struct in_addr &addr, unsigned port,
-        const sp<AMessage> &notify, int32_t *sessionID) {
-    return createClientOrServer(
-            kModeCreateRTSPServer,
-            &addr,
-            port,
-            NULL /* remoteHost */,
-            0 /* remotePort */,
-            notify,
-            sessionID);
-}
-
-status_t ANetworkSession::createUDPSession(
-        unsigned localPort, const sp<AMessage> &notify, int32_t *sessionID) {
-    return createUDPSession(localPort, NULL, 0, notify, sessionID);
-}
-
-status_t ANetworkSession::createUDPSession(
-        unsigned localPort,
-        const char *remoteHost,
-        unsigned remotePort,
-        const sp<AMessage> &notify,
-        int32_t *sessionID) {
-    return createClientOrServer(
-            kModeCreateUDPSession,
-            NULL /* addr */,
-            localPort,
-            remoteHost,
-            remotePort,
-            notify,
-            sessionID);
-}
-
-status_t ANetworkSession::createTCPDatagramSession(
-        const struct in_addr &addr, unsigned port,
-        const sp<AMessage> &notify, int32_t *sessionID) {
-    return createClientOrServer(
-            kModeCreateTCPDatagramSessionPassive,
-            &addr,
-            port,
-            NULL /* remoteHost */,
-            0 /* remotePort */,
-            notify,
-            sessionID);
-}
-
-status_t ANetworkSession::createTCPDatagramSession(
-        unsigned localPort,
-        const char *remoteHost,
-        unsigned remotePort,
-        const sp<AMessage> &notify,
-        int32_t *sessionID) {
-    return createClientOrServer(
-            kModeCreateTCPDatagramSessionActive,
-            NULL /* addr */,
-            localPort,
-            remoteHost,
-            remotePort,
-            notify,
-            sessionID);
-}
-
-status_t ANetworkSession::destroySession(int32_t sessionID) {
-    Mutex::Autolock autoLock(mLock);
-
-    ssize_t index = mSessions.indexOfKey(sessionID);
-
-    if (index < 0) {
-        return -ENOENT;
-    }
-
-    mSessions.removeItemsAt(index);
-
-    interrupt();
-
-    return OK;
-}
-
-// static
-status_t ANetworkSession::MakeSocketNonBlocking(int s) {
-    int flags = fcntl(s, F_GETFL, 0);
-    if (flags < 0) {
-        flags = 0;
-    }
-
-    int res = fcntl(s, F_SETFL, flags | O_NONBLOCK);
-    if (res < 0) {
-        return -errno;
-    }
-
-    return OK;
-}
-
-status_t ANetworkSession::createClientOrServer(
-        Mode mode,
-        const struct in_addr *localAddr,
-        unsigned port,
-        const char *remoteHost,
-        unsigned remotePort,
-        const sp<AMessage> &notify,
-        int32_t *sessionID) {
-    Mutex::Autolock autoLock(mLock);
-
-    *sessionID = 0;
-    status_t err = OK;
-    int s, res;
-    sp<Session> session;
-
-    s = socket(
-            AF_INET,
-            (mode == kModeCreateUDPSession) ? SOCK_DGRAM : SOCK_STREAM,
-            0);
-
-    if (s < 0) {
-        err = -errno;
-        goto bail;
-    }
-
-    if (mode == kModeCreateRTSPServer
-            || mode == kModeCreateTCPDatagramSessionPassive) {
-        const int yes = 1;
-        res = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
-
-        if (res < 0) {
-            err = -errno;
-            goto bail2;
-        }
-    }
-
-    if (mode == kModeCreateUDPSession) {
-        int size = 256 * 1024;
-
-        res = setsockopt(s, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
-
-        if (res < 0) {
-            err = -errno;
-            goto bail2;
-        }
-
-        res = setsockopt(s, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
-
-        if (res < 0) {
-            err = -errno;
-            goto bail2;
-        }
-    } else if (mode == kModeCreateTCPDatagramSessionActive) {
-        int flag = 1;
-        res = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));
-
-        if (res < 0) {
-            err = -errno;
-            goto bail2;
-        }
-
-        int tos = 224;  // VOICE
-        res = setsockopt(s, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
-
-        if (res < 0) {
-            err = -errno;
-            goto bail2;
-        }
-    }
-
-    err = MakeSocketNonBlocking(s);
-
-    if (err != OK) {
-        goto bail2;
-    }
-
-    struct sockaddr_in addr;
-    memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
-    addr.sin_family = AF_INET;
-
-    if (mode == kModeCreateRTSPClient
-            || mode == kModeCreateTCPDatagramSessionActive) {
-        struct hostent *ent= gethostbyname(remoteHost);
-        if (ent == NULL) {
-            err = -h_errno;
-            goto bail2;
-        }
-
-        addr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr;
-        addr.sin_port = htons(remotePort);
-    } else if (localAddr != NULL) {
-        addr.sin_addr = *localAddr;
-        addr.sin_port = htons(port);
-    } else {
-        addr.sin_addr.s_addr = htonl(INADDR_ANY);
-        addr.sin_port = htons(port);
-    }
-
-    if (mode == kModeCreateRTSPClient
-            || mode == kModeCreateTCPDatagramSessionActive) {
-        in_addr_t x = ntohl(addr.sin_addr.s_addr);
-        ALOGI("connecting socket %d to %d.%d.%d.%d:%d",
-              s,
-              (x >> 24),
-              (x >> 16) & 0xff,
-              (x >> 8) & 0xff,
-              x & 0xff,
-              ntohs(addr.sin_port));
-
-        res = connect(s, (const struct sockaddr *)&addr, sizeof(addr));
-
-        CHECK_LT(res, 0);
-        if (errno == EINPROGRESS) {
-            res = 0;
-        }
-    } else {
-        res = bind(s, (const struct sockaddr *)&addr, sizeof(addr));
-
-        if (res == 0) {
-            if (mode == kModeCreateRTSPServer
-                    || mode == kModeCreateTCPDatagramSessionPassive) {
-                res = listen(s, 4);
-            } else {
-                CHECK_EQ(mode, kModeCreateUDPSession);
-
-                if (remoteHost != NULL) {
-                    struct sockaddr_in remoteAddr;
-                    memset(remoteAddr.sin_zero, 0, sizeof(remoteAddr.sin_zero));
-                    remoteAddr.sin_family = AF_INET;
-                    remoteAddr.sin_port = htons(remotePort);
-
-                    struct hostent *ent= gethostbyname(remoteHost);
-                    if (ent == NULL) {
-                        err = -h_errno;
-                        goto bail2;
-                    }
-
-                    remoteAddr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr;
-
-                    res = connect(
-                            s,
-                            (const struct sockaddr *)&remoteAddr,
-                            sizeof(remoteAddr));
-                }
-            }
-        }
-    }
-
-    if (res < 0) {
-        err = -errno;
-        goto bail2;
-    }
-
-    Session::State state;
-    switch (mode) {
-        case kModeCreateRTSPClient:
-            state = Session::CONNECTING;
-            break;
-
-        case kModeCreateTCPDatagramSessionActive:
-            state = Session::CONNECTING;
-            break;
-
-        case kModeCreateTCPDatagramSessionPassive:
-            state = Session::LISTENING_TCP_DGRAMS;
-            break;
-
-        case kModeCreateRTSPServer:
-            state = Session::LISTENING_RTSP;
-            break;
-
-        default:
-            CHECK_EQ(mode, kModeCreateUDPSession);
-            state = Session::DATAGRAM;
-            break;
-    }
-
-    session = new Session(
-            mNextSessionID++,
-            state,
-            s,
-            notify);
-
-    if (mode == kModeCreateTCPDatagramSessionActive) {
-        session->setMode(Session::MODE_DATAGRAM);
-    } else if (mode == kModeCreateRTSPClient) {
-        session->setMode(Session::MODE_RTSP);
-    }
-
-    mSessions.add(session->sessionID(), session);
-
-    interrupt();
-
-    *sessionID = session->sessionID();
-
-    goto bail;
-
-bail2:
-    close(s);
-    s = -1;
-
-bail:
-    return err;
-}
-
-status_t ANetworkSession::connectUDPSession(
-        int32_t sessionID, const char *remoteHost, unsigned remotePort) {
-    Mutex::Autolock autoLock(mLock);
-
-    ssize_t index = mSessions.indexOfKey(sessionID);
-
-    if (index < 0) {
-        return -ENOENT;
-    }
-
-    const sp<Session> session = mSessions.valueAt(index);
-    int s = session->socket();
-
-    struct sockaddr_in remoteAddr;
-    memset(remoteAddr.sin_zero, 0, sizeof(remoteAddr.sin_zero));
-    remoteAddr.sin_family = AF_INET;
-    remoteAddr.sin_port = htons(remotePort);
-
-    status_t err = OK;
-    struct hostent *ent = gethostbyname(remoteHost);
-    if (ent == NULL) {
-        err = -h_errno;
-    } else {
-        remoteAddr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr;
-
-        int res = connect(
-                s,
-                (const struct sockaddr *)&remoteAddr,
-                sizeof(remoteAddr));
-
-        if (res < 0) {
-            err = -errno;
-        }
-    }
-
-    return err;
-}
-
-status_t ANetworkSession::sendRequest(
-        int32_t sessionID, const void *data, ssize_t size,
-        bool timeValid, int64_t timeUs) {
-    Mutex::Autolock autoLock(mLock);
-
-    ssize_t index = mSessions.indexOfKey(sessionID);
-
-    if (index < 0) {
-        return -ENOENT;
-    }
-
-    const sp<Session> session = mSessions.valueAt(index);
-
-    status_t err = session->sendRequest(data, size, timeValid, timeUs);
-
-    interrupt();
-
-    return err;
-}
-
-status_t ANetworkSession::switchToWebSocketMode(int32_t sessionID) {
-    Mutex::Autolock autoLock(mLock);
-
-    ssize_t index = mSessions.indexOfKey(sessionID);
-
-    if (index < 0) {
-        return -ENOENT;
-    }
-
-    const sp<Session> session = mSessions.valueAt(index);
-    return session->switchToWebSocketMode();
-}
-
-void ANetworkSession::interrupt() {
-    static const char dummy = 0;
-
-    ssize_t n;
-    do {
-        n = write(mPipeFd[1], &dummy, 1);
-    } while (n < 0 && errno == EINTR);
-
-    if (n < 0) {
-        ALOGW("Error writing to pipe (%s)", strerror(errno));
-    }
-}
-
-void ANetworkSession::threadLoop() {
-    fd_set rs, ws;
-    FD_ZERO(&rs);
-    FD_ZERO(&ws);
-
-    FD_SET(mPipeFd[0], &rs);
-    int maxFd = mPipeFd[0];
-
-    {
-        Mutex::Autolock autoLock(mLock);
-
-        for (size_t i = 0; i < mSessions.size(); ++i) {
-            const sp<Session> &session = mSessions.valueAt(i);
-
-            int s = session->socket();
-
-            if (s < 0) {
-                continue;
-            }
-
-            if (session->wantsToRead()) {
-                FD_SET(s, &rs);
-                if (s > maxFd) {
-                    maxFd = s;
-                }
-            }
-
-            if (session->wantsToWrite()) {
-                FD_SET(s, &ws);
-                if (s > maxFd) {
-                    maxFd = s;
-                }
-            }
-        }
-    }
-
-    int res = select(maxFd + 1, &rs, &ws, NULL, NULL /* tv */);
-
-    if (res == 0) {
-        return;
-    }
-
-    if (res < 0) {
-        if (errno == EINTR) {
-            return;
-        }
-
-        ALOGE("select failed w/ error %d (%s)", errno, strerror(errno));
-        return;
-    }
-
-    if (FD_ISSET(mPipeFd[0], &rs)) {
-        char c;
-        ssize_t n;
-        do {
-            n = read(mPipeFd[0], &c, 1);
-        } while (n < 0 && errno == EINTR);
-
-        if (n < 0) {
-            ALOGW("Error reading from pipe (%s)", strerror(errno));
-        }
-
-        --res;
-    }
-
-    {
-        Mutex::Autolock autoLock(mLock);
-
-        List<sp<Session> > sessionsToAdd;
-
-        for (size_t i = mSessions.size(); res > 0 && i > 0;) {
-            i--;
-            const sp<Session> &session = mSessions.valueAt(i);
-
-            int s = session->socket();
-
-            if (s < 0) {
-                continue;
-            }
-
-            if (FD_ISSET(s, &rs) || FD_ISSET(s, &ws)) {
-                --res;
-            }
-
-            if (FD_ISSET(s, &rs)) {
-                if (session->isRTSPServer() || session->isTCPDatagramServer()) {
-                    struct sockaddr_in remoteAddr;
-                    socklen_t remoteAddrLen = sizeof(remoteAddr);
-
-                    int clientSocket = accept(
-                            s, (struct sockaddr *)&remoteAddr, &remoteAddrLen);
-
-                    if (clientSocket >= 0) {
-                        status_t err = MakeSocketNonBlocking(clientSocket);
-
-                        if (err != OK) {
-                            ALOGE("Unable to make client socket non blocking, "
-                                  "failed w/ error %d (%s)",
-                                  err, strerror(-err));
-
-                            close(clientSocket);
-                            clientSocket = -1;
-                        } else {
-                            in_addr_t addr = ntohl(remoteAddr.sin_addr.s_addr);
-
-                            ALOGI("incoming connection from %d.%d.%d.%d:%d "
-                                  "(socket %d)",
-                                  (addr >> 24),
-                                  (addr >> 16) & 0xff,
-                                  (addr >> 8) & 0xff,
-                                  addr & 0xff,
-                                  ntohs(remoteAddr.sin_port),
-                                  clientSocket);
-
-                            sp<Session> clientSession =
-                                new Session(
-                                        mNextSessionID++,
-                                        Session::CONNECTED,
-                                        clientSocket,
-                                        session->getNotificationMessage());
-
-                            clientSession->setMode(
-                                    session->isRTSPServer()
-                                        ? Session::MODE_RTSP
-                                        : Session::MODE_DATAGRAM);
-
-                            sessionsToAdd.push_back(clientSession);
-                        }
-                    } else {
-                        ALOGE("accept returned error %d (%s)",
-                              errno, strerror(errno));
-                    }
-                } else {
-                    status_t err = session->readMore();
-                    if (err != OK) {
-                        ALOGE("readMore on socket %d failed w/ error %d (%s)",
-                              s, err, strerror(-err));
-                    }
-                }
-            }
-
-            if (FD_ISSET(s, &ws)) {
-                status_t err = session->writeMore();
-                if (err != OK) {
-                    ALOGE("writeMore on socket %d failed w/ error %d (%s)",
-                          s, err, strerror(-err));
-                }
-            }
-        }
-
-        while (!sessionsToAdd.empty()) {
-            sp<Session> session = *sessionsToAdd.begin();
-            sessionsToAdd.erase(sessionsToAdd.begin());
-
-            mSessions.add(session->sessionID(), session);
-
-            ALOGI("added clientSession %d", session->sessionID());
-        }
-    }
-}
-
-}  // namespace android
diff --git a/media/libstagefright/foundation/AString.cpp b/media/libstagefright/foundation/AString.cpp
index 04fac19..fb51cc5 100644
--- a/media/libstagefright/foundation/AString.cpp
+++ b/media/libstagefright/foundation/AString.cpp
@@ -31,7 +31,7 @@
 namespace android {
 
 // static
-const char *AString::kEmptyString = "";
+constexpr const char *AString::kEmptyString;
 
 AString::AString()
     : mData((char *)kEmptyString),
@@ -125,12 +125,10 @@
 }
 
 void AString::clear() {
-    if (mData && mData != kEmptyString) {
+    if (mData != kEmptyString) {
         free(mData);
-        mData = NULL;
+        mData = (char *)kEmptyString;
     }
-
-    mData = (char *)kEmptyString;
     mSize = 0;
     mAllocSize = 1;
 }
@@ -367,6 +365,8 @@
 // static
 AString AString::FromParcel(const Parcel &parcel) {
     size_t size = static_cast<size_t>(parcel.readInt32());
+    // The static analyzer incorrectly reports a false-positive here in c++17.
+    // https://bugs.llvm.org/show_bug.cgi?id=38176 . NOLINTNEXTLINE
     return AString(static_cast<const char *>(parcel.readInplace(size)), size);
 }
 
diff --git a/media/libstagefright/foundation/Android.bp b/media/libstagefright/foundation/Android.bp
index f663542..533cd72 100644
--- a/media/libstagefright/foundation/Android.bp
+++ b/media/libstagefright/foundation/Android.bp
@@ -4,12 +4,13 @@
     vendor_available: true,
 }
 
-cc_library {
-    name: "libstagefright_foundation",
+cc_defaults {
+    name: "libstagefright_foundation_defaults",
     vendor_available: true,
     vndk: {
         enabled: true,
     },
+    double_loadable: true,
     include_dirs: [
         "frameworks/av/include",
         "frameworks/native/include",
@@ -24,6 +25,7 @@
     header_libs: [
         "libhardware_headers",
         "libstagefright_foundation_headers",
+        "media_ndk_headers",
         "media_plugin_headers",
     ],
 
@@ -55,18 +57,22 @@
         "ABuffer.cpp",
         "ADebug.cpp",
         "AHandler.cpp",
-        "AHierarchicalStateMachine.cpp",
         "ALooper.cpp",
         "ALooperRoster.cpp",
         "AMessage.cpp",
-        "ANetworkSession.cpp",
         "AString.cpp",
         "AStringUtils.cpp",
+        "AudioPresentationInfo.cpp",
         "ByteUtils.cpp",
         "ColorUtils.cpp",
+        "MediaBuffer.cpp",
+        "MediaBufferBase.cpp",
+        "MediaBufferGroup.cpp",
         "MediaDefs.cpp",
         "MediaKeys.cpp",
-        "ParsedMessage.cpp",
+        "MetaData.cpp",
+        "MetaDataBase.cpp",
+        "OpusHeader.cpp",
         "avc_utils.cpp",
         "base64.cpp",
         "hexdump.cpp",
@@ -80,8 +86,22 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 }
+
+cc_library {
+    name: "libstagefright_foundation",
+    defaults: ["libstagefright_foundation_defaults"],
+}
+
+cc_library_static {
+    name: "libstagefright_foundation_without_imemory",
+    defaults: ["libstagefright_foundation_defaults"],
+
+    cflags: [
+        "-Wno-multichar",
+        "-Werror",
+        "-Wall",
+        "-DNO_IMEMORY",
+    ],
+}
diff --git a/media/libstagefright/foundation/AudioPresentationInfo.cpp b/media/libstagefright/foundation/AudioPresentationInfo.cpp
new file mode 100644
index 0000000..4b8e969
--- /dev/null
+++ b/media/libstagefright/foundation/AudioPresentationInfo.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// #define LOG_NDEBUG 0
+#define LOG_TAG "AudioPresentationInfo"
+
+#include <vector>
+
+#include "AudioPresentationInfo.h"
+
+#include <utils/Log.h>
+
+namespace android {
+
+void serializeAudioPresentations(const AudioPresentationCollection& presentations,
+        std::ostream* serializedOutput) {
+    uint32_t numPresentations = presentations.size();
+    serializedOutput->write(reinterpret_cast<char*>(&numPresentations), sizeof(numPresentations));
+    for (const auto& ap : presentations) {
+        if (ap.mVersion == PRESENTATION_VERSION_1) {
+            serializedOutput->write(
+                    const_cast<char*>(reinterpret_cast<const char*>(&ap.mVersion)),
+                    sizeof(ap.mVersion));
+            serializedOutput->write(
+                    const_cast<char*>(reinterpret_cast<const char*>(&ap.mPresentationId)),
+                    sizeof(ap.mPresentationId));
+            serializedOutput->write(
+                    const_cast<char*>(reinterpret_cast<const char*>(&ap.mProgramId)),
+                    sizeof(ap.mProgramId));
+
+            uint32_t numLabels = ap.mLabels.size();
+            serializedOutput->write(
+                    const_cast<char*>(reinterpret_cast<const char*>(&numLabels)),
+                    sizeof(numLabels));
+            for (const auto& label : ap.mLabels) {
+                uint32_t labelKeySize = label.first.size();
+                serializedOutput->write(
+                        const_cast<char*>(reinterpret_cast<const char*>(&labelKeySize)),
+                        sizeof(labelKeySize));
+                serializedOutput->write(label.first.c_str(), labelKeySize);
+
+                uint32_t labelValSize = label.second.size();
+                serializedOutput->write(
+                        const_cast<char*>(reinterpret_cast<const char*>(&labelValSize)),
+                        sizeof(labelValSize));
+                serializedOutput->write(label.second.c_str(), labelValSize);
+            }
+
+            uint32_t langSize = ap.mLanguage.size();
+            serializedOutput->write(
+                    const_cast<char*>(reinterpret_cast<const char*>(&langSize)),
+                    sizeof(langSize));
+            serializedOutput->write(ap.mLanguage.c_str(), langSize);
+
+            serializedOutput->write(
+                    const_cast<char*>(reinterpret_cast<const char*>(&ap.mMasteringIndication)),
+                    sizeof(ap.mMasteringIndication));
+            serializedOutput->write(
+                    const_cast<char*>(reinterpret_cast<const char*>(&ap.mAudioDescriptionAvailable)),
+                    sizeof(ap.mAudioDescriptionAvailable));
+            serializedOutput->write(
+                    const_cast<char*>(reinterpret_cast<const char*>(&ap.mSpokenSubtitlesAvailable)),
+                    sizeof(ap.mSpokenSubtitlesAvailable));
+            serializedOutput->write(
+                    const_cast<char*>(reinterpret_cast<const char*>(&ap.mDialogueEnhancementAvailable)),
+                    sizeof(ap.mDialogueEnhancementAvailable));
+        }
+    }
+}
+
+status_t deserializeAudioPresentations(std::istream* serializedInput,
+        AudioPresentationCollection *presentations) {
+    uint32_t numPresentations;
+    serializedInput->read(reinterpret_cast<char*>(&numPresentations), sizeof(numPresentations));
+    for (uint32_t i = 0; i < numPresentations; ++i) {
+        uint32_t version;
+        serializedInput->read(reinterpret_cast<char*>(&version), sizeof(version));
+        if (version == PRESENTATION_VERSION_1) {
+            AudioPresentationV1 ap;
+            serializedInput->read(
+                    reinterpret_cast<char*>(&ap.mPresentationId),
+                    sizeof(ap.mPresentationId));
+            serializedInput->read(reinterpret_cast<char*>(&ap.mProgramId), sizeof(ap.mProgramId));
+
+            uint32_t numLabels;
+            serializedInput->read(reinterpret_cast<char*>(&numLabels), sizeof(numLabels));
+            for (uint32_t j = 0; j < numLabels; ++j) {
+                uint32_t labelKeySize;
+                serializedInput->read(reinterpret_cast<char*>(&labelKeySize), sizeof(labelKeySize));
+                std::vector<char> labelKey(labelKeySize);
+                serializedInput->read(labelKey.data(), labelKeySize);
+
+                uint32_t labelValSize;
+                serializedInput->read(reinterpret_cast<char*>(&labelValSize), sizeof(labelValSize));
+                std::vector<char> labelVal(labelValSize);
+                serializedInput->read(labelVal.data(), labelValSize);
+                ap.mLabels.emplace(
+                        std::string(reinterpret_cast<char*>(labelKey.data()), labelKeySize),
+                        std::string(reinterpret_cast<char*>(labelVal.data()), labelValSize));
+            }
+            uint32_t languageSize;
+            serializedInput->read(reinterpret_cast<char*>(&languageSize), sizeof(languageSize));
+            std::vector<char> language(languageSize);
+            serializedInput->read(language.data(), languageSize);
+            ap.mLanguage = std::string(reinterpret_cast<char*>(language.data()), languageSize);
+            serializedInput->read(reinterpret_cast<char*>(&ap.mMasteringIndication),
+                                 sizeof(ap.mMasteringIndication));
+            serializedInput->read(reinterpret_cast<char*>(&ap.mAudioDescriptionAvailable),
+                                 sizeof(ap.mAudioDescriptionAvailable));
+            serializedInput->read(reinterpret_cast<char*>(&ap.mSpokenSubtitlesAvailable),
+                                 sizeof(ap.mSpokenSubtitlesAvailable));
+            serializedInput->read(reinterpret_cast<char*>(&ap.mDialogueEnhancementAvailable),
+                                 sizeof(ap.mDialogueEnhancementAvailable));
+            presentations->push_back(std::move(ap));
+        } else {
+            ALOGE("Audio presentation info version is not supported");
+            return INVALID_OPERATION;
+        }
+    }
+    return OK;
+}
+
+}  // namespace android
diff --git a/media/libstagefright/foundation/ColorUtils.cpp b/media/libstagefright/foundation/ColorUtils.cpp
index c4eaa27..070e325 100644
--- a/media/libstagefright/foundation/ColorUtils.cpp
+++ b/media/libstagefright/foundation/ColorUtils.cpp
@@ -23,6 +23,7 @@
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ALookup.h>
 #include <media/stagefright/foundation/ColorUtils.h>
+#include <media/NdkMediaFormatPriv.h>
 
 namespace android {
 
@@ -342,6 +343,14 @@
     aspects.mRange = fullRange ? ColorAspects::RangeFull : ColorAspects::RangeLimited;
 }
 
+void ColorUtils::convertIsoColorAspectsToPlatformAspects(
+        int32_t primaries, int32_t intransfer, int32_t coeffs, bool fullRange,
+        int32_t *range, int32_t *standard, int32_t *outtransfer) {
+    ColorAspects aspects;
+    convertIsoColorAspectsToCodecAspects(primaries, intransfer, coeffs, fullRange, aspects);
+    convertCodecColorAspectsToPlatformAspects(aspects, range, standard, outtransfer);
+}
+
 // static
 ColorAspects ColorUtils::unpackToColorAspects(uint32_t packed) {
     ColorAspects aspects;
@@ -684,6 +693,13 @@
             transfer, asString((ColorTransfer)transfer));
 }
 
+
+// static
+void ColorUtils::setHDRStaticInfoIntoAMediaFormat(
+        const HDRStaticInfo &info, AMediaFormat *format) {
+    setHDRStaticInfoIntoFormat(info, format->mFormat);
+}
+
 // static
 void ColorUtils::setHDRStaticInfoIntoFormat(
         const HDRStaticInfo &info, sp<AMessage> &format) {
diff --git a/media/libstagefright/foundation/MediaBuffer.cpp b/media/libstagefright/foundation/MediaBuffer.cpp
new file mode 100644
index 0000000..9beac05
--- /dev/null
+++ b/media/libstagefright/foundation/MediaBuffer.cpp
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "MediaBuffer"
+#include <utils/Log.h>
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdlib.h>
+
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MetaData.h>
+
+namespace android {
+
+/* static */
+std::atomic_int_least32_t MediaBuffer::mUseSharedMemory(0);
+
+MediaBuffer::MediaBuffer(void *data, size_t size)
+    : mObserver(NULL),
+      mRefCount(0),
+      mData(data),
+      mSize(size),
+      mRangeOffset(0),
+      mRangeLength(size),
+      mOwnsData(false),
+      mMetaData(new MetaDataBase) {
+}
+
+MediaBuffer::MediaBuffer(size_t size)
+    : mObserver(NULL),
+      mRefCount(0),
+      mData(NULL),
+      mSize(size),
+      mRangeOffset(0),
+      mRangeLength(size),
+      mOwnsData(true),
+      mMetaData(new MetaDataBase) {
+#ifndef NO_IMEMORY
+    if (size < kSharedMemThreshold
+            || std::atomic_load_explicit(&mUseSharedMemory, std::memory_order_seq_cst) == 0) {
+#endif
+        mData = malloc(size);
+#ifndef NO_IMEMORY
+    } else {
+        ALOGV("creating memoryDealer");
+        size_t newSize = 0;
+        if (!__builtin_add_overflow(size, sizeof(SharedControl), &newSize)) {
+            sp<MemoryDealer> memoryDealer = new MemoryDealer(newSize, "MediaBuffer");
+            mMemory = memoryDealer->allocate(newSize);
+        }
+        if (mMemory == NULL) {
+            ALOGW("Failed to allocate shared memory, trying regular allocation!");
+            mData = malloc(size);
+            if (mData == NULL) {
+                ALOGE("Out of memory");
+            }
+        } else {
+            getSharedControl()->clear();
+            mData = (uint8_t *)mMemory->pointer() + sizeof(SharedControl);
+            ALOGV("Allocated shared mem buffer of size %zu @ %p", size, mData);
+        }
+    }
+#endif
+}
+
+MediaBuffer::MediaBuffer(const sp<ABuffer> &buffer)
+    : mObserver(NULL),
+      mRefCount(0),
+      mData(buffer->data()),
+      mSize(buffer->size()),
+      mRangeOffset(0),
+      mRangeLength(mSize),
+      mBuffer(buffer),
+      mOwnsData(false),
+      mMetaData(new MetaDataBase) {
+}
+
+void MediaBuffer::release() {
+    if (mObserver == NULL) {
+        // Legacy contract for MediaBuffer without a MediaBufferGroup.
+        CHECK_EQ(mRefCount, 0);
+        delete this;
+        return;
+    }
+
+    int prevCount = mRefCount.fetch_sub(1);
+    if (prevCount == 1) {
+        if (mObserver == NULL) {
+            delete this;
+            return;
+        }
+
+        mObserver->signalBufferReturned(this);
+    }
+    CHECK(prevCount > 0);
+}
+
+void MediaBuffer::claim() {
+    CHECK(mObserver != NULL);
+    CHECK_EQ(mRefCount.load(std::memory_order_relaxed), 1);
+
+    mRefCount.store(0, std::memory_order_relaxed);
+}
+
+void MediaBuffer::add_ref() {
+    (void) mRefCount.fetch_add(1);
+}
+
+void *MediaBuffer::data() const {
+    return mData;
+}
+
+size_t MediaBuffer::size() const {
+    return mSize;
+}
+
+size_t MediaBuffer::range_offset() const {
+    return mRangeOffset;
+}
+
+size_t MediaBuffer::range_length() const {
+    return mRangeLength;
+}
+
+void MediaBuffer::set_range(size_t offset, size_t length) {
+    if (offset + length > mSize) {
+        ALOGE("offset = %zu, length = %zu, mSize = %zu", offset, length, mSize);
+    }
+    CHECK(offset + length <= mSize);
+
+    mRangeOffset = offset;
+    mRangeLength = length;
+}
+
+MetaDataBase& MediaBuffer::meta_data() {
+    return *mMetaData;
+}
+
+void MediaBuffer::reset() {
+    mMetaData->clear();
+    set_range(0, mSize);
+}
+
+MediaBuffer::~MediaBuffer() {
+    CHECK(mObserver == NULL);
+
+    if (mOwnsData && mData != NULL && mMemory == NULL) {
+        free(mData);
+        mData = NULL;
+    }
+
+   if (mMemory.get() != nullptr) {
+       getSharedControl()->setDeadObject();
+   }
+   delete mMetaData;
+}
+
+void MediaBuffer::setObserver(MediaBufferObserver *observer) {
+    CHECK(observer == NULL || mObserver == NULL);
+    mObserver = observer;
+}
+
+}  // namespace android
diff --git a/media/libmediaextractor/MediaBufferBase.cpp b/media/libstagefright/foundation/MediaBufferBase.cpp
similarity index 100%
rename from media/libmediaextractor/MediaBufferBase.cpp
rename to media/libstagefright/foundation/MediaBufferBase.cpp
diff --git a/media/libstagefright/foundation/MediaBufferGroup.cpp b/media/libstagefright/foundation/MediaBufferGroup.cpp
new file mode 100644
index 0000000..84ff9a6
--- /dev/null
+++ b/media/libstagefright/foundation/MediaBufferGroup.cpp
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "MediaBufferGroup"
+#include <utils/Log.h>
+
+#include <list>
+
+#include <binder/MemoryDealer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaBufferGroup.h>
+#include <utils/threads.h>
+
+namespace android {
+
+// std::min is not constexpr in C++11
+template<typename T>
+constexpr T MIN(const T &a, const T &b) { return a <= b ? a : b; }
+
+// MediaBufferGroup may create shared memory buffers at a
+// smaller threshold than an isolated new MediaBuffer.
+static const size_t kSharedMemoryThreshold = MIN(
+        (size_t)MediaBuffer::kSharedMemThreshold, (size_t)(4 * 1024));
+
+struct MediaBufferGroup::InternalData {
+    Mutex mLock;
+    Condition mCondition;
+    size_t mGrowthLimit;  // Do not automatically grow group larger than this.
+    std::list<MediaBufferBase *> mBuffers;
+};
+
+MediaBufferGroup::MediaBufferGroup(size_t growthLimit)
+    : mWrapper(nullptr), mInternal(new InternalData()) {
+    mInternal->mGrowthLimit = growthLimit;
+}
+
+MediaBufferGroup::MediaBufferGroup(size_t buffers, size_t buffer_size, size_t growthLimit)
+    : mWrapper(nullptr), mInternal(new InternalData()) {
+    init(buffers, buffer_size, growthLimit);
+}
+
+void MediaBufferGroup::init(size_t buffers, size_t buffer_size, size_t growthLimit) {
+    mInternal->mGrowthLimit = growthLimit;
+
+    if (mInternal->mGrowthLimit > 0 && buffers > mInternal->mGrowthLimit) {
+        ALOGW("Preallocated buffers %zu > growthLimit %zu, increasing growthLimit",
+                buffers, mInternal->mGrowthLimit);
+        mInternal->mGrowthLimit = buffers;
+    }
+
+#ifndef NO_IMEMORY
+    if (buffer_size >= kSharedMemoryThreshold) {
+        ALOGD("creating MemoryDealer");
+        // Using a single MemoryDealer is efficient for a group of shared memory objects.
+        // This loop guarantees that we use shared memory (no fallback to malloc).
+
+        size_t alignment = MemoryDealer::getAllocationAlignment();
+        size_t augmented_size = buffer_size + sizeof(MediaBuffer::SharedControl);
+        size_t total = (augmented_size + alignment - 1) / alignment * alignment * buffers;
+        sp<MemoryDealer> memoryDealer = new MemoryDealer(total, "MediaBufferGroup");
+
+        for (size_t i = 0; i < buffers; ++i) {
+            sp<IMemory> mem = memoryDealer->allocate(augmented_size);
+            if (mem.get() == nullptr || mem->pointer() == nullptr) {
+                ALOGW("Only allocated %zu shared buffers of size %zu", i, buffer_size);
+                break;
+            }
+            MediaBuffer *buffer = new MediaBuffer(mem);
+            buffer->getSharedControl()->clear();
+            add_buffer(buffer);
+        }
+        return;
+    }
+#else
+    (void)kSharedMemoryThreshold;
+#endif
+
+    // Non-shared memory allocation.
+    for (size_t i = 0; i < buffers; ++i) {
+        MediaBuffer *buffer = new MediaBuffer(buffer_size);
+        if (buffer->data() == nullptr) {
+            delete buffer; // don't call release, it's not properly formed
+            ALOGW("Only allocated %zu malloc buffers of size %zu", i, buffer_size);
+            break;
+        }
+        add_buffer(buffer);
+    }
+}
+
+MediaBufferGroup::~MediaBufferGroup() {
+    for (MediaBufferBase *buffer : mInternal->mBuffers) {
+        if (buffer->refcount() != 0) {
+            const int localRefcount = buffer->localRefcount();
+            const int remoteRefcount = buffer->remoteRefcount();
+
+            // Fatal if we have a local refcount.
+            LOG_ALWAYS_FATAL_IF(localRefcount != 0,
+                    "buffer(%p) localRefcount %d != 0, remoteRefcount %d",
+                    buffer, localRefcount, remoteRefcount);
+
+            // Log an error if we have a remaining remote refcount,
+            // as the remote process may have died or may have inappropriate behavior.
+            // The shared memory associated with the MediaBuffer will
+            // automatically be reclaimed when there are no remaining fds
+            // associated with it.
+            ALOGE("buffer(%p) has residual remoteRefcount %d",
+                    buffer, remoteRefcount);
+        }
+        // gracefully delete.
+        buffer->setObserver(nullptr);
+        buffer->release();
+    }
+    delete mInternal;
+    delete mWrapper;
+}
+
+void MediaBufferGroup::add_buffer(MediaBufferBase *buffer) {
+    Mutex::Autolock autoLock(mInternal->mLock);
+
+    // if we're above our growth limit, release buffers if we can
+    for (auto it = mInternal->mBuffers.begin();
+            mInternal->mGrowthLimit > 0
+            && mInternal->mBuffers.size() >= mInternal->mGrowthLimit
+            && it != mInternal->mBuffers.end();) {
+        if ((*it)->refcount() == 0) {
+            (*it)->setObserver(nullptr);
+            (*it)->release();
+            it = mInternal->mBuffers.erase(it);
+        } else {
+            ++it;
+        }
+    }
+
+    buffer->setObserver(this);
+    mInternal->mBuffers.emplace_back(buffer);
+}
+
+bool MediaBufferGroup::has_buffers() {
+    if (mInternal->mBuffers.size() < mInternal->mGrowthLimit) {
+        return true; // We can add more buffers internally.
+    }
+    for (MediaBufferBase *buffer : mInternal->mBuffers) {
+        if (buffer->refcount() == 0) {
+            return true;
+        }
+    }
+    return false;
+}
+
+status_t MediaBufferGroup::acquire_buffer(
+        MediaBufferBase **out, bool nonBlocking, size_t requestedSize) {
+    Mutex::Autolock autoLock(mInternal->mLock);
+    for (;;) {
+        size_t smallest = requestedSize;
+        size_t biggest = requestedSize;
+        MediaBufferBase *buffer = nullptr;
+        auto free = mInternal->mBuffers.end();
+        for (auto it = mInternal->mBuffers.begin(); it != mInternal->mBuffers.end(); ++it) {
+            const size_t size = (*it)->size();
+            if (size > biggest) {
+                biggest = size;
+            }
+            if ((*it)->refcount() == 0) {
+                if (size >= requestedSize) {
+                    buffer = *it;
+                    break;
+                }
+                if (size < smallest) {
+                    smallest = size; // always free the smallest buf
+                    free = it;
+                }
+            }
+        }
+        if (buffer == nullptr
+                && (free != mInternal->mBuffers.end()
+                    || mInternal->mBuffers.size() < mInternal->mGrowthLimit)) {
+            // We alloc before we free so failure leaves group unchanged.
+            const size_t allocateSize = requestedSize == 0 ? biggest :
+                    requestedSize < SIZE_MAX / 3 * 2 /* NB: ordering */ ?
+                    requestedSize * 3 / 2 : requestedSize;
+            buffer = new MediaBuffer(allocateSize);
+            if (buffer->data() == nullptr) {
+                ALOGE("Allocation failure for size %zu", allocateSize);
+                delete buffer; // Invalid alloc, prefer not to call release.
+                buffer = nullptr;
+            } else {
+                buffer->setObserver(this);
+                if (free != mInternal->mBuffers.end()) {
+                    ALOGV("reallocate buffer, requested size %zu vs available %zu",
+                            requestedSize, (*free)->size());
+                    (*free)->setObserver(nullptr);
+                    (*free)->release();
+                    *free = buffer; // in-place replace
+                } else {
+                    ALOGV("allocate buffer, requested size %zu", requestedSize);
+                    mInternal->mBuffers.emplace_back(buffer);
+                }
+            }
+        }
+        if (buffer != nullptr) {
+            buffer->add_ref();
+            buffer->reset();
+            *out = buffer;
+            return OK;
+        }
+        if (nonBlocking) {
+            *out = nullptr;
+            return WOULD_BLOCK;
+        }
+        // All buffers are in use, block until one of them is returned.
+        mInternal->mCondition.wait(mInternal->mLock);
+    }
+    // Never gets here.
+}
+
+size_t MediaBufferGroup::buffers() const {
+    return mInternal->mBuffers.size();
+}
+
+void MediaBufferGroup::signalBufferReturned(MediaBufferBase *) {
+    Mutex::Autolock autoLock(mInternal->mLock);
+    mInternal->mCondition.signal();
+}
+
+}  // namespace android
diff --git a/media/libstagefright/foundation/MediaDefs.cpp b/media/libstagefright/foundation/MediaDefs.cpp
index 1695c75..a08fed1 100644
--- a/media/libstagefright/foundation/MediaDefs.cpp
+++ b/media/libstagefright/foundation/MediaDefs.cpp
@@ -23,6 +23,7 @@
 
 const char *MEDIA_MIMETYPE_VIDEO_VP8 = "video/x-vnd.on2.vp8";
 const char *MEDIA_MIMETYPE_VIDEO_VP9 = "video/x-vnd.on2.vp9";
+const char *MEDIA_MIMETYPE_VIDEO_AV1 = "video/av01";
 const char *MEDIA_MIMETYPE_VIDEO_AVC = "video/avc";
 const char *MEDIA_MIMETYPE_VIDEO_HEVC = "video/hevc";
 const char *MEDIA_MIMETYPE_VIDEO_MPEG4 = "video/mp4v-es";
@@ -31,6 +32,10 @@
 const char *MEDIA_MIMETYPE_VIDEO_RAW = "video/raw";
 const char *MEDIA_MIMETYPE_VIDEO_DOLBY_VISION = "video/dolby-vision";
 const char *MEDIA_MIMETYPE_VIDEO_SCRAMBLED = "video/scrambled";
+const char *MEDIA_MIMETYPE_VIDEO_DIVX = "video/divx";
+const char *MEDIA_MIMETYPE_VIDEO_DIVX3 = "video/divx3";
+const char *MEDIA_MIMETYPE_VIDEO_XVID = "video/xvid";
+const char *MEDIA_MIMETYPE_VIDEO_MJPEG = "video/x-motion-jpeg";
 
 const char *MEDIA_MIMETYPE_AUDIO_AMR_NB = "audio/3gpp";
 const char *MEDIA_MIMETYPE_AUDIO_AMR_WB = "audio/amr-wb";
@@ -50,11 +55,18 @@
 const char *MEDIA_MIMETYPE_AUDIO_MSGSM = "audio/gsm";
 const char *MEDIA_MIMETYPE_AUDIO_AC3 = "audio/ac3";
 const char *MEDIA_MIMETYPE_AUDIO_EAC3 = "audio/eac3";
+const char *MEDIA_MIMETYPE_AUDIO_EAC3_JOC = "audio/eac3-joc";
+const char *MEDIA_MIMETYPE_AUDIO_AC4 = "audio/ac4";
 const char *MEDIA_MIMETYPE_AUDIO_SCRAMBLED = "audio/scrambled";
+const char *MEDIA_MIMETYPE_AUDIO_ALAC = "audio/alac";
+const char *MEDIA_MIMETYPE_AUDIO_WMA = "audio/x-ms-wma";
+const char *MEDIA_MIMETYPE_AUDIO_MS_ADPCM = "audio/x-adpcm-ms";
+const char *MEDIA_MIMETYPE_AUDIO_DVI_IMA_ADPCM = "audio/x-adpcm-dvi-ima";
+
 
 const char *MEDIA_MIMETYPE_CONTAINER_MPEG4 = "video/mp4";
 const char *MEDIA_MIMETYPE_CONTAINER_WAV = "audio/x-wav";
-const char *MEDIA_MIMETYPE_CONTAINER_OGG = "application/ogg";
+const char *MEDIA_MIMETYPE_CONTAINER_OGG = "audio/ogg";
 const char *MEDIA_MIMETYPE_CONTAINER_MATROSKA = "video/x-matroska";
 const char *MEDIA_MIMETYPE_CONTAINER_MPEG2TS = "video/mp2ts";
 const char *MEDIA_MIMETYPE_CONTAINER_AVI = "video/avi";
diff --git a/media/libmediaextractor/MetaData.cpp b/media/libstagefright/foundation/MetaData.cpp
similarity index 100%
rename from media/libmediaextractor/MetaData.cpp
rename to media/libstagefright/foundation/MetaData.cpp
diff --git a/media/libmediaextractor/MetaDataBase.cpp b/media/libstagefright/foundation/MetaDataBase.cpp
similarity index 100%
rename from media/libmediaextractor/MetaDataBase.cpp
rename to media/libstagefright/foundation/MetaDataBase.cpp
diff --git a/media/libstagefright/foundation/OpusHeader.cpp b/media/libstagefright/foundation/OpusHeader.cpp
new file mode 100644
index 0000000..513e41f
--- /dev/null
+++ b/media/libstagefright/foundation/OpusHeader.cpp
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "OpusHeader"
+#include <cstring>
+#include <inttypes.h>
+#include <stdint.h>
+
+#include <log/log.h>
+
+#include "OpusHeader.h"
+
+namespace android {
+
+// Opus uses Vorbis channel mapping, and Vorbis channel mapping specifies
+// mappings for up to 8 channels. This information is part of the Vorbis I
+// Specification:
+// http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html
+constexpr int kMaxChannels = 8;
+
+constexpr uint8_t kOpusChannelMap[kMaxChannels][kMaxChannels] = {
+        {0},
+        {0, 1},
+        {0, 2, 1},
+        {0, 1, 2, 3},
+        {0, 4, 1, 2, 3},
+        {0, 4, 1, 2, 3, 5},
+        {0, 4, 1, 2, 3, 5, 6},
+        {0, 6, 1, 2, 3, 4, 5, 7},
+};
+
+// Size of the Opus header excluding optional mapping information.
+constexpr size_t kOpusHeaderSize = 19;
+// Offset to magic string that starts Opus header.
+constexpr size_t kOpusHeaderLabelOffset = 0;
+// Offset to Opus version in the Opus header.
+constexpr size_t kOpusHeaderVersionOffset = 8;
+// Offset to the channel count byte in the Opus header.
+constexpr size_t kOpusHeaderChannelsOffset = 9;
+// Offset to the pre-skip value in the Opus header.
+constexpr size_t kOpusHeaderSkipSamplesOffset = 10;
+// Offset to sample rate in the Opus header.
+constexpr size_t kOpusHeaderSampleRateOffset = 12;
+// Offset to the gain value in the Opus header.
+constexpr size_t kOpusHeaderGainOffset = 16;
+// Offset to the channel mapping byte in the Opus header.
+constexpr size_t kOpusHeaderChannelMappingOffset = 18;
+// Opus Header contains a stream map. The mapping values are in the header
+// beyond the always present |kOpusHeaderSize| bytes of data. The mapping
+// data contains stream count, coupling information, and per channel mapping
+// values:
+//   - Byte 0: Number of streams.
+//   - Byte 1: Number coupled.
+//   - Byte 2: Starting at byte 2 are |header->channels| uint8 mapping
+//             values.
+// Offset to the number of streams in the Opus header.
+constexpr size_t kOpusHeaderNumStreamsOffset = 19;
+// Offset to the number of streams that are coupled in the Opus header.
+constexpr size_t kOpusHeaderNumCoupledStreamsOffset = 20;
+// Offset to the stream to channel mapping in the Opus header.
+constexpr size_t kOpusHeaderStreamMapOffset = 21;
+
+// Default audio output channel layout. Used to initialize |stream_map| in
+// OpusHeader, and passed to opus_multistream_decoder_create() when the header
+// does not contain mapping information. The values are valid only for mono and
+// stereo output: Opus streams with more than 2 channels require a stream map.
+constexpr int kMaxChannelsWithDefaultLayout = 2;
+
+static uint16_t ReadLE16(const uint8_t* data, size_t data_size, uint32_t read_offset) {
+    // check whether the 2nd byte is within the buffer
+    if (read_offset + 1 >= data_size) return 0;
+    uint16_t val;
+    val = data[read_offset];
+    val |= data[read_offset + 1] << 8;
+    return val;
+}
+
+// Parses Opus Header. Header spec: http://wiki.xiph.org/OggOpus#ID_Header
+bool ParseOpusHeader(const uint8_t* data, size_t data_size, OpusHeader* header) {
+    if (data == NULL) {
+        return false;
+    }
+    if (data_size < kOpusHeaderSize) {
+        ALOGV("Header size is too small.");
+        return false;
+    }
+    header->channels = data[kOpusHeaderChannelsOffset];
+
+    if (header->channels < 1 || header->channels > kMaxChannels) {
+        ALOGV("Invalid Header, bad channel count: %d", header->channels);
+        return false;
+    }
+    header->skip_samples = ReadLE16(data, data_size, kOpusHeaderSkipSamplesOffset);
+    header->gain_db = static_cast<int16_t>(ReadLE16(data, data_size, kOpusHeaderGainOffset));
+    header->channel_mapping = data[kOpusHeaderChannelMappingOffset];
+    if (!header->channel_mapping) {
+        if (header->channels > kMaxChannelsWithDefaultLayout) {
+            ALOGV("Invalid Header, missing stream map.");
+            return false;
+        }
+        header->num_streams = 1;
+        header->num_coupled = header->channels > 1;
+        header->stream_map[0] = 0;
+        header->stream_map[1] = 1;
+        return true;
+    }
+    if (data_size < kOpusHeaderStreamMapOffset + header->channels) {
+        ALOGV("Invalid stream map; insufficient data for current channel "
+              "count: %d",
+              header->channels);
+        return false;
+    }
+    header->num_streams = data[kOpusHeaderNumStreamsOffset];
+    header->num_coupled = data[kOpusHeaderNumCoupledStreamsOffset];
+    if (header->num_streams + header->num_coupled != header->channels) {
+        ALOGV("Inconsistent channel mapping.");
+        return false;
+    }
+    for (int i = 0; i < header->channels; ++i)
+        header->stream_map[i] = data[kOpusHeaderStreamMapOffset + i];
+    return true;
+}
+
+int WriteOpusHeader(const OpusHeader &header, int input_sample_rate,
+                    uint8_t* output, size_t output_size) {
+    // See https://wiki.xiph.org/OggOpus#ID_Header.
+    const size_t total_size = kOpusHeaderStreamMapOffset + header.channels;
+    if (output_size < total_size) {
+        ALOGE("Output buffer too small for header.");
+        return -1;
+    }
+
+    // ensure entire header is cleared, even though we overwrite much of it below
+    memset(output, 0, output_size);
+
+    // Set magic signature.
+    memcpy(output + kOpusHeaderLabelOffset, "OpusHead", 8);
+    // Set Opus version.
+    output[kOpusHeaderVersionOffset] = 1;
+    // Set channel count.
+    output[kOpusHeaderChannelsOffset] = (uint8_t)header.channels;
+    // Set pre-skip
+    memcpy(output + kOpusHeaderSkipSamplesOffset, &header.skip_samples, sizeof(uint16_t));
+    // Set original input sample rate in Hz.
+    memcpy(output + kOpusHeaderSampleRateOffset, &input_sample_rate, sizeof(uint32_t));
+    // Set output gain in dB.
+    memcpy(output + kOpusHeaderGainOffset, &header.gain_db, sizeof(uint16_t));
+
+    if (header.channels > 2) {
+        // Set channel mapping
+        output[kOpusHeaderChannelMappingOffset] = 1;
+        // Assuming no coupled streams. This should actually be
+        // channels() - |coupled_streams|.
+        output[kOpusHeaderNumStreamsOffset] = header.channels;
+        output[kOpusHeaderNumCoupledStreamsOffset] = 0;
+
+        // Set the actual stream map.
+        for (int i = 0; i < header.channels; ++i) {
+            output[kOpusHeaderStreamMapOffset + i] = kOpusChannelMap[header.channels - 1][i];
+        }
+        return kOpusHeaderStreamMapOffset + header.channels + 1;
+    } else {
+        output[kOpusHeaderChannelMappingOffset] = 0;
+        return kOpusHeaderChannelMappingOffset + 1;
+    }
+}
+
+int WriteOpusHeaders(const OpusHeader &header, int inputSampleRate,
+                     uint8_t* output, size_t outputSize, uint64_t codecDelay,
+                     uint64_t seekPreRoll) {
+    if (outputSize < AOPUS_UNIFIED_CSD_MINSIZE) {
+        ALOGD("Buffer not large enough to hold unified OPUS CSD");
+        return -1;
+    }
+    int headerLen = 0;
+
+    // Add opus header
+    /*
+      Following is the CSD syntax for signalling OpusHeader
+      (http://wiki.xiph.org/OggOpus#ID_Header)
+
+      Marker (8 bytes) | Length (8 bytes) | OpusHeader
+
+      Markers supported:
+      AOPUS_CSD_OPUS_HEADER_MARKER - Signals Opus Header
+
+      Length should be a value within AOPUS_OPUSHEAD_MINSIZE and AOPUS_OPUSHEAD_MAXSIZE.
+    */
+
+    memcpy(output + headerLen, AOPUS_CSD_OPUS_HEADER_MARKER, AOPUS_MARKER_SIZE);
+    headerLen += AOPUS_MARKER_SIZE;
+
+    // Place holder for opusHeader Size
+    headerLen += AOPUS_LENGTH_SIZE;
+
+    int headerSize = WriteOpusHeader(header, inputSampleRate, output + headerLen,
+        outputSize - headerLen);
+    if (headerSize < 0) {
+        ALOGD("%s: WriteOpusHeader failed", __func__);
+        return -1;
+    }
+    headerLen += headerSize;
+
+    // Update opus headerSize after AOPUS_CSD_OPUS_HEADER_MARKER
+    uint64_t length = headerSize;
+    memcpy(output + AOPUS_MARKER_SIZE, &length, AOPUS_LENGTH_SIZE);
+
+    /*
+      Following is the CSD syntax for signalling codec delay and
+      seek pre-roll which is to be appended after OpusHeader
+
+      Marker (8 bytes) | Length (8 bytes) | Samples in ns (8 bytes)
+
+      Markers supported:
+      AOPUS_CSD_CODEC_DELAY_MARKER - codec delay as samples in ns, represented in 8 bytes
+      AOPUS_CSD_SEEK_PREROLL_MARKER - preroll adjustment as samples in ns, represented in 8 bytes
+
+    */
+    length = sizeof(codecDelay);
+    if (headerLen > (outputSize - AOPUS_MARKER_SIZE - AOPUS_LENGTH_SIZE - length)) {
+        ALOGD("Buffer not large enough to hold codec delay");
+        return -1;
+    }
+    // Add codec delay
+    memcpy(output + headerLen, AOPUS_CSD_CODEC_DELAY_MARKER, AOPUS_MARKER_SIZE);
+    headerLen += AOPUS_MARKER_SIZE;
+    memcpy(output + headerLen, &length, AOPUS_LENGTH_SIZE);
+    headerLen += AOPUS_LENGTH_SIZE;
+    memcpy(output + headerLen, &codecDelay, length);
+    headerLen += length;
+
+    length = sizeof(seekPreRoll);
+    if (headerLen > (outputSize - AOPUS_MARKER_SIZE - AOPUS_LENGTH_SIZE - length)) {
+        ALOGD("Buffer not large enough to hold seek pre roll");
+        return -1;
+    }
+    // Add skip pre roll
+    memcpy(output + headerLen, AOPUS_CSD_SEEK_PREROLL_MARKER, AOPUS_MARKER_SIZE);
+    headerLen += AOPUS_MARKER_SIZE;
+    memcpy(output + headerLen, &length, AOPUS_LENGTH_SIZE);
+    headerLen += AOPUS_LENGTH_SIZE;
+    memcpy(output + headerLen, &seekPreRoll, length);
+    headerLen += length;
+
+    return headerLen;
+}
+
+bool IsOpusHeader(const uint8_t *data, size_t data_size) {
+    if (data_size < AOPUS_MARKER_SIZE) {
+        return false;
+    }
+
+    return !memcmp(data, AOPUS_CSD_OPUS_HEADER_MARKER, AOPUS_MARKER_SIZE);
+}
+
+bool GetOpusHeaderBuffers(const uint8_t *data, size_t data_size,
+                          void **opusHeadBuf, size_t *opusHeadSize,
+                          void **codecDelayBuf, size_t *codecDelaySize,
+                          void **seekPreRollBuf, size_t *seekPreRollSize) {
+    *codecDelayBuf = NULL;
+    *codecDelaySize = 0;
+    *seekPreRollBuf = NULL;
+    *seekPreRollSize = 0;
+    *opusHeadBuf = NULL;
+    *opusHeadSize = 0;
+
+    // AOPUS_MARKER_SIZE is 8 "OpusHead" is of size 8
+    if (data_size < 8)
+        return false;
+
+    // Check if the CSD is in legacy format
+    if (!memcmp("OpusHead", data, 8)) {
+        if (data_size < AOPUS_OPUSHEAD_MINSIZE || data_size > AOPUS_OPUSHEAD_MAXSIZE) {
+            ALOGD("Unexpected size for opusHeadSize %zu", data_size);
+            return false;
+        }
+        *opusHeadBuf = (void *)data;
+        *opusHeadSize = data_size;
+        return true;
+    } else if (memcmp(AOPUS_CSD_MARKER_PREFIX, data, AOPUS_CSD_MARKER_PREFIX_SIZE) == 0) {
+        size_t i = 0;
+        bool found = false;
+        while (i <= data_size - AOPUS_MARKER_SIZE - AOPUS_LENGTH_SIZE) {
+            uint8_t *csdBuf = (uint8_t *)data + i;
+            if (!memcmp(csdBuf, AOPUS_CSD_OPUS_HEADER_MARKER, AOPUS_MARKER_SIZE)) {
+                uint64_t value;
+                memcpy(&value, csdBuf + AOPUS_MARKER_SIZE, sizeof(value));
+                if (value < AOPUS_OPUSHEAD_MINSIZE || value > AOPUS_OPUSHEAD_MAXSIZE) {
+                    ALOGD("Unexpected size for opusHeadSize %" PRIu64, value);
+                    return false;
+                }
+                i += AOPUS_MARKER_SIZE + AOPUS_LENGTH_SIZE + value;
+                if (i > data_size) {
+                    ALOGD("Marker signals a header that is larger than input");
+                    return false;
+                }
+                *opusHeadBuf = csdBuf + AOPUS_MARKER_SIZE + AOPUS_LENGTH_SIZE;
+                *opusHeadSize = value;
+                found = true;
+            } else if (!memcmp(csdBuf, AOPUS_CSD_CODEC_DELAY_MARKER, AOPUS_MARKER_SIZE)) {
+                uint64_t value;
+                memcpy(&value, csdBuf + AOPUS_MARKER_SIZE, sizeof(value));
+                if (value != sizeof(uint64_t)) {
+                    ALOGD("Unexpected size for codecDelay %" PRIu64, value);
+                    return false;
+                }
+                i += AOPUS_MARKER_SIZE + AOPUS_LENGTH_SIZE + value;
+                if (i > data_size) {
+                    ALOGD("Marker signals a header that is larger than input");
+                    return false;
+                }
+                *codecDelayBuf = csdBuf + AOPUS_MARKER_SIZE + AOPUS_LENGTH_SIZE;
+                *codecDelaySize = value;
+            } else if (!memcmp(csdBuf, AOPUS_CSD_SEEK_PREROLL_MARKER, AOPUS_MARKER_SIZE)) {
+                uint64_t value;
+                memcpy(&value, csdBuf + AOPUS_MARKER_SIZE, sizeof(value));
+                if (value != sizeof(uint64_t)) {
+                    ALOGD("Unexpected size for seekPreRollSize %" PRIu64, value);
+                    return false;
+                }
+                i += AOPUS_MARKER_SIZE + AOPUS_LENGTH_SIZE + value;
+                if (i > data_size) {
+                    ALOGD("Marker signals a header that is larger than input");
+                    return false;
+                }
+                *seekPreRollBuf = csdBuf + AOPUS_MARKER_SIZE + AOPUS_LENGTH_SIZE;
+                *seekPreRollSize = value;
+            } else {
+                i++;
+            }
+        }
+        return found;
+    } else {
+        return false;  // it isn't in either format
+    }
+}
+
+}  // namespace android
diff --git a/media/libstagefright/foundation/ParsedMessage.cpp b/media/libstagefright/foundation/ParsedMessage.cpp
deleted file mode 100644
index 049c9ad..0000000
--- a/media/libstagefright/foundation/ParsedMessage.cpp
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright 2012, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "ParsedMessage.h"
-
-#include <ctype.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/hexdump.h>
-
-namespace android {
-
-// static
-sp<ParsedMessage> ParsedMessage::Parse(
-        const char *data, size_t size, bool noMoreData, size_t *length) {
-    sp<ParsedMessage> msg = new ParsedMessage;
-    ssize_t res = msg->parse(data, size, noMoreData);
-
-    if (res < 0) {
-        *length = 0;
-        return NULL;
-    }
-
-    *length = res;
-    return msg;
-}
-
-ParsedMessage::ParsedMessage() {
-}
-
-ParsedMessage::~ParsedMessage() {
-}
-
-bool ParsedMessage::findString(const char *name, AString *value) const {
-    AString key = name;
-    key.tolower();
-
-    ssize_t index = mDict.indexOfKey(key);
-
-    if (index < 0) {
-        value->clear();
-
-        return false;
-    }
-
-    *value = mDict.valueAt(index);
-    return true;
-}
-
-bool ParsedMessage::findInt32(const char *name, int32_t *value) const {
-    AString stringValue;
-
-    if (!findString(name, &stringValue)) {
-        return false;
-    }
-
-    char *end;
-    *value = strtol(stringValue.c_str(), &end, 10);
-
-    if (end == stringValue.c_str() || *end != '\0') {
-        *value = 0;
-        return false;
-    }
-
-    return true;
-}
-
-const char *ParsedMessage::getContent() const {
-    return mContent.c_str();
-}
-
-ssize_t ParsedMessage::parse(const char *data, size_t size, bool noMoreData) {
-    if (size == 0) {
-        return -1;
-    }
-
-    ssize_t lastDictIndex = -1;
-
-    size_t offset = 0;
-    bool headersComplete = false;
-    while (offset < size) {
-        size_t lineEndOffset = offset;
-        while (lineEndOffset + 1 < size
-                && (data[lineEndOffset] != '\r'
-                        || data[lineEndOffset + 1] != '\n')) {
-            ++lineEndOffset;
-        }
-
-        if (lineEndOffset + 1 >= size) {
-            return -1;
-        }
-
-        AString line(&data[offset], lineEndOffset - offset);
-
-        if (offset == 0) {
-            // Special handling for the request/status line.
-
-            mDict.add(AString("_"), line);
-            offset = lineEndOffset + 2;
-
-            continue;
-        }
-
-        if (lineEndOffset == offset) {
-            // An empty line separates headers from body.
-            headersComplete = true;
-            offset += 2;
-            break;
-        }
-
-        if (line.c_str()[0] == ' ' || line.c_str()[0] == '\t') {
-            // Support for folded header values.
-
-            if (lastDictIndex >= 0) {
-                // Otherwise it's malformed since the first header line
-                // cannot continue anything...
-
-                AString &value = mDict.editValueAt(lastDictIndex);
-                value.append(line);
-            }
-
-            offset = lineEndOffset + 2;
-            continue;
-        }
-
-        ssize_t colonPos = line.find(":");
-        if (colonPos >= 0) {
-            AString key(line, 0, colonPos);
-            key.trim();
-            key.tolower();
-
-            line.erase(0, colonPos + 1);
-
-            lastDictIndex = mDict.add(key, line);
-        }
-
-        offset = lineEndOffset + 2;
-    }
-
-    if (!headersComplete && (!noMoreData || offset == 0)) {
-        // We either saw the empty line separating headers from body
-        // or we saw at least the status line and know that no more data
-        // is going to follow.
-        return -1;
-    }
-
-    for (size_t i = 0; i < mDict.size(); ++i) {
-        mDict.editValueAt(i).trim();
-    }
-
-    int32_t contentLength;
-    if (!findInt32("content-length", &contentLength) || contentLength < 0) {
-        contentLength = 0;
-    }
-
-    size_t totalLength = offset + contentLength;
-
-    if (size < totalLength) {
-        return -1;
-    }
-
-    mContent.setTo(&data[offset], contentLength);
-
-    return totalLength;
-}
-
-bool ParsedMessage::getRequestField(size_t index, AString *field) const {
-    AString line;
-    CHECK(findString("_", &line));
-
-    size_t prevOffset = 0;
-    size_t offset = 0;
-    for (size_t i = 0; i <= index; ++i) {
-        if (offset >= line.size()) {
-            return false;
-        }
-
-        ssize_t spacePos = line.find(" ", offset);
-
-        if (spacePos < 0) {
-            spacePos = line.size();
-        }
-
-        prevOffset = offset;
-        offset = spacePos + 1;
-    }
-
-    field->setTo(line, prevOffset, offset - prevOffset - 1);
-
-    return true;
-}
-
-bool ParsedMessage::getStatusCode(int32_t *statusCode) const {
-    AString statusCodeString;
-    if (!getRequestField(1, &statusCodeString)) {
-        *statusCode = 0;
-        return false;
-    }
-
-    char *end;
-    *statusCode = strtol(statusCodeString.c_str(), &end, 10);
-
-    if (*end != '\0' || end == statusCodeString.c_str()
-            || (*statusCode) < 100 || (*statusCode) > 999) {
-        *statusCode = 0;
-        return false;
-    }
-
-    return true;
-}
-
-AString ParsedMessage::debugString() const {
-    AString line;
-    CHECK(findString("_", &line));
-
-    line.append("\n");
-
-    for (size_t i = 0; i < mDict.size(); ++i) {
-        const AString &key = mDict.keyAt(i);
-        const AString &value = mDict.valueAt(i);
-
-        if (key == AString("_")) {
-            continue;
-        }
-
-        line.append(key);
-        line.append(": ");
-        line.append(value);
-        line.append("\n");
-    }
-
-    line.append("\n");
-    line.append(mContent);
-
-    return line;
-}
-
-// static
-bool ParsedMessage::GetAttribute(
-        const char *s, const char *key, AString *value) {
-    value->clear();
-
-    size_t keyLen = strlen(key);
-
-    for (;;) {
-        while (isspace(*s)) {
-            ++s;
-        }
-
-        const char *colonPos = strchr(s, ';');
-
-        size_t len =
-            (colonPos == NULL) ? strlen(s) : colonPos - s;
-
-        if (len >= keyLen + 1 && s[keyLen] == '=' && !strncmp(s, key, keyLen)) {
-            value->setTo(&s[keyLen + 1], len - keyLen - 1);
-            return true;
-        }
-
-        if (colonPos == NULL) {
-            return false;
-        }
-
-        s = colonPos + 1;
-    }
-}
-
-// static
-bool ParsedMessage::GetInt32Attribute(
-        const char *s, const char *key, int32_t *value) {
-    AString stringValue;
-    if (!GetAttribute(s, key, &stringValue)) {
-        *value = 0;
-        return false;
-    }
-
-    char *end;
-    *value = strtol(stringValue.c_str(), &end, 10);
-
-    if (end == stringValue.c_str() || *end != '\0') {
-        *value = 0;
-        return false;
-    }
-
-    return true;
-}
-
-}  // namespace android
-
diff --git a/media/libstagefright/foundation/base64.cpp b/media/libstagefright/foundation/base64.cpp
index 8f32582..834b88f 100644
--- a/media/libstagefright/foundation/base64.cpp
+++ b/media/libstagefright/foundation/base64.cpp
@@ -28,14 +28,31 @@
         return NULL;
     }
 
+    size_t bufSize = n / 4 * 3;
+    sp<ABuffer> buf = new ABuffer(bufSize);
+
+    if (decodeBase64(buf->data(), &bufSize, s.c_str())) {
+        buf->setRange(0, bufSize);
+        return buf;
+    }
+    return NULL;
+}
+
+bool decodeBase64(uint8_t *out, size_t *inOutBufSize, const char* s) {
+    size_t n = strlen(s);
+
+    if ((n % 4) != 0) {
+        return false;
+    }
+
     size_t padding = 0;
-    if (n >= 1 && s.c_str()[n - 1] == '=') {
+    if (n >= 1 && s[n - 1] == '=') {
         padding = 1;
 
-        if (n >= 2 && s.c_str()[n - 2] == '=') {
+        if (n >= 2 && s[n - 2] == '=') {
             padding = 2;
 
-            if (n >= 3 && s.c_str()[n - 3] == '=') {
+            if (n >= 3 && s[n - 3] == '=') {
                 padding = 3;
             }
         }
@@ -45,15 +62,13 @@
     // already made sure that n % 4 == 0.
     size_t outLen = (n / 4) * 3 - padding;
 
-    sp<ABuffer> buffer = new ABuffer(outLen);
-    uint8_t *out = buffer->data();
-    if (out == NULL || buffer->size() < outLen) {
-        return NULL;
+    if (out == NULL || *inOutBufSize < outLen) {
+        return false;
     }
     size_t j = 0;
     uint32_t accum = 0;
     for (size_t i = 0; i < n; ++i) {
-        char c = s.c_str()[i];
+        char c = s[i];
         unsigned value;
         if (c >= 'A' && c <= 'Z') {
             value = c - 'A';
@@ -66,10 +81,10 @@
         } else if (c == '/' || c == '_') {
             value = 63;
         } else if (c != '=') {
-            return NULL;
+            return false;
         } else {
             if (i < n - padding) {
-                return NULL;
+                return false;
             }
 
             value = 0;
@@ -86,7 +101,8 @@
         }
     }
 
-    return buffer;
+    *inOutBufSize = j;
+    return true;
 }
 
 static char encode6Bit(unsigned x) {
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AData.h b/media/libstagefright/foundation/include/media/stagefright/foundation/AData.h
index 85e4378..c6c12ff 100644
--- a/media/libstagefright/foundation/include/media/stagefright/foundation/AData.h
+++ b/media/libstagefright/foundation/include/media/stagefright/foundation/AData.h
@@ -774,7 +774,7 @@
         /**
          * Move assignment operator.
          */
-        Custom& operator=(Custom &&o) {
+        Custom& operator=(Custom &&o) noexcept {
             if (&o != this) {
                 if (this->used() && !this->clear()) {
                     __builtin_trap();
@@ -795,7 +795,7 @@
         /**
          * Move constructor.
          */
-        Custom(Custom &&o) : Custom() {
+        Custom(Custom &&o) noexcept : Custom() {
             *this = std::move(o);
         }
 
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ADebug.h b/media/libstagefright/foundation/include/media/stagefright/foundation/ADebug.h
index bac8fa9..ab17a02 100644
--- a/media/libstagefright/foundation/include/media/stagefright/foundation/ADebug.h
+++ b/media/libstagefright/foundation/include/media/stagefright/foundation/ADebug.h
@@ -53,9 +53,11 @@
 #define LITERAL_TO_STRING_INTERNAL(x)    #x
 #define LITERAL_TO_STRING(x) LITERAL_TO_STRING_INTERNAL(x)
 
-#ifdef CHECK
-#undef CHECK
-#endif
+// allow to use CHECK_OP from android-base/logging.h
+// TODO: longterm replace this with android-base/logging.h, but there are some nuances, e.g.
+// android-base CHECK_OP requires a copy constructor, whereas we don't.
+#ifndef CHECK_OP
+
 #define CHECK(condition)                                \
     LOG_ALWAYS_FATAL_IF(                                \
             !(condition),                               \
@@ -63,51 +65,21 @@
             __FILE__ ":" LITERAL_TO_STRING(__LINE__)    \
             " CHECK(" #condition ") failed.")
 
-#define MAKE_COMPARATOR(suffix,op)                          \
-    template<class A, class B>                              \
-    AString Compare_##suffix(const A &a, const B &b) {      \
-        AString res;                                        \
-        if (!(a op b)) {                                    \
-            res.append(a);                                  \
-            res.append(" vs. ");                            \
-            res.append(b);                                  \
-        }                                                   \
-        return res;                                         \
-    }
-
-MAKE_COMPARATOR(EQ,==)
-MAKE_COMPARATOR(NE,!=)
-MAKE_COMPARATOR(LE,<=)
-MAKE_COMPARATOR(GE,>=)
-MAKE_COMPARATOR(LT,<)
-MAKE_COMPARATOR(GT,>)
-
-#ifdef CHECK_OP
-#undef CHECK_OP
-#endif
-
 #define CHECK_OP(x,y,suffix,op)                                         \
     do {                                                                \
-        AString ___res = Compare_##suffix(x, y);                        \
-        if (!___res.empty()) {                                          \
+        const auto &a = x;                                              \
+        const auto &b = y;                                              \
+        if (!(a op b)) {                                                \
             AString ___full =                                           \
                 __FILE__ ":" LITERAL_TO_STRING(__LINE__)                \
                     " CHECK_" #suffix "( " #x "," #y ") failed: ";      \
-            ___full.append(___res);                                     \
-                                                                        \
+            ___full.append(a);                                          \
+            ___full.append(" vs. ");                                    \
+            ___full.append(b);                                          \
             LOG_ALWAYS_FATAL("%s", ___full.c_str());                    \
         }                                                               \
     } while (false)
 
-#ifdef CHECK_EQ
-#undef CHECK_EQ
-#undef CHECK_NE
-#undef CHECK_LE
-#undef CHECK_LT
-#undef CHECK_GE
-#undef CHECK_GT
-#endif
-
 #define CHECK_EQ(x,y)   CHECK_OP(x,y,EQ,==)
 #define CHECK_NE(x,y)   CHECK_OP(x,y,NE,!=)
 #define CHECK_LE(x,y)   CHECK_OP(x,y,LE,<=)
@@ -115,6 +87,8 @@
 #define CHECK_GE(x,y)   CHECK_OP(x,y,GE,>=)
 #define CHECK_GT(x,y)   CHECK_OP(x,y,GT,>)
 
+#endif
+
 #define TRESPASS(...) \
         LOG_ALWAYS_FATAL(                                       \
             __FILE__ ":" LITERAL_TO_STRING(__LINE__)            \
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ANetworkSession.h b/media/libstagefright/foundation/include/media/stagefright/foundation/ANetworkSession.h
deleted file mode 100644
index fd3ebaa..0000000
--- a/media/libstagefright/foundation/include/media/stagefright/foundation/ANetworkSession.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright 2012, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef A_NETWORK_SESSION_H_
-
-#define A_NETWORK_SESSION_H_
-
-#include <media/stagefright/foundation/ABase.h>
-#include <utils/KeyedVector.h>
-#include <utils/RefBase.h>
-#include <utils/Thread.h>
-
-#include <netinet/in.h>
-
-namespace android {
-
-struct AMessage;
-
-// Helper class to manage a number of live sockets (datagram and stream-based)
-// on a single thread. Clients are notified about activity through AMessages.
-struct ANetworkSession : public RefBase {
-    ANetworkSession();
-
-    status_t start();
-    status_t stop();
-
-    status_t createRTSPClient(
-            const char *host, unsigned port, const sp<AMessage> &notify,
-            int32_t *sessionID);
-
-    status_t createRTSPServer(
-            const struct in_addr &addr, unsigned port,
-            const sp<AMessage> &notify, int32_t *sessionID);
-
-    status_t createUDPSession(
-            unsigned localPort, const sp<AMessage> &notify, int32_t *sessionID);
-
-    status_t createUDPSession(
-            unsigned localPort,
-            const char *remoteHost,
-            unsigned remotePort,
-            const sp<AMessage> &notify,
-            int32_t *sessionID);
-
-    status_t connectUDPSession(
-            int32_t sessionID, const char *remoteHost, unsigned remotePort);
-
-    // passive
-    status_t createTCPDatagramSession(
-            const struct in_addr &addr, unsigned port,
-            const sp<AMessage> &notify, int32_t *sessionID);
-
-    // active
-    status_t createTCPDatagramSession(
-            unsigned localPort,
-            const char *remoteHost,
-            unsigned remotePort,
-            const sp<AMessage> &notify,
-            int32_t *sessionID);
-
-    status_t destroySession(int32_t sessionID);
-
-    status_t sendRequest(
-            int32_t sessionID, const void *data, ssize_t size = -1,
-            bool timeValid = false, int64_t timeUs = -1ll);
-
-    status_t switchToWebSocketMode(int32_t sessionID);
-
-    enum NotificationReason {
-        kWhatError,
-        kWhatConnected,
-        kWhatClientConnected,
-        kWhatData,
-        kWhatDatagram,
-        kWhatBinaryData,
-        kWhatWebSocketMessage,
-        kWhatNetworkStall,
-    };
-
-protected:
-    virtual ~ANetworkSession();
-
-private:
-    struct NetworkThread;
-    struct Session;
-
-    Mutex mLock;
-    sp<Thread> mThread;
-
-    int32_t mNextSessionID;
-
-    int mPipeFd[2];
-
-    KeyedVector<int32_t, sp<Session> > mSessions;
-
-    enum Mode {
-        kModeCreateUDPSession,
-        kModeCreateTCPDatagramSessionPassive,
-        kModeCreateTCPDatagramSessionActive,
-        kModeCreateRTSPServer,
-        kModeCreateRTSPClient,
-    };
-    status_t createClientOrServer(
-            Mode mode,
-            const struct in_addr *addr,
-            unsigned port,
-            const char *remoteHost,
-            unsigned remotePort,
-            const sp<AMessage> &notify,
-            int32_t *sessionID);
-
-    void threadLoop();
-    void interrupt();
-
-    static status_t MakeSocketNonBlocking(int s);
-
-    DISALLOW_EVIL_CONSTRUCTORS(ANetworkSession);
-};
-
-}  // namespace android
-
-#endif  // A_NETWORK_SESSION_H_
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AString.h b/media/libstagefright/foundation/include/media/stagefright/foundation/AString.h
index ff086b3..0f6299c 100644
--- a/media/libstagefright/foundation/include/media/stagefright/foundation/AString.h
+++ b/media/libstagefright/foundation/include/media/stagefright/foundation/AString.h
@@ -93,7 +93,7 @@
     status_t writeToParcel(Parcel *parcel) const;
 
 private:
-    static const char *kEmptyString;
+    constexpr static const char *kEmptyString = "";
 
     char *mData;
     size_t mSize;
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AudioPresentationInfo.h b/media/libstagefright/foundation/include/media/stagefright/foundation/AudioPresentationInfo.h
new file mode 100644
index 0000000..4bd4d9f
--- /dev/null
+++ b/media/libstagefright/foundation/include/media/stagefright/foundation/AudioPresentationInfo.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AUDIO_PRESENTATION_INFO_H_
+#define AUDIO_PRESENTATION_INFO_H_
+
+#include <map>
+#include <sstream>
+#include <stdint.h>
+#include <vector>
+
+#include <utils/Errors.h>
+
+namespace android {
+
+enum AudioPresentationVersion {
+    PRESENTATION_VERSION_UNDEFINED = 0,
+    PRESENTATION_VERSION_1,
+};
+
+enum MasteringIndication {
+    MASTERING_NOT_INDICATED,
+    MASTERED_FOR_STEREO,
+    MASTERED_FOR_SURROUND,
+    MASTERED_FOR_3D,
+    MASTERED_FOR_HEADPHONE,
+};
+
+struct AudioPresentation {
+    uint32_t mVersion = PRESENTATION_VERSION_UNDEFINED;
+    int32_t mPresentationId = -1;
+    int32_t mProgramId = -1;
+    std::map<std::string, std::string> mLabels;
+    std::string mLanguage;
+    MasteringIndication mMasteringIndication = MASTERING_NOT_INDICATED;
+    bool mAudioDescriptionAvailable = false;
+    bool mSpokenSubtitlesAvailable = false;
+    bool mDialogueEnhancementAvailable = false;
+};
+
+struct AudioPresentationV1 : public AudioPresentation {
+    AudioPresentationV1() {
+        mVersion = PRESENTATION_VERSION_1;
+    }
+};
+
+typedef std::vector<AudioPresentation> AudioPresentationCollection;
+
+void serializeAudioPresentations(const AudioPresentationCollection& presentations,
+                                               std::ostream* serializedOutput);
+status_t deserializeAudioPresentations(std::istream* serializedInput,
+                                                AudioPresentationCollection *presentations);
+}  // namespace android
+
+#endif  // AUDIO_PRESENTATION_INFO_H_
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ColorUtils.h b/media/libstagefright/foundation/include/media/stagefright/foundation/ColorUtils.h
index d6c768d..cd0af2b 100644
--- a/media/libstagefright/foundation/include/media/stagefright/foundation/ColorUtils.h
+++ b/media/libstagefright/foundation/include/media/stagefright/foundation/ColorUtils.h
@@ -27,6 +27,8 @@
 #include <media/hardware/VideoAPI.h>
 #include <system/graphics.h>
 
+struct AMediaFormat;
+
 namespace android {
 
 struct ColorUtils {
@@ -135,6 +137,9 @@
     static void convertIsoColorAspectsToCodecAspects(
             int32_t primaries, int32_t transfer, int32_t coeffs, bool fullRange,
             ColorAspects &aspects);
+    static void convertIsoColorAspectsToPlatformAspects(
+        int32_t primaries, int32_t isotransfer, int32_t coeffs, bool fullRange,
+        int32_t *range, int32_t *standard, int32_t *transfer);
 
     // unpack a uint32_t to a full ColorAspects struct
     static ColorAspects unpackToColorAspects(uint32_t packed);
@@ -180,6 +185,8 @@
 
     // writes |info| into format.
     static void setHDRStaticInfoIntoFormat(const HDRStaticInfo &info, sp<AMessage> &format);
+    // writes |info| into format.
+    static void setHDRStaticInfoIntoAMediaFormat(const HDRStaticInfo &info, AMediaFormat *format);
 };
 
 inline static const char *asString(android::ColorUtils::ColorStandard i, const char *def = "??") {
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/MediaDefs.h b/media/libstagefright/foundation/include/media/stagefright/foundation/MediaDefs.h
index 25be89f..1f9e636 100644
--- a/media/libstagefright/foundation/include/media/stagefright/foundation/MediaDefs.h
+++ b/media/libstagefright/foundation/include/media/stagefright/foundation/MediaDefs.h
@@ -25,6 +25,7 @@
 
 extern const char *MEDIA_MIMETYPE_VIDEO_VP8;
 extern const char *MEDIA_MIMETYPE_VIDEO_VP9;
+extern const char *MEDIA_MIMETYPE_VIDEO_AV1;
 extern const char *MEDIA_MIMETYPE_VIDEO_AVC;
 extern const char *MEDIA_MIMETYPE_VIDEO_HEVC;
 extern const char *MEDIA_MIMETYPE_VIDEO_MPEG4;
@@ -33,6 +34,10 @@
 extern const char *MEDIA_MIMETYPE_VIDEO_RAW;
 extern const char *MEDIA_MIMETYPE_VIDEO_DOLBY_VISION;
 extern const char *MEDIA_MIMETYPE_VIDEO_SCRAMBLED;
+extern const char *MEDIA_MIMETYPE_VIDEO_DIVX;
+extern const char *MEDIA_MIMETYPE_VIDEO_DIVX3;
+extern const char *MEDIA_MIMETYPE_VIDEO_XVID;
+extern const char *MEDIA_MIMETYPE_VIDEO_MJPEG;
 
 extern const char *MEDIA_MIMETYPE_AUDIO_AMR_NB;
 extern const char *MEDIA_MIMETYPE_AUDIO_AMR_WB;
@@ -52,7 +57,14 @@
 extern const char *MEDIA_MIMETYPE_AUDIO_MSGSM;
 extern const char *MEDIA_MIMETYPE_AUDIO_AC3;
 extern const char *MEDIA_MIMETYPE_AUDIO_EAC3;
+extern const char *MEDIA_MIMETYPE_AUDIO_EAC3_JOC;
+extern const char *MEDIA_MIMETYPE_AUDIO_AC4;
 extern const char *MEDIA_MIMETYPE_AUDIO_SCRAMBLED;
+extern const char *MEDIA_MIMETYPE_AUDIO_ALAC;
+extern const char *MEDIA_MIMETYPE_AUDIO_WMA;
+extern const char *MEDIA_MIMETYPE_AUDIO_MS_ADPCM;
+extern const char *MEDIA_MIMETYPE_AUDIO_DVI_IMA_ADPCM;
+
 
 extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG4;
 extern const char *MEDIA_MIMETYPE_CONTAINER_WAV;
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/Mutexed.h b/media/libstagefright/foundation/include/media/stagefright/foundation/Mutexed.h
index 143b140..03720fd 100644
--- a/media/libstagefright/foundation/include/media/stagefright/foundation/Mutexed.h
+++ b/media/libstagefright/foundation/include/media/stagefright/foundation/Mutexed.h
@@ -103,7 +103,7 @@
     class Locked {
     public:
         inline Locked(Mutexed<T> &mParent);
-        inline Locked(Locked &&from) :
+        inline Locked(Locked &&from) noexcept :
             mLock(from.mLock),
             mTreasure(from.mTreasure),
             mLocked(from.mLocked) {}
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/OpusHeader.h b/media/libstagefright/foundation/include/media/stagefright/foundation/OpusHeader.h
new file mode 100644
index 0000000..29037af
--- /dev/null
+++ b/media/libstagefright/foundation/include/media/stagefright/foundation/OpusHeader.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * The Opus specification is part of IETF RFC 6716:
+ * http://tools.ietf.org/html/rfc6716
+ */
+
+#ifndef OPUS_HEADER_H_
+#define OPUS_HEADER_H_
+
+namespace android {
+
+/* Constants used for delimiting Opus CSD */
+#define AOPUS_CSD_MARKER_PREFIX "AOPUS"
+#define AOPUS_CSD_MARKER_PREFIX_SIZE (sizeof(AOPUS_CSD_MARKER_PREFIX) - 1)
+#define AOPUS_CSD_OPUS_HEADER_MARKER AOPUS_CSD_MARKER_PREFIX "HDR"
+#define AOPUS_CSD_CODEC_DELAY_MARKER AOPUS_CSD_MARKER_PREFIX "DLY"
+#define AOPUS_CSD_SEEK_PREROLL_MARKER AOPUS_CSD_MARKER_PREFIX "PRL"
+#define AOPUS_MARKER_SIZE 8
+#define AOPUS_LENGTH_SIZE sizeof(uint64_t)
+#define AOPUS_CSD_CODEC_DELAY_SIZE \
+     (AOPUS_MARKER_SIZE) + (AOPUS_LENGTH_SIZE) + sizeof(uint64_t)
+#define AOPUS_CSD_SEEK_PREROLL_SIZE \
+     (AOPUS_MARKER_SIZE) + (AOPUS_LENGTH_SIZE) + sizeof(uint64_t)
+
+/* OpusHead csd minimum size is 19 */
+#define AOPUS_OPUSHEAD_MINSIZE 19
+#define AOPUS_CSD_OPUSHEAD_MINSIZE \
+    (AOPUS_MARKER_SIZE) + (AOPUS_LENGTH_SIZE) + (AOPUS_OPUSHEAD_MINSIZE)
+
+#define AOPUS_UNIFIED_CSD_MINSIZE \
+    ((AOPUS_CSD_OPUSHEAD_MINSIZE) + \
+     (AOPUS_CSD_CODEC_DELAY_SIZE) + \
+     (AOPUS_CSD_SEEK_PREROLL_SIZE))
+
+/* OpusHead csd at max can be AOPUS_CSD_OPUSHEAD_MINSIZE + 2 + max number of channels (255) */
+#define AOPUS_OPUSHEAD_MAXSIZE ((AOPUS_OPUSHEAD_MINSIZE) + 2 + 255)
+#define AOPUS_CSD_OPUSHEAD_MAXSIZE \
+    (AOPUS_MARKER_SIZE) + (AOPUS_LENGTH_SIZE) + (AOPUS_OPUSHEAD_MAXSIZE)
+
+#define AOPUS_UNIFIED_CSD_MAXSIZE \
+    ((AOPUS_CSD_OPUSHEAD_MAXSIZE) + \
+     (AOPUS_CSD_CODEC_DELAY_SIZE) + \
+     (AOPUS_CSD_SEEK_PREROLL_SIZE))
+
+struct OpusHeader {
+    int channels;
+    int channel_mapping;
+    int num_streams;
+    int num_coupled;
+    int16_t gain_db;
+    int skip_samples;
+    uint8_t stream_map[8];
+};
+
+bool ParseOpusHeader(const uint8_t* data, size_t data_size, OpusHeader* header);
+int WriteOpusHeader(const OpusHeader &header, int input_sample_rate, uint8_t* output, size_t output_size);
+bool GetOpusHeaderBuffers(const uint8_t *data, size_t data_size,
+                          void **opusHeadBuf, size_t *opusHeadSize,
+                          void **codecDelayBuf, size_t *codecDelaySize,
+                          void **seekPreRollBuf, size_t *seekPreRollSize);
+int WriteOpusHeaders(const OpusHeader &header, int inputSampleRate,
+                     uint8_t* output, size_t outputSize, uint64_t codecDelay,
+                     uint64_t seekPreRoll);
+bool IsOpusHeader(const uint8_t *data, size_t data_size);
+}  // namespace android
+
+#endif  // OPUS_HEADER_H_
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ParsedMessage.h b/media/libstagefright/foundation/include/media/stagefright/foundation/ParsedMessage.h
deleted file mode 100644
index 9d43a93..0000000
--- a/media/libstagefright/foundation/include/media/stagefright/foundation/ParsedMessage.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2012, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <media/stagefright/foundation/ABase.h>
-#include <media/stagefright/foundation/AString.h>
-#include <utils/KeyedVector.h>
-#include <utils/RefBase.h>
-
-namespace android {
-
-// Encapsulates an "HTTP/RTSP style" response, i.e. a status line,
-// key/value pairs making up the headers and an optional body/content.
-struct ParsedMessage : public RefBase {
-    static sp<ParsedMessage> Parse(
-            const char *data, size_t size, bool noMoreData, size_t *length);
-
-    bool findString(const char *name, AString *value) const;
-    bool findInt32(const char *name, int32_t *value) const;
-
-    const char *getContent() const;
-
-    bool getRequestField(size_t index, AString *field) const;
-    bool getStatusCode(int32_t *statusCode) const;
-
-    AString debugString() const;
-
-    static bool GetAttribute(const char *s, const char *key, AString *value);
-
-    static bool GetInt32Attribute(
-            const char *s, const char *key, int32_t *value);
-
-
-protected:
-    virtual ~ParsedMessage();
-
-private:
-    KeyedVector<AString, AString> mDict;
-    AString mContent;
-
-    ParsedMessage();
-
-    ssize_t parse(const char *data, size_t size, bool noMoreData);
-
-    DISALLOW_EVIL_CONSTRUCTORS(ParsedMessage);
-};
-
-}  // namespace android
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/base64.h b/media/libstagefright/foundation/include/media/stagefright/foundation/base64.h
index abc95e0..60fb9ff 100644
--- a/media/libstagefright/foundation/include/media/stagefright/foundation/base64.h
+++ b/media/libstagefright/foundation/include/media/stagefright/foundation/base64.h
@@ -26,6 +26,9 @@
 struct AString;
 
 sp<ABuffer> decodeBase64(const AString &s);
+
+bool decodeBase64(uint8_t *out, size_t *inOutBufSize, const char* s);
+
 void encodeBase64(const void *data, size_t size, AString *out);
 
 void encodeBase64Url(const void *data, size_t size, AString *out);
diff --git a/media/libstagefright/http/Android.bp b/media/libstagefright/http/Android.bp
index 2e49fc4..8655caf 100644
--- a/media/libstagefright/http/Android.bp
+++ b/media/libstagefright/http/Android.bp
@@ -29,9 +29,6 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
     product_variables: {
diff --git a/media/libstagefright/http/ClearMediaHTTP.cpp b/media/libstagefright/http/ClearMediaHTTP.cpp
new file mode 100644
index 0000000..9557c8a
--- /dev/null
+++ b/media/libstagefright/http/ClearMediaHTTP.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ClearMediaHTTP"
+#include <utils/Log.h>
+
+#include <media/stagefright/ClearMediaHTTP.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/Utils.h>
+
+#include <media/MediaHTTPConnection.h>
+
+namespace android {
+
+ClearMediaHTTP::ClearMediaHTTP(const sp<MediaHTTPConnection> &conn)
+    : mInitCheck((conn != NULL) ? OK : NO_INIT),
+      mHTTPConnection(conn),
+      mCachedSizeValid(false),
+      mCachedSize(0ll) {
+}
+
+ClearMediaHTTP::~ClearMediaHTTP() {
+}
+
+status_t ClearMediaHTTP::connect(
+        const char *uri,
+        const KeyedVector<String8, String8> *headers,
+        off64_t /* offset */) {
+    if (mInitCheck != OK) {
+        return mInitCheck;
+    }
+
+    KeyedVector<String8, String8> extHeaders;
+    if (headers != NULL) {
+        extHeaders = *headers;
+    }
+
+    if (extHeaders.indexOfKey(String8("User-Agent")) < 0) {
+        extHeaders.add(String8("User-Agent"), String8(MakeUserAgent().c_str()));
+    }
+
+    mLastURI = uri;
+    // reconnect() calls with uri == old mLastURI.c_str(), which gets zapped
+    // as part of the above assignment. Ensure no accidental later use.
+    uri = NULL;
+
+    bool success = mHTTPConnection->connect(mLastURI.c_str(), &extHeaders);
+
+    mLastHeaders = extHeaders;
+
+    mCachedSizeValid = false;
+
+    if (success) {
+        AString sanitized = uriDebugString(mLastURI);
+        mName = String8::format("ClearMediaHTTP(%s)", sanitized.c_str());
+    }
+
+    return success ? OK : UNKNOWN_ERROR;
+}
+
+void ClearMediaHTTP::close() {
+    disconnect();
+}
+
+void ClearMediaHTTP::disconnect() {
+    mName = String8("ClearMediaHTTP(<disconnected>)");
+    if (mInitCheck != OK) {
+        return;
+    }
+
+    mHTTPConnection->disconnect();
+}
+
+status_t ClearMediaHTTP::initCheck() const {
+    return mInitCheck;
+}
+
+ssize_t ClearMediaHTTP::readAt(off64_t offset, void *data, size_t size) {
+    if (mInitCheck != OK) {
+        return mInitCheck;
+    }
+
+    int64_t startTimeUs = ALooper::GetNowUs();
+
+    size_t numBytesRead = 0;
+    while (numBytesRead < size) {
+        size_t copy = size - numBytesRead;
+
+        if (copy > 64 * 1024) {
+            // limit the buffer sizes transferred across binder boundaries
+            // to avoid spurious transaction failures.
+            copy = 64 * 1024;
+        }
+
+        ssize_t n = mHTTPConnection->readAt(
+                offset + numBytesRead, (uint8_t *)data + numBytesRead, copy);
+
+        if (n < 0) {
+            return n;
+        } else if (n == 0) {
+            break;
+        }
+
+        numBytesRead += n;
+    }
+
+    int64_t delayUs = ALooper::GetNowUs() - startTimeUs;
+
+    addBandwidthMeasurement(numBytesRead, delayUs);
+
+    return numBytesRead;
+}
+
+status_t ClearMediaHTTP::getSize(off64_t *size) {
+    if (mInitCheck != OK) {
+        return mInitCheck;
+    }
+
+    // Caching the returned size so that it stays valid even after a
+    // disconnect. NuCachedSource2 relies on this.
+
+    if (!mCachedSizeValid) {
+        mCachedSize = mHTTPConnection->getSize();
+        mCachedSizeValid = true;
+    }
+
+    *size = mCachedSize;
+
+    return *size < 0 ? *size : static_cast<status_t>(OK);
+}
+
+uint32_t ClearMediaHTTP::flags() {
+    return kWantsPrefetching | kIsHTTPBasedSource;
+}
+
+status_t ClearMediaHTTP::reconnectAtOffset(off64_t offset) {
+    return connect(mLastURI.c_str(), &mLastHeaders, offset);
+}
+
+
+String8 ClearMediaHTTP::getUri() {
+    if (mInitCheck != OK) {
+        return String8::empty();
+    }
+
+    String8 uri;
+    if (OK == mHTTPConnection->getUri(&uri)) {
+        return uri;
+    }
+    return String8(mLastURI.c_str());
+}
+
+String8 ClearMediaHTTP::getMIMEType() const {
+    if (mInitCheck != OK) {
+        return String8("application/octet-stream");
+    }
+
+    String8 mimeType;
+    status_t err = mHTTPConnection->getMIMEType(&mimeType);
+
+    if (err != OK) {
+        return String8("application/octet-stream");
+    }
+
+    return mimeType;
+}
+
+}  // namespace android
diff --git a/media/libstagefright/http/HTTPHelper.cpp b/media/libstagefright/http/HTTPHelper.cpp
index 77845e2..b895f03 100644
--- a/media/libstagefright/http/HTTPHelper.cpp
+++ b/media/libstagefright/http/HTTPHelper.cpp
@@ -42,11 +42,11 @@
             env, env->FindClass("android/media/MediaHTTPService"));
     CHECK(clazz.get() != NULL);
 
-    jmethodID constructID = env->GetMethodID(clazz.get(), "<init>", "()V");
+    jmethodID constructID = env->GetMethodID(clazz.get(), "<init>", "(Ljava/util/List;)V");
     CHECK(constructID != NULL);
 
     ScopedLocalRef<jobject> httpServiceObj(
-            env, env->NewObject(clazz.get(), constructID));
+            env, env->NewObject(clazz.get(), constructID, NULL));
 
     sp<IMediaHTTPService> httpService;
     if (httpServiceObj.get() != NULL) {
diff --git a/media/libstagefright/http/MediaHTTP.cpp b/media/libstagefright/http/MediaHTTP.cpp
index 7c9247e..0fba3dc 100644
--- a/media/libstagefright/http/MediaHTTP.cpp
+++ b/media/libstagefright/http/MediaHTTP.cpp
@@ -30,10 +30,7 @@
 namespace android {
 
 MediaHTTP::MediaHTTP(const sp<MediaHTTPConnection> &conn)
-    : mInitCheck((conn != NULL) ? OK : NO_INIT),
-      mHTTPConnection(conn),
-      mCachedSizeValid(false),
-      mCachedSize(0ll),
+    : ClearMediaHTTP(conn),
       mDrmManagerClient(NULL) {
 }
 
@@ -41,117 +38,6 @@
     clearDRMState_l();
 }
 
-status_t MediaHTTP::connect(
-        const char *uri,
-        const KeyedVector<String8, String8> *headers,
-        off64_t /* offset */) {
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
-
-    KeyedVector<String8, String8> extHeaders;
-    if (headers != NULL) {
-        extHeaders = *headers;
-    }
-
-    if (extHeaders.indexOfKey(String8("User-Agent")) < 0) {
-        extHeaders.add(String8("User-Agent"), String8(MakeUserAgent().c_str()));
-    }
-
-    mLastURI = uri;
-    // reconnect() calls with uri == old mLastURI.c_str(), which gets zapped
-    // as part of the above assignment. Ensure no accidental later use.
-    uri = NULL;
-
-    bool success = mHTTPConnection->connect(mLastURI.c_str(), &extHeaders);
-
-    mLastHeaders = extHeaders;
-
-    mCachedSizeValid = false;
-
-    if (success) {
-        AString sanitized = uriDebugString(mLastURI);
-        mName = String8::format("MediaHTTP(%s)", sanitized.c_str());
-    }
-
-    return success ? OK : UNKNOWN_ERROR;
-}
-
-void MediaHTTP::disconnect() {
-    mName = String8("MediaHTTP(<disconnected>)");
-    if (mInitCheck != OK) {
-        return;
-    }
-
-    mHTTPConnection->disconnect();
-}
-
-status_t MediaHTTP::initCheck() const {
-    return mInitCheck;
-}
-
-ssize_t MediaHTTP::readAt(off64_t offset, void *data, size_t size) {
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
-
-    int64_t startTimeUs = ALooper::GetNowUs();
-
-    size_t numBytesRead = 0;
-    while (numBytesRead < size) {
-        size_t copy = size - numBytesRead;
-
-        if (copy > 64 * 1024) {
-            // limit the buffer sizes transferred across binder boundaries
-            // to avoid spurious transaction failures.
-            copy = 64 * 1024;
-        }
-
-        ssize_t n = mHTTPConnection->readAt(
-                offset + numBytesRead, (uint8_t *)data + numBytesRead, copy);
-
-        if (n < 0) {
-            return n;
-        } else if (n == 0) {
-            break;
-        }
-
-        numBytesRead += n;
-    }
-
-    int64_t delayUs = ALooper::GetNowUs() - startTimeUs;
-
-    addBandwidthMeasurement(numBytesRead, delayUs);
-
-    return numBytesRead;
-}
-
-status_t MediaHTTP::getSize(off64_t *size) {
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
-
-    // Caching the returned size so that it stays valid even after a
-    // disconnect. NuCachedSource2 relies on this.
-
-    if (!mCachedSizeValid) {
-        mCachedSize = mHTTPConnection->getSize();
-        mCachedSizeValid = true;
-    }
-
-    *size = mCachedSize;
-
-    return *size < 0 ? *size : static_cast<status_t>(OK);
-}
-
-uint32_t MediaHTTP::flags() {
-    return kWantsPrefetching | kIsHTTPBasedSource;
-}
-
-status_t MediaHTTP::reconnectAtOffset(off64_t offset) {
-    return connect(mLastURI.c_str(), &mLastHeaders, offset);
-}
-
 // DRM...
 
 sp<DecryptHandle> MediaHTTP::DrmInitialization(const char* mime) {
@@ -176,33 +62,6 @@
     return mDecryptHandle;
 }
 
-String8 MediaHTTP::getUri() {
-    if (mInitCheck != OK) {
-        return String8::empty();
-    }
-
-    String8 uri;
-    if (OK == mHTTPConnection->getUri(&uri)) {
-        return uri;
-    }
-    return String8(mLastURI.c_str());
-}
-
-String8 MediaHTTP::getMIMEType() const {
-    if (mInitCheck != OK) {
-        return String8("application/octet-stream");
-    }
-
-    String8 mimeType;
-    status_t err = mHTTPConnection->getMIMEType(&mimeType);
-
-    if (err != OK) {
-        return String8("application/octet-stream");
-    }
-
-    return mimeType;
-}
-
 void MediaHTTP::clearDRMState_l() {
     if (mDecryptHandle != NULL) {
         // To release mDecryptHandle
diff --git a/media/libstagefright/httplive/Android.bp b/media/libstagefright/httplive/Android.bp
index 8a77401..c0ee14e 100644
--- a/media/libstagefright/httplive/Android.bp
+++ b/media/libstagefright/httplive/Android.bp
@@ -25,25 +25,26 @@
             "unsigned-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
     shared_libs: [
         "liblog",
-        "libbinder",
         "libcrypto",
         "libcutils",
         "libmedia",
-        "libmediaextractor",
+        "libmediandk",
         "libstagefright",
         "libstagefright_foundation",
         "libutils",
-        "libhidlallocatorutils",
         "libhidlbase",
+        "libhidlmemory",
         "android.hardware.cas@1.0",
         "android.hardware.cas.native@1.0",
+        "android.hidl.allocator@1.0",
+    ],
+
+    header_libs: [
+        "libbase_headers",
     ],
 
     static_libs: [
diff --git a/media/libstagefright/httplive/HTTPDownloader.cpp b/media/libstagefright/httplive/HTTPDownloader.cpp
index 6c34963..c7e92cd 100644
--- a/media/libstagefright/httplive/HTTPDownloader.cpp
+++ b/media/libstagefright/httplive/HTTPDownloader.cpp
@@ -26,8 +26,8 @@
 #include <media/MediaHTTPService.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/MediaHTTP.h>
-#include <media/stagefright/FileSource.h>
+#include <media/stagefright/ClearMediaHTTP.h>
+#include <media/stagefright/ClearFileSource.h>
 #include <openssl/aes.h>
 #include <openssl/md5.h>
 #include <utils/Mutex.h>
@@ -38,7 +38,7 @@
 HTTPDownloader::HTTPDownloader(
         const sp<MediaHTTPService> &httpService,
         const KeyedVector<String8, String8> &headers) :
-    mHTTPDataSource(new MediaHTTP(httpService->makeHTTPConnection())),
+    mHTTPDataSource(new ClearMediaHTTP(httpService->makeHTTPConnection())),
     mExtraHeaders(headers),
     mDisconnecting(false) {
 }
@@ -91,7 +91,7 @@
 
     if (reconnect) {
         if (!strncasecmp(url, "file://", 7)) {
-            mDataSource = new FileSource(url + 7);
+            mDataSource = new ClearFileSource(url + 7);
         } else if (strncasecmp(url, "http://", 7)
                 && strncasecmp(url, "https://", 8)) {
             return ERROR_UNSUPPORTED;
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 7eff8eb..9cf97c7 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -44,10 +44,10 @@
 
 // static
 // Bandwidth Switch Mark Defaults
-const int64_t LiveSession::kUpSwitchMarkUs = 15000000ll;
-const int64_t LiveSession::kDownSwitchMarkUs = 20000000ll;
-const int64_t LiveSession::kUpSwitchMarginUs = 5000000ll;
-const int64_t LiveSession::kResumeThresholdUs = 100000ll;
+const int64_t LiveSession::kUpSwitchMarkUs = 15000000LL;
+const int64_t LiveSession::kDownSwitchMarkUs = 20000000LL;
+const int64_t LiveSession::kUpSwitchMarginUs = 5000000LL;
+const int64_t LiveSession::kResumeThresholdUs = 100000LL;
 
 //TODO: redefine this mark to a fair value
 // default buffer underflow mark
@@ -66,9 +66,9 @@
     // Bandwidth estimation parameters
     static const int32_t kShortTermBandwidthItems = 3;
     static const int32_t kMinBandwidthHistoryItems = 20;
-    static const int64_t kMinBandwidthHistoryWindowUs = 5000000ll; // 5 sec
-    static const int64_t kMaxBandwidthHistoryWindowUs = 30000000ll; // 30 sec
-    static const int64_t kMaxBandwidthHistoryAgeUs = 60000000ll; // 60 sec
+    static const int64_t kMinBandwidthHistoryWindowUs = 5000000LL; // 5 sec
+    static const int64_t kMaxBandwidthHistoryWindowUs = 30000000LL; // 30 sec
+    static const int64_t kMaxBandwidthHistoryAgeUs = 60000000LL; // 60 sec
 
     struct BandwidthEntry {
         int64_t mTimestampUs;
@@ -284,7 +284,7 @@
       mPrevBufferPercentage(-1),
       mCurBandwidthIndex(-1),
       mOrigBandwidthIndex(-1),
-      mLastBandwidthBps(-1ll),
+      mLastBandwidthBps(-1LL),
       mLastBandwidthStable(false),
       mBandwidthEstimator(new BandwidthEstimator()),
       mMaxWidth(720),
@@ -294,8 +294,8 @@
       mSwapMask(0),
       mSwitchGeneration(0),
       mSubtitleGeneration(0),
-      mLastDequeuedTimeUs(0ll),
-      mRealTimeBaseUs(0ll),
+      mLastDequeuedTimeUs(0LL),
+      mRealTimeBaseUs(0LL),
       mReconfigurationInProgress(false),
       mSwitchInProgress(false),
       mUpSwitchMark(kUpSwitchMarkUs),
@@ -445,7 +445,7 @@
                return -EAGAIN;
             };
             (*accessUnit)->meta()->setInt32(
-                    "trackIndex", mPlaylist->getSelectedIndex());
+                    "track-index", mPlaylist->getSelectedIndex());
             (*accessUnit)->meta()->setInt64("baseUs", mRealTimeBaseUs);
         } else if (stream == STREAMTYPE_METADATA) {
             HLSTime mdTime((*accessUnit)->meta());
@@ -844,7 +844,7 @@
                     // (If we don't have that cushion we'd rather cancel and try again.)
                     int64_t delayUs =
                         switchUp ?
-                            (kUnderflowMarkMs * 1000ll + 1000000ll)
+                            (kUnderflowMarkMs * 1000LL + 1000000LL)
                             : 0;
                     bool needResumeUntil = false;
                     sp<AMessage> stopParams = msg;
@@ -954,7 +954,7 @@
 
 // static
 bool LiveSession::isBandwidthValid(const BandwidthItem &item) {
-    static const int64_t kBlacklistWindowUs = 300 * 1000000ll;
+    static const int64_t kBlacklistWindowUs = 300 * 1000000LL;
     return item.mLastFailureUs < 0
             || ALooper::GetNowUs() - item.mLastFailureUs > kBlacklistWindowUs;
 }
@@ -1060,7 +1060,7 @@
             BandwidthItem item;
 
             item.mPlaylistIndex = i;
-            item.mLastFailureUs = -1ll;
+            item.mLastFailureUs = -1LL;
 
             sp<AMessage> meta;
             AString uri;
@@ -1114,7 +1114,7 @@
 
     mPlaylist->pickRandomMediaItems();
     changeConfiguration(
-            0ll /* timeUs */, initialBandwidthIndex, false /* pickTrack */);
+            0LL /* timeUs */, initialBandwidthIndex, false /* pickTrack */);
 }
 
 void LiveSession::finishDisconnect() {
@@ -1175,7 +1175,7 @@
     FetcherInfo info;
     info.mFetcher = new PlaylistFetcher(
             notify, this, uri, mCurBandwidthIndex, mSubtitleGeneration);
-    info.mDurationUs = -1ll;
+    info.mDurationUs = -1LL;
     info.mToBeRemoved = false;
     info.mToBeResumed = false;
     mFetcherLooper->registerHandler(info.mFetcher);
@@ -1234,7 +1234,7 @@
         const AString &uri, uint32_t streamMask, int64_t timeUs, bool newUri) {
     ssize_t index = mFetcherInfos.indexOfKey(uri);
     if (index < 0) {
-        ALOGE("did not find fetcher for uri: %s", uri.c_str());
+        ALOGE("did not find fetcher for uri: %s", uriDebugString(uri).c_str());
         return false;
     }
 
@@ -1384,7 +1384,7 @@
         while (index > lowestBandwidth) {
             // be conservative (70%) to avoid overestimating and immediately
             // switching down again.
-            size_t adjustedBandwidthBps = bandwidthBps * 7 / 10;
+            size_t adjustedBandwidthBps = bandwidthBps * .7f;
             const BandwidthItem &item = mBandwidthItems[index];
             if (item.mBandwidth <= adjustedBandwidthBps
                     && isBandwidthValid(item)) {
@@ -1466,7 +1466,7 @@
 }
 
 status_t LiveSession::getDuration(int64_t *durationUs) const {
-    int64_t maxDurationUs = -1ll;
+    int64_t maxDurationUs = -1LL;
     for (size_t i = 0; i < mFetcherInfos.size(); ++i) {
         int64_t fetcherDurationUs = mFetcherInfos.valueAt(i).mDurationUs;
 
@@ -1592,7 +1592,7 @@
         // Delay fetcher removal if not picking tracks, AND old fetcher
         // has stream mask that overlaps new variant. (Okay to discard
         // old fetcher now, if completely no overlap.)
-        if (discardFetcher && timeUs < 0ll && !pickTrack
+        if (discardFetcher && timeUs < 0LL && !pickTrack
                 && (fetcher->getStreamTypeMask() & streamMask)) {
             discardFetcher = false;
             delayRemoval = true;
@@ -1604,7 +1604,7 @@
         } else {
             float threshold = 0.0f; // default to pause after current block (47Kbytes)
             bool disconnect = false;
-            if (timeUs >= 0ll) {
+            if (timeUs >= 0LL) {
                 // seeking, no need to finish fetching
                 disconnect = true;
             } else if (delayRemoval) {
@@ -1620,7 +1620,7 @@
     }
 
     sp<AMessage> msg;
-    if (timeUs < 0ll) {
+    if (timeUs < 0LL) {
         // skip onChangeConfiguration2 (decoder destruction) if not seeking.
         msg = new AMessage(kWhatChangeConfiguration3, this);
     } else {
@@ -1654,9 +1654,9 @@
     if (!mReconfigurationInProgress) {
         int32_t pickTrack = 0;
         msg->findInt32("pickTrack", &pickTrack);
-        changeConfiguration(-1ll /* timeUs */, -1, pickTrack);
+        changeConfiguration(-1LL /* timeUs */, -1, pickTrack);
     } else {
-        msg->post(1000000ll); // retry in 1 sec
+        msg->post(1000000LL); // retry in 1 sec
     }
 }
 
@@ -1788,7 +1788,7 @@
     CHECK(msg->findInt64("timeUs", &timeUs));
     CHECK(msg->findInt32("pickTrack", &pickTrack));
 
-    if (timeUs < 0ll) {
+    if (timeUs < 0LL) {
         if (!pickTrack) {
             // mSwapMask contains streams that are in both old and new variant,
             // (in mNewStreamMask & mStreamMask) but with different URIs
@@ -2005,7 +2005,7 @@
 
             if ((mNewStreamMask & stream) && mStreams[idx].mNewUri.empty()) {
                 ALOGW("swapping stream type %d %s to empty stream",
-                        stream, mStreams[idx].mUri.c_str());
+                        stream, uriDebugString(mStreams[idx].mUri).c_str());
             }
             mStreams[idx].mUri = mStreams[idx].mNewUri;
             mStreams[idx].mNewUri.clear();
@@ -2033,7 +2033,7 @@
         CHECK(idx >= 0);
         if (mStreams[idx].mNewUri.empty()) {
             ALOGW("swapping extra stream type %d %s to empty stream",
-                    stream, mStreams[idx].mUri.c_str());
+                    stream, uriDebugString(mStreams[idx].mUri).c_str());
         }
         mStreams[idx].mUri = mStreams[idx].mNewUri;
         mStreams[idx].mNewUri.clear();
@@ -2062,7 +2062,7 @@
 void LiveSession::schedulePollBuffering() {
     sp<AMessage> msg = new AMessage(kWhatPollBuffering, this);
     msg->setInt32("generation", mPollBufferingGeneration);
-    msg->post(1000000ll);
+    msg->post(1000000LL);
 }
 
 void LiveSession::cancelPollBuffering() {
@@ -2138,7 +2138,7 @@
             ALOGV("stopping newUri = %s", newUri.c_str());
             ssize_t index = mFetcherInfos.indexOfKey(newUri);
             if (index < 0) {
-                ALOGE("did not find fetcher for newUri: %s", newUri.c_str());
+                ALOGE("did not find fetcher for newUri: %s", uriDebugString(newUri).c_str());
                 continue;
             }
             FetcherInfo &info = mFetcherInfos.editValueAt(index);
@@ -2208,13 +2208,13 @@
         int64_t readyMarkUs =
             (mInPreparationPhase ?
                 mBufferingSettings.mInitialMarkMs :
-                mBufferingSettings.mResumePlaybackMarkMs) * 1000ll;
+                mBufferingSettings.mResumePlaybackMarkMs) * 1000LL;
         if (bufferedDurationUs > readyMarkUs
                 || mPacketSources[i]->isFinished(0)) {
             ++readyCount;
         }
         if (!mPacketSources[i]->isFinished(0)) {
-            if (bufferedDurationUs < kUnderflowMarkMs * 1000ll) {
+            if (bufferedDurationUs < kUnderflowMarkMs * 1000LL) {
                 ++underflowCount;
             }
             if (bufferedDurationUs > mUpSwitchMark) {
@@ -2300,7 +2300,7 @@
         ssize_t lowestValid = getLowestValidBandwidthIndex();
         if (mCurBandwidthIndex > lowestValid) {
             cancelBandwidthSwitch();
-            changeConfiguration(-1ll, lowestValid);
+            changeConfiguration(-1LL, lowestValid);
             return true;
         }
     }
@@ -2370,7 +2370,7 @@
             // if not yet prepared, just restart again with new bw index.
             // this is faster and playback experience is cleaner.
             changeConfiguration(
-                    mInPreparationPhase ? 0 : -1ll, bandwidthIndex);
+                    mInPreparationPhase ? 0 : -1LL, bandwidthIndex);
             return true;
         }
     }
diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp
index 8ab33f7..cb97a3c 100644
--- a/media/libstagefright/httplive/M3UParser.cpp
+++ b/media/libstagefright/httplive/M3UParser.cpp
@@ -258,7 +258,7 @@
       mIsEvent(false),
       mFirstSeqNumber(-1),
       mLastSeqNumber(-1),
-      mTargetDurationUs(-1ll),
+      mTargetDurationUs(-1LL),
       mDiscontinuitySeq(0),
       mDiscontinuityCount(0),
       mSelectedIndex(-1) {
@@ -706,6 +706,12 @@
         ++lineNo;
     }
 
+    // playlist has no item, would cause exception
+    if (mItems.size() == 0) {
+        ALOGE("playlist has no item");
+        return ERROR_MALFORMED;
+    }
+
     // error checking of all fields that's required to appear once
     // (currently only checking "target-duration"), and
     // initialization of playlist properties (eg. mTargetDurationUs)
@@ -716,7 +722,7 @@
             ALOGE("Media playlist missing #EXT-X-TARGETDURATION");
             return ERROR_MALFORMED;
         }
-        mTargetDurationUs = targetDurationSecs * 1000000ll;
+        mTargetDurationUs = targetDurationSecs * 1000000LL;
 
         mFirstSeqNumber = 0;
         if (mMeta != NULL) {
@@ -1199,8 +1205,7 @@
             if (val.size() < 2
                     || val.c_str()[0] != '"'
                     || val.c_str()[val.size() - 1] != '"') {
-                ALOGE("Expected quoted string for URI, got '%s' instead.",
-                      val.c_str());
+                ALOGE("Expected quoted string for URI.");
 
                 return ERROR_MALFORMED;
             }
@@ -1391,6 +1396,19 @@
         case 'QDMC':
         case 'ulaw':
         case 'vdva':
+        case 'ac-4':
+        case 'Opus':
+        case 'a3ds':
+        case 'dts+':
+        case 'dts-':
+        case 'dtsx':
+        case 'dtsy':
+        case 'ec+3':
+        case 'mha1':
+        case 'mha2':
+        case 'mhm1':
+        case 'mhm2':
+        case 'sevs':
             return !strcmp("audio", type);
 
         case 'avc1':
@@ -1439,6 +1457,35 @@
         case 'tga ':
         case 'tiff':
         case 'WRLE':
+        case 'a3d1':
+        case 'a3d2':
+        case 'a3d3':
+        case 'a3d4':
+        case 'avc3':
+        case 'avc4':
+        case 'dva1':
+        case 'dvav':
+        case 'dvh1':
+        case 'dvhe':
+        case 'hev1':
+        case 'hev2':
+        case 'hvc1':
+        case 'hvc2':
+        case 'hvt1':
+        case 'lhe1':
+        case 'lht1':
+        case 'lhv1':
+        case 'mjpg':
+        case 'mvc3':
+        case 'mvc4':
+        case 'mvd1':
+        case 'mvd2':
+        case 'mvd3':
+        case 'mvd4':
+        case 'rv60':
+        case 'svc2':
+        case 'vp08':
+        case 'vp09':
             return !strcmp("video", type);
 
         default:
diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp
index 9f39b5e..635ecfe 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.cpp
+++ b/media/libstagefright/httplive/PlaylistFetcher.cpp
@@ -16,6 +16,7 @@
 
 //#define LOG_NDEBUG 0
 #define LOG_TAG "PlaylistFetcher"
+#include <android-base/macros.h>
 #include <utils/Log.h>
 #include <utils/misc.h>
 
@@ -49,8 +50,8 @@
 namespace android {
 
 // static
-const int64_t PlaylistFetcher::kMinBufferedDurationUs = 30000000ll;
-const int64_t PlaylistFetcher::kMaxMonitorDelayUs = 3000000ll;
+const int64_t PlaylistFetcher::kMinBufferedDurationUs = 30000000LL;
+const int64_t PlaylistFetcher::kMaxMonitorDelayUs = 3000000LL;
 // LCM of 188 (size of a TS packet) & 1k works well
 const int32_t PlaylistFetcher::kDownloadBlockSize = 47 * 1024;
 
@@ -151,25 +152,26 @@
       mURI(uri),
       mFetcherID(id),
       mStreamTypeMask(0),
-      mStartTimeUs(-1ll),
-      mSegmentStartTimeUs(-1ll),
-      mDiscontinuitySeq(-1ll),
+      mStartTimeUs(-1LL),
+      mSegmentStartTimeUs(-1LL),
+      mDiscontinuitySeq(-1LL),
       mStartTimeUsRelative(false),
-      mLastPlaylistFetchTimeUs(-1ll),
-      mPlaylistTimeUs(-1ll),
+      mLastPlaylistFetchTimeUs(-1LL),
+      mPlaylistTimeUs(-1LL),
       mSeqNumber(-1),
       mNumRetries(0),
+      mNumRetriesForMonitorQueue(0),
       mStartup(true),
       mIDRFound(false),
       mSeekMode(LiveSession::kSeekModeExactPosition),
       mTimeChangeSignaled(false),
-      mNextPTSTimeUs(-1ll),
+      mNextPTSTimeUs(-1LL),
       mMonitorQueueGeneration(0),
       mSubtitleGeneration(subtitleGeneration),
-      mLastDiscontinuitySeq(-1ll),
+      mLastDiscontinuitySeq(-1LL),
       mRefreshState(INITIAL_MINIMUM_RELOAD_DELAY),
       mFirstPTSValid(false),
-      mFirstTimeUs(-1ll),
+      mFirstTimeUs(-1LL),
       mVideoBuffer(new AnotherPacketSource(NULL)),
       mSampleAesKeyItemChanged(false),
       mThresholdRatio(-1.0f),
@@ -199,7 +201,7 @@
     CHECK_GE(seqNumber, firstSeqNumberInPlaylist);
     CHECK_LE(seqNumber, lastSeqNumberInPlaylist);
 
-    int64_t segmentStartUs = 0ll;
+    int64_t segmentStartUs = 0LL;
     for (int32_t index = 0;
             index < seqNumber - firstSeqNumberInPlaylist; ++index) {
         sp<AMessage> itemMeta;
@@ -239,13 +241,13 @@
 int64_t PlaylistFetcher::delayUsToRefreshPlaylist() const {
     int64_t nowUs = ALooper::GetNowUs();
 
-    if (mPlaylist == NULL || mLastPlaylistFetchTimeUs < 0ll) {
+    if (mPlaylist == NULL || mLastPlaylistFetchTimeUs < 0LL) {
         CHECK_EQ((int)mRefreshState, (int)INITIAL_MINIMUM_RELOAD_DELAY);
-        return 0ll;
+        return 0LL;
     }
 
     if (mPlaylist->isComplete()) {
-        return (~0llu >> 1);
+        return (~0LLU >> 1);
     }
 
     int64_t targetDurationUs = mPlaylist->getTargetDuration();
@@ -267,7 +269,7 @@
                 break;
             }
 
-            // fall through
+            FALLTHROUGH_INTENDED;
         }
 
         case FIRST_UNCHANGED_RELOAD_ATTEMPT:
@@ -294,7 +296,7 @@
     }
 
     int64_t delayUs = mLastPlaylistFetchTimeUs + minPlaylistAgeUs - nowUs;
-    return delayUs > 0ll ? delayUs : 0ll;
+    return delayUs > 0LL ? delayUs : 0LL;
 }
 
 status_t PlaylistFetcher::decryptBuffer(
@@ -364,10 +366,10 @@
         if (err == ERROR_NOT_CONNECTED) {
             return ERROR_NOT_CONNECTED;
         } else if (err < 0) {
-            ALOGE("failed to fetch cipher key from '%s'.", keyURI.c_str());
+            ALOGE("failed to fetch cipher key from '%s'.", uriDebugString(keyURI).c_str());
             return ERROR_IO;
         } else if (key->size() != 16) {
-            ALOGE("key file '%s' wasn't 16 bytes in size.", keyURI.c_str());
+            ALOGE("key file '%s' wasn't 16 bytes in size.", uriDebugString(keyURI).c_str());
             return ERROR_MALFORMED;
         }
 
@@ -848,7 +850,17 @@
     // in the middle of an unfinished download, delay
     // playlist refresh as it'll change seq numbers
     if (!mDownloadState->hasSavedState()) {
-        refreshPlaylist();
+        status_t err = refreshPlaylist();
+        if (err != OK) {
+            if (mNumRetriesForMonitorQueue < kMaxNumRetries) {
+                ++mNumRetriesForMonitorQueue;
+            } else {
+                notifyError(err);
+            }
+            return;
+        } else {
+            mNumRetriesForMonitorQueue = 0;
+        }
     }
 
     int64_t targetDurationUs = kMinBufferedDurationUs;
@@ -856,7 +868,7 @@
         targetDurationUs = mPlaylist->getTargetDuration();
     }
 
-    int64_t bufferedDurationUs = 0ll;
+    int64_t bufferedDurationUs = 0LL;
     status_t finalResult = OK;
     if (mStreamTypeMask == LiveSession::STREAMTYPE_SUBTITLES) {
         sp<AnotherPacketSource> packetSource =
@@ -869,7 +881,7 @@
         // enqueued to prevent us from waiting on a non-existent stream;
         // when we cannot make out from the manifest what streams are included in
         // a playlist we might assume extra streams.
-        bufferedDurationUs = -1ll;
+        bufferedDurationUs = -1LL;
         for (size_t i = 0; i < mPacketSources.size(); ++i) {
             if ((mStreamTypeMask & mPacketSources.keyAt(i)) == 0
                     || mPacketSources[i]->getLatestEnqueuedMeta() == NULL) {
@@ -881,13 +893,13 @@
 
             FSLOGV(mPacketSources.keyAt(i), "buffered %lld", (long long)bufferedStreamDurationUs);
 
-            if (bufferedDurationUs == -1ll
+            if (bufferedDurationUs == -1LL
                  || bufferedStreamDurationUs < bufferedDurationUs) {
                 bufferedDurationUs = bufferedStreamDurationUs;
             }
         }
-        if (bufferedDurationUs == -1ll) {
-            bufferedDurationUs = 0ll;
+        if (bufferedDurationUs == -1LL) {
+            bufferedDurationUs = 0LL;
         }
     }
 
@@ -900,12 +912,12 @@
         // onDownloadNext();
         sp<AMessage> msg = new AMessage(kWhatDownloadNext, this);
         msg->setInt32("generation", mMonitorQueueGeneration);
-        msg->post(1000l);
+        msg->post(1000L);
     } else {
         // We'd like to maintain buffering above durationToBufferUs, so try
         // again when buffer just about to go below durationToBufferUs
         // (or after targetDurationUs / 2, whichever is smaller).
-        int64_t delayUs = bufferedDurationUs - kMinBufferedDurationUs + 1000000ll;
+        int64_t delayUs = bufferedDurationUs - kMinBufferedDurationUs + 1000000LL;
         if (delayUs > targetDurationUs / 2) {
             delayUs = targetDurationUs / 2;
         }
@@ -1072,10 +1084,10 @@
         }
     }
 
-    mSegmentFirstPTS = -1ll;
+    mSegmentFirstPTS = -1LL;
 
     if (mPlaylist != NULL && mSeqNumber < 0) {
-        CHECK_GE(mStartTimeUs, 0ll);
+        CHECK_GE(mStartTimeUs, 0LL);
 
         if (mSegmentStartTimeUs < 0) {
             if (!mPlaylist->isComplete() && !mPlaylist->isEvent()) {
@@ -1365,7 +1377,7 @@
         }
         if (bytesRead < 0) {
             status_t err = bytesRead;
-            ALOGE("failed to fetch .ts segment at url '%s'", uri.c_str());
+            ALOGE("failed to fetch .ts segment at url '%s'", uriDebugString(uri).c_str());
             notifyError(err);
             return;
         }
@@ -1378,7 +1390,7 @@
                         & (LiveSession::STREAMTYPE_AUDIO
                         | LiveSession::STREAMTYPE_VIDEO))) {
             mSession->addBandwidthMeasurement(bytesRead, delayUs);
-            if (delayUs > 2000000ll) {
+            if (delayUs > 2000000LL) {
                 FLOGV("bytesRead %zd took %.2f seconds - abnormal bandwidth dip",
                         bytesRead, (double)delayUs / 1.0e6);
             }
@@ -1552,7 +1564,7 @@
         // if the previous fetcher paused in the middle of a segment, we
         // want to start at a segment that overlaps the last sample
         minDiffUs = -mPlaylist->getTargetDuration();
-        maxDiffUs = 0ll;
+        maxDiffUs = 0LL;
     } else {
         // if the previous fetcher paused at the end of a segment, ideally
         // we want to start at the segment that's roughly aligned with its
@@ -1703,7 +1715,7 @@
         mTSParser = new ATSParser(ATSParser::TS_TIMESTAMPS_ARE_ABSOLUTE);
     }
 
-    if (mNextPTSTimeUs >= 0ll) {
+    if (mNextPTSTimeUs >= 0LL) {
         sp<AMessage> extra = new AMessage;
         // Since we are using absolute timestamps, signal an offset of 0 to prevent
         // ATSParser from skewing the timestamps of access units.
@@ -1718,7 +1730,7 @@
         mTSParser->signalDiscontinuity(
                 ATSParser::DISCONTINUITY_TIME, extra);
 
-        mNextPTSTimeUs = -1ll;
+        mNextPTSTimeUs = -1LL;
     }
 
     if (mSampleAesKeyItemChanged) {
@@ -1739,7 +1751,7 @@
     // setRange to indicate consumed bytes.
     buffer->setRange(buffer->offset() + offset, buffer->size() - offset);
 
-    if (mSegmentFirstPTS < 0ll) {
+    if (mSegmentFirstPTS < 0LL) {
         // get the smallest first PTS from all streams present in this parser
         for (size_t i = mPacketSources.size(); i > 0;) {
             i--;
@@ -1763,12 +1775,12 @@
             if (meta != NULL) {
                 int64_t timeUs;
                 CHECK(meta->findInt64("timeUs", &timeUs));
-                if (mSegmentFirstPTS < 0ll || timeUs < mSegmentFirstPTS) {
+                if (mSegmentFirstPTS < 0LL || timeUs < mSegmentFirstPTS) {
                     mSegmentFirstPTS = timeUs;
                 }
             }
         }
-        if (mSegmentFirstPTS < 0ll) {
+        if (mSegmentFirstPTS < 0LL) {
             // didn't find any TS packet, can return early
             return OK;
         }
@@ -1987,8 +1999,8 @@
         return OK;
     }
 
-    if (mNextPTSTimeUs >= 0ll) {
-        mNextPTSTimeUs = -1ll;
+    if (mNextPTSTimeUs >= 0LL) {
+        mNextPTSTimeUs = -1LL;
     }
 
     // This better be an ISO 13818-7 (AAC) or ISO 13818-1 (MPEG) audio
@@ -2087,17 +2099,17 @@
         packetSource->setFormat(meta);
     }
 
-    int64_t numSamples = 0ll;
+    int64_t numSamples = 0LL;
     int32_t sampleRate;
     CHECK(packetSource->getFormat()->findInt32(kKeySampleRate, &sampleRate));
 
-    int64_t timeUs = (PTS * 100ll) / 9ll;
+    int64_t timeUs = (PTS * 100LL) / 9LL;
     if (mStartup && !mFirstPTSValid) {
         mFirstPTSValid = true;
         mFirstTimeUs = timeUs;
     }
 
-    if (mSegmentFirstPTS < 0ll) {
+    if (mSegmentFirstPTS < 0LL) {
         mSegmentFirstPTS = timeUs;
         if (!mStartTimeUsRelative) {
             // Duplicated logic from how we handle .ts playlists.
@@ -2124,7 +2136,10 @@
     size_t offset = 0;
     while (offset < buffer->size()) {
         const uint8_t *adtsHeader = buffer->data() + offset;
-        CHECK_LT(offset + 5, buffer->size());
+        if (buffer->size() <= offset+5) {
+            ALOGV("buffer does not contain a complete header");
+            return ERROR_MALFORMED;
+        }
         // non-const pointer for decryption if needed
         uint8_t *adtsFrame = buffer->data() + offset;
 
@@ -2147,7 +2162,7 @@
 
         CHECK_LE(offset + aac_frame_length, buffer->size());
 
-        int64_t unitTimeUs = timeUs + numSamples * 1000000ll / sampleRate;
+        int64_t unitTimeUs = timeUs + numSamples * 1000000LL / sampleRate;
         offset += aac_frame_length;
 
         // Each AAC frame encodes 1024 samples.
@@ -2208,7 +2223,7 @@
 }
 
 void PlaylistFetcher::updateDuration() {
-    int64_t durationUs = 0ll;
+    int64_t durationUs = 0LL;
     for (size_t index = 0; index < mPlaylist->size(); ++index) {
         sp<AMessage> itemMeta;
         CHECK(mPlaylist->itemAt(
diff --git a/media/libstagefright/httplive/PlaylistFetcher.h b/media/libstagefright/httplive/PlaylistFetcher.h
index d7db54a..5d3f9c1 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.h
+++ b/media/libstagefright/httplive/PlaylistFetcher.h
@@ -145,6 +145,7 @@
     sp<M3UParser> mPlaylist;
     int32_t mSeqNumber;
     int32_t mNumRetries;
+    int32_t mNumRetriesForMonitorQueue;
     bool mStartup;
     bool mIDRFound;
     int32_t mSeekMode;
diff --git a/media/libstagefright/id3/Android.bp b/media/libstagefright/id3/Android.bp
index 37f9d50..7151d07 100644
--- a/media/libstagefright/id3/Android.bp
+++ b/media/libstagefright/id3/Android.bp
@@ -3,6 +3,10 @@
 
     srcs: ["ID3.cpp"],
 
+    header_libs: [
+        "media_ndk_headers",
+    ],
+
     cflags: [
         "-Werror",
         "-Wall",
@@ -12,9 +16,6 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 }
 
@@ -43,9 +44,6 @@
 
     sanitize: {
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
 }
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index a0a62f4..792a68a 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -21,6 +21,8 @@
 #include "../include/ID3.h"
 
 #include <media/DataSource.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ByteUtils.h>
 #include <utils/String8.h>
@@ -41,7 +43,7 @@
     }
 
     virtual ssize_t readAt(off64_t offset, void *data, size_t size) {
-        off64_t available = (offset >= (off64_t)mSize) ? 0ll : mSize - offset;
+        off64_t available = (offset >= (off64_t)mSize) ? 0LL : mSize - offset;
 
         size_t copy = (available > (off64_t)size) ? size : available;
         memcpy(data, mData + offset, copy);
@@ -56,6 +58,55 @@
     DISALLOW_EVIL_CONSTRUCTORS(MemorySource);
 };
 
+class DataSourceUnwrapper : public DataSourceBase {
+
+public:
+    explicit DataSourceUnwrapper(DataSourceHelper *sourcehelper) {
+        mSource = sourcehelper;
+    }
+    virtual status_t initCheck() const { return OK; }
+
+    // Returns the number of bytes read, or -1 on failure. It's not an error if
+    // this returns zero; it just means the given offset is equal to, or
+    // beyond, the end of the source.
+    virtual ssize_t readAt(off64_t offset, void *data, size_t size) {
+        return mSource->readAt(offset, data, size);
+    }
+
+    // May return ERROR_UNSUPPORTED.
+    virtual status_t getSize(off64_t *size) {
+        return mSource->getSize(size);
+    }
+
+    virtual bool getUri(char * /*uriString*/, size_t /*bufferSize*/) {
+        return false;
+    }
+
+    virtual uint32_t flags() {
+        return 0;
+    }
+
+    virtual void close() {};
+private:
+    DataSourceHelper *mSource;
+};
+
+
+ID3::ID3(DataSourceHelper *sourcehelper, bool ignoreV1, off64_t offset)
+    : mIsValid(false),
+      mData(NULL),
+      mSize(0),
+      mFirstFrameOffset(0),
+      mVersion(ID3_UNKNOWN),
+      mRawSize(0) {
+    DataSourceUnwrapper source(sourcehelper);
+    mIsValid = parseV2(&source, offset);
+
+    if (!mIsValid && !ignoreV1) {
+        mIsValid = parseV1(&source);
+    }
+}
+
 ID3::ID3(DataSourceBase *source, bool ignoreV1, off64_t offset)
     : mIsValid(false),
       mData(NULL),
diff --git a/media/libstagefright/include/HTTPBase.h b/media/libstagefright/include/HTTPBase.h
index a924197..8b20187 100644
--- a/media/libstagefright/include/HTTPBase.h
+++ b/media/libstagefright/include/HTTPBase.h
@@ -51,12 +51,6 @@
 
     virtual void setBandwidthHistorySize(size_t numHistoryItems);
 
-    static void RegisterSocketUserTag(int sockfd, uid_t uid, uint32_t kTag);
-    static void UnRegisterSocketUserTag(int sockfd);
-
-    static void RegisterSocketUserMark(int sockfd, uid_t uid);
-    static void UnRegisterSocketUserMark(int sockfd);
-
     virtual String8 toString() {
         return mName;
     }
diff --git a/media/libstagefright/include/ID3.h b/media/libstagefright/include/ID3.h
index 7c2391e..5e433ea 100644
--- a/media/libstagefright/include/ID3.h
+++ b/media/libstagefright/include/ID3.h
@@ -24,6 +24,7 @@
 
 class DataSourceBase;
 class String8;
+class DataSourceHelper;
 
 struct ID3 {
     enum Version {
@@ -35,6 +36,7 @@
         ID3_V2_4,
     };
 
+    explicit ID3(DataSourceHelper *source, bool ignoreV1 = false, off64_t offset = 0);
     explicit ID3(DataSourceBase *source, bool ignoreV1 = false, off64_t offset = 0);
     ID3(const uint8_t *data, size_t size, bool ignoreV1 = false);
     ~ID3();
diff --git a/media/libstagefright/include/NuCachedSource2.h b/media/libstagefright/include/NuCachedSource2.h
index f439a1c..596efb8 100644
--- a/media/libstagefright/include/NuCachedSource2.h
+++ b/media/libstagefright/include/NuCachedSource2.h
@@ -37,6 +37,8 @@
 
     virtual ssize_t readAt(off64_t offset, void *data, size_t size);
 
+    virtual void close();
+
     virtual void disconnect();
 
     virtual status_t getSize(off64_t *size);
@@ -51,6 +53,8 @@
         return mName;
     }
 
+    status_t getAvailableSize(off64_t offset, off64_t *size);
+
     ////////////////////////////////////////////////////////////////////////////
 
     size_t cachedSize();
@@ -135,7 +139,7 @@
     ssize_t readInternal(off64_t offset, void *data, size_t size);
     status_t seekInternal_l(off64_t offset);
 
-    size_t approxDataRemaining_l(status_t *finalStatus) const;
+    size_t approxDataRemaining_l(off64_t offset, status_t *finalStatus) const;
 
     void restartPrefetcherIfNecessary_l(
             bool ignoreLowWaterThreshold = false, bool force = false);
diff --git a/media/libstagefright/include/SoftwareRenderer.h b/media/libstagefright/include/SoftwareRenderer.h
index c286516..64dca4e 100644
--- a/media/libstagefright/include/SoftwareRenderer.h
+++ b/media/libstagefright/include/SoftwareRenderer.h
@@ -51,7 +51,7 @@
     ColorConverter *mConverter;
     YUVMode mYUVMode;
     sp<ANativeWindow> mNativeWindow;
-    int32_t mWidth, mHeight;
+    int32_t mWidth, mHeight, mStride;
     int32_t mCropLeft, mCropTop, mCropRight, mCropBottom;
     int32_t mCropWidth, mCropHeight;
     int32_t mRotationDegrees;
diff --git a/media/libstagefright/include/StagefrightMetadataRetriever.h b/media/libstagefright/include/StagefrightMetadataRetriever.h
index f78e125..c50677a 100644
--- a/media/libstagefright/include/StagefrightMetadataRetriever.h
+++ b/media/libstagefright/include/StagefrightMetadataRetriever.h
@@ -26,7 +26,6 @@
 namespace android {
 
 class DataSource;
-class MediaExtractor;
 struct ImageDecoder;
 struct FrameRect;
 
@@ -66,6 +65,7 @@
     sp<ImageDecoder> mImageDecoder;
     int mLastImageIndex;
     void parseMetaData();
+    void parseColorAspects(const sp<MetaData>& meta);
     // Delete album art and clear metadata.
     void clearMetadata();
 
diff --git a/media/libstagefright/include/media/stagefright/ACodec.h b/media/libstagefright/include/media/stagefright/ACodec.h
index 97d15a7..784fd36 100644
--- a/media/libstagefright/include/media/stagefright/ACodec.h
+++ b/media/libstagefright/include/media/stagefright/ACodec.h
@@ -22,7 +22,7 @@
 #include <media/hardware/MetadataBufferType.h>
 #include <media/MediaCodecInfo.h>
 #include <media/IOMX.h>
-#include <media/stagefright/foundation/AHierarchicalStateMachine.h>
+#include <media/stagefright/AHierarchicalStateMachine.h>
 #include <media/stagefright/CodecBase.h>
 #include <media/stagefright/FrameRenderTracker.h>
 #include <media/stagefright/MediaDefs.h>
@@ -137,6 +137,7 @@
         kWhatOMXDied                 = 'OMXd',
         kWhatReleaseCodecInstance    = 'relC',
         kWhatForceStateTransition    = 'fstt',
+        kWhatCheckIfStuck            = 'Cstk',
     };
 
     enum {
@@ -236,6 +237,8 @@
     android_native_rect_t mLastNativeWindowCrop;
     int32_t mLastNativeWindowDataSpace;
     HDRStaticInfo mLastHDRStaticInfo;
+    sp<ABuffer> mHdr10PlusScratchBuffer;
+    sp<ABuffer> mLastHdr10PlusBuffer;
     sp<AMessage> mConfigFormat;
     sp<AMessage> mInputFormat;
     sp<AMessage> mOutputFormat;
@@ -283,12 +286,13 @@
     double mFps;
     double mCaptureFps;
     bool mCreateInputBuffersSuspended;
-    uint32_t mLatency;
+    std::optional<uint32_t> mLatency;
 
     bool mTunneled;
 
     OMX_INDEXTYPE mDescribeColorAspectsIndex;
     OMX_INDEXTYPE mDescribeHDRStaticInfoIndex;
+    OMX_INDEXTYPE mDescribeHDR10PlusInfoIndex;
 
     std::shared_ptr<ACodecBufferChannel> mBufferChannel;
 
@@ -423,6 +427,11 @@
     // unspecified values.
     void onDataSpaceChanged(android_dataspace dataSpace, const ColorAspects &aspects);
 
+    // notifies the codec that the config with |configIndex| has changed, the value
+    // can be queried by OMX getConfig, and the config should be applied to the next
+    // output buffer notified after this callback.
+    void onConfigUpdate(OMX_INDEXTYPE configIndex);
+
     // gets index or sets it to 0 on error. Returns error from codec.
     status_t initDescribeHDRStaticInfoIndex();
 
@@ -434,12 +443,22 @@
     // sets |params|. Returns the codec error.
     status_t setHDRStaticInfo(const DescribeHDRStaticInfoParams &params);
 
+    // sets |hdr10PlusInfo|. Returns the codec error.
+    status_t setHdr10PlusInfo(const sp<ABuffer> &hdr10PlusInfo);
+
     // gets |params|. Returns the codec error.
     status_t getHDRStaticInfo(DescribeHDRStaticInfoParams &params);
 
     // gets HDR static information for the video encoder/decoder port and sets them into |format|.
     status_t getHDRStaticInfoForVideoCodec(OMX_U32 portIndex, sp<AMessage> &format);
 
+    // gets DescribeHDR10PlusInfoParams params. If |paramSizeUsed| is zero, it's
+    // possible that the returned DescribeHDR10PlusInfoParams only has the
+    // nParamSizeUsed field updated, because the size of the storage is insufficient.
+    // In this case, getHDR10PlusInfo() should be called again with |paramSizeUsed|
+    // specified to the previous returned value.
+    DescribeHDR10PlusInfoParams* getHDR10PlusInfo(size_t paramSizeUsed = 0);
+
     typedef struct drcParams {
         int32_t drcCut;
         int32_t drcBoost;
@@ -460,6 +479,8 @@
 
     status_t setupEAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate);
 
+    status_t setupAC4Codec(bool encoder, int32_t numChannels, int32_t sampleRate);
+
     status_t selectAudioPortFormat(
             OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat);
 
@@ -467,7 +488,8 @@
     status_t setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels);
 
     status_t setupFlacCodec(
-            bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel);
+            bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel,
+            AudioEncoding encoding);
 
     status_t setupRawAudioFormat(
             OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels,
@@ -476,6 +498,7 @@
     status_t setPriority(int32_t priority);
     status_t setLatency(uint32_t latency);
     status_t getLatency(uint32_t *latency);
+    status_t setAudioPresentation(int32_t presentationId, int32_t programId);
     status_t setOperatingRate(float rateFloat, bool isVideo);
     status_t getIntraRefreshPeriod(uint32_t *intraRefreshPeriod);
     status_t setIntraRefreshPeriod(uint32_t intraRefreshPeriod, bool inConfigure);
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AHierarchicalStateMachine.h b/media/libstagefright/include/media/stagefright/AHierarchicalStateMachine.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/AHierarchicalStateMachine.h
rename to media/libstagefright/include/media/stagefright/AHierarchicalStateMachine.h
diff --git a/media/libstagefright/include/media/stagefright/AudioSource.h b/media/libstagefright/include/media/stagefright/AudioSource.h
index 206d322..af04dad 100644
--- a/media/libstagefright/include/media/stagefright/AudioSource.h
+++ b/media/libstagefright/include/media/stagefright/AudioSource.h
@@ -44,7 +44,9 @@
             uint32_t outSampleRate = 0,
             uid_t uid = -1,
             pid_t pid = -1,
-            audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE);
+            audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE,
+            audio_microphone_direction_t selectedMicDirection = MIC_DIRECTION_UNSPECIFIED,
+            float selectedMicFieldDimension = MIC_FIELD_DIMENSION_NORMAL);
 
     status_t initCheck() const;
 
@@ -68,7 +70,10 @@
     status_t removeAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback);
 
     status_t getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones);
+    status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction);
+    status_t setPreferredMicrophoneFieldDimension(float zoom);
 
+    status_t getPortId(audio_port_handle_t *portId) const;
 
 protected:
     virtual ~AudioSource();
diff --git a/media/libstagefright/include/media/stagefright/ClearFileSource.h b/media/libstagefright/include/media/stagefright/ClearFileSource.h
new file mode 100644
index 0000000..be83748
--- /dev/null
+++ b/media/libstagefright/include/media/stagefright/ClearFileSource.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CLEAR_FILE_SOURCE_H_
+
+#define CLEAR_FILE_SOURCE_H_
+
+#include <stdio.h>
+
+#include <media/DataSource.h>
+#include <media/stagefright/MediaErrors.h>
+#include <utils/threads.h>
+
+namespace android {
+
+class ClearFileSource : public DataSource {
+public:
+    ClearFileSource(const char *filename);
+    // ClearFileSource takes ownership and will close the fd
+    ClearFileSource(int fd, int64_t offset, int64_t length);
+
+    virtual status_t initCheck() const;
+
+    virtual ssize_t readAt(off64_t offset, void *data, size_t size);
+
+    virtual status_t getSize(off64_t *size);
+
+    virtual uint32_t flags() {
+        return kIsLocalFileSource;
+    }
+
+    virtual String8 toString() {
+        return mName;
+    }
+
+protected:
+    virtual ~ClearFileSource();
+    virtual ssize_t readAt_l(off64_t offset, void *data, size_t size);
+
+    int mFd;
+    int64_t mOffset;
+    int64_t mLength;
+    Mutex mLock;
+
+private:
+    String8 mName;
+
+    ClearFileSource(const ClearFileSource &);
+    ClearFileSource &operator=(const ClearFileSource &);
+};
+
+}  // namespace android
+
+#endif  // CLEAR_FILE_SOURCE_H_
+
diff --git a/media/libstagefright/include/media/stagefright/ClearMediaHTTP.h b/media/libstagefright/include/media/stagefright/ClearMediaHTTP.h
new file mode 100644
index 0000000..72907a9
--- /dev/null
+++ b/media/libstagefright/include/media/stagefright/ClearMediaHTTP.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CLEAR_MEDIA_HTTP_H_
+
+#define CLEAR_MEDIA_HTTP_H_
+
+#include <media/stagefright/foundation/AString.h>
+
+#include "include/HTTPBase.h"
+
+namespace android {
+
+struct MediaHTTPConnection;
+
+struct ClearMediaHTTP : public HTTPBase {
+    ClearMediaHTTP(const sp<MediaHTTPConnection> &conn);
+
+    virtual status_t connect(
+            const char *uri,
+            const KeyedVector<String8, String8> *headers,
+            off64_t offset);
+
+    virtual void close();
+
+    virtual void disconnect();
+
+    virtual status_t initCheck() const;
+
+    virtual ssize_t readAt(off64_t offset, void *data, size_t size);
+
+    virtual status_t getSize(off64_t *size);
+
+    virtual uint32_t flags();
+
+    virtual status_t reconnectAtOffset(off64_t offset);
+
+protected:
+    virtual ~ClearMediaHTTP();
+
+    virtual String8 getUri();
+    virtual String8 getMIMEType() const;
+
+    AString mLastURI;
+
+private:
+    status_t mInitCheck;
+    sp<MediaHTTPConnection> mHTTPConnection;
+
+    KeyedVector<String8, String8> mLastHeaders;
+
+    bool mCachedSizeValid;
+    off64_t mCachedSize;
+
+    DISALLOW_EVIL_CONSTRUCTORS(ClearMediaHTTP);
+};
+
+}  // namespace android
+
+#endif  // CLEAR_MEDIA_HTTP_H_
diff --git a/media/libstagefright/include/media/stagefright/ColorConverter.h b/media/libstagefright/include/media/stagefright/ColorConverter.h
index 5b3543d..75b0d8e 100644
--- a/media/libstagefright/include/media/stagefright/ColorConverter.h
+++ b/media/libstagefright/include/media/stagefright/ColorConverter.h
@@ -35,21 +35,32 @@
 
     bool isDstRGB() const;
 
+    void setSrcColorSpace(uint32_t standard, uint32_t range, uint32_t transfer);
+
     status_t convert(
             const void *srcBits,
-            size_t srcWidth, size_t srcHeight,
+            size_t srcWidth, size_t srcHeight, size_t srcStride,
             size_t srcCropLeft, size_t srcCropTop,
             size_t srcCropRight, size_t srcCropBottom,
             void *dstBits,
-            size_t dstWidth, size_t dstHeight,
+            size_t dstWidth, size_t dstHeight, size_t dstStride,
             size_t dstCropLeft, size_t dstCropTop,
             size_t dstCropRight, size_t dstCropBottom);
 
 private:
+    struct ColorSpace {
+        uint32_t mStandard;
+        uint32_t mRange;
+        uint32_t mTransfer;
+
+        bool isBt709();
+        bool isJpeg();
+    };
+
     struct BitmapParams {
         BitmapParams(
                 void *bits,
-                size_t width, size_t height,
+                size_t width, size_t height, size_t stride,
                 size_t cropLeft, size_t cropTop,
                 size_t cropRight, size_t cropBottom,
                 OMX_COLOR_FORMATTYPE colorFromat);
@@ -65,6 +76,7 @@
     };
 
     OMX_COLOR_FORMATTYPE mSrcFormat, mDstFormat;
+    ColorSpace mSrcColorSpace;
     uint8_t *mClip;
 
     uint8_t *initClip();
@@ -78,6 +90,9 @@
     status_t convertYUV420PlanarUseLibYUV(
             const BitmapParams &src, const BitmapParams &dst);
 
+    status_t convertYUV420SemiPlanarUseLibYUV(
+            const BitmapParams &src, const BitmapParams &dst);
+
     status_t convertYUV420Planar16(
             const BitmapParams &src, const BitmapParams &dst);
 
diff --git a/media/libstagefright/include/media/stagefright/DataSource.h b/media/libstagefright/include/media/stagefright/DataSource.h
new file mode 100644
index 0000000..1f7a473
--- /dev/null
+++ b/media/libstagefright/include/media/stagefright/DataSource.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef DATA_SOURCE_H_
+
+#define DATA_SOURCE_H_
+
+#include <sys/types.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/DataSourceBase.h>
+#include <media/IDataSource.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/threads.h>
+#include <drm/DrmManagerClient.h>
+
+
+namespace android {
+
+class String8;
+
+class DataSource : public DataSourceBase, public virtual RefBase {
+public:
+    DataSource() : mWrapper(NULL) {}
+
+    // returns a pointer to IDataSource if it is wrapped.
+    virtual sp<IDataSource> getIDataSource() const {
+        return nullptr;
+    }
+
+    virtual String8 toString() {
+        return String8("<unspecified>");
+    }
+
+    virtual status_t reconnectAtOffset(off64_t /*offset*/) {
+        return ERROR_UNSUPPORTED;
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+
+    // for DRM
+    virtual sp<DecryptHandle> DrmInitialization(const char * /*mime*/ = NULL) {
+        return NULL;
+    }
+
+    virtual String8 getUri() {
+        return String8();
+    }
+
+    virtual bool getUri(char *uriString, size_t bufferSize) final {
+        int ret = snprintf(uriString, bufferSize, "%s", getUri().c_str());
+        return ret >= 0 && static_cast<size_t>(ret) < bufferSize;
+    }
+
+    virtual String8 getMIMEType() const {
+        return String8("application/octet-stream");
+    }
+
+    CDataSource *wrap() {
+        if (mWrapper) {
+            return mWrapper;
+        }
+        mWrapper = new CDataSource();
+        mWrapper->handle = this;
+
+        mWrapper->readAt = [](void *handle, off64_t offset, void *data, size_t size) -> ssize_t {
+            return ((DataSource*)handle)->readAt(offset, data, size);
+        };
+        mWrapper->getSize = [](void *handle, off64_t *size) -> status_t {
+            return ((DataSource*)handle)->getSize(size);
+        };
+        mWrapper->flags = [](void *handle) -> uint32_t {
+            return ((DataSource*)handle)->flags();
+        };
+        mWrapper->getUri = [](void *handle, char *uriString, size_t bufferSize) -> bool {
+            return ((DataSource*)handle)->getUri(uriString, bufferSize);
+        };
+        return mWrapper;
+    }
+
+protected:
+    virtual ~DataSource() {
+        delete mWrapper;
+    }
+
+private:
+    CDataSource *mWrapper;
+    DataSource(const DataSource &);
+    DataSource &operator=(const DataSource &);
+};
+
+}  // namespace android
+
+#endif  // DATA_SOURCE_H_
diff --git a/media/libstagefright/include/media/stagefright/DataSourceBase.h b/media/libstagefright/include/media/stagefright/DataSourceBase.h
new file mode 100644
index 0000000..c607c91
--- /dev/null
+++ b/media/libstagefright/include/media/stagefright/DataSourceBase.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef DATA_SOURCE_BASE_H_
+
+#define DATA_SOURCE_BASE_H_
+
+#include <media/stagefright/foundation/ByteUtils.h>
+#include <media/stagefright/MediaErrors.h>
+#include <sys/types.h>
+#include <utils/Errors.h>
+
+namespace android {
+
+class String8;
+
+class DataSourceBase {
+public:
+    enum Flags {
+        kWantsPrefetching      = 1,
+        kStreamedFromLocalHost = 2,
+        kIsCachingDataSource   = 4,
+        kIsHTTPBasedSource     = 8,
+        kIsLocalFileSource     = 16,
+    };
+
+    DataSourceBase() {}
+
+    virtual status_t initCheck() const = 0;
+
+    // Returns the number of bytes read, or -1 on failure. It's not an error if
+    // this returns zero; it just means the given offset is equal to, or
+    // beyond, the end of the source.
+    virtual ssize_t readAt(off64_t offset, void *data, size_t size) = 0;
+
+    // Convenience methods:
+    bool getUInt16(off64_t offset, uint16_t *x) {
+        *x = 0;
+
+        uint8_t byte[2];
+        if (readAt(offset, byte, 2) != 2) {
+            return false;
+        }
+
+        *x = (byte[0] << 8) | byte[1];
+
+        return true;
+    }
+    // 3 byte int, returned as a 32-bit int
+    bool getUInt24(off64_t offset, uint32_t *x) {
+        *x = 0;
+
+        uint8_t byte[3];
+        if (readAt(offset, byte, 3) != 3) {
+            return false;
+        }
+
+        *x = (byte[0] << 16) | (byte[1] << 8) | byte[2];
+
+        return true;
+    }
+    bool getUInt32(off64_t offset, uint32_t *x) {
+        *x = 0;
+
+        uint32_t tmp;
+        if (readAt(offset, &tmp, 4) != 4) {
+            return false;
+        }
+
+        *x = ntohl(tmp);
+
+        return true;
+    }
+    bool getUInt64(off64_t offset, uint64_t *x) {
+        *x = 0;
+
+        uint64_t tmp;
+        if (readAt(offset, &tmp, 8) != 8) {
+            return false;
+        }
+
+        *x = ntoh64(tmp);
+
+        return true;
+    }
+
+    // read either int<N> or int<2N> into a uint<2N>_t, size is the int size in bytes.
+    bool getUInt16Var(off64_t offset, uint16_t *x, size_t size) {
+        if (size == 2) {
+            return getUInt16(offset, x);
+        }
+        if (size == 1) {
+            uint8_t tmp;
+            if (readAt(offset, &tmp, 1) == 1) {
+                *x = tmp;
+                return true;
+            }
+        }
+        return false;
+    }
+    bool getUInt32Var(off64_t offset, uint32_t *x, size_t size) {
+        if (size == 4) {
+            return getUInt32(offset, x);
+        }
+        if (size == 2) {
+            uint16_t tmp;
+            if (getUInt16(offset, &tmp)) {
+                *x = tmp;
+                return true;
+            }
+        }
+        return false;
+    }
+    bool getUInt64Var(off64_t offset, uint64_t *x, size_t size) {
+        if (size == 8) {
+            return getUInt64(offset, x);
+        }
+        if (size == 4) {
+            uint32_t tmp;
+            if (getUInt32(offset, &tmp)) {
+                *x = tmp;
+                return true;
+            }
+        }
+        return false;
+    }
+
+    // May return ERROR_UNSUPPORTED.
+    virtual status_t getSize(off64_t *size) {
+        *size = 0;
+        return ERROR_UNSUPPORTED;
+    }
+
+    virtual bool getUri(char * /*uriString*/, size_t /*bufferSize*/) {
+        return false;
+    }
+
+    virtual uint32_t flags() {
+        return 0;
+    }
+
+    virtual void close() {};
+
+    virtual status_t getAvailableSize(off64_t /*offset*/, off64_t * /*size*/) {
+        return -1;
+    }
+
+protected:
+    virtual ~DataSourceBase() {}
+
+private:
+    DataSourceBase(const DataSourceBase &);
+    DataSourceBase &operator=(const DataSourceBase &);
+};
+
+}  // namespace android
+
+#endif  // DATA_SOURCE_BASE_H_
diff --git a/media/libstagefright/include/media/stagefright/FileSource.h b/media/libstagefright/include/media/stagefright/FileSource.h
index 8604890..b610eef 100644
--- a/media/libstagefright/include/media/stagefright/FileSource.h
+++ b/media/libstagefright/include/media/stagefright/FileSource.h
@@ -20,47 +20,29 @@
 
 #include <stdio.h>
 
-#include <media/DataSource.h>
+#include <media/stagefright/ClearFileSource.h>
 #include <media/stagefright/MediaErrors.h>
 #include <utils/threads.h>
 #include <drm/DrmManagerClient.h>
 
 namespace android {
 
-class FileSource : public DataSource {
+class FileSource : public ClearFileSource {
 public:
     FileSource(const char *filename);
     // FileSource takes ownership and will close the fd
     FileSource(int fd, int64_t offset, int64_t length);
 
-    virtual status_t initCheck() const;
-
     virtual ssize_t readAt(off64_t offset, void *data, size_t size);
 
-    virtual status_t getSize(off64_t *size);
-
-    virtual uint32_t flags() {
-        return kIsLocalFileSource;
-    }
-
     virtual sp<DecryptHandle> DrmInitialization(const char *mime);
 
-    virtual String8 toString() {
-        return mName;
-    }
-
     static bool requiresDrm(int fd, int64_t offset, int64_t length, const char *mime);
 
 protected:
     virtual ~FileSource();
 
 private:
-    int mFd;
-    int64_t mOffset;
-    int64_t mLength;
-    Mutex mLock;
-    String8 mName;
-
     /*for DRM*/
     sp<DecryptHandle> mDecryptHandle;
     DrmManagerClient *mDrmManagerClient;
@@ -68,7 +50,7 @@
     ssize_t mDrmBufSize;
     unsigned char *mDrmBuf;
 
-    ssize_t readAtDRM(off64_t offset, void *data, size_t size);
+    ssize_t readAtDRM_l(off64_t offset, void *data, size_t size);
 
     FileSource(const FileSource &);
     FileSource &operator=(const FileSource &);
diff --git a/media/libstagefright/include/media/stagefright/InterfaceUtils.h b/media/libstagefright/include/media/stagefright/InterfaceUtils.h
index f0ebd48..b83a958 100644
--- a/media/libstagefright/include/media/stagefright/InterfaceUtils.h
+++ b/media/libstagefright/include/media/stagefright/InterfaceUtils.h
@@ -18,7 +18,6 @@
 #define INTERFACE_UTILS_H_
 
 #include <utils/RefBase.h>
-#include <media/MediaExtractor.h>
 #include <media/stagefright/RemoteMediaExtractor.h>
 #include <media/MediaSource.h>
 #include <media/IMediaExtractor.h>
diff --git a/media/libstagefright/include/media/stagefright/MPEG4Writer.h b/media/libstagefright/include/media/stagefright/MPEG4Writer.h
index f18940d..6f19023 100644
--- a/media/libstagefright/include/media/stagefright/MPEG4Writer.h
+++ b/media/libstagefright/include/media/stagefright/MPEG4Writer.h
@@ -82,10 +82,6 @@
         kWhatSwitch                          = 'swch',
     };
 
-    enum {
-        kMaxCttsOffsetTimeUs = 1000000LL,  // 1 second
-    };
-
     int  mFd;
     int mNextFd;
     sp<MetaData> mStartMeta;
@@ -110,6 +106,7 @@
     uint32_t mInterleaveDurationUs;
     int32_t mTimeScale;
     int64_t mStartTimestampUs;
+    int32_t mStartTimeOffsetBFramesUs; // Start time offset when B Frames are present
     int mLatitudex10000;
     int mLongitudex10000;
     bool mAreGeoTagsAvailable;
@@ -129,6 +126,7 @@
 
     void setStartTimestampUs(int64_t timeUs);
     int64_t getStartTimestampUs();  // Not const
+    int32_t getStartTimeOffsetBFramesUs();
     status_t startTracks(MetaData *params);
     size_t numTracks();
     int64_t estimateMoovBoxSize(int32_t bitRate);
@@ -255,7 +253,9 @@
     void initInternal(int fd, bool isFirstSession);
 
     // Acquire lock before calling these methods
-    off64_t addSample_l(MediaBuffer *buffer, bool usePrefix, bool isExif, size_t *bytesWritten);
+    off64_t addSample_l(
+            MediaBuffer *buffer, bool usePrefix,
+            uint32_t tiffHdrOffset, size_t *bytesWritten);
     void addLengthPrefixedSample_l(MediaBuffer *buffer);
     void addMultipleLengthPrefixedSamples_l(MediaBuffer *buffer);
     uint16_t addProperty_l(const ItemProperty &);
diff --git a/media/libstagefright/include/media/stagefright/MediaBuffer.h b/media/libstagefright/include/media/stagefright/MediaBuffer.h
deleted file mode 120000
index 1d49c1a..0000000
--- a/media/libstagefright/include/media/stagefright/MediaBuffer.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libmediaextractor/include/media/stagefright/MediaBuffer.h
\ No newline at end of file
diff --git a/media/libstagefright/include/media/stagefright/MediaBuffer.h b/media/libstagefright/include/media/stagefright/MediaBuffer.h
new file mode 100644
index 0000000..ace63ae
--- /dev/null
+++ b/media/libstagefright/include/media/stagefright/MediaBuffer.h
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MEDIA_BUFFER_H_
+
+#define MEDIA_BUFFER_H_
+
+#include <atomic>
+#include <list>
+
+#include <pthread.h>
+
+#include <binder/MemoryDealer.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <media/stagefright/MediaBufferBase.h>
+
+namespace android {
+
+struct ABuffer;
+class MediaBuffer;
+class MediaBufferObserver;
+class MetaDataBase;
+
+class MediaBuffer : public MediaBufferBase {
+public:
+    // allocations larger than or equal to this will use shared memory.
+    static const size_t kSharedMemThreshold = 64 * 1024;
+
+    // The underlying data remains the responsibility of the caller!
+    MediaBuffer(void *data, size_t size);
+
+    explicit MediaBuffer(size_t size);
+
+    explicit MediaBuffer(const sp<ABuffer> &buffer);
+#ifndef NO_IMEMORY
+    MediaBuffer(const sp<IMemory> &mem) :
+        MediaBuffer((uint8_t *)mem->pointer() + sizeof(SharedControl), mem->size()) {
+        // delegate and override mMemory
+        mMemory = mem;
+    }
+#endif
+
+    // If MediaBufferGroup is set, decrement the local reference count;
+    // if the local reference count drops to 0, return the buffer to the
+    // associated MediaBufferGroup.
+    //
+    // If no MediaBufferGroup is set, the local reference count must be zero
+    // when called, whereupon the MediaBuffer is deleted.
+    virtual void release();
+
+    // Increments the local reference count.
+    // Use only when MediaBufferGroup is set.
+    virtual void add_ref();
+
+    virtual void *data() const;
+    virtual size_t size() const;
+
+    virtual size_t range_offset() const;
+    virtual size_t range_length() const;
+
+    virtual void set_range(size_t offset, size_t length);
+
+    MetaDataBase& meta_data();
+
+    // Clears meta data and resets the range to the full extent.
+    virtual void reset();
+
+    virtual void setObserver(MediaBufferObserver *group);
+
+    // sum of localRefcount() and remoteRefcount()
+    // Result should be treated as approximate unless the result precludes concurrent accesses.
+    virtual int refcount() const {
+        return localRefcount() + remoteRefcount();
+    }
+
+    // Result should be treated as approximate unless the result precludes concurrent accesses.
+    virtual int localRefcount() const {
+        return mRefCount.load(std::memory_order_relaxed);
+    }
+
+    virtual int remoteRefcount() const {
+#ifndef NO_IMEMORY
+        if (mMemory.get() == nullptr || mMemory->pointer() == nullptr) return 0;
+        int32_t remoteRefcount =
+                reinterpret_cast<SharedControl *>(mMemory->pointer())->getRemoteRefcount();
+        // Sanity check so that remoteRefCount() is non-negative.
+        return remoteRefcount >= 0 ? remoteRefcount : 0; // do not allow corrupted data.
+#else
+        return 0;
+#endif
+    }
+
+    // returns old value
+    int addRemoteRefcount(int32_t value) {
+#ifndef NO_IMEMORY
+        if (mMemory.get() == nullptr || mMemory->pointer() == nullptr) return 0;
+        return reinterpret_cast<SharedControl *>(mMemory->pointer())->addRemoteRefcount(value);
+#else
+        (void) value;
+        return 0;
+#endif
+    }
+
+    bool isDeadObject() const {
+        return isDeadObject(mMemory);
+    }
+
+    static bool isDeadObject(const sp<IMemory> &memory) {
+#ifndef NO_IMEMORY
+        if (memory.get() == nullptr || memory->pointer() == nullptr) return false;
+        return reinterpret_cast<SharedControl *>(memory->pointer())->isDeadObject();
+#else
+        (void) memory;
+        return false;
+#endif
+    }
+
+    // Sticky on enabling of shared memory MediaBuffers. By default we don't use
+    // shared memory for MediaBuffers, but we enable this for those processes
+    // that export MediaBuffers.
+    static void useSharedMemory() {
+        std::atomic_store_explicit(
+                &mUseSharedMemory, (int_least32_t)1, std::memory_order_seq_cst);
+    }
+
+protected:
+    // true if MediaBuffer is observed (part of a MediaBufferGroup).
+    inline bool isObserved() const {
+        return mObserver != nullptr;
+    }
+
+    virtual ~MediaBuffer();
+
+    sp<IMemory> mMemory;
+
+private:
+    friend class MediaBufferGroup;
+    friend class OMXDecoder;
+    friend class BnMediaSource;
+    friend class BpMediaSource;
+
+    // For use by OMXDecoder, reference count must be 1, drop reference
+    // count to 0 without signalling the observer.
+    void claim();
+
+    MediaBufferObserver *mObserver;
+    std::atomic<int> mRefCount;
+
+    void *mData;
+    size_t mSize, mRangeOffset, mRangeLength;
+    sp<ABuffer> mBuffer;
+
+    bool mOwnsData;
+
+    MetaDataBase* mMetaData;
+
+    static std::atomic_int_least32_t mUseSharedMemory;
+
+    MediaBuffer(const MediaBuffer &);
+    MediaBuffer &operator=(const MediaBuffer &);
+
+    // SharedControl block at the start of IMemory.
+    struct SharedControl {
+        enum {
+            FLAG_DEAD_OBJECT = (1 << 0),
+        };
+
+        // returns old value
+        inline int32_t addRemoteRefcount(int32_t value) {
+            return std::atomic_fetch_add_explicit(
+                    &mRemoteRefcount, (int_least32_t)value, std::memory_order_seq_cst);
+        }
+
+        inline int32_t getRemoteRefcount() const {
+            return std::atomic_load_explicit(&mRemoteRefcount, std::memory_order_seq_cst);
+        }
+
+        inline void setRemoteRefcount(int32_t value) {
+            std::atomic_store_explicit(
+                    &mRemoteRefcount, (int_least32_t)value, std::memory_order_seq_cst);
+        }
+
+        inline bool isDeadObject() const {
+            return (std::atomic_load_explicit(
+                    &mFlags, std::memory_order_seq_cst) & FLAG_DEAD_OBJECT) != 0;
+        }
+
+        inline void setDeadObject() {
+            (void)std::atomic_fetch_or_explicit(
+                    &mFlags, (int_least32_t)FLAG_DEAD_OBJECT, std::memory_order_seq_cst);
+        }
+
+        inline void clear() {
+            std::atomic_store_explicit(
+                    &mFlags, (int_least32_t)0, std::memory_order_seq_cst);
+            std::atomic_store_explicit(
+                    &mRemoteRefcount, (int_least32_t)0, std::memory_order_seq_cst);
+        }
+
+    private:
+        // Caution: atomic_int_fast32_t is 64 bits on LP64.
+        std::atomic_int_least32_t mFlags;
+        std::atomic_int_least32_t mRemoteRefcount;
+        int32_t unused[6] __attribute__((__unused__)); // additional buffer space
+    };
+
+    inline SharedControl *getSharedControl() const {
+#ifndef NO_IMEMORY
+         return reinterpret_cast<SharedControl *>(mMemory->pointer());
+#else
+         return nullptr;
+#endif
+     }
+};
+
+}  // namespace android
+
+#endif  // MEDIA_BUFFER_H_
diff --git a/media/libstagefright/include/media/stagefright/MediaBufferBase.h b/media/libstagefright/include/media/stagefright/MediaBufferBase.h
deleted file mode 120000
index 80e49b0..0000000
--- a/media/libstagefright/include/media/stagefright/MediaBufferBase.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libmediaextractor/include/media/stagefright/MediaBufferBase.h
\ No newline at end of file
diff --git a/media/libstagefright/include/media/stagefright/MediaBufferBase.h b/media/libstagefright/include/media/stagefright/MediaBufferBase.h
new file mode 100644
index 0000000..e2cbfc8
--- /dev/null
+++ b/media/libstagefright/include/media/stagefright/MediaBufferBase.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MEDIA_BUFFER_BASE_H_
+
+#define MEDIA_BUFFER_BASE_H_
+
+#include <media/MediaExtractorPluginApi.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/NdkMediaFormatPriv.h>
+
+namespace android {
+
+class MediaBufferBase;
+class MetaDataBase;
+
+class MediaBufferObserver {
+public:
+    MediaBufferObserver() {}
+    virtual ~MediaBufferObserver() {}
+
+    virtual void signalBufferReturned(MediaBufferBase *buffer) = 0;
+
+private:
+    MediaBufferObserver(const MediaBufferObserver &);
+    MediaBufferObserver &operator=(const MediaBufferObserver &);
+};
+
+class MediaBufferBase {
+public:
+    static MediaBufferBase *Create(size_t size);
+
+    // If MediaBufferGroup is set, decrement the local reference count;
+    // if the local reference count drops to 0, return the buffer to the
+    // associated MediaBufferGroup.
+    //
+    // If no MediaBufferGroup is set, the local reference count must be zero
+    // when called, whereupon the MediaBuffer is deleted.
+    virtual void release() = 0;
+
+    // Increments the local reference count.
+    // Use only when MediaBufferGroup is set.
+    virtual void add_ref() = 0;
+
+    virtual void *data() const = 0;
+    virtual size_t size() const = 0;
+
+    virtual size_t range_offset() const = 0;
+    virtual size_t range_length() const = 0;
+
+    virtual void set_range(size_t offset, size_t length) = 0;
+
+    virtual MetaDataBase& meta_data() = 0;
+
+    // Clears meta data and resets the range to the full extent.
+    virtual void reset() = 0;
+
+    virtual void setObserver(MediaBufferObserver *group) = 0;
+
+    virtual int refcount() const = 0;
+
+    virtual int localRefcount() const = 0;
+    virtual int remoteRefcount() const = 0;
+
+    virtual ~MediaBufferBase() {
+        delete mWrapper;
+        delete mFormat;
+    };
+
+    CMediaBuffer *wrap() {
+        if (mWrapper) {
+            return mWrapper;
+        }
+        mWrapper = new CMediaBuffer;
+        mWrapper->handle = this;
+
+        mWrapper->release = [](void *handle) -> void {
+            ((MediaBufferBase*)handle)->release();
+        };
+
+        mWrapper->data = [](void *handle) -> void * {
+            return ((MediaBufferBase*)handle)->data();
+        };
+
+        mWrapper->size = [](void *handle) -> size_t {
+            return ((MediaBufferBase*)handle)->size();
+        };
+
+        mWrapper->range_offset = [](void *handle) -> size_t {
+            return ((MediaBufferBase*)handle)->range_offset();
+        };
+
+        mWrapper->range_length = [](void *handle) -> size_t {
+            return ((MediaBufferBase*)handle)->range_length();
+        };
+
+        mWrapper->set_range = [](void *handle, size_t offset, size_t length) -> void {
+            return ((MediaBufferBase*)handle)->set_range(offset, length);
+        };
+
+        mWrapper->meta_data = [](void *handle) -> AMediaFormat* {
+            if (((MediaBufferBase*)handle)->mFormat == nullptr) {
+                sp<AMessage> msg = new AMessage();
+                ((MediaBufferBase*)handle)->mFormat = AMediaFormat_fromMsg(&msg);
+            }
+            return ((MediaBufferBase*)handle)->mFormat;
+        };
+
+        return mWrapper;
+    }
+protected:
+    MediaBufferBase() {
+        mWrapper = nullptr;
+        mFormat = nullptr;
+    }
+private:
+    CMediaBuffer *mWrapper;
+    AMediaFormat *mFormat;
+};
+
+}  // namespace android
+
+#endif  // MEDIA_BUFFER_BASE_H_
diff --git a/media/libstagefright/include/media/stagefright/MediaBufferGroup.h b/media/libstagefright/include/media/stagefright/MediaBufferGroup.h
deleted file mode 120000
index 009b3d9..0000000
--- a/media/libstagefright/include/media/stagefright/MediaBufferGroup.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libmediaextractor/include/media/stagefright/MediaBufferGroup.h
\ No newline at end of file
diff --git a/media/libstagefright/include/media/stagefright/MediaBufferGroup.h b/media/libstagefright/include/media/stagefright/MediaBufferGroup.h
new file mode 100644
index 0000000..a162116
--- /dev/null
+++ b/media/libstagefright/include/media/stagefright/MediaBufferGroup.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MEDIA_BUFFER_GROUP_H_
+
+#define MEDIA_BUFFER_GROUP_H_
+
+#include <list>
+
+#include <media/MediaExtractorPluginApi.h>
+#include <media/NdkMediaErrorPriv.h>
+#include <media/stagefright/MediaBufferBase.h>
+#include <utils/Errors.h>
+#include <utils/threads.h>
+
+namespace android {
+
+class MediaBufferBase;
+
+class MediaBufferGroup : public MediaBufferObserver {
+public:
+    MediaBufferGroup(size_t growthLimit = 0);
+
+    // create a media buffer group with preallocated buffers
+    MediaBufferGroup(size_t buffers, size_t buffer_size, size_t growthLimit = 0);
+
+    ~MediaBufferGroup();
+
+    void add_buffer(MediaBufferBase *buffer);
+
+    bool has_buffers();
+
+    // If nonBlocking is false, it blocks until a buffer is available and
+    // passes it to the caller in *buffer, while returning OK.
+    // The returned buffer will have a reference count of 1.
+    // If nonBlocking is true and a buffer is not immediately available,
+    // buffer is set to NULL and it returns WOULD_BLOCK.
+    // If requestedSize is 0, any free MediaBuffer will be returned.
+    // If requestedSize is > 0, the returned MediaBuffer should have buffer
+    // size of at least requstedSize.
+    status_t acquire_buffer(
+            MediaBufferBase **buffer, bool nonBlocking = false, size_t requestedSize = 0);
+
+    size_t buffers() const;
+
+    // If buffer is nullptr, have acquire_buffer() check for remote release.
+    virtual void signalBufferReturned(MediaBufferBase *buffer);
+
+    CMediaBufferGroup *wrap() {
+        if (mWrapper) {
+            return mWrapper;
+        }
+
+        mWrapper = new CMediaBufferGroup;
+        mWrapper->handle = this;
+
+        mWrapper->add_buffer = [](void *handle, size_t size) -> void {
+            MediaBufferBase *buf = MediaBufferBase::Create(size);
+            ((MediaBufferGroup*)handle)->add_buffer(buf);
+        };
+
+        mWrapper->init = [](void *handle,
+                size_t buffers, size_t buffer_size, size_t growthLimit) -> bool {
+            ((MediaBufferGroup*)handle)->init(buffers, buffer_size, growthLimit);
+          //  ((MediaBufferGroup*)handle)->mWrapper->init = nullptr; // enforce call-once
+            return true;
+        };
+
+        mWrapper->acquire_buffer = [](void *handle,
+                CMediaBuffer **buf, bool nonBlocking, size_t requestedSize) -> media_status_t {
+            MediaBufferBase *acquiredBuf = nullptr;
+            status_t err = ((MediaBufferGroup*)handle)->acquire_buffer(
+                    &acquiredBuf, nonBlocking, requestedSize);
+            if (err == OK && acquiredBuf != nullptr) {
+                *buf = acquiredBuf->wrap();
+            } else {
+                *buf = nullptr;
+            }
+            return translate_error(err);
+        };
+
+        mWrapper->has_buffers = [](void *handle) -> bool {
+            return ((MediaBufferGroup*)handle)->has_buffers();
+        };
+
+        return mWrapper;
+    }
+
+private:
+    CMediaBufferGroup *mWrapper;
+    struct InternalData;
+    InternalData *mInternal;
+
+    MediaBufferGroup(const MediaBufferGroup &);
+    MediaBufferGroup &operator=(const MediaBufferGroup &);
+    void init(size_t buffers, size_t buffer_size, size_t growthLimit);
+};
+
+}  // namespace android
+
+#endif  // MEDIA_BUFFER_GROUP_H_
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index 7f6aae6..89cca63 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -313,6 +313,7 @@
     sp<ALooper> mCodecLooper;
     sp<CodecBase> mCodec;
     AString mComponentName;
+    AString mOwnerName;
     sp<MediaCodecInfo> mCodecInfo;
     sp<AReplyToken> mReplyID;
     uint32_t mFlags;
@@ -339,6 +340,7 @@
     int32_t mVideoWidth;
     int32_t mVideoHeight;
     int32_t mRotationDegrees;
+    int32_t mAllowFrameDroppingBySurface;
 
     // initial create parameters
     AString mInitName;
diff --git a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
index 3ef4c0e..50d7724 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
@@ -31,6 +31,21 @@
 constexpr int32_t AVCProfileConstrainedBaseline = 0x10000;
 constexpr int32_t AVCProfileConstrainedHigh     = 0x80000;
 
+inline static const char *asString_AVCProfile(int32_t i, const char *def = "??") {
+    switch (i) {
+        case AVCProfileBaseline:            return "Baseline";
+        case AVCProfileMain:                return "Main";
+        case AVCProfileExtended:            return "Extended";
+        case AVCProfileHigh:                return "High";
+        case AVCProfileHigh10:              return "High10";
+        case AVCProfileHigh422:             return "High422";
+        case AVCProfileHigh444:             return "High444";
+        case AVCProfileConstrainedBaseline: return "ConstrainedBaseline";
+        case AVCProfileConstrainedHigh:     return "ConstrainedHigh";
+        default:                            return def;
+    }
+}
+
 constexpr int32_t AVCLevel1       = 0x01;
 constexpr int32_t AVCLevel1b      = 0x02;
 constexpr int32_t AVCLevel11      = 0x04;
@@ -48,6 +63,35 @@
 constexpr int32_t AVCLevel5       = 0x4000;
 constexpr int32_t AVCLevel51      = 0x8000;
 constexpr int32_t AVCLevel52      = 0x10000;
+constexpr int32_t AVCLevel6       = 0x20000;
+constexpr int32_t AVCLevel61      = 0x40000;
+constexpr int32_t AVCLevel62      = 0x80000;
+
+inline static const char *asString_AVCLevel(int32_t i, const char *def = "??") {
+    switch (i) {
+        case AVCLevel1:     return "1";
+        case AVCLevel1b:    return "1b";
+        case AVCLevel11:    return "1.1";
+        case AVCLevel12:    return "1.2";
+        case AVCLevel13:    return "1.3";
+        case AVCLevel2:     return "2";
+        case AVCLevel21:    return "2.1";
+        case AVCLevel22:    return "2.2";
+        case AVCLevel3:     return "3";
+        case AVCLevel31:    return "3.1";
+        case AVCLevel32:    return "3.2";
+        case AVCLevel4:     return "4";
+        case AVCLevel41:    return "4.1";
+        case AVCLevel42:    return "4.2";
+        case AVCLevel5:     return "5";
+        case AVCLevel51:    return "5.1";
+        case AVCLevel52:    return "5.2";
+        case AVCLevel6:     return "6";
+        case AVCLevel61:    return "6.1";
+        case AVCLevel62:    return "6.2";
+        default:            return def;
+    }
+}
 
 constexpr int32_t H263ProfileBaseline             = 0x01;
 constexpr int32_t H263ProfileH320Coding           = 0x02;
@@ -59,6 +103,21 @@
 constexpr int32_t H263ProfileInterlace            = 0x80;
 constexpr int32_t H263ProfileHighLatency          = 0x100;
 
+inline static const char *asString_H263Profile(int32_t i, const char *def = "??") {
+    switch (i) {
+        case H263ProfileBaseline:           return "Baseline";
+        case H263ProfileH320Coding:         return "H320Coding";
+        case H263ProfileBackwardCompatible: return "BackwardCompatible";
+        case H263ProfileISWV2:              return "ISWV2";
+        case H263ProfileISWV3:              return "ISWV3";
+        case H263ProfileHighCompression:    return "HighCompression";
+        case H263ProfileInternet:           return "Internet";
+        case H263ProfileInterlace:          return "Interlace";
+        case H263ProfileHighLatency:        return "HighLatency";
+        default:                            return def;
+    }
+}
+
 constexpr int32_t H263Level10      = 0x01;
 constexpr int32_t H263Level20      = 0x02;
 constexpr int32_t H263Level30      = 0x04;
@@ -68,6 +127,20 @@
 constexpr int32_t H263Level60      = 0x40;
 constexpr int32_t H263Level70      = 0x80;
 
+inline static const char *asString_H263Level(int32_t i, const char *def = "??") {
+    switch (i) {
+        case H263Level10:   return "10";
+        case H263Level20:   return "20";
+        case H263Level30:   return "30";
+        case H263Level40:   return "40";
+        case H263Level45:   return "45";
+        case H263Level50:   return "50";
+        case H263Level60:   return "60";
+        case H263Level70:   return "70";
+        default:            return def;
+    }
+}
+
 constexpr int32_t MPEG4ProfileSimple              = 0x01;
 constexpr int32_t MPEG4ProfileSimpleScalable      = 0x02;
 constexpr int32_t MPEG4ProfileCore                = 0x04;
@@ -85,6 +158,28 @@
 constexpr int32_t MPEG4ProfileAdvancedScalable    = 0x4000;
 constexpr int32_t MPEG4ProfileAdvancedSimple      = 0x8000;
 
+inline static const char *asString_MPEG4Profile(int32_t i, const char *def = "??") {
+    switch (i) {
+        case MPEG4ProfileSimple:            return "Simple";
+        case MPEG4ProfileSimpleScalable:    return "SimpleScalable";
+        case MPEG4ProfileCore:              return "Core";
+        case MPEG4ProfileMain:              return "Main";
+        case MPEG4ProfileNbit:              return "Nbit";
+        case MPEG4ProfileScalableTexture:   return "ScalableTexture";
+        case MPEG4ProfileSimpleFace:        return "SimpleFace";
+        case MPEG4ProfileSimpleFBA:         return "SimpleFBA";
+        case MPEG4ProfileBasicAnimated:     return "BasicAnimated";
+        case MPEG4ProfileHybrid:            return "Hybrid";
+        case MPEG4ProfileAdvancedRealTime:  return "AdvancedRealTime";
+        case MPEG4ProfileCoreScalable:      return "CoreScalable";
+        case MPEG4ProfileAdvancedCoding:    return "AdvancedCoding";
+        case MPEG4ProfileAdvancedCore:      return "AdvancedCore";
+        case MPEG4ProfileAdvancedScalable:  return "AdvancedScalable";
+        case MPEG4ProfileAdvancedSimple:    return "AdvancedSimple";
+        default:                            return def;
+    }
+}
+
 constexpr int32_t MPEG4Level0      = 0x01;
 constexpr int32_t MPEG4Level0b     = 0x02;
 constexpr int32_t MPEG4Level1      = 0x04;
@@ -96,6 +191,22 @@
 constexpr int32_t MPEG4Level5      = 0x80;
 constexpr int32_t MPEG4Level6      = 0x100;
 
+inline static const char *asString_MPEG4Level(int32_t i, const char *def = "??") {
+    switch (i) {
+        case MPEG4Level0:   return "0";
+        case MPEG4Level0b:  return "0b";
+        case MPEG4Level1:   return "1";
+        case MPEG4Level2:   return "2";
+        case MPEG4Level3:   return "3";
+        case MPEG4Level3b:  return "3b";
+        case MPEG4Level4:   return "4";
+        case MPEG4Level4a:  return "4a";
+        case MPEG4Level5:   return "5";
+        case MPEG4Level6:   return "6";
+        default:            return def;
+    }
+}
+
 constexpr int32_t MPEG2ProfileSimple              = 0x00;
 constexpr int32_t MPEG2ProfileMain                = 0x01;
 constexpr int32_t MPEG2Profile422                 = 0x02;
@@ -103,12 +214,35 @@
 constexpr int32_t MPEG2ProfileSpatial             = 0x04;
 constexpr int32_t MPEG2ProfileHigh                = 0x05;
 
+inline static const char *asString_MPEG2Profile(int32_t i, const char *def = "??") {
+    switch (i) {
+        case MPEG2ProfileSimple:    return "Simple";
+        case MPEG2ProfileMain:      return "Main";
+        case MPEG2Profile422:       return "422";
+        case MPEG2ProfileSNR:       return "SNR";
+        case MPEG2ProfileSpatial:   return "Spatial";
+        case MPEG2ProfileHigh:      return "High";
+        default:                    return def;
+    }
+}
+
 constexpr int32_t MPEG2LevelLL     = 0x00;
 constexpr int32_t MPEG2LevelML     = 0x01;
 constexpr int32_t MPEG2LevelH14    = 0x02;
 constexpr int32_t MPEG2LevelHL     = 0x03;
 constexpr int32_t MPEG2LevelHP     = 0x04;
 
+inline static const char *asString_MPEG2Level(int32_t i, const char *def = "??") {
+    switch (i) {
+        case MPEG2LevelLL:  return "LL";
+        case MPEG2LevelML:  return "ML";
+        case MPEG2LevelH14: return "H14";
+        case MPEG2LevelHL:  return "HL";
+        case MPEG2LevelHP:  return "HP";
+        default:            return def;
+    }
+}
+
 constexpr int32_t AACObjectMain       = 1;
 constexpr int32_t AACObjectLC         = 2;
 constexpr int32_t AACObjectSSR        = 3;
@@ -122,19 +256,70 @@
 constexpr int32_t AACObjectELD        = 39;
 constexpr int32_t AACObjectXHE        = 42;
 
+inline static const char *asString_AACObject(int32_t i, const char *def = "??") {
+    switch (i) {
+        case AACObjectMain:         return "Main";
+        case AACObjectLC:           return "LC";
+        case AACObjectSSR:          return "SSR";
+        case AACObjectLTP:          return "LTP";
+        case AACObjectHE:           return "HE";
+        case AACObjectScalable:     return "Scalable";
+        case AACObjectERLC:         return "ERLC";
+        case AACObjectERScalable:   return "ERScalable";
+        case AACObjectLD:           return "LD";
+        case AACObjectHE_PS:        return "HE_PS";
+        case AACObjectELD:          return "ELD";
+        case AACObjectXHE:          return "XHE";
+        default:                    return def;
+    }
+}
+
 constexpr int32_t VP8Level_Version0 = 0x01;
 constexpr int32_t VP8Level_Version1 = 0x02;
 constexpr int32_t VP8Level_Version2 = 0x04;
 constexpr int32_t VP8Level_Version3 = 0x08;
 
+inline static const char *asString_VP8Level(int32_t i, const char *def = "??") {
+    switch (i) {
+        case VP8Level_Version0: return "V0";
+        case VP8Level_Version1: return "V1";
+        case VP8Level_Version2: return "V2";
+        case VP8Level_Version3: return "V3";
+        default:                return def;
+    }
+}
+
 constexpr int32_t VP8ProfileMain = 0x01;
 
+inline static const char *asString_VP8Profile(int32_t i, const char *def = "??") {
+    switch (i) {
+        case VP8ProfileMain:    return "Main";
+        default:                return def;
+    }
+}
+
 constexpr int32_t VP9Profile0 = 0x01;
 constexpr int32_t VP9Profile1 = 0x02;
 constexpr int32_t VP9Profile2 = 0x04;
 constexpr int32_t VP9Profile3 = 0x08;
 constexpr int32_t VP9Profile2HDR = 0x1000;
 constexpr int32_t VP9Profile3HDR = 0x2000;
+constexpr int32_t VP9Profile2HDR10Plus = 0x4000;
+constexpr int32_t VP9Profile3HDR10Plus = 0x8000;
+
+inline static const char *asString_VP9Profile(int32_t i, const char *def = "??") {
+    switch (i) {
+        case VP9Profile0:           return "0";
+        case VP9Profile1:           return "1";
+        case VP9Profile2:           return "2";
+        case VP9Profile3:           return "3";
+        case VP9Profile2HDR:        return "2HDR";
+        case VP9Profile3HDR:        return "3HDR";
+        case VP9Profile2HDR10Plus:  return "2HDRPlus";
+        case VP9Profile3HDR10Plus:  return "3HDRPlus";
+        default:                    return def;
+    }
+}
 
 constexpr int32_t VP9Level1  = 0x1;
 constexpr int32_t VP9Level11 = 0x2;
@@ -151,10 +336,112 @@
 constexpr int32_t VP9Level61 = 0x1000;
 constexpr int32_t VP9Level62 = 0x2000;
 
+inline static const char *asString_VP9Level(int32_t i, const char *def = "??") {
+    switch (i) {
+        case VP9Level1:     return "1";
+        case VP9Level11:    return "1.1";
+        case VP9Level2:     return "2";
+        case VP9Level21:    return "2.1";
+        case VP9Level3:     return "3";
+        case VP9Level31:    return "3.1";
+        case VP9Level4:     return "4";
+        case VP9Level41:    return "4.1";
+        case VP9Level5:     return "5";
+        case VP9Level51:    return "5.1";
+        case VP9Level52:    return "5.2";
+        case VP9Level6:     return "6";
+        case VP9Level61:    return "6.1";
+        case VP9Level62:    return "6.2";
+        default:            return def;
+    }
+}
+
+constexpr int32_t AV1ProfileMain8 = 0x1;
+constexpr int32_t AV1ProfileMain10 = 0x2;
+constexpr int32_t AV1ProfileMain10HDR10 = 0x1000;
+constexpr int32_t AV1ProfileMain10HDR10Plus = 0x2000;
+
+inline static const char *asString_AV1Profile(int32_t i, const char *def = "??") {
+    switch (i) {
+        case AV1ProfileMain8:           return "Main8";
+        case AV1ProfileMain10:          return "Main10HDR";
+        case AV1ProfileMain10HDR10:     return "Main10HDR10";
+        case AV1ProfileMain10HDR10Plus: return "Main10HDRPlus";
+        default:                        return def;
+    }
+}
+
+constexpr int32_t AV1Level2  = 0x1;
+constexpr int32_t AV1Level21 = 0x2;
+constexpr int32_t AV1Level22 = 0x4;
+constexpr int32_t AV1Level23 = 0x8;
+constexpr int32_t AV1Level3  = 0x10;
+constexpr int32_t AV1Level31 = 0x20;
+constexpr int32_t AV1Level32 = 0x40;
+constexpr int32_t AV1Level33 = 0x80;
+constexpr int32_t AV1Level4  = 0x100;
+constexpr int32_t AV1Level41 = 0x200;
+constexpr int32_t AV1Level42 = 0x400;
+constexpr int32_t AV1Level43 = 0x800;
+constexpr int32_t AV1Level5  = 0x1000;
+constexpr int32_t AV1Level51 = 0x2000;
+constexpr int32_t AV1Level52 = 0x4000;
+constexpr int32_t AV1Level53 = 0x8000;
+constexpr int32_t AV1Level6  = 0x10000;
+constexpr int32_t AV1Level61 = 0x20000;
+constexpr int32_t AV1Level62 = 0x40000;
+constexpr int32_t AV1Level63 = 0x80000;
+constexpr int32_t AV1Level7  = 0x100000;
+constexpr int32_t AV1Level71 = 0x200000;
+constexpr int32_t AV1Level72 = 0x400000;
+constexpr int32_t AV1Level73 = 0x800000;
+
+inline static const char *asString_AV1Level(int32_t i, const char *def = "??") {
+    switch (i) {
+        case AV1Level2:     return "2";
+        case AV1Level21:    return "2.1";
+        case AV1Level22:    return "2.2";
+        case AV1Level23:    return "2.3";
+        case AV1Level3:     return "3";
+        case AV1Level31:    return "3.1";
+        case AV1Level32:    return "3.2";
+        case AV1Level33:    return "3.3";
+        case AV1Level4:     return "4";
+        case AV1Level41:    return "4.1";
+        case AV1Level42:    return "4.2";
+        case AV1Level43:    return "4.3";
+        case AV1Level5:     return "5";
+        case AV1Level51:    return "5.1";
+        case AV1Level52:    return "5.2";
+        case AV1Level53:    return "5.3";
+        case AV1Level6:     return "6";
+        case AV1Level61:    return "6.1";
+        case AV1Level62:    return "6.2";
+        case AV1Level63:    return "6.3";
+        case AV1Level7:     return "7";
+        case AV1Level71:    return "7.1";
+        case AV1Level72:    return "7.2";
+        case AV1Level73:    return "7.3";
+        default:            return def;
+    }
+}
+
 constexpr int32_t HEVCProfileMain        = 0x01;
 constexpr int32_t HEVCProfileMain10      = 0x02;
 constexpr int32_t HEVCProfileMainStill   = 0x04;
 constexpr int32_t HEVCProfileMain10HDR10 = 0x1000;
+constexpr int32_t HEVCProfileMain10HDR10Plus = 0x2000;
+
+inline static const char *asString_HEVCProfile(int32_t i, const char *def = "??") {
+    switch (i) {
+        case HEVCProfileMain:               return "Main";
+        case HEVCProfileMain10:             return "Main10";
+        case HEVCProfileMainStill:          return "MainStill";
+        case HEVCProfileMain10HDR10:        return "Main10HDR10";
+        case HEVCProfileMain10HDR10Plus:    return "Main10HDR10Plus";
+        default:                            return def;
+    }
+}
 
 constexpr int32_t HEVCMainTierLevel1  = 0x1;
 constexpr int32_t HEVCHighTierLevel1  = 0x2;
@@ -183,6 +470,38 @@
 constexpr int32_t HEVCMainTierLevel62 = 0x1000000;
 constexpr int32_t HEVCHighTierLevel62 = 0x2000000;
 
+inline static const char *asString_HEVCTierLevel(int32_t i, const char *def = "??") {
+    switch (i) {
+        case HEVCMainTierLevel1:    return "Main 1";
+        case HEVCHighTierLevel1:    return "High 1";
+        case HEVCMainTierLevel2:    return "Main 2";
+        case HEVCHighTierLevel2:    return "High 2";
+        case HEVCMainTierLevel21:   return "Main 2.1";
+        case HEVCHighTierLevel21:   return "High 2.1";
+        case HEVCMainTierLevel3:    return "Main 3";
+        case HEVCHighTierLevel3:    return "High 3";
+        case HEVCMainTierLevel31:   return "Main 3.1";
+        case HEVCHighTierLevel31:   return "High 3.1";
+        case HEVCMainTierLevel4:    return "Main 4";
+        case HEVCHighTierLevel4:    return "High 4";
+        case HEVCMainTierLevel41:   return "Main 4.1";
+        case HEVCHighTierLevel41:   return "High 4.1";
+        case HEVCMainTierLevel5:    return "Main 5";
+        case HEVCHighTierLevel5:    return "High 5";
+        case HEVCMainTierLevel51:   return "Main 5.1";
+        case HEVCHighTierLevel51:   return "High 5.1";
+        case HEVCMainTierLevel52:   return "Main 5.2";
+        case HEVCHighTierLevel52:   return "High 5.2";
+        case HEVCMainTierLevel6:    return "Main 6";
+        case HEVCHighTierLevel6:    return "High 6";
+        case HEVCMainTierLevel61:   return "Main 6.1";
+        case HEVCHighTierLevel61:   return "High 6.1";
+        case HEVCMainTierLevel62:   return "Main 6.2";
+        case HEVCHighTierLevel62:   return "High 6.2";
+        default:                    return def;
+    }
+}
+
 constexpr int32_t DolbyVisionProfileDvavPer = 0x1;
 constexpr int32_t DolbyVisionProfileDvavPen = 0x2;
 constexpr int32_t DolbyVisionProfileDvheDer = 0x4;
@@ -194,6 +513,22 @@
 constexpr int32_t DolbyVisionProfileDvheSt = 0x100;
 constexpr int32_t DolbyVisionProfileDvavSe = 0x200;
 
+inline static const char *asString_DolbyVisionProfile(int32_t i, const char *def = "??") {
+    switch (i) {
+        case DolbyVisionProfileDvavPer: return "DvavPer";
+        case DolbyVisionProfileDvavPen: return "DvavPen";
+        case DolbyVisionProfileDvheDer: return "DvheDer";
+        case DolbyVisionProfileDvheDen: return "DvheDen";
+        case DolbyVisionProfileDvheDtr: return "DvheDtr";
+        case DolbyVisionProfileDvheStn: return "DvheStn";
+        case DolbyVisionProfileDvheDth: return "DvheDth";
+        case DolbyVisionProfileDvheDtb: return "DvheDtb";
+        case DolbyVisionProfileDvheSt:  return "DvheSt";
+        case DolbyVisionProfileDvavSe:  return "DvavSe";
+        default:                        return def;
+    }
+}
+
 constexpr int32_t DolbyVisionLevelHd24    = 0x1;
 constexpr int32_t DolbyVisionLevelHd30    = 0x2;
 constexpr int32_t DolbyVisionLevelFhd24   = 0x4;
@@ -204,10 +539,34 @@
 constexpr int32_t DolbyVisionLevelUhd48   = 0x80;
 constexpr int32_t DolbyVisionLevelUhd60   = 0x100;
 
+inline static const char *asString_DolbyVisionLevel(int32_t i, const char *def = "??") {
+    switch (i) {
+        case DolbyVisionLevelHd24:  return "Hd24";
+        case DolbyVisionLevelHd30:  return "Hd30";
+        case DolbyVisionLevelFhd24: return "Fhd24";
+        case DolbyVisionLevelFhd30: return "Fhd30";
+        case DolbyVisionLevelFhd60: return "Fhd60";
+        case DolbyVisionLevelUhd24: return "Uhd24";
+        case DolbyVisionLevelUhd30: return "Uhd30";
+        case DolbyVisionLevelUhd48: return "Uhd48";
+        case DolbyVisionLevelUhd60: return "Uhd60";
+        default:                    return def;
+    }
+}
+
 constexpr int32_t BITRATE_MODE_CBR = 2;
 constexpr int32_t BITRATE_MODE_CQ = 0;
 constexpr int32_t BITRATE_MODE_VBR = 1;
 
+inline static const char *asString_BitrateMode(int32_t i, const char *def = "??") {
+    switch (i) {
+        case BITRATE_MODE_CBR:  return "CBR";
+        case BITRATE_MODE_CQ:   return "CQ";
+        case BITRATE_MODE_VBR:  return "VBR";
+        default:                return def;
+    }
+}
+
 constexpr int32_t COLOR_Format12bitRGB444             = 3;
 constexpr int32_t COLOR_Format16bitARGB1555           = 5;
 constexpr int32_t COLOR_Format16bitARGB4444           = 4;
@@ -261,6 +620,64 @@
 constexpr int32_t COLOR_QCOM_FormatYUV420SemiPlanar   = 0x7fa30c00;
 constexpr int32_t COLOR_TI_FormatYUV420PackedSemiPlanar = 0x7f000100;
 
+inline static const char *asString_ColorFormat(int32_t i, const char *def = "??") {
+    switch (i) {
+        case COLOR_Format12bitRGB444:               return "12bitRGB444";
+        case COLOR_Format16bitARGB1555:             return "16bitARGB1555";
+        case COLOR_Format16bitARGB4444:             return "16bitARGB4444";
+        case COLOR_Format16bitBGR565:               return "16bitBGR565";
+        case COLOR_Format16bitRGB565:               return "16bitRGB565";
+        case COLOR_Format18bitARGB1665:             return "18bitARGB1665";
+        case COLOR_Format18BitBGR666:               return "18BitBGR666";
+        case COLOR_Format18bitRGB666:               return "18bitRGB666";
+        case COLOR_Format19bitARGB1666:             return "19bitARGB1666";
+        case COLOR_Format24BitABGR6666:             return "24BitABGR6666";
+        case COLOR_Format24bitARGB1887:             return "24bitARGB1887";
+        case COLOR_Format24BitARGB6666:             return "24BitARGB6666";
+        case COLOR_Format24bitBGR888:               return "24bitBGR888";
+        case COLOR_Format24bitRGB888:               return "24bitRGB888";
+        case COLOR_Format25bitARGB1888:             return "25bitARGB1888";
+        case COLOR_Format32bitABGR8888:             return "32bitABGR8888";
+        case COLOR_Format32bitARGB8888:             return "32bitARGB8888";
+        case COLOR_Format32bitBGRA8888:             return "32bitBGRA8888";
+        case COLOR_Format8bitRGB332:                return "8bitRGB332";
+        case COLOR_FormatCbYCrY:                    return "CbYCrY";
+        case COLOR_FormatCrYCbY:                    return "CrYCbY";
+        case COLOR_FormatL16:                       return "L16";
+        case COLOR_FormatL2:                        return "L2";
+        case COLOR_FormatL24:                       return "L24";
+        case COLOR_FormatL32:                       return "L32";
+        case COLOR_FormatL4:                        return "L4";
+        case COLOR_FormatL8:                        return "L8";
+        case COLOR_FormatMonochrome:                return "Monochrome";
+        case COLOR_FormatRawBayer10bit:             return "RawBayer10bit";
+        case COLOR_FormatRawBayer8bit:              return "RawBayer8bit";
+        case COLOR_FormatRawBayer8bitcompressed:    return "RawBayer8bitcompressed";
+        case COLOR_FormatRGBAFlexible:              return "RGBAFlexible";
+        case COLOR_FormatRGBFlexible:               return "RGBFlexible";
+        case COLOR_FormatSurface:                   return "Surface";
+        case COLOR_FormatYCbYCr:                    return "YCbYCr";
+        case COLOR_FormatYCrYCb:                    return "YCrYCb";
+        case COLOR_FormatYUV411PackedPlanar:        return "YUV411PackedPlanar";
+        case COLOR_FormatYUV411Planar:              return "YUV411Planar";
+        case COLOR_FormatYUV420Flexible:            return "YUV420Flexible";
+        case COLOR_FormatYUV420PackedPlanar:        return "YUV420PackedPlanar";
+        case COLOR_FormatYUV420PackedSemiPlanar:    return "YUV420PackedSemiPlanar";
+        case COLOR_FormatYUV420Planar:              return "YUV420Planar";
+        case COLOR_FormatYUV420SemiPlanar:          return "YUV420SemiPlanar";
+        case COLOR_FormatYUV422Flexible:            return "YUV422Flexible";
+        case COLOR_FormatYUV422PackedPlanar:        return "YUV422PackedPlanar";
+        case COLOR_FormatYUV422PackedSemiPlanar:    return "YUV422PackedSemiPlanar";
+        case COLOR_FormatYUV422Planar:              return "YUV422Planar";
+        case COLOR_FormatYUV422SemiPlanar:          return "YUV422SemiPlanar";
+        case COLOR_FormatYUV444Flexible:            return "YUV444Flexible";
+        case COLOR_FormatYUV444Interleaved:         return "YUV444Interleaved";
+        case COLOR_QCOM_FormatYUV420SemiPlanar:     return "QCOM_YUV420SemiPlanar";
+        case COLOR_TI_FormatYUV420PackedSemiPlanar: return "TI_YUV420PackedSemiPlanar";
+        default:                                    return def;
+    }
+}
+
 constexpr char FEATURE_AdaptivePlayback[]       = "adaptive-playback";
 constexpr char FEATURE_IntraRefresh[] = "intra-refresh";
 constexpr char FEATURE_PartialFrame[] = "partial-frame";
@@ -270,6 +687,7 @@
 // from MediaFormat.java
 constexpr char MIMETYPE_VIDEO_VP8[] = "video/x-vnd.on2.vp8";
 constexpr char MIMETYPE_VIDEO_VP9[] = "video/x-vnd.on2.vp9";
+constexpr char MIMETYPE_VIDEO_AV1[] = "video/av01";
 constexpr char MIMETYPE_VIDEO_AVC[] = "video/avc";
 constexpr char MIMETYPE_VIDEO_HEVC[] = "video/hevc";
 constexpr char MIMETYPE_VIDEO_MPEG4[] = "video/mp4v-es";
@@ -327,6 +745,7 @@
 constexpr char KEY_BITRATE_MODE[] = "bitrate-mode";
 constexpr char KEY_CA_SESSION_ID[] = "ca-session-id";
 constexpr char KEY_CA_SYSTEM_ID[] = "ca-system-id";
+constexpr char KEY_CA_PRIVATE_DATA[] = "ca-private-data";
 constexpr char KEY_CAPTURE_RATE[] = "capture-rate";
 constexpr char KEY_CHANNEL_COUNT[] = "channel-count";
 constexpr char KEY_CHANNEL_MASK[] = "channel-mask";
@@ -335,6 +754,7 @@
 constexpr char KEY_COLOR_STANDARD[] = "color-standard";
 constexpr char KEY_COLOR_TRANSFER[] = "color-transfer";
 constexpr char KEY_COMPLEXITY[] = "complexity";
+constexpr char KEY_CREATE_INPUT_SURFACE_SUSPENDED[] = "create-input-buffers-suspended";
 constexpr char KEY_DURATION[] = "durationUs";
 constexpr char KEY_FEATURE_[] = "feature-";
 constexpr char KEY_FLAC_COMPRESSION_LEVEL[] = "flac-compression-level";
@@ -342,6 +762,7 @@
 constexpr char KEY_GRID_COLUMNS[] = "grid-cols";
 constexpr char KEY_GRID_ROWS[] = "grid-rows";
 constexpr char KEY_HDR_STATIC_INFO[] = "hdr-static-info";
+constexpr char KEY_HDR10_PLUS_INFO[] = "hdr10-plus-info";
 constexpr char KEY_HEIGHT[] = "height";
 constexpr char KEY_I_FRAME_INTERVAL[] = "i-frame-interval";
 constexpr char KEY_INTRA_REFRESH_PERIOD[] = "intra-refresh-period";
@@ -353,14 +774,18 @@
 constexpr char KEY_LANGUAGE[] = "language";
 constexpr char KEY_LATENCY[] = "latency";
 constexpr char KEY_LEVEL[] = "level";
+constexpr char KEY_MAX_B_FRAMES[] = "max-bframes";
 constexpr char KEY_MAX_BIT_RATE[] = "max-bitrate";
+constexpr char KEY_MAX_FPS_TO_ENCODER[] = "max-fps-to-encoder";
 constexpr char KEY_MAX_HEIGHT[] = "max-height";
 constexpr char KEY_MAX_INPUT_SIZE[] = "max-input-size";
+constexpr char KEY_MAX_PTS_GAP_TO_ENCODER[] = "max-pts-gap-to-encoder";
 constexpr char KEY_MAX_WIDTH[] = "max-width";
 constexpr char KEY_MIME[] = "mime";
 constexpr char KEY_OPERATING_RATE[] = "operating-rate";
 constexpr char KEY_OUTPUT_REORDER_DEPTH[] = "output-reorder-depth";
 constexpr char KEY_PCM_ENCODING[] = "pcm-encoding";
+constexpr char KEY_PREPEND_HEADERS_TO_SYNC_FRAMES[] = "prepend-sps-pps-to-idr-frames";
 constexpr char KEY_PRIORITY[] = "priority";
 constexpr char KEY_PROFILE[] = "profile";
 constexpr char KEY_PUSH_BLANK_BUFFERS_ON_STOP[] = "push-blank-buffers-on-shutdown";
@@ -410,8 +835,10 @@
 constexpr int32_t INFO_TRY_AGAIN_LATER        = -1;
 constexpr int32_t VIDEO_SCALING_MODE_SCALE_TO_FIT               = 1;
 constexpr int32_t VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2;
+constexpr char PARAMETER_KEY_OFFSET_TIME[] = "time-offset-us";
 constexpr char PARAMETER_KEY_REQUEST_SYNC_FRAME[] = "request-sync";
 constexpr char PARAMETER_KEY_SUSPEND[] = "drop-input-frames";
+constexpr char PARAMETER_KEY_SUSPEND_TIME[] = "drop-start-time-us";
 constexpr char PARAMETER_KEY_VIDEO_BITRATE[] = "video-bitrate";
 
 }
diff --git a/media/libstagefright/include/media/stagefright/MediaCodecListWriter.h b/media/libstagefright/include/media/stagefright/MediaCodecListWriter.h
index 59f57c7..f53b23e 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodecListWriter.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodecListWriter.h
@@ -48,6 +48,13 @@
      * added `MediaCodecInfo` object.
      */
     std::unique_ptr<MediaCodecInfoWriter> addMediaCodecInfo();
+    /**
+     * Find an existing `MediaCodecInfo` object for a codec name and return a
+     * `MediaCodecInfoWriter` object associated with the found added `MediaCodecInfo`.
+     *
+     * @return The `MediaCodecInfoWriter` object if found, or nullptr if not found.
+     */
+    std::unique_ptr<MediaCodecInfoWriter> findMediaCodecInfo(const char *codecName);
 private:
     MediaCodecListWriter() = default;
 
diff --git a/media/libstagefright/include/media/stagefright/MediaErrors.h b/media/libstagefright/include/media/stagefright/MediaErrors.h
index 6a5c6b6..09639e2 100644
--- a/media/libstagefright/include/media/stagefright/MediaErrors.h
+++ b/media/libstagefright/include/media/stagefright/MediaErrors.h
@@ -70,7 +70,12 @@
     ERROR_DRM_DEVICE_REVOKED                 = DRM_ERROR_BASE - 9,
     ERROR_DRM_RESOURCE_BUSY                  = DRM_ERROR_BASE - 10,
     ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION = DRM_ERROR_BASE - 11,
-    ERROR_DRM_LAST_USED_ERRORCODE            = DRM_ERROR_BASE - 11,
+    ERROR_DRM_INSUFFICIENT_SECURITY          = DRM_ERROR_BASE - 12,
+    ERROR_DRM_FRAME_TOO_LARGE                = DRM_ERROR_BASE - 13,
+    ERROR_DRM_RESOURCE_CONTENTION            = DRM_ERROR_BASE - 14,
+    ERROR_DRM_SESSION_LOST_STATE             = DRM_ERROR_BASE - 15,
+    ERROR_DRM_INVALID_STATE                  = DRM_ERROR_BASE - 16,
+    ERROR_DRM_LAST_USED_ERRORCODE            = DRM_ERROR_BASE - 16,
 
     ERROR_DRM_VENDOR_MAX                     = DRM_ERROR_BASE - 500,
     ERROR_DRM_VENDOR_MIN                     = DRM_ERROR_BASE - 999,
diff --git a/media/libstagefright/include/media/stagefright/MediaExtractor.h b/media/libstagefright/include/media/stagefright/MediaExtractor.h
new file mode 100644
index 0000000..79f18d5
--- /dev/null
+++ b/media/libstagefright/include/media/stagefright/MediaExtractor.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MEDIA_EXTRACTOR_H_
+
+#define MEDIA_EXTRACTOR_H_
+
+#include <stdio.h>
+#include <vector>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <utils/RefBase.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
+
+namespace android {
+
+class DataSourceBase;
+class MetaDataBase;
+struct MediaTrack;
+
+
+class ExtractorAllocTracker {
+public:
+    ExtractorAllocTracker() {
+        ALOGD("extractor allocated: %p", this);
+    }
+    virtual ~ExtractorAllocTracker() {
+        ALOGD("extractor freed: %p", this);
+    }
+};
+
+class MediaExtractor
+// : public ExtractorAllocTracker
+{
+public:
+    virtual ~MediaExtractor();
+    virtual size_t countTracks() = 0;
+    virtual MediaTrack *getTrack(size_t index) = 0;
+
+    enum GetTrackMetaDataFlags {
+        kIncludeExtensiveMetaData = 1
+    };
+    virtual status_t getTrackMetaData(
+            MetaDataBase& meta,
+            size_t index, uint32_t flags = 0) = 0;
+
+    // Return container specific meta-data. The default implementation
+    // returns an empty metadata object.
+    virtual status_t getMetaData(MetaDataBase& meta) = 0;
+
+    enum Flags {
+        CAN_SEEK_BACKWARD  = 1,  // the "seek 10secs back button"
+        CAN_SEEK_FORWARD   = 2,  // the "seek 10secs forward button"
+        CAN_PAUSE          = 4,
+        CAN_SEEK           = 8,  // the "seek bar"
+    };
+
+    // If subclasses do _not_ override this, the default is
+    // CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK | CAN_PAUSE
+    virtual uint32_t flags() const;
+
+    virtual status_t setMediaCas(const uint8_t* /*casToken*/, size_t /*size*/) {
+        return INVALID_OPERATION;
+    }
+
+    virtual const char * name() { return "<unspecified>"; }
+
+protected:
+    MediaExtractor();
+
+private:
+    MediaExtractor(const MediaExtractor &);
+    MediaExtractor &operator=(const MediaExtractor &);
+};
+
+class MediaExtractorCUnwrapper : public MediaExtractor {
+public:
+    explicit MediaExtractorCUnwrapper(CMediaExtractor *plugin);
+    virtual size_t countTracks();
+    virtual MediaTrack *getTrack(size_t index);
+    virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags = 0);
+    virtual status_t getMetaData(MetaDataBase& meta);
+    virtual const char * name();
+    virtual uint32_t flags() const;
+    virtual status_t setMediaCas(const uint8_t* casToken, size_t size);
+protected:
+    virtual ~MediaExtractorCUnwrapper();
+private:
+    CMediaExtractor *plugin;
+};
+
+}  // namespace android
+
+#endif  // MEDIA_EXTRACTOR_H_
diff --git a/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h b/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h
index fb9f5bd..2ab98e1 100644
--- a/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h
+++ b/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h
@@ -19,10 +19,10 @@
 #define MEDIA_EXTRACTOR_FACTORY_H_
 
 #include <stdio.h>
+#include <unordered_set>
 
+#include <android/dlext.h>
 #include <media/IMediaExtractor.h>
-#include <media/MediaExtractor.h>
-#include <utils/List.h>
 
 namespace android {
 
@@ -35,26 +35,25 @@
             const sp<DataSource> &source, const char *mime = NULL);
     static sp<IMediaExtractor> CreateFromService(
             const sp<DataSource> &source, const char *mime = NULL);
-    static void LoadPlugins(const ::std::string& apkPath);
     static status_t dump(int fd, const Vector<String16>& args);
+    static std::unordered_set<std::string> getSupportedTypes();
+    static void LoadExtractors();
 
 private:
     static Mutex gPluginMutex;
-    static std::shared_ptr<List<sp<ExtractorPlugin>>> gPlugins;
+    static std::shared_ptr<std::list<sp<ExtractorPlugin>>> gPlugins;
     static bool gPluginsRegistered;
+    static bool gIgnoreVersion;
 
-    static void RegisterExtractorsInApk(
-            const char *apkPath, List<sp<ExtractorPlugin>> &pluginList);
-    static void RegisterExtractorsInSystem(
-            const char *libDirPath, List<sp<ExtractorPlugin>> &pluginList);
+    static void RegisterExtractors(
+            const char *libDirPath, const android_dlextinfo* dlextinfo,
+            std::list<sp<ExtractorPlugin>> &pluginList);
     static void RegisterExtractor(
-            const sp<ExtractorPlugin> &plugin, List<sp<ExtractorPlugin>> &pluginList);
+            const sp<ExtractorPlugin> &plugin, std::list<sp<ExtractorPlugin>> &pluginList);
 
-    static MediaExtractor::CreatorFunc sniff(DataSourceBase *source,
-            float *confidence, void **meta, MediaExtractor::FreeMetaFunc *freeMeta,
-            sp<ExtractorPlugin> &plugin);
-
-    static void UpdateExtractors(const char *newUpdateApkPath);
+    static void *sniff(const sp<DataSource> &source,
+            float *confidence, void **meta, FreeMetaFunc *freeMeta,
+            sp<ExtractorPlugin> &plugin, uint32_t *creatorVersion);
 };
 
 }  // namespace android
diff --git a/media/libstagefright/include/media/stagefright/MediaHTTP.h b/media/libstagefright/include/media/stagefright/MediaHTTP.h
index fe0e613..acaa6c4 100644
--- a/media/libstagefright/include/media/stagefright/MediaHTTP.h
+++ b/media/libstagefright/include/media/stagefright/MediaHTTP.h
@@ -19,50 +19,21 @@
 #define MEDIA_HTTP_H_
 
 #include <media/stagefright/foundation/AString.h>
-
-#include "include/HTTPBase.h"
+#include <media/stagefright/ClearMediaHTTP.h>
 
 namespace android {
 
 struct MediaHTTPConnection;
 
-struct MediaHTTP : public HTTPBase {
+struct MediaHTTP : public ClearMediaHTTP {
     MediaHTTP(const sp<MediaHTTPConnection> &conn);
 
-    virtual status_t connect(
-            const char *uri,
-            const KeyedVector<String8, String8> *headers,
-            off64_t offset);
-
-    virtual void disconnect();
-
-    virtual status_t initCheck() const;
-
-    virtual ssize_t readAt(off64_t offset, void *data, size_t size);
-
-    virtual status_t getSize(off64_t *size);
-
-    virtual uint32_t flags();
-
-    virtual status_t reconnectAtOffset(off64_t offset);
-
 protected:
     virtual ~MediaHTTP();
 
     virtual sp<DecryptHandle> DrmInitialization(const char* mime);
-    virtual String8 getUri();
-    virtual String8 getMIMEType() const;
 
 private:
-    status_t mInitCheck;
-    sp<MediaHTTPConnection> mHTTPConnection;
-
-    KeyedVector<String8, String8> mLastHeaders;
-    AString mLastURI;
-
-    bool mCachedSizeValid;
-    off64_t mCachedSize;
-
     sp<DecryptHandle> mDecryptHandle;
     DrmManagerClient *mDrmManagerClient;
 
diff --git a/media/libstagefright/include/media/stagefright/MediaMuxer.h b/media/libstagefright/include/media/stagefright/MediaMuxer.h
index 66f4d72..69d6cde 100644
--- a/media/libstagefright/include/media/stagefright/MediaMuxer.h
+++ b/media/libstagefright/include/media/stagefright/MediaMuxer.h
@@ -49,6 +49,7 @@
         OUTPUT_FORMAT_WEBM        = 1,
         OUTPUT_FORMAT_THREE_GPP   = 2,
         OUTPUT_FORMAT_HEIF        = 3,
+        OUTPUT_FORMAT_OGG         = 4,
         OUTPUT_FORMAT_LIST_END // must be last - used to validate format type
     };
 
diff --git a/media/libmediaextractor/include/media/MediaSource.h b/media/libstagefright/include/media/stagefright/MediaSource.h
similarity index 100%
rename from media/libmediaextractor/include/media/MediaSource.h
rename to media/libstagefright/include/media/stagefright/MediaSource.h
diff --git a/media/libstagefright/include/media/stagefright/MetaData.h b/media/libstagefright/include/media/stagefright/MetaData.h
deleted file mode 120000
index 160f8d3..0000000
--- a/media/libstagefright/include/media/stagefright/MetaData.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libmediaextractor/include/media/stagefright/MetaData.h
\ No newline at end of file
diff --git a/media/libmediaextractor/include/media/stagefright/MetaData.h b/media/libstagefright/include/media/stagefright/MetaData.h
similarity index 100%
rename from media/libmediaextractor/include/media/stagefright/MetaData.h
rename to media/libstagefright/include/media/stagefright/MetaData.h
diff --git a/media/libstagefright/include/media/stagefright/MetaDataBase.h b/media/libstagefright/include/media/stagefright/MetaDataBase.h
deleted file mode 120000
index 1e12193..0000000
--- a/media/libstagefright/include/media/stagefright/MetaDataBase.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libmediaextractor/include/media/stagefright/MetaDataBase.h
\ No newline at end of file
diff --git a/media/libstagefright/include/media/stagefright/MetaDataBase.h b/media/libstagefright/include/media/stagefright/MetaDataBase.h
new file mode 100644
index 0000000..8dc2dd5
--- /dev/null
+++ b/media/libstagefright/include/media/stagefright/MetaDataBase.h
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef META_DATA_BASE_H_
+
+#define META_DATA_BASE_H_
+
+#include <sys/types.h>
+
+#include <stdint.h>
+
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+namespace android {
+
+// The following keys map to int32_t data unless indicated otherwise.
+enum {
+    kKeyMIMEType          = 'mime',  // cstring
+    kKeyWidth             = 'widt',  // int32_t, image pixel
+    kKeyHeight            = 'heig',  // int32_t, image pixel
+    kKeyDisplayWidth      = 'dWid',  // int32_t, display/presentation
+    kKeyDisplayHeight     = 'dHgt',  // int32_t, display/presentation
+    kKeySARWidth          = 'sarW',  // int32_t, sampleAspectRatio width
+    kKeySARHeight         = 'sarH',  // int32_t, sampleAspectRatio height
+    kKeyThumbnailWidth    = 'thbW',  // int32_t, thumbnail width
+    kKeyThumbnailHeight   = 'thbH',  // int32_t, thumbnail height
+
+    // a rectangle, if absent assumed to be (0, 0, width - 1, height - 1)
+    kKeyCropRect          = 'crop',
+
+    kKeyRotation          = 'rotA',  // int32_t (angle in degrees)
+    kKeyIFramesInterval   = 'ifiv',  // int32_t
+    kKeyStride            = 'strd',  // int32_t
+    kKeySliceHeight       = 'slht',  // int32_t
+    kKeyChannelCount      = '#chn',  // int32_t
+    kKeyChannelMask       = 'chnm',  // int32_t
+    kKeySampleRate        = 'srte',  // int32_t (audio sampling rate Hz)
+    kKeyPcmEncoding       = 'PCMe',  // int32_t (audio encoding enum)
+    kKeyFrameRate         = 'frmR',  // int32_t (video frame rate fps)
+    kKeyBitRate           = 'brte',  // int32_t (bps)
+    kKeyMaxBitRate        = 'mxBr',  // int32_t (bps)
+    kKeyBitsPerSample     = 'bits',  // int32_t (bits per sample)
+    kKeyStreamHeader      = 'stHd',  // raw data
+    kKeyESDS              = 'esds',  // raw data
+    kKeyAACProfile        = 'aacp',  // int32_t
+    kKeyAVCC              = 'avcc',  // raw data
+    kKeyHVCC              = 'hvcc',  // raw data
+    kKeyAV1C              = 'av1c',  // raw data
+    kKeyThumbnailHVCC     = 'thvc',  // raw data
+    kKeyD263              = 'd263',  // raw data
+    kKeyOpusHeader        = 'ohdr',  // raw data
+    kKeyOpusCodecDelay    = 'ocod',  // uint64_t (codec delay in ns)
+    kKeyOpusSeekPreRoll   = 'ospr',  // uint64_t (seek preroll in ns)
+    kKeyVp9CodecPrivate   = 'vp9p',  // raw data (vp9 csd information)
+    kKeyIsSyncFrame       = 'sync',  // int32_t (bool)
+    kKeyIsCodecConfig     = 'conf',  // int32_t (bool)
+    kKeyIsMuxerData       = 'muxd',  // int32_t (bool)
+    kKeyTime              = 'time',  // int64_t (usecs)
+    kKeyDecodingTime      = 'decT',  // int64_t (decoding timestamp in usecs)
+    kKeyNTPTime           = 'ntpT',  // uint64_t (ntp-timestamp)
+    kKeyTargetTime        = 'tarT',  // int64_t (usecs)
+    kKeyDriftTime         = 'dftT',  // int64_t (usecs)
+    kKeyAnchorTime        = 'ancT',  // int64_t (usecs)
+    kKeyDuration          = 'dura',  // int64_t (usecs)
+    kKeyPixelFormat       = 'pixf',  // int32_t
+    kKeyColorFormat       = 'colf',  // int32_t
+    kKeyColorSpace        = 'cols',  // int32_t
+    kKeyPlatformPrivate   = 'priv',  // pointer
+    kKeyDecoderComponent  = 'decC',  // cstring
+    kKeyBufferID          = 'bfID',
+    kKeyMaxInputSize      = 'inpS',
+    kKeyMaxWidth          = 'maxW',
+    kKeyMaxHeight         = 'maxH',
+    kKeyThumbnailTime     = 'thbT',  // int64_t (usecs)
+    kKeyTrackID           = 'trID',
+    kKeyEncoderDelay      = 'encd',  // int32_t (frames)
+    kKeyEncoderPadding    = 'encp',  // int32_t (frames)
+
+    kKeyAlbum             = 'albu',  // cstring
+    kKeyArtist            = 'arti',  // cstring
+    kKeyAlbumArtist       = 'aart',  // cstring
+    kKeyComposer          = 'comp',  // cstring
+    kKeyGenre             = 'genr',  // cstring
+    kKeyTitle             = 'titl',  // cstring
+    kKeyYear              = 'year',  // cstring
+    kKeyAlbumArt          = 'albA',  // compressed image data
+    kKeyAuthor            = 'auth',  // cstring
+    kKeyCDTrackNumber     = 'cdtr',  // cstring
+    kKeyDiscNumber        = 'dnum',  // cstring
+    kKeyDate              = 'date',  // cstring
+    kKeyWriter            = 'writ',  // cstring
+    kKeyCompilation       = 'cpil',  // cstring
+    kKeyLocation          = 'loc ',  // cstring
+    kKeyTimeScale         = 'tmsl',  // int32_t
+    kKeyCaptureFramerate  = 'capF',  // float (capture fps)
+
+    // video profile and level
+    kKeyVideoProfile      = 'vprf',  // int32_t
+    kKeyVideoLevel        = 'vlev',  // int32_t
+
+    // Set this key to enable authoring files in 64-bit offset
+    kKey64BitFileOffset   = 'fobt',  // int32_t (bool)
+    kKey2ByteNalLength    = '2NAL',  // int32_t (bool)
+
+    // Identify the file output format for authoring
+    // Please see <media/mediarecorder.h> for the supported
+    // file output formats.
+    kKeyFileType          = 'ftyp',  // int32_t
+
+    // Track authoring progress status
+    // kKeyTrackTimeStatus is used to track progress in elapsed time
+    kKeyTrackTimeStatus   = 'tktm',  // int64_t
+
+    kKeyRealTimeRecording = 'rtrc',  // bool (int32_t)
+    kKeyNumBuffers        = 'nbbf',  // int32_t
+
+    // Ogg files can be tagged to be automatically looping...
+    kKeyAutoLoop          = 'autL',  // bool (int32_t)
+
+    kKeyValidSamples      = 'valD',  // int32_t
+
+    kKeyIsUnreadable      = 'unre',  // bool (int32_t)
+
+    // An indication that a video buffer has been rendered.
+    kKeyRendered          = 'rend',  // bool (int32_t)
+
+    // The language code for this media
+    kKeyMediaLanguage     = 'lang',  // cstring
+
+    // The manufacturer code for this media
+    kKeyManufacturer  = 'manu',  // cstring
+
+    // To store the timed text format data
+    kKeyTextFormatData    = 'text',  // raw data
+
+    kKeyRequiresSecureBuffers = 'secu',  // bool (int32_t)
+
+    kKeyIsADTS            = 'adts',  // bool (int32_t)
+    kKeyAACAOT            = 'aaot',  // int32_t
+
+    // If a MediaBuffer's data represents (at least partially) encrypted
+    // data, the following fields aid in decryption.
+    // The data can be thought of as pairs of plain and encrypted data
+    // fragments, i.e. plain and encrypted data alternate.
+    // The first fragment is by convention plain data (if that's not the
+    // case, simply specify plain fragment size of 0).
+    // kKeyEncryptedSizes and kKeyPlainSizes each map to an array of
+    // size_t values. The sum total of all size_t values of both arrays
+    // must equal the amount of data (i.e. MediaBuffer's range_length()).
+    // If both arrays are present, they must be of the same size.
+    // If only encrypted sizes are present it is assumed that all
+    // plain sizes are 0, i.e. all fragments are encrypted.
+    // To programmatically set these array, use the MetaDataBase::setData API, i.e.
+    // const size_t encSizes[];
+    // meta->setData(
+    //  kKeyEncryptedSizes, 0 /* type */, encSizes, sizeof(encSizes));
+    // A plain sizes array by itself makes no sense.
+    kKeyEncryptedSizes    = 'encr',  // size_t[]
+    kKeyPlainSizes        = 'plai',  // size_t[]
+    kKeyCryptoKey         = 'cryK',  // uint8_t[16]
+    kKeyCryptoIV          = 'cryI',  // uint8_t[16]
+    kKeyCryptoMode        = 'cryM',  // int32_t
+
+    kKeyCryptoDefaultIVSize = 'cryS',  // int32_t
+
+    kKeyPssh              = 'pssh',  // raw data
+    kKeyCASystemID        = 'caid',  // int32_t
+    kKeyCASessionID       = 'seid',  // raw data
+    kKeyCAPrivateData     = 'cadc',  // raw data
+
+    kKeyEncryptedByteBlock = 'cblk',  // uint8_t
+    kKeySkipByteBlock     = 'sblk',  // uint8_t
+
+    // Please see MediaFormat.KEY_IS_AUTOSELECT.
+    kKeyTrackIsAutoselect = 'auto', // bool (int32_t)
+    // Please see MediaFormat.KEY_IS_DEFAULT.
+    kKeyTrackIsDefault    = 'dflt', // bool (int32_t)
+    // Similar to MediaFormat.KEY_IS_FORCED_SUBTITLE but pertains to av tracks as well.
+    kKeyTrackIsForced     = 'frcd', // bool (int32_t)
+
+    // H264 supplemental enhancement information offsets/sizes
+    kKeySEI               = 'sei ', // raw data
+
+    // MPEG user data offsets
+    kKeyMpegUserData      = 'mpud', // size_t[]
+
+    // HDR related
+    kKeyHdrStaticInfo    = 'hdrS', // HDRStaticInfo
+    kKeyHdr10PlusInfo    = 'hdrD', // raw data
+
+    // color aspects
+    kKeyColorRange       = 'cRng', // int32_t, color range, value defined by ColorAspects.Range
+    kKeyColorPrimaries   = 'cPrm', // int32_t,
+                                   // color Primaries, value defined by ColorAspects.Primaries
+    kKeyTransferFunction = 'tFun', // int32_t,
+                                   // transfer Function, value defined by ColorAspects.Transfer.
+    kKeyColorMatrix      = 'cMtx', // int32_t,
+                                   // color Matrix, value defined by ColorAspects.MatrixCoeffs.
+    kKeyTemporalLayerId  = 'iLyr', // int32_t, temporal layer-id. 0-based (0 => base layer)
+    kKeyTemporalLayerCount = 'cLyr', // int32_t, number of temporal layers encoded
+
+    kKeyTileWidth        = 'tilW', // int32_t, HEIF tile width
+    kKeyTileHeight       = 'tilH', // int32_t, HEIF tile height
+    kKeyGridRows         = 'grdR', // int32_t, HEIF grid rows
+    kKeyGridCols         = 'grdC', // int32_t, HEIF grid columns
+    kKeyIccProfile       = 'prof', // raw data, ICC profile data
+    kKeyIsPrimaryImage   = 'prim', // bool (int32_t), image track is the primary image
+    kKeyFrameCount       = 'nfrm', // int32_t, total number of frame in video track
+    kKeyExifOffset       = 'exof', // int64_t, Exif data offset
+    kKeyExifSize         = 'exsz', // int64_t, Exif data size
+    kKeyExifTiffOffset   = 'thdr', // int32_t, if > 0, buffer contains exif data block with
+                                   // tiff hdr at specified offset
+    kKeyPcmBigEndian     = 'pcmb', // bool (int32_t)
+
+    // Key for ALAC Magic Cookie
+    kKeyAlacMagicCookie  = 'almc', // raw data
+
+    // AC-4 AudioPresentationInfo
+    kKeyAudioPresentationInfo = 'audP',  // raw data
+
+    // opaque codec specific data being passed from extractor to codec
+    kKeyOpaqueCSD0       = 'csd0',
+    kKeyOpaqueCSD1       = 'csd1',
+    kKeyOpaqueCSD2       = 'csd2',
+
+    kKeyHapticChannelCount = 'hapC',
+};
+
+enum {
+    kTypeESDS        = 'esds',
+    kTypeAVCC        = 'avcc',
+    kTypeHVCC        = 'hvcc',
+    kTypeAV1C        = 'av1c',
+    kTypeD263        = 'd263',
+};
+
+enum {
+    kCryptoModeUnencrypted = 0,
+    kCryptoModeAesCtr      = 1,
+    kCryptoModeAesCbc      = 2,
+};
+
+class Parcel;
+
+class MetaDataBase {
+public:
+    MetaDataBase();
+    MetaDataBase(const MetaDataBase &from);
+    MetaDataBase& operator = (const MetaDataBase &);
+
+    virtual ~MetaDataBase();
+
+    enum Type {
+        TYPE_NONE     = 'none',
+        TYPE_C_STRING = 'cstr',
+        TYPE_INT32    = 'in32',
+        TYPE_INT64    = 'in64',
+        TYPE_FLOAT    = 'floa',
+        TYPE_POINTER  = 'ptr ',
+        TYPE_RECT     = 'rect',
+    };
+
+    void clear();
+    bool remove(uint32_t key);
+
+    bool setCString(uint32_t key, const char *value);
+    bool setInt32(uint32_t key, int32_t value);
+    bool setInt64(uint32_t key, int64_t value);
+    bool setFloat(uint32_t key, float value);
+    bool setPointer(uint32_t key, void *value);
+
+    bool setRect(
+            uint32_t key,
+            int32_t left, int32_t top,
+            int32_t right, int32_t bottom);
+
+    bool findCString(uint32_t key, const char **value) const;
+    bool findInt32(uint32_t key, int32_t *value) const;
+    bool findInt64(uint32_t key, int64_t *value) const;
+    bool findFloat(uint32_t key, float *value) const;
+    bool findPointer(uint32_t key, void **value) const;
+
+    bool findRect(
+            uint32_t key,
+            int32_t *left, int32_t *top,
+            int32_t *right, int32_t *bottom) const;
+
+    bool setData(uint32_t key, uint32_t type, const void *data, size_t size);
+
+    bool findData(uint32_t key, uint32_t *type,
+                  const void **data, size_t *size) const;
+
+    bool hasData(uint32_t key) const;
+
+    String8 toString() const;
+    void dumpToLog() const;
+
+private:
+    friend class BpMediaSource;
+    friend class BnMediaSource;
+    friend class BnMediaExtractor;
+    friend class MetaData;
+
+    struct typed_data;
+    struct Rect;
+    struct MetaDataInternal;
+    MetaDataInternal *mInternalData;
+    status_t writeToParcel(Parcel &parcel);
+    status_t updateFromParcel(const Parcel &parcel);
+};
+
+}  // namespace android
+
+#endif  // META_DATA_H_
diff --git a/media/libstagefright/include/media/stagefright/MetaDataUtils.h b/media/libstagefright/include/media/stagefright/MetaDataUtils.h
index d5a8080..dcaf27f 100644
--- a/media/libstagefright/include/media/stagefright/MetaDataUtils.h
+++ b/media/libstagefright/include/media/stagefright/MetaDataUtils.h
@@ -20,13 +20,24 @@
 
 #include <media/stagefright/MetaData.h>
 
+struct AMediaFormat;
+
 namespace android {
 
 struct ABuffer;
 bool MakeAVCCodecSpecificData(MetaDataBase &meta, const uint8_t *data, size_t size);
+bool MakeAVCCodecSpecificData(AMediaFormat *meta, const uint8_t *data, size_t size);
+
+bool MakeAACCodecSpecificData(MetaDataBase &meta, const uint8_t *data, size_t size);
 bool MakeAACCodecSpecificData(MetaDataBase &meta, unsigned profile, unsigned sampling_freq_index,
         unsigned channel_configuration);
 
+bool MakeAACCodecSpecificData(AMediaFormat *meta, unsigned profile, unsigned sampling_freq_index,
+        unsigned channel_configuration);
+
+void parseVorbisComment(
+        AMediaFormat *fileMeta, const char *comment, size_t commentLength);
+
 }  // namespace android
 
 #endif  // META_DATA_UTILS_H_
diff --git a/media/libstagefright/include/media/stagefright/NuMediaExtractor.h b/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
index 54a7095..4307110 100644
--- a/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
+++ b/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
@@ -20,6 +20,7 @@
 #include <list>
 #include <media/mediaplayer.h>
 #include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/foundation/AudioPresentationInfo.h>
 #include <media/IMediaExtractor.h>
 #include <media/MediaSource.h>
 #include <utils/Errors.h>
@@ -64,8 +65,6 @@
 
     status_t setMediaCas(const HInterfaceToken &casToken);
 
-    void disconnect();
-
     size_t countTracks() const;
     status_t getTrackFormat(size_t index, sp<AMessage> *format, uint32_t flags = 0) const;
 
@@ -97,6 +96,8 @@
 
     bool getCachedDuration(int64_t *durationUs, bool *eos) const;
 
+    status_t getAudioPresentations(size_t trackIdx, AudioPresentationCollection *presentations);
+
 protected:
     virtual ~NuMediaExtractor();
 
@@ -148,7 +149,6 @@
             MediaSource::ReadOptions::SeekMode mode =
                 MediaSource::ReadOptions::SEEK_CLOSEST_SYNC);
 
-    void releaseOneSample(TrackInfo *info);
     void releaseTrackSamples(TrackInfo *info);
     void releaseAllTrackSamples();
 
diff --git a/media/libstagefright/include/media/stagefright/OggWriter.h b/media/libstagefright/include/media/stagefright/OggWriter.h
new file mode 100644
index 0000000..1a0a1d2
--- /dev/null
+++ b/media/libstagefright/include/media/stagefright/OggWriter.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OGG_WRITER_H_
+
+#define OGG_WRITER_H_
+
+#include <stdio.h>
+
+#include <media/stagefright/MediaWriter.h>
+#include <utils/threads.h>
+
+struct OggStreamState;
+
+namespace android {
+
+struct OggWriter : public MediaWriter {
+    OggWriter(int fd);
+
+    status_t initCheck() const;
+
+    virtual status_t addSource(const sp<MediaSource>& source);
+    virtual bool reachedEOS();
+    virtual status_t start(MetaData* params = NULL);
+    virtual status_t stop() { return reset(); }
+    virtual status_t pause();
+
+protected:
+    ~OggWriter();
+
+private:
+    int mFd;
+    bool mHaveAllCodecSpecificData;
+    status_t mInitCheck;
+    sp<MediaSource> mSource;
+    bool mStarted = false;
+    volatile bool mPaused = false;
+    volatile bool mResumed = false;
+    volatile bool mDone;
+    volatile bool mReachedEOS;
+    pthread_t mThread;
+    int64_t mSampleRate;
+    int64_t mEstimatedSizeBytes;
+    int64_t mEstimatedDurationUs;
+
+    static void* ThreadWrapper(void*);
+    status_t threadFunc();
+    bool exceedsFileSizeLimit();
+    bool exceedsFileDurationLimit();
+    status_t reset();
+
+    int32_t mCurrentPacketId;
+    OggStreamState* mOs = nullptr;
+
+    OggWriter(const OggWriter&);
+    OggWriter& operator=(const OggWriter&);
+
+    status_t writeOggHeaderPackets(unsigned char *buf, size_t size);
+};
+
+}  // namespace android
+
+#endif  // OGG_WRITER_H_
diff --git a/media/libstagefright/include/media/stagefright/OmxInfoBuilder.h b/media/libstagefright/include/media/stagefright/OmxInfoBuilder.h
index 28f6094..1410a16 100644
--- a/media/libstagefright/include/media/stagefright/OmxInfoBuilder.h
+++ b/media/libstagefright/include/media/stagefright/OmxInfoBuilder.h
@@ -23,8 +23,11 @@
 namespace android {
 
 class OmxInfoBuilder : public MediaCodecListBuilderBase {
+private:
+    bool mAllowSurfaceEncoders; // allow surface encoders
+
 public:
-    OmxInfoBuilder();
+    explicit OmxInfoBuilder(bool allowSurfaceEncoders);
     ~OmxInfoBuilder() override = default;
     status_t buildMediaCodecList(MediaCodecListWriter* writer) override;
 };
diff --git a/media/libstagefright/include/media/stagefright/RemoteMediaExtractor.h b/media/libstagefright/include/media/stagefright/RemoteMediaExtractor.h
index 509e669..9925114 100644
--- a/media/libstagefright/include/media/stagefright/RemoteMediaExtractor.h
+++ b/media/libstagefright/include/media/stagefright/RemoteMediaExtractor.h
@@ -18,7 +18,7 @@
 #define REMOTE_MEDIA_EXTRACTOR_H_
 
 #include <media/IMediaExtractor.h>
-#include <media/MediaExtractor.h>
+#include <media/stagefright/MediaExtractor.h>
 #include <media/stagefright/foundation/ABase.h>
 
 namespace android {
diff --git a/media/libstagefright/include/media/stagefright/RemoteMediaSource.h b/media/libstagefright/include/media/stagefright/RemoteMediaSource.h
index 1d720af..03d3869 100644
--- a/media/libstagefright/include/media/stagefright/RemoteMediaSource.h
+++ b/media/libstagefright/include/media/stagefright/RemoteMediaSource.h
@@ -37,12 +37,13 @@
     virtual status_t read(
             MediaBufferBase **buffer,
             const MediaSource::ReadOptions *options = NULL);
+    virtual bool supportNonblockingRead();
     virtual status_t pause();
     virtual status_t setStopTimeUs(int64_t stopTimeUs);
 
 private:
     sp<RemoteMediaExtractor> mExtractor;
-    MediaTrack *mSource;
+    MediaTrack *mTrack;
     sp<RefBase> mExtractorPlugin;
 
     explicit RemoteMediaSource(
diff --git a/media/libstagefright/include/media/stagefright/SurfaceUtils.h b/media/libstagefright/include/media/stagefright/SurfaceUtils.h
index 689e458..ae55c65 100644
--- a/media/libstagefright/include/media/stagefright/SurfaceUtils.h
+++ b/media/libstagefright/include/media/stagefright/SurfaceUtils.h
@@ -19,8 +19,10 @@
 #define SURFACE_UTILS_H_
 
 #include <utils/Errors.h>
+#include <utils/StrongPointer.h>
 
 struct ANativeWindow;
+class Surface;
 
 namespace android {
 
@@ -40,6 +42,15 @@
 status_t nativeWindowConnect(ANativeWindow *surface, const char *reason);
 status_t nativeWindowDisconnect(ANativeWindow *surface, const char *reason);
 
+/**
+ * Disable buffer dropping behavior of BufferQueue if target sdk of application
+ * is Q or later. If the caller is not an app (e.g. MediaPlayer in mediaserver)
+ * retain buffer dropping behavior.
+ *
+ * @return NO_ERROR
+ */
+status_t disableLegacyBufferDropPostQ(const sp<Surface> &surface);
+
 } // namespace android
 
 #endif  // SURFACE_UTILS_H_
diff --git a/media/libstagefright/include/media/stagefright/Utils.h b/media/libstagefright/include/media/stagefright/Utils.h
index 6a28e0b..e8e0a11 100644
--- a/media/libstagefright/include/media/stagefright/Utils.h
+++ b/media/libstagefright/include/media/stagefright/Utils.h
@@ -30,6 +30,8 @@
 
 struct AMessage;
 status_t convertMetaDataToMessage(
+        const MetaDataBase *meta, sp<AMessage> *format);
+status_t convertMetaDataToMessage(
         const sp<MetaData> &meta, sp<AMessage> *format);
 void convertMessageToMetaData(
         const sp<AMessage> &format, sp<MetaData> &meta);
@@ -50,6 +52,10 @@
 // Send information from MetaData to the HAL via AudioSink
 status_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink, const sp<MetaData>& meta);
 
+// Return |audio_offload_info_t| filled from given metadata
+status_t getAudioOffloadInfo(const sp<MetaData>& meta, bool hasVideo,
+        bool isStreaming, audio_stream_type_t streamType, audio_offload_info_t *info);
+
 // Check whether the stream defined by meta can be offloaded to hardware
 bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo,
                       bool isStreaming, audio_stream_type_t streamType);
diff --git a/media/libstagefright/include/media/stagefright/VideoFrameScheduler.h b/media/libstagefright/include/media/stagefright/VideoFrameScheduler.h
index 9d97dfd..fcfcbec 100644
--- a/media/libstagefright/include/media/stagefright/VideoFrameScheduler.h
+++ b/media/libstagefright/include/media/stagefright/VideoFrameScheduler.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014, The Android Open Source Project
+ * Copyright 2018, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,87 +17,24 @@
 #ifndef VIDEO_FRAME_SCHEDULER_H_
 #define VIDEO_FRAME_SCHEDULER_H_
 
-#include <utils/RefBase.h>
-#include <utils/Timers.h>
-
-#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/VideoFrameSchedulerBase.h>
 
 namespace android {
 
 class ISurfaceComposer;
 
-struct VideoFrameScheduler : public RefBase {
+struct VideoFrameScheduler : public VideoFrameSchedulerBase {
     VideoFrameScheduler();
-
-    // (re)initialize scheduler
-    void init(float videoFps = -1);
-    // use in case of video render-time discontinuity, e.g. seek
-    void restart();
-    // get adjusted nanotime for a video frame render at renderTime
-    nsecs_t schedule(nsecs_t renderTime);
-
-    // returns the vsync period for the main display
-    nsecs_t getVsyncPeriod();
-
-    // returns the current frames-per-second, or 0.f if not primed
-    float getFrameRate();
-
-    void release();
-
-    static const size_t kHistorySize = 8;
+    void release() override;
 
 protected:
     virtual ~VideoFrameScheduler();
 
 private:
-    struct PLL {
-        PLL();
-
-        // reset PLL to new PLL
-        void reset(float fps = -1);
-        // keep current estimate, but restart phase
-        void restart();
-        // returns period or 0 if not yet primed
-        nsecs_t addSample(nsecs_t time);
-        nsecs_t getPeriod() const;
-
-    private:
-        nsecs_t mPeriod;
-        nsecs_t mPhase;
-
-        bool    mPrimed;        // have an estimate for the period
-        size_t  mSamplesUsedForPriming;
-
-        nsecs_t mLastTime;      // last input time
-        nsecs_t mRefitAt;       // next input time to fit at
-
-        size_t  mNumSamples;    // can go past kHistorySize
-        nsecs_t mTimes[kHistorySize];
-
-        void test();
-        // returns whether fit was successful
-        bool fit(nsecs_t phase, nsecs_t period, size_t numSamples,
-                int64_t *a, int64_t *b, int64_t *err);
-        void prime(size_t numSamples);
-    };
-
-    void updateVsync();
-
-    nsecs_t mVsyncTime;        // vsync timing from display
-    nsecs_t mVsyncPeriod;
-    nsecs_t mVsyncRefreshAt;   // next time to refresh timing info
-
-    nsecs_t mLastVsyncTime;    // estimated vsync time for last frame
-    nsecs_t mTimeCorrection;   // running adjustment
-
-    PLL mPll;                  // PLL for video frame rate based on render time
-
+    void updateVsync() override;
     sp<ISurfaceComposer> mComposer;
-
-    DISALLOW_EVIL_CONSTRUCTORS(VideoFrameScheduler);
 };
 
 }  // namespace android
 
 #endif  // VIDEO_FRAME_SCHEDULER_H_
-
diff --git a/media/libstagefright/include/media/stagefright/VideoFrameScheduler2.h b/media/libstagefright/include/media/stagefright/VideoFrameScheduler2.h
new file mode 100644
index 0000000..891b9a0
--- /dev/null
+++ b/media/libstagefright/include/media/stagefright/VideoFrameScheduler2.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef VIDEO_FRAME_SCHEDULER_2_H_
+#define VIDEO_FRAME_SCHEDULER_2_H_
+
+#include <media/stagefright/VideoFrameSchedulerBase.h>
+
+namespace android {
+
+class VsyncTracker;
+struct ChoreographerThread;
+
+struct VideoFrameScheduler2 : public VideoFrameSchedulerBase {
+    VideoFrameScheduler2();
+    void release() override;
+
+protected:
+    virtual ~VideoFrameScheduler2();
+
+private:
+    void updateVsync() override;
+
+    nsecs_t mAppVsyncOffset;
+    nsecs_t mSfVsyncOffset;
+    sp<VsyncTracker> mVsyncTracker;
+    sp<ChoreographerThread> mChoreographerThread;
+    Mutex mLock;
+};
+
+}  // namespace android
+
+#endif  // VIDEO_FRAME_SCHEDULER_2_H_
diff --git a/media/libstagefright/include/media/stagefright/VideoFrameSchedulerBase.h b/media/libstagefright/include/media/stagefright/VideoFrameSchedulerBase.h
new file mode 100644
index 0000000..ff5f716
--- /dev/null
+++ b/media/libstagefright/include/media/stagefright/VideoFrameSchedulerBase.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef VIDEO_FRAME_SCHEDULER_BASE_H_
+#define VIDEO_FRAME_SCHEDULER_BASE_H_
+
+#include <utils/RefBase.h>
+#include <utils/Timers.h>
+
+#include <media/stagefright/foundation/ABase.h>
+
+namespace android {
+
+struct VideoFrameSchedulerBase : public RefBase {
+    VideoFrameSchedulerBase();
+
+    // (re)initialize scheduler
+    void init(float videoFps = -1);
+    // use in case of video render-time discontinuity, e.g. seek
+    void restart();
+    // get adjusted nanotime for a video frame render at renderTime
+    nsecs_t schedule(nsecs_t renderTime);
+
+    // returns the vsync period for the main display
+    nsecs_t getVsyncPeriod();
+
+    // returns the current frames-per-second, or 0.f if not primed
+    float getFrameRate();
+
+    virtual void release() = 0;
+
+    static const size_t kHistorySize = 8;
+    static const nsecs_t kNanosIn1s = 1000000000;
+    static const nsecs_t kDefaultVsyncPeriod = kNanosIn1s / 60;  // 60Hz
+    static const nsecs_t kVsyncRefreshPeriod = kNanosIn1s;       // 1 sec
+
+protected:
+    virtual ~VideoFrameSchedulerBase();
+
+    nsecs_t mVsyncTime;        // vsync timing from display
+    nsecs_t mVsyncPeriod;
+    nsecs_t mVsyncRefreshAt;   // next time to refresh timing info
+
+private:
+    struct PLL {
+        PLL();
+
+        // reset PLL to new PLL
+        void reset(float fps = -1);
+        // keep current estimate, but restart phase
+        void restart();
+        // returns period or 0 if not yet primed
+        nsecs_t addSample(nsecs_t time);
+        nsecs_t getPeriod() const;
+
+    private:
+        nsecs_t mPeriod;
+        nsecs_t mPhase;
+
+        bool    mPrimed;        // have an estimate for the period
+        size_t  mSamplesUsedForPriming;
+
+        nsecs_t mLastTime;      // last input time
+        nsecs_t mRefitAt;       // next input time to fit at
+
+        size_t  mNumSamples;    // can go past kHistorySize
+        nsecs_t mTimes[kHistorySize];
+
+        void test();
+        // returns whether fit was successful
+        bool fit(nsecs_t phase, nsecs_t period, size_t numSamples,
+                int64_t *a, int64_t *b, int64_t *err);
+        void prime(size_t numSamples);
+    };
+
+    virtual void updateVsync() = 0;
+
+    nsecs_t mLastVsyncTime;    // estimated vsync time for last frame
+    nsecs_t mTimeCorrection;   // running adjustment
+    PLL mPll;                  // PLL for video frame rate based on render time
+
+    DISALLOW_EVIL_CONSTRUCTORS(VideoFrameSchedulerBase);
+};
+
+}  // namespace android
+
+#endif  // VIDEO_FRAME_SCHEDULER_BASE_H_
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 5cc5093..1482072 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -23,10 +23,10 @@
 #include "ESQueue.h"
 
 #include <android/hardware/cas/native/1.0/IDescrambler.h>
-#include <binder/IMemory.h>
-#include <binder/MemoryDealer.h>
+#include <android/hidl/allocator/1.0/IAllocator.h>
+#include <android/hidl/memory/1.0/IMemory.h>
 #include <cutils/native_handle.h>
-#include <hidlmemory/FrameworkUtils.h>
+#include <hidlmemory/mapping.h>
 #include <media/cas/DescramblerAPI.h>
 #include <media/stagefright/foundation/ABitReader.h>
 #include <media/stagefright/foundation/ABuffer.h>
@@ -46,12 +46,13 @@
 #include <inttypes.h>
 
 namespace android {
-using hardware::fromHeap;
 using hardware::hidl_string;
 using hardware::hidl_vec;
-using hardware::HidlMemory;
+using hardware::hidl_memory;
 using namespace hardware::cas::V1_0;
 using namespace hardware::cas::native::V1_0;
+typedef hidl::allocator::V1_0::IAllocator TAllocator;
+typedef hidl::memory::V1_0::IMemory TMemory;
 
 // I want the expression "y" evaluated even if verbose logging is off.
 #define MY_LOGV(x, y) \
@@ -117,15 +118,12 @@
     void signalNewSampleAesKey(const sp<AMessage> &keyItem);
 
 private:
-    struct StreamInfo {
-        unsigned mType;
-        unsigned mPID;
-        int32_t mCASystemId;
-    };
 
     ATSParser *mParser;
     unsigned mProgramNumber;
     unsigned mProgramMapPID;
+    uint32_t mPMTVersion;
+    uint32_t mPMT_CRC;
     KeyedVector<unsigned, sp<Stream> > mStreams;
     bool mFirstPTSValid;
     uint64_t mFirstPTS;
@@ -142,15 +140,15 @@
 };
 
 struct ATSParser::Stream : public RefBase {
-    Stream(Program *program,
-           unsigned elementaryPID,
-           unsigned streamType,
-           unsigned PCR_PID,
-           int32_t CA_system_ID);
+    Stream(Program *program, unsigned PCR_PID, const StreamInfo &info);
 
     unsigned type() const { return mStreamType; }
+    unsigned typeExt() const { return mStreamTypeExt; }
     unsigned pid() const { return mElementaryPID; }
     void setPID(unsigned pid) { mElementaryPID = pid; }
+    void setAudioPresentations(AudioPresentationCollection audioPresentations) {
+        mAudioPresentations = audioPresentations;
+    }
 
     void setCasInfo(
             int32_t systemId,
@@ -194,6 +192,7 @@
     Program *mProgram;
     unsigned mElementaryPID;
     unsigned mStreamType;
+    unsigned mStreamTypeExt;
     unsigned mPCR_PID;
     int32_t mExpectedContinuityCounter;
 
@@ -210,13 +209,16 @@
     bool mScrambled;
     bool mSampleEncrypted;
     sp<AMessage> mSampleAesKeyItem;
-    sp<IMemory> mMem;
-    sp<MemoryDealer> mDealer;
-    sp<HidlMemory> mHidlMemory;
+    sp<TMemory> mHidlMemory;
+    sp<TAllocator> mHidlAllocator;
     hardware::cas::native::V1_0::SharedBuffer mDescramblerSrcBuffer;
     sp<ABuffer> mDescrambledBuffer;
     List<SubSampleInfo> mSubSamples;
     sp<IDescrambler> mDescrambler;
+    AudioPresentationCollection mAudioPresentations;
+
+    // Send audio presentations along with access units.
+    void addAudioPresentations(const sp<ABuffer> &buffer);
 
     // Flush accumulated payload if necessary --- i.e. at EOS or at the start of
     // another payload. event is set if the flushed payload is PES with a sync
@@ -299,6 +301,8 @@
     : mParser(parser),
       mProgramNumber(programNumber),
       mProgramMapPID(programMapPID),
+      mPMTVersion(0xffffffff),
+      mPMT_CRC(0xffffffff),
       mFirstPTSValid(false),
       mFirstPTS(0),
       mLastRecoveredPTS(lastRecoveredPTS) {
@@ -447,7 +451,7 @@
         if (descriptor_length > infoLength) {
             break;
         }
-        if (descriptor_tag == 9 && descriptor_length >= 4) {
+        if (descriptor_tag == DESCRIPTOR_CA && descriptor_length >= 4) {
             found = true;
             caDescriptor->mSystemID = br->getBits(16);
             caDescriptor->mPID = br->getBits(16) & 0x1fff;
@@ -486,7 +490,13 @@
 
     MY_LOGV("  program_number = %u", br->getBits(16));
     MY_LOGV("  reserved = %u", br->getBits(2));
-    MY_LOGV("  version_number = %u", br->getBits(5));
+    bool audioPresentationsChanged = false;
+    unsigned pmtVersion = br->getBits(5);
+    if (pmtVersion != mPMTVersion) {
+        audioPresentationsChanged = true;
+        mPMTVersion = pmtVersion;
+    }
+    MY_LOGV("  version_number = %u", pmtVersion);
     MY_LOGV("  current_next_indicator = %u", br->getBits(1));
     MY_LOGV("  section_number = %u", br->getBits(8));
     MY_LOGV("  last_section_number = %u", br->getBits(8));
@@ -513,43 +523,166 @@
     // infoBytesRemaining is the number of bytes that make up the
     // variable length section of ES_infos. It does not include the
     // final CRC.
-    size_t infoBytesRemaining = section_length - 9 - program_info_length - 4;
+    int32_t infoBytesRemaining = section_length - 9 - program_info_length - 4;
 
     while (infoBytesRemaining >= 5) {
-
-        unsigned streamType = br->getBits(8);
-        ALOGV("    stream_type = 0x%02x", streamType);
-
+        StreamInfo info;
+        info.mType = br->getBits(8);
+        ALOGV("    stream_type = 0x%02x", info.mType);
         MY_LOGV("    reserved = %u", br->getBits(3));
 
-        unsigned elementaryPID = br->getBits(13);
-        ALOGV("    elementary_PID = 0x%04x", elementaryPID);
+        info.mPID = br->getBits(13);
+        ALOGV("    elementary_PID = 0x%04x", info.mPID);
 
         MY_LOGV("    reserved = %u", br->getBits(4));
 
         unsigned ES_info_length = br->getBits(12);
         ALOGV("    ES_info_length = %u", ES_info_length);
+        infoBytesRemaining -= 5 + ES_info_length;
 
         CADescriptor streamCA;
-        bool hasStreamCA = findCADescriptor(br, ES_info_length, &streamCA);
+        info.mTypeExt = EXT_DESCRIPTOR_DVB_RESERVED_MAX;
+
+        info.mAudioPresentations.clear();
+        bool hasStreamCA = false;
+        while (ES_info_length > 2 && infoBytesRemaining >= 0) {
+            unsigned descriptor_tag = br->getBits(8);
+            ALOGV("      tag = 0x%02x", descriptor_tag);
+
+            unsigned descriptor_length = br->getBits(8);
+            ALOGV("      len = %u", descriptor_length);
+
+            ES_info_length -= 2;
+            if (descriptor_length > ES_info_length) {
+                return ERROR_MALFORMED;
+            }
+            if (descriptor_tag == DESCRIPTOR_CA && descriptor_length >= 4) {
+                hasStreamCA = true;
+                streamCA.mSystemID = br->getBits(16);
+                streamCA.mPID = br->getBits(16) & 0x1fff;
+                ES_info_length -= descriptor_length;
+                descriptor_length -= 4;
+                streamCA.mPrivateData.assign(br->data(), br->data() + descriptor_length);
+                br->skipBits(descriptor_length * 8);
+            } else if (info.mType == STREAMTYPE_PES_PRIVATE_DATA &&
+                       descriptor_tag == DESCRIPTOR_DVB_EXTENSION && descriptor_length >= 1) {
+                unsigned descTagExt = br->getBits(8);
+                ALOGV("      tag_ext = 0x%02x", descTagExt);
+                ES_info_length -= descriptor_length;
+                descriptor_length--;
+                // The AC4 descriptor is used in the PSI PMT to identify streams which carry AC4
+                // audio.
+                if (descTagExt == EXT_DESCRIPTOR_DVB_AC4) {
+                    info.mTypeExt = EXT_DESCRIPTOR_DVB_AC4;
+                    br->skipBits(descriptor_length * 8);
+                } else if (descTagExt == EXT_DESCRIPTOR_DVB_AUDIO_PRESELECTION &&
+                           descriptor_length >= 1) {
+                    // DVB BlueBook A038 Table 110
+                    unsigned num_preselections = br->getBits(5);
+                    br->skipBits(3);  // reserved
+                    for (unsigned i = 0; i < num_preselections; ++i) {
+                        if (br->numBitsLeft() < 16) {
+                            ALOGE("Not enough data left in bitreader!");
+                            return ERROR_MALFORMED;
+                        }
+                        AudioPresentationV1 ap;
+                        ap.mPresentationId = br->getBits(5);  // preselection_id
+
+                        // audio_rendering_indication
+                        ap.mMasteringIndication = static_cast<MasteringIndication>(br->getBits(3));
+                        ap.mAudioDescriptionAvailable = (br->getBits(1) == 1);
+                        ap.mSpokenSubtitlesAvailable = (br->getBits(1) == 1);
+                        ap.mDialogueEnhancementAvailable = (br->getBits(1) == 1);
+
+                        bool interactivity_enabled = (br->getBits(1) == 1);
+                        MY_LOGV("      interactivity_enabled = %d", interactivity_enabled);
+
+                        bool language_code_present = (br->getBits(1) == 1);
+                        bool text_label_present = (br->getBits(1) == 1);
+
+                        bool multi_stream_info_present = (br->getBits(1) == 1);
+                        bool future_extension = (br->getBits(1) == 1);
+                        if (language_code_present) {
+                            if (br->numBitsLeft() < 24) {
+                                ALOGE("Not enough data left in bitreader!");
+                                return ERROR_MALFORMED;
+                            }
+                            char language[4];
+                            language[0] = br->getBits(8);
+                            language[1] = br->getBits(8);
+                            language[2] = br->getBits(8);
+                            language[3] = 0;
+                            ap.mLanguage = String8(language);
+                        }
+
+                        // This maps the presentation id to the message id in the
+                        // EXT_DESCRIPTOR_DVB_MESSAGE so that we can get the presentation label.
+                        if (text_label_present) {
+                            if (br->numBitsLeft() < 8) {
+                                ALOGE("Not enough data left in bitreader!");
+                                return ERROR_MALFORMED;
+                            }
+                            unsigned message_id = br->getBits(8);
+                            MY_LOGV("      message_id = %u", message_id);
+                        }
+
+                        if (multi_stream_info_present) {
+                            if (br->numBitsLeft() < 8) {
+                                ALOGE("Not enough data left in bitreader!");
+                                return ERROR_MALFORMED;
+                            }
+                            unsigned num_aux_components = br->getBits(3);
+                            br->skipBits(5);  // reserved
+                            if (br->numBitsLeft() < (num_aux_components * 8)) {
+                                ALOGE("Not enough data left in bitreader!");
+                                return ERROR_MALFORMED;
+                            }
+                            br->skipBits(num_aux_components * 8);  // component_tag
+                        }
+                        if (future_extension) {
+                            if (br->numBitsLeft() < 8) {
+                                return ERROR_MALFORMED;
+                            }
+                            br->skipBits(3);  // reserved
+                            unsigned future_extension_length = br->getBits(5);
+                            if (br->numBitsLeft() < (future_extension_length * 8)) {
+                                ALOGE("Not enough data left in bitreader!");
+                                return ERROR_MALFORMED;
+                            }
+                            br->skipBits(future_extension_length * 8);  // future_extension_byte
+                        }
+                        info.mAudioPresentations.push_back(std::move(ap));
+                    }
+                } else {
+                    br->skipBits(descriptor_length * 8);
+                }
+            } else {
+                ES_info_length -= descriptor_length;
+                br->skipBits(descriptor_length * 8);
+            }
+        }
         if (hasStreamCA && !mParser->mCasManager->addStream(
-                mProgramNumber, elementaryPID, streamCA)) {
+                mProgramNumber, info.mPID, streamCA)) {
             return ERROR_MALFORMED;
         }
-        StreamInfo info;
-        info.mType = streamType;
-        info.mPID = elementaryPID;
-        info.mCASystemId = hasProgramCA ? programCA.mSystemID :
-                           hasStreamCA ? streamCA.mSystemID  : -1;
-        infos.push(info);
+        if (hasProgramCA) {
+            info.mCADescriptor = programCA;
+        } else if (hasStreamCA) {
+            info.mCADescriptor = streamCA;
+        }
 
-        infoBytesRemaining -= 5 + ES_info_length;
+        infos.push(info);
     }
 
     if (infoBytesRemaining != 0) {
         ALOGW("Section data remains unconsumed");
     }
-    MY_LOGV("  CRC = 0x%08x", br->getBits(32));
+    unsigned crc = br->getBits(32);
+    if (crc != mPMT_CRC) {
+        audioPresentationsChanged = true;
+        mPMT_CRC = crc;
+    }
+    MY_LOGV("  CRC = 0x%08x", crc);
 
     bool PIDsChanged = false;
     for (size_t i = 0; i < infos.size(); ++i) {
@@ -601,16 +734,19 @@
         ssize_t index = mStreams.indexOfKey(info.mPID);
 
         if (index < 0) {
-            sp<Stream> stream = new Stream(
-                    this, info.mPID, info.mType, PCR_PID, info.mCASystemId);
+            sp<Stream> stream = new Stream(this, PCR_PID, info);
 
             if (mSampleAesKeyItem != NULL) {
                 stream->signalNewSampleAesKey(mSampleAesKeyItem);
             }
 
-            isAddingScrambledStream |= info.mCASystemId >= 0;
+            isAddingScrambledStream |= info.mCADescriptor.mSystemID >= 0;
             mStreams.add(info.mPID, stream);
         }
+        else if (index >= 0 && mStreams.editValueAt(index)->isAudio()
+                 && audioPresentationsChanged) {
+            mStreams.editValueAt(index)->setAudioPresentations(info.mAudioPresentations);
+        }
     }
 
     if (isAddingScrambledStream) {
@@ -625,21 +761,21 @@
     // reasonable amount of time. To handle the wrap-around, use fancy math
     // to get an extended PTS that is within [-0xffffffff, 0xffffffff]
     // of the latest recovered PTS.
-    if (mLastRecoveredPTS < 0ll) {
+    if (mLastRecoveredPTS < 0LL) {
         // Use the original 33bit number for 1st frame, the reason is that
         // if 1st frame wraps to negative that's far away from 0, we could
         // never start. Only start wrapping around from 2nd frame.
         mLastRecoveredPTS = static_cast<int64_t>(PTS_33bit);
     } else {
         mLastRecoveredPTS = static_cast<int64_t>(
-                ((mLastRecoveredPTS - static_cast<int64_t>(PTS_33bit) + 0x100000000ll)
+                ((mLastRecoveredPTS - static_cast<int64_t>(PTS_33bit) + 0x100000000LL)
                 & 0xfffffffe00000000ull) | PTS_33bit);
         // We start from 0, but recovered PTS could be slightly below 0.
         // Clamp it to 0 as rest of the pipeline doesn't take negative pts.
         // (eg. video is read first and starts at 0, but audio starts at 0xfffffff0)
-        if (mLastRecoveredPTS < 0ll) {
+        if (mLastRecoveredPTS < 0LL) {
             ALOGI("Clamping negative recovered PTS (%" PRId64 ") to 0", mLastRecoveredPTS);
-            mLastRecoveredPTS = 0ll;
+            mLastRecoveredPTS = 0LL;
         }
     }
 
@@ -689,7 +825,7 @@
 
     int64_t timeUs = (PTS * 100) / 9;
 
-    if (mParser->mAbsoluteTimeAnchorUs >= 0ll) {
+    if (mParser->mAbsoluteTimeAnchorUs >= 0LL) {
         timeUs += mParser->mAbsoluteTimeAnchorUs;
     }
 
@@ -717,34 +853,33 @@
 static const size_t kInitialStreamBufferSize = 192 * 1024;
 
 ATSParser::Stream::Stream(
-        Program *program,
-        unsigned elementaryPID,
-        unsigned streamType,
-        unsigned PCR_PID,
-        int32_t CA_system_ID)
+        Program *program, unsigned PCR_PID, const StreamInfo &info)
     : mProgram(program),
-      mElementaryPID(elementaryPID),
-      mStreamType(streamType),
+      mElementaryPID(info.mPID),
+      mStreamType(info.mType),
+      mStreamTypeExt(info.mTypeExt),
       mPCR_PID(PCR_PID),
       mExpectedContinuityCounter(-1),
       mPayloadStarted(false),
       mEOSReached(false),
       mPrevPTS(0),
       mQueue(NULL),
-      mScrambled(CA_system_ID >= 0) {
-
+      mScrambled(info.mCADescriptor.mSystemID >= 0),
+      mAudioPresentations(info.mAudioPresentations) {
     mSampleEncrypted =
             mStreamType == STREAMTYPE_H264_ENCRYPTED ||
             mStreamType == STREAMTYPE_AAC_ENCRYPTED  ||
             mStreamType == STREAMTYPE_AC3_ENCRYPTED;
 
     ALOGV("new stream PID 0x%02x, type 0x%02x, scrambled %d, SampleEncrypted: %d",
-            elementaryPID, streamType, mScrambled, mSampleEncrypted);
+            info.mPID, info.mType, mScrambled, mSampleEncrypted);
 
-    uint32_t flags =
-            (isVideo() && mScrambled) ? ElementaryStreamQueue::kFlag_ScrambledData :
-            (mSampleEncrypted) ? ElementaryStreamQueue::kFlag_SampleEncryptedData :
-            0;
+    uint32_t flags = 0;
+    if (((isVideo() || isAudio()) && mScrambled)) {
+        flags = ElementaryStreamQueue::kFlag_ScrambledData;
+    } else if (mSampleEncrypted) {
+        flags = ElementaryStreamQueue::kFlag_SampleEncryptedData;
+    }
 
     ElementaryStreamQueue::Mode mode = ElementaryStreamQueue::INVALID;
 
@@ -781,13 +916,23 @@
             mode = ElementaryStreamQueue::AC3;
             break;
 
+        case STREAMTYPE_EAC3:
+            mode = ElementaryStreamQueue::EAC3;
+            break;
+
+        case STREAMTYPE_PES_PRIVATE_DATA:
+            if (mStreamTypeExt == EXT_DESCRIPTOR_DVB_AC4) {
+                mode = ElementaryStreamQueue::AC4;
+            }
+            break;
+
         case STREAMTYPE_METADATA:
             mode = ElementaryStreamQueue::METADATA;
             break;
 
         default:
             ALOGE("stream PID 0x%02x has invalid stream type 0x%02x",
-                    elementaryPID, streamType);
+                    info.mPID, info.mType);
             return;
     }
 
@@ -807,7 +952,13 @@
                     isAudio() ? MEDIA_MIMETYPE_AUDIO_SCRAMBLED
                               : MEDIA_MIMETYPE_VIDEO_SCRAMBLED);
             // for MediaExtractor.CasInfo
-            meta->setInt32(kKeyCASystemID, CA_system_ID);
+            const CADescriptor &descriptor = info.mCADescriptor;
+            meta->setInt32(kKeyCASystemID, descriptor.mSystemID);
+
+            meta->setData(kKeyCAPrivateData, 0,
+                    descriptor.mPrivateData.data(),
+                    descriptor.mPrivateData.size());
+
             mSource = new AnotherPacketSource(meta);
         }
     }
@@ -827,16 +978,43 @@
             mBuffer == NULL ? 0 : mBuffer->capacity(), neededSize, mScrambled);
 
     sp<ABuffer> newBuffer, newScrambledBuffer;
-    sp<IMemory> newMem;
-    sp<MemoryDealer> newDealer;
+    sp<TMemory> newMem;
     if (mScrambled) {
-        size_t alignment = MemoryDealer::getAllocationAlignment();
-        neededSize = (neededSize + (alignment - 1)) & ~(alignment - 1);
-        // Align to multiples of 64K.
-        neededSize = (neededSize + 65535) & ~65535;
-        newDealer = new MemoryDealer(neededSize, "ATSParser");
-        newMem = newDealer->allocate(neededSize);
-        newScrambledBuffer = new ABuffer(newMem->pointer(), newMem->size());
+        if (mHidlAllocator == nullptr) {
+            mHidlAllocator = TAllocator::getService("ashmem");
+            if (mHidlAllocator == nullptr) {
+                ALOGE("[stream %d] can't get hidl allocator", mElementaryPID);
+                return false;
+            }
+        }
+
+        hidl_memory hidlMemToken;
+        bool success;
+        auto transStatus = mHidlAllocator->allocate(
+                neededSize,
+                [&success, &hidlMemToken](
+                        bool s,
+                        hidl_memory const& m) {
+                    success = s;
+                    hidlMemToken = m;
+                });
+
+        if (!transStatus.isOk()) {
+            ALOGE("[stream %d] hidl allocator failed at the transport: %s",
+                    mElementaryPID, transStatus.description().c_str());
+            return false;
+        }
+        if (!success) {
+            ALOGE("[stream %d] hidl allocator failed", mElementaryPID);
+            return false;
+        }
+        newMem = mapMemory(hidlMemToken);
+        if (newMem == nullptr || newMem->getPointer() == nullptr) {
+            ALOGE("[stream %d] hidl failed to map memory", mElementaryPID);
+            return false;
+        }
+
+        newScrambledBuffer = new ABuffer(newMem->getPointer(), newMem->getSize());
 
         if (mDescrambledBuffer != NULL) {
             memcpy(newScrambledBuffer->data(),
@@ -845,24 +1023,15 @@
         } else {
             newScrambledBuffer->setRange(0, 0);
         }
-        mMem = newMem;
-        mDealer = newDealer;
+        mHidlMemory = newMem;
         mDescrambledBuffer = newScrambledBuffer;
 
-        ssize_t offset;
-        size_t size;
-        sp<IMemoryHeap> heap = newMem->getMemory(&offset, &size);
-        if (heap == NULL) {
-            return false;
-        }
+        mDescramblerSrcBuffer.heapBase = hidlMemToken;
+        mDescramblerSrcBuffer.offset = 0ULL;
+        mDescramblerSrcBuffer.size =  (uint64_t)neededSize;
 
-        mHidlMemory = fromHeap(heap);
-        mDescramblerSrcBuffer.heapBase = *mHidlMemory;
-        mDescramblerSrcBuffer.offset = (uint64_t) offset;
-        mDescramblerSrcBuffer.size = (uint64_t) size;
-
-        ALOGD("[stream %d] created shared buffer for descrambling, offset %zd, size %zu",
-                mElementaryPID, offset, size);
+        ALOGD("[stream %d] created shared buffer for descrambling, size %zu",
+                mElementaryPID, neededSize);
     } else {
         // Align to multiples of 64K.
         neededSize = (neededSize + 65535) & ~65535;
@@ -986,9 +1155,12 @@
         case STREAMTYPE_MPEG2_AUDIO_ADTS:
         case STREAMTYPE_LPCM_AC3:
         case STREAMTYPE_AC3:
+        case STREAMTYPE_EAC3:
         case STREAMTYPE_AAC_ENCRYPTED:
         case STREAMTYPE_AC3_ENCRYPTED:
             return true;
+        case STREAMTYPE_PES_PRIVATE_DATA:
+            return mStreamTypeExt == EXT_DESCRIPTOR_DVB_AC4;
 
         default:
             return false;
@@ -1347,7 +1519,7 @@
         return UNKNOWN_ERROR;
     }
 
-    if (mDescrambledBuffer == NULL || mMem == NULL) {
+    if (mDescrambledBuffer == NULL || mHidlMemory == NULL) {
         ALOGE("received scrambled packets without shared memory!");
 
         return UNKNOWN_ERROR;
@@ -1395,7 +1567,7 @@
     // Perform the 1st pass descrambling if needed
     if (descrambleBytes > 0) {
         memcpy(mDescrambledBuffer->data(), mBuffer->data(), descrambleBytes);
-        mDescrambledBuffer->setRange(0, descrambleBytes);
+        mDescrambledBuffer->setRange(0, mBuffer->size());
 
         hidl_vec<SubSample> subSamples;
         subSamples.resize(descrambleSubSamples);
@@ -1412,10 +1584,9 @@
             }
         }
 
-        uint64_t srcOffset = 0, dstOffset = 0;
-        // If scrambled at PES-level, PES header should be skipped
+        // If scrambled at PES-level, PES header is in the clear
         if (pesScramblingControl != 0) {
-            srcOffset = dstOffset = pesOffset;
+            subSamples[0].numBytesOfClearData = pesOffset;
             subSamples[0].numBytesOfEncryptedData -= pesOffset;
         }
 
@@ -1431,9 +1602,9 @@
                 (ScramblingControl) sctrl,
                 subSamples,
                 mDescramblerSrcBuffer,
-                srcOffset,
+                0 /*srcOffset*/,
                 dstBuffer,
-                dstOffset,
+                0 /*dstOffset*/,
                 [&status, &bytesWritten, &detailedError] (
                         Status _status, uint32_t _bytesWritten,
                         const hidl_string& _detailedError) {
@@ -1442,17 +1613,29 @@
                     detailedError = _detailedError;
                 });
 
-        if (!returnVoid.isOk()) {
-            ALOGE("[stream %d] descramble failed, trans=%s",
-                    mElementaryPID, returnVoid.description().c_str());
+        if (!returnVoid.isOk() || status != Status::OK) {
+            ALOGE("[stream %d] descramble failed, trans=%s, status=%d",
+                    mElementaryPID, returnVoid.description().c_str(), status);
             return UNKNOWN_ERROR;
         }
 
         ALOGV("[stream %d] descramble succeeded, %d bytes",
                 mElementaryPID, bytesWritten);
-        memcpy(mBuffer->data(), mDescrambledBuffer->data(), descrambleBytes);
+
+        // Set descrambleBytes to the returned result.
+        // Note that this might be smaller than the total length of input data.
+        // (eg. when we're descrambling the PES header portion of a secure stream,
+        // the plugin might cut it off right after the PES header.)
+        descrambleBytes = bytesWritten;
     }
 
+    // |buffer| points to the buffer from which we'd parse the PES header.
+    // When the output stream is scrambled, it points to mDescrambledBuffer
+    // (unless all packets in this PES are actually clear, in which case,
+    // it points to mBuffer since we never copied into mDescrambledBuffer).
+    // When the output stream is clear, it points to mBuffer, and we'll
+    // copy all descrambled data back to mBuffer.
+    sp<ABuffer> buffer = mBuffer;
     if (mQueue->isScrambled()) {
         // Queue subSample info for scrambled queue
         sp<ABuffer> clearSizesBuffer = new ABuffer(mSubSamples.size() * 4);
@@ -1464,8 +1647,7 @@
         for (auto it = mSubSamples.begin();
                 it != mSubSamples.end(); it++, i++) {
             if ((it->transport_scrambling_mode == 0
-                    && pesScramblingControl == 0)
-                    || i < descrambleSubSamples) {
+                    && pesScramblingControl == 0)) {
                 clearSizePtr[i] = it->subSampleSize;
                 encSizePtr[i] = 0;
             } else {
@@ -1474,14 +1656,29 @@
             }
             isSync |= it->random_access_indicator;
         }
+
+        // If scrambled at PES-level, PES header is in the clear
+        if (pesScramblingControl != 0) {
+            clearSizePtr[0] = pesOffset;
+            encSizePtr[0] -= pesOffset;
+        }
         // Pass the original TS subsample size now. The PES header adjust
         // will be applied when the scrambled AU is dequeued.
+        // Note that if descrambleBytes is 0, it means this PES contains only
+        // all ts packets, leadingClearBytes is entire buffer size.
         mQueue->appendScrambledData(
-                mBuffer->data(), mBuffer->size(), sctrl,
-                isSync, clearSizesBuffer, encSizesBuffer);
+                mBuffer->data(), mBuffer->size(),
+                (descrambleBytes > 0) ? descrambleBytes : mBuffer->size(),
+                sctrl, isSync, clearSizesBuffer, encSizesBuffer);
+
+        if (descrambleBytes > 0) {
+            buffer = mDescrambledBuffer;
+        }
+    } else {
+        memcpy(mBuffer->data(), mDescrambledBuffer->data(), descrambleBytes);
     }
 
-    ABitReader br(mBuffer->data(), mBuffer->size());
+    ABitReader br(buffer->data(), buffer->size());
     status_t err = parsePES(&br, event);
 
     if (err != OK) {
@@ -1514,6 +1711,13 @@
     return err;
 }
 
+void ATSParser::Stream::addAudioPresentations(const sp<ABuffer> &buffer) {
+    std::ostringstream outStream(std::ios::out);
+    serializeAudioPresentations(mAudioPresentations, &outStream);
+    sp<ABuffer> ap = ABuffer::CreateAsCopy(outStream.str().data(), outStream.str().size());
+    buffer->meta()->setBuffer("audio-presentation-info", ap);
+}
+
 void ATSParser::Stream::onPayloadData(
         unsigned PTS_DTS_flags, uint64_t PTS, uint64_t /* DTS */,
         unsigned PES_scrambling_control,
@@ -1529,7 +1733,7 @@
 
     ALOGV("onPayloadData mStreamType=0x%02x size: %zu", mStreamType, size);
 
-    int64_t timeUs = 0ll;  // no presentation timestamp available.
+    int64_t timeUs = 0LL;  // no presentation timestamp available.
     if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {
         timeUs = mProgram->convertPTSToTimestamp(PTS);
     }
@@ -1564,6 +1768,9 @@
                     }
                 }
                 mSource = new AnotherPacketSource(meta);
+                if (mAudioPresentations.size() > 0) {
+                    addAudioPresentations(accessUnit);
+                }
                 mSource->queueAccessUnit(accessUnit);
                 ALOGV("onPayloadData: created AnotherPacketSource PID 0x%08x of type 0x%02x",
                         mElementaryPID, mStreamType);
@@ -1576,6 +1783,9 @@
             if (mSource->getFormat() == NULL) {
                 mSource->setFormat(mQueue->getFormat());
             }
+            if (mAudioPresentations.size() > 0) {
+                addAudioPresentations(accessUnit);
+            }
             mSource->queueAccessUnit(accessUnit);
         }
 
@@ -1659,10 +1869,10 @@
 
 ATSParser::ATSParser(uint32_t flags)
     : mFlags(flags),
-      mAbsoluteTimeAnchorUs(-1ll),
+      mAbsoluteTimeAnchorUs(-1LL),
       mTimeOffsetValid(false),
-      mTimeOffsetUs(0ll),
-      mLastRecoveredPTS(-1ll),
+      mTimeOffsetUs(0LL),
+      mLastRecoveredPTS(-1LL),
       mNumTSPacketsParsed(0),
       mNumPCRs(0) {
     mPSISections.add(0 /* PID */, new PSISection);
@@ -1704,7 +1914,7 @@
         if ((mFlags & TS_TIMESTAMPS_ARE_ABSOLUTE)
                 && extra->findInt64(
                     kATSParserKeyRecentMediaTimeUs, &mediaTimeUs)) {
-            if (mAbsoluteTimeAnchorUs >= 0ll) {
+            if (mAbsoluteTimeAnchorUs >= 0LL) {
                 mediaTimeUs -= mAbsoluteTimeAnchorUs;
             }
             if (mTimeOffsetValid) {
diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h
index 45ca06b..0ff2d7e 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.h
+++ b/media/libstagefright/mpeg2ts/ATSParser.h
@@ -23,6 +23,7 @@
 #include <media/MediaSource.h>
 #include <media/stagefright/foundation/ABase.h>
 #include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/AudioPresentationInfo.h>
 #include <utils/KeyedVector.h>
 #include <utils/Vector.h>
 #include <utils/RefBase.h>
@@ -142,6 +143,7 @@
         STREAMTYPE_MPEG2_VIDEO          = 0x02,
         STREAMTYPE_MPEG1_AUDIO          = 0x03,
         STREAMTYPE_MPEG2_AUDIO          = 0x04,
+        STREAMTYPE_PES_PRIVATE_DATA     = 0x06,
         STREAMTYPE_MPEG2_AUDIO_ADTS     = 0x0f,
         STREAMTYPE_MPEG4_VIDEO          = 0x10,
         STREAMTYPE_METADATA             = 0x15,
@@ -153,6 +155,7 @@
         // Stream type 0x83 is non-standard,
         // it could be LPCM or TrueHD AC3
         STREAMTYPE_LPCM_AC3             = 0x83,
+        STREAMTYPE_EAC3                 = 0x87,
 
         //Sample Encrypted types
         STREAMTYPE_H264_ENCRYPTED       = 0xDB,
@@ -160,6 +163,21 @@
         STREAMTYPE_AC3_ENCRYPTED        = 0xC1,
     };
 
+    enum {
+        // From ISO/IEC 13818-1: 2007 (E), Table 2-45
+        DESCRIPTOR_CA                   = 0x09,
+
+        // DVB BlueBook A038 Table 12
+        DESCRIPTOR_DVB_EXTENSION        = 0x7F,
+    };
+
+    // DVB BlueBook A038 Table 109
+    enum {
+        EXT_DESCRIPTOR_DVB_AC4                  = 0x15,
+        EXT_DESCRIPTOR_DVB_AUDIO_PRESELECTION   = 0x19,
+        EXT_DESCRIPTOR_DVB_RESERVED_MAX         = 0x7F,
+    };
+
 protected:
     virtual ~ATSParser();
 
@@ -169,11 +187,20 @@
     struct PSISection;
     struct CasManager;
     struct CADescriptor {
-        int32_t mSystemID;
+        CADescriptor() : mPID(0), mSystemID(-1) {}
         unsigned mPID;
+        int32_t mSystemID;
         std::vector<uint8_t> mPrivateData;
     };
 
+    struct StreamInfo {
+        unsigned mType;
+        unsigned mTypeExt;
+        unsigned mPID;
+        CADescriptor mCADescriptor;
+        AudioPresentationCollection mAudioPresentations;
+    };
+
     sp<CasManager> mCasManager;
 
     uint32_t mFlags;
diff --git a/media/libstagefright/mpeg2ts/Android.bp b/media/libstagefright/mpeg2ts/Android.bp
index fbf1496..a507b91 100644
--- a/media/libstagefright/mpeg2ts/Android.bp
+++ b/media/libstagefright/mpeg2ts/Android.bp
@@ -25,17 +25,19 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
     shared_libs: [
         "libcrypto",
         "libmedia",
-        "libhidlallocatorutils",
+        "libhidlmemory",
         "android.hardware.cas.native@1.0",
         "android.hidl.memory@1.0",
+        "android.hidl.allocator@1.0",
+    ],
+
+    header_libs: [
+        "media_ndk_headers",
     ],
 
     whole_static_libs: [
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
index ece0692..62e3a4b 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
@@ -35,7 +35,7 @@
 
 namespace android {
 
-const int64_t kNearEOSMarkUs = 2000000ll; // 2 secs
+const int64_t kNearEOSMarkUs = 2000000LL; // 2 secs
 
 AnotherPacketSource::AnotherPacketSource(const sp<MetaData> &meta)
     : mIsAudio(false),
@@ -223,9 +223,16 @@
                     kKeyMpegUserData, 0, mpegUserData->data(), mpegUserData->size());
         }
 
+        sp<ABuffer> ap;
+        if (buffer->meta()->findBuffer("audio-presentation-info", &ap) && ap != NULL) {
+            bufmeta.setData(
+                    kKeyAudioPresentationInfo, 0, ap->data(), ap->size());
+        }
+
         int32_t cryptoMode;
         if (buffer->meta()->findInt32("cryptoMode", &cryptoMode)) {
             int32_t cryptoKey;
+            int32_t pesOffset;
             sp<ABuffer> clearBytesBuffer, encBytesBuffer;
 
             CHECK(buffer->meta()->findInt32("cryptoKey", &cryptoKey));
@@ -233,6 +240,8 @@
                     && clearBytesBuffer != NULL);
             CHECK(buffer->meta()->findBuffer("encBytes", &encBytesBuffer)
                     && encBytesBuffer != NULL);
+            CHECK(buffer->meta()->findInt32("pesOffset", &pesOffset)
+                    && (pesOffset >= 0) && (pesOffset < 65536));
 
             bufmeta.setInt32(kKeyCryptoMode, cryptoMode);
 
@@ -240,6 +249,11 @@
             bufmeta.setData(kKeyCryptoIV, 0, array, 16);
 
             array[0] = (uint8_t) (cryptoKey & 0xff);
+            // array[1] contains PES header flag, which we don't use.
+            // array[2~3] contain the PES offset.
+            array[2] = (uint8_t) (pesOffset & 0xff);
+            array[3] = (uint8_t) ((pesOffset >> 8) & 0xff);
+
             bufmeta.setData(kKeyCryptoKey, 0, array, 16);
 
             bufmeta.setData(kKeyPlainSizes, 0,
@@ -285,7 +299,7 @@
     if (buffer->meta()->findInt32("discontinuity", &discontinuity)){
         ALOGV("queueing a discontinuity with queueAccessUnit");
 
-        mLastQueuedTimeUs = 0ll;
+        mLastQueuedTimeUs = 0LL;
         mEOSResult = OK;
         mLatestEnqueuedMeta = NULL;
 
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index 86fa245..e89d3e3 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -86,6 +86,21 @@
     mCasSessionId = sessionId;
 }
 
+static int32_t readVariableBits(ABitReader &bits, int32_t nbits) {
+    int32_t value = 0;
+    int32_t more_bits = 1;
+
+    while (more_bits) {
+        value += bits.getBits(nbits);
+        more_bits = bits.getBits(1);
+        if (!more_bits)
+            break;
+        value++;
+        value <<= nbits;
+    }
+    return value;
+}
+
 // Parse AC3 header assuming the current ptr is start position of syncframe,
 // update metadata only applicable, and return the payload size
 static unsigned parseAC3SyncFrame(
@@ -195,8 +210,153 @@
     return payloadSize;
 }
 
-static bool IsSeeminglyValidAC3Header(const uint8_t *ptr, size_t size) {
-    return parseAC3SyncFrame(ptr, size, NULL) > 0;
+// Parse EAC3 header assuming the current ptr is start position of syncframe,
+// update metadata only applicable, and return the payload size
+// ATSC A/52:2012 E2.3.1
+static unsigned parseEAC3SyncFrame(
+    const uint8_t *ptr, size_t size, sp<MetaData> *metaData) {
+    static const unsigned channelCountTable[] = {2, 1, 2, 3, 3, 4, 4, 5};
+    static const unsigned samplingRateTable[] = {48000, 44100, 32000};
+    static const unsigned samplingRateTable2[] = {24000, 22050, 16000};
+
+    ABitReader bits(ptr, size);
+    if (bits.numBitsLeft() < 16) {
+        ALOGE("Not enough bits left for further parsing");
+        return 0;
+    }
+    if (bits.getBits(16) != 0x0B77) {
+        ALOGE("No valid sync word in EAC3 header");
+        return 0;
+    }
+
+    // we parse up to bsid so there needs to be at least that many bits
+    if (bits.numBitsLeft() < 2 + 3 + 11 + 2 + 2 + 3 + 1 + 5) {
+        ALOGE("Not enough bits left for further parsing");
+        return 0;
+    }
+
+    unsigned strmtyp = bits.getBits(2);
+    if (strmtyp == 3) {
+        ALOGE("Incorrect strmtyp in EAC3 header");
+        return 0;
+    }
+
+    unsigned substreamid = bits.getBits(3);
+    // only the first independent stream is supported
+    if ((strmtyp == 0 || strmtyp == 2) && substreamid != 0)
+        return 0;
+
+    unsigned frmsiz = bits.getBits(11);
+    unsigned fscod = bits.getBits(2);
+
+    unsigned samplingRate = 0;
+    if (fscod == 0x3) {
+        unsigned fscod2 = bits.getBits(2);
+        if (fscod2 == 3) {
+            ALOGW("Incorrect fscod2 in EAC3 header");
+            return 0;
+        }
+        samplingRate = samplingRateTable2[fscod2];
+    } else {
+        samplingRate = samplingRateTable[fscod];
+        unsigned numblkscod __unused = bits.getBits(2);
+    }
+
+    unsigned acmod = bits.getBits(3);
+    unsigned lfeon = bits.getBits(1);
+    unsigned bsid = bits.getBits(5);
+    if (bsid < 11 || bsid > 16) {
+        ALOGW("Incorrect bsid in EAC3 header. Could be AC-3 or some unknown EAC3 format");
+        return 0;
+    }
+
+    // we currently only support the first independant stream
+    if (metaData != NULL && (strmtyp == 0 || strmtyp == 2)) {
+        unsigned channelCount = channelCountTable[acmod] + lfeon;
+        ALOGV("EAC3 channelCount = %d", channelCount);
+        ALOGV("EAC3 samplingRate = %d", samplingRate);
+        (*metaData)->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_EAC3);
+        (*metaData)->setInt32(kKeyChannelCount, channelCount);
+        (*metaData)->setInt32(kKeySampleRate, samplingRate);
+        (*metaData)->setInt32(kKeyIsSyncFrame, 1);
+    }
+
+    unsigned payloadSize = frmsiz + 1;
+    payloadSize <<= 1;  // convert from 16-bit words to bytes
+
+    return payloadSize;
+}
+
+// Parse AC4 header assuming the current ptr is start position of syncframe
+// and update frameSize and metadata.
+static status_t parseAC4SyncFrame(
+        const uint8_t *ptr, size_t size, unsigned &frameSize, sp<MetaData> *metaData) {
+    // ETSI TS 103 190-2 V1.1.1 (2015-09), Annex C
+    // The sync_word can be either 0xAC40 or 0xAC41.
+    static const int kSyncWordAC40 = 0xAC40;
+    static const int kSyncWordAC41 = 0xAC41;
+
+    size_t headerSize = 0;
+    ABitReader bits(ptr, size);
+    int32_t syncWord = bits.getBits(16);
+    if ((syncWord != kSyncWordAC40) && (syncWord != kSyncWordAC41)) {
+        ALOGE("Invalid syncword in AC4 header");
+        return ERROR_MALFORMED;
+    }
+    headerSize += 2;
+
+    frameSize = bits.getBits(16);
+    headerSize += 2;
+    if (frameSize == 0xFFFF) {
+        frameSize = bits.getBits(24);
+        headerSize += 3;
+    }
+
+    if (frameSize == 0) {
+        ALOGE("Invalid frame size in AC4 header");
+        return ERROR_MALFORMED;
+    }
+    frameSize += headerSize;
+    // If the sync_word is 0xAC41, a crc_word is also transmitted.
+    if (syncWord == kSyncWordAC41) {
+        frameSize += 2; // crc_word
+    }
+    ALOGV("AC4 frameSize = %u", frameSize);
+
+    // ETSI TS 103 190-2 V1.1.1 6.2.1.1
+    uint32_t bitstreamVersion = bits.getBits(2);
+    if (bitstreamVersion == 3) {
+        bitstreamVersion += readVariableBits(bits, 2);
+    }
+
+    bits.skipBits(10); // Sequence Counter
+
+    uint32_t bWaitFrames = bits.getBits(1);
+    if (bWaitFrames) {
+        uint32_t waitFrames = bits.getBits(3);
+        if (waitFrames > 0) {
+            bits.skipBits(2); // br_code;
+        }
+    }
+
+    // ETSI TS 103 190 V1.1.1 Table 82
+    bool fsIndex = bits.getBits(1);
+    uint32_t samplingRate = fsIndex ? 48000 : 44100;
+
+    if (metaData != NULL) {
+        ALOGV("dequeueAccessUnitAC4 Setting mFormat");
+        (*metaData)->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC4);
+        (*metaData)->setInt32(kKeyIsSyncFrame, 1);
+        // [FIXME] AC4 channel count is defined per presentation. Provide a default channel count
+        // as stereo for the entire stream.
+        (*metaData)->setInt32(kKeyChannelCount, 2);
+        (*metaData)->setInt32(kKeySampleRate, samplingRate);
+    }
+    return OK;
+}
+
+static status_t IsSeeminglyValidAC4Header(const uint8_t *ptr, size_t size, unsigned &frameSize) {
+    return parseAC4SyncFrame(ptr, size, frameSize, NULL);
 }
 
 static bool IsSeeminglyValidADTSHeader(
@@ -279,7 +439,8 @@
         ALOGE("appending data after EOS");
         return ERROR_MALFORMED;
     }
-    if (mBuffer == NULL || mBuffer->size() == 0) {
+
+    if (!isScrambled() && (mBuffer == NULL || mBuffer->size() == 0)) {
         switch (mMode) {
             case H264:
             case MPEG_VIDEO:
@@ -390,12 +551,19 @@
             }
 
             case AC3:
+            case EAC3:
             {
                 uint8_t *ptr = (uint8_t *)data;
 
                 ssize_t startOffset = -1;
                 for (size_t i = 0; i < size; ++i) {
-                    if (IsSeeminglyValidAC3Header(&ptr[i], size - i)) {
+                    unsigned payloadSize = 0;
+                    if (mMode == AC3) {
+                        payloadSize = parseAC3SyncFrame(&ptr[i], size - i, NULL);
+                    } else if (mMode == EAC3) {
+                        payloadSize = parseEAC3SyncFrame(&ptr[i], size - i, NULL);
+                    }
+                    if (payloadSize > 0) {
                         startOffset = i;
                         break;
                     }
@@ -406,7 +574,7 @@
                 }
 
                 if (startOffset > 0) {
-                    ALOGI("found something resembling an AC3 syncword at "
+                    ALOGI("found something resembling an (E)AC3 syncword at "
                           "offset %zd",
                           startOffset);
                 }
@@ -416,6 +584,43 @@
                 break;
             }
 
+            case AC4:
+            {
+                uint8_t *ptr = (uint8_t *)data;
+                unsigned frameSize = 0;
+                ssize_t startOffset = -1;
+
+                // A valid AC4 stream should have minimum of 7 bytes in its buffer.
+                // (Sync header 4 bytes + AC4 toc 3 bytes)
+                if (size < 7) {
+                    return ERROR_MALFORMED;
+                }
+                for (size_t i = 0; i < size; ++i) {
+                    if (IsSeeminglyValidAC4Header(&ptr[i], size - i, frameSize) == OK) {
+                        startOffset = i;
+                        break;
+                    }
+                }
+
+                if (startOffset < 0) {
+                    return ERROR_MALFORMED;
+                }
+
+                if (startOffset > 0) {
+                    ALOGI("found something resembling an AC4 syncword at "
+                          "offset %zd",
+                          startOffset);
+                }
+                if (frameSize != size - startOffset) {
+                    ALOGV("AC4 frame size is %u bytes, while the buffer size is %zd bytes.",
+                          frameSize, size - startOffset);
+                }
+
+                data = &ptr[startOffset];
+                size -= startOffset;
+                break;
+            }
+
             case MPEG_AUDIO:
             {
                 uint8_t *ptr = (uint8_t *)data;
@@ -494,6 +699,7 @@
 
 void ElementaryStreamQueue::appendScrambledData(
         const void *data, size_t size,
+        size_t leadingClearBytes,
         int32_t keyId, bool isSync,
         sp<ABuffer> clearSizes, sp<ABuffer> encSizes) {
     if (!isScrambled()) {
@@ -521,6 +727,7 @@
 
     ScrambledRangeInfo scrambledInfo;
     scrambledInfo.mLength = size;
+    scrambledInfo.mLeadingClearBytes = leadingClearBytes;
     scrambledInfo.mKeyId = keyId;
     scrambledInfo.mIsSync = isSync;
     scrambledInfo.mClearSizes = clearSizes;
@@ -533,7 +740,6 @@
 
 sp<ABuffer> ElementaryStreamQueue::dequeueScrambledAccessUnit() {
     size_t nextScan = mBuffer->size();
-    mBuffer->setRange(0, 0);
     int32_t pesOffset = 0, pesScramblingControl = 0;
     int64_t timeUs = fetchTimestamp(nextScan, &pesOffset, &pesScramblingControl);
     if (timeUs < 0ll) {
@@ -544,6 +750,7 @@
     // return scrambled unit
     int32_t keyId = pesScramblingControl, isSync = 0, scrambledLength = 0;
     sp<ABuffer> clearSizes, encSizes;
+    size_t leadingClearBytes;
     while (mScrambledRangeInfos.size() > mRangeInfos.size()) {
         auto it = mScrambledRangeInfos.begin();
         ALOGV("[stream %d] fetching scrambled range: size=%zu", mMode, it->mLength);
@@ -561,6 +768,7 @@
         clearSizes = it->mClearSizes;
         encSizes = it->mEncSizes;
         isSync = it->mIsSync;
+        leadingClearBytes = it->mLeadingClearBytes;
         mScrambledRangeInfos.erase(it);
     }
     if (scrambledLength == 0) {
@@ -568,26 +776,74 @@
         return NULL;
     }
 
-    // skip the PES header, and copy the rest into scrambled access unit
-    sp<ABuffer> scrambledAccessUnit = ABuffer::CreateAsCopy(
-            mScrambledBuffer->data() + pesOffset,
-            scrambledLength - pesOffset);
-
-    // fix up first sample size after skipping the PES header
-    if (pesOffset > 0) {
-        int32_t &firstClearSize = *(int32_t*)clearSizes->data();
-        int32_t &firstEncSize = *(int32_t*)encSizes->data();
-        // Cut away the PES header
-        if (firstClearSize >= pesOffset) {
-            // This is for TS-level scrambling, we descrambled the first
-            // (or it was clear to begin with)
-            firstClearSize -= pesOffset;
-        } else if (firstEncSize >= pesOffset) {
-            // This can only be PES-level scrambling
-            firstEncSize -= pesOffset;
-        }
+    // Retrieve the leading clear bytes info, and use it to set the clear
+    // range on mBuffer. Note that the leading clear bytes includes the
+    // PES header portion, while mBuffer doesn't.
+    if ((int32_t)leadingClearBytes > pesOffset) {
+        mBuffer->setRange(0, leadingClearBytes - pesOffset);
+    } else {
+        mBuffer->setRange(0, 0);
     }
 
+    // Try to parse formats, and if unavailable set up a dummy format.
+    // Only support the following modes for scrambled content for now.
+    // (will be expanded later).
+    if (mFormat == NULL) {
+        mFormat = new MetaData;
+        switch (mMode) {
+            case H264:
+            {
+                if (!MakeAVCCodecSpecificData(
+                        *mFormat, mBuffer->data(), mBuffer->size())) {
+                    ALOGI("Creating dummy AVC format for scrambled content");
+
+                    mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
+                    mFormat->setInt32(kKeyWidth, 1280);
+                    mFormat->setInt32(kKeyHeight, 720);
+                }
+                break;
+            }
+            case AAC:
+            {
+                if (!MakeAACCodecSpecificData(
+                        *mFormat, mBuffer->data(), mBuffer->size())) {
+                    ALOGI("Creating dummy AAC format for scrambled content");
+
+                    MakeAACCodecSpecificData(*mFormat,
+                            1 /*profile*/, 7 /*sampling_freq_index*/, 1 /*channel_config*/);
+                    mFormat->setInt32(kKeyIsADTS, true);
+                }
+
+                break;
+            }
+            case MPEG_VIDEO:
+            {
+                ALOGI("Creating dummy MPEG format for scrambled content");
+
+                mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2);
+                mFormat->setInt32(kKeyWidth, 1280);
+                mFormat->setInt32(kKeyHeight, 720);
+                break;
+            }
+            default:
+            {
+                ALOGE("Unknown mode for scrambled content");
+                return NULL;
+            }
+        }
+
+        // for MediaExtractor.CasInfo
+        mFormat->setInt32(kKeyCASystemID, mCASystemId);
+        mFormat->setData(kKeyCASessionID,
+                0, mCasSessionId.data(), mCasSessionId.size());
+    }
+
+    mBuffer->setRange(0, 0);
+
+    // copy into scrambled access unit
+    sp<ABuffer> scrambledAccessUnit = ABuffer::CreateAsCopy(
+            mScrambledBuffer->data(), scrambledLength);
+
     scrambledAccessUnit->meta()->setInt64("timeUs", timeUs);
     if (isSync) {
         scrambledAccessUnit->meta()->setInt32("isSync", 1);
@@ -600,6 +856,7 @@
     scrambledAccessUnit->meta()->setInt32("cryptoKey", keyId);
     scrambledAccessUnit->meta()->setBuffer("clearBytes", clearSizes);
     scrambledAccessUnit->meta()->setBuffer("encBytes", encSizes);
+    scrambledAccessUnit->meta()->setInt32("pesOffset", pesOffset);
 
     memmove(mScrambledBuffer->data(),
             mScrambledBuffer->data() + scrambledLength,
@@ -614,7 +871,11 @@
 }
 
 sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnit() {
-    if ((mFlags & kFlag_AlignedData) && mMode == H264 && !isScrambled()) {
+    if (isScrambled()) {
+        return dequeueScrambledAccessUnit();
+    }
+
+    if ((mFlags & kFlag_AlignedData) && mMode == H264) {
         if (mRangeInfos.empty()) {
             return NULL;
         }
@@ -648,7 +909,10 @@
         case AAC:
             return dequeueAccessUnitAAC();
         case AC3:
-            return dequeueAccessUnitAC3();
+        case EAC3:
+            return dequeueAccessUnitEAC3();
+        case AC4:
+            return dequeueAccessUnitAC4();
         case MPEG_VIDEO:
             return dequeueAccessUnitMPEGVideo();
         case MPEG4_VIDEO:
@@ -666,34 +930,38 @@
     }
 }
 
-sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitAC3() {
+sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitEAC3() {
     unsigned syncStartPos = 0;  // in bytes
     unsigned payloadSize = 0;
     sp<MetaData> format = new MetaData;
 
-    ALOGV("dequeueAccessUnit_AC3[%d]: mBuffer %p(%zu)", mAUIndex, mBuffer->data(), mBuffer->size());
+    ALOGV("dequeueAccessUnitEAC3[%d]: mBuffer %p(%zu)", mAUIndex,
+            mBuffer->data(), mBuffer->size());
 
     while (true) {
         if (syncStartPos + 2 >= mBuffer->size()) {
             return NULL;
         }
 
-        payloadSize = parseAC3SyncFrame(
-                mBuffer->data() + syncStartPos,
-                mBuffer->size() - syncStartPos,
-                &format);
+        uint8_t *ptr = mBuffer->data() + syncStartPos;
+        size_t size = mBuffer->size() - syncStartPos;
+        if (mMode == AC3) {
+            payloadSize = parseAC3SyncFrame(ptr, size, &format);
+        } else if (mMode == EAC3) {
+            payloadSize = parseEAC3SyncFrame(ptr, size, &format);
+        }
         if (payloadSize > 0) {
             break;
         }
 
-        ALOGV("dequeueAccessUnit_AC3[%d]: syncStartPos %u payloadSize %u",
+        ALOGV("dequeueAccessUnitEAC3[%d]: syncStartPos %u payloadSize %u",
                 mAUIndex, syncStartPos, payloadSize);
 
         ++syncStartPos;
     }
 
     if (mBuffer->size() < syncStartPos + payloadSize) {
-        ALOGV("Not enough buffer size for AC3");
+        ALOGV("Not enough buffer size for E/AC3");
         return NULL;
     }
 
@@ -701,7 +969,6 @@
         mFormat = format;
     }
 
-
     int64_t timeUs = fetchTimestamp(syncStartPos + payloadSize);
     if (timeUs < 0ll) {
         ALOGE("negative timeUs");
@@ -710,7 +977,12 @@
 
     // Not decrypting if key info not available (e.g., scanner/extractor parsing ts files)
     if (mSampleDecryptor != NULL) {
-        mSampleDecryptor->processAC3(mBuffer->data() + syncStartPos, payloadSize);
+        if (mMode == AC3) {
+            mSampleDecryptor->processAC3(mBuffer->data() + syncStartPos, payloadSize);
+        } else if (mMode == EAC3) {
+            ALOGE("EAC3 AU is encrypted and decryption is not supported");
+            return NULL;
+        }
     }
     mAUIndex++;
 
@@ -730,6 +1002,69 @@
     return accessUnit;
 }
 
+sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitAC4() {
+    unsigned syncStartPos = 0;
+    unsigned payloadSize = 0;
+    sp<MetaData> format = new MetaData;
+    ALOGV("dequeueAccessUnit_AC4[%d]: mBuffer %p(%zu)", mAUIndex, mBuffer->data(), mBuffer->size());
+
+    // A valid AC4 stream should have minimum of 7 bytes in its buffer.
+    // (Sync header 4 bytes + AC4 toc 3 bytes)
+    if (mBuffer->size() < 7) {
+        return NULL;
+    }
+
+    while (true) {
+        if (syncStartPos + 2 >= mBuffer->size()) {
+            return NULL;
+        }
+
+        status_t status = parseAC4SyncFrame(
+                    mBuffer->data() + syncStartPos,
+                    mBuffer->size() - syncStartPos,
+                    payloadSize,
+                    &format);
+        if (status == OK) {
+            break;
+        }
+
+        ALOGV("dequeueAccessUnit_AC4[%d]: syncStartPos %u payloadSize %u",
+                mAUIndex, syncStartPos, payloadSize);
+
+        ++syncStartPos;
+    }
+
+    if (mBuffer->size() < syncStartPos + payloadSize) {
+        ALOGV("Not enough buffer size for AC4");
+        return NULL;
+    }
+
+    if (mFormat == NULL) {
+        mFormat = format;
+    }
+
+    int64_t timeUs = fetchTimestamp(syncStartPos + payloadSize);
+    if (timeUs < 0ll) {
+        ALOGE("negative timeUs");
+        return NULL;
+    }
+    mAUIndex++;
+
+    sp<ABuffer> accessUnit = new ABuffer(syncStartPos + payloadSize);
+    memcpy(accessUnit->data(), mBuffer->data(), syncStartPos + payloadSize);
+
+    accessUnit->meta()->setInt64("timeUs", timeUs);
+    accessUnit->meta()->setInt32("isSync", 1);
+
+    memmove(
+            mBuffer->data(),
+            mBuffer->data() + syncStartPos + payloadSize,
+            mBuffer->size() - syncStartPos - payloadSize);
+
+    mBuffer->setRange(0, mBuffer->size() - syncStartPos - payloadSize);
+    return accessUnit;
+}
+
 sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitPCMAudio() {
     if (mBuffer->size() < 4) {
         return NULL;
@@ -776,7 +1111,7 @@
     memcpy(accessUnit->data(), mBuffer->data() + 4, payloadSize);
 
     int64_t timeUs = fetchTimestamp(payloadSize + 4);
-    if (timeUs < 0ll) {
+    if (timeUs < 0LL) {
         ALOGE("Negative timeUs");
         return NULL;
     }
@@ -812,7 +1147,7 @@
         return NULL;
     }
 
-    if (info.mTimestampUs < 0ll) {
+    if (info.mTimestampUs < 0LL) {
         ALOGE("Negative info.mTimestampUs");
         return NULL;
     }
@@ -851,25 +1186,11 @@
         bool protection_absent = bits.getBits(1) != 0;
 
         if (mFormat == NULL) {
-            unsigned profile = bits.getBits(2);
-            if (profile == 3u) {
-                ALOGE("profile should not be 3");
-                return NULL;
-            }
-            unsigned sampling_freq_index = bits.getBits(4);
-            bits.getBits(1);  // private_bit
-            unsigned channel_configuration = bits.getBits(3);
-            if (channel_configuration == 0u) {
-                ALOGE("channel_config should not be 0");
-                return NULL;
-            }
-            bits.skipBits(2);  // original_copy, home
-
             mFormat = new MetaData;
-            MakeAACCodecSpecificData(*mFormat,
-                    profile, sampling_freq_index, channel_configuration);
-
-            mFormat->setInt32(kKeyIsADTS, true);
+            if (!MakeAACCodecSpecificData(
+                    *mFormat, mBuffer->data() + offset, mBuffer->size() - offset)) {
+                return NULL;
+            }
 
             int32_t sampleRate;
             int32_t numChannels;
@@ -884,12 +1205,12 @@
 
             ALOGI("found AAC codec config (%d Hz, %d channels)",
                  sampleRate, numChannels);
-        } else {
-            // profile_ObjectType, sampling_frequency_index, private_bits,
-            // channel_configuration, original_copy, home
-            bits.skipBits(12);
         }
 
+        // profile_ObjectType, sampling_frequency_index, private_bits,
+        // channel_configuration, original_copy, home
+        bits.skipBits(12);
+
         // adts_variable_header
 
         // copyright_identification_bit, copyright_identification_start
@@ -996,7 +1317,7 @@
 
     }
 
-    if (timeUs == 0ll) {
+    if (timeUs == 0LL) {
         ALOGV("Returning 0 timestamp");
     }
 
@@ -1004,27 +1325,6 @@
 }
 
 sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitH264() {
-    if (isScrambled()) {
-        if (mBuffer == NULL || mBuffer->size() == 0) {
-            return NULL;
-        }
-        if (mFormat == NULL) {
-            mFormat = new MetaData;
-            if (!MakeAVCCodecSpecificData(*mFormat, mBuffer->data(), mBuffer->size())) {
-                ALOGW("Creating dummy AVC format for scrambled content");
-                mFormat = new MetaData;
-                mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
-                mFormat->setInt32(kKeyWidth, 1280);
-                mFormat->setInt32(kKeyHeight, 720);
-            }
-            // for MediaExtractor.CasInfo
-            mFormat->setInt32(kKeyCASystemID, mCASystemId);
-            mFormat->setData(kKeyCASessionID, 0,
-                    mCasSessionId.data(), mCasSessionId.size());
-        }
-        return dequeueScrambledAccessUnit();
-    }
-
     const uint8_t *data = mBuffer->data();
 
     size_t size = mBuffer->size();
@@ -1166,7 +1466,7 @@
             mBuffer->setRange(0, mBuffer->size() - nextScan);
 
             int64_t timeUs = fetchTimestamp(nextScan);
-            if (timeUs < 0ll) {
+            if (timeUs < 0LL) {
                 ALOGE("Negative timeUs");
                 return NULL;
             }
@@ -1232,6 +1532,7 @@
                 header, &frameSize, &samplingRate, &numChannels,
                 &bitrate, &numSamples)) {
         ALOGE("Failed to get audio frame size");
+        mBuffer->setRange(0, 0);
         return NULL;
     }
 
@@ -1251,11 +1552,27 @@
     mBuffer->setRange(0, mBuffer->size() - frameSize);
 
     int64_t timeUs = fetchTimestamp(frameSize);
-    if (timeUs < 0ll) {
+    if (timeUs < 0LL) {
         ALOGE("Negative timeUs");
         return NULL;
     }
 
+    if (mFormat != NULL) {
+        const char *mime;
+        if (mFormat->findCString(kKeyMIMEType, &mime)) {
+            if ((layer == 1) && strcmp (mime, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I)) {
+                ALOGE("Audio layer is not MPEG_LAYER_I");
+                return NULL;
+            } else if ((layer == 2) && strcmp (mime, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II)) {
+                ALOGE("Audio layer is not MPEG_LAYER_II");
+                return NULL;
+            } else if ((layer == 3) && strcmp (mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
+                ALOGE("Audio layer is not AUDIO_MPEG");
+                return NULL;
+            }
+        }
+    }
+
     accessUnit->meta()->setInt64("timeUs", timeUs);
     accessUnit->meta()->setInt32("isSync", 1);
 
@@ -1330,25 +1647,6 @@
 }
 
 sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGVideo() {
-    if (isScrambled()) {
-        if (mBuffer == NULL || mBuffer->size() == 0) {
-            return NULL;
-        }
-        if (mFormat == NULL) {
-            ALOGI("Creating dummy MPEG format for scrambled content");
-            mFormat = new MetaData;
-            mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2);
-            mFormat->setInt32(kKeyWidth, 1280);
-            mFormat->setInt32(kKeyHeight, 720);
-
-            // for MediaExtractor.CasInfo
-            mFormat->setInt32(kKeyCASystemID, mCASystemId);
-            mFormat->setData(kKeyCASessionID, 0,
-                    mCasSessionId.data(), mCasSessionId.size());
-        }
-        return dequeueScrambledAccessUnit();
-    }
-
     const uint8_t *data = mBuffer->data();
     size_t size = mBuffer->size();
 
@@ -1457,7 +1755,7 @@
                 mBuffer->setRange(0, mBuffer->size() - offset);
 
                 int64_t timeUs = fetchTimestamp(offset);
-                if (timeUs < 0ll) {
+                if (timeUs < 0LL) {
                     ALOGE("Negative timeUs");
                     return NULL;
                 }
@@ -1654,7 +1952,7 @@
                     mBuffer->setRange(0, size);
 
                     int64_t timeUs = fetchTimestamp(offset);
-                    if (timeUs < 0ll) {
+                    if (timeUs < 0LL) {
                         ALOGE("Negative timeus");
                         return NULL;
                     }
diff --git a/media/libstagefright/mpeg2ts/ESQueue.h b/media/libstagefright/mpeg2ts/ESQueue.h
index ffcb502..3227f47 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.h
+++ b/media/libstagefright/mpeg2ts/ESQueue.h
@@ -38,6 +38,8 @@
         H264,
         AAC,
         AC3,
+        EAC3,
+        AC4,
         MPEG_AUDIO,
         MPEG_VIDEO,
         MPEG4_VIDEO,
@@ -59,6 +61,7 @@
 
     void appendScrambledData(
             const void *data, size_t size,
+            size_t leadingClearBytes,
             int32_t keyId, bool isSync,
             sp<ABuffer> clearSizes, sp<ABuffer> encSizes);
 
@@ -84,8 +87,8 @@
     };
 
     struct ScrambledRangeInfo {
-        //int64_t mTimestampUs;
         size_t mLength;
+        size_t mLeadingClearBytes;
         int32_t mKeyId;
         int32_t mIsSync;
         sp<ABuffer> mClearSizes;
@@ -115,7 +118,8 @@
 
     sp<ABuffer> dequeueAccessUnitH264();
     sp<ABuffer> dequeueAccessUnitAAC();
-    sp<ABuffer> dequeueAccessUnitAC3();
+    sp<ABuffer> dequeueAccessUnitEAC3();
+    sp<ABuffer> dequeueAccessUnitAC4();
     sp<ABuffer> dequeueAccessUnitMPEGAudio();
     sp<ABuffer> dequeueAccessUnitMPEGVideo();
     sp<ABuffer> dequeueAccessUnitMPEG4Video();
diff --git a/media/libstagefright/mpeg2ts/HlsSampleDecryptor.cpp b/media/libstagefright/mpeg2ts/HlsSampleDecryptor.cpp
index e32f676..7d446ab 100644
--- a/media/libstagefright/mpeg2ts/HlsSampleDecryptor.cpp
+++ b/media/libstagefright/mpeg2ts/HlsSampleDecryptor.cpp
@@ -149,6 +149,11 @@
     }
 
     // ADTS header is included in the size
+    if (size < adtsHdrSize) {
+        ALOGV("processAAC: size (%zu) < adtsHdrSize (%zu)", size, adtsHdrSize);
+        android_errorWriteLog(0x534e4554, "128433933");
+        return;
+    }
     size_t offset = adtsHdrSize;
     size_t remainingBytes = size - adtsHdrSize;
 
diff --git a/media/libstagefright/omx/1.0/Omx.cpp b/media/libstagefright/omx/1.0/Omx.cpp
index 4e2d398..eef9ce3 100644
--- a/media/libstagefright/omx/1.0/Omx.cpp
+++ b/media/libstagefright/omx/1.0/Omx.cpp
@@ -18,7 +18,6 @@
 #include <list>
 
 #include <android-base/logging.h>
-#include <gui/IGraphicBufferProducer.h>
 #include <media/openmax/OMX_Core.h>
 #include <media/openmax/OMX_AsString.h>
 
@@ -28,7 +27,6 @@
 
 #include <media/stagefright/omx/1.0/WOmxNode.h>
 #include <media/stagefright/omx/1.0/WOmxObserver.h>
-#include <media/stagefright/omx/1.0/WGraphicBufferProducer.h>
 #include <media/stagefright/omx/1.0/WGraphicBufferSource.h>
 #include <media/stagefright/omx/1.0/Conversion.h>
 #include <media/stagefright/omx/1.0/Omx.h>
@@ -45,6 +43,8 @@
 Omx::Omx() :
     mMaster(new OMXMaster()),
     mParser() {
+    (void)mParser.parseXmlFilesInSearchDirs();
+    (void)mParser.parseXmlPath(mParser.defaultProfilingResultsXmlPath);
 }
 
 Omx::~Omx() {
@@ -124,11 +124,11 @@
         } else {
             uint32_t quirks = 0;
             for (const auto& quirk : codec->second.quirkSet) {
-                if (quirk == "requires-allocate-on-input-ports") {
+                if (quirk == "quirk::requires-allocate-on-input-ports") {
                     quirks |= OMXNodeInstance::
                             kRequiresAllocateBufferOnInputPorts;
                 }
-                if (quirk == "requires-allocate-on-output-ports") {
+                if (quirk == "quirk::requires-allocate-on-output-ports") {
                     quirks |= OMXNodeInstance::
                             kRequiresAllocateBufferOnOutputPorts;
                 }
@@ -146,8 +146,6 @@
 }
 
 Return<void> Omx::createInputSurface(createInputSurface_cb _hidl_cb) {
-    sp<::android::IGraphicBufferProducer> bufferProducer;
-
     sp<OmxGraphicBufferSource> graphicBufferSource = new OmxGraphicBufferSource();
     status_t err = graphicBufferSource->initCheck();
     if (err != OK) {
@@ -157,10 +155,9 @@
         _hidl_cb(toStatus(err), nullptr, nullptr);
         return Void();
     }
-    bufferProducer = graphicBufferSource->getIGraphicBufferProducer();
 
     _hidl_cb(toStatus(OK),
-            new TWGraphicBufferProducer(bufferProducer),
+            graphicBufferSource->getHGraphicBufferProducer_V1_0(),
             new TWGraphicBufferSource(graphicBufferSource));
     return Void();
 }
diff --git a/media/libstagefright/omx/1.0/OmxStore.cpp b/media/libstagefright/omx/1.0/OmxStore.cpp
index 447af6f..67f478e 100644
--- a/media/libstagefright/omx/1.0/OmxStore.cpp
+++ b/media/libstagefright/omx/1.0/OmxStore.cpp
@@ -17,6 +17,8 @@
 #include <ios>
 #include <list>
 
+#define LOG_TAG "OmxStore"
+
 #include <android-base/logging.h>
 
 #include <media/stagefright/omx/1.0/Conversion.h>
@@ -30,16 +32,33 @@
 namespace V1_0 {
 namespace implementation {
 
+using ::android::hardware::media::omx::V1_0::Status;
+using ::android::hardware::media::omx::V1_0::IOmx;
+
 OmxStore::OmxStore(
+        const sp<IOmx> &omx,
         const char* owner,
-        const char* const* searchDirs,
-        const char* mainXmlName,
-        const char* performanceXmlName,
+        const std::vector<std::string> &searchDirs,
+        const std::vector<std::string> &xmlNames,
         const char* profilingResultsXmlPath) {
-    MediaCodecsXmlParser parser(searchDirs,
-            mainXmlName,
-            performanceXmlName,
-            profilingResultsXmlPath);
+    // retrieve list of omx nodes
+    std::set<std::string> nodes;
+    if (omx != nullptr) {
+        omx->listNodes([&nodes](const Status &status,
+                                const hidl_vec<IOmx::ComponentInfo> &nodeList) {
+            if (status == Status::OK) {
+                for (const IOmx::ComponentInfo& info : nodeList) {
+                    nodes.emplace(info.mName.c_str());
+                }
+            }
+        });
+    }
+
+    MediaCodecsXmlParser parser;
+    parser.parseXmlFilesInSearchDirs(xmlNames, searchDirs);
+    if (profilingResultsXmlPath != nullptr) {
+        parser.parseXmlPath(profilingResultsXmlPath);
+    }
     mParsingStatus = toStatus(parser.getParsingStatus());
 
     const auto& serviceAttributeMap = parser.getServiceAttributeMap();
@@ -61,14 +80,18 @@
         role.role = rolePair.first;
         role.type = rolePair.second.type;
         role.isEncoder = rolePair.second.isEncoder;
-        // TODO: Currently, preferPlatformNodes information is not available in
-        // the xml file. Once we have a way to provide this information, it
-        // should be parsed properly.
-        role.preferPlatformNodes = rolePair.first.compare(0, 5, "audio") == 0;
+        role.preferPlatformNodes = false; // deprecated and ignored, using rank instead
         hidl_vec<NodeInfo>& nodeList = role.nodes;
         nodeList.resize(rolePair.second.nodeList.size());
         size_t j = 0;
         for (const auto& nodePair : rolePair.second.nodeList) {
+            if (!nodes.count(nodePair.second.name)) {
+                // not supported by this OMX instance
+                if (!strncasecmp(nodePair.second.name.c_str(), "omx.", 4)) {
+                    LOG(INFO) << "node [" << nodePair.second.name.c_str() << "] not found in IOmx";
+                }
+                continue;
+            }
             NodeInfo node;
             node.name = nodePair.second.name;
             node.owner = owner;
@@ -85,6 +108,7 @@
             nodeList[j] = std::move(node);
             ++j;
         }
+        nodeList.resize(j);
         mRoleList[i] = std::move(role);
         ++i;
     }
diff --git a/media/libstagefright/omx/Android.bp b/media/libstagefright/omx/Android.bp
index 3e6942b..7d03d98 100644
--- a/media/libstagefright/omx/Android.bp
+++ b/media/libstagefright/omx/Android.bp
@@ -6,16 +6,10 @@
     },
 
     srcs: [
-        "BWGraphicBufferSource.cpp",
         "OMXMaster.cpp",
         "OMXNodeInstance.cpp",
         "OMXUtils.cpp",
         "OmxGraphicBufferSource.cpp",
-        "SimpleSoftOMXComponent.cpp",
-        "SoftOMXComponent.cpp",
-        "SoftOMXPlugin.cpp",
-        "SoftVideoDecoderOMXComponent.cpp",
-        "SoftVideoEncoderOMXComponent.cpp",
         "1.0/Omx.cpp",
         "1.0/OmxStore.cpp",
         "1.0/WGraphicBufferSource.cpp",
@@ -29,6 +23,7 @@
     ],
 
     header_libs: [
+        "libbase_headers",
         "media_plugin_headers",
     ],
 
@@ -43,7 +38,6 @@
         "libutils",
         "liblog",
         "libui",
-        "libgui",
         "libcutils",
         "libstagefright_foundation",
         "libstagefright_bufferqueue_helper",
@@ -52,14 +46,12 @@
         "libhidlbase",
         "libhidlmemory",
         "libhidltransport",
-        "libnativewindow", // TODO(b/62923479): use header library
         "libvndksupport",
         "android.hardware.media.omx@1.0",
         "android.hardware.graphics.bufferqueue@1.0",
     ],
 
     export_shared_lib_headers: [
-        "libmedia_omx",
         "libstagefright_foundation",
         "libstagefright_xmlparser",
         "libutils",
@@ -78,10 +70,127 @@
             "unsigned-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
+
+}
+
+cc_library_shared {
+    name: "libstagefright_softomx",
+    vendor_available: true,
+
+    srcs: [
+        "SimpleSoftOMXComponent.cpp",
+        "SoftOMXComponent.cpp",
+        "SoftVideoDecoderOMXComponent.cpp",
+        "SoftVideoEncoderOMXComponent.cpp",
+    ],
+
+    export_include_dirs: [
+        "include",
+    ],
+
+    header_libs: [
+        "media_plugin_headers",
+    ],
+
+    export_header_lib_headers: [
+        "media_plugin_headers",
+    ],
+
+    shared_libs: [
+        "libstagefright_foundation",
+        "liblog",
+        "libui",
+        "libutils",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+        "-Wno-unused-parameter",
+        "-Wno-documentation",
+    ],
+
+    sanitize: {
+        misc_undefined: [
+            "signed-integer-overflow",
+            "unsigned-integer-overflow",
+        ],
+        cfi: true,
+    },
+}
+
+cc_library_shared {
+    name: "libstagefright_softomx_plugin",
+    vendor_available: true,
+
+    srcs: [
+        "SoftOMXPlugin.cpp",
+    ],
+
+    export_include_dirs: [
+        "include",
+    ],
+
+    header_libs: [
+        "media_plugin_headers",
+    ],
+
+    export_header_lib_headers: [
+        "media_plugin_headers",
+    ],
+
+    shared_libs: [
+        "libstagefright_softomx",
+        "libstagefright_foundation",
+        "liblog",
+        "libutils",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+        "-Wno-unused-parameter",
+        "-Wno-documentation",
+    ],
+
+    sanitize: {
+        misc_undefined: [
+            "signed-integer-overflow",
+            "unsigned-integer-overflow",
+        ],
+        cfi: true,
+    },
+}
+
+cc_defaults {
+    name: "libstagefright_softomx-defaults",
+    vendor_available: true,
+
+    cflags: [
+        "-Werror",
+    ],
+
+    header_libs: [
+        "media_plugin_headers"
+    ],
+
+    shared_libs: [
+        "libstagefright_softomx",
+        "libstagefright_foundation",
+        "libutils",
+        "liblog",
+    ],
+
+    sanitize: {
+        misc_undefined: [
+            "signed-integer-overflow",
+            "unsigned-integer-overflow",
+        ],
+        cfi: true,
+    },
+
+    compile_multilib: "32",
 }
 
 cc_library_shared {
@@ -90,6 +199,7 @@
     vndk: {
         enabled: true,
     },
+    double_loadable: true,
     srcs: ["OMXUtils.cpp"],
     export_include_dirs: [
         "include",
@@ -114,13 +224,7 @@
             "unsigned-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
     cflags: ["-Wall", "-Werror"],
 }
 
-//###############################################################################
-
-subdirs = ["tests"]
diff --git a/media/libstagefright/omx/BWGraphicBufferSource.cpp b/media/libstagefright/omx/BWGraphicBufferSource.cpp
deleted file mode 100644
index fa30a46..0000000
--- a/media/libstagefright/omx/BWGraphicBufferSource.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "BWGraphicBufferSource"
-
-#include <media/stagefright/omx/BWGraphicBufferSource.h>
-#include <media/stagefright/omx/OMXUtils.h>
-#include <media/openmax/OMX_Component.h>
-#include <media/openmax/OMX_IndexExt.h>
-#include <media/OMXBuffer.h>
-#include <media/IOMX.h>
-
-namespace android {
-
-static const OMX_U32 kPortIndexInput = 0;
-
-struct BWGraphicBufferSource::BWOmxNodeWrapper : public IOmxNodeWrapper {
-    sp<IOMXNode> mOMXNode;
-
-    BWOmxNodeWrapper(const sp<IOMXNode> &omxNode): mOMXNode(omxNode) {
-    }
-
-    virtual status_t emptyBuffer(
-            int32_t bufferId, uint32_t flags,
-            const sp<GraphicBuffer> &buffer,
-            int64_t timestamp, int fenceFd) override {
-        return mOMXNode->emptyBuffer(bufferId, buffer, flags, timestamp, fenceFd);
-    }
-
-    virtual void dispatchDataSpaceChanged(
-            int32_t dataSpace, int32_t aspects, int32_t pixelFormat) override {
-        omx_message msg;
-        msg.type = omx_message::EVENT;
-        msg.fenceFd = -1;
-        msg.u.event_data.event = OMX_EventDataSpaceChanged;
-        msg.u.event_data.data1 = dataSpace;
-        msg.u.event_data.data2 = aspects;
-        msg.u.event_data.data3 = pixelFormat;
-        mOMXNode->dispatchMessage(msg);
-    }
-};
-
-struct BWGraphicBufferSource::BWOMXBufferSource : public BnOMXBufferSource {
-    sp<OmxGraphicBufferSource> mSource;
-
-    BWOMXBufferSource(const sp<OmxGraphicBufferSource> &source): mSource(source) {
-    }
-
-    Status onOmxExecuting() override {
-        return mSource->onOmxExecuting();
-    }
-
-    Status onOmxIdle() override {
-        return mSource->onOmxIdle();
-    }
-
-    Status onOmxLoaded() override {
-        return mSource->onOmxLoaded();
-    }
-
-    Status onInputBufferAdded(int bufferId) override {
-        return mSource->onInputBufferAdded(bufferId);
-    }
-
-    Status onInputBufferEmptied(
-            int bufferId, const OMXFenceParcelable& fenceParcel) override {
-        return mSource->onInputBufferEmptied(bufferId, fenceParcel.get());
-    }
-};
-
-BWGraphicBufferSource::BWGraphicBufferSource(
-        sp<OmxGraphicBufferSource> const& base) :
-    mBase(base),
-    mOMXBufferSource(new BWOMXBufferSource(base)) {
-}
-
-::android::binder::Status BWGraphicBufferSource::configure(
-        const sp<IOMXNode>& omxNode, int32_t dataSpace) {
-    // Do setInputSurface() first, the node will try to enable metadata
-    // mode on input, and does necessary error checking. If this fails,
-    // we can't use this input surface on the node.
-    status_t err = omxNode->setInputSurface(mOMXBufferSource);
-    if (err != NO_ERROR) {
-        ALOGE("Unable to set input surface: %d", err);
-        return Status::fromStatusT(err);
-    }
-
-    // use consumer usage bits queried from encoder, but always add
-    // HW_VIDEO_ENCODER for backward compatibility.
-    uint32_t consumerUsage;
-    if (omxNode->getParameter(
-            (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
-            &consumerUsage, sizeof(consumerUsage)) != OK) {
-        consumerUsage = 0;
-    }
-
-    OMX_PARAM_PORTDEFINITIONTYPE def;
-    InitOMXParams(&def);
-    def.nPortIndex = kPortIndexInput;
-
-    err = omxNode->getParameter(
-            OMX_IndexParamPortDefinition, &def, sizeof(def));
-    if (err != NO_ERROR) {
-        ALOGE("Failed to get port definition: %d", err);
-        return Status::fromStatusT(UNKNOWN_ERROR);
-    }
-
-    return Status::fromStatusT(mBase->configure(
-              new BWOmxNodeWrapper(omxNode),
-              dataSpace,
-              def.nBufferCountActual,
-              def.format.video.nFrameWidth,
-              def.format.video.nFrameHeight,
-              consumerUsage));
-}
-
-::android::binder::Status BWGraphicBufferSource::setSuspend(
-        bool suspend, int64_t timeUs) {
-    return Status::fromStatusT(mBase->setSuspend(suspend, timeUs));
-}
-
-::android::binder::Status BWGraphicBufferSource::setRepeatPreviousFrameDelayUs(
-        int64_t repeatAfterUs) {
-    return Status::fromStatusT(mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs));
-}
-
-::android::binder::Status BWGraphicBufferSource::setMaxFps(float maxFps) {
-    return Status::fromStatusT(mBase->setMaxFps(maxFps));
-}
-
-::android::binder::Status BWGraphicBufferSource::setTimeLapseConfig(
-        double fps, double captureFps) {
-    return Status::fromStatusT(mBase->setTimeLapseConfig(
-            fps, captureFps));
-}
-
-::android::binder::Status BWGraphicBufferSource::setStartTimeUs(
-        int64_t startTimeUs) {
-    return Status::fromStatusT(mBase->setStartTimeUs(startTimeUs));
-}
-
-::android::binder::Status BWGraphicBufferSource::setStopTimeUs(
-        int64_t stopTimeUs) {
-    return Status::fromStatusT(mBase->setStopTimeUs(stopTimeUs));
-}
-
-::android::binder::Status BWGraphicBufferSource::getStopTimeOffsetUs(
-        int64_t *stopTimeOffsetUs) {
-    return Status::fromStatusT(mBase->getStopTimeOffsetUs(stopTimeOffsetUs));
-}
-
-::android::binder::Status BWGraphicBufferSource::setColorAspects(
-        int32_t aspects) {
-    return Status::fromStatusT(mBase->setColorAspects(aspects));
-}
-
-::android::binder::Status BWGraphicBufferSource::setTimeOffsetUs(
-        int64_t timeOffsetsUs) {
-    return Status::fromStatusT(mBase->setTimeOffsetUs(timeOffsetsUs));
-}
-
-::android::binder::Status BWGraphicBufferSource::signalEndOfInputStream() {
-    return Status::fromStatusT(mBase->signalEndOfInputStream());
-}
-
-}  // namespace android
diff --git a/media/libstagefright/omx/OMXMaster.cpp b/media/libstagefright/omx/OMXMaster.cpp
index 0967b5f..8c5ca6e 100644
--- a/media/libstagefright/omx/OMXMaster.cpp
+++ b/media/libstagefright/omx/OMXMaster.cpp
@@ -29,8 +29,7 @@
 
 namespace android {
 
-OMXMaster::OMXMaster()
-    : mVendorLibHandle(NULL) {
+OMXMaster::OMXMaster() {
 
     pid_t pid = getpid();
     char filename[20];
@@ -52,47 +51,52 @@
     }
 
     addVendorPlugin();
-    addPlugin(new SoftOMXPlugin);
+    addPlatformPlugin();
 }
 
 OMXMaster::~OMXMaster() {
     clearPlugins();
-
-    if (mVendorLibHandle != NULL) {
-        dlclose(mVendorLibHandle);
-        mVendorLibHandle = NULL;
-    }
 }
 
 void OMXMaster::addVendorPlugin() {
     addPlugin("libstagefrighthw.so");
 }
 
-void OMXMaster::addPlugin(const char *libname) {
-    mVendorLibHandle = android_load_sphal_library(libname, RTLD_NOW);
+void OMXMaster::addPlatformPlugin() {
+    addPlugin("libstagefright_softomx_plugin.so");
+}
 
-    if (mVendorLibHandle == NULL) {
+void OMXMaster::addPlugin(const char *libname) {
+    void *libHandle = android_load_sphal_library(libname, RTLD_NOW);
+
+    if (libHandle == NULL) {
         return;
     }
 
     typedef OMXPluginBase *(*CreateOMXPluginFunc)();
     CreateOMXPluginFunc createOMXPlugin =
         (CreateOMXPluginFunc)dlsym(
-                mVendorLibHandle, "createOMXPlugin");
+                libHandle, "createOMXPlugin");
     if (!createOMXPlugin)
         createOMXPlugin = (CreateOMXPluginFunc)dlsym(
-                mVendorLibHandle, "_ZN7android15createOMXPluginEv");
+                libHandle, "_ZN7android15createOMXPluginEv");
 
+    OMXPluginBase *plugin = nullptr;
     if (createOMXPlugin) {
-        addPlugin((*createOMXPlugin)());
+        plugin = (*createOMXPlugin)();
+    }
+
+    if (plugin) {
+        mPlugins.push_back({ plugin, libHandle });
+        addPlugin(plugin);
+    } else {
+        android_unload_sphal_library(libHandle);
     }
 }
 
 void OMXMaster::addPlugin(OMXPluginBase *plugin) {
     Mutex::Autolock autoLock(mLock);
 
-    mPlugins.push_back(plugin);
-
     OMX_U32 index = 0;
 
     char name[128];
@@ -120,20 +124,20 @@
 void OMXMaster::clearPlugins() {
     Mutex::Autolock autoLock(mLock);
 
-    typedef void (*DestroyOMXPluginFunc)(OMXPluginBase*);
-    DestroyOMXPluginFunc destroyOMXPlugin =
-        (DestroyOMXPluginFunc)dlsym(
-                mVendorLibHandle, "destroyOMXPlugin");
-
     mPluginByComponentName.clear();
+    mPluginByInstance.clear();
 
-    for (List<OMXPluginBase *>::iterator it = mPlugins.begin();
-            it != mPlugins.end(); ++it) {
+    typedef void (*DestroyOMXPluginFunc)(OMXPluginBase*);
+    for (const Plugin &plugin : mPlugins) {
+        DestroyOMXPluginFunc destroyOMXPlugin =
+            (DestroyOMXPluginFunc)dlsym(
+                    plugin.mLibHandle, "destroyOMXPlugin");
         if (destroyOMXPlugin)
-            destroyOMXPlugin(*it);
+            destroyOMXPlugin(plugin.mOmx);
         else
-            delete *it;
-        *it = NULL;
+            delete plugin.mOmx;
+
+        android_unload_sphal_library(plugin.mLibHandle);
     }
 
     mPlugins.clear();
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 32113c2..ddb4ba0 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -16,6 +16,7 @@
 
 //#define LOG_NDEBUG 0
 #define LOG_TAG "OMXNodeInstance"
+#include <android-base/macros.h>
 #include <utils/Log.h>
 
 #include <inttypes.h>
@@ -32,12 +33,13 @@
 
 #include <binder/IMemory.h>
 #include <cutils/properties.h>
-#include <gui/BufferQueue.h>
 #include <media/hardware/HardwareAPI.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ColorUtils.h>
 #include <media/stagefright/MediaErrors.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/Fence.h>
 #include <utils/misc.h>
 #include <utils/NativeHandle.h>
 #include <media/OMXBuffer.h>
@@ -354,9 +356,9 @@
       mQuirks(0),
       mBufferIDCount(0),
       mRestorePtsFailed(false),
-      mMaxTimestampGapUs(0ll),
-      mPrevOriginalTimeUs(-1ll),
-      mPrevModifiedTimeUs(-1ll)
+      mMaxTimestampGapUs(0LL),
+      mPrevOriginalTimeUs(-1LL),
+      mPrevModifiedTimeUs(-1LL)
 {
     mName = ADebug::GetDebugName(name);
     DEBUG = ADebug::GetDebugLevelFromProperty(name, "debug.stagefright.omx-debug");
@@ -459,7 +461,7 @@
                 break;
             }
 
-            // fall through
+            FALLTHROUGH_INTENDED;
         }
 
         case OMX_StateIdle:
@@ -486,7 +488,7 @@
             }
             CHECK_EQ(err, OMX_ErrorNone);
 
-            // fall through
+            FALLTHROUGH_INTENDED;
         }
 
         case OMX_StateLoaded:
@@ -535,6 +537,9 @@
     }
 
     Mutex::Autolock autoLock(mLock);
+    if (mHandle == NULL) {
+        return DEAD_OBJECT;
+    }
 
     if (cmd == OMX_CommandStateSet) {
         // There are no configurations past first StateSet command.
@@ -599,6 +604,9 @@
 status_t OMXNodeInstance::getParameter(
         OMX_INDEXTYPE index, void *params, size_t /* size */) {
     Mutex::Autolock autoLock(mLock);
+    if (mHandle == NULL) {
+        return DEAD_OBJECT;
+    }
 
     if (isProhibitedIndex_l(index)) {
         android_errorWriteLog(0x534e4554, "29422020");
@@ -617,6 +625,10 @@
 status_t OMXNodeInstance::setParameter(
         OMX_INDEXTYPE index, const void *params, size_t size) {
     Mutex::Autolock autoLock(mLock);
+    if (mHandle == NULL) {
+        return DEAD_OBJECT;
+    }
+
     OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index;
     CLOG_CONFIG(setParameter, "%s(%#x), %zu@%p)", asString(extIndex), index, size, params);
 
@@ -638,6 +650,9 @@
 status_t OMXNodeInstance::getConfig(
         OMX_INDEXTYPE index, void *params, size_t /* size */) {
     Mutex::Autolock autoLock(mLock);
+    if (mHandle == NULL) {
+        return DEAD_OBJECT;
+    }
 
     if (isProhibitedIndex_l(index)) {
         android_errorWriteLog(0x534e4554, "29422020");
@@ -656,6 +671,10 @@
 status_t OMXNodeInstance::setConfig(
         OMX_INDEXTYPE index, const void *params, size_t size) {
     Mutex::Autolock autoLock(mLock);
+    if (mHandle == NULL) {
+        return DEAD_OBJECT;
+    }
+
     OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index;
     CLOG_CONFIG(setConfig, "%s(%#x), %zu@%p)", asString(extIndex), index, size, params);
 
@@ -672,6 +691,9 @@
 
 status_t OMXNodeInstance::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
     Mutex::Autolock autoLock(mLock);
+    if (mHandle == NULL) {
+        return DEAD_OBJECT;
+    }
 
     if (portIndex >= NELEM(mPortMode)) {
         ALOGE("b/31385713, portIndex(%u)", portIndex);
@@ -854,6 +876,9 @@
 status_t OMXNodeInstance::getGraphicBufferUsage(
         OMX_U32 portIndex, OMX_U32* usage) {
     Mutex::Autolock autoLock(mLock);
+    if (mHandle == NULL) {
+        return DEAD_OBJECT;
+    }
 
     OMX_INDEXTYPE index;
     OMX_STRING name = const_cast<OMX_STRING>(
@@ -967,6 +992,10 @@
         OMX_U32 portIndex, OMX_BOOL enable, OMX_U32 maxFrameWidth,
         OMX_U32 maxFrameHeight) {
     Mutex::Autolock autolock(mLock);
+    if (mHandle == NULL) {
+        return DEAD_OBJECT;
+    }
+
     if (mSailed) {
         android_errorWriteLog(0x534e4554, "29422020");
         return INVALID_OPERATION;
@@ -1007,6 +1036,10 @@
         OMX_U32 portIndex, OMX_BOOL tunneled, OMX_U32 audioHwSync,
         native_handle_t **sidebandHandle) {
     Mutex::Autolock autolock(mLock);
+    if (mHandle == NULL) {
+        return DEAD_OBJECT;
+    }
+
     if (mSailed) {
         android_errorWriteLog(0x534e4554, "29422020");
         return INVALID_OPERATION;
@@ -1061,6 +1094,10 @@
     }
 
     Mutex::Autolock autoLock(mLock);
+    if (mHandle == NULL) {
+        return DEAD_OBJECT;
+    }
+
     if (!mSailed) {
         ALOGE("b/35467458");
         android_errorWriteLog(0x534e4554, "35467458");
@@ -1477,6 +1514,9 @@
 status_t OMXNodeInstance::setInputSurface(
         const sp<IOMXBufferSource> &bufferSource) {
     Mutex::Autolock autolock(mLock);
+    if (mHandle == NULL) {
+        return DEAD_OBJECT;
+    }
 
     status_t err;
 
@@ -1543,6 +1583,9 @@
     }
 
     Mutex::Autolock autoLock(mLock);
+    if (mHandle == NULL) {
+        return DEAD_OBJECT;
+    }
 
     if (!mSailed) {
         ALOGE("b/35467458");
@@ -1599,6 +1642,10 @@
 status_t OMXNodeInstance::freeBuffer(
         OMX_U32 portIndex, IOMX::buffer_id buffer) {
     Mutex::Autolock autoLock(mLock);
+    if (mHandle == NULL) {
+        return DEAD_OBJECT;
+    }
+
     CLOG_BUFFER(freeBuffer, "%s:%u %#x", portString(portIndex), portIndex, buffer);
 
     removeActiveBuffer(portIndex, buffer);
@@ -1626,6 +1673,9 @@
 status_t OMXNodeInstance::fillBuffer(
         IOMX::buffer_id buffer, const OMXBuffer &omxBuffer, int fenceFd) {
     Mutex::Autolock autoLock(mLock);
+    if (mHandle == NULL) {
+        return DEAD_OBJECT;
+    }
 
     OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, kPortIndexOutput);
     if (header == NULL) {
@@ -1676,6 +1726,9 @@
         buffer_id buffer, const OMXBuffer &omxBuffer,
         OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
     Mutex::Autolock autoLock(mLock);
+    if (mHandle == NULL) {
+        return DEAD_OBJECT;
+    }
 
     switch (omxBuffer.mBufferType) {
     case OMXBuffer::kBufferTypePreset:
@@ -1896,7 +1949,7 @@
 int64_t OMXNodeInstance::getCodecTimestamp(OMX_TICKS timestamp) {
     int64_t originalTimeUs = timestamp;
 
-    if (mMaxTimestampGapUs > 0ll) {
+    if (mMaxTimestampGapUs > 0LL) {
         /* Cap timestamp gap between adjacent frames to specified max
          *
          * In the scenario of cast mirroring, encoding could be suspended for
@@ -1904,7 +1957,7 @@
          * where encoder's rate control logic produces huge frames after a
          * long period of suspension.
          */
-        if (mPrevOriginalTimeUs >= 0ll) {
+        if (mPrevOriginalTimeUs >= 0LL) {
             int64_t timestampGapUs = originalTimeUs - mPrevOriginalTimeUs;
             timestamp = (timestampGapUs < mMaxTimestampGapUs ?
                 timestampGapUs : mMaxTimestampGapUs) + mPrevModifiedTimeUs;
@@ -1912,7 +1965,7 @@
         ALOGV("IN  timestamp: %lld -> %lld",
             static_cast<long long>(originalTimeUs),
             static_cast<long long>(timestamp));
-    } else if (mMaxTimestampGapUs < 0ll) {
+    } else if (mMaxTimestampGapUs < 0LL) {
         /*
          * Apply a fixed timestamp gap between adjacent frames.
          *
@@ -1920,7 +1973,7 @@
          * on frames could go forward or backward. Some encoders may silently
          * drop frames when it goes backward (or even stay unchanged).
          */
-        if (mPrevOriginalTimeUs >= 0ll) {
+        if (mPrevOriginalTimeUs >= 0LL) {
             timestamp = mPrevModifiedTimeUs - mMaxTimestampGapUs;
         }
         ALOGV("IN  timestamp: %lld -> %lld",
@@ -1931,7 +1984,7 @@
     mPrevOriginalTimeUs = originalTimeUs;
     mPrevModifiedTimeUs = timestamp;
 
-    if (mMaxTimestampGapUs != 0ll && !mRestorePtsFailed) {
+    if (mMaxTimestampGapUs != 0LL && !mRestorePtsFailed) {
         mOriginalTimeUs.add(timestamp, originalTimeUs);
     }
 
@@ -1964,7 +2017,7 @@
 void OMXNodeInstance::codecBufferFilled(omx_message &msg) {
     Mutex::Autolock autoLock(mLock);
 
-    if (mMaxTimestampGapUs == 0ll || mRestorePtsFailed) {
+    if (mMaxTimestampGapUs == 0LL || mRestorePtsFailed) {
         return;
     }
 
@@ -1990,6 +2043,9 @@
 status_t OMXNodeInstance::getExtensionIndex(
         const char *parameterName, OMX_INDEXTYPE *index) {
     Mutex::Autolock autoLock(mLock);
+    if (mHandle == NULL) {
+        return DEAD_OBJECT;
+    }
 
     OMX_ERRORTYPE err = OMX_GetExtensionIndex(
             mHandle, const_cast<char *>(parameterName), index);
@@ -2196,8 +2252,8 @@
                     // bump internal-state debug level for 2 input and output frames
                     Mutex::Autolock _l(mDebugLock);
                     bumpDebugLevel_l(2 /* numInputBuffers */, 2 /* numOutputBuffers */);
+                    FALLTHROUGH_INTENDED;
                 }
-                // fall through
                 default:
                     arg2String = portString(arg2);
             }
@@ -2208,7 +2264,7 @@
             break;
         case OMX_EventPortSettingsChanged:
             arg2String = asString((OMX_INDEXEXTTYPE)arg2);
-            // fall through
+            FALLTHROUGH_INTENDED;
         default:
             arg1String = portString(arg1);
     }
diff --git a/media/libstagefright/omx/OMXUtils.cpp b/media/libstagefright/omx/OMXUtils.cpp
index f7b569d..1b8493a 100644
--- a/media/libstagefright/omx/OMXUtils.cpp
+++ b/media/libstagefright/omx/OMXUtils.cpp
@@ -19,6 +19,7 @@
 
 #include <string.h>
 
+#include <android-base/macros.h>
 #include <media/stagefright/omx/OMXUtils.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AUtils.h>
@@ -149,6 +150,8 @@
             "video_decoder.vp8", "video_encoder.vp8" },
         { MEDIA_MIMETYPE_VIDEO_VP9,
             "video_decoder.vp9", "video_encoder.vp9" },
+        { MEDIA_MIMETYPE_VIDEO_AV1,
+            "video_decoder.av1", "video_encoder.av1" },
         { MEDIA_MIMETYPE_AUDIO_RAW,
             "audio_decoder.raw", "audio_encoder.raw" },
         { MEDIA_MIMETYPE_VIDEO_DOLBY_VISION,
@@ -163,6 +166,10 @@
             "audio_decoder.ac3", "audio_encoder.ac3" },
         { MEDIA_MIMETYPE_AUDIO_EAC3,
             "audio_decoder.eac3", "audio_encoder.eac3" },
+        { MEDIA_MIMETYPE_AUDIO_EAC3_JOC,
+            "audio_decoder.eac3_joc", "audio_encoder.eac3_joc" },
+        { MEDIA_MIMETYPE_AUDIO_AC4,
+            "audio_decoder.ac4", "audio_encoder.ac4" },
         { MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC,
             "image_decoder.heic", "image_encoder.heic" },
     };
@@ -273,6 +280,7 @@
                 break;
             } else {
                 // fall through as YV12 is used for YUV420Planar by some codecs
+                FALLTHROUGH_INTENDED;
             }
 
         case OMX_COLOR_FormatYUV420Planar:
diff --git a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
index 55afe04..ddb459f 100644
--- a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
+++ b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
@@ -34,7 +34,8 @@
       mLooper(new ALooper),
       mHandler(new AHandlerReflector<SimpleSoftOMXComponent>(this)),
       mState(OMX_StateLoaded),
-      mTargetState(OMX_StateLoaded) {
+      mTargetState(OMX_StateLoaded),
+      mFrameConfig(false) {
     mLooper->setName(name);
     mLooper->registerHandler(mHandler);
 
@@ -204,6 +205,21 @@
     }
 }
 
+OMX_ERRORTYPE SimpleSoftOMXComponent::internalSetConfig(
+        OMX_INDEXTYPE index, const OMX_PTR params, bool *frameConfig) {
+    return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE SimpleSoftOMXComponent::setConfig(
+        OMX_INDEXTYPE index, const OMX_PTR params) {
+    bool frameConfig = mFrameConfig;
+    OMX_ERRORTYPE err = internalSetConfig(index, params, &frameConfig);
+    if (err == OMX_ErrorNone) {
+        mFrameConfig = frameConfig;
+    }
+    return err;
+}
+
 OMX_ERRORTYPE SimpleSoftOMXComponent::useBuffer(
         OMX_BUFFERHEADERTYPE **header,
         OMX_U32 portIndex,
@@ -336,6 +352,10 @@
         OMX_BUFFERHEADERTYPE *buffer) {
     sp<AMessage> msg = new AMessage(kWhatEmptyThisBuffer, mHandler);
     msg->setPointer("header", buffer);
+    if (mFrameConfig) {
+        msg->setInt32("frame-config", mFrameConfig);
+        mFrameConfig = false;
+    }
     msg->post();
 
     return OMX_ErrorNone;
@@ -378,6 +398,10 @@
         {
             OMX_BUFFERHEADERTYPE *header;
             CHECK(msg->findPointer("header", (void **)&header));
+            int32_t frameConfig;
+            if (!msg->findInt32("frame-config", &frameConfig)) {
+                frameConfig = 0;
+            }
 
             CHECK(mState == OMX_StateExecuting && mTargetState == mState);
 
@@ -393,6 +417,7 @@
                     CHECK(!buffer->mOwnedByUs);
 
                     buffer->mOwnedByUs = true;
+                    buffer->mFrameConfig = (bool)frameConfig;
 
                     CHECK((msgType == kWhatEmptyThisBuffer
                             && port->mDef.eDir == OMX_DirInput)
diff --git a/media/libstagefright/omx/SoftOMXPlugin.cpp b/media/libstagefright/omx/SoftOMXPlugin.cpp
index 1f3e8c1..a720bc9 100644
--- a/media/libstagefright/omx/SoftOMXPlugin.cpp
+++ b/media/libstagefright/omx/SoftOMXPlugin.cpp
@@ -71,6 +71,16 @@
 static const size_t kNumComponents =
     sizeof(kComponents) / sizeof(kComponents[0]);
 
+extern "C" OMXPluginBase* createOMXPlugin() {
+    ALOGI("createOMXPlugin");
+    return new SoftOMXPlugin();
+}
+
+extern "C" void destroyOMXPlugin(OMXPluginBase* plugin) {
+    ALOGI("destroyOMXPlugin");
+    delete plugin;
+}
+
 SoftOMXPlugin::SoftOMXPlugin() {
 }
 
diff --git a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
index 935dc34..e853da9 100644
--- a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
@@ -154,12 +154,12 @@
     outDef->format.video.nFrameWidth = outputBufferWidth();
     outDef->format.video.nFrameHeight = outputBufferHeight();
     outDef->format.video.eColorFormat = mOutputFormat;
-    outDef->format.video.nStride = outDef->format.video.nFrameWidth;
     outDef->format.video.nSliceHeight = outDef->format.video.nFrameHeight;
 
     int32_t bpp = (mOutputFormat == OMX_COLOR_FormatYUV420Planar16) ? 2 : 1;
+    outDef->format.video.nStride = outDef->format.video.nFrameWidth * bpp;
     outDef->nBufferSize =
-        (outDef->format.video.nStride * outDef->format.video.nSliceHeight * bpp * 3) / 2;
+            (outDef->format.video.nStride * outDef->format.video.nSliceHeight * 3) / 2;
 
     OMX_PARAM_PORTDEFINITIONTYPE *inDef = &editPortInfo(kInputPortIndex)->mDef;
     inDef->format.video.nFrameWidth = mWidth;
@@ -502,7 +502,8 @@
             // These values were chosen to prevent integer overflows further down the line, and do
             // not indicate support for 32kx32k video.
             if (newWidth > 32768 || newHeight > 32768
-                    || video_def->nStride > 32768 || video_def->nSliceHeight > 32768) {
+                    || video_def->nStride > 32768 || video_def->nStride < -32768
+                    || video_def->nSliceHeight > 32768) {
                 ALOGE("b/22885421");
                 return OMX_ErrorBadParameter;
             }
@@ -601,13 +602,40 @@
             return OMX_ErrorNone;
         }
 
+        case kDescribeHdr10PlusInfoIndex:
+        {
+            if (!supportDescribeHdr10PlusInfo()) {
+                return OMX_ErrorUnsupportedIndex;
+            }
+
+            if (mHdr10PlusOutputs.size() > 0) {
+                auto it = mHdr10PlusOutputs.begin();
+
+                auto info = (*it).get();
+
+                DescribeHDR10PlusInfoParams* outParams =
+                        (DescribeHDR10PlusInfoParams *)params;
+
+                outParams->nParamSizeUsed = info->size();
+
+                // If the buffer provided by the client does not have enough
+                // storage, return the size only and do not remove the param yet.
+                if (outParams->nParamSize >= info->size()) {
+                    memcpy(outParams->nValue, info->data(), info->size());
+                    mHdr10PlusOutputs.erase(it);
+                }
+                return OMX_ErrorNone;
+            }
+            return OMX_ErrorUnderflow;
+        }
+
         default:
             return OMX_ErrorUnsupportedIndex;
     }
 }
 
-OMX_ERRORTYPE SoftVideoDecoderOMXComponent::setConfig(
-        OMX_INDEXTYPE index, const OMX_PTR params){
+OMX_ERRORTYPE SoftVideoDecoderOMXComponent::internalSetConfig(
+        OMX_INDEXTYPE index, const OMX_PTR params, bool *frameConfig){
     switch ((int)index) {
         case kDescribeColorAspectsIndex:
         {
@@ -657,11 +685,55 @@
             return OMX_ErrorNone;
         }
 
+        case kDescribeHdr10PlusInfoIndex:
+        {
+            if (!supportDescribeHdr10PlusInfo()) {
+                return OMX_ErrorUnsupportedIndex;
+            }
+
+            const DescribeHDR10PlusInfoParams* inParams =
+                    (DescribeHDR10PlusInfoParams *)params;
+
+            if (*frameConfig) {
+                // This is a request to append to the current frame config set.
+                // For now, we only support kDescribeHdr10PlusInfoIndex, which
+                // we simply replace with the last set value.
+                if (mHdr10PlusInputs.size() > 0) {
+                    *(--mHdr10PlusInputs.end()) = ABuffer::CreateAsCopy(
+                            inParams->nValue, inParams->nParamSizeUsed);
+                } else {
+                    ALOGW("Ignoring kDescribeHdr10PlusInfoIndex: append to "
+                            "frame config while no frame config is present");
+                }
+            } else {
+                // This is a frame config, setting *frameConfig to true so that
+                // the client marks the next queued input frame to apply it.
+                *frameConfig = true;
+                mHdr10PlusInputs.push_back(ABuffer::CreateAsCopy(
+                        inParams->nValue, inParams->nParamSizeUsed));
+            }
+            return OMX_ErrorNone;
+        }
+
         default:
             return OMX_ErrorUnsupportedIndex;
     }
 }
 
+sp<ABuffer> SoftVideoDecoderOMXComponent::dequeueInputFrameConfig() {
+    auto it = mHdr10PlusInputs.begin();
+    sp<ABuffer> info = *it;
+    mHdr10PlusInputs.erase(it);
+    return info;
+}
+
+void SoftVideoDecoderOMXComponent::queueOutputFrameConfig(const sp<ABuffer> &info) {
+    mHdr10PlusOutputs.push_back(info);
+    notify(OMX_EventConfigUpdate,
+           kOutputPortIndex,
+           kDescribeHdr10PlusInfoIndex,
+           NULL);
+}
 
 OMX_ERRORTYPE SoftVideoDecoderOMXComponent::getExtensionIndex(
         const char *name, OMX_INDEXTYPE *index) {
@@ -676,6 +748,10 @@
             && supportDescribeHdrStaticInfo()) {
         *(int32_t*)index = kDescribeHdrStaticInfoIndex;
         return OMX_ErrorNone;
+    } else if (!strcmp(name, "OMX.google.android.index.describeHDR10PlusInfo")
+            && supportDescribeHdr10PlusInfo()) {
+        *(int32_t*)index = kDescribeHdr10PlusInfoIndex;
+        return OMX_ErrorNone;
     }
 
     return SimpleSoftOMXComponent::getExtensionIndex(name, index);
@@ -693,6 +769,10 @@
     return false;
 }
 
+bool SoftVideoDecoderOMXComponent::supportDescribeHdr10PlusInfo() {
+    return false;
+}
+
 void SoftVideoDecoderOMXComponent::onReset() {
     mOutputPortSettingsChange = NONE;
 }
diff --git a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
index 2fbbb44..d75acda 100644
--- a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
@@ -559,7 +559,7 @@
         if (nativeMeta.nFenceFd >= 0) {
             sp<Fence> fence = new Fence(nativeMeta.nFenceFd);
             nativeMeta.nFenceFd = -1;
-            status_t err = fence->wait(IOMX::kFenceTimeoutMs);
+            status_t err = fence->wait(kFenceTimeoutMs);
             if (err != OK) {
                 ALOGE("Timed out waiting on input fence");
                 return NULL;
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h b/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h
index a9fce55..9669677 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HARDWARE_MEDIA_OMX_V1_0__CONVERSION_H
-#define ANDROID_HARDWARE_MEDIA_OMX_V1_0__CONVERSION_H
+#ifndef ANDROID_HARDWARE_MEDIA_OMX_V1_0_IMPL_CONVERSION_H
+#define ANDROID_HARDWARE_MEDIA_OMX_V1_0_IMPL_CONVERSION_H
 
 #include <vector>
 #include <list>
@@ -29,15 +29,15 @@
 
 #include <binder/Binder.h>
 #include <binder/Status.h>
+#include <ui/BufferQueueDefs.h>
 #include <ui/FenceTime.h>
 #include <cutils/native_handle.h>
-#include <gui/IGraphicBufferProducer.h>
 
 #include <media/OMXFenceParcelable.h>
 #include <media/OMXBuffer.h>
+#include <media/omx/1.0/Conversion.h>
 #include <media/hardware/VideoAPI.h>
 #include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/bqhelper/Conversion.h>
 
 #include <android/hidl/memory/1.0/IMemory.h>
 #include <android/hardware/graphics/bufferqueue/1.0/IProducerListener.h>
@@ -99,16 +99,9 @@
 
 typedef ::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer
         HGraphicBufferProducer;
-typedef ::android::IGraphicBufferProducer
-        BGraphicBufferProducer;
 
-// We want to use all functions declared in ::android::conversion
-using namespace ::android::conversion;
-
-// Now specifically inject these two functions here, because we're going to
-// declare functions with the same name in this namespace.
-using ::android::conversion::convertTo;
-using ::android::conversion::toStatusT;
+// Use the conversion functions from libmedia_omx so that we don't need libgui
+using namespace ::android::hardware::media::omx::V1_0::utils;
 
 /**
  * Conversion functions
@@ -143,57 +136,6 @@
  */
 
 /**
- * \brief Convert `Status` to `status_t`. This is for legacy binder calls.
- *
- * \param[in] t The source `Status`.
- * \return the corresponding `status_t`.
- */
-// convert: Status -> status_t
-inline status_t toStatusT(Status const& t) {
-    switch (t) {
-    case Status::NO_ERROR:
-    case Status::NAME_NOT_FOUND:
-    case Status::WOULD_BLOCK:
-    case Status::NO_MEMORY:
-    case Status::ALREADY_EXISTS:
-    case Status::NO_INIT:
-    case Status::BAD_VALUE:
-    case Status::DEAD_OBJECT:
-    case Status::INVALID_OPERATION:
-    case Status::TIMED_OUT:
-    case Status::ERROR_UNSUPPORTED:
-    case Status::UNKNOWN_ERROR:
-    case Status::RELEASE_ALL_BUFFERS:
-        return static_cast<status_t>(t);
-    case Status::BUFFER_NEEDS_REALLOCATION:
-        return NOT_ENOUGH_DATA;
-    default:
-        ALOGW("Unrecognized status value: %" PRId32, static_cast<int32_t>(t));
-        return static_cast<status_t>(t);
-    }
-}
-
-/**
- * \brief Convert `Return<Status>` to `status_t`. This is for legacy binder
- * calls.
- *
- * \param[in] t The source `Return<Status>`.
- * \return The corresponding `status_t`.
- *
- * This function first check if \p t has a transport error. If it does, then the
- * return value is the transport error code. Otherwise, the return value is
- * converted from `Status` contained inside \p t.
- *
- * Note:
- * - This `Status` is omx-specific. It is defined in `types.hal`.
- * - The name of this function is not `convert`.
- */
-// convert: Status -> status_t
-inline status_t toStatusT(Return<Status> const& t) {
-    return t.isOk() ? toStatusT(static_cast<Status>(t)) : UNKNOWN_ERROR;
-}
-
-/**
  * \brief Convert `status_t` to `Status`.
  *
  * \param[in] l The source `status_t`.
@@ -214,8 +156,8 @@
     case TIMED_OUT:
     case ERROR_UNSUPPORTED:
     case UNKNOWN_ERROR:
-    case IGraphicBufferProducer::RELEASE_ALL_BUFFERS:
-    case IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION:
+    case BufferQueueDefs::RELEASE_ALL_BUFFERS:
+    case BufferQueueDefs::BUFFER_NEEDS_REALLOCATION:
         return static_cast<Status>(l);
     case NOT_ENOUGH_DATA:
         return Status::BUFFER_NEEDS_REALLOCATION;
@@ -567,7 +509,8 @@
             anwBuffer.nativeHandle = t.nativeHandle;
             anwBuffer.attr = t.attr.anwBuffer;
             sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
-            if (!convertTo(graphicBuffer.get(), anwBuffer)) {
+            if (!::android::hardware::media::omx::V1_0::utils::convertTo(
+                    graphicBuffer.get(), anwBuffer)) {
                 return false;
             }
             *l = OMXBuffer(graphicBuffer);
@@ -751,4 +694,4 @@
 }  // namespace hardware
 }  // namespace android
 
-#endif  // ANDROID_HARDWARE_MEDIA_OMX_V1_0__CONVERSION_H
+#endif  // ANDROID_HARDWARE_MEDIA_OMX_V1_0_IMPL_CONVERSION_H
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/1.0/OmxStore.h b/media/libstagefright/omx/include/media/stagefright/omx/1.0/OmxStore.h
index 006d2d9..15d46991 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/1.0/OmxStore.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/1.0/OmxStore.h
@@ -20,6 +20,7 @@
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
 
+#include <android/hardware/media/omx/1.0/IOmx.h>
 #include <android/hardware/media/omx/1.0/IOmxStore.h>
 #include <media/stagefright/xmlparser/MediaCodecsXmlParser.h>
 
@@ -43,15 +44,14 @@
 
 struct OmxStore : public IOmxStore {
     OmxStore(
+            const sp<IOmx> &omx = nullptr,
             const char* owner = "default",
-            const char* const* searchDirs
-                = MediaCodecsXmlParser::defaultSearchDirs,
-            const char* mainXmlName
-                = MediaCodecsXmlParser::defaultMainXmlName,
-            const char* performanceXmlName
-                = MediaCodecsXmlParser::defaultPerformanceXmlName,
-            const char* profilingResultsXmlPath
-                = MediaCodecsXmlParser::defaultProfilingResultsXmlPath);
+            const std::vector<std::string> &searchDirs =
+                MediaCodecsXmlParser::getDefaultSearchDirs(),
+            const std::vector<std::string> &xmlFiles =
+                MediaCodecsXmlParser::getDefaultXmlNames(),
+            const char *xmlProfilingResultsPath =
+                MediaCodecsXmlParser::defaultProfilingResultsXmlPath);
 
     virtual ~OmxStore();
 
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/1.0/WGraphicBufferProducer.h b/media/libstagefright/omx/include/media/stagefright/omx/1.0/WGraphicBufferProducer.h
deleted file mode 100644
index 322a699..0000000
--- a/media/libstagefright/omx/include/media/stagefright/omx/1.0/WGraphicBufferProducer.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2018, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_MEDIA_OMX_V1_0_WGRAPHICBUFFERPRODUCER_H
-#define ANDROID_HARDWARE_MEDIA_OMX_V1_0_WGRAPHICBUFFERPRODUCER_H
-
-#include <media/stagefright/bqhelper/WGraphicBufferProducer.h>
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace omx {
-namespace V1_0 {
-namespace implementation {
-
-using TWGraphicBufferProducer = ::android::TWGraphicBufferProducer<
-    ::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer>;
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace omx
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
-
-#endif  // ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMXBUFFERPRODUCER_H
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/BWGraphicBufferSource.h b/media/libstagefright/omx/include/media/stagefright/omx/BWGraphicBufferSource.h
deleted file mode 100644
index 0efff22..0000000
--- a/media/libstagefright/omx/include/media/stagefright/omx/BWGraphicBufferSource.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef BWGRAPHIC_BUFFER_SOURCE_H_
-#define BWGRAPHIC_BUFFER_SOURCE_H_
-
-#include <binder/Binder.h>
-#include <binder/Status.h>
-#include <android/BnGraphicBufferSource.h>
-#include <android/BnOMXBufferSource.h>
-#include <media/IOMX.h>
-
-#include "OmxGraphicBufferSource.h"
-#include "IOmxNodeWrapper.h"
-
-namespace android {
-
-using ::android::binder::Status;
-using ::android::BnGraphicBufferSource;
-using ::android::OmxGraphicBufferSource;
-using ::android::IOMXNode;
-using ::android::sp;
-
-struct BWGraphicBufferSource : public BnGraphicBufferSource {
-    struct BWOMXBufferSource;
-    struct BWOmxNodeWrapper;
-
-    sp<OmxGraphicBufferSource> mBase;
-    sp<IOMXBufferSource> mOMXBufferSource;
-
-    BWGraphicBufferSource(sp<OmxGraphicBufferSource> const &base);
-
-    Status configure(
-            const sp<IOMXNode>& omxNode, int32_t dataSpace) override;
-    Status setSuspend(bool suspend, int64_t timeUs) override;
-    Status setRepeatPreviousFrameDelayUs(
-            int64_t repeatAfterUs) override;
-    Status setMaxFps(float maxFps) override;
-    Status setTimeLapseConfig(
-            double fps, double captureFps) override;
-    Status setStartTimeUs(int64_t startTimeUs) override;
-    Status setStopTimeUs(int64_t stopTimeUs) override;
-    Status getStopTimeOffsetUs(int64_t* stopTimeOffsetUs) override;
-    Status setColorAspects(int32_t aspects) override;
-    Status setTimeOffsetUs(int64_t timeOffsetsUs) override;
-    Status signalEndOfInputStream() override;
-};
-
-}  // namespace android
-
-#endif  // ANDROID_HARDWARE_MEDIA_OMX_V1_0_WGRAPHICBUFFERSOURCE_H
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/OMXMaster.h b/media/libstagefright/omx/include/media/stagefright/omx/OMXMaster.h
index 897f287..93eaef1 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/OMXMaster.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/OMXMaster.h
@@ -52,13 +52,16 @@
 private:
     char mProcessName[16];
     Mutex mLock;
-    List<OMXPluginBase *> mPlugins;
+    struct Plugin {
+        OMXPluginBase *mOmx;
+        void *mLibHandle;
+    };
+    List<Plugin> mPlugins;
     KeyedVector<String8, OMXPluginBase *> mPluginByComponentName;
     KeyedVector<OMX_COMPONENTTYPE *, OMXPluginBase *> mPluginByInstance;
 
-    void *mVendorLibHandle;
-
     void addVendorPlugin();
+    void addPlatformPlugin();
     void addPlugin(const char *libname);
     void addPlugin(OMXPluginBase *plugin);
     void clearPlugins();
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/SimpleSoftOMXComponent.h b/media/libstagefright/omx/include/media/stagefright/omx/SimpleSoftOMXComponent.h
index 1d1f2bd..6bbedda 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/SimpleSoftOMXComponent.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/SimpleSoftOMXComponent.h
@@ -20,6 +20,7 @@
 
 #include "SoftOMXComponent.h"
 
+#include <atomic>
 #include <media/stagefright/foundation/AHandlerReflector.h>
 #include <utils/RefBase.h>
 #include <utils/threads.h>
@@ -28,6 +29,7 @@
 namespace android {
 
 struct ALooper;
+struct ABuffer;
 
 struct CodecProfileLevel {
     OMX_U32 mProfile;
@@ -49,6 +51,7 @@
     struct BufferInfo {
         OMX_BUFFERHEADERTYPE *mHeader;
         bool mOwnedByUs;
+        bool mFrameConfig;
     };
 
     struct PortInfo {
@@ -76,6 +79,9 @@
     virtual OMX_ERRORTYPE internalSetParameter(
             OMX_INDEXTYPE index, const OMX_PTR params);
 
+    virtual OMX_ERRORTYPE internalSetConfig(
+            OMX_INDEXTYPE index, const OMX_PTR params, bool *frameConfig);
+
     virtual void onQueueFilled(OMX_U32 portIndex);
     List<BufferInfo *> &getPortQueue(OMX_U32 portIndex);
 
@@ -101,6 +107,7 @@
     OMX_STATETYPE mTargetState;
 
     Vector<PortInfo> mPorts;
+    std::atomic_bool mFrameConfig;
 
     bool isSetParameterAllowed(
             OMX_INDEXTYPE index, const OMX_PTR params) const;
@@ -114,6 +121,9 @@
     virtual OMX_ERRORTYPE setParameter(
             OMX_INDEXTYPE index, const OMX_PTR params);
 
+    virtual OMX_ERRORTYPE setConfig(
+            OMX_INDEXTYPE index, const OMX_PTR params);
+
     virtual OMX_ERRORTYPE useBuffer(
             OMX_BUFFERHEADERTYPE **buffer,
             OMX_U32 portIndex,
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/SoftOMXComponent.h b/media/libstagefright/omx/include/media/stagefright/omx/SoftOMXComponent.h
index 3ab6f88..79f0c77 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/SoftOMXComponent.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/SoftOMXComponent.h
@@ -21,12 +21,15 @@
 #include <media/stagefright/foundation/ABase.h>
 #include <media/stagefright/foundation/AString.h>
 #include <utils/RefBase.h>
-
+#include <utils/Log.h>
 #include <OMX_Component.h>
 
 namespace android {
 
 struct SoftOMXComponent : public RefBase {
+    enum {
+        kFenceTimeoutMs = 1000
+    };
     SoftOMXComponent(
             const char *name,
             const OMX_CALLBACKTYPE *callbacks,
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/SoftVideoDecoderOMXComponent.h b/media/libstagefright/omx/include/media/stagefright/omx/SoftVideoDecoderOMXComponent.h
index 56fc691..d7c1658 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/SoftVideoDecoderOMXComponent.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/SoftVideoDecoderOMXComponent.h
@@ -20,14 +20,19 @@
 
 #include "SimpleSoftOMXComponent.h"
 
+#include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/AHandlerReflector.h>
 #include <media/stagefright/foundation/ColorUtils.h>
-#include <media/IOMX.h>
+#include <media/openmax/OMX_Core.h>
+#include <media/openmax/OMX_Video.h>
+#include <media/openmax/OMX_VideoExt.h>
+
 #include <media/hardware/HardwareAPI.h>
 
 #include <utils/RefBase.h>
 #include <utils/threads.h>
 #include <utils/Vector.h>
+#include <utils/List.h>
 
 namespace android {
 
@@ -48,6 +53,7 @@
     enum {
         kDescribeColorAspectsIndex = kPrepareForAdaptivePlaybackIndex + 1,
         kDescribeHdrStaticInfoIndex = kPrepareForAdaptivePlaybackIndex + 2,
+        kDescribeHdr10PlusInfoIndex = kPrepareForAdaptivePlaybackIndex + 3,
     };
 
     enum {
@@ -68,8 +74,8 @@
     virtual OMX_ERRORTYPE getConfig(
             OMX_INDEXTYPE index, OMX_PTR params);
 
-    virtual OMX_ERRORTYPE setConfig(
-            OMX_INDEXTYPE index, const OMX_PTR params);
+    virtual OMX_ERRORTYPE internalSetConfig(
+            OMX_INDEXTYPE index, const OMX_PTR params, bool *frameConfig);
 
     virtual OMX_ERRORTYPE getExtensionIndex(
             const char *name, OMX_INDEXTYPE *index);
@@ -80,6 +86,8 @@
 
     virtual bool supportDescribeHdrStaticInfo();
 
+    virtual bool supportDescribeHdr10PlusInfo();
+
     // This function sets both minimum buffer count and actual buffer count of
     // input port to be |numInputBuffers|. It will also set both minimum buffer
     // count and actual buffer count of output port to be |numOutputBuffers|.
@@ -166,6 +174,9 @@
     // Helper function to dump the ColorAspects.
     void dumpColorAspects(const ColorAspects &colorAspects);
 
+    sp<ABuffer> dequeueInputFrameConfig();
+    void queueOutputFrameConfig(const sp<ABuffer> &info);
+
 private:
     uint32_t mMinInputBufferSize;
     uint32_t mMinCompressionRatio;
@@ -174,6 +185,9 @@
     OMX_VIDEO_CODINGTYPE mCodingType;
     const CodecProfileLevel *mProfileLevels;
     size_t mNumProfileLevels;
+    typedef List<sp<ABuffer> > Hdr10PlusInfoList;
+    Hdr10PlusInfoList mHdr10PlusInputs;
+    Hdr10PlusInfoList mHdr10PlusOutputs;
 
     DISALLOW_EVIL_CONSTRUCTORS(SoftVideoDecoderOMXComponent);
 };
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/SoftVideoEncoderOMXComponent.h b/media/libstagefright/omx/include/media/stagefright/omx/SoftVideoEncoderOMXComponent.h
index 2d6f31b..9cb72dd 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/SoftVideoEncoderOMXComponent.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/SoftVideoEncoderOMXComponent.h
@@ -18,7 +18,9 @@
 
 #define SOFT_VIDEO_ENCODER_OMX_COMPONENT_H_
 
-#include <media/IOMX.h>
+#include <media/openmax/OMX_Core.h>
+#include <media/openmax/OMX_Video.h>
+#include <media/openmax/OMX_VideoExt.h>
 
 #include "SimpleSoftOMXComponent.h"
 
diff --git a/media/libstagefright/omx/tests/Android.bp b/media/libstagefright/omx/tests/Android.bp
index 3b521ab..569fa88 100644
--- a/media/libstagefright/omx/tests/Android.bp
+++ b/media/libstagefright/omx/tests/Android.bp
@@ -9,7 +9,6 @@
         "libbinder",
         "libmedia",
         "libmedia_omx",
-        "libmediaextractor",
         "libutils",
         "liblog",
         "libstagefright_foundation",
@@ -19,12 +18,11 @@
         "libnativewindow",
         "android.hidl.allocator@1.0",
         "android.hidl.memory@1.0",
-        "android.hardware.media.omx@1.0",
     ],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright",
-        "frameworks/native/include/media/openmax",
+    header_libs: [
+        "libbase_headers",
+        "media_ndk_headers",
     ],
 
     cflags: [
diff --git a/media/libstagefright/omx/tests/OMXHarness.cpp b/media/libstagefright/omx/tests/OMXHarness.cpp
index 895a4ce..cc8c234 100644
--- a/media/libstagefright/omx/tests/OMXHarness.cpp
+++ b/media/libstagefright/omx/tests/OMXHarness.cpp
@@ -17,6 +17,7 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "OMXHarness"
 #include <inttypes.h>
+#include <android-base/macros.h>
 #include <utils/Log.h>
 
 #include "OMXHarness.h"
@@ -28,7 +29,6 @@
 #include <cutils/properties.h>
 #include <media/DataSource.h>
 #include <media/IMediaHTTPService.h>
-#include <media/MediaExtractor.h>
 #include <media/MediaSource.h>
 #include <media/OMXBuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
@@ -40,9 +40,8 @@
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MediaExtractorFactory.h>
 #include <media/stagefright/MetaData.h>
+#include <media/stagefright/OMXClient.h>
 #include <media/stagefright/SimpleDecodingSource.h>
-#include <android/hardware/media/omx/1.0/IOmx.h>
-#include <media/omx/1.0/WOmx.h>
 #include <system/window.h>
 
 #define DEFAULT_TIMEOUT         500000
@@ -81,12 +80,13 @@
 }
 
 status_t Harness::initOMX() {
-    using namespace ::android::hardware::media::omx::V1_0;
-    sp<IOmx> tOmx = IOmx::getService();
-    if (tOmx == nullptr) {
+    OMXClient client;
+    if (client.connect() != OK) {
+        ALOGE("Failed to connect to OMX to create persistent input surface.");
         return NO_INIT;
     }
-    mOMX = new utils::LWOmx(tOmx);
+
+    mOMX = client.interface();
 
     return mOMX != 0 ? OK : NO_INIT;
 }
@@ -844,7 +844,7 @@
 
             case '?':
                 fprintf(stderr, "\n");
-                // fall through
+                FALLTHROUGH_INTENDED;
 
             case 'h':
             default:
diff --git a/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp b/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp
index 82a0631..4302aee 100644
--- a/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp
+++ b/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp
@@ -423,6 +423,11 @@
             CHECK_LE(offset + (mOtherDataLenBits / 8), buffer->size());
             offset += mOtherDataLenBits / 8;
         }
+
+        if (i < mNumSubFrames && offset >= buffer->size()) {
+            ALOGW("Skip subframes after %d, total %d", (int)i, (int)mNumSubFrames);
+            break;
+        }
     }
 
     if (offset < buffer->size()) {
diff --git a/media/libstagefright/rtsp/APacketSource.cpp b/media/libstagefright/rtsp/APacketSource.cpp
index c5605b4..1aa8a20 100644
--- a/media/libstagefright/rtsp/APacketSource.cpp
+++ b/media/libstagefright/rtsp/APacketSource.cpp
@@ -417,7 +417,7 @@
     if (sessionDesc->getDurationUs(&durationUs)) {
         mFormat->setInt64(kKeyDuration, durationUs);
     } else {
-        mFormat->setInt64(kKeyDuration, -1ll);
+        mFormat->setInt64(kKeyDuration, -1LL);
     }
 
     mInitCheck = OK;
diff --git a/media/libstagefright/rtsp/ARTPAssembler.cpp b/media/libstagefright/rtsp/ARTPAssembler.cpp
index c7a65c2..befc226 100644
--- a/media/libstagefright/rtsp/ARTPAssembler.cpp
+++ b/media/libstagefright/rtsp/ARTPAssembler.cpp
@@ -36,7 +36,7 @@
 
         if (status == WRONG_SEQUENCE_NUMBER) {
             if (mFirstFailureTimeUs >= 0) {
-                if (ALooper::GetNowUs() - mFirstFailureTimeUs > 10000ll) {
+                if (ALooper::GetNowUs() - mFirstFailureTimeUs > 10000LL) {
                     mFirstFailureTimeUs = -1;
 
                     // LOG(VERBOSE) << "waited too long for packet.";
diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp
index a86ab74..6a4706d 100644
--- a/media/libstagefright/rtsp/ARTPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTPConnection.cpp
@@ -50,7 +50,7 @@
 }
 
 // static
-const int64_t ARTPConnection::kSelectTimeoutUs = 1000ll;
+const int64_t ARTPConnection::kSelectTimeoutUs = 1000LL;
 
 struct ARTPConnection::StreamInfo {
     int mRTPSocket;
@@ -118,7 +118,7 @@
     bumpSocketBufferSize(*rtcpSocket);
 
     /* rand() * 1000 may overflow int type, use long long */
-    unsigned start = (unsigned)((rand()* 1000ll)/RAND_MAX) + 15550;
+    unsigned start = (unsigned)((rand()* 1000LL)/RAND_MAX) + 15550;
     start &= ~1;
 
     for (unsigned port = start; port < 65536; port += 2) {
@@ -307,7 +307,7 @@
 
     int64_t nowUs = ALooper::GetNowUs();
     if (mLastReceiverReportTimeUs <= 0
-            || mLastReceiverReportTimeUs + 5000000ll <= nowUs) {
+            || mLastReceiverReportTimeUs + 5000000LL <= nowUs) {
         sp<ABuffer> buffer = new ABuffer(kMaxUDPSize);
         List<StreamInfo>::iterator it = mStreams.begin();
         while (it != mStreams.end()) {
diff --git a/media/libstagefright/rtsp/ARTPSource.cpp b/media/libstagefright/rtsp/ARTPSource.cpp
index 4827cd2..4afa6f4 100644
--- a/media/libstagefright/rtsp/ARTPSource.cpp
+++ b/media/libstagefright/rtsp/ARTPSource.cpp
@@ -180,7 +180,7 @@
     }
 
     int64_t nowUs = ALooper::GetNowUs();
-    if (mLastFIRRequestUs >= 0 && mLastFIRRequestUs + 5000000ll > nowUs) {
+    if (mLastFIRRequestUs >= 0 && mLastFIRRequestUs + 5000000LL > nowUs) {
         // Send FIR requests at most every 5 secs.
         return;
     }
diff --git a/media/libstagefright/rtsp/ARTPWriter.cpp b/media/libstagefright/rtsp/ARTPWriter.cpp
index 0667df1..4f86773 100644
--- a/media/libstagefright/rtsp/ARTPWriter.cpp
+++ b/media/libstagefright/rtsp/ARTPWriter.cpp
@@ -400,8 +400,10 @@
         switch (count) {
             case 3:
                 data[offset++] = 0;
+                [[fallthrough]];
             case 2:
                 data[offset++] = 0;
+                [[fallthrough]];
             case 1:
                 data[offset++] = 0;
         }
@@ -418,10 +420,10 @@
 uint64_t ARTPWriter::GetNowNTP() {
     uint64_t nowUs = ALooper::GetNowUs();
 
-    nowUs += ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll;
+    nowUs += ((70LL * 365 + 17) * 24) * 60 * 60 * 1000000LL;
 
-    uint64_t hi = nowUs / 1000000ll;
-    uint64_t lo = ((1ll << 32) * (nowUs % 1000000ll)) / 1000000ll;
+    uint64_t hi = nowUs / 1000000LL;
+    uint64_t lo = ((1LL << 32) * (nowUs % 1000000LL)) / 1000000LL;
 
     return (hi << 32) | lo;
 }
@@ -574,7 +576,7 @@
     int64_t timeUs;
     CHECK(mediaBuf->meta_data().findInt64(kKeyTime, &timeUs));
 
-    uint32_t rtpTime = mRTPTimeBase + (timeUs * 9 / 100ll);
+    uint32_t rtpTime = mRTPTimeBase + (timeUs * 9 / 100LL);
 
     const uint8_t *mediaData =
         (const uint8_t *)mediaBuf->data() + mediaBuf->range_offset();
@@ -669,7 +671,7 @@
     int64_t timeUs;
     CHECK(mediaBuf->meta_data().findInt64(kKeyTime, &timeUs));
 
-    uint32_t rtpTime = mRTPTimeBase + (timeUs * 9 / 100ll);
+    uint32_t rtpTime = mRTPTimeBase + (timeUs * 9 / 100LL);
 
     const uint8_t *mediaData =
         (const uint8_t *)mediaBuf->data() + mediaBuf->range_offset();
diff --git a/media/libstagefright/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp
index 5620cf8..789e62a 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTSPConnection.cpp
@@ -19,6 +19,7 @@
 #include <utils/Log.h>
 
 #include "ARTSPConnection.h"
+#include "NetworkUtils.h"
 
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
@@ -38,7 +39,7 @@
 namespace android {
 
 // static
-const int64_t ARTSPConnection::kSelectTimeoutUs = 1000ll;
+const int64_t ARTSPConnection::kSelectTimeoutUs = 1000LL;
 
 // static
 const AString ARTSPConnection::sUserAgent =
@@ -59,8 +60,8 @@
     if (mSocket >= 0) {
         ALOGE("Connection is still open, closing the socket.");
         if (mUIDValid) {
-            HTTPBase::UnRegisterSocketUserTag(mSocket);
-            HTTPBase::UnRegisterSocketUserMark(mSocket);
+            NetworkUtils::UnRegisterSocketUserTag(mSocket);
+            NetworkUtils::UnRegisterSocketUserMark(mSocket);
         }
         close(mSocket);
         mSocket = -1;
@@ -214,8 +215,8 @@
 
     if (mState != DISCONNECTED) {
         if (mUIDValid) {
-            HTTPBase::UnRegisterSocketUserTag(mSocket);
-            HTTPBase::UnRegisterSocketUserMark(mSocket);
+            NetworkUtils::UnRegisterSocketUserTag(mSocket);
+            NetworkUtils::UnRegisterSocketUserMark(mSocket);
         }
         close(mSocket);
         mSocket = -1;
@@ -254,7 +255,7 @@
 
     struct hostent *ent = gethostbyname(host.c_str());
     if (ent == NULL) {
-        ALOGE("Unknown host %s", host.c_str());
+        ALOGE("Unknown host %s", uriDebugString(host).c_str());
 
         reply->setInt32("result", -ENOENT);
         reply->post();
@@ -266,9 +267,9 @@
     mSocket = socket(AF_INET, SOCK_STREAM, 0);
 
     if (mUIDValid) {
-        HTTPBase::RegisterSocketUserTag(mSocket, mUID,
+        NetworkUtils::RegisterSocketUserTag(mSocket, mUID,
                                         (uint32_t)*(uint32_t*) "RTSP");
-        HTTPBase::RegisterSocketUserMark(mSocket, mUID);
+        NetworkUtils::RegisterSocketUserMark(mSocket, mUID);
     }
 
     MakeSocketBlocking(mSocket, false);
@@ -297,8 +298,8 @@
         mState = DISCONNECTED;
 
         if (mUIDValid) {
-            HTTPBase::UnRegisterSocketUserTag(mSocket);
-            HTTPBase::UnRegisterSocketUserMark(mSocket);
+            NetworkUtils::UnRegisterSocketUserTag(mSocket);
+            NetworkUtils::UnRegisterSocketUserMark(mSocket);
         }
         close(mSocket);
         mSocket = -1;
@@ -315,8 +316,8 @@
 
 void ARTSPConnection::performDisconnect() {
     if (mUIDValid) {
-        HTTPBase::UnRegisterSocketUserTag(mSocket);
-        HTTPBase::UnRegisterSocketUserMark(mSocket);
+        NetworkUtils::UnRegisterSocketUserTag(mSocket);
+        NetworkUtils::UnRegisterSocketUserMark(mSocket);
     }
     close(mSocket);
     mSocket = -1;
@@ -389,8 +390,8 @@
 
         mState = DISCONNECTED;
         if (mUIDValid) {
-            HTTPBase::UnRegisterSocketUserTag(mSocket);
-            HTTPBase::UnRegisterSocketUserMark(mSocket);
+            NetworkUtils::UnRegisterSocketUserTag(mSocket);
+            NetworkUtils::UnRegisterSocketUserMark(mSocket);
         }
         close(mSocket);
         mSocket = -1;
diff --git a/media/libstagefright/rtsp/ASessionDescription.cpp b/media/libstagefright/rtsp/ASessionDescription.cpp
index 325084c..9263565 100644
--- a/media/libstagefright/rtsp/ASessionDescription.cpp
+++ b/media/libstagefright/rtsp/ASessionDescription.cpp
@@ -80,7 +80,7 @@
             return false;
         }
 
-        ALOGI("%s", line.c_str());
+        ALOGV("%s", line.c_str());
 
         switch (line.c_str()[0]) {
             case 'v':
@@ -261,7 +261,7 @@
         return false;
     }
 
-    if (strncmp(value.c_str(), "npt=", 4)) {
+    if (strncmp(value.c_str(), "npt=", 4) && strncmp(value.c_str(), "npt:", 4)) {
         return false;
     }
 
diff --git a/media/libstagefright/rtsp/Android.bp b/media/libstagefright/rtsp/Android.bp
index debd07e..9bc9c89 100644
--- a/media/libstagefright/rtsp/Android.bp
+++ b/media/libstagefright/rtsp/Android.bp
@@ -1,5 +1,5 @@
-cc_library_static {
-    name: "libstagefright_rtsp",
+cc_defaults {
+    name: "libstagefright_rtsp_defaults",
 
     srcs: [
         "AAMRAssembler.cpp",
@@ -46,12 +46,24 @@
             "unsigned-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 }
 
+cc_library_static {
+    name: "libstagefright_rtsp",
+
+    srcs: ["NetworkUtils.cpp"],
+    header_libs: ["libnetd_client_headers"],
+    defaults: ["libstagefright_rtsp_defaults"],
+}
+
+cc_library_static {
+    name: "libstagefright_rtsp_player2",
+
+    srcs: ["NetworkUtilsForAppProc.cpp"],
+    defaults: ["libstagefright_rtsp_defaults"],
+}
+
 //###############################################################################
 
 cc_test {
@@ -89,8 +101,5 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 }
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h
index c6c0245..48bc8ce 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -31,6 +31,7 @@
 #include "ARTPConnection.h"
 #include "ARTSPConnection.h"
 #include "ASessionDescription.h"
+#include "NetworkUtils.h"
 
 #include <ctype.h>
 #include <cutils/properties.h>
@@ -54,6 +55,10 @@
 #define UNUSED_UNLESS_VERBOSE(x)
 #endif
 
+#ifndef FALLTHROUGH_INTENDED
+#define FALLTHROUGH_INTENDED [[clang::fallthrough]]  // NOLINT
+#endif
+
 // If no access units are received within 5 secs, assume that the rtp
 // stream has ended and signal end of stream.
 static int64_t kAccessUnitTimeoutUs = 10000000ll;
@@ -70,6 +75,8 @@
 // a new sequence.
 static int32_t kMaxAllowedStaleAccessUnits = 20;
 
+static int64_t kTearDownTimeoutUs = 3000000ll;
+
 namespace android {
 
 static bool GetAttribute(const char *s, const char *key, AString *value) {
@@ -306,8 +313,10 @@
             switch (count) {
                 case 3:
                     data[offset++] = 0;
+                    FALLTHROUGH_INTENDED;
                 case 2:
                     data[offset++] = 0;
+                    FALLTHROUGH_INTENDED;
                 case 1:
                     data[offset++] = 0;
             }
@@ -338,8 +347,7 @@
 
             struct hostent *ent = gethostbyname(mSessionHost.c_str());
             if (ent == NULL) {
-                ALOGE("Failed to look up address of session host '%s'",
-                     mSessionHost.c_str());
+                ALOGE("Failed to look up address of session host");
 
                 return false;
             }
@@ -524,7 +532,7 @@
                             mSessionURL.append(AStringPrintf("%u", port));
                             mSessionURL.append(path);
 
-                            ALOGI("rewritten session url: '%s'", mSessionURL.c_str());
+                            ALOGV("rewritten session url: '%s'", mSessionURL.c_str());
                         }
 
                         sp<AMessage> reply = new AMessage('conn', this);
@@ -751,10 +759,10 @@
                         if (!track->mUsingInterleavedTCP) {
                             // Clear the tag
                             if (mUIDValid) {
-                                HTTPBase::UnRegisterSocketUserTag(track->mRTPSocket);
-                                HTTPBase::UnRegisterSocketUserMark(track->mRTPSocket);
-                                HTTPBase::UnRegisterSocketUserTag(track->mRTCPSocket);
-                                HTTPBase::UnRegisterSocketUserMark(track->mRTCPSocket);
+                                NetworkUtils::UnRegisterSocketUserTag(track->mRTPSocket);
+                                NetworkUtils::UnRegisterSocketUserMark(track->mRTPSocket);
+                                NetworkUtils::UnRegisterSocketUserTag(track->mRTCPSocket);
+                                NetworkUtils::UnRegisterSocketUserMark(track->mRTCPSocket);
                             }
 
                             close(track->mRTPSocket);
@@ -880,10 +888,10 @@
 
                         // Clear the tag
                         if (mUIDValid) {
-                            HTTPBase::UnRegisterSocketUserTag(info->mRTPSocket);
-                            HTTPBase::UnRegisterSocketUserMark(info->mRTPSocket);
-                            HTTPBase::UnRegisterSocketUserTag(info->mRTCPSocket);
-                            HTTPBase::UnRegisterSocketUserMark(info->mRTCPSocket);
+                            NetworkUtils::UnRegisterSocketUserTag(info->mRTPSocket);
+                            NetworkUtils::UnRegisterSocketUserMark(info->mRTPSocket);
+                            NetworkUtils::UnRegisterSocketUserTag(info->mRTCPSocket);
+                            NetworkUtils::UnRegisterSocketUserMark(info->mRTCPSocket);
                         }
 
                         close(info->mRTPSocket);
@@ -924,6 +932,14 @@
                 request.append("\r\n");
 
                 mConn->sendRequest(request.c_str(), reply);
+
+                // If the response of teardown hasn't been received in 3 seconds,
+                // post 'tear' message to avoid ANR.
+                if (!msg->findInt32("reconnect", &reconnect) || !reconnect) {
+                    sp<AMessage> teardown = reply->dup();
+                    teardown->setInt32("result", -ECONNABORTED);
+                    teardown->post(kTearDownTimeoutUs);
+                }
                 break;
             }
 
@@ -1659,12 +1675,12 @@
                     &info->mRTPSocket, &info->mRTCPSocket, &rtpPort);
 
             if (mUIDValid) {
-                HTTPBase::RegisterSocketUserTag(info->mRTPSocket, mUID,
-                                                (uint32_t)*(uint32_t*) "RTP_");
-                HTTPBase::RegisterSocketUserTag(info->mRTCPSocket, mUID,
-                                                (uint32_t)*(uint32_t*) "RTP_");
-                HTTPBase::RegisterSocketUserMark(info->mRTPSocket, mUID);
-                HTTPBase::RegisterSocketUserMark(info->mRTCPSocket, mUID);
+                NetworkUtils::RegisterSocketUserTag(info->mRTPSocket, mUID,
+                        (uint32_t)*(uint32_t*) "RTP_");
+                NetworkUtils::RegisterSocketUserTag(info->mRTCPSocket, mUID,
+                        (uint32_t)*(uint32_t*) "RTP_");
+                NetworkUtils::RegisterSocketUserMark(info->mRTPSocket, mUID);
+                NetworkUtils::RegisterSocketUserMark(info->mRTCPSocket, mUID);
             }
 
             request.append("Transport: RTP/AVP/UDP;unicast;client_port=");
@@ -1906,7 +1922,7 @@
             mLastMediaTimeUs = mediaTimeUs;
         }
 
-        if (mediaTimeUs < 0) {
+        if (mediaTimeUs < 0 && !mSeekable) {
             ALOGV("dropping early accessUnit.");
             return false;
         }
diff --git a/media/libstagefright/rtsp/NetworkUtils.cpp b/media/libstagefright/rtsp/NetworkUtils.cpp
new file mode 100644
index 0000000..cc36b78
--- /dev/null
+++ b/media/libstagefright/rtsp/NetworkUtils.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "NetworkUtils"
+#include <utils/Log.h>
+
+#include "NetworkUtils.h"
+#include <cutils/qtaguid.h>
+#include <NetdClient.h>
+
+namespace android {
+
+// static
+void NetworkUtils::RegisterSocketUserTag(int sockfd, uid_t uid, uint32_t kTag) {
+    int res = qtaguid_tagSocket(sockfd, kTag, uid);
+    if (res != 0) {
+        ALOGE("Failed tagging socket %d for uid %d (My UID=%d)", sockfd, uid, geteuid());
+    }
+}
+
+// static
+void NetworkUtils::UnRegisterSocketUserTag(int sockfd) {
+    int res = qtaguid_untagSocket(sockfd);
+    if (res != 0) {
+        ALOGE("Failed untagging socket %d (My UID=%d)", sockfd, geteuid());
+    }
+}
+
+// static
+void NetworkUtils::RegisterSocketUserMark(int sockfd, uid_t uid) {
+    setNetworkForUser(uid, sockfd);
+}
+
+// static
+void NetworkUtils::UnRegisterSocketUserMark(int sockfd) {
+    RegisterSocketUserMark(sockfd, geteuid());
+}
+
+}  // namespace android
diff --git a/media/libstagefright/rtsp/NetworkUtils.h b/media/libstagefright/rtsp/NetworkUtils.h
new file mode 100644
index 0000000..e25ee46
--- /dev/null
+++ b/media/libstagefright/rtsp/NetworkUtils.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NETWORK_UTILS_H_
+#define NETWORK_UTILS_H_
+
+namespace android {
+
+struct NetworkUtils {
+    static void RegisterSocketUserTag(int sockfd, uid_t uid, uint32_t kTag);
+    static void UnRegisterSocketUserTag(int sockfd);
+
+    static void RegisterSocketUserMark(int sockfd, uid_t uid);
+    static void UnRegisterSocketUserMark(int sockfd);
+};
+
+}  // namespace android
+
+#endif  // NETWORK_UTILS_H_
diff --git a/media/libstagefright/rtsp/NetworkUtilsForAppProc.cpp b/media/libstagefright/rtsp/NetworkUtilsForAppProc.cpp
new file mode 100644
index 0000000..662159c
--- /dev/null
+++ b/media/libstagefright/rtsp/NetworkUtilsForAppProc.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "NetworkUtils"
+#include <utils/Log.h>
+
+#include "NetworkUtils.h"
+
+// NetworkUtils implementation for application process.
+namespace android {
+
+// static
+void NetworkUtils::RegisterSocketUserTag(int, uid_t, uint32_t) {
+    // No op. Framework already handles the data usage billing for applications.
+}
+
+// static
+void NetworkUtils::UnRegisterSocketUserTag(int) {
+    // No op.
+}
+
+// static
+void NetworkUtils::RegisterSocketUserMark(int, uid_t) {
+    // No op. Framework already handles the data usage billing for applications.
+}
+
+// static
+void NetworkUtils::UnRegisterSocketUserMark(int) {
+    // No op.
+}
+
+}  // namespace android
diff --git a/media/libstagefright/rtsp/SDPLoader.cpp b/media/libstagefright/rtsp/SDPLoader.cpp
index d459cbd..665d51a 100644
--- a/media/libstagefright/rtsp/SDPLoader.cpp
+++ b/media/libstagefright/rtsp/SDPLoader.cpp
@@ -24,7 +24,7 @@
 
 #include <media/MediaHTTPConnection.h>
 #include <media/MediaHTTPService.h>
-#include <media/stagefright/MediaHTTP.h>
+#include <media/stagefright/ClearMediaHTTP.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/Utils.h>
@@ -41,7 +41,7 @@
       mFlags(flags),
       mNetLooper(new ALooper),
       mCancelled(false),
-      mHTTPDataSource(new MediaHTTP(httpService->makeHTTPConnection())) {
+      mHTTPDataSource(new ClearMediaHTTP(httpService->makeHTTPConnection())) {
     mNetLooper->setName("sdp net");
     mNetLooper->start(false /* runOnCallingThread */,
                       false /* canCallJava */,
diff --git a/media/libstagefright/timedtext/Android.bp b/media/libstagefright/timedtext/Android.bp
index a5ad6c6..6935655 100644
--- a/media/libstagefright/timedtext/Android.bp
+++ b/media/libstagefright/timedtext/Android.bp
@@ -14,9 +14,36 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
+    },
+
+    include_dirs: [
+        "frameworks/av/media/libstagefright",
+    ],
+
+    shared_libs: ["libmedia"],
+}
+
+cc_library_static {
+    name: "libstagefright_timedtext2",
+
+    srcs: ["TextDescriptions2.cpp"],
+
+    static_libs: [
+        "libmediaplayer2-protos",
+        "libprotobuf-cpp-lite",
+    ],
+
+    cflags: [
+        "-Wno-multichar",
+        "-Werror",
+        "-Wall",
+    ],
+
+    sanitize: {
+        misc_undefined: [
+            "signed-integer-overflow",
+        ],
+        cfi: true,
     },
 
     include_dirs: [
diff --git a/media/libstagefright/timedtext/TextDescriptions2.cpp b/media/libstagefright/timedtext/TextDescriptions2.cpp
new file mode 100644
index 0000000..fd42d3a
--- /dev/null
+++ b/media/libstagefright/timedtext/TextDescriptions2.cpp
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "TextDescriptions2.h"
+#include <media/stagefright/foundation/ByteUtils.h>
+#include <media/stagefright/MediaErrors.h>
+
+namespace android {
+
+TextDescriptions2::TextDescriptions2() {
+}
+
+status_t TextDescriptions2::getPlayerMessageOfDescriptions(
+        const uint8_t *data, ssize_t size,
+        uint32_t flags, int timeMs, PlayerMessage *playerMsg) {
+    if (flags & IN_BAND_TEXT_3GPP) {
+        if (flags & GLOBAL_DESCRIPTIONS) {
+            return extract3GPPGlobalDescriptions(data, size, playerMsg);
+        } else if (flags & LOCAL_DESCRIPTIONS) {
+            return extract3GPPLocalDescriptions(data, size, timeMs, playerMsg);
+        }
+    } else if (flags & OUT_OF_BAND_TEXT_SRT) {
+        if (flags & LOCAL_DESCRIPTIONS) {
+            return extractSRTLocalDescriptions(data, size, timeMs, playerMsg);
+        }
+    }
+
+    return ERROR_UNSUPPORTED;
+}
+
+// Parse the SRT text sample, and store the timing and text sample in a PlayerMessage.
+// The PlayerMessage will be sent to MediaPlayer2.java through event, and will be
+// parsed in TimedText.java.
+status_t TextDescriptions2::extractSRTLocalDescriptions(
+        const uint8_t *data, ssize_t size, int timeMs, PlayerMessage *playerMsg) {
+    playerMsg->add_values()->set_int32_value(KEY_LOCAL_SETTING);
+    playerMsg->add_values()->set_int32_value(KEY_START_TIME);
+    playerMsg->add_values()->set_int32_value(timeMs);
+
+    playerMsg->add_values()->set_int32_value(KEY_STRUCT_TEXT);
+    playerMsg->add_values()->set_bytes_value(data, size);
+
+    return OK;
+}
+
+// Extract the local 3GPP display descriptions. 3GPP local descriptions
+// are appended to the text sample if any.
+status_t TextDescriptions2::extract3GPPLocalDescriptions(
+        const uint8_t *data, ssize_t size,
+        int timeMs, PlayerMessage *playerMsg) {
+
+    playerMsg->add_values()->set_int32_value(KEY_LOCAL_SETTING);
+
+    // write start time to display this text sample
+    playerMsg->add_values()->set_int32_value(KEY_START_TIME);
+    playerMsg->add_values()->set_int32_value(timeMs);
+
+    if (size < 2) {
+        return OK;
+    }
+    ssize_t textLen = (*data) << 8 | (*(data + 1));
+
+    if (size < textLen + 2) {
+        return OK;
+    }
+
+    // write text sample length and text sample itself
+    playerMsg->add_values()->set_int32_value(KEY_STRUCT_TEXT);
+    playerMsg->add_values()->set_bytes_value(data + 2, textLen);
+
+    if (size > textLen + 2) {
+        data += (textLen + 2);
+        size -= (textLen + 2);
+    } else {
+        return OK;
+    }
+
+    while (size >= 8) {
+        const uint8_t *tmpData = data;
+        ssize_t chunkSize = U32_AT(tmpData);      // size includes size and type
+        uint32_t chunkType = U32_AT(tmpData + 4);
+
+        if (chunkSize <= 8 || chunkSize > size) {
+            return OK;
+        }
+
+        size_t remaining = chunkSize - 8;
+
+        tmpData += 8;
+
+        switch(chunkType) {
+            // 'tbox' box to indicate the position of the text with values
+            // of top, left, bottom and right
+            case FOURCC('t', 'b', 'o', 'x'):
+            {
+                if (remaining < 8) {
+                    return OK;
+                }
+                playerMsg->add_values()->set_int32_value(KEY_STRUCT_TEXT_POS);
+                playerMsg->add_values()->set_int32_value(U16_AT(tmpData));
+                playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 2));
+                playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 4));
+                playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 6));
+
+                tmpData += 8;
+                remaining -= 8;
+                break;
+            }
+            default:
+            {
+                break;
+            }
+        }
+
+        data += chunkSize;
+        size -= chunkSize;
+    }
+
+    return OK;
+}
+
+// To extract box 'tx3g' defined in 3GPP TS 26.245, and store it in a PlayerMessage
+status_t TextDescriptions2::extract3GPPGlobalDescriptions(
+        const uint8_t *data, ssize_t size, PlayerMessage *playerMsg) {
+
+    playerMsg->add_values()->set_int32_value(KEY_GLOBAL_SETTING);
+
+    while (size >= 8) {
+        ssize_t chunkSize = U32_AT(data);
+        uint32_t chunkType = U32_AT(data + 4);
+        const uint8_t *tmpData = data;
+        tmpData += 8;
+        size_t remaining = size - 8;
+
+        if (chunkSize <= 8 || size < chunkSize) {
+            return OK;
+        }
+        switch(chunkType) {
+            case FOURCC('t', 'x', '3', 'g'):
+            {
+                if (remaining < 18) {
+                    return OK;
+                }
+                // Skip DISPLAY_FLAGS, STRUCT_JUSTIFICATION, and BACKGROUND_COLOR_RGBA
+                tmpData += 18;
+                remaining -= 18;
+
+                if (remaining < 8) {
+                    return OK;
+                }
+                playerMsg->add_values()->set_int32_value(KEY_STRUCT_TEXT_POS);
+                playerMsg->add_values()->set_int32_value(U16_AT(tmpData));
+                playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 2));
+                playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 4));
+                playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 6));
+
+                tmpData += 8;
+                remaining -= 18;
+                // Ignore remaining data.
+                break;
+            }
+            default:
+            {
+                break;
+            }
+        }
+
+        data += chunkSize;
+        size -= chunkSize;
+    }
+
+    return OK;
+}
+
+}  // namespace android
diff --git a/media/libstagefright/timedtext/TextDescriptions2.h b/media/libstagefright/timedtext/TextDescriptions2.h
new file mode 100644
index 0000000..7c7d2d0
--- /dev/null
+++ b/media/libstagefright/timedtext/TextDescriptions2.h
@@ -0,0 +1,88 @@
+ /*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TEXT_DESCRIPTIONS2_H_
+
+#define TEXT_DESCRIPTIONS2_H_
+
+#include <binder/Parcel.h>
+#include <media/stagefright/foundation/ABase.h>
+
+#include "mediaplayer2.pb.h"
+
+using android::media::MediaPlayer2Proto::PlayerMessage;
+
+namespace android {
+
+class TextDescriptions2 {
+public:
+    enum {
+        IN_BAND_TEXT_3GPP             = 0x01,
+        OUT_OF_BAND_TEXT_SRT          = 0x02,
+
+        GLOBAL_DESCRIPTIONS           = 0x100,
+        LOCAL_DESCRIPTIONS            = 0x200,
+    };
+
+    static status_t getPlayerMessageOfDescriptions(
+            const uint8_t *data, ssize_t size,
+            uint32_t flags, int timeMs, PlayerMessage *playerMsg);
+private:
+    TextDescriptions2();
+
+    enum {
+        // These keys must be in sync with the keys in TimedText.java
+        KEY_DISPLAY_FLAGS                 = 1, // int
+        KEY_STYLE_FLAGS                   = 2, // int
+        KEY_BACKGROUND_COLOR_RGBA         = 3, // int
+        KEY_HIGHLIGHT_COLOR_RGBA          = 4, // int
+        KEY_SCROLL_DELAY                  = 5, // int
+        KEY_WRAP_TEXT                     = 6, // int
+        KEY_START_TIME                    = 7, // int
+        KEY_STRUCT_BLINKING_TEXT_LIST     = 8, // List<CharPos>
+        KEY_STRUCT_FONT_LIST              = 9, // List<Font>
+        KEY_STRUCT_HIGHLIGHT_LIST         = 10, // List<CharPos>
+        KEY_STRUCT_HYPER_TEXT_LIST        = 11, // List<HyperText>
+        KEY_STRUCT_KARAOKE_LIST           = 12, // List<Karaoke>
+        KEY_STRUCT_STYLE_LIST             = 13, // List<Style>
+        KEY_STRUCT_TEXT_POS               = 14, // TextPos
+        KEY_STRUCT_JUSTIFICATION          = 15, // Justification
+        KEY_STRUCT_TEXT                   = 16, // Text
+
+        KEY_GLOBAL_SETTING                = 101,
+        KEY_LOCAL_SETTING                 = 102,
+        KEY_START_CHAR                    = 103,
+        KEY_END_CHAR                      = 104,
+        KEY_FONT_ID                       = 105,
+        KEY_FONT_SIZE                     = 106,
+        KEY_TEXT_COLOR_RGBA               = 107,
+    };
+
+    static status_t extractSRTLocalDescriptions(
+            const uint8_t *data, ssize_t size,
+            int timeMs, PlayerMessage *playerMsg);
+    static status_t extract3GPPGlobalDescriptions(
+            const uint8_t *data, ssize_t size,
+            PlayerMessage *playerMsg);
+    static status_t extract3GPPLocalDescriptions(
+            const uint8_t *data, ssize_t size,
+            int timeMs, PlayerMessage *playerMsg);
+
+    DISALLOW_EVIL_CONSTRUCTORS(TextDescriptions2);
+};
+
+}  // namespace android
+#endif  // TEXT_DESCRIPTIONS2_H_
diff --git a/media/libstagefright/webm/Android.bp b/media/libstagefright/webm/Android.bp
index f968788..64ecc2d 100644
--- a/media/libstagefright/webm/Android.bp
+++ b/media/libstagefright/webm/Android.bp
@@ -14,9 +14,6 @@
             "unsigned-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
     srcs: [
@@ -34,4 +31,8 @@
         "libutils",
         "liblog",
     ],
+
+    header_libs: [
+        "media_ndk_headers",
+    ],
 }
diff --git a/media/libstagefright/webm/WebmElement.cpp b/media/libstagefright/webm/WebmElement.cpp
index a5120b9..4d504e0 100644
--- a/media/libstagefright/webm/WebmElement.cpp
+++ b/media/libstagefright/webm/WebmElement.cpp
@@ -305,6 +305,7 @@
 }
 
 sp<WebmElement> WebmElement::AudioTrackEntry(
+        const char *codec,
         int chans,
         double rate,
         const sp<ABuffer> &buf,
@@ -322,7 +323,7 @@
             uid,
             lacing,
             lang,
-            "A_VORBIS",
+            codec,
             kAudioType,
             trackEntryFields);
 
diff --git a/media/libstagefright/webm/WebmElement.h b/media/libstagefright/webm/WebmElement.h
index ffbba1b..a94c23f 100644
--- a/media/libstagefright/webm/WebmElement.h
+++ b/media/libstagefright/webm/WebmElement.h
@@ -50,6 +50,7 @@
     static sp<WebmElement> SegmentInfo(uint64_t scale = 1000000, double dur = 0);
 
     static sp<WebmElement> AudioTrackEntry(
+            const char *codec,
             int chans,
             double rate,
             const sp<ABuffer> &buf,
diff --git a/media/libstagefright/webm/WebmFrame.cpp b/media/libstagefright/webm/WebmFrame.cpp
index 4b0d47c..52c30ec 100644
--- a/media/libstagefright/webm/WebmFrame.cpp
+++ b/media/libstagefright/webm/WebmFrame.cpp
@@ -62,6 +62,14 @@
             mData);
 }
 
+uint64_t WebmFrame::getAbsTimecode() {
+    return mAbsTimecode;
+}
+
+void WebmFrame::updateAbsTimecode(uint64_t newAbsTimecode) {
+    mAbsTimecode = newAbsTimecode;
+}
+
 bool WebmFrame::operator<(const WebmFrame &other) const {
     if (this->mEos) {
         return false;
diff --git a/media/libstagefright/webm/WebmFrame.h b/media/libstagefright/webm/WebmFrame.h
index a410a87..47f2523 100644
--- a/media/libstagefright/webm/WebmFrame.h
+++ b/media/libstagefright/webm/WebmFrame.h
@@ -25,7 +25,7 @@
 public:
     const int mType;
     const bool mKey;
-    const uint64_t mAbsTimecode;
+    uint64_t mAbsTimecode;
     const sp<ABuffer> mData;
     const bool mEos;
 
@@ -33,6 +33,8 @@
     WebmFrame(int type, bool key, uint64_t absTimecode, MediaBufferBase *buf);
     ~WebmFrame() {}
 
+    uint64_t getAbsTimecode();
+    void updateAbsTimecode(uint64_t newAbsTimecode);
     sp<WebmElement> SimpleBlock(uint64_t baseTimecode) const;
 
     bool operator<(const WebmFrame &other) const;
diff --git a/media/libstagefright/webm/WebmFrameThread.cpp b/media/libstagefright/webm/WebmFrameThread.cpp
index 23269af..631a2ab 100644
--- a/media/libstagefright/webm/WebmFrameThread.cpp
+++ b/media/libstagefright/webm/WebmFrameThread.cpp
@@ -78,6 +78,7 @@
       mVideoFrames(videoThread->mSink),
       mAudioFrames(audioThread->mSink),
       mCues(cues),
+      mStartOffsetTimecode(UINT64_MAX),
       mDone(true) {
 }
 
@@ -92,6 +93,7 @@
       mVideoFrames(videoSource),
       mAudioFrames(audioSource),
       mCues(cues),
+      mStartOffsetTimecode(UINT64_MAX),
       mDone(true) {
 }
 
@@ -213,6 +215,11 @@
         const sp<WebmFrame> audioFrame = mAudioFrames.peek();
         ALOGV("a frame: %p", audioFrame.get());
 
+        if (mStartOffsetTimecode == UINT64_MAX) {
+            mStartOffsetTimecode =
+                    std::min(audioFrame->getAbsTimecode(), videoFrame->getAbsTimecode());
+        }
+
         if (videoFrame->mEos && audioFrame->mEos) {
             break;
         }
@@ -220,10 +227,12 @@
         if (*audioFrame < *videoFrame) {
             ALOGV("take a frame");
             mAudioFrames.take();
+            audioFrame->updateAbsTimecode(audioFrame->getAbsTimecode() - mStartOffsetTimecode);
             outstandingFrames.push_back(audioFrame);
         } else {
             ALOGV("take v frame");
             mVideoFrames.take();
+            videoFrame->updateAbsTimecode(videoFrame->getAbsTimecode() - mStartOffsetTimecode);
             outstandingFrames.push_back(videoFrame);
             if (videoFrame->mKey)
                 numVideoKeyFrames++;
@@ -350,7 +359,6 @@
         if (mStartTimeUs == kUninitialized) {
             mStartTimeUs = timestampUs;
         }
-        timestampUs -= mStartTimeUs;
 
         if (mPaused && !mResumed) {
             lastDurationUs = timestampUs - lastTimestampUs;
@@ -364,14 +372,14 @@
         // adjust time-stamps after pause/resume
         if (mResumed) {
             int64_t durExcludingEarlierPausesUs = timestampUs - previousPausedDurationUs;
-            CHECK_GE(durExcludingEarlierPausesUs, 0ll);
+            CHECK_GE(durExcludingEarlierPausesUs, 0LL);
             int64_t pausedDurationUs = durExcludingEarlierPausesUs - mTrackDurationUs;
             CHECK_GE(pausedDurationUs, lastDurationUs);
             previousPausedDurationUs += pausedDurationUs - lastDurationUs;
             mResumed = false;
         }
         timestampUs -= previousPausedDurationUs;
-        CHECK_GE(timestampUs, 0ll);
+        CHECK_GE(timestampUs, 0LL);
 
         int32_t isSync = false;
         md.findInt32(kKeyIsSyncFrame, &isSync);
diff --git a/media/libstagefright/webm/WebmFrameThread.h b/media/libstagefright/webm/WebmFrameThread.h
index 76c91f1..1ddaf9a 100644
--- a/media/libstagefright/webm/WebmFrameThread.h
+++ b/media/libstagefright/webm/WebmFrameThread.h
@@ -83,6 +83,7 @@
     LinkedBlockingQueue<const sp<WebmFrame> >& mVideoFrames;
     LinkedBlockingQueue<const sp<WebmFrame> >& mAudioFrames;
     List<sp<WebmElement> >& mCues;
+    uint64_t mStartOffsetTimecode;
 
     volatile bool mDone;
 
diff --git a/media/libstagefright/webm/WebmWriter.cpp b/media/libstagefright/webm/WebmWriter.cpp
index 4d73eb8..5eaadbd 100644
--- a/media/libstagefright/webm/WebmWriter.cpp
+++ b/media/libstagefright/webm/WebmWriter.cpp
@@ -23,6 +23,8 @@
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/hexdump.h>
+#include <media/stagefright/foundation/OpusHeader.h>
 
 #include <utils/Errors.h>
 
@@ -112,46 +114,107 @@
 // static
 sp<WebmElement> WebmWriter::audioTrack(const sp<MetaData>& md) {
     int32_t nChannels, samplerate;
-    uint32_t type;
-    const void *headerData1;
-    const char headerData2[] = { 3, 'v', 'o', 'r', 'b', 'i', 's', 7, 0, 0, 0,
-            'a', 'n', 'd', 'r', 'o', 'i', 'd', 0, 0, 0, 0, 1 };
-    const void *headerData3;
-    size_t headerSize1, headerSize2 = sizeof(headerData2), headerSize3;
+    const char* mimeType;
 
     if (!md->findInt32(kKeyChannelCount, &nChannels)
-            || !md->findInt32(kKeySampleRate, &samplerate)
-            || !md->findData(kKeyVorbisInfo, &type, &headerData1, &headerSize1)
-            || !md->findData(kKeyVorbisBooks, &type, &headerData3, &headerSize3)) {
+        || !md->findInt32(kKeySampleRate, &samplerate)
+        || !md->findCString(kKeyMIMEType, &mimeType)) {
         ALOGE("Missing format keys for audio track");
         md->dumpToLog();
         return NULL;
     }
 
-    size_t codecPrivateSize = 1;
-    codecPrivateSize += XiphLaceCodeLen(headerSize1);
-    codecPrivateSize += XiphLaceCodeLen(headerSize2);
-    codecPrivateSize += headerSize1 + headerSize2 + headerSize3;
+    int32_t bitsPerSample = 0;
+    if (!md->findInt32(kKeyBitsPerSample, &bitsPerSample)) {
+        ALOGV("kKeyBitsPerSample not available");
+    }
 
-    off_t off = 0;
-    sp<ABuffer> codecPrivateBuf = new ABuffer(codecPrivateSize);
-    uint8_t *codecPrivateData = codecPrivateBuf->data();
-    codecPrivateData[off++] = 2;
+    if (!strncasecmp(mimeType, MEDIA_MIMETYPE_AUDIO_OPUS, strlen(MEDIA_MIMETYPE_AUDIO_OPUS))) {
+        // Opus in WebM is a well-known, yet under-documented, format. The codec private data
+        // of the track is an Opus Ogg header (https://tools.ietf.org/html/rfc7845#section-5.1)
+        // The name of the track isn't standardized, its value should be "A_OPUS".
+        OpusHeader header;
+        header.channels = nChannels;
+        header.num_streams = nChannels;
+        header.num_coupled = 0;
+        // - Channel mapping family (8 bits unsigned)
+        //  --  0 = one stream: mono or L,R stereo
+        //  --  1 = channels in vorbis spec order: mono or L,R stereo or ... or FL,C,FR,RL,RR,LFE, ...
+        //  --  2..254 = reserved (treat as 255)
+        //  --  255 = no defined channel meaning
+        //
+        //  our implementation encodes:  0, 1, or 255
+        header.channel_mapping = ((nChannels > 8) ? 255 : (nChannels > 2));
+        header.gain_db = 0;
+        header.skip_samples = 0;
 
-    off += XiphLaceEnc(codecPrivateData + off, headerSize1);
-    off += XiphLaceEnc(codecPrivateData + off, headerSize2);
+        // headers are 21-bytes + something driven by channel count
+        // expect numbers in the low 30's here. WriteOpusHeader() will tell us
+        // if things are bad.
+        unsigned char header_data[100];
+        int headerSize = WriteOpusHeader(header, samplerate, (uint8_t*)header_data,
+                                            sizeof(header_data));
 
-    memcpy(codecPrivateData + off, headerData1, headerSize1);
-    off += headerSize1;
-    memcpy(codecPrivateData + off, headerData2, headerSize2);
-    off += headerSize2;
-    memcpy(codecPrivateData + off, headerData3, headerSize3);
+        if (headerSize < 0) {
+            // didn't fill out that header for some reason
+            ALOGE("failed to generate OPUS header");
+            return NULL;
+        }
 
-    sp<WebmElement> entry = WebmElement::AudioTrackEntry(
-            nChannels,
-            samplerate,
-            codecPrivateBuf);
-    return entry;
+        size_t codecPrivateSize = 0;
+        codecPrivateSize += headerSize;
+
+        off_t off = 0;
+        sp<ABuffer> codecPrivateBuf = new ABuffer(codecPrivateSize);
+        uint8_t* codecPrivateData = codecPrivateBuf->data();
+
+        memcpy(codecPrivateData + off, (uint8_t*)header_data, headerSize);
+        sp<WebmElement> entry = WebmElement::AudioTrackEntry("A_OPUS", nChannels, samplerate,
+                                                             codecPrivateBuf, bitsPerSample);
+        return entry;
+    } else if (!strncasecmp(mimeType,
+                            MEDIA_MIMETYPE_AUDIO_VORBIS,
+                            strlen(MEDIA_MIMETYPE_AUDIO_VORBIS))) {
+        uint32_t type;
+        const void *headerData1;
+        const char headerData2[] = { 3, 'v', 'o', 'r', 'b', 'i', 's', 7, 0, 0, 0,
+                'a', 'n', 'd', 'r', 'o', 'i', 'd', 0, 0, 0, 0, 1 };
+        const void *headerData3;
+        size_t headerSize1, headerSize2 = sizeof(headerData2), headerSize3;
+
+        if (!md->findData(kKeyOpaqueCSD0, &type, &headerData1, &headerSize1)
+            || !md->findData(kKeyOpaqueCSD1, &type, &headerData3, &headerSize3)) {
+            ALOGE("Missing header format keys for vorbis track");
+            md->dumpToLog();
+            return NULL;
+        }
+
+        size_t codecPrivateSize = 1;
+        codecPrivateSize += XiphLaceCodeLen(headerSize1);
+        codecPrivateSize += XiphLaceCodeLen(headerSize2);
+        codecPrivateSize += headerSize1 + headerSize2 + headerSize3;
+
+        off_t off = 0;
+        sp<ABuffer> codecPrivateBuf = new ABuffer(codecPrivateSize);
+        uint8_t *codecPrivateData = codecPrivateBuf->data();
+        codecPrivateData[off++] = 2;
+
+        off += XiphLaceEnc(codecPrivateData + off, headerSize1);
+        off += XiphLaceEnc(codecPrivateData + off, headerSize2);
+
+        memcpy(codecPrivateData + off, headerData1, headerSize1);
+        off += headerSize1;
+        memcpy(codecPrivateData + off, headerData2, headerSize2);
+        off += headerSize2;
+        memcpy(codecPrivateData + off, headerData3, headerSize3);
+
+        sp<WebmElement> entry = WebmElement::AudioTrackEntry("A_VORBIS", nChannels, samplerate,
+                                                             codecPrivateBuf, bitsPerSample);
+        return entry;
+    } else {
+        ALOGE("Track (%s) is not a supported audio format", mimeType);
+        return NULL;
+    }
 }
 
 size_t WebmWriter::numTracks() {
@@ -382,16 +445,18 @@
     const char *vp8 = MEDIA_MIMETYPE_VIDEO_VP8;
     const char *vp9 = MEDIA_MIMETYPE_VIDEO_VP9;
     const char *vorbis = MEDIA_MIMETYPE_AUDIO_VORBIS;
+    const char* opus = MEDIA_MIMETYPE_AUDIO_OPUS;
 
     size_t streamIndex;
     if (!strncasecmp(mime, vp8, strlen(vp8)) ||
         !strncasecmp(mime, vp9, strlen(vp9))) {
         streamIndex = kVideoIndex;
-    } else if (!strncasecmp(mime, vorbis, strlen(vorbis))) {
+    } else if (!strncasecmp(mime, vorbis, strlen(vorbis)) ||
+               !strncasecmp(mime, opus, strlen(opus))) {
         streamIndex = kAudioIndex;
     } else {
-        ALOGE("Track (%s) other than %s, %s or %s is not supported",
-              mime, vp8, vp9, vorbis);
+        ALOGE("Track (%s) other than %s, %s, %s, or %s is not supported",
+              mime, vp8, vp9, vorbis, opus);
         return ERROR_UNSUPPORTED;
     }
 
diff --git a/media/libstagefright/xmlparser/Android.bp b/media/libstagefright/xmlparser/Android.bp
index a4fa342..38de831 100644
--- a/media/libstagefright/xmlparser/Android.bp
+++ b/media/libstagefright/xmlparser/Android.bp
@@ -1,3 +1,9 @@
+cc_library_headers {
+    name: "libstagefright_xmlparser_headers",
+    export_include_dirs: ["include"],
+    vendor_available: true,
+}
+
 cc_library_shared {
     name: "libstagefright_xmlparser",
     vendor_available: true,
@@ -14,6 +20,7 @@
     ],
 
     shared_libs: [
+        "libbase",
         "libexpat",
         "liblog",
         "libstagefright_omx_utils",
@@ -32,10 +39,13 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
 }
 
+xsd_config {
+    name: "media_codecs",
+    srcs: ["media_codecs.xsd"],
+    package_name: "media.codecs",
+}
+
diff --git a/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp b/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
index d98e123..9783e9b 100644
--- a/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
+++ b/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
@@ -19,19 +19,34 @@
 
 #include <media/stagefright/xmlparser/MediaCodecsXmlParser.h>
 
+#include <android-base/logging.h>
+#include <android-base/macros.h>
 #include <utils/Log.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/omx/OMXUtils.h>
-#include <sys/stat.h>
-#include <expat.h>
 
-#include <cctype>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/omx/OMXUtils.h>
+
+#include <expat.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+
 #include <algorithm>
+#include <cctype>
+#include <string>
 
 namespace android {
 
+using MCXP = MediaCodecsXmlParser;
+
 namespace {
 
+bool fileExists(const std::string &path) {
+    struct stat fileStat;
+    return stat(path.c_str(), &fileStat) == 0 && S_ISREG(fileStat.st_mode);
+}
+
 /**
  * Search for a file in a list of search directories.
  *
@@ -42,7 +57,7 @@
  * search continues until the `nullptr` element in `searchDirs` is reached, at
  * which point the function returns `false`.
  *
- * \param[in] searchDirs Null-terminated array of search paths.
+ * \param[in] searchDirs array of search paths.
  * \param[in] fileName Name of the file to search.
  * \param[out] outPath Full path of the file. `outPath` will hold a valid file
  * name if the return value of this function is `true`.
@@ -50,14 +65,13 @@
  * valid file name; `false` otherwise.
  */
 bool findFileInDirs(
-        const char* const* searchDirs,
-        const char *fileName,
+        const std::vector<std::string> &searchDirs,
+        const std::string &fileName,
         std::string *outPath) {
-    for (; *searchDirs != nullptr; ++searchDirs) {
-        *outPath = std::string(*searchDirs) + "/" + fileName;
-        struct stat fileStat;
-        if (stat(outPath->c_str(), &fileStat) == 0 &&
-                S_ISREG(fileStat.st_mode)) {
+    for (const std::string &searchDir : searchDirs) {
+        std::string path = searchDir + "/" + fileName;
+        if (fileExists(path)) {
+            *outPath = path;
             return true;
         }
     }
@@ -83,123 +97,435 @@
 bool parseBoolean(const char* s) {
     return striEq(s, "y") ||
             striEq(s, "yes") ||
+            striEq(s, "enabled") ||
             striEq(s, "t") ||
             striEq(s, "true") ||
             striEq(s, "1");
 }
 
-status_t limitFoundMissingAttr(const char* name, const char *attr, bool found = true) {
-    ALOGE("limit '%s' with %s'%s' attribute", name,
-            (found ? "" : "no "), attr);
-    return BAD_VALUE;
+
+status_t combineStatus(status_t a, status_t b) {
+    if (a == NO_INIT) {
+        return b;
+    } else if ((a == OK && (b == NAME_NOT_FOUND || b == ALREADY_EXISTS || b == NO_INIT))
+            || (b == OK && (a == NAME_NOT_FOUND || a == ALREADY_EXISTS))) {
+        // ignore NAME_NOT_FOUND and ALREADY_EXIST errors as long as the other error is OK
+        // also handle OK + NO_INIT here
+        return OK;
+    } else {
+        // prefer the first error result
+        return a ? : b;
+    }
 }
 
-status_t limitError(const char* name, const char *msg) {
-    ALOGE("limit '%s' %s", name, msg);
-    return BAD_VALUE;
+MCXP::StringSet parseCommaSeparatedStringSet(const char *s) {
+    MCXP::StringSet result;
+    for (const char *ptr = s ? : ""; *ptr; ) {
+        const char *end = strchrnul(ptr, ',');
+        if (ptr != end) { // skip empty values
+            result.emplace(ptr, end - ptr);
+        }
+        ptr = end + ('\0' != *end);
+    }
+    return result;
 }
 
-status_t limitInvalidAttr(const char* name, const char* attr, const char* value) {
-    ALOGE("limit '%s' with invalid '%s' attribute (%s)", name,
-            attr, value);
-    return BAD_VALUE;
-}
+#define PLOGD(msg, ...) \
+        ALOGD(msg " at line %zu of %s", ##__VA_ARGS__, \
+                (size_t)::XML_GetCurrentLineNumber(mParser.get()), mPath.c_str());
 
-}; // unnamed namespace
+}  // unnamed namespace
 
-constexpr char const* MediaCodecsXmlParser::defaultSearchDirs[];
-constexpr char const* MediaCodecsXmlParser::defaultMainXmlName;
-constexpr char const* MediaCodecsXmlParser::defaultPerformanceXmlName;
+struct MediaCodecsXmlParser::Impl {
+    // status + error message
+    struct Result {
+    private:
+        status_t mStatus;
+        std::string mError;
+
+    public:
+        Result(status_t s, std::string error = "")
+            : mStatus(s),
+              mError(error) {
+            if (error.empty() && s) {
+                mError = "Failed (" + std::string(asString(s)) + ")";
+            }
+        }
+        operator status_t() const { return mStatus; }
+        std::string error() const { return mError; }
+    };
+
+
+    // Parsed data
+    struct Data {
+        // Service attributes
+        AttributeMap mServiceAttributeMap;
+        CodecMap mCodecMap;
+        Result addGlobal(std::string key, std::string value, bool updating);
+    };
+
+    enum Section {
+        SECTION_TOPLEVEL,
+        SECTION_SETTINGS,
+        SECTION_DECODERS,
+        SECTION_DECODER,
+        SECTION_DECODER_TYPE,
+        SECTION_ENCODERS,
+        SECTION_ENCODER,
+        SECTION_ENCODER_TYPE,
+        SECTION_INCLUDE,
+        SECTION_VARIANT,
+        SECTION_UNKNOWN,
+    };
+
+    // XML parsing state
+    struct State {
+    private:
+        Data *mData;
+
+        // current codec and/or type, plus whether we are updating
+        struct CodecAndType {
+            std::string mName;
+            CodecMap::iterator mCodec;
+            TypeMap::iterator mType;
+            bool mUpdating;
+        };
+
+        // using vectors as we need to reset their sizes
+        std::vector<std::string> mIncludeStack;
+        std::vector<Section> mSectionStack;
+        std::vector<StringSet> mVariantsStack;
+        std::vector<CodecAndType> mCurrent;
+
+    public:
+        State(Data *data);
+
+        Data &data() { return *mData; }
+
+        // used to restore parsing state at XML include boundaries, in case parsing the included
+        // file fails.
+        struct RestorePoint {
+            size_t numIncludes;
+            size_t numSections;
+            size_t numVariantSets;
+            size_t numCodecAndTypes;
+        };
+
+        // method manipulating restore points (all state stacks)
+        RestorePoint createRestorePoint() const {
+            return {
+                mIncludeStack.size(), mSectionStack.size(), mVariantsStack.size(), mCurrent.size()
+            };
+        }
+
+        void restore(RestorePoint rp) {
+            CHECK_GE(mIncludeStack.size(), rp.numIncludes);
+            CHECK_GE(mSectionStack.size(), rp.numSections);
+            CHECK_GE(mVariantsStack.size(), rp.numVariantSets);
+            CHECK_GE(mCurrent.size(), rp.numCodecAndTypes);
+
+            mIncludeStack.resize(rp.numIncludes);
+            mSectionStack.resize(rp.numSections);
+            mVariantsStack.resize(rp.numVariantSets);
+            mCurrent.resize(rp.numCodecAndTypes);
+        }
+
+        // methods manipulating the include stack
+        Result enterInclude(const std::string &path);
+        void exitInclude() {
+            mIncludeStack.pop_back();
+        }
+
+        // methods manipulating the codec/type stack/state
+        bool inCodec() const {
+            return !mCurrent.empty() && mCurrent.back().mCodec != mData->mCodecMap.end();
+        }
+
+        bool inType() const {
+            return inCodec()
+                    && mCurrent.back().mType != mCurrent.back().mCodec->second.typeMap.end();
+        }
+
+        Result enterMediaCodec(bool encoder, const char *name, const char *type, bool update);
+        Result enterType(const char *name, bool update);
+        void exitCodecOrType() {
+            mCurrent.pop_back();
+        }
+
+        // can only be called when inCodec()
+        MediaCodecsXmlParser::CodecProperties &codec() {
+            return mCurrent.back().mCodec->second;
+        }
+        // can only be called when inCodec()
+        std::string codecName() const {
+            return mCurrent.back().mName;
+        }
+        // can only be called when inCodec()
+        bool updating() const {
+            return mCurrent.back().mUpdating;
+        }
+        // can only be called when inType()
+        MediaCodecsXmlParser::AttributeMap &type() {
+            return mCurrent.back().mType->second;
+        }
+
+        // methods manipulating the section stack
+        Section section() const {
+            return mSectionStack.back();
+        }
+        Section lastNonIncludeSection() const;
+        void enterSection(Section s) {
+            mSectionStack.push_back(s);
+        }
+        void exitSection() {
+            mSectionStack.pop_back();
+            CHECK(!mSectionStack.empty());
+        }
+
+        // methods manipulating the variants stack
+        StringSet variants() const {
+            return mVariantsStack.back();
+        }
+        void enterVariants(StringSet variants) {
+            mVariantsStack.push_back(variants);
+        }
+        void exitVariants() {
+            mVariantsStack.pop_back();
+        }
+
+        // utility methods
+
+        // updates rank, domains, variants and enabledness on the current codec/type
+        Result updateCodec(
+                const char *rank, StringSet domains, StringSet variants, const char *enabled);
+        // adds a key-value attribute detail to the current type of the current codec
+        void addDetail(const std::string &key, const std::string &value);
+    };
+
+    /** XML Parser (state) */
+    struct Parser {
+        State *mState;
+
+        Parser(State *state, std::string path);
+
+        // keep track of the parser state
+        std::shared_ptr<XML_ParserStruct> mParser;
+        std::string mPath;
+        std::string mHrefBase;
+        status_t mStatus;
+
+        void parseXmlFile();
+
+        // XML parser callbacks
+        static void StartElementHandlerWrapper(void *me, const char *name, const char **attrs);
+        static void EndElementHandlerWrapper(void *me, const char *name);
+
+        void startElementHandler(const char *name, const char **attrs);
+        void endElementHandler(const char *name);
+
+        void updateStatus(status_t status);
+        void logAnyErrors(const Result &status) const;
+        status_t getStatus() const { return mStatus; }
+
+        status_t addAlias(const char **attrs);
+        status_t addFeature(const char **attrs);
+        status_t addLimit(const char **attrs);
+        status_t addQuirk(const char **attrs, const char *prefix = nullptr);
+        status_t addSetting(const char **attrs, const char *prefix = nullptr);
+        status_t enterMediaCodec(const char **attrs, bool encoder);
+        status_t enterType(const char **attrs);
+        status_t includeXmlFile(const char **attrs);
+        status_t limitVariants(const char **attrs);
+
+        status_t updateMediaCodec(
+                const char *rank, const StringSet &domain, const StringSet &variants,
+                const char *enabled);
+    };
+
+    status_t parseXmlFilesInSearchDirs(
+        const std::vector<std::string> &fileNames,
+        const std::vector<std::string> &searchDirs);
+
+    status_t parseXmlPath(const std::string &path);
+
+    // Computed longest common prefix
+    Data mData;
+    State mState;
+
+    // Role map
+    mutable std::string mCommonPrefix;
+    mutable RoleMap mRoleMap;
+    mutable std::mutex mLock;
+
+    status_t mParsingStatus;
+
+    Impl()
+        : mState(&mData),
+          mParsingStatus(NO_INIT) {
+    }
+
+    void generateRoleMap() const;
+    void generateCommonPrefix() const;
+
+    const AttributeMap& getServiceAttributeMap() const {
+        std::lock_guard<std::mutex> guard(mLock);
+        return mData.mServiceAttributeMap;
+    }
+
+    const CodecMap& getCodecMap() const {
+        std::lock_guard<std::mutex> guard(mLock);
+        return mData.mCodecMap;
+    }
+
+    const RoleMap& getRoleMap() const;
+    const char* getCommonPrefix() const;
+
+    status_t getParsingStatus() const {
+        std::lock_guard<std::mutex> guard(mLock);
+        return mParsingStatus;
+    }
+};
+
 constexpr char const* MediaCodecsXmlParser::defaultProfilingResultsXmlPath;
 
-MediaCodecsXmlParser::MediaCodecsXmlParser(
-        const char* const* searchDirs,
-        const char* mainXmlName,
-        const char* performanceXmlName,
-        const char* profilingResultsXmlPath) :
-    mParsingStatus(NO_INIT),
-    mUpdate(false),
-    mCodecCounter(0) {
-    std::string path;
-    if (findFileInDirs(searchDirs, mainXmlName, &path)) {
-        parseTopLevelXMLFile(path.c_str(), false);
-    } else {
-        ALOGE("Cannot find %s", mainXmlName);
-        mParsingStatus = NAME_NOT_FOUND;
-    }
-    if (findFileInDirs(searchDirs, performanceXmlName, &path)) {
-        parseTopLevelXMLFile(path.c_str(), true);
-    }
-    if (profilingResultsXmlPath != nullptr) {
-        parseTopLevelXMLFile(profilingResultsXmlPath, true);
-    }
+MediaCodecsXmlParser::MediaCodecsXmlParser()
+    : mImpl(new Impl()) {
 }
 
-bool MediaCodecsXmlParser::parseTopLevelXMLFile(
-        const char *codecs_xml,
-        bool ignore_errors) {
-    // get href_base
-    const char *href_base_end = strrchr(codecs_xml, '/');
-    if (href_base_end != nullptr) {
-        mHrefBase = std::string(codecs_xml, href_base_end - codecs_xml + 1);
-    }
+status_t MediaCodecsXmlParser::parseXmlFilesInSearchDirs(
+        const std::vector<std::string> &fileNames,
+        const std::vector<std::string> &searchDirs) {
+    return mImpl->parseXmlFilesInSearchDirs(fileNames, searchDirs);
+}
 
-    mParsingStatus = OK; // keeping this here for safety
-    mCurrentSection = SECTION_TOPLEVEL;
+status_t MediaCodecsXmlParser::parseXmlPath(const std::string &path) {
+    return mImpl->parseXmlPath(path);
+}
 
-    parseXMLFile(codecs_xml);
-
-    if (mParsingStatus != OK) {
-        ALOGW("parseTopLevelXMLFile(%s) failed", codecs_xml);
-        if (ignore_errors) {
-            mParsingStatus = OK;
-            return false;
+status_t MediaCodecsXmlParser::Impl::parseXmlFilesInSearchDirs(
+        const std::vector<std::string> &fileNames,
+        const std::vector<std::string> &searchDirs) {
+    status_t res = NO_INIT;
+    for (const std::string fileName : fileNames) {
+        status_t err = NO_INIT;
+        std::string path;
+        if (findFileInDirs(searchDirs, fileName, &path)) {
+            err = parseXmlPath(path);
+        } else {
+            ALOGD("Cannot find %s", path.c_str());
         }
-        mCodecMap.clear();
-        return false;
+        res = combineStatus(res, err);
     }
-    return true;
+    return res;
+}
+
+status_t MediaCodecsXmlParser::Impl::parseXmlPath(const std::string &path) {
+    std::lock_guard<std::mutex> guard(mLock);
+    if (!fileExists(path)) {
+        ALOGD("Cannot find %s", path.c_str());
+        mParsingStatus = combineStatus(mParsingStatus, NAME_NOT_FOUND);
+        return NAME_NOT_FOUND;
+    }
+
+    // save state (even though we should always be at toplevel here)
+    State::RestorePoint rp = mState.createRestorePoint();
+    Parser parser(&mState, path);
+    parser.parseXmlFile();
+    mState.restore(rp);
+
+    if (parser.getStatus() != OK) {
+        ALOGD("parseXmlPath(%s) failed with %s", path.c_str(), asString(parser.getStatus()));
+    }
+    mParsingStatus = combineStatus(mParsingStatus, parser.getStatus());
+    return parser.getStatus();
 }
 
 MediaCodecsXmlParser::~MediaCodecsXmlParser() {
 }
 
-void MediaCodecsXmlParser::parseXMLFile(const char *path) {
+MediaCodecsXmlParser::Impl::State::State(MediaCodecsXmlParser::Impl::Data *data)
+    : mData(data) {
+    mSectionStack.emplace_back(SECTION_TOPLEVEL);
+}
+
+MediaCodecsXmlParser::Impl::Section
+MediaCodecsXmlParser::Impl::State::lastNonIncludeSection() const {
+    for (auto it = mSectionStack.end(); it != mSectionStack.begin(); --it) {
+        if (it[-1] != SECTION_INCLUDE) {
+            return it[-1];
+        }
+    }
+    TRESPASS("must have non-include section");
+}
+
+void MediaCodecsXmlParser::Impl::Parser::updateStatus(status_t status) {
+    mStatus = combineStatus(mStatus, status);
+}
+
+void MediaCodecsXmlParser::Impl::Parser::logAnyErrors(const Result &status) const {
+    if (status) {
+        if (status.error().empty()) {
+            PLOGD("error %s", asString((status_t)status));
+        } else {
+            PLOGD("%s", status.error().c_str());
+        }
+    }
+}
+
+MediaCodecsXmlParser::Impl::Parser::Parser(State *state, std::string path)
+    : mState(state),
+      mPath(path),
+      mStatus(NO_INIT) {
+    // determine href_base
+    std::string::size_type end = path.rfind("/");
+    if (end != std::string::npos) {
+        mHrefBase = path.substr(0, end + 1);
+    }
+}
+
+void MediaCodecsXmlParser::Impl::Parser::parseXmlFile() {
+    const char *path = mPath.c_str();
+    ALOGD("parsing %s...", path);
     FILE *file = fopen(path, "r");
 
     if (file == nullptr) {
-        ALOGW("unable to open media codecs configuration xml file: %s", path);
-        mParsingStatus = NAME_NOT_FOUND;
+        ALOGD("unable to open media codecs configuration xml file: %s", path);
+        mStatus = NAME_NOT_FOUND;
         return;
     }
 
-    XML_Parser parser = ::XML_ParserCreate(nullptr);
-    LOG_FATAL_IF(parser == nullptr, "XML_MediaCodecsXmlParserCreate() failed.");
+    mParser = std::shared_ptr<XML_ParserStruct>(
+        ::XML_ParserCreate(nullptr),
+        [](XML_ParserStruct *parser) { ::XML_ParserFree(parser); });
+    LOG_FATAL_IF(!mParser, "XML_MediaCodecsXmlParserCreate() failed.");
 
-    ::XML_SetUserData(parser, this);
-    ::XML_SetElementHandler(
-            parser, StartElementHandlerWrapper, EndElementHandlerWrapper);
+    ::XML_SetUserData(mParser.get(), this);
+    ::XML_SetElementHandler(mParser.get(), StartElementHandlerWrapper, EndElementHandlerWrapper);
 
     static constexpr int BUFF_SIZE = 512;
-    while (mParsingStatus == OK) {
-        void *buff = ::XML_GetBuffer(parser, BUFF_SIZE);
+    // updateStatus(OK);
+    if (mStatus == NO_INIT) {
+        mStatus = OK;
+    }
+    while (mStatus == OK) {
+        void *buff = ::XML_GetBuffer(mParser.get(), BUFF_SIZE);
         if (buff == nullptr) {
-            ALOGE("failed in call to XML_GetBuffer()");
-            mParsingStatus = UNKNOWN_ERROR;
+            ALOGD("failed in call to XML_GetBuffer()");
+            mStatus = UNKNOWN_ERROR;
             break;
         }
 
         int bytes_read = ::fread(buff, 1, BUFF_SIZE, file);
         if (bytes_read < 0) {
-            ALOGE("failed in call to read");
-            mParsingStatus = ERROR_IO;
+            ALOGD("failed in call to read");
+            mStatus = ERROR_IO;
             break;
         }
 
-        XML_Status status = ::XML_ParseBuffer(parser, bytes_read, bytes_read == 0);
+        XML_Status status = ::XML_ParseBuffer(mParser.get(), bytes_read, bytes_read == 0);
         if (status != XML_STATUS_OK) {
-            ALOGE("malformed (%s)", ::XML_ErrorString(::XML_GetErrorCode(parser)));
-            mParsingStatus = ERROR_MALFORMED;
+            PLOGD("malformed (%s)", ::XML_ErrorString(::XML_GetErrorCode(mParser.get())));
+            mStatus = ERROR_MALFORMED;
             break;
         }
 
@@ -208,39 +534,47 @@
         }
     }
 
-    ::XML_ParserFree(parser);
+    mParser.reset();
 
     fclose(file);
     file = nullptr;
 }
 
 // static
-void MediaCodecsXmlParser::StartElementHandlerWrapper(
+void MediaCodecsXmlParser::Impl::Parser::StartElementHandlerWrapper(
         void *me, const char *name, const char **attrs) {
-    static_cast<MediaCodecsXmlParser*>(me)->startElementHandler(name, attrs);
+    static_cast<MediaCodecsXmlParser::Impl::Parser*>(me)->startElementHandler(name, attrs);
 }
 
 // static
-void MediaCodecsXmlParser::EndElementHandlerWrapper(void *me, const char *name) {
-    static_cast<MediaCodecsXmlParser*>(me)->endElementHandler(name);
+void MediaCodecsXmlParser::Impl::Parser::EndElementHandlerWrapper(void *me, const char *name) {
+    static_cast<MediaCodecsXmlParser::Impl::Parser*>(me)->endElementHandler(name);
 }
 
-status_t MediaCodecsXmlParser::includeXMLFile(const char **attrs) {
+status_t MediaCodecsXmlParser::Impl::Parser::includeXmlFile(const char **attrs) {
     const char *href = nullptr;
     size_t i = 0;
     while (attrs[i] != nullptr) {
-        if (strEq(attrs[i], "href")) {
-            if (attrs[++i] == nullptr) {
-                return BAD_VALUE;
-            }
-            href = attrs[i];
-        } else {
-            ALOGE("includeXMLFile: unrecognized attribute: %s", attrs[i]);
+        CHECK((i & 1) == 0);
+        if (attrs[i + 1] == nullptr) {
+            PLOGD("Include: attribute '%s' is null", attrs[i]);
             return BAD_VALUE;
         }
+
+        if (strEq(attrs[i], "href")) {
+            href = attrs[++i];
+        } else {
+            PLOGD("Include: ignoring unrecognized attribute '%s'", attrs[i]);
+            ++i;
+        }
         ++i;
     }
 
+    if (href == nullptr) {
+        PLOGD("Include with no 'href' attribute");
+        return BAD_VALUE;
+    }
+
     // For security reasons and for simplicity, file names can only contain
     // [a-zA-Z0-9_.] and must start with  media_codecs_ and end with .xml
     for (i = 0; href[i] != '\0'; i++) {
@@ -250,74 +584,114 @@
                 (href[i] >= 'a' && href[i] <= 'z')) {
             continue;
         }
-        ALOGE("invalid include file name: %s", href);
+        PLOGD("invalid include file name: %s", href);
         return BAD_VALUE;
     }
 
     std::string filename = href;
     if (filename.compare(0, 13, "media_codecs_") != 0 ||
             filename.compare(filename.size() - 4, 4, ".xml") != 0) {
-        ALOGE("invalid include file name: %s", href);
+        PLOGD("invalid include file name: %s", href);
         return BAD_VALUE;
     }
     filename.insert(0, mHrefBase);
 
-    status_t oldParsingStatus = mParsingStatus;
+    Result res = mState->enterInclude(filename);
+    if (res) {
+        logAnyErrors(res);
+        return res;
+    }
 
-    parseXMLFile(filename.c_str());
-
-    status_t newParsingStatus = mParsingStatus;
-    mParsingStatus = oldParsingStatus;
-    return newParsingStatus;
+    // save state so that we can resume even if XML parsing of the included file failed midway
+    State::RestorePoint rp = mState->createRestorePoint();
+    Parser parser(mState, filename);
+    parser.parseXmlFile();
+    mState->restore(rp);
+    mState->exitInclude();
+    return parser.getStatus();
 }
 
-void MediaCodecsXmlParser::startElementHandler(
+MediaCodecsXmlParser::Impl::Result
+MediaCodecsXmlParser::Impl::State::enterInclude(const std::string &fileName) {
+    if (std::find(mIncludeStack.begin(), mIncludeStack.end(), fileName)
+            != mIncludeStack.end()) {
+        return { BAD_VALUE, "recursive include chain" };
+    }
+    mIncludeStack.emplace_back(fileName);
+    return OK;
+}
+
+void MediaCodecsXmlParser::Impl::Parser::startElementHandler(
         const char *name, const char **attrs) {
     bool inType = true;
+    Result err = NO_INIT;
 
+    Section section = mState->section();
+
+    // handle include at any level
     if (strEq(name, "Include")) {
-        if (includeXMLFile(attrs) == OK) {
-            mSectionStack.push_back(mCurrentSection);
-            mCurrentSection = SECTION_INCLUDE;
-        }
+        mState->enterSection(SECTION_INCLUDE);
+        updateStatus(includeXmlFile(attrs));
         return;
     }
 
-    switch (mCurrentSection) {
+    // handle include section (top level)
+    if (section == SECTION_INCLUDE) {
+        if (strEq(name, "Included")) {
+            return;
+        }
+        // imitate prior level
+        section = mState->lastNonIncludeSection();
+    }
+
+    switch (section) {
         case SECTION_TOPLEVEL:
         {
+            Section nextSection;
             if (strEq(name, "Decoders")) {
-                mCurrentSection = SECTION_DECODERS;
+                nextSection = SECTION_DECODERS;
             } else if (strEq(name, "Encoders")) {
-                mCurrentSection = SECTION_ENCODERS;
+                nextSection = SECTION_ENCODERS;
             } else if (strEq(name, "Settings")) {
-                mCurrentSection = SECTION_SETTINGS;
+                nextSection = SECTION_SETTINGS;
+            } else if (strEq(name, "MediaCodecs") || strEq(name, "Included")) {
+                return;
+            } else {
+                break;
             }
-            break;
+            mState->enterSection(nextSection);
+            return;
         }
 
         case SECTION_SETTINGS:
         {
             if (strEq(name, "Setting")) {
-                (void)addSettingFromAttributes(attrs);
+                err = addSetting(attrs);
+            } else if (strEq(name, "Variant")) {
+                err = addSetting(attrs, "variant-");
+            } else if (strEq(name, "Domain")) {
+                err = addSetting(attrs, "domain-");
+            } else {
+                break;
             }
-            break;
+            updateStatus(err);
+            return;
         }
 
         case SECTION_DECODERS:
-        {
-            if (strEq(name, "MediaCodec")) {
-                (void)addMediaCodecFromAttributes(false /* encoder */, attrs);
-                mCurrentSection = SECTION_DECODER;
-            }
-            break;
-        }
-
         case SECTION_ENCODERS:
         {
             if (strEq(name, "MediaCodec")) {
-                (void)addMediaCodecFromAttributes(true /* encoder */, attrs);
-                mCurrentSection = SECTION_ENCODER;
+                err = enterMediaCodec(attrs, section == SECTION_ENCODERS);
+                updateStatus(err);
+                if (err != OK) { // skip this element on error
+                    mState->enterSection(SECTION_UNKNOWN);
+                } else {
+                    mState->enterVariants(mState->codec().variantSet);
+                    mState->enterSection(
+                            section == SECTION_DECODERS ? SECTION_DECODER : SECTION_ENCODER);
+                }
+                return;
             }
             break;
         }
@@ -326,103 +700,123 @@
         case SECTION_ENCODER:
         {
             if (strEq(name, "Quirk")) {
-                (void)addQuirk(attrs);
+                err = addQuirk(attrs, "quirk::");
+            } else if (strEq(name, "Attribute")) {
+                err = addQuirk(attrs, "attribute::");
+            } else if (strEq(name, "Alias")) {
+                err = addAlias(attrs);
             } else if (strEq(name, "Type")) {
-                (void)addTypeFromAttributes(attrs,
-                        (mCurrentSection == SECTION_ENCODER));
-                mCurrentSection =
-                        (mCurrentSection == SECTION_DECODER ?
-                        SECTION_DECODER_TYPE : SECTION_ENCODER_TYPE);
+                err = enterType(attrs);
+                if (err != OK) { // skip this element on error
+                    mState->enterSection(SECTION_UNKNOWN);
+                } else {
+                    mState->enterSection(
+                            section == SECTION_DECODER
+                                    ? SECTION_DECODER_TYPE : SECTION_ENCODER_TYPE);
+                }
             }
         }
         inType = false;
-        // fall through
+        FALLTHROUGH_INTENDED;
 
         case SECTION_DECODER_TYPE:
         case SECTION_ENCODER_TYPE:
+        case SECTION_VARIANT:
         {
             // ignore limits and features specified outside of type
-            bool outside = !inType &&
-                    mCurrentType == mCurrentCodec->second.typeMap.end();
-            if (outside &&
-                    (strEq(name, "Limit") || strEq(name, "Feature"))) {
-                ALOGW("ignoring %s specified outside of a Type", name);
+            if (!mState->inType()
+                    && (strEq(name, "Limit") || strEq(name, "Feature") || strEq(name, "Variant"))) {
+                PLOGD("ignoring %s specified outside of a Type", name);
+                return;
             } else if (strEq(name, "Limit")) {
-                (void)addLimit(attrs);
+                err = addLimit(attrs);
             } else if (strEq(name, "Feature")) {
-                (void)addFeature(attrs);
+                err = addFeature(attrs);
+            } else if (strEq(name, "Variant") && section != SECTION_VARIANT) {
+                err = limitVariants(attrs);
+                mState->enterSection(err == OK ? SECTION_VARIANT : SECTION_UNKNOWN);
+            } else if (inType
+                    && (strEq(name, "Alias") || strEq(name, "Attribute") || strEq(name, "Quirk"))) {
+                PLOGD("ignoring %s specified not directly in a MediaCodec", name);
+                return;
+            } else if (err == NO_INIT) {
+                break;
             }
-            break;
+            updateStatus(err);
+            return;
         }
 
         default:
             break;
     }
 
+    if (section != SECTION_UNKNOWN) {
+        PLOGD("Ignoring unrecognized tag <%s>", name);
+    }
+    mState->enterSection(SECTION_UNKNOWN);
 }
 
-void MediaCodecsXmlParser::endElementHandler(const char *name) {
-    switch (mCurrentSection) {
+void MediaCodecsXmlParser::Impl::Parser::endElementHandler(const char *name) {
+    // XMLParser handles tag matching, so we really just need to handle the section state here
+    Section section = mState->section();
+    switch (section) {
+        case SECTION_INCLUDE:
+        {
+            // this could also be any of: Included, MediaCodecs
+            if (strEq(name, "Include")) {
+                mState->exitSection();
+                return;
+            }
+            break;
+        }
+
         case SECTION_SETTINGS:
         {
+            // this could also be any of: Domain, Variant, Setting
             if (strEq(name, "Settings")) {
-                mCurrentSection = SECTION_TOPLEVEL;
+                mState->exitSection();
             }
             break;
         }
 
         case SECTION_DECODERS:
-        {
-            if (strEq(name, "Decoders")) {
-                mCurrentSection = SECTION_TOPLEVEL;
-            }
-            break;
-        }
-
         case SECTION_ENCODERS:
+        case SECTION_UNKNOWN:
         {
-            if (strEq(name, "Encoders")) {
-                mCurrentSection = SECTION_TOPLEVEL;
-            }
+            mState->exitSection();
             break;
         }
 
         case SECTION_DECODER_TYPE:
         case SECTION_ENCODER_TYPE:
         {
+            // this could also be any of: Alias, Limit, Feature
             if (strEq(name, "Type")) {
-                mCurrentSection =
-                        (mCurrentSection == SECTION_DECODER_TYPE ?
-                        SECTION_DECODER : SECTION_ENCODER);
-
-                mCurrentType = mCurrentCodec->second.typeMap.end();
+                mState->exitSection();
+                mState->exitCodecOrType();
             }
             break;
         }
 
         case SECTION_DECODER:
-        {
-            if (strEq(name, "MediaCodec")) {
-                mCurrentSection = SECTION_DECODERS;
-                mCurrentName.clear();
-            }
-            break;
-        }
-
         case SECTION_ENCODER:
         {
+            // this could also be any of: Alias, Limit, Quirk, Variant
             if (strEq(name, "MediaCodec")) {
-                mCurrentSection = SECTION_ENCODERS;
-                mCurrentName.clear();
+                mState->exitSection();
+                mState->exitCodecOrType();
+                mState->exitVariants();
             }
             break;
         }
 
-        case SECTION_INCLUDE:
+        case SECTION_VARIANT:
         {
-            if (strEq(name, "Include") && (mSectionStack.size() > 0)) {
-                mCurrentSection = mSectionStack.back();
-                mSectionStack.pop_back();
+            // this could also be any of: Alias, Limit, Quirk
+            if (strEq(name, "Variant")) {
+                mState->exitSection();
+                mState->exitVariants();
+                return;
             }
             break;
         }
@@ -430,243 +824,302 @@
         default:
             break;
     }
-
 }
 
-status_t MediaCodecsXmlParser::addSettingFromAttributes(const char **attrs) {
-    const char *name = nullptr;
-    const char *value = nullptr;
-    const char *update = nullptr;
+status_t MediaCodecsXmlParser::Impl::Parser::addSetting(const char **attrs, const char *prefix) {
+    const char *a_name = nullptr;
+    const char *a_value = nullptr;
+    const char *a_update = nullptr;
+    bool isBoolean = false;
 
     size_t i = 0;
     while (attrs[i] != nullptr) {
-        if (strEq(attrs[i], "name")) {
-            if (attrs[++i] == nullptr) {
-                ALOGE("addSettingFromAttributes: name is null");
-                return BAD_VALUE;
-            }
-            name = attrs[i];
-        } else if (strEq(attrs[i], "value")) {
-            if (attrs[++i] == nullptr) {
-                ALOGE("addSettingFromAttributes: value is null");
-                return BAD_VALUE;
-            }
-            value = attrs[i];
-        } else if (strEq(attrs[i], "update")) {
-            if (attrs[++i] == nullptr) {
-                ALOGE("addSettingFromAttributes: update is null");
-                return BAD_VALUE;
-            }
-            update = attrs[i];
-        } else {
-            ALOGE("addSettingFromAttributes: unrecognized attribute: %s", attrs[i]);
+        CHECK((i & 1) == 0);
+        if (attrs[i + 1] == nullptr) {
+            PLOGD("Setting: attribute '%s' is null", attrs[i]);
             return BAD_VALUE;
         }
+
+        if (strEq(attrs[i], "name")) {
+            a_name = attrs[++i];
+        } else if (strEq(attrs[i], "value") || strEq(attrs[i], "enabled")) {
+            if (a_value) {
+                PLOGD("Setting: redundant attribute '%s'", attrs[i]);
+                return BAD_VALUE;
+            }
+            isBoolean = strEq(attrs[i], "enabled");
+            a_value = attrs[++i];
+        } else if (strEq(attrs[i], "update")) {
+            a_update = attrs[++i];
+        } else {
+            PLOGD("Setting: ignoring unrecognized attribute '%s'", attrs[i]);
+            ++i;
+        }
         ++i;
     }
 
-    if (name == nullptr || value == nullptr) {
-        ALOGE("addSettingFromAttributes: name or value unspecified");
+    if (a_name == nullptr || a_value == nullptr) {
+        PLOGD("Setting with no 'name' or 'value' attribute");
         return BAD_VALUE;
     }
 
     // Boolean values are converted to "0" or "1".
-    if (strHasPrefix(name, "supports-")) {
-        value = parseBoolean(value) ? "1" : "0";
+    if (strHasPrefix(a_name, "supports-") || isBoolean) {
+        a_value = parseBoolean(a_value) ? "1" : "0";
     }
 
-    mUpdate = (update != nullptr) && parseBoolean(update);
-    auto attribute = mServiceAttributeMap.find(name);
+    bool update = (a_update != nullptr) && parseBoolean(a_update);
+    Result res = mState->data().addGlobal(std::string(prefix ? : "") + a_name, a_value, update);
+    if (res != OK) {
+        PLOGD("Setting: %s", res.error().c_str());
+    }
+    return res;
+}
+
+MediaCodecsXmlParser::Impl::Result MediaCodecsXmlParser::Impl::Data::addGlobal(
+        std::string key, std::string value, bool updating) {
+    auto attribute = mServiceAttributeMap.find(key);
     if (attribute == mServiceAttributeMap.end()) { // New attribute name
-        if (mUpdate) {
-            ALOGE("addSettingFromAttributes: updating non-existing setting");
-            return BAD_VALUE;
+        if (updating) {
+            return { NAME_NOT_FOUND, "cannot update non-existing setting" };
         }
-        mServiceAttributeMap.insert(Attribute(name, value));
+        mServiceAttributeMap.insert(Attribute(key, value));
     } else { // Existing attribute name
-        if (!mUpdate) {
-            ALOGE("addSettingFromAttributes: adding existing setting");
-        }
         attribute->second = value;
+        if (!updating) {
+            return { ALREADY_EXISTS, "updating existing setting" };
+        }
     }
 
     return OK;
 }
 
-status_t MediaCodecsXmlParser::addMediaCodecFromAttributes(
-        bool encoder, const char **attrs) {
-    const char *name = nullptr;
-    const char *type = nullptr;
-    const char *update = nullptr;
+status_t MediaCodecsXmlParser::Impl::Parser::enterMediaCodec(
+        const char **attrs, bool encoder) {
+    const char *a_name = nullptr;
+    const char *a_type = nullptr;
+    const char *a_update = nullptr;
+    const char *a_rank = nullptr;
+    const char *a_domain = nullptr;
+    const char *a_variant = nullptr;
+    const char *a_enabled = nullptr;
 
     size_t i = 0;
     while (attrs[i] != nullptr) {
-        if (strEq(attrs[i], "name")) {
-            if (attrs[++i] == nullptr) {
-                ALOGE("addMediaCodecFromAttributes: name is null");
-                return BAD_VALUE;
-            }
-            name = attrs[i];
-        } else if (strEq(attrs[i], "type")) {
-            if (attrs[++i] == nullptr) {
-                ALOGE("addMediaCodecFromAttributes: type is null");
-                return BAD_VALUE;
-            }
-            type = attrs[i];
-        } else if (strEq(attrs[i], "update")) {
-            if (attrs[++i] == nullptr) {
-                ALOGE("addMediaCodecFromAttributes: update is null");
-                return BAD_VALUE;
-            }
-            update = attrs[i];
-        } else {
-            ALOGE("addMediaCodecFromAttributes: unrecognized attribute: %s", attrs[i]);
+        CHECK((i & 1) == 0);
+        if (attrs[i + 1] == nullptr) {
+            PLOGD("MediaCodec: attribute '%s' is null", attrs[i]);
             return BAD_VALUE;
         }
+
+        if (strEq(attrs[i], "name")) {
+            a_name = attrs[++i];
+        } else if (strEq(attrs[i], "type")) {
+            a_type = attrs[++i];
+        } else if (strEq(attrs[i], "update")) {
+            a_update = attrs[++i];
+        } else if (strEq(attrs[i], "rank")) {
+            a_rank = attrs[++i];
+        } else if (strEq(attrs[i], "domain")) {
+            a_domain = attrs[++i];
+        } else if (strEq(attrs[i], "variant")) {
+            a_variant = attrs[++i];
+        } else if (strEq(attrs[i], "enabled")) {
+            a_enabled = attrs[++i];
+        } else {
+            PLOGD("MediaCodec: ignoring unrecognized attribute '%s'", attrs[i]);
+            ++i;
+        }
         ++i;
     }
 
-    if (name == nullptr) {
-        ALOGE("addMediaCodecFromAttributes: name not found");
+    if (a_name == nullptr) {
+        PLOGD("MediaCodec with no 'name' attribute");
         return BAD_VALUE;
     }
 
-    mUpdate = (update != nullptr) && parseBoolean(update);
-    mCurrentCodec = mCodecMap.find(name);
-    if (mCurrentCodec == mCodecMap.end()) { // New codec name
-        if (mUpdate) {
-            ALOGW("addMediaCodecFromAttributes: cannot update "
-                  "non-existing codec \"%s\".", name);
-            return BAD_VALUE;
+    bool update = (a_update != nullptr) && parseBoolean(a_update);
+    if (a_domain != nullptr) {
+        // disable codecs with domain by default (unless updating)
+        if (!a_enabled && !update) {
+            a_enabled = "false";
+        }
+    }
+
+    Result res = mState->enterMediaCodec(encoder, a_name, a_type, update);
+    if (res != OK) {
+        logAnyErrors(res);
+        return res;
+    }
+
+    return updateMediaCodec(
+            a_rank, parseCommaSeparatedStringSet(a_domain),
+            parseCommaSeparatedStringSet(a_variant), a_enabled);
+}
+
+MediaCodecsXmlParser::Impl::Result
+MediaCodecsXmlParser::Impl::State::enterMediaCodec(
+        bool encoder, const char *name, const char *type, bool updating) {
+    // store name even in case of an error
+    CodecMap::iterator codecIt = mData->mCodecMap.find(name);
+    TypeMap::iterator typeIt;
+    if (codecIt == mData->mCodecMap.end()) { // New codec name
+        if (updating) {
+            return { NAME_NOT_FOUND, "MediaCodec: cannot update non-existing codec" };
         }
         // Create a new codec in mCodecMap
-        mCurrentCodec = mCodecMap.insert(
-                Codec(name, CodecProperties())).first;
+        codecIt = mData->mCodecMap.insert(Codec(name, CodecProperties())).first;
         if (type != nullptr) {
-            mCurrentType = mCurrentCodec->second.typeMap.insert(
-                    Type(type, AttributeMap())).first;
+            typeIt = codecIt->second.typeMap.insert(Type(type, AttributeMap())).first;
         } else {
-            mCurrentType = mCurrentCodec->second.typeMap.end();
+            typeIt = codecIt->second.typeMap.end();
         }
-        mCurrentCodec->second.isEncoder = encoder;
-        mCurrentCodec->second.order = mCodecCounter++;
+        codecIt->second.isEncoder = encoder;
+        codecIt->second.order = mData->mCodecMap.size();
     } else { // Existing codec name
-        if (!mUpdate) {
-            ALOGW("addMediaCodecFromAttributes: trying to add "
-                  "existing codec \"%s\"", name);
-            return ALREADY_EXISTS;
+        if (!updating) {
+            return { ALREADY_EXISTS, "MediaCodec: cannot add existing codec" };
         }
         if (type != nullptr) {
-            mCurrentType = mCurrentCodec->second.typeMap.find(type);
-            if (mCurrentType == mCurrentCodec->second.typeMap.end()) {
-                ALOGE("addMediaCodecFromAttributes: cannot update "
-                      "non-existing type \"%s\" for codec \"%s\"",
-                        type, name);
-                return BAD_VALUE;
+            typeIt = codecIt->second.typeMap.find(type);
+            if (typeIt == codecIt->second.typeMap.end()) {
+                return { NAME_NOT_FOUND, "MediaCodec: cannot update non-existing type for codec" };
             }
         } else {
             // This should happen only when the codec has at most one type.
-            mCurrentType = mCurrentCodec->second.typeMap.begin();
-            if (mCurrentType == mCurrentCodec->second.typeMap.end()) {
-                ALOGE("addMediaCodecFromAttributes: cannot update "
-                      "codec \"%s\" without type specified", name);
-                return BAD_VALUE;
+            typeIt = codecIt->second.typeMap.begin();
+            if (typeIt == codecIt->second.typeMap.end()
+                    || codecIt->second.typeMap.size() != 1) {
+                return { BAD_VALUE, "MediaCodec: cannot update codec without type specified" };
             }
         }
     }
-
+    mCurrent.emplace_back(CodecAndType{name, codecIt, typeIt, updating});
     return OK;
 }
 
-status_t MediaCodecsXmlParser::addQuirk(const char **attrs) {
-    if (mCurrentCodec == mCodecMap.end()) {
-        return BAD_VALUE;
+status_t MediaCodecsXmlParser::Impl::Parser::updateMediaCodec(
+        const char *rank, const StringSet &domains, const StringSet &variants,
+        const char *enabled) {
+    CHECK(mState->inCodec());
+    CodecProperties &codec = mState->codec();
+
+    if (rank != nullptr) {
+        ALOGD_IF(!codec.rank.empty() && codec.rank != rank,
+                "codec '%s' rank changed from '%s' to '%s'",
+                mState->codecName().c_str(), codec.rank.c_str(), rank);
+        codec.rank = rank;
     }
 
-    const char *name = nullptr;
+    codec.variantSet = variants;
+
+    for (const std::string &domain : domains) {
+        if (domain.size() && domain.at(0) == '!') {
+            codec.domainSet.erase(domain.substr(1));
+        } else {
+            codec.domainSet.emplace(domain);
+        }
+    }
+
+    if (enabled != nullptr) {
+        if (parseBoolean(enabled)) {
+            codec.quirkSet.erase("attribute::disabled");
+            ALOGD("enabling %s", mState->codecName().c_str());
+        } else {
+            codec.quirkSet.emplace("attribute::disabled");
+            ALOGD("disabling %s", mState->codecName().c_str());
+        }
+    }
+    return OK;
+}
+
+status_t MediaCodecsXmlParser::Impl::Parser::addQuirk(const char **attrs, const char *prefix) {
+    CHECK(mState->inCodec());
+    const char *a_name = nullptr;
 
     size_t i = 0;
     while (attrs[i] != nullptr) {
-        if (strEq(attrs[i], "name")) {
-            if (attrs[++i] == nullptr) {
-                ALOGE("addQuirk: name is null");
-                return BAD_VALUE;
-            }
-            name = attrs[i];
-        } else {
-            ALOGE("addQuirk: unrecognized attribute: %s", attrs[i]);
+        CHECK((i & 1) == 0);
+        if (attrs[i + 1] == nullptr) {
+            PLOGD("Quirk: attribute '%s' is null", attrs[i]);
             return BAD_VALUE;
         }
+
+        if (strEq(attrs[i], "name")) {
+            a_name = attrs[++i];
+        } else {
+            PLOGD("Quirk: ignoring unrecognized attribute '%s'", attrs[i]);
+            ++i;
+        }
         ++i;
     }
 
-    if (name == nullptr) {
-        ALOGE("addQuirk: name not found");
+    if (a_name == nullptr) {
+        PLOGD("Quirk with no 'name' attribute");
         return BAD_VALUE;
     }
 
-    mCurrentCodec->second.quirkSet.emplace(name);
+    std::string key = std::string(prefix ? : "") + a_name;
+    mState->codec().quirkSet.emplace(key);
+    ALOGV("adding %s to %s", key.c_str(), mState->codecName().c_str());
     return OK;
 }
 
-status_t MediaCodecsXmlParser::addTypeFromAttributes(const char **attrs, bool encoder) {
-    if (mCurrentCodec == mCodecMap.end()) {
-        return BAD_VALUE;
-    }
+status_t MediaCodecsXmlParser::Impl::Parser::enterType(const char **attrs) {
+    CHECK(mState->inCodec());
 
-    const char *name = nullptr;
-    const char *update = nullptr;
+    const char *a_name = nullptr;
+    const char *a_update = nullptr;
 
     size_t i = 0;
     while (attrs[i] != nullptr) {
+        CHECK((i & 1) == 0);
+        if (attrs[i + 1] == nullptr) {
+            PLOGD("Type: attribute '%s' is null", attrs[i]);
+            return BAD_VALUE;
+        }
+
         if (strEq(attrs[i], "name")) {
-            if (attrs[++i] == nullptr) {
-                ALOGE("addTypeFromAttributes: name is null");
-                return BAD_VALUE;
-            }
-            name = attrs[i];
+            a_name = attrs[++i];
         } else if (strEq(attrs[i], "update")) {
-            if (attrs[++i] == nullptr) {
-                ALOGE("addTypeFromAttributes: update is null");
-                return BAD_VALUE;
-            }
-            update = attrs[i];
+            a_update = attrs[++i];
         } else {
-            ALOGE("addTypeFromAttributes: unrecognized attribute: %s", attrs[i]);
-            return BAD_VALUE;
+            PLOGD("Type: ignoring unrecognized attribute '%s'", attrs[i]);
+            ++i;
         }
         ++i;
     }
 
-    if (name == nullptr) {
+    if (a_name == nullptr) {
+        PLOGD("Type with no 'name' attribute");
         return BAD_VALUE;
     }
 
-    mCurrentCodec->second.isEncoder = encoder;
-    mCurrentType = mCurrentCodec->second.typeMap.find(name);
-    if (!mUpdate) {
-        if (mCurrentType != mCurrentCodec->second.typeMap.end()) {
-            ALOGW("addTypeFromAttributes: trying to update "
-                  "existing type \"%s\"", name);
-            return ALREADY_EXISTS;
+    bool update = (a_update != nullptr) && parseBoolean(a_update);
+    return mState->enterType(a_name, update);
+}
+
+MediaCodecsXmlParser::Impl::Result
+MediaCodecsXmlParser::Impl::State::enterType(const char *name, bool update) {
+    update = update || updating(); // handle parent
+
+    CodecMap::iterator codecIt = mCurrent.back().mCodec;
+    TypeMap::iterator typeIt = codecIt->second.typeMap.find(name);
+    if (!update) {
+        if (typeIt != codecIt->second.typeMap.end()) {
+            return { ALREADY_EXISTS, "trying to update existing type '" + std::string(name) + "'" };
         }
-        mCurrentType = mCurrentCodec->second.typeMap.insert(
-                Type(name, AttributeMap())).first;
-    } else if (mCurrentType == mCurrentCodec->second.typeMap.end()) {
-        ALOGE("addTypeFromAttributes: updating non-existing type");
-        return BAD_VALUE;
+        typeIt = codecIt->second.typeMap.insert(Type(name, AttributeMap())).first;
+    } else if (typeIt == codecIt->second.typeMap.end()) {
+        return { NAME_NOT_FOUND, "addType: updating non-existing type" };
     }
+    mCurrent.push_back({ codecName(), codecIt, typeIt, update });
+    CHECK(inType());
     return OK;
 }
 
-status_t MediaCodecsXmlParser::addLimit(const char **attrs) {
-    if (mCurrentCodec == mCodecMap.end()) {
-        return BAD_VALUE;
-    }
-    if (mCurrentType == mCurrentCodec->second.typeMap.end()) {
-        return BAD_VALUE;
-    }
-
+status_t MediaCodecsXmlParser::Impl::Parser::addLimit(const char **attrs) {
+    CHECK(mState->inType());
     const char* a_name = nullptr;
     const char* a_default = nullptr;
     const char* a_in = nullptr;
@@ -679,69 +1132,39 @@
 
     size_t i = 0;
     while (attrs[i] != nullptr) {
-        if (strEq(attrs[i], "name")) {
-            if (attrs[++i] == nullptr) {
-                ALOGE("addLimit: name is null");
-                return BAD_VALUE;
-            }
-            a_name = attrs[i];
-        } else if (strEq(attrs[i], "default")) {
-            if (attrs[++i] == nullptr) {
-                ALOGE("addLimit: default is null");
-                return BAD_VALUE;
-            }
-            a_default = attrs[i];
-        } else if (strEq(attrs[i], "in")) {
-            if (attrs[++i] == nullptr) {
-                ALOGE("addLimit: in is null");
-                return BAD_VALUE;
-            }
-            a_in = attrs[i];
-        } else if (strEq(attrs[i], "max")) {
-            if (attrs[++i] == nullptr) {
-                ALOGE("addLimit: max is null");
-                return BAD_VALUE;
-            }
-            a_max = attrs[i];
-        } else if (strEq(attrs[i], "min")) {
-            if (attrs[++i] == nullptr) {
-                ALOGE("addLimit: min is null");
-                return BAD_VALUE;
-            }
-            a_min = attrs[i];
-        } else if (strEq(attrs[i], "range")) {
-            if (attrs[++i] == nullptr) {
-                ALOGE("addLimit: range is null");
-                return BAD_VALUE;
-            }
-            a_range = attrs[i];
-        } else if (strEq(attrs[i], "ranges")) {
-            if (attrs[++i] == nullptr) {
-                ALOGE("addLimit: ranges is null");
-                return BAD_VALUE;
-            }
-            a_ranges = attrs[i];
-        } else if (strEq(attrs[i], "scale")) {
-            if (attrs[++i] == nullptr) {
-                ALOGE("addLimit: scale is null");
-                return BAD_VALUE;
-            }
-            a_scale = attrs[i];
-        } else if (strEq(attrs[i], "value")) {
-            if (attrs[++i] == nullptr) {
-                ALOGE("addLimit: value is null");
-                return BAD_VALUE;
-            }
-            a_value = attrs[i];
-        } else {
-            ALOGE("addLimit: unrecognized limit: %s", attrs[i]);
+        CHECK((i & 1) == 0);
+        if (attrs[i + 1] == nullptr) {
+            PLOGD("Limit: attribute '%s' is null", attrs[i]);
             return BAD_VALUE;
         }
+
+        if (strEq(attrs[i], "name")) {
+            a_name = attrs[++i];
+        } else if (strEq(attrs[i], "default")) {
+            a_default = attrs[++i];
+        } else if (strEq(attrs[i], "in")) {
+            a_in = attrs[++i];
+        } else if (strEq(attrs[i], "max")) {
+            a_max = attrs[++i];
+        } else if (strEq(attrs[i], "min")) {
+            a_min = attrs[++i];
+        } else if (strEq(attrs[i], "range")) {
+            a_range = attrs[++i];
+        } else if (strEq(attrs[i], "ranges")) {
+            a_ranges = attrs[++i];
+        } else if (strEq(attrs[i], "scale")) {
+            a_scale = attrs[++i];
+        } else if (strEq(attrs[i], "value")) {
+            a_value = attrs[++i];
+        } else {
+            PLOGD("Limit: ignoring unrecognized limit: %s", attrs[i]);
+            ++i;
+        }
         ++i;
     }
 
     if (a_name == nullptr) {
-        ALOGE("limit with no 'name' attribute");
+        PLOGD("Limit with no 'name' attribute");
         return BAD_VALUE;
     }
 
@@ -749,8 +1172,50 @@
     // measured-frame-rate, measured-blocks-per-second: range
     // quality: range + default + [scale]
     // complexity: range + default
-    std::string range;
-    if (strEq(a_name, "aspect-ratio") ||
+    std::string key = a_name, value;
+
+    // don't allow specifying more than one of value, range or min/max
+    if ((a_value != nullptr) + (a_range != nullptr) + (a_ranges != nullptr)
+            + (a_min != nullptr || a_max != nullptr) > 1) {
+        PLOGD("Limit '%s' has multiple 'min'/'max', 'range', 'ranges' or 'value' attributes",
+                a_name);
+        return BAD_VALUE;
+    }
+
+    // Min/max limits (only containing min or max attribute)
+    //
+    // Current "max" limits are "channel-count", "concurrent-instances".
+    // There are no current "min" limits
+    //
+    // Range limits. "range" is specified in exactly one of the following forms:
+    // 1) min-max
+    // 2) value-value
+    // 3) range
+    //
+    // Current range limits are "aspect-ratio", "bitrate", "block-count", "blocks-per-second",
+    // "complexity", "frame-rate", "quality", "size", "measured-blocks-per-second",
+    // "performance-point-*", "measured-frame-rate-*"
+    //
+    // Other limits (containing only value or ranges)
+    //
+    // Current ranges limit is "sample-rate"
+    if ((a_min != nullptr) ^ (a_max != nullptr)) {
+        // min/max limit
+        if (a_max != nullptr) {
+            key = "max-" + key;
+            value = a_max;
+        } else if (a_min != nullptr) {
+            key = "min-" + key;
+            value = a_min;
+        }
+    } else if (a_min != nullptr && a_max != nullptr) {
+        // min-max
+        key += "-range";
+        value = a_min + std::string("-") + a_max;
+    } else if (a_value != nullptr) {
+        // value-value or value
+        value = a_value;
+        if (strEq(a_name, "aspect-ratio") ||
             strEq(a_name, "bitrate") ||
             strEq(a_name, "block-count") ||
             strEq(a_name, "blocks-per-second") ||
@@ -759,222 +1224,201 @@
             strEq(a_name, "quality") ||
             strEq(a_name, "size") ||
             strEq(a_name, "measured-blocks-per-second") ||
+            strHasPrefix(a_name, "performance-point-") ||
             strHasPrefix(a_name, "measured-frame-rate-")) {
-        // "range" is specified in exactly one of the following forms:
-        // 1) min-max
-        // 2) value-value
-        // 3) range
-        if (a_min != nullptr && a_max != nullptr) {
-            // min-max
-            if (a_range != nullptr || a_value != nullptr) {
-                return limitError(a_name, "has 'min' and 'max' as well as 'range' or "
-                        "'value' attributes");
-            }
-            range = a_min;
-            range += '-';
-            range += a_max;
-        } else if (a_min != nullptr || a_max != nullptr) {
-            return limitError(a_name, "has only 'min' or 'max' attribute");
-        } else if (a_value != nullptr) {
-            // value-value
-            if (a_range != nullptr) {
-                return limitError(a_name, "has both 'range' and 'value' attributes");
-            }
-            range = a_value;
-            range += '-';
-            range += a_value;
-        } else if (a_range == nullptr) {
-            return limitError(a_name, "with no 'range', 'value' or 'min'/'max' attributes");
-        } else {
-            // range
-            range = a_range;
+            key += "-range";
+            value += std::string("-") + a_value;
         }
-
-        // "aspect-ratio" requires some special treatment.
-        if (strEq(a_name, "aspect-ratio")) {
-            // "aspect-ratio" must have "in".
-            if (a_in == nullptr) {
-                return limitFoundMissingAttr(a_name, "in", false);
-            }
-            // "in" must be either "pixels" or "blocks".
-            if (!strEq(a_in, "pixels") && !strEq(a_in, "blocks")) {
-                return limitInvalidAttr(a_name, "in", a_in);
-            }
-            // name will be "pixel-aspect-ratio-range" or
-            // "block-aspect-ratio-range".
-            mCurrentType->second[
-                    std::string(a_in).substr(0, strlen(a_in) - 1) +
-                    "-aspect-ratio-range"] = range;
-        } else {
-            // For everything else (apart from "aspect-ratio"), simply append
-            // "-range" to the name for the range-type property.
-            mCurrentType->second[std::string(a_name) + "-range"] = range;
-
-            // Only "quality" may have "scale".
-            if (!strEq(a_name, "quality") && a_scale != nullptr) {
-                return limitFoundMissingAttr(a_name, "scale");
-            } else if (strEq(a_name, "quality")) {
-                // The default value of "quality-scale" is "linear".
-                mCurrentType->second["quality-scale"] = a_scale == nullptr ?
-                        "linear" : a_scale;
-            }
-
-            // "quality" and "complexity" must have "default".
-            // Other limits must not have "default".
-            if (strEq(a_name, "quality") || strEq(a_name, "complexity")) {
-                if (a_default == nullptr) {
-                    return limitFoundMissingAttr(a_name, "default", false);
-                }
-                // name will be "quality-default" or "complexity-default".
-                mCurrentType->second[std::string(a_name) + "-default"] = a_default;
-            } else if (a_default != nullptr) {
-                return limitFoundMissingAttr(a_name, "default", true);
-            }
-        }
+    } else if (a_range != nullptr) {
+        // range
+        key += "-range";
+        value = a_range;
+    } else if (a_ranges != nullptr) {
+        // ranges
+        key += "-ranges";
+        value = a_ranges;
     } else {
-        if (a_default != nullptr) {
-            return limitFoundMissingAttr(a_name, "default");
-        }
-        if (a_in != nullptr) {
-            return limitFoundMissingAttr(a_name, "in");
-        }
-        if (a_scale != nullptr) {
-            return limitFoundMissingAttr(a_name, "scale");
-        }
-        if (a_range != nullptr) {
-            return limitFoundMissingAttr(a_name, "range");
-        }
-        if (a_min != nullptr) {
-            return limitFoundMissingAttr(a_name, "min");
-        }
-
-        if (a_max != nullptr) {
-            // "max" must exist if and only if name is "channel-count" or
-            // "concurrent-instances".
-            // "min" is not ncessary.
-            if (strEq(a_name, "channel-count") ||
-                    strEq(a_name, "concurrent-instances")) {
-                mCurrentType->second[std::string("max-") + a_name] = a_max;
-            } else {
-                return limitFoundMissingAttr(a_name, "max", false);
-            }
-        } else if (strEq(a_name, "channel-count") ||
-                strEq(a_name, "concurrent-instances")) {
-            return limitFoundMissingAttr(a_name, "max");
-        }
-
-        if (a_ranges != nullptr) {
-            // "ranges" must exist if and only if name is "sample-rate".
-            if (strEq(a_name, "sample-rate")) {
-                mCurrentType->second["sample-rate-ranges"] = a_ranges;
-            } else {
-                return limitFoundMissingAttr(a_name, "ranges", false);
-            }
-        } else if (strEq(a_name, "sample-rate")) {
-            return limitFoundMissingAttr(a_name, "ranges");
-        }
-
-        if (a_value != nullptr) {
-            // "value" must exist if and only if name is "alignment" or
-            // "block-size".
-            if (strEq(a_name, "alignment") || strEq(a_name, "block-size")) {
-                mCurrentType->second[a_name] = a_value;
-            } else {
-                return limitFoundMissingAttr(a_name, "value", false);
-            }
-        } else if (strEq(a_name, "alignment") || strEq(a_name, "block-size")) {
-            return limitFoundMissingAttr(a_name, "value", false);
-        }
-
+        PLOGD("Limit '%s' with no 'range', 'value' or 'min'/'max' attributes", a_name);
+        return BAD_VALUE;
     }
 
+    // handle 'in' attribute - this changes the key
+    if (a_in != nullptr) {
+        // Currently "aspect-ratio" uses in attribute
+        const size_t a_in_len = strlen(a_in);
+        key = std::string(a_in, a_in_len - a_in[a_in_len] == 's') + '-' + key;
+    }
+
+    // handle 'scale' attribute - this adds a new detail
+    if (a_scale != nullptr) {
+        mState->addDetail(a_name + std::string("-scale"), a_scale);
+    } else if (strEq(a_name, "quality")) {
+        // The default value of "quality-scale" is "linear" even if unspecified.
+        mState->addDetail(a_name + std::string("-scale"), "linear");
+    }
+
+    // handle 'default' attribute - this adds a new detail
+    if (a_default != nullptr) {
+        mState->addDetail(a_name + std::string("-default"), a_default);
+    }
+
+    mState->addDetail(key, value);
     return OK;
 }
 
-status_t MediaCodecsXmlParser::addFeature(const char **attrs) {
-    if (mCurrentCodec == mCodecMap.end()) {
-        return BAD_VALUE;
+void MediaCodecsXmlParser::Impl::State::addDetail(
+        const std::string &key, const std::string &value) {
+    CHECK(inType());
+    ALOGI("limit: %s = %s", key.c_str(), value.c_str());
+    const StringSet &variants = mVariantsStack.back();
+    if (variants.empty()) {
+        type()[key] = value;
+    } else {
+        for (const std::string &variant : variants) {
+            type()[variant + ":::" + key] = value;
+        }
     }
-    if (mCurrentType == mCurrentCodec->second.typeMap.end()) {
-        return BAD_VALUE;
-    }
+}
+
+status_t MediaCodecsXmlParser::Impl::Parser::limitVariants(const char **attrs) {
+    const char* a_name = nullptr;
 
     size_t i = 0;
-    const char *name = nullptr;
+    while (attrs[i] != nullptr) {
+        CHECK((i & 1) == 0);
+        if (attrs[i + 1] == nullptr) {
+            PLOGD("Variant: attribute '%s' is null", attrs[i]);
+            return BAD_VALUE;
+        }
+        if (strEq(attrs[i], "name")) {
+            a_name = attrs[++i];
+        } else {
+            PLOGD("Variant: ignoring unrecognized attribute: %s", attrs[i]);
+            ++i;
+        }
+        ++i;
+    }
+
+    if (a_name == nullptr || *a_name == '\0') {
+        PLOGD("Variant with no or empty 'name' attribute");
+        return BAD_VALUE;
+    }
+
+    StringSet variants;
+    for (const std::string &variant : parseCommaSeparatedStringSet(a_name)) {
+        if (mState->variants().count(variant)) {
+            variants.emplace(variant);
+        } else {
+            PLOGD("Variant: variant '%s' not in parent variants", variant.c_str());
+            return BAD_VALUE;
+        }
+    }
+    mState->enterVariants(variants);
+    return OK;
+}
+
+status_t MediaCodecsXmlParser::Impl::Parser::addFeature(const char **attrs) {
+    CHECK(mState->inType());
+    size_t i = 0;
+    const char *a_name = nullptr;
     int32_t optional = -1;
     int32_t required = -1;
-    const char *value = nullptr;
+    const char *a_value = nullptr;
 
     while (attrs[i] != nullptr) {
-        if (strEq(attrs[i], "name")) {
-            if (attrs[++i] == nullptr) {
-                ALOGE("addFeature: name is null");
-                return BAD_VALUE;
-            }
-            name = attrs[i];
-        } else if (strEq(attrs[i], "optional")) {
-            if (attrs[++i] == nullptr) {
-                ALOGE("addFeature: optional is null");
-                return BAD_VALUE;
-            }
-            optional = parseBoolean(attrs[i]) ? 1 : 0;
-        } else if (strEq(attrs[i], "required")) {
-            if (attrs[++i] == nullptr) {
-                ALOGE("addFeature: required is null");
-                return BAD_VALUE;
-            }
-            required = parseBoolean(attrs[i]) ? 1 : 0;
-        } else if (strEq(attrs[i], "value")) {
-            if (attrs[++i] == nullptr) {
-                ALOGE("addFeature: value is null");
-                return BAD_VALUE;
-            }
-            value = attrs[i];
-        } else {
-            ALOGE("addFeature: unrecognized attribute: %s", attrs[i]);
+        CHECK((i & 1) == 0);
+        if (attrs[i + 1] == nullptr) {
+            PLOGD("Feature: attribute '%s' is null", attrs[i]);
             return BAD_VALUE;
         }
+
+        if (strEq(attrs[i], "name")) {
+            a_name = attrs[++i];
+        } else if (strEq(attrs[i], "optional")) {
+            optional = parseBoolean(attrs[++i]) ? 1 : 0;
+        } else if (strEq(attrs[i], "required")) {
+            required = parseBoolean(attrs[++i]) ? 1 : 0;
+        } else if (strEq(attrs[i], "value")) {
+            a_value = attrs[++i];
+        } else {
+            PLOGD("Feature: ignoring unrecognized attribute '%s'", attrs[i]);
+            ++i;
+        }
         ++i;
     }
 
     // Every feature must have a name.
-    if (name == nullptr) {
-        ALOGE("feature with no 'name' attribute");
+    if (a_name == nullptr) {
+        PLOGD("Feature with no 'name' attribute");
         return BAD_VALUE;
     }
 
-    if ((optional != -1) || (required != -1)) {
-        if (optional == required) {
-            ALOGE("feature '%s' is both/neither optional and required", name);
+    if (a_value != nullptr) {
+        if (optional != -1 || required != -1) {
+            PLOGD("Feature '%s' has both value and optional/required attributes", a_name);
             return BAD_VALUE;
         }
-        if ((optional == 1) || (required == 1)) {
-            if (value != nullptr) {
-                ALOGE("feature '%s' cannot have extra 'value'", name);
-                return BAD_VALUE;
-            }
-            mCurrentType->second[std::string("feature-") + name] =
-                    optional == 1 ? "0" : "1";
-            return OK;
+    } else {
+        if (optional == required && optional != -1) {
+            PLOGD("Feature '%s' is both/neither optional and required", a_name);
+            return BAD_VALUE;
         }
+        a_value = (required == 1 || optional == 0) ? "1" : "0";
     }
-    mCurrentType->second[std::string("feature-") + name] = value == nullptr ?
-            "0" : value;
+
+    mState->addDetail(std::string("feature-") + a_name, a_value ? : "0");
+    return OK;
+}
+
+status_t MediaCodecsXmlParser::Impl::Parser::addAlias(const char **attrs) {
+    CHECK(mState->inCodec());
+    size_t i = 0;
+    const char *a_name = nullptr;
+
+    while (attrs[i] != nullptr) {
+        CHECK((i & 1) == 0);
+        if (attrs[i + 1] == nullptr) {
+            PLOGD("Alias: attribute '%s' is null", attrs[i]);
+            return BAD_VALUE;
+        }
+
+        if (strEq(attrs[i], "name")) {
+            a_name = attrs[++i];
+        } else {
+            PLOGD("Alias: ignoring unrecognized attribute '%s'", attrs[i]);
+            ++i;
+        }
+        ++i;
+    }
+
+    // Every feature must have a name.
+    if (a_name == nullptr) {
+        PLOGD("Alias with no 'name' attribute");
+        return BAD_VALUE;
+    }
+
+    mState->codec().aliases.emplace_back(a_name);
     return OK;
 }
 
 const MediaCodecsXmlParser::AttributeMap&
-        MediaCodecsXmlParser::getServiceAttributeMap() const {
-    return mServiceAttributeMap;
+MediaCodecsXmlParser::getServiceAttributeMap() const {
+    return mImpl->getServiceAttributeMap();
 }
 
 const MediaCodecsXmlParser::CodecMap&
-        MediaCodecsXmlParser::getCodecMap() const {
-    return mCodecMap;
+MediaCodecsXmlParser::getCodecMap() const {
+    return mImpl->getCodecMap();
 }
 
 const MediaCodecsXmlParser::RoleMap&
-        MediaCodecsXmlParser::getRoleMap() const {
+MediaCodecsXmlParser::getRoleMap() const {
+    return mImpl->getRoleMap();
+}
+
+const MediaCodecsXmlParser::RoleMap&
+MediaCodecsXmlParser::Impl::getRoleMap() const {
+    std::lock_guard<std::mutex> guard(mLock);
     if (mRoleMap.empty()) {
         generateRoleMap();
     }
@@ -982,6 +1426,11 @@
 }
 
 const char* MediaCodecsXmlParser::getCommonPrefix() const {
+    return mImpl->getCommonPrefix();
+}
+
+const char* MediaCodecsXmlParser::Impl::getCommonPrefix() const {
+    std::lock_guard<std::mutex> guard(mLock);
     if (mCommonPrefix.empty()) {
         generateCommonPrefix();
     }
@@ -989,14 +1438,18 @@
 }
 
 status_t MediaCodecsXmlParser::getParsingStatus() const {
-    return mParsingStatus;
+    return mImpl->getParsingStatus();
 }
 
-void MediaCodecsXmlParser::generateRoleMap() const {
-    for (const auto& codec : mCodecMap) {
-        const auto& codecName = codec.first;
+void MediaCodecsXmlParser::Impl::generateRoleMap() const {
+    for (const auto& codec : mData.mCodecMap) {
+        const auto &codecName = codec.first;
+        if (codecName == "<dummy>") {
+            continue;
+        }
         bool isEncoder = codec.second.isEncoder;
         size_t order = codec.second.order;
+        std::string rank = codec.second.rank;
         const auto& typeMap = codec.second.typeMap;
         for (const auto& type : typeMap) {
             const auto& typeName = type.first;
@@ -1040,25 +1493,35 @@
 
             NodeInfo nodeInfo;
             nodeInfo.name = codecName;
+            // NOTE: no aliases are exposed in role info
+            // attribute quirks are exposed as node attributes
             nodeInfo.attributeList.reserve(typeAttributeMap.size());
             for (const auto& attribute : typeAttributeMap) {
                 nodeInfo.attributeList.push_back(
                         Attribute{attribute.first, attribute.second});
             }
+            for (const std::string &quirk : codec.second.quirkSet) {
+                if (strHasPrefix(quirk.c_str(), "attribute::")) {
+                    nodeInfo.attributeList.push_back(Attribute{quirk, "present"});
+                }
+            }
+            if (!rank.empty()) {
+                nodeInfo.attributeList.push_back(Attribute{"rank", rank});
+            }
             nodeList->insert(std::make_pair(
                     std::move(order), std::move(nodeInfo)));
         }
     }
 }
 
-void MediaCodecsXmlParser::generateCommonPrefix() const {
-    if (mCodecMap.empty()) {
+void MediaCodecsXmlParser::Impl::generateCommonPrefix() const {
+    if (mData.mCodecMap.empty()) {
         return;
     }
-    auto i = mCodecMap.cbegin();
+    auto i = mData.mCodecMap.cbegin();
     auto first = i->first.cbegin();
     auto last = i->first.cend();
-    for (++i; i != mCodecMap.cend(); ++i) {
+    for (++i; i != mData.mCodecMap.cend(); ++i) {
         last = std::mismatch(
                 first, last, i->first.cbegin(), i->first.cend()).first;
     }
@@ -1066,4 +1529,3 @@
 }
 
 } // namespace android
-
diff --git a/media/libstagefright/xmlparser/api/current.txt b/media/libstagefright/xmlparser/api/current.txt
new file mode 100644
index 0000000..16c8af8
--- /dev/null
+++ b/media/libstagefright/xmlparser/api/current.txt
@@ -0,0 +1,159 @@
+// Signature format: 2.0
+package media.codecs {
+
+  public class Alias {
+    ctor public Alias();
+    method public String getName();
+    method public void setName(String);
+  }
+
+  public class Decoders {
+    ctor public Decoders();
+    method public java.util.List<media.codecs.MediaCodec> getMediaCodec();
+  }
+
+  public class Encoders {
+    ctor public Encoders();
+    method public java.util.List<media.codecs.MediaCodec> getMediaCodec();
+  }
+
+  public class Feature {
+    ctor public Feature();
+    method public String getName();
+    method public String getOptional();
+    method public String getRequired();
+    method public String getValue();
+    method public void setName(String);
+    method public void setOptional(String);
+    method public void setRequired(String);
+    method public void setValue(String);
+  }
+
+  public class Include {
+    ctor public Include();
+    method public String getHref();
+    method public void setHref(String);
+  }
+
+  public class Included {
+    ctor public Included();
+    method public java.util.List<media.codecs.Decoders> getDecoders_optional();
+    method public java.util.List<media.codecs.Encoders> getEncoders_optional();
+    method public java.util.List<media.codecs.Include> getInclude_optional();
+    method public java.util.List<media.codecs.Settings> getSettings_optional();
+  }
+
+  public class Limit {
+    ctor public Limit();
+    method public String getIn();
+    method public String getMax();
+    method public String getMin();
+    method public String getName();
+    method public String getRange();
+    method public String getRanges();
+    method public String getScale();
+    method public String getValue();
+    method public String get_default();
+    method public void setIn(String);
+    method public void setMax(String);
+    method public void setMin(String);
+    method public void setName(String);
+    method public void setRange(String);
+    method public void setRanges(String);
+    method public void setScale(String);
+    method public void setValue(String);
+    method public void set_default(String);
+  }
+
+  public class MediaCodec {
+    ctor public MediaCodec();
+    method public java.util.List<media.codecs.Alias> getAlias_optional();
+    method public java.util.List<media.codecs.Quirk> getAttribute_optional();
+    method public String getDomain();
+    method public String getEnabled();
+    method public java.util.List<media.codecs.Feature> getFeature_optional();
+    method public java.util.List<media.codecs.Limit> getLimit_optional();
+    method public String getName();
+    method public java.util.List<media.codecs.Quirk> getQuirk_optional();
+    method public String getRank();
+    method public String getType();
+    method public java.util.List<media.codecs.Type> getType_optional();
+    method public String getUpdate();
+    method public String getVariant();
+    method public java.util.List<media.codecs.Variant> getVariant_optional();
+    method public void setDomain(String);
+    method public void setEnabled(String);
+    method public void setName(String);
+    method public void setRank(String);
+    method public void setType(String);
+    method public void setUpdate(String);
+    method public void setVariant(String);
+  }
+
+  public class MediaCodecs {
+    ctor public MediaCodecs();
+    method public java.util.List<media.codecs.Decoders> getDecoders_optional();
+    method public java.util.List<media.codecs.Encoders> getEncoders_optional();
+    method public java.util.List<media.codecs.Include> getInclude_optional();
+    method public java.util.List<media.codecs.Settings> getSettings_optional();
+  }
+
+  public class Quirk {
+    ctor public Quirk();
+    method public String getName();
+    method public String getValue();
+    method public void setName(String);
+    method public void setValue(String);
+  }
+
+  public class Setting {
+    ctor public Setting();
+    method public String getEnabled();
+    method public String getName();
+    method public String getUpdate();
+    method public String getValue();
+    method public void setEnabled(String);
+    method public void setName(String);
+    method public void setUpdate(String);
+    method public void setValue(String);
+  }
+
+  public class Settings {
+    ctor public Settings();
+    method public java.util.List<media.codecs.Setting> getDomain_optional();
+    method public java.util.List<media.codecs.Setting> getSetting_optional();
+    method public java.util.List<media.codecs.Setting> getVariant_optional();
+  }
+
+  public class Type {
+    ctor public Type();
+    method public java.util.List<media.codecs.Alias> getAlias();
+    method public java.util.List<media.codecs.Feature> getFeature();
+    method public java.util.List<media.codecs.Limit> getLimit();
+    method public String getName();
+    method public String getUpdate();
+    method public void setName(String);
+    method public void setUpdate(String);
+  }
+
+  public class Variant {
+    ctor public Variant();
+    method public java.util.List<media.codecs.Alias> getAlias_optional();
+    method public java.util.List<media.codecs.Quirk> getAttribute_optional();
+    method public java.util.List<media.codecs.Feature> getFeature_optional();
+    method public java.util.List<media.codecs.Limit> getLimit_optional();
+    method public String getName();
+    method public java.util.List<media.codecs.Quirk> getQuirk_optional();
+    method public void setName(String);
+  }
+
+  public class XmlParser {
+    ctor public XmlParser();
+    method public static media.codecs.Included readIncluded(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static media.codecs.MediaCodecs readMediaCodecs(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+  }
+
+}
+
diff --git a/media/common_time/MODULE_LICENSE_APACHE2 b/media/libstagefright/xmlparser/api/last_current.txt
similarity index 100%
copy from media/common_time/MODULE_LICENSE_APACHE2
copy to media/libstagefright/xmlparser/api/last_current.txt
diff --git a/media/common_time/MODULE_LICENSE_APACHE2 b/media/libstagefright/xmlparser/api/last_removed.txt
similarity index 100%
copy from media/common_time/MODULE_LICENSE_APACHE2
copy to media/libstagefright/xmlparser/api/last_removed.txt
diff --git a/media/libstagefright/xmlparser/api/removed.txt b/media/libstagefright/xmlparser/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/media/libstagefright/xmlparser/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/media/libstagefright/xmlparser/include/media/stagefright/xmlparser/MediaCodecsXmlParser.h b/media/libstagefright/xmlparser/include/media/stagefright/xmlparser/MediaCodecsXmlParser.h
index cc69e52..b666de4 100644
--- a/media/libstagefright/xmlparser/include/media/stagefright/xmlparser/MediaCodecsXmlParser.h
+++ b/media/libstagefright/xmlparser/include/media/stagefright/xmlparser/MediaCodecsXmlParser.h
@@ -19,34 +19,31 @@
 
 #include <sys/types.h>
 #include <utils/Errors.h>
-#include <utils/Vector.h>
-#include <utils/StrongPointer.h>
 
-#include <string>
-#include <set>
 #include <map>
+#include <mutex>
+#include <set>
+#include <string>
 #include <vector>
 
+struct XML_ParserStruct; // from expat library
+
 namespace android {
 
 class MediaCodecsXmlParser {
 public:
 
     // Treblized media codec list will be located in /odm/etc or /vendor/etc.
-    static constexpr char const* defaultSearchDirs[] =
-            {"/odm/etc", "/vendor/etc", "/etc", nullptr};
-    static constexpr char const* defaultMainXmlName =
-            "media_codecs.xml";
-    static constexpr char const* defaultPerformanceXmlName =
-            "media_codecs_performance.xml";
+    static std::vector<std::string> getDefaultSearchDirs() {
+            return { "/odm/etc", "/vendor/etc", "/etc" };
+    }
+    static std::vector<std::string> getDefaultXmlNames() {
+            return { "media_codecs.xml", "media_codecs_performance.xml" };
+    }
     static constexpr char const* defaultProfilingResultsXmlPath =
             "/data/misc/media/media_codecs_profiling_results.xml";
 
-    MediaCodecsXmlParser(
-            const char* const* searchDirs = defaultSearchDirs,
-            const char* mainXmlName = defaultMainXmlName,
-            const char* performanceXmlName = defaultPerformanceXmlName,
-            const char* profilingResultsXmlPath = defaultProfilingResultsXmlPath);
+    MediaCodecsXmlParser();
     ~MediaCodecsXmlParser();
 
     typedef std::pair<std::string, std::string> Attribute;
@@ -55,7 +52,7 @@
     typedef std::pair<std::string, AttributeMap> Type;
     typedef std::map<std::string, AttributeMap> TypeMap;
 
-    typedef std::set<std::string> QuirkSet;
+    typedef std::set<std::string> StringSet;
 
     /**
      * Properties of a codec (node)
@@ -63,8 +60,12 @@
     struct CodecProperties {
         bool isEncoder;    ///< Whether this codec is an encoder or a decoder
         size_t order;      ///< Order of appearance in the file (starting from 0)
-        QuirkSet quirkSet; ///< Set of quirks requested by this codec
+        StringSet quirkSet; ///< Set of quirks requested by this codec
+        StringSet domainSet; ///< Set of domains this codec is in
+        StringSet variantSet; ///< Set of variants this codec is enabled on
         TypeMap typeMap;   ///< Map of types supported by this codec
+        std::vector<std::string> aliases; ///< Name aliases for this codec
+        std::string rank;  ///< Rank of this codec. This is a numeric string.
     };
 
     typedef std::pair<std::string, CodecProperties> Codec;
@@ -76,6 +77,7 @@
     struct NodeInfo {
         std::string name;
         std::vector<Attribute> attributeList;
+        // note: aliases are not exposed here as they are not part of the role map
     };
 
     /**
@@ -116,69 +118,31 @@
 
     status_t getParsingStatus() const;
 
+    /**
+     * Parse top level XML files from a group of search directories.
+     *
+     * @param xmlFiles ordered list of XML file names (no paths)
+     * @param searchDirs ordered list of paths to consider
+     *
+     * @return parsing status
+     */
+    status_t parseXmlFilesInSearchDirs(
+            const std::vector<std::string> &xmlFiles = getDefaultXmlNames(),
+            const std::vector<std::string> &searchDirs = getDefaultSearchDirs());
+
+
+    /**
+     * Parse a top level XML file.
+     *
+     * @param path XML file path
+     *
+     * @return parsing status
+     */
+    status_t parseXmlPath(const std::string &path);
+
 private:
-    enum Section {
-        SECTION_TOPLEVEL,
-        SECTION_SETTINGS,
-        SECTION_DECODERS,
-        SECTION_DECODER,
-        SECTION_DECODER_TYPE,
-        SECTION_ENCODERS,
-        SECTION_ENCODER,
-        SECTION_ENCODER_TYPE,
-        SECTION_INCLUDE,
-    };
-
-    status_t mParsingStatus;
-    Section mCurrentSection;
-    bool mUpdate;
-    std::vector<Section> mSectionStack;
-    std::string mHrefBase;
-
-    // Service attributes
-    AttributeMap mServiceAttributeMap;
-
-    // Codec attributes
-    std::string mCurrentName;
-    std::set<std::string> mCodecSet;
-    Codec mCodecListTemp[2048];
-    CodecMap mCodecMap;
-    size_t mCodecCounter;
-    CodecMap::iterator mCurrentCodec;
-    TypeMap::iterator mCurrentType;
-
-    // Role map
-    mutable RoleMap mRoleMap;
-
-    // Computed longest common prefix
-    mutable std::string mCommonPrefix;
-
-    bool parseTopLevelXMLFile(const char *path, bool ignore_errors = false);
-
-    void parseXMLFile(const char *path);
-
-    static void StartElementHandlerWrapper(
-            void *me, const char *name, const char **attrs);
-
-    static void EndElementHandlerWrapper(void *me, const char *name);
-
-    void startElementHandler(const char *name, const char **attrs);
-    void endElementHandler(const char *name);
-
-    status_t includeXMLFile(const char **attrs);
-    status_t addSettingFromAttributes(const char **attrs);
-    status_t addMediaCodecFromAttributes(bool encoder, const char **attrs);
-    void addMediaCodec(bool encoder, const char *name,
-            const char *type = nullptr);
-
-    status_t addQuirk(const char **attrs);
-    status_t addTypeFromAttributes(const char **attrs, bool encoder);
-    status_t addLimit(const char **attrs);
-    status_t addFeature(const char **attrs);
-    void addType(const char *name);
-
-    void generateRoleMap() const;
-    void generateCommonPrefix() const;
+    struct Impl;
+    std::shared_ptr<Impl> mImpl;
 
     MediaCodecsXmlParser(const MediaCodecsXmlParser&) = delete;
     MediaCodecsXmlParser& operator=(const MediaCodecsXmlParser&) = delete;
@@ -187,4 +151,3 @@
 } // namespace android
 
 #endif // MEDIA_STAGEFRIGHT_XMLPARSER_H_
-
diff --git a/media/libstagefright/xmlparser/media_codecs.xsd b/media/libstagefright/xmlparser/media_codecs.xsd
new file mode 100644
index 0000000..3b5681f
--- /dev/null
+++ b/media/libstagefright/xmlparser/media_codecs.xsd
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+         Licensed under the Apache License, Version 2.0 (the "License");
+         you may not use this file except in compliance with the License.
+         You may obtain a copy of the License at
+
+                    http://www.apache.org/licenses/LICENSE-2.0
+
+         Unless required by applicable law or agreed to in writing, software
+         distributed under the License is distributed on an "AS IS" BASIS,
+         WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+         See the License for the specific language governing permissions and
+         limitations under the License.
+-->
+<!-- TODO: define a targetNamespace. Note that it will break retrocompatibility -->
+<xs:schema version="2.0"
+           elementFormDefault="qualified"
+           attributeFormDefault="unqualified"
+           xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <xs:element name="MediaCodecs">
+        <xs:complexType>
+            <xs:choice minOccurs="0" maxOccurs="unbounded">
+                <xs:element name="Include" type="Include" maxOccurs="unbounded"/>
+                <xs:element name="Settings" type="Settings"/>
+                <xs:element name="Decoders" type="Decoders"/>
+                <xs:element name="Encoders" type="Encoders"/>
+            </xs:choice>
+        </xs:complexType>
+    </xs:element>
+    <xs:element name="Included">
+        <xs:complexType>
+            <xs:choice minOccurs="0" maxOccurs="unbounded">
+                <xs:element name="Include" type="Include" maxOccurs="unbounded"/>
+                <xs:element name="Settings" type="Settings"/>
+                <xs:element name="Decoders" type="Decoders"/>
+                <xs:element name="Encoders" type="Encoders"/>
+            </xs:choice>
+        </xs:complexType>
+    </xs:element>
+    <xs:complexType name="Decoders">
+        <xs:sequence>
+            <xs:element name="MediaCodec" type="MediaCodec" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="Encoders">
+        <xs:sequence>
+            <xs:element name="MediaCodec" type="MediaCodec" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="Settings">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+            <xs:element name="Setting" type="Setting"/>
+            <xs:element name="Variant" type="Setting"/>
+            <xs:element name="Domain" type="Setting"/>
+        </xs:choice>
+    </xs:complexType>
+    <xs:complexType name="MediaCodec">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+            <xs:element name="Quirk" type="Quirk" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="Attribute" type="Quirk" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="Type" type="Type" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="Alias" type="Alias" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="Limit" type="Limit" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="Feature" type="Feature" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="Variant" type="Variant" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string"/>
+        <xs:attribute name="type" type="xs:string"/>
+        <xs:attribute name="update" type="xs:string"/>
+        <xs:attribute name="rank" type="xs:string"/>
+        <xs:attribute name="domain" type="xs:string"/>
+        <xs:attribute name="variant" type="xs:string"/>
+        <xs:attribute name="enabled" type="xs:string"/>
+    </xs:complexType>
+    <xs:complexType name="Quirk">
+        <xs:attribute name="name" type="xs:string"/>
+        <xs:attribute name="value" type="xs:string"/>
+    </xs:complexType>
+    <xs:complexType name="Type">
+        <xs:sequence>
+            <xs:element name="Alias" type="Alias" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="Limit" type="Limit" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="Feature" type="Feature" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+        <xs:attribute name="name" type="xs:string"/>
+        <xs:attribute name="update" type="xs:string"/>
+    </xs:complexType>
+    <xs:complexType name="Alias">
+        <xs:attribute name="name" type="xs:string"/>
+    </xs:complexType>
+    <xs:complexType name="Limit">
+        <xs:attribute name="name" type="xs:string"/>
+        <xs:attribute name="default" type="xs:string"/>
+        <xs:attribute name="in" type="xs:string"/>
+        <xs:attribute name="max" type="xs:string"/>
+        <xs:attribute name="min" type="xs:string"/>
+        <xs:attribute name="range" type="xs:string"/>
+        <xs:attribute name="ranges" type="xs:string"/>
+        <xs:attribute name="scale" type="xs:string"/>
+        <xs:attribute name="value" type="xs:string"/>
+    </xs:complexType>
+    <xs:complexType name="Feature">
+        <xs:attribute name="name" type="xs:string"/>
+        <xs:attribute name="optional" type="xs:string"/>
+        <xs:attribute name="required" type="xs:string"/>
+        <xs:attribute name="value" type="xs:string"/>
+    </xs:complexType>
+    <xs:complexType name="Variant">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+            <xs:element name="Quirk" type="Quirk"/>
+            <xs:element name="Attribute" type="Quirk"/>
+            <xs:element name="Alias" type="Alias"/>
+            <xs:element name="Limit" type="Limit"/>
+            <xs:element name="Feature" type="Feature"/>
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string"/>
+    </xs:complexType>
+    <xs:complexType name="Setting">
+        <xs:attribute name="name" type="xs:string"/>
+        <xs:attribute name="value" type="xs:string"/>
+        <xs:attribute name="enabled" type="xs:string"/>
+        <xs:attribute name="update" type="xs:string"/>
+    </xs:complexType>
+    <xs:complexType name="Include">
+        <xs:attribute name="href" type="xs:string"/>
+    </xs:complexType>
+</xs:schema>
diff --git a/media/libstagefright/xmlparser/vts/Android.bp b/media/libstagefright/xmlparser/vts/Android.bp
new file mode 100644
index 0000000..3f93e9e
--- /dev/null
+++ b/media/libstagefright/xmlparser/vts/Android.bp
@@ -0,0 +1,33 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+    name: "vts_mediaCodecs_validate_test",
+    srcs: [
+        "ValidateMediaCodecs.cpp"
+    ],
+    static_libs: [
+        "android.hardware.audio.common.test.utility",
+        "libxml2",
+    ],
+    shared_libs: [
+        "liblog",
+    ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+}
diff --git a/media/libstagefright/xmlparser/vts/Android.mk b/media/libstagefright/xmlparser/vts/Android.mk
new file mode 100644
index 0000000..d5290ba
--- /dev/null
+++ b/media/libstagefright/xmlparser/vts/Android.mk
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := VtsValidateMediaCodecs
+include test/vts/tools/build/Android.host_config.mk
diff --git a/media/libstagefright/xmlparser/vts/AndroidTest.xml b/media/libstagefright/xmlparser/vts/AndroidTest.xml
new file mode 100644
index 0000000..97ee107
--- /dev/null
+++ b/media/libstagefright/xmlparser/vts/AndroidTest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for VTS VtsValidateMediaCodecs.">
+    <option name="config-descriptor:metadata" key="plan" value="vts-treble" />
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
+        <option name="abort-on-push-failure" value="false"/>
+        <option name="push-group" value="HostDrivenTest.push"/>
+        <option name="push" value="DATA/etc/media_codecs.xsd->/data/local/tmp/media_codecs.xsd"/>
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
+        <option name="test-module-name" value="VtsValidateMediaCodecs"/>
+        <option name="binary-test-source" value="_32bit::DATA/nativetest/vts_mediaCodecs_validate_test/vts_mediaCodecs_validate_test" />
+        <option name="binary-test-source" value="_64bit::DATA/nativetest64/vts_mediaCodecs_validate_test/vts_mediaCodecs_validate_test" />
+        <option name="binary-test-type" value="gtest"/>
+        <option name="test-timeout" value="30s"/>
+    </test>
+</configuration>
diff --git a/media/libstagefright/xmlparser/vts/ValidateMediaCodecs.cpp b/media/libstagefright/xmlparser/vts/ValidateMediaCodecs.cpp
new file mode 100644
index 0000000..b07833e
--- /dev/null
+++ b/media/libstagefright/xmlparser/vts/ValidateMediaCodecs.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dirent.h>
+#include <regex>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string>
+
+#include "utility/ValidateXml.h"
+
+static void get_files_in_dirs(const char* dir_path, std::vector<std::string>& files) {
+    DIR* d;
+    struct dirent* de;
+
+    d = opendir(dir_path);
+    if (d == nullptr) {
+        return;
+    }
+
+    while ((de = readdir(d))) {
+        if (de->d_type != DT_REG) {
+            continue;
+        }
+        if (std::regex_match(de->d_name, std::regex("(media_codecs)(.*)(.xml)"))) {
+            files.push_back(de->d_name);
+        }
+    }
+    closedir(d);
+}
+
+TEST(CheckConfig, mediaCodecsValidation) {
+    RecordProperty("description",
+                   "Verify that the media codecs file "
+                   "is valid according to the schema");
+
+    const char* location = "/vendor/etc";
+
+    std::vector<std::string> files;
+    get_files_in_dirs(location, files);
+
+    for (std::string file_name : files) {
+        EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS(file_name.c_str(), {location},
+                                                "/data/local/tmp/media_codecs.xsd");
+    }
+}
diff --git a/media/mediaserver/Android.bp b/media/mediaserver/Android.bp
new file mode 100644
index 0000000..a968890
--- /dev/null
+++ b/media/mediaserver/Android.bp
@@ -0,0 +1,47 @@
+
+cc_library_static {
+    name: "libregistermsext",
+    srcs: ["register.cpp"],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+}
+
+cc_binary {
+    name: "mediaserver",
+
+    srcs: ["main_mediaserver.cpp"],
+
+    shared_libs: [
+        "libresourcemanagerservice",
+        "liblog",
+        "libmediaplayerservice",
+        "libutils",
+        "libbinder",
+        "libandroidicu",
+        "android.hardware.media.omx@1.0",
+    ],
+
+    static_libs: [
+        "libregistermsext",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/libmediaplayerservice",
+        "frameworks/av/services/mediaresourcemanager",
+    ],
+
+    // back to 32-bit, b/126502613
+    compile_multilib: "32",
+
+    init_rc: ["mediaserver.rc"],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+
+    vintf_fragments: ["manifest_media_c2_software.xml"],
+}
diff --git a/media/mediaserver/Android.mk b/media/mediaserver/Android.mk
deleted file mode 100644
index f7597db..0000000
--- a/media/mediaserver/Android.mk
+++ /dev/null
@@ -1,41 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-ifneq ($(BOARD_USE_CUSTOM_MEDIASERVEREXTENSIONS),true)
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := register.cpp
-LOCAL_MODULE := libregistermsext
-LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS := -Werror -Wall
-include $(BUILD_STATIC_LIBRARY)
-endif
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-        main_mediaserver.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-        libresourcemanagerservice \
-        liblog \
-        libmediaplayerservice \
-        libutils \
-        libbinder \
-        libicuuc \
-        android.hardware.media.omx@1.0 \
-
-LOCAL_STATIC_LIBRARIES := \
-        libicuandroid_utils \
-        libregistermsext
-
-LOCAL_C_INCLUDES := \
-        frameworks/av/media/libmediaplayerservice \
-        frameworks/av/services/mediaresourcemanager \
-
-LOCAL_MODULE:= mediaserver
-LOCAL_32_BIT_ONLY := true
-
-LOCAL_INIT_RC := mediaserver.rc
-
-LOCAL_CFLAGS := -Werror -Wall
-
-include $(BUILD_EXECUTABLE)
diff --git a/media/mediaserver/main_mediaserver.cpp b/media/mediaserver/main_mediaserver.cpp
index ecddc48..7b22b05 100644
--- a/media/mediaserver/main_mediaserver.cpp
+++ b/media/mediaserver/main_mediaserver.cpp
@@ -18,6 +18,7 @@
 #define LOG_TAG "mediaserver"
 //#define LOG_NDEBUG 0
 
+#include <aicu/AIcu.h>
 #include <binder/IPCThreadState.h>
 #include <binder/ProcessState.h>
 #include <binder/IServiceManager.h>
@@ -25,7 +26,6 @@
 #include "RegisterExtensions.h"
 
 // from LOCAL_C_INCLUDES
-#include "IcuUtils.h"
 #include "MediaPlayerService.h"
 #include "ResourceManagerService.h"
 
@@ -38,7 +38,7 @@
     sp<ProcessState> proc(ProcessState::self());
     sp<IServiceManager> sm(defaultServiceManager());
     ALOGI("ServiceManager: %p", sm.get());
-    InitializeIcuOrDie();
+    AIcu_initializeIcuOrDie();
     MediaPlayerService::instantiate();
     ResourceManagerService::instantiate();
     registerExtensions();
diff --git a/media/mediaserver/manifest_media_c2_software.xml b/media/mediaserver/manifest_media_c2_software.xml
new file mode 100644
index 0000000..5196336
--- /dev/null
+++ b/media/mediaserver/manifest_media_c2_software.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="framework">
+    <hal>
+        <name>android.hardware.media.c2</name>
+        <transport>hwbinder</transport>
+        <version>1.0</version>
+        <interface>
+            <name>IComponentStore</name>
+            <instance>software</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/media/mtp/Android.bp b/media/mtp/Android.bp
index 2cf9b82..66a3139 100644
--- a/media/mtp/Android.bp
+++ b/media/mtp/Android.bp
@@ -54,6 +54,3 @@
     ],
 }
 
-subdirs = [
-    "tests",
-]
diff --git a/media/mtp/IMtpDatabase.h b/media/mtp/IMtpDatabase.h
index 1245092..81fa60c 100644
--- a/media/mtp/IMtpDatabase.h
+++ b/media/mtp/IMtpDatabase.h
@@ -112,8 +112,8 @@
                                             MtpObjectHandle handle, bool succeeded) = 0;
 
     virtual MtpResponseCode         beginCopyObject(MtpObjectHandle handle, MtpObjectHandle newParent,
-                                            MtpStorageID newStorage);
-    virtual void                    endCopyObject(MtpObjectHandle handle, bool succeeded);
+                                            MtpStorageID newStorage) = 0;
+    virtual void                    endCopyObject(MtpObjectHandle handle, bool succeeded) = 0;
 };
 
 }; // namespace android
diff --git a/media/mtp/MtpDataPacket.cpp b/media/mtp/MtpDataPacket.cpp
index 992dc9a..5dbcd08 100644
--- a/media/mtp/MtpDataPacket.cpp
+++ b/media/mtp/MtpDataPacket.cpp
@@ -561,7 +561,7 @@
     return processedBytes == mPacketSize ? processedBytes : -1;
 }
 
-int MtpDataPacket::write(struct usb_request *request,
+int64_t MtpDataPacket::write(struct usb_request *request,
                          UrbPacketDivisionMode divisionMode,
                          int fd,
                          size_t payloadSize) {
diff --git a/media/mtp/MtpDataPacket.h b/media/mtp/MtpDataPacket.h
index 1ddb821..138f7b0 100644
--- a/media/mtp/MtpDataPacket.h
+++ b/media/mtp/MtpDataPacket.h
@@ -117,7 +117,8 @@
     int                 write(struct usb_request *request, UrbPacketDivisionMode divisionMode);
     // Similar to previous write method but it reads the payload from |fd|. If |size| is larger than
     // MTP_BUFFER_SIZE, the data will be sent by multiple bulk transfer requests.
-    int                 write(struct usb_request *request, UrbPacketDivisionMode divisionMode,
+    // Return type (int64_t) is used to handle the case that the size can be larger than 2GB.
+    int64_t             write(struct usb_request *request, UrbPacketDivisionMode divisionMode,
                               int fd, size_t size);
 #endif
 
diff --git a/media/mtp/MtpDevice.cpp b/media/mtp/MtpDevice.cpp
index 993797a..9665c58 100644
--- a/media/mtp/MtpDevice.cpp
+++ b/media/mtp/MtpDevice.cpp
@@ -516,7 +516,7 @@
     return (MtpObjectHandle)-1;
 }
 
-bool MtpDevice::sendObject(MtpObjectHandle handle, int size, int srcFD) {
+bool MtpDevice::sendObject(MtpObjectHandle handle, uint32_t size, int srcFD) {
     std::lock_guard<std::mutex> lg(mMutex);
 
     if (mLastSendObjectInfoTransactionID + 1 != mTransactionID ||
@@ -529,7 +529,7 @@
     if (sendRequest(MTP_OPERATION_SEND_OBJECT)) {
         mData.setOperationCode(mRequest.getOperationCode());
         mData.setTransactionID(mRequest.getTransactionID());
-        const int writeResult = mData.write(mRequestOut, mPacketDivisionMode, srcFD, size);
+        const int64_t writeResult = mData.write(mRequestOut, mPacketDivisionMode, srcFD, size);
         const MtpResponseCode ret = readResponse();
         return ret == MTP_RESPONSE_OK && writeResult > 0;
     }
diff --git a/media/mtp/MtpDevice.h b/media/mtp/MtpDevice.h
index 8cf9e5e..01bc3db 100644
--- a/media/mtp/MtpDevice.h
+++ b/media/mtp/MtpDevice.h
@@ -104,7 +104,7 @@
     MtpObjectInfo*          getObjectInfo(MtpObjectHandle handle);
     void*                   getThumbnail(MtpObjectHandle handle, int& outLength);
     MtpObjectHandle         sendObjectInfo(MtpObjectInfo* info);
-    bool                    sendObject(MtpObjectHandle handle, int size, int srcFD);
+    bool                    sendObject(MtpObjectHandle handle, uint32_t size, int srcFD);
     bool                    deleteObject(MtpObjectHandle handle);
     MtpObjectHandle         getParent(MtpObjectHandle handle);
     MtpStorageID            getStorageID(MtpObjectHandle handle);
diff --git a/media/mtp/MtpFfsHandle.cpp b/media/mtp/MtpFfsHandle.cpp
index f25fc71..bd6a6c6 100644
--- a/media/mtp/MtpFfsHandle.cpp
+++ b/media/mtp/MtpFfsHandle.cpp
@@ -47,6 +47,9 @@
 constexpr unsigned MAX_FILE_CHUNK_SIZE = AIO_BUFS_MAX * AIO_BUF_LEN;
 
 constexpr uint32_t MAX_MTP_FILE_SIZE = 0xFFFFFFFF;
+// Note: POLL_TIMEOUT_MS = 0 means return immediately i.e. no sleep.
+// And this will cause high CPU usage.
+constexpr int32_t POLL_TIMEOUT_MS = 500;
 
 struct timespec ZERO_TIMEOUT = { 0, 0 };
 
@@ -212,7 +215,6 @@
     uint16_t value = setup->wValue;
     std::vector<char> buf;
     buf.resize(length);
-    int ret = 0;
 
     if (!(type & USB_DIR_IN)) {
         if (::read(mControl, buf.data(), length) != length) {
@@ -225,8 +227,8 @@
         case MTP_REQ_RESET:
         case MTP_REQ_CANCEL:
             errno = ECANCELED;
-            ret = -1;
-            break;
+            return -1;
+        //    break;
         case MTP_REQ_GET_DEVICE_STATUS:
         {
             if (length < sizeof(struct mtp_device_status) + 4) {
@@ -306,7 +308,7 @@
     int error = 0;
 
     while (num_events < min_events) {
-        if (poll(mPollFds, 2, 0) == -1) {
+        if (poll(mPollFds, 2, POLL_TIMEOUT_MS) == -1) {
             PLOG(ERROR) << "Mtp error during poll()";
             return -1;
         }
diff --git a/media/mtp/MtpPacket.cpp b/media/mtp/MtpPacket.cpp
index 3dd4248..3b298a9 100644
--- a/media/mtp/MtpPacket.cpp
+++ b/media/mtp/MtpPacket.cpp
@@ -157,7 +157,7 @@
                             request->endpoint,
                             request->buffer,
                             request->buffer_length,
-                            0);
+                            1000);
     request->actual_length = result;
     return result;
 }
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index ccddd6e..ca8cb78 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -99,6 +99,7 @@
     MTP_EVENT_STORE_ADDED,
     MTP_EVENT_STORE_REMOVED,
     MTP_EVENT_DEVICE_PROP_CHANGED,
+    MTP_EVENT_OBJECT_INFO_CHANGED,
 };
 
 MtpServer::MtpServer(IMtpDatabase* database, int controlFd, bool ptp,
@@ -259,6 +260,11 @@
     sendEvent(MTP_EVENT_OBJECT_REMOVED, handle);
 }
 
+void MtpServer::sendObjectInfoChanged(MtpObjectHandle handle) {
+    ALOGV("sendObjectInfoChanged %d\n", handle);
+    sendEvent(MTP_EVENT_OBJECT_INFO_CHANGED, handle);
+}
+
 void MtpServer::sendStoreAdded(MtpStorageID id) {
     ALOGV("sendStoreAdded %08X\n", id);
     sendEvent(MTP_EVENT_STORE_ADDED, id);
@@ -442,6 +448,9 @@
             break;
     }
 
+    if (response != MTP_RESPONSE_OK)
+      ALOGW("[MTP] got response 0x%X in command %s (%x)", response,
+            MtpDebug::getOperationCodeName(operation), operation);
     if (response == MTP_RESPONSE_TRANSACTION_CANCELLED)
         return false;
     mResponse.setResponseCode(response);
@@ -652,8 +661,8 @@
         return MTP_RESPONSE_INVALID_PARAMETER;
     MtpObjectHandle handle = mRequest.getParameter(1);
     MtpObjectProperty property = mRequest.getParameter(2);
-    ALOGV("GetObjectPropValue %d %s\n", handle,
-            MtpDebug::getObjectPropCodeName(property));
+    ALOGV("GetObjectPropValue %d %s (0x%04X)\n", handle,
+          MtpDebug::getObjectPropCodeName(property), property);
 
     return mDatabase->getObjectPropertyValue(handle, property, mData);
 }
@@ -946,7 +955,8 @@
     if (!mData.getString(modified)) return MTP_RESPONSE_INVALID_PARAMETER;     // date modified
     // keywords follow
 
-    ALOGV("name: %s format: %04X\n", (const char *)name, format);
+    ALOGV("name: %s format: 0x%04X (%s)\n", (const char*)name, format,
+          MtpDebug::getFormatCodeName(format));
     time_t modifiedTime;
     if (!parseDateTime(modified, modifiedTime))
         modifiedTime = 0;
@@ -967,9 +977,10 @@
             return MTP_RESPONSE_OBJECT_TOO_LARGE;
     }
 
-    ALOGD("path: %s parent: %d storageID: %08X", (const char*)path, parent, storageID);
+    ALOGV("path: %s parent: %d storageID: %08X", (const char*)path, parent, storageID);
     MtpObjectHandle handle = mDatabase->beginSendObject((const char*)path, format,
             parent, storageID);
+    ALOGD("handle: %d, parent: %d, storageID: %08X", handle, parent, storageID);
     if (handle == kInvalidObjectHandle) {
         return MTP_RESPONSE_GENERAL_ERROR;
     }
diff --git a/media/mtp/MtpServer.h b/media/mtp/MtpServer.h
index f6939d7..1f8799f 100644
--- a/media/mtp/MtpServer.h
+++ b/media/mtp/MtpServer.h
@@ -115,6 +115,7 @@
 
     void                sendObjectAdded(MtpObjectHandle handle);
     void                sendObjectRemoved(MtpObjectHandle handle);
+    void                sendObjectInfoChanged(MtpObjectHandle handle);
     void                sendDevicePropertyChanged(MtpDeviceProperty property);
 
 private:
diff --git a/media/mtp/OWNERS b/media/mtp/OWNERS
index 219307b..1928ba8 100644
--- a/media/mtp/OWNERS
+++ b/media/mtp/OWNERS
@@ -1 +1,7 @@
-zhangjerry@google.com
+set noparent
+
+marcone@google.com
+jsharkey@android.com
+jameswei@google.com
+rmojumder@google.com
+
diff --git a/media/mtp/PosixAsyncIO.cpp b/media/mtp/PosixAsyncIO.cpp
index e67c568..72c07cc 100644
--- a/media/mtp/PosixAsyncIO.cpp
+++ b/media/mtp/PosixAsyncIO.cpp
@@ -15,42 +15,109 @@
  */
 
 #include <android-base/logging.h>
-#include <condition_variable>
 #include <memory>
-#include <mutex>
+#include <pthread.h>
 #include <queue>
+#include <thread>
 #include <unistd.h>
 
 #include "PosixAsyncIO.h"
 
 namespace {
 
-void read_func(struct aiocb *aiocbp) {
-    aiocbp->ret = TEMP_FAILURE_RETRY(pread(aiocbp->aio_fildes,
-                aiocbp->aio_buf, aiocbp->aio_nbytes, aiocbp->aio_offset));
-    if (aiocbp->ret == -1) aiocbp->error = errno;
+std::thread gWorkerThread;
+std::deque<struct aiocb*> gWorkQueue;
+bool gSuspended = true;
+int gAiocbRefcount = 0;
+std::mutex gLock;
+std::condition_variable gWait;
+
+void work_func(void *) {
+    pthread_setname_np(pthread_self(), "AsyncIO work");
+    while (true) {
+        struct aiocb *aiocbp;
+        {
+            std::unique_lock<std::mutex> lk(gLock);
+            gWait.wait(lk, []{return gWorkQueue.size() > 0 || gSuspended;});
+            if (gSuspended)
+                return;
+            aiocbp = gWorkQueue.back();
+            gWorkQueue.pop_back();
+        }
+        CHECK(aiocbp->queued);
+        int ret;
+        if (aiocbp->read) {
+            ret = TEMP_FAILURE_RETRY(pread(aiocbp->aio_fildes,
+                    aiocbp->aio_buf, aiocbp->aio_nbytes, aiocbp->aio_offset));
+        } else {
+            ret = TEMP_FAILURE_RETRY(pwrite(aiocbp->aio_fildes,
+               aiocbp->aio_buf, aiocbp->aio_nbytes, aiocbp->aio_offset));
+        }
+        {
+            std::unique_lock<std::mutex> lk(aiocbp->lock);
+            aiocbp->ret = ret;
+            if (aiocbp->ret == -1) {
+                aiocbp->error = errno;
+            }
+            aiocbp->queued = false;
+        }
+        aiocbp->cv.notify_all();
+    }
 }
 
-void write_func(struct aiocb *aiocbp) {
-    aiocbp->ret = TEMP_FAILURE_RETRY(pwrite(aiocbp->aio_fildes,
-                aiocbp->aio_buf, aiocbp->aio_nbytes, aiocbp->aio_offset));
-    if (aiocbp->ret == -1) aiocbp->error = errno;
+int aio_add(struct aiocb *aiocbp) {
+    CHECK(!aiocbp->queued);
+    aiocbp->queued = true;
+    {
+        std::unique_lock<std::mutex> lk(gLock);
+        gWorkQueue.push_front(aiocbp);
+    }
+    gWait.notify_one();
+    return 0;
 }
 
 } // end anonymous namespace
 
+aiocb::aiocb() {
+    this->ret = 0;
+    this->queued = false;
+    {
+        std::unique_lock<std::mutex> lk(gLock);
+        if (gAiocbRefcount == 0) {
+            CHECK(gWorkQueue.size() == 0);
+            CHECK(gSuspended);
+            gSuspended = false;
+            gWorkerThread = std::thread(work_func, nullptr);
+        }
+        gAiocbRefcount++;
+    }
+}
+
 aiocb::~aiocb() {
-    CHECK(!thread.joinable());
+    CHECK(!this->queued);
+    {
+        std::unique_lock<std::mutex> lk(gLock);
+        CHECK(!gSuspended);
+        if (gAiocbRefcount == 1) {
+            CHECK(gWorkQueue.size() == 0);
+            gSuspended = true;
+            lk.unlock();
+            gWait.notify_one();
+            gWorkerThread.join();
+            lk.lock();
+        }
+        gAiocbRefcount--;
+    }
 }
 
 int aio_read(struct aiocb *aiocbp) {
-    aiocbp->thread = std::thread(read_func, aiocbp);
-    return 0;
+    aiocbp->read = true;
+    return aio_add(aiocbp);
 }
 
 int aio_write(struct aiocb *aiocbp) {
-    aiocbp->thread = std::thread(write_func, aiocbp);
-    return 0;
+    aiocbp->read = false;
+    return aio_add(aiocbp);
 }
 
 int aio_error(const struct aiocb *aiocbp) {
@@ -64,7 +131,10 @@
 int aio_suspend(struct aiocb *aiocbp[], int n,
         const struct timespec *) {
     for (int i = 0; i < n; i++) {
-        aiocbp[i]->thread.join();
+        {
+            std::unique_lock<std::mutex> lk(aiocbp[i]->lock);
+            aiocbp[i]->cv.wait(lk, [aiocbp, i]{return !aiocbp[i]->queued;});
+        }
     }
     return 0;
 }
diff --git a/media/mtp/PosixAsyncIO.h b/media/mtp/PosixAsyncIO.h
index 590aaef..2bb5735 100644
--- a/media/mtp/PosixAsyncIO.h
+++ b/media/mtp/PosixAsyncIO.h
@@ -17,10 +17,11 @@
 #ifndef _POSIXASYNCIO_H
 #define _POSIXASYNCIO_H
 
+#include <condition_variable>
+#include <mutex>
 #include <sys/cdefs.h>
 #include <sys/types.h>
 #include <time.h>
-#include <thread>
 #include <unistd.h>
 
 /**
@@ -35,10 +36,15 @@
     size_t aio_nbytes;
 
     // Used internally
-    std::thread thread;
+    bool read;
+    bool queued;
     ssize_t ret;
     int error;
 
+    std::mutex lock;
+    std::condition_variable cv;
+
+    aiocb();
     ~aiocb();
 };
 
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index 4a36681..a3cabd8 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -31,6 +31,13 @@
     license: "NOTICE",
 }
 
+// for use with header_libs
+cc_library_headers {
+    name: "media_ndk_headers",
+    vendor_available: true,
+    export_include_dirs: ["include"]
+}
+
 cc_library_shared {
     name: "libmediandk",
 
@@ -54,9 +61,7 @@
     ],
 
     cflags: [
-        "-fvisibility=hidden",
         "-DEXPORT=__attribute__((visibility(\"default\")))",
-
         "-Werror",
         "-Wall",
     ],
@@ -66,35 +71,111 @@
     ],
 
     shared_libs: [
+        "android.hardware.graphics.bufferqueue@1.0",
+        "android.hidl.token@1.0-utils",
+        "libandroid_runtime_lazy",
+        "libbase",
         "libbinder",
         "libmedia",
         "libmedia_omx",
-        "libmedia_jni",
+        "libmedia_jni_utils",
         "libmediadrm",
-        "libmediaextractor",
         "libstagefright",
         "libstagefright_foundation",
         "liblog",
         "libutils",
         "libcutils",
-        "libandroid",
-        "libandroid_runtime",
+        "libnativewindow",
         "libbinder",
+        "libhidlbase",
         "libgui",
         "libui",
+        "libmedia2_jni_core",
+        "libmediandk_utils",
     ],
 
     export_include_dirs: ["include"],
 
+    export_shared_lib_headers: [
+        "libgui",
+    ],
+
     product_variables: {
         pdk: {
             enabled: false,
         },
     },
+    version_script: "libmediandk.map.txt",
+    stubs: {
+        symbol_file: "libmediandk.map.txt",
+        versions: ["29"],
+    },
+
+    // Bug: http://b/124522995 libmediandk has linker errors when built with
+    // coverage
+    native_coverage: false,
 }
 
 llndk_library {
     name: "libmediandk",
     symbol_file: "libmediandk.map.txt",
-    export_include_dirs: ["include"],
+    export_include_dirs: [
+        "include",
+    ],
+}
+
+cc_library {
+    name: "libmediandk_utils",
+
+    srcs: [
+        "NdkMediaDataSourceCallbacks.cpp",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/libstagefright/include",
+        "frameworks/av/media/ndk/include",
+    ],
+
+    export_include_dirs: [
+        "include",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wno-error=deprecated-declarations",
+        "-Wall",
+    ],
+
+    shared_libs: [
+    ],
+
+    sanitize: {
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+        cfi: true,
+    },
+}
+
+cc_test {
+    name: "AImageReaderWindowHandleTest",
+    srcs: ["tests/AImageReaderWindowHandleTest.cpp"],
+    shared_libs: [
+        "libbinder",
+        "libmediandk",
+        "libmediautils",
+        "libnativewindow",
+        "libgui",
+        "libutils",
+        "libui",
+        "libcutils",
+        "android.hardware.graphics.bufferqueue@1.0",
+    ],
+    cflags: [
+        "-D__ANDROID_VNDK__",
+    ],
+    include_dirs: [
+        "frameworks/av/media/ndk/",
+    ],
 }
diff --git a/media/ndk/NdkImage.cpp b/media/ndk/NdkImage.cpp
index 20b1667..1883f63 100644
--- a/media/ndk/NdkImage.cpp
+++ b/media/ndk/NdkImage.cpp
@@ -23,7 +23,7 @@
 #include "NdkImageReaderPriv.h"
 
 #include <android_media_Utils.h>
-#include <android_runtime/android_hardware_HardwareBuffer.h>
+#include <private/android/AHardwareBufferHelpers.h>
 #include <utils/Log.h>
 #include "hardware/camera3.h"
 
@@ -190,7 +190,7 @@
 
     auto lockedBuffer = std::make_unique<CpuConsumer::LockedBuffer>();
 
-    uint64_t grallocUsage = android_hardware_HardwareBuffer_convertToGrallocUsageBits(mUsage);
+    uint64_t grallocUsage = AHardwareBuffer_convertToGrallocUsageBits(mUsage);
 
     status_t ret =
             lockImageFromBuffer(mBuffer, grallocUsage, mBuffer->mFence->dup(), lockedBuffer.get());
diff --git a/media/ndk/NdkImageReader.cpp b/media/ndk/NdkImageReader.cpp
index be635ff..baa4fc7 100644
--- a/media/ndk/NdkImageReader.cpp
+++ b/media/ndk/NdkImageReader.cpp
@@ -21,13 +21,15 @@
 
 #include "NdkImagePriv.h"
 #include "NdkImageReaderPriv.h"
+#include <private/media/NdkImage.h>
 
 #include <cutils/atomic.h>
 #include <utils/Log.h>
 #include <android_media_Utils.h>
-#include <android_runtime/android_view_Surface.h>
-#include <android_runtime/android_hardware_HardwareBuffer.h>
+#include <ui/PublicFormat.h>
+#include <private/android/AHardwareBufferHelpers.h>
 #include <grallocusage/GrallocUsageConversion.h>
+#include <gui/bufferqueue/1.0/WGraphicBufferProducer.h>
 
 using namespace android;
 
@@ -43,6 +45,10 @@
 const char* AImageReader::kContextKey    = "Context";
 const char* AImageReader::kGraphicBufferKey = "GraphicBuffer";
 
+static constexpr int kWindowHalTokenSizeMax = 256;
+
+static native_handle_t *convertHalTokenToNativeHandle(const HalToken &halToken);
+
 bool
 AImageReader::isSupportedFormatAndUsage(int32_t format, uint64_t usage) {
     // Check whether usage has either CPU_READ_OFTEN or CPU_READ set. Note that check against
@@ -58,11 +64,15 @@
         case AIMAGE_FORMAT_YUV_420_888:
         case AIMAGE_FORMAT_JPEG:
         case AIMAGE_FORMAT_RAW16:
+        case AIMAGE_FORMAT_RAW_DEPTH:
         case AIMAGE_FORMAT_RAW_PRIVATE:
         case AIMAGE_FORMAT_RAW10:
         case AIMAGE_FORMAT_RAW12:
         case AIMAGE_FORMAT_DEPTH16:
         case AIMAGE_FORMAT_DEPTH_POINT_CLOUD:
+        case AIMAGE_FORMAT_Y8:
+        case AIMAGE_FORMAT_HEIC:
+        case AIMAGE_FORMAT_DEPTH_JPEG:
             return true;
         case AIMAGE_FORMAT_PRIVATE:
             // For private format, cpu usage is prohibited.
@@ -84,11 +94,15 @@
         case AIMAGE_FORMAT_RGBA_FP16:
         case AIMAGE_FORMAT_JPEG:
         case AIMAGE_FORMAT_RAW16:
+        case AIMAGE_FORMAT_RAW_DEPTH:
         case AIMAGE_FORMAT_RAW_PRIVATE:
         case AIMAGE_FORMAT_RAW10:
         case AIMAGE_FORMAT_RAW12:
         case AIMAGE_FORMAT_DEPTH16:
         case AIMAGE_FORMAT_DEPTH_POINT_CLOUD:
+        case AIMAGE_FORMAT_Y8:
+        case AIMAGE_FORMAT_HEIC:
+        case AIMAGE_FORMAT_DEPTH_JPEG:
             return 1;
         case AIMAGE_FORMAT_PRIVATE:
             return 0;
@@ -261,9 +275,9 @@
 media_status_t
 AImageReader::init() {
     PublicFormat publicFormat = static_cast<PublicFormat>(mFormat);
-    mHalFormat = android_view_Surface_mapPublicFormatToHalFormat(publicFormat);
-    mHalDataSpace = android_view_Surface_mapPublicFormatToHalDataspace(publicFormat);
-    mHalUsage = android_hardware_HardwareBuffer_convertToGrallocUsageBits(mUsage);
+    mHalFormat = mapPublicFormatToHalFormat(publicFormat);
+    mHalDataSpace = mapPublicFormatToHalDataspace(publicFormat);
+    mHalUsage = AHardwareBuffer_convertToGrallocUsageBits(mUsage);
 
     sp<IGraphicBufferProducer> gbProducer;
     sp<IGraphicBufferConsumer> gbConsumer;
@@ -301,6 +315,9 @@
         ALOGE("Failed to set BufferItemConsumer buffer dataSpace");
         return AMEDIA_ERROR_UNKNOWN;
     }
+    if (mUsage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT) {
+        gbConsumer->setConsumerIsProtected(true);
+    }
 
     mSurface = new Surface(mProducer, /*controlledByApp*/true);
     if (mSurface == nullptr) {
@@ -350,8 +367,10 @@
               it != mAcquiredImages.end(); it++) {
         AImage* image = *it;
         Mutex::Autolock _l(image->mLock);
-        releaseImageLocked(image, /*releaseFenceFd*/-1);
+        // Do not alter mAcquiredImages while we are iterating on it
+        releaseImageLocked(image, /*releaseFenceFd*/-1, /*clearCache*/false);
     }
+    mAcquiredImages.clear();
 
     // Delete Buffer Items
     for (auto it = mBuffers.begin();
@@ -363,6 +382,15 @@
         mBufferItemConsumer->abandon();
         mBufferItemConsumer->setFrameAvailableListener(nullptr);
     }
+
+    if (mWindowHandle != nullptr) {
+        int size = mWindowHandle->data[0];
+        hidl_vec<uint8_t> halToken;
+        halToken.setToExternal(
+            reinterpret_cast<uint8_t *>(&mWindowHandle->data[1]), size);
+        deleteHalToken(halToken);
+        native_handle_delete(mWindowHandle);
+    }
 }
 
 media_status_t
@@ -481,7 +509,7 @@
 }
 
 void
-AImageReader::releaseImageLocked(AImage* image, int releaseFenceFd) {
+AImageReader::releaseImageLocked(AImage* image, int releaseFenceFd, bool clearCache) {
     BufferItem* buffer = image->mBuffer;
     if (buffer == nullptr) {
         // This should not happen, but is not fatal
@@ -505,6 +533,10 @@
     image->mLockedBuffer = nullptr;
     image->mIsClosed = true;
 
+    if (!clearCache) {
+        return;
+    }
+
     bool found = false;
     // cleanup acquired image list
     for (auto it = mAcquiredImages.begin();
@@ -522,6 +554,25 @@
     }
 }
 
+media_status_t AImageReader::getWindowNativeHandle(native_handle **handle) {
+    if (mWindowHandle != nullptr) {
+        *handle = mWindowHandle;
+        return AMEDIA_OK;
+    }
+    sp<HGraphicBufferProducer> hgbp =
+        new TWGraphicBufferProducer<HGraphicBufferProducer>(mProducer);
+    HalToken halToken;
+    if (!createHalToken(hgbp, &halToken)) {
+        return AMEDIA_ERROR_UNKNOWN;
+    }
+    mWindowHandle = convertHalTokenToNativeHandle(halToken);
+    if (!mWindowHandle) {
+        return AMEDIA_ERROR_UNKNOWN;
+    }
+    *handle = mWindowHandle;
+    return AMEDIA_OK;
+}
+
 int
 AImageReader::getBufferWidth(BufferItem* buffer) {
     if (buffer == NULL) return -1;
@@ -585,6 +636,33 @@
     }
 }
 
+static native_handle_t *convertHalTokenToNativeHandle(
+        const HalToken &halToken) {
+    // We attempt to store halToken in the ints of the native_handle_t after its
+    // size. The first int stores the size of the token. We store this in an int
+    // to avoid alignment issues where size_t and int do not have the same
+    // alignment.
+    size_t nhDataByteSize = halToken.size();
+    if (nhDataByteSize > kWindowHalTokenSizeMax) {
+        // The size of the token isn't reasonable..
+        return nullptr;
+    }
+    size_t numInts = ceil(nhDataByteSize / sizeof(int)) + 1;
+
+    // We don't check for overflow, whether numInts can fit in an int, since we
+    // expect kWindowHalTokenSizeMax to be a reasonable limit.
+    // create a native_handle_t with 0 numFds and numInts number of ints.
+    native_handle_t *nh =
+        native_handle_create(0, numInts);
+    if (!nh) {
+        return nullptr;
+    }
+    // Store the size of the token in the first int.
+    nh->data[0] = nhDataByteSize;
+    memcpy(&(nh->data[1]), halToken.data(), nhDataByteSize);
+    return nh;
+}
+
 EXPORT
 media_status_t AImageReader_new(
         int32_t width, int32_t height, int32_t format, int32_t maxImages,
@@ -594,6 +672,19 @@
             width, height, format, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, maxImages, reader);
 }
 
+extern "C" {
+
+EXPORT
+media_status_t AImageReader_getWindowNativeHandle(
+        AImageReader *reader, /*out*/native_handle_t **handle) {
+    if (reader == nullptr || handle == nullptr) {
+        return AMEDIA_ERROR_INVALID_PARAMETER;
+    }
+    return reader->getWindowNativeHandle(handle);
+}
+
+} //extern "C"
+
 EXPORT
 media_status_t AImageReader_newWithUsage(
         int32_t width, int32_t height, int32_t format, uint64_t usage,
diff --git a/media/ndk/NdkImageReaderPriv.h b/media/ndk/NdkImageReaderPriv.h
index bed8a21..e328cb1 100644
--- a/media/ndk/NdkImageReaderPriv.h
+++ b/media/ndk/NdkImageReaderPriv.h
@@ -69,6 +69,8 @@
     media_status_t acquireNextImage(/*out*/AImage** image, /*out*/int* fenceFd);
     media_status_t acquireLatestImage(/*out*/AImage** image, /*out*/int* fenceFd);
 
+    media_status_t getWindowNativeHandle(/*out*/native_handle_t **handle);
+
     ANativeWindow* getWindow()    const { return mWindow.get(); };
     int32_t        getWidth()     const { return mWidth; };
     int32_t        getHeight()    const { return mHeight; };
@@ -86,7 +88,7 @@
     media_status_t acquireImageLocked(/*out*/AImage** image, /*out*/int* fenceFd);
 
     // Called by AImage/~AImageReader to close image. Caller is responsible to grab AImage::mLock
-    void releaseImageLocked(AImage* image, int releaseFenceFd);
+    void releaseImageLocked(AImage* image, int releaseFenceFd, bool clearCache = true);
 
     static int getBufferWidth(BufferItem* buffer);
     static int getBufferHeight(BufferItem* buffer);
@@ -160,6 +162,7 @@
     sp<Surface>                mSurface;
     sp<BufferItemConsumer>     mBufferItemConsumer;
     sp<ANativeWindow>          mWindow;
+    native_handle_t*           mWindowHandle = nullptr;
 
     List<AImage*>              mAcquiredImages;
 
diff --git a/media/ndk/NdkMediaCodec.cpp b/media/ndk/NdkMediaCodec.cpp
index 42285f8..c23f19b 100644
--- a/media/ndk/NdkMediaCodec.cpp
+++ b/media/ndk/NdkMediaCodec.cpp
@@ -21,8 +21,8 @@
 
 #include <media/NdkMediaCodec.h>
 #include <media/NdkMediaError.h>
+#include <media/NdkMediaFormatPriv.h>
 #include "NdkMediaCryptoPriv.h"
-#include "NdkMediaFormatPriv.h"
 
 #include <utils/Log.h>
 #include <utils/StrongPointer.h>
diff --git a/media/ndk/NdkMediaCrypto.cpp b/media/ndk/NdkMediaCrypto.cpp
index d7193ca..ce2c660 100644
--- a/media/ndk/NdkMediaCrypto.cpp
+++ b/media/ndk/NdkMediaCrypto.cpp
@@ -20,7 +20,7 @@
 
 #include <media/NdkMediaCrypto.h>
 #include <media/NdkMediaCodec.h>
-#include "NdkMediaFormatPriv.h"
+#include <media/NdkMediaFormatPriv.h>
 
 
 #include <cutils/properties.h>
@@ -29,7 +29,6 @@
 #include <binder/IServiceManager.h>
 #include <media/ICrypto.h>
 #include <media/IMediaDrmService.h>
-#include <android_runtime/AndroidRuntime.h>
 #include <android_util_Binder.h>
 
 #include <jni.h>
diff --git a/media/ndk/NdkMediaDataSource.cpp b/media/ndk/NdkMediaDataSource.cpp
index 9d00e5e..7979c2f 100644
--- a/media/ndk/NdkMediaDataSource.cpp
+++ b/media/ndk/NdkMediaDataSource.cpp
@@ -23,16 +23,23 @@
 #include <jni.h>
 #include <unistd.h>
 
-#include <binder/IServiceManager.h>
+#include <android_runtime/AndroidRuntime.h>
+#include <android_util_Binder.h>
 #include <cutils/properties.h>
 #include <utils/Log.h>
 #include <utils/StrongPointer.h>
+#include <media/IMediaHTTPService.h>
 #include <media/NdkMediaError.h>
 #include <media/NdkMediaDataSource.h>
+#include <media/stagefright/DataSourceFactory.h>
 #include <media/stagefright/InterfaceUtils.h>
+#include <mediaplayer2/JavaVMHelper.h>
+#include <mediaplayer2/JMedia2HTTPService.h>
 
 #include "../../libstagefright/include/HTTPBase.h"
 #include "../../libstagefright/include/NuCachedSource2.h"
+#include "NdkMediaDataSourceCallbacksPriv.h"
+
 
 using namespace android;
 
@@ -41,14 +48,20 @@
     AMediaDataSourceReadAt readAt;
     AMediaDataSourceGetSize getSize;
     AMediaDataSourceClose close;
+    AMediaDataSourceGetAvailableSize getAvailableSize;
+    sp<DataSource> mImpl;
+    uint32_t mFlags;
 };
 
 NdkDataSource::NdkDataSource(AMediaDataSource *dataSource)
     : mDataSource(AMediaDataSource_new()) {
-      AMediaDataSource_setReadAt(mDataSource, dataSource->readAt);
-      AMediaDataSource_setGetSize(mDataSource, dataSource->getSize);
-      AMediaDataSource_setClose(mDataSource, dataSource->close);
-      AMediaDataSource_setUserdata(mDataSource, dataSource->userdata);
+    AMediaDataSource_setReadAt(mDataSource, dataSource->readAt);
+    AMediaDataSource_setGetSize(mDataSource, dataSource->getSize);
+    AMediaDataSource_setClose(mDataSource, dataSource->close);
+    AMediaDataSource_setUserdata(mDataSource, dataSource->userdata);
+    AMediaDataSource_setGetAvailableSize(mDataSource, dataSource->getAvailableSize);
+    mDataSource->mImpl = dataSource->mImpl;
+    mDataSource->mFlags = dataSource->mFlags;
 }
 
 NdkDataSource::~NdkDataSource() {
@@ -59,9 +72,13 @@
     return OK;
 }
 
+uint32_t NdkDataSource::flags() {
+    return mDataSource->mFlags;
+}
+
 ssize_t NdkDataSource::readAt(off64_t offset, void *data, size_t size) {
     Mutex::Autolock l(mLock);
-    if (mDataSource->getSize == NULL || mDataSource->userdata == NULL) {
+    if (mDataSource->readAt == NULL || mDataSource->userdata == NULL) {
         return -1;
     }
     return mDataSource->readAt(mDataSource->userdata, offset, data, size);
@@ -92,6 +109,95 @@
     }
 }
 
+status_t NdkDataSource::getAvailableSize(off64_t offset, off64_t *sizeptr) {
+    off64_t size = -1;
+    if (mDataSource->getAvailableSize != NULL
+            && mDataSource->userdata != NULL
+            && sizeptr != NULL) {
+        size = mDataSource->getAvailableSize(mDataSource->userdata, offset);
+        *sizeptr = size;
+    }
+    return size >= 0 ? OK : UNKNOWN_ERROR;
+}
+
+static sp<MediaHTTPService> createMediaHttpServiceFromJavaObj(JNIEnv *env, jobject obj, int version) {
+    if (obj == NULL) {
+        return NULL;
+    }
+    switch (version) {
+        case 1:
+            return interface_cast<IMediaHTTPService>(ibinderForJavaObject(env, obj));
+        case 2:
+            return new JMedia2HTTPService(env, obj);
+        default:
+            return NULL;
+    }
+}
+
+static sp<MediaHTTPService> createMediaHttpServiceTemplate(
+        JNIEnv *env,
+        const char *uri,
+        const char *clazz,
+        const char *method,
+        const char *signature,
+        int version) {
+    jobject service = NULL;
+    if (env == NULL) {
+        ALOGE("http service must be created from Java thread");
+        return NULL;
+    }
+
+    jclass mediahttpclass = env->FindClass(clazz);
+    if (mediahttpclass == NULL) {
+        ALOGE("can't find Media(2)HttpService");
+        env->ExceptionClear();
+        return NULL;
+    }
+
+    jmethodID mediaHttpCreateMethod = env->GetStaticMethodID(mediahttpclass, method, signature);
+    if (mediaHttpCreateMethod == NULL) {
+        ALOGE("can't find method");
+        env->ExceptionClear();
+        return NULL;
+    }
+
+    jstring juri = env->NewStringUTF(uri);
+
+    service = env->CallStaticObjectMethod(mediahttpclass, mediaHttpCreateMethod, juri);
+    env->DeleteLocalRef(juri);
+
+    env->ExceptionClear();
+    sp<MediaHTTPService> httpService = createMediaHttpServiceFromJavaObj(env, service, version);
+    return httpService;
+
+}
+
+sp<MediaHTTPService> createMediaHttpService(const char *uri, int version) {
+
+    JNIEnv *env;
+    const char *clazz, *method, *signature;
+
+    switch (version) {
+        case 1:
+            env = AndroidRuntime::getJNIEnv();
+            clazz = "android/media/MediaHTTPService";
+            method = "createHttpServiceBinderIfNecessary";
+            signature = "(Ljava/lang/String;)Landroid/os/IBinder;";
+            break;
+        case 2:
+            env = JavaVMHelper::getJNIEnv();
+            clazz = "android/media/Media2HTTPService";
+            method = "createHTTPService";
+            signature = "(Ljava/lang/String;)Landroid/media/Media2HTTPService;";
+            break;
+        default:
+            return NULL;
+    }
+
+    return createMediaHttpServiceTemplate(env, uri, clazz, method, signature, version);
+
+}
+
 extern "C" {
 
 EXPORT
@@ -105,6 +211,32 @@
 }
 
 EXPORT
+AMediaDataSource* AMediaDataSource_newUri(
+        const char *uri,
+        int numheaders,
+        const char * const *key_values) {
+
+    sp<MediaHTTPService> service = createMediaHttpService(uri, /* version = */ 1);
+    KeyedVector<String8, String8> headers;
+    for (int i = 0; i < numheaders; ++i) {
+        String8 key8(key_values[i * 2]);
+        String8 value8(key_values[i * 2 + 1]);
+        headers.add(key8, value8);
+    }
+
+    sp<DataSource> source = DataSourceFactory::CreateFromURI(service, uri, &headers);
+    if (source == NULL) {
+        ALOGE("AMediaDataSource_newUri source is null");
+        return NULL;
+    }
+    ALOGI("AMediaDataSource_newUri source %s flags %u", source->toString().c_str(), source->flags());
+    AMediaDataSource* aSource = convertDataSourceToAMediaDataSource(source);
+    aSource->mImpl = source;
+    aSource->mFlags = source->flags();
+    return aSource;
+}
+
+EXPORT
 void AMediaDataSource_delete(AMediaDataSource *mSource) {
     ALOGV("dtor");
     if (mSource != NULL) {
@@ -132,5 +264,16 @@
     mSource->close = close;
 }
 
+EXPORT
+void AMediaDataSource_close(AMediaDataSource *mSource) {
+    return mSource->close(mSource->userdata);
+}
+
+EXPORT
+void AMediaDataSource_setGetAvailableSize(AMediaDataSource *mSource,
+        AMediaDataSourceGetAvailableSize getAvailableSize) {
+    mSource->getAvailableSize = getAvailableSize;
+}
+
 } // extern "C"
 
diff --git a/media/ndk/NdkMediaDataSourceCallbacks.cpp b/media/ndk/NdkMediaDataSourceCallbacks.cpp
new file mode 100644
index 0000000..86a57da
--- /dev/null
+++ b/media/ndk/NdkMediaDataSourceCallbacks.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "NdkMediaDataSourceCallbacks"
+
+#include "NdkMediaDataSourceCallbacksPriv.h"
+#include <media/DataSource.h>
+#include <media/NdkMediaErrorPriv.h>
+
+namespace android {
+
+ssize_t DataSource_getSize(void *userdata) {
+    DataSource *source = static_cast<DataSource *>(userdata);
+    off64_t size = -1;
+    source->getSize(&size);
+    return size;
+}
+
+ssize_t DataSource_readAt(void *userdata, off64_t offset, void * buf, size_t size) {
+    DataSource *source = static_cast<DataSource *>(userdata);
+    return source->readAt(offset, buf, size);
+}
+
+void DataSource_close(void *userdata) {
+    DataSource *source = static_cast<DataSource *>(userdata);
+    source->close();
+}
+
+ssize_t DataSource_getAvailableSize(void *userdata, off64_t offset) {
+    off64_t size = -1;
+    DataSource *source = static_cast<DataSource *>(userdata);
+    source->getAvailableSize(offset, &size);
+    return  size;
+}
+
+}  // namespace android
diff --git a/media/ndk/NdkMediaDataSourceCallbacksPriv.h b/media/ndk/NdkMediaDataSourceCallbacksPriv.h
new file mode 100644
index 0000000..6503305
--- /dev/null
+++ b/media/ndk/NdkMediaDataSourceCallbacksPriv.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef A_MEDIA_DATA_SOURCE_CALLBACKS_H
+
+#define A_MEDIA_DATA_SOURCE_CALLBACKS_H
+
+#include <media/DataSource.h>
+#include <media/NdkMediaDataSource.h>
+#include <media/NdkMediaError.h>
+#include <sys/types.h>
+
+namespace android {
+
+ssize_t DataSource_getSize(void *userdata);
+
+ssize_t DataSource_readAt(void *userdata, off64_t offset, void * buf, size_t size);
+
+void DataSource_close(void *userdata);
+
+ssize_t DataSource_getAvailableSize(void *userdata, off64_t offset);
+
+static inline AMediaDataSource* convertDataSourceToAMediaDataSource(const sp<DataSource> &source) {
+    if (source == NULL) {
+        return NULL;
+    }
+    AMediaDataSource *mSource = AMediaDataSource_new();
+    AMediaDataSource_setUserdata(mSource, source.get());
+    AMediaDataSource_setReadAt(mSource, DataSource_readAt);
+    AMediaDataSource_setGetSize(mSource, DataSource_getSize);
+    AMediaDataSource_setClose(mSource, DataSource_close);
+    AMediaDataSource_setGetAvailableSize(mSource, DataSource_getAvailableSize);
+    return mSource;
+}
+
+}  // namespace android
+
+#endif  // A_MEDIA_DATA_SOURCE_CALLBACKS_H
diff --git a/media/ndk/NdkMediaDataSourcePriv.h b/media/ndk/NdkMediaDataSourcePriv.h
index ea9c865..16ff974 100644
--- a/media/ndk/NdkMediaDataSourcePriv.h
+++ b/media/ndk/NdkMediaDataSourcePriv.h
@@ -32,6 +32,7 @@
 #include <sys/types.h>
 
 #include <media/DataSource.h>
+#include <media/MediaHTTPService.h>
 #include <media/NdkMediaDataSource.h>
 #include <utils/Mutex.h>
 #include <utils/String8.h>
@@ -43,11 +44,13 @@
     NdkDataSource(AMediaDataSource *);
 
     virtual status_t initCheck() const;
+    virtual uint32_t flags();
     virtual ssize_t readAt(off64_t offset, void *data, size_t size);
     virtual status_t getSize(off64_t *);
     virtual String8 toString();
     virtual String8 getMIMEType() const;
     virtual void close();
+    virtual status_t getAvailableSize(off64_t offset, off64_t *size);
 
 protected:
     virtual ~NdkDataSource();
@@ -59,5 +62,7 @@
 
 };
 
+sp<MediaHTTPService> createMediaHttpService(const char *uri, int version);
+
 #endif // _NDK_MEDIA_DATASOURCE_PRIV_H
 
diff --git a/media/ndk/NdkMediaDrm.cpp b/media/ndk/NdkMediaDrm.cpp
index 6d10f1c..85dbffe 100644
--- a/media/ndk/NdkMediaDrm.cpp
+++ b/media/ndk/NdkMediaDrm.cpp
@@ -17,6 +17,9 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "NdkMediaDrm"
 
+#include <inttypes.h>
+#include <unistd.h>
+
 #include <media/NdkMediaDrm.h>
 
 #include <cutils/properties.h>
@@ -24,6 +27,8 @@
 #include <utils/StrongPointer.h>
 #include <gui/Surface.h>
 
+#include <android-base/properties.h>
+#include <binder/PermissionController.h>
 #include <media/IDrm.h>
 #include <media/IDrmClient.h>
 #include <media/stagefright/MediaErrors.h>
@@ -40,10 +45,32 @@
 {
 private:
     AMediaDrm *mObj;
-    AMediaDrmEventListener mListener;
+    AMediaDrmEventListener mEventListener;
+    AMediaDrmExpirationUpdateListener mExpirationUpdateListener;
+    AMediaDrmKeysChangeListener mKeysChangeListener;
 
 public:
-    DrmListener(AMediaDrm *obj, AMediaDrmEventListener listener) : mObj(obj), mListener(listener) {}
+    DrmListener(AMediaDrm *obj, AMediaDrmEventListener listener) : mObj(obj),
+            mEventListener(listener), mExpirationUpdateListener(NULL), mKeysChangeListener(NULL) {}
+
+    DrmListener(AMediaDrm *obj, AMediaDrmExpirationUpdateListener listener) : mObj(obj),
+            mEventListener(NULL), mExpirationUpdateListener(listener), mKeysChangeListener(NULL) {}
+
+    DrmListener(AMediaDrm *obj, AMediaDrmKeysChangeListener listener) : mObj(obj),
+            mEventListener(NULL), mExpirationUpdateListener(NULL), mKeysChangeListener(listener) {}
+
+    void setEventListener(AMediaDrmEventListener listener) {
+        mEventListener = listener;
+    }
+
+    void setExpirationUpdateListener(AMediaDrmExpirationUpdateListener listener) {
+        mExpirationUpdateListener = listener;
+    }
+
+    void setKeysChangeListener(AMediaDrmKeysChangeListener listener) {
+        mKeysChangeListener = listener;
+    }
+
     void notify(DrmPlugin::EventType eventType, int extra, const Parcel *obj);
 };
 
@@ -62,27 +89,75 @@
 };
 
 void DrmListener::notify(DrmPlugin::EventType eventType, int extra, const Parcel *obj) {
-    if (!mListener) {
+    if (!mEventListener && !mExpirationUpdateListener && !mKeysChangeListener) {
+        ALOGE("No listeners are specified");
         return;
     }
 
+    obj->setDataPosition(0);
+
     AMediaDrmSessionId sessionId = {NULL, 0};
     int32_t sessionIdSize = obj->readInt32();
-    if (sessionIdSize) {
-        uint8_t *sessionIdData = new uint8_t[sessionIdSize];
-        sessionId.ptr = sessionIdData;
-        sessionId.length = sessionIdSize;
-        obj->read(sessionIdData, sessionId.length);
+    if (sessionIdSize <= 0) {
+        ALOGE("Invalid session id size");
+        return;
     }
 
-    int32_t dataSize = obj->readInt32();
-    uint8_t *data = NULL;
-    if (dataSize) {
-        data = new uint8_t[dataSize];
-        obj->read(data, dataSize);
+    std::unique_ptr<uint8_t[]> sessionIdData(new uint8_t[sessionIdSize]);
+    sessionId.ptr = sessionIdData.get();
+    sessionId.length = sessionIdSize;
+    status_t err = obj->read(sessionIdData.get(), sessionId.length);
+    if (err != OK) {
+        ALOGE("Failed to read session id, error=%d", err);
+        return;
     }
 
-    // translate DrmPlugin event types into their NDK equivalents
+    if (DrmPlugin::kDrmPluginEventExpirationUpdate == eventType) {
+        int64_t expiryTimeInMS = obj->readInt64();
+        if (expiryTimeInMS >= 0) {
+            (*mExpirationUpdateListener)(mObj, &sessionId, expiryTimeInMS);
+        } else {
+            ALOGE("Failed to read expiry time, status=%" PRId64 "", expiryTimeInMS);
+        }
+        return;
+    } else if (DrmPlugin::kDrmPluginEventKeysChange == eventType) {
+        int32_t numKeys = 0;
+        err = obj->readInt32(&numKeys);
+        if (err != OK) {
+            ALOGE("Failed to read number of keys status, error=%d", err);
+            return;
+        }
+
+        Vector<AMediaDrmKeyStatus> keysStatus;
+        std::vector<std::unique_ptr<uint8_t[]> > dataPointers;
+        AMediaDrmKeyStatus keyStatus;
+
+        for (size_t i = 0; i < numKeys; ++i) {
+            keyStatus.keyId.ptr = nullptr;
+            keyStatus.keyId.length = 0;
+            int32_t idSize = obj->readInt32();
+            if (idSize > 0) {
+                std::unique_ptr<uint8_t[]> data(new uint8_t[idSize]);
+                err = obj->read(data.get(), idSize);
+                if (err != OK) {
+                    ALOGE("Failed to read key data, error=%d", err);
+                    return;
+                }
+                keyStatus.keyId.ptr = data.get();
+                keyStatus.keyId.length = idSize;
+                dataPointers.push_back(std::move(data));
+            }
+            keyStatus.keyType = static_cast<AMediaDrmKeyStatusType>(obj->readInt32());
+            keysStatus.push(keyStatus);
+        }
+
+        bool hasNewUsableKey = obj->readInt32();
+        (*mKeysChangeListener)(mObj, &sessionId, keysStatus.array(), numKeys, hasNewUsableKey);
+        return;
+    }
+
+    // Handles AMediaDrmEventListener below:
+    //  translates DrmPlugin event types into their NDK equivalents
     AMediaDrmEventType ndkEventType;
     switch(eventType) {
         case DrmPlugin::kDrmPluginEventProvisionRequired:
@@ -97,19 +172,30 @@
         case DrmPlugin::kDrmPluginEventVendorDefined:
             ndkEventType = EVENT_VENDOR_DEFINED;
             break;
+        case DrmPlugin::kDrmPluginEventSessionReclaimed:
+            ndkEventType = EVENT_SESSION_RECLAIMED;
+            break;
         default:
             ALOGE("Invalid event DrmPlugin::EventType %d, ignored", (int)eventType);
-            goto cleanup;
+            return;
     }
 
-    (*mListener)(mObj, &sessionId, ndkEventType, extra, data, dataSize);
-
- cleanup:
-    delete [] sessionId.ptr;
-    delete [] data;
+    int32_t dataSize = obj->readInt32();
+    uint8_t *data = NULL;
+    if (dataSize > 0) {
+        data = new uint8_t[dataSize];
+        err = obj->read(data, dataSize);
+        if (err == OK) {
+            (*mEventListener)(mObj, &sessionId, ndkEventType, extra, data, dataSize);
+        } else {
+            ALOGE("Failed to read event data, error=%d", err);
+        }
+        delete [] data;
+    } else {
+        ALOGE("Error reading parcel: invalid event data size=%d", dataSize);
+    }
 }
 
-
 extern "C" {
 
 static media_status_t translateStatus(status_t status) {
@@ -148,6 +234,39 @@
     return result;
 }
 
+static bool ShouldGetAppPackageName(void) {
+    // Check what this device's first API level was.
+    int32_t firstApiLevel = android::base::GetIntProperty<int32_t>("ro.product.first_api_level", 0);
+    if (firstApiLevel == 0) {
+        // First API Level is 0 on factory ROMs, but we can assume the current SDK
+        // version is the first if it's a factory ROM.
+        firstApiLevel = android::base::GetIntProperty<int32_t>("ro.build.version.sdk", 0);
+    }
+    return firstApiLevel >= 29;  // Android Q
+}
+
+static status_t GetAppPackageName(String8 *packageName) {
+    sp<IServiceManager> serviceManager = defaultServiceManager();
+    sp<IBinder> binder = serviceManager->getService(String16("permission"));
+
+    sp<IPermissionController> permissionContol = interface_cast<IPermissionController>(binder);
+    if (permissionContol == NULL) {
+        ALOGE("Failed to get permission service");
+        return UNKNOWN_ERROR;
+    }
+
+    Vector<String16> packages;
+    permissionContol->getPackagesForUid(getuid(), packages);
+
+    if (packages.isEmpty()) {
+        ALOGE("Unable to get package name for current UID");
+        return UNKNOWN_ERROR;
+    }
+
+    *packageName = String8(packages[0]);
+    return OK;
+}
+
 static sp<IDrm> CreateDrm() {
     sp<IServiceManager> sm = defaultServiceManager();
     sp<IBinder> binder = sm->getService(String16("media.drm"));
@@ -172,8 +291,16 @@
         return NULL;
     }
 
-    String8 nullPackageName;
-    status_t err = drm->createPlugin(uuid, nullPackageName);
+    String8 packageName;
+    if (ShouldGetAppPackageName()) {
+        status_t err = GetAppPackageName(&packageName);
+
+        if (err != OK) {
+            return NULL;
+        }
+    }
+
+    status_t err = drm->createPlugin(uuid, packageName);
 
     if (err != OK) {
         return NULL;
@@ -191,13 +318,18 @@
     }
 
     String8 mimeStr = mimeType ? String8(mimeType) : String8("");
-    return drm->isCryptoSchemeSupported(uuid, mimeStr);
+    bool isSupported = false;
+    status_t status = drm->isCryptoSchemeSupported(uuid, mimeStr,
+            DrmPlugin::kSecurityLevelUnknown, &isSupported);
+    return (status == OK) && isSupported;
 }
 
 EXPORT
 AMediaDrm* AMediaDrm_createByUUID(const AMediaUUID uuid) {
     AMediaDrm *mObj = new AMediaDrm();
     mObj->mDrm = CreateDrmFromUUID(uuid);
+
+    mObj->mListener.clear();
     return mObj;
 }
 
@@ -216,11 +348,47 @@
     if (!mObj || mObj->mDrm == NULL) {
         return AMEDIA_ERROR_INVALID_OBJECT;
     }
-    mObj->mListener = new DrmListener(mObj, listener);
+
+    if (mObj->mListener.get()) {
+        mObj->mListener->setEventListener(listener);
+    } else {
+        mObj->mListener = new DrmListener(mObj, listener);
+    }
     mObj->mDrm->setListener(mObj->mListener);
     return AMEDIA_OK;
 }
 
+EXPORT
+media_status_t AMediaDrm_setOnExpirationUpdateListener(AMediaDrm *mObj,
+        AMediaDrmExpirationUpdateListener listener) {
+    if (!mObj || mObj->mDrm == NULL) {
+        return AMEDIA_ERROR_INVALID_OBJECT;
+    }
+
+    if (mObj->mListener.get()) {
+        mObj->mListener->setExpirationUpdateListener(listener);
+    } else {
+        mObj->mListener = new DrmListener(mObj, listener);
+    }
+    mObj->mDrm->setListener(mObj->mListener);
+    return AMEDIA_OK;
+}
+
+EXPORT
+media_status_t AMediaDrm_setOnKeysChangeListener(AMediaDrm *mObj,
+        AMediaDrmKeysChangeListener listener) {
+    if (!mObj || mObj->mDrm == NULL) {
+        return AMEDIA_ERROR_INVALID_OBJECT;
+    }
+
+    if (mObj->mListener.get()) {
+        mObj->mListener->setKeysChangeListener(listener);
+    } else {
+        mObj->mListener = new DrmListener(mObj, listener);
+    }
+    mObj->mDrm->setListener(mObj->mListener);
+    return AMEDIA_OK;
+}
 
 static bool findId(AMediaDrm *mObj, const AMediaDrmByteArray &id, List<idvec_t>::iterator &iter) {
     for (iter = mObj->mIds.begin(); iter != mObj->mIds.end(); ++iter) {
@@ -309,6 +477,7 @@
     }
     String8 defaultUrl;
     DrmPlugin::KeyRequestType keyRequestType;
+    mObj->mKeyRequest.clear();
     status_t status = mObj->mDrm->getKeyRequest(*iter, mdInit, String8(mimeType),
             mdKeyType, mdOptionalParameters, mObj->mKeyRequest, defaultUrl,
             &keyRequestType);
@@ -576,7 +745,7 @@
     Vector<uint8_t> byteArray;
     byteArray.appendArray(value, valueSize);
 
-    return translateStatus(mObj->mDrm->getPropertyByteArray(String8(propertyName),
+    return translateStatus(mObj->mDrm->setPropertyByteArray(String8(propertyName),
                     byteArray));
 }
 
diff --git a/media/ndk/NdkMediaExtractor.cpp b/media/ndk/NdkMediaExtractor.cpp
index b5e60a4..c83b255 100644
--- a/media/ndk/NdkMediaExtractor.cpp
+++ b/media/ndk/NdkMediaExtractor.cpp
@@ -20,8 +20,9 @@
 
 #include <media/NdkMediaError.h>
 #include <media/NdkMediaExtractor.h>
+#include <media/NdkMediaErrorPriv.h>
+#include <media/NdkMediaFormatPriv.h>
 #include "NdkMediaDataSourcePriv.h"
-#include "NdkMediaFormatPriv.h"
 
 
 #include <inttypes.h>
@@ -33,31 +34,29 @@
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/NuMediaExtractor.h>
 #include <media/IMediaHTTPService.h>
-#include <android_runtime/AndroidRuntime.h>
 #include <android_util_Binder.h>
 
 #include <jni.h>
 
 using namespace android;
 
-static media_status_t translate_error(status_t err) {
-    if (err == OK) {
-        return AMEDIA_OK;
-    } else if (err == ERROR_END_OF_STREAM) {
-        return AMEDIA_ERROR_END_OF_STREAM;
-    } else if (err == ERROR_IO) {
-        return AMEDIA_ERROR_IO;
-    }
-
-    ALOGE("sf error code: %d", err);
-    return AMEDIA_ERROR_UNKNOWN;
-}
-
 struct AMediaExtractor {
     sp<NuMediaExtractor> mImpl;
     sp<ABuffer> mPsshBuf;
 };
 
+sp<ABuffer> U32ArrayToSizeBuf(size_t numSubSamples, uint32_t *data) {
+    if (numSubSamples >  SIZE_MAX / sizeof(size_t)) {
+        return NULL;
+    }
+    sp<ABuffer> sizebuf = new ABuffer(numSubSamples * sizeof(size_t));
+    size_t *sizes = (size_t *)sizebuf->data();
+    for (size_t i = 0; sizes != NULL && i < numSubSamples; i++) {
+        sizes[i] = data[i];
+    }
+    return sizebuf;
+}
+
 extern "C" {
 
 EXPORT
@@ -82,47 +81,35 @@
     return translate_error(mData->mImpl->setDataSource(fd, offset, length));
 }
 
+media_status_t AMediaExtractor_setDataSourceWithHeaders(AMediaExtractor *mData,
+        const char *uri,
+        int numheaders,
+        const char * const *keys,
+        const char * const *values) {
+
+    ALOGV("setDataSource(%s)", uri);
+
+    sp<MediaHTTPService> httpService = createMediaHttpService(uri, /* version = */ 1);
+    if (httpService == NULL) {
+        ALOGE("can't create http service");
+        return AMEDIA_ERROR_UNSUPPORTED;
+    }
+
+    KeyedVector<String8, String8> headers;
+    for (int i = 0; i < numheaders; ++i) {
+        String8 key8(keys[i]);
+        String8 value8(values[i]);
+        headers.add(key8, value8);
+    }
+
+    status_t err;
+    err = mData->mImpl->setDataSource(httpService, uri, numheaders > 0 ? &headers : NULL);
+    return translate_error(err);
+}
+
 EXPORT
 media_status_t AMediaExtractor_setDataSource(AMediaExtractor *mData, const char *location) {
-    ALOGV("setDataSource(%s)", location);
-    // TODO: add header support
-
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
-    jobject service = NULL;
-    if (env == NULL) {
-        ALOGE("setDataSource(path) must be called from Java thread");
-        return AMEDIA_ERROR_UNSUPPORTED;
-    }
-
-    jclass mediahttpclass = env->FindClass("android/media/MediaHTTPService");
-    if (mediahttpclass == NULL) {
-        ALOGE("can't find MediaHttpService");
-        env->ExceptionClear();
-        return AMEDIA_ERROR_UNSUPPORTED;
-    }
-
-    jmethodID mediaHttpCreateMethod = env->GetStaticMethodID(mediahttpclass,
-            "createHttpServiceBinderIfNecessary", "(Ljava/lang/String;)Landroid/os/IBinder;");
-    if (mediaHttpCreateMethod == NULL) {
-        ALOGE("can't find method");
-        env->ExceptionClear();
-        return AMEDIA_ERROR_UNSUPPORTED;
-    }
-
-    jstring jloc = env->NewStringUTF(location);
-
-    service = env->CallStaticObjectMethod(mediahttpclass, mediaHttpCreateMethod, jloc);
-    env->DeleteLocalRef(jloc);
-
-    sp<IMediaHTTPService> httpService;
-    if (service != NULL) {
-        sp<IBinder> binder = ibinderForJavaObject(env, service);
-        httpService = interface_cast<IMediaHTTPService>(binder);
-    }
-
-    status_t err = mData->mImpl->setDataSource(httpService, location, NULL);
-    env->ExceptionClear();
-    return translate_error(err);
+    return AMediaExtractor_setDataSourceWithHeaders(mData, location, 0, NULL, NULL);
 }
 
 EXPORT
@@ -363,7 +350,7 @@
     if (!meta->findData(kKeyEncryptedSizes, &type, &crypteddata, &cryptedsize)) {
         return NULL;
     }
-    size_t numSubSamples = cryptedsize / sizeof(size_t);
+    size_t numSubSamples = cryptedsize / sizeof(uint32_t);
 
     const void *cleardata;
     size_t clearsize;
@@ -397,6 +384,16 @@
         mode = CryptoPlugin::kMode_AES_CTR;
     }
 
+    if (sizeof(uint32_t) != sizeof(size_t)) {
+        sp<ABuffer> clearbuf   = U32ArrayToSizeBuf(numSubSamples, (uint32_t *)cleardata);
+        sp<ABuffer> cryptedbuf = U32ArrayToSizeBuf(numSubSamples, (uint32_t *)crypteddata);
+        cleardata   = clearbuf    == NULL ? NULL : clearbuf->data();
+        crypteddata = crypteddata == NULL ? NULL : cryptedbuf->data();
+        if(crypteddata == NULL || cleardata == NULL) {
+            return NULL;
+        }
+    }
+
     return AMediaCodecCryptoInfo_new(
             numSubSamples,
             (uint8_t*) key,
@@ -472,12 +469,16 @@
         meta->setBuffer(AMEDIAFORMAT_KEY_MPEG_USER_DATA, mpegUserData);
     }
 
-    return AMEDIA_OK;
-}
+    const void *audioPresentationsPointer;
+    size_t audioPresentationsLength;
+    if (sampleMeta->findData(
+            kKeyAudioPresentationInfo, &dataType,
+            &audioPresentationsPointer, &audioPresentationsLength)) {
+        sp<ABuffer> audioPresentationsData = ABuffer::CreateAsCopy(
+                audioPresentationsPointer, audioPresentationsLength);
+        meta->setBuffer(AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO, audioPresentationsData);
+    }
 
-EXPORT
-media_status_t AMediaExtractor_disconnect(AMediaExtractor * ex) {
-    ex->mImpl->disconnect();
     return AMEDIA_OK;
 }
 
diff --git a/media/ndk/NdkMediaFormat.cpp b/media/ndk/NdkMediaFormat.cpp
index f32b83e..51138c8 100644
--- a/media/ndk/NdkMediaFormat.cpp
+++ b/media/ndk/NdkMediaFormat.cpp
@@ -20,43 +20,20 @@
 #include <inttypes.h>
 
 #include <media/NdkMediaFormat.h>
+#include <media/NdkMediaFormatPriv.h>
 
 #include <utils/Log.h>
 #include <utils/StrongPointer.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/AMessage.h>
-#include <android_runtime/AndroidRuntime.h>
 #include <android_util_Binder.h>
 
 #include <jni.h>
 
 using namespace android;
 
-struct AMediaFormat {
-    sp<AMessage> mFormat;
-    String8 mDebug;
-    KeyedVector<String8, String8> mStringCache;
-};
-
 extern "C" {
 
-// private functions for conversion to/from AMessage
-AMediaFormat* AMediaFormat_fromMsg(const void* data) {
-    ALOGV("private ctor");
-    AMediaFormat* mData = new AMediaFormat();
-    mData->mFormat = *((sp<AMessage>*)data);
-    if (mData->mFormat == NULL) {
-        ALOGW("got NULL format");
-        mData->mFormat = new AMessage;
-    }
-    return mData;
-}
-
-void AMediaFormat_getFormat(const AMediaFormat* mData, void* dest) {
-    *((sp<AMessage>*)dest) = mData->mFormat;
-}
-
-
 /*
  * public function follow
  */
@@ -74,6 +51,21 @@
     return AMEDIA_OK;
 }
 
+EXPORT
+void AMediaFormat_clear(AMediaFormat *format) {
+    format->mFormat->clear();
+}
+
+EXPORT
+media_status_t AMediaFormat_copy(AMediaFormat *to, AMediaFormat *from) {
+    if (!to || !from) {
+        return AMEDIA_ERROR_INVALID_PARAMETER;
+    }
+    to->mFormat->clear();
+    to->mFormat->extend(from->mFormat);
+    return AMEDIA_OK;
+}
+
 
 EXPORT
 const char* AMediaFormat_toString(AMediaFormat *mData) {
@@ -256,7 +248,7 @@
 }
 
 EXPORT
-void AMediaFormat_setBuffer(AMediaFormat* format, const char* name, void* data, size_t size) {
+void AMediaFormat_setBuffer(AMediaFormat* format, const char* name, const void* data, size_t size) {
     // the ABuffer(void*, size_t) constructor doesn't take ownership of the data, so create
     // a new buffer and copy the data into it
     sp<ABuffer> buf = new ABuffer(size);
@@ -275,65 +267,124 @@
 EXPORT const char* AMEDIAFORMAT_KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT = "aac-max-output-channel_count";
 EXPORT const char* AMEDIAFORMAT_KEY_AAC_PROFILE = "aac-profile";
 EXPORT const char* AMEDIAFORMAT_KEY_AAC_SBR_MODE = "aac-sbr-mode";
+EXPORT const char* AMEDIAFORMAT_KEY_ALBUM = "album";
+EXPORT const char* AMEDIAFORMAT_KEY_ALBUMART = "albumart";
+EXPORT const char* AMEDIAFORMAT_KEY_ALBUMARTIST = "albumartist";
+EXPORT const char* AMEDIAFORMAT_KEY_ARTIST = "artist";
+EXPORT const char* AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO = "audio-presentation-info";
+EXPORT const char* AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_PRESENTATION_ID =
+        "audio-presentation-presentation-id";
+EXPORT const char* AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_PROGRAM_ID = "audio-presentation-program-id";
 EXPORT const char* AMEDIAFORMAT_KEY_AUDIO_SESSION_ID = "audio-session-id";
+EXPORT const char* AMEDIAFORMAT_KEY_AUTHOR = "author";
 EXPORT const char* AMEDIAFORMAT_KEY_BITRATE_MODE = "bitrate-mode";
 EXPORT const char* AMEDIAFORMAT_KEY_BIT_RATE = "bitrate";
+EXPORT const char* AMEDIAFORMAT_KEY_BITS_PER_SAMPLE = "bits-per-sample";
 EXPORT const char* AMEDIAFORMAT_KEY_CAPTURE_RATE = "capture-rate";
+EXPORT const char* AMEDIAFORMAT_KEY_CDTRACKNUMBER = "cdtracknum";
 EXPORT const char* AMEDIAFORMAT_KEY_CHANNEL_COUNT = "channel-count";
 EXPORT const char* AMEDIAFORMAT_KEY_CHANNEL_MASK = "channel-mask";
 EXPORT const char* AMEDIAFORMAT_KEY_COLOR_FORMAT = "color-format";
 EXPORT const char* AMEDIAFORMAT_KEY_COLOR_RANGE = "color-range";
 EXPORT const char* AMEDIAFORMAT_KEY_COLOR_STANDARD = "color-standard";
 EXPORT const char* AMEDIAFORMAT_KEY_COLOR_TRANSFER = "color-transfer";
+EXPORT const char* AMEDIAFORMAT_KEY_COMPILATION = "compilation";
 EXPORT const char* AMEDIAFORMAT_KEY_COMPLEXITY = "complexity";
+EXPORT const char* AMEDIAFORMAT_KEY_COMPOSER = "composer";
+EXPORT const char* AMEDIAFORMAT_KEY_CREATE_INPUT_SURFACE_SUSPENDED = "create-input-buffers-suspended";
+EXPORT const char* AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE = "crypto-default-iv-size";
+EXPORT const char* AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK = "crypto-encrypted-byte-block";
+EXPORT const char* AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES = "crypto-encrypted-sizes";
+EXPORT const char* AMEDIAFORMAT_KEY_CRYPTO_IV = "crypto-iv";
+EXPORT const char* AMEDIAFORMAT_KEY_CRYPTO_KEY = "crypto-key";
+EXPORT const char* AMEDIAFORMAT_KEY_CRYPTO_MODE = "crypto-mode";
+EXPORT const char* AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES = "crypto-plain-sizes";
+EXPORT const char* AMEDIAFORMAT_KEY_CRYPTO_SKIP_BYTE_BLOCK = "crypto-skip-byte-block";
 EXPORT const char* AMEDIAFORMAT_KEY_CSD = "csd";
 EXPORT const char* AMEDIAFORMAT_KEY_CSD_0 = "csd-0";
 EXPORT const char* AMEDIAFORMAT_KEY_CSD_1 = "csd-1";
 EXPORT const char* AMEDIAFORMAT_KEY_CSD_2 = "csd-2";
+EXPORT const char* AMEDIAFORMAT_KEY_CSD_AVC = "csd-avc";
+EXPORT const char* AMEDIAFORMAT_KEY_CSD_HEVC = "csd-hevc";
+EXPORT const char* AMEDIAFORMAT_KEY_D263 = "d263";
+EXPORT const char* AMEDIAFORMAT_KEY_DATE = "date";
+EXPORT const char* AMEDIAFORMAT_KEY_DISCNUMBER = "discnum";
 EXPORT const char* AMEDIAFORMAT_KEY_DISPLAY_CROP = "crop";
 EXPORT const char* AMEDIAFORMAT_KEY_DISPLAY_HEIGHT = "display-height";
 EXPORT const char* AMEDIAFORMAT_KEY_DISPLAY_WIDTH = "display-width";
 EXPORT const char* AMEDIAFORMAT_KEY_DURATION = "durationUs";
+EXPORT const char* AMEDIAFORMAT_KEY_ENCODER_DELAY = "encoder-delay";
+EXPORT const char* AMEDIAFORMAT_KEY_ENCODER_PADDING = "encoder-padding";
+EXPORT const char* AMEDIAFORMAT_KEY_ESDS = "esds";
+EXPORT const char* AMEDIAFORMAT_KEY_EXIF_OFFSET = "exif-offset";
+EXPORT const char* AMEDIAFORMAT_KEY_EXIF_SIZE = "exif-size";
 EXPORT const char* AMEDIAFORMAT_KEY_FLAC_COMPRESSION_LEVEL = "flac-compression-level";
+EXPORT const char* AMEDIAFORMAT_KEY_FRAME_COUNT = "frame-count";
 EXPORT const char* AMEDIAFORMAT_KEY_FRAME_RATE = "frame-rate";
+EXPORT const char* AMEDIAFORMAT_KEY_GENRE = "genre";
 EXPORT const char* AMEDIAFORMAT_KEY_GRID_COLUMNS = "grid-cols";
 EXPORT const char* AMEDIAFORMAT_KEY_GRID_ROWS = "grid-rows";
+EXPORT const char* AMEDIAFORMAT_KEY_HAPTIC_CHANNEL_COUNT = "haptic-channel-count";
 EXPORT const char* AMEDIAFORMAT_KEY_HDR_STATIC_INFO = "hdr-static-info";
+EXPORT const char* AMEDIAFORMAT_KEY_HDR10_PLUS_INFO = "hdr10-plus-info";
 EXPORT const char* AMEDIAFORMAT_KEY_HEIGHT = "height";
+EXPORT const char* AMEDIAFORMAT_KEY_ICC_PROFILE = "icc-profile";
 EXPORT const char* AMEDIAFORMAT_KEY_INTRA_REFRESH_PERIOD = "intra-refresh-period";
 EXPORT const char* AMEDIAFORMAT_KEY_IS_ADTS = "is-adts";
 EXPORT const char* AMEDIAFORMAT_KEY_IS_AUTOSELECT = "is-autoselect";
 EXPORT const char* AMEDIAFORMAT_KEY_IS_DEFAULT = "is-default";
 EXPORT const char* AMEDIAFORMAT_KEY_IS_FORCED_SUBTITLE = "is-forced-subtitle";
+EXPORT const char* AMEDIAFORMAT_KEY_IS_SYNC_FRAME = "is-sync-frame";
 EXPORT const char* AMEDIAFORMAT_KEY_I_FRAME_INTERVAL = "i-frame-interval";
 EXPORT const char* AMEDIAFORMAT_KEY_LANGUAGE = "language";
 EXPORT const char* AMEDIAFORMAT_KEY_LATENCY = "latency";
 EXPORT const char* AMEDIAFORMAT_KEY_LEVEL = "level";
+EXPORT const char* AMEDIAFORMAT_KEY_LOCATION = "location";
+EXPORT const char* AMEDIAFORMAT_KEY_LOOP = "loop";
+EXPORT const char* AMEDIAFORMAT_KEY_LYRICIST = "lyricist";
+EXPORT const char* AMEDIAFORMAT_KEY_MANUFACTURER = "manufacturer";
+EXPORT const char* AMEDIAFORMAT_KEY_MAX_BIT_RATE = "max-bitrate";
+EXPORT const char* AMEDIAFORMAT_KEY_MAX_FPS_TO_ENCODER = "max-fps-to-encoder";
 EXPORT const char* AMEDIAFORMAT_KEY_MAX_HEIGHT = "max-height";
 EXPORT const char* AMEDIAFORMAT_KEY_MAX_INPUT_SIZE = "max-input-size";
+EXPORT const char* AMEDIAFORMAT_KEY_MAX_PTS_GAP_TO_ENCODER = "max-pts-gap-to-encoder";
 EXPORT const char* AMEDIAFORMAT_KEY_MAX_WIDTH = "max-width";
 EXPORT const char* AMEDIAFORMAT_KEY_MIME = "mime";
 EXPORT const char* AMEDIAFORMAT_KEY_MPEG_USER_DATA = "mpeg-user-data";
+EXPORT const char* AMEDIAFORMAT_KEY_MPEG2_STREAM_HEADER = "mpeg2-stream-header";
 EXPORT const char* AMEDIAFORMAT_KEY_OPERATING_RATE = "operating-rate";
 EXPORT const char* AMEDIAFORMAT_KEY_PCM_ENCODING = "pcm-encoding";
 EXPORT const char* AMEDIAFORMAT_KEY_PRIORITY = "priority";
 EXPORT const char* AMEDIAFORMAT_KEY_PROFILE = "profile";
+EXPORT const char* AMEDIAFORMAT_KEY_PCM_BIG_ENDIAN = "pcm-big-endian";
+EXPORT const char* AMEDIAFORMAT_KEY_PSSH = "pssh";
 EXPORT const char* AMEDIAFORMAT_KEY_PUSH_BLANK_BUFFERS_ON_STOP = "push-blank-buffers-on-shutdown";
 EXPORT const char* AMEDIAFORMAT_KEY_REPEAT_PREVIOUS_FRAME_AFTER = "repeat-previous-frame-after";
 EXPORT const char* AMEDIAFORMAT_KEY_ROTATION = "rotation-degrees";
 EXPORT const char* AMEDIAFORMAT_KEY_SAMPLE_RATE = "sample-rate";
+EXPORT const char* AMEDIAFORMAT_KEY_SAR_HEIGHT = "sar-height";
+EXPORT const char* AMEDIAFORMAT_KEY_SAR_WIDTH = "sar-width";
 EXPORT const char* AMEDIAFORMAT_KEY_SEI = "sei";
 EXPORT const char* AMEDIAFORMAT_KEY_SLICE_HEIGHT = "slice-height";
 EXPORT const char* AMEDIAFORMAT_KEY_STRIDE = "stride";
+EXPORT const char* AMEDIAFORMAT_KEY_TARGET_TIME = "target-time";
+EXPORT const char* AMEDIAFORMAT_KEY_TEMPORAL_LAYER_COUNT = "temporal-layer-count";
 EXPORT const char* AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID = "temporal-layer-id";
 EXPORT const char* AMEDIAFORMAT_KEY_TEMPORAL_LAYERING = "ts-schema";
+EXPORT const char* AMEDIAFORMAT_KEY_TEXT_FORMAT_DATA = "text-format-data";
+EXPORT const char* AMEDIAFORMAT_KEY_THUMBNAIL_CSD_HEVC = "thumbnail-csd-hevc";
+EXPORT const char* AMEDIAFORMAT_KEY_THUMBNAIL_HEIGHT = "thumbnail-height";
+EXPORT const char* AMEDIAFORMAT_KEY_THUMBNAIL_TIME = "thumbnail-time";
+EXPORT const char* AMEDIAFORMAT_KEY_THUMBNAIL_WIDTH = "thumbnail-width";
 EXPORT const char* AMEDIAFORMAT_KEY_TILE_HEIGHT = "tile-height";
 EXPORT const char* AMEDIAFORMAT_KEY_TILE_WIDTH = "tile-width";
 EXPORT const char* AMEDIAFORMAT_KEY_TIME_US = "timeUs";
+EXPORT const char* AMEDIAFORMAT_KEY_TITLE = "title";
 EXPORT const char* AMEDIAFORMAT_KEY_TRACK_ID = "track-id";
 EXPORT const char* AMEDIAFORMAT_KEY_TRACK_INDEX = "track-index";
+EXPORT const char* AMEDIAFORMAT_KEY_VALID_SAMPLES = "valid-samples";
 EXPORT const char* AMEDIAFORMAT_KEY_WIDTH = "width";
-
+EXPORT const char* AMEDIAFORMAT_KEY_YEAR = "year";
 
 } // extern "C"
 
diff --git a/media/ndk/NdkMediaFormatPriv.h b/media/ndk/NdkMediaFormatPriv.h
deleted file mode 100644
index c6a6563..0000000
--- a/media/ndk/NdkMediaFormatPriv.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * This file defines an NDK API.
- * Do not remove methods.
- * Do not change method signatures.
- * Do not change the value of constants.
- * Do not change the size of any of the classes defined in here.
- * Do not reference types that are not part of the NDK.
- * Do not #include files that aren't part of the NDK.
- */
-
-#ifndef _NDK_MEDIA_FORMAT_PRIV_H
-#define _NDK_MEDIA_FORMAT_PRIV_H
-
-#include <media/NdkMediaFormat.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-AMediaFormat* AMediaFormat_fromMsg(void*);
-void AMediaFormat_getFormat(const AMediaFormat* mData, void* dest);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // _NDK_MEDIA_FORMAT_PRIV_H
-
diff --git a/media/ndk/NdkMediaMuxer.cpp b/media/ndk/NdkMediaMuxer.cpp
index dffc4d7..d1992bf 100644
--- a/media/ndk/NdkMediaMuxer.cpp
+++ b/media/ndk/NdkMediaMuxer.cpp
@@ -20,7 +20,8 @@
 
 #include <media/NdkMediaMuxer.h>
 #include <media/NdkMediaCodec.h>
-#include "NdkMediaFormatPriv.h"
+#include <media/NdkMediaErrorPriv.h>
+#include <media/NdkMediaFormatPriv.h>
 
 
 #include <utils/Log.h>
@@ -29,21 +30,12 @@
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/MediaMuxer.h>
 #include <media/IMediaHTTPService.h>
-#include <android_runtime/AndroidRuntime.h>
 #include <android_util_Binder.h>
 
 #include <jni.h>
 
 using namespace android;
 
-static media_status_t translate_error(status_t err) {
-    if (err == OK) {
-        return AMEDIA_OK;
-    }
-    ALOGE("sf error code: %d", err);
-    return AMEDIA_ERROR_UNKNOWN;
-}
-
 struct AMediaMuxer {
     sp<MediaMuxer> mImpl;
 
diff --git a/media/ndk/OWNERS b/media/ndk/OWNERS
index 11e8340..9dc441e 100644
--- a/media/ndk/OWNERS
+++ b/media/ndk/OWNERS
@@ -1,5 +1,3 @@
 marcone@google.com
 # For AImage/AImageReader
-etalvala@google.com
-yinchiayeh@google.com
-zhijunhe@google.com
+include platform/frameworks/av:/camera/OWNERS
diff --git a/media/ndk/include/media/NdkImage.h b/media/ndk/include/media/NdkImage.h
index 19df760..3e60de0 100644
--- a/media/ndk/include/media/NdkImage.h
+++ b/media/ndk/include/media/NdkImage.h
@@ -36,13 +36,12 @@
 #ifndef _NDK_IMAGE_H
 #define _NDK_IMAGE_H
 
+#include <stdint.h>
 #include <sys/cdefs.h>
 
 #include "NdkMediaError.h"
 
-#if __ANDROID_API__ >= 26
 #include <android/hardware_buffer.h>
-#endif /* __ANDROID_API__ >= 26 */
 
 __BEGIN_DECLS
 
@@ -500,7 +499,51 @@
      * <p>When an {@link AImage} of this format is obtained from an {@link AImageReader} or
      * {@link AImage_getNumberOfPlanes()} method will return zero.</p>
      */
-    AIMAGE_FORMAT_PRIVATE           = 0x22
+    AIMAGE_FORMAT_PRIVATE           = 0x22,
+
+    /**
+     * Android Y8 format.
+     *
+     * <p>Y8 is a planar format comprised of a WxH Y plane only, with each pixel
+     * being represented by 8 bits.</p>
+     *
+     * <p>This format assumes
+     * <ul>
+     * <li>an even width</li>
+     * <li>an even height</li>
+     * <li>a horizontal stride multiple of 16 pixels</li>
+     * </ul>
+     * </p>
+     *
+     * <pre> size = stride * height </pre>
+     *
+     * <p>For example, the {@link AImage} object can provide data
+     * in this format from a {@link ACameraDevice} (if supported) through a
+     * {@link AImageReader} object. The number of planes returned by
+     * {@link AImage_getNumberOfPlanes} will always be 1. The pixel stride returned by
+     * {@link AImage_getPlanePixelStride} will always be 1, and the
+     * {@link AImage_getPlaneRowStride} described the vertical neighboring pixel distance
+     * (in bytes) between adjacent rows.</p>
+     *
+     */
+    AIMAGE_FORMAT_Y8 = 0x20203859,
+
+    /**
+     * Compressed HEIC format.
+     *
+     * <p>This format defines the HEIC brand of High Efficiency Image File
+     * Format as described in ISO/IEC 23008-12.</p>
+     */
+    AIMAGE_FORMAT_HEIC = 0x48454946,
+
+    /**
+     * Depth augmented compressed JPEG format.
+     *
+     * <p>JPEG compressed main image along with XMP embedded depth metadata
+     * following ISO 16684-1:2011(E).</p>
+     */
+    AIMAGE_FORMAT_DEPTH_JPEG = 0x69656963,
+
 };
 
 /**
@@ -529,7 +572,7 @@
  *
  * @param image The {@link AImage} to be deleted.
  */
-void AImage_delete(AImage* image);
+void AImage_delete(AImage* image) __INTRODUCED_IN(24);
 
 /**
  * Query the width of the input {@link AImage}.
@@ -543,7 +586,7 @@
  *         <li>{@link AMEDIA_ERROR_INVALID_OBJECT} if the {@link AImageReader} generated this
  *                 image has been deleted.</li></ul>
  */
-media_status_t AImage_getWidth(const AImage* image, /*out*/int32_t* width);
+media_status_t AImage_getWidth(const AImage* image, /*out*/int32_t* width) __INTRODUCED_IN(24);
 
 /**
  * Query the height of the input {@link AImage}.
@@ -557,7 +600,7 @@
  *         <li>{@link AMEDIA_ERROR_INVALID_OBJECT} if the {@link AImageReader} generated this
  *                 image has been deleted.</li></ul>
  */
-media_status_t AImage_getHeight(const AImage* image, /*out*/int32_t* height);
+media_status_t AImage_getHeight(const AImage* image, /*out*/int32_t* height) __INTRODUCED_IN(24);
 
 /**
  * Query the format of the input {@link AImage}.
@@ -573,7 +616,7 @@
  *         <li>{@link AMEDIA_ERROR_INVALID_OBJECT} if the {@link AImageReader} generated this
  *                 image has been deleted.</li></ul>
  */
-media_status_t AImage_getFormat(const AImage* image, /*out*/int32_t* format);
+media_status_t AImage_getFormat(const AImage* image, /*out*/int32_t* format) __INTRODUCED_IN(24);
 
 /**
  * Query the cropped rectangle of the input {@link AImage}.
@@ -590,7 +633,7 @@
  *         <li>{@link AMEDIA_ERROR_INVALID_OBJECT} if the {@link AImageReader} generated this
  *                 image has been deleted.</li></ul>
  */
-media_status_t AImage_getCropRect(const AImage* image, /*out*/AImageCropRect* rect);
+media_status_t AImage_getCropRect(const AImage* image, /*out*/AImageCropRect* rect) __INTRODUCED_IN(24);
 
 /**
  * Query the timestamp of the input {@link AImage}.
@@ -614,7 +657,7 @@
  *         <li>{@link AMEDIA_ERROR_INVALID_OBJECT} if the {@link AImageReader} generated this
  *                 image has been deleted.</li></ul>
  */
-media_status_t AImage_getTimestamp(const AImage* image, /*out*/int64_t* timestampNs);
+media_status_t AImage_getTimestamp(const AImage* image, /*out*/int64_t* timestampNs) __INTRODUCED_IN(24);
 
 /**
  * Query the number of planes of the input {@link AImage}.
@@ -632,7 +675,7 @@
  *         <li>{@link AMEDIA_ERROR_INVALID_OBJECT} if the {@link AImageReader} generated this
  *                 image has been deleted.</li></ul>
  */
-media_status_t AImage_getNumberOfPlanes(const AImage* image, /*out*/int32_t* numPlanes);
+media_status_t AImage_getNumberOfPlanes(const AImage* image, /*out*/int32_t* numPlanes) __INTRODUCED_IN(24);
 
 /**
  * Query the pixel stride of the input {@link AImage}.
@@ -660,7 +703,7 @@
  *                 for CPU access.</li></ul>
  */
 media_status_t AImage_getPlanePixelStride(
-        const AImage* image, int planeIdx, /*out*/int32_t* pixelStride);
+        const AImage* image, int planeIdx, /*out*/int32_t* pixelStride) __INTRODUCED_IN(24);
 
 /**
  * Query the row stride of the input {@link AImage}.
@@ -687,7 +730,7 @@
  *                 for CPU access.</li></ul>
  */
 media_status_t AImage_getPlaneRowStride(
-        const AImage* image, int planeIdx, /*out*/int32_t* rowStride);
+        const AImage* image, int planeIdx, /*out*/int32_t* rowStride) __INTRODUCED_IN(24);
 
 /**
  * Get the data pointer of the input image for direct application access.
@@ -712,7 +755,7 @@
  */
 media_status_t AImage_getPlaneData(
         const AImage* image, int planeIdx,
-        /*out*/uint8_t** data, /*out*/int* dataLength);
+        /*out*/uint8_t** data, /*out*/int* dataLength) __INTRODUCED_IN(24);
 
 #endif /* __ANDROID_API__ >= 24 */
 
@@ -732,7 +775,7 @@
  *
  * @see sync.h
  */
-void AImage_deleteAsync(AImage* image, int releaseFenceFd);
+void AImage_deleteAsync(AImage* image, int releaseFenceFd) __INTRODUCED_IN(26);
 
 /**
  * Get the hardware buffer handle of the input image intended for GPU and/or hardware access.
@@ -760,7 +803,7 @@
  *
  * @see AImageReader_ImageCallback
  */
-media_status_t AImage_getHardwareBuffer(const AImage* image, /*out*/AHardwareBuffer** buffer);
+media_status_t AImage_getHardwareBuffer(const AImage* image, /*out*/AHardwareBuffer** buffer) __INTRODUCED_IN(26);
 
 #endif /* __ANDROID_API__ >= 26 */
 
diff --git a/media/ndk/include/media/NdkImageReader.h b/media/ndk/include/media/NdkImageReader.h
index 571410b..e5d863c 100644
--- a/media/ndk/include/media/NdkImageReader.h
+++ b/media/ndk/include/media/NdkImageReader.h
@@ -37,6 +37,9 @@
 #define _NDK_IMAGE_READER_H
 
 #include <sys/cdefs.h>
+#ifdef __ANDROID_VNDK__
+#include <cutils/native_handle.h>
+#endif
 
 #include <android/native_window.h>
 #include "NdkMediaError.h"
@@ -88,7 +91,7 @@
  */
 media_status_t AImageReader_new(
         int32_t width, int32_t height, int32_t format, int32_t maxImages,
-        /*out*/AImageReader** reader);
+        /*out*/AImageReader** reader) __INTRODUCED_IN(24);
 
 /**
  * Delete an {@link AImageReader} and return all images generated by this reader to system.
@@ -100,7 +103,7 @@
  *
  * @param reader The image reader to be deleted.
  */
-void AImageReader_delete(AImageReader* reader);
+void AImageReader_delete(AImageReader* reader) __INTRODUCED_IN(24);
 
 /**
  * Get a {@link ANativeWindow} that can be used to produce {@link AImage} for this image reader.
@@ -114,7 +117,7 @@
  *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
  *         <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader or window is NULL.</li></ul>
  */
-media_status_t AImageReader_getWindow(AImageReader* reader, /*out*/ANativeWindow** window);
+media_status_t AImageReader_getWindow(AImageReader* reader, /*out*/ANativeWindow** window) __INTRODUCED_IN(24);
 
 /**
  * Query the default width of the {@link AImage} generated by this reader, in pixels.
@@ -130,7 +133,7 @@
  *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
  *         <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader or width is NULL.</li></ul>
  */
-media_status_t AImageReader_getWidth(const AImageReader* reader, /*out*/int32_t* width);
+media_status_t AImageReader_getWidth(const AImageReader* reader, /*out*/int32_t* width) __INTRODUCED_IN(24);
 
 /**
  * Query the default height of the {@link AImage} generated by this reader, in pixels.
@@ -146,7 +149,7 @@
  *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
  *         <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader or height is NULL.</li></ul>
  */
-media_status_t AImageReader_getHeight(const AImageReader* reader, /*out*/int32_t* height);
+media_status_t AImageReader_getHeight(const AImageReader* reader, /*out*/int32_t* height) __INTRODUCED_IN(24);
 
 /**
  * Query the format of the {@link AImage} generated by this reader.
@@ -159,7 +162,7 @@
  *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
  *         <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader or format is NULL.</li></ul>
  */
-media_status_t AImageReader_getFormat(const AImageReader* reader, /*out*/int32_t* format);
+media_status_t AImageReader_getFormat(const AImageReader* reader, /*out*/int32_t* format) __INTRODUCED_IN(24);
 
 /**
  * Query the maximum number of concurrently acquired {@link AImage}s of this reader.
@@ -172,7 +175,7 @@
  *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
  *         <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader or maxImages is NULL.</li></ul>
  */
-media_status_t AImageReader_getMaxImages(const AImageReader* reader, /*out*/int32_t* maxImages);
+media_status_t AImageReader_getMaxImages(const AImageReader* reader, /*out*/int32_t* maxImages) __INTRODUCED_IN(24);
 
 /**
  * Acquire the next {@link AImage} from the image reader's queue.
@@ -208,7 +211,7 @@
  *
  * @see AImageReader_acquireLatestImage
  */
-media_status_t AImageReader_acquireNextImage(AImageReader* reader, /*out*/AImage** image);
+media_status_t AImageReader_acquireNextImage(AImageReader* reader, /*out*/AImage** image) __INTRODUCED_IN(24);
 
 /**
 
@@ -252,7 +255,7 @@
  *
  * @see AImageReader_acquireNextImage
  */
-media_status_t AImageReader_acquireLatestImage(AImageReader* reader, /*out*/AImage** image);
+media_status_t AImageReader_acquireLatestImage(AImageReader* reader, /*out*/AImage** image) __INTRODUCED_IN(24);
 
 
 /**
@@ -296,7 +299,7 @@
  *         <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader is NULL.</li></ul>
  */
 media_status_t AImageReader_setImageListener(
-        AImageReader* reader, AImageReader_ImageListener* listener);
+        AImageReader* reader, AImageReader_ImageListener* listener) __INTRODUCED_IN(24);
 
 #endif /* __ANDROID_API__ >= 24 */
 
@@ -365,7 +368,7 @@
  */
 media_status_t AImageReader_newWithUsage(
         int32_t width, int32_t height, int32_t format, uint64_t usage, int32_t maxImages,
-        /*out*/ AImageReader** reader);
+        /*out*/ AImageReader** reader) __INTRODUCED_IN(26);
 
 /**
  * Acquire the next {@link AImage} from the image reader's queue asynchronously.
@@ -384,7 +387,7 @@
  * @see sync_get_fence_info
  */
 media_status_t AImageReader_acquireNextImageAsync(
-        AImageReader* reader, /*out*/AImage** image, /*out*/int* acquireFenceFd);
+        AImageReader* reader, /*out*/AImage** image, /*out*/int* acquireFenceFd) __INTRODUCED_IN(26);
 
 /**
  * Acquire the latest {@link AImage} from the image reader's queue asynchronously, dropping older
@@ -404,7 +407,7 @@
  * @see sync_get_fence_info
  */
 media_status_t AImageReader_acquireLatestImageAsync(
-        AImageReader* reader, /*out*/AImage** image, /*out*/int* acquireFenceFd);
+        AImageReader* reader, /*out*/AImage** image, /*out*/int* acquireFenceFd) __INTRODUCED_IN(26);
 /**
  * Signature of the callback which is called when {@link AImageReader} is about to remove a buffer.
  *
@@ -459,7 +462,24 @@
  * @see AImage_getHardwareBuffer
  */
 media_status_t AImageReader_setBufferRemovedListener(
-        AImageReader* reader, AImageReader_BufferRemovedListener* listener);
+        AImageReader* reader, AImageReader_BufferRemovedListener* listener) __INTRODUCED_IN(26);
+
+#ifdef __ANDROID_VNDK__
+/*
+ * Get the native_handle_t corresponding to the ANativeWindow owned by the
+ * AImageReader provided.
+ *
+ * @param reader The image reader of interest.
+ * @param handle The output native_handle_t. This native handle is owned by
+ *               this image reader.
+ *
+ * @return AMEDIA_OK if the method call succeeds.
+ *         AMEDIA_ERROR_INVALID_PARAMETER if reader or handle are NULL.
+ *         AMEDIA_ERROR_UNKNOWN if some other error is encountered.
+ */
+media_status_t AImageReader_getWindowNativeHandle(
+    AImageReader *reader, /* out */native_handle_t **handle);
+#endif
 
 #endif /* __ANDROID_API__ >= 26 */
 
diff --git a/media/ndk/include/media/NdkMediaCodec.h b/media/ndk/include/media/NdkMediaCodec.h
index f4a51d0..b3ee853 100644
--- a/media/ndk/include/media/NdkMediaCodec.h
+++ b/media/ndk/include/media/NdkMediaCodec.h
@@ -14,6 +14,15 @@
  * limitations under the License.
  */
 
+/**
+ * @addtogroup Media
+ * @{
+ */
+
+/**
+ * @file NdkMediaCodec.h
+ */
+
 /*
  * This file defines an NDK API.
  * Do not remove methods.
@@ -119,23 +128,23 @@
  * When configuring, you will need to specify whether to use the codec as an
  * encoder or decoder.
  */
-AMediaCodec* AMediaCodec_createCodecByName(const char *name);
+AMediaCodec* AMediaCodec_createCodecByName(const char *name) __INTRODUCED_IN(21);
 
 /**
  * Create codec by mime type. Most applications will use this, specifying a
  * mime type obtained from media extractor.
  */
-AMediaCodec* AMediaCodec_createDecoderByType(const char *mime_type);
+AMediaCodec* AMediaCodec_createDecoderByType(const char *mime_type) __INTRODUCED_IN(21);
 
 /**
  * Create encoder by name.
  */
-AMediaCodec* AMediaCodec_createEncoderByType(const char *mime_type);
+AMediaCodec* AMediaCodec_createEncoderByType(const char *mime_type) __INTRODUCED_IN(21);
 
 /**
  * delete the codec and free its resources
  */
-media_status_t AMediaCodec_delete(AMediaCodec*);
+media_status_t AMediaCodec_delete(AMediaCodec*) __INTRODUCED_IN(21);
 
 /**
  * Configure the codec. For decoding you would typically get the format from an extractor.
@@ -145,43 +154,43 @@
         const AMediaFormat* format,
         ANativeWindow* surface,
         AMediaCrypto *crypto,
-        uint32_t flags);
+        uint32_t flags) __INTRODUCED_IN(21);
 
 /**
  * Start the codec. A codec must be configured before it can be started, and must be started
  * before buffers can be sent to it.
  */
-media_status_t AMediaCodec_start(AMediaCodec*);
+media_status_t AMediaCodec_start(AMediaCodec*) __INTRODUCED_IN(21);
 
 /**
  * Stop the codec.
  */
-media_status_t AMediaCodec_stop(AMediaCodec*);
+media_status_t AMediaCodec_stop(AMediaCodec*) __INTRODUCED_IN(21);
 
 /*
  * Flush the codec's input and output. All indices previously returned from calls to
  * AMediaCodec_dequeueInputBuffer and AMediaCodec_dequeueOutputBuffer become invalid.
  */
-media_status_t AMediaCodec_flush(AMediaCodec*);
+media_status_t AMediaCodec_flush(AMediaCodec*) __INTRODUCED_IN(21);
 
 /**
  * Get an input buffer. The specified buffer index must have been previously obtained from
  * dequeueInputBuffer, and not yet queued.
  */
-uint8_t* AMediaCodec_getInputBuffer(AMediaCodec*, size_t idx, size_t *out_size);
+uint8_t* AMediaCodec_getInputBuffer(AMediaCodec*, size_t idx, size_t *out_size) __INTRODUCED_IN(21);
 
 /**
  * Get an output buffer. The specified buffer index must have been previously obtained from
  * dequeueOutputBuffer, and not yet queued.
  */
-uint8_t* AMediaCodec_getOutputBuffer(AMediaCodec*, size_t idx, size_t *out_size);
+uint8_t* AMediaCodec_getOutputBuffer(AMediaCodec*, size_t idx, size_t *out_size) __INTRODUCED_IN(21);
 
 /**
  * Get the index of the next available input buffer. An app will typically use this with
  * getInputBuffer() to get a pointer to the buffer, then copy the data to be encoded or decoded
  * into the buffer before passing it to the codec.
  */
-ssize_t AMediaCodec_dequeueInputBuffer(AMediaCodec*, int64_t timeoutUs);
+ssize_t AMediaCodec_dequeueInputBuffer(AMediaCodec*, int64_t timeoutUs) __INTRODUCED_IN(21);
 
 /*
  * __USE_FILE_OFFSET64 changes the type of off_t in LP32, which changes the ABI
@@ -212,7 +221,7 @@
  */
 media_status_t AMediaCodec_queueInputBuffer(AMediaCodec*, size_t idx,
                                             _off_t_compat offset, size_t size,
-                                            uint64_t time, uint32_t flags);
+                                            uint64_t time, uint32_t flags) __INTRODUCED_IN(21);
 
 /**
  * Send the specified buffer to the codec for processing.
@@ -220,7 +229,7 @@
 media_status_t AMediaCodec_queueSecureInputBuffer(AMediaCodec*, size_t idx,
                                                   _off_t_compat offset,
                                                   AMediaCodecCryptoInfo*,
-                                                  uint64_t time, uint32_t flags);
+                                                  uint64_t time, uint32_t flags) __INTRODUCED_IN(21);
 
 #undef _off_t_compat
 
@@ -228,21 +237,15 @@
  * Get the index of the next available buffer of processed data.
  */
 ssize_t AMediaCodec_dequeueOutputBuffer(AMediaCodec*, AMediaCodecBufferInfo *info,
-        int64_t timeoutUs);
-AMediaFormat* AMediaCodec_getOutputFormat(AMediaCodec*);
-
-/**
- * Get format of the buffer. The specified buffer index must have been previously obtained from
- * dequeueOutputBuffer.
- */
-AMediaFormat* AMediaCodec_getBufferFormat(AMediaCodec*, size_t index);
+        int64_t timeoutUs) __INTRODUCED_IN(21);
+AMediaFormat* AMediaCodec_getOutputFormat(AMediaCodec*) __INTRODUCED_IN(21);
 
 /**
  * If you are done with a buffer, use this call to return the buffer to
  * the codec. If you previously specified a surface when configuring this
  * video decoder you can optionally render the buffer.
  */
-media_status_t AMediaCodec_releaseOutputBuffer(AMediaCodec*, size_t idx, bool render);
+media_status_t AMediaCodec_releaseOutputBuffer(AMediaCodec*, size_t idx, bool render) __INTRODUCED_IN(21);
 
 /**
  * Dynamically sets the output surface of a codec.
@@ -254,7 +257,7 @@
  *
  * For more details, see the Java documentation for MediaCodec.setOutputSurface.
  */
-media_status_t AMediaCodec_setOutputSurface(AMediaCodec*, ANativeWindow* surface);
+media_status_t AMediaCodec_setOutputSurface(AMediaCodec*, ANativeWindow* surface) __INTRODUCED_IN(21);
 
 /**
  * If you are done with a buffer, use this call to update its surface timestamp
@@ -265,7 +268,7 @@
  * For more details, see the Java documentation for MediaCodec.releaseOutputBuffer.
  */
 media_status_t AMediaCodec_releaseOutputBufferAtTime(
-        AMediaCodec *mData, size_t idx, int64_t timestampNs);
+        AMediaCodec *mData, size_t idx, int64_t timestampNs) __INTRODUCED_IN(21);
 
 #if __ANDROID_API__ >= 26
 
@@ -281,7 +284,7 @@
  * For more details, see the Java documentation for MediaCodec.createInputSurface.
  */
 media_status_t AMediaCodec_createInputSurface(
-        AMediaCodec *mData, ANativeWindow **surface);
+        AMediaCodec *mData, ANativeWindow **surface) __INTRODUCED_IN(26);
 
 /**
  * Creates a persistent Surface that can be used as the input to encoder
@@ -297,7 +300,7 @@
  * For more details, see the Java documentation for MediaCodec.createPersistentInputSurface.
  */
 media_status_t AMediaCodec_createPersistentInputSurface(
-        ANativeWindow **surface);
+        ANativeWindow **surface) __INTRODUCED_IN(26);
 
 /**
  * Set a persistent-surface that can be used as the input to encoder, in place of input buffers
@@ -310,7 +313,7 @@
  * For more details, see the Java documentation for MediaCodec.setInputSurface.
  */
 media_status_t AMediaCodec_setInputSurface(
-        AMediaCodec *mData, ANativeWindow *surface);
+        AMediaCodec *mData, ANativeWindow *surface) __INTRODUCED_IN(26);
 
 /**
  * Signal additional parameters to the codec instance.
@@ -321,7 +324,7 @@
  * NOTE: Some of these parameter changes may silently fail to apply.
  */
 media_status_t AMediaCodec_setParameters(
-        AMediaCodec *mData, const AMediaFormat* params);
+        AMediaCodec *mData, const AMediaFormat* params) __INTRODUCED_IN(26);
 
 /**
  * Signals end-of-stream on input. Equivalent to submitting an empty buffer with
@@ -337,23 +340,29 @@
  *
  * For more details, see the Java documentation for MediaCodec.signalEndOfInputStream.
  */
-media_status_t AMediaCodec_signalEndOfInputStream(AMediaCodec *mData);
+media_status_t AMediaCodec_signalEndOfInputStream(AMediaCodec *mData) __INTRODUCED_IN(26);
 
 #endif /* __ANDROID_API__ >= 26 */
 
 #if __ANDROID_API__ >= 28
 
 /**
+ * Get format of the buffer. The specified buffer index must have been previously obtained from
+ * dequeueOutputBuffer.
+ */
+AMediaFormat* AMediaCodec_getBufferFormat(AMediaCodec*, size_t index) __INTRODUCED_IN(28);
+
+/**
  * Get the component name. If the codec was created by createDecoderByType
  * or createEncoderByType, what component is chosen is not known beforehand.
  * Caller shall call AMediaCodec_releaseName to free the returned pointer.
  */
-media_status_t AMediaCodec_getName(AMediaCodec*, char** out_name);
+media_status_t AMediaCodec_getName(AMediaCodec*, char** out_name) __INTRODUCED_IN(28);
 
 /**
  * Free the memory pointed by name which is returned by AMediaCodec_getName.
  */
-void AMediaCodec_releaseName(AMediaCodec*, char* name);
+void AMediaCodec_releaseName(AMediaCodec*, char* name) __INTRODUCED_IN(28);
 
 /**
  * Set an asynchronous callback for actionable AMediaCodec events.
@@ -377,32 +386,32 @@
 media_status_t AMediaCodec_setAsyncNotifyCallback(
         AMediaCodec*,
         AMediaCodecOnAsyncNotifyCallback callback,
-        void *userdata);
+        void *userdata) __INTRODUCED_IN(28);
 
 /**
  * Release the crypto if applicable.
  */
-media_status_t AMediaCodec_releaseCrypto(AMediaCodec*);
+media_status_t AMediaCodec_releaseCrypto(AMediaCodec*) __INTRODUCED_IN(28);
 
 /**
  * Call this after AMediaCodec_configure() returns successfully to get the input
  * format accepted by the codec. Do this to determine what optional configuration
  * parameters were supported by the codec.
  */
-AMediaFormat* AMediaCodec_getInputFormat(AMediaCodec*);
+AMediaFormat* AMediaCodec_getInputFormat(AMediaCodec*) __INTRODUCED_IN(28);
 
 /**
  * Returns true if the codec cannot proceed further, but can be recovered by stopping,
  * configuring, and starting again.
  */
-bool AMediaCodecActionCode_isRecoverable(int32_t actionCode);
+bool AMediaCodecActionCode_isRecoverable(int32_t actionCode) __INTRODUCED_IN(28);
 
 /**
  * Returns true if the codec error is a transient issue, perhaps due to
  * resource constraints, and that the method (or encoding/decoding) may be
  * retried at a later time.
  */
-bool AMediaCodecActionCode_isTransient(int32_t actionCode);
+bool AMediaCodecActionCode_isTransient(int32_t actionCode) __INTRODUCED_IN(28);
 
 #endif /* __ANDROID_API__ >= 28 */
 
@@ -438,54 +447,56 @@
         uint8_t iv[16],
         cryptoinfo_mode_t mode,
         size_t *clearbytes,
-        size_t *encryptedbytes);
+        size_t *encryptedbytes) __INTRODUCED_IN(21);
 
 /**
  * delete an AMediaCodecCryptoInfo created previously with AMediaCodecCryptoInfo_new, or
  * obtained from AMediaExtractor
  */
-media_status_t AMediaCodecCryptoInfo_delete(AMediaCodecCryptoInfo*);
+media_status_t AMediaCodecCryptoInfo_delete(AMediaCodecCryptoInfo*) __INTRODUCED_IN(21);
 
 /**
  * Set the crypto pattern on an AMediaCryptoInfo object
  */
 void AMediaCodecCryptoInfo_setPattern(
         AMediaCodecCryptoInfo *info,
-        cryptoinfo_pattern_t *pattern);
+        cryptoinfo_pattern_t *pattern) __INTRODUCED_IN(21);
 
 /**
  * The number of subsamples that make up the buffer's contents.
  */
-size_t AMediaCodecCryptoInfo_getNumSubSamples(AMediaCodecCryptoInfo*);
+size_t AMediaCodecCryptoInfo_getNumSubSamples(AMediaCodecCryptoInfo*) __INTRODUCED_IN(21);
 
 /**
  * A 16-byte opaque key
  */
-media_status_t AMediaCodecCryptoInfo_getKey(AMediaCodecCryptoInfo*, uint8_t *dst);
+media_status_t AMediaCodecCryptoInfo_getKey(AMediaCodecCryptoInfo*, uint8_t *dst) __INTRODUCED_IN(21);
 
 /**
  * A 16-byte initialization vector
  */
-media_status_t AMediaCodecCryptoInfo_getIV(AMediaCodecCryptoInfo*, uint8_t *dst);
+media_status_t AMediaCodecCryptoInfo_getIV(AMediaCodecCryptoInfo*, uint8_t *dst) __INTRODUCED_IN(21);
 
 /**
  * The type of encryption that has been applied,
  * one of AMEDIACODECRYPTOINFO_MODE_CLEAR or AMEDIACODECRYPTOINFO_MODE_AES_CTR.
  */
-cryptoinfo_mode_t AMediaCodecCryptoInfo_getMode(AMediaCodecCryptoInfo*);
+cryptoinfo_mode_t AMediaCodecCryptoInfo_getMode(AMediaCodecCryptoInfo*) __INTRODUCED_IN(21);
 
 /**
  * The number of leading unencrypted bytes in each subsample.
  */
-media_status_t AMediaCodecCryptoInfo_getClearBytes(AMediaCodecCryptoInfo*, size_t *dst);
+media_status_t AMediaCodecCryptoInfo_getClearBytes(AMediaCodecCryptoInfo*, size_t *dst) __INTRODUCED_IN(21);
 
 /**
  * The number of trailing encrypted bytes in each subsample.
  */
-media_status_t AMediaCodecCryptoInfo_getEncryptedBytes(AMediaCodecCryptoInfo*, size_t *dst);
+media_status_t AMediaCodecCryptoInfo_getEncryptedBytes(AMediaCodecCryptoInfo*, size_t *dst) __INTRODUCED_IN(21);
 
 #endif /* __ANDROID_API__ >= 21 */
 
 __END_DECLS
 
 #endif //_NDK_MEDIA_CODEC_H
+
+/** @} */
diff --git a/media/ndk/include/media/NdkMediaCrypto.h b/media/ndk/include/media/NdkMediaCrypto.h
index d31dbdc..bcdf9a0 100644
--- a/media/ndk/include/media/NdkMediaCrypto.h
+++ b/media/ndk/include/media/NdkMediaCrypto.h
@@ -14,6 +14,14 @@
  * limitations under the License.
  */
 
+/**
+ * @addtogroup Media
+ * @{
+ */
+
+/**
+ * @file NdkMediaCrypto.h
+ */
 
 /*
  * This file defines an NDK API.
@@ -41,16 +49,18 @@
 
 #if __ANDROID_API__ >= 21
 
-bool AMediaCrypto_isCryptoSchemeSupported(const AMediaUUID uuid);
+bool AMediaCrypto_isCryptoSchemeSupported(const AMediaUUID uuid) __INTRODUCED_IN(21);
 
-bool AMediaCrypto_requiresSecureDecoderComponent(const char *mime);
+bool AMediaCrypto_requiresSecureDecoderComponent(const char *mime) __INTRODUCED_IN(21);
 
-AMediaCrypto* AMediaCrypto_new(const AMediaUUID uuid, const void *initData, size_t initDataSize);
+AMediaCrypto* AMediaCrypto_new(const AMediaUUID uuid, const void *initData, size_t initDataSize) __INTRODUCED_IN(21);
 
-void AMediaCrypto_delete(AMediaCrypto* crypto);
+void AMediaCrypto_delete(AMediaCrypto* crypto) __INTRODUCED_IN(21);
 
 #endif /* __ANDROID_API__ >= 21 */
 
 __END_DECLS
 
 #endif // _NDK_MEDIA_CRYPTO_H
+
+/** @} */
diff --git a/media/ndk/include/media/NdkMediaDataSource.h b/media/ndk/include/media/NdkMediaDataSource.h
index 9e2e351..16b1eb3 100644
--- a/media/ndk/include/media/NdkMediaDataSource.h
+++ b/media/ndk/include/media/NdkMediaDataSource.h
@@ -43,14 +43,9 @@
 /*
  * AMediaDataSource's callbacks will be invoked on an implementation-defined thread
  * or thread pool. No guarantees are provided about which thread(s) will be used for
- * callbacks. However, it is guaranteed that AMediaDataSource's callbacks will only
- * ever be invoked by a single thread at a time.
- *
- * There will be a thread synchronization point between each call to ensure that
- * modifications to the state of your AMediaDataSource are visible to future
- * calls. This means you don't need to do your own synchronization unless you're
- * modifying the AMediaDataSource from another thread while it's being used by the
- * framework.
+ * callbacks. For example, |close| can be invoked from a different thread than the
+ * thread invoking |readAt|. As such, the Implementations of AMediaDataSource callbacks
+ * must be threadsafe.
  */
 
 /**
@@ -74,9 +69,19 @@
 typedef ssize_t (*AMediaDataSourceGetSize)(void *userdata);
 
 /**
- * Called to close the data source and release associated resources.
- * The NDK media framework guarantees that after |close| is called
- * no future callbacks will be invoked on the data source.
+ * Called to close the data source, unblock reads, and release associated
+ * resources.
+ *
+ * The NDK media framework guarantees that after the first |close| is
+ * called, no future callbacks will be invoked on the data source except
+ * for |close| itself.
+ *
+ * Closing a data source allows readAt calls that were blocked waiting
+ * for I/O data to return promptly.
+ *
+ * When using AMediaDataSource as input to AMediaExtractor, closing
+ * has the effect of unblocking slow reads inside of setDataSource
+ * and readSampleData.
  */
 typedef void (*AMediaDataSourceClose)(void *userdata);
 
@@ -84,19 +89,51 @@
  * Create new media data source. Returns NULL if memory allocation
  * for the new data source object fails.
  */
-AMediaDataSource* AMediaDataSource_new();
+AMediaDataSource* AMediaDataSource_new() __INTRODUCED_IN(28);
+
+#if __ANDROID_API__ >= 29
+
+/**
+ * Called to get an estimate of the number of bytes that can be read from this data source
+ * starting at |offset| without blocking for I/O.
+ *
+ * Return -1 when such an estimate is not possible.
+ */
+typedef ssize_t (*AMediaDataSourceGetAvailableSize)(void *userdata, off64_t offset);
+
+/**
+ * Create new media data source. Returns NULL if memory allocation
+ * for the new data source object fails.
+ *
+ * Set the |uri| from which the data source will read,
+ * plus additional http headers when initiating the request.
+ *
+ * Headers will contain corresponding items from |key_values|
+ * in the following fashion:
+ *
+ * key_values[0]:key_values[1]
+ * key_values[2]:key_values[3]
+ * ...
+ * key_values[(numheaders - 1) * 2]:key_values[(numheaders - 1) * 2 + 1]
+ *
+ */
+AMediaDataSource* AMediaDataSource_newUri(const char *uri,
+        int numheaders,
+        const char * const *key_values) __INTRODUCED_IN(29);
+
+#endif  /*__ANDROID_API__ >= 29 */
 
 /**
  * Delete a previously created media data source.
  */
-void AMediaDataSource_delete(AMediaDataSource*);
+void AMediaDataSource_delete(AMediaDataSource*) __INTRODUCED_IN(28);
 
 /**
  * Set an user provided opaque handle. This opaque handle is passed as
  * the first argument to the data source callbacks.
  */
 void AMediaDataSource_setUserdata(
-        AMediaDataSource*, void *userdata);
+        AMediaDataSource*, void *userdata) __INTRODUCED_IN(28);
 
 /**
  * Set a custom callback for supplying random access media data to the
@@ -111,7 +148,7 @@
  */
 void AMediaDataSource_setReadAt(
         AMediaDataSource*,
-        AMediaDataSourceReadAt);
+        AMediaDataSourceReadAt) __INTRODUCED_IN(28);
 
 /**
  * Set a custom callback for supplying the size of the data source to the
@@ -122,7 +159,7 @@
  */
 void AMediaDataSource_setGetSize(
         AMediaDataSource*,
-        AMediaDataSourceGetSize);
+        AMediaDataSourceGetSize) __INTRODUCED_IN(28);
 
 /**
  * Set a custom callback to receive signal from the NDK media framework
@@ -133,10 +170,34 @@
  */
 void AMediaDataSource_setClose(
         AMediaDataSource*,
-        AMediaDataSourceClose);
+        AMediaDataSourceClose) __INTRODUCED_IN(28);
 
 #endif  /*__ANDROID_API__ >= 28 */
 
+#if __ANDROID_API__ >= 29
+
+/**
+ * Close the data source, unblock reads, and release associated resources.
+ *
+ * Please refer to the definition of AMediaDataSourceClose for
+ * additional details.
+ */
+void AMediaDataSource_close(AMediaDataSource*) __INTRODUCED_IN(29);
+
+/**
+ * Set a custom callback for supplying the estimated number of bytes
+ * that can be read from this data source starting at an offset without
+ * blocking for I/O.
+ *
+ * Please refer to the definition of AMediaDataSourceGetAvailableSize
+ * for additional details.
+ */
+void AMediaDataSource_setGetAvailableSize(
+        AMediaDataSource*,
+        AMediaDataSourceGetAvailableSize) __INTRODUCED_IN(29);
+
+#endif  /*__ANDROID_API__ >= 29 */
+
 __END_DECLS
 
 #endif // _NDK_MEDIA_DATASOURCE_H
diff --git a/media/ndk/include/media/NdkMediaDrm.h b/media/ndk/include/media/NdkMediaDrm.h
index 9e9f4c3..2e438d9 100644
--- a/media/ndk/include/media/NdkMediaDrm.h
+++ b/media/ndk/include/media/NdkMediaDrm.h
@@ -14,6 +14,15 @@
  * limitations under the License.
  */
 
+/**
+ * @addtogroup Media
+ * @{
+ */
+
+/**
+ * @file NdkMediaDrm.h
+ */
+
 /*
  * This file defines an NDK API.
  * Do not remove methods.
@@ -47,6 +56,7 @@
 typedef AMediaDrmByteArray AMediaDrmScope;
 typedef AMediaDrmByteArray AMediaDrmKeySetId;
 typedef AMediaDrmByteArray AMediaDrmSecureStop;
+typedef AMediaDrmByteArray AMediaDrmKeyId;
 
 typedef enum AMediaDrmEventType {
     /**
@@ -72,59 +82,18 @@
      * This event may indicate some specific vendor-defined condition, see your
      * DRM provider documentation for details
      */
-    EVENT_VENDOR_DEFINED = 4
+    EVENT_VENDOR_DEFINED = 4,
+
+    /**
+     * This event indicates that a session opened by the app has been reclaimed
+     * by the resource manager.
+     */
+    EVENT_SESSION_RECLAIMED = 5,
 } AMediaDrmEventType;
 
-typedef void (*AMediaDrmEventListener)(AMediaDrm *, const AMediaDrmSessionId *sessionId,
-        AMediaDrmEventType eventType, int extra, const uint8_t *data, size_t dataSize);
-
-#if __ANDROID_API__ >= 21
-
-/**
- * Query if the given scheme identified by its UUID is supported on this device, and
- * whether the drm plugin is able to handle the media container format specified by mimeType.
- *
- * uuid identifies the universal unique ID of the crypto scheme. uuid must be 16 bytes.
- * mimeType is the MIME type of the media container, e.g. "video/mp4".  If mimeType
- * is not known or required, it can be provided as NULL.
- */
-bool AMediaDrm_isCryptoSchemeSupported(const uint8_t *uuid, const char *mimeType);
-
-/**
- * Create a MediaDrm instance from a UUID
- * uuid identifies the universal unique ID of the crypto scheme. uuid must be 16 bytes.
- */
-AMediaDrm* AMediaDrm_createByUUID(const uint8_t *uuid);
-
-/**
- * Release a MediaDrm object
- */
-void AMediaDrm_release(AMediaDrm *);
-
-/**
- * Register a callback to be invoked when an event occurs
- *
- * listener is the callback that will be invoked on event
- */
-media_status_t AMediaDrm_setOnEventListener(AMediaDrm *, AMediaDrmEventListener listener);
-
-/**
- * Open a new session with the MediaDrm object.  A session ID is returned.
- *
- * returns MEDIADRM_NOT_PROVISIONED_ERROR if provisioning is needed
- * returns MEDIADRM_RESOURCE_BUSY_ERROR if required resources are in use
- */
-media_status_t AMediaDrm_openSession(AMediaDrm *, AMediaDrmSessionId *sessionId);
-
-/**
- * Close a session on the MediaDrm object that was previously opened
- * with AMediaDrm_openSession.
- */
-media_status_t AMediaDrm_closeSession(AMediaDrm *, const AMediaDrmSessionId *sessionId);
-
 typedef enum AMediaDrmKeyType {
     /**
-     * This key request type species that the keys will be for online use, they will
+     * This key request type specifies that the keys will be for online use, they will
      * not be saved to the device for subsequent use when the device is not connected
      * to a network.
      */
@@ -150,6 +119,116 @@
     const char *mValue;
 } AMediaDrmKeyValue;
 
+typedef enum AMediaKeyStatusType {
+    /**
+     * The key is currently usable to decrypt media data.
+     */
+    KEY_STATUS_TYPE_USABLE,
+
+    /**
+     * The key is no longer usable to decrypt media data because its expiration
+     * time has passed.
+     */
+    KEY_STATUS_TYPE_EXPIRED,
+
+    /**
+     * The key is not currently usable to decrypt media data because its output
+     * requirements cannot currently be met.
+     */
+    KEY_STATUS_TYPE_OUTPUTNOTALLOWED,
+
+    /**
+     * The status of the key is not yet known and is being determined.
+     */
+    KEY_STATUS_TYPE_STATUSPENDING,
+
+    /**
+     * The key is not currently usable to decrypt media data because of an
+     * internal error in processing unrelated to input parameters.
+     */
+    KEY_STATUS_TYPE_INTERNALERROR,
+
+} AMediaDrmKeyStatusType;
+
+typedef struct AMediaDrmKeyStatus {
+    AMediaDrmKeyId keyId;
+    AMediaDrmKeyStatusType keyType;
+} AMediaDrmKeyStatus;
+
+typedef void (*AMediaDrmEventListener)(AMediaDrm *, const AMediaDrmSessionId *sessionId,
+        AMediaDrmEventType eventType, int extra, const uint8_t *data, size_t dataSize);
+
+typedef void (*AMediaDrmExpirationUpdateListener)(AMediaDrm *,
+        const AMediaDrmSessionId *sessionId, int64_t expiryTimeInMS);
+
+typedef void (*AMediaDrmKeysChangeListener)(AMediaDrm *,
+        const AMediaDrmSessionId *sessionId, const AMediaDrmKeyStatus *keyStatus,
+        size_t numKeys, bool hasNewUsableKey);
+
+#if __ANDROID_API__ >= 21
+
+/**
+ * Query if the given scheme identified by its UUID is supported on this device, and
+ * whether the drm plugin is able to handle the media container format specified by mimeType.
+ *
+ * uuid identifies the universal unique ID of the crypto scheme. uuid must be 16 bytes.
+ * mimeType is the MIME type of the media container, e.g. "video/mp4".  If mimeType
+ * is not known or required, it can be provided as NULL.
+ */
+bool AMediaDrm_isCryptoSchemeSupported(const uint8_t *uuid,
+        const char *mimeType) __INTRODUCED_IN(21);
+
+/**
+ * Create a MediaDrm instance from a UUID
+ * uuid identifies the universal unique ID of the crypto scheme. uuid must be 16 bytes.
+ */
+AMediaDrm* AMediaDrm_createByUUID(const uint8_t *uuid) __INTRODUCED_IN(21);
+
+/**
+ * Release a MediaDrm object
+ */
+void AMediaDrm_release(AMediaDrm *) __INTRODUCED_IN(21);
+
+/**
+ * Register a callback to be invoked when an event occurs
+ *
+ * listener is the callback that will be invoked on event
+ */
+media_status_t AMediaDrm_setOnEventListener(AMediaDrm *,
+        AMediaDrmEventListener listener) __INTRODUCED_IN(21);
+
+/**
+ * Register a callback to be invoked when an expiration update event occurs
+ *
+ * listener is the callback that will be invoked on event
+ */
+media_status_t AMediaDrm_setOnExpirationUpdateListener(AMediaDrm *,
+        AMediaDrmExpirationUpdateListener listener) __INTRODUCED_IN(29);
+
+/**
+ * Register a callback to be invoked when a key status change event occurs
+ *
+ * listener is the callback that will be invoked on event
+ */
+media_status_t AMediaDrm_setOnKeysChangeListener(AMediaDrm *,
+        AMediaDrmKeysChangeListener listener) __INTRODUCED_IN(29);
+
+/**
+ * Open a new session with the MediaDrm object.  A session ID is returned.
+ *
+ * returns MEDIADRM_NOT_PROVISIONED_ERROR if provisioning is needed
+ * returns MEDIADRM_RESOURCE_BUSY_ERROR if required resources are in use
+ */
+media_status_t AMediaDrm_openSession(AMediaDrm *,
+        AMediaDrmSessionId *sessionId) __INTRODUCED_IN(21);
+
+/**
+ * Close a session on the MediaDrm object that was previously opened
+ * with AMediaDrm_openSession.
+ */
+media_status_t AMediaDrm_closeSession(AMediaDrm *,
+        const AMediaDrmSessionId *sessionId) __INTRODUCED_IN(21);
+
 /**
  * A key request/response exchange occurs between the app and a license server
  * to obtain or release keys used to decrypt encrypted content.
@@ -199,7 +278,7 @@
 media_status_t AMediaDrm_getKeyRequest(AMediaDrm *, const AMediaDrmScope *scope,
         const uint8_t *init, size_t initSize, const char *mimeType, AMediaDrmKeyType keyType,
         const AMediaDrmKeyValue *optionalParameters, size_t numOptionalParameters,
-        const uint8_t **keyRequest, size_t *keyRequestSize);
+        const uint8_t **keyRequest, size_t *keyRequestSize) __INTRODUCED_IN(21);
 
 /**
  * A key response is received from the license server by the app, then it is
@@ -219,7 +298,8 @@
  */
 
 media_status_t AMediaDrm_provideKeyResponse(AMediaDrm *, const AMediaDrmScope *scope,
-        const uint8_t *response, size_t responseSize, AMediaDrmKeySetId *keySetId);
+        const uint8_t *response, size_t responseSize,
+        AMediaDrmKeySetId *keySetId) __INTRODUCED_IN(21);
 
 /**
  * Restore persisted offline keys into a new session.  keySetId identifies the
@@ -229,14 +309,15 @@
  * keySetId identifies the saved key set to restore
  */
 media_status_t AMediaDrm_restoreKeys(AMediaDrm *, const AMediaDrmSessionId *sessionId,
-        const AMediaDrmKeySetId *keySetId);
+        const AMediaDrmKeySetId *keySetId) __INTRODUCED_IN(21);
 
 /**
  * Remove the current keys from a session.
  *
  * keySetId identifies keys to remove
  */
-media_status_t AMediaDrm_removeKeys(AMediaDrm *, const AMediaDrmSessionId *keySetId);
+media_status_t AMediaDrm_removeKeys(AMediaDrm *,
+        const AMediaDrmSessionId *keySetId) __INTRODUCED_IN(21);
 
 /**
  * Request an informative description of the key status for the session.  The status is
@@ -252,7 +333,7 @@
  * and numPairs will be set to the number of pairs available.
  */
 media_status_t AMediaDrm_queryKeyStatus(AMediaDrm *, const AMediaDrmSessionId *sessionId,
-        AMediaDrmKeyValue *keyValuePairs, size_t *numPairs);
+        AMediaDrmKeyValue *keyValuePairs, size_t *numPairs) __INTRODUCED_IN(21);
 
 
 /**
@@ -271,7 +352,7 @@
  *       the next call to getProvisionRequest.
  */
 media_status_t AMediaDrm_getProvisionRequest(AMediaDrm *, const uint8_t **provisionRequest,
-        size_t *provisionRequestSize, const char **serverUrl);
+        size_t *provisionRequestSize, const char **serverUrl) __INTRODUCED_IN(21);
 
 
 /**
@@ -286,7 +367,7 @@
  * server rejected the request
  */
 media_status_t AMediaDrm_provideProvisionResponse(AMediaDrm *,
-        const uint8_t *response, size_t responseSize);
+        const uint8_t *response, size_t responseSize) __INTRODUCED_IN(21);
 
 
 /**
@@ -311,7 +392,7 @@
  * number required.
  */
 media_status_t AMediaDrm_getSecureStops(AMediaDrm *,
-        AMediaDrmSecureStop *secureStops, size_t *numSecureStops);
+        AMediaDrmSecureStop *secureStops, size_t *numSecureStops) __INTRODUCED_IN(21);
 
 /**
  * Process the SecureStop server response message ssRelease.  After authenticating
@@ -320,7 +401,7 @@
  * ssRelease is the server response indicating which secure stops to release
  */
 media_status_t AMediaDrm_releaseSecureStops(AMediaDrm *,
-        const AMediaDrmSecureStop *ssRelease);
+        const AMediaDrmSecureStop *ssRelease) __INTRODUCED_IN(21);
 
 /**
  * String property name: identifies the maker of the DRM engine plugin
@@ -353,7 +434,7 @@
  * will remain valid until the next call to AMediaDrm_getPropertyString.
  */
 media_status_t AMediaDrm_getPropertyString(AMediaDrm *, const char *propertyName,
-        const char **propertyValue);
+        const char **propertyValue) __INTRODUCED_IN(21);
 
 /**
  * Byte array property name: the device unique identifier is established during
@@ -368,19 +449,19 @@
  * will remain valid until the next call to AMediaDrm_getPropertyByteArray.
  */
 media_status_t AMediaDrm_getPropertyByteArray(AMediaDrm *, const char *propertyName,
-        AMediaDrmByteArray *propertyValue);
+        AMediaDrmByteArray *propertyValue) __INTRODUCED_IN(21);
 
 /**
  * Set a DRM engine plugin String property value.
  */
 media_status_t AMediaDrm_setPropertyString(AMediaDrm *, const char *propertyName,
-        const char *value);
+        const char *value) __INTRODUCED_IN(21);
 
 /**
  * Set a DRM engine plugin byte array property value.
  */
 media_status_t AMediaDrm_setPropertyByteArray(AMediaDrm *, const char *propertyName,
-        const uint8_t *value, size_t valueSize);
+        const uint8_t *value, size_t valueSize) __INTRODUCED_IN(21);
 
 /**
  * In addition to supporting decryption of DASH Common Encrypted Media, the
@@ -409,7 +490,7 @@
  */
 media_status_t AMediaDrm_encrypt(AMediaDrm *, const AMediaDrmSessionId *sessionId,
         const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
-        const uint8_t *input, uint8_t *output, size_t dataSize);
+        const uint8_t *input, uint8_t *output, size_t dataSize) __INTRODUCED_IN(21);
 
 /*
  * Decrypt the data referenced by input of length dataSize using algorithm specified
@@ -420,7 +501,7 @@
  */
 media_status_t AMediaDrm_decrypt(AMediaDrm *, const AMediaDrmSessionId *sessionId,
         const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
-        const uint8_t *input, uint8_t *output, size_t dataSize);
+        const uint8_t *input, uint8_t *output, size_t dataSize) __INTRODUCED_IN(21);
 
 /*
  * Generate a signature using the specified macAlgorithm over the message data
@@ -433,7 +514,7 @@
  */
 media_status_t AMediaDrm_sign(AMediaDrm *, const AMediaDrmSessionId *sessionId,
         const char *macAlgorithm, uint8_t *keyId, uint8_t *message, size_t messageSize,
-        uint8_t *signature, size_t *signatureSize);
+        uint8_t *signature, size_t *signatureSize) __INTRODUCED_IN(21);
 
 /*
  * Perform a signature verification using the specified macAlgorithm over the message
@@ -444,10 +525,12 @@
  */
 media_status_t AMediaDrm_verify(AMediaDrm *, const AMediaDrmSessionId *sessionId,
         const char *macAlgorithm, uint8_t *keyId, const uint8_t *message, size_t messageSize,
-        const uint8_t *signature, size_t signatureSize);
+        const uint8_t *signature, size_t signatureSize) __INTRODUCED_IN(21);
 
 #endif /* __ANDROID_API__ >= 21 */
 
 __END_DECLS
 
 #endif //_NDK_MEDIA_DRM_H
+
+/** @} */
diff --git a/media/ndk/include/media/NdkMediaError.h b/media/ndk/include/media/NdkMediaError.h
index 13aacc9..2be1d6e 100644
--- a/media/ndk/include/media/NdkMediaError.h
+++ b/media/ndk/include/media/NdkMediaError.h
@@ -14,6 +14,14 @@
  * limitations under the License.
  */
 
+/**
+ * @addtogroup Media
+ * @{
+ */
+
+/**
+ * @file NdkMediaError.h
+ */
 
 /*
  * This file defines an NDK API.
@@ -55,6 +63,7 @@
     AMEDIA_ERROR_INVALID_OPERATION     = AMEDIA_ERROR_BASE - 5,
     AMEDIA_ERROR_END_OF_STREAM         = AMEDIA_ERROR_BASE - 6,
     AMEDIA_ERROR_IO                    = AMEDIA_ERROR_BASE - 7,
+    AMEDIA_ERROR_WOULD_BLOCK           = AMEDIA_ERROR_BASE - 8,
 
     AMEDIA_DRM_ERROR_BASE              = -20000,
     AMEDIA_DRM_NOT_PROVISIONED         = AMEDIA_DRM_ERROR_BASE - 1,
@@ -79,3 +88,5 @@
 __END_DECLS
 
 #endif // _NDK_MEDIA_ERROR_H
+
+/** @} */
diff --git a/media/ndk/include/media/NdkMediaExtractor.h b/media/ndk/include/media/NdkMediaExtractor.h
index f7b9cfd..e3d9fe6 100644
--- a/media/ndk/include/media/NdkMediaExtractor.h
+++ b/media/ndk/include/media/NdkMediaExtractor.h
@@ -14,6 +14,14 @@
  * limitations under the License.
  */
 
+/**
+ * @addtogroup Media
+ * @{
+ */
+
+/**
+ * @file NdkMediaExtractor.h
+ */
 
 /*
  * This file defines an NDK API.
@@ -46,43 +54,44 @@
 /**
  * Create new media extractor
  */
-AMediaExtractor* AMediaExtractor_new();
+AMediaExtractor* AMediaExtractor_new() __INTRODUCED_IN(21);
 
 /**
  * Delete a previously created media extractor
  */
-media_status_t AMediaExtractor_delete(AMediaExtractor*);
+media_status_t AMediaExtractor_delete(AMediaExtractor*) __INTRODUCED_IN(21);
 
 /**
  *  Set the file descriptor from which the extractor will read.
  */
 media_status_t AMediaExtractor_setDataSourceFd(AMediaExtractor*, int fd, off64_t offset,
-        off64_t length);
+        off64_t length) __INTRODUCED_IN(21);
 
 /**
  * Set the URI from which the extractor will read.
  */
-media_status_t AMediaExtractor_setDataSource(AMediaExtractor*, const char *location);
-        // TODO support headers
+media_status_t AMediaExtractor_setDataSource(AMediaExtractor*,
+        const char *location) __INTRODUCED_IN(21);
 
 #if __ANDROID_API__ >= 28
 
 /**
  * Set the custom data source implementation from which the extractor will read.
  */
-media_status_t AMediaExtractor_setDataSourceCustom(AMediaExtractor*, AMediaDataSource *src);
+media_status_t AMediaExtractor_setDataSourceCustom(AMediaExtractor*,
+        AMediaDataSource *src) __INTRODUCED_IN(28);
 
 #endif /* __ANDROID_API__ >= 28 */
 
 /**
  * Return the number of tracks in the previously specified media file
  */
-size_t AMediaExtractor_getTrackCount(AMediaExtractor*);
+size_t AMediaExtractor_getTrackCount(AMediaExtractor*) __INTRODUCED_IN(21);
 
 /**
  * Return the format of the specified track. The caller must free the returned format
  */
-AMediaFormat* AMediaExtractor_getTrackFormat(AMediaExtractor*, size_t idx);
+AMediaFormat* AMediaExtractor_getTrackFormat(AMediaExtractor*, size_t idx) __INTRODUCED_IN(21);
 
 /**
  * Select the specified track. Subsequent calls to readSampleData, getSampleTrackIndex and
@@ -90,41 +99,42 @@
  * Selecting the same track multiple times has no effect, the track is
  * only selected once.
  */
-media_status_t AMediaExtractor_selectTrack(AMediaExtractor*, size_t idx);
+media_status_t AMediaExtractor_selectTrack(AMediaExtractor*, size_t idx) __INTRODUCED_IN(21);
 
 /**
  * Unselect the specified track. Subsequent calls to readSampleData, getSampleTrackIndex and
  * getSampleTime only retrieve information for the subset of tracks selected..
  */
-media_status_t AMediaExtractor_unselectTrack(AMediaExtractor*, size_t idx);
+media_status_t AMediaExtractor_unselectTrack(AMediaExtractor*, size_t idx) __INTRODUCED_IN(21);
 
 /**
  * Read the current sample.
  */
-ssize_t AMediaExtractor_readSampleData(AMediaExtractor*, uint8_t *buffer, size_t capacity);
+ssize_t AMediaExtractor_readSampleData(AMediaExtractor*,
+        uint8_t *buffer, size_t capacity) __INTRODUCED_IN(21);
 
 /**
  * Read the current sample's flags.
  */
-uint32_t AMediaExtractor_getSampleFlags(AMediaExtractor*); // see definitions below
+uint32_t AMediaExtractor_getSampleFlags(AMediaExtractor*) __INTRODUCED_IN(21);
 
 /**
  * Returns the track index the current sample originates from (or -1
  * if no more samples are available)
  */
-int AMediaExtractor_getSampleTrackIndex(AMediaExtractor*);
+int AMediaExtractor_getSampleTrackIndex(AMediaExtractor*) __INTRODUCED_IN(21);
 
 /**
  * Returns the current sample's presentation time in microseconds.
  * or -1 if no more samples are available.
  */
-int64_t AMediaExtractor_getSampleTime(AMediaExtractor*);
+int64_t AMediaExtractor_getSampleTime(AMediaExtractor*) __INTRODUCED_IN(21);
 
 /**
  * Advance to the next sample. Returns false if no more sample data
  * is available (end of stream).
  */
-bool AMediaExtractor_advance(AMediaExtractor*);
+bool AMediaExtractor_advance(AMediaExtractor*) __INTRODUCED_IN(21);
 
 typedef enum {
     AMEDIAEXTRACTOR_SEEK_PREVIOUS_SYNC,
@@ -135,7 +145,8 @@
 /**
  *
  */
-media_status_t AMediaExtractor_seekTo(AMediaExtractor*, int64_t seekPosUs, SeekMode mode);
+media_status_t AMediaExtractor_seekTo(AMediaExtractor*,
+        int64_t seekPosUs, SeekMode mode) __INTRODUCED_IN(21);
 
 /**
  * mapping of crypto scheme uuid to the scheme specific data for that scheme
@@ -157,10 +168,10 @@
 /**
  * Get the PSSH info if present.
  */
-PsshInfo* AMediaExtractor_getPsshInfo(AMediaExtractor*);
+PsshInfo* AMediaExtractor_getPsshInfo(AMediaExtractor*) __INTRODUCED_IN(21);
 
 
-AMediaCodecCryptoInfo *AMediaExtractor_getSampleCryptoInfo(AMediaExtractor *);
+AMediaCodecCryptoInfo *AMediaExtractor_getSampleCryptoInfo(AMediaExtractor *) __INTRODUCED_IN(21);
 
 enum {
     AMEDIAEXTRACTOR_SAMPLE_FLAG_SYNC = 1,
@@ -176,7 +187,7 @@
  * This function will always return a format; however, the format could be empty
  * (no key-value pairs) if the media container does not provide format information.
  */
-AMediaFormat* AMediaExtractor_getFileFormat(AMediaExtractor*);
+AMediaFormat* AMediaExtractor_getFileFormat(AMediaExtractor*) __INTRODUCED_IN(28);
 
 /**
  * Returns the size of the current sample in bytes, or -1 when no samples are
@@ -188,7 +199,7 @@
  * AMediaExtractor_readSampleData(ex, buf, sampleSize);
  *
  */
-ssize_t AMediaExtractor_getSampleSize(AMediaExtractor*);
+ssize_t AMediaExtractor_getSampleSize(AMediaExtractor*) __INTRODUCED_IN(28);
 
 /**
  * Returns the duration of cached media samples downloaded from a network data source
@@ -201,7 +212,7 @@
  * cached duration cannot be calculated (bitrate, duration, and file size information
  * not available).
  */
-int64_t AMediaExtractor_getCachedDuration(AMediaExtractor *);
+int64_t AMediaExtractor_getCachedDuration(AMediaExtractor *) __INTRODUCED_IN(28);
 
 /**
  * Read the current sample's metadata format into |fmt|. Examples of sample metadata are
@@ -212,7 +223,8 @@
  * Existing key-value pairs in |fmt| would be removed if this API returns AMEDIA_OK.
  * The contents of |fmt| is undefined if this API returns AMEDIA_ERROR_*.
  */
-media_status_t AMediaExtractor_getSampleFormat(AMediaExtractor *ex, AMediaFormat *fmt);
+media_status_t AMediaExtractor_getSampleFormat(AMediaExtractor *ex,
+        AMediaFormat *fmt) __INTRODUCED_IN(28);
 
 #endif /* __ANDROID_API__ >= 28 */
 
@@ -221,3 +233,5 @@
 __END_DECLS
 
 #endif // _NDK_MEDIA_EXTRACTOR_H
+
+/** @} */
diff --git a/media/ndk/include/media/NdkMediaFormat.h b/media/ndk/include/media/NdkMediaFormat.h
index 687054e..fd43f36 100644
--- a/media/ndk/include/media/NdkMediaFormat.h
+++ b/media/ndk/include/media/NdkMediaFormat.h
@@ -14,6 +14,15 @@
  * limitations under the License.
  */
 
+/**
+ * @addtogroup Media
+ * @{
+ */
+
+/**
+ * @file NdkMediaFormat.h
+ */
+
 /*
  * This file defines an NDK API.
  * Do not remove methods.
@@ -39,128 +48,197 @@
 
 #if __ANDROID_API__ >= 21
 
-AMediaFormat *AMediaFormat_new();
-media_status_t AMediaFormat_delete(AMediaFormat*);
+AMediaFormat *AMediaFormat_new() __INTRODUCED_IN(21);
+media_status_t AMediaFormat_delete(AMediaFormat*) __INTRODUCED_IN(21);
 
 /**
  * Human readable representation of the format. The returned string is owned by the format,
  * and remains valid until the next call to toString, or until the format is deleted.
  */
-const char* AMediaFormat_toString(AMediaFormat*);
+const char* AMediaFormat_toString(AMediaFormat*) __INTRODUCED_IN(21);
 
-bool AMediaFormat_getInt32(AMediaFormat*, const char *name, int32_t *out);
-bool AMediaFormat_getInt64(AMediaFormat*, const char *name, int64_t *out);
-bool AMediaFormat_getFloat(AMediaFormat*, const char *name, float *out);
-bool AMediaFormat_getSize(AMediaFormat*, const char *name, size_t *out);
+bool AMediaFormat_getInt32(AMediaFormat*, const char *name, int32_t *out) __INTRODUCED_IN(21);
+bool AMediaFormat_getInt64(AMediaFormat*, const char *name, int64_t *out) __INTRODUCED_IN(21);
+bool AMediaFormat_getFloat(AMediaFormat*, const char *name, float *out) __INTRODUCED_IN(21);
+bool AMediaFormat_getSize(AMediaFormat*, const char *name, size_t *out) __INTRODUCED_IN(21);
 /**
  * The returned data is owned by the format and remains valid as long as the named entry
  * is part of the format.
  */
-bool AMediaFormat_getBuffer(AMediaFormat*, const char *name, void** data, size_t *size);
+bool AMediaFormat_getBuffer(AMediaFormat*, const char *name, void** data, size_t *size) __INTRODUCED_IN(21);
 /**
  * The returned string is owned by the format, and remains valid until the next call to getString,
  * or until the format is deleted.
  */
-bool AMediaFormat_getString(AMediaFormat*, const char *name, const char **out);
+bool AMediaFormat_getString(AMediaFormat*, const char *name, const char **out) __INTRODUCED_IN(21);
 
 
-void AMediaFormat_setInt32(AMediaFormat*, const char* name, int32_t value);
-void AMediaFormat_setInt64(AMediaFormat*, const char* name, int64_t value);
-void AMediaFormat_setFloat(AMediaFormat*, const char* name, float value);
+void AMediaFormat_setInt32(AMediaFormat*, const char* name, int32_t value) __INTRODUCED_IN(21);
+void AMediaFormat_setInt64(AMediaFormat*, const char* name, int64_t value) __INTRODUCED_IN(21);
+void AMediaFormat_setFloat(AMediaFormat*, const char* name, float value) __INTRODUCED_IN(21);
 /**
  * The provided string is copied into the format.
  */
-void AMediaFormat_setString(AMediaFormat*, const char* name, const char* value);
+void AMediaFormat_setString(AMediaFormat*, const char* name, const char* value) __INTRODUCED_IN(21);
 /**
  * The provided data is copied into the format.
  */
-void AMediaFormat_setBuffer(AMediaFormat*, const char* name, void* data, size_t size);
+void AMediaFormat_setBuffer(AMediaFormat*, const char* name, const void* data, size_t size) __INTRODUCED_IN(21);
 
 
-
-/**
- * XXX should these be ints/enums that we look up in a table as needed?
- */
-extern const char* AMEDIAFORMAT_KEY_AAC_DRC_ATTENUATION_FACTOR;
-extern const char* AMEDIAFORMAT_KEY_AAC_DRC_BOOST_FACTOR;
-extern const char* AMEDIAFORMAT_KEY_AAC_DRC_HEAVY_COMPRESSION;
-extern const char* AMEDIAFORMAT_KEY_AAC_DRC_TARGET_REFERENCE_LEVEL;
-extern const char* AMEDIAFORMAT_KEY_AAC_ENCODED_TARGET_LEVEL;
-extern const char* AMEDIAFORMAT_KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT;
-extern const char* AMEDIAFORMAT_KEY_AAC_PROFILE;
-extern const char* AMEDIAFORMAT_KEY_AAC_SBR_MODE;
-extern const char* AMEDIAFORMAT_KEY_AUDIO_SESSION_ID;
-extern const char* AMEDIAFORMAT_KEY_BITRATE_MODE;
-extern const char* AMEDIAFORMAT_KEY_BIT_RATE;
-extern const char* AMEDIAFORMAT_KEY_CAPTURE_RATE;
-extern const char* AMEDIAFORMAT_KEY_CHANNEL_COUNT;
-extern const char* AMEDIAFORMAT_KEY_CHANNEL_MASK;
-extern const char* AMEDIAFORMAT_KEY_COLOR_FORMAT;
-extern const char* AMEDIAFORMAT_KEY_COLOR_RANGE;
-extern const char* AMEDIAFORMAT_KEY_COLOR_STANDARD;
-extern const char* AMEDIAFORMAT_KEY_COLOR_TRANSFER;
-extern const char* AMEDIAFORMAT_KEY_COMPLEXITY;
-extern const char* AMEDIAFORMAT_KEY_CSD;
-extern const char* AMEDIAFORMAT_KEY_CSD_0;
-extern const char* AMEDIAFORMAT_KEY_CSD_1;
-extern const char* AMEDIAFORMAT_KEY_CSD_2;
-extern const char* AMEDIAFORMAT_KEY_DISPLAY_CROP;
-extern const char* AMEDIAFORMAT_KEY_DISPLAY_HEIGHT;
-extern const char* AMEDIAFORMAT_KEY_DISPLAY_WIDTH;
-extern const char* AMEDIAFORMAT_KEY_DURATION;
-extern const char* AMEDIAFORMAT_KEY_FLAC_COMPRESSION_LEVEL;
-extern const char* AMEDIAFORMAT_KEY_FRAME_RATE;
-extern const char* AMEDIAFORMAT_KEY_GRID_COLUMNS;
-extern const char* AMEDIAFORMAT_KEY_GRID_ROWS;
-extern const char* AMEDIAFORMAT_KEY_HDR_STATIC_INFO;
-extern const char* AMEDIAFORMAT_KEY_HEIGHT;
-extern const char* AMEDIAFORMAT_KEY_INTRA_REFRESH_PERIOD;
-extern const char* AMEDIAFORMAT_KEY_IS_ADTS;
-extern const char* AMEDIAFORMAT_KEY_IS_AUTOSELECT;
-extern const char* AMEDIAFORMAT_KEY_IS_DEFAULT;
-extern const char* AMEDIAFORMAT_KEY_IS_FORCED_SUBTITLE;
-extern const char* AMEDIAFORMAT_KEY_I_FRAME_INTERVAL;
-extern const char* AMEDIAFORMAT_KEY_LANGUAGE;
-extern const char* AMEDIAFORMAT_KEY_LATENCY;
-extern const char* AMEDIAFORMAT_KEY_LEVEL;
-extern const char* AMEDIAFORMAT_KEY_MAX_HEIGHT;
-extern const char* AMEDIAFORMAT_KEY_MAX_INPUT_SIZE;
-extern const char* AMEDIAFORMAT_KEY_MAX_WIDTH;
-extern const char* AMEDIAFORMAT_KEY_MIME;
-extern const char* AMEDIAFORMAT_KEY_MPEG_USER_DATA;
-extern const char* AMEDIAFORMAT_KEY_OPERATING_RATE;
-extern const char* AMEDIAFORMAT_KEY_PCM_ENCODING;
-extern const char* AMEDIAFORMAT_KEY_PRIORITY;
-extern const char* AMEDIAFORMAT_KEY_PROFILE;
-extern const char* AMEDIAFORMAT_KEY_PUSH_BLANK_BUFFERS_ON_STOP;
-extern const char* AMEDIAFORMAT_KEY_REPEAT_PREVIOUS_FRAME_AFTER;
-extern const char* AMEDIAFORMAT_KEY_ROTATION;
-extern const char* AMEDIAFORMAT_KEY_SAMPLE_RATE;
-extern const char* AMEDIAFORMAT_KEY_SEI;
-extern const char* AMEDIAFORMAT_KEY_SLICE_HEIGHT;
-extern const char* AMEDIAFORMAT_KEY_STRIDE;
-extern const char* AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID;
-extern const char* AMEDIAFORMAT_KEY_TEMPORAL_LAYERING;
-extern const char* AMEDIAFORMAT_KEY_TILE_HEIGHT;
-extern const char* AMEDIAFORMAT_KEY_TILE_WIDTH;
-extern const char* AMEDIAFORMAT_KEY_TIME_US;
-extern const char* AMEDIAFORMAT_KEY_TRACK_ID;
-extern const char* AMEDIAFORMAT_KEY_TRACK_INDEX;
-extern const char* AMEDIAFORMAT_KEY_WIDTH;
-
+extern const char* AMEDIAFORMAT_KEY_AAC_DRC_ATTENUATION_FACTOR __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_AAC_DRC_BOOST_FACTOR __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_AAC_DRC_HEAVY_COMPRESSION __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_AAC_DRC_TARGET_REFERENCE_LEVEL __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_AAC_ENCODED_TARGET_LEVEL __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_AAC_PROFILE __INTRODUCED_IN(21);
+extern const char* AMEDIAFORMAT_KEY_AAC_SBR_MODE __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_AUDIO_SESSION_ID __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_BITRATE_MODE __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_BIT_RATE __INTRODUCED_IN(21);
+extern const char* AMEDIAFORMAT_KEY_CAPTURE_RATE __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_CHANNEL_COUNT __INTRODUCED_IN(21);
+extern const char* AMEDIAFORMAT_KEY_CHANNEL_MASK __INTRODUCED_IN(21);
+extern const char* AMEDIAFORMAT_KEY_COLOR_FORMAT __INTRODUCED_IN(21);
+extern const char* AMEDIAFORMAT_KEY_COLOR_RANGE __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_COLOR_STANDARD __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_COLOR_TRANSFER __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_COMPLEXITY __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_CSD __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_CSD_0 __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_CSD_1 __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_CSD_2 __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_DISPLAY_CROP __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_DISPLAY_HEIGHT __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_DISPLAY_WIDTH __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_DURATION __INTRODUCED_IN(21);
+extern const char* AMEDIAFORMAT_KEY_FLAC_COMPRESSION_LEVEL __INTRODUCED_IN(21);
+extern const char* AMEDIAFORMAT_KEY_FRAME_RATE __INTRODUCED_IN(21);
+extern const char* AMEDIAFORMAT_KEY_GRID_COLUMNS __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_GRID_ROWS __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_HDR_STATIC_INFO __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_HEIGHT __INTRODUCED_IN(21);
+extern const char* AMEDIAFORMAT_KEY_INTRA_REFRESH_PERIOD __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_IS_ADTS __INTRODUCED_IN(21);
+extern const char* AMEDIAFORMAT_KEY_IS_AUTOSELECT __INTRODUCED_IN(21);
+extern const char* AMEDIAFORMAT_KEY_IS_DEFAULT __INTRODUCED_IN(21);
+extern const char* AMEDIAFORMAT_KEY_IS_FORCED_SUBTITLE __INTRODUCED_IN(21);
+extern const char* AMEDIAFORMAT_KEY_I_FRAME_INTERVAL __INTRODUCED_IN(21);
+extern const char* AMEDIAFORMAT_KEY_LANGUAGE __INTRODUCED_IN(21);
+extern const char* AMEDIAFORMAT_KEY_LATENCY __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_LEVEL __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_MAX_HEIGHT __INTRODUCED_IN(21);
+extern const char* AMEDIAFORMAT_KEY_MAX_INPUT_SIZE __INTRODUCED_IN(21);
+extern const char* AMEDIAFORMAT_KEY_MAX_WIDTH __INTRODUCED_IN(21);
+extern const char* AMEDIAFORMAT_KEY_MIME __INTRODUCED_IN(21);
+extern const char* AMEDIAFORMAT_KEY_MPEG_USER_DATA __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_OPERATING_RATE __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_PCM_ENCODING __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_PRIORITY __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_PROFILE __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_PUSH_BLANK_BUFFERS_ON_STOP __INTRODUCED_IN(21);
+extern const char* AMEDIAFORMAT_KEY_REPEAT_PREVIOUS_FRAME_AFTER __INTRODUCED_IN(21);
+extern const char* AMEDIAFORMAT_KEY_ROTATION __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_SAMPLE_RATE __INTRODUCED_IN(21);
+extern const char* AMEDIAFORMAT_KEY_SEI __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_SLICE_HEIGHT __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_STRIDE __INTRODUCED_IN(21);
+extern const char* AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_TEMPORAL_LAYERING __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_TILE_HEIGHT __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_TILE_WIDTH __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_TIME_US __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_TRACK_ID __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_TRACK_INDEX __INTRODUCED_IN(28);
+extern const char* AMEDIAFORMAT_KEY_WIDTH __INTRODUCED_IN(21);
 #endif /* __ANDROID_API__ >= 21 */
 
 #if __ANDROID_API__ >= 28
-bool AMediaFormat_getDouble(AMediaFormat*, const char *name, double *out);
+bool AMediaFormat_getDouble(AMediaFormat*, const char *name, double *out) __INTRODUCED_IN(28);
 bool AMediaFormat_getRect(AMediaFormat*, const char *name,
-                          int32_t *left, int32_t *top, int32_t *right, int32_t *bottom);
+        int32_t *left, int32_t *top, int32_t *right, int32_t *bottom) __INTRODUCED_IN(28);
 
-void AMediaFormat_setDouble(AMediaFormat*, const char* name, double value);
-void AMediaFormat_setSize(AMediaFormat*, const char* name, size_t value);
+void AMediaFormat_setDouble(AMediaFormat*, const char* name, double value) __INTRODUCED_IN(28);
+void AMediaFormat_setSize(AMediaFormat*, const char* name, size_t value) __INTRODUCED_IN(28);
 void AMediaFormat_setRect(AMediaFormat*, const char* name,
-                          int32_t left, int32_t top, int32_t right, int32_t bottom);
+        int32_t left, int32_t top, int32_t right, int32_t bottom) __INTRODUCED_IN(28);
 #endif /* __ANDROID_API__ >= 28 */
 
+#if __ANDROID_API__ >= 29
+/**
+ * remove all key/value pairs from the given AMediaFormat
+ */
+void AMediaFormat_clear(AMediaFormat*) __INTRODUCED_IN(29);
+
+/**
+ * copy one AMediaFormat to another
+ */
+media_status_t AMediaFormat_copy(AMediaFormat *to, AMediaFormat *from) __INTRODUCED_IN(29);
+
+extern const char* AMEDIAFORMAT_KEY_ALBUM __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_ALBUMART __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_ALBUMARTIST __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_ARTIST __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_PRESENTATION_ID __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_PROGRAM_ID __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_AUTHOR __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_BITS_PER_SAMPLE __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_CDTRACKNUMBER __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_COMPILATION __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_COMPOSER __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_CREATE_INPUT_SURFACE_SUSPENDED __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_CRYPTO_IV __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_CRYPTO_KEY __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_CRYPTO_MODE __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_CRYPTO_SKIP_BYTE_BLOCK __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_CSD_AVC __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_CSD_HEVC __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_D263 __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_DATE __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_DISCNUMBER __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_ENCODER_DELAY __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_ENCODER_PADDING __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_ESDS __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_EXIF_OFFSET __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_EXIF_SIZE __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_FRAME_COUNT __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_GENRE __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_HAPTIC_CHANNEL_COUNT __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_ICC_PROFILE __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_IS_SYNC_FRAME __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_LOCATION __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_LOOP __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_LYRICIST __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_MANUFACTURER __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_MAX_BIT_RATE __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_MAX_FPS_TO_ENCODER __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_MAX_PTS_GAP_TO_ENCODER __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_MPEG2_STREAM_HEADER __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_PCM_BIG_ENDIAN __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_PSSH __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_SAR_HEIGHT __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_SAR_WIDTH __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_TARGET_TIME __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_TEMPORAL_LAYER_COUNT __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_TEXT_FORMAT_DATA __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_THUMBNAIL_CSD_HEVC __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_THUMBNAIL_HEIGHT __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_THUMBNAIL_TIME __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_THUMBNAIL_WIDTH __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_TITLE __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_VALID_SAMPLES __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_YEAR __INTRODUCED_IN(29);
+
+#endif /* __ANDROID_API__ >= 29 */
+
 __END_DECLS
 
 #endif // _NDK_MEDIA_FORMAT_H
+
+/** @} */
diff --git a/media/ndk/include/media/NdkMediaMuxer.h b/media/ndk/include/media/NdkMediaMuxer.h
index 1ecd1ca..7393867 100644
--- a/media/ndk/include/media/NdkMediaMuxer.h
+++ b/media/ndk/include/media/NdkMediaMuxer.h
@@ -14,6 +14,14 @@
  * limitations under the License.
  */
 
+/**
+ * @addtogroup Media
+ * @{
+ */
+
+/**
+ * @file NdkMediaMuxer.h
+ */
 
 /*
  * This file defines an NDK API.
@@ -50,12 +58,12 @@
 /**
  * Create new media muxer
  */
-AMediaMuxer* AMediaMuxer_new(int fd, OutputFormat format);
+AMediaMuxer* AMediaMuxer_new(int fd, OutputFormat format) __INTRODUCED_IN(21);
 
 /**
  * Delete a previously created media muxer
  */
-media_status_t AMediaMuxer_delete(AMediaMuxer*);
+media_status_t AMediaMuxer_delete(AMediaMuxer*) __INTRODUCED_IN(21);
 
 /**
  * Set and store the geodata (latitude and longitude) in the output file.
@@ -68,7 +76,8 @@
  * Latitude must be in the range [-90, 90].
  * Longitude must be in the range [-180, 180].
  */
-media_status_t AMediaMuxer_setLocation(AMediaMuxer*, float latitude, float longitude);
+media_status_t AMediaMuxer_setLocation(AMediaMuxer*,
+        float latitude, float longitude) __INTRODUCED_IN(21);
 
 /**
  * Sets the orientation hint for output video playback.
@@ -82,26 +91,26 @@
  * The angle is specified in degrees, clockwise.
  * The supported angles are 0, 90, 180, and 270 degrees.
  */
-media_status_t AMediaMuxer_setOrientationHint(AMediaMuxer*, int degrees);
+media_status_t AMediaMuxer_setOrientationHint(AMediaMuxer*, int degrees) __INTRODUCED_IN(21);
 
 /**
  * Adds a track with the specified format.
  * Returns the index of the new track or a negative value in case of failure,
  * which can be interpreted as a media_status_t.
  */
-ssize_t AMediaMuxer_addTrack(AMediaMuxer*, const AMediaFormat* format);
+ssize_t AMediaMuxer_addTrack(AMediaMuxer*, const AMediaFormat* format) __INTRODUCED_IN(21);
 
 /**
  * Start the muxer. Should be called after AMediaMuxer_addTrack and
  * before AMediaMuxer_writeSampleData.
  */
-media_status_t AMediaMuxer_start(AMediaMuxer*);
+media_status_t AMediaMuxer_start(AMediaMuxer*) __INTRODUCED_IN(21);
 
 /**
  * Stops the muxer.
  * Once the muxer stops, it can not be restarted.
  */
-media_status_t AMediaMuxer_stop(AMediaMuxer*);
+media_status_t AMediaMuxer_stop(AMediaMuxer*) __INTRODUCED_IN(21);
 
 /**
  * Writes an encoded sample into the muxer.
@@ -111,10 +120,13 @@
  * by the encoder.)
  */
 media_status_t AMediaMuxer_writeSampleData(AMediaMuxer *muxer,
-        size_t trackIdx, const uint8_t *data, const AMediaCodecBufferInfo *info);
+        size_t trackIdx, const uint8_t *data,
+        const AMediaCodecBufferInfo *info) __INTRODUCED_IN(21);
 
 #endif /* __ANDROID_API__ >= 21 */
 
 __END_DECLS
 
 #endif // _NDK_MEDIA_MUXER_H
+
+/** @} */
diff --git a/media/ndk/include/private/media/NdkImage.h b/media/ndk/include/private/media/NdkImage.h
new file mode 100644
index 0000000..4368a56
--- /dev/null
+++ b/media/ndk/include/private/media/NdkImage.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _PRIVATE_MEDIA_NDKIMAGE_H_
+#define _PRIVATE_MEDIA_NDKIMAGE_H_
+// Formats not listed in the public API, but still available to AImageReader
+enum AIMAGE_PRIVATE_FORMATS {
+    /**
+     * Unprocessed implementation-dependent raw
+     * depth measurements, opaque with 16 bit
+     * samples.
+     *
+     */
+
+    AIMAGE_FORMAT_RAW_DEPTH = 0x1002,
+};
+#endif // _PRIVATE_MEDIA_NDKIMAGE
diff --git a/media/ndk/libmediandk.map.txt b/media/ndk/libmediandk.map.txt
index fb56694..f666ad0 100644
--- a/media/ndk/libmediandk.map.txt
+++ b/media/ndk/libmediandk.map.txt
@@ -4,6 +4,7 @@
     AImageReader_acquireLatestImageAsync; # introduced=26
     AImageReader_acquireNextImage; # introduced=24
     AImageReader_acquireNextImageAsync; # introduced=26
+    AImageReader_getWindowNativeHandle; #vndk
     AImageReader_delete; # introduced=24
     AImageReader_getFormat; # introduced=24
     AImageReader_getHeight; # introduced=24
@@ -32,55 +33,122 @@
     AMEDIAFORMAT_KEY_AAC_DRC_TARGET_REFERENCE_LEVEL; # var introduced=28
     AMEDIAFORMAT_KEY_AAC_ENCODED_TARGET_LEVEL; # var introduced=28
     AMEDIAFORMAT_KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT; # var introduced=28
-    AMEDIAFORMAT_KEY_AAC_PROFILE; # var
+    AMEDIAFORMAT_KEY_AAC_PROFILE; # var introduced=21
     AMEDIAFORMAT_KEY_AAC_SBR_MODE; # var introduced=28
+    AMEDIAFORMAT_KEY_ALBUM; # var introduced=29
+    AMEDIAFORMAT_KEY_ALBUMART; # var introduced=29
+    AMEDIAFORMAT_KEY_ALBUMARTIST; # var introduced=29
+    AMEDIAFORMAT_KEY_ARTIST; # var introduced=29
+    AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO; # var introduced=29
     AMEDIAFORMAT_KEY_AUDIO_SESSION_ID; # var introduced=28
+    AMEDIAFORMAT_KEY_AUTHOR; # var introduced=29
     AMEDIAFORMAT_KEY_BITRATE_MODE; # var introduced=28
-    AMEDIAFORMAT_KEY_BIT_RATE; # var
+    AMEDIAFORMAT_KEY_BIT_RATE; # var introduced=21
+    AMEDIAFORMAT_KEY_BITS_PER_SAMPLE; # var introduced=29
     AMEDIAFORMAT_KEY_CAPTURE_RATE; # var introduced=28
-    AMEDIAFORMAT_KEY_CHANNEL_COUNT; # var
-    AMEDIAFORMAT_KEY_CHANNEL_MASK; # var
-    AMEDIAFORMAT_KEY_COLOR_FORMAT; # var
+    AMEDIAFORMAT_KEY_CDTRACKNUMBER; # var introduced=29
+    AMEDIAFORMAT_KEY_CHANNEL_COUNT; # var introduced=21
+    AMEDIAFORMAT_KEY_CHANNEL_MASK; # var introduced=21
+    AMEDIAFORMAT_KEY_COLOR_FORMAT; # var introduced=21
     AMEDIAFORMAT_KEY_COLOR_RANGE; # var introduced=28
     AMEDIAFORMAT_KEY_COLOR_STANDARD; # var introduced=28
     AMEDIAFORMAT_KEY_COLOR_TRANSFER; # var introduced=28
+    AMEDIAFORMAT_KEY_COMPILATION; # var introduced=29
     AMEDIAFORMAT_KEY_COMPLEXITY; # var introduced=28
+    AMEDIAFORMAT_KEY_COMPOSER; # var introduced=29
+    AMEDIAFORMAT_KEY_CREATE_INPUT_SURFACE_SUSPENDED; # var introduced=29
+    AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE; # var introduced=29
+    AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK; # var introduced=29
+    AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES; # var introduced=29
+    AMEDIAFORMAT_KEY_CRYPTO_IV; # var introduced=29
+    AMEDIAFORMAT_KEY_CRYPTO_KEY; # var introduced=29
+    AMEDIAFORMAT_KEY_CRYPTO_MODE; # var introduced=29
+    AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES; # var introduced=29
+    AMEDIAFORMAT_KEY_CRYPTO_SKIP_BYTE_BLOCK; # var introduced=29
+    AMEDIAFORMAT_KEY_CSD; # var introduced=28
+    AMEDIAFORMAT_KEY_CSD_0; # var introduced=28
+    AMEDIAFORMAT_KEY_CSD_1; # var introduced=28
+    AMEDIAFORMAT_KEY_CSD_2; # var introduced=28
+    AMEDIAFORMAT_KEY_CSD_AVC; # var introduced=29
+    AMEDIAFORMAT_KEY_CSD_HEVC; # var introduced=29
+    AMEDIAFORMAT_KEY_D263; # var introduced=29
+    AMEDIAFORMAT_KEY_DATE; # var introduced=29
+    AMEDIAFORMAT_KEY_DISCNUMBER; # var introduced=29
     AMEDIAFORMAT_KEY_DISPLAY_CROP; # var introduced=28
-    AMEDIAFORMAT_KEY_DURATION; # var
-    AMEDIAFORMAT_KEY_FLAC_COMPRESSION_LEVEL; # var
-    AMEDIAFORMAT_KEY_FRAME_RATE; # var
+    AMEDIAFORMAT_KEY_DISPLAY_HEIGHT; # var introduced=28
+    AMEDIAFORMAT_KEY_DISPLAY_WIDTH; # var introduced=28
+    AMEDIAFORMAT_KEY_DURATION; # var introduced=21
+    AMEDIAFORMAT_KEY_ENCODER_DELAY; # var introduced=29
+    AMEDIAFORMAT_KEY_ENCODER_PADDING; # var introduced=29
+    AMEDIAFORMAT_KEY_ESDS; # var introduced=29
+    AMEDIAFORMAT_KEY_EXIF_OFFSET; # var introduced=29
+    AMEDIAFORMAT_KEY_EXIF_SIZE; # var introduced=29
+    AMEDIAFORMAT_KEY_FRAME_COUNT; # var introduced=29
+    AMEDIAFORMAT_KEY_FLAC_COMPRESSION_LEVEL; # var introduced=21
+    AMEDIAFORMAT_KEY_FRAME_RATE; # var introduced=21
+    AMEDIAFORMAT_KEY_GENRE; # var introduced=29
     AMEDIAFORMAT_KEY_GRID_COLUMNS; # var introduced=28
     AMEDIAFORMAT_KEY_GRID_ROWS; # var introduced=28
+    AMEDIAFORMAT_KEY_HAPTIC_CHANNEL_COUNT; # var introduced=29
     AMEDIAFORMAT_KEY_HDR_STATIC_INFO; # var introduced=28
-    AMEDIAFORMAT_KEY_HEIGHT; # var
+    AMEDIAFORMAT_KEY_HEIGHT; # var introduced=21
+    AMEDIAFORMAT_KEY_ICC_PROFILE; # var introduced=29
     AMEDIAFORMAT_KEY_INTRA_REFRESH_PERIOD; # var introduced=28
-    AMEDIAFORMAT_KEY_IS_ADTS; # var
-    AMEDIAFORMAT_KEY_IS_AUTOSELECT; # var
-    AMEDIAFORMAT_KEY_IS_DEFAULT; # var
-    AMEDIAFORMAT_KEY_IS_FORCED_SUBTITLE; # var
-    AMEDIAFORMAT_KEY_I_FRAME_INTERVAL; # var
-    AMEDIAFORMAT_KEY_LANGUAGE; # var
+    AMEDIAFORMAT_KEY_IS_ADTS; # var introduced=21
+    AMEDIAFORMAT_KEY_IS_AUTOSELECT; # var introduced=21
+    AMEDIAFORMAT_KEY_IS_DEFAULT; # var introduced=21
+    AMEDIAFORMAT_KEY_IS_FORCED_SUBTITLE; # var introduced=21
+    AMEDIAFORMAT_KEY_IS_SYNC_FRAME; # var introduced=29
+    AMEDIAFORMAT_KEY_I_FRAME_INTERVAL; # var introduced=21
+    AMEDIAFORMAT_KEY_LANGUAGE; # var introduced=21
     AMEDIAFORMAT_KEY_LATENCY; # var introduced=28
     AMEDIAFORMAT_KEY_LEVEL; # var introduced=28
-    AMEDIAFORMAT_KEY_MAX_HEIGHT; # var
-    AMEDIAFORMAT_KEY_MAX_INPUT_SIZE; # var
-    AMEDIAFORMAT_KEY_MAX_WIDTH; # var
-    AMEDIAFORMAT_KEY_MIME; # var
+    AMEDIAFORMAT_KEY_LOCATION; # var introduced=29
+    AMEDIAFORMAT_KEY_LOOP; # var introduced=29
+    AMEDIAFORMAT_KEY_LYRICIST; # var introduced=29
+    AMEDIAFORMAT_KEY_MANUFACTURER; # var introduced=29
+    AMEDIAFORMAT_KEY_MAX_BIT_RATE; # var introduced=29
+    AMEDIAFORMAT_KEY_MAX_FPS_TO_ENCODER; # var introduced=29
+    AMEDIAFORMAT_KEY_MAX_HEIGHT; # var introduced=21
+    AMEDIAFORMAT_KEY_MAX_INPUT_SIZE; # var introduced=21
+    AMEDIAFORMAT_KEY_MAX_PTS_GAP_TO_ENCODER; # var introduced=29
+    AMEDIAFORMAT_KEY_MAX_WIDTH; # var introduced=21
+    AMEDIAFORMAT_KEY_MIME; # var introduced=21
+    AMEDIAFORMAT_KEY_MPEG_USER_DATA; # var introduced=28
+    AMEDIAFORMAT_KEY_MPEG2_STREAM_HEADER; # var introduced=29
     AMEDIAFORMAT_KEY_OPERATING_RATE; # var introduced=28
+    AMEDIAFORMAT_KEY_PCM_BIG_ENDIAN; # var introduced=29
     AMEDIAFORMAT_KEY_PCM_ENCODING; # var introduced=28
     AMEDIAFORMAT_KEY_PRIORITY; # var introduced=28
     AMEDIAFORMAT_KEY_PROFILE; # var introduced=28
-    AMEDIAFORMAT_KEY_PUSH_BLANK_BUFFERS_ON_STOP; # var
-    AMEDIAFORMAT_KEY_REPEAT_PREVIOUS_FRAME_AFTER; # var
+    AMEDIAFORMAT_KEY_PSSH; # var introduced=29
+    AMEDIAFORMAT_KEY_PUSH_BLANK_BUFFERS_ON_STOP; # var introduced=21
+    AMEDIAFORMAT_KEY_REPEAT_PREVIOUS_FRAME_AFTER; # var introduced=21
     AMEDIAFORMAT_KEY_ROTATION; # var introduced=28
-    AMEDIAFORMAT_KEY_SAMPLE_RATE; # var
+    AMEDIAFORMAT_KEY_SAMPLE_RATE; # var introduced=21
+    AMEDIAFORMAT_KEY_SAR_HEIGHT; # var introduced=29
+    AMEDIAFORMAT_KEY_SAR_WIDTH; # var introduced=29
+    AMEDIAFORMAT_KEY_SEI; # var introduced=28
     AMEDIAFORMAT_KEY_SLICE_HEIGHT; # var introduced=28
-    AMEDIAFORMAT_KEY_STRIDE; # var
+    AMEDIAFORMAT_KEY_STRIDE; # var introduced=21
+    AMEDIAFORMAT_KEY_TARGET_TIME; # var introduced=29
+    AMEDIAFORMAT_KEY_TEMPORAL_LAYER_COUNT; # var introduced=29
+    AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID; # var introduced=28
     AMEDIAFORMAT_KEY_TEMPORAL_LAYERING; # var introduced=28
+    AMEDIAFORMAT_KEY_TEXT_FORMAT_DATA; # var introduced=29
+    AMEDIAFORMAT_KEY_THUMBNAIL_CSD_HEVC; # var introduced=29
+    AMEDIAFORMAT_KEY_THUMBNAIL_HEIGHT; # var introduced=29
+    AMEDIAFORMAT_KEY_THUMBNAIL_TIME; # var introduced=29
+    AMEDIAFORMAT_KEY_THUMBNAIL_WIDTH; # var introduced=29
+    AMEDIAFORMAT_KEY_TITLE; # var introduced=28
     AMEDIAFORMAT_KEY_TILE_HEIGHT; # var introduced=28
     AMEDIAFORMAT_KEY_TILE_WIDTH; # var introduced=28
+    AMEDIAFORMAT_KEY_TIME_US; # var introduced=28
+    AMEDIAFORMAT_KEY_TRACK_INDEX; # var introduced=28
     AMEDIAFORMAT_KEY_TRACK_ID; # var introduced=28
-    AMEDIAFORMAT_KEY_WIDTH; # var
+    AMEDIAFORMAT_KEY_VALID_SAMPLES; # var introduced=29
+    AMEDIAFORMAT_KEY_WIDTH; # var introduced=21
+    AMEDIAFORMAT_KEY_YEAR; # var introduced=29
     AMediaCodecActionCode_isRecoverable; # introduced=28
     AMediaCodecActionCode_isTransient; # introduced=28
     AMediaCodecCryptoInfo_delete;
@@ -100,6 +168,7 @@
     AMediaCodec_dequeueInputBuffer;
     AMediaCodec_dequeueOutputBuffer;
     AMediaCodec_flush;
+    AMediaCodec_getBufferFormat; # introduced=28
     AMediaCodec_getInputBuffer;
     AMediaCodec_getInputFormat; # introduced=28
     AMediaCodec_getName; # introduced=28
@@ -130,6 +199,9 @@
     AMediaDataSource_setGetSize;  # introduced=28
     AMediaDataSource_setReadAt;   # introduced=28
     AMediaDataSource_setUserdata; # introduced=28
+    AMediaDataSource_newUri;      # introduced=29
+    AMediaDataSource_close;       # introduced=29
+    AMediaDataSource_setGetAvailableSize; # introduced=29
     AMediaDrm_closeSession;
     AMediaDrm_createByUUID;
     AMediaDrm_decrypt;
@@ -151,6 +223,8 @@
     AMediaDrm_setOnEventListener;
     AMediaDrm_setPropertyByteArray;
     AMediaDrm_setPropertyString;
+    AMediaDrm_setOnExpirationUpdateListener; # introduced=29
+    AMediaDrm_setOnKeysChangeListener; # introduced=29
     AMediaDrm_sign;
     AMediaDrm_verify;
     AMediaExtractor_advance;
@@ -174,6 +248,8 @@
     AMediaExtractor_setDataSourceCustom; # introduced=28
     AMediaExtractor_setDataSourceFd;
     AMediaExtractor_unselectTrack;
+    AMediaFormat_clear; # introduced=29
+    AMediaFormat_copy; # introduced=29
     AMediaFormat_delete;
     AMediaFormat_getBuffer;
     AMediaFormat_getDouble; # introduced=28
diff --git a/media/ndk/tests/AImageReaderWindowHandleTest.cpp b/media/ndk/tests/AImageReaderWindowHandleTest.cpp
new file mode 100644
index 0000000..5b65064
--- /dev/null
+++ b/media/ndk/tests/AImageReaderWindowHandleTest.cpp
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+#include <media/NdkImageReader.h>
+#include <media/NdkImage.h>
+#include <private/media/NdkImage.h>
+#include <mediautils/AImageReaderUtils.h>
+#include <gui/IGraphicBufferProducer.h>
+#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
+#include <NdkImageReaderPriv.h>
+#include <vndk/hardware_buffer.h>
+#include <memory>
+
+namespace android {
+
+using HGraphicBufferProducer = hardware::graphics::bufferqueue::V1_0::
+        IGraphicBufferProducer;
+using hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer;
+using aimg::AImageReader_getHGBPFromHandle;
+
+typedef IGraphicBufferProducer::QueueBufferInput QueueBufferInput;
+typedef IGraphicBufferProducer::QueueBufferOutput QueueBufferOutput;
+
+static constexpr uint64_t kImageBufferUsage =
+    AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
+static constexpr int kImageWidth = 640;
+static constexpr int kImageHeight = 480;
+static constexpr int kImageFormat = AIMAGE_FORMAT_RGBA_8888;
+static constexpr int kMaxImages = 1;
+
+static constexpr int64_t kQueueBufferInputTimeStamp = 1384888611;
+static constexpr bool kQueueBufferInputIsAutoTimeStamp = false;
+static constexpr android_dataspace kQueueBufferInputDataspace = HAL_DATASPACE_UNKNOWN;
+static const Rect kQueueBufferInputRect = Rect(kImageWidth, kImageHeight);
+static constexpr int kQueueBufferInputScalingMode = 0;
+static constexpr int kQueueBufferInputTransform = 0;
+static const sp<Fence> kQueueBufferInputFence = Fence::NO_FENCE;
+
+static constexpr int kOnImageAvailableWaitUs = 100 * 1000;
+
+class AImageReaderWindowHandleTest : public ::testing::Test {
+   public:
+    void SetUp() override {
+        AImageReader_newWithUsage(kImageWidth, kImageHeight, kImageFormat,
+                                  kImageBufferUsage , kMaxImages, &imageReader_);
+        media_status_t ret = AMEDIA_ERROR_UNKNOWN;
+        ASSERT_NE(imageReader_, nullptr);
+        ret = AImageReader_setImageListener(imageReader_,
+                                            &imageReaderAvailableCb_);
+        ASSERT_EQ(ret, AMEDIA_OK);
+        ret = AImageReader_setBufferRemovedListener(imageReader_,
+                                                    &imageReaderDetachedCb_);
+        ASSERT_EQ(ret, AMEDIA_OK);
+    }
+    void TearDown() override {
+        if (imageReader_) {
+            AImageReader_delete(imageReader_);
+        }
+    }
+
+    void HandleImageAvailable() {
+        AImage *outImage = nullptr;
+        media_status_t ret = AMEDIA_OK;
+        auto imageDeleter = [](AImage *img) { AImage_delete(img); };
+        std::unique_ptr<AImage, decltype(imageDeleter)> img(nullptr, imageDeleter);
+
+        // Test that the image can be acquired.
+        ret = AImageReader_acquireNextImage(imageReader_, &outImage);
+        ASSERT_EQ(ret, AMEDIA_OK);
+        img.reset(outImage);
+        ASSERT_NE(img, nullptr);
+
+        // Test that we can get a handle to the image's hardware buffer and a
+        // native handle to it.
+        AHardwareBuffer *hardwareBuffer = nullptr;
+        ret = AImage_getHardwareBuffer(img.get(), &hardwareBuffer);
+        ASSERT_EQ(ret, AMEDIA_OK);
+        ASSERT_NE(hardwareBuffer, nullptr);
+        const native_handle_t *nh = AHardwareBuffer_getNativeHandle(hardwareBuffer);
+        ASSERT_NE(nh, nullptr);
+        std::unique_lock<std::mutex> lock(imageAvailableMutex_);
+        imageAvailable_ = true;
+        imageCondVar_.notify_one();
+    }
+
+    static void onImageAvailable(void *context, AImageReader *reader) {
+        (void)reader;
+        AImageReaderWindowHandleTest *thisContext =
+            reinterpret_cast<AImageReaderWindowHandleTest *>(context);
+        thisContext->HandleImageAvailable();
+    }
+
+    static void onBufferRemoved(void *, AImageReader *, AHardwareBuffer *) {
+    }
+
+    AImageReader *imageReader_ = nullptr;
+    AImageReader_ImageListener imageReaderAvailableCb_{this, onImageAvailable};
+    AImageReader_BufferRemovedListener imageReaderDetachedCb_{this, onBufferRemoved};
+    std::mutex imageAvailableMutex_;
+    std::condition_variable imageCondVar_;
+    bool imageAvailable_ = false;
+};
+
+static void fillRGBA8Buffer(uint8_t* buf, int w, int h, int stride) {
+    const size_t PIXEL_SIZE = 4;
+    for (int x = 0; x < w; x++) {
+        for (int y = 0; y < h; y++) {
+            off_t offset = (y * stride + x) * PIXEL_SIZE;
+            for (int c = 0; c < 4; c++) {
+                int parityX = (x / (1 << (c+2))) & 1;
+                int parityY = (y / (1 << (c+2))) & 1;
+                buf[offset + c] = (parityX ^ parityY) ? 231 : 35;
+            }
+        }
+    }
+}
+
+TEST_F(AImageReaderWindowHandleTest, CreateWindowNativeHandle) {
+    // Check that we can create a native_handle_t corresponding to the
+    // AImageReader.
+    native_handle_t *nh = nullptr;
+    AImageReader_getWindowNativeHandle(imageReader_, &nh);
+    ASSERT_NE(nh, nullptr);
+
+    // Check that there are only ints in the handle.
+    ASSERT_EQ(nh->numFds, 0);
+    ASSERT_NE(nh->numInts, 0);
+
+    // Check that the HGBP can be retrieved from the handle.
+    sp<HGraphicBufferProducer> hgbp =  AImageReader_getHGBPFromHandle(nh);
+    ASSERT_NE(hgbp, nullptr);
+    sp<IGraphicBufferProducer> igbp = new H2BGraphicBufferProducer(hgbp);
+    int dequeuedSlot = -1;
+    sp<Fence> dequeuedFence;
+    IGraphicBufferProducer::QueueBufferOutput output;
+    ASSERT_EQ(OK, igbp->connect(nullptr, NATIVE_WINDOW_API_CPU, false, &output));
+
+    // Test that we can dequeue a buffer.
+    ASSERT_EQ(OK,
+              ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
+                      (igbp->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
+                                           kImageWidth, kImageHeight,
+                                           kImageFormat, kImageBufferUsage,
+                                           nullptr, nullptr)));
+    EXPECT_LE(0, dequeuedSlot);
+    EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, dequeuedSlot);
+
+    sp<GraphicBuffer> dequeuedBuffer;
+    igbp->requestBuffer(dequeuedSlot, &dequeuedBuffer);
+    uint8_t* img = nullptr;
+    ASSERT_EQ(NO_ERROR, dequeuedBuffer->lock(kImageBufferUsage, (void**)(&img)));
+
+    // Write in some dummy image data.
+    fillRGBA8Buffer(img, dequeuedBuffer->getWidth(), dequeuedBuffer->getHeight(),
+                    dequeuedBuffer->getStride());
+    ASSERT_EQ(NO_ERROR, dequeuedBuffer->unlock());
+    QueueBufferInput queueBufferInput(kQueueBufferInputTimeStamp,
+                                      kQueueBufferInputIsAutoTimeStamp,
+                                      kQueueBufferInputDataspace,
+                                      kQueueBufferInputRect,
+                                      kQueueBufferInputScalingMode,
+                                      kQueueBufferInputTransform,
+                                      kQueueBufferInputFence);
+    QueueBufferOutput queueBufferOutput;
+    ASSERT_EQ(OK, igbp->queueBuffer(dequeuedSlot, queueBufferInput,
+                                    &queueBufferOutput));
+    // wait until the onImageAvailable callback is called, or timeout completes.
+    std::unique_lock<std::mutex> lock(imageAvailableMutex_);
+    imageCondVar_.wait_for(lock, std::chrono::microseconds(kOnImageAvailableWaitUs),
+                           [this]{ return this->imageAvailable_;});
+    EXPECT_TRUE(imageAvailable_) <<  "Timed out waiting for image data to be handled!\n";
+}
+
+class AImageReaderPrivateFormatTest : public ::testing::Test {
+  public:
+    void SetUp() override {
+        auto status = AImageReader_new(kImageWidth, kImageHeight, AIMAGE_FORMAT_RAW_DEPTH,
+                                       kMaxImages, &imgReader);
+        EXPECT_TRUE(status == AMEDIA_OK);
+    }
+
+    void TearDown() override {
+        if (imgReader) {
+            AImageReader_delete(imgReader);
+        }
+    }
+    AImageReader *imgReader = nullptr;
+};
+
+TEST_F(AImageReaderPrivateFormatTest, CreateTest) {
+    EXPECT_TRUE(imgReader != nullptr);
+}
+
+
+}  // namespace android
diff --git a/media/utils/AImageReaderUtils.cpp b/media/utils/AImageReaderUtils.cpp
new file mode 100644
index 0000000..d97c340
--- /dev/null
+++ b/media/utils/AImageReaderUtils.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cmath>
+
+#include <mediautils/AImageReaderUtils.h>
+#include <hidl/HybridInterface.h>
+
+namespace android {
+namespace aimg {
+
+using hardware::hidl_vec;
+
+static sp<HGraphicBufferProducer> convertNativeHandleToHGBP (
+        const native_handle_t *handle) {
+    // Read the size of the halToken vec<uint8_t>
+    hidl_vec<uint8_t> halToken;
+    halToken.setToExternal(
+        reinterpret_cast<uint8_t *>(const_cast<int *>(&(handle->data[1]))),
+        handle->data[0]);
+    sp<HGraphicBufferProducer> hgbp =
+        HGraphicBufferProducer::castFrom(retrieveHalInterface(halToken));
+    return hgbp;
+}
+
+sp<HGraphicBufferProducer> AImageReader_getHGBPFromHandle(
+    const native_handle_t *handle) {
+    if (handle == nullptr) {
+        return nullptr;
+    }
+    if (handle->numFds != 0  ||
+        handle->numInts < std::ceil(sizeof(size_t) / sizeof(int))) {
+        return nullptr;
+    }
+    return convertNativeHandleToHGBP(handle);
+}
+
+} //namespace aimg
+} //namespace android
diff --git a/media/utils/Android.bp b/media/utils/Android.bp
index d6dae5b..3adb40f 100644
--- a/media/utils/Android.bp
+++ b/media/utils/Android.bp
@@ -16,25 +16,43 @@
     name: "libmediautils",
 
     srcs: [
+        "AImageReaderUtils.cpp",
         "BatteryNotifier.cpp",
         "ISchedulingPolicyService.cpp",
         "MemoryLeakTrackUtil.cpp",
         "ProcessInfo.cpp",
         "SchedulingPolicyService.cpp",
+        "ServiceUtilities.cpp",
+        "TimeCheck.cpp",
     ],
     shared_libs: [
         "libbinder",
         "liblog",
         "libutils",
         "libmemunreachable",
+        "libhidlbase",
+        "android.hardware.graphics.bufferqueue@1.0",
+        "android.hidl.token@1.0-utils",
     ],
 
+    logtags: ["EventLogTags.logtags"],
+
     cflags: [
         "-Wall",
         "-Wextra",
         "-Werror",
     ],
 
+    product_variables: {
+        product_is_iot: {
+            cflags: ["-DTARGET_ANDROID_THINGS"],
+        },
+    },
+
+    include_dirs: [
+        // For android_mallopt definitions.
+        "bionic/libc/private"
+    ],
     local_include_dirs: ["include"],
     export_include_dirs: ["include"],
 }
diff --git a/media/utils/EventLogTags.logtags b/media/utils/EventLogTags.logtags
new file mode 100644
index 0000000..67f0ea8
--- /dev/null
+++ b/media/utils/EventLogTags.logtags
@@ -0,0 +1,41 @@
+# The entries in this file map a sparse set of log tag numbers to tag names.
+# This is installed on the device, in /system/etc, and parsed by logcat.
+#
+# Tag numbers are decimal integers, from 0 to 2^31.  (Let's leave the
+# negative values alone for now.)
+#
+# Tag names are one or more ASCII letters and numbers or underscores, i.e.
+# "[A-Z][a-z][0-9]_".  Do not include spaces or punctuation (the former
+# impacts log readability, the latter makes regex searches more annoying).
+#
+# Tag numbers and names are separated by whitespace.  Blank lines and lines
+# starting with '#' are ignored.
+#
+# Optionally, after the tag names can be put a description for the value(s)
+# of the tag. Description are in the format
+#    (<name>|data type[|data unit])
+# Multiple values are separated by commas.
+#
+# The data type is a number from the following values:
+# 1: int
+# 2: long
+# 3: string
+# 4: list
+#
+# The data unit is a number taken from the following list:
+# 1: Number of objects
+# 2: Number of bytes
+# 3: Number of milliseconds
+# 4: Number of allocations
+# 5: Id
+# 6: Percent
+# Default value for data of type int/long is 2 (bytes).
+#
+# See system/core/logcat/event.logtags for the master copy of the tags.
+
+# 61000 - 61199 reserved for audioserver
+
+61000 audioserver_binder_timeout (command|3)
+
+# NOTE - the range 1000000-2000000 is reserved for partners and others who
+# want to define their own log tags without conflicting with the core platform.
diff --git a/media/utils/MemoryLeakTrackUtil.cpp b/media/utils/MemoryLeakTrackUtil.cpp
index 18f5f25..2988b52 100644
--- a/media/utils/MemoryLeakTrackUtil.cpp
+++ b/media/utils/MemoryLeakTrackUtil.cpp
@@ -22,6 +22,8 @@
 #include "media/MemoryLeakTrackUtil.h"
 #include <sstream>
 
+#include <bionic_malloc.h>
+
 /*
  * The code here originally resided in MediaPlayerService.cpp
  */
@@ -47,29 +49,22 @@
 
 namespace android {
 
-extern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize,
-        size_t* infoSize, size_t* totalMemory, size_t* backtraceSize);
-
-extern "C" void free_malloc_leak_info(uint8_t* info);
-
 std::string dumpMemoryAddresses(size_t limit)
 {
-    uint8_t *info;
-    size_t overallSize;
-    size_t infoSize;
-    size_t totalMemory;
-    size_t backtraceSize;
-    get_malloc_leak_info(&info, &overallSize, &infoSize, &totalMemory, &backtraceSize);
+    android_mallopt_leak_info_t leak_info;
+    if (!android_mallopt(M_GET_MALLOC_LEAK_INFO, &leak_info, sizeof(leak_info))) {
+      return "";
+    }
 
     size_t count;
-    if (info == nullptr || overallSize == 0 || infoSize == 0
-            || (count = overallSize / infoSize) == 0) {
+    if (leak_info.buffer == nullptr || leak_info.overall_size == 0 || leak_info.info_size == 0
+            || (count = leak_info.overall_size / leak_info.info_size) == 0) {
         ALOGD("no malloc info, libc.debug.malloc.program property should be set");
-        return std::string();
+        return "";
     }
 
     std::ostringstream oss;
-    oss << totalMemory << " bytes in " << count << " allocations\n";
+    oss << leak_info.total_memory << " bytes in " << count << " allocations\n";
     oss << "  ABI: '" ABI_STRING "'" << "\n\n";
     if (count > limit) count = limit;
 
@@ -83,14 +78,14 @@
             uintptr_t backtrace[];
         };
 
-        const AllocEntry * const e = (AllocEntry *)(info + i * infoSize);
+        const AllocEntry * const e = (AllocEntry *)(leak_info.buffer + i * leak_info.info_size);
 
         oss << (e->size * e->allocations)
                 << " bytes ( " << e->size << " bytes * " << e->allocations << " allocations )\n";
-        oss << backtrace_string(e->backtrace, backtraceSize) << "\n";
+        oss << backtrace_string(e->backtrace, leak_info.backtrace_size) << "\n";
     }
     oss << "\n";
-    free_malloc_leak_info(info);
+    android_mallopt(M_FREE_MALLOC_LEAK_INFO, &leak_info, sizeof(leak_info));
     return oss.str();
 }
 
diff --git a/media/utils/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp
new file mode 100644
index 0000000..b824212
--- /dev/null
+++ b/media/utils/ServiceUtilities.cpp
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ServiceUtilities"
+
+#include <binder/AppOpsManager.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/PermissionCache.h>
+#include "mediautils/ServiceUtilities.h"
+
+#include <iterator>
+#include <algorithm>
+
+/* When performing permission checks we do not use permission cache for
+ * runtime permissions (protection level dangerous) as they may change at
+ * runtime. All other permissions (protection level normal and dangerous)
+ * can be cached as they never change. Of course all permission checked
+ * here are platform defined.
+ */
+
+namespace android {
+
+static const String16 sAndroidPermissionRecordAudio("android.permission.RECORD_AUDIO");
+static const String16 sModifyPhoneState("android.permission.MODIFY_PHONE_STATE");
+static const String16 sModifyAudioRouting("android.permission.MODIFY_AUDIO_ROUTING");
+
+static String16 resolveCallingPackage(PermissionController& permissionController,
+        const String16& opPackageName, uid_t uid) {
+    if (opPackageName.size() > 0) {
+        return opPackageName;
+    }
+    // In some cases the calling code has no access to the package it runs under.
+    // For example, code using the wilhelm framework's OpenSL-ES APIs. In this
+    // case we will get the packages for the calling UID and pick the first one
+    // for attributing the app op. This will work correctly for runtime permissions
+    // as for legacy apps we will toggle the app op for all packages in the UID.
+    // The caveat is that the operation may be attributed to the wrong package and
+    // stats based on app ops may be slightly off.
+    Vector<String16> packages;
+    permissionController.getPackagesForUid(uid, packages);
+    if (packages.isEmpty()) {
+        ALOGE("No packages for uid %d", uid);
+        return opPackageName; // empty string
+    }
+    return packages[0];
+}
+
+static bool checkRecordingInternal(const String16& opPackageName, pid_t pid,
+        uid_t uid, bool start) {
+    // Okay to not track in app ops as audio server is us and if
+    // device is rooted security model is considered compromised.
+    if (isAudioServerOrRootUid(uid)) return true;
+
+    // We specify a pid and uid here as mediaserver (aka MediaRecorder or StageFrightRecorder)
+    // may open a record track on behalf of a client.  Note that pid may be a tid.
+    // IMPORTANT: DON'T USE PermissionCache - RUNTIME PERMISSIONS CHANGE.
+    PermissionController permissionController;
+    const bool ok = permissionController.checkPermission(sAndroidPermissionRecordAudio, pid, uid);
+    if (!ok) {
+        ALOGE("Request requires %s", String8(sAndroidPermissionRecordAudio).c_str());
+        return false;
+    }
+
+    String16 resolvedOpPackageName = resolveCallingPackage(
+            permissionController, opPackageName, uid);
+    if (resolvedOpPackageName.size() == 0) {
+        return false;
+    }
+
+    AppOpsManager appOps;
+    const int32_t op = appOps.permissionToOpCode(sAndroidPermissionRecordAudio);
+    if (start) {
+        if (appOps.startOpNoThrow(op, uid, resolvedOpPackageName, /*startIfModeDefault*/ false)
+                != AppOpsManager::MODE_ALLOWED) {
+            ALOGE("Request denied by app op: %d", op);
+            return false;
+        }
+    } else {
+        if (appOps.checkOp(op, uid, resolvedOpPackageName) != AppOpsManager::MODE_ALLOWED) {
+            ALOGE("Request denied by app op: %d", op);
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid) {
+    return checkRecordingInternal(opPackageName, pid, uid, /*start*/ false);
+}
+
+bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid) {
+     return checkRecordingInternal(opPackageName, pid, uid, /*start*/ true);
+}
+
+void finishRecording(const String16& opPackageName, uid_t uid) {
+    // Okay to not track in app ops as audio server is us and if
+    // device is rooted security model is considered compromised.
+    if (isAudioServerOrRootUid(uid)) return;
+
+    PermissionController permissionController;
+    String16 resolvedOpPackageName = resolveCallingPackage(
+            permissionController, opPackageName, uid);
+    if (resolvedOpPackageName.size() == 0) {
+        return;
+    }
+
+    AppOpsManager appOps;
+    const int32_t op = appOps.permissionToOpCode(sAndroidPermissionRecordAudio);
+    appOps.finishOp(op, uid, resolvedOpPackageName);
+}
+
+bool captureAudioOutputAllowed(pid_t pid, uid_t uid) {
+    if (isAudioServerOrRootUid(uid)) return true;
+    static const String16 sCaptureAudioOutput("android.permission.CAPTURE_AUDIO_OUTPUT");
+    bool ok = PermissionCache::checkPermission(sCaptureAudioOutput, pid, uid);
+    if (!ok) ALOGV("Request requires android.permission.CAPTURE_AUDIO_OUTPUT");
+    return ok;
+}
+
+bool captureMediaOutputAllowed(pid_t pid, uid_t uid) {
+    if (isAudioServerOrRootUid(uid)) return true;
+    static const String16 sCaptureMediaOutput("android.permission.CAPTURE_MEDIA_OUTPUT");
+    bool ok = PermissionCache::checkPermission(sCaptureMediaOutput, pid, uid);
+    if (!ok) ALOGE("Request requires android.permission.CAPTURE_MEDIA_OUTPUT");
+    return ok;
+}
+
+bool captureHotwordAllowed(const String16& opPackageName, pid_t pid, uid_t uid) {
+    // CAPTURE_AUDIO_HOTWORD permission implies RECORD_AUDIO permission
+    bool ok = recordingAllowed(opPackageName, pid, uid);
+
+    if (ok) {
+        static const String16 sCaptureHotwordAllowed("android.permission.CAPTURE_AUDIO_HOTWORD");
+        // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
+        ok = PermissionCache::checkPermission(sCaptureHotwordAllowed, pid, uid);
+    }
+    if (!ok) ALOGV("android.permission.CAPTURE_AUDIO_HOTWORD");
+    return ok;
+}
+
+bool settingsAllowed() {
+    // given this is a permission check, could this be isAudioServerOrRootUid()?
+    if (isAudioServerUid(IPCThreadState::self()->getCallingUid())) return true;
+    static const String16 sAudioSettings("android.permission.MODIFY_AUDIO_SETTINGS");
+    // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
+    bool ok = PermissionCache::checkCallingPermission(sAudioSettings);
+    if (!ok) ALOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
+    return ok;
+}
+
+bool modifyAudioRoutingAllowed() {
+    // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
+    bool ok = PermissionCache::checkCallingPermission(sModifyAudioRouting);
+    if (!ok) ALOGE("android.permission.MODIFY_AUDIO_ROUTING");
+    return ok;
+}
+
+bool modifyDefaultAudioEffectsAllowed() {
+    static const String16 sModifyDefaultAudioEffectsAllowed(
+            "android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS");
+    // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
+    bool ok = PermissionCache::checkCallingPermission(sModifyDefaultAudioEffectsAllowed);
+
+#ifdef TARGET_ANDROID_THINGS
+    if (!ok) {
+        // Use a secondary permission on Android Things to allow a more lenient level of protection.
+        static const String16 sModifyDefaultAudioEffectsAndroidThingsAllowed(
+                "com.google.android.things.permission.MODIFY_DEFAULT_AUDIO_EFFECTS");
+        ok = PermissionCache::checkCallingPermission(
+                sModifyDefaultAudioEffectsAndroidThingsAllowed);
+    }
+    if (!ok) ALOGE("com.google.android.things.permission.MODIFY_DEFAULT_AUDIO_EFFECTS");
+#else
+    if (!ok) ALOGE("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS");
+#endif
+    return ok;
+}
+
+bool dumpAllowed() {
+    static const String16 sDump("android.permission.DUMP");
+    // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
+    bool ok = PermissionCache::checkCallingPermission(sDump);
+    // convention is for caller to dump an error message to fd instead of logging here
+    //if (!ok) ALOGE("Request requires android.permission.DUMP");
+    return ok;
+}
+
+bool modifyPhoneStateAllowed(pid_t pid, uid_t uid) {
+    bool ok = PermissionCache::checkPermission(sModifyPhoneState, pid, uid);
+    ALOGE_IF(!ok, "Request requires %s", String8(sModifyPhoneState).c_str());
+    return ok;
+}
+
+// privileged behavior needed by Dialer, Settings, SetupWizard and CellBroadcastReceiver
+bool bypassInterruptionPolicyAllowed(pid_t pid, uid_t uid) {
+    static const String16 sWriteSecureSettings("android.permission.WRITE_SECURE_SETTINGS");
+    bool ok = PermissionCache::checkPermission(sModifyPhoneState, pid, uid)
+        || PermissionCache::checkPermission(sWriteSecureSettings, pid, uid)
+        || PermissionCache::checkPermission(sModifyAudioRouting, pid, uid);
+    ALOGE_IF(!ok, "Request requires %s or %s",
+             String8(sModifyPhoneState).c_str(), String8(sWriteSecureSettings).c_str());
+    return ok;
+}
+
+status_t checkIMemory(const sp<IMemory>& iMemory)
+{
+    if (iMemory == 0) {
+        ALOGE("%s check failed: NULL IMemory pointer", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    sp<IMemoryHeap> heap = iMemory->getMemory();
+    if (heap == 0) {
+        ALOGE("%s check failed: NULL heap pointer", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    off_t size = lseek(heap->getHeapID(), 0, SEEK_END);
+    lseek(heap->getHeapID(), 0, SEEK_SET);
+
+    if (iMemory->pointer() == NULL || size < (off_t)iMemory->size()) {
+        ALOGE("%s check failed: pointer %p size %zu fd size %u",
+              __FUNCTION__, iMemory->pointer(), iMemory->size(), (uint32_t)size);
+        return BAD_VALUE;
+    }
+
+    return NO_ERROR;
+}
+
+sp<content::pm::IPackageManagerNative> MediaPackageManager::retreivePackageManager() {
+    const sp<IServiceManager> sm = defaultServiceManager();
+    if (sm == nullptr) {
+        ALOGW("%s: failed to retrieve defaultServiceManager", __func__);
+        return nullptr;
+    }
+    sp<IBinder> packageManager = sm->checkService(String16(nativePackageManagerName));
+    if (packageManager == nullptr) {
+        ALOGW("%s: failed to retrieve native package manager", __func__);
+        return nullptr;
+    }
+    return interface_cast<content::pm::IPackageManagerNative>(packageManager);
+}
+
+std::optional<bool> MediaPackageManager::doIsAllowed(uid_t uid) {
+    if (mPackageManager == nullptr) {
+        /** Can not fetch package manager at construction it may not yet be registered. */
+        mPackageManager = retreivePackageManager();
+        if (mPackageManager == nullptr) {
+            ALOGW("%s: Playback capture is denied as package manager is not reachable", __func__);
+            return std::nullopt;
+        }
+    }
+
+    std::vector<std::string> packageNames;
+    auto status = mPackageManager->getNamesForUids({(int32_t)uid}, &packageNames);
+    if (!status.isOk()) {
+        ALOGW("%s: Playback capture is denied for uid %u as the package names could not be "
+              "retrieved from the package manager: %s", __func__, uid, status.toString8().c_str());
+        return std::nullopt;
+    }
+    if (packageNames.empty()) {
+        ALOGW("%s: Playback capture for uid %u is denied as no package name could be retrieved "
+              "from the package manager: %s", __func__, uid, status.toString8().c_str());
+        return std::nullopt;
+    }
+    std::vector<bool> isAllowed;
+    status = mPackageManager->isAudioPlaybackCaptureAllowed(packageNames, &isAllowed);
+    if (!status.isOk()) {
+        ALOGW("%s: Playback capture is denied for uid %u as the manifest property could not be "
+              "retrieved from the package manager: %s", __func__, uid, status.toString8().c_str());
+        return std::nullopt;
+    }
+    if (packageNames.size() != isAllowed.size()) {
+        ALOGW("%s: Playback capture is denied for uid %u as the package manager returned incoherent"
+              " response size: %zu != %zu", __func__, uid, packageNames.size(), isAllowed.size());
+        return std::nullopt;
+    }
+
+    // Zip together packageNames and isAllowed for debug logs
+    Packages& packages = mDebugLog[uid];
+    packages.resize(packageNames.size()); // Reuse all objects
+    std::transform(begin(packageNames), end(packageNames), begin(isAllowed),
+                   begin(packages), [] (auto& name, bool isAllowed) -> Package {
+                       return {std::move(name), isAllowed};
+                   });
+
+    // Only allow playback record if all packages in this UID allow it
+    bool playbackCaptureAllowed = std::all_of(begin(isAllowed), end(isAllowed),
+                                                  [](bool b) { return b; });
+
+    return playbackCaptureAllowed;
+}
+
+void MediaPackageManager::dump(int fd, int spaces) const {
+    dprintf(fd, "%*sAllow playback capture log:\n", spaces, "");
+    if (mPackageManager == nullptr) {
+        dprintf(fd, "%*sNo package manager\n", spaces + 2, "");
+    }
+    dprintf(fd, "%*sPackage manager errors: %u\n", spaces + 2, "", mPackageManagerErrors);
+
+    for (const auto& uidCache : mDebugLog) {
+        for (const auto& package : std::get<Packages>(uidCache)) {
+            dprintf(fd, "%*s- uid=%5u, allowPlaybackCapture=%s, packageName=%s\n", spaces + 2, "",
+                    std::get<const uid_t>(uidCache),
+                    package.playbackCaptureAllowed ? "true " : "false",
+                    package.name.c_str());
+        }
+    }
+}
+
+} // namespace android
diff --git a/media/utils/TimeCheck.cpp b/media/utils/TimeCheck.cpp
new file mode 100644
index 0000000..59cf4ef
--- /dev/null
+++ b/media/utils/TimeCheck.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <utils/Log.h>
+#include <media/TimeCheck.h>
+#include <media/EventLog.h>
+
+namespace android {
+
+/* static */
+sp<TimeCheck::TimeCheckThread> TimeCheck::getTimeCheckThread()
+{
+    static sp<TimeCheck::TimeCheckThread> sTimeCheckThread = new TimeCheck::TimeCheckThread();
+    return sTimeCheckThread;
+}
+
+TimeCheck::TimeCheck(const char *tag, uint32_t timeoutMs)
+    : mEndTimeNs(getTimeCheckThread()->startMonitoring(tag, timeoutMs))
+{
+}
+
+TimeCheck::~TimeCheck() {
+    getTimeCheckThread()->stopMonitoring(mEndTimeNs);
+}
+
+TimeCheck::TimeCheckThread::~TimeCheckThread()
+{
+    AutoMutex _l(mMutex);
+    requestExit();
+    mMonitorRequests.clear();
+    mCond.signal();
+}
+
+nsecs_t TimeCheck::TimeCheckThread::startMonitoring(const char *tag, uint32_t timeoutMs) {
+    Mutex::Autolock _l(mMutex);
+    nsecs_t endTimeNs = systemTime() + milliseconds(timeoutMs);
+    for (; mMonitorRequests.indexOfKey(endTimeNs) >= 0; ++endTimeNs);
+    mMonitorRequests.add(endTimeNs, tag);
+    mCond.signal();
+    return endTimeNs;
+}
+
+void TimeCheck::TimeCheckThread::stopMonitoring(nsecs_t endTimeNs) {
+    Mutex::Autolock _l(mMutex);
+    mMonitorRequests.removeItem(endTimeNs);
+    mCond.signal();
+}
+
+bool TimeCheck::TimeCheckThread::threadLoop()
+{
+    status_t status = TIMED_OUT;
+    const char *tag;
+    {
+        AutoMutex _l(mMutex);
+
+        if (exitPending()) {
+            return false;
+        }
+
+        nsecs_t endTimeNs = INT64_MAX;
+        // KeyedVector mMonitorRequests is ordered so take first entry as next timeout
+        if (mMonitorRequests.size() != 0) {
+            endTimeNs = mMonitorRequests.keyAt(0);
+            tag = mMonitorRequests.valueAt(0);
+        }
+
+        const nsecs_t waitTimeNs = endTimeNs - systemTime();
+        if (waitTimeNs > 0) {
+            status = mCond.waitRelative(mMutex, waitTimeNs);
+        }
+    }
+    if (status != NO_ERROR) {
+        LOG_EVENT_STRING(LOGTAG_AUDIO_BINDER_TIMEOUT, tag);
+        LOG_ALWAYS_FATAL("TimeCheck timeout for %s", tag);
+    }
+    return true;
+}
+
+}; // namespace android
diff --git a/media/utils/include/mediautils/AImageReaderUtils.h b/media/utils/include/mediautils/AImageReaderUtils.h
new file mode 100644
index 0000000..c9bde1f
--- /dev/null
+++ b/media/utils/include/mediautils/AImageReaderUtils.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AIMAGE_READER_UTILS_H
+#define AIMAGE_READER_UTILS_H
+
+#include <cutils/native_handle.h>
+#include <android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer.h>
+
+namespace android {
+namespace aimg {
+
+using HGraphicBufferProducer = hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer;
+
+// Retrieves HGraphicBufferProducer corresponding to the native_handle_t
+// provided (this native handle MUST have been obtained by AImageReader_getWindowNativeHandle()).
+sp<HGraphicBufferProducer> AImageReader_getHGBPFromHandle(const native_handle_t *handle);
+
+}// namespace aimg
+}// namespace android
+
+#endif //AIMAGE_READER_UTILS_H
diff --git a/media/utils/include/mediautils/EventLog.h b/media/utils/include/mediautils/EventLog.h
new file mode 100644
index 0000000..553d3bd
--- /dev/null
+++ b/media/utils/include/mediautils/EventLog.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_AUDIO_EVENT_LOG_H_
+#define ANDROID_AUDIO_EVENT_LOG_H_
+
+namespace android {
+
+// keep values in sync with frameworks/av/media/utils/EventLogTags.logtags
+enum {
+  LOGTAG_AUDIO_BINDER_TIMEOUT = 61000,
+};
+
+}  // namespace android
+
+#endif  // ANDROID_AUDIO_EVENT_LOG_H_
diff --git a/media/utils/include/mediautils/ServiceUtilities.h b/media/utils/include/mediautils/ServiceUtilities.h
new file mode 100644
index 0000000..2a6e609
--- /dev/null
+++ b/media/utils/include/mediautils/ServiceUtilities.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_MEDIAUTILS_SERVICEUTILITIES_H
+#define ANDROID_MEDIAUTILS_SERVICEUTILITIES_H
+
+#include <unistd.h>
+
+#include <android/content/pm/IPackageManagerNative.h>
+#include <binder/IMemory.h>
+#include <binder/PermissionController.h>
+#include <cutils/multiuser.h>
+#include <private/android_filesystem_config.h>
+
+#include <map>
+#include <optional>
+#include <string>
+#include <vector>
+
+namespace android {
+
+// Audio permission utilities
+
+// Used for calls that should originate from system services.
+// We allow that some services might have separate processes to
+// handle multiple users, e.g. u10_system, u10_bluetooth, u10_radio.
+static inline bool isServiceUid(uid_t uid) {
+    return multiuser_get_app_id(uid) < AID_APP_START;
+}
+
+// Used for calls that should originate from audioserver.
+static inline bool isAudioServerUid(uid_t uid) {
+    return uid == AID_AUDIOSERVER;
+}
+
+// Used for some permission checks.
+// AID_ROOT is OK for command-line tests.  Native audioserver always OK.
+static inline bool isAudioServerOrRootUid(uid_t uid) {
+    return uid == AID_AUDIOSERVER || uid == AID_ROOT;
+}
+
+// Used for calls that should come from system server or internal.
+// Note: system server is multiprocess for multiple users.  audioserver is not.
+static inline bool isAudioServerOrSystemServerUid(uid_t uid) {
+    return multiuser_get_app_id(uid) == AID_SYSTEM || uid == AID_AUDIOSERVER;
+}
+
+// Mediaserver may forward the client PID and UID as part of a binder interface call;
+// otherwise the calling UID must be equal to the client UID.
+static inline bool isAudioServerOrMediaServerUid(uid_t uid) {
+    switch (uid) {
+    case AID_MEDIA:
+    case AID_AUDIOSERVER:
+        return true;
+    default:
+        return false;
+    }
+}
+
+bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid);
+bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid);
+void finishRecording(const String16& opPackageName, uid_t uid);
+bool captureAudioOutputAllowed(pid_t pid, uid_t uid);
+bool captureMediaOutputAllowed(pid_t pid, uid_t uid);
+bool captureHotwordAllowed(const String16& opPackageName, pid_t pid, uid_t uid);
+bool settingsAllowed();
+bool modifyAudioRoutingAllowed();
+bool modifyDefaultAudioEffectsAllowed();
+bool dumpAllowed();
+bool modifyPhoneStateAllowed(pid_t pid, uid_t uid);
+bool bypassInterruptionPolicyAllowed(pid_t pid, uid_t uid);
+
+status_t checkIMemory(const sp<IMemory>& iMemory);
+
+class MediaPackageManager {
+public:
+    /** Query the PackageManager to check if all apps of an UID allow playback capture. */
+    bool allowPlaybackCapture(uid_t uid) {
+        auto result = doIsAllowed(uid);
+        if (!result) {
+            mPackageManagerErrors++;
+        }
+        return result.value_or(false);
+    }
+    void dump(int fd, int spaces = 0) const;
+private:
+    static constexpr const char* nativePackageManagerName = "package_native";
+    std::optional<bool> doIsAllowed(uid_t uid);
+    sp<content::pm::IPackageManagerNative> retreivePackageManager();
+    sp<content::pm::IPackageManagerNative> mPackageManager; // To check apps manifest
+    uint_t mPackageManagerErrors = 0;
+    struct Package {
+        std::string name;
+        bool playbackCaptureAllowed = false;
+    };
+    using Packages = std::vector<Package>;
+    std::map<uid_t, Packages> mDebugLog;
+};
+}
+
+#endif // ANDROID_MEDIAUTILS_SERVICEUTILITIES_H
diff --git a/media/libmedia/include/media/TimeCheck.h b/media/utils/include/mediautils/TimeCheck.h
similarity index 100%
rename from media/libmedia/include/media/TimeCheck.h
rename to media/utils/include/mediautils/TimeCheck.h
diff --git a/packages/MediaComponents/Android.mk b/packages/MediaComponents/Android.mk
deleted file mode 100644
index def9dc5..0000000
--- a/packages/MediaComponents/Android.mk
+++ /dev/null
@@ -1,72 +0,0 @@
-#
-# Copyright 2017 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# This package is excluded from build for now since APIs using this apk became hidden.
-#
-#LOCAL_PATH := $(call my-dir)
-#ifneq ($(TARGET_BUILD_PDK),true) # Build MediaComponents only if this is not a PDK build.  MediaComponents won't
-## build in PDK builds because frameworks/base/core/java is not available but
-## IMediaSession2.aidl and IMediaController2.aidl are using classes from
-## frameworks/base/core/java.
-#
-#include $(CLEAR_VARS)
-#
-#LOCAL_PACKAGE_NAME := MediaComponents
-#LOCAL_MODULE_OWNER := google
-#
-## TODO: create a separate key for this package.
-#LOCAL_CERTIFICATE := platform
-#
-## TODO: Use System SDK once public APIs are approved
-## LOCAL_SDK_VERSION := system_current
-#LOCAL_PRIVATE_PLATFORM_APIS := true
-#
-#LOCAL_SRC_FILES := \
-#    $(call all-java-files-under, src) \
-#    $(call all-Iaidl-files-under, src)
-#
-#LOCAL_PROGUARD_FLAG_FILES := proguard.cfg
-#
-#LOCAL_MULTILIB := first
-#
-#LOCAL_JAVA_LIBRARIES += android-support-annotations
-#
-## To embed native libraries in package, uncomment the lines below.
-##LOCAL_MODULE_TAGS := samples
-##LOCAL_JNI_SHARED_LIBRARIES := \
-##    libaacextractor \
-##    libamrextractor \
-##    libflacextractor \
-##    libmidiextractor \
-##    libmkvextractor \
-##    libmp3extractor \
-##    libmp4extractor \
-##    libmpeg2extractor \
-##    liboggextractor \
-##    libwavextractor \
-#
-## TODO: Remove dependency with other support libraries.
-#LOCAL_STATIC_ANDROID_LIBRARIES += \
-#    android-support-v4 \
-#    android-support-v7-appcompat \
-#    android-support-v7-palette
-#LOCAL_USE_AAPT2 := true
-#
-#include $(BUILD_PACKAGE)
-#
-#endif  # ifneq ($(TARGET_BUILD_PDK),true)
-#
-#include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/MediaComponents/AndroidManifest.xml b/packages/MediaComponents/AndroidManifest.xml
deleted file mode 100644
index 50fdca1..0000000
--- a/packages/MediaComponents/AndroidManifest.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.media.update"
-    android:versionCode="1"
-    android:versionName="1.0" >
-
-    <application
-        android:label="Media Components Update"
-        android:multiArch="true"
-        android:allowBackup="false"
-        android:hasCode="false"
-        android:extractNativeLibs="false">
-    </application>
-
-</manifest>
diff --git a/packages/MediaComponents/proguard.cfg b/packages/MediaComponents/proguard.cfg
deleted file mode 100644
index d7bf730..0000000
--- a/packages/MediaComponents/proguard.cfg
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Copyright 2017 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# Keep entry point for updatable Java classes
--keep public class com.android.media.update.ApiFactory {
-   public static com.android.media.update.ApiFactory initialize(android.content.pm.ApplicationInfo);
-}
diff --git a/packages/MediaComponents/res/drawable-hdpi/ic_audiotrack_dark.png b/packages/MediaComponents/res/drawable-hdpi/ic_audiotrack_dark.png
deleted file mode 100644
index 17fd51f..0000000
--- a/packages/MediaComponents/res/drawable-hdpi/ic_audiotrack_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-hdpi/ic_audiotrack_light.png b/packages/MediaComponents/res/drawable-hdpi/ic_audiotrack_light.png
deleted file mode 100644
index d7c8252..0000000
--- a/packages/MediaComponents/res/drawable-hdpi/ic_audiotrack_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-hdpi/ic_dialog_close_dark.png b/packages/MediaComponents/res/drawable-hdpi/ic_dialog_close_dark.png
deleted file mode 100644
index 928ddea..0000000
--- a/packages/MediaComponents/res/drawable-hdpi/ic_dialog_close_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-hdpi/ic_dialog_close_light.png b/packages/MediaComponents/res/drawable-hdpi/ic_dialog_close_light.png
deleted file mode 100644
index 1a9cd75..0000000
--- a/packages/MediaComponents/res/drawable-hdpi/ic_dialog_close_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-hdpi/ic_media_pause_dark.png b/packages/MediaComponents/res/drawable-hdpi/ic_media_pause_dark.png
deleted file mode 100644
index 7192ad4..0000000
--- a/packages/MediaComponents/res/drawable-hdpi/ic_media_pause_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-hdpi/ic_media_pause_light.png b/packages/MediaComponents/res/drawable-hdpi/ic_media_pause_light.png
deleted file mode 100644
index bb707ea..0000000
--- a/packages/MediaComponents/res/drawable-hdpi/ic_media_pause_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-hdpi/ic_media_play_dark.png b/packages/MediaComponents/res/drawable-hdpi/ic_media_play_dark.png
deleted file mode 100644
index 0c32d00..0000000
--- a/packages/MediaComponents/res/drawable-hdpi/ic_media_play_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-hdpi/ic_media_play_light.png b/packages/MediaComponents/res/drawable-hdpi/ic_media_play_light.png
deleted file mode 100644
index 5345ee3..0000000
--- a/packages/MediaComponents/res/drawable-hdpi/ic_media_play_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-hdpi/ic_media_stop_dark.png b/packages/MediaComponents/res/drawable-hdpi/ic_media_stop_dark.png
deleted file mode 100644
index 801d341..0000000
--- a/packages/MediaComponents/res/drawable-hdpi/ic_media_stop_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-hdpi/ic_media_stop_light.png b/packages/MediaComponents/res/drawable-hdpi/ic_media_stop_light.png
deleted file mode 100644
index 9d6b65d..0000000
--- a/packages/MediaComponents/res/drawable-hdpi/ic_media_stop_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-hdpi/ic_media_subtitle_disabled.png b/packages/MediaComponents/res/drawable-hdpi/ic_media_subtitle_disabled.png
deleted file mode 100644
index 0354f61..0000000
--- a/packages/MediaComponents/res/drawable-hdpi/ic_media_subtitle_disabled.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-hdpi/ic_media_subtitle_enabled.png b/packages/MediaComponents/res/drawable-hdpi/ic_media_subtitle_enabled.png
deleted file mode 100644
index 5f8febe..0000000
--- a/packages/MediaComponents/res/drawable-hdpi/ic_media_subtitle_enabled.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-hdpi/ic_mr_button_disabled_dark.png b/packages/MediaComponents/res/drawable-hdpi/ic_mr_button_disabled_dark.png
deleted file mode 100644
index 8ad305d..0000000
--- a/packages/MediaComponents/res/drawable-hdpi/ic_mr_button_disabled_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-hdpi/ic_mr_button_disabled_light.png b/packages/MediaComponents/res/drawable-hdpi/ic_mr_button_disabled_light.png
deleted file mode 100644
index 887fde4..0000000
--- a/packages/MediaComponents/res/drawable-hdpi/ic_mr_button_disabled_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-hdpi/ic_mr_button_disconnected_dark.png b/packages/MediaComponents/res/drawable-hdpi/ic_mr_button_disconnected_dark.png
deleted file mode 100644
index 5739df7..0000000
--- a/packages/MediaComponents/res/drawable-hdpi/ic_mr_button_disconnected_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-hdpi/ic_mr_button_disconnected_light.png b/packages/MediaComponents/res/drawable-hdpi/ic_mr_button_disconnected_light.png
deleted file mode 100644
index 58c344a..0000000
--- a/packages/MediaComponents/res/drawable-hdpi/ic_mr_button_disconnected_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-hdpi/ic_mr_button_grey.png b/packages/MediaComponents/res/drawable-hdpi/ic_mr_button_grey.png
deleted file mode 100644
index 1a03420..0000000
--- a/packages/MediaComponents/res/drawable-hdpi/ic_mr_button_grey.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-hdpi/ic_vol_type_speaker_dark.png b/packages/MediaComponents/res/drawable-hdpi/ic_vol_type_speaker_dark.png
deleted file mode 100755
index 723e455..0000000
--- a/packages/MediaComponents/res/drawable-hdpi/ic_vol_type_speaker_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-hdpi/ic_vol_type_speaker_group_dark.png b/packages/MediaComponents/res/drawable-hdpi/ic_vol_type_speaker_group_dark.png
deleted file mode 100755
index 40c25a3..0000000
--- a/packages/MediaComponents/res/drawable-hdpi/ic_vol_type_speaker_group_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-hdpi/ic_vol_type_speaker_group_light.png b/packages/MediaComponents/res/drawable-hdpi/ic_vol_type_speaker_group_light.png
deleted file mode 100755
index afdb9c1..0000000
--- a/packages/MediaComponents/res/drawable-hdpi/ic_vol_type_speaker_group_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-hdpi/ic_vol_type_speaker_light.png b/packages/MediaComponents/res/drawable-hdpi/ic_vol_type_speaker_light.png
deleted file mode 100755
index 846c109..0000000
--- a/packages/MediaComponents/res/drawable-hdpi/ic_vol_type_speaker_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-hdpi/ic_vol_type_tv_dark.png b/packages/MediaComponents/res/drawable-hdpi/ic_vol_type_tv_dark.png
deleted file mode 100755
index 33bf484..0000000
--- a/packages/MediaComponents/res/drawable-hdpi/ic_vol_type_tv_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-hdpi/ic_vol_type_tv_light.png b/packages/MediaComponents/res/drawable-hdpi/ic_vol_type_tv_light.png
deleted file mode 100755
index c911b5c..0000000
--- a/packages/MediaComponents/res/drawable-hdpi/ic_vol_type_tv_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-mdpi/ic_audiotrack_dark.png b/packages/MediaComponents/res/drawable-mdpi/ic_audiotrack_dark.png
deleted file mode 100644
index e94ed50..0000000
--- a/packages/MediaComponents/res/drawable-mdpi/ic_audiotrack_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-mdpi/ic_audiotrack_light.png b/packages/MediaComponents/res/drawable-mdpi/ic_audiotrack_light.png
deleted file mode 100644
index 2cf7e0c..0000000
--- a/packages/MediaComponents/res/drawable-mdpi/ic_audiotrack_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-mdpi/ic_dialog_close_dark.png b/packages/MediaComponents/res/drawable-mdpi/ic_dialog_close_dark.png
deleted file mode 100644
index 66558a8..0000000
--- a/packages/MediaComponents/res/drawable-mdpi/ic_dialog_close_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-mdpi/ic_dialog_close_light.png b/packages/MediaComponents/res/drawable-mdpi/ic_dialog_close_light.png
deleted file mode 100644
index 40a1a84..0000000
--- a/packages/MediaComponents/res/drawable-mdpi/ic_dialog_close_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-mdpi/ic_media_pause_dark.png b/packages/MediaComponents/res/drawable-mdpi/ic_media_pause_dark.png
deleted file mode 100644
index f49aed7..0000000
--- a/packages/MediaComponents/res/drawable-mdpi/ic_media_pause_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-mdpi/ic_media_pause_light.png b/packages/MediaComponents/res/drawable-mdpi/ic_media_pause_light.png
deleted file mode 100644
index 74068ea..0000000
--- a/packages/MediaComponents/res/drawable-mdpi/ic_media_pause_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-mdpi/ic_media_play_dark.png b/packages/MediaComponents/res/drawable-mdpi/ic_media_play_dark.png
deleted file mode 100644
index 9cc777c..0000000
--- a/packages/MediaComponents/res/drawable-mdpi/ic_media_play_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-mdpi/ic_media_play_light.png b/packages/MediaComponents/res/drawable-mdpi/ic_media_play_light.png
deleted file mode 100644
index f208795..0000000
--- a/packages/MediaComponents/res/drawable-mdpi/ic_media_play_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-mdpi/ic_media_stop_dark.png b/packages/MediaComponents/res/drawable-mdpi/ic_media_stop_dark.png
deleted file mode 100644
index 3ad2c9c..0000000
--- a/packages/MediaComponents/res/drawable-mdpi/ic_media_stop_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-mdpi/ic_media_stop_light.png b/packages/MediaComponents/res/drawable-mdpi/ic_media_stop_light.png
deleted file mode 100644
index b002ab7..0000000
--- a/packages/MediaComponents/res/drawable-mdpi/ic_media_stop_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-mdpi/ic_media_subtitle_disabled.png b/packages/MediaComponents/res/drawable-mdpi/ic_media_subtitle_disabled.png
deleted file mode 100644
index 0354f61..0000000
--- a/packages/MediaComponents/res/drawable-mdpi/ic_media_subtitle_disabled.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-mdpi/ic_media_subtitle_enabled.png b/packages/MediaComponents/res/drawable-mdpi/ic_media_subtitle_enabled.png
deleted file mode 100644
index 5f8febe..0000000
--- a/packages/MediaComponents/res/drawable-mdpi/ic_media_subtitle_enabled.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-mdpi/ic_mr_button_disabled_dark.png b/packages/MediaComponents/res/drawable-mdpi/ic_mr_button_disabled_dark.png
deleted file mode 100644
index 4446ea4..0000000
--- a/packages/MediaComponents/res/drawable-mdpi/ic_mr_button_disabled_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-mdpi/ic_mr_button_disabled_light.png b/packages/MediaComponents/res/drawable-mdpi/ic_mr_button_disabled_light.png
deleted file mode 100644
index 4d790c6..0000000
--- a/packages/MediaComponents/res/drawable-mdpi/ic_mr_button_disabled_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-mdpi/ic_mr_button_disconnected_dark.png b/packages/MediaComponents/res/drawable-mdpi/ic_mr_button_disconnected_dark.png
deleted file mode 100644
index c401dc0..0000000
--- a/packages/MediaComponents/res/drawable-mdpi/ic_mr_button_disconnected_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-mdpi/ic_mr_button_disconnected_light.png b/packages/MediaComponents/res/drawable-mdpi/ic_mr_button_disconnected_light.png
deleted file mode 100644
index e24d586..0000000
--- a/packages/MediaComponents/res/drawable-mdpi/ic_mr_button_disconnected_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-mdpi/ic_mr_button_grey.png b/packages/MediaComponents/res/drawable-mdpi/ic_mr_button_grey.png
deleted file mode 100644
index ccbb772..0000000
--- a/packages/MediaComponents/res/drawable-mdpi/ic_mr_button_grey.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-mdpi/ic_vol_type_speaker_dark.png b/packages/MediaComponents/res/drawable-mdpi/ic_vol_type_speaker_dark.png
deleted file mode 100755
index 7cc9845..0000000
--- a/packages/MediaComponents/res/drawable-mdpi/ic_vol_type_speaker_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-mdpi/ic_vol_type_speaker_group_dark.png b/packages/MediaComponents/res/drawable-mdpi/ic_vol_type_speaker_group_dark.png
deleted file mode 100755
index 22617e1..0000000
--- a/packages/MediaComponents/res/drawable-mdpi/ic_vol_type_speaker_group_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-mdpi/ic_vol_type_speaker_group_light.png b/packages/MediaComponents/res/drawable-mdpi/ic_vol_type_speaker_group_light.png
deleted file mode 100755
index cefef3c..0000000
--- a/packages/MediaComponents/res/drawable-mdpi/ic_vol_type_speaker_group_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-mdpi/ic_vol_type_speaker_light.png b/packages/MediaComponents/res/drawable-mdpi/ic_vol_type_speaker_light.png
deleted file mode 100755
index 9a0047c..0000000
--- a/packages/MediaComponents/res/drawable-mdpi/ic_vol_type_speaker_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-mdpi/ic_vol_type_tv_dark.png b/packages/MediaComponents/res/drawable-mdpi/ic_vol_type_tv_dark.png
deleted file mode 100755
index ca5d6a2..0000000
--- a/packages/MediaComponents/res/drawable-mdpi/ic_vol_type_tv_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-mdpi/ic_vol_type_tv_light.png b/packages/MediaComponents/res/drawable-mdpi/ic_vol_type_tv_light.png
deleted file mode 100755
index 8134310..0000000
--- a/packages/MediaComponents/res/drawable-mdpi/ic_vol_type_tv_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_audiotrack_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_audiotrack_dark.png
deleted file mode 100644
index b5c899f..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_audiotrack_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_audiotrack_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_audiotrack_light.png
deleted file mode 100644
index 4778e00..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_audiotrack_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_dialog_close_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_dialog_close_dark.png
deleted file mode 100644
index f992fc5..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_dialog_close_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_dialog_close_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_dialog_close_light.png
deleted file mode 100644
index d3884e6..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_dialog_close_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_media_pause_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_media_pause_dark.png
deleted file mode 100644
index 660ac65..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_media_pause_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_media_pause_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_media_pause_light.png
deleted file mode 100644
index 792104f..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_media_pause_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_media_play_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_media_play_dark.png
deleted file mode 100644
index be5c062..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_media_play_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_media_play_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_media_play_light.png
deleted file mode 100644
index d12d495..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_media_play_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_media_stop_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_media_stop_dark.png
deleted file mode 100644
index 5239336..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_media_stop_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_media_stop_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_media_stop_light.png
deleted file mode 100644
index 5bc5a6c..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_media_stop_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_00_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_00_dark.png
deleted file mode 100644
index f6dd214..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_00_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_00_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_00_light.png
deleted file mode 100644
index 6b7bdcd..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_00_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_01_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_01_dark.png
deleted file mode 100644
index c7fe576..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_01_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_01_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_01_light.png
deleted file mode 100644
index 0a5d6aa..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_01_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_02_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_02_dark.png
deleted file mode 100644
index 0aadfa3..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_02_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_02_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_02_light.png
deleted file mode 100644
index 125fe0b..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_02_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_03_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_03_dark.png
deleted file mode 100644
index 05c48a7..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_03_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_03_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_03_light.png
deleted file mode 100644
index 741e911..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_03_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_04_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_04_dark.png
deleted file mode 100644
index ae4218a..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_04_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_04_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_04_light.png
deleted file mode 100644
index 8b30fab..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_04_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_05_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_05_dark.png
deleted file mode 100644
index d7aa903..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_05_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_05_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_05_light.png
deleted file mode 100644
index f7e2f29..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_05_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_06_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_06_dark.png
deleted file mode 100644
index e7871e2..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_06_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_06_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_06_light.png
deleted file mode 100644
index 8c57f63..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_06_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_07_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_07_dark.png
deleted file mode 100644
index 0041b01..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_07_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_07_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_07_light.png
deleted file mode 100644
index 6dbb694..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_07_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_08_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_08_dark.png
deleted file mode 100644
index 08e1013..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_08_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_08_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_08_light.png
deleted file mode 100644
index 5c352c3..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_08_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_09_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_09_dark.png
deleted file mode 100644
index 70532e9f0..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_09_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_09_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_09_light.png
deleted file mode 100644
index 9c6ba30..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_09_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_10_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_10_dark.png
deleted file mode 100644
index 9ba3b5f..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_10_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_10_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_10_light.png
deleted file mode 100644
index bd4bb22..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_10_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_11_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_11_dark.png
deleted file mode 100644
index 2156127..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_11_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_11_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_11_light.png
deleted file mode 100644
index b417a9f..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_11_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_12_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_12_dark.png
deleted file mode 100644
index 9bf633e..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_12_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_12_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_12_light.png
deleted file mode 100644
index ba51811..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_12_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_13_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_13_dark.png
deleted file mode 100644
index 756a53c..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_13_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_13_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_13_light.png
deleted file mode 100644
index 4705dca..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_13_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_14_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_14_dark.png
deleted file mode 100644
index 50e4ea3..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_14_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_14_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_14_light.png
deleted file mode 100644
index bc6724f..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_14_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_15_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_15_dark.png
deleted file mode 100644
index 9e3b410..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_15_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_15_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_15_light.png
deleted file mode 100644
index 2f18abd..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_15_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_16_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_16_dark.png
deleted file mode 100644
index de81133..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_16_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_16_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_16_light.png
deleted file mode 100644
index b80b191..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_16_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_17_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_17_dark.png
deleted file mode 100644
index 48aba3d..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_17_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_17_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_17_light.png
deleted file mode 100644
index ca34d5b..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_17_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_18_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_18_dark.png
deleted file mode 100644
index e9957b3..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_18_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_18_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_18_light.png
deleted file mode 100644
index a5d384f..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_18_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_19_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_19_dark.png
deleted file mode 100644
index ddc6297..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_19_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_19_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_19_light.png
deleted file mode 100644
index 28ab684..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_19_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_20_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_20_dark.png
deleted file mode 100644
index 51e7f75..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_20_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_20_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_20_light.png
deleted file mode 100644
index 4aa3ca3..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_20_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_21_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_21_dark.png
deleted file mode 100644
index 9caecde..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_21_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_21_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_21_light.png
deleted file mode 100644
index 1b8d0b6..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_21_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_22_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_22_dark.png
deleted file mode 100644
index 400be3c..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_22_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_22_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_22_light.png
deleted file mode 100644
index c14f1bf..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_22_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_23_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_23_dark.png
deleted file mode 100644
index 4e18b46..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_23_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_23_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_23_light.png
deleted file mode 100644
index c4c2c00..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_23_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_24_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_24_dark.png
deleted file mode 100644
index 98fae44..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_24_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_24_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_24_light.png
deleted file mode 100644
index d64c289..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_24_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_25_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_25_dark.png
deleted file mode 100644
index 91f9327..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_25_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_25_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_25_light.png
deleted file mode 100644
index f5e1f69..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_25_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_26_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_26_dark.png
deleted file mode 100644
index 3e6fafd..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_26_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_26_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_26_light.png
deleted file mode 100644
index ae2bd87..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_26_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_27_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_27_dark.png
deleted file mode 100644
index f73a1f8..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_27_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_27_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_27_light.png
deleted file mode 100644
index 78c1069..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_27_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_28_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_28_dark.png
deleted file mode 100644
index 562b803..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_28_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_28_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_28_light.png
deleted file mode 100644
index ddfba02..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_28_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_29_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_29_dark.png
deleted file mode 100644
index 257f2d2..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_29_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_29_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_29_light.png
deleted file mode 100644
index 38f5478..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_29_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_30_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_30_dark.png
deleted file mode 100644
index f995af0..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_30_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_30_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_30_light.png
deleted file mode 100644
index c50b7f0..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connected_30_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_00_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_00_dark.png
deleted file mode 100644
index f6dd214..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_00_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_00_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_00_light.png
deleted file mode 100644
index 6b7bdcd..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_00_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_01_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_01_dark.png
deleted file mode 100644
index c7fe576..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_01_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_01_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_01_light.png
deleted file mode 100644
index 0a5d6aa..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_01_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_02_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_02_dark.png
deleted file mode 100644
index 0aadfa3..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_02_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_02_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_02_light.png
deleted file mode 100644
index 125fe0b..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_02_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_03_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_03_dark.png
deleted file mode 100644
index 05c48a7..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_03_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_03_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_03_light.png
deleted file mode 100644
index 741e911..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_03_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_04_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_04_dark.png
deleted file mode 100644
index ae4218a..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_04_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_04_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_04_light.png
deleted file mode 100644
index 8b30fab..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_04_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_05_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_05_dark.png
deleted file mode 100644
index d7aa903..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_05_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_05_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_05_light.png
deleted file mode 100644
index f7e2f29..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_05_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_06_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_06_dark.png
deleted file mode 100644
index e7871e2..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_06_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_06_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_06_light.png
deleted file mode 100644
index 8c57f63..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_06_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_07_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_07_dark.png
deleted file mode 100644
index 0041b01..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_07_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_07_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_07_light.png
deleted file mode 100644
index 6dbb694..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_07_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_08_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_08_dark.png
deleted file mode 100644
index 08e1013..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_08_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_08_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_08_light.png
deleted file mode 100644
index 5c352c3..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_08_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_09_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_09_dark.png
deleted file mode 100644
index 70532e9f0..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_09_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_09_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_09_light.png
deleted file mode 100644
index 9c6ba30..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_09_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_10_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_10_dark.png
deleted file mode 100644
index 9ba3b5f..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_10_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_10_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_10_light.png
deleted file mode 100644
index bd4bb22..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_10_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_11_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_11_dark.png
deleted file mode 100644
index f3570f4..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_11_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_11_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_11_light.png
deleted file mode 100644
index 65a403e..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_11_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_12_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_12_dark.png
deleted file mode 100644
index f644bfd..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_12_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_12_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_12_light.png
deleted file mode 100644
index c7d6048..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_12_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_13_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_13_dark.png
deleted file mode 100644
index 6e0d558..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_13_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_13_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_13_light.png
deleted file mode 100644
index f3bc48d..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_13_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_14_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_14_dark.png
deleted file mode 100644
index 14d8f8e..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_14_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_14_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_14_light.png
deleted file mode 100644
index 98b90e5..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_14_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_15_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_15_dark.png
deleted file mode 100644
index 83234a7..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_15_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_15_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_15_light.png
deleted file mode 100644
index 47d452f..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_15_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_16_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_16_dark.png
deleted file mode 100644
index b81cf5a..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_16_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_16_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_16_light.png
deleted file mode 100644
index 20d08b4..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_16_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_17_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_17_dark.png
deleted file mode 100644
index 6feb3f1..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_17_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_17_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_17_light.png
deleted file mode 100644
index e6ae8b3..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_17_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_18_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_18_dark.png
deleted file mode 100644
index 0b0fc08..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_18_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_18_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_18_light.png
deleted file mode 100644
index c2a16ac..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_18_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_19_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_19_dark.png
deleted file mode 100644
index a3598cc..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_19_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_19_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_19_light.png
deleted file mode 100644
index 846d16d..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_19_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_20_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_20_dark.png
deleted file mode 100644
index 2070455..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_20_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_20_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_20_light.png
deleted file mode 100644
index ae6db13..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_20_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_21_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_21_dark.png
deleted file mode 100644
index 7f3828a..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_21_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_21_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_21_light.png
deleted file mode 100644
index aaccc73..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_21_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_22_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_22_dark.png
deleted file mode 100644
index 5c8ced9..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_22_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_22_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_22_light.png
deleted file mode 100644
index ad01b9e..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_22_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_23_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_23_dark.png
deleted file mode 100644
index ce31dd3..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_23_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_23_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_23_light.png
deleted file mode 100644
index 9ef78e4..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_23_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_24_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_24_dark.png
deleted file mode 100644
index a7c2cdb..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_24_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_24_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_24_light.png
deleted file mode 100644
index e7c5bea..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_24_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_25_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_25_dark.png
deleted file mode 100644
index ecad0d4..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_25_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_25_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_25_light.png
deleted file mode 100644
index 5fa5923..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_25_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_26_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_26_dark.png
deleted file mode 100644
index f687e25..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_26_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_26_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_26_light.png
deleted file mode 100644
index 9c06db8..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_26_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_27_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_27_dark.png
deleted file mode 100644
index 90225ba..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_27_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_27_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_27_light.png
deleted file mode 100644
index 19697de..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_27_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_28_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_28_dark.png
deleted file mode 100644
index d37ec21..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_28_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_28_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_28_light.png
deleted file mode 100644
index 21840bf..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_28_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_29_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_29_dark.png
deleted file mode 100644
index 5445e3a..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_29_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_29_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_29_light.png
deleted file mode 100644
index 2337c65..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_29_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_30_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_30_dark.png
deleted file mode 100644
index f6dd214..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_30_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_30_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_30_light.png
deleted file mode 100644
index 6b7bdcd..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_connecting_30_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_disabled_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_disabled_dark.png
deleted file mode 100644
index c4dc132..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_disabled_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_disabled_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_disabled_light.png
deleted file mode 100644
index b14617c..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_disabled_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_disconnected_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_disconnected_dark.png
deleted file mode 100644
index bb30773..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_disconnected_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_disconnected_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_disconnected_light.png
deleted file mode 100644
index a05d7d7..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_disconnected_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_grey.png b/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_grey.png
deleted file mode 100644
index 2238d58..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_mr_button_grey.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_vol_type_speaker_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_vol_type_speaker_dark.png
deleted file mode 100755
index e40349d..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_vol_type_speaker_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_vol_type_speaker_group_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_vol_type_speaker_group_dark.png
deleted file mode 100755
index f67c463..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_vol_type_speaker_group_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_vol_type_speaker_group_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_vol_type_speaker_group_light.png
deleted file mode 100755
index 7fcebf5..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_vol_type_speaker_group_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_vol_type_speaker_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_vol_type_speaker_light.png
deleted file mode 100755
index ea32a7a..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_vol_type_speaker_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_vol_type_tv_dark.png b/packages/MediaComponents/res/drawable-xhdpi/ic_vol_type_tv_dark.png
deleted file mode 100755
index d62ca37..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_vol_type_tv_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xhdpi/ic_vol_type_tv_light.png b/packages/MediaComponents/res/drawable-xhdpi/ic_vol_type_tv_light.png
deleted file mode 100755
index 3131256..0000000
--- a/packages/MediaComponents/res/drawable-xhdpi/ic_vol_type_tv_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_audiotrack_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_audiotrack_dark.png
deleted file mode 100644
index f131e1b..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_audiotrack_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_audiotrack_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_audiotrack_light.png
deleted file mode 100644
index e5946a2..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_audiotrack_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_dialog_close_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_dialog_close_dark.png
deleted file mode 100644
index b85e87f..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_dialog_close_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_dialog_close_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_dialog_close_light.png
deleted file mode 100644
index 51b4401..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_dialog_close_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_media_pause_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_media_pause_dark.png
deleted file mode 100644
index 3ea7e03..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_media_pause_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_media_pause_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_media_pause_light.png
deleted file mode 100644
index dc63538..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_media_pause_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_media_play_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_media_play_dark.png
deleted file mode 100644
index 2745c3a..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_media_play_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_media_play_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_media_play_light.png
deleted file mode 100644
index eda3ba5..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_media_play_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_media_stop_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_media_stop_dark.png
deleted file mode 100644
index 035ca18..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_media_stop_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_media_stop_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_media_stop_light.png
deleted file mode 100644
index eac183d..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_media_stop_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_00_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_00_dark.png
deleted file mode 100644
index 0db679e..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_00_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_00_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_00_light.png
deleted file mode 100644
index 51c6051..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_00_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_01_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_01_dark.png
deleted file mode 100644
index c083914..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_01_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_01_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_01_light.png
deleted file mode 100644
index c3c3caf..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_01_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_02_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_02_dark.png
deleted file mode 100644
index fc444cf..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_02_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_02_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_02_light.png
deleted file mode 100644
index abd6377..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_02_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_03_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_03_dark.png
deleted file mode 100644
index 6dbd1da..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_03_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_03_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_03_light.png
deleted file mode 100644
index d2e7108..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_03_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_04_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_04_dark.png
deleted file mode 100644
index d9f596b..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_04_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_04_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_04_light.png
deleted file mode 100644
index 4f32e1a..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_04_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_05_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_05_dark.png
deleted file mode 100644
index c568e04..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_05_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_05_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_05_light.png
deleted file mode 100644
index ed20dd9..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_05_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_06_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_06_dark.png
deleted file mode 100644
index bbe39e7..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_06_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_06_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_06_light.png
deleted file mode 100644
index 1edc15f..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_06_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_07_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_07_dark.png
deleted file mode 100644
index 78aebaf..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_07_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_07_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_07_light.png
deleted file mode 100644
index b5a6a4f..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_07_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_08_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_08_dark.png
deleted file mode 100644
index 44b91ce..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_08_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_08_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_08_light.png
deleted file mode 100644
index 85f66f9..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_08_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_09_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_09_dark.png
deleted file mode 100644
index 51ea34b..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_09_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_09_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_09_light.png
deleted file mode 100644
index 952de04..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_09_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_10_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_10_dark.png
deleted file mode 100644
index 8b1aa21..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_10_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_10_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_10_light.png
deleted file mode 100644
index 534bcc0..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_10_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_11_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_11_dark.png
deleted file mode 100644
index f666b35..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_11_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_11_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_11_light.png
deleted file mode 100644
index 145a8fb..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_11_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_12_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_12_dark.png
deleted file mode 100644
index edeb132..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_12_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_12_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_12_light.png
deleted file mode 100644
index 9da2b60..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_12_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_13_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_13_dark.png
deleted file mode 100644
index ab80aa9..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_13_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_13_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_13_light.png
deleted file mode 100644
index 115efe4..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_13_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_14_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_14_dark.png
deleted file mode 100644
index 8c0cc31..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_14_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_14_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_14_light.png
deleted file mode 100644
index e6ae6fc..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_14_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_15_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_15_dark.png
deleted file mode 100644
index b8816c9..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_15_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_15_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_15_light.png
deleted file mode 100644
index bd42931..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_15_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_16_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_16_dark.png
deleted file mode 100644
index 10d5b7f..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_16_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_16_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_16_light.png
deleted file mode 100644
index 303a0fe..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_16_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_17_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_17_dark.png
deleted file mode 100644
index 3c2a655..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_17_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_17_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_17_light.png
deleted file mode 100644
index 90debc2..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_17_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_18_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_18_dark.png
deleted file mode 100644
index d3e78a7..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_18_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_18_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_18_light.png
deleted file mode 100644
index 3a3f991..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_18_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_19_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_19_dark.png
deleted file mode 100644
index 63fad9e..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_19_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_19_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_19_light.png
deleted file mode 100644
index d6dd8d4..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_19_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_20_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_20_dark.png
deleted file mode 100644
index 890fd5f..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_20_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_20_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_20_light.png
deleted file mode 100644
index 6b0b5c1..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_20_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_21_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_21_dark.png
deleted file mode 100644
index 9ce1ef1..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_21_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_21_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_21_light.png
deleted file mode 100644
index 81710d4..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_21_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_22_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_22_dark.png
deleted file mode 100644
index 861c080..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_22_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_22_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_22_light.png
deleted file mode 100644
index 1c4aa21..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_22_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_23_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_23_dark.png
deleted file mode 100644
index 59a6b30..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_23_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_23_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_23_light.png
deleted file mode 100644
index c6e8fe0..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_23_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_24_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_24_dark.png
deleted file mode 100644
index 57b840e..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_24_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_24_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_24_light.png
deleted file mode 100644
index bf24050..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_24_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_25_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_25_dark.png
deleted file mode 100644
index 01c18c1..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_25_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_25_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_25_light.png
deleted file mode 100644
index be9753e..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_25_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_26_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_26_dark.png
deleted file mode 100644
index 3f291b1..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_26_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_26_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_26_light.png
deleted file mode 100644
index dc1c619..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_26_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_27_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_27_dark.png
deleted file mode 100644
index 6504a70..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_27_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_27_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_27_light.png
deleted file mode 100644
index a7e0a60..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_27_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_28_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_28_dark.png
deleted file mode 100644
index 57b1f3e..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_28_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_28_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_28_light.png
deleted file mode 100644
index 5c551ec..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_28_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_29_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_29_dark.png
deleted file mode 100644
index 238667e..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_29_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_29_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_29_light.png
deleted file mode 100644
index ffb8183..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_29_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_30_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_30_dark.png
deleted file mode 100644
index 4893f18..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_30_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_30_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_30_light.png
deleted file mode 100644
index ac5e156..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connected_30_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_00_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_00_dark.png
deleted file mode 100644
index 0db679e..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_00_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_00_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_00_light.png
deleted file mode 100644
index 51c6051..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_00_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_01_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_01_dark.png
deleted file mode 100644
index c083914..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_01_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_01_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_01_light.png
deleted file mode 100644
index c3c3caf..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_01_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_02_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_02_dark.png
deleted file mode 100644
index fc444cf..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_02_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_02_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_02_light.png
deleted file mode 100644
index abd6377..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_02_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_03_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_03_dark.png
deleted file mode 100644
index 6dbd1da..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_03_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_03_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_03_light.png
deleted file mode 100644
index d2e7108..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_03_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_04_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_04_dark.png
deleted file mode 100644
index d9f596b..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_04_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_04_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_04_light.png
deleted file mode 100644
index 4f32e1a..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_04_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_05_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_05_dark.png
deleted file mode 100644
index c568e04..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_05_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_05_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_05_light.png
deleted file mode 100644
index ed20dd9..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_05_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_06_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_06_dark.png
deleted file mode 100644
index bbe39e7..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_06_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_06_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_06_light.png
deleted file mode 100644
index 1edc15f..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_06_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_07_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_07_dark.png
deleted file mode 100644
index 78aebaf..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_07_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_07_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_07_light.png
deleted file mode 100644
index b5a6a4f..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_07_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_08_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_08_dark.png
deleted file mode 100644
index 44b91ce..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_08_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_08_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_08_light.png
deleted file mode 100644
index 85f66f9..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_08_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_09_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_09_dark.png
deleted file mode 100644
index 51ea34b..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_09_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_09_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_09_light.png
deleted file mode 100644
index 952de04..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_09_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_10_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_10_dark.png
deleted file mode 100644
index 8b1aa21..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_10_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_10_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_10_light.png
deleted file mode 100644
index 534bcc0..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_10_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_11_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_11_dark.png
deleted file mode 100644
index 1fffa01..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_11_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_11_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_11_light.png
deleted file mode 100644
index 0ff7e57..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_11_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_12_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_12_dark.png
deleted file mode 100644
index 06ac4dc..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_12_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_12_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_12_light.png
deleted file mode 100644
index 42a86f5..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_12_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_13_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_13_dark.png
deleted file mode 100644
index 0301090..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_13_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_13_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_13_light.png
deleted file mode 100644
index 4396f0e..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_13_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_14_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_14_dark.png
deleted file mode 100644
index e19001b..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_14_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_14_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_14_light.png
deleted file mode 100644
index 2271581..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_14_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_15_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_15_dark.png
deleted file mode 100644
index 5e96208..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_15_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_15_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_15_light.png
deleted file mode 100644
index 0f69500..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_15_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_16_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_16_dark.png
deleted file mode 100644
index 07e1bd6..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_16_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_16_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_16_light.png
deleted file mode 100644
index cde8f19..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_16_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_17_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_17_dark.png
deleted file mode 100644
index b632e95..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_17_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_17_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_17_light.png
deleted file mode 100644
index 11d5d2e..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_17_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_18_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_18_dark.png
deleted file mode 100644
index 660d527..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_18_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_18_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_18_light.png
deleted file mode 100644
index 2761ae1..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_18_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_19_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_19_dark.png
deleted file mode 100644
index 0aa3f84..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_19_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_19_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_19_light.png
deleted file mode 100644
index 27d166f..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_19_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_20_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_20_dark.png
deleted file mode 100644
index ebe527e..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_20_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_20_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_20_light.png
deleted file mode 100644
index aeb2a8e..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_20_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_21_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_21_dark.png
deleted file mode 100644
index 7337af5..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_21_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_21_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_21_light.png
deleted file mode 100644
index f3f31ef..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_21_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_22_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_22_dark.png
deleted file mode 100644
index 20d9f57..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_22_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_22_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_22_light.png
deleted file mode 100644
index bf8eb77..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_22_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_23_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_23_dark.png
deleted file mode 100644
index 56a0e14..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_23_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_23_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_23_light.png
deleted file mode 100644
index 67425e1..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_23_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_24_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_24_dark.png
deleted file mode 100644
index 7c76e19..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_24_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_24_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_24_light.png
deleted file mode 100644
index e02f1ed..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_24_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_25_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_25_dark.png
deleted file mode 100644
index f5fdcdd..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_25_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_25_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_25_light.png
deleted file mode 100644
index 8ce9b819..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_25_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_26_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_26_dark.png
deleted file mode 100644
index a29e443..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_26_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_26_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_26_light.png
deleted file mode 100644
index 349ca89..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_26_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_27_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_27_dark.png
deleted file mode 100644
index 0fc75d5..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_27_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_27_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_27_light.png
deleted file mode 100644
index 5cbd27c..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_27_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_28_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_28_dark.png
deleted file mode 100644
index 0ebb0ac..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_28_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_28_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_28_light.png
deleted file mode 100644
index 5b514aa..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_28_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_29_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_29_dark.png
deleted file mode 100644
index 8e7fe5c..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_29_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_29_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_29_light.png
deleted file mode 100644
index efb2c10..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_29_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_30_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_30_dark.png
deleted file mode 100644
index 0db679e..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_30_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_30_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_30_light.png
deleted file mode 100644
index 51c6051..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_connecting_30_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_disabled_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_disabled_dark.png
deleted file mode 100644
index fdb2121..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_disabled_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_disabled_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_disabled_light.png
deleted file mode 100644
index 9ce7e3a..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_disabled_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_disconnected_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_disconnected_dark.png
deleted file mode 100644
index e8601ce..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_disconnected_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_disconnected_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_disconnected_light.png
deleted file mode 100644
index 34928d7..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_disconnected_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_grey.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_grey.png
deleted file mode 100644
index 792fd77..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_mr_button_grey.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_vol_type_speaker_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_vol_type_speaker_dark.png
deleted file mode 100755
index f171a8c..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_vol_type_speaker_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_vol_type_speaker_group_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_vol_type_speaker_group_dark.png
deleted file mode 100755
index c8cb6ca..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_vol_type_speaker_group_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_vol_type_speaker_group_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_vol_type_speaker_group_light.png
deleted file mode 100755
index 9c8863d..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_vol_type_speaker_group_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_vol_type_speaker_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_vol_type_speaker_light.png
deleted file mode 100755
index 9335038..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_vol_type_speaker_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_vol_type_tv_dark.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_vol_type_tv_dark.png
deleted file mode 100755
index a6a4858..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_vol_type_tv_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxhdpi/ic_vol_type_tv_light.png b/packages/MediaComponents/res/drawable-xxhdpi/ic_vol_type_tv_light.png
deleted file mode 100755
index 4ca6787..0000000
--- a/packages/MediaComponents/res/drawable-xxhdpi/ic_vol_type_tv_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_00.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_00.png
deleted file mode 100644
index b2305d2..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_00.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_01.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_01.png
deleted file mode 100644
index 59395d4..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_01.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_02.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_02.png
deleted file mode 100644
index 70a7282..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_02.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_03.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_03.png
deleted file mode 100644
index b3f0f53..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_03.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_04.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_04.png
deleted file mode 100644
index 66a80d9..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_04.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_05.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_05.png
deleted file mode 100644
index 8ec3939..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_05.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_06.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_06.png
deleted file mode 100644
index 0f02536..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_06.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_07.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_07.png
deleted file mode 100644
index ba228f4..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_07.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_08.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_08.png
deleted file mode 100644
index 304277e..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_08.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_09.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_09.png
deleted file mode 100644
index f865bfb..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_09.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_10.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_10.png
deleted file mode 100644
index 17c5d6b..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_10.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_11.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_11.png
deleted file mode 100644
index a2f4ad5..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_11.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_12.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_12.png
deleted file mode 100644
index c230648..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_12.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_13.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_13.png
deleted file mode 100644
index b99324e..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_13.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_14.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_14.png
deleted file mode 100644
index c8618f0..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_14.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_15.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_15.png
deleted file mode 100644
index 4a0d770..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_collapse_15.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_00.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_00.png
deleted file mode 100644
index 4a0d770..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_00.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_01.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_01.png
deleted file mode 100644
index 4db4e50..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_01.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_02.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_02.png
deleted file mode 100644
index 82b5f03..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_02.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_03.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_03.png
deleted file mode 100644
index b05c758..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_03.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_04.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_04.png
deleted file mode 100644
index fa5c7fa..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_04.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_05.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_05.png
deleted file mode 100644
index 2c287e47..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_05.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_06.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_06.png
deleted file mode 100644
index eb7d0cf..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_06.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_07.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_07.png
deleted file mode 100644
index 95fa72b..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_07.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_08.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_08.png
deleted file mode 100644
index 5650eea..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_08.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_09.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_09.png
deleted file mode 100644
index 6f44355..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_09.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_10.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_10.png
deleted file mode 100644
index 4e877c3..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_10.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_11.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_11.png
deleted file mode 100644
index 7927f0a..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_11.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_12.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_12.png
deleted file mode 100644
index 71b19bb..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_12.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_13.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_13.png
deleted file mode 100644
index bf5921e..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_13.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_14.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_14.png
deleted file mode 100644
index 14b76b1..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_14.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_15.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_15.png
deleted file mode 100644
index b2305d2..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_group_expand_15.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable-xxxhdpi/ic_mr_button_grey.png b/packages/MediaComponents/res/drawable-xxxhdpi/ic_mr_button_grey.png
deleted file mode 100644
index 04a9525..0000000
--- a/packages/MediaComponents/res/drawable-xxxhdpi/ic_mr_button_grey.png
+++ /dev/null
Binary files differ
diff --git a/packages/MediaComponents/res/drawable/custom_progress.xml b/packages/MediaComponents/res/drawable/custom_progress.xml
deleted file mode 100644
index 9731a6e..0000000
--- a/packages/MediaComponents/res/drawable/custom_progress.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
-    <item android:id="@android:id/background">
-        <shape android:shape="rectangle" >
-            <solid android:color="#26000000" />
-        </shape>
-    </item>
-    <item android:id="@android:id/secondaryProgress">
-        <clip>
-            <shape android:shape="rectangle" >
-                <solid android:color="#5Cffffff" />
-            </shape>
-        </clip>
-    </item>
-    <item android:id="@android:id/progress">
-        <clip>
-            <shape android:shape="rectangle" >
-                <solid android:color="#ffffff" />
-            </shape>
-        </clip>
-    </item>
-</layer-list>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/drawable/custom_progress_thumb.xml b/packages/MediaComponents/res/drawable/custom_progress_thumb.xml
deleted file mode 100644
index 1a35970..0000000
--- a/packages/MediaComponents/res/drawable/custom_progress_thumb.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="oval" >
-    <solid android:color="#ffffff" />
-    <size
-        android:height="@dimen/mcv2_custom_progress_thumb_size"
-        android:width="@dimen/mcv2_custom_progress_thumb_size" />
-</shape>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/drawable/ic_arrow_back.xml b/packages/MediaComponents/res/drawable/ic_arrow_back.xml
deleted file mode 100644
index 2b5f71e..0000000
--- a/packages/MediaComponents/res/drawable/ic_arrow_back.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"
-        android:fillColor="#FFFFFF"/>
-</vector>
diff --git a/packages/MediaComponents/res/drawable/ic_aspect_ratio.xml b/packages/MediaComponents/res/drawable/ic_aspect_ratio.xml
deleted file mode 100644
index c6228e6..0000000
--- a/packages/MediaComponents/res/drawable/ic_aspect_ratio.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M19,12h-2v3h-3v2h5v-5zM7,9h3L10,7L5,7v5h2L7,9zM21,3L3,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2zM21,19.01L3,19.01L3,4.99h18v14.02z"
-        android:fillColor="#FFFFFF"/>
-</vector>
diff --git a/packages/MediaComponents/res/drawable/ic_audiotrack.xml b/packages/MediaComponents/res/drawable/ic_audiotrack.xml
deleted file mode 100644
index 27c12b5..0000000
--- a/packages/MediaComponents/res/drawable/ic_audiotrack.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24.0"
-    android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12,3v9.28c-0.47,-0.17 -0.97,-0.28 -1.5,-0.28C8.01,12 6,14.01 6,16.5S8.01,21 10.5,21c2.31,0 4.2,-1.75 4.45,-4H15V6h4V3h-7z"/>
-</vector>
diff --git a/packages/MediaComponents/res/drawable/ic_check.xml b/packages/MediaComponents/res/drawable/ic_check.xml
deleted file mode 100644
index 32f720b..0000000
--- a/packages/MediaComponents/res/drawable/ic_check.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M0 0h24v24H0z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z" />
-</vector>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/drawable/ic_chevron_left.xml b/packages/MediaComponents/res/drawable/ic_chevron_left.xml
deleted file mode 100644
index 8336d17..0000000
--- a/packages/MediaComponents/res/drawable/ic_chevron_left.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M15.41,7.41L14,6l-6,6 6,6 1.41,-1.41L10.83,12z"
-        android:fillColor="#FFFFFF"/>
-</vector>
diff --git a/packages/MediaComponents/res/drawable/ic_chevron_right.xml b/packages/MediaComponents/res/drawable/ic_chevron_right.xml
deleted file mode 100644
index fb2ce09..0000000
--- a/packages/MediaComponents/res/drawable/ic_chevron_right.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M10,6L8.59,7.41 13.17,12l-4.58,4.59L10,18l6,-6z"
-        android:fillColor="#FFFFFF"/>
-</vector>
diff --git a/packages/MediaComponents/res/drawable/ic_default_album_image.xml b/packages/MediaComponents/res/drawable/ic_default_album_image.xml
deleted file mode 100644
index 1cee643..0000000
--- a/packages/MediaComponents/res/drawable/ic_default_album_image.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="512dp"
-    android:height="512dp"
-    android:viewportWidth="512"
-    android:viewportHeight="512">
-
-    <path
-        android:fillColor="#616161"
-        android:pathData="M 0 0 H 512 V 512 H 0 V 0 Z" />
-    <path
-        android:fillColor="#525252"
-        android:pathData="M256,151v123.14c-6.88-4.02-14.82-6.48-23.33-6.48 c-25.78,0-46.67,20.88-46.67,46.67c0,25.78,20.88,46.67,46.67,46.67s46.67-20.88,46.67-46.67V197.67H326V151H256z" />
-</vector>
diff --git a/packages/MediaComponents/res/drawable/ic_forward_30.xml b/packages/MediaComponents/res/drawable/ic_forward_30.xml
deleted file mode 100644
index 7efdf16..0000000
--- a/packages/MediaComponents/res/drawable/ic_forward_30.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="40dp"
-        android:height="40dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <group>
-        <clip-path android:pathData="M24,24H0V0h24v24z M 0,0" />
-    <path
-        android:pathData="M9.6 13.5h.4c.2 0 .4,-.1.5,-.2s.2,-.2.2,-.4v-.2s-.1,-.1,-.1,-.2,-.1,-.1,-.2,-.1h-.5s-.1.1,-.2.1,-.1.1,-.1.2v.2h-1c0,-.2 0,-.3.1,-.5s.2,-.3.3,-.4.3,-.2.4,-.2.4,-.1.5,-.1c.2 0 .4 0 .6.1s.3.1.5.2.2.2.3.4.1.3.1.5v.3s-.1.2,-.1.3,-.1.2,-.2.2,-.2.1,-.3.2c.2.1.4.2.5.4s.2.4.2.6c0 .2 0 .4,-.1.5s-.2.3,-.3.4,-.3.2,-.5.2,-.4.1,-.6.1c-.2 0,-.4 0,-.5,-.1s-.3,-.1,-.5,-.2,-.2,-.2,-.3,-.4,-.1,-.4,-.1,-.6h.8v.2s.1.1.1.2.1.1.2.1h.5s.1,-.1.2,-.1.1,-.1.1,-.2v-.5s-.1,-.1,-.1,-.2,-.1,-.1,-.2,-.1h-.6v-.7zm5.7.7c0 .3 0 .6,-.1.8l-.3.6s-.3.3,-.5.3,-.4.1,-.6.1,-.4 0,-.6,-.1,-.3,-.2,-.5,-.3,-.2,-.3,-.3,-.6,-.1,-.5,-.1,-.8v-.7c0,-.3 0,-.6.1,-.8l.3,-.6s.3,-.3.5,-.3.4,-.1.6,-.1.4 0 .6.1.3.2.5.3.2.3.3.6.1.5.1.8v.7zm-.9,-.8v-.5s-.1,-.2,-.1,-.3,-.1,-.1,-.2,-.2,-.2,-.1,-.3,-.1,-.2 0,-.3.1l-.2.2s-.1.2,-.1.3v2s.1.2.1.3.1.1.2.2.2.1.3.1.2 0 .3,-.1l.2,-.2s.1,-.2.1,-.3v-1.5zM4 13c0 4.4 3.6 8 8 8s8,-3.6 8,-8h-2c0 3.3,-2.7 6,-6 6s-6,-2.7,-6,-6 2.7,-6 6,-6v4l5,-5,-5,-5v4c-4.4 0,-8 3.6,-8 8z"
-        android:fillColor="#FFFFFF"/>
-    </group>
-</vector>
diff --git a/packages/MediaComponents/res/drawable/ic_fullscreen.xml b/packages/MediaComponents/res/drawable/ic_fullscreen.xml
deleted file mode 100644
index 4b4f6bc..0000000
--- a/packages/MediaComponents/res/drawable/ic_fullscreen.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M7,14L5,14v5h5v-2L7,17v-3zM5,10h2L7,7h3L10,5L5,5v5zM17,17h-3v2h5v-5h-2v3zM14,5v2h3v3h2L19,5h-5z"
-        android:fillColor="#FFFFFF"/>
-</vector>
diff --git a/packages/MediaComponents/res/drawable/ic_fullscreen_exit.xml b/packages/MediaComponents/res/drawable/ic_fullscreen_exit.xml
deleted file mode 100644
index bc204e2..0000000
--- a/packages/MediaComponents/res/drawable/ic_fullscreen_exit.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M5,16h3v3h2v-5L5,14v2zM8,8L5,8v2h5L10,5L8,5v3zM14,19h2v-3h3v-2h-5v5zM16,8L16,5h-2v5h5L19,8h-3z"
-        android:fillColor="#FFFFFF"/>
-</vector>
diff --git a/packages/MediaComponents/res/drawable/ic_help.xml b/packages/MediaComponents/res/drawable/ic_help.xml
deleted file mode 100644
index 4d1d75d..0000000
--- a/packages/MediaComponents/res/drawable/ic_help.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M0 0h24v24H0z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1
-17h-2v-2h2v2zm2.07-7.75l-.9 .92 C13.45 12.9 13 13.5 13 15h-2v-.5c0-1.1 .45 -2.1
-1.17-2.83l1.24-1.26c.37-.36 .59 -.86 .59 -1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21
-1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z" />
-</vector>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/drawable/ic_high_quality.xml b/packages/MediaComponents/res/drawable/ic_high_quality.xml
deleted file mode 100644
index f76e22f..0000000
--- a/packages/MediaComponents/res/drawable/ic_high_quality.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="34dp"
-    android:height="34dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M0 0h24v24H0z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M19 4H5c-1.11 0-2 0.9-2 2v12c0 1.1 0.89 2 2 2h14c1.1 0 2-0.9 2-2V6c0-1.1-0.9-2-2-2zm-8 11H9.5v-2h-2v2H6V9h1.5v2.5h2V9H11v6zm7-1c0 0.55-0.45 1-1 1h-0.75v1.5h-1.5V15H14c-0.55 0-1-0.45-1-1v-4c0-0.55 0.45 -1 1-1h3c0.55 0 1 0.45 1 1v4zm-3.5-0.5h2v-3h-2v3z" />
-</vector>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/drawable/ic_launch.xml b/packages/MediaComponents/res/drawable/ic_launch.xml
deleted file mode 100644
index f7af6aa..0000000
--- a/packages/MediaComponents/res/drawable/ic_launch.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24.0"
-    android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M19,19H5V5h7V3H5c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2v-7h-2v7zM14,3v2h3.59l-9.83,9.83 1.41,1.41L19,6.41V10h2V3h-7z"/>
-</vector>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/drawable/ic_mute.xml b/packages/MediaComponents/res/drawable/ic_mute.xml
deleted file mode 100644
index 560aaec..0000000
--- a/packages/MediaComponents/res/drawable/ic_mute.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v2.21l2.45,2.45c0.03,-0.2 0.05,-0.41 0.05,-0.63zM19,12c0,0.94 -0.2,1.82 -0.54,2.64l1.51,1.51C20.63,14.91 21,13.5 21,12c0,-4.28 -2.99,-7.86 -7,-8.77v2.06c2.89,0.86 5,3.54 5,6.71zM4.27,3L3,4.27 7.73,9L3,9v6h4l5,5v-6.73l4.25,4.25c-0.67,0.52 -1.42,0.93 -2.25,1.18v2.06c1.38,-0.31 2.63,-0.95 3.69,-1.81L19.73,21 21,19.73l-9,-9L4.27,3zM12,4L9.91,6.09 12,8.18L12,4z"
-        android:fillColor="#FFFFFF"/>
-</vector>
diff --git a/packages/MediaComponents/res/drawable/ic_pause_circle_filled.xml b/packages/MediaComponents/res/drawable/ic_pause_circle_filled.xml
deleted file mode 100644
index 73be228..0000000
--- a/packages/MediaComponents/res/drawable/ic_pause_circle_filled.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="40dp"
-        android:height="40dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM11,16L9,16L9,8h2v8zM15,16h-2L13,8h2v8z"
-        android:fillColor="#FFFFFF"/>
-</vector>
diff --git a/packages/MediaComponents/res/drawable/ic_play_circle_filled.xml b/packages/MediaComponents/res/drawable/ic_play_circle_filled.xml
deleted file mode 100644
index 9d39def..0000000
--- a/packages/MediaComponents/res/drawable/ic_play_circle_filled.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="40dp"
-        android:height="40dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM10,16.5v-9l6,4.5 -6,4.5z"
-        android:fillColor="#FFFFFF"/>
-</vector>
diff --git a/packages/MediaComponents/res/drawable/ic_replay_circle_filled.xml b/packages/MediaComponents/res/drawable/ic_replay_circle_filled.xml
deleted file mode 100644
index a56d5d9..0000000
--- a/packages/MediaComponents/res/drawable/ic_replay_circle_filled.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="40dp"
-    android:height="40dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M0,0h24v24H0V0z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:fillType="evenOdd"
-        android:pathData="M12,2C6.48,2,2,6.48,2,12c0,5.52,4.48,10,10,10c5.52,0,10-4.48,10-10
-C22,6.48,17.52,2,12,2z
-M18,12c0,3.31-2.69,6-6,6c-3.31,0-6-2.69-6-6h2c0,2.21,1.79,4,4,4s4-1.79,4-4s-1.79-4-4-4v3L8,7l4-4v3
-C15.31,6,18,8.69,18,12z" />
-</vector>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/drawable/ic_rewind_10.xml b/packages/MediaComponents/res/drawable/ic_rewind_10.xml
deleted file mode 100644
index ae586b4..0000000
--- a/packages/MediaComponents/res/drawable/ic_rewind_10.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="40dp"
-        android:height="40dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <group>
-        <clip-path android:pathData="M0,0h24v24H0V0z M 0,0" />
-    <path
-        android:pathData="M12 5V1L7 6l5 5V7c3.3 0 6 2.7 6 6s-2.7 6,-6 6,-6,-2.7,-6,-6H4c0 4.4 3.6 8 8 8s8,-3.6 8,-8,-3.6,-8,-8,-8zm-1.1 11H10v-3.3L9 13v-.7l1.8,-.6h.1V16zm4.3,-1.8c0 .3 0 .6,-.1.8l-.3.6s-.3.3,-.5.3,-.4.1,-.6.1,-.4 0,-.6,-.1,-.3,-.2,-.5,-.3,-.2,-.3,-.3,-.6,-.1,-.5,-.1,-.8v-.7c0,-.3 0,-.6.1,-.8l.3,-.6s.3,-.3.5,-.3.4,-.1.6,-.1.4 0 .6.1c.2.1.3.2.5.3s.2.3.3.6.1.5.1.8v.7zm-.9,-.8v-.5s-.1,-.2,-.1,-.3,-.1,-.1,-.2,-.2,-.2,-.1,-.3,-.1,-.2 0,-.3.1l-.2.2s-.1.2,-.1.3v2s.1.2.1.3.1.1.2.2.2.1.3.1.2 0 .3,-.1l.2,-.2s.1,-.2.1,-.3v-1.5z"
-        android:fillColor="#FFFFFF"/>
-    </group>
-</vector>
diff --git a/packages/MediaComponents/res/drawable/ic_sd.xml b/packages/MediaComponents/res/drawable/ic_sd.xml
deleted file mode 100644
index decb6d2..0000000
--- a/packages/MediaComponents/res/drawable/ic_sd.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M0,0h24v24H0V0z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M19,3H5C3.89,3,3,3.9,3,5v14c0,1.1,0.89,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z
-M13,9h4c0.55,0,1,0.45,1,1v4 c0,0.55-0.45,1-1,1h-4V9z
-M9.5,13.5v-1H7c-0.55,0-1-0.45-1-1V10c0-0.55,0.45-1,1-1h3c0.55,0,1,0.45,1,1v1H9.5v-0.5h-2v1H10
-c0.55,0,1,0.45,1,1V14c0,0.55-0.45,1-1,1H7c-0.55,0-1-0.45-1-1v-1h1.5v0.5H9.5z
-M14.5,13.5h2v-3h-2V13.5z" />
-</vector>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/drawable/ic_settings.xml b/packages/MediaComponents/res/drawable/ic_settings.xml
deleted file mode 100644
index a59ecc1..0000000
--- a/packages/MediaComponents/res/drawable/ic_settings.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z"
-        android:fillColor="#FFFFFF"/>
-</vector>
diff --git a/packages/MediaComponents/res/drawable/ic_skip_next.xml b/packages/MediaComponents/res/drawable/ic_skip_next.xml
deleted file mode 100644
index b1f2812..0000000
--- a/packages/MediaComponents/res/drawable/ic_skip_next.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="40dp"
-        android:height="40dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M6,18l8.5,-6L6,6v12zM16,6v12h2V6h-2z"
-        android:fillColor="#FFFFFF"/>
-</vector>
diff --git a/packages/MediaComponents/res/drawable/ic_skip_previous.xml b/packages/MediaComponents/res/drawable/ic_skip_previous.xml
deleted file mode 100644
index 81da314..0000000
--- a/packages/MediaComponents/res/drawable/ic_skip_previous.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="40dp"
-        android:height="40dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M6,6h2v12L6,18zM9.5,12l8.5,6L18,6z"
-        android:fillColor="#FFFFFF"/>
-</vector>
diff --git a/packages/MediaComponents/res/drawable/ic_subtitle_off.xml b/packages/MediaComponents/res/drawable/ic_subtitle_off.xml
deleted file mode 100644
index c0a727a..0000000
--- a/packages/MediaComponents/res/drawable/ic_subtitle_off.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M0,0h24v24H0V0z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M19.5,5.5v13h-15v-13H19.5z M19,4H5C3.89,4,3,4.9,3,6v12c0,1.1,0.89,2,2,2h14c1.1,0,2-0.9,2-2V6C21,4.9,20.1,4,19,4L19,4z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M11,11H9.5v-0.5h-2v3h2V13H11v1c0,0.55-0.45,1-1,1H7c-0.55,0-1-0.45-1-1v-4c0-0.55,0.45-1,1-1h3c0.55,0,1,0.45,1,1V11z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M18,11h-1.5v-0.5h-2v3h2V13H18v1c0,0.55-0.45,1-1,1h-3c-0.55,0-1-0.45-1-1v-4c0-0.55,0.45-1,1-1h3c0.55,0,1,0.45,1,1V11z" />
-</vector>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/drawable/ic_subtitle_on.xml b/packages/MediaComponents/res/drawable/ic_subtitle_on.xml
deleted file mode 100644
index 7c91c06..0000000
--- a/packages/MediaComponents/res/drawable/ic_subtitle_on.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M0 0h24v24H0z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M19 4H5c-1.11 0-2 0.9-2 2v12c0 1.1 0.89 2 2 2h14c1.1 0 2-0.9 2-2V6c0-1.1-0.9-2-2-2zm-8 7H9.5v-0.5h-2v3h2V13H11v1c0 0.55-0.45 1-1 1H7c-0.55 0-1-0.45-1-1v-4c0-0.55 0.45 -1 1-1h3c0.55 0 1 0.45 1 1v1zm7 0h-1.5v-0.5h-2v3h2V13H18v1c0 0.55-0.45 1-1 1h-3c-0.55 0-1-0.45-1-1v-4c0-0.55 0.45 -1 1-1h3c0.55 0 1 0.45 1 1v1z" />
-</vector>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/drawable/ic_unmute.xml b/packages/MediaComponents/res/drawable/ic_unmute.xml
deleted file mode 100644
index 9dfb2b9..0000000
--- a/packages/MediaComponents/res/drawable/ic_unmute.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M3,9v6h4l5,5L12,4L7,9L3,9zM16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v8.05c1.48,-0.73 2.5,-2.25 2.5,-4.02zM14,3.23v2.06c2.89,0.86 5,3.54 5,6.71s-2.11,5.85 -5,6.71v2.06c4.01,-0.91 7,-4.49 7,-8.77s-2.99,-7.86 -7,-8.77z"
-        android:fillColor="#FFFFFF"/>
-</vector>
diff --git a/packages/MediaComponents/res/drawable/mr_button_connected_dark.xml b/packages/MediaComponents/res/drawable/mr_button_connected_dark.xml
deleted file mode 100644
index 110ff13..0000000
--- a/packages/MediaComponents/res/drawable/mr_button_connected_dark.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<animation-list
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:oneshot="true">
-    <item android:drawable="@drawable/ic_mr_button_connected_00_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_01_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_02_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_03_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_04_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_05_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_06_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_07_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_08_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_09_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_10_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_11_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_12_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_13_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_14_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_15_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_16_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_17_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_18_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_19_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_20_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_21_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_22_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_23_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_24_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_25_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_26_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_27_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_28_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_29_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_30_dark" android:duration="42" />
-</animation-list>
diff --git a/packages/MediaComponents/res/drawable/mr_button_connected_light.xml b/packages/MediaComponents/res/drawable/mr_button_connected_light.xml
deleted file mode 100644
index bcfc7fe..0000000
--- a/packages/MediaComponents/res/drawable/mr_button_connected_light.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<animation-list
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:oneshot="true">
-    <item android:drawable="@drawable/ic_mr_button_connected_00_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_01_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_02_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_03_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_04_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_05_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_06_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_07_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_08_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_09_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_10_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_11_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_12_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_13_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_14_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_15_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_16_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_17_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_18_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_19_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_20_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_21_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_22_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_23_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_24_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_25_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_26_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_27_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_28_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_29_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connected_30_light" android:duration="42" />
-</animation-list>
diff --git a/packages/MediaComponents/res/drawable/mr_button_connecting_dark.xml b/packages/MediaComponents/res/drawable/mr_button_connecting_dark.xml
deleted file mode 100644
index 55af7b3..0000000
--- a/packages/MediaComponents/res/drawable/mr_button_connecting_dark.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<animation-list
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:oneshot="false">
-    <item android:drawable="@drawable/ic_mr_button_connecting_00_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_01_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_02_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_03_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_04_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_05_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_06_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_07_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_08_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_09_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_10_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_11_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_12_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_13_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_14_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_15_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_16_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_17_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_18_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_19_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_20_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_21_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_22_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_23_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_24_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_25_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_26_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_27_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_28_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_29_dark" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_30_dark" android:duration="42" />
-</animation-list>
diff --git a/packages/MediaComponents/res/drawable/mr_button_connecting_light.xml b/packages/MediaComponents/res/drawable/mr_button_connecting_light.xml
deleted file mode 100644
index 93b4170..0000000
--- a/packages/MediaComponents/res/drawable/mr_button_connecting_light.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<animation-list
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:oneshot="false">
-    <item android:drawable="@drawable/ic_mr_button_connecting_00_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_01_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_02_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_03_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_04_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_05_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_06_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_07_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_08_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_09_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_10_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_11_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_12_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_13_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_14_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_15_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_16_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_17_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_18_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_19_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_20_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_21_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_22_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_23_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_24_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_25_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_26_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_27_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_28_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_29_light" android:duration="42" />
-    <item android:drawable="@drawable/ic_mr_button_connecting_30_light" android:duration="42" />
-</animation-list>
diff --git a/packages/MediaComponents/res/drawable/mr_button_dark.xml b/packages/MediaComponents/res/drawable/mr_button_dark.xml
deleted file mode 100644
index 8f1dfaa..0000000
--- a/packages/MediaComponents/res/drawable/mr_button_dark.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_checked="true" android:state_enabled="true"
-            android:drawable="@drawable/mr_button_connected_dark" />
-    <item android:state_checkable="true" android:state_enabled="true"
-            android:drawable="@drawable/mr_button_connecting_dark" />
-    <item android:state_enabled="true"
-            android:drawable="@drawable/ic_mr_button_disconnected_dark" />
-    <item android:drawable="@drawable/ic_mr_button_disabled_dark" />
-</selector>
diff --git a/packages/MediaComponents/res/drawable/mr_button_light.xml b/packages/MediaComponents/res/drawable/mr_button_light.xml
deleted file mode 100644
index 1d3d84e..0000000
--- a/packages/MediaComponents/res/drawable/mr_button_light.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_checked="true" android:state_enabled="true"
-            android:drawable="@drawable/mr_button_connected_light" />
-    <item android:state_checkable="true" android:state_enabled="true"
-            android:drawable="@drawable/mr_button_connecting_light" />
-    <item android:state_enabled="true"
-            android:drawable="@drawable/ic_mr_button_disconnected_light" />
-    <item android:drawable="@drawable/ic_mr_button_disabled_light" />
-</selector>
diff --git a/packages/MediaComponents/res/drawable/mr_dialog_close_dark.xml b/packages/MediaComponents/res/drawable/mr_dialog_close_dark.xml
deleted file mode 100644
index 288c8c7..0000000
--- a/packages/MediaComponents/res/drawable/mr_dialog_close_dark.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:drawable="@drawable/ic_dialog_close_dark" />
-</selector>
diff --git a/packages/MediaComponents/res/drawable/mr_dialog_close_light.xml b/packages/MediaComponents/res/drawable/mr_dialog_close_light.xml
deleted file mode 100644
index cd50e0f..0000000
--- a/packages/MediaComponents/res/drawable/mr_dialog_close_light.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item>
-        <bitmap
-            android:src="@drawable/ic_dialog_close_light"
-            android:alpha="0.87" />
-    </item>
-
-</selector>
diff --git a/packages/MediaComponents/res/drawable/mr_dialog_material_background_dark.xml b/packages/MediaComponents/res/drawable/mr_dialog_material_background_dark.xml
deleted file mode 100644
index ebc7eca..0000000
--- a/packages/MediaComponents/res/drawable/mr_dialog_material_background_dark.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<!-- This is the copy of @drawable/abc_dialog_material_background_dark except for inset
-     which includes unnecessary padding. -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-        android:shape="rectangle">
-    <corners android:radius="2dp" />
-    <solid android:color="@color/background_floating_material_dark" />
-</shape>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/drawable/mr_dialog_material_background_light.xml b/packages/MediaComponents/res/drawable/mr_dialog_material_background_light.xml
deleted file mode 100644
index c1b235a..0000000
--- a/packages/MediaComponents/res/drawable/mr_dialog_material_background_light.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<!-- This is the copy of @drawable/abc_dialog_material_background_light except for inset
-     which includes unnecessary padding. -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-        android:shape="rectangle">
-    <corners android:radius="2dp" />
-    <solid android:color="@color/background_floating_material_light" />
-</shape>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/drawable/mr_group_collapse.xml b/packages/MediaComponents/res/drawable/mr_group_collapse.xml
deleted file mode 100644
index 8f72bc8..0000000
--- a/packages/MediaComponents/res/drawable/mr_group_collapse.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
-        android:oneshot="true">
-    <item android:drawable="@drawable/ic_group_collapse_00" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_collapse_01" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_collapse_02" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_collapse_03" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_collapse_04" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_collapse_05" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_collapse_06" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_collapse_07" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_collapse_08" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_collapse_09" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_collapse_10" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_collapse_11" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_collapse_12" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_collapse_13" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_collapse_14" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_collapse_15" android:duration="13" />
-</animation-list>
diff --git a/packages/MediaComponents/res/drawable/mr_group_expand.xml b/packages/MediaComponents/res/drawable/mr_group_expand.xml
deleted file mode 100644
index 6b3fdb6..0000000
--- a/packages/MediaComponents/res/drawable/mr_group_expand.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
-        android:oneshot="true">
-    <item android:drawable="@drawable/ic_group_expand_00" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_expand_01" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_expand_02" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_expand_03" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_expand_04" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_expand_05" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_expand_06" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_expand_07" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_expand_08" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_expand_09" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_expand_10" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_expand_11" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_expand_12" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_expand_13" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_expand_14" android:duration="13" />
-    <item android:drawable="@drawable/ic_group_expand_15" android:duration="13" />
-</animation-list>
diff --git a/packages/MediaComponents/res/drawable/mr_media_pause_dark.xml b/packages/MediaComponents/res/drawable/mr_media_pause_dark.xml
deleted file mode 100644
index 86218a7..0000000
--- a/packages/MediaComponents/res/drawable/mr_media_pause_dark.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:drawable="@drawable/ic_media_pause_dark" />
-</selector>
diff --git a/packages/MediaComponents/res/drawable/mr_media_pause_light.xml b/packages/MediaComponents/res/drawable/mr_media_pause_light.xml
deleted file mode 100644
index 2dd1f02..0000000
--- a/packages/MediaComponents/res/drawable/mr_media_pause_light.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item>
-        <bitmap
-            android:src="@drawable/ic_media_pause_light"
-            android:alpha="0.87" />
-    </item>
-</selector>
diff --git a/packages/MediaComponents/res/drawable/mr_media_play_dark.xml b/packages/MediaComponents/res/drawable/mr_media_play_dark.xml
deleted file mode 100644
index 9d45a33..0000000
--- a/packages/MediaComponents/res/drawable/mr_media_play_dark.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:drawable="@drawable/ic_media_play_dark" />
-</selector>
diff --git a/packages/MediaComponents/res/drawable/mr_media_play_light.xml b/packages/MediaComponents/res/drawable/mr_media_play_light.xml
deleted file mode 100644
index f1fb7a6..0000000
--- a/packages/MediaComponents/res/drawable/mr_media_play_light.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item>
-        <bitmap
-            android:src="@drawable/ic_media_play_light"
-            android:alpha="0.87" />
-    </item>
-</selector>
diff --git a/packages/MediaComponents/res/drawable/mr_media_stop_dark.xml b/packages/MediaComponents/res/drawable/mr_media_stop_dark.xml
deleted file mode 100644
index 3e108a9..0000000
--- a/packages/MediaComponents/res/drawable/mr_media_stop_dark.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:drawable="@drawable/ic_media_stop_dark" />
-</selector>
diff --git a/packages/MediaComponents/res/drawable/mr_media_stop_light.xml b/packages/MediaComponents/res/drawable/mr_media_stop_light.xml
deleted file mode 100644
index b2c6ce8..0000000
--- a/packages/MediaComponents/res/drawable/mr_media_stop_light.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item>
-        <bitmap
-            android:src="@drawable/ic_media_stop_light"
-            android:alpha="0.87" />
-    </item>
-</selector>
diff --git a/packages/MediaComponents/res/drawable/mr_vol_type_audiotrack_dark.xml b/packages/MediaComponents/res/drawable/mr_vol_type_audiotrack_dark.xml
deleted file mode 100644
index 44f4fd6..0000000
--- a/packages/MediaComponents/res/drawable/mr_vol_type_audiotrack_dark.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:drawable="@drawable/ic_audiotrack_dark" />
-</selector>
diff --git a/packages/MediaComponents/res/drawable/mr_vol_type_audiotrack_light.xml b/packages/MediaComponents/res/drawable/mr_vol_type_audiotrack_light.xml
deleted file mode 100644
index 5c9dbc0..0000000
--- a/packages/MediaComponents/res/drawable/mr_vol_type_audiotrack_light.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item>
-        <bitmap
-            android:src="@drawable/ic_audiotrack_light"
-            android:alpha="0.87" />
-    </item>
-</selector>
diff --git a/packages/MediaComponents/res/interpolator/mr_fast_out_slow_in.xml b/packages/MediaComponents/res/interpolator/mr_fast_out_slow_in.xml
deleted file mode 100644
index 6b6a171..0000000
--- a/packages/MediaComponents/res/interpolator/mr_fast_out_slow_in.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2018 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:controlX1="0.4"
-    android:controlY1="0"
-    android:controlX2="0.2"
-    android:controlY2="1"/>
diff --git a/packages/MediaComponents/res/interpolator/mr_linear_out_slow_in.xml b/packages/MediaComponents/res/interpolator/mr_linear_out_slow_in.xml
deleted file mode 100644
index 20bf298..0000000
--- a/packages/MediaComponents/res/interpolator/mr_linear_out_slow_in.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2018 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:controlX1="0"
-    android:controlY1="0"
-    android:controlX2="0.2"
-    android:controlY2="1"/>
diff --git a/packages/MediaComponents/res/layout/embedded_music.xml b/packages/MediaComponents/res/layout/embedded_music.xml
deleted file mode 100644
index 3e4d365..0000000
--- a/packages/MediaComponents/res/layout/embedded_music.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
-
-    <View
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="0.25"/>
-
-    <ImageView
-        android:id="@+id/album"
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="0.5"
-        android:scaleType="fitCenter"
-        android:src="@drawable/ic_default_album_image" />
-
-    <View
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="0.25"/>
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/layout/embedded_settings_list_item.xml b/packages/MediaComponents/res/layout/embedded_settings_list_item.xml
deleted file mode 100644
index 1156dca..0000000
--- a/packages/MediaComponents/res/layout/embedded_settings_list_item.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="@dimen/mcv2_embedded_settings_height"
-    android:orientation="horizontal"
-    android:background="@color/black_opacity_70">
-
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="@dimen/mcv2_embedded_settings_height"
-        android:gravity="center"
-        android:orientation="horizontal">
-
-        <ImageView
-            android:id="@+id/icon"
-            android:layout_width="@dimen/mcv2_embedded_settings_icon_size"
-            android:layout_height="@dimen/mcv2_embedded_settings_icon_size"
-            android:layout_margin="8dp"
-            android:gravity="center" />
-    </LinearLayout>
-
-    <RelativeLayout
-        android:layout_width="wrap_content"
-        android:layout_height="@dimen/mcv2_embedded_settings_height"
-        android:gravity="center"
-        android:orientation="vertical">
-
-        <TextView
-            android:id="@+id/main_text"
-            android:layout_width="wrap_content"
-            android:layout_height="@dimen/mcv2_embedded_settings_text_height"
-            android:gravity="center"
-            android:paddingLeft="2dp"
-            android:textColor="@color/white"
-            android:textSize="@dimen/mcv2_embedded_settings_main_text_size"/>
-
-        <TextView
-            android:id="@+id/sub_text"
-            android:layout_width="wrap_content"
-            android:layout_height="@dimen/mcv2_embedded_settings_text_height"
-            android:layout_below="@id/main_text"
-            android:gravity="center"
-            android:paddingLeft="2dp"
-            android:textColor="@color/white_opacity_70"
-            android:textSize="@dimen/mcv2_embedded_settings_sub_text_size"/>
-    </RelativeLayout>
-</LinearLayout>
-
diff --git a/packages/MediaComponents/res/layout/embedded_sub_settings_list_item.xml b/packages/MediaComponents/res/layout/embedded_sub_settings_list_item.xml
deleted file mode 100644
index 5947a72..0000000
--- a/packages/MediaComponents/res/layout/embedded_sub_settings_list_item.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="@dimen/mcv2_embedded_settings_height"
-    android:orientation="horizontal"
-    android:background="@color/black_opacity_70">
-
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="@dimen/mcv2_embedded_settings_height"
-        android:gravity="center"
-        android:orientation="horizontal">
-
-        <ImageView
-            android:id="@+id/check"
-            android:layout_width="@dimen/mcv2_embedded_settings_icon_size"
-            android:layout_height="@dimen/mcv2_embedded_settings_icon_size"
-            android:layout_margin="8dp"
-            android:gravity="center"
-            android:src="@drawable/ic_check"/>
-    </LinearLayout>
-
-    <RelativeLayout
-        android:layout_width="wrap_content"
-        android:layout_height="@dimen/mcv2_embedded_settings_height"
-        android:gravity="center"
-        android:orientation="vertical">
-
-        <TextView
-            android:id="@+id/text"
-            android:layout_width="wrap_content"
-            android:layout_height="@dimen/mcv2_embedded_settings_text_height"
-            android:gravity="center"
-            android:paddingLeft="2dp"
-            android:textColor="@color/white"
-            android:textSize="@dimen/mcv2_embedded_settings_main_text_size"/>
-    </RelativeLayout>
-</LinearLayout>
diff --git a/packages/MediaComponents/res/layout/embedded_transport_controls.xml b/packages/MediaComponents/res/layout/embedded_transport_controls.xml
deleted file mode 100644
index a3a5957..0000000
--- a/packages/MediaComponents/res/layout/embedded_transport_controls.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:gravity="center"
-    android:orientation="horizontal"
-    android:paddingLeft="@dimen/mcv2_transport_controls_padding"
-    android:paddingRight="@dimen/mcv2_transport_controls_padding"
-    android:visibility="visible">
-
-    <ImageButton android:id="@+id/prev" style="@style/EmbeddedTransportControlsButton.Previous" />
-    <ImageButton android:id="@+id/rew" style="@style/EmbeddedTransportControlsButton.Rew" />
-    <ImageButton android:id="@+id/pause" style="@style/EmbeddedTransportControlsButton.Pause" />
-    <ImageButton android:id="@+id/ffwd" style="@style/EmbeddedTransportControlsButton.Ffwd" />
-    <ImageButton android:id="@+id/next" style="@style/EmbeddedTransportControlsButton.Next" />
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/layout/full_landscape_music.xml b/packages/MediaComponents/res/layout/full_landscape_music.xml
deleted file mode 100644
index 8ce7058..0000000
--- a/packages/MediaComponents/res/layout/full_landscape_music.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:background="#B300FF00"
-    android:orientation="horizontal">
-
-    <LinearLayout
-        android:id="@+id/music_image"
-        style="@style/FullMusicLandscape.Image">
-
-        <ImageView
-            android:id="@+id/album"
-            android:layout_width="@dimen/mcv2_full_album_image_landscape_size"
-            android:layout_height="@dimen/mcv2_full_album_image_landscape_size"
-            android:src="@drawable/ic_default_album_image"/>
-    </LinearLayout>
-
-    <LinearLayout
-        android:id="@+id/music_text"
-        style="@style/FullMusicLandscape.Text">
-
-        <TextView
-            android:id="@+id/title"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="@string/mcv2_music_title_unknown_text"
-            android:textSize="20sp"
-            android:textStyle="bold"
-            android:textColor="#FFFFFF" />
-        <TextView
-            android:id="@+id/artist"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="@string/mcv2_music_artist_unknown_text"
-            android:textSize="16sp"
-            android:textColor="#BBBBBB" />
-    </LinearLayout>
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/layout/full_portrait_music.xml b/packages/MediaComponents/res/layout/full_portrait_music.xml
deleted file mode 100644
index 75f1bb3..0000000
--- a/packages/MediaComponents/res/layout/full_portrait_music.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
-
-    <LinearLayout
-        android:id="@+id/music_image"
-        style="@style/FullMusicPortrait.Image">
-
-        <ImageView
-            android:id="@+id/album"
-            android:layout_width="@dimen/mcv2_full_album_image_portrait_size"
-            android:layout_height="@dimen/mcv2_full_album_image_portrait_size"
-            android:src="@drawable/ic_default_album_image"/>
-    </LinearLayout>
-
-    <LinearLayout
-        android:id="@+id/music_text"
-        style="@style/FullMusicPortrait.Text">
-
-        <TextView
-            android:id="@+id/title"
-            android:layout_width="@dimen/mcv2_full_album_image_portrait_size"
-            android:layout_height="wrap_content"
-            android:text="@string/mcv2_music_title_unknown_text"
-            android:textSize="20sp"
-            android:textStyle="bold"
-            android:textColor="#FFFFFF" />
-        <TextView
-            android:id="@+id/artist"
-            android:layout_width="@dimen/mcv2_full_album_image_portrait_size"
-            android:layout_height="wrap_content"
-            android:text="@string/mcv2_music_artist_unknown_text"
-            android:textSize="16sp"
-            android:textColor="#BBBBBB" />
-    </LinearLayout>
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/layout/full_settings_list_item.xml b/packages/MediaComponents/res/layout/full_settings_list_item.xml
deleted file mode 100644
index f92ea5e..0000000
--- a/packages/MediaComponents/res/layout/full_settings_list_item.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="@dimen/mcv2_full_settings_height"
-    android:orientation="horizontal"
-    android:background="@color/black_opacity_70">
-
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="@dimen/mcv2_full_settings_height"
-        android:gravity="center"
-        android:orientation="horizontal">
-
-        <ImageView
-            android:id="@+id/icon"
-            android:layout_width="@dimen/mcv2_full_settings_icon_size"
-            android:layout_height="@dimen/mcv2_full_settings_icon_size"
-            android:layout_margin="8dp"
-            android:gravity="center"/>
-    </LinearLayout>
-
-    <RelativeLayout
-        android:layout_width="wrap_content"
-        android:layout_height="@dimen/mcv2_full_settings_height"
-        android:gravity="center"
-        android:orientation="vertical">
-
-        <TextView
-            android:id="@+id/main_text"
-            android:layout_width="wrap_content"
-            android:layout_height="@dimen/mcv2_full_settings_text_height"
-            android:paddingLeft="2dp"
-            android:gravity="center"
-            android:textColor="@color/white"
-            android:textSize="@dimen/mcv2_full_settings_main_text_size"/>
-
-        <TextView
-            android:id="@+id/sub_text"
-            android:layout_width="wrap_content"
-            android:layout_height="@dimen/mcv2_full_settings_text_height"
-            android:layout_below="@id/main_text"
-            android:gravity="center"
-            android:paddingLeft="2dp"
-            android:textColor="@color/white_opacity_70"
-            android:textSize="@dimen/mcv2_full_settings_sub_text_size"/>
-    </RelativeLayout>
-</LinearLayout>
diff --git a/packages/MediaComponents/res/layout/full_sub_settings_list_item.xml b/packages/MediaComponents/res/layout/full_sub_settings_list_item.xml
deleted file mode 100644
index 49128d0..0000000
--- a/packages/MediaComponents/res/layout/full_sub_settings_list_item.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="@dimen/mcv2_full_settings_height"
-    android:orientation="horizontal"
-    android:background="@color/black_opacity_70">
-
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="@dimen/mcv2_full_settings_height"
-        android:gravity="center"
-        android:orientation="horizontal">
-
-        <ImageView
-            android:id="@+id/check"
-            android:layout_width="@dimen/mcv2_full_settings_icon_size"
-            android:layout_height="@dimen/mcv2_full_settings_icon_size"
-            android:layout_margin="8dp"
-            android:gravity="center"
-            android:src="@drawable/ic_check"/>
-    </LinearLayout>
-
-    <RelativeLayout
-        android:layout_width="wrap_content"
-        android:layout_height="@dimen/mcv2_full_settings_height"
-        android:gravity="center"
-        android:orientation="vertical">
-
-        <TextView
-            android:id="@+id/text"
-            android:layout_width="wrap_content"
-            android:layout_height="@dimen/mcv2_full_settings_text_height"
-            android:gravity="center"
-            android:paddingLeft="2dp"
-            android:textColor="@color/white"
-            android:textSize="@dimen/mcv2_full_settings_main_text_size"/>
-    </RelativeLayout>
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/layout/full_transport_controls.xml b/packages/MediaComponents/res/layout/full_transport_controls.xml
deleted file mode 100644
index 0914785..0000000
--- a/packages/MediaComponents/res/layout/full_transport_controls.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:gravity="center"
-    android:orientation="horizontal"
-    android:paddingLeft="@dimen/mcv2_transport_controls_padding"
-    android:paddingRight="@dimen/mcv2_transport_controls_padding"
-    android:visibility="visible">
-
-    <ImageButton android:id="@+id/prev" style="@style/FullTransportControlsButton.Previous" />
-    <ImageButton android:id="@+id/rew" style="@style/FullTransportControlsButton.Rew" />
-    <ImageButton android:id="@+id/pause" style="@style/FullTransportControlsButton.Pause" />
-    <ImageButton android:id="@+id/ffwd" style="@style/FullTransportControlsButton.Ffwd" />
-    <ImageButton android:id="@+id/next" style="@style/FullTransportControlsButton.Next" />
-</LinearLayout>
diff --git a/packages/MediaComponents/res/layout/media_controller.xml b/packages/MediaComponents/res/layout/media_controller.xml
deleted file mode 100644
index 4658f04..0000000
--- a/packages/MediaComponents/res/layout/media_controller.xml
+++ /dev/null
@@ -1,265 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical"
-    android:layoutDirection="ltr">
-
-    <RelativeLayout
-        android:id="@+id/title_bar"
-        android:background="@layout/title_bar_gradient"
-        style="@style/TitleBar">
-
-        <LinearLayout
-            android:id="@+id/title_bar_left"
-            android:gravity="center"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignParentLeft="true"
-            android:layout_centerVertical="true"
-            android:orientation="horizontal">
-
-            <ImageButton
-                android:id="@+id/back"
-                android:clickable="true"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_alignParentStart="true"
-                android:layout_centerVertical="true"
-                android:paddingLeft="5dip"
-                android:visibility="visible"
-                style="@style/TitleBarButton.Back"/>
-
-            <TextView
-                android:id="@+id/title_text"
-                android:ellipsize="end"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_toRightOf="@id/back"
-                android:layout_centerVertical="true"
-                android:maxLines="1"
-                android:paddingLeft="5dip"
-                android:paddingRight="5dip"
-                android:textSize="15sp"
-                android:textColor="#FFFFFFFF"/>
-        </LinearLayout>
-
-        <LinearLayout
-            android:id="@+id/title_bar_right"
-            android:gravity="center"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignParentRight="true"
-            android:layout_centerVertical="true"
-            android:orientation="horizontal">
-
-            <LinearLayout
-                android:id="@+id/ad_external_link"
-                android:clickable="true"
-                android:gravity="center"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_alignParentRight="true"
-                android:layout_centerVertical="true"
-                android:paddingLeft="5dip"
-                android:paddingRight="10dip"
-                android:orientation="horizontal"
-                android:visibility="gone">
-
-                <TextView
-                    android:id="@+id/ad_text"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_centerVertical="true"
-                    android:paddingRight="5dip"
-                    android:text="@string/MediaControlView2_ad_text"
-                    android:textSize="10sp"
-                    android:textColor="#FFFFFFFF" />
-
-                <ImageButton
-                    android:id="@+id/ad_launch"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_centerVertical="true"
-                    style="@style/TitleBarButton.Launch" />
-            </LinearLayout>
-
-            <view class="com.android.support.mediarouter.app.MediaRouteButton"
-                android:id="@+id/cast"
-                android:layout_centerVertical="true"
-                android:visibility="gone"
-                android:contentDescription="@string/mr_button_content_description"
-                style="@style/TitleBarButton" />
-        </LinearLayout>
-
-    </RelativeLayout>
-
-    <LinearLayout
-        android:id="@+id/center_view"
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1"
-        android:gravity="center"
-        android:orientation="vertical">
-    </LinearLayout>
-
-    <LinearLayout
-        android:id="@+id/minimal_extra_view"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:gravity="right">
-
-        <ImageButton
-            android:id="@+id/fullscreen"
-            android:gravity="right"
-            style="@style/BottomBarButton.FullScreen" />
-    </LinearLayout>
-
-    <RelativeLayout
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/mcv2_custom_progress_thumb_size">
-
-        <SeekBar
-            android:id="@+id/progress"
-            android:layout_width="match_parent"
-            android:layout_height="@dimen/mcv2_custom_progress_thumb_size"
-            android:contentDescription="@string/mcv2_seek_bar_desc"
-            android:padding="0dp"
-            android:maxHeight="@dimen/mcv2_custom_progress_max_size"
-            android:minHeight="@dimen/mcv2_custom_progress_max_size"
-            android:elevation="10dp"/>
-
-        <View
-            android:id="@+id/progress_buffer"
-            android:layout_width="match_parent"
-            android:layout_height="@dimen/mcv2_buffer_view_height"
-            android:layout_alignParentBottom="true"
-            android:background="@color/bottom_bar_background"
-            android:elevation="0dp"/>
-    </RelativeLayout>
-
-    <RelativeLayout
-        android:id="@+id/bottom_bar"
-        android:layout_width="match_parent"
-        android:layout_height="44dp"
-        android:orientation="horizontal"
-        android:background="@color/bottom_bar_background">
-
-        <LinearLayout
-            android:id="@+id/bottom_bar_left"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_alignParentStart="true"
-            android:layout_centerVertical="true">
-
-            <TextView
-                android:id="@+id/ad_skip_time"
-                android:gravity="center"
-                android:layout_width="wrap_content"
-                android:layout_height="match_parent"
-                android:layout_marginLeft="4dp"
-                android:textSize="12sp"
-                android:textColor="#FFFFFF"
-                android:visibility="gone" />
-        </LinearLayout>
-
-        <LinearLayout
-            android:id="@+id/time"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_toRightOf="@id/bottom_bar_left"
-            android:paddingLeft="10dp"
-            android:paddingRight="10dp"
-            android:gravity="center" >
-
-            <TextView
-                android:id="@+id/time_current"
-                style="@style/TimeText.Current"/>
-            <TextView
-                android:id="@+id/time_interpunct"
-                style="@style/TimeText.Interpunct"/>
-            <TextView
-                android:id="@+id/time_end"
-                style="@style/TimeText.End"/>
-        </LinearLayout>
-
-        <LinearLayout
-            android:id="@+id/bottom_bar_right"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignParentEnd="true"
-            android:gravity="right">
-
-            <LinearLayout
-                android:id="@+id/basic_controls"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:gravity="center_vertical"
-                android:orientation="horizontal" >
-
-                <TextView
-                    android:id="@+id/ad_remaining"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:gravity="center"
-                    android:textSize="12sp"
-                    android:textColor="#FFFFFF"
-                    android:visibility="gone" />
-
-                <ImageButton
-                    android:id="@+id/mute"
-                    style="@style/BottomBarButton.Mute" />
-                <ImageButton
-                    android:id="@+id/subtitle"
-                    android:scaleType="fitCenter"
-                    android:visibility="gone"
-                    style="@style/BottomBarButton.CC" />
-                <ImageButton
-                    android:id="@+id/fullscreen"
-                    style="@style/BottomBarButton.FullScreen"/>
-                <ImageButton
-                    android:id="@+id/overflow_right"
-                    style="@style/BottomBarButton.OverflowRight"/>
-            </LinearLayout>
-
-            <LinearLayout
-                android:id="@+id/extra_controls"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:visibility="gone"
-                android:orientation="horizontal"
-                android:gravity="center_vertical">
-
-                <LinearLayout
-                    android:id="@+id/custom_buttons"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content" />
-
-                <ImageButton
-                    android:id="@+id/video_quality"
-                    style="@style/BottomBarButton.VideoQuality" />
-                <ImageButton
-                    android:id="@+id/settings"
-                    style="@style/BottomBarButton.Settings" />
-                <ImageButton
-                    android:id="@+id/overflow_left"
-                    style="@style/BottomBarButton.OverflowLeft"/>
-            </LinearLayout>
-        </LinearLayout>
-    </RelativeLayout>
-</LinearLayout>
diff --git a/packages/MediaComponents/res/layout/minimal_transport_controls.xml b/packages/MediaComponents/res/layout/minimal_transport_controls.xml
deleted file mode 100644
index 800c80b..0000000
--- a/packages/MediaComponents/res/layout/minimal_transport_controls.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:gravity="center"
-    android:orientation="horizontal">
-
-    <ImageButton android:id="@+id/pause" style="@style/MinimalTransportControlsButton" />
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/layout/mr_chooser_dialog.xml b/packages/MediaComponents/res/layout/mr_chooser_dialog.xml
deleted file mode 100644
index ee89e16..0000000
--- a/packages/MediaComponents/res/layout/mr_chooser_dialog.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-             android:layout_width="fill_parent"
-             android:layout_height="wrap_content"
-             android:orientation="vertical">
-    <TextView android:id="@+id/mr_chooser_title"
-              android:layout_width="fill_parent"
-              android:layout_height="wrap_content"
-              android:paddingLeft="24dp"
-              android:paddingRight="24dp"
-              android:paddingTop="24dp"
-              android:text="@string/mr_chooser_title"
-              android:singleLine="true"
-              android:ellipsize="end"
-              android:textAppearance="@style/TextAppearance.MediaRouter.Title" />
-    <ListView android:id="@+id/mr_chooser_list"
-              android:layout_width="fill_parent"
-              android:layout_height="wrap_content"
-              android:divider="@android:color/transparent"
-              android:dividerHeight="0dp" />
-    <LinearLayout android:id="@android:id/empty"
-              android:layout_width="fill_parent"
-              android:layout_height="240dp"
-              android:orientation="vertical"
-              android:paddingTop="90dp"
-              android:paddingLeft="16dp"
-              android:paddingRight="16dp"
-              android:visibility="gone">
-        <TextView android:layout_width="wrap_content"
-                  android:layout_height="wrap_content"
-                  android:layout_gravity="center"
-                  android:text="@string/mr_chooser_searching"
-                  android:textAppearance="@style/TextAppearance.MediaRouter.SecondaryText" />
-        <ProgressBar android:layout_width="150dp"
-                     android:layout_height="wrap_content"
-                     android:layout_gravity="center"
-                     android:indeterminate="true"
-                     style="?android:attr/progressBarStyleHorizontal" />
-    </LinearLayout>
-</LinearLayout>
diff --git a/packages/MediaComponents/res/layout/mr_chooser_list_item.xml b/packages/MediaComponents/res/layout/mr_chooser_list_item.xml
deleted file mode 100644
index 958879b..0000000
--- a/packages/MediaComponents/res/layout/mr_chooser_list_item.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:layout_width="fill_parent"
-              android:layout_height="wrap_content"
-              android:minHeight="56dp"
-              android:paddingLeft="24dp"
-              android:paddingRight="24dp"
-              android:orientation="horizontal"
-              android:gravity="center_vertical" >
-
-    <ImageView android:id="@+id/mr_chooser_route_icon"
-               android:layout_width="24dp"
-               android:layout_height="24dp"
-               android:layout_marginRight="24dp" />
-
-    <LinearLayout android:layout_width="fill_parent"
-                  android:layout_height="wrap_content"
-                  android:layout_marginBottom="1dp"
-                  android:orientation="vertical" >
-
-        <TextView android:id="@+id/mr_chooser_route_name"
-                  android:layout_width="fill_parent"
-                  android:layout_height="32dp"
-                  android:singleLine="true"
-                  android:ellipsize="marquee"
-                  android:textAppearance="@style/TextAppearance.MediaRouter.PrimaryText" />
-
-        <TextView android:id="@+id/mr_chooser_route_desc"
-                  android:layout_width="fill_parent"
-                  android:layout_height="24dp"
-                  android:singleLine="true"
-                  android:ellipsize="marquee"
-                  android:textAppearance="@style/TextAppearance.MediaRouter.SecondaryText" />
-    </LinearLayout>
-
-</LinearLayout>
diff --git a/packages/MediaComponents/res/layout/mr_controller_material_dialog_b.xml b/packages/MediaComponents/res/layout/mr_controller_material_dialog_b.xml
deleted file mode 100644
index b304471..0000000
--- a/packages/MediaComponents/res/layout/mr_controller_material_dialog_b.xml
+++ /dev/null
@@ -1,206 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/mr_expandable_area"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent">
-    <LinearLayout android:id="@+id/mr_dialog_area"
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:orientation="vertical"
-        android:background="?android:attr/colorBackgroundFloating">
-        <LinearLayout android:id="@+id/mr_title_bar"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:paddingLeft="24dp"
-            android:paddingRight="12dp"
-            android:orientation="horizontal" >
-            <TextView android:id="@+id/mr_name"
-                android:layout_width="0dp"
-                android:layout_height="72dp"
-                android:layout_weight="1"
-                android:gravity="center_vertical"
-                android:singleLine="true"
-                android:ellipsize="end"
-                android:textAppearance="@style/TextAppearance.MediaRouter.Title" />
-            <ImageButton android:id="@+id/mr_close"
-                android:layout_width="48dp"
-                android:layout_height="48dp"
-                android:layout_gravity="center_vertical"
-                android:contentDescription="@string/mr_controller_close_description"
-                android:src="?attr/mediaRouteCloseDrawable"
-                android:background="?android:attr/selectableItemBackgroundBorderless" />
-        </LinearLayout>
-        <FrameLayout android:id="@+id/mr_custom_control"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:visibility="gone" />
-        <FrameLayout android:id="@+id/mr_default_control"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content">
-            <ImageView android:id="@+id/mr_art"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:adjustViewBounds="true"
-                android:scaleType="fitXY"
-                android:background="?android:attr/colorPrimary"
-                android:layout_gravity="top"
-                android:contentDescription="@string/mr_controller_album_art"
-                android:visibility="gone" />
-            <LinearLayout android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:orientation="vertical"
-                android:layout_gravity="bottom"
-                android:splitMotionEvents="false">
-                <LinearLayout android:id="@+id/mr_media_main_control"
-                    android:layout_width="fill_parent"
-                    android:layout_height="wrap_content"
-                    android:orientation="vertical"
-                    android:paddingTop="16dp"
-                    android:paddingBottom="16dp"
-                    android:layout_gravity="bottom"
-                    android:theme="?attr/mediaRouteControlPanelThemeOverlay">
-                    <RelativeLayout
-                        android:id="@+id/mr_playback_control"
-                        android:layout_width="fill_parent"
-                        android:layout_height="wrap_content"
-                        android:orientation="horizontal"
-                        android:paddingLeft="24dp"
-                        android:paddingRight="12dp" >
-                        <ImageButton android:id="@+id/mr_control_playback_ctrl"
-                            android:layout_width="wrap_content"
-                            android:layout_height="wrap_content"
-                            android:layout_marginLeft="12dp"
-                            android:layout_alignParentRight="true"
-                            android:layout_centerVertical="true"
-                            android:contentDescription="@string/mr_controller_play"
-                            android:background="?android:attr/selectableItemBackgroundBorderless"
-                            android:visibility="gone" />
-                        <LinearLayout android:id="@+id/mr_control_title_container"
-                            android:orientation="vertical"
-                            android:layout_width="wrap_content"
-                            android:layout_height="wrap_content"
-                            android:layout_toLeftOf="@id/mr_control_playback_ctrl"
-                            android:layout_alignParentLeft="true"
-                            android:layout_centerVertical="true">
-                            <TextView android:id="@+id/mr_control_title"
-                                android:layout_width="wrap_content"
-                                android:layout_height="wrap_content"
-                                android:textAppearance="@style/TextAppearance.MediaRouter.PrimaryText"
-                                android:singleLine="true" />
-                            <TextView android:id="@+id/mr_control_subtitle"
-                                android:layout_width="wrap_content"
-                                android:layout_height="wrap_content"
-                                android:textAppearance="@style/TextAppearance.MediaRouter.SecondaryText"
-                                android:singleLine="true" />
-                        </LinearLayout>
-                    </RelativeLayout>
-                    <View android:id="@+id/mr_control_divider"
-                        android:layout_width="fill_parent"
-                        android:layout_height="8dp"
-                        android:visibility="gone" />
-                    <LinearLayout
-                        android:id="@+id/mr_volume_control"
-                        android:layout_width="fill_parent"
-                        android:layout_height="wrap_content"
-                        android:minHeight="48dp"
-                        android:gravity="center_vertical"
-                        android:paddingLeft="24dp"
-                        android:paddingRight="12dp"
-                        android:splitMotionEvents="false">
-                        <ImageView
-                            android:layout_width="24dp"
-                            android:layout_height="24dp"
-                            android:src="?attr/mediaRouteAudioTrackDrawable"
-                            android:gravity="center"
-                            android:scaleType="center"/>
-                        <!-- Since dialog's top layout mr_expandable_area is clickable, it propagates pressed state
-                             to its non-clickable children. Specify android:clickable="true" to prevent volume slider
-                             from having false pressed state. -->
-                        <com.android.support.mediarouter.app.MediaRouteVolumeSlider
-                            android:id="@+id/mr_volume_slider"
-                            android:layout_width="0dp"
-                            android:layout_height="wrap_content"
-                            android:minHeight="48dp"
-                            android:maxHeight="48dp"
-                            android:layout_weight="1"
-                            android:clickable="true"
-                            android:contentDescription="@string/mr_controller_volume_slider" />
-                        <com.android.support.mediarouter.app.MediaRouteExpandCollapseButton
-                            android:id="@+id/mr_group_expand_collapse"
-                            android:layout_width="48dp"
-                            android:layout_height="48dp"
-                            android:padding="12dp"
-                            android:background="?android:attr/selectableItemBackgroundBorderless"
-                            android:visibility="gone"/>
-                    </LinearLayout>
-                </LinearLayout>
-                <com.android.support.mediarouter.app.OverlayListView
-                    android:id="@+id/mr_volume_group_list"
-                    android:layout_width="fill_parent"
-                    android:layout_height="wrap_content"
-                    android:paddingTop="@dimen/mr_controller_volume_group_list_padding_top"
-                    android:scrollbarStyle="outsideOverlay"
-                    android:clipToPadding="false"
-                    android:visibility="gone"
-                    android:splitMotionEvents="false"
-                    android:theme="?attr/mediaRouteControlPanelThemeOverlay" />
-            </LinearLayout>
-        </FrameLayout>
-        <ScrollView
-            android:id="@+id/buttonPanel"
-            style="?attr/buttonBarStyle"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:fillViewport="true"
-            android:scrollIndicators="top|bottom">
-            <android.support.v7.widget.ButtonBarLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:gravity="bottom"
-                android:layoutDirection="locale"
-                android:orientation="horizontal"
-                android:paddingBottom="4dp"
-                android:paddingLeft="12dp"
-                android:paddingRight="12dp"
-                android:paddingTop="4dp">
-                <Button
-                    android:id="@android:id/button3"
-                    style="?android:attr/buttonBarNeutralButtonStyle"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"/>
-                <android.support.v4.widget.Space
-                    android:id="@+id/spacer"
-                    android:layout_width="0dp"
-                    android:layout_height="0dp"
-                    android:layout_weight="1"
-                    android:visibility="invisible"/>
-                <Button
-                    android:id="@android:id/button2"
-                    style="?android:attr/buttonBarNegativeButtonStyle"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"/>
-                <Button
-                    android:id="@android:id/button1"
-                    style="?android:attr/buttonBarPositiveButtonStyle"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"/>
-            </android.support.v7.widget.ButtonBarLayout>
-        </ScrollView>
-    </LinearLayout>
-</FrameLayout>
diff --git a/packages/MediaComponents/res/layout/mr_controller_volume_item.xml b/packages/MediaComponents/res/layout/mr_controller_volume_item.xml
deleted file mode 100644
index a89058b..0000000
--- a/packages/MediaComponents/res/layout/mr_controller_volume_item.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:layout_width="fill_parent"
-              android:layout_height="wrap_content">
-    <LinearLayout android:id="@+id/volume_item_container"
-                  android:layout_width="fill_parent"
-                  android:layout_height="@dimen/mr_controller_volume_group_list_item_height"
-                  android:paddingLeft="24dp"
-                  android:paddingRight="60dp"
-                  android:paddingBottom="8dp"
-                  android:orientation="vertical" >
-        <TextView android:id="@+id/mr_name"
-                  android:layout_width="wrap_content"
-                  android:layout_height="wrap_content"
-                  android:textAppearance="@style/TextAppearance.MediaRouter.SecondaryText"
-                  android:singleLine="true" />
-        <LinearLayout android:layout_width="fill_parent"
-                      android:layout_height="wrap_content"
-                      android:orientation="horizontal"
-                      android:gravity="center_vertical">
-            <ImageView android:id="@+id/mr_volume_item_icon"
-                       android:layout_width="@dimen/mr_controller_volume_group_list_item_icon_size"
-                       android:layout_height="@dimen/mr_controller_volume_group_list_item_icon_size"
-                       android:layout_marginTop="8dp"
-                       android:layout_marginBottom="8dp"
-                       android:scaleType="fitCenter"
-                       android:src="?attr/mediaRouteAudioTrackDrawable" />
-            <android.support.v7.app.MediaRouteVolumeSlider
-                android:id="@+id/mr_volume_slider"
-                android:layout_width="fill_parent"
-                android:layout_height="40dp"
-                android:minHeight="40dp"
-                android:maxHeight="40dp"
-                android:contentDescription="@string/mr_controller_volume_slider" />
-        </LinearLayout>
-    </LinearLayout>
-</LinearLayout>
diff --git a/packages/MediaComponents/res/layout/settings_list.xml b/packages/MediaComponents/res/layout/settings_list.xml
deleted file mode 100644
index ea30538..0000000
--- a/packages/MediaComponents/res/layout/settings_list.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<ListView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="@dimen/mcv2_embedded_settings_width"
-    android:layout_height="@dimen/mcv2_embedded_settings_height"
-    android:divider="@null"
-    android:dividerHeight="0dp">
-</ListView>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/layout/title_bar_gradient.xml b/packages/MediaComponents/res/layout/title_bar_gradient.xml
deleted file mode 100644
index ab1fc6e..0000000
--- a/packages/MediaComponents/res/layout/title_bar_gradient.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-    <gradient
-        android:startColor="@color/title_bar_gradient_start"
-        android:endColor="@color/title_bar_gradient_end"
-        android:angle="-270" />
-</shape>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/values-af/strings.xml b/packages/MediaComponents/res/values-af/strings.xml
deleted file mode 100644
index 47230ad..0000000
--- a/packages/MediaComponents/res/values-af/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Stelsel"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Toestelle"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Cast-knoppie"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Uitsaai-knoppie. Ontkoppel"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Uitsaai-knoppie. Koppel tans"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Uitsaai-knoppie. Gekoppel"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Saai uit na"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Vind tans toestelle"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Ontkoppel"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Hou op uitsaai"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Maak toe"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Speel"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Laat wag"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Stop"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Vou uit"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Vou in"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Albumkunswerk"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Volumeglyer"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Geen media is gekies nie"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Geen inligting beskikbaar nie"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Saai tans skerm uit"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-am/strings.xml b/packages/MediaComponents/res/values-am/strings.xml
deleted file mode 100644
index 39a1903..0000000
--- a/packages/MediaComponents/res/values-am/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"ስርዓት"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"መሣሪያዎች"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"የCast አዝራር"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Cast አዝራር። ግንኙነት ተቋርጧል"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Cast አዝራር በማገናኘት ላይ"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Cast አዝራር። ተገናኝቷል"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Cast አድርግ ወደ"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"መሣሪያዎችን በማግኘት ላይ"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"ግንኙነት አቋርጥ"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Cast ማድረግ አቁም"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"ዝጋ"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"አጫውት"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"ለአፍታ አቁም"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"አቁም"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"አስፋ"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"ሰብስብ"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"የአልበም ስነ-ጥበብ"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"ተንሸራታች የድምፅ መቆጣጠሪያ"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"ምንም ማህደረመረጃ አልተመረጠም"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"ምንም መረጃ አይገኝም"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"ማያ ገጽን በመውሰድ ላይ"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-ar/strings.xml b/packages/MediaComponents/res/values-ar/strings.xml
deleted file mode 100644
index f8fb97d..0000000
--- a/packages/MediaComponents/res/values-ar/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"النظام"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"الأجهزة"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"زر الإرسال"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"زر الإرسال. تم قطع الاتصال"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"زر الإرسال. جارٍ الاتصال"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"زر الإرسال. تم الاتصال"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"إرسال إلى"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"جارٍ البحث عن أجهزة"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"قطع الاتصال"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"إيقاف الإرسال"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"إغلاق"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"تشغيل"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"إيقاف مؤقت"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"إيقاف"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"توسيع"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"تصغير"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"صورة الألبوم"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"شريط تمرير مستوى الصوت"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"لم يتم اختيار أي وسائط"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"لا تتوفر أي معلومات"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"جارٍ إرسال الشاشة"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-az/strings.xml b/packages/MediaComponents/res/values-az/strings.xml
deleted file mode 100644
index a3c60ab..0000000
--- a/packages/MediaComponents/res/values-az/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Sistem"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Cihazlar"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Yayım düyməsi"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Yayım düyməsi. Bağlantı kəsildi"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Yayım düyməsi. Qoşulur"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Yayım düyməsi. Qoşuldu"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Bura yayımlayın"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Cihazlar axtarılır"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Bağlantını kəsin"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Yayımı dayandırın"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Qapadın"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Oynadın"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Durdurun"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Dayandırın"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Genişləndirin"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Yığcamlaşdırın"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Albom incəsənəti"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Səs hərmi diyircəyi"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Heç bir media seçilməyib"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Əlçatan məlumat yoxdur"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Ekran yayımlanır"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-b+sr+Latn/strings.xml b/packages/MediaComponents/res/values-b+sr+Latn/strings.xml
deleted file mode 100644
index e25bd6e..0000000
--- a/packages/MediaComponents/res/values-b+sr+Latn/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Sistem"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Uređaji"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Dugme Prebaci"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Dugme Prebaci. Veza je prekinuta"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Dugme Prebaci. Povezuje se"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Dugme Prebaci. Povezan je"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Prebacuj na"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Pronalaženje uređaja"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Prekini vezu"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Zaustavi prebacivanje"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Zatvori"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Pusti"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Pauziraj"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Zaustavi"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Proširi"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Skupi"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Omot albuma"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Klizač za jačinu zvuka"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Nema izabranih medija"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Nisu dostupne nikakve informacije"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Prebacuje se ekran"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-be/strings.xml b/packages/MediaComponents/res/values-be/strings.xml
deleted file mode 100644
index ac391c1..0000000
--- a/packages/MediaComponents/res/values-be/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Сістэма"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Прылады"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Кнопка трансляцыі"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Кнопка трансляцыі. Адключана"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Кнопка трансляцыі. Ідзе падключэнне"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Кнопка трансляцыі. Падключана"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Трансліраваць на"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Пошук прылад"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Адлучыць"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Спыніць трансляцыю"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Закрыць"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Прайграць"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Прыпыніць"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Спыніць"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Разгарнуць"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Згарнуць"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Вокладка альбома"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Паўзунок гучнасці"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Медыяфайл не выбраны"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Інфармацыя адсутнічае"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Экран трансляцыі"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-bg/strings.xml b/packages/MediaComponents/res/values-bg/strings.xml
deleted file mode 100644
index 76712d4..0000000
--- a/packages/MediaComponents/res/values-bg/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Система"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Устройства"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Бутон за предаване"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Бутон за предаване. Връзката е прекратена"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Бутон за предаване. Свързва се"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Бутон за предаване. Установена е връзка"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Предаване към"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Търсят се устройства"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Прекратяване на връзката"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Спиране на предаването"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Затваряне"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Пускане"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Поставяне на пауза"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Спиране"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Разгъване"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Свиване"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Обложка на албума"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Плъзгач за силата на звука"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Няма избрана мултимедия"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Няма налична информация"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Екранът се предава"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-bn/strings.xml b/packages/MediaComponents/res/values-bn/strings.xml
deleted file mode 100644
index 1bf5932..0000000
--- a/packages/MediaComponents/res/values-bn/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"সিস্টেম"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"ডিভাইসগুলি"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"কাস্ট করার বোতাম"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"কাস্ট করার বোতাম৷ সংযোগ বিচ্ছিন্ন হয়েছে"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"কাস্ট করার বোতাম৷ সংযোগ করা হচ্ছে"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"কাস্ট করার বোতাম৷ সংযুক্ত হয়েছে"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"এতে কাস্ট করুন"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"ডিভাইসগুলিকে খোঁজা হচ্ছে"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"সংযোগ বিচ্ছিন্ন করুন"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"কাস্ট করা বন্ধ করুন"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"বন্ধ করুন"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"চালান"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"বিরাম দিন"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"থামান"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"বড় করুন"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"সঙ্কুচিত করুন"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"অ্যালবাম শৈলি"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"ভলিউম স্লাইডার"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"কোনো মিডিয়া নির্বাচন করা হয়নি"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"কোনো তথ্য উপলব্ধ নেই"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"স্ক্রীন কাস্ট করা হচ্ছে"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-bs/strings.xml b/packages/MediaComponents/res/values-bs/strings.xml
deleted file mode 100644
index 711c742..0000000
--- a/packages/MediaComponents/res/values-bs/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Sistem"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Uređaji"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Dugme za emitiranje"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Dugme za emitiranje. Veza je prekinuta"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Dugme za emitiranje. Povezivanje"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Dugme za emitiranje. Povezano"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Emitiranje na"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Traženje uređaja"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Prekini vezu"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Zaustavi prebacivanje"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Zatvori"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Reproduciraj"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Pauziraj"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Zaustavi"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Proširi"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Skupi"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Omot albuma"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Klizač za jačinu zvuka"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Nijedan medij nije odabran"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Nema dostupnih informacija"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Prebacuje se ekran"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-ca/strings.xml b/packages/MediaComponents/res/values-ca/strings.xml
deleted file mode 100644
index bf85acf..0000000
--- a/packages/MediaComponents/res/values-ca/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Dispositius"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Botó d\'emetre"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Botó Emet. Desconnectat."</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Botó Emet. S\'està connectant."</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Botó Emet. Connectat."</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Emet a"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"S\'estan cercant dispositius"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Desconnecta"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Atura l\'emissió"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Tanca"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Reprodueix"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Posa en pausa"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Atura"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Desplega"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Replega"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Imatge de l\'àlbum"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Control lliscant de volum"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"No s\'ha seleccionat cap fitxer multimèdia"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"No hi ha informació disponible"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Emissió de pantalla"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-cs/strings.xml b/packages/MediaComponents/res/values-cs/strings.xml
deleted file mode 100644
index 09a8920..0000000
--- a/packages/MediaComponents/res/values-cs/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Systém"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Zařízení"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Tlačítko odesílání"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Tlačítko odesílání. Odpojeno"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Tlačítko odesílání. Připojování"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Tlačítko odesílání. Připojeno"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Odesílat do"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Hledání zařízení"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Odpojit"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Zastavit odesílání"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Zavřít"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Přehrát"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Pozastavit"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Zastavit"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Rozbalit"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Sbalit"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Obal alba"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Posuvník hlasitosti"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Nebyla vybrána žádná média"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Nejsou k dispozici žádné informace"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Odesílání obsahu obrazovky"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-da/strings.xml b/packages/MediaComponents/res/values-da/strings.xml
deleted file mode 100644
index 8e7a790..0000000
--- a/packages/MediaComponents/res/values-da/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Enheder"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Cast-knap"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Cast-knap. Forbindelsen er afbrudt"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Cast-knap. Opretter forbindelse"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Cast-knap. Tilsluttet"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Cast til"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Finder enheder"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Afbryd"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Stop med at caste"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Luk"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Afspil"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Sæt på pause"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Stop"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Udvid"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Skjul"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Albumgrafik"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Lydstyrkeskyder"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Ingen medier er markeret"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Der er ingen tilgængelige oplysninger"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Skærmen castes"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-de/strings.xml b/packages/MediaComponents/res/values-de/strings.xml
deleted file mode 100644
index 26bf57c..0000000
--- a/packages/MediaComponents/res/values-de/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Geräte"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Cast-Symbol"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Streaming-Schaltfläche. Nicht verbunden"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Streaming-Schaltfläche. Verbindung wird hergestellt"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Streaming-Schaltfläche. Verbunden"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Streamen auf"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Geräte werden gesucht."</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Verbindung trennen"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Streaming beenden"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Schließen"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Wiedergeben"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Pausieren"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Beenden"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Maximieren"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Minimieren"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Albumcover"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Schieberegler für die Lautstärke"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Keine Medien ausgewählt"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Keine Informationen verfügbar"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Bildschirm wird gestreamt."</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-el/strings.xml b/packages/MediaComponents/res/values-el/strings.xml
deleted file mode 100644
index d82f69b..0000000
--- a/packages/MediaComponents/res/values-el/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Σύστημα"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Συσκευές"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Κουμπί Cast"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Κουμπί μετάδοσης. Αποσυνδέθηκε"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Κουμπί μετάδοση. Σύνδεση σε εξέλιξη"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Κουμπί μετάδοσης. Συνδέθηκε"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Μετάδοση σε"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Εύρεση συσκευών"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Αποσύνδεση"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Διακοπή μετάδοσης"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Κλείσιμο"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Αναπαραγωγή"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Παύση"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Διακοπή"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Ανάπτυξη"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Σύμπτυξη"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Εξώφυλλο άλμπουμ"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Ρυθμιστικό έντασης ήχου"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Δεν έχουν επιλεγεί μέσα"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Δεν υπάρχουν διαθέσιμες πληροφορίες"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Μετάδοση οθόνης"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-en-rAU/strings.xml b/packages/MediaComponents/res/values-en-rAU/strings.xml
deleted file mode 100644
index dd3f219..0000000
--- a/packages/MediaComponents/res/values-en-rAU/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Devices"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Cast button"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Cast button. Disconnected"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Cast button. Connecting"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Cast button. Connected"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Cast to"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Finding devices"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Disconnect"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Stop casting"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Close"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Play"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Pause"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Stop"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Expand"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Collapse"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Album art"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Volume slider"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"No media selected"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"No info available"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Casting screen"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-en-rCA/strings.xml b/packages/MediaComponents/res/values-en-rCA/strings.xml
deleted file mode 100644
index dd3f219..0000000
--- a/packages/MediaComponents/res/values-en-rCA/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Devices"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Cast button"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Cast button. Disconnected"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Cast button. Connecting"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Cast button. Connected"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Cast to"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Finding devices"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Disconnect"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Stop casting"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Close"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Play"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Pause"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Stop"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Expand"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Collapse"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Album art"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Volume slider"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"No media selected"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"No info available"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Casting screen"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-en-rGB/strings.xml b/packages/MediaComponents/res/values-en-rGB/strings.xml
deleted file mode 100644
index dd3f219..0000000
--- a/packages/MediaComponents/res/values-en-rGB/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Devices"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Cast button"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Cast button. Disconnected"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Cast button. Connecting"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Cast button. Connected"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Cast to"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Finding devices"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Disconnect"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Stop casting"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Close"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Play"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Pause"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Stop"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Expand"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Collapse"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Album art"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Volume slider"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"No media selected"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"No info available"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Casting screen"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-en-rIN/strings.xml b/packages/MediaComponents/res/values-en-rIN/strings.xml
deleted file mode 100644
index dd3f219..0000000
--- a/packages/MediaComponents/res/values-en-rIN/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Devices"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Cast button"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Cast button. Disconnected"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Cast button. Connecting"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Cast button. Connected"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Cast to"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Finding devices"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Disconnect"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Stop casting"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Close"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Play"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Pause"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Stop"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Expand"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Collapse"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Album art"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Volume slider"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"No media selected"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"No info available"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Casting screen"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-en-rXC/strings.xml b/packages/MediaComponents/res/values-en-rXC/strings.xml
deleted file mode 100644
index a87007e..0000000
--- a/packages/MediaComponents/res/values-en-rXC/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‎‏‏‎‎‏‎‏‎‎‏‎‎‎‏‏‏‎‎‏‎‎‎‎‎‏‏‏‎‎‎‎‎‏‏‏‎‏‎‏‏‏‏‎‎‎‏‎System‎‏‎‎‏‎"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‏‏‎‏‎‏‎‎‏‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‏‎‏‏‎‎‏‏‎‎‎‎‏‏‎‎‏‎‏‎‎‏‏‏‏‏‎Devices‎‏‎‎‏‎"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‎‎‏‏‎‏‎‎‎‏‏‏‎‏‎‎‎‏‏‎‎‎‏‏‎‏‏‏‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‏‎‎‎‏‎Cast button‎‏‎‎‏‎"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‏‎‎‎‎‎‏‏‎‎‏‏‎‎‎‎‏‎‎‏‏‎‎‎‎‎‏‎‎‏‎‎‏‏‎‏‎‏‏‎‏‎‎‏‏‏‎‏‎‎‎‎Cast button. Disconnected‎‏‎‎‏‎"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‏‎‎‎‎‎‎‏‎‎‎‏‎‏‎‎‏‏‎‎‎‎‎‏‎‎‏‎‎‏‎‎‎‎‏‎‏‎‏‎‎Cast button. Connecting‎‏‎‎‏‎"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎‏‏‏‎‏‏‎‏‏‏‎‏‎‎‎‎‏‏‎‎‏‎‏‎‎‏‎‏‎‏‎‏‏‎‎‎‏‏‏‎‏‏‏‏‎‏‎‎‏‎‏‎‏‎Cast button. Connected‎‏‎‎‏‎"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‎‏‎‏‏‏‎‏‏‎‏‏‏‏‎‎‏‏‏‎‎‏‎‏‏‎‎‎‏‏‎‏‏‎‏‏‎‎Cast to‎‏‎‎‏‎"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‏‎‏‏‏‏‎‎‎‏‎‎‎‎‏‎‎‏‎‏‏‏‏‏‎‎‏‎‎‏‏‎‏‎‎‏‎‎‎Finding devices‎‏‎‎‏‎"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‏‎‎‎‎‎‎‏‏‏‏‎‏‏‏‎‏‎‏‎‎‎‏‎‎‎‏‎‏‏‎‎‎‏‎‏‎‎‏‏‎‎‏‎‏‎‎‎‏‏‎‎‎Disconnect‎‏‎‎‏‎"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‏‎‎‎‏‏‎‏‏‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‏‏‎‎‎‏‎‏‏‏‎‏‏‏‎‏‎‎Stop casting‎‏‎‎‏‎"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‏‏‏‎‎‎‏‏‏‎‎‏‏‏‎‏‎‏‎‏‎‏‎‏‏‏‏‎‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‎‏‎‏‏‏‎‎‎Close‎‏‎‎‏‎"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‎‎‎‎‎‏‎‎‎‎‎‎‎‏‎‎‏‏‎‏‎‎‎‏‏‏‎‎‎‏‏‏‏‎‎‎‎‎‏‎‎Play‎‏‎‎‏‎"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‏‎‎‎‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‎‎‎‏‏‏‏‏‏‎‎‎‏‏‎‏‏‏‏‎‎‏‎‏‎‎‎‏‏‏‏‏‎‎Pause‎‏‎‎‏‎"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‎‏‏‎‎‏‎‏‏‎‏‎‎‎‎‏‎‏‏‎‏‎‎‎‎‏‏‎‏‏‏‏‎‎‎‏‏‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎Stop‎‏‎‎‏‎"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‎‎‎‏‏‏‏‎‎‎‏‎‏‏‏‎‏‎‏‎‏‎‎‎‏‎‎‏‏‎‏‏‎Expand‎‏‎‎‏‎"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‎‎‏‏‎‎‎‏‏‎‏‏‎‎‏‎‎‏‏‎‏‎‏‏‏‏‏‎‎‎‏‏‏‏‎‎Collapse‎‏‎‎‏‎"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‎‏‎‎‏‏‎‎‎‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‏‏‏‎‏‎‏‎‏‎‎‏‎‎‎‎‏‏‎‎‎‎‏‎Album art‎‏‎‎‏‎"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‎‎‎‏‏‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‎‏‎‏‎‎‎‏‏‏‏‏‎‎‎‎‏‎‏‎‏‎‏‏‎‏‎Volume slider‎‏‎‎‏‎"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‏‎‎‎‎‎‏‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎‏‎‏‏‎‏‎No media selected‎‏‎‎‏‎"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‎‏‏‎‏‏‎‎‏‎‎‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‎‏‎‎‏‏‎‏‏‏‏‎‎‎‏‏‎‎‎No info available‎‏‎‎‏‎"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‎‏‎‎‎‎‎‎‏‏‏‏‎‎‏‎‏‏‎‏‏‏‏‏‎‎‎‎‏‏‏‏‏‎‏‎‏‎‏‎‏‎‏‏‎‏‏‎‎‎‎‎‏‏‎Casting screen‎‏‎‎‏‎"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-es-rUS/strings.xml b/packages/MediaComponents/res/values-es-rUS/strings.xml
deleted file mode 100644
index 441ead1..0000000
--- a/packages/MediaComponents/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Dispositivos"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Botón para transmitir"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Botón para transmitir (desconectado)"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Botón para transmitir (conectando)"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Botón para transmitir (conectado)"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Transmitir a"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Buscando dispositivos"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Desconectar"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Detener la transmisión"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Cerrar"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Reproducir"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Pausar"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Detener"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Mostrar"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Ocultar"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Imagen del álbum"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Control deslizante del volumen"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"No se seleccionó ningún contenido multimedia"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Sin información disponible"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Transmitiendo pantalla"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-es/strings.xml b/packages/MediaComponents/res/values-es/strings.xml
deleted file mode 100644
index ff43008..0000000
--- a/packages/MediaComponents/res/values-es/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Dispositivos"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Botón de enviar"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Botón de enviar. Desconectado"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Botón de enviar. Conectando"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Botón de enviar. Conectado"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Enviar a"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Buscando dispositivos"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Desconectar"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Detener envío de contenido"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Cerrar"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Reproducir"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Pausa"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Detener"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Mostrar"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Ocultar"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Portada del álbum"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Control deslizante de volumen"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"No se ha seleccionado ningún medio"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"No hay información disponible"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Enviando pantalla"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-et/strings.xml b/packages/MediaComponents/res/values-et/strings.xml
deleted file mode 100644
index 453235b..0000000
--- a/packages/MediaComponents/res/values-et/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Süsteem"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Seadmed"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Ülekandenupp"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Ülekandenupp. Ühendus on katkestatud"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Ülekandenupp. Ühendamine"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Ülekandenupp. Ühendatud"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Ülekandmine seadmesse"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Seadmete otsimine"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Katkesta ühendus"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Peata ülekandmine"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Sulgemine"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Esitamine"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Peatamine"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Peata"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Laiendamine"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Ahendamine"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Albumi kujundus"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Helitugevuse liugur"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Meediat pole valitud"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Teave puudub"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Ekraanikuva ülekandmine"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-eu/strings.xml b/packages/MediaComponents/res/values-eu/strings.xml
deleted file mode 100644
index dba19e4..0000000
--- a/packages/MediaComponents/res/values-eu/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Gailuak"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Igorri botoia"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Igortzeko botoia. Deskonektatuta"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Igortzeko botoia. Konektatzen"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Igortzeko botoia. Konektatuta"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Igorri hona:"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Gailuak bilatzen"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Deskonektatu"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Utzi igortzeari"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Itxi"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Erreproduzitu"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Pausatu"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Gelditu"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Zabaldu"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Tolestu"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Albumaren azala"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Bolumenaren graduatzailea"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Ez da hautatu multimedia-edukirik"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Ez dago informaziorik"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Pantaila igortzen"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-fa/strings.xml b/packages/MediaComponents/res/values-fa/strings.xml
deleted file mode 100644
index 4c6c779..0000000
--- a/packages/MediaComponents/res/values-fa/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"سیستم"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"دستگاه‌ها"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"دکمه ارسال محتوا"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"دکمه فرستادن. ارتباط قطع شد"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"دکمه فرستادن. درحال مرتبط‌سازی"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"دکمه فرستادن. مرتبط شد"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"ارسال محتوا به"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"پیدا کردن دستگاه‌ها"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"قطع ارتباط"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"توقف ارسال محتوا"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"بستن"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"پخش"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"مکث"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"توقف"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"بزرگ کردن"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"کوچک کردن"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"عکس روی جلد آلبوم"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"لغزنده میزان صدا"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"رسانه انتخاب نشده است"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"اطلاعات در دسترس نیست"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"درحال فرستادن صفحه"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-fi/strings.xml b/packages/MediaComponents/res/values-fi/strings.xml
deleted file mode 100644
index d683435..0000000
--- a/packages/MediaComponents/res/values-fi/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Järjestelmä"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Laitteet"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Cast-painike"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Cast-painike. Yhteys katkaistu"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Cast-painike. Yhdistetään"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Cast-painike. Yhdistetty"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Suoratoiston kohde"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Etsitään laitteita"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Katkaise yhteys"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Lopeta suoratoisto"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Sulje"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Toista"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Keskeytä"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Pysäytä"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Laajenna"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Tiivistä"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Albumin kansikuva"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Äänenvoimakkuuden liukusäädin"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Ei valittua mediaa."</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Tietoja ei ole saatavilla"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Suoratoistetaan näyttöä"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-fr-rCA/strings.xml b/packages/MediaComponents/res/values-fr-rCA/strings.xml
deleted file mode 100644
index c4f984b..0000000
--- a/packages/MediaComponents/res/values-fr-rCA/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Système"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Appareils"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Bouton Diffuser"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Bouton Diffuser. Déconnecté"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Bouton Diffuser. Connexion en cours…"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Bouton Diffuser. Connecté"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Diffuser sur"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Recherche d\'appareils"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Se déconnecter"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Arrêter la diffusion"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Fermer"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Lire"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Interrompre"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Arrêter"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Développer"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Réduire"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Image de l\'album"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Curseur de réglage du volume"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Aucun média sélectionné"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Aucune information disponible"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Diffusion de l\'écran en cours"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-fr/strings.xml b/packages/MediaComponents/res/values-fr/strings.xml
deleted file mode 100644
index 12c312f..0000000
--- a/packages/MediaComponents/res/values-fr/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Système"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Appareils"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Icône Cast"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Icône Cast. Déconnecté"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Icône Cast. Connexion…"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Icône Cast. Connecté"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Caster sur"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Recherche d\'appareils…"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Déconnecter"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Arrêter la diffusion"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Fermer"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Lecture"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Pause"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Arrêter"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Développer"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Réduire"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Image de l\'album"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Curseur de volume"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Aucun média sélectionné"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Aucune information disponible"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Diffusion de l\'écran en cours…"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-gl/strings.xml b/packages/MediaComponents/res/values-gl/strings.xml
deleted file mode 100644
index 1b2c354..0000000
--- a/packages/MediaComponents/res/values-gl/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Dispositivos"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Botón de emitir"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Botón de emitir. Desconectado"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Botón de emitir. Conectando"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Botón de emitir. Conectado"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Emitir a"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Buscando dispositivos"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Desconectar"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Deter emisión"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Pechar"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Reproduce"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Pausa"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Deter"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Ampliar"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Contraer"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Portada do álbum"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Control desprazable do volume"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Non se seleccionaron recursos"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Non hai información dispoñible"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Emisión de pantalla"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-gu/strings.xml b/packages/MediaComponents/res/values-gu/strings.xml
deleted file mode 100644
index 2cd5f3f..0000000
--- a/packages/MediaComponents/res/values-gu/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"સિસ્ટમ"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"ઉપકરણો"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"કાસ્ટ કરો બટન"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"કાસ્ટ કરો બટન. ડિસ્કનેક્ટ કર્યું"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"કાસ્ટ કરો બટન. કનેક્ટ થઈ રહ્યું છે"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"કાસ્ટ કરો બટન. કનેક્ટ થયું"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"આના પર કાસ્ટ કરો"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"ઉપકરણો શોધી રહ્યાં છીએ"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"ડિસ્કનેક્ટ કરો"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"કાસ્ટ કરવાનું રોકો"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"બંધ કરો"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"ચલાવો"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"થોભાવો"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"રોકો"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"વિસ્તૃત કરો"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"સંકુચિત કરો"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"આલ્બમ કલા"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"વૉલ્યુમ સ્લાઇડર"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"કોઈ મીડિયા પસંદ કરેલ નથી"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"કોઈ માહિતી ઉપલબ્ધ નથી"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"સ્ક્રીનને કાસ્ટ કરી રહ્યાં છે"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-hi/strings.xml b/packages/MediaComponents/res/values-hi/strings.xml
deleted file mode 100644
index 9552a59..0000000
--- a/packages/MediaComponents/res/values-hi/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"सिस्टम"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"डिवाइस"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"कास्ट करें बटन"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"कास्ट करें बटन. डिसकनेक्ट है"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"कास्ट करें बटन. कनेक्ट हो रहा है"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"कास्ट करें बटन. कनेक्ट है"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"इस पर कास्‍ट करें"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"डिवाइस ढूंढ रहा है"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"डिसकनेक्ट करें"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"कास्ट करना बंद करें"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"बंद करें"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"चलाएं"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"रोकें"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"बंद करें"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"विस्तार करें"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"छोटा करें"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"एल्बम आर्ट"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"वॉल्यूम स्लाइडर"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"कोई मीडिया चयनित नहीं है"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"कोई जानकारी मौजूद नहीं है"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"स्क्रीन कास्ट हो रही है"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-hr/strings.xml b/packages/MediaComponents/res/values-hr/strings.xml
deleted file mode 100644
index 3c43ee7..0000000
--- a/packages/MediaComponents/res/values-hr/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Sustav"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Uređaji"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Gumb za emitiranje"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Gumb za emitiranje. Veza prekinuta"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Gumb za emitiranje. Povezivanje"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Gumb za emitiranje. Povezan"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Emitiranje na"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Traženje uređaja"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Prekini vezu"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Zaustavi emitiranje"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Zatvaranje"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Reprodukcija"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Pauziranje"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Zaustavi"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Proširivanje"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Sažimanje"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Naslovnica albuma"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Klizač za glasnoću"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Nije odabran nijedan medij"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Informacije nisu dostupne"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Emitiranje zaslona"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-hu/strings.xml b/packages/MediaComponents/res/values-hu/strings.xml
deleted file mode 100644
index a36bdfe..0000000
--- a/packages/MediaComponents/res/values-hu/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Rendszer"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Eszközök"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Átküldés gomb"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Átküldés gomb. Kapcsolat bontva"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Átküldés gomb. Csatlakozás"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Átküldés gomb. Csatlakoztatva"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Átküldés ide"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Eszközök keresése"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Leválasztás"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Átküldés leállítása"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Bezárás"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Lejátszás"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Szüneteltetés"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Leállítás"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Kibontás"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Összecsukás"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Lemezborító"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Hangerőszabályzó"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Nincs média kiválasztva"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Nincs információ"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Képernyőtartalom átküldése"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-hy/strings.xml b/packages/MediaComponents/res/values-hy/strings.xml
deleted file mode 100644
index 8ec82b7..0000000
--- a/packages/MediaComponents/res/values-hy/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Համակարգ"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Սարքեր"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Հեռարձակման կոճակ"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Հեռարձակման կոճակ: Սարքն անջատված է"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Հեռարձակման կոճակ: Սարքը կապակցվում է"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Հեռարձակման կոճակ: Սարքը կապակցված է"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Ընտրեք սարքը"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Սարքերի որոնում"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Անջատել"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Դադարեցնել հեռարձակումը"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Փակել"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Նվագարկել"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Դադար"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Դադարեցնել"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Ընդարձակել"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Կոծկել"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Ալբոմի շապիկ"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Ձայնի ուժգնության կարգավորիչ"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Մեդիա ֆայլեր չեն ընտրվել"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Տեղեկությունները հասանելի չեն"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Էկրանը հեռարձակվում է"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-in/strings.xml b/packages/MediaComponents/res/values-in/strings.xml
deleted file mode 100644
index 6b2752e..0000000
--- a/packages/MediaComponents/res/values-in/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Sistem"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Perangkat"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Tombol Cast"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Tombol Cast. Terputus"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Tombol Cast. Menghubungkan"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Tombol Cast. Terhubung"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Transmisikan ke"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Mencari perangkat"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Putuskan sambungan"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Hentikan cast"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Tutup"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Putar"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Jeda"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Berhenti"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Luaskan"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Ciutkan"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Sampul album"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Bilah geser volume"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Tidak ada media yang dipilih"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Tidak ada info yang tersedia"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Transmisi layar"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-is/strings.xml b/packages/MediaComponents/res/values-is/strings.xml
deleted file mode 100644
index 6a35ea6..0000000
--- a/packages/MediaComponents/res/values-is/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Kerfi"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Tæki"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Útsendingarhnappur"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Útsendingarhnappur. Aftengt"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Útsendingarhnappur. Tengist"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Útsendingarhnappur. Tengt"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Senda út í"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Leitað að tækjum"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Aftengjast"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Stöðva útsendingu"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Loka"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Spila"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Hlé"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Stöðva"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Stækka"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Minnka"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Plötuumslag"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Hljóðstyrkssleði"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Enginn miðill valinn"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Engar upplýsingar í boði"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Skjár sendur út"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-it/strings.xml b/packages/MediaComponents/res/values-it/strings.xml
deleted file mode 100644
index 716e3ac..0000000
--- a/packages/MediaComponents/res/values-it/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Dispositivi"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Pulsante Trasmetti"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Pulsante Trasmetti. Disconnesso"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Pulsante Trasmetti. Connessione in corso"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Pulsante Trasmetti. Connesso"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Trasmetti a"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Ricerca di dispositivi in corso"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Scollega"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Interrompi trasmissione"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Chiudi"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Riproduci"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Pausa"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Interrompi"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Espandi"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Comprimi"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Copertina"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Dispositivo di scorrimento del volume"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Nessun contenuto multimediale selezionato"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Nessuna informazione disponibile"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Trasmissione dello schermo in corso"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-iw/strings.xml b/packages/MediaComponents/res/values-iw/strings.xml
deleted file mode 100644
index 252b0ce..0000000
--- a/packages/MediaComponents/res/values-iw/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"מערכת"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"מכשירים"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"‏לחצן הפעלת Cast"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"‏לחצן הפעלת Cast. מנותק"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"‏לחצן הפעלת Cast. מתחבר"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"‏לחצן הפעלת Cast. מחובר"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"העברה אל"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"מחפש מכשירים"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"נתק"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"הפסק את ההעברה"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"סגור"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"הפעל"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"השהה"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"הפסק"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"הרחב"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"כווץ"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"עטיפת אלבום"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"מחוון עוצמה"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"לא נבחרה מדיה"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"אין מידע זמין"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"העברת מסך מתבצעת"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-ja/strings.xml b/packages/MediaComponents/res/values-ja/strings.xml
deleted file mode 100644
index a149727..0000000
--- a/packages/MediaComponents/res/values-ja/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"システム"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"端末"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"キャストアイコン"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"キャスト アイコン。接続解除済み"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"キャスト アイコン。接続中"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"キャスト アイコン。接続済み"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"キャストするデバイス"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"端末を検索しています"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"接続を解除"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"キャストを停止"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"閉じる"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"再生"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"一時停止"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"停止"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"展開"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"折りたたむ"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"アルバムアート"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"音量スライダー"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"メディアが選択されていません"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"情報がありません"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"画面をキャストしています"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-ka/strings.xml b/packages/MediaComponents/res/values-ka/strings.xml
deleted file mode 100644
index 3da081a..0000000
--- a/packages/MediaComponents/res/values-ka/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"სისტემა"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"მოწყობილობები"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"ტრანსლირების ღილაკი"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"ტრანსლირების ღილაკი. გათიშული"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"ტრანსლირების ღილაკი. მიმდინარეობს დაკავშირება"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"ტრანსლირების ღილაკი. დაკავშირებული"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"ტრანსლირება:"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"მოწყობილობების მოძიება..."</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"კავშირის გაწყვეტა"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"ტრანსლირების შეწყვეტა"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"დახურვა"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"დაკვრა"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"პაუზა"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"შეწყვეტა"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"გაშლა"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"ჩაკეცვა"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"ალბომის გარეკანი"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"ხმის სლაიდერი"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"მედია არჩეული არ არის"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"ინფორმაცია არ არის ხელმისაწვდომი"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"მიმდინარეობს ეკრანის გადაცემა"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-kk/strings.xml b/packages/MediaComponents/res/values-kk/strings.xml
deleted file mode 100644
index 94dcbb3..0000000
--- a/packages/MediaComponents/res/values-kk/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Жүйе"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Құрылғылар"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Трансляциялау түймесі"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"\"Трансляциялау\" түймесі. Ажыратулы"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"\"Трансляциялау\" түймесі. Қосылуда"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"\"Трансляциялау\" түймесі. Қосылды"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Келесіге трансляциялау"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Құрылғыларды табу"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Ажырату"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Трансляциялауды тоқтату"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Жабу"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Ойнату"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Кідірту"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Тоқтату"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Жаю"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Жию"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Альбом шебері"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Дыбыс деңгейінің жүгірткісі"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Ешбір тасушы таңдалмаған"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Қол жетімді ақпарат жоқ"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Экранды трансляциялау"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-km/strings.xml b/packages/MediaComponents/res/values-km/strings.xml
deleted file mode 100644
index e44780e..0000000
--- a/packages/MediaComponents/res/values-km/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"ប្រព័ន្ធ"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"ឧបករណ៍"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"ប៊ូតុងខាស"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"ខាសប៊ូតុង៖ បានកាត់ផ្តាច់"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"ខាសប៊ូតុង៖ កំពុងភ្ជាប់"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"ខាសប៊ូតុង៖ បានភ្ជាប់ហើយ"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"បញ្ជូនទៅ"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"កំពុងស្វែងរកឧបករណ៍"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"ផ្ដាច់"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"ឈប់ភ្ជាប់"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"បិទ"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"ចាក់"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"ផ្អាក"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"ឈប់"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"ពង្រីក"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"បង្រួម"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"ស្នាដៃសិល្បៈអាល់ប៊ុម"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"របារកម្រិតសំឡេង"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"គ្មានការជ្រើសមេឌៀទេ"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"មិនមានព័ត៌មានទេ"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"កំពុងខាសអេក្រង់"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-kn/strings.xml b/packages/MediaComponents/res/values-kn/strings.xml
deleted file mode 100644
index 4237fdd..0000000
--- a/packages/MediaComponents/res/values-kn/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"ಸಿಸ್ಟಂ"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"ಸಾಧನಗಳು"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"ಬಿತ್ತರಿಸು ಬಟನ್‌"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"ಬಿತ್ತರಿಸು ಬಟನ್‌. ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗಿದೆ"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"ಬಿತ್ತರಿಸು ಬಟನ್‌. ಸಂಪರ್ಕಿಸಲಾಗುತ್ತಿದೆ"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"ಬಿತ್ತರಿಸು ಬಟನ್‌. ಸಂಪರ್ಕಿತಗೊಂಡಿದೆ"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"ಇದಕ್ಕೆ ಬಿತ್ತರಿಸಿ"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"ಸಾಧನಗಳನ್ನು ಹುಡುಕಲಾಗುತ್ತಿದೆ"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸು"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"ಬಿತ್ತರಿಸುವಿಕೆ ನಿಲ್ಲಿಸಿ"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"ಮುಚ್ಚು"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"ಪ್ಲೇ ಮಾಡಿ"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"ವಿರಾಮ"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"ನಿಲ್ಲಿಸಿ"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"ವಿಸ್ತರಿಸು"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"ಸಂಕುಚಿಸು"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"ಆಲ್ಬಮ್ ಕಲೆ"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"ವಾಲ್ಯೂಮ್ ಸ್ಲೈಡರ್"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"ಯಾವುದೇ ಮಾಧ್ಯಮ ಆಯ್ಕೆಮಾಡಲಾಗಿಲ್ಲ"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"ಯಾವುದೇ ಮಾಹಿತಿ ಲಭ್ಯವಿಲ್ಲ"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"ಪರದೆಯನ್ನು ಬಿತ್ತರಿಸಲಾಗುತ್ತಿದೆ"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-ko/strings.xml b/packages/MediaComponents/res/values-ko/strings.xml
deleted file mode 100644
index be893a9..0000000
--- a/packages/MediaComponents/res/values-ko/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"시스템"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"기기"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"전송 버튼"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"전송 버튼. 연결 해제됨"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"전송 버튼. 연결 중"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"전송 버튼. 연결됨"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"전송할 기기"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"기기를 찾는 중"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"연결 해제"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"전송 중지"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"닫기"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"재생"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"일시중지"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"중지"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"펼치기"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"접기"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"앨범아트"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"볼륨 슬라이더"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"선택한 미디어 없음"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"정보가 없습니다."</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"화면 전송 중"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-ky/strings.xml b/packages/MediaComponents/res/values-ky/strings.xml
deleted file mode 100644
index 57813af..0000000
--- a/packages/MediaComponents/res/values-ky/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Тутум"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Түзмөктөр"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Тышкы экранга чыгаруу баскычы"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Тышкы экранга чыгаруу баскычы. Түзмөк ажырап турат."</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Тышкы экранга чыгаруу баскычы. Түзмөк туташууда"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Тышкы экранга чыгаруу баскычы. Түзмөк туташып турат"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Төмөнкүгө чыгаруу"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Түзмөктөр изделүүдө"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Ажыратуу"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Тышк экранга чыгарну токтотуу"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Жабуу"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Ойнотуу"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Тындыруу"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Токтотуу"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Жайып көрсөтүү"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Жыйыштыруу"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Альбом мукабасы"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Үндү катуулатуучу сыдырма"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Бир да медиа файл тандалган жок"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Эч маалымат жок"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Тышкы экранга чыгарылууда"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-land/dimens.xml b/packages/MediaComponents/res/values-land/dimens.xml
deleted file mode 100644
index 29f1e1d..0000000
--- a/packages/MediaComponents/res/values-land/dimens.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <!-- MediaRouteController's volume group list -->
-    <eat-comment />
-    <!-- Maximum height of volume group list. -->
-    <dimen name="mr_controller_volume_group_list_max_height">132dp</dimen>
-    <!-- Height of volume group item. -->
-    <dimen name="mr_controller_volume_group_list_item_height">61dp</dimen>
-    <!-- Size of an item's icon. -->
-    <dimen name="mr_controller_volume_group_list_item_icon_size">18dp</dimen>
-</resources>
diff --git a/packages/MediaComponents/res/values-lo/strings.xml b/packages/MediaComponents/res/values-lo/strings.xml
deleted file mode 100644
index 91737db..0000000
--- a/packages/MediaComponents/res/values-lo/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"ລະບົບ"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"ອຸປະກອນ"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"ປຸ່ມ​ຄາ​ສ​ທ໌"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"ປຸ່ມສົ່ງສັນຍານ. ຕັດການເຊື່ອມຕໍ່ແລ້ວ"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"ປຸ່ມສົ່ງສັນຍານ. ກຳລັງເຊື່ອມຕໍ່"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"ປຸ່ມສົ່ງສັນຍານ. ເຊື່ອມຕໍ່ແລ້ວ"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"ສົ່ງສັນຍານຫາ"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"ກຳລັງ​ຊອກ​ຫາ​ອຸ​ປະ​ກອນ"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"ຕັດການເຊື່ອມຕໍ່"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"ຢຸດການສົ່ງສັນຍານ"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"ປິດ"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"ຫຼິ້ນ"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"ຢຸດຊົ່ວຄາວ"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"ຢຸດ"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"ຂະຫຍາຍ"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"ຫຍໍ້ລົງ"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"ໜ້າປົກອະລະບໍ້າ"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"ຕົວປັບລະດັບສຽງ"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"ບໍ່​ໄດ້​ເລືອກ​ມີ​ເດຍ​ໃດ​ໄວ້"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"ບໍ່​ມີ​ຂໍ້​ມູນ"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"ການສົ່ງພາບໜ້າຈໍ"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-lt/strings.xml b/packages/MediaComponents/res/values-lt/strings.xml
deleted file mode 100644
index ff036d1..0000000
--- a/packages/MediaComponents/res/values-lt/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Įrenginiai"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Perdavimo mygtukas"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Perdavimo mygtukas. Atsijungta"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Perdavimo mygtukas. Prisijungiama"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Perdavimo mygtukas. Prisijungta"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Perduoti į"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Randami įrenginiai"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Atjungti"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Sustabdyti perdavimą"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Uždaryti"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Leisti"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Pristabdyti"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Sustabdyti"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Išskleisti"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Sutraukti"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Albumo viršelis"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Garsumo šliaužiklis"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Nepasirinkta jokia medija"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Informacija nepasiekiama"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Perduodamas ekranas"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-lv/strings.xml b/packages/MediaComponents/res/values-lv/strings.xml
deleted file mode 100644
index 454063e..0000000
--- a/packages/MediaComponents/res/values-lv/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Sistēma"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Ierīces"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Apraides poga"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Apraides poga. Savienojums pārtraukts"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Apraides poga. Notiek savienojuma izveide"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Apraides poga. Savienojums izveidots"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Apraidīšana uz ierīci"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Notiek ierīču meklēšana"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Atvienot"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Apturēt apraidi"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Aizvērt"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Atskaņot"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Apturēt"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Apturēt"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Izvērst"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Sakļaut"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Albuma vāciņš"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Skaļuma slīdnis"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Nav atlasīti multivides faili"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Nav pieejama informācija"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Notiek ekrāna apraide"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-mk/strings.xml b/packages/MediaComponents/res/values-mk/strings.xml
deleted file mode 100644
index 12dee36..0000000
--- a/packages/MediaComponents/res/values-mk/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Систем"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Уреди"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Копчето за Cast"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Копче за Cast. Исклучено"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Копче за Cast. Се поврзува"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Копче за Cast. Поврзано"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Емитувај на"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Се бараат уреди"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Исклучи"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Сопри го емитувањето"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Затвори"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Репродуцирај"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Паузирај"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Сопри"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Прошири"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Собери"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Корица на албум"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Лизгач за јачина на звук"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Не се избрани медиуми"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Нема достапни информации"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Екранот се емитува"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-ml/strings.xml b/packages/MediaComponents/res/values-ml/strings.xml
deleted file mode 100644
index 2d914b9..0000000
--- a/packages/MediaComponents/res/values-ml/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"സിസ്റ്റം"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"ഉപകരണങ്ങൾ"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"ടാപ്പുചെയ്യുക"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"കാസ്റ്റ് ബട്ടൺ. വിച്ഛേദിച്ചു"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"കാസ്റ്റ് ബട്ടൺ. കണക്‌റ്റുചെയ്യുന്നു"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"കാസ്റ്റ് ബട്ടൺ. കണക്റ്റുചെയ്തു"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"ഇതിലേക്ക് കാസ്റ്റുചെയ്യുക"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"ഉപകരണങ്ങൾ കണ്ടെത്തുന്നു"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"വിച്ഛേദിക്കുക"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"കാസ്റ്റുചെയ്യൽ നിർത്തുക"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"അവസാനിപ്പിക്കുക"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"പ്ലേ ചെയ്യുക"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"തൽക്കാലം നിർത്തൂ"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"നിര്‍ത്തുക"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"വികസിപ്പിക്കുക"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"ചുരുക്കുക"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"ആൽബം ആർട്ട്"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"വോളിയം സ്ലൈഡർ"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"മീഡിയയൊന്നും തിരഞ്ഞെടുത്തിട്ടില്ല"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"വിവരങ്ങളൊന്നും ലഭ്യമല്ല"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"സ്‌ക്രീൻ കാസ്റ്റുചെയ്യുന്നു"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-mn/strings.xml b/packages/MediaComponents/res/values-mn/strings.xml
deleted file mode 100644
index ef87c92..0000000
--- a/packages/MediaComponents/res/values-mn/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Систем"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Төхөөрөмжүүд"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Дамжуулах товчлуур"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Дамжуулах товчлуур. Салсан"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Дамжуулах товчлуур. Холбож байна"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Дамжуулах товчлуур. Холбогдсон"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Дамжуулах"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Төхөөрөмж хайж байна"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Салгах"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Дамжуулахыг зогсоох"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Хаах"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Тоглуулах"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Түр зогсоох"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Зогсоох"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Дэлгэх"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Хураах"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Цомгийн зураг"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Дууны түвшин тааруулагч"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Ямар ч медиа сонгоогүй"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Мэдээлэл байхгүй байна"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Дэлгэцийг дамжуулж байна"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-mr/strings.xml b/packages/MediaComponents/res/values-mr/strings.xml
deleted file mode 100644
index 2ffbebb..0000000
--- a/packages/MediaComponents/res/values-mr/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"सिस्टम"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"डिव्हाइसेस"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"कास्ट बटण"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"कास्ट बटण. डिस्कनेक्ट केले"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"कास्ट बटण. कनेक्ट करत आहे"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"कास्ट बटण. कनेक्ट केले"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"यावर कास्ट करा"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"डिव्हाइसेस शोधत आहे"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"डिस्‍कनेक्‍ट करा"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"कास्ट करणे थांबवा"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"बंद करा"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"प्ले करा"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"विराम"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"थांबा"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"विस्तृत करा"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"संकुचित करा"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"अल्बम कला"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"व्हॉल्यूम स्लायडर"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"मीडिया निवडला नाही"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"कोणतीही माहिती उपलब्ध नाही"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"स्क्रीन कास्‍ट करत आहे"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-ms/strings.xml b/packages/MediaComponents/res/values-ms/strings.xml
deleted file mode 100644
index 085e480..0000000
--- a/packages/MediaComponents/res/values-ms/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Sistem"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Peranti"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Butang Hantar"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Butang hantar. Sambungan diputuskan"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Butang hantar. Menyambung"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Butang hantar. Disambungkan"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Hantar ke"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Mencari peranti"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Putuskan sambungan"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Berhenti menghantar"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Tutup"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Main"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Jeda"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Berhenti"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Kembangkan"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Runtuhkan"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Seni album"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Peluncur kelantangan"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Tiada media dipilih"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Maklumat tidak tersedia"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Menghantar skrin"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-my/strings.xml b/packages/MediaComponents/res/values-my/strings.xml
deleted file mode 100644
index 083d805..0000000
--- a/packages/MediaComponents/res/values-my/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"စနစ်"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"စက်ပစ္စည်းများ"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"ကာစ်တ်လုပ်ရန် ခလုတ်"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"ကာစ်ခလုတ်။ ချိတ်ဆက်မထားပါ"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"ကာစ်ခလုတ်။ ချိတ်ဆက်နေသည်"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"ကာစ်ခလုတ်။ ချိတ်ဆက်ထားသည်"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"ကာစ်လုပ်ရန် စက်"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"စက်ပစ္စည်းများ ရှာဖွေခြင်း"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"ဆက်သွယ်မှု ဖြတ်ရန်"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"ကာစ်လုပ်ခြင်း ရပ်ရန်"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"ပိတ်ရန်"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"ဖွင့်ရန်"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"ခဏရပ်ရန်"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"ရပ်ရန်"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"ဖြန့်ချရန်၃"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"ခေါက်သိမ်းရန်..."</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"အယ်လ်ဘမ်ပုံ"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"အသံအတိုးအကျယ်ချိန်သည့် ဆလိုက်ဒါ"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"မည်သည့်မီဒီမှ မရွေးချယ်ထားပါ"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"အချက်အလက် မရရှိနိုင်ပါ"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"တည်းဖြတ်ရေး မျက်နှာပြင်"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-nb/strings.xml b/packages/MediaComponents/res/values-nb/strings.xml
deleted file mode 100644
index 4f764c9..0000000
--- a/packages/MediaComponents/res/values-nb/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Enheter"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Cast-ikonet"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Cast-knappen. Frakoblet"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Cast-knappen. Kobler til"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Cast-knappen. Tilkoblet"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Cast til"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Søker etter enheter"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Koble fra"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Stopp castingen"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Lukk"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Spill av"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Sett på pause"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Stopp"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Utvid"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Skjul"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Albumgrafikk"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Glidebryter for volum"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Du har ikke valgt noen medier"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Ingen informasjon er tilgjengelig"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Caster skjermen"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-ne/strings.xml b/packages/MediaComponents/res/values-ne/strings.xml
deleted file mode 100644
index d6c2e1a..0000000
--- a/packages/MediaComponents/res/values-ne/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"प्रणाली"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"उपकरणहरू"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Cast बटन"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Cast बटन। जडान विच्छेद भयो"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Cast बटन। जडान हुँदै"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Cast बटन। जडान भयो"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"यसमा Cast गर्नुहोस्"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"यन्त्रहरू पत्ता लगाउँदै"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"विच्छेद गर्नुहोस्"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"casting रोक्नुहोस्"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"बन्द गर्नुहोस्"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"बजाउनुहोस्"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"रोक्नुहोस्"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"रोक्नुहोस्"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"विस्तार गर्नुहोस्"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"संक्षिप्त पार्नुहोस्"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"एल्बम आर्ट"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"भोल्युमको स्लाइडर"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"कुनै मिडिया चयन भएको छैन"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"जानकारी उपलब्ध छैन"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"स्क्रिन cast गर्दै"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-nl/strings.xml b/packages/MediaComponents/res/values-nl/strings.xml
deleted file mode 100644
index 05df62d..0000000
--- a/packages/MediaComponents/res/values-nl/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Systeem"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Apparaten"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Cast-icoon"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Cast-icoon. Verbinding verbroken"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Cast-icoon. Verbinding maken"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Cast-icoon. Verbonden"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Casten naar"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Apparaten zoeken"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Loskoppelen"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Casten stoppen"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Sluiten"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Afspelen"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Onderbreken"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Stoppen"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Uitvouwen"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Samenvouwen"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Albumhoes"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Volumeschuifregelaar"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Geen media geselecteerd"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Geen informatie beschikbaar"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Scherm casten"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-pa/strings.xml b/packages/MediaComponents/res/values-pa/strings.xml
deleted file mode 100644
index 1b5df71..0000000
--- a/packages/MediaComponents/res/values-pa/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"ਸਿਸਟਮ"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"ਡਿਵਾਈਸਾਂ"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"ਕਾਸਟ ਬਟਨ"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"ਕਾਸਟ ਬਟਨ। ਡਿਸਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"ਕਾਸਟ ਬਟਨ। ਕਨੈਕਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"ਕਾਸਟ ਬਟਨ। ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"ਏਥੇ ਕਾਸਟ ਕਰੋ"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"ਡੀਵਾਈਸਾਂ ਨੂੰ ਲੱਭਿਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"ਡਿਸਕਨੈਕਟ ਕਰੋ"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"ਕਾਸਟ ਕਰਨਾ ਬੰਦ ਕਰੋ"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"ਬੰਦ ਕਰੋ"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"ਪਲੇ ਕਰੋ"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"ਰੋਕੋ"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"ਬੰਦ ਕਰੋ"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"ਵਿਸਤਾਰ ਕਰੋ"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"ਬੰਦ ਕਰੋ"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"ਐਲਬਮ ਆਰਟ"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"ਵੌਲਯੂਮ ਸਲਾਈਡਰ"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"ਕੋਈ ਵੀ ਮੀਡੀਆ ਨਹੀਂ ਚੁਣਿਆ ਗਿਆ"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"ਕੋਈ ਜਾਣਕਾਰੀ ਉਪਲਬਧ ਨਹੀਂ"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"ਸਕ੍ਰੀਨ ਜੋੜ ਰਿਹਾ ਹੈ"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-pl/strings.xml b/packages/MediaComponents/res/values-pl/strings.xml
deleted file mode 100644
index c792a6d..0000000
--- a/packages/MediaComponents/res/values-pl/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Urządzenia"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Przycisk Cast"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Przycisk Prześlij ekran. Rozłączono"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Przycisk Prześlij ekran. Łączę"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Przycisk Prześlij ekran. Połączono"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Przesyłaj na"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Znajdowanie urządzeń"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Odłącz"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Zatrzymaj przesyłanie"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Zamknij"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Odtwórz"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Wstrzymaj"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Zatrzymaj"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Rozwiń"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Zwiń"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Okładka albumu"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Suwak głośności"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Nie wybrano multimediów"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Brak informacji"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Przesyłam ekran"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-pt-rBR/strings.xml b/packages/MediaComponents/res/values-pt-rBR/strings.xml
deleted file mode 100644
index 43c619d..0000000
--- a/packages/MediaComponents/res/values-pt-rBR/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Dispositivos"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Botão Transmitir"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Botão \"Transmitir\". Desconectado"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Botão \"Transmitir\". Conectando"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Botão \"Transmitir\". Conectado"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Transmitir para"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Localizando dispositivos"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Desconectar"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Interromper transmissão"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Fechar"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Reproduzir"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Pausar"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Parar"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Expandir"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Recolher"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Arte do álbum"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Controle deslizante de volume"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Nenhuma mídia selecionada"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Nenhuma informação disponível"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Transmitindo a tela"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-pt-rPT/strings.xml b/packages/MediaComponents/res/values-pt-rPT/strings.xml
deleted file mode 100644
index 3f0a61d..0000000
--- a/packages/MediaComponents/res/values-pt-rPT/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Dispositivos"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Botão Transmitir"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Botão Transmitir. Desligado"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Botão Transmitir. A ligar..."</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Botão Transmitir. Ligado"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Transmitir para"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"A localizar dispositivos"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Desassociar"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Parar a transmissão"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Fechar"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Reproduzir"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Interromper"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Parar"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Expandir"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Reduzir"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Imagem do álbum"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Controlo de deslize do volume"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Nenhum suporte multimédia selecionado"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Nenhuma informação disponível"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"A transmitir o ecrã"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-pt/strings.xml b/packages/MediaComponents/res/values-pt/strings.xml
deleted file mode 100644
index 43c619d..0000000
--- a/packages/MediaComponents/res/values-pt/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Dispositivos"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Botão Transmitir"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Botão \"Transmitir\". Desconectado"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Botão \"Transmitir\". Conectando"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Botão \"Transmitir\". Conectado"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Transmitir para"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Localizando dispositivos"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Desconectar"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Interromper transmissão"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Fechar"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Reproduzir"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Pausar"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Parar"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Expandir"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Recolher"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Arte do álbum"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Controle deslizante de volume"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Nenhuma mídia selecionada"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Nenhuma informação disponível"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Transmitindo a tela"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-ro/strings.xml b/packages/MediaComponents/res/values-ro/strings.xml
deleted file mode 100644
index 6ebb2f6..0000000
--- a/packages/MediaComponents/res/values-ro/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Sistem"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Dispozitive"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Butonul de proiecție"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Butonul de proiecție. Deconectat"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Butonul de proiecție. Se conectează"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Butonul de proiecție. Conectat"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Proiectați pe"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Se caută dispozitive"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Deconectați-vă"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Nu mai proiectați"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Închideți"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Redați"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Întrerupeți"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Opriți"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Extindeți"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Restrângeți"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Grafica albumului"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Glisor pentru volum"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Niciun fișier media selectat"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Nu sunt disponibile informații"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Se proiectează ecranul"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-ru/strings.xml b/packages/MediaComponents/res/values-ru/strings.xml
deleted file mode 100644
index 7c462d2..0000000
--- a/packages/MediaComponents/res/values-ru/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Система"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Устройства"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Кнопка трансляции"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Кнопка трансляции. Устройство отключено."</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Кнопка трансляции. Устройство подключается."</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Кнопка трансляции. Устройство подключено."</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Выберите устройство"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Поиск устройств…"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Отключить"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Прекратить трансляцию"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Закрыть"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Воспроизвести"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Приостановить"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Остановить"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Развернуть"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Свернуть"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Обложка"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Регулятор громкости"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Медиафайл не выбран"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Данных нет"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Подключение к удаленному монитору"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-si/strings.xml b/packages/MediaComponents/res/values-si/strings.xml
deleted file mode 100644
index a55ce50..0000000
--- a/packages/MediaComponents/res/values-si/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"පද්ධතිය"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"උපාංග"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"විකාශ බොත්තම"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"විකාශ බොත්තම. විසන්ධි කරන ලදී"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"විකාශ බොත්තම සම්බන්ධ කරමින්"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"විකාශ බොත්තම සම්බන්ධ කරන ලදී"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"විකාශය"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"උපාංග සෙවීම"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"විසන්ධි කරන්න"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"විකාශ කිරීම නතර කරන්න"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"වසන්න"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"ධාවනය කරන්න"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"විරාම ගන්වන්න"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"නතර කරන්න"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"දිග හරින්න"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"හකුළන්න"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"ඇල්බම කලාව"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"හඬ පරිමා ස්ලයිඩරය"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"මාධ්‍යය තෝරා නැත"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"ලබා ගත හැකි තොරතුරු නොමැත"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"විකාශ තිරය"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-sk/strings.xml b/packages/MediaComponents/res/values-sk/strings.xml
deleted file mode 100644
index a58aa11..0000000
--- a/packages/MediaComponents/res/values-sk/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Systém"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Zariadenia"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Tlačidlo prenosu"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Tlačidlo prenosu. Odpojené"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Tlačidlo prenosu. Pripája sa"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Tlačidlo prenosu. Pripojené"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Prenos do"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Hľadajú sa zariadenia"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Odpojiť"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Zastaviť prenášanie"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Zavrieť"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Prehrať"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Pozastaviť"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Zastaviť"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Rozbaliť"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Zbaliť"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Obrázok albumu"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Posúvač hlasitosti"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Nie sú vybrané žiadne médiá"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Nie sú k dispozícii žiadne informácie"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Prenáša sa obrazovka"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-sl/strings.xml b/packages/MediaComponents/res/values-sl/strings.xml
deleted file mode 100644
index 8ca4ce4..0000000
--- a/packages/MediaComponents/res/values-sl/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Sistem"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Naprave"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Gumb za predvajanje"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Gumb za predvajanje. Povezava je prekinjena."</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Gumb za predvajanje. Vzpostavljanje povezave."</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Gumb za predvajanje. Povezava je vzpostavljena."</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Predvajanje prek:"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Iskanje naprav"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Prekini povezavo"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Ustavi predvajanje"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Zapri"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Predvajanje"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Zaustavi"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Ustavi"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Razširi"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Strni"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Naslovnica albuma"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Drsnik za glasnost"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Ni izbrane predstavnosti"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Podatki niso na voljo"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Predvajanje zaslona"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-sq/strings.xml b/packages/MediaComponents/res/values-sq/strings.xml
deleted file mode 100644
index 816e110..0000000
--- a/packages/MediaComponents/res/values-sq/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Sistemi"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Pajisjet"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Butoni i transmetimit"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Butoni i transmetimit. Je i shkëputur"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Butoni i transmetimit. Po lidhet"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Butoni i transmetimit. Je i lidhur"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Transmeto te"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Po kërkon pajisje"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Shkëpute"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Ndalo transmetimin"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Mbyll"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Luaj"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Pauzë"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Ndalo"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Zgjeroje"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Palose"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Kopertina e albumit"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Rrëshqitësi i volumit"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Nuk u zgjodh asnjë media"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Nuk jepet asnjë informacion"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Po transmeton ekranin"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-sr/strings.xml b/packages/MediaComponents/res/values-sr/strings.xml
deleted file mode 100644
index caabad5..0000000
--- a/packages/MediaComponents/res/values-sr/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Систем"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Уређаји"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Дугме Пребаци"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Дугме Пребаци. Веза је прекинута"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Дугме Пребаци. Повезује се"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Дугме Пребаци. Повезан је"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Пребацуј на"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Проналажење уређаја"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Прекини везу"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Заустави пребацивање"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Затвори"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Пусти"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Паузирај"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Заустави"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Прошири"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Скупи"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Омот албума"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Клизач за јачину звука"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Нема изабраних медија"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Нису доступне никакве информације"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Пребацује се екран"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-sv/strings.xml b/packages/MediaComponents/res/values-sv/strings.xml
deleted file mode 100644
index ca7d3e0..0000000
--- a/packages/MediaComponents/res/values-sv/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Enheter"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Cast-knappen"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Cast-knappen. Frånkopplad"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Cast-knappen. Ansluter"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Cast-knappen. Ansluten"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Casta till"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Letar efter enheter"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Koppla från"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Sluta casta"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Stäng"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Spela upp"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Pausa"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Avbryt"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Utöka"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Komprimera"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Skivomslag"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Volymreglage"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Inga media har valts"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Det finns ingen information"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Skärmen castas"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-sw/strings.xml b/packages/MediaComponents/res/values-sw/strings.xml
deleted file mode 100644
index 9562cb1..0000000
--- a/packages/MediaComponents/res/values-sw/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Mfumo"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Vifaa"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Kitufe cha kutuma"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Kitufe cha kutuma. Kimeondolewa"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Kitufe cha kutuma. Kinaunganisha"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Kitufe cha kutuma. Kimeunganishwa"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Tuma kwenye"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Inatafuta vifaa"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Ondoa"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Acha kutuma"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Funga"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Cheza"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Sitisha"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Simamisha"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Panua"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Kunja"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Sanaa ya albamu"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Kitelezi cha sauti"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Hakuna maudhui yaliyochaguliwa"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Hakuna maelezo yaliyopatikana"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Inatuma skrini"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-sw600dp/dimens.xml b/packages/MediaComponents/res/values-sw600dp/dimens.xml
deleted file mode 100644
index 4042348..0000000
--- a/packages/MediaComponents/res/values-sw600dp/dimens.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <!-- The platform's desired fixed width for a dialog along the major axis
-         (the screen is in landscape). This may be either a fraction or a dimension.-->
-    <item type="dimen" name="mr_dialog_fixed_width_major">60%</item>
-    <!-- The platform's desired fixed width for a dialog along the minor axis
-         (the screen is in portrait). This may be either a fraction or a dimension.-->
-    <item type="dimen" name="mr_dialog_fixed_width_minor">90%</item>
-</resources>
diff --git a/packages/MediaComponents/res/values-sw720dp/dimens.xml b/packages/MediaComponents/res/values-sw720dp/dimens.xml
deleted file mode 100644
index 634ab8d..0000000
--- a/packages/MediaComponents/res/values-sw720dp/dimens.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <!-- The platform's desired fixed width for a dialog along the major axis
-         (the screen is in landscape). This may be either a fraction or a dimension.-->
-    <item type="dimen" name="mr_dialog_fixed_width_major">50%</item>
-    <!-- The platform's desired fixed width for a dialog along the minor axis
-         (the screen is in portrait). This may be either a fraction or a dimension.-->
-    <item type="dimen" name="mr_dialog_fixed_width_minor">70%</item>
-</resources>
diff --git a/packages/MediaComponents/res/values-ta/strings.xml b/packages/MediaComponents/res/values-ta/strings.xml
deleted file mode 100644
index e1978f3..0000000
--- a/packages/MediaComponents/res/values-ta/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"சிஸ்டம்"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"சாதனங்கள்"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"திரையிடு பட்டன்"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"அனுப்புதல் பொத்தான். துண்டிக்கப்பட்டது"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"அனுப்புதல் பொத்தான். இணைக்கிறது"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"அனுப்புதல் பொத்தான். இணைக்கப்பட்டது"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"இதற்கு அனுப்பு"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"சாதனங்களைத் தேடுகிறது"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"தொடர்பைத் துண்டி"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"அனுப்புவதை நிறுத்து"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"மூடும்"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"இயக்கும்"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"இடைநிறுத்தும்"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"நிறுத்துவதற்கான பொத்தான்"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"விரிவாக்கு"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"சுருக்கு"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"ஆல்பம் ஆர்ட்"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"ஒலியளவு ஸ்லைடர்"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"மீடியா எதுவும் தேர்ந்தெடுக்கப்படவில்லை"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"தகவல் எதுவுமில்லை"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"திரையை அனுப்புகிறீர்கள்"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-te/strings.xml b/packages/MediaComponents/res/values-te/strings.xml
deleted file mode 100644
index 7d312e3..0000000
--- a/packages/MediaComponents/res/values-te/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"సిస్టమ్"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"పరికరాలు"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"ప్రసారం చేయి బటన్"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"ప్రసార బటన్. డిస్‌కనెక్ట్ చేయబడింది"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"ప్రసార బటన్. కనెక్ట్ చేస్తోంది"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"ప్రసార బటన్. కనెక్ట్ చేయబడింది"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"దీనికి ప్రసారం చేయండి"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"పరికరాలను కనుగొంటోంది"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"డిస్‌కనెక్ట్ చేయి"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"ప్రసారాన్ని ఆపివేయి"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"మూసివేస్తుంది"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"ప్లే చేస్తుంది"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"పాజ్ చేస్తుంది"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"ఆపివేయి"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"విస్తరింపజేస్తుంది"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"కుదిస్తుంది"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"ఆల్బమ్ ఆర్ట్"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"వాల్యూమ్ స్లయిడర్"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"మీడియా ఏదీ ఎంచుకోబడలేదు"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"సమాచారం అందుబాటులో లేదు"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"స్క్రీన్‌ను ప్రసారం చేస్తోంది"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-th/strings.xml b/packages/MediaComponents/res/values-th/strings.xml
deleted file mode 100644
index cfa8ae5..0000000
--- a/packages/MediaComponents/res/values-th/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"ระบบ"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"อุปกรณ์"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"ปุ่ม \"แคสต์\""</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"ปุ่ม \"แคสต์\" ยกเลิกการเชื่อมต่อ"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"ปุ่ม \"แคสต์\" กำลังเชื่อมต่อ"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"ปุ่ม \"แคสต์\" เชื่อมต่อแล้ว"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"แคสต์ไปยัง"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"กำลังค้นหาอุปกรณ์"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"ยกเลิกการเชื่อมต่อ"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"หยุดแคสต์"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"ปิด"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"เล่น"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"หยุดชั่วคราว"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"หยุด"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"ขยาย"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"ยุบ"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"ปกอัลบั้ม"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"แถบเลื่อนปรับระดับเสียง"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"ไม่ได้เลือกสื่อไว้"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"ไม่มีข้อมูล"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"กำลังแคสต์หน้าจอ"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-tl/strings.xml b/packages/MediaComponents/res/values-tl/strings.xml
deleted file mode 100644
index a8be3d0..0000000
--- a/packages/MediaComponents/res/values-tl/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Mga Device"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Button na I-cast"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Button na I-cast. Nadiskonekta"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Button na I-cast. Kumokonekta"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Button na I-cast. Nakakonekta"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"I-cast sa"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Naghahanap ng mga device"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Idiskonekta"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Ihinto ang pag-cast"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Isara"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"I-play"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"I-pause"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Ihinto"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Palawakin"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"I-collapse"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Album art"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Slider ng volume"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Walang piniling media"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Walang available na impormasyon"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Kina-cast ang screen"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-tr/strings.xml b/packages/MediaComponents/res/values-tr/strings.xml
deleted file mode 100644
index 05f6392..0000000
--- a/packages/MediaComponents/res/values-tr/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Sistem"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Cihazlar"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Yayınla düğmesi"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Yayınla düğmesi. Bağlantı kesildi"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Yayınla düğmesi. Bağlanıyor"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Yayınla düğmesi. Bağlandı"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Şuraya yayınla:"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Cihazlar bulunuyor"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Bağlantıyı kes"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Yayını durdur"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Kapat"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Oynat"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Duraklat"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Durdur"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Genişlet"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Daralt"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Albüm kapağı"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Ses düzeyi kaydırma çubuğu"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Medya seçilmedi"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Bilgi yok"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Ekran yayınlanıyor"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-uk/strings.xml b/packages/MediaComponents/res/values-uk/strings.xml
deleted file mode 100644
index 33d365e..0000000
--- a/packages/MediaComponents/res/values-uk/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Система"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Пристрої"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Кнопка трансляції"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Кнопка трансляції. Від’єднано"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Кнопка трансляції. Під’єднання"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Кнопка трансляції. Під’єднано"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Транслювати на"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Пошук пристроїв"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Відключити"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Припинити трансляцію"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Закрити"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Відтворити"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Призупинити"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Припинити"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Розгорнути"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Згорнути"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Обкладинка альбому"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Повзунок гучності"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Медіа-файл не вибрано"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Немає даних"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Трансляція екрана"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-ur/strings.xml b/packages/MediaComponents/res/values-ur/strings.xml
deleted file mode 100644
index 632c598..0000000
--- a/packages/MediaComponents/res/values-ur/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"سسٹم"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"آلات"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"کاسٹ کرنے کا بٹن"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"کاسٹ کرنے کا بٹن۔ غیر منسلک ہے"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"کاسٹ کرنے کا بٹن۔ منسلک ہو رہا ہے"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"کاسٹ کرنے کا بٹن۔ منسلک ہے"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"اس میں کاسٹ کریں"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"آلات تلاش ہو رہے ہیں"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"غیر منسلک کریں"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"کاسٹ کرنا بند کریں"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"بند کریں"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"چلائیں"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"موقوف کریں"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"روکیں"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"پھیلائیں"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"سکیڑیں"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"البم آرٹ"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"والیوم سلائیڈر"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"کوئی میڈیا منتخب نہیں ہے"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"کوئی معلومات دستیاب نہیں"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"سکرین کاسٹ ہو رہی ہے"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-uz/strings.xml b/packages/MediaComponents/res/values-uz/strings.xml
deleted file mode 100644
index 10a0817..0000000
--- a/packages/MediaComponents/res/values-uz/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Tizim"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Qurilmalar"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Translatsiya tugmasi"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Translatsiya tugmasi. Uzildi"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Translatsiya tugmasi. Ulanmoqda"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Translatsiya tugmasi. Ulandi"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Quyidagiga translatsiya qilish:"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Qurilmalarni topish"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Ulanishni uzish"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Translatsiyani to‘xtatish"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Yopish"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Boshlash"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"To‘xtatib turish"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"To‘xtatish"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Yoyish"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Yig‘ish"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Albom muqovasi"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Tovush balandligi slayderi"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Multimedia tanlamagan"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Hech qanday ma’lumot yo‘q"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Ekranni translatsiya qilish"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-vi/strings.xml b/packages/MediaComponents/res/values-vi/strings.xml
deleted file mode 100644
index 7098cca..0000000
--- a/packages/MediaComponents/res/values-vi/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Hệ thống"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Thiết bị"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Nút truyền"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Nút truyền. Đã ngắt kết nối"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Nút truyền. Đang kết nối"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Nút truyền. Đã kết nối"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Truyền tới"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Đang tìm thiết bị"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Ngắt kết nối"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Dừng truyền"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Đóng"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Phát"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Tạm dừng"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Dừng"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Mở rộng"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Thu gọn"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Ảnh bìa album"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Thanh trượt âm lượng"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Không có phương tiện nào được chọn"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Không có thông tin nào"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Đang truyền màn hình"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-zh-rCN/strings.xml b/packages/MediaComponents/res/values-zh-rCN/strings.xml
deleted file mode 100644
index 1e22d01..0000000
--- a/packages/MediaComponents/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"系统"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"设备"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"投射按钮"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"投射按钮。已断开连接"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"投射按钮。正在连接"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"投射按钮。已连接"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"投射到"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"正在查找设备"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"断开连接"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"停止投射"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"关闭"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"播放"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"暂停"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"停止"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"展开"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"收起"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"专辑封面"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"音量滑块"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"未选择任何媒体"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"没有任何相关信息"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"正在投射屏幕"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-zh-rHK/strings.xml b/packages/MediaComponents/res/values-zh-rHK/strings.xml
deleted file mode 100644
index 156e5c2..0000000
--- a/packages/MediaComponents/res/values-zh-rHK/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"系統"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"裝置"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"投放按鈕"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"投放按鈕。已解除連接"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"投放按鈕。正在連接"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"投放按鈕。已連接"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"投放至"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"正在尋找裝置"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"中斷連線"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"停止投放"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"關閉"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"播放"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"暫停"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"停止"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"展開"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"收合"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"專輯封面"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"音量滑桿"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"尚未選擇媒體"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"沒有詳細資料"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"正在投放螢幕"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-zh-rTW/strings.xml b/packages/MediaComponents/res/values-zh-rTW/strings.xml
deleted file mode 100644
index 6cafde1..0000000
--- a/packages/MediaComponents/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"系統"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"裝置"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"投放按鈕"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"投放按鈕;已中斷連線"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"投放按鈕;連線中"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"投放按鈕;已連線"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"投放到"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"正在尋找裝置"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"中斷連線"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"停止投放"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"關閉"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"播放"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"暫停"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"停止"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"展開"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"收合"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"專輯封面"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"音量滑桿"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"未選取任何媒體"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"沒有可用的資訊"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"正在投放螢幕"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values-zu/strings.xml b/packages/MediaComponents/res/values-zu/strings.xml
deleted file mode 100644
index e107c43..0000000
--- a/packages/MediaComponents/res/values-zu/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="5441529851481176817">"Isistimu"</string>
-    <string name="mr_user_route_category_name" msgid="7498112907524977311">"Amadivayisi"</string>
-    <string name="mr_button_content_description" msgid="3698378085901466129">"Inkinobho ye-Cast"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Inkinobho yokusakaza. Kunqanyuliwe"</string>
-    <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Inkinobho yokusakaza. Kuyaxhunywa"</string>
-    <string name="mr_cast_button_connected" msgid="5088427771788648085">"Inkinobho yokusakaza. Kuxhunyiwe"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Sakaza ku-"</string>
-    <string name="mr_chooser_searching" msgid="6349900579507521956">"Ithola amadivayisi"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"Nqamula"</string>
-    <string name="mr_controller_stop_casting" msgid="8857886794086583226">"Misa ukusakaza"</string>
-    <string name="mr_controller_close_description" msgid="7333862312480583260">"Vala"</string>
-    <string name="mr_controller_play" msgid="683634565969987458">"Dlala"</string>
-    <string name="mr_controller_pause" msgid="5451884435510905406">"Misa isikhashana"</string>
-    <string name="mr_controller_stop" msgid="735874641921425123">"Misa"</string>
-    <string name="mr_controller_expand_group" msgid="8062427022744266907">"Nweba"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"Goqa"</string>
-    <string name="mr_controller_album_art" msgid="6422801843540543585">"Ubuciko be-albhamu"</string>
-    <string name="mr_controller_volume_slider" msgid="2361785992211841709">"Isilayida sevolumu"</string>
-    <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"Ayikho imidiya ekhethiwe"</string>
-    <string name="mr_controller_no_info_available" msgid="5585418471741142924">"Alukho ulwazi olutholakalayo"</string>
-    <string name="mr_controller_casting_screen" msgid="4868457957151124867">"Isikrini sokusakaza"</string>
-</resources>
diff --git a/packages/MediaComponents/res/values/arrays.xml b/packages/MediaComponents/res/values/arrays.xml
deleted file mode 100644
index 1187320..0000000
--- a/packages/MediaComponents/res/values/arrays.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <integer-array name="speed_multiplied_by_100">
-        <item>25</item>
-        <item>50</item>
-        <item>75</item>
-        <item>100</item>
-        <item>125</item>
-        <item>150</item>
-        <item>200</item>
-    </integer-array>
-</resources>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/values/attrs.xml b/packages/MediaComponents/res/values/attrs.xml
deleted file mode 100644
index e37285b..0000000
--- a/packages/MediaComponents/res/values/attrs.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <declare-styleable name="MediaRouteButton">
-        <!-- This drawable is a state list where the "checked" state
-             indicates active media routing.  Checkable indicates connecting
-             and non-checked / non-checkable indicates
-             that media is playing to the local device only. -->
-        <attr name="externalRouteEnabledDrawable" format="reference" />
-        <!-- Tint to apply to the media route button -->
-        <attr name="mediaRouteButtonTint" format="color" />
-
-        <attr name="android:minWidth" />
-        <attr name="android:minHeight" />
-    </declare-styleable>
-
-    <attr name="mediaRouteButtonStyle" format="reference" />
-    <attr name="mediaRouteCloseDrawable" format="reference" />
-    <attr name="mediaRoutePlayDrawable" format="reference" />
-    <attr name="mediaRoutePauseDrawable" format="reference" />
-    <attr name="mediaRouteStopDrawable" format="reference" />
-    <attr name="mediaRouteAudioTrackDrawable" format="reference" />
-    <attr name="mediaRouteDefaultIconDrawable" format="reference" />
-    <attr name="mediaRouteTvIconDrawable" format="reference" />
-    <attr name="mediaRouteSpeakerIconDrawable" format="reference" />
-    <attr name="mediaRouteSpeakerGroupIconDrawable" format="reference" />
-    <attr name="mediaRouteControlPanelThemeOverlay" format="reference" />
-
-    <attr name="mediaRouteTheme" format="reference" />
-</resources>
diff --git a/packages/MediaComponents/res/values/colors.xml b/packages/MediaComponents/res/values/colors.xml
deleted file mode 100644
index e7bc299..0000000
--- a/packages/MediaComponents/res/values/colors.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <color name="gray">#808080</color>
-    <color name="white">#ffffff</color>
-    <color name="white_opacity_70">#B3ffffff</color>
-    <color name="black_opacity_70">#B3000000</color>
-    <color name="title_bar_gradient_start">#50000000</color>
-    <color name="title_bar_gradient_end">#00000000</color>
-    <color name="bottom_bar_background">#40202020</color>
-</resources>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/values/dimens.xml b/packages/MediaComponents/res/values/dimens.xml
deleted file mode 100644
index 2d7b022..0000000
--- a/packages/MediaComponents/res/values/dimens.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <!-- Dialog size -->
-    <eat-comment />
-    <!-- The platform's desired fixed width for a dialog along the major axis
-         (the screen is in landscape). This may be either a fraction or a dimension.-->
-    <dimen name="mr_dialog_fixed_width_major">320dp</dimen>
-    <!-- The platform's desired fixed width for a dialog along the minor axis
-         (the screen is in portrait). This may be either a fraction or a dimension.-->
-    <dimen name="mr_dialog_fixed_width_minor">320dp</dimen>
-
-    <!-- MediaRouteController's volume group list -->
-    <eat-comment />
-    <!-- Maximum height of volume group list. -->
-    <dimen name="mr_controller_volume_group_list_max_height">288dp</dimen>
-    <!-- Height of volume group item. -->
-    <dimen name="mr_controller_volume_group_list_item_height">68dp</dimen>
-    <!-- Size of an item's icon. -->
-    <dimen name="mr_controller_volume_group_list_item_icon_size">24dp</dimen>
-
-    <dimen name="mr_controller_volume_group_list_padding_top">16dp</dimen>
-    <!-- Group list expand/collapse animation duration. -->
-    <integer name="mr_controller_volume_group_list_animation_duration_ms">400</integer>
-    <!-- Group list fade in animation duration. -->
-    <integer name="mr_controller_volume_group_list_fade_in_duration_ms">400</integer>
-    <!-- Group list fade out animation duration. -->
-    <integer name="mr_controller_volume_group_list_fade_out_duration_ms">200</integer>
-
-    <dimen name="mcv2_embedded_settings_width">150dp</dimen>
-    <dimen name="mcv2_embedded_settings_height">36dp</dimen>
-    <dimen name="mcv2_embedded_settings_icon_size">20dp</dimen>
-    <dimen name="mcv2_embedded_settings_text_height">18dp</dimen>
-    <dimen name="mcv2_embedded_settings_main_text_size">12sp</dimen>
-    <dimen name="mcv2_embedded_settings_sub_text_size">10sp</dimen>
-    <dimen name="mcv2_full_settings_width">225dp</dimen>
-    <dimen name="mcv2_full_settings_height">54dp</dimen>
-    <dimen name="mcv2_full_settings_icon_size">30dp</dimen>
-    <dimen name="mcv2_full_settings_text_height">27dp</dimen>
-    <dimen name="mcv2_full_settings_main_text_size">16sp</dimen>
-    <dimen name="mcv2_full_settings_sub_text_size">13sp</dimen>
-    <dimen name="mcv2_settings_offset">8dp</dimen>
-
-    <dimen name="mcv2_transport_controls_padding">4dp</dimen>
-    <dimen name="mcv2_pause_icon_size">36dp</dimen>
-    <dimen name="mcv2_full_icon_size">28dp</dimen>
-    <dimen name="mcv2_embedded_icon_size">24dp</dimen>
-    <dimen name="mcv2_minimal_icon_size">24dp</dimen>
-    <dimen name="mcv2_icon_margin">10dp</dimen>
-
-    <dimen name="mcv2_full_album_image_portrait_size">232dp</dimen>
-    <dimen name="mcv2_full_album_image_landscape_size">176dp</dimen>
-
-    <dimen name="mcv2_custom_progress_max_size">2dp</dimen>
-    <dimen name="mcv2_custom_progress_thumb_size">12dp</dimen>
-    <dimen name="mcv2_buffer_view_height">5dp</dimen>
-    <!-- TODO: adjust bottom bar view -->
-</resources>
diff --git a/packages/MediaComponents/res/values/strings.xml b/packages/MediaComponents/res/values/strings.xml
deleted file mode 100644
index 2597a3b..0000000
--- a/packages/MediaComponents/res/values/strings.xml
+++ /dev/null
@@ -1,157 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
-    <!-- Name for the default system route prior to Jellybean. [CHAR LIMIT=30] -->
-    <string name="mr_system_route_name">System</string>
-
-    <!-- Name for the user route category created when publishing routes to the system in Jellybean and above. [CHAR LIMIT=30] -->
-    <string name="mr_user_route_category_name">Devices</string>
-
-    <!-- String to be shown as a tooltip of MediaRouteButton
-        Cast is the standard android verb for sending content to a remote device. [CHAR LIMIT=50] -->
-    <string name="mr_button_content_description">Cast button</string>
-
-    <!-- Content description of a MediaRouteButton for accessibility support when no remote device is connected.
-        Cast is the standard android verb for sending content to a remote device. [CHAR LIMIT=NONE] -->
-    <string name="mr_cast_button_disconnected">Cast button. Disconnected</string>
-
-    <!-- Content description of a MediaRouteButton for accessibility support while connecting to a remote device.
-        Cast is the standard android verb for sending content to a remote device. [CHAR LIMIT=NONE] -->
-    <string name="mr_cast_button_connecting">Cast button. Connecting</string>
-
-    <!-- Content description of a MediaRouteButton for accessibility support when a remote device is connected.
-        Cast is the standard android verb for sending content to a remote device. [CHAR LIMIT=NONE] -->
-    <string name="mr_cast_button_connected">Cast button. Connected</string>
-
-    <!-- Title of the media route chooser dialog. [CHAR LIMIT=30] -->
-    <string name="mr_chooser_title">Cast to</string>
-
-    <!-- Placeholder text to show when no devices have been found. [CHAR LIMIT=50] -->
-    <string name="mr_chooser_searching">Finding devices</string>
-
-    <!-- Button to disconnect from a media route.  [CHAR LIMIT=30] -->
-    <string name="mr_controller_disconnect">Disconnect</string>
-
-    <!-- Button to stop playback and disconnect from a media route. [CHAR LIMIT=30] -->
-    <string name="mr_controller_stop_casting">Stop casting</string>
-
-    <!-- Content description for accessibility (not shown on the screen): dialog close button. [CHAR LIMIT=NONE] -->
-    <string name="mr_controller_close_description">Close</string>
-
-    <!-- Content description for accessibility (not shown on the screen): media play button. [CHAR LIMIT=NONE] -->
-    <string name="mr_controller_play">Play</string>
-
-    <!-- Content description for accessibility (not shown on the screen): media pause button. [CHAR LIMIT=NONE] -->
-    <string name="mr_controller_pause">Pause</string>
-
-    <!-- Content description for accessibility (not shown on the screen): media stop button. [CHAR LIMIT=NONE] -->
-    <string name="mr_controller_stop">Stop</string>
-
-    <!-- Content description for accessibility (not shown on the screen): group expand button. Pressing button shows group members of a selected route group. [CHAR LIMIT=NONE] -->
-    <string name="mr_controller_expand_group">Expand</string>
-
-    <!-- Content description for accessibility (not shown on the screen): group collapse button. Pressing button hides group members of a selected route group. [CHAR LIMIT=NONE] -->
-    <string name="mr_controller_collapse_group">Collapse</string>
-
-    <!-- Content description for accessibility (not shown on the screen): album art button. Clicking on the album art takes user to a predefined activity per media app. [CHAR LIMIT=50] -->
-    <string name="mr_controller_album_art">Album art</string>
-
-    <!-- Content description for accessibility (not shown on the screen): volume slider. [CHAR LIMIT=NONE] -->
-    <string name="mr_controller_volume_slider">Volume slider</string>
-
-    <!-- Placeholder text to show when no media have been selected for playback. [CHAR LIMIT=50] -->
-    <string name="mr_controller_no_media_selected">No media selected</string>
-
-    <!-- Placeholder text to show when no title/description have been found for a given song/video. [CHAR LIMIT=50] -->
-    <string name="mr_controller_no_info_available">No info available</string>
-
-    <!-- Placeholder text indicating that the user is currently casting screen. [CHAR LIMIT=50] -->
-    <string name="mr_controller_casting_screen">Casting screen</string>
-
-    <!-- Text for error alert when a video container is not valid for progressive download/playback. -->
-    <string name="VideoView2_error_text_invalid_progressive_playback">This video isn\'t valid for streaming to this device.</string>
-    <!-- Text for error alert when a video cannot be played. It can be used by any app. -->
-    <string name="VideoView2_error_text_unknown">Can\'t play this video.</string>
-    <!-- Button to close error alert when a video cannot be played. -->
-    <string name="VideoView2_error_button">OK</string>
-
-    <!-- Text for displaying ad skip wait time. -->
-    <string name="MediaControlView2_ad_skip_wait_time">
-        You can skip Ad in <xliff:g id="wait_time" example="5">%1$d</xliff:g>s
-    </string>
-    <!-- Text for displaying ad total remaining time. -->
-    <string name="MediaControlView2_ad_remaining_time">
-        Ad · <xliff:g id="remaining_time" example="1:15">%1$s</xliff:g> remaining
-    </string>
-    <!-- Placeholder text indicating that the user can press the button to go to an external website. -->
-    <string name="MediaControlView2_ad_text">Visit Advertiser</string>
-    <string name="MediaControlView2_subtitle_text">Closed caption</string>
-    <string name="MediaControlView2_subtitle_off_text">Off</string>
-    <string name="MediaControlView2_audio_track_text">Audio track</string>
-    <string name="MediaControlView2_audio_track_none_text">None</string>
-    <string name="MediaControlView2_video_quality_text">Video quality</string>
-    <string name="MediaControlView2_video_quality_auto_text">Auto</string>
-    <string name="MediaControlView2_help_text">Help &amp; feedback</string>
-    <string name="MediaControlView2_playback_speed_text">Playback speed</string>
-    <string-array name="MediaControlView2_playback_speeds">
-        <item>0.25x</item>
-        <item>0.5x</item>
-        <item>0.75x</item>
-        <item>Normal</item>
-        <item>1.25x</item>
-        <item>1.5x</item>
-        <item>2x</item>
-    </string-array>
-    <!-- Placeholder text for displaying time. Used to calculate which size layout to use. -->
-    <string name="MediaControlView2_time_placeholder">00:00:00</string>
-
-    <!-- Text for displaying subtitle track number. -->
-    <string name="MediaControlView2_subtitle_track_number_text">
-        Track <xliff:g id="track_number" example="1">%1$s</xliff:g>
-    </string>
-    <!-- Text for displaying audio track number. -->
-    <string name="MediaControlView2_audio_track_number_text">
-        Track <xliff:g id="audio_number" example="1">%1$s</xliff:g>
-    </string>
-    <!-- Text for displaying unknown song title. -->
-    <string name="mcv2_music_title_unknown_text">Song title unknown</string>
-    <!-- Text for displaying unknown artist name. -->
-    <string name="mcv2_music_artist_unknown_text">Artist unknown</string>
-
-    <!--Content Descriptions -->
-    <string name="mcv2_back_button_desc">Back</string>
-    <string name="mcv2_overflow_left_button_desc">See more buttons</string>
-    <string name="mcv2_overflow_right_button_desc">Back to previous button list</string>
-    <string name="mcv2_seek_bar_desc">Playback progress</string>
-    <string name="mcv2_settings_button_desc">Settings</string>
-    <string name="mcv2_video_quality_button_desc">Video Quality Selection</string>
-    <string name="mcv2_cc_is_on">Subtitle is on. Click to hide it.</string>
-    <string name="mcv2_cc_is_off">Subtitle is off. Click to show it.</string>
-    <string name="mcv2_replay_button_desc">Replay</string>
-    <string name="mcv2_play_button_desc">Play</string>
-    <string name="mcv2_pause_button_desc">Pause</string>
-    <string name="mcv2_previous_button_desc">Previous media</string>
-    <string name="mcv2_next_button_desc">Next media</string>
-    <string name="mcv2_rewind_button_desc">Rewind by 10 seconds</string>
-    <string name="mcv2_ffwd_button_desc">Go forward by 30 seconds</string>
-    <string name="mcv2_launch_button_desc">Launch Link</string>
-    <string name="mcv2_muted_button_desc">Muted. Click to unmute</string>
-    <string name="mcv2_unmuted_button_desc">Click to Mute</string>
-    <string name="mcv2_full_screen_button_desc">Full screen</string>
-</resources>
diff --git a/packages/MediaComponents/res/values/style.xml b/packages/MediaComponents/res/values/style.xml
deleted file mode 100644
index 5b9a8ee..0000000
--- a/packages/MediaComponents/res/values/style.xml
+++ /dev/null
@@ -1,221 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <style name="FullTransportControlsButton">
-        <item name="android:background">@null</item>
-        <item name="android:layout_margin">@dimen/mcv2_icon_margin</item>
-        <item name="android:scaleType">fitXY</item>
-    </style>
-
-    <style name="FullTransportControlsButton.Previous">
-        <item name="android:src">@drawable/ic_skip_previous</item>
-        <item name="android:layout_width">@dimen/mcv2_full_icon_size</item>
-        <item name="android:layout_height">@dimen/mcv2_full_icon_size</item>
-        <item name="android:contentDescription">@string/mcv2_previous_button_desc</item>
-    </style>
-
-    <style name="FullTransportControlsButton.Next">
-        <item name="android:src">@drawable/ic_skip_next</item>
-        <item name="android:layout_width">@dimen/mcv2_full_icon_size</item>
-        <item name="android:layout_height">@dimen/mcv2_full_icon_size</item>
-        <item name="android:contentDescription">@string/mcv2_next_button_desc</item>
-    </style>
-
-    <style name="FullTransportControlsButton.Pause">
-        <item name="android:src">@drawable/ic_pause_circle_filled</item>
-        <item name="android:layout_width">@dimen/mcv2_pause_icon_size</item>
-        <item name="android:layout_height">@dimen/mcv2_pause_icon_size</item>
-        <item name="android:contentDescription">@string/mcv2_pause_button_desc</item>
-    </style>
-
-    <style name="FullTransportControlsButton.Ffwd">
-        <item name="android:src">@drawable/ic_forward_30</item>
-        <item name="android:layout_width">@dimen/mcv2_full_icon_size</item>
-        <item name="android:layout_height">@dimen/mcv2_full_icon_size</item>
-        <item name="android:contentDescription">@string/mcv2_ffwd_button_desc</item>
-    </style>
-
-    <style name="FullTransportControlsButton.Rew">
-        <item name="android:src">@drawable/ic_rewind_10</item>
-        <item name="android:layout_width">@dimen/mcv2_full_icon_size</item>
-        <item name="android:layout_height">@dimen/mcv2_full_icon_size</item>
-        <item name="android:contentDescription">@string/mcv2_rewind_button_desc</item>
-    </style>
-
-    <style name="EmbeddedTransportControlsButton">
-        <item name="android:background">@null</item>
-        <item name="android:layout_margin">@dimen/mcv2_icon_margin</item>
-        <item name="android:scaleType">fitXY</item>
-    </style>
-
-    <style name="EmbeddedTransportControlsButton.Previous">
-        <item name="android:src">@drawable/ic_skip_previous</item>
-        <item name="android:layout_width">@dimen/mcv2_embedded_icon_size</item>
-        <item name="android:layout_height">@dimen/mcv2_embedded_icon_size</item>
-        <item name="android:contentDescription">@string/mcv2_previous_button_desc</item>
-    </style>
-
-    <style name="EmbeddedTransportControlsButton.Next">
-        <item name="android:src">@drawable/ic_skip_next</item>
-        <item name="android:layout_width">@dimen/mcv2_embedded_icon_size</item>
-        <item name="android:layout_height">@dimen/mcv2_embedded_icon_size</item>
-        <item name="android:contentDescription">@string/mcv2_next_button_desc</item>
-    </style>
-
-    <style name="EmbeddedTransportControlsButton.Pause">
-        <item name="android:src">@drawable/ic_pause_circle_filled</item>
-        <item name="android:layout_width">@dimen/mcv2_pause_icon_size</item>
-        <item name="android:layout_height">@dimen/mcv2_pause_icon_size</item>
-        <item name="android:contentDescription">@string/mcv2_pause_button_desc</item>
-    </style>
-
-    <style name="EmbeddedTransportControlsButton.Ffwd">
-        <item name="android:src">@drawable/ic_forward_30</item>
-        <item name="android:layout_width">@dimen/mcv2_embedded_icon_size</item>
-        <item name="android:layout_height">@dimen/mcv2_embedded_icon_size</item>
-        <item name="android:contentDescription">@string/mcv2_ffwd_button_desc</item>
-    </style>
-
-    <style name="EmbeddedTransportControlsButton.Rew">
-        <item name="android:src">@drawable/ic_rewind_10</item>
-        <item name="android:layout_width">@dimen/mcv2_embedded_icon_size</item>
-        <item name="android:layout_height">@dimen/mcv2_embedded_icon_size</item>
-        <item name="android:contentDescription">@string/mcv2_rewind_button_desc</item>
-    </style>
-
-    <style name="MinimalTransportControlsButton">
-        <item name="android:background">@null</item>
-        <item name="android:layout_width">@dimen/mcv2_pause_icon_size</item>
-        <item name="android:layout_height">@dimen/mcv2_pause_icon_size</item>
-        <item name="android:layout_margin">@dimen/mcv2_icon_margin</item>
-        <item name="android:scaleType">fitXY</item>
-        <item name="android:src">@drawable/ic_pause_circle_filled</item>
-        <item name="android:contentDescription">@string/mcv2_pause_button_desc</item>
-    </style>
-
-    <style name="TitleBar">
-        <item name="android:layout_width">match_parent</item>
-        <item name="android:layout_height">46dp</item>
-        <item name="android:paddingStart">5dp</item>
-        <item name="android:paddingEnd">5dp</item>
-    </style>
-
-    <style name="TitleBarButton">
-        <item name="android:background">@null</item>
-        <item name="android:layout_width">36dp</item>
-        <item name="android:layout_height">36dp</item>
-    </style>
-
-    <style name="TitleBarButton.Back">
-        <item name="android:src">@drawable/ic_arrow_back</item>
-        <item name="android:contentDescription">@string/mcv2_back_button_desc</item>
-    </style>
-
-    <style name="TitleBarButton.Launch">
-        <item name="android:src">@drawable/ic_launch</item>
-        <item name="android:contentDescription">@string/mcv2_launch_button_desc</item>
-    </style>
-
-    <style name="TimeText">
-        <item name="android:layout_width">wrap_content</item>
-        <item name="android:layout_height">wrap_content</item>
-        <item name="android:paddingStart">4dp</item>
-        <item name="android:paddingEnd">4dp</item>
-        <item name="android:textStyle">bold</item>
-        <item name="android:textSize">14sp</item>
-        <item name="android:gravity">center</item>
-    </style>
-
-    <style name="TimeText.Current">
-        <item name="android:textColor">@color/white</item>
-        <item name="android:text">@string/MediaControlView2_time_placeholder</item>
-    </style>
-
-    <style name="TimeText.Interpunct">
-        <item name="android:textColor">@color/white_opacity_70</item>
-        <item name="android:text">·</item>
-    </style>
-
-    <style name="TimeText.End">
-        <item name="android:textColor">@color/white_opacity_70</item>
-        <item name="android:text">@string/MediaControlView2_time_placeholder</item>
-    </style>
-
-    <style name="BottomBarButton">
-        <item name="android:background">@null</item>
-        <item name="android:layout_width">@dimen/mcv2_embedded_icon_size</item>
-        <item name="android:layout_height">@dimen/mcv2_embedded_icon_size</item>
-        <item name="android:layout_margin">@dimen/mcv2_icon_margin</item>
-        <item name="android:gravity">center_horizontal</item>
-        <item name="android:scaleType">fitXY</item>
-    </style>
-
-    <style name="BottomBarButton.CC">
-        <item name="android:src">@drawable/ic_subtitle_off</item>
-        <item name="android:contentDescription">@string/mcv2_cc_is_off</item>
-    </style>
-
-    <style name="BottomBarButton.FullScreen">
-        <item name="android:src">@drawable/ic_fullscreen</item>
-        <item name="android:contentDescription">@string/mcv2_full_screen_button_desc</item>
-    </style>
-
-    <style name="BottomBarButton.OverflowRight">
-        <item name="android:src">@drawable/ic_chevron_right</item>
-        <item name="android:contentDescription">@string/mcv2_overflow_right_button_desc</item>
-    </style>
-
-    <style name="BottomBarButton.OverflowLeft">
-        <item name="android:src">@drawable/ic_chevron_left</item>
-        <item name="android:contentDescription">@string/mcv2_overflow_left_button_desc</item>
-    </style>
-
-    <style name="BottomBarButton.Settings">
-        <item name="android:src">@drawable/ic_settings</item>
-        <item name="android:contentDescription">@string/mcv2_settings_button_desc</item>
-    </style>
-
-    <style name="BottomBarButton.Mute">
-        <item name="android:src">@drawable/ic_unmute</item>
-        <item name="android:contentDescription">@string/mcv2_unmuted_button_desc</item>
-    </style>
-
-    <style name="BottomBarButton.VideoQuality">
-      <item name="android:src">@drawable/ic_high_quality</item>
-      <item name="android:contentDescription">@string/mcv2_video_quality_button_desc</item>
-    </style>
-
-    <style name="FullMusicPortrait">
-        <item name="android:layout_height">0dp</item>
-    </style>
-
-    <style name="FullMusicPortrait.Image">
-        <item name="android:layout_width">match_parent</item>
-        <item name="android:layout_weight">0.6</item>
-        <item name="android:gravity">center</item>
-    </style>
-
-    <style name="FullMusicPortrait.Text">
-        <item name="android:layout_width">match_parent</item>
-        <item name="android:layout_weight">0.4</item>
-        <item name="android:gravity">top|center</item>
-        <item name="android:orientation">vertical</item>
-    </style>
-
-    <style name="FullMusicLandscape">
-        <item name="android:layout_width">0dp</item>
-    </style>
-
-    <style name="FullMusicLandscape.Image">
-        <item name="android:layout_height">match_parent</item>
-        <item name="android:layout_weight">0.35</item>
-        <item name="android:gravity">center|right</item>
-    </style>
-
-    <style name="FullMusicLandscape.Text">
-        <item name="android:layout_height">match_parent</item>
-        <item name="android:layout_weight">0.65</item>
-        <item name="android:layout_marginLeft">24dp</item>
-        <item name="android:gravity">center|left</item>
-        <item name="android:orientation">vertical</item>
-    </style>
-</resources>
diff --git a/packages/MediaComponents/res/values/styles.xml b/packages/MediaComponents/res/values/styles.xml
deleted file mode 100644
index bde6900..0000000
--- a/packages/MediaComponents/res/values/styles.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <style name="Widget.MediaRouter.MediaRouteButton"
-            parent="Widget.AppCompat.ActionButton">
-        <item name="externalRouteEnabledDrawable">@drawable/mr_button_dark</item>
-    </style>
-
-    <style name="Widget.MediaRouter.Light.MediaRouteButton"
-            parent="Widget.AppCompat.Light.ActionButton">
-        <item name="externalRouteEnabledDrawable">@drawable/mr_button_light</item>
-    </style>
-
-    <style name="TextAppearance.MediaRouter.Title" parent="TextAppearance.AppCompat.Title" />
-
-    <style name="TextAppearance.MediaRouter.PrimaryText" parent="TextAppearance.AppCompat.Subhead" />
-
-    <style name="TextAppearance.MediaRouter.SecondaryText" parent="TextAppearance.AppCompat.Body1" />
-</resources>
diff --git a/packages/MediaComponents/res/values/symbols.xml b/packages/MediaComponents/res/values/symbols.xml
deleted file mode 100644
index ee0e8c6..0000000
--- a/packages/MediaComponents/res/values/symbols.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* Copyright 2017, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<resources>
-    <!--java-symbol type="id" name="cc" />
-    <java-symbol type="id" name="ffwd" />
-    <java-symbol type="id" name="mediacontroller_progress" />
-    <java-symbol type="id" name="next" />
-    <java-symbol type="id" name="pause" />
-    <java-symbol type="id" name="prev" />
-    <java-symbol type="id" name="rew" />
-    <java-symbol type="id" name="time" />
-    <java-symbol type="id" name="time_current" /-->
-</resources>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/values/themes.xml b/packages/MediaComponents/res/values/themes.xml
deleted file mode 100644
index d9a754b..0000000
--- a/packages/MediaComponents/res/values/themes.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-
-    <style name="Theme.MediaRouter" parent="android:Theme.Material">
-        <item name="android:windowNoTitle">true</item>
-        <item name="mediaRouteButtonStyle">@style/Widget.MediaRouter.MediaRouteButton</item>
-
-        <item name="mediaRouteCloseDrawable">@drawable/mr_dialog_close_dark</item>
-        <item name="mediaRoutePlayDrawable">@drawable/mr_media_play_dark</item>
-        <item name="mediaRoutePauseDrawable">@drawable/mr_media_pause_dark</item>
-        <item name="mediaRouteStopDrawable">@drawable/mr_media_stop_dark</item>
-        <item name="mediaRouteAudioTrackDrawable">@drawable/mr_vol_type_audiotrack_dark</item>
-        <item name="mediaRouteDefaultIconDrawable">@drawable/ic_mr_button_disconnected_dark</item>
-        <item name="mediaRouteTvIconDrawable">@drawable/ic_vol_type_tv_dark</item>
-        <item name="mediaRouteSpeakerIconDrawable">@drawable/ic_vol_type_speaker_dark</item>
-        <item name="mediaRouteSpeakerGroupIconDrawable">@drawable/ic_vol_type_speaker_group_dark</item>
-
-        <item name="mediaRouteControlPanelThemeOverlay">@null</item>
-    </style>
-
-    <style name="Theme.MediaRouter.LightControlPanel">
-        <item name="mediaRouteControlPanelThemeOverlay">@style/ThemeOverlay.MediaRouter.Light</item>
-    </style>
-
-    <style name="Theme.MediaRouter.Light" parent="android:Theme.Material.Light">
-        <item name="android:windowNoTitle">true</item>
-        <item name="mediaRouteButtonStyle">@style/Widget.MediaRouter.Light.MediaRouteButton</item>
-
-        <item name="mediaRouteCloseDrawable">@drawable/mr_dialog_close_light</item>
-        <item name="mediaRoutePlayDrawable">@drawable/mr_media_play_light</item>
-        <item name="mediaRoutePauseDrawable">@drawable/mr_media_pause_light</item>
-        <item name="mediaRouteStopDrawable">@drawable/mr_media_stop_light</item>
-        <item name="mediaRouteAudioTrackDrawable">@drawable/mr_vol_type_audiotrack_light</item>
-        <item name="mediaRouteDefaultIconDrawable">@drawable/ic_mr_button_grey</item>
-        <item name="mediaRouteTvIconDrawable">@drawable/ic_vol_type_tv_light</item>
-        <item name="mediaRouteSpeakerIconDrawable">@drawable/ic_vol_type_speaker_light</item>
-        <item name="mediaRouteSpeakerGroupIconDrawable">@drawable/ic_vol_type_speaker_group_light</item>
-
-        <item name="mediaRouteControlPanelThemeOverlay">@null</item>
-    </style>
-
-    <style name="Theme.MediaRouter.Light.DarkControlPanel">
-        <item name="mediaRouteControlPanelThemeOverlay">@style/ThemeOverlay.MediaRouter.Dark</item>
-    </style>
-
-    <style name="ThemeOverlay.MediaRouter.Dark" parent="android:Theme.Material">
-        <item name="mediaRoutePlayDrawable">@drawable/mr_media_play_dark</item>
-        <item name="mediaRoutePauseDrawable">@drawable/mr_media_pause_dark</item>
-        <item name="mediaRouteStopDrawable">@drawable/mr_media_stop_dark</item>
-        <item name="mediaRouteAudioTrackDrawable">@drawable/mr_vol_type_audiotrack_dark</item>
-
-    </style>
-    <style name="ThemeOverlay.MediaRouter.Light" parent="android:Theme.Material.Light">
-        <item name="mediaRoutePlayDrawable">@drawable/mr_media_play_light</item>
-        <item name="mediaRoutePauseDrawable">@drawable/mr_media_pause_light</item>
-        <item name="mediaRouteStopDrawable">@drawable/mr_media_stop_light</item>
-        <item name="mediaRouteAudioTrackDrawable">@drawable/mr_vol_type_audiotrack_light</item>
-    </style>
-
-</resources>
diff --git a/packages/MediaComponents/runcts.sh b/packages/MediaComponents/runcts.sh
deleted file mode 100644
index 61b1a1e..0000000
--- a/packages/MediaComponents/runcts.sh
+++ /dev/null
@@ -1,224 +0,0 @@
-#!/bin/bash
-# Copyright 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Usage '. runcts.sh'
-
-function _runtest_cts_mediacomponent_usage() {
-  echo 'runtest-cts-MediaComponents [option]: Build, flash device,'
-  echo '              and run subset of CtsMediaTestCases that MediaComponents covers.'
-  echo '          *Warning* This bypasses CTS setup (e.g. download media contents from server)'
-  echo '          For running CTS in official way, use atest or cts-tradefed '
-  echo '     -h|--help: This help'
-  echo '     --skip: Skip build and flash. Just rerun-tests'
-  echo '     --min: Only rebuild tests and updatable library.'
-  echo '     --test: Only rebuild tests'
-  echo '     -s [device_id]: Specify a device name to run test against.'
-  echo '                     You can define ${ADBHOST} instead.'
-  echo '     -r [count]: Repeat tests for given count. It will stop when fails.'
-  echo '     --ignore: Keep repeating tests even when it fails.'
-  echo '     -t [test]: Only run the specific test. Can be either a class or a method.'
-}
-
-function runtest-cts-MediaComponents() {
-  # Edit here if you want to support other tests.
-  # List up libs and apks in the media_api needed for tests, and place test target at the last.
-  local TEST_PACKAGE_DIR=("frameworks/av/packages/MediaComponents/test")
-  local TEST_PACKAGE=("android.media.cts")
-  local BUILD_TARGETS=("MediaComponents" "CtsMediaTestCases")
-  # Don't include MediaComponents -- if we simply install it, system server
-  # wouldn't use the installed one.
-  local INSTALL_TARGETS=("CtsMediaTestCases")
-  local TEST_RUNNER="android.support.test.runner.AndroidJUnitRunner"
-  local DEPENDENCIES=("mockito-target-minus-junit4" "android-support-test" "compatibility-device-util")
-  local DEFAULT_TEST_TARGET=""
-  DEFAULT_TEST_TARGET+="android.media.cts.MediaBrowser2Test"
-  DEFAULT_TEST_TARGET+=",android.media.cts.MediaController2Test"
-  DEFAULT_TEST_TARGET+=",android.media.cts.MediaMetadata2Test"
-  DEFAULT_TEST_TARGET+=",android.media.cts.MediaSession2Test"
-  DEFAULT_TEST_TARGET+=",android.media.cts.MediaSession2_PermissionTest"
-  DEFAULT_TEST_TARGET+=",android.media.cts.MediaSessionManager_MediaSession2Test"
-  DEFAULT_TEST_TARGET+=",android.media.cts.SessionToken2Test"
-  if [[ -z "${ANDROID_BUILD_TOP}" ]]; then
-    echo "Needs to lunch a target first"
-    return
-  fi
-
-  local old_path=${OLDPWD}
-  while true; do
-    local OPTION_SKIP="false"
-    local OPTION_MIN="false"
-    local OPTION_TEST="false"
-    local OPTION_REPEAT_COUNT="1"
-    local OPTION_IGNORE="false"
-    local OPTION_TEST_TARGET="${DEFAULT_TEST_TARGET}"
-    local adbhost_local
-    while (( "$#" )); do
-      case "${1}" in
-        -h|--help)
-          _runtest_cts_mediacomponent_usage
-          return
-          ;;
-        --skip)
-          OPTION_SKIP="true"
-          ;;
-        --min)
-          OPTION_MIN="true"
-          ;;
-        --test)
-          OPTION_TEST="true"
-          ;;
-        -s)
-          shift
-          adbhost_local=${1}
-          ;;
-        -r)
-          shift
-          OPTION_REPEAT_COUNT="${1}"
-          ;;
-        --ignore)
-          OPTION_IGNORE="true"
-          ;;
-        -t)
-          shift
-          OPTION_TEST_TARGET="${1}"
-      esac
-      shift
-    done
-
-    # Build adb command.
-    local adb
-    if [[ -z "${adbhost_local}" ]]; then
-      adbhost_local=${ADBHOST}
-    fi
-    if [[ -z "${adbhost_local}" ]]; then
-      local device_count=$(adb devices | sed '/^[[:space:]]*$/d' | wc -l)
-      if [[ "${device_count}" != "2" ]]; then
-        echo "Too many devices. Specify a device." && break
-      fi
-      adb="adb"
-    else
-      adb="adb -s ${adbhost_local}"
-    fi
-
-    local target_dir="${ANDROID_BUILD_TOP}/${TEST_PACKAGE_DIR}"
-    #local TEST_PACKAGE=$(sed -n 's/^.*\bpackage\b="\([a-z0-9\.]*\)".*$/\1/p' ${target_dir}/AndroidManifest.xml)
-
-    if [[ "${OPTION_SKIP}" != "true" ]]; then
-      # Build dependencies if needed.
-      local dependency
-      local build_dependency=""
-      for dependency in ${DEPENDENCIES[@]}; do
-        if [[ "${dependency}" == "out/"* ]]; then
-          if [[ ! -f ${ANDROID_BUILD_TOP}/${dependency} ]]; then
-            build_dependency="true"
-            break
-          fi
-        else
-          if [[ "$(find ${OUT} -name ${dependency}_intermediates | wc -l)" == "0" ]]; then
-            build_dependency="true"
-            break
-          fi
-        fi
-      done
-      if [[ "${build_dependency}" == "true" ]]; then
-        echo "Building dependencies. Will only print stderr."
-        m ${DEPENDENCIES[@]} -j > /dev/null
-      fi
-
-      # Build test apk and required apk.
-      local build_targets
-      if [[ "${OPTION_TEST}" == "true" ]]; then
-        build_targets="${INSTALL_TARGETS[@]}"
-      elif [[ "${OPTION_MIN}" == "true" ]]; then
-        build_targets="${BUILD_TARGETS[@]}"
-      else
-        build_targets="${BUILD_TARGETS[@]} droid"
-      fi
-      m ${build_targets} -j || break
-
-      if [[ "${OPTION_TEST}" != "true" ]]; then
-        # Flash only when needed
-        local device_build_type="$(${adb} shell getprop ro.build.type)"
-        if [[ "${device_build_type}" == "user" ]]; then
-          # User build. Cannot adb sync
-          ${adb} reboot bootloader
-          fastboot flashall
-        else
-          ${adb} root
-          local device_verity_mode="$(${adb} shell getprop ro.boot.veritymode)"
-          if [[ "${device_verity_mode}" != "disabled" ]]; then
-            ${adb} disable-verity
-            ${adb} reboot
-            ${adb} wait-for-device || break
-            ${adb} root
-          fi
-          ${adb} remount
-          ${adb} shell stop
-          ${adb} shell setprop log.tag.MediaSessionService DEBUG
-          ${adb} sync
-          ${adb} shell start
-        fi
-        ${adb} wait-for-device || break
-        # Ensure package manager is loaded.
-        # TODO(jaewan): Find better way to wait
-        sleep 15
-      fi
-
-      # Install apks
-      local install_failed="false"
-      for target in ${INSTALL_TARGETS[@]}; do
-        local apk_path=$(find ${OUT}/system ${OUT}/data -name ${target}.apk)
-        local apk_num=$(find ${OUT}/system ${OUT}/data -name ${target}.apk | wc -l)
-        if [[ "${apk_num}" != "1" ]]; then
-          echo "Cannot locate a ${target}.apk. Found ${apk_num} apks" && break
-        fi
-        echo "Installing ${target}.apk. path=${apk_path}"
-        ${adb} install -r ${apk_path}
-        if [[ "${?}" != "0" ]]; then
-          install_failed="true"
-          break
-        fi
-      done
-      if [[ "${install_failed}" == "true" ]]; then
-        echo "Failed to install. Test wouldn't run."
-        break
-      fi
-    fi
-
-    local test_target=""
-    if [[ -n "${OPTION_TEST_TARGET}" ]]; then
-      test_target="-e class ${OPTION_TEST_TARGET}"
-    fi
-
-    local i
-    local tmpfile=$(tempfile)
-    for ((i=1; i <= ${OPTION_REPEAT_COUNT}; i++)); do
-      echo "Run test ${i}/${OPTION_REPEAT_COUNT}"
-      ${adb} shell am instrument ${test_target} -w ${TEST_PACKAGE}/${TEST_RUNNER} >& ${tmpfile}
-      cat ${tmpfile}
-      if [[ "${OPTION_IGNORE}" != "true" ]]; then
-        if [[ -n "$(grep ${tmpfile} -e 'FAILURE\|crashed')" ]]; then
-          # am instrument doesn't return error code so need to grep result message instead
-          break
-        fi
-      fi
-    done
-    rm ${tmpfile}
-    break
-  done
-}
-
-echo "Following functions are added to your environment:"
-_runtest_cts_mediacomponent_usage
diff --git a/packages/MediaComponents/src/com/android/media/IMediaController2.aidl b/packages/MediaComponents/src/com/android/media/IMediaController2.aidl
deleted file mode 100644
index 0488b70..0000000
--- a/packages/MediaComponents/src/com/android/media/IMediaController2.aidl
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.media;
-
-import android.app.PendingIntent;
-import android.os.Bundle;
-import android.os.ResultReceiver;
-
-import com.android.media.IMediaSession2;
-
-/**
- * Interface from MediaSession2 to MediaController2.
- * <p>
- * Keep this interface oneway. Otherwise a malicious app may implement fake version of this,
- * and holds calls from session to make session owner(s) frozen.
- */
-// TODO(jaewan): (Post P) Handle when the playlist becomes too huge.
-//               Note that ParcelledSliceList isn't a good idea for the purpose. (see: b/37493677)
-oneway interface IMediaController2 {
-    void onPlayerStateChanged(int state);
-    void onPositionChanged(long eventTimeMs, long positionMs);
-    void onPlaybackSpeedChanged(float speed);
-    void onBufferedPositionChanged(long bufferedPositionMs);
-    void onPlaylistChanged(in List<Bundle> playlist, in Bundle metadata);
-    void onPlaylistMetadataChanged(in Bundle metadata);
-    void onPlaybackInfoChanged(in Bundle playbackInfo);
-    void onRepeatModeChanged(int repeatMode);
-    void onShuffleModeChanged(int shuffleMode);
-    void onError(int errorCode, in Bundle extras);
-
-    void onConnected(IMediaSession2 sessionBinder, in Bundle commandGroup,
-            int playerState, long positionEventTimeMs, long positionMs, float playbackSpeed,
-            long bufferedPositionMs, in Bundle playbackInfo, int repeatMode, int shuffleMode,
-            in List<Bundle> playlist, in PendingIntent sessionActivity);
-    void onDisconnected();
-
-    void onCustomLayoutChanged(in List<Bundle> commandButtonlist);
-    void onAllowedCommandsChanged(in Bundle commands);
-
-    void onCustomCommand(in Bundle command, in Bundle args, in ResultReceiver receiver);
-
-    //////////////////////////////////////////////////////////////////////////////////////////////
-    // Browser sepcific
-    //////////////////////////////////////////////////////////////////////////////////////////////
-    void onGetLibraryRootDone(in Bundle rootHints, String rootMediaId, in Bundle rootExtra);
-    void onGetItemDone(String mediaId, in Bundle result);
-    void onChildrenChanged(String rootMediaId, int itemCount, in Bundle extras);
-    void onGetChildrenDone(String parentId, int page, int pageSize, in List<Bundle> result,
-            in Bundle extras);
-    void onSearchResultChanged(String query, int itemCount, in Bundle extras);
-    void onGetSearchResultDone(String query, int page, int pageSize, in List<Bundle> result,
-            in Bundle extras);
-}
diff --git a/packages/MediaComponents/src/com/android/media/IMediaSession2.aidl b/packages/MediaComponents/src/com/android/media/IMediaSession2.aidl
deleted file mode 100644
index 664467d..0000000
--- a/packages/MediaComponents/src/com/android/media/IMediaSession2.aidl
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.media;
-
-import android.os.Bundle;
-import android.os.ResultReceiver;
-import android.net.Uri;
-
-import com.android.media.IMediaController2;
-
-/**
- * Interface from MediaController2 to MediaSession2.
- * <p>
- * Keep this interface oneway. Otherwise a malicious app may implement fake version of this,
- * and holds calls from session to make session owner(s) frozen.
- */
- // TODO(jaewan): (Post P) Handle when the playlist becomes too huge.
- //               Note that ParcelledSliceList isn't a good idea for the purpose. (see: b/37493677)
-oneway interface IMediaSession2 {
-    // TODO(jaewan): add onCommand() to send private command
-
-    // TODO(jaewan): (Post P) We may consider to add another binder just for the connection
-    //               not to expose other methods to the controller whose connection wasn't accepted.
-    //               But this would be enough for now because it's the same as existing
-    //               MediaBrowser and MediaBrowserService.
-    void connect(IMediaController2 caller, String callingPackage);
-    void release(IMediaController2 caller);
-
-    void setVolumeTo(IMediaController2 caller, int value, int flags);
-    void adjustVolume(IMediaController2 caller, int direction, int flags);
-
-    //////////////////////////////////////////////////////////////////////////////////////////////
-    // send command
-    //////////////////////////////////////////////////////////////////////////////////////////////
-    void sendTransportControlCommand(IMediaController2 caller,
-            int commandCode, in Bundle args);
-    void sendCustomCommand(IMediaController2 caller, in Bundle command, in Bundle args,
-            in ResultReceiver receiver);
-
-    void prepareFromUri(IMediaController2 caller, in Uri uri, in Bundle extras);
-    void prepareFromSearch(IMediaController2 caller, String query, in Bundle extras);
-    void prepareFromMediaId(IMediaController2 caller, String mediaId, in Bundle extras);
-    void playFromUri(IMediaController2 caller, in Uri uri, in Bundle extras);
-    void playFromSearch(IMediaController2 caller, String query, in Bundle extras);
-    void playFromMediaId(IMediaController2 caller, String mediaId, in Bundle extras);
-    void setRating(IMediaController2 caller, String mediaId, in Bundle rating);
-
-    void setPlaylist(IMediaController2 caller, in List<Bundle> playlist, in Bundle metadata);
-    void updatePlaylistMetadata(IMediaController2 caller, in Bundle metadata);
-    void addPlaylistItem(IMediaController2 caller, int index, in Bundle mediaItem);
-    void removePlaylistItem(IMediaController2 caller, in Bundle mediaItem);
-    void replacePlaylistItem(IMediaController2 caller, int index, in Bundle mediaItem);
-    void skipToPlaylistItem(IMediaController2 caller, in Bundle mediaItem);
-    void skipToPreviousItem(IMediaController2 caller);
-    void skipToNextItem(IMediaController2 caller);
-    void setRepeatMode(IMediaController2 caller, int repeatMode);
-    void setShuffleMode(IMediaController2 caller, int shuffleMode);
-
-    //////////////////////////////////////////////////////////////////////////////////////////////
-    // library service specific
-    //////////////////////////////////////////////////////////////////////////////////////////////
-    void getLibraryRoot(IMediaController2 caller, in Bundle rootHints);
-    void getItem(IMediaController2 caller, String mediaId);
-    void getChildren(IMediaController2 caller, String parentId, int page, int pageSize,
-            in Bundle extras);
-    void search(IMediaController2 caller, String query, in Bundle extras);
-    void getSearchResult(IMediaController2 caller, String query, int page, int pageSize,
-            in Bundle extras);
-    void subscribe(IMediaController2 caller, String parentId, in Bundle extras);
-    void unsubscribe(IMediaController2 caller, String parentId);
-}
diff --git a/packages/MediaComponents/src/com/android/media/MediaBrowser2Impl.java b/packages/MediaComponents/src/com/android/media/MediaBrowser2Impl.java
deleted file mode 100644
index c909099..0000000
--- a/packages/MediaComponents/src/com/android/media/MediaBrowser2Impl.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.media;
-
-import android.content.Context;
-import android.media.MediaBrowser2;
-import android.media.MediaBrowser2.BrowserCallback;
-import android.media.MediaController2;
-import android.media.MediaItem2;
-import android.media.SessionToken2;
-import android.media.update.MediaBrowser2Provider;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.util.List;
-import java.util.concurrent.Executor;
-
-public class MediaBrowser2Impl extends MediaController2Impl implements MediaBrowser2Provider {
-    private final String TAG = "MediaBrowser2";
-    private final boolean DEBUG = true; // TODO(jaewan): change.
-
-    private final MediaBrowser2 mInstance;
-    private final MediaBrowser2.BrowserCallback mCallback;
-
-    public MediaBrowser2Impl(Context context, MediaBrowser2 instance, SessionToken2 token,
-            Executor executor, BrowserCallback callback) {
-        super(context, instance, token, executor, callback);
-        mInstance = instance;
-        mCallback = callback;
-    }
-
-    @Override MediaBrowser2 getInstance() {
-        return (MediaBrowser2) super.getInstance();
-    }
-
-    @Override
-    public void getLibraryRoot_impl(Bundle rootHints) {
-        final IMediaSession2 binder = getSessionBinder();
-        if (binder != null) {
-            try {
-                binder.getLibraryRoot(getControllerStub(), rootHints);
-            } catch (RemoteException e) {
-                // TODO(jaewan): Handle disconnect.
-                if (DEBUG) {
-                    Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-                }
-            }
-        } else {
-            Log.w(TAG, "Session isn't active", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void subscribe_impl(String parentId, Bundle extras) {
-        if (parentId == null) {
-            throw new IllegalArgumentException("parentId shouldn't be null");
-        }
-
-        final IMediaSession2 binder = getSessionBinder();
-        if (binder != null) {
-            try {
-                binder.subscribe(getControllerStub(), parentId, extras);
-            } catch (RemoteException e) {
-                // TODO(jaewan): Handle disconnect.
-                if (DEBUG) {
-                    Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-                }
-            }
-        } else {
-            Log.w(TAG, "Session isn't active", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void unsubscribe_impl(String parentId) {
-        if (parentId == null) {
-            throw new IllegalArgumentException("parentId shouldn't be null");
-        }
-
-        final IMediaSession2 binder = getSessionBinder();
-        if (binder != null) {
-            try {
-                binder.unsubscribe(getControllerStub(), parentId);
-            } catch (RemoteException e) {
-                // TODO(jaewan): Handle disconnect.
-                if (DEBUG) {
-                    Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-                }
-            }
-        } else {
-            Log.w(TAG, "Session isn't active", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void getItem_impl(String mediaId) {
-        if (mediaId == null) {
-            throw new IllegalArgumentException("mediaId shouldn't be null");
-        }
-
-        final IMediaSession2 binder = getSessionBinder();
-        if (binder != null) {
-            try {
-                binder.getItem(getControllerStub(), mediaId);
-            } catch (RemoteException e) {
-                // TODO(jaewan): Handle disconnect.
-                if (DEBUG) {
-                    Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-                }
-            }
-        } else {
-            Log.w(TAG, "Session isn't active", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void getChildren_impl(String parentId, int page, int pageSize, Bundle extras) {
-        if (parentId == null) {
-            throw new IllegalArgumentException("parentId shouldn't be null");
-        }
-        if (page < 1 || pageSize < 1) {
-            throw new IllegalArgumentException("Neither page nor pageSize should be less than 1");
-        }
-
-        final IMediaSession2 binder = getSessionBinder();
-        if (binder != null) {
-            try {
-                binder.getChildren(getControllerStub(), parentId, page, pageSize, extras);
-            } catch (RemoteException e) {
-                // TODO(jaewan): Handle disconnect.
-                if (DEBUG) {
-                    Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-                }
-            }
-        } else {
-            Log.w(TAG, "Session isn't active", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void search_impl(String query, Bundle extras) {
-        if (TextUtils.isEmpty(query)) {
-            throw new IllegalArgumentException("query shouldn't be empty");
-        }
-        final IMediaSession2 binder = getSessionBinder();
-        if (binder != null) {
-            try {
-                binder.search(getControllerStub(), query, extras);
-            } catch (RemoteException e) {
-                // TODO(jaewan): Handle disconnect.
-                if (DEBUG) {
-                    Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-                }
-            }
-        } else {
-            Log.w(TAG, "Session isn't active", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void getSearchResult_impl(String query, int page, int pageSize, Bundle extras) {
-        if (TextUtils.isEmpty(query)) {
-            throw new IllegalArgumentException("query shouldn't be empty");
-        }
-        if (page < 1 || pageSize < 1) {
-            throw new IllegalArgumentException("Neither page nor pageSize should be less than 1");
-        }
-        final IMediaSession2 binder = getSessionBinder();
-        if (binder != null) {
-            try {
-                binder.getSearchResult(getControllerStub(), query, page, pageSize, extras);
-            } catch (RemoteException e) {
-                // TODO(jaewan): Handle disconnect.
-                if (DEBUG) {
-                    Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-                }
-            }
-        } else {
-            Log.w(TAG, "Session isn't active", new IllegalStateException());
-        }
-    }
-
-    public void onGetLibraryRootDone(
-            final Bundle rootHints, final String rootMediaId, final Bundle rootExtra) {
-        getCallbackExecutor().execute(() -> {
-            mCallback.onGetLibraryRootDone(getInstance(), rootHints, rootMediaId, rootExtra);
-        });
-    }
-
-    public void onGetItemDone(String mediaId, MediaItem2 item) {
-        getCallbackExecutor().execute(() -> {
-            mCallback.onGetItemDone(getInstance(), mediaId, item);
-        });
-    }
-
-    public void onGetChildrenDone(String parentId, int page, int pageSize, List<MediaItem2> result,
-            Bundle extras) {
-        getCallbackExecutor().execute(() -> {
-            mCallback.onGetChildrenDone(getInstance(), parentId, page, pageSize, result, extras);
-        });
-    }
-
-    public void onSearchResultChanged(String query, int itemCount, Bundle extras) {
-        getCallbackExecutor().execute(() -> {
-            mCallback.onSearchResultChanged(getInstance(), query, itemCount, extras);
-        });
-    }
-
-    public void onGetSearchResultDone(String query, int page, int pageSize, List<MediaItem2> result,
-            Bundle extras) {
-        getCallbackExecutor().execute(() -> {
-            mCallback.onGetSearchResultDone(getInstance(), query, page, pageSize, result, extras);
-        });
-    }
-
-    public void onChildrenChanged(final String parentId, int itemCount, final Bundle extras) {
-        getCallbackExecutor().execute(() -> {
-            mCallback.onChildrenChanged(getInstance(), parentId, itemCount, extras);
-        });
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/media/MediaController2Impl.java b/packages/MediaComponents/src/com/android/media/MediaController2Impl.java
deleted file mode 100644
index 249365a..0000000
--- a/packages/MediaComponents/src/com/android/media/MediaController2Impl.java
+++ /dev/null
@@ -1,1143 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.media;
-
-import static android.media.SessionCommand2.COMMAND_CODE_SET_VOLUME;
-import static android.media.SessionCommand2.COMMAND_CODE_PLAYLIST_ADD_ITEM;
-import static android.media.SessionCommand2.COMMAND_CODE_PLAYLIST_REMOVE_ITEM;
-import static android.media.SessionCommand2.COMMAND_CODE_PLAYLIST_REPLACE_ITEM;
-import static android.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SET_LIST;
-import static android.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SET_LIST_METADATA;
-import static android.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SET_REPEAT_MODE;
-import static android.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SET_SHUFFLE_MODE;
-import static android.media.SessionCommand2.COMMAND_CODE_SESSION_PLAY_FROM_MEDIA_ID;
-import static android.media.SessionCommand2.COMMAND_CODE_SESSION_PLAY_FROM_SEARCH;
-import static android.media.SessionCommand2.COMMAND_CODE_SESSION_PLAY_FROM_URI;
-import static android.media.SessionCommand2.COMMAND_CODE_SESSION_PREPARE_FROM_MEDIA_ID;
-import static android.media.SessionCommand2.COMMAND_CODE_SESSION_PREPARE_FROM_SEARCH;
-import static android.media.SessionCommand2.COMMAND_CODE_SESSION_PREPARE_FROM_URI;
-
-import android.app.PendingIntent;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.media.AudioAttributes;
-import android.media.MediaController2;
-import android.media.MediaController2.ControllerCallback;
-import android.media.MediaController2.PlaybackInfo;
-import android.media.MediaItem2;
-import android.media.MediaMetadata2;
-import android.media.MediaPlaylistAgent.RepeatMode;
-import android.media.MediaPlaylistAgent.ShuffleMode;
-import android.media.SessionCommand2;
-import android.media.MediaSession2.CommandButton;
-import android.media.SessionCommandGroup2;
-import android.media.MediaSessionService2;
-import android.media.Rating2;
-import android.media.SessionToken2;
-import android.media.update.MediaController2Provider;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.os.UserHandle;
-import android.support.annotation.GuardedBy;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executor;
-
-public class MediaController2Impl implements MediaController2Provider {
-    private static final String TAG = "MediaController2";
-    private static final boolean DEBUG = true; // TODO(jaewan): Change
-
-    private final MediaController2 mInstance;
-    private final Context mContext;
-    private final Object mLock = new Object();
-
-    private final MediaController2Stub mControllerStub;
-    private final SessionToken2 mToken;
-    private final ControllerCallback mCallback;
-    private final Executor mCallbackExecutor;
-    private final IBinder.DeathRecipient mDeathRecipient;
-
-    @GuardedBy("mLock")
-    private SessionServiceConnection mServiceConnection;
-    @GuardedBy("mLock")
-    private boolean mIsReleased;
-    @GuardedBy("mLock")
-    private List<MediaItem2> mPlaylist;
-    @GuardedBy("mLock")
-    private MediaMetadata2 mPlaylistMetadata;
-    @GuardedBy("mLock")
-    private @RepeatMode int mRepeatMode;
-    @GuardedBy("mLock")
-    private @ShuffleMode int mShuffleMode;
-    @GuardedBy("mLock")
-    private int mPlayerState;
-    @GuardedBy("mLock")
-    private long mPositionEventTimeMs;
-    @GuardedBy("mLock")
-    private long mPositionMs;
-    @GuardedBy("mLock")
-    private float mPlaybackSpeed;
-    @GuardedBy("mLock")
-    private long mBufferedPositionMs;
-    @GuardedBy("mLock")
-    private PlaybackInfo mPlaybackInfo;
-    @GuardedBy("mLock")
-    private PendingIntent mSessionActivity;
-    @GuardedBy("mLock")
-    private SessionCommandGroup2 mAllowedCommands;
-
-    // Assignment should be used with the lock hold, but should be used without a lock to prevent
-    // potential deadlock.
-    // Postfix -Binder is added to explicitly show that it's potentially remote process call.
-    // Technically -Interface is more correct, but it may misread that it's interface (vs class)
-    // so let's keep this postfix until we find better postfix.
-    @GuardedBy("mLock")
-    private volatile IMediaSession2 mSessionBinder;
-
-    // TODO(jaewan): Require session activeness changed listener, because controller can be
-    //               available when the session's player is null.
-    public MediaController2Impl(Context context, MediaController2 instance, SessionToken2 token,
-            Executor executor, ControllerCallback callback) {
-        mInstance = instance;
-        if (context == null) {
-            throw new IllegalArgumentException("context shouldn't be null");
-        }
-        if (token == null) {
-            throw new IllegalArgumentException("token shouldn't be null");
-        }
-        if (callback == null) {
-            throw new IllegalArgumentException("callback shouldn't be null");
-        }
-        if (executor == null) {
-            throw new IllegalArgumentException("executor shouldn't be null");
-        }
-        mContext = context;
-        mControllerStub = new MediaController2Stub(this);
-        mToken = token;
-        mCallback = callback;
-        mCallbackExecutor = executor;
-        mDeathRecipient = () -> {
-            mInstance.close();
-        };
-
-        mSessionBinder = null;
-    }
-
-    @Override
-    public void initialize() {
-        // TODO(jaewan): More sanity checks.
-        if (mToken.getType() == SessionToken2.TYPE_SESSION) {
-            // Session
-            mServiceConnection = null;
-            connectToSession(SessionToken2Impl.from(mToken).getSessionBinder());
-        } else {
-            // Session service
-            if (Process.myUid() == Process.SYSTEM_UID) {
-                // It's system server (MediaSessionService) that wants to monitor session.
-                // Don't bind if able..
-                IMediaSession2 binder = SessionToken2Impl.from(mToken).getSessionBinder();
-                if (binder != null) {
-                    // Use binder in the session token instead of bind by its own.
-                    // Otherwise server will holds the binding to the service *forever* and service
-                    // will never stop.
-                    mServiceConnection = null;
-                    connectToSession(SessionToken2Impl.from(mToken).getSessionBinder());
-                    return;
-                } else if (DEBUG) {
-                    // Should happen only when system server wants to dispatch media key events to
-                    // a dead service.
-                    Log.d(TAG, "System server binds to a session service. Should unbind"
-                            + " immediately after the use.");
-                }
-            }
-            mServiceConnection = new SessionServiceConnection();
-            connectToService();
-        }
-    }
-
-    private void connectToService() {
-        // Service. Needs to get fresh binder whenever connection is needed.
-        SessionToken2Impl impl = SessionToken2Impl.from(mToken);
-        final Intent intent = new Intent(MediaSessionService2.SERVICE_INTERFACE);
-        intent.setClassName(mToken.getPackageName(), impl.getServiceName());
-
-        // Use bindService() instead of startForegroundService() to start session service for three
-        // reasons.
-        // 1. Prevent session service owner's stopSelf() from destroying service.
-        //    With the startForegroundService(), service's call of stopSelf() will trigger immediate
-        //    onDestroy() calls on the main thread even when onConnect() is running in another
-        //    thread.
-        // 2. Minimize APIs for developers to take care about.
-        //    With bindService(), developers only need to take care about Service.onBind()
-        //    but Service.onStartCommand() should be also taken care about with the
-        //    startForegroundService().
-        // 3. Future support for UI-less playback
-        //    If a service wants to keep running, it should be either foreground service or
-        //    bounded service. But there had been request for the feature for system apps
-        //    and using bindService() will be better fit with it.
-        boolean result;
-        if (Process.myUid() == Process.SYSTEM_UID) {
-            // Use bindServiceAsUser() for binding from system service to avoid following warning.
-            // ContextImpl: Calling a method in the system process without a qualified user
-            result = mContext.bindServiceAsUser(intent, mServiceConnection, Context.BIND_AUTO_CREATE,
-                    UserHandle.getUserHandleForUid(mToken.getUid()));
-        } else {
-            result = mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
-        }
-        if (!result) {
-            Log.w(TAG, "bind to " + mToken + " failed");
-        } else if (DEBUG) {
-            Log.d(TAG, "bind to " + mToken + " success");
-        }
-    }
-
-    private void connectToSession(IMediaSession2 sessionBinder) {
-        try {
-            sessionBinder.connect(mControllerStub, mContext.getPackageName());
-        } catch (RemoteException e) {
-            Log.w(TAG, "Failed to call connection request. Framework will retry"
-                    + " automatically");
-        }
-    }
-
-    @Override
-    public void close_impl() {
-        if (DEBUG) {
-            Log.d(TAG, "release from " + mToken);
-        }
-        final IMediaSession2 binder;
-        synchronized (mLock) {
-            if (mIsReleased) {
-                // Prevent re-enterance from the ControllerCallback.onDisconnected()
-                return;
-            }
-            mIsReleased = true;
-            if (mServiceConnection != null) {
-                mContext.unbindService(mServiceConnection);
-                mServiceConnection = null;
-            }
-            binder = mSessionBinder;
-            mSessionBinder = null;
-            mControllerStub.destroy();
-        }
-        if (binder != null) {
-            try {
-                binder.asBinder().unlinkToDeath(mDeathRecipient, 0);
-                binder.release(mControllerStub);
-            } catch (RemoteException e) {
-                // No-op.
-            }
-        }
-        mCallbackExecutor.execute(() -> {
-            mCallback.onDisconnected(mInstance);
-        });
-    }
-
-    IMediaSession2 getSessionBinder() {
-        return mSessionBinder;
-    }
-
-    MediaController2Stub getControllerStub() {
-        return mControllerStub;
-    }
-
-    Executor getCallbackExecutor() {
-        return mCallbackExecutor;
-    }
-
-    Context getContext() {
-        return mContext;
-    }
-
-    MediaController2 getInstance() {
-        return mInstance;
-    }
-
-    // Returns session binder if the controller can send the command.
-    IMediaSession2 getSessionBinderIfAble(int commandCode) {
-        synchronized (mLock) {
-            if (!mAllowedCommands.hasCommand(commandCode)) {
-                // Cannot send because isn't allowed to.
-                Log.w(TAG, "Controller isn't allowed to call command, commandCode="
-                        + commandCode);
-                return null;
-            }
-        }
-        // TODO(jaewan): Should we do this with the lock hold?
-        final IMediaSession2 binder = mSessionBinder;
-        if (binder == null) {
-            // Cannot send because disconnected.
-            Log.w(TAG, "Session is disconnected");
-        }
-        return binder;
-    }
-
-    // Returns session binder if the controller can send the command.
-    IMediaSession2 getSessionBinderIfAble(SessionCommand2 command) {
-        synchronized (mLock) {
-            if (!mAllowedCommands.hasCommand(command)) {
-                Log.w(TAG, "Controller isn't allowed to call command, command=" + command);
-                return null;
-            }
-        }
-        // TODO(jaewan): Should we do this with the lock hold?
-        final IMediaSession2 binder = mSessionBinder;
-        if (binder == null) {
-            // Cannot send because disconnected.
-            Log.w(TAG, "Session is disconnected");
-        }
-        return binder;
-    }
-
-    @Override
-    public SessionToken2 getSessionToken_impl() {
-        return mToken;
-    }
-
-    @Override
-    public boolean isConnected_impl() {
-        final IMediaSession2 binder = mSessionBinder;
-        return binder != null;
-    }
-
-    @Override
-    public void play_impl() {
-        sendTransportControlCommand(SessionCommand2.COMMAND_CODE_PLAYBACK_PLAY);
-    }
-
-    @Override
-    public void pause_impl() {
-        sendTransportControlCommand(SessionCommand2.COMMAND_CODE_PLAYBACK_PAUSE);
-    }
-
-    @Override
-    public void stop_impl() {
-        sendTransportControlCommand(SessionCommand2.COMMAND_CODE_PLAYBACK_STOP);
-    }
-
-    @Override
-    public void skipToPlaylistItem_impl(MediaItem2 item) {
-        if (item == null) {
-            throw new IllegalArgumentException("item shouldn't be null");
-        }
-        final IMediaSession2 binder = mSessionBinder;
-        if (binder != null) {
-            try {
-                binder.skipToPlaylistItem(mControllerStub, item.toBundle());
-            } catch (RemoteException e) {
-                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-            }
-        } else {
-            Log.w(TAG, "Session isn't active", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void skipToPreviousItem_impl() {
-        final IMediaSession2 binder = mSessionBinder;
-        if (binder != null) {
-            try {
-                binder.skipToPreviousItem(mControllerStub);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-            }
-        } else {
-            Log.w(TAG, "Session isn't active", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void skipToNextItem_impl() {
-        final IMediaSession2 binder = mSessionBinder;
-        if (binder != null) {
-            try {
-                binder.skipToNextItem(mControllerStub);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-            }
-        } else {
-            Log.w(TAG, "Session isn't active", new IllegalStateException());
-        }
-    }
-
-    private void sendTransportControlCommand(int commandCode) {
-        sendTransportControlCommand(commandCode, null);
-    }
-
-    private void sendTransportControlCommand(int commandCode, Bundle args) {
-        final IMediaSession2 binder = mSessionBinder;
-        if (binder != null) {
-            try {
-                binder.sendTransportControlCommand(mControllerStub, commandCode, args);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-            }
-        } else {
-            Log.w(TAG, "Session isn't active", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public PendingIntent getSessionActivity_impl() {
-        return mSessionActivity;
-    }
-
-    @Override
-    public void setVolumeTo_impl(int value, int flags) {
-        // TODO(hdmoon): sanity check
-        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_SET_VOLUME);
-        if (binder != null) {
-            try {
-                binder.setVolumeTo(mControllerStub, value, flags);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-            }
-        } else {
-            Log.w(TAG, "Session isn't active", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void adjustVolume_impl(int direction, int flags) {
-        // TODO(hdmoon): sanity check
-        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_SET_VOLUME);
-        if (binder != null) {
-            try {
-                binder.adjustVolume(mControllerStub, direction, flags);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-            }
-        } else {
-            Log.w(TAG, "Session isn't active", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void prepareFromUri_impl(Uri uri, Bundle extras) {
-        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_SESSION_PREPARE_FROM_URI);
-        if (uri == null) {
-            throw new IllegalArgumentException("uri shouldn't be null");
-        }
-        if (binder != null) {
-            try {
-                binder.prepareFromUri(mControllerStub, uri, extras);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-            }
-        } else {
-            // TODO(jaewan): Handle.
-        }
-    }
-
-    @Override
-    public void prepareFromSearch_impl(String query, Bundle extras) {
-        final IMediaSession2 binder = getSessionBinderIfAble(
-                COMMAND_CODE_SESSION_PREPARE_FROM_SEARCH);
-        if (TextUtils.isEmpty(query)) {
-            throw new IllegalArgumentException("query shouldn't be empty");
-        }
-        if (binder != null) {
-            try {
-                binder.prepareFromSearch(mControllerStub, query, extras);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-            }
-        } else {
-            // TODO(jaewan): Handle.
-        }
-    }
-
-    @Override
-    public void prepareFromMediaId_impl(String mediaId, Bundle extras) {
-        final IMediaSession2 binder = getSessionBinderIfAble(
-                COMMAND_CODE_SESSION_PREPARE_FROM_MEDIA_ID);
-        if (mediaId == null) {
-            throw new IllegalArgumentException("mediaId shouldn't be null");
-        }
-        if (binder != null) {
-            try {
-                binder.prepareFromMediaId(mControllerStub, mediaId, extras);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-            }
-        } else {
-            // TODO(jaewan): Handle.
-        }
-    }
-
-    @Override
-    public void playFromUri_impl(Uri uri, Bundle extras) {
-        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_SESSION_PLAY_FROM_URI);
-        if (uri == null) {
-            throw new IllegalArgumentException("uri shouldn't be null");
-        }
-        if (binder != null) {
-            try {
-                binder.playFromUri(mControllerStub, uri, extras);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-            }
-        } else {
-            // TODO(jaewan): Handle.
-        }
-    }
-
-    @Override
-    public void playFromSearch_impl(String query, Bundle extras) {
-        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_SESSION_PLAY_FROM_SEARCH);
-        if (TextUtils.isEmpty(query)) {
-            throw new IllegalArgumentException("query shouldn't be empty");
-        }
-        if (binder != null) {
-            try {
-                binder.playFromSearch(mControllerStub, query, extras);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-            }
-        } else {
-            // TODO(jaewan): Handle.
-        }
-    }
-
-    @Override
-    public void playFromMediaId_impl(String mediaId, Bundle extras) {
-        final IMediaSession2 binder = getSessionBinderIfAble(
-                COMMAND_CODE_SESSION_PLAY_FROM_MEDIA_ID);
-        if (mediaId == null) {
-            throw new IllegalArgumentException("mediaId shouldn't be null");
-        }
-        if (binder != null) {
-            try {
-                binder.playFromMediaId(mControllerStub, mediaId, extras);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-            }
-        } else {
-            // TODO(jaewan): Handle.
-        }
-    }
-
-    @Override
-    public void setRating_impl(String mediaId, Rating2 rating) {
-        if (mediaId == null) {
-            throw new IllegalArgumentException("mediaId shouldn't be null");
-        }
-        if (rating == null) {
-            throw new IllegalArgumentException("rating shouldn't be null");
-        }
-
-        final IMediaSession2 binder = mSessionBinder;
-        if (binder != null) {
-            try {
-                binder.setRating(mControllerStub, mediaId, rating.toBundle());
-            } catch (RemoteException e) {
-                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-            }
-        } else {
-            // TODO(jaewan): Handle.
-        }
-    }
-
-    @Override
-    public void sendCustomCommand_impl(SessionCommand2 command, Bundle args, ResultReceiver cb) {
-        if (command == null) {
-            throw new IllegalArgumentException("command shouldn't be null");
-        }
-        final IMediaSession2 binder = getSessionBinderIfAble(command);
-        if (binder != null) {
-            try {
-                binder.sendCustomCommand(mControllerStub, command.toBundle(), args, cb);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-            }
-        } else {
-            Log.w(TAG, "Session isn't active", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public List<MediaItem2> getPlaylist_impl() {
-        synchronized (mLock) {
-            return mPlaylist;
-        }
-    }
-
-    @Override
-    public void setPlaylist_impl(List<MediaItem2> list, MediaMetadata2 metadata) {
-        if (list == null) {
-            throw new IllegalArgumentException("list shouldn't be null");
-        }
-        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_PLAYLIST_SET_LIST);
-        if (binder != null) {
-            List<Bundle> bundleList = new ArrayList<>();
-            for (int i = 0; i < list.size(); i++) {
-                bundleList.add(list.get(i).toBundle());
-            }
-            Bundle metadataBundle = (metadata == null) ? null : metadata.toBundle();
-            try {
-                binder.setPlaylist(mControllerStub, bundleList, metadataBundle);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-            }
-        } else {
-            Log.w(TAG, "Session isn't active", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public MediaMetadata2 getPlaylistMetadata_impl() {
-        synchronized (mLock) {
-            return mPlaylistMetadata;
-        }
-    }
-
-    @Override
-    public void updatePlaylistMetadata_impl(MediaMetadata2 metadata) {
-        final IMediaSession2 binder = getSessionBinderIfAble(
-                COMMAND_CODE_PLAYLIST_SET_LIST_METADATA);
-        if (binder != null) {
-            Bundle metadataBundle = (metadata == null) ? null : metadata.toBundle();
-            try {
-                binder.updatePlaylistMetadata(mControllerStub, metadataBundle);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-            }
-        } else {
-            Log.w(TAG, "Session isn't active", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void prepare_impl() {
-        sendTransportControlCommand(SessionCommand2.COMMAND_CODE_PLAYBACK_PREPARE);
-    }
-
-    @Override
-    public void fastForward_impl() {
-        // TODO(jaewan): Implement this. Note that fast forward isn't a transport command anymore
-        //sendTransportControlCommand(MediaSession2.COMMAND_CODE_SESSION_FAST_FORWARD);
-    }
-
-    @Override
-    public void rewind_impl() {
-        // TODO(jaewan): Implement this. Note that rewind isn't a transport command anymore
-        //sendTransportControlCommand(MediaSession2.COMMAND_CODE_SESSION_REWIND);
-    }
-
-    @Override
-    public void seekTo_impl(long pos) {
-        if (pos < 0) {
-            throw new IllegalArgumentException("position shouldn't be negative");
-        }
-        Bundle args = new Bundle();
-        args.putLong(MediaSession2Stub.ARGUMENT_KEY_POSITION, pos);
-        sendTransportControlCommand(SessionCommand2.COMMAND_CODE_PLAYBACK_SEEK_TO, args);
-    }
-
-    @Override
-    public void addPlaylistItem_impl(int index, MediaItem2 item) {
-        if (index < 0) {
-            throw new IllegalArgumentException("index shouldn't be negative");
-        }
-        if (item == null) {
-            throw new IllegalArgumentException("item shouldn't be null");
-        }
-        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_PLAYLIST_ADD_ITEM);
-        if (binder != null) {
-            try {
-                binder.addPlaylistItem(mControllerStub, index, item.toBundle());
-            } catch (RemoteException e) {
-                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-            }
-        } else {
-            Log.w(TAG, "Session isn't active", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void removePlaylistItem_impl(MediaItem2 item) {
-        if (item == null) {
-            throw new IllegalArgumentException("item shouldn't be null");
-        }
-        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_PLAYLIST_REMOVE_ITEM);
-        if (binder != null) {
-            try {
-                binder.removePlaylistItem(mControllerStub, item.toBundle());
-            } catch (RemoteException e) {
-                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-            }
-        } else {
-            Log.w(TAG, "Session isn't active", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void replacePlaylistItem_impl(int index, MediaItem2 item) {
-        if (index < 0) {
-            throw new IllegalArgumentException("index shouldn't be negative");
-        }
-        if (item == null) {
-            throw new IllegalArgumentException("item shouldn't be null");
-        }
-        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_PLAYLIST_REPLACE_ITEM);
-        if (binder != null) {
-            try {
-                binder.replacePlaylistItem(mControllerStub, index, item.toBundle());
-            } catch (RemoteException e) {
-                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-            }
-        } else {
-            Log.w(TAG, "Session isn't active", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public int getShuffleMode_impl() {
-        return mShuffleMode;
-    }
-
-    @Override
-    public void setShuffleMode_impl(int shuffleMode) {
-        final IMediaSession2 binder = getSessionBinderIfAble(
-                COMMAND_CODE_PLAYLIST_SET_SHUFFLE_MODE);
-        if (binder != null) {
-            try {
-                binder.setShuffleMode(mControllerStub, shuffleMode);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-            }
-        } else {
-            Log.w(TAG, "Session isn't active", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public int getRepeatMode_impl() {
-        return mRepeatMode;
-    }
-
-    @Override
-    public void setRepeatMode_impl(int repeatMode) {
-        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_PLAYLIST_SET_REPEAT_MODE);
-        if (binder != null) {
-            try {
-                binder.setRepeatMode(mControllerStub, repeatMode);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
-            }
-        } else {
-            Log.w(TAG, "Session isn't active", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public PlaybackInfo getPlaybackInfo_impl() {
-        synchronized (mLock) {
-            return mPlaybackInfo;
-        }
-    }
-
-    @Override
-    public int getPlayerState_impl() {
-        synchronized (mLock) {
-            return mPlayerState;
-        }
-    }
-
-    @Override
-    public long getCurrentPosition_impl() {
-        synchronized (mLock) {
-            long timeDiff = System.currentTimeMillis() - mPositionEventTimeMs;
-            long expectedPosition = mPositionMs + (long) (mPlaybackSpeed * timeDiff);
-            return Math.max(0, expectedPosition);
-        }
-    }
-
-    @Override
-    public float getPlaybackSpeed_impl() {
-        synchronized (mLock) {
-            return mPlaybackSpeed;
-        }
-    }
-
-    @Override
-    public long getBufferedPosition_impl() {
-        synchronized (mLock) {
-            return mBufferedPositionMs;
-        }
-    }
-
-    @Override
-    public MediaItem2 getCurrentMediaItem_impl() {
-        // TODO(jaewan): Implement
-        return null;
-    }
-
-    void pushPlayerStateChanges(final int state) {
-        synchronized (mLock) {
-            mPlayerState = state;
-        }
-        mCallbackExecutor.execute(() -> {
-            if (!mInstance.isConnected()) {
-                return;
-            }
-            mCallback.onPlayerStateChanged(mInstance, state);
-        });
-    }
-
-    // TODO(jaewan): Rename to seek completed
-    void pushPositionChanges(final long eventTimeMs, final long positionMs) {
-        synchronized (mLock) {
-            mPositionEventTimeMs = eventTimeMs;
-            mPositionMs = positionMs;
-        }
-        mCallbackExecutor.execute(() -> {
-            if (!mInstance.isConnected()) {
-                return;
-            }
-            mCallback.onSeekCompleted(mInstance, positionMs);
-        });
-    }
-
-    void pushPlaybackSpeedChanges(final float speed) {
-        synchronized (mLock) {
-            mPlaybackSpeed = speed;
-        }
-        mCallbackExecutor.execute(() -> {
-            if (!mInstance.isConnected()) {
-                return;
-            }
-            mCallback.onPlaybackSpeedChanged(mInstance, speed);
-        });
-    }
-
-    void pushBufferedPositionChanges(final long bufferedPositionMs) {
-        synchronized (mLock) {
-            mBufferedPositionMs = bufferedPositionMs;
-        }
-        mCallbackExecutor.execute(() -> {
-            if (!mInstance.isConnected()) {
-                return;
-            }
-            // TODO(jaewan): Fix this -- it's now buffered state
-            //mCallback.onBufferedPositionChanged(mInstance, bufferedPositionMs);
-        });
-    }
-
-    void pushPlaybackInfoChanges(final PlaybackInfo info) {
-        synchronized (mLock) {
-            mPlaybackInfo = info;
-        }
-        mCallbackExecutor.execute(() -> {
-            if (!mInstance.isConnected()) {
-                return;
-            }
-            mCallback.onPlaybackInfoChanged(mInstance, info);
-        });
-    }
-
-    void pushPlaylistChanges(final List<MediaItem2> playlist, final MediaMetadata2 metadata) {
-        synchronized (mLock) {
-            mPlaylist = playlist;
-            mPlaylistMetadata = metadata;
-        }
-        mCallbackExecutor.execute(() -> {
-            if (!mInstance.isConnected()) {
-                return;
-            }
-            mCallback.onPlaylistChanged(mInstance, playlist, metadata);
-        });
-    }
-
-    void pushPlaylistMetadataChanges(MediaMetadata2 metadata) {
-        synchronized (mLock) {
-            mPlaylistMetadata = metadata;
-        }
-        mCallbackExecutor.execute(() -> {
-            if (!mInstance.isConnected()) {
-                return;
-            }
-            mCallback.onPlaylistMetadataChanged(mInstance, metadata);
-        });
-    }
-
-    void pushShuffleModeChanges(int shuffleMode) {
-        synchronized (mLock) {
-            mShuffleMode = shuffleMode;
-        }
-        mCallbackExecutor.execute(() -> {
-            if (!mInstance.isConnected()) {
-                return;
-            }
-            mCallback.onShuffleModeChanged(mInstance, shuffleMode);
-        });
-    }
-
-    void pushRepeatModeChanges(int repeatMode) {
-        synchronized (mLock) {
-            mRepeatMode = repeatMode;
-        }
-        mCallbackExecutor.execute(() -> {
-            if (!mInstance.isConnected()) {
-                return;
-            }
-            mCallback.onRepeatModeChanged(mInstance, repeatMode);
-        });
-    }
-
-    void pushError(int errorCode, Bundle extras) {
-        mCallbackExecutor.execute(() -> {
-            if (!mInstance.isConnected()) {
-                return;
-            }
-            mCallback.onError(mInstance, errorCode, extras);
-        });
-    }
-
-    // Should be used without a lock to prevent potential deadlock.
-    void onConnectedNotLocked(IMediaSession2 sessionBinder,
-            final SessionCommandGroup2 allowedCommands,
-            final int playerState,
-            final long positionEventTimeMs,
-            final long positionMs,
-            final float playbackSpeed,
-            final long bufferedPositionMs,
-            final PlaybackInfo info,
-            final int repeatMode,
-            final int shuffleMode,
-            final List<MediaItem2> playlist,
-            final PendingIntent sessionActivity) {
-        if (DEBUG) {
-            Log.d(TAG, "onConnectedNotLocked sessionBinder=" + sessionBinder
-                    + ", allowedCommands=" + allowedCommands);
-        }
-        boolean close = false;
-        try {
-            if (sessionBinder == null || allowedCommands == null) {
-                // Connection rejected.
-                close = true;
-                return;
-            }
-            synchronized (mLock) {
-                if (mIsReleased) {
-                    return;
-                }
-                if (mSessionBinder != null) {
-                    Log.e(TAG, "Cannot be notified about the connection result many times."
-                            + " Probably a bug or malicious app.");
-                    close = true;
-                    return;
-                }
-                mAllowedCommands = allowedCommands;
-                mPlayerState = playerState;
-                mPositionEventTimeMs = positionEventTimeMs;
-                mPositionMs = positionMs;
-                mPlaybackSpeed = playbackSpeed;
-                mBufferedPositionMs = bufferedPositionMs;
-                mPlaybackInfo = info;
-                mRepeatMode = repeatMode;
-                mShuffleMode = shuffleMode;
-                mPlaylist = playlist;
-                mSessionActivity = sessionActivity;
-                mSessionBinder = sessionBinder;
-                try {
-                    // Implementation for the local binder is no-op,
-                    // so can be used without worrying about deadlock.
-                    mSessionBinder.asBinder().linkToDeath(mDeathRecipient, 0);
-                } catch (RemoteException e) {
-                    if (DEBUG) {
-                        Log.d(TAG, "Session died too early.", e);
-                    }
-                    close = true;
-                    return;
-                }
-            }
-            // TODO(jaewan): Keep commands to prevents illegal API calls.
-            mCallbackExecutor.execute(() -> {
-                // Note: We may trigger ControllerCallbacks with the initial values
-                // But it's hard to define the order of the controller callbacks
-                // Only notify about the
-                mCallback.onConnected(mInstance, allowedCommands);
-            });
-        } finally {
-            if (close) {
-                // Trick to call release() without holding the lock, to prevent potential deadlock
-                // with the developer's custom lock within the ControllerCallback.onDisconnected().
-                mInstance.close();
-            }
-        }
-    }
-
-    void onCustomCommand(final SessionCommand2 command, final Bundle args,
-            final ResultReceiver receiver) {
-        if (DEBUG) {
-            Log.d(TAG, "onCustomCommand cmd=" + command);
-        }
-        mCallbackExecutor.execute(() -> {
-            // TODO(jaewan): Double check if the controller exists.
-            mCallback.onCustomCommand(mInstance, command, args, receiver);
-        });
-    }
-
-    void onAllowedCommandsChanged(final SessionCommandGroup2 commands) {
-        mCallbackExecutor.execute(() -> {
-            mCallback.onAllowedCommandsChanged(mInstance, commands);
-        });
-    }
-
-    void onCustomLayoutChanged(final List<CommandButton> layout) {
-        mCallbackExecutor.execute(() -> {
-            mCallback.onCustomLayoutChanged(mInstance, layout);
-        });
-    }
-
-    // This will be called on the main thread.
-    private class SessionServiceConnection implements ServiceConnection {
-        @Override
-        public void onServiceConnected(ComponentName name, IBinder service) {
-            // Note that it's always main-thread.
-            if (DEBUG) {
-                Log.d(TAG, "onServiceConnected " + name + " " + this);
-            }
-            // Sanity check
-            if (!mToken.getPackageName().equals(name.getPackageName())) {
-                Log.wtf(TAG, name + " was connected, but expected pkg="
-                        + mToken.getPackageName() + " with id=" + mToken.getId());
-                return;
-            }
-            final IMediaSession2 sessionBinder = IMediaSession2.Stub.asInterface(service);
-            connectToSession(sessionBinder);
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName name) {
-            // Temporal lose of the binding because of the service crash. System will automatically
-            // rebind, so just no-op.
-            // TODO(jaewan): Really? Either disconnect cleanly or
-            if (DEBUG) {
-                Log.w(TAG, "Session service " + name + " is disconnected.");
-            }
-        }
-
-        @Override
-        public void onBindingDied(ComponentName name) {
-            // Permanent lose of the binding because of the service package update or removed.
-            // This SessionServiceRecord will be removed accordingly, but forget session binder here
-            // for sure.
-            mInstance.close();
-        }
-    }
-
-    public static final class PlaybackInfoImpl implements PlaybackInfoProvider {
-
-        private static final String KEY_PLAYBACK_TYPE =
-                "android.media.playbackinfo_impl.playback_type";
-        private static final String KEY_CONTROL_TYPE =
-                "android.media.playbackinfo_impl.control_type";
-        private static final String KEY_MAX_VOLUME =
-                "android.media.playbackinfo_impl.max_volume";
-        private static final String KEY_CURRENT_VOLUME =
-                "android.media.playbackinfo_impl.current_volume";
-        private static final String KEY_AUDIO_ATTRIBUTES =
-                "android.media.playbackinfo_impl.audio_attrs";
-
-        private final PlaybackInfo mInstance;
-
-        private final int mPlaybackType;
-        private final int mControlType;
-        private final int mMaxVolume;
-        private final int mCurrentVolume;
-        private final AudioAttributes mAudioAttrs;
-
-        private PlaybackInfoImpl(int playbackType, AudioAttributes attrs, int controlType,
-                int max, int current) {
-            mPlaybackType = playbackType;
-            mAudioAttrs = attrs;
-            mControlType = controlType;
-            mMaxVolume = max;
-            mCurrentVolume = current;
-            mInstance = new PlaybackInfo(this);
-        }
-
-        @Override
-        public int getPlaybackType_impl() {
-            return mPlaybackType;
-        }
-
-        @Override
-        public AudioAttributes getAudioAttributes_impl() {
-            return mAudioAttrs;
-        }
-
-        @Override
-        public int getControlType_impl() {
-            return mControlType;
-        }
-
-        @Override
-        public int getMaxVolume_impl() {
-            return mMaxVolume;
-        }
-
-        @Override
-        public int getCurrentVolume_impl() {
-            return mCurrentVolume;
-        }
-
-        PlaybackInfo getInstance() {
-            return mInstance;
-        }
-
-        Bundle toBundle() {
-            Bundle bundle = new Bundle();
-            bundle.putInt(KEY_PLAYBACK_TYPE, mPlaybackType);
-            bundle.putInt(KEY_CONTROL_TYPE, mControlType);
-            bundle.putInt(KEY_MAX_VOLUME, mMaxVolume);
-            bundle.putInt(KEY_CURRENT_VOLUME, mCurrentVolume);
-            bundle.putParcelable(KEY_AUDIO_ATTRIBUTES, mAudioAttrs);
-            return bundle;
-        }
-
-        static PlaybackInfo createPlaybackInfo(int playbackType, AudioAttributes attrs,
-                int controlType, int max, int current) {
-            return new PlaybackInfoImpl(playbackType, attrs, controlType, max, current)
-                    .getInstance();
-        }
-
-        static PlaybackInfo fromBundle(Bundle bundle) {
-            if (bundle == null) {
-                return null;
-            }
-            final int volumeType = bundle.getInt(KEY_PLAYBACK_TYPE);
-            final int volumeControl = bundle.getInt(KEY_CONTROL_TYPE);
-            final int maxVolume = bundle.getInt(KEY_MAX_VOLUME);
-            final int currentVolume = bundle.getInt(KEY_CURRENT_VOLUME);
-            final AudioAttributes attrs = bundle.getParcelable(KEY_AUDIO_ATTRIBUTES);
-
-            return createPlaybackInfo(volumeType, attrs, volumeControl, maxVolume, currentVolume);
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/media/MediaController2Stub.java b/packages/MediaComponents/src/com/android/media/MediaController2Stub.java
deleted file mode 100644
index 2cfc5df..0000000
--- a/packages/MediaComponents/src/com/android/media/MediaController2Stub.java
+++ /dev/null
@@ -1,470 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.media;
-
-import android.app.PendingIntent;
-import android.content.Context;
-import android.media.MediaController2;
-import android.media.MediaItem2;
-import android.media.MediaMetadata2;
-import android.media.SessionCommand2;
-import android.media.MediaSession2.CommandButton;
-import android.media.SessionCommandGroup2;
-import android.os.Bundle;
-import android.os.ResultReceiver;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.media.MediaController2Impl.PlaybackInfoImpl;
-import com.android.media.MediaSession2Impl.CommandButtonImpl;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.List;
-
-public class MediaController2Stub extends IMediaController2.Stub {
-    private static final String TAG = "MediaController2Stub";
-    private static final boolean DEBUG = true; // TODO(jaewan): Change
-
-    private final WeakReference<MediaController2Impl> mController;
-
-    MediaController2Stub(MediaController2Impl controller) {
-        mController = new WeakReference<>(controller);
-    }
-
-    private MediaController2Impl getController() throws IllegalStateException {
-        final MediaController2Impl controller = mController.get();
-        if (controller == null) {
-            throw new IllegalStateException("Controller is released");
-        }
-        return controller;
-    }
-
-    private MediaBrowser2Impl getBrowser() throws IllegalStateException {
-        final MediaController2Impl controller = getController();
-        if (controller instanceof MediaBrowser2Impl) {
-            return (MediaBrowser2Impl) controller;
-        }
-        return null;
-    }
-
-    public void destroy() {
-        mController.clear();
-    }
-
-    @Override
-    public void onPlayerStateChanged(int state) {
-        final MediaController2Impl controller;
-        try {
-            controller = getController();
-        } catch (IllegalStateException e) {
-            Log.w(TAG, "Don't fail silently here. Highly likely a bug");
-            return;
-        }
-        controller.pushPlayerStateChanges(state);
-    }
-
-    @Override
-    public void onPositionChanged(long eventTimeMs, long positionMs) {
-        final MediaController2Impl controller;
-        try {
-            controller = getController();
-        } catch (IllegalStateException e) {
-            Log.w(TAG, "Don't fail silently here. Highly likely a bug");
-            return;
-        }
-        if (eventTimeMs < 0) {
-            Log.w(TAG, "onPositionChanged(): Ignoring negative eventTimeMs");
-            return;
-        }
-        if (positionMs < 0) {
-            Log.w(TAG, "onPositionChanged(): Ignoring negative positionMs");
-            return;
-        }
-        controller.pushPositionChanges(eventTimeMs, positionMs);
-    }
-
-    @Override
-    public void onPlaybackSpeedChanged(float speed) {
-        final MediaController2Impl controller;
-        try {
-            controller = getController();
-        } catch (IllegalStateException e) {
-            Log.w(TAG, "Don't fail silently here. Highly likely a bug");
-            return;
-        }
-        controller.pushPlaybackSpeedChanges(speed);
-    }
-
-    @Override
-    public void onBufferedPositionChanged(long bufferedPositionMs) {
-        final MediaController2Impl controller;
-        try {
-            controller = getController();
-        } catch (IllegalStateException e) {
-            Log.w(TAG, "Don't fail silently here. Highly likely a bug");
-            return;
-        }
-        if (bufferedPositionMs < 0) {
-            Log.w(TAG, "onBufferedPositionChanged(): Ignoring negative bufferedPositionMs");
-            return;
-        }
-        controller.pushBufferedPositionChanges(bufferedPositionMs);
-    }
-
-    @Override
-    public void onPlaylistChanged(List<Bundle> playlistBundle, Bundle metadataBundle) {
-        final MediaController2Impl controller;
-        try {
-            controller = getController();
-        } catch (IllegalStateException e) {
-            Log.w(TAG, "Don't fail silently here. Highly likely a bug");
-            return;
-        }
-        if (playlistBundle == null) {
-            Log.w(TAG, "onPlaylistChanged(): Ignoring null playlist from " + controller);
-            return;
-        }
-        List<MediaItem2> playlist = new ArrayList<>();
-        for (Bundle bundle : playlistBundle) {
-            MediaItem2 item = MediaItem2.fromBundle(bundle);
-            if (item == null) {
-                Log.w(TAG, "onPlaylistChanged(): Ignoring null item in playlist");
-            } else {
-                playlist.add(item);
-            }
-        }
-        MediaMetadata2 metadata = MediaMetadata2.fromBundle(metadataBundle);
-        controller.pushPlaylistChanges(playlist, metadata);
-    }
-
-    @Override
-    public void onPlaylistMetadataChanged(Bundle metadataBundle) throws RuntimeException {
-        final MediaController2Impl controller;
-        try {
-            controller = getController();
-        } catch (IllegalStateException e) {
-            Log.w(TAG, "Don't fail silently here. Highly likely a bug");
-            return;
-        }
-        MediaMetadata2 metadata = MediaMetadata2.fromBundle(metadataBundle);
-        controller.pushPlaylistMetadataChanges(metadata);
-    }
-
-    @Override
-    public void onRepeatModeChanged(int repeatMode) {
-        final MediaController2Impl controller;
-        try {
-            controller = getController();
-        } catch (IllegalStateException e) {
-            Log.w(TAG, "Don't fail silently here. Highly likely a bug");
-            return;
-        }
-        controller.pushRepeatModeChanges(repeatMode);
-    }
-
-    @Override
-    public void onPlaybackInfoChanged(Bundle playbackInfo) throws RuntimeException {
-        if (DEBUG) {
-            Log.d(TAG, "onPlaybackInfoChanged");
-        }
-        final MediaController2Impl controller;
-        try {
-            controller = getController();
-        } catch (IllegalStateException e) {
-            Log.w(TAG, "Don't fail silently here. Highly likely a bug");
-            return;
-        }
-        MediaController2.PlaybackInfo info = PlaybackInfoImpl.fromBundle(playbackInfo);
-        if (info == null) {
-            Log.w(TAG, "onPlaybackInfoChanged(): Ignoring null playbackInfo");
-            return;
-        }
-        controller.pushPlaybackInfoChanges(info);
-    }
-
-    @Override
-    public void onShuffleModeChanged(int shuffleMode) {
-        final MediaController2Impl controller;
-        try {
-            controller = getController();
-        } catch (IllegalStateException e) {
-            Log.w(TAG, "Don't fail silently here. Highly likely a bug");
-            return;
-        }
-        controller.pushShuffleModeChanges(shuffleMode);
-    }
-
-    @Override
-    public void onError(int errorCode, Bundle extras) {
-        final MediaController2Impl controller;
-        try {
-            controller = getController();
-        } catch (IllegalStateException e) {
-            Log.w(TAG, "Don't fail silently here. Highly likely a bug");
-            return;
-        }
-        controller.pushError(errorCode, extras);
-    }
-
-    @Override
-    public void onConnected(IMediaSession2 sessionBinder, Bundle commandGroup,
-            int playerState, long positionEventTimeMs, long positionMs, float playbackSpeed,
-            long bufferedPositionMs, Bundle playbackInfo, int shuffleMode, int repeatMode,
-            List<Bundle> itemBundleList, PendingIntent sessionActivity) {
-        final MediaController2Impl controller = mController.get();
-        if (controller == null) {
-            if (DEBUG) {
-                Log.d(TAG, "onConnected after MediaController2.close()");
-            }
-            return;
-        }
-        final Context context = controller.getContext();
-        List<MediaItem2> itemList = null;
-        if (itemBundleList != null) {
-            itemList = new ArrayList<>();
-            for (int i = 0; i < itemBundleList.size(); i++) {
-                MediaItem2 item = MediaItem2.fromBundle(itemBundleList.get(i));
-                if (item != null) {
-                    itemList.add(item);
-                }
-            }
-        }
-        controller.onConnectedNotLocked(sessionBinder,
-                SessionCommandGroup2.fromBundle(commandGroup),
-                playerState, positionEventTimeMs, positionMs, playbackSpeed, bufferedPositionMs,
-                PlaybackInfoImpl.fromBundle(playbackInfo), repeatMode, shuffleMode,
-                itemList, sessionActivity);
-    }
-
-    @Override
-    public void onDisconnected() {
-        final MediaController2Impl controller = mController.get();
-        if (controller == null) {
-            if (DEBUG) {
-                Log.d(TAG, "onDisconnected after MediaController2.close()");
-            }
-            return;
-        }
-        controller.getInstance().close();
-    }
-
-    @Override
-    public void onCustomLayoutChanged(List<Bundle> commandButtonlist) {
-        if (commandButtonlist == null) {
-            Log.w(TAG, "onCustomLayoutChanged(): Ignoring null commandButtonlist");
-            return;
-        }
-        final MediaController2Impl controller;
-        try {
-            controller = getController();
-        } catch (IllegalStateException e) {
-            Log.w(TAG, "Don't fail silently here. Highly likely a bug");
-            return;
-        }
-        if (controller == null) {
-            // TODO(jaewan): Revisit here. Could be a bug
-            return;
-        }
-        List<CommandButton> layout = new ArrayList<>();
-        for (int i = 0; i < commandButtonlist.size(); i++) {
-            CommandButton button = CommandButtonImpl.fromBundle(commandButtonlist.get(i));
-            if (button != null) {
-                layout.add(button);
-            }
-        }
-        controller.onCustomLayoutChanged(layout);
-    }
-
-    @Override
-    public void onAllowedCommandsChanged(Bundle commandsBundle) {
-        final MediaController2Impl controller;
-        try {
-            controller = getController();
-        } catch (IllegalStateException e) {
-            Log.w(TAG, "Don't fail silently here. Highly likely a bug");
-            return;
-        }
-        if (controller == null) {
-            // TODO(jaewan): Revisit here. Could be a bug
-            return;
-        }
-        SessionCommandGroup2 commands = SessionCommandGroup2.fromBundle(commandsBundle);
-        if (commands == null) {
-            Log.w(TAG, "onAllowedCommandsChanged(): Ignoring null commands");
-            return;
-        }
-        controller.onAllowedCommandsChanged(commands);
-    }
-
-    @Override
-    public void onCustomCommand(Bundle commandBundle, Bundle args, ResultReceiver receiver) {
-        final MediaController2Impl controller;
-        try {
-            controller = getController();
-        } catch (IllegalStateException e) {
-            Log.w(TAG, "Don't fail silently here. Highly likely a bug");
-            return;
-        }
-        SessionCommand2 command = SessionCommand2.fromBundle(commandBundle);
-        if (command == null) {
-            Log.w(TAG, "onCustomCommand(): Ignoring null command");
-            return;
-        }
-        controller.onCustomCommand(command, args, receiver);
-    }
-
-    ////////////////////////////////////////////////////////////////////////////////////////////
-    // MediaBrowser specific
-    ////////////////////////////////////////////////////////////////////////////////////////////
-    @Override
-    public void onGetLibraryRootDone(Bundle rootHints, String rootMediaId, Bundle rootExtra)
-            throws RuntimeException {
-        final MediaBrowser2Impl browser;
-        try {
-            browser = getBrowser();
-        } catch (IllegalStateException e) {
-            Log.w(TAG, "Don't fail silently here. Highly likely a bug");
-            return;
-        }
-        if (browser == null) {
-            // TODO(jaewan): Revisit here. Could be a bug
-            return;
-        }
-        browser.onGetLibraryRootDone(rootHints, rootMediaId, rootExtra);
-    }
-
-
-    @Override
-    public void onGetItemDone(String mediaId, Bundle itemBundle) throws RuntimeException {
-        if (mediaId == null) {
-            Log.w(TAG, "onGetItemDone(): Ignoring null mediaId");
-            return;
-        }
-        final MediaBrowser2Impl browser;
-        try {
-            browser = getBrowser();
-        } catch (IllegalStateException e) {
-            Log.w(TAG, "Don't fail silently here. Highly likely a bug");
-            return;
-        }
-        if (browser == null) {
-            // TODO(jaewan): Revisit here. Could be a bug
-            return;
-        }
-        browser.onGetItemDone(mediaId, MediaItem2.fromBundle(itemBundle));
-    }
-
-    @Override
-    public void onGetChildrenDone(String parentId, int page, int pageSize,
-            List<Bundle> itemBundleList, Bundle extras) throws RuntimeException {
-        if (parentId == null) {
-            Log.w(TAG, "onGetChildrenDone(): Ignoring null parentId");
-            return;
-        }
-        final MediaBrowser2Impl browser;
-        try {
-            browser = getBrowser();
-        } catch (IllegalStateException e) {
-            Log.w(TAG, "Don't fail silently here. Highly likely a bug");
-            return;
-        }
-        if (browser == null) {
-            // TODO(jaewan): Revisit here. Could be a bug
-            return;
-        }
-
-        List<MediaItem2> result = null;
-        if (itemBundleList != null) {
-            result = new ArrayList<>();
-            for (Bundle bundle : itemBundleList) {
-                result.add(MediaItem2.fromBundle(bundle));
-            }
-        }
-        browser.onGetChildrenDone(parentId, page, pageSize, result, extras);
-    }
-
-    @Override
-    public void onSearchResultChanged(String query, int itemCount, Bundle extras)
-            throws RuntimeException {
-        if (TextUtils.isEmpty(query)) {
-            Log.w(TAG, "onSearchResultChanged(): Ignoring empty query");
-            return;
-        }
-        final MediaBrowser2Impl browser;
-        try {
-            browser = getBrowser();
-        } catch (IllegalStateException e) {
-            Log.w(TAG, "Don't fail silently here. Highly likely a bug");
-            return;
-        }
-        if (browser == null) {
-            // TODO(jaewan): Revisit here. Could be a bug
-            return;
-        }
-        browser.onSearchResultChanged(query, itemCount, extras);
-    }
-
-    @Override
-    public void onGetSearchResultDone(String query, int page, int pageSize,
-            List<Bundle> itemBundleList, Bundle extras) throws RuntimeException {
-        if (TextUtils.isEmpty(query)) {
-            Log.w(TAG, "onGetSearchResultDone(): Ignoring empty query");
-            return;
-        }
-        final MediaBrowser2Impl browser;
-        try {
-            browser = getBrowser();
-        } catch (IllegalStateException e) {
-            Log.w(TAG, "Don't fail silently here. Highly likely a bug");
-            return;
-        }
-        if (browser == null) {
-            // TODO(jaewan): Revisit here. Could be a bug
-            return;
-        }
-
-        List<MediaItem2> result = null;
-        if (itemBundleList != null) {
-            result = new ArrayList<>();
-            for (Bundle bundle : itemBundleList) {
-                result.add(MediaItem2.fromBundle(bundle));
-            }
-        }
-        browser.onGetSearchResultDone(query, page, pageSize, result, extras);
-    }
-
-    @Override
-    public void onChildrenChanged(String parentId, int itemCount, Bundle extras) {
-        if (parentId == null) {
-            Log.w(TAG, "onChildrenChanged(): Ignoring null parentId");
-            return;
-        }
-        final MediaBrowser2Impl browser;
-        try {
-            browser = getBrowser();
-        } catch (IllegalStateException e) {
-            Log.w(TAG, "Don't fail silently here. Highly likely a bug");
-            return;
-        }
-        if (browser == null) {
-            // TODO(jaewan): Revisit here. Could be a bug
-            return;
-        }
-        browser.onChildrenChanged(parentId, itemCount, extras);
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/media/MediaItem2Impl.java b/packages/MediaComponents/src/com/android/media/MediaItem2Impl.java
deleted file mode 100644
index 910a0f1..0000000
--- a/packages/MediaComponents/src/com/android/media/MediaItem2Impl.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.media;
-
-import static android.media.MediaItem2.FLAG_BROWSABLE;
-import static android.media.MediaItem2.FLAG_PLAYABLE;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.media.DataSourceDesc;
-import android.media.MediaItem2;
-import android.media.MediaItem2.Builder;
-import android.media.MediaItem2.Flags;
-import android.media.MediaMetadata2;
-import android.media.update.MediaItem2Provider;
-import android.os.Bundle;
-import android.text.TextUtils;
-
-import java.util.UUID;
-
-public class MediaItem2Impl implements MediaItem2Provider {
-    private static final String KEY_ID = "android.media.mediaitem2.id";
-    private static final String KEY_FLAGS = "android.media.mediaitem2.flags";
-    private static final String KEY_METADATA = "android.media.mediaitem2.metadata";
-    private static final String KEY_UUID = "android.media.mediaitem2.uuid";
-
-    private final MediaItem2 mInstance;
-    private final String mId;
-    private final int mFlags;
-    private final UUID mUUID;
-    private MediaMetadata2 mMetadata;
-    private DataSourceDesc mDataSourceDesc;
-
-    // From the public API
-    public MediaItem2Impl(@NonNull String mediaId, @Nullable DataSourceDesc dsd,
-            @Nullable MediaMetadata2 metadata, @Flags int flags) {
-        this(mediaId, dsd, metadata, flags, null);
-    }
-
-    private MediaItem2Impl(@NonNull String mediaId, @Nullable DataSourceDesc dsd,
-            @Nullable MediaMetadata2 metadata, @Flags int flags, @Nullable UUID uuid) {
-        if (mediaId == null) {
-            throw new IllegalArgumentException("mediaId shouldn't be null");
-        }
-        if (metadata != null && !TextUtils.equals(mediaId, metadata.getMediaId())) {
-            throw new IllegalArgumentException("metadata's id should be matched with the mediaid");
-        }
-
-        mId = mediaId;
-        mDataSourceDesc = dsd;
-        mMetadata = metadata;
-        mFlags = flags;
-        mUUID = (uuid == null) ? UUID.randomUUID() : uuid;
-
-        mInstance = new MediaItem2(this);
-    }
-
-    @Override
-    public boolean equals_impl(Object obj) {
-        if (!(obj instanceof MediaItem2)) {
-            return false;
-        }
-        MediaItem2 other = (MediaItem2) obj;
-        return mUUID.equals(((MediaItem2Impl) other.getProvider()).mUUID);
-    }
-
-    /**
-     * Return this object as a bundle to share between processes.
-     *
-     * @return a new bundle instance
-     */
-    public Bundle toBundle_impl() {
-        Bundle bundle = new Bundle();
-        bundle.putString(KEY_ID, mId);
-        bundle.putInt(KEY_FLAGS, mFlags);
-        if (mMetadata != null) {
-            bundle.putBundle(KEY_METADATA, mMetadata.toBundle());
-        }
-        bundle.putString(KEY_UUID, mUUID.toString());
-        return bundle;
-    }
-
-    /**
-     * Create a MediaItem2 from the {@link Bundle}.
-     *
-     * @param bundle The bundle which was published by {@link MediaItem2#toBundle()}.
-     * @return The newly created MediaItem2
-     */
-    public static MediaItem2 fromBundle_impl(@NonNull Bundle bundle) {
-        if (bundle == null) {
-            return null;
-        }
-        final String uuidString = bundle.getString(KEY_UUID);
-        return fromBundle(bundle, UUID.fromString(uuidString));
-    }
-
-    /**
-     * Create a MediaItem2 from the {@link Bundle} with the specified {@link UUID}.
-     * If {@link UUID}
-     * can be null for creating new.
-     *
-     * @param bundle The bundle which was published by {@link MediaItem2#toBundle()}.
-     * @param uuid A {@link UUID} to override. Can be {@link null} for override.
-     * @return The newly created MediaItem2
-     */
-    static MediaItem2 fromBundle(@NonNull Bundle bundle, @Nullable UUID uuid) {
-        if (bundle == null) {
-            return null;
-        }
-        final String id = bundle.getString(KEY_ID);
-        final Bundle metadataBundle = bundle.getBundle(KEY_METADATA);
-        final MediaMetadata2 metadata = MediaMetadata2.fromBundle(metadataBundle);
-        final int flags = bundle.getInt(KEY_FLAGS);
-        return new MediaItem2Impl(id, null, metadata, flags, uuid).getInstance();
-    }
-
-    private MediaItem2 getInstance() {
-        return mInstance;
-    }
-
-    @Override
-    public String toString_impl() {
-        final StringBuilder sb = new StringBuilder("MediaItem2{");
-        sb.append("mFlags=").append(mFlags);
-        sb.append(", mMetadata=").append(mMetadata);
-        sb.append('}');
-        return sb.toString();
-    }
-
-    @Override
-    public @Flags int getFlags_impl() {
-        return mFlags;
-    }
-
-    @Override
-    public boolean isBrowsable_impl() {
-        return (mFlags & FLAG_BROWSABLE) != 0;
-    }
-
-    @Override
-    public boolean isPlayable_impl() {
-        return (mFlags & FLAG_PLAYABLE) != 0;
-    }
-
-    @Override
-    public void setMetadata_impl(@Nullable MediaMetadata2 metadata) {
-        if (metadata != null && !TextUtils.equals(mId, metadata.getMediaId())) {
-            throw new IllegalArgumentException("metadata's id should be matched with the mediaId");
-        }
-        mMetadata = metadata;
-    }
-
-    @Override
-    public @Nullable MediaMetadata2 getMetadata_impl() {
-        return mMetadata;
-    }
-
-    @Override
-    public @NonNull String getMediaId_impl() {
-        return mId;
-    }
-
-    @Override
-    public @Nullable DataSourceDesc getDataSourceDesc_impl() {
-        return mDataSourceDesc;
-    }
-
-    public static class BuilderImpl implements MediaItem2Provider.BuilderProvider {
-        private Builder mInstance;
-        private @Flags int mFlags;
-        private String mMediaId;
-        private MediaMetadata2 mMetadata;
-        private DataSourceDesc mDataSourceDesc;
-
-        public BuilderImpl(Builder instance, int flags) {
-            mInstance = instance;
-            mFlags = flags;
-        }
-
-        @Override
-        public Builder setMediaId_impl(@Nullable String mediaId) {
-            mMediaId = mediaId;
-            return mInstance;
-        }
-
-        @Override
-        public Builder setMetadata_impl(@Nullable MediaMetadata2 metadata) {
-            mMetadata = metadata;
-            return mInstance;
-        }
-
-        @Override
-        public Builder setDataSourceDesc_impl(@Nullable DataSourceDesc dataSourceDesc) {
-            mDataSourceDesc = dataSourceDesc;
-            return mInstance;
-        }
-
-        @Override
-        public MediaItem2 build_impl() {
-            String id = (mMetadata != null)
-                    ? mMetadata.getString(MediaMetadata2.METADATA_KEY_MEDIA_ID) : null;
-            if (id == null) {
-                //  TODO(jaewan): Double check if its sufficient (e.g. Use UUID instead?)
-                id = (mMediaId != null) ? mMediaId : toString();
-            }
-            return new MediaItem2Impl(id, mDataSourceDesc, mMetadata, mFlags).getInstance();
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/media/MediaLibraryService2Impl.java b/packages/MediaComponents/src/com/android/media/MediaLibraryService2Impl.java
deleted file mode 100644
index cf34cd4..0000000
--- a/packages/MediaComponents/src/com/android/media/MediaLibraryService2Impl.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.media;
-
-import android.app.PendingIntent;
-import android.content.Context;
-import android.media.MediaLibraryService2;
-import android.media.MediaLibraryService2.LibraryRoot;
-import android.media.MediaLibraryService2.MediaLibrarySession;
-import android.media.MediaLibraryService2.MediaLibrarySession.Builder;
-import android.media.MediaLibraryService2.MediaLibrarySession.MediaLibrarySessionCallback;
-import android.media.MediaPlayerBase;
-import android.media.MediaPlaylistAgent;
-import android.media.MediaSession2;
-import android.media.MediaSession2.ControllerInfo;
-import android.media.MediaSessionService2;
-import android.media.SessionToken2;
-import android.media.VolumeProvider2;
-import android.media.update.MediaLibraryService2Provider;
-import android.os.Bundle;
-import android.text.TextUtils;
-
-import com.android.media.MediaSession2Impl.BuilderBaseImpl;
-
-import java.util.concurrent.Executor;
-
-public class MediaLibraryService2Impl extends MediaSessionService2Impl implements
-        MediaLibraryService2Provider {
-    private final MediaSessionService2 mInstance;
-    private MediaLibrarySession mLibrarySession;
-
-    public MediaLibraryService2Impl(MediaLibraryService2 instance) {
-        super(instance);
-        mInstance = instance;
-    }
-
-    @Override
-    public void onCreate_impl() {
-        super.onCreate_impl();
-
-        // Effectively final
-        MediaSession2 session = getSession();
-        if (!(session instanceof MediaLibrarySession)) {
-            throw new RuntimeException("Expected MediaLibrarySession, but returned MediaSession2");
-        }
-        mLibrarySession = (MediaLibrarySession) getSession();
-    }
-
-    @Override
-    int getSessionType() {
-        return SessionToken2.TYPE_LIBRARY_SERVICE;
-    }
-
-    public static class MediaLibrarySessionImpl extends MediaSession2Impl
-            implements MediaLibrarySessionProvider {
-        public MediaLibrarySessionImpl(Context context,
-                MediaPlayerBase player, String id, MediaPlaylistAgent playlistAgent,
-                VolumeProvider2 volumeProvider,
-                PendingIntent sessionActivity, Executor callbackExecutor,
-                MediaLibrarySessionCallback callback) {
-            super(context, player, id, playlistAgent, volumeProvider, sessionActivity,
-                    callbackExecutor, callback);
-            // Don't put any extra initialization here. Here's the reason.
-            // System service will recognize this session inside of the super constructor and would
-            // connect to this session assuming that initialization is finished. However, if any
-            // initialization logic is here, calls from the server would fail.
-            // see: MediaSession2Stub#connect()
-        }
-
-        @Override
-        MediaLibrarySession createInstance() {
-            return new MediaLibrarySession(this);
-        }
-
-        @Override
-        MediaLibrarySession getInstance() {
-            return (MediaLibrarySession) super.getInstance();
-        }
-
-        @Override
-        MediaLibrarySessionCallback getCallback() {
-            return (MediaLibrarySessionCallback) super.getCallback();
-        }
-
-        @Override
-        public void notifyChildrenChanged_impl(ControllerInfo controller, String parentId,
-                int itemCount, Bundle extras) {
-            if (controller == null) {
-                throw new IllegalArgumentException("controller shouldn't be null");
-            }
-            if (parentId == null) {
-                throw new IllegalArgumentException("parentId shouldn't be null");
-            }
-            getSessionStub().notifyChildrenChangedNotLocked(controller, parentId, itemCount,
-                    extras);
-        }
-
-        @Override
-        public void notifyChildrenChanged_impl(String parentId, int itemCount, Bundle extras) {
-            if (parentId == null) {
-                throw new IllegalArgumentException("parentId shouldn't be null");
-            }
-            getSessionStub().notifyChildrenChangedNotLocked(parentId, itemCount, extras);
-        }
-
-        @Override
-        public void notifySearchResultChanged_impl(ControllerInfo controller, String query,
-                int itemCount, Bundle extras) {
-            ensureCallingThread();
-            if (controller == null) {
-                throw new IllegalArgumentException("controller shouldn't be null");
-            }
-            if (TextUtils.isEmpty(query)) {
-                throw new IllegalArgumentException("query shouldn't be empty");
-            }
-            getSessionStub().notifySearchResultChanged(controller, query, itemCount, extras);
-        }
-    }
-
-    public static class BuilderImpl
-            extends BuilderBaseImpl<MediaLibrarySession, MediaLibrarySessionCallback> {
-        public BuilderImpl(MediaLibraryService2 service, Builder instance,
-                Executor callbackExecutor, MediaLibrarySessionCallback callback) {
-            super(service);
-            setSessionCallback_impl(callbackExecutor, callback);
-        }
-
-        @Override
-        public MediaLibrarySession build_impl() {
-            return new MediaLibrarySessionImpl(mContext, mPlayer, mId, mPlaylistAgent,
-                    mVolumeProvider, mSessionActivity, mCallbackExecutor, mCallback).getInstance();
-        }
-    }
-
-    public static final class LibraryRootImpl implements LibraryRootProvider {
-        private final LibraryRoot mInstance;
-        private final String mRootId;
-        private final Bundle mExtras;
-
-        public LibraryRootImpl(LibraryRoot instance, String rootId, Bundle extras) {
-            if (rootId == null) {
-                throw new IllegalArgumentException("rootId shouldn't be null.");
-            }
-            mInstance = instance;
-            mRootId = rootId;
-            mExtras = extras;
-        }
-
-        @Override
-        public String getRootId_impl() {
-            return mRootId;
-        }
-
-        @Override
-        public Bundle getExtras_impl() {
-            return mExtras;
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/media/MediaMetadata2Impl.java b/packages/MediaComponents/src/com/android/media/MediaMetadata2Impl.java
deleted file mode 100644
index cf1c532..0000000
--- a/packages/MediaComponents/src/com/android/media/MediaMetadata2Impl.java
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.media;
-
-import static android.media.MediaMetadata2.*;
-
-import android.annotation.Nullable;
-import android.graphics.Bitmap;
-import android.media.MediaMetadata2;
-import android.media.MediaMetadata2.BitmapKey;
-import android.media.MediaMetadata2.Builder;
-import android.media.MediaMetadata2.LongKey;
-import android.media.MediaMetadata2.RatingKey;
-import android.media.MediaMetadata2.TextKey;
-import android.media.Rating2;
-import android.media.update.MediaMetadata2Provider;
-import android.os.Bundle;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import java.util.Set;
-
-public class MediaMetadata2Impl implements MediaMetadata2Provider {
-    private static final String TAG = "MediaMetadata2";
-
-    static final int METADATA_TYPE_LONG = 0;
-    static final int METADATA_TYPE_TEXT = 1;
-    static final int METADATA_TYPE_BITMAP = 2;
-    static final int METADATA_TYPE_RATING = 3;
-    static final int METADATA_TYPE_FLOAT = 4;
-    static final ArrayMap<String, Integer> METADATA_KEYS_TYPE;
-
-    static {
-        METADATA_KEYS_TYPE = new ArrayMap<String, Integer>();
-        METADATA_KEYS_TYPE.put(METADATA_KEY_TITLE, METADATA_TYPE_TEXT);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_ARTIST, METADATA_TYPE_TEXT);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_DURATION, METADATA_TYPE_LONG);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM, METADATA_TYPE_TEXT);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_AUTHOR, METADATA_TYPE_TEXT);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_WRITER, METADATA_TYPE_TEXT);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_COMPOSER, METADATA_TYPE_TEXT);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_COMPILATION, METADATA_TYPE_TEXT);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_DATE, METADATA_TYPE_TEXT);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_YEAR, METADATA_TYPE_LONG);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_GENRE, METADATA_TYPE_TEXT);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_TRACK_NUMBER, METADATA_TYPE_LONG);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_NUM_TRACKS, METADATA_TYPE_LONG);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_DISC_NUMBER, METADATA_TYPE_LONG);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM_ARTIST, METADATA_TYPE_TEXT);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_ART, METADATA_TYPE_BITMAP);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_ART_URI, METADATA_TYPE_TEXT);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM_ART, METADATA_TYPE_BITMAP);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM_ART_URI, METADATA_TYPE_TEXT);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_USER_RATING, METADATA_TYPE_RATING);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_RATING, METADATA_TYPE_RATING);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_DISPLAY_TITLE, METADATA_TYPE_TEXT);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_DISPLAY_SUBTITLE, METADATA_TYPE_TEXT);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_DISPLAY_DESCRIPTION, METADATA_TYPE_TEXT);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_DISPLAY_ICON, METADATA_TYPE_BITMAP);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_DISPLAY_ICON_URI, METADATA_TYPE_TEXT);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_MEDIA_ID, METADATA_TYPE_TEXT);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_BT_FOLDER_TYPE, METADATA_TYPE_LONG);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_MEDIA_URI, METADATA_TYPE_TEXT);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_ADVERTISEMENT, METADATA_TYPE_LONG);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_DOWNLOAD_STATUS, METADATA_TYPE_LONG);
-    }
-
-    private static final @TextKey
-    String[] PREFERRED_DESCRIPTION_ORDER = {
-            METADATA_KEY_TITLE,
-            METADATA_KEY_ARTIST,
-            METADATA_KEY_ALBUM,
-            METADATA_KEY_ALBUM_ARTIST,
-            METADATA_KEY_WRITER,
-            METADATA_KEY_AUTHOR,
-            METADATA_KEY_COMPOSER
-    };
-
-    private static final @BitmapKey
-    String[] PREFERRED_BITMAP_ORDER = {
-            METADATA_KEY_DISPLAY_ICON,
-            METADATA_KEY_ART,
-            METADATA_KEY_ALBUM_ART
-    };
-
-    private static final @TextKey
-    String[] PREFERRED_URI_ORDER = {
-            METADATA_KEY_DISPLAY_ICON_URI,
-            METADATA_KEY_ART_URI,
-            METADATA_KEY_ALBUM_ART_URI
-    };
-
-    private final MediaMetadata2 mInstance;
-    private final Bundle mBundle;
-
-    public MediaMetadata2Impl(Bundle bundle) {
-        mInstance = new MediaMetadata2(this);
-        mBundle = bundle;
-    }
-
-    public MediaMetadata2 getInstance() {
-        return mInstance;
-    }
-
-    @Override
-    public boolean containsKey_impl(String key) {
-        if (key == null) {
-            throw new IllegalArgumentException("key shouldn't be null");
-        }
-        return mBundle.containsKey(key);
-    }
-
-    @Override
-    public CharSequence getText_impl(@TextKey String key) {
-        if (key == null) {
-            throw new IllegalArgumentException("key shouldn't be null");
-        }
-        return mBundle.getCharSequence(key);
-    }
-
-    @Override
-    public @Nullable String getMediaId_impl() {
-        return mInstance.getString(METADATA_KEY_MEDIA_ID);
-    }
-
-    @Override
-    public String getString_impl(@TextKey String key) {
-        if (key == null) {
-            throw new IllegalArgumentException("key shouldn't be null");
-        }
-        CharSequence text = mBundle.getCharSequence(key);
-        if (text != null) {
-            return text.toString();
-        }
-        return null;
-    }
-
-    @Override
-    public long getLong_impl(@LongKey String key) {
-        if (key == null) {
-            throw new IllegalArgumentException("key shouldn't be null");
-        }
-        return mBundle.getLong(key, 0);
-    }
-
-    @Override
-    public Rating2 getRating_impl(@RatingKey String key) {
-        if (key == null) {
-            throw new IllegalArgumentException("key shouldn't be null");
-        }
-        // TODO(jaewan): Add backward compatibility
-        Rating2 rating = null;
-        try {
-            rating = Rating2.fromBundle(mBundle.getBundle(key));
-        } catch (Exception e) {
-            // ignore, value was not a rating
-            Log.w(TAG, "Failed to retrieve a key as Rating.", e);
-        }
-        return rating;
-    }
-
-    @Override
-    public float getFloat_impl(@FloatKey String key) {
-        if (key == null) {
-            throw new IllegalArgumentException("key shouldn't be null");
-        }
-        return mBundle.getFloat(key);
-    }
-
-    @Override
-    public Bitmap getBitmap_impl(@BitmapKey String key) {
-        if (key == null) {
-            throw new IllegalArgumentException("key shouldn't be null");
-        }
-        Bitmap bmp = null;
-        try {
-            bmp = mBundle.getParcelable(key);
-        } catch (Exception e) {
-            // ignore, value was not a bitmap
-            Log.w(TAG, "Failed to retrieve a key as Bitmap.", e);
-        }
-        return bmp;
-    }
-
-    @Override
-    public Bundle getExtras_impl() {
-        try {
-            return mBundle.getBundle(METADATA_KEY_EXTRAS);
-        } catch (Exception e) {
-            // ignore, value was not an bundle
-            Log.w(TAG, "Failed to retrieve an extra");
-        }
-        return null;
-    }
-
-    @Override
-    public int size_impl() {
-        return mBundle.size();
-    }
-
-    @Override
-    public Set<String> keySet_impl() {
-        return mBundle.keySet();
-    }
-
-    @Override
-    public Bundle toBundle_impl() {
-        return mBundle;
-    }
-
-    public static MediaMetadata2 fromBundle_impl(Bundle bundle) {
-        return (bundle == null) ? null : new MediaMetadata2Impl(bundle).getInstance();
-    }
-
-    public static final class BuilderImpl implements MediaMetadata2Provider.BuilderProvider {
-        private final MediaMetadata2.Builder mInstance;
-        private final Bundle mBundle;
-
-        public BuilderImpl(MediaMetadata2.Builder instance) {
-            mInstance = instance;
-            mBundle = new Bundle();
-        }
-
-        public BuilderImpl(MediaMetadata2.Builder instance, MediaMetadata2 source) {
-            if (source == null) {
-                throw new IllegalArgumentException("source shouldn't be null");
-            }
-            mInstance = instance;
-            mBundle = new Bundle(source.toBundle());
-        }
-
-        public BuilderImpl(int maxBitmapSize) {
-            mInstance = new MediaMetadata2.Builder(this);
-            mBundle = new Bundle();
-
-            for (String key : mBundle.keySet()) {
-                Object value = mBundle.get(key);
-                if (value instanceof Bitmap) {
-                    Bitmap bmp = (Bitmap) value;
-                    if (bmp.getHeight() > maxBitmapSize || bmp.getWidth() > maxBitmapSize) {
-                        mInstance.putBitmap(key, scaleBitmap(bmp, maxBitmapSize));
-                    }
-                }
-            }
-        }
-
-        @Override
-        public Builder putText_impl(@TextKey String key, CharSequence value) {
-            if (key == null) {
-                throw new IllegalArgumentException("key shouldn't be null");
-            }
-            if (METADATA_KEYS_TYPE.containsKey(key)) {
-                if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_TEXT) {
-                    throw new IllegalArgumentException("The " + key
-                            + " key cannot be used to put a CharSequence");
-                }
-            }
-            mBundle.putCharSequence(key, value);
-            return mInstance;
-        }
-
-        @Override
-        public Builder putString_impl(@TextKey String key, String value) {
-            if (key == null) {
-                throw new IllegalArgumentException("key shouldn't be null");
-            }
-            if (METADATA_KEYS_TYPE.containsKey(key)) {
-                if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_TEXT) {
-                    throw new IllegalArgumentException("The " + key
-                            + " key cannot be used to put a String");
-                }
-            }
-            mBundle.putCharSequence(key, value);
-            return mInstance;
-        }
-
-        @Override
-        public Builder putLong_impl(@LongKey String key, long value) {
-            if (key == null) {
-                throw new IllegalArgumentException("key shouldn't be null");
-            }
-            if (METADATA_KEYS_TYPE.containsKey(key)) {
-                if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_LONG) {
-                    throw new IllegalArgumentException("The " + key
-                            + " key cannot be used to put a long");
-                }
-            }
-            mBundle.putLong(key, value);
-            return mInstance;
-        }
-
-        @Override
-        public Builder putRating_impl(@RatingKey String key, Rating2 value) {
-            if (key == null) {
-                throw new IllegalArgumentException("key shouldn't be null");
-            }
-            if (METADATA_KEYS_TYPE.containsKey(key)) {
-                if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_RATING) {
-                    throw new IllegalArgumentException("The " + key
-                            + " key cannot be used to put a Rating");
-                }
-            }
-            mBundle.putBundle(key, value.toBundle());
-            return mInstance;
-        }
-
-        @Override
-        public Builder putBitmap_impl(@BitmapKey String key, Bitmap value) {
-            if (key == null) {
-                throw new IllegalArgumentException("key shouldn't be null");
-            }
-            if (METADATA_KEYS_TYPE.containsKey(key)) {
-                if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_BITMAP) {
-                    throw new IllegalArgumentException("The " + key
-                            + " key cannot be used to put a Bitmap");
-                }
-            }
-            mBundle.putParcelable(key, value);
-            return mInstance;
-        }
-
-        @Override
-        public Builder putFloat_impl(@FloatKey String key, float value) {
-            if (key == null) {
-                throw new IllegalArgumentException("key shouldn't be null");
-            }
-            if (METADATA_KEYS_TYPE.containsKey(key)) {
-                if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_FLOAT) {
-                    throw new IllegalArgumentException("The " + key
-                            + " key cannot be used to put a float");
-                }
-            }
-            mBundle.putFloat(key, value);
-            return mInstance;
-        }
-
-        @Override
-        public Builder setExtras_impl(Bundle bundle) {
-            mBundle.putBundle(METADATA_KEY_EXTRAS, bundle);
-            return mInstance;
-        }
-
-        @Override
-        public MediaMetadata2 build_impl() {
-            return new MediaMetadata2Impl(mBundle).getInstance();
-        }
-
-        private Bitmap scaleBitmap(Bitmap bmp, int maxSize) {
-            float maxSizeF = maxSize;
-            float widthScale = maxSizeF / bmp.getWidth();
-            float heightScale = maxSizeF / bmp.getHeight();
-            float scale = Math.min(widthScale, heightScale);
-            int height = (int) (bmp.getHeight() * scale);
-            int width = (int) (bmp.getWidth() * scale);
-            return Bitmap.createScaledBitmap(bmp, width, height, true);
-        }
-    }
-}
-
diff --git a/packages/MediaComponents/src/com/android/media/MediaPlaylistAgentImpl.java b/packages/MediaComponents/src/com/android/media/MediaPlaylistAgentImpl.java
deleted file mode 100644
index dfd4e1a..0000000
--- a/packages/MediaComponents/src/com/android/media/MediaPlaylistAgentImpl.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.media;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.media.DataSourceDesc;
-import android.media.MediaItem2;
-import android.media.MediaMetadata2;
-import android.media.MediaPlaylistAgent;
-import android.media.MediaPlaylistAgent.PlaylistEventCallback;
-import android.media.update.MediaPlaylistAgentProvider;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.util.List;
-import java.util.concurrent.Executor;
-
-public class MediaPlaylistAgentImpl implements MediaPlaylistAgentProvider {
-    private static final String TAG = "MediaPlaylistAgent";
-
-    private final MediaPlaylistAgent mInstance;
-
-    private final Object mLock = new Object();
-    @GuardedBy("mLock")
-    private final ArrayMap<PlaylistEventCallback, Executor> mCallbacks = new ArrayMap<>();
-
-    public MediaPlaylistAgentImpl(MediaPlaylistAgent instance) {
-        mInstance = instance;
-    }
-
-    @Override
-    final public void registerPlaylistEventCallback_impl(
-            @NonNull @CallbackExecutor Executor executor, @NonNull PlaylistEventCallback callback) {
-        if (executor == null) {
-            throw new IllegalArgumentException("executor shouldn't be null");
-        }
-        if (callback == null) {
-            throw new IllegalArgumentException("callback shouldn't be null");
-        }
-
-        synchronized (mLock) {
-            if (mCallbacks.get(callback) != null) {
-                Log.w(TAG, "callback is already added. Ignoring.");
-                return;
-            }
-            mCallbacks.put(callback, executor);
-        }
-    }
-
-    @Override
-    final public void unregisterPlaylistEventCallback_impl(
-            @NonNull PlaylistEventCallback callback) {
-        if (callback == null) {
-            throw new IllegalArgumentException("callback shouldn't be null");
-        }
-        synchronized (mLock) {
-            mCallbacks.remove(callback);
-        }
-    }
-
-    @Override
-    final public void notifyPlaylistChanged_impl() {
-        ArrayMap<PlaylistEventCallback, Executor> callbacks = getCallbacks();
-        List<MediaItem2> playlist= mInstance.getPlaylist();
-        MediaMetadata2 metadata = mInstance.getPlaylistMetadata();
-        for (int i = 0; i < callbacks.size(); i++) {
-            final PlaylistEventCallback callback = callbacks.keyAt(i);
-            final Executor executor = callbacks.valueAt(i);
-            executor.execute(() -> callback.onPlaylistChanged(
-                    mInstance, playlist, metadata));
-        }
-    }
-
-    @Override
-    final public void notifyPlaylistMetadataChanged_impl() {
-        ArrayMap<PlaylistEventCallback, Executor> callbacks = getCallbacks();
-        for (int i = 0; i < callbacks.size(); i++) {
-            final PlaylistEventCallback callback = callbacks.keyAt(i);
-            final Executor executor = callbacks.valueAt(i);
-            executor.execute(() -> callback.onPlaylistMetadataChanged(
-                    mInstance, mInstance.getPlaylistMetadata()));
-        }
-    }
-
-    @Override
-    final public void notifyShuffleModeChanged_impl() {
-        ArrayMap<PlaylistEventCallback, Executor> callbacks = getCallbacks();
-        for (int i = 0; i < callbacks.size(); i++) {
-            final PlaylistEventCallback callback = callbacks.keyAt(i);
-            final Executor executor = callbacks.valueAt(i);
-            executor.execute(() -> callback.onShuffleModeChanged(
-                    mInstance, mInstance.getShuffleMode()));
-        }
-    }
-
-    @Override
-    final public void notifyRepeatModeChanged_impl() {
-        ArrayMap<PlaylistEventCallback, Executor> callbacks = getCallbacks();
-        for (int i = 0; i < callbacks.size(); i++) {
-            final PlaylistEventCallback callback = callbacks.keyAt(i);
-            final Executor executor = callbacks.valueAt(i);
-            executor.execute(() -> callback.onRepeatModeChanged(
-                    mInstance, mInstance.getRepeatMode()));
-        }
-    }
-
-    @Override
-    public @Nullable List<MediaItem2> getPlaylist_impl() {
-        // empty implementation
-        return null;
-    }
-
-    @Override
-    public void setPlaylist_impl(@NonNull List<MediaItem2> list,
-            @Nullable MediaMetadata2 metadata) {
-        // empty implementation
-    }
-
-    @Override
-    public @Nullable MediaMetadata2 getPlaylistMetadata_impl() {
-        // empty implementation
-        return null;
-    }
-
-    @Override
-    public void updatePlaylistMetadata_impl(@Nullable MediaMetadata2 metadata) {
-        // empty implementation
-    }
-
-    @Override
-    public void addPlaylistItem_impl(int index, @NonNull MediaItem2 item) {
-        // empty implementation
-    }
-
-    @Override
-    public void removePlaylistItem_impl(@NonNull MediaItem2 item) {
-        // empty implementation
-    }
-
-    @Override
-    public void replacePlaylistItem_impl(int index, @NonNull MediaItem2 item) {
-        // empty implementation
-    }
-
-    @Override
-    public void skipToPlaylistItem_impl(@NonNull MediaItem2 item) {
-        // empty implementation
-    }
-
-    @Override
-    public void skipToPreviousItem_impl() {
-        // empty implementation
-    }
-
-    @Override
-    public void skipToNextItem_impl() {
-        // empty implementation
-    }
-
-    @Override
-    public int getRepeatMode_impl() {
-        return MediaPlaylistAgent.REPEAT_MODE_NONE;
-    }
-
-    @Override
-    public void setRepeatMode_impl(int repeatMode) {
-        // empty implementation
-    }
-
-    @Override
-    public int getShuffleMode_impl() {
-        // empty implementation
-        return MediaPlaylistAgent.SHUFFLE_MODE_NONE;
-    }
-
-    @Override
-    public void setShuffleMode_impl(int shuffleMode) {
-        // empty implementation
-    }
-
-    @Override
-    public @Nullable MediaItem2 getMediaItem_impl(@NonNull DataSourceDesc dsd) {
-        if (dsd == null) {
-            throw new IllegalArgumentException("dsd shouldn't be null");
-        }
-        List<MediaItem2> itemList = mInstance.getPlaylist();
-        if (itemList == null) {
-            return null;
-        }
-        for (int i = 0; i < itemList.size(); i++) {
-            MediaItem2 item = itemList.get(i);
-            if (item != null && item.getDataSourceDesc() == dsd) {
-                return item;
-            }
-        }
-        return null;
-    }
-
-    private ArrayMap<PlaylistEventCallback, Executor> getCallbacks() {
-        ArrayMap<PlaylistEventCallback, Executor> callbacks = new ArrayMap<>();
-        synchronized (mLock) {
-            callbacks.putAll(mCallbacks);
-        }
-        return callbacks;
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java b/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
deleted file mode 100644
index 4ec6042..0000000
--- a/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
+++ /dev/null
@@ -1,1555 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.media;
-
-import static android.media.SessionCommand2.COMMAND_CODE_CUSTOM;
-import static android.media.SessionToken2.TYPE_LIBRARY_SERVICE;
-import static android.media.SessionToken2.TYPE_SESSION;
-import static android.media.SessionToken2.TYPE_SESSION_SERVICE;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.media.AudioAttributes;
-import android.media.AudioFocusRequest;
-import android.media.AudioManager;
-import android.media.DataSourceDesc;
-import android.media.MediaController2;
-import android.media.MediaController2.PlaybackInfo;
-import android.media.MediaItem2;
-import android.media.MediaLibraryService2;
-import android.media.MediaMetadata2;
-import android.media.MediaPlayerBase;
-import android.media.MediaPlayerBase.PlayerEventCallback;
-import android.media.MediaPlayerBase.PlayerState;
-import android.media.MediaPlaylistAgent;
-import android.media.MediaPlaylistAgent.PlaylistEventCallback;
-import android.media.MediaSession2;
-import android.media.MediaSession2.Builder;
-import android.media.SessionCommand2;
-import android.media.MediaSession2.CommandButton;
-import android.media.SessionCommandGroup2;
-import android.media.MediaSession2.ControllerInfo;
-import android.media.MediaSession2.OnDataSourceMissingHelper;
-import android.media.MediaSession2.SessionCallback;
-import android.media.MediaSessionService2;
-import android.media.SessionToken2;
-import android.media.VolumeProvider2;
-import android.media.session.MediaSessionManager;
-import android.media.update.MediaSession2Provider;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Parcelable;
-import android.os.Process;
-import android.os.ResultReceiver;
-import android.support.annotation.GuardedBy;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import java.util.concurrent.Executor;
-
-public class MediaSession2Impl implements MediaSession2Provider {
-    private static final String TAG = "MediaSession2";
-    private static final boolean DEBUG = true;//Log.isLoggable(TAG, Log.DEBUG);
-
-    private final Object mLock = new Object();
-
-    private final MediaSession2 mInstance;
-    private final Context mContext;
-    private final String mId;
-    private final Executor mCallbackExecutor;
-    private final SessionCallback mCallback;
-    private final MediaSession2Stub mSessionStub;
-    private final SessionToken2 mSessionToken;
-    private final AudioManager mAudioManager;
-    private final PendingIntent mSessionActivity;
-    private final PlayerEventCallback mPlayerEventCallback;
-    private final PlaylistEventCallback mPlaylistEventCallback;
-
-    // mPlayer is set to null when the session is closed, and we shouldn't throw an exception
-    // nor leave log always for using mPlayer when it's null. Here's the reason.
-    // When a MediaSession2 is closed, there could be a pended operation in the session callback
-    // executor that may want to access the player. Here's the sample code snippet for that.
-    //
-    //   public void onFoo() {
-    //     if (mPlayer == null) return; // first check
-    //     mSessionCallbackExecutor.executor(() -> {
-    //       // Error. Session may be closed and mPlayer can be null here.
-    //       mPlayer.foo();
-    //     });
-    //   }
-    //
-    // By adding protective code, we can also protect APIs from being called after the close()
-    //
-    // TODO(jaewan): Should we put volatile here?
-    @GuardedBy("mLock")
-    private MediaPlayerBase mPlayer;
-    @GuardedBy("mLock")
-    private MediaPlaylistAgent mPlaylistAgent;
-    @GuardedBy("mLock")
-    private SessionPlaylistAgent mSessionPlaylistAgent;
-    @GuardedBy("mLock")
-    private VolumeProvider2 mVolumeProvider;
-    @GuardedBy("mLock")
-    private PlaybackInfo mPlaybackInfo;
-    @GuardedBy("mLock")
-    private OnDataSourceMissingHelper mDsmHelper;
-
-    /**
-     * Can be only called by the {@link Builder#build()}.
-     * @param context
-     * @param player
-     * @param id
-     * @param playlistAgent
-     * @param volumeProvider
-     * @param sessionActivity
-     * @param callbackExecutor
-     * @param callback
-     */
-    public MediaSession2Impl(Context context, MediaPlayerBase player, String id,
-            MediaPlaylistAgent playlistAgent, VolumeProvider2 volumeProvider,
-            PendingIntent sessionActivity,
-            Executor callbackExecutor, SessionCallback callback) {
-        // TODO(jaewan): Keep other params.
-        mInstance = createInstance();
-
-        // Argument checks are done by builder already.
-        // Initialize finals first.
-        mContext = context;
-        mId = id;
-        mCallback = callback;
-        mCallbackExecutor = callbackExecutor;
-        mSessionActivity = sessionActivity;
-        mSessionStub = new MediaSession2Stub(this);
-        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
-        mPlayerEventCallback = new MyPlayerEventCallback(this);
-        mPlaylistEventCallback = new MyPlaylistEventCallback(this);
-
-        // Infer type from the id and package name.
-        String libraryService = getServiceName(context, MediaLibraryService2.SERVICE_INTERFACE, id);
-        String sessionService = getServiceName(context, MediaSessionService2.SERVICE_INTERFACE, id);
-        if (sessionService != null && libraryService != null) {
-            throw new IllegalArgumentException("Ambiguous session type. Multiple"
-                    + " session services define the same id=" + id);
-        } else if (libraryService != null) {
-            mSessionToken = new SessionToken2Impl(Process.myUid(), TYPE_LIBRARY_SERVICE,
-                    mContext.getPackageName(), libraryService, id, mSessionStub).getInstance();
-        } else if (sessionService != null) {
-            mSessionToken = new SessionToken2Impl(Process.myUid(), TYPE_SESSION_SERVICE,
-                    mContext.getPackageName(), sessionService, id, mSessionStub).getInstance();
-        } else {
-            mSessionToken = new SessionToken2Impl(Process.myUid(), TYPE_SESSION,
-                    mContext.getPackageName(), null, id, mSessionStub).getInstance();
-        }
-
-        updatePlayer(player, playlistAgent, volumeProvider);
-
-        // Ask server for the sanity check, and starts
-        // Sanity check for making session ID unique 'per package' cannot be done in here.
-        // Server can only know if the package has another process and has another session with the
-        // same id. Note that 'ID is unique per package' is important for controller to distinguish
-        // a session in another package.
-        MediaSessionManager manager =
-                (MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE);
-        if (!manager.createSession2(mSessionToken)) {
-            throw new IllegalStateException("Session with the same id is already used by"
-                    + " another process. Use MediaController2 instead.");
-        }
-    }
-
-    MediaSession2 createInstance() {
-        return new MediaSession2(this);
-    }
-
-    private static String getServiceName(Context context, String serviceAction, String id) {
-        PackageManager manager = context.getPackageManager();
-        Intent serviceIntent = new Intent(serviceAction);
-        serviceIntent.setPackage(context.getPackageName());
-        List<ResolveInfo> services = manager.queryIntentServices(serviceIntent,
-                PackageManager.GET_META_DATA);
-        String serviceName = null;
-        if (services != null) {
-            for (int i = 0; i < services.size(); i++) {
-                String serviceId = SessionToken2Impl.getSessionId(services.get(i));
-                if (serviceId != null && TextUtils.equals(id, serviceId)) {
-                    if (services.get(i).serviceInfo == null) {
-                        continue;
-                    }
-                    if (serviceName != null) {
-                        throw new IllegalArgumentException("Ambiguous session type. Multiple"
-                                + " session services define the same id=" + id);
-                    }
-                    serviceName = services.get(i).serviceInfo.name;
-                }
-            }
-        }
-        return serviceName;
-    }
-
-    @Override
-    public void updatePlayer_impl(@NonNull MediaPlayerBase player, MediaPlaylistAgent playlistAgent,
-            VolumeProvider2 volumeProvider) throws IllegalArgumentException {
-        ensureCallingThread();
-        if (player == null) {
-            throw new IllegalArgumentException("player shouldn't be null");
-        }
-        updatePlayer(player, playlistAgent, volumeProvider);
-    }
-
-    private void updatePlayer(MediaPlayerBase player, MediaPlaylistAgent agent,
-            VolumeProvider2 volumeProvider) {
-        final MediaPlayerBase oldPlayer;
-        final MediaPlaylistAgent oldAgent;
-        final PlaybackInfo info = createPlaybackInfo(volumeProvider, player.getAudioAttributes());
-        synchronized (mLock) {
-            oldPlayer = mPlayer;
-            oldAgent = mPlaylistAgent;
-            mPlayer = player;
-            if (agent == null) {
-                mSessionPlaylistAgent = new SessionPlaylistAgent(this, mPlayer);
-                if (mDsmHelper != null) {
-                    mSessionPlaylistAgent.setOnDataSourceMissingHelper(mDsmHelper);
-                }
-                agent = mSessionPlaylistAgent;
-            }
-            mPlaylistAgent = agent;
-            mVolumeProvider = volumeProvider;
-            mPlaybackInfo = info;
-        }
-        if (player != oldPlayer) {
-            player.registerPlayerEventCallback(mCallbackExecutor, mPlayerEventCallback);
-            if (oldPlayer != null) {
-                // Warning: Poorly implement player may ignore this
-                oldPlayer.unregisterPlayerEventCallback(mPlayerEventCallback);
-            }
-        }
-        if (agent != oldAgent) {
-            agent.registerPlaylistEventCallback(mCallbackExecutor, mPlaylistEventCallback);
-            if (oldAgent != null) {
-                // Warning: Poorly implement player may ignore this
-                oldAgent.unregisterPlaylistEventCallback(mPlaylistEventCallback);
-            }
-        }
-
-        if (oldPlayer != null) {
-            mSessionStub.notifyPlaybackInfoChanged(info);
-            notifyPlayerUpdatedNotLocked(oldPlayer);
-        }
-        // TODO(jaewan): Repeat the same thing for the playlist agent.
-    }
-
-    private PlaybackInfo createPlaybackInfo(VolumeProvider2 volumeProvider, AudioAttributes attrs) {
-        PlaybackInfo info;
-        if (volumeProvider == null) {
-            int stream;
-            if (attrs == null) {
-                stream = AudioManager.STREAM_MUSIC;
-            } else {
-                stream = attrs.getVolumeControlStream();
-                if (stream == AudioManager.USE_DEFAULT_STREAM_TYPE) {
-                    // It may happen if the AudioAttributes doesn't have usage.
-                    // Change it to the STREAM_MUSIC because it's not supported by audio manager
-                    // for querying volume level.
-                    stream = AudioManager.STREAM_MUSIC;
-                }
-            }
-            info = MediaController2Impl.PlaybackInfoImpl.createPlaybackInfo(
-                    PlaybackInfo.PLAYBACK_TYPE_LOCAL,
-                    attrs,
-                    mAudioManager.isVolumeFixed()
-                            ? VolumeProvider2.VOLUME_CONTROL_FIXED
-                            : VolumeProvider2.VOLUME_CONTROL_ABSOLUTE,
-                    mAudioManager.getStreamMaxVolume(stream),
-                    mAudioManager.getStreamVolume(stream));
-        } else {
-            info = MediaController2Impl.PlaybackInfoImpl.createPlaybackInfo(
-                    PlaybackInfo.PLAYBACK_TYPE_REMOTE /* ControlType */,
-                    attrs,
-                    volumeProvider.getControlType(),
-                    volumeProvider.getMaxVolume(),
-                    volumeProvider.getCurrentVolume());
-        }
-        return info;
-    }
-
-    @Override
-    public void close_impl() {
-        // Stop system service from listening this session first.
-        MediaSessionManager manager =
-                (MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE);
-        manager.destroySession2(mSessionToken);
-
-        if (mSessionStub != null) {
-            if (DEBUG) {
-                Log.d(TAG, "session is now unavailable, id=" + mId);
-            }
-            // Invalidate previously published session stub.
-            mSessionStub.destroyNotLocked();
-        }
-        final MediaPlayerBase player;
-        final MediaPlaylistAgent agent;
-        synchronized (mLock) {
-            player = mPlayer;
-            mPlayer = null;
-            agent = mPlaylistAgent;
-            mPlaylistAgent = null;
-            mSessionPlaylistAgent = null;
-        }
-        if (player != null) {
-            player.unregisterPlayerEventCallback(mPlayerEventCallback);
-        }
-        if (agent != null) {
-            agent.unregisterPlaylistEventCallback(mPlaylistEventCallback);
-        }
-    }
-
-    @Override
-    public MediaPlayerBase getPlayer_impl() {
-        return getPlayer();
-    }
-
-    @Override
-    public MediaPlaylistAgent getPlaylistAgent_impl() {
-        return mPlaylistAgent;
-    }
-
-    @Override
-    public VolumeProvider2 getVolumeProvider_impl() {
-        return mVolumeProvider;
-    }
-
-    @Override
-    public SessionToken2 getToken_impl() {
-        return mSessionToken;
-    }
-
-    @Override
-    public List<ControllerInfo> getConnectedControllers_impl() {
-        return mSessionStub.getControllers();
-    }
-
-    @Override
-    public void setAudioFocusRequest_impl(AudioFocusRequest afr) {
-        // implement
-    }
-
-    @Override
-    public void play_impl() {
-        ensureCallingThread();
-        final MediaPlayerBase player = mPlayer;
-        if (player != null) {
-            player.play();
-        } else if (DEBUG) {
-            Log.d(TAG, "API calls after the close()", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void pause_impl() {
-        ensureCallingThread();
-        final MediaPlayerBase player = mPlayer;
-        if (player != null) {
-            player.pause();
-        } else if (DEBUG) {
-            Log.d(TAG, "API calls after the close()", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void stop_impl() {
-        ensureCallingThread();
-        final MediaPlayerBase player = mPlayer;
-        if (player != null) {
-            player.reset();
-        } else if (DEBUG) {
-            Log.d(TAG, "API calls after the close()", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void skipToPlaylistItem_impl(@NonNull MediaItem2 item) {
-        if (item == null) {
-            throw new IllegalArgumentException("item shouldn't be null");
-        }
-        final MediaPlaylistAgent agent = mPlaylistAgent;
-        if (agent != null) {
-            agent.skipToPlaylistItem(item);
-        } else if (DEBUG) {
-            Log.d(TAG, "API calls after the close()", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void skipToPreviousItem_impl() {
-        final MediaPlaylistAgent agent = mPlaylistAgent;
-        if (agent != null) {
-            agent.skipToPreviousItem();
-        } else if (DEBUG) {
-            Log.d(TAG, "API calls after the close()", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void skipToNextItem_impl() {
-        final MediaPlaylistAgent agent = mPlaylistAgent;
-        if (agent != null) {
-            agent.skipToNextItem();
-        } else if (DEBUG) {
-            Log.d(TAG, "API calls after the close()", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void setCustomLayout_impl(@NonNull ControllerInfo controller,
-            @NonNull List<CommandButton> layout) {
-        ensureCallingThread();
-        if (controller == null) {
-            throw new IllegalArgumentException("controller shouldn't be null");
-        }
-        if (layout == null) {
-            throw new IllegalArgumentException("layout shouldn't be null");
-        }
-        mSessionStub.notifyCustomLayoutNotLocked(controller, layout);
-    }
-
-    //////////////////////////////////////////////////////////////////////////////////////
-    // TODO(jaewan): Implement follows
-    //////////////////////////////////////////////////////////////////////////////////////
-
-    @Override
-    public void setAllowedCommands_impl(@NonNull ControllerInfo controller,
-            @NonNull SessionCommandGroup2 commands) {
-        if (controller == null) {
-            throw new IllegalArgumentException("controller shouldn't be null");
-        }
-        if (commands == null) {
-            throw new IllegalArgumentException("commands shouldn't be null");
-        }
-        mSessionStub.setAllowedCommands(controller, commands);
-    }
-
-    @Override
-    public void sendCustomCommand_impl(@NonNull ControllerInfo controller,
-            @NonNull SessionCommand2 command, Bundle args, ResultReceiver receiver) {
-        if (controller == null) {
-            throw new IllegalArgumentException("controller shouldn't be null");
-        }
-        if (command == null) {
-            throw new IllegalArgumentException("command shouldn't be null");
-        }
-        mSessionStub.sendCustomCommand(controller, command, args, receiver);
-    }
-
-    @Override
-    public void sendCustomCommand_impl(@NonNull SessionCommand2 command, Bundle args) {
-        if (command == null) {
-            throw new IllegalArgumentException("command shouldn't be null");
-        }
-        mSessionStub.sendCustomCommand(command, args);
-    }
-
-    @Override
-    public void setPlaylist_impl(@NonNull List<MediaItem2> list, MediaMetadata2 metadata) {
-        if (list == null) {
-            throw new IllegalArgumentException("list shouldn't be null");
-        }
-        ensureCallingThread();
-        final MediaPlaylistAgent agent = mPlaylistAgent;
-        if (agent != null) {
-            agent.setPlaylist(list, metadata);
-        } else if (DEBUG) {
-            Log.d(TAG, "API calls after the close()", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void updatePlaylistMetadata_impl(MediaMetadata2 metadata) {
-        final MediaPlaylistAgent agent = mPlaylistAgent;
-        if (agent != null) {
-            agent.updatePlaylistMetadata(metadata);
-        } else if (DEBUG) {
-            Log.d(TAG, "API calls after the close()", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void addPlaylistItem_impl(int index, @NonNull MediaItem2 item) {
-        if (index < 0) {
-            throw new IllegalArgumentException("index shouldn't be negative");
-        }
-        if (item == null) {
-            throw new IllegalArgumentException("item shouldn't be null");
-        }
-        final MediaPlaylistAgent agent = mPlaylistAgent;
-        if (agent != null) {
-            agent.addPlaylistItem(index, item);
-        } else if (DEBUG) {
-            Log.d(TAG, "API calls after the close()", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void removePlaylistItem_impl(@NonNull MediaItem2 item) {
-        if (item == null) {
-            throw new IllegalArgumentException("item shouldn't be null");
-        }
-        final MediaPlaylistAgent agent = mPlaylistAgent;
-        if (agent != null) {
-            agent.removePlaylistItem(item);
-        } else if (DEBUG) {
-            Log.d(TAG, "API calls after the close()", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void replacePlaylistItem_impl(int index, @NonNull MediaItem2 item) {
-        if (index < 0) {
-            throw new IllegalArgumentException("index shouldn't be negative");
-        }
-        if (item == null) {
-            throw new IllegalArgumentException("item shouldn't be null");
-        }
-        final MediaPlaylistAgent agent = mPlaylistAgent;
-        if (agent != null) {
-            agent.replacePlaylistItem(index, item);
-        } else if (DEBUG) {
-            Log.d(TAG, "API calls after the close()", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public List<MediaItem2> getPlaylist_impl() {
-        final MediaPlaylistAgent agent = mPlaylistAgent;
-        if (agent != null) {
-            return agent.getPlaylist();
-        } else if (DEBUG) {
-            Log.d(TAG, "API calls after the close()", new IllegalStateException());
-        }
-        return null;
-    }
-
-    @Override
-    public MediaMetadata2 getPlaylistMetadata_impl() {
-        final MediaPlaylistAgent agent = mPlaylistAgent;
-        if (agent != null) {
-            return agent.getPlaylistMetadata();
-        } else if (DEBUG) {
-            Log.d(TAG, "API calls after the close()", new IllegalStateException());
-        }
-        return null;
-    }
-
-    @Override
-    public MediaItem2 getCurrentPlaylistItem_impl() {
-        // TODO(jaewan): Implement
-        return null;
-    }
-
-    @Override
-    public int getRepeatMode_impl() {
-        final MediaPlaylistAgent agent = mPlaylistAgent;
-        if (agent != null) {
-            return agent.getRepeatMode();
-        } else if (DEBUG) {
-            Log.d(TAG, "API calls after the close()", new IllegalStateException());
-        }
-        return MediaPlaylistAgent.REPEAT_MODE_NONE;
-    }
-
-    @Override
-    public void setRepeatMode_impl(int repeatMode) {
-        final MediaPlaylistAgent agent = mPlaylistAgent;
-        if (agent != null) {
-            agent.setRepeatMode(repeatMode);
-        } else if (DEBUG) {
-            Log.d(TAG, "API calls after the close()", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public int getShuffleMode_impl() {
-        final MediaPlaylistAgent agent = mPlaylistAgent;
-        if (agent != null) {
-            return agent.getShuffleMode();
-        } else if (DEBUG) {
-            Log.d(TAG, "API calls after the close()", new IllegalStateException());
-        }
-        return MediaPlaylistAgent.SHUFFLE_MODE_NONE;
-    }
-
-    @Override
-    public void setShuffleMode_impl(int shuffleMode) {
-        final MediaPlaylistAgent agent = mPlaylistAgent;
-        if (agent != null) {
-            agent.setShuffleMode(shuffleMode);
-        } else if (DEBUG) {
-            Log.d(TAG, "API calls after the close()", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void prepare_impl() {
-        ensureCallingThread();
-        final MediaPlayerBase player = mPlayer;
-        if (player != null) {
-            player.prepare();
-        } else if (DEBUG) {
-            Log.d(TAG, "API calls after the close()", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void seekTo_impl(long pos) {
-        ensureCallingThread();
-        final MediaPlayerBase player = mPlayer;
-        if (player != null) {
-            player.seekTo(pos);
-        } else if (DEBUG) {
-            Log.d(TAG, "API calls after the close()", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public @PlayerState int getPlayerState_impl() {
-        final MediaPlayerBase player = mPlayer;
-        if (player != null) {
-            return mPlayer.getPlayerState();
-        } else if (DEBUG) {
-            Log.d(TAG, "API calls after the close()", new IllegalStateException());
-        }
-        return MediaPlayerBase.PLAYER_STATE_ERROR;
-    }
-
-    @Override
-    public long getCurrentPosition_impl() {
-        final MediaPlayerBase player = mPlayer;
-        if (player != null) {
-            return mPlayer.getCurrentPosition();
-        } else if (DEBUG) {
-            Log.d(TAG, "API calls after the close()", new IllegalStateException());
-        }
-        return MediaPlayerBase.UNKNOWN_TIME;
-    }
-
-    @Override
-    public long getBufferedPosition_impl() {
-        final MediaPlayerBase player = mPlayer;
-        if (player != null) {
-            return mPlayer.getBufferedPosition();
-        } else if (DEBUG) {
-            Log.d(TAG, "API calls after the close()", new IllegalStateException());
-        }
-        return MediaPlayerBase.UNKNOWN_TIME;
-    }
-
-    @Override
-    public void notifyError_impl(int errorCode, Bundle extras) {
-        mSessionStub.notifyError(errorCode, extras);
-    }
-
-    @Override
-    public void setOnDataSourceMissingHelper_impl(@NonNull OnDataSourceMissingHelper helper) {
-        if (helper == null) {
-            throw new IllegalArgumentException("helper shouldn't be null");
-        }
-        synchronized (mLock) {
-            mDsmHelper = helper;
-            if (mSessionPlaylistAgent != null) {
-                mSessionPlaylistAgent.setOnDataSourceMissingHelper(helper);
-            }
-        }
-    }
-
-    @Override
-    public void clearOnDataSourceMissingHelper_impl() {
-        synchronized (mLock) {
-            mDsmHelper = null;
-            if (mSessionPlaylistAgent != null) {
-                mSessionPlaylistAgent.clearOnDataSourceMissingHelper();
-            }
-        }
-    }
-
-    ///////////////////////////////////////////////////
-    // Protected or private methods
-    ///////////////////////////////////////////////////
-
-    // Enforces developers to call all the methods on the initially given thread
-    // because calls from the MediaController2 will be run on the thread.
-    // TODO(jaewan): Should we allow calls from the multiple thread?
-    //               I prefer this way because allowing multiple thread may case tricky issue like
-    //               b/63446360. If the {@link #setPlayer()} with {@code null} can be called from
-    //               another thread, transport controls can be called after that.
-    //               That's basically the developer's mistake, but they cannot understand what's
-    //               happening behind until we tell them so.
-    //               If enforcing callling thread doesn't look good, we can alternatively pick
-    //               1. Allow calls from random threads for all methods.
-    //               2. Allow calls from random threads for all methods, except for the
-    //                  {@link #setPlayer()}.
-    void ensureCallingThread() {
-        // TODO(jaewan): Uncomment or remove
-        /*
-        if (mHandler.getLooper() != Looper.myLooper()) {
-            throw new IllegalStateException("Run this on the given thread");
-        }*/
-    }
-
-    private void notifyPlaylistChangedOnExecutor(MediaPlaylistAgent playlistAgent,
-            List<MediaItem2> list, MediaMetadata2 metadata) {
-        if (playlistAgent != mPlaylistAgent) {
-            // Ignore calls from the old agent.
-            return;
-        }
-        mCallback.onPlaylistChanged(mInstance, playlistAgent, list, metadata);
-        mSessionStub.notifyPlaylistChangedNotLocked(list, metadata);
-    }
-
-    private void notifyPlaylistMetadataChangedOnExecutor(MediaPlaylistAgent playlistAgent,
-            MediaMetadata2 metadata) {
-        if (playlistAgent != mPlaylistAgent) {
-            // Ignore calls from the old agent.
-            return;
-        }
-        mCallback.onPlaylistMetadataChanged(mInstance, playlistAgent, metadata);
-        mSessionStub.notifyPlaylistMetadataChangedNotLocked(metadata);
-    }
-
-    private void notifyRepeatModeChangedOnExecutor(MediaPlaylistAgent playlistAgent,
-            int repeatMode) {
-        if (playlistAgent != mPlaylistAgent) {
-            // Ignore calls from the old agent.
-            return;
-        }
-        mCallback.onRepeatModeChanged(mInstance, playlistAgent, repeatMode);
-        mSessionStub.notifyRepeatModeChangedNotLocked(repeatMode);
-    }
-
-    private void notifyShuffleModeChangedOnExecutor(MediaPlaylistAgent playlistAgent,
-            int shuffleMode) {
-        if (playlistAgent != mPlaylistAgent) {
-            // Ignore calls from the old agent.
-            return;
-        }
-        mCallback.onShuffleModeChanged(mInstance, playlistAgent, shuffleMode);
-        mSessionStub.notifyShuffleModeChangedNotLocked(shuffleMode);
-    }
-
-    private void notifyPlayerUpdatedNotLocked(MediaPlayerBase oldPlayer) {
-        final MediaPlayerBase player = mPlayer;
-        // TODO(jaewan): (Can be post-P) Find better way for player.getPlayerState() //
-        //               In theory, Session.getXXX() may not be the same as Player.getXXX()
-        //               and we should notify information of the session.getXXX() instead of
-        //               player.getXXX()
-        // Notify to controllers as well.
-        final int state = player.getPlayerState();
-        if (state != oldPlayer.getPlayerState()) {
-            mSessionStub.notifyPlayerStateChangedNotLocked(state);
-        }
-
-        final long currentTimeMs = System.currentTimeMillis();
-        final long position = player.getCurrentPosition();
-        if (position != oldPlayer.getCurrentPosition()) {
-            mSessionStub.notifyPositionChangedNotLocked(currentTimeMs, position);
-        }
-
-        final float speed = player.getPlaybackSpeed();
-        if (speed != oldPlayer.getPlaybackSpeed()) {
-            mSessionStub.notifyPlaybackSpeedChangedNotLocked(speed);
-        }
-
-        final long bufferedPosition = player.getBufferedPosition();
-        if (bufferedPosition != oldPlayer.getBufferedPosition()) {
-            mSessionStub.notifyBufferedPositionChangedNotLocked(bufferedPosition);
-        }
-    }
-
-    Context getContext() {
-        return mContext;
-    }
-
-    MediaSession2 getInstance() {
-        return mInstance;
-    }
-
-    MediaPlayerBase getPlayer() {
-        return mPlayer;
-    }
-
-    MediaPlaylistAgent getPlaylistAgent() {
-        return mPlaylistAgent;
-    }
-
-    Executor getCallbackExecutor() {
-        return mCallbackExecutor;
-    }
-
-    SessionCallback getCallback() {
-        return mCallback;
-    }
-
-    MediaSession2Stub getSessionStub() {
-        return mSessionStub;
-    }
-
-    VolumeProvider2 getVolumeProvider() {
-        return mVolumeProvider;
-    }
-
-    PlaybackInfo getPlaybackInfo() {
-        synchronized (mLock) {
-            return mPlaybackInfo;
-        }
-    }
-
-    PendingIntent getSessionActivity() {
-        return mSessionActivity;
-    }
-
-    private static class MyPlayerEventCallback extends PlayerEventCallback {
-        private final WeakReference<MediaSession2Impl> mSession;
-
-        private MyPlayerEventCallback(MediaSession2Impl session) {
-            mSession = new WeakReference<>(session);
-        }
-
-        @Override
-        public void onCurrentDataSourceChanged(MediaPlayerBase mpb, DataSourceDesc dsd) {
-            MediaSession2Impl session = getSession();
-            if (session == null || dsd == null) {
-                return;
-            }
-            session.getCallbackExecutor().execute(() -> {
-                MediaItem2 item = getMediaItem(session, dsd);
-                if (item == null) {
-                    return;
-                }
-                session.getCallback().onCurrentMediaItemChanged(session.getInstance(), mpb, item);
-                // TODO (jaewan): Notify controllers through appropriate callback. (b/74505936)
-            });
-        }
-
-        @Override
-        public void onMediaPrepared(MediaPlayerBase mpb, DataSourceDesc dsd) {
-            MediaSession2Impl session = getSession();
-            if (session == null || dsd == null) {
-                return;
-            }
-            session.getCallbackExecutor().execute(() -> {
-                MediaItem2 item = getMediaItem(session, dsd);
-                if (item == null) {
-                    return;
-                }
-                session.getCallback().onMediaPrepared(session.getInstance(), mpb, item);
-                // TODO (jaewan): Notify controllers through appropriate callback. (b/74505936)
-            });
-        }
-
-        @Override
-        public void onPlayerStateChanged(MediaPlayerBase mpb, int state) {
-            MediaSession2Impl session = getSession();
-            if (session == null) {
-                return;
-            }
-            session.getCallbackExecutor().execute(() -> {
-                session.getCallback().onPlayerStateChanged(session.getInstance(), mpb, state);
-                session.getSessionStub().notifyPlayerStateChangedNotLocked(state);
-            });
-        }
-
-        @Override
-        public void onBufferingStateChanged(MediaPlayerBase mpb, DataSourceDesc dsd, int state) {
-            MediaSession2Impl session = getSession();
-            if (session == null || dsd == null) {
-                return;
-            }
-            session.getCallbackExecutor().execute(() -> {
-                MediaItem2 item = getMediaItem(session, dsd);
-                if (item == null) {
-                    return;
-                }
-                session.getCallback().onBufferingStateChanged(
-                        session.getInstance(), mpb, item, state);
-                // TODO (jaewan): Notify controllers through appropriate callback. (b/74505936)
-            });
-        }
-
-        private MediaSession2Impl getSession() {
-            final MediaSession2Impl session = mSession.get();
-            if (session == null && DEBUG) {
-                Log.d(TAG, "Session is closed", new IllegalStateException());
-            }
-            return session;
-        }
-
-        private MediaItem2 getMediaItem(MediaSession2Impl session, DataSourceDesc dsd) {
-            MediaPlaylistAgent agent = session.getPlaylistAgent();
-            if (agent == null) {
-                if (DEBUG) {
-                    Log.d(TAG, "Session is closed", new IllegalStateException());
-                }
-                return null;
-            }
-            MediaItem2 item = agent.getMediaItem(dsd);
-            if (item == null) {
-                if (DEBUG) {
-                    Log.d(TAG, "Could not find matching item for dsd=" + dsd,
-                            new NoSuchElementException());
-                }
-            }
-            return item;
-        }
-    }
-
-    private static class MyPlaylistEventCallback extends PlaylistEventCallback {
-        private final WeakReference<MediaSession2Impl> mSession;
-
-        private MyPlaylistEventCallback(MediaSession2Impl session) {
-            mSession = new WeakReference<>(session);
-        }
-
-        @Override
-        public void onPlaylistChanged(MediaPlaylistAgent playlistAgent, List<MediaItem2> list,
-                MediaMetadata2 metadata) {
-            final MediaSession2Impl session = mSession.get();
-            if (session == null) {
-                return;
-            }
-            session.notifyPlaylistChangedOnExecutor(playlistAgent, list, metadata);
-        }
-
-        @Override
-        public void onPlaylistMetadataChanged(MediaPlaylistAgent playlistAgent,
-                MediaMetadata2 metadata) {
-            final MediaSession2Impl session = mSession.get();
-            if (session == null) {
-                return;
-            }
-            session.notifyPlaylistMetadataChangedOnExecutor(playlistAgent, metadata);
-        }
-
-        @Override
-        public void onRepeatModeChanged(MediaPlaylistAgent playlistAgent, int repeatMode) {
-            final MediaSession2Impl session = mSession.get();
-            if (session == null) {
-                return;
-            }
-            session.notifyRepeatModeChangedOnExecutor(playlistAgent, repeatMode);
-        }
-
-        @Override
-        public void onShuffleModeChanged(MediaPlaylistAgent playlistAgent, int shuffleMode) {
-            final MediaSession2Impl session = mSession.get();
-            if (session == null) {
-                return;
-            }
-            session.notifyShuffleModeChangedOnExecutor(playlistAgent, shuffleMode);
-        }
-    }
-
-    public static final class CommandImpl implements CommandProvider {
-        private static final String KEY_COMMAND_CODE
-                = "android.media.media_session2.command.command_code";
-        private static final String KEY_COMMAND_CUSTOM_COMMAND
-                = "android.media.media_session2.command.custom_command";
-        private static final String KEY_COMMAND_EXTRAS
-                = "android.media.media_session2.command.extras";
-
-        private final SessionCommand2 mInstance;
-        private final int mCommandCode;
-        // Nonnull if it's custom command
-        private final String mCustomCommand;
-        private final Bundle mExtras;
-
-        public CommandImpl(SessionCommand2 instance, int commandCode) {
-            mInstance = instance;
-            mCommandCode = commandCode;
-            mCustomCommand = null;
-            mExtras = null;
-        }
-
-        public CommandImpl(SessionCommand2 instance, @NonNull String action,
-                @Nullable Bundle extras) {
-            if (action == null) {
-                throw new IllegalArgumentException("action shouldn't be null");
-            }
-            mInstance = instance;
-            mCommandCode = COMMAND_CODE_CUSTOM;
-            mCustomCommand = action;
-            mExtras = extras;
-        }
-
-        @Override
-        public int getCommandCode_impl() {
-            return mCommandCode;
-        }
-
-        @Override
-        public @Nullable String getCustomCommand_impl() {
-            return mCustomCommand;
-        }
-
-        @Override
-        public @Nullable Bundle getExtras_impl() {
-            return mExtras;
-        }
-
-        /**
-         * @return a new Bundle instance from the Command
-         */
-        @Override
-        public Bundle toBundle_impl() {
-            Bundle bundle = new Bundle();
-            bundle.putInt(KEY_COMMAND_CODE, mCommandCode);
-            bundle.putString(KEY_COMMAND_CUSTOM_COMMAND, mCustomCommand);
-            bundle.putBundle(KEY_COMMAND_EXTRAS, mExtras);
-            return bundle;
-        }
-
-        /**
-         * @return a new Command instance from the Bundle
-         */
-        public static SessionCommand2 fromBundle_impl(@NonNull Bundle command) {
-            if (command == null) {
-                throw new IllegalArgumentException("command shouldn't be null");
-            }
-            int code = command.getInt(KEY_COMMAND_CODE);
-            if (code != COMMAND_CODE_CUSTOM) {
-                return new SessionCommand2(code);
-            } else {
-                String customCommand = command.getString(KEY_COMMAND_CUSTOM_COMMAND);
-                if (customCommand == null) {
-                    return null;
-                }
-                return new SessionCommand2(customCommand, command.getBundle(KEY_COMMAND_EXTRAS));
-            }
-        }
-
-        @Override
-        public boolean equals_impl(Object obj) {
-            if (!(obj instanceof CommandImpl)) {
-                return false;
-            }
-            CommandImpl other = (CommandImpl) obj;
-            // TODO(jaewan): Compare Commands with the generated UUID, as we're doing for the MI2.
-            return mCommandCode == other.mCommandCode
-                    && TextUtils.equals(mCustomCommand, other.mCustomCommand);
-        }
-
-        @Override
-        public int hashCode_impl() {
-            final int prime = 31;
-            return ((mCustomCommand != null)
-                    ? mCustomCommand.hashCode() : 0) * prime + mCommandCode;
-        }
-    }
-
-    /**
-     * Represent set of {@link SessionCommand2}.
-     */
-    public static class CommandGroupImpl implements CommandGroupProvider {
-        private static final String KEY_COMMANDS =
-                "android.media.mediasession2.commandgroup.commands";
-
-        // Prefix for all command codes
-        private static final String PREFIX_COMMAND_CODE = "COMMAND_CODE_";
-
-        // Prefix for command codes that will be sent directly to the MediaPlayerBase
-        private static final String PREFIX_COMMAND_CODE_PLAYBACK = "COMMAND_CODE_PLAYBACK_";
-
-        // Prefix for command codes that will be sent directly to the MediaPlaylistAgent
-        private static final String PREFIX_COMMAND_CODE_PLAYLIST = "COMMAND_CODE_PLAYLIST_";
-
-        private Set<SessionCommand2> mCommands = new HashSet<>();
-        private final SessionCommandGroup2 mInstance;
-
-        public CommandGroupImpl(SessionCommandGroup2 instance, Object other) {
-            mInstance = instance;
-            if (other != null && other instanceof CommandGroupImpl) {
-                mCommands.addAll(((CommandGroupImpl) other).mCommands);
-            }
-        }
-
-        public CommandGroupImpl() {
-            mInstance = new SessionCommandGroup2(this);
-        }
-
-        @Override
-        public void addCommand_impl(@NonNull SessionCommand2 command) {
-            if (command == null) {
-                throw new IllegalArgumentException("command shouldn't be null");
-            }
-            mCommands.add(command);
-        }
-
-        @Override
-        public void addAllPredefinedCommands_impl() {
-            addCommandsWithPrefix(PREFIX_COMMAND_CODE);
-        }
-
-        void addAllPlaybackCommands() {
-            addCommandsWithPrefix(PREFIX_COMMAND_CODE_PLAYBACK);
-        }
-
-        void addAllPlaylistCommands() {
-            addCommandsWithPrefix(PREFIX_COMMAND_CODE_PLAYLIST);
-        }
-
-        private void addCommandsWithPrefix(String prefix) {
-            // TODO(jaewan): (Can be post-P): Don't use reflection for this purpose.
-            final Field[] fields = MediaSession2.class.getFields();
-            if (fields != null) {
-                for (int i = 0; i < fields.length; i++) {
-                    if (fields[i].getName().startsWith(prefix)) {
-                        try {
-                            mCommands.add(new SessionCommand2(fields[i].getInt(null)));
-                        } catch (IllegalAccessException e) {
-                            Log.w(TAG, "Unexpected " + fields[i] + " in MediaSession2");
-                        }
-                    }
-                }
-            }
-        }
-
-        @Override
-        public void removeCommand_impl(@NonNull SessionCommand2 command) {
-            if (command == null) {
-                throw new IllegalArgumentException("command shouldn't be null");
-            }
-            mCommands.remove(command);
-        }
-
-        @Override
-        public boolean hasCommand_impl(@NonNull SessionCommand2 command) {
-            if (command == null) {
-                throw new IllegalArgumentException("command shouldn't be null");
-            }
-            return mCommands.contains(command);
-        }
-
-        @Override
-        public boolean hasCommand_impl(int code) {
-            if (code == COMMAND_CODE_CUSTOM) {
-                throw new IllegalArgumentException("Use hasCommand(Command) for custom command");
-            }
-            for (SessionCommand2 command : mCommands) {
-                if (command.getCommandCode() == code) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public Set<SessionCommand2> getCommands_impl() {
-            return getCommands();
-        }
-
-        public Set<SessionCommand2> getCommands() {
-            return Collections.unmodifiableSet(mCommands);
-        }
-
-        /**
-         * @return new bundle from the CommandGroup
-         * @hide
-         */
-        @Override
-        public Bundle toBundle_impl() {
-            ArrayList<Bundle> list = new ArrayList<>();
-            for (SessionCommand2 command : mCommands) {
-                list.add(command.toBundle());
-            }
-            Bundle bundle = new Bundle();
-            bundle.putParcelableArrayList(KEY_COMMANDS, list);
-            return bundle;
-        }
-
-        /**
-         * @return new instance of CommandGroup from the bundle
-         * @hide
-         */
-        public static @Nullable SessionCommandGroup2 fromBundle_impl(Bundle commands) {
-            if (commands == null) {
-                return null;
-            }
-            List<Parcelable> list = commands.getParcelableArrayList(KEY_COMMANDS);
-            if (list == null) {
-                return null;
-            }
-            SessionCommandGroup2 commandGroup = new SessionCommandGroup2();
-            for (int i = 0; i < list.size(); i++) {
-                Parcelable parcelable = list.get(i);
-                if (!(parcelable instanceof Bundle)) {
-                    continue;
-                }
-                Bundle commandBundle = (Bundle) parcelable;
-                SessionCommand2 command = SessionCommand2.fromBundle(commandBundle);
-                if (command != null) {
-                    commandGroup.addCommand(command);
-                }
-            }
-            return commandGroup;
-        }
-    }
-
-    public static class ControllerInfoImpl implements ControllerInfoProvider {
-        private final ControllerInfo mInstance;
-        private final int mUid;
-        private final String mPackageName;
-        private final boolean mIsTrusted;
-        private final IMediaController2 mControllerBinder;
-
-        public ControllerInfoImpl(Context context, ControllerInfo instance, int uid,
-                int pid, @NonNull String packageName, @NonNull IMediaController2 callback) {
-            if (TextUtils.isEmpty(packageName)) {
-                throw new IllegalArgumentException("packageName shouldn't be empty");
-            }
-            if (callback == null) {
-                throw new IllegalArgumentException("callback shouldn't be null");
-            }
-
-            mInstance = instance;
-            mUid = uid;
-            mPackageName = packageName;
-            mControllerBinder = callback;
-            MediaSessionManager manager =
-                  (MediaSessionManager) context.getSystemService(Context.MEDIA_SESSION_SERVICE);
-            // Ask server whether the controller is trusted.
-            // App cannot know this because apps cannot query enabled notification listener for
-            // another package, but system server can do.
-            mIsTrusted = manager.isTrustedForMediaControl(
-                    new MediaSessionManager.RemoteUserInfo(packageName, pid, uid));
-        }
-
-        @Override
-        public String getPackageName_impl() {
-            return mPackageName;
-        }
-
-        @Override
-        public int getUid_impl() {
-            return mUid;
-        }
-
-        @Override
-        public boolean isTrusted_impl() {
-            return mIsTrusted;
-        }
-
-        @Override
-        public int hashCode_impl() {
-            return mControllerBinder.hashCode();
-        }
-
-        @Override
-        public boolean equals_impl(Object obj) {
-            if (!(obj instanceof ControllerInfo)) {
-                return false;
-            }
-            return equals(((ControllerInfo) obj).getProvider());
-        }
-
-        @Override
-        public String toString_impl() {
-            return "ControllerInfo {pkg=" + mPackageName + ", uid=" + mUid + ", trusted="
-                    + mIsTrusted + "}";
-        }
-
-        @Override
-        public int hashCode() {
-            return mControllerBinder.hashCode();
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (!(obj instanceof ControllerInfoImpl)) {
-                return false;
-            }
-            ControllerInfoImpl other = (ControllerInfoImpl) obj;
-            return mControllerBinder.asBinder().equals(other.mControllerBinder.asBinder());
-        }
-
-        ControllerInfo getInstance() {
-            return mInstance;
-        }
-
-        IBinder getId() {
-            return mControllerBinder.asBinder();
-        }
-
-        IMediaController2 getControllerBinder() {
-            return mControllerBinder;
-        }
-
-        static ControllerInfoImpl from(ControllerInfo controller) {
-            return (ControllerInfoImpl) controller.getProvider();
-        }
-    }
-
-    public static class CommandButtonImpl implements CommandButtonProvider {
-        private static final String KEY_COMMAND
-                = "android.media.media_session2.command_button.command";
-        private static final String KEY_ICON_RES_ID
-                = "android.media.media_session2.command_button.icon_res_id";
-        private static final String KEY_DISPLAY_NAME
-                = "android.media.media_session2.command_button.display_name";
-        private static final String KEY_EXTRAS
-                = "android.media.media_session2.command_button.extras";
-        private static final String KEY_ENABLED
-                = "android.media.media_session2.command_button.enabled";
-
-        private final CommandButton mInstance;
-        private SessionCommand2 mCommand;
-        private int mIconResId;
-        private String mDisplayName;
-        private Bundle mExtras;
-        private boolean mEnabled;
-
-        public CommandButtonImpl(@Nullable SessionCommand2 command, int iconResId,
-                @Nullable String displayName, Bundle extras, boolean enabled) {
-            mCommand = command;
-            mIconResId = iconResId;
-            mDisplayName = displayName;
-            mExtras = extras;
-            mEnabled = enabled;
-            mInstance = new CommandButton(this);
-        }
-
-        @Override
-        public @Nullable
-        SessionCommand2 getCommand_impl() {
-            return mCommand;
-        }
-
-        @Override
-        public int getIconResId_impl() {
-            return mIconResId;
-        }
-
-        @Override
-        public @Nullable String getDisplayName_impl() {
-            return mDisplayName;
-        }
-
-        @Override
-        public @Nullable Bundle getExtras_impl() {
-            return mExtras;
-        }
-
-        @Override
-        public boolean isEnabled_impl() {
-            return mEnabled;
-        }
-
-        @NonNull Bundle toBundle() {
-            Bundle bundle = new Bundle();
-            bundle.putBundle(KEY_COMMAND, mCommand.toBundle());
-            bundle.putInt(KEY_ICON_RES_ID, mIconResId);
-            bundle.putString(KEY_DISPLAY_NAME, mDisplayName);
-            bundle.putBundle(KEY_EXTRAS, mExtras);
-            bundle.putBoolean(KEY_ENABLED, mEnabled);
-            return bundle;
-        }
-
-        static @Nullable CommandButton fromBundle(Bundle bundle) {
-            if (bundle == null) {
-                return null;
-            }
-            CommandButton.Builder builder = new CommandButton.Builder();
-            builder.setCommand(SessionCommand2.fromBundle(bundle.getBundle(KEY_COMMAND)));
-            builder.setIconResId(bundle.getInt(KEY_ICON_RES_ID, 0));
-            builder.setDisplayName(bundle.getString(KEY_DISPLAY_NAME));
-            builder.setExtras(bundle.getBundle(KEY_EXTRAS));
-            builder.setEnabled(bundle.getBoolean(KEY_ENABLED));
-            try {
-                return builder.build();
-            } catch (IllegalStateException e) {
-                // Malformed or version mismatch. Return null for now.
-                return null;
-            }
-        }
-
-        /**
-         * Builder for {@link CommandButton}.
-         */
-        public static class BuilderImpl implements CommandButtonProvider.BuilderProvider {
-            private final CommandButton.Builder mInstance;
-            private SessionCommand2 mCommand;
-            private int mIconResId;
-            private String mDisplayName;
-            private Bundle mExtras;
-            private boolean mEnabled;
-
-            public BuilderImpl(CommandButton.Builder instance) {
-                mInstance = instance;
-                mEnabled = true;
-            }
-
-            @Override
-            public CommandButton.Builder setCommand_impl(SessionCommand2 command) {
-                mCommand = command;
-                return mInstance;
-            }
-
-            @Override
-            public CommandButton.Builder setIconResId_impl(int resId) {
-                mIconResId = resId;
-                return mInstance;
-            }
-
-            @Override
-            public CommandButton.Builder setDisplayName_impl(String displayName) {
-                mDisplayName = displayName;
-                return mInstance;
-            }
-
-            @Override
-            public CommandButton.Builder setEnabled_impl(boolean enabled) {
-                mEnabled = enabled;
-                return mInstance;
-            }
-
-            @Override
-            public CommandButton.Builder setExtras_impl(Bundle extras) {
-                mExtras = extras;
-                return mInstance;
-            }
-
-            @Override
-            public CommandButton build_impl() {
-                if (mEnabled && mCommand == null) {
-                    throw new IllegalStateException("Enabled button needs Command"
-                            + " for controller to invoke the command");
-                }
-                if (mCommand != null && mCommand.getCommandCode() == COMMAND_CODE_CUSTOM
-                        && (mIconResId == 0 || TextUtils.isEmpty(mDisplayName))) {
-                    throw new IllegalStateException("Custom commands needs icon and"
-                            + " and name to display");
-                }
-                return new CommandButtonImpl(mCommand, mIconResId, mDisplayName, mExtras, mEnabled)
-                        .mInstance;
-            }
-        }
-    }
-
-    public static abstract class BuilderBaseImpl<T extends MediaSession2, C extends SessionCallback>
-            implements BuilderBaseProvider<T, C> {
-        final Context mContext;
-        MediaPlayerBase mPlayer;
-        String mId;
-        Executor mCallbackExecutor;
-        C mCallback;
-        MediaPlaylistAgent mPlaylistAgent;
-        VolumeProvider2 mVolumeProvider;
-        PendingIntent mSessionActivity;
-
-        /**
-         * Constructor.
-         *
-         * @param context a context
-         * @throws IllegalArgumentException if any parameter is null, or the player is a
-         *      {@link MediaSession2} or {@link MediaController2}.
-         */
-        // TODO(jaewan): Also need executor
-        public BuilderBaseImpl(@NonNull Context context) {
-            if (context == null) {
-                throw new IllegalArgumentException("context shouldn't be null");
-            }
-            mContext = context;
-            // Ensure non-null
-            mId = "";
-        }
-
-        @Override
-        public void setPlayer_impl(@NonNull MediaPlayerBase player) {
-            if (player == null) {
-                throw new IllegalArgumentException("player shouldn't be null");
-            }
-            mPlayer = player;
-        }
-
-        @Override
-        public void setPlaylistAgent_impl(@NonNull MediaPlaylistAgent playlistAgent) {
-            if (playlistAgent == null) {
-                throw new IllegalArgumentException("playlistAgent shouldn't be null");
-            }
-            mPlaylistAgent = playlistAgent;
-        }
-
-        @Override
-        public void setVolumeProvider_impl(VolumeProvider2 volumeProvider) {
-            mVolumeProvider = volumeProvider;
-        }
-
-        @Override
-        public void setSessionActivity_impl(PendingIntent pi) {
-            mSessionActivity = pi;
-        }
-
-        @Override
-        public void setId_impl(@NonNull String id) {
-            if (id == null) {
-                throw new IllegalArgumentException("id shouldn't be null");
-            }
-            mId = id;
-        }
-
-        @Override
-        public void setSessionCallback_impl(@NonNull Executor executor, @NonNull C callback) {
-            if (executor == null) {
-                throw new IllegalArgumentException("executor shouldn't be null");
-            }
-            if (callback == null) {
-                throw new IllegalArgumentException("callback shouldn't be null");
-            }
-            mCallbackExecutor = executor;
-            mCallback = callback;
-        }
-
-        @Override
-        public abstract T build_impl();
-    }
-
-    public static class BuilderImpl extends BuilderBaseImpl<MediaSession2, SessionCallback> {
-        public BuilderImpl(Context context, Builder instance) {
-            super(context);
-        }
-
-        @Override
-        public MediaSession2 build_impl() {
-            if (mCallbackExecutor == null) {
-                mCallbackExecutor = mContext.getMainExecutor();
-            }
-            if (mCallback == null) {
-                mCallback = new SessionCallback() {};
-            }
-            return new MediaSession2Impl(mContext, mPlayer, mId, mPlaylistAgent,
-                    mVolumeProvider, mSessionActivity, mCallbackExecutor, mCallback).getInstance();
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java b/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java
deleted file mode 100644
index ec657d7..0000000
--- a/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java
+++ /dev/null
@@ -1,1113 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.media;
-
-import android.app.PendingIntent;
-import android.content.Context;
-import android.media.MediaController2;
-import android.media.MediaItem2;
-import android.media.MediaLibraryService2.LibraryRoot;
-import android.media.MediaMetadata2;
-import android.media.SessionCommand2;
-import android.media.MediaSession2.CommandButton;
-import android.media.SessionCommandGroup2;
-import android.media.MediaSession2.ControllerInfo;
-import android.media.Rating2;
-import android.media.VolumeProvider2;
-import android.net.Uri;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.DeadObjectException;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.support.annotation.GuardedBy;
-import android.support.annotation.NonNull;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.SparseArray;
-
-import com.android.media.MediaLibraryService2Impl.MediaLibrarySessionImpl;
-import com.android.media.MediaSession2Impl.CommandButtonImpl;
-import com.android.media.MediaSession2Impl.CommandGroupImpl;
-import com.android.media.MediaSession2Impl.ControllerInfoImpl;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-public class MediaSession2Stub extends IMediaSession2.Stub {
-
-    static final String ARGUMENT_KEY_POSITION = "android.media.media_session2.key_position";
-    static final String ARGUMENT_KEY_ITEM_INDEX = "android.media.media_session2.key_item_index";
-    static final String ARGUMENT_KEY_PLAYLIST_PARAMS =
-            "android.media.media_session2.key_playlist_params";
-
-    private static final String TAG = "MediaSession2Stub";
-    private static final boolean DEBUG = true; // TODO(jaewan): Rename.
-
-    private static final SparseArray<SessionCommand2> sCommandsForOnCommandRequest =
-            new SparseArray<>();
-
-    private final Object mLock = new Object();
-    private final WeakReference<MediaSession2Impl> mSession;
-
-    @GuardedBy("mLock")
-    private final ArrayMap<IBinder, ControllerInfo> mControllers = new ArrayMap<>();
-    @GuardedBy("mLock")
-    private final Set<IBinder> mConnectingControllers = new HashSet<>();
-    @GuardedBy("mLock")
-    private final ArrayMap<ControllerInfo, SessionCommandGroup2> mAllowedCommandGroupMap =
-            new ArrayMap<>();
-    @GuardedBy("mLock")
-    private final ArrayMap<ControllerInfo, Set<String>> mSubscriptions = new ArrayMap<>();
-
-    public MediaSession2Stub(MediaSession2Impl session) {
-        mSession = new WeakReference<>(session);
-
-        synchronized (sCommandsForOnCommandRequest) {
-            if (sCommandsForOnCommandRequest.size() == 0) {
-                CommandGroupImpl group = new CommandGroupImpl();
-                group.addAllPlaybackCommands();
-                group.addAllPlaylistCommands();
-                Set<SessionCommand2> commands = group.getCommands();
-                for (SessionCommand2 command : commands) {
-                    sCommandsForOnCommandRequest.append(command.getCommandCode(), command);
-                }
-            }
-        }
-    }
-
-    public void destroyNotLocked() {
-        final List<ControllerInfo> list;
-        synchronized (mLock) {
-            mSession.clear();
-            list = getControllers();
-            mControllers.clear();
-        }
-        for (int i = 0; i < list.size(); i++) {
-            IMediaController2 controllerBinder =
-                    ((ControllerInfoImpl) list.get(i).getProvider()).getControllerBinder();
-            try {
-                // Should be used without a lock hold to prevent potential deadlock.
-                controllerBinder.onDisconnected();
-            } catch (RemoteException e) {
-                // Controller is gone. Should be fine because we're destroying.
-            }
-        }
-    }
-
-    private MediaSession2Impl getSession() {
-        final MediaSession2Impl session = mSession.get();
-        if (session == null && DEBUG) {
-            Log.d(TAG, "Session is closed", new IllegalStateException());
-        }
-        return session;
-    }
-
-    private MediaLibrarySessionImpl getLibrarySession() throws IllegalStateException {
-        final MediaSession2Impl session = getSession();
-        if (!(session instanceof MediaLibrarySessionImpl)) {
-            throw new RuntimeException("Session isn't a library session");
-        }
-        return (MediaLibrarySessionImpl) session;
-    }
-
-    // Get controller if the command from caller to session is able to be handled.
-    private ControllerInfo getControllerIfAble(IMediaController2 caller) {
-        synchronized (mLock) {
-            final ControllerInfo controllerInfo = mControllers.get(caller.asBinder());
-            if (controllerInfo == null && DEBUG) {
-                Log.d(TAG, "Controller is disconnected", new IllegalStateException());
-            }
-            return controllerInfo;
-        }
-    }
-
-    // Get controller if the command from caller to session is able to be handled.
-    private ControllerInfo getControllerIfAble(IMediaController2 caller, int commandCode) {
-        synchronized (mLock) {
-            final ControllerInfo controllerInfo = getControllerIfAble(caller);
-            if (controllerInfo == null) {
-                return null;
-            }
-            SessionCommandGroup2 allowedCommands = mAllowedCommandGroupMap.get(controllerInfo);
-            if (allowedCommands == null) {
-                Log.w(TAG, "Controller with null allowed commands. Ignoring",
-                        new IllegalStateException());
-                return null;
-            }
-            if (!allowedCommands.hasCommand(commandCode)) {
-                if (DEBUG) {
-                    Log.d(TAG, "Controller isn't allowed for command " + commandCode);
-                }
-                return null;
-            }
-            return controllerInfo;
-        }
-    }
-
-    // Get controller if the command from caller to session is able to be handled.
-    private ControllerInfo getControllerIfAble(IMediaController2 caller, SessionCommand2 command) {
-        synchronized (mLock) {
-            final ControllerInfo controllerInfo = getControllerIfAble(caller);
-            if (controllerInfo == null) {
-                return null;
-            }
-            SessionCommandGroup2 allowedCommands = mAllowedCommandGroupMap.get(controllerInfo);
-            if (allowedCommands == null) {
-                Log.w(TAG, "Controller with null allowed commands. Ignoring",
-                        new IllegalStateException());
-                return null;
-            }
-            if (!allowedCommands.hasCommand(command)) {
-                if (DEBUG) {
-                    Log.d(TAG, "Controller isn't allowed for command " + command);
-                }
-                return null;
-            }
-            return controllerInfo;
-        }
-    }
-
-    // Return binder if the session is able to send a command to the controller.
-    private IMediaController2 getControllerBinderIfAble(ControllerInfo controller) {
-        if (getSession() == null) {
-            // getSession() already logged if session is closed.
-            return null;
-        }
-        final ControllerInfoImpl impl = ControllerInfoImpl.from(controller);
-        synchronized (mLock) {
-            if (mControllers.get(impl.getId()) != null
-                    || mConnectingControllers.contains(impl.getId())) {
-                return impl.getControllerBinder();
-            }
-            if (DEBUG) {
-                Log.d(TAG, controller + " isn't connected nor connecting",
-                        new IllegalArgumentException());
-            }
-            return null;
-        }
-    }
-
-    // Return binder if the session is able to send a command to the controller.
-    private IMediaController2 getControllerBinderIfAble(ControllerInfo controller,
-            int commandCode) {
-        synchronized (mLock) {
-            SessionCommandGroup2 allowedCommands = mAllowedCommandGroupMap.get(controller);
-            if (allowedCommands == null) {
-                Log.w(TAG, "Controller with null allowed commands. Ignoring");
-                return null;
-            }
-            if (!allowedCommands.hasCommand(commandCode)) {
-                if (DEBUG) {
-                    Log.d(TAG, "Controller isn't allowed for command " + commandCode);
-                }
-                return null;
-            }
-            return getControllerBinderIfAble(controller);
-        }
-    }
-
-    private void onCommand(@NonNull IMediaController2 caller, int commandCode,
-            @NonNull SessionRunnable runnable) {
-        final MediaSession2Impl session = getSession();
-        final ControllerInfo controller = getControllerIfAble(caller, commandCode);
-        if (session == null || controller == null) {
-            return;
-        }
-        session.getCallbackExecutor().execute(() -> {
-            if (getControllerIfAble(caller, commandCode) == null) {
-                return;
-            }
-            SessionCommand2 command = sCommandsForOnCommandRequest.get(commandCode);
-            if (command != null) {
-                boolean accepted = session.getCallback().onCommandRequest(session.getInstance(),
-                        controller, command);
-                if (!accepted) {
-                    // Don't run rejected command.
-                    if (DEBUG) {
-                        Log.d(TAG, "Command (code=" + commandCode + ") from "
-                                + controller + " was rejected by " + session);
-                    }
-                    return;
-                }
-            }
-            runnable.run(session, controller);
-        });
-    }
-
-    private void onBrowserCommand(@NonNull IMediaController2 caller,
-            @NonNull LibrarySessionRunnable runnable) {
-        final MediaLibrarySessionImpl session = getLibrarySession();
-        // TODO(jaewan): Consider command code
-        final ControllerInfo controller = getControllerIfAble(caller);
-        if (session == null || controller == null) {
-            return;
-        }
-        session.getCallbackExecutor().execute(() -> {
-            // TODO(jaewan): Consider command code
-            if (getControllerIfAble(caller) == null) {
-                return;
-            }
-            runnable.run(session, controller);
-        });
-    }
-
-
-    private void notifyAll(int commandCode, @NonNull NotifyRunnable runnable) {
-        List<ControllerInfo> controllers = getControllers();
-        for (int i = 0; i < controllers.size(); i++) {
-            notifyInternal(controllers.get(i),
-                    getControllerBinderIfAble(controllers.get(i), commandCode), runnable);
-        }
-    }
-
-    private void notifyAll(@NonNull NotifyRunnable runnable) {
-        List<ControllerInfo> controllers = getControllers();
-        for (int i = 0; i < controllers.size(); i++) {
-            notifyInternal(controllers.get(i),
-                    getControllerBinderIfAble(controllers.get(i)), runnable);
-        }
-    }
-
-    private void notify(@NonNull ControllerInfo controller, @NonNull NotifyRunnable runnable) {
-        notifyInternal(controller, getControllerBinderIfAble(controller), runnable);
-    }
-
-    private void notify(@NonNull ControllerInfo controller, int commandCode,
-            @NonNull NotifyRunnable runnable) {
-        notifyInternal(controller, getControllerBinderIfAble(controller, commandCode), runnable);
-    }
-
-    // Do not call this API directly. Use notify() instead.
-    private void notifyInternal(@NonNull ControllerInfo controller,
-            @NonNull IMediaController2 iController, @NonNull NotifyRunnable runnable) {
-        if (controller == null || iController == null) {
-            return;
-        }
-        try {
-            runnable.run(controller, iController);
-        } catch (DeadObjectException e) {
-            if (DEBUG) {
-                Log.d(TAG, controller.toString() + " is gone", e);
-            }
-            onControllerClosed(iController);
-        } catch (RemoteException e) {
-            // Currently it's TransactionTooLargeException or DeadSystemException.
-            // We'd better to leave log for those cases because
-            //   - TransactionTooLargeException means that we may need to fix our code.
-            //     (e.g. add pagination or special way to deliver Bitmap)
-            //   - DeadSystemException means that errors around it can be ignored.
-            Log.w(TAG, "Exception in " + controller.toString(), e);
-        }
-    }
-
-    private void onControllerClosed(IMediaController2 iController) {
-        ControllerInfo controller;
-        synchronized (mLock) {
-            controller = mControllers.remove(iController.asBinder());
-            if (DEBUG) {
-                Log.d(TAG, "releasing " + controller);
-            }
-            mSubscriptions.remove(controller);
-        }
-        final MediaSession2Impl session = getSession();
-        if (session == null || controller == null) {
-            return;
-        }
-        session.getCallbackExecutor().execute(() -> {
-            session.getCallback().onDisconnected(session.getInstance(), controller);
-        });
-    }
-
-    //////////////////////////////////////////////////////////////////////////////////////////////
-    // AIDL methods for session overrides
-    //////////////////////////////////////////////////////////////////////////////////////////////
-    @Override
-    public void connect(final IMediaController2 caller, final String callingPackage)
-            throws RuntimeException {
-        final MediaSession2Impl session = getSession();
-        if (session == null) {
-            return;
-        }
-        final Context context = session.getContext();
-        final ControllerInfo controllerInfo = new ControllerInfo(context,
-                Binder.getCallingUid(), Binder.getCallingPid(), callingPackage, caller);
-        session.getCallbackExecutor().execute(() -> {
-            if (getSession() == null) {
-                return;
-            }
-            synchronized (mLock) {
-                // Keep connecting controllers.
-                // This helps sessions to call APIs in the onConnect() (e.g. setCustomLayout())
-                // instead of pending them.
-                mConnectingControllers.add(ControllerInfoImpl.from(controllerInfo).getId());
-            }
-            SessionCommandGroup2 allowedCommands = session.getCallback().onConnect(
-                    session.getInstance(), controllerInfo);
-            // Don't reject connection for the request from trusted app.
-            // Otherwise server will fail to retrieve session's information to dispatch
-            // media keys to.
-            boolean accept = allowedCommands != null || controllerInfo.isTrusted();
-            if (accept) {
-                ControllerInfoImpl controllerImpl = ControllerInfoImpl.from(controllerInfo);
-                if (DEBUG) {
-                    Log.d(TAG, "Accepting connection, controllerInfo=" + controllerInfo
-                            + " allowedCommands=" + allowedCommands);
-                }
-                if (allowedCommands == null) {
-                    // For trusted apps, send non-null allowed commands to keep connection.
-                    allowedCommands = new SessionCommandGroup2();
-                }
-                synchronized (mLock) {
-                    mConnectingControllers.remove(controllerImpl.getId());
-                    mControllers.put(controllerImpl.getId(),  controllerInfo);
-                    mAllowedCommandGroupMap.put(controllerInfo, allowedCommands);
-                }
-                // If connection is accepted, notify the current state to the controller.
-                // It's needed because we cannot call synchronous calls between session/controller.
-                // Note: We're doing this after the onConnectionChanged(), but there's no guarantee
-                //       that events here are notified after the onConnected() because
-                //       IMediaController2 is oneway (i.e. async call) and Stub will
-                //       use thread poll for incoming calls.
-                final int playerState = session.getInstance().getPlayerState();
-                final long positionEventTimeMs = System.currentTimeMillis();
-                final long positionMs = session.getInstance().getCurrentPosition();
-                final float playbackSpeed = session.getInstance().getPlaybackSpeed();
-                final long bufferedPositionMs = session.getInstance().getBufferedPosition();
-                final Bundle playbackInfoBundle = ((MediaController2Impl.PlaybackInfoImpl)
-                        session.getPlaybackInfo().getProvider()).toBundle();
-                final int repeatMode = session.getInstance().getRepeatMode();
-                final int shuffleMode = session.getInstance().getShuffleMode();
-                final PendingIntent sessionActivity = session.getSessionActivity();
-                final List<MediaItem2> playlist =
-                        allowedCommands.hasCommand(SessionCommand2.COMMAND_CODE_PLAYLIST_GET_LIST)
-                                ? session.getInstance().getPlaylist() : null;
-                final List<Bundle> playlistBundle;
-                if (playlist != null) {
-                    playlistBundle = new ArrayList<>();
-                    // TODO(jaewan): Find a way to avoid concurrent modification exception.
-                    for (int i = 0; i < playlist.size(); i++) {
-                        final MediaItem2 item = playlist.get(i);
-                        if (item != null) {
-                            final Bundle itemBundle = item.toBundle();
-                            if (itemBundle != null) {
-                                playlistBundle.add(itemBundle);
-                            }
-                        }
-                    }
-                } else {
-                    playlistBundle = null;
-                }
-
-                // Double check if session is still there, because close() can be called in another
-                // thread.
-                if (getSession() == null) {
-                    return;
-                }
-                try {
-                    caller.onConnected(MediaSession2Stub.this, allowedCommands.toBundle(),
-                            playerState, positionEventTimeMs, positionMs, playbackSpeed,
-                            bufferedPositionMs, playbackInfoBundle, repeatMode, shuffleMode,
-                            playlistBundle, sessionActivity);
-                } catch (RemoteException e) {
-                    // Controller may be died prematurely.
-                    // TODO(jaewan): Handle here.
-                }
-            } else {
-                synchronized (mLock) {
-                    mConnectingControllers.remove(ControllerInfoImpl.from(controllerInfo).getId());
-                }
-                if (DEBUG) {
-                    Log.d(TAG, "Rejecting connection, controllerInfo=" + controllerInfo);
-                }
-                try {
-                    caller.onDisconnected();
-                } catch (RemoteException e) {
-                    // Controller may be died prematurely.
-                    // Not an issue because we'll ignore it anyway.
-                }
-            }
-        });
-    }
-
-    @Override
-    public void release(final IMediaController2 caller) throws RemoteException {
-        onControllerClosed(caller);
-    }
-
-    @Override
-    public void setVolumeTo(final IMediaController2 caller, final int value, final int flags)
-            throws RuntimeException {
-        onCommand(caller, SessionCommand2.COMMAND_CODE_SET_VOLUME,
-                (session, controller) -> {
-                    VolumeProvider2 volumeProvider = session.getVolumeProvider();
-                    if (volumeProvider == null) {
-                        // TODO(jaewan): Set local stream volume
-                    } else {
-                        volumeProvider.onSetVolumeTo(value);
-                    }
-                });
-    }
-
-    @Override
-    public void adjustVolume(IMediaController2 caller, int direction, int flags)
-            throws RuntimeException {
-        onCommand(caller, SessionCommand2.COMMAND_CODE_SET_VOLUME,
-                (session, controller) -> {
-                    VolumeProvider2 volumeProvider = session.getVolumeProvider();
-                    if (volumeProvider == null) {
-                        // TODO(jaewan): Adjust local stream volume
-                    } else {
-                        volumeProvider.onAdjustVolume(direction);
-                    }
-                });
-    }
-
-    @Override
-    public void sendTransportControlCommand(IMediaController2 caller,
-            int commandCode, Bundle args) throws RuntimeException {
-        onCommand(caller, commandCode, (session, controller) -> {
-            switch (commandCode) {
-                case SessionCommand2.COMMAND_CODE_PLAYBACK_PLAY:
-                    session.getInstance().play();
-                    break;
-                case SessionCommand2.COMMAND_CODE_PLAYBACK_PAUSE:
-                    session.getInstance().pause();
-                    break;
-                case SessionCommand2.COMMAND_CODE_PLAYBACK_STOP:
-                    session.getInstance().stop();
-                    break;
-                case SessionCommand2.COMMAND_CODE_PLAYBACK_PREPARE:
-                    session.getInstance().prepare();
-                    break;
-                case SessionCommand2.COMMAND_CODE_PLAYBACK_SEEK_TO:
-                    session.getInstance().seekTo(args.getLong(ARGUMENT_KEY_POSITION));
-                    break;
-                default:
-                    // TODO(jaewan): Resend unknown (new) commands through the custom command.
-            }
-        });
-    }
-
-    @Override
-    public void sendCustomCommand(final IMediaController2 caller, final Bundle commandBundle,
-            final Bundle args, final ResultReceiver receiver) {
-        final MediaSession2Impl session = getSession();
-        if (session == null) {
-            return;
-        }
-        final SessionCommand2 command = SessionCommand2.fromBundle(commandBundle);
-        if (command == null) {
-            Log.w(TAG, "sendCustomCommand(): Ignoring null command from "
-                    + getControllerIfAble(caller));
-            return;
-        }
-        final ControllerInfo controller = getControllerIfAble(caller, command);
-        if (controller == null) {
-            return;
-        }
-        session.getCallbackExecutor().execute(() -> {
-            if (getControllerIfAble(caller, command) == null) {
-                return;
-            }
-            session.getCallback().onCustomCommand(session.getInstance(),
-                    controller, command, args, receiver);
-        });
-    }
-
-    @Override
-    public void prepareFromUri(final IMediaController2 caller, final Uri uri,
-            final Bundle extras) {
-        onCommand(caller, SessionCommand2.COMMAND_CODE_SESSION_PREPARE_FROM_URI,
-                (session, controller) -> {
-                    if (uri == null) {
-                        Log.w(TAG, "prepareFromUri(): Ignoring null uri from " + controller);
-                        return;
-                    }
-                    session.getCallback().onPrepareFromUri(session.getInstance(), controller, uri,
-                            extras);
-                });
-    }
-
-    @Override
-    public void prepareFromSearch(final IMediaController2 caller, final String query,
-            final Bundle extras) {
-        onCommand(caller, SessionCommand2.COMMAND_CODE_SESSION_PREPARE_FROM_SEARCH,
-                (session, controller) -> {
-                    if (TextUtils.isEmpty(query)) {
-                        Log.w(TAG, "prepareFromSearch(): Ignoring empty query from " + controller);
-                        return;
-                    }
-                    session.getCallback().onPrepareFromSearch(session.getInstance(),
-                            controller, query, extras);
-                });
-    }
-
-    @Override
-    public void prepareFromMediaId(final IMediaController2 caller, final String mediaId,
-            final Bundle extras) {
-        onCommand(caller, SessionCommand2.COMMAND_CODE_SESSION_PREPARE_FROM_MEDIA_ID,
-                (session, controller) -> {
-            if (mediaId == null) {
-                Log.w(TAG, "prepareFromMediaId(): Ignoring null mediaId from " + controller);
-                return;
-            }
-            session.getCallback().onPrepareFromMediaId(session.getInstance(),
-                    controller, mediaId, extras);
-        });
-    }
-
-    @Override
-    public void playFromUri(final IMediaController2 caller, final Uri uri,
-            final Bundle extras) {
-        onCommand(caller, SessionCommand2.COMMAND_CODE_SESSION_PLAY_FROM_URI,
-                (session, controller) -> {
-                    if (uri == null) {
-                        Log.w(TAG, "playFromUri(): Ignoring null uri from " + controller);
-                        return;
-                    }
-                    session.getCallback().onPlayFromUri(session.getInstance(), controller, uri,
-                            extras);
-                });
-    }
-
-    @Override
-    public void playFromSearch(final IMediaController2 caller, final String query,
-            final Bundle extras) {
-        onCommand(caller, SessionCommand2.COMMAND_CODE_SESSION_PLAY_FROM_SEARCH,
-                (session, controller) -> {
-                    if (TextUtils.isEmpty(query)) {
-                        Log.w(TAG, "playFromSearch(): Ignoring empty query from " + controller);
-                        return;
-                    }
-                    session.getCallback().onPlayFromSearch(session.getInstance(),
-                            controller, query, extras);
-                });
-    }
-
-    @Override
-    public void playFromMediaId(final IMediaController2 caller, final String mediaId,
-            final Bundle extras) {
-        onCommand(caller, SessionCommand2.COMMAND_CODE_SESSION_PLAY_FROM_MEDIA_ID,
-                (session, controller) -> {
-                    if (mediaId == null) {
-                        Log.w(TAG, "playFromMediaId(): Ignoring null mediaId from " + controller);
-                        return;
-                    }
-                    session.getCallback().onPlayFromMediaId(session.getInstance(), controller,
-                            mediaId, extras);
-                });
-    }
-
-    @Override
-    public void setRating(final IMediaController2 caller, final String mediaId,
-            final Bundle ratingBundle) {
-        onCommand(caller, SessionCommand2.COMMAND_CODE_SESSION_SET_RATING,
-                (session, controller) -> {
-                    if (mediaId == null) {
-                        Log.w(TAG, "setRating(): Ignoring null mediaId from " + controller);
-                        return;
-                    }
-                    if (ratingBundle == null) {
-                        Log.w(TAG, "setRating(): Ignoring null ratingBundle from " + controller);
-                        return;
-                    }
-                    Rating2 rating = Rating2.fromBundle(ratingBundle);
-                    if (rating == null) {
-                        if (ratingBundle == null) {
-                            Log.w(TAG, "setRating(): Ignoring null rating from " + controller);
-                            return;
-                        }
-                        return;
-                    }
-                    session.getCallback().onSetRating(session.getInstance(), controller, mediaId,
-                            rating);
-                });
-    }
-
-    @Override
-    public void setPlaylist(final IMediaController2 caller, final List<Bundle> playlist,
-            final Bundle metadata) {
-        onCommand(caller, SessionCommand2.COMMAND_CODE_PLAYLIST_SET_LIST, (session, controller) -> {
-            if (playlist == null) {
-                Log.w(TAG, "setPlaylist(): Ignoring null playlist from " + controller);
-                return;
-            }
-            List<MediaItem2> list = new ArrayList<>();
-            for (int i = 0; i < playlist.size(); i++) {
-                // Recreates UUID in the playlist
-                MediaItem2 item = MediaItem2Impl.fromBundle(playlist.get(i), null);
-                if (item != null) {
-                    list.add(item);
-                }
-            }
-            session.getInstance().setPlaylist(list, MediaMetadata2.fromBundle(metadata));
-        });
-    }
-
-    @Override
-    public void updatePlaylistMetadata(final IMediaController2 caller, final Bundle metadata) {
-        onCommand(caller, SessionCommand2.COMMAND_CODE_PLAYLIST_SET_LIST_METADATA,
-                (session, controller) -> {
-            session.getInstance().updatePlaylistMetadata(MediaMetadata2.fromBundle(metadata));
-        });
-    }
-
-    @Override
-    public void addPlaylistItem(IMediaController2 caller, int index, Bundle mediaItem) {
-        onCommand(caller, SessionCommand2.COMMAND_CODE_PLAYLIST_ADD_ITEM,
-                (session, controller) -> {
-                    // Resets the UUID from the incoming media id, so controller may reuse a media
-                    // item multiple times for addPlaylistItem.
-                    session.getInstance().addPlaylistItem(index,
-                            MediaItem2Impl.fromBundle(mediaItem, null));
-                });
-    }
-
-    @Override
-    public void removePlaylistItem(IMediaController2 caller, Bundle mediaItem) {
-        onCommand(caller, SessionCommand2.COMMAND_CODE_PLAYLIST_REMOVE_ITEM,
-                (session, controller) -> {
-            MediaItem2 item = MediaItem2.fromBundle(mediaItem);
-            // Note: MediaItem2 has hidden UUID to identify it across the processes.
-            session.getInstance().removePlaylistItem(item);
-        });
-    }
-
-    @Override
-    public void replacePlaylistItem(IMediaController2 caller, int index, Bundle mediaItem) {
-        onCommand(caller, SessionCommand2.COMMAND_CODE_PLAYLIST_REPLACE_ITEM,
-                (session, controller) -> {
-                    // Resets the UUID from the incoming media id, so controller may reuse a media
-                    // item multiple times for replacePlaylistItem.
-                    session.getInstance().replacePlaylistItem(index,
-                            MediaItem2Impl.fromBundle(mediaItem, null));
-                });
-    }
-
-    @Override
-    public void skipToPlaylistItem(IMediaController2 caller, Bundle mediaItem) {
-        onCommand(caller, SessionCommand2.COMMAND_CODE_PLAYLIST_SKIP_TO_PLAYLIST_ITEM,
-                (session, controller) -> {
-                    if (mediaItem == null) {
-                        Log.w(TAG, "skipToPlaylistItem(): Ignoring null mediaItem from "
-                                + controller);
-                    }
-                    // Note: MediaItem2 has hidden UUID to identify it across the processes.
-                    session.getInstance().skipToPlaylistItem(MediaItem2.fromBundle(mediaItem));
-                });
-    }
-
-    @Override
-    public void skipToPreviousItem(IMediaController2 caller) {
-        onCommand(caller, SessionCommand2.COMMAND_CODE_PLAYLIST_SKIP_PREV_ITEM,
-                (session, controller) -> {
-                    session.getInstance().skipToPreviousItem();
-                });
-    }
-
-    @Override
-    public void skipToNextItem(IMediaController2 caller) {
-        onCommand(caller, SessionCommand2.COMMAND_CODE_PLAYLIST_SKIP_NEXT_ITEM,
-                (session, controller) -> {
-                    session.getInstance().skipToNextItem();
-                });
-    }
-
-    @Override
-    public void setRepeatMode(IMediaController2 caller, int repeatMode) {
-        onCommand(caller, SessionCommand2.COMMAND_CODE_PLAYLIST_SET_REPEAT_MODE,
-                (session, controller) -> {
-                    session.getInstance().setRepeatMode(repeatMode);
-                });
-    }
-
-    @Override
-    public void setShuffleMode(IMediaController2 caller, int shuffleMode) {
-        onCommand(caller, SessionCommand2.COMMAND_CODE_PLAYLIST_SET_SHUFFLE_MODE,
-                (session, controller) -> {
-                    session.getInstance().setShuffleMode(shuffleMode);
-                });
-    }
-
-    //////////////////////////////////////////////////////////////////////////////////////////////
-    // AIDL methods for LibrarySession overrides
-    //////////////////////////////////////////////////////////////////////////////////////////////
-
-    @Override
-    public void getLibraryRoot(final IMediaController2 caller, final Bundle rootHints)
-            throws RuntimeException {
-        onBrowserCommand(caller, (session, controller) -> {
-            final LibraryRoot root = session.getCallback().onGetLibraryRoot(session.getInstance(),
-                    controller, rootHints);
-            notify(controller, (unused, iController) -> {
-                iController.onGetLibraryRootDone(rootHints,
-                        root == null ? null : root.getRootId(),
-                        root == null ? null : root.getExtras());
-            });
-        });
-    }
-
-    @Override
-    public void getItem(final IMediaController2 caller, final String mediaId)
-            throws RuntimeException {
-        onBrowserCommand(caller, (session, controller) -> {
-            if (mediaId == null) {
-                if (DEBUG) {
-                    Log.d(TAG, "mediaId shouldn't be null");
-                }
-                return;
-            }
-            final MediaItem2 result = session.getCallback().onGetItem(session.getInstance(),
-                    controller, mediaId);
-            notify(controller, (unused, iController) -> {
-                iController.onGetItemDone(mediaId, result == null ? null : result.toBundle());
-            });
-        });
-    }
-
-    @Override
-    public void getChildren(final IMediaController2 caller, final String parentId,
-            final int page, final int pageSize, final Bundle extras) throws RuntimeException {
-        onBrowserCommand(caller, (session, controller) -> {
-            if (parentId == null) {
-                if (DEBUG) {
-                    Log.d(TAG, "parentId shouldn't be null");
-                }
-                return;
-            }
-            if (page < 1 || pageSize < 1) {
-                if (DEBUG) {
-                    Log.d(TAG, "Neither page nor pageSize should be less than 1");
-                }
-                return;
-            }
-            List<MediaItem2> result = session.getCallback().onGetChildren(session.getInstance(),
-                    controller, parentId, page, pageSize, extras);
-            if (result != null && result.size() > pageSize) {
-                throw new IllegalArgumentException("onGetChildren() shouldn't return media items "
-                        + "more than pageSize. result.size()=" + result.size() + " pageSize="
-                        + pageSize);
-            }
-            final List<Bundle> bundleList;
-            if (result != null) {
-                bundleList = new ArrayList<>();
-                for (MediaItem2 item : result) {
-                    bundleList.add(item == null ? null : item.toBundle());
-                }
-            } else {
-                bundleList = null;
-            }
-            notify(controller, (unused, iController) -> {
-                iController.onGetChildrenDone(parentId, page, pageSize, bundleList, extras);
-            });
-        });
-    }
-
-    @Override
-    public void search(IMediaController2 caller, String query, Bundle extras) {
-        onBrowserCommand(caller, (session, controller) -> {
-            if (TextUtils.isEmpty(query)) {
-                Log.w(TAG, "search(): Ignoring empty query from " + controller);
-                return;
-            }
-            session.getCallback().onSearch(session.getInstance(), controller, query, extras);
-        });
-    }
-
-    @Override
-    public void getSearchResult(final IMediaController2 caller, final String query,
-            final int page, final int pageSize, final Bundle extras) {
-        onBrowserCommand(caller, (session, controller) -> {
-            if (TextUtils.isEmpty(query)) {
-                Log.w(TAG, "getSearchResult(): Ignoring empty query from " + controller);
-                return;
-            }
-            if (page < 1 || pageSize < 1) {
-                Log.w(TAG, "getSearchResult(): Ignoring negative page / pageSize."
-                        + " page=" + page + " pageSize=" + pageSize + " from " + controller);
-                return;
-            }
-            List<MediaItem2> result = session.getCallback().onGetSearchResult(session.getInstance(),
-                    controller, query, page, pageSize, extras);
-            if (result != null && result.size() > pageSize) {
-                throw new IllegalArgumentException("onGetSearchResult() shouldn't return media "
-                        + "items more than pageSize. result.size()=" + result.size() + " pageSize="
-                        + pageSize);
-            }
-            final List<Bundle> bundleList;
-            if (result != null) {
-                bundleList = new ArrayList<>();
-                for (MediaItem2 item : result) {
-                    bundleList.add(item == null ? null : item.toBundle());
-                }
-            } else {
-                bundleList = null;
-            }
-            notify(controller, (unused, iController) -> {
-                iController.onGetSearchResultDone(query, page, pageSize, bundleList, extras);
-            });
-        });
-    }
-
-    @Override
-    public void subscribe(final IMediaController2 caller, final String parentId,
-            final Bundle option) {
-        onBrowserCommand(caller, (session, controller) -> {
-            if (parentId == null) {
-                Log.w(TAG, "subscribe(): Ignoring null parentId from " + controller);
-                return;
-            }
-            session.getCallback().onSubscribe(session.getInstance(),
-                    controller, parentId, option);
-            synchronized (mLock) {
-                Set<String> subscription = mSubscriptions.get(controller);
-                if (subscription == null) {
-                    subscription = new HashSet<>();
-                    mSubscriptions.put(controller, subscription);
-                }
-                subscription.add(parentId);
-            }
-        });
-    }
-
-    @Override
-    public void unsubscribe(final IMediaController2 caller, final String parentId) {
-        onBrowserCommand(caller, (session, controller) -> {
-            if (parentId == null) {
-                Log.w(TAG, "unsubscribe(): Ignoring null parentId from " + controller);
-                return;
-            }
-            session.getCallback().onUnsubscribe(session.getInstance(), controller, parentId);
-            synchronized (mLock) {
-                mSubscriptions.remove(controller);
-            }
-        });
-    }
-
-    //////////////////////////////////////////////////////////////////////////////////////////////
-    // APIs for MediaSession2Impl
-    //////////////////////////////////////////////////////////////////////////////////////////////
-
-    // TODO(jaewan): (Can be Post-P) Need a way to get controller with permissions
-    public List<ControllerInfo> getControllers() {
-        ArrayList<ControllerInfo> controllers = new ArrayList<>();
-        synchronized (mLock) {
-            for (int i = 0; i < mControllers.size(); i++) {
-                controllers.add(mControllers.valueAt(i));
-            }
-        }
-        return controllers;
-    }
-
-    // Should be used without a lock to prevent potential deadlock.
-    public void notifyPlayerStateChangedNotLocked(int state) {
-        notifyAll((controller, iController) -> {
-            iController.onPlayerStateChanged(state);
-        });
-    }
-
-    // TODO(jaewan): Rename
-    public void notifyPositionChangedNotLocked(long eventTimeMs, long positionMs) {
-        notifyAll((controller, iController) -> {
-            iController.onPositionChanged(eventTimeMs, positionMs);
-        });
-    }
-
-    public void notifyPlaybackSpeedChangedNotLocked(float speed) {
-        notifyAll((controller, iController) -> {
-            iController.onPlaybackSpeedChanged(speed);
-        });
-    }
-
-    public void notifyBufferedPositionChangedNotLocked(long bufferedPositionMs) {
-        notifyAll((controller, iController) -> {
-            iController.onBufferedPositionChanged(bufferedPositionMs);
-        });
-    }
-
-    public void notifyCustomLayoutNotLocked(ControllerInfo controller, List<CommandButton> layout) {
-        notify(controller, (unused, iController) -> {
-            List<Bundle> layoutBundles = new ArrayList<>();
-            for (int i = 0; i < layout.size(); i++) {
-                Bundle bundle = ((CommandButtonImpl) layout.get(i).getProvider()).toBundle();
-                if (bundle != null) {
-                    layoutBundles.add(bundle);
-                }
-            }
-            iController.onCustomLayoutChanged(layoutBundles);
-        });
-    }
-
-    public void notifyPlaylistChangedNotLocked(List<MediaItem2> playlist, MediaMetadata2 metadata) {
-        final List<Bundle> bundleList;
-        if (playlist != null) {
-            bundleList = new ArrayList<>();
-            for (int i = 0; i < playlist.size(); i++) {
-                if (playlist.get(i) != null) {
-                    Bundle bundle = playlist.get(i).toBundle();
-                    if (bundle != null) {
-                        bundleList.add(bundle);
-                    }
-                }
-            }
-        } else {
-            bundleList = null;
-        }
-        final Bundle metadataBundle = (metadata == null) ? null : metadata.toBundle();
-        notifyAll((controller, iController) -> {
-            if (getControllerBinderIfAble(controller,
-                    SessionCommand2.COMMAND_CODE_PLAYLIST_GET_LIST) != null) {
-                iController.onPlaylistChanged(bundleList, metadataBundle);
-            } else if (getControllerBinderIfAble(controller,
-                    SessionCommand2.COMMAND_CODE_PLAYLIST_GET_LIST_METADATA) != null) {
-                iController.onPlaylistMetadataChanged(metadataBundle);
-            }
-        });
-    }
-
-    public void notifyPlaylistMetadataChangedNotLocked(MediaMetadata2 metadata) {
-        final Bundle metadataBundle = (metadata == null) ? null : metadata.toBundle();
-        notifyAll(SessionCommand2.COMMAND_CODE_PLAYLIST_GET_LIST_METADATA,
-                (unused, iController) -> {
-                    iController.onPlaylistMetadataChanged(metadataBundle);
-                });
-    }
-
-    public void notifyRepeatModeChangedNotLocked(int repeatMode) {
-        notifyAll((unused, iController) -> {
-            iController.onRepeatModeChanged(repeatMode);
-        });
-    }
-
-    public void notifyShuffleModeChangedNotLocked(int shuffleMode) {
-        notifyAll((unused, iController) -> {
-            iController.onShuffleModeChanged(shuffleMode);
-        });
-    }
-
-    public void notifyPlaybackInfoChanged(MediaController2.PlaybackInfo playbackInfo) {
-        final Bundle playbackInfoBundle =
-                ((MediaController2Impl.PlaybackInfoImpl) playbackInfo.getProvider()).toBundle();
-        notifyAll((unused, iController) -> {
-            iController.onPlaybackInfoChanged(playbackInfoBundle);
-        });
-    }
-
-    public void setAllowedCommands(ControllerInfo controller, SessionCommandGroup2 commands) {
-        synchronized (mLock) {
-            mAllowedCommandGroupMap.put(controller, commands);
-        }
-        notify(controller, (unused, iController) -> {
-            iController.onAllowedCommandsChanged(commands.toBundle());
-        });
-    }
-
-    public void sendCustomCommand(ControllerInfo controller, SessionCommand2 command, Bundle args,
-            ResultReceiver receiver) {
-        if (receiver != null && controller == null) {
-            throw new IllegalArgumentException("Controller shouldn't be null if result receiver is"
-                    + " specified");
-        }
-        if (command == null) {
-            throw new IllegalArgumentException("command shouldn't be null");
-        }
-        notify(controller, (unused, iController) -> {
-            Bundle commandBundle = command.toBundle();
-            iController.onCustomCommand(commandBundle, args, null);
-        });
-    }
-
-    public void sendCustomCommand(SessionCommand2 command, Bundle args) {
-        if (command == null) {
-            throw new IllegalArgumentException("command shouldn't be null");
-        }
-        Bundle commandBundle = command.toBundle();
-        notifyAll((unused, iController) -> {
-            iController.onCustomCommand(commandBundle, args, null);
-        });
-    }
-
-    public void notifyError(int errorCode, Bundle extras) {
-        notifyAll((unused, iController) -> {
-            iController.onError(errorCode, extras);
-        });
-    }
-
-    //////////////////////////////////////////////////////////////////////////////////////////////
-    // APIs for MediaLibrarySessionImpl
-    //////////////////////////////////////////////////////////////////////////////////////////////
-
-    public void notifySearchResultChanged(ControllerInfo controller, String query, int itemCount,
-            Bundle extras) {
-        notify(controller, (unused, iController) -> {
-            iController.onSearchResultChanged(query, itemCount, extras);
-        });
-    }
-
-    public void notifyChildrenChangedNotLocked(ControllerInfo controller, String parentId,
-            int itemCount, Bundle extras) {
-        notify(controller, (unused, iController) -> {
-            if (isSubscribed(controller, parentId)) {
-                iController.onChildrenChanged(parentId, itemCount, extras);
-            }
-        });
-    }
-
-    public void notifyChildrenChangedNotLocked(String parentId, int itemCount, Bundle extras) {
-        notifyAll((controller, iController) -> {
-            if (isSubscribed(controller, parentId)) {
-                iController.onChildrenChanged(parentId, itemCount, extras);
-            }
-        });
-    }
-
-    private boolean isSubscribed(ControllerInfo controller, String parentId) {
-        synchronized (mLock) {
-            Set<String> subscriptions = mSubscriptions.get(controller);
-            if (subscriptions == null || !subscriptions.contains(parentId)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    //////////////////////////////////////////////////////////////////////////////////////////////
-    // Misc
-    //////////////////////////////////////////////////////////////////////////////////////////////
-
-    @FunctionalInterface
-    private interface SessionRunnable {
-        void run(final MediaSession2Impl session, final ControllerInfo controller);
-    }
-
-    @FunctionalInterface
-    private interface LibrarySessionRunnable {
-        void run(final MediaLibrarySessionImpl session, final ControllerInfo controller);
-    }
-
-    @FunctionalInterface
-    private interface NotifyRunnable {
-        void run(final ControllerInfo controller,
-                final IMediaController2 iController) throws RemoteException;
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/media/MediaSessionService2Impl.java b/packages/MediaComponents/src/com/android/media/MediaSessionService2Impl.java
deleted file mode 100644
index c33eb65..0000000
--- a/packages/MediaComponents/src/com/android/media/MediaSessionService2Impl.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.media;
-
-import static android.content.Context.NOTIFICATION_SERVICE;
-
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.content.Context;
-import android.content.Intent;
-import android.media.MediaPlayerBase;
-import android.media.MediaPlayerBase.PlayerEventCallback;
-import android.media.MediaSession2;
-import android.media.MediaSessionService2;
-import android.media.MediaSessionService2.MediaNotification;
-import android.media.SessionToken2;
-import android.media.SessionToken2.TokenType;
-import android.media.update.MediaSessionService2Provider;
-import android.os.IBinder;
-import android.support.annotation.GuardedBy;
-import android.util.Log;
-
-// TODO(jaewan): Need a test for session service itself.
-public class MediaSessionService2Impl implements MediaSessionService2Provider {
-
-    private static final String TAG = "MPSessionService"; // to meet 23 char limit in Log tag
-    private static final boolean DEBUG = true; // TODO(jaewan): Change this. (b/74094611)
-
-    private final MediaSessionService2 mInstance;
-    private final PlayerEventCallback mCallback = new SessionServiceEventCallback();
-
-    private final Object mLock = new Object();
-    @GuardedBy("mLock")
-    private NotificationManager mNotificationManager;
-    @GuardedBy("mLock")
-    private Intent mStartSelfIntent;
-
-    private boolean mIsRunningForeground;
-    private MediaSession2 mSession;
-
-    public MediaSessionService2Impl(MediaSessionService2 instance) {
-        if (DEBUG) {
-            Log.d(TAG, "MediaSessionService2Impl(" + instance + ")");
-        }
-        mInstance = instance;
-    }
-
-    @Override
-    public MediaSession2 getSession_impl() {
-        return getSession();
-    }
-
-    MediaSession2 getSession() {
-        synchronized (mLock) {
-            return mSession;
-        }
-    }
-
-    @Override
-    public MediaNotification onUpdateNotification_impl() {
-        // Provide default notification UI later.
-        return null;
-    }
-
-    @Override
-    public void onCreate_impl() {
-        mNotificationManager = (NotificationManager) mInstance.getSystemService(
-                NOTIFICATION_SERVICE);
-        mStartSelfIntent = new Intent(mInstance, mInstance.getClass());
-
-        SessionToken2 token = new SessionToken2(mInstance, mInstance.getPackageName(),
-                mInstance.getClass().getName());
-        if (token.getType() != getSessionType()) {
-            throw new RuntimeException("Expected session service, but was " + token.getType());
-        }
-        mSession = mInstance.onCreateSession(token.getId());
-        if (mSession == null || !token.getId().equals(mSession.getToken().getId())) {
-            throw new RuntimeException("Expected session with id " + token.getId()
-                    + ", but got " + mSession);
-        }
-        // TODO(jaewan): Uncomment here.
-        // mSession.registerPlayerEventCallback(mCallback, mSession.getExecutor());
-    }
-
-    @TokenType int getSessionType() {
-        return SessionToken2.TYPE_SESSION_SERVICE;
-    }
-
-    public IBinder onBind_impl(Intent intent) {
-        if (MediaSessionService2.SERVICE_INTERFACE.equals(intent.getAction())) {
-            return ((MediaSession2Impl) mSession.getProvider()).getSessionStub().asBinder();
-        }
-        return null;
-    }
-
-    private void updateNotification(int playerState) {
-        MediaNotification mediaNotification = mInstance.onUpdateNotification();
-        if (mediaNotification == null) {
-            return;
-        }
-        switch(playerState) {
-            case MediaPlayerBase.PLAYER_STATE_PLAYING:
-                if (!mIsRunningForeground) {
-                    mIsRunningForeground = true;
-                    mInstance.startForegroundService(mStartSelfIntent);
-                    mInstance.startForeground(mediaNotification.getNotificationId(),
-                            mediaNotification.getNotification());
-                    return;
-                }
-                break;
-            case MediaPlayerBase.PLAYER_STATE_IDLE:
-            case MediaPlayerBase.PLAYER_STATE_ERROR:
-                if (mIsRunningForeground) {
-                    mIsRunningForeground = false;
-                    mInstance.stopForeground(true);
-                    return;
-                }
-                break;
-        }
-        mNotificationManager.notify(mediaNotification.getNotificationId(),
-                mediaNotification.getNotification());
-    }
-
-    private class SessionServiceEventCallback extends PlayerEventCallback {
-        @Override
-        public void onPlayerStateChanged(MediaPlayerBase player, int state) {
-            // TODO: Implement this
-            return;
-        }
-    }
-
-    public static class MediaNotificationImpl implements MediaNotificationProvider {
-        private int mNotificationId;
-        private Notification mNotification;
-
-        public MediaNotificationImpl(MediaNotification instance, int notificationId,
-                Notification notification) {
-            if (notification == null) {
-                throw new IllegalArgumentException("notification shouldn't be null");
-            }
-            mNotificationId = notificationId;
-            mNotification = notification;
-        }
-
-        @Override
-        public int getNotificationId_impl() {
-            return mNotificationId;
-        }
-
-        @Override
-        public Notification getNotification_impl() {
-            return mNotification;
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/media/Rating2Impl.java b/packages/MediaComponents/src/com/android/media/Rating2Impl.java
deleted file mode 100644
index d558129..0000000
--- a/packages/MediaComponents/src/com/android/media/Rating2Impl.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.media;
-
-import static android.media.Rating2.*;
-
-import android.content.Context;
-import android.media.Rating2;
-import android.media.Rating2.Style;
-import android.media.update.Rating2Provider;
-import android.os.Bundle;
-import android.util.Log;
-
-import java.util.Objects;
-
-public final class Rating2Impl implements Rating2Provider {
-    private static final String TAG = "Rating2";
-
-    private static final String KEY_STYLE = "android.media.rating2.style";
-    private static final String KEY_VALUE = "android.media.rating2.value";
-
-    private final static float RATING_NOT_RATED = -1.0f;
-
-    private final Rating2 mInstance;
-    private final int mRatingStyle;
-    private final float mRatingValue;
-
-    private Rating2Impl(@Style int ratingStyle, float rating) {
-        mRatingStyle = ratingStyle;
-        mRatingValue = rating;
-        mInstance = new Rating2(this);
-    }
-
-    @Override
-    public String toString_impl() {
-        return "Rating2:style=" + mRatingStyle + " rating="
-                + (mRatingValue < 0.0f ? "unrated" : String.valueOf(mRatingValue));
-    }
-
-    @Override
-    public boolean equals_impl(Object obj) {
-        if (!(obj instanceof Rating2)) {
-            return false;
-        }
-        Rating2Impl other = (Rating2Impl) ((Rating2) obj).getProvider();
-        return mRatingStyle == other.mRatingStyle
-                && mRatingValue == other.mRatingValue;
-    }
-
-    @Override
-    public int hashCode_impl() {
-        return Objects.hash(mRatingStyle, mRatingValue);
-    }
-
-    Rating2 getInstance() {
-        return mInstance;
-    }
-
-    public static Rating2 fromBundle_impl(Bundle bundle) {
-        if (bundle == null) {
-            return null;
-        }
-        return new Rating2Impl(bundle.getInt(KEY_STYLE), bundle.getFloat(KEY_VALUE)).getInstance();
-    }
-
-    public Bundle toBundle_impl() {
-        Bundle bundle = new Bundle();
-        bundle.putInt(KEY_STYLE, mRatingStyle);
-        bundle.putFloat(KEY_VALUE, mRatingValue);
-        return bundle;
-    }
-
-    public static Rating2 newUnratedRating_impl(@Style int ratingStyle) {
-        switch(ratingStyle) {
-            case RATING_HEART:
-            case RATING_THUMB_UP_DOWN:
-            case RATING_3_STARS:
-            case RATING_4_STARS:
-            case RATING_5_STARS:
-            case RATING_PERCENTAGE:
-                return new Rating2Impl(ratingStyle, RATING_NOT_RATED).getInstance();
-            default:
-                return null;
-        }
-    }
-
-    public static Rating2 newHeartRating_impl(boolean hasHeart) {
-        return new Rating2Impl(RATING_HEART, hasHeart ? 1.0f : 0.0f).getInstance();
-    }
-
-    public static Rating2 newThumbRating_impl(boolean thumbIsUp) {
-        return new Rating2Impl(RATING_THUMB_UP_DOWN, thumbIsUp ? 1.0f : 0.0f).getInstance();
-    }
-
-    public static Rating2 newStarRating_impl(int starRatingStyle, float starRating) {
-        float maxRating = RATING_NOT_RATED;
-        switch(starRatingStyle) {
-            case RATING_3_STARS:
-                maxRating = 3.0f;
-                break;
-            case RATING_4_STARS:
-                maxRating = 4.0f;
-                break;
-            case RATING_5_STARS:
-                maxRating = 5.0f;
-                break;
-            default:
-                Log.e(TAG, "Invalid rating style (" + starRatingStyle + ") for a star rating");
-                return null;
-        }
-        if ((starRating < 0.0f) || (starRating > maxRating)) {
-            Log.e(TAG, "Trying to set out of range star-based rating");
-            return null;
-        }
-        return new Rating2Impl(starRatingStyle, starRating).getInstance();
-    }
-
-    public static Rating2 newPercentageRating_impl(float percent) {
-        if ((percent < 0.0f) || (percent > 100.0f)) {
-            Log.e(TAG, "Invalid percentage-based rating value");
-            return null;
-        } else {
-            return new Rating2Impl(RATING_PERCENTAGE, percent).getInstance();
-        }
-    }
-
-    @Override
-    public boolean isRated_impl() {
-        return mRatingValue >= 0.0f;
-    }
-
-    @Override
-    public int getRatingStyle_impl() {
-        return mRatingStyle;
-    }
-
-    @Override
-    public boolean hasHeart_impl() {
-        if (mRatingStyle != RATING_HEART) {
-            return false;
-        } else {
-            return (mRatingValue == 1.0f);
-        }
-    }
-
-    @Override
-    public boolean isThumbUp_impl() {
-        if (mRatingStyle != RATING_THUMB_UP_DOWN) {
-            return false;
-        } else {
-            return (mRatingValue == 1.0f);
-        }
-    }
-
-    @Override
-    public float getStarRating_impl() {
-        switch (mRatingStyle) {
-            case RATING_3_STARS:
-            case RATING_4_STARS:
-            case RATING_5_STARS:
-                if (mInstance.isRated()) {
-                    return mRatingValue;
-                }
-            default:
-                return -1.0f;
-        }
-    }
-
-    @Override
-    public float getPercentRating_impl() {
-        if ((mRatingStyle != RATING_PERCENTAGE) || !mInstance.isRated()) {
-            return -1.0f;
-        } else {
-            return mRatingValue;
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/media/RoutePlayer.java b/packages/MediaComponents/src/com/android/media/RoutePlayer.java
deleted file mode 100644
index 9450d34..0000000
--- a/packages/MediaComponents/src/com/android/media/RoutePlayer.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.media;
-
-import android.content.Context;
-import android.media.DataSourceDesc;
-import android.media.session.MediaSession;
-import android.media.session.PlaybackState;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.support.annotation.RequiresApi;
-
-import com.android.support.mediarouter.media.MediaItemStatus;
-import com.android.support.mediarouter.media.MediaRouter;
-import com.android.support.mediarouter.media.MediaSessionStatus;
-import com.android.support.mediarouter.media.RemotePlaybackClient;
-import com.android.support.mediarouter.media.RemotePlaybackClient.ItemActionCallback;
-import com.android.support.mediarouter.media.RemotePlaybackClient.SessionActionCallback;
-import com.android.support.mediarouter.media.RemotePlaybackClient.StatusCallback;
-
-import java.util.Map;
-
-@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
-public class RoutePlayer extends MediaSession.Callback {
-    public static final long PLAYBACK_ACTIONS = PlaybackState.ACTION_PAUSE
-            | PlaybackState.ACTION_PLAY | PlaybackState.ACTION_SEEK_TO
-            | PlaybackState.ACTION_FAST_FORWARD | PlaybackState.ACTION_REWIND;
-
-    private RemotePlaybackClient mClient;
-    private String mSessionId;
-    private String mItemId;
-    private PlayerEventCallback mCallback;
-
-    private StatusCallback mStatusCallback = new StatusCallback() {
-        @Override
-        public void onItemStatusChanged(Bundle data,
-                String sessionId, MediaSessionStatus sessionStatus,
-                String itemId, MediaItemStatus itemStatus) {
-            updateSessionStatus(sessionId, sessionStatus);
-            updateItemStatus(itemId, itemStatus);
-        }
-    };
-
-    public RoutePlayer(Context context, MediaRouter.RouteInfo route) {
-        mClient = new RemotePlaybackClient(context, route);
-        mClient.setStatusCallback(mStatusCallback);
-        mClient.startSession(null, new SessionActionCallback() {
-            @Override
-            public void onResult(Bundle data,
-                    String sessionId, MediaSessionStatus sessionStatus) {
-                updateSessionStatus(sessionId, sessionStatus);
-            }
-        });
-    }
-
-    @Override
-    public void onPlay() {
-        mClient.resume(null, new SessionActionCallback() {
-            @Override
-            public void onResult(Bundle data,
-                    String sessionId, MediaSessionStatus sessionStatus) {
-                updateSessionStatus(sessionId, sessionStatus);
-            }
-        });
-    }
-
-    @Override
-    public void onPause() {
-        mClient.pause(null, new SessionActionCallback() {
-            @Override
-            public void onResult(Bundle data,
-                    String sessionId, MediaSessionStatus sessionStatus) {
-                updateSessionStatus(sessionId, sessionStatus);
-            }
-        });
-    }
-
-    @Override
-    public void onSeekTo(long pos) {
-        mClient.seek(mItemId, pos, null, new ItemActionCallback() {
-            @Override
-            public void onResult(Bundle data,
-                    String sessionId, MediaSessionStatus sessionStatus,
-                    String itemId, MediaItemStatus itemStatus) {
-                updateSessionStatus(sessionId, sessionStatus);
-                updateItemStatus(itemId, itemStatus);
-            }
-        });
-    }
-
-    @Override
-    public void onStop() {
-        mClient.stop(null, new SessionActionCallback() {
-            @Override
-            public void onResult(Bundle data,
-                    String sessionId, MediaSessionStatus sessionStatus) {
-                updateSessionStatus(sessionId, sessionStatus);
-            }
-        });
-    }
-
-    public void setPlayerEventCallback(PlayerEventCallback callback) {
-        mCallback = callback;
-    }
-
-    public void openVideo(DataSourceDesc dsd) {
-        mClient.play(dsd.getUri(), "video/mp4", null, 0, null, new ItemActionCallback() {
-            @Override
-            public void onResult(Bundle data,
-                    String sessionId, MediaSessionStatus sessionStatus,
-                    String itemId, MediaItemStatus itemStatus) {
-                updateSessionStatus(sessionId, sessionStatus);
-                updateItemStatus(itemId, itemStatus);
-                playInternal(dsd.getUri());
-            }
-        });
-    }
-
-    public void release() {
-        if (mClient != null) {
-            mClient.release();
-            mClient = null;
-        }
-        if (mCallback != null) {
-            mCallback = null;
-        }
-    }
-
-    private void playInternal(Uri uri) {
-        mClient.play(uri, "video/mp4", null, 0, null, new ItemActionCallback() {
-            @Override
-            public void onResult(Bundle data,
-                    String sessionId, MediaSessionStatus sessionStatus,
-                    String itemId, MediaItemStatus itemStatus) {
-                updateSessionStatus(sessionId, sessionStatus);
-                updateItemStatus(itemId, itemStatus);
-            }
-        });
-    }
-
-    private void updateSessionStatus(String sessionId, MediaSessionStatus sessionStatus) {
-        mSessionId = sessionId;
-    }
-
-    private void updateItemStatus(String itemId, MediaItemStatus itemStatus) {
-        mItemId = itemId;
-        if (itemStatus == null || mCallback == null) return;
-        mCallback.onPlayerStateChanged(itemStatus);
-    }
-
-    public static abstract class PlayerEventCallback {
-        public void onPlayerStateChanged(MediaItemStatus itemStatus) { }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/media/SessionPlaylistAgent.java b/packages/MediaComponents/src/com/android/media/SessionPlaylistAgent.java
deleted file mode 100644
index 1c570aa..0000000
--- a/packages/MediaComponents/src/com/android/media/SessionPlaylistAgent.java
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.media;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.media.DataSourceDesc;
-import android.media.MediaItem2;
-import android.media.MediaMetadata2;
-import android.media.MediaPlayerBase;
-import android.media.MediaPlayerBase.PlayerEventCallback;
-import android.media.MediaPlaylistAgent;
-import android.media.MediaSession2.OnDataSourceMissingHelper;
-import android.util.ArrayMap;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ThreadLocalRandom;
-
-public class SessionPlaylistAgent extends MediaPlaylistAgent {
-    private static final String TAG = "SessionPlaylistAgent";
-    @VisibleForTesting
-    static final int END_OF_PLAYLIST = -1;
-    @VisibleForTesting
-    static final int NO_VALID_ITEMS = -2;
-
-    private final PlayItem mEopPlayItem = new PlayItem(END_OF_PLAYLIST, null);
-
-    private final Object mLock = new Object();
-    private final MediaSession2Impl mSessionImpl;
-    private final MyPlayerEventCallback mPlayerCallback;
-
-    @GuardedBy("mLock")
-    private MediaPlayerBase mPlayer;
-    @GuardedBy("mLock")
-    private OnDataSourceMissingHelper mDsmHelper;
-    // TODO: Check if having the same item is okay (b/74090741)
-    @GuardedBy("mLock")
-    private ArrayList<MediaItem2> mPlaylist = new ArrayList<>();
-    @GuardedBy("mLock")
-    private ArrayList<MediaItem2> mShuffledList = new ArrayList<>();
-    @GuardedBy("mLock")
-    private Map<MediaItem2, DataSourceDesc> mItemDsdMap = new ArrayMap<>();
-    @GuardedBy("mLock")
-    private MediaMetadata2 mMetadata;
-    @GuardedBy("mLock")
-    private int mRepeatMode;
-    @GuardedBy("mLock")
-    private int mShuffleMode;
-    @GuardedBy("mLock")
-    private PlayItem mCurrent;
-
-    // Called on session callback executor.
-    private class MyPlayerEventCallback extends PlayerEventCallback {
-        public void onCurrentDataSourceChanged(@NonNull MediaPlayerBase mpb,
-                @Nullable DataSourceDesc dsd) {
-            if (mPlayer != mpb) {
-                return;
-            }
-            synchronized (mLock) {
-                if (dsd == null && mCurrent != null) {
-                    mCurrent = getNextValidPlayItemLocked(mCurrent.shuffledIdx, 1);
-                    updateCurrentIfNeededLocked();
-                }
-            }
-        }
-    }
-
-    private class PlayItem {
-        int shuffledIdx;
-        DataSourceDesc dsd;
-        MediaItem2 mediaItem;
-
-        PlayItem(int shuffledIdx) {
-            this(shuffledIdx, null);
-        }
-
-        PlayItem(int shuffledIdx, DataSourceDesc dsd) {
-            this.shuffledIdx = shuffledIdx;
-            if (shuffledIdx >= 0) {
-                this.mediaItem = mShuffledList.get(shuffledIdx);
-                if (dsd == null) {
-                    synchronized (mLock) {
-                        this.dsd = retrieveDataSourceDescLocked(this.mediaItem);
-                    }
-                } else {
-                    this.dsd = dsd;
-                }
-            }
-        }
-
-        boolean isValid() {
-            if (this == mEopPlayItem) {
-                return true;
-            }
-            if (mediaItem == null) {
-                return false;
-            }
-            if (dsd == null) {
-                return false;
-            }
-            if (shuffledIdx >= mShuffledList.size()) {
-                return false;
-            }
-            if (mediaItem != mShuffledList.get(shuffledIdx)) {
-                return false;
-            }
-            if (mediaItem.getDataSourceDesc() != null
-                    && !mediaItem.getDataSourceDesc().equals(dsd)) {
-                return false;
-            }
-            return true;
-        }
-    }
-
-    public SessionPlaylistAgent(@NonNull MediaSession2Impl sessionImpl,
-            @NonNull MediaPlayerBase player) {
-        if (sessionImpl == null) {
-            throw new IllegalArgumentException("sessionImpl shouldn't be null");
-        }
-        if (player == null) {
-            throw new IllegalArgumentException("player shouldn't be null");
-        }
-        mSessionImpl = sessionImpl;
-        mPlayer = player;
-        mPlayerCallback = new MyPlayerEventCallback();
-        mPlayer.registerPlayerEventCallback(mSessionImpl.getCallbackExecutor(), mPlayerCallback);
-    }
-
-    public void setPlayer(@NonNull MediaPlayerBase player) {
-        if (player == null) {
-            throw new IllegalArgumentException("player shouldn't be null");
-        }
-        synchronized (mLock) {
-            if (player == mPlayer) {
-                return;
-            }
-            mPlayer.unregisterPlayerEventCallback(mPlayerCallback);
-            mPlayer = player;
-            mPlayer.registerPlayerEventCallback(
-                    mSessionImpl.getCallbackExecutor(), mPlayerCallback);
-            updatePlayerDataSourceLocked();
-        }
-    }
-
-    public void setOnDataSourceMissingHelper(OnDataSourceMissingHelper helper) {
-        synchronized (mLock) {
-            mDsmHelper = helper;
-        }
-    }
-
-    public void clearOnDataSourceMissingHelper() {
-        synchronized (mLock) {
-            mDsmHelper = null;
-        }
-    }
-
-    @Override
-    public @Nullable List<MediaItem2> getPlaylist() {
-        synchronized (mLock) {
-            return Collections.unmodifiableList(mPlaylist);
-        }
-    }
-
-    @Override
-    public void setPlaylist(@NonNull List<MediaItem2> list, @Nullable MediaMetadata2 metadata) {
-        if (list == null) {
-            throw new IllegalArgumentException("list shouldn't be null");
-        }
-
-        synchronized (mLock) {
-            mItemDsdMap.clear();
-
-            mPlaylist.clear();
-            mPlaylist.addAll(list);
-            applyShuffleModeLocked();
-
-            mMetadata = metadata;
-            mCurrent = getNextValidPlayItemLocked(END_OF_PLAYLIST, 1);
-            updatePlayerDataSourceLocked();
-        }
-        notifyPlaylistChanged();
-    }
-
-    @Override
-    public @Nullable MediaMetadata2 getPlaylistMetadata() {
-        return mMetadata;
-    }
-
-    @Override
-    public void updatePlaylistMetadata(@Nullable MediaMetadata2 metadata) {
-        synchronized (mLock) {
-            if (metadata == mMetadata) {
-                return;
-            }
-            mMetadata = metadata;
-        }
-        notifyPlaylistMetadataChanged();
-    }
-
-    @Override
-    public void addPlaylistItem(int index, @NonNull MediaItem2 item) {
-        if (item == null) {
-            throw new IllegalArgumentException("item shouldn't be null");
-        }
-        synchronized (mLock) {
-            index = clamp(index, mPlaylist.size());
-            int shuffledIdx = index;
-            mPlaylist.add(index, item);
-            if (mShuffleMode == MediaPlaylistAgent.SHUFFLE_MODE_NONE) {
-                mShuffledList.add(index, item);
-            } else {
-                // Add the item in random position of mShuffledList.
-                shuffledIdx = ThreadLocalRandom.current().nextInt(mShuffledList.size() + 1);
-                mShuffledList.add(shuffledIdx, item);
-            }
-            if (!hasValidItem()) {
-                mCurrent = getNextValidPlayItemLocked(END_OF_PLAYLIST, 1);
-                updatePlayerDataSourceLocked();
-            } else {
-                updateCurrentIfNeededLocked();
-            }
-        }
-        notifyPlaylistChanged();
-    }
-
-    @Override
-    public void removePlaylistItem(@NonNull MediaItem2 item) {
-        if (item == null) {
-            throw new IllegalArgumentException("item shouldn't be null");
-        }
-        synchronized (mLock) {
-            if (!mPlaylist.remove(item)) {
-                return;
-            }
-            mShuffledList.remove(item);
-            mItemDsdMap.remove(item);
-            updateCurrentIfNeededLocked();
-        }
-        notifyPlaylistChanged();
-    }
-
-    @Override
-    public void replacePlaylistItem(int index, @NonNull MediaItem2 item) {
-        if (item == null) {
-            throw new IllegalArgumentException("item shouldn't be null");
-        }
-        synchronized (mLock) {
-            if (mPlaylist.size() <= 0) {
-                return;
-            }
-            index = clamp(index, mPlaylist.size() - 1);
-            int shuffledIdx = mShuffledList.indexOf(mPlaylist.get(index));
-            mItemDsdMap.remove(mShuffledList.get(shuffledIdx));
-            mShuffledList.set(shuffledIdx, item);
-            mPlaylist.set(index, item);
-            if (!hasValidItem()) {
-                mCurrent = getNextValidPlayItemLocked(END_OF_PLAYLIST, 1);
-                updatePlayerDataSourceLocked();
-            } else {
-                updateCurrentIfNeededLocked();
-            }
-        }
-        notifyPlaylistChanged();
-    }
-
-    @Override
-    public void skipToPlaylistItem(@NonNull MediaItem2 item) {
-        if (item == null) {
-            throw new IllegalArgumentException("item shouldn't be null");
-        }
-        synchronized (mLock) {
-            if (!hasValidItem() || item.equals(mCurrent.mediaItem)) {
-                return;
-            }
-            int shuffledIdx = mShuffledList.indexOf(item);
-            if (shuffledIdx < 0) {
-                return;
-            }
-            mCurrent = new PlayItem(shuffledIdx);
-            updateCurrentIfNeededLocked();
-        }
-    }
-
-    @Override
-    public void skipToPreviousItem() {
-        synchronized (mLock) {
-            if (!hasValidItem()) {
-                return;
-            }
-            PlayItem prev = getNextValidPlayItemLocked(mCurrent.shuffledIdx, -1);
-            if (prev != mEopPlayItem) {
-                mCurrent = prev;
-            }
-            updateCurrentIfNeededLocked();
-       }
-    }
-
-    @Override
-    public void skipToNextItem() {
-        synchronized (mLock) {
-            if (!hasValidItem() || mCurrent == mEopPlayItem) {
-                return;
-            }
-            PlayItem next = getNextValidPlayItemLocked(mCurrent.shuffledIdx, 1);
-            if (next != mEopPlayItem) {
-                mCurrent = next;
-            }
-            updateCurrentIfNeededLocked();
-        }
-    }
-
-    @Override
-    public int getRepeatMode() {
-        return mRepeatMode;
-    }
-
-    @Override
-    public void setRepeatMode(int repeatMode) {
-        if (repeatMode < MediaPlaylistAgent.REPEAT_MODE_NONE
-                || repeatMode > MediaPlaylistAgent.REPEAT_MODE_GROUP) {
-            return;
-        }
-        synchronized (mLock) {
-            if (mRepeatMode == repeatMode) {
-                return;
-            }
-            mRepeatMode = repeatMode;
-            switch (repeatMode) {
-                case MediaPlaylistAgent.REPEAT_MODE_ONE:
-                    if (mCurrent != null && mCurrent != mEopPlayItem) {
-                        mPlayer.loopCurrent(true);
-                    }
-                    break;
-                case MediaPlaylistAgent.REPEAT_MODE_ALL:
-                case MediaPlaylistAgent.REPEAT_MODE_GROUP:
-                    if (mCurrent == mEopPlayItem) {
-                        mCurrent = getNextValidPlayItemLocked(END_OF_PLAYLIST, 1);
-                        updatePlayerDataSourceLocked();
-                    }
-                    // pass through
-                case MediaPlaylistAgent.REPEAT_MODE_NONE:
-                    mPlayer.loopCurrent(false);
-                    break;
-            }
-        }
-        notifyRepeatModeChanged();
-    }
-
-    @Override
-    public int getShuffleMode() {
-        return mShuffleMode;
-    }
-
-    @Override
-    public void setShuffleMode(int shuffleMode) {
-        if (shuffleMode < MediaPlaylistAgent.SHUFFLE_MODE_NONE
-                || shuffleMode > MediaPlaylistAgent.SHUFFLE_MODE_GROUP) {
-            return;
-        }
-        synchronized (mLock) {
-            if (mShuffleMode == shuffleMode) {
-                return;
-            }
-            mShuffleMode = shuffleMode;
-            applyShuffleModeLocked();
-            updateCurrentIfNeededLocked();
-        }
-        notifyShuffleModeChanged();
-    }
-
-    @VisibleForTesting
-    int getCurShuffledIndex() {
-        return hasValidItem() ? mCurrent.shuffledIdx : NO_VALID_ITEMS;
-    }
-
-    private boolean hasValidItem() {
-        return mCurrent != null;
-    }
-
-    private DataSourceDesc retrieveDataSourceDescLocked(MediaItem2 item) {
-        DataSourceDesc dsd = item.getDataSourceDesc();
-        if (dsd != null) {
-            mItemDsdMap.put(item, dsd);
-            return dsd;
-        }
-        dsd = mItemDsdMap.get(item);
-        if (dsd != null) {
-            return dsd;
-        }
-        OnDataSourceMissingHelper helper = mDsmHelper;
-        if (helper != null) {
-            // TODO: Do not call onDataSourceMissing with the lock (b/74090741).
-            dsd = helper.onDataSourceMissing(mSessionImpl.getInstance(), item);
-            if (dsd != null) {
-                mItemDsdMap.put(item, dsd);
-            }
-        }
-        return dsd;
-    }
-
-    // TODO: consider to call updateCurrentIfNeededLocked inside (b/74090741)
-    private PlayItem getNextValidPlayItemLocked(int curShuffledIdx, int direction) {
-        int size = mPlaylist.size();
-        if (curShuffledIdx == END_OF_PLAYLIST) {
-            curShuffledIdx = (direction > 0) ? -1 : size;
-        }
-        for (int i = 0; i < size; i++) {
-            curShuffledIdx += direction;
-            if (curShuffledIdx < 0 || curShuffledIdx >= mPlaylist.size()) {
-                if (mRepeatMode == REPEAT_MODE_NONE) {
-                    return (i == size - 1) ? null : mEopPlayItem;
-                } else {
-                    curShuffledIdx = curShuffledIdx < 0 ? mPlaylist.size() - 1 : 0;
-                }
-            }
-            DataSourceDesc dsd = retrieveDataSourceDescLocked(mShuffledList.get(curShuffledIdx));
-            if (dsd != null) {
-                return new PlayItem(curShuffledIdx, dsd);
-            }
-        }
-        return null;
-    }
-
-    private void updateCurrentIfNeededLocked() {
-        if (!hasValidItem() || mCurrent.isValid()) {
-            return;
-        }
-        int shuffledIdx = mShuffledList.indexOf(mCurrent.mediaItem);
-        if (shuffledIdx >= 0) {
-            // Added an item.
-            mCurrent.shuffledIdx = shuffledIdx;
-            return;
-        }
-
-        if (mCurrent.shuffledIdx >= mShuffledList.size()) {
-            mCurrent = getNextValidPlayItemLocked(mShuffledList.size() - 1, 1);
-        } else {
-            mCurrent.mediaItem = mShuffledList.get(mCurrent.shuffledIdx);
-            if (retrieveDataSourceDescLocked(mCurrent.mediaItem) == null) {
-                mCurrent = getNextValidPlayItemLocked(mCurrent.shuffledIdx, 1);
-            }
-        }
-        updatePlayerDataSourceLocked();
-        return;
-    }
-
-    private void updatePlayerDataSourceLocked() {
-        if (mCurrent == null || mCurrent == mEopPlayItem) {
-            return;
-        }
-        if (mPlayer.getCurrentDataSource() != mCurrent.dsd) {
-            mPlayer.setDataSource(mCurrent.dsd);
-            mPlayer.loopCurrent(mRepeatMode == MediaPlaylistAgent.REPEAT_MODE_ONE);
-        }
-        // TODO: Call setNextDataSource (b/74090741)
-    }
-
-    private void applyShuffleModeLocked() {
-        mShuffledList.clear();
-        mShuffledList.addAll(mPlaylist);
-        if (mShuffleMode == MediaPlaylistAgent.SHUFFLE_MODE_ALL
-                || mShuffleMode == MediaPlaylistAgent.SHUFFLE_MODE_GROUP) {
-            Collections.shuffle(mShuffledList);
-        }
-    }
-
-    // Clamps value to [0, size]
-    private static int clamp(int value, int size) {
-        if (value < 0) {
-            return 0;
-        }
-        return (value > size) ? size : value;
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java b/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java
deleted file mode 100644
index a5cf8c4..0000000
--- a/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.media;
-
-import static android.media.SessionToken2.TYPE_SESSION;
-import static android.media.SessionToken2.TYPE_SESSION_SERVICE;
-import static android.media.SessionToken2.TYPE_LIBRARY_SERVICE;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ResolveInfo;
-import android.media.MediaLibraryService2;
-import android.media.MediaSessionService2;
-import android.media.SessionToken2;
-import android.media.SessionToken2.TokenType;
-import android.media.update.SessionToken2Provider;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.text.TextUtils;
-
-import java.util.List;
-
-public class SessionToken2Impl implements SessionToken2Provider {
-    private static final String KEY_UID = "android.media.token.uid";
-    private static final String KEY_TYPE = "android.media.token.type";
-    private static final String KEY_PACKAGE_NAME = "android.media.token.package_name";
-    private static final String KEY_SERVICE_NAME = "android.media.token.service_name";
-    private static final String KEY_ID = "android.media.token.id";
-    private static final String KEY_SESSION_BINDER = "android.media.token.session_binder";
-
-    private final SessionToken2 mInstance;
-    private final int mUid;
-    private final @TokenType int mType;
-    private final String mPackageName;
-    private final String mServiceName;
-    private final String mId;
-    private final IMediaSession2 mSessionBinder;
-
-    /**
-     * Public constructor for the legacy support (i.e. browser can try connecting to any browser
-     * service if it knows the service name)
-     */
-    public SessionToken2Impl(Context context, SessionToken2 instance,
-            String packageName, String serviceName, int uid) {
-        if (TextUtils.isEmpty(packageName)) {
-            throw new IllegalArgumentException("packageName shouldn't be empty");
-        }
-        if (TextUtils.isEmpty(serviceName)) {
-            throw new IllegalArgumentException("serviceName shouldn't be empty");
-        }
-        mInstance = instance;
-        // Calculate uid if it's not specified.
-        final PackageManager manager = context.getPackageManager();
-        if (uid < 0) {
-            try {
-                uid = manager.getPackageUid(packageName, 0);
-            } catch (NameNotFoundException e) {
-                throw new IllegalArgumentException("Cannot find package " + packageName);
-            }
-        }
-        mUid = uid;
-
-        // Infer id and type from package name and service name
-        // TODO(jaewan): Handle multi-user.
-        String id = getSessionIdFromService(manager, MediaLibraryService2.SERVICE_INTERFACE,
-                packageName, serviceName);
-        if (id != null) {
-            mId = id;
-            mType = TYPE_LIBRARY_SERVICE;
-        } else {
-            // retry with session service
-            mId = getSessionIdFromService(manager, MediaSessionService2.SERVICE_INTERFACE,
-                    packageName, serviceName);
-            mType = TYPE_SESSION_SERVICE;
-        }
-        if (mId == null) {
-            throw new IllegalArgumentException("service " + serviceName + " doesn't implement"
-                    + " session service nor library service. Use service's full name.");
-        }
-        mPackageName = packageName;
-        mServiceName = serviceName;
-        mSessionBinder = null;
-    }
-
-    SessionToken2Impl(int uid, int type, String packageName, String serviceName, String id,
-            IMediaSession2 sessionBinder) {
-        // TODO(jaewan): Add sanity check (b/73863865)
-        mUid = uid;
-        mType = type;
-        mPackageName = packageName;
-        mServiceName = serviceName;
-        mId = id;
-        mSessionBinder = sessionBinder;
-        mInstance = new SessionToken2(this);
-    }
-
-    private static String getSessionIdFromService(PackageManager manager, String serviceInterface,
-            String packageName, String serviceName) {
-        Intent serviceIntent = new Intent(serviceInterface);
-        serviceIntent.setPackage(packageName);
-        // Use queryIntentServices to find services with MediaLibraryService2.SERVICE_INTERFACE.
-        // We cannot use resolveService with intent specified class name, because resolveService
-        // ignores actions if Intent.setClassName() is specified.
-        List<ResolveInfo> list = manager.queryIntentServices(
-                serviceIntent, PackageManager.GET_META_DATA);
-        if (list != null) {
-            for (int i = 0; i < list.size(); i++) {
-                ResolveInfo resolveInfo = list.get(i);
-                if (resolveInfo == null || resolveInfo.serviceInfo == null) {
-                    continue;
-                }
-                if (TextUtils.equals(resolveInfo.serviceInfo.name, serviceName)) {
-                    return getSessionId(resolveInfo);
-                }
-            }
-        }
-        return null;
-    }
-
-    public static String getSessionId(ResolveInfo resolveInfo) {
-        if (resolveInfo == null || resolveInfo.serviceInfo == null) {
-            return null;
-        } else if (resolveInfo.serviceInfo.metaData == null) {
-            return "";
-        } else {
-            return resolveInfo.serviceInfo.metaData.getString(
-                    MediaSessionService2.SERVICE_META_DATA, "");
-        }
-    }
-
-    public SessionToken2 getInstance() {
-        return mInstance;
-    }
-
-    @Override
-    public String getPackageName_impl() {
-        return mPackageName;
-    }
-
-    @Override
-    public int getUid_impl() {
-        return mUid;
-    }
-
-    @Override
-    public String getId_imp() {
-        return mId;
-    }
-
-    @Override
-    public int getType_impl() {
-        return mType;
-    }
-
-    String getServiceName() {
-        return mServiceName;
-    }
-
-    IMediaSession2 getSessionBinder() {
-        return mSessionBinder;
-    }
-
-    public static SessionToken2 fromBundle_impl(Bundle bundle) {
-        if (bundle == null) {
-            return null;
-        }
-        final int uid = bundle.getInt(KEY_UID);
-        final @TokenType int type = bundle.getInt(KEY_TYPE, -1);
-        final String packageName = bundle.getString(KEY_PACKAGE_NAME);
-        final String serviceName = bundle.getString(KEY_SERVICE_NAME);
-        final String id = bundle.getString(KEY_ID);
-        final IBinder sessionBinder = bundle.getBinder(KEY_SESSION_BINDER);
-
-        // Sanity check.
-        switch (type) {
-            case TYPE_SESSION:
-                if (sessionBinder == null) {
-                    throw new IllegalArgumentException("Unexpected sessionBinder for session,"
-                            + " binder=" + sessionBinder);
-                }
-                break;
-            case TYPE_SESSION_SERVICE:
-            case TYPE_LIBRARY_SERVICE:
-                if (TextUtils.isEmpty(serviceName)) {
-                    throw new IllegalArgumentException("Session service needs service name");
-                }
-                break;
-            default:
-                throw new IllegalArgumentException("Invalid type");
-        }
-        if (TextUtils.isEmpty(packageName) || id == null) {
-            throw new IllegalArgumentException("Package name nor ID cannot be null.");
-        }
-        return new SessionToken2Impl(uid, type, packageName, serviceName, id,
-                sessionBinder != null ? IMediaSession2.Stub.asInterface(sessionBinder) : null)
-                .getInstance();
-    }
-
-    @Override
-    public Bundle toBundle_impl() {
-        Bundle bundle = new Bundle();
-        bundle.putInt(KEY_UID, mUid);
-        bundle.putString(KEY_PACKAGE_NAME, mPackageName);
-        bundle.putString(KEY_SERVICE_NAME, mServiceName);
-        bundle.putString(KEY_ID, mId);
-        bundle.putInt(KEY_TYPE, mType);
-        bundle.putBinder(KEY_SESSION_BINDER,
-                mSessionBinder != null ? mSessionBinder.asBinder() : null);
-        return bundle;
-    }
-
-    @Override
-    public int hashCode_impl() {
-        final int prime = 31;
-        return mType
-                + prime * (mUid
-                + prime * (mPackageName.hashCode()
-                + prime * (mId.hashCode()
-                + prime * (mServiceName != null ? mServiceName.hashCode() : 0))));
-    }
-
-    @Override
-    public boolean equals_impl(Object obj) {
-        if (!(obj instanceof SessionToken2)) {
-            return false;
-        }
-        SessionToken2Impl other = from((SessionToken2) obj);
-        return mUid == other.mUid
-                && TextUtils.equals(mPackageName, other.mPackageName)
-                && TextUtils.equals(mServiceName, other.mServiceName)
-                && TextUtils.equals(mId, other.mId)
-                && mType == other.mType;
-    }
-
-    @Override
-    public String toString_impl() {
-        return "SessionToken {pkg=" + mPackageName + " id=" + mId + " type=" + mType
-                + " service=" + mServiceName + " binder=" + mSessionBinder + "}";
-    }
-
-    static SessionToken2Impl from(SessionToken2 token) {
-        return ((SessionToken2Impl) token.getProvider());
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/media/VolumeProvider2Impl.java b/packages/MediaComponents/src/com/android/media/VolumeProvider2Impl.java
deleted file mode 100644
index bf22e1b..0000000
--- a/packages/MediaComponents/src/com/android/media/VolumeProvider2Impl.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.media;
-
-import static android.media.VolumeProvider2.VOLUME_CONTROL_ABSOLUTE;
-import static android.media.VolumeProvider2.VOLUME_CONTROL_FIXED;
-import static android.media.VolumeProvider2.VOLUME_CONTROL_RELATIVE;
-
-import android.media.VolumeProvider2;
-import android.media.update.VolumeProvider2Provider;
-
-public class VolumeProvider2Impl implements VolumeProvider2Provider {
-    private final VolumeProvider2 mInstance;
-    private final int mControlType;
-    private final int mMaxVolume;
-
-    private int mCurrentVolume;
-    private Callback mCallback;
-
-    public VolumeProvider2Impl(VolumeProvider2 instance,
-            @VolumeProvider2.ControlType int controlType, int maxVolume, int currentVolume) {
-        if (controlType != VOLUME_CONTROL_FIXED && controlType != VOLUME_CONTROL_RELATIVE
-                && controlType != VOLUME_CONTROL_ABSOLUTE) {
-            throw new IllegalArgumentException("wrong controlType " + controlType);
-        }
-        if (maxVolume < 0 || currentVolume < 0) {
-            throw new IllegalArgumentException("volume shouldn't be negative"
-                    + ", maxVolume=" + maxVolume + ", currentVolume=" + currentVolume);
-        }
-        if (currentVolume > maxVolume) {
-            throw new IllegalArgumentException("currentVolume shouldn't be greater than maxVolume"
-                    + ", maxVolume=" + maxVolume + ", currentVolume=" + currentVolume);
-        }
-        mInstance = instance;
-        mControlType = controlType;
-        mMaxVolume = maxVolume;
-        mCurrentVolume = currentVolume;
-    }
-
-    @Override
-    public int getControlType_impl() {
-        return mControlType;
-    }
-
-    @Override
-    public int getMaxVolume_impl() {
-        return mMaxVolume;
-    }
-
-    @Override
-    public int getCurrentVolume_impl() {
-        return mCurrentVolume;
-    }
-
-    @Override
-    public void setCurrentVolume_impl(int currentVolume) {
-        if (currentVolume < 0) {
-            throw new IllegalArgumentException("currentVolume shouldn't be negative"
-                    + ", currentVolume=" + currentVolume);
-        }
-        mCurrentVolume = currentVolume;
-        if (mCallback != null) {
-            mCallback.onVolumeChanged(mInstance);
-        }
-    }
-
-    /**
-     * Sets a callback to receive volume changes.
-     */
-    public void setCallback(Callback callback) {
-        mCallback = callback;
-    }
-
-    /**
-     * Listens for changes to the volume.
-     */
-    public static abstract class Callback {
-        public abstract void onVolumeChanged(VolumeProvider2 volumeProvider);
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/media/subtitle/ClosedCaptionRenderer.java b/packages/MediaComponents/src/com/android/media/subtitle/ClosedCaptionRenderer.java
deleted file mode 100644
index ff7eec9..0000000
--- a/packages/MediaComponents/src/com/android/media/subtitle/ClosedCaptionRenderer.java
+++ /dev/null
@@ -1,1501 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.media.subtitle;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.Typeface;
-import android.media.MediaFormat;
-import android.text.Spannable;
-import android.text.SpannableStringBuilder;
-import android.text.TextPaint;
-import android.text.style.CharacterStyle;
-import android.text.style.StyleSpan;
-import android.text.style.UnderlineSpan;
-import android.text.style.UpdateAppearance;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.accessibility.CaptioningManager;
-import android.view.accessibility.CaptioningManager.CaptionStyle;
-import android.view.accessibility.CaptioningManager.CaptioningChangeListener;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Vector;
-
-// Note: This is forked from android.media.ClosedCaptionRenderer since P
-public class ClosedCaptionRenderer extends SubtitleController.Renderer {
-    private final Context mContext;
-    private Cea608CCWidget mCCWidget;
-
-    public ClosedCaptionRenderer(Context context) {
-        mContext = context;
-    }
-
-    @Override
-    public boolean supports(MediaFormat format) {
-        if (format.containsKey(MediaFormat.KEY_MIME)) {
-            String mimeType = format.getString(MediaFormat.KEY_MIME);
-            return MediaFormat.MIMETYPE_TEXT_CEA_608.equals(mimeType);
-        }
-        return false;
-    }
-
-    @Override
-    public SubtitleTrack createTrack(MediaFormat format) {
-        String mimeType = format.getString(MediaFormat.KEY_MIME);
-        if (MediaFormat.MIMETYPE_TEXT_CEA_608.equals(mimeType)) {
-            if (mCCWidget == null) {
-                mCCWidget = new Cea608CCWidget(mContext);
-            }
-            return new Cea608CaptionTrack(mCCWidget, format);
-        }
-        throw new RuntimeException("No matching format: " + format.toString());
-    }
-}
-
-class Cea608CaptionTrack extends SubtitleTrack {
-    private final Cea608CCParser mCCParser;
-    private final Cea608CCWidget mRenderingWidget;
-
-    Cea608CaptionTrack(Cea608CCWidget renderingWidget, MediaFormat format) {
-        super(format);
-
-        mRenderingWidget = renderingWidget;
-        mCCParser = new Cea608CCParser(mRenderingWidget);
-    }
-
-    @Override
-    public void onData(byte[] data, boolean eos, long runID) {
-        mCCParser.parse(data);
-    }
-
-    @Override
-    public RenderingWidget getRenderingWidget() {
-        return mRenderingWidget;
-    }
-
-    @Override
-    public void updateView(Vector<Cue> activeCues) {
-        // Overriding with NO-OP, CC rendering by-passes this
-    }
-}
-
-/**
- * Abstract widget class to render a closed caption track.
- */
-abstract class ClosedCaptionWidget extends ViewGroup implements SubtitleTrack.RenderingWidget {
-
-    interface ClosedCaptionLayout {
-        void setCaptionStyle(CaptionStyle captionStyle);
-        void setFontScale(float scale);
-    }
-
-    private static final CaptionStyle DEFAULT_CAPTION_STYLE = CaptionStyle.DEFAULT;
-
-    /** Captioning manager, used to obtain and track caption properties. */
-    private final CaptioningManager mManager;
-
-    /** Current caption style. */
-    protected CaptionStyle mCaptionStyle;
-
-    /** Callback for rendering changes. */
-    protected OnChangedListener mListener;
-
-    /** Concrete layout of CC. */
-    protected ClosedCaptionLayout mClosedCaptionLayout;
-
-    /** Whether a caption style change listener is registered. */
-    private boolean mHasChangeListener;
-
-    public ClosedCaptionWidget(Context context) {
-        this(context, null);
-    }
-
-    public ClosedCaptionWidget(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public ClosedCaptionWidget(Context context, AttributeSet attrs, int defStyle) {
-        this(context, attrs, defStyle, 0);
-    }
-
-    public ClosedCaptionWidget(Context context, AttributeSet attrs, int defStyleAttr,
-            int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-
-        // Cannot render text over video when layer type is hardware.
-        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
-
-        mManager = (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);
-        mCaptionStyle = DEFAULT_CAPTION_STYLE.applyStyle(mManager.getUserStyle());
-
-        mClosedCaptionLayout = createCaptionLayout(context);
-        mClosedCaptionLayout.setCaptionStyle(mCaptionStyle);
-        mClosedCaptionLayout.setFontScale(mManager.getFontScale());
-        addView((ViewGroup) mClosedCaptionLayout, LayoutParams.MATCH_PARENT,
-                LayoutParams.MATCH_PARENT);
-
-        requestLayout();
-    }
-
-    public abstract ClosedCaptionLayout createCaptionLayout(Context context);
-
-    @Override
-    public void setOnChangedListener(OnChangedListener listener) {
-        mListener = listener;
-    }
-
-    @Override
-    public void setSize(int width, int height) {
-        final int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
-        final int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
-
-        measure(widthSpec, heightSpec);
-        layout(0, 0, width, height);
-    }
-
-    @Override
-    public void setVisible(boolean visible) {
-        if (visible) {
-            setVisibility(View.VISIBLE);
-        } else {
-            setVisibility(View.GONE);
-        }
-
-        manageChangeListener();
-    }
-
-    @Override
-    public void onAttachedToWindow() {
-        super.onAttachedToWindow();
-
-        manageChangeListener();
-    }
-
-    @Override
-    public void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-
-        manageChangeListener();
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        ((ViewGroup) mClosedCaptionLayout).measure(widthMeasureSpec, heightMeasureSpec);
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        ((ViewGroup) mClosedCaptionLayout).layout(l, t, r, b);
-    }
-
-    /**
-     * Manages whether this renderer is listening for caption style changes.
-     */
-    private final CaptioningChangeListener mCaptioningListener = new CaptioningChangeListener() {
-        @Override
-        public void onUserStyleChanged(CaptionStyle userStyle) {
-            mCaptionStyle = DEFAULT_CAPTION_STYLE.applyStyle(userStyle);
-            mClosedCaptionLayout.setCaptionStyle(mCaptionStyle);
-        }
-
-        @Override
-        public void onFontScaleChanged(float fontScale) {
-            mClosedCaptionLayout.setFontScale(fontScale);
-        }
-    };
-
-    private void manageChangeListener() {
-        final boolean needsListener = isAttachedToWindow() && getVisibility() == View.VISIBLE;
-        if (mHasChangeListener != needsListener) {
-            mHasChangeListener = needsListener;
-
-            if (needsListener) {
-                mManager.addCaptioningChangeListener(mCaptioningListener);
-            } else {
-                mManager.removeCaptioningChangeListener(mCaptioningListener);
-            }
-        }
-    }
-}
-
-/**
- * CCParser processes CEA-608 closed caption data.
- *
- * It calls back into OnDisplayChangedListener upon
- * display change with styled text for rendering.
- *
- */
-class Cea608CCParser {
-    public static final int MAX_ROWS = 15;
-    public static final int MAX_COLS = 32;
-
-    private static final String TAG = "Cea608CCParser";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    private static final int INVALID = -1;
-
-    // EIA-CEA-608: Table 70 - Control Codes
-    private static final int RCL = 0x20;
-    private static final int BS  = 0x21;
-    private static final int AOF = 0x22;
-    private static final int AON = 0x23;
-    private static final int DER = 0x24;
-    private static final int RU2 = 0x25;
-    private static final int RU3 = 0x26;
-    private static final int RU4 = 0x27;
-    private static final int FON = 0x28;
-    private static final int RDC = 0x29;
-    private static final int TR  = 0x2a;
-    private static final int RTD = 0x2b;
-    private static final int EDM = 0x2c;
-    private static final int CR  = 0x2d;
-    private static final int ENM = 0x2e;
-    private static final int EOC = 0x2f;
-
-    // Transparent Space
-    private static final char TS = '\u00A0';
-
-    // Captioning Modes
-    private static final int MODE_UNKNOWN = 0;
-    private static final int MODE_PAINT_ON = 1;
-    private static final int MODE_ROLL_UP = 2;
-    private static final int MODE_POP_ON = 3;
-    private static final int MODE_TEXT = 4;
-
-    private final DisplayListener mListener;
-
-    private int mMode = MODE_PAINT_ON;
-    private int mRollUpSize = 4;
-    private int mPrevCtrlCode = INVALID;
-
-    private CCMemory mDisplay = new CCMemory();
-    private CCMemory mNonDisplay = new CCMemory();
-    private CCMemory mTextMem = new CCMemory();
-
-    Cea608CCParser(DisplayListener listener) {
-        mListener = listener;
-    }
-
-    public void parse(byte[] data) {
-        CCData[] ccData = CCData.fromByteArray(data);
-
-        for (int i = 0; i < ccData.length; i++) {
-            if (DEBUG) {
-                Log.d(TAG, ccData[i].toString());
-            }
-
-            if (handleCtrlCode(ccData[i])
-                    || handleTabOffsets(ccData[i])
-                    || handlePACCode(ccData[i])
-                    || handleMidRowCode(ccData[i])) {
-                continue;
-            }
-
-            handleDisplayableChars(ccData[i]);
-        }
-    }
-
-    interface DisplayListener {
-        void onDisplayChanged(SpannableStringBuilder[] styledTexts);
-        CaptionStyle getCaptionStyle();
-    }
-
-    private CCMemory getMemory() {
-        // get the CC memory to operate on for current mode
-        switch (mMode) {
-        case MODE_POP_ON:
-            return mNonDisplay;
-        case MODE_TEXT:
-            // TODO(chz): support only caption mode for now,
-            // in text mode, dump everything to text mem.
-            return mTextMem;
-        case MODE_PAINT_ON:
-        case MODE_ROLL_UP:
-            return mDisplay;
-        default:
-            Log.w(TAG, "unrecoginized mode: " + mMode);
-        }
-        return mDisplay;
-    }
-
-    private boolean handleDisplayableChars(CCData ccData) {
-        if (!ccData.isDisplayableChar()) {
-            return false;
-        }
-
-        // Extended char includes 1 automatic backspace
-        if (ccData.isExtendedChar()) {
-            getMemory().bs();
-        }
-
-        getMemory().writeText(ccData.getDisplayText());
-
-        if (mMode == MODE_PAINT_ON || mMode == MODE_ROLL_UP) {
-            updateDisplay();
-        }
-
-        return true;
-    }
-
-    private boolean handleMidRowCode(CCData ccData) {
-        StyleCode m = ccData.getMidRow();
-        if (m != null) {
-            getMemory().writeMidRowCode(m);
-            return true;
-        }
-        return false;
-    }
-
-    private boolean handlePACCode(CCData ccData) {
-        PAC pac = ccData.getPAC();
-
-        if (pac != null) {
-            if (mMode == MODE_ROLL_UP) {
-                getMemory().moveBaselineTo(pac.getRow(), mRollUpSize);
-            }
-            getMemory().writePAC(pac);
-            return true;
-        }
-
-        return false;
-    }
-
-    private boolean handleTabOffsets(CCData ccData) {
-        int tabs = ccData.getTabOffset();
-
-        if (tabs > 0) {
-            getMemory().tab(tabs);
-            return true;
-        }
-
-        return false;
-    }
-
-    private boolean handleCtrlCode(CCData ccData) {
-        int ctrlCode = ccData.getCtrlCode();
-
-        if (mPrevCtrlCode != INVALID && mPrevCtrlCode == ctrlCode) {
-            // discard double ctrl codes (but if there's a 3rd one, we still take that)
-            mPrevCtrlCode = INVALID;
-            return true;
-        }
-
-        switch(ctrlCode) {
-        case RCL:
-            // select pop-on style
-            mMode = MODE_POP_ON;
-            break;
-        case BS:
-            getMemory().bs();
-            break;
-        case DER:
-            getMemory().der();
-            break;
-        case RU2:
-        case RU3:
-        case RU4:
-            mRollUpSize = (ctrlCode - 0x23);
-            // erase memory if currently in other style
-            if (mMode != MODE_ROLL_UP) {
-                mDisplay.erase();
-                mNonDisplay.erase();
-            }
-            // select roll-up style
-            mMode = MODE_ROLL_UP;
-            break;
-        case FON:
-            Log.i(TAG, "Flash On");
-            break;
-        case RDC:
-            // select paint-on style
-            mMode = MODE_PAINT_ON;
-            break;
-        case TR:
-            mMode = MODE_TEXT;
-            mTextMem.erase();
-            break;
-        case RTD:
-            mMode = MODE_TEXT;
-            break;
-        case EDM:
-            // erase display memory
-            mDisplay.erase();
-            updateDisplay();
-            break;
-        case CR:
-            if (mMode == MODE_ROLL_UP) {
-                getMemory().rollUp(mRollUpSize);
-            } else {
-                getMemory().cr();
-            }
-            if (mMode == MODE_ROLL_UP) {
-                updateDisplay();
-            }
-            break;
-        case ENM:
-            // erase non-display memory
-            mNonDisplay.erase();
-            break;
-        case EOC:
-            // swap display/non-display memory
-            swapMemory();
-            // switch to pop-on style
-            mMode = MODE_POP_ON;
-            updateDisplay();
-            break;
-        case INVALID:
-        default:
-            mPrevCtrlCode = INVALID;
-            return false;
-        }
-
-        mPrevCtrlCode = ctrlCode;
-
-        // handled
-        return true;
-    }
-
-    private void updateDisplay() {
-        if (mListener != null) {
-            CaptionStyle captionStyle = mListener.getCaptionStyle();
-            mListener.onDisplayChanged(mDisplay.getStyledText(captionStyle));
-        }
-    }
-
-    private void swapMemory() {
-        CCMemory temp = mDisplay;
-        mDisplay = mNonDisplay;
-        mNonDisplay = temp;
-    }
-
-    private static class StyleCode {
-        static final int COLOR_WHITE = 0;
-        static final int COLOR_GREEN = 1;
-        static final int COLOR_BLUE = 2;
-        static final int COLOR_CYAN = 3;
-        static final int COLOR_RED = 4;
-        static final int COLOR_YELLOW = 5;
-        static final int COLOR_MAGENTA = 6;
-        static final int COLOR_INVALID = 7;
-
-        static final int STYLE_ITALICS   = 0x00000001;
-        static final int STYLE_UNDERLINE = 0x00000002;
-
-        static final String[] mColorMap = {
-            "WHITE", "GREEN", "BLUE", "CYAN", "RED", "YELLOW", "MAGENTA", "INVALID"
-        };
-
-        final int mStyle;
-        final int mColor;
-
-        static StyleCode fromByte(byte data2) {
-            int style = 0;
-            int color = (data2 >> 1) & 0x7;
-
-            if ((data2 & 0x1) != 0) {
-                style |= STYLE_UNDERLINE;
-            }
-
-            if (color == COLOR_INVALID) {
-                // WHITE ITALICS
-                color = COLOR_WHITE;
-                style |= STYLE_ITALICS;
-            }
-
-            return new StyleCode(style, color);
-        }
-
-        StyleCode(int style, int color) {
-            mStyle = style;
-            mColor = color;
-        }
-
-        boolean isItalics() {
-            return (mStyle & STYLE_ITALICS) != 0;
-        }
-
-        boolean isUnderline() {
-            return (mStyle & STYLE_UNDERLINE) != 0;
-        }
-
-        int getColor() {
-            return mColor;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder str = new StringBuilder();
-            str.append("{");
-            str.append(mColorMap[mColor]);
-            if ((mStyle & STYLE_ITALICS) != 0) {
-                str.append(", ITALICS");
-            }
-            if ((mStyle & STYLE_UNDERLINE) != 0) {
-                str.append(", UNDERLINE");
-            }
-            str.append("}");
-
-            return str.toString();
-        }
-    }
-
-    private static class PAC extends StyleCode {
-        final int mRow;
-        final int mCol;
-
-        static PAC fromBytes(byte data1, byte data2) {
-            int[] rowTable = {11, 1, 3, 12, 14, 5, 7, 9};
-            int row = rowTable[data1 & 0x07] + ((data2 & 0x20) >> 5);
-            int style = 0;
-            if ((data2 & 1) != 0) {
-                style |= STYLE_UNDERLINE;
-            }
-            if ((data2 & 0x10) != 0) {
-                // indent code
-                int indent = (data2 >> 1) & 0x7;
-                return new PAC(row, indent * 4, style, COLOR_WHITE);
-            } else {
-                // style code
-                int color = (data2 >> 1) & 0x7;
-
-                if (color == COLOR_INVALID) {
-                    // WHITE ITALICS
-                    color = COLOR_WHITE;
-                    style |= STYLE_ITALICS;
-                }
-                return new PAC(row, -1, style, color);
-            }
-        }
-
-        PAC(int row, int col, int style, int color) {
-            super(style, color);
-            mRow = row;
-            mCol = col;
-        }
-
-        boolean isIndentPAC() {
-            return (mCol >= 0);
-        }
-
-        int getRow() {
-            return mRow;
-        }
-
-        int getCol() {
-            return mCol;
-        }
-
-        @Override
-        public String toString() {
-            return String.format("{%d, %d}, %s",
-                    mRow, mCol, super.toString());
-        }
-    }
-
-    /**
-     * Mutable version of BackgroundSpan to facilitate text rendering with edge styles.
-     */
-    public static class MutableBackgroundColorSpan extends CharacterStyle
-            implements UpdateAppearance {
-        private int mColor;
-
-        public MutableBackgroundColorSpan(int color) {
-            mColor = color;
-        }
-
-        public void setBackgroundColor(int color) {
-            mColor = color;
-        }
-
-        public int getBackgroundColor() {
-            return mColor;
-        }
-
-        @Override
-        public void updateDrawState(TextPaint ds) {
-            ds.bgColor = mColor;
-        }
-    }
-
-    /* CCLineBuilder keeps track of displayable chars, as well as
-     * MidRow styles and PACs, for a single line of CC memory.
-     *
-     * It generates styled text via getStyledText() method.
-     */
-    private static class CCLineBuilder {
-        private final StringBuilder mDisplayChars;
-        private final StyleCode[] mMidRowStyles;
-        private final StyleCode[] mPACStyles;
-
-        CCLineBuilder(String str) {
-            mDisplayChars = new StringBuilder(str);
-            mMidRowStyles = new StyleCode[mDisplayChars.length()];
-            mPACStyles = new StyleCode[mDisplayChars.length()];
-        }
-
-        void setCharAt(int index, char ch) {
-            mDisplayChars.setCharAt(index, ch);
-            mMidRowStyles[index] = null;
-        }
-
-        void setMidRowAt(int index, StyleCode m) {
-            mDisplayChars.setCharAt(index, ' ');
-            mMidRowStyles[index] = m;
-        }
-
-        void setPACAt(int index, PAC pac) {
-            mPACStyles[index] = pac;
-        }
-
-        char charAt(int index) {
-            return mDisplayChars.charAt(index);
-        }
-
-        int length() {
-            return mDisplayChars.length();
-        }
-
-        void applyStyleSpan(
-                SpannableStringBuilder styledText,
-                StyleCode s, int start, int end) {
-            if (s.isItalics()) {
-                styledText.setSpan(
-                        new StyleSpan(android.graphics.Typeface.ITALIC),
-                        start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-            }
-            if (s.isUnderline()) {
-                styledText.setSpan(
-                        new UnderlineSpan(),
-                        start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-            }
-        }
-
-        SpannableStringBuilder getStyledText(CaptionStyle captionStyle) {
-            SpannableStringBuilder styledText = new SpannableStringBuilder(mDisplayChars);
-            int start = -1, next = 0;
-            int styleStart = -1;
-            StyleCode curStyle = null;
-            while (next < mDisplayChars.length()) {
-                StyleCode newStyle = null;
-                if (mMidRowStyles[next] != null) {
-                    // apply mid-row style change
-                    newStyle = mMidRowStyles[next];
-                } else if (mPACStyles[next] != null
-                    && (styleStart < 0 || start < 0)) {
-                    // apply PAC style change, only if:
-                    // 1. no style set, or
-                    // 2. style set, but prev char is none-displayable
-                    newStyle = mPACStyles[next];
-                }
-                if (newStyle != null) {
-                    curStyle = newStyle;
-                    if (styleStart >= 0 && start >= 0) {
-                        applyStyleSpan(styledText, newStyle, styleStart, next);
-                    }
-                    styleStart = next;
-                }
-
-                if (mDisplayChars.charAt(next) != TS) {
-                    if (start < 0) {
-                        start = next;
-                    }
-                } else if (start >= 0) {
-                    int expandedStart = mDisplayChars.charAt(start) == ' ' ? start : start - 1;
-                    int expandedEnd = mDisplayChars.charAt(next - 1) == ' ' ? next : next + 1;
-                    styledText.setSpan(
-                            new MutableBackgroundColorSpan(captionStyle.backgroundColor),
-                            expandedStart, expandedEnd,
-                            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-                    if (styleStart >= 0) {
-                        applyStyleSpan(styledText, curStyle, styleStart, expandedEnd);
-                    }
-                    start = -1;
-                }
-                next++;
-            }
-
-            return styledText;
-        }
-    }
-
-    /*
-     * CCMemory models a console-style display.
-     */
-    private static class CCMemory {
-        private final String mBlankLine;
-        private final CCLineBuilder[] mLines = new CCLineBuilder[MAX_ROWS + 2];
-        private int mRow;
-        private int mCol;
-
-        CCMemory() {
-            char[] blank = new char[MAX_COLS + 2];
-            Arrays.fill(blank, TS);
-            mBlankLine = new String(blank);
-        }
-
-        void erase() {
-            // erase all lines
-            for (int i = 0; i < mLines.length; i++) {
-                mLines[i] = null;
-            }
-            mRow = MAX_ROWS;
-            mCol = 1;
-        }
-
-        void der() {
-            if (mLines[mRow] != null) {
-                for (int i = 0; i < mCol; i++) {
-                    if (mLines[mRow].charAt(i) != TS) {
-                        for (int j = mCol; j < mLines[mRow].length(); j++) {
-                            mLines[j].setCharAt(j, TS);
-                        }
-                        return;
-                    }
-                }
-                mLines[mRow] = null;
-            }
-        }
-
-        void tab(int tabs) {
-            moveCursorByCol(tabs);
-        }
-
-        void bs() {
-            moveCursorByCol(-1);
-            if (mLines[mRow] != null) {
-                mLines[mRow].setCharAt(mCol, TS);
-                if (mCol == MAX_COLS - 1) {
-                    // Spec recommendation:
-                    // if cursor was at col 32, move cursor
-                    // back to col 31 and erase both col 31&32
-                    mLines[mRow].setCharAt(MAX_COLS, TS);
-                }
-            }
-        }
-
-        void cr() {
-            moveCursorTo(mRow + 1, 1);
-        }
-
-        void rollUp(int windowSize) {
-            int i;
-            for (i = 0; i <= mRow - windowSize; i++) {
-                mLines[i] = null;
-            }
-            int startRow = mRow - windowSize + 1;
-            if (startRow < 1) {
-                startRow = 1;
-            }
-            for (i = startRow; i < mRow; i++) {
-                mLines[i] = mLines[i + 1];
-            }
-            for (i = mRow; i < mLines.length; i++) {
-                // clear base row
-                mLines[i] = null;
-            }
-            // default to col 1, in case PAC is not sent
-            mCol = 1;
-        }
-
-        void writeText(String text) {
-            for (int i = 0; i < text.length(); i++) {
-                getLineBuffer(mRow).setCharAt(mCol, text.charAt(i));
-                moveCursorByCol(1);
-            }
-        }
-
-        void writeMidRowCode(StyleCode m) {
-            getLineBuffer(mRow).setMidRowAt(mCol, m);
-            moveCursorByCol(1);
-        }
-
-        void writePAC(PAC pac) {
-            if (pac.isIndentPAC()) {
-                moveCursorTo(pac.getRow(), pac.getCol());
-            } else {
-                moveCursorTo(pac.getRow(), 1);
-            }
-            getLineBuffer(mRow).setPACAt(mCol, pac);
-        }
-
-        SpannableStringBuilder[] getStyledText(CaptionStyle captionStyle) {
-            ArrayList<SpannableStringBuilder> rows = new ArrayList<>(MAX_ROWS);
-            for (int i = 1; i <= MAX_ROWS; i++) {
-                rows.add(mLines[i] != null ?
-                        mLines[i].getStyledText(captionStyle) : null);
-            }
-            return rows.toArray(new SpannableStringBuilder[MAX_ROWS]);
-        }
-
-        private static int clamp(int x, int min, int max) {
-            return x < min ? min : (x > max ? max : x);
-        }
-
-        private void moveCursorTo(int row, int col) {
-            mRow = clamp(row, 1, MAX_ROWS);
-            mCol = clamp(col, 1, MAX_COLS);
-        }
-
-        private void moveCursorToRow(int row) {
-            mRow = clamp(row, 1, MAX_ROWS);
-        }
-
-        private void moveCursorByCol(int col) {
-            mCol = clamp(mCol + col, 1, MAX_COLS);
-        }
-
-        private void moveBaselineTo(int baseRow, int windowSize) {
-            if (mRow == baseRow) {
-                return;
-            }
-            int actualWindowSize = windowSize;
-            if (baseRow < actualWindowSize) {
-                actualWindowSize = baseRow;
-            }
-            if (mRow < actualWindowSize) {
-                actualWindowSize = mRow;
-            }
-
-            int i;
-            if (baseRow < mRow) {
-                // copy from bottom to top row
-                for (i = actualWindowSize - 1; i >= 0; i--) {
-                    mLines[baseRow - i] = mLines[mRow - i];
-                }
-            } else {
-                // copy from top to bottom row
-                for (i = 0; i < actualWindowSize; i++) {
-                    mLines[baseRow - i] = mLines[mRow - i];
-                }
-            }
-            // clear rest of the rows
-            for (i = 0; i <= baseRow - windowSize; i++) {
-                mLines[i] = null;
-            }
-            for (i = baseRow + 1; i < mLines.length; i++) {
-                mLines[i] = null;
-            }
-        }
-
-        private CCLineBuilder getLineBuffer(int row) {
-            if (mLines[row] == null) {
-                mLines[row] = new CCLineBuilder(mBlankLine);
-            }
-            return mLines[row];
-        }
-    }
-
-    /*
-     * CCData parses the raw CC byte pair into displayable chars,
-     * misc control codes, Mid-Row or Preamble Address Codes.
-     */
-    private static class CCData {
-        private final byte mType;
-        private final byte mData1;
-        private final byte mData2;
-
-        private static final String[] mCtrlCodeMap = {
-            "RCL", "BS" , "AOF", "AON",
-            "DER", "RU2", "RU3", "RU4",
-            "FON", "RDC", "TR" , "RTD",
-            "EDM", "CR" , "ENM", "EOC",
-        };
-
-        private static final String[] mSpecialCharMap = {
-            "\u00AE",
-            "\u00B0",
-            "\u00BD",
-            "\u00BF",
-            "\u2122",
-            "\u00A2",
-            "\u00A3",
-            "\u266A", // Eighth note
-            "\u00E0",
-            "\u00A0", // Transparent space
-            "\u00E8",
-            "\u00E2",
-            "\u00EA",
-            "\u00EE",
-            "\u00F4",
-            "\u00FB",
-        };
-
-        private static final String[] mSpanishCharMap = {
-            // Spanish and misc chars
-            "\u00C1", // A
-            "\u00C9", // E
-            "\u00D3", // I
-            "\u00DA", // O
-            "\u00DC", // U
-            "\u00FC", // u
-            "\u2018", // opening single quote
-            "\u00A1", // inverted exclamation mark
-            "*",
-            "'",
-            "\u2014", // em dash
-            "\u00A9", // Copyright
-            "\u2120", // Servicemark
-            "\u2022", // round bullet
-            "\u201C", // opening double quote
-            "\u201D", // closing double quote
-            // French
-            "\u00C0",
-            "\u00C2",
-            "\u00C7",
-            "\u00C8",
-            "\u00CA",
-            "\u00CB",
-            "\u00EB",
-            "\u00CE",
-            "\u00CF",
-            "\u00EF",
-            "\u00D4",
-            "\u00D9",
-            "\u00F9",
-            "\u00DB",
-            "\u00AB",
-            "\u00BB"
-        };
-
-        private static final String[] mProtugueseCharMap = {
-            // Portuguese
-            "\u00C3",
-            "\u00E3",
-            "\u00CD",
-            "\u00CC",
-            "\u00EC",
-            "\u00D2",
-            "\u00F2",
-            "\u00D5",
-            "\u00F5",
-            "{",
-            "}",
-            "\\",
-            "^",
-            "_",
-            "|",
-            "~",
-            // German and misc chars
-            "\u00C4",
-            "\u00E4",
-            "\u00D6",
-            "\u00F6",
-            "\u00DF",
-            "\u00A5",
-            "\u00A4",
-            "\u2502", // vertical bar
-            "\u00C5",
-            "\u00E5",
-            "\u00D8",
-            "\u00F8",
-            "\u250C", // top-left corner
-            "\u2510", // top-right corner
-            "\u2514", // lower-left corner
-            "\u2518", // lower-right corner
-        };
-
-        static CCData[] fromByteArray(byte[] data) {
-            CCData[] ccData = new CCData[data.length / 3];
-
-            for (int i = 0; i < ccData.length; i++) {
-                ccData[i] = new CCData(
-                        data[i * 3],
-                        data[i * 3 + 1],
-                        data[i * 3 + 2]);
-            }
-
-            return ccData;
-        }
-
-        CCData(byte type, byte data1, byte data2) {
-            mType = type;
-            mData1 = data1;
-            mData2 = data2;
-        }
-
-        int getCtrlCode() {
-            if ((mData1 == 0x14 || mData1 == 0x1c)
-                    && mData2 >= 0x20 && mData2 <= 0x2f) {
-                return mData2;
-            }
-            return INVALID;
-        }
-
-        StyleCode getMidRow() {
-            // only support standard Mid-row codes, ignore
-            // optional background/foreground mid-row codes
-            if ((mData1 == 0x11 || mData1 == 0x19)
-                    && mData2 >= 0x20 && mData2 <= 0x2f) {
-                return StyleCode.fromByte(mData2);
-            }
-            return null;
-        }
-
-        PAC getPAC() {
-            if ((mData1 & 0x70) == 0x10
-                    && (mData2 & 0x40) == 0x40
-                    && ((mData1 & 0x07) != 0 || (mData2 & 0x20) == 0)) {
-                return PAC.fromBytes(mData1, mData2);
-            }
-            return null;
-        }
-
-        int getTabOffset() {
-            if ((mData1 == 0x17 || mData1 == 0x1f)
-                    && mData2 >= 0x21 && mData2 <= 0x23) {
-                return mData2 & 0x3;
-            }
-            return 0;
-        }
-
-        boolean isDisplayableChar() {
-            return isBasicChar() || isSpecialChar() || isExtendedChar();
-        }
-
-        String getDisplayText() {
-            String str = getBasicChars();
-
-            if (str == null) {
-                str =  getSpecialChar();
-
-                if (str == null) {
-                    str = getExtendedChar();
-                }
-            }
-
-            return str;
-        }
-
-        private String ctrlCodeToString(int ctrlCode) {
-            return mCtrlCodeMap[ctrlCode - 0x20];
-        }
-
-        private boolean isBasicChar() {
-            return mData1 >= 0x20 && mData1 <= 0x7f;
-        }
-
-        private boolean isSpecialChar() {
-            return ((mData1 == 0x11 || mData1 == 0x19)
-                    && mData2 >= 0x30 && mData2 <= 0x3f);
-        }
-
-        private boolean isExtendedChar() {
-            return ((mData1 == 0x12 || mData1 == 0x1A
-                    || mData1 == 0x13 || mData1 == 0x1B)
-                    && mData2 >= 0x20 && mData2 <= 0x3f);
-        }
-
-        private char getBasicChar(byte data) {
-            char c;
-            // replace the non-ASCII ones
-            switch (data) {
-                case 0x2A: c = '\u00E1'; break;
-                case 0x5C: c = '\u00E9'; break;
-                case 0x5E: c = '\u00ED'; break;
-                case 0x5F: c = '\u00F3'; break;
-                case 0x60: c = '\u00FA'; break;
-                case 0x7B: c = '\u00E7'; break;
-                case 0x7C: c = '\u00F7'; break;
-                case 0x7D: c = '\u00D1'; break;
-                case 0x7E: c = '\u00F1'; break;
-                case 0x7F: c = '\u2588'; break; // Full block
-                default: c = (char) data; break;
-            }
-            return c;
-        }
-
-        private String getBasicChars() {
-            if (mData1 >= 0x20 && mData1 <= 0x7f) {
-                StringBuilder builder = new StringBuilder(2);
-                builder.append(getBasicChar(mData1));
-                if (mData2 >= 0x20 && mData2 <= 0x7f) {
-                    builder.append(getBasicChar(mData2));
-                }
-                return builder.toString();
-            }
-
-            return null;
-        }
-
-        private String getSpecialChar() {
-            if ((mData1 == 0x11 || mData1 == 0x19)
-                    && mData2 >= 0x30 && mData2 <= 0x3f) {
-                return mSpecialCharMap[mData2 - 0x30];
-            }
-
-            return null;
-        }
-
-        private String getExtendedChar() {
-            if ((mData1 == 0x12 || mData1 == 0x1A)
-                    && mData2 >= 0x20 && mData2 <= 0x3f){
-                // 1 Spanish/French char
-                return mSpanishCharMap[mData2 - 0x20];
-            } else if ((mData1 == 0x13 || mData1 == 0x1B)
-                    && mData2 >= 0x20 && mData2 <= 0x3f){
-                // 1 Portuguese/German/Danish char
-                return mProtugueseCharMap[mData2 - 0x20];
-            }
-
-            return null;
-        }
-
-        @Override
-        public String toString() {
-            String str;
-
-            if (mData1 < 0x10 && mData2 < 0x10) {
-                // Null Pad, ignore
-                return String.format("[%d]Null: %02x %02x", mType, mData1, mData2);
-            }
-
-            int ctrlCode = getCtrlCode();
-            if (ctrlCode != INVALID) {
-                return String.format("[%d]%s", mType, ctrlCodeToString(ctrlCode));
-            }
-
-            int tabOffset = getTabOffset();
-            if (tabOffset > 0) {
-                return String.format("[%d]Tab%d", mType, tabOffset);
-            }
-
-            PAC pac = getPAC();
-            if (pac != null) {
-                return String.format("[%d]PAC: %s", mType, pac.toString());
-            }
-
-            StyleCode m = getMidRow();
-            if (m != null) {
-                return String.format("[%d]Mid-row: %s", mType, m.toString());
-            }
-
-            if (isDisplayableChar()) {
-                return String.format("[%d]Displayable: %s (%02x %02x)",
-                        mType, getDisplayText(), mData1, mData2);
-            }
-
-            return String.format("[%d]Invalid: %02x %02x", mType, mData1, mData2);
-        }
-    }
-}
-
-/**
- * Widget capable of rendering CEA-608 closed captions.
- */
-class Cea608CCWidget extends ClosedCaptionWidget implements Cea608CCParser.DisplayListener {
-    private static final Rect mTextBounds = new Rect();
-    private static final String mDummyText = "1234567890123456789012345678901234";
-
-    public Cea608CCWidget(Context context) {
-        this(context, null);
-    }
-
-    public Cea608CCWidget(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public Cea608CCWidget(Context context, AttributeSet attrs, int defStyle) {
-        this(context, attrs, defStyle, 0);
-    }
-
-    public Cea608CCWidget(Context context, AttributeSet attrs, int defStyleAttr,
-            int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    @Override
-    public ClosedCaptionLayout createCaptionLayout(Context context) {
-        return new CCLayout(context);
-    }
-
-    @Override
-    public void onDisplayChanged(SpannableStringBuilder[] styledTexts) {
-        ((CCLayout) mClosedCaptionLayout).update(styledTexts);
-
-        if (mListener != null) {
-            mListener.onChanged(this);
-        }
-    }
-
-    @Override
-    public CaptionStyle getCaptionStyle() {
-        return mCaptionStyle;
-    }
-
-    private static class CCLineBox extends TextView {
-        private static final float FONT_PADDING_RATIO = 0.75f;
-        private static final float EDGE_OUTLINE_RATIO = 0.1f;
-        private static final float EDGE_SHADOW_RATIO = 0.05f;
-        private float mOutlineWidth;
-        private float mShadowRadius;
-        private float mShadowOffset;
-
-        private int mTextColor = Color.WHITE;
-        private int mBgColor = Color.BLACK;
-        private int mEdgeType = CaptionStyle.EDGE_TYPE_NONE;
-        private int mEdgeColor = Color.TRANSPARENT;
-
-        CCLineBox(Context context) {
-            super(context);
-            setGravity(Gravity.CENTER);
-            setBackgroundColor(Color.TRANSPARENT);
-            setTextColor(Color.WHITE);
-            setTypeface(Typeface.MONOSPACE);
-            setVisibility(View.INVISIBLE);
-
-            final Resources res = getContext().getResources();
-
-            // get the default (will be updated later during measure)
-            mOutlineWidth = res.getDimensionPixelSize(
-                    com.android.internal.R.dimen.subtitle_outline_width);
-            mShadowRadius = res.getDimensionPixelSize(
-                    com.android.internal.R.dimen.subtitle_shadow_radius);
-            mShadowOffset = res.getDimensionPixelSize(
-                    com.android.internal.R.dimen.subtitle_shadow_offset);
-        }
-
-        void setCaptionStyle(CaptionStyle captionStyle) {
-            mTextColor = captionStyle.foregroundColor;
-            mBgColor = captionStyle.backgroundColor;
-            mEdgeType = captionStyle.edgeType;
-            mEdgeColor = captionStyle.edgeColor;
-
-            setTextColor(mTextColor);
-            if (mEdgeType == CaptionStyle.EDGE_TYPE_DROP_SHADOW) {
-                setShadowLayer(mShadowRadius, mShadowOffset, mShadowOffset, mEdgeColor);
-            } else {
-                setShadowLayer(0, 0, 0, 0);
-            }
-            invalidate();
-        }
-
-        @Override
-        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-            float fontSize = MeasureSpec.getSize(heightMeasureSpec) * FONT_PADDING_RATIO;
-            setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize);
-
-            mOutlineWidth = EDGE_OUTLINE_RATIO * fontSize + 1.0f;
-            mShadowRadius = EDGE_SHADOW_RATIO * fontSize + 1.0f;;
-            mShadowOffset = mShadowRadius;
-
-            // set font scale in the X direction to match the required width
-            setScaleX(1.0f);
-            getPaint().getTextBounds(mDummyText, 0, mDummyText.length(), mTextBounds);
-            float actualTextWidth = mTextBounds.width();
-            float requiredTextWidth = MeasureSpec.getSize(widthMeasureSpec);
-            setScaleX(requiredTextWidth / actualTextWidth);
-
-            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        }
-
-        @Override
-        protected void onDraw(Canvas c) {
-            if (mEdgeType == CaptionStyle.EDGE_TYPE_UNSPECIFIED
-                    || mEdgeType == CaptionStyle.EDGE_TYPE_NONE
-                    || mEdgeType == CaptionStyle.EDGE_TYPE_DROP_SHADOW) {
-                // these edge styles don't require a second pass
-                super.onDraw(c);
-                return;
-            }
-
-            if (mEdgeType == CaptionStyle.EDGE_TYPE_OUTLINE) {
-                drawEdgeOutline(c);
-            } else {
-                // Raised or depressed
-                drawEdgeRaisedOrDepressed(c);
-            }
-        }
-
-        private void drawEdgeOutline(Canvas c) {
-            TextPaint textPaint = getPaint();
-
-            Paint.Style previousStyle = textPaint.getStyle();
-            Paint.Join previousJoin = textPaint.getStrokeJoin();
-            float previousWidth = textPaint.getStrokeWidth();
-
-            setTextColor(mEdgeColor);
-            textPaint.setStyle(Paint.Style.FILL_AND_STROKE);
-            textPaint.setStrokeJoin(Paint.Join.ROUND);
-            textPaint.setStrokeWidth(mOutlineWidth);
-
-            // Draw outline and background only.
-            super.onDraw(c);
-
-            // Restore original settings.
-            setTextColor(mTextColor);
-            textPaint.setStyle(previousStyle);
-            textPaint.setStrokeJoin(previousJoin);
-            textPaint.setStrokeWidth(previousWidth);
-
-            // Remove the background.
-            setBackgroundSpans(Color.TRANSPARENT);
-            // Draw foreground only.
-            super.onDraw(c);
-            // Restore the background.
-            setBackgroundSpans(mBgColor);
-        }
-
-        private void drawEdgeRaisedOrDepressed(Canvas c) {
-            TextPaint textPaint = getPaint();
-
-            Paint.Style previousStyle = textPaint.getStyle();
-            textPaint.setStyle(Paint.Style.FILL);
-
-            final boolean raised = mEdgeType == CaptionStyle.EDGE_TYPE_RAISED;
-            final int colorUp = raised ? Color.WHITE : mEdgeColor;
-            final int colorDown = raised ? mEdgeColor : Color.WHITE;
-            final float offset = mShadowRadius / 2f;
-
-            // Draw background and text with shadow up
-            setShadowLayer(mShadowRadius, -offset, -offset, colorUp);
-            super.onDraw(c);
-
-            // Remove the background.
-            setBackgroundSpans(Color.TRANSPARENT);
-
-            // Draw text with shadow down
-            setShadowLayer(mShadowRadius, +offset, +offset, colorDown);
-            super.onDraw(c);
-
-            // Restore settings
-            textPaint.setStyle(previousStyle);
-
-            // Restore the background.
-            setBackgroundSpans(mBgColor);
-        }
-
-        private void setBackgroundSpans(int color) {
-            CharSequence text = getText();
-            if (text instanceof Spannable) {
-                Spannable spannable = (Spannable) text;
-                Cea608CCParser.MutableBackgroundColorSpan[] bgSpans = spannable.getSpans(
-                        0, spannable.length(), Cea608CCParser.MutableBackgroundColorSpan.class);
-                for (int i = 0; i < bgSpans.length; i++) {
-                    bgSpans[i].setBackgroundColor(color);
-                }
-            }
-        }
-    }
-
-    private static class CCLayout extends LinearLayout implements ClosedCaptionLayout {
-        private static final int MAX_ROWS = Cea608CCParser.MAX_ROWS;
-        private static final float SAFE_AREA_RATIO = 0.9f;
-
-        private final CCLineBox[] mLineBoxes = new CCLineBox[MAX_ROWS];
-
-        CCLayout(Context context) {
-            super(context);
-            setGravity(Gravity.START);
-            setOrientation(LinearLayout.VERTICAL);
-            for (int i = 0; i < MAX_ROWS; i++) {
-                mLineBoxes[i] = new CCLineBox(getContext());
-                addView(mLineBoxes[i], LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
-            }
-        }
-
-        @Override
-        public void setCaptionStyle(CaptionStyle captionStyle) {
-            for (int i = 0; i < MAX_ROWS; i++) {
-                mLineBoxes[i].setCaptionStyle(captionStyle);
-            }
-        }
-
-        @Override
-        public void setFontScale(float fontScale) {
-            // Ignores the font scale changes of the system wide CC preference.
-        }
-
-        void update(SpannableStringBuilder[] textBuffer) {
-            for (int i = 0; i < MAX_ROWS; i++) {
-                if (textBuffer[i] != null) {
-                    mLineBoxes[i].setText(textBuffer[i], TextView.BufferType.SPANNABLE);
-                    mLineBoxes[i].setVisibility(View.VISIBLE);
-                } else {
-                    mLineBoxes[i].setVisibility(View.INVISIBLE);
-                }
-            }
-        }
-
-        @Override
-        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-
-            int safeWidth = getMeasuredWidth();
-            int safeHeight = getMeasuredHeight();
-
-            // CEA-608 assumes 4:3 video
-            if (safeWidth * 3 >= safeHeight * 4) {
-                safeWidth = safeHeight * 4 / 3;
-            } else {
-                safeHeight = safeWidth * 3 / 4;
-            }
-            safeWidth *= SAFE_AREA_RATIO;
-            safeHeight *= SAFE_AREA_RATIO;
-
-            int lineHeight = safeHeight / MAX_ROWS;
-            int lineHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
-                    lineHeight, MeasureSpec.EXACTLY);
-            int lineWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
-                    safeWidth, MeasureSpec.EXACTLY);
-
-            for (int i = 0; i < MAX_ROWS; i++) {
-                mLineBoxes[i].measure(lineWidthMeasureSpec, lineHeightMeasureSpec);
-            }
-        }
-
-        @Override
-        protected void onLayout(boolean changed, int l, int t, int r, int b) {
-            // safe caption area
-            int viewPortWidth = r - l;
-            int viewPortHeight = b - t;
-            int safeWidth, safeHeight;
-            // CEA-608 assumes 4:3 video
-            if (viewPortWidth * 3 >= viewPortHeight * 4) {
-                safeWidth = viewPortHeight * 4 / 3;
-                safeHeight = viewPortHeight;
-            } else {
-                safeWidth = viewPortWidth;
-                safeHeight = viewPortWidth * 3 / 4;
-            }
-            safeWidth *= SAFE_AREA_RATIO;
-            safeHeight *= SAFE_AREA_RATIO;
-            int left = (viewPortWidth - safeWidth) / 2;
-            int top = (viewPortHeight - safeHeight) / 2;
-
-            for (int i = 0; i < MAX_ROWS; i++) {
-                mLineBoxes[i].layout(
-                        left,
-                        top + safeHeight * i / MAX_ROWS,
-                        left + safeWidth,
-                        top + safeHeight * (i + 1) / MAX_ROWS);
-            }
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/media/subtitle/MediaTimeProvider.java b/packages/MediaComponents/src/com/android/media/subtitle/MediaTimeProvider.java
deleted file mode 100644
index af36d7f..0000000
--- a/packages/MediaComponents/src/com/android/media/subtitle/MediaTimeProvider.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.media.subtitle;
-
-// Note: This is just copied from android.media.MediaTimeProvider.
-public interface MediaTimeProvider {
-    // we do not allow negative media time
-    /**
-     * Presentation time value if no timed event notification is requested.
-     */
-    public final static long NO_TIME = -1;
-
-    /**
-     * Cancels all previous notification request from this listener if any.  It
-     * registers the listener to get seek and stop notifications.  If timeUs is
-     * not negative, it also registers the listener for a timed event
-     * notification when the presentation time reaches (becomes greater) than
-     * the value specified.  This happens immediately if the current media time
-     * is larger than or equal to timeUs.
-     *
-     * @param timeUs presentation time to get timed event callback at (or
-     *               {@link #NO_TIME})
-     */
-    public void notifyAt(long timeUs, OnMediaTimeListener listener);
-
-    /**
-     * Cancels all previous notification request from this listener if any.  It
-     * registers the listener to get seek and stop notifications.  If the media
-     * is stopped, the listener will immediately receive a stop notification.
-     * Otherwise, it will receive a timed event notificaton.
-     */
-    public void scheduleUpdate(OnMediaTimeListener listener);
-
-    /**
-     * Cancels all previous notification request from this listener if any.
-     */
-    public void cancelNotifications(OnMediaTimeListener listener);
-
-    /**
-     * Get the current presentation time.
-     *
-     * @param precise   Whether getting a precise time is important. This is
-     *                  more costly.
-     * @param monotonic Whether returned time should be monotonic: that is,
-     *                  greater than or equal to the last returned time.  Don't
-     *                  always set this to true.  E.g. this has undesired
-     *                  consequences if the media is seeked between calls.
-     * @throws IllegalStateException if the media is not initialized
-     */
-    public long getCurrentTimeUs(boolean precise, boolean monotonic)
-            throws IllegalStateException;
-
-    public static interface OnMediaTimeListener {
-        /**
-         * Called when the registered time was reached naturally.
-         *
-         * @param timeUs current media time
-         */
-        void onTimedEvent(long timeUs);
-
-        /**
-         * Called when the media time changed due to seeking.
-         *
-         * @param timeUs current media time
-         */
-        void onSeek(long timeUs);
-
-        /**
-         * Called when the playback stopped.  This is not called on pause, only
-         * on full stop, at which point there is no further current media time.
-         */
-        void onStop();
-    }
-}
-
diff --git a/packages/MediaComponents/src/com/android/media/subtitle/SubtitleController.java b/packages/MediaComponents/src/com/android/media/subtitle/SubtitleController.java
deleted file mode 100644
index a4d55d7..0000000
--- a/packages/MediaComponents/src/com/android/media/subtitle/SubtitleController.java
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.media.subtitle;
-
-import java.util.Locale;
-import java.util.Vector;
-
-import android.content.Context;
-import android.media.MediaFormat;
-import android.media.MediaPlayer2;
-import android.media.MediaPlayer2.TrackInfo;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.view.accessibility.CaptioningManager;
-
-import com.android.media.subtitle.SubtitleTrack.RenderingWidget;
-
-// Note: This is forked from android.media.SubtitleController since P
-/**
- * The subtitle controller provides the architecture to display subtitles for a
- * media source.  It allows specifying which tracks to display, on which anchor
- * to display them, and also allows adding external, out-of-band subtitle tracks.
- */
-public class SubtitleController {
-    private MediaTimeProvider mTimeProvider;
-    private Vector<Renderer> mRenderers;
-    private Vector<SubtitleTrack> mTracks;
-    private SubtitleTrack mSelectedTrack;
-    private boolean mShowing;
-    private CaptioningManager mCaptioningManager;
-    private Handler mHandler;
-
-    private static final int WHAT_SHOW = 1;
-    private static final int WHAT_HIDE = 2;
-    private static final int WHAT_SELECT_TRACK = 3;
-    private static final int WHAT_SELECT_DEFAULT_TRACK = 4;
-
-    private final Handler.Callback mCallback = new Handler.Callback() {
-        @Override
-        public boolean handleMessage(Message msg) {
-            switch (msg.what) {
-            case WHAT_SHOW:
-                doShow();
-                return true;
-            case WHAT_HIDE:
-                doHide();
-                return true;
-            case WHAT_SELECT_TRACK:
-                doSelectTrack((SubtitleTrack)msg.obj);
-                return true;
-            case WHAT_SELECT_DEFAULT_TRACK:
-                doSelectDefaultTrack();
-                return true;
-            default:
-                return false;
-            }
-        }
-    };
-
-    private CaptioningManager.CaptioningChangeListener mCaptioningChangeListener =
-        new CaptioningManager.CaptioningChangeListener() {
-            @Override
-            public void onEnabledChanged(boolean enabled) {
-                selectDefaultTrack();
-            }
-
-            @Override
-            public void onLocaleChanged(Locale locale) {
-                selectDefaultTrack();
-            }
-        };
-
-    public SubtitleController(Context context) {
-        this(context, null, null);
-    }
-
-    /**
-     * Creates a subtitle controller for a media playback object that implements
-     * the MediaTimeProvider interface.
-     *
-     * @param timeProvider
-     */
-    public SubtitleController(
-            Context context,
-            MediaTimeProvider timeProvider,
-            Listener listener) {
-        mTimeProvider = timeProvider;
-        mListener = listener;
-
-        mRenderers = new Vector<Renderer>();
-        mShowing = false;
-        mTracks = new Vector<SubtitleTrack>();
-        mCaptioningManager =
-            (CaptioningManager)context.getSystemService(Context.CAPTIONING_SERVICE);
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        mCaptioningManager.removeCaptioningChangeListener(
-                mCaptioningChangeListener);
-        super.finalize();
-    }
-
-    /**
-     * @return the available subtitle tracks for this media. These include
-     * the tracks found by {@link MediaPlayer} as well as any tracks added
-     * manually via {@link #addTrack}.
-     */
-    public SubtitleTrack[] getTracks() {
-        synchronized(mTracks) {
-            SubtitleTrack[] tracks = new SubtitleTrack[mTracks.size()];
-            mTracks.toArray(tracks);
-            return tracks;
-        }
-    }
-
-    /**
-     * @return the currently selected subtitle track
-     */
-    public SubtitleTrack getSelectedTrack() {
-        return mSelectedTrack;
-    }
-
-    private RenderingWidget getRenderingWidget() {
-        if (mSelectedTrack == null) {
-            return null;
-        }
-        return mSelectedTrack.getRenderingWidget();
-    }
-
-    /**
-     * Selects a subtitle track.  As a result, this track will receive
-     * in-band data from the {@link MediaPlayer}.  However, this does
-     * not change the subtitle visibility.
-     *
-     * Should be called from the anchor's (UI) thread. {@see #Anchor.getSubtitleLooper}
-     *
-     * @param track The subtitle track to select.  This must be one of the
-     *              tracks in {@link #getTracks}.
-     * @return true if the track was successfully selected.
-     */
-    public boolean selectTrack(SubtitleTrack track) {
-        if (track != null && !mTracks.contains(track)) {
-            return false;
-        }
-
-        processOnAnchor(mHandler.obtainMessage(WHAT_SELECT_TRACK, track));
-        return true;
-    }
-
-    private void doSelectTrack(SubtitleTrack track) {
-        mTrackIsExplicit = true;
-        if (mSelectedTrack == track) {
-            return;
-        }
-
-        if (mSelectedTrack != null) {
-            mSelectedTrack.hide();
-            mSelectedTrack.setTimeProvider(null);
-        }
-
-        mSelectedTrack = track;
-        if (mAnchor != null) {
-            mAnchor.setSubtitleWidget(getRenderingWidget());
-        }
-
-        if (mSelectedTrack != null) {
-            mSelectedTrack.setTimeProvider(mTimeProvider);
-            mSelectedTrack.show();
-        }
-
-        if (mListener != null) {
-            mListener.onSubtitleTrackSelected(track);
-        }
-    }
-
-    /**
-     * @return the default subtitle track based on system preferences, or null,
-     * if no such track exists in this manager.
-     *
-     * Supports HLS-flags: AUTOSELECT, FORCED & DEFAULT.
-     *
-     * 1. If captioning is disabled, only consider FORCED tracks. Otherwise,
-     * consider all tracks, but prefer non-FORCED ones.
-     * 2. If user selected "Default" caption language:
-     *   a. If there is a considered track with DEFAULT=yes, returns that track
-     *      (favor the first one in the current language if there are more than
-     *      one default tracks, or the first in general if none of them are in
-     *      the current language).
-     *   b. Otherwise, if there is a track with AUTOSELECT=yes in the current
-     *      language, return that one.
-     *   c. If there are no default tracks, and no autoselectable tracks in the
-     *      current language, return null.
-     * 3. If there is a track with the caption language, select that one.  Prefer
-     * the one with AUTOSELECT=no.
-     *
-     * The default values for these flags are DEFAULT=no, AUTOSELECT=yes
-     * and FORCED=no.
-     */
-    public SubtitleTrack getDefaultTrack() {
-        SubtitleTrack bestTrack = null;
-        int bestScore = -1;
-
-        Locale selectedLocale = mCaptioningManager.getLocale();
-        Locale locale = selectedLocale;
-        if (locale == null) {
-            locale = Locale.getDefault();
-        }
-        boolean selectForced = !mCaptioningManager.isEnabled();
-
-        synchronized(mTracks) {
-            for (SubtitleTrack track: mTracks) {
-                MediaFormat format = track.getFormat();
-                String language = format.getString(MediaFormat.KEY_LANGUAGE);
-                boolean forced =
-                    format.getInteger(MediaFormat.KEY_IS_FORCED_SUBTITLE, 0) != 0;
-                boolean autoselect =
-                    format.getInteger(MediaFormat.KEY_IS_AUTOSELECT, 1) != 0;
-                boolean is_default =
-                    format.getInteger(MediaFormat.KEY_IS_DEFAULT, 0) != 0;
-
-                boolean languageMatches =
-                    (locale == null ||
-                    locale.getLanguage().equals("") ||
-                    locale.getISO3Language().equals(language) ||
-                    locale.getLanguage().equals(language));
-                // is_default is meaningless unless caption language is 'default'
-                int score = (forced ? 0 : 8) +
-                    (((selectedLocale == null) && is_default) ? 4 : 0) +
-                    (autoselect ? 0 : 2) + (languageMatches ? 1 : 0);
-
-                if (selectForced && !forced) {
-                    continue;
-                }
-
-                // we treat null locale/language as matching any language
-                if ((selectedLocale == null && is_default) ||
-                    (languageMatches &&
-                     (autoselect || forced || selectedLocale != null))) {
-                    if (score > bestScore) {
-                        bestScore = score;
-                        bestTrack = track;
-                    }
-                }
-            }
-        }
-        return bestTrack;
-    }
-
-    private boolean mTrackIsExplicit = false;
-    private boolean mVisibilityIsExplicit = false;
-
-    /** should be called from anchor thread */
-    public void selectDefaultTrack() {
-        processOnAnchor(mHandler.obtainMessage(WHAT_SELECT_DEFAULT_TRACK));
-    }
-
-    private void doSelectDefaultTrack() {
-        if (mTrackIsExplicit) {
-            // If track selection is explicit, but visibility
-            // is not, it falls back to the captioning setting
-            if (!mVisibilityIsExplicit) {
-                if (mCaptioningManager.isEnabled() ||
-                    (mSelectedTrack != null &&
-                     mSelectedTrack.getFormat().getInteger(
-                            MediaFormat.KEY_IS_FORCED_SUBTITLE, 0) != 0)) {
-                    show();
-                } else if (mSelectedTrack != null
-                        && mSelectedTrack.getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
-                    hide();
-                }
-                mVisibilityIsExplicit = false;
-            }
-            return;
-        }
-
-        // We can have a default (forced) track even if captioning
-        // is not enabled.  This is handled by getDefaultTrack().
-        // Show this track unless subtitles were explicitly hidden.
-        SubtitleTrack track = getDefaultTrack();
-        if (track != null) {
-            selectTrack(track);
-            mTrackIsExplicit = false;
-            if (!mVisibilityIsExplicit) {
-                show();
-                mVisibilityIsExplicit = false;
-            }
-        }
-    }
-
-    /** must be called from anchor thread */
-    public void reset() {
-        checkAnchorLooper();
-        hide();
-        selectTrack(null);
-        mTracks.clear();
-        mTrackIsExplicit = false;
-        mVisibilityIsExplicit = false;
-        mCaptioningManager.removeCaptioningChangeListener(
-                mCaptioningChangeListener);
-    }
-
-    /**
-     * Adds a new, external subtitle track to the manager.
-     *
-     * @param format the format of the track that will include at least
-     *               the MIME type {@link MediaFormat@KEY_MIME}.
-     * @return the created {@link SubtitleTrack} object
-     */
-    public SubtitleTrack addTrack(MediaFormat format) {
-        synchronized(mRenderers) {
-            for (Renderer renderer: mRenderers) {
-                if (renderer.supports(format)) {
-                    SubtitleTrack track = renderer.createTrack(format);
-                    if (track != null) {
-                        synchronized(mTracks) {
-                            if (mTracks.size() == 0) {
-                                mCaptioningManager.addCaptioningChangeListener(
-                                        mCaptioningChangeListener);
-                            }
-                            mTracks.add(track);
-                        }
-                        return track;
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Show the selected (or default) subtitle track.
-     *
-     * Should be called from the anchor's (UI) thread. {@see #Anchor.getSubtitleLooper}
-     */
-    public void show() {
-        processOnAnchor(mHandler.obtainMessage(WHAT_SHOW));
-    }
-
-    private void doShow() {
-        mShowing = true;
-        mVisibilityIsExplicit = true;
-        if (mSelectedTrack != null) {
-            mSelectedTrack.show();
-        }
-    }
-
-    /**
-     * Hide the selected (or default) subtitle track.
-     *
-     * Should be called from the anchor's (UI) thread. {@see #Anchor.getSubtitleLooper}
-     */
-    public void hide() {
-        processOnAnchor(mHandler.obtainMessage(WHAT_HIDE));
-    }
-
-    private void doHide() {
-        mVisibilityIsExplicit = true;
-        if (mSelectedTrack != null) {
-            mSelectedTrack.hide();
-        }
-        mShowing = false;
-    }
-
-    /**
-     * Interface for supporting a single or multiple subtitle types in {@link
-     * MediaPlayer}.
-     */
-    public abstract static class Renderer {
-        /**
-         * Called by {@link MediaPlayer}'s {@link SubtitleController} when a new
-         * subtitle track is detected, to see if it should use this object to
-         * parse and display this subtitle track.
-         *
-         * @param format the format of the track that will include at least
-         *               the MIME type {@link MediaFormat@KEY_MIME}.
-         *
-         * @return true if and only if the track format is supported by this
-         * renderer
-         */
-        public abstract boolean supports(MediaFormat format);
-
-        /**
-         * Called by {@link MediaPlayer}'s {@link SubtitleController} for each
-         * subtitle track that was detected and is supported by this object to
-         * create a {@link SubtitleTrack} object.  This object will be created
-         * for each track that was found.  If the track is selected for display,
-         * this object will be used to parse and display the track data.
-         *
-         * @param format the format of the track that will include at least
-         *               the MIME type {@link MediaFormat@KEY_MIME}.
-         * @return a {@link SubtitleTrack} object that will be used to parse
-         * and render the subtitle track.
-         */
-        public abstract SubtitleTrack createTrack(MediaFormat format);
-    }
-
-    /**
-     * Add support for a subtitle format in {@link MediaPlayer}.
-     *
-     * @param renderer a {@link SubtitleController.Renderer} object that adds
-     *                 support for a subtitle format.
-     */
-    public void registerRenderer(Renderer renderer) {
-        synchronized(mRenderers) {
-            // TODO how to get available renderers in the system
-            if (!mRenderers.contains(renderer)) {
-                // TODO should added renderers override existing ones (to allow replacing?)
-                mRenderers.add(renderer);
-            }
-        }
-    }
-
-    public boolean hasRendererFor(MediaFormat format) {
-        synchronized(mRenderers) {
-            // TODO how to get available renderers in the system
-            for (Renderer renderer: mRenderers) {
-                if (renderer.supports(format)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Subtitle anchor, an object that is able to display a subtitle renderer,
-     * e.g. a VideoView.
-     */
-    public interface Anchor {
-        /**
-         * Anchor should use the supplied subtitle rendering widget, or
-         * none if it is null.
-         */
-        public void setSubtitleWidget(RenderingWidget subtitleWidget);
-
-        /**
-         * Anchors provide the looper on which all track visibility changes
-         * (track.show/hide, setSubtitleWidget) will take place.
-         */
-        public Looper getSubtitleLooper();
-    }
-
-    private Anchor mAnchor;
-
-    /**
-     *  called from anchor's looper (if any, both when unsetting and
-     *  setting)
-     */
-    public void setAnchor(Anchor anchor) {
-        if (mAnchor == anchor) {
-            return;
-        }
-
-        if (mAnchor != null) {
-            checkAnchorLooper();
-            mAnchor.setSubtitleWidget(null);
-        }
-        mAnchor = anchor;
-        mHandler = null;
-        if (mAnchor != null) {
-            mHandler = new Handler(mAnchor.getSubtitleLooper(), mCallback);
-            checkAnchorLooper();
-            mAnchor.setSubtitleWidget(getRenderingWidget());
-        }
-    }
-
-    private void checkAnchorLooper() {
-        assert mHandler != null : "Should have a looper already";
-        assert Looper.myLooper() == mHandler.getLooper()
-                : "Must be called from the anchor's looper";
-    }
-
-    private void processOnAnchor(Message m) {
-        assert mHandler != null : "Should have a looper already";
-        if (Looper.myLooper() == mHandler.getLooper()) {
-            mHandler.dispatchMessage(m);
-        } else {
-            mHandler.sendMessage(m);
-        }
-    }
-
-    public interface Listener {
-        /**
-         * Called when a subtitle track has been selected.
-         *
-         * @param track selected subtitle track or null
-         */
-        public void onSubtitleTrackSelected(SubtitleTrack track);
-    }
-
-    private Listener mListener;
-}
diff --git a/packages/MediaComponents/src/com/android/media/subtitle/SubtitleTrack.java b/packages/MediaComponents/src/com/android/media/subtitle/SubtitleTrack.java
deleted file mode 100644
index 6b9064a..0000000
--- a/packages/MediaComponents/src/com/android/media/subtitle/SubtitleTrack.java
+++ /dev/null
@@ -1,696 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.media.subtitle;
-
-import android.graphics.Canvas;
-import android.media.MediaFormat;
-import android.media.MediaPlayer2.TrackInfo;
-import android.media.SubtitleData;
-import android.os.Handler;
-import android.util.Log;
-import android.util.LongSparseArray;
-import android.util.Pair;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import java.util.SortedMap;
-import java.util.TreeMap;
-import java.util.Vector;
-
-// Note: This is forked from android.media.SubtitleTrack since P
-/**
- * A subtitle track abstract base class that is responsible for parsing and displaying
- * an instance of a particular type of subtitle.
- */
-public abstract class SubtitleTrack implements MediaTimeProvider.OnMediaTimeListener {
-    private static final String TAG = "SubtitleTrack";
-    private long mLastUpdateTimeMs;
-    private long mLastTimeMs;
-
-    private Runnable mRunnable;
-
-    final private LongSparseArray<Run> mRunsByEndTime = new LongSparseArray<Run>();
-    final private LongSparseArray<Run> mRunsByID = new LongSparseArray<Run>();
-
-    private CueList mCues;
-    final private Vector<Cue> mActiveCues = new Vector<Cue>();
-    protected boolean mVisible;
-
-    public boolean DEBUG = false;
-
-    protected Handler mHandler = new Handler();
-
-    private MediaFormat mFormat;
-
-    public SubtitleTrack(MediaFormat format) {
-        mFormat = format;
-        mCues = new CueList();
-        clearActiveCues();
-        mLastTimeMs = -1;
-    }
-
-    public final MediaFormat getFormat() {
-        return mFormat;
-    }
-
-    private long mNextScheduledTimeMs = -1;
-
-    public void onData(SubtitleData data) {
-        long runID = data.getStartTimeUs() + 1;
-        onData(data.getData(), true /* eos */, runID);
-        setRunDiscardTimeMs(
-                runID,
-                (data.getStartTimeUs() + data.getDurationUs()) / 1000);
-    }
-
-    /**
-     * Called when there is input data for the subtitle track.  The
-     * complete subtitle for a track can include multiple whole units
-     * (runs).  Each of these units can have multiple sections.  The
-     * contents of a run are submitted in sequential order, with eos
-     * indicating the last section of the run.  Calls from different
-     * runs must not be intermixed.
-     *
-     * @param data subtitle data byte buffer
-     * @param eos true if this is the last section of the run.
-     * @param runID mostly-unique ID for this run of data.  Subtitle cues
-     *              with runID of 0 are discarded immediately after
-     *              display.  Cues with runID of ~0 are discarded
-     *              only at the deletion of the track object.  Cues
-     *              with other runID-s are discarded at the end of the
-     *              run, which defaults to the latest timestamp of
-     *              any of its cues (with this runID).
-     */
-    protected abstract void onData(byte[] data, boolean eos, long runID);
-
-    /**
-     * Called when adding the subtitle rendering widget to the view hierarchy,
-     * as well as when showing or hiding the subtitle track, or when the video
-     * surface position has changed.
-     *
-     * @return the widget that renders this subtitle track. For most renderers
-     *         there should be a single shared instance that is used for all
-     *         tracks supported by that renderer, as at most one subtitle track
-     *         is visible at one time.
-     */
-    public abstract RenderingWidget getRenderingWidget();
-
-    /**
-     * Called when the active cues have changed, and the contents of the subtitle
-     * view should be updated.
-     */
-    public abstract void updateView(Vector<Cue> activeCues);
-
-    protected synchronized void updateActiveCues(boolean rebuild, long timeMs) {
-        // out-of-order times mean seeking or new active cues being added
-        // (during their own timespan)
-        if (rebuild || mLastUpdateTimeMs > timeMs) {
-            clearActiveCues();
-        }
-
-        for(Iterator<Pair<Long, Cue> > it =
-                mCues.entriesBetween(mLastUpdateTimeMs, timeMs).iterator(); it.hasNext(); ) {
-            Pair<Long, Cue> event = it.next();
-            Cue cue = event.second;
-
-            if (cue.mEndTimeMs == event.first) {
-                // remove past cues
-                if (DEBUG) Log.v(TAG, "Removing " + cue);
-                mActiveCues.remove(cue);
-                if (cue.mRunID == 0) {
-                    it.remove();
-                }
-            } else if (cue.mStartTimeMs == event.first) {
-                // add new cues
-                // TRICKY: this will happen in start order
-                if (DEBUG) Log.v(TAG, "Adding " + cue);
-                if (cue.mInnerTimesMs != null) {
-                    cue.onTime(timeMs);
-                }
-                mActiveCues.add(cue);
-            } else if (cue.mInnerTimesMs != null) {
-                // cue is modified
-                cue.onTime(timeMs);
-            }
-        }
-
-        /* complete any runs */
-        while (mRunsByEndTime.size() > 0 &&
-               mRunsByEndTime.keyAt(0) <= timeMs) {
-            removeRunsByEndTimeIndex(0); // removes element
-        }
-        mLastUpdateTimeMs = timeMs;
-    }
-
-    private void removeRunsByEndTimeIndex(int ix) {
-        Run run = mRunsByEndTime.valueAt(ix);
-        while (run != null) {
-            Cue cue = run.mFirstCue;
-            while (cue != null) {
-                mCues.remove(cue);
-                Cue nextCue = cue.mNextInRun;
-                cue.mNextInRun = null;
-                cue = nextCue;
-            }
-            mRunsByID.remove(run.mRunID);
-            Run nextRun = run.mNextRunAtEndTimeMs;
-            run.mPrevRunAtEndTimeMs = null;
-            run.mNextRunAtEndTimeMs = null;
-            run = nextRun;
-        }
-        mRunsByEndTime.removeAt(ix);
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        /* remove all cues (untangle all cross-links) */
-        int size = mRunsByEndTime.size();
-        for(int ix = size - 1; ix >= 0; ix--) {
-            removeRunsByEndTimeIndex(ix);
-        }
-
-        super.finalize();
-    }
-
-    private synchronized void takeTime(long timeMs) {
-        mLastTimeMs = timeMs;
-    }
-
-    protected synchronized void clearActiveCues() {
-        if (DEBUG) Log.v(TAG, "Clearing " + mActiveCues.size() + " active cues");
-        mActiveCues.clear();
-        mLastUpdateTimeMs = -1;
-    }
-
-    protected void scheduleTimedEvents() {
-        /* get times for the next event */
-        if (mTimeProvider != null) {
-            mNextScheduledTimeMs = mCues.nextTimeAfter(mLastTimeMs);
-            if (DEBUG) Log.d(TAG, "sched @" + mNextScheduledTimeMs + " after " + mLastTimeMs);
-            mTimeProvider.notifyAt(
-                    mNextScheduledTimeMs >= 0 ?
-                        (mNextScheduledTimeMs * 1000) : MediaTimeProvider.NO_TIME,
-                    this);
-        }
-    }
-
-    @Override
-    public void onTimedEvent(long timeUs) {
-        if (DEBUG) Log.d(TAG, "onTimedEvent " + timeUs);
-        synchronized (this) {
-            long timeMs = timeUs / 1000;
-            updateActiveCues(false, timeMs);
-            takeTime(timeMs);
-        }
-        updateView(mActiveCues);
-        scheduleTimedEvents();
-    }
-
-    @Override
-    public void onSeek(long timeUs) {
-        if (DEBUG) Log.d(TAG, "onSeek " + timeUs);
-        synchronized (this) {
-            long timeMs = timeUs / 1000;
-            updateActiveCues(true, timeMs);
-            takeTime(timeMs);
-        }
-        updateView(mActiveCues);
-        scheduleTimedEvents();
-    }
-
-    @Override
-    public void onStop() {
-        synchronized (this) {
-            if (DEBUG) Log.d(TAG, "onStop");
-            clearActiveCues();
-            mLastTimeMs = -1;
-        }
-        updateView(mActiveCues);
-        mNextScheduledTimeMs = -1;
-        mTimeProvider.notifyAt(MediaTimeProvider.NO_TIME, this);
-    }
-
-    protected MediaTimeProvider mTimeProvider;
-
-    public void show() {
-        if (mVisible) {
-            return;
-        }
-
-        mVisible = true;
-        RenderingWidget renderingWidget = getRenderingWidget();
-        if (renderingWidget != null) {
-            renderingWidget.setVisible(true);
-        }
-        if (mTimeProvider != null) {
-            mTimeProvider.scheduleUpdate(this);
-        }
-    }
-
-    public void hide() {
-        if (!mVisible) {
-            return;
-        }
-
-        if (mTimeProvider != null) {
-            mTimeProvider.cancelNotifications(this);
-        }
-        RenderingWidget renderingWidget = getRenderingWidget();
-        if (renderingWidget != null) {
-            renderingWidget.setVisible(false);
-        }
-        mVisible = false;
-    }
-
-    protected synchronized boolean addCue(Cue cue) {
-        mCues.add(cue);
-
-        if (cue.mRunID != 0) {
-            Run run = mRunsByID.get(cue.mRunID);
-            if (run == null) {
-                run = new Run();
-                mRunsByID.put(cue.mRunID, run);
-                run.mEndTimeMs = cue.mEndTimeMs;
-            } else if (run.mEndTimeMs < cue.mEndTimeMs) {
-                run.mEndTimeMs = cue.mEndTimeMs;
-            }
-
-            // link-up cues in the same run
-            cue.mNextInRun = run.mFirstCue;
-            run.mFirstCue = cue;
-        }
-
-        // if a cue is added that should be visible, need to refresh view
-        long nowMs = -1;
-        if (mTimeProvider != null) {
-            try {
-                nowMs = mTimeProvider.getCurrentTimeUs(
-                        false /* precise */, true /* monotonic */) / 1000;
-            } catch (IllegalStateException e) {
-                // handle as it we are not playing
-            }
-        }
-
-        if (DEBUG) Log.v(TAG, "mVisible=" + mVisible + ", " +
-                cue.mStartTimeMs + " <= " + nowMs + ", " +
-                cue.mEndTimeMs + " >= " + mLastTimeMs);
-
-        if (mVisible &&
-                cue.mStartTimeMs <= nowMs &&
-                // we don't trust nowMs, so check any cue since last callback
-                cue.mEndTimeMs >= mLastTimeMs) {
-            if (mRunnable != null) {
-                mHandler.removeCallbacks(mRunnable);
-            }
-            final SubtitleTrack track = this;
-            final long thenMs = nowMs;
-            mRunnable = new Runnable() {
-                @Override
-                public void run() {
-                    // even with synchronized, it is possible that we are going
-                    // to do multiple updates as the runnable could be already
-                    // running.
-                    synchronized (track) {
-                        mRunnable = null;
-                        updateActiveCues(true, thenMs);
-                        updateView(mActiveCues);
-                    }
-                }
-            };
-            // delay update so we don't update view on every cue.  TODO why 10?
-            if (mHandler.postDelayed(mRunnable, 10 /* delay */)) {
-                if (DEBUG) Log.v(TAG, "scheduling update");
-            } else {
-                if (DEBUG) Log.w(TAG, "failed to schedule subtitle view update");
-            }
-            return true;
-        }
-
-        if (mVisible &&
-                cue.mEndTimeMs >= mLastTimeMs &&
-                (cue.mStartTimeMs < mNextScheduledTimeMs ||
-                 mNextScheduledTimeMs < 0)) {
-            scheduleTimedEvents();
-        }
-
-        return false;
-    }
-
-    public synchronized void setTimeProvider(MediaTimeProvider timeProvider) {
-        if (mTimeProvider == timeProvider) {
-            return;
-        }
-        if (mTimeProvider != null) {
-            mTimeProvider.cancelNotifications(this);
-        }
-        mTimeProvider = timeProvider;
-        if (mTimeProvider != null) {
-            mTimeProvider.scheduleUpdate(this);
-        }
-    }
-
-
-    static class CueList {
-        private static final String TAG = "CueList";
-        // simplistic, inefficient implementation
-        private SortedMap<Long, Vector<Cue> > mCues;
-        public boolean DEBUG = false;
-
-        private boolean addEvent(Cue cue, long timeMs) {
-            Vector<Cue> cues = mCues.get(timeMs);
-            if (cues == null) {
-                cues = new Vector<Cue>(2);
-                mCues.put(timeMs, cues);
-            } else if (cues.contains(cue)) {
-                // do not duplicate cues
-                return false;
-            }
-
-            cues.add(cue);
-            return true;
-        }
-
-        private void removeEvent(Cue cue, long timeMs) {
-            Vector<Cue> cues = mCues.get(timeMs);
-            if (cues != null) {
-                cues.remove(cue);
-                if (cues.size() == 0) {
-                    mCues.remove(timeMs);
-                }
-            }
-        }
-
-        public void add(Cue cue) {
-            // ignore non-positive-duration cues
-            if (cue.mStartTimeMs >= cue.mEndTimeMs)
-                return;
-
-            if (!addEvent(cue, cue.mStartTimeMs)) {
-                return;
-            }
-
-            long lastTimeMs = cue.mStartTimeMs;
-            if (cue.mInnerTimesMs != null) {
-                for (long timeMs: cue.mInnerTimesMs) {
-                    if (timeMs > lastTimeMs && timeMs < cue.mEndTimeMs) {
-                        addEvent(cue, timeMs);
-                        lastTimeMs = timeMs;
-                    }
-                }
-            }
-
-            addEvent(cue, cue.mEndTimeMs);
-        }
-
-        public void remove(Cue cue) {
-            removeEvent(cue, cue.mStartTimeMs);
-            if (cue.mInnerTimesMs != null) {
-                for (long timeMs: cue.mInnerTimesMs) {
-                    removeEvent(cue, timeMs);
-                }
-            }
-            removeEvent(cue, cue.mEndTimeMs);
-        }
-
-        public Iterable<Pair<Long, Cue>> entriesBetween(
-                final long lastTimeMs, final long timeMs) {
-            return new Iterable<Pair<Long, Cue> >() {
-                @Override
-                public Iterator<Pair<Long, Cue> > iterator() {
-                    if (DEBUG) Log.d(TAG, "slice (" + lastTimeMs + ", " + timeMs + "]=");
-                    try {
-                        return new EntryIterator(
-                                mCues.subMap(lastTimeMs + 1, timeMs + 1));
-                    } catch(IllegalArgumentException e) {
-                        return new EntryIterator(null);
-                    }
-                }
-            };
-        }
-
-        public long nextTimeAfter(long timeMs) {
-            SortedMap<Long, Vector<Cue>> tail = null;
-            try {
-                tail = mCues.tailMap(timeMs + 1);
-                if (tail != null) {
-                    return tail.firstKey();
-                } else {
-                    return -1;
-                }
-            } catch(IllegalArgumentException e) {
-                return -1;
-            } catch(NoSuchElementException e) {
-                return -1;
-            }
-        }
-
-        class EntryIterator implements Iterator<Pair<Long, Cue> > {
-            @Override
-            public boolean hasNext() {
-                return !mDone;
-            }
-
-            @Override
-            public Pair<Long, Cue> next() {
-                if (mDone) {
-                    throw new NoSuchElementException("");
-                }
-                mLastEntry = new Pair<Long, Cue>(
-                        mCurrentTimeMs, mListIterator.next());
-                mLastListIterator = mListIterator;
-                if (!mListIterator.hasNext()) {
-                    nextKey();
-                }
-                return mLastEntry;
-            }
-
-            @Override
-            public void remove() {
-                // only allow removing end tags
-                if (mLastListIterator == null ||
-                        mLastEntry.second.mEndTimeMs != mLastEntry.first) {
-                    throw new IllegalStateException("");
-                }
-
-                // remove end-cue
-                mLastListIterator.remove();
-                mLastListIterator = null;
-                if (mCues.get(mLastEntry.first).size() == 0) {
-                    mCues.remove(mLastEntry.first);
-                }
-
-                // remove rest of the cues
-                Cue cue = mLastEntry.second;
-                removeEvent(cue, cue.mStartTimeMs);
-                if (cue.mInnerTimesMs != null) {
-                    for (long timeMs: cue.mInnerTimesMs) {
-                        removeEvent(cue, timeMs);
-                    }
-                }
-            }
-
-            public EntryIterator(SortedMap<Long, Vector<Cue> > cues) {
-                if (DEBUG) Log.v(TAG, cues + "");
-                mRemainingCues = cues;
-                mLastListIterator = null;
-                nextKey();
-            }
-
-            private void nextKey() {
-                do {
-                    try {
-                        if (mRemainingCues == null) {
-                            throw new NoSuchElementException("");
-                        }
-                        mCurrentTimeMs = mRemainingCues.firstKey();
-                        mListIterator =
-                            mRemainingCues.get(mCurrentTimeMs).iterator();
-                        try {
-                            mRemainingCues =
-                                mRemainingCues.tailMap(mCurrentTimeMs + 1);
-                        } catch (IllegalArgumentException e) {
-                            mRemainingCues = null;
-                        }
-                        mDone = false;
-                    } catch (NoSuchElementException e) {
-                        mDone = true;
-                        mRemainingCues = null;
-                        mListIterator = null;
-                        return;
-                    }
-                } while (!mListIterator.hasNext());
-            }
-
-            private long mCurrentTimeMs;
-            private Iterator<Cue> mListIterator;
-            private boolean mDone;
-            private SortedMap<Long, Vector<Cue> > mRemainingCues;
-            private Iterator<Cue> mLastListIterator;
-            private Pair<Long,Cue> mLastEntry;
-        }
-
-        CueList() {
-            mCues = new TreeMap<Long, Vector<Cue>>();
-        }
-    }
-
-    public static class Cue {
-        public long mStartTimeMs;
-        public long mEndTimeMs;
-        public long[] mInnerTimesMs;
-        public long mRunID;
-
-        public Cue mNextInRun;
-
-        public void onTime(long timeMs) { }
-    }
-
-    /** update mRunsByEndTime (with default end time) */
-    protected void finishedRun(long runID) {
-        if (runID != 0 && runID != ~0) {
-            Run run = mRunsByID.get(runID);
-            if (run != null) {
-                run.storeByEndTimeMs(mRunsByEndTime);
-            }
-        }
-    }
-
-    /** update mRunsByEndTime with given end time */
-    public void setRunDiscardTimeMs(long runID, long timeMs) {
-        if (runID != 0 && runID != ~0) {
-            Run run = mRunsByID.get(runID);
-            if (run != null) {
-                run.mEndTimeMs = timeMs;
-                run.storeByEndTimeMs(mRunsByEndTime);
-            }
-        }
-    }
-
-    /** whether this is a text track who fires events instead getting rendered */
-    public int getTrackType() {
-        return getRenderingWidget() == null
-                ? TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT
-                : TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE;
-    }
-
-
-    private static class Run {
-        public Cue mFirstCue;
-        public Run mNextRunAtEndTimeMs;
-        public Run mPrevRunAtEndTimeMs;
-        public long mEndTimeMs = -1;
-        public long mRunID = 0;
-        private long mStoredEndTimeMs = -1;
-
-        public void storeByEndTimeMs(LongSparseArray<Run> runsByEndTime) {
-            // remove old value if any
-            int ix = runsByEndTime.indexOfKey(mStoredEndTimeMs);
-            if (ix >= 0) {
-                if (mPrevRunAtEndTimeMs == null) {
-                    assert(this == runsByEndTime.valueAt(ix));
-                    if (mNextRunAtEndTimeMs == null) {
-                        runsByEndTime.removeAt(ix);
-                    } else {
-                        runsByEndTime.setValueAt(ix, mNextRunAtEndTimeMs);
-                    }
-                }
-                removeAtEndTimeMs();
-            }
-
-            // add new value
-            if (mEndTimeMs >= 0) {
-                mPrevRunAtEndTimeMs = null;
-                mNextRunAtEndTimeMs = runsByEndTime.get(mEndTimeMs);
-                if (mNextRunAtEndTimeMs != null) {
-                    mNextRunAtEndTimeMs.mPrevRunAtEndTimeMs = this;
-                }
-                runsByEndTime.put(mEndTimeMs, this);
-                mStoredEndTimeMs = mEndTimeMs;
-            }
-        }
-
-        public void removeAtEndTimeMs() {
-            Run prev = mPrevRunAtEndTimeMs;
-
-            if (mPrevRunAtEndTimeMs != null) {
-                mPrevRunAtEndTimeMs.mNextRunAtEndTimeMs = mNextRunAtEndTimeMs;
-                mPrevRunAtEndTimeMs = null;
-            }
-            if (mNextRunAtEndTimeMs != null) {
-                mNextRunAtEndTimeMs.mPrevRunAtEndTimeMs = prev;
-                mNextRunAtEndTimeMs = null;
-            }
-        }
-    }
-
-    /**
-     * Interface for rendering subtitles onto a Canvas.
-     */
-    public interface RenderingWidget {
-        /**
-         * Sets the widget's callback, which is used to send updates when the
-         * rendered data has changed.
-         *
-         * @param callback update callback
-         */
-        public void setOnChangedListener(OnChangedListener callback);
-
-        /**
-         * Sets the widget's size.
-         *
-         * @param width width in pixels
-         * @param height height in pixels
-         */
-        public void setSize(int width, int height);
-
-        /**
-         * Sets whether the widget should draw subtitles.
-         *
-         * @param visible true if subtitles should be drawn, false otherwise
-         */
-        public void setVisible(boolean visible);
-
-        /**
-         * Renders subtitles onto a {@link Canvas}.
-         *
-         * @param c canvas on which to render subtitles
-         */
-        public void draw(Canvas c);
-
-        /**
-         * Called when the widget is attached to a window.
-         */
-        public void onAttachedToWindow();
-
-        /**
-         * Called when the widget is detached from a window.
-         */
-        public void onDetachedFromWindow();
-
-        /**
-         * Callback used to send updates about changes to rendering data.
-         */
-        public interface OnChangedListener {
-            /**
-             * Called when the rendering data has changed.
-             *
-             * @param renderingWidget the widget whose data has changed
-             */
-            public void onChanged(RenderingWidget renderingWidget);
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/media/update/ApiFactory.java b/packages/MediaComponents/src/com/android/media/update/ApiFactory.java
deleted file mode 100644
index d7be549..0000000
--- a/packages/MediaComponents/src/com/android/media/update/ApiFactory.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.media.update;
-
-import android.app.Notification;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.media.MediaBrowser2;
-import android.media.MediaBrowser2.BrowserCallback;
-import android.media.MediaController2;
-import android.media.MediaController2.ControllerCallback;
-import android.media.MediaItem2;
-import android.media.MediaLibraryService2;
-import android.media.MediaLibraryService2.LibraryRoot;
-import android.media.MediaLibraryService2.MediaLibrarySession;
-import android.media.MediaLibraryService2.MediaLibrarySession.MediaLibrarySessionCallback;
-import android.media.MediaMetadata2;
-import android.media.MediaPlaylistAgent;
-import android.media.MediaSession2;
-import android.media.SessionCommand2;
-import android.media.SessionCommandGroup2;
-import android.media.MediaSession2.ControllerInfo;
-import android.media.MediaSession2.SessionCallback;
-import android.media.MediaSessionService2;
-import android.media.MediaSessionService2.MediaNotification;
-import android.media.Rating2;
-import android.media.SessionToken2;
-import android.media.VolumeProvider2;
-import android.media.update.MediaBrowser2Provider;
-import android.media.update.MediaControlView2Provider;
-import android.media.update.MediaController2Provider;
-import android.media.update.MediaItem2Provider;
-import android.media.update.MediaLibraryService2Provider.LibraryRootProvider;
-import android.media.update.MediaMetadata2Provider;
-import android.media.update.MediaPlaylistAgentProvider;
-import android.media.update.MediaSession2Provider;
-import android.media.update.MediaSession2Provider.BuilderBaseProvider;
-import android.media.update.MediaSession2Provider.CommandButtonProvider.BuilderProvider;
-import android.media.update.MediaSessionService2Provider;
-import android.media.update.MediaSessionService2Provider.MediaNotificationProvider;
-import android.media.update.SessionToken2Provider;
-import android.media.update.StaticProvider;
-import android.media.update.VideoView2Provider;
-import android.media.update.ViewGroupProvider;
-import android.media.update.VolumeProvider2Provider;
-import android.os.Bundle;
-import android.os.IInterface;
-import android.support.annotation.Nullable;
-import android.util.AttributeSet;
-import android.widget.MediaControlView2;
-import android.widget.VideoView2;
-
-import com.android.media.IMediaController2;
-import com.android.media.MediaBrowser2Impl;
-import com.android.media.MediaController2Impl;
-import com.android.media.MediaItem2Impl;
-import com.android.media.MediaLibraryService2Impl;
-import com.android.media.MediaLibraryService2Impl.LibraryRootImpl;
-import com.android.media.MediaMetadata2Impl;
-import com.android.media.MediaPlaylistAgentImpl;
-import com.android.media.MediaSession2Impl;
-import com.android.media.MediaSessionService2Impl;
-import com.android.media.Rating2Impl;
-import com.android.media.SessionToken2Impl;
-import com.android.media.VolumeProvider2Impl;
-import com.android.widget.MediaControlView2Impl;
-import com.android.widget.VideoView2Impl;
-
-import java.util.concurrent.Executor;
-
-public final class ApiFactory implements StaticProvider {
-    private ApiFactory() { }
-
-    public static StaticProvider initialize(ApplicationInfo updatableInfo) {
-        ApiHelper.initialize(updatableInfo);
-        return new ApiFactory();
-    }
-
-    @Override
-    public MediaController2Provider createMediaController2(
-            Context context, MediaController2 instance, SessionToken2 token,
-            Executor executor, ControllerCallback callback) {
-        return new MediaController2Impl(context, instance, token, executor, callback);
-    }
-
-    @Override
-    public MediaBrowser2Provider createMediaBrowser2(Context context, MediaBrowser2 instance,
-            SessionToken2 token, Executor executor, BrowserCallback callback) {
-        return new MediaBrowser2Impl(context, instance, token, executor, callback);
-    }
-
-    @Override
-    public MediaSession2Provider.CommandProvider createMediaSession2Command(
-            SessionCommand2 instance, int commandCode, String action, Bundle extra) {
-        if (action == null && extra == null) {
-            return new MediaSession2Impl.CommandImpl(instance, commandCode);
-        }
-        return new MediaSession2Impl.CommandImpl(instance, action, extra);
-    }
-
-    @Override
-    public SessionCommand2 fromBundle_MediaSession2Command(Bundle command) {
-        return MediaSession2Impl.CommandImpl.fromBundle_impl(command);
-    }
-
-    @Override
-    public MediaSession2Provider.CommandGroupProvider createMediaSession2CommandGroup(
-            SessionCommandGroup2 instance, SessionCommandGroup2 other) {
-        return new MediaSession2Impl.CommandGroupImpl(instance,
-                (other == null) ? null : other.getProvider());
-    }
-
-    @Override
-    public SessionCommandGroup2 fromBundle_MediaSession2CommandGroup(Bundle commands) {
-        return MediaSession2Impl.CommandGroupImpl.fromBundle_impl(commands);
-    }
-
-    @Override
-    public MediaSession2Provider.ControllerInfoProvider createMediaSession2ControllerInfo(
-            Context context, ControllerInfo instance, int uid, int pid, String packageName,
-            IInterface callback) {
-        return new MediaSession2Impl.ControllerInfoImpl(context,
-                instance, uid, pid, packageName, (IMediaController2) callback);
-    }
-
-    @Override
-    public BuilderProvider createMediaSession2CommandButtonBuilder(
-            MediaSession2.CommandButton.Builder instance) {
-        return new MediaSession2Impl.CommandButtonImpl.BuilderImpl(instance);
-    }
-
-    public BuilderBaseProvider<MediaSession2, SessionCallback> createMediaSession2Builder(
-            Context context, MediaSession2.Builder instance) {
-        return new MediaSession2Impl.BuilderImpl(context, instance);
-    }
-
-    @Override
-    public MediaSessionService2Provider createMediaSessionService2(MediaSessionService2 instance) {
-        return new MediaSessionService2Impl(instance);
-    }
-
-    @Override
-    public MediaNotificationProvider createMediaSessionService2MediaNotification(
-            MediaNotification instance, int notificationId, Notification notification) {
-        return new MediaSessionService2Impl.MediaNotificationImpl(
-                instance, notificationId, notification);
-    }
-
-    @Override
-    public MediaSessionService2Provider createMediaLibraryService2(MediaLibraryService2 instance) {
-        return new MediaLibraryService2Impl(instance);
-    }
-
-    @Override
-    public BuilderBaseProvider<MediaLibrarySession, MediaLibrarySessionCallback>
-        createMediaLibraryService2Builder(MediaLibraryService2 service,
-            MediaLibrarySession.Builder instance, Executor callbackExecutor,
-            MediaLibrarySessionCallback callback) {
-        return new MediaLibraryService2Impl.BuilderImpl(service, instance, callbackExecutor,
-                callback);
-    }
-
-    @Override
-    public LibraryRootProvider createMediaLibraryService2LibraryRoot(
-            LibraryRoot instance, String rootId, Bundle extras) {
-        return new LibraryRootImpl(instance, rootId, extras);
-    }
-
-    @Override
-    public MediaControlView2Provider createMediaControlView2(MediaControlView2 instance,
-            ViewGroupProvider superProvider, ViewGroupProvider privateProvider,
-            @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        return new MediaControlView2Impl(instance, superProvider, privateProvider);
-    }
-
-    @Override
-    public VideoView2Provider createVideoView2(
-            VideoView2 instance, ViewGroupProvider superProvider, ViewGroupProvider privateProvider,
-            @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        return new VideoView2Impl(instance, superProvider, privateProvider);
-    }
-
-    @Override
-    public SessionToken2Provider createSessionToken2(Context context, SessionToken2 instance,
-            String packageName, String serviceName, int uid) {
-        return new SessionToken2Impl(context, instance, packageName, serviceName, uid);
-    }
-
-    @Override
-    public SessionToken2 fromBundle_SessionToken2(Bundle bundle) {
-        return SessionToken2Impl.fromBundle_impl(bundle);
-    }
-
-    @Override
-    public MediaItem2Provider.BuilderProvider createMediaItem2Builder(MediaItem2.Builder instance,
-            int flags) {
-        return new MediaItem2Impl.BuilderImpl(instance, flags);
-    }
-
-    @Override
-    public MediaItem2 fromBundle_MediaItem2(Bundle bundle) {
-        return MediaItem2Impl.fromBundle_impl(bundle);
-    }
-
-    @Override
-    public VolumeProvider2Provider createVolumeProvider2(VolumeProvider2 instance, int controlType,
-            int maxVolume, int currentVolume) {
-        return new VolumeProvider2Impl(instance, controlType, maxVolume, currentVolume);
-    }
-
-    @Override
-    public MediaMetadata2 fromBundle_MediaMetadata2(Bundle bundle) {
-        return MediaMetadata2Impl.fromBundle_impl(bundle);
-    }
-
-    @Override
-    public MediaMetadata2Provider.BuilderProvider createMediaMetadata2Builder(
-            MediaMetadata2.Builder instance) {
-        return new MediaMetadata2Impl.BuilderImpl(instance);
-    }
-
-    @Override
-    public MediaMetadata2Provider.BuilderProvider createMediaMetadata2Builder(
-            MediaMetadata2.Builder instance, MediaMetadata2 source) {
-        return new MediaMetadata2Impl.BuilderImpl(instance, source);
-    }
-
-    @Override
-    public Rating2 fromBundle_Rating2(Bundle bundle) {
-        return Rating2Impl.fromBundle_impl(bundle);
-    }
-
-    @Override
-    public Rating2 newUnratedRating_Rating2(int ratingStyle) {
-        return Rating2Impl.newUnratedRating_impl(ratingStyle);
-    }
-
-    @Override
-    public Rating2 newHeartRating_Rating2(boolean hasHeart) {
-        return Rating2Impl.newHeartRating_impl(hasHeart);
-    }
-
-    @Override
-    public Rating2 newThumbRating_Rating2(boolean thumbIsUp) {
-        return Rating2Impl.newThumbRating_impl(thumbIsUp);
-    }
-
-    @Override
-    public Rating2 newStarRating_Rating2(int starRatingStyle, float starRating) {
-        return Rating2Impl.newStarRating_impl(starRatingStyle, starRating);
-    }
-
-    @Override
-    public Rating2 newPercentageRating_Rating2(float percent) {
-        return Rating2Impl.newPercentageRating_impl(percent);
-    }
-
-    @Override
-    public MediaPlaylistAgentProvider createMediaPlaylistAgent(MediaPlaylistAgent instance) {
-        return new MediaPlaylistAgentImpl(instance);
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/media/update/ApiHelper.java b/packages/MediaComponents/src/com/android/media/update/ApiHelper.java
deleted file mode 100644
index ad8bb48..0000000
--- a/packages/MediaComponents/src/com/android/media/update/ApiHelper.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.media.update;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.content.res.Resources.Theme;
-import android.content.res.XmlResourceParser;
-import android.support.annotation.GuardedBy;
-import android.support.v4.widget.Space;
-import android.support.v7.widget.ButtonBarLayout;
-import android.util.AttributeSet;
-import android.view.ContextThemeWrapper;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.android.support.mediarouter.app.MediaRouteButton;
-import com.android.support.mediarouter.app.MediaRouteExpandCollapseButton;
-import com.android.support.mediarouter.app.MediaRouteVolumeSlider;
-import com.android.support.mediarouter.app.OverlayListView;
-
-public final class ApiHelper {
-    private static ApplicationInfo sUpdatableInfo;
-
-    @GuardedBy("this")
-    private static Theme sLibTheme;
-
-    private ApiHelper() { }
-
-    static void initialize(ApplicationInfo updatableInfo) {
-        if (sUpdatableInfo != null) {
-            throw new IllegalStateException("initialize should only be called once");
-        }
-
-        sUpdatableInfo = updatableInfo;
-    }
-
-    public static Resources getLibResources(Context context) {
-        return getLibTheme(context).getResources();
-    }
-
-    public static Theme getLibTheme(Context context) {
-        if (sLibTheme != null) return sLibTheme;
-
-        return getLibThemeSynchronized(context);
-    }
-
-    public static Theme getLibTheme(Context context, int themeId) {
-        Theme theme = getLibResources(context).newTheme();
-        theme.applyStyle(themeId, true);
-        return theme;
-    }
-
-    public static LayoutInflater getLayoutInflater(Context context) {
-        return getLayoutInflater(context, null);
-    }
-
-    public static LayoutInflater getLayoutInflater(Context context, Theme theme) {
-        if (theme == null) {
-            theme = getLibTheme(context);
-        }
-
-        // TODO (b/72975976): Avoid to use ContextThemeWrapper with app context and lib theme.
-        LayoutInflater layoutInflater = LayoutInflater.from(context).cloneInContext(
-                new ContextThemeWrapper(context, theme));
-        layoutInflater.setFactory2(new LayoutInflater.Factory2() {
-            @Override
-            public View onCreateView(
-                    View parent, String name, Context context, AttributeSet attrs) {
-                if (MediaRouteButton.class.getCanonicalName().equals(name)) {
-                    return new MediaRouteButton(context, attrs);
-                } else if (MediaRouteVolumeSlider.class.getCanonicalName().equals(name)) {
-                    return new MediaRouteVolumeSlider(context, attrs);
-                } else if (MediaRouteExpandCollapseButton.class.getCanonicalName().equals(name)) {
-                    return new MediaRouteExpandCollapseButton(context, attrs);
-                } else if (OverlayListView.class.getCanonicalName().equals(name)) {
-                    return new OverlayListView(context, attrs);
-                } else if (ButtonBarLayout.class.getCanonicalName().equals(name)) {
-                    return new ButtonBarLayout(context, attrs);
-                } else if (Space.class.getCanonicalName().equals(name)) {
-                    return new Space(context, attrs);
-                }
-                return null;
-            }
-
-            @Override
-            public View onCreateView(String name, Context context, AttributeSet attrs) {
-                return onCreateView(null, name, context, attrs);
-            }
-        });
-        return layoutInflater;
-    }
-
-    public static View inflateLibLayout(Context context, int libResId) {
-        return inflateLibLayout(context, getLibTheme(context), libResId, null, false);
-    }
-
-    public static View inflateLibLayout(Context context, Theme theme, int libResId) {
-        return inflateLibLayout(context, theme, libResId, null, false);
-    }
-
-    public static View inflateLibLayout(Context context, Theme theme, int libResId,
-            @Nullable ViewGroup root, boolean attachToRoot) {
-        try (XmlResourceParser parser = getLibResources(context).getLayout(libResId)) {
-            return getLayoutInflater(context, theme).inflate(parser, root, attachToRoot);
-        }
-    }
-
-    private static synchronized Theme getLibThemeSynchronized(Context context) {
-        if (sLibTheme != null) return sLibTheme;
-
-        if (sUpdatableInfo == null) {
-            throw new IllegalStateException("initialize hasn't been called yet");
-        }
-
-        try {
-            return sLibTheme = context.getPackageManager()
-                    .getResourcesForApplication(sUpdatableInfo).newTheme();
-        } catch (NameNotFoundException e) {
-            throw new RuntimeException(e);
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/api24/media/MediaRouterApi24.java b/packages/MediaComponents/src/com/android/support/mediarouter/api24/media/MediaRouterApi24.java
deleted file mode 100644
index 1146af6..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/api24/media/MediaRouterApi24.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.media;
-
-// @@RequiresApi(24)
-final class MediaRouterApi24 {
-    public static final class RouteInfo {
-        public static int getDeviceType(Object routeObj) {
-            return ((android.media.MediaRouter.RouteInfo)routeObj).getDeviceType();
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteActionProvider.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteActionProvider.java
deleted file mode 100644
index d3e8d47..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteActionProvider.java
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.app;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.support.v4.view.ActionProvider;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.android.support.mediarouter.media.MediaRouteSelector;
-import com.android.support.mediarouter.media.MediaRouter;
-
-import java.lang.ref.WeakReference;
-
-/**
- * The media route action provider displays a {@link MediaRouteButton media route button}
- * in the application's {@link ActionBar} to allow the user to select routes and
- * to control the currently selected route.
- * <p>
- * The application must specify the kinds of routes that the user should be allowed
- * to select by specifying a {@link MediaRouteSelector selector} with the
- * {@link #setRouteSelector} method.
- * </p><p>
- * Refer to {@link MediaRouteButton} for a description of the button that will
- * appear in the action bar menu.  Note that instead of disabling the button
- * when no routes are available, the action provider will instead make the
- * menu item invisible.  In this way, the button will only be visible when it
- * is possible for the user to discover and select a matching route.
- * </p>
- *
- * <h3>Prerequisites</h3>
- * <p>
- * To use the media route action provider, the activity must be a subclass of
- * {@link AppCompatActivity} from the <code>android.support.v7.appcompat</code>
- * support library.  Refer to support library documentation for details.
- * </p>
- *
- * <h3>Example</h3>
- * <p>
- * </p><p>
- * The application should define a menu resource to include the provider in the
- * action bar options menu.  Note that the support library action bar uses attributes
- * that are defined in the application's resource namespace rather than the framework's
- * resource namespace to configure each item.
- * </p><pre>
- * &lt;menu xmlns:android="http://schemas.android.com/apk/res/android"
- *         xmlns:app="http://schemas.android.com/apk/res-auto">
- *     &lt;item android:id="@+id/media_route_menu_item"
- *         android:title="@string/media_route_menu_title"
- *         app:showAsAction="always"
- *         app:actionProviderClass="android.support.v7.app.MediaRouteActionProvider"/>
- * &lt;/menu>
- * </pre><p>
- * Then configure the menu and set the route selector for the chooser.
- * </p><pre>
- * public class MyActivity extends AppCompatActivity {
- *     private MediaRouter mRouter;
- *     private MediaRouter.Callback mCallback;
- *     private MediaRouteSelector mSelector;
- *
- *     protected void onCreate(Bundle savedInstanceState) {
- *         super.onCreate(savedInstanceState);
- *
- *         mRouter = Mediarouter.getInstance(this);
- *         mSelector = new MediaRouteSelector.Builder()
- *                 .addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO)
- *                 .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
- *                 .build();
- *         mCallback = new MyCallback();
- *     }
- *
- *     // Add the callback on start to tell the media router what kinds of routes
- *     // the application is interested in so that it can try to discover suitable ones.
- *     public void onStart() {
- *         super.onStart();
- *
- *         mediaRouter.addCallback(mSelector, mCallback,
- *                 MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
- *
- *         MediaRouter.RouteInfo route = mediaRouter.updateSelectedRoute(mSelector);
- *         // do something with the route...
- *     }
- *
- *     // Remove the selector on stop to tell the media router that it no longer
- *     // needs to invest effort trying to discover routes of these kinds for now.
- *     public void onStop() {
- *         super.onStop();
- *
- *         mediaRouter.removeCallback(mCallback);
- *     }
- *
- *     public boolean onCreateOptionsMenu(Menu menu) {
- *         super.onCreateOptionsMenu(menu);
- *
- *         getMenuInflater().inflate(R.menu.sample_media_router_menu, menu);
- *
- *         MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item);
- *         MediaRouteActionProvider mediaRouteActionProvider =
- *                 (MediaRouteActionProvider)MenuItemCompat.getActionProvider(mediaRouteMenuItem);
- *         mediaRouteActionProvider.setRouteSelector(mSelector);
- *         return true;
- *     }
- *
- *     private final class MyCallback extends MediaRouter.Callback {
- *         // Implement callback methods as needed.
- *     }
- * }
- * </pre>
- *
- * @see #setRouteSelector
- */
-public class MediaRouteActionProvider extends ActionProvider {
-    private static final String TAG = "MediaRouteActionProvider";
-
-    private final MediaRouter mRouter;
-    private final MediaRouterCallback mCallback;
-
-    private MediaRouteSelector mSelector = MediaRouteSelector.EMPTY;
-    private MediaRouteDialogFactory mDialogFactory = MediaRouteDialogFactory.getDefault();
-    private MediaRouteButton mButton;
-
-    /**
-     * Creates the action provider.
-     *
-     * @param context The context.
-     */
-    public MediaRouteActionProvider(Context context) {
-        super(context);
-
-        mRouter = MediaRouter.getInstance(context);
-        mCallback = new MediaRouterCallback(this);
-    }
-
-    /**
-     * Gets the media route selector for filtering the routes that the user can
-     * select using the media route chooser dialog.
-     *
-     * @return The selector, never null.
-     */
-    @NonNull
-    public MediaRouteSelector getRouteSelector() {
-        return mSelector;
-    }
-
-    /**
-     * Sets the media route selector for filtering the routes that the user can
-     * select using the media route chooser dialog.
-     *
-     * @param selector The selector, must not be null.
-     */
-    public void setRouteSelector(@NonNull MediaRouteSelector selector) {
-        if (selector == null) {
-            throw new IllegalArgumentException("selector must not be null");
-        }
-
-        if (!mSelector.equals(selector)) {
-            // FIXME: We currently have no way of knowing whether the action provider
-            // is still needed by the UI.  Unfortunately this means the action provider
-            // may leak callbacks until garbage collection occurs.  This may result in
-            // media route providers doing more work than necessary in the short term
-            // while trying to discover routes that are no longer of interest to the
-            // application.  To solve this problem, the action provider will need some
-            // indication from the framework that it is being destroyed.
-            if (!mSelector.isEmpty()) {
-                mRouter.removeCallback(mCallback);
-            }
-            if (!selector.isEmpty()) {
-                mRouter.addCallback(selector, mCallback);
-            }
-            mSelector = selector;
-            refreshRoute();
-
-            if (mButton != null) {
-                mButton.setRouteSelector(selector);
-            }
-        }
-    }
-
-    /**
-     * Gets the media route dialog factory to use when showing the route chooser
-     * or controller dialog.
-     *
-     * @return The dialog factory, never null.
-     */
-    @NonNull
-    public MediaRouteDialogFactory getDialogFactory() {
-        return mDialogFactory;
-    }
-
-    /**
-     * Sets the media route dialog factory to use when showing the route chooser
-     * or controller dialog.
-     *
-     * @param factory The dialog factory, must not be null.
-     */
-    public void setDialogFactory(@NonNull MediaRouteDialogFactory factory) {
-        if (factory == null) {
-            throw new IllegalArgumentException("factory must not be null");
-        }
-
-        if (mDialogFactory != factory) {
-            mDialogFactory = factory;
-
-            if (mButton != null) {
-                mButton.setDialogFactory(factory);
-            }
-        }
-    }
-
-    /**
-     * Gets the associated media route button, or null if it has not yet been created.
-     */
-    @Nullable
-    public MediaRouteButton getMediaRouteButton() {
-        return mButton;
-    }
-
-    /**
-     * Called when the media route button is being created.
-     * <p>
-     * Subclasses may override this method to customize the button.
-     * </p>
-     */
-    public MediaRouteButton onCreateMediaRouteButton() {
-        return new MediaRouteButton(getContext());
-    }
-
-    @Override
-    @SuppressWarnings("deprecation")
-    public View onCreateActionView() {
-        if (mButton != null) {
-            Log.e(TAG, "onCreateActionView: this ActionProvider is already associated " +
-                    "with a menu item. Don't reuse MediaRouteActionProvider instances! " +
-                    "Abandoning the old menu item...");
-        }
-
-        mButton = onCreateMediaRouteButton();
-        mButton.setCheatSheetEnabled(true);
-        mButton.setRouteSelector(mSelector);
-        mButton.setDialogFactory(mDialogFactory);
-        mButton.setLayoutParams(new ViewGroup.LayoutParams(
-                ViewGroup.LayoutParams.WRAP_CONTENT,
-                ViewGroup.LayoutParams.MATCH_PARENT));
-        return mButton;
-    }
-
-    @Override
-    public boolean onPerformDefaultAction() {
-        if (mButton != null) {
-            return mButton.showDialog();
-        }
-        return false;
-    }
-
-    @Override
-    public boolean overridesItemVisibility() {
-        return true;
-    }
-
-    @Override
-    public boolean isVisible() {
-        return mRouter.isRouteAvailable(mSelector,
-                MediaRouter.AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE);
-    }
-
-    void refreshRoute() {
-        refreshVisibility();
-    }
-
-    private static final class MediaRouterCallback extends MediaRouter.Callback {
-        private final WeakReference<MediaRouteActionProvider> mProviderWeak;
-
-        public MediaRouterCallback(MediaRouteActionProvider provider) {
-            mProviderWeak = new WeakReference<MediaRouteActionProvider>(provider);
-        }
-
-        @Override
-        public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo info) {
-            refreshRoute(router);
-        }
-
-        @Override
-        public void onRouteRemoved(MediaRouter router, MediaRouter.RouteInfo info) {
-            refreshRoute(router);
-        }
-
-        @Override
-        public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo info) {
-            refreshRoute(router);
-        }
-
-        @Override
-        public void onProviderAdded(MediaRouter router, MediaRouter.ProviderInfo provider) {
-            refreshRoute(router);
-        }
-
-        @Override
-        public void onProviderRemoved(MediaRouter router, MediaRouter.ProviderInfo provider) {
-            refreshRoute(router);
-        }
-
-        @Override
-        public void onProviderChanged(MediaRouter router, MediaRouter.ProviderInfo provider) {
-            refreshRoute(router);
-        }
-
-        private void refreshRoute(MediaRouter router) {
-            MediaRouteActionProvider provider = mProviderWeak.get();
-            if (provider != null) {
-                provider.refreshRoute();
-            } else {
-                router.removeCallback(this);
-            }
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteButton.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteButton.java
deleted file mode 100644
index fde8a63..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteButton.java
+++ /dev/null
@@ -1,629 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.app;
-
-import android.annotation.NonNull;
-import android.app.Activity;
-import android.app.FragmentManager;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.res.ColorStateList;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.drawable.AnimationDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.AsyncTask;
-import android.support.v4.graphics.drawable.DrawableCompat;
-import android.support.v7.widget.TooltipCompat;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.SparseArray;
-import android.view.SoundEffectConstants;
-import android.view.View;
-
-import com.android.media.update.ApiHelper;
-import com.android.media.update.R;
-import com.android.support.mediarouter.media.MediaRouteSelector;
-import com.android.support.mediarouter.media.MediaRouter;
-
-/**
- * The media route button allows the user to select routes and to control the
- * currently selected route.
- * <p>
- * The application must specify the kinds of routes that the user should be allowed
- * to select by specifying a {@link MediaRouteSelector selector} with the
- * {@link #setRouteSelector} method.
- * </p><p>
- * When the default route is selected or when the currently selected route does not
- * match the {@link #getRouteSelector() selector}, the button will appear in
- * an inactive state indicating that the application is not connected to a
- * route of the kind that it wants to use.  Clicking on the button opens
- * a {@link MediaRouteChooserDialog} to allow the user to select a route.
- * If no non-default routes match the selector and it is not possible for an active
- * scan to discover any matching routes, then the button is disabled and cannot
- * be clicked.
- * </p><p>
- * When a non-default route is selected that matches the selector, the button will
- * appear in an active state indicating that the application is connected
- * to a route of the kind that it wants to use.  The button may also appear
- * in an intermediary connecting state if the route is in the process of connecting
- * to the destination but has not yet completed doing so.  In either case, clicking
- * on the button opens a {@link MediaRouteControllerDialog} to allow the user
- * to control or disconnect from the current route.
- * </p>
- *
- * <h3>Prerequisites</h3>
- * <p>
- * To use the media route button, the activity must be a subclass of
- * {@link FragmentActivity} from the <code>android.support.v4</code>
- * support library.  Refer to support library documentation for details.
- * </p>
- *
- * @see MediaRouteActionProvider
- * @see #setRouteSelector
- */
-public class MediaRouteButton extends View {
-    private static final String TAG = "MediaRouteButton";
-
-    private static final String CHOOSER_FRAGMENT_TAG =
-            "android.support.v7.mediarouter:MediaRouteChooserDialogFragment";
-    private static final String CONTROLLER_FRAGMENT_TAG =
-            "android.support.v7.mediarouter:MediaRouteControllerDialogFragment";
-
-    private final MediaRouter mRouter;
-    private final MediaRouterCallback mCallback;
-
-    private MediaRouteSelector mSelector = MediaRouteSelector.EMPTY;
-    private int mRouteCallbackFlags;
-    private MediaRouteDialogFactory mDialogFactory = MediaRouteDialogFactory.getDefault();
-
-    private boolean mAttachedToWindow;
-
-    private static final SparseArray<Drawable.ConstantState> sRemoteIndicatorCache =
-            new SparseArray<>(2);
-    private RemoteIndicatorLoader mRemoteIndicatorLoader;
-    private Drawable mRemoteIndicator;
-    private boolean mRemoteActive;
-    private boolean mIsConnecting;
-
-    private ColorStateList mButtonTint;
-    private int mMinWidth;
-    private int mMinHeight;
-
-    // The checked state is used when connected to a remote route.
-    private static final int[] CHECKED_STATE_SET = {
-        android.R.attr.state_checked
-    };
-
-    // The checkable state is used while connecting to a remote route.
-    private static final int[] CHECKABLE_STATE_SET = {
-        android.R.attr.state_checkable
-    };
-
-    public MediaRouteButton(Context context) {
-        this(context, null);
-    }
-
-    public MediaRouteButton(Context context, AttributeSet attrs) {
-        this(context, attrs, R.attr.mediaRouteButtonStyle);
-    }
-
-    public MediaRouteButton(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(MediaRouterThemeHelper.createThemedButtonContext(context), attrs, defStyleAttr);
-        context = getContext();
-
-        mRouter = MediaRouter.getInstance(context);
-        mCallback = new MediaRouterCallback();
-
-        Resources.Theme theme = ApiHelper.getLibResources(context).newTheme();
-        theme.applyStyle(MediaRouterThemeHelper.getRouterThemeId(context), true);
-        TypedArray a = theme.obtainStyledAttributes(attrs,
-                R.styleable.MediaRouteButton, defStyleAttr, 0);
-
-        mButtonTint = a.getColorStateList(R.styleable.MediaRouteButton_mediaRouteButtonTint);
-        mMinWidth = a.getDimensionPixelSize(
-                R.styleable.MediaRouteButton_android_minWidth, 0);
-        mMinHeight = a.getDimensionPixelSize(
-                R.styleable.MediaRouteButton_android_minHeight, 0);
-        int remoteIndicatorResId = a.getResourceId(
-                R.styleable.MediaRouteButton_externalRouteEnabledDrawable, 0);
-        a.recycle();
-
-        if (remoteIndicatorResId != 0) {
-            Drawable.ConstantState remoteIndicatorState =
-                    sRemoteIndicatorCache.get(remoteIndicatorResId);
-            if (remoteIndicatorState != null) {
-                setRemoteIndicatorDrawable(remoteIndicatorState.newDrawable());
-            } else {
-                mRemoteIndicatorLoader = new RemoteIndicatorLoader(remoteIndicatorResId);
-                mRemoteIndicatorLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-            }
-        }
-
-        updateContentDescription();
-        setClickable(true);
-    }
-
-    /**
-     * Gets the media route selector for filtering the routes that the user can
-     * select using the media route chooser dialog.
-     *
-     * @return The selector, never null.
-     */
-    @NonNull
-    public MediaRouteSelector getRouteSelector() {
-        return mSelector;
-    }
-
-    /**
-     * Sets the media route selector for filtering the routes that the user can
-     * select using the media route chooser dialog.
-     *
-     * @param selector The selector.
-     */
-    public void setRouteSelector(MediaRouteSelector selector) {
-        setRouteSelector(selector, 0);
-    }
-
-    /**
-     * Sets the media route selector for filtering the routes that the user can
-     * select using the media route chooser dialog.
-     *
-     * @param selector The selector.
-     * @param flags Flags to control the behavior of the callback. May be zero or a combination of
-     *              {@link #MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN} and
-     *              {@link #MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS}.
-     */
-    public void setRouteSelector(MediaRouteSelector selector, int flags) {
-        if (mSelector.equals(selector) && mRouteCallbackFlags == flags) {
-            return;
-        }
-        if (!mSelector.isEmpty()) {
-            mRouter.removeCallback(mCallback);
-        }
-        if (selector == null || selector.isEmpty()) {
-            mSelector = MediaRouteSelector.EMPTY;
-            return;
-        }
-
-        mSelector = selector;
-        mRouteCallbackFlags = flags;
-
-        if (mAttachedToWindow) {
-            mRouter.addCallback(selector, mCallback, flags);
-            refreshRoute();
-        }
-    }
-
-    /**
-     * Gets the media route dialog factory to use when showing the route chooser
-     * or controller dialog.
-     *
-     * @return The dialog factory, never null.
-     */
-    @NonNull
-    public MediaRouteDialogFactory getDialogFactory() {
-        return mDialogFactory;
-    }
-
-    /**
-     * Sets the media route dialog factory to use when showing the route chooser
-     * or controller dialog.
-     *
-     * @param factory The dialog factory, must not be null.
-     */
-    public void setDialogFactory(@NonNull MediaRouteDialogFactory factory) {
-        if (factory == null) {
-            throw new IllegalArgumentException("factory must not be null");
-        }
-
-        mDialogFactory = factory;
-    }
-
-    /**
-     * Show the route chooser or controller dialog.
-     * <p>
-     * If the default route is selected or if the currently selected route does
-     * not match the {@link #getRouteSelector selector}, then shows the route chooser dialog.
-     * Otherwise, shows the route controller dialog to offer the user
-     * a choice to disconnect from the route or perform other control actions
-     * such as setting the route's volume.
-     * </p><p>
-     * The application can customize the dialogs by calling {@link #setDialogFactory}
-     * to provide a customized dialog factory.
-     * </p>
-     *
-     * @return True if the dialog was actually shown.
-     *
-     * @throws IllegalStateException if the activity is not a subclass of
-     * {@link FragmentActivity}.
-     */
-    public boolean showDialog() {
-        if (!mAttachedToWindow) {
-            return false;
-        }
-
-        final FragmentManager fm = getActivity().getFragmentManager();
-        if (fm == null) {
-            throw new IllegalStateException("The activity must be a subclass of FragmentActivity");
-        }
-
-        MediaRouter.RouteInfo route = mRouter.getSelectedRoute();
-        if (route.isDefaultOrBluetooth() || !route.matchesSelector(mSelector)) {
-            if (fm.findFragmentByTag(CHOOSER_FRAGMENT_TAG) != null) {
-                Log.w(TAG, "showDialog(): Route chooser dialog already showing!");
-                return false;
-            }
-            MediaRouteChooserDialogFragment f =
-                    mDialogFactory.onCreateChooserDialogFragment();
-            f.setRouteSelector(mSelector);
-            f.show(fm, CHOOSER_FRAGMENT_TAG);
-        } else {
-            if (fm.findFragmentByTag(CONTROLLER_FRAGMENT_TAG) != null) {
-                Log.w(TAG, "showDialog(): Route controller dialog already showing!");
-                return false;
-            }
-            MediaRouteControllerDialogFragment f =
-                    mDialogFactory.onCreateControllerDialogFragment();
-            f.show(fm, CONTROLLER_FRAGMENT_TAG);
-        }
-        return true;
-    }
-
-
-    private Activity getActivity() {
-        // Gross way of unwrapping the Activity so we can get the FragmentManager
-        Context context = getContext();
-        while (context instanceof ContextWrapper) {
-            if (context instanceof Activity) {
-                return (Activity)context;
-            }
-            context = ((ContextWrapper)context).getBaseContext();
-        }
-        return null;
-    }
-
-    /**
-     * Sets whether to enable showing a toast with the content descriptor of the
-     * button when the button is long pressed.
-     */
-    void setCheatSheetEnabled(boolean enable) {
-        TooltipCompat.setTooltipText(this, enable
-                ? ApiHelper.getLibResources(getContext())
-                    .getString(R.string.mr_button_content_description)
-                : null);
-    }
-
-    @Override
-    public boolean performClick() {
-        // Send the appropriate accessibility events and call listeners
-        boolean handled = super.performClick();
-        if (!handled) {
-            playSoundEffect(SoundEffectConstants.CLICK);
-        }
-        return showDialog() || handled;
-    }
-
-    @Override
-    protected int[] onCreateDrawableState(int extraSpace) {
-        final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
-
-        // Technically we should be handling this more completely, but these
-        // are implementation details here. Checkable is used to express the connecting
-        // drawable state and it's mutually exclusive with check for the purposes
-        // of state selection here.
-        if (mIsConnecting) {
-            mergeDrawableStates(drawableState, CHECKABLE_STATE_SET);
-        } else if (mRemoteActive) {
-            mergeDrawableStates(drawableState, CHECKED_STATE_SET);
-        }
-        return drawableState;
-    }
-
-    @Override
-    protected void drawableStateChanged() {
-        super.drawableStateChanged();
-
-        if (mRemoteIndicator != null) {
-            int[] myDrawableState = getDrawableState();
-            mRemoteIndicator.setState(myDrawableState);
-            invalidate();
-        }
-    }
-
-    /**
-     * Sets a drawable to use as the remote route indicator.
-     */
-    public void setRemoteIndicatorDrawable(Drawable d) {
-        if (mRemoteIndicatorLoader != null) {
-            mRemoteIndicatorLoader.cancel(false);
-        }
-
-        if (mRemoteIndicator != null) {
-            mRemoteIndicator.setCallback(null);
-            unscheduleDrawable(mRemoteIndicator);
-        }
-        if (d != null) {
-            if (mButtonTint != null) {
-                d = DrawableCompat.wrap(d.mutate());
-                DrawableCompat.setTintList(d, mButtonTint);
-            }
-            d.setCallback(this);
-            d.setState(getDrawableState());
-            d.setVisible(getVisibility() == VISIBLE, false);
-        }
-        mRemoteIndicator = d;
-
-        refreshDrawableState();
-        if (mAttachedToWindow && mRemoteIndicator != null
-                && mRemoteIndicator.getCurrent() instanceof AnimationDrawable) {
-            AnimationDrawable curDrawable = (AnimationDrawable) mRemoteIndicator.getCurrent();
-            if (mIsConnecting) {
-                if (!curDrawable.isRunning()) {
-                    curDrawable.start();
-                }
-            } else if (mRemoteActive) {
-                if (curDrawable.isRunning()) {
-                    curDrawable.stop();
-                }
-                curDrawable.selectDrawable(curDrawable.getNumberOfFrames() - 1);
-            }
-        }
-    }
-
-    @Override
-    protected boolean verifyDrawable(Drawable who) {
-        return super.verifyDrawable(who) || who == mRemoteIndicator;
-    }
-
-    @Override
-    public void jumpDrawablesToCurrentState() {
-        // We can't call super to handle the background so we do it ourselves.
-        //super.jumpDrawablesToCurrentState();
-        if (getBackground() != null) {
-            DrawableCompat.jumpToCurrentState(getBackground());
-        }
-
-        // Handle our own remote indicator.
-        if (mRemoteIndicator != null) {
-            DrawableCompat.jumpToCurrentState(mRemoteIndicator);
-        }
-    }
-
-    @Override
-    public void setVisibility(int visibility) {
-        super.setVisibility(visibility);
-
-        if (mRemoteIndicator != null) {
-            mRemoteIndicator.setVisible(getVisibility() == VISIBLE, false);
-        }
-    }
-
-    @Override
-    public void onAttachedToWindow() {
-        super.onAttachedToWindow();
-
-        mAttachedToWindow = true;
-        if (!mSelector.isEmpty()) {
-            mRouter.addCallback(mSelector, mCallback, mRouteCallbackFlags);
-        }
-        refreshRoute();
-    }
-
-    @Override
-    public void onDetachedFromWindow() {
-        mAttachedToWindow = false;
-        if (!mSelector.isEmpty()) {
-            mRouter.removeCallback(mCallback);
-        }
-
-        super.onDetachedFromWindow();
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
-        final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
-        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
-        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
-
-        final int width = Math.max(mMinWidth, mRemoteIndicator != null ?
-                mRemoteIndicator.getIntrinsicWidth() + getPaddingLeft() + getPaddingRight() : 0);
-        final int height = Math.max(mMinHeight, mRemoteIndicator != null ?
-                mRemoteIndicator.getIntrinsicHeight() + getPaddingTop() + getPaddingBottom() : 0);
-
-        int measuredWidth;
-        switch (widthMode) {
-            case MeasureSpec.EXACTLY:
-                measuredWidth = widthSize;
-                break;
-            case MeasureSpec.AT_MOST:
-                measuredWidth = Math.min(widthSize, width);
-                break;
-            default:
-            case MeasureSpec.UNSPECIFIED:
-                measuredWidth = width;
-                break;
-        }
-
-        int measuredHeight;
-        switch (heightMode) {
-            case MeasureSpec.EXACTLY:
-                measuredHeight = heightSize;
-                break;
-            case MeasureSpec.AT_MOST:
-                measuredHeight = Math.min(heightSize, height);
-                break;
-            default:
-            case MeasureSpec.UNSPECIFIED:
-                measuredHeight = height;
-                break;
-        }
-
-        setMeasuredDimension(measuredWidth, measuredHeight);
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-
-        if (mRemoteIndicator != null) {
-            final int left = getPaddingLeft();
-            final int right = getWidth() - getPaddingRight();
-            final int top = getPaddingTop();
-            final int bottom = getHeight() - getPaddingBottom();
-
-            final int drawWidth = mRemoteIndicator.getIntrinsicWidth();
-            final int drawHeight = mRemoteIndicator.getIntrinsicHeight();
-            final int drawLeft = left + (right - left - drawWidth) / 2;
-            final int drawTop = top + (bottom - top - drawHeight) / 2;
-
-            mRemoteIndicator.setBounds(drawLeft, drawTop,
-                    drawLeft + drawWidth, drawTop + drawHeight);
-            mRemoteIndicator.draw(canvas);
-        }
-    }
-
-    void refreshRoute() {
-        final MediaRouter.RouteInfo route = mRouter.getSelectedRoute();
-        final boolean isRemote = !route.isDefaultOrBluetooth() && route.matchesSelector(mSelector);
-        final boolean isConnecting = isRemote && route.isConnecting();
-        boolean needsRefresh = false;
-        if (mRemoteActive != isRemote) {
-            mRemoteActive = isRemote;
-            needsRefresh = true;
-        }
-        if (mIsConnecting != isConnecting) {
-            mIsConnecting = isConnecting;
-            needsRefresh = true;
-        }
-
-        if (needsRefresh) {
-            updateContentDescription();
-            refreshDrawableState();
-        }
-        if (mAttachedToWindow) {
-            setEnabled(mRouter.isRouteAvailable(mSelector,
-                    MediaRouter.AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE));
-        }
-        if (mRemoteIndicator != null
-                && mRemoteIndicator.getCurrent() instanceof AnimationDrawable) {
-            AnimationDrawable curDrawable = (AnimationDrawable) mRemoteIndicator.getCurrent();
-            if (mAttachedToWindow) {
-                if ((needsRefresh || isConnecting) && !curDrawable.isRunning()) {
-                    curDrawable.start();
-                }
-            } else if (isRemote && !isConnecting) {
-                // When the route is already connected before the view is attached, show the last
-                // frame of the connected animation immediately.
-                if (curDrawable.isRunning()) {
-                    curDrawable.stop();
-                }
-                curDrawable.selectDrawable(curDrawable.getNumberOfFrames() - 1);
-            }
-        }
-    }
-
-    private void updateContentDescription() {
-        int resId;
-        if (mIsConnecting) {
-            resId = R.string.mr_cast_button_connecting;
-        } else if (mRemoteActive) {
-            resId = R.string.mr_cast_button_connected;
-        } else {
-            resId = R.string.mr_cast_button_disconnected;
-        }
-        setContentDescription(ApiHelper.getLibResources(getContext()).getString(resId));
-    }
-
-    private final class MediaRouterCallback extends MediaRouter.Callback {
-        MediaRouterCallback() {
-        }
-
-        @Override
-        public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo info) {
-            refreshRoute();
-        }
-
-        @Override
-        public void onRouteRemoved(MediaRouter router, MediaRouter.RouteInfo info) {
-            refreshRoute();
-        }
-
-        @Override
-        public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo info) {
-            refreshRoute();
-        }
-
-        @Override
-        public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo info) {
-            refreshRoute();
-        }
-
-        @Override
-        public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo info) {
-            refreshRoute();
-        }
-
-        @Override
-        public void onProviderAdded(MediaRouter router, MediaRouter.ProviderInfo provider) {
-            refreshRoute();
-        }
-
-        @Override
-        public void onProviderRemoved(MediaRouter router, MediaRouter.ProviderInfo provider) {
-            refreshRoute();
-        }
-
-        @Override
-        public void onProviderChanged(MediaRouter router, MediaRouter.ProviderInfo provider) {
-            refreshRoute();
-        }
-    }
-
-    private final class RemoteIndicatorLoader extends AsyncTask<Void, Void, Drawable> {
-        private final int mResId;
-
-        RemoteIndicatorLoader(int resId) {
-            mResId = resId;
-        }
-
-        @Override
-        protected Drawable doInBackground(Void... params) {
-            return ApiHelper.getLibResources(getContext()).getDrawable(mResId);
-        }
-
-        @Override
-        protected void onPostExecute(Drawable remoteIndicator) {
-            cacheAndReset(remoteIndicator);
-            setRemoteIndicatorDrawable(remoteIndicator);
-        }
-
-        @Override
-        protected void onCancelled(Drawable remoteIndicator) {
-            cacheAndReset(remoteIndicator);
-        }
-
-        private void cacheAndReset(Drawable remoteIndicator) {
-            if (remoteIndicator != null) {
-                sRemoteIndicatorCache.put(mResId, remoteIndicator.getConstantState());
-            }
-            mRemoteIndicatorLoader = null;
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteChooserDialog.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteChooserDialog.java
deleted file mode 100644
index cac64d9..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteChooserDialog.java
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.app;
-
-import static com.android.support.mediarouter.media.MediaRouter.RouteInfo.CONNECTION_STATE_CONNECTED;
-import static com.android.support.mediarouter.media.MediaRouter.RouteInfo.CONNECTION_STATE_CONNECTING;
-
-import android.annotation.NonNull;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemClock;
-import android.support.v7.app.AppCompatDialog;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.ContextThemeWrapper;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.TextView;
-
-import com.android.media.update.ApiHelper;
-import com.android.media.update.R;
-import com.android.support.mediarouter.media.MediaRouteSelector;
-import com.android.support.mediarouter.media.MediaRouter;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-/**
- * This class implements the route chooser dialog for {@link MediaRouter}.
- * <p>
- * This dialog allows the user to choose a route that matches a given selector.
- * </p>
- *
- * @see MediaRouteButton
- * @see MediaRouteActionProvider
- */
-public class MediaRouteChooserDialog extends Dialog {
-    static final String TAG = "MediaRouteChooserDialog";
-
-    // Do not update the route list immediately to avoid unnatural dialog change.
-    private static final long UPDATE_ROUTES_DELAY_MS = 300L;
-    static final int MSG_UPDATE_ROUTES = 1;
-
-    private final MediaRouter mRouter;
-    private final MediaRouterCallback mCallback;
-
-    private TextView mTitleView;
-    private MediaRouteSelector mSelector = MediaRouteSelector.EMPTY;
-    private ArrayList<MediaRouter.RouteInfo> mRoutes;
-    private RouteAdapter mAdapter;
-    private ListView mListView;
-    private boolean mAttachedToWindow;
-    private long mLastUpdateTime;
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message message) {
-            switch (message.what) {
-                case MSG_UPDATE_ROUTES:
-                    updateRoutes((List<MediaRouter.RouteInfo>) message.obj);
-                    break;
-            }
-        }
-    };
-
-    public MediaRouteChooserDialog(Context context) {
-        this(context, 0);
-    }
-
-    public MediaRouteChooserDialog(Context context, int theme) {
-        // TODO (b/72975976): Avoid to use ContextThemeWrapper with app context and lib theme.
-        super(new ContextThemeWrapper(context, ApiHelper.getLibTheme(context,
-                MediaRouterThemeHelper.getRouterThemeId(context))), theme);
-        context = getContext();
-
-        mRouter = MediaRouter.getInstance(context);
-        mCallback = new MediaRouterCallback();
-    }
-
-    /**
-     * Gets the media route selector for filtering the routes that the user can select.
-     *
-     * @return The selector, never null.
-     */
-    @NonNull
-    public MediaRouteSelector getRouteSelector() {
-        return mSelector;
-    }
-
-    /**
-     * Sets the media route selector for filtering the routes that the user can select.
-     *
-     * @param selector The selector, must not be null.
-     */
-    public void setRouteSelector(@NonNull MediaRouteSelector selector) {
-        if (selector == null) {
-            throw new IllegalArgumentException("selector must not be null");
-        }
-
-        if (!mSelector.equals(selector)) {
-            mSelector = selector;
-
-            if (mAttachedToWindow) {
-                mRouter.removeCallback(mCallback);
-                mRouter.addCallback(selector, mCallback,
-                        MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
-            }
-
-            refreshRoutes();
-        }
-    }
-
-    /**
-     * Called to filter the set of routes that should be included in the list.
-     * <p>
-     * The default implementation iterates over all routes in the provided list and
-     * removes those for which {@link #onFilterRoute} returns false.
-     * </p>
-     *
-     * @param routes The list of routes to filter in-place, never null.
-     */
-    public void onFilterRoutes(@NonNull List<MediaRouter.RouteInfo> routes) {
-        for (int i = routes.size(); i-- > 0; ) {
-            if (!onFilterRoute(routes.get(i))) {
-                routes.remove(i);
-            }
-        }
-    }
-
-    /**
-     * Returns true if the route should be included in the list.
-     * <p>
-     * The default implementation returns true for enabled non-default routes that
-     * match the selector.  Subclasses can override this method to filter routes
-     * differently.
-     * </p>
-     *
-     * @param route The route to consider, never null.
-     * @return True if the route should be included in the chooser dialog.
-     */
-    public boolean onFilterRoute(@NonNull MediaRouter.RouteInfo route) {
-        return !route.isDefaultOrBluetooth() && route.isEnabled()
-                && route.matchesSelector(mSelector);
-    }
-
-    @Override
-    public void setTitle(CharSequence title) {
-        mTitleView.setText(title);
-    }
-
-    @Override
-    public void setTitle(int titleId) {
-        mTitleView.setText(titleId);
-    }
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        setContentView(ApiHelper.inflateLibLayout(getContext(), ApiHelper.getLibTheme(getContext(),
-                MediaRouterThemeHelper.getRouterThemeId(getContext())),
-                R.layout.mr_chooser_dialog));
-
-        mRoutes = new ArrayList<>();
-        mAdapter = new RouteAdapter(getContext(), mRoutes);
-        mListView = (ListView)findViewById(R.id.mr_chooser_list);
-        mListView.setAdapter(mAdapter);
-        mListView.setOnItemClickListener(mAdapter);
-        mListView.setEmptyView(findViewById(android.R.id.empty));
-        mTitleView = findViewById(R.id.mr_chooser_title);
-
-        updateLayout();
-    }
-
-    /**
-     * Sets the width of the dialog. Also called when configuration changes.
-     */
-    void updateLayout() {
-        getWindow().setLayout(MediaRouteDialogHelper.getDialogWidth(getContext()),
-                ViewGroup.LayoutParams.WRAP_CONTENT);
-    }
-
-    @Override
-    public void onAttachedToWindow() {
-        super.onAttachedToWindow();
-
-        mAttachedToWindow = true;
-        mRouter.addCallback(mSelector, mCallback, MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
-        refreshRoutes();
-    }
-
-    @Override
-    public void onDetachedFromWindow() {
-        mAttachedToWindow = false;
-        mRouter.removeCallback(mCallback);
-        mHandler.removeMessages(MSG_UPDATE_ROUTES);
-
-        super.onDetachedFromWindow();
-    }
-
-    /**
-     * Refreshes the list of routes that are shown in the chooser dialog.
-     */
-    public void refreshRoutes() {
-        if (mAttachedToWindow) {
-            ArrayList<MediaRouter.RouteInfo> routes = new ArrayList<>(mRouter.getRoutes());
-            onFilterRoutes(routes);
-            Collections.sort(routes, RouteComparator.sInstance);
-            if (SystemClock.uptimeMillis() - mLastUpdateTime >= UPDATE_ROUTES_DELAY_MS) {
-                updateRoutes(routes);
-            } else {
-                mHandler.removeMessages(MSG_UPDATE_ROUTES);
-                mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_UPDATE_ROUTES, routes),
-                        mLastUpdateTime + UPDATE_ROUTES_DELAY_MS);
-            }
-        }
-    }
-
-    void updateRoutes(List<MediaRouter.RouteInfo> routes) {
-        mLastUpdateTime = SystemClock.uptimeMillis();
-        mRoutes.clear();
-        mRoutes.addAll(routes);
-        mAdapter.notifyDataSetChanged();
-    }
-
-    private final class RouteAdapter extends ArrayAdapter<MediaRouter.RouteInfo>
-            implements ListView.OnItemClickListener {
-        private final Drawable mDefaultIcon;
-        private final Drawable mTvIcon;
-        private final Drawable mSpeakerIcon;
-        private final Drawable mSpeakerGroupIcon;
-
-        public RouteAdapter(Context context, List<MediaRouter.RouteInfo> routes) {
-            super(context, 0, routes);
-
-            TypedArray styledAttributes = ApiHelper.getLibTheme(context,
-                    MediaRouterThemeHelper.getRouterThemeId(context)).obtainStyledAttributes(
-                            new int[] {
-                                R.attr.mediaRouteDefaultIconDrawable,
-                                R.attr.mediaRouteTvIconDrawable,
-                                R.attr.mediaRouteSpeakerIconDrawable,
-                                R.attr.mediaRouteSpeakerGroupIconDrawable
-                            });
-
-            mDefaultIcon = styledAttributes.getDrawable(0);
-            mTvIcon = styledAttributes.getDrawable(1);
-            mSpeakerIcon = styledAttributes.getDrawable(2);
-            mSpeakerGroupIcon = styledAttributes.getDrawable(3);
-            styledAttributes.recycle();
-        }
-
-        @Override
-        public boolean areAllItemsEnabled() {
-            return false;
-        }
-
-        @Override
-        public boolean isEnabled(int position) {
-            return getItem(position).isEnabled();
-        }
-
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            View view = convertView;
-            if (view == null) {
-                view = ApiHelper.inflateLibLayout(getContext(),
-                        ApiHelper.getLibTheme(getContext(),
-                                MediaRouterThemeHelper.getRouterThemeId(getContext())),
-                        R.layout.mr_chooser_list_item, parent, false);
-            }
-
-            MediaRouter.RouteInfo route = getItem(position);
-            TextView text1 = (TextView) view.findViewById(R.id.mr_chooser_route_name);
-            TextView text2 = (TextView) view.findViewById(R.id.mr_chooser_route_desc);
-            text1.setText(route.getName());
-            String description = route.getDescription();
-            boolean isConnectedOrConnecting =
-                    route.getConnectionState() == CONNECTION_STATE_CONNECTED
-                            || route.getConnectionState() == CONNECTION_STATE_CONNECTING;
-            if (isConnectedOrConnecting && !TextUtils.isEmpty(description)) {
-                text1.setGravity(Gravity.BOTTOM);
-                text2.setVisibility(View.VISIBLE);
-                text2.setText(description);
-            } else {
-                text1.setGravity(Gravity.CENTER_VERTICAL);
-                text2.setVisibility(View.GONE);
-                text2.setText("");
-            }
-            view.setEnabled(route.isEnabled());
-
-            ImageView iconView = (ImageView) view.findViewById(R.id.mr_chooser_route_icon);
-            if (iconView != null) {
-                iconView.setImageDrawable(getIconDrawable(route));
-            }
-            return view;
-        }
-
-        @Override
-        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-            MediaRouter.RouteInfo route = getItem(position);
-            if (route.isEnabled()) {
-                route.select();
-                dismiss();
-            }
-        }
-
-        private Drawable getIconDrawable(MediaRouter.RouteInfo route) {
-            Uri iconUri = route.getIconUri();
-            if (iconUri != null) {
-                try {
-                    InputStream is = getContext().getContentResolver().openInputStream(iconUri);
-                    Drawable drawable = Drawable.createFromStream(is, null);
-                    if (drawable != null) {
-                        return drawable;
-                    }
-                } catch (IOException e) {
-                    Log.w(TAG, "Failed to load " + iconUri, e);
-                    // Falls back.
-                }
-            }
-            return getDefaultIconDrawable(route);
-        }
-
-        private Drawable getDefaultIconDrawable(MediaRouter.RouteInfo route) {
-            // If the type of the receiver device is specified, use it.
-            switch (route.getDeviceType()) {
-                case  MediaRouter.RouteInfo.DEVICE_TYPE_TV:
-                    return mTvIcon;
-                case MediaRouter.RouteInfo.DEVICE_TYPE_SPEAKER:
-                    return mSpeakerIcon;
-            }
-
-            // Otherwise, make the best guess based on other route information.
-            if (route instanceof MediaRouter.RouteGroup) {
-                // Only speakers can be grouped for now.
-                return mSpeakerGroupIcon;
-            }
-            return mDefaultIcon;
-        }
-    }
-
-    private final class MediaRouterCallback extends MediaRouter.Callback {
-        MediaRouterCallback() {
-        }
-
-        @Override
-        public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo info) {
-            refreshRoutes();
-        }
-
-        @Override
-        public void onRouteRemoved(MediaRouter router, MediaRouter.RouteInfo info) {
-            refreshRoutes();
-        }
-
-        @Override
-        public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo info) {
-            refreshRoutes();
-        }
-
-        @Override
-        public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo route) {
-            dismiss();
-        }
-    }
-
-    static final class RouteComparator implements Comparator<MediaRouter.RouteInfo> {
-        public static final RouteComparator sInstance = new RouteComparator();
-
-        @Override
-        public int compare(MediaRouter.RouteInfo lhs, MediaRouter.RouteInfo rhs) {
-            return lhs.getName().compareToIgnoreCase(rhs.getName());
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteChooserDialogFragment.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteChooserDialogFragment.java
deleted file mode 100644
index 65e6b29..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteChooserDialogFragment.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.app;
-
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.os.Bundle;
-
-import com.android.support.mediarouter.media.MediaRouteSelector;
-
-/**
- * Media route chooser dialog fragment.
- * <p>
- * Creates a {@link MediaRouteChooserDialog}.  The application may subclass
- * this dialog fragment to customize the media route chooser dialog.
- * </p>
- */
-public class MediaRouteChooserDialogFragment extends DialogFragment {
-    private final String ARGUMENT_SELECTOR = "selector";
-
-    private MediaRouteChooserDialog mDialog;
-    private MediaRouteSelector mSelector;
-
-    /**
-     * Creates a media route chooser dialog fragment.
-     * <p>
-     * All subclasses of this class must also possess a default constructor.
-     * </p>
-     */
-    public MediaRouteChooserDialogFragment() {
-        setCancelable(true);
-    }
-
-    /**
-     * Gets the media route selector for filtering the routes that the user can select.
-     *
-     * @return The selector, never null.
-     */
-    public MediaRouteSelector getRouteSelector() {
-        ensureRouteSelector();
-        return mSelector;
-    }
-
-    private void ensureRouteSelector() {
-        if (mSelector == null) {
-            Bundle args = getArguments();
-            if (args != null) {
-                mSelector = MediaRouteSelector.fromBundle(args.getBundle(ARGUMENT_SELECTOR));
-            }
-            if (mSelector == null) {
-                mSelector = MediaRouteSelector.EMPTY;
-            }
-        }
-    }
-
-    /**
-     * Sets the media route selector for filtering the routes that the user can select.
-     * This method must be called before the fragment is added.
-     *
-     * @param selector The selector to set.
-     */
-    public void setRouteSelector(MediaRouteSelector selector) {
-        if (selector == null) {
-            throw new IllegalArgumentException("selector must not be null");
-        }
-
-        ensureRouteSelector();
-        if (!mSelector.equals(selector)) {
-            mSelector = selector;
-
-            Bundle args = getArguments();
-            if (args == null) {
-                args = new Bundle();
-            }
-            args.putBundle(ARGUMENT_SELECTOR, selector.asBundle());
-            setArguments(args);
-
-            MediaRouteChooserDialog dialog = (MediaRouteChooserDialog)getDialog();
-            if (dialog != null) {
-                dialog.setRouteSelector(selector);
-            }
-        }
-    }
-
-    /**
-     * Called when the chooser dialog is being created.
-     * <p>
-     * Subclasses may override this method to customize the dialog.
-     * </p>
-     */
-    public MediaRouteChooserDialog onCreateChooserDialog(
-            Context context, Bundle savedInstanceState) {
-        return new MediaRouteChooserDialog(context);
-    }
-
-    @Override
-    public Dialog onCreateDialog(Bundle savedInstanceState) {
-        mDialog = onCreateChooserDialog(getContext(), savedInstanceState);
-        mDialog.setRouteSelector(getRouteSelector());
-        return mDialog;
-    }
-
-    @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        if (mDialog != null) {
-            mDialog.updateLayout();
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteControllerDialog.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteControllerDialog.java
deleted file mode 100644
index 060cfca..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteControllerDialog.java
+++ /dev/null
@@ -1,1486 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.app;
-
-import static android.support.v4.media.session.PlaybackStateCompat.ACTION_PAUSE;
-import static android.support.v4.media.session.PlaybackStateCompat.ACTION_PLAY;
-import static android.support.v4.media.session.PlaybackStateCompat.ACTION_PLAY_PAUSE;
-import static android.support.v4.media.session.PlaybackStateCompat.ACTION_STOP;
-
-import android.app.AlertDialog;
-import android.app.PendingIntent;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Rect;
-import android.graphics.drawable.BitmapDrawable;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.support.v4.media.MediaDescriptionCompat;
-import android.support.v4.media.MediaMetadataCompat;
-import android.support.v4.media.session.MediaControllerCompat;
-import android.support.v4.media.session.MediaSessionCompat;
-import android.support.v4.media.session.PlaybackStateCompat;
-import android.support.v4.util.ObjectsCompat;
-import android.support.v4.view.accessibility.AccessibilityEventCompat;
-import android.support.v7.graphics.Palette;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.ContextThemeWrapper;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.MeasureSpec;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-import android.view.animation.AccelerateDecelerateInterpolator;
-import android.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
-import android.view.animation.AnimationSet;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-import android.view.animation.Transformation;
-import android.view.animation.TranslateAnimation;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.FrameLayout;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.RelativeLayout;
-import android.widget.SeekBar;
-import android.widget.TextView;
-
-import com.android.media.update.ApiHelper;
-import com.android.media.update.R;
-import com.android.support.mediarouter.media.MediaRouteSelector;
-import com.android.support.mediarouter.media.MediaRouter;
-import com.android.support.mediarouter.app.OverlayListView.OverlayObject;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-/**
- * This class implements the route controller dialog for {@link MediaRouter}.
- * <p>
- * This dialog allows the user to control or disconnect from the currently selected route.
- * </p>
- *
- * @see MediaRouteButton
- * @see MediaRouteActionProvider
- */
-public class MediaRouteControllerDialog extends AlertDialog {
-    // Tags should be less than 24 characters long (see docs for android.util.Log.isLoggable())
-    static final String TAG = "MediaRouteCtrlDialog";
-    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    // Time to wait before updating the volume when the user lets go of the seek bar
-    // to allow the route provider time to propagate the change and publish a new
-    // route descriptor.
-    static final int VOLUME_UPDATE_DELAY_MILLIS = 500;
-    static final int CONNECTION_TIMEOUT_MILLIS = (int) TimeUnit.SECONDS.toMillis(30L);
-
-    private static final int BUTTON_NEUTRAL_RES_ID = android.R.id.button3;
-    static final int BUTTON_DISCONNECT_RES_ID = android.R.id.button2;
-    static final int BUTTON_STOP_RES_ID = android.R.id.button1;
-
-    final MediaRouter mRouter;
-    private final MediaRouterCallback mCallback;
-    final MediaRouter.RouteInfo mRoute;
-
-    Context mContext;
-    private boolean mCreated;
-    private boolean mAttachedToWindow;
-
-    private int mDialogContentWidth;
-
-    private View mCustomControlView;
-
-    private Button mDisconnectButton;
-    private Button mStopCastingButton;
-    private ImageButton mPlaybackControlButton;
-    private ImageButton mCloseButton;
-    private MediaRouteExpandCollapseButton mGroupExpandCollapseButton;
-
-    private FrameLayout mExpandableAreaLayout;
-    private LinearLayout mDialogAreaLayout;
-    FrameLayout mDefaultControlLayout;
-    private FrameLayout mCustomControlLayout;
-    private ImageView mArtView;
-    private TextView mTitleView;
-    private TextView mSubtitleView;
-    private TextView mRouteNameTextView;
-
-    private boolean mVolumeControlEnabled = true;
-    // Layout for media controllers including play/pause button and the main volume slider.
-    private LinearLayout mMediaMainControlLayout;
-    private RelativeLayout mPlaybackControlLayout;
-    private LinearLayout mVolumeControlLayout;
-    private View mDividerView;
-
-    OverlayListView mVolumeGroupList;
-    VolumeGroupAdapter mVolumeGroupAdapter;
-    private List<MediaRouter.RouteInfo> mGroupMemberRoutes;
-    Set<MediaRouter.RouteInfo> mGroupMemberRoutesAdded;
-    private Set<MediaRouter.RouteInfo> mGroupMemberRoutesRemoved;
-    Set<MediaRouter.RouteInfo> mGroupMemberRoutesAnimatingWithBitmap;
-    SeekBar mVolumeSlider;
-    VolumeChangeListener mVolumeChangeListener;
-    MediaRouter.RouteInfo mRouteInVolumeSliderTouched;
-    private int mVolumeGroupListItemIconSize;
-    private int mVolumeGroupListItemHeight;
-    private int mVolumeGroupListMaxHeight;
-    private final int mVolumeGroupListPaddingTop;
-    Map<MediaRouter.RouteInfo, SeekBar> mVolumeSliderMap;
-
-    MediaControllerCompat mMediaController;
-    MediaControllerCallback mControllerCallback;
-    PlaybackStateCompat mState;
-    MediaDescriptionCompat mDescription;
-
-    FetchArtTask mFetchArtTask;
-    Bitmap mArtIconBitmap;
-    Uri mArtIconUri;
-    boolean mArtIconIsLoaded;
-    Bitmap mArtIconLoadedBitmap;
-    int mArtIconBackgroundColor;
-
-    boolean mHasPendingUpdate;
-    boolean mPendingUpdateAnimationNeeded;
-
-    boolean mIsGroupExpanded;
-    boolean mIsGroupListAnimating;
-    boolean mIsGroupListAnimationPending;
-    int mGroupListAnimationDurationMs;
-    private int mGroupListFadeInDurationMs;
-    private int mGroupListFadeOutDurationMs;
-
-    private Interpolator mInterpolator;
-    private Interpolator mLinearOutSlowInInterpolator;
-    private Interpolator mFastOutSlowInInterpolator;
-    private Interpolator mAccelerateDecelerateInterpolator;
-
-    final AccessibilityManager mAccessibilityManager;
-
-    Runnable mGroupListFadeInAnimation = new Runnable() {
-        @Override
-        public void run() {
-            startGroupListFadeInAnimation();
-        }
-    };
-
-    public MediaRouteControllerDialog(Context context) {
-        this(context, 0);
-    }
-
-    public MediaRouteControllerDialog(Context context, int theme) {
-        // TODO (b/72975976): Avoid to use ContextThemeWrapper with app context and lib theme.
-        super(new ContextThemeWrapper(context, ApiHelper.getLibTheme(context,
-                MediaRouterThemeHelper.getRouterThemeId(context))), theme);
-        mContext = getContext();
-
-        mControllerCallback = new MediaControllerCallback();
-        mRouter = MediaRouter.getInstance(mContext);
-        mCallback = new MediaRouterCallback();
-        mRoute = mRouter.getSelectedRoute();
-        setMediaSession(mRouter.getMediaSessionToken());
-        mVolumeGroupListPaddingTop = ApiHelper.getLibResources(context).getDimensionPixelSize(
-                R.dimen.mr_controller_volume_group_list_padding_top);
-        mAccessibilityManager =
-                (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
-        mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(
-                mContext, android.R.interpolator.linear_out_slow_in);
-        mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(
-                mContext, android.R.interpolator.fast_out_slow_in);
-        mAccelerateDecelerateInterpolator = new AccelerateDecelerateInterpolator();
-    }
-
-    /**
-     * Gets the route that this dialog is controlling.
-     */
-    public MediaRouter.RouteInfo getRoute() {
-        return mRoute;
-    }
-
-    private MediaRouter.RouteGroup getGroup() {
-        if (mRoute instanceof MediaRouter.RouteGroup) {
-            return (MediaRouter.RouteGroup) mRoute;
-        }
-        return null;
-    }
-
-    /**
-     * Provides the subclass an opportunity to create a view that will replace the default media
-     * controls for the currently playing content.
-     *
-     * @param savedInstanceState The dialog's saved instance state.
-     * @return The media control view, or null if none.
-     */
-    public View onCreateMediaControlView(Bundle savedInstanceState) {
-        return null;
-    }
-
-    /**
-     * Gets the media control view that was created by {@link #onCreateMediaControlView(Bundle)}.
-     *
-     * @return The media control view, or null if none.
-     */
-    public View getMediaControlView() {
-        return mCustomControlView;
-    }
-
-    /**
-     * Sets whether to enable the volume slider and volume control using the volume keys
-     * when the route supports it.
-     * <p>
-     * The default value is true.
-     * </p>
-     */
-    public void setVolumeControlEnabled(boolean enable) {
-        if (mVolumeControlEnabled != enable) {
-            mVolumeControlEnabled = enable;
-            if (mCreated) {
-                update(false);
-            }
-        }
-    }
-
-    /**
-     * Returns whether to enable the volume slider and volume control using the volume keys
-     * when the route supports it.
-     */
-    public boolean isVolumeControlEnabled() {
-        return mVolumeControlEnabled;
-    }
-
-    /**
-     * Set the session to use for metadata and transport controls. The dialog
-     * will listen to changes on this session and update the UI automatically in
-     * response to changes.
-     *
-     * @param sessionToken The token for the session to use.
-     */
-    private void setMediaSession(MediaSessionCompat.Token sessionToken) {
-        if (mMediaController != null) {
-            mMediaController.unregisterCallback(mControllerCallback);
-            mMediaController = null;
-        }
-        if (sessionToken == null) {
-            return;
-        }
-        if (!mAttachedToWindow) {
-            return;
-        }
-        try {
-            mMediaController = new MediaControllerCompat(mContext, sessionToken);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error creating media controller in setMediaSession.", e);
-        }
-        if (mMediaController != null) {
-            mMediaController.registerCallback(mControllerCallback);
-        }
-        MediaMetadataCompat metadata = mMediaController == null ? null
-                : mMediaController.getMetadata();
-        mDescription = metadata == null ? null : metadata.getDescription();
-        mState = mMediaController == null ? null : mMediaController.getPlaybackState();
-        updateArtIconIfNeeded();
-        update(false);
-    }
-
-    /**
-     * Gets the session to use for metadata and transport controls.
-     *
-     * @return The token for the session to use or null if none.
-     */
-    public MediaSessionCompat.Token getMediaSession() {
-        return mMediaController == null ? null : mMediaController.getSessionToken();
-    }
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        getWindow().setBackgroundDrawableResource(android.R.color.transparent);
-
-        setContentView(ApiHelper.inflateLibLayout(mContext,
-                ApiHelper.getLibTheme(mContext, MediaRouterThemeHelper.getRouterThemeId(mContext)),
-                R.layout.mr_controller_material_dialog_b));
-
-        // Remove the neutral button.
-        findViewById(BUTTON_NEUTRAL_RES_ID).setVisibility(View.GONE);
-
-        ClickListener listener = new ClickListener();
-
-        mExpandableAreaLayout = findViewById(R.id.mr_expandable_area);
-        mExpandableAreaLayout.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                dismiss();
-            }
-        });
-        mDialogAreaLayout = findViewById(R.id.mr_dialog_area);
-        mDialogAreaLayout.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                // Eat unhandled touch events.
-            }
-        });
-        int color = MediaRouterThemeHelper.getButtonTextColor(mContext);
-        mDisconnectButton = findViewById(BUTTON_DISCONNECT_RES_ID);
-        mDisconnectButton.setText(
-                ApiHelper.getLibResources(mContext).getString(R.string.mr_controller_disconnect));
-        mDisconnectButton.setTextColor(color);
-        mDisconnectButton.setOnClickListener(listener);
-
-        mStopCastingButton = findViewById(BUTTON_STOP_RES_ID);
-        mStopCastingButton.setText(
-                ApiHelper.getLibResources(mContext).getString(R.string.mr_controller_stop_casting));
-        mStopCastingButton.setTextColor(color);
-        mStopCastingButton.setOnClickListener(listener);
-
-        mRouteNameTextView = findViewById(R.id.mr_name);
-        mCloseButton = findViewById(R.id.mr_close);
-        mCloseButton.setOnClickListener(listener);
-        mCustomControlLayout = findViewById(R.id.mr_custom_control);
-        mDefaultControlLayout = findViewById(R.id.mr_default_control);
-
-        // Start the session activity when a content item (album art, title or subtitle) is clicked.
-        View.OnClickListener onClickListener = new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                if (mMediaController != null) {
-                    PendingIntent pi = mMediaController.getSessionActivity();
-                    if (pi != null) {
-                        try {
-                            pi.send();
-                            dismiss();
-                        } catch (PendingIntent.CanceledException e) {
-                            Log.e(TAG, pi + " was not sent, it had been canceled.");
-                        }
-                    }
-                }
-            }
-        };
-        mArtView = findViewById(R.id.mr_art);
-        mArtView.setOnClickListener(onClickListener);
-        findViewById(R.id.mr_control_title_container).setOnClickListener(onClickListener);
-
-        mMediaMainControlLayout = findViewById(R.id.mr_media_main_control);
-        mDividerView = findViewById(R.id.mr_control_divider);
-
-        mPlaybackControlLayout = findViewById(R.id.mr_playback_control);
-        mTitleView = findViewById(R.id.mr_control_title);
-        mSubtitleView = findViewById(R.id.mr_control_subtitle);
-        mPlaybackControlButton = findViewById(R.id.mr_control_playback_ctrl);
-        mPlaybackControlButton.setOnClickListener(listener);
-
-        mVolumeControlLayout = findViewById(R.id.mr_volume_control);
-        mVolumeControlLayout.setVisibility(View.GONE);
-        mVolumeSlider = findViewById(R.id.mr_volume_slider);
-        mVolumeSlider.setTag(mRoute);
-        mVolumeChangeListener = new VolumeChangeListener();
-        mVolumeSlider.setOnSeekBarChangeListener(mVolumeChangeListener);
-
-        mVolumeGroupList = findViewById(R.id.mr_volume_group_list);
-        mGroupMemberRoutes = new ArrayList<MediaRouter.RouteInfo>();
-        mVolumeGroupAdapter = new VolumeGroupAdapter(mVolumeGroupList.getContext(),
-                mGroupMemberRoutes);
-        mVolumeGroupList.setAdapter(mVolumeGroupAdapter);
-        mGroupMemberRoutesAnimatingWithBitmap = new HashSet<>();
-
-        MediaRouterThemeHelper.setMediaControlsBackgroundColor(mContext,
-                mMediaMainControlLayout, mVolumeGroupList, getGroup() != null);
-        MediaRouterThemeHelper.setVolumeSliderColor(mContext,
-                (MediaRouteVolumeSlider) mVolumeSlider, mMediaMainControlLayout);
-        mVolumeSliderMap = new HashMap<>();
-        mVolumeSliderMap.put(mRoute, mVolumeSlider);
-
-        mGroupExpandCollapseButton =
-                findViewById(R.id.mr_group_expand_collapse);
-        mGroupExpandCollapseButton.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                mIsGroupExpanded = !mIsGroupExpanded;
-                if (mIsGroupExpanded) {
-                    mVolumeGroupList.setVisibility(View.VISIBLE);
-                }
-                loadInterpolator();
-                updateLayoutHeight(true);
-            }
-        });
-        loadInterpolator();
-        mGroupListAnimationDurationMs = ApiHelper.getLibResources(mContext).getInteger(
-                R.integer.mr_controller_volume_group_list_animation_duration_ms);
-        mGroupListFadeInDurationMs = ApiHelper.getLibResources(mContext).getInteger(
-                R.integer.mr_controller_volume_group_list_fade_in_duration_ms);
-        mGroupListFadeOutDurationMs = ApiHelper.getLibResources(mContext).getInteger(
-                R.integer.mr_controller_volume_group_list_fade_out_duration_ms);
-
-        mCustomControlView = onCreateMediaControlView(savedInstanceState);
-        if (mCustomControlView != null) {
-            mCustomControlLayout.addView(mCustomControlView);
-            mCustomControlLayout.setVisibility(View.VISIBLE);
-        }
-        mCreated = true;
-        updateLayout();
-    }
-
-    /**
-     * Sets the width of the dialog. Also called when configuration changes.
-     */
-    void updateLayout() {
-        int width = MediaRouteDialogHelper.getDialogWidth(mContext);
-        getWindow().setLayout(width, ViewGroup.LayoutParams.WRAP_CONTENT);
-
-        View decorView = getWindow().getDecorView();
-        mDialogContentWidth = width - decorView.getPaddingLeft() - decorView.getPaddingRight();
-
-        Resources res = ApiHelper.getLibResources(mContext);
-        mVolumeGroupListItemIconSize = res.getDimensionPixelSize(
-                R.dimen.mr_controller_volume_group_list_item_icon_size);
-        mVolumeGroupListItemHeight = res.getDimensionPixelSize(
-                R.dimen.mr_controller_volume_group_list_item_height);
-        mVolumeGroupListMaxHeight = res.getDimensionPixelSize(
-                R.dimen.mr_controller_volume_group_list_max_height);
-
-        // Fetch art icons again for layout changes to resize it accordingly
-        mArtIconBitmap = null;
-        mArtIconUri = null;
-        updateArtIconIfNeeded();
-        update(false);
-    }
-
-    @Override
-    public void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        mAttachedToWindow = true;
-
-        mRouter.addCallback(MediaRouteSelector.EMPTY, mCallback,
-                MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS);
-        setMediaSession(mRouter.getMediaSessionToken());
-    }
-
-    @Override
-    public void onDetachedFromWindow() {
-        mRouter.removeCallback(mCallback);
-        setMediaSession(null);
-        mAttachedToWindow = false;
-        super.onDetachedFromWindow();
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
-                || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
-            mRoute.requestUpdateVolume(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ? -1 : 1);
-            return true;
-        }
-        return super.onKeyDown(keyCode, event);
-    }
-
-    @Override
-    public boolean onKeyUp(int keyCode, KeyEvent event) {
-        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
-                || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
-            return true;
-        }
-        return super.onKeyUp(keyCode, event);
-    }
-
-    void update(boolean animate) {
-        // Defer dialog updates if a user is adjusting a volume in the list
-        if (mRouteInVolumeSliderTouched != null) {
-            mHasPendingUpdate = true;
-            mPendingUpdateAnimationNeeded |= animate;
-            return;
-        }
-        mHasPendingUpdate = false;
-        mPendingUpdateAnimationNeeded = false;
-        if (!mRoute.isSelected() || mRoute.isDefaultOrBluetooth()) {
-            dismiss();
-            return;
-        }
-        if (!mCreated) {
-            return;
-        }
-
-        mRouteNameTextView.setText(mRoute.getName());
-        mDisconnectButton.setVisibility(mRoute.canDisconnect() ? View.VISIBLE : View.GONE);
-        if (mCustomControlView == null && mArtIconIsLoaded) {
-            if (isBitmapRecycled(mArtIconLoadedBitmap)) {
-                Log.w(TAG, "Can't set artwork image with recycled bitmap: " + mArtIconLoadedBitmap);
-            } else {
-                mArtView.setImageBitmap(mArtIconLoadedBitmap);
-                mArtView.setBackgroundColor(mArtIconBackgroundColor);
-            }
-            clearLoadedBitmap();
-        }
-        updateVolumeControlLayout();
-        updatePlaybackControlLayout();
-        updateLayoutHeight(animate);
-    }
-
-    private boolean isBitmapRecycled(Bitmap bitmap) {
-        return bitmap != null && bitmap.isRecycled();
-    }
-
-    private boolean canShowPlaybackControlLayout() {
-        return mCustomControlView == null && (mDescription != null || mState != null);
-    }
-
-    /**
-     * Returns the height of main media controller which includes playback control and master
-     * volume control.
-     */
-    private int getMainControllerHeight(boolean showPlaybackControl) {
-        int height = 0;
-        if (showPlaybackControl || mVolumeControlLayout.getVisibility() == View.VISIBLE) {
-            height += mMediaMainControlLayout.getPaddingTop()
-                    + mMediaMainControlLayout.getPaddingBottom();
-            if (showPlaybackControl) {
-                height +=  mPlaybackControlLayout.getMeasuredHeight();
-            }
-            if (mVolumeControlLayout.getVisibility() == View.VISIBLE) {
-                height += mVolumeControlLayout.getMeasuredHeight();
-            }
-            if (showPlaybackControl && mVolumeControlLayout.getVisibility() == View.VISIBLE) {
-                height += mDividerView.getMeasuredHeight();
-            }
-        }
-        return height;
-    }
-
-    private void updateMediaControlVisibility(boolean canShowPlaybackControlLayout) {
-        // TODO: Update the top and bottom padding of the control layout according to the display
-        // height.
-        mDividerView.setVisibility((mVolumeControlLayout.getVisibility() == View.VISIBLE
-                && canShowPlaybackControlLayout) ? View.VISIBLE : View.GONE);
-        mMediaMainControlLayout.setVisibility((mVolumeControlLayout.getVisibility() == View.GONE
-                && !canShowPlaybackControlLayout) ? View.GONE : View.VISIBLE);
-    }
-
-    void updateLayoutHeight(final boolean animate) {
-        // We need to defer the update until the first layout has occurred, as we don't yet know the
-        // overall visible display size in which the window this view is attached to has been
-        // positioned in.
-        mDefaultControlLayout.requestLayout();
-        ViewTreeObserver observer = mDefaultControlLayout.getViewTreeObserver();
-        observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
-            @Override
-            public void onGlobalLayout() {
-                mDefaultControlLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
-                if (mIsGroupListAnimating) {
-                    mIsGroupListAnimationPending = true;
-                } else {
-                    updateLayoutHeightInternal(animate);
-                }
-            }
-        });
-    }
-
-    /**
-     * Updates the height of views and hide artwork or metadata if space is limited.
-     */
-    void updateLayoutHeightInternal(boolean animate) {
-        // Measure the size of widgets and get the height of main components.
-        int oldHeight = getLayoutHeight(mMediaMainControlLayout);
-        setLayoutHeight(mMediaMainControlLayout, ViewGroup.LayoutParams.MATCH_PARENT);
-        updateMediaControlVisibility(canShowPlaybackControlLayout());
-        View decorView = getWindow().getDecorView();
-        decorView.measure(
-                MeasureSpec.makeMeasureSpec(getWindow().getAttributes().width, MeasureSpec.EXACTLY),
-                MeasureSpec.UNSPECIFIED);
-        setLayoutHeight(mMediaMainControlLayout, oldHeight);
-        int artViewHeight = 0;
-        if (mCustomControlView == null && mArtView.getDrawable() instanceof BitmapDrawable) {
-            Bitmap art = ((BitmapDrawable) mArtView.getDrawable()).getBitmap();
-            if (art != null) {
-                artViewHeight = getDesiredArtHeight(art.getWidth(), art.getHeight());
-                mArtView.setScaleType(art.getWidth() >= art.getHeight()
-                        ? ImageView.ScaleType.FIT_XY : ImageView.ScaleType.FIT_CENTER);
-            }
-        }
-        int mainControllerHeight = getMainControllerHeight(canShowPlaybackControlLayout());
-        int volumeGroupListCount = mGroupMemberRoutes.size();
-        // Scale down volume group list items in landscape mode.
-        int expandedGroupListHeight = getGroup() == null ? 0 :
-                mVolumeGroupListItemHeight * getGroup().getRoutes().size();
-        if (volumeGroupListCount > 0) {
-            expandedGroupListHeight += mVolumeGroupListPaddingTop;
-        }
-        expandedGroupListHeight = Math.min(expandedGroupListHeight, mVolumeGroupListMaxHeight);
-        int visibleGroupListHeight = mIsGroupExpanded ? expandedGroupListHeight : 0;
-
-        int desiredControlLayoutHeight =
-                Math.max(artViewHeight, visibleGroupListHeight) + mainControllerHeight;
-        Rect visibleRect = new Rect();
-        decorView.getWindowVisibleDisplayFrame(visibleRect);
-        // Height of non-control views in decor view.
-        // This includes title bar, button bar, and dialog's vertical padding which should be
-        // always shown.
-        int nonControlViewHeight = mDialogAreaLayout.getMeasuredHeight()
-                - mDefaultControlLayout.getMeasuredHeight();
-        // Maximum allowed height for controls to fit screen.
-        int maximumControlViewHeight = visibleRect.height() - nonControlViewHeight;
-
-        // Show artwork if it fits the screen.
-        if (mCustomControlView == null && artViewHeight > 0
-                && desiredControlLayoutHeight <= maximumControlViewHeight) {
-            mArtView.setVisibility(View.VISIBLE);
-            setLayoutHeight(mArtView, artViewHeight);
-        } else {
-            if (getLayoutHeight(mVolumeGroupList) + mMediaMainControlLayout.getMeasuredHeight()
-                    >= mDefaultControlLayout.getMeasuredHeight()) {
-                mArtView.setVisibility(View.GONE);
-            }
-            artViewHeight = 0;
-            desiredControlLayoutHeight = visibleGroupListHeight + mainControllerHeight;
-        }
-        // Show the playback control if it fits the screen.
-        if (canShowPlaybackControlLayout()
-                && desiredControlLayoutHeight <= maximumControlViewHeight) {
-            mPlaybackControlLayout.setVisibility(View.VISIBLE);
-        } else {
-            mPlaybackControlLayout.setVisibility(View.GONE);
-        }
-        updateMediaControlVisibility(mPlaybackControlLayout.getVisibility() == View.VISIBLE);
-        mainControllerHeight = getMainControllerHeight(
-                mPlaybackControlLayout.getVisibility() == View.VISIBLE);
-        desiredControlLayoutHeight =
-                Math.max(artViewHeight, visibleGroupListHeight) + mainControllerHeight;
-
-        // Limit the volume group list height to fit the screen.
-        if (desiredControlLayoutHeight > maximumControlViewHeight) {
-            visibleGroupListHeight -= (desiredControlLayoutHeight - maximumControlViewHeight);
-            desiredControlLayoutHeight = maximumControlViewHeight;
-        }
-        // Update the layouts with the computed heights.
-        mMediaMainControlLayout.clearAnimation();
-        mVolumeGroupList.clearAnimation();
-        mDefaultControlLayout.clearAnimation();
-        if (animate) {
-            animateLayoutHeight(mMediaMainControlLayout, mainControllerHeight);
-            animateLayoutHeight(mVolumeGroupList, visibleGroupListHeight);
-            animateLayoutHeight(mDefaultControlLayout, desiredControlLayoutHeight);
-        } else {
-            setLayoutHeight(mMediaMainControlLayout, mainControllerHeight);
-            setLayoutHeight(mVolumeGroupList, visibleGroupListHeight);
-            setLayoutHeight(mDefaultControlLayout, desiredControlLayoutHeight);
-        }
-        // Maximize the window size with a transparent layout in advance for smooth animation.
-        setLayoutHeight(mExpandableAreaLayout, visibleRect.height());
-        rebuildVolumeGroupList(animate);
-    }
-
-    void updateVolumeGroupItemHeight(View item) {
-        LinearLayout container = (LinearLayout) item.findViewById(R.id.volume_item_container);
-        setLayoutHeight(container, mVolumeGroupListItemHeight);
-        View icon = item.findViewById(R.id.mr_volume_item_icon);
-        ViewGroup.LayoutParams lp = icon.getLayoutParams();
-        lp.width = mVolumeGroupListItemIconSize;
-        lp.height = mVolumeGroupListItemIconSize;
-        icon.setLayoutParams(lp);
-    }
-
-    private void animateLayoutHeight(final View view, int targetHeight) {
-        final int startValue = getLayoutHeight(view);
-        final int endValue = targetHeight;
-        Animation anim = new Animation() {
-            @Override
-            protected void applyTransformation(float interpolatedTime, Transformation t) {
-                int height = startValue - (int) ((startValue - endValue) * interpolatedTime);
-                setLayoutHeight(view, height);
-            }
-        };
-        anim.setDuration(mGroupListAnimationDurationMs);
-        if (android.os.Build.VERSION.SDK_INT >= 21) {
-            anim.setInterpolator(mInterpolator);
-        }
-        view.startAnimation(anim);
-    }
-
-    void loadInterpolator() {
-        mInterpolator =
-                mIsGroupExpanded ? mLinearOutSlowInInterpolator : mFastOutSlowInInterpolator;
-    }
-
-    private void updateVolumeControlLayout() {
-        if (isVolumeControlAvailable(mRoute)) {
-            if (mVolumeControlLayout.getVisibility() == View.GONE) {
-                mVolumeControlLayout.setVisibility(View.VISIBLE);
-                mVolumeSlider.setMax(mRoute.getVolumeMax());
-                mVolumeSlider.setProgress(mRoute.getVolume());
-                mGroupExpandCollapseButton.setVisibility(getGroup() == null ? View.GONE
-                        : View.VISIBLE);
-            }
-        } else {
-            mVolumeControlLayout.setVisibility(View.GONE);
-        }
-    }
-
-    private void rebuildVolumeGroupList(boolean animate) {
-        List<MediaRouter.RouteInfo> routes = getGroup() == null ? null : getGroup().getRoutes();
-        if (routes == null) {
-            mGroupMemberRoutes.clear();
-            mVolumeGroupAdapter.notifyDataSetChanged();
-        } else if (MediaRouteDialogHelper.listUnorderedEquals(mGroupMemberRoutes, routes)) {
-            mVolumeGroupAdapter.notifyDataSetChanged();
-        } else {
-            HashMap<MediaRouter.RouteInfo, Rect> previousRouteBoundMap = animate
-                    ? MediaRouteDialogHelper.getItemBoundMap(mVolumeGroupList, mVolumeGroupAdapter)
-                    : null;
-            HashMap<MediaRouter.RouteInfo, BitmapDrawable> previousRouteBitmapMap = animate
-                    ? MediaRouteDialogHelper.getItemBitmapMap(mContext, mVolumeGroupList,
-                            mVolumeGroupAdapter) : null;
-            mGroupMemberRoutesAdded =
-                    MediaRouteDialogHelper.getItemsAdded(mGroupMemberRoutes, routes);
-            mGroupMemberRoutesRemoved = MediaRouteDialogHelper.getItemsRemoved(mGroupMemberRoutes,
-                    routes);
-            mGroupMemberRoutes.addAll(0, mGroupMemberRoutesAdded);
-            mGroupMemberRoutes.removeAll(mGroupMemberRoutesRemoved);
-            mVolumeGroupAdapter.notifyDataSetChanged();
-            if (animate && mIsGroupExpanded
-                    && mGroupMemberRoutesAdded.size() + mGroupMemberRoutesRemoved.size() > 0) {
-                animateGroupListItems(previousRouteBoundMap, previousRouteBitmapMap);
-            } else {
-                mGroupMemberRoutesAdded = null;
-                mGroupMemberRoutesRemoved = null;
-            }
-        }
-    }
-
-    private void animateGroupListItems(final Map<MediaRouter.RouteInfo, Rect> previousRouteBoundMap,
-            final Map<MediaRouter.RouteInfo, BitmapDrawable> previousRouteBitmapMap) {
-        mVolumeGroupList.setEnabled(false);
-        mVolumeGroupList.requestLayout();
-        mIsGroupListAnimating = true;
-        ViewTreeObserver observer = mVolumeGroupList.getViewTreeObserver();
-        observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
-            @Override
-            public void onGlobalLayout() {
-                mVolumeGroupList.getViewTreeObserver().removeGlobalOnLayoutListener(this);
-                animateGroupListItemsInternal(previousRouteBoundMap, previousRouteBitmapMap);
-            }
-        });
-    }
-
-    void animateGroupListItemsInternal(
-            Map<MediaRouter.RouteInfo, Rect> previousRouteBoundMap,
-            Map<MediaRouter.RouteInfo, BitmapDrawable> previousRouteBitmapMap) {
-        if (mGroupMemberRoutesAdded == null || mGroupMemberRoutesRemoved == null) {
-            return;
-        }
-        int groupSizeDelta = mGroupMemberRoutesAdded.size() - mGroupMemberRoutesRemoved.size();
-        boolean listenerRegistered = false;
-        Animation.AnimationListener listener = new Animation.AnimationListener() {
-            @Override
-            public void onAnimationStart(Animation animation) {
-                mVolumeGroupList.startAnimationAll();
-                mVolumeGroupList.postDelayed(mGroupListFadeInAnimation,
-                        mGroupListAnimationDurationMs);
-            }
-
-            @Override
-            public void onAnimationEnd(Animation animation) { }
-
-            @Override
-            public void onAnimationRepeat(Animation animation) { }
-        };
-
-        // Animate visible items from previous positions to current positions except routes added
-        // just before. Added routes will remain hidden until translate animation finishes.
-        int first = mVolumeGroupList.getFirstVisiblePosition();
-        for (int i = 0; i < mVolumeGroupList.getChildCount(); ++i) {
-            View view = mVolumeGroupList.getChildAt(i);
-            int position = first + i;
-            MediaRouter.RouteInfo route = mVolumeGroupAdapter.getItem(position);
-            Rect previousBounds = previousRouteBoundMap.get(route);
-            int currentTop = view.getTop();
-            int previousTop = previousBounds != null ? previousBounds.top
-                    : (currentTop + mVolumeGroupListItemHeight * groupSizeDelta);
-            AnimationSet animSet = new AnimationSet(true);
-            if (mGroupMemberRoutesAdded != null && mGroupMemberRoutesAdded.contains(route)) {
-                previousTop = currentTop;
-                Animation alphaAnim = new AlphaAnimation(0.0f, 0.0f);
-                alphaAnim.setDuration(mGroupListFadeInDurationMs);
-                animSet.addAnimation(alphaAnim);
-            }
-            Animation translationAnim = new TranslateAnimation(0, 0, previousTop - currentTop, 0);
-            translationAnim.setDuration(mGroupListAnimationDurationMs);
-            animSet.addAnimation(translationAnim);
-            animSet.setFillAfter(true);
-            animSet.setFillEnabled(true);
-            animSet.setInterpolator(mInterpolator);
-            if (!listenerRegistered) {
-                listenerRegistered = true;
-                animSet.setAnimationListener(listener);
-            }
-            view.clearAnimation();
-            view.startAnimation(animSet);
-            previousRouteBoundMap.remove(route);
-            previousRouteBitmapMap.remove(route);
-        }
-
-        // If a member route doesn't exist any longer, it can be either removed or moved out of the
-        // ListView layout boundary. In this case, use the previously captured bitmaps for
-        // animation.
-        for (Map.Entry<MediaRouter.RouteInfo, BitmapDrawable> item
-                : previousRouteBitmapMap.entrySet()) {
-            final MediaRouter.RouteInfo route = item.getKey();
-            final BitmapDrawable bitmap = item.getValue();
-            final Rect bounds = previousRouteBoundMap.get(route);
-            OverlayObject object = null;
-            if (mGroupMemberRoutesRemoved.contains(route)) {
-                object = new OverlayObject(bitmap, bounds).setAlphaAnimation(1.0f, 0.0f)
-                        .setDuration(mGroupListFadeOutDurationMs)
-                        .setInterpolator(mInterpolator);
-            } else {
-                int deltaY = groupSizeDelta * mVolumeGroupListItemHeight;
-                object = new OverlayObject(bitmap, bounds).setTranslateYAnimation(deltaY)
-                        .setDuration(mGroupListAnimationDurationMs)
-                        .setInterpolator(mInterpolator)
-                        .setAnimationEndListener(new OverlayObject.OnAnimationEndListener() {
-                            @Override
-                            public void onAnimationEnd() {
-                                mGroupMemberRoutesAnimatingWithBitmap.remove(route);
-                                mVolumeGroupAdapter.notifyDataSetChanged();
-                            }
-                        });
-                mGroupMemberRoutesAnimatingWithBitmap.add(route);
-            }
-            mVolumeGroupList.addOverlayObject(object);
-        }
-    }
-
-    void startGroupListFadeInAnimation() {
-        clearGroupListAnimation(true);
-        mVolumeGroupList.requestLayout();
-        ViewTreeObserver observer = mVolumeGroupList.getViewTreeObserver();
-        observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
-            @Override
-            public void onGlobalLayout() {
-                mVolumeGroupList.getViewTreeObserver().removeGlobalOnLayoutListener(this);
-                startGroupListFadeInAnimationInternal();
-            }
-        });
-    }
-
-    void startGroupListFadeInAnimationInternal() {
-        if (mGroupMemberRoutesAdded != null && mGroupMemberRoutesAdded.size() != 0) {
-            fadeInAddedRoutes();
-        } else {
-            finishAnimation(true);
-        }
-    }
-
-    void finishAnimation(boolean animate) {
-        mGroupMemberRoutesAdded = null;
-        mGroupMemberRoutesRemoved = null;
-        mIsGroupListAnimating = false;
-        if (mIsGroupListAnimationPending) {
-            mIsGroupListAnimationPending = false;
-            updateLayoutHeight(animate);
-        }
-        mVolumeGroupList.setEnabled(true);
-    }
-
-    private void fadeInAddedRoutes() {
-        Animation.AnimationListener listener = new Animation.AnimationListener() {
-            @Override
-            public void onAnimationStart(Animation animation) { }
-
-            @Override
-            public void onAnimationEnd(Animation animation) {
-                finishAnimation(true);
-            }
-
-            @Override
-            public void onAnimationRepeat(Animation animation) { }
-        };
-        boolean listenerRegistered = false;
-        int first = mVolumeGroupList.getFirstVisiblePosition();
-        for (int i = 0; i < mVolumeGroupList.getChildCount(); ++i) {
-            View view = mVolumeGroupList.getChildAt(i);
-            int position = first + i;
-            MediaRouter.RouteInfo route = mVolumeGroupAdapter.getItem(position);
-            if (mGroupMemberRoutesAdded.contains(route)) {
-                Animation alphaAnim = new AlphaAnimation(0.0f, 1.0f);
-                alphaAnim.setDuration(mGroupListFadeInDurationMs);
-                alphaAnim.setFillEnabled(true);
-                alphaAnim.setFillAfter(true);
-                if (!listenerRegistered) {
-                    listenerRegistered = true;
-                    alphaAnim.setAnimationListener(listener);
-                }
-                view.clearAnimation();
-                view.startAnimation(alphaAnim);
-            }
-        }
-    }
-
-    void clearGroupListAnimation(boolean exceptAddedRoutes) {
-        int first = mVolumeGroupList.getFirstVisiblePosition();
-        for (int i = 0; i < mVolumeGroupList.getChildCount(); ++i) {
-            View view = mVolumeGroupList.getChildAt(i);
-            int position = first + i;
-            MediaRouter.RouteInfo route = mVolumeGroupAdapter.getItem(position);
-            if (exceptAddedRoutes && mGroupMemberRoutesAdded != null
-                    && mGroupMemberRoutesAdded.contains(route)) {
-                continue;
-            }
-            LinearLayout container = (LinearLayout) view.findViewById(R.id.volume_item_container);
-            container.setVisibility(View.VISIBLE);
-            AnimationSet animSet = new AnimationSet(true);
-            Animation alphaAnim = new AlphaAnimation(1.0f, 1.0f);
-            alphaAnim.setDuration(0);
-            animSet.addAnimation(alphaAnim);
-            Animation translationAnim = new TranslateAnimation(0, 0, 0, 0);
-            translationAnim.setDuration(0);
-            animSet.setFillAfter(true);
-            animSet.setFillEnabled(true);
-            view.clearAnimation();
-            view.startAnimation(animSet);
-        }
-        mVolumeGroupList.stopAnimationAll();
-        if (!exceptAddedRoutes) {
-            finishAnimation(false);
-        }
-    }
-
-    private void updatePlaybackControlLayout() {
-        if (canShowPlaybackControlLayout()) {
-            CharSequence title = mDescription == null ? null : mDescription.getTitle();
-            boolean hasTitle = !TextUtils.isEmpty(title);
-
-            CharSequence subtitle = mDescription == null ? null : mDescription.getSubtitle();
-            boolean hasSubtitle = !TextUtils.isEmpty(subtitle);
-
-            boolean showTitle = false;
-            boolean showSubtitle = false;
-            if (mRoute.getPresentationDisplayId()
-                    != MediaRouter.RouteInfo.PRESENTATION_DISPLAY_ID_NONE) {
-                // The user is currently casting screen.
-                mTitleView.setText(ApiHelper.getLibResources(mContext).getString(
-                        R.string.mr_controller_casting_screen));
-                showTitle = true;
-            } else if (mState == null || mState.getState() == PlaybackStateCompat.STATE_NONE) {
-                // Show "No media selected" as we don't yet know the playback state.
-                mTitleView.setText(ApiHelper.getLibResources(mContext).getString(
-                        R.string.mr_controller_no_media_selected));
-                showTitle = true;
-            } else if (!hasTitle && !hasSubtitle) {
-                mTitleView.setText(ApiHelper.getLibResources(mContext).getString(
-                        R.string.mr_controller_no_info_available));
-                showTitle = true;
-            } else {
-                if (hasTitle) {
-                    mTitleView.setText(title);
-                    showTitle = true;
-                }
-                if (hasSubtitle) {
-                    mSubtitleView.setText(subtitle);
-                    showSubtitle = true;
-                }
-            }
-            mTitleView.setVisibility(showTitle ? View.VISIBLE : View.GONE);
-            mSubtitleView.setVisibility(showSubtitle ? View.VISIBLE : View.GONE);
-
-            if (mState != null) {
-                boolean isPlaying = mState.getState() == PlaybackStateCompat.STATE_BUFFERING
-                        || mState.getState() == PlaybackStateCompat.STATE_PLAYING;
-                Context playbackControlButtonContext = mPlaybackControlButton.getContext();
-                boolean visible = true;
-                int iconDrawableAttr = 0;
-                int iconDescResId = 0;
-                if (isPlaying && isPauseActionSupported()) {
-                    iconDrawableAttr = R.attr.mediaRoutePauseDrawable;
-                    iconDescResId = R.string.mr_controller_pause;
-                } else if (isPlaying && isStopActionSupported()) {
-                    iconDrawableAttr = R.attr.mediaRouteStopDrawable;
-                    iconDescResId = R.string.mr_controller_stop;
-                } else if (!isPlaying && isPlayActionSupported()) {
-                    iconDrawableAttr = R.attr.mediaRoutePlayDrawable;
-                    iconDescResId = R.string.mr_controller_play;
-                } else {
-                    visible = false;
-                }
-                mPlaybackControlButton.setVisibility(visible ? View.VISIBLE : View.GONE);
-                if (visible) {
-                    mPlaybackControlButton.setImageResource(
-                            MediaRouterThemeHelper.getThemeResource(
-                                    playbackControlButtonContext, iconDrawableAttr));
-                    mPlaybackControlButton.setContentDescription(
-                            playbackControlButtonContext.getResources()
-                                    .getText(iconDescResId));
-                }
-            }
-        }
-    }
-
-    private boolean isPlayActionSupported() {
-        return (mState.getActions() & (ACTION_PLAY | ACTION_PLAY_PAUSE)) != 0;
-    }
-
-    private boolean isPauseActionSupported() {
-        return (mState.getActions() & (ACTION_PAUSE | ACTION_PLAY_PAUSE)) != 0;
-    }
-
-    private boolean isStopActionSupported() {
-        return (mState.getActions() & ACTION_STOP) != 0;
-    }
-
-    boolean isVolumeControlAvailable(MediaRouter.RouteInfo route) {
-        return mVolumeControlEnabled && route.getVolumeHandling()
-                == MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE;
-    }
-
-    private static int getLayoutHeight(View view) {
-        return view.getLayoutParams().height;
-    }
-
-    static void setLayoutHeight(View view, int height) {
-        ViewGroup.LayoutParams lp = view.getLayoutParams();
-        lp.height = height;
-        view.setLayoutParams(lp);
-    }
-
-    private static boolean uriEquals(Uri uri1, Uri uri2) {
-        if (uri1 != null && uri1.equals(uri2)) {
-            return true;
-        } else if (uri1 == null && uri2 == null) {
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Returns desired art height to fit into controller dialog.
-     */
-    int getDesiredArtHeight(int originalWidth, int originalHeight) {
-        if (originalWidth >= originalHeight) {
-            // For landscape art, fit width to dialog width.
-            return (int) ((float) mDialogContentWidth * originalHeight / originalWidth + 0.5f);
-        }
-        // For portrait art, fit height to 16:9 ratio case's height.
-        return (int) ((float) mDialogContentWidth * 9 / 16 + 0.5f);
-    }
-
-    void updateArtIconIfNeeded() {
-        if (mCustomControlView != null || !isIconChanged()) {
-            return;
-        }
-        if (mFetchArtTask != null) {
-            mFetchArtTask.cancel(true);
-        }
-        mFetchArtTask = new FetchArtTask();
-        mFetchArtTask.execute();
-    }
-
-    /**
-     * Clear the bitmap loaded by FetchArtTask. Will be called after the loaded bitmaps are applied
-     * to artwork, or no longer valid.
-     */
-    void clearLoadedBitmap() {
-        mArtIconIsLoaded = false;
-        mArtIconLoadedBitmap = null;
-        mArtIconBackgroundColor = 0;
-    }
-
-    /**
-     * Returns whether a new art image is different from an original art image. Compares
-     * Bitmap objects first, and then compares URIs only if bitmap is unchanged with
-     * a null value.
-     */
-    private boolean isIconChanged() {
-        Bitmap newBitmap = mDescription == null ? null : mDescription.getIconBitmap();
-        Uri newUri = mDescription == null ? null : mDescription.getIconUri();
-        Bitmap oldBitmap = mFetchArtTask == null ? mArtIconBitmap : mFetchArtTask.getIconBitmap();
-        Uri oldUri = mFetchArtTask == null ? mArtIconUri : mFetchArtTask.getIconUri();
-        if (oldBitmap != newBitmap) {
-            return true;
-        } else if (oldBitmap == null && !uriEquals(oldUri, newUri)) {
-            return true;
-        }
-        return false;
-    }
-
-    private final class MediaRouterCallback extends MediaRouter.Callback {
-        MediaRouterCallback() {
-        }
-
-        @Override
-        public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo route) {
-            update(false);
-        }
-
-        @Override
-        public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo route) {
-            update(true);
-        }
-
-        @Override
-        public void onRouteVolumeChanged(MediaRouter router, MediaRouter.RouteInfo route) {
-            SeekBar volumeSlider = mVolumeSliderMap.get(route);
-            int volume = route.getVolume();
-            if (DEBUG) {
-                Log.d(TAG, "onRouteVolumeChanged(), route.getVolume:" + volume);
-            }
-            if (volumeSlider != null && mRouteInVolumeSliderTouched != route) {
-                volumeSlider.setProgress(volume);
-            }
-        }
-    }
-
-    private final class MediaControllerCallback extends MediaControllerCompat.Callback {
-        MediaControllerCallback() {
-        }
-
-        @Override
-        public void onSessionDestroyed() {
-            if (mMediaController != null) {
-                mMediaController.unregisterCallback(mControllerCallback);
-                mMediaController = null;
-            }
-        }
-
-        @Override
-        public void onPlaybackStateChanged(PlaybackStateCompat state) {
-            mState = state;
-            update(false);
-        }
-
-        @Override
-        public void onMetadataChanged(MediaMetadataCompat metadata) {
-            mDescription = metadata == null ? null : metadata.getDescription();
-            updateArtIconIfNeeded();
-            update(false);
-        }
-    }
-
-    private final class ClickListener implements View.OnClickListener {
-        ClickListener() {
-        }
-
-        @Override
-        public void onClick(View v) {
-            int id = v.getId();
-            if (id == BUTTON_STOP_RES_ID || id == BUTTON_DISCONNECT_RES_ID) {
-                if (mRoute.isSelected()) {
-                    mRouter.unselect(id == BUTTON_STOP_RES_ID ?
-                            MediaRouter.UNSELECT_REASON_STOPPED :
-                            MediaRouter.UNSELECT_REASON_DISCONNECTED);
-                }
-                dismiss();
-            } else if (id == R.id.mr_control_playback_ctrl) {
-                if (mMediaController != null && mState != null) {
-                    boolean isPlaying = mState.getState() == PlaybackStateCompat.STATE_PLAYING;
-                    int actionDescResId = 0;
-                    if (isPlaying && isPauseActionSupported()) {
-                        mMediaController.getTransportControls().pause();
-                        actionDescResId = R.string.mr_controller_pause;
-                    } else if (isPlaying && isStopActionSupported()) {
-                        mMediaController.getTransportControls().stop();
-                        actionDescResId = R.string.mr_controller_stop;
-                    } else if (!isPlaying && isPlayActionSupported()){
-                        mMediaController.getTransportControls().play();
-                        actionDescResId = R.string.mr_controller_play;
-                    }
-                    // Announce the action for accessibility.
-                    if (mAccessibilityManager != null && mAccessibilityManager.isEnabled()
-                            && actionDescResId != 0) {
-                        AccessibilityEvent event = AccessibilityEvent.obtain(
-                                AccessibilityEventCompat.TYPE_ANNOUNCEMENT);
-                        event.setPackageName(mContext.getPackageName());
-                        event.setClassName(getClass().getName());
-                        event.getText().add(
-                                ApiHelper.getLibResources(mContext).getString(actionDescResId));
-                        mAccessibilityManager.sendAccessibilityEvent(event);
-                    }
-                }
-            } else if (id == R.id.mr_close) {
-                dismiss();
-            }
-        }
-    }
-
-    private class VolumeChangeListener implements SeekBar.OnSeekBarChangeListener {
-        private final Runnable mStopTrackingTouch = new Runnable() {
-            @Override
-            public void run() {
-                if (mRouteInVolumeSliderTouched != null) {
-                    mRouteInVolumeSliderTouched = null;
-                    if (mHasPendingUpdate) {
-                        update(mPendingUpdateAnimationNeeded);
-                    }
-                }
-            }
-        };
-
-        VolumeChangeListener() {
-        }
-
-        @Override
-        public void onStartTrackingTouch(SeekBar seekBar) {
-            if (mRouteInVolumeSliderTouched != null) {
-                mVolumeSlider.removeCallbacks(mStopTrackingTouch);
-            }
-            mRouteInVolumeSliderTouched = (MediaRouter.RouteInfo) seekBar.getTag();
-        }
-
-        @Override
-        public void onStopTrackingTouch(SeekBar seekBar) {
-            // Defer resetting mVolumeSliderTouched to allow the media route provider
-            // a little time to settle into its new state and publish the final
-            // volume update.
-            mVolumeSlider.postDelayed(mStopTrackingTouch, VOLUME_UPDATE_DELAY_MILLIS);
-        }
-
-        @Override
-        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
-            if (fromUser) {
-                MediaRouter.RouteInfo route = (MediaRouter.RouteInfo) seekBar.getTag();
-                if (DEBUG) {
-                    Log.d(TAG, "onProgressChanged(): calling "
-                            + "MediaRouter.RouteInfo.requestSetVolume(" + progress + ")");
-                }
-                route.requestSetVolume(progress);
-            }
-        }
-    }
-
-    private class VolumeGroupAdapter extends ArrayAdapter<MediaRouter.RouteInfo> {
-        final float mDisabledAlpha;
-
-        public VolumeGroupAdapter(Context context, List<MediaRouter.RouteInfo> objects) {
-            super(context, 0, objects);
-            mDisabledAlpha = MediaRouterThemeHelper.getDisabledAlpha(context);
-        }
-
-        @Override
-        public boolean isEnabled(int position) {
-            return false;
-        }
-
-        @Override
-        public View getView(final int position, View convertView, ViewGroup parent) {
-            View v = convertView;
-            if (v == null) {
-                v = LayoutInflater.from(parent.getContext()).inflate(
-                        R.layout.mr_controller_volume_item, parent, false);
-            } else {
-                updateVolumeGroupItemHeight(v);
-            }
-
-            MediaRouter.RouteInfo route = getItem(position);
-            if (route != null) {
-                boolean isEnabled = route.isEnabled();
-
-                TextView routeName = (TextView) v.findViewById(R.id.mr_name);
-                routeName.setEnabled(isEnabled);
-                routeName.setText(route.getName());
-
-                MediaRouteVolumeSlider volumeSlider =
-                        (MediaRouteVolumeSlider) v.findViewById(R.id.mr_volume_slider);
-                MediaRouterThemeHelper.setVolumeSliderColor(
-                        parent.getContext(), volumeSlider, mVolumeGroupList);
-                volumeSlider.setTag(route);
-                mVolumeSliderMap.put(route, volumeSlider);
-                volumeSlider.setHideThumb(!isEnabled);
-                volumeSlider.setEnabled(isEnabled);
-                if (isEnabled) {
-                    if (isVolumeControlAvailable(route)) {
-                        volumeSlider.setMax(route.getVolumeMax());
-                        volumeSlider.setProgress(route.getVolume());
-                        volumeSlider.setOnSeekBarChangeListener(mVolumeChangeListener);
-                    } else {
-                        volumeSlider.setMax(100);
-                        volumeSlider.setProgress(100);
-                        volumeSlider.setEnabled(false);
-                    }
-                }
-
-                ImageView volumeItemIcon =
-                        (ImageView) v.findViewById(R.id.mr_volume_item_icon);
-                volumeItemIcon.setAlpha(isEnabled ? 0xFF : (int) (0xFF * mDisabledAlpha));
-
-                // If overlay bitmap exists, real view should remain hidden until
-                // the animation ends.
-                LinearLayout container = (LinearLayout) v.findViewById(R.id.volume_item_container);
-                container.setVisibility(mGroupMemberRoutesAnimatingWithBitmap.contains(route)
-                        ? View.INVISIBLE : View.VISIBLE);
-
-                // Routes which are being added will be invisible until animation ends.
-                if (mGroupMemberRoutesAdded != null && mGroupMemberRoutesAdded.contains(route)) {
-                    Animation alphaAnim = new AlphaAnimation(0.0f, 0.0f);
-                    alphaAnim.setDuration(0);
-                    alphaAnim.setFillEnabled(true);
-                    alphaAnim.setFillAfter(true);
-                    v.clearAnimation();
-                    v.startAnimation(alphaAnim);
-                }
-            }
-            return v;
-        }
-    }
-
-    private class FetchArtTask extends AsyncTask<Void, Void, Bitmap> {
-        // Show animation only when fetching takes a long time.
-        private static final long SHOW_ANIM_TIME_THRESHOLD_MILLIS = 120L;
-
-        private final Bitmap mIconBitmap;
-        private final Uri mIconUri;
-        private int mBackgroundColor;
-        private long mStartTimeMillis;
-
-        FetchArtTask() {
-            Bitmap bitmap = mDescription == null ? null : mDescription.getIconBitmap();
-            if (isBitmapRecycled(bitmap)) {
-                Log.w(TAG, "Can't fetch the given art bitmap because it's already recycled.");
-                bitmap = null;
-            }
-            mIconBitmap = bitmap;
-            mIconUri = mDescription == null ? null : mDescription.getIconUri();
-        }
-
-        public Bitmap getIconBitmap() {
-            return mIconBitmap;
-        }
-
-        public Uri getIconUri() {
-            return mIconUri;
-        }
-
-        @Override
-        protected void onPreExecute() {
-            mStartTimeMillis = SystemClock.uptimeMillis();
-            clearLoadedBitmap();
-        }
-
-        @Override
-        protected Bitmap doInBackground(Void... arg) {
-            Bitmap art = null;
-            if (mIconBitmap != null) {
-                art = mIconBitmap;
-            } else if (mIconUri != null) {
-                InputStream stream = null;
-                try {
-                    if ((stream = openInputStreamByScheme(mIconUri)) == null) {
-                        Log.w(TAG, "Unable to open: " + mIconUri);
-                        return null;
-                    }
-                    // Query art size.
-                    BitmapFactory.Options options = new BitmapFactory.Options();
-                    options.inJustDecodeBounds = true;
-                    BitmapFactory.decodeStream(stream, null, options);
-                    if (options.outWidth == 0 || options.outHeight == 0) {
-                        return null;
-                    }
-                    // Rewind the stream in order to restart art decoding.
-                    try {
-                        stream.reset();
-                    } catch (IOException e) {
-                        // Failed to rewind the stream, try to reopen it.
-                        stream.close();
-                        if ((stream = openInputStreamByScheme(mIconUri)) == null) {
-                            Log.w(TAG, "Unable to open: " + mIconUri);
-                            return null;
-                        }
-                    }
-                    // Calculate required size to decode the art and possibly resize it.
-                    options.inJustDecodeBounds = false;
-                    int reqHeight = getDesiredArtHeight(options.outWidth, options.outHeight);
-                    int ratio = options.outHeight / reqHeight;
-                    options.inSampleSize = Math.max(1, Integer.highestOneBit(ratio));
-                    if (isCancelled()) {
-                        return null;
-                    }
-                    art = BitmapFactory.decodeStream(stream, null, options);
-                } catch (IOException e){
-                    Log.w(TAG, "Unable to open: " + mIconUri, e);
-                } finally {
-                    if (stream != null) {
-                        try {
-                            stream.close();
-                        } catch (IOException e) {
-                        }
-                    }
-                }
-            }
-            if (isBitmapRecycled(art)) {
-                Log.w(TAG, "Can't use recycled bitmap: " + art);
-                return null;
-            }
-            if (art != null && art.getWidth() < art.getHeight()) {
-                // Portrait art requires dominant color as background color.
-                Palette palette = new Palette.Builder(art).maximumColorCount(1).generate();
-                mBackgroundColor = palette.getSwatches().isEmpty()
-                        ? 0 : palette.getSwatches().get(0).getRgb();
-            }
-            return art;
-        }
-
-        @Override
-        protected void onPostExecute(Bitmap art) {
-            mFetchArtTask = null;
-            if (!ObjectsCompat.equals(mArtIconBitmap, mIconBitmap)
-                    || !ObjectsCompat.equals(mArtIconUri, mIconUri)) {
-                mArtIconBitmap = mIconBitmap;
-                mArtIconLoadedBitmap = art;
-                mArtIconUri = mIconUri;
-                mArtIconBackgroundColor = mBackgroundColor;
-                mArtIconIsLoaded = true;
-                long elapsedTimeMillis = SystemClock.uptimeMillis() - mStartTimeMillis;
-                // Loaded bitmap will be applied on the next update
-                update(elapsedTimeMillis > SHOW_ANIM_TIME_THRESHOLD_MILLIS);
-            }
-        }
-
-        private InputStream openInputStreamByScheme(Uri uri) throws IOException {
-            String scheme = uri.getScheme().toLowerCase();
-            InputStream stream = null;
-            if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)
-                    || ContentResolver.SCHEME_CONTENT.equals(scheme)
-                    || ContentResolver.SCHEME_FILE.equals(scheme)) {
-                stream = mContext.getContentResolver().openInputStream(uri);
-            } else {
-                URL url = new URL(uri.toString());
-                URLConnection conn = url.openConnection();
-                conn.setConnectTimeout(CONNECTION_TIMEOUT_MILLIS);
-                conn.setReadTimeout(CONNECTION_TIMEOUT_MILLIS);
-                stream = conn.getInputStream();
-            }
-            return (stream == null) ? null : new BufferedInputStream(stream);
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteControllerDialogFragment.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteControllerDialogFragment.java
deleted file mode 100644
index 215d74f..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteControllerDialogFragment.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.app;
-
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.os.Bundle;
-
-/**
- * Media route controller dialog fragment.
- * <p>
- * Creates a {@link MediaRouteControllerDialog}.  The application may subclass
- * this dialog fragment to customize the media route controller dialog.
- * </p>
- */
-public class MediaRouteControllerDialogFragment extends DialogFragment {
-    private MediaRouteControllerDialog mDialog;
-    /**
-     * Creates a media route controller dialog fragment.
-     * <p>
-     * All subclasses of this class must also possess a default constructor.
-     * </p>
-     */
-    public MediaRouteControllerDialogFragment() {
-        setCancelable(true);
-    }
-
-    /**
-     * Called when the controller dialog is being created.
-     * <p>
-     * Subclasses may override this method to customize the dialog.
-     * </p>
-     */
-    public MediaRouteControllerDialog onCreateControllerDialog(
-            Context context, Bundle savedInstanceState) {
-        return new MediaRouteControllerDialog(context);
-    }
-
-    @Override
-    public Dialog onCreateDialog(Bundle savedInstanceState) {
-        mDialog = onCreateControllerDialog(getContext(), savedInstanceState);
-        return mDialog;
-    }
-
-    @Override
-    public void onStop() {
-        super.onStop();
-        if (mDialog != null) {
-            mDialog.clearGroupListAnimation(false);
-        }
-    }
-
-    @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        if (mDialog != null) {
-            mDialog.updateLayout();
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteDialogFactory.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteDialogFactory.java
deleted file mode 100644
index a9eaf39..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteDialogFactory.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.app;
-
-import android.support.annotation.NonNull;
-
-/**
- * The media route dialog factory is responsible for creating the media route
- * chooser and controller dialogs as needed.
- * <p>
- * The application can customize the dialogs by providing a subclass of the
- * dialog factory to the {@link MediaRouteButton} using the
- * {@link MediaRouteButton#setDialogFactory setDialogFactory} method.
- * </p>
- */
-public class MediaRouteDialogFactory {
-    private static final MediaRouteDialogFactory sDefault = new MediaRouteDialogFactory();
-
-    /**
-     * Creates a default media route dialog factory.
-     */
-    public MediaRouteDialogFactory() {
-    }
-
-    /**
-     * Gets the default factory instance.
-     *
-     * @return The default media route dialog factory, never null.
-     */
-    @NonNull
-    public static MediaRouteDialogFactory getDefault() {
-        return sDefault;
-    }
-
-    /**
-     * Called when the chooser dialog is being opened and it is time to create the fragment.
-     * <p>
-     * Subclasses may override this method to create a customized fragment.
-     * </p>
-     *
-     * @return The media route chooser dialog fragment, must not be null.
-     */
-    @NonNull
-    public MediaRouteChooserDialogFragment onCreateChooserDialogFragment() {
-        return new MediaRouteChooserDialogFragment();
-    }
-
-    /**
-     * Called when the controller dialog is being opened and it is time to create the fragment.
-     * <p>
-     * Subclasses may override this method to create a customized fragment.
-     * </p>
-     *
-     * @return The media route controller dialog fragment, must not be null.
-     */
-    @NonNull
-    public MediaRouteControllerDialogFragment onCreateControllerDialogFragment() {
-        return new MediaRouteControllerDialogFragment();
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteDialogHelper.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteDialogHelper.java
deleted file mode 100644
index 9aabf7b..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteDialogHelper.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.app;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.drawable.BitmapDrawable;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-
-import com.android.media.update.ApiHelper;
-import com.android.media.update.R;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-final class MediaRouteDialogHelper {
-    /**
-     * The framework should set the dialog width properly, but somehow it doesn't work, hence
-     * duplicating a similar logic here to determine the appropriate dialog width.
-     */
-    public static int getDialogWidth(Context context) {
-        DisplayMetrics metrics = ApiHelper.getLibResources(context).getDisplayMetrics();
-        boolean isPortrait = metrics.widthPixels < metrics.heightPixels;
-
-        TypedValue value = new TypedValue();
-        ApiHelper.getLibResources(context).getValue(isPortrait
-                ? R.dimen.mr_dialog_fixed_width_minor
-                : R.dimen.mr_dialog_fixed_width_major, value, true);
-        if (value.type == TypedValue.TYPE_DIMENSION) {
-            return (int) value.getDimension(metrics);
-        } else if (value.type == TypedValue.TYPE_FRACTION) {
-            return (int) value.getFraction(metrics.widthPixels, metrics.widthPixels);
-        }
-        return ViewGroup.LayoutParams.WRAP_CONTENT;
-    }
-
-    /**
-     * Compares two lists regardless of order.
-     *
-     * @param list1 A list
-     * @param list2 A list to be compared with {@code list1}
-     * @return True if two lists have exactly same items regardless of order, false otherwise.
-     */
-    public static <E> boolean listUnorderedEquals(List<E> list1, List<E> list2) {
-        HashSet<E> set1 = new HashSet<>(list1);
-        HashSet<E> set2 = new HashSet<>(list2);
-        return set1.equals(set2);
-    }
-
-    /**
-     * Compares two lists and returns a set of items which exist
-     * after-list but before-list, which means newly added items.
-     *
-     * @param before A list
-     * @param after A list to be compared with {@code before}
-     * @return A set of items which contains newly added items while
-     * comparing {@code after} to {@code before}.
-     */
-    public static <E> Set<E> getItemsAdded(List<E> before, List<E> after) {
-        HashSet<E> set = new HashSet<>(after);
-        set.removeAll(before);
-        return set;
-    }
-
-    /**
-     * Compares two lists and returns a set of items which exist
-     * before-list but after-list, which means removed items.
-     *
-     * @param before A list
-     * @param after A list to be compared with {@code before}
-     * @return A set of items which contains removed items while
-     * comparing {@code after} to {@code before}.
-     */
-    public static <E> Set<E> getItemsRemoved(List<E> before, List<E> after) {
-        HashSet<E> set = new HashSet<>(before);
-        set.removeAll(after);
-        return set;
-    }
-
-    /**
-     * Generates an item-Rect map which indicates where member
-     * items are located in the given ListView.
-     *
-     * @param listView A list view
-     * @param adapter An array adapter which contains an array of items.
-     * @return A map of items and bounds of their views located in the given list view.
-     */
-    public static <E> HashMap<E, Rect> getItemBoundMap(ListView listView,
-            ArrayAdapter<E> adapter) {
-        HashMap<E, Rect> itemBoundMap = new HashMap<>();
-        int firstVisiblePosition = listView.getFirstVisiblePosition();
-        for (int i = 0; i < listView.getChildCount(); ++i) {
-            int position = firstVisiblePosition + i;
-            E item = adapter.getItem(position);
-            View view = listView.getChildAt(i);
-            itemBoundMap.put(item,
-                    new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom()));
-        }
-        return itemBoundMap;
-    }
-
-    /**
-     * Generates an item-BitmapDrawable map which stores snapshots
-     * of member items in the given ListView.
-     *
-     * @param context A context
-     * @param listView A list view
-     * @param adapter An array adapter which contains an array of items.
-     * @return A map of items and snapshots of their views in the given list view.
-     */
-    public static <E> HashMap<E, BitmapDrawable> getItemBitmapMap(Context context,
-            ListView listView, ArrayAdapter<E> adapter) {
-        HashMap<E, BitmapDrawable> itemBitmapMap = new HashMap<>();
-        int firstVisiblePosition = listView.getFirstVisiblePosition();
-        for (int i = 0; i < listView.getChildCount(); ++i) {
-            int position = firstVisiblePosition + i;
-            E item = adapter.getItem(position);
-            View view = listView.getChildAt(i);
-            itemBitmapMap.put(item, getViewBitmap(context, view));
-        }
-        return itemBitmapMap;
-    }
-
-    private static BitmapDrawable getViewBitmap(Context context, View view) {
-        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),
-                Bitmap.Config.ARGB_8888);
-        Canvas canvas = new Canvas(bitmap);
-        view.draw(canvas);
-        return new BitmapDrawable(context.getResources(), bitmap);
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteDiscoveryFragment.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteDiscoveryFragment.java
deleted file mode 100644
index 02ee118..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteDiscoveryFragment.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.app;
-
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-
-import com.android.support.mediarouter.media.MediaRouter;
-import com.android.support.mediarouter.media.MediaRouteSelector;
-
-/**
- * Media route discovery fragment.
- * <p>
- * This fragment takes care of registering a callback for media route discovery
- * during the {@link Fragment#onStart onStart()} phase
- * and removing it during the {@link Fragment#onStop onStop()} phase.
- * </p><p>
- * The application must supply a route selector to specify the kinds of routes
- * to discover.  The application may also override {@link #onCreateCallback} to
- * provide the {@link MediaRouter} callback to register.
- * </p><p>
- * Note that the discovery callback makes the application be connected with all the
- * {@link android.support.v7.media.MediaRouteProviderService media route provider services}
- * while it is registered.
- * </p>
- */
-public class MediaRouteDiscoveryFragment extends Fragment {
-    private final String ARGUMENT_SELECTOR = "selector";
-
-    private MediaRouter mRouter;
-    private MediaRouteSelector mSelector;
-    private MediaRouter.Callback mCallback;
-
-    public MediaRouteDiscoveryFragment() {
-    }
-
-    /**
-     * Gets the media router instance.
-     */
-    public MediaRouter getMediaRouter() {
-        ensureRouter();
-        return mRouter;
-    }
-
-    private void ensureRouter() {
-        if (mRouter == null) {
-            mRouter = MediaRouter.getInstance(getContext());
-        }
-    }
-
-    /**
-     * Gets the media route selector for filtering the routes to be discovered.
-     *
-     * @return The selector, never null.
-     */
-    public MediaRouteSelector getRouteSelector() {
-        ensureRouteSelector();
-        return mSelector;
-    }
-
-    /**
-     * Sets the media route selector for filtering the routes to be discovered.
-     * This method must be called before the fragment is added.
-     *
-     * @param selector The selector to set.
-     */
-    public void setRouteSelector(MediaRouteSelector selector) {
-        if (selector == null) {
-            throw new IllegalArgumentException("selector must not be null");
-        }
-
-        ensureRouteSelector();
-        if (!mSelector.equals(selector)) {
-            mSelector = selector;
-
-            Bundle args = getArguments();
-            if (args == null) {
-                args = new Bundle();
-            }
-            args.putBundle(ARGUMENT_SELECTOR, selector.asBundle());
-            setArguments(args);
-
-            if (mCallback != null) {
-                mRouter.removeCallback(mCallback);
-                mRouter.addCallback(mSelector, mCallback, onPrepareCallbackFlags());
-            }
-        }
-    }
-
-    private void ensureRouteSelector() {
-        if (mSelector == null) {
-            Bundle args = getArguments();
-            if (args != null) {
-                mSelector = MediaRouteSelector.fromBundle(args.getBundle(ARGUMENT_SELECTOR));
-            }
-            if (mSelector == null) {
-                mSelector = MediaRouteSelector.EMPTY;
-            }
-        }
-    }
-
-    /**
-     * Called to create the {@link android.support.v7.media.MediaRouter.Callback callback}
-     * that will be registered.
-     * <p>
-     * The default callback does nothing.  The application may override this method to
-     * supply its own callback.
-     * </p>
-     *
-     * @return The new callback, or null if no callback should be registered.
-     */
-    public MediaRouter.Callback onCreateCallback() {
-        return new MediaRouter.Callback() { };
-    }
-
-    /**
-     * Called to prepare the callback flags that will be used when the
-     * {@link android.support.v7.media.MediaRouter.Callback callback} is registered.
-     * <p>
-     * The default implementation returns {@link MediaRouter#CALLBACK_FLAG_REQUEST_DISCOVERY}.
-     * </p>
-     *
-     * @return The desired callback flags.
-     */
-    public int onPrepareCallbackFlags() {
-        return MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY;
-    }
-
-    @Override
-    public void onStart() {
-        super.onStart();
-
-        ensureRouteSelector();
-        ensureRouter();
-        mCallback = onCreateCallback();
-        if (mCallback != null) {
-            mRouter.addCallback(mSelector, mCallback, onPrepareCallbackFlags());
-        }
-    }
-
-    @Override
-    public void onStop() {
-        if (mCallback != null) {
-            mRouter.removeCallback(mCallback);
-            mCallback = null;
-        }
-
-        super.onStop();
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteExpandCollapseButton.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteExpandCollapseButton.java
deleted file mode 100644
index 6a0a95a..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteExpandCollapseButton.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.app;
-
-import android.content.Context;
-import android.graphics.ColorFilter;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffColorFilter;
-import android.graphics.drawable.AnimationDrawable;
-import android.support.v4.content.ContextCompat;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.ImageButton;
-
-import com.android.media.update.ApiHelper;
-import com.android.media.update.R;
-
-/**
- * Chevron/Caret button to expand/collapse group volume list with animation.
- */
-public class MediaRouteExpandCollapseButton extends ImageButton {
-    final AnimationDrawable mExpandAnimationDrawable;
-    final AnimationDrawable mCollapseAnimationDrawable;
-    final String mExpandGroupDescription;
-    final String mCollapseGroupDescription;
-    boolean mIsGroupExpanded;
-    OnClickListener mListener;
-
-    public MediaRouteExpandCollapseButton(Context context) {
-        this(context, null);
-    }
-
-    public MediaRouteExpandCollapseButton(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public MediaRouteExpandCollapseButton(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        mExpandAnimationDrawable = (AnimationDrawable)
-                ApiHelper.getLibResources(context).getDrawable(R.drawable.mr_group_expand);
-        mCollapseAnimationDrawable = (AnimationDrawable)
-                ApiHelper.getLibResources(context).getDrawable(R.drawable.mr_group_collapse);
-
-        ColorFilter filter = new PorterDuffColorFilter(
-                MediaRouterThemeHelper.getControllerColor(context, defStyleAttr),
-                PorterDuff.Mode.SRC_IN);
-        mExpandAnimationDrawable.setColorFilter(filter);
-        mCollapseAnimationDrawable.setColorFilter(filter);
-
-        mExpandGroupDescription =
-                ApiHelper.getLibResources(context).getString(R.string.mr_controller_expand_group);
-        mCollapseGroupDescription =
-                ApiHelper.getLibResources(context).getString(R.string.mr_controller_collapse_group);
-
-        setImageDrawable(mExpandAnimationDrawable.getFrame(0));
-        setContentDescription(mExpandGroupDescription);
-
-        super.setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View view) {
-                mIsGroupExpanded = !mIsGroupExpanded;
-                if (mIsGroupExpanded) {
-                    setImageDrawable(mExpandAnimationDrawable);
-                    mExpandAnimationDrawable.start();
-                    setContentDescription(mCollapseGroupDescription);
-                } else {
-                    setImageDrawable(mCollapseAnimationDrawable);
-                    mCollapseAnimationDrawable.start();
-                    setContentDescription(mExpandGroupDescription);
-                }
-                if (mListener != null) {
-                    mListener.onClick(view);
-                }
-            }
-        });
-    }
-
-    @Override
-    public void setOnClickListener(OnClickListener listener) {
-        mListener = listener;
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteVolumeSlider.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteVolumeSlider.java
deleted file mode 100644
index d05d20e..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteVolumeSlider.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.app;
-
-import android.content.Context;
-import android.graphics.Color;
-import android.graphics.PorterDuff;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.widget.SeekBar;
-
-/**
- * Volume slider with showing, hiding, and applying alpha supports to the thumb.
- */
-public class MediaRouteVolumeSlider extends SeekBar {
-    private static final String TAG = "MediaRouteVolumeSlider";
-
-    private final float mDisabledAlpha;
-
-    private boolean mHideThumb;
-    private Drawable mThumb;
-    private int mColor;
-
-    public MediaRouteVolumeSlider(Context context) {
-        this(context, null);
-    }
-
-    public MediaRouteVolumeSlider(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        mDisabledAlpha = MediaRouterThemeHelper.getDisabledAlpha(context);
-    }
-
-    public MediaRouteVolumeSlider(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        mDisabledAlpha = MediaRouterThemeHelper.getDisabledAlpha(context);
-    }
-
-    @Override
-    protected void drawableStateChanged() {
-        super.drawableStateChanged();
-        int alpha = isEnabled() ? 0xFF : (int) (0xFF * mDisabledAlpha);
-
-        // The thumb drawable is a collection of drawables and its current drawables are changed per
-        // state. Apply the color filter and alpha on every state change.
-        if (mThumb != null) {
-            mThumb.setColorFilter(mColor, PorterDuff.Mode.SRC_IN);
-            mThumb.setAlpha(alpha);
-        }
-
-        getProgressDrawable().setColorFilter(mColor, PorterDuff.Mode.SRC_IN);
-        getProgressDrawable().setAlpha(alpha);
-    }
-
-    @Override
-    public void setThumb(Drawable thumb) {
-        mThumb = thumb;
-        super.setThumb(mHideThumb ? null : mThumb);
-    }
-
-    /**
-     * Sets whether to show or hide thumb.
-     */
-    public void setHideThumb(boolean hideThumb) {
-        if (mHideThumb == hideThumb) {
-            return;
-        }
-        mHideThumb = hideThumb;
-        super.setThumb(mHideThumb ? null : mThumb);
-    }
-
-    /**
-     * Sets the volume slider color. The change takes effect next time drawable state is changed.
-     * <p>
-     * The color cannot be translucent, otherwise the underlying progress bar will be seen through
-     * the thumb.
-     * </p>
-     */
-    public void setColor(int color) {
-        if (mColor == color) {
-            return;
-        }
-        if (Color.alpha(color) != 0xFF) {
-            Log.e(TAG, "Volume slider color cannot be translucent: #" + Integer.toHexString(color));
-        }
-        mColor = color;
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouterThemeHelper.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouterThemeHelper.java
deleted file mode 100644
index 63f042f..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouterThemeHelper.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.app;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Color;
-import android.support.annotation.IntDef;
-import android.support.v4.graphics.ColorUtils;
-import android.util.TypedValue;
-import android.view.ContextThemeWrapper;
-import android.view.View;
-
-import com.android.media.update.R;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-final class MediaRouterThemeHelper {
-    private static final float MIN_CONTRAST = 3.0f;
-
-    @IntDef({COLOR_DARK_ON_LIGHT_BACKGROUND, COLOR_WHITE_ON_DARK_BACKGROUND})
-    @Retention(RetentionPolicy.SOURCE)
-    private @interface ControllerColorType {}
-
-    static final int COLOR_DARK_ON_LIGHT_BACKGROUND = 0xDE000000; /* Opacity of 87% */
-    static final int COLOR_WHITE_ON_DARK_BACKGROUND = Color.WHITE;
-
-    private MediaRouterThemeHelper() {
-    }
-
-    static Context createThemedButtonContext(Context context) {
-        // Apply base Media Router theme.
-        context = new ContextThemeWrapper(context, getRouterThemeId(context));
-
-        // Apply custom Media Router theme.
-        int style = getThemeResource(context, R.attr.mediaRouteTheme);
-        if (style != 0) {
-            context = new ContextThemeWrapper(context, style);
-        }
-
-        return context;
-    }
-
-    /*
-     * The following two methods are to be used in conjunction. They should be used to prepare
-     * the context and theme for a super class constructor (the latter method relies on the
-     * former method to properly prepare the context):
-     *   super(context = createThemedDialogContext(context, theme),
-     *           createThemedDialogStyle(context));
-     *
-     * It will apply theme in the following order (style lookups will be done in reverse):
-     *   1) Current theme
-     *   2) Supplied theme
-     *   3) Base Media Router theme
-     *   4) Custom Media Router theme, if provided
-     */
-    static Context createThemedDialogContext(Context context, int theme, boolean alertDialog) {
-        // 1) Current theme is already applied to the context
-
-        // 2) If no theme is supplied, look it up from the context (dialogTheme/alertDialogTheme)
-        if (theme == 0) {
-            theme = getThemeResource(context,
-                    !alertDialog ? android.R.attr.dialogTheme : android.R.attr.alertDialogTheme);
-        }
-        //    Apply it
-        context = new ContextThemeWrapper(context, theme);
-
-        // 3) If a custom Media Router theme is provided then apply the base theme
-        if (getThemeResource(context, R.attr.mediaRouteTheme) != 0) {
-            context = new ContextThemeWrapper(context, getRouterThemeId(context));
-        }
-
-        return context;
-    }
-    // This method should be used in conjunction with the previous method.
-    static int createThemedDialogStyle(Context context) {
-        // 4) Apply the custom Media Router theme
-        int theme = getThemeResource(context, R.attr.mediaRouteTheme);
-        if (theme == 0) {
-            // 3) No custom MediaRouter theme was provided so apply the base theme instead
-            theme = getRouterThemeId(context);
-        }
-
-        return theme;
-    }
-    // END. Previous two methods should be used in conjunction.
-
-    static int getThemeResource(Context context, int attr) {
-        TypedValue value = new TypedValue();
-        return context.getTheme().resolveAttribute(attr, value, true) ? value.resourceId : 0;
-    }
-
-    static float getDisabledAlpha(Context context) {
-        TypedValue value = new TypedValue();
-        return context.getTheme().resolveAttribute(android.R.attr.disabledAlpha, value, true)
-                ? value.getFloat() : 0.5f;
-    }
-
-    static @ControllerColorType int getControllerColor(Context context, int style) {
-        int primaryColor = getThemeColor(context, style, android.R.attr.colorPrimary);
-        if (primaryColor == 0) {
-            primaryColor = getThemeColor(context, style, android.R.attr.colorPrimary);
-            if (primaryColor == 0) {
-                primaryColor = 0xFF000000;
-            }
-        }
-        if (ColorUtils.calculateContrast(COLOR_WHITE_ON_DARK_BACKGROUND, primaryColor)
-                >= MIN_CONTRAST) {
-            return COLOR_WHITE_ON_DARK_BACKGROUND;
-        }
-        return COLOR_DARK_ON_LIGHT_BACKGROUND;
-    }
-
-    static int getButtonTextColor(Context context) {
-        int primaryColor = getThemeColor(context, 0, android.R.attr.colorPrimary);
-        int backgroundColor = getThemeColor(context, 0, android.R.attr.colorBackground);
-
-        if (ColorUtils.calculateContrast(primaryColor, backgroundColor) < MIN_CONTRAST) {
-            // Default to colorAccent if the contrast ratio is low.
-            return getThemeColor(context, 0, android.R.attr.colorAccent);
-        }
-        return primaryColor;
-    }
-
-    static void setMediaControlsBackgroundColor(
-            Context context, View mainControls, View groupControls, boolean hasGroup) {
-        int primaryColor = getThemeColor(context, 0, android.R.attr.colorPrimary);
-        int primaryDarkColor = getThemeColor(context, 0, android.R.attr.colorPrimaryDark);
-        if (hasGroup && getControllerColor(context, 0) == COLOR_DARK_ON_LIGHT_BACKGROUND) {
-            // Instead of showing dark controls in a possibly dark (i.e. the primary dark), model
-            // the white dialog and use the primary color for the group controls.
-            primaryDarkColor = primaryColor;
-            primaryColor = Color.WHITE;
-        }
-        mainControls.setBackgroundColor(primaryColor);
-        groupControls.setBackgroundColor(primaryDarkColor);
-        // Also store the background colors to the view tags. They are used in
-        // setVolumeSliderColor() below.
-        mainControls.setTag(primaryColor);
-        groupControls.setTag(primaryDarkColor);
-    }
-
-    static void setVolumeSliderColor(
-            Context context, MediaRouteVolumeSlider volumeSlider, View backgroundView) {
-        int controllerColor = getControllerColor(context, 0);
-        if (Color.alpha(controllerColor) != 0xFF) {
-            // Composite with the background in order not to show the underlying progress bar
-            // through the thumb.
-            int backgroundColor = (int) backgroundView.getTag();
-            controllerColor = ColorUtils.compositeColors(controllerColor, backgroundColor);
-        }
-        volumeSlider.setColor(controllerColor);
-    }
-
-    private static boolean isLightTheme(Context context) {
-        TypedValue value = new TypedValue();
-        // TODO(sungsoo): Switch to com.android.internal.R.attr.isLightTheme
-        return context.getTheme().resolveAttribute(android.support.v7.appcompat.R.attr.isLightTheme,
-                value, true) && value.data != 0;
-    }
-
-    private static int getThemeColor(Context context, int style, int attr) {
-        if (style != 0) {
-            int[] attrs = { attr };
-            TypedArray ta = context.obtainStyledAttributes(style, attrs);
-            int color = ta.getColor(0, 0);
-            ta.recycle();
-            if (color != 0) {
-                return color;
-            }
-        }
-        TypedValue value = new TypedValue();
-        context.getTheme().resolveAttribute(attr, value, true);
-        if (value.resourceId != 0) {
-            return context.getResources().getColor(value.resourceId);
-        }
-        return value.data;
-    }
-
-    static int getRouterThemeId(Context context) {
-        int themeId;
-        if (isLightTheme(context)) {
-            if (getControllerColor(context, 0) == COLOR_DARK_ON_LIGHT_BACKGROUND) {
-                themeId = R.style.Theme_MediaRouter_Light;
-            } else {
-                themeId = R.style.Theme_MediaRouter_Light_DarkControlPanel;
-            }
-        } else {
-            if (getControllerColor(context, 0) == COLOR_DARK_ON_LIGHT_BACKGROUND) {
-                themeId = R.style.Theme_MediaRouter_LightControlPanel;
-            } else {
-                themeId = R.style.Theme_MediaRouter;
-            }
-        }
-        return themeId;
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/OverlayListView.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/OverlayListView.java
deleted file mode 100644
index b00dee2..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/OverlayListView.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.app;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.drawable.BitmapDrawable;
-import android.util.AttributeSet;
-import android.view.animation.Interpolator;
-import android.widget.ListView;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * A ListView which has an additional overlay layer. {@link BitmapDrawable}
- * can be added to the layer and can be animated.
- */
-public final class OverlayListView extends ListView {
-    private final List<OverlayObject> mOverlayObjects = new ArrayList<>();
-
-    public OverlayListView(Context context) {
-        super(context);
-    }
-
-    public OverlayListView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public OverlayListView(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    /**
-     * Adds an object to the overlay layer.
-     *
-     * @param object An object to be added.
-     */
-    public void addOverlayObject(OverlayObject object) {
-        mOverlayObjects.add(object);
-    }
-
-    /**
-     * Starts all animations of objects in the overlay layer.
-     */
-    public void startAnimationAll() {
-        for (OverlayObject object : mOverlayObjects) {
-            if (!object.isAnimationStarted()) {
-                object.startAnimation(getDrawingTime());
-            }
-        }
-    }
-
-    /**
-     * Stops all animations of objects in the overlay layer.
-     */
-    public void stopAnimationAll() {
-        for (OverlayObject object : mOverlayObjects) {
-            object.stopAnimation();
-        }
-    }
-
-    @Override
-    public void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-        if (mOverlayObjects.size() > 0) {
-            Iterator<OverlayObject> it = mOverlayObjects.iterator();
-            while (it.hasNext()) {
-                OverlayObject object = it.next();
-                BitmapDrawable bitmap = object.getBitmapDrawable();
-                if (bitmap != null) {
-                    bitmap.draw(canvas);
-                }
-                if (!object.update(getDrawingTime())) {
-                    it.remove();
-                }
-            }
-        }
-    }
-
-    /**
-     * A class that represents an object to be shown in the overlay layer.
-     */
-    public static class OverlayObject {
-        private BitmapDrawable mBitmap;
-        private float mCurrentAlpha = 1.0f;
-        private Rect mCurrentBounds;
-        private Interpolator mInterpolator;
-        private long mDuration;
-        private Rect mStartRect;
-        private int mDeltaY;
-        private float mStartAlpha = 1.0f;
-        private float mEndAlpha = 1.0f;
-        private long mStartTime;
-        private boolean mIsAnimationStarted;
-        private boolean mIsAnimationEnded;
-        private OnAnimationEndListener mListener;
-
-        public OverlayObject(BitmapDrawable bitmap, Rect startRect) {
-            mBitmap = bitmap;
-            mStartRect = startRect;
-            mCurrentBounds = new Rect(startRect);
-            if (mBitmap != null && mCurrentBounds != null) {
-                mBitmap.setAlpha((int) (mCurrentAlpha * 255));
-                mBitmap.setBounds(mCurrentBounds);
-            }
-        }
-
-        /**
-         * Returns the bitmap that this object represents.
-         *
-         * @return BitmapDrawable that this object has.
-         */
-        public BitmapDrawable getBitmapDrawable() {
-            return mBitmap;
-        }
-
-        /**
-         * Returns the started status of the animation.
-         *
-         * @return True if the animation has started, false otherwise.
-         */
-        public boolean isAnimationStarted() {
-            return mIsAnimationStarted;
-        }
-
-        /**
-         * Sets animation for varying alpha.
-         *
-         * @param startAlpha Starting alpha value for the animation, where 1.0 means
-         * fully opaque and 0.0 means fully transparent.
-         * @param endAlpha Ending alpha value for the animation.
-         * @return This OverlayObject to allow for chaining of calls.
-         */
-        public OverlayObject setAlphaAnimation(float startAlpha, float endAlpha) {
-            mStartAlpha = startAlpha;
-            mEndAlpha = endAlpha;
-            return this;
-        }
-
-        /**
-         * Sets animation for moving objects vertically.
-         *
-         * @param deltaY Distance to move in pixels.
-         * @return This OverlayObject to allow for chaining of calls.
-         */
-        public OverlayObject setTranslateYAnimation(int deltaY) {
-            mDeltaY = deltaY;
-            return this;
-        }
-
-        /**
-         * Sets how long the animation will last.
-         *
-         * @param duration Duration in milliseconds
-         * @return This OverlayObject to allow for chaining of calls.
-         */
-        public OverlayObject setDuration(long duration) {
-            mDuration = duration;
-            return this;
-        }
-
-        /**
-         * Sets the acceleration curve for this animation.
-         *
-         * @param interpolator The interpolator which defines the acceleration curve
-         * @return This OverlayObject to allow for chaining of calls.
-         */
-        public OverlayObject setInterpolator(Interpolator interpolator) {
-            mInterpolator = interpolator;
-            return this;
-        }
-
-        /**
-         * Binds an animation end listener to the animation.
-         *
-         * @param listener the animation end listener to be notified.
-         * @return This OverlayObject to allow for chaining of calls.
-         */
-        public OverlayObject setAnimationEndListener(OnAnimationEndListener listener) {
-            mListener = listener;
-            return this;
-        }
-
-        /**
-         * Starts the animation and sets the start time.
-         *
-         * @param startTime Start time to be set in Millis
-         */
-        public void startAnimation(long startTime) {
-            mStartTime = startTime;
-            mIsAnimationStarted = true;
-        }
-
-        /**
-         * Stops the animation.
-         */
-        public void stopAnimation() {
-            mIsAnimationStarted = true;
-            mIsAnimationEnded = true;
-            if (mListener != null) {
-                mListener.onAnimationEnd();
-            }
-        }
-
-        /**
-         * Calculates and updates current bounds and alpha value.
-         *
-         * @param currentTime Current time.in millis
-         */
-        public boolean update(long currentTime) {
-            if (mIsAnimationEnded) {
-                return false;
-            }
-            float normalizedTime = (currentTime - mStartTime) / (float) mDuration;
-            normalizedTime = Math.max(0.0f, Math.min(1.0f, normalizedTime));
-            if (!mIsAnimationStarted) {
-                normalizedTime = 0.0f;
-            }
-            float interpolatedTime = (mInterpolator == null) ? normalizedTime
-                    : mInterpolator.getInterpolation(normalizedTime);
-            int deltaY = (int) (mDeltaY * interpolatedTime);
-            mCurrentBounds.top = mStartRect.top + deltaY;
-            mCurrentBounds.bottom = mStartRect.bottom + deltaY;
-            mCurrentAlpha = mStartAlpha + (mEndAlpha - mStartAlpha) * interpolatedTime;
-            if (mBitmap != null && mCurrentBounds != null) {
-                mBitmap.setAlpha((int) (mCurrentAlpha * 255));
-                mBitmap.setBounds(mCurrentBounds);
-            }
-            if (mIsAnimationStarted && normalizedTime >= 1.0f) {
-                mIsAnimationEnded = true;
-                if (mListener != null) {
-                    mListener.onAnimationEnd();
-                }
-            }
-            return !mIsAnimationEnded;
-        }
-
-        /**
-         * An animation listener that receives notifications when the animation ends.
-         */
-        public interface OnAnimationEndListener {
-            /**
-             * Notifies the end of the animation.
-             */
-            public void onAnimationEnd();
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/jellybean-mr1/MediaRouterJellybeanMr1.java b/packages/MediaComponents/src/com/android/support/mediarouter/jellybean-mr1/MediaRouterJellybeanMr1.java
deleted file mode 100644
index f8539bd..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/jellybean-mr1/MediaRouterJellybeanMr1.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.media;
-
-import android.content.Context;
-import android.hardware.display.DisplayManager;
-import android.os.Build;
-import android.os.Handler;
-import android.support.annotation.RequiresApi;
-import android.util.Log;
-import android.view.Display;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-// @@RequiresApi(17)
-final class MediaRouterJellybeanMr1 {
-    private static final String TAG = "MediaRouterJellybeanMr1";
-
-    public static Object createCallback(Callback callback) {
-        return new CallbackProxy<Callback>(callback);
-    }
-
-    public static final class RouteInfo {
-        public static boolean isEnabled(Object routeObj) {
-            return ((android.media.MediaRouter.RouteInfo)routeObj).isEnabled();
-        }
-
-        public static Display getPresentationDisplay(Object routeObj) {
-            // android.media.MediaRouter.RouteInfo.getPresentationDisplay() was
-            // added in API 17. However, some factory releases of JB MR1 missed it.
-            try {
-                return ((android.media.MediaRouter.RouteInfo)routeObj).getPresentationDisplay();
-            } catch (NoSuchMethodError ex) {
-                Log.w(TAG, "Cannot get presentation display for the route.", ex);
-            }
-            return null;
-        }
-    }
-
-    public static interface Callback extends MediaRouterJellybean.Callback {
-        public void onRoutePresentationDisplayChanged(Object routeObj);
-    }
-
-    /**
-     * Workaround the fact that the version of MediaRouter.addCallback() that accepts a
-     * flag to perform an active scan does not exist in JB MR1 so we need to force
-     * wifi display scans directly through the DisplayManager.
-     * Do not use on JB MR2 and above.
-     */
-    public static final class ActiveScanWorkaround implements Runnable {
-        // Time between wifi display scans when actively scanning in milliseconds.
-        private static final int WIFI_DISPLAY_SCAN_INTERVAL = 15000;
-
-        private final DisplayManager mDisplayManager;
-        private final Handler mHandler;
-        private Method mScanWifiDisplaysMethod;
-
-        private boolean mActivelyScanningWifiDisplays;
-
-        public ActiveScanWorkaround(Context context, Handler handler) {
-            if (Build.VERSION.SDK_INT != 17) {
-                throw new UnsupportedOperationException();
-            }
-
-            mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
-            mHandler = handler;
-            try {
-                mScanWifiDisplaysMethod = DisplayManager.class.getMethod("scanWifiDisplays");
-            } catch (NoSuchMethodException ex) {
-            }
-        }
-
-        public void setActiveScanRouteTypes(int routeTypes) {
-            // On JB MR1, there is no API to scan wifi display routes.
-            // Instead we must make a direct call into the DisplayManager to scan
-            // wifi displays on this version but only when live video routes are requested.
-            // See also the JellybeanMr2Impl implementation of this method.
-            // This was fixed in JB MR2 by adding a new overload of addCallback() to
-            // enable active scanning on request.
-            if ((routeTypes & MediaRouterJellybean.ROUTE_TYPE_LIVE_VIDEO) != 0) {
-                if (!mActivelyScanningWifiDisplays) {
-                    if (mScanWifiDisplaysMethod != null) {
-                        mActivelyScanningWifiDisplays = true;
-                        mHandler.post(this);
-                    } else {
-                        Log.w(TAG, "Cannot scan for wifi displays because the "
-                                + "DisplayManager.scanWifiDisplays() method is "
-                                + "not available on this device.");
-                    }
-                }
-            } else {
-                if (mActivelyScanningWifiDisplays) {
-                    mActivelyScanningWifiDisplays = false;
-                    mHandler.removeCallbacks(this);
-                }
-            }
-        }
-
-        @Override
-        public void run() {
-            if (mActivelyScanningWifiDisplays) {
-                try {
-                    mScanWifiDisplaysMethod.invoke(mDisplayManager);
-                } catch (IllegalAccessException ex) {
-                    Log.w(TAG, "Cannot scan for wifi displays.", ex);
-                } catch (InvocationTargetException ex) {
-                    Log.w(TAG, "Cannot scan for wifi displays.", ex);
-                }
-                mHandler.postDelayed(this, WIFI_DISPLAY_SCAN_INTERVAL);
-            }
-        }
-    }
-
-    /**
-     * Workaround the fact that the isConnecting() method does not exist in JB MR1.
-     * Do not use on JB MR2 and above.
-     */
-    public static final class IsConnectingWorkaround {
-        private Method mGetStatusCodeMethod;
-        private int mStatusConnecting;
-
-        public IsConnectingWorkaround() {
-            if (Build.VERSION.SDK_INT != 17) {
-                throw new UnsupportedOperationException();
-            }
-
-            try {
-                Field statusConnectingField =
-                        android.media.MediaRouter.RouteInfo.class.getField("STATUS_CONNECTING");
-                mStatusConnecting = statusConnectingField.getInt(null);
-                mGetStatusCodeMethod =
-                        android.media.MediaRouter.RouteInfo.class.getMethod("getStatusCode");
-            } catch (NoSuchFieldException ex) {
-            } catch (NoSuchMethodException ex) {
-            } catch (IllegalAccessException ex) {
-            }
-        }
-
-        public boolean isConnecting(Object routeObj) {
-            android.media.MediaRouter.RouteInfo route =
-                    (android.media.MediaRouter.RouteInfo)routeObj;
-
-            if (mGetStatusCodeMethod != null) {
-                try {
-                    int statusCode = (Integer)mGetStatusCodeMethod.invoke(route);
-                    return statusCode == mStatusConnecting;
-                } catch (IllegalAccessException ex) {
-                } catch (InvocationTargetException ex) {
-                }
-            }
-
-            // Assume not connecting.
-            return false;
-        }
-    }
-
-    static class CallbackProxy<T extends Callback>
-            extends MediaRouterJellybean.CallbackProxy<T> {
-        public CallbackProxy(T callback) {
-            super(callback);
-        }
-
-        @Override
-        public void onRoutePresentationDisplayChanged(android.media.MediaRouter router,
-                android.media.MediaRouter.RouteInfo route) {
-            mCallback.onRoutePresentationDisplayChanged(route);
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/jellybean-mr2/MediaRouterJellybeanMr2.java b/packages/MediaComponents/src/com/android/support/mediarouter/jellybean-mr2/MediaRouterJellybeanMr2.java
deleted file mode 100644
index 1103549..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/jellybean-mr2/MediaRouterJellybeanMr2.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.media;
-
-// @@RequiresApi(18)
-final class MediaRouterJellybeanMr2 {
-    public static Object getDefaultRoute(Object routerObj) {
-        return ((android.media.MediaRouter)routerObj).getDefaultRoute();
-    }
-
-    public static void addCallback(Object routerObj, int types, Object callbackObj, int flags) {
-        ((android.media.MediaRouter)routerObj).addCallback(types,
-                (android.media.MediaRouter.Callback)callbackObj, flags);
-    }
-
-    public static final class RouteInfo {
-        public static CharSequence getDescription(Object routeObj) {
-            return ((android.media.MediaRouter.RouteInfo)routeObj).getDescription();
-        }
-
-        public static boolean isConnecting(Object routeObj) {
-            return ((android.media.MediaRouter.RouteInfo)routeObj).isConnecting();
-        }
-    }
-
-    public static final class UserRouteInfo {
-        public static void setDescription(Object routeObj, CharSequence description) {
-            ((android.media.MediaRouter.UserRouteInfo)routeObj).setDescription(description);
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/jellybean/MediaRouterJellybean.java b/packages/MediaComponents/src/com/android/support/mediarouter/jellybean/MediaRouterJellybean.java
deleted file mode 100644
index 0bb59b8..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/jellybean/MediaRouterJellybean.java
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.media;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.media.AudioManager;
-import android.os.Build;
-import android.util.Log;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-
-// @@RequiresApi(16)
-final class MediaRouterJellybean {
-    private static final String TAG = "MediaRouterJellybean";
-
-    // android.media.AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP = 0x80;
-    // android.media.AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100;
-    // android.media.AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200;
-    public static final int DEVICE_OUT_BLUETOOTH = 0x80 | 0x100 | 0x200;
-
-    public static final int ROUTE_TYPE_LIVE_AUDIO = 0x1;
-    public static final int ROUTE_TYPE_LIVE_VIDEO = 0x2;
-    public static final int ROUTE_TYPE_USER = 0x00800000;
-
-    public static final int ALL_ROUTE_TYPES =
-            MediaRouterJellybean.ROUTE_TYPE_LIVE_AUDIO
-            | MediaRouterJellybean.ROUTE_TYPE_LIVE_VIDEO
-            | MediaRouterJellybean.ROUTE_TYPE_USER;
-
-    public static Object getMediaRouter(Context context) {
-        return context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
-    }
-
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    public static List getRoutes(Object routerObj) {
-        final android.media.MediaRouter router = (android.media.MediaRouter)routerObj;
-        final int count = router.getRouteCount();
-        List out = new ArrayList(count);
-        for (int i = 0; i < count; i++) {
-            out.add(router.getRouteAt(i));
-        }
-        return out;
-    }
-
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    public static List getCategories(Object routerObj) {
-        final android.media.MediaRouter router = (android.media.MediaRouter)routerObj;
-        final int count = router.getCategoryCount();
-        List out = new ArrayList(count);
-        for (int i = 0; i < count; i++) {
-            out.add(router.getCategoryAt(i));
-        }
-        return out;
-    }
-
-    public static Object getSelectedRoute(Object routerObj, int type) {
-        return ((android.media.MediaRouter)routerObj).getSelectedRoute(type);
-    }
-
-    public static void selectRoute(Object routerObj, int types, Object routeObj) {
-        ((android.media.MediaRouter)routerObj).selectRoute(types,
-                (android.media.MediaRouter.RouteInfo)routeObj);
-    }
-
-    public static void addCallback(Object routerObj, int types, Object callbackObj) {
-        ((android.media.MediaRouter)routerObj).addCallback(types,
-                (android.media.MediaRouter.Callback)callbackObj);
-    }
-
-    public static void removeCallback(Object routerObj, Object callbackObj) {
-        ((android.media.MediaRouter)routerObj).removeCallback(
-                (android.media.MediaRouter.Callback)callbackObj);
-    }
-
-    public static Object createRouteCategory(Object routerObj,
-            String name, boolean isGroupable) {
-        return ((android.media.MediaRouter)routerObj).createRouteCategory(name, isGroupable);
-    }
-
-    public static Object createUserRoute(Object routerObj, Object categoryObj) {
-        return ((android.media.MediaRouter)routerObj).createUserRoute(
-                (android.media.MediaRouter.RouteCategory)categoryObj);
-    }
-
-    public static void addUserRoute(Object routerObj, Object routeObj) {
-        ((android.media.MediaRouter)routerObj).addUserRoute(
-                (android.media.MediaRouter.UserRouteInfo)routeObj);
-    }
-
-    public static void removeUserRoute(Object routerObj, Object routeObj) {
-        ((android.media.MediaRouter)routerObj).removeUserRoute(
-                (android.media.MediaRouter.UserRouteInfo)routeObj);
-    }
-
-    public static Object createCallback(Callback callback) {
-        return new CallbackProxy<Callback>(callback);
-    }
-
-    public static Object createVolumeCallback(VolumeCallback callback) {
-        return new VolumeCallbackProxy<VolumeCallback>(callback);
-    }
-
-    static boolean checkRoutedToBluetooth(Context context) {
-        try {
-            AudioManager audioManager = (AudioManager) context.getSystemService(
-                    Context.AUDIO_SERVICE);
-            Method method = audioManager.getClass().getDeclaredMethod(
-                    "getDevicesForStream", int.class);
-            int device = (Integer) method.invoke(audioManager, AudioManager.STREAM_MUSIC);
-            return (device & DEVICE_OUT_BLUETOOTH) != 0;
-        } catch (Exception e) {
-            return false;
-        }
-    }
-
-    public static final class RouteInfo {
-        public static CharSequence getName(Object routeObj, Context context) {
-            return ((android.media.MediaRouter.RouteInfo)routeObj).getName(context);
-        }
-
-        public static CharSequence getStatus(Object routeObj) {
-            return ((android.media.MediaRouter.RouteInfo)routeObj).getStatus();
-        }
-
-        public static int getSupportedTypes(Object routeObj) {
-            return ((android.media.MediaRouter.RouteInfo)routeObj).getSupportedTypes();
-        }
-
-        public static Object getCategory(Object routeObj) {
-            return ((android.media.MediaRouter.RouteInfo)routeObj).getCategory();
-        }
-
-        public static Drawable getIconDrawable(Object routeObj) {
-            return ((android.media.MediaRouter.RouteInfo)routeObj).getIconDrawable();
-        }
-
-        public static int getPlaybackType(Object routeObj) {
-            return ((android.media.MediaRouter.RouteInfo)routeObj).getPlaybackType();
-        }
-
-        public static int getPlaybackStream(Object routeObj) {
-            return ((android.media.MediaRouter.RouteInfo)routeObj).getPlaybackStream();
-        }
-
-        public static int getVolume(Object routeObj) {
-            return ((android.media.MediaRouter.RouteInfo)routeObj).getVolume();
-        }
-
-        public static int getVolumeMax(Object routeObj) {
-            return ((android.media.MediaRouter.RouteInfo)routeObj).getVolumeMax();
-        }
-
-        public static int getVolumeHandling(Object routeObj) {
-            return ((android.media.MediaRouter.RouteInfo)routeObj).getVolumeHandling();
-        }
-
-        public static Object getTag(Object routeObj) {
-            return ((android.media.MediaRouter.RouteInfo)routeObj).getTag();
-        }
-
-        public static void setTag(Object routeObj, Object tag) {
-            ((android.media.MediaRouter.RouteInfo)routeObj).setTag(tag);
-        }
-
-        public static void requestSetVolume(Object routeObj, int volume) {
-            ((android.media.MediaRouter.RouteInfo)routeObj).requestSetVolume(volume);
-        }
-
-        public static void requestUpdateVolume(Object routeObj, int direction) {
-            ((android.media.MediaRouter.RouteInfo)routeObj).requestUpdateVolume(direction);
-        }
-
-        public static Object getGroup(Object routeObj) {
-            return ((android.media.MediaRouter.RouteInfo)routeObj).getGroup();
-        }
-
-        public static boolean isGroup(Object routeObj) {
-            return routeObj instanceof android.media.MediaRouter.RouteGroup;
-        }
-    }
-
-    public static final class RouteGroup {
-        @SuppressWarnings({ "rawtypes", "unchecked" })
-        public static List getGroupedRoutes(Object groupObj) {
-            final android.media.MediaRouter.RouteGroup group =
-                    (android.media.MediaRouter.RouteGroup)groupObj;
-            final int count = group.getRouteCount();
-            List out = new ArrayList(count);
-            for (int i = 0; i < count; i++) {
-                out.add(group.getRouteAt(i));
-            }
-            return out;
-        }
-    }
-
-    public static final class UserRouteInfo {
-        public static void setName(Object routeObj, CharSequence name) {
-            ((android.media.MediaRouter.UserRouteInfo)routeObj).setName(name);
-        }
-
-        public static void setStatus(Object routeObj, CharSequence status) {
-            ((android.media.MediaRouter.UserRouteInfo)routeObj).setStatus(status);
-        }
-
-        public static void setIconDrawable(Object routeObj, Drawable icon) {
-            ((android.media.MediaRouter.UserRouteInfo)routeObj).setIconDrawable(icon);
-        }
-
-        public static void setPlaybackType(Object routeObj, int type) {
-            ((android.media.MediaRouter.UserRouteInfo)routeObj).setPlaybackType(type);
-        }
-
-        public static void setPlaybackStream(Object routeObj, int stream) {
-            ((android.media.MediaRouter.UserRouteInfo)routeObj).setPlaybackStream(stream);
-        }
-
-        public static void setVolume(Object routeObj, int volume) {
-            ((android.media.MediaRouter.UserRouteInfo)routeObj).setVolume(volume);
-        }
-
-        public static void setVolumeMax(Object routeObj, int volumeMax) {
-            ((android.media.MediaRouter.UserRouteInfo)routeObj).setVolumeMax(volumeMax);
-        }
-
-        public static void setVolumeHandling(Object routeObj, int volumeHandling) {
-            ((android.media.MediaRouter.UserRouteInfo)routeObj).setVolumeHandling(volumeHandling);
-        }
-
-        public static void setVolumeCallback(Object routeObj, Object volumeCallbackObj) {
-            ((android.media.MediaRouter.UserRouteInfo)routeObj).setVolumeCallback(
-                    (android.media.MediaRouter.VolumeCallback)volumeCallbackObj);
-        }
-
-        public static void setRemoteControlClient(Object routeObj, Object rccObj) {
-            ((android.media.MediaRouter.UserRouteInfo)routeObj).setRemoteControlClient(
-                    (android.media.RemoteControlClient)rccObj);
-        }
-    }
-
-    public static final class RouteCategory {
-        public static CharSequence getName(Object categoryObj, Context context) {
-            return ((android.media.MediaRouter.RouteCategory)categoryObj).getName(context);
-        }
-
-        @SuppressWarnings({ "rawtypes", "unchecked" })
-        public static List getRoutes(Object categoryObj) {
-            ArrayList out = new ArrayList();
-            ((android.media.MediaRouter.RouteCategory)categoryObj).getRoutes(out);
-            return out;
-        }
-
-        public static int getSupportedTypes(Object categoryObj) {
-            return ((android.media.MediaRouter.RouteCategory)categoryObj).getSupportedTypes();
-        }
-
-        public static boolean isGroupable(Object categoryObj) {
-            return ((android.media.MediaRouter.RouteCategory)categoryObj).isGroupable();
-        }
-    }
-
-    public static interface Callback {
-        public void onRouteSelected(int type, Object routeObj);
-        public void onRouteUnselected(int type, Object routeObj);
-        public void onRouteAdded(Object routeObj);
-        public void onRouteRemoved(Object routeObj);
-        public void onRouteChanged(Object routeObj);
-        public void onRouteGrouped(Object routeObj, Object groupObj, int index);
-        public void onRouteUngrouped(Object routeObj, Object groupObj);
-        public void onRouteVolumeChanged(Object routeObj);
-    }
-
-    public static interface VolumeCallback {
-        public void onVolumeSetRequest(Object routeObj, int volume);
-        public void onVolumeUpdateRequest(Object routeObj, int direction);
-    }
-
-    /**
-     * Workaround for limitations of selectRoute() on JB and JB MR1.
-     * Do not use on JB MR2 and above.
-     */
-    public static final class SelectRouteWorkaround {
-        private Method mSelectRouteIntMethod;
-
-        public SelectRouteWorkaround() {
-            if (Build.VERSION.SDK_INT < 16 || Build.VERSION.SDK_INT > 17) {
-                throw new UnsupportedOperationException();
-            }
-            try {
-                mSelectRouteIntMethod = android.media.MediaRouter.class.getMethod(
-                        "selectRouteInt", int.class, android.media.MediaRouter.RouteInfo.class);
-            } catch (NoSuchMethodException ex) {
-            }
-        }
-
-        public void selectRoute(Object routerObj, int types, Object routeObj) {
-            android.media.MediaRouter router = (android.media.MediaRouter)routerObj;
-            android.media.MediaRouter.RouteInfo route =
-                    (android.media.MediaRouter.RouteInfo)routeObj;
-
-            int routeTypes = route.getSupportedTypes();
-            if ((routeTypes & ROUTE_TYPE_USER) == 0) {
-                // Handle non-user routes.
-                // On JB and JB MR1, the selectRoute() API only supports programmatically
-                // selecting user routes.  So instead we rely on the hidden selectRouteInt()
-                // method on these versions of the platform.
-                // This limitation was removed in JB MR2.
-                if (mSelectRouteIntMethod != null) {
-                    try {
-                        mSelectRouteIntMethod.invoke(router, types, route);
-                        return; // success!
-                    } catch (IllegalAccessException ex) {
-                        Log.w(TAG, "Cannot programmatically select non-user route.  "
-                                + "Media routing may not work.", ex);
-                    } catch (InvocationTargetException ex) {
-                        Log.w(TAG, "Cannot programmatically select non-user route.  "
-                                + "Media routing may not work.", ex);
-                    }
-                } else {
-                    Log.w(TAG, "Cannot programmatically select non-user route "
-                            + "because the platform is missing the selectRouteInt() "
-                            + "method.  Media routing may not work.");
-                }
-            }
-
-            // Default handling.
-            router.selectRoute(types, route);
-        }
-    }
-
-    /**
-     * Workaround the fact that the getDefaultRoute() method does not exist in JB and JB MR1.
-     * Do not use on JB MR2 and above.
-     */
-    public static final class GetDefaultRouteWorkaround {
-        private Method mGetSystemAudioRouteMethod;
-
-        public GetDefaultRouteWorkaround() {
-            if (Build.VERSION.SDK_INT < 16 || Build.VERSION.SDK_INT > 17) {
-                throw new UnsupportedOperationException();
-            }
-            try {
-                mGetSystemAudioRouteMethod =
-                        android.media.MediaRouter.class.getMethod("getSystemAudioRoute");
-            } catch (NoSuchMethodException ex) {
-            }
-        }
-
-        public Object getDefaultRoute(Object routerObj) {
-            android.media.MediaRouter router = (android.media.MediaRouter)routerObj;
-
-            if (mGetSystemAudioRouteMethod != null) {
-                try {
-                    return mGetSystemAudioRouteMethod.invoke(router);
-                } catch (IllegalAccessException ex) {
-                } catch (InvocationTargetException ex) {
-                }
-            }
-
-            // Could not find the method or it does not work.
-            // Return the first route and hope for the best.
-            return router.getRouteAt(0);
-        }
-    }
-
-    static class CallbackProxy<T extends Callback>
-            extends android.media.MediaRouter.Callback {
-        protected final T mCallback;
-
-        public CallbackProxy(T callback) {
-            mCallback = callback;
-        }
-
-        @Override
-        public void onRouteSelected(android.media.MediaRouter router,
-                int type, android.media.MediaRouter.RouteInfo route) {
-            mCallback.onRouteSelected(type, route);
-        }
-
-        @Override
-        public void onRouteUnselected(android.media.MediaRouter router,
-                int type, android.media.MediaRouter.RouteInfo route) {
-            mCallback.onRouteUnselected(type, route);
-        }
-
-        @Override
-        public void onRouteAdded(android.media.MediaRouter router,
-                android.media.MediaRouter.RouteInfo route) {
-            mCallback.onRouteAdded(route);
-        }
-
-        @Override
-        public void onRouteRemoved(android.media.MediaRouter router,
-                android.media.MediaRouter.RouteInfo route) {
-            mCallback.onRouteRemoved(route);
-        }
-
-        @Override
-        public void onRouteChanged(android.media.MediaRouter router,
-                android.media.MediaRouter.RouteInfo route) {
-            mCallback.onRouteChanged(route);
-        }
-
-        @Override
-        public void onRouteGrouped(android.media.MediaRouter router,
-                android.media.MediaRouter.RouteInfo route,
-                android.media.MediaRouter.RouteGroup group, int index) {
-            mCallback.onRouteGrouped(route, group, index);
-        }
-
-        @Override
-        public void onRouteUngrouped(android.media.MediaRouter router,
-                android.media.MediaRouter.RouteInfo route,
-                android.media.MediaRouter.RouteGroup group) {
-            mCallback.onRouteUngrouped(route, group);
-        }
-
-        @Override
-        public void onRouteVolumeChanged(android.media.MediaRouter router,
-                android.media.MediaRouter.RouteInfo route) {
-            mCallback.onRouteVolumeChanged(route);
-        }
-    }
-
-    static class VolumeCallbackProxy<T extends VolumeCallback>
-            extends android.media.MediaRouter.VolumeCallback {
-        protected final T mCallback;
-
-        public VolumeCallbackProxy(T callback) {
-            mCallback = callback;
-        }
-
-        @Override
-        public void onVolumeSetRequest(android.media.MediaRouter.RouteInfo route,
-                int volume) {
-            mCallback.onVolumeSetRequest(route, volume);
-        }
-
-        @Override
-        public void onVolumeUpdateRequest(android.media.MediaRouter.RouteInfo route,
-                int direction) {
-            mCallback.onVolumeUpdateRequest(route, direction);
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaControlIntent.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaControlIntent.java
deleted file mode 100644
index 1d9e777..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaControlIntent.java
+++ /dev/null
@@ -1,1228 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.media;
-
-import android.app.PendingIntent;
-import android.content.Intent;
-import android.net.Uri;
-
-/**
- * Constants for media control intents.
- * <p>
- * This class declares a set of standard media control intent categories and actions that
- * applications can use to identify the capabilities of media routes and control them.
- * </p>
- *
- * <h3>Media control intent categories</h3>
- * <p>
- * Media control intent categories specify means by which applications can
- * send media to the destination of a media route.  Categories are sometimes referred
- * to as describing "types" or "kinds" of routes.
- * </p><p>
- * For example, if a route supports the {@link #CATEGORY_REMOTE_PLAYBACK remote playback category},
- * then an application can ask it to play media remotely by sending a
- * {@link #ACTION_PLAY play} or {@link #ACTION_ENQUEUE enqueue} intent with the Uri of the
- * media content to play.  Such a route may then be referred to as
- * a "remote playback route" because it supports remote playback requests.  It is common
- * for a route to support multiple categories of requests at the same time, such as
- * live audio and live video.
- * </p><p>
- * The following standard route categories are defined.
- * </p><ul>
- * <li>{@link #CATEGORY_LIVE_AUDIO Live audio}: The route supports streaming live audio
- * from the device to the destination.  Live audio routes include local speakers
- * and Bluetooth headsets.
- * <li>{@link #CATEGORY_LIVE_VIDEO Live video}: The route supports streaming live video
- * from the device to the destination.  Live video routes include local displays
- * and wireless displays that support mirroring and
- * {@link android.app.Presentation presentations}.  Live video routes typically also
- * support live audio capabilities.
- * <li>{@link #CATEGORY_REMOTE_PLAYBACK Remote playback}: The route supports sending
- * remote playback requests for media content to the destination.  The content to be
- * played is identified by a Uri and mime-type.
- * </ul><p>
- * Media route providers may define custom media control intent categories of their own in
- * addition to the standard ones.  Custom categories can be used to provide a variety
- * of features to applications that recognize and know how to use them.  For example,
- * a media route provider might define a custom category to indicate that its routes
- * support a special device-specific control interface in addition to other
- * standard features.
- * </p><p>
- * Applications can determine which categories a route supports by using the
- * {@link MediaRouter.RouteInfo#supportsControlCategory MediaRouter.RouteInfo.supportsControlCategory}
- * or {@link MediaRouter.RouteInfo#getControlFilters MediaRouter.RouteInfo.getControlFilters}
- * methods.  Applications can also specify the types of routes that they want to use by
- * creating {@link MediaRouteSelector media route selectors} that contain the desired
- * categories and are used to filter routes in several parts of the media router API.
- * </p>
- *
- * <h3>Media control intent actions</h3>
- * <p>
- * Media control intent actions specify particular functions that applications
- * can ask the destination of a media route to perform.  Media route control requests
- * take the form of intents in a similar manner to other intents used to start activities
- * or send broadcasts.  The difference is that media control intents are directed to
- * routes rather than activity or broadcast receiver components.
- * </p><p>
- * Each media route control intent specifies an action, a category and some number of parameters
- * that are supplied as extras.  Applications send media control requests to routes using the
- * {@link MediaRouter.RouteInfo#sendControlRequest MediaRouter.RouteInfo.sendControlRequest}
- * method and receive results via a callback.
- * </p><p>
- * All media control intent actions are associated with the media control intent categories
- * that support them.  Thus only remote playback routes may perform remote playback actions.
- * The documentation of each action specifies the category to which the action belongs,
- * the parameters it requires, and the results it returns.
- * </p>
- *
- * <h3>Live audio and live video routes</h3>
- * <p>
- * {@link #CATEGORY_LIVE_AUDIO Live audio} and {@link #CATEGORY_LIVE_VIDEO live video}
- * routes present media using standard system interfaces such as audio streams,
- * {@link android.app.Presentation presentations} or display mirroring.  These routes are
- * the easiest to use because applications simply render content locally on the device
- * and the system streams it to the route destination automatically.
- * </p><p>
- * In most cases, applications can stream content to live audio and live video routes in
- * the same way they would play the content locally without any modification.  However,
- * applications may also be able to take advantage of more sophisticated features such
- * as second-screen presentation APIs that are particular to these routes.
- * </p>
- *
- * <h3>Remote playback routes</h3>
- * <p>
- * {@link #CATEGORY_REMOTE_PLAYBACK Remote playback} routes present media remotely
- * by playing content from a Uri.
- * These routes destinations take responsibility for fetching and rendering content
- * on their own.  Applications do not render the content themselves; instead, applications
- * send control requests to initiate play, pause, resume, or stop media items and receive
- * status updates as they change state.
- * </p>
- *
- * <h4>Sessions</h4>
- * <p>
- * Each remote media playback action is conducted within the scope of a session.
- * Sessions are used to prevent applications from accidentally interfering with one
- * another because at most one session can be valid at a time.
- * </p><p>
- * A session can be created using the {@link #ACTION_START_SESSION start session action}
- * and terminated using the {@link #ACTION_END_SESSION end session action} when the
- * route provides explicit session management features.
- * </p><p>
- * Explicit session management was added in a later revision of the protocol so not
- * all routes support it.  If the route does not support explicit session management
- * then implicit session management may still be used.  Implicit session management
- * relies on the use of the {@link #ACTION_PLAY play} and {@link #ACTION_ENQUEUE enqueue}
- * actions which have the side-effect of creating a new session if none is provided
- * as argument.
- * </p><p>
- * When a new session is created, the previous session is invalidated and any ongoing
- * media playback is stopped before the requested action is performed.  Any attempt
- * to use an invalidated session will result in an error.  (Protocol implementations
- * are encouraged to aggressively discard information associated with invalidated sessions
- * since it is no longer of use.)
- * </p><p>
- * Each session is identified by a unique session id that may be used to control
- * the session using actions such as pause, resume, stop and end session.
- * </p>
- *
- * <h4>Media items</h4>
- * <p>
- * Each successful {@link #ACTION_PLAY play} or {@link #ACTION_ENQUEUE enqueue} action
- * returns a unique media item id that an application can use to monitor and control
- * playback.  The media item id may be passed to other actions such as
- * {@link #ACTION_SEEK seek} or {@link #ACTION_GET_STATUS get status}.  It will also appear
- * as a parameter in status update broadcasts to identify the associated playback request.
- * </p><p>
- * Each media item is scoped to the session in which it was created.  Therefore media item
- * ids are only ever used together with session ids.  Media item ids are meaningless
- * on their own.  When the session is invalidated, all of its media items are also
- * invalidated.
- * </p>
- *
- * <h4>The playback queue</h4>
- * <p>
- * Each session has its own playback queue that consists of the media items that
- * are pending, playing, buffering or paused.  Items are added to the queue when
- * a playback request is issued.  Items are removed from the queue when they are no
- * longer eligible for playback (enter terminal states).
- * </p><p>
- * As described in the {@link MediaItemStatus} class, media items initially
- * start in a pending state, transition to the playing (or buffering or paused) state
- * during playback, and end in a finished, canceled, invalidated or error state.
- * Once the current item enters a terminal state, playback proceeds on to the
- * next item.
- * </p><p>
- * The application should determine whether the route supports queuing by checking
- * whether the {@link #ACTION_ENQUEUE} action is declared in the route's control filter
- * using {@link MediaRouter.RouteInfo#supportsControlRequest RouteInfo.supportsControlRequest}.
- * </p><p>
- * If the {@link #ACTION_ENQUEUE} action is supported by the route, then the route promises
- * to allow at least two items (possibly more) to be enqueued at a time.  Enqueued items play
- * back to back one after the other as the previous item completes.  Ideally there should
- * be no audible pause between items for standard audio content types.
- * </p><p>
- * If the {@link #ACTION_ENQUEUE} action is not supported by the route, then the queue
- * effectively contains at most one item at a time.  Each play action has the effect of
- * clearing the queue and resetting its state before the next item is played.
- * </p>
- *
- * <h4>Impact of pause, resume, stop and play actions on the playback queue</h4>
- * <p>
- * The pause, resume and stop actions affect the session's whole queue.  Pause causes
- * the playback queue to be suspended no matter which item is currently playing.
- * Resume reverses the effects of pause.  Stop clears the queue and also resets
- * the pause flag just like resume.
- * </p><p>
- * As described earlier, the play action has the effect of clearing the queue
- * and completely resetting its state (like the stop action) then enqueuing a
- * new media item to be played immediately.  Play is therefore equivalent
- * to stop followed by an action to enqueue an item.
- * </p><p>
- * The play action is also special in that it can be used to create new sessions.
- * An application with simple needs may find that it only needs to use play
- * (and occasionally stop) to control playback.
- * </p>
- *
- * <h4>Resolving conflicts between applications</h4>
- * <p>
- * When an application has a valid session, it is essentially in control of remote playback
- * on the route.  No other application can view or modify the remote playback state
- * of that application's session without knowing its id.
- * </p><p>
- * However, other applications can perform actions that have the effect of stopping
- * playback and invalidating the current session.  When this occurs, the former application
- * will be informed that it has lost control by way of individual media item status
- * update broadcasts that indicate that its queued media items have become
- * {@link MediaItemStatus#PLAYBACK_STATE_INVALIDATED invalidated}.  This broadcast
- * implies that playback was terminated abnormally by an external cause.
- * </p><p>
- * Applications should handle conflicts conservatively to allow other applications to
- * smoothly assume control over the route.  When a conflict occurs, the currently playing
- * application should release its session and allow the new application to use the
- * route until such time as the user intervenes to take over the route again and begin
- * a new playback session.
- * </p>
- *
- * <h4>Basic actions</h4>
- * <p>
- * The following basic actions must be supported (all or nothing) by all remote
- * playback routes.  These actions form the basis of the remote playback protocol
- * and are required in all implementations.
- * </p><ul>
- * <li>{@link #ACTION_PLAY Play}: Starts playing content specified by a given Uri
- * and returns a new media item id to describe the request.  Implicitly creates a new
- * session if no session id was specified as a parameter.
- * <li>{@link #ACTION_SEEK Seek}: Sets the content playback position of a specific media item.
- * <li>{@link #ACTION_GET_STATUS Get status}: Gets the status of a media item
- * including the item's current playback position and progress.
- * <li>{@link #ACTION_PAUSE Pause}: Pauses playback of the queue.
- * <li>{@link #ACTION_RESUME Resume}: Resumes playback of the queue.
- * <li>{@link #ACTION_STOP Stop}: Stops playback, clears the queue, and resets the
- * pause state.
- * </ul>
- *
- * <h4>Queue actions</h4>
- * <p>
- * The following queue actions must be supported (all or nothing) by remote
- * playback routes that offer optional queuing capabilities.
- * </p><ul>
- * <li>{@link #ACTION_ENQUEUE Enqueue}: Enqueues content specified by a given Uri
- * and returns a new media item id to describe the request.  Implicitly creates a new
- * session if no session id was specified as a parameter.
- * <li>{@link #ACTION_REMOVE Remove}: Removes a specified media item from the queue.
- * </ul>
- *
- * <h4>Session actions</h4>
- * <p>
- * The following session actions must be supported (all or nothing) by remote
- * playback routes that offer optional session management capabilities.
- * </p><ul>
- * <li>{@link #ACTION_START_SESSION Start session}: Starts a new session explicitly.
- * <li>{@link #ACTION_GET_SESSION_STATUS Get session status}: Gets the status of a session.
- * <li>{@link #ACTION_END_SESSION End session}: Ends a session explicitly.
- * </ul>
- *
- * <h4>Implementation note</h4>
- * <p>
- * Implementations of the remote playback protocol must implement <em>all</em> of the
- * documented actions, parameters and results.  Note that the documentation is written from
- * the perspective of a client of the protocol.  In particular, whenever a parameter
- * is described as being "optional", it is only from the perspective of the client.
- * Compliant media route provider implementations of this protocol must support all
- * of the features described herein.
- * </p>
- */
-public final class MediaControlIntent {
-    /* Route categories. */
-
-    /**
-     * Media control category: Live audio.
-     * <p>
-     * A route that supports live audio routing will allow the media audio stream
-     * to be sent to supported destinations.  This can include internal speakers or
-     * audio jacks on the device itself, A2DP devices, and more.
-     * </p><p>
-     * When a live audio route is selected, audio routing is transparent to the application.
-     * All audio played on the media stream will be routed to the selected destination.
-     * </p><p>
-     * Refer to the class documentation for details about live audio routes.
-     * </p>
-     */
-    public static final String CATEGORY_LIVE_AUDIO = "android.media.intent.category.LIVE_AUDIO";
-
-    /**
-     * Media control category: Live video.
-     * <p>
-     * A route that supports live video routing will allow a mirrored version
-     * of the device's primary display or a customized
-     * {@link android.app.Presentation Presentation} to be sent to supported
-     * destinations.
-     * </p><p>
-     * When a live video route is selected, audio and video routing is transparent
-     * to the application.  By default, audio and video is routed to the selected
-     * destination.  For certain live video routes, the application may also use a
-     * {@link android.app.Presentation Presentation} to replace the mirrored view
-     * on the external display with different content.
-     * </p><p>
-     * Refer to the class documentation for details about live video routes.
-     * </p>
-     *
-     * @see MediaRouter.RouteInfo#getPresentationDisplay()
-     * @see android.app.Presentation
-     */
-    public static final String CATEGORY_LIVE_VIDEO = "android.media.intent.category.LIVE_VIDEO";
-
-    /**
-     * Media control category: Remote playback.
-     * <p>
-     * A route that supports remote playback routing will allow an application to send
-     * requests to play content remotely to supported destinations.
-     * </p><p>
-     * Remote playback routes destinations operate independently of the local device.
-     * When a remote playback route is selected, the application can control the content
-     * playing on the destination by sending media control actions to the route.
-     * The application may also receive status updates from the route regarding
-     * remote playback.
-     * </p><p>
-     * Refer to the class documentation for details about remote playback routes.
-     * </p>
-     *
-     * @see MediaRouter.RouteInfo#sendControlRequest
-     */
-    public static final String CATEGORY_REMOTE_PLAYBACK =
-            "android.media.intent.category.REMOTE_PLAYBACK";
-
-    /* Remote playback actions that affect individual items. */
-
-    /**
-     * Remote playback media control action: Play media item.
-     * <p>
-     * Used with routes that support {@link #CATEGORY_REMOTE_PLAYBACK remote playback}
-     * media control.
-     * </p><p>
-     * This action causes a remote playback route to start playing content with
-     * the {@link Uri} specified in the {@link Intent}'s {@link Intent#getData() data uri}.
-     * The action returns a media session id and media item id which can be used
-     * to control playback using other remote playback actions.
-     * </p><p>
-     * Once initiated, playback of the specified content will be managed independently
-     * by the destination.  The application will receive status updates as the state
-     * of the media item changes.
-     * </p><p>
-     * If the data uri specifies an HTTP or HTTPS scheme, then the destination is
-     * responsible for following HTTP redirects to a reasonable depth of at least 3
-     * levels as might typically be handled by a web browser.  If an HTTP error
-     * occurs, then the destination should send a {@link MediaItemStatus status update}
-     * back to the client indicating the {@link MediaItemStatus#PLAYBACK_STATE_ERROR error}
-     * {@link MediaItemStatus#getPlaybackState() playback state}.
-     * </p>
-     *
-     * <h3>One item at a time</h3>
-     * <p>
-     * Each successful play action <em>replaces</em> the previous play action.
-     * If an item is already playing, then it is canceled, the session's playback queue
-     * is cleared and the new item begins playing immediately (regardless of
-     * whether the previously playing item had been paused).
-     * </p><p>
-     * Play is therefore equivalent to {@link #ACTION_STOP stop} followed by an action
-     * to enqueue a new media item to be played immediately.
-     * </p>
-     *
-     * <h3>Sessions</h3>
-     * <p>
-     * This request has the effect of implicitly creating a media session whenever the
-     * application does not specify the {@link #EXTRA_SESSION_ID session id} parameter.
-     * Because there can only be at most one valid session at a time, creating a new session
-     * has the side-effect of invalidating any existing sessions and their media items,
-     * then handling the playback request with a new session.
-     * </p><p>
-     * If the application specifies an invalid session id, then an error is returned.
-     * When this happens, the application should assume that its session
-     * is no longer valid.  To obtain a new session, the application may try again
-     * and omit the session id parameter.  However, the application should
-     * only retry requests due to an explicit action performed by the user,
-     * such as the user clicking on a "play" button in the UI, since another
-     * application may be trying to take control of the route and the former
-     * application should try to stay out of its way.
-     * </p><p>
-     * For more information on sessions, queues and media items, please refer to the
-     * class documentation.
-     * </p>
-     *
-     * <h3>Request parameters</h3>
-     * <ul>
-     * <li>{@link #EXTRA_SESSION_ID} <em>(optional)</em>: Specifies the session id of the
-     * session to which the playback request belongs.  If omitted, a new session
-     * is created implicitly.
-     * <li>{@link #EXTRA_ITEM_CONTENT_POSITION} <em>(optional)</em>: Specifies the initial
-     * content playback position as a long integer number of milliseconds from
-     * the beginning of the content.
-     * <li>{@link #EXTRA_ITEM_METADATA} <em>(optional)</em>: Specifies metadata associated
-     * with the content such as the title of a song.
-     * <li>{@link #EXTRA_ITEM_STATUS_UPDATE_RECEIVER} <em>(optional)</em>: Specifies a
-     * {@link PendingIntent} for a broadcast receiver that will receive status updates
-     * about the media item.
-     * </ul>
-     *
-     * <h3>Result data</h3>
-     * <ul>
-     * <li>{@link #EXTRA_SESSION_ID} <em>(always returned)</em>: Specifies the session id of the
-     * session that was affected by the request.  This will be a new session in
-     * the case where no session id was supplied as a parameter.
-     * <li>{@link #EXTRA_SESSION_STATUS} <em>(optional, old implementations may
-     * omit this key)</em>: Specifies the status of the media session.
-     * <li>{@link #EXTRA_ITEM_ID} <em>(always returned)</em>: Specifies an opaque string identifier
-     * to use to refer to the media item in subsequent requests such as
-     * {@link #ACTION_GET_STATUS}.
-     * <li>{@link #EXTRA_ITEM_STATUS} <em>(always returned)</em>: Specifies the initial status of
-     * the new media item.
-     * </ul>
-     *
-     * <h3>Status updates</h3>
-     * <p>
-     * If the client supplies an
-     * {@link #EXTRA_ITEM_STATUS_UPDATE_RECEIVER item status update receiver}
-     * then the media route provider is responsible for sending status updates to the receiver
-     * when significant media item state changes occur such as when playback starts or
-     * stops.  The receiver will not be invoked for content playback position changes.
-     * The application may retrieve the current playback position when necessary
-     * using the {@link #ACTION_GET_STATUS} request.
-     * </p><p>
-     * Refer to {@link MediaItemStatus} for details.
-     * </p>
-     *
-     * <h3>Errors</h3>
-     * <p>
-     * This action returns an error if a session id was provided but is unknown or
-     * no longer valid, if the item Uri or content type is not supported, or if
-     * any other arguments are invalid.
-     * </p><ul>
-     * <li>{@link #EXTRA_ERROR_CODE} <em>(optional)</em>: Specifies the cause of the error.
-     * </ul>
-     *
-     * <h3>Example</h3>
-     * <pre>
-     * MediaRouter mediaRouter = MediaRouter.getInstance(context);
-     * MediaRouter.RouteInfo route = mediaRouter.getSelectedRoute();
-     * Intent intent = new Intent(MediaControlIntent.ACTION_PLAY);
-     * intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
-     * intent.setDataAndType("http://example.com/videos/movie.mp4", "video/mp4");
-     * if (route.supportsControlRequest(intent)) {
-     *     MediaRouter.ControlRequestCallback callback = new MediaRouter.ControlRequestCallback() {
-     *         public void onResult(Bundle data) {
-     *             // The request succeeded.
-     *             // Playback may be controlled using the returned session and item id.
-     *             String sessionId = data.getString(MediaControlIntent.EXTRA_SESSION_ID);
-     *             String itemId = data.getString(MediaControlIntent.EXTRA_ITEM_ID);
-     *             MediaItemStatus status = MediaItemStatus.fromBundle(data.getBundle(
-     *                     MediaControlIntent.EXTRA_ITEM_STATUS));
-     *             // ...
-     *         }
-     *
-     *         public void onError(String message, Bundle data) {
-     *             // An error occurred!
-     *         }
-     *     };
-     *     route.sendControlRequest(intent, callback);
-     * }</pre>
-     *
-     * @see MediaRouter.RouteInfo#sendControlRequest
-     * @see #CATEGORY_REMOTE_PLAYBACK
-     * @see #ACTION_SEEK
-     * @see #ACTION_GET_STATUS
-     * @see #ACTION_PAUSE
-     * @see #ACTION_RESUME
-     * @see #ACTION_STOP
-     */
-    public static final String ACTION_PLAY = "android.media.intent.action.PLAY";
-
-    /**
-     * Remote playback media control action: Enqueue media item.
-     * <p>
-     * Used with routes that support {@link #CATEGORY_REMOTE_PLAYBACK remote playback}
-     * media control.
-     * </p><p>
-     * This action works just like {@link #ACTION_PLAY play} except that it does
-     * not clear the queue or reset the pause state when it enqueues the
-     * new media item into the session's playback queue.  This action only
-     * enqueues a media item with no other side-effects on the queue.
-     * </p><p>
-     * If the queue is currently empty and then the item will play immediately
-     * (assuming the queue is not paused).  Otherwise, the item will play
-     * after all earlier items in the queue have finished or been removed.
-     * </p><p>
-     * The enqueue action can be used to create new sessions just like play.
-     * Its parameters and results are also the same.  Only the queuing behavior
-     * is different.
-     * </p>
-     *
-     * @see #ACTION_PLAY
-     */
-    public static final String ACTION_ENQUEUE = "android.media.intent.action.ENQUEUE";
-
-    /**
-     * Remote playback media control action: Seek media item to a new playback position.
-     * <p>
-     * Used with routes that support {@link #CATEGORY_REMOTE_PLAYBACK remote playback}
-     * media control.
-     * </p><p>
-     * This action causes a remote playback route to modify the current playback position
-     * of the specified media item.
-     * </p><p>
-     * This action only affects the playback position of the media item; not its playback state.
-     * If the playback queue is paused, then seeking sets the position but the item
-     * remains paused.  Likewise if the item is playing, then seeking will cause playback
-     * to jump to the new position and continue playing from that point.  If the item has
-     * not yet started playing, then the new playback position is remembered by the
-     * queue and used as the item's initial content position when playback eventually begins.
-     * </p><p>
-     * If successful, the media item's playback position is changed.
-     * </p>
-     *
-     * <h3>Request parameters</h3>
-     * <ul>
-     * <li>{@link #EXTRA_SESSION_ID} <em>(required)</em>: Specifies the session id of the session
-     * to which the media item belongs.
-     * <li>{@link #EXTRA_ITEM_ID} <em>(required)</em>: Specifies the media item id of
-     * the media item to seek.
-     * <li>{@link #EXTRA_ITEM_CONTENT_POSITION} <em>(required)</em>: Specifies the new
-     * content position for playback as a long integer number of milliseconds from
-     * the beginning of the content.
-     * </ul>
-     *
-     * <h3>Result data</h3>
-     * <ul>
-     * <li>{@link #EXTRA_SESSION_STATUS} <em>(optional, old implementations may
-     * omit this key)</em>: Specifies the status of the media session.
-     * <li>{@link #EXTRA_ITEM_STATUS} <em>(always returned)</em>: Specifies the new status of
-     * the media item.
-     * </ul>
-     *
-     * <h3>Errors</h3>
-     * <p>
-     * This action returns an error if the session id or media item id are unknown
-     * or no longer valid, if the content position is invalid, or if the media item
-     * is in a terminal state.
-     * </p><ul>
-     * <li>{@link #EXTRA_ERROR_CODE} <em>(optional)</em>: Specifies the cause of the error.
-     * </ul>
-     *
-     * @see MediaRouter.RouteInfo#sendControlRequest
-     * @see #CATEGORY_REMOTE_PLAYBACK
-     */
-    public static final String ACTION_SEEK = "android.media.intent.action.SEEK";
-
-    /**
-     * Remote playback media control action: Get media item playback status
-     * and progress information.
-     * <p>
-     * Used with routes that support {@link #CATEGORY_REMOTE_PLAYBACK remote playback}
-     * media control.
-     * </p><p>
-     * This action asks a remote playback route to provide updated playback status and progress
-     * information about the specified media item.
-     * </p>
-     *
-     * <h3>Request parameters</h3>
-     * <ul>
-     * <li>{@link #EXTRA_SESSION_ID} <em>(required)</em>: Specifies the session id of the session
-     * to which the media item belongs.
-     * <li>{@link #EXTRA_ITEM_ID} <em>(required)</em>: Specifies the media item id of
-     * the media item to query.
-     * </ul>
-     *
-     * <h3>Result data</h3>
-     * <ul>
-     * <li>{@link #EXTRA_SESSION_STATUS} <em>(optional, old implementations may
-     * omit this key)</em>: Specifies the status of the media session.
-     * <li>{@link #EXTRA_ITEM_STATUS} <em>(always returned)</em>: Specifies the current status of
-     * the media item.
-     * </ul>
-     *
-     * <h3>Errors</h3>
-     * <p>
-     * This action returns an error if the session id or media item id are unknown
-     * or no longer valid.
-     * </p><ul>
-     * <li>{@link #EXTRA_ERROR_CODE} <em>(optional)</em>: Specifies the cause of the error.
-     * </ul>
-     *
-     * @see MediaRouter.RouteInfo#sendControlRequest
-     * @see #CATEGORY_REMOTE_PLAYBACK
-     * @see #EXTRA_ITEM_STATUS_UPDATE_RECEIVER
-     */
-    public static final String ACTION_GET_STATUS = "android.media.intent.action.GET_STATUS";
-
-    /**
-     * Remote playback media control action: Remove media item from session's queue.
-     * <p>
-     * Used with routes that support {@link #CATEGORY_REMOTE_PLAYBACK remote playback}
-     * media control.
-     * </p><p>
-     * This action asks a remote playback route to remove the specified media item
-     * from the session's playback queue.  If the current item is removed, then
-     * playback will proceed to the next media item (assuming the queue has not been
-     * paused).
-     * </p><p>
-     * This action does not affect the pause state of the queue.  If the queue was paused
-     * then it remains paused (even if it is now empty) until a resume, stop or play
-     * action is issued that causes the pause state to be cleared.
-     * </p>
-     *
-     * <h3>Request parameters</h3>
-     * <ul>
-     * <li>{@link #EXTRA_SESSION_ID} <em>(required)</em>: Specifies the session id of the session
-     * to which the media item belongs.
-     * <li>{@link #EXTRA_ITEM_ID} <em>(required)</em>: Specifies the media item id of
-     * the media item to remove.
-     * </ul>
-     *
-     * <h3>Result data</h3>
-     * <ul>
-     * <li>{@link #EXTRA_SESSION_STATUS} <em>(optional, old implementations may
-     * omit this key)</em>: Specifies the status of the media session.
-     * <li>{@link #EXTRA_ITEM_STATUS} <em>(always returned)</em>: Specifies the new status of
-     * the media item.
-     * </ul>
-     *
-     * <h3>Errors</h3>
-     * <p>
-     * This action returns an error if the session id or media item id are unknown
-     * or no longer valid, or if the media item is in a terminal state (and therefore
-     * no longer in the queue).
-     * </p><ul>
-     * <li>{@link #EXTRA_ERROR_CODE} <em>(optional)</em>: Specifies the cause of the error.
-     * </ul>
-     *
-     * @see MediaRouter.RouteInfo#sendControlRequest
-     * @see #CATEGORY_REMOTE_PLAYBACK
-     */
-    public static final String ACTION_REMOVE = "android.media.intent.action.REMOVE";
-
-    /* Remote playback actions that affect the whole playback queue. */
-
-    /**
-     * Remote playback media control action: Pause media playback.
-     * <p>
-     * Used with routes that support {@link #CATEGORY_REMOTE_PLAYBACK remote playback}
-     * media control.
-     * </p><p>
-     * This action causes the playback queue of the specified session to be paused.
-     * </p>
-     *
-     * <h3>Request parameters</h3>
-     * <ul>
-     * <li>{@link #EXTRA_SESSION_ID} <em>(required)</em>: Specifies the session id of the session
-     * whose playback queue is to be paused.
-     * </ul>
-     *
-     * <h3>Result data</h3>
-     * <ul>
-     * <li>{@link #EXTRA_SESSION_STATUS} <em>(optional, old implementations may
-     * omit this key)</em>: Specifies the status of the media session.
-     * </ul>
-     *
-     * <h3>Errors</h3>
-     * <p>
-     * This action returns an error if the session id is unknown or no longer valid.
-     * </p><ul>
-     * <li>{@link #EXTRA_ERROR_CODE} <em>(optional)</em>: Specifies the cause of the error.
-     * </ul>
-     *
-     * @see MediaRouter.RouteInfo#sendControlRequest
-     * @see #CATEGORY_REMOTE_PLAYBACK
-     * @see #ACTION_RESUME
-     */
-    public static final String ACTION_PAUSE = "android.media.intent.action.PAUSE";
-
-    /**
-     * Remote playback media control action: Resume media playback (unpause).
-     * <p>
-     * Used with routes that support {@link #CATEGORY_REMOTE_PLAYBACK remote playback}
-     * media control.
-     * </p><p>
-     * This action causes the playback queue of the specified session to be resumed.
-     * Reverses the effects of {@link #ACTION_PAUSE}.
-     * </p>
-     *
-     * <h3>Request parameters</h3>
-     * <ul>
-     * <li>{@link #EXTRA_SESSION_ID} <em>(required)</em>: Specifies the session id of the session
-     * whose playback queue is to be resumed.
-     * </ul>
-     *
-     * <h3>Result data</h3>
-     * <ul>
-     * <li>{@link #EXTRA_SESSION_STATUS} <em>(optional, old implementations may
-     * omit this key)</em>: Specifies the status of the media session.
-     * </ul>
-     *
-     * <h3>Errors</h3>
-     * <p>
-     * This action returns an error if the session id is unknown or no longer valid.
-     * </p><ul>
-     * <li>{@link #EXTRA_ERROR_CODE} <em>(optional)</em>: Specifies the cause of the error.
-     * </ul>
-     *
-     * @see MediaRouter.RouteInfo#sendControlRequest
-     * @see #CATEGORY_REMOTE_PLAYBACK
-     * @see #ACTION_PAUSE
-     */
-    public static final String ACTION_RESUME = "android.media.intent.action.RESUME";
-
-    /**
-     * Remote playback media control action: Stop media playback (clear queue and unpause).
-     * <p>
-     * Used with routes that support {@link #CATEGORY_REMOTE_PLAYBACK remote playback}
-     * media control.
-     * </p><p>
-     * This action causes a remote playback route to stop playback, cancel and remove
-     * all media items from the session's media item queue and, reset the queue's
-     * pause state.
-     * </p><p>
-     * If successful, the status of all media items in the queue is set to
-     * {@link MediaItemStatus#PLAYBACK_STATE_CANCELED canceled} and a status update is sent
-     * to the appropriate status update receivers indicating the new status of each item.
-     * </p>
-     *
-     * <h3>Request parameters</h3>
-     * <ul>
-     * <li>{@link #EXTRA_SESSION_ID} <em>(required)</em>: Specifies the session id of
-     * the session whose playback queue is to be stopped (cleared and unpaused).
-     * </ul>
-     *
-     * <h3>Result data</h3>
-     * <ul>
-     * <li>{@link #EXTRA_SESSION_STATUS} <em>(optional, old implementations may
-     * omit this key)</em>: Specifies the status of the media session.
-     * </ul>
-     *
-     * <h3>Errors</h3>
-     * <p>
-     * This action returns an error if the session id is unknown or no longer valid.
-     * </p><ul>
-     * <li>{@link #EXTRA_ERROR_CODE} <em>(optional)</em>: Specifies the cause of the error.
-     * </ul>
-     *
-     * @see MediaRouter.RouteInfo#sendControlRequest
-     * @see #CATEGORY_REMOTE_PLAYBACK
-     */
-    public static final String ACTION_STOP = "android.media.intent.action.STOP";
-
-    /**
-     * Remote playback media control action: Start session.
-     * <p>
-     * Used with routes that support {@link #CATEGORY_REMOTE_PLAYBACK remote playback}
-     * media control.
-     * </p><p>
-     * This action causes a remote playback route to invalidate the current session
-     * and start a new session.  The new session initially has an empty queue.
-     * </p><p>
-     * If successful, the status of all media items in the previous session's queue is set to
-     * {@link MediaItemStatus#PLAYBACK_STATE_INVALIDATED invalidated} and a status update
-     * is sent to the appropriate status update receivers indicating the new status
-     * of each item.  The previous session becomes no longer valid and the new session
-     * takes control of the route.
-     * </p>
-     *
-     * <h3>Request parameters</h3>
-     * <ul>
-     * <li>{@link #EXTRA_SESSION_STATUS_UPDATE_RECEIVER} <em>(optional)</em>: Specifies a
-     * {@link PendingIntent} for a broadcast receiver that will receive status updates
-     * about the media session.
-     * <li>{@link #EXTRA_MESSAGE_RECEIVER} <em>(optional)</em>: Specifies a
-     * {@link PendingIntent} for a broadcast receiver that will receive messages from
-     * the media session.
-     * </ul>
-     *
-     * <h3>Result data</h3>
-     * <ul>
-     * <li>{@link #EXTRA_SESSION_ID} <em>(always returned)</em>: Specifies the session id of the
-     * session that was started by the request.  This will always be a brand new session
-     * distinct from any other previously created sessions.
-     * <li>{@link #EXTRA_SESSION_STATUS} <em>(always returned)</em>: Specifies the
-     * status of the media session.
-     * </ul>
-     *
-     * <h3>Status updates</h3>
-     * <p>
-     * If the client supplies a
-     * {@link #EXTRA_SESSION_STATUS_UPDATE_RECEIVER status update receiver}
-     * then the media route provider is responsible for sending status updates to the receiver
-     * when significant media session state changes occur such as when the session's
-     * queue is paused or resumed or when the session is terminated or invalidated.
-     * </p><p>
-     * Refer to {@link MediaSessionStatus} for details.
-     * </p>
-     *
-     * <h3>Custom messages</h3>
-     * <p>
-     * If the client supplies a {@link #EXTRA_MESSAGE_RECEIVER message receiver}
-     * then the media route provider is responsible for sending messages to the receiver
-     * when the session has any messages to send.
-     * </p><p>
-     * Refer to {@link #EXTRA_MESSAGE} for details.
-     * </p>
-     *
-     * <h3>Errors</h3>
-     * <p>
-     * This action returns an error if the session could not be created.
-     * </p><ul>
-     * <li>{@link #EXTRA_ERROR_CODE} <em>(optional)</em>: Specifies the cause of the error.
-     * </ul>
-     *
-     * @see MediaRouter.RouteInfo#sendControlRequest
-     * @see #CATEGORY_REMOTE_PLAYBACK
-     */
-    public static final String ACTION_START_SESSION = "android.media.intent.action.START_SESSION";
-
-    /**
-     * Remote playback media control action: Get media session status information.
-     * <p>
-     * Used with routes that support {@link #CATEGORY_REMOTE_PLAYBACK remote playback}
-     * media control.
-     * </p><p>
-     * This action asks a remote playback route to provide updated status information
-     * about the specified media session.
-     * </p>
-     *
-     * <h3>Request parameters</h3>
-     * <ul>
-     * <li>{@link #EXTRA_SESSION_ID} <em>(required)</em>: Specifies the session id of the
-     * session whose status is to be retrieved.
-     * </ul>
-     *
-     * <h3>Result data</h3>
-     * <ul>
-     * <li>{@link #EXTRA_SESSION_STATUS} <em>(always returned)</em>: Specifies the
-     * current status of the media session.
-     * </ul>
-     *
-     * <h3>Errors</h3>
-     * <p>
-     * This action returns an error if the session id is unknown or no longer valid.
-     * </p><ul>
-     * <li>{@link #EXTRA_ERROR_CODE} <em>(optional)</em>: Specifies the cause of the error.
-     * </ul>
-     *
-     * @see MediaRouter.RouteInfo#sendControlRequest
-     * @see #CATEGORY_REMOTE_PLAYBACK
-     * @see #EXTRA_SESSION_STATUS_UPDATE_RECEIVER
-     */
-    public static final String ACTION_GET_SESSION_STATUS =
-            "android.media.intent.action.GET_SESSION_STATUS";
-
-    /**
-     * Remote playback media control action: End session.
-     * <p>
-     * Used with routes that support {@link #CATEGORY_REMOTE_PLAYBACK remote playback}
-     * media control.
-     * </p><p>
-     * This action causes a remote playback route to end the specified session.
-     * The session becomes no longer valid and the route ceases to be under control
-     * of the session.
-     * </p><p>
-     * If successful, the status of the session is set to
-     * {@link MediaSessionStatus#SESSION_STATE_ENDED} and a status update is sent to
-     * the session's status update receiver.
-     * </p><p>
-     * Additionally, the status of all media items in the queue is set to
-     * {@link MediaItemStatus#PLAYBACK_STATE_CANCELED canceled} and a status update is sent
-     * to the appropriate status update receivers indicating the new status of each item.
-     * </p>
-     *
-     * <h3>Request parameters</h3>
-     * <ul>
-     * <li>{@link #EXTRA_SESSION_ID} <em>(required)</em>: Specifies the session id of
-     * the session to end.
-     * </ul>
-     *
-     * <h3>Result data</h3>
-     * <ul>
-     * <li>{@link #EXTRA_SESSION_STATUS} <em>(always returned)</em>: Specifies the
-     * status of the media session.
-     * </ul>
-     *
-     * <h3>Errors</h3>
-     * <p>
-     * This action returns an error if the session id is unknown or no longer valid.
-     * In other words, it is an error to attempt to end a session other than the
-     * current session.
-     * </p><ul>
-     * <li>{@link #EXTRA_ERROR_CODE} <em>(optional)</em>: Specifies the cause of the error.
-     * </ul>
-     *
-     * @see MediaRouter.RouteInfo#sendControlRequest
-     * @see #CATEGORY_REMOTE_PLAYBACK
-     */
-    public static final String ACTION_END_SESSION = "android.media.intent.action.END_SESSION";
-
-    /**
-     * Custom media control action: Send {@link #EXTRA_MESSAGE}.
-     * <p>
-     * This action asks a route to handle a message described by EXTRA_MESSAGE.
-     * </p>
-     *
-     * <h3>Request parameters</h3>
-     * <ul>
-     * <li>{@link #EXTRA_SESSION_ID} <em>(required)</em>: Specifies the session id of the session
-     * to which will handle this message.
-     * <li>{@link #EXTRA_MESSAGE} <em>(required)</em>: Specifies the message to send.
-     * </ul>
-     *
-     * <h3>Result data</h3>
-     * Any messages defined by each media route provider.
-     *
-     * <h3>Errors</h3>
-     * Any error messages defined by each media route provider.
-     *
-     * @see MediaRouter.RouteInfo#sendControlRequest
-     */
-    public static final String ACTION_SEND_MESSAGE = "android.media.intent.action.SEND_MESSAGE";
-
-    /* Extras and related constants. */
-
-    /**
-     * Bundle extra: Media session id.
-     * <p>
-     * An opaque unique identifier that identifies the remote playback media session.
-     * </p><p>
-     * Used with various actions to specify the id of the media session to be controlled.
-     * </p><p>
-     * Included in broadcast intents sent to
-     * {@link #EXTRA_ITEM_STATUS_UPDATE_RECEIVER item status update receivers} to identify
-     * the session to which the item in question belongs.
-     * </p><p>
-     * Included in broadcast intents sent to
-     * {@link #EXTRA_SESSION_STATUS_UPDATE_RECEIVER session status update receivers} to identify
-     * the session.
-     * </p><p>
-     * The value is a unique string value generated by the media route provider
-     * to represent one particular media session.
-     * </p>
-     *
-     * @see #ACTION_PLAY
-     * @see #ACTION_SEEK
-     * @see #ACTION_GET_STATUS
-     * @see #ACTION_PAUSE
-     * @see #ACTION_RESUME
-     * @see #ACTION_STOP
-     * @see #ACTION_START_SESSION
-     * @see #ACTION_GET_SESSION_STATUS
-     * @see #ACTION_END_SESSION
-     */
-    public static final String EXTRA_SESSION_ID =
-            "android.media.intent.extra.SESSION_ID";
-
-    /**
-     * Bundle extra: Media session status.
-     * <p>
-     * Returned as a result from media session actions such as {@link #ACTION_START_SESSION},
-     * {@link #ACTION_PAUSE}, and {@link #ACTION_GET_SESSION_STATUS}
-     * to describe the status of the specified media session.
-     * </p><p>
-     * Included in broadcast intents sent to
-     * {@link #EXTRA_SESSION_STATUS_UPDATE_RECEIVER session status update receivers} to provide
-     * updated status information.
-     * </p><p>
-     * The value is a {@link android.os.Bundle} of data that can be converted into
-     * a {@link MediaSessionStatus} object using
-     * {@link MediaSessionStatus#fromBundle MediaSessionStatus.fromBundle}.
-     * </p>
-     *
-     * @see #ACTION_PLAY
-     * @see #ACTION_SEEK
-     * @see #ACTION_GET_STATUS
-     * @see #ACTION_PAUSE
-     * @see #ACTION_RESUME
-     * @see #ACTION_STOP
-     * @see #ACTION_START_SESSION
-     * @see #ACTION_GET_SESSION_STATUS
-     * @see #ACTION_END_SESSION
-     */
-    public static final String EXTRA_SESSION_STATUS =
-            "android.media.intent.extra.SESSION_STATUS";
-
-    /**
-     * Bundle extra: Media session status update receiver.
-     * <p>
-     * Used with {@link #ACTION_START_SESSION} to specify a {@link PendingIntent} for a
-     * broadcast receiver that will receive status updates about the media session.
-     * </p><p>
-     * Whenever the status of the media session changes, the media route provider will
-     * send a broadcast to the pending intent with extras that identify the session
-     * id and its updated status.
-     * </p><p>
-     * The value is a {@link PendingIntent}.
-     * </p>
-     *
-     * <h3>Broadcast extras</h3>
-     * <ul>
-     * <li>{@link #EXTRA_SESSION_ID} <em>(required)</em>: Specifies the session id of
-     * the session.
-     * <li>{@link #EXTRA_SESSION_STATUS} <em>(required)</em>: Specifies the status of the
-     * session as a bundle that can be decoded into a {@link MediaSessionStatus} object.
-     * </ul>
-     *
-     * @see #ACTION_START_SESSION
-     */
-    public static final String EXTRA_SESSION_STATUS_UPDATE_RECEIVER =
-            "android.media.intent.extra.SESSION_STATUS_UPDATE_RECEIVER";
-
-    /**
-     * Bundle extra: Media message receiver.
-     * <p>
-     * Used with {@link #ACTION_START_SESSION} to specify a {@link PendingIntent} for a
-     * broadcast receiver that will receive messages from the media session.
-     * </p><p>
-     * When the media session has a message to send, the media route provider will
-     * send a broadcast to the pending intent with extras that identify the session
-     * id and its message.
-     * </p><p>
-     * The value is a {@link PendingIntent}.
-     * </p>
-     *
-     * <h3>Broadcast extras</h3>
-     * <ul>
-     * <li>{@link #EXTRA_SESSION_ID} <em>(required)</em>: Specifies the session id of
-     * the session.
-     * <li>{@link #EXTRA_MESSAGE} <em>(required)</em>: Specifies the message from
-     * the session as a bundle object.
-     * </ul>
-     *
-     * @see #ACTION_START_SESSION
-     */
-    public static final String EXTRA_MESSAGE_RECEIVER =
-            "android.media.intent.extra.MESSAGE_RECEIVER";
-
-    /**
-     * Bundle extra: Media item id.
-     * <p>
-     * An opaque unique identifier returned as a result from {@link #ACTION_PLAY} or
-     * {@link #ACTION_ENQUEUE} that represents the media item that was created by the
-     * playback request.
-     * </p><p>
-     * Used with various actions to specify the id of the media item to be controlled.
-     * </p><p>
-     * Included in broadcast intents sent to
-     * {@link #EXTRA_ITEM_STATUS_UPDATE_RECEIVER status update receivers} to identify
-     * the item in question.
-     * </p><p>
-     * The value is a unique string value generated by the media route provider
-     * to represent one particular media item.
-     * </p>
-     *
-     * @see #ACTION_PLAY
-     * @see #ACTION_ENQUEUE
-     * @see #ACTION_SEEK
-     * @see #ACTION_GET_STATUS
-     */
-    public static final String EXTRA_ITEM_ID =
-            "android.media.intent.extra.ITEM_ID";
-
-    /**
-     * Bundle extra: Media item status.
-     * <p>
-     * Returned as a result from media item actions such as {@link #ACTION_PLAY},
-     * {@link #ACTION_ENQUEUE}, {@link #ACTION_SEEK}, and {@link #ACTION_GET_STATUS}
-     * to describe the status of the specified media item.
-     * </p><p>
-     * Included in broadcast intents sent to
-     * {@link #EXTRA_ITEM_STATUS_UPDATE_RECEIVER item status update receivers} to provide
-     * updated status information.
-     * </p><p>
-     * The value is a {@link android.os.Bundle} of data that can be converted into
-     * a {@link MediaItemStatus} object using
-     * {@link MediaItemStatus#fromBundle MediaItemStatus.fromBundle}.
-     * </p>
-     *
-     * @see #ACTION_PLAY
-     * @see #ACTION_ENQUEUE
-     * @see #ACTION_SEEK
-     * @see #ACTION_GET_STATUS
-     */
-    public static final String EXTRA_ITEM_STATUS =
-            "android.media.intent.extra.ITEM_STATUS";
-
-    /**
-     * Long extra: Media item content position.
-     * <p>
-     * Used with {@link #ACTION_PLAY} or {@link #ACTION_ENQUEUE} to specify the
-     * starting playback position.
-     * </p><p>
-     * Used with {@link #ACTION_SEEK} to set a new playback position.
-     * </p><p>
-     * The value is a long integer number of milliseconds from the beginning of the content.
-     * <p>
-     *
-     * @see #ACTION_PLAY
-     * @see #ACTION_ENQUEUE
-     * @see #ACTION_SEEK
-     */
-    public static final String EXTRA_ITEM_CONTENT_POSITION =
-            "android.media.intent.extra.ITEM_POSITION";
-
-    /**
-     * Bundle extra: Media item metadata.
-     * <p>
-     * Used with {@link #ACTION_PLAY} or {@link #ACTION_ENQUEUE} to specify metadata
-     * associated with the content of a media item.
-     * </p><p>
-     * The value is a {@link android.os.Bundle} of metadata key-value pairs as defined
-     * in {@link MediaItemMetadata}.
-     * </p>
-     *
-     * @see #ACTION_PLAY
-     * @see #ACTION_ENQUEUE
-     */
-    public static final String EXTRA_ITEM_METADATA =
-            "android.media.intent.extra.ITEM_METADATA";
-
-    /**
-     * Bundle extra: HTTP request headers.
-     * <p>
-     * Used with {@link #ACTION_PLAY} or {@link #ACTION_ENQUEUE} to specify HTTP request
-     * headers to be included when fetching to the content indicated by the media
-     * item's data Uri.
-     * </p><p>
-     * This extra may be used to provide authentication tokens and other
-     * parameters to the server separately from the media item's data Uri.
-     * </p><p>
-     * The value is a {@link android.os.Bundle} of string based key-value pairs
-     * that describe the HTTP request headers.
-     * </p>
-     *
-     * @see #ACTION_PLAY
-     * @see #ACTION_ENQUEUE
-     */
-    public static final String EXTRA_ITEM_HTTP_HEADERS =
-            "android.media.intent.extra.HTTP_HEADERS";
-
-    /**
-     * Bundle extra: Media item status update receiver.
-     * <p>
-     * Used with {@link #ACTION_PLAY} or {@link #ACTION_ENQUEUE} to specify
-     * a {@link PendingIntent} for a
-     * broadcast receiver that will receive status updates about a particular
-     * media item.
-     * </p><p>
-     * Whenever the status of the media item changes, the media route provider will
-     * send a broadcast to the pending intent with extras that identify the session
-     * to which the item belongs, the session status, the item's id
-     * and the item's updated status.
-     * </p><p>
-     * The same pending intent and broadcast receiver may be shared by any number of
-     * media items since the broadcast intent includes the media session id
-     * and media item id.
-     * </p><p>
-     * The value is a {@link PendingIntent}.
-     * </p>
-     *
-     * <h3>Broadcast extras</h3>
-     * <ul>
-     * <li>{@link #EXTRA_SESSION_ID} <em>(required)</em>: Specifies the session id of
-     * the session to which the item in question belongs.
-     * <li>{@link #EXTRA_SESSION_STATUS} <em>(optional, old implementations may
-     * omit this key)</em>: Specifies the status of the media session.
-     * <li>{@link #EXTRA_ITEM_ID} <em>(required)</em>: Specifies the media item id of the
-     * media item in question.
-     * <li>{@link #EXTRA_ITEM_STATUS} <em>(required)</em>: Specifies the status of the
-     * item as a bundle that can be decoded into a {@link MediaItemStatus} object.
-     * </ul>
-     *
-     * @see #ACTION_PLAY
-     * @see #ACTION_ENQUEUE
-     */
-    public static final String EXTRA_ITEM_STATUS_UPDATE_RECEIVER =
-            "android.media.intent.extra.ITEM_STATUS_UPDATE_RECEIVER";
-
-    /**
-     * Bundle extra: Message.
-     * <p>
-     * Used with {@link #ACTION_SEND_MESSAGE}, and included in broadcast intents sent to
-     * {@link #EXTRA_MESSAGE_RECEIVER message receivers} to describe a message between a
-     * session and a media route provider.
-     * </p><p>
-     * The value is a {@link android.os.Bundle}.
-     * </p>
-     */
-    public static final String EXTRA_MESSAGE = "android.media.intent.extra.MESSAGE";
-
-    /**
-     * Integer extra: Error code.
-     * <p>
-     * Used with all media control requests to describe the cause of an error.
-     * This extra may be omitted when the error is unknown.
-     * </p><p>
-     * The value is one of: {@link #ERROR_UNKNOWN}, {@link #ERROR_UNSUPPORTED_OPERATION},
-     * {@link #ERROR_INVALID_SESSION_ID}, {@link #ERROR_INVALID_ITEM_ID}.
-     * </p>
-     */
-    public static final String EXTRA_ERROR_CODE = "android.media.intent.extra.ERROR_CODE";
-
-    /**
-     * Error code: An unknown error occurred.
-     *
-     * @see #EXTRA_ERROR_CODE
-     */
-    public static final int ERROR_UNKNOWN = 0;
-
-    /**
-     * Error code: The operation is not supported.
-     *
-     * @see #EXTRA_ERROR_CODE
-     */
-    public static final int ERROR_UNSUPPORTED_OPERATION = 1;
-
-    /**
-     * Error code: The session id specified in the request was invalid.
-     *
-     * @see #EXTRA_ERROR_CODE
-     */
-    public static final int ERROR_INVALID_SESSION_ID = 2;
-
-    /**
-     * Error code: The item id specified in the request was invalid.
-     *
-     * @see #EXTRA_ERROR_CODE
-     */
-    public static final int ERROR_INVALID_ITEM_ID = 3;
-
-    private MediaControlIntent() {
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaItemMetadata.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaItemMetadata.java
deleted file mode 100644
index d52ddb6..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaItemMetadata.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.media;
-
-import android.os.Bundle;
-
-/**
- * Constants for specifying metadata about a media item as a {@link Bundle}.
- * <p>
- * This class is part of the remote playback protocol described by the
- * {@link MediaControlIntent MediaControlIntent} class.
- * </p><p>
- * Media item metadata is described as a bundle of key/value pairs as defined
- * in this class.  The documentation specifies the type of value associated
- * with each key.
- * </p><p>
- * An application may specify additional custom metadata keys but there is no guarantee
- * that they will be recognized by the destination.
- * </p>
- */
-public final class MediaItemMetadata {
-    /*
-     * Note: MediaMetadataRetriever also defines a collection of metadata keys that can be
-     * retrieved from a content stream although the representation is somewhat different here
-     * since we are sending the data to a remote endpoint.
-     */
-
-    private MediaItemMetadata() {
-    }
-
-    /**
-     * String key: Album artist name.
-     * <p>
-     * The value is a string suitable for display.
-     * </p>
-     */
-    public static final String KEY_ALBUM_ARTIST = "android.media.metadata.ALBUM_ARTIST";
-
-    /**
-     * String key: Album title.
-     * <p>
-     * The value is a string suitable for display.
-     * </p>
-     */
-    public static final String KEY_ALBUM_TITLE = "android.media.metadata.ALBUM_TITLE";
-
-    /**
-     * String key: Artwork Uri.
-     * <p>
-     * The value is a string URI for an image file associated with the media item,
-     * such as album or cover art.
-     * </p>
-     */
-    public static final String KEY_ARTWORK_URI = "android.media.metadata.ARTWORK_URI";
-
-    /**
-     * String key: Artist name.
-     * <p>
-     * The value is a string suitable for display.
-     * </p>
-     */
-    public static final String KEY_ARTIST = "android.media.metadata.ARTIST";
-
-    /**
-     * String key: Author name.
-     * <p>
-     * The value is a string suitable for display.
-     * </p>
-     */
-    public static final String KEY_AUTHOR = "android.media.metadata.AUTHOR";
-
-    /**
-     * String key: Composer name.
-     * <p>
-     * The value is a string suitable for display.
-     * </p>
-     */
-    public static final String KEY_COMPOSER = "android.media.metadata.COMPOSER";
-
-    /**
-     * String key: Track title.
-     * <p>
-     * The value is a string suitable for display.
-     * </p>
-     */
-    public static final String KEY_TITLE = "android.media.metadata.TITLE";
-
-    /**
-     * Integer key: Year of publication.
-     * <p>
-     * The value is an integer year number.
-     * </p>
-     */
-    public static final String KEY_YEAR = "android.media.metadata.YEAR";
-
-    /**
-     * Integer key: Track number (such as a track on a CD).
-     * <p>
-     * The value is a one-based integer track number.
-     * </p>
-     */
-    public static final String KEY_TRACK_NUMBER = "android.media.metadata.TRACK_NUMBER";
-
-    /**
-     * Integer key: Disc number within a collection.
-     * <p>
-     * The value is a one-based integer disc number.
-     * </p>
-     */
-    public static final String KEY_DISC_NUMBER = "android.media.metadata.DISC_NUMBER";
-
-    /**
-     * Long key: Item playback duration in milliseconds.
-     * <p>
-     * The value is a <code>long</code> number of milliseconds.
-     * </p><p>
-     * The duration metadata is only a hint to enable a remote media player to
-     * guess the duration of the content before it actually opens the media stream.
-     * The remote media player should still determine the actual content duration from
-     * the media stream itself independent of the value that may be specified by this key.
-     * </p>
-     */
-    public static final String KEY_DURATION = "android.media.metadata.DURATION";
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaItemStatus.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaItemStatus.java
deleted file mode 100644
index 90ea2d5..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaItemStatus.java
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.media;
-
-import android.app.PendingIntent;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.support.v4.util.TimeUtils;
-
-/**
- * Describes the playback status of a media item.
- * <p>
- * This class is part of the remote playback protocol described by the
- * {@link MediaControlIntent MediaControlIntent} class.
- * </p><p>
- * As a media item is played, it transitions through a sequence of states including:
- * {@link #PLAYBACK_STATE_PENDING pending}, {@link #PLAYBACK_STATE_BUFFERING buffering},
- * {@link #PLAYBACK_STATE_PLAYING playing}, {@link #PLAYBACK_STATE_PAUSED paused},
- * {@link #PLAYBACK_STATE_FINISHED finished}, {@link #PLAYBACK_STATE_CANCELED canceled},
- * {@link #PLAYBACK_STATE_INVALIDATED invalidated}, and
- * {@link #PLAYBACK_STATE_ERROR error}.  Refer to the documentation of each state
- * for an explanation of its meaning.
- * </p><p>
- * While the item is playing, the playback status may also include progress information
- * about the {@link #getContentPosition content position} and
- * {@link #getContentDuration content duration} although not all route destinations
- * will report it.
- * </p><p>
- * To monitor playback status, the application should supply a {@link PendingIntent} to use as the
- * {@link MediaControlIntent#EXTRA_ITEM_STATUS_UPDATE_RECEIVER item status update receiver}
- * for a given {@link MediaControlIntent#ACTION_PLAY playback request}.  Note that
- * the status update receiver will only be invoked for major status changes such as a
- * transition from playing to finished.
- * </p><p class="note">
- * The status update receiver will not be invoked for minor progress updates such as
- * changes to playback position or duration.  If the application wants to monitor
- * playback progress, then it must use the
- * {@link MediaControlIntent#ACTION_GET_STATUS get status request} to poll for changes
- * periodically and estimate the playback position while playing.  Note that there may
- * be a significant power impact to polling so the application is advised only
- * to poll when the screen is on and never more than about once every 5 seconds or so.
- * </p><p>
- * This object is immutable once created using a {@link Builder} instance.
- * </p>
- */
-public final class MediaItemStatus {
-    static final String KEY_TIMESTAMP = "timestamp";
-    static final String KEY_PLAYBACK_STATE = "playbackState";
-    static final String KEY_CONTENT_POSITION = "contentPosition";
-    static final String KEY_CONTENT_DURATION = "contentDuration";
-    static final String KEY_EXTRAS = "extras";
-
-    final Bundle mBundle;
-
-    /**
-     * Playback state: Pending.
-     * <p>
-     * Indicates that the media item has not yet started playback but will be played eventually.
-     * </p>
-     */
-    public static final int PLAYBACK_STATE_PENDING = 0;
-
-    /**
-     * Playback state: Playing.
-     * <p>
-     * Indicates that the media item is currently playing.
-     * </p>
-     */
-    public static final int PLAYBACK_STATE_PLAYING = 1;
-
-    /**
-     * Playback state: Paused.
-     * <p>
-     * Indicates that playback of the media item has been paused.  Playback can be
-     * resumed using the {@link MediaControlIntent#ACTION_RESUME resume} action.
-     * </p>
-     */
-    public static final int PLAYBACK_STATE_PAUSED = 2;
-
-    /**
-     * Playback state: Buffering or seeking to a new position.
-     * <p>
-     * Indicates that the media item has been temporarily interrupted
-     * to fetch more content.  Playback will continue automatically
-     * when enough content has been buffered.
-     * </p>
-     */
-    public static final int PLAYBACK_STATE_BUFFERING = 3;
-
-    /**
-     * Playback state: Finished.
-     * <p>
-     * Indicates that the media item played to the end of the content and finished normally.
-     * </p><p>
-     * A finished media item cannot be resumed.  To play the content again, the application
-     * must send a new {@link MediaControlIntent#ACTION_PLAY play} or
-     * {@link MediaControlIntent#ACTION_ENQUEUE enqueue} action.
-     * </p>
-     */
-    public static final int PLAYBACK_STATE_FINISHED = 4;
-
-    /**
-     * Playback state: Canceled.
-     * <p>
-     * Indicates that the media item was explicitly removed from the queue by the
-     * application.  Items may be canceled and removed from the queue using
-     * the {@link MediaControlIntent#ACTION_REMOVE remove} or
-     * {@link MediaControlIntent#ACTION_STOP stop} action or by issuing
-     * another {@link MediaControlIntent#ACTION_PLAY play} action that has the
-     * side-effect of clearing the queue.
-     * </p><p>
-     * A canceled media item cannot be resumed.  To play the content again, the
-     * application must send a new {@link MediaControlIntent#ACTION_PLAY play} or
-     * {@link MediaControlIntent#ACTION_ENQUEUE enqueue} action.
-     * </p>
-     */
-    public static final int PLAYBACK_STATE_CANCELED = 5;
-
-    /**
-     * Playback state: Invalidated.
-     * <p>
-     * Indicates that the media item was invalidated permanently and involuntarily.
-     * This state is used to indicate that the media item was invalidated and removed
-     * from the queue because the session to which it belongs was invalidated
-     * (typically by another application taking control of the route).
-     * </p><p>
-     * When invalidation occurs, the application should generally wait for the user
-     * to perform an explicit action, such as clicking on a play button in the UI,
-     * before creating a new media session to avoid unnecessarily interrupting
-     * another application that may have just started using the route.
-     * </p><p>
-     * An invalidated media item cannot be resumed.  To play the content again, the application
-     * must send a new {@link MediaControlIntent#ACTION_PLAY play} or
-     * {@link MediaControlIntent#ACTION_ENQUEUE enqueue} action.
-     * </p>
-     */
-    public static final int PLAYBACK_STATE_INVALIDATED = 6;
-
-    /**
-     * Playback state: Playback halted or aborted due to an error.
-     * <p>
-     * Examples of errors are no network connectivity when attempting to retrieve content
-     * from a server, or expired user credentials when trying to play subscription-based
-     * content.
-     * </p><p>
-     * A media item in the error state cannot be resumed.  To play the content again,
-     * the application must send a new {@link MediaControlIntent#ACTION_PLAY play} or
-     * {@link MediaControlIntent#ACTION_ENQUEUE enqueue} action.
-     * </p>
-     */
-    public static final int PLAYBACK_STATE_ERROR = 7;
-
-    /**
-     * Integer extra: HTTP status code.
-     * <p>
-     * Specifies the HTTP status code that was encountered when the content
-     * was requested after all redirects were followed.  This key only needs to
-     * specified when the content uri uses the HTTP or HTTPS scheme and an error
-     * occurred.  This key may be omitted if the content was able to be played
-     * successfully; there is no need to report a 200 (OK) status code.
-     * </p><p>
-     * The value is an integer HTTP status code, such as 401 (Unauthorized),
-     * 404 (Not Found), or 500 (Server Error), or 0 if none.
-     * </p>
-     */
-    public static final String EXTRA_HTTP_STATUS_CODE =
-            "android.media.status.extra.HTTP_STATUS_CODE";
-
-    /**
-     * Bundle extra: HTTP response headers.
-     * <p>
-     * Specifies the HTTP response headers that were returned when the content was
-     * requested from the network.  The headers may include additional information
-     * about the content or any errors conditions that were encountered while
-     * trying to fetch the content.
-     * </p><p>
-     * The value is a {@link android.os.Bundle} of string based key-value pairs
-     * that describe the HTTP response headers.
-     * </p>
-     */
-    public static final String EXTRA_HTTP_RESPONSE_HEADERS =
-            "android.media.status.extra.HTTP_RESPONSE_HEADERS";
-
-    MediaItemStatus(Bundle bundle) {
-        mBundle = bundle;
-    }
-
-    /**
-     * Gets the timestamp associated with the status information in
-     * milliseconds since boot in the {@link SystemClock#elapsedRealtime} time base.
-     *
-     * @return The status timestamp in the {@link SystemClock#elapsedRealtime()} time base.
-     */
-    public long getTimestamp() {
-        return mBundle.getLong(KEY_TIMESTAMP);
-    }
-
-    /**
-     * Gets the playback state of the media item.
-     *
-     * @return The playback state.  One of {@link #PLAYBACK_STATE_PENDING},
-     * {@link #PLAYBACK_STATE_PLAYING}, {@link #PLAYBACK_STATE_PAUSED},
-     * {@link #PLAYBACK_STATE_BUFFERING}, {@link #PLAYBACK_STATE_FINISHED},
-     * {@link #PLAYBACK_STATE_CANCELED}, {@link #PLAYBACK_STATE_INVALIDATED},
-     * or {@link #PLAYBACK_STATE_ERROR}.
-     */
-    public int getPlaybackState() {
-        return mBundle.getInt(KEY_PLAYBACK_STATE, PLAYBACK_STATE_ERROR);
-    }
-
-    /**
-     * Gets the content playback position as a long integer number of milliseconds
-     * from the beginning of the content.
-     *
-     * @return The content playback position in milliseconds, or -1 if unknown.
-     */
-    public long getContentPosition() {
-        return mBundle.getLong(KEY_CONTENT_POSITION, -1);
-    }
-
-    /**
-     * Gets the total duration of the content to be played as a long integer number of
-     * milliseconds.
-     *
-     * @return The content duration in milliseconds, or -1 if unknown.
-     */
-    public long getContentDuration() {
-        return mBundle.getLong(KEY_CONTENT_DURATION, -1);
-    }
-
-    /**
-     * Gets a bundle of extras for this status object.
-     * The extras will be ignored by the media router but they may be used
-     * by applications.
-     */
-    public Bundle getExtras() {
-        return mBundle.getBundle(KEY_EXTRAS);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder result = new StringBuilder();
-        result.append("MediaItemStatus{ ");
-        result.append("timestamp=");
-        TimeUtils.formatDuration(SystemClock.elapsedRealtime() - getTimestamp(), result);
-        result.append(" ms ago");
-        result.append(", playbackState=").append(playbackStateToString(getPlaybackState()));
-        result.append(", contentPosition=").append(getContentPosition());
-        result.append(", contentDuration=").append(getContentDuration());
-        result.append(", extras=").append(getExtras());
-        result.append(" }");
-        return result.toString();
-    }
-
-    private static String playbackStateToString(int playbackState) {
-        switch (playbackState) {
-            case PLAYBACK_STATE_PENDING:
-                return "pending";
-            case PLAYBACK_STATE_BUFFERING:
-                return "buffering";
-            case PLAYBACK_STATE_PLAYING:
-                return "playing";
-            case PLAYBACK_STATE_PAUSED:
-                return "paused";
-            case PLAYBACK_STATE_FINISHED:
-                return "finished";
-            case PLAYBACK_STATE_CANCELED:
-                return "canceled";
-            case PLAYBACK_STATE_INVALIDATED:
-                return "invalidated";
-            case PLAYBACK_STATE_ERROR:
-                return "error";
-        }
-        return Integer.toString(playbackState);
-    }
-
-    /**
-     * Converts this object to a bundle for serialization.
-     *
-     * @return The contents of the object represented as a bundle.
-     */
-    public Bundle asBundle() {
-        return mBundle;
-    }
-
-    /**
-     * Creates an instance from a bundle.
-     *
-     * @param bundle The bundle, or null if none.
-     * @return The new instance, or null if the bundle was null.
-     */
-    public static MediaItemStatus fromBundle(Bundle bundle) {
-        return bundle != null ? new MediaItemStatus(bundle) : null;
-    }
-
-    /**
-     * Builder for {@link MediaItemStatus media item status objects}.
-     */
-    public static final class Builder {
-        private final Bundle mBundle;
-
-        /**
-         * Creates a media item status builder using the current time as the
-         * reference timestamp.
-         *
-         * @param playbackState The item playback state.
-         */
-        public Builder(int playbackState) {
-            mBundle = new Bundle();
-            setTimestamp(SystemClock.elapsedRealtime());
-            setPlaybackState(playbackState);
-        }
-
-        /**
-         * Creates a media item status builder whose initial contents are
-         * copied from an existing status.
-         */
-        public Builder(MediaItemStatus status) {
-            if (status == null) {
-                throw new IllegalArgumentException("status must not be null");
-            }
-
-            mBundle = new Bundle(status.mBundle);
-        }
-
-        /**
-         * Sets the timestamp associated with the status information in
-         * milliseconds since boot in the {@link SystemClock#elapsedRealtime} time base.
-         */
-        public Builder setTimestamp(long elapsedRealtimeTimestamp) {
-            mBundle.putLong(KEY_TIMESTAMP, elapsedRealtimeTimestamp);
-            return this;
-        }
-
-        /**
-         * Sets the playback state of the media item.
-         */
-        public Builder setPlaybackState(int playbackState) {
-            mBundle.putInt(KEY_PLAYBACK_STATE, playbackState);
-            return this;
-        }
-
-        /**
-         * Sets the content playback position as a long integer number of milliseconds
-         * from the beginning of the content.
-         */
-        public Builder setContentPosition(long positionMilliseconds) {
-            mBundle.putLong(KEY_CONTENT_POSITION, positionMilliseconds);
-            return this;
-        }
-
-        /**
-         * Sets the total duration of the content to be played as a long integer number
-         * of milliseconds.
-         */
-        public Builder setContentDuration(long durationMilliseconds) {
-            mBundle.putLong(KEY_CONTENT_DURATION, durationMilliseconds);
-            return this;
-        }
-
-        /**
-         * Sets a bundle of extras for this status object.
-         * The extras will be ignored by the media router but they may be used
-         * by applications.
-         */
-        public Builder setExtras(Bundle extras) {
-            mBundle.putBundle(KEY_EXTRAS, extras);
-            return this;
-        }
-
-        /**
-         * Builds the {@link MediaItemStatus media item status object}.
-         */
-        public MediaItemStatus build() {
-            return new MediaItemStatus(mBundle);
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteDescriptor.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteDescriptor.java
deleted file mode 100644
index 6bc84fc..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteDescriptor.java
+++ /dev/null
@@ -1,693 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.support.mediarouter.media;
-
-import android.content.IntentFilter;
-import android.content.IntentSender;
-import android.net.Uri;
-import android.os.Bundle;
-import android.text.TextUtils;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Describes the properties of a route.
- * <p>
- * Each route is uniquely identified by an opaque id string.  This token
- * may take any form as long as it is unique within the media route provider.
- * </p><p>
- * This object is immutable once created using a {@link Builder} instance.
- * </p>
- */
-public final class MediaRouteDescriptor {
-    static final String KEY_ID = "id";
-    static final String KEY_GROUP_MEMBER_IDS = "groupMemberIds";
-    static final String KEY_NAME = "name";
-    static final String KEY_DESCRIPTION = "status";
-    static final String KEY_ICON_URI = "iconUri";
-    static final String KEY_ENABLED = "enabled";
-    static final String KEY_CONNECTING = "connecting";
-    static final String KEY_CONNECTION_STATE = "connectionState";
-    static final String KEY_CONTROL_FILTERS = "controlFilters";
-    static final String KEY_PLAYBACK_TYPE = "playbackType";
-    static final String KEY_PLAYBACK_STREAM = "playbackStream";
-    static final String KEY_DEVICE_TYPE = "deviceType";
-    static final String KEY_VOLUME = "volume";
-    static final String KEY_VOLUME_MAX = "volumeMax";
-    static final String KEY_VOLUME_HANDLING = "volumeHandling";
-    static final String KEY_PRESENTATION_DISPLAY_ID = "presentationDisplayId";
-    static final String KEY_EXTRAS = "extras";
-    static final String KEY_CAN_DISCONNECT = "canDisconnect";
-    static final String KEY_SETTINGS_INTENT = "settingsIntent";
-    static final String KEY_MIN_CLIENT_VERSION = "minClientVersion";
-    static final String KEY_MAX_CLIENT_VERSION = "maxClientVersion";
-
-    final Bundle mBundle;
-    List<IntentFilter> mControlFilters;
-
-    MediaRouteDescriptor(Bundle bundle, List<IntentFilter> controlFilters) {
-        mBundle = bundle;
-        mControlFilters = controlFilters;
-    }
-
-    /**
-     * Gets the unique id of the route.
-     * <p>
-     * The route id associated with a route descriptor functions as a stable
-     * identifier for the route and must be unique among all routes offered
-     * by the provider.
-     * </p>
-     */
-    public String getId() {
-        return mBundle.getString(KEY_ID);
-    }
-
-    /**
-     * Gets the group member ids of the route.
-     * <p>
-     * A route descriptor that has one or more group member route ids
-     * represents a route group. A member route may belong to another group.
-     * </p>
-     * @hide
-     */
-    // @RestrictTo(LIBRARY_GROUP)
-    public List<String> getGroupMemberIds() {
-        return mBundle.getStringArrayList(KEY_GROUP_MEMBER_IDS);
-    }
-
-    /**
-     * Gets the user-visible name of the route.
-     * <p>
-     * The route name identifies the destination represented by the route.
-     * It may be a user-supplied name, an alias, or device serial number.
-     * </p>
-     */
-    public String getName() {
-        return mBundle.getString(KEY_NAME);
-    }
-
-    /**
-     * Gets the user-visible description of the route.
-     * <p>
-     * The route description describes the kind of destination represented by the route.
-     * It may be a user-supplied string, a model number or brand of device.
-     * </p>
-     */
-    public String getDescription() {
-        return mBundle.getString(KEY_DESCRIPTION);
-    }
-
-    /**
-     * Gets the URI of the icon representing this route.
-     * <p>
-     * This icon will be used in picker UIs if available.
-     * </p>
-     */
-    public Uri getIconUri() {
-        String iconUri = mBundle.getString(KEY_ICON_URI);
-        return iconUri == null ? null : Uri.parse(iconUri);
-    }
-
-    /**
-     * Gets whether the route is enabled.
-     */
-    public boolean isEnabled() {
-        return mBundle.getBoolean(KEY_ENABLED, true);
-    }
-
-    /**
-     * Gets whether the route is connecting.
-     * @deprecated Use {@link #getConnectionState} instead
-     */
-    @Deprecated
-    public boolean isConnecting() {
-        return mBundle.getBoolean(KEY_CONNECTING, false);
-    }
-
-    /**
-     * Gets the connection state of the route.
-     *
-     * @return The connection state of this route:
-     * {@link MediaRouter.RouteInfo#CONNECTION_STATE_DISCONNECTED},
-     * {@link MediaRouter.RouteInfo#CONNECTION_STATE_CONNECTING}, or
-     * {@link MediaRouter.RouteInfo#CONNECTION_STATE_CONNECTED}.
-     */
-    public int getConnectionState() {
-        return mBundle.getInt(KEY_CONNECTION_STATE,
-                MediaRouter.RouteInfo.CONNECTION_STATE_DISCONNECTED);
-    }
-
-    /**
-     * Gets whether the route can be disconnected without stopping playback.
-     * <p>
-     * The route can normally be disconnected without stopping playback when
-     * the destination device on the route is connected to two or more source
-     * devices. The route provider should update the route immediately when the
-     * number of connected devices changes.
-     * </p><p>
-     * To specify that the route should disconnect without stopping use
-     * {@link MediaRouter#unselect(int)} with
-     * {@link MediaRouter#UNSELECT_REASON_DISCONNECTED}.
-     * </p>
-     */
-    public boolean canDisconnectAndKeepPlaying() {
-        return mBundle.getBoolean(KEY_CAN_DISCONNECT, false);
-    }
-
-    /**
-     * Gets an {@link IntentSender} for starting a settings activity for this
-     * route. The activity may have specific route settings or general settings
-     * for the connected device or route provider.
-     *
-     * @return An {@link IntentSender} to start a settings activity.
-     */
-    public IntentSender getSettingsActivity() {
-        return mBundle.getParcelable(KEY_SETTINGS_INTENT);
-    }
-
-    /**
-     * Gets the route's {@link MediaControlIntent media control intent} filters.
-     */
-    public List<IntentFilter> getControlFilters() {
-        ensureControlFilters();
-        return mControlFilters;
-    }
-
-    void ensureControlFilters() {
-        if (mControlFilters == null) {
-            mControlFilters = mBundle.<IntentFilter>getParcelableArrayList(KEY_CONTROL_FILTERS);
-            if (mControlFilters == null) {
-                mControlFilters = Collections.<IntentFilter>emptyList();
-            }
-        }
-    }
-
-    /**
-     * Gets the type of playback associated with this route.
-     *
-     * @return The type of playback associated with this route:
-     * {@link MediaRouter.RouteInfo#PLAYBACK_TYPE_LOCAL} or
-     * {@link MediaRouter.RouteInfo#PLAYBACK_TYPE_REMOTE}.
-     */
-    public int getPlaybackType() {
-        return mBundle.getInt(KEY_PLAYBACK_TYPE, MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE);
-    }
-
-    /**
-     * Gets the route's playback stream.
-     */
-    public int getPlaybackStream() {
-        return mBundle.getInt(KEY_PLAYBACK_STREAM, -1);
-    }
-
-    /**
-     * Gets the type of the receiver device associated with this route.
-     *
-     * @return The type of the receiver device associated with this route:
-     * {@link MediaRouter.RouteInfo#DEVICE_TYPE_TV} or
-     * {@link MediaRouter.RouteInfo#DEVICE_TYPE_SPEAKER}.
-     */
-    public int getDeviceType() {
-        return mBundle.getInt(KEY_DEVICE_TYPE);
-    }
-
-    /**
-     * Gets the route's current volume, or 0 if unknown.
-     */
-    public int getVolume() {
-        return mBundle.getInt(KEY_VOLUME);
-    }
-
-    /**
-     * Gets the route's maximum volume, or 0 if unknown.
-     */
-    public int getVolumeMax() {
-        return mBundle.getInt(KEY_VOLUME_MAX);
-    }
-
-    /**
-     * Gets information about how volume is handled on the route.
-     *
-     * @return How volume is handled on the route:
-     * {@link MediaRouter.RouteInfo#PLAYBACK_VOLUME_FIXED} or
-     * {@link MediaRouter.RouteInfo#PLAYBACK_VOLUME_VARIABLE}.
-     */
-    public int getVolumeHandling() {
-        return mBundle.getInt(KEY_VOLUME_HANDLING,
-                MediaRouter.RouteInfo.PLAYBACK_VOLUME_FIXED);
-    }
-
-    /**
-     * Gets the route's presentation display id, or -1 if none.
-     */
-    public int getPresentationDisplayId() {
-        return mBundle.getInt(
-                KEY_PRESENTATION_DISPLAY_ID, MediaRouter.RouteInfo.PRESENTATION_DISPLAY_ID_NONE);
-    }
-
-    /**
-     * Gets a bundle of extras for this route descriptor.
-     * The extras will be ignored by the media router but they may be used
-     * by applications.
-     */
-    public Bundle getExtras() {
-        return mBundle.getBundle(KEY_EXTRAS);
-    }
-
-    /**
-     * Gets the minimum client version required for this route.
-     * @hide
-     */
-    // @RestrictTo(LIBRARY_GROUP)
-    public int getMinClientVersion() {
-        return mBundle.getInt(KEY_MIN_CLIENT_VERSION,
-                MediaRouteProviderProtocol.CLIENT_VERSION_START);
-    }
-
-    /**
-     * Gets the maximum client version required for this route.
-     * @hide
-     */
-    // @RestrictTo(LIBRARY_GROUP)
-    public int getMaxClientVersion() {
-        return mBundle.getInt(KEY_MAX_CLIENT_VERSION, Integer.MAX_VALUE);
-    }
-
-    /**
-     * Returns true if the route descriptor has all of the required fields.
-     */
-    public boolean isValid() {
-        ensureControlFilters();
-        if (TextUtils.isEmpty(getId())
-                || TextUtils.isEmpty(getName())
-                || mControlFilters.contains(null)) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder result = new StringBuilder();
-        result.append("MediaRouteDescriptor{ ");
-        result.append("id=").append(getId());
-        result.append(", groupMemberIds=").append(getGroupMemberIds());
-        result.append(", name=").append(getName());
-        result.append(", description=").append(getDescription());
-        result.append(", iconUri=").append(getIconUri());
-        result.append(", isEnabled=").append(isEnabled());
-        result.append(", isConnecting=").append(isConnecting());
-        result.append(", connectionState=").append(getConnectionState());
-        result.append(", controlFilters=").append(Arrays.toString(getControlFilters().toArray()));
-        result.append(", playbackType=").append(getPlaybackType());
-        result.append(", playbackStream=").append(getPlaybackStream());
-        result.append(", deviceType=").append(getDeviceType());
-        result.append(", volume=").append(getVolume());
-        result.append(", volumeMax=").append(getVolumeMax());
-        result.append(", volumeHandling=").append(getVolumeHandling());
-        result.append(", presentationDisplayId=").append(getPresentationDisplayId());
-        result.append(", extras=").append(getExtras());
-        result.append(", isValid=").append(isValid());
-        result.append(", minClientVersion=").append(getMinClientVersion());
-        result.append(", maxClientVersion=").append(getMaxClientVersion());
-        result.append(" }");
-        return result.toString();
-    }
-
-    /**
-     * Converts this object to a bundle for serialization.
-     *
-     * @return The contents of the object represented as a bundle.
-     */
-    public Bundle asBundle() {
-        return mBundle;
-    }
-
-    /**
-     * Creates an instance from a bundle.
-     *
-     * @param bundle The bundle, or null if none.
-     * @return The new instance, or null if the bundle was null.
-     */
-    public static MediaRouteDescriptor fromBundle(Bundle bundle) {
-        return bundle != null ? new MediaRouteDescriptor(bundle, null) : null;
-    }
-
-    /**
-     * Builder for {@link MediaRouteDescriptor media route descriptors}.
-     */
-    public static final class Builder {
-        private final Bundle mBundle;
-        private ArrayList<String> mGroupMemberIds;
-        private ArrayList<IntentFilter> mControlFilters;
-
-        /**
-         * Creates a media route descriptor builder.
-         *
-         * @param id The unique id of the route.
-         * @param name The user-visible name of the route.
-         */
-        public Builder(String id, String name) {
-            mBundle = new Bundle();
-            setId(id);
-            setName(name);
-        }
-
-        /**
-         * Creates a media route descriptor builder whose initial contents are
-         * copied from an existing descriptor.
-         */
-        public Builder(MediaRouteDescriptor descriptor) {
-            if (descriptor == null) {
-                throw new IllegalArgumentException("descriptor must not be null");
-            }
-
-            mBundle = new Bundle(descriptor.mBundle);
-
-            descriptor.ensureControlFilters();
-            if (!descriptor.mControlFilters.isEmpty()) {
-                mControlFilters = new ArrayList<IntentFilter>(descriptor.mControlFilters);
-            }
-        }
-
-        /**
-         * Sets the unique id of the route.
-         * <p>
-         * The route id associated with a route descriptor functions as a stable
-         * identifier for the route and must be unique among all routes offered
-         * by the provider.
-         * </p>
-         */
-        public Builder setId(String id) {
-            mBundle.putString(KEY_ID, id);
-            return this;
-        }
-
-        /**
-         * Adds a group member id of the route.
-         * <p>
-         * A route descriptor that has one or more group member route ids
-         * represents a route group. A member route may belong to another group.
-         * </p>
-         * @hide
-         */
-        // @RestrictTo(LIBRARY_GROUP)
-        public Builder addGroupMemberId(String groupMemberId) {
-            if (TextUtils.isEmpty(groupMemberId)) {
-                throw new IllegalArgumentException("groupMemberId must not be empty");
-            }
-
-            if (mGroupMemberIds == null) {
-                mGroupMemberIds = new ArrayList<>();
-            }
-            if (!mGroupMemberIds.contains(groupMemberId)) {
-                mGroupMemberIds.add(groupMemberId);
-            }
-            return this;
-        }
-
-        /**
-         * Adds a list of group member ids of the route.
-         * <p>
-         * A route descriptor that has one or more group member route ids
-         * represents a route group. A member route may belong to another group.
-         * </p>
-         * @hide
-         */
-        // @RestrictTo(LIBRARY_GROUP)
-        public Builder addGroupMemberIds(Collection<String> groupMemberIds) {
-            if (groupMemberIds == null) {
-                throw new IllegalArgumentException("groupMemberIds must not be null");
-            }
-
-            if (!groupMemberIds.isEmpty()) {
-                for (String groupMemberId : groupMemberIds) {
-                    addGroupMemberId(groupMemberId);
-                }
-            }
-            return this;
-        }
-
-        /**
-         * Sets the user-visible name of the route.
-         * <p>
-         * The route name identifies the destination represented by the route.
-         * It may be a user-supplied name, an alias, or device serial number.
-         * </p>
-         */
-        public Builder setName(String name) {
-            mBundle.putString(KEY_NAME, name);
-            return this;
-        }
-
-        /**
-         * Sets the user-visible description of the route.
-         * <p>
-         * The route description describes the kind of destination represented by the route.
-         * It may be a user-supplied string, a model number or brand of device.
-         * </p>
-         */
-        public Builder setDescription(String description) {
-            mBundle.putString(KEY_DESCRIPTION, description);
-            return this;
-        }
-
-        /**
-         * Sets the URI of the icon representing this route.
-         * <p>
-         * This icon will be used in picker UIs if available.
-         * </p><p>
-         * The URI must be one of the following formats:
-         * <ul>
-         * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
-         * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
-         * </li>
-         * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
-         * </ul>
-         * </p>
-         */
-        public Builder setIconUri(Uri iconUri) {
-            if (iconUri == null) {
-                throw new IllegalArgumentException("iconUri must not be null");
-            }
-            mBundle.putString(KEY_ICON_URI, iconUri.toString());
-            return this;
-        }
-
-        /**
-         * Sets whether the route is enabled.
-         * <p>
-         * Disabled routes represent routes that a route provider knows about, such as paired
-         * Wifi Display receivers, but that are not currently available for use.
-         * </p>
-         */
-        public Builder setEnabled(boolean enabled) {
-            mBundle.putBoolean(KEY_ENABLED, enabled);
-            return this;
-        }
-
-        /**
-         * Sets whether the route is in the process of connecting and is not yet
-         * ready for use.
-         * @deprecated Use {@link #setConnectionState} instead.
-         */
-        @Deprecated
-        public Builder setConnecting(boolean connecting) {
-            mBundle.putBoolean(KEY_CONNECTING, connecting);
-            return this;
-        }
-
-        /**
-         * Sets the route's connection state.
-         *
-         * @param connectionState The connection state of the route:
-         * {@link MediaRouter.RouteInfo#CONNECTION_STATE_DISCONNECTED},
-         * {@link MediaRouter.RouteInfo#CONNECTION_STATE_CONNECTING}, or
-         * {@link MediaRouter.RouteInfo#CONNECTION_STATE_CONNECTED}.
-         */
-        public Builder setConnectionState(int connectionState) {
-            mBundle.putInt(KEY_CONNECTION_STATE, connectionState);
-            return this;
-        }
-
-        /**
-         * Sets whether the route can be disconnected without stopping playback.
-         */
-        public Builder setCanDisconnect(boolean canDisconnect) {
-            mBundle.putBoolean(KEY_CAN_DISCONNECT, canDisconnect);
-            return this;
-        }
-
-        /**
-         * Sets an intent sender for launching the settings activity for this
-         * route.
-         */
-        public Builder setSettingsActivity(IntentSender is) {
-            mBundle.putParcelable(KEY_SETTINGS_INTENT, is);
-            return this;
-        }
-
-        /**
-         * Adds a {@link MediaControlIntent media control intent} filter for the route.
-         */
-        public Builder addControlFilter(IntentFilter filter) {
-            if (filter == null) {
-                throw new IllegalArgumentException("filter must not be null");
-            }
-
-            if (mControlFilters == null) {
-                mControlFilters = new ArrayList<IntentFilter>();
-            }
-            if (!mControlFilters.contains(filter)) {
-                mControlFilters.add(filter);
-            }
-            return this;
-        }
-
-        /**
-         * Adds a list of {@link MediaControlIntent media control intent} filters for the route.
-         */
-        public Builder addControlFilters(Collection<IntentFilter> filters) {
-            if (filters == null) {
-                throw new IllegalArgumentException("filters must not be null");
-            }
-
-            if (!filters.isEmpty()) {
-                for (IntentFilter filter : filters) {
-                    addControlFilter(filter);
-                }
-            }
-            return this;
-        }
-
-        /**
-         * Sets the route's playback type.
-         *
-         * @param playbackType The playback type of the route:
-         * {@link MediaRouter.RouteInfo#PLAYBACK_TYPE_LOCAL} or
-         * {@link MediaRouter.RouteInfo#PLAYBACK_TYPE_REMOTE}.
-         */
-        public Builder setPlaybackType(int playbackType) {
-            mBundle.putInt(KEY_PLAYBACK_TYPE, playbackType);
-            return this;
-        }
-
-        /**
-         * Sets the route's playback stream.
-         */
-        public Builder setPlaybackStream(int playbackStream) {
-            mBundle.putInt(KEY_PLAYBACK_STREAM, playbackStream);
-            return this;
-        }
-
-        /**
-         * Sets the route's receiver device type.
-         *
-         * @param deviceType The receive device type of the route:
-         * {@link MediaRouter.RouteInfo#DEVICE_TYPE_TV} or
-         * {@link MediaRouter.RouteInfo#DEVICE_TYPE_SPEAKER}.
-         */
-        public Builder setDeviceType(int deviceType) {
-            mBundle.putInt(KEY_DEVICE_TYPE, deviceType);
-            return this;
-        }
-
-        /**
-         * Sets the route's current volume, or 0 if unknown.
-         */
-        public Builder setVolume(int volume) {
-            mBundle.putInt(KEY_VOLUME, volume);
-            return this;
-        }
-
-        /**
-         * Sets the route's maximum volume, or 0 if unknown.
-         */
-        public Builder setVolumeMax(int volumeMax) {
-            mBundle.putInt(KEY_VOLUME_MAX, volumeMax);
-            return this;
-        }
-
-        /**
-         * Sets the route's volume handling.
-         *
-         * @param volumeHandling how volume is handled on the route:
-         * {@link MediaRouter.RouteInfo#PLAYBACK_VOLUME_FIXED} or
-         * {@link MediaRouter.RouteInfo#PLAYBACK_VOLUME_VARIABLE}.
-         */
-        public Builder setVolumeHandling(int volumeHandling) {
-            mBundle.putInt(KEY_VOLUME_HANDLING, volumeHandling);
-            return this;
-        }
-
-        /**
-         * Sets the route's presentation display id, or -1 if none.
-         */
-        public Builder setPresentationDisplayId(int presentationDisplayId) {
-            mBundle.putInt(KEY_PRESENTATION_DISPLAY_ID, presentationDisplayId);
-            return this;
-        }
-
-        /**
-         * Sets a bundle of extras for this route descriptor.
-         * The extras will be ignored by the media router but they may be used
-         * by applications.
-         */
-        public Builder setExtras(Bundle extras) {
-            mBundle.putBundle(KEY_EXTRAS, extras);
-            return this;
-        }
-
-        /**
-         * Sets the route's minimum client version.
-         * A router whose version is lower than this will not be able to connect to this route.
-         * @hide
-         */
-        // @RestrictTo(LIBRARY_GROUP)
-        public Builder setMinClientVersion(int minVersion) {
-            mBundle.putInt(KEY_MIN_CLIENT_VERSION, minVersion);
-            return this;
-        }
-
-        /**
-         * Sets the route's maximum client version.
-         * A router whose version is higher than this will not be able to connect to this route.
-         * @hide
-         */
-        // @RestrictTo(LIBRARY_GROUP)
-        public Builder setMaxClientVersion(int maxVersion) {
-            mBundle.putInt(KEY_MAX_CLIENT_VERSION, maxVersion);
-            return this;
-        }
-
-        /**
-         * Builds the {@link MediaRouteDescriptor media route descriptor}.
-         */
-        public MediaRouteDescriptor build() {
-            if (mControlFilters != null) {
-                mBundle.putParcelableArrayList(KEY_CONTROL_FILTERS, mControlFilters);
-            }
-            if (mGroupMemberIds != null) {
-                mBundle.putStringArrayList(KEY_GROUP_MEMBER_IDS, mGroupMemberIds);
-            }
-            return new MediaRouteDescriptor(mBundle, mControlFilters);
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteDiscoveryRequest.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteDiscoveryRequest.java
deleted file mode 100644
index 039627f..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteDiscoveryRequest.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.support.mediarouter.media;
-
-import android.os.Bundle;
-
-/**
- * Describes the kinds of routes that the media router would like to discover
- * and whether to perform active scanning.
- * <p>
- * This object is immutable once created.
- * </p>
- */
-public final class MediaRouteDiscoveryRequest {
-    private static final String KEY_SELECTOR = "selector";
-    private static final String KEY_ACTIVE_SCAN = "activeScan";
-
-    private final Bundle mBundle;
-    private MediaRouteSelector mSelector;
-
-    /**
-     * Creates a media route discovery request.
-     *
-     * @param selector The route selector that specifies the kinds of routes to discover.
-     * @param activeScan True if active scanning should be performed.
-     */
-    public MediaRouteDiscoveryRequest(MediaRouteSelector selector, boolean activeScan) {
-        if (selector == null) {
-            throw new IllegalArgumentException("selector must not be null");
-        }
-
-        mBundle = new Bundle();
-        mSelector = selector;
-        mBundle.putBundle(KEY_SELECTOR, selector.asBundle());
-        mBundle.putBoolean(KEY_ACTIVE_SCAN, activeScan);
-    }
-
-    private MediaRouteDiscoveryRequest(Bundle bundle) {
-        mBundle = bundle;
-    }
-
-    /**
-     * Gets the route selector that specifies the kinds of routes to discover.
-     */
-    public MediaRouteSelector getSelector() {
-        ensureSelector();
-        return mSelector;
-    }
-
-    private void ensureSelector() {
-        if (mSelector == null) {
-            mSelector = MediaRouteSelector.fromBundle(mBundle.getBundle(KEY_SELECTOR));
-            if (mSelector == null) {
-                mSelector = MediaRouteSelector.EMPTY;
-            }
-        }
-    }
-
-    /**
-     * Returns true if active scanning should be performed.
-     *
-     * @see MediaRouter#CALLBACK_FLAG_PERFORM_ACTIVE_SCAN
-     */
-    public boolean isActiveScan() {
-        return mBundle.getBoolean(KEY_ACTIVE_SCAN);
-    }
-
-    /**
-     * Returns true if the discovery request has all of the required fields.
-     */
-    public boolean isValid() {
-        ensureSelector();
-        return mSelector.isValid();
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (o instanceof MediaRouteDiscoveryRequest) {
-            MediaRouteDiscoveryRequest other = (MediaRouteDiscoveryRequest)o;
-            return getSelector().equals(other.getSelector())
-                    && isActiveScan() == other.isActiveScan();
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return getSelector().hashCode() ^ (isActiveScan() ? 1 : 0);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder result = new StringBuilder();
-        result.append("DiscoveryRequest{ selector=").append(getSelector());
-        result.append(", activeScan=").append(isActiveScan());
-        result.append(", isValid=").append(isValid());
-        result.append(" }");
-        return result.toString();
-    }
-
-    /**
-     * Converts this object to a bundle for serialization.
-     *
-     * @return The contents of the object represented as a bundle.
-     */
-    public Bundle asBundle() {
-        return mBundle;
-    }
-
-    /**
-     * Creates an instance from a bundle.
-     *
-     * @param bundle The bundle, or null if none.
-     * @return The new instance, or null if the bundle was null.
-     */
-    public static MediaRouteDiscoveryRequest fromBundle(Bundle bundle) {
-        return bundle != null ? new MediaRouteDiscoveryRequest(bundle) : null;
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteProvider.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteProvider.java
deleted file mode 100644
index 91a2e1a..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteProvider.java
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.media;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.Message;
-import android.support.v4.util.ObjectsCompat;
-
-import com.android.support.mediarouter.media.MediaRouter.ControlRequestCallback;
-
-/**
- * Media route providers are used to publish additional media routes for
- * use within an application.  Media route providers may also be declared
- * as a service to publish additional media routes to all applications
- * in the system.
- * <p>
- * The purpose of a media route provider is to discover media routes that satisfy
- * the criteria specified by the current {@link MediaRouteDiscoveryRequest} and publish a
- * {@link MediaRouteProviderDescriptor} with information about each route by calling
- * {@link #setDescriptor} to notify the currently registered {@link Callback}.
- * </p><p>
- * The provider should watch for changes to the discovery request by implementing
- * {@link #onDiscoveryRequestChanged} and updating the set of routes that it is
- * attempting to discover.  It should also handle route control requests such
- * as volume changes or {@link MediaControlIntent media control intents}
- * by implementing {@link #onCreateRouteController} to return a {@link RouteController}
- * for a particular route.
- * </p><p>
- * A media route provider may be used privately within the scope of a single
- * application process by calling {@link MediaRouter#addProvider MediaRouter.addProvider}
- * to add it to the local {@link MediaRouter}.  A media route provider may also be made
- * available globally to all applications by registering a {@link MediaRouteProviderService}
- * in the provider's manifest.  When the media route provider is registered
- * as a service, all applications that use the media router API will be able to
- * discover and used the provider's routes without having to install anything else.
- * </p><p>
- * This object must only be accessed on the main thread.
- * </p>
- */
-public abstract class MediaRouteProvider {
-    static final int MSG_DELIVER_DESCRIPTOR_CHANGED = 1;
-    static final int MSG_DELIVER_DISCOVERY_REQUEST_CHANGED = 2;
-
-    private final Context mContext;
-    private final ProviderMetadata mMetadata;
-    private final ProviderHandler mHandler = new ProviderHandler();
-
-    private Callback mCallback;
-
-    private MediaRouteDiscoveryRequest mDiscoveryRequest;
-    private boolean mPendingDiscoveryRequestChange;
-
-    private MediaRouteProviderDescriptor mDescriptor;
-    private boolean mPendingDescriptorChange;
-
-    /**
-     * Creates a media route provider.
-     *
-     * @param context The context.
-     */
-    public MediaRouteProvider(@NonNull Context context) {
-        this(context, null);
-    }
-
-    MediaRouteProvider(Context context, ProviderMetadata metadata) {
-        if (context == null) {
-            throw new IllegalArgumentException("context must not be null");
-        }
-
-        mContext = context;
-        if (metadata == null) {
-            mMetadata = new ProviderMetadata(new ComponentName(context, getClass()));
-        } else {
-            mMetadata = metadata;
-        }
-    }
-
-    /**
-     * Gets the context of the media route provider.
-     */
-    public final Context getContext() {
-        return mContext;
-    }
-
-    /**
-     * Gets the provider's handler which is associated with the main thread.
-     */
-    public final Handler getHandler() {
-        return mHandler;
-    }
-
-    /**
-     * Gets some metadata about the provider's implementation.
-     */
-    public final ProviderMetadata getMetadata() {
-        return mMetadata;
-    }
-
-    /**
-     * Sets a callback to invoke when the provider's descriptor changes.
-     *
-     * @param callback The callback to use, or null if none.
-     */
-    public final void setCallback(@Nullable Callback callback) {
-        MediaRouter.checkCallingThread();
-        mCallback = callback;
-    }
-
-    /**
-     * Gets the current discovery request which informs the provider about the
-     * kinds of routes to discover and whether to perform active scanning.
-     *
-     * @return The current discovery request, or null if no discovery is needed at this time.
-     *
-     * @see #onDiscoveryRequestChanged
-     */
-    @Nullable
-    public final MediaRouteDiscoveryRequest getDiscoveryRequest() {
-        return mDiscoveryRequest;
-    }
-
-    /**
-     * Sets a discovery request to inform the provider about the kinds of
-     * routes that its clients would like to discover and whether to perform active scanning.
-     *
-     * @param request The discovery request, or null if no discovery is needed at this time.
-     *
-     * @see #onDiscoveryRequestChanged
-     */
-    public final void setDiscoveryRequest(MediaRouteDiscoveryRequest request) {
-        MediaRouter.checkCallingThread();
-
-        if (ObjectsCompat.equals(mDiscoveryRequest, request)) {
-            return;
-        }
-
-        mDiscoveryRequest = request;
-        if (!mPendingDiscoveryRequestChange) {
-            mPendingDiscoveryRequestChange = true;
-            mHandler.sendEmptyMessage(MSG_DELIVER_DISCOVERY_REQUEST_CHANGED);
-        }
-    }
-
-    void deliverDiscoveryRequestChanged() {
-        mPendingDiscoveryRequestChange = false;
-        onDiscoveryRequestChanged(mDiscoveryRequest);
-    }
-
-    /**
-     * Called by the media router when the {@link MediaRouteDiscoveryRequest discovery request}
-     * has changed.
-     * <p>
-     * Whenever an applications calls {@link MediaRouter#addCallback} to register
-     * a callback, it also provides a selector to specify the kinds of routes that
-     * it is interested in.  The media router combines all of these selectors together
-     * to generate a {@link MediaRouteDiscoveryRequest} and notifies each provider when a change
-     * occurs by calling {@link #setDiscoveryRequest} which posts a message to invoke
-     * this method asynchronously.
-     * </p><p>
-     * The provider should examine the {@link MediaControlIntent media control categories}
-     * in the discovery request's {@link MediaRouteSelector selector} to determine what
-     * kinds of routes it should try to discover and whether it should perform active
-     * or passive scans.  In many cases, the provider may be able to save power by
-     * determining that the selector does not contain any categories that it supports
-     * and it can therefore avoid performing any scans at all.
-     * </p>
-     *
-     * @param request The new discovery request, or null if no discovery is needed at this time.
-     *
-     * @see MediaRouter#addCallback
-     */
-    public void onDiscoveryRequestChanged(@Nullable MediaRouteDiscoveryRequest request) {
-    }
-
-    /**
-     * Gets the provider's descriptor.
-     * <p>
-     * The descriptor describes the state of the media route provider and
-     * the routes that it publishes.  Watch for changes to the descriptor
-     * by registering a {@link Callback callback} with {@link #setCallback}.
-     * </p>
-     *
-     * @return The media route provider descriptor, or null if none.
-     *
-     * @see Callback#onDescriptorChanged
-     */
-    @Nullable
-    public final MediaRouteProviderDescriptor getDescriptor() {
-        return mDescriptor;
-    }
-
-    /**
-     * Sets the provider's descriptor.
-     * <p>
-     * The provider must call this method to notify the currently registered
-     * {@link Callback callback} about the change to the provider's descriptor.
-     * </p>
-     *
-     * @param descriptor The updated route provider descriptor, or null if none.
-     *
-     * @see Callback#onDescriptorChanged
-     */
-    public final void setDescriptor(@Nullable MediaRouteProviderDescriptor descriptor) {
-        MediaRouter.checkCallingThread();
-
-        if (mDescriptor != descriptor) {
-            mDescriptor = descriptor;
-            if (!mPendingDescriptorChange) {
-                mPendingDescriptorChange = true;
-                mHandler.sendEmptyMessage(MSG_DELIVER_DESCRIPTOR_CHANGED);
-            }
-        }
-    }
-
-    void deliverDescriptorChanged() {
-        mPendingDescriptorChange = false;
-
-        if (mCallback != null) {
-            mCallback.onDescriptorChanged(this, mDescriptor);
-        }
-    }
-
-    /**
-     * Called by the media router to obtain a route controller for a particular route.
-     * <p>
-     * The media router will invoke the {@link RouteController#onRelease} method of the route
-     * controller when it is no longer needed to allow it to free its resources.
-     * </p>
-     *
-     * @param routeId The unique id of the route.
-     * @return The route controller.  Returns null if there is no such route or if the route
-     * cannot be controlled using the route controller interface.
-     */
-    @Nullable
-    public RouteController onCreateRouteController(@NonNull String routeId) {
-        if (routeId == null) {
-            throw new IllegalArgumentException("routeId cannot be null");
-        }
-        return null;
-    }
-
-    /**
-     * Called by the media router to obtain a route controller for a particular route which is a
-     * member of {@link MediaRouter.RouteGroup}.
-     * <p>
-     * The media router will invoke the {@link RouteController#onRelease} method of the route
-     * controller when it is no longer needed to allow it to free its resources.
-     * </p>
-     *
-     * @param routeId The unique id of the member route.
-     * @param routeGroupId The unique id of the route group.
-     * @return The route controller.  Returns null if there is no such route or if the route
-     * cannot be controlled using the route controller interface.
-     * @hide
-     */
-    // @RestrictTo(LIBRARY_GROUP)
-    @Nullable
-    public RouteController onCreateRouteController(@NonNull String routeId,
-            @NonNull String routeGroupId) {
-        if (routeId == null) {
-            throw new IllegalArgumentException("routeId cannot be null");
-        }
-        if (routeGroupId == null) {
-            throw new IllegalArgumentException("routeGroupId cannot be null");
-        }
-        return onCreateRouteController(routeId);
-    }
-
-    /**
-     * Describes properties of the route provider's implementation.
-     * <p>
-     * This object is immutable once created.
-     * </p>
-     */
-    public static final class ProviderMetadata {
-        private final ComponentName mComponentName;
-
-        ProviderMetadata(ComponentName componentName) {
-            if (componentName == null) {
-                throw new IllegalArgumentException("componentName must not be null");
-            }
-            mComponentName = componentName;
-        }
-
-        /**
-         * Gets the provider's package name.
-         */
-        public String getPackageName() {
-            return mComponentName.getPackageName();
-        }
-
-        /**
-         * Gets the provider's component name.
-         */
-        public ComponentName getComponentName() {
-            return mComponentName;
-        }
-
-        @Override
-        public String toString() {
-            return "ProviderMetadata{ componentName="
-                    + mComponentName.flattenToShortString() + " }";
-        }
-    }
-
-    /**
-     * Provides control over a particular route.
-     * <p>
-     * The media router obtains a route controller for a route whenever it needs
-     * to control a route.  When a route is selected, the media router invokes
-     * the {@link #onSelect} method of its route controller.  While selected,
-     * the media router may call other methods of the route controller to
-     * request that it perform certain actions to the route.  When a route is
-     * unselected, the media router invokes the {@link #onUnselect} method of its
-     * route controller.  When the media route no longer needs the route controller
-     * it will invoke the {@link #onRelease} method to allow the route controller
-     * to free its resources.
-     * </p><p>
-     * There may be multiple route controllers simultaneously active for the
-     * same route.  Each route controller will be released separately.
-     * </p><p>
-     * All operations on the route controller are asynchronous and
-     * results are communicated via callbacks.
-     * </p>
-     */
-    public static abstract class RouteController {
-        /**
-         * Releases the route controller, allowing it to free its resources.
-         */
-        public void onRelease() {
-        }
-
-        /**
-         * Selects the route.
-         */
-        public void onSelect() {
-        }
-
-        /**
-         * Unselects the route.
-         */
-        public void onUnselect() {
-        }
-
-        /**
-         * Unselects the route and provides a reason. The default implementation
-         * calls {@link #onUnselect()}.
-         * <p>
-         * The reason provided will be one of the following:
-         * <ul>
-         * <li>{@link MediaRouter#UNSELECT_REASON_UNKNOWN}</li>
-         * <li>{@link MediaRouter#UNSELECT_REASON_DISCONNECTED}</li>
-         * <li>{@link MediaRouter#UNSELECT_REASON_STOPPED}</li>
-         * <li>{@link MediaRouter#UNSELECT_REASON_ROUTE_CHANGED}</li>
-         * </ul>
-         *
-         * @param reason The reason for unselecting the route.
-         */
-        public void onUnselect(int reason) {
-            onUnselect();
-        }
-
-        /**
-         * Requests to set the volume of the route.
-         *
-         * @param volume The new volume value between 0 and {@link MediaRouteDescriptor#getVolumeMax}.
-         */
-        public void onSetVolume(int volume) {
-        }
-
-        /**
-         * Requests an incremental volume update for the route.
-         *
-         * @param delta The delta to add to the current volume.
-         */
-        public void onUpdateVolume(int delta) {
-        }
-
-        /**
-         * Performs a {@link MediaControlIntent media control} request
-         * asynchronously on behalf of the route.
-         *
-         * @param intent A {@link MediaControlIntent media control intent}.
-         * @param callback A {@link ControlRequestCallback} to invoke with the result
-         * of the request, or null if no result is required.
-         * @return True if the controller intends to handle the request and will
-         * invoke the callback when finished.  False if the controller will not
-         * handle the request and will not invoke the callback.
-         *
-         * @see MediaControlIntent
-         */
-        public boolean onControlRequest(Intent intent, @Nullable ControlRequestCallback callback) {
-            return false;
-        }
-    }
-
-    /**
-     * Callback which is invoked when route information becomes available or changes.
-     */
-    public static abstract class Callback {
-        /**
-         * Called when information about a route provider and its routes changes.
-         *
-         * @param provider The media route provider that changed, never null.
-         * @param descriptor The new media route provider descriptor, or null if none.
-         */
-        public void onDescriptorChanged(@NonNull MediaRouteProvider provider,
-                @Nullable MediaRouteProviderDescriptor descriptor) {
-        }
-    }
-
-    private final class ProviderHandler extends Handler {
-        ProviderHandler() {
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_DELIVER_DESCRIPTOR_CHANGED:
-                    deliverDescriptorChanged();
-                    break;
-                case MSG_DELIVER_DISCOVERY_REQUEST_CHANGED:
-                    deliverDiscoveryRequestChanged();
-                    break;
-            }
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteProviderDescriptor.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteProviderDescriptor.java
deleted file mode 100644
index eb1ce09..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteProviderDescriptor.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.support.mediarouter.media;
-
-import android.os.Bundle;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Describes the state of a media route provider and the routes that it publishes.
- * <p>
- * This object is immutable once created using a {@link Builder} instance.
- * </p>
- */
-public final class MediaRouteProviderDescriptor {
-    private static final String KEY_ROUTES = "routes";
-
-    private final Bundle mBundle;
-    private List<MediaRouteDescriptor> mRoutes;
-
-    private MediaRouteProviderDescriptor(Bundle bundle, List<MediaRouteDescriptor> routes) {
-        mBundle = bundle;
-        mRoutes = routes;
-    }
-
-    /**
-     * Gets the list of all routes that this provider has published.
-     */
-    public List<MediaRouteDescriptor> getRoutes() {
-        ensureRoutes();
-        return mRoutes;
-    }
-
-    private void ensureRoutes() {
-        if (mRoutes == null) {
-            ArrayList<Bundle> routeBundles = mBundle.<Bundle>getParcelableArrayList(KEY_ROUTES);
-            if (routeBundles == null || routeBundles.isEmpty()) {
-                mRoutes = Collections.<MediaRouteDescriptor>emptyList();
-            } else {
-                final int count = routeBundles.size();
-                mRoutes = new ArrayList<MediaRouteDescriptor>(count);
-                for (int i = 0; i < count; i++) {
-                    mRoutes.add(MediaRouteDescriptor.fromBundle(routeBundles.get(i)));
-                }
-            }
-        }
-    }
-
-    /**
-     * Returns true if the route provider descriptor and all of the routes that
-     * it contains have all of the required fields.
-     * <p>
-     * This verification is deep.  If the provider descriptor is known to be
-     * valid then it is not necessary to call {@link #isValid} on each of its routes.
-     * </p>
-     */
-    public boolean isValid() {
-        ensureRoutes();
-        final int routeCount = mRoutes.size();
-        for (int i = 0; i < routeCount; i++) {
-            MediaRouteDescriptor route = mRoutes.get(i);
-            if (route == null || !route.isValid()) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder result = new StringBuilder();
-        result.append("MediaRouteProviderDescriptor{ ");
-        result.append("routes=").append(
-                Arrays.toString(getRoutes().toArray()));
-        result.append(", isValid=").append(isValid());
-        result.append(" }");
-        return result.toString();
-    }
-
-    /**
-     * Converts this object to a bundle for serialization.
-     *
-     * @return The contents of the object represented as a bundle.
-     */
-    public Bundle asBundle() {
-        return mBundle;
-    }
-
-    /**
-     * Creates an instance from a bundle.
-     *
-     * @param bundle The bundle, or null if none.
-     * @return The new instance, or null if the bundle was null.
-     */
-    public static MediaRouteProviderDescriptor fromBundle(Bundle bundle) {
-        return bundle != null ? new MediaRouteProviderDescriptor(bundle, null) : null;
-    }
-
-    /**
-     * Builder for {@link MediaRouteProviderDescriptor media route provider descriptors}.
-     */
-    public static final class Builder {
-        private final Bundle mBundle;
-        private ArrayList<MediaRouteDescriptor> mRoutes;
-
-        /**
-         * Creates an empty media route provider descriptor builder.
-         */
-        public Builder() {
-            mBundle = new Bundle();
-        }
-
-        /**
-         * Creates a media route provider descriptor builder whose initial contents are
-         * copied from an existing descriptor.
-         */
-        public Builder(MediaRouteProviderDescriptor descriptor) {
-            if (descriptor == null) {
-                throw new IllegalArgumentException("descriptor must not be null");
-            }
-
-            mBundle = new Bundle(descriptor.mBundle);
-
-            descriptor.ensureRoutes();
-            if (!descriptor.mRoutes.isEmpty()) {
-                mRoutes = new ArrayList<MediaRouteDescriptor>(descriptor.mRoutes);
-            }
-        }
-
-        /**
-         * Adds a route.
-         */
-        public Builder addRoute(MediaRouteDescriptor route) {
-            if (route == null) {
-                throw new IllegalArgumentException("route must not be null");
-            }
-
-            if (mRoutes == null) {
-                mRoutes = new ArrayList<MediaRouteDescriptor>();
-            } else if (mRoutes.contains(route)) {
-                throw new IllegalArgumentException("route descriptor already added");
-            }
-            mRoutes.add(route);
-            return this;
-        }
-
-        /**
-         * Adds a list of routes.
-         */
-        public Builder addRoutes(Collection<MediaRouteDescriptor> routes) {
-            if (routes == null) {
-                throw new IllegalArgumentException("routes must not be null");
-            }
-
-            if (!routes.isEmpty()) {
-                for (MediaRouteDescriptor route : routes) {
-                    addRoute(route);
-                }
-            }
-            return this;
-        }
-
-        /**
-         * Sets the list of routes.
-         */
-        Builder setRoutes(Collection<MediaRouteDescriptor> routes) {
-            if (routes == null || routes.isEmpty()) {
-                mRoutes = null;
-                mBundle.remove(KEY_ROUTES);
-            } else {
-                mRoutes = new ArrayList<>(routes);
-            }
-            return this;
-        }
-
-        /**
-         * Builds the {@link MediaRouteProviderDescriptor media route provider descriptor}.
-         */
-        public MediaRouteProviderDescriptor build() {
-            if (mRoutes != null) {
-                final int count = mRoutes.size();
-                ArrayList<Bundle> routeBundles = new ArrayList<Bundle>(count);
-                for (int i = 0; i < count; i++) {
-                    routeBundles.add(mRoutes.get(i).asBundle());
-                }
-                mBundle.putParcelableArrayList(KEY_ROUTES, routeBundles);
-            }
-            return new MediaRouteProviderDescriptor(mBundle, mRoutes);
-        }
-    }
-}
\ No newline at end of file
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteProviderProtocol.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteProviderProtocol.java
deleted file mode 100644
index 6be9343..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteProviderProtocol.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.media;
-
-import android.content.Intent;
-import android.os.Messenger;
-
-/**
- * Defines the communication protocol for media route provider services.
- */
-abstract class MediaRouteProviderProtocol {
-    /**
-     * The {@link Intent} that must be declared as handled by the service.
-     * Put this in your manifest.
-     */
-    public static final String SERVICE_INTERFACE =
-            "android.media.MediaRouteProviderService";
-
-    /*
-     * Messages sent from the client to the service.
-     * DO NOT RENUMBER THESE!
-     */
-
-    /** (client v1)
-     * Register client.
-     * - replyTo : client messenger
-     * - arg1    : request id
-     * - arg2    : client version
-     */
-    public static final int CLIENT_MSG_REGISTER = 1;
-
-    /** (client v1)
-     * Unregister client.
-     * - replyTo : client messenger
-     * - arg1    : request id
-     */
-    public static final int CLIENT_MSG_UNREGISTER = 2;
-
-    /** (client v1)
-     * Create route controller.
-     * - replyTo : client messenger
-     * - arg1    : request id
-     * - arg2    : route controller id
-     * - CLIENT_DATA_ROUTE_ID : route id string
-     */
-    public static final int CLIENT_MSG_CREATE_ROUTE_CONTROLLER = 3;
-
-    /** (client v1)
-     * Release route controller.
-     * - replyTo : client messenger
-     * - arg1    : request id
-     * - arg2    : route controller id
-     */
-    public static final int CLIENT_MSG_RELEASE_ROUTE_CONTROLLER = 4;
-
-    /** (client v1)
-     * Select route.
-     * - replyTo : client messenger
-     * - arg1    : request id
-     * - arg2    : route controller id
-     */
-    public static final int CLIENT_MSG_SELECT_ROUTE = 5;
-
-    /** (client v1)
-     * Unselect route.
-     * - replyTo : client messenger
-     * - arg1    : request id
-     * - arg2    : route controller id
-     */
-    public static final int CLIENT_MSG_UNSELECT_ROUTE = 6;
-
-    /** (client v1)
-     * Set route volume.
-     * - replyTo : client messenger
-     * - arg1    : request id
-     * - arg2    : route controller id
-     * - CLIENT_DATA_VOLUME : volume integer
-     */
-    public static final int CLIENT_MSG_SET_ROUTE_VOLUME = 7;
-
-    /** (client v1)
-     * Update route volume.
-     * - replyTo : client messenger
-     * - arg1    : request id
-     * - arg2    : route controller id
-     * - CLIENT_DATA_VOLUME : volume delta integer
-     */
-    public static final int CLIENT_MSG_UPDATE_ROUTE_VOLUME = 8;
-
-    /** (client v1)
-     * Route control request.
-     * - replyTo : client messenger
-     * - arg1    : request id
-     * - arg2    : route controller id
-     * - obj     : media control intent
-     */
-    public static final int CLIENT_MSG_ROUTE_CONTROL_REQUEST = 9;
-
-    /** (client v1)
-     * Sets the discovery request.
-     * - replyTo : client messenger
-     * - arg1    : request id
-     * - obj     : discovery request bundle, or null if none
-     */
-    public static final int CLIENT_MSG_SET_DISCOVERY_REQUEST = 10;
-
-    public static final String CLIENT_DATA_ROUTE_ID = "routeId";
-    public static final String CLIENT_DATA_ROUTE_LIBRARY_GROUP = "routeGroupId";
-    public static final String CLIENT_DATA_VOLUME = "volume";
-    public static final String CLIENT_DATA_UNSELECT_REASON = "unselectReason";
-
-    /*
-     * Messages sent from the service to the client.
-     * DO NOT RENUMBER THESE!
-     */
-
-    /** (service v1)
-     * Generic failure sent in response to any unrecognized or malformed request.
-     * - arg1    : request id
-     */
-    public static final int SERVICE_MSG_GENERIC_FAILURE = 0;
-
-    /** (service v1)
-     * Generic failure sent in response to a successful message.
-     * - arg1    : request id
-     */
-    public static final int SERVICE_MSG_GENERIC_SUCCESS = 1;
-
-    /** (service v1)
-     * Registration succeeded.
-     * - arg1    : request id
-     * - arg2    : server version
-     * - obj     : route provider descriptor bundle, or null
-     */
-    public static final int SERVICE_MSG_REGISTERED = 2;
-
-    /** (service v1)
-     * Route control request success result.
-     * - arg1    : request id
-     * - obj     : result data bundle, or null
-     */
-    public static final int SERVICE_MSG_CONTROL_REQUEST_SUCCEEDED = 3;
-
-    /** (service v1)
-     * Route control request failure result.
-     * - arg1    : request id
-     * - obj     : result data bundle, or null
-     * - SERVICE_DATA_ERROR: error message
-     */
-    public static final int SERVICE_MSG_CONTROL_REQUEST_FAILED = 4;
-
-    /** (service v1)
-     * Route provider descriptor changed.  (unsolicited event)
-     * - arg1    : reserved (0)
-     * - obj     : route provider descriptor bundle, or null
-     */
-    public static final int SERVICE_MSG_DESCRIPTOR_CHANGED = 5;
-
-    public static final String SERVICE_DATA_ERROR = "error";
-
-    /*
-     * Recognized client version numbers.  (Reserved for future use.)
-     * DO NOT RENUMBER THESE!
-     */
-
-    /**
-     * The client version used from the beginning.
-     */
-    public static final int CLIENT_VERSION_1 = 1;
-
-    /**
-     * The client version used from support library v24.1.0.
-     */
-    public static final int CLIENT_VERSION_2 = 2;
-
-    /**
-     * The current client version.
-     */
-    public static final int CLIENT_VERSION_CURRENT = CLIENT_VERSION_2;
-
-    /*
-     * Recognized server version numbers.  (Reserved for future use.)
-     * DO NOT RENUMBER THESE!
-     */
-
-    /**
-     * The service version used from the beginning.
-     */
-    public static final int SERVICE_VERSION_1 = 1;
-
-    /**
-     * The current service version.
-     */
-    public static final int SERVICE_VERSION_CURRENT = SERVICE_VERSION_1;
-
-    static final int CLIENT_VERSION_START = CLIENT_VERSION_1;
-
-    /**
-     * Returns true if the messenger object is valid.
-     * <p>
-     * The messenger constructor and unparceling code does not check whether the
-     * provided IBinder is a valid IMessenger object.  As a result, it's possible
-     * for a peer to send an invalid IBinder that will result in crashes downstream.
-     * This method checks that the messenger is in a valid state.
-     * </p>
-     */
-    public static boolean isValidRemoteMessenger(Messenger messenger) {
-        try {
-            return messenger != null && messenger.getBinder() != null;
-        } catch (NullPointerException ex) {
-            // If the messenger was constructed with a binder interface other than
-            // IMessenger then the call to getBinder() will crash with an NPE.
-            return false;
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteProviderService.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteProviderService.java
deleted file mode 100644
index 43cde10..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteProviderService.java
+++ /dev/null
@@ -1,759 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.media;
-
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.CLIENT_DATA_ROUTE_ID;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .CLIENT_DATA_ROUTE_LIBRARY_GROUP;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .CLIENT_DATA_UNSELECT_REASON;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.CLIENT_DATA_VOLUME;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .CLIENT_MSG_CREATE_ROUTE_CONTROLLER;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.CLIENT_MSG_REGISTER;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .CLIENT_MSG_RELEASE_ROUTE_CONTROLLER;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .CLIENT_MSG_ROUTE_CONTROL_REQUEST;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.CLIENT_MSG_SELECT_ROUTE;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .CLIENT_MSG_SET_DISCOVERY_REQUEST;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .CLIENT_MSG_SET_ROUTE_VOLUME;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.CLIENT_MSG_UNREGISTER;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .CLIENT_MSG_UNSELECT_ROUTE;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .CLIENT_MSG_UPDATE_ROUTE_VOLUME;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.CLIENT_VERSION_1;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.SERVICE_DATA_ERROR;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .SERVICE_MSG_CONTROL_REQUEST_FAILED;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .SERVICE_MSG_CONTROL_REQUEST_SUCCEEDED;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .SERVICE_MSG_DESCRIPTOR_CHANGED;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .SERVICE_MSG_GENERIC_FAILURE;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .SERVICE_MSG_GENERIC_SUCCESS;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.SERVICE_MSG_REGISTERED;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.SERVICE_VERSION_CURRENT;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.isValidRemoteMessenger;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.DeadObjectException;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.IBinder.DeathRecipient;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.support.annotation.VisibleForTesting;
-import android.support.v4.util.ObjectsCompat;
-import android.util.Log;
-import android.util.SparseArray;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-
-/**
- * Base class for media route provider services.
- * <p>
- * A media router will bind to media route provider services when a callback is added via
- * {@link MediaRouter#addCallback(MediaRouteSelector, MediaRouter.Callback, int)} with a discovery
- * flag: {@link MediaRouter#CALLBACK_FLAG_REQUEST_DISCOVERY},
- * {@link MediaRouter#CALLBACK_FLAG_FORCE_DISCOVERY}, or
- * {@link MediaRouter#CALLBACK_FLAG_PERFORM_ACTIVE_SCAN}, and will unbind when the callback
- * is removed via {@link MediaRouter#removeCallback(MediaRouter.Callback)}.
- * </p><p>
- * To implement your own media route provider service, extend this class and
- * override the {@link #onCreateMediaRouteProvider} method to return an
- * instance of your {@link MediaRouteProvider}.
- * </p><p>
- * Declare your media route provider service in your application manifest
- * like this:
- * </p>
- * <pre>
- *   &lt;service android:name=".MyMediaRouteProviderService"
- *           android:label="@string/my_media_route_provider_service">
- *       &lt;intent-filter>
- *           &lt;action android:name="android.media.MediaRouteProviderService" />
- *       &lt;/intent-filter>
- *   &lt;/service>
- * </pre>
- */
-public abstract class MediaRouteProviderService extends Service {
-    static final String TAG = "MediaRouteProviderSrv"; // max. 23 chars
-    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    private final ArrayList<ClientRecord> mClients = new ArrayList<ClientRecord>();
-    private final ReceiveHandler mReceiveHandler;
-    private final Messenger mReceiveMessenger;
-    final PrivateHandler mPrivateHandler;
-    private final ProviderCallback mProviderCallback;
-
-    MediaRouteProvider mProvider;
-    private MediaRouteDiscoveryRequest mCompositeDiscoveryRequest;
-
-    /**
-     * The {@link Intent} that must be declared as handled by the service.
-     * Put this in your manifest.
-     */
-    public static final String SERVICE_INTERFACE = MediaRouteProviderProtocol.SERVICE_INTERFACE;
-
-    /*
-     * Private messages used internally.  (Yes, you can renumber these.)
-     */
-
-    static final int PRIVATE_MSG_CLIENT_DIED = 1;
-
-    /**
-     * Creates a media route provider service.
-     */
-    public MediaRouteProviderService() {
-        mReceiveHandler = new ReceiveHandler(this);
-        mReceiveMessenger = new Messenger(mReceiveHandler);
-        mPrivateHandler = new PrivateHandler();
-        mProviderCallback = new ProviderCallback();
-    }
-
-    /**
-     * Called by the system when it is time to create the media route provider.
-     *
-     * @return The media route provider offered by this service, or null if
-     * this service has decided not to offer a media route provider.
-     */
-    public abstract MediaRouteProvider onCreateMediaRouteProvider();
-
-    /**
-     * Gets the media route provider offered by this service.
-     *
-     * @return The media route provider offered by this service, or null if
-     * it has not yet been created.
-     *
-     * @see #onCreateMediaRouteProvider()
-     */
-    public MediaRouteProvider getMediaRouteProvider() {
-        return mProvider;
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        if (intent.getAction().equals(SERVICE_INTERFACE)) {
-            if (mProvider == null) {
-                MediaRouteProvider provider = onCreateMediaRouteProvider();
-                if (provider != null) {
-                    String providerPackage = provider.getMetadata().getPackageName();
-                    if (!providerPackage.equals(getPackageName())) {
-                        throw new IllegalStateException("onCreateMediaRouteProvider() returned "
-                                + "a provider whose package name does not match the package "
-                                + "name of the service.  A media route provider service can "
-                                + "only export its own media route providers.  "
-                                + "Provider package name: " + providerPackage
-                                + ".  Service package name: " + getPackageName() + ".");
-                    }
-                    mProvider = provider;
-                    mProvider.setCallback(mProviderCallback);
-                }
-            }
-            if (mProvider != null) {
-                return mReceiveMessenger.getBinder();
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public boolean onUnbind(Intent intent) {
-        if (mProvider != null) {
-            mProvider.setCallback(null);
-        }
-        return super.onUnbind(intent);
-    }
-
-    boolean onRegisterClient(Messenger messenger, int requestId, int version) {
-        if (version >= CLIENT_VERSION_1) {
-            int index = findClient(messenger);
-            if (index < 0) {
-                ClientRecord client = new ClientRecord(messenger, version);
-                if (client.register()) {
-                    mClients.add(client);
-                    if (DEBUG) {
-                        Log.d(TAG, client + ": Registered, version=" + version);
-                    }
-                    if (requestId != 0) {
-                        MediaRouteProviderDescriptor descriptor = mProvider.getDescriptor();
-                        sendReply(messenger, SERVICE_MSG_REGISTERED,
-                                requestId, SERVICE_VERSION_CURRENT,
-                                createDescriptorBundleForClientVersion(descriptor,
-                                        client.mVersion), null);
-                    }
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    boolean onUnregisterClient(Messenger messenger, int requestId) {
-        int index = findClient(messenger);
-        if (index >= 0) {
-            ClientRecord client = mClients.remove(index);
-            if (DEBUG) {
-                Log.d(TAG, client + ": Unregistered");
-            }
-            client.dispose();
-            sendGenericSuccess(messenger, requestId);
-            return true;
-        }
-        return false;
-    }
-
-    void onBinderDied(Messenger messenger) {
-        int index = findClient(messenger);
-        if (index >= 0) {
-            ClientRecord client = mClients.remove(index);
-            if (DEBUG) {
-                Log.d(TAG, client + ": Binder died");
-            }
-            client.dispose();
-        }
-    }
-
-    boolean onCreateRouteController(Messenger messenger, int requestId,
-            int controllerId, String routeId, String routeGroupId) {
-        ClientRecord client = getClient(messenger);
-        if (client != null) {
-            if (client.createRouteController(routeId, routeGroupId, controllerId)) {
-                if (DEBUG) {
-                    Log.d(TAG, client + ": Route controller created, controllerId=" + controllerId
-                            + ", routeId=" + routeId + ", routeGroupId=" + routeGroupId);
-                }
-                sendGenericSuccess(messenger, requestId);
-                return true;
-            }
-        }
-        return false;
-    }
-
-    boolean onReleaseRouteController(Messenger messenger, int requestId,
-            int controllerId) {
-        ClientRecord client = getClient(messenger);
-        if (client != null) {
-            if (client.releaseRouteController(controllerId)) {
-                if (DEBUG) {
-                    Log.d(TAG, client + ": Route controller released"
-                            + ", controllerId=" + controllerId);
-                }
-                sendGenericSuccess(messenger, requestId);
-                return true;
-            }
-        }
-        return false;
-    }
-
-    boolean onSelectRoute(Messenger messenger, int requestId,
-            int controllerId) {
-        ClientRecord client = getClient(messenger);
-        if (client != null) {
-            MediaRouteProvider.RouteController controller =
-                    client.getRouteController(controllerId);
-            if (controller != null) {
-                controller.onSelect();
-                if (DEBUG) {
-                    Log.d(TAG, client + ": Route selected"
-                            + ", controllerId=" + controllerId);
-                }
-                sendGenericSuccess(messenger, requestId);
-                return true;
-            }
-        }
-        return false;
-    }
-
-    boolean onUnselectRoute(Messenger messenger, int requestId,
-            int controllerId, int reason) {
-        ClientRecord client = getClient(messenger);
-        if (client != null) {
-            MediaRouteProvider.RouteController controller =
-                    client.getRouteController(controllerId);
-            if (controller != null) {
-                controller.onUnselect(reason);
-                if (DEBUG) {
-                    Log.d(TAG, client + ": Route unselected"
-                            + ", controllerId=" + controllerId);
-                }
-                sendGenericSuccess(messenger, requestId);
-                return true;
-            }
-        }
-        return false;
-    }
-
-    boolean onSetRouteVolume(Messenger messenger, int requestId,
-            int controllerId, int volume) {
-        ClientRecord client = getClient(messenger);
-        if (client != null) {
-            MediaRouteProvider.RouteController controller =
-                    client.getRouteController(controllerId);
-            if (controller != null) {
-                controller.onSetVolume(volume);
-                if (DEBUG) {
-                    Log.d(TAG, client + ": Route volume changed"
-                            + ", controllerId=" + controllerId + ", volume=" + volume);
-                }
-                sendGenericSuccess(messenger, requestId);
-                return true;
-            }
-        }
-        return false;
-    }
-
-    boolean onUpdateRouteVolume(Messenger messenger, int requestId,
-            int controllerId, int delta) {
-        ClientRecord client = getClient(messenger);
-        if (client != null) {
-            MediaRouteProvider.RouteController controller =
-                    client.getRouteController(controllerId);
-            if (controller != null) {
-                controller.onUpdateVolume(delta);
-                if (DEBUG) {
-                    Log.d(TAG, client + ": Route volume updated"
-                            + ", controllerId=" + controllerId + ", delta=" + delta);
-                }
-                sendGenericSuccess(messenger, requestId);
-                return true;
-            }
-        }
-        return false;
-    }
-
-    boolean onRouteControlRequest(final Messenger messenger, final int requestId,
-            final int controllerId, final Intent intent) {
-        final ClientRecord client = getClient(messenger);
-        if (client != null) {
-            MediaRouteProvider.RouteController controller =
-                    client.getRouteController(controllerId);
-            if (controller != null) {
-                MediaRouter.ControlRequestCallback callback = null;
-                if (requestId != 0) {
-                    callback = new MediaRouter.ControlRequestCallback() {
-                        @Override
-                        public void onResult(Bundle data) {
-                            if (DEBUG) {
-                                Log.d(TAG, client + ": Route control request succeeded"
-                                        + ", controllerId=" + controllerId
-                                        + ", intent=" + intent
-                                        + ", data=" + data);
-                            }
-                            if (findClient(messenger) >= 0) {
-                                sendReply(messenger, SERVICE_MSG_CONTROL_REQUEST_SUCCEEDED,
-                                        requestId, 0, data, null);
-                            }
-                        }
-
-                        @Override
-                        public void onError(String error, Bundle data) {
-                            if (DEBUG) {
-                                Log.d(TAG, client + ": Route control request failed"
-                                        + ", controllerId=" + controllerId
-                                        + ", intent=" + intent
-                                        + ", error=" + error + ", data=" + data);
-                            }
-                            if (findClient(messenger) >= 0) {
-                                if (error != null) {
-                                    Bundle bundle = new Bundle();
-                                    bundle.putString(SERVICE_DATA_ERROR, error);
-                                    sendReply(messenger, SERVICE_MSG_CONTROL_REQUEST_FAILED,
-                                            requestId, 0, data, bundle);
-                                } else {
-                                    sendReply(messenger, SERVICE_MSG_CONTROL_REQUEST_FAILED,
-                                            requestId, 0, data, null);
-                                }
-                            }
-                        }
-                    };
-                }
-                if (controller.onControlRequest(intent, callback)) {
-                    if (DEBUG) {
-                        Log.d(TAG, client + ": Route control request delivered"
-                                + ", controllerId=" + controllerId + ", intent=" + intent);
-                    }
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    boolean onSetDiscoveryRequest(Messenger messenger, int requestId,
-            MediaRouteDiscoveryRequest request) {
-        ClientRecord client = getClient(messenger);
-        if (client != null) {
-            boolean actuallyChanged = client.setDiscoveryRequest(request);
-            if (DEBUG) {
-                Log.d(TAG, client + ": Set discovery request, request=" + request
-                        + ", actuallyChanged=" + actuallyChanged
-                        + ", compositeDiscoveryRequest=" + mCompositeDiscoveryRequest);
-            }
-            sendGenericSuccess(messenger, requestId);
-            return true;
-        }
-        return false;
-    }
-
-    void sendDescriptorChanged(MediaRouteProviderDescriptor descriptor) {
-        final int count = mClients.size();
-        for (int i = 0; i < count; i++) {
-            ClientRecord client = mClients.get(i);
-            sendReply(client.mMessenger, SERVICE_MSG_DESCRIPTOR_CHANGED, 0, 0,
-                    createDescriptorBundleForClientVersion(descriptor, client.mVersion), null);
-            if (DEBUG) {
-                Log.d(TAG, client + ": Sent descriptor change event, descriptor=" + descriptor);
-            }
-        }
-    }
-
-    @VisibleForTesting
-    static Bundle createDescriptorBundleForClientVersion(MediaRouteProviderDescriptor descriptor,
-            int clientVersion) {
-        if (descriptor == null) {
-            return null;
-        }
-        MediaRouteProviderDescriptor.Builder builder =
-                new MediaRouteProviderDescriptor.Builder(descriptor);
-        builder.setRoutes(null);
-        for (MediaRouteDescriptor route : descriptor.getRoutes()) {
-            if (clientVersion >= route.getMinClientVersion()
-                    && clientVersion <= route.getMaxClientVersion()) {
-                builder.addRoute(route);
-            }
-        }
-        return builder.build().asBundle();
-    }
-
-    boolean updateCompositeDiscoveryRequest() {
-        MediaRouteDiscoveryRequest composite = null;
-        MediaRouteSelector.Builder selectorBuilder = null;
-        boolean activeScan = false;
-        final int count = mClients.size();
-        for (int i = 0; i < count; i++) {
-            MediaRouteDiscoveryRequest request = mClients.get(i).mDiscoveryRequest;
-            if (request != null
-                    && (!request.getSelector().isEmpty() || request.isActiveScan())) {
-                activeScan |= request.isActiveScan();
-                if (composite == null) {
-                    composite = request;
-                } else {
-                    if (selectorBuilder == null) {
-                        selectorBuilder = new MediaRouteSelector.Builder(composite.getSelector());
-                    }
-                    selectorBuilder.addSelector(request.getSelector());
-                }
-            }
-        }
-        if (selectorBuilder != null) {
-            composite = new MediaRouteDiscoveryRequest(selectorBuilder.build(), activeScan);
-        }
-        if (!ObjectsCompat.equals(mCompositeDiscoveryRequest, composite)) {
-            mCompositeDiscoveryRequest = composite;
-            mProvider.setDiscoveryRequest(composite);
-            return true;
-        }
-        return false;
-    }
-
-    private ClientRecord getClient(Messenger messenger) {
-        int index = findClient(messenger);
-        return index >= 0 ? mClients.get(index) : null;
-    }
-
-    int findClient(Messenger messenger) {
-        final int count = mClients.size();
-        for (int i = 0; i < count; i++) {
-            ClientRecord client = mClients.get(i);
-            if (client.hasMessenger(messenger)) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    static void sendGenericFailure(Messenger messenger, int requestId) {
-        if (requestId != 0) {
-            sendReply(messenger, SERVICE_MSG_GENERIC_FAILURE, requestId, 0, null, null);
-        }
-    }
-
-    private static void sendGenericSuccess(Messenger messenger, int requestId) {
-        if (requestId != 0) {
-            sendReply(messenger, SERVICE_MSG_GENERIC_SUCCESS, requestId, 0, null, null);
-        }
-    }
-
-    static void sendReply(Messenger messenger, int what,
-            int requestId, int arg, Object obj, Bundle data) {
-        Message msg = Message.obtain();
-        msg.what = what;
-        msg.arg1 = requestId;
-        msg.arg2 = arg;
-        msg.obj = obj;
-        msg.setData(data);
-        try {
-            messenger.send(msg);
-        } catch (DeadObjectException ex) {
-            // The client died.
-        } catch (RemoteException ex) {
-            Log.e(TAG, "Could not send message to " + getClientId(messenger), ex);
-        }
-    }
-
-    static String getClientId(Messenger messenger) {
-        return "Client connection " + messenger.getBinder().toString();
-    }
-
-    private final class PrivateHandler extends Handler {
-        PrivateHandler() {
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case PRIVATE_MSG_CLIENT_DIED:
-                    onBinderDied((Messenger)msg.obj);
-                    break;
-            }
-        }
-    }
-
-    private final class ProviderCallback extends MediaRouteProvider.Callback {
-        ProviderCallback() {
-        }
-
-        @Override
-        public void onDescriptorChanged(MediaRouteProvider provider,
-                MediaRouteProviderDescriptor descriptor) {
-            sendDescriptorChanged(descriptor);
-        }
-    }
-
-    private final class ClientRecord implements DeathRecipient {
-        public final Messenger mMessenger;
-        public final int mVersion;
-        public MediaRouteDiscoveryRequest mDiscoveryRequest;
-
-        private final SparseArray<MediaRouteProvider.RouteController> mControllers =
-                new SparseArray<MediaRouteProvider.RouteController>();
-
-        public ClientRecord(Messenger messenger, int version) {
-            mMessenger = messenger;
-            mVersion = version;
-        }
-
-        public boolean register() {
-            try {
-                mMessenger.getBinder().linkToDeath(this, 0);
-                return true;
-            } catch (RemoteException ex) {
-                binderDied();
-            }
-            return false;
-        }
-
-        public void dispose() {
-            int count = mControllers.size();
-            for (int i = 0; i < count; i++) {
-                mControllers.valueAt(i).onRelease();
-            }
-            mControllers.clear();
-
-            mMessenger.getBinder().unlinkToDeath(this, 0);
-
-            setDiscoveryRequest(null);
-        }
-
-        public boolean hasMessenger(Messenger other) {
-            return mMessenger.getBinder() == other.getBinder();
-        }
-
-        public boolean createRouteController(String routeId, String routeGroupId,
-                int controllerId) {
-            if (mControllers.indexOfKey(controllerId) < 0) {
-                MediaRouteProvider.RouteController controller = routeGroupId == null
-                        ? mProvider.onCreateRouteController(routeId)
-                        : mProvider.onCreateRouteController(routeId, routeGroupId);
-                if (controller != null) {
-                    mControllers.put(controllerId, controller);
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        public boolean releaseRouteController(int controllerId) {
-            MediaRouteProvider.RouteController controller = mControllers.get(controllerId);
-            if (controller != null) {
-                mControllers.remove(controllerId);
-                controller.onRelease();
-                return true;
-            }
-            return false;
-        }
-
-        public MediaRouteProvider.RouteController getRouteController(int controllerId) {
-            return mControllers.get(controllerId);
-        }
-
-        public boolean setDiscoveryRequest(MediaRouteDiscoveryRequest request) {
-            if (!ObjectsCompat.equals(mDiscoveryRequest, request)) {
-                mDiscoveryRequest = request;
-                return updateCompositeDiscoveryRequest();
-            }
-            return false;
-        }
-
-        // Runs on a binder thread.
-        @Override
-        public void binderDied() {
-            mPrivateHandler.obtainMessage(PRIVATE_MSG_CLIENT_DIED, mMessenger).sendToTarget();
-        }
-
-        @Override
-        public String toString() {
-            return getClientId(mMessenger);
-        }
-    }
-
-    /**
-     * Handler that receives messages from clients.
-     * <p>
-     * This inner class is static and only retains a weak reference to the service
-     * to prevent the service from being leaked in case one of the clients is holding an
-     * active reference to the server's messenger.
-     * </p><p>
-     * This handler should not be used to handle any messages other than those
-     * that come from the client.
-     * </p>
-     */
-    private static final class ReceiveHandler extends Handler {
-        private final WeakReference<MediaRouteProviderService> mServiceRef;
-
-        public ReceiveHandler(MediaRouteProviderService service) {
-            mServiceRef = new WeakReference<MediaRouteProviderService>(service);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            final Messenger messenger = msg.replyTo;
-            if (isValidRemoteMessenger(messenger)) {
-                final int what = msg.what;
-                final int requestId = msg.arg1;
-                final int arg = msg.arg2;
-                final Object obj = msg.obj;
-                final Bundle data = msg.peekData();
-                if (!processMessage(what, messenger, requestId, arg, obj, data)) {
-                    if (DEBUG) {
-                        Log.d(TAG, getClientId(messenger) + ": Message failed, what=" + what
-                                + ", requestId=" + requestId + ", arg=" + arg
-                                + ", obj=" + obj + ", data=" + data);
-                    }
-                    sendGenericFailure(messenger, requestId);
-                }
-            } else {
-                if (DEBUG) {
-                    Log.d(TAG, "Ignoring message without valid reply messenger.");
-                }
-            }
-        }
-
-        private boolean processMessage(int what,
-                Messenger messenger, int requestId, int arg, Object obj, Bundle data) {
-            MediaRouteProviderService service = mServiceRef.get();
-            if (service != null) {
-                switch (what) {
-                    case CLIENT_MSG_REGISTER:
-                        return service.onRegisterClient(messenger, requestId, arg);
-
-                    case CLIENT_MSG_UNREGISTER:
-                        return service.onUnregisterClient(messenger, requestId);
-
-                    case CLIENT_MSG_CREATE_ROUTE_CONTROLLER: {
-                        String routeId = data.getString(CLIENT_DATA_ROUTE_ID);
-                        String routeGroupId = data.getString(CLIENT_DATA_ROUTE_LIBRARY_GROUP);
-                        if (routeId != null) {
-                            return service.onCreateRouteController(
-                                    messenger, requestId, arg, routeId, routeGroupId);
-                        }
-                        break;
-                    }
-
-                    case CLIENT_MSG_RELEASE_ROUTE_CONTROLLER:
-                        return service.onReleaseRouteController(messenger, requestId, arg);
-
-                    case CLIENT_MSG_SELECT_ROUTE:
-                        return service.onSelectRoute(messenger, requestId, arg);
-
-                    case CLIENT_MSG_UNSELECT_ROUTE:
-                        int reason = data == null ?
-                                MediaRouter.UNSELECT_REASON_UNKNOWN
-                                : data.getInt(CLIENT_DATA_UNSELECT_REASON,
-                                        MediaRouter.UNSELECT_REASON_UNKNOWN);
-                        return service.onUnselectRoute(messenger, requestId, arg, reason);
-
-                    case CLIENT_MSG_SET_ROUTE_VOLUME: {
-                        int volume = data.getInt(CLIENT_DATA_VOLUME, -1);
-                        if (volume >= 0) {
-                            return service.onSetRouteVolume(
-                                    messenger, requestId, arg, volume);
-                        }
-                        break;
-                    }
-
-                    case CLIENT_MSG_UPDATE_ROUTE_VOLUME: {
-                        int delta = data.getInt(CLIENT_DATA_VOLUME, 0);
-                        if (delta != 0) {
-                            return service.onUpdateRouteVolume(
-                                    messenger, requestId, arg, delta);
-                        }
-                        break;
-                    }
-
-                    case CLIENT_MSG_ROUTE_CONTROL_REQUEST:
-                        if (obj instanceof Intent) {
-                            return service.onRouteControlRequest(
-                                    messenger, requestId, arg, (Intent)obj);
-                        }
-                        break;
-
-                    case CLIENT_MSG_SET_DISCOVERY_REQUEST: {
-                        if (obj == null || obj instanceof Bundle) {
-                            MediaRouteDiscoveryRequest request =
-                                    MediaRouteDiscoveryRequest.fromBundle((Bundle)obj);
-                            return service.onSetDiscoveryRequest(
-                                    messenger, requestId,
-                                    request != null && request.isValid() ? request : null);
-                        }
-                    }
-                }
-            }
-            return false;
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteSelector.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteSelector.java
deleted file mode 100644
index 5669b19..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteSelector.java
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.support.mediarouter.media;
-
-import android.content.IntentFilter;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Describes the capabilities of routes that applications would like to discover and use.
- * <p>
- * This object is immutable once created using a {@link Builder} instance.
- * </p>
- *
- * <h3>Example</h3>
- * <pre>
- * MediaRouteSelector selectorBuilder = new MediaRouteSelector.Builder()
- *         .addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO)
- *         .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
- *         .build();
- *
- * MediaRouter router = MediaRouter.getInstance(context);
- * router.addCallback(selector, callback, MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
- * </pre>
- */
-public final class MediaRouteSelector {
-    static final String KEY_CONTROL_CATEGORIES = "controlCategories";
-
-    private final Bundle mBundle;
-    List<String> mControlCategories;
-
-    /**
-     * An empty media route selector that will not match any routes.
-     */
-    public static final MediaRouteSelector EMPTY = new MediaRouteSelector(new Bundle(), null);
-
-    MediaRouteSelector(Bundle bundle, List<String> controlCategories) {
-        mBundle = bundle;
-        mControlCategories = controlCategories;
-    }
-
-    /**
-     * Gets the list of {@link MediaControlIntent media control categories} in the selector.
-     *
-     * @return The list of categories.
-     */
-    public List<String> getControlCategories() {
-        ensureControlCategories();
-        return mControlCategories;
-    }
-
-    void ensureControlCategories() {
-        if (mControlCategories == null) {
-            mControlCategories = mBundle.getStringArrayList(KEY_CONTROL_CATEGORIES);
-            if (mControlCategories == null || mControlCategories.isEmpty()) {
-                mControlCategories = Collections.<String>emptyList();
-            }
-        }
-    }
-
-    /**
-     * Returns true if the selector contains the specified category.
-     *
-     * @param category The category to check.
-     * @return True if the category is present.
-     */
-    public boolean hasControlCategory(String category) {
-        if (category != null) {
-            ensureControlCategories();
-            final int categoryCount = mControlCategories.size();
-            for (int i = 0; i < categoryCount; i++) {
-                if (mControlCategories.get(i).equals(category)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns true if the selector matches at least one of the specified control filters.
-     *
-     * @param filters The list of control filters to consider.
-     * @return True if a match is found.
-     */
-    public boolean matchesControlFilters(List<IntentFilter> filters) {
-        if (filters != null) {
-            ensureControlCategories();
-            final int categoryCount = mControlCategories.size();
-            if (categoryCount != 0) {
-                final int filterCount = filters.size();
-                for (int i = 0; i < filterCount; i++) {
-                    final IntentFilter filter = filters.get(i);
-                    if (filter != null) {
-                        for (int j = 0; j < categoryCount; j++) {
-                            if (filter.hasCategory(mControlCategories.get(j))) {
-                                return true;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns true if this selector contains all of the capabilities described
-     * by the specified selector.
-     *
-     * @param selector The selector to be examined.
-     * @return True if this selector contains all of the capabilities described
-     * by the specified selector.
-     */
-    public boolean contains(MediaRouteSelector selector) {
-        if (selector != null) {
-            ensureControlCategories();
-            selector.ensureControlCategories();
-            return mControlCategories.containsAll(selector.mControlCategories);
-        }
-        return false;
-    }
-
-    /**
-     * Returns true if the selector does not specify any capabilities.
-     */
-    public boolean isEmpty() {
-        ensureControlCategories();
-        return mControlCategories.isEmpty();
-    }
-
-    /**
-     * Returns true if the selector has all of the required fields.
-     */
-    public boolean isValid() {
-        ensureControlCategories();
-        if (mControlCategories.contains(null)) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (o instanceof MediaRouteSelector) {
-            MediaRouteSelector other = (MediaRouteSelector)o;
-            ensureControlCategories();
-            other.ensureControlCategories();
-            return mControlCategories.equals(other.mControlCategories);
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        ensureControlCategories();
-        return mControlCategories.hashCode();
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder result = new StringBuilder();
-        result.append("MediaRouteSelector{ ");
-        result.append("controlCategories=").append(
-                Arrays.toString(getControlCategories().toArray()));
-        result.append(" }");
-        return result.toString();
-    }
-
-    /**
-     * Converts this object to a bundle for serialization.
-     *
-     * @return The contents of the object represented as a bundle.
-     */
-    public Bundle asBundle() {
-        return mBundle;
-    }
-
-    /**
-     * Creates an instance from a bundle.
-     *
-     * @param bundle The bundle, or null if none.
-     * @return The new instance, or null if the bundle was null.
-     */
-    public static MediaRouteSelector fromBundle(@Nullable Bundle bundle) {
-        return bundle != null ? new MediaRouteSelector(bundle, null) : null;
-    }
-
-    /**
-     * Builder for {@link MediaRouteSelector media route selectors}.
-     */
-    public static final class Builder {
-        private ArrayList<String> mControlCategories;
-
-        /**
-         * Creates an empty media route selector builder.
-         */
-        public Builder() {
-        }
-
-        /**
-         * Creates a media route selector descriptor builder whose initial contents are
-         * copied from an existing selector.
-         */
-        public Builder(@NonNull MediaRouteSelector selector) {
-            if (selector == null) {
-                throw new IllegalArgumentException("selector must not be null");
-            }
-
-            selector.ensureControlCategories();
-            if (!selector.mControlCategories.isEmpty()) {
-                mControlCategories = new ArrayList<String>(selector.mControlCategories);
-            }
-        }
-
-        /**
-         * Adds a {@link MediaControlIntent media control category} to the builder.
-         *
-         * @param category The category to add to the set of desired capabilities, such as
-         * {@link MediaControlIntent#CATEGORY_LIVE_AUDIO}.
-         * @return The builder instance for chaining.
-         */
-        @NonNull
-        public Builder addControlCategory(@NonNull String category) {
-            if (category == null) {
-                throw new IllegalArgumentException("category must not be null");
-            }
-
-            if (mControlCategories == null) {
-                mControlCategories = new ArrayList<String>();
-            }
-            if (!mControlCategories.contains(category)) {
-                mControlCategories.add(category);
-            }
-            return this;
-        }
-
-        /**
-         * Adds a list of {@link MediaControlIntent media control categories} to the builder.
-         *
-         * @param categories The list categories to add to the set of desired capabilities,
-         * such as {@link MediaControlIntent#CATEGORY_LIVE_AUDIO}.
-         * @return The builder instance for chaining.
-         */
-        @NonNull
-        public Builder addControlCategories(@NonNull Collection<String> categories) {
-            if (categories == null) {
-                throw new IllegalArgumentException("categories must not be null");
-            }
-
-            if (!categories.isEmpty()) {
-                for (String category : categories) {
-                    addControlCategory(category);
-                }
-            }
-            return this;
-        }
-
-        /**
-         * Adds the contents of an existing media route selector to the builder.
-         *
-         * @param selector The media route selector whose contents are to be added.
-         * @return The builder instance for chaining.
-         */
-        @NonNull
-        public Builder addSelector(@NonNull MediaRouteSelector selector) {
-            if (selector == null) {
-                throw new IllegalArgumentException("selector must not be null");
-            }
-
-            addControlCategories(selector.getControlCategories());
-            return this;
-        }
-
-        /**
-         * Builds the {@link MediaRouteSelector media route selector}.
-         */
-        @NonNull
-        public MediaRouteSelector build() {
-            if (mControlCategories == null) {
-                return EMPTY;
-            }
-            Bundle bundle = new Bundle();
-            bundle.putStringArrayList(KEY_CONTROL_CATEGORIES, mControlCategories);
-            return new MediaRouteSelector(bundle, mControlCategories);
-        }
-    }
-}
\ No newline at end of file
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouter.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouter.java
deleted file mode 100644
index db0052e..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouter.java
+++ /dev/null
@@ -1,2999 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.media;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.ActivityManager;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.IntentSender;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.support.v4.app.ActivityManagerCompat;
-import android.support.v4.hardware.display.DisplayManagerCompat;
-import android.support.v4.media.VolumeProviderCompat;
-import android.support.v4.media.session.MediaSessionCompat;
-import android.support.v4.util.Pair;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.Display;
-
-import com.android.support.mediarouter.media.MediaRouteProvider.ProviderMetadata;
-import com.android.support.mediarouter.media.MediaRouteProvider.RouteController;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * MediaRouter allows applications to control the routing of media channels
- * and streams from the current device to external speakers and destination devices.
- * <p>
- * A MediaRouter instance is retrieved through {@link #getInstance}.  Applications
- * can query the media router about the currently selected route and its capabilities
- * to determine how to send content to the route's destination.  Applications can
- * also {@link RouteInfo#sendControlRequest send control requests} to the route
- * to ask the route's destination to perform certain remote control functions
- * such as playing media.
- * </p><p>
- * See also {@link MediaRouteProvider} for information on how an application
- * can publish new media routes to the media router.
- * </p><p>
- * The media router API is not thread-safe; all interactions with it must be
- * done from the main thread of the process.
- * </p>
- */
-public final class MediaRouter {
-    static final String TAG = "MediaRouter";
-    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    /**
-     * Passed to {@link android.support.v7.media.MediaRouteProvider.RouteController#onUnselect(int)}
-     * and {@link Callback#onRouteUnselected(MediaRouter, RouteInfo, int)} when the reason the route
-     * was unselected is unknown.
-     */
-    public static final int UNSELECT_REASON_UNKNOWN = 0;
-    /**
-     * Passed to {@link android.support.v7.media.MediaRouteProvider.RouteController#onUnselect(int)}
-     * and {@link Callback#onRouteUnselected(MediaRouter, RouteInfo, int)} when the user pressed
-     * the disconnect button to disconnect and keep playing.
-     * <p>
-     *
-     * @see MediaRouteDescriptor#canDisconnectAndKeepPlaying()
-     */
-    public static final int UNSELECT_REASON_DISCONNECTED = 1;
-    /**
-     * Passed to {@link android.support.v7.media.MediaRouteProvider.RouteController#onUnselect(int)}
-     * and {@link Callback#onRouteUnselected(MediaRouter, RouteInfo, int)} when the user pressed
-     * the stop casting button.
-     */
-    public static final int UNSELECT_REASON_STOPPED = 2;
-    /**
-     * Passed to {@link android.support.v7.media.MediaRouteProvider.RouteController#onUnselect(int)}
-     * and {@link Callback#onRouteUnselected(MediaRouter, RouteInfo, int)} when the user selected
-     * a different route.
-     */
-    public static final int UNSELECT_REASON_ROUTE_CHANGED = 3;
-
-    // Maintains global media router state for the process.
-    // This field is initialized in MediaRouter.getInstance() before any
-    // MediaRouter objects are instantiated so it is guaranteed to be
-    // valid whenever any instance method is invoked.
-    static GlobalMediaRouter sGlobal;
-
-    // Context-bound state of the media router.
-    final Context mContext;
-    final ArrayList<CallbackRecord> mCallbackRecords = new ArrayList<CallbackRecord>();
-
-    @IntDef(flag = true,
-            value = {
-                    CALLBACK_FLAG_PERFORM_ACTIVE_SCAN,
-                    CALLBACK_FLAG_REQUEST_DISCOVERY,
-                    CALLBACK_FLAG_UNFILTERED_EVENTS
-            }
-    )
-    @Retention(RetentionPolicy.SOURCE)
-    private @interface CallbackFlags {}
-
-    /**
-     * Flag for {@link #addCallback}: Actively scan for routes while this callback
-     * is registered.
-     * <p>
-     * When this flag is specified, the media router will actively scan for new
-     * routes.  Certain routes, such as wifi display routes, may not be discoverable
-     * except when actively scanning.  This flag is typically used when the route picker
-     * dialog has been opened by the user to ensure that the route information is
-     * up to date.
-     * </p><p>
-     * Active scanning may consume a significant amount of power and may have intrusive
-     * effects on wireless connectivity.  Therefore it is important that active scanning
-     * only be requested when it is actually needed to satisfy a user request to
-     * discover and select a new route.
-     * </p><p>
-     * This flag implies {@link #CALLBACK_FLAG_REQUEST_DISCOVERY} but performing
-     * active scans is much more expensive than a normal discovery request.
-     * </p>
-     *
-     * @see #CALLBACK_FLAG_REQUEST_DISCOVERY
-     */
-    public static final int CALLBACK_FLAG_PERFORM_ACTIVE_SCAN = 1 << 0;
-
-    /**
-     * Flag for {@link #addCallback}: Do not filter route events.
-     * <p>
-     * When this flag is specified, the callback will be invoked for events that affect any
-     * route even if they do not match the callback's filter.
-     * </p>
-     */
-    public static final int CALLBACK_FLAG_UNFILTERED_EVENTS = 1 << 1;
-
-    /**
-     * Flag for {@link #addCallback}: Request passive route discovery while this
-     * callback is registered, except on {@link ActivityManager#isLowRamDevice low-RAM devices}.
-     * <p>
-     * When this flag is specified, the media router will try to discover routes.
-     * Although route discovery is intended to be efficient, checking for new routes may
-     * result in some network activity and could slowly drain the battery.  Therefore
-     * applications should only specify {@link #CALLBACK_FLAG_REQUEST_DISCOVERY} when
-     * they are running in the foreground and would like to provide the user with the
-     * option of connecting to new routes.
-     * </p><p>
-     * Applications should typically add a callback using this flag in the
-     * {@link android.app.Activity activity's} {@link android.app.Activity#onStart onStart}
-     * method and remove it in the {@link android.app.Activity#onStop onStop} method.
-     * The {@link android.support.v7.app.MediaRouteDiscoveryFragment} fragment may
-     * also be used for this purpose.
-     * </p><p class="note">
-     * On {@link ActivityManager#isLowRamDevice low-RAM devices} this flag
-     * will be ignored.  Refer to
-     * {@link #addCallback(MediaRouteSelector, Callback, int) addCallback} for details.
-     * </p>
-     *
-     * @see android.support.v7.app.MediaRouteDiscoveryFragment
-     */
-    public static final int CALLBACK_FLAG_REQUEST_DISCOVERY = 1 << 2;
-
-    /**
-     * Flag for {@link #addCallback}: Request passive route discovery while this
-     * callback is registered, even on {@link ActivityManager#isLowRamDevice low-RAM devices}.
-     * <p class="note">
-     * This flag has a significant performance impact on low-RAM devices
-     * since it may cause many media route providers to be started simultaneously.
-     * It is much better to use {@link #CALLBACK_FLAG_REQUEST_DISCOVERY} instead to avoid
-     * performing passive discovery on these devices altogether.  Refer to
-     * {@link #addCallback(MediaRouteSelector, Callback, int) addCallback} for details.
-     * </p>
-     *
-     * @see android.support.v7.app.MediaRouteDiscoveryFragment
-     */
-    public static final int CALLBACK_FLAG_FORCE_DISCOVERY = 1 << 3;
-
-    /**
-     * Flag for {@link #isRouteAvailable}: Ignore the default route.
-     * <p>
-     * This flag is used to determine whether a matching non-default route is available.
-     * This constraint may be used to decide whether to offer the route chooser dialog
-     * to the user.  There is no point offering the chooser if there are no
-     * non-default choices.
-     * </p>
-     */
-    public static final int AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE = 1 << 0;
-
-    /**
-     * Flag for {@link #isRouteAvailable}: Require an actual route to be matched.
-     * <p>
-     * If this flag is not set, then {@link #isRouteAvailable} will return true
-     * if it is possible to discover a matching route even if discovery is not in
-     * progress or if no matching route has yet been found.  This feature is used to
-     * save resources by removing the need to perform passive route discovery on
-     * {@link ActivityManager#isLowRamDevice low-RAM devices}.
-     * </p><p>
-     * If this flag is set, then {@link #isRouteAvailable} will only return true if
-     * a matching route has actually been discovered.
-     * </p>
-     */
-    public static final int AVAILABILITY_FLAG_REQUIRE_MATCH = 1 << 1;
-
-    private MediaRouter(Context context) {
-        mContext = context;
-    }
-
-    /**
-     * Gets an instance of the media router service associated with the context.
-     * <p>
-     * The application is responsible for holding a strong reference to the returned
-     * {@link MediaRouter} instance, such as by storing the instance in a field of
-     * the {@link android.app.Activity}, to ensure that the media router remains alive
-     * as long as the application is using its features.
-     * </p><p>
-     * In other words, the support library only holds a {@link WeakReference weak reference}
-     * to each media router instance.  When there are no remaining strong references to the
-     * media router instance, all of its callbacks will be removed and route discovery
-     * will no longer be performed on its behalf.
-     * </p>
-     *
-     * @return The media router instance for the context.  The application must hold
-     * a strong reference to this object as long as it is in use.
-     */
-    public static MediaRouter getInstance(@NonNull Context context) {
-        if (context == null) {
-            throw new IllegalArgumentException("context must not be null");
-        }
-        checkCallingThread();
-
-        if (sGlobal == null) {
-            sGlobal = new GlobalMediaRouter(context.getApplicationContext());
-            sGlobal.start();
-        }
-        return sGlobal.getRouter(context);
-    }
-
-    /**
-     * Gets information about the {@link MediaRouter.RouteInfo routes} currently known to
-     * this media router.
-     */
-    public List<RouteInfo> getRoutes() {
-        checkCallingThread();
-        return sGlobal.getRoutes();
-    }
-
-    /**
-     * Gets information about the {@link MediaRouter.ProviderInfo route providers}
-     * currently known to this media router.
-     */
-    public List<ProviderInfo> getProviders() {
-        checkCallingThread();
-        return sGlobal.getProviders();
-    }
-
-    /**
-     * Gets the default route for playing media content on the system.
-     * <p>
-     * The system always provides a default route.
-     * </p>
-     *
-     * @return The default route, which is guaranteed to never be null.
-     */
-    @NonNull
-    public RouteInfo getDefaultRoute() {
-        checkCallingThread();
-        return sGlobal.getDefaultRoute();
-    }
-
-    /**
-     * Gets a bluetooth route for playing media content on the system.
-     *
-     * @return A bluetooth route, if exist, otherwise null.
-     */
-    public RouteInfo getBluetoothRoute() {
-        checkCallingThread();
-        return sGlobal.getBluetoothRoute();
-    }
-
-    /**
-     * Gets the currently selected route.
-     * <p>
-     * The application should examine the route's
-     * {@link RouteInfo#getControlFilters media control intent filters} to assess the
-     * capabilities of the route before attempting to use it.
-     * </p>
-     *
-     * <h3>Example</h3>
-     * <pre>
-     * public boolean playMovie() {
-     *     MediaRouter mediaRouter = MediaRouter.getInstance(context);
-     *     MediaRouter.RouteInfo route = mediaRouter.getSelectedRoute();
-     *
-     *     // First try using the remote playback interface, if supported.
-     *     if (route.supportsControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) {
-     *         // The route supports remote playback.
-     *         // Try to send it the Uri of the movie to play.
-     *         Intent intent = new Intent(MediaControlIntent.ACTION_PLAY);
-     *         intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
-     *         intent.setDataAndType("http://example.com/videos/movie.mp4", "video/mp4");
-     *         if (route.supportsControlRequest(intent)) {
-     *             route.sendControlRequest(intent, null);
-     *             return true; // sent the request to play the movie
-     *         }
-     *     }
-     *
-     *     // If remote playback was not possible, then play locally.
-     *     if (route.supportsControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO)) {
-     *         // The route supports live video streaming.
-     *         // Prepare to play content locally in a window or in a presentation.
-     *         return playMovieInWindow();
-     *     }
-     *
-     *     // Neither interface is supported, so we can't play the movie to this route.
-     *     return false;
-     * }
-     * </pre>
-     *
-     * @return The selected route, which is guaranteed to never be null.
-     *
-     * @see RouteInfo#getControlFilters
-     * @see RouteInfo#supportsControlCategory
-     * @see RouteInfo#supportsControlRequest
-     */
-    @NonNull
-    public RouteInfo getSelectedRoute() {
-        checkCallingThread();
-        return sGlobal.getSelectedRoute();
-    }
-
-    /**
-     * Returns the selected route if it matches the specified selector, otherwise
-     * selects the default route and returns it. If there is one live audio route
-     * (usually Bluetooth A2DP), it will be selected instead of default route.
-     *
-     * @param selector The selector to match.
-     * @return The previously selected route if it matched the selector, otherwise the
-     * newly selected default route which is guaranteed to never be null.
-     *
-     * @see MediaRouteSelector
-     * @see RouteInfo#matchesSelector
-     */
-    @NonNull
-    public RouteInfo updateSelectedRoute(@NonNull MediaRouteSelector selector) {
-        if (selector == null) {
-            throw new IllegalArgumentException("selector must not be null");
-        }
-        checkCallingThread();
-
-        if (DEBUG) {
-            Log.d(TAG, "updateSelectedRoute: " + selector);
-        }
-        RouteInfo route = sGlobal.getSelectedRoute();
-        if (!route.isDefaultOrBluetooth() && !route.matchesSelector(selector)) {
-            route = sGlobal.chooseFallbackRoute();
-            sGlobal.selectRoute(route);
-        }
-        return route;
-    }
-
-    /**
-     * Selects the specified route.
-     *
-     * @param route The route to select.
-     */
-    public void selectRoute(@NonNull RouteInfo route) {
-        if (route == null) {
-            throw new IllegalArgumentException("route must not be null");
-        }
-        checkCallingThread();
-
-        if (DEBUG) {
-            Log.d(TAG, "selectRoute: " + route);
-        }
-        sGlobal.selectRoute(route);
-    }
-
-    /**
-     * Unselects the current round and selects the default route instead.
-     * <p>
-     * The reason given must be one of:
-     * <ul>
-     * <li>{@link MediaRouter#UNSELECT_REASON_UNKNOWN}</li>
-     * <li>{@link MediaRouter#UNSELECT_REASON_DISCONNECTED}</li>
-     * <li>{@link MediaRouter#UNSELECT_REASON_STOPPED}</li>
-     * <li>{@link MediaRouter#UNSELECT_REASON_ROUTE_CHANGED}</li>
-     * </ul>
-     *
-     * @param reason The reason for disconnecting the current route.
-     */
-    public void unselect(int reason) {
-        if (reason < MediaRouter.UNSELECT_REASON_UNKNOWN ||
-                reason > MediaRouter.UNSELECT_REASON_ROUTE_CHANGED) {
-            throw new IllegalArgumentException("Unsupported reason to unselect route");
-        }
-        checkCallingThread();
-
-        // Choose the fallback route if it's not already selected.
-        // Otherwise, select the default route.
-        RouteInfo fallbackRoute = sGlobal.chooseFallbackRoute();
-        if (sGlobal.getSelectedRoute() != fallbackRoute) {
-            sGlobal.selectRoute(fallbackRoute, reason);
-        } else {
-            sGlobal.selectRoute(sGlobal.getDefaultRoute(), reason);
-        }
-    }
-
-    /**
-     * Returns true if there is a route that matches the specified selector.
-     * <p>
-     * This method returns true if there are any available routes that match the
-     * selector regardless of whether they are enabled or disabled. If the
-     * {@link #AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE} flag is specified, then
-     * the method will only consider non-default routes.
-     * </p>
-     * <p class="note">
-     * On {@link ActivityManager#isLowRamDevice low-RAM devices} this method
-     * will return true if it is possible to discover a matching route even if
-     * discovery is not in progress or if no matching route has yet been found.
-     * Use {@link #AVAILABILITY_FLAG_REQUIRE_MATCH} to require an actual match.
-     * </p>
-     *
-     * @param selector The selector to match.
-     * @param flags Flags to control the determination of whether a route may be
-     *            available. May be zero or some combination of
-     *            {@link #AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE} and
-     *            {@link #AVAILABILITY_FLAG_REQUIRE_MATCH}.
-     * @return True if a matching route may be available.
-     */
-    public boolean isRouteAvailable(@NonNull MediaRouteSelector selector, int flags) {
-        if (selector == null) {
-            throw new IllegalArgumentException("selector must not be null");
-        }
-        checkCallingThread();
-
-        return sGlobal.isRouteAvailable(selector, flags);
-    }
-
-    /**
-     * Registers a callback to discover routes that match the selector and to receive
-     * events when they change.
-     * <p>
-     * This is a convenience method that has the same effect as calling
-     * {@link #addCallback(MediaRouteSelector, Callback, int)} without flags.
-     * </p>
-     *
-     * @param selector A route selector that indicates the kinds of routes that the
-     * callback would like to discover.
-     * @param callback The callback to add.
-     * @see #removeCallback
-     */
-    public void addCallback(MediaRouteSelector selector, Callback callback) {
-        addCallback(selector, callback, 0);
-    }
-
-    /**
-     * Registers a callback to discover routes that match the selector and to receive
-     * events when they change.
-     * <p>
-     * The selector describes the kinds of routes that the application wants to
-     * discover.  For example, if the application wants to use
-     * live audio routes then it should include the
-     * {@link MediaControlIntent#CATEGORY_LIVE_AUDIO live audio media control intent category}
-     * in its selector when it adds a callback to the media router.
-     * The selector may include any number of categories.
-     * </p><p>
-     * If the callback has already been registered, then the selector is added to
-     * the set of selectors being monitored by the callback.
-     * </p><p>
-     * By default, the callback will only be invoked for events that affect routes
-     * that match the specified selector.  Event filtering may be disabled by specifying
-     * the {@link #CALLBACK_FLAG_UNFILTERED_EVENTS} flag when the callback is registered.
-     * </p><p>
-     * Applications should use the {@link #isRouteAvailable} method to determine
-     * whether is it possible to discover a route with the desired capabilities
-     * and therefore whether the media route button should be shown to the user.
-     * </p><p>
-     * The {@link #CALLBACK_FLAG_REQUEST_DISCOVERY} flag should be used while the application
-     * is in the foreground to request that passive discovery be performed if there are
-     * sufficient resources to allow continuous passive discovery.
-     * On {@link ActivityManager#isLowRamDevice low-RAM devices} this flag will be
-     * ignored to conserve resources.
-     * </p><p>
-     * The {@link #CALLBACK_FLAG_FORCE_DISCOVERY} flag should be used when
-     * passive discovery absolutely must be performed, even on low-RAM devices.
-     * This flag has a significant performance impact on low-RAM devices
-     * since it may cause many media route providers to be started simultaneously.
-     * It is much better to use {@link #CALLBACK_FLAG_REQUEST_DISCOVERY} instead to avoid
-     * performing passive discovery on these devices altogether.
-     * </p><p>
-     * The {@link #CALLBACK_FLAG_PERFORM_ACTIVE_SCAN} flag should be used when the
-     * media route chooser dialog is showing to confirm the presence of available
-     * routes that the user may connect to.  This flag may use substantially more
-     * power.
-     * </p>
-     *
-     * <h3>Example</h3>
-     * <pre>
-     * public class MyActivity extends Activity {
-     *     private MediaRouter mRouter;
-     *     private MediaRouter.Callback mCallback;
-     *     private MediaRouteSelector mSelector;
-     *
-     *     protected void onCreate(Bundle savedInstanceState) {
-     *         super.onCreate(savedInstanceState);
-     *
-     *         mRouter = Mediarouter.getInstance(this);
-     *         mCallback = new MyCallback();
-     *         mSelector = new MediaRouteSelector.Builder()
-     *                 .addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO)
-     *                 .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
-     *                 .build();
-     *     }
-     *
-     *     // Add the callback on start to tell the media router what kinds of routes
-     *     // the application is interested in so that it can try to discover suitable ones.
-     *     public void onStart() {
-     *         super.onStart();
-     *
-     *         mediaRouter.addCallback(mSelector, mCallback,
-     *                 MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
-     *
-     *         MediaRouter.RouteInfo route = mediaRouter.updateSelectedRoute(mSelector);
-     *         // do something with the route...
-     *     }
-     *
-     *     // Remove the selector on stop to tell the media router that it no longer
-     *     // needs to invest effort trying to discover routes of these kinds for now.
-     *     public void onStop() {
-     *         super.onStop();
-     *
-     *         mediaRouter.removeCallback(mCallback);
-     *     }
-     *
-     *     private final class MyCallback extends MediaRouter.Callback {
-     *         // Implement callback methods as needed.
-     *     }
-     * }
-     * </pre>
-     *
-     * @param selector A route selector that indicates the kinds of routes that the
-     * callback would like to discover.
-     * @param callback The callback to add.
-     * @param flags Flags to control the behavior of the callback.
-     * May be zero or a combination of {@link #CALLBACK_FLAG_PERFORM_ACTIVE_SCAN} and
-     * {@link #CALLBACK_FLAG_UNFILTERED_EVENTS}.
-     * @see #removeCallback
-     */
-    public void addCallback(@NonNull MediaRouteSelector selector, @NonNull Callback callback,
-            @CallbackFlags int flags) {
-        if (selector == null) {
-            throw new IllegalArgumentException("selector must not be null");
-        }
-        if (callback == null) {
-            throw new IllegalArgumentException("callback must not be null");
-        }
-        checkCallingThread();
-
-        if (DEBUG) {
-            Log.d(TAG, "addCallback: selector=" + selector
-                    + ", callback=" + callback + ", flags=" + Integer.toHexString(flags));
-        }
-
-        CallbackRecord record;
-        int index = findCallbackRecord(callback);
-        if (index < 0) {
-            record = new CallbackRecord(this, callback);
-            mCallbackRecords.add(record);
-        } else {
-            record = mCallbackRecords.get(index);
-        }
-        boolean updateNeeded = false;
-        if ((flags & ~record.mFlags) != 0) {
-            record.mFlags |= flags;
-            updateNeeded = true;
-        }
-        if (!record.mSelector.contains(selector)) {
-            record.mSelector = new MediaRouteSelector.Builder(record.mSelector)
-                    .addSelector(selector)
-                    .build();
-            updateNeeded = true;
-        }
-        if (updateNeeded) {
-            sGlobal.updateDiscoveryRequest();
-        }
-    }
-
-    /**
-     * Removes the specified callback.  It will no longer receive events about
-     * changes to media routes.
-     *
-     * @param callback The callback to remove.
-     * @see #addCallback
-     */
-    public void removeCallback(@NonNull Callback callback) {
-        if (callback == null) {
-            throw new IllegalArgumentException("callback must not be null");
-        }
-        checkCallingThread();
-
-        if (DEBUG) {
-            Log.d(TAG, "removeCallback: callback=" + callback);
-        }
-
-        int index = findCallbackRecord(callback);
-        if (index >= 0) {
-            mCallbackRecords.remove(index);
-            sGlobal.updateDiscoveryRequest();
-        }
-    }
-
-    private int findCallbackRecord(Callback callback) {
-        final int count = mCallbackRecords.size();
-        for (int i = 0; i < count; i++) {
-            if (mCallbackRecords.get(i).mCallback == callback) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    /**
-     * Registers a media route provider within this application process.
-     * <p>
-     * The provider will be added to the list of providers that all {@link MediaRouter}
-     * instances within this process can use to discover routes.
-     * </p>
-     *
-     * @param providerInstance The media route provider instance to add.
-     *
-     * @see MediaRouteProvider
-     * @see #removeCallback
-     */
-    public void addProvider(@NonNull MediaRouteProvider providerInstance) {
-        if (providerInstance == null) {
-            throw new IllegalArgumentException("providerInstance must not be null");
-        }
-        checkCallingThread();
-
-        if (DEBUG) {
-            Log.d(TAG, "addProvider: " + providerInstance);
-        }
-        sGlobal.addProvider(providerInstance);
-    }
-
-    /**
-     * Unregisters a media route provider within this application process.
-     * <p>
-     * The provider will be removed from the list of providers that all {@link MediaRouter}
-     * instances within this process can use to discover routes.
-     * </p>
-     *
-     * @param providerInstance The media route provider instance to remove.
-     *
-     * @see MediaRouteProvider
-     * @see #addCallback
-     */
-    public void removeProvider(@NonNull MediaRouteProvider providerInstance) {
-        if (providerInstance == null) {
-            throw new IllegalArgumentException("providerInstance must not be null");
-        }
-        checkCallingThread();
-
-        if (DEBUG) {
-            Log.d(TAG, "removeProvider: " + providerInstance);
-        }
-        sGlobal.removeProvider(providerInstance);
-    }
-
-    /**
-     * Adds a remote control client to enable remote control of the volume
-     * of the selected route.
-     * <p>
-     * The remote control client must have previously been registered with
-     * the audio manager using the {@link android.media.AudioManager#registerRemoteControlClient
-     * AudioManager.registerRemoteControlClient} method.
-     * </p>
-     *
-     * @param remoteControlClient The {@link android.media.RemoteControlClient} to register.
-     */
-    public void addRemoteControlClient(@NonNull Object remoteControlClient) {
-        if (remoteControlClient == null) {
-            throw new IllegalArgumentException("remoteControlClient must not be null");
-        }
-        checkCallingThread();
-
-        if (DEBUG) {
-            Log.d(TAG, "addRemoteControlClient: " + remoteControlClient);
-        }
-        sGlobal.addRemoteControlClient(remoteControlClient);
-    }
-
-    /**
-     * Removes a remote control client.
-     *
-     * @param remoteControlClient The {@link android.media.RemoteControlClient}
-     *            to unregister.
-     */
-    public void removeRemoteControlClient(@NonNull Object remoteControlClient) {
-        if (remoteControlClient == null) {
-            throw new IllegalArgumentException("remoteControlClient must not be null");
-        }
-
-        if (DEBUG) {
-            Log.d(TAG, "removeRemoteControlClient: " + remoteControlClient);
-        }
-        sGlobal.removeRemoteControlClient(remoteControlClient);
-    }
-
-    /**
-     * Sets the media session to enable remote control of the volume of the
-     * selected route. This should be used instead of
-     * {@link #addRemoteControlClient} when using media sessions. Set the
-     * session to null to clear it.
-     *
-     * @param mediaSession The {@link android.media.session.MediaSession} to
-     *            use.
-     */
-    public void setMediaSession(Object mediaSession) {
-        if (DEBUG) {
-            Log.d(TAG, "addMediaSession: " + mediaSession);
-        }
-        sGlobal.setMediaSession(mediaSession);
-    }
-
-    /**
-     * Sets a compat media session to enable remote control of the volume of the
-     * selected route. This should be used instead of
-     * {@link #addRemoteControlClient} when using {@link MediaSessionCompat}.
-     * Set the session to null to clear it.
-     *
-     * @param mediaSession
-     */
-    public void setMediaSessionCompat(MediaSessionCompat mediaSession) {
-        if (DEBUG) {
-            Log.d(TAG, "addMediaSessionCompat: " + mediaSession);
-        }
-        sGlobal.setMediaSessionCompat(mediaSession);
-    }
-
-    public MediaSessionCompat.Token getMediaSessionToken() {
-        return sGlobal.getMediaSessionToken();
-    }
-
-    /**
-     * Ensures that calls into the media router are on the correct thread.
-     * It pays to be a little paranoid when global state invariants are at risk.
-     */
-    static void checkCallingThread() {
-        if (Looper.myLooper() != Looper.getMainLooper()) {
-            throw new IllegalStateException("The media router service must only be "
-                    + "accessed on the application's main thread.");
-        }
-    }
-
-    static <T> boolean equal(T a, T b) {
-        return a == b || (a != null && b != null && a.equals(b));
-    }
-
-    /**
-     * Provides information about a media route.
-     * <p>
-     * Each media route has a list of {@link MediaControlIntent media control}
-     * {@link #getControlFilters intent filters} that describe the capabilities of the
-     * route and the manner in which it is used and controlled.
-     * </p>
-     */
-    public static class RouteInfo {
-        private final ProviderInfo mProvider;
-        private final String mDescriptorId;
-        private final String mUniqueId;
-        private String mName;
-        private String mDescription;
-        private Uri mIconUri;
-        private boolean mEnabled;
-        private boolean mConnecting;
-        private int mConnectionState;
-        private boolean mCanDisconnect;
-        private final ArrayList<IntentFilter> mControlFilters = new ArrayList<>();
-        private int mPlaybackType;
-        private int mPlaybackStream;
-        private int mDeviceType;
-        private int mVolumeHandling;
-        private int mVolume;
-        private int mVolumeMax;
-        private Display mPresentationDisplay;
-        private int mPresentationDisplayId = PRESENTATION_DISPLAY_ID_NONE;
-        private Bundle mExtras;
-        private IntentSender mSettingsIntent;
-        MediaRouteDescriptor mDescriptor;
-
-        @IntDef({CONNECTION_STATE_DISCONNECTED, CONNECTION_STATE_CONNECTING,
-                CONNECTION_STATE_CONNECTED})
-        @Retention(RetentionPolicy.SOURCE)
-        private @interface ConnectionState {}
-
-        /**
-         * The default connection state indicating the route is disconnected.
-         *
-         * @see #getConnectionState
-         */
-        public static final int CONNECTION_STATE_DISCONNECTED = 0;
-
-        /**
-         * A connection state indicating the route is in the process of connecting and is not yet
-         * ready for use.
-         *
-         * @see #getConnectionState
-         */
-        public static final int CONNECTION_STATE_CONNECTING = 1;
-
-        /**
-         * A connection state indicating the route is connected.
-         *
-         * @see #getConnectionState
-         */
-        public static final int CONNECTION_STATE_CONNECTED = 2;
-
-        @IntDef({PLAYBACK_TYPE_LOCAL,PLAYBACK_TYPE_REMOTE})
-        @Retention(RetentionPolicy.SOURCE)
-        private @interface PlaybackType {}
-
-        /**
-         * The default playback type, "local", indicating the presentation of the media
-         * is happening on the same device (e.g. a phone, a tablet) as where it is
-         * controlled from.
-         *
-         * @see #getPlaybackType
-         */
-        public static final int PLAYBACK_TYPE_LOCAL = 0;
-
-        /**
-         * A playback type indicating the presentation of the media is happening on
-         * a different device (i.e. the remote device) than where it is controlled from.
-         *
-         * @see #getPlaybackType
-         */
-        public static final int PLAYBACK_TYPE_REMOTE = 1;
-
-        @IntDef({DEVICE_TYPE_UNKNOWN, DEVICE_TYPE_TV, DEVICE_TYPE_SPEAKER, DEVICE_TYPE_BLUETOOTH})
-        @Retention(RetentionPolicy.SOURCE)
-        private @interface DeviceType {}
-
-        /**
-         * The default receiver device type of the route indicating the type is unknown.
-         *
-         * @see #getDeviceType
-         * @hide
-         */
-        // @RestrictTo(LIBRARY_GROUP)
-        public static final int DEVICE_TYPE_UNKNOWN = 0;
-
-        /**
-         * A receiver device type of the route indicating the presentation of the media is happening
-         * on a TV.
-         *
-         * @see #getDeviceType
-         */
-        public static final int DEVICE_TYPE_TV = 1;
-
-        /**
-         * A receiver device type of the route indicating the presentation of the media is happening
-         * on a speaker.
-         *
-         * @see #getDeviceType
-         */
-        public static final int DEVICE_TYPE_SPEAKER = 2;
-
-        /**
-         * A receiver device type of the route indicating the presentation of the media is happening
-         * on a bluetooth device such as a bluetooth speaker.
-         *
-         * @see #getDeviceType
-         * @hide
-         */
-        // @RestrictTo(LIBRARY_GROUP)
-        public static final int DEVICE_TYPE_BLUETOOTH = 3;
-
-        @IntDef({PLAYBACK_VOLUME_FIXED,PLAYBACK_VOLUME_VARIABLE})
-        @Retention(RetentionPolicy.SOURCE)
-        private @interface PlaybackVolume {}
-
-        /**
-         * Playback information indicating the playback volume is fixed, i.e. it cannot be
-         * controlled from this object. An example of fixed playback volume is a remote player,
-         * playing over HDMI where the user prefers to control the volume on the HDMI sink, rather
-         * than attenuate at the source.
-         *
-         * @see #getVolumeHandling
-         */
-        public static final int PLAYBACK_VOLUME_FIXED = 0;
-
-        /**
-         * Playback information indicating the playback volume is variable and can be controlled
-         * from this object.
-         *
-         * @see #getVolumeHandling
-         */
-        public static final int PLAYBACK_VOLUME_VARIABLE = 1;
-
-        /**
-         * The default presentation display id indicating no presentation display is associated
-         * with the route.
-         * @hide
-         */
-        // @RestrictTo(LIBRARY_GROUP)
-        public static final int PRESENTATION_DISPLAY_ID_NONE = -1;
-
-        static final int CHANGE_GENERAL = 1 << 0;
-        static final int CHANGE_VOLUME = 1 << 1;
-        static final int CHANGE_PRESENTATION_DISPLAY = 1 << 2;
-
-        // Should match to SystemMediaRouteProvider.PACKAGE_NAME.
-        static final String SYSTEM_MEDIA_ROUTE_PROVIDER_PACKAGE_NAME = "android";
-
-        RouteInfo(ProviderInfo provider, String descriptorId, String uniqueId) {
-            mProvider = provider;
-            mDescriptorId = descriptorId;
-            mUniqueId = uniqueId;
-        }
-
-        /**
-         * Gets information about the provider of this media route.
-         */
-        public ProviderInfo getProvider() {
-            return mProvider;
-        }
-
-        /**
-         * Gets the unique id of the route.
-         * <p>
-         * The route unique id functions as a stable identifier by which the route is known.
-         * For example, an application can use this id as a token to remember the
-         * selected route across restarts or to communicate its identity to a service.
-         * </p>
-         *
-         * @return The unique id of the route, never null.
-         */
-        @NonNull
-        public String getId() {
-            return mUniqueId;
-        }
-
-        /**
-         * Gets the user-visible name of the route.
-         * <p>
-         * The route name identifies the destination represented by the route.
-         * It may be a user-supplied name, an alias, or device serial number.
-         * </p>
-         *
-         * @return The user-visible name of a media route.  This is the string presented
-         * to users who may select this as the active route.
-         */
-        public String getName() {
-            return mName;
-        }
-
-        /**
-         * Gets the user-visible description of the route.
-         * <p>
-         * The route description describes the kind of destination represented by the route.
-         * It may be a user-supplied string, a model number or brand of device.
-         * </p>
-         *
-         * @return The description of the route, or null if none.
-         */
-        @Nullable
-        public String getDescription() {
-            return mDescription;
-        }
-
-        /**
-         * Gets the URI of the icon representing this route.
-         * <p>
-         * This icon will be used in picker UIs if available.
-         * </p>
-         *
-         * @return The URI of the icon representing this route, or null if none.
-         */
-        public Uri getIconUri() {
-            return mIconUri;
-        }
-
-        /**
-         * Returns true if this route is enabled and may be selected.
-         *
-         * @return True if this route is enabled.
-         */
-        public boolean isEnabled() {
-            return mEnabled;
-        }
-
-        /**
-         * Returns true if the route is in the process of connecting and is not
-         * yet ready for use.
-         *
-         * @return True if this route is in the process of connecting.
-         */
-        public boolean isConnecting() {
-            return mConnecting;
-        }
-
-        /**
-         * Gets the connection state of the route.
-         *
-         * @return The connection state of this route: {@link #CONNECTION_STATE_DISCONNECTED},
-         * {@link #CONNECTION_STATE_CONNECTING}, or {@link #CONNECTION_STATE_CONNECTED}.
-         */
-        @ConnectionState
-        public int getConnectionState() {
-            return mConnectionState;
-        }
-
-        /**
-         * Returns true if this route is currently selected.
-         *
-         * @return True if this route is currently selected.
-         *
-         * @see MediaRouter#getSelectedRoute
-         */
-        public boolean isSelected() {
-            checkCallingThread();
-            return sGlobal.getSelectedRoute() == this;
-        }
-
-        /**
-         * Returns true if this route is the default route.
-         *
-         * @return True if this route is the default route.
-         *
-         * @see MediaRouter#getDefaultRoute
-         */
-        public boolean isDefault() {
-            checkCallingThread();
-            return sGlobal.getDefaultRoute() == this;
-        }
-
-        /**
-         * Returns true if this route is a bluetooth route.
-         *
-         * @return True if this route is a bluetooth route.
-         *
-         * @see MediaRouter#getBluetoothRoute
-         */
-        public boolean isBluetooth() {
-            checkCallingThread();
-            return sGlobal.getBluetoothRoute() == this;
-        }
-
-        /**
-         * Returns true if this route is the default route and the device speaker.
-         *
-         * @return True if this route is the default route and the device speaker.
-         */
-        public boolean isDeviceSpeaker() {
-            int defaultAudioRouteNameResourceId = Resources.getSystem().getIdentifier(
-                    "default_audio_route_name", "string", "android");
-            return isDefault()
-                    && Resources.getSystem().getText(defaultAudioRouteNameResourceId).equals(mName);
-        }
-
-        /**
-         * Gets a list of {@link MediaControlIntent media control intent} filters that
-         * describe the capabilities of this route and the media control actions that
-         * it supports.
-         *
-         * @return A list of intent filters that specifies the media control intents that
-         * this route supports.
-         *
-         * @see MediaControlIntent
-         * @see #supportsControlCategory
-         * @see #supportsControlRequest
-         */
-        public List<IntentFilter> getControlFilters() {
-            return mControlFilters;
-        }
-
-        /**
-         * Returns true if the route supports at least one of the capabilities
-         * described by a media route selector.
-         *
-         * @param selector The selector that specifies the capabilities to check.
-         * @return True if the route supports at least one of the capabilities
-         * described in the media route selector.
-         */
-        public boolean matchesSelector(@NonNull MediaRouteSelector selector) {
-            if (selector == null) {
-                throw new IllegalArgumentException("selector must not be null");
-            }
-            checkCallingThread();
-            return selector.matchesControlFilters(mControlFilters);
-        }
-
-        /**
-         * Returns true if the route supports the specified
-         * {@link MediaControlIntent media control} category.
-         * <p>
-         * Media control categories describe the capabilities of this route
-         * such as whether it supports live audio streaming or remote playback.
-         * </p>
-         *
-         * @param category A {@link MediaControlIntent media control} category
-         * such as {@link MediaControlIntent#CATEGORY_LIVE_AUDIO},
-         * {@link MediaControlIntent#CATEGORY_LIVE_VIDEO},
-         * {@link MediaControlIntent#CATEGORY_REMOTE_PLAYBACK}, or a provider-defined
-         * media control category.
-         * @return True if the route supports the specified intent category.
-         *
-         * @see MediaControlIntent
-         * @see #getControlFilters
-         */
-        public boolean supportsControlCategory(@NonNull String category) {
-            if (category == null) {
-                throw new IllegalArgumentException("category must not be null");
-            }
-            checkCallingThread();
-
-            int count = mControlFilters.size();
-            for (int i = 0; i < count; i++) {
-                if (mControlFilters.get(i).hasCategory(category)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        /**
-         * Returns true if the route supports the specified
-         * {@link MediaControlIntent media control} category and action.
-         * <p>
-         * Media control actions describe specific requests that an application
-         * can ask a route to perform.
-         * </p>
-         *
-         * @param category A {@link MediaControlIntent media control} category
-         * such as {@link MediaControlIntent#CATEGORY_LIVE_AUDIO},
-         * {@link MediaControlIntent#CATEGORY_LIVE_VIDEO},
-         * {@link MediaControlIntent#CATEGORY_REMOTE_PLAYBACK}, or a provider-defined
-         * media control category.
-         * @param action A {@link MediaControlIntent media control} action
-         * such as {@link MediaControlIntent#ACTION_PLAY}.
-         * @return True if the route supports the specified intent action.
-         *
-         * @see MediaControlIntent
-         * @see #getControlFilters
-         */
-        public boolean supportsControlAction(@NonNull String category, @NonNull String action) {
-            if (category == null) {
-                throw new IllegalArgumentException("category must not be null");
-            }
-            if (action == null) {
-                throw new IllegalArgumentException("action must not be null");
-            }
-            checkCallingThread();
-
-            int count = mControlFilters.size();
-            for (int i = 0; i < count; i++) {
-                IntentFilter filter = mControlFilters.get(i);
-                if (filter.hasCategory(category) && filter.hasAction(action)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        /**
-         * Returns true if the route supports the specified
-         * {@link MediaControlIntent media control} request.
-         * <p>
-         * Media control requests are used to request the route to perform
-         * actions such as starting remote playback of a media item.
-         * </p>
-         *
-         * @param intent A {@link MediaControlIntent media control intent}.
-         * @return True if the route can handle the specified intent.
-         *
-         * @see MediaControlIntent
-         * @see #getControlFilters
-         */
-        public boolean supportsControlRequest(@NonNull Intent intent) {
-            if (intent == null) {
-                throw new IllegalArgumentException("intent must not be null");
-            }
-            checkCallingThread();
-
-            ContentResolver contentResolver = sGlobal.getContentResolver();
-            int count = mControlFilters.size();
-            for (int i = 0; i < count; i++) {
-                if (mControlFilters.get(i).match(contentResolver, intent, true, TAG) >= 0) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        /**
-         * Sends a {@link MediaControlIntent media control} request to be performed
-         * asynchronously by the route's destination.
-         * <p>
-         * Media control requests are used to request the route to perform
-         * actions such as starting remote playback of a media item.
-         * </p><p>
-         * This function may only be called on a selected route.  Control requests
-         * sent to unselected routes will fail.
-         * </p>
-         *
-         * @param intent A {@link MediaControlIntent media control intent}.
-         * @param callback A {@link ControlRequestCallback} to invoke with the result
-         * of the request, or null if no result is required.
-         *
-         * @see MediaControlIntent
-         */
-        public void sendControlRequest(@NonNull Intent intent,
-                @Nullable ControlRequestCallback callback) {
-            if (intent == null) {
-                throw new IllegalArgumentException("intent must not be null");
-            }
-            checkCallingThread();
-
-            sGlobal.sendControlRequest(this, intent, callback);
-        }
-
-        /**
-         * Gets the type of playback associated with this route.
-         *
-         * @return The type of playback associated with this route: {@link #PLAYBACK_TYPE_LOCAL}
-         * or {@link #PLAYBACK_TYPE_REMOTE}.
-         */
-        @PlaybackType
-        public int getPlaybackType() {
-            return mPlaybackType;
-        }
-
-        /**
-         * Gets the audio stream over which the playback associated with this route is performed.
-         *
-         * @return The stream over which the playback associated with this route is performed.
-         */
-        public int getPlaybackStream() {
-            return mPlaybackStream;
-        }
-
-        /**
-         * Gets the type of the receiver device associated with this route.
-         *
-         * @return The type of the receiver device associated with this route:
-         * {@link #DEVICE_TYPE_TV} or {@link #DEVICE_TYPE_SPEAKER}.
-         */
-        public int getDeviceType() {
-            return mDeviceType;
-        }
-
-
-        /**
-         * @hide
-         */
-        // @RestrictTo(LIBRARY_GROUP)
-        public boolean isDefaultOrBluetooth() {
-            if (isDefault() || mDeviceType == DEVICE_TYPE_BLUETOOTH) {
-                return true;
-            }
-            // This is a workaround for platform version 23 or below where the system route
-            // provider doesn't specify device type for bluetooth media routes.
-            return isSystemMediaRouteProvider(this)
-                    && supportsControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO)
-                    && !supportsControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO);
-        }
-
-        /**
-         * Returns {@code true} if the route is selectable.
-         */
-        boolean isSelectable() {
-            // This tests whether the route is still valid and enabled.
-            // The route descriptor field is set to null when the route is removed.
-            return mDescriptor != null && mEnabled;
-        }
-
-        private static boolean isSystemMediaRouteProvider(MediaRouter.RouteInfo route) {
-            return TextUtils.equals(route.getProviderInstance().getMetadata().getPackageName(),
-                    SYSTEM_MEDIA_ROUTE_PROVIDER_PACKAGE_NAME);
-        }
-
-        /**
-         * Gets information about how volume is handled on the route.
-         *
-         * @return How volume is handled on the route: {@link #PLAYBACK_VOLUME_FIXED}
-         * or {@link #PLAYBACK_VOLUME_VARIABLE}.
-         */
-        @PlaybackVolume
-        public int getVolumeHandling() {
-            return mVolumeHandling;
-        }
-
-        /**
-         * Gets the current volume for this route. Depending on the route, this may only
-         * be valid if the route is currently selected.
-         *
-         * @return The volume at which the playback associated with this route is performed.
-         */
-        public int getVolume() {
-            return mVolume;
-        }
-
-        /**
-         * Gets the maximum volume at which the playback associated with this route is performed.
-         *
-         * @return The maximum volume at which the playback associated with
-         * this route is performed.
-         */
-        public int getVolumeMax() {
-            return mVolumeMax;
-        }
-
-        /**
-         * Gets whether this route supports disconnecting without interrupting
-         * playback.
-         *
-         * @return True if this route can disconnect without stopping playback,
-         *         false otherwise.
-         */
-        public boolean canDisconnect() {
-            return mCanDisconnect;
-        }
-
-        /**
-         * Requests a volume change for this route asynchronously.
-         * <p>
-         * This function may only be called on a selected route.  It will have
-         * no effect if the route is currently unselected.
-         * </p>
-         *
-         * @param volume The new volume value between 0 and {@link #getVolumeMax}.
-         */
-        public void requestSetVolume(int volume) {
-            checkCallingThread();
-            sGlobal.requestSetVolume(this, Math.min(mVolumeMax, Math.max(0, volume)));
-        }
-
-        /**
-         * Requests an incremental volume update for this route asynchronously.
-         * <p>
-         * This function may only be called on a selected route.  It will have
-         * no effect if the route is currently unselected.
-         * </p>
-         *
-         * @param delta The delta to add to the current volume.
-         */
-        public void requestUpdateVolume(int delta) {
-            checkCallingThread();
-            if (delta != 0) {
-                sGlobal.requestUpdateVolume(this, delta);
-            }
-        }
-
-        /**
-         * Gets the {@link Display} that should be used by the application to show
-         * a {@link android.app.Presentation} on an external display when this route is selected.
-         * Depending on the route, this may only be valid if the route is currently
-         * selected.
-         * <p>
-         * The preferred presentation display may change independently of the route
-         * being selected or unselected.  For example, the presentation display
-         * of the default system route may change when an external HDMI display is connected
-         * or disconnected even though the route itself has not changed.
-         * </p><p>
-         * This method may return null if there is no external display associated with
-         * the route or if the display is not ready to show UI yet.
-         * </p><p>
-         * The application should listen for changes to the presentation display
-         * using the {@link Callback#onRoutePresentationDisplayChanged} callback and
-         * show or dismiss its {@link android.app.Presentation} accordingly when the display
-         * becomes available or is removed.
-         * </p><p>
-         * This method only makes sense for
-         * {@link MediaControlIntent#CATEGORY_LIVE_VIDEO live video} routes.
-         * </p>
-         *
-         * @return The preferred presentation display to use when this route is
-         * selected or null if none.
-         *
-         * @see MediaControlIntent#CATEGORY_LIVE_VIDEO
-         * @see android.app.Presentation
-         */
-        @Nullable
-        public Display getPresentationDisplay() {
-            checkCallingThread();
-            if (mPresentationDisplayId >= 0 && mPresentationDisplay == null) {
-                mPresentationDisplay = sGlobal.getDisplay(mPresentationDisplayId);
-            }
-            return mPresentationDisplay;
-        }
-
-        /**
-         * Gets the route's presentation display id, or -1 if none.
-         * @hide
-         */
-        // @RestrictTo(LIBRARY_GROUP)
-        public int getPresentationDisplayId() {
-            return mPresentationDisplayId;
-        }
-
-        /**
-         * Gets a collection of extra properties about this route that were supplied
-         * by its media route provider, or null if none.
-         */
-        @Nullable
-        public Bundle getExtras() {
-            return mExtras;
-        }
-
-        /**
-         * Gets an intent sender for launching a settings activity for this
-         * route.
-         */
-        @Nullable
-        public IntentSender getSettingsIntent() {
-            return mSettingsIntent;
-        }
-
-        /**
-         * Selects this media route.
-         */
-        public void select() {
-            checkCallingThread();
-            sGlobal.selectRoute(this);
-        }
-
-        @Override
-        public String toString() {
-            return "MediaRouter.RouteInfo{ uniqueId=" + mUniqueId
-                    + ", name=" + mName
-                    + ", description=" + mDescription
-                    + ", iconUri=" + mIconUri
-                    + ", enabled=" + mEnabled
-                    + ", connecting=" + mConnecting
-                    + ", connectionState=" + mConnectionState
-                    + ", canDisconnect=" + mCanDisconnect
-                    + ", playbackType=" + mPlaybackType
-                    + ", playbackStream=" + mPlaybackStream
-                    + ", deviceType=" + mDeviceType
-                    + ", volumeHandling=" + mVolumeHandling
-                    + ", volume=" + mVolume
-                    + ", volumeMax=" + mVolumeMax
-                    + ", presentationDisplayId=" + mPresentationDisplayId
-                    + ", extras=" + mExtras
-                    + ", settingsIntent=" + mSettingsIntent
-                    + ", providerPackageName=" + mProvider.getPackageName()
-                    + " }";
-        }
-
-        int maybeUpdateDescriptor(MediaRouteDescriptor descriptor) {
-            int changes = 0;
-            if (mDescriptor != descriptor) {
-                changes = updateDescriptor(descriptor);
-            }
-            return changes;
-        }
-
-        int updateDescriptor(MediaRouteDescriptor descriptor) {
-            int changes = 0;
-            mDescriptor = descriptor;
-            if (descriptor != null) {
-                if (!equal(mName, descriptor.getName())) {
-                    mName = descriptor.getName();
-                    changes |= CHANGE_GENERAL;
-                }
-                if (!equal(mDescription, descriptor.getDescription())) {
-                    mDescription = descriptor.getDescription();
-                    changes |= CHANGE_GENERAL;
-                }
-                if (!equal(mIconUri, descriptor.getIconUri())) {
-                    mIconUri = descriptor.getIconUri();
-                    changes |= CHANGE_GENERAL;
-                }
-                if (mEnabled != descriptor.isEnabled()) {
-                    mEnabled = descriptor.isEnabled();
-                    changes |= CHANGE_GENERAL;
-                }
-                if (mConnecting != descriptor.isConnecting()) {
-                    mConnecting = descriptor.isConnecting();
-                    changes |= CHANGE_GENERAL;
-                }
-                if (mConnectionState != descriptor.getConnectionState()) {
-                    mConnectionState = descriptor.getConnectionState();
-                    changes |= CHANGE_GENERAL;
-                }
-                if (!mControlFilters.equals(descriptor.getControlFilters())) {
-                    mControlFilters.clear();
-                    mControlFilters.addAll(descriptor.getControlFilters());
-                    changes |= CHANGE_GENERAL;
-                }
-                if (mPlaybackType != descriptor.getPlaybackType()) {
-                    mPlaybackType = descriptor.getPlaybackType();
-                    changes |= CHANGE_GENERAL;
-                }
-                if (mPlaybackStream != descriptor.getPlaybackStream()) {
-                    mPlaybackStream = descriptor.getPlaybackStream();
-                    changes |= CHANGE_GENERAL;
-                }
-                if (mDeviceType != descriptor.getDeviceType()) {
-                    mDeviceType = descriptor.getDeviceType();
-                    changes |= CHANGE_GENERAL;
-                }
-                if (mVolumeHandling != descriptor.getVolumeHandling()) {
-                    mVolumeHandling = descriptor.getVolumeHandling();
-                    changes |= CHANGE_GENERAL | CHANGE_VOLUME;
-                }
-                if (mVolume != descriptor.getVolume()) {
-                    mVolume = descriptor.getVolume();
-                    changes |= CHANGE_GENERAL | CHANGE_VOLUME;
-                }
-                if (mVolumeMax != descriptor.getVolumeMax()) {
-                    mVolumeMax = descriptor.getVolumeMax();
-                    changes |= CHANGE_GENERAL | CHANGE_VOLUME;
-                }
-                if (mPresentationDisplayId != descriptor.getPresentationDisplayId()) {
-                    mPresentationDisplayId = descriptor.getPresentationDisplayId();
-                    mPresentationDisplay = null;
-                    changes |= CHANGE_GENERAL | CHANGE_PRESENTATION_DISPLAY;
-                }
-                if (!equal(mExtras, descriptor.getExtras())) {
-                    mExtras = descriptor.getExtras();
-                    changes |= CHANGE_GENERAL;
-                }
-                if (!equal(mSettingsIntent, descriptor.getSettingsActivity())) {
-                    mSettingsIntent = descriptor.getSettingsActivity();
-                    changes |= CHANGE_GENERAL;
-                }
-                if (mCanDisconnect != descriptor.canDisconnectAndKeepPlaying()) {
-                    mCanDisconnect = descriptor.canDisconnectAndKeepPlaying();
-                    changes |= CHANGE_GENERAL | CHANGE_PRESENTATION_DISPLAY;
-                }
-            }
-            return changes;
-        }
-
-        String getDescriptorId() {
-            return mDescriptorId;
-        }
-
-        /** @hide */
-        // @RestrictTo(LIBRARY_GROUP)
-        public MediaRouteProvider getProviderInstance() {
-            return mProvider.getProviderInstance();
-        }
-    }
-
-    /**
-     * Information about a route that consists of multiple other routes in a group.
-     * @hide
-     */
-    // @RestrictTo(LIBRARY_GROUP)
-    public static class RouteGroup extends RouteInfo {
-        private List<RouteInfo> mRoutes = new ArrayList<>();
-
-        RouteGroup(ProviderInfo provider, String descriptorId, String uniqueId) {
-            super(provider, descriptorId, uniqueId);
-        }
-
-        /**
-         * @return The number of routes in this group
-         */
-        public int getRouteCount() {
-            return mRoutes.size();
-        }
-
-        /**
-         * Returns the route in this group at the specified index
-         *
-         * @param index Index to fetch
-         * @return The route at index
-         */
-        public RouteInfo getRouteAt(int index) {
-            return mRoutes.get(index);
-        }
-
-        /**
-         * Returns the routes in this group
-         *
-         * @return The list of the routes in this group
-         */
-        public List<RouteInfo> getRoutes() {
-            return mRoutes;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder sb = new StringBuilder(super.toString());
-            sb.append('[');
-            final int count = mRoutes.size();
-            for (int i = 0; i < count; i++) {
-                if (i > 0) sb.append(", ");
-                sb.append(mRoutes.get(i));
-            }
-            sb.append(']');
-            return sb.toString();
-        }
-
-        @Override
-        int maybeUpdateDescriptor(MediaRouteDescriptor descriptor) {
-            boolean changed = false;
-            if (mDescriptor != descriptor) {
-                mDescriptor = descriptor;
-                if (descriptor != null) {
-                    List<String> groupMemberIds = descriptor.getGroupMemberIds();
-                    List<RouteInfo> routes = new ArrayList<>();
-                    changed = groupMemberIds.size() != mRoutes.size();
-                    for (String groupMemberId : groupMemberIds) {
-                        String uniqueId = sGlobal.getUniqueId(getProvider(), groupMemberId);
-                        RouteInfo groupMember = sGlobal.getRoute(uniqueId);
-                        if (groupMember != null) {
-                            routes.add(groupMember);
-                            if (!changed && !mRoutes.contains(groupMember)) {
-                                changed = true;
-                            }
-                        }
-                    }
-                    if (changed) {
-                        mRoutes = routes;
-                    }
-                }
-            }
-            return (changed ? CHANGE_GENERAL : 0) | super.updateDescriptor(descriptor);
-        }
-    }
-
-    /**
-     * Provides information about a media route provider.
-     * <p>
-     * This object may be used to determine which media route provider has
-     * published a particular route.
-     * </p>
-     */
-    public static final class ProviderInfo {
-        private final MediaRouteProvider mProviderInstance;
-        private final List<RouteInfo> mRoutes = new ArrayList<>();
-
-        private final ProviderMetadata mMetadata;
-        private MediaRouteProviderDescriptor mDescriptor;
-        private Resources mResources;
-        private boolean mResourcesNotAvailable;
-
-        ProviderInfo(MediaRouteProvider provider) {
-            mProviderInstance = provider;
-            mMetadata = provider.getMetadata();
-        }
-
-        /**
-         * Gets the provider's underlying {@link MediaRouteProvider} instance.
-         */
-        public MediaRouteProvider getProviderInstance() {
-            checkCallingThread();
-            return mProviderInstance;
-        }
-
-        /**
-         * Gets the package name of the media route provider.
-         */
-        public String getPackageName() {
-            return mMetadata.getPackageName();
-        }
-
-        /**
-         * Gets the component name of the media route provider.
-         */
-        public ComponentName getComponentName() {
-            return mMetadata.getComponentName();
-        }
-
-        /**
-         * Gets the {@link MediaRouter.RouteInfo routes} published by this route provider.
-         */
-        public List<RouteInfo> getRoutes() {
-            checkCallingThread();
-            return mRoutes;
-        }
-
-        Resources getResources() {
-            if (mResources == null && !mResourcesNotAvailable) {
-                String packageName = getPackageName();
-                Context context = sGlobal.getProviderContext(packageName);
-                if (context != null) {
-                    mResources = context.getResources();
-                } else {
-                    Log.w(TAG, "Unable to obtain resources for route provider package: "
-                            + packageName);
-                    mResourcesNotAvailable = true;
-                }
-            }
-            return mResources;
-        }
-
-        boolean updateDescriptor(MediaRouteProviderDescriptor descriptor) {
-            if (mDescriptor != descriptor) {
-                mDescriptor = descriptor;
-                return true;
-            }
-            return false;
-        }
-
-        int findRouteByDescriptorId(String id) {
-            final int count = mRoutes.size();
-            for (int i = 0; i < count; i++) {
-                if (mRoutes.get(i).mDescriptorId.equals(id)) {
-                    return i;
-                }
-            }
-            return -1;
-        }
-
-        @Override
-        public String toString() {
-            return "MediaRouter.RouteProviderInfo{ packageName=" + getPackageName()
-                    + " }";
-        }
-    }
-
-    /**
-     * Interface for receiving events about media routing changes.
-     * All methods of this interface will be called from the application's main thread.
-     * <p>
-     * A Callback will only receive events relevant to routes that the callback
-     * was registered for unless the {@link MediaRouter#CALLBACK_FLAG_UNFILTERED_EVENTS}
-     * flag was specified in {@link MediaRouter#addCallback(MediaRouteSelector, Callback, int)}.
-     * </p>
-     *
-     * @see MediaRouter#addCallback(MediaRouteSelector, Callback, int)
-     * @see MediaRouter#removeCallback(Callback)
-     */
-    public static abstract class Callback {
-        /**
-         * Called when the supplied media route becomes selected as the active route.
-         *
-         * @param router The media router reporting the event.
-         * @param route The route that has been selected.
-         */
-        public void onRouteSelected(MediaRouter router, RouteInfo route) {
-        }
-
-        /**
-         * Called when the supplied media route becomes unselected as the active route.
-         * For detailed reason, override {@link #onRouteUnselected(MediaRouter, RouteInfo, int)}
-         * instead.
-         *
-         * @param router The media router reporting the event.
-         * @param route The route that has been unselected.
-         */
-        public void onRouteUnselected(MediaRouter router, RouteInfo route) {
-        }
-
-        /**
-         * Called when the supplied media route becomes unselected as the active route.
-         * The default implementation calls {@link #onRouteUnselected}.
-         * <p>
-         * The reason provided will be one of the following:
-         * <ul>
-         * <li>{@link MediaRouter#UNSELECT_REASON_UNKNOWN}</li>
-         * <li>{@link MediaRouter#UNSELECT_REASON_DISCONNECTED}</li>
-         * <li>{@link MediaRouter#UNSELECT_REASON_STOPPED}</li>
-         * <li>{@link MediaRouter#UNSELECT_REASON_ROUTE_CHANGED}</li>
-         * </ul>
-         *
-         * @param router The media router reporting the event.
-         * @param route The route that has been unselected.
-         * @param reason The reason for unselecting the route.
-         */
-        public void onRouteUnselected(MediaRouter router, RouteInfo route, int reason) {
-            onRouteUnselected(router, route);
-        }
-
-        /**
-         * Called when a media route has been added.
-         *
-         * @param router The media router reporting the event.
-         * @param route The route that has become available for use.
-         */
-        public void onRouteAdded(MediaRouter router, RouteInfo route) {
-        }
-
-        /**
-         * Called when a media route has been removed.
-         *
-         * @param router The media router reporting the event.
-         * @param route The route that has been removed from availability.
-         */
-        public void onRouteRemoved(MediaRouter router, RouteInfo route) {
-        }
-
-        /**
-         * Called when a property of the indicated media route has changed.
-         *
-         * @param router The media router reporting the event.
-         * @param route The route that was changed.
-         */
-        public void onRouteChanged(MediaRouter router, RouteInfo route) {
-        }
-
-        /**
-         * Called when a media route's volume changes.
-         *
-         * @param router The media router reporting the event.
-         * @param route The route whose volume changed.
-         */
-        public void onRouteVolumeChanged(MediaRouter router, RouteInfo route) {
-        }
-
-        /**
-         * Called when a media route's presentation display changes.
-         * <p>
-         * This method is called whenever the route's presentation display becomes
-         * available, is removed or has changes to some of its properties (such as its size).
-         * </p>
-         *
-         * @param router The media router reporting the event.
-         * @param route The route whose presentation display changed.
-         *
-         * @see RouteInfo#getPresentationDisplay()
-         */
-        public void onRoutePresentationDisplayChanged(MediaRouter router, RouteInfo route) {
-        }
-
-        /**
-         * Called when a media route provider has been added.
-         *
-         * @param router The media router reporting the event.
-         * @param provider The provider that has become available for use.
-         */
-        public void onProviderAdded(MediaRouter router, ProviderInfo provider) {
-        }
-
-        /**
-         * Called when a media route provider has been removed.
-         *
-         * @param router The media router reporting the event.
-         * @param provider The provider that has been removed from availability.
-         */
-        public void onProviderRemoved(MediaRouter router, ProviderInfo provider) {
-        }
-
-        /**
-         * Called when a property of the indicated media route provider has changed.
-         *
-         * @param router The media router reporting the event.
-         * @param provider The provider that was changed.
-         */
-        public void onProviderChanged(MediaRouter router, ProviderInfo provider) {
-        }
-    }
-
-    /**
-     * Callback which is invoked with the result of a media control request.
-     *
-     * @see RouteInfo#sendControlRequest
-     */
-    public static abstract class ControlRequestCallback {
-        /**
-         * Called when a media control request succeeds.
-         *
-         * @param data Result data, or null if none.
-         * Contents depend on the {@link MediaControlIntent media control action}.
-         */
-        public void onResult(Bundle data) {
-        }
-
-        /**
-         * Called when a media control request fails.
-         *
-         * @param error A localized error message which may be shown to the user, or null
-         * if the cause of the error is unclear.
-         * @param data Error data, or null if none.
-         * Contents depend on the {@link MediaControlIntent media control action}.
-         */
-        public void onError(String error, Bundle data) {
-        }
-    }
-
-    private static final class CallbackRecord {
-        public final MediaRouter mRouter;
-        public final Callback mCallback;
-        public MediaRouteSelector mSelector;
-        public int mFlags;
-
-        public CallbackRecord(MediaRouter router, Callback callback) {
-            mRouter = router;
-            mCallback = callback;
-            mSelector = MediaRouteSelector.EMPTY;
-        }
-
-        public boolean filterRouteEvent(RouteInfo route) {
-            return (mFlags & CALLBACK_FLAG_UNFILTERED_EVENTS) != 0
-                    || route.matchesSelector(mSelector);
-        }
-    }
-
-    /**
-     * Global state for the media router.
-     * <p>
-     * Media routes and media route providers are global to the process; their
-     * state and the bulk of the media router implementation lives here.
-     * </p>
-     */
-    private static final class GlobalMediaRouter
-            implements SystemMediaRouteProvider.SyncCallback,
-            RegisteredMediaRouteProviderWatcher.Callback {
-        final Context mApplicationContext;
-        final ArrayList<WeakReference<MediaRouter>> mRouters = new ArrayList<>();
-        private final ArrayList<RouteInfo> mRoutes = new ArrayList<>();
-        private final Map<Pair<String, String>, String> mUniqueIdMap = new HashMap<>();
-        private final ArrayList<ProviderInfo> mProviders = new ArrayList<>();
-        private final ArrayList<RemoteControlClientRecord> mRemoteControlClients =
-                new ArrayList<>();
-        final RemoteControlClientCompat.PlaybackInfo mPlaybackInfo =
-                new RemoteControlClientCompat.PlaybackInfo();
-        private final ProviderCallback mProviderCallback = new ProviderCallback();
-        final CallbackHandler mCallbackHandler = new CallbackHandler();
-        private final DisplayManagerCompat mDisplayManager;
-        final SystemMediaRouteProvider mSystemProvider;
-        private final boolean mLowRam;
-
-        private RegisteredMediaRouteProviderWatcher mRegisteredProviderWatcher;
-        private RouteInfo mDefaultRoute;
-        private RouteInfo mBluetoothRoute;
-        RouteInfo mSelectedRoute;
-        private RouteController mSelectedRouteController;
-        // A map from route descriptor ID to RouteController for the member routes in the currently
-        // selected route group.
-        private final Map<String, RouteController> mRouteControllerMap = new HashMap<>();
-        private MediaRouteDiscoveryRequest mDiscoveryRequest;
-        private MediaSessionRecord mMediaSession;
-        MediaSessionCompat mRccMediaSession;
-        private MediaSessionCompat mCompatSession;
-        private MediaSessionCompat.OnActiveChangeListener mSessionActiveListener =
-                new MediaSessionCompat.OnActiveChangeListener() {
-            @Override
-            public void onActiveChanged() {
-                if(mRccMediaSession != null) {
-                    if (mRccMediaSession.isActive()) {
-                        addRemoteControlClient(mRccMediaSession.getRemoteControlClient());
-                    } else {
-                        removeRemoteControlClient(mRccMediaSession.getRemoteControlClient());
-                    }
-                }
-            }
-        };
-
-        GlobalMediaRouter(Context applicationContext) {
-            mApplicationContext = applicationContext;
-            mDisplayManager = DisplayManagerCompat.getInstance(applicationContext);
-            mLowRam = ActivityManagerCompat.isLowRamDevice(
-                    (ActivityManager)applicationContext.getSystemService(
-                            Context.ACTIVITY_SERVICE));
-
-            // Add the system media route provider for interoperating with
-            // the framework media router.  This one is special and receives
-            // synchronization messages from the media router.
-            mSystemProvider = SystemMediaRouteProvider.obtain(applicationContext, this);
-        }
-
-        public void start() {
-            addProvider(mSystemProvider);
-
-            // Start watching for routes published by registered media route
-            // provider services.
-            mRegisteredProviderWatcher = new RegisteredMediaRouteProviderWatcher(
-                    mApplicationContext, this);
-            mRegisteredProviderWatcher.start();
-        }
-
-        public MediaRouter getRouter(Context context) {
-            MediaRouter router;
-            for (int i = mRouters.size(); --i >= 0; ) {
-                router = mRouters.get(i).get();
-                if (router == null) {
-                    mRouters.remove(i);
-                } else if (router.mContext == context) {
-                    return router;
-                }
-            }
-            router = new MediaRouter(context);
-            mRouters.add(new WeakReference<MediaRouter>(router));
-            return router;
-        }
-
-        public ContentResolver getContentResolver() {
-            return mApplicationContext.getContentResolver();
-        }
-
-        public Context getProviderContext(String packageName) {
-            if (packageName.equals(SystemMediaRouteProvider.PACKAGE_NAME)) {
-                return mApplicationContext;
-            }
-            try {
-                return mApplicationContext.createPackageContext(
-                        packageName, Context.CONTEXT_RESTRICTED);
-            } catch (NameNotFoundException ex) {
-                return null;
-            }
-        }
-
-        public Display getDisplay(int displayId) {
-            return mDisplayManager.getDisplay(displayId);
-        }
-
-        public void sendControlRequest(RouteInfo route,
-                Intent intent, ControlRequestCallback callback) {
-            if (route == mSelectedRoute && mSelectedRouteController != null) {
-                if (mSelectedRouteController.onControlRequest(intent, callback)) {
-                    return;
-                }
-            }
-            if (callback != null) {
-                callback.onError(null, null);
-            }
-        }
-
-        public void requestSetVolume(RouteInfo route, int volume) {
-            if (route == mSelectedRoute && mSelectedRouteController != null) {
-                mSelectedRouteController.onSetVolume(volume);
-            } else if (!mRouteControllerMap.isEmpty()) {
-                RouteController controller = mRouteControllerMap.get(route.mDescriptorId);
-                if (controller != null) {
-                    controller.onSetVolume(volume);
-                }
-            }
-        }
-
-        public void requestUpdateVolume(RouteInfo route, int delta) {
-            if (route == mSelectedRoute && mSelectedRouteController != null) {
-                mSelectedRouteController.onUpdateVolume(delta);
-            }
-        }
-
-        public RouteInfo getRoute(String uniqueId) {
-            for (RouteInfo info : mRoutes) {
-                if (info.mUniqueId.equals(uniqueId)) {
-                    return info;
-                }
-            }
-            return null;
-        }
-
-        public List<RouteInfo> getRoutes() {
-            return mRoutes;
-        }
-
-        List<ProviderInfo> getProviders() {
-            return mProviders;
-        }
-
-        @NonNull RouteInfo getDefaultRoute() {
-            if (mDefaultRoute == null) {
-                // This should never happen once the media router has been fully
-                // initialized but it is good to check for the error in case there
-                // is a bug in provider initialization.
-                throw new IllegalStateException("There is no default route.  "
-                        + "The media router has not yet been fully initialized.");
-            }
-            return mDefaultRoute;
-        }
-
-        RouteInfo getBluetoothRoute() {
-            return mBluetoothRoute;
-        }
-
-        @NonNull RouteInfo getSelectedRoute() {
-            if (mSelectedRoute == null) {
-                // This should never happen once the media router has been fully
-                // initialized but it is good to check for the error in case there
-                // is a bug in provider initialization.
-                throw new IllegalStateException("There is no currently selected route.  "
-                        + "The media router has not yet been fully initialized.");
-            }
-            return mSelectedRoute;
-        }
-
-        void selectRoute(@NonNull RouteInfo route) {
-            selectRoute(route, MediaRouter.UNSELECT_REASON_ROUTE_CHANGED);
-        }
-
-        void selectRoute(@NonNull RouteInfo route, int unselectReason) {
-            if (!mRoutes.contains(route)) {
-                Log.w(TAG, "Ignoring attempt to select removed route: " + route);
-                return;
-            }
-            if (!route.mEnabled) {
-                Log.w(TAG, "Ignoring attempt to select disabled route: " + route);
-                return;
-            }
-            setSelectedRouteInternal(route, unselectReason);
-        }
-
-        public boolean isRouteAvailable(MediaRouteSelector selector, int flags) {
-            if (selector.isEmpty()) {
-                return false;
-            }
-
-            // On low-RAM devices, do not rely on actual discovery results unless asked to.
-            if ((flags & AVAILABILITY_FLAG_REQUIRE_MATCH) == 0 && mLowRam) {
-                return true;
-            }
-
-            // Check whether any existing routes match the selector.
-            final int routeCount = mRoutes.size();
-            for (int i = 0; i < routeCount; i++) {
-                RouteInfo route = mRoutes.get(i);
-                if ((flags & AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE) != 0
-                        && route.isDefaultOrBluetooth()) {
-                    continue;
-                }
-                if (route.matchesSelector(selector)) {
-                    return true;
-                }
-            }
-
-            // It doesn't look like we can find a matching route right now.
-            return false;
-        }
-
-        public void updateDiscoveryRequest() {
-            // Combine all of the callback selectors and active scan flags.
-            boolean discover = false;
-            boolean activeScan = false;
-            MediaRouteSelector.Builder builder = new MediaRouteSelector.Builder();
-            for (int i = mRouters.size(); --i >= 0; ) {
-                MediaRouter router = mRouters.get(i).get();
-                if (router == null) {
-                    mRouters.remove(i);
-                } else {
-                    final int count = router.mCallbackRecords.size();
-                    for (int j = 0; j < count; j++) {
-                        CallbackRecord callback = router.mCallbackRecords.get(j);
-                        builder.addSelector(callback.mSelector);
-                        if ((callback.mFlags & CALLBACK_FLAG_PERFORM_ACTIVE_SCAN) != 0) {
-                            activeScan = true;
-                            discover = true; // perform active scan implies request discovery
-                        }
-                        if ((callback.mFlags & CALLBACK_FLAG_REQUEST_DISCOVERY) != 0) {
-                            if (!mLowRam) {
-                                discover = true;
-                            }
-                        }
-                        if ((callback.mFlags & CALLBACK_FLAG_FORCE_DISCOVERY) != 0) {
-                            discover = true;
-                        }
-                    }
-                }
-            }
-            MediaRouteSelector selector = discover ? builder.build() : MediaRouteSelector.EMPTY;
-
-            // Create a new discovery request.
-            if (mDiscoveryRequest != null
-                    && mDiscoveryRequest.getSelector().equals(selector)
-                    && mDiscoveryRequest.isActiveScan() == activeScan) {
-                return; // no change
-            }
-            if (selector.isEmpty() && !activeScan) {
-                // Discovery is not needed.
-                if (mDiscoveryRequest == null) {
-                    return; // no change
-                }
-                mDiscoveryRequest = null;
-            } else {
-                // Discovery is needed.
-                mDiscoveryRequest = new MediaRouteDiscoveryRequest(selector, activeScan);
-            }
-            if (DEBUG) {
-                Log.d(TAG, "Updated discovery request: " + mDiscoveryRequest);
-            }
-            if (discover && !activeScan && mLowRam) {
-                Log.i(TAG, "Forcing passive route discovery on a low-RAM device, "
-                        + "system performance may be affected.  Please consider using "
-                        + "CALLBACK_FLAG_REQUEST_DISCOVERY instead of "
-                        + "CALLBACK_FLAG_FORCE_DISCOVERY.");
-            }
-
-            // Notify providers.
-            final int providerCount = mProviders.size();
-            for (int i = 0; i < providerCount; i++) {
-                mProviders.get(i).mProviderInstance.setDiscoveryRequest(mDiscoveryRequest);
-            }
-        }
-
-        @Override
-        public void addProvider(MediaRouteProvider providerInstance) {
-            int index = findProviderInfo(providerInstance);
-            if (index < 0) {
-                // 1. Add the provider to the list.
-                ProviderInfo provider = new ProviderInfo(providerInstance);
-                mProviders.add(provider);
-                if (DEBUG) {
-                    Log.d(TAG, "Provider added: " + provider);
-                }
-                mCallbackHandler.post(CallbackHandler.MSG_PROVIDER_ADDED, provider);
-                // 2. Create the provider's contents.
-                updateProviderContents(provider, providerInstance.getDescriptor());
-                // 3. Register the provider callback.
-                providerInstance.setCallback(mProviderCallback);
-                // 4. Set the discovery request.
-                providerInstance.setDiscoveryRequest(mDiscoveryRequest);
-            }
-        }
-
-        @Override
-        public void removeProvider(MediaRouteProvider providerInstance) {
-            int index = findProviderInfo(providerInstance);
-            if (index >= 0) {
-                // 1. Unregister the provider callback.
-                providerInstance.setCallback(null);
-                // 2. Clear the discovery request.
-                providerInstance.setDiscoveryRequest(null);
-                // 3. Delete the provider's contents.
-                ProviderInfo provider = mProviders.get(index);
-                updateProviderContents(provider, null);
-                // 4. Remove the provider from the list.
-                if (DEBUG) {
-                    Log.d(TAG, "Provider removed: " + provider);
-                }
-                mCallbackHandler.post(CallbackHandler.MSG_PROVIDER_REMOVED, provider);
-                mProviders.remove(index);
-            }
-        }
-
-        void updateProviderDescriptor(MediaRouteProvider providerInstance,
-                MediaRouteProviderDescriptor descriptor) {
-            int index = findProviderInfo(providerInstance);
-            if (index >= 0) {
-                // Update the provider's contents.
-                ProviderInfo provider = mProviders.get(index);
-                updateProviderContents(provider, descriptor);
-            }
-        }
-
-        private int findProviderInfo(MediaRouteProvider providerInstance) {
-            final int count = mProviders.size();
-            for (int i = 0; i < count; i++) {
-                if (mProviders.get(i).mProviderInstance == providerInstance) {
-                    return i;
-                }
-            }
-            return -1;
-        }
-
-        private void updateProviderContents(ProviderInfo provider,
-                MediaRouteProviderDescriptor providerDescriptor) {
-            if (provider.updateDescriptor(providerDescriptor)) {
-                // Update all existing routes and reorder them to match
-                // the order of their descriptors.
-                int targetIndex = 0;
-                boolean selectedRouteDescriptorChanged = false;
-                if (providerDescriptor != null) {
-                    if (providerDescriptor.isValid()) {
-                        final List<MediaRouteDescriptor> routeDescriptors =
-                                providerDescriptor.getRoutes();
-                        final int routeCount = routeDescriptors.size();
-                        // Updating route group's contents requires all member routes' information.
-                        // Add the groups to the lists and update them later.
-                        List<Pair<RouteInfo, MediaRouteDescriptor>> addedGroups = new ArrayList<>();
-                        List<Pair<RouteInfo, MediaRouteDescriptor>> updatedGroups =
-                                new ArrayList<>();
-                        for (int i = 0; i < routeCount; i++) {
-                            final MediaRouteDescriptor routeDescriptor = routeDescriptors.get(i);
-                            final String id = routeDescriptor.getId();
-                            final int sourceIndex = provider.findRouteByDescriptorId(id);
-                            if (sourceIndex < 0) {
-                                // 1. Add the route to the list.
-                                String uniqueId = assignRouteUniqueId(provider, id);
-                                boolean isGroup = routeDescriptor.getGroupMemberIds() != null;
-                                RouteInfo route = isGroup ? new RouteGroup(provider, id, uniqueId) :
-                                        new RouteInfo(provider, id, uniqueId);
-                                provider.mRoutes.add(targetIndex++, route);
-                                mRoutes.add(route);
-                                // 2. Create the route's contents.
-                                if (isGroup) {
-                                    addedGroups.add(new Pair<>(route, routeDescriptor));
-                                } else {
-                                    route.maybeUpdateDescriptor(routeDescriptor);
-                                    // 3. Notify clients about addition.
-                                    if (DEBUG) {
-                                        Log.d(TAG, "Route added: " + route);
-                                    }
-                                    mCallbackHandler.post(CallbackHandler.MSG_ROUTE_ADDED, route);
-                                }
-
-                            } else if (sourceIndex < targetIndex) {
-                                Log.w(TAG, "Ignoring route descriptor with duplicate id: "
-                                        + routeDescriptor);
-                            } else {
-                                // 1. Reorder the route within the list.
-                                RouteInfo route = provider.mRoutes.get(sourceIndex);
-                                Collections.swap(provider.mRoutes,
-                                        sourceIndex, targetIndex++);
-                                // 2. Update the route's contents.
-                                if (route instanceof RouteGroup) {
-                                    updatedGroups.add(new Pair<>(route, routeDescriptor));
-                                } else {
-                                    // 3. Notify clients about changes.
-                                    if (updateRouteDescriptorAndNotify(route, routeDescriptor)
-                                            != 0) {
-                                        if (route == mSelectedRoute) {
-                                            selectedRouteDescriptorChanged = true;
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                        // Update the new and/or existing groups.
-                        for (Pair<RouteInfo, MediaRouteDescriptor> pair : addedGroups) {
-                            RouteInfo route = pair.first;
-                            route.maybeUpdateDescriptor(pair.second);
-                            if (DEBUG) {
-                                Log.d(TAG, "Route added: " + route);
-                            }
-                            mCallbackHandler.post(CallbackHandler.MSG_ROUTE_ADDED, route);
-                        }
-                        for (Pair<RouteInfo, MediaRouteDescriptor> pair : updatedGroups) {
-                            RouteInfo route = pair.first;
-                            if (updateRouteDescriptorAndNotify(route, pair.second) != 0) {
-                                if (route == mSelectedRoute) {
-                                    selectedRouteDescriptorChanged = true;
-                                }
-                            }
-                        }
-                    } else {
-                        Log.w(TAG, "Ignoring invalid provider descriptor: " + providerDescriptor);
-                    }
-                }
-
-                // Dispose all remaining routes that do not have matching descriptors.
-                for (int i = provider.mRoutes.size() - 1; i >= targetIndex; i--) {
-                    // 1. Delete the route's contents.
-                    RouteInfo route = provider.mRoutes.get(i);
-                    route.maybeUpdateDescriptor(null);
-                    // 2. Remove the route from the list.
-                    mRoutes.remove(route);
-                }
-
-                // Update the selected route if needed.
-                updateSelectedRouteIfNeeded(selectedRouteDescriptorChanged);
-
-                // Now notify clients about routes that were removed.
-                // We do this after updating the selected route to ensure
-                // that the framework media router observes the new route
-                // selection before the removal since removing the currently
-                // selected route may have side-effects.
-                for (int i = provider.mRoutes.size() - 1; i >= targetIndex; i--) {
-                    RouteInfo route = provider.mRoutes.remove(i);
-                    if (DEBUG) {
-                        Log.d(TAG, "Route removed: " + route);
-                    }
-                    mCallbackHandler.post(CallbackHandler.MSG_ROUTE_REMOVED, route);
-                }
-
-                // Notify provider changed.
-                if (DEBUG) {
-                    Log.d(TAG, "Provider changed: " + provider);
-                }
-                mCallbackHandler.post(CallbackHandler.MSG_PROVIDER_CHANGED, provider);
-            }
-        }
-
-        private int updateRouteDescriptorAndNotify(RouteInfo route,
-                MediaRouteDescriptor routeDescriptor) {
-            int changes = route.maybeUpdateDescriptor(routeDescriptor);
-            if (changes != 0) {
-                if ((changes & RouteInfo.CHANGE_GENERAL) != 0) {
-                    if (DEBUG) {
-                        Log.d(TAG, "Route changed: " + route);
-                    }
-                    mCallbackHandler.post(
-                            CallbackHandler.MSG_ROUTE_CHANGED, route);
-                }
-                if ((changes & RouteInfo.CHANGE_VOLUME) != 0) {
-                    if (DEBUG) {
-                        Log.d(TAG, "Route volume changed: " + route);
-                    }
-                    mCallbackHandler.post(
-                            CallbackHandler.MSG_ROUTE_VOLUME_CHANGED, route);
-                }
-                if ((changes & RouteInfo.CHANGE_PRESENTATION_DISPLAY) != 0) {
-                    if (DEBUG) {
-                        Log.d(TAG, "Route presentation display changed: "
-                                + route);
-                    }
-                    mCallbackHandler.post(CallbackHandler.
-                            MSG_ROUTE_PRESENTATION_DISPLAY_CHANGED, route);
-                }
-            }
-            return changes;
-        }
-
-        private String assignRouteUniqueId(ProviderInfo provider, String routeDescriptorId) {
-            // Although route descriptor ids are unique within a provider, it's
-            // possible for there to be two providers with the same package name.
-            // Therefore we must dedupe the composite id.
-            String componentName = provider.getComponentName().flattenToShortString();
-            String uniqueId = componentName + ":" + routeDescriptorId;
-            if (findRouteByUniqueId(uniqueId) < 0) {
-                mUniqueIdMap.put(new Pair<>(componentName, routeDescriptorId), uniqueId);
-                return uniqueId;
-            }
-            Log.w(TAG, "Either " + routeDescriptorId + " isn't unique in " + componentName
-                    + " or we're trying to assign a unique ID for an already added route");
-            for (int i = 2; ; i++) {
-                String newUniqueId = String.format(Locale.US, "%s_%d", uniqueId, i);
-                if (findRouteByUniqueId(newUniqueId) < 0) {
-                    mUniqueIdMap.put(new Pair<>(componentName, routeDescriptorId), newUniqueId);
-                    return newUniqueId;
-                }
-            }
-        }
-
-        private int findRouteByUniqueId(String uniqueId) {
-            final int count = mRoutes.size();
-            for (int i = 0; i < count; i++) {
-                if (mRoutes.get(i).mUniqueId.equals(uniqueId)) {
-                    return i;
-                }
-            }
-            return -1;
-        }
-
-        private String getUniqueId(ProviderInfo provider, String routeDescriptorId) {
-            String componentName = provider.getComponentName().flattenToShortString();
-            return mUniqueIdMap.get(new Pair<>(componentName, routeDescriptorId));
-        }
-
-        private void updateSelectedRouteIfNeeded(boolean selectedRouteDescriptorChanged) {
-            // Update default route.
-            if (mDefaultRoute != null && !mDefaultRoute.isSelectable()) {
-                Log.i(TAG, "Clearing the default route because it "
-                        + "is no longer selectable: " + mDefaultRoute);
-                mDefaultRoute = null;
-            }
-            if (mDefaultRoute == null && !mRoutes.isEmpty()) {
-                for (RouteInfo route : mRoutes) {
-                    if (isSystemDefaultRoute(route) && route.isSelectable()) {
-                        mDefaultRoute = route;
-                        Log.i(TAG, "Found default route: " + mDefaultRoute);
-                        break;
-                    }
-                }
-            }
-
-            // Update bluetooth route.
-            if (mBluetoothRoute != null && !mBluetoothRoute.isSelectable()) {
-                Log.i(TAG, "Clearing the bluetooth route because it "
-                        + "is no longer selectable: " + mBluetoothRoute);
-                mBluetoothRoute = null;
-            }
-            if (mBluetoothRoute == null && !mRoutes.isEmpty()) {
-                for (RouteInfo route : mRoutes) {
-                    if (isSystemLiveAudioOnlyRoute(route) && route.isSelectable()) {
-                        mBluetoothRoute = route;
-                        Log.i(TAG, "Found bluetooth route: " + mBluetoothRoute);
-                        break;
-                    }
-                }
-            }
-
-            // Update selected route.
-            if (mSelectedRoute == null || !mSelectedRoute.isSelectable()) {
-                Log.i(TAG, "Unselecting the current route because it "
-                        + "is no longer selectable: " + mSelectedRoute);
-                setSelectedRouteInternal(chooseFallbackRoute(),
-                        MediaRouter.UNSELECT_REASON_UNKNOWN);
-            } else if (selectedRouteDescriptorChanged) {
-                // In case the selected route is a route group, select/unselect route controllers
-                // for the added/removed route members.
-                if (mSelectedRoute instanceof RouteGroup) {
-                    List<RouteInfo> routes = ((RouteGroup) mSelectedRoute).getRoutes();
-                    // Build a set of descriptor IDs for the new route group.
-                    Set<String> idSet = new HashSet<>();
-                    for (RouteInfo route : routes) {
-                        idSet.add(route.mDescriptorId);
-                    }
-                    // Unselect route controllers for the removed routes.
-                    Iterator<Map.Entry<String, RouteController>> iter =
-                            mRouteControllerMap.entrySet().iterator();
-                    while (iter.hasNext()) {
-                        Map.Entry<String, RouteController> entry = iter.next();
-                        if (!idSet.contains(entry.getKey())) {
-                            RouteController controller = entry.getValue();
-                            controller.onUnselect();
-                            controller.onRelease();
-                            iter.remove();
-                        }
-                    }
-                    // Select route controllers for the added routes.
-                    for (RouteInfo route : routes) {
-                        if (!mRouteControllerMap.containsKey(route.mDescriptorId)) {
-                            RouteController controller = route.getProviderInstance()
-                                    .onCreateRouteController(
-                                            route.mDescriptorId, mSelectedRoute.mDescriptorId);
-                            controller.onSelect();
-                            mRouteControllerMap.put(route.mDescriptorId, controller);
-                        }
-                    }
-                }
-                // Update the playback info because the properties of the route have changed.
-                updatePlaybackInfoFromSelectedRoute();
-            }
-        }
-
-        RouteInfo chooseFallbackRoute() {
-            // When the current route is removed or no longer selectable,
-            // we want to revert to a live audio route if there is
-            // one (usually Bluetooth A2DP).  Failing that, use
-            // the default route.
-            for (RouteInfo route : mRoutes) {
-                if (route != mDefaultRoute
-                        && isSystemLiveAudioOnlyRoute(route)
-                        && route.isSelectable()) {
-                    return route;
-                }
-            }
-            return mDefaultRoute;
-        }
-
-        private boolean isSystemLiveAudioOnlyRoute(RouteInfo route) {
-            return route.getProviderInstance() == mSystemProvider
-                    && route.supportsControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO)
-                    && !route.supportsControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO);
-        }
-
-        private boolean isSystemDefaultRoute(RouteInfo route) {
-            return route.getProviderInstance() == mSystemProvider
-                    && route.mDescriptorId.equals(
-                            SystemMediaRouteProvider.DEFAULT_ROUTE_ID);
-        }
-
-        private void setSelectedRouteInternal(@NonNull RouteInfo route, int unselectReason) {
-            // TODO: Remove the following logging when no longer needed.
-            if (sGlobal == null || (mBluetoothRoute != null && route.isDefault())) {
-                final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
-                StringBuilder sb = new StringBuilder();
-                // callStack[3] is the caller of this method.
-                for (int i = 3; i < callStack.length; i++) {
-                    StackTraceElement caller = callStack[i];
-                    sb.append(caller.getClassName())
-                            .append(".")
-                            .append(caller.getMethodName())
-                            .append(":")
-                            .append(caller.getLineNumber())
-                            .append("  ");
-                }
-                if (sGlobal == null) {
-                    Log.w(TAG, "setSelectedRouteInternal is called while sGlobal is null: pkgName="
-                            + mApplicationContext.getPackageName() + ", callers=" + sb.toString());
-                } else {
-                    Log.w(TAG, "Default route is selected while a BT route is available: pkgName="
-                            + mApplicationContext.getPackageName() + ", callers=" + sb.toString());
-                }
-            }
-
-            if (mSelectedRoute != route) {
-                if (mSelectedRoute != null) {
-                    if (DEBUG) {
-                        Log.d(TAG, "Route unselected: " + mSelectedRoute + " reason: "
-                                + unselectReason);
-                    }
-                    mCallbackHandler.post(CallbackHandler.MSG_ROUTE_UNSELECTED, mSelectedRoute,
-                            unselectReason);
-                    if (mSelectedRouteController != null) {
-                        mSelectedRouteController.onUnselect(unselectReason);
-                        mSelectedRouteController.onRelease();
-                        mSelectedRouteController = null;
-                    }
-                    if (!mRouteControllerMap.isEmpty()) {
-                        for (RouteController controller : mRouteControllerMap.values()) {
-                            controller.onUnselect(unselectReason);
-                            controller.onRelease();
-                        }
-                        mRouteControllerMap.clear();
-                    }
-                }
-
-                mSelectedRoute = route;
-                mSelectedRouteController = route.getProviderInstance().onCreateRouteController(
-                        route.mDescriptorId);
-                if (mSelectedRouteController != null) {
-                    mSelectedRouteController.onSelect();
-                }
-                if (DEBUG) {
-                    Log.d(TAG, "Route selected: " + mSelectedRoute);
-                }
-                mCallbackHandler.post(CallbackHandler.MSG_ROUTE_SELECTED, mSelectedRoute);
-
-                if (mSelectedRoute instanceof RouteGroup) {
-                    List<RouteInfo> routes = ((RouteGroup) mSelectedRoute).getRoutes();
-                    mRouteControllerMap.clear();
-                    for (RouteInfo r : routes) {
-                        RouteController controller =
-                                r.getProviderInstance().onCreateRouteController(
-                                        r.mDescriptorId, mSelectedRoute.mDescriptorId);
-                        controller.onSelect();
-                        mRouteControllerMap.put(r.mDescriptorId, controller);
-                    }
-                }
-
-                updatePlaybackInfoFromSelectedRoute();
-            }
-        }
-
-        @Override
-        public void onSystemRouteSelectedByDescriptorId(String id) {
-            // System route is selected, do not sync the route we selected before.
-            mCallbackHandler.removeMessages(CallbackHandler.MSG_ROUTE_SELECTED);
-            int providerIndex = findProviderInfo(mSystemProvider);
-            if (providerIndex >= 0) {
-                ProviderInfo provider = mProviders.get(providerIndex);
-                int routeIndex = provider.findRouteByDescriptorId(id);
-                if (routeIndex >= 0) {
-                    provider.mRoutes.get(routeIndex).select();
-                }
-            }
-        }
-
-        public void addRemoteControlClient(Object rcc) {
-            int index = findRemoteControlClientRecord(rcc);
-            if (index < 0) {
-                RemoteControlClientRecord record = new RemoteControlClientRecord(rcc);
-                mRemoteControlClients.add(record);
-            }
-        }
-
-        public void removeRemoteControlClient(Object rcc) {
-            int index = findRemoteControlClientRecord(rcc);
-            if (index >= 0) {
-                RemoteControlClientRecord record = mRemoteControlClients.remove(index);
-                record.disconnect();
-            }
-        }
-
-        public void setMediaSession(Object session) {
-            setMediaSessionRecord(session != null ? new MediaSessionRecord(session) : null);
-        }
-
-        public void setMediaSessionCompat(final MediaSessionCompat session) {
-            mCompatSession = session;
-            if (android.os.Build.VERSION.SDK_INT >= 21) {
-                setMediaSessionRecord(session != null ? new MediaSessionRecord(session) : null);
-            } else if (android.os.Build.VERSION.SDK_INT >= 14) {
-                if (mRccMediaSession != null) {
-                    removeRemoteControlClient(mRccMediaSession.getRemoteControlClient());
-                    mRccMediaSession.removeOnActiveChangeListener(mSessionActiveListener);
-                }
-                mRccMediaSession = session;
-                if (session != null) {
-                    session.addOnActiveChangeListener(mSessionActiveListener);
-                    if (session.isActive()) {
-                        addRemoteControlClient(session.getRemoteControlClient());
-                    }
-                }
-            }
-        }
-
-        private void setMediaSessionRecord(MediaSessionRecord mediaSessionRecord) {
-            if (mMediaSession != null) {
-                mMediaSession.clearVolumeHandling();
-            }
-            mMediaSession = mediaSessionRecord;
-            if (mediaSessionRecord != null) {
-                updatePlaybackInfoFromSelectedRoute();
-            }
-        }
-
-        public MediaSessionCompat.Token getMediaSessionToken() {
-            if (mMediaSession != null) {
-                return mMediaSession.getToken();
-            } else if (mCompatSession != null) {
-                return mCompatSession.getSessionToken();
-            }
-            return null;
-        }
-
-        private int findRemoteControlClientRecord(Object rcc) {
-            final int count = mRemoteControlClients.size();
-            for (int i = 0; i < count; i++) {
-                RemoteControlClientRecord record = mRemoteControlClients.get(i);
-                if (record.getRemoteControlClient() == rcc) {
-                    return i;
-                }
-            }
-            return -1;
-        }
-
-        private void updatePlaybackInfoFromSelectedRoute() {
-            if (mSelectedRoute != null) {
-                mPlaybackInfo.volume = mSelectedRoute.getVolume();
-                mPlaybackInfo.volumeMax = mSelectedRoute.getVolumeMax();
-                mPlaybackInfo.volumeHandling = mSelectedRoute.getVolumeHandling();
-                mPlaybackInfo.playbackStream = mSelectedRoute.getPlaybackStream();
-                mPlaybackInfo.playbackType = mSelectedRoute.getPlaybackType();
-
-                final int count = mRemoteControlClients.size();
-                for (int i = 0; i < count; i++) {
-                    RemoteControlClientRecord record = mRemoteControlClients.get(i);
-                    record.updatePlaybackInfo();
-                }
-                if (mMediaSession != null) {
-                    if (mSelectedRoute == getDefaultRoute()
-                            || mSelectedRoute == getBluetoothRoute()) {
-                        // Local route
-                        mMediaSession.clearVolumeHandling();
-                    } else {
-                        @VolumeProviderCompat.ControlType int controlType =
-                                VolumeProviderCompat.VOLUME_CONTROL_FIXED;
-                        if (mPlaybackInfo.volumeHandling
-                                == MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE) {
-                            controlType = VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE;
-                        }
-                        mMediaSession.configureVolume(controlType, mPlaybackInfo.volumeMax,
-                                mPlaybackInfo.volume);
-                    }
-                }
-            } else {
-                if (mMediaSession != null) {
-                    mMediaSession.clearVolumeHandling();
-                }
-            }
-        }
-
-        private final class ProviderCallback extends MediaRouteProvider.Callback {
-            ProviderCallback() {
-            }
-
-            @Override
-            public void onDescriptorChanged(MediaRouteProvider provider,
-                    MediaRouteProviderDescriptor descriptor) {
-                updateProviderDescriptor(provider, descriptor);
-            }
-        }
-
-        private final class MediaSessionRecord {
-            private final MediaSessionCompat mMsCompat;
-
-            private @VolumeProviderCompat.ControlType int mControlType;
-            private int mMaxVolume;
-            private VolumeProviderCompat mVpCompat;
-
-            public MediaSessionRecord(Object mediaSession) {
-                mMsCompat = MediaSessionCompat.fromMediaSession(mApplicationContext, mediaSession);
-            }
-
-            public MediaSessionRecord(MediaSessionCompat mediaSessionCompat) {
-                mMsCompat = mediaSessionCompat;
-            }
-
-            public void configureVolume(@VolumeProviderCompat.ControlType int controlType,
-                    int max, int current) {
-                if (mVpCompat != null && controlType == mControlType && max == mMaxVolume) {
-                    // If we haven't changed control type or max just set the
-                    // new current volume
-                    mVpCompat.setCurrentVolume(current);
-                } else {
-                    // Otherwise create a new provider and update
-                    mVpCompat = new VolumeProviderCompat(controlType, max, current) {
-                        @Override
-                        public void onSetVolumeTo(final int volume) {
-                            mCallbackHandler.post(new Runnable() {
-                                @Override
-                                public void run() {
-                                    if (mSelectedRoute != null) {
-                                        mSelectedRoute.requestSetVolume(volume);
-                                    }
-                                }
-                            });
-                        }
-
-                        @Override
-                        public void onAdjustVolume(final int direction) {
-                            mCallbackHandler.post(new Runnable() {
-                                @Override
-                                public void run() {
-                                    if (mSelectedRoute != null) {
-                                        mSelectedRoute.requestUpdateVolume(direction);
-                                    }
-                                }
-                            });
-                        }
-                    };
-                    mMsCompat.setPlaybackToRemote(mVpCompat);
-                }
-            }
-
-            public void clearVolumeHandling() {
-                mMsCompat.setPlaybackToLocal(mPlaybackInfo.playbackStream);
-                mVpCompat = null;
-            }
-
-            public MediaSessionCompat.Token getToken() {
-                return mMsCompat.getSessionToken();
-            }
-        }
-
-        private final class RemoteControlClientRecord
-                implements RemoteControlClientCompat.VolumeCallback {
-            private final RemoteControlClientCompat mRccCompat;
-            private boolean mDisconnected;
-
-            public RemoteControlClientRecord(Object rcc) {
-                mRccCompat = RemoteControlClientCompat.obtain(mApplicationContext, rcc);
-                mRccCompat.setVolumeCallback(this);
-                updatePlaybackInfo();
-            }
-
-            public Object getRemoteControlClient() {
-                return mRccCompat.getRemoteControlClient();
-            }
-
-            public void disconnect() {
-                mDisconnected = true;
-                mRccCompat.setVolumeCallback(null);
-            }
-
-            public void updatePlaybackInfo() {
-                mRccCompat.setPlaybackInfo(mPlaybackInfo);
-            }
-
-            @Override
-            public void onVolumeSetRequest(int volume) {
-                if (!mDisconnected && mSelectedRoute != null) {
-                    mSelectedRoute.requestSetVolume(volume);
-                }
-            }
-
-            @Override
-            public void onVolumeUpdateRequest(int direction) {
-                if (!mDisconnected && mSelectedRoute != null) {
-                    mSelectedRoute.requestUpdateVolume(direction);
-                }
-            }
-        }
-
-        private final class CallbackHandler extends Handler {
-            private final ArrayList<CallbackRecord> mTempCallbackRecords =
-                    new ArrayList<CallbackRecord>();
-
-            private static final int MSG_TYPE_MASK = 0xff00;
-            private static final int MSG_TYPE_ROUTE = 0x0100;
-            private static final int MSG_TYPE_PROVIDER = 0x0200;
-
-            public static final int MSG_ROUTE_ADDED = MSG_TYPE_ROUTE | 1;
-            public static final int MSG_ROUTE_REMOVED = MSG_TYPE_ROUTE | 2;
-            public static final int MSG_ROUTE_CHANGED = MSG_TYPE_ROUTE | 3;
-            public static final int MSG_ROUTE_VOLUME_CHANGED = MSG_TYPE_ROUTE | 4;
-            public static final int MSG_ROUTE_PRESENTATION_DISPLAY_CHANGED = MSG_TYPE_ROUTE | 5;
-            public static final int MSG_ROUTE_SELECTED = MSG_TYPE_ROUTE | 6;
-            public static final int MSG_ROUTE_UNSELECTED = MSG_TYPE_ROUTE | 7;
-
-            public static final int MSG_PROVIDER_ADDED = MSG_TYPE_PROVIDER | 1;
-            public static final int MSG_PROVIDER_REMOVED = MSG_TYPE_PROVIDER | 2;
-            public static final int MSG_PROVIDER_CHANGED = MSG_TYPE_PROVIDER | 3;
-
-            CallbackHandler() {
-            }
-
-            public void post(int msg, Object obj) {
-                obtainMessage(msg, obj).sendToTarget();
-            }
-
-            public void post(int msg, Object obj, int arg) {
-                Message message = obtainMessage(msg, obj);
-                message.arg1 = arg;
-                message.sendToTarget();
-            }
-
-            @Override
-            public void handleMessage(Message msg) {
-                final int what = msg.what;
-                final Object obj = msg.obj;
-                final int arg = msg.arg1;
-
-                if (what == MSG_ROUTE_CHANGED
-                        && getSelectedRoute().getId().equals(((RouteInfo) obj).getId())) {
-                    updateSelectedRouteIfNeeded(true);
-                }
-
-                // Synchronize state with the system media router.
-                syncWithSystemProvider(what, obj);
-
-                // Invoke all registered callbacks.
-                // Build a list of callbacks before invoking them in case callbacks
-                // are added or removed during dispatch.
-                try {
-                    for (int i = mRouters.size(); --i >= 0; ) {
-                        MediaRouter router = mRouters.get(i).get();
-                        if (router == null) {
-                            mRouters.remove(i);
-                        } else {
-                            mTempCallbackRecords.addAll(router.mCallbackRecords);
-                        }
-                    }
-
-                    final int callbackCount = mTempCallbackRecords.size();
-                    for (int i = 0; i < callbackCount; i++) {
-                        invokeCallback(mTempCallbackRecords.get(i), what, obj, arg);
-                    }
-                } finally {
-                    mTempCallbackRecords.clear();
-                }
-            }
-
-            private void syncWithSystemProvider(int what, Object obj) {
-                switch (what) {
-                    case MSG_ROUTE_ADDED:
-                        mSystemProvider.onSyncRouteAdded((RouteInfo) obj);
-                        break;
-                    case MSG_ROUTE_REMOVED:
-                        mSystemProvider.onSyncRouteRemoved((RouteInfo) obj);
-                        break;
-                    case MSG_ROUTE_CHANGED:
-                        mSystemProvider.onSyncRouteChanged((RouteInfo) obj);
-                        break;
-                    case MSG_ROUTE_SELECTED:
-                        mSystemProvider.onSyncRouteSelected((RouteInfo) obj);
-                        break;
-                }
-            }
-
-            private void invokeCallback(CallbackRecord record, int what, Object obj, int arg) {
-                final MediaRouter router = record.mRouter;
-                final MediaRouter.Callback callback = record.mCallback;
-                switch (what & MSG_TYPE_MASK) {
-                    case MSG_TYPE_ROUTE: {
-                        final RouteInfo route = (RouteInfo)obj;
-                        if (!record.filterRouteEvent(route)) {
-                            break;
-                        }
-                        switch (what) {
-                            case MSG_ROUTE_ADDED:
-                                callback.onRouteAdded(router, route);
-                                break;
-                            case MSG_ROUTE_REMOVED:
-                                callback.onRouteRemoved(router, route);
-                                break;
-                            case MSG_ROUTE_CHANGED:
-                                callback.onRouteChanged(router, route);
-                                break;
-                            case MSG_ROUTE_VOLUME_CHANGED:
-                                callback.onRouteVolumeChanged(router, route);
-                                break;
-                            case MSG_ROUTE_PRESENTATION_DISPLAY_CHANGED:
-                                callback.onRoutePresentationDisplayChanged(router, route);
-                                break;
-                            case MSG_ROUTE_SELECTED:
-                                callback.onRouteSelected(router, route);
-                                break;
-                            case MSG_ROUTE_UNSELECTED:
-                                callback.onRouteUnselected(router, route, arg);
-                                break;
-                        }
-                        break;
-                    }
-                    case MSG_TYPE_PROVIDER: {
-                        final ProviderInfo provider = (ProviderInfo)obj;
-                        switch (what) {
-                            case MSG_PROVIDER_ADDED:
-                                callback.onProviderAdded(router, provider);
-                                break;
-                            case MSG_PROVIDER_REMOVED:
-                                callback.onProviderRemoved(router, provider);
-                                break;
-                            case MSG_PROVIDER_CHANGED:
-                                callback.onProviderChanged(router, provider);
-                                break;
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaSessionStatus.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaSessionStatus.java
deleted file mode 100644
index 3206596..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaSessionStatus.java
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.media;
-
-import android.app.PendingIntent;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.support.v4.util.TimeUtils;
-
-/**
- * Describes the playback status of a media session.
- * <p>
- * This class is part of the remote playback protocol described by the
- * {@link MediaControlIntent MediaControlIntent} class.
- * </p><p>
- * When a media session is created, it is initially in the
- * {@link #SESSION_STATE_ACTIVE active} state.  When the media session ends
- * normally, it transitions to the {@link #SESSION_STATE_ENDED ended} state.
- * If the media session is invalidated due to another session forcibly taking
- * control of the route, then it transitions to the
- * {@link #SESSION_STATE_INVALIDATED invalidated} state.
- * Refer to the documentation of each state for an explanation of its meaning.
- * </p><p>
- * To monitor session status, the application should supply a {@link PendingIntent} to use as the
- * {@link MediaControlIntent#EXTRA_SESSION_STATUS_UPDATE_RECEIVER session status update receiver}
- * for a given {@link MediaControlIntent#ACTION_START_SESSION session start request}.
- * </p><p>
- * This object is immutable once created using a {@link Builder} instance.
- * </p>
- */
-public final class MediaSessionStatus {
-    static final String KEY_TIMESTAMP = "timestamp";
-    static final String KEY_SESSION_STATE = "sessionState";
-    static final String KEY_QUEUE_PAUSED = "queuePaused";
-    static final String KEY_EXTRAS = "extras";
-
-    final Bundle mBundle;
-
-    /**
-     * Session state: Active.
-     * <p>
-     * Indicates that the media session is active and in control of the route.
-     * </p>
-     */
-    public static final int SESSION_STATE_ACTIVE = 0;
-
-    /**
-     * Session state: Ended.
-     * <p>
-     * Indicates that the media session was ended normally using the
-     * {@link MediaControlIntent#ACTION_END_SESSION end session} action.
-     * </p><p>
-     * A terminated media session cannot be used anymore.  To play more media, the
-     * application must start a new session.
-     * </p>
-     */
-    public static final int SESSION_STATE_ENDED = 1;
-
-    /**
-     * Session state: Invalidated.
-     * <p>
-     * Indicates that the media session was invalidated involuntarily due to
-     * another session taking control of the route.
-     * </p><p>
-     * An invalidated media session cannot be used anymore.  To play more media, the
-     * application must start a new session.
-     * </p>
-     */
-    public static final int SESSION_STATE_INVALIDATED = 2;
-
-    MediaSessionStatus(Bundle bundle) {
-        mBundle = bundle;
-    }
-
-    /**
-     * Gets the timestamp associated with the status information in
-     * milliseconds since boot in the {@link SystemClock#elapsedRealtime} time base.
-     *
-     * @return The status timestamp in the {@link SystemClock#elapsedRealtime()} time base.
-     */
-    public long getTimestamp() {
-        return mBundle.getLong(KEY_TIMESTAMP);
-    }
-
-    /**
-     * Gets the session state.
-     *
-     * @return The session state.  One of {@link #SESSION_STATE_ACTIVE},
-     * {@link #SESSION_STATE_ENDED}, or {@link #SESSION_STATE_INVALIDATED}.
-     */
-    public int getSessionState() {
-        return mBundle.getInt(KEY_SESSION_STATE, SESSION_STATE_INVALIDATED);
-    }
-
-    /**
-     * Returns true if the session's queue is paused.
-     *
-     * @return True if the session's queue is paused.
-     */
-    public boolean isQueuePaused() {
-        return mBundle.getBoolean(KEY_QUEUE_PAUSED);
-    }
-
-    /**
-     * Gets a bundle of extras for this status object.
-     * The extras will be ignored by the media router but they may be used
-     * by applications.
-     */
-    public Bundle getExtras() {
-        return mBundle.getBundle(KEY_EXTRAS);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder result = new StringBuilder();
-        result.append("MediaSessionStatus{ ");
-        result.append("timestamp=");
-        TimeUtils.formatDuration(SystemClock.elapsedRealtime() - getTimestamp(), result);
-        result.append(" ms ago");
-        result.append(", sessionState=").append(sessionStateToString(getSessionState()));
-        result.append(", queuePaused=").append(isQueuePaused());
-        result.append(", extras=").append(getExtras());
-        result.append(" }");
-        return result.toString();
-    }
-
-    private static String sessionStateToString(int sessionState) {
-        switch (sessionState) {
-            case SESSION_STATE_ACTIVE:
-                return "active";
-            case SESSION_STATE_ENDED:
-                return "ended";
-            case SESSION_STATE_INVALIDATED:
-                return "invalidated";
-        }
-        return Integer.toString(sessionState);
-    }
-
-    /**
-     * Converts this object to a bundle for serialization.
-     *
-     * @return The contents of the object represented as a bundle.
-     */
-    public Bundle asBundle() {
-        return mBundle;
-    }
-
-    /**
-     * Creates an instance from a bundle.
-     *
-     * @param bundle The bundle, or null if none.
-     * @return The new instance, or null if the bundle was null.
-     */
-    public static MediaSessionStatus fromBundle(Bundle bundle) {
-        return bundle != null ? new MediaSessionStatus(bundle) : null;
-    }
-
-    /**
-     * Builder for {@link MediaSessionStatus media session status objects}.
-     */
-    public static final class Builder {
-        private final Bundle mBundle;
-
-        /**
-         * Creates a media session status builder using the current time as the
-         * reference timestamp.
-         *
-         * @param sessionState The session state.
-         */
-        public Builder(int sessionState) {
-            mBundle = new Bundle();
-            setTimestamp(SystemClock.elapsedRealtime());
-            setSessionState(sessionState);
-        }
-
-        /**
-         * Creates a media session status builder whose initial contents are
-         * copied from an existing status.
-         */
-        public Builder(MediaSessionStatus status) {
-            if (status == null) {
-                throw new IllegalArgumentException("status must not be null");
-            }
-
-            mBundle = new Bundle(status.mBundle);
-        }
-
-        /**
-         * Sets the timestamp associated with the status information in
-         * milliseconds since boot in the {@link SystemClock#elapsedRealtime} time base.
-         */
-        public Builder setTimestamp(long elapsedRealtimeTimestamp) {
-            mBundle.putLong(KEY_TIMESTAMP, elapsedRealtimeTimestamp);
-            return this;
-        }
-
-        /**
-         * Sets the session state.
-         */
-        public Builder setSessionState(int sessionState) {
-            mBundle.putInt(KEY_SESSION_STATE, sessionState);
-            return this;
-        }
-
-        /**
-         * Sets whether the queue is paused.
-         */
-        public Builder setQueuePaused(boolean queuePaused) {
-            mBundle.putBoolean(KEY_QUEUE_PAUSED, queuePaused);
-            return this;
-        }
-
-        /**
-         * Sets a bundle of extras for this status object.
-         * The extras will be ignored by the media router but they may be used
-         * by applications.
-         */
-        public Builder setExtras(Bundle extras) {
-            mBundle.putBundle(KEY_EXTRAS, extras);
-            return this;
-        }
-
-        /**
-         * Builds the {@link MediaSessionStatus media session status object}.
-         */
-        public MediaSessionStatus build() {
-            return new MediaSessionStatus(mBundle);
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/RegisteredMediaRouteProvider.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/RegisteredMediaRouteProvider.java
deleted file mode 100644
index 98e4e28..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/RegisteredMediaRouteProvider.java
+++ /dev/null
@@ -1,741 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.media;
-
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.CLIENT_DATA_ROUTE_ID;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .CLIENT_DATA_ROUTE_LIBRARY_GROUP;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .CLIENT_DATA_UNSELECT_REASON;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.CLIENT_DATA_VOLUME;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .CLIENT_MSG_CREATE_ROUTE_CONTROLLER;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.CLIENT_MSG_REGISTER;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .CLIENT_MSG_RELEASE_ROUTE_CONTROLLER;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .CLIENT_MSG_ROUTE_CONTROL_REQUEST;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.CLIENT_MSG_SELECT_ROUTE;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .CLIENT_MSG_SET_DISCOVERY_REQUEST;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .CLIENT_MSG_SET_ROUTE_VOLUME;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.CLIENT_MSG_UNREGISTER;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .CLIENT_MSG_UNSELECT_ROUTE;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .CLIENT_MSG_UPDATE_ROUTE_VOLUME;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.CLIENT_VERSION_CURRENT;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.SERVICE_DATA_ERROR;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .SERVICE_MSG_CONTROL_REQUEST_FAILED;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .SERVICE_MSG_CONTROL_REQUEST_SUCCEEDED;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .SERVICE_MSG_DESCRIPTOR_CHANGED;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .SERVICE_MSG_GENERIC_FAILURE;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
-        .SERVICE_MSG_GENERIC_SUCCESS;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.SERVICE_MSG_REGISTERED;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.SERVICE_VERSION_1;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.isValidRemoteMessenger;
-
-import android.annotation.NonNull;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.Bundle;
-import android.os.DeadObjectException;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.IBinder.DeathRecipient;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.util.Log;
-import android.util.SparseArray;
-
-import com.android.support.mediarouter.media.MediaRouter.ControlRequestCallback;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Maintains a connection to a particular media route provider service.
- */
-final class RegisteredMediaRouteProvider extends MediaRouteProvider
-        implements ServiceConnection {
-    static final String TAG = "MediaRouteProviderProxy";  // max. 23 chars
-    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    private final ComponentName mComponentName;
-    final PrivateHandler mPrivateHandler;
-    private final ArrayList<Controller> mControllers = new ArrayList<Controller>();
-
-    private boolean mStarted;
-    private boolean mBound;
-    private Connection mActiveConnection;
-    private boolean mConnectionReady;
-
-    public RegisteredMediaRouteProvider(Context context, ComponentName componentName) {
-        super(context, new ProviderMetadata(componentName));
-
-        mComponentName = componentName;
-        mPrivateHandler = new PrivateHandler();
-    }
-
-    @Override
-    public RouteController onCreateRouteController(@NonNull String routeId) {
-        if (routeId == null) {
-            throw new IllegalArgumentException("routeId cannot be null");
-        }
-        return createRouteController(routeId, null);
-    }
-
-    @Override
-    public RouteController onCreateRouteController(
-            @NonNull String routeId, @NonNull String routeGroupId) {
-        if (routeId == null) {
-            throw new IllegalArgumentException("routeId cannot be null");
-        }
-        if (routeGroupId == null) {
-            throw new IllegalArgumentException("routeGroupId cannot be null");
-        }
-        return createRouteController(routeId, routeGroupId);
-    }
-
-    @Override
-    public void onDiscoveryRequestChanged(MediaRouteDiscoveryRequest request) {
-        if (mConnectionReady) {
-            mActiveConnection.setDiscoveryRequest(request);
-        }
-        updateBinding();
-    }
-
-    @Override
-    public void onServiceConnected(ComponentName name, IBinder service) {
-        if (DEBUG) {
-            Log.d(TAG, this + ": Connected");
-        }
-
-        if (mBound) {
-            disconnect();
-
-            Messenger messenger = (service != null ? new Messenger(service) : null);
-            if (isValidRemoteMessenger(messenger)) {
-                Connection connection = new Connection(messenger);
-                if (connection.register()) {
-                    mActiveConnection = connection;
-                } else {
-                    if (DEBUG) {
-                        Log.d(TAG, this + ": Registration failed");
-                    }
-                }
-            } else {
-                Log.e(TAG, this + ": Service returned invalid messenger binder");
-            }
-        }
-    }
-
-    @Override
-    public void onServiceDisconnected(ComponentName name) {
-        if (DEBUG) {
-            Log.d(TAG, this + ": Service disconnected");
-        }
-        disconnect();
-    }
-
-    @Override
-    public String toString() {
-        return "Service connection " + mComponentName.flattenToShortString();
-    }
-
-    public boolean hasComponentName(String packageName, String className) {
-        return mComponentName.getPackageName().equals(packageName)
-                && mComponentName.getClassName().equals(className);
-    }
-
-    public void start() {
-        if (!mStarted) {
-            if (DEBUG) {
-                Log.d(TAG, this + ": Starting");
-            }
-
-            mStarted = true;
-            updateBinding();
-        }
-    }
-
-    public void stop() {
-        if (mStarted) {
-            if (DEBUG) {
-                Log.d(TAG, this + ": Stopping");
-            }
-
-            mStarted = false;
-            updateBinding();
-        }
-    }
-
-    public void rebindIfDisconnected() {
-        if (mActiveConnection == null && shouldBind()) {
-            unbind();
-            bind();
-        }
-    }
-
-    private void updateBinding() {
-        if (shouldBind()) {
-            bind();
-        } else {
-            unbind();
-        }
-    }
-
-    private boolean shouldBind() {
-        if (mStarted) {
-            // Bind whenever there is a discovery request.
-            if (getDiscoveryRequest() != null) {
-                return true;
-            }
-
-            // Bind whenever the application has an active route controller.
-            // This means that one of this provider's routes is selected.
-            if (!mControllers.isEmpty()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private void bind() {
-        if (!mBound) {
-            if (DEBUG) {
-                Log.d(TAG, this + ": Binding");
-            }
-
-            Intent service = new Intent(MediaRouteProviderProtocol.SERVICE_INTERFACE);
-            service.setComponent(mComponentName);
-            try {
-                mBound = getContext().bindService(service, this, Context.BIND_AUTO_CREATE);
-                if (!mBound && DEBUG) {
-                    Log.d(TAG, this + ": Bind failed");
-                }
-            } catch (SecurityException ex) {
-                if (DEBUG) {
-                    Log.d(TAG, this + ": Bind failed", ex);
-                }
-            }
-        }
-    }
-
-    private void unbind() {
-        if (mBound) {
-            if (DEBUG) {
-                Log.d(TAG, this + ": Unbinding");
-            }
-
-            mBound = false;
-            disconnect();
-            getContext().unbindService(this);
-        }
-    }
-
-    private RouteController createRouteController(String routeId, String routeGroupId) {
-        MediaRouteProviderDescriptor descriptor = getDescriptor();
-        if (descriptor != null) {
-            List<MediaRouteDescriptor> routes = descriptor.getRoutes();
-            final int count = routes.size();
-            for (int i = 0; i < count; i++) {
-                final MediaRouteDescriptor route = routes.get(i);
-                if (route.getId().equals(routeId)) {
-                    Controller controller = new Controller(routeId, routeGroupId);
-                    mControllers.add(controller);
-                    if (mConnectionReady) {
-                        controller.attachConnection(mActiveConnection);
-                    }
-                    updateBinding();
-                    return controller;
-                }
-            }
-        }
-        return null;
-    }
-
-    void onConnectionReady(Connection connection) {
-        if (mActiveConnection == connection) {
-            mConnectionReady = true;
-            attachControllersToConnection();
-
-            MediaRouteDiscoveryRequest request = getDiscoveryRequest();
-            if (request != null) {
-                mActiveConnection.setDiscoveryRequest(request);
-            }
-        }
-    }
-
-    void onConnectionDied(Connection connection) {
-        if (mActiveConnection == connection) {
-            if (DEBUG) {
-                Log.d(TAG, this + ": Service connection died");
-            }
-            disconnect();
-        }
-    }
-
-    void onConnectionError(Connection connection, String error) {
-        if (mActiveConnection == connection) {
-            if (DEBUG) {
-                Log.d(TAG, this + ": Service connection error - " + error);
-            }
-            unbind();
-        }
-    }
-
-    void onConnectionDescriptorChanged(Connection connection,
-            MediaRouteProviderDescriptor descriptor) {
-        if (mActiveConnection == connection) {
-            if (DEBUG) {
-                Log.d(TAG, this + ": Descriptor changed, descriptor=" + descriptor);
-            }
-            setDescriptor(descriptor);
-        }
-    }
-
-    private void disconnect() {
-        if (mActiveConnection != null) {
-            setDescriptor(null);
-            mConnectionReady = false;
-            detachControllersFromConnection();
-            mActiveConnection.dispose();
-            mActiveConnection = null;
-        }
-    }
-
-    void onControllerReleased(Controller controller) {
-        mControllers.remove(controller);
-        controller.detachConnection();
-        updateBinding();
-    }
-
-    private void attachControllersToConnection() {
-        int count = mControllers.size();
-        for (int i = 0; i < count; i++) {
-            mControllers.get(i).attachConnection(mActiveConnection);
-        }
-    }
-
-    private void detachControllersFromConnection() {
-        int count = mControllers.size();
-        for (int i = 0; i < count; i++) {
-            mControllers.get(i).detachConnection();
-        }
-    }
-
-    private final class Controller extends RouteController {
-        private final String mRouteId;
-        private final String mRouteGroupId;
-
-        private boolean mSelected;
-        private int mPendingSetVolume = -1;
-        private int mPendingUpdateVolumeDelta;
-
-        private Connection mConnection;
-        private int mControllerId;
-
-        public Controller(String routeId, String routeGroupId) {
-            mRouteId = routeId;
-            mRouteGroupId = routeGroupId;
-        }
-
-        public void attachConnection(Connection connection) {
-            mConnection = connection;
-            mControllerId = connection.createRouteController(mRouteId, mRouteGroupId);
-            if (mSelected) {
-                connection.selectRoute(mControllerId);
-                if (mPendingSetVolume >= 0) {
-                    connection.setVolume(mControllerId, mPendingSetVolume);
-                    mPendingSetVolume = -1;
-                }
-                if (mPendingUpdateVolumeDelta != 0) {
-                    connection.updateVolume(mControllerId, mPendingUpdateVolumeDelta);
-                    mPendingUpdateVolumeDelta = 0;
-                }
-            }
-        }
-
-        public void detachConnection() {
-            if (mConnection != null) {
-                mConnection.releaseRouteController(mControllerId);
-                mConnection = null;
-                mControllerId = 0;
-            }
-        }
-
-        @Override
-        public void onRelease() {
-            onControllerReleased(this);
-        }
-
-        @Override
-        public void onSelect() {
-            mSelected = true;
-            if (mConnection != null) {
-                mConnection.selectRoute(mControllerId);
-            }
-        }
-
-        @Override
-        public void onUnselect() {
-            onUnselect(MediaRouter.UNSELECT_REASON_UNKNOWN);
-        }
-
-        @Override
-        public void onUnselect(int reason) {
-            mSelected = false;
-            if (mConnection != null) {
-                mConnection.unselectRoute(mControllerId, reason);
-            }
-        }
-
-        @Override
-        public void onSetVolume(int volume) {
-            if (mConnection != null) {
-                mConnection.setVolume(mControllerId, volume);
-            } else {
-                mPendingSetVolume = volume;
-                mPendingUpdateVolumeDelta = 0;
-            }
-        }
-
-        @Override
-        public void onUpdateVolume(int delta) {
-            if (mConnection != null) {
-                mConnection.updateVolume(mControllerId, delta);
-            } else {
-                mPendingUpdateVolumeDelta += delta;
-            }
-        }
-
-        @Override
-        public boolean onControlRequest(Intent intent, ControlRequestCallback callback) {
-            if (mConnection != null) {
-                return mConnection.sendControlRequest(mControllerId, intent, callback);
-            }
-            return false;
-        }
-    }
-
-    private final class Connection implements DeathRecipient {
-        private final Messenger mServiceMessenger;
-        private final ReceiveHandler mReceiveHandler;
-        private final Messenger mReceiveMessenger;
-
-        private int mNextRequestId = 1;
-        private int mNextControllerId = 1;
-        private int mServiceVersion; // non-zero when registration complete
-
-        private int mPendingRegisterRequestId;
-        private final SparseArray<ControlRequestCallback> mPendingCallbacks =
-                new SparseArray<ControlRequestCallback>();
-
-        public Connection(Messenger serviceMessenger) {
-            mServiceMessenger = serviceMessenger;
-            mReceiveHandler = new ReceiveHandler(this);
-            mReceiveMessenger = new Messenger(mReceiveHandler);
-        }
-
-        public boolean register() {
-            mPendingRegisterRequestId = mNextRequestId++;
-            if (!sendRequest(CLIENT_MSG_REGISTER,
-                    mPendingRegisterRequestId,
-                    CLIENT_VERSION_CURRENT, null, null)) {
-                return false;
-            }
-
-            try {
-                mServiceMessenger.getBinder().linkToDeath(this, 0);
-                return true;
-            } catch (RemoteException ex) {
-                binderDied();
-            }
-            return false;
-        }
-
-        public void dispose() {
-            sendRequest(CLIENT_MSG_UNREGISTER, 0, 0, null, null);
-            mReceiveHandler.dispose();
-            mServiceMessenger.getBinder().unlinkToDeath(this, 0);
-
-            mPrivateHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    failPendingCallbacks();
-                }
-            });
-        }
-
-        void failPendingCallbacks() {
-            int count = 0;
-            for (int i = 0; i < mPendingCallbacks.size(); i++) {
-                mPendingCallbacks.valueAt(i).onError(null, null);
-            }
-            mPendingCallbacks.clear();
-        }
-
-        public boolean onGenericFailure(int requestId) {
-            if (requestId == mPendingRegisterRequestId) {
-                mPendingRegisterRequestId = 0;
-                onConnectionError(this, "Registration failed");
-            }
-            ControlRequestCallback callback = mPendingCallbacks.get(requestId);
-            if (callback != null) {
-                mPendingCallbacks.remove(requestId);
-                callback.onError(null, null);
-            }
-            return true;
-        }
-
-        public boolean onGenericSuccess(int requestId) {
-            return true;
-        }
-
-        public boolean onRegistered(int requestId, int serviceVersion,
-                Bundle descriptorBundle) {
-            if (mServiceVersion == 0
-                    && requestId == mPendingRegisterRequestId
-                    && serviceVersion >= SERVICE_VERSION_1) {
-                mPendingRegisterRequestId = 0;
-                mServiceVersion = serviceVersion;
-                onConnectionDescriptorChanged(this,
-                        MediaRouteProviderDescriptor.fromBundle(descriptorBundle));
-                onConnectionReady(this);
-                return true;
-            }
-            return false;
-        }
-
-        public boolean onDescriptorChanged(Bundle descriptorBundle) {
-            if (mServiceVersion != 0) {
-                onConnectionDescriptorChanged(this,
-                        MediaRouteProviderDescriptor.fromBundle(descriptorBundle));
-                return true;
-            }
-            return false;
-        }
-
-        public boolean onControlRequestSucceeded(int requestId, Bundle data) {
-            ControlRequestCallback callback = mPendingCallbacks.get(requestId);
-            if (callback != null) {
-                mPendingCallbacks.remove(requestId);
-                callback.onResult(data);
-                return true;
-            }
-            return false;
-        }
-
-        public boolean onControlRequestFailed(int requestId, String error, Bundle data) {
-            ControlRequestCallback callback = mPendingCallbacks.get(requestId);
-            if (callback != null) {
-                mPendingCallbacks.remove(requestId);
-                callback.onError(error, data);
-                return true;
-            }
-            return false;
-        }
-
-        @Override
-        public void binderDied() {
-            mPrivateHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    onConnectionDied(Connection.this);
-                }
-            });
-        }
-
-        public int createRouteController(String routeId, String routeGroupId) {
-            int controllerId = mNextControllerId++;
-            Bundle data = new Bundle();
-            data.putString(CLIENT_DATA_ROUTE_ID, routeId);
-            data.putString(CLIENT_DATA_ROUTE_LIBRARY_GROUP, routeGroupId);
-            sendRequest(CLIENT_MSG_CREATE_ROUTE_CONTROLLER,
-                    mNextRequestId++, controllerId, null, data);
-            return controllerId;
-        }
-
-        public void releaseRouteController(int controllerId) {
-            sendRequest(CLIENT_MSG_RELEASE_ROUTE_CONTROLLER,
-                    mNextRequestId++, controllerId, null, null);
-        }
-
-        public void selectRoute(int controllerId) {
-            sendRequest(CLIENT_MSG_SELECT_ROUTE,
-                    mNextRequestId++, controllerId, null, null);
-        }
-
-        public void unselectRoute(int controllerId, int reason) {
-            Bundle extras = new Bundle();
-            extras.putInt(CLIENT_DATA_UNSELECT_REASON, reason);
-            sendRequest(CLIENT_MSG_UNSELECT_ROUTE,
-                    mNextRequestId++, controllerId, null, extras);
-        }
-
-        public void setVolume(int controllerId, int volume) {
-            Bundle data = new Bundle();
-            data.putInt(CLIENT_DATA_VOLUME, volume);
-            sendRequest(CLIENT_MSG_SET_ROUTE_VOLUME,
-                    mNextRequestId++, controllerId, null, data);
-        }
-
-        public void updateVolume(int controllerId, int delta) {
-            Bundle data = new Bundle();
-            data.putInt(CLIENT_DATA_VOLUME, delta);
-            sendRequest(CLIENT_MSG_UPDATE_ROUTE_VOLUME,
-                    mNextRequestId++, controllerId, null, data);
-        }
-
-        public boolean sendControlRequest(int controllerId, Intent intent,
-                ControlRequestCallback callback) {
-            int requestId = mNextRequestId++;
-            if (sendRequest(CLIENT_MSG_ROUTE_CONTROL_REQUEST,
-                    requestId, controllerId, intent, null)) {
-                if (callback != null) {
-                    mPendingCallbacks.put(requestId, callback);
-                }
-                return true;
-            }
-            return false;
-        }
-
-        public void setDiscoveryRequest(MediaRouteDiscoveryRequest request) {
-            sendRequest(CLIENT_MSG_SET_DISCOVERY_REQUEST,
-                    mNextRequestId++, 0, request != null ? request.asBundle() : null, null);
-        }
-
-        private boolean sendRequest(int what, int requestId, int arg, Object obj, Bundle data) {
-            Message msg = Message.obtain();
-            msg.what = what;
-            msg.arg1 = requestId;
-            msg.arg2 = arg;
-            msg.obj = obj;
-            msg.setData(data);
-            msg.replyTo = mReceiveMessenger;
-            try {
-                mServiceMessenger.send(msg);
-                return true;
-            } catch (DeadObjectException ex) {
-                // The service died.
-            } catch (RemoteException ex) {
-                if (what != CLIENT_MSG_UNREGISTER) {
-                    Log.e(TAG, "Could not send message to service.", ex);
-                }
-            }
-            return false;
-        }
-    }
-
-    private static final class PrivateHandler extends Handler {
-        PrivateHandler() {
-        }
-    }
-
-    /**
-     * Handler that receives messages from the server.
-     * <p>
-     * This inner class is static and only retains a weak reference to the connection
-     * to prevent the client from being leaked in case the service is holding an
-     * active reference to the client's messenger.
-     * </p><p>
-     * This handler should not be used to handle any messages other than those
-     * that come from the service.
-     * </p>
-     */
-    private static final class ReceiveHandler extends Handler {
-        private final WeakReference<Connection> mConnectionRef;
-
-        public ReceiveHandler(Connection connection) {
-            mConnectionRef = new WeakReference<Connection>(connection);
-        }
-
-        public void dispose() {
-            mConnectionRef.clear();
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            Connection connection = mConnectionRef.get();
-            if (connection != null) {
-                final int what = msg.what;
-                final int requestId = msg.arg1;
-                final int arg = msg.arg2;
-                final Object obj = msg.obj;
-                final Bundle data = msg.peekData();
-                if (!processMessage(connection, what, requestId, arg, obj, data)) {
-                    if (DEBUG) {
-                        Log.d(TAG, "Unhandled message from server: " + msg);
-                    }
-                }
-            }
-        }
-
-        private boolean processMessage(Connection connection,
-                int what, int requestId, int arg, Object obj, Bundle data) {
-            switch (what) {
-                case SERVICE_MSG_GENERIC_FAILURE:
-                    connection.onGenericFailure(requestId);
-                    return true;
-
-                case SERVICE_MSG_GENERIC_SUCCESS:
-                    connection.onGenericSuccess(requestId);
-                    return true;
-
-                case SERVICE_MSG_REGISTERED:
-                    if (obj == null || obj instanceof Bundle) {
-                        return connection.onRegistered(requestId, arg, (Bundle)obj);
-                    }
-                    break;
-
-                case SERVICE_MSG_DESCRIPTOR_CHANGED:
-                    if (obj == null || obj instanceof Bundle) {
-                        return connection.onDescriptorChanged((Bundle)obj);
-                    }
-                    break;
-
-                case SERVICE_MSG_CONTROL_REQUEST_SUCCEEDED:
-                    if (obj == null || obj instanceof Bundle) {
-                        return connection.onControlRequestSucceeded(
-                                requestId, (Bundle)obj);
-                    }
-                    break;
-
-                case SERVICE_MSG_CONTROL_REQUEST_FAILED:
-                    if (obj == null || obj instanceof Bundle) {
-                        String error = (data == null ? null :
-                                data.getString(SERVICE_DATA_ERROR));
-                        return connection.onControlRequestFailed(
-                                requestId, error, (Bundle)obj);
-                    }
-                    break;
-            }
-            return false;
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/RegisteredMediaRouteProviderWatcher.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/RegisteredMediaRouteProviderWatcher.java
deleted file mode 100644
index ba1f647..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/RegisteredMediaRouteProviderWatcher.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.media;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.os.Handler;
-
-import java.util.ArrayList;
-import java.util.Collections;
-
-/**
- * Watches for media route provider services to be installed.
- * Adds a provider to the media router for each registered service.
- *
- * @see RegisteredMediaRouteProvider
- */
-final class RegisteredMediaRouteProviderWatcher {
-    private final Context mContext;
-    private final Callback mCallback;
-    private final Handler mHandler;
-    private final PackageManager mPackageManager;
-
-    private final ArrayList<RegisteredMediaRouteProvider> mProviders =
-            new ArrayList<RegisteredMediaRouteProvider>();
-    private boolean mRunning;
-
-    public RegisteredMediaRouteProviderWatcher(Context context, Callback callback) {
-        mContext = context;
-        mCallback = callback;
-        mHandler = new Handler();
-        mPackageManager = context.getPackageManager();
-    }
-
-    public void start() {
-        if (!mRunning) {
-            mRunning = true;
-
-            IntentFilter filter = new IntentFilter();
-            filter.addAction(Intent.ACTION_PACKAGE_ADDED);
-            filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
-            filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
-            filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
-            filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
-            filter.addDataScheme("package");
-            mContext.registerReceiver(mScanPackagesReceiver, filter, null, mHandler);
-
-            // Scan packages.
-            // Also has the side-effect of restarting providers if needed.
-            mHandler.post(mScanPackagesRunnable);
-        }
-    }
-
-    public void stop() {
-        if (mRunning) {
-            mRunning = false;
-
-            mContext.unregisterReceiver(mScanPackagesReceiver);
-            mHandler.removeCallbacks(mScanPackagesRunnable);
-
-            // Stop all providers.
-            for (int i = mProviders.size() - 1; i >= 0; i--) {
-                mProviders.get(i).stop();
-            }
-        }
-    }
-
-    void scanPackages() {
-        if (!mRunning) {
-            return;
-        }
-
-        // Add providers for all new services.
-        // Reorder the list so that providers left at the end will be the ones to remove.
-        int targetIndex = 0;
-        Intent intent = new Intent(MediaRouteProviderService.SERVICE_INTERFACE);
-        for (ResolveInfo resolveInfo : mPackageManager.queryIntentServices(intent, 0)) {
-            ServiceInfo serviceInfo = resolveInfo.serviceInfo;
-            if (serviceInfo != null) {
-                int sourceIndex = findProvider(serviceInfo.packageName, serviceInfo.name);
-                if (sourceIndex < 0) {
-                    RegisteredMediaRouteProvider provider =
-                            new RegisteredMediaRouteProvider(mContext,
-                            new ComponentName(serviceInfo.packageName, serviceInfo.name));
-                    provider.start();
-                    mProviders.add(targetIndex++, provider);
-                    mCallback.addProvider(provider);
-                } else if (sourceIndex >= targetIndex) {
-                    RegisteredMediaRouteProvider provider = mProviders.get(sourceIndex);
-                    provider.start(); // restart the provider if needed
-                    provider.rebindIfDisconnected();
-                    Collections.swap(mProviders, sourceIndex, targetIndex++);
-                }
-            }
-        }
-
-        // Remove providers for missing services.
-        if (targetIndex < mProviders.size()) {
-            for (int i = mProviders.size() - 1; i >= targetIndex; i--) {
-                RegisteredMediaRouteProvider provider = mProviders.get(i);
-                mCallback.removeProvider(provider);
-                mProviders.remove(provider);
-                provider.stop();
-            }
-        }
-    }
-
-    private int findProvider(String packageName, String className) {
-        int count = mProviders.size();
-        for (int i = 0; i < count; i++) {
-            RegisteredMediaRouteProvider provider = mProviders.get(i);
-            if (provider.hasComponentName(packageName, className)) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    private final BroadcastReceiver mScanPackagesReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            scanPackages();
-        }
-    };
-
-    private final Runnable mScanPackagesRunnable = new Runnable() {
-        @Override
-        public void run() {
-            scanPackages();
-        }
-    };
-
-    public interface Callback {
-        void addProvider(MediaRouteProvider provider);
-        void removeProvider(MediaRouteProvider provider);
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/RemoteControlClientCompat.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/RemoteControlClientCompat.java
deleted file mode 100644
index 826449b..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/RemoteControlClientCompat.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.support.mediarouter.media;
-
-import android.content.Context;
-import android.media.AudioManager;
-import android.os.Build;
-import android.support.annotation.RequiresApi;
-
-import java.lang.ref.WeakReference;
-
-/**
- * Provides access to features of the remote control client.
- *
- * Hidden for now but we might want to make this available to applications
- * in the future.
- */
-abstract class RemoteControlClientCompat {
-    protected final Context mContext;
-    protected final Object mRcc;
-    protected VolumeCallback mVolumeCallback;
-
-    protected RemoteControlClientCompat(Context context, Object rcc) {
-        mContext = context;
-        mRcc = rcc;
-    }
-
-    public static RemoteControlClientCompat obtain(Context context, Object rcc) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return new JellybeanImpl(context, rcc);
-        }
-        return new LegacyImpl(context, rcc);
-    }
-
-    public Object getRemoteControlClient() {
-        return mRcc;
-    }
-
-    /**
-     * Sets the current playback information.
-     * Must be called at least once to attach to the remote control client.
-     *
-     * @param info The playback information.  Must not be null.
-     */
-    public void setPlaybackInfo(PlaybackInfo info) {
-    }
-
-    /**
-     * Sets a callback to receive volume change requests from the remote control client.
-     *
-     * @param callback The volume callback to use or null if none.
-     */
-    public void setVolumeCallback(VolumeCallback callback) {
-        mVolumeCallback = callback;
-    }
-
-    /**
-     * Specifies information about the playback.
-     */
-    public static final class PlaybackInfo {
-        public int volume;
-        public int volumeMax;
-        public int volumeHandling = MediaRouter.RouteInfo.PLAYBACK_VOLUME_FIXED;
-        public int playbackStream = AudioManager.STREAM_MUSIC;
-        public int playbackType = MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE;
-    }
-
-    /**
-     * Called when volume updates are requested by the remote control client.
-     */
-    public interface VolumeCallback {
-        /**
-         * Called when the volume should be increased or decreased.
-         *
-         * @param direction An integer indicating whether the volume is to be increased
-         * (positive value) or decreased (negative value).
-         * For bundled changes, the absolute value indicates the number of changes
-         * in the same direction, e.g. +3 corresponds to three "volume up" changes.
-         */
-        public void onVolumeUpdateRequest(int direction);
-
-        /**
-         * Called when the volume for the route should be set to the given value.
-         *
-         * @param volume An integer indicating the new volume value that should be used,
-         * always between 0 and the value set by {@link PlaybackInfo#volumeMax}.
-         */
-        public void onVolumeSetRequest(int volume);
-    }
-
-    /**
-     * Legacy implementation for platform versions prior to Jellybean.
-     * Does nothing.
-     */
-    static class LegacyImpl extends RemoteControlClientCompat {
-        public LegacyImpl(Context context, Object rcc) {
-            super(context, rcc);
-        }
-    }
-
-    /**
-     * Implementation for Jellybean.
-     *
-     * The basic idea of this implementation is to attach the RCC to a UserRouteInfo
-     * in order to hook up stream metadata and volume callbacks because there is no
-     * other API available to do so in this platform version.  The UserRouteInfo itself
-     * is not attached to the MediaRouter so it is transparent to the user.
-     */
-    // @@RequiresApi(16)
-    static class JellybeanImpl extends RemoteControlClientCompat {
-        private final Object mRouterObj;
-        private final Object mUserRouteCategoryObj;
-        private final Object mUserRouteObj;
-        private boolean mRegistered;
-
-        public JellybeanImpl(Context context, Object rcc) {
-            super(context, rcc);
-
-            mRouterObj = MediaRouterJellybean.getMediaRouter(context);
-            mUserRouteCategoryObj = MediaRouterJellybean.createRouteCategory(
-                    mRouterObj, "", false);
-            mUserRouteObj = MediaRouterJellybean.createUserRoute(
-                    mRouterObj, mUserRouteCategoryObj);
-        }
-
-        @Override
-        public void setPlaybackInfo(PlaybackInfo info) {
-            MediaRouterJellybean.UserRouteInfo.setVolume(
-                    mUserRouteObj, info.volume);
-            MediaRouterJellybean.UserRouteInfo.setVolumeMax(
-                    mUserRouteObj, info.volumeMax);
-            MediaRouterJellybean.UserRouteInfo.setVolumeHandling(
-                    mUserRouteObj, info.volumeHandling);
-            MediaRouterJellybean.UserRouteInfo.setPlaybackStream(
-                    mUserRouteObj, info.playbackStream);
-            MediaRouterJellybean.UserRouteInfo.setPlaybackType(
-                    mUserRouteObj, info.playbackType);
-
-            if (!mRegistered) {
-                mRegistered = true;
-                MediaRouterJellybean.UserRouteInfo.setVolumeCallback(mUserRouteObj,
-                        MediaRouterJellybean.createVolumeCallback(
-                                new VolumeCallbackWrapper(this)));
-                MediaRouterJellybean.UserRouteInfo.setRemoteControlClient(mUserRouteObj, mRcc);
-            }
-        }
-
-        private static final class VolumeCallbackWrapper
-                implements MediaRouterJellybean.VolumeCallback {
-            // Unfortunately, the framework never unregisters its volume observer from
-            // the audio service so the UserRouteInfo object may leak along with
-            // any callbacks that we attach to it.  Use a weak reference to prevent
-            // the volume callback from holding strong references to anything important.
-            private final WeakReference<JellybeanImpl> mImplWeak;
-
-            public VolumeCallbackWrapper(JellybeanImpl impl) {
-                mImplWeak = new WeakReference<JellybeanImpl>(impl);
-            }
-
-            @Override
-            public void onVolumeUpdateRequest(Object routeObj, int direction) {
-                JellybeanImpl impl = mImplWeak.get();
-                if (impl != null && impl.mVolumeCallback != null) {
-                    impl.mVolumeCallback.onVolumeUpdateRequest(direction);
-                }
-            }
-
-            @Override
-            public void onVolumeSetRequest(Object routeObj, int volume) {
-                JellybeanImpl impl = mImplWeak.get();
-                if (impl != null && impl.mVolumeCallback != null) {
-                    impl.mVolumeCallback.onVolumeSetRequest(volume);
-                }
-            }
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/RemotePlaybackClient.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/RemotePlaybackClient.java
deleted file mode 100644
index f6e1497..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/RemotePlaybackClient.java
+++ /dev/null
@@ -1,1044 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.support.mediarouter.media;
-
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v4.util.ObjectsCompat;
-import android.util.Log;
-
-/**
- * A helper class for playing media on remote routes using the remote playback protocol
- * defined by {@link MediaControlIntent}.
- * <p>
- * The client maintains session state and offers a simplified interface for issuing
- * remote playback media control intents to a single route.
- * </p>
- */
-public class RemotePlaybackClient {
-    static final String TAG = "RemotePlaybackClient";
-    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    private final Context mContext;
-    private final MediaRouter.RouteInfo mRoute;
-    private final ActionReceiver mActionReceiver;
-    private final PendingIntent mItemStatusPendingIntent;
-    private final PendingIntent mSessionStatusPendingIntent;
-    private final PendingIntent mMessagePendingIntent;
-
-    private boolean mRouteSupportsRemotePlayback;
-    private boolean mRouteSupportsQueuing;
-    private boolean mRouteSupportsSessionManagement;
-    private boolean mRouteSupportsMessaging;
-
-    String mSessionId;
-    StatusCallback mStatusCallback;
-    OnMessageReceivedListener mOnMessageReceivedListener;
-
-    /**
-     * Creates a remote playback client for a route.
-     *
-     * @param route The media route.
-     */
-    public RemotePlaybackClient(Context context, MediaRouter.RouteInfo route) {
-        if (context == null) {
-            throw new IllegalArgumentException("context must not be null");
-        }
-        if (route == null) {
-            throw new IllegalArgumentException("route must not be null");
-        }
-
-        mContext = context;
-        mRoute = route;
-
-        IntentFilter actionFilter = new IntentFilter();
-        actionFilter.addAction(ActionReceiver.ACTION_ITEM_STATUS_CHANGED);
-        actionFilter.addAction(ActionReceiver.ACTION_SESSION_STATUS_CHANGED);
-        actionFilter.addAction(ActionReceiver.ACTION_MESSAGE_RECEIVED);
-        mActionReceiver = new ActionReceiver();
-        context.registerReceiver(mActionReceiver, actionFilter);
-
-        Intent itemStatusIntent = new Intent(ActionReceiver.ACTION_ITEM_STATUS_CHANGED);
-        itemStatusIntent.setPackage(context.getPackageName());
-        mItemStatusPendingIntent = PendingIntent.getBroadcast(
-                context, 0, itemStatusIntent, 0);
-
-        Intent sessionStatusIntent = new Intent(ActionReceiver.ACTION_SESSION_STATUS_CHANGED);
-        sessionStatusIntent.setPackage(context.getPackageName());
-        mSessionStatusPendingIntent = PendingIntent.getBroadcast(
-                context, 0, sessionStatusIntent, 0);
-
-        Intent messageIntent = new Intent(ActionReceiver.ACTION_MESSAGE_RECEIVED);
-        messageIntent.setPackage(context.getPackageName());
-        mMessagePendingIntent = PendingIntent.getBroadcast(
-                context, 0, messageIntent, 0);
-        detectFeatures();
-    }
-
-    /**
-     * Releases resources owned by the client.
-     */
-    public void release() {
-        mContext.unregisterReceiver(mActionReceiver);
-    }
-
-    /**
-     * Returns true if the route supports remote playback.
-     * <p>
-     * If the route does not support remote playback, then none of the functionality
-     * offered by the client will be available.
-     * </p><p>
-     * This method returns true if the route supports all of the following
-     * actions: {@link MediaControlIntent#ACTION_PLAY play},
-     * {@link MediaControlIntent#ACTION_SEEK seek},
-     * {@link MediaControlIntent#ACTION_GET_STATUS get status},
-     * {@link MediaControlIntent#ACTION_PAUSE pause},
-     * {@link MediaControlIntent#ACTION_RESUME resume},
-     * {@link MediaControlIntent#ACTION_STOP stop}.
-     * </p>
-     *
-     * @return True if remote playback is supported.
-     */
-    public boolean isRemotePlaybackSupported() {
-        return mRouteSupportsRemotePlayback;
-    }
-
-    /**
-     * Returns true if the route supports queuing features.
-     * <p>
-     * If the route does not support queuing, then at most one media item can be played
-     * at a time and the {@link #enqueue} method will not be available.
-     * </p><p>
-     * This method returns true if the route supports all of the basic remote playback
-     * actions and all of the following actions:
-     * {@link MediaControlIntent#ACTION_ENQUEUE enqueue},
-     * {@link MediaControlIntent#ACTION_REMOVE remove}.
-     * </p>
-     *
-     * @return True if queuing is supported.  Implies {@link #isRemotePlaybackSupported}
-     * is also true.
-     *
-     * @see #isRemotePlaybackSupported
-     */
-    public boolean isQueuingSupported() {
-        return mRouteSupportsQueuing;
-    }
-
-    /**
-     * Returns true if the route supports session management features.
-     * <p>
-     * If the route does not support session management, then the session will
-     * not be created until the first media item is played.
-     * </p><p>
-     * This method returns true if the route supports all of the basic remote playback
-     * actions and all of the following actions:
-     * {@link MediaControlIntent#ACTION_START_SESSION start session},
-     * {@link MediaControlIntent#ACTION_GET_SESSION_STATUS get session status},
-     * {@link MediaControlIntent#ACTION_END_SESSION end session}.
-     * </p>
-     *
-     * @return True if session management is supported.
-     * Implies {@link #isRemotePlaybackSupported} is also true.
-     *
-     * @see #isRemotePlaybackSupported
-     */
-    public boolean isSessionManagementSupported() {
-        return mRouteSupportsSessionManagement;
-    }
-
-    /**
-     * Returns true if the route supports messages.
-     * <p>
-     * This method returns true if the route supports all of the basic remote playback
-     * actions and all of the following actions:
-     * {@link MediaControlIntent#ACTION_START_SESSION start session},
-     * {@link MediaControlIntent#ACTION_SEND_MESSAGE send message},
-     * {@link MediaControlIntent#ACTION_END_SESSION end session}.
-     * </p>
-     *
-     * @return True if session management is supported.
-     * Implies {@link #isRemotePlaybackSupported} is also true.
-     *
-     * @see #isRemotePlaybackSupported
-     */
-    public boolean isMessagingSupported() {
-        return mRouteSupportsMessaging;
-    }
-
-    /**
-     * Gets the current session id if there is one.
-     *
-     * @return The current session id, or null if none.
-     */
-    public String getSessionId() {
-        return mSessionId;
-    }
-
-    /**
-     * Sets the current session id.
-     * <p>
-     * It is usually not necessary to set the session id explicitly since
-     * it is created as a side-effect of other requests such as
-     * {@link #play}, {@link #enqueue}, and {@link #startSession}.
-     * </p>
-     *
-     * @param sessionId The new session id, or null if none.
-     */
-    public void setSessionId(String sessionId) {
-        if (!ObjectsCompat.equals(mSessionId, sessionId)) {
-            if (DEBUG) {
-                Log.d(TAG, "Session id is now: " + sessionId);
-            }
-            mSessionId = sessionId;
-            if (mStatusCallback != null) {
-                mStatusCallback.onSessionChanged(sessionId);
-            }
-        }
-    }
-
-    /**
-     * Returns true if the client currently has a session.
-     * <p>
-     * Equivalent to checking whether {@link #getSessionId} returns a non-null result.
-     * </p>
-     *
-     * @return True if there is a current session.
-     */
-    public boolean hasSession() {
-        return mSessionId != null;
-    }
-
-    /**
-     * Sets a callback that should receive status updates when the state of
-     * media sessions or media items created by this instance of the remote
-     * playback client changes.
-     * <p>
-     * The callback should be set before the session is created or any play
-     * commands are issued.
-     * </p>
-     *
-     * @param callback The callback to set.  May be null to remove the previous callback.
-     */
-    public void setStatusCallback(StatusCallback callback) {
-        mStatusCallback = callback;
-    }
-
-    /**
-     * Sets a callback that should receive messages when a message is sent from
-     * media sessions created by this instance of the remote playback client changes.
-     * <p>
-     * The callback should be set before the session is created.
-     * </p>
-     *
-     * @param listener The callback to set.  May be null to remove the previous callback.
-     */
-    public void setOnMessageReceivedListener(OnMessageReceivedListener listener) {
-        mOnMessageReceivedListener = listener;
-    }
-
-    /**
-     * Sends a request to play a media item.
-     * <p>
-     * Clears the queue and starts playing the new item immediately.  If the queue
-     * was previously paused, then it is resumed as a side-effect of this request.
-     * </p><p>
-     * The request is issued in the current session.  If no session is available, then
-     * one is created implicitly.
-     * </p><p>
-     * Please refer to {@link MediaControlIntent#ACTION_PLAY ACTION_PLAY} for
-     * more information about the semantics of this request.
-     * </p>
-     *
-     * @param contentUri The content Uri to play.
-     * @param mimeType The mime type of the content, or null if unknown.
-     * @param positionMillis The initial content position for the item in milliseconds,
-     * or <code>0</code> to start at the beginning.
-     * @param metadata The media item metadata bundle, or null if none.
-     * @param extras A bundle of extra arguments to be added to the
-     * {@link MediaControlIntent#ACTION_PLAY} intent, or null if none.
-     * @param callback A callback to invoke when the request has been
-     * processed, or null if none.
-     *
-     * @throws UnsupportedOperationException if the route does not support remote playback.
-     *
-     * @see MediaControlIntent#ACTION_PLAY
-     * @see #isRemotePlaybackSupported
-     */
-    public void play(Uri contentUri, String mimeType, Bundle metadata,
-            long positionMillis, Bundle extras, ItemActionCallback callback) {
-        playOrEnqueue(contentUri, mimeType, metadata, positionMillis,
-                extras, callback, MediaControlIntent.ACTION_PLAY);
-    }
-
-    /**
-     * Sends a request to enqueue a media item.
-     * <p>
-     * Enqueues a new item to play.  If the queue was previously paused, then will
-     * remain paused.
-     * </p><p>
-     * The request is issued in the current session.  If no session is available, then
-     * one is created implicitly.
-     * </p><p>
-     * Please refer to {@link MediaControlIntent#ACTION_ENQUEUE ACTION_ENQUEUE} for
-     * more information about the semantics of this request.
-     * </p>
-     *
-     * @param contentUri The content Uri to enqueue.
-     * @param mimeType The mime type of the content, or null if unknown.
-     * @param positionMillis The initial content position for the item in milliseconds,
-     * or <code>0</code> to start at the beginning.
-     * @param metadata The media item metadata bundle, or null if none.
-     * @param extras A bundle of extra arguments to be added to the
-     * {@link MediaControlIntent#ACTION_ENQUEUE} intent, or null if none.
-     * @param callback A callback to invoke when the request has been
-     * processed, or null if none.
-     *
-     * @throws UnsupportedOperationException if the route does not support queuing.
-     *
-     * @see MediaControlIntent#ACTION_ENQUEUE
-     * @see #isRemotePlaybackSupported
-     * @see #isQueuingSupported
-     */
-    public void enqueue(Uri contentUri, String mimeType, Bundle metadata,
-            long positionMillis, Bundle extras, ItemActionCallback callback) {
-        playOrEnqueue(contentUri, mimeType, metadata, positionMillis,
-                extras, callback, MediaControlIntent.ACTION_ENQUEUE);
-    }
-
-    private void playOrEnqueue(Uri contentUri, String mimeType, Bundle metadata,
-            long positionMillis, Bundle extras,
-            final ItemActionCallback callback, String action) {
-        if (contentUri == null) {
-            throw new IllegalArgumentException("contentUri must not be null");
-        }
-        throwIfRemotePlaybackNotSupported();
-        if (action.equals(MediaControlIntent.ACTION_ENQUEUE)) {
-            throwIfQueuingNotSupported();
-        }
-
-        Intent intent = new Intent(action);
-        intent.setDataAndType(contentUri, mimeType);
-        intent.putExtra(MediaControlIntent.EXTRA_ITEM_STATUS_UPDATE_RECEIVER,
-                mItemStatusPendingIntent);
-        if (metadata != null) {
-            intent.putExtra(MediaControlIntent.EXTRA_ITEM_METADATA, metadata);
-        }
-        if (positionMillis != 0) {
-            intent.putExtra(MediaControlIntent.EXTRA_ITEM_CONTENT_POSITION, positionMillis);
-        }
-        performItemAction(intent, mSessionId, null, extras, callback);
-    }
-
-    /**
-     * Sends a request to seek to a new position in a media item.
-     * <p>
-     * Seeks to a new position.  If the queue was previously paused then it
-     * remains paused but the item's new position is still remembered.
-     * </p><p>
-     * The request is issued in the current session.
-     * </p><p>
-     * Please refer to {@link MediaControlIntent#ACTION_SEEK ACTION_SEEK} for
-     * more information about the semantics of this request.
-     * </p>
-     *
-     * @param itemId The item id.
-     * @param positionMillis The new content position for the item in milliseconds,
-     * or <code>0</code> to start at the beginning.
-     * @param extras A bundle of extra arguments to be added to the
-     * {@link MediaControlIntent#ACTION_SEEK} intent, or null if none.
-     * @param callback A callback to invoke when the request has been
-     * processed, or null if none.
-     *
-     * @throws IllegalStateException if there is no current session.
-     *
-     * @see MediaControlIntent#ACTION_SEEK
-     * @see #isRemotePlaybackSupported
-     */
-    public void seek(String itemId, long positionMillis, Bundle extras,
-            ItemActionCallback callback) {
-        if (itemId == null) {
-            throw new IllegalArgumentException("itemId must not be null");
-        }
-        throwIfNoCurrentSession();
-
-        Intent intent = new Intent(MediaControlIntent.ACTION_SEEK);
-        intent.putExtra(MediaControlIntent.EXTRA_ITEM_CONTENT_POSITION, positionMillis);
-        performItemAction(intent, mSessionId, itemId, extras, callback);
-    }
-
-    /**
-     * Sends a request to get the status of a media item.
-     * <p>
-     * The request is issued in the current session.
-     * </p><p>
-     * Please refer to {@link MediaControlIntent#ACTION_GET_STATUS ACTION_GET_STATUS} for
-     * more information about the semantics of this request.
-     * </p>
-     *
-     * @param itemId The item id.
-     * @param extras A bundle of extra arguments to be added to the
-     * {@link MediaControlIntent#ACTION_GET_STATUS} intent, or null if none.
-     * @param callback A callback to invoke when the request has been
-     * processed, or null if none.
-     *
-     * @throws IllegalStateException if there is no current session.
-     *
-     * @see MediaControlIntent#ACTION_GET_STATUS
-     * @see #isRemotePlaybackSupported
-     */
-    public void getStatus(String itemId, Bundle extras, ItemActionCallback callback) {
-        if (itemId == null) {
-            throw new IllegalArgumentException("itemId must not be null");
-        }
-        throwIfNoCurrentSession();
-
-        Intent intent = new Intent(MediaControlIntent.ACTION_GET_STATUS);
-        performItemAction(intent, mSessionId, itemId, extras, callback);
-    }
-
-    /**
-     * Sends a request to remove a media item from the queue.
-     * <p>
-     * The request is issued in the current session.
-     * </p><p>
-     * Please refer to {@link MediaControlIntent#ACTION_REMOVE ACTION_REMOVE} for
-     * more information about the semantics of this request.
-     * </p>
-     *
-     * @param itemId The item id.
-     * @param extras A bundle of extra arguments to be added to the
-     * {@link MediaControlIntent#ACTION_REMOVE} intent, or null if none.
-     * @param callback A callback to invoke when the request has been
-     * processed, or null if none.
-     *
-     * @throws IllegalStateException if there is no current session.
-     * @throws UnsupportedOperationException if the route does not support queuing.
-     *
-     * @see MediaControlIntent#ACTION_REMOVE
-     * @see #isRemotePlaybackSupported
-     * @see #isQueuingSupported
-     */
-    public void remove(String itemId, Bundle extras, ItemActionCallback callback) {
-        if (itemId == null) {
-            throw new IllegalArgumentException("itemId must not be null");
-        }
-        throwIfQueuingNotSupported();
-        throwIfNoCurrentSession();
-
-        Intent intent = new Intent(MediaControlIntent.ACTION_REMOVE);
-        performItemAction(intent, mSessionId, itemId, extras, callback);
-    }
-
-    /**
-     * Sends a request to pause media playback.
-     * <p>
-     * The request is issued in the current session.  If playback is already paused
-     * then the request has no effect.
-     * </p><p>
-     * Please refer to {@link MediaControlIntent#ACTION_PAUSE ACTION_PAUSE} for
-     * more information about the semantics of this request.
-     * </p>
-     *
-     * @param extras A bundle of extra arguments to be added to the
-     * {@link MediaControlIntent#ACTION_PAUSE} intent, or null if none.
-     * @param callback A callback to invoke when the request has been
-     * processed, or null if none.
-     *
-     * @throws IllegalStateException if there is no current session.
-     *
-     * @see MediaControlIntent#ACTION_PAUSE
-     * @see #isRemotePlaybackSupported
-     */
-    public void pause(Bundle extras, SessionActionCallback callback) {
-        throwIfNoCurrentSession();
-
-        Intent intent = new Intent(MediaControlIntent.ACTION_PAUSE);
-        performSessionAction(intent, mSessionId, extras, callback);
-    }
-
-    /**
-     * Sends a request to resume (unpause) media playback.
-     * <p>
-     * The request is issued in the current session.  If playback is not paused
-     * then the request has no effect.
-     * </p><p>
-     * Please refer to {@link MediaControlIntent#ACTION_RESUME ACTION_RESUME} for
-     * more information about the semantics of this request.
-     * </p>
-     *
-     * @param extras A bundle of extra arguments to be added to the
-     * {@link MediaControlIntent#ACTION_RESUME} intent, or null if none.
-     * @param callback A callback to invoke when the request has been
-     * processed, or null if none.
-     *
-     * @throws IllegalStateException if there is no current session.
-     *
-     * @see MediaControlIntent#ACTION_RESUME
-     * @see #isRemotePlaybackSupported
-     */
-    public void resume(Bundle extras, SessionActionCallback callback) {
-        throwIfNoCurrentSession();
-
-        Intent intent = new Intent(MediaControlIntent.ACTION_RESUME);
-        performSessionAction(intent, mSessionId, extras, callback);
-    }
-
-    /**
-     * Sends a request to stop media playback and clear the media playback queue.
-     * <p>
-     * The request is issued in the current session.  If the queue is already
-     * empty then the request has no effect.
-     * </p><p>
-     * Please refer to {@link MediaControlIntent#ACTION_STOP ACTION_STOP} for
-     * more information about the semantics of this request.
-     * </p>
-     *
-     * @param extras A bundle of extra arguments to be added to the
-     * {@link MediaControlIntent#ACTION_STOP} intent, or null if none.
-     * @param callback A callback to invoke when the request has been
-     * processed, or null if none.
-     *
-     * @throws IllegalStateException if there is no current session.
-     *
-     * @see MediaControlIntent#ACTION_STOP
-     * @see #isRemotePlaybackSupported
-     */
-    public void stop(Bundle extras, SessionActionCallback callback) {
-        throwIfNoCurrentSession();
-
-        Intent intent = new Intent(MediaControlIntent.ACTION_STOP);
-        performSessionAction(intent, mSessionId, extras, callback);
-    }
-
-    /**
-     * Sends a request to start a new media playback session.
-     * <p>
-     * The application must wait for the callback to indicate that this request
-     * is complete before issuing other requests that affect the session.  If this
-     * request is successful then the previous session will be invalidated.
-     * </p><p>
-     * Please refer to {@link MediaControlIntent#ACTION_START_SESSION ACTION_START_SESSION}
-     * for more information about the semantics of this request.
-     * </p>
-     *
-     * @param extras A bundle of extra arguments to be added to the
-     * {@link MediaControlIntent#ACTION_START_SESSION} intent, or null if none.
-     * @param callback A callback to invoke when the request has been
-     * processed, or null if none.
-     *
-     * @throws UnsupportedOperationException if the route does not support session management.
-     *
-     * @see MediaControlIntent#ACTION_START_SESSION
-     * @see #isRemotePlaybackSupported
-     * @see #isSessionManagementSupported
-     */
-    public void startSession(Bundle extras, SessionActionCallback callback) {
-        throwIfSessionManagementNotSupported();
-
-        Intent intent = new Intent(MediaControlIntent.ACTION_START_SESSION);
-        intent.putExtra(MediaControlIntent.EXTRA_SESSION_STATUS_UPDATE_RECEIVER,
-                mSessionStatusPendingIntent);
-        if (mRouteSupportsMessaging) {
-            intent.putExtra(MediaControlIntent.EXTRA_MESSAGE_RECEIVER, mMessagePendingIntent);
-        }
-        performSessionAction(intent, null, extras, callback);
-    }
-
-    /**
-     * Sends a message.
-     * <p>
-     * The request is issued in the current session.
-     * </p><p>
-     * Please refer to {@link MediaControlIntent#ACTION_SEND_MESSAGE} for
-     * more information about the semantics of this request.
-     * </p>
-     *
-     * @param message A bundle message denoting {@link MediaControlIntent#EXTRA_MESSAGE}.
-     * @param callback A callback to invoke when the request has been processed, or null if none.
-     *
-     * @throws IllegalStateException if there is no current session.
-     * @throws UnsupportedOperationException if the route does not support messages.
-     *
-     * @see MediaControlIntent#ACTION_SEND_MESSAGE
-     * @see #isMessagingSupported
-     */
-    public void sendMessage(Bundle message, SessionActionCallback callback) {
-        throwIfNoCurrentSession();
-        throwIfMessageNotSupported();
-
-        Intent intent = new Intent(MediaControlIntent.ACTION_SEND_MESSAGE);
-        performSessionAction(intent, mSessionId, message, callback);
-    }
-
-    /**
-     * Sends a request to get the status of the media playback session.
-     * <p>
-     * The request is issued in the current session.
-     * </p><p>
-     * Please refer to {@link MediaControlIntent#ACTION_GET_SESSION_STATUS
-     * ACTION_GET_SESSION_STATUS} for more information about the semantics of this request.
-     * </p>
-     *
-     * @param extras A bundle of extra arguments to be added to the
-     * {@link MediaControlIntent#ACTION_GET_SESSION_STATUS} intent, or null if none.
-     * @param callback A callback to invoke when the request has been
-     * processed, or null if none.
-     *
-     * @throws IllegalStateException if there is no current session.
-     * @throws UnsupportedOperationException if the route does not support session management.
-     *
-     * @see MediaControlIntent#ACTION_GET_SESSION_STATUS
-     * @see #isRemotePlaybackSupported
-     * @see #isSessionManagementSupported
-     */
-    public void getSessionStatus(Bundle extras, SessionActionCallback callback) {
-        throwIfSessionManagementNotSupported();
-        throwIfNoCurrentSession();
-
-        Intent intent = new Intent(MediaControlIntent.ACTION_GET_SESSION_STATUS);
-        performSessionAction(intent, mSessionId, extras, callback);
-    }
-
-    /**
-     * Sends a request to end the media playback session.
-     * <p>
-     * The request is issued in the current session.  If this request is successful,
-     * the {@link #getSessionId session id property} will be set to null after
-     * the callback is invoked.
-     * </p><p>
-     * Please refer to {@link MediaControlIntent#ACTION_END_SESSION ACTION_END_SESSION}
-     * for more information about the semantics of this request.
-     * </p>
-     *
-     * @param extras A bundle of extra arguments to be added to the
-     * {@link MediaControlIntent#ACTION_END_SESSION} intent, or null if none.
-     * @param callback A callback to invoke when the request has been
-     * processed, or null if none.
-     *
-     * @throws IllegalStateException if there is no current session.
-     * @throws UnsupportedOperationException if the route does not support session management.
-     *
-     * @see MediaControlIntent#ACTION_END_SESSION
-     * @see #isRemotePlaybackSupported
-     * @see #isSessionManagementSupported
-     */
-    public void endSession(Bundle extras, SessionActionCallback callback) {
-        throwIfSessionManagementNotSupported();
-        throwIfNoCurrentSession();
-
-        Intent intent = new Intent(MediaControlIntent.ACTION_END_SESSION);
-        performSessionAction(intent, mSessionId, extras, callback);
-    }
-
-    private void performItemAction(final Intent intent,
-            final String sessionId, final String itemId,
-            Bundle extras, final ItemActionCallback callback) {
-        intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
-        if (sessionId != null) {
-            intent.putExtra(MediaControlIntent.EXTRA_SESSION_ID, sessionId);
-        }
-        if (itemId != null) {
-            intent.putExtra(MediaControlIntent.EXTRA_ITEM_ID, itemId);
-        }
-        if (extras != null) {
-            intent.putExtras(extras);
-        }
-        logRequest(intent);
-        mRoute.sendControlRequest(intent, new MediaRouter.ControlRequestCallback() {
-            @Override
-            public void onResult(Bundle data) {
-                if (data != null) {
-                    String sessionIdResult = inferMissingResult(sessionId,
-                            data.getString(MediaControlIntent.EXTRA_SESSION_ID));
-                    MediaSessionStatus sessionStatus = MediaSessionStatus.fromBundle(
-                            data.getBundle(MediaControlIntent.EXTRA_SESSION_STATUS));
-                    String itemIdResult = inferMissingResult(itemId,
-                            data.getString(MediaControlIntent.EXTRA_ITEM_ID));
-                    MediaItemStatus itemStatus = MediaItemStatus.fromBundle(
-                            data.getBundle(MediaControlIntent.EXTRA_ITEM_STATUS));
-                    adoptSession(sessionIdResult);
-                    if (sessionIdResult != null && itemIdResult != null && itemStatus != null) {
-                        if (DEBUG) {
-                            Log.d(TAG, "Received result from " + intent.getAction()
-                                    + ": data=" + bundleToString(data)
-                                    + ", sessionId=" + sessionIdResult
-                                    + ", sessionStatus=" + sessionStatus
-                                    + ", itemId=" + itemIdResult
-                                    + ", itemStatus=" + itemStatus);
-                        }
-                        callback.onResult(data, sessionIdResult, sessionStatus,
-                                itemIdResult, itemStatus);
-                        return;
-                    }
-                }
-                handleInvalidResult(intent, callback, data);
-            }
-
-            @Override
-            public void onError(String error, Bundle data) {
-                handleError(intent, callback, error, data);
-            }
-        });
-    }
-
-    private void performSessionAction(final Intent intent, final String sessionId,
-            Bundle extras, final SessionActionCallback callback) {
-        intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
-        if (sessionId != null) {
-            intent.putExtra(MediaControlIntent.EXTRA_SESSION_ID, sessionId);
-        }
-        if (extras != null) {
-            intent.putExtras(extras);
-        }
-        logRequest(intent);
-        mRoute.sendControlRequest(intent, new MediaRouter.ControlRequestCallback() {
-            @Override
-            public void onResult(Bundle data) {
-                if (data != null) {
-                    String sessionIdResult = inferMissingResult(sessionId,
-                            data.getString(MediaControlIntent.EXTRA_SESSION_ID));
-                    MediaSessionStatus sessionStatus = MediaSessionStatus.fromBundle(
-                            data.getBundle(MediaControlIntent.EXTRA_SESSION_STATUS));
-                    adoptSession(sessionIdResult);
-                    if (sessionIdResult != null) {
-                        if (DEBUG) {
-                            Log.d(TAG, "Received result from " + intent.getAction()
-                                    + ": data=" + bundleToString(data)
-                                    + ", sessionId=" + sessionIdResult
-                                    + ", sessionStatus=" + sessionStatus);
-                        }
-                        try {
-                            callback.onResult(data, sessionIdResult, sessionStatus);
-                        } finally {
-                            if (intent.getAction().equals(MediaControlIntent.ACTION_END_SESSION)
-                                    && sessionIdResult.equals(mSessionId)) {
-                                setSessionId(null);
-                            }
-                        }
-                        return;
-                    }
-                }
-                handleInvalidResult(intent, callback, data);
-            }
-
-            @Override
-            public void onError(String error, Bundle data) {
-                handleError(intent, callback, error, data);
-            }
-        });
-    }
-
-    void adoptSession(String sessionId) {
-        if (sessionId != null) {
-            setSessionId(sessionId);
-        }
-    }
-
-    void handleInvalidResult(Intent intent, ActionCallback callback,
-            Bundle data) {
-        Log.w(TAG, "Received invalid result data from " + intent.getAction()
-                + ": data=" + bundleToString(data));
-        callback.onError(null, MediaControlIntent.ERROR_UNKNOWN, data);
-    }
-
-    void handleError(Intent intent, ActionCallback callback,
-            String error, Bundle data) {
-        final int code;
-        if (data != null) {
-            code = data.getInt(MediaControlIntent.EXTRA_ERROR_CODE,
-                    MediaControlIntent.ERROR_UNKNOWN);
-        } else {
-            code = MediaControlIntent.ERROR_UNKNOWN;
-        }
-        if (DEBUG) {
-            Log.w(TAG, "Received error from " + intent.getAction()
-                    + ": error=" + error
-                    + ", code=" + code
-                    + ", data=" + bundleToString(data));
-        }
-        callback.onError(error, code, data);
-    }
-
-    private void detectFeatures() {
-        mRouteSupportsRemotePlayback = routeSupportsAction(MediaControlIntent.ACTION_PLAY)
-                && routeSupportsAction(MediaControlIntent.ACTION_SEEK)
-                && routeSupportsAction(MediaControlIntent.ACTION_GET_STATUS)
-                && routeSupportsAction(MediaControlIntent.ACTION_PAUSE)
-                && routeSupportsAction(MediaControlIntent.ACTION_RESUME)
-                && routeSupportsAction(MediaControlIntent.ACTION_STOP);
-        mRouteSupportsQueuing = mRouteSupportsRemotePlayback
-                && routeSupportsAction(MediaControlIntent.ACTION_ENQUEUE)
-                && routeSupportsAction(MediaControlIntent.ACTION_REMOVE);
-        mRouteSupportsSessionManagement = mRouteSupportsRemotePlayback
-                && routeSupportsAction(MediaControlIntent.ACTION_START_SESSION)
-                && routeSupportsAction(MediaControlIntent.ACTION_GET_SESSION_STATUS)
-                && routeSupportsAction(MediaControlIntent.ACTION_END_SESSION);
-        mRouteSupportsMessaging = doesRouteSupportMessaging();
-    }
-
-    private boolean routeSupportsAction(String action) {
-        return mRoute.supportsControlAction(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK, action);
-    }
-
-    private boolean doesRouteSupportMessaging() {
-        for (IntentFilter filter : mRoute.getControlFilters()) {
-            if (filter.hasAction(MediaControlIntent.ACTION_SEND_MESSAGE)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private void throwIfRemotePlaybackNotSupported() {
-        if (!mRouteSupportsRemotePlayback) {
-            throw new UnsupportedOperationException("The route does not support remote playback.");
-        }
-    }
-
-    private void throwIfQueuingNotSupported() {
-        if (!mRouteSupportsQueuing) {
-            throw new UnsupportedOperationException("The route does not support queuing.");
-        }
-    }
-
-    private void throwIfSessionManagementNotSupported() {
-        if (!mRouteSupportsSessionManagement) {
-            throw new UnsupportedOperationException("The route does not support "
-                    + "session management.");
-        }
-    }
-
-    private void throwIfMessageNotSupported() {
-        if (!mRouteSupportsMessaging) {
-            throw new UnsupportedOperationException("The route does not support message.");
-        }
-    }
-
-    private void throwIfNoCurrentSession() {
-        if (mSessionId == null) {
-            throw new IllegalStateException("There is no current session.");
-        }
-    }
-
-    static String inferMissingResult(String request, String result) {
-        if (result == null) {
-            // Result is missing.
-            return request;
-        }
-        if (request == null || request.equals(result)) {
-            // Request didn't specify a value or result matches request.
-            return result;
-        }
-        // Result conflicts with request.
-        return null;
-    }
-
-    private static void logRequest(Intent intent) {
-        if (DEBUG) {
-            Log.d(TAG, "Sending request: " + intent);
-        }
-    }
-
-    static String bundleToString(Bundle bundle) {
-        if (bundle != null) {
-            bundle.size(); // force bundle to be unparcelled
-            return bundle.toString();
-        }
-        return "null";
-    }
-
-    private final class ActionReceiver extends BroadcastReceiver {
-        public static final String ACTION_ITEM_STATUS_CHANGED =
-                "android.support.v7.media.actions.ACTION_ITEM_STATUS_CHANGED";
-        public static final String ACTION_SESSION_STATUS_CHANGED =
-                "android.support.v7.media.actions.ACTION_SESSION_STATUS_CHANGED";
-        public static final String ACTION_MESSAGE_RECEIVED =
-                "android.support.v7.media.actions.ACTION_MESSAGE_RECEIVED";
-
-        ActionReceiver() {
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String sessionId = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID);
-            if (sessionId == null || !sessionId.equals(mSessionId)) {
-                Log.w(TAG, "Discarding spurious status callback "
-                        + "with missing or invalid session id: sessionId=" + sessionId);
-                return;
-            }
-
-            MediaSessionStatus sessionStatus = MediaSessionStatus.fromBundle(
-                    intent.getBundleExtra(MediaControlIntent.EXTRA_SESSION_STATUS));
-            String action = intent.getAction();
-            if (action.equals(ACTION_ITEM_STATUS_CHANGED)) {
-                String itemId = intent.getStringExtra(MediaControlIntent.EXTRA_ITEM_ID);
-                if (itemId == null) {
-                    Log.w(TAG, "Discarding spurious status callback with missing item id.");
-                    return;
-                }
-
-                MediaItemStatus itemStatus = MediaItemStatus.fromBundle(
-                        intent.getBundleExtra(MediaControlIntent.EXTRA_ITEM_STATUS));
-                if (itemStatus == null) {
-                    Log.w(TAG, "Discarding spurious status callback with missing item status.");
-                    return;
-                }
-
-                if (DEBUG) {
-                    Log.d(TAG, "Received item status callback: sessionId=" + sessionId
-                            + ", sessionStatus=" + sessionStatus
-                            + ", itemId=" + itemId
-                            + ", itemStatus=" + itemStatus);
-                }
-
-                if (mStatusCallback != null) {
-                    mStatusCallback.onItemStatusChanged(intent.getExtras(),
-                            sessionId, sessionStatus, itemId, itemStatus);
-                }
-            } else if (action.equals(ACTION_SESSION_STATUS_CHANGED)) {
-                if (sessionStatus == null) {
-                    Log.w(TAG, "Discarding spurious media status callback with "
-                            +"missing session status.");
-                    return;
-                }
-
-                if (DEBUG) {
-                    Log.d(TAG, "Received session status callback: sessionId=" + sessionId
-                            + ", sessionStatus=" + sessionStatus);
-                }
-
-                if (mStatusCallback != null) {
-                    mStatusCallback.onSessionStatusChanged(intent.getExtras(),
-                            sessionId, sessionStatus);
-                }
-            } else if (action.equals(ACTION_MESSAGE_RECEIVED)) {
-                if (DEBUG) {
-                    Log.d(TAG, "Received message callback: sessionId=" + sessionId);
-                }
-
-                if (mOnMessageReceivedListener != null) {
-                    mOnMessageReceivedListener.onMessageReceived(sessionId,
-                            intent.getBundleExtra(MediaControlIntent.EXTRA_MESSAGE));
-                }
-            }
-        }
-    }
-
-    /**
-     * A callback that will receive media status updates.
-     */
-    public static abstract class StatusCallback {
-        /**
-         * Called when the status of a media item changes.
-         *
-         * @param data The result data bundle.
-         * @param sessionId The session id.
-         * @param sessionStatus The session status, or null if unknown.
-         * @param itemId The item id.
-         * @param itemStatus The item status.
-         */
-        public void onItemStatusChanged(Bundle data,
-                String sessionId, MediaSessionStatus sessionStatus,
-                String itemId, MediaItemStatus itemStatus) {
-        }
-
-        /**
-         * Called when the status of a media session changes.
-         *
-         * @param data The result data bundle.
-         * @param sessionId The session id.
-         * @param sessionStatus The session status, or null if unknown.
-         */
-        public void onSessionStatusChanged(Bundle data,
-                String sessionId, MediaSessionStatus sessionStatus) {
-        }
-
-        /**
-         * Called when the session of the remote playback client changes.
-         *
-         * @param sessionId The new session id.
-         */
-        public void onSessionChanged(String sessionId) {
-        }
-    }
-
-    /**
-     * Base callback type for remote playback requests.
-     */
-    public static abstract class ActionCallback {
-        /**
-         * Called when a media control request fails.
-         *
-         * @param error A localized error message which may be shown to the user, or null
-         * if the cause of the error is unclear.
-         * @param code The error code, or {@link MediaControlIntent#ERROR_UNKNOWN} if unknown.
-         * @param data The error data bundle, or null if none.
-         */
-        public void onError(String error, int code, Bundle data) {
-        }
-    }
-
-    /**
-     * Callback for remote playback requests that operate on items.
-     */
-    public static abstract class ItemActionCallback extends ActionCallback {
-        /**
-         * Called when the request succeeds.
-         *
-         * @param data The result data bundle.
-         * @param sessionId The session id.
-         * @param sessionStatus The session status, or null if unknown.
-         * @param itemId The item id.
-         * @param itemStatus The item status.
-         */
-        public void onResult(Bundle data, String sessionId, MediaSessionStatus sessionStatus,
-                String itemId, MediaItemStatus itemStatus) {
-        }
-    }
-
-    /**
-     * Callback for remote playback requests that operate on sessions.
-     */
-    public static abstract class SessionActionCallback extends ActionCallback {
-        /**
-         * Called when the request succeeds.
-         *
-         * @param data The result data bundle.
-         * @param sessionId The session id.
-         * @param sessionStatus The session status, or null if unknown.
-         */
-        public void onResult(Bundle data, String sessionId, MediaSessionStatus sessionStatus) {
-        }
-    }
-
-    /**
-     * A callback that will receive messages from media sessions.
-     */
-    public interface OnMessageReceivedListener {
-        /**
-         * Called when a message received.
-         *
-         * @param sessionId The session id.
-         * @param message A bundle message denoting {@link MediaControlIntent#EXTRA_MESSAGE}.
-         */
-        void onMessageReceived(String sessionId, Bundle message);
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/SystemMediaRouteProvider.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/SystemMediaRouteProvider.java
deleted file mode 100644
index a38491f..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/SystemMediaRouteProvider.java
+++ /dev/null
@@ -1,883 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.support.mediarouter.media;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.media.AudioManager;
-import android.os.Build;
-import android.support.annotation.RequiresApi;
-import android.view.Display;
-
-import com.android.media.update.ApiHelper;
-import com.android.media.update.R;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-
-/**
- * Provides routes for built-in system destinations such as the local display
- * and speaker.  On Jellybean and newer platform releases, queries the framework
- * MediaRouter for framework-provided routes and registers non-framework-provided
- * routes as user routes.
- */
-abstract class SystemMediaRouteProvider extends MediaRouteProvider {
-    private static final String TAG = "SystemMediaRouteProvider";
-
-    public static final String PACKAGE_NAME = "android";
-    public static final String DEFAULT_ROUTE_ID = "DEFAULT_ROUTE";
-
-    protected SystemMediaRouteProvider(Context context) {
-        super(context, new ProviderMetadata(new ComponentName(PACKAGE_NAME,
-                SystemMediaRouteProvider.class.getName())));
-    }
-
-    public static SystemMediaRouteProvider obtain(Context context, SyncCallback syncCallback) {
-        if (Build.VERSION.SDK_INT >= 24) {
-            return new Api24Impl(context, syncCallback);
-        }
-        if (Build.VERSION.SDK_INT >= 18) {
-            return new JellybeanMr2Impl(context, syncCallback);
-        }
-        if (Build.VERSION.SDK_INT >= 17) {
-            return new JellybeanMr1Impl(context, syncCallback);
-        }
-        if (Build.VERSION.SDK_INT >= 16) {
-            return new JellybeanImpl(context, syncCallback);
-        }
-        return new LegacyImpl(context);
-    }
-
-    /**
-     * Called by the media router when a route is added to synchronize state with
-     * the framework media router.
-     */
-    public void onSyncRouteAdded(MediaRouter.RouteInfo route) {
-    }
-
-    /**
-     * Called by the media router when a route is removed to synchronize state with
-     * the framework media router.
-     */
-    public void onSyncRouteRemoved(MediaRouter.RouteInfo route) {
-    }
-
-    /**
-     * Called by the media router when a route is changed to synchronize state with
-     * the framework media router.
-     */
-    public void onSyncRouteChanged(MediaRouter.RouteInfo route) {
-    }
-
-    /**
-     * Called by the media router when a route is selected to synchronize state with
-     * the framework media router.
-     */
-    public void onSyncRouteSelected(MediaRouter.RouteInfo route) {
-    }
-
-    /**
-     * Callbacks into the media router to synchronize state with the framework media router.
-     */
-    public interface SyncCallback {
-        void onSystemRouteSelectedByDescriptorId(String id);
-    }
-
-    protected Object getDefaultRoute() {
-        return null;
-    }
-
-    protected Object getSystemRoute(MediaRouter.RouteInfo route) {
-        return null;
-    }
-
-    /**
-     * Legacy implementation for platform versions prior to Jellybean.
-     */
-    static class LegacyImpl extends SystemMediaRouteProvider {
-        static final int PLAYBACK_STREAM = AudioManager.STREAM_MUSIC;
-
-        private static final ArrayList<IntentFilter> CONTROL_FILTERS;
-        static {
-            IntentFilter f = new IntentFilter();
-            f.addCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO);
-            f.addCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO);
-
-            CONTROL_FILTERS = new ArrayList<IntentFilter>();
-            CONTROL_FILTERS.add(f);
-        }
-
-        final AudioManager mAudioManager;
-        private final VolumeChangeReceiver mVolumeChangeReceiver;
-        int mLastReportedVolume = -1;
-
-        public LegacyImpl(Context context) {
-            super(context);
-            mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
-            mVolumeChangeReceiver = new VolumeChangeReceiver();
-
-            context.registerReceiver(mVolumeChangeReceiver,
-                    new IntentFilter(VolumeChangeReceiver.VOLUME_CHANGED_ACTION));
-            publishRoutes();
-        }
-
-        void publishRoutes() {
-            Resources r = getContext().getResources();
-            int maxVolume = mAudioManager.getStreamMaxVolume(PLAYBACK_STREAM);
-            mLastReportedVolume = mAudioManager.getStreamVolume(PLAYBACK_STREAM);
-            MediaRouteDescriptor defaultRoute = new MediaRouteDescriptor.Builder(
-                    DEFAULT_ROUTE_ID, r.getString(R.string.mr_system_route_name))
-                    .addControlFilters(CONTROL_FILTERS)
-                    .setPlaybackStream(PLAYBACK_STREAM)
-                    .setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_LOCAL)
-                    .setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE)
-                    .setVolumeMax(maxVolume)
-                    .setVolume(mLastReportedVolume)
-                    .build();
-
-            MediaRouteProviderDescriptor providerDescriptor =
-                    new MediaRouteProviderDescriptor.Builder()
-                    .addRoute(defaultRoute)
-                    .build();
-            setDescriptor(providerDescriptor);
-        }
-
-        @Override
-        public RouteController onCreateRouteController(String routeId) {
-            if (routeId.equals(DEFAULT_ROUTE_ID)) {
-                return new DefaultRouteController();
-            }
-            return null;
-        }
-
-        final class DefaultRouteController extends RouteController {
-            @Override
-            public void onSetVolume(int volume) {
-                mAudioManager.setStreamVolume(PLAYBACK_STREAM, volume, 0);
-                publishRoutes();
-            }
-
-            @Override
-            public void onUpdateVolume(int delta) {
-                int volume = mAudioManager.getStreamVolume(PLAYBACK_STREAM);
-                int maxVolume = mAudioManager.getStreamMaxVolume(PLAYBACK_STREAM);
-                int newVolume = Math.min(maxVolume, Math.max(0, volume + delta));
-                if (newVolume != volume) {
-                    mAudioManager.setStreamVolume(PLAYBACK_STREAM, volume, 0);
-                }
-                publishRoutes();
-            }
-        }
-
-        final class VolumeChangeReceiver extends BroadcastReceiver {
-            // These constants come from AudioManager.
-            public static final String VOLUME_CHANGED_ACTION =
-                    "android.media.VOLUME_CHANGED_ACTION";
-            public static final String EXTRA_VOLUME_STREAM_TYPE =
-                    "android.media.EXTRA_VOLUME_STREAM_TYPE";
-            public static final String EXTRA_VOLUME_STREAM_VALUE =
-                    "android.media.EXTRA_VOLUME_STREAM_VALUE";
-
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                if (intent.getAction().equals(VOLUME_CHANGED_ACTION)) {
-                    final int streamType = intent.getIntExtra(EXTRA_VOLUME_STREAM_TYPE, -1);
-                    if (streamType == PLAYBACK_STREAM) {
-                        final int volume = intent.getIntExtra(EXTRA_VOLUME_STREAM_VALUE, -1);
-                        if (volume >= 0 && volume != mLastReportedVolume) {
-                            publishRoutes();
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Jellybean implementation.
-     */
-    // @@RequiresApi(16)
-    static class JellybeanImpl extends SystemMediaRouteProvider
-            implements MediaRouterJellybean.Callback, MediaRouterJellybean.VolumeCallback {
-        private static final ArrayList<IntentFilter> LIVE_AUDIO_CONTROL_FILTERS;
-        static {
-            IntentFilter f = new IntentFilter();
-            f.addCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO);
-
-            LIVE_AUDIO_CONTROL_FILTERS = new ArrayList<IntentFilter>();
-            LIVE_AUDIO_CONTROL_FILTERS.add(f);
-        }
-
-        private static final ArrayList<IntentFilter> LIVE_VIDEO_CONTROL_FILTERS;
-        static {
-            IntentFilter f = new IntentFilter();
-            f.addCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO);
-
-            LIVE_VIDEO_CONTROL_FILTERS = new ArrayList<IntentFilter>();
-            LIVE_VIDEO_CONTROL_FILTERS.add(f);
-        }
-
-        private final SyncCallback mSyncCallback;
-
-        protected final Object mRouterObj;
-        protected final Object mCallbackObj;
-        protected final Object mVolumeCallbackObj;
-        protected final Object mUserRouteCategoryObj;
-        protected int mRouteTypes;
-        protected boolean mActiveScan;
-        protected boolean mCallbackRegistered;
-
-        // Maintains an association from framework routes to support library routes.
-        // Note that we cannot use the tag field for this because an application may
-        // have published its own user routes to the framework media router and already
-        // used the tag for its own purposes.
-        protected final ArrayList<SystemRouteRecord> mSystemRouteRecords =
-                new ArrayList<SystemRouteRecord>();
-
-        // Maintains an association from support library routes to framework routes.
-        protected final ArrayList<UserRouteRecord> mUserRouteRecords =
-                new ArrayList<UserRouteRecord>();
-
-        private MediaRouterJellybean.SelectRouteWorkaround mSelectRouteWorkaround;
-        private MediaRouterJellybean.GetDefaultRouteWorkaround mGetDefaultRouteWorkaround;
-
-        public JellybeanImpl(Context context, SyncCallback syncCallback) {
-            super(context);
-            mSyncCallback = syncCallback;
-            mRouterObj = MediaRouterJellybean.getMediaRouter(context);
-            mCallbackObj = createCallbackObj();
-            mVolumeCallbackObj = createVolumeCallbackObj();
-
-            Resources r = ApiHelper.getLibResources(context);
-            mUserRouteCategoryObj = MediaRouterJellybean.createRouteCategory(
-                    mRouterObj, r.getString(R.string.mr_user_route_category_name), false);
-
-            updateSystemRoutes();
-        }
-
-        @Override
-        public RouteController onCreateRouteController(String routeId) {
-            int index = findSystemRouteRecordByDescriptorId(routeId);
-            if (index >= 0) {
-                SystemRouteRecord record = mSystemRouteRecords.get(index);
-                return new SystemRouteController(record.mRouteObj);
-            }
-            return null;
-        }
-
-        @Override
-        public void onDiscoveryRequestChanged(MediaRouteDiscoveryRequest request) {
-            int newRouteTypes = 0;
-            boolean newActiveScan = false;
-            if (request != null) {
-                final MediaRouteSelector selector = request.getSelector();
-                final List<String> categories = selector.getControlCategories();
-                final int count = categories.size();
-                for (int i = 0; i < count; i++) {
-                    String category = categories.get(i);
-                    if (category.equals(MediaControlIntent.CATEGORY_LIVE_AUDIO)) {
-                        newRouteTypes |= MediaRouterJellybean.ROUTE_TYPE_LIVE_AUDIO;
-                    } else if (category.equals(MediaControlIntent.CATEGORY_LIVE_VIDEO)) {
-                        newRouteTypes |= MediaRouterJellybean.ROUTE_TYPE_LIVE_VIDEO;
-                    } else {
-                        newRouteTypes |= MediaRouterJellybean.ROUTE_TYPE_USER;
-                    }
-                }
-                newActiveScan = request.isActiveScan();
-            }
-
-            if (mRouteTypes != newRouteTypes || mActiveScan != newActiveScan) {
-                mRouteTypes = newRouteTypes;
-                mActiveScan = newActiveScan;
-                updateSystemRoutes();
-            }
-        }
-
-        @Override
-        public void onRouteAdded(Object routeObj) {
-            if (addSystemRouteNoPublish(routeObj)) {
-                publishRoutes();
-            }
-        }
-
-        private void updateSystemRoutes() {
-            updateCallback();
-            boolean changed = false;
-            for (Object routeObj : MediaRouterJellybean.getRoutes(mRouterObj)) {
-                changed |= addSystemRouteNoPublish(routeObj);
-            }
-            if (changed) {
-                publishRoutes();
-            }
-        }
-
-        private boolean addSystemRouteNoPublish(Object routeObj) {
-            if (getUserRouteRecord(routeObj) == null
-                    && findSystemRouteRecord(routeObj) < 0) {
-                String id = assignRouteId(routeObj);
-                SystemRouteRecord record = new SystemRouteRecord(routeObj, id);
-                updateSystemRouteDescriptor(record);
-                mSystemRouteRecords.add(record);
-                return true;
-            }
-            return false;
-        }
-
-        private String assignRouteId(Object routeObj) {
-            // TODO: The framework media router should supply a unique route id that
-            // we can use here.  For now we use a hash of the route name and take care
-            // to dedupe it.
-            boolean isDefault = (getDefaultRoute() == routeObj);
-            String id = isDefault ? DEFAULT_ROUTE_ID :
-                    String.format(Locale.US, "ROUTE_%08x", getRouteName(routeObj).hashCode());
-            if (findSystemRouteRecordByDescriptorId(id) < 0) {
-                return id;
-            }
-            for (int i = 2; ; i++) {
-                String newId = String.format(Locale.US, "%s_%d", id, i);
-                if (findSystemRouteRecordByDescriptorId(newId) < 0) {
-                    return newId;
-                }
-            }
-        }
-
-        @Override
-        public void onRouteRemoved(Object routeObj) {
-            if (getUserRouteRecord(routeObj) == null) {
-                int index = findSystemRouteRecord(routeObj);
-                if (index >= 0) {
-                    mSystemRouteRecords.remove(index);
-                    publishRoutes();
-                }
-            }
-        }
-
-        @Override
-        public void onRouteChanged(Object routeObj) {
-            if (getUserRouteRecord(routeObj) == null) {
-                int index = findSystemRouteRecord(routeObj);
-                if (index >= 0) {
-                    SystemRouteRecord record = mSystemRouteRecords.get(index);
-                    updateSystemRouteDescriptor(record);
-                    publishRoutes();
-                }
-            }
-        }
-
-        @Override
-        public void onRouteVolumeChanged(Object routeObj) {
-            if (getUserRouteRecord(routeObj) == null) {
-                int index = findSystemRouteRecord(routeObj);
-                if (index >= 0) {
-                    SystemRouteRecord record = mSystemRouteRecords.get(index);
-                    int newVolume = MediaRouterJellybean.RouteInfo.getVolume(routeObj);
-                    if (newVolume != record.mRouteDescriptor.getVolume()) {
-                        record.mRouteDescriptor =
-                                new MediaRouteDescriptor.Builder(record.mRouteDescriptor)
-                                .setVolume(newVolume)
-                                .build();
-                        publishRoutes();
-                    }
-                }
-            }
-        }
-
-        @Override
-        public void onRouteSelected(int type, Object routeObj) {
-            if (routeObj != MediaRouterJellybean.getSelectedRoute(mRouterObj,
-                    MediaRouterJellybean.ALL_ROUTE_TYPES)) {
-                // The currently selected route has already changed so this callback
-                // is stale.  Drop it to prevent getting into sync loops.
-                return;
-            }
-
-            UserRouteRecord userRouteRecord = getUserRouteRecord(routeObj);
-            if (userRouteRecord != null) {
-                userRouteRecord.mRoute.select();
-            } else {
-                // Select the route if it already exists in the compat media router.
-                // If not, we will select it instead when the route is added.
-                int index = findSystemRouteRecord(routeObj);
-                if (index >= 0) {
-                    SystemRouteRecord record = mSystemRouteRecords.get(index);
-                    mSyncCallback.onSystemRouteSelectedByDescriptorId(record.mRouteDescriptorId);
-                }
-            }
-        }
-
-        @Override
-        public void onRouteUnselected(int type, Object routeObj) {
-            // Nothing to do when a route is unselected.
-            // We only need to handle when a route is selected.
-        }
-
-        @Override
-        public void onRouteGrouped(Object routeObj, Object groupObj, int index) {
-            // Route grouping is deprecated and no longer supported.
-        }
-
-        @Override
-        public void onRouteUngrouped(Object routeObj, Object groupObj) {
-            // Route grouping is deprecated and no longer supported.
-        }
-
-        @Override
-        public void onVolumeSetRequest(Object routeObj, int volume) {
-            UserRouteRecord record = getUserRouteRecord(routeObj);
-            if (record != null) {
-                record.mRoute.requestSetVolume(volume);
-            }
-        }
-
-        @Override
-        public void onVolumeUpdateRequest(Object routeObj, int direction) {
-            UserRouteRecord record = getUserRouteRecord(routeObj);
-            if (record != null) {
-                record.mRoute.requestUpdateVolume(direction);
-            }
-        }
-
-        @Override
-        public void onSyncRouteAdded(MediaRouter.RouteInfo route) {
-            if (route.getProviderInstance() != this) {
-                Object routeObj = MediaRouterJellybean.createUserRoute(
-                        mRouterObj, mUserRouteCategoryObj);
-                UserRouteRecord record = new UserRouteRecord(route, routeObj);
-                MediaRouterJellybean.RouteInfo.setTag(routeObj, record);
-                MediaRouterJellybean.UserRouteInfo.setVolumeCallback(routeObj, mVolumeCallbackObj);
-                updateUserRouteProperties(record);
-                mUserRouteRecords.add(record);
-                MediaRouterJellybean.addUserRoute(mRouterObj, routeObj);
-            } else {
-                // If the newly added route is the counterpart of the currently selected
-                // route in the framework media router then ensure it is selected in
-                // the compat media router.
-                Object routeObj = MediaRouterJellybean.getSelectedRoute(
-                        mRouterObj, MediaRouterJellybean.ALL_ROUTE_TYPES);
-                int index = findSystemRouteRecord(routeObj);
-                if (index >= 0) {
-                    SystemRouteRecord record = mSystemRouteRecords.get(index);
-                    if (record.mRouteDescriptorId.equals(route.getDescriptorId())) {
-                        route.select();
-                    }
-                }
-            }
-        }
-
-        @Override
-        public void onSyncRouteRemoved(MediaRouter.RouteInfo route) {
-            if (route.getProviderInstance() != this) {
-                int index = findUserRouteRecord(route);
-                if (index >= 0) {
-                    UserRouteRecord record = mUserRouteRecords.remove(index);
-                    MediaRouterJellybean.RouteInfo.setTag(record.mRouteObj, null);
-                    MediaRouterJellybean.UserRouteInfo.setVolumeCallback(record.mRouteObj, null);
-                    MediaRouterJellybean.removeUserRoute(mRouterObj, record.mRouteObj);
-                }
-            }
-        }
-
-        @Override
-        public void onSyncRouteChanged(MediaRouter.RouteInfo route) {
-            if (route.getProviderInstance() != this) {
-                int index = findUserRouteRecord(route);
-                if (index >= 0) {
-                    UserRouteRecord record = mUserRouteRecords.get(index);
-                    updateUserRouteProperties(record);
-                }
-            }
-        }
-
-        @Override
-        public void onSyncRouteSelected(MediaRouter.RouteInfo route) {
-            if (!route.isSelected()) {
-                // The currently selected route has already changed so this callback
-                // is stale.  Drop it to prevent getting into sync loops.
-                return;
-            }
-
-            if (route.getProviderInstance() != this) {
-                int index = findUserRouteRecord(route);
-                if (index >= 0) {
-                    UserRouteRecord record = mUserRouteRecords.get(index);
-                    selectRoute(record.mRouteObj);
-                }
-            } else {
-                int index = findSystemRouteRecordByDescriptorId(route.getDescriptorId());
-                if (index >= 0) {
-                    SystemRouteRecord record = mSystemRouteRecords.get(index);
-                    selectRoute(record.mRouteObj);
-                }
-            }
-        }
-
-        protected void publishRoutes() {
-            MediaRouteProviderDescriptor.Builder builder =
-                    new MediaRouteProviderDescriptor.Builder();
-            int count = mSystemRouteRecords.size();
-            for (int i = 0; i < count; i++) {
-                builder.addRoute(mSystemRouteRecords.get(i).mRouteDescriptor);
-            }
-
-            setDescriptor(builder.build());
-        }
-
-        protected int findSystemRouteRecord(Object routeObj) {
-            final int count = mSystemRouteRecords.size();
-            for (int i = 0; i < count; i++) {
-                if (mSystemRouteRecords.get(i).mRouteObj == routeObj) {
-                    return i;
-                }
-            }
-            return -1;
-        }
-
-        protected int findSystemRouteRecordByDescriptorId(String id) {
-            final int count = mSystemRouteRecords.size();
-            for (int i = 0; i < count; i++) {
-                if (mSystemRouteRecords.get(i).mRouteDescriptorId.equals(id)) {
-                    return i;
-                }
-            }
-            return -1;
-        }
-
-        protected int findUserRouteRecord(MediaRouter.RouteInfo route) {
-            final int count = mUserRouteRecords.size();
-            for (int i = 0; i < count; i++) {
-                if (mUserRouteRecords.get(i).mRoute == route) {
-                    return i;
-                }
-            }
-            return -1;
-        }
-
-        protected UserRouteRecord getUserRouteRecord(Object routeObj) {
-            Object tag = MediaRouterJellybean.RouteInfo.getTag(routeObj);
-            return tag instanceof UserRouteRecord ? (UserRouteRecord)tag : null;
-        }
-
-        protected void updateSystemRouteDescriptor(SystemRouteRecord record) {
-            // We must always recreate the route descriptor when making any changes
-            // because they are intended to be immutable once published.
-            MediaRouteDescriptor.Builder builder = new MediaRouteDescriptor.Builder(
-                    record.mRouteDescriptorId, getRouteName(record.mRouteObj));
-            onBuildSystemRouteDescriptor(record, builder);
-            record.mRouteDescriptor = builder.build();
-        }
-
-        protected String getRouteName(Object routeObj) {
-            // Routes should not have null names but it may happen for badly configured
-            // user routes.  We tolerate this by using an empty name string here but
-            // such unnamed routes will be discarded by the media router upstream
-            // (with a log message so we can track down the problem).
-            CharSequence name = MediaRouterJellybean.RouteInfo.getName(routeObj, getContext());
-            return name != null ? name.toString() : "";
-        }
-
-        protected void onBuildSystemRouteDescriptor(SystemRouteRecord record,
-                MediaRouteDescriptor.Builder builder) {
-            int supportedTypes = MediaRouterJellybean.RouteInfo.getSupportedTypes(
-                    record.mRouteObj);
-            if ((supportedTypes & MediaRouterJellybean.ROUTE_TYPE_LIVE_AUDIO) != 0) {
-                builder.addControlFilters(LIVE_AUDIO_CONTROL_FILTERS);
-            }
-            if ((supportedTypes & MediaRouterJellybean.ROUTE_TYPE_LIVE_VIDEO) != 0) {
-                builder.addControlFilters(LIVE_VIDEO_CONTROL_FILTERS);
-            }
-
-            builder.setPlaybackType(
-                    MediaRouterJellybean.RouteInfo.getPlaybackType(record.mRouteObj));
-            builder.setPlaybackStream(
-                    MediaRouterJellybean.RouteInfo.getPlaybackStream(record.mRouteObj));
-            builder.setVolume(
-                    MediaRouterJellybean.RouteInfo.getVolume(record.mRouteObj));
-            builder.setVolumeMax(
-                    MediaRouterJellybean.RouteInfo.getVolumeMax(record.mRouteObj));
-            builder.setVolumeHandling(
-                    MediaRouterJellybean.RouteInfo.getVolumeHandling(record.mRouteObj));
-        }
-
-        protected void updateUserRouteProperties(UserRouteRecord record) {
-            MediaRouterJellybean.UserRouteInfo.setName(
-                    record.mRouteObj, record.mRoute.getName());
-            MediaRouterJellybean.UserRouteInfo.setPlaybackType(
-                    record.mRouteObj, record.mRoute.getPlaybackType());
-            MediaRouterJellybean.UserRouteInfo.setPlaybackStream(
-                    record.mRouteObj, record.mRoute.getPlaybackStream());
-            MediaRouterJellybean.UserRouteInfo.setVolume(
-                    record.mRouteObj, record.mRoute.getVolume());
-            MediaRouterJellybean.UserRouteInfo.setVolumeMax(
-                    record.mRouteObj, record.mRoute.getVolumeMax());
-            MediaRouterJellybean.UserRouteInfo.setVolumeHandling(
-                    record.mRouteObj, record.mRoute.getVolumeHandling());
-        }
-
-        protected void updateCallback() {
-            if (mCallbackRegistered) {
-                mCallbackRegistered = false;
-                MediaRouterJellybean.removeCallback(mRouterObj, mCallbackObj);
-            }
-
-            if (mRouteTypes != 0) {
-                mCallbackRegistered = true;
-                MediaRouterJellybean.addCallback(mRouterObj, mRouteTypes, mCallbackObj);
-            }
-        }
-
-        protected Object createCallbackObj() {
-            return MediaRouterJellybean.createCallback(this);
-        }
-
-        protected Object createVolumeCallbackObj() {
-            return MediaRouterJellybean.createVolumeCallback(this);
-        }
-
-        protected void selectRoute(Object routeObj) {
-            if (mSelectRouteWorkaround == null) {
-                mSelectRouteWorkaround = new MediaRouterJellybean.SelectRouteWorkaround();
-            }
-            mSelectRouteWorkaround.selectRoute(mRouterObj,
-                    MediaRouterJellybean.ALL_ROUTE_TYPES, routeObj);
-        }
-
-        @Override
-        protected Object getDefaultRoute() {
-            if (mGetDefaultRouteWorkaround == null) {
-                mGetDefaultRouteWorkaround = new MediaRouterJellybean.GetDefaultRouteWorkaround();
-            }
-            return mGetDefaultRouteWorkaround.getDefaultRoute(mRouterObj);
-        }
-
-        @Override
-        protected Object getSystemRoute(MediaRouter.RouteInfo route) {
-            if (route == null) {
-                return null;
-            }
-            int index = findSystemRouteRecordByDescriptorId(route.getDescriptorId());
-            if (index >= 0) {
-                return mSystemRouteRecords.get(index).mRouteObj;
-            }
-            return null;
-        }
-
-        /**
-         * Represents a route that is provided by the framework media router
-         * and published by this route provider to the support library media router.
-         */
-        protected static final class SystemRouteRecord {
-            public final Object mRouteObj;
-            public final String mRouteDescriptorId;
-            public MediaRouteDescriptor mRouteDescriptor; // assigned immediately after creation
-
-            public SystemRouteRecord(Object routeObj, String id) {
-                mRouteObj = routeObj;
-                mRouteDescriptorId = id;
-            }
-        }
-
-        /**
-         * Represents a route that is provided by the support library media router
-         * and published by this route provider to the framework media router.
-         */
-        protected static final class UserRouteRecord {
-            public final MediaRouter.RouteInfo mRoute;
-            public final Object mRouteObj;
-
-            public UserRouteRecord(MediaRouter.RouteInfo route, Object routeObj) {
-                mRoute = route;
-                mRouteObj = routeObj;
-            }
-        }
-
-        protected static final class SystemRouteController extends RouteController {
-            private final Object mRouteObj;
-
-            public SystemRouteController(Object routeObj) {
-                mRouteObj = routeObj;
-            }
-
-            @Override
-            public void onSetVolume(int volume) {
-                MediaRouterJellybean.RouteInfo.requestSetVolume(mRouteObj, volume);
-            }
-
-            @Override
-            public void onUpdateVolume(int delta) {
-                MediaRouterJellybean.RouteInfo.requestUpdateVolume(mRouteObj, delta);
-            }
-        }
-    }
-
-    /**
-     * Jellybean MR1 implementation.
-     */
-    // @@RequiresApi(17)
-    private static class JellybeanMr1Impl extends JellybeanImpl
-            implements MediaRouterJellybeanMr1.Callback {
-        private MediaRouterJellybeanMr1.ActiveScanWorkaround mActiveScanWorkaround;
-        private MediaRouterJellybeanMr1.IsConnectingWorkaround mIsConnectingWorkaround;
-
-        public JellybeanMr1Impl(Context context, SyncCallback syncCallback) {
-            super(context, syncCallback);
-        }
-
-        @Override
-        public void onRoutePresentationDisplayChanged(Object routeObj) {
-            int index = findSystemRouteRecord(routeObj);
-            if (index >= 0) {
-                SystemRouteRecord record = mSystemRouteRecords.get(index);
-                Display newPresentationDisplay =
-                        MediaRouterJellybeanMr1.RouteInfo.getPresentationDisplay(routeObj);
-                int newPresentationDisplayId = (newPresentationDisplay != null
-                        ? newPresentationDisplay.getDisplayId() : -1);
-                if (newPresentationDisplayId
-                        != record.mRouteDescriptor.getPresentationDisplayId()) {
-                    record.mRouteDescriptor =
-                            new MediaRouteDescriptor.Builder(record.mRouteDescriptor)
-                            .setPresentationDisplayId(newPresentationDisplayId)
-                            .build();
-                    publishRoutes();
-                }
-            }
-        }
-
-        @Override
-        protected void onBuildSystemRouteDescriptor(SystemRouteRecord record,
-                MediaRouteDescriptor.Builder builder) {
-            super.onBuildSystemRouteDescriptor(record, builder);
-
-            if (!MediaRouterJellybeanMr1.RouteInfo.isEnabled(record.mRouteObj)) {
-                builder.setEnabled(false);
-            }
-
-            if (isConnecting(record)) {
-                builder.setConnecting(true);
-            }
-
-            Display presentationDisplay =
-                    MediaRouterJellybeanMr1.RouteInfo.getPresentationDisplay(record.mRouteObj);
-            if (presentationDisplay != null) {
-                builder.setPresentationDisplayId(presentationDisplay.getDisplayId());
-            }
-        }
-
-        @Override
-        protected void updateCallback() {
-            super.updateCallback();
-
-            if (mActiveScanWorkaround == null) {
-                mActiveScanWorkaround = new MediaRouterJellybeanMr1.ActiveScanWorkaround(
-                        getContext(), getHandler());
-            }
-            mActiveScanWorkaround.setActiveScanRouteTypes(mActiveScan ? mRouteTypes : 0);
-        }
-
-        @Override
-        protected Object createCallbackObj() {
-            return MediaRouterJellybeanMr1.createCallback(this);
-        }
-
-        protected boolean isConnecting(SystemRouteRecord record) {
-            if (mIsConnectingWorkaround == null) {
-                mIsConnectingWorkaround = new MediaRouterJellybeanMr1.IsConnectingWorkaround();
-            }
-            return mIsConnectingWorkaround.isConnecting(record.mRouteObj);
-        }
-    }
-
-    /**
-     * Jellybean MR2 implementation.
-     */
-    // @@RequiresApi(18)
-    private static class JellybeanMr2Impl extends JellybeanMr1Impl {
-        public JellybeanMr2Impl(Context context, SyncCallback syncCallback) {
-            super(context, syncCallback);
-        }
-
-        @Override
-        protected void onBuildSystemRouteDescriptor(SystemRouteRecord record,
-                MediaRouteDescriptor.Builder builder) {
-            super.onBuildSystemRouteDescriptor(record, builder);
-
-            CharSequence description =
-                    MediaRouterJellybeanMr2.RouteInfo.getDescription(record.mRouteObj);
-            if (description != null) {
-                builder.setDescription(description.toString());
-            }
-        }
-
-        @Override
-        protected void selectRoute(Object routeObj) {
-            MediaRouterJellybean.selectRoute(mRouterObj,
-                    MediaRouterJellybean.ALL_ROUTE_TYPES, routeObj);
-        }
-
-        @Override
-        protected Object getDefaultRoute() {
-            return MediaRouterJellybeanMr2.getDefaultRoute(mRouterObj);
-        }
-
-        @Override
-        protected void updateUserRouteProperties(UserRouteRecord record) {
-            super.updateUserRouteProperties(record);
-
-            MediaRouterJellybeanMr2.UserRouteInfo.setDescription(
-                    record.mRouteObj, record.mRoute.getDescription());
-        }
-
-        @Override
-        protected void updateCallback() {
-            if (mCallbackRegistered) {
-                MediaRouterJellybean.removeCallback(mRouterObj, mCallbackObj);
-            }
-
-            mCallbackRegistered = true;
-            MediaRouterJellybeanMr2.addCallback(mRouterObj, mRouteTypes, mCallbackObj,
-                    MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS
-                    | (mActiveScan ? MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN : 0));
-        }
-
-        @Override
-        protected boolean isConnecting(SystemRouteRecord record) {
-            return MediaRouterJellybeanMr2.RouteInfo.isConnecting(record.mRouteObj);
-        }
-    }
-
-    /**
-     * Api24 implementation.
-     */
-    // @@RequiresApi(24)
-    private static class Api24Impl extends JellybeanMr2Impl {
-        public Api24Impl(Context context, SyncCallback syncCallback) {
-            super(context, syncCallback);
-        }
-
-        @Override
-        protected void onBuildSystemRouteDescriptor(SystemRouteRecord record,
-                                                    MediaRouteDescriptor.Builder builder) {
-            super.onBuildSystemRouteDescriptor(record, builder);
-
-            builder.setDeviceType(MediaRouterApi24.RouteInfo.getDeviceType(record.mRouteObj));
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/package.html b/packages/MediaComponents/src/com/android/support/mediarouter/media/package.html
deleted file mode 100644
index be2aaf2..0000000
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/package.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<html>
-
-<body>
-
-<p>Contains APIs that control the routing of media channels and streams from the current device
-  to external speakers and destination devices.</p>
-
-</body>
-</html>
diff --git a/packages/MediaComponents/src/com/android/widget/BaseLayout.java b/packages/MediaComponents/src/com/android/widget/BaseLayout.java
deleted file mode 100644
index fb6471d..0000000
--- a/packages/MediaComponents/src/com/android/widget/BaseLayout.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.widget;
-
-import android.graphics.drawable.Drawable;
-import android.media.update.ViewGroupProvider;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.view.ViewGroup.MarginLayoutParams;
-
-import java.util.ArrayList;
-
-public class BaseLayout extends ViewGroupImpl {
-    private final ViewGroup mInstance;
-    private final ViewGroupProvider mSuperProvider;
-    private final ViewGroupProvider mPrivateProvider;
-
-    private final ArrayList<View> mMatchParentChildren = new ArrayList<>(1);
-
-    public BaseLayout(ViewGroup instance,
-            ViewGroupProvider superProvider, ViewGroupProvider privateProvider) {
-        super(instance, superProvider, privateProvider);
-        mInstance = instance;
-        mSuperProvider = superProvider;
-        mPrivateProvider = privateProvider;
-    }
-
-    @Override
-    public boolean checkLayoutParams_impl(LayoutParams p) {
-        return p instanceof MarginLayoutParams;
-    }
-
-    @Override
-    public LayoutParams generateDefaultLayoutParams_impl() {
-        return new MarginLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
-    }
-
-    @Override
-    public LayoutParams generateLayoutParams_impl(AttributeSet attrs) {
-        return new MarginLayoutParams(mInstance.getContext(), attrs);
-    }
-
-    @Override
-    public LayoutParams generateLayoutParams_impl(LayoutParams lp) {
-        if (lp instanceof MarginLayoutParams) {
-            return lp;
-        }
-        return new MarginLayoutParams(lp);
-    }
-
-    @Override
-    public void onMeasure_impl(int widthMeasureSpec, int heightMeasureSpec) {
-        int count = mInstance.getChildCount();
-
-        final boolean measureMatchParentChildren =
-                View.MeasureSpec.getMode(widthMeasureSpec) != View.MeasureSpec.EXACTLY ||
-                        View.MeasureSpec.getMode(heightMeasureSpec) != View.MeasureSpec.EXACTLY;
-        mMatchParentChildren.clear();
-
-        int maxHeight = 0;
-        int maxWidth = 0;
-        int childState = 0;
-
-        for (int i = 0; i < count; i++) {
-            final View child = mInstance.getChildAt(i);
-            if (child.getVisibility() != View.GONE) {
-                mPrivateProvider.measureChildWithMargins_impl(
-                        child, widthMeasureSpec, 0, heightMeasureSpec, 0);
-                final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
-                maxWidth = Math.max(maxWidth,
-                        child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
-                maxHeight = Math.max(maxHeight,
-                        child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
-                childState = childState | child.getMeasuredState();
-                if (measureMatchParentChildren) {
-                    if (lp.width == LayoutParams.MATCH_PARENT ||
-                            lp.height == LayoutParams.MATCH_PARENT) {
-                        mMatchParentChildren.add(child);
-                    }
-                }
-            }
-        }
-
-        // Account for padding too
-        maxWidth += getPaddingLeftWithForeground() + getPaddingRightWithForeground();
-        maxHeight += getPaddingTopWithForeground() + getPaddingBottomWithForeground();
-
-        // Check against our minimum height and width
-        maxHeight = Math.max(maxHeight, mPrivateProvider.getSuggestedMinimumHeight_impl());
-        maxWidth = Math.max(maxWidth, mPrivateProvider.getSuggestedMinimumWidth_impl());
-
-        // Check against our foreground's minimum height and width
-        final Drawable drawable = mInstance.getForeground();
-        if (drawable != null) {
-            maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
-            maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
-        }
-
-        mPrivateProvider.setMeasuredDimension_impl(
-                mInstance.resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
-                mInstance.resolveSizeAndState(maxHeight, heightMeasureSpec,
-                        childState << View.MEASURED_HEIGHT_STATE_SHIFT));
-
-        count = mMatchParentChildren.size();
-        if (count > 1) {
-            for (int i = 0; i < count; i++) {
-                final View child = mMatchParentChildren.get(i);
-                final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
-
-                final int childWidthMeasureSpec;
-                if (lp.width == LayoutParams.MATCH_PARENT) {
-                    final int width = Math.max(0, mInstance.getMeasuredWidth()
-                            - getPaddingLeftWithForeground() - getPaddingRightWithForeground()
-                            - lp.leftMargin - lp.rightMargin);
-                    childWidthMeasureSpec = View.MeasureSpec.makeMeasureSpec(
-                            width, View.MeasureSpec.EXACTLY);
-                } else {
-                    childWidthMeasureSpec = mInstance.getChildMeasureSpec(widthMeasureSpec,
-                            getPaddingLeftWithForeground() + getPaddingRightWithForeground() +
-                                    lp.leftMargin + lp.rightMargin,
-                            lp.width);
-                }
-
-                final int childHeightMeasureSpec;
-                if (lp.height == LayoutParams.MATCH_PARENT) {
-                    final int height = Math.max(0, mInstance.getMeasuredHeight()
-                            - getPaddingTopWithForeground() - getPaddingBottomWithForeground()
-                            - lp.topMargin - lp.bottomMargin);
-                    childHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec(
-                            height, View.MeasureSpec.EXACTLY);
-                } else {
-                    childHeightMeasureSpec = mInstance.getChildMeasureSpec(heightMeasureSpec,
-                            getPaddingTopWithForeground() + getPaddingBottomWithForeground() +
-                                    lp.topMargin + lp.bottomMargin,
-                            lp.height);
-                }
-
-                child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
-            }
-        }
-    }
-
-    @Override
-    public void onLayout_impl(boolean changed, int left, int top, int right, int bottom) {
-        final int count = mInstance.getChildCount();
-
-        final int parentLeft = getPaddingLeftWithForeground();
-        final int parentRight = right - left - getPaddingRightWithForeground();
-
-        final int parentTop = getPaddingTopWithForeground();
-        final int parentBottom = bottom - top - getPaddingBottomWithForeground();
-
-        for (int i = 0; i < count; i++) {
-            final View child = mInstance.getChildAt(i);
-            if (child.getVisibility() != View.GONE) {
-                final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
-
-                final int width = child.getMeasuredWidth();
-                final int height = child.getMeasuredHeight();
-
-                int childLeft;
-                int childTop;
-
-                childLeft = parentLeft + (parentRight - parentLeft - width) / 2 +
-                        lp.leftMargin - lp.rightMargin;
-
-                childTop = parentTop + (parentBottom - parentTop - height) / 2 +
-                        lp.topMargin - lp.bottomMargin;
-
-                child.layout(childLeft, childTop, childLeft + width, childTop + height);
-            }
-        }
-    }
-
-    @Override
-    public boolean shouldDelayChildPressedState_impl() {
-        return false;
-    }
-
-    private int getPaddingLeftWithForeground() {
-        return mInstance.isForegroundInsidePadding() ? Math.max(mInstance.getPaddingLeft(), 0) :
-                mInstance.getPaddingLeft() + 0;
-    }
-
-    private int getPaddingRightWithForeground() {
-        return mInstance.isForegroundInsidePadding() ? Math.max(mInstance.getPaddingRight(), 0) :
-                mInstance.getPaddingRight() + 0;
-    }
-
-    private int getPaddingTopWithForeground() {
-        return mInstance.isForegroundInsidePadding() ? Math.max(mInstance.getPaddingTop(), 0) :
-                mInstance.getPaddingTop() + 0;
-    }
-
-    private int getPaddingBottomWithForeground() {
-        return mInstance.isForegroundInsidePadding() ? Math.max(mInstance.getPaddingBottom(), 0) :
-                mInstance.getPaddingBottom() + 0;
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java b/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java
deleted file mode 100644
index 3aff150..0000000
--- a/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java
+++ /dev/null
@@ -1,1722 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.widget;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Point;
-import android.media.MediaMetadata;
-import android.media.session.MediaController;
-import android.media.session.PlaybackState;
-import android.media.SessionToken2;
-import android.media.update.MediaControlView2Provider;
-import android.media.update.ViewGroupProvider;
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.AdapterView;
-import android.widget.BaseAdapter;
-import android.widget.Button;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.MediaControlView2;
-import android.widget.ProgressBar;
-import android.widget.PopupWindow;
-import android.widget.RelativeLayout;
-import android.widget.SeekBar;
-import android.widget.SeekBar.OnSeekBarChangeListener;
-import android.widget.TextView;
-
-import com.android.media.update.ApiHelper;
-import com.android.media.update.R;
-import com.android.support.mediarouter.app.MediaRouteButton;
-import com.android.support.mediarouter.media.MediaRouter;
-import com.android.support.mediarouter.media.MediaRouteSelector;
-
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.Formatter;
-import java.util.List;
-import java.util.Locale;
-
-public class MediaControlView2Impl extends BaseLayout implements MediaControlView2Provider {
-    private static final String TAG = "MediaControlView2";
-
-    private final MediaControlView2 mInstance;
-
-    static final String ARGUMENT_KEY_FULLSCREEN = "fullScreen";
-
-    // TODO: Move these constants to public api to support custom video view.
-    // TODO: Combine these constants into one regarding TrackInfo.
-    static final String KEY_VIDEO_TRACK_COUNT = "VideoTrackCount";
-    static final String KEY_AUDIO_TRACK_COUNT = "AudioTrackCount";
-    static final String KEY_SUBTITLE_TRACK_COUNT = "SubtitleTrackCount";
-    static final String KEY_PLAYBACK_SPEED = "PlaybackSpeed";
-    static final String KEY_SELECTED_AUDIO_INDEX = "SelectedAudioIndex";
-    static final String KEY_SELECTED_SUBTITLE_INDEX = "SelectedSubtitleIndex";
-    static final String EVENT_UPDATE_TRACK_STATUS = "UpdateTrackStatus";
-
-    // TODO: Remove this once integrating with MediaSession2 & MediaMetadata2
-    static final String KEY_STATE_IS_ADVERTISEMENT = "MediaTypeAdvertisement";
-    static final String EVENT_UPDATE_MEDIA_TYPE_STATUS = "UpdateMediaTypeStatus";
-
-    // String for sending command to show subtitle to MediaSession.
-    static final String COMMAND_SHOW_SUBTITLE = "showSubtitle";
-    // String for sending command to hide subtitle to MediaSession.
-    static final String COMMAND_HIDE_SUBTITLE = "hideSubtitle";
-    // TODO: remove once the implementation is revised
-    public static final String COMMAND_SET_FULLSCREEN = "setFullscreen";
-    // String for sending command to select audio track to MediaSession.
-    static final String COMMAND_SELECT_AUDIO_TRACK = "SelectTrack";
-    // String for sending command to set playback speed to MediaSession.
-    static final String COMMAND_SET_PLAYBACK_SPEED = "SetPlaybackSpeed";
-    // String for sending command to mute audio to MediaSession.
-    static final String COMMAND_MUTE= "Mute";
-    // String for sending command to unmute audio to MediaSession.
-    static final String COMMAND_UNMUTE = "Unmute";
-
-    private static final int SETTINGS_MODE_AUDIO_TRACK = 0;
-    private static final int SETTINGS_MODE_PLAYBACK_SPEED = 1;
-    private static final int SETTINGS_MODE_HELP = 2;
-    private static final int SETTINGS_MODE_SUBTITLE_TRACK = 3;
-    private static final int SETTINGS_MODE_VIDEO_QUALITY = 4;
-    private static final int SETTINGS_MODE_MAIN = 5;
-    private static final int PLAYBACK_SPEED_1x_INDEX = 3;
-
-    private static final int MEDIA_TYPE_DEFAULT = 0;
-    private static final int MEDIA_TYPE_MUSIC = 1;
-    private static final int MEDIA_TYPE_ADVERTISEMENT = 2;
-
-    private static final int SIZE_TYPE_EMBEDDED = 0;
-    private static final int SIZE_TYPE_FULL = 1;
-    // TODO: add support for Minimal size type.
-    private static final int SIZE_TYPE_MINIMAL = 2;
-
-    private static final int MAX_PROGRESS = 1000;
-    private static final int DEFAULT_PROGRESS_UPDATE_TIME_MS = 1000;
-    private static final int REWIND_TIME_MS = 10000;
-    private static final int FORWARD_TIME_MS = 30000;
-    private static final int AD_SKIP_WAIT_TIME_MS = 5000;
-    private static final int RESOURCE_NON_EXISTENT = -1;
-    private static final String RESOURCE_EMPTY = "";
-
-    private Resources mResources;
-    private MediaController mController;
-    private MediaController.TransportControls mControls;
-    private PlaybackState mPlaybackState;
-    private MediaMetadata mMetadata;
-    private int mDuration;
-    private int mPrevState;
-    private int mPrevWidth;
-    private int mPrevHeight;
-    private int mOriginalLeftBarWidth;
-    private int mVideoTrackCount;
-    private int mAudioTrackCount;
-    private int mSubtitleTrackCount;
-    private int mSettingsMode;
-    private int mSelectedSubtitleTrackIndex;
-    private int mSelectedAudioTrackIndex;
-    private int mSelectedVideoQualityIndex;
-    private int mSelectedSpeedIndex;
-    private int mEmbeddedSettingsItemWidth;
-    private int mFullSettingsItemWidth;
-    private int mEmbeddedSettingsItemHeight;
-    private int mFullSettingsItemHeight;
-    private int mSettingsWindowMargin;
-    private int mMediaType;
-    private int mSizeType;
-    private long mPlaybackActions;
-    private boolean mDragging;
-    private boolean mIsFullScreen;
-    private boolean mOverflowExpanded;
-    private boolean mIsStopped;
-    private boolean mSubtitleIsEnabled;
-    private boolean mSeekAvailable;
-    private boolean mIsAdvertisement;
-    private boolean mIsMute;
-    private boolean mNeedUXUpdate;
-
-    // Relating to Title Bar View
-    private ViewGroup mRoot;
-    private View mTitleBar;
-    private TextView mTitleView;
-    private View mAdExternalLink;
-    private ImageButton mBackButton;
-    private MediaRouteButton mRouteButton;
-    private MediaRouteSelector mRouteSelector;
-
-    // Relating to Center View
-    private ViewGroup mCenterView;
-    private View mTransportControls;
-    private ImageButton mPlayPauseButton;
-    private ImageButton mFfwdButton;
-    private ImageButton mRewButton;
-    private ImageButton mNextButton;
-    private ImageButton mPrevButton;
-
-    // Relating to Minimal Extra View
-    private LinearLayout mMinimalExtraView;
-
-    // Relating to Progress Bar View
-    private ProgressBar mProgress;
-    private View mProgressBuffer;
-
-    // Relating to Bottom Bar View
-    private ViewGroup mBottomBar;
-
-    // Relating to Bottom Bar Left View
-    private ViewGroup mBottomBarLeftView;
-    private ViewGroup mTimeView;
-    private TextView mEndTime;
-    private TextView mCurrentTime;
-    private TextView mAdSkipView;
-    private StringBuilder mFormatBuilder;
-    private Formatter mFormatter;
-
-    // Relating to Bottom Bar Right View
-    private ViewGroup mBottomBarRightView;
-    private ViewGroup mBasicControls;
-    private ViewGroup mExtraControls;
-    private ViewGroup mCustomButtons;
-    private ImageButton mSubtitleButton;
-    private ImageButton mFullScreenButton;
-    private ImageButton mOverflowButtonRight;
-    private ImageButton mOverflowButtonLeft;
-    private ImageButton mMuteButton;
-    private ImageButton mVideoQualityButton;
-    private ImageButton mSettingsButton;
-    private TextView mAdRemainingView;
-
-    // Relating to Settings List View
-    private ListView mSettingsListView;
-    private PopupWindow mSettingsWindow;
-    private SettingsAdapter mSettingsAdapter;
-    private SubSettingsAdapter mSubSettingsAdapter;
-    private List<String> mSettingsMainTextsList;
-    private List<String> mSettingsSubTextsList;
-    private List<Integer> mSettingsIconIdsList;
-    private List<String> mSubtitleDescriptionsList;
-    private List<String> mAudioTrackList;
-    private List<String> mVideoQualityList;
-    private List<String> mPlaybackSpeedTextList;
-    private List<Float> mPlaybackSpeedList;
-
-    public MediaControlView2Impl(MediaControlView2 instance,
-            ViewGroupProvider superProvider, ViewGroupProvider privateProvider) {
-        super(instance, superProvider, privateProvider);
-        mInstance = instance;
-    }
-
-    @Override
-    public void initialize(@Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        mResources = ApiHelper.getLibResources(mInstance.getContext());
-        // Inflate MediaControlView2 from XML
-        mRoot = makeControllerView();
-        mInstance.addView(mRoot);
-    }
-
-    @Override
-    public void setMediaSessionToken_impl(SessionToken2 token) {
-        // TODO: implement this
-    }
-
-    @Override
-    public void setOnFullScreenListener_impl(MediaControlView2.OnFullScreenListener l) {
-        // TODO: implement this
-    }
-
-    @Override
-    public void setController_impl(MediaController controller) {
-        mController = controller;
-        if (controller != null) {
-            mControls = controller.getTransportControls();
-            // Set mMetadata and mPlaybackState to existing MediaSession variables since they may
-            // be called before the callback is called
-            mPlaybackState = mController.getPlaybackState();
-            mMetadata = mController.getMetadata();
-            updateDuration();
-            updateTitle();
-
-            mController.registerCallback(new MediaControllerCallback());
-        }
-    }
-
-    @Override
-    public void setButtonVisibility_impl(int button, int visibility) {
-        // TODO: add member variables for Fast-Forward/Prvious/Rewind buttons to save visibility in
-        // order to prevent being overriden inside updateLayout().
-        switch (button) {
-            case MediaControlView2.BUTTON_PLAY_PAUSE:
-                if (mPlayPauseButton != null && canPause()) {
-                    mPlayPauseButton.setVisibility(visibility);
-                }
-                break;
-            case MediaControlView2.BUTTON_FFWD:
-                if (mFfwdButton != null && canSeekForward()) {
-                    mFfwdButton.setVisibility(visibility);
-                }
-                break;
-            case MediaControlView2.BUTTON_REW:
-                if (mRewButton != null && canSeekBackward()) {
-                    mRewButton.setVisibility(visibility);
-                }
-                break;
-            case MediaControlView2.BUTTON_NEXT:
-                if (mNextButton != null) {
-                    mNextButton.setVisibility(visibility);
-                }
-                break;
-            case MediaControlView2.BUTTON_PREV:
-                if (mPrevButton != null) {
-                    mPrevButton.setVisibility(visibility);
-                }
-                break;
-            case MediaControlView2.BUTTON_SUBTITLE:
-                if (mSubtitleButton != null && mSubtitleTrackCount > 0) {
-                    mSubtitleButton.setVisibility(visibility);
-                }
-                break;
-            case MediaControlView2.BUTTON_FULL_SCREEN:
-                if (mFullScreenButton != null) {
-                    mFullScreenButton.setVisibility(visibility);
-                }
-                break;
-            case MediaControlView2.BUTTON_OVERFLOW:
-                if (mOverflowButtonRight != null) {
-                    mOverflowButtonRight.setVisibility(visibility);
-                }
-                break;
-            case MediaControlView2.BUTTON_MUTE:
-                if (mMuteButton != null) {
-                    mMuteButton.setVisibility(visibility);
-                }
-                break;
-            case MediaControlView2.BUTTON_SETTINGS:
-                if (mSettingsButton != null) {
-                    mSettingsButton.setVisibility(visibility);
-                }
-                break;
-            default:
-                break;
-        }
-    }
-
-    @Override
-    public void requestPlayButtonFocus_impl() {
-        if (mPlayPauseButton != null) {
-            mPlayPauseButton.requestFocus();
-        }
-    }
-
-    @Override
-    public CharSequence getAccessibilityClassName_impl() {
-        return MediaControlView2.class.getName();
-    }
-
-    @Override
-    public boolean onTouchEvent_impl(MotionEvent ev) {
-        return false;
-    }
-
-    // TODO: Should this function be removed?
-    @Override
-    public boolean onTrackballEvent_impl(MotionEvent ev) {
-        return false;
-    }
-
-    @Override
-    public void onMeasure_impl(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure_impl(widthMeasureSpec, heightMeasureSpec);
-
-        // Update layout when this view's width changes in order to avoid any UI overlap between
-        // transport controls.
-        if (mPrevWidth != mInstance.getMeasuredWidth()
-                || mPrevHeight != mInstance.getMeasuredHeight() || mNeedUXUpdate) {
-            // Dismiss SettingsWindow if it is showing.
-            mSettingsWindow.dismiss();
-
-            // These views may not have been initialized yet.
-            if (mTransportControls.getWidth() == 0 || mTimeView.getWidth() == 0) {
-                return;
-            }
-
-            int currWidth = mInstance.getMeasuredWidth();
-            int currHeight = mInstance.getMeasuredHeight();
-            WindowManager manager = (WindowManager) mInstance.getContext().getApplicationContext()
-                    .getSystemService(Context.WINDOW_SERVICE);
-            Point screenSize = new Point();
-            manager.getDefaultDisplay().getSize(screenSize);
-            int screenWidth = screenSize.x;
-            int screenHeight = screenSize.y;
-            int fullIconSize = mResources.getDimensionPixelSize(R.dimen.mcv2_full_icon_size);
-            int embeddedIconSize = mResources.getDimensionPixelSize(
-                    R.dimen.mcv2_embedded_icon_size);
-            int marginSize = mResources.getDimensionPixelSize(R.dimen.mcv2_icon_margin);
-
-            // TODO: add support for Advertisement Mode.
-            if (mMediaType == MEDIA_TYPE_DEFAULT) {
-                // Max number of icons inside BottomBarRightView for Music mode is 4.
-                int maxIconCount = 4;
-                updateLayout(maxIconCount, fullIconSize, embeddedIconSize, marginSize, currWidth,
-                        currHeight, screenWidth, screenHeight);
-            } else if (mMediaType == MEDIA_TYPE_MUSIC) {
-                if (mNeedUXUpdate) {
-                    // One-time operation for Music media type
-                    mBasicControls.removeView(mMuteButton);
-                    mExtraControls.addView(mMuteButton, 0);
-                    mVideoQualityButton.setVisibility(View.GONE);
-                    if (mFfwdButton != null) {
-                        mFfwdButton.setVisibility(View.GONE);
-                    }
-                    if (mRewButton != null) {
-                        mRewButton.setVisibility(View.GONE);
-                    }
-                }
-                mNeedUXUpdate = false;
-
-                // Max number of icons inside BottomBarRightView for Music mode is 3.
-                int maxIconCount = 3;
-                updateLayout(maxIconCount, fullIconSize, embeddedIconSize, marginSize, currWidth,
-                        currHeight, screenWidth, screenHeight);
-            }
-            mPrevWidth = currWidth;
-            mPrevHeight = currHeight;
-        }
-        // TODO: move this to a different location.
-        // Update title bar parameters in order to avoid overlap between title view and the right
-        // side of the title bar.
-        updateTitleBarLayout();
-    }
-
-    @Override
-    public void setEnabled_impl(boolean enabled) {
-        super.setEnabled_impl(enabled);
-
-        // TODO: Merge the below code with disableUnsupportedButtons().
-        if (mPlayPauseButton != null) {
-            mPlayPauseButton.setEnabled(enabled);
-        }
-        if (mFfwdButton != null) {
-            mFfwdButton.setEnabled(enabled);
-        }
-        if (mRewButton != null) {
-            mRewButton.setEnabled(enabled);
-        }
-        if (mNextButton != null) {
-            mNextButton.setEnabled(enabled);
-        }
-        if (mPrevButton != null) {
-            mPrevButton.setEnabled(enabled);
-        }
-        if (mProgress != null) {
-            mProgress.setEnabled(enabled);
-        }
-        disableUnsupportedButtons();
-    }
-
-    @Override
-    public void onVisibilityAggregated_impl(boolean isVisible) {
-        super.onVisibilityAggregated_impl(isVisible);
-
-        if (isVisible) {
-            disableUnsupportedButtons();
-            mInstance.removeCallbacks(mUpdateProgress);
-            mInstance.post(mUpdateProgress);
-        } else {
-            mInstance.removeCallbacks(mUpdateProgress);
-        }
-    }
-
-    public void setRouteSelector(MediaRouteSelector selector) {
-        mRouteSelector = selector;
-        if (mRouteSelector != null && !mRouteSelector.isEmpty()) {
-            mRouteButton.setRouteSelector(selector, MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
-            mRouteButton.setVisibility(View.VISIBLE);
-        } else {
-            mRouteButton.setRouteSelector(MediaRouteSelector.EMPTY);
-            mRouteButton.setVisibility(View.GONE);
-        }
-    }
-
-    ///////////////////////////////////////////////////
-    // Protected or private methods
-    ///////////////////////////////////////////////////
-
-    private boolean isPlaying() {
-        if (mPlaybackState != null) {
-            return mPlaybackState.getState() == PlaybackState.STATE_PLAYING;
-        }
-        return false;
-    }
-
-    private int getCurrentPosition() {
-        mPlaybackState = mController.getPlaybackState();
-        if (mPlaybackState != null) {
-            return (int) mPlaybackState.getPosition();
-        }
-        return 0;
-    }
-
-    private int getBufferPercentage() {
-        if (mDuration == 0) {
-            return 0;
-        }
-        mPlaybackState = mController.getPlaybackState();
-        if (mPlaybackState != null) {
-            long bufferedPos = mPlaybackState.getBufferedPosition();
-            return (bufferedPos == -1) ? -1 : (int) (bufferedPos * 100 / mDuration);
-        }
-        return 0;
-    }
-
-    private boolean canPause() {
-        if (mPlaybackState != null) {
-            return (mPlaybackState.getActions() & PlaybackState.ACTION_PAUSE) != 0;
-        }
-        return true;
-    }
-
-    private boolean canSeekBackward() {
-        if (mPlaybackState != null) {
-            return (mPlaybackState.getActions() & PlaybackState.ACTION_REWIND) != 0;
-        }
-        return true;
-    }
-
-    private boolean canSeekForward() {
-        if (mPlaybackState != null) {
-            return (mPlaybackState.getActions() & PlaybackState.ACTION_FAST_FORWARD) != 0;
-        }
-        return true;
-    }
-
-    /**
-     * Create the view that holds the widgets that control playback.
-     * Derived classes can override this to create their own.
-     *
-     * @return The controller view.
-     * @hide This doesn't work as advertised
-     */
-    protected ViewGroup makeControllerView() {
-        ViewGroup root = (ViewGroup) ApiHelper.inflateLibLayout(mInstance.getContext(),
-                R.layout.media_controller);
-        initControllerView(root);
-        return root;
-    }
-
-    private void initControllerView(ViewGroup v) {
-        // Relating to Title Bar View
-        mTitleBar = v.findViewById(R.id.title_bar);
-        mTitleView = v.findViewById(R.id.title_text);
-        mAdExternalLink = v.findViewById(R.id.ad_external_link);
-        mBackButton = v.findViewById(R.id.back);
-        if (mBackButton != null) {
-            mBackButton.setOnClickListener(mBackListener);
-            mBackButton.setVisibility(View.GONE);
-        }
-        mRouteButton = v.findViewById(R.id.cast);
-
-        // Relating to Center View
-        mCenterView = v.findViewById(R.id.center_view);
-        mTransportControls = inflateTransportControls(R.layout.embedded_transport_controls);
-        mCenterView.addView(mTransportControls);
-
-        // Relating to Minimal Extra View
-        mMinimalExtraView = (LinearLayout) v.findViewById(R.id.minimal_extra_view);
-        LinearLayout.LayoutParams params =
-                (LinearLayout.LayoutParams) mMinimalExtraView.getLayoutParams();
-        int iconSize = mResources.getDimensionPixelSize(R.dimen.mcv2_embedded_icon_size);
-        int marginSize = mResources.getDimensionPixelSize(R.dimen.mcv2_icon_margin);
-        params.setMargins(0, (iconSize + marginSize * 2) * (-1), 0, 0);
-        mMinimalExtraView.setLayoutParams(params);
-        mMinimalExtraView.setVisibility(View.GONE);
-
-        // Relating to Progress Bar View
-        mProgress = v.findViewById(R.id.progress);
-        if (mProgress != null) {
-            if (mProgress instanceof SeekBar) {
-                SeekBar seeker = (SeekBar) mProgress;
-                seeker.setOnSeekBarChangeListener(mSeekListener);
-                seeker.setProgressDrawable(mResources.getDrawable(R.drawable.custom_progress));
-                seeker.setThumb(mResources.getDrawable(R.drawable.custom_progress_thumb));
-            }
-            mProgress.setMax(MAX_PROGRESS);
-        }
-        mProgressBuffer = v.findViewById(R.id.progress_buffer);
-
-        // Relating to Bottom Bar View
-        mBottomBar = v.findViewById(R.id.bottom_bar);
-
-        // Relating to Bottom Bar Left View
-        mBottomBarLeftView = v.findViewById(R.id.bottom_bar_left);
-        mTimeView = v.findViewById(R.id.time);
-        mEndTime = v.findViewById(R.id.time_end);
-        mCurrentTime = v.findViewById(R.id.time_current);
-        mAdSkipView = v.findViewById(R.id.ad_skip_time);
-        mFormatBuilder = new StringBuilder();
-        mFormatter = new Formatter(mFormatBuilder, Locale.getDefault());
-
-        // Relating to Bottom Bar Right View
-        mBottomBarRightView = v.findViewById(R.id.bottom_bar_right);
-        mBasicControls = v.findViewById(R.id.basic_controls);
-        mExtraControls = v.findViewById(R.id.extra_controls);
-        mCustomButtons = v.findViewById(R.id.custom_buttons);
-        mSubtitleButton = v.findViewById(R.id.subtitle);
-        if (mSubtitleButton != null) {
-            mSubtitleButton.setOnClickListener(mSubtitleListener);
-        }
-        mFullScreenButton = v.findViewById(R.id.fullscreen);
-        if (mFullScreenButton != null) {
-            mFullScreenButton.setOnClickListener(mFullScreenListener);
-            // TODO: Show Fullscreen button when only it is possible.
-        }
-        mOverflowButtonRight = v.findViewById(R.id.overflow_right);
-        if (mOverflowButtonRight != null) {
-            mOverflowButtonRight.setOnClickListener(mOverflowRightListener);
-        }
-        mOverflowButtonLeft = v.findViewById(R.id.overflow_left);
-        if (mOverflowButtonLeft != null) {
-            mOverflowButtonLeft.setOnClickListener(mOverflowLeftListener);
-        }
-        mMuteButton = v.findViewById(R.id.mute);
-        if (mMuteButton != null) {
-            mMuteButton.setOnClickListener(mMuteButtonListener);
-        }
-        mSettingsButton = v.findViewById(R.id.settings);
-        if (mSettingsButton != null) {
-            mSettingsButton.setOnClickListener(mSettingsButtonListener);
-        }
-        mVideoQualityButton = v.findViewById(R.id.video_quality);
-        if (mVideoQualityButton != null) {
-            mVideoQualityButton.setOnClickListener(mVideoQualityListener);
-        }
-        mAdRemainingView = v.findViewById(R.id.ad_remaining);
-
-        // Relating to Settings List View
-        initializeSettingsLists();
-        mSettingsListView = (ListView) ApiHelper.inflateLibLayout(mInstance.getContext(),
-                R.layout.settings_list);
-        mSettingsAdapter = new SettingsAdapter(mSettingsMainTextsList, mSettingsSubTextsList,
-                mSettingsIconIdsList);
-        mSubSettingsAdapter = new SubSettingsAdapter(null, 0);
-        mSettingsListView.setAdapter(mSettingsAdapter);
-        mSettingsListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
-        mSettingsListView.setOnItemClickListener(mSettingsItemClickListener);
-
-        mEmbeddedSettingsItemWidth = mResources.getDimensionPixelSize(
-                R.dimen.mcv2_embedded_settings_width);
-        mFullSettingsItemWidth = mResources.getDimensionPixelSize(R.dimen.mcv2_full_settings_width);
-        mEmbeddedSettingsItemHeight = mResources.getDimensionPixelSize(
-                R.dimen.mcv2_embedded_settings_height);
-        mFullSettingsItemHeight = mResources.getDimensionPixelSize(
-                R.dimen.mcv2_full_settings_height);
-        mSettingsWindowMargin = (-1) * mResources.getDimensionPixelSize(
-                R.dimen.mcv2_settings_offset);
-        mSettingsWindow = new PopupWindow(mSettingsListView, mEmbeddedSettingsItemWidth,
-                ViewGroup.LayoutParams.WRAP_CONTENT, true);
-    }
-
-    /**
-     * Disable pause or seek buttons if the stream cannot be paused or seeked.
-     * This requires the control interface to be a MediaPlayerControlExt
-     */
-    private void disableUnsupportedButtons() {
-        try {
-            if (mPlayPauseButton != null && !canPause()) {
-                mPlayPauseButton.setEnabled(false);
-            }
-            if (mRewButton != null && !canSeekBackward()) {
-                mRewButton.setEnabled(false);
-            }
-            if (mFfwdButton != null && !canSeekForward()) {
-                mFfwdButton.setEnabled(false);
-            }
-            // TODO What we really should do is add a canSeek to the MediaPlayerControl interface;
-            // this scheme can break the case when applications want to allow seek through the
-            // progress bar but disable forward/backward buttons.
-            //
-            // However, currently the flags SEEK_BACKWARD_AVAILABLE, SEEK_FORWARD_AVAILABLE,
-            // and SEEK_AVAILABLE are all (un)set together; as such the aforementioned issue
-            // shouldn't arise in existing applications.
-            if (mProgress != null && !canSeekBackward() && !canSeekForward()) {
-                mProgress.setEnabled(false);
-            }
-        } catch (IncompatibleClassChangeError ex) {
-            // We were given an old version of the interface, that doesn't have
-            // the canPause/canSeekXYZ methods. This is OK, it just means we
-            // assume the media can be paused and seeked, and so we don't disable
-            // the buttons.
-        }
-    }
-
-    private final Runnable mUpdateProgress = new Runnable() {
-        @Override
-        public void run() {
-            int pos = setProgress();
-            boolean isShowing = mInstance.getVisibility() == View.VISIBLE;
-            if (!mDragging && isShowing && isPlaying()) {
-                mInstance.postDelayed(mUpdateProgress,
-                        DEFAULT_PROGRESS_UPDATE_TIME_MS - (pos % DEFAULT_PROGRESS_UPDATE_TIME_MS));
-            }
-        }
-    };
-
-    private String stringForTime(int timeMs) {
-        int totalSeconds = timeMs / 1000;
-
-        int seconds = totalSeconds % 60;
-        int minutes = (totalSeconds / 60) % 60;
-        int hours = totalSeconds / 3600;
-
-        mFormatBuilder.setLength(0);
-        if (hours > 0) {
-            return mFormatter.format("%d:%02d:%02d", hours, minutes, seconds).toString();
-        } else {
-            return mFormatter.format("%02d:%02d", minutes, seconds).toString();
-        }
-    }
-
-    private int setProgress() {
-        if (mController == null || mDragging) {
-            return 0;
-        }
-        int positionOnProgressBar = 0;
-        int currentPosition = getCurrentPosition();
-        if (mDuration > 0) {
-            positionOnProgressBar = (int) (MAX_PROGRESS * (long) currentPosition / mDuration);
-        }
-        if (mProgress != null && currentPosition != mDuration) {
-            mProgress.setProgress(positionOnProgressBar);
-            // If the media is a local file, there is no need to set a buffer, so set secondary
-            // progress to maximum.
-            if (getBufferPercentage() < 0) {
-                mProgress.setSecondaryProgress(MAX_PROGRESS);
-            } else {
-                mProgress.setSecondaryProgress(getBufferPercentage() * 10);
-            }
-        }
-
-        if (mEndTime != null) {
-            mEndTime.setText(stringForTime(mDuration));
-
-        }
-        if (mCurrentTime != null) {
-            mCurrentTime.setText(stringForTime(currentPosition));
-        }
-
-        if (mIsAdvertisement) {
-            // Update the remaining number of seconds until the first 5 seconds of the
-            // advertisement.
-            if (mAdSkipView != null) {
-                if (currentPosition <= AD_SKIP_WAIT_TIME_MS) {
-                    if (mAdSkipView.getVisibility() == View.GONE) {
-                        mAdSkipView.setVisibility(View.VISIBLE);
-                    }
-                    String skipTimeText = mResources.getString(
-                            R.string.MediaControlView2_ad_skip_wait_time,
-                            ((AD_SKIP_WAIT_TIME_MS - currentPosition) / 1000 + 1));
-                    mAdSkipView.setText(skipTimeText);
-                } else {
-                    if (mAdSkipView.getVisibility() == View.VISIBLE) {
-                        mAdSkipView.setVisibility(View.GONE);
-                        mNextButton.setEnabled(true);
-                        mNextButton.clearColorFilter();
-                    }
-                }
-            }
-            // Update the remaining number of seconds of the advertisement.
-            if (mAdRemainingView != null) {
-                int remainingTime =
-                        (mDuration - currentPosition < 0) ? 0 : (mDuration - currentPosition);
-                String remainingTimeText = mResources.getString(
-                        R.string.MediaControlView2_ad_remaining_time,
-                        stringForTime(remainingTime));
-                mAdRemainingView.setText(remainingTimeText);
-            }
-        }
-        return currentPosition;
-    }
-
-    private void togglePausePlayState() {
-        if (isPlaying()) {
-            mControls.pause();
-            mPlayPauseButton.setImageDrawable(
-                    mResources.getDrawable(R.drawable.ic_play_circle_filled, null));
-            mPlayPauseButton.setContentDescription(
-                    mResources.getString(R.string.mcv2_play_button_desc));
-        } else {
-            mControls.play();
-            mPlayPauseButton.setImageDrawable(
-                    mResources.getDrawable(R.drawable.ic_pause_circle_filled, null));
-            mPlayPauseButton.setContentDescription(
-                    mResources.getString(R.string.mcv2_pause_button_desc));
-        }
-    }
-
-    // There are two scenarios that can trigger the seekbar listener to trigger:
-    //
-    // The first is the user using the touchpad to adjust the posititon of the
-    // seekbar's thumb. In this case onStartTrackingTouch is called followed by
-    // a number of onProgressChanged notifications, concluded by onStopTrackingTouch.
-    // We're setting the field "mDragging" to true for the duration of the dragging
-    // session to avoid jumps in the position in case of ongoing playback.
-    //
-    // The second scenario involves the user operating the scroll ball, in this
-    // case there WON'T BE onStartTrackingTouch/onStopTrackingTouch notifications,
-    // we will simply apply the updated position without suspending regular updates.
-    private final OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {
-        @Override
-        public void onStartTrackingTouch(SeekBar bar) {
-            if (!mSeekAvailable) {
-                return;
-            }
-
-            mDragging = true;
-
-            // By removing these pending progress messages we make sure
-            // that a) we won't update the progress while the user adjusts
-            // the seekbar and b) once the user is done dragging the thumb
-            // we will post one of these messages to the queue again and
-            // this ensures that there will be exactly one message queued up.
-            mInstance.removeCallbacks(mUpdateProgress);
-
-            // Check if playback is currently stopped. In this case, update the pause button to
-            // show the play image instead of the replay image.
-            if (mIsStopped) {
-                mPlayPauseButton.setImageDrawable(
-                        mResources.getDrawable(R.drawable.ic_play_circle_filled, null));
-                mPlayPauseButton.setContentDescription(
-                        mResources.getString(R.string.mcv2_play_button_desc));
-                mIsStopped = false;
-            }
-        }
-
-        @Override
-        public void onProgressChanged(SeekBar bar, int progress, boolean fromUser) {
-            if (!mSeekAvailable) {
-                return;
-            }
-            if (!fromUser) {
-                // We're not interested in programmatically generated changes to
-                // the progress bar's position.
-                return;
-            }
-            if (mDuration > 0) {
-                int position = (int) (((long) mDuration * progress) / MAX_PROGRESS);
-                mControls.seekTo(position);
-
-                if (mCurrentTime != null) {
-                    mCurrentTime.setText(stringForTime(position));
-                }
-            }
-        }
-
-        @Override
-        public void onStopTrackingTouch(SeekBar bar) {
-            if (!mSeekAvailable) {
-                return;
-            }
-            mDragging = false;
-
-            setProgress();
-
-            // Ensure that progress is properly updated in the future,
-            // the call to show() does not guarantee this because it is a
-            // no-op if we are already showing.
-            mInstance.post(mUpdateProgress);
-        }
-    };
-
-    private final View.OnClickListener mPlayPauseListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            togglePausePlayState();
-        }
-    };
-
-    private final View.OnClickListener mRewListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            int pos = getCurrentPosition() - REWIND_TIME_MS;
-            mControls.seekTo(pos);
-            setProgress();
-        }
-    };
-
-    private final View.OnClickListener mFfwdListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            int pos = getCurrentPosition() + FORWARD_TIME_MS;
-            mControls.seekTo(pos);
-            setProgress();
-        }
-    };
-
-    private final View.OnClickListener mNextListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            mControls.skipToNext();
-        }
-    };
-
-    private final View.OnClickListener mPrevListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            mControls.skipToPrevious();
-        }
-    };
-
-    private final View.OnClickListener mBackListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            // TODO: implement
-        }
-    };
-
-    private final View.OnClickListener mSubtitleListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            mSettingsMode = SETTINGS_MODE_SUBTITLE_TRACK;
-            mSubSettingsAdapter.setTexts(mSubtitleDescriptionsList);
-            mSubSettingsAdapter.setCheckPosition(mSelectedSubtitleTrackIndex);
-            displaySettingsWindow(mSubSettingsAdapter);
-        }
-    };
-
-    private final View.OnClickListener mVideoQualityListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            mSettingsMode = SETTINGS_MODE_VIDEO_QUALITY;
-            mSubSettingsAdapter.setTexts(mVideoQualityList);
-            mSubSettingsAdapter.setCheckPosition(mSelectedVideoQualityIndex);
-            displaySettingsWindow(mSubSettingsAdapter);
-        }
-    };
-
-    private final View.OnClickListener mFullScreenListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            final boolean isEnteringFullScreen = !mIsFullScreen;
-            // TODO: Re-arrange the button layouts according to the UX.
-            if (isEnteringFullScreen) {
-                mFullScreenButton.setImageDrawable(
-                        mResources.getDrawable(R.drawable.ic_fullscreen_exit, null));
-            } else {
-                mFullScreenButton.setImageDrawable(
-                        mResources.getDrawable(R.drawable.ic_fullscreen, null));
-            }
-            Bundle args = new Bundle();
-            args.putBoolean(ARGUMENT_KEY_FULLSCREEN, isEnteringFullScreen);
-            mController.sendCommand(COMMAND_SET_FULLSCREEN, args, null);
-
-            mIsFullScreen = isEnteringFullScreen;
-        }
-    };
-
-    private final View.OnClickListener mOverflowRightListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            mBasicControls.setVisibility(View.GONE);
-            mExtraControls.setVisibility(View.VISIBLE);
-        }
-    };
-
-    private final View.OnClickListener mOverflowLeftListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            mBasicControls.setVisibility(View.VISIBLE);
-            mExtraControls.setVisibility(View.GONE);
-        }
-    };
-
-    private final View.OnClickListener mMuteButtonListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            if (!mIsMute) {
-                mMuteButton.setImageDrawable(
-                        mResources.getDrawable(R.drawable.ic_mute, null));
-                mMuteButton.setContentDescription(
-                        mResources.getString(R.string.mcv2_muted_button_desc));
-                mIsMute = true;
-                mController.sendCommand(COMMAND_MUTE, null, null);
-            } else {
-                mMuteButton.setImageDrawable(
-                        mResources.getDrawable(R.drawable.ic_unmute, null));
-                mMuteButton.setContentDescription(
-                        mResources.getString(R.string.mcv2_unmuted_button_desc));
-                mIsMute = false;
-                mController.sendCommand(COMMAND_UNMUTE, null, null);
-            }
-        }
-    };
-
-    private final View.OnClickListener mSettingsButtonListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            mSettingsMode = SETTINGS_MODE_MAIN;
-            mSettingsAdapter.setSubTexts(mSettingsSubTextsList);
-            displaySettingsWindow(mSettingsAdapter);
-        }
-    };
-
-    private final AdapterView.OnItemClickListener mSettingsItemClickListener
-            = new AdapterView.OnItemClickListener() {
-        @Override
-        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-            switch (mSettingsMode) {
-                case SETTINGS_MODE_MAIN:
-                    if (position == SETTINGS_MODE_AUDIO_TRACK) {
-                        mSubSettingsAdapter.setTexts(mAudioTrackList);
-                        mSubSettingsAdapter.setCheckPosition(mSelectedAudioTrackIndex);
-                        mSettingsMode = SETTINGS_MODE_AUDIO_TRACK;
-                    } else if (position == SETTINGS_MODE_PLAYBACK_SPEED) {
-                        mSubSettingsAdapter.setTexts(mPlaybackSpeedTextList);
-                        mSubSettingsAdapter.setCheckPosition(mSelectedSpeedIndex);
-                        mSettingsMode = SETTINGS_MODE_PLAYBACK_SPEED;
-                    } else if (position == SETTINGS_MODE_HELP) {
-                        // TODO: implement this.
-                        mSettingsWindow.dismiss();
-                        return;
-                    }
-                    displaySettingsWindow(mSubSettingsAdapter);
-                    break;
-                case SETTINGS_MODE_AUDIO_TRACK:
-                    if (position != mSelectedAudioTrackIndex) {
-                        mSelectedAudioTrackIndex = position;
-                        if (mAudioTrackCount > 0) {
-                            Bundle extra = new Bundle();
-                            extra.putInt(KEY_SELECTED_AUDIO_INDEX, position);
-                            mController.sendCommand(COMMAND_SELECT_AUDIO_TRACK, extra, null);
-                        }
-                        mSettingsSubTextsList.set(SETTINGS_MODE_AUDIO_TRACK,
-                                mSubSettingsAdapter.getMainText(position));
-                    }
-                    mSettingsWindow.dismiss();
-                    break;
-                case SETTINGS_MODE_PLAYBACK_SPEED:
-                    if (position != mSelectedSpeedIndex) {
-                        mSelectedSpeedIndex = position;
-                        Bundle extra = new Bundle();
-                        extra.putFloat(KEY_PLAYBACK_SPEED, mPlaybackSpeedList.get(position));
-                        mController.sendCommand(COMMAND_SET_PLAYBACK_SPEED, extra, null);
-                        mSettingsSubTextsList.set(SETTINGS_MODE_PLAYBACK_SPEED,
-                                mSubSettingsAdapter.getMainText(position));
-                    }
-                    mSettingsWindow.dismiss();
-                    break;
-                case SETTINGS_MODE_HELP:
-                    // TODO: implement this.
-                    break;
-                case SETTINGS_MODE_SUBTITLE_TRACK:
-                    if (position != mSelectedSubtitleTrackIndex) {
-                        mSelectedSubtitleTrackIndex = position;
-                        if (position > 0) {
-                            Bundle extra = new Bundle();
-                            extra.putInt(KEY_SELECTED_SUBTITLE_INDEX, position - 1);
-                            mController.sendCommand(
-                                    MediaControlView2Impl.COMMAND_SHOW_SUBTITLE, extra, null);
-                            mSubtitleButton.setImageDrawable(
-                                    mResources.getDrawable(R.drawable.ic_subtitle_on, null));
-                            mSubtitleButton.setContentDescription(
-                                    mResources.getString(R.string.mcv2_cc_is_on));
-                            mSubtitleIsEnabled = true;
-                        } else {
-                            mController.sendCommand(
-                                    MediaControlView2Impl.COMMAND_HIDE_SUBTITLE, null, null);
-                            mSubtitleButton.setImageDrawable(
-                                    mResources.getDrawable(R.drawable.ic_subtitle_off, null));
-                            mSubtitleButton.setContentDescription(
-                                    mResources.getString(R.string.mcv2_cc_is_off));
-
-                            mSubtitleIsEnabled = false;
-                        }
-                    }
-                    mSettingsWindow.dismiss();
-                    break;
-                case SETTINGS_MODE_VIDEO_QUALITY:
-                    // TODO: add support for video quality
-                    mSelectedVideoQualityIndex = position;
-                    mSettingsWindow.dismiss();
-                    break;
-            }
-        }
-    };
-
-    private void updateDuration() {
-        if (mMetadata != null) {
-            if (mMetadata.containsKey(MediaMetadata.METADATA_KEY_DURATION)) {
-                mDuration = (int) mMetadata.getLong(MediaMetadata.METADATA_KEY_DURATION);
-                // update progress bar
-                setProgress();
-            }
-        }
-    }
-
-    private void updateTitle() {
-        if (mMetadata != null) {
-            if (mMetadata.containsKey(MediaMetadata.METADATA_KEY_TITLE)) {
-                mTitleView.setText(mMetadata.getString(MediaMetadata.METADATA_KEY_TITLE));
-            }
-        }
-    }
-
-    // The title bar is made up of two separate LinearLayouts. If the sum of the two bars are
-    // greater than the length of the title bar, reduce the size of the left bar (which makes the
-    // TextView that contains the title of the media file shrink).
-    private void updateTitleBarLayout() {
-        if (mTitleBar != null) {
-            int titleBarWidth = mTitleBar.getWidth();
-
-            View leftBar = mTitleBar.findViewById(R.id.title_bar_left);
-            View rightBar = mTitleBar.findViewById(R.id.title_bar_right);
-            int leftBarWidth = leftBar.getWidth();
-            int rightBarWidth = rightBar.getWidth();
-
-            RelativeLayout.LayoutParams params =
-                    (RelativeLayout.LayoutParams) leftBar.getLayoutParams();
-            if (leftBarWidth + rightBarWidth > titleBarWidth) {
-                params.width = titleBarWidth - rightBarWidth;
-                mOriginalLeftBarWidth = leftBarWidth;
-            } else if (leftBarWidth + rightBarWidth < titleBarWidth && mOriginalLeftBarWidth != 0) {
-                params.width = mOriginalLeftBarWidth;
-                mOriginalLeftBarWidth = 0;
-            }
-            leftBar.setLayoutParams(params);
-        }
-    }
-
-    private void updateAudioMetadata() {
-        if (mMediaType != MEDIA_TYPE_MUSIC) {
-            return;
-        }
-
-        if (mMetadata != null) {
-            String titleText = "";
-            String artistText = "";
-            if (mMetadata.containsKey(MediaMetadata.METADATA_KEY_TITLE)) {
-                titleText = mMetadata.getString(MediaMetadata.METADATA_KEY_TITLE);
-            } else {
-                titleText = mResources.getString(R.string.mcv2_music_title_unknown_text);
-            }
-
-            if (mMetadata.containsKey(MediaMetadata.METADATA_KEY_ARTIST)) {
-                artistText = mMetadata.getString(MediaMetadata.METADATA_KEY_ARTIST);
-            } else {
-                artistText = mResources.getString(R.string.mcv2_music_artist_unknown_text);
-            }
-
-            // Update title for Embedded size type
-            mTitleView.setText(titleText + " - " + artistText);
-
-            // Set to true to update layout inside onMeasure()
-            mNeedUXUpdate = true;
-        }
-    }
-
-    private void updateLayout() {
-        if (mIsAdvertisement) {
-            mRewButton.setVisibility(View.GONE);
-            mFfwdButton.setVisibility(View.GONE);
-            mPrevButton.setVisibility(View.GONE);
-            mTimeView.setVisibility(View.GONE);
-
-            mAdSkipView.setVisibility(View.VISIBLE);
-            mAdRemainingView.setVisibility(View.VISIBLE);
-            mAdExternalLink.setVisibility(View.VISIBLE);
-
-            mProgress.setEnabled(false);
-            mNextButton.setEnabled(false);
-            mNextButton.setColorFilter(R.color.gray);
-        } else {
-            mRewButton.setVisibility(View.VISIBLE);
-            mFfwdButton.setVisibility(View.VISIBLE);
-            mPrevButton.setVisibility(View.VISIBLE);
-            mTimeView.setVisibility(View.VISIBLE);
-
-            mAdSkipView.setVisibility(View.GONE);
-            mAdRemainingView.setVisibility(View.GONE);
-            mAdExternalLink.setVisibility(View.GONE);
-
-            mProgress.setEnabled(true);
-            mNextButton.setEnabled(true);
-            mNextButton.clearColorFilter();
-            disableUnsupportedButtons();
-        }
-    }
-
-    private void updateLayout(int maxIconCount, int fullIconSize, int embeddedIconSize,
-             int marginSize, int currWidth, int currHeight, int screenWidth, int screenHeight) {
-        int fullBottomBarRightWidthMax = fullIconSize * maxIconCount
-                + marginSize * (maxIconCount * 2);
-        int embeddedBottomBarRightWidthMax = embeddedIconSize * maxIconCount
-                + marginSize * (maxIconCount * 2);
-        int fullWidth = mTransportControls.getWidth() + mTimeView.getWidth()
-                + fullBottomBarRightWidthMax;
-        int embeddedWidth = mTimeView.getWidth() + embeddedBottomBarRightWidthMax;
-        int screenMaxLength = Math.max(screenWidth, screenHeight);
-
-        if (fullWidth > screenMaxLength) {
-            // TODO: screen may be smaller than the length needed for Full size.
-        }
-
-        boolean isFullSize = (mMediaType == MEDIA_TYPE_DEFAULT) ? (currWidth == screenMaxLength) :
-                (currWidth == screenWidth && currHeight == screenHeight);
-
-        if (isFullSize) {
-            if (mSizeType != SIZE_TYPE_FULL) {
-                updateLayoutForSizeChange(SIZE_TYPE_FULL);
-                if (mMediaType == MEDIA_TYPE_MUSIC) {
-                    mTitleView.setVisibility(View.GONE);
-                }
-            }
-        } else if (embeddedWidth <= currWidth) {
-            if (mSizeType != SIZE_TYPE_EMBEDDED) {
-                updateLayoutForSizeChange(SIZE_TYPE_EMBEDDED);
-                if (mMediaType == MEDIA_TYPE_MUSIC) {
-                    mTitleView.setVisibility(View.VISIBLE);
-                }
-            }
-        } else {
-            if (mSizeType != SIZE_TYPE_MINIMAL) {
-                updateLayoutForSizeChange(SIZE_TYPE_MINIMAL);
-                if (mMediaType == MEDIA_TYPE_MUSIC) {
-                    mTitleView.setVisibility(View.GONE);
-                }
-            }
-        }
-    }
-
-    private void updateLayoutForSizeChange(int sizeType) {
-        mSizeType = sizeType;
-        RelativeLayout.LayoutParams timeViewParams =
-                (RelativeLayout.LayoutParams) mTimeView.getLayoutParams();
-        SeekBar seeker = (SeekBar) mProgress;
-        switch (mSizeType) {
-            case SIZE_TYPE_EMBEDDED:
-                // Relating to Title Bar
-                mTitleBar.setVisibility(View.VISIBLE);
-                mBackButton.setVisibility(View.GONE);
-
-                // Relating to Full Screen Button
-                mMinimalExtraView.setVisibility(View.GONE);
-                mFullScreenButton = mBottomBarRightView.findViewById(R.id.fullscreen);
-                mFullScreenButton.setOnClickListener(mFullScreenListener);
-
-                // Relating to Center View
-                mCenterView.removeAllViews();
-                mBottomBarLeftView.removeView(mTransportControls);
-                mBottomBarLeftView.setVisibility(View.GONE);
-                mTransportControls = inflateTransportControls(R.layout.embedded_transport_controls);
-                mCenterView.addView(mTransportControls);
-
-                // Relating to Progress Bar
-                seeker.setThumb(mResources.getDrawable(R.drawable.custom_progress_thumb));
-                mProgressBuffer.setVisibility(View.VISIBLE);
-
-                // Relating to Bottom Bar
-                mBottomBar.setVisibility(View.VISIBLE);
-                if (timeViewParams.getRule(RelativeLayout.LEFT_OF) != 0) {
-                    timeViewParams.removeRule(RelativeLayout.LEFT_OF);
-                    timeViewParams.addRule(RelativeLayout.RIGHT_OF, R.id.bottom_bar_left);
-                }
-                break;
-            case SIZE_TYPE_FULL:
-                // Relating to Title Bar
-                mTitleBar.setVisibility(View.VISIBLE);
-                mBackButton.setVisibility(View.VISIBLE);
-
-                // Relating to Full Screen Button
-                mMinimalExtraView.setVisibility(View.GONE);
-                mFullScreenButton = mBottomBarRightView.findViewById(R.id.fullscreen);
-                mFullScreenButton.setOnClickListener(mFullScreenListener);
-
-                // Relating to Center View
-                mCenterView.removeAllViews();
-                mBottomBarLeftView.removeView(mTransportControls);
-                mTransportControls = inflateTransportControls(R.layout.full_transport_controls);
-                mBottomBarLeftView.addView(mTransportControls, 0);
-                mBottomBarLeftView.setVisibility(View.VISIBLE);
-
-                // Relating to Progress Bar
-                seeker.setThumb(mResources.getDrawable(R.drawable.custom_progress_thumb));
-                mProgressBuffer.setVisibility(View.VISIBLE);
-
-                // Relating to Bottom Bar
-                mBottomBar.setVisibility(View.VISIBLE);
-                if (timeViewParams.getRule(RelativeLayout.RIGHT_OF) != 0) {
-                    timeViewParams.removeRule(RelativeLayout.RIGHT_OF);
-                    timeViewParams.addRule(RelativeLayout.LEFT_OF, R.id.bottom_bar_right);
-                }
-                break;
-            case SIZE_TYPE_MINIMAL:
-                // Relating to Title Bar
-                mTitleBar.setVisibility(View.GONE);
-                mBackButton.setVisibility(View.GONE);
-
-                // Relating to Full Screen Button
-                mMinimalExtraView.setVisibility(View.VISIBLE);
-                mFullScreenButton = mMinimalExtraView.findViewById(R.id.fullscreen);
-                mFullScreenButton.setOnClickListener(mFullScreenListener);
-
-                // Relating to Center View
-                mCenterView.removeAllViews();
-                mBottomBarLeftView.removeView(mTransportControls);
-                mTransportControls = inflateTransportControls(R.layout.minimal_transport_controls);
-                mCenterView.addView(mTransportControls);
-
-                // Relating to Progress Bar
-                seeker.setThumb(null);
-                mProgressBuffer.setVisibility(View.GONE);
-
-                // Relating to Bottom Bar
-                mBottomBar.setVisibility(View.GONE);
-                break;
-        }
-        mTimeView.setLayoutParams(timeViewParams);
-
-        if (isPlaying()) {
-            mPlayPauseButton.setImageDrawable(
-                    mResources.getDrawable(R.drawable.ic_pause_circle_filled, null));
-            mPlayPauseButton.setContentDescription(
-                    mResources.getString(R.string.mcv2_pause_button_desc));
-        } else {
-            mPlayPauseButton.setImageDrawable(
-                    mResources.getDrawable(R.drawable.ic_play_circle_filled, null));
-            mPlayPauseButton.setContentDescription(
-                    mResources.getString(R.string.mcv2_play_button_desc));
-        }
-
-        if (mIsFullScreen) {
-            mFullScreenButton.setImageDrawable(
-                    mResources.getDrawable(R.drawable.ic_fullscreen_exit, null));
-        } else {
-            mFullScreenButton.setImageDrawable(
-                    mResources.getDrawable(R.drawable.ic_fullscreen, null));
-        }
-    }
-
-    private View inflateTransportControls(int layoutId) {
-        View v = ApiHelper.inflateLibLayout(mInstance.getContext(), layoutId);
-        mPlayPauseButton = v.findViewById(R.id.pause);
-        if (mPlayPauseButton != null) {
-            mPlayPauseButton.requestFocus();
-            mPlayPauseButton.setOnClickListener(mPlayPauseListener);
-        }
-        mFfwdButton = v.findViewById(R.id.ffwd);
-        if (mFfwdButton != null) {
-            mFfwdButton.setOnClickListener(mFfwdListener);
-            if (mMediaType == MEDIA_TYPE_MUSIC) {
-                mFfwdButton.setVisibility(View.GONE);
-            }
-        }
-        mRewButton = v.findViewById(R.id.rew);
-        if (mRewButton != null) {
-            mRewButton.setOnClickListener(mRewListener);
-            if (mMediaType == MEDIA_TYPE_MUSIC) {
-                mRewButton.setVisibility(View.GONE);
-            }
-        }
-        // TODO: Add support for Next and Previous buttons
-        mNextButton = v.findViewById(R.id.next);
-        if (mNextButton != null) {
-            mNextButton.setOnClickListener(mNextListener);
-            mNextButton.setVisibility(View.GONE);
-        }
-        mPrevButton = v.findViewById(R.id.prev);
-        if (mPrevButton != null) {
-            mPrevButton.setOnClickListener(mPrevListener);
-            mPrevButton.setVisibility(View.GONE);
-        }
-        return v;
-    }
-
-    private void initializeSettingsLists() {
-        mSettingsMainTextsList = new ArrayList<String>();
-        mSettingsMainTextsList.add(
-                mResources.getString(R.string.MediaControlView2_audio_track_text));
-        mSettingsMainTextsList.add(
-                mResources.getString(R.string.MediaControlView2_playback_speed_text));
-        mSettingsMainTextsList.add(
-                mResources.getString(R.string.MediaControlView2_help_text));
-
-        mSettingsSubTextsList = new ArrayList<String>();
-        mSettingsSubTextsList.add(
-                mResources.getString(R.string.MediaControlView2_audio_track_none_text));
-        mSettingsSubTextsList.add(
-                mResources.getStringArray(
-                        R.array.MediaControlView2_playback_speeds)[PLAYBACK_SPEED_1x_INDEX]);
-        mSettingsSubTextsList.add(RESOURCE_EMPTY);
-
-        mSettingsIconIdsList = new ArrayList<Integer>();
-        mSettingsIconIdsList.add(R.drawable.ic_audiotrack);
-        mSettingsIconIdsList.add(R.drawable.ic_play_circle_filled);
-        mSettingsIconIdsList.add(R.drawable.ic_help);
-
-        mAudioTrackList = new ArrayList<String>();
-        mAudioTrackList.add(
-                mResources.getString(R.string.MediaControlView2_audio_track_none_text));
-
-        mVideoQualityList = new ArrayList<String>();
-        mVideoQualityList.add(
-                mResources.getString(R.string.MediaControlView2_video_quality_auto_text));
-
-        mPlaybackSpeedTextList = new ArrayList<String>(Arrays.asList(
-                mResources.getStringArray(R.array.MediaControlView2_playback_speeds)));
-        // Select the "1x" speed as the default value.
-        mSelectedSpeedIndex = PLAYBACK_SPEED_1x_INDEX;
-
-        mPlaybackSpeedList = new ArrayList<Float>();
-        int[] speeds = mResources.getIntArray(R.array.speed_multiplied_by_100);
-        for (int i = 0; i < speeds.length; i++) {
-            float speed = (float) speeds[i] / 100.0f;
-            mPlaybackSpeedList.add(speed);
-        }
-    }
-
-    private void displaySettingsWindow(BaseAdapter adapter) {
-        // Set Adapter
-        mSettingsListView.setAdapter(adapter);
-
-        // Set width of window
-        int itemWidth = (mSizeType == SIZE_TYPE_EMBEDDED)
-                ? mEmbeddedSettingsItemWidth : mFullSettingsItemWidth;
-        mSettingsWindow.setWidth(itemWidth);
-
-        // Calculate height of window and show
-        int itemHeight = (mSizeType == SIZE_TYPE_EMBEDDED)
-                ? mEmbeddedSettingsItemHeight : mFullSettingsItemHeight;
-        int totalHeight = adapter.getCount() * itemHeight;
-        mSettingsWindow.dismiss();
-        mSettingsWindow.showAsDropDown(mInstance, mSettingsWindowMargin,
-                mSettingsWindowMargin - totalHeight, Gravity.BOTTOM | Gravity.RIGHT);
-    }
-
-    private class MediaControllerCallback extends MediaController.Callback {
-        @Override
-        public void onPlaybackStateChanged(PlaybackState state) {
-            mPlaybackState = state;
-
-            // Update pause button depending on playback state for the following two reasons:
-            //   1) Need to handle case where app customizes playback state behavior when app
-            //      activity is resumed.
-            //   2) Need to handle case where the media file reaches end of duration.
-            if (mPlaybackState.getState() != mPrevState) {
-                switch (mPlaybackState.getState()) {
-                    case PlaybackState.STATE_PLAYING:
-                        mPlayPauseButton.setImageDrawable(
-                                mResources.getDrawable(R.drawable.ic_pause_circle_filled, null));
-                        mPlayPauseButton.setContentDescription(
-                                mResources.getString(R.string.mcv2_pause_button_desc));
-                        mInstance.removeCallbacks(mUpdateProgress);
-                        mInstance.post(mUpdateProgress);
-                        break;
-                    case PlaybackState.STATE_PAUSED:
-                        mPlayPauseButton.setImageDrawable(
-                                mResources.getDrawable(R.drawable.ic_play_circle_filled, null));
-                        mPlayPauseButton.setContentDescription(
-                                mResources.getString(R.string.mcv2_play_button_desc));
-                        break;
-                    case PlaybackState.STATE_STOPPED:
-                        mPlayPauseButton.setImageDrawable(
-                                mResources.getDrawable(R.drawable.ic_replay_circle_filled, null));
-                        mPlayPauseButton.setContentDescription(
-                                mResources.getString(R.string.mcv2_replay_button_desc));
-                        mIsStopped = true;
-                        break;
-                    default:
-                        break;
-                }
-                mPrevState = mPlaybackState.getState();
-            }
-
-            if (mPlaybackActions != mPlaybackState.getActions()) {
-                long newActions = mPlaybackState.getActions();
-                if ((newActions & PlaybackState.ACTION_PAUSE) != 0) {
-                    mPlayPauseButton.setVisibility(View.VISIBLE);
-                }
-                if ((newActions & PlaybackState.ACTION_REWIND) != 0
-                        && mMediaType != MEDIA_TYPE_MUSIC) {
-                    if (mRewButton != null) {
-                        mRewButton.setVisibility(View.VISIBLE);
-                    }
-                }
-                if ((newActions & PlaybackState.ACTION_FAST_FORWARD) != 0
-                        && mMediaType != MEDIA_TYPE_MUSIC) {
-                    if (mFfwdButton != null) {
-                        mFfwdButton.setVisibility(View.VISIBLE);
-                    }
-                }
-                if ((newActions & PlaybackState.ACTION_SEEK_TO) != 0) {
-                    mSeekAvailable = true;
-                } else {
-                    mSeekAvailable = false;
-                }
-                mPlaybackActions = newActions;
-            }
-
-            // Add buttons if custom actions are present.
-            List<PlaybackState.CustomAction> customActions = mPlaybackState.getCustomActions();
-            mCustomButtons.removeAllViews();
-            if (customActions.size() > 0) {
-                for (PlaybackState.CustomAction action : customActions) {
-                    ImageButton button = new ImageButton(mInstance.getContext(),
-                            null /* AttributeSet */, 0 /* Style */);
-                    // TODO: Apply R.style.BottomBarButton to this button using library context.
-                    // Refer Constructor with argument (int defStyleRes) of View.java
-                    button.setImageResource(action.getIcon());
-                    button.setTooltipText(action.getName());
-                    final String actionString = action.getAction().toString();
-                    button.setOnClickListener(new View.OnClickListener() {
-                        @Override
-                        public void onClick(View v) {
-                            // TODO: Currently, we are just sending extras that came from session.
-                            // Is it the right behavior?
-                            mControls.sendCustomAction(actionString, action.getExtras());
-                            mInstance.setVisibility(View.VISIBLE);
-                        }
-                    });
-                    mCustomButtons.addView(button);
-                }
-            }
-        }
-
-        @Override
-        public void onMetadataChanged(MediaMetadata metadata) {
-            mMetadata = metadata;
-            updateDuration();
-            updateTitle();
-            updateAudioMetadata();
-        }
-
-        @Override
-        public void onSessionEvent(String event, Bundle extras) {
-            switch (event) {
-                case EVENT_UPDATE_TRACK_STATUS:
-                    mVideoTrackCount = extras.getInt(KEY_VIDEO_TRACK_COUNT);
-                    // If there is one or more audio tracks, and this information has not been
-                    // reflected into the Settings window yet, automatically check the first track.
-                    // Otherwise, the Audio Track selection will be defaulted to "None".
-                    mAudioTrackCount = extras.getInt(KEY_AUDIO_TRACK_COUNT);
-                    mAudioTrackList = new ArrayList<String>();
-                    if (mAudioTrackCount > 0) {
-                        // TODO: add more text about track info.
-                        for (int i = 0; i < mAudioTrackCount; i++) {
-                            String track = mResources.getString(
-                                    R.string.MediaControlView2_audio_track_number_text, i + 1);
-                            mAudioTrackList.add(track);
-                        }
-                        // Change sub text inside the Settings window.
-                        mSettingsSubTextsList.set(SETTINGS_MODE_AUDIO_TRACK,
-                                mAudioTrackList.get(0));
-                    } else {
-                        mAudioTrackList.add(mResources.getString(
-                                R.string.MediaControlView2_audio_track_none_text));
-                    }
-                    if (mVideoTrackCount == 0 && mAudioTrackCount > 0) {
-                        mMediaType = MEDIA_TYPE_MUSIC;
-                    }
-
-                    mSubtitleTrackCount = extras.getInt(KEY_SUBTITLE_TRACK_COUNT);
-                    mSubtitleDescriptionsList = new ArrayList<String>();
-                    if (mSubtitleTrackCount > 0) {
-                        mSubtitleButton.setVisibility(View.VISIBLE);
-                        mSubtitleButton.setEnabled(true);
-                        mSubtitleDescriptionsList.add(mResources.getString(
-                                R.string.MediaControlView2_subtitle_off_text));
-                        for (int i = 0; i < mSubtitleTrackCount; i++) {
-                            String track = mResources.getString(
-                                    R.string.MediaControlView2_subtitle_track_number_text, i + 1);
-                            mSubtitleDescriptionsList.add(track);
-                        }
-                    } else {
-                        mSubtitleButton.setVisibility(View.GONE);
-                        mSubtitleButton.setEnabled(false);
-                    }
-                    break;
-                case EVENT_UPDATE_MEDIA_TYPE_STATUS:
-                    boolean newStatus = extras.getBoolean(KEY_STATE_IS_ADVERTISEMENT);
-                    if (newStatus != mIsAdvertisement) {
-                        mIsAdvertisement = newStatus;
-                        updateLayout();
-                    }
-                    break;
-            }
-        }
-    }
-
-    private class SettingsAdapter extends BaseAdapter {
-        private List<Integer> mIconIds;
-        private List<String> mMainTexts;
-        private List<String> mSubTexts;
-
-        public SettingsAdapter(List<String> mainTexts, @Nullable List<String> subTexts,
-                @Nullable List<Integer> iconIds) {
-            mMainTexts = mainTexts;
-            mSubTexts = subTexts;
-            mIconIds = iconIds;
-        }
-
-        public void updateSubTexts(List<String> subTexts) {
-            mSubTexts = subTexts;
-            notifyDataSetChanged();
-        }
-
-        public String getMainText(int position) {
-            if (mMainTexts != null) {
-                if (position < mMainTexts.size()) {
-                    return mMainTexts.get(position);
-                }
-            }
-            return RESOURCE_EMPTY;
-        }
-
-        @Override
-        public int getCount() {
-            return (mMainTexts == null) ? 0 : mMainTexts.size();
-        }
-
-        @Override
-        public long getItemId(int position) {
-            // Auto-generated method stub--does not have any purpose here
-            // TODO: implement this.
-            return 0;
-        }
-
-        @Override
-        public Object getItem(int position) {
-            // Auto-generated method stub--does not have any purpose here
-            // TODO: implement this.
-            return null;
-        }
-
-        @Override
-        public View getView(int position, View convertView, ViewGroup container) {
-            View row;
-            if (mSizeType == SIZE_TYPE_FULL) {
-                row = ApiHelper.inflateLibLayout(mInstance.getContext(),
-                        R.layout.full_settings_list_item);
-            } else {
-                row = ApiHelper.inflateLibLayout(mInstance.getContext(),
-                        R.layout.embedded_settings_list_item);
-            }
-            TextView mainTextView = (TextView) row.findViewById(R.id.main_text);
-            TextView subTextView = (TextView) row.findViewById(R.id.sub_text);
-            ImageView iconView = (ImageView) row.findViewById(R.id.icon);
-
-            // Set main text
-            mainTextView.setText(mMainTexts.get(position));
-
-            // Remove sub text and center the main text if sub texts do not exist at all or the sub
-            // text at this particular position is empty.
-            if (mSubTexts == null || mSubTexts.get(position) == RESOURCE_EMPTY) {
-                subTextView.setVisibility(View.GONE);
-            } else {
-                // Otherwise, set sub text.
-                subTextView.setText(mSubTexts.get(position));
-            }
-
-            // Remove main icon and set visibility to gone if icons are set to null or the icon at
-            // this particular position is set to RESOURCE_NON_EXISTENT.
-            if (mIconIds == null || mIconIds.get(position) == RESOURCE_NON_EXISTENT) {
-                iconView.setVisibility(View.GONE);
-            } else {
-                // Otherwise, set main icon.
-                iconView.setImageDrawable(mResources.getDrawable(mIconIds.get(position), null));
-            }
-            return row;
-        }
-
-        public void setSubTexts(List<String> subTexts) {
-            mSubTexts = subTexts;
-        }
-    }
-
-    // TODO: extend this class from SettingsAdapter
-    private class SubSettingsAdapter extends BaseAdapter {
-        private List<String> mTexts;
-        private int mCheckPosition;
-
-        public SubSettingsAdapter(List<String> texts, int checkPosition) {
-            mTexts = texts;
-            mCheckPosition = checkPosition;
-        }
-
-        public String getMainText(int position) {
-            if (mTexts != null) {
-                if (position < mTexts.size()) {
-                    return mTexts.get(position);
-                }
-            }
-            return RESOURCE_EMPTY;
-        }
-
-        @Override
-        public int getCount() {
-            return (mTexts == null) ? 0 : mTexts.size();
-        }
-
-        @Override
-        public long getItemId(int position) {
-            // Auto-generated method stub--does not have any purpose here
-            // TODO: implement this.
-            return 0;
-        }
-
-        @Override
-        public Object getItem(int position) {
-            // Auto-generated method stub--does not have any purpose here
-            // TODO: implement this.
-            return null;
-        }
-
-        @Override
-        public View getView(int position, View convertView, ViewGroup container) {
-            View row;
-            if (mSizeType == SIZE_TYPE_FULL) {
-                row = ApiHelper.inflateLibLayout(mInstance.getContext(),
-                        R.layout.full_sub_settings_list_item);
-            } else {
-                row = ApiHelper.inflateLibLayout(mInstance.getContext(),
-                        R.layout.embedded_sub_settings_list_item);
-            }
-            TextView textView = (TextView) row.findViewById(R.id.text);
-            ImageView checkView = (ImageView) row.findViewById(R.id.check);
-
-            textView.setText(mTexts.get(position));
-            if (position != mCheckPosition) {
-                checkView.setVisibility(View.INVISIBLE);
-            }
-            return row;
-        }
-
-        public void setTexts(List<String> texts) {
-            mTexts = texts;
-        }
-
-        public void setCheckPosition(int checkPosition) {
-            mCheckPosition = checkPosition;
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/widget/SubtitleView.java b/packages/MediaComponents/src/com/android/widget/SubtitleView.java
deleted file mode 100644
index 67b2cd1..0000000
--- a/packages/MediaComponents/src/com/android/widget/SubtitleView.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.widget;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.os.Looper;
-import android.support.annotation.Nullable;
-import android.util.AttributeSet;
-import android.widget.FrameLayout;
-
-import com.android.media.subtitle.SubtitleController.Anchor;
-import com.android.media.subtitle.SubtitleTrack.RenderingWidget;
-
-class SubtitleView extends FrameLayout implements Anchor {
-    private static final String TAG = "SubtitleView";
-
-    private RenderingWidget mSubtitleWidget;
-    private RenderingWidget.OnChangedListener mSubtitlesChangedListener;
-
-    public SubtitleView(Context context) {
-        this(context, null);
-    }
-
-    public SubtitleView(Context context, @Nullable AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public SubtitleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
-    }
-
-    public SubtitleView(
-            Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    @Override
-    public void setSubtitleWidget(RenderingWidget subtitleWidget) {
-        if (mSubtitleWidget == subtitleWidget) {
-            return;
-        }
-
-        final boolean attachedToWindow = isAttachedToWindow();
-        if (mSubtitleWidget != null) {
-            if (attachedToWindow) {
-                mSubtitleWidget.onDetachedFromWindow();
-            }
-
-            mSubtitleWidget.setOnChangedListener(null);
-        }
-        mSubtitleWidget = subtitleWidget;
-
-        if (subtitleWidget != null) {
-            if (mSubtitlesChangedListener == null) {
-                mSubtitlesChangedListener = new RenderingWidget.OnChangedListener() {
-                    @Override
-                    public void onChanged(RenderingWidget renderingWidget) {
-                        invalidate();
-                    }
-                };
-            }
-
-            setWillNotDraw(false);
-            subtitleWidget.setOnChangedListener(mSubtitlesChangedListener);
-
-            if (attachedToWindow) {
-                subtitleWidget.onAttachedToWindow();
-                requestLayout();
-            }
-        } else {
-            setWillNotDraw(true);
-        }
-
-        invalidate();
-    }
-
-    @Override
-    public Looper getSubtitleLooper() {
-        return Looper.getMainLooper();
-    }
-
-    @Override
-    public void onAttachedToWindow() {
-        super.onAttachedToWindow();
-
-        if (mSubtitleWidget != null) {
-            mSubtitleWidget.onAttachedToWindow();
-        }
-    }
-
-    @Override
-    public void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-
-        if (mSubtitleWidget != null) {
-            mSubtitleWidget.onDetachedFromWindow();
-        }
-    }
-
-    @Override
-    public void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
-
-        if (mSubtitleWidget != null) {
-            final int width = getWidth() - getPaddingLeft() - getPaddingRight();
-            final int height = getHeight() - getPaddingTop() - getPaddingBottom();
-
-            mSubtitleWidget.setSize(width, height);
-        }
-    }
-
-    @Override
-    public void draw(Canvas canvas) {
-        super.draw(canvas);
-
-        if (mSubtitleWidget != null) {
-            final int saveCount = canvas.save();
-            canvas.translate(getPaddingLeft(), getPaddingTop());
-            mSubtitleWidget.draw(canvas);
-            canvas.restoreToCount(saveCount);
-        }
-    }
-
-    @Override
-    public CharSequence getAccessibilityClassName() {
-        return SubtitleView.class.getName();
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/widget/VideoSurfaceView.java b/packages/MediaComponents/src/com/android/widget/VideoSurfaceView.java
deleted file mode 100644
index fc92e85..0000000
--- a/packages/MediaComponents/src/com/android/widget/VideoSurfaceView.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.widget;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.media.MediaPlayer2;
-import android.support.annotation.NonNull;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.View;
-
-import static android.widget.VideoView2.VIEW_TYPE_SURFACEVIEW;
-
-class VideoSurfaceView extends SurfaceView implements VideoViewInterface, SurfaceHolder.Callback {
-    private static final String TAG = "VideoSurfaceView";
-    private static final boolean DEBUG = true; // STOPSHIP: Log.isLoggable(TAG, Log.DEBUG);
-    private SurfaceHolder mSurfaceHolder = null;
-    private SurfaceListener mSurfaceListener = null;
-    private MediaPlayer2 mMediaPlayer;
-    // A flag to indicate taking over other view should be proceed.
-    private boolean mIsTakingOverOldView;
-    private VideoViewInterface mOldView;
-
-
-    public VideoSurfaceView(Context context) {
-        this(context, null);
-    }
-
-    public VideoSurfaceView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public VideoSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
-    }
-
-    public VideoSurfaceView(Context context, AttributeSet attrs, int defStyleAttr,
-                            int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        getHolder().addCallback(this);
-    }
-
-    ////////////////////////////////////////////////////
-    // implements VideoViewInterface
-    ////////////////////////////////////////////////////
-
-    @Override
-    public boolean assignSurfaceToMediaPlayer(MediaPlayer2 mp) {
-        Log.d(TAG, "assignSurfaceToMediaPlayer(): mSurfaceHolder: " + mSurfaceHolder);
-        if (mp == null || !hasAvailableSurface()) {
-            return false;
-        }
-        mp.setDisplay(mSurfaceHolder);
-        return true;
-    }
-
-    @Override
-    public void setSurfaceListener(SurfaceListener l) {
-        mSurfaceListener = l;
-    }
-
-    @Override
-    public int getViewType() {
-        return VIEW_TYPE_SURFACEVIEW;
-    }
-
-    @Override
-    public void setMediaPlayer(MediaPlayer2 mp) {
-        mMediaPlayer = mp;
-        if (mIsTakingOverOldView) {
-            takeOver(mOldView);
-        }
-    }
-
-    @Override
-    public void takeOver(@NonNull VideoViewInterface oldView) {
-        if (assignSurfaceToMediaPlayer(mMediaPlayer)) {
-            ((View) oldView).setVisibility(GONE);
-            mIsTakingOverOldView = false;
-            mOldView = null;
-            if (mSurfaceListener != null) {
-                mSurfaceListener.onSurfaceTakeOverDone(this);
-            }
-        } else {
-            mIsTakingOverOldView = true;
-            mOldView = oldView;
-        }
-    }
-
-    @Override
-    public boolean hasAvailableSurface() {
-        return (mSurfaceHolder != null && mSurfaceHolder.getSurface() != null);
-    }
-
-    ////////////////////////////////////////////////////
-    // implements SurfaceHolder.Callback
-    ////////////////////////////////////////////////////
-
-    @Override
-    public void surfaceCreated(SurfaceHolder holder) {
-        Log.d(TAG, "surfaceCreated: mSurfaceHolder: " + mSurfaceHolder + ", new holder: " + holder);
-        mSurfaceHolder = holder;
-        if (mIsTakingOverOldView) {
-            takeOver(mOldView);
-        } else {
-            assignSurfaceToMediaPlayer(mMediaPlayer);
-        }
-
-        if (mSurfaceListener != null) {
-            Rect rect = mSurfaceHolder.getSurfaceFrame();
-            mSurfaceListener.onSurfaceCreated(this, rect.width(), rect.height());
-        }
-    }
-
-    @Override
-    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
-        if (mSurfaceListener != null) {
-            mSurfaceListener.onSurfaceChanged(this, width, height);
-        }
-    }
-
-    @Override
-    public void surfaceDestroyed(SurfaceHolder holder) {
-        // After we return from this we can't use the surface any more
-        mSurfaceHolder = null;
-        if (mSurfaceListener != null) {
-            mSurfaceListener.onSurfaceDestroyed(this);
-        }
-    }
-
-    // TODO: Investigate the way to move onMeasure() code into FrameLayout.
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        int videoWidth = (mMediaPlayer == null) ? 0 : mMediaPlayer.getVideoWidth();
-        int videoHeight = (mMediaPlayer == null) ? 0 : mMediaPlayer.getVideoHeight();
-        if (DEBUG) {
-            Log.d(TAG, "onMeasure(" + MeasureSpec.toString(widthMeasureSpec) + ", "
-                    + MeasureSpec.toString(heightMeasureSpec) + ")");
-            Log.i(TAG, " measuredSize: " + getMeasuredWidth() + "/" + getMeasuredHeight());
-            Log.i(TAG, " viewSize: " + getWidth() + "/" + getHeight());
-            Log.i(TAG, " mVideoWidth/height: " + videoWidth + ", " + videoHeight);
-        }
-
-        int width = getDefaultSize(videoWidth, widthMeasureSpec);
-        int height = getDefaultSize(videoHeight, heightMeasureSpec);
-
-        if (videoWidth > 0 && videoHeight > 0) {
-            int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
-            int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
-
-            width = widthSpecSize;
-            height = heightSpecSize;
-
-            // for compatibility, we adjust size based on aspect ratio
-            if (videoWidth * height < width * videoHeight) {
-                width = height * videoWidth / videoHeight;
-                if (DEBUG) {
-                    Log.d(TAG, "image too wide, correcting. width: " + width);
-                }
-            } else if (videoWidth * height > width * videoHeight) {
-                height = width * videoHeight / videoWidth;
-                if (DEBUG) {
-                    Log.d(TAG, "image too tall, correcting. height: " + height);
-                }
-            }
-        } else {
-            // no size yet, just adopt the given spec sizes
-        }
-        setMeasuredDimension(width, height);
-        if (DEBUG) {
-            Log.i(TAG, "end of onMeasure()");
-            Log.i(TAG, " measuredSize: " + getMeasuredWidth() + "/" + getMeasuredHeight());
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "ViewType: SurfaceView / Visibility: " + getVisibility()
-                + " / surfaceHolder: " + mSurfaceHolder;
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/widget/VideoTextureView.java b/packages/MediaComponents/src/com/android/widget/VideoTextureView.java
deleted file mode 100644
index 024a3aa..0000000
--- a/packages/MediaComponents/src/com/android/widget/VideoTextureView.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.widget;
-
-import android.content.Context;
-import android.graphics.SurfaceTexture;
-import android.media.MediaPlayer2;
-import android.support.annotation.NonNull;
-import android.support.annotation.RequiresApi;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Surface;
-import android.view.TextureView;
-import android.view.View;
-
-import static android.widget.VideoView2.VIEW_TYPE_TEXTUREVIEW;
-
-@RequiresApi(26)
-class VideoTextureView extends TextureView
-        implements VideoViewInterface, TextureView.SurfaceTextureListener {
-    private static final String TAG = "VideoTextureView";
-    private static final boolean DEBUG = true; // STOPSHIP: Log.isLoggable(TAG, Log.DEBUG);
-
-    private SurfaceTexture mSurfaceTexture;
-    private Surface mSurface;
-    private SurfaceListener mSurfaceListener;
-    private MediaPlayer2 mMediaPlayer;
-    // A flag to indicate taking over other view should be proceed.
-    private boolean mIsTakingOverOldView;
-    private VideoViewInterface mOldView;
-
-    public VideoTextureView(Context context) {
-        this(context, null);
-    }
-
-    public VideoTextureView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public VideoTextureView(Context context, AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
-    }
-
-    public VideoTextureView(
-            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        setSurfaceTextureListener(this);
-    }
-
-    ////////////////////////////////////////////////////
-    // implements VideoViewInterface
-    ////////////////////////////////////////////////////
-
-    @Override
-    public boolean assignSurfaceToMediaPlayer(MediaPlayer2 mp) {
-        Log.d(TAG, "assignSurfaceToMediaPlayer(): mSurfaceTexture: " + mSurfaceTexture);
-        if (mp == null || !hasAvailableSurface()) {
-            // Surface is not ready.
-            return false;
-        }
-        mp.setSurface(mSurface);
-        return true;
-    }
-
-    @Override
-    public void setSurfaceListener(SurfaceListener l) {
-        mSurfaceListener = l;
-    }
-
-    @Override
-    public int getViewType() {
-        return VIEW_TYPE_TEXTUREVIEW;
-    }
-
-    @Override
-    public void setMediaPlayer(MediaPlayer2 mp) {
-        mMediaPlayer = mp;
-        if (mIsTakingOverOldView) {
-            takeOver(mOldView);
-        }
-    }
-
-    @Override
-    public void takeOver(@NonNull VideoViewInterface oldView) {
-        if (assignSurfaceToMediaPlayer(mMediaPlayer)) {
-            ((View) oldView).setVisibility(GONE);
-            mIsTakingOverOldView = false;
-            mOldView = null;
-            if (mSurfaceListener != null) {
-                mSurfaceListener.onSurfaceTakeOverDone(this);
-            }
-        } else {
-            mIsTakingOverOldView = true;
-            mOldView = oldView;
-        }
-    }
-
-    @Override
-    public boolean hasAvailableSurface() {
-        return (mSurfaceTexture != null && !mSurfaceTexture.isReleased() && mSurface != null);
-    }
-
-    ////////////////////////////////////////////////////
-    // implements TextureView.SurfaceTextureListener
-    ////////////////////////////////////////////////////
-
-    @Override
-    public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
-        Log.d(TAG, "onSurfaceTextureAvailable: mSurfaceTexture: " + mSurfaceTexture
-                + ", new surface: " + surfaceTexture);
-        mSurfaceTexture = surfaceTexture;
-        mSurface = new Surface(mSurfaceTexture);
-        if (mIsTakingOverOldView) {
-            takeOver(mOldView);
-        } else {
-            assignSurfaceToMediaPlayer(mMediaPlayer);
-        }
-        if (mSurfaceListener != null) {
-            mSurfaceListener.onSurfaceCreated(this, width, height);
-        }
-    }
-
-    @Override
-    public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) {
-        if (mSurfaceListener != null) {
-            mSurfaceListener.onSurfaceChanged(this, width, height);
-        }
-        // requestLayout();  // TODO: figure out if it should be called here?
-    }
-
-    @Override
-    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
-        // no-op
-    }
-
-    @Override
-    public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
-        if (mSurfaceListener != null) {
-            mSurfaceListener.onSurfaceDestroyed(this);
-        }
-        mSurfaceTexture = null;
-        mSurface = null;
-        return true;
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        int videoWidth = (mMediaPlayer == null) ? 0 : mMediaPlayer.getVideoWidth();
-        int videoHeight = (mMediaPlayer == null) ? 0 : mMediaPlayer.getVideoHeight();
-        if (DEBUG) {
-            Log.d(TAG, "onMeasure(" + MeasureSpec.toString(widthMeasureSpec) + ", "
-                    + MeasureSpec.toString(heightMeasureSpec) + ")");
-            Log.i(TAG, " measuredSize: " + getMeasuredWidth() + "/" + getMeasuredHeight());
-            Log.i(TAG, " viewSize: " + getWidth() + "/" + getHeight());
-            Log.i(TAG, " mVideoWidth/height: " + videoWidth + ", " + videoHeight);
-        }
-
-        int width = getDefaultSize(videoWidth, widthMeasureSpec);
-        int height = getDefaultSize(videoHeight, heightMeasureSpec);
-
-        if (videoWidth > 0 && videoHeight > 0) {
-            int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
-            int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
-
-            width = widthSpecSize;
-            height = heightSpecSize;
-
-            // for compatibility, we adjust size based on aspect ratio
-            if (videoWidth * height < width * videoHeight) {
-                width = height * videoWidth / videoHeight;
-                if (DEBUG) {
-                    Log.d(TAG, "image too wide, correcting. width: " + width);
-                }
-            } else if (videoWidth * height > width * videoHeight) {
-                height = width * videoHeight / videoWidth;
-                if (DEBUG) {
-                    Log.d(TAG, "image too tall, correcting. height: " + height);
-                }
-            }
-        } else {
-            // no size yet, just adopt the given spec sizes
-        }
-        setMeasuredDimension(width, height);
-        if (DEBUG) {
-            Log.i(TAG, "end of onMeasure()");
-            Log.i(TAG, " measuredSize: " + getMeasuredWidth() + "/" + getMeasuredHeight());
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "ViewType: TextureView / Visibility: " + getVisibility()
-                + " / surfaceTexture: " + mSurfaceTexture;
-
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java b/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
deleted file mode 100644
index 97279d6..0000000
--- a/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
+++ /dev/null
@@ -1,1405 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.widget;
-
-import android.content.Context;
-import android.content.pm.ActivityInfo;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Point;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.media.AudioAttributes;
-import android.media.AudioFocusRequest;
-import android.media.AudioManager;
-import android.media.DataSourceDesc;
-import android.media.MediaMetadata;
-import android.media.MediaPlayer2;
-import android.media.MediaPlayer2.MediaPlayer2EventCallback;
-import android.media.MediaPlayer2.OnSubtitleDataListener;
-import android.media.MediaPlayer2Impl;
-import android.media.SubtitleData;
-import android.media.MediaItem2;
-import android.media.MediaMetadata2;
-import android.media.MediaMetadataRetriever;
-import android.media.Metadata;
-import android.media.PlaybackParams;
-import android.media.TimedText;
-import android.media.session.MediaController;
-import android.media.session.MediaController.PlaybackInfo;
-import android.media.session.MediaSession;
-import android.media.session.PlaybackState;
-import android.media.SessionToken2;
-import android.media.update.VideoView2Provider;
-import android.media.update.ViewGroupProvider;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.ResultReceiver;
-import android.support.annotation.Nullable;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.util.Pair;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup.LayoutParams;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityManager;
-import android.widget.ImageView;
-import android.widget.MediaControlView2;
-import android.widget.TextView;
-import android.widget.VideoView2;
-
-import com.android.internal.graphics.palette.Palette;
-import com.android.media.RoutePlayer;
-import com.android.media.subtitle.ClosedCaptionRenderer;
-import com.android.media.subtitle.SubtitleController;
-import com.android.media.subtitle.SubtitleTrack;
-import com.android.media.update.ApiHelper;
-import com.android.media.update.R;
-import com.android.support.mediarouter.media.MediaItemStatus;
-import com.android.support.mediarouter.media.MediaControlIntent;
-import com.android.support.mediarouter.media.MediaRouter;
-import com.android.support.mediarouter.media.MediaRouteSelector;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Executor;
-
-public class VideoView2Impl extends BaseLayout
-        implements VideoView2Provider, VideoViewInterface.SurfaceListener {
-    private static final String TAG = "VideoView2";
-    private static final boolean DEBUG = true; // STOPSHIP: Log.isLoggable(TAG, Log.DEBUG);
-    private static final long DEFAULT_SHOW_CONTROLLER_INTERVAL_MS = 2000;
-
-    private final VideoView2 mInstance;
-
-    private static final int STATE_ERROR = -1;
-    private static final int STATE_IDLE = 0;
-    private static final int STATE_PREPARING = 1;
-    private static final int STATE_PREPARED = 2;
-    private static final int STATE_PLAYING = 3;
-    private static final int STATE_PAUSED = 4;
-    private static final int STATE_PLAYBACK_COMPLETED = 5;
-
-    private static final int INVALID_TRACK_INDEX = -1;
-    private static final float INVALID_SPEED = 0f;
-
-    private static final int SIZE_TYPE_EMBEDDED = 0;
-    private static final int SIZE_TYPE_FULL = 1;
-    // TODO: add support for Minimal size type.
-    private static final int SIZE_TYPE_MINIMAL = 2;
-
-    private AccessibilityManager mAccessibilityManager;
-    private AudioManager mAudioManager;
-    private AudioAttributes mAudioAttributes;
-    private int mAudioFocusType = AudioManager.AUDIOFOCUS_GAIN; // legacy focus gain
-
-    private Pair<Executor, VideoView2.OnCustomActionListener> mCustomActionListenerRecord;
-    private VideoView2.OnViewTypeChangedListener mViewTypeChangedListener;
-    private VideoView2.OnFullScreenRequestListener mFullScreenRequestListener;
-
-    private VideoViewInterface mCurrentView;
-    private VideoTextureView mTextureView;
-    private VideoSurfaceView mSurfaceView;
-
-    private MediaPlayer2 mMediaPlayer;
-    private DataSourceDesc mDsd;
-    private MediaControlView2 mMediaControlView;
-    private MediaSession mMediaSession;
-    private MediaController mMediaController;
-    private Metadata mMetadata;
-    private MediaMetadata2 mMediaMetadata;
-    private MediaMetadataRetriever mRetriever;
-    private boolean mNeedUpdateMediaType;
-    private Bundle mMediaTypeData;
-    private String mTitle;
-
-    // TODO: move music view inside SurfaceView/TextureView or implement VideoViewInterface.
-    private WindowManager mManager;
-    private Resources mResources;
-    private View mMusicView;
-    private Drawable mMusicAlbumDrawable;
-    private String mMusicTitleText;
-    private String mMusicArtistText;
-    private boolean mIsMusicMediaType;
-    private int mPrevWidth;
-    private int mPrevHeight;
-    private int mDominantColor;
-    private int mSizeType;
-
-    private PlaybackState.Builder mStateBuilder;
-    private List<PlaybackState.CustomAction> mCustomActionList;
-    private int mTargetState = STATE_IDLE;
-    private int mCurrentState = STATE_IDLE;
-    private int mCurrentBufferPercentage;
-    private long mSeekWhenPrepared;  // recording the seek position while preparing
-
-    private int mVideoWidth;
-    private int mVideoHeight;
-
-    private ArrayList<Integer> mVideoTrackIndices;
-    private ArrayList<Integer> mAudioTrackIndices;
-    private ArrayList<Pair<Integer, SubtitleTrack>> mSubtitleTrackIndices;
-    private SubtitleController mSubtitleController;
-
-    // selected video/audio/subtitle track index as MediaPlayer2 returns
-    private int mSelectedVideoTrackIndex;
-    private int mSelectedAudioTrackIndex;
-    private int mSelectedSubtitleTrackIndex;
-
-    private SubtitleView mSubtitleView;
-    private boolean mSubtitleEnabled;
-
-    private float mSpeed;
-    // TODO: Remove mFallbackSpeed when integration with MediaPlayer2's new setPlaybackParams().
-    // Refer: https://docs.google.com/document/d/1nzAfns6i2hJ3RkaUre3QMT6wsDedJ5ONLiA_OOBFFX8/edit
-    private float mFallbackSpeed;  // keep the original speed before 'pause' is called.
-    private float mVolumeLevelFloat;
-    private int mVolumeLevel;
-
-    private long mShowControllerIntervalMs;
-
-    private MediaRouter mMediaRouter;
-    private MediaRouteSelector mRouteSelector;
-    private MediaRouter.RouteInfo mRoute;
-    private RoutePlayer mRoutePlayer;
-
-    private final MediaRouter.Callback mRouterCallback = new MediaRouter.Callback() {
-        @Override
-        public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo route) {
-            if (route.supportsControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) {
-                // Stop local playback (if necessary)
-                resetPlayer();
-                mRoute = route;
-                mRoutePlayer = new RoutePlayer(mInstance.getContext(), route);
-                mRoutePlayer.setPlayerEventCallback(new RoutePlayer.PlayerEventCallback() {
-                    @Override
-                    public void onPlayerStateChanged(MediaItemStatus itemStatus) {
-                        PlaybackState.Builder psBuilder = new PlaybackState.Builder();
-                        psBuilder.setActions(RoutePlayer.PLAYBACK_ACTIONS);
-                        long position = itemStatus.getContentPosition();
-                        switch (itemStatus.getPlaybackState()) {
-                            case MediaItemStatus.PLAYBACK_STATE_PENDING:
-                                psBuilder.setState(PlaybackState.STATE_NONE, position, 0);
-                                mCurrentState = STATE_IDLE;
-                                break;
-                            case MediaItemStatus.PLAYBACK_STATE_PLAYING:
-                                psBuilder.setState(PlaybackState.STATE_PLAYING, position, 1);
-                                mCurrentState = STATE_PLAYING;
-                                break;
-                            case MediaItemStatus.PLAYBACK_STATE_PAUSED:
-                                psBuilder.setState(PlaybackState.STATE_PAUSED, position, 0);
-                                mCurrentState = STATE_PAUSED;
-                                break;
-                            case MediaItemStatus.PLAYBACK_STATE_BUFFERING:
-                                psBuilder.setState(PlaybackState.STATE_BUFFERING, position, 0);
-                                mCurrentState = STATE_PAUSED;
-                                break;
-                            case MediaItemStatus.PLAYBACK_STATE_FINISHED:
-                                psBuilder.setState(PlaybackState.STATE_STOPPED, position, 0);
-                                mCurrentState = STATE_PLAYBACK_COMPLETED;
-                                break;
-                        }
-
-                        PlaybackState pbState = psBuilder.build();
-                        mMediaSession.setPlaybackState(pbState);
-
-                        MediaMetadata.Builder mmBuilder = new MediaMetadata.Builder();
-                        mmBuilder.putLong(MediaMetadata.METADATA_KEY_DURATION,
-                                itemStatus.getContentDuration());
-                        mMediaSession.setMetadata(mmBuilder.build());
-                    }
-                });
-                // Start remote playback (if necessary)
-                mRoutePlayer.openVideo(mDsd);
-            }
-        }
-
-        @Override
-        public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo route, int reason) {
-            if (mRoute != null && mRoutePlayer != null) {
-                mRoutePlayer.release();
-                mRoutePlayer = null;
-            }
-            if (mRoute == route) {
-                mRoute = null;
-            }
-            if (reason != MediaRouter.UNSELECT_REASON_ROUTE_CHANGED) {
-                // TODO: Resume local playback  (if necessary)
-                openVideo(mDsd);
-            }
-        }
-    };
-
-    public VideoView2Impl(VideoView2 instance,
-            ViewGroupProvider superProvider, ViewGroupProvider privateProvider) {
-        super(instance, superProvider, privateProvider);
-        mInstance = instance;
-    }
-
-    @Override
-    public void initialize(@Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        mVideoWidth = 0;
-        mVideoHeight = 0;
-        mSpeed = 1.0f;
-        mFallbackSpeed = mSpeed;
-        mSelectedSubtitleTrackIndex = INVALID_TRACK_INDEX;
-        // TODO: add attributes to get this value.
-        mShowControllerIntervalMs = DEFAULT_SHOW_CONTROLLER_INTERVAL_MS;
-
-        mAccessibilityManager = AccessibilityManager.getInstance(mInstance.getContext());
-
-        mAudioManager = (AudioManager) mInstance.getContext()
-                .getSystemService(Context.AUDIO_SERVICE);
-        mAudioAttributes = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA)
-                .setContentType(AudioAttributes.CONTENT_TYPE_MOVIE).build();
-        mInstance.setFocusable(true);
-        mInstance.setFocusableInTouchMode(true);
-        mInstance.requestFocus();
-
-        // TODO: try to keep a single child at a time rather than always having both.
-        mTextureView = new VideoTextureView(mInstance.getContext());
-        mSurfaceView = new VideoSurfaceView(mInstance.getContext());
-        LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,
-                LayoutParams.MATCH_PARENT);
-        mTextureView.setLayoutParams(params);
-        mSurfaceView.setLayoutParams(params);
-        mTextureView.setSurfaceListener(this);
-        mSurfaceView.setSurfaceListener(this);
-        mInstance.addView(mTextureView);
-        mInstance.addView(mSurfaceView);
-
-        mSubtitleView = new SubtitleView(mInstance.getContext());
-        mSubtitleView.setLayoutParams(params);
-        mSubtitleView.setBackgroundColor(0);
-        mInstance.addView(mSubtitleView);
-
-        boolean enableControlView = (attrs == null) || attrs.getAttributeBooleanValue(
-                "http://schemas.android.com/apk/res/android",
-                "enableControlView", true);
-        if (enableControlView) {
-            mMediaControlView = new MediaControlView2(mInstance.getContext());
-        }
-
-        mSubtitleEnabled = (attrs == null) || attrs.getAttributeBooleanValue(
-                "http://schemas.android.com/apk/res/android",
-                "enableSubtitle", false);
-
-        // TODO: Choose TextureView when SurfaceView cannot be created.
-        // Choose surface view by default
-        int viewType = (attrs == null) ? VideoView2.VIEW_TYPE_SURFACEVIEW
-                : attrs.getAttributeIntValue(
-                "http://schemas.android.com/apk/res/android",
-                "viewType", VideoView2.VIEW_TYPE_SURFACEVIEW);
-        if (viewType == VideoView2.VIEW_TYPE_SURFACEVIEW) {
-            Log.d(TAG, "viewType attribute is surfaceView.");
-            mTextureView.setVisibility(View.GONE);
-            mSurfaceView.setVisibility(View.VISIBLE);
-            mCurrentView = mSurfaceView;
-        } else if (viewType == VideoView2.VIEW_TYPE_TEXTUREVIEW) {
-            Log.d(TAG, "viewType attribute is textureView.");
-            mTextureView.setVisibility(View.VISIBLE);
-            mSurfaceView.setVisibility(View.GONE);
-            mCurrentView = mTextureView;
-        }
-
-        MediaRouteSelector.Builder builder = new MediaRouteSelector.Builder();
-        builder.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
-        builder.addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO);
-        builder.addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO);
-        mRouteSelector = builder.build();
-    }
-
-    @Override
-    public void setMediaControlView2_impl(MediaControlView2 mediaControlView, long intervalMs) {
-        mMediaControlView = mediaControlView;
-        mShowControllerIntervalMs = intervalMs;
-        // TODO: Call MediaControlView2.setRouteSelector only when cast availalbe.
-        ((MediaControlView2Impl) mMediaControlView.getProvider()).setRouteSelector(mRouteSelector);
-
-        if (mInstance.isAttachedToWindow()) {
-            attachMediaControlView();
-        }
-    }
-
-    @Override
-    public MediaController getMediaController_impl() {
-        if (mMediaSession == null) {
-            throw new IllegalStateException("MediaSession instance is not available.");
-        }
-        return mMediaController;
-    }
-
-    @Override
-    public SessionToken2 getMediaSessionToken_impl() {
-        // TODO: implement this
-        return null;
-    }
-
-    @Override
-    public MediaControlView2 getMediaControlView2_impl() {
-        return mMediaControlView;
-    }
-
-    @Override
-    public MediaMetadata2 getMediaMetadata_impl() {
-        return mMediaMetadata;
-    }
-
-    @Override
-    public void setMediaMetadata_impl(MediaMetadata2 metadata) {
-        // TODO: integrate this with MediaSession2#MediaItem2
-        mMediaMetadata = metadata;
-
-        // TODO: add support for handling website link
-        mMediaTypeData = new Bundle();
-        boolean isAd = metadata == null ?
-                false : metadata.getLong(MediaMetadata2.METADATA_KEY_ADVERTISEMENT) != 0;
-        mMediaTypeData.putBoolean(
-                MediaControlView2Impl.KEY_STATE_IS_ADVERTISEMENT, isAd);
-
-        if (mMediaSession != null) {
-            mMediaSession.sendSessionEvent(
-                    MediaControlView2Impl.EVENT_UPDATE_MEDIA_TYPE_STATUS, mMediaTypeData);
-        } else {
-            // Update later inside OnPreparedListener after MediaSession is initialized.
-            mNeedUpdateMediaType = true;
-        }
-    }
-
-    @Override
-    public void setSubtitleEnabled_impl(boolean enable) {
-        if (enable != mSubtitleEnabled) {
-            selectOrDeselectSubtitle(enable);
-        }
-        mSubtitleEnabled = enable;
-    }
-
-    @Override
-    public boolean isSubtitleEnabled_impl() {
-        return mSubtitleEnabled;
-    }
-
-    // TODO: remove setSpeed_impl once MediaController2 is ready.
-    @Override
-    public void setSpeed_impl(float speed) {
-        if (speed <= 0.0f) {
-            Log.e(TAG, "Unsupported speed (" + speed + ") is ignored.");
-            return;
-        }
-        mSpeed = speed;
-        if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
-            applySpeed();
-        }
-        updatePlaybackState();
-    }
-
-    @Override
-    public void setAudioFocusRequest_impl(int focusGain) {
-        if (focusGain != AudioManager.AUDIOFOCUS_NONE
-                && focusGain != AudioManager.AUDIOFOCUS_GAIN
-                && focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT
-                && focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
-                && focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE) {
-            throw new IllegalArgumentException("Illegal audio focus type " + focusGain);
-        }
-        mAudioFocusType = focusGain;
-    }
-
-    @Override
-    public void setAudioAttributes_impl(AudioAttributes attributes) {
-        if (attributes == null) {
-            throw new IllegalArgumentException("Illegal null AudioAttributes");
-        }
-        mAudioAttributes = attributes;
-    }
-
-    @Override
-    public void setVideoPath_impl(String path) {
-        mInstance.setVideoUri(Uri.parse(path));
-    }
-
-    @Override
-    public void setVideoUri_impl(Uri uri) {
-        mInstance.setVideoUri(uri, null);
-    }
-
-    @Override
-    public void setVideoUri_impl(Uri uri, Map<String, String> headers) {
-        DataSourceDesc.Builder builder = new DataSourceDesc.Builder();
-        builder.setDataSource(mInstance.getContext(), uri, headers, null);
-        mInstance.setDataSource(builder.build());
-    }
-
-    @Override
-    public void setMediaItem_impl(MediaItem2 mediaItem) {
-        // TODO: implement this
-    }
-
-    @Override
-    public void setDataSource_impl(DataSourceDesc dsd) {
-        mDsd = dsd;
-        mSeekWhenPrepared = 0;
-        openVideo(dsd);
-    }
-
-    @Override
-    public void setViewType_impl(int viewType) {
-        if (viewType == mCurrentView.getViewType()) {
-            return;
-        }
-        VideoViewInterface targetView;
-        if (viewType == VideoView2.VIEW_TYPE_TEXTUREVIEW) {
-            Log.d(TAG, "switching to TextureView");
-            targetView = mTextureView;
-        } else if (viewType == VideoView2.VIEW_TYPE_SURFACEVIEW) {
-            Log.d(TAG, "switching to SurfaceView");
-            targetView = mSurfaceView;
-        } else {
-            throw new IllegalArgumentException("Unknown view type: " + viewType);
-        }
-        ((View) targetView).setVisibility(View.VISIBLE);
-        targetView.takeOver(mCurrentView);
-        mInstance.requestLayout();
-    }
-
-    @Override
-    public int getViewType_impl() {
-        return mCurrentView.getViewType();
-    }
-
-    @Override
-    public void setCustomActions_impl(
-            List<PlaybackState.CustomAction> actionList,
-            Executor executor, VideoView2.OnCustomActionListener listener) {
-        mCustomActionList = actionList;
-        mCustomActionListenerRecord = new Pair<>(executor, listener);
-
-        // Create a new playback builder in order to clear existing the custom actions.
-        mStateBuilder = null;
-        updatePlaybackState();
-    }
-
-    @Override
-    public void setOnViewTypeChangedListener_impl(VideoView2.OnViewTypeChangedListener l) {
-        mViewTypeChangedListener = l;
-    }
-
-    @Override
-    public void setFullScreenRequestListener_impl(VideoView2.OnFullScreenRequestListener l) {
-        mFullScreenRequestListener = l;
-    }
-
-    @Override
-    public void onAttachedToWindow_impl() {
-        super.onAttachedToWindow_impl();
-
-        // Create MediaSession
-        mMediaSession = new MediaSession(mInstance.getContext(), "VideoView2MediaSession");
-        mMediaSession.setCallback(new MediaSessionCallback());
-        mMediaSession.setActive(true);
-        mMediaController = mMediaSession.getController();
-        mMediaRouter = MediaRouter.getInstance(mInstance.getContext());
-        mMediaRouter.setMediaSession(mMediaSession);
-        mMediaRouter.addCallback(mRouteSelector, mRouterCallback);
-        attachMediaControlView();
-        // TODO: remove this after moving MediaSession creating code inside initializing VideoView2
-        if (mCurrentState == STATE_PREPARED) {
-            extractTracks();
-            extractMetadata();
-            extractAudioMetadata();
-            if (mNeedUpdateMediaType) {
-                mMediaSession.sendSessionEvent(
-                        MediaControlView2Impl.EVENT_UPDATE_MEDIA_TYPE_STATUS,
-                        mMediaTypeData);
-                mNeedUpdateMediaType = false;
-            }
-        }
-    }
-
-    @Override
-    public void onDetachedFromWindow_impl() {
-        super.onDetachedFromWindow_impl();
-
-        mMediaSession.release();
-        mMediaSession = null;
-        mMediaController = null;
-    }
-
-    @Override
-    public CharSequence getAccessibilityClassName_impl() {
-        return VideoView2.class.getName();
-    }
-
-    @Override
-    public boolean onTouchEvent_impl(MotionEvent ev) {
-        if (DEBUG) {
-            Log.d(TAG, "onTouchEvent(). mCurrentState=" + mCurrentState
-                    + ", mTargetState=" + mTargetState);
-        }
-        if (ev.getAction() == MotionEvent.ACTION_UP && mMediaControlView != null) {
-            if (!mIsMusicMediaType || mSizeType != SIZE_TYPE_FULL) {
-                toggleMediaControlViewVisibility();
-            }
-        }
-
-        return super.onTouchEvent_impl(ev);
-    }
-
-    @Override
-    public boolean onTrackballEvent_impl(MotionEvent ev) {
-        if (ev.getAction() == MotionEvent.ACTION_UP && mMediaControlView != null) {
-            if (!mIsMusicMediaType || mSizeType != SIZE_TYPE_FULL) {
-                toggleMediaControlViewVisibility();
-            }
-        }
-
-        return super.onTrackballEvent_impl(ev);
-    }
-
-    @Override
-    public boolean dispatchTouchEvent_impl(MotionEvent ev) {
-        // TODO: Test touch event handling logic thoroughly and simplify the logic.
-        return super.dispatchTouchEvent_impl(ev);
-    }
-
-    @Override
-    public void onMeasure_impl(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure_impl(widthMeasureSpec, heightMeasureSpec);
-
-        if (mIsMusicMediaType) {
-            if (mPrevWidth != mInstance.getMeasuredWidth()
-                    || mPrevHeight != mInstance.getMeasuredHeight()) {
-                int currWidth = mInstance.getMeasuredWidth();
-                int currHeight = mInstance.getMeasuredHeight();
-                Point screenSize = new Point();
-                mManager.getDefaultDisplay().getSize(screenSize);
-                int screenWidth = screenSize.x;
-                int screenHeight = screenSize.y;
-
-                if (currWidth == screenWidth && currHeight == screenHeight) {
-                    int orientation = retrieveOrientation();
-                    if (orientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
-                        inflateMusicView(R.layout.full_landscape_music);
-                    } else {
-                        inflateMusicView(R.layout.full_portrait_music);
-                    }
-
-                    if (mSizeType != SIZE_TYPE_FULL) {
-                        mSizeType = SIZE_TYPE_FULL;
-                        // Remove existing mFadeOut callback
-                        mMediaControlView.removeCallbacks(mFadeOut);
-                        mMediaControlView.setVisibility(View.VISIBLE);
-                    }
-                } else {
-                    if (mSizeType != SIZE_TYPE_EMBEDDED) {
-                        mSizeType = SIZE_TYPE_EMBEDDED;
-                        inflateMusicView(R.layout.embedded_music);
-                        // Add new mFadeOut callback
-                        mMediaControlView.postDelayed(mFadeOut, mShowControllerIntervalMs);
-                    }
-                }
-                mPrevWidth = currWidth;
-                mPrevHeight = currHeight;
-            }
-        }
-    }
-
-    ///////////////////////////////////////////////////
-    // Implements VideoViewInterface.SurfaceListener
-    ///////////////////////////////////////////////////
-
-    @Override
-    public void onSurfaceCreated(View view, int width, int height) {
-        if (DEBUG) {
-            Log.d(TAG, "onSurfaceCreated(). mCurrentState=" + mCurrentState
-                    + ", mTargetState=" + mTargetState + ", width/height: " + width + "/" + height
-                    + ", " + view.toString());
-        }
-        if (needToStart()) {
-            mMediaController.getTransportControls().play();
-        }
-    }
-
-    @Override
-    public void onSurfaceDestroyed(View view) {
-        if (DEBUG) {
-            Log.d(TAG, "onSurfaceDestroyed(). mCurrentState=" + mCurrentState
-                    + ", mTargetState=" + mTargetState + ", " + view.toString());
-        }
-    }
-
-    @Override
-    public void onSurfaceChanged(View view, int width, int height) {
-        // TODO: Do we need to call requestLayout here?
-        if (DEBUG) {
-            Log.d(TAG, "onSurfaceChanged(). width/height: " + width + "/" + height
-                    + ", " + view.toString());
-        }
-    }
-
-    @Override
-    public void onSurfaceTakeOverDone(VideoViewInterface view) {
-        if (DEBUG) {
-            Log.d(TAG, "onSurfaceTakeOverDone(). Now current view is: " + view);
-        }
-        mCurrentView = view;
-        if (mViewTypeChangedListener != null) {
-            mViewTypeChangedListener.onViewTypeChanged(mInstance, view.getViewType());
-        }
-        if (needToStart()) {
-            mMediaController.getTransportControls().play();
-        }
-    }
-
-    ///////////////////////////////////////////////////
-    // Protected or private methods
-    ///////////////////////////////////////////////////
-
-    private void attachMediaControlView() {
-        // Get MediaController from MediaSession and set it inside MediaControlView
-        mMediaControlView.setController(mMediaSession.getController());
-
-        LayoutParams params =
-                new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
-        mInstance.addView(mMediaControlView, params);
-    }
-
-    private boolean isInPlaybackState() {
-        return (mMediaPlayer != null || mRoutePlayer != null)
-                && mCurrentState != STATE_ERROR
-                && mCurrentState != STATE_IDLE
-                && mCurrentState != STATE_PREPARING;
-    }
-
-    private boolean needToStart() {
-        return (mMediaPlayer != null || mRoutePlayer != null)
-                && mCurrentState != STATE_PLAYING
-                && mTargetState == STATE_PLAYING;
-    }
-
-    // Creates a MediaPlayer2 instance and prepare playback.
-    private void openVideo(DataSourceDesc dsd) {
-        Uri uri = dsd.getUri();
-        Map<String, String> headers = dsd.getUriHeaders();
-        resetPlayer();
-        if (isRemotePlayback()) {
-            mRoutePlayer.openVideo(dsd);
-            return;
-        }
-        if (mAudioFocusType != AudioManager.AUDIOFOCUS_NONE) {
-            // TODO this should have a focus listener
-            AudioFocusRequest focusRequest;
-            focusRequest = new AudioFocusRequest.Builder(mAudioFocusType)
-                    .setAudioAttributes(mAudioAttributes)
-                    .build();
-            mAudioManager.requestAudioFocus(focusRequest);
-        }
-
-        try {
-            Log.d(TAG, "openVideo(): creating new MediaPlayer2 instance.");
-            mMediaPlayer = new MediaPlayer2Impl();
-            mSurfaceView.setMediaPlayer(mMediaPlayer);
-            mTextureView.setMediaPlayer(mMediaPlayer);
-            mCurrentView.assignSurfaceToMediaPlayer(mMediaPlayer);
-
-            final Context context = mInstance.getContext();
-            // TODO: Add timely firing logic for more accurate sync between CC and video frame
-            mSubtitleController = new SubtitleController(context);
-            mSubtitleController.registerRenderer(new ClosedCaptionRenderer(context));
-            mSubtitleController.setAnchor((SubtitleController.Anchor) mSubtitleView);
-            Executor executor = new Executor() {
-                @Override
-                public void execute(Runnable runnable) {
-                    runnable.run();
-                }
-            };
-            mMediaPlayer.setMediaPlayer2EventCallback(executor, mMediaPlayer2Callback);
-
-            mCurrentBufferPercentage = -1;
-            mMediaPlayer.setDataSource(dsd);
-            mMediaPlayer.setAudioAttributes(mAudioAttributes);
-            mMediaPlayer.setOnSubtitleDataListener(mSubtitleListener);
-            // we don't set the target state here either, but preserve the
-            // target state that was there before.
-            mCurrentState = STATE_PREPARING;
-            mMediaPlayer.prepare();
-
-            // Save file name as title since the file may not have a title Metadata.
-            mTitle = uri.getPath();
-            String scheme = uri.getScheme();
-            if (scheme != null && scheme.equals("file")) {
-                mTitle = uri.getLastPathSegment();
-            }
-            mRetriever = new MediaMetadataRetriever();
-            mRetriever.setDataSource(mInstance.getContext(), uri);
-
-            if (DEBUG) {
-                Log.d(TAG, "openVideo(). mCurrentState=" + mCurrentState
-                        + ", mTargetState=" + mTargetState);
-            }
-        } catch (IllegalArgumentException ex) {
-            Log.w(TAG, "Unable to open content: " + uri, ex);
-            mCurrentState = STATE_ERROR;
-            mTargetState = STATE_ERROR;
-            mMediaPlayer2Callback.onError(mMediaPlayer, dsd,
-                    MediaPlayer2.MEDIA_ERROR_UNKNOWN, MediaPlayer2.MEDIA_ERROR_IO);
-        }
-    }
-
-    /*
-     * Reset the media player in any state
-     */
-    private void resetPlayer() {
-        if (mMediaPlayer != null) {
-            final MediaPlayer2 player = mMediaPlayer;
-            new AsyncTask<MediaPlayer2, Void, Void>() {
-                @Override
-                protected Void doInBackground(MediaPlayer2... players) {
-                    // TODO: Fix NPE while MediaPlayer2.close()
-                    //players[0].close();
-                    return null;
-                }
-            }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, player);
-            mMediaPlayer = null;
-            mTextureView.setMediaPlayer(null);
-            mSurfaceView.setMediaPlayer(null);
-            //mPendingSubtitleTracks.clear();
-            mCurrentState = STATE_IDLE;
-            mTargetState = STATE_IDLE;
-            if (mAudioFocusType != AudioManager.AUDIOFOCUS_NONE) {
-                mAudioManager.abandonAudioFocus(null);
-            }
-        }
-        mVideoWidth = 0;
-        mVideoHeight = 0;
-    }
-
-    private void updatePlaybackState() {
-        if (mStateBuilder == null) {
-            // Get the capabilities of the player for this stream
-            mMetadata = mMediaPlayer.getMetadata(MediaPlayer2.METADATA_ALL,
-                    MediaPlayer2.BYPASS_METADATA_FILTER);
-
-            // Add Play action as default
-            long playbackActions = PlaybackState.ACTION_PLAY;
-            if (mMetadata != null) {
-                if (!mMetadata.has(Metadata.PAUSE_AVAILABLE)
-                        || mMetadata.getBoolean(Metadata.PAUSE_AVAILABLE)) {
-                    playbackActions |= PlaybackState.ACTION_PAUSE;
-                }
-                if (!mMetadata.has(Metadata.SEEK_BACKWARD_AVAILABLE)
-                        || mMetadata.getBoolean(Metadata.SEEK_BACKWARD_AVAILABLE)) {
-                    playbackActions |= PlaybackState.ACTION_REWIND;
-                }
-                if (!mMetadata.has(Metadata.SEEK_FORWARD_AVAILABLE)
-                        || mMetadata.getBoolean(Metadata.SEEK_FORWARD_AVAILABLE)) {
-                    playbackActions |= PlaybackState.ACTION_FAST_FORWARD;
-                }
-                if (!mMetadata.has(Metadata.SEEK_AVAILABLE)
-                        || mMetadata.getBoolean(Metadata.SEEK_AVAILABLE)) {
-                    playbackActions |= PlaybackState.ACTION_SEEK_TO;
-                }
-            } else {
-                playbackActions |= (PlaybackState.ACTION_PAUSE |
-                        PlaybackState.ACTION_REWIND | PlaybackState.ACTION_FAST_FORWARD |
-                        PlaybackState.ACTION_SEEK_TO);
-            }
-            mStateBuilder = new PlaybackState.Builder();
-            mStateBuilder.setActions(playbackActions);
-
-            if (mCustomActionList != null) {
-                for (PlaybackState.CustomAction action : mCustomActionList) {
-                    mStateBuilder.addCustomAction(action);
-                }
-            }
-        }
-        mStateBuilder.setState(getCorrespondingPlaybackState(),
-                mMediaPlayer.getCurrentPosition(), mSpeed);
-        if (mCurrentState != STATE_ERROR
-            && mCurrentState != STATE_IDLE
-            && mCurrentState != STATE_PREPARING) {
-            // TODO: this should be replaced with MediaPlayer2.getBufferedPosition() once it is
-            // implemented.
-            if (mCurrentBufferPercentage == -1) {
-                mStateBuilder.setBufferedPosition(-1);
-            } else {
-                mStateBuilder.setBufferedPosition(
-                        (long) (mCurrentBufferPercentage / 100.0 * mMediaPlayer.getDuration()));
-            }
-        }
-
-        // Set PlaybackState for MediaSession
-        if (mMediaSession != null) {
-            PlaybackState state = mStateBuilder.build();
-            mMediaSession.setPlaybackState(state);
-        }
-    }
-
-    private int getCorrespondingPlaybackState() {
-        switch (mCurrentState) {
-            case STATE_ERROR:
-                return PlaybackState.STATE_ERROR;
-            case STATE_IDLE:
-                return PlaybackState.STATE_NONE;
-            case STATE_PREPARING:
-                return PlaybackState.STATE_CONNECTING;
-            case STATE_PREPARED:
-                return PlaybackState.STATE_PAUSED;
-            case STATE_PLAYING:
-                return PlaybackState.STATE_PLAYING;
-            case STATE_PAUSED:
-                return PlaybackState.STATE_PAUSED;
-            case STATE_PLAYBACK_COMPLETED:
-                return PlaybackState.STATE_STOPPED;
-            default:
-                return -1;
-        }
-    }
-
-    private final Runnable mFadeOut = new Runnable() {
-        @Override
-        public void run() {
-            if (mCurrentState == STATE_PLAYING) {
-                mMediaControlView.setVisibility(View.GONE);
-            }
-        }
-    };
-
-    private void showController() {
-        // TODO: Decide what to show when the state is not in playback state
-        if (mMediaControlView == null || !isInPlaybackState()
-                || (mIsMusicMediaType && mSizeType == SIZE_TYPE_FULL)) {
-            return;
-        }
-        mMediaControlView.removeCallbacks(mFadeOut);
-        mMediaControlView.setVisibility(View.VISIBLE);
-        if (mShowControllerIntervalMs != 0
-            && !mAccessibilityManager.isTouchExplorationEnabled()) {
-            mMediaControlView.postDelayed(mFadeOut, mShowControllerIntervalMs);
-        }
-    }
-
-    private void toggleMediaControlViewVisibility() {
-        if (mMediaControlView.getVisibility() == View.VISIBLE) {
-            mMediaControlView.removeCallbacks(mFadeOut);
-            mMediaControlView.setVisibility(View.GONE);
-        } else {
-            showController();
-        }
-    }
-
-    private void applySpeed() {
-        PlaybackParams params = mMediaPlayer.getPlaybackParams().allowDefaults();
-        if (mSpeed != params.getSpeed()) {
-            try {
-                params.setSpeed(mSpeed);
-                mMediaPlayer.setPlaybackParams(params);
-                mFallbackSpeed = mSpeed;
-            } catch (IllegalArgumentException e) {
-                Log.e(TAG, "PlaybackParams has unsupported value: " + e);
-                // TODO: should revise this part after integrating with MP2.
-                // If mSpeed had an illegal value for speed rate, system will determine best
-                // handling (see PlaybackParams.AUDIO_FALLBACK_MODE_DEFAULT).
-                // Note: The pre-MP2 returns 0.0f when it is paused. In this case, VideoView2 will
-                // use mFallbackSpeed instead.
-                float fallbackSpeed = mMediaPlayer.getPlaybackParams().allowDefaults().getSpeed();
-                if (fallbackSpeed > 0.0f) {
-                    mFallbackSpeed = fallbackSpeed;
-                }
-                mSpeed = mFallbackSpeed;
-            }
-        }
-    }
-
-    private boolean isRemotePlayback() {
-        if (mMediaController == null) {
-            return false;
-        }
-        PlaybackInfo playbackInfo = mMediaController.getPlaybackInfo();
-        return playbackInfo != null
-                && playbackInfo.getPlaybackType() == PlaybackInfo.PLAYBACK_TYPE_REMOTE;
-    }
-
-    private void selectOrDeselectSubtitle(boolean select) {
-        if (!isInPlaybackState()) {
-            return;
-        }
-        if (select) {
-            if (mSubtitleTrackIndices.size() > 0) {
-                // TODO: make this selection dynamic
-                mSelectedSubtitleTrackIndex = mSubtitleTrackIndices.get(0).first;
-                mSubtitleController.selectTrack(mSubtitleTrackIndices.get(0).second);
-                mMediaPlayer.selectTrack(mSelectedSubtitleTrackIndex);
-                mSubtitleView.setVisibility(View.VISIBLE);
-            }
-        } else {
-            if (mSelectedSubtitleTrackIndex != INVALID_TRACK_INDEX) {
-                mMediaPlayer.deselectTrack(mSelectedSubtitleTrackIndex);
-                mSelectedSubtitleTrackIndex = INVALID_TRACK_INDEX;
-                mSubtitleView.setVisibility(View.GONE);
-            }
-        }
-    }
-
-    private void extractTracks() {
-        List<MediaPlayer2.TrackInfo> trackInfos = mMediaPlayer.getTrackInfo();
-        mVideoTrackIndices = new ArrayList<>();
-        mAudioTrackIndices = new ArrayList<>();
-        mSubtitleTrackIndices = new ArrayList<>();
-        mSubtitleController.reset();
-        for (int i = 0; i < trackInfos.size(); ++i) {
-            int trackType = trackInfos.get(i).getTrackType();
-            if (trackType == MediaPlayer2.TrackInfo.MEDIA_TRACK_TYPE_VIDEO) {
-                mVideoTrackIndices.add(i);
-            } else if (trackType == MediaPlayer2.TrackInfo.MEDIA_TRACK_TYPE_AUDIO) {
-                mAudioTrackIndices.add(i);
-            } else if (trackType == MediaPlayer2.TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE
-                    || trackType == MediaPlayer2.TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT) {
-                SubtitleTrack track = mSubtitleController.addTrack(trackInfos.get(i).getFormat());
-                if (track != null) {
-                    mSubtitleTrackIndices.add(new Pair<>(i, track));
-                }
-            }
-        }
-        // Select first tracks as default
-        if (mVideoTrackIndices.size() > 0) {
-            mSelectedVideoTrackIndex = 0;
-        }
-        if (mAudioTrackIndices.size() > 0) {
-            mSelectedAudioTrackIndex = 0;
-        }
-        if (mVideoTrackIndices.size() == 0 && mAudioTrackIndices.size() > 0) {
-            mIsMusicMediaType = true;
-        }
-
-        Bundle data = new Bundle();
-        data.putInt(MediaControlView2Impl.KEY_VIDEO_TRACK_COUNT, mVideoTrackIndices.size());
-        data.putInt(MediaControlView2Impl.KEY_AUDIO_TRACK_COUNT, mAudioTrackIndices.size());
-        data.putInt(MediaControlView2Impl.KEY_SUBTITLE_TRACK_COUNT, mSubtitleTrackIndices.size());
-        if (mSubtitleTrackIndices.size() > 0) {
-            selectOrDeselectSubtitle(mSubtitleEnabled);
-        }
-        mMediaSession.sendSessionEvent(MediaControlView2Impl.EVENT_UPDATE_TRACK_STATUS, data);
-    }
-
-    private void extractMetadata() {
-        // Get and set duration and title values as MediaMetadata for MediaControlView2
-        MediaMetadata.Builder builder = new MediaMetadata.Builder();
-        if (mMetadata != null && mMetadata.has(Metadata.TITLE)) {
-            mTitle = mMetadata.getString(Metadata.TITLE);
-        }
-        builder.putString(MediaMetadata.METADATA_KEY_TITLE, mTitle);
-        builder.putLong(
-                MediaMetadata.METADATA_KEY_DURATION, mMediaPlayer.getDuration());
-
-        if (mMediaSession != null) {
-            mMediaSession.setMetadata(builder.build());
-        }
-    }
-
-    private void extractAudioMetadata() {
-        if (!mIsMusicMediaType) {
-            return;
-        }
-
-        mResources = ApiHelper.getLibResources(mInstance.getContext());
-        mManager = (WindowManager) mInstance.getContext().getApplicationContext()
-                .getSystemService(Context.WINDOW_SERVICE);
-
-        byte[] album = mRetriever.getEmbeddedPicture();
-        if (album != null) {
-            Bitmap bitmap = BitmapFactory.decodeByteArray(album, 0, album.length);
-            mMusicAlbumDrawable = new BitmapDrawable(bitmap);
-
-            // TODO: replace with visualizer
-            Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
-                public void onGenerated(Palette palette) {
-                    // TODO: add dominant color for default album image.
-                    mDominantColor = palette.getDominantColor(0);
-                    if (mMusicView != null) {
-                        mMusicView.setBackgroundColor(mDominantColor);
-                    }
-                }
-            });
-        } else {
-            mMusicAlbumDrawable = mResources.getDrawable(R.drawable.ic_default_album_image);
-        }
-
-        String title = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
-        if (title != null) {
-            mMusicTitleText = title;
-        } else {
-            mMusicTitleText = mResources.getString(R.string.mcv2_music_title_unknown_text);
-        }
-
-        String artist = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);
-        if (artist != null) {
-            mMusicArtistText = artist;
-        } else {
-            mMusicArtistText = mResources.getString(R.string.mcv2_music_artist_unknown_text);
-        }
-
-        // Send title and artist string to MediaControlView2
-        MediaMetadata.Builder builder = new MediaMetadata.Builder();
-        builder.putString(MediaMetadata.METADATA_KEY_TITLE, mMusicTitleText);
-        builder.putString(MediaMetadata.METADATA_KEY_ARTIST, mMusicArtistText);
-        mMediaSession.setMetadata(builder.build());
-
-        // Display Embedded mode as default
-        mInstance.removeView(mSurfaceView);
-        mInstance.removeView(mTextureView);
-        inflateMusicView(R.layout.embedded_music);
-    }
-
-    private int retrieveOrientation() {
-        DisplayMetrics dm = Resources.getSystem().getDisplayMetrics();
-        int width = dm.widthPixels;
-        int height = dm.heightPixels;
-
-        return (height > width) ?
-                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT :
-                ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
-    }
-
-    private void inflateMusicView(int layoutId) {
-        mInstance.removeView(mMusicView);
-
-        View v = ApiHelper.inflateLibLayout(mInstance.getContext(), layoutId);
-        v.setBackgroundColor(mDominantColor);
-
-        ImageView albumView = v.findViewById(R.id.album);
-        if (albumView != null) {
-            albumView.setImageDrawable(mMusicAlbumDrawable);
-        }
-
-        TextView titleView = v.findViewById(R.id.title);
-        if (titleView != null) {
-            titleView.setText(mMusicTitleText);
-        }
-
-        TextView artistView = v.findViewById(R.id.artist);
-        if (artistView != null) {
-            artistView.setText(mMusicArtistText);
-        }
-
-        mMusicView = v;
-        mInstance.addView(mMusicView, 0);
-    }
-
-    OnSubtitleDataListener mSubtitleListener =
-            new OnSubtitleDataListener() {
-                @Override
-                public void onSubtitleData(MediaPlayer2 mp, SubtitleData data) {
-                    if (DEBUG) {
-                        Log.d(TAG, "onSubtitleData(): getTrackIndex: " + data.getTrackIndex()
-                                + ", getCurrentPosition: " + mp.getCurrentPosition()
-                                + ", getStartTimeUs(): " + data.getStartTimeUs()
-                                + ", diff: "
-                                + (data.getStartTimeUs()/1000 - mp.getCurrentPosition())
-                                + "ms, getDurationUs(): " + data.getDurationUs()
-                                );
-
-                    }
-                    final int index = data.getTrackIndex();
-                    if (index != mSelectedSubtitleTrackIndex) {
-                        Log.d(TAG, "onSubtitleData(): getTrackIndex: " + data.getTrackIndex()
-                                + ", selected track index: " + mSelectedSubtitleTrackIndex);
-                        return;
-                    }
-                    for (Pair<Integer, SubtitleTrack> p : mSubtitleTrackIndices) {
-                        if (p.first == index) {
-                            SubtitleTrack track = p.second;
-                            track.onData(data);
-                        }
-                    }
-                }
-            };
-
-    MediaPlayer2EventCallback mMediaPlayer2Callback =
-            new MediaPlayer2EventCallback() {
-                @Override
-                public void onVideoSizeChanged(
-                        MediaPlayer2 mp, DataSourceDesc dsd, int width, int height) {
-                    if (DEBUG) {
-                        Log.d(TAG, "onVideoSizeChanged(): size: " + width + "/" + height);
-                    }
-                    mVideoWidth = mp.getVideoWidth();
-                    mVideoHeight = mp.getVideoHeight();
-                    if (DEBUG) {
-                        Log.d(TAG, "onVideoSizeChanged(): mVideoSize:" + mVideoWidth + "/"
-                                + mVideoHeight);
-                    }
-                    if (mVideoWidth != 0 && mVideoHeight != 0) {
-                        mInstance.requestLayout();
-                    }
-                }
-
-                // TODO: Remove timed text related code later once relevant Renderer is defined.
-                // This is just for debugging purpose.
-                @Override
-                public void onTimedText(
-                        MediaPlayer2 mp, DataSourceDesc dsd, TimedText text) {
-                        Log.d(TAG, "TimedText: " + text.getText());
-                }
-
-                @Override
-                public void onInfo(
-                        MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
-                    if (what == MediaPlayer2.MEDIA_INFO_METADATA_UPDATE) {
-                        extractTracks();
-                    } else if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
-                        this.onPrepared(mp, dsd);
-                    } else if (what == MediaPlayer2.MEDIA_INFO_PLAYBACK_COMPLETE) {
-                        this.onCompletion(mp, dsd);
-                    } else if (what == MediaPlayer2.MEDIA_INFO_BUFFERING_UPDATE) {
-                        this.onBufferingUpdate(mp, dsd, extra);
-                    }
-                }
-
-                @Override
-                public void onError(
-                        MediaPlayer2 mp, DataSourceDesc dsd, int frameworkErr, int implErr) {
-                    if (DEBUG) {
-                        Log.d(TAG, "Error: " + frameworkErr + "," + implErr);
-                    }
-                    mCurrentState = STATE_ERROR;
-                    mTargetState = STATE_ERROR;
-                    updatePlaybackState();
-
-                    if (mMediaControlView != null) {
-                        mMediaControlView.setVisibility(View.GONE);
-                    }
-                }
-
-                @Override
-                public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what,
-                        int status) {
-                    if (what == MediaPlayer2.CALL_COMPLETED_SEEK_TO && status == 0) {
-                        updatePlaybackState();
-                    }
-                }
-
-                private void onPrepared(MediaPlayer2 mp, DataSourceDesc dsd) {
-                    if (DEBUG) {
-                        Log.d(TAG, "OnPreparedListener(). mCurrentState=" + mCurrentState
-                                + ", mTargetState=" + mTargetState);
-                    }
-                    mCurrentState = STATE_PREPARED;
-                    // Create and set playback state for MediaControlView2
-                    updatePlaybackState();
-
-                    // TODO: change this to send TrackInfos to MediaControlView2
-                    // TODO: create MediaSession when initializing VideoView2
-                    if (mMediaSession != null) {
-                        extractTracks();
-                        extractMetadata();
-                        extractAudioMetadata();
-                    }
-
-                    if (mMediaControlView != null) {
-                        mMediaControlView.setEnabled(true);
-                    }
-                    int videoWidth = mp.getVideoWidth();
-                    int videoHeight = mp.getVideoHeight();
-
-                    // mSeekWhenPrepared may be changed after seekTo() call
-                    long seekToPosition = mSeekWhenPrepared;
-                    if (seekToPosition != 0) {
-                        mMediaController.getTransportControls().seekTo(seekToPosition);
-                    }
-
-                    if (videoWidth != 0 && videoHeight != 0) {
-                        if (videoWidth != mVideoWidth || videoHeight != mVideoHeight) {
-                            if (DEBUG) {
-                                Log.i(TAG, "OnPreparedListener() : ");
-                                Log.i(TAG, " video size: " + videoWidth + "/" + videoHeight);
-                                Log.i(TAG, " measuredSize: " + mInstance.getMeasuredWidth() + "/"
-                                        + mInstance.getMeasuredHeight());
-                                Log.i(TAG, " viewSize: " + mInstance.getWidth() + "/"
-                                        + mInstance.getHeight());
-                            }
-                            mVideoWidth = videoWidth;
-                            mVideoHeight = videoHeight;
-                            mInstance.requestLayout();
-                        }
-
-                        if (needToStart()) {
-                            mMediaController.getTransportControls().play();
-                        }
-                    } else {
-                        // We don't know the video size yet, but should start anyway.
-                        // The video size might be reported to us later.
-                        if (needToStart()) {
-                            mMediaController.getTransportControls().play();
-                        }
-                    }
-                }
-
-                private void onCompletion(MediaPlayer2 mp, DataSourceDesc dsd) {
-                    mCurrentState = STATE_PLAYBACK_COMPLETED;
-                    mTargetState = STATE_PLAYBACK_COMPLETED;
-                    updatePlaybackState();
-                    if (mAudioFocusType != AudioManager.AUDIOFOCUS_NONE) {
-                        mAudioManager.abandonAudioFocus(null);
-                    }
-                }
-
-                private void onBufferingUpdate(MediaPlayer2 mp, DataSourceDesc dsd, int percent) {
-                    mCurrentBufferPercentage = percent;
-                    updatePlaybackState();
-                }
-            };
-
-    private class MediaSessionCallback extends MediaSession.Callback {
-        @Override
-        public void onCommand(String command, Bundle args, ResultReceiver receiver) {
-            if (isRemotePlayback()) {
-                mRoutePlayer.onCommand(command, args, receiver);
-            } else {
-                switch (command) {
-                    case MediaControlView2Impl.COMMAND_SHOW_SUBTITLE:
-                        int subtitleIndex = args.getInt(
-                                MediaControlView2Impl.KEY_SELECTED_SUBTITLE_INDEX,
-                                INVALID_TRACK_INDEX);
-                        if (subtitleIndex != INVALID_TRACK_INDEX) {
-                            int subtitleTrackIndex = mSubtitleTrackIndices.get(subtitleIndex).first;
-                            if (subtitleTrackIndex != mSelectedSubtitleTrackIndex) {
-                                mSelectedSubtitleTrackIndex = subtitleTrackIndex;
-                                mInstance.setSubtitleEnabled(true);
-                            }
-                        }
-                        break;
-                    case MediaControlView2Impl.COMMAND_HIDE_SUBTITLE:
-                        mInstance.setSubtitleEnabled(false);
-                        break;
-                    case MediaControlView2Impl.COMMAND_SET_FULLSCREEN:
-                        if (mFullScreenRequestListener != null) {
-                            mFullScreenRequestListener.onFullScreenRequest(
-                                    mInstance,
-                                    args.getBoolean(MediaControlView2Impl.ARGUMENT_KEY_FULLSCREEN));
-                        }
-                        break;
-                    case MediaControlView2Impl.COMMAND_SELECT_AUDIO_TRACK:
-                        int audioIndex = args.getInt(MediaControlView2Impl.KEY_SELECTED_AUDIO_INDEX,
-                                INVALID_TRACK_INDEX);
-                        if (audioIndex != INVALID_TRACK_INDEX) {
-                            int audioTrackIndex = mAudioTrackIndices.get(audioIndex);
-                            if (audioTrackIndex != mSelectedAudioTrackIndex) {
-                                mSelectedAudioTrackIndex = audioTrackIndex;
-                                mMediaPlayer.selectTrack(mSelectedAudioTrackIndex);
-                            }
-                        }
-                        break;
-                    case MediaControlView2Impl.COMMAND_SET_PLAYBACK_SPEED:
-                        float speed = args.getFloat(
-                                MediaControlView2Impl.KEY_PLAYBACK_SPEED, INVALID_SPEED);
-                        if (speed != INVALID_SPEED && speed != mSpeed) {
-                            mInstance.setSpeed(speed);
-                            mSpeed = speed;
-                        }
-                        break;
-                    case MediaControlView2Impl.COMMAND_MUTE:
-                        mVolumeLevel = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
-                        mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
-                        break;
-                    case MediaControlView2Impl.COMMAND_UNMUTE:
-                        mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mVolumeLevel, 0);
-                        break;
-                }
-            }
-            showController();
-        }
-
-        @Override
-        public void onCustomAction(String action, Bundle extras) {
-            mCustomActionListenerRecord.first.execute(() ->
-                    mCustomActionListenerRecord.second.onCustomAction(action, extras));
-            showController();
-        }
-
-        @Override
-        public void onPlay() {
-            if (isInPlaybackState() && (mCurrentView.hasAvailableSurface() || mIsMusicMediaType)) {
-                if (isRemotePlayback()) {
-                    mRoutePlayer.onPlay();
-                } else {
-                    applySpeed();
-                    mMediaPlayer.play();
-                    mCurrentState = STATE_PLAYING;
-                    updatePlaybackState();
-                }
-                mCurrentState = STATE_PLAYING;
-            }
-            mTargetState = STATE_PLAYING;
-            if (DEBUG) {
-                Log.d(TAG, "onPlay(). mCurrentState=" + mCurrentState
-                        + ", mTargetState=" + mTargetState);
-            }
-            showController();
-        }
-
-        @Override
-        public void onPause() {
-            if (isInPlaybackState()) {
-                if (isRemotePlayback()) {
-                    mRoutePlayer.onPause();
-                    mCurrentState = STATE_PAUSED;
-                } else if (mMediaPlayer.isPlaying()) {
-                    mMediaPlayer.pause();
-                    mCurrentState = STATE_PAUSED;
-                    updatePlaybackState();
-                }
-            }
-            mTargetState = STATE_PAUSED;
-            if (DEBUG) {
-                Log.d(TAG, "onPause(). mCurrentState=" + mCurrentState
-                        + ", mTargetState=" + mTargetState);
-            }
-            showController();
-        }
-
-        @Override
-        public void onSeekTo(long pos) {
-            if (isInPlaybackState()) {
-                if (isRemotePlayback()) {
-                    mRoutePlayer.onSeekTo(pos);
-                } else {
-                    mMediaPlayer.seekTo(pos, MediaPlayer2.SEEK_PREVIOUS_SYNC);
-                    mSeekWhenPrepared = 0;
-                }
-            } else {
-                mSeekWhenPrepared = pos;
-            }
-            showController();
-        }
-
-        @Override
-        public void onStop() {
-            if (isRemotePlayback()) {
-                mRoutePlayer.onStop();
-            } else {
-                resetPlayer();
-            }
-            showController();
-        }
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/widget/VideoViewInterface.java b/packages/MediaComponents/src/com/android/widget/VideoViewInterface.java
deleted file mode 100644
index 854d47e..0000000
--- a/packages/MediaComponents/src/com/android/widget/VideoViewInterface.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.widget;
-
-import android.annotation.NonNull;
-import android.media.MediaPlayer2;
-import android.view.View;
-
-interface VideoViewInterface {
-    /**
-     * Assigns the view's surface to the given MediaPlayer2 instance.
-     *
-     * @param mp MediaPlayer2
-     * @return true if the surface is successfully assigned, false if not. It will fail to assign
-     *         if any of MediaPlayer2 or surface is unavailable.
-     */
-    boolean assignSurfaceToMediaPlayer(MediaPlayer2 mp);
-    void setSurfaceListener(SurfaceListener l);
-    int getViewType();
-    void setMediaPlayer(MediaPlayer2 mp);
-
-    /**
-     * Takes over oldView. It means that the MediaPlayer2 will start rendering on this view.
-     * The visibility of oldView will be set as {@link View.GONE}. If the view doesn't have a
-     * MediaPlayer2 instance or its surface is not available, the actual execution is deferred until
-     * a MediaPlayer2 instance is set by {@link #setMediaPlayer} or its surface becomes available.
-     * {@link SurfaceListener.onSurfaceTakeOverDone} will be called when the actual execution is
-     * done.
-     *
-     * @param oldView The view that MediaPlayer2 is currently rendering on.
-     */
-    void takeOver(@NonNull VideoViewInterface oldView);
-
-    /**
-     * Indicates if the view's surface is available.
-     *
-     * @return true if the surface is available.
-     */
-    boolean hasAvailableSurface();
-
-    /**
-     * An instance of VideoViewInterface calls these surface notification methods accordingly if
-     * a listener has been registered via {@link #setSurfaceListener(SurfaceListener)}.
-     */
-    interface SurfaceListener {
-        void onSurfaceCreated(View view, int width, int height);
-        void onSurfaceDestroyed(View view);
-        void onSurfaceChanged(View view, int width, int height);
-        void onSurfaceTakeOverDone(VideoViewInterface view);
-    }
-}
diff --git a/packages/MediaComponents/src/com/android/widget/ViewGroupImpl.java b/packages/MediaComponents/src/com/android/widget/ViewGroupImpl.java
deleted file mode 100644
index 5a06826..0000000
--- a/packages/MediaComponents/src/com/android/widget/ViewGroupImpl.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.widget;
-
-import android.media.update.ViewGroupProvider;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-
-public abstract class ViewGroupImpl implements ViewGroupProvider {
-    private final ViewGroupProvider mSuperProvider;
-
-    public ViewGroupImpl(ViewGroup instance,
-            ViewGroupProvider superProvider, ViewGroupProvider privateProvider) {
-        mSuperProvider = superProvider;
-    }
-
-    @Override
-    public void onAttachedToWindow_impl() {
-        mSuperProvider.onAttachedToWindow_impl();
-    }
-
-    @Override
-    public void onDetachedFromWindow_impl() {
-        mSuperProvider.onDetachedFromWindow_impl();
-    }
-
-    @Override
-    public CharSequence getAccessibilityClassName_impl() {
-        return mSuperProvider.getAccessibilityClassName_impl();
-    }
-
-    @Override
-    public boolean onTouchEvent_impl(MotionEvent ev) {
-        return mSuperProvider.onTouchEvent_impl(ev);
-    }
-
-    @Override
-    public boolean onTrackballEvent_impl(MotionEvent ev) {
-        return mSuperProvider.onTrackballEvent_impl(ev);
-    }
-
-    @Override
-    public void onFinishInflate_impl() {
-        mSuperProvider.onFinishInflate_impl();
-    }
-
-    @Override
-    public void setEnabled_impl(boolean enabled) {
-        mSuperProvider.setEnabled_impl(enabled);
-    }
-
-    @Override
-    public void onVisibilityAggregated_impl(boolean isVisible) {
-        mSuperProvider.onVisibilityAggregated_impl(isVisible);
-    }
-
-    @Override
-    public void onLayout_impl(boolean changed, int left, int top, int right, int bottom) {
-        mSuperProvider.onLayout_impl(changed, left, top, right, bottom);
-    }
-
-    @Override
-    public void onMeasure_impl(int widthMeasureSpec, int heightMeasureSpec) {
-        mSuperProvider.onMeasure_impl(widthMeasureSpec, heightMeasureSpec);
-    }
-
-    @Override
-    public int getSuggestedMinimumWidth_impl() {
-        return mSuperProvider.getSuggestedMinimumWidth_impl();
-    }
-
-    @Override
-    public int getSuggestedMinimumHeight_impl() {
-        return mSuperProvider.getSuggestedMinimumHeight_impl();
-    }
-
-    @Override
-    public void setMeasuredDimension_impl(int measuredWidth, int measuredHeight) {
-        mSuperProvider.setMeasuredDimension_impl(measuredWidth, measuredHeight);
-    }
-
-    @Override
-    public boolean dispatchTouchEvent_impl(MotionEvent ev) {
-        return mSuperProvider.dispatchTouchEvent_impl(ev);
-    }
-
-    @Override
-    public boolean checkLayoutParams_impl(ViewGroup.LayoutParams p) {
-        return mSuperProvider.checkLayoutParams_impl(p);
-    }
-
-    @Override
-    public ViewGroup.LayoutParams generateDefaultLayoutParams_impl() {
-        return mSuperProvider.generateDefaultLayoutParams_impl();
-    }
-
-    @Override
-    public ViewGroup.LayoutParams generateLayoutParams_impl(AttributeSet attrs) {
-        return mSuperProvider.generateLayoutParams_impl(attrs);
-    }
-
-    @Override
-    public ViewGroup.LayoutParams generateLayoutParams_impl(ViewGroup.LayoutParams lp) {
-        return mSuperProvider.generateLayoutParams_impl(lp);
-    }
-
-    @Override
-    public boolean shouldDelayChildPressedState_impl() {
-        return mSuperProvider.shouldDelayChildPressedState_impl();
-    }
-
-    @Override
-    public void measureChildWithMargins_impl(View child,
-        int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed) {
-        mSuperProvider.measureChildWithMargins_impl(child,
-                parentWidthMeasureSpec, widthUsed, parentHeightMeasureSpec, heightUsed);
-    }
-}
diff --git a/packages/MediaComponents/tests/Android.mk b/packages/MediaComponents/tests/Android.mk
deleted file mode 100644
index dddfd2a..0000000
--- a/packages/MediaComponents/tests/Android.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    android.test.runner.stubs \
-    android.test.base.stubs \
-    mockito-target-minus-junit4 \
-    junit
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := MediaComponentsTest
-
-LOCAL_INSTRUMENTATION_FOR := MediaComponents
-
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_CERTIFICATE := platform
-
-include $(BUILD_PACKAGE)
diff --git a/packages/MediaComponents/tests/AndroidManifest.xml b/packages/MediaComponents/tests/AndroidManifest.xml
deleted file mode 100644
index 7255265..0000000
--- a/packages/MediaComponents/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.media.tests">
-
-    <application android:label="Media API Test">
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <!--
-    To run the tests use the command:
-    "adb shell am instrument -w com.android.media.tests/android.test.InstrumentationTestRunner"
-    -->
-    <instrumentation
-        android:name="android.test.InstrumentationTestRunner"
-        android:targetPackage="com.android.media.update"
-        android:label="Media API test" />
-
-</manifest>
diff --git a/packages/MediaComponents/tests/src/com/android/media/SessionPlaylistAgentTest.java b/packages/MediaComponents/tests/src/com/android/media/SessionPlaylistAgentTest.java
deleted file mode 100644
index beb0848..0000000
--- a/packages/MediaComponents/tests/src/com/android/media/SessionPlaylistAgentTest.java
+++ /dev/null
@@ -1,642 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.media;
-
-import static org.mockito.Mockito.*;
-
-import android.content.Context;
-import android.media.AudioAttributes;
-import android.media.DataSourceDesc;
-import android.media.MediaItem2;
-import android.media.MediaMetadata2;
-import android.media.MediaPlayerBase;
-import android.media.MediaPlayerBase.PlayerEventCallback;
-import android.media.MediaPlaylistAgent;
-import android.media.MediaSession2;
-import android.media.MediaSession2.OnDataSourceMissingHelper;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.test.AndroidTestCase;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Matchers;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executor;
-
-/**
- * Tests {@link SessionPlaylistAgent}.
- */
-public class SessionPlaylistAgentTest extends AndroidTestCase {
-    private static final String TAG = "SessionPlaylistAgentTest";
-    private static final int WAIT_TIME_MS = 1000;
-    private static final int INVALID_REPEAT_MODE = -100;
-    private static final int INVALID_SHUFFLE_MODE = -100;
-
-    private Handler mHandler;
-    private Executor mHandlerExecutor;
-
-    private Object mWaitLock = new Object();
-    private Context mContext;
-    private MediaSession2Impl mSessionImpl;
-    private MediaPlayerBase mPlayer;
-    private PlayerEventCallback mPlayerEventCallback;
-    private SessionPlaylistAgent mAgent;
-    private OnDataSourceMissingHelper mDataSourceHelper;
-    private MyPlaylistEventCallback mEventCallback;
-
-    public class MyPlaylistEventCallback extends MediaPlaylistAgent.PlaylistEventCallback {
-        boolean onPlaylistChangedCalled;
-        boolean onPlaylistMetadataChangedCalled;
-        boolean onRepeatModeChangedCalled;
-        boolean onShuffleModeChangedCalled;
-
-        private Object mWaitLock;
-
-        public MyPlaylistEventCallback(Object waitLock) {
-            mWaitLock = waitLock;
-        }
-
-        public void clear() {
-            onPlaylistChangedCalled = false;
-            onPlaylistMetadataChangedCalled = false;
-            onRepeatModeChangedCalled = false;
-            onShuffleModeChangedCalled = false;
-        }
-
-        public void onPlaylistChanged(MediaPlaylistAgent playlistAgent, List<MediaItem2> list,
-                MediaMetadata2 metadata) {
-            synchronized (mWaitLock) {
-                onPlaylistChangedCalled = true;
-                mWaitLock.notify();
-            }
-        }
-
-        public void onPlaylistMetadataChanged(MediaPlaylistAgent playlistAgent,
-                MediaMetadata2 metadata) {
-            synchronized (mWaitLock) {
-                onPlaylistMetadataChangedCalled = true;
-                mWaitLock.notify();
-            }
-        }
-
-        public void onRepeatModeChanged(MediaPlaylistAgent playlistAgent, int repeatMode) {
-            synchronized (mWaitLock) {
-                onRepeatModeChangedCalled = true;
-                mWaitLock.notify();
-            }
-        }
-
-        public void onShuffleModeChanged(MediaPlaylistAgent playlistAgent, int shuffleMode) {
-            synchronized (mWaitLock) {
-                onShuffleModeChangedCalled = true;
-                mWaitLock.notify();
-            }
-        }
-    }
-
-    public class MyDataSourceHelper implements OnDataSourceMissingHelper {
-        @Override
-        public DataSourceDesc onDataSourceMissing(MediaSession2 session, MediaItem2 item) {
-            if (item.getMediaId().contains("WITHOUT_DSD")) {
-                return null;
-            }
-            return new DataSourceDesc.Builder()
-                    .setDataSource(getContext(), Uri.parse("dsd://test"))
-                    .setMediaId(item.getMediaId())
-                    .build();
-        }
-    }
-
-    public class MockPlayer extends MediaPlayerBase {
-        @Override
-        public void play() {
-        }
-
-        @Override
-        public void prepare() {
-        }
-
-        @Override
-        public void pause() {
-        }
-
-        @Override
-        public void reset() {
-        }
-
-        @Override
-        public void skipToNext() {
-        }
-
-        @Override
-        public void seekTo(long pos) {
-        }
-
-        @Override
-        public int getPlayerState() {
-            return 0;
-        }
-
-        @Override
-        public int getBufferingState() {
-            return 0;
-        }
-
-        @Override
-        public void setAudioAttributes(AudioAttributes attributes) {
-        }
-
-        @Override
-        public AudioAttributes getAudioAttributes() {
-            return null;
-        }
-
-        @Override
-        public void setDataSource(DataSourceDesc dsd) {
-        }
-
-        @Override
-        public void setNextDataSource(DataSourceDesc dsd) {
-        }
-
-        @Override
-        public void setNextDataSources(List<DataSourceDesc> dsds) {
-        }
-
-        @Override
-        public DataSourceDesc getCurrentDataSource() {
-            return null;
-        }
-
-        @Override
-        public void loopCurrent(boolean loop) {
-        }
-
-        @Override
-        public void setPlaybackSpeed(float speed) {
-        }
-
-        @Override
-        public void setPlayerVolume(float volume) {
-        }
-
-        @Override
-        public float getPlayerVolume() {
-            return 0;
-        }
-
-        @Override
-        public void registerPlayerEventCallback(Executor e, PlayerEventCallback cb) {
-        }
-
-        @Override
-        public void unregisterPlayerEventCallback(PlayerEventCallback cb) {
-        }
-
-        @Override
-        public void close() throws Exception {
-        }
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        mContext = getContext();
-        // Workaround for dexmaker bug: https://code.google.com/p/dexmaker/issues/detail?id=2
-        // Dexmaker is used by mockito.
-        System.setProperty("dexmaker.dexcache", mContext.getCacheDir().getPath());
-
-        HandlerThread handlerThread = new HandlerThread("SessionPlaylistAgent");
-        handlerThread.start();
-        mHandler = new Handler(handlerThread.getLooper());
-        mHandlerExecutor = (runnable) -> {
-            mHandler.post(runnable);
-        };
-
-        mPlayer = mock(MockPlayer.class);
-        doAnswer(invocation -> {
-            Object[] args = invocation.getArguments();
-            mPlayerEventCallback = (PlayerEventCallback) args[1];
-            return null;
-        }).when(mPlayer).registerPlayerEventCallback(Matchers.any(), Matchers.any());
-
-        mSessionImpl = mock(MediaSession2Impl.class);
-        mDataSourceHelper = new MyDataSourceHelper();
-        mAgent = new SessionPlaylistAgent(mSessionImpl, mPlayer);
-        mAgent.setOnDataSourceMissingHelper(mDataSourceHelper);
-        mEventCallback = new MyPlaylistEventCallback(mWaitLock);
-        mAgent.registerPlaylistEventCallback(mHandlerExecutor, mEventCallback);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mHandler.getLooper().quitSafely();
-        mHandler = null;
-        mHandlerExecutor = null;
-    }
-
-    @Test
-    public void testSetAndGetShuflleMode() throws Exception {
-        int shuffleMode = mAgent.getShuffleMode();
-        if (shuffleMode != MediaPlaylistAgent.SHUFFLE_MODE_NONE) {
-            mEventCallback.clear();
-            synchronized (mWaitLock) {
-                mAgent.setShuffleMode(MediaPlaylistAgent.SHUFFLE_MODE_NONE);
-                mWaitLock.wait(WAIT_TIME_MS);
-                assertTrue(mEventCallback.onShuffleModeChangedCalled);
-            }
-            assertEquals(MediaPlaylistAgent.SHUFFLE_MODE_NONE, mAgent.getShuffleMode());
-        }
-
-        mEventCallback.clear();
-        synchronized (mWaitLock) {
-            mAgent.setShuffleMode(MediaPlaylistAgent.SHUFFLE_MODE_ALL);
-            mWaitLock.wait(WAIT_TIME_MS);
-            assertTrue(mEventCallback.onShuffleModeChangedCalled);
-        }
-        assertEquals(MediaPlaylistAgent.SHUFFLE_MODE_ALL, mAgent.getShuffleMode());
-
-        mEventCallback.clear();
-        synchronized (mWaitLock) {
-            mAgent.setShuffleMode(MediaPlaylistAgent.SHUFFLE_MODE_GROUP);
-            mWaitLock.wait(WAIT_TIME_MS);
-            assertTrue(mEventCallback.onShuffleModeChangedCalled);
-        }
-        assertEquals(MediaPlaylistAgent.SHUFFLE_MODE_GROUP, mAgent.getShuffleMode());
-
-        // INVALID_SHUFFLE_MODE will not change the shuffle mode.
-        mEventCallback.clear();
-        synchronized (mWaitLock) {
-            mAgent.setShuffleMode(INVALID_SHUFFLE_MODE);
-            mWaitLock.wait(WAIT_TIME_MS);
-            assertFalse(mEventCallback.onShuffleModeChangedCalled);
-        }
-        assertEquals(MediaPlaylistAgent.SHUFFLE_MODE_GROUP, mAgent.getShuffleMode());
-    }
-
-    @Test
-    public void testSetAndGetRepeatMode() throws Exception {
-        int repeatMode = mAgent.getRepeatMode();
-        if (repeatMode != MediaPlaylistAgent.REPEAT_MODE_NONE) {
-            mEventCallback.clear();
-            synchronized (mWaitLock) {
-                mAgent.setRepeatMode(MediaPlaylistAgent.REPEAT_MODE_NONE);
-                mWaitLock.wait(WAIT_TIME_MS);
-                assertTrue(mEventCallback.onRepeatModeChangedCalled);
-            }
-            assertEquals(MediaPlaylistAgent.REPEAT_MODE_NONE, mAgent.getRepeatMode());
-        }
-
-        mEventCallback.clear();
-        synchronized (mWaitLock) {
-            mAgent.setRepeatMode(MediaPlaylistAgent.REPEAT_MODE_ONE);
-            mWaitLock.wait(WAIT_TIME_MS);
-            assertTrue(mEventCallback.onRepeatModeChangedCalled);
-        }
-        assertEquals(MediaPlaylistAgent.REPEAT_MODE_ONE, mAgent.getRepeatMode());
-
-        mEventCallback.clear();
-        synchronized (mWaitLock) {
-            mAgent.setRepeatMode(MediaPlaylistAgent.REPEAT_MODE_ALL);
-            mWaitLock.wait(WAIT_TIME_MS);
-            assertTrue(mEventCallback.onRepeatModeChangedCalled);
-        }
-        assertEquals(MediaPlaylistAgent.REPEAT_MODE_ALL, mAgent.getRepeatMode());
-
-        mEventCallback.clear();
-        synchronized (mWaitLock) {
-            mAgent.setRepeatMode(MediaPlaylistAgent.REPEAT_MODE_GROUP);
-            mWaitLock.wait(WAIT_TIME_MS);
-            assertTrue(mEventCallback.onRepeatModeChangedCalled);
-        }
-        assertEquals(MediaPlaylistAgent.REPEAT_MODE_GROUP, mAgent.getRepeatMode());
-
-        // INVALID_SHUFFLE_MODE will not change the shuffle mode.
-        mEventCallback.clear();
-        synchronized (mWaitLock) {
-            mAgent.setRepeatMode(INVALID_REPEAT_MODE);
-            mWaitLock.wait(WAIT_TIME_MS);
-            assertFalse(mEventCallback.onRepeatModeChangedCalled);
-        }
-        assertEquals(MediaPlaylistAgent.REPEAT_MODE_GROUP, mAgent.getRepeatMode());
-    }
-
-    @Test
-    public void testSetPlaylist() throws Exception {
-        int listSize = 10;
-        createAndSetPlaylist(10);
-        assertEquals(listSize, mAgent.getPlaylist().size());
-        assertEquals(0, mAgent.getCurShuffledIndex());
-    }
-
-    @Test
-    public void testSkipItems() throws Exception {
-        int listSize = 5;
-        List<MediaItem2> playlist = createAndSetPlaylist(listSize);
-
-        mAgent.setRepeatMode(MediaPlaylistAgent.REPEAT_MODE_NONE);
-        // Test skipToPlaylistItem
-        for (int i = listSize - 1; i >= 0; --i) {
-            mAgent.skipToPlaylistItem(playlist.get(i));
-            assertEquals(i, mAgent.getCurShuffledIndex());
-        }
-
-        // Test skipToNextItem
-        // curPlayPos = 0
-        for (int curPlayPos = 0; curPlayPos < listSize - 1; ++curPlayPos) {
-            mAgent.skipToNextItem();
-            assertEquals(curPlayPos + 1, mAgent.getCurShuffledIndex());
-        }
-        mAgent.skipToNextItem();
-        assertEquals(listSize - 1, mAgent.getCurShuffledIndex());
-
-        // Test skipToPrevious
-        // curPlayPos = listSize - 1
-        for (int curPlayPos = listSize - 1; curPlayPos > 0; --curPlayPos) {
-            mAgent.skipToPreviousItem();
-            assertEquals(curPlayPos - 1, mAgent.getCurShuffledIndex());
-        }
-        mAgent.skipToPreviousItem();
-        assertEquals(0, mAgent.getCurShuffledIndex());
-
-        mAgent.setRepeatMode(MediaPlaylistAgent.REPEAT_MODE_ALL);
-        // Test skipToPrevious with repeat mode all
-        // curPlayPos = 0
-        mAgent.skipToPreviousItem();
-        assertEquals(listSize - 1, mAgent.getCurShuffledIndex());
-
-        // Test skipToNext with repeat mode all
-        // curPlayPos = listSize - 1
-        mAgent.skipToNextItem();
-        assertEquals(0, mAgent.getCurShuffledIndex());
-
-        mAgent.skipToPreviousItem();
-        // curPlayPos = listSize - 1, nextPlayPos = 0
-        // Test next play pos after setting repeat mode none.
-        mAgent.setRepeatMode(MediaPlaylistAgent.REPEAT_MODE_NONE);
-        assertEquals(listSize - 1, mAgent.getCurShuffledIndex());
-    }
-
-    @Test
-    public void testEditPlaylist() throws Exception {
-        int listSize = 5;
-        List<MediaItem2> playlist = createAndSetPlaylist(listSize);
-
-        // Test add item: [0 (cur), 1, 2, 3, 4] -> [0 (cur), 1, 5, 2, 3, 4]
-        mEventCallback.clear();
-        MediaItem2 item_5 = generateMediaItem(5);
-        synchronized (mWaitLock) {
-            playlist.add(2, item_5);
-            mAgent.addPlaylistItem(2, item_5);
-            mWaitLock.wait(WAIT_TIME_MS);
-            assertTrue(mEventCallback.onPlaylistChangedCalled);
-        }
-        assertPlaylistEquals(playlist, mAgent.getPlaylist());
-
-        mEventCallback.clear();
-        // Move current: [0 (cur), 1, 5, 2, 3, 4] -> [0, 1, 5 (cur), 2, 3, 4]
-        mAgent.skipToPlaylistItem(item_5);
-        // Remove current item: [0, 1, 5 (cur), 2, 3, 4] -> [0, 1, 2 (cur), 3, 4]
-        synchronized (mWaitLock) {
-            playlist.remove(item_5);
-            mAgent.removePlaylistItem(item_5);
-            mWaitLock.wait(WAIT_TIME_MS);
-            assertTrue(mEventCallback.onPlaylistChangedCalled);
-        }
-        assertPlaylistEquals(playlist, mAgent.getPlaylist());
-        assertEquals(2, mAgent.getCurShuffledIndex());
-
-        // Remove previous item: [0, 1, 2 (cur), 3, 4] -> [0, 2 (cur), 3, 4]
-        mEventCallback.clear();
-        MediaItem2 previousItem = playlist.get(1);
-        synchronized (mWaitLock) {
-            playlist.remove(previousItem);
-            mAgent.removePlaylistItem(previousItem);
-            mWaitLock.wait(WAIT_TIME_MS);
-            assertTrue(mEventCallback.onPlaylistChangedCalled);
-        }
-        assertPlaylistEquals(playlist, mAgent.getPlaylist());
-        assertEquals(1, mAgent.getCurShuffledIndex());
-
-        // Remove next item: [0, 2 (cur), 3, 4] -> [0, 2 (cur), 4]
-        mEventCallback.clear();
-        MediaItem2 nextItem = playlist.get(2);
-        synchronized (mWaitLock) {
-            playlist.remove(nextItem);
-            mAgent.removePlaylistItem(nextItem);
-            mWaitLock.wait(WAIT_TIME_MS);
-            assertTrue(mEventCallback.onPlaylistChangedCalled);
-        }
-        assertPlaylistEquals(playlist, mAgent.getPlaylist());
-        assertEquals(1, mAgent.getCurShuffledIndex());
-
-        // Replace item: [0, 2 (cur), 4] -> [0, 2 (cur), 5]
-        mEventCallback.clear();
-        synchronized (mWaitLock) {
-            playlist.set(2, item_5);
-            mAgent.replacePlaylistItem(2, item_5);
-            mWaitLock.wait(WAIT_TIME_MS);
-            assertTrue(mEventCallback.onPlaylistChangedCalled);
-        }
-        assertPlaylistEquals(playlist, mAgent.getPlaylist());
-        assertEquals(1, mAgent.getCurShuffledIndex());
-
-        // Move last and remove the last item: [0, 2 (cur), 5] -> [0, 2, 5 (cur)] -> [0, 2 (cur)]
-        MediaItem2 lastItem = playlist.get(1);
-        mAgent.skipToPlaylistItem(lastItem);
-        mEventCallback.clear();
-        synchronized (mWaitLock) {
-            playlist.remove(lastItem);
-            mAgent.removePlaylistItem(lastItem);
-            mWaitLock.wait(WAIT_TIME_MS);
-            assertTrue(mEventCallback.onPlaylistChangedCalled);
-        }
-        assertPlaylistEquals(playlist, mAgent.getPlaylist());
-        assertEquals(1, mAgent.getCurShuffledIndex());
-
-        // Remove all items
-        for (int i = playlist.size() - 1; i >= 0; --i) {
-            MediaItem2 item = playlist.get(i);
-            mAgent.skipToPlaylistItem(item);
-            mEventCallback.clear();
-            synchronized (mWaitLock) {
-                playlist.remove(item);
-                mAgent.removePlaylistItem(item);
-                mWaitLock.wait(WAIT_TIME_MS);
-                assertTrue(mEventCallback.onPlaylistChangedCalled);
-            }
-            assertPlaylistEquals(playlist, mAgent.getPlaylist());
-        }
-        assertEquals(SessionPlaylistAgent.NO_VALID_ITEMS, mAgent.getCurShuffledIndex());
-    }
-
-
-    @Test
-    public void testPlaylistWithInvalidItem() throws Exception {
-        int listSize = 2;
-        List<MediaItem2> playlist = createAndSetPlaylist(listSize);
-
-        // Add item: [0 (cur), 1] -> [0 (cur), 3 (no_dsd), 1]
-        mEventCallback.clear();
-        MediaItem2 invalidItem2 = generateMediaItemWithoutDataSourceDesc(2);
-        synchronized (mWaitLock) {
-            playlist.add(1, invalidItem2);
-            mAgent.addPlaylistItem(1, invalidItem2);
-            mWaitLock.wait(WAIT_TIME_MS);
-            assertTrue(mEventCallback.onPlaylistChangedCalled);
-        }
-        assertPlaylistEquals(playlist, mAgent.getPlaylist());
-        assertEquals(0, mAgent.getCurShuffledIndex());
-
-        // Test skip to next item:  [0 (cur), 2 (no_dsd), 1] -> [0, 2 (no_dsd), 1 (cur)]
-        mAgent.skipToNextItem();
-        assertEquals(2, mAgent.getCurShuffledIndex());
-
-        // Test skip to previous item: [0, 2 (no_dsd), 1 (cur)] -> [0 (cur), 2 (no_dsd), 1]
-        mAgent.skipToPreviousItem();
-        assertEquals(0, mAgent.getCurShuffledIndex());
-
-        // Remove current item: [0 (cur), 2 (no_dsd), 1] -> [2 (no_dsd), 1 (cur)]
-        mEventCallback.clear();
-        MediaItem2 item = playlist.get(0);
-        synchronized (mWaitLock) {
-            playlist.remove(item);
-            mAgent.removePlaylistItem(item);
-            mWaitLock.wait(WAIT_TIME_MS);
-            assertTrue(mEventCallback.onPlaylistChangedCalled);
-        }
-        assertPlaylistEquals(playlist, mAgent.getPlaylist());
-        assertEquals(1, mAgent.getCurShuffledIndex());
-
-        // Remove current item: [2 (no_dsd), 1 (cur)] -> [2 (no_dsd)]
-        mEventCallback.clear();
-        item = playlist.get(1);
-        synchronized (mWaitLock) {
-            playlist.remove(item);
-            mAgent.removePlaylistItem(item);
-            mWaitLock.wait(WAIT_TIME_MS);
-            assertTrue(mEventCallback.onPlaylistChangedCalled);
-        }
-        assertPlaylistEquals(playlist, mAgent.getPlaylist());
-        assertEquals(SessionPlaylistAgent.NO_VALID_ITEMS, mAgent.getCurShuffledIndex());
-
-        // Add invalid item: [2 (no_dsd)] -> [0 (no_dsd), 2 (no_dsd)]
-        MediaItem2 invalidItem0 = generateMediaItemWithoutDataSourceDesc(0);
-        mEventCallback.clear();
-        synchronized (mWaitLock) {
-            playlist.add(0, invalidItem0);
-            mAgent.addPlaylistItem(0, invalidItem0);
-            mWaitLock.wait(WAIT_TIME_MS);
-            assertTrue(mEventCallback.onPlaylistChangedCalled);
-        }
-        assertPlaylistEquals(playlist, mAgent.getPlaylist());
-        assertEquals(SessionPlaylistAgent.NO_VALID_ITEMS, mAgent.getCurShuffledIndex());
-
-        // Add valid item: [0 (no_dsd), 2 (no_dsd)] -> [0 (no_dsd), 1, 2 (no_dsd)]
-        MediaItem2 invalidItem1 = generateMediaItem(1);
-        mEventCallback.clear();
-        synchronized (mWaitLock) {
-            playlist.add(1, invalidItem1);
-            mAgent.addPlaylistItem(1, invalidItem1);
-            mWaitLock.wait(WAIT_TIME_MS);
-            assertTrue(mEventCallback.onPlaylistChangedCalled);
-        }
-        assertPlaylistEquals(playlist, mAgent.getPlaylist());
-        assertEquals(1, mAgent.getCurShuffledIndex());
-
-        // Replace the valid item with an invalid item:
-        // [0 (no_dsd), 1 (cur), 2 (no_dsd)] -> [0 (no_dsd), 3 (no_dsd), 2 (no_dsd)]
-        MediaItem2 invalidItem3 = generateMediaItemWithoutDataSourceDesc(3);
-        mEventCallback.clear();
-        synchronized (mWaitLock) {
-            playlist.set(1, invalidItem3);
-            mAgent.replacePlaylistItem(1, invalidItem3);
-            mWaitLock.wait(WAIT_TIME_MS);
-            assertTrue(mEventCallback.onPlaylistChangedCalled);
-        }
-        assertPlaylistEquals(playlist, mAgent.getPlaylist());
-        assertEquals(SessionPlaylistAgent.END_OF_PLAYLIST, mAgent.getCurShuffledIndex());
-    }
-
-    @Test
-    public void testPlaylistAfterOnCurrentDataSourceChanged() throws Exception {
-        int listSize = 2;
-        verify(mPlayer).registerPlayerEventCallback(Matchers.any(), Matchers.any());
-
-        createAndSetPlaylist(listSize);
-        assertEquals(0, mAgent.getCurShuffledIndex());
-
-        mPlayerEventCallback.onCurrentDataSourceChanged(mPlayer, null);
-        assertEquals(1, mAgent.getCurShuffledIndex());
-        mPlayerEventCallback.onCurrentDataSourceChanged(mPlayer, null);
-        assertEquals(SessionPlaylistAgent.END_OF_PLAYLIST, mAgent.getCurShuffledIndex());
-
-        mAgent.skipToNextItem();
-        assertEquals(SessionPlaylistAgent.END_OF_PLAYLIST, mAgent.getCurShuffledIndex());
-
-        mAgent.setRepeatMode(MediaPlaylistAgent.REPEAT_MODE_ONE);
-        assertEquals(SessionPlaylistAgent.END_OF_PLAYLIST, mAgent.getCurShuffledIndex());
-
-        mAgent.setRepeatMode(MediaPlaylistAgent.REPEAT_MODE_ALL);
-        assertEquals(0, mAgent.getCurShuffledIndex());
-        mPlayerEventCallback.onCurrentDataSourceChanged(mPlayer, null);
-        assertEquals(1, mAgent.getCurShuffledIndex());
-        mPlayerEventCallback.onCurrentDataSourceChanged(mPlayer, null);
-        assertEquals(0, mAgent.getCurShuffledIndex());
-    }
-
-    private List<MediaItem2> createAndSetPlaylist(int listSize) throws Exception {
-        List<MediaItem2> items = new ArrayList<>();
-        for (int i = 0; i < listSize; ++i) {
-            items.add(generateMediaItem(i));
-        }
-        mEventCallback.clear();
-        synchronized (mWaitLock) {
-            mAgent.setPlaylist(items, null);
-            mWaitLock.wait(WAIT_TIME_MS);
-            assertTrue(mEventCallback.onPlaylistChangedCalled);
-        }
-        return items;
-    }
-
-    private void assertPlaylistEquals(List<MediaItem2> expected, List<MediaItem2> actual) {
-        if (expected == actual) {
-            return;
-        }
-        assertTrue(expected != null && actual != null);
-        assertEquals(expected.size(), actual.size());
-        for (int i = 0; i < expected.size(); ++i) {
-            assertTrue(expected.get(i).equals(actual.get(i)));
-        }
-    }
-
-    private MediaItem2 generateMediaItemWithoutDataSourceDesc(int key) {
-        return new MediaItem2.Builder(0)
-                .setMediaId("TEST_MEDIA_ID_WITHOUT_DSD_" + key)
-                .build();
-    }
-
-    private MediaItem2 generateMediaItem(int key) {
-        return new MediaItem2.Builder(0)
-                .setMediaId("TEST_MEDIA_ID_" + key)
-                .build();
-    }
-}
diff --git a/packages/OWNERS b/packages/OWNERS
deleted file mode 100644
index bbc4cef..0000000
--- a/packages/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-akersten@google.com
-dwkang@google.com
-jaewan@google.com
-marcone@google.com
-sungsoo@google.com
-wjia@google.com
diff --git a/services/OWNERS b/services/OWNERS
index d5d00da..66a4bcb 100644
--- a/services/OWNERS
+++ b/services/OWNERS
@@ -1,4 +1,7 @@
+chz@google.com
 elaurent@google.com
+essick@google.com
 etalvala@google.com
 gkasten@google.com
 hunga@google.com
+marcone@google.com
diff --git a/services/audioflinger/Android.bp b/services/audioflinger/Android.bp
new file mode 100644
index 0000000..96ad54b
--- /dev/null
+++ b/services/audioflinger/Android.bp
@@ -0,0 +1,73 @@
+
+
+cc_library_shared {
+    name: "libaudioflinger",
+
+    srcs: [
+        "AudioFlinger.cpp",
+        "AudioHwDevice.cpp",
+        "AudioStreamOut.cpp",
+        "AudioWatchdog.cpp",
+        "BufLog.cpp",
+        "Effects.cpp",
+        "FastCapture.cpp",
+        "FastCaptureDumpState.cpp",
+        "FastCaptureState.cpp",
+        "FastMixer.cpp",
+        "FastMixerDumpState.cpp",
+        "FastMixerState.cpp",
+        "FastThread.cpp",
+        "FastThreadDumpState.cpp",
+        "FastThreadState.cpp",
+        "NBAIO_Tee.cpp",
+        "PatchPanel.cpp",
+        "SpdifStreamOut.cpp",
+        "StateQueue.cpp",
+        "Threads.cpp",
+        "Tracks.cpp",
+        "TypedLogger.cpp",
+    ],
+
+    include_dirs: [
+        "frameworks/av/services/audiopolicy",
+        "frameworks/av/services/medialog",
+    ],
+
+    shared_libs: [
+        "libaudiohal",
+        "libaudioprocessing",
+        "libaudiospdif",
+        "libaudioutils",
+        "libcutils",
+        "libutils",
+        "liblog",
+        "libbinder",
+        "libaudioclient",
+        "libmedialogservice",
+        "libmediametrics",
+        "libmediautils",
+        "libnbaio",
+        "libnblog",
+        "libpowermanager",
+        "libmediautils",
+        "libmemunreachable",
+        "libmedia_helper",
+        "libvibrator",
+    ],
+
+    static_libs: [
+        "libcpustats",
+        "libsndfile",
+    ],
+
+    cflags: [
+        "-DSTATE_QUEUE_INSTANTIATIONS=\"StateQueueInstantiations.cpp\"",
+        "-fvisibility=hidden",
+        "-Werror",
+        "-Wall",
+    ],
+    sanitize: {
+        integer_overflow: true,
+    },
+
+}
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
deleted file mode 100644
index 7419e64..0000000
--- a/services/audioflinger/Android.mk
+++ /dev/null
@@ -1,88 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-    ServiceUtilities.cpp
-
-# FIXME Move this library to frameworks/native
-LOCAL_MODULE := libserviceutility
-
-LOCAL_SHARED_LIBRARIES := \
-    libcutils \
-    libutils \
-    liblog \
-    libbinder
-
-LOCAL_CFLAGS := -Wall -Werror
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:=               \
-    AudioFlinger.cpp            \
-    Threads.cpp                 \
-    Tracks.cpp                  \
-    AudioHwDevice.cpp           \
-    AudioStreamOut.cpp          \
-    SpdifStreamOut.cpp          \
-    Effects.cpp                 \
-    PatchPanel.cpp              \
-    StateQueue.cpp              \
-    BufLog.cpp                  \
-    TypedLogger.cpp
-
-LOCAL_C_INCLUDES := \
-    frameworks/av/services/audiopolicy \
-    frameworks/av/services/medialog \
-    $(call include-path-for, audio-utils)
-
-LOCAL_SHARED_LIBRARIES := \
-    libaudiohal \
-    libaudioprocessing \
-    libaudiospdif \
-    libaudioutils \
-    libcutils \
-    libutils \
-    liblog \
-    libbinder \
-    libaudioclient \
-    libmedialogservice \
-    libmediautils \
-    libnbaio \
-    libnblog \
-    libpowermanager \
-    libserviceutility \
-    libmediautils \
-    libmemunreachable \
-    libmedia_helper
-
-LOCAL_STATIC_LIBRARIES := \
-    libcpustats \
-
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
-LOCAL_MODULE:= libaudioflinger
-
-LOCAL_SRC_FILES += \
-    AudioWatchdog.cpp        \
-    FastCapture.cpp          \
-    FastCaptureDumpState.cpp \
-    FastCaptureState.cpp     \
-    FastMixer.cpp            \
-    FastMixerDumpState.cpp   \
-    FastMixerState.cpp       \
-    FastThread.cpp           \
-    FastThreadDumpState.cpp  \
-    FastThreadState.cpp
-
-LOCAL_CFLAGS += -DSTATE_QUEUE_INSTANTIATIONS='"StateQueueInstantiations.cpp"'
-
-LOCAL_CFLAGS += -fvisibility=hidden
-
-LOCAL_CFLAGS += -Werror -Wall
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index b884cf4..d38190d 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -23,12 +23,13 @@
 #include <dirent.h>
 #include <math.h>
 #include <signal.h>
+#include <string>
 #include <sys/time.h>
 #include <sys/resource.h>
 
+#include <android/os/IExternalVibratorService.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
-#include <cutils/multiuser.h>
 #include <utils/Log.h>
 #include <utils/Trace.h>
 #include <binder/Parcel.h>
@@ -45,9 +46,10 @@
 #include <cutils/properties.h>
 
 #include <system/audio.h>
+#include <audiomanager/AudioManager.h>
 
 #include "AudioFlinger.h"
-#include "ServiceUtilities.h"
+#include "NBAIO_Tee.h"
 
 #include <media/AudioResamplerPublic.h>
 
@@ -56,7 +58,6 @@
 #include <system/audio_effects/effect_aec.h>
 
 #include <audio_utils/primitives.h>
-#include <audio_utils/string.h>
 
 #include <powermanager/PowerManager.h>
 
@@ -64,8 +65,8 @@
 #include <media/MemoryLeakTrackUtil.h>
 #include <media/nbaio/Pipe.h>
 #include <media/nbaio/PipeReader.h>
-#include <media/AudioParameter.h>
 #include <mediautils/BatteryNotifier.h>
+#include <mediautils/ServiceUtilities.h>
 #include <private/android_filesystem_config.h>
 
 //#define BUFLOG_NDEBUG 0
@@ -100,17 +101,6 @@
 
 uint32_t AudioFlinger::mScreenState;
 
-
-#ifdef TEE_SINK
-bool AudioFlinger::mTeeSinkInputEnabled = false;
-bool AudioFlinger::mTeeSinkOutputEnabled = false;
-bool AudioFlinger::mTeeSinkTrackEnabled = false;
-
-size_t AudioFlinger::mTeeSinkInputFrames = kTeeSinkInputFramesDefault;
-size_t AudioFlinger::mTeeSinkOutputFrames = kTeeSinkOutputFramesDefault;
-size_t AudioFlinger::mTeeSinkTrackFrames = kTeeSinkTrackFramesDefault;
-#endif
-
 // In order to avoid invalidating offloaded tracks each time a Visualizer is turned on and off
 // we define a minimum time during which a global effect is considered enabled.
 static const nsecs_t kMinGlobalEffectEnabletimeNs = seconds(7200);
@@ -134,6 +124,21 @@
     }
 }
 
+// Keep a strong reference to external vibrator service
+static sp<os::IExternalVibratorService> sExternalVibratorService;
+
+static sp<os::IExternalVibratorService> getExternalVibratorService() {
+    if (sExternalVibratorService == 0) {
+        sp <IBinder> binder = defaultServiceManager()->getService(
+            String16("external_vibrator_service"));
+        if (binder != 0) {
+            sExternalVibratorService =
+                interface_cast<os::IExternalVibratorService>(binder);
+        }
+    }
+    return sExternalVibratorService;
+}
+
 // ----------------------------------------------------------------------------
 
 std::string formatToString(audio_format_t format) {
@@ -160,6 +165,7 @@
       mTotalMemory(0),
       mClientSharedHeapSize(kMinimumClientSharedHeapSizeBytes),
       mGlobalEffectEnableTime(0),
+      mPatchPanel(this),
       mSystemReady(false)
 {
     // unsigned instead of audio_unique_id_use_t, because ++ operator is unavailable for enum
@@ -168,7 +174,6 @@
         mNextUniqueIds[use] = AUDIO_UNIQUE_ID_USE_MAX;
     }
 
-    getpid_cached = getpid();
     const bool doLog = property_get_bool("ro.test_harness", false);
     if (doLog) {
         mLogMemoryDealer = new MemoryDealer(kLogMemorySize, "LogWriters",
@@ -185,27 +190,6 @@
     mEffectsFactoryHal = EffectsFactoryHalInterface::create();
 
     mMediaLogNotifier->run("MediaLogNotifier");
-
-#ifdef TEE_SINK
-    char value[PROPERTY_VALUE_MAX];
-    (void) property_get("ro.debuggable", value, "0");
-    int debuggable = atoi(value);
-    int teeEnabled = 0;
-    if (debuggable) {
-        (void) property_get("af.tee", value, "0");
-        teeEnabled = atoi(value);
-    }
-    // FIXME symbolic constants here
-    if (teeEnabled & 1) {
-        mTeeSinkInputEnabled = true;
-    }
-    if (teeEnabled & 2) {
-        mTeeSinkOutputEnabled = true;
-    }
-    if (teeEnabled & 4) {
-        mTeeSinkTrackEnabled = true;
-    }
-#endif
 }
 
 void AudioFlinger::onFirstRef()
@@ -226,8 +210,6 @@
         }
     }
 
-    mPatchPanel = new PatchPanel(this);
-
     mMode = AUDIO_MODE_NORMAL;
 
     gAudioFlinger = this;
@@ -243,6 +225,14 @@
         // closeOutput_nonvirtual() will remove specified entry from mPlaybackThreads
         closeOutput_nonvirtual(mPlaybackThreads.keyAt(0));
     }
+    while (!mMmapThreads.isEmpty()) {
+        const audio_io_handle_t io = mMmapThreads.keyAt(0);
+        if (mMmapThreads.valueAt(0)->isOutput()) {
+            closeOutput_nonvirtual(io); // removes entry from mMmapThreads
+        } else {
+            closeInput_nonvirtual(io);  // removes entry from mMmapThreads
+        }
+    }
 
     for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
         // no mHardwareLock needed, as there are no other references to this
@@ -306,20 +296,26 @@
     audio_stream_type_t streamType = AUDIO_STREAM_DEFAULT;
     audio_io_handle_t io = AUDIO_IO_HANDLE_NONE;
     audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
+    audio_attributes_t localAttr = *attr;
     if (direction == MmapStreamInterface::DIRECTION_OUTPUT) {
         audio_config_t fullConfig = AUDIO_CONFIG_INITIALIZER;
         fullConfig.sample_rate = config->sample_rate;
         fullConfig.channel_mask = config->channel_mask;
         fullConfig.format = config->format;
-        ret = AudioSystem::getOutputForAttr(attr, &io,
+        std::vector<audio_io_handle_t> secondaryOutputs;
+
+        ret = AudioSystem::getOutputForAttr(&localAttr, &io,
                                             actualSessionId,
                                             &streamType, client.clientPid, client.clientUid,
                                             &fullConfig,
                                             (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ |
                                                     AUDIO_OUTPUT_FLAG_DIRECT),
-                                            deviceId, &portId);
+                                            deviceId, &portId, &secondaryOutputs);
+        ALOGW_IF(!secondaryOutputs.empty(),
+                 "%s does not support secondary outputs, ignoring them", __func__);
     } else {
-        ret = AudioSystem::getInputForAttr(attr, &io,
+        ret = AudioSystem::getInputForAttr(&localAttr, &io,
+                                              RECORD_RIID_INVALID,
                                               actualSessionId,
                                               client.clientPid,
                                               client.clientUid,
@@ -336,12 +332,12 @@
     sp<MmapThread> thread = mMmapThreads.valueFor(io);
     if (thread != 0) {
         interface = new MmapThreadHandle(thread);
-        thread->configure(attr, streamType, actualSessionId, callback, *deviceId, portId);
+        thread->configure(&localAttr, streamType, actualSessionId, callback, *deviceId, portId);
         *handle = portId;
         *sessionId = actualSessionId;
     } else {
         if (direction == MmapStreamInterface::DIRECTION_OUTPUT) {
-            AudioSystem::releaseOutput(io, streamType, actualSessionId);
+            AudioSystem::releaseOutput(portId);
         } else {
             AudioSystem::releaseInput(portId);
         }
@@ -353,6 +349,27 @@
     return ret;
 }
 
+/* static */
+int AudioFlinger::onExternalVibrationStart(const sp<os::ExternalVibration>& externalVibration) {
+    sp<os::IExternalVibratorService> evs = getExternalVibratorService();
+    if (evs != 0) {
+        int32_t ret;
+        binder::Status status = evs->onExternalVibrationStart(*externalVibration, &ret);
+        if (status.isOk()) {
+            return ret;
+        }
+    }
+    return AudioMixer::HAPTIC_SCALE_MUTE;
+}
+
+/* static */
+void AudioFlinger::onExternalVibrationStop(const sp<os::ExternalVibration>& externalVibration) {
+    sp<os::IExternalVibratorService> evs = getExternalVibratorService();
+    if (evs != 0) {
+        evs->onExternalVibrationStop(*externalVibration);
+    }
+}
+
 static const char * const audio_interfaces[] = {
     AUDIO_HARDWARE_MODULE_ID_PRIMARY,
     AUDIO_HARDWARE_MODULE_ID_A2DP,
@@ -453,15 +470,8 @@
 
 bool AudioFlinger::dumpTryLock(Mutex& mutex)
 {
-    bool locked = false;
-    for (int i = 0; i < kDumpLockRetries; ++i) {
-        if (mutex.tryLock() == NO_ERROR) {
-            locked = true;
-            break;
-        }
-        usleep(kDumpLockSleepUs);
-    }
-    return locked;
+    status_t err = mutex.timedLock(kDumpLockTimeoutNs);
+    return err == NO_ERROR;
 }
 
 status_t AudioFlinger::dump(int fd, const Vector<String16>& args)
@@ -478,7 +488,7 @@
             mHardwareLock.unlock();
         }
 
-        bool locked = dumpTryLock(mLock);
+        const bool locked = dumpTryLock(mLock);
 
         // failed to lock - AudioFlinger is probably deadlocked
         if (!locked) {
@@ -534,12 +544,22 @@
             dev->dump(fd);
         }
 
-#ifdef TEE_SINK
-        // dump the serially shared record tee sink
-        if (mRecordTeeSource != 0) {
-            dumpTee(fd, mRecordTeeSource, AUDIO_IO_HANDLE_NONE, 'C');
-        }
-#endif
+        mPatchPanel.dump(fd);
+
+        // dump external setParameters
+        auto dumpLogger = [fd](SimpleLog& logger, const char* name) {
+            dprintf(fd, "\n%s setParameters:\n", name);
+            logger.dump(fd, "    " /* prefix */);
+        };
+        dumpLogger(mRejectedSetParameterLog, "Rejected");
+        dumpLogger(mAppSetParameterLog, "App");
+        dumpLogger(mSystemSetParameterLog, "System");
+
+        // dump historical threads in the last 10 seconds
+        const std::string threadLog = mThreadLog.dumpToString(
+                "Historical Thread Log ", 0 /* lines */,
+                audio_utils_get_real_time_ns() - 10 * 60 * NANOS_PER_SECOND);
+        write(fd, threadLog.c_str(), threadLog.size());
 
         BUFLOG_RESET;
 
@@ -547,6 +567,10 @@
             mLock.unlock();
         }
 
+#ifdef TEE_SINK
+        // NBAIO_Tee dump is safe to call outside of AF lock.
+        NBAIO_Tee::dumpAll(fd, "_DUMP");
+#endif
         // append a copy of media.log here by forwarding fd to it, but don't attempt
         // to lookup the service if it's not running, as it will block for a second
         if (sMediaLogServiceAsBinder != 0) {
@@ -662,11 +686,16 @@
     status_t lStatus;
     audio_stream_type_t streamType;
     audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
+    std::vector<audio_io_handle_t> secondaryOutputs;
 
     bool updatePid = (input.clientInfo.clientPid == -1);
     const uid_t callingUid = IPCThreadState::self()->getCallingUid();
     uid_t clientUid = input.clientInfo.clientUid;
-    if (!isTrustedCallingUid(callingUid)) {
+    audio_io_handle_t effectThreadId = AUDIO_IO_HANDLE_NONE;
+    std::vector<int> effectIds;
+    audio_attributes_t localAttr = input.attr;
+
+    if (!isAudioServerOrMediaServerUid(callingUid)) {
         ALOGW_IF(clientUid != callingUid,
                 "%s uid %d tried to pass itself off as %d",
                 __FUNCTION__, callingUid, clientUid);
@@ -674,8 +703,8 @@
         updatePid = true;
     }
     pid_t clientPid = input.clientInfo.clientPid;
+    const pid_t callingPid = IPCThreadState::self()->getCallingPid();
     if (updatePid) {
-        const pid_t callingPid = IPCThreadState::self()->getCallingPid();
         ALOGW_IF(clientPid != -1 && clientPid != callingPid,
                  "%s uid %d pid %d tried to pass itself off as pid %d",
                  __func__, callingUid, callingPid, clientPid);
@@ -693,10 +722,9 @@
     output.sessionId = sessionId;
     output.outputId = AUDIO_IO_HANDLE_NONE;
     output.selectedDeviceId = input.selectedDeviceId;
-
-    lStatus = AudioSystem::getOutputForAttr(&input.attr, &output.outputId, sessionId, &streamType,
+    lStatus = AudioSystem::getOutputForAttr(&localAttr, &output.outputId, sessionId, &streamType,
                                             clientPid, clientUid, &input.config, input.flags,
-                                            &output.selectedDeviceId, &portId);
+                                            &output.selectedDeviceId, &portId, &secondaryOutputs);
 
     if (lStatus != NO_ERROR || output.outputId == AUDIO_IO_HANDLE_NONE) {
         ALOGE("createTrack() getOutputForAttr() return error %d or invalid output handle", lStatus);
@@ -755,18 +783,81 @@
         output.notificationFrameCount = input.notificationFrameCount;
         output.flags = input.flags;
 
-        track = thread->createTrack_l(client, streamType, input.attr, &output.sampleRate,
+        track = thread->createTrack_l(client, streamType, localAttr, &output.sampleRate,
                                       input.config.format, input.config.channel_mask,
                                       &output.frameCount, &output.notificationFrameCount,
                                       input.notificationsPerBuffer, input.speed,
                                       input.sharedBuffer, sessionId, &output.flags,
-                                      input.clientInfo.clientTid, clientUid, &lStatus, portId);
+                                      callingPid, input.clientInfo.clientTid, clientUid,
+                                      &lStatus, portId);
         LOG_ALWAYS_FATAL_IF((lStatus == NO_ERROR) && (track == 0));
         // we don't abort yet if lStatus != NO_ERROR; there is still work to be done regardless
 
         output.afFrameCount = thread->frameCount();
         output.afSampleRate = thread->sampleRate();
         output.afLatencyMs = thread->latency();
+        output.portId = portId;
+
+        if (lStatus == NO_ERROR) {
+            // Connect secondary outputs. Failure on a secondary output must not imped the primary
+            // Any secondary output setup failure will lead to a desync between the AP and AF until
+            // the track is destroyed.
+            TeePatches teePatches;
+            for (audio_io_handle_t secondaryOutput : secondaryOutputs) {
+                PlaybackThread *secondaryThread = checkPlaybackThread_l(secondaryOutput);
+                if (secondaryThread == NULL) {
+                    ALOGE("no playback thread found for secondary output %d", output.outputId);
+                    continue;
+                }
+
+                size_t frameCount = std::lcm(thread->frameCount(), secondaryThread->frameCount());
+
+                using namespace std::chrono_literals;
+                auto inChannelMask = audio_channel_mask_out_to_in(input.config.channel_mask);
+                sp patchRecord = new RecordThread::PatchRecord(nullptr /* thread */,
+                                                               output.sampleRate,
+                                                               inChannelMask,
+                                                               input.config.format,
+                                                               frameCount,
+                                                               NULL /* buffer */,
+                                                               (size_t)0 /* bufferSize */,
+                                                               AUDIO_INPUT_FLAG_DIRECT,
+                                                               0ns /* timeout */);
+                status_t status = patchRecord->initCheck();
+                if (status != NO_ERROR) {
+                    ALOGE("Secondary output patchRecord init failed: %d", status);
+                    continue;
+                }
+
+                // TODO: We could check compatibility of the secondaryThread with the PatchTrack
+                // for fast usage: thread has fast mixer, sample rate matches, etc.;
+                // for now, we exclude fast tracks by removing the Fast flag.
+                const audio_output_flags_t outputFlags =
+                        (audio_output_flags_t)(output.flags & ~AUDIO_OUTPUT_FLAG_FAST);
+                sp patchTrack = new PlaybackThread::PatchTrack(secondaryThread,
+                                                               streamType,
+                                                               output.sampleRate,
+                                                               input.config.channel_mask,
+                                                               input.config.format,
+                                                               frameCount,
+                                                               patchRecord->buffer(),
+                                                               patchRecord->bufferSize(),
+                                                               outputFlags,
+                                                               0ns /* timeout */);
+                status = patchTrack->initCheck();
+                if (status != NO_ERROR) {
+                    ALOGE("Secondary output patchTrack init failed: %d", status);
+                    continue;
+                }
+                teePatches.push_back({patchRecord, patchTrack});
+                secondaryThread->addPatchTrack(patchTrack);
+                // In case the downstream patchTrack on the secondaryThread temporarily outlives
+                // our created track, ensure the corresponding patchRecord is still alive.
+                patchTrack->setPeerProxy(patchRecord, true /* holdReference */);
+                patchRecord->setPeerProxy(patchTrack, false /* holdReference */);
+            }
+            track->setTeePatches(std::move(teePatches));
+        }
 
         // move effect chain to this output thread if an effect on same session was waiting
         // for a track to be created
@@ -774,7 +865,10 @@
             // no risk of deadlock because AudioFlinger::mLock is held
             Mutex::Autolock _dl(thread->mLock);
             Mutex::Autolock _sl(effectThread->mLock);
-            moveEffectChain_l(sessionId, effectThread, thread, true);
+            if (moveEffectChain_l(sessionId, effectThread, thread) == NO_ERROR) {
+                effectThreadId = thread->id();
+                effectIds = thread->getEffectIds_l(sessionId);
+            }
         }
 
         // Look for sync events awaiting for a session to be used.
@@ -808,12 +902,18 @@
         goto Exit;
     }
 
+    // effectThreadId is not NONE if an effect chain corresponding to the track session
+    // was found on another thread and must be moved on this thread
+    if (effectThreadId != AUDIO_IO_HANDLE_NONE) {
+        AudioSystem::moveEffectsToIo(effectIds, effectThreadId);
+    }
+
     // return handle to client
     trackHandle = new TrackHandle(track);
 
 Exit:
     if (lStatus != NO_ERROR && output.outputId != AUDIO_IO_HANDLE_NONE) {
-        AudioSystem::releaseOutput(output.outputId, streamType, sessionId);
+        AudioSystem::releaseOutput(portId);
     }
     *status = lStatus;
     return trackHandle;
@@ -917,6 +1017,40 @@
     return NO_ERROR;
 }
 
+status_t AudioFlinger::setMasterBalance(float balance)
+{
+    status_t ret = initCheck();
+    if (ret != NO_ERROR) {
+        return ret;
+    }
+
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+
+    // check range
+    if (isnan(balance) || fabs(balance) > 1.f) {
+        return BAD_VALUE;
+    }
+
+    Mutex::Autolock _l(mLock);
+
+    // short cut.
+    if (mMasterBalance == balance) return NO_ERROR;
+
+    mMasterBalance = balance;
+
+    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
+        if (mPlaybackThreads.valueAt(i)->isDuplicating()) {
+            continue;
+        }
+        mPlaybackThreads.valueAt(i)->setMasterBalance(balance);
+    }
+
+    return NO_ERROR;
+}
+
 status_t AudioFlinger::setMode(audio_mode_t mode)
 {
     status_t ret = initCheck();
@@ -1056,6 +1190,13 @@
     return masterVolume_l();
 }
 
+status_t AudioFlinger::getMasterBalance(float *balance) const
+{
+    Mutex::Autolock _l(mLock);
+    *balance = getMasterBalance_l();
+    return NO_ERROR; // if called through binder, may return a transactional error
+}
+
 bool AudioFlinger::masterMute() const
 {
     Mutex::Autolock _l(mLock);
@@ -1067,6 +1208,11 @@
     return mMasterVolume;
 }
 
+float AudioFlinger::getMasterBalance_l() const
+{
+    return mMasterBalance;
+}
+
 bool AudioFlinger::masterMute_l() const
 {
     return mMasterMute;
@@ -1078,9 +1224,9 @@
         ALOGW("checkStreamType() invalid stream %d", stream);
         return BAD_VALUE;
     }
-    pid_t caller = IPCThreadState::self()->getCallingPid();
-    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT && caller != getpid_cached) {
-        ALOGW("checkStreamType() pid %d cannot use internal stream type %d", caller, stream);
+    const uid_t callerUid = IPCThreadState::self()->getCallingUid();
+    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT && !isAudioServerUid(callerUid)) {
+        ALOGW("checkStreamType() uid %d cannot use internal stream type %d", callerUid, stream);
         return PERMISSION_DENIED;
     }
 
@@ -1102,7 +1248,8 @@
     if (output == AUDIO_IO_HANDLE_NONE) {
         return BAD_VALUE;
     }
-    ALOG_ASSERT(stream != AUDIO_STREAM_PATCH, "attempt to change AUDIO_STREAM_PATCH volume");
+    LOG_ALWAYS_FATAL_IF(stream == AUDIO_STREAM_PATCH && value != 1.0f,
+                        "AUDIO_STREAM_PATCH must have full scale volume");
 
     AutoMutex lock(mLock);
     VolumeInterface *volumeInterface = getVolumeInterface_l(output);
@@ -1180,6 +1327,23 @@
     }
 }
 
+// forwardAudioHwSyncToDownstreamPatches_l() must be called with AudioFlinger::mLock held
+void AudioFlinger::forwardParametersToDownstreamPatches_l(
+        audio_io_handle_t upStream, const String8& keyValuePairs,
+        std::function<bool(const sp<PlaybackThread>&)> useThread)
+{
+    std::vector<PatchPanel::SoftwarePatch> swPatches;
+    if (mPatchPanel.getDownstreamSoftwarePatches(upStream, &swPatches) != OK) return;
+    ALOGV_IF(!swPatches.empty(), "%s found %zu downstream patches for stream ID %d",
+            __func__, swPatches.size(), upStream);
+    for (const auto& swPatch : swPatches) {
+        sp<PlaybackThread> downStream = checkPlaybackThread_l(swPatch.getPlaybackThreadHandle());
+        if (downStream != NULL && (useThread == nullptr || useThread(downStream))) {
+            downStream->setParameters(keyValuePairs);
+        }
+    }
+}
+
 // Filter reserved keys from setParameters() before forwarding to audio HAL or acting upon.
 // Some keys are used for audio routing and audio path configuration and should be reserved for use
 // by audio policy and audio flinger for functional, privacy and security reasons.
@@ -1200,23 +1364,39 @@
         String8(AudioParameter::keyStreamSupportedSamplingRates),
     };
 
-    // multiuser friendly app ID check for requests coming from audioserver
-    if (multiuser_get_app_id(callingUid) == AID_AUDIOSERVER) {
-        return;
+    if (isAudioServerUid(callingUid)) {
+        return; // no need to filter if audioserver.
     }
 
     AudioParameter param = AudioParameter(keyValuePairs);
     String8 value;
+    AudioParameter rejectedParam;
     for (auto& key : kReservedParameters) {
         if (param.get(key, value) == NO_ERROR) {
-            ALOGW("%s: filtering key %s value %s from uid %d",
-                  __func__, key.string(), value.string(), callingUid);
+            rejectedParam.add(key, value);
             param.remove(key);
         }
     }
+    logFilteredParameters(param.size() + rejectedParam.size(), keyValuePairs,
+                          rejectedParam.size(), rejectedParam.toString(), callingUid);
     keyValuePairs = param.toString();
 }
 
+void AudioFlinger::logFilteredParameters(size_t originalKVPSize, const String8& originalKVPs,
+                                         size_t rejectedKVPSize, const String8& rejectedKVPs,
+                                         uid_t callingUid) {
+    auto prefix = String8::format("UID %5d", callingUid);
+    auto suffix = String8::format("%zu KVP received: %s", originalKVPSize, originalKVPs.c_str());
+    if (rejectedKVPSize != 0) {
+        auto error = String8::format("%zu KVP rejected: %s", rejectedKVPSize, rejectedKVPs.c_str());
+        ALOGW("%s: %s, %s, %s", __func__, prefix.c_str(), error.c_str(), suffix.c_str());
+        mRejectedSetParameterLog.log("%s, %s, %s", prefix.c_str(), error.c_str(), suffix.c_str());
+    } else {
+        auto& logger = (isServiceUid(callingUid) ? mSystemSetParameterLog : mAppSetParameterLog);
+        logger.log("%s, %s", prefix.c_str(), suffix.c_str());
+    }
+}
+
 status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)
 {
     ALOGV("setParameters(): io %d, keyvalue %s, calling pid %d calling uid %d",
@@ -1296,7 +1476,9 @@
         }
     }
     if (thread != 0) {
-        return thread->setParameters(filteredKeyValuePairs);
+        status_t result = thread->setParameters(filteredKeyValuePairs);
+        forwardParametersToDownstreamPatches_l(thread->id(), filteredKeyValuePairs);
+        return result;
     }
     return BAD_VALUE;
 }
@@ -1472,30 +1654,36 @@
 
 void AudioFlinger::removeNotificationClient(pid_t pid)
 {
-    Mutex::Autolock _l(mLock);
+    std::vector< sp<AudioFlinger::EffectModule> > removedEffects;
     {
-        Mutex::Autolock _cl(mClientLock);
-        mNotificationClients.removeItem(pid);
-    }
+        Mutex::Autolock _l(mLock);
+        {
+            Mutex::Autolock _cl(mClientLock);
+            mNotificationClients.removeItem(pid);
+        }
 
-    ALOGV("%d died, releasing its sessions", pid);
-    size_t num = mAudioSessionRefs.size();
-    bool removed = false;
-    for (size_t i = 0; i < num; ) {
-        AudioSessionRef *ref = mAudioSessionRefs.itemAt(i);
-        ALOGV(" pid %d @ %zu", ref->mPid, i);
-        if (ref->mPid == pid) {
-            ALOGV(" removing entry for pid %d session %d", pid, ref->mSessionid);
-            mAudioSessionRefs.removeAt(i);
-            delete ref;
-            removed = true;
-            num--;
-        } else {
-            i++;
+        ALOGV("%d died, releasing its sessions", pid);
+        size_t num = mAudioSessionRefs.size();
+        bool removed = false;
+        for (size_t i = 0; i < num; ) {
+            AudioSessionRef *ref = mAudioSessionRefs.itemAt(i);
+            ALOGV(" pid %d @ %zu", ref->mPid, i);
+            if (ref->mPid == pid) {
+                ALOGV(" removing entry for pid %d session %d", pid, ref->mSessionid);
+                mAudioSessionRefs.removeAt(i);
+                delete ref;
+                removed = true;
+                num--;
+            } else {
+                i++;
+            }
+        }
+        if (removed) {
+            removedEffects = purgeStaleEffects_l();
         }
     }
-    if (removed) {
-        purgeStaleEffects_l();
+    for (auto& effect : removedEffects) {
+        effect->updatePolicyState();
     }
 }
 
@@ -1521,18 +1709,35 @@
 }
 
 // getEffectThread_l() must be called with AudioFlinger::mLock held
-sp<AudioFlinger::PlaybackThread> AudioFlinger::getEffectThread_l(audio_session_t sessionId,
-        int EffectId)
+sp<AudioFlinger::ThreadBase> AudioFlinger::getEffectThread_l(audio_session_t sessionId,
+        int effectId)
 {
-    sp<PlaybackThread> thread;
+    sp<ThreadBase> thread;
 
     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
-        if (mPlaybackThreads.valueAt(i)->getEffect(sessionId, EffectId) != 0) {
+        if (mPlaybackThreads.valueAt(i)->getEffect(sessionId, effectId) != 0) {
             ALOG_ASSERT(thread == 0);
             thread = mPlaybackThreads.valueAt(i);
         }
     }
-
+    if (thread != nullptr) {
+        return thread;
+    }
+    for (size_t i = 0; i < mRecordThreads.size(); i++) {
+        if (mRecordThreads.valueAt(i)->getEffect(sessionId, effectId) != 0) {
+            ALOG_ASSERT(thread == 0);
+            thread = mRecordThreads.valueAt(i);
+        }
+    }
+    if (thread != nullptr) {
+        return thread;
+    }
+    for (size_t i = 0; i < mMmapThreads.size(); i++) {
+        if (mMmapThreads.valueAt(i)->getEffect(sessionId, effectId) != 0) {
+            ALOG_ASSERT(thread == 0);
+            thread = mMmapThreads.valueAt(i);
+        }
+    }
     return thread;
 }
 
@@ -1636,7 +1841,7 @@
     bool updatePid = (input.clientInfo.clientPid == -1);
     const uid_t callingUid = IPCThreadState::self()->getCallingUid();
     uid_t clientUid = input.clientInfo.clientUid;
-    if (!isTrustedCallingUid(callingUid)) {
+    if (!isAudioServerOrMediaServerUid(callingUid)) {
         ALOGW_IF(clientUid != callingUid,
                 "%s uid %d tried to pass itself off as %d",
                 __FUNCTION__, callingUid, clientUid);
@@ -1644,8 +1849,8 @@
         updatePid = true;
     }
     pid_t clientPid = input.clientInfo.clientPid;
+    const pid_t callingPid = IPCThreadState::self()->getCallingPid();
     if (updatePid) {
-        const pid_t callingPid = IPCThreadState::self()->getCallingPid();
         ALOGW_IF(clientPid != -1 && clientPid != callingPid,
                  "%s uid %d pid %d tried to pass itself off as pid %d",
                  __func__, callingUid, callingPid, clientPid);
@@ -1694,6 +1899,7 @@
         portId = AUDIO_PORT_HANDLE_NONE;
     }
     lStatus = AudioSystem::getInputForAttr(&input.attr, &output.inputId,
+                                      input.riid,
                                       sessionId,
                                     // FIXME compare to AudioTrack
                                       clientPid,
@@ -1701,12 +1907,16 @@
                                       input.opPackageName,
                                       &input.config,
                                       output.flags, &output.selectedDeviceId, &portId);
+    if (lStatus != NO_ERROR) {
+        ALOGE("createRecord() getInputForAttr return error %d", lStatus);
+        goto Exit;
+    }
 
     {
         Mutex::Autolock _l(mLock);
         RecordThread *thread = checkRecordThread_l(output.inputId);
         if (thread == NULL) {
-            ALOGE("createRecord() checkRecordThread_l failed");
+            ALOGE("createRecord() checkRecordThread_l failed, input handle %d", output.inputId);
             lStatus = BAD_VALUE;
             goto Exit;
         }
@@ -1721,7 +1931,7 @@
                                                   input.config.format, input.config.channel_mask,
                                                   &output.frameCount, sessionId,
                                                   &output.notificationFrameCount,
-                                                  clientUid, &output.flags,
+                                                  callingPid, clientUid, &output.flags,
                                                   input.clientInfo.clientTid,
                                                   &lStatus, portId,
                                                   input.opPackageName);
@@ -1752,6 +1962,7 @@
 
     output.cblk = recordTrack->getCblk();
     output.buffers = recordTrack->getBuffers();
+    output.portId = portId;
 
     // return handle to client
     recordHandle = new RecordHandle(recordTrack);
@@ -1855,6 +2066,10 @@
 
         mHardwareStatus = AUDIO_HW_IDLE;
     }
+    if (strcmp(name, AUDIO_HARDWARE_MODULE_ID_MSD) == 0) {
+        // An MSD module is inserted before hardware modules in order to mix encoded streams.
+        flags = static_cast<AudioHwDevice::Flags>(flags | AudioHwDevice::AHWD_IS_INSERT);
+    }
 
     audio_module_handle_t handle = (audio_module_handle_t) nextUniqueId(AUDIO_UNIQUE_ID_USE_MODULE);
     mAudioHwDevs.add(handle, new AudioHwDevice(handle, name, dev, flags));
@@ -1886,7 +2101,7 @@
 status_t AudioFlinger::setLowRamDevice(bool isLowRamDevice, int64_t totalMemory)
 {
     uid_t uid = IPCThreadState::self()->getCallingUid();
-    if (uid != AID_SYSTEM) {
+    if (!isAudioServerOrSystemServerUid(uid)) {
         return PERMISSION_DENIED;
     }
     Mutex::Autolock _l(mLock);
@@ -1931,6 +2146,28 @@
     return mClientSharedHeapSize;
 }
 
+status_t AudioFlinger::setAudioPortConfig(const struct audio_port_config *config)
+{
+    ALOGV(__func__);
+
+    audio_module_handle_t module;
+    if (config->type == AUDIO_PORT_TYPE_DEVICE) {
+        module = config->ext.device.hw_module;
+    } else {
+        module = config->ext.mix.hw_module;
+    }
+
+    Mutex::Autolock _l(mLock);
+    ssize_t index = mAudioHwDevs.indexOfKey(module);
+    if (index < 0) {
+        ALOGW("%s() bad hw module %d", __func__, module);
+        return BAD_VALUE;
+    }
+
+    AudioHwDevice *audioHwDevice = mAudioHwDevs.valueAt(index);
+    return audioHwDevice->hwDevice()->setAudioPortConfig(config);
+}
+
 audio_hw_sync_t AudioFlinger::getAudioHwSyncForSession(audio_session_t sessionId)
 {
     Mutex::Autolock _l(mLock);
@@ -1976,7 +2213,10 @@
         if (sessions & ThreadBase::TRACK_SESSION) {
             AudioParameter param = AudioParameter();
             param.addInt(String8(AudioParameter::keyStreamHwAvSync), value);
-            thread->setParameters(param.toString());
+            String8 keyValuePairs = param.toString();
+            thread->setParameters(keyValuePairs);
+            forwardParametersToDownstreamPatches_l(thread->id(), keyValuePairs,
+                    [](const sp<PlaybackThread>& thread) { return thread->usesHwAvSync(); });
             break;
         }
     }
@@ -2022,7 +2262,10 @@
         ALOGV("setAudioHwSyncForSession_l found ID %d for session %d", syncId, sessionId);
         AudioParameter param = AudioParameter();
         param.addInt(String8(AudioParameter::keyStreamHwAvSync), syncId);
-        thread->setParameters(param.toString());
+        String8 keyValuePairs = param.toString();
+        thread->setParameters(keyValuePairs);
+        forwardParametersToDownstreamPatches_l(thread->id(), keyValuePairs,
+                [](const sp<PlaybackThread>& thread) { return thread->usesHwAvSync(); });
     }
 }
 
@@ -2112,6 +2355,7 @@
                       *output, thread.get());
             }
             mPlaybackThreads.add(*output, thread);
+            mPatchPanel.notifyStreamOpened(outHwDev, *output);
             return thread;
         }
     }
@@ -2210,6 +2454,8 @@
         if (playbackThread != NULL) {
             ALOGV("closeOutput() %d", output);
 
+            dumpToThreadLog_l(playbackThread);
+
             if (playbackThread->type() == ThreadBase::MIXER) {
                 for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
                     if (mPlaybackThreads.valueAt(i)->isDuplicating()) {
@@ -2232,7 +2478,7 @@
                     Vector< sp<EffectChain> > effectChains = playbackThread->getEffectChains_l();
                     for (size_t i = 0; i < effectChains.size(); i ++) {
                         moveEffectChain_l(effectChains[i]->sessionId(), playbackThread.get(),
-                                dstThread, true);
+                                dstThread);
                     }
                 }
             }
@@ -2241,12 +2487,14 @@
             if (mmapThread == 0) {
                 return BAD_VALUE;
             }
+            dumpToThreadLog_l(mmapThread);
             mMmapThreads.removeItem(output);
             ALOGD("closing mmapThread %p", mmapThread.get());
         }
         const sp<AudioIoDescriptor> ioDesc = new AudioIoDescriptor();
         ioDesc->mIoHandle = output;
         ioConfigChanged(AUDIO_OUTPUT_CLOSED, ioDesc);
+        mPatchPanel.notifyStreamClosed(output);
     }
     // The thread entity (active unit of execution) is no longer running here,
     // but the ThreadBase container still exists.
@@ -2275,7 +2523,7 @@
     delete out;
 }
 
-void AudioFlinger::closeOutputInternal_l(const sp<PlaybackThread>& thread)
+void AudioFlinger::closeThreadInternal_l(const sp<PlaybackThread>& thread)
 {
     mPlaybackThreads.removeItem(thread->mId);
     thread->exit();
@@ -2327,7 +2575,8 @@
         return BAD_VALUE;
     }
 
-    sp<ThreadBase> thread = openInput_l(module, input, config, *devices, address, source, flags);
+    sp<ThreadBase> thread = openInput_l(
+            module, input, config, *devices, address, source, flags, AUDIO_DEVICE_NONE, String8{});
 
     if (thread != 0) {
         // notify client processes of the new input creation
@@ -2343,7 +2592,9 @@
                                                          audio_devices_t devices,
                                                          const String8& address,
                                                          audio_source_t source,
-                                                         audio_input_flags_t flags)
+                                                         audio_input_flags_t flags,
+                                                         audio_devices_t outputDevice,
+                                                         const String8& outputDeviceAddress)
 {
     AudioHwDevice *inHwDev = findSuitableHwDev_l(module, devices);
     if (inHwDev == NULL) {
@@ -2351,6 +2602,9 @@
         return 0;
     }
 
+    // Some flags are specific to framework and must not leak to the HAL.
+    flags = static_cast<audio_input_flags_t>(flags & ~AUDIO_INPUT_FRAMEWORK_FLAGS);
+
     // Audio Policy can request a specific handle for hardware hotword.
     // The goal here is not to re-open an already opened input.
     // It is to use a pre-assigned I/O handle.
@@ -2369,7 +2623,8 @@
     sp<DeviceHalInterface> inHwHal = inHwDev->hwDevice();
     sp<StreamInHalInterface> inStream;
     status_t status = inHwHal->openInputStream(
-            *input, devices, &halconfig, flags, address.string(), source, &inStream);
+            *input, devices, &halconfig, flags, address.string(), source,
+            outputDevice, outputDeviceAddress, &inStream);
     ALOGV("openInput_l() openInputStream returned input %p, devices %#x, SamplingRate %d"
            ", Format %#x, Channels %#x, flags %#x, status %d addr %s",
             inStream.get(),
@@ -2392,7 +2647,8 @@
         ALOGV("openInput_l() reopening with proposed sampling rate and channel mask");
         inStream.clear();
         status = inHwHal->openInputStream(
-                *input, devices, &halconfig, flags, address.string(), source, &inStream);
+                *input, devices, &halconfig, flags, address.string(), source,
+                outputDevice, outputDeviceAddress, &inStream);
         // FIXME log this new status; HAL should not propose any further changes
     }
 
@@ -2408,55 +2664,6 @@
                     thread.get());
             return thread;
         } else {
-#ifdef TEE_SINK
-            // Try to re-use most recently used Pipe to archive a copy of input for dumpsys,
-            // or (re-)create if current Pipe is idle and does not match the new format
-            sp<NBAIO_Sink> teeSink;
-            enum {
-                TEE_SINK_NO,    // don't copy input
-                TEE_SINK_NEW,   // copy input using a new pipe
-                TEE_SINK_OLD,   // copy input using an existing pipe
-            } kind;
-            NBAIO_Format format = Format_from_SR_C(halconfig.sample_rate,
-                    audio_channel_count_from_in_mask(halconfig.channel_mask), halconfig.format);
-            if (!mTeeSinkInputEnabled) {
-                kind = TEE_SINK_NO;
-            } else if (!Format_isValid(format)) {
-                kind = TEE_SINK_NO;
-            } else if (mRecordTeeSink == 0) {
-                kind = TEE_SINK_NEW;
-            } else if (mRecordTeeSink->getStrongCount() != 1) {
-                kind = TEE_SINK_NO;
-            } else if (Format_isEqual(format, mRecordTeeSink->format())) {
-                kind = TEE_SINK_OLD;
-            } else {
-                kind = TEE_SINK_NEW;
-            }
-            switch (kind) {
-            case TEE_SINK_NEW: {
-                Pipe *pipe = new Pipe(mTeeSinkInputFrames, format);
-                size_t numCounterOffers = 0;
-                const NBAIO_Format offers[1] = {format};
-                ssize_t index = pipe->negotiate(offers, 1, NULL, numCounterOffers);
-                ALOG_ASSERT(index == 0);
-                PipeReader *pipeReader = new PipeReader(*pipe);
-                numCounterOffers = 0;
-                index = pipeReader->negotiate(offers, 1, NULL, numCounterOffers);
-                ALOG_ASSERT(index == 0);
-                mRecordTeeSink = pipe;
-                mRecordTeeSource = pipeReader;
-                teeSink = pipe;
-                }
-                break;
-            case TEE_SINK_OLD:
-                teeSink = mRecordTeeSink;
-                break;
-            case TEE_SINK_NO:
-            default:
-                break;
-            }
-#endif
-
             // Start record thread
             // RecordThread requires both input and output device indication to forward to audio
             // pre processing modules
@@ -2466,9 +2673,6 @@
                                       primaryOutputDevice_l(),
                                       devices,
                                       mSystemReady
-#ifdef TEE_SINK
-                                      , teeSink
-#endif
                                       );
             mRecordThreads.add(*input, thread);
             ALOGV("openInput_l() created record thread: ID %d thread %p", *input, thread.get());
@@ -2497,6 +2701,8 @@
         if (recordThread != 0) {
             ALOGV("closeInput() %d", input);
 
+            dumpToThreadLog_l(recordThread);
+
             // If we still have effect chains, it means that a client still holds a handle
             // on at least one effect. We must either move the chain to an existing thread with the
             // same session ID or put it aside in case a new record thread is opened for a
@@ -2539,6 +2745,7 @@
             if (mmapThread == 0) {
                 return BAD_VALUE;
             }
+            dumpToThreadLog_l(mmapThread);
             mMmapThreads.removeItem(input);
         }
         const sp<AudioIoDescriptor> ioDesc = new AudioIoDescriptor();
@@ -2568,7 +2775,7 @@
     delete in;
 }
 
-void AudioFlinger::closeInputInternal_l(const sp<RecordThread>& thread)
+void AudioFlinger::closeThreadInternal_l(const sp<RecordThread>& thread)
 {
     mRecordThreads.removeItem(thread->mId);
     closeInputFinish(thread);
@@ -2606,7 +2813,8 @@
     Mutex::Autolock _l(mLock);
     pid_t caller = IPCThreadState::self()->getCallingPid();
     ALOGV("acquiring %d from %d, for %d", audioSession, caller, pid);
-    if (pid != -1 && (caller == getpid_cached)) {
+    const uid_t callerUid = IPCThreadState::self()->getCallingUid();
+    if (pid != -1 && isAudioServerUid(callerUid)) { // check must match releaseAudioSessionId()
         caller = pid;
     }
 
@@ -2637,29 +2845,40 @@
 
 void AudioFlinger::releaseAudioSessionId(audio_session_t audioSession, pid_t pid)
 {
-    Mutex::Autolock _l(mLock);
-    pid_t caller = IPCThreadState::self()->getCallingPid();
-    ALOGV("releasing %d from %d for %d", audioSession, caller, pid);
-    if (pid != -1 && (caller == getpid_cached)) {
-        caller = pid;
-    }
-    size_t num = mAudioSessionRefs.size();
-    for (size_t i = 0; i < num; i++) {
-        AudioSessionRef *ref = mAudioSessionRefs.itemAt(i);
-        if (ref->mSessionid == audioSession && ref->mPid == caller) {
-            ref->mCnt--;
-            ALOGV(" decremented refcount to %d", ref->mCnt);
-            if (ref->mCnt == 0) {
-                mAudioSessionRefs.removeAt(i);
-                delete ref;
-                purgeStaleEffects_l();
-            }
-            return;
+    std::vector< sp<EffectModule> > removedEffects;
+    {
+        Mutex::Autolock _l(mLock);
+        pid_t caller = IPCThreadState::self()->getCallingPid();
+        ALOGV("releasing %d from %d for %d", audioSession, caller, pid);
+        const uid_t callerUid = IPCThreadState::self()->getCallingUid();
+        if (pid != -1 && isAudioServerUid(callerUid)) { // check must match acquireAudioSessionId()
+            caller = pid;
         }
+        size_t num = mAudioSessionRefs.size();
+        for (size_t i = 0; i < num; i++) {
+            AudioSessionRef *ref = mAudioSessionRefs.itemAt(i);
+            if (ref->mSessionid == audioSession && ref->mPid == caller) {
+                ref->mCnt--;
+                ALOGV(" decremented refcount to %d", ref->mCnt);
+                if (ref->mCnt == 0) {
+                    mAudioSessionRefs.removeAt(i);
+                    delete ref;
+                    std::vector< sp<EffectModule> > effects = purgeStaleEffects_l();
+                    removedEffects.insert(removedEffects.end(), effects.begin(), effects.end());
+                }
+                goto Exit;
+            }
+        }
+        // If the caller is audioserver it is likely that the session being released was acquired
+        // on behalf of a process not in notification clients and we ignore the warning.
+        ALOGW_IF(!isAudioServerUid(callerUid),
+                 "session id %d not found for pid %d", audioSession, caller);
     }
-    // If the caller is mediaserver it is likely that the session being released was acquired
-    // on behalf of a process not in notification clients and we ignore the warning.
-    ALOGW_IF(caller != getpid_cached, "session id %d not found for pid %d", audioSession, caller);
+
+Exit:
+    for (auto& effect : removedEffects) {
+        effect->updatePolicyState();
+    }
 }
 
 bool AudioFlinger::isSessionAcquired_l(audio_session_t audioSession)
@@ -2674,11 +2893,12 @@
     return false;
 }
 
-void AudioFlinger::purgeStaleEffects_l() {
+std::vector<sp<AudioFlinger::EffectModule>> AudioFlinger::purgeStaleEffects_l() {
 
     ALOGV("purging stale effects");
 
     Vector< sp<EffectChain> > chains;
+    std::vector< sp<EffectModule> > removedEffects;
 
     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
         sp<PlaybackThread> t = mPlaybackThreads.valueAt(i);
@@ -2690,6 +2910,7 @@
             }
         }
     }
+
     for (size_t i = 0; i < mRecordThreads.size(); i++) {
         sp<RecordThread> t = mRecordThreads.valueAt(i);
         Mutex::Autolock _l(t->mLock);
@@ -2699,6 +2920,15 @@
         }
     }
 
+    for (size_t i = 0; i < mMmapThreads.size(); i++) {
+        sp<MmapThread> t = mMmapThreads.valueAt(i);
+        Mutex::Autolock _l(t->mLock);
+        for (size_t j = 0; j < t->mEffectChains.size(); j++) {
+            sp<EffectChain> ec = t->mEffectChains[j];
+            chains.push(ec);
+        }
+    }
+
     for (size_t i = 0; i < chains.size(); i++) {
         sp<EffectChain> ec = chains[i];
         int sessionid = ec->sessionId();
@@ -2727,11 +2957,22 @@
                 if (effect->purgeHandles()) {
                     t->checkSuspendOnEffectEnabled_l(effect, false, effect->sessionId());
                 }
-                AudioSystem::unregisterEffect(effect->id());
+                removedEffects.push_back(effect);
             }
         }
     }
-    return;
+    return removedEffects;
+}
+
+// dumpToThreadLog_l() must be called with AudioFlinger::mLock held
+void AudioFlinger::dumpToThreadLog_l(const sp<ThreadBase> &thread)
+{
+    audio_utils::FdToString fdToString;
+    const int fd = fdToString.fd();
+    if (fd >= 0) {
+        thread->dump(fd, {} /* args */);
+        mThreadLog.logs(-1 /* time */, fdToString.getStringAndClose());
+    }
 }
 
 // checkThread_l() must be called with AudioFlinger::mLock held
@@ -2939,16 +3180,74 @@
 }
 
 status_t AudioFlinger::getEffectDescriptor(const effect_uuid_t *pUuid,
-        effect_descriptor_t *descriptor) const
+                                           const effect_uuid_t *pTypeUuid,
+                                           uint32_t preferredTypeFlag,
+                                           effect_descriptor_t *descriptor) const
 {
+    if (pUuid == NULL || pTypeUuid == NULL || descriptor == NULL) {
+        return BAD_VALUE;
+    }
+
     Mutex::Autolock _l(mLock);
-    if (mEffectsFactoryHal.get()) {
-        return mEffectsFactoryHal->getDescriptor(pUuid, descriptor);
-    } else {
+
+    if (!mEffectsFactoryHal.get()) {
         return -ENODEV;
     }
-}
 
+    status_t status = NO_ERROR;
+    if (!EffectsFactoryHalInterface::isNullUuid(pUuid)) {
+        // If uuid is specified, request effect descriptor from that.
+        status = mEffectsFactoryHal->getDescriptor(pUuid, descriptor);
+    } else if (!EffectsFactoryHalInterface::isNullUuid(pTypeUuid)) {
+        // If uuid is not specified, look for an available implementation
+        // of the required type instead.
+
+        // Use a temporary descriptor to avoid modifying |descriptor| in the failure case.
+        effect_descriptor_t desc;
+        desc.flags = 0; // prevent compiler warning
+
+        uint32_t numEffects = 0;
+        status = mEffectsFactoryHal->queryNumberEffects(&numEffects);
+        if (status < 0) {
+            ALOGW("getEffectDescriptor() error %d from FactoryHal queryNumberEffects", status);
+            return status;
+        }
+
+        bool found = false;
+        for (uint32_t i = 0; i < numEffects; i++) {
+            status = mEffectsFactoryHal->getDescriptor(i, &desc);
+            if (status < 0) {
+                ALOGW("getEffectDescriptor() error %d from FactoryHal getDescriptor", status);
+                continue;
+            }
+            if (memcmp(&desc.type, pTypeUuid, sizeof(effect_uuid_t)) == 0) {
+                // If matching type found save effect descriptor.
+                found = true;
+                *descriptor = desc;
+
+                // If there's no preferred flag or this descriptor matches the preferred
+                // flag, success! If this descriptor doesn't match the preferred
+                // flag, continue enumeration in case a better matching version of this
+                // effect type is available. Note that this means if no effect with a
+                // correct flag is found, the descriptor returned will correspond to the
+                // last effect that at least had a matching type uuid (if any).
+                if (preferredTypeFlag == EFFECT_FLAG_TYPE_MASK ||
+                    (desc.flags & EFFECT_FLAG_TYPE_MASK) == preferredTypeFlag) {
+                    break;
+                }
+            }
+        }
+
+        if (!found) {
+            status = NAME_NOT_FOUND;
+            ALOGW("getEffectDescriptor(): Effect not found by type.");
+        }
+    } else {
+        status = BAD_VALUE;
+        ALOGE("getEffectDescriptor(): Either uuid or type uuid must be non-null UUIDs.");
+    }
+    return status;
+}
 
 sp<IEffect> AudioFlinger::createEffect(
         effect_descriptor_t *pDesc,
@@ -2967,7 +3266,7 @@
     effect_descriptor_t desc;
 
     const uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    if (pid == -1 || !isTrustedCallingUid(callingUid)) {
+    if (pid == -1 || !isAudioServerOrMediaServerUid(callingUid)) {
         const pid_t callingPid = IPCThreadState::self()->getCallingPid();
         ALOGW_IF(pid != -1 && pid != callingPid,
                  "%s uid %d pid %d tried to pass itself off as pid %d",
@@ -2983,84 +3282,55 @@
         goto Exit;
     }
 
-    // check audio settings permission for global effects
-    if (sessionId == AUDIO_SESSION_OUTPUT_MIX && !settingsAllowed()) {
-        lStatus = PERMISSION_DENIED;
-        goto Exit;
-    }
-
-    // Session AUDIO_SESSION_OUTPUT_STAGE is reserved for output stage effects
-    // that can only be created by audio policy manager (running in same process)
-    if (sessionId == AUDIO_SESSION_OUTPUT_STAGE && getpid_cached != pid) {
-        lStatus = PERMISSION_DENIED;
-        goto Exit;
-    }
-
     if (mEffectsFactoryHal == 0) {
+        ALOGE("%s: no effects factory hal", __func__);
         lStatus = NO_INIT;
         goto Exit;
     }
 
-    {
-        Mutex::Autolock _l(mLock);
-
-        if (!EffectsFactoryHalInterface::isNullUuid(&pDesc->uuid)) {
-            // if uuid is specified, request effect descriptor
-            lStatus = mEffectsFactoryHal->getDescriptor(&pDesc->uuid, &desc);
-            if (lStatus < 0) {
-                ALOGW("createEffect() error %d from EffectGetDescriptor", lStatus);
-                goto Exit;
-            }
-        } else {
-            // if uuid is not specified, look for an available implementation
-            // of the required type in effect factory
-            if (EffectsFactoryHalInterface::isNullUuid(&pDesc->type)) {
-                ALOGW("createEffect() no effect type");
-                lStatus = BAD_VALUE;
-                goto Exit;
-            }
-            uint32_t numEffects = 0;
-            effect_descriptor_t d;
-            d.flags = 0; // prevent compiler warning
-            bool found = false;
-
-            lStatus = mEffectsFactoryHal->queryNumberEffects(&numEffects);
-            if (lStatus < 0) {
-                ALOGW("createEffect() error %d from EffectQueryNumberEffects", lStatus);
-                goto Exit;
-            }
-            for (uint32_t i = 0; i < numEffects; i++) {
-                lStatus = mEffectsFactoryHal->getDescriptor(i, &desc);
-                if (lStatus < 0) {
-                    ALOGW("createEffect() error %d from EffectQueryEffect", lStatus);
-                    continue;
-                }
-                if (memcmp(&desc.type, &pDesc->type, sizeof(effect_uuid_t)) == 0) {
-                    // If matching type found save effect descriptor. If the session is
-                    // 0 and the effect is not auxiliary, continue enumeration in case
-                    // an auxiliary version of this effect type is available
-                    found = true;
-                    d = desc;
-                    if (sessionId != AUDIO_SESSION_OUTPUT_MIX ||
-                            (desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
-                        break;
-                    }
-                }
-            }
-            if (!found) {
-                lStatus = BAD_VALUE;
-                ALOGW("createEffect() effect not found");
-                goto Exit;
-            }
-            // For same effect type, chose auxiliary version over insert version if
-            // connect to output mix (Compliance to OpenSL ES)
-            if (sessionId == AUDIO_SESSION_OUTPUT_MIX &&
-                    (d.flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_AUXILIARY) {
-                desc = d;
-            }
+    // check audio settings permission for global effects
+    if (sessionId == AUDIO_SESSION_OUTPUT_MIX) {
+        if (!settingsAllowed()) {
+            ALOGE("%s: no permission for AUDIO_SESSION_OUTPUT_MIX", __func__);
+            lStatus = PERMISSION_DENIED;
+            goto Exit;
         }
+    } else if (sessionId == AUDIO_SESSION_OUTPUT_STAGE) {
+        if (!isAudioServerUid(callingUid)) {
+            ALOGE("%s: only APM can create using AUDIO_SESSION_OUTPUT_STAGE", __func__);
+            lStatus = PERMISSION_DENIED;
+            goto Exit;
+        }
+
+        if (io == AUDIO_IO_HANDLE_NONE) {
+            ALOGE("%s: APM must specify output when using AUDIO_SESSION_OUTPUT_STAGE", __func__);
+            lStatus = BAD_VALUE;
+            goto Exit;
+        }
+    } else {
+        // general sessionId.
+
+        if (audio_unique_id_get_use(sessionId) != AUDIO_UNIQUE_ID_USE_SESSION) {
+            ALOGE("%s: invalid sessionId %d", __func__, sessionId);
+            lStatus = BAD_VALUE;
+            goto Exit;
+        }
+
+        // TODO: should we check if the callingUid (limited to pid) is in mAudioSessionRefs
+        // to prevent creating an effect when one doesn't actually have track with that session?
     }
+
     {
+        // Get the full effect descriptor from the uuid/type.
+        // If the session is the output mix, prefer an auxiliary effect,
+        // otherwise no preference.
+        uint32_t preferredType = (sessionId == AUDIO_SESSION_OUTPUT_MIX ?
+                                  EFFECT_FLAG_TYPE_AUXILIARY : EFFECT_FLAG_TYPE_MASK);
+        lStatus = getEffectDescriptor(&pDesc->uuid, &pDesc->type, preferredType, &desc);
+        if (lStatus < 0) {
+            ALOGW("createEffect() error %d from getEffectDescriptor", lStatus);
+            goto Exit;
+        }
 
         // Do not allow auxiliary effects on a session different from 0 (output mix)
         if (sessionId != AUDIO_SESSION_OUTPUT_MIX &&
@@ -3093,41 +3363,36 @@
         // output threads.
         // If output is 0 here, sessionId is neither SESSION_OUTPUT_STAGE nor SESSION_OUTPUT_MIX
         // because of code checking output when entering the function.
-        // Note: io is never 0 when creating an effect on an input
+        // Note: io is never AUDIO_IO_HANDLE_NONE when creating an effect on an input by APM.
+        // An AudioEffect created from the Java API will have io as AUDIO_IO_HANDLE_NONE.
         if (io == AUDIO_IO_HANDLE_NONE) {
-            if (sessionId == AUDIO_SESSION_OUTPUT_STAGE) {
-                // output must be specified by AudioPolicyManager when using session
-                // AUDIO_SESSION_OUTPUT_STAGE
-                lStatus = BAD_VALUE;
+            // look for the thread where the specified audio session is present
+            io = findIoHandleBySessionId_l(sessionId, mPlaybackThreads);
+            if (io == AUDIO_IO_HANDLE_NONE) {
+                io = findIoHandleBySessionId_l(sessionId, mRecordThreads);
+            }
+            if (io == AUDIO_IO_HANDLE_NONE) {
+                io = findIoHandleBySessionId_l(sessionId, mMmapThreads);
+            }
+
+            // If you wish to create a Record preprocessing AudioEffect in Java,
+            // you MUST create an AudioRecord first and keep it alive so it is picked up above.
+            // Otherwise it will fail when created on a Playback thread by legacy
+            // handling below.  Ditto with Mmap, the associated Mmap track must be created
+            // before creating the AudioEffect or the io handle must be specified.
+            //
+            // Detect if the effect is created after an AudioRecord is destroyed.
+            if (getOrphanEffectChain_l(sessionId).get() != nullptr) {
+                ALOGE("%s: effect %s with no specified io handle is denied because the AudioRecord"
+                        " for session %d no longer exists",
+                         __func__, desc.name, sessionId);
+                lStatus = PERMISSION_DENIED;
                 goto Exit;
             }
-            // look for the thread where the specified audio session is present
-            for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
-                uint32_t sessionType = mPlaybackThreads.valueAt(i)->hasAudioSession(sessionId);
-                if (sessionType != 0) {
-                    io = mPlaybackThreads.keyAt(i);
-                    // thread with same effect session is preferable
-                    if ((sessionType & ThreadBase::EFFECT_SESSION) != 0) {
-                        break;
-                    }
-                }
-            }
-            if (io == AUDIO_IO_HANDLE_NONE) {
-                for (size_t i = 0; i < mRecordThreads.size(); i++) {
-                    if (mRecordThreads.valueAt(i)->hasAudioSession(sessionId) != 0) {
-                        io = mRecordThreads.keyAt(i);
-                        break;
-                    }
-                }
-            }
-            if (io == AUDIO_IO_HANDLE_NONE) {
-                for (size_t i = 0; i < mMmapThreads.size(); i++) {
-                    if (mMmapThreads.valueAt(i)->hasAudioSession(sessionId) != 0) {
-                        io = mMmapThreads.keyAt(i);
-                        break;
-                    }
-                }
-            }
+
+            // Legacy handling of creating an effect on an expired or made-up
+            // session id.  We think that it is a Playback effect.
+            //
             // If no output thread contains the requested session ID, default to
             // first output. The effect chain will be moved to the correct output
             // thread when a track with the same session ID is created
@@ -3188,8 +3453,16 @@
         }
     }
 
-    if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
-        // handle must be cleared outside lock.
+    if (lStatus == NO_ERROR || lStatus == ALREADY_EXISTS) {
+        // Check CPU and memory usage
+        sp<EffectModule> effect = handle->effect().promote();
+        if (effect != nullptr) {
+            status_t rStatus = effect->updatePolicyState();
+            if (rStatus != NO_ERROR) {
+                lStatus = rStatus;
+            }
+        }
+    } else {
         handle.clear();
     }
 
@@ -3221,14 +3494,30 @@
 
     Mutex::Autolock _dl(dstThread->mLock);
     Mutex::Autolock _sl(srcThread->mLock);
-    return moveEffectChain_l(sessionId, srcThread, dstThread, false);
+    return moveEffectChain_l(sessionId, srcThread, dstThread);
 }
 
+
+void AudioFlinger::setEffectSuspended(int effectId,
+                                audio_session_t sessionId,
+                                bool suspended)
+{
+    Mutex::Autolock _l(mLock);
+
+    sp<ThreadBase> thread = getEffectThread_l(sessionId, effectId);
+    if (thread == nullptr) {
+      return;
+    }
+    Mutex::Autolock _sl(thread->mLock);
+    sp<EffectModule> effect = thread->getEffect_l(sessionId, effectId);
+    thread->setEffectSuspended_l(&effect->desc().type, suspended, sessionId);
+}
+
+
 // moveEffectChain_l must be called with both srcThread and dstThread mLocks held
 status_t AudioFlinger::moveEffectChain_l(audio_session_t sessionId,
                                    AudioFlinger::PlaybackThread *srcThread,
-                                   AudioFlinger::PlaybackThread *dstThread,
-                                   bool reRegister)
+                                   AudioFlinger::PlaybackThread *dstThread)
 {
     ALOGV("moveEffectChain_l() session %d from thread %p to thread %p",
             sessionId, srcThread, dstThread);
@@ -3284,36 +3573,68 @@
             }
             strategy = dstChain->strategy();
         }
-        if (reRegister) {
-            AudioSystem::unregisterEffect(effect->id());
-            AudioSystem::registerEffect(&effect->desc(),
-                                        dstThread->id(),
-                                        strategy,
-                                        sessionId,
-                                        effect->id());
-            AudioSystem::setEffectEnabled(effect->id(), effect->isEnabled());
-        }
         effect = chain->getEffectFromId_l(0);
     }
 
     if (status != NO_ERROR) {
         for (size_t i = 0; i < removed.size(); i++) {
             srcThread->addEffect_l(removed[i]);
-            if (dstChain != 0 && reRegister) {
-                AudioSystem::unregisterEffect(removed[i]->id());
-                AudioSystem::registerEffect(&removed[i]->desc(),
-                                            srcThread->id(),
-                                            strategy,
-                                            sessionId,
-                                            removed[i]->id());
-                AudioSystem::setEffectEnabled(effect->id(), effect->isEnabled());
-            }
         }
     }
 
     return status;
 }
 
+status_t AudioFlinger::moveAuxEffectToIo(int EffectId,
+                                         const sp<PlaybackThread>& dstThread,
+                                         sp<PlaybackThread> *srcThread)
+{
+    status_t status = NO_ERROR;
+    Mutex::Autolock _l(mLock);
+    sp<PlaybackThread> thread =
+        static_cast<PlaybackThread *>(getEffectThread_l(AUDIO_SESSION_OUTPUT_MIX, EffectId).get());
+
+    if (EffectId != 0 && thread != 0 && dstThread != thread.get()) {
+        Mutex::Autolock _dl(dstThread->mLock);
+        Mutex::Autolock _sl(thread->mLock);
+        sp<EffectChain> srcChain = thread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
+        sp<EffectChain> dstChain;
+        if (srcChain == 0) {
+            return INVALID_OPERATION;
+        }
+
+        sp<EffectModule> effect = srcChain->getEffectFromId_l(EffectId);
+        if (effect == 0) {
+            return INVALID_OPERATION;
+        }
+        thread->removeEffect_l(effect);
+        status = dstThread->addEffect_l(effect);
+        if (status != NO_ERROR) {
+            thread->addEffect_l(effect);
+            status = INVALID_OPERATION;
+            goto Exit;
+        }
+
+        dstChain = effect->chain().promote();
+        if (dstChain == 0) {
+            thread->addEffect_l(effect);
+            status = INVALID_OPERATION;
+        }
+
+Exit:
+        // removeEffect_l() has stopped the effect if it was active so it must be restarted
+        if (effect->state() == EffectModule::ACTIVE ||
+            effect->state() == EffectModule::STOPPING) {
+            effect->start();
+        }
+    }
+
+    if (status == NO_ERROR && srcThread != nullptr) {
+        *srcThread = thread;
+    }
+    return status;
+}
+
 bool AudioFlinger::isNonOffloadableGlobalEffectEnabled_l()
 {
     if (mGlobalEffectEnableTime != 0 &&
@@ -3394,136 +3715,6 @@
 }
 
 
-struct Entry {
-#define TEE_MAX_FILENAME 32 // %Y%m%d%H%M%S_%d.wav = 4+2+2+2+2+2+1+1+4+1 = 21
-    char mFileName[TEE_MAX_FILENAME];
-};
-
-int comparEntry(const void *p1, const void *p2)
-{
-    return strcmp(((const Entry *) p1)->mFileName, ((const Entry *) p2)->mFileName);
-}
-
-#ifdef TEE_SINK
-void AudioFlinger::dumpTee(int fd, const sp<NBAIO_Source>& source, audio_io_handle_t id, char suffix)
-{
-    NBAIO_Source *teeSource = source.get();
-    if (teeSource != NULL) {
-        // .wav rotation
-        // There is a benign race condition if 2 threads call this simultaneously.
-        // They would both traverse the directory, but the result would simply be
-        // failures at unlink() which are ignored.  It's also unlikely since
-        // normally dumpsys is only done by bugreport or from the command line.
-        char teePath[PATH_MAX] = "/data/misc/audioserver";
-        size_t teePathLen = strlen(teePath);
-        DIR *dir = opendir(teePath);
-        teePath[teePathLen++] = '/';
-        if (dir != NULL) {
-#define TEE_MAX_SORT 20 // number of entries to sort
-#define TEE_MAX_KEEP 10 // number of entries to keep
-            struct Entry entries[TEE_MAX_SORT];
-            size_t entryCount = 0;
-            while (entryCount < TEE_MAX_SORT) {
-                errno = 0; // clear errno before readdir() to track potential errors.
-                const struct dirent *result = readdir(dir);
-                if (result == nullptr) {
-                    ALOGW_IF(errno != 0, "tee readdir() failure %s", strerror(errno));
-                    break;
-                }
-                // ignore non .wav file entries
-                const size_t nameLen = strlen(result->d_name);
-                if (nameLen <= 4 || nameLen >= TEE_MAX_FILENAME ||
-                        strcmp(&result->d_name[nameLen - 4], ".wav")) {
-                    continue;
-                }
-                (void)audio_utils_strlcpy(entries[entryCount++].mFileName, result->d_name);
-            }
-            (void) closedir(dir);
-            if (entryCount > TEE_MAX_KEEP) {
-                qsort(entries, entryCount, sizeof(Entry), comparEntry);
-                for (size_t i = 0; i < entryCount - TEE_MAX_KEEP; ++i) {
-                    strcpy(&teePath[teePathLen], entries[i].mFileName);
-                    (void) unlink(teePath);
-                }
-            }
-        } else {
-            if (fd >= 0) {
-                dprintf(fd, "unable to rotate tees in %.*s: %s\n", (int) teePathLen, teePath,
-                        strerror(errno));
-            }
-        }
-        char teeTime[16];
-        struct timeval tv;
-        gettimeofday(&tv, NULL);
-        struct tm tm;
-        localtime_r(&tv.tv_sec, &tm);
-        strftime(teeTime, sizeof(teeTime), "%Y%m%d%H%M%S", &tm);
-        snprintf(&teePath[teePathLen], sizeof(teePath) - teePathLen, "%s_%d_%c.wav", teeTime, id,
-                suffix);
-        // if 2 dumpsys are done within 1 second, and rotation didn't work, then discard 2nd
-        int teeFd = open(teePath, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW, S_IRUSR | S_IWUSR);
-        if (teeFd >= 0) {
-            // FIXME use libsndfile
-            char wavHeader[44];
-            memcpy(wavHeader,
-                "RIFF\0\0\0\0WAVEfmt \20\0\0\0\1\0\2\0\104\254\0\0\0\0\0\0\4\0\20\0data\0\0\0\0",
-                sizeof(wavHeader));
-            NBAIO_Format format = teeSource->format();
-            unsigned channelCount = Format_channelCount(format);
-            uint32_t sampleRate = Format_sampleRate(format);
-            size_t frameSize = Format_frameSize(format);
-            wavHeader[22] = channelCount;       // number of channels
-            wavHeader[24] = sampleRate;         // sample rate
-            wavHeader[25] = sampleRate >> 8;
-            wavHeader[32] = frameSize;          // block alignment
-            wavHeader[33] = frameSize >> 8;
-            write(teeFd, wavHeader, sizeof(wavHeader));
-            size_t total = 0;
-            bool firstRead = true;
-#define TEE_SINK_READ 1024                      // frames per I/O operation
-            void *buffer = malloc(TEE_SINK_READ * frameSize);
-            for (;;) {
-                size_t count = TEE_SINK_READ;
-                ssize_t actual = teeSource->read(buffer, count);
-                bool wasFirstRead = firstRead;
-                firstRead = false;
-                if (actual <= 0) {
-                    if (actual == (ssize_t) OVERRUN && wasFirstRead) {
-                        continue;
-                    }
-                    break;
-                }
-                ALOG_ASSERT(actual <= (ssize_t)count);
-                write(teeFd, buffer, actual * frameSize);
-                total += actual;
-            }
-            free(buffer);
-            lseek(teeFd, (off_t) 4, SEEK_SET);
-            uint32_t temp = 44 + total * frameSize - 8;
-            // FIXME not big-endian safe
-            write(teeFd, &temp, sizeof(temp));
-            lseek(teeFd, (off_t) 40, SEEK_SET);
-            temp =  total * frameSize;
-            // FIXME not big-endian safe
-            write(teeFd, &temp, sizeof(temp));
-            close(teeFd);
-            // TODO Should create file with temporary name and then rename to final if non-empty.
-            if (total > 0) {
-                if (fd >= 0) {
-                    dprintf(fd, "tee copied to %s\n", teePath);
-                }
-            } else {
-                unlink(teePath);
-            }
-        } else {
-            if (fd >= 0) {
-                dprintf(fd, "unable to create tee %s: %s\n", teePath, strerror(errno));
-            }
-        }
-    }
-}
-#endif
-
 // ----------------------------------------------------------------------------
 
 status_t AudioFlinger::onTransact(
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 567c5a9..72e669a 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -21,13 +21,19 @@
 #include "Configuration.h"
 #include <atomic>
 #include <mutex>
+#include <chrono>
 #include <deque>
 #include <map>
+#include <numeric>
+#include <optional>
+#include <set>
+#include <string>
 #include <vector>
 #include <stdint.h>
 #include <sys/types.h>
 #include <limits.h>
 
+#include <android/os/BnExternalVibrationController.h>
 #include <android-base/macros.h>
 
 #include <cutils/atomic.h>
@@ -64,7 +70,10 @@
 #include <media/LinearMap.h>
 #include <media/VolumeShaper.h>
 
+#include <audio_utils/clock.h>
+#include <audio_utils/FdToString.h>
 #include <audio_utils/SimpleLog.h>
+#include <audio_utils/TimestampVerifier.h>
 
 #include "FastCapture.h"
 #include "FastMixer.h"
@@ -73,6 +82,7 @@
 #include "AudioStreamOut.h"
 #include "SpdifStreamOut.h"
 #include "AudioHwDevice.h"
+#include "NBAIO_Tee.h"
 
 #include <powermanager/IPowerManager.h>
 
@@ -80,6 +90,8 @@
 #include <private/media/AudioEffectShared.h>
 #include <private/media/AudioTrackShared.h>
 
+#include <vibrator/ExternalVibration.h>
+
 #include "android/media/BnAudioRecord.h"
 
 namespace android {
@@ -133,6 +145,10 @@
     virtual     float       masterVolume() const;
     virtual     bool        masterMute() const;
 
+    // Balance value must be within -1.f (left only) to 1.f (right only) inclusive.
+                status_t    setMasterBalance(float balance) override;
+                status_t    getMasterBalance(float *balance) const override;
+
     virtual     status_t    setStreamVolume(audio_stream_type_t stream, float value,
                                             audio_io_handle_t output);
     virtual     status_t    setStreamMute(audio_stream_type_t stream, bool muted);
@@ -204,6 +220,8 @@
     virtual status_t queryEffect(uint32_t index, effect_descriptor_t *descriptor) const;
 
     virtual status_t getEffectDescriptor(const effect_uuid_t *pUuid,
+                                         const effect_uuid_t *pTypeUuid,
+                                         uint32_t preferredTypeFlag,
                                          effect_descriptor_t *descriptor) const;
 
     virtual sp<IEffect> createEffect(
@@ -221,6 +239,10 @@
     virtual status_t moveEffects(audio_session_t sessionId, audio_io_handle_t srcOutput,
                         audio_io_handle_t dstOutput);
 
+            void setEffectSuspended(int effectId,
+                                    audio_session_t sessionId,
+                                    bool suspended) override;
+
     virtual audio_module_handle_t loadHwModule(const char *name);
 
     virtual uint32_t getPrimaryOutputSamplingRate();
@@ -278,6 +300,9 @@
                             const sp<MmapStreamCallback>& callback,
                             sp<MmapStreamInterface>& interface,
                             audio_port_handle_t *handle);
+
+    static int onExternalVibrationStart(const sp<os::ExternalVibration>& externalVibration);
+    static void onExternalVibrationStop(const sp<os::ExternalVibration>& externalVibration);
 private:
     // FIXME The 400 is temporarily too high until a leak of writers in media.log is fixed.
     static const size_t kLogMemorySize = 400 * 1024;
@@ -348,7 +373,6 @@
 
     AudioHwDevice*          findSuitableHwDev_l(audio_module_handle_t module,
                                                 audio_devices_t devices);
-    void                    purgeStaleEffects_l();
 
     // Set kEnableExtendedChannels to true to enable greater than stereo output
     // for the MixerThread and device sink.  Number of channels allowed is
@@ -359,16 +383,17 @@
     static inline bool isValidPcmSinkChannelMask(audio_channel_mask_t channelMask) {
         switch (audio_channel_mask_get_representation(channelMask)) {
         case AUDIO_CHANNEL_REPRESENTATION_POSITION: {
-            uint32_t channelCount = FCC_2; // stereo is default
-            if (kEnableExtendedChannels) {
-                channelCount = audio_channel_count_from_out_mask(channelMask);
-                if (channelCount < FCC_2 // mono is not supported at this time
-                        || channelCount > AudioMixer::MAX_NUM_CHANNELS) {
-                    return false;
-                }
+            // Haptic channel mask is only applicable for channel position mask.
+            const uint32_t channelCount = audio_channel_count_from_out_mask(
+                    channelMask & ~AUDIO_CHANNEL_HAPTIC_ALL);
+            const uint32_t maxChannelCount = kEnableExtendedChannels
+                    ? AudioMixer::MAX_NUM_CHANNELS : FCC_2;
+            if (channelCount < FCC_2 // mono is not supported at this time
+                    || channelCount > maxChannelCount) {
+                return false;
             }
             // check that channelMask is the "canonical" one we expect for the channelCount.
-            return channelMask == audio_channel_out_mask_from_count(channelCount);
+            return audio_channel_position_mask_is_out_canonical(channelMask);
             }
         case AUDIO_CHANNEL_REPRESENTATION_INDEX:
             if (kEnableExtendedChannels) {
@@ -411,13 +436,17 @@
     static uint32_t         mScreenState;
 
     // Internal dump utilities.
-    static const int kDumpLockRetries = 50;
-    static const int kDumpLockSleepUs = 20000;
+    static const int kDumpLockTimeoutNs = 1 * NANOS_PER_SECOND;
     static bool dumpTryLock(Mutex& mutex);
     void dumpPermissionDenial(int fd, const Vector<String16>& args);
     void dumpClients(int fd, const Vector<String16>& args);
     void dumpInternals(int fd, const Vector<String16>& args);
 
+    SimpleLog mThreadLog{16}; // 16 Thread history limit
+
+    class ThreadBase;
+    void dumpToThreadLog_l(const sp<ThreadBase> &thread);
+
     // --- Client ---
     class Client : public RefBase {
     public:
@@ -504,6 +533,9 @@
     class EffectChain;
 
     struct AudioStreamIn;
+    struct TeePatch;
+    using TeePatches = std::vector<TeePatch>;
+
 
     struct  stream_type_t {
         stream_type_t()
@@ -530,6 +562,26 @@
 
 #include "PatchPanel.h"
 
+    // Find io handle by session id.
+    // Preference is given to an io handle with a matching effect chain to session id.
+    // If none found, AUDIO_IO_HANDLE_NONE is returned.
+    template <typename T>
+    static audio_io_handle_t findIoHandleBySessionId_l(
+            audio_session_t sessionId, const T& threads) {
+        audio_io_handle_t io = AUDIO_IO_HANDLE_NONE;
+
+        for (size_t i = 0; i < threads.size(); i++) {
+            const uint32_t sessionType = threads.valueAt(i)->hasAudioSession(sessionId);
+            if (sessionType != 0) {
+                io = threads.keyAt(i);
+                if ((sessionType & AudioFlinger::ThreadBase::EFFECT_SESSION) != 0) {
+                    break; // effect chain here.
+                }
+            }
+        }
+        return io;
+    }
+
     // server side of the client's IAudioTrack
     class TrackHandle : public android::BnAudioTrack {
     public:
@@ -542,6 +594,7 @@
         virtual void        pause();
         virtual status_t    attachAuxEffect(int effectId);
         virtual status_t    setParameters(const String8& keyValuePairs);
+        virtual status_t    selectPresentation(int presentationId, int programId);
         virtual media::VolumeShaper::Status applyVolumeShaper(
                 const sp<media::VolumeShaper::Configuration>& configuration,
                 const sp<media::VolumeShaper::Operation>& operation) override;
@@ -566,6 +619,10 @@
         virtual binder::Status   stop();
         virtual binder::Status   getActiveMicrophones(
                 std::vector<media::MicrophoneInfo>* activeMicrophones);
+        virtual binder::Status   setPreferredMicrophoneDirection(
+                int /*audio_microphone_direction_t*/ direction);
+        virtual binder::Status   setPreferredMicrophoneFieldDimension(float zoom);
+
     private:
         const sp<RecordThread::RecordTrack> mRecordTrack;
 
@@ -607,7 +664,9 @@
                                            audio_devices_t device,
                                            const String8& address,
                                            audio_source_t source,
-                                           audio_input_flags_t flags);
+                                           audio_input_flags_t flags,
+                                           audio_devices_t outputDevice,
+                                           const String8& outputDeviceAddress);
               sp<ThreadBase> openOutput_l(audio_module_handle_t module,
                                               audio_io_handle_t *output,
                                               audio_config_t *config,
@@ -640,8 +699,11 @@
 
               status_t moveEffectChain_l(audio_session_t sessionId,
                                      PlaybackThread *srcThread,
-                                     PlaybackThread *dstThread,
-                                     bool reRegister);
+                                     PlaybackThread *dstThread);
+
+              status_t moveAuxEffectToIo(int EffectId,
+                                         const sp<PlaybackThread>& dstThread,
+                                         sp<PlaybackThread> *srcThread);
 
               // return thread associated with primary hardware device, or NULL
               PlaybackThread *primaryPlaybackThread_l() const;
@@ -650,7 +712,7 @@
               // return the playback thread with smallest HAL buffer size, and prefer fast
               PlaybackThread *fastPlaybackThread_l() const;
 
-              sp<PlaybackThread> getEffectThread_l(audio_session_t sessionId, int EffectId);
+              sp<ThreadBase> getEffectThread_l(audio_session_t sessionId, int effectId);
 
 
                 void        removeClient_l(pid_t pid);
@@ -676,7 +738,12 @@
                 // Return true if the effect was found in mOrphanEffectChains, false otherwise.
                 bool            updateOrphanEffectChains(const sp<EffectModule>& effect);
 
+                std::vector< sp<EffectModule> > purgeStaleEffects_l();
+
                 void broacastParametersToRecordThreads_l(const String8& keyValuePairs);
+                void forwardParametersToDownstreamPatches_l(
+                        audio_io_handle_t upStream, const String8& keyValuePairs,
+                        std::function<bool(const sp<PlaybackThread>&)> useThread = nullptr);
 
     // AudioStreamIn is immutable, so their fields are const.
     // For emphasis, we could also make all pointers to them be "const *",
@@ -693,6 +760,11 @@
             audioHwDev(dev), stream(in), flags(flags) {}
     };
 
+    struct TeePatch {
+        sp<RecordThread::PatchRecord> patchRecord;
+        sp<PlaybackThread::PatchTrack> patchTrack;
+    };
+
     // for mAudioSessionRefs only
     struct AudioSessionRef {
         AudioSessionRef(audio_session_t sessionid, pid_t pid) :
@@ -754,6 +826,7 @@
                 // member variables below are protected by mLock
                 float                               mMasterVolume;
                 bool                                mMasterMute;
+                float                               mMasterBalance = 0.f;
                 // end of variables protected by mLock
 
                 DefaultKeyedVector< audio_io_handle_t, sp<RecordThread> >    mRecordThreads;
@@ -771,6 +844,7 @@
                 Vector<AudioSessionRef*> mAudioSessionRefs;
 
                 float       masterVolume_l() const;
+                float       getMasterBalance_l() const;
                 bool        masterMute_l() const;
                 audio_module_handle_t loadHwModule_l(const char *name);
 
@@ -793,44 +867,19 @@
 
     // for use from destructor
     status_t    closeOutput_nonvirtual(audio_io_handle_t output);
-    void        closeOutputInternal_l(const sp<PlaybackThread>& thread);
+    void        closeThreadInternal_l(const sp<PlaybackThread>& thread);
     status_t    closeInput_nonvirtual(audio_io_handle_t input);
-    void        closeInputInternal_l(const sp<RecordThread>& thread);
+    void        closeThreadInternal_l(const sp<RecordThread>& thread);
     void        setAudioHwSyncForSession_l(PlaybackThread *thread, audio_session_t sessionId);
 
     status_t    checkStreamType(audio_stream_type_t stream) const;
 
     void        filterReservedParameters(String8& keyValuePairs, uid_t callingUid);
-
-#ifdef TEE_SINK
-    // all record threads serially share a common tee sink, which is re-created on format change
-    sp<NBAIO_Sink>   mRecordTeeSink;
-    sp<NBAIO_Source> mRecordTeeSource;
-#endif
+    void        logFilteredParameters(size_t originalKVPSize, const String8& originalKVPs,
+                                      size_t rejectedKVPSize, const String8& rejectedKVPs,
+                                      uid_t callingUid);
 
 public:
-
-#ifdef TEE_SINK
-    // tee sink, if enabled by property, allows dumpsys to write most recent audio to .wav file
-    static void dumpTee(int fd, const sp<NBAIO_Source>& source, audio_io_handle_t id, char suffix);
-
-    // whether tee sink is enabled by property
-    static bool mTeeSinkInputEnabled;
-    static bool mTeeSinkOutputEnabled;
-    static bool mTeeSinkTrackEnabled;
-
-    // runtime configured size of each tee sink pipe, in frames
-    static size_t mTeeSinkInputFrames;
-    static size_t mTeeSinkOutputFrames;
-    static size_t mTeeSinkTrackFrames;
-
-    // compile-time default size of tee sink pipes, in frames
-    // 0x200000 stereo 16-bit PCM frames = 47.5 seconds at 44.1 kHz, 8 megabytes
-    static const size_t kTeeSinkInputFramesDefault = 0x200000;
-    static const size_t kTeeSinkOutputFramesDefault = 0x200000;
-    static const size_t kTeeSinkTrackFramesDefault = 0x200000;
-#endif
-
     // These methods read variables atomically without mLock,
     // though the variables are updated with mLock.
     bool    isLowRamDevice() const { return mIsLowRamDevice; }
@@ -845,10 +894,15 @@
 
     nsecs_t mGlobalEffectEnableTime;  // when a global effect was last enabled
 
-    sp<PatchPanel> mPatchPanel;
+    // protected by mLock
+    PatchPanel mPatchPanel;
     sp<EffectsFactoryHalInterface> mEffectsFactoryHal;
 
-    bool        mSystemReady;
+    bool       mSystemReady;
+
+    SimpleLog  mRejectedSetParameterLog;
+    SimpleLog  mAppSetParameterLog;
+    SimpleLog  mSystemSetParameterLog;
 };
 
 #undef INCLUDING_FROM_AUDIOFLINGER_H
diff --git a/services/audioflinger/AudioHwDevice.h b/services/audioflinger/AudioHwDevice.h
index eb826c6..d4299b0 100644
--- a/services/audioflinger/AudioHwDevice.h
+++ b/services/audioflinger/AudioHwDevice.h
@@ -35,6 +35,9 @@
     enum Flags {
         AHWD_CAN_SET_MASTER_VOLUME  = 0x1,
         AHWD_CAN_SET_MASTER_MUTE    = 0x2,
+        // Means that this isn't a terminal module, and software patches
+        // are used to transport audio data further.
+        AHWD_IS_INSERT              = 0x4,
     };
 
     AudioHwDevice(audio_module_handle_t handle,
@@ -55,6 +58,10 @@
         return (0 != (mFlags & AHWD_CAN_SET_MASTER_MUTE));
     }
 
+    bool isInsert() const {
+        return (0 != (mFlags & AHWD_IS_INSERT));
+    }
+
     audio_module_handle_t handle() const { return mHandle; }
     const char *moduleName() const { return mModuleName; }
     sp<DeviceHalInterface> hwDevice() const { return mHwDevice; }
diff --git a/services/audioflinger/AudioStreamOut.cpp b/services/audioflinger/AudioStreamOut.cpp
index 1d4b3fe..a60a5f2 100644
--- a/services/audioflinger/AudioStreamOut.cpp
+++ b/services/audioflinger/AudioStreamOut.cpp
@@ -66,8 +66,9 @@
     // Maintain a 64-bit render position using the 32-bit result from the HAL.
     // This delta calculation relies on the arithmetic overflow behavior
     // of integers. For example (100 - 0xFFFFFFF0) = 116.
-    uint32_t truncatedPosition = (uint32_t)mRenderPosition;
-    int32_t deltaHalPosition = (int32_t)(halPosition - truncatedPosition);
+    const uint32_t truncatedPosition = (uint32_t)mRenderPosition;
+    int32_t deltaHalPosition; // initialization not needed, overwitten by __builtin_sub_overflow()
+    (void) __builtin_sub_overflow(halPosition, truncatedPosition, &deltaHalPosition);
     if (deltaHalPosition > 0) {
         mRenderPosition += deltaHalPosition;
     }
diff --git a/services/audioflinger/BufLog.cpp b/services/audioflinger/BufLog.cpp
index ae96036..5f6aca0 100644
--- a/services/audioflinger/BufLog.cpp
+++ b/services/audioflinger/BufLog.cpp
@@ -115,7 +115,7 @@
         unsigned int samplingRate,
         size_t maxBytes = 0) : mId(id), mFormat(format), mChannels(channels),
                 mSamplingRate(samplingRate), mMaxBytes(maxBytes) {
-    mByteCount = 0l;
+    mByteCount = 0;
     mPaused = false;
     if (tag != NULL) {
         (void)audio_utils_strlcpy(mTag, tag);
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 2047dfd..3c4fbba 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -31,9 +31,9 @@
 #include <media/AudioEffect.h>
 #include <media/audiohal/EffectHalInterface.h>
 #include <media/audiohal/EffectsFactoryHalInterface.h>
+#include <mediautils/ServiceUtilities.h>
 
 #include "AudioFlinger.h"
-#include "ServiceUtilities.h"
 
 // ----------------------------------------------------------------------------
 
@@ -50,6 +50,8 @@
 #define ALOGVV(a...) do { } while(0)
 #endif
 
+#define DEFAULT_OUTPUT_SAMPLE_RATE 48000
+
 namespace android {
 
 // ----------------------------------------------------------------------------
@@ -166,6 +168,68 @@
     return status;
 }
 
+status_t AudioFlinger::EffectModule::updatePolicyState()
+{
+    status_t status = NO_ERROR;
+    bool doRegister = false;
+    bool registered = false;
+    bool doEnable = false;
+    bool enabled = false;
+    audio_io_handle_t io;
+    uint32_t strategy;
+
+    {
+        Mutex::Autolock _l(mLock);
+        // register effect when first handle is attached and unregister when last handle is removed
+        if (mPolicyRegistered != mHandles.size() > 0) {
+            doRegister = true;
+            mPolicyRegistered = mHandles.size() > 0;
+            if (mPolicyRegistered) {
+              sp <EffectChain> chain = mChain.promote();
+              sp <ThreadBase> thread = mThread.promote();
+
+              if (thread == nullptr || chain == nullptr) {
+                    return INVALID_OPERATION;
+                }
+                io = thread->id();
+                strategy = chain->strategy();
+            }
+        }
+        // enable effect when registered according to enable state requested by controlling handle
+        if (mHandles.size() > 0) {
+            EffectHandle *handle = controlHandle_l();
+            if (handle != nullptr && mPolicyEnabled != handle->enabled()) {
+                doEnable = true;
+                mPolicyEnabled = handle->enabled();
+            }
+        }
+        registered = mPolicyRegistered;
+        enabled = mPolicyEnabled;
+        mPolicyLock.lock();
+    }
+    ALOGV("%s name %s id %d session %d doRegister %d registered %d doEnable %d enabled %d",
+        __func__, mDescriptor.name, mId, mSessionId, doRegister, registered, doEnable, enabled);
+    if (doRegister) {
+        if (registered) {
+            status = AudioSystem::registerEffect(
+                &mDescriptor,
+                io,
+                strategy,
+                mSessionId,
+                mId);
+        } else {
+            status = AudioSystem::unregisterEffect(mId);
+        }
+    }
+    if (registered && doEnable) {
+        status = AudioSystem::setEffectEnabled(mId, enabled);
+    }
+    mPolicyLock.unlock();
+
+    return status;
+}
+
+
 ssize_t AudioFlinger::EffectModule::removeHandle(EffectHandle *handle)
 {
     Mutex::Autolock _l(mLock);
@@ -228,7 +292,6 @@
     Mutex::Autolock _l(mLock);
     ssize_t numHandles = removeHandle_l(handle);
     if ((numHandles == 0) && (!mPinned || unpinIfLast)) {
-        AudioSystem::unregisterEffect(mId);
         sp<AudioFlinger> af = mAudioFlinger.promote();
         if (af != 0) {
             mLock.unlock();
@@ -246,7 +309,7 @@
     switch (mState) {
     case RESTART:
         reset_l();
-        // FALL THROUGH
+        FALLTHROUGH_INTENDED;
 
     case STARTING:
         // clear auxiliary effect input buffer for next accumulation
@@ -263,7 +326,9 @@
         }
         break;
     case STOPPING:
-        if (stop_l() == NO_ERROR) {
+        // volume control for offload and direct threads must take effect immediately.
+        if (stop_l() == NO_ERROR
+            && !(isVolumeControl() && isOffloadedOrDirect())) {
             mDisableWaitCnt = mMaxDisableWaitCnt;
         } else {
             mDisableWaitCnt = 1; // will cause immediate transition to IDLE
@@ -305,8 +370,8 @@
     // input and output effect buffers without an intermediary effect process.
     // TODO: consider implementing channel conversion.
     const size_t safeInputOutputSampleCount =
-            inChannelCount != outChannelCount ? 0
-                    : outChannelCount * std::min(
+            mInChannelCountRequested != mOutChannelCountRequested ? 0
+                    : mOutChannelCountRequested * std::min(
                             mConfig.inputCfg.buffer.frameCount,
                             mConfig.outputCfg.buffer.frameCount);
     const auto accumulateInputToOutput = [this, safeInputOutputSampleCount]() {
@@ -476,7 +541,12 @@
         // accumulate input onto output
         sp<EffectChain> chain = mChain.promote();
         if (chain.get() != nullptr && chain->activeTrackCnt() != 0) {
-            accumulateInputToOutput();
+            // similar handling with data_bypass above.
+            if (mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
+                accumulateInputToOutput();
+            } else { // EFFECT_BUFFER_ACCESS_WRITE
+                copyInputToOutput();
+            }
         }
     }
 }
@@ -547,7 +617,14 @@
 
     mConfig.inputCfg.format = EFFECT_BUFFER_FORMAT;
     mConfig.outputCfg.format = EFFECT_BUFFER_FORMAT;
-    mConfig.inputCfg.samplingRate = thread->sampleRate();
+
+    // Don't use sample rate for thread if effect isn't offloadable.
+    if ((thread->type() == ThreadBase::OFFLOAD) && !isOffloaded()) {
+        mConfig.inputCfg.samplingRate = DEFAULT_OUTPUT_SAMPLE_RATE;
+        ALOGV("Overriding effect input as 48kHz");
+    } else {
+        mConfig.inputCfg.samplingRate = thread->sampleRate();
+    }
     mConfig.outputCfg.samplingRate = mConfig.inputCfg.samplingRate;
     mConfig.inputCfg.bufferProvider.cookie = NULL;
     mConfig.inputCfg.bufferProvider.getBuffer = NULL;
@@ -778,6 +855,16 @@
     }
     status_t cmdStatus = NO_ERROR;
     uint32_t size = sizeof(status_t);
+
+    if (isVolumeControl() && isOffloadedOrDirect()) {
+        sp<EffectChain>chain = mChain.promote();
+        // We have the EffectChain and EffectModule lock, permit a reentrant call to setVolume:
+        // resetVolume_l --> setVolume_l --> EffectModule::setVolume
+        mSetVolumeReentrantTid = gettid();
+        chain->resetVolume_l();
+        mSetVolumeReentrantTid = INVALID_PID;
+    }
+
     status_t status = mEffectInterface->command(EFFECT_CMD_DISABLE,
                                                 0,
                                                 NULL,
@@ -917,11 +1004,6 @@
     ALOGV("setEnabled %p enabled %d", this, enabled);
 
     if (enabled != isEnabled()) {
-        status_t status = AudioSystem::setEffectEnabled(mId, enabled);
-        if (enabled && status != NO_ERROR) {
-            return status;
-        }
-
         switch (mState) {
         // going from disabled to enabled
         case IDLE:
@@ -993,6 +1075,16 @@
     }
 }
 
+bool AudioFlinger::EffectModule::isOffloadedOrDirect() const
+{
+    return (mThreadType == ThreadBase::OFFLOAD || mThreadType == ThreadBase::DIRECT);
+}
+
+bool AudioFlinger::EffectModule::isVolumeControlEnabled() const
+{
+    return (isVolumeControl() && (isOffloadedOrDirect() ? isEnabled() : isProcessEnabled()));
+}
+
 void AudioFlinger::EffectModule::setInBuffer(const sp<EffectBufferHalInterface>& buffer) {
     ALOGVV("setInBuffer %p",(&buffer));
 
@@ -1091,7 +1183,7 @@
 
 status_t AudioFlinger::EffectModule::setVolume(uint32_t *left, uint32_t *right, bool controller)
 {
-    Mutex::Autolock _l(mLock);
+    AutoLockReentrant _l(mLock, mSetVolumeReentrantTid);
     if (mStatus != NO_ERROR) {
         return mStatus;
     }
@@ -1100,7 +1192,8 @@
     // if controller flag is set (Note that controller == TRUE => EFFECT_FLAG_VOLUME_CTRL set)
     if (isProcessEnabled() &&
             ((mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL ||
-            (mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_IND)) {
+             (mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_IND ||
+             (mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_MONITOR)) {
         uint32_t volume[2];
         uint32_t *pVolume = NULL;
         uint32_t size = sizeof(volume);
@@ -1122,6 +1215,19 @@
     return status;
 }
 
+void AudioFlinger::EffectChain::setVolumeForOutput_l(uint32_t left, uint32_t right)
+{
+    sp<ThreadBase> thread = mThread.promote();
+    if (thread != 0 &&
+        (thread->type() == ThreadBase::OFFLOAD || thread->type() == ThreadBase::DIRECT) &&
+        !isNonOffloadableEnabled_l()) {
+        PlaybackThread *t = (PlaybackThread *)thread.get();
+        float vol_l = (float)left / (1 << 24);
+        float vol_r = (float)right / (1 << 24);
+        t->setVolumeForOutput_l(vol_l, vol_r);
+    }
+}
+
 status_t AudioFlinger::EffectModule::setDevice(audio_devices_t device)
 {
     if (device == AUDIO_DEVICE_NONE) {
@@ -1203,14 +1309,11 @@
 {
     bool enabled = false;
     Mutex::Autolock _l(mLock);
-    for (size_t i = 0; i < mHandles.size(); i++) {
-        EffectHandle *handle = mHandles[i];
-        if (handle != NULL && !handle->disconnected()) {
-            if (handle->hasControl()) {
-                enabled = handle->enabled();
-            }
-        }
+    EffectHandle *handle = controlHandle_l();
+    if (handle != NULL) {
+        enabled = handle->enabled();
     }
+    mHandles.clear();
     return enabled;
 }
 
@@ -1282,6 +1385,7 @@
     case EFFECT_FLAG_VOLUME_NONE: s.append("none"); break;
     case EFFECT_FLAG_VOLUME_CTRL: s.append("implements control"); break;
     case EFFECT_FLAG_VOLUME_IND: s.append("requires indication"); break;
+    case EFFECT_FLAG_VOLUME_MONITOR: s.append("monitors volume"); break;
     default: s.append("unknown/reserved"); break;
     }
     s.append(", ");
@@ -1384,9 +1488,10 @@
         result.append("\t\tCould not lock Fx mutex:\n");
     }
 
-    result.append("\t\tSession Status State Engine:\n");
-    result.appendFormat("\t\t%05d   %03d    %03d   %p\n",
-            mSessionId, mStatus, mState, mEffectInterface.get());
+    result.append("\t\tSession Status State Registered Enabled Suspended Engine:\n");
+    result.appendFormat("\t\t%05d   %03d    %03d   %s          %s       %s         %p\n",
+            mSessionId, mStatus, mState, mPolicyRegistered ? "y" : "n", mPolicyEnabled ? "y" : "n",
+            mSuspended ? "y" : "n", mEffectInterface.get());
 
     result.append("\t\tDescriptor:\n");
     char uuidStr[64];
@@ -1449,6 +1554,11 @@
 
     write(fd, result.string(), result.length());
 
+    if (mEffectInterface != 0) {
+        dprintf(fd, "\tEffect ID %d HAL dump:\n", mId);
+        (void)mEffectInterface->dump(fd);
+    }
+
     if (locked) {
         mLock.unlock();
     }
@@ -1516,6 +1626,12 @@
 
     mEnabled = true;
 
+    status_t status = effect->updatePolicyState();
+    if (status != NO_ERROR) {
+        mEnabled = false;
+        return status;
+    }
+
     sp<ThreadBase> thread = effect->thread().promote();
     if (thread != 0) {
         thread->checkSuspendOnEffectEnabled(effect, true, effect->sessionId());
@@ -1526,7 +1642,7 @@
         return NO_ERROR;
     }
 
-    status_t status = effect->setEnabled(true);
+    status = effect->setEnabled(true);
     if (status != NO_ERROR) {
         if (thread != 0) {
             thread->checkSuspendOnEffectEnabled(effect, false, effect->sessionId());
@@ -1569,6 +1685,8 @@
     }
     mEnabled = false;
 
+    effect->updatePolicyState();
+
     if (effect->suspended()) {
         return NO_ERROR;
     }
@@ -1604,20 +1722,17 @@
         return;
     }
     mDisconnected = true;
-    sp<ThreadBase> thread;
     {
         sp<EffectModule> effect = mEffect.promote();
         if (effect != 0) {
-            thread = effect->thread().promote();
-        }
-    }
-    if (thread != 0) {
-        thread->disconnectEffectHandle(this, unpinIfLast);
-    } else {
-        // try to cleanup as much as we can
-        sp<EffectModule> effect = mEffect.promote();
-        if (effect != 0 && effect->disconnectHandle(this, unpinIfLast) > 0) {
-            ALOGW("%s Effect handle %p disconnected after thread destruction", __FUNCTION__, this);
+            sp<ThreadBase> thread = effect->thread().promote();
+            if (thread != 0) {
+                thread->disconnectEffectHandle(this, unpinIfLast);
+            } else if (effect->disconnectHandle(this, unpinIfLast) > 0) {
+                ALOGW("%s Effect handle %p disconnected after thread destruction",
+                    __func__, this);
+            }
+            effect->updatePolicyState();
         }
     }
 
@@ -1815,7 +1930,7 @@
     bool locked = mCblk != NULL && AudioFlinger::dumpTryLock(mCblk->lock);
 
     snprintf(buffer, size, "\t\t\t%5d    %5d  %3s    %3s  %5u  %5u\n",
-            (mClient == 0) ? getpid_cached : mClient->pid(),
+            (mClient == 0) ? getpid() : mClient->pid(),
             mPriority,
             mHasControl ? "yes" : "no",
             locked ? "yes" : "no",
@@ -1891,6 +2006,16 @@
     return 0;
 }
 
+std::vector<int> AudioFlinger::EffectChain::getEffectIds()
+{
+    std::vector<int> ids;
+    Mutex::Autolock _l(mLock);
+    for (size_t i = 0; i < mEffects.size(); i++) {
+        ids.push_back(mEffects[i]->id());
+    }
+    return ids;
+}
+
 void AudioFlinger::EffectChain::clearInputBuffer()
 {
     Mutex::Autolock _l(mLock);
@@ -2200,8 +2325,7 @@
 
     // first update volume controller
     for (size_t i = size; i > 0; i--) {
-        if (mEffects[i - 1]->isProcessEnabled() &&
-            (mEffects[i - 1]->desc().flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL) {
+        if (mEffects[i - 1]->isVolumeControlEnabled()) {
             ctrlIdx = i - 1;
             hasControl = true;
             break;
@@ -2229,7 +2353,7 @@
     }
     // then indicate volume to all other effects in chain.
     // Pass altered volume to effects before volume controller
-    // and requested volume to effects after controller
+    // and requested volume to effects after controller or with volume monitor flag
     uint32_t lVol = newLeft;
     uint32_t rVol = newRight;
 
@@ -2242,11 +2366,18 @@
             lVol = *left;
             rVol = *right;
         }
-        mEffects[i]->setVolume(&lVol, &rVol, false);
+        // Pass requested volume directly if this is volume monitor module
+        if (mEffects[i]->isVolumeMonitor()) {
+            mEffects[i]->setVolume(left, right, false);
+        } else {
+            mEffects[i]->setVolume(&lVol, &rVol, false);
+        }
     }
     *left = newLeft;
     *right = newRight;
 
+    setVolumeForOutput_l(*left, *right);
+
     return hasControl;
 }
 
@@ -2273,13 +2404,10 @@
 
 void AudioFlinger::EffectChain::dump(int fd, const Vector<String16>& args)
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
     String8 result;
 
-    size_t numEffects = mEffects.size();
-    snprintf(buffer, SIZE, "    %zu effects for session %d\n", numEffects, mSessionId);
-    result.append(buffer);
+    const size_t numEffects = mEffects.size();
+    result.appendFormat("    %zu effects for session %d\n", numEffects, mSessionId);
 
     if (numEffects) {
         bool locked = AudioFlinger::dumpTryLock(mLock);
@@ -2307,6 +2435,8 @@
         if (locked) {
             mLock.unlock();
         }
+    } else {
+        write(fd, result.string(), result.size());
     }
 }
 
@@ -2508,6 +2638,11 @@
 bool AudioFlinger::EffectChain::isNonOffloadableEnabled()
 {
     Mutex::Autolock _l(mLock);
+    return isNonOffloadableEnabled_l();
+}
+
+bool AudioFlinger::EffectChain::isNonOffloadableEnabled_l()
+{
     size_t size = mEffects.size();
     for (size_t i = 0; i < size; i++) {
         if (mEffects[i]->isEnabled() && !mEffects[i]->isOffloadable()) {
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 2327bb9..220874d 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -85,6 +85,8 @@
     status_t    setEnabled_l(bool enabled);
     bool isEnabled() const;
     bool isProcessEnabled() const;
+    bool isOffloadedOrDirect() const;
+    bool isVolumeControlEnabled() const;
 
     void        setInBuffer(const sp<EffectBufferHalInterface>& buffer);
     int16_t     *inBuffer() const {
@@ -95,7 +97,8 @@
         return mOutBuffer != 0 ? reinterpret_cast<int16_t*>(mOutBuffer->ptr()) : NULL;
     }
     void        setChain(const wp<EffectChain>& chain) { mChain = chain; }
-    void        setThread(const wp<ThreadBase>& thread) { mThread = thread; }
+    void        setThread(const wp<ThreadBase>& thread)
+                    { mThread = thread; mThreadType = thread.promote()->type(); }
     const wp<ThreadBase>& thread() { return mThread; }
 
     status_t addHandle(EffectHandle *handle);
@@ -128,11 +131,19 @@
                         { return (mDescriptor.flags & EFFECT_FLAG_HW_ACC_MASK) == 0; }
     bool             isProcessImplemented() const
                         { return (mDescriptor.flags & EFFECT_FLAG_NO_PROCESS) == 0; }
+    bool             isVolumeControl() const
+                        { return (mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK)
+                            == EFFECT_FLAG_VOLUME_CTRL; }
+    bool             isVolumeMonitor() const
+                        { return (mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK)
+                            == EFFECT_FLAG_VOLUME_MONITOR; }
     status_t         setOffloaded(bool offloaded, audio_io_handle_t io);
     bool             isOffloaded() const;
     void             addEffectToHal_l();
     void             release_l();
 
+    status_t         updatePolicyState();
+
     void             dump(int fd, const Vector<String16>& args);
 
 private:
@@ -150,6 +161,7 @@
 
 mutable Mutex               mLock;      // mutex for process, commands and handles list protection
     wp<ThreadBase>      mThread;    // parent thread
+    ThreadBase::type_t  mThreadType; // parent thread type
     wp<EffectChain>     mChain;     // parent effect chain
     const int           mId;        // this instance unique ID
     const audio_session_t mSessionId; // audio session ID
@@ -176,6 +188,34 @@
     uint32_t mInChannelCountRequested;
     uint32_t mOutChannelCountRequested;
 #endif
+
+    class AutoLockReentrant {
+    public:
+        AutoLockReentrant(Mutex& mutex, pid_t allowedTid)
+            : mMutex(gettid() == allowedTid ? nullptr : &mutex)
+        {
+            if (mMutex != nullptr) mMutex->lock();
+        }
+        ~AutoLockReentrant() {
+            if (mMutex != nullptr) mMutex->unlock();
+        }
+    private:
+        Mutex * const mMutex;
+    };
+
+    static constexpr pid_t INVALID_PID = (pid_t)-1;
+    // this tid is allowed to call setVolume() without acquiring the mutex.
+    pid_t mSetVolumeReentrantTid = INVALID_PID;
+
+    // Audio policy effect state management
+    // Mutex protecting transactions with audio policy manager as mLock cannot
+    // be held to avoid cross deadlocks with audio policy mutex
+    Mutex   mPolicyLock;
+    // Effect is registered in APM or not
+    bool    mPolicyRegistered = false;
+    // Effect enabled state communicated to APM. Enabled state corresponds to
+    // state requested by the EffectHandle with control
+    bool    mPolicyEnabled = false;
 };
 
 // The EffectHandle class implements the IEffect interface. It provides resources
@@ -306,6 +346,7 @@
     sp<EffectModule> getEffectFromDesc_l(effect_descriptor_t *descriptor);
     sp<EffectModule> getEffectFromId_l(int id);
     sp<EffectModule> getEffectFromType_l(const effect_uuid_t *type);
+    std::vector<int> getEffectIds();
     // FIXME use float to improve the dynamic range
     bool setVolume_l(uint32_t *left, uint32_t *right, bool force = false);
     void resetVolume_l();
@@ -353,6 +394,7 @@
 
     // At least one non offloadable effect in the chain is enabled
     bool isNonOffloadableEnabled();
+    bool isNonOffloadableEnabled_l();
 
     void syncHalEffectsState();
 
@@ -403,6 +445,8 @@
 
     void setThread(const sp<ThreadBase>& thread);
 
+    void setVolumeForOutput_l(uint32_t left, uint32_t right);
+
              wp<ThreadBase> mThread;     // parent mixer thread
     mutable  Mutex mLock;        // mutex protecting effect list
              Vector< sp<EffectModule> > mEffects; // list of effect modules
diff --git a/services/audioflinger/FastCapture.cpp b/services/audioflinger/FastCapture.cpp
index d063772..d6d6e25 100644
--- a/services/audioflinger/FastCapture.cpp
+++ b/services/audioflinger/FastCapture.cpp
@@ -20,6 +20,7 @@
 #define ATRACE_TAG ATRACE_TAG_AUDIO
 
 #include "Configuration.h"
+#include <audio_utils/format.h>
 #include <linux/futex.h>
 #include <sys/syscall.h>
 #include <media/AudioBufferProvider.h>
@@ -153,7 +154,7 @@
         mReadBufferState = -1;
         dumpState->mFrameCount = frameCount;
     }
-
+    dumpState->mSilenced = current->mSilenceCapture;
 }
 
 void FastCapture::onWork()
@@ -161,7 +162,21 @@
     const FastCaptureState * const current = (const FastCaptureState *) mCurrent;
     FastCaptureDumpState * const dumpState = (FastCaptureDumpState *) mDumpState;
     const FastCaptureState::Command command = mCommand;
-    const size_t frameCount = current->mFrameCount;
+    size_t frameCount = current->mFrameCount;
+    AudioBufferProvider* fastPatchRecordBufferProvider = current->mFastPatchRecordBufferProvider;
+    AudioBufferProvider::Buffer patchBuffer;
+
+    if (fastPatchRecordBufferProvider != 0) {
+        patchBuffer.frameCount = ~0;
+        status_t status = fastPatchRecordBufferProvider->getNextBuffer(&patchBuffer);
+        if (status != NO_ERROR) {
+            frameCount = 0;
+        } else if (patchBuffer.frameCount < frameCount) {
+            // TODO: Make sure that it doesn't cause any issues if we just get a small available
+            // buffer from the buffer provider.
+            frameCount = patchBuffer.frameCount;
+        }
+    }
 
     if ((command & FastCaptureState::READ) /*&& isWarm*/) {
         ALOG_ASSERT(mInputSource != NULL);
@@ -176,6 +191,7 @@
             mTotalNativeFramesRead += framesRead;
             dumpState->mFramesRead = mTotalNativeFramesRead;
             mReadBufferState = framesRead;
+            patchBuffer.frameCount = framesRead;
         } else {
             dumpState->mReadErrors++;
             mReadBufferState = 0;
@@ -192,12 +208,22 @@
             mReadBufferState = frameCount;
         }
         if (mReadBufferState > 0) {
+            if (current->mSilenceCapture) {
+                memset(mReadBuffer, 0, mReadBufferState * Format_frameSize(mFormat));
+            }
             ssize_t framesWritten = mPipeSink->write(mReadBuffer, mReadBufferState);
-            // FIXME This supports at most one fast capture client.
-            //       To handle multiple clients this could be converted to an array,
-            //       or with a lot more work the control block could be shared by all clients.
             audio_track_cblk_t* cblk = current->mCblk;
-            if (cblk != NULL && framesWritten > 0) {
+            if (fastPatchRecordBufferProvider != 0) {
+                // This indicates the fast track is a patch record, update the cblk by
+                // calling releaseBuffer().
+                memcpy_by_audio_format(patchBuffer.raw, current->mFastPatchRecordFormat,
+                        mReadBuffer, mFormat.mFormat, framesWritten * mFormat.mChannelCount);
+                patchBuffer.frameCount = framesWritten;
+                fastPatchRecordBufferProvider->releaseBuffer(&patchBuffer);
+            } else if (cblk != NULL && framesWritten > 0) {
+                // FIXME This supports at most one fast capture client.
+                //       To handle multiple clients this could be converted to an array,
+                //       or with a lot more work the control block could be shared by all clients.
                 int32_t rear = cblk->u.mStreaming.mRear;
                 android_atomic_release_store(framesWritten + rear, &cblk->u.mStreaming.mRear);
                 cblk->mServer += framesWritten;
diff --git a/services/audioflinger/FastCaptureDumpState.cpp b/services/audioflinger/FastCaptureDumpState.cpp
index 53eeba5..b8b3866 100644
--- a/services/audioflinger/FastCaptureDumpState.cpp
+++ b/services/audioflinger/FastCaptureDumpState.cpp
@@ -44,10 +44,11 @@
     double periodSec = (double) mFrameCount / mSampleRate;
     dprintf(fd, "  FastCapture command=%s readSequence=%u framesRead=%u\n"
                 "              readErrors=%u sampleRate=%u frameCount=%zu\n"
-                "              measuredWarmup=%.3g ms, warmupCycles=%u period=%.2f ms\n",
+                "              measuredWarmup=%.3g ms, warmupCycles=%u period=%.2f ms\n"
+                "              silenced: %s\n",
                 FastCaptureState::commandToString(mCommand), mReadSequence, mFramesRead,
                 mReadErrors, mSampleRate, mFrameCount, measuredWarmupMs, mWarmupCycles,
-                periodSec * 1e3);
+                periodSec * 1e3, mSilenced ? "true" : "false");
 }
 
 }   // android
diff --git a/services/audioflinger/FastCaptureDumpState.h b/services/audioflinger/FastCaptureDumpState.h
index 6f9c4c3..a1b8706 100644
--- a/services/audioflinger/FastCaptureDumpState.h
+++ b/services/audioflinger/FastCaptureDumpState.h
@@ -35,6 +35,7 @@
     uint32_t mReadErrors;       // total number of read() errors
     uint32_t mSampleRate;
     size_t   mFrameCount;
+    bool     mSilenced = false; // capture is silenced
 };
 
 }   // android
diff --git a/services/audioflinger/FastCaptureState.h b/services/audioflinger/FastCaptureState.h
index 9bca2d4..f949275 100644
--- a/services/audioflinger/FastCaptureState.h
+++ b/services/audioflinger/FastCaptureState.h
@@ -18,6 +18,7 @@
 #define ANDROID_AUDIO_FAST_CAPTURE_STATE_H
 
 #include <media/nbaio/NBAIO.h>
+#include <media/AudioBufferProvider.h>
 #include "FastThreadState.h"
 #include <private/media/AudioTrackShared.h>
 
@@ -37,6 +38,12 @@
     size_t          mFrameCount;        // number of frames per fast capture buffer
     audio_track_cblk_t* mCblk;          // control block for the single fast client, or NULL
 
+    audio_format_t  mFastPatchRecordFormat = AUDIO_FORMAT_INVALID;
+    AudioBufferProvider* mFastPatchRecordBufferProvider = nullptr;   // a reference to a patch
+                                                                     // record in fast mode
+    bool            mSilenceCapture = false;    // request to silence capture for fast track.
+                                                // note: this also silences the normal mixer pipe
+
     // Extends FastThreadState::Command
     static const Command
         // The following commands also process configuration changes, and can be "or"ed:
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index 79bb9fe..c5b9953 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -32,13 +32,14 @@
 #include <utils/Trace.h>
 #include <system/audio.h>
 #ifdef FAST_THREAD_STATISTICS
-#include <cpustats/CentralTendencyStatistics.h>
+#include <audio_utils/Statistics.h>
 #ifdef CPU_FREQUENCY_STATISTICS
 #include <cpustats/ThreadCpuUsage.h>
 #endif
 #endif
-#include <audio_utils/mono_blend.h>
+#include <audio_utils/channels.h>
 #include <audio_utils/format.h>
+#include <audio_utils/mono_blend.h>
 #include <media/AudioMixer.h>
 #include "FastMixer.h"
 #include "TypedLogger.h"
@@ -47,7 +48,8 @@
 
 /*static*/ const FastMixerState FastMixer::sInitial;
 
-FastMixer::FastMixer() : FastThread("cycle_ms", "load_us"),
+FastMixer::FastMixer(audio_io_handle_t parentIoHandle)
+    : FastThread("cycle_ms", "load_us"),
     // mFastTrackNames
     // mGenerations
     mOutputSink(NULL),
@@ -58,7 +60,6 @@
     mSinkChannelCount(FCC_2),
     mMixerBuffer(NULL),
     mMixerBufferSize(0),
-    mMixerBufferFormat(AUDIO_FORMAT_PCM_16_BIT),
     mMixerBufferState(UNDEFINED),
     mFormat(Format_Invalid),
     mSampleRate(0),
@@ -66,8 +67,11 @@
     mTotalNativeFramesWritten(0),
     // timestamp
     mNativeFramesWrittenButNotPresented(0),   // the = 0 is to silence the compiler
-    mMasterMono(false)
+    mMasterMono(false),
+    mThreadIoHandle(parentIoHandle)
 {
+    (void)mThreadIoHandle; // prevent unused warning, see C++17 [[maybe_unused]]
+
     // FIXME pass sInitial as parameter to base class constructor, and make it static local
     mPrevious = &sInitial;
     mCurrent = &sInitial;
@@ -135,6 +139,75 @@
     }
 }
 
+void FastMixer::updateMixerTrack(int index, Reason reason) {
+    const FastMixerState * const current = (const FastMixerState *) mCurrent;
+    const FastTrack * const fastTrack = &current->mFastTracks[index];
+
+    // check and update generation
+    if (reason == REASON_MODIFY && mGenerations[index] == fastTrack->mGeneration) {
+        return; // no change on an already configured track.
+    }
+    mGenerations[index] = fastTrack->mGeneration;
+
+    // mMixer == nullptr on configuration failure (check done after generation update).
+    if (mMixer == nullptr) {
+        return;
+    }
+
+    switch (reason) {
+    case REASON_REMOVE:
+        mMixer->destroy(index);
+        break;
+    case REASON_ADD: {
+        const status_t status = mMixer->create(
+                index, fastTrack->mChannelMask, fastTrack->mFormat, AUDIO_SESSION_OUTPUT_MIX);
+        LOG_ALWAYS_FATAL_IF(status != NO_ERROR,
+                "%s: cannot create fast track index"
+                " %d, mask %#x, format %#x in AudioMixer",
+                __func__, index, fastTrack->mChannelMask, fastTrack->mFormat);
+    }
+        [[fallthrough]];  // now fallthrough to update the newly created track.
+    case REASON_MODIFY:
+        mMixer->setBufferProvider(index, fastTrack->mBufferProvider);
+
+        float vlf, vrf;
+        if (fastTrack->mVolumeProvider != nullptr) {
+            const gain_minifloat_packed_t vlr = fastTrack->mVolumeProvider->getVolumeLR();
+            vlf = float_from_gain(gain_minifloat_unpack_left(vlr));
+            vrf = float_from_gain(gain_minifloat_unpack_right(vlr));
+        } else {
+            vlf = vrf = AudioMixer::UNITY_GAIN_FLOAT;
+        }
+
+        // set volume to avoid ramp whenever the track is updated (or created).
+        // Note: this does not distinguish from starting fresh or
+        // resuming from a paused state.
+        mMixer->setParameter(index, AudioMixer::VOLUME, AudioMixer::VOLUME0, &vlf);
+        mMixer->setParameter(index, AudioMixer::VOLUME, AudioMixer::VOLUME1, &vrf);
+
+        mMixer->setParameter(index, AudioMixer::RESAMPLE, AudioMixer::REMOVE, nullptr);
+        mMixer->setParameter(index, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER,
+                (void *)mMixerBuffer);
+        mMixer->setParameter(index, AudioMixer::TRACK, AudioMixer::MIXER_FORMAT,
+                (void *)(uintptr_t)mMixerBufferFormat);
+        mMixer->setParameter(index, AudioMixer::TRACK, AudioMixer::FORMAT,
+                (void *)(uintptr_t)fastTrack->mFormat);
+        mMixer->setParameter(index, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
+                (void *)(uintptr_t)fastTrack->mChannelMask);
+        mMixer->setParameter(index, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK,
+                (void *)(uintptr_t)mSinkChannelMask);
+        mMixer->setParameter(index, AudioMixer::TRACK, AudioMixer::HAPTIC_ENABLED,
+                (void *)(uintptr_t)fastTrack->mHapticPlaybackEnabled);
+        mMixer->setParameter(index, AudioMixer::TRACK, AudioMixer::HAPTIC_INTENSITY,
+                (void *)(uintptr_t)fastTrack->mHapticIntensity);
+
+        mMixer->enable(index);
+        break;
+    default:
+        LOG_ALWAYS_FATAL("%s: invalid update reason %d", __func__, reason);
+    }
+}
+
 void FastMixer::onStateChange()
 {
     const FastMixerState * const current = (const FastMixerState *) mCurrent;
@@ -155,20 +228,25 @@
     if (current->mOutputSinkGen != mOutputSinkGen) {
         mOutputSink = current->mOutputSink;
         mOutputSinkGen = current->mOutputSinkGen;
+        mSinkChannelMask = current->mSinkChannelMask;
+        mBalance.setChannelMask(mSinkChannelMask);
         if (mOutputSink == NULL) {
             mFormat = Format_Invalid;
             mSampleRate = 0;
             mSinkChannelCount = 0;
             mSinkChannelMask = AUDIO_CHANNEL_NONE;
+            mAudioChannelCount = 0;
         } else {
             mFormat = mOutputSink->format();
             mSampleRate = Format_sampleRate(mFormat);
             mSinkChannelCount = Format_channelCount(mFormat);
             LOG_ALWAYS_FATAL_IF(mSinkChannelCount > AudioMixer::MAX_NUM_CHANNELS);
 
-            // TODO: Add channel mask to NBAIO_Format
-            // We assume that the channel mask must be a valid positional channel mask.
-            mSinkChannelMask = audio_channel_out_mask_from_count(mSinkChannelCount);
+            if (mSinkChannelMask == AUDIO_CHANNEL_NONE) {
+                mSinkChannelMask = audio_channel_out_mask_from_count(mSinkChannelCount);
+            }
+            mAudioChannelCount = mSinkChannelCount - audio_channel_count_from_out_mask(
+                    mSinkChannelMask & AUDIO_CHANNEL_HAPTIC_ALL);
         }
         dumpState->mSampleRate = mSampleRate;
     }
@@ -182,15 +260,15 @@
         free(mSinkBuffer);
         mSinkBuffer = NULL;
         if (frameCount > 0 && mSampleRate > 0) {
-            // The mixer produces either 16 bit PCM or float output, select
-            // float output if the HAL supports higher than 16 bit precision.
-            mMixerBufferFormat = mFormat.mFormat == AUDIO_FORMAT_PCM_16_BIT ?
-                    AUDIO_FORMAT_PCM_16_BIT : AUDIO_FORMAT_PCM_FLOAT;
             // FIXME new may block for unbounded time at internal mutex of the heap
             //       implementation; it would be better to have normal mixer allocate for us
             //       to avoid blocking here and to prevent possible priority inversion
             mMixer = new AudioMixer(frameCount, mSampleRate);
             // FIXME See the other FIXME at FastMixer::setNBLogWriter()
+            NBLog::thread_params_t params;
+            params.frameCount = frameCount;
+            params.sampleRate = mSampleRate;
+            LOG_THREAD_PARAMS(params);
             const size_t mixerFrameSize = mSinkChannelCount
                     * audio_bytes_per_sample(mMixerBufferFormat);
             mMixerBufferSize = mixerFrameSize * frameCount;
@@ -220,6 +298,10 @@
         previousTrackMask = 0;
         mFastTracksGen = current->mFastTracksGen - 1;
         dumpState->mFrameCount = frameCount;
+#ifdef TEE_SINK
+        mTee.set(mFormat, NBAIO_Tee::TEE_FLAG_OUTPUT_THREAD);
+        mTee.setId(std::string("_") + std::to_string(mThreadIoHandle) + "_F");
+#endif
     } else {
         previousTrackMask = previous->mTrackMask;
     }
@@ -227,21 +309,16 @@
     // check for change in active track set
     const unsigned currentTrackMask = current->mTrackMask;
     dumpState->mTrackMask = currentTrackMask;
+    dumpState->mNumTracks = popcount(currentTrackMask);
     if (current->mFastTracksGen != mFastTracksGen) {
-        ALOG_ASSERT(mMixerBuffer != NULL);
 
         // process removed tracks first to avoid running out of track names
         unsigned removedTracks = previousTrackMask & ~currentTrackMask;
         while (removedTracks != 0) {
             int i = __builtin_ctz(removedTracks);
             removedTracks &= ~(1 << i);
-            const FastTrack* fastTrack = &current->mFastTracks[i];
-            ALOG_ASSERT(fastTrack->mBufferProvider == NULL);
-            if (mMixer != NULL) {
-                mMixer->destroy(i);
-            }
+            updateMixerTrack(i, REASON_REMOVE);
             // don't reset track dump state, since other side is ignoring it
-            mGenerations[i] = fastTrack->mGeneration;
         }
 
         // now process added tracks
@@ -249,36 +326,7 @@
         while (addedTracks != 0) {
             int i = __builtin_ctz(addedTracks);
             addedTracks &= ~(1 << i);
-            const FastTrack* fastTrack = &current->mFastTracks[i];
-            AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
-            if (mMixer != NULL) {
-                const int name = i; // for clarity, choose name as fast track index.
-                status_t status = mMixer->create(
-                        name,
-                        fastTrack->mChannelMask,
-                        fastTrack->mFormat, AUDIO_SESSION_OUTPUT_MIX);
-                LOG_ALWAYS_FATAL_IF(status != NO_ERROR,
-                        "%s: cannot create track name"
-                        " %d, mask %#x, format %#x, sessionId %d in AudioMixer",
-                        __func__, name,
-                        fastTrack->mChannelMask, fastTrack->mFormat, AUDIO_SESSION_OUTPUT_MIX);
-                mMixer->setBufferProvider(name, bufferProvider);
-                mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER,
-                        (void *)mMixerBuffer);
-                // newly allocated track names default to full scale volume
-                mMixer->setParameter(
-                        name,
-                        AudioMixer::TRACK,
-                        AudioMixer::MIXER_FORMAT, (void *)mMixerBufferFormat);
-                mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FORMAT,
-                        (void *)(uintptr_t)fastTrack->mFormat);
-                mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
-                        (void *)(uintptr_t)fastTrack->mChannelMask);
-                mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK,
-                        (void *)(uintptr_t)mSinkChannelMask);
-                mMixer->enable(name);
-            }
-            mGenerations[i] = fastTrack->mGeneration;
+            updateMixerTrack(i, REASON_ADD);
         }
 
         // finally process (potentially) modified tracks; these use the same slot
@@ -287,40 +335,10 @@
         while (modifiedTracks != 0) {
             int i = __builtin_ctz(modifiedTracks);
             modifiedTracks &= ~(1 << i);
-            const FastTrack* fastTrack = &current->mFastTracks[i];
-            if (fastTrack->mGeneration != mGenerations[i]) {
-                // this track was actually modified
-                AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
-                ALOG_ASSERT(bufferProvider != NULL);
-                if (mMixer != NULL) {
-                    const int name = i;
-                    mMixer->setBufferProvider(name, bufferProvider);
-                    if (fastTrack->mVolumeProvider == NULL) {
-                        float f = AudioMixer::UNITY_GAIN_FLOAT;
-                        mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0, &f);
-                        mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1, &f);
-                    }
-                    mMixer->setParameter(name, AudioMixer::RESAMPLE,
-                            AudioMixer::REMOVE, NULL);
-                    mMixer->setParameter(
-                            name,
-                            AudioMixer::TRACK,
-                            AudioMixer::MIXER_FORMAT, (void *)mMixerBufferFormat);
-                    mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FORMAT,
-                            (void *)(uintptr_t)fastTrack->mFormat);
-                    mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
-                            (void *)(uintptr_t)fastTrack->mChannelMask);
-                    mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK,
-                            (void *)(uintptr_t)mSinkChannelMask);
-                    // already enabled
-                }
-                mGenerations[i] = fastTrack->mGeneration;
-            }
+            updateMixerTrack(i, REASON_MODIFY);
         }
 
         mFastTracksGen = current->mFastTracksGen;
-
-        dumpState->mNumTracks = popcount(currentTrackMask);
     }
 }
 
@@ -328,13 +346,24 @@
 {
     // TODO: pass an ID parameter to indicate which time series we want to write to in NBLog.cpp
     // Or: pass both of these into a single call with a boolean
-    if (mIsWarm) {
-        LOG_HIST_TS();
-    } else {
-        LOG_AUDIO_STATE();
-    }
     const FastMixerState * const current = (const FastMixerState *) mCurrent;
     FastMixerDumpState * const dumpState = (FastMixerDumpState *) mDumpState;
+
+    if (mIsWarm) {
+        // Logging timestamps for FastMixer is currently disabled to make memory room for logging
+        // other statistics in FastMixer.
+        // To re-enable, delete the #ifdef FASTMIXER_LOG_HIST_TS lines (and the #endif lines).
+#ifdef FASTMIXER_LOG_HIST_TS
+        LOG_HIST_TS();
+#endif
+        //ALOGD("Eric FastMixer::onWork() mIsWarm");
+    } else {
+        dumpState->mTimestampVerifier.discontinuity();
+        // See comment in if block.
+#ifdef FASTMIXER_LOG_HIST_TS
+        LOG_AUDIO_STATE();
+#endif
+    }
     const FastMixerState::Command command = mCommand;
     const size_t frameCount = current->mFrameCount;
 
@@ -376,8 +405,8 @@
                 float vlf = float_from_gain(gain_minifloat_unpack_left(vlr));
                 float vrf = float_from_gain(gain_minifloat_unpack_right(vlr));
 
-                mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0, &vlf);
-                mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1, &vrf);
+                mMixer->setParameter(name, AudioMixer::RAMP_VOLUME, AudioMixer::VOLUME0, &vlf);
+                mMixer->setParameter(name, AudioMixer::RAMP_VOLUME, AudioMixer::VOLUME1, &vrf);
             }
             // FIXME The current implementation of framesReady() for fast tracks
             // takes a tryLock, which can block
@@ -439,17 +468,29 @@
             mono_blend(mMixerBuffer, mMixerBufferFormat, Format_channelCount(mFormat), frameCount,
                     true /*limit*/);
         }
+
+        // Balance must take effect after mono conversion.
+        // mBalance detects zero balance within the class for speed (not needed here).
+        mBalance.setBalance(mMasterBalance.load());
+        mBalance.process((float *)mMixerBuffer, frameCount);
+
         // prepare the buffer used to write to sink
         void *buffer = mSinkBuffer != NULL ? mSinkBuffer : mMixerBuffer;
         if (mFormat.mFormat != mMixerBufferFormat) { // sink format not the same as mixer format
             memcpy_by_audio_format(buffer, mFormat.mFormat, mMixerBuffer, mMixerBufferFormat,
                     frameCount * Format_channelCount(mFormat));
         }
-        // if non-NULL, then duplicate write() to this non-blocking sink
-        NBAIO_Sink* teeSink;
-        if ((teeSink = current->mTeeSink) != NULL) {
-            (void) teeSink->write(buffer, frameCount);
+        if (mSinkChannelMask & AUDIO_CHANNEL_HAPTIC_ALL) {
+            // When there are haptic channels, the sample data is partially interleaved.
+            // Make the sample data fully interleaved here.
+            adjust_channels_non_destructive(buffer, mAudioChannelCount, buffer, mSinkChannelCount,
+                    audio_bytes_per_sample(mFormat.mFormat),
+                    frameCount * audio_bytes_per_frame(mAudioChannelCount, mFormat.mFormat));
         }
+        // if non-NULL, then duplicate write() to this non-blocking sink
+#ifdef TEE_SINK
+        mTee.write(buffer, frameCount);
+#endif
         // FIXME write() is non-blocking and lock-free for a properly implemented NBAIO sink,
         //       but this code should be modified to handle both non-blocking and blocking sinks
         dumpState->mWriteSequence++;
@@ -470,35 +511,49 @@
         mAttemptedWrite = true;
         // FIXME count # of writes blocked excessively, CPU usage, etc. for dump
 
-        ExtendedTimestamp timestamp; // local
-        status_t status = mOutputSink->getTimestamp(timestamp);
-        if (status == NO_ERROR) {
-            const int64_t totalNativeFramesPresented =
-                    timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL];
-            if (totalNativeFramesPresented <= mTotalNativeFramesWritten) {
-                mNativeFramesWrittenButNotPresented =
-                    mTotalNativeFramesWritten - totalNativeFramesPresented;
-                mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] =
+        if (mIsWarm) {
+            ExtendedTimestamp timestamp; // local
+            status_t status = mOutputSink->getTimestamp(timestamp);
+            if (status == NO_ERROR) {
+                dumpState->mTimestampVerifier.add(
+                        timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL],
+                        timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL],
+                        mSampleRate);
+                const int64_t totalNativeFramesPresented =
                         timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL];
-                mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] =
-                        timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL];
+                if (totalNativeFramesPresented <= mTotalNativeFramesWritten) {
+                    mNativeFramesWrittenButNotPresented =
+                        mTotalNativeFramesWritten - totalNativeFramesPresented;
+                    mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] =
+                            timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL];
+                    mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] =
+                            timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL];
+                    // We don't compensate for server - kernel time difference and
+                    // only update latency if we have valid info.
+                    const double latencyMs =
+                            (double)mNativeFramesWrittenButNotPresented * 1000 / mSampleRate;
+                    dumpState->mLatencyMs = latencyMs;
+                    LOG_LATENCY(latencyMs);
+                } else {
+                    // HAL reported that more frames were presented than were written
+                    mNativeFramesWrittenButNotPresented = 0;
+                    status = INVALID_OPERATION;
+                }
             } else {
-                // HAL reported that more frames were presented than were written
-                mNativeFramesWrittenButNotPresented = 0;
-                status = INVALID_OPERATION;
+                dumpState->mTimestampVerifier.error();
             }
-        }
-        if (status == NO_ERROR) {
-            mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] =
-                    mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL];
-        } else {
-            // fetch server time if we can't get timestamp
-            mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] =
-                    systemTime(SYSTEM_TIME_MONOTONIC);
-            // clear out kernel cached position as this may get rapidly stale
-            // if we never get a new valid timestamp
-            mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] = 0;
-            mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] = -1;
+            if (status == NO_ERROR) {
+                mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] =
+                        mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL];
+            } else {
+                // fetch server time if we can't get timestamp
+                mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] =
+                        systemTime(SYSTEM_TIME_MONOTONIC);
+                // clear out kernel cached position as this may get rapidly stale
+                // if we never get a new valid timestamp
+                mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] = 0;
+                mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] = -1;
+            }
         }
     }
 }
diff --git a/services/audioflinger/FastMixer.h b/services/audioflinger/FastMixer.h
index 235d23f..97ab635 100644
--- a/services/audioflinger/FastMixer.h
+++ b/services/audioflinger/FastMixer.h
@@ -18,10 +18,12 @@
 #define ANDROID_AUDIO_FAST_MIXER_H
 
 #include <atomic>
+#include <audio_utils/Balance.h>
 #include "FastThread.h"
 #include "StateQueue.h"
 #include "FastMixerState.h"
 #include "FastMixerDumpState.h"
+#include "NBAIO_Tee.h"
 
 namespace android {
 
@@ -32,12 +34,16 @@
 class FastMixer : public FastThread {
 
 public:
-            FastMixer();
+    /** FastMixer constructor takes as param the parent MixerThread's io handle (id)
+        for purposes of identification. */
+    explicit FastMixer(audio_io_handle_t threadIoHandle);
     virtual ~FastMixer();
 
             FastMixerStateQueue* sq();
 
     virtual void setMasterMono(bool mono) { mMasterMono.store(mono); /* memory_order_seq_cst */ }
+    virtual void setMasterBalance(float balance) { mMasterBalance.store(balance); }
+    virtual float getMasterBalance() const { return mMasterBalance.load(); }
     virtual void setBoottimeOffset(int64_t boottimeOffset) {
         mBoottimeOffset.store(boottimeOffset); /* memory_order_seq_cst */
     }
@@ -53,6 +59,14 @@
     virtual void onStateChange();
     virtual void onWork();
 
+    enum Reason {
+        REASON_REMOVE,
+        REASON_ADD,
+        REASON_MODIFY,
+    };
+    // called when a fast track of index has been removed, added, or modified
+    void updateMixerTrack(int index, Reason reason);
+
     // FIXME these former local variables need comments
     static const FastMixerState sInitial;
 
@@ -71,7 +85,9 @@
     audio_channel_mask_t mSinkChannelMask;
     void*           mMixerBuffer;       // mixer output buffer.
     size_t          mMixerBufferSize;
-    audio_format_t  mMixerBufferFormat; // mixer output format: AUDIO_FORMAT_PCM_(16_BIT|FLOAT).
+    static constexpr audio_format_t mMixerBufferFormat = AUDIO_FORMAT_PCM_FLOAT;
+
+    uint32_t        mAudioChannelCount; // audio channel count, excludes haptic channels.
 
     enum {UNDEFINED, MIXED, ZEROED} mMixerBufferState;
     NBAIO_Format    mFormat;
@@ -84,9 +100,17 @@
     ExtendedTimestamp mTimestamp;
     int64_t         mNativeFramesWrittenButNotPresented;
 
+    audio_utils::Balance mBalance;
+
     // accessed without lock between multiple threads.
     std::atomic_bool mMasterMono;
+    std::atomic<float> mMasterBalance{};
     std::atomic_int_fast64_t mBoottimeOffset;
+
+    const audio_io_handle_t mThreadIoHandle; // parent thread id for debugging purposes
+#ifdef TEE_SINK
+    NBAIO_Tee       mTee;
+#endif
 };  // class FastMixer
 
 }   // namespace android
diff --git a/services/audioflinger/FastMixerDumpState.cpp b/services/audioflinger/FastMixerDumpState.cpp
index 2e4fb8c..a42e09c 100644
--- a/services/audioflinger/FastMixerDumpState.cpp
+++ b/services/audioflinger/FastMixerDumpState.cpp
@@ -19,7 +19,7 @@
 
 #include "Configuration.h"
 #ifdef FAST_THREAD_STATISTICS
-#include <cpustats/CentralTendencyStatistics.h>
+#include <audio_utils/Statistics.h>
 #ifdef CPU_FREQUENCY_STATISTICS
 #include <cpustats/ThreadCpuUsage.h>
 #endif
@@ -68,21 +68,22 @@
     dprintf(fd, "  FastMixer command=%s writeSequence=%u framesWritten=%u\n"
                 "            numTracks=%u writeErrors=%u underruns=%u overruns=%u\n"
                 "            sampleRate=%u frameCount=%zu measuredWarmup=%.3g ms, warmupCycles=%u\n"
-                "            mixPeriod=%.2f ms\n",
+                "            mixPeriod=%.2f ms latency=%.2f ms\n",
                 FastMixerState::commandToString(mCommand), mWriteSequence, mFramesWritten,
                 mNumTracks, mWriteErrors, mUnderruns, mOverruns,
                 mSampleRate, mFrameCount, measuredWarmupMs, mWarmupCycles,
-                mixPeriodSec * 1e3);
+                mixPeriodSec * 1e3, mLatencyMs);
+    dprintf(fd, "  FastMixer Timestamp stats: %s\n", mTimestampVerifier.toString().c_str());
 #ifdef FAST_THREAD_STATISTICS
     // find the interval of valid samples
-    uint32_t bounds = mBounds;
-    uint32_t newestOpen = bounds & 0xFFFF;
+    const uint32_t bounds = mBounds;
+    const uint32_t newestOpen = bounds & 0xFFFF;
     uint32_t oldestClosed = bounds >> 16;
 
     //uint32_t n = (newestOpen - oldestClosed) & 0xFFFF;
     uint32_t n;
     __builtin_sub_overflow(newestOpen, oldestClosed, &n);
-    n = n & 0xFFFF;
+    n &= 0xFFFF;
 
     if (n > mSamplingN) {
         ALOGE("too many samples %u", n);
@@ -90,9 +91,9 @@
     }
     // statistics for monotonic (wall clock) time, thread raw CPU load in time, CPU clock frequency,
     // and adjusted CPU load in MHz normalized for CPU clock frequency
-    CentralTendencyStatistics wall, loadNs;
+    audio_utils::Statistics<double> wall, loadNs;
 #ifdef CPU_FREQUENCY_STATISTICS
-    CentralTendencyStatistics kHz, loadMHz;
+    audio_utils::Statistics<double> kHz, loadMHz;
     uint32_t previousCpukHz = 0;
 #endif
     // Assuming a normal distribution for cycle times, three standard deviations on either side of
@@ -107,18 +108,18 @@
         if (tail != NULL) {
             tail[j] = wallNs;
         }
-        wall.sample(wallNs);
+        wall.add(wallNs);
         uint32_t sampleLoadNs = mLoadNs[i];
-        loadNs.sample(sampleLoadNs);
+        loadNs.add(sampleLoadNs);
 #ifdef CPU_FREQUENCY_STATISTICS
         uint32_t sampleCpukHz = mCpukHz[i];
         // skip bad kHz samples
         if ((sampleCpukHz & ~0xF) != 0) {
-            kHz.sample(sampleCpukHz >> 4);
+            kHz.add(sampleCpukHz >> 4);
             if (sampleCpukHz == previousCpukHz) {
                 double megacycles = (double) sampleLoadNs * (double) (sampleCpukHz >> 4) * 1e-12;
                 double adjMHz = megacycles / mixPeriodSec;  // _not_ wallNs * 1e9
-                loadMHz.sample(adjMHz);
+                loadMHz.add(adjMHz);
             }
         }
         previousCpukHz = sampleCpukHz;
@@ -126,42 +127,42 @@
     }
     if (n) {
         dprintf(fd, "  Simple moving statistics over last %.1f seconds:\n",
-                    wall.n() * mixPeriodSec);
+                    wall.getN() * mixPeriodSec);
         dprintf(fd, "    wall clock time in ms per mix cycle:\n"
                     "      mean=%.2f min=%.2f max=%.2f stddev=%.2f\n",
-                    wall.mean()*1e-6, wall.minimum()*1e-6, wall.maximum()*1e-6,
-                    wall.stddev()*1e-6);
+                    wall.getMean()*1e-6, wall.getMin()*1e-6, wall.getMax()*1e-6,
+                    wall.getStdDev()*1e-6);
         dprintf(fd, "    raw CPU load in us per mix cycle:\n"
                     "      mean=%.0f min=%.0f max=%.0f stddev=%.0f\n",
-                    loadNs.mean()*1e-3, loadNs.minimum()*1e-3, loadNs.maximum()*1e-3,
-                    loadNs.stddev()*1e-3);
+                    loadNs.getMean()*1e-3, loadNs.getMin()*1e-3, loadNs.getMax()*1e-3,
+                    loadNs.getStdDev()*1e-3);
     } else {
         dprintf(fd, "  No FastMixer statistics available currently\n");
     }
 #ifdef CPU_FREQUENCY_STATISTICS
     dprintf(fd, "  CPU clock frequency in MHz:\n"
                 "    mean=%.0f min=%.0f max=%.0f stddev=%.0f\n",
-                kHz.mean()*1e-3, kHz.minimum()*1e-3, kHz.maximum()*1e-3, kHz.stddev()*1e-3);
+                kHz.getMean()*1e-3, kHz.getMin()*1e-3, kHz.getMax()*1e-3, kHz.getStdDev()*1e-3);
     dprintf(fd, "  adjusted CPU load in MHz (i.e. normalized for CPU clock frequency):\n"
                 "    mean=%.1f min=%.1f max=%.1f stddev=%.1f\n",
-                loadMHz.mean(), loadMHz.minimum(), loadMHz.maximum(), loadMHz.stddev());
+                loadMHz.getMean(), loadMHz.getMin(), loadMHz.getMax(), loadMHz.getStdDev());
 #endif
     if (tail != NULL) {
         qsort(tail, n, sizeof(uint32_t), compare_uint32_t);
         // assume same number of tail samples on each side, left and right
         uint32_t count = n / kTailDenominator;
-        CentralTendencyStatistics left, right;
+        audio_utils::Statistics<double> left, right;
         for (uint32_t i = 0; i < count; ++i) {
-            left.sample(tail[i]);
-            right.sample(tail[n - (i + 1)]);
+            left.add(tail[i]);
+            right.add(tail[n - (i + 1)]);
         }
         dprintf(fd, "  Distribution of mix cycle times in ms for the tails "
                     "(> ~3 stddev outliers):\n"
                     "    left tail: mean=%.2f min=%.2f max=%.2f stddev=%.2f\n"
                     "    right tail: mean=%.2f min=%.2f max=%.2f stddev=%.2f\n",
-                    left.mean()*1e-6, left.minimum()*1e-6, left.maximum()*1e-6, left.stddev()*1e-6,
-                    right.mean()*1e-6, right.minimum()*1e-6, right.maximum()*1e-6,
-                    right.stddev()*1e-6);
+                    left.getMean()*1e-6, left.getMin()*1e-6, left.getMax()*1e-6, left.getStdDev()*1e-6,
+                    right.getMean()*1e-6, right.getMin()*1e-6, right.getMax()*1e-6,
+                    right.getStdDev()*1e-6);
         delete[] tail;
     }
 #endif
diff --git a/services/audioflinger/FastMixerDumpState.h b/services/audioflinger/FastMixerDumpState.h
index 8ef31d1..9b91cbc 100644
--- a/services/audioflinger/FastMixerDumpState.h
+++ b/services/audioflinger/FastMixerDumpState.h
@@ -18,6 +18,7 @@
 #define ANDROID_AUDIO_FAST_MIXER_DUMP_STATE_H
 
 #include <stdint.h>
+#include <audio_utils/TimestampVerifier.h>
 #include "Configuration.h"
 #include "FastThreadDumpState.h"
 #include "FastMixerState.h"
@@ -66,6 +67,7 @@
 
     void dump(int fd) const;    // should only be called on a stable copy, not the original
 
+    double   mLatencyMs = 0.;   // measured latency, default of 0 if no valid timestamp read.
     uint32_t mWriteSequence;    // incremented before and after each write()
     uint32_t mFramesWritten;    // total number of frames written successfully
     uint32_t mNumTracks;        // total number of active fast tracks
@@ -74,6 +76,9 @@
     size_t   mFrameCount;
     uint32_t mTrackMask;        // mask of active tracks
     FastTrackDump   mTracks[FastMixerState::kMaxFastTracks];
+
+    // For timestamp statistics.
+    TimestampVerifier<int64_t /* frame count */, int64_t /* time ns */> mTimestampVerifier;
 };
 
 }   // android
diff --git a/services/audioflinger/FastMixerState.cpp b/services/audioflinger/FastMixerState.cpp
index 36d8eef..b98842d 100644
--- a/services/audioflinger/FastMixerState.cpp
+++ b/services/audioflinger/FastMixerState.cpp
@@ -35,7 +35,7 @@
 FastMixerState::FastMixerState() : FastThreadState(),
     // mFastTracks
     mFastTracksGen(0), mTrackMask(0), mOutputSink(NULL), mOutputSinkGen(0),
-    mFrameCount(0), mTeeSink(NULL)
+    mFrameCount(0)
 {
     int ok = pthread_once(&sMaxFastTracksOnce, sMaxFastTracksInit);
     if (ok != 0) {
diff --git a/services/audioflinger/FastMixerState.h b/services/audioflinger/FastMixerState.h
index 2be1e91..396c797 100644
--- a/services/audioflinger/FastMixerState.h
+++ b/services/audioflinger/FastMixerState.h
@@ -19,6 +19,7 @@
 
 #include <audio_utils/minifloat.h>
 #include <system/audio.h>
+#include <media/AudioMixer.h>
 #include <media/ExtendedAudioBufferProvider.h>
 #include <media/nbaio/NBAIO.h>
 #include <media/nblog/NBLog.h>
@@ -47,6 +48,9 @@
     audio_channel_mask_t    mChannelMask;    // AUDIO_CHANNEL_OUT_MONO or AUDIO_CHANNEL_OUT_STEREO
     audio_format_t          mFormat;         // track format
     int                     mGeneration;     // increment when any field is assigned
+    bool                    mHapticPlaybackEnabled = false; // haptic playback is enabled or not
+    AudioMixer::haptic_intensity_t mHapticIntensity = AudioMixer::HAPTIC_SCALE_MUTE; // intensity of
+                                                                                     // haptic data
 };
 
 // Represents a single state of the fast mixer
@@ -69,6 +73,9 @@
     NBAIO_Sink* mOutputSink;    // HAL output device, must already be negotiated
     int         mOutputSinkGen; // increment when mOutputSink is assigned
     size_t      mFrameCount;    // number of frames per fast mix buffer
+    audio_channel_mask_t mSinkChannelMask; // If not AUDIO_CHANNEL_NONE, specifies sink channel
+                                           // mask when it cannot be directly calculated from
+                                           // channel count
 
     // Extends FastThreadState::Command
     static const Command
@@ -77,9 +84,6 @@
         WRITE = 0x10,           // write to output sink
         MIX_WRITE = 0x18;       // mix tracks and write to output sink
 
-    // This might be a one-time configuration rather than per-state
-    NBAIO_Sink* mTeeSink;       // if non-NULL, then duplicate write()s to this non-blocking sink
-
     // never returns NULL; asserts if command is invalid
     static const char *commandToString(Command command);
 
diff --git a/services/audioflinger/FastThread.cpp b/services/audioflinger/FastThread.cpp
index dc15487..04b32c2 100644
--- a/services/audioflinger/FastThread.cpp
+++ b/services/audioflinger/FastThread.cpp
@@ -22,6 +22,7 @@
 #include "Configuration.h"
 #include <linux/futex.h>
 #include <sys/syscall.h>
+#include <audio_utils/clock.h>
 #include <cutils/atomic.h>
 #include <utils/Log.h>
 #include <utils/Trace.h>
@@ -65,8 +66,6 @@
     /* mMeasuredWarmupTs({0, 0}), */
     mWarmupCycles(0),
     mWarmupConsecutiveInRangeCycles(0),
-    // mDummyNBLogWriter
-    mNBLogWriter(&mDummyNBLogWriter),
     mTimestampStatus(INVALID_OPERATION),
 
     mCommand(FastThreadState::INITIAL),
@@ -93,7 +92,7 @@
 {
     // LOGT now works even if tlNBLogWriter is nullptr, but we're considering changing that,
     // so this initialization permits a future change to remove the check for nullptr.
-    tlNBLogWriter = &mDummyNBLogWriter;
+    tlNBLogWriter = mDummyNBLogWriter.get();
     for (;;) {
 
         // either nanosleep, sched_yield, or busy wait
@@ -123,9 +122,9 @@
 
             // As soon as possible of learning of a new dump area, start using it
             mDumpState = next->mDumpState != NULL ? next->mDumpState : mDummyDumpState;
-            mNBLogWriter = next->mNBLogWriter != NULL ? next->mNBLogWriter : &mDummyNBLogWriter;
-            setNBLogWriter(mNBLogWriter);   // FastMixer informs its AudioMixer, FastCapture ignores
-            tlNBLogWriter = mNBLogWriter;
+            tlNBLogWriter = next->mNBLogWriter != NULL ?
+                    next->mNBLogWriter : mDummyNBLogWriter.get();
+            setNBLogWriter(tlNBLogWriter); // FastMixer informs its AudioMixer, FastCapture ignores
 
             // We want to always have a valid reference to the previous (non-idle) state.
             // However, the state queue only guarantees access to current and previous states.
@@ -260,6 +259,9 @@
                         mIsWarm = true;
                         mDumpState->mMeasuredWarmupTs = mMeasuredWarmupTs;
                         mDumpState->mWarmupCycles = mWarmupCycles;
+                        const double measuredWarmupMs = (mMeasuredWarmupTs.tv_sec * 1e3) +
+                                (mMeasuredWarmupTs.tv_nsec * 1e-6);
+                        LOG_WARMUP_TIME(measuredWarmupMs);
                     }
                 }
                 mSleepNs = -1;
@@ -270,6 +272,7 @@
                         ALOGV("underrun: time since last cycle %d.%03ld sec",
                                 (int) sec, nsec / 1000000L);
                         mDumpState->mUnderruns++;
+                        LOG_UNDERRUN(audio_utils_ns_from_timespec(&newTs));
                         mIgnoreNextOverrun = true;
                     } else if (nsec < mOverrunNs) {
                         if (mIgnoreNextOverrun) {
@@ -279,6 +282,7 @@
                             ALOGV("overrun: time since last cycle %d.%03ld sec",
                                     (int) sec, nsec / 1000000L);
                             mDumpState->mOverruns++;
+                            LOG_OVERRUN(audio_utils_ns_from_timespec(&newTs));
                         }
                         // This forces a minimum cycle time. It:
                         //  - compensates for an audio HAL with jitter due to sample rate conversion
@@ -339,6 +343,7 @@
                     // these stores #1, #2, #3 are not atomic with respect to each other,
                     // or with respect to store #4 below
                     mDumpState->mMonotonicNs[i] = monotonicNs;
+                    LOG_WORK_TIME(monotonicNs);
                     mDumpState->mLoadNs[i] = loadNs;
 #ifdef CPU_FREQUENCY_STATISTICS
                     mDumpState->mCpukHz[i] = kHz;
diff --git a/services/audioflinger/FastThread.h b/services/audioflinger/FastThread.h
index 2a71414..3f6b206 100644
--- a/services/audioflinger/FastThread.h
+++ b/services/audioflinger/FastThread.h
@@ -78,12 +78,11 @@
     unsigned        mColdGen;       // last observed mColdGen
     bool            mIsWarm;        // true means ready to mix,
                                     // false means wait for warmup before mixing
-    struct timespec mMeasuredWarmupTs;  // how long did it take for warmup to complete
-    uint32_t        mWarmupCycles;  // counter of number of loop cycles during warmup phase
-    uint32_t        mWarmupConsecutiveInRangeCycles;    // number of consecutive cycles in range
-    NBLog::Writer   mDummyNBLogWriter;
-    NBLog::Writer*  mNBLogWriter;   // always non-nullptr: real NBLog::Writer* or &mDummyNBLogWriter
-    status_t        mTimestampStatus;
+    struct timespec   mMeasuredWarmupTs;  // how long did it take for warmup to complete
+    uint32_t          mWarmupCycles;  // counter of number of loop cycles during warmup phase
+    uint32_t          mWarmupConsecutiveInRangeCycles;    // number of consecutive cycles in range
+    const sp<NBLog::Writer> mDummyNBLogWriter{new NBLog::Writer()};
+    status_t          mTimestampStatus;
 
     FastThreadState::Command mCommand;
     bool            mAttemptedWrite;
diff --git a/services/audioflinger/MmapTracks.h b/services/audioflinger/MmapTracks.h
index 6f546c3..b83f6b5 100644
--- a/services/audioflinger/MmapTracks.h
+++ b/services/audioflinger/MmapTracks.h
@@ -28,8 +28,10 @@
                             audio_format_t format,
                             audio_channel_mask_t channelMask,
                             audio_session_t sessionId,
+                            bool isOut,
                             uid_t uid,
                             pid_t pid,
+                            pid_t creatorPid,
                             audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
     virtual             ~MmapTrack();
 
@@ -39,8 +41,9 @@
                               audio_session_t triggerSession);
     virtual void        stop();
     virtual bool        isFastTrack() const { return false; }
+            bool        isDirect() const override { return true; }
 
-     static void        appendDumpHeader(String8& result);
+            void        appendDumpHeader(String8& result);
             void        appendDump(String8& result, bool active);
 
                         // protected by MMapThread::mLock
diff --git a/services/audioflinger/NBAIO_Tee.cpp b/services/audioflinger/NBAIO_Tee.cpp
new file mode 100644
index 0000000..53083d5
--- /dev/null
+++ b/services/audioflinger/NBAIO_Tee.cpp
@@ -0,0 +1,517 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "NBAIO_Tee"
+//#define LOG_NDEBUG 0
+
+#include <utils/Log.h>
+
+#include <deque>
+#include <dirent.h>
+#include <future>
+#include <list>
+#include <vector>
+
+#include <audio_utils/format.h>
+#include <audio_utils/sndfile.h>
+#include <media/nbaio/PipeReader.h>
+
+#include "Configuration.h"
+#include "NBAIO_Tee.h"
+
+// Enabled with TEE_SINK in Configuration.h
+#ifdef TEE_SINK
+
+namespace android {
+
+/*
+ Tee filenames generated as follows:
+
+ "aftee_Date_ThreadId_C_reason.wav" RecordThread
+ "aftee_Date_ThreadId_M_reason.wav" MixerThread (Normal)
+ "aftee_Date_ThreadId_F_reason.wav" MixerThread (Fast)
+ "aftee_Date_ThreadId_TrackId_R_reason.wav" RecordTrack
+ "aftee_Date_ThreadId_TrackId_TrackName_T_reason.wav" PlaybackTrack
+
+ where Date = YYYYmmdd_HHMMSS_MSEC
+
+ where Reason = [ DTOR | DUMP | REMOVE ]
+
+ Examples:
+  aftee_20180424_153811_038_13_57_2_T_REMOVE.wav
+  aftee_20180424_153811_218_13_57_2_T_REMOVE.wav
+  aftee_20180424_153811_378_13_57_2_T_REMOVE.wav
+  aftee_20180424_153825_147_62_C_DUMP.wav
+  aftee_20180424_153825_148_62_59_R_DUMP.wav
+  aftee_20180424_153825_149_13_F_DUMP.wav
+  aftee_20180424_153842_125_62_59_R_REMOVE.wav
+  aftee_20180424_153842_168_62_C_DTOR.wav
+*/
+
+static constexpr char DEFAULT_PREFIX[] = "aftee_";
+static constexpr char DEFAULT_DIRECTORY[] = "/data/misc/audioserver";
+static constexpr size_t DEFAULT_THREADPOOL_SIZE = 8;
+
+/** AudioFileHandler manages temporary audio wav files with a least recently created
+    retention policy.
+
+    The temporary filenames are systematically generated. A common filename prefix,
+    storage directory, and concurrency pool are passed in on creating the object.
+
+    Temporary files are created by "create", which returns a filename generated by
+
+    prefix + 14 char date + suffix
+
+    TODO Move to audio_utils.
+    TODO Avoid pointing two AudioFileHandlers to the same directory and prefix
+    as we don't have a prefix specific lock file. */
+
+class AudioFileHandler {
+public:
+
+    AudioFileHandler(const std::string &prefix, const std::string &directory, size_t pool)
+        : mThreadPool(pool)
+        , mPrefix(prefix)
+    {
+        (void)setDirectory(directory);
+    }
+
+    /** returns filename of created audio file, else empty string on failure. */
+    std::string create(
+            std::function<ssize_t /* frames_read */
+                        (void * /* buffer */, size_t /* size_in_frames */)> reader,
+            uint32_t sampleRate,
+            uint32_t channelCount,
+            audio_format_t format,
+            const std::string &suffix);
+
+private:
+    /** sets the current directory. this is currently private to avoid confusion
+        when changing while pending operations are occurring (it's okay, but
+        weakly synchronized). */
+    status_t setDirectory(const std::string &directory);
+
+    /** cleans current directory and returns the directory name done. */
+    status_t clean(std::string *dir = nullptr);
+
+    /** creates an audio file from a reader functor passed in. */
+    status_t createInternal(
+            std::function<ssize_t /* frames_read */
+                        (void * /* buffer */, size_t /* size_in_frames */)> reader,
+            uint32_t sampleRate,
+            uint32_t channelCount,
+            audio_format_t format,
+            const std::string &filename);
+
+    static bool isDirectoryValid(const std::string &directory) {
+        return directory.size() > 0 && directory[0] == '/';
+    }
+
+    std::string generateFilename(const std::string &suffix) const {
+        char fileTime[sizeof("YYYYmmdd_HHMMSS_\0")];
+        struct timeval tv;
+        gettimeofday(&tv, NULL);
+        struct tm tm;
+        localtime_r(&tv.tv_sec, &tm);
+        LOG_ALWAYS_FATAL_IF(strftime(fileTime, sizeof(fileTime), "%Y%m%d_%H%M%S_", &tm) == 0,
+            "incorrect fileTime buffer");
+        char msec[4];
+        (void)snprintf(msec, sizeof(msec), "%03d", (int)(tv.tv_usec / 1000));
+        return mPrefix + fileTime + msec + suffix + ".wav";
+    }
+
+    bool isManagedFilename(const char *name) {
+        constexpr size_t FILENAME_LEN_DATE = 4 + 2 + 2 // %Y%m%d%
+            + 1 + 2 + 2 + 2 // _H%M%S
+            + 1 + 3; //_MSEC
+        const size_t prefixLen = mPrefix.size();
+        const size_t nameLen = strlen(name);
+
+        // reject on size, prefix, and .wav
+        if (nameLen < prefixLen + FILENAME_LEN_DATE + 4 /* .wav */
+             || strncmp(name, mPrefix.c_str(), prefixLen) != 0
+             || strcmp(name + nameLen - 4, ".wav") != 0) {
+            return false;
+        }
+
+        // validate date portion
+        const char *date = name + prefixLen;
+        return std::all_of(date, date + 8, isdigit)
+            && date[8] == '_'
+            && std::all_of(date + 9, date + 15, isdigit)
+            && date[15] == '_'
+            && std::all_of(date + 16, date + 19, isdigit);
+    }
+
+    // yet another ThreadPool implementation.
+    class ThreadPool {
+    public:
+        ThreadPool(size_t size)
+            : mThreadPoolSize(size)
+        { }
+
+        /** launches task "name" with associated function "func".
+            if the threadpool is exhausted, it will launch on calling function */
+        status_t launch(const std::string &name, std::function<status_t()> func);
+
+    private:
+        std::mutex mLock;
+        std::list<std::pair<
+                std::string, std::future<status_t>>> mFutures; // GUARDED_BY(mLock)
+
+        const size_t mThreadPoolSize;
+    } mThreadPool;
+
+    const std::string mPrefix;
+    std::mutex mLock;
+    std::string mDirectory;         // GUARDED_BY(mLock)
+    std::deque<std::string> mFiles; // GUARDED_BY(mLock)  sorted list of files by creation time
+
+    static constexpr size_t FRAMES_PER_READ = 1024;
+    static constexpr size_t MAX_FILES_READ = 1024;
+    static constexpr size_t MAX_FILES_KEEP = 32;
+};
+
+/* static */
+void NBAIO_Tee::NBAIO_TeeImpl::dumpTee(
+        int fd, const NBAIO_SinkSource &sinkSource, const std::string &suffix)
+{
+    // Singleton. Constructed thread-safe on first call, never destroyed.
+    static AudioFileHandler audioFileHandler(
+            DEFAULT_PREFIX, DEFAULT_DIRECTORY, DEFAULT_THREADPOOL_SIZE);
+
+    auto &source = sinkSource.second;
+    if (source.get() == nullptr) {
+        return;
+    }
+
+    const NBAIO_Format format = source->format();
+    bool firstRead = true;
+    std::string filename = audioFileHandler.create(
+            // this functor must not hold references to stack
+            [firstRead, sinkSource] (void *buffer, size_t frames) mutable {
+                    auto &source = sinkSource.second;
+                    ssize_t actualRead = source->read(buffer, frames);
+                    if (actualRead == (ssize_t)OVERRUN && firstRead) {
+                        // recheck once
+                        actualRead = source->read(buffer, frames);
+                    }
+                    firstRead = false;
+                    return actualRead;
+                },
+            Format_sampleRate(format),
+            Format_channelCount(format),
+            format.mFormat,
+            suffix);
+
+    if (fd >= 0 && filename.size() > 0) {
+        dprintf(fd, "tee wrote to %s\n", filename.c_str());
+    }
+}
+
+/* static */
+NBAIO_Tee::NBAIO_TeeImpl::NBAIO_SinkSource NBAIO_Tee::NBAIO_TeeImpl::makeSinkSource(
+        const NBAIO_Format &format, size_t frames, bool *enabled)
+{
+    if (Format_isValid(format) && audio_is_linear_pcm(format.mFormat)) {
+        Pipe *pipe = new Pipe(frames, format);
+        size_t numCounterOffers = 0;
+        const NBAIO_Format offers[1] = {format};
+        ssize_t index = pipe->negotiate(offers, 1, NULL, numCounterOffers);
+        if (index != 0) {
+            ALOGW("pipe failure to negotiate: %zd", index);
+            goto exit;
+        }
+        PipeReader *pipeReader = new PipeReader(*pipe);
+        numCounterOffers = 0;
+        index = pipeReader->negotiate(offers, 1, NULL, numCounterOffers);
+        if (index != 0) {
+            ALOGW("pipeReader failure to negotiate: %zd", index);
+            goto exit;
+        }
+        if (enabled != nullptr) *enabled = true;
+        return {pipe, pipeReader};
+    }
+exit:
+    if (enabled != nullptr) *enabled = false;
+    return {nullptr, nullptr};
+}
+
+std::string AudioFileHandler::create(
+        std::function<ssize_t /* frames_read */
+                    (void * /* buffer */, size_t /* size_in_frames */)> reader,
+        uint32_t sampleRate,
+        uint32_t channelCount,
+        audio_format_t format,
+        const std::string &suffix)
+{
+    const std::string filename = generateFilename(suffix);
+
+    if (mThreadPool.launch(std::string("create ") + filename,
+            [=]() { return createInternal(reader, sampleRate, channelCount, format, filename); })
+            == NO_ERROR) {
+        return filename;
+    }
+    return "";
+}
+
+status_t AudioFileHandler::setDirectory(const std::string &directory)
+{
+    if (!isDirectoryValid(directory)) return BAD_VALUE;
+
+    // TODO: consider using std::filesystem in C++17
+    DIR *dir = opendir(directory.c_str());
+
+    if (dir == nullptr) {
+        ALOGW("%s: cannot open directory %s", __func__, directory.c_str());
+        return BAD_VALUE;
+    }
+
+    size_t toRemove = 0;
+    decltype(mFiles) files;
+
+    while (files.size() < MAX_FILES_READ) {
+        errno = 0;
+        const struct dirent *result = readdir(dir);
+        if (result == nullptr) {
+            ALOGW_IF(errno != 0, "%s: readdir failure %s", __func__, strerror(errno));
+            break;
+        }
+        // is it a managed filename?
+        if (!isManagedFilename(result->d_name)) {
+            continue;
+        }
+        files.emplace_back(result->d_name);
+    }
+    (void)closedir(dir);
+
+    // OPTIMIZATION: we don't need to stat each file, the filenames names are
+    // already (roughly) ordered by creation date.  we use std::deque instead
+    // of std::set for faster insertion and sorting times.
+
+    if (files.size() > MAX_FILES_KEEP) {
+        // removed files can use a partition (no need to do a full sort).
+        toRemove = files.size() - MAX_FILES_KEEP;
+        std::nth_element(files.begin(), files.begin() + toRemove - 1, files.end());
+    }
+
+    // kept files must be sorted.
+    std::sort(files.begin() + toRemove, files.end());
+
+    {
+        std::lock_guard<std::mutex> _l(mLock);
+
+        mDirectory = directory;
+        mFiles = std::move(files);
+    }
+
+    if (toRemove > 0) { // launch a clean in background.
+        (void)mThreadPool.launch(
+                std::string("cleaning ") + directory, [this]() { return clean(); });
+    }
+    return NO_ERROR;
+}
+
+status_t AudioFileHandler::clean(std::string *directory)
+{
+    std::vector<std::string> filesToRemove;
+    std::string dir;
+    {
+        std::lock_guard<std::mutex> _l(mLock);
+
+        if (!isDirectoryValid(mDirectory)) return NO_INIT;
+
+        dir = mDirectory;
+        if (mFiles.size() > MAX_FILES_KEEP) {
+            size_t toRemove = mFiles.size() - MAX_FILES_KEEP;
+
+            // use move and erase to efficiently transfer std::string
+            std::move(mFiles.begin(),
+                    mFiles.begin() + toRemove,
+                    std::back_inserter(filesToRemove));
+            mFiles.erase(mFiles.begin(), mFiles.begin() + toRemove);
+        }
+    }
+
+    std::string dirp = dir + "/";
+    // remove files outside of lock for better concurrency.
+    for (const auto &file : filesToRemove) {
+        (void)unlink((dirp + file).c_str());
+    }
+
+    // return the directory if requested.
+    if (directory != nullptr) {
+        *directory = dir;
+    }
+    return NO_ERROR;
+}
+
+status_t AudioFileHandler::ThreadPool::launch(
+        const std::string &name, std::function<status_t()> func)
+{
+    if (mThreadPoolSize > 1) {
+        std::lock_guard<std::mutex> _l(mLock);
+        if (mFutures.size() >= mThreadPoolSize) {
+            for (auto it = mFutures.begin(); it != mFutures.end();) {
+                const std::string &filename = it->first;
+                std::future<status_t> &future = it->second;
+                if (!future.valid() ||
+                        future.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
+                    ALOGV("%s: future %s ready", __func__, filename.c_str());
+                    it = mFutures.erase(it);
+                } else {
+                    ALOGV("%s: future %s not ready", __func__, filename.c_str());
+                    ++it;
+                }
+            }
+        }
+        if (mFutures.size() < mThreadPoolSize) {
+            ALOGV("%s: deferred calling %s", __func__, name.c_str());
+            mFutures.emplace_back(name, std::async(std::launch::async, func));
+            return NO_ERROR;
+        }
+    }
+    ALOGV("%s: immediate calling %s", __func__, name.c_str());
+    return func();
+}
+
+status_t AudioFileHandler::createInternal(
+        std::function<ssize_t /* frames_read */
+                    (void * /* buffer */, size_t /* size_in_frames */)> reader,
+        uint32_t sampleRate,
+        uint32_t channelCount,
+        audio_format_t format,
+        const std::string &filename)
+{
+    // Attempt to choose the best matching file format.
+    // We can choose any sf_format
+    // but writeFormat must be one of 16, 32, float
+    // due to sf_writef compatibility.
+    int sf_format;
+    audio_format_t writeFormat;
+    switch (format) {
+    case AUDIO_FORMAT_PCM_8_BIT:
+    case AUDIO_FORMAT_PCM_16_BIT:
+        sf_format = SF_FORMAT_PCM_16;
+        writeFormat = AUDIO_FORMAT_PCM_16_BIT;
+        ALOGV("%s: %s using PCM_16 for format %#x", __func__, filename.c_str(), format);
+        break;
+    case AUDIO_FORMAT_PCM_8_24_BIT:
+    case AUDIO_FORMAT_PCM_24_BIT_PACKED:
+    case AUDIO_FORMAT_PCM_32_BIT:
+        sf_format = SF_FORMAT_PCM_32;
+        writeFormat = AUDIO_FORMAT_PCM_32_BIT;
+        ALOGV("%s: %s using PCM_32 for format %#x", __func__, filename.c_str(), format);
+        break;
+    case AUDIO_FORMAT_PCM_FLOAT:
+        sf_format = SF_FORMAT_FLOAT;
+        writeFormat = AUDIO_FORMAT_PCM_FLOAT;
+        ALOGV("%s: %s using PCM_FLOAT for format %#x", __func__, filename.c_str(), format);
+        break;
+    default:
+        // TODO:
+        // handle audio_has_proportional_frames() formats.
+        // handle compressed formats as single byte files.
+        return BAD_VALUE;
+    }
+
+    std::string directory;
+    status_t status = clean(&directory);
+    if (status != NO_ERROR) return status;
+    std::string dirPrefix = directory + "/";
+
+    const std::string path = dirPrefix + filename;
+
+    /* const */ SF_INFO info = {
+        .frames = 0,
+        .samplerate = (int)sampleRate,
+        .channels = (int)channelCount,
+        .format = SF_FORMAT_WAV | sf_format,
+    };
+    SNDFILE *sf = sf_open(path.c_str(), SFM_WRITE, &info);
+    if (sf == nullptr) {
+        return INVALID_OPERATION;
+    }
+
+    size_t total = 0;
+    void *buffer = malloc(FRAMES_PER_READ * std::max(
+            channelCount * audio_bytes_per_sample(writeFormat), //output framesize
+            channelCount * audio_bytes_per_sample(format))); // input framesize
+    if (buffer == nullptr) {
+        sf_close(sf);
+        return NO_MEMORY;
+    }
+
+    for (;;) {
+        const ssize_t actualRead = reader(buffer, FRAMES_PER_READ);
+        if (actualRead <= 0) {
+            break;
+        }
+
+        // Convert input format to writeFormat as needed.
+        if (format != writeFormat) {
+            memcpy_by_audio_format(
+                    buffer, writeFormat, buffer, format, actualRead * info.channels);
+        }
+
+        ssize_t reallyWritten;
+        switch (writeFormat) {
+        case AUDIO_FORMAT_PCM_16_BIT:
+            reallyWritten = sf_writef_short(sf, (const int16_t *)buffer, actualRead);
+            break;
+        case AUDIO_FORMAT_PCM_32_BIT:
+            reallyWritten = sf_writef_int(sf, (const int32_t *)buffer, actualRead);
+            break;
+        case AUDIO_FORMAT_PCM_FLOAT:
+            reallyWritten = sf_writef_float(sf, (const float *)buffer, actualRead);
+            break;
+        default:
+            LOG_ALWAYS_FATAL("%s: %s writeFormat: %#x", __func__, filename.c_str(), writeFormat);
+            break;
+        }
+
+        if (reallyWritten < 0) {
+            ALOGW("%s: %s write error: %zd", __func__, filename.c_str(), reallyWritten);
+            break;
+        }
+        total += reallyWritten;
+        if (reallyWritten < actualRead) {
+            ALOGW("%s: %s write short count: %zd < %zd",
+                     __func__, filename.c_str(), reallyWritten, actualRead);
+            break;
+        }
+    }
+    sf_close(sf);
+    free(buffer);
+    if (total == 0) {
+        (void)unlink(path.c_str());
+        return NOT_ENOUGH_DATA;
+    }
+
+    // Success: add our name to managed files.
+    {
+        std::lock_guard<std::mutex> _l(mLock);
+        // weak synchronization - only update mFiles if the directory hasn't changed.
+        if (mDirectory == directory) {
+            mFiles.emplace_back(filename);  // add to the end to preserve sort.
+        }
+    }
+    return NO_ERROR; // return full path
+}
+
+} // namespace android
+
+#endif // TEE_SINK
diff --git a/services/audioflinger/NBAIO_Tee.h b/services/audioflinger/NBAIO_Tee.h
new file mode 100644
index 0000000..fed8cc8
--- /dev/null
+++ b/services/audioflinger/NBAIO_Tee.h
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Enabled with TEE_SINK in Configuration.h
+#ifndef ANDROID_NBAIO_TEE_H
+#define ANDROID_NBAIO_TEE_H
+
+#ifdef TEE_SINK
+
+#include <atomic>
+#include <mutex>
+#include <set>
+
+#include <cutils/properties.h>
+#include <media/nbaio/NBAIO.h>
+
+namespace android {
+
+/**
+ * The NBAIO_Tee uses the NBAIO Pipe and PipeReader for nonblocking
+ * data collection, for eventual dump to log files.
+ * See https://source.android.com/devices/audio/debugging for how to
+ * enable by ro.debuggable and af.tee properties.
+ *
+ * The write() into the NBAIO_Tee is therefore nonblocking,
+ * but changing NBAIO_Tee formats with set() cannot be done during a write();
+ * usually the caller already implements this mutual exclusion.
+ *
+ * All other calls except set() vs write() may occur at any time.
+ *
+ * dump() disruption is minimized to the caller since system calls are executed
+ * in an asynchronous thread (when possible).
+ *
+ * Currently the NBAIO_Tee is "hardwired" for AudioFlinger support.
+ *
+ * Some AudioFlinger specific notes:
+ *
+ * 1) Tees capture only linear PCM data.
+ * 2) Tees without any data written are considered empty and do not generate
+ *    any output files.
+ * 2) Once a Tee dumps data, it is considered "emptied" and new data
+ *    needs to be written before another Tee file is generated.
+ * 3) Tee file format is
+ *    WAV integer PCM 16 bit for AUDIO_FORMAT_PCM_8_BIT, AUDIO_FORMAT_PCM_16_BIT.
+ *    WAV integer PCM 32 bit for AUDIO_FORMAT_PCM_8_24_BIT, AUDIO_FORMAT_PCM_24_BIT_PACKED
+ *                               AUDIO_FORMAT_PCM_32_BIT.
+ *    WAV float PCM 32 bit for AUDIO_FORMAT_PCM_FLOAT.
+ *
+ * Input_Thread:
+ * 1) Capture buffer is teed when read from the HAL, before resampling for the AudioRecord
+ *    client.
+ *
+ * Output_Thread:
+ * 1) MixerThreads will tee at the FastMixer output (if it has one) or at the
+ *    NormalMixer output (if no FastMixer).
+ * 2) DuplicatingThreads do not tee any mixed data. Apply a tee on the downstream OutputTrack
+ *    or on the upstream playback Tracks.
+ * 3) DirectThreads and OffloadThreads do not tee any data. The upstream track
+ *    (if linear PCM format) may be teed to discover data.
+ * 4) MmapThreads are not supported.
+ *
+ * Tracks:
+ * 1) RecordTracks and playback Tracks tee as data is being written to or
+ *    read from the shared client-server track buffer by the associated Threads.
+ * 2) The mechanism is on the AudioBufferProvider release() so large static Track
+ *    playback may not show any Tee data depending on when it is released.
+ * 3) When a track becomes inactive, the Thread will trigger a dump.
+ */
+
+class NBAIO_Tee {
+public:
+    /* TEE_FLAG is used in set() and must match the flags for the af.tee property
+       given in https://source.android.com/devices/audio/debugging
+    */
+    enum TEE_FLAG {
+        TEE_FLAG_NONE = 0,
+        TEE_FLAG_INPUT_THREAD = (1 << 0),  // treat as a Tee for input (Capture) Threads
+        TEE_FLAG_OUTPUT_THREAD = (1 << 1), // treat as a Tee for output (Playback) Threads
+        TEE_FLAG_TRACK = (1 << 2),         // treat as a Tee for tracks (Record and Playback)
+    };
+
+    NBAIO_Tee()
+        : mTee(std::make_shared<NBAIO_TeeImpl>())
+    {
+        getRunningTees().add(mTee);
+    }
+
+    ~NBAIO_Tee() {
+        getRunningTees().remove(mTee);
+        dump(-1, "_DTOR"); // log any data remaining in Tee.
+    }
+
+    /**
+     * \brief set is used for deferred configuration of Tee.
+     *
+     *  May be called anytime except concurrently with write().
+     *
+     * \param format NBAIO_Format used to open NBAIO pipes
+     * \param flags (https://source.android.com/devices/audio/debugging)
+     *              - TEE_FLAG_NONE to bypass af.tee property checks (default);
+     *              - TEE_FLAG_INPUT_THREAD to check af.tee if input thread logging set;
+     *              - TEE_FLAG_OUTPUT_THREAD to check af.tee if output thread logging set;
+     *              - TEE_FLAG_TRACK to check af.tee if track logging set.
+     * \param frames number of frames to open the NBAIO pipe (set to 0 to use default).
+     *
+     * \return
+     *         - NO_ERROR on success (or format unchanged)
+     *         - BAD_VALUE if format or flags invalid.
+     *         - PERMISSION_DENIED if flags not allowed by af.tee
+     */
+
+    status_t set(const NBAIO_Format &format,
+            TEE_FLAG flags = TEE_FLAG_NONE, size_t frames = 0) const {
+        return mTee->set(format, flags, frames);
+    }
+
+    status_t set(uint32_t sampleRate, uint32_t channelCount, audio_format_t format,
+            TEE_FLAG flags = TEE_FLAG_NONE, size_t frames = 0) const {
+        return mTee->set(Format_from_SR_C(sampleRate, channelCount, format), flags, frames);
+    }
+
+    /**
+     * \brief write data to the tee.
+     *
+     * This call is lock free (as shared pointer and NBAIO is lock free);
+     * may be called simultaneous to all methods except set().
+     *
+     * \param buffer to write to pipe.
+     * \param frameCount in frames as specified by the format passed to set()
+     */
+
+    void write(const void *buffer, size_t frameCount) const {
+        mTee->write(buffer, frameCount);
+    }
+
+    /** sets Tee id string which identifies the generated file (should be unique). */
+    void setId(const std::string &id) const {
+        mTee->setId(id);
+    }
+
+    /**
+     * \brief dump the audio content written to the Tee.
+     *
+     * \param fd file descriptor to write dumped filename for logging, use -1 to ignore.
+     * \param reason string suffix to append to the generated file.
+     */
+    void dump(int fd, const std::string &reason = "") const {
+        mTee->dump(fd, reason);
+    }
+
+    /**
+     * \brief dump all Tees currently alive.
+     *
+     * \param fd file descriptor to write dumped filename for logging, use -1 to ignore.
+     * \param reason string suffix to append to the generated file.
+     */
+    static void dumpAll(int fd, const std::string &reason = "") {
+        getRunningTees().dump(fd, reason);
+    }
+
+private:
+
+    /** The underlying implementation of the Tee - the lifetime is through
+        a shared pointer so destruction of the NBAIO_Tee container may proceed
+        even though dumping is occurring. */
+    class NBAIO_TeeImpl {
+    public:
+        status_t set(const NBAIO_Format &format, TEE_FLAG flags, size_t frames) {
+            static const int teeConfig = property_get_bool("ro.debuggable", false)
+                   ? property_get_int32("af.tee", 0) : 0;
+
+            // check the type of Tee
+            const TEE_FLAG type = TEE_FLAG(
+                    flags & (TEE_FLAG_INPUT_THREAD | TEE_FLAG_OUTPUT_THREAD | TEE_FLAG_TRACK));
+
+            // parameter flags can't select multiple types.
+            if (__builtin_popcount(type) > 1) {
+                return BAD_VALUE;
+            }
+
+            // if type is set, we check to see if it is permitted by configuration.
+            if (type != 0 && (type & teeConfig) == 0) {
+                return PERMISSION_DENIED;
+            }
+
+            // determine number of frames for Tee
+            if (frames == 0) {
+                // TODO: consider varying frame count based on type.
+                frames = DEFAULT_TEE_FRAMES;
+            }
+
+            // TODO: should we check minimum number of frames?
+
+            // don't do anything if format and frames are the same.
+            if (Format_isEqual(format, mFormat) && frames == mFrames) {
+                return NO_ERROR;
+            }
+
+            bool enabled = false;
+            auto sinksource = makeSinkSource(format, frames, &enabled);
+
+            // enabled is set if makeSinkSource is successful.
+            // Note: as mentioned in NBAIO_Tee::set(), don't call set() while write() is
+            // ongoing.
+            if (enabled) {
+                std::lock_guard<std::mutex> _l(mLock);
+                mFlags = flags;
+                mFormat = format; // could get this from the Sink.
+                mFrames = frames;
+                mSinkSource = std::move(sinksource);
+                mEnabled.store(true);
+                return NO_ERROR;
+            }
+            return BAD_VALUE;
+        }
+
+        void setId(const std::string &id) {
+            std::lock_guard<std::mutex> _l(mLock);
+            mId = id;
+        }
+
+        void dump(int fd, const std::string &reason) {
+            if (!mDataReady.exchange(false)) return;
+            std::string suffix;
+            NBAIO_SinkSource sinkSource;
+            {
+                std::lock_guard<std::mutex> _l(mLock);
+                suffix = mId + reason;
+                sinkSource = mSinkSource;
+            }
+            dumpTee(fd, sinkSource, suffix);
+        }
+
+        void write(const void *buffer, size_t frameCount) {
+            if (!mEnabled.load() || frameCount == 0) return;
+            (void)mSinkSource.first->write(buffer, frameCount);
+            mDataReady.store(true);
+        }
+
+    private:
+        // TRICKY: We need to keep the NBAIO_Sink and NBAIO_Source both alive at the same time
+        // because PipeReader holds a naked reference (not a strong or weak pointer) to Pipe.
+        using NBAIO_SinkSource = std::pair<sp<NBAIO_Sink>, sp<NBAIO_Source>>;
+
+        static void dumpTee(int fd, const NBAIO_SinkSource& sinkSource, const std::string& suffix);
+
+        static NBAIO_SinkSource makeSinkSource(
+                const NBAIO_Format &format, size_t frames, bool *enabled);
+
+        // 0x200000 stereo 16-bit PCM frames = 47.5 seconds at 44.1 kHz, 8 megabytes
+        static constexpr size_t DEFAULT_TEE_FRAMES = 0x200000;
+
+        // atomic status checking
+        std::atomic<bool> mEnabled{false};
+        std::atomic<bool> mDataReady{false};
+
+        // locked dump information
+        mutable std::mutex mLock;
+        std::string mId;                                         // GUARDED_BY(mLock)
+        TEE_FLAG mFlags = TEE_FLAG_NONE;                         // GUARDED_BY(mLock)
+        NBAIO_Format mFormat = Format_Invalid;                   // GUARDED_BY(mLock)
+        size_t mFrames = 0;                                      // GUARDED_BY(mLock)
+        NBAIO_SinkSource mSinkSource;                            // GUARDED_BY(mLock)
+    };
+
+    /** RunningTees tracks current running tees for dump purposes.
+        It is implemented to have minimal locked regions, to be transparent to the caller. */
+    class RunningTees {
+    public:
+        void add(const std::shared_ptr<NBAIO_TeeImpl> &tee) {
+            std::lock_guard<std::mutex> _l(mLock);
+            ALOGW_IF(!mTees.emplace(tee).second,
+                    "%s: %p already exists in mTees", __func__, tee.get());
+        }
+
+        void remove(const std::shared_ptr<NBAIO_TeeImpl> &tee) {
+            std::lock_guard<std::mutex> _l(mLock);
+            ALOGW_IF(mTees.erase(tee) != 1,
+                    "%s: %p doesn't exist in mTees", __func__, tee.get());
+        }
+
+        void dump(int fd, const std::string &reason) {
+            std::vector<std::shared_ptr<NBAIO_TeeImpl>> tees; // safe snapshot of tees
+            {
+                std::lock_guard<std::mutex> _l(mLock);
+                tees.insert(tees.end(), mTees.begin(), mTees.end());
+            }
+            for (const auto &tee : tees) {
+                tee->dump(fd, reason);
+            }
+        }
+
+    private:
+        std::mutex mLock;
+        std::set<std::shared_ptr<NBAIO_TeeImpl>> mTees; // GUARDED_BY(mLock)
+    };
+
+    // singleton
+    static RunningTees &getRunningTees() {
+        static RunningTees runningTees;
+        return runningTees;
+    }
+
+    // The NBAIO TeeImpl may have lifetime longer than NBAIO_Tee if
+    // RunningTees::dump() is being called simultaneous to ~NBAIO_Tee().
+    // This is allowed for maximum concurrency.
+    const std::shared_ptr<NBAIO_TeeImpl> mTee;
+}; // NBAIO_Tee
+
+} // namespace android
+
+#endif // TEE_SINK
+#endif // !ANDROID_NBAIO_TEE_H
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index e5cb8a2..edb331d 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -24,8 +24,9 @@
 #include <audio_utils/primitives.h>
 
 #include "AudioFlinger.h"
-#include "ServiceUtilities.h"
 #include <media/AudioParameter.h>
+#include <media/PatchBuilder.h>
+#include <mediautils/ServiceUtilities.h>
 
 // ----------------------------------------------------------------------------
 
@@ -49,111 +50,77 @@
                                 struct audio_port *ports)
 {
     Mutex::Autolock _l(mLock);
-    if (mPatchPanel != 0) {
-        return mPatchPanel->listAudioPorts(num_ports, ports);
-    }
-    return NO_INIT;
+    return mPatchPanel.listAudioPorts(num_ports, ports);
 }
 
 /* Get supported attributes for a given audio port */
 status_t AudioFlinger::getAudioPort(struct audio_port *port)
 {
     Mutex::Autolock _l(mLock);
-    if (mPatchPanel != 0) {
-        return mPatchPanel->getAudioPort(port);
-    }
-    return NO_INIT;
+    return mPatchPanel.getAudioPort(port);
 }
 
-
 /* Connect a patch between several source and sink ports */
 status_t AudioFlinger::createAudioPatch(const struct audio_patch *patch,
                                    audio_patch_handle_t *handle)
 {
     Mutex::Autolock _l(mLock);
-    if (mPatchPanel != 0) {
-        return mPatchPanel->createAudioPatch(patch, handle);
-    }
-    return NO_INIT;
+    return mPatchPanel.createAudioPatch(patch, handle);
 }
 
 /* Disconnect a patch */
 status_t AudioFlinger::releaseAudioPatch(audio_patch_handle_t handle)
 {
     Mutex::Autolock _l(mLock);
-    if (mPatchPanel != 0) {
-        return mPatchPanel->releaseAudioPatch(handle);
-    }
-    return NO_INIT;
+    return mPatchPanel.releaseAudioPatch(handle);
 }
 
-
 /* List connected audio ports and they attributes */
 status_t AudioFlinger::listAudioPatches(unsigned int *num_patches,
                                   struct audio_patch *patches)
 {
     Mutex::Autolock _l(mLock);
-    if (mPatchPanel != 0) {
-        return mPatchPanel->listAudioPatches(num_patches, patches);
+    return mPatchPanel.listAudioPatches(num_patches, patches);
+}
+
+status_t AudioFlinger::PatchPanel::SoftwarePatch::getLatencyMs_l(double *latencyMs) const
+{
+    const auto& iter = mPatchPanel.mPatches.find(mPatchHandle);
+    if (iter != mPatchPanel.mPatches.end()) {
+        return iter->second.getLatencyMs(latencyMs);
+    } else {
+        return BAD_VALUE;
     }
-    return NO_INIT;
-}
-
-/* Set audio port configuration */
-status_t AudioFlinger::setAudioPortConfig(const struct audio_port_config *config)
-{
-    Mutex::Autolock _l(mLock);
-    if (mPatchPanel != 0) {
-        return mPatchPanel->setAudioPortConfig(config);
-    }
-    return NO_INIT;
-}
-
-
-AudioFlinger::PatchPanel::PatchPanel(const sp<AudioFlinger>& audioFlinger)
-                                   : mAudioFlinger(audioFlinger)
-{
-}
-
-AudioFlinger::PatchPanel::~PatchPanel()
-{
 }
 
 /* List connected audio ports and their attributes */
 status_t AudioFlinger::PatchPanel::listAudioPorts(unsigned int *num_ports __unused,
                                 struct audio_port *ports __unused)
 {
-    ALOGV("listAudioPorts");
+    ALOGV(__func__);
     return NO_ERROR;
 }
 
 /* Get supported attributes for a given audio port */
 status_t AudioFlinger::PatchPanel::getAudioPort(struct audio_port *port __unused)
 {
-    ALOGV("getAudioPort");
+    ALOGV(__func__);
     return NO_ERROR;
 }
 
-
 /* Connect a patch between several source and sink ports */
 status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *patch,
                                    audio_patch_handle_t *handle)
 {
-    status_t status = NO_ERROR;
-    audio_patch_handle_t halHandle = AUDIO_PATCH_HANDLE_NONE;
-    sp<AudioFlinger> audioflinger = mAudioFlinger.promote();
     if (handle == NULL || patch == NULL) {
         return BAD_VALUE;
     }
-    ALOGV("createAudioPatch() num_sources %d num_sinks %d handle %d",
-          patch->num_sources, patch->num_sinks, *handle);
-    if (audioflinger == 0) {
-        return NO_INIT;
-    }
+    ALOGV("%s() num_sources %d num_sinks %d handle %d",
+            __func__, patch->num_sources, patch->num_sinks, *handle);
+    status_t status = NO_ERROR;
+    audio_patch_handle_t halHandle = AUDIO_PATCH_HANDLE_NONE;
 
-    if (patch->num_sources == 0 || patch->num_sources > AUDIO_PATCH_PORTS_MAX ||
-            (patch->num_sinks == 0 && patch->num_sources != 2) ||
-            patch->num_sinks > AUDIO_PATCH_PORTS_MAX) {
+    if (!audio_patch_is_valid(patch) || (patch->num_sinks == 0 && patch->num_sources != 2)) {
         return BAD_VALUE;
     }
     // limit number of sources to 1 for now or 2 sources for special cross hw module case.
@@ -163,81 +130,73 @@
     }
 
     if (*handle != AUDIO_PATCH_HANDLE_NONE) {
-        for (size_t index = 0; *handle != 0 && index < mPatches.size(); index++) {
-            if (*handle == mPatches[index]->mHandle) {
-                ALOGV("createAudioPatch() removing patch handle %d", *handle);
-                halHandle = mPatches[index]->mHalHandle;
-                Patch *removedPatch = mPatches[index];
-                // free resources owned by the removed patch if applicable
-                // 1) if a software patch is present, release the playback and capture threads and
-                // tracks created. This will also release the corresponding audio HAL patches
-                if ((removedPatch->mRecordPatchHandle
-                        != AUDIO_PATCH_HANDLE_NONE) ||
-                        (removedPatch->mPlaybackPatchHandle !=
-                                AUDIO_PATCH_HANDLE_NONE)) {
-                    clearPatchConnections(removedPatch);
-                }
-                // 2) if the new patch and old patch source or sink are devices from different
-                // hw modules,  clear the audio HAL patches now because they will not be updated
-                // by call to create_audio_patch() below which will happen on a different HW module
-                if (halHandle != AUDIO_PATCH_HANDLE_NONE) {
-                    audio_module_handle_t hwModule = AUDIO_MODULE_HANDLE_NONE;
-                    if ((removedPatch->mAudioPatch.sources[0].type == AUDIO_PORT_TYPE_DEVICE) &&
-                        ((patch->sources[0].type != AUDIO_PORT_TYPE_DEVICE) ||
-                          (removedPatch->mAudioPatch.sources[0].ext.device.hw_module !=
-                           patch->sources[0].ext.device.hw_module))) {
-                        hwModule = removedPatch->mAudioPatch.sources[0].ext.device.hw_module;
-                    } else if ((patch->num_sinks == 0) ||
-                            ((removedPatch->mAudioPatch.sinks[0].type == AUDIO_PORT_TYPE_DEVICE) &&
-                             ((patch->sinks[0].type != AUDIO_PORT_TYPE_DEVICE) ||
-                              (removedPatch->mAudioPatch.sinks[0].ext.device.hw_module !=
-                               patch->sinks[0].ext.device.hw_module)))) {
-                        // Note on (patch->num_sinks == 0): this situation should not happen as
-                        // these special patches are only created by the policy manager but just
-                        // in case, systematically clear the HAL patch.
-                        // Note that removedPatch->mAudioPatch.num_sinks cannot be 0 here because
-                        // halHandle would be AUDIO_PATCH_HANDLE_NONE in this case.
-                        hwModule = removedPatch->mAudioPatch.sinks[0].ext.device.hw_module;
-                    }
-                    if (hwModule != AUDIO_MODULE_HANDLE_NONE) {
-                        ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(hwModule);
-                        if (index >= 0) {
-                            sp<DeviceHalInterface> hwDevice =
-                                    audioflinger->mAudioHwDevs.valueAt(index)->hwDevice();
-                            hwDevice->releaseAudioPatch(halHandle);
-                        }
-                    }
-                }
-                mPatches.removeAt(index);
-                delete removedPatch;
-                break;
+        auto iter = mPatches.find(*handle);
+        if (iter != mPatches.end()) {
+            ALOGV("%s() removing patch handle %d", __func__, *handle);
+            Patch &removedPatch = iter->second;
+            // free resources owned by the removed patch if applicable
+            // 1) if a software patch is present, release the playback and capture threads and
+            // tracks created. This will also release the corresponding audio HAL patches
+            if (removedPatch.isSoftware()) {
+                removedPatch.clearConnections(this);
             }
+            // 2) if the new patch and old patch source or sink are devices from different
+            // hw modules,  clear the audio HAL patches now because they will not be updated
+            // by call to create_audio_patch() below which will happen on a different HW module
+            if (removedPatch.mHalHandle != AUDIO_PATCH_HANDLE_NONE) {
+                audio_module_handle_t hwModule = AUDIO_MODULE_HANDLE_NONE;
+                const struct audio_patch &oldPatch = removedPatch.mAudioPatch;
+                if (oldPatch.sources[0].type == AUDIO_PORT_TYPE_DEVICE &&
+                        (patch->sources[0].type != AUDIO_PORT_TYPE_DEVICE ||
+                                oldPatch.sources[0].ext.device.hw_module !=
+                                patch->sources[0].ext.device.hw_module)) {
+                    hwModule = oldPatch.sources[0].ext.device.hw_module;
+                } else if (patch->num_sinks == 0 ||
+                        (oldPatch.sinks[0].type == AUDIO_PORT_TYPE_DEVICE &&
+                                (patch->sinks[0].type != AUDIO_PORT_TYPE_DEVICE ||
+                                        oldPatch.sinks[0].ext.device.hw_module !=
+                                        patch->sinks[0].ext.device.hw_module))) {
+                    // Note on (patch->num_sinks == 0): this situation should not happen as
+                    // these special patches are only created by the policy manager but just
+                    // in case, systematically clear the HAL patch.
+                    // Note that removedPatch.mAudioPatch.num_sinks cannot be 0 here because
+                    // removedPatch.mHalHandle would be AUDIO_PATCH_HANDLE_NONE in this case.
+                    hwModule = oldPatch.sinks[0].ext.device.hw_module;
+                }
+                sp<DeviceHalInterface> hwDevice = findHwDeviceByModule(hwModule);
+                if (hwDevice != 0) {
+                    hwDevice->releaseAudioPatch(removedPatch.mHalHandle);
+                }
+            }
+            mPatches.erase(iter);
+            removeSoftwarePatchFromInsertedModules(*handle);
         }
     }
 
-    Patch *newPatch = new Patch(patch);
+    Patch newPatch{*patch};
+    audio_module_handle_t insertedModule = AUDIO_MODULE_HANDLE_NONE;
 
     switch (patch->sources[0].type) {
         case AUDIO_PORT_TYPE_DEVICE: {
             audio_module_handle_t srcModule = patch->sources[0].ext.device.hw_module;
-            ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(srcModule);
-            if (index < 0) {
-                ALOGW("createAudioPatch() bad src hw module %d", srcModule);
+            AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule(srcModule);
+            if (!audioHwDevice) {
                 status = BAD_VALUE;
                 goto exit;
             }
-            AudioHwDevice *audioHwDevice = audioflinger->mAudioHwDevs.valueAt(index);
             for (unsigned int i = 0; i < patch->num_sinks; i++) {
                 // support only one sink if connection to a mix or across HW modules
                 if ((patch->sinks[i].type == AUDIO_PORT_TYPE_MIX ||
-                        patch->sinks[i].ext.mix.hw_module != srcModule) &&
+                                (patch->sinks[i].type == AUDIO_PORT_TYPE_DEVICE &&
+                                        patch->sinks[i].ext.device.hw_module != srcModule)) &&
                         patch->num_sinks > 1) {
+                    ALOGW("%s() multiple sinks for mix or across modules not supported", __func__);
                     status = INVALID_OPERATION;
                     goto exit;
                 }
                 // reject connection to different sink types
                 if (patch->sinks[i].type != patch->sinks[0].type) {
-                    ALOGW("createAudioPatch() different sink types in same patch not supported");
+                    ALOGW("%s() different sink types in same patch not supported", __func__);
                     status = BAD_VALUE;
                     goto exit;
                 }
@@ -252,42 +211,56 @@
                 ((patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) &&
                  ((patch->sinks[0].ext.device.hw_module != srcModule) ||
                   !audioHwDevice->supportsAudioPatches()))) {
+                audio_devices_t outputDevice = patch->sinks[0].ext.device.type;
+                String8 outputDeviceAddress = String8(patch->sinks[0].ext.device.address);
                 if (patch->num_sources == 2) {
                     if (patch->sources[1].type != AUDIO_PORT_TYPE_MIX ||
                             (patch->num_sinks != 0 && patch->sinks[0].ext.device.hw_module !=
                                     patch->sources[1].ext.mix.hw_module)) {
-                        ALOGW("createAudioPatch() invalid source combination");
+                        ALOGW("%s() invalid source combination", __func__);
                         status = INVALID_OPERATION;
                         goto exit;
                     }
 
                     sp<ThreadBase> thread =
-                            audioflinger->checkPlaybackThread_l(patch->sources[1].ext.mix.handle);
-                    newPatch->mPlaybackThread = (MixerThread *)thread.get();
+                            mAudioFlinger.checkPlaybackThread_l(patch->sources[1].ext.mix.handle);
                     if (thread == 0) {
-                        ALOGW("createAudioPatch() cannot get playback thread");
+                        ALOGW("%s() cannot get playback thread", __func__);
                         status = INVALID_OPERATION;
                         goto exit;
                     }
+                    // existing playback thread is reused, so it is not closed when patch is cleared
+                    newPatch.mPlayback.setThread(
+                            reinterpret_cast<PlaybackThread*>(thread.get()), false /*closeThread*/);
                 } else {
                     audio_config_t config = AUDIO_CONFIG_INITIALIZER;
-                    audio_devices_t device = patch->sinks[0].ext.device.type;
-                    String8 address = String8(patch->sinks[0].ext.device.address);
                     audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
-                    sp<ThreadBase> thread = audioflinger->openOutput_l(
+                    audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE;
+                    if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
+                        config.sample_rate = patch->sinks[0].sample_rate;
+                    }
+                    if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
+                        config.channel_mask = patch->sinks[0].channel_mask;
+                    }
+                    if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_FORMAT) {
+                        config.format = patch->sinks[0].format;
+                    }
+                    if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_FLAGS) {
+                        flags = patch->sinks[0].flags.output;
+                    }
+                    sp<ThreadBase> thread = mAudioFlinger.openOutput_l(
                                                             patch->sinks[0].ext.device.hw_module,
                                                             &output,
                                                             &config,
-                                                            device,
-                                                            address,
-                                                            AUDIO_OUTPUT_FLAG_NONE);
-                    newPatch->mPlaybackThread = (PlaybackThread *)thread.get();
-                    ALOGV("audioflinger->openOutput_l() returned %p",
-                                          newPatch->mPlaybackThread.get());
-                    if (newPatch->mPlaybackThread == 0) {
+                                                            outputDevice,
+                                                            outputDeviceAddress,
+                                                            flags);
+                    ALOGV("mAudioFlinger.openOutput_l() returned %p", thread.get());
+                    if (thread == 0) {
                         status = NO_MEMORY;
                         goto exit;
                     }
+                    newPatch.mPlayback.setThread(reinterpret_cast<PlaybackThread*>(thread.get()));
                 }
                 audio_devices_t device = patch->sources[0].ext.device.type;
                 String8 address = String8(patch->sources[0].ext.device.address);
@@ -297,52 +270,67 @@
                 if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
                     config.sample_rate = patch->sources[0].sample_rate;
                 } else {
-                    config.sample_rate = newPatch->mPlaybackThread->sampleRate();
+                    config.sample_rate = newPatch.mPlayback.thread()->sampleRate();
                 }
                 if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
                     config.channel_mask = patch->sources[0].channel_mask;
                 } else {
-                    config.channel_mask =
-                        audio_channel_in_mask_from_count(newPatch->mPlaybackThread->channelCount());
+                    config.channel_mask = audio_channel_in_mask_from_count(
+                            newPatch.mPlayback.thread()->channelCount());
                 }
                 if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_FORMAT) {
                     config.format = patch->sources[0].format;
                 } else {
-                    config.format = newPatch->mPlaybackThread->format();
+                    config.format = newPatch.mPlayback.thread()->format();
                 }
+                audio_input_flags_t flags =
+                        patch->sources[0].config_mask & AUDIO_PORT_CONFIG_FLAGS ?
+                        patch->sources[0].flags.input : AUDIO_INPUT_FLAG_NONE;
                 audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
-                sp<ThreadBase> thread = audioflinger->openInput_l(srcModule,
+                sp<ThreadBase> thread = mAudioFlinger.openInput_l(srcModule,
                                                                     &input,
                                                                     &config,
                                                                     device,
                                                                     address,
                                                                     AUDIO_SOURCE_MIC,
-                                                                    AUDIO_INPUT_FLAG_NONE);
-                newPatch->mRecordThread = (RecordThread *)thread.get();
-                ALOGV("audioflinger->openInput_l() returned %p inChannelMask %08x",
-                      newPatch->mRecordThread.get(), config.channel_mask);
-                if (newPatch->mRecordThread == 0) {
+                                                                    flags,
+                                                                    outputDevice,
+                                                                    outputDeviceAddress);
+                ALOGV("mAudioFlinger.openInput_l() returned %p inChannelMask %08x",
+                      thread.get(), config.channel_mask);
+                if (thread == 0) {
                     status = NO_MEMORY;
                     goto exit;
                 }
-                status = createPatchConnections(newPatch, patch);
+                newPatch.mRecord.setThread(reinterpret_cast<RecordThread*>(thread.get()));
+                status = newPatch.createConnections(this);
                 if (status != NO_ERROR) {
                     goto exit;
                 }
+                if (audioHwDevice->isInsert()) {
+                    insertedModule = audioHwDevice->handle();
+                }
             } else {
                 if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
-                    sp<ThreadBase> thread = audioflinger->checkRecordThread_l(
+                    sp<ThreadBase> thread = mAudioFlinger.checkRecordThread_l(
                                                               patch->sinks[0].ext.mix.handle);
                     if (thread == 0) {
-                        thread = audioflinger->checkMmapThread_l(patch->sinks[0].ext.mix.handle);
+                        thread = mAudioFlinger.checkMmapThread_l(patch->sinks[0].ext.mix.handle);
                         if (thread == 0) {
-                            ALOGW("createAudioPatch() bad capture I/O handle %d",
-                                                                  patch->sinks[0].ext.mix.handle);
+                            ALOGW("%s() bad capture I/O handle %d",
+                                    __func__, patch->sinks[0].ext.mix.handle);
                             status = BAD_VALUE;
                             goto exit;
                         }
                     }
                     status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
+                    // remove stale audio patch with same input as sink if any
+                    for (auto& iter : mPatches) {
+                        if (iter.second.mAudioPatch.sinks[0].ext.mix.handle == thread->id()) {
+                            mPatches.erase(iter.first);
+                            break;
+                        }
+                    }
                 } else {
                     sp<DeviceHalInterface> hwDevice = audioHwDevice->hwDevice();
                     status = hwDevice->createAudioPatch(patch->num_sources,
@@ -356,9 +344,9 @@
         } break;
         case AUDIO_PORT_TYPE_MIX: {
             audio_module_handle_t srcModule =  patch->sources[0].ext.mix.hw_module;
-            ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(srcModule);
+            ssize_t index = mAudioFlinger.mAudioHwDevs.indexOfKey(srcModule);
             if (index < 0) {
-                ALOGW("createAudioPatch() bad src hw module %d", srcModule);
+                ALOGW("%s() bad src hw module %d", __func__, srcModule);
                 status = BAD_VALUE;
                 goto exit;
             }
@@ -366,8 +354,8 @@
             audio_devices_t type = AUDIO_DEVICE_NONE;
             for (unsigned int i = 0; i < patch->num_sinks; i++) {
                 if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
-                    ALOGW("createAudioPatch() invalid sink type %d for mix source",
-                          patch->sinks[i].type);
+                    ALOGW("%s() invalid sink type %d for mix source",
+                            __func__, patch->sinks[i].type);
                     status = BAD_VALUE;
                     goto exit;
                 }
@@ -379,319 +367,451 @@
                 type |= patch->sinks[i].ext.device.type;
             }
             sp<ThreadBase> thread =
-                            audioflinger->checkPlaybackThread_l(patch->sources[0].ext.mix.handle);
+                            mAudioFlinger.checkPlaybackThread_l(patch->sources[0].ext.mix.handle);
             if (thread == 0) {
-                thread = audioflinger->checkMmapThread_l(patch->sources[0].ext.mix.handle);
+                thread = mAudioFlinger.checkMmapThread_l(patch->sources[0].ext.mix.handle);
                 if (thread == 0) {
-                    ALOGW("createAudioPatch() bad playback I/O handle %d",
-                              patch->sources[0].ext.mix.handle);
+                    ALOGW("%s() bad playback I/O handle %d",
+                            __func__, patch->sources[0].ext.mix.handle);
                     status = BAD_VALUE;
                     goto exit;
                 }
             }
-            if (thread == audioflinger->primaryPlaybackThread_l()) {
+            if (thread == mAudioFlinger.primaryPlaybackThread_l()) {
                 AudioParameter param = AudioParameter();
                 param.addInt(String8(AudioParameter::keyRouting), (int)type);
 
-                audioflinger->broacastParametersToRecordThreads_l(param.toString());
+                mAudioFlinger.broacastParametersToRecordThreads_l(param.toString());
             }
 
             status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
+
+            // remove stale audio patch with same output as source if any
+            for (auto& iter : mPatches) {
+                if (iter.second.mAudioPatch.sources[0].ext.mix.handle == thread->id()) {
+                    mPatches.erase(iter.first);
+                    break;
+                }
+            }
         } break;
         default:
             status = BAD_VALUE;
             goto exit;
     }
 exit:
-    ALOGV("createAudioPatch() status %d", status);
+    ALOGV("%s() status %d", __func__, status);
     if (status == NO_ERROR) {
-        *handle = (audio_patch_handle_t) audioflinger->nextUniqueId(AUDIO_UNIQUE_ID_USE_PATCH);
-        newPatch->mHandle = *handle;
-        newPatch->mHalHandle = halHandle;
-        mPatches.add(newPatch);
-        ALOGV("createAudioPatch() added new patch handle %d halHandle %d", *handle, halHandle);
+        *handle = (audio_patch_handle_t) mAudioFlinger.nextUniqueId(AUDIO_UNIQUE_ID_USE_PATCH);
+        newPatch.mHalHandle = halHandle;
+        mPatches.insert(std::make_pair(*handle, std::move(newPatch)));
+        if (insertedModule != AUDIO_MODULE_HANDLE_NONE) {
+            addSoftwarePatchToInsertedModules(insertedModule, *handle);
+        }
+        ALOGV("%s() added new patch handle %d halHandle %d", __func__, *handle, halHandle);
     } else {
-        clearPatchConnections(newPatch);
-        delete newPatch;
+        newPatch.clearConnections(this);
     }
     return status;
 }
 
-status_t AudioFlinger::PatchPanel::createPatchConnections(Patch *patch,
-                                                          const struct audio_patch *audioPatch)
+AudioFlinger::PatchPanel::Patch::~Patch()
+{
+    ALOGE_IF(isSoftware(), "Software patch connections leaked %d %d",
+            mRecord.handle(), mPlayback.handle());
+}
+
+status_t AudioFlinger::PatchPanel::Patch::createConnections(PatchPanel *panel)
 {
     // create patch from source device to record thread input
-    struct audio_patch subPatch;
-    subPatch.num_sources = 1;
-    subPatch.sources[0] = audioPatch->sources[0];
-    subPatch.num_sinks = 1;
-
-    patch->mRecordThread->getAudioPortConfig(&subPatch.sinks[0]);
-    subPatch.sinks[0].ext.mix.usecase.source = AUDIO_SOURCE_MIC;
-
-    status_t status = createAudioPatch(&subPatch, &patch->mRecordPatchHandle);
+    status_t status = panel->createAudioPatch(
+            PatchBuilder().addSource(mAudioPatch.sources[0]).
+                addSink(mRecord.thread(), { .source = AUDIO_SOURCE_MIC }).patch(),
+            mRecord.handlePtr());
     if (status != NO_ERROR) {
-        patch->mRecordPatchHandle = AUDIO_PATCH_HANDLE_NONE;
+        *mRecord.handlePtr() = AUDIO_PATCH_HANDLE_NONE;
         return status;
     }
 
     // create patch from playback thread output to sink device
-    if (audioPatch->num_sinks != 0) {
-        patch->mPlaybackThread->getAudioPortConfig(&subPatch.sources[0]);
-        subPatch.sinks[0] = audioPatch->sinks[0];
-        status = createAudioPatch(&subPatch, &patch->mPlaybackPatchHandle);
+    if (mAudioPatch.num_sinks != 0) {
+        status = panel->createAudioPatch(
+                PatchBuilder().addSource(mPlayback.thread()).addSink(mAudioPatch.sinks[0]).patch(),
+                mPlayback.handlePtr());
         if (status != NO_ERROR) {
-            patch->mPlaybackPatchHandle = AUDIO_PATCH_HANDLE_NONE;
+            *mPlayback.handlePtr() = AUDIO_PATCH_HANDLE_NONE;
             return status;
         }
     } else {
-        patch->mPlaybackPatchHandle = AUDIO_PATCH_HANDLE_NONE;
+        *mPlayback.handlePtr() = AUDIO_PATCH_HANDLE_NONE;
     }
 
     // use a pseudo LCM between input and output framecount
-    size_t playbackFrameCount = patch->mPlaybackThread->frameCount();
+    size_t playbackFrameCount = mPlayback.thread()->frameCount();
     int playbackShift = __builtin_ctz(playbackFrameCount);
-    size_t recordFramecount = patch->mRecordThread->frameCount();
-    int shift = __builtin_ctz(recordFramecount);
+    size_t recordFrameCount = mRecord.thread()->frameCount();
+    int shift = __builtin_ctz(recordFrameCount);
     if (playbackShift < shift) {
         shift = playbackShift;
     }
-    size_t frameCount = (playbackFrameCount * recordFramecount) >> shift;
-    ALOGV("createPatchConnections() playframeCount %zu recordFramecount %zu frameCount %zu",
-          playbackFrameCount, recordFramecount, frameCount);
+    size_t frameCount = (playbackFrameCount * recordFrameCount) >> shift;
+    ALOGV("%s() playframeCount %zu recordFrameCount %zu frameCount %zu",
+            __func__, playbackFrameCount, recordFrameCount, frameCount);
 
     // create a special record track to capture from record thread
-    uint32_t channelCount = patch->mPlaybackThread->channelCount();
+    uint32_t channelCount = mPlayback.thread()->channelCount();
     audio_channel_mask_t inChannelMask = audio_channel_in_mask_from_count(channelCount);
-    audio_channel_mask_t outChannelMask = patch->mPlaybackThread->channelMask();
-    uint32_t sampleRate = patch->mPlaybackThread->sampleRate();
-    audio_format_t format = patch->mPlaybackThread->format();
+    audio_channel_mask_t outChannelMask = mPlayback.thread()->channelMask();
+    uint32_t sampleRate = mPlayback.thread()->sampleRate();
+    audio_format_t format = mPlayback.thread()->format();
 
-    patch->mPatchRecord = new RecordThread::PatchRecord(
-                                             patch->mRecordThread.get(),
+    audio_format_t inputFormat = mRecord.thread()->format();
+    if (!audio_is_linear_pcm(inputFormat)) {
+        // The playbackThread format will say PCM for IEC61937 packetized stream.
+        // Use recordThread format.
+        format = inputFormat;
+    }
+    audio_input_flags_t inputFlags = mAudioPatch.sources[0].config_mask & AUDIO_PORT_CONFIG_FLAGS ?
+            mAudioPatch.sources[0].flags.input : AUDIO_INPUT_FLAG_NONE;
+    if (sampleRate == mRecord.thread()->sampleRate() &&
+            inChannelMask == mRecord.thread()->channelMask() &&
+            mRecord.thread()->fastTrackAvailable() &&
+            mRecord.thread()->hasFastCapture()) {
+        // Create a fast track if the record thread has fast capture to get better performance.
+        // Only enable fast mode when there is no resample needed.
+        inputFlags = (audio_input_flags_t) (inputFlags | AUDIO_INPUT_FLAG_FAST);
+    } else {
+        // Fast mode is not available in this case.
+        inputFlags = (audio_input_flags_t) (inputFlags & ~AUDIO_INPUT_FLAG_FAST);
+    }
+    sp<RecordThread::PatchRecord> tempRecordTrack = new (std::nothrow) RecordThread::PatchRecord(
+                                             mRecord.thread().get(),
                                              sampleRate,
                                              inChannelMask,
                                              format,
                                              frameCount,
                                              NULL,
                                              (size_t)0 /* bufferSize */,
-                                             AUDIO_INPUT_FLAG_NONE);
-    if (patch->mPatchRecord == 0) {
-        return NO_MEMORY;
-    }
-    status = patch->mPatchRecord->initCheck();
+                                             inputFlags);
+    status = mRecord.checkTrack(tempRecordTrack.get());
     if (status != NO_ERROR) {
         return status;
     }
-    patch->mRecordThread->addPatchRecord(patch->mPatchRecord);
+
+    audio_output_flags_t outputFlags = mAudioPatch.sinks[0].config_mask & AUDIO_PORT_CONFIG_FLAGS ?
+            mAudioPatch.sinks[0].flags.output : AUDIO_OUTPUT_FLAG_NONE;
+    audio_stream_type_t streamType = AUDIO_STREAM_PATCH;
+    if (mAudioPatch.num_sources == 2 && mAudioPatch.sources[1].type == AUDIO_PORT_TYPE_MIX) {
+        // "reuse one existing output mix" case
+        streamType = mAudioPatch.sources[1].ext.mix.usecase.stream;
+    }
+    if (mPlayback.thread()->hasFastMixer()) {
+        // Create a fast track if the playback thread has fast mixer to get better performance.
+        // Note: we should have matching channel mask, sample rate, and format by the logic above.
+        outputFlags = (audio_output_flags_t) (outputFlags | AUDIO_OUTPUT_FLAG_FAST);
+    } else {
+        outputFlags = (audio_output_flags_t) (outputFlags & ~AUDIO_OUTPUT_FLAG_FAST);
+    }
 
     // create a special playback track to render to playback thread.
     // this track is given the same buffer as the PatchRecord buffer
-    patch->mPatchTrack = new PlaybackThread::PatchTrack(
-                                           patch->mPlaybackThread.get(),
-                                           audioPatch->sources[1].ext.mix.usecase.stream,
+    sp<PlaybackThread::PatchTrack> tempPatchTrack = new (std::nothrow) PlaybackThread::PatchTrack(
+                                           mPlayback.thread().get(),
+                                           streamType,
                                            sampleRate,
                                            outChannelMask,
                                            format,
                                            frameCount,
-                                           patch->mPatchRecord->buffer(),
-                                           patch->mPatchRecord->bufferSize(),
-                                           AUDIO_OUTPUT_FLAG_NONE);
-    status = patch->mPatchTrack->initCheck();
+                                           tempRecordTrack->buffer(),
+                                           tempRecordTrack->bufferSize(),
+                                           outputFlags);
+    status = mPlayback.checkTrack(tempPatchTrack.get());
     if (status != NO_ERROR) {
         return status;
     }
-    patch->mPlaybackThread->addPatchTrack(patch->mPatchTrack);
 
     // tie playback and record tracks together
-    patch->mPatchRecord->setPeerProxy(patch->mPatchTrack.get());
-    patch->mPatchTrack->setPeerProxy(patch->mPatchRecord.get());
+    mRecord.setTrackAndPeer(tempRecordTrack, tempPatchTrack);
+    mPlayback.setTrackAndPeer(tempPatchTrack, tempRecordTrack);
 
     // start capture and playback
-    patch->mPatchRecord->start(AudioSystem::SYNC_EVENT_NONE, AUDIO_SESSION_NONE);
-    patch->mPatchTrack->start();
+    mRecord.track()->start(AudioSystem::SYNC_EVENT_NONE, AUDIO_SESSION_NONE);
+    mPlayback.track()->start();
 
     return status;
 }
 
-void AudioFlinger::PatchPanel::clearPatchConnections(Patch *patch)
+void AudioFlinger::PatchPanel::Patch::clearConnections(PatchPanel *panel)
 {
-    sp<AudioFlinger> audioflinger = mAudioFlinger.promote();
-    if (audioflinger == 0) {
-        return;
+    ALOGV("%s() mRecord.handle %d mPlayback.handle %d",
+            __func__, mRecord.handle(), mPlayback.handle());
+    mRecord.stopTrack();
+    mPlayback.stopTrack();
+    mRecord.clearTrackPeer(); // mRecord stop is synchronous. Break PeerProxy sp<> cycle.
+    mRecord.closeConnections(panel);
+    mPlayback.closeConnections(panel);
+}
+
+status_t AudioFlinger::PatchPanel::Patch::getLatencyMs(double *latencyMs) const
+{
+    if (!isSoftware()) return INVALID_OPERATION;
+
+    auto recordTrack = mRecord.const_track();
+    if (recordTrack.get() == nullptr) return INVALID_OPERATION;
+
+    auto playbackTrack = mPlayback.const_track();
+    if (playbackTrack.get() == nullptr) return INVALID_OPERATION;
+
+    // Latency information for tracks may be called without obtaining
+    // the underlying thread lock.
+    //
+    // We use record server latency + playback track latency (generally smaller than the
+    // reverse due to internal biases).
+    //
+    // TODO: is this stable enough? Consider a PatchTrack synchronized version of this.
+
+    // For PCM tracks get server latency.
+    if (audio_is_linear_pcm(recordTrack->format())) {
+        double recordServerLatencyMs, playbackTrackLatencyMs;
+        if (recordTrack->getServerLatencyMs(&recordServerLatencyMs) == OK
+                && playbackTrack->getTrackLatencyMs(&playbackTrackLatencyMs) == OK) {
+            *latencyMs = recordServerLatencyMs + playbackTrackLatencyMs;
+            return OK;
+        }
     }
 
-    ALOGV("clearPatchConnections() patch->mRecordPatchHandle %d patch->mPlaybackPatchHandle %d",
-          patch->mRecordPatchHandle, patch->mPlaybackPatchHandle);
+    // See if kernel latencies are available.
+    // If so, do a frame diff and time difference computation to estimate
+    // the total patch latency. This requires that frame counts are reported by the
+    // HAL are matched properly in the case of record overruns and playback underruns.
+    ThreadBase::TrackBase::FrameTime recordFT{}, playFT{};
+    recordTrack->getKernelFrameTime(&recordFT);
+    playbackTrack->getKernelFrameTime(&playFT);
+    if (recordFT.timeNs > 0 && playFT.timeNs > 0) {
+        const int64_t frameDiff = recordFT.frames - playFT.frames;
+        const int64_t timeDiffNs = recordFT.timeNs - playFT.timeNs;
 
-    if (patch->mPatchRecord != 0) {
-        patch->mPatchRecord->stop();
-    }
-    if (patch->mPatchTrack != 0) {
-        patch->mPatchTrack->stop();
-    }
-    if (patch->mRecordPatchHandle != AUDIO_PATCH_HANDLE_NONE) {
-        releaseAudioPatch(patch->mRecordPatchHandle);
-        patch->mRecordPatchHandle = AUDIO_PATCH_HANDLE_NONE;
-    }
-    if (patch->mPlaybackPatchHandle != AUDIO_PATCH_HANDLE_NONE) {
-        releaseAudioPatch(patch->mPlaybackPatchHandle);
-        patch->mPlaybackPatchHandle = AUDIO_PATCH_HANDLE_NONE;
-    }
-    if (patch->mRecordThread != 0) {
-        if (patch->mPatchRecord != 0) {
-            patch->mRecordThread->deletePatchRecord(patch->mPatchRecord);
+        // It is possible that the patch track and patch record have a large time disparity because
+        // one thread runs but another is stopped.  We arbitrarily choose the maximum timestamp
+        // time difference based on how often we expect the timestamps to update in normal operation
+        // (typical should be no more than 50 ms).
+        //
+        // If the timestamps aren't sampled close enough, the patch latency is not
+        // considered valid.
+        //
+        // TODO: change this based on more experiments.
+        constexpr int64_t maxValidTimeDiffNs = 200 * NANOS_PER_MILLISECOND;
+        if (std::abs(timeDiffNs) < maxValidTimeDiffNs) {
+            *latencyMs = frameDiff * 1e3 / recordTrack->sampleRate()
+                   - timeDiffNs * 1e-6;
+            return OK;
         }
-        audioflinger->closeInputInternal_l(patch->mRecordThread);
-    }
-    if (patch->mPlaybackThread != 0) {
-        if (patch->mPatchTrack != 0) {
-            patch->mPlaybackThread->deletePatchTrack(patch->mPatchTrack);
-        }
-        // if num sources == 2 we are reusing an existing playback thread so we do not close it
-        if (patch->mAudioPatch.num_sources != 2) {
-            audioflinger->closeOutputInternal_l(patch->mPlaybackThread);
-        }
-    }
-    if (patch->mRecordThread != 0) {
-        if (patch->mPatchRecord != 0) {
-            patch->mPatchRecord.clear();
-        }
-        patch->mRecordThread.clear();
-    }
-    if (patch->mPlaybackThread != 0) {
-        if (patch->mPatchTrack != 0) {
-            patch->mPatchTrack.clear();
-        }
-        patch->mPlaybackThread.clear();
     }
 
+    return INVALID_OPERATION;
+}
+
+String8 AudioFlinger::PatchPanel::Patch::dump(audio_patch_handle_t myHandle) const
+{
+    // TODO: Consider table dump form for patches, just like tracks.
+    String8 result = String8::format("Patch %d: thread %p => thread %p",
+            myHandle, mRecord.const_thread().get(), mPlayback.const_thread().get());
+
+    // add latency if it exists
+    double latencyMs;
+    if (getLatencyMs(&latencyMs) == OK) {
+        result.appendFormat("  latency: %.2lf ms", latencyMs);
+    }
+    return result;
 }
 
 /* Disconnect a patch */
 status_t AudioFlinger::PatchPanel::releaseAudioPatch(audio_patch_handle_t handle)
 {
-    ALOGV("releaseAudioPatch handle %d", handle);
+    ALOGV("%s handle %d", __func__, handle);
     status_t status = NO_ERROR;
-    size_t index;
 
-    sp<AudioFlinger> audioflinger = mAudioFlinger.promote();
-    if (audioflinger == 0) {
-        return NO_INIT;
-    }
-
-    for (index = 0; index < mPatches.size(); index++) {
-        if (handle == mPatches[index]->mHandle) {
-            break;
-        }
-    }
-    if (index == mPatches.size()) {
+    auto iter = mPatches.find(handle);
+    if (iter == mPatches.end()) {
         return BAD_VALUE;
     }
-    Patch *removedPatch = mPatches[index];
-    mPatches.removeAt(index);
+    Patch &removedPatch = iter->second;
+    const struct audio_patch &patch = removedPatch.mAudioPatch;
 
-    struct audio_patch *patch = &removedPatch->mAudioPatch;
-
-    switch (patch->sources[0].type) {
+    const struct audio_port_config &src = patch.sources[0];
+    switch (src.type) {
         case AUDIO_PORT_TYPE_DEVICE: {
-            audio_module_handle_t srcModule = patch->sources[0].ext.device.hw_module;
-            ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(srcModule);
-            if (index < 0) {
-                ALOGW("releaseAudioPatch() bad src hw module %d", srcModule);
+            sp<DeviceHalInterface> hwDevice = findHwDeviceByModule(src.ext.device.hw_module);
+            if (hwDevice == 0) {
+                ALOGW("%s() bad src hw module %d", __func__, src.ext.device.hw_module);
                 status = BAD_VALUE;
                 break;
             }
 
-            if (removedPatch->mRecordPatchHandle != AUDIO_PATCH_HANDLE_NONE ||
-                    removedPatch->mPlaybackPatchHandle != AUDIO_PATCH_HANDLE_NONE) {
-                clearPatchConnections(removedPatch);
+            if (removedPatch.isSoftware()) {
+                removedPatch.clearConnections(this);
                 break;
             }
 
-            if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
-                sp<ThreadBase> thread = audioflinger->checkRecordThread_l(
-                                                                patch->sinks[0].ext.mix.handle);
+            if (patch.sinks[0].type == AUDIO_PORT_TYPE_MIX) {
+                audio_io_handle_t ioHandle = patch.sinks[0].ext.mix.handle;
+                sp<ThreadBase> thread = mAudioFlinger.checkRecordThread_l(ioHandle);
                 if (thread == 0) {
-                    thread = audioflinger->checkMmapThread_l(patch->sinks[0].ext.mix.handle);
+                    thread = mAudioFlinger.checkMmapThread_l(ioHandle);
                     if (thread == 0) {
-                        ALOGW("releaseAudioPatch() bad capture I/O handle %d",
-                                                                  patch->sinks[0].ext.mix.handle);
+                        ALOGW("%s() bad capture I/O handle %d", __func__, ioHandle);
                         status = BAD_VALUE;
                         break;
                     }
                 }
-                status = thread->sendReleaseAudioPatchConfigEvent(removedPatch->mHalHandle);
+                status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle);
             } else {
-                AudioHwDevice *audioHwDevice = audioflinger->mAudioHwDevs.valueAt(index);
-                sp<DeviceHalInterface> hwDevice = audioHwDevice->hwDevice();
-                status = hwDevice->releaseAudioPatch(removedPatch->mHalHandle);
+                status = hwDevice->releaseAudioPatch(removedPatch.mHalHandle);
             }
         } break;
         case AUDIO_PORT_TYPE_MIX: {
-            audio_module_handle_t srcModule =  patch->sources[0].ext.mix.hw_module;
-            ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(srcModule);
-            if (index < 0) {
-                ALOGW("releaseAudioPatch() bad src hw module %d", srcModule);
+            if (findHwDeviceByModule(src.ext.mix.hw_module) == 0) {
+                ALOGW("%s() bad src hw module %d", __func__, src.ext.mix.hw_module);
                 status = BAD_VALUE;
                 break;
             }
-            sp<ThreadBase> thread =
-                            audioflinger->checkPlaybackThread_l(patch->sources[0].ext.mix.handle);
+            audio_io_handle_t ioHandle = src.ext.mix.handle;
+            sp<ThreadBase> thread = mAudioFlinger.checkPlaybackThread_l(ioHandle);
             if (thread == 0) {
-                thread = audioflinger->checkMmapThread_l(patch->sources[0].ext.mix.handle);
+                thread = mAudioFlinger.checkMmapThread_l(ioHandle);
                 if (thread == 0) {
-                    ALOGW("releaseAudioPatch() bad playback I/O handle %d",
-                                                                  patch->sources[0].ext.mix.handle);
+                    ALOGW("%s() bad playback I/O handle %d", __func__, ioHandle);
                     status = BAD_VALUE;
                     break;
                 }
             }
-            status = thread->sendReleaseAudioPatchConfigEvent(removedPatch->mHalHandle);
+            status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle);
         } break;
         default:
             status = BAD_VALUE;
-            break;
     }
 
-    delete removedPatch;
+    mPatches.erase(iter);
+    removeSoftwarePatchFromInsertedModules(handle);
     return status;
 }
 
-
 /* List connected audio ports and they attributes */
 status_t AudioFlinger::PatchPanel::listAudioPatches(unsigned int *num_patches __unused,
                                   struct audio_patch *patches __unused)
 {
-    ALOGV("listAudioPatches");
+    ALOGV(__func__);
     return NO_ERROR;
 }
 
-/* Set audio port configuration */
-status_t AudioFlinger::PatchPanel::setAudioPortConfig(const struct audio_port_config *config)
+status_t AudioFlinger::PatchPanel::getDownstreamSoftwarePatches(
+        audio_io_handle_t stream,
+        std::vector<AudioFlinger::PatchPanel::SoftwarePatch> *patches) const
 {
-    ALOGV("setAudioPortConfig");
-
-    sp<AudioFlinger> audioflinger = mAudioFlinger.promote();
-    if (audioflinger == 0) {
-        return NO_INIT;
+    for (const auto& module : mInsertedModules) {
+        if (module.second.streams.count(stream)) {
+            for (const auto& patchHandle : module.second.sw_patches) {
+                const auto& patch_iter = mPatches.find(patchHandle);
+                if (patch_iter != mPatches.end()) {
+                    const Patch &patch = patch_iter->second;
+                    patches->emplace_back(*this, patchHandle,
+                            patch.mPlayback.const_thread()->id(),
+                            patch.mRecord.const_thread()->id());
+                } else {
+                    ALOGE("Stale patch handle in the cache: %d", patchHandle);
+                }
+            }
+            return OK;
+        }
     }
+    // The stream is not associated with any of inserted modules.
+    return BAD_VALUE;
+}
 
-    audio_module_handle_t module;
-    if (config->type == AUDIO_PORT_TYPE_DEVICE) {
-        module = config->ext.device.hw_module;
-    } else {
-        module = config->ext.mix.hw_module;
+void AudioFlinger::PatchPanel::notifyStreamOpened(
+        AudioHwDevice *audioHwDevice, audio_io_handle_t stream)
+{
+    if (audioHwDevice->isInsert()) {
+        mInsertedModules[audioHwDevice->handle()].streams.insert(stream);
     }
+}
 
-    ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(module);
+void AudioFlinger::PatchPanel::notifyStreamClosed(audio_io_handle_t stream)
+{
+    for (auto& module : mInsertedModules) {
+        module.second.streams.erase(stream);
+    }
+}
+
+AudioHwDevice* AudioFlinger::PatchPanel::findAudioHwDeviceByModule(audio_module_handle_t module)
+{
+    if (module == AUDIO_MODULE_HANDLE_NONE) return nullptr;
+    ssize_t index = mAudioFlinger.mAudioHwDevs.indexOfKey(module);
     if (index < 0) {
-        ALOGW("setAudioPortConfig() bad hw module %d", module);
-        return BAD_VALUE;
+        ALOGW("%s() bad hw module %d", __func__, module);
+        return nullptr;
+    }
+    return mAudioFlinger.mAudioHwDevs.valueAt(index);
+}
+
+sp<DeviceHalInterface> AudioFlinger::PatchPanel::findHwDeviceByModule(audio_module_handle_t module)
+{
+    AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule(module);
+    return audioHwDevice ? audioHwDevice->hwDevice() : nullptr;
+}
+
+void AudioFlinger::PatchPanel::addSoftwarePatchToInsertedModules(
+        audio_module_handle_t module, audio_patch_handle_t handle)
+{
+    mInsertedModules[module].sw_patches.insert(handle);
+}
+
+void AudioFlinger::PatchPanel::removeSoftwarePatchFromInsertedModules(
+        audio_patch_handle_t handle)
+{
+    for (auto& module : mInsertedModules) {
+        module.second.sw_patches.erase(handle);
+    }
+}
+
+void AudioFlinger::PatchPanel::dump(int fd) const
+{
+    String8 patchPanelDump;
+    const char *indent = "  ";
+
+    // Only dump software patches.
+    bool headerPrinted = false;
+    for (const auto& iter : mPatches) {
+        if (iter.second.isSoftware()) {
+            if (!headerPrinted) {
+                patchPanelDump += "\nSoftware patches:\n";
+                headerPrinted = true;
+            }
+            patchPanelDump.appendFormat("%s%s\n", indent, iter.second.dump(iter.first).string());
+        }
     }
 
-    AudioHwDevice *audioHwDevice = audioflinger->mAudioHwDevs.valueAt(index);
-    return audioHwDevice->hwDevice()->setAudioPortConfig(config);
+    headerPrinted = false;
+    for (const auto& module : mInsertedModules) {
+        if (!module.second.streams.empty() || !module.second.sw_patches.empty()) {
+            if (!headerPrinted) {
+                patchPanelDump += "\nTracked inserted modules:\n";
+                headerPrinted = true;
+            }
+            String8 moduleDump = String8::format("Module %d: I/O handles: ", module.first);
+            for (const auto& stream : module.second.streams) {
+                moduleDump.appendFormat("%d ", stream);
+            }
+            moduleDump.append("; SW Patches: ");
+            for (const auto& patch : module.second.sw_patches) {
+                moduleDump.appendFormat("%d ", patch);
+            }
+            patchPanelDump.appendFormat("%s%s\n", indent, moduleDump.string());
+        }
+    }
+
+    if (!patchPanelDump.isEmpty()) {
+        write(fd, patchPanelDump.string(), patchPanelDump.size());
+    }
 }
 
 } // namespace android
diff --git a/services/audioflinger/PatchPanel.h b/services/audioflinger/PatchPanel.h
index d37c0d3..181e27c 100644
--- a/services/audioflinger/PatchPanel.h
+++ b/services/audioflinger/PatchPanel.h
@@ -19,13 +19,33 @@
     #error This header file should only be included from AudioFlinger.h
 #endif
 
-class PatchPanel : public RefBase {
+
+// PatchPanel is concealed within AudioFlinger, their lifetimes are the same.
+class PatchPanel {
 public:
+    class SoftwarePatch {
+      public:
+        SoftwarePatch(const PatchPanel &patchPanel, audio_patch_handle_t patchHandle,
+                audio_io_handle_t playbackThreadHandle, audio_io_handle_t recordThreadHandle)
+                : mPatchPanel(patchPanel), mPatchHandle(patchHandle),
+                  mPlaybackThreadHandle(playbackThreadHandle),
+                  mRecordThreadHandle(recordThreadHandle) {}
+        SoftwarePatch(const SoftwarePatch&) = default;
+        SoftwarePatch& operator=(const SoftwarePatch&) = default;
 
-    class Patch;
+        // Must be called under AudioFlinger::mLock
+        status_t getLatencyMs_l(double *latencyMs) const;
+        audio_patch_handle_t getPatchHandle() const { return mPatchHandle; };
+        audio_io_handle_t getPlaybackThreadHandle() const { return mPlaybackThreadHandle; };
+        audio_io_handle_t getRecordThreadHandle() const { return mRecordThreadHandle; };
+      private:
+        const PatchPanel &mPatchPanel;
+        const audio_patch_handle_t mPatchHandle;
+        const audio_io_handle_t mPlaybackThreadHandle;
+        const audio_io_handle_t mRecordThreadHandle;
+    };
 
-    explicit PatchPanel(const sp<AudioFlinger>& audioFlinger);
-    virtual ~PatchPanel();
+    explicit PatchPanel(AudioFlinger* audioFlinger) : mAudioFlinger(*audioFlinger) {}
 
     /* List connected audio ports and their attributes */
     status_t listAudioPorts(unsigned int *num_ports,
@@ -45,46 +65,157 @@
     status_t listAudioPatches(unsigned int *num_patches,
                                       struct audio_patch *patches);
 
-    /* Set audio port configuration */
-    status_t setAudioPortConfig(const struct audio_port_config *config);
+    // Retrieves all currently estrablished software patches for a stream
+    // opened on an intermediate module.
+    status_t getDownstreamSoftwarePatches(audio_io_handle_t stream,
+            std::vector<SoftwarePatch> *patches) const;
 
-    status_t createPatchConnections(Patch *patch,
-                                    const struct audio_patch *audioPatch);
-    void clearPatchConnections(Patch *patch);
+    // Notifies patch panel about all opened and closed streams.
+    void notifyStreamOpened(AudioHwDevice *audioHwDevice, audio_io_handle_t stream);
+    void notifyStreamClosed(audio_io_handle_t stream);
+
+    void dump(int fd) const;
+
+private:
+    template<typename ThreadType, typename TrackType>
+    class Endpoint {
+    public:
+        Endpoint() = default;
+        Endpoint(const Endpoint&) = delete;
+        Endpoint& operator=(const Endpoint&) = delete;
+        Endpoint(Endpoint&& other) noexcept { swap(other); }
+        Endpoint& operator=(Endpoint&& other) noexcept {
+            swap(other);
+            return *this;
+        }
+        ~Endpoint() {
+            ALOGE_IF(mHandle != AUDIO_PATCH_HANDLE_NONE,
+                    "A non empty Patch Endpoint leaked, handle %d", mHandle);
+        }
+
+        status_t checkTrack(TrackType *trackOrNull) const {
+            if (trackOrNull == nullptr) return NO_MEMORY;
+            return trackOrNull->initCheck();
+        }
+        audio_patch_handle_t handle() const { return mHandle; }
+        sp<ThreadType> thread() { return mThread; }
+        sp<TrackType> track() { return mTrack; }
+        sp<const ThreadType> const_thread() const { return mThread; }
+        sp<const TrackType> const_track() const { return mTrack; }
+
+        void closeConnections(PatchPanel *panel) {
+            if (mHandle != AUDIO_PATCH_HANDLE_NONE) {
+                panel->releaseAudioPatch(mHandle);
+                mHandle = AUDIO_PATCH_HANDLE_NONE;
+            }
+            if (mThread != 0) {
+                if (mTrack != 0) {
+                    mThread->deletePatchTrack(mTrack);
+                }
+                if (mCloseThread) {
+                    panel->mAudioFlinger.closeThreadInternal_l(mThread);
+                }
+            }
+        }
+        audio_patch_handle_t* handlePtr() { return &mHandle; }
+        void setThread(const sp<ThreadType>& thread, bool closeThread = true) {
+            mThread = thread;
+            mCloseThread = closeThread;
+        }
+        template <typename T>
+        void setTrackAndPeer(const sp<TrackType>& track, const sp<T> &peer) {
+            mTrack = track;
+            mThread->addPatchTrack(mTrack);
+            mTrack->setPeerProxy(peer, true /* holdReference */);
+        }
+        void clearTrackPeer() { if (mTrack) mTrack->clearPeerProxy(); }
+        void stopTrack() { if (mTrack) mTrack->stop(); }
+
+        void swap(Endpoint &other) noexcept {
+            using std::swap;
+            swap(mThread, other.mThread);
+            swap(mCloseThread, other.mCloseThread);
+            swap(mHandle, other.mHandle);
+            swap(mTrack, other.mTrack);
+        }
+
+        friend void swap(Endpoint &a, Endpoint &b) noexcept {
+            a.swap(b);
+        }
+
+    private:
+        sp<ThreadType> mThread;
+        bool mCloseThread = true;
+        audio_patch_handle_t mHandle = AUDIO_PATCH_HANDLE_NONE;
+        sp<TrackType> mTrack;
+    };
 
     class Patch {
     public:
-        explicit Patch(const struct audio_patch *patch) :
-            mAudioPatch(*patch), mHandle(AUDIO_PATCH_HANDLE_NONE),
-            mHalHandle(AUDIO_PATCH_HANDLE_NONE), mRecordPatchHandle(AUDIO_PATCH_HANDLE_NONE),
-            mPlaybackPatchHandle(AUDIO_PATCH_HANDLE_NONE) {}
-        ~Patch() {}
+        explicit Patch(const struct audio_patch &patch) : mAudioPatch(patch) {}
+        ~Patch();
+        Patch(const Patch&) = delete;
+        Patch(Patch&&) = default;
+        Patch& operator=(const Patch&) = delete;
+        Patch& operator=(Patch&&) = default;
 
+        status_t createConnections(PatchPanel *panel);
+        void clearConnections(PatchPanel *panel);
+        bool isSoftware() const {
+            return mRecord.handle() != AUDIO_PATCH_HANDLE_NONE ||
+                    mPlayback.handle() != AUDIO_PATCH_HANDLE_NONE; }
+
+        // returns the latency of the patch (from record to playback).
+        status_t getLatencyMs(double *latencyMs) const;
+
+        String8 dump(audio_patch_handle_t myHandle) const;
+
+        // Note that audio_patch::id is only unique within a HAL module
         struct audio_patch              mAudioPatch;
-        audio_patch_handle_t            mHandle;
         // handle for audio HAL patch handle present only when the audio HAL version is >= 3.0
-        audio_patch_handle_t            mHalHandle;
+        audio_patch_handle_t            mHalHandle = AUDIO_PATCH_HANDLE_NONE;
         // below members are used by a software audio patch connecting a source device from a
         // given audio HW module to a sink device on an other audio HW module.
-        // playback thread created by createAudioPatch() and released by clearPatchConnections() if
-        // no existing playback thread can be used by the software patch
-        sp<PlaybackThread>              mPlaybackThread;
-        // audio track created by createPatchConnections() and released by clearPatchConnections()
-        sp<PlaybackThread::PatchTrack>  mPatchTrack;
-        // record thread created by createAudioPatch() and released by clearPatchConnections()
-        sp<RecordThread>                mRecordThread;
-        // audio record created by createPatchConnections() and released by clearPatchConnections()
-        sp<RecordThread::PatchRecord>   mPatchRecord;
-        // handle for audio patch connecting source device to record thread input.
-        // created by createPatchConnections() and released by clearPatchConnections()
-        audio_patch_handle_t            mRecordPatchHandle;
-        // handle for audio patch connecting playback thread output to sink device
-        // created by createPatchConnections() and released by clearPatchConnections()
-        audio_patch_handle_t            mPlaybackPatchHandle;
-
+        // the objects are created by createConnections() and released by clearConnections()
+        // playback thread is created if no existing playback thread can be used
+        // connects playback thread output to sink device
+        Endpoint<PlaybackThread, PlaybackThread::PatchTrack> mPlayback;
+        // connects source device to record thread input
+        Endpoint<RecordThread, RecordThread::PatchRecord> mRecord;
     };
 
-private:
-    const wp<AudioFlinger>      mAudioFlinger;
-    SortedVector <Patch *>      mPatches;
+    AudioHwDevice* findAudioHwDeviceByModule(audio_module_handle_t module);
+    sp<DeviceHalInterface> findHwDeviceByModule(audio_module_handle_t module);
+    void addSoftwarePatchToInsertedModules(
+            audio_module_handle_t module, audio_patch_handle_t handle);
+    void removeSoftwarePatchFromInsertedModules(audio_patch_handle_t handle);
+
+    AudioFlinger &mAudioFlinger;
+    std::map<audio_patch_handle_t, Patch> mPatches;
+
+    // This map allows going from a thread to "downstream" software patches
+    // when a processing module inserted in between. Example:
+    //
+    //  from map value.streams                               map key
+    //  [Mixer thread] --> [Virtual output device] --> [Processing module] ---\
+    //       [Harware module] <-- [Physical output device] <-- [S/W Patch] <--/
+    //                                                 from map value.sw_patches
+    //
+    // This allows the mixer thread to look up the threads of the software patch
+    // for propagating timing info, parameters, etc.
+    //
+    // The current assumptions are:
+    //   1) The processing module acts as a mixer with several outputs which
+    //      represent differently downmixed and / or encoded versions of the same
+    //      mixed stream. There is no 1:1 correspondence between the input streams
+    //      and the software patches, but rather a N:N correspondence between
+    //      a group of streams and a group of patches.
+    //   2) There are only a couple of inserted processing modules in the system,
+    //      so when looking for a stream or patch handle we can iterate over
+    //      all modules.
+    struct ModuleConnections {
+        std::set<audio_io_handle_t> streams;
+        std::set<audio_patch_handle_t> sw_patches;
+    };
+    std::map<audio_module_handle_t, ModuleConnections> mInsertedModules;
 };
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index a78be992..a093893 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -19,6 +19,42 @@
     #error This header file should only be included from AudioFlinger.h
 #endif
 
+// Checks and monitors OP_PLAY_AUDIO
+class OpPlayAudioMonitor : public RefBase {
+public:
+    ~OpPlayAudioMonitor() override;
+    bool hasOpPlayAudio() const;
+
+    static sp<OpPlayAudioMonitor> createIfNeeded(
+            uid_t uid, const audio_attributes_t& attr, int id, audio_stream_type_t streamType);
+
+private:
+    OpPlayAudioMonitor(uid_t uid, audio_usage_t usage, int id);
+    void onFirstRef() override;
+    static void getPackagesForUid(uid_t uid, Vector<String16>& packages);
+
+    AppOpsManager mAppOpsManager;
+
+    class PlayAudioOpCallback : public BnAppOpsCallback {
+    public:
+        explicit PlayAudioOpCallback(const wp<OpPlayAudioMonitor>& monitor);
+        void opChanged(int32_t op, const String16& packageName) override;
+
+    private:
+        const wp<OpPlayAudioMonitor> mMonitor;
+    };
+
+    sp<PlayAudioOpCallback> mOpCallback;
+    // called by PlayAudioOpCallback when OP_PLAY_AUDIO is updated in AppOp callback
+    void checkPlayAudioForUsage();
+
+    std::atomic_bool mHasOpPlayAudio;
+    Vector<String16> mPackages;
+    const uid_t mUid;
+    const int32_t mUsage; // on purpose not audio_usage_t because always checked in appOps as int32_t
+    const int mId; // for logging purposes only
+};
+
 // playback track
 class Track : public TrackBase, public VolumeProvider {
 public:
@@ -34,6 +70,7 @@
                                 size_t bufferSize,
                                 const sp<IMemory>& sharedBuffer,
                                 audio_session_t sessionId,
+                                pid_t creatorPid,
                                 uid_t uid,
                                 audio_output_flags_t flags,
                                 track_type type,
@@ -41,22 +78,15 @@
     virtual             ~Track();
     virtual status_t    initCheck() const;
 
-    static  void        appendDumpHeader(String8& result);
+            void        appendDumpHeader(String8& result);
             void        appendDump(String8& result, bool active);
-    virtual status_t    start(AudioSystem::sync_event_t event =
-                                    AudioSystem::SYNC_EVENT_NONE,
-                             audio_session_t triggerSession = AUDIO_SESSION_NONE);
+    virtual status_t    start(AudioSystem::sync_event_t event = AudioSystem::SYNC_EVENT_NONE,
+                              audio_session_t triggerSession = AUDIO_SESSION_NONE);
     virtual void        stop();
             void        pause();
 
             void        flush();
             void        destroy();
-            int         name() const { return mName; }
-            void        setName(int name) {
-                LOG_ALWAYS_FATAL_IF(mName >= 0 && name >= 0,
-                        "%s both old name %d and new name %d are valid", __func__, mName, name);
-                mName = name;
-            }
 
     virtual uint32_t    sampleRate() const;
 
@@ -65,12 +95,15 @@
             }
             bool        isOffloaded() const
                                 { return (mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0; }
-            bool        isDirect() const { return (mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0; }
+            bool        isDirect() const override
+                                { return (mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0; }
             bool        isOffloadedOrDirect() const { return (mFlags
                             & (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD
                                     | AUDIO_OUTPUT_FLAG_DIRECT)) != 0; }
+            bool        isStatic() const { return  mSharedBuffer.get() != nullptr; }
 
             status_t    setParameters(const String8& keyValuePairs);
+            status_t    selectPresentation(int presentationId, int programId);
             status_t    attachAuxEffect(int EffectId);
             void        setAuxBuffer(int EffectId, int32_t *buffer);
             int32_t     *auxBuffer() const { return mAuxBuffer; }
@@ -87,6 +120,10 @@
 
     virtual bool        isFastTrack() const { return (mFlags & AUDIO_OUTPUT_FLAG_FAST) != 0; }
 
+            double      bufferLatencyMs() const override {
+                            return isStatic() ? 0. : TrackBase::bufferLatencyMs();
+                        }
+
 // implement volume handling.
     media::VolumeShaper::Status applyVolumeShaper(
                                 const sp<media::VolumeShaper::Configuration>& configuration,
@@ -111,6 +148,26 @@
     /** Copy the track metadata in the provided iterator. Thread safe. */
     virtual void    copyMetadataTo(MetadataInserter& backInserter) const;
 
+            /** Return haptic playback of the track is enabled or not, used in mixer. */
+            bool    getHapticPlaybackEnabled() const { return mHapticPlaybackEnabled; }
+            /** Set haptic playback of the track is enabled or not, should be
+             *  set after query or get callback from vibrator service */
+            void    setHapticPlaybackEnabled(bool hapticPlaybackEnabled) {
+                mHapticPlaybackEnabled = hapticPlaybackEnabled;
+            }
+            /** Return at what intensity to play haptics, used in mixer. */
+            AudioMixer::haptic_intensity_t getHapticIntensity() const { return mHapticIntensity; }
+            /** Set intensity of haptic playback, should be set after querying vibrator service. */
+            void    setHapticIntensity(AudioMixer::haptic_intensity_t hapticIntensity) {
+                if (AudioMixer::isValidHapticIntensity(hapticIntensity)) {
+                    mHapticIntensity = hapticIntensity;
+                    setHapticPlaybackEnabled(mHapticIntensity != AudioMixer::HAPTIC_SCALE_MUTE);
+                }
+            }
+            sp<os::ExternalVibration> getExternalVibration() const { return mExternalVibration; }
+
+            void    setTeePatches(TeePatches teePatches);
+
 protected:
     // for numerous
     friend class PlaybackThread;
@@ -121,8 +178,8 @@
     DISALLOW_COPY_AND_ASSIGN(Track);
 
     // AudioBufferProvider interface
-    virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
-    // releaseBuffer() not overridden
+    status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) override;
+    void releaseBuffer(AudioBufferProvider::Buffer* buffer) override;
 
     // ExtendedAudioBufferProvider interface
     virtual size_t framesReady() const;
@@ -140,7 +197,7 @@
     bool isResumePending();
     void resumeAck();
     void updateTrackFrameInfo(int64_t trackFramesReleased, int64_t sinkFramesWritten,
-            const ExtendedTimestamp &timeStamp);
+            uint32_t halSampleRate, const ExtendedTimestamp &timeStamp);
 
     sp<IMemory> sharedBuffer() const { return mSharedBuffer; }
 
@@ -159,6 +216,10 @@
 
     int fastIndex() const { return mFastIndex; }
 
+    bool isPlaybackRestricted() const {
+        // The monitor is only created for tracks that can be silenced.
+        return mOpPlayAudioMonitor ? !mOpPlayAudioMonitor->hasOpPlayAudio() : false; }
+
 protected:
 
     // FILLED state is used for suppressing volume ramp at begin of playing
@@ -171,7 +232,6 @@
 
     bool                mResetDone;
     const audio_stream_type_t mStreamType;
-    int                 mName;
     effect_buffer_t     *mMainBuffer;
 
     int32_t             *mAuxBuffer;
@@ -188,7 +248,31 @@
 
     sp<media::VolumeHandler>  mVolumeHandler; // handles multiple VolumeShaper configs and operations
 
+    sp<OpPlayAudioMonitor>  mOpPlayAudioMonitor;
+
+    bool                mHapticPlaybackEnabled = false; // indicates haptic playback enabled or not
+    // intensity to play haptic data
+    AudioMixer::haptic_intensity_t mHapticIntensity = AudioMixer::HAPTIC_SCALE_MUTE;
+    class AudioVibrationController : public os::BnExternalVibrationController {
+    public:
+        explicit AudioVibrationController(Track* track) : mTrack(track) {}
+        binder::Status mute(/*out*/ bool *ret) override;
+        binder::Status unmute(/*out*/ bool *ret) override;
+    private:
+        Track* const mTrack;
+    };
+    sp<AudioVibrationController> mAudioVibrationController;
+    sp<os::ExternalVibration>    mExternalVibration;
+
 private:
+    void                interceptBuffer(const AudioBufferProvider::Buffer& buffer);
+    /** Write the source data in the buffer provider. @return written frame count. */
+    size_t              writeFrames(AudioBufferProvider* dest, const void* src, size_t frameCount);
+    template <class F>
+    void                forEachTeePatchTrack(F f) {
+        for (auto& tp : mTeePatches) { f(tp.patchTrack); }
+    };
+
     // The following fields are only for fast tracks, and should be in a subclass
     int                 mFastIndex; // index within FastMixerState::mFastTracks[];
                                     // either mFastIndex == -1 if not isFastTrack()
@@ -208,6 +292,7 @@
     audio_output_flags_t mFlags;
     // If the last track change was notified to the client with readAndClearHasChanged
     std::atomic_flag     mChangeNotified = ATOMIC_FLAG_INIT;
+    TeePatches  mTeePatches;
 };  // end of Track
 
 
@@ -233,7 +318,7 @@
                                     AudioSystem::SYNC_EVENT_NONE,
                              audio_session_t triggerSession = AUDIO_SESSION_NONE);
     virtual void        stop();
-            bool        write(void* data, uint32_t frames);
+            ssize_t     write(void* data, uint32_t frames);
             bool        bufferQueueEmpty() const { return mBufferQueue.size() == 0; }
             bool        isActive() const { return mActive; }
     const wp<ThreadBase>& thread() const { return mThread; }
@@ -241,6 +326,18 @@
             void        copyMetadataTo(MetadataInserter& backInserter) const override;
     /** Set the metadatas of the upstream tracks. Thread safe. */
             void        setMetadatas(const SourceMetadatas& metadatas);
+    /** returns client timestamp to the upstream duplicating thread. */
+    ExtendedTimestamp   getClientProxyTimestamp() const {
+                            // server - kernel difference is not true latency when drained
+                            // i.e. mServerProxy->isDrained().
+                            ExtendedTimestamp timestamp;
+                            (void) mClientProxy->getTimestamp(&timestamp);
+                            // On success, the timestamp LOCATION_SERVER and LOCATION_KERNEL
+                            // entries will be properly filled. If getTimestamp()
+                            // is unsuccessful, then a default initialized timestamp
+                            // (with mTimeNs[] filled with -1's) is returned.
+                            return timestamp;
+                        }
 
 private:
     status_t            obtainBuffer(AudioBufferProvider::Buffer* buffer,
@@ -257,6 +354,7 @@
     bool                        mActive;
     DuplicatingThread* const    mSourceThread; // for waitTimeMs() in write()
     sp<AudioTrackClientProxy>   mClientProxy;
+
     /** Attributes of the source tracks.
      *
      * This member must be accessed with mTrackMetadatasMutex taken.
@@ -274,7 +372,7 @@
 };  // end of OutputTrack
 
 // playback track, used by PatchPanel
-class PatchTrack : public Track, public PatchProxyBufferProvider {
+class PatchTrack : public Track, public PatchTrackBase {
 public:
 
                         PatchTrack(PlaybackThread *playbackThread,
@@ -285,7 +383,8 @@
                                    size_t frameCount,
                                    void *buffer,
                                    size_t bufferSize,
-                                   audio_output_flags_t flags);
+                                   audio_output_flags_t flags,
+                                   const Timeout& timeout = {});
     virtual             ~PatchTrack();
 
     virtual status_t    start(AudioSystem::sync_event_t event =
@@ -301,12 +400,7 @@
                                      const struct timespec *timeOut = NULL);
     virtual void        releaseBuffer(Proxy::Buffer* buffer);
 
-            void setPeerProxy(PatchProxyBufferProvider *proxy) { mPeerProxy = proxy; }
-
 private:
             void restartIfDisabled();
 
-    sp<ClientProxy>             mProxy;
-    PatchProxyBufferProvider*   mPeerProxy;
-    struct timespec             mPeerTimeout;
 };  // end of PatchTrack
diff --git a/services/audioflinger/RecordTracks.h b/services/audioflinger/RecordTracks.h
index 37b8f91..c8397cd 100644
--- a/services/audioflinger/RecordTracks.h
+++ b/services/audioflinger/RecordTracks.h
@@ -65,6 +65,7 @@
                                 void *buffer,
                                 size_t bufferSize,
                                 audio_session_t sessionId,
+                                pid_t creatorPid,
                                 uid_t uid,
                                 audio_input_flags_t flags,
                                 track_type type,
@@ -85,7 +86,7 @@
             bool        setOverflow() { bool tmp = mOverflow; mOverflow = true;
                                                 return tmp; }
 
-    static  void        appendDumpHeader(String8& result);
+            void        appendDumpHeader(String8& result);
             void        appendDump(String8& result, bool active);
 
             void        handleSyncStartEvent(const sp<SyncEvent>& event);
@@ -97,12 +98,23 @@
                                              const ExtendedTimestamp &timestamp);
 
     virtual bool        isFastTrack() const { return (mFlags & AUDIO_INPUT_FLAG_FAST) != 0; }
+            bool        isDirect() const override
+                                { return (mFlags & AUDIO_INPUT_FLAG_DIRECT) != 0; }
 
             void        setSilenced(bool silenced) { if (!isPatchTrack()) mSilenced = silenced; }
             bool        isSilenced() const;
 
             status_t    getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones);
 
+            status_t    setPreferredMicrophoneDirection(audio_microphone_direction_t direction);
+            status_t    setPreferredMicrophoneFieldDimension(float zoom);
+
+    static  bool        checkServerLatencySupported(
+                                audio_format_t format, audio_input_flags_t flags) {
+                            return audio_is_linear_pcm(format)
+                                    && (flags & AUDIO_INPUT_FLAG_HW_AV_SYNC) == 0;
+                        }
+
 private:
     friend class AudioFlinger;  // for mState
 
@@ -141,7 +153,7 @@
 };
 
 // playback track, used by PatchPanel
-class PatchRecord : virtual public RecordTrack, public PatchProxyBufferProvider {
+class PatchRecord : public RecordTrack, public PatchTrackBase {
 public:
 
     PatchRecord(RecordThread *recordThread,
@@ -151,7 +163,8 @@
                 size_t frameCount,
                 void *buffer,
                 size_t bufferSize,
-                audio_input_flags_t flags);
+                audio_input_flags_t flags,
+                const Timeout& timeout = {});
     virtual             ~PatchRecord();
 
     // AudioBufferProvider interface
@@ -162,11 +175,4 @@
     virtual status_t    obtainBuffer(Proxy::Buffer *buffer,
                                      const struct timespec *timeOut = NULL);
     virtual void        releaseBuffer(Proxy::Buffer *buffer);
-
-    void setPeerProxy(PatchProxyBufferProvider *proxy) { mPeerProxy = proxy; }
-
-private:
-    sp<ClientProxy>             mProxy;
-    PatchProxyBufferProvider*   mPeerProxy;
-    struct timespec             mPeerTimeout;
 };  // end of PatchRecord
diff --git a/services/audioflinger/ServiceUtilities.cpp b/services/audioflinger/ServiceUtilities.cpp
deleted file mode 100644
index aa267ea..0000000
--- a/services/audioflinger/ServiceUtilities.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <binder/AppOpsManager.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <binder/PermissionCache.h>
-#include <private/android_filesystem_config.h>
-#include "ServiceUtilities.h"
-
-/* When performing permission checks we do not use permission cache for
- * runtime permissions (protection level dangerous) as they may change at
- * runtime. All other permissions (protection level normal and dangerous)
- * can be cached as they never change. Of course all permission checked
- * here are platform defined.
- */
-
-namespace android {
-
-static const String16 sAndroidPermissionRecordAudio("android.permission.RECORD_AUDIO");
-
-// Not valid until initialized by AudioFlinger constructor.  It would have to be
-// re-initialized if the process containing AudioFlinger service forks (which it doesn't).
-// This is often used to validate binder interface calls within audioserver
-// (e.g. AudioPolicyManager to AudioFlinger).
-pid_t getpid_cached;
-
-// A trusted calling UID may specify the client UID as part of a binder interface call.
-// otherwise the calling UID must be equal to the client UID.
-bool isTrustedCallingUid(uid_t uid) {
-    switch (uid) {
-    case AID_MEDIA:
-    case AID_AUDIOSERVER:
-        return true;
-    default:
-        return false;
-    }
-}
-
-static String16 resolveCallingPackage(PermissionController& permissionController,
-        const String16& opPackageName, uid_t uid) {
-    if (opPackageName.size() > 0) {
-        return opPackageName;
-    }
-    // In some cases the calling code has no access to the package it runs under.
-    // For example, code using the wilhelm framework's OpenSL-ES APIs. In this
-    // case we will get the packages for the calling UID and pick the first one
-    // for attributing the app op. This will work correctly for runtime permissions
-    // as for legacy apps we will toggle the app op for all packages in the UID.
-    // The caveat is that the operation may be attributed to the wrong package and
-    // stats based on app ops may be slightly off.
-    Vector<String16> packages;
-    permissionController.getPackagesForUid(uid, packages);
-    if (packages.isEmpty()) {
-        ALOGE("No packages for uid %d", uid);
-        return opPackageName; // empty string
-    }
-    return packages[0];
-}
-
-static inline bool isAudioServerOrRoot(uid_t uid) {
-    // AID_ROOT is OK for command-line tests.  Native unforked audioserver always OK.
-    return uid == AID_ROOT || uid == AID_AUDIOSERVER ;
-}
-
-static bool checkRecordingInternal(const String16& opPackageName, pid_t pid,
-        uid_t uid, bool start) {
-    // Okay to not track in app ops as audio server is us and if
-    // device is rooted security model is considered compromised.
-    if (isAudioServerOrRoot(uid)) return true;
-
-    // We specify a pid and uid here as mediaserver (aka MediaRecorder or StageFrightRecorder)
-    // may open a record track on behalf of a client.  Note that pid may be a tid.
-    // IMPORTANT: DON'T USE PermissionCache - RUNTIME PERMISSIONS CHANGE.
-    PermissionController permissionController;
-    const bool ok = permissionController.checkPermission(sAndroidPermissionRecordAudio, pid, uid);
-    if (!ok) {
-        ALOGE("Request requires %s", String8(sAndroidPermissionRecordAudio).c_str());
-        return false;
-    }
-
-    String16 resolvedOpPackageName = resolveCallingPackage(
-            permissionController, opPackageName, uid);
-    if (resolvedOpPackageName.size() == 0) {
-        return false;
-    }
-
-    AppOpsManager appOps;
-    const int32_t op = appOps.permissionToOpCode(sAndroidPermissionRecordAudio);
-    if (start) {
-        if (appOps.startOpNoThrow(op, uid, resolvedOpPackageName, /*startIfModeDefault*/ false)
-                != AppOpsManager::MODE_ALLOWED) {
-            ALOGE("Request denied by app op: %d", op);
-            return false;
-        }
-    } else {
-        if (appOps.noteOp(op, uid, resolvedOpPackageName) != AppOpsManager::MODE_ALLOWED) {
-            ALOGE("Request denied by app op: %d", op);
-            return false;
-        }
-    }
-
-    return true;
-}
-
-bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid) {
-    return checkRecordingInternal(opPackageName, pid, uid, /*start*/ false);
-}
-
-bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid) {
-     return checkRecordingInternal(opPackageName, pid, uid, /*start*/ true);
-}
-
-void finishRecording(const String16& opPackageName, uid_t uid) {
-    // Okay to not track in app ops as audio server is us and if
-    // device is rooted security model is considered compromised.
-    if (isAudioServerOrRoot(uid)) return;
-
-    PermissionController permissionController;
-    String16 resolvedOpPackageName = resolveCallingPackage(
-            permissionController, opPackageName, uid);
-    if (resolvedOpPackageName.size() == 0) {
-        return;
-    }
-
-    AppOpsManager appOps;
-    const int32_t op = appOps.permissionToOpCode(sAndroidPermissionRecordAudio);
-    appOps.finishOp(op, uid, resolvedOpPackageName);
-}
-
-bool captureAudioOutputAllowed(pid_t pid, uid_t uid) {
-    if (getpid_cached == IPCThreadState::self()->getCallingPid()) return true;
-    static const String16 sCaptureAudioOutput("android.permission.CAPTURE_AUDIO_OUTPUT");
-    bool ok = PermissionCache::checkPermission(sCaptureAudioOutput, pid, uid);
-    if (!ok) ALOGE("Request requires android.permission.CAPTURE_AUDIO_OUTPUT");
-    return ok;
-}
-
-bool captureHotwordAllowed(pid_t pid, uid_t uid) {
-    // CAPTURE_AUDIO_HOTWORD permission implies RECORD_AUDIO permission
-    bool ok = recordingAllowed(String16(""), pid, uid);
-
-    if (ok) {
-        static const String16 sCaptureHotwordAllowed("android.permission.CAPTURE_AUDIO_HOTWORD");
-        // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
-        ok = PermissionCache::checkCallingPermission(sCaptureHotwordAllowed);
-    }
-    if (!ok) ALOGE("android.permission.CAPTURE_AUDIO_HOTWORD");
-    return ok;
-}
-
-bool settingsAllowed() {
-    if (getpid_cached == IPCThreadState::self()->getCallingPid()) return true;
-    static const String16 sAudioSettings("android.permission.MODIFY_AUDIO_SETTINGS");
-    // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
-    bool ok = PermissionCache::checkCallingPermission(sAudioSettings);
-    if (!ok) ALOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
-    return ok;
-}
-
-bool modifyAudioRoutingAllowed() {
-    static const String16 sModifyAudioRoutingAllowed("android.permission.MODIFY_AUDIO_ROUTING");
-    // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
-    bool ok = PermissionCache::checkCallingPermission(sModifyAudioRoutingAllowed);
-    if (!ok) ALOGE("android.permission.MODIFY_AUDIO_ROUTING");
-    return ok;
-}
-
-bool dumpAllowed() {
-    // don't optimize for same pid, since mediaserver never dumps itself
-    static const String16 sDump("android.permission.DUMP");
-    // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
-    bool ok = PermissionCache::checkCallingPermission(sDump);
-    // convention is for caller to dump an error message to fd instead of logging here
-    //if (!ok) ALOGE("Request requires android.permission.DUMP");
-    return ok;
-}
-
-bool modifyPhoneStateAllowed(pid_t pid, uid_t uid) {
-    static const String16 sModifyPhoneState("android.permission.MODIFY_PHONE_STATE");
-    bool ok = PermissionCache::checkPermission(sModifyPhoneState, pid, uid);
-    if (!ok) ALOGE("Request requires android.permission.MODIFY_PHONE_STATE");
-    return ok;
-}
-
-} // namespace android
diff --git a/services/audioflinger/ServiceUtilities.h b/services/audioflinger/ServiceUtilities.h
deleted file mode 100644
index 03756b3..0000000
--- a/services/audioflinger/ServiceUtilities.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <cutils/multiuser.h>
-#include <private/android_filesystem_config.h>
-#include <unistd.h>
-
-#include <binder/PermissionController.h>
-
-namespace android {
-
-// Used for calls that should originate from system services.
-// We allow that some services might have separate processes to
-// handle multiple users, e.g. u10_system, u10_bluetooth, u10_radio.
-static inline bool isServiceUid(uid_t uid) {
-    return multiuser_get_app_id(uid) < AID_APP_START;
-}
-
-extern pid_t getpid_cached;
-bool isTrustedCallingUid(uid_t uid);
-bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid);
-bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid);
-void finishRecording(const String16& opPackageName, uid_t uid);
-bool captureAudioOutputAllowed(pid_t pid, uid_t uid);
-bool captureHotwordAllowed(pid_t pid, uid_t uid);
-bool settingsAllowed();
-bool modifyAudioRoutingAllowed();
-bool dumpAllowed();
-bool modifyPhoneStateAllowed(pid_t pid, uid_t uid);
-}
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 4993420..8732273 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -23,6 +23,8 @@
 #include "Configuration.h"
 #include <math.h>
 #include <fcntl.h>
+#include <memory>
+#include <string>
 #include <linux/futex.h>
 #include <sys/stat.h>
 #include <sys/syscall.h>
@@ -36,10 +38,13 @@
 
 #include <private/media/AudioTrackShared.h>
 #include <private/android_filesystem_config.h>
+#include <audio_utils/Balance.h>
+#include <audio_utils/channels.h>
 #include <audio_utils/mono_blend.h>
 #include <audio_utils/primitives.h>
 #include <audio_utils/format.h>
 #include <audio_utils/minifloat.h>
+#include <audio_utils/safe_math.h>
 #include <system/audio_effects/effect_ns.h>
 #include <system/audio_effects/effect_aec.h>
 #include <system/audio.h>
@@ -54,6 +59,7 @@
 #include <media/nbaio/SourceAudioBufferProvider.h>
 #include <mediautils/BatteryNotifier.h>
 
+#include <audiomanager/AudioManager.h>
 #include <powermanager/PowerManager.h>
 
 #include <media/audiohal/EffectsFactoryHalInterface.h>
@@ -62,8 +68,8 @@
 #include "AudioFlinger.h"
 #include "FastMixer.h"
 #include "FastCapture.h"
-#include "ServiceUtilities.h"
-#include "mediautils/SchedulingPolicyService.h"
+#include <mediautils/SchedulingPolicyService.h>
+#include <mediautils/ServiceUtilities.h>
 
 #ifdef ADD_BATTERY_DATA
 #include <media/IMediaPlayerService.h>
@@ -71,7 +77,7 @@
 #endif
 
 #ifdef DEBUG_CPU_USAGE
-#include <cpustats/CentralTendencyStatistics.h>
+#include <audio_utils/Statistics.h>
 #include <cpustats/ThreadCpuUsage.h>
 #endif
 
@@ -200,7 +206,7 @@
 // Initially this heap is used to allocate client buffers for "fast" AudioRecord.
 // Eventually it will be the single buffer that FastCapture writes into via HAL read(),
 // and that all "fast" AudioRecord clients read from.  In either case, the size can be small.
-static const size_t kRecordThreadReadOnlyHeapSize = 0x4000;
+static const size_t kRecordThreadReadOnlyHeapSize = 0xD000;
 
 // ----------------------------------------------------------------------------
 
@@ -333,9 +339,9 @@
 #ifdef DEBUG_CPU_USAGE
 private:
     ThreadCpuUsage mCpuUsage;           // instantaneous thread CPU usage in wall clock ns
-    CentralTendencyStatistics mWcStats; // statistics on thread CPU usage in wall clock ns
+    audio_utils::Statistics<double> mWcStats; // statistics on thread CPU usage in wall clock ns
 
-    CentralTendencyStatistics mHzStats; // statistics on thread CPU usage in cycles
+    audio_utils::Statistics<double> mHzStats; // statistics on thread CPU usage in cycles
 
     int mCpuNum;                        // thread's current CPU number
     int mCpukHz;                        // frequency of thread's current CPU in kHz
@@ -361,7 +367,7 @@
 
     // record sample for wall clock statistics
     if (valid) {
-        mWcStats.sample(wcNs);
+        mWcStats.add(wcNs);
     }
 
     // get the current CPU number
@@ -380,26 +386,26 @@
 
     // if no change in CPU number or frequency, then record sample for cycle statistics
     if (valid && mCpukHz > 0) {
-        double cycles = wcNs * cpukHz * 0.000001;
-        mHzStats.sample(cycles);
+        const double cycles = wcNs * cpukHz * 0.000001;
+        mHzStats.add(cycles);
     }
 
-    unsigned n = mWcStats.n();
+    const unsigned n = mWcStats.getN();
     // mCpuUsage.elapsed() is expensive, so don't call it every loop
     if ((n & 127) == 1) {
-        long long elapsed = mCpuUsage.elapsed();
+        const long long elapsed = mCpuUsage.elapsed();
         if (elapsed >= DEBUG_CPU_USAGE * 1000000000LL) {
-            double perLoop = elapsed / (double) n;
-            double perLoop100 = perLoop * 0.01;
-            double perLoop1k = perLoop * 0.001;
-            double mean = mWcStats.mean();
-            double stddev = mWcStats.stddev();
-            double minimum = mWcStats.minimum();
-            double maximum = mWcStats.maximum();
-            double meanCycles = mHzStats.mean();
-            double stddevCycles = mHzStats.stddev();
-            double minCycles = mHzStats.minimum();
-            double maxCycles = mHzStats.maximum();
+            const double perLoop = elapsed / (double) n;
+            const double perLoop100 = perLoop * 0.01;
+            const double perLoop1k = perLoop * 0.001;
+            const double mean = mWcStats.getMean();
+            const double stddev = mWcStats.getStdDev();
+            const double minimum = mWcStats.getMin();
+            const double maximum = mWcStats.getMax();
+            const double meanCycles = mHzStats.getMean();
+            const double stddevCycles = mHzStats.getStdDev();
+            const double minCycles = mHzStats.getMin();
+            const double maxCycles = mHzStats.getMax();
             mCpuUsage.resetElapsed();
             mWcStats.reset();
             mHzStats.reset();
@@ -453,50 +459,6 @@
     }
 }
 
-std::string devicesToString(audio_devices_t devices)
-{
-    std::string result;
-    if (devices & AUDIO_DEVICE_BIT_IN) {
-        InputDeviceConverter::maskToString(devices, result);
-    } else {
-        OutputDeviceConverter::maskToString(devices, result);
-    }
-    return result;
-}
-
-std::string inputFlagsToString(audio_input_flags_t flags)
-{
-    std::string result;
-    InputFlagConverter::maskToString(flags, result);
-    return result;
-}
-
-std::string outputFlagsToString(audio_output_flags_t flags)
-{
-    std::string result;
-    OutputFlagConverter::maskToString(flags, result);
-    return result;
-}
-
-const char *sourceToString(audio_source_t source)
-{
-    switch (source) {
-    case AUDIO_SOURCE_DEFAULT:              return "default";
-    case AUDIO_SOURCE_MIC:                  return "mic";
-    case AUDIO_SOURCE_VOICE_UPLINK:         return "voice uplink";
-    case AUDIO_SOURCE_VOICE_DOWNLINK:       return "voice downlink";
-    case AUDIO_SOURCE_VOICE_CALL:           return "voice call";
-    case AUDIO_SOURCE_CAMCORDER:            return "camcorder";
-    case AUDIO_SOURCE_VOICE_RECOGNITION:    return "voice recognition";
-    case AUDIO_SOURCE_VOICE_COMMUNICATION:  return "voice communication";
-    case AUDIO_SOURCE_REMOTE_SUBMIX:        return "remote submix";
-    case AUDIO_SOURCE_UNPROCESSED:          return "unprocessed";
-    case AUDIO_SOURCE_FM_TUNER:             return "FM tuner";
-    case AUDIO_SOURCE_HOTWORD:              return "hotword";
-    default:                                return "unknown";
-    }
-}
-
 AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
         audio_devices_t outDevice, audio_devices_t inDevice, type_t type, bool systemReady)
     :   Thread(false /*canCallJava*/),
@@ -528,6 +490,8 @@
         sp<IBinder> binder = IInterface::asBinder(mPowerManager);
         binder->unlinkToDeath(mDeathRecipient);
     }
+
+    sendStatistics(true /* force */);
 }
 
 status_t AudioFlinger::ThreadBase::readyToRun()
@@ -602,16 +566,27 @@
     return status;
 }
 
-void AudioFlinger::ThreadBase::sendIoConfigEvent(audio_io_config_event event, pid_t pid)
+void AudioFlinger::ThreadBase::sendIoConfigEvent(audio_io_config_event event, pid_t pid,
+                                                 audio_port_handle_t portId)
 {
     Mutex::Autolock _l(mLock);
-    sendIoConfigEvent_l(event, pid);
+    sendIoConfigEvent_l(event, pid, portId);
 }
 
 // sendIoConfigEvent_l() must be called with ThreadBase::mLock held
-void AudioFlinger::ThreadBase::sendIoConfigEvent_l(audio_io_config_event event, pid_t pid)
+void AudioFlinger::ThreadBase::sendIoConfigEvent_l(audio_io_config_event event, pid_t pid,
+                                                   audio_port_handle_t portId)
 {
-    sp<ConfigEvent> configEvent = (ConfigEvent *)new IoConfigEvent(event, pid);
+    // The audio statistics history is exponentially weighted to forget events
+    // about five or more seconds in the past.  In order to have
+    // crisper statistics for mediametrics, we reset the statistics on
+    // an IoConfigEvent, to reflect different properties for a new device.
+    mIoJitterMs.reset();
+    mLatencyMs.reset();
+    mProcessTimeMs.reset();
+    mTimestampVerifier.discontinuity();
+
+    sp<ConfigEvent> configEvent = (ConfigEvent *)new IoConfigEvent(event, pid, portId);
     sendConfigEvent_l(configEvent);
 }
 
@@ -694,7 +669,7 @@
         } break;
         case CFG_EVENT_IO: {
             IoConfigEventData *data = (IoConfigEventData *)event->mData.get();
-            ioConfigChanged(data->mEvent, data->mPid);
+            ioConfigChanged(data->mEvent, data->mPid, data->mPortId);
         } break;
         case CFG_EVENT_SET_PARAMETER: {
             SetParameterConfigEventData *data = (SetParameterConfigEventData *)event->mData.get();
@@ -711,8 +686,8 @@
             event->mStatus = createAudioPatch_l(&data->mPatch, &data->mHandle);
             const audio_devices_t newDevice = getDevice();
             mLocalLog.log("CFG_EVENT_CREATE_AUDIO_PATCH: old device %#x (%s) new device %#x (%s)",
-                    (unsigned)oldDevice, devicesToString(oldDevice).c_str(),
-                    (unsigned)newDevice, devicesToString(newDevice).c_str());
+                    (unsigned)oldDevice, toString(oldDevice).c_str(),
+                    (unsigned)newDevice, toString(newDevice).c_str());
         } break;
         case CFG_EVENT_RELEASE_AUDIO_PATCH: {
             const audio_devices_t oldDevice = getDevice();
@@ -721,8 +696,8 @@
             event->mStatus = releaseAudioPatch_l(data->mHandle);
             const audio_devices_t newDevice = getDevice();
             mLocalLog.log("CFG_EVENT_RELEASE_AUDIO_PATCH: old device %#x (%s) new device %#x (%s)",
-                    (unsigned)oldDevice, devicesToString(oldDevice).c_str(),
-                    (unsigned)newDevice, devicesToString(newDevice).c_str());
+                    (unsigned)oldDevice, toString(oldDevice).c_str(),
+                    (unsigned)newDevice, toString(newDevice).c_str());
         } break;
         default:
             ALOG_ASSERT(false, "processConfigEvents_l() unknown event type %d", event->mType);
@@ -749,6 +724,7 @@
             audio_channel_mask_get_representation(mask);
 
     switch (representation) {
+    // Travel all single bit channel mask to convert channel mask to string.
     case AUDIO_CHANNEL_REPRESENTATION_POSITION: {
         if (output) {
             if (mask & AUDIO_CHANNEL_OUT_FRONT_LEFT) s.append("front-left, ");
@@ -769,6 +745,10 @@
             if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_LEFT) s.append("top-back-left, ");
             if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_CENTER) s.append("top-back-center, " );
             if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT) s.append("top-back-right, " );
+            if (mask & AUDIO_CHANNEL_OUT_TOP_SIDE_LEFT) s.append("top-side-left, " );
+            if (mask & AUDIO_CHANNEL_OUT_TOP_SIDE_RIGHT) s.append("top-side-right, " );
+            if (mask & AUDIO_CHANNEL_OUT_HAPTIC_B) s.append("haptic-B, " );
+            if (mask & AUDIO_CHANNEL_OUT_HAPTIC_A) s.append("haptic-A, " );
             if (mask & ~AUDIO_CHANNEL_OUT_ALL) s.append("unknown,  ");
         } else {
             if (mask & AUDIO_CHANNEL_IN_LEFT) s.append("left, ");
@@ -783,6 +763,12 @@
             if (mask & AUDIO_CHANNEL_IN_X_AXIS) s.append("X, ");
             if (mask & AUDIO_CHANNEL_IN_Y_AXIS) s.append("Y, ");
             if (mask & AUDIO_CHANNEL_IN_Z_AXIS) s.append("Z, ");
+            if (mask & AUDIO_CHANNEL_IN_BACK_LEFT) s.append("back-left, ");
+            if (mask & AUDIO_CHANNEL_IN_BACK_RIGHT) s.append("back-right, ");
+            if (mask & AUDIO_CHANNEL_IN_CENTER) s.append("center, ");
+            if (mask & AUDIO_CHANNEL_IN_LOW_FREQUENCY) s.append("low freq, ");
+            if (mask & AUDIO_CHANNEL_IN_TOP_LEFT) s.append("top-left, " );
+            if (mask & AUDIO_CHANNEL_IN_TOP_RIGHT) s.append("top-right, " );
             if (mask & AUDIO_CHANNEL_IN_VOICE_UPLINK) s.append("voice-uplink, ");
             if (mask & AUDIO_CHANNEL_IN_VOICE_DNLINK) s.append("voice-dnlink, ");
             if (mask & ~AUDIO_CHANNEL_IN_ALL) s.append("unknown,  ");
@@ -804,12 +790,8 @@
     }
 }
 
-void AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args __unused)
+void AudioFlinger::ThreadBase::dump(int fd, const Vector<String16>& args)
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
     dprintf(fd, "\n%s thread %p, name %s, tid %d, type %d (%s):\n", isOutput() ? "Output" : "Input",
             this, mThreadName, getTid(), type(), threadTypeToString(type()));
 
@@ -818,6 +800,21 @@
         dprintf(fd, "  Thread may be deadlocked\n");
     }
 
+    dumpBase_l(fd, args);
+    dumpInternals_l(fd, args);
+    dumpTracks_l(fd, args);
+    dumpEffectChains_l(fd, args);
+
+    if (locked) {
+        mLock.unlock();
+    }
+
+    dprintf(fd, "  Local log:\n");
+    mLocalLog.dump(fd, "   " /* prefix */, 40 /* lines */);
+}
+
+void AudioFlinger::ThreadBase::dumpBase_l(int fd, const Vector<String16>& args __unused)
+{
     dprintf(fd, "  I/O handle: %d\n", mId);
     dprintf(fd, "  Standby: %s\n", mStandby ? "yes" : "no");
     dprintf(fd, "  Sample rate: %u Hz\n", mSampleRate);
@@ -832,6 +829,8 @@
     dprintf(fd, "  Pending config events:");
     size_t numConfig = mConfigEvents.size();
     if (numConfig) {
+        const size_t SIZE = 256;
+        char buffer[SIZE];
         for (size_t i = 0; i < numConfig; i++) {
             mConfigEvents[i]->dump(buffer, SIZE);
             dprintf(fd, "\n    %s", buffer);
@@ -841,20 +840,47 @@
         dprintf(fd, " none\n");
     }
     // Note: output device may be used by capture threads for effects such as AEC.
-    dprintf(fd, "  Output device: %#x (%s)\n", mOutDevice, devicesToString(mOutDevice).c_str());
-    dprintf(fd, "  Input device: %#x (%s)\n", mInDevice, devicesToString(mInDevice).c_str());
-    dprintf(fd, "  Audio source: %d (%s)\n", mAudioSource, sourceToString(mAudioSource));
+    dprintf(fd, "  Output device: %#x (%s)\n", mOutDevice, toString(mOutDevice).c_str());
+    dprintf(fd, "  Input device: %#x (%s)\n", mInDevice, toString(mInDevice).c_str());
+    dprintf(fd, "  Audio source: %d (%s)\n", mAudioSource, toString(mAudioSource).c_str());
 
-    if (locked) {
-        mLock.unlock();
+    // Dump timestamp statistics for the Thread types that support it.
+    if (mType == RECORD
+            || mType == MIXER
+            || mType == DUPLICATING
+            || mType == DIRECT
+            || mType == OFFLOAD) {
+        dprintf(fd, "  Timestamp stats: %s\n", mTimestampVerifier.toString().c_str());
+        dprintf(fd, "  Timestamp corrected: %s\n", isTimestampCorrectionEnabled() ? "yes" : "no");
+    }
+
+    if (mLastIoBeginNs > 0) { // MMAP may not set this
+        dprintf(fd, "  Last %s occurred (msecs): %lld\n",
+                isOutput() ? "write" : "read",
+                (long long) (systemTime() - mLastIoBeginNs) / NANOS_PER_MILLISECOND);
+    }
+
+    if (mProcessTimeMs.getN() > 0) {
+        dprintf(fd, "  Process time ms stats: %s\n", mProcessTimeMs.toString().c_str());
+    }
+
+    if (mIoJitterMs.getN() > 0) {
+        dprintf(fd, "  Hal %s jitter ms stats: %s\n",
+                isOutput() ? "write" : "read",
+                mIoJitterMs.toString().c_str());
+    }
+
+    if (mLatencyMs.getN() > 0) {
+        dprintf(fd, "  Threadloop %s latency stats: %s\n",
+                isOutput() ? "write" : "read",
+                mLatencyMs.toString().c_str());
     }
 }
 
-void AudioFlinger::ThreadBase::dumpEffectChains(int fd, const Vector<String16>& args)
+void AudioFlinger::ThreadBase::dumpEffectChains_l(int fd, const Vector<String16>& args)
 {
     const size_t SIZE = 256;
     char buffer[SIZE];
-    String8 result;
 
     size_t numEffectChains = mEffectChains.size();
     snprintf(buffer, SIZE, "  %zu Effect Chains\n", numEffectChains);
@@ -1283,7 +1309,6 @@
     sp<EffectChain> chain;
     bool chainCreated = false;
     bool effectCreated = false;
-    bool effectRegistered = false;
     audio_unique_id_t effectId = AUDIO_UNIQUE_ID_USE_UNSPECIFIED;
 
     lStatus = initCheck();
@@ -1319,13 +1344,6 @@
 
         if (effect == 0) {
             effectId = mAudioFlinger->nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT);
-            // Check CPU and memory usage
-            lStatus = AudioSystem::registerEffect(
-                    desc, mId, chain->strategy(), sessionId, effectId);
-            if (lStatus != NO_ERROR) {
-                goto Exit;
-            }
-            effectRegistered = true;
             // create a new effect module if none present in the chain
             lStatus = chain->createEffect_l(effect, this, desc, effectId, sessionId, pinned);
             if (lStatus != NO_ERROR) {
@@ -1355,9 +1373,6 @@
         if (effectCreated) {
             chain->removeEffect_l(effect);
         }
-        if (effectRegistered) {
-            AudioSystem::unregisterEffect(effectId);
-        }
         if (chainCreated) {
             removeEffectChain_l(chain);
         }
@@ -1388,7 +1403,6 @@
     }
     if (remove) {
         mAudioFlinger->updateOrphanEffectChains(effect);
-        AudioSystem::unregisterEffect(effect->id());
         if (handle->enabled()) {
             checkSuspendOnEffectEnabled(effect, false, effect->sessionId());
         }
@@ -1409,6 +1423,12 @@
     return chain != 0 ? chain->getEffectFromId_l(effectId) : 0;
 }
 
+std::vector<int> AudioFlinger::ThreadBase::getEffectIds_l(audio_session_t sessionId)
+{
+    sp<EffectChain> chain = getEffectChain_l(sessionId);
+    return chain != nullptr ? chain->getEffectIds() : std::vector<int>{};
+}
+
 // PlaybackThread::addEffect_l() must be called with AudioFlinger::mLock and
 // PlaybackThread::mLock held
 status_t AudioFlinger::ThreadBase::addEffect_l(const sp<EffectModule>& effect)
@@ -1519,7 +1539,7 @@
     }
 }
 
-void AudioFlinger::ThreadBase::getAudioPortConfig(struct audio_port_config *config)
+void AudioFlinger::ThreadBase::toAudioPortConfig(struct audio_port_config *config)
 {
     config->type = AUDIO_PORT_TYPE_MIX;
     config->ext.mix.handle = mId;
@@ -1571,6 +1591,9 @@
     --mBatteryCounter[track->uid()].second;
     // mLatestActiveTrack is not cleared even if is the same as track.
     mHasChanged = true;
+#ifdef TEE_SINK
+    track->dumpTee(-1 /* fd */, "_REMOVE");
+#endif
     return index;
 }
 
@@ -1645,6 +1668,65 @@
     mWaitWorkCV.broadcast();
 }
 
+// Call only from threadLoop() or when it is idle.
+// Do not call from high performance code as this may do binder rpc to the MediaMetrics service.
+void AudioFlinger::ThreadBase::sendStatistics(bool force)
+{
+    // Do not log if we have no stats.
+    // We choose the timestamp verifier because it is the most likely item to be present.
+    const int64_t nstats = mTimestampVerifier.getN() - mLastRecordedTimestampVerifierN;
+    if (nstats == 0) {
+        return;
+    }
+
+    // Don't log more frequently than once per 12 hours.
+    // We use BOOTTIME to include suspend time.
+    const int64_t timeNs = systemTime(SYSTEM_TIME_BOOTTIME);
+    const int64_t sinceNs = timeNs - mLastRecordedTimeNs; // ok if mLastRecordedTimeNs = 0
+    if (!force && sinceNs <= 12 * NANOS_PER_HOUR) {
+        return;
+    }
+
+    mLastRecordedTimestampVerifierN = mTimestampVerifier.getN();
+    mLastRecordedTimeNs = timeNs;
+
+    std::unique_ptr<MediaAnalyticsItem> item(MediaAnalyticsItem::create("audiothread"));
+
+#define MM_PREFIX "android.media.audiothread." // avoid cut-n-paste errors.
+
+    // thread configuration
+    item->setInt32(MM_PREFIX "id", (int32_t)mId); // IO handle
+    // item->setInt32(MM_PREFIX "portId", (int32_t)mPortId);
+    item->setCString(MM_PREFIX "type", threadTypeToString(mType));
+    item->setInt32(MM_PREFIX "sampleRate", (int32_t)mSampleRate);
+    item->setInt64(MM_PREFIX "channelMask", (int64_t)mChannelMask);
+    item->setCString(MM_PREFIX "encoding", toString(mFormat).c_str());
+    item->setInt32(MM_PREFIX "frameCount", (int32_t)mFrameCount);
+    item->setCString(MM_PREFIX "outDevice", toString(mOutDevice).c_str());
+    item->setCString(MM_PREFIX "inDevice", toString(mInDevice).c_str());
+
+    // thread statistics
+    if (mIoJitterMs.getN() > 0) {
+        item->setDouble(MM_PREFIX "ioJitterMs.mean", mIoJitterMs.getMean());
+        item->setDouble(MM_PREFIX "ioJitterMs.std", mIoJitterMs.getStdDev());
+    }
+    if (mProcessTimeMs.getN() > 0) {
+        item->setDouble(MM_PREFIX "processTimeMs.mean", mProcessTimeMs.getMean());
+        item->setDouble(MM_PREFIX "processTimeMs.std", mProcessTimeMs.getStdDev());
+    }
+    const auto tsjitter = mTimestampVerifier.getJitterMs();
+    if (tsjitter.getN() > 0) {
+        item->setDouble(MM_PREFIX "timestampJitterMs.mean", tsjitter.getMean());
+        item->setDouble(MM_PREFIX "timestampJitterMs.std", tsjitter.getStdDev());
+    }
+    if (mLatencyMs.getN() > 0) {
+        item->setDouble(MM_PREFIX "latencyMs.mean", mLatencyMs.getMean());
+        item->setDouble(MM_PREFIX "latencyMs.std", mLatencyMs.getStdDev());
+    }
+
+    item->selfrecord();
+}
+
 // ----------------------------------------------------------------------------
 //      Playback
 // ----------------------------------------------------------------------------
@@ -1674,7 +1756,7 @@
         // mStreamTypes[] initialized in constructor body
         mTracks(type == MIXER),
         mOutput(output),
-        mLastWriteTime(-1), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),
+        mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),
         mMixerStatus(MIXER_IDLE),
         mMixerStatusIgnoringFastTracks(MIXER_IDLE),
         mStandbyDelayNs(AudioFlinger::mStandbyTimeInNsecs),
@@ -1709,10 +1791,21 @@
         if (mOutput->audioHwDev->canSetMasterMute()) {
             mMasterMute = false;
         }
+        mIsMsdDevice = strcmp(
+                mOutput->audioHwDev->moduleName(), AUDIO_HARDWARE_MODULE_ID_MSD) == 0;
     }
 
     readOutputParameters_l();
 
+    // TODO: We may also match on address as well as device type for
+    // AUDIO_DEVICE_OUT_BUS, AUDIO_DEVICE_OUT_ALL_A2DP, AUDIO_DEVICE_OUT_REMOTE_SUBMIX
+    if (type == MIXER || type == DIRECT) {
+        mTimestampCorrectedDevices = (audio_devices_t)property_get_int64(
+                "audio.timestamp.corrected_output_devices",
+                (int64_t)(mIsMsdDevice ? AUDIO_DEVICE_OUT_BUS // turn on by default for MSD
+                                       : AUDIO_DEVICE_NONE));
+    }
+
     // ++ operator does not compile
     for (audio_stream_type_t stream = AUDIO_STREAM_MIN; stream < AUDIO_STREAM_FOR_POLICY_CNT;
             stream = (audio_stream_type_t) (stream + 1)) {
@@ -1732,16 +1825,24 @@
     free(mEffectBuffer);
 }
 
-void AudioFlinger::PlaybackThread::dump(int fd, const Vector<String16>& args)
+// Thread virtuals
+
+void AudioFlinger::PlaybackThread::onFirstRef()
 {
-    dumpInternals(fd, args);
-    dumpTracks(fd, args);
-    dumpEffectChains(fd, args);
-    dprintf(fd, "  Local log:\n");
-    mLocalLog.dump(fd, "   " /* prefix */, 40 /* lines */);
+    run(mThreadName, ANDROID_PRIORITY_URGENT_AUDIO);
 }
 
-void AudioFlinger::PlaybackThread::dumpTracks(int fd, const Vector<String16>& args __unused)
+// ThreadBase virtuals
+void AudioFlinger::PlaybackThread::preExit()
+{
+    ALOGV("  preExit()");
+    // FIXME this is using hard-coded strings but in the future, this functionality will be
+    //       converted to use audio HAL extensions required to support tunneling
+    status_t result = mOutput->stream->setParameters(String8("exiting=1"));
+    ALOGE_IF(result != OK, "Error when setting parameters on exit: %d", result);
+}
+
+void AudioFlinger::PlaybackThread::dumpTracks_l(int fd, const Vector<String16>& args __unused)
 {
     String8 result;
 
@@ -1773,7 +1874,7 @@
     if (numtracks) {
         dprintf(fd, " of which %zu are active\n", numactive);
         result.append(prefix);
-        Track::appendDumpHeader(result);
+        mTracks[0]->appendDumpHeader(result);
         for (size_t i = 0; i < numtracks; ++i) {
             sp<Track> track = mTracks[i];
             if (track != 0) {
@@ -1793,7 +1894,7 @@
         result.append("  The following tracks are in the active list but"
                 " not in the track list\n");
         result.append(prefix);
-        Track::appendDumpHeader(result);
+        mActiveTracks[0]->appendDumpHeader(result);
         for (size_t i = 0; i < numactive; ++i) {
             sp<Track> track = mActiveTracks[i];
             if (mTracks.indexOf(track) < 0) {
@@ -1806,13 +1907,14 @@
     write(fd, result.string(), result.size());
 }
 
-void AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String16>& args)
+void AudioFlinger::PlaybackThread::dumpInternals_l(int fd, const Vector<String16>& args __unused)
 {
-    dumpBase(fd, args);
-
+    dprintf(fd, "  Master mute: %s\n", mMasterMute ? "on" : "off");
+    if (mHapticChannelMask != AUDIO_CHANNEL_NONE) {
+        dprintf(fd, "  Haptic channel mask: %#x (%s)\n", mHapticChannelMask,
+                channelMaskToString(mHapticChannelMask, true /* output */).c_str());
+    }
     dprintf(fd, "  Normal frame count: %zu\n", mNormalFrameCount);
-    dprintf(fd, "  Last write occurred (msecs): %llu\n",
-            (unsigned long long) ns2ms(systemTime() - mLastWriteTime));
     dprintf(fd, "  Total writes: %d\n", mNumWrites);
     dprintf(fd, "  Delayed writes: %d\n", mNumDelayedWrites);
     dprintf(fd, "  Blocked in write: %s\n", mInWrite ? "yes" : "no");
@@ -1825,7 +1927,7 @@
     AudioStreamOut *output = mOutput;
     audio_output_flags_t flags = output != NULL ? output->flags : AUDIO_OUTPUT_FLAG_NONE;
     dprintf(fd, "  AudioStreamOut: %p flags %#x (%s)\n",
-            output, flags, outputFlagsToString(flags).c_str());
+            output, flags, toString(flags).c_str());
     dprintf(fd, "  Frames written: %lld\n", (long long)mFramesWritten);
     dprintf(fd, "  Suspended frames: %lld\n", (long long)mSuspendedFrames);
     if (mPipeSink.get() != nullptr) {
@@ -1837,23 +1939,6 @@
     }
 }
 
-// Thread virtuals
-
-void AudioFlinger::PlaybackThread::onFirstRef()
-{
-    run(mThreadName, ANDROID_PRIORITY_URGENT_AUDIO);
-}
-
-// ThreadBase virtuals
-void AudioFlinger::PlaybackThread::preExit()
-{
-    ALOGV("  preExit()");
-    // FIXME this is using hard-coded strings but in the future, this functionality will be
-    //       converted to use audio HAL extensions required to support tunneling
-    status_t result = mOutput->stream->setParameters(String8("exiting=1"));
-    ALOGE_IF(result != OK, "Error when setting parameters on exit: %d", result);
-}
-
 // PlaybackThread::createTrack_l() must be called with AudioFlinger::mLock held
 sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrack_l(
         const sp<AudioFlinger::Client>& client,
@@ -1869,6 +1954,7 @@
         const sp<IMemory>& sharedBuffer,
         audio_session_t sessionId,
         audio_output_flags_t *flags,
+        pid_t creatorPid,
         pid_t tid,
         uid_t uid,
         status_t *status,
@@ -1880,11 +1966,17 @@
     status_t lStatus;
     audio_output_flags_t outputFlags = mOutput->flags;
     audio_output_flags_t requestedFlags = *flags;
+    uint32_t sampleRate;
+
+    if (sharedBuffer != 0 && checkIMemory(sharedBuffer) != NO_ERROR) {
+        lStatus = BAD_VALUE;
+        goto Exit;
+    }
 
     if (*pSampleRate == 0) {
         *pSampleRate = mSampleRate;
     }
-    uint32_t sampleRate = *pSampleRate;
+    sampleRate = *pSampleRate;
 
     // special case for FAST flag considered OK if fast mixer is present
     if (hasFastMixer()) {
@@ -1905,7 +1997,7 @@
             audio_is_linear_pcm(format) &&
             // TODO: extract as a data library function that checks that a computationally
             // expensive downmixer is not required: isFastOutputChannelConversion()
-            (channelMask == mChannelMask ||
+            (channelMask == (mChannelMask | mHapticChannelMask) ||
                     mChannelMask != AUDIO_CHANNEL_OUT_STEREO ||
                     (channelMask == AUDIO_CHANNEL_OUT_MONO
                             /* && mChannelMask == AUDIO_CHANNEL_OUT_STEREO */)) &&
@@ -2043,9 +2135,15 @@
             // notify every HAL buffer, regardless of the size of the track buffer
             maxNotificationFrames = mFrameCount;
         } else {
-            // For normal tracks, use at least double-buffering if no sample rate conversion,
-            // or at least triple-buffering if there is sample rate conversion
-            const int nBuffering = sampleRate == mSampleRate ? 2 : 3;
+            // Triple buffer the notification period for a triple buffered mixer period;
+            // otherwise, double buffering for the notification period is fine.
+            //
+            // TODO: This should be moved to AudioTrack to modify the notification period
+            // on AudioTrack::setBufferSizeInFrames() changes.
+            const int nBuffering =
+                    (uint64_t{frameCount} * mSampleRate)
+                            / (uint64_t{mNormalFrameCount} * sampleRate) == 3 ? 3 : 2;
+
             maxNotificationFrames = frameCount / nBuffering;
             // If client requested a fast track but this was denied, then use the smaller maximum.
             if (requestedFlags & AUDIO_OUTPUT_FLAG_FAST) {
@@ -2140,7 +2238,7 @@
         track = new Track(this, client, streamType, attr, sampleRate, format,
                           channelMask, frameCount,
                           nullptr /* buffer */, (size_t)0 /* bufferSize */, sharedBuffer,
-                          sessionId, uid, *flags, TrackBase::TYPE_DEFAULT, portId);
+                          sessionId, creatorPid, uid, *flags, TrackBase::TYPE_DEFAULT, portId);
 
         lStatus = track != 0 ? track->initCheck() : (status_t) NO_MEMORY;
         if (lStatus != NO_ERROR) {
@@ -2174,48 +2272,17 @@
 }
 
 template<typename T>
-ssize_t AudioFlinger::PlaybackThread::Tracks<T>::add(const sp<T> &track)
-{
-    const ssize_t index = mTracks.add(track);
-    if (index >= 0) {
-        // set name for track when adding.
-        int name;
-        if (mUnusedTrackNames.empty()) {
-            name = mTracks.size() - 1; // new name {0 ... size-1}.
-        } else {
-            // reuse smallest name for deleted track.
-            auto it = mUnusedTrackNames.begin();
-            name = *it;
-            (void)mUnusedTrackNames.erase(it);
-        }
-        track->setName(name);
-    } else {
-        LOG_ALWAYS_FATAL("cannot add track");
-    }
-    return index;
-}
-
-template<typename T>
 ssize_t AudioFlinger::PlaybackThread::Tracks<T>::remove(const sp<T> &track)
 {
-    const int name = track->name();
+    const int trackId = track->id();
     const ssize_t index = mTracks.remove(track);
     if (index >= 0) {
-        // invalidate name when removing from mTracks.
-        LOG_ALWAYS_FATAL_IF(name < 0, "invalid name %d for track on mTracks", name);
-
-        if (mSaveDeletedTrackNames) {
+        if (mSaveDeletedTrackIds) {
             // We can't directly access mAudioMixer since the caller may be outside of threadLoop.
-            // Instead, we add to mDeletedTrackNames which is solely used for mAudioMixer update,
+            // Instead, we add to mDeletedTrackIds which is solely used for mAudioMixer update,
             // to be handled when MixerThread::prepareTracks_l() next changes mAudioMixer.
-            mDeletedTrackNames.emplace(name);
+            mDeletedTrackIds.emplace(trackId);
         }
-
-        mUnusedTrackNames.emplace(name);
-        track->setName(T::TRACK_NAME_PENDING);
-    } else {
-        LOG_ALWAYS_FATAL_IF(name >= 0,
-                "valid name %d for track not in mTracks (returned %zd)", name, index);
     }
     return index;
 }
@@ -2251,6 +2318,11 @@
     }
 }
 
+void AudioFlinger::PlaybackThread::setMasterBalance(float balance)
+{
+    mMasterBalance.store(balance);
+}
+
 void AudioFlinger::PlaybackThread::setMasterMute(bool muted)
 {
     if (isDuplicating()) {
@@ -2286,6 +2358,11 @@
     return mStreamTypes[stream].volume;
 }
 
+void AudioFlinger::PlaybackThread::setVolumeForOutput_l(float left, float right) const
+{
+    mOutput->stream->setVolume(left, right);
+}
+
 // addTrack_l() must be called with ThreadBase::mLock held
 status_t AudioFlinger::PlaybackThread::addTrack_l(const sp<Track>& track)
 {
@@ -2298,15 +2375,13 @@
         if (track->isExternalTrack()) {
             TrackBase::track_state state = track->mState;
             mLock.unlock();
-            status = AudioSystem::startOutput(mId, track->streamType(),
-                                              track->sessionId());
+            status = AudioSystem::startOutput(track->portId());
             mLock.lock();
             // abort track was stopped/paused while we released the lock
             if (state != track->mState) {
                 if (status == NO_ERROR) {
                     mLock.unlock();
-                    AudioSystem::stopOutput(mId, track->streamType(),
-                                            track->sessionId());
+                    AudioSystem::stopOutput(track->portId());
                     mLock.lock();
                 }
                 return INVALID_OPERATION;
@@ -2319,6 +2394,7 @@
             // to track the speaker usage
             addBatteryData(IMediaPlayerService::kBatteryDataAudioFlingerStart);
 #endif
+            sendIoConfigEvent_l(AUDIO_CLIENT_STARTED, track->creatorPid(), track->portId());
         }
 
         // set retry count for buffer fill
@@ -2335,6 +2411,25 @@
                     track->sharedBuffer() != 0 ? Track::FS_FILLED : Track::FS_FILLING;
         }
 
+        if ((track->channelMask() & AUDIO_CHANNEL_HAPTIC_ALL) != AUDIO_CHANNEL_NONE
+                && mHapticChannelMask != AUDIO_CHANNEL_NONE) {
+            // Unlock due to VibratorService will lock for this call and will
+            // call Tracks.mute/unmute which also require thread's lock.
+            mLock.unlock();
+            const int intensity = AudioFlinger::onExternalVibrationStart(
+                    track->getExternalVibration());
+            mLock.lock();
+            track->setHapticIntensity(static_cast<AudioMixer::haptic_intensity_t>(intensity));
+            // Haptic playback should be enabled by vibrator service.
+            if (track->getHapticPlaybackEnabled()) {
+                // Disable haptic playback of all active track to ensure only
+                // one track playing haptic if current track should play haptic.
+                for (const auto &t : mActiveTracks) {
+                    t->setHapticPlaybackEnabled(false);
+                }
+            }
+        }
+
         track->mResetDone = false;
         track->mPresentationCompleteFrames = 0;
         mActiveTracks.add(track);
@@ -2400,7 +2495,16 @@
     return String8();
 }
 
-void AudioFlinger::PlaybackThread::ioConfigChanged(audio_io_config_event event, pid_t pid) {
+status_t AudioFlinger::DirectOutputThread::selectPresentation(int presentationId, int programId) {
+    Mutex::Autolock _l(mLock);
+    if (mOutput == nullptr || mOutput->stream == nullptr) {
+        return NO_INIT;
+    }
+    return mOutput->stream->selectPresentation(presentationId, programId);
+}
+
+void AudioFlinger::PlaybackThread::ioConfigChanged(audio_io_config_event event, pid_t pid,
+                                                   audio_port_handle_t portId) {
     sp<AudioIoDescriptor> desc = new AudioIoDescriptor();
     ALOGV("PlaybackThread::ioConfigChanged, thread %p, event %d", this, event);
 
@@ -2419,7 +2523,10 @@
         desc->mFrameCountHAL = mFrameCount;
         desc->mLatency = latency_l();
         break;
-
+    case AUDIO_CLIENT_STARTED:
+        desc->mPatch = mPatch;
+        desc->mPortId = portId;
+        break;
     case AUDIO_OUTPUT_CLOSED:
     default:
         break;
@@ -2457,6 +2564,11 @@
     Mutex::Autolock _l(mLock);
     // reject out of sequence requests
     if ((mDrainSequence & 1) && (sequence == mDrainSequence)) {
+        // Register discontinuity when HW drain is completed because that can cause
+        // the timestamp frame position to reset to 0 for direct and offload threads.
+        // (Out of sequence requests are ignored, since the discontinuity would be handled
+        // elsewhere, e.g. in flush).
+        mTimestampVerifier.discontinuity();
         mDrainSequence &= ~1;
         mWaitWorkCV.signal();
     }
@@ -2476,6 +2588,7 @@
                 mChannelMask);
     }
     mChannelCount = audio_channel_count_from_out_mask(mChannelMask);
+    mBalance.setChannelMask(mChannelMask);
 
     // Get actual HAL format.
     status_t result = mOutput->stream->getFormat(&mHALFormat);
@@ -2595,7 +2708,7 @@
     free(mMixerBuffer);
     mMixerBuffer = NULL;
     if (mMixerBufferEnabled) {
-        mMixerBufferFormat = AUDIO_FORMAT_PCM_FLOAT; // also valid: AUDIO_FORMAT_PCM_16_BIT.
+        mMixerBufferFormat = AUDIO_FORMAT_PCM_FLOAT; // no longer valid: AUDIO_FORMAT_PCM_16_BIT.
         mMixerBufferSize = mNormalFrameCount * mChannelCount
                 * audio_bytes_per_sample(mMixerBufferFormat);
         (void)posix_memalign(&mMixerBuffer, 32, mMixerBufferSize);
@@ -2609,6 +2722,11 @@
         (void)posix_memalign(&mEffectBuffer, 32, mEffectBufferSize);
     }
 
+    mHapticChannelMask = mChannelMask & AUDIO_CHANNEL_HAPTIC_ALL;
+    mChannelMask &= ~mHapticChannelMask;
+    mHapticChannelCount = audio_channel_count_from_out_mask(mHapticChannelMask);
+    mChannelCount -= mHapticChannelCount;
+
     // force reconfiguration of effect chains and engines to take new buffer size and audio
     // parameters into account
     // Note that mLock is not held when readOutputParameters_l() is called from the constructor
@@ -2617,7 +2735,8 @@
     // create a copy of mEffectChains as calling moveEffectChain_l() can reorder some effect chains
     Vector< sp<EffectChain> > effectChains = mEffectChains;
     for (size_t i = 0; i < effectChains.size(); i ++) {
-        mAudioFlinger->moveEffectChain_l(effectChains[i]->sessionId(), this, this, false);
+        mAudioFlinger->moveEffectChain_l(effectChains[i]->sessionId(),
+            this/* srcThread */, this/* dstThread */);
     }
 }
 
@@ -2677,28 +2796,6 @@
     }
 }
 
-// hasAudioSession_l() must be called with ThreadBase::mLock held
-uint32_t AudioFlinger::PlaybackThread::hasAudioSession_l(audio_session_t sessionId) const
-{
-    uint32_t result = 0;
-    if (getEffectChain_l(sessionId) != 0) {
-        result = EFFECT_SESSION;
-    }
-
-    for (size_t i = 0; i < mTracks.size(); ++i) {
-        sp<Track> track = mTracks[i];
-        if (sessionId == track->sessionId() && !track->isInvalid()) {
-            result |= TRACK_SESSION;
-            if (track->isFastTrack()) {
-                result |= FAST_SESSION;
-            }
-            break;
-        }
-    }
-
-    return result;
-}
-
 uint32_t AudioFlinger::PlaybackThread::getStrategyForSession_l(audio_session_t sessionId)
 {
     // session AUDIO_SESSION_OUTPUT_MIX is placed in same strategy as MUSIC stream so that
@@ -2776,24 +2873,18 @@
 void AudioFlinger::PlaybackThread::threadLoop_removeTracks(
         const Vector< sp<Track> >& tracksToRemove)
 {
-    size_t count = tracksToRemove.size();
-    if (count > 0) {
-        for (size_t i = 0 ; i < count ; i++) {
-            const sp<Track>& track = tracksToRemove.itemAt(i);
-            if (track->isExternalTrack()) {
-                AudioSystem::stopOutput(mId, track->streamType(),
-                                        track->sessionId());
+    // Miscellaneous track cleanup when removed from the active list,
+    // called without Thread lock but synchronized with threadLoop processing.
 #ifdef ADD_BATTERY_DATA
-                // to track the speaker usage
-                addBatteryData(IMediaPlayerService::kBatteryDataAudioFlingerStop);
-#endif
-                if (track->isTerminated()) {
-                    AudioSystem::releaseOutput(mId, track->streamType(),
-                                               track->sessionId());
-                }
-            }
+    for (const auto& track : tracksToRemove) {
+        if (track->isExternalTrack()) {
+            // to track the speaker usage
+            addBatteryData(IMediaPlayerService::kBatteryDataAudioFlingerStop);
         }
     }
+#else
+    (void)tracksToRemove; // suppress unused warning
+#endif
 }
 
 void AudioFlinger::PlaybackThread::checkSilentMode_l()
@@ -2845,6 +2936,9 @@
         ATRACE_END();
         if (framesWritten > 0) {
             bytesWritten = framesWritten * mFrameSize;
+#ifdef TEE_SINK
+            mTee.write((char *)mSinkBuffer + offset, framesWritten);
+#endif
         } else {
             bytesWritten = framesWritten;
         }
@@ -2984,7 +3078,7 @@
         // Only one effect chain can be present in direct output thread and it uses
         // the sink buffer as input
         if (mType != DIRECT) {
-            size_t numSamples = mNormalFrameCount * mChannelCount;
+            size_t numSamples = mNormalFrameCount * (mChannelCount + mHapticChannelCount);
             status_t result = mAudioFlinger->mEffectsFactoryHal->allocateBuffer(
                     numSamples * sizeof(effect_buffer_t),
                     &halInBuffer);
@@ -3125,8 +3219,8 @@
     Vector< sp<Track> > tracksToRemove;
 
     mStandbyTimeNs = systemTime();
-    nsecs_t lastWriteFinished = -1; // time last server write completed
-    int64_t lastFramesWritten = -1; // track changes in timestamp server frames written
+    int64_t lastLoopCountWritten = -2; // never matches "previous" loop, when loopCount = 0.
+    int64_t lastFramesWritten = -1;    // track changes in timestamp server frames written
 
     // MIXER
     nsecs_t lastWarning = 0;
@@ -3162,7 +3256,18 @@
 
     checkSilentMode_l();
 
-    while (!exitPending())
+    // DIRECT and OFFLOAD threads should reset frame count to zero on stop/flush
+    // TODO: add confirmation checks:
+    // 1) DIRECT threads and linear PCM format really resets to 0?
+    // 2) Is frame count really valid if not linear pcm?
+    // 3) Are all 64 bits of position returned, not just lowest 32 bits?
+    if (mType == OFFLOAD || mType == DIRECT) {
+        mTimestampVerifier.setDiscontinuityMode(mTimestampVerifier.DISCONTINUITY_MODE_ZERO);
+    }
+    audio_patch_handle_t lastDownstreamPatchHandle = AUDIO_PATCH_HANDLE_NONE;
+
+    // loopCount is used for statistics and diagnostics.
+    for (int64_t loopCount = 0; !exitPending(); ++loopCount)
     {
         // Log merge requests are performed during AudioFlinger binder transactions, but
         // that does not cover audio playback. It's requested here for that reason.
@@ -3171,6 +3276,51 @@
         cpuStats.sample(myName);
 
         Vector< sp<EffectChain> > effectChains;
+        audio_session_t activeHapticSessionId = AUDIO_SESSION_NONE;
+        std::vector<sp<Track>> activeTracks;
+
+        // If the device is AUDIO_DEVICE_OUT_BUS, check for downstream latency.
+        //
+        // Note: we access outDevice() outside of mLock.
+        if (isMsdDevice() && (outDevice() & AUDIO_DEVICE_OUT_BUS) != 0) {
+            // Here, we try for the AF lock, but do not block on it as the latency
+            // is more informational.
+            if (mAudioFlinger->mLock.tryLock() == NO_ERROR) {
+                std::vector<PatchPanel::SoftwarePatch> swPatches;
+                double latencyMs;
+                status_t status = INVALID_OPERATION;
+                audio_patch_handle_t downstreamPatchHandle = AUDIO_PATCH_HANDLE_NONE;
+                if (mAudioFlinger->mPatchPanel.getDownstreamSoftwarePatches(id(), &swPatches) == OK
+                        && swPatches.size() > 0) {
+                        status = swPatches[0].getLatencyMs_l(&latencyMs);
+                        downstreamPatchHandle = swPatches[0].getPatchHandle();
+                }
+                if (downstreamPatchHandle != lastDownstreamPatchHandle) {
+                    mDownstreamLatencyStatMs.reset();
+                    lastDownstreamPatchHandle = downstreamPatchHandle;
+                }
+                if (status == OK) {
+                    // verify downstream latency (we assume a max reasonable
+                    // latency of 5 seconds).
+                    const double minLatency = 0., maxLatency = 5000.;
+                    if (latencyMs >= minLatency && latencyMs <= maxLatency) {
+                        ALOGV("new downstream latency %lf ms", latencyMs);
+                    } else {
+                        ALOGD("out of range downstream latency %lf ms", latencyMs);
+                        if (latencyMs < minLatency) latencyMs = minLatency;
+                        else if (latencyMs > maxLatency) latencyMs = maxLatency;
+                    }
+                    mDownstreamLatencyStatMs.add(latencyMs);
+                }
+                mAudioFlinger->mLock.unlock();
+            }
+        } else {
+            if (lastDownstreamPatchHandle != AUDIO_PATCH_HANDLE_NONE) {
+                // our device is no longer AUDIO_DEVICE_OUT_BUS, reset patch handle and stats.
+                mDownstreamLatencyStatMs.reset();
+                lastDownstreamPatchHandle = AUDIO_PATCH_HANDLE_NONE;
+            }
+        }
 
         { // scope for mLock
 
@@ -3185,16 +3335,51 @@
                 logString = NULL;
             }
 
+            // Collect timestamp statistics for the Playback Thread types that support it.
+            if (mType == MIXER
+                    || mType == DUPLICATING
+                    || mType == DIRECT
+                    || mType == OFFLOAD) { // no indentation
             // Gather the framesReleased counters for all active tracks,
             // and associate with the sink frames written out.  We need
             // this to convert the sink timestamp to the track timestamp.
             bool kernelLocationUpdate = false;
-            if (mNormalSink != 0) {
-                // Note: The DuplicatingThread may not have a mNormalSink.
+            ExtendedTimestamp timestamp; // use private copy to fetch
+            if (mStandby) {
+                mTimestampVerifier.discontinuity();
+            } else if (threadloop_getHalTimestamp_l(&timestamp) == OK) {
+                mTimestampVerifier.add(timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL],
+                        timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL],
+                        mSampleRate);
+
+                if (isTimestampCorrectionEnabled()) {
+                    ALOGV("TS_BEFORE: %d %lld %lld", id(),
+                            (long long)timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL],
+                            (long long)timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL]);
+                    auto correctedTimestamp = mTimestampVerifier.getLastCorrectedTimestamp();
+                    timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL]
+                            = correctedTimestamp.mFrames;
+                    timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL]
+                            = correctedTimestamp.mTimeNs;
+                    ALOGV("TS_AFTER: %d %lld %lld", id(),
+                            (long long)timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL],
+                            (long long)timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL]);
+
+                    // Note: Downstream latency only added if timestamp correction enabled.
+                    if (mDownstreamLatencyStatMs.getN() > 0) { // we have latency info.
+                        const int64_t newPosition =
+                                timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL]
+                                - int64_t(mDownstreamLatencyStatMs.getMean() * mSampleRate * 1e-3);
+                        // prevent retrograde
+                        timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] = max(
+                                newPosition,
+                                (mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL]
+                                        - mSuspendedFrames));
+                    }
+                }
+
                 // We always fetch the timestamp here because often the downstream
                 // sink will block while writing.
-                ExtendedTimestamp timestamp; // use private copy to fetch
-                (void) mNormalSink->getTimestamp(timestamp);
 
                 // We keep track of the last valid kernel position in case we are in underrun
                 // and the normal mixer period is the same as the fast mixer period, or there
@@ -3223,7 +3408,10 @@
                         + mSuspendedFrames; // add frames discarded when suspended
                 mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] =
                         timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL];
+            } else {
+                mTimestampVerifier.error();
             }
+
             // mFramesWritten for non-offloaded tracks are contiguous
             // even after standby() is called. This is useful for the track frame
             // to sink frame mapping.
@@ -3239,11 +3427,11 @@
                     // use the time before we called the HAL write - it is a bit more accurate
                     // to when the server last read data than the current time here.
                     //
-                    // If we haven't written anything, mLastWriteTime will be -1
+                    // If we haven't written anything, mLastIoBeginNs will be -1
                     // and we use systemTime().
                     mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] = mFramesWritten;
-                    mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] = mLastWriteTime == -1
-                            ? systemTime() : mLastWriteTime;
+                    mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] = mLastIoBeginNs == -1
+                            ? systemTime() : mLastIoBeginNs;
                 }
 
                 for (const sp<Track> &t : mActiveTracks) {
@@ -3251,10 +3439,20 @@
                         t->updateTrackFrameInfo(
                                 t->mAudioTrackServerProxy->framesReleased(),
                                 mFramesWritten,
+                                mSampleRate,
                                 mTimestamp);
                     }
                 }
             }
+
+            if (audio_has_proportional_frames(mFormat)) {
+                const double latencyMs = mTimestamp.getOutputServerLatencyMs(mSampleRate);
+                if (latencyMs != 0.) { // note 0. means timestamp is empty.
+                    mLatencyMs.add(latencyMs);
+                }
+            }
+
+            } // if (mType ... ) { // no indentation
 #if 0
             // logFormat example
             if (z % 100 == 0) {
@@ -3295,7 +3493,7 @@
 
                 continue;
             }
-            if ((!mActiveTracks.size() && systemTime() > mStandbyTimeNs) ||
+            if ((mActiveTracks.isEmpty() && systemTime() > mStandbyTimeNs) ||
                                    isSuspended()) {
                 // put audio hardware into standby after short delay
                 if (shouldStandby_l()) {
@@ -3307,9 +3505,10 @@
                         LOG_AUDIO_STATE();
                     }
                     mStandby = true;
+                    sendStatistics(false /* force */);
                 }
 
-                if (!mActiveTracks.size() && mConfigEvents.isEmpty()) {
+                if (mActiveTracks.isEmpty() && mConfigEvents.isEmpty()) {
                     // we're about to wait, flush the binder command buffer
                     IPCThreadState::self()->flushCommands();
 
@@ -3352,6 +3551,25 @@
             // during mixing and effect process as the audio buffers could be deleted
             // or modified if an effect is created or deleted
             lockEffectChains_l(effectChains);
+
+            // Determine which session to pick up haptic data.
+            // This must be done under the same lock as prepareTracks_l().
+            // TODO: Write haptic data directly to sink buffer when mixing.
+            if (mHapticChannelCount > 0 && effectChains.size() > 0) {
+                for (const auto& track : mActiveTracks) {
+                    if (track->getHapticPlaybackEnabled()) {
+                        activeHapticSessionId = track->sessionId();
+                        break;
+                    }
+                }
+            }
+
+            // Acquire a local copy of active tracks with lock (release w/o lock).
+            //
+            // Control methods on the track acquire the ThreadBase lock (e.g. start()
+            // stop(), pause(), etc.), but the threadLoop is entitled to call audio
+            // data / buffer methods on tracks from activeTracks without the ThreadBase lock.
+            activeTracks.insert(activeTracks.end(), mActiveTracks.begin(), mActiveTracks.end());
         } // mLock scope ends
 
         if (mBytesRemaining == 0) {
@@ -3366,6 +3584,13 @@
                 threadLoop_sleepTime();
                 if (mSleepTimeUs == 0) {
                     mCurrentWriteLength = mSinkBufferSize;
+
+                    // Tally underrun frames as we are inserting 0s here.
+                    for (const auto& track : activeTracks) {
+                        if (track->mFillingUpStatus == Track::FS_ACTIVE) {
+                            track->mAudioTrackServerProxy->tallyUnderrunFrames(mNormalFrameCount);
+                        }
+                    }
                 }
             }
             // Either threadLoop_mix() or threadLoop_sleepTime() should have set
@@ -3389,8 +3614,26 @@
                                true /*limit*/);
                 }
 
+                if (!hasFastMixer()) {
+                    // Balance must take effect after mono conversion.
+                    // We do it here if there is no FastMixer.
+                    // mBalance detects zero balance within the class for speed (not needed here).
+                    mBalance.setBalance(mMasterBalance.load());
+                    mBalance.process((float *)mMixerBuffer, mNormalFrameCount);
+                }
+
                 memcpy_by_audio_format(buffer, format, mMixerBuffer, mMixerBufferFormat,
-                        mNormalFrameCount * mChannelCount);
+                        mNormalFrameCount * (mChannelCount + mHapticChannelCount));
+
+                // If we're going directly to the sink and there are haptic channels,
+                // we should adjust channels as the sample data is partially interleaved
+                // in this case.
+                if (!mEffectBufferValid && mHapticChannelCount > 0) {
+                    adjust_channels_non_destructive(buffer, mChannelCount, buffer,
+                            mChannelCount + mHapticChannelCount,
+                            audio_bytes_per_sample(format),
+                            audio_bytes_per_frame(mChannelCount, format) * mNormalFrameCount);
+                }
             }
 
             mBytesRemaining = mCurrentWriteLength;
@@ -3408,6 +3651,19 @@
             if (mSleepTimeUs == 0 && mType != OFFLOAD) {
                 for (size_t i = 0; i < effectChains.size(); i ++) {
                     effectChains[i]->process_l();
+                    // TODO: Write haptic data directly to sink buffer when mixing.
+                    if (activeHapticSessionId != AUDIO_SESSION_NONE
+                            && activeHapticSessionId == effectChains[i]->sessionId()) {
+                        // Haptic data is active in this case, copy it directly from
+                        // in buffer to out buffer.
+                        const size_t audioBufferSize = mNormalFrameCount
+                                * audio_bytes_per_frame(mChannelCount, EFFECT_BUFFER_FORMAT);
+                        memcpy_by_audio_format(
+                                (uint8_t*)effectChains[i]->outBuffer() + audioBufferSize,
+                                EFFECT_BUFFER_FORMAT,
+                                (const uint8_t*)effectChains[i]->inBuffer() + audioBufferSize,
+                                EFFECT_BUFFER_FORMAT, mNormalFrameCount * mHapticChannelCount);
+                    }
                 }
             }
         }
@@ -3433,8 +3689,24 @@
                            true /*limit*/);
             }
 
+            if (!hasFastMixer()) {
+                // Balance must take effect after mono conversion.
+                // We do it here if there is no FastMixer.
+                // mBalance detects zero balance within the class for speed (not needed here).
+                mBalance.setBalance(mMasterBalance.load());
+                mBalance.process((float *)mEffectBuffer, mNormalFrameCount);
+            }
+
             memcpy_by_audio_format(mSinkBuffer, mFormat, mEffectBuffer, mEffectBufferFormat,
-                    mNormalFrameCount * mChannelCount);
+                    mNormalFrameCount * (mChannelCount + mHapticChannelCount));
+            // The sample data is partially interleaved when haptic channels exist,
+            // we need to adjust channels here.
+            if (mHapticChannelCount > 0) {
+                adjust_channels_non_destructive(mSinkBuffer, mChannelCount, mSinkBuffer,
+                        mChannelCount + mHapticChannelCount,
+                        audio_bytes_per_sample(mFormat),
+                        audio_bytes_per_frame(mChannelCount, mFormat) * mNormalFrameCount);
+            }
         }
 
         // enable changes in effect chain
@@ -3444,43 +3716,68 @@
             // mSleepTimeUs == 0 means we must write to audio hardware
             if (mSleepTimeUs == 0) {
                 ssize_t ret = 0;
-                // We save lastWriteFinished here, as previousLastWriteFinished,
-                // for throttling. On thread start, previousLastWriteFinished will be
-                // set to -1, which properly results in no throttling after the first write.
-                nsecs_t previousLastWriteFinished = lastWriteFinished;
-                nsecs_t delta = 0;
+                // writePeriodNs is updated >= 0 when ret > 0.
+                int64_t writePeriodNs = -1;
                 if (mBytesRemaining) {
                     // FIXME rewrite to reduce number of system calls
-                    mLastWriteTime = systemTime();  // also used for dumpsys
+                    const int64_t lastIoBeginNs = systemTime();
                     ret = threadLoop_write();
-                    lastWriteFinished = systemTime();
-                    delta = lastWriteFinished - mLastWriteTime;
+                    const int64_t lastIoEndNs = systemTime();
                     if (ret < 0) {
                         mBytesRemaining = 0;
-                    } else {
+                    } else if (ret > 0) {
                         mBytesWritten += ret;
                         mBytesRemaining -= ret;
-                        mFramesWritten += ret / mFrameSize;
+                        const int64_t frames = ret / mFrameSize;
+                        mFramesWritten += frames;
+
+                        writePeriodNs = lastIoEndNs - mLastIoEndNs;
+                        // process information relating to write time.
+                        if (audio_has_proportional_frames(mFormat)) {
+                            // we are in a continuous mixing cycle
+                            if (mMixerStatus == MIXER_TRACKS_READY &&
+                                    loopCount == lastLoopCountWritten + 1) {
+
+                                const double jitterMs =
+                                        TimestampVerifier<int64_t, int64_t>::computeJitterMs(
+                                                {frames, writePeriodNs},
+                                                {0, 0} /* lastTimestamp */, mSampleRate);
+                                const double processMs =
+                                       (lastIoBeginNs - mLastIoEndNs) * 1e-6;
+
+                                Mutex::Autolock _l(mLock);
+                                mIoJitterMs.add(jitterMs);
+                                mProcessTimeMs.add(processMs);
+                            }
+
+                            // write blocked detection
+                            const int64_t deltaWriteNs = lastIoEndNs - lastIoBeginNs;
+                            if (mType == MIXER && deltaWriteNs > maxPeriod) {
+                                mNumDelayedWrites++;
+                                if ((lastIoEndNs - lastWarning) > kWarningThrottleNs) {
+                                    ATRACE_NAME("underrun");
+                                    ALOGW("write blocked for %lld msecs, "
+                                            "%d delayed writes, thread %d",
+                                            (long long)deltaWriteNs / NANOS_PER_MILLISECOND,
+                                            mNumDelayedWrites, mId);
+                                    lastWarning = lastIoEndNs;
+                                }
+                            }
+                        }
+                        // update timing info.
+                        mLastIoBeginNs = lastIoBeginNs;
+                        mLastIoEndNs = lastIoEndNs;
+                        lastLoopCountWritten = loopCount;
                     }
                 } else if ((mMixerStatus == MIXER_DRAIN_TRACK) ||
                         (mMixerStatus == MIXER_DRAIN_ALL)) {
                     threadLoop_drain();
                 }
                 if (mType == MIXER && !mStandby) {
-                    // write blocked detection
-                    if (delta > maxPeriod) {
-                        mNumDelayedWrites++;
-                        if ((lastWriteFinished - lastWarning) > kWarningThrottleNs) {
-                            ATRACE_NAME("underrun");
-                            ALOGW("write blocked for %llu msecs, %d delayed writes, thread %p",
-                                    (unsigned long long) ns2ms(delta), mNumDelayedWrites, this);
-                            lastWarning = lastWriteFinished;
-                        }
-                    }
 
                     if (mThreadThrottle
                             && mMixerStatus == MIXER_TRACKS_READY // we are mixing (active tracks)
-                            && ret > 0) {                         // we wrote something
+                            && writePeriodNs > 0) {               // we have write period info
                         // Limit MixerThread data processing to no more than twice the
                         // expected processing rate.
                         //
@@ -3499,12 +3796,9 @@
                         // 2. threadLoop_mix (significant for heavy mixing, especially
                         //                    on low tier processors)
 
-                        // it's OK if deltaMs (and deltaNs) is an overestimate.
-                        nsecs_t deltaNs;
-                        // deltaNs = lastWriteFinished - previousLastWriteFinished;
-                        __builtin_sub_overflow(
-                            lastWriteFinished,previousLastWriteFinished, &deltaNs);
-                        const int32_t deltaMs = deltaNs / 1000000;
+                        // it's OK if deltaMs is an overestimate.
+
+                        const int32_t deltaMs = writePeriodNs / NANOS_PER_MILLISECOND;
 
                         const int32_t throttleMs = (int32_t)mHalfBufferMs - deltaMs;
                         if ((signed)mHalfBufferMs >= throttleMs && throttleMs > 0) {
@@ -3517,7 +3811,8 @@
                             mThreadThrottleTimeMs += throttleMs;
                             // Throttle must be attributed to the previous mixer loop's write time
                             // to allow back-to-back throttling.
-                            lastWriteFinished += throttleMs * 1000000;
+                            // This also ensures proper timing statistics.
+                            mLastIoEndNs = systemTime();  // we fetch the write end time again.
                         } else {
                             uint32_t diff = mThreadThrottleTimeMs - mThreadThrottleEndMs;
                             if (diff > 0) {
@@ -3600,24 +3895,36 @@
 // removeTracks_l() must be called with ThreadBase::mLock held
 void AudioFlinger::PlaybackThread::removeTracks_l(const Vector< sp<Track> >& tracksToRemove)
 {
-    size_t count = tracksToRemove.size();
-    if (count > 0) {
-        for (size_t i=0 ; i<count ; i++) {
-            const sp<Track>& track = tracksToRemove.itemAt(i);
-            mActiveTracks.remove(track);
-            ALOGV("removeTracks_l removing track on session %d", track->sessionId());
-            sp<EffectChain> chain = getEffectChain_l(track->sessionId());
-            if (chain != 0) {
-                ALOGV("stopping track on chain %p for session Id: %d", chain.get(),
-                        track->sessionId());
-                chain->decActiveTrackCnt();
-            }
+    for (const auto& track : tracksToRemove) {
+        mActiveTracks.remove(track);
+        ALOGV("%s(%d): removing track on session %d", __func__, track->id(), track->sessionId());
+        sp<EffectChain> chain = getEffectChain_l(track->sessionId());
+        if (chain != 0) {
+            ALOGV("%s(%d): stopping track on chain %p for session Id: %d",
+                    __func__, track->id(), chain.get(), track->sessionId());
+            chain->decActiveTrackCnt();
+        }
+        // If an external client track, inform APM we're no longer active, and remove if needed.
+        // We do this under lock so that the state is consistent if the Track is destroyed.
+        if (track->isExternalTrack()) {
+            AudioSystem::stopOutput(track->portId());
             if (track->isTerminated()) {
-                removeTrack_l(track);
+                AudioSystem::releaseOutput(track->portId());
             }
         }
+        if (track->isTerminated()) {
+            // remove from our tracks vector
+            removeTrack_l(track);
+        }
+        if ((track->channelMask() & AUDIO_CHANNEL_HAPTIC_ALL) != AUDIO_CHANNEL_NONE
+                && mHapticChannelCount > 0) {
+            mLock.unlock();
+            // Unlock due to VibratorService will lock for this call and will
+            // call Tracks.mute/unmute which also require thread's lock.
+            AudioFlinger::onExternalVibrationStop(track->getExternalVibration());
+            mLock.lock();
+        }
     }
-
 }
 
 status_t AudioFlinger::PlaybackThread::getTimestamp_l(AudioTimestamp& timestamp)
@@ -3634,6 +3941,15 @@
         uint64_t position64;
         if (mOutput->getPresentationPosition(&position64, &timestamp.mTime) == OK) {
             timestamp.mPosition = (uint32_t)position64;
+            if (mDownstreamLatencyStatMs.getN() > 0) {
+                const uint32_t positionOffset =
+                    (uint32_t)(mDownstreamLatencyStatMs.getMean() * mSampleRate * 1e-3);
+                if (positionOffset > timestamp.mPosition) {
+                    timestamp.mPosition = 0;
+                } else {
+                    timestamp.mPosition -= positionOffset;
+                }
+            }
             return NO_ERROR;
         }
     }
@@ -3666,6 +3982,7 @@
         type |= patch->sinks[i].ext.device.type;
     }
 
+    audio_port_handle_t sinkPortId = patch->sinks[0].id;
 #ifdef ADD_BATTERY_DATA
     // when changing the audio output device, call addBatteryData to notify
     // the change
@@ -3695,7 +4012,7 @@
 
     // mPrevOutDevice is the latest device set by createAudioPatch_l(). It is not set when
     // the thread is created so that the first patch creation triggers an ioConfigChanged callback
-    bool configChanged = mPrevOutDevice != type;
+    bool configChanged = (mPrevOutDevice != type) || (mDeviceId != sinkPortId);
     mOutDevice = type;
     mPatch = *patch;
 
@@ -3724,6 +4041,7 @@
     }
     if (configChanged) {
         mPrevOutDevice = type;
+        mDeviceId = sinkPortId;
         sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED);
     }
     return status;
@@ -3772,12 +4090,16 @@
     destroyTrack_l(track);
 }
 
-void AudioFlinger::PlaybackThread::getAudioPortConfig(struct audio_port_config *config)
+void AudioFlinger::PlaybackThread::toAudioPortConfig(struct audio_port_config *config)
 {
-    ThreadBase::getAudioPortConfig(config);
+    ThreadBase::toAudioPortConfig(config);
     config->role = AUDIO_PORT_ROLE_SOURCE;
     config->ext.mix.hw_module = mOutput->audioHwDev->handle();
     config->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
+    if (mOutput && mOutput->flags != AUDIO_OUTPUT_FLAG_NONE) {
+        config->config_mask |= AUDIO_PORT_CONFIG_FLAGS;
+        config->flags.output = mOutput->flags;
+    }
 }
 
 // ----------------------------------------------------------------------------
@@ -3793,6 +4115,7 @@
         // mPipeSink below
         // mNormalSink below
 {
+    setMasterBalance(audioFlinger->getMasterBalance_l());
     ALOGV("MixerThread() id=%d device=%#x type=%d", id, device, type);
     ALOGV("mSampleRate=%u, mChannelMask=%#x, mChannelCount=%u, mFormat=%#x, mFrameSize=%zu, "
             "mFrameCount=%zu, mNormalFrameCount=%zu",
@@ -3809,7 +4132,8 @@
     // create an NBAIO sink for the HAL output stream, and negotiate
     mOutputSink = new AudioStreamOutSink(output->stream);
     size_t numCounterOffers = 0;
-    const NBAIO_Format offers[1] = {Format_from_SR_C(mSampleRate, mChannelCount, mFormat)};
+    const NBAIO_Format offers[1] = {Format_from_SR_C(
+            mSampleRate, mChannelCount + mHapticChannelCount, mFormat)};
 #if !LOG_NDEBUG
     ssize_t index =
 #else
@@ -3851,16 +4175,14 @@
             // change our Sink format to accept our intermediate precision
             mFormat = fastMixerFormat;
             free(mSinkBuffer);
-            mFrameSize = mChannelCount * audio_bytes_per_sample(mFormat);
+            mFrameSize = audio_bytes_per_frame(mChannelCount + mHapticChannelCount, mFormat);
             const size_t sinkBufferSize = mNormalFrameCount * mFrameSize;
             (void)posix_memalign(&mSinkBuffer, 32, sinkBufferSize);
         }
 
         // create a MonoPipe to connect our submix to FastMixer
         NBAIO_Format format = mOutputSink->format();
-#ifdef TEE_SINK
-        NBAIO_Format origformat = format;
-#endif
+
         // adjust format to match that of the Fast Mixer
         ALOGV("format changed from %#x to %#x", format.mFormat, fastMixerFormat);
         format.mFormat = fastMixerFormat;
@@ -3872,7 +4194,7 @@
         MonoPipe *monoPipe = new MonoPipe(mNormalFrameCount * 4, format, true /*writeCanBlock*/);
         const NBAIO_Format offers[1] = {format};
         size_t numCounterOffers = 0;
-#if !LOG_NDEBUG || defined(TEE_SINK)
+#if !LOG_NDEBUG
         ssize_t index =
 #else
         (void)
@@ -3883,25 +4205,8 @@
                 (monoPipe->maxFrames() * 7) / 8 : mNormalFrameCount * 2);
         mPipeSink = monoPipe;
 
-#ifdef TEE_SINK
-        if (mTeeSinkOutputEnabled) {
-            // create a Pipe to archive a copy of FastMixer's output for dumpsys
-            Pipe *teeSink = new Pipe(mTeeSinkOutputFrames, origformat);
-            const NBAIO_Format offers2[1] = {origformat};
-            numCounterOffers = 0;
-            index = teeSink->negotiate(offers2, 1, NULL, numCounterOffers);
-            ALOG_ASSERT(index == 0);
-            mTeeSink = teeSink;
-            PipeReader *teeSource = new PipeReader(*teeSink);
-            numCounterOffers = 0;
-            index = teeSource->negotiate(offers2, 1, NULL, numCounterOffers);
-            ALOG_ASSERT(index == 0);
-            mTeeSource = teeSource;
-        }
-#endif
-
         // create fast mixer and configure it initially with just one fast track for our submix
-        mFastMixer = new FastMixer();
+        mFastMixer = new FastMixer(mId);
         FastMixerStateQueue *sq = mFastMixer->sq();
 #ifdef STATE_QUEUE_DUMP
         sq->setObserverDump(&mStateQueueObserverDump);
@@ -3912,8 +4217,11 @@
         // wrap the source side of the MonoPipe to make it an AudioBufferProvider
         fastTrack->mBufferProvider = new SourceAudioBufferProvider(new MonoPipeReader(monoPipe));
         fastTrack->mVolumeProvider = NULL;
-        fastTrack->mChannelMask = mChannelMask; // mPipeSink channel mask for audio to FastMixer
+        fastTrack->mChannelMask = mChannelMask | mHapticChannelMask; // mPipeSink channel mask for
+                                                                     // audio to FastMixer
         fastTrack->mFormat = mFormat; // mPipeSink format for audio to FastMixer
+        fastTrack->mHapticPlaybackEnabled = mHapticChannelMask != AUDIO_CHANNEL_NONE;
+        fastTrack->mHapticIntensity = AudioMixer::HAPTIC_SCALE_NONE;
         fastTrack->mGeneration++;
         state->mFastTracksGen++;
         state->mTrackMask = 1;
@@ -3921,24 +4229,30 @@
         state->mOutputSink = mOutputSink.get();
         state->mOutputSinkGen++;
         state->mFrameCount = mFrameCount;
+        // specify sink channel mask when haptic channel mask present as it can not
+        // be calculated directly from channel count
+        state->mSinkChannelMask = mHapticChannelMask == AUDIO_CHANNEL_NONE
+                ? AUDIO_CHANNEL_NONE : mChannelMask | mHapticChannelMask;
         state->mCommand = FastMixerState::COLD_IDLE;
         // already done in constructor initialization list
         //mFastMixerFutex = 0;
         state->mColdFutexAddr = &mFastMixerFutex;
         state->mColdGen++;
         state->mDumpState = &mFastMixerDumpState;
-#ifdef TEE_SINK
-        state->mTeeSink = mTeeSink.get();
-#endif
         mFastMixerNBLogWriter = audioFlinger->newWriter_l(kFastMixerLogSize, "FastMixer");
         state->mNBLogWriter = mFastMixerNBLogWriter.get();
         sq->end();
         sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
 
+        NBLog::thread_info_t info;
+        info.id = mId;
+        info.type = NBLog::FASTMIXER;
+        mFastMixerNBLogWriter->log<NBLog::EVENT_THREAD_INFO>(info);
+
         // start the fast mixer
         mFastMixer->run("FastMixer", PRIORITY_URGENT_AUDIO);
         pid_t tid = mFastMixer->getTid();
-        sendPrioConfigEvent(getpid_cached, tid, kPriorityFastMixer, false /*forApp*/);
+        sendPrioConfigEvent(getpid(), tid, kPriorityFastMixer, false /*forApp*/);
         stream()->setHalThreadPriority(kPriorityFastMixer);
 
 #ifdef AUDIO_WATCHDOG
@@ -3947,9 +4261,14 @@
         mAudioWatchdog->setDump(&mAudioWatchdogDump);
         mAudioWatchdog->run("AudioWatchdog", PRIORITY_URGENT_AUDIO);
         tid = mAudioWatchdog->getTid();
-        sendPrioConfigEvent(getpid_cached, tid, kPriorityFastMixer, false /*forApp*/);
+        sendPrioConfigEvent(getpid(), tid, kPriorityFastMixer, false /*forApp*/);
 #endif
-
+    } else {
+#ifdef TEE_SINK
+        // Only use the MixerThread tee if there is no FastMixer.
+        mTee.set(mOutputSink->format(), NBAIO_Tee::TEE_FLAG_OUTPUT_THREAD);
+        mTee.setId(std::string("_") + std::to_string(mId) + "_M");
+#endif
     }
 
     switch (kUseFastMixer) {
@@ -4013,12 +4332,6 @@
     return latency;
 }
 
-
-void AudioFlinger::MixerThread::threadLoop_removeTracks(const Vector< sp<Track> >& tracksToRemove)
-{
-    PlaybackThread::threadLoop_removeTracks(tracksToRemove);
-}
-
 ssize_t AudioFlinger::MixerThread::threadLoop_write()
 {
     // FIXME we should only do one push per cycle; confirm this is true
@@ -4217,14 +4530,14 @@
 AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTracks_l(
         Vector< sp<Track> > *tracksToRemove)
 {
-    // clean up deleted track names in AudioMixer before allocating new tracks
-    (void)mTracks.processDeletedTrackNames([this](int name) {
-        // for each name, destroy it in the AudioMixer
-        if (mAudioMixer->exists(name)) {
-            mAudioMixer->destroy(name);
+    // clean up deleted track ids in AudioMixer before allocating new tracks
+    (void)mTracks.processDeletedTrackIds([this](int trackId) {
+        // for each trackId, destroy it in the AudioMixer
+        if (mAudioMixer->exists(trackId)) {
+            mAudioMixer->destroy(trackId);
         }
     });
-    mTracks.clearDeletedTrackNames();
+    mTracks.clearDeletedTrackIds();
 
     mixer_state mixerStatus = MIXER_IDLE;
     // find out which tracks need to be processed
@@ -4265,6 +4578,38 @@
     mMixerBufferValid = false;  // mMixerBuffer has no valid data until appropriate tracks found.
     mEffectBufferValid = false; // mEffectBuffer has no valid data until tracks found.
 
+    // DeferredOperations handles statistics after setting mixerStatus.
+    class DeferredOperations {
+    public:
+        DeferredOperations(mixer_state *mixerStatus)
+            : mMixerStatus(mixerStatus) { }
+
+        // when leaving scope, tally frames properly.
+        ~DeferredOperations() {
+            // Tally underrun frames only if we are actually mixing (MIXER_TRACKS_READY)
+            // because that is when the underrun occurs.
+            // We do not distinguish between FastTracks and NormalTracks here.
+            if (*mMixerStatus == MIXER_TRACKS_READY) {
+                for (const auto &underrun : mUnderrunFrames) {
+                    underrun.first->mAudioTrackServerProxy->tallyUnderrunFrames(
+                            underrun.second);
+                }
+            }
+        }
+
+        // tallyUnderrunFrames() is called to update the track counters
+        // with the number of underrun frames for a particular mixer period.
+        // We defer tallying until we know the final mixer status.
+        void tallyUnderrunFrames(sp<Track> track, size_t underrunFrames) {
+            mUnderrunFrames.emplace_back(track, underrunFrames);
+        }
+
+    private:
+        const mixer_state * const mMixerStatus;
+        std::vector<std::pair<sp<Track>, size_t>> mUnderrunFrames;
+    } deferredOperations(&mixerStatus); // implicit nested scope for variable capture
+
+    bool noFastHapticTrack = true;
     for (size_t i=0 ; i<count ; i++) {
         const sp<Track> t = mActiveTracks[i];
 
@@ -4273,6 +4618,13 @@
 
         // process fast tracks
         if (track->isFastTrack()) {
+            LOG_ALWAYS_FATAL_IF(mFastMixer.get() == nullptr,
+                    "%s(%d): FastTrack(%d) present without FastMixer",
+                     __func__, id(), track->id());
+
+            if (track->getHapticPlaybackEnabled()) {
+                noFastHapticTrack = false;
+            }
 
             // It's theoretically possible (though unlikely) for a fast track to be created
             // and then removed within the same normal mix cycle.  This is not a problem, as
@@ -4299,13 +4651,14 @@
             track->mObservedUnderruns = underruns;
             // don't count underruns that occur while stopping or pausing
             // or stopped which can occur when flush() is called while active
+            size_t underrunFrames = 0;
             if (!(track->isStopping() || track->isPausing() || track->isStopped()) &&
                     recentUnderruns > 0) {
                 // FIXME fast mixer will pull & mix partial buffers, but we count as a full underrun
-                track->mAudioTrackServerProxy->tallyUnderrunFrames(recentUnderruns * mFrameCount);
-            } else {
-                track->mAudioTrackServerProxy->tallyUnderrunFrames(0);
+                underrunFrames = recentUnderruns * mFrameCount;
             }
+            // Immediately account for FastTrack underruns.
+            track->mAudioTrackServerProxy->tallyUnderrunFrames(underrunFrames);
 
             // This is similar to the state machine for normal tracks,
             // with a few modifications for fast tracks.
@@ -4352,7 +4705,7 @@
                     isActive = false;
                     break;
                 }
-                // fall through
+                FALLTHROUGH_INTENDED;
             case TrackBase::STOPPING_2:
             case TrackBase::PAUSED:
             case TrackBase::STOPPED:
@@ -4397,6 +4750,8 @@
                     fastTrack->mVolumeProvider = vp;
                     fastTrack->mChannelMask = track->mChannelMask;
                     fastTrack->mFormat = track->mFormat;
+                    fastTrack->mHapticPlaybackEnabled = track->getHapticPlaybackEnabled();
+                    fastTrack->mHapticIntensity = track->getHapticIntensity();
                     fastTrack->mGeneration++;
                     state->mTrackMask |= 1 << j;
                     didModify = true;
@@ -4407,9 +4762,14 @@
                 // lacks any synchronization or barrier so VolumeProvider may read a stale value
                 const float vh = track->getVolumeHandler()->getVolume(
                         proxy->framesReleased()).first;
-                float volume = masterVolume
+                float volume;
+                if (track->isPlaybackRestricted()) {
+                    volume = 0.f;
+                } else {
+                    volume = masterVolume
                         * mStreamTypes[track->streamType()].volume
                         * vh;
+                }
                 track->mCachedVolume = volume;
                 gain_minifloat_packed_t vlr = proxy->getVolumeLR();
                 float vlf = volume * float_from_gain(gain_minifloat_unpack_left(vlr));
@@ -4442,6 +4802,10 @@
                 // Avoids a misleading display in dumpsys
                 track->mObservedUnderruns.mBitFields.mMostRecent = UNDERRUN_FULL;
             }
+            if (fastTrack->mHapticPlaybackEnabled != track->getHapticPlaybackEnabled()) {
+                fastTrack->mHapticPlaybackEnabled = track->getHapticPlaybackEnabled();
+                didModify = true;
+            }
             continue;
         }
 
@@ -4451,19 +4815,21 @@
 
         // The first time a track is added we wait
         // for all its buffers to be filled before processing it
-        int name = track->name();
+        const int trackId = track->id();
 
         // if an active track doesn't exist in the AudioMixer, create it.
-        if (!mAudioMixer->exists(name)) {
+        // use the trackId as the AudioMixer name.
+        if (!mAudioMixer->exists(trackId)) {
             status_t status = mAudioMixer->create(
-                    name,
+                    trackId,
                     track->mChannelMask,
                     track->mFormat,
                     track->mSessionId);
             if (status != OK) {
-                ALOGW("%s: cannot create track name"
-                        " %d, mask %#x, format %#x, sessionId %d in AudioMixer",
-                        __func__, name, track->mChannelMask, track->mFormat, track->mSessionId);
+                ALOGW("%s(): AudioMixer cannot create track(%d)"
+                        " mask %#x, format %#x, sessionId %d",
+                        __func__, trackId,
+                        track->mChannelMask, track->mFormat, track->mSessionId);
                 tracksToRemove->add(track);
                 track->invalidate(); // consider it dead.
                 continue;
@@ -4484,7 +4850,7 @@
         // TODO: ONLY USED FOR LEGACY RESAMPLERS, remove when they are removed.
         // add frames already consumed but not yet released by the resampler
         // because mAudioTrackServerProxy->framesReady() will include these frames
-        desiredFrames += mAudioMixer->getUnreleasedFrames(track->name());
+        desiredFrames += mAudioMixer->getUnreleasedFrames(trackId);
 
         uint32_t minFrames = 1;
         if ((track->sharedBuffer() == 0) && !track->isStopped() && !track->isPausing() &&
@@ -4496,13 +4862,13 @@
         if (ATRACE_ENABLED()) {
             // I wish we had formatted trace names
             std::string traceName("nRdy");
-            traceName += std::to_string(track->name());
+            traceName += std::to_string(trackId);
             ATRACE_INT(traceName.c_str(), framesReady);
         }
         if ((framesReady >= minFrames) && track->isReady() &&
                 !track->isPaused() && !track->isTerminated())
         {
-            ALOGVV("track %d s=%08x [OK] on thread %p", name, cblk->mServer, this);
+            ALOGVV("track(%d) s=%08x [OK] on thread %p", trackId, cblk->mServer, this);
 
             mixedTracks++;
 
@@ -4519,9 +4885,9 @@
                 if (chain != 0) {
                     tracksWithEffect++;
                 } else {
-                    ALOGW("prepareTracks_l(): track %d attached to effect but no chain found on "
+                    ALOGW("prepareTracks_l(): track(%d) attached to effect but no chain found on "
                             "session %d",
-                            name, track->sessionId());
+                            trackId, track->sessionId());
                 }
             }
 
@@ -4532,9 +4898,12 @@
                 track->mFillingUpStatus = Track::FS_ACTIVE;
                 if (track->mState == TrackBase::RESUMING) {
                     track->mState = TrackBase::ACTIVE;
-                    param = AudioMixer::RAMP_VOLUME;
+                    // If a new track is paused immediately after start, do not ramp on resume.
+                    if (cblk->mServer != 0) {
+                        param = AudioMixer::RAMP_VOLUME;
+                    }
                 }
-                mAudioMixer->setParameter(name, AudioMixer::RESAMPLE, AudioMixer::RESET, NULL);
+                mAudioMixer->setParameter(trackId, AudioMixer::RESAMPLE, AudioMixer::RESET, NULL);
                 mLeftVolFloat = -1.0;
             // FIXME should not make a decision based on mServer
             } else if (cblk->mServer != 0) {
@@ -4549,15 +4918,19 @@
             // read original volumes with volume control
             float typeVolume = mStreamTypes[track->streamType()].volume;
             float v = masterVolume * typeVolume;
+            // Always fetch volumeshaper volume to ensure state is updated.
+            const sp<AudioTrackServerProxy> proxy = track->mAudioTrackServerProxy;
+            const float vh = track->getVolumeHandler()->getVolume(
+                    track->mAudioTrackServerProxy->framesReleased()).first;
 
-            if (track->isPausing() || mStreamTypes[track->streamType()].mute) {
+            if (track->isPausing() || mStreamTypes[track->streamType()].mute
+                    || track->isPlaybackRestricted()) {
                 vl = vr = 0;
                 vlf = vrf = vaf = 0.;
                 if (track->isPausing()) {
                     track->setPaused();
                 }
             } else {
-                sp<AudioTrackServerProxy> proxy = track->mAudioTrackServerProxy;
                 gain_minifloat_packed_t vlr = proxy->getVolumeLR();
                 vlf = float_from_gain(gain_minifloat_unpack_left(vlr));
                 vrf = float_from_gain(gain_minifloat_unpack_right(vlr));
@@ -4570,8 +4943,6 @@
                     ALOGV("Track right volume out of range: %.3g", vrf);
                     vrf = GAIN_FLOAT_UNITY;
                 }
-                const float vh = track->getVolumeHandler()->getVolume(
-                        track->mAudioTrackServerProxy->framesReleased()).first;
                 // now apply the master volume and stream type volume and shaper volume
                 vlf *= v * vh;
                 vrf *= v * vh;
@@ -4630,41 +5001,42 @@
                }
             }
             // XXX: these things DON'T need to be done each time
-            mAudioMixer->setBufferProvider(name, track);
-            mAudioMixer->enable(name);
+            mAudioMixer->setBufferProvider(trackId, track);
+            mAudioMixer->enable(trackId);
 
-            mAudioMixer->setParameter(name, param, AudioMixer::VOLUME0, &vlf);
-            mAudioMixer->setParameter(name, param, AudioMixer::VOLUME1, &vrf);
-            mAudioMixer->setParameter(name, param, AudioMixer::AUXLEVEL, &vaf);
+            mAudioMixer->setParameter(trackId, param, AudioMixer::VOLUME0, &vlf);
+            mAudioMixer->setParameter(trackId, param, AudioMixer::VOLUME1, &vrf);
+            mAudioMixer->setParameter(trackId, param, AudioMixer::AUXLEVEL, &vaf);
             mAudioMixer->setParameter(
-                name,
+                trackId,
                 AudioMixer::TRACK,
                 AudioMixer::FORMAT, (void *)track->format());
             mAudioMixer->setParameter(
-                name,
+                trackId,
                 AudioMixer::TRACK,
                 AudioMixer::CHANNEL_MASK, (void *)(uintptr_t)track->channelMask());
             mAudioMixer->setParameter(
-                name,
+                trackId,
                 AudioMixer::TRACK,
-                AudioMixer::MIXER_CHANNEL_MASK, (void *)(uintptr_t)mChannelMask);
+                AudioMixer::MIXER_CHANNEL_MASK,
+                (void *)(uintptr_t)(mChannelMask | mHapticChannelMask));
             // limit track sample rate to 2 x output sample rate, which changes at re-configuration
             uint32_t maxSampleRate = mSampleRate * AUDIO_RESAMPLER_DOWN_RATIO_MAX;
-            uint32_t reqSampleRate = track->mAudioTrackServerProxy->getSampleRate();
+            uint32_t reqSampleRate = proxy->getSampleRate();
             if (reqSampleRate == 0) {
                 reqSampleRate = mSampleRate;
             } else if (reqSampleRate > maxSampleRate) {
                 reqSampleRate = maxSampleRate;
             }
             mAudioMixer->setParameter(
-                name,
+                trackId,
                 AudioMixer::RESAMPLE,
                 AudioMixer::SAMPLE_RATE,
                 (void *)(uintptr_t)reqSampleRate);
 
-            AudioPlaybackRate playbackRate = track->mAudioTrackServerProxy->getPlaybackRate();
+            AudioPlaybackRate playbackRate = proxy->getPlaybackRate();
             mAudioMixer->setParameter(
-                name,
+                trackId,
                 AudioMixer::TIMESTRETCH,
                 AudioMixer::PLAYBACK_RATE,
                 &playbackRate);
@@ -4685,29 +5057,37 @@
                     && (track->mainBuffer() == mSinkBuffer
                             || track->mainBuffer() == mMixerBuffer)) {
                 mAudioMixer->setParameter(
-                        name,
+                        trackId,
                         AudioMixer::TRACK,
                         AudioMixer::MIXER_FORMAT, (void *)mMixerBufferFormat);
                 mAudioMixer->setParameter(
-                        name,
+                        trackId,
                         AudioMixer::TRACK,
                         AudioMixer::MAIN_BUFFER, (void *)mMixerBuffer);
                 // TODO: override track->mainBuffer()?
                 mMixerBufferValid = true;
             } else {
                 mAudioMixer->setParameter(
-                        name,
+                        trackId,
                         AudioMixer::TRACK,
                         AudioMixer::MIXER_FORMAT, (void *)EFFECT_BUFFER_FORMAT);
                 mAudioMixer->setParameter(
-                        name,
+                        trackId,
                         AudioMixer::TRACK,
                         AudioMixer::MAIN_BUFFER, (void *)track->mainBuffer());
             }
             mAudioMixer->setParameter(
-                name,
+                trackId,
                 AudioMixer::TRACK,
                 AudioMixer::AUX_BUFFER, (void *)track->auxBuffer());
+            mAudioMixer->setParameter(
+                trackId,
+                AudioMixer::TRACK,
+                AudioMixer::HAPTIC_ENABLED, (void *)(uintptr_t)track->getHapticPlaybackEnabled());
+            mAudioMixer->setParameter(
+                trackId,
+                AudioMixer::TRACK,
+                AudioMixer::HAPTIC_INTENSITY, (void *)(uintptr_t)track->getHapticIntensity());
 
             // reset retry count
             track->mRetryCount = kMaxTrackRetries;
@@ -4720,13 +5100,13 @@
                 mixerStatus = MIXER_TRACKS_READY;
             }
         } else {
+            size_t underrunFrames = 0;
             if (framesReady < desiredFrames && !track->isStopped() && !track->isPaused()) {
-                ALOGV("track(%p) underrun,  framesReady(%zu) < framesDesired(%zd)",
-                        track, framesReady, desiredFrames);
-                track->mAudioTrackServerProxy->tallyUnderrunFrames(desiredFrames);
-            } else {
-                track->mAudioTrackServerProxy->tallyUnderrunFrames(0);
+                ALOGV("track(%d) underrun,  framesReady(%zu) < framesDesired(%zd)",
+                        trackId, framesReady, desiredFrames);
+                underrunFrames = desiredFrames;
             }
+            deferredOperations.tallyUnderrunFrames(track, underrunFrames);
 
             // clear effect chain input buffer if an active track underruns to avoid sending
             // previous audio buffer again to effects
@@ -4735,7 +5115,7 @@
                 chain->clearInputBuffer();
             }
 
-            ALOGVV("track %d s=%08x [NOT READY] on thread %p", name, cblk->mServer, this);
+            ALOGVV("track(%d) s=%08x [NOT READY] on thread %p", trackId, cblk->mServer, this);
             if ((track->sharedBuffer() != 0) || track->isTerminated() ||
                     track->isStopped() || track->isPaused()) {
                 // We have consumed all the buffers of this track.
@@ -4754,7 +5134,8 @@
                 // No buffers for this track. Give it a few chances to
                 // fill a buffer, then remove it from active list.
                 if (--(track->mRetryCount) <= 0) {
-                    ALOGI("BUFFER TIMEOUT: remove(%d) from active list on thread %p", name, this);
+                    ALOGI("BUFFER TIMEOUT: remove(%d) from active list on thread %p",
+                            trackId, this);
                     tracksToRemove->add(track);
                     // indicate to client process that the track was disabled because of underrun;
                     // it will then automatically call start() when data is available
@@ -4767,13 +5148,24 @@
                     mixerStatus = MIXER_TRACKS_ENABLED;
                 }
             }
-            mAudioMixer->disable(name);
+            mAudioMixer->disable(trackId);
         }
 
         }   // local variable scope to avoid goto warning
 
     }
 
+    if (mHapticChannelMask != AUDIO_CHANNEL_NONE && sq != NULL) {
+        // When there is no fast track playing haptic and FastMixer exists,
+        // enabling the first FastTrack, which provides mixed data from normal
+        // tracks, to play haptic data.
+        FastTrack *fastTrack = &state->mFastTracks[0];
+        if (fastTrack->mHapticPlaybackEnabled != noFastHapticTrack) {
+            fastTrack->mHapticPlaybackEnabled = noFastHapticTrack;
+            didModify = true;
+        }
+    }
+
     // Push the new FastMixer state if necessary
     bool pauseAudioWatchdog = false;
     if (didModify) {
@@ -4828,9 +5220,9 @@
     // of prepareTracks_l(); this releases any outstanding buffer back to the track.
     // See also the implementation of destroyTrack_l().
     for (const auto &track : *tracksToRemove) {
-        const int name = track->name();
-        if (mAudioMixer->exists(name)) { // Normal tracks here, fast tracks in FastMixer.
-            mAudioMixer->setBufferProvider(name, nullptr /* bufferProvider */);
+        const int trackId = track->id();
+        if (mAudioMixer->exists(trackId)) { // Normal tracks here, fast tracks in FastMixer.
+            mAudioMixer->setBufferProvider(trackId, nullptr /* bufferProvider */);
         }
     }
 
@@ -4999,17 +5391,17 @@
             delete mAudioMixer;
             mAudioMixer = new AudioMixer(mNormalFrameCount, mSampleRate);
             for (const auto &track : mTracks) {
-                const int name = track->name();
+                const int trackId = track->id();
                 status_t status = mAudioMixer->create(
-                        name,
+                        trackId,
                         track->mChannelMask,
                         track->mFormat,
                         track->mSessionId);
                 ALOGW_IF(status != NO_ERROR,
-                        "%s: cannot create track name"
-                        " %d, mask %#x, format %#x, sessionId %d in AudioMixer",
+                        "%s(): AudioMixer cannot create track(%d)"
+                        " mask %#x, format %#x, sessionId %d",
                         __func__,
-                        name, track->mChannelMask, track->mFormat, track->mSessionId);
+                        trackId, track->mChannelMask, track->mFormat, track->mSessionId);
             }
             sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED);
         }
@@ -5019,13 +5411,15 @@
 }
 
 
-void AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& args)
+void AudioFlinger::MixerThread::dumpInternals_l(int fd, const Vector<String16>& args)
 {
-    PlaybackThread::dumpInternals(fd, args);
+    PlaybackThread::dumpInternals_l(fd, args);
     dprintf(fd, "  Thread throttle time (msecs): %u\n", mThreadThrottleTimeMs);
     dprintf(fd, "  AudioMixer tracks: %s\n", mAudioMixer->trackNames().c_str());
     dprintf(fd, "  Master mono: %s\n", mMasterMono ? "on" : "off");
-
+    dprintf(fd, "  Master balance: %f (%s)\n", mMasterBalance.load(),
+            (hasFastMixer() ? std::to_string(mFastMixer->getMasterBalance())
+                            : mBalance.toString()).c_str());
     if (hasFastMixer()) {
         dprintf(fd, "  FastMixer thread %p tid=%d", mFastMixer.get(), mFastMixer->getTid());
 
@@ -5033,9 +5427,9 @@
         // while we are dumping it.  It may be inconsistent, but it won't mutate!
         // This is a large object so we place it on the heap.
         // FIXME 25972958: Need an intelligent copy constructor that does not touch unused pages.
-        const FastMixerDumpState *copy = new FastMixerDumpState(mFastMixerDumpState);
+        const std::unique_ptr<FastMixerDumpState> copy =
+                std::make_unique<FastMixerDumpState>(mFastMixerDumpState);
         copy->dump(fd);
-        delete copy;
 
 #ifdef STATE_QUEUE_DUMP
         // Similar for state queue
@@ -5056,12 +5450,6 @@
     } else {
         dprintf(fd, "  No FastMixer\n");
     }
-
-#ifdef TEE_SINK
-    // Write the tee output to a .wav file
-    dumpTee(fd, mTeeSource, mId, 'M');
-#endif
-
 }
 
 uint32_t AudioFlinger::MixerThread::idleSleepTimeUs() const
@@ -5088,52 +5476,61 @@
 // ----------------------------------------------------------------------------
 
 AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger,
-        AudioStreamOut* output, audio_io_handle_t id, audio_devices_t device, bool systemReady)
-    :   PlaybackThread(audioFlinger, output, id, device, DIRECT, systemReady)
-{
-}
-
-AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger,
-        AudioStreamOut* output, audio_io_handle_t id, uint32_t device,
+        AudioStreamOut* output, audio_io_handle_t id, audio_devices_t device,
         ThreadBase::type_t type, bool systemReady)
     :   PlaybackThread(audioFlinger, output, id, device, type, systemReady)
-        , mVolumeShaperActive(false)
 {
+    setMasterBalance(audioFlinger->getMasterBalance_l());
 }
 
 AudioFlinger::DirectOutputThread::~DirectOutputThread()
 {
 }
 
+void AudioFlinger::DirectOutputThread::dumpInternals_l(int fd, const Vector<String16>& args)
+{
+    PlaybackThread::dumpInternals_l(fd, args);
+    dprintf(fd, "  Master balance: %f  Left: %f  Right: %f\n",
+            mMasterBalance.load(), mMasterBalanceLeft, mMasterBalanceRight);
+}
+
+void AudioFlinger::DirectOutputThread::setMasterBalance(float balance)
+{
+    Mutex::Autolock _l(mLock);
+    if (mMasterBalance != balance) {
+        mMasterBalance.store(balance);
+        mBalance.computeStereoBalance(balance, &mMasterBalanceLeft, &mMasterBalanceRight);
+        broadcast_l();
+    }
+}
+
 void AudioFlinger::DirectOutputThread::processVolume_l(Track *track, bool lastTrack)
 {
     float left, right;
 
-    if (mMasterMute || mStreamTypes[track->streamType()].mute) {
+    // Ensure volumeshaper state always advances even when muted.
+    const sp<AudioTrackServerProxy> proxy = track->mAudioTrackServerProxy;
+    const auto [shaperVolume, shaperActive] = track->getVolumeHandler()->getVolume(
+            proxy->framesReleased());
+    mVolumeShaperActive = shaperActive;
+
+    if (mMasterMute || mStreamTypes[track->streamType()].mute || track->isPlaybackRestricted()) {
         left = right = 0;
     } else {
         float typeVolume = mStreamTypes[track->streamType()].volume;
-        float v = mMasterVolume * typeVolume;
-        sp<AudioTrackServerProxy> proxy = track->mAudioTrackServerProxy;
-
-        // Get volumeshaper scaling
-        std::pair<float /* volume */, bool /* active */>
-            vh = track->getVolumeHandler()->getVolume(
-                    track->mAudioTrackServerProxy->framesReleased());
-        v *= vh.first;
-        mVolumeShaperActive = vh.second;
+        const float v = mMasterVolume * typeVolume * shaperVolume;
 
         gain_minifloat_packed_t vlr = proxy->getVolumeLR();
         left = float_from_gain(gain_minifloat_unpack_left(vlr));
         if (left > GAIN_FLOAT_UNITY) {
             left = GAIN_FLOAT_UNITY;
         }
-        left *= v;
+        left *= v * mMasterBalanceLeft; // DirectOutputThread balance applied as track volume
         right = float_from_gain(gain_minifloat_unpack_right(vlr));
         if (right > GAIN_FLOAT_UNITY) {
             right = GAIN_FLOAT_UNITY;
         }
-        right *= v;
+        right *= v * mMasterBalanceRight;
     }
 
     if (lastTrack) {
@@ -5142,20 +5539,20 @@
             mLeftVolFloat = left;
             mRightVolFloat = right;
 
-            // Convert volumes from float to 8.24
-            uint32_t vl = (uint32_t)(left * (1 << 24));
-            uint32_t vr = (uint32_t)(right * (1 << 24));
-
             // Delegate volume control to effect in track effect chain if needed
             // only one effect chain can be present on DirectOutputThread, so if
             // there is one, the track is connected to it
             if (!mEffectChains.isEmpty()) {
-                mEffectChains[0]->setVolume_l(&vl, &vr);
-                left = (float)vl / (1 << 24);
-                right = (float)vr / (1 << 24);
+                // if effect chain exists, volume is handled by it.
+                // Convert volumes from float to 8.24
+                uint32_t vl = (uint32_t)(left * (1 << 24));
+                uint32_t vr = (uint32_t)(right * (1 << 24));
+                // Direct/Offload effect chains set output volume in setVolume_l().
+                (void)mEffectChains[0]->setVolume_l(&vl, &vr);
+            } else {
+                // otherwise we directly set the volume.
+                setVolumeForOutput_l(left, right);
             }
-            status_t result = mOutput->stream->setVolume(left, right);
-            ALOGE_IF(result != OK, "Error when setting output stream volume: %d", result);
         }
     }
 }
@@ -5175,6 +5572,11 @@
                 mFlushPending = true;
             }
         }
+    } else if (previousTrack == 0) {
+        // there could be an old track added back during track transition for direct
+        // output, so always issues flush to flush data of the previous track if it
+        // was already destroyed with HAL paused, then flush can resume the playback
+        mFlushPending = true;
     }
     PlaybackThread::onAddNewTrack_l();
 }
@@ -5213,7 +5615,6 @@
                 doHwPause = true;
                 mHwPaused = true;
             }
-            tracksToRemove->add(track);
         } else if (track->isFlushPending()) {
             track->flushAck();
             if (last) {
@@ -5248,7 +5649,7 @@
         if ((track->framesReady() >= minFrames) && track->isReady() && !track->isPaused() &&
                 !track->isStopping_2() && !track->isStopped())
         {
-            ALOGVV("track %d s=%08x [OK]", track->name(), cblk->mServer);
+            ALOGVV("track(%d) s=%08x [OK]", track->id(), cblk->mServer);
 
             if (track->mFillingUpStatus == Track::FS_FILLED) {
                 track->mFillingUpStatus = Track::FS_ACTIVE;
@@ -5310,7 +5711,8 @@
 
                 int64_t framesWritten = mBytesWritten / mFrameSize;
                 if (mStandby || !last ||
-                        track->presentationComplete(framesWritten, audioHALFrames)) {
+                        track->presentationComplete(framesWritten, audioHALFrames) ||
+                        track->isPaused()) {
                     if (track->isStopping_2()) {
                         track->mState = TrackBase::STOPPED;
                     }
@@ -5324,7 +5726,7 @@
                 // fill a buffer, then remove it from active list.
                 // Only consider last track started for mixer state control
                 if (--(track->mRetryCount) <= 0) {
-                    ALOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name());
+                    ALOGV("BUFFER TIMEOUT: remove track(%d) from active list", track->id());
                     tracksToRemove->add(track);
                     // indicate to client process that the track was disabled because of underrun;
                     // it will then automatically call start() when data is available
@@ -5563,6 +5965,7 @@
     mOutput->flush();
     mHwPaused = false;
     mFlushPending = false;
+    mTimestampVerifier.discontinuity(); // DIRECT and OFFLOADED flush resets frame count.
 }
 
 int64_t AudioFlinger::DirectOutputThread::computeWaitTimeNs_l() const {
@@ -5806,7 +6209,7 @@
             }
         }  else if (track->framesReady() && track->isReady() &&
                 !track->isPaused() && !track->isTerminated() && !track->isStopping_2()) {
-            ALOGVV("OffloadThread: track %d s=%08x [OK]", track->name(), cblk->mServer);
+            ALOGVV("OffloadThread: track(%d) s=%08x [OK]", track->id(), cblk->mServer);
             if (track->mFillingUpStatus == Track::FS_FILLED) {
                 track->mFillingUpStatus = Track::FS_ACTIVE;
                 if (last) {
@@ -5850,7 +6253,7 @@
                 mixerStatus = MIXER_TRACKS_READY;
             }
         } else {
-            ALOGVV("OffloadThread: track %d s=%08x [NOT READY]", track->name(), cblk->mServer);
+            ALOGVV("OffloadThread: track(%d) s=%08x [NOT READY]", track->id(), cblk->mServer);
             if (track->isStopping_1()) {
                 if (--(track->mRetryCount) <= 0) {
                     // Hardware buffer can hold a large amount of audio so we must
@@ -5897,6 +6300,14 @@
                     track->presentationComplete(framesWritten, audioHALFrames);
                     track->reset();
                     tracksToRemove->add(track);
+                    // DIRECT and OFFLOADED stop resets frame counts.
+                    if (!mUseAsyncWrite) {
+                        // If we don't get explicit drain notification we must
+                        // register discontinuity regardless of whether this is
+                        // the previous (!last) or the upcoming (last) track
+                        // to avoid skipping the discontinuity.
+                        mTimestampVerifier.discontinuity();
+                    }
                 }
             } else {
                 // No buffers for this track. Give it a few chances to
@@ -5918,8 +6329,8 @@
                     if (running) { // still running, give us more time.
                         track->mRetryCount = kMaxTrackRetriesOffload;
                     } else {
-                        ALOGV("OffloadThread: BUFFER TIMEOUT: remove(%d) from active list",
-                                track->name());
+                        ALOGV("OffloadThread: BUFFER TIMEOUT: remove track(%d) from active list",
+                                track->id());
                         tracksToRemove->add(track);
                         // tell client process that the track was disabled because of underrun;
                         // it will then automatically call start() when data is available
@@ -6062,7 +6473,22 @@
 ssize_t AudioFlinger::DuplicatingThread::threadLoop_write()
 {
     for (size_t i = 0; i < outputTracks.size(); i++) {
-        outputTracks[i]->write(mSinkBuffer, writeFrames);
+        const ssize_t actualWritten = outputTracks[i]->write(mSinkBuffer, writeFrames);
+
+        // Consider the first OutputTrack for timestamp and frame counting.
+
+        // The threadLoop() generally assumes writing a full sink buffer size at a time.
+        // Here, we correct for writeFrames of 0 (a stop) or underruns because
+        // we always claim success.
+        if (i == 0) {
+            const ssize_t correction = mSinkBufferSize / mFrameSize - actualWritten;
+            ALOGD_IF(correction != 0 && writeFrames != 0,
+                    "%s: writeFrames:%u  actualWritten:%zd  correction:%zd  mFramesWritten:%lld",
+                    __func__, writeFrames, actualWritten, correction, (long long)mFramesWritten);
+            mFramesWritten -= correction;
+        }
+
+        // TODO: Report correction for the other output tracks and show in the dump.
     }
     mStandby = false;
     return (ssize_t)mSinkBufferSize;
@@ -6076,9 +6502,9 @@
     }
 }
 
-void AudioFlinger::DuplicatingThread::dumpInternals(int fd, const Vector<String16>& args __unused)
+void AudioFlinger::DuplicatingThread::dumpInternals_l(int fd, const Vector<String16>& args __unused)
 {
-    MixerThread::dumpInternals(fd, args);
+    MixerThread::dumpInternals_l(fd, args);
 
     std::stringstream ss;
     const size_t numTracks = mOutputTracks.size();
@@ -6087,7 +6513,7 @@
         ss << ":";
         for (const auto &track : mOutputTracks) {
             const sp<ThreadBase> thread = track->thread().promote();
-            ss << " (" << track->name() << " : ";
+            ss << " (" << track->id() << " : ";
             if (thread.get() != nullptr) {
                 ss << thread.get() << ", " << thread->id();
             } else {
@@ -6227,9 +6653,6 @@
                                          audio_devices_t outDevice,
                                          audio_devices_t inDevice,
                                          bool systemReady
-#ifdef TEE_SINK
-                                         , const sp<NBAIO_Sink>& teeSink
-#endif
                                          ) :
     ThreadBase(audioFlinger, id, outDevice, inDevice, RECORD, systemReady),
     mInput(input),
@@ -6237,9 +6660,6 @@
     mRsmpInBuffer(NULL),
     // mRsmpInFrames, mRsmpInFramesP2, and mRsmpInFramesOA are set by readInputParameters_l()
     mRsmpInRear(0)
-#ifdef TEE_SINK
-    , mTeeSink(teeSink)
-#endif
     , mReadOnlyHeap(new MemoryDealer(kRecordThreadReadOnlyHeapSize,
             "RecordThreadRO", MemoryHeapBase::READ_ONLY))
     // mFastCapture below
@@ -6256,8 +6676,20 @@
     snprintf(mThreadName, kThreadNameLength, "AudioIn_%X", id);
     mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mThreadName);
 
+    if (mInput != nullptr && mInput->audioHwDev != nullptr) {
+        mIsMsdDevice = strcmp(
+                mInput->audioHwDev->moduleName(), AUDIO_HARDWARE_MODULE_ID_MSD) == 0;
+    }
+
     readInputParameters_l();
 
+    // TODO: We may also match on address as well as device type for
+    // AUDIO_DEVICE_IN_BUS, AUDIO_DEVICE_IN_BLUETOOTH_A2DP, AUDIO_DEVICE_IN_REMOTE_SUBMIX
+    mTimestampCorrectedDevices = (audio_devices_t)property_get_int64(
+            "audio.timestamp.corrected_input_devices",
+            (int64_t)(mIsMsdDevice ? AUDIO_DEVICE_IN_BUS // turn on by default for MSD
+                                   : AUDIO_DEVICE_NONE));
+
     // create an NBAIO source for the HAL input stream, and negotiate
     mInputSource = new AudioStreamInSource(input->stream);
     size_t numCounterOffers = 0;
@@ -6354,7 +6786,7 @@
         // start the fast capture
         mFastCapture->run("FastCapture", ANDROID_PRIORITY_URGENT_AUDIO);
         pid_t tid = mFastCapture->getTid();
-        sendPrioConfigEvent(getpid_cached, tid, kPriorityFastCapture, false /*forApp*/);
+        sendPrioConfigEvent(getpid(), tid, kPriorityFastCapture, false /*forApp*/);
         stream()->setHalThreadPriority(kPriorityFastCapture);
 #ifdef AUDIO_WATCHDOG
         // FIXME
@@ -6362,6 +6794,10 @@
 
         mFastTrackAvail = true;
     }
+#ifdef TEE_SINK
+    mTee.set(mInputSource->format(), NBAIO_Tee::TEE_FLAG_INPUT_THREAD);
+    mTee.setId(std::string("_") + std::to_string(mId) + "_C");
+#endif
 failed: ;
 
     // FIXME mNormalSource
@@ -6422,8 +6858,10 @@
     // used to request a deferred sleep, to be executed later while mutex is unlocked
     uint32_t sleepUs = 0;
 
+    int64_t lastLoopCountRead = -2;  // never matches "previous" loop, when loopCount = 0.
+
     // loop while there is work to do
-    for (;;) {
+    for (int64_t loopCount = 0;; ++loopCount) {  // loopCount used for statistics tracking
         Vector< sp<EffectChain> > effectChains;
 
         // activeTracks accumulates a copy of a subset of mActiveTracks
@@ -6435,6 +6873,8 @@
         // reference to a fast track which is about to be removed
         sp<RecordTrack> fastTrackToRemove;
 
+        bool silenceFastCapture = false;
+
         { // scope for mLock
             Mutex::Autolock _l(mLock);
 
@@ -6489,6 +6929,7 @@
 
                 case TrackBase::PAUSING:
                     mActiveTracks.remove(activeTrack);
+                    activeTrack->mState = TrackBase::PAUSED;
                     doBroadcast = true;
                     size--;
                     continue;
@@ -6510,22 +6951,41 @@
                     allStopped = false;
                     break;
 
-                case TrackBase::IDLE:
-                    i++;
-                    continue;
-
+                case TrackBase::IDLE:    // cannot be on ActiveTracks if idle
+                case TrackBase::PAUSED:  // cannot be on ActiveTracks if paused
+                case TrackBase::STOPPED: // cannot be on ActiveTracks if destroyed/terminated
                 default:
-                    LOG_ALWAYS_FATAL("Unexpected activeTrackState %d", activeTrackState);
+                    LOG_ALWAYS_FATAL("%s: Unexpected active track state:%d, id:%d, tracks:%zu",
+                            __func__, activeTrackState, activeTrack->id(), size);
+                }
+
+                if (activeTrack->isFastTrack()) {
+                    ALOG_ASSERT(!mFastTrackAvail);
+                    ALOG_ASSERT(fastTrack == 0);
+                    // if the active fast track is silenced either:
+                    // 1) silence the whole capture from fast capture buffer if this is
+                    //    the only active track
+                    // 2) invalidate this track: this will cause the client to reconnect and possibly
+                    //    be invalidated again until unsilenced
+                    if (activeTrack->isSilenced()) {
+                        if (size > 1) {
+                            activeTrack->invalidate();
+                            ALOG_ASSERT(fastTrackToRemove == 0);
+                            fastTrackToRemove = activeTrack;
+                            removeTrack_l(activeTrack);
+                            mActiveTracks.remove(activeTrack);
+                            size--;
+                            continue;
+                        } else {
+                            silenceFastCapture = true;
+                        }
+                    }
+                    fastTrack = activeTrack;
                 }
 
                 activeTracks.add(activeTrack);
                 i++;
 
-                if (activeTrack->isFastTrack()) {
-                    ALOG_ASSERT(!mFastTrackAvail);
-                    ALOG_ASSERT(fastTrack == 0);
-                    fastTrack = activeTrack;
-                }
             }
 
             mActiveTracks.updatePowerState(this);
@@ -6540,7 +7000,7 @@
             }
 
             // sleep if there are no active tracks to process
-            if (activeTracks.size() == 0) {
+            if (activeTracks.isEmpty()) {
                 if (sleepUs == 0) {
                     sleepUs = kRecordThreadSleepUs;
                 }
@@ -6591,6 +7051,18 @@
                 }
                 didModify = true;
             }
+            AudioBufferProvider* abp = (fastTrack != 0 && fastTrack->isPatchTrack()) ?
+                    reinterpret_cast<AudioBufferProvider*>(fastTrack.get()) : nullptr;
+            if (state->mFastPatchRecordBufferProvider != abp) {
+                state->mFastPatchRecordBufferProvider = abp;
+                state->mFastPatchRecordFormat = fastTrack == 0 ?
+                        AUDIO_FORMAT_INVALID : fastTrack->format();
+                didModify = true;
+            }
+            if (state->mSilenceCapture != silenceFastCapture) {
+                state->mSilenceCapture = silenceFastCapture;
+                didModify = true;
+            }
             sq->end(didModify);
             if (didModify) {
                 sq->push(block);
@@ -6613,11 +7085,11 @@
 
         int32_t rear = mRsmpInRear & (mRsmpInFramesP2 - 1);
         ssize_t framesRead;
+        const int64_t lastIoBeginNs = systemTime(); // start IO timing
 
         // If an NBAIO source is present, use it to read the normal capture's data
         if (mPipeSource != 0) {
-            size_t framesToRead = mBufferSize / mFrameSize;
-            framesToRead = min(mRsmpInFramesOA - rear, mRsmpInFramesP2 / 2);
+            size_t framesToRead = min(mRsmpInFramesOA - rear, mRsmpInFramesP2 / 2);
 
             // The audio fifo read() returns OVERRUN on overflow, and advances the read pointer
             // to the full buffer point (clearing the overflow condition).  Upon OVERRUN error,
@@ -6671,16 +7143,34 @@
             }
         }
 
+        const int64_t lastIoEndNs = systemTime(); // end IO timing
+
         // Update server timestamp with server stats
         // systemTime() is optional if the hardware supports timestamps.
         mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] += framesRead;
-        mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] = systemTime();
+        mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] = lastIoEndNs;
 
         // Update server timestamp with kernel stats
         if (mPipeSource.get() == nullptr /* don't obtain for FastCapture, could block */) {
             int64_t position, time;
-            int ret = mInput->stream->getCapturePosition(&position, &time);
-            if (ret == NO_ERROR) {
+            if (mStandby) {
+                mTimestampVerifier.discontinuity();
+            } else if (mInput->stream->getCapturePosition(&position, &time) == NO_ERROR
+                    && time > mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL]) {
+
+                mTimestampVerifier.add(position, time, mSampleRate);
+
+                // Correct timestamps
+                if (isTimestampCorrectionEnabled()) {
+                    ALOGV("TS_BEFORE: %d %lld %lld",
+                            id(), (long long)time, (long long)position);
+                    auto correctedTimestamp = mTimestampVerifier.getLastCorrectedTimestamp();
+                    position = correctedTimestamp.mFrames;
+                    time = correctedTimestamp.mTimeNs;
+                    ALOGV("TS_AFTER: %d %lld %lld",
+                            id(), (long long)time, (long long)position);
+                }
+
                 mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] = position;
                 mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] = time;
                 // Note: In general record buffers should tend to be empty in
@@ -6688,8 +7178,19 @@
                 //
                 // Also, it is not advantageous to call get_presentation_position during the read
                 // as the read obtains a lock, preventing the timestamp call from executing.
+            } else {
+                mTimestampVerifier.error();
             }
         }
+
+        // From the timestamp, input read latency is negative output write latency.
+        const audio_input_flags_t flags = mInput != NULL ? mInput->flags : AUDIO_INPUT_FLAG_NONE;
+        const double latencyMs = RecordTrack::checkServerLatencySupported(mFormat, flags)
+                ? - mTimestamp.getOutputServerLatencyMs(mSampleRate) : 0.;
+        if (latencyMs != 0.) { // note 0. means timestamp is empty.
+            mLatencyMs.add(latencyMs);
+        }
+
         // Use this to track timestamp information
         // ALOGD("%s", mTimestamp.toString().c_str());
 
@@ -6703,10 +7204,11 @@
             goto unlock;
         }
         ALOG_ASSERT(framesRead > 0);
+        mFramesRead += framesRead;
 
-        if (mTeeSink != 0) {
-            (void) mTeeSink->write((uint8_t*)mRsmpInBuffer + rear * mFrameSize, framesRead);
-        }
+#ifdef TEE_SINK
+        (void)mTee.write((uint8_t*)mRsmpInBuffer + rear * mFrameSize, framesRead);
+#endif
         // If destination is non-contiguous, we now correct for reading past end of buffer.
         {
             size_t part1 = mRsmpInFramesP2 - rear;
@@ -6764,9 +7266,33 @@
                 framesOut = min(framesOut,
                         destinationFramesPossible(
                                 framesIn, mSampleRate, activeTrack->mSampleRate));
-                // process frames from the RecordThread buffer provider to the RecordTrack buffer
-                framesOut = activeTrack->mRecordBufferConverter->convert(
-                        activeTrack->mSink.raw, activeTrack->mResamplerBufferProvider, framesOut);
+
+                if (activeTrack->isDirect()) {
+                    // No RecordBufferConverter used for direct streams. Pass
+                    // straight from RecordThread buffer to RecordTrack buffer.
+                    AudioBufferProvider::Buffer buffer;
+                    buffer.frameCount = framesOut;
+                    status_t status = activeTrack->mResamplerBufferProvider->getNextBuffer(&buffer);
+                    if (status == OK && buffer.frameCount != 0) {
+                        ALOGV_IF(buffer.frameCount != framesOut,
+                                "%s() read less than expected (%zu vs %zu)",
+                                __func__, buffer.frameCount, framesOut);
+                        framesOut = buffer.frameCount;
+                        memcpy(activeTrack->mSink.raw, buffer.raw, buffer.frameCount * mFrameSize);
+                        activeTrack->mResamplerBufferProvider->releaseBuffer(&buffer);
+                    } else {
+                        framesOut = 0;
+                        ALOGE("%s() cannot fill request, status: %d, frameCount: %zu",
+                            __func__, status, buffer.frameCount);
+                    }
+                } else {
+                    // process frames from the RecordThread buffer provider to the RecordTrack
+                    // buffer
+                    framesOut = activeTrack->mRecordBufferConverter->convert(
+                            activeTrack->mSink.raw,
+                            activeTrack->mResamplerBufferProvider,
+                            framesOut);
+                }
 
                 if (framesOut > 0 && (overrun == OVERRUN_UNKNOWN)) {
                     overrun = OVERRUN_FALSE;
@@ -6785,7 +7311,7 @@
                 } else {
                     // FIXME could do a partial drop of framesOut
                     if (activeTrack->mFramesToDrop > 0) {
-                        activeTrack->mFramesToDrop -= framesOut;
+                        activeTrack->mFramesToDrop -= (ssize_t)framesOut;
                         if (activeTrack->mFramesToDrop <= 0) {
                             activeTrack->clearSyncStartEvent();
                         }
@@ -6839,6 +7365,23 @@
         // enable changes in effect chain
         unlockEffectChains(effectChains);
         // effectChains doesn't need to be cleared, since it is cleared by destructor at scope end
+        if (audio_has_proportional_frames(mFormat)
+            && loopCount == lastLoopCountRead + 1) {
+            const int64_t readPeriodNs = lastIoEndNs - mLastIoEndNs;
+            const double jitterMs =
+                TimestampVerifier<int64_t, int64_t>::computeJitterMs(
+                    {framesRead, readPeriodNs},
+                    {0, 0} /* lastTimestamp */, mSampleRate);
+            const double processMs = (lastIoBeginNs - mLastIoEndNs) * 1e-6;
+
+            Mutex::Autolock _l(mLock);
+            mIoJitterMs.add(jitterMs);
+            mProcessTimeMs.add(processMs);
+        }
+        // update timing info.
+        mLastIoBeginNs = lastIoBeginNs;
+        mLastIoEndNs = lastIoEndNs;
+        lastLoopCountRead = loopCount;
     }
 
     standbyIfNotAlreadyInStandby();
@@ -6917,6 +7460,7 @@
         size_t *pFrameCount,
         audio_session_t sessionId,
         size_t *pNotificationFrameCount,
+        pid_t creatorPid,
         uid_t uid,
         audio_input_flags_t *flags,
         pid_t tid,
@@ -6938,6 +7482,12 @@
         goto Exit;
     }
 
+    if (!audio_is_linear_pcm(mFormat) && (*flags & AUDIO_INPUT_FLAG_DIRECT) == 0) {
+        ALOGE("createRecordTrack_l() on an encoded stream requires AUDIO_INPUT_FLAG_DIRECT");
+        lStatus = BAD_VALUE;
+        goto Exit;
+    }
+
     if (*pSampleRate == 0) {
         *pSampleRate = mSampleRate;
     }
@@ -6962,8 +7512,10 @@
             // we formerly checked for a callback handler (non-0 tid),
             // but that is no longer required for TRANSFER_OBTAIN mode
             //
-            // frame count is not specified, or is exactly the pipe depth
-            ((frameCount == 0) || (frameCount == mPipeFramesP2)) &&
+            // Frame count is not specified (0), or is less than or equal the pipe depth.
+            // It is OK to provide a higher capacity than requested.
+            // We will force it to mPipeFramesP2 below.
+            (frameCount <= mPipeFramesP2) &&
             // PCM data
             audio_is_linear_pcm(format) &&
             // hardware format
@@ -7047,7 +7599,7 @@
 
         track = new RecordTrack(this, client, attr, sampleRate,
                       format, channelMask, frameCount,
-                      nullptr /* buffer */, (size_t)0 /* bufferSize */, sessionId, uid,
+                      nullptr /* buffer */, (size_t)0 /* bufferSize */, sessionId, creatorPid, uid,
                       *flags, TrackBase::TYPE_DEFAULT, opPackageName, portId);
 
         lStatus = track->initCheck();
@@ -7103,8 +7655,14 @@
     {
         // This section is a rendezvous between binder thread executing start() and RecordThread
         AutoMutex lock(mLock);
+        if (recordTrack->isInvalid()) {
+            recordTrack->clearSyncStartEvent();
+            return INVALID_OPERATION;
+        }
         if (mActiveTracks.indexOf(recordTrack) >= 0) {
             if (recordTrack->mState == TrackBase::PAUSING) {
+                // We haven't stopped yet (moved to PAUSED and not in mActiveTracks)
+                // so no need to startInput().
                 ALOGV("active record track PAUSING -> ACTIVE");
                 recordTrack->mState = TrackBase::ACTIVE;
             } else {
@@ -7121,17 +7679,36 @@
         status_t status = NO_ERROR;
         if (recordTrack->isExternalTrack()) {
             mLock.unlock();
-            bool silenced;
-            status = AudioSystem::startInput(recordTrack->portId(), &silenced);
+            status = AudioSystem::startInput(recordTrack->portId());
             mLock.lock();
-            // FIXME should verify that recordTrack is still in mActiveTracks
+            if (recordTrack->isInvalid()) {
+                recordTrack->clearSyncStartEvent();
+                if (status == NO_ERROR && recordTrack->mState == TrackBase::STARTING_1) {
+                    recordTrack->mState = TrackBase::STARTING_2;
+                    // STARTING_2 forces destroy to call stopInput.
+                }
+                return INVALID_OPERATION;
+            }
+            if (recordTrack->mState != TrackBase::STARTING_1) {
+                ALOGW("%s(%d): unsynchronized mState:%d change",
+                    __func__, recordTrack->id(), recordTrack->mState);
+                // Someone else has changed state, let them take over,
+                // leave mState in the new state.
+                recordTrack->clearSyncStartEvent();
+                return INVALID_OPERATION;
+            }
+            // we're ok, but perhaps startInput has failed
             if (status != NO_ERROR) {
+                ALOGW("%s(%d): startInput failed, status %d",
+                    __func__, recordTrack->id(), status);
+                // We are in ActiveTracks if STARTING_1 and valid, so remove from ActiveTracks,
+                // leave in STARTING_1, so destroy() will not call stopInput.
                 mActiveTracks.remove(recordTrack);
                 recordTrack->clearSyncStartEvent();
-                ALOGV("RecordThread::start error %d", status);
                 return status;
             }
-            recordTrack->setSilenced(silenced);
+            sendIoConfigEvent_l(
+                AUDIO_CLIENT_STARTED, recordTrack->creatorPid(), recordTrack->portId());
         }
         // Catch up with current buffer indices if thread is already running.
         // This is what makes a new client discard all buffered data.  If the track's mRsmpInFront
@@ -7139,26 +7716,15 @@
         // see previously buffered data before it called start(), but with greater risk of overrun.
 
         recordTrack->mResamplerBufferProvider->reset();
-        // clear any converter state as new data will be discontinuous
-        recordTrack->mRecordBufferConverter->reset();
+        if (!recordTrack->isDirect()) {
+            // clear any converter state as new data will be discontinuous
+            recordTrack->mRecordBufferConverter->reset();
+        }
         recordTrack->mState = TrackBase::STARTING_2;
         // signal thread to start
         mWaitWorkCV.broadcast();
-        if (mActiveTracks.indexOf(recordTrack) < 0) {
-            ALOGV("Record failed to start");
-            status = BAD_VALUE;
-            goto startError;
-        }
         return status;
     }
-
-startError:
-    if (recordTrack->isExternalTrack()) {
-        AudioSystem::stopInput(recordTrack->portId());
-    }
-    recordTrack->clearSyncStartEvent();
-    // FIXME I wonder why we do not reset the state here?
-    return status;
 }
 
 void AudioFlinger::RecordThread::syncStartEventCallback(const wp<SyncEvent>& event)
@@ -7177,24 +7743,28 @@
 bool AudioFlinger::RecordThread::stop(RecordThread::RecordTrack* recordTrack) {
     ALOGV("RecordThread::stop");
     AutoMutex _l(mLock);
+    // if we're invalid, we can't be on the ActiveTracks.
     if (mActiveTracks.indexOf(recordTrack) < 0 || recordTrack->mState == TrackBase::PAUSING) {
         return false;
     }
     // note that threadLoop may still be processing the track at this point [without lock]
     recordTrack->mState = TrackBase::PAUSING;
-    // signal thread to stop
-    mWaitWorkCV.broadcast();
-    // do not wait for mStartStopCond if exiting
-    if (exitPending()) {
-        return true;
+
+    // NOTE: Waiting here is important to keep stop synchronous.
+    // This is needed for proper patchRecord peer release.
+    while (recordTrack->mState == TrackBase::PAUSING && !recordTrack->isInvalid()) {
+        mWaitWorkCV.broadcast(); // signal thread to stop
+        mStartStopCond.wait(mLock);
     }
-    // FIXME incorrect usage of wait: no explicit predicate or loop
-    mStartStopCond.wait(mLock);
-    // if we have been restarted, recordTrack is in mActiveTracks here
-    if (exitPending() || mActiveTracks.indexOf(recordTrack) < 0) {
+
+    if (recordTrack->mState == TrackBase::PAUSED) { // successful stop
         ALOGV("Record stopped OK");
         return true;
     }
+
+    // don't handle anything - we've been invalidated or restarted and in a different state
+    ALOGW_IF("%s(%d): unsynchronized stop, state: %d",
+            __func__, recordTrack->id(), recordTrack->mState);
     return false;
 }
 
@@ -7237,6 +7807,21 @@
     return status;
 }
 
+status_t AudioFlinger::RecordThread::setPreferredMicrophoneDirection(
+            audio_microphone_direction_t direction)
+{
+    ALOGV("setPreferredMicrophoneDirection(%d)", direction);
+    AutoMutex _l(mLock);
+    return mInput->stream->setPreferredMicrophoneDirection(direction);
+}
+
+status_t AudioFlinger::RecordThread::setPreferredMicrophoneFieldDimension(float zoom)
+{
+    ALOGV("setPreferredMicrophoneFieldDimension(%f)", zoom);
+    AutoMutex _l(mLock);
+    return mInput->stream->setPreferredMicrophoneFieldDimension(zoom);
+}
+
 void AudioFlinger::RecordThread::updateMetadata_l()
 {
     if (mInput == nullptr || mInput->stream == nullptr ||
@@ -7279,24 +7864,14 @@
     }
 }
 
-void AudioFlinger::RecordThread::dump(int fd, const Vector<String16>& args)
+void AudioFlinger::RecordThread::dumpInternals_l(int fd, const Vector<String16>& args __unused)
 {
-    dumpInternals(fd, args);
-    dumpTracks(fd, args);
-    dumpEffectChains(fd, args);
-    dprintf(fd, "  Local log:\n");
-    mLocalLog.dump(fd, "   " /* prefix */, 40 /* lines */);
-}
-
-void AudioFlinger::RecordThread::dumpInternals(int fd, const Vector<String16>& args)
-{
-    dumpBase(fd, args);
-
     AudioStreamIn *input = mInput;
     audio_input_flags_t flags = input != NULL ? input->flags : AUDIO_INPUT_FLAG_NONE;
     dprintf(fd, "  AudioStreamIn: %p flags %#x (%s)\n",
-            input, flags, inputFlagsToString(flags).c_str());
-    if (mActiveTracks.size() == 0) {
+            input, flags, toString(flags).c_str());
+    dprintf(fd, "  Frames read: %lld\n", (long long)mFramesRead);
+    if (mActiveTracks.isEmpty()) {
         dprintf(fd, "  No active record clients\n");
     }
 
@@ -7312,12 +7887,12 @@
     // while we are dumping it.  It may be inconsistent, but it won't mutate!
     // This is a large object so we place it on the heap.
     // FIXME 25972958: Need an intelligent copy constructor that does not touch unused pages.
-    const FastCaptureDumpState *copy = new FastCaptureDumpState(mFastCaptureDumpState);
+    const std::unique_ptr<FastCaptureDumpState> copy =
+            std::make_unique<FastCaptureDumpState>(mFastCaptureDumpState);
     copy->dump(fd);
-    delete copy;
 }
 
-void AudioFlinger::RecordThread::dumpTracks(int fd, const Vector<String16>& args __unused)
+void AudioFlinger::RecordThread::dumpTracks_l(int fd, const Vector<String16>& args __unused)
 {
     String8 result;
     size_t numtracks = mTracks.size();
@@ -7328,7 +7903,7 @@
     if (numtracks) {
         dprintf(fd, " of which %zu are active\n", numactive);
         result.append(prefix);
-        RecordTrack::appendDumpHeader(result);
+        mTracks[0]->appendDumpHeader(result);
         for (size_t i = 0; i < numtracks ; ++i) {
             sp<RecordTrack> track = mTracks[i];
             if (track != 0) {
@@ -7348,7 +7923,7 @@
         result.append("  The following tracks are in the active list but"
                 " not in the track list\n");
         result.append(prefix);
-        RecordTrack::appendDumpHeader(result);
+        mActiveTracks[0]->appendDumpHeader(result);
         for (size_t i = 0; i < numactive; ++i) {
             sp<RecordTrack> track = mActiveTracks[i];
             if (mTracks.indexOf(track) < 0) {
@@ -7387,7 +7962,7 @@
     RecordThread *recordThread = (RecordThread *) threadBase.get();
     const int32_t rear = recordThread->mRsmpInRear;
     const int32_t front = mRsmpInFront;
-    const ssize_t filled = rear - front;
+    const ssize_t filled = audio_utils::safe_sub_overflow(rear, front);
 
     size_t framesIn;
     bool overrun = false;
@@ -7401,7 +7976,8 @@
     } else {
         // client is not keeping up with server, but give it latest data
         framesIn = recordThread->mRsmpInFrames;
-        mRsmpInFront = /* front = */ rear - framesIn;
+        mRsmpInFront = /* front = */ audio_utils::safe_sub_overflow(
+                rear, static_cast<int32_t>(framesIn));
         overrun = true;
     }
     if (framesAvailable != NULL) {
@@ -7425,7 +8001,7 @@
     RecordThread *recordThread = (RecordThread *) threadBase.get();
     int32_t rear = recordThread->mRsmpInRear;
     int32_t front = mRsmpInFront;
-    ssize_t filled = rear - front;
+    ssize_t filled = audio_utils::safe_sub_overflow(rear, front);
     // FIXME should not be P2 (don't want to increase latency)
     // FIXME if client not keeping up, discard
     LOG_ALWAYS_FATAL_IF(!(0 <= filled && (size_t) filled <= recordThread->mRsmpInFrames));
@@ -7458,13 +8034,13 @@
 void AudioFlinger::RecordThread::ResamplerBufferProvider::releaseBuffer(
         AudioBufferProvider::Buffer* buffer)
 {
-    size_t stepCount = buffer->frameCount;
+    int32_t stepCount = static_cast<int32_t>(buffer->frameCount);
     if (stepCount == 0) {
         return;
     }
     ALOG_ASSERT(stepCount <= mRsmpInUnrel);
     mRsmpInUnrel -= stepCount;
-    mRsmpInFront += stepCount;
+    mRsmpInFront = audio_utils::safe_add_overflow(mRsmpInFront, stepCount);
     buffer->raw = NULL;
     buffer->frameCount = 0;
 }
@@ -7614,7 +8190,8 @@
     return String8();
 }
 
-void AudioFlinger::RecordThread::ioConfigChanged(audio_io_config_event event, pid_t pid) {
+void AudioFlinger::RecordThread::ioConfigChanged(audio_io_config_event event, pid_t pid,
+                                                 audio_port_handle_t portId) {
     sp<AudioIoDescriptor> desc = new AudioIoDescriptor();
 
     desc->mIoHandle = mId;
@@ -7631,7 +8208,10 @@
         desc->mFrameCountHAL = mFrameCount;
         desc->mLatency = 0;
         break;
-
+    case AUDIO_CLIENT_STARTED:
+        desc->mPatch = mPatch;
+        desc->mPortId = portId;
+        break;
     case AUDIO_INPUT_CLOSED:
     default:
         break;
@@ -7643,10 +8223,15 @@
 {
     status_t result = mInput->stream->getAudioProperties(&mSampleRate, &mChannelMask, &mHALFormat);
     LOG_ALWAYS_FATAL_IF(result != OK, "Error retrieving audio properties from HAL: %d", result);
-    mChannelCount = audio_channel_count_from_in_mask(mChannelMask);
-    LOG_ALWAYS_FATAL_IF(mChannelCount > FCC_8, "HAL channel count %d > %d", mChannelCount, FCC_8);
     mFormat = mHALFormat;
-    LOG_ALWAYS_FATAL_IF(!audio_is_linear_pcm(mFormat), "HAL format %#x is not linear pcm", mFormat);
+    mChannelCount = audio_channel_count_from_in_mask(mChannelMask);
+    if (audio_is_linear_pcm(mFormat)) {
+        LOG_ALWAYS_FATAL_IF(mChannelCount > FCC_8, "HAL channel count %d > %d",
+                mChannelCount, FCC_8);
+    } else {
+        // Can have more that FCC_8 channels in encoded streams.
+        ALOGI("HAL format %#x is not linear pcm", mFormat);
+    }
     result = mInput->stream->getFrameSize(&mFrameSize);
     LOG_ALWAYS_FATAL_IF(result != OK, "Error retrieving frame size from HAL: %d", result);
     result = mInput->stream->getBufferSize(&mBufferSize);
@@ -7696,27 +8281,6 @@
     return 0;
 }
 
-// hasAudioSession_l() must be called with ThreadBase::mLock held
-uint32_t AudioFlinger::RecordThread::hasAudioSession_l(audio_session_t sessionId) const
-{
-    uint32_t result = 0;
-    if (getEffectChain_l(sessionId) != 0) {
-        result = EFFECT_SESSION;
-    }
-
-    for (size_t i = 0; i < mTracks.size(); ++i) {
-        if (sessionId == mTracks[i]->sessionId()) {
-            result |= TRACK_SESSION;
-            if (mTracks[i]->isFastTrack()) {
-                result |= FAST_SESSION;
-            }
-            break;
-        }
-    }
-
-    return result;
-}
-
 KeyedVector<audio_session_t, bool> AudioFlinger::RecordThread::sessionIds() const
 {
     KeyedVector<audio_session_t, bool> ids;
@@ -7750,11 +8314,6 @@
 
 status_t AudioFlinger::RecordThread::addEffectChain_l(const sp<EffectChain>& chain)
 {
-    // only one chain per input thread
-    if (mEffectChains.size() != 0) {
-        ALOGW("addEffectChain_l() already one chain %p on thread %p", chain.get(), this);
-        return INVALID_OPERATION;
-    }
     ALOGV("addEffectChain_l() %p on thread %p", chain.get(), this);
     chain->setThread(this);
     chain->setInBuffer(NULL);
@@ -7774,13 +8333,14 @@
 size_t AudioFlinger::RecordThread::removeEffectChain_l(const sp<EffectChain>& chain)
 {
     ALOGV("removeEffectChain_l() %p from thread %p", chain.get(), this);
-    ALOGW_IF(mEffectChains.size() != 1,
-            "removeEffectChain_l() %p invalid chain size %zu on thread %p",
-            chain.get(), mEffectChains.size(), this);
-    if (mEffectChains.size() == 1) {
-        mEffectChains.removeAt(0);
+
+    for (size_t i = 0; i < mEffectChains.size(); i++) {
+        if (chain == mEffectChains[i]) {
+            mEffectChains.removeAt(i);
+            break;
+        }
     }
-    return 0;
+    return mEffectChains.size();
 }
 
 status_t AudioFlinger::RecordThread::createAudioPatch_l(const struct audio_patch *patch,
@@ -7790,6 +8350,7 @@
 
     // store new device and send to effects
     mInDevice = patch->sources[0].ext.device.type;
+    audio_port_handle_t deviceId = patch->sources[0].id;
     mPatch = *patch;
     for (size_t i = 0; i < mEffectChains.size(); i++) {
         mEffectChains[i]->setDevice_l(mInDevice);
@@ -7831,9 +8392,10 @@
         *handle = AUDIO_PATCH_HANDLE_NONE;
     }
 
-    if (mInDevice != mPrevInDevice) {
+    if ((mInDevice != mPrevInDevice) || (mDeviceId != deviceId)) {
         sendIoConfigEvent_l(AUDIO_INPUT_CONFIG_CHANGED);
         mPrevInDevice = mInDevice;
+        mDeviceId = deviceId;
     }
 
     return status;
@@ -7856,24 +8418,28 @@
     return status;
 }
 
-void AudioFlinger::RecordThread::addPatchRecord(const sp<PatchRecord>& record)
+void AudioFlinger::RecordThread::addPatchTrack(const sp<PatchRecord>& record)
 {
     Mutex::Autolock _l(mLock);
     mTracks.add(record);
 }
 
-void AudioFlinger::RecordThread::deletePatchRecord(const sp<PatchRecord>& record)
+void AudioFlinger::RecordThread::deletePatchTrack(const sp<PatchRecord>& record)
 {
     Mutex::Autolock _l(mLock);
     destroyTrack_l(record);
 }
 
-void AudioFlinger::RecordThread::getAudioPortConfig(struct audio_port_config *config)
+void AudioFlinger::RecordThread::toAudioPortConfig(struct audio_port_config *config)
 {
-    ThreadBase::getAudioPortConfig(config);
+    ThreadBase::toAudioPortConfig(config);
     config->role = AUDIO_PORT_ROLE_SINK;
     config->ext.mix.hw_module = mInput->audioHwDev->handle();
     config->ext.mix.usecase.source = mAudioSource;
+    if (mInput && mInput->flags != AUDIO_INPUT_FLAG_NONE) {
+        config->config_mask |= AUDIO_PORT_CONFIG_FLAGS;
+        config->flags.input = mInput->flags;
+    }
 }
 
 // ----------------------------------------------------------------------------
@@ -7926,7 +8492,7 @@
         audio_devices_t outDevice, audio_devices_t inDevice, bool systemReady)
     : ThreadBase(audioFlinger, id, outDevice, inDevice, MMAP, systemReady),
       mSessionId(AUDIO_SESSION_NONE),
-      mDeviceId(AUDIO_PORT_HANDLE_NONE), mPortId(AUDIO_PORT_HANDLE_NONE),
+      mPortId(AUDIO_PORT_HANDLE_NONE),
       mHalStream(stream), mHalDevice(hwDev->hwDevice()), mAudioHwDev(hwDev),
       mActiveTracks(&this->mLocalLog),
       mHalVolFloat(-1.0f), // Initialize to illegal value so it always gets set properly later.
@@ -7960,7 +8526,7 @@
     }
     // This will decrement references and may cause the destruction of this thread.
     if (isOutput()) {
-        AudioSystem::releaseOutput(mId, streamType(), mSessionId);
+        AudioSystem::releaseOutput(mPortId);
     } else {
         AudioSystem::releaseInput(mPortId);
     }
@@ -8039,6 +8605,7 @@
         audio_output_flags_t flags =
                 (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT);
         audio_port_handle_t deviceId = mDeviceId;
+        std::vector<audio_io_handle_t> secondaryOutputs;
         ret = AudioSystem::getOutputForAttr(&mAttr, &io,
                                             mSessionId,
                                             &stream,
@@ -8047,7 +8614,10 @@
                                             &config,
                                             flags,
                                             &deviceId,
-                                            &portId);
+                                            &portId,
+                                            &secondaryOutputs);
+        ALOGD_IF(!secondaryOutputs.empty(),
+                 "MmapThread::start does not support secondary outputs, ignoring them");
     } else {
         audio_config_base_t config;
         config.sample_rate = mSampleRate;
@@ -8055,6 +8625,7 @@
         config.format = mFormat;
         audio_port_handle_t deviceId = mDeviceId;
         ret = AudioSystem::getInputForAttr(&mAttr, &io,
+                                              RECORD_RIID_INVALID,
                                               mSessionId,
                                               client.clientPid,
                                               client.clientUid,
@@ -8072,21 +8643,20 @@
         return BAD_VALUE;
     }
 
-    bool silenced = false;
     if (isOutput()) {
-        ret = AudioSystem::startOutput(mId, streamType(), mSessionId);
+        ret = AudioSystem::startOutput(portId);
     } else {
-        ret = AudioSystem::startInput(portId, &silenced);
+        ret = AudioSystem::startInput(portId);
     }
 
     Mutex::Autolock _l(mLock);
     // abort if start is rejected by audio policy manager
     if (ret != NO_ERROR) {
         ALOGE("%s: error start rejected by AudioPolicyManager = %d", __FUNCTION__, ret);
-        if (mActiveTracks.size() != 0) {
+        if (!mActiveTracks.isEmpty()) {
             mLock.unlock();
             if (isOutput()) {
-                AudioSystem::releaseOutput(mId, streamType(), mSessionId);
+                AudioSystem::releaseOutput(portId);
             } else {
                 AudioSystem::releaseInput(portId);
             }
@@ -8097,21 +8667,22 @@
         return PERMISSION_DENIED;
     }
 
+    // Given that MmapThread::mAttr is mutable, should a MmapTrack have attributes ?
+    sp<MmapTrack> track = new MmapTrack(this, mAttr, mSampleRate, mFormat, mChannelMask, mSessionId,
+                                        isOutput(), client.clientUid, client.clientPid,
+                                        IPCThreadState::self()->getCallingPid(), portId);
+
     if (isOutput()) {
         // force volume update when a new track is added
         mHalVolFloat = -1.0f;
-    } else if (!silenced) {
-        for (const sp<MmapTrack> &track : mActiveTracks) {
-            if (track->isSilenced_l() && track->uid() != client.clientUid)
-                track->invalidate();
+    } else if (!track->isSilenced_l()) {
+        for (const sp<MmapTrack> &t : mActiveTracks) {
+            if (t->isSilenced_l() && t->uid() != client.clientUid)
+                t->invalidate();
         }
     }
 
-    // Given that MmapThread::mAttr is mutable, should a MmapTrack have attributes ?
-    sp<MmapTrack> track = new MmapTrack(this, mAttr, mSampleRate, mFormat, mChannelMask, mSessionId,
-                                        client.clientUid, client.clientPid, portId);
 
-    track->setSilenced_l(silenced);
     mActiveTracks.add(track);
     sp<EffectChain> chain = getEffectChain_l(mSessionId);
     if (chain != 0) {
@@ -8158,8 +8729,8 @@
 
     mLock.unlock();
     if (isOutput()) {
-        AudioSystem::stopOutput(mId, streamType(), track->sessionId());
-        AudioSystem::releaseOutput(mId, streamType(), track->sessionId());
+        AudioSystem::stopOutput(track->portId());
+        AudioSystem::releaseOutput(track->portId());
     } else {
         AudioSystem::stopInput(track->portId());
         AudioSystem::releaseInput(track->portId());
@@ -8184,7 +8755,7 @@
     if (mHalStream == 0) {
         return NO_INIT;
     }
-    if (mActiveTracks.size() != 0) {
+    if (!mActiveTracks.isEmpty()) {
         return INVALID_OPERATION;
     }
     mHalStream->standby();
@@ -8215,9 +8786,11 @@
 
     while (!exitPending())
     {
-        Mutex::Autolock _l(mLock);
         Vector< sp<EffectChain> > effectChains;
 
+        { // under Thread lock
+        Mutex::Autolock _l(mLock);
+
         if (mSignalPending) {
             // A signal was raised while we were unlocked
             mSignalPending = false;
@@ -8252,10 +8825,13 @@
         updateMetadata_l();
 
         lockEffectChains_l(effectChains);
+        } // release Thread lock
+
         for (size_t i = 0; i < effectChains.size(); i ++) {
-            effectChains[i]->process_l();
+            effectChains[i]->process_l(); // Thread is not locked, but effect chain is locked
         }
-        // enable changes in effect chain
+
+        // enable changes in effect chain, including moving to another thread.
         unlockEffectChains(effectChains);
         // Effect chains will be actually deleted here if they were removed from
         // mEffectChains list during mixing or effects processing
@@ -8320,7 +8896,8 @@
     return String8();
 }
 
-void AudioFlinger::MmapThread::ioConfigChanged(audio_io_config_event event, pid_t pid) {
+void AudioFlinger::MmapThread::ioConfigChanged(audio_io_config_event event, pid_t pid,
+                                               audio_port_handle_t portId __unused) {
     sp<AudioIoDescriptor> desc = new AudioIoDescriptor();
 
     desc->mIoHandle = mId;
@@ -8411,7 +8988,7 @@
         *handle = AUDIO_PATCH_HANDLE_NONE;
     }
 
-    if (isOutput() && mPrevOutDevice != mOutDevice) {
+    if (isOutput() && (mPrevOutDevice != mOutDevice || mDeviceId != deviceId)) {
         mPrevOutDevice = type;
         sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED);
         sp<MmapStreamCallback> callback = mCallback.promote();
@@ -8422,7 +8999,7 @@
         }
         mDeviceId = deviceId;
     }
-    if (!isOutput() && mPrevInDevice != mInDevice) {
+    if (!isOutput() && (mPrevInDevice != mInDevice || mDeviceId != deviceId)) {
         mPrevInDevice = type;
         sendIoConfigEvent_l(AUDIO_INPUT_CONFIG_CHANGED);
         sp<MmapStreamCallback> callback = mCallback.promote();
@@ -8455,9 +9032,9 @@
     return status;
 }
 
-void AudioFlinger::MmapThread::getAudioPortConfig(struct audio_port_config *config)
+void AudioFlinger::MmapThread::toAudioPortConfig(struct audio_port_config *config)
 {
-    ThreadBase::getAudioPortConfig(config);
+    ThreadBase::toAudioPortConfig(config);
     if (isOutput()) {
         config->role = AUDIO_PORT_ROLE_SOURCE;
         config->ext.mix.hw_module = mAudioHwDev->handle();
@@ -8516,28 +9093,6 @@
     return mEffectChains.size();
 }
 
-// hasAudioSession_l() must be called with ThreadBase::mLock held
-uint32_t AudioFlinger::MmapThread::hasAudioSession_l(audio_session_t sessionId) const
-{
-    uint32_t result = 0;
-    if (getEffectChain_l(sessionId) != 0) {
-        result = EFFECT_SESSION;
-    }
-
-    for (size_t i = 0; i < mActiveTracks.size(); i++) {
-        sp<MmapTrack> track = mActiveTracks[i];
-        if (sessionId == track->sessionId()) {
-            result |= TRACK_SESSION;
-            if (track->isFastTrack()) {
-                result |= FAST_SESSION;
-            }
-            break;
-        }
-    }
-
-    return result;
-}
-
 void AudioFlinger::MmapThread::threadLoop_standby()
 {
     mHalStream->standby();
@@ -8606,28 +9161,17 @@
     }
 }
 
-void AudioFlinger::MmapThread::dump(int fd, const Vector<String16>& args)
+void AudioFlinger::MmapThread::dumpInternals_l(int fd, const Vector<String16>& args __unused)
 {
-    dumpInternals(fd, args);
-    dumpTracks(fd, args);
-    dumpEffectChains(fd, args);
-    dprintf(fd, "  Local log:\n");
-    mLocalLog.dump(fd, "   " /* prefix */, 40 /* lines */);
-}
-
-void AudioFlinger::MmapThread::dumpInternals(int fd, const Vector<String16>& args)
-{
-    dumpBase(fd, args);
-
     dprintf(fd, "  Attributes: content type %d usage %d source %d\n",
             mAttr.content_type, mAttr.usage, mAttr.source);
     dprintf(fd, "  Session: %d port Id: %d\n", mSessionId, mPortId);
-    if (mActiveTracks.size() == 0) {
+    if (mActiveTracks.isEmpty()) {
         dprintf(fd, "  No active clients\n");
     }
 }
 
-void AudioFlinger::MmapThread::dumpTracks(int fd, const Vector<String16>& args __unused)
+void AudioFlinger::MmapThread::dumpTracks_l(int fd, const Vector<String16>& args __unused)
 {
     String8 result;
     size_t numtracks = mActiveTracks.size();
@@ -8635,7 +9179,7 @@
     const char *prefix = "    ";
     if (numtracks) {
         result.append(prefix);
-        MmapTrack::appendDumpHeader(result);
+        mActiveTracks[0]->appendDumpHeader(result);
         for (size_t i = 0; i < numtracks ; ++i) {
             sp<MmapTrack> track = mActiveTracks[i];
             result.append(prefix);
@@ -8841,9 +9385,18 @@
     }
 }
 
-void AudioFlinger::MmapPlaybackThread::dumpInternals(int fd, const Vector<String16>& args)
+void AudioFlinger::MmapPlaybackThread::toAudioPortConfig(struct audio_port_config *config)
 {
-    MmapThread::dumpInternals(fd, args);
+    MmapThread::toAudioPortConfig(config);
+    if (mOutput && mOutput->flags != AUDIO_OUTPUT_FLAG_NONE) {
+        config->config_mask |= AUDIO_PORT_CONFIG_FLAGS;
+        config->flags.output = mOutput->flags;
+    }
+}
+
+void AudioFlinger::MmapPlaybackThread::dumpInternals_l(int fd, const Vector<String16>& args)
+{
+    MmapThread::dumpInternals_l(fd, args);
 
     dprintf(fd, "  Stream type: %d Stream volume: %f HAL volume: %f Stream mute %d\n",
             mStreamType, mStreamVolume, mHalVolFloat, mStreamMute);
@@ -8863,7 +9416,13 @@
 
 status_t AudioFlinger::MmapCaptureThread::exitStandby()
 {
-    mInput->stream->setGain(1.0f);
+    {
+        // mInput might have been cleared by clearInput()
+        Mutex::Autolock _l(mLock);
+        if (mInput != nullptr && mInput->stream != nullptr) {
+            mInput->stream->setGain(1.0f);
+        }
+    }
     return MmapThread::exitStandby();
 }
 
@@ -8931,4 +9490,13 @@
     }
 }
 
+void AudioFlinger::MmapCaptureThread::toAudioPortConfig(struct audio_port_config *config)
+{
+    MmapThread::toAudioPortConfig(config);
+    if (mInput && mInput->flags != AUDIO_INPUT_FLAG_NONE) {
+        config->config_mask |= AUDIO_PORT_CONFIG_FLAGS;
+        config->flags.input = mInput->flags;
+    }
+}
+
 } // namespace android
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 33d6923..c6a8201 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -43,9 +43,6 @@
 
     virtual status_t    readyToRun();
 
-    void dumpBase(int fd, const Vector<String16>& args);
-    void dumpEffectChains(int fd, const Vector<String16>& args);
-
     void clearPowerManager();
 
     // base for record and playback
@@ -106,8 +103,9 @@
 
     class IoConfigEventData : public ConfigEventData {
     public:
-        IoConfigEventData(audio_io_config_event event, pid_t pid) :
-            mEvent(event), mPid(pid) {}
+        IoConfigEventData(audio_io_config_event event, pid_t pid,
+                          audio_port_handle_t portId) :
+            mEvent(event), mPid(pid), mPortId(portId) {}
 
         virtual  void dump(char *buffer, size_t size) {
             snprintf(buffer, size, "IO event: event %d\n", mEvent);
@@ -115,13 +113,14 @@
 
         const audio_io_config_event mEvent;
         const pid_t                 mPid;
+        const audio_port_handle_t   mPortId;
     };
 
     class IoConfigEvent : public ConfigEvent {
     public:
-        IoConfigEvent(audio_io_config_event event, pid_t pid) :
+        IoConfigEvent(audio_io_config_event event, pid_t pid, audio_port_handle_t portId) :
             ConfigEvent(CFG_EVENT_IO) {
-            mData = new IoConfigEventData(event, pid);
+            mData = new IoConfigEventData(event, pid, portId);
         }
         virtual ~IoConfigEvent() {}
     };
@@ -263,13 +262,16 @@
                                                     status_t& status) = 0;
     virtual     status_t    setParameters(const String8& keyValuePairs);
     virtual     String8     getParameters(const String8& keys) = 0;
-    virtual     void        ioConfigChanged(audio_io_config_event event, pid_t pid = 0) = 0;
+    virtual     void        ioConfigChanged(audio_io_config_event event, pid_t pid = 0,
+                                        audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) = 0;
                 // sendConfigEvent_l() must be called with ThreadBase::mLock held
                 // Can temporarily release the lock if waiting for a reply from
                 // processConfigEvents_l().
                 status_t    sendConfigEvent_l(sp<ConfigEvent>& event);
-                void        sendIoConfigEvent(audio_io_config_event event, pid_t pid = 0);
-                void        sendIoConfigEvent_l(audio_io_config_event event, pid_t pid = 0);
+                void        sendIoConfigEvent(audio_io_config_event event, pid_t pid = 0,
+                                              audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
+                void        sendIoConfigEvent_l(audio_io_config_event event, pid_t pid = 0,
+                                            audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
                 void        sendPrioConfigEvent(pid_t pid, pid_t tid, int32_t prio, bool forApp);
                 void        sendPrioConfigEvent_l(pid_t pid, pid_t tid, int32_t prio, bool forApp);
                 status_t    sendSetParameterConfigEvent_l(const String8& keyValuePair);
@@ -281,7 +283,7 @@
     virtual     status_t    createAudioPatch_l(const struct audio_patch *patch,
                                                audio_patch_handle_t *handle) = 0;
     virtual     status_t    releaseAudioPatch_l(const audio_patch_handle_t handle) = 0;
-    virtual     void        getAudioPortConfig(struct audio_port_config *config) = 0;
+    virtual     void        toAudioPortConfig(struct audio_port_config *config) = 0;
 
 
                 // see note at declaration of mStandby, mOutDevice and mInDevice
@@ -318,6 +320,7 @@
                 sp<EffectChain> getEffectChain(audio_session_t sessionId);
                 // same as getEffectChain() but must be called with ThreadBase mutex locked
                 sp<EffectChain> getEffectChain_l(audio_session_t sessionId) const;
+                std::vector<int> getEffectIds_l(audio_session_t sessionId);
                 // add an effect chain to the chain list (mEffectChains)
     virtual     status_t addEffectChain_l(const sp<EffectChain>& chain) = 0;
                 // remove an effect chain from the chain list (mEffectChains)
@@ -337,7 +340,8 @@
                 sp<AudioFlinger::EffectModule> getEffect(audio_session_t sessionId, int effectId);
                 sp<AudioFlinger::EffectModule> getEffect_l(audio_session_t sessionId, int effectId);
                 // add and effect module. Also creates the effect chain is none exists for
-                // the effects audio session
+                // the effects audio session. Only called in a context of moving an effect
+                // from one thread to another
                 status_t addEffect_l(const sp< EffectModule>& effect);
                 // remove and effect module. Also removes the effect chain is this was the last
                 // effect
@@ -356,6 +360,27 @@
                     return hasAudioSession_l(sessionId);
                 }
 
+                template <typename T>
+                uint32_t hasAudioSession_l(audio_session_t sessionId, const T& tracks) const {
+                    uint32_t result = 0;
+                    if (getEffectChain_l(sessionId) != 0) {
+                        result = EFFECT_SESSION;
+                    }
+                    for (size_t i = 0; i < tracks.size(); ++i) {
+                        const sp<TrackBase>& track = tracks[i];
+                        if (sessionId == track->sessionId()
+                                && !track->isInvalid()       // not yet removed from tracks.
+                                && !track->isTerminated()) {
+                            result |= TRACK_SESSION;
+                            if (track->isFastTrack()) {
+                                result |= FAST_SESSION;  // caution, only represents first track.
+                            }
+                            break;
+                        }
+                    }
+                    return result;
+                }
+
                 // the value returned by default implementation is not important as the
                 // strategy is only meaningful for PlaybackThread which implements this method
                 virtual uint32_t getStrategyForSession_l(audio_session_t sessionId __unused)
@@ -393,6 +418,15 @@
 
                         void        broadcast_l();
 
+                virtual bool        isTimestampCorrectionEnabled() const { return false; }
+
+                bool                isMsdDevice() const { return mIsMsdDevice; }
+
+                void                dump(int fd, const Vector<String16>& args);
+
+                // deliver stats to mediametrics.
+                void                sendStatistics(bool force);
+
     mutable     Mutex                   mLock;
 
 protected:
@@ -434,6 +468,17 @@
     virtual     void        setMasterMono_l(bool mono __unused) { }
     virtual     bool        requireMonoBlend() { return false; }
 
+                            // called within the threadLoop to obtain timestamp from the HAL.
+    virtual     status_t    threadloop_getHalTimestamp_l(
+                                    ExtendedTimestamp *timestamp __unused) const {
+                                return INVALID_OPERATION;
+                            }
+
+    virtual     void        dumpInternals_l(int fd __unused, const Vector<String16>& args __unused)
+                            { }
+    virtual     void        dumpTracks_l(int fd __unused, const Vector<String16>& args __unused) { }
+
+
     friend class AudioFlinger;      // for mEffectChains
 
                 const type_t            mType;
@@ -473,6 +518,10 @@
                 audio_devices_t         mPrevOutDevice;   // previous output device
                 audio_devices_t         mPrevInDevice;    // previous input device
                 struct audio_patch      mPatch;
+                /**
+                 * @brief mDeviceId  current device port unique identifier
+                 */
+                audio_port_handle_t     mDeviceId = AUDIO_PORT_HANDLE_NONE;
                 audio_source_t          mAudioSource;
 
                 const audio_io_handle_t mId;
@@ -493,10 +542,31 @@
                 sp<NBLog::Writer>       mNBLogWriter;
                 bool                    mSystemReady;
                 ExtendedTimestamp       mTimestamp;
+                TimestampVerifier< // For timestamp statistics.
+                        int64_t /* frame count */, int64_t /* time ns */> mTimestampVerifier;
+                audio_devices_t         mTimestampCorrectedDevices = AUDIO_DEVICE_NONE;
+
+                // ThreadLoop statistics per iteration.
+                int64_t                 mLastIoBeginNs = -1;
+                int64_t                 mLastIoEndNs = -1;
+
+                // This should be read under ThreadBase lock (if not on the threadLoop thread).
+                audio_utils::Statistics<double> mIoJitterMs{0.995 /* alpha */};
+                audio_utils::Statistics<double> mProcessTimeMs{0.995 /* alpha */};
+                audio_utils::Statistics<double> mLatencyMs{0.995 /* alpha */};
+
+                // Save the last count when we delivered statistics to mediametrics.
+                int64_t                 mLastRecordedTimestampVerifierN = 0;
+                int64_t                 mLastRecordedTimeNs = 0;  // BOOTTIME to include suspend.
+
+                bool                    mIsMsdDevice = false;
                 // A condition that must be evaluated by the thread loop has changed and
                 // we must not wait for async write callback in the thread loop before evaluating it
                 bool                    mSignalPending;
 
+#ifdef TEE_SINK
+                NBAIO_Tee               mTee;
+#endif
                 // ActiveTracks is a sorted vector of track type T representing the
                 // active tracks of threadLoop() to be considered by the locked prepare portion.
                 // ActiveTracks should be accessed with the ThreadBase lock held.
@@ -543,6 +613,9 @@
                     size_t          size() const {
                         return mActiveTracks.size();
                     }
+                    bool            isEmpty() const {
+                        return mActiveTracks.isEmpty();
+                    }
                     ssize_t         indexOf(const sp<T>& item) {
                         return mActiveTracks.indexOf(item);
                     }
@@ -593,6 +666,10 @@
                 };
 
                 SimpleLog mLocalLog;
+
+private:
+                void dumpBase_l(int fd, const Vector<String16>& args);
+                void dumpEffectChains_l(int fd, const Vector<String16>& args);
 };
 
 class VolumeInterface {
@@ -645,8 +722,6 @@
                    audio_io_handle_t id, audio_devices_t device, type_t type, bool systemReady);
     virtual             ~PlaybackThread();
 
-                void        dump(int fd, const Vector<String16>& args);
-
     // Thread virtuals
     virtual     bool        threadLoop();
 
@@ -696,6 +771,9 @@
                                 mActiveTracks.updatePowerState(this, true /* force */);
                             }
 
+                void        dumpInternals_l(int fd, const Vector<String16>& args) override;
+                void        dumpTracks_l(int fd, const Vector<String16>& args) override;
+
 public:
 
     virtual     status_t    initCheck() const { return (mOutput == NULL) ? NO_INIT : NO_ERROR; }
@@ -707,11 +785,14 @@
 
                 // VolumeInterface
     virtual     void        setMasterVolume(float value);
+    virtual     void        setMasterBalance(float balance);
     virtual     void        setMasterMute(bool muted);
     virtual     void        setStreamVolume(audio_stream_type_t stream, float value);
     virtual     void        setStreamMute(audio_stream_type_t stream, bool muted);
     virtual     float       streamVolume(audio_stream_type_t stream) const;
 
+                void        setVolumeForOutput_l(float left, float right) const;
+
                 sp<Track>   createTrack_l(
                                 const sp<AudioFlinger::Client>& client,
                                 audio_stream_type_t streamType,
@@ -726,6 +807,7 @@
                                 const sp<IMemory>& sharedBuffer,
                                 audio_session_t sessionId,
                                 audio_output_flags_t *flags,
+                                pid_t creatorPid,
                                 pid_t tid,
                                 uid_t uid,
                                 status_t *status /*non-NULL*/,
@@ -749,7 +831,8 @@
                                 { return android_atomic_acquire_load(&mSuspended) > 0; }
 
     virtual     String8     getParameters(const String8& keys);
-    virtual     void        ioConfigChanged(audio_io_config_event event, pid_t pid = 0);
+    virtual     void        ioConfigChanged(audio_io_config_event event, pid_t pid = 0,
+                                            audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
                 status_t    getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames);
                 // Consider also removing and passing an explicit mMainBuffer initialization
                 // parameter to AF::PlaybackThread::Track::Track().
@@ -764,7 +847,9 @@
 
                 virtual status_t addEffectChain_l(const sp<EffectChain>& chain);
                 virtual size_t removeEffectChain_l(const sp<EffectChain>& chain);
-                virtual uint32_t hasAudioSession_l(audio_session_t sessionId) const;
+                        uint32_t hasAudioSession_l(audio_session_t sessionId) const override {
+                            return ThreadBase::hasAudioSession_l(sessionId, mTracks);
+                        }
                 virtual uint32_t getStrategyForSession_l(audio_session_t sessionId);
 
 
@@ -782,7 +867,7 @@
                 void        addPatchTrack(const sp<PatchTrack>& track);
                 void        deletePatchTrack(const sp<PatchTrack>& track);
 
-    virtual     void        getAudioPortConfig(struct audio_port_config *config);
+    virtual     void        toAudioPortConfig(struct audio_port_config *config);
 
                 // Return the asynchronous signal wait time.
     virtual     int64_t     computeWaitTimeNs_l() const { return INT64_MAX; }
@@ -799,6 +884,11 @@
                                        && mTracks.size() < PlaybackThread::kMaxTracks;
                             }
 
+                bool        isTimestampCorrectionEnabled() const override {
+                                const audio_devices_t device =
+                                        mOutDevice & mTimestampCorrectedDevices;
+                                return audio_is_output_devices(device) && popcount(device) > 0;
+                            }
 protected:
     // updated by readOutputParameters_l()
     size_t                          mNormalFrameCount;  // normal mixer and effects
@@ -878,6 +968,11 @@
     int64_t                         mBytesWritten;
     int64_t                         mFramesWritten; // not reset on standby
     int64_t                         mSuspendedFrames; // not reset on standby
+
+    // mHapticChannelMask and mHapticChannelCount will only be valid when the thread support
+    // haptic playback.
+    audio_channel_mask_t            mHapticChannelMask = AUDIO_CHANNEL_NONE;
+    uint32_t                        mHapticChannelCount = 0;
 private:
     // mMasterMute is in both PlaybackThread and in AudioFlinger.  When a
     // PlaybackThread needs to find out if master-muted, it checks it's local
@@ -930,19 +1025,19 @@
     void        updateMetadata_l() final;
     virtual void sendMetadataToBackend_l(const StreamOutHalInterface::SourceMetadata& metadata);
 
-    virtual void dumpInternals(int fd, const Vector<String16>& args);
-    void        dumpTracks(int fd, const Vector<String16>& args);
-
-    // The Tracks class manages names for all tracks
-    // added and removed from the Thread.
+    // The Tracks class manages tracks added and removed from the Thread.
     template <typename T>
     class Tracks {
     public:
-        Tracks(bool saveDeletedTrackNames) :
-            mSaveDeletedTrackNames(saveDeletedTrackNames) { }
+        Tracks(bool saveDeletedTrackIds) :
+            mSaveDeletedTrackIds(saveDeletedTrackIds) { }
 
         // SortedVector methods
-        ssize_t         add(const sp<T> &track);
+        ssize_t         add(const sp<T> &track) {
+            const ssize_t index = mTracks.add(track);
+            LOG_ALWAYS_FATAL_IF(index < 0, "cannot add track");
+            return index;
+        }
         ssize_t         remove(const sp<T> &track);
         size_t          size() const {
             return mTracks.size();
@@ -963,28 +1058,19 @@
             return mTracks.end();
         }
 
-        size_t          processDeletedTrackNames(std::function<void(int)> f) {
-            const size_t size = mDeletedTrackNames.size();
-            if (size > 0) {
-                for (const int name : mDeletedTrackNames) {
-                    f(name);
-                }
+        size_t          processDeletedTrackIds(std::function<void(int)> f) {
+            for (const int trackId : mDeletedTrackIds) {
+                f(trackId);
             }
-            return size;
+            return mDeletedTrackIds.size();
         }
 
-        void            clearDeletedTrackNames() { mDeletedTrackNames.clear(); }
+        void            clearDeletedTrackIds() { mDeletedTrackIds.clear(); }
 
     private:
-        // Track names pending deletion for MIXER type threads
-        const bool mSaveDeletedTrackNames; // true to enable tracking
-        std::set<int> mDeletedTrackNames;
-
-        // Fast lookup of previously deleted track names for reuse.
-        // This is an arbitrary decision (actually any non-negative
-        // integer that isn't in mTracks[*]->names() could be used) - we attempt
-        // to use the smallest possible available name.
-        std::set<int> mUnusedTrackNames;
+        // Tracks pending deletion for MIXER type threads
+        const bool mSaveDeletedTrackIds; // true to enable tracking
+        std::set<int> mDeletedTrackIds;
 
         SortedVector<sp<T>> mTracks; // wrapped SortedVector.
     };
@@ -995,7 +1081,8 @@
     AudioStreamOut                  *mOutput;
 
     float                           mMasterVolume;
-    nsecs_t                         mLastWriteTime;
+    std::atomic<float>              mMasterBalance{};
+    audio_utils::Balance            mBalance;
     int                             mNumWrites;
     int                             mNumDelayedWrites;
     bool                            mInWrite;
@@ -1054,16 +1141,13 @@
     sp<NBAIO_Sink>          mPipeSink;
     // The current sink for the normal mixer to write it's (sub)mix, mOutputSink or mPipeSink
     sp<NBAIO_Sink>          mNormalSink;
-#ifdef TEE_SINK
-    // For dumpsys
-    sp<NBAIO_Sink>          mTeeSink;
-    sp<NBAIO_Source>        mTeeSource;
-#endif
     uint32_t                mScreenState;   // cached copy of gScreenState
     // TODO: add comment and adjust size as needed
     static const size_t     kFastMixerLogSize = 8 * 1024;
     sp<NBLog::Writer>       mFastMixerNBLogWriter;
 
+    // Downstream patch latency, available if mDownstreamLatencyStatMs.getN() > 0.
+    audio_utils::Statistics<double> mDownstreamLatencyStatMs{0.999};
 
 public:
     virtual     bool        hasFastMixer() const = 0;
@@ -1095,7 +1179,6 @@
 
     virtual     bool        checkForNewParameter_l(const String8& keyValuePair,
                                                    status_t& status);
-    virtual     void        dumpInternals(int fd, const Vector<String16>& args);
 
     virtual     bool        isTrackAllowed_l(
                                     audio_channel_mask_t channelMask, audio_format_t format,
@@ -1114,12 +1197,13 @@
         }
     }
 
+                void        dumpInternals_l(int fd, const Vector<String16>& args) override;
+
     // threadLoop snippets
     virtual     ssize_t     threadLoop_write();
     virtual     void        threadLoop_standby();
     virtual     void        threadLoop_mix();
     virtual     void        threadLoop_sleepTime();
-    virtual     void        threadLoop_removeTracks(const Vector< sp<Track> >& tracksToRemove);
     virtual     uint32_t    correctLatency_l(uint32_t latency) const;
 
     virtual     status_t    createAudioPatch_l(const struct audio_patch *patch,
@@ -1152,6 +1236,14 @@
                               return mFastMixerDumpState.mTracks[fastIndex].mUnderruns;
                             }
 
+                status_t    threadloop_getHalTimestamp_l(
+                                    ExtendedTimestamp *timestamp) const override {
+                                if (mNormalSink.get() != nullptr) {
+                                    return mNormalSink->getTimestamp(*timestamp);
+                                }
+                                return INVALID_OPERATION;
+                            }
+
 protected:
     virtual     void       setMasterMono_l(bool mono) {
                                mMasterMono.store(mono);
@@ -1163,27 +1255,43 @@
                 // Blending with limiter is not idempotent,
                 // and blending without limiter is idempotent but inefficient to do twice.
     virtual     bool       requireMonoBlend() { return mMasterMono.load() && !hasFastMixer(); }
+
+                void       setMasterBalance(float balance) override {
+                               mMasterBalance.store(balance);
+                               if (hasFastMixer()) {
+                                   mFastMixer->setMasterBalance(balance);
+                               }
+                           }
 };
 
 class DirectOutputThread : public PlaybackThread {
 public:
 
     DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
-                       audio_io_handle_t id, audio_devices_t device, bool systemReady);
+                       audio_io_handle_t id, audio_devices_t device, bool systemReady)
+        : DirectOutputThread(audioFlinger, output, id, device, DIRECT, systemReady) { }
+
     virtual                 ~DirectOutputThread();
 
+                status_t    selectPresentation(int presentationId, int programId);
+
     // Thread virtuals
 
     virtual     bool        checkForNewParameter_l(const String8& keyValuePair,
                                                    status_t& status);
+
     virtual     void        flushHw_l();
 
+                void        setMasterBalance(float balance) override;
+
 protected:
     virtual     uint32_t    activeSleepTimeUs() const;
     virtual     uint32_t    idleSleepTimeUs() const;
     virtual     uint32_t    suspendSleepTimeUs() const;
     virtual     void        cacheParameters_l();
 
+                void        dumpInternals_l(int fd, const Vector<String16>& args) override;
+
     // threadLoop snippets
     virtual     mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove);
     virtual     void        threadLoop_mix();
@@ -1193,10 +1301,10 @@
 
     virtual     void        onAddNewTrack_l();
 
-    bool mVolumeShaperActive;
+    bool mVolumeShaperActive = false;
 
     DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
-                        audio_io_handle_t id, uint32_t device, ThreadBase::type_t type,
+                        audio_io_handle_t id, audio_devices_t device, ThreadBase::type_t type,
                         bool systemReady);
     void processVolume_l(Track *track, bool lastTrack);
 
@@ -1205,10 +1313,31 @@
 
     wp<Track>               mPreviousTrack;         // used to detect track switch
 
+    // This must be initialized for initial condition of mMasterBalance = 0 (disabled).
+    float                   mMasterBalanceLeft = 1.f;
+    float                   mMasterBalanceRight = 1.f;
+
 public:
     virtual     bool        hasFastMixer() const { return false; }
 
     virtual     int64_t     computeWaitTimeNs_l() const override;
+
+    status_t    threadloop_getHalTimestamp_l(ExtendedTimestamp *timestamp) const override {
+                    // For DIRECT and OFFLOAD threads, query the output sink directly.
+                    if (mOutput != nullptr) {
+                        uint64_t uposition64;
+                        struct timespec time;
+                        if (mOutput->getPresentationPosition(
+                                &uposition64, &time) == OK) {
+                            timestamp->mPosition[ExtendedTimestamp::LOCATION_KERNEL]
+                                    = (int64_t)uposition64;
+                            timestamp->mTimeNs[ExtendedTimestamp::LOCATION_KERNEL]
+                                    = audio_utils_ns_from_timespec(&time);
+                            return NO_ERROR;
+                        }
+                    }
+                    return INVALID_OPERATION;
+                }
 };
 
 class OffloadThread : public DirectOutputThread {
@@ -1282,8 +1411,6 @@
     virtual                 ~DuplicatingThread();
 
     // Thread virtuals
-    virtual     void        dumpInternals(int fd, const Vector<String16>& args) override;
-
                 void        addOutputTrack(MixerThread* thread);
                 void        removeOutputTrack(MixerThread* thread);
                 uint32_t    waitTimeMs() const { return mWaitTimeMs; }
@@ -1292,6 +1419,7 @@
                         const StreamOutHalInterface::SourceMetadata& metadata) override;
 protected:
     virtual     uint32_t    activeSleepTimeUs() const;
+                void        dumpInternals_l(int fd, const Vector<String16>& args) override;
 
 private:
                 bool        outputsReady(const SortedVector< sp<OutputTrack> > &outputTracks);
@@ -1316,6 +1444,22 @@
     SortedVector < sp<OutputTrack> >  mOutputTracks;
 public:
     virtual     bool        hasFastMixer() const { return false; }
+                status_t    threadloop_getHalTimestamp_l(
+                                    ExtendedTimestamp *timestamp) const override {
+        if (mOutputTracks.size() > 0) {
+            // forward the first OutputTrack's kernel information for timestamp.
+            const ExtendedTimestamp trackTimestamp =
+                    mOutputTracks[0]->getClientProxyTimestamp();
+            if (trackTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] > 0) {
+                timestamp->mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] =
+                        trackTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL];
+                timestamp->mPosition[ExtendedTimestamp::LOCATION_KERNEL] =
+                        trackTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL];
+                return OK;  // discard server timestamp - that's ignored.
+            }
+        }
+        return INVALID_OPERATION;
+    }
 };
 
 // record thread
@@ -1374,9 +1518,6 @@
                     audio_devices_t outDevice,
                     audio_devices_t inDevice,
                     bool systemReady
-#ifdef TEE_SINK
-                    , const sp<NBAIO_Sink>& teeSink
-#endif
                     );
             virtual     ~RecordThread();
 
@@ -1384,9 +1525,6 @@
     void        destroyTrack_l(const sp<RecordTrack>& track);
     void        removeTrack_l(const sp<RecordTrack>& track);
 
-    void        dumpInternals(int fd, const Vector<String16>& args);
-    void        dumpTracks(int fd, const Vector<String16>& args);
-
     // Thread virtuals
     virtual bool        threadLoop();
     virtual void        preExit();
@@ -1409,6 +1547,7 @@
                     size_t *pFrameCount,
                     audio_session_t sessionId,
                     size_t *pNotificationFrameCount,
+                    pid_t creatorPid,
                     uid_t uid,
                     audio_input_flags_t *flags,
                     pid_t tid,
@@ -1424,7 +1563,6 @@
             // return true if the caller should then do it's part of the stopping process
             bool        stop(RecordTrack* recordTrack);
 
-            void        dump(int fd, const Vector<String16>& args);
             AudioStreamIn* clearInput();
             virtual sp<StreamHalInterface> stream() const;
 
@@ -1433,20 +1571,23 @@
                                                status_t& status);
     virtual void        cacheParameters_l() {}
     virtual String8     getParameters(const String8& keys);
-    virtual void        ioConfigChanged(audio_io_config_event event, pid_t pid = 0);
+    virtual void        ioConfigChanged(audio_io_config_event event, pid_t pid = 0,
+                                        audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
     virtual status_t    createAudioPatch_l(const struct audio_patch *patch,
                                            audio_patch_handle_t *handle);
     virtual status_t    releaseAudioPatch_l(const audio_patch_handle_t handle);
 
-            void        addPatchRecord(const sp<PatchRecord>& record);
-            void        deletePatchRecord(const sp<PatchRecord>& record);
+            void        addPatchTrack(const sp<PatchRecord>& record);
+            void        deletePatchTrack(const sp<PatchRecord>& record);
 
             void        readInputParameters_l();
     virtual uint32_t    getInputFramesLost();
 
     virtual status_t addEffectChain_l(const sp<EffectChain>& chain);
     virtual size_t removeEffectChain_l(const sp<EffectChain>& chain);
-    virtual uint32_t hasAudioSession_l(audio_session_t sessionId) const;
+            uint32_t hasAudioSession_l(audio_session_t sessionId) const override {
+                         return ThreadBase::hasAudioSession_l(sessionId, mTracks);
+                     }
 
             // Return the set of unique session IDs across all tracks.
             // The keys are the session IDs, and the associated values are meaningless.
@@ -1460,7 +1601,7 @@
 
     virtual size_t      frameCount() const { return mFrameCount; }
             bool        hasFastCapture() const { return mFastCapture != 0; }
-    virtual void        getAudioPortConfig(struct audio_port_config *config);
+    virtual void        toAudioPortConfig(struct audio_port_config *config);
 
     virtual status_t    checkEffectCompatibility_l(const effect_descriptor_t *desc,
                                                    audio_session_t sessionId);
@@ -1478,8 +1619,23 @@
 
             status_t    getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones);
 
+            status_t    setPreferredMicrophoneDirection(audio_microphone_direction_t direction);
+            status_t    setPreferredMicrophoneFieldDimension(float zoom);
+
             void        updateMetadata_l() override;
 
+            bool        fastTrackAvailable() const { return mFastTrackAvail; }
+
+            bool        isTimestampCorrectionEnabled() const override {
+                            // checks popcount for exactly one device.
+                            return audio_is_input_device(
+                                    mInDevice & mTimestampCorrectedDevices);
+                        }
+
+protected:
+            void        dumpInternals_l(int fd, const Vector<String16>& args) override;
+            void        dumpTracks_l(int fd, const Vector<String16>& args) override;
+
 private:
             // Enter standby if not already in standby, and set mStandby flag
             void    standbyIfNotAlreadyInStandby();
@@ -1507,8 +1663,6 @@
             int32_t                             mRsmpInRear;    // last filled frame + 1
 
             // For dumpsys
-            const sp<NBAIO_Sink>                mTeeSink;
-
             const sp<MemoryDealer>              mReadOnlyHeap;
 
             // one-time initialization, no locks required
@@ -1551,6 +1705,8 @@
             bool                                mFastTrackAvail;    // true if fast track available
             // common state to all record threads
             std::atomic_bool                    mBtNrecSuspended;
+
+            int64_t                             mFramesRead = 0;    // continuous running counter.
 };
 
 class MmapThread : public ThreadBase
@@ -1597,13 +1753,14 @@
     virtual     bool        checkForNewParameter_l(const String8& keyValuePair,
                                                     status_t& status);
     virtual     String8     getParameters(const String8& keys);
-    virtual     void        ioConfigChanged(audio_io_config_event event, pid_t pid = 0);
+    virtual     void        ioConfigChanged(audio_io_config_event event, pid_t pid = 0,
+                                            audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
                 void        readHalParameters_l();
     virtual     void        cacheParameters_l() {}
     virtual     status_t    createAudioPatch_l(const struct audio_patch *patch,
                                                audio_patch_handle_t *handle);
     virtual     status_t    releaseAudioPatch_l(const audio_patch_handle_t handle);
-    virtual     void        getAudioPortConfig(struct audio_port_config *config);
+    virtual     void        toAudioPortConfig(struct audio_port_config *config);
 
     virtual     sp<StreamHalInterface> stream() const { return mHalStream; }
     virtual     status_t    addEffectChain_l(const sp<EffectChain>& chain);
@@ -1611,7 +1768,10 @@
     virtual     status_t    checkEffectCompatibility_l(const effect_descriptor_t *desc,
                                                                audio_session_t sessionId);
 
-    virtual     uint32_t    hasAudioSession_l(audio_session_t sessionId) const;
+                uint32_t    hasAudioSession_l(audio_session_t sessionId) const override {
+                                // Note: using mActiveTracks as no mTracks here.
+                                return ThreadBase::hasAudioSession_l(sessionId, mActiveTracks);
+                            }
     virtual     status_t    setSyncEvent(const sp<SyncEvent>& event);
     virtual     bool        isValidSyncEvent(const sp<SyncEvent>& event) const;
 
@@ -1626,15 +1786,12 @@
                 // Sets the UID records silence
     virtual     void        setRecordSilenced(uid_t uid __unused, bool silenced __unused) {}
 
-                void        dump(int fd, const Vector<String16>& args);
-    virtual     void        dumpInternals(int fd, const Vector<String16>& args);
-                void        dumpTracks(int fd, const Vector<String16>& args);
-
  protected:
+                void        dumpInternals_l(int fd, const Vector<String16>& args) override;
+                void        dumpTracks_l(int fd, const Vector<String16>& args) override;
 
                 audio_attributes_t      mAttr;
                 audio_session_t         mSessionId;
-                audio_port_handle_t     mDeviceId;
                 audio_port_handle_t     mPortId;
 
                 wp<MmapStreamCallback>  mCallback;
@@ -1681,13 +1838,14 @@
     virtual     void        checkSilentMode_l();
                 void        processVolume_l() override;
 
-    virtual     void        dumpInternals(int fd, const Vector<String16>& args);
-
     virtual     bool        isOutput() const override { return true; }
 
                 void        updateMetadata_l() override;
 
+    virtual     void        toAudioPortConfig(struct audio_port_config *config);
+
 protected:
+                void        dumpInternals_l(int fd, const Vector<String16>& args) override;
 
                 audio_stream_type_t         mStreamType;
                 float                       mMasterVolume;
@@ -1715,6 +1873,8 @@
                 void           processVolume_l() override;
                 void           setRecordSilenced(uid_t uid, bool silenced) override;
 
+    virtual     void           toAudioPortConfig(struct audio_port_config *config);
+
 protected:
 
                 AudioStreamIn*  mInput;
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index 3b8369f..65589e2 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -25,13 +25,13 @@
 public:
     enum track_state {
         IDLE,
-        FLUSHED,
+        FLUSHED,        // for PlaybackTracks only
         STOPPED,
         // next 2 states are currently used for fast tracks
         // and offloaded tracks only
         STOPPING_1,     // waiting for first underrun
         STOPPING_2,     // waiting for presentation complete
-        RESUMING,
+        RESUMING,       // for PlaybackTracks only
         ACTIVE,
         PAUSING,
         PAUSED,
@@ -54,11 +54,6 @@
         TYPE_PATCH,
     };
 
-    enum {
-        TRACK_NAME_PENDING = -1,
-        TRACK_NAME_FAILURE = -2,
-    };
-
                         TrackBase(ThreadBase *thread,
                                 const sp<Client>& client,
                                 const audio_attributes_t& mAttr,
@@ -69,6 +64,7 @@
                                 void *buffer,
                                 size_t bufferSize,
                                 audio_session_t sessionId,
+                                pid_t creatorPid,
                                 uid_t uid,
                                 bool isOut,
                                 alloc_type alloc = ALLOC_CBLK,
@@ -84,6 +80,8 @@
             audio_track_cblk_t* cblk() const { return mCblk; }
             audio_session_t sessionId() const { return mSessionId; }
             uid_t       uid() const { return mUid; }
+            pid_t       creatorPid() const { return mCreatorPid; }
+
             audio_port_handle_t portId() const { return mPortId; }
     virtual status_t    setSyncEvent(const sp<SyncEvent>& event);
 
@@ -91,6 +89,7 @@
             void*       buffer() const { return mBuffer; }
             size_t      bufferSize() const { return mBufferSize; }
     virtual bool        isFastTrack() const = 0;
+    virtual bool        isDirect() const = 0;
             bool        isOutputTrack() const { return (mType == TYPE_OUTPUT); }
             bool        isPatchTrack() const { return (mType == TYPE_PATCH); }
             bool        isExternalTrack() const { return !isOutputTrack() && !isPatchTrack(); }
@@ -98,8 +97,111 @@
     virtual void        invalidate() { mIsInvalid = true; }
             bool        isInvalid() const { return mIsInvalid; }
 
+            void        terminate() { mTerminated = true; }
+            bool        isTerminated() const { return mTerminated; }
+
     audio_attributes_t  attributes() const { return mAttr; }
 
+#ifdef TEE_SINK
+           void         dumpTee(int fd, const std::string &reason) const {
+                                mTee.dump(fd, reason);
+                        }
+#endif
+
+            /** returns the buffer contents size converted to time in milliseconds
+             * for PCM Playback or Record streaming tracks. The return value is zero for
+             * PCM static tracks and not defined for non-PCM tracks.
+             *
+             * This may be called without the thread lock.
+             */
+    virtual double      bufferLatencyMs() const {
+                            return mServerProxy->framesReadySafe() * 1000 / sampleRate();
+                        }
+
+            /** returns whether the track supports server latency computation.
+             * This is set in the constructor and constant throughout the track lifetime.
+             */
+
+            bool        isServerLatencySupported() const { return mServerLatencySupported; }
+
+            /** computes the server latency for PCM Playback or Record track
+             * to the device sink/source.  This is the time for the next frame in the track buffer
+             * written or read from the server thread to the device source or sink.
+             *
+             * This may be called without the thread lock, but latencyMs and fromTrack
+             * may be not be synchronized. For example PatchPanel may not obtain the
+             * thread lock before calling.
+             *
+             * \param latencyMs on success is set to the latency in milliseconds of the
+             *        next frame written/read by the server thread to/from the track buffer
+             *        from the device source/sink.
+             * \param fromTrack on success is set to true if latency was computed directly
+             *        from the track timestamp; otherwise set to false if latency was
+             *        estimated from the server timestamp.
+             *        fromTrack may be nullptr or omitted if not required.
+             *
+             * \returns OK or INVALID_OPERATION on failure.
+             */
+            status_t    getServerLatencyMs(double *latencyMs, bool *fromTrack = nullptr) const {
+                            if (!isServerLatencySupported()) {
+                                return INVALID_OPERATION;
+                            }
+
+                            // if no thread lock is acquired, these atomics are not
+                            // synchronized with each other, considered a benign race.
+
+                            const double serverLatencyMs = mServerLatencyMs.load();
+                            if (serverLatencyMs == 0.) {
+                                return INVALID_OPERATION;
+                            }
+                            if (fromTrack != nullptr) {
+                                *fromTrack = mServerLatencyFromTrack.load();
+                            }
+                            *latencyMs = serverLatencyMs;
+                            return OK;
+                        }
+
+            /** computes the total client latency for PCM Playback or Record tracks
+             * for the next client app access to the device sink/source; i.e. the
+             * server latency plus the buffer latency.
+             *
+             * This may be called without the thread lock, but latencyMs and fromTrack
+             * may be not be synchronized. For example PatchPanel may not obtain the
+             * thread lock before calling.
+             *
+             * \param latencyMs on success is set to the latency in milliseconds of the
+             *        next frame written/read by the client app to/from the track buffer
+             *        from the device sink/source.
+             * \param fromTrack on success is set to true if latency was computed directly
+             *        from the track timestamp; otherwise set to false if latency was
+             *        estimated from the server timestamp.
+             *        fromTrack may be nullptr or omitted if not required.
+             *
+             * \returns OK or INVALID_OPERATION on failure.
+             */
+            status_t    getTrackLatencyMs(double *latencyMs, bool *fromTrack = nullptr) const {
+                            double serverLatencyMs;
+                            status_t status = getServerLatencyMs(&serverLatencyMs, fromTrack);
+                            if (status == OK) {
+                                *latencyMs = serverLatencyMs + bufferLatencyMs();
+                            }
+                            return status;
+                        }
+
+           // TODO: Consider making this external.
+           struct FrameTime {
+               int64_t frames;
+               int64_t timeNs;
+           };
+
+           // KernelFrameTime is updated per "mix" period even for non-pcm tracks.
+           void         getKernelFrameTime(FrameTime *ft) const {
+                           *ft = mKernelFrameTime.load();
+                        }
+
+           audio_format_t format() const { return mFormat; }
+           int id() const { return mId; }
+
 protected:
     DISALLOW_COPY_AND_ASSIGN(TrackBase);
 
@@ -111,8 +213,6 @@
     // but putting it in TrackBase avoids the complexity of virtual inheritance
     virtual size_t  framesReady() const { return SIZE_MAX; }
 
-    audio_format_t format() const { return mFormat; }
-
     uint32_t channelCount() const { return mChannelCount; }
 
     size_t frameSize() const { return mFrameSize; }
@@ -136,14 +236,6 @@
         return mState == STOPPING_2;
     }
 
-    bool isTerminated() const {
-        return mTerminated;
-    }
-
-    void terminate() {
-        mTerminated = true;
-    }
-
     // Upper case characters are final states.
     // Lower case characters are transitory.
     const char *getTrackStateString() const {
@@ -210,13 +302,21 @@
     const bool          mIsOut;
     sp<ServerProxy>     mServerProxy;
     const int           mId;
-    sp<NBAIO_Sink>      mTeeSink;
-    sp<NBAIO_Source>    mTeeSource;
+#ifdef TEE_SINK
+    NBAIO_Tee           mTee;
+#endif
     bool                mTerminated;
     track_type          mType;      // must be one of TYPE_DEFAULT, TYPE_OUTPUT, TYPE_PATCH ...
     audio_io_handle_t   mThreadIoHandle; // I/O handle of the thread the track is attached to
     audio_port_handle_t mPortId; // unique ID for this track used by audio policy
     bool                mIsInvalid; // non-resettable latch, set by invalidate()
+
+    bool                mServerLatencySupported = false;
+    std::atomic<bool>   mServerLatencyFromTrack{}; // latency from track or server timestamp.
+    std::atomic<double> mServerLatencyMs{};        // last latency pushed from server thread.
+    std::atomic<FrameTime> mKernelFrameTime{};     // last frame time on kernel side.
+    const pid_t         mCreatorPid;  // can be different from mclient->pid() for instance
+                                      // when created by NuPlayer on behalf of a client
 };
 
 // PatchProxyBufferProvider interface is implemented by PatchTrack and PatchRecord.
@@ -231,3 +331,28 @@
                                      const struct timespec *requested = NULL) = 0;
     virtual void        releaseBuffer(Proxy::Buffer* buffer) = 0;
 };
+
+class PatchTrackBase : public PatchProxyBufferProvider
+{
+public:
+    using Timeout = std::optional<std::chrono::nanoseconds>;
+                        PatchTrackBase(sp<ClientProxy> proxy, const ThreadBase& thread,
+                                       const Timeout& timeout);
+            void        setPeerTimeout(std::chrono::nanoseconds timeout);
+            template <typename T>
+            void        setPeerProxy(const sp<T> &proxy, bool holdReference) {
+                            mPeerReferenceHold = holdReference ? proxy : nullptr;
+                            mPeerProxy = proxy.get();
+                        }
+            void        clearPeerProxy() {
+                            mPeerReferenceHold.clear();
+                            mPeerProxy = nullptr;
+                        }
+
+protected:
+    const sp<ClientProxy>       mProxy;
+    sp<RefBase>                 mPeerReferenceHold;   // keeps mPeerProxy alive during access.
+    PatchProxyBufferProvider*   mPeerProxy = nullptr;
+    struct timespec             mPeerTimeout{};
+
+};
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index de15e4b..2a5a713 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -28,11 +28,11 @@
 #include <private/media/AudioTrackShared.h>
 
 #include "AudioFlinger.h"
-#include "ServiceUtilities.h"
 
 #include <media/nbaio/Pipe.h>
 #include <media/nbaio/PipeReader.h>
 #include <media/RecordBufferConverter.h>
+#include <mediautils/ServiceUtilities.h>
 #include <audio_utils/minifloat.h>
 
 // ----------------------------------------------------------------------------
@@ -56,6 +56,8 @@
 // ----------------------------------------------------------------------------
 //      TrackBase
 // ----------------------------------------------------------------------------
+#undef LOG_TAG
+#define LOG_TAG "AF::TrackBase"
 
 static volatile int32_t nextTrackId = 55;
 
@@ -71,6 +73,7 @@
             void *buffer,
             size_t bufferSize,
             audio_session_t sessionId,
+            pid_t creatorPid,
             uid_t clientUid,
             bool isOut,
             alloc_type alloc,
@@ -97,14 +100,16 @@
         mId(android_atomic_inc(&nextTrackId)),
         mTerminated(false),
         mType(type),
-        mThreadIoHandle(thread->id()),
+        mThreadIoHandle(thread ? thread->id() : AUDIO_IO_HANDLE_NONE),
         mPortId(portId),
-        mIsInvalid(false)
+        mIsInvalid(false),
+        mCreatorPid(creatorPid)
 {
     const uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    if (!isTrustedCallingUid(callingUid) || clientUid == AUDIO_UID_INVALID) {
+    if (!isAudioServerOrMediaServerUid(callingUid) || clientUid == AUDIO_UID_INVALID) {
         ALOGW_IF(clientUid != AUDIO_UID_INVALID && clientUid != callingUid,
-                "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, clientUid);
+                "%s(%d): uid %d tried to pass itself off as %d",
+                 __func__, mId, callingUid, clientUid);
         clientUid = callingUid;
     }
     // clientUid contains the uid of the app that is responsible for this track, so we can blame
@@ -144,7 +149,7 @@
         mCblkMemory = client->heap()->allocate(size);
         if (mCblkMemory == 0 ||
                 (mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer())) == NULL) {
-            ALOGE("not enough memory for AudioTrack size=%zu", size);
+            ALOGE("%s(%d): not enough memory for AudioTrack size=%zu", __func__, mId, size);
             client->heap()->dump("AudioTrack");
             mCblkMemory.clear();
             return;
@@ -152,7 +157,7 @@
     } else {
         mCblk = (audio_track_cblk_t *) malloc(size);
         if (mCblk == NULL) {
-            ALOGE("not enough memory for AudioTrack size=%zu", size);
+            ALOGE("%s(%d): not enough memory for AudioTrack size=%zu", __func__, mId, size);
             return;
         }
     }
@@ -166,7 +171,8 @@
             if (roHeap == 0 ||
                     (mBufferMemory = roHeap->allocate(bufferSize)) == 0 ||
                     (mBuffer = mBufferMemory->pointer()) == NULL) {
-                ALOGE("not enough memory for read-only buffer size=%zu", bufferSize);
+                ALOGE("%s(%d): not enough memory for read-only buffer size=%zu",
+                        __func__, mId, bufferSize);
                 if (roHeap != 0) {
                     roHeap->dump("buffer");
                 }
@@ -205,27 +211,12 @@
             mBuffer = buffer;
             break;
         default:
-            LOG_ALWAYS_FATAL("invalid allocation type: %d", (int)alloc);
+            LOG_ALWAYS_FATAL("%s(%d): invalid allocation type: %d", __func__, mId, (int)alloc);
         }
         mBufferSize = bufferSize;
 
 #ifdef TEE_SINK
-        if (mTeeSinkTrackEnabled) {
-            NBAIO_Format pipeFormat = Format_from_SR_C(mSampleRate, mChannelCount, mFormat);
-            if (Format_isValid(pipeFormat)) {
-                Pipe *pipe = new Pipe(mTeeSinkTrackFrames, pipeFormat);
-                size_t numCounterOffers = 0;
-                const NBAIO_Format offers[1] = {pipeFormat};
-                ssize_t index = pipe->negotiate(offers, 1, NULL, numCounterOffers);
-                ALOG_ASSERT(index == 0);
-                PipeReader *pipeReader = new PipeReader(*pipe);
-                numCounterOffers = 0;
-                index = pipeReader->negotiate(offers, 1, NULL, numCounterOffers);
-                ALOG_ASSERT(index == 0);
-                mTeeSink = pipe;
-                mTeeSource = pipeReader;
-            }
-        }
+        mTee.set(sampleRate, mChannelCount, format, NBAIO_Tee::TEE_FLAG_TRACK);
 #endif
 
     }
@@ -244,9 +235,6 @@
 
 AudioFlinger::ThreadBase::TrackBase::~TrackBase()
 {
-#ifdef TEE_SINK
-    dumpTee(-1, mTeeSource, mId, 'T');
-#endif
     // delete the proxy before deleting the shared memory it refers to, to avoid dangling reference
     mServerProxy.clear();
     if (mCblk != NULL) {
@@ -274,9 +262,7 @@
 void AudioFlinger::ThreadBase::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
 {
 #ifdef TEE_SINK
-    if (mTeeSink != 0) {
-        (void) mTeeSink->write(buffer->raw, buffer->frameCount);
-    }
+    mTee.write(buffer->raw, buffer->frameCount);
 #endif
 
     ServerProxy::Buffer buf;
@@ -293,9 +279,32 @@
     return NO_ERROR;
 }
 
+AudioFlinger::ThreadBase::PatchTrackBase::PatchTrackBase(sp<ClientProxy> proxy,
+                                                         const ThreadBase& thread,
+                                                         const Timeout& timeout)
+    : mProxy(proxy)
+{
+    if (timeout) {
+        setPeerTimeout(*timeout);
+    } else {
+        // Double buffer mixer
+        uint64_t mixBufferNs = ((uint64_t)2 * thread.frameCount() * 1000000000) /
+                                              thread.sampleRate();
+        setPeerTimeout(std::chrono::nanoseconds{mixBufferNs});
+    }
+}
+
+void AudioFlinger::ThreadBase::PatchTrackBase::setPeerTimeout(std::chrono::nanoseconds timeout) {
+    mPeerTimeout.tv_sec = timeout.count() / std::nano::den;
+    mPeerTimeout.tv_nsec = timeout.count() % std::nano::den;
+}
+
+
 // ----------------------------------------------------------------------------
 //      Playback
 // ----------------------------------------------------------------------------
+#undef LOG_TAG
+#define LOG_TAG "AF::TrackHandle"
 
 AudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::PlaybackThread::Track>& track)
     : BnAudioTrack(),
@@ -340,6 +349,10 @@
     return mTrack->setParameters(keyValuePairs);
 }
 
+status_t AudioFlinger::TrackHandle::selectPresentation(int presentationId, int programId) {
+    return mTrack->selectPresentation(presentationId, programId);
+}
+
 VolumeShaper::Status AudioFlinger::TrackHandle::applyVolumeShaper(
         const sp<VolumeShaper::Configuration>& configuration,
         const sp<VolumeShaper::Operation>& operation) {
@@ -368,6 +381,117 @@
 }
 
 // ----------------------------------------------------------------------------
+//      AppOp for audio playback
+// -------------------------------
+
+// static
+sp<AudioFlinger::PlaybackThread::OpPlayAudioMonitor>
+AudioFlinger::PlaybackThread::OpPlayAudioMonitor::createIfNeeded(
+            uid_t uid, const audio_attributes_t& attr, int id, audio_stream_type_t streamType)
+{
+    if (isServiceUid(uid)) {
+        Vector <String16> packages;
+        getPackagesForUid(uid, packages);
+        if (packages.isEmpty()) {
+            ALOGD("OpPlayAudio: not muting track:%d usage:%d for service UID %d",
+                  id,
+                  attr.usage,
+                  uid);
+            return nullptr;
+        }
+    }
+    // stream type has been filtered by audio policy to indicate whether it can be muted
+    if (streamType == AUDIO_STREAM_ENFORCED_AUDIBLE) {
+        ALOGD("OpPlayAudio: not muting track:%d usage:%d ENFORCED_AUDIBLE", id, attr.usage);
+        return nullptr;
+    }
+    if ((attr.flags & AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY)
+            == AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY) {
+        ALOGD("OpPlayAudio: not muting track:%d flags %#x have FLAG_BYPASS_INTERRUPTION_POLICY",
+            id, attr.flags);
+        return nullptr;
+    }
+    return new OpPlayAudioMonitor(uid, attr.usage, id);
+}
+
+AudioFlinger::PlaybackThread::OpPlayAudioMonitor::OpPlayAudioMonitor(
+        uid_t uid, audio_usage_t usage, int id)
+        : mHasOpPlayAudio(true), mUid(uid), mUsage((int32_t) usage), mId(id)
+{
+}
+
+AudioFlinger::PlaybackThread::OpPlayAudioMonitor::~OpPlayAudioMonitor()
+{
+    if (mOpCallback != 0) {
+        mAppOpsManager.stopWatchingMode(mOpCallback);
+    }
+    mOpCallback.clear();
+}
+
+void AudioFlinger::PlaybackThread::OpPlayAudioMonitor::onFirstRef()
+{
+    getPackagesForUid(mUid, mPackages);
+    checkPlayAudioForUsage();
+    if (!mPackages.isEmpty()) {
+        mOpCallback = new PlayAudioOpCallback(this);
+        mAppOpsManager.startWatchingMode(AppOpsManager::OP_PLAY_AUDIO, mPackages[0], mOpCallback);
+    }
+}
+
+bool AudioFlinger::PlaybackThread::OpPlayAudioMonitor::hasOpPlayAudio() const {
+    return mHasOpPlayAudio.load();
+}
+
+// Note this method is never called (and never to be) for audio server / patch record track
+// - not called from constructor due to check on UID,
+// - not called from PlayAudioOpCallback because the callback is not installed in this case
+void AudioFlinger::PlaybackThread::OpPlayAudioMonitor::checkPlayAudioForUsage()
+{
+    if (mPackages.isEmpty()) {
+        mHasOpPlayAudio.store(false);
+    } else {
+        bool hasIt = true;
+        for (const String16& packageName : mPackages) {
+            const int32_t mode = mAppOpsManager.checkAudioOpNoThrow(AppOpsManager::OP_PLAY_AUDIO,
+                    mUsage, mUid, packageName);
+            if (mode != AppOpsManager::MODE_ALLOWED) {
+                hasIt = false;
+                break;
+            }
+        }
+        ALOGD("OpPlayAudio: track:%d usage:%d %smuted", mId, mUsage, hasIt ? "not " : "");
+        mHasOpPlayAudio.store(hasIt);
+    }
+}
+
+AudioFlinger::PlaybackThread::OpPlayAudioMonitor::PlayAudioOpCallback::PlayAudioOpCallback(
+        const wp<OpPlayAudioMonitor>& monitor) : mMonitor(monitor)
+{ }
+
+void AudioFlinger::PlaybackThread::OpPlayAudioMonitor::PlayAudioOpCallback::opChanged(int32_t op,
+            const String16& packageName) {
+    // we only have uid, so we need to check all package names anyway
+    UNUSED(packageName);
+    if (op != AppOpsManager::OP_PLAY_AUDIO) {
+        return;
+    }
+    sp<OpPlayAudioMonitor> monitor = mMonitor.promote();
+    if (monitor != NULL) {
+        monitor->checkPlayAudioForUsage();
+    }
+}
+
+// static
+void AudioFlinger::PlaybackThread::OpPlayAudioMonitor::getPackagesForUid(
+    uid_t uid, Vector<String16>& packages)
+{
+    PermissionController permissionController;
+    permissionController.getPackagesForUid(uid, packages);
+}
+
+// ----------------------------------------------------------------------------
+#undef LOG_TAG
+#define LOG_TAG "AF::Track"
 
 // Track constructor must be called with AudioFlinger::mLock and ThreadBase::mLock held
 AudioFlinger::PlaybackThread::Track::Track(
@@ -383,6 +507,7 @@
             size_t bufferSize,
             const sp<IMemory>& sharedBuffer,
             audio_session_t sessionId,
+            pid_t creatorPid,
             uid_t uid,
             audio_output_flags_t flags,
             track_type type,
@@ -390,20 +515,20 @@
     :   TrackBase(thread, client, attr, sampleRate, format, channelMask, frameCount,
                   (sharedBuffer != 0) ? sharedBuffer->pointer() : buffer,
                   (sharedBuffer != 0) ? sharedBuffer->size() : bufferSize,
-                  sessionId, uid, true /*isOut*/,
+                  sessionId, creatorPid, uid, true /*isOut*/,
                   (type == TYPE_PATCH) ? ( buffer == NULL ? ALLOC_LOCAL : ALLOC_NONE) : ALLOC_CBLK,
                   type, portId),
     mFillingUpStatus(FS_INVALID),
     // mRetryCount initialized later when needed
     mSharedBuffer(sharedBuffer),
     mStreamType(streamType),
-    mName(TRACK_NAME_FAILURE),  // set to TRACK_NAME_PENDING on constructor success.
     mMainBuffer(thread->sinkBuffer()),
     mAuxBuffer(NULL),
     mAuxEffectId(0), mHasVolumeController(false),
     mPresentationCompleteFrames(0),
     mFrameMap(16 /* sink-frame-to-track-frame map memory */),
     mVolumeHandler(new media::VolumeHandler(sampleRate)),
+    mOpPlayAudioMonitor(OpPlayAudioMonitor::createIfNeeded(uid, attr, id(), streamType)),
     // mSinkTimestamp
     mFastIndex(-1),
     mCachedVolume(1.0),
@@ -417,8 +542,8 @@
     // client == 0 implies sharedBuffer == 0
     ALOG_ASSERT(!(client == 0 && sharedBuffer != 0));
 
-    ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %zu", sharedBuffer->pointer(),
-            sharedBuffer->size());
+    ALOGV_IF(sharedBuffer != 0, "%s(%d): sharedBuffer: %p, size: %zu",
+            __func__, mId, sharedBuffer->pointer(), sharedBuffer->size());
 
     if (mCblk == NULL) {
         return;
@@ -434,7 +559,7 @@
     mServerProxy = mAudioTrackServerProxy;
 
     if (!thread->isTrackAllowed_l(channelMask, format, sessionId, uid)) {
-        ALOGE("no more tracks available");
+        ALOGE("%s(%d): no more tracks available", __func__, mId);
         return;
     }
     // only allocate a fast track index if we were able to allocate a normal track name
@@ -453,12 +578,24 @@
         mFastIndex = i;
         thread->mFastTrackAvailMask &= ~(1 << i);
     }
-    mName = TRACK_NAME_PENDING;
+
+    mServerLatencySupported = thread->type() == ThreadBase::MIXER
+            || thread->type() == ThreadBase::DUPLICATING;
+#ifdef TEE_SINK
+    mTee.setId(std::string("_") + std::to_string(mThreadIoHandle)
+            + "_" + std::to_string(mId) + "_T");
+#endif
+
+    if (channelMask & AUDIO_CHANNEL_HAPTIC_ALL) {
+        mAudioVibrationController = new AudioVibrationController(this);
+        mExternalVibration = new os::ExternalVibration(
+                mUid, "" /* pkg */, mAttr, mAudioVibrationController);
+    }
 }
 
 AudioFlinger::PlaybackThread::Track::~Track()
 {
-    ALOGV("PlaybackThread::Track destructor");
+    ALOGV("%s(%d)", __func__, mId);
 
     // The destructor would clear mSharedBuffer,
     // but it will not push the decremented reference count,
@@ -472,7 +609,7 @@
 status_t AudioFlinger::PlaybackThread::Track::initCheck() const
 {
     status_t status = TrackBase::initCheck();
-    if (status == NO_ERROR && mName == TRACK_NAME_FAILURE) {
+    if (status == NO_ERROR && mCblk == nullptr) {
         status = NO_MEMORY;
     }
     return status;
@@ -498,18 +635,21 @@
             wasActive = playbackThread->destroyTrack_l(this);
         }
         if (isExternalTrack() && !wasActive) {
-            AudioSystem::releaseOutput(mThreadIoHandle, mStreamType, mSessionId);
+            AudioSystem::releaseOutput(mPortId);
         }
     }
+    forEachTeePatchTrack([](auto patchTrack) { patchTrack->destroy(); });
 }
 
-/*static*/ void AudioFlinger::PlaybackThread::Track::appendDumpHeader(String8& result)
+void AudioFlinger::PlaybackThread::Track::appendDumpHeader(String8& result)
 {
-    result.append("T Name Active Client Session S  Flags "
-                  "  Format Chn mask  SRate "
-                  "ST  L dB  R dB  VS dB "
-                  "  Server FrmCnt  FrmRdy F Underruns  Flushed "
-                  "Main Buf  Aux Buf\n");
+    result.appendFormat("Type     Id Active Client Session Port Id S  Flags "
+                        "  Format Chn mask  SRate "
+                        "ST Usg CT "
+                        " G db  L dB  R dB  VS dB "
+                        "  Server FrmCnt  FrmRdy F Underruns  Flushed"
+                        "%s\n",
+                        isServerLatencySupported() ? "   Latency" : "");
 }
 
 void AudioFlinger::PlaybackThread::Track::appendDump(String8& result, bool active)
@@ -518,7 +658,7 @@
     switch (mType) {
     case TYPE_DEFAULT:
     case TYPE_OUTPUT:
-        if (mSharedBuffer.get() != nullptr) {
+        if (isStatic()) {
             trackType = 'S'; // static
         } else {
             trackType = ' '; // normal
@@ -532,13 +672,9 @@
     }
 
     if (isFastTrack()) {
-        result.appendFormat("F%c %3d", trackType, mFastIndex);
-    } else if (mName == TRACK_NAME_PENDING) {
-        result.appendFormat("%c pend", trackType);
-    } else if (mName == TRACK_NAME_FAILURE) {
-        result.appendFormat("%c fail", trackType);
+        result.appendFormat("F%d %c %6d", mFastIndex, trackType, mId);
     } else {
-        result.appendFormat("%c %4d", trackType, mName);
+        result.appendFormat("   %c %6d", trackType, mId);
     }
 
     char nowInUnderrun;
@@ -593,22 +729,27 @@
             ? 'r' /* buffer reduced */: bufferSizeInFrames > mFrameCount
                     ? 'e' /* error */ : ' ' /* identical */;
 
-    result.appendFormat("%7s %6u %7u %2s 0x%03X "
-                           "%08X %08X %6u "
-                           "%2u %5.2g %5.2g %5.2g%c "
-                           "%08X %6zu%c %6zu %c %9u%c %7u "
-                           "%08zX %08zX\n",
+    result.appendFormat("%7s %6u %7u %7u %2s 0x%03X "
+                        "%08X %08X %6u "
+                        "%2u %3x %2x "
+                        "%5.2g %5.2g %5.2g %5.2g%c "
+                        "%08X %6zu%c %6zu %c %9u%c %7u",
             active ? "yes" : "no",
-            (mClient == 0) ? getpid_cached : mClient->pid(),
+            (mClient == 0) ? getpid() : mClient->pid(),
             mSessionId,
+            mPortId,
             getTrackStateString(),
             mCblk->mFlags,
 
             mFormat,
             mChannelMask,
-            mAudioTrackServerProxy->getSampleRate(),
+            sampleRate(),
 
             mStreamType,
+            mAttr.usage,
+            mAttr.content_type,
+
+            20.0 * log10(mFinalVolume),
             20.0 * log10(float_from_gain(gain_minifloat_unpack_left(vlr))),
             20.0 * log10(float_from_gain(gain_minifloat_unpack_right(vlr))),
             20.0 * log10(vsVolume.first), // VolumeShaper(s) total volume
@@ -621,11 +762,21 @@
             fillingStatus,
             mAudioTrackServerProxy->getUnderrunFrames(),
             nowInUnderrun,
-            (unsigned)mAudioTrackServerProxy->framesFlushed() % 10000000,
-
-            (size_t)mMainBuffer, // use %zX as %p appends 0x
-            (size_t)mAuxBuffer   // use %zX as %p appends 0x
+            (unsigned)mAudioTrackServerProxy->framesFlushed() % 10000000
             );
+
+    if (isServerLatencySupported()) {
+        double latencyMs;
+        bool fromTrack;
+        if (getTrackLatencyMs(&latencyMs, &fromTrack) == OK) {
+            // Show latency in msec, followed by 't' if from track timestamp (the most accurate)
+            // or 'k' if estimated from kernel because track frames haven't been presented yet.
+            result.appendFormat(" %7.2lf %c", latencyMs, fromTrack ? 't' : 'k');
+        } else {
+            result.appendFormat("%10s", mCblk->mServer != 0 ? "unavail" : "new");
+        }
+    }
+    result.append("\n");
 }
 
 uint32_t AudioFlinger::PlaybackThread::Track::sampleRate() const {
@@ -633,8 +784,7 @@
 }
 
 // AudioBufferProvider interface
-status_t AudioFlinger::PlaybackThread::Track::getNextBuffer(
-        AudioBufferProvider::Buffer* buffer)
+status_t AudioFlinger::PlaybackThread::Track::getNextBuffer(AudioBufferProvider::Buffer* buffer)
 {
     ServerProxy::Buffer buf;
     size_t desiredFrames = buffer->frameCount;
@@ -643,16 +793,72 @@
     buffer->frameCount = buf.mFrameCount;
     buffer->raw = buf.mRaw;
     if (buf.mFrameCount == 0 && !isStopping() && !isStopped() && !isPaused()) {
-        ALOGV("underrun,  framesReady(%zu) < framesDesired(%zd), state: %d",
-                buf.mFrameCount, desiredFrames, mState);
+        ALOGV("%s(%d): underrun,  framesReady(%zu) < framesDesired(%zd), state: %d",
+                __func__, mId, buf.mFrameCount, desiredFrames, mState);
         mAudioTrackServerProxy->tallyUnderrunFrames(desiredFrames);
     } else {
         mAudioTrackServerProxy->tallyUnderrunFrames(0);
     }
-
     return status;
 }
 
+void AudioFlinger::PlaybackThread::Track::releaseBuffer(AudioBufferProvider::Buffer* buffer)
+{
+    interceptBuffer(*buffer);
+    TrackBase::releaseBuffer(buffer);
+}
+
+// TODO: compensate for time shift between HW modules.
+void AudioFlinger::PlaybackThread::Track::interceptBuffer(
+        const AudioBufferProvider::Buffer& sourceBuffer) {
+    auto start = std::chrono::steady_clock::now();
+    const size_t frameCount = sourceBuffer.frameCount;
+    if (frameCount == 0) {
+        return;  // No audio to intercept.
+        // Additionally PatchProxyBufferProvider::obtainBuffer (called by PathTrack::getNextBuffer)
+        // does not allow 0 frame size request contrary to getNextBuffer
+    }
+    for (auto& teePatch : mTeePatches) {
+        RecordThread::PatchRecord* patchRecord = teePatch.patchRecord.get();
+
+        size_t framesWritten = writeFrames(patchRecord, sourceBuffer.i8, frameCount);
+        // On buffer wrap, the buffer frame count will be less than requested,
+        // when this happens a second buffer needs to be used to write the leftover audio
+        size_t framesLeft = frameCount - framesWritten;
+        if (framesWritten != 0 && framesLeft != 0) {
+            framesWritten +=
+                writeFrames(patchRecord, sourceBuffer.i8 + framesWritten * mFrameSize, framesLeft);
+            framesLeft = frameCount - framesWritten;
+        }
+        ALOGW_IF(framesLeft != 0, "%s(%d) PatchRecord %d can not provide big enough "
+                 "buffer %zu/%zu, dropping %zu frames", __func__, mId, patchRecord->mId,
+                 framesWritten, frameCount, framesLeft);
+    }
+    auto spent = ceil<std::chrono::microseconds>(std::chrono::steady_clock::now() - start);
+    using namespace std::chrono_literals;
+    // Average is ~20us per track, this should virtually never be logged (Logging takes >200us)
+    ALOGD_IF(spent > 200us, "%s: took %lldus to intercept %zu tracks", __func__,
+             spent.count(), mTeePatches.size());
+}
+
+size_t AudioFlinger::PlaybackThread::Track::writeFrames(AudioBufferProvider* dest,
+                                                        const void* src,
+                                                        size_t frameCount) {
+    AudioBufferProvider::Buffer patchBuffer;
+    patchBuffer.frameCount = frameCount;
+    auto status = dest->getNextBuffer(&patchBuffer);
+    if (status != NO_ERROR) {
+       ALOGW("%s PathRecord getNextBuffer failed with error %d: %s",
+             __func__, status, strerror(-status));
+       return 0;
+    }
+    ALOG_ASSERT(patchBuffer.frameCount <= frameCount);
+    memcpy(patchBuffer.raw, src, patchBuffer.frameCount * mFrameSize);
+    auto framesWritten = patchBuffer.frameCount;
+    dest->releaseBuffer(&patchBuffer);
+    return framesWritten;
+}
+
 // releaseBuffer() is not overridden
 
 // ExtendedAudioBufferProvider interface
@@ -682,6 +888,13 @@
     mAudioTrackServerProxy->setTimestamp(timestamp);
 
     // We do not set drained here, as FastTrack timestamp may not go to very last frame.
+
+    // Compute latency.
+    // TODO: Consider whether the server latency may be passed in by FastMixer
+    // as a constant for all active FastTracks.
+    const double latencyMs = timestamp.getOutputServerLatencyMs(sampleRate());
+    mServerLatencyFromTrack.store(true);
+    mServerLatencyMs.store(latencyMs);
 }
 
 // Don't call for fast tracks; the framesReady() could result in priority inversion
@@ -710,8 +923,8 @@
                                                     audio_session_t triggerSession __unused)
 {
     status_t status = NO_ERROR;
-    ALOGV("start(%d), calling pid %d session %d",
-            mName, IPCThreadState::self()->getCallingPid(), mSessionId);
+    ALOGV("%s(%d): calling pid %d session %d",
+            __func__, mId, IPCThreadState::self()->getCallingPid(), mSessionId);
 
     sp<ThreadBase> thread = mThread.promote();
     if (thread != 0) {
@@ -737,14 +950,17 @@
             if (mResumeToStopping) {
                 // happened we need to resume to STOPPING_1
                 mState = TrackBase::STOPPING_1;
-                ALOGV("PAUSED => STOPPING_1 (%d) on thread %p", mName, this);
+                ALOGV("%s(%d): PAUSED => STOPPING_1 on thread %d",
+                        __func__, mId, (int)mThreadIoHandle);
             } else {
                 mState = TrackBase::RESUMING;
-                ALOGV("PAUSED => RESUMING (%d) on thread %p", mName, this);
+                ALOGV("%s(%d): PAUSED => RESUMING on thread %d",
+                        __func__,  mId, (int)mThreadIoHandle);
             }
         } else {
             mState = TrackBase::ACTIVE;
-            ALOGV("? => ACTIVE (%d) on thread %p", mName, this);
+            ALOGV("%s(%d): ? => ACTIVE on thread %d",
+                    __func__, mId, (int)mThreadIoHandle);
         }
 
         // states to reset position info for non-offloaded/direct tracks
@@ -790,12 +1006,15 @@
     } else {
         status = BAD_VALUE;
     }
+    if (status == NO_ERROR) {
+        forEachTeePatchTrack([](auto patchTrack) { patchTrack->start(); });
+    }
     return status;
 }
 
 void AudioFlinger::PlaybackThread::Track::stop()
 {
-    ALOGV("stop(%d), calling pid %d", mName, IPCThreadState::self()->getCallingPid());
+    ALOGV("%s(%d): calling pid %d", __func__, mId, IPCThreadState::self()->getCallingPid());
     sp<ThreadBase> thread = mThread.promote();
     if (thread != 0) {
         Mutex::Autolock _l(thread->mLock);
@@ -819,15 +1038,16 @@
                 }
             }
             playbackThread->broadcast_l();
-            ALOGV("not stopping/stopped => stopping/stopped (%d) on thread %p", mName,
-                    playbackThread);
+            ALOGV("%s(%d): not stopping/stopped => stopping/stopped on thread %d",
+                    __func__, mId, (int)mThreadIoHandle);
         }
     }
+    forEachTeePatchTrack([](auto patchTrack) { patchTrack->stop(); });
 }
 
 void AudioFlinger::PlaybackThread::Track::pause()
 {
-    ALOGV("pause(%d), calling pid %d", mName, IPCThreadState::self()->getCallingPid());
+    ALOGV("%s(%d): calling pid %d", __func__, mId, IPCThreadState::self()->getCallingPid());
     sp<ThreadBase> thread = mThread.promote();
     if (thread != 0) {
         Mutex::Autolock _l(thread->mLock);
@@ -842,11 +1062,12 @@
 
             // Offloaded track was draining, we need to carry on draining when resumed
             mResumeToStopping = true;
-            // fall through...
+            FALLTHROUGH_INTENDED;
         case ACTIVE:
         case RESUMING:
             mState = PAUSING;
-            ALOGV("ACTIVE/RESUMING => PAUSING (%d) on thread %p", mName, thread.get());
+            ALOGV("%s(%d): ACTIVE/RESUMING => PAUSING on thread %d",
+                    __func__, mId, (int)mThreadIoHandle);
             playbackThread->broadcast_l();
             break;
 
@@ -854,11 +1075,13 @@
             break;
         }
     }
+    // Pausing the TeePatch to avoid a glitch on underrun, at the cost of buffered audio loss.
+    forEachTeePatchTrack([](auto patchTrack) { patchTrack->pause(); });
 }
 
 void AudioFlinger::PlaybackThread::Track::flush()
 {
-    ALOGV("flush(%d)", mName);
+    ALOGV("%s(%d)", __func__, mId);
     sp<ThreadBase> thread = mThread.promote();
     if (thread != 0) {
         Mutex::Autolock _l(thread->mLock);
@@ -880,11 +1103,12 @@
                 return;
             }
 
-            ALOGV("flush: offload flush");
+            ALOGV("%s(%d): offload flush", __func__, mId);
             reset();
 
             if (mState == STOPPING_1 || mState == STOPPING_2) {
-                ALOGV("flushed in STOPPING_1 or 2 state, change state to ACTIVE");
+                ALOGV("%s(%d): flushed in STOPPING_1 or 2 state, change state to ACTIVE",
+                        __func__, mId);
                 mState = ACTIVE;
             }
 
@@ -914,6 +1138,8 @@
         // because the hardware buffer could hold a large amount of audio
         playbackThread->broadcast_l();
     }
+    // Flush the Tee to avoid on resume playing old data and glitching on the transition to new data
+    forEachTeePatchTrack([](auto patchTrack) { patchTrack->flush(); });
 }
 
 // must be called with thread lock held
@@ -949,7 +1175,7 @@
 {
     sp<ThreadBase> thread = mThread.promote();
     if (thread == 0) {
-        ALOGE("thread is dead");
+        ALOGE("%s(%d): thread is dead", __func__, mId);
         return FAILED_TRANSACTION;
     } else if ((thread->type() == ThreadBase::DIRECT) ||
                     (thread->type() == ThreadBase::OFFLOAD)) {
@@ -959,6 +1185,19 @@
     }
 }
 
+status_t AudioFlinger::PlaybackThread::Track::selectPresentation(int presentationId,
+        int programId) {
+    sp<ThreadBase> thread = mThread.promote();
+    if (thread == 0) {
+        ALOGE("thread is dead");
+        return FAILED_TRANSACTION;
+    } else if ((thread->type() == ThreadBase::DIRECT) || (thread->type() == ThreadBase::OFFLOAD)) {
+        DirectOutputThread *directOutputThread = static_cast<DirectOutputThread*>(thread.get());
+        return directOutputThread->selectPresentation(presentationId, programId);
+    }
+    return INVALID_OPERATION;
+}
+
 VolumeShaper::Status AudioFlinger::PlaybackThread::Track::applyVolumeShaper(
         const sp<VolumeShaper::Configuration>& configuration,
         const sp<VolumeShaper::Operation>& operation)
@@ -969,8 +1208,10 @@
         const VolumeShaper::Configuration::OptionFlag optionFlag
             = configuration->getOptionFlags();
         if ((optionFlag & VolumeShaper::Configuration::OPTION_FLAG_CLOCK_TIME) == 0) {
-            ALOGW("%s tracks do not support frame counted VolumeShaper,"
-                    " using clock time instead", isOffloaded() ? "Offload" : "Direct");
+            ALOGW("%s(%d): %s tracks do not support frame counted VolumeShaper,"
+                    " using clock time instead",
+                    __func__, mId,
+                    isOffloaded() ? "Offload" : "Direct");
             newConfiguration = new VolumeShaper::Configuration(*configuration);
             newConfiguration->setOptionFlags(
                 VolumeShaper::Configuration::OptionFlag(optionFlag
@@ -985,7 +1226,7 @@
         // Signal thread to fetch new volume.
         sp<ThreadBase> thread = mThread.promote();
         if (thread != 0) {
-             Mutex::Autolock _l(thread->mLock);
+            Mutex::Autolock _l(thread->mLock);
             thread->broadcast_l();
         }
     }
@@ -1017,6 +1258,11 @@
     };
 }
 
+void AudioFlinger::PlaybackThread::Track::setTeePatches(TeePatches teePatches) {
+    forEachTeePatchTrack([](auto patchTrack) { patchTrack->destroy(); });
+    mTeePatches = std::move(teePatches);
+}
+
 status_t AudioFlinger::PlaybackThread::Track::getTimestamp(AudioTimestamp& timestamp)
 {
     if (!isOffloaded() && !isDirect()) {
@@ -1034,54 +1280,25 @@
 
 status_t AudioFlinger::PlaybackThread::Track::attachAuxEffect(int EffectId)
 {
-    status_t status = DEAD_OBJECT;
     sp<ThreadBase> thread = mThread.promote();
-    if (thread != 0) {
-        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
-        sp<AudioFlinger> af = mClient->audioFlinger();
+    if (thread == nullptr) {
+        return DEAD_OBJECT;
+    }
 
-        Mutex::Autolock _l(af->mLock);
+    sp<PlaybackThread> dstThread = (PlaybackThread *)thread.get();
+    sp<PlaybackThread> srcThread; // srcThread is initialized by call to moveAuxEffectToIo()
+    sp<AudioFlinger> af = mClient->audioFlinger();
+    status_t status = af->moveAuxEffectToIo(EffectId, dstThread, &srcThread);
 
-        sp<PlaybackThread> srcThread = af->getEffectThread_l(AUDIO_SESSION_OUTPUT_MIX, EffectId);
-
-        if (EffectId != 0 && srcThread != 0 && playbackThread != srcThread.get()) {
-            Mutex::Autolock _dl(playbackThread->mLock);
-            Mutex::Autolock _sl(srcThread->mLock);
-            sp<EffectChain> chain = srcThread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
-            if (chain == 0) {
-                return INVALID_OPERATION;
-            }
-
-            sp<EffectModule> effect = chain->getEffectFromId_l(EffectId);
-            if (effect == 0) {
-                return INVALID_OPERATION;
-            }
-            srcThread->removeEffect_l(effect);
-            status = playbackThread->addEffect_l(effect);
-            if (status != NO_ERROR) {
-                srcThread->addEffect_l(effect);
-                return INVALID_OPERATION;
-            }
-            // removeEffect_l() has stopped the effect if it was active so it must be restarted
-            if (effect->state() == EffectModule::ACTIVE ||
-                    effect->state() == EffectModule::STOPPING) {
-                effect->start();
-            }
-
-            sp<EffectChain> dstChain = effect->chain().promote();
-            if (dstChain == 0) {
-                srcThread->addEffect_l(effect);
-                return INVALID_OPERATION;
-            }
-            AudioSystem::unregisterEffect(effect->id());
-            AudioSystem::registerEffect(&effect->desc(),
-                                        srcThread->id(),
-                                        dstChain->strategy(),
-                                        AUDIO_SESSION_OUTPUT_MIX,
-                                        effect->id());
-            AudioSystem::setEffectEnabled(effect->id(), effect->isEnabled());
+    if (EffectId != 0 && status == NO_ERROR) {
+        status = dstThread->attachAuxEffect(this, EffectId);
+        if (status == NO_ERROR) {
+            AudioSystem::moveEffectsToIo(std::vector<int>(EffectId), dstThread->id());
         }
-        status = playbackThread->attachAuxEffect(this, EffectId);
+    }
+
+    if (status != NO_ERROR && srcThread != nullptr) {
+        af->moveAuxEffectToIo(EffectId, srcThread, &dstThread);
     }
     return status;
 }
@@ -1105,11 +1322,14 @@
     // to detect when all frames have been played. In this case framesWritten isn't
     // useful because it doesn't always reflect whether there is data in the h/w
     // buffers, particularly if a track has been paused and resumed during draining
-    ALOGV("presentationComplete() mPresentationCompleteFrames %lld framesWritten %lld",
+    ALOGV("%s(%d): presentationComplete() mPresentationCompleteFrames %lld framesWritten %lld",
+            __func__, mId,
             (long long)mPresentationCompleteFrames, (long long)framesWritten);
     if (mPresentationCompleteFrames == 0) {
         mPresentationCompleteFrames = framesWritten + audioHalFrames;
-        ALOGV("presentationComplete() reset: mPresentationCompleteFrames %lld audioHalFrames %zu",
+        ALOGV("%s(%d): presentationComplete() reset:"
+                " mPresentationCompleteFrames %lld audioHalFrames %zu",
+                __func__, mId,
                 (long long)mPresentationCompleteFrames, audioHalFrames);
     }
 
@@ -1175,7 +1395,8 @@
     if (isTerminated() || mState == PAUSED ||
             ((framesReady() == 0) && ((mSharedBuffer != 0) ||
                                       (mState == STOPPED)))) {
-        ALOGW("Track::setSyncEvent() in invalid state %d on session %d %s mode, framesReady %zu",
+        ALOGW("%s(%d): in invalid state %d on session %d %s mode, framesReady %zu",
+              __func__, mId,
               mState, mSessionId, (mSharedBuffer != 0) ? "static" : "stream", framesReady());
         event->cancel();
         return INVALID_OPERATION;
@@ -1246,7 +1467,17 @@
 //To be called with thread lock held
 void AudioFlinger::PlaybackThread::Track::updateTrackFrameInfo(
         int64_t trackFramesReleased, int64_t sinkFramesWritten,
-        const ExtendedTimestamp &timeStamp) {
+        uint32_t halSampleRate, const ExtendedTimestamp &timeStamp) {
+   // Make the kernel frametime available.
+    const FrameTime ft{
+            timeStamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL],
+            timeStamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL]};
+    // ALOGD("FrameTime: %lld %lld", (long long)ft.frames, (long long)ft.timeNs);
+    mKernelFrameTime.store(ft);
+    if (!audio_is_linear_pcm(mFormat)) {
+        return;
+    }
+
     //update frame map
     mFrameMap.push(trackFramesReleased, sinkFramesWritten);
 
@@ -1255,6 +1486,7 @@
     // Our timestamps are only updated when the track is on the Thread active list.
     // We need to ensure that tracks are not removed before full drain.
     ExtendedTimestamp local = timeStamp;
+    bool drained = true; // default assume drained, if no server info found
     bool checked = false;
     for (int i = ExtendedTimestamp::LOCATION_MAX - 1;
             i >= ExtendedTimestamp::LOCATION_SERVER; --i) {
@@ -1263,21 +1495,64 @@
             local.mPosition[i] = mFrameMap.findX(local.mPosition[i]);
             // check drain state from the latest stage in the pipeline.
             if (!checked && i <= ExtendedTimestamp::LOCATION_KERNEL) {
-                mAudioTrackServerProxy->setDrained(
-                        local.mPosition[i] >= mAudioTrackServerProxy->framesReleased());
+                drained = local.mPosition[i] >= mAudioTrackServerProxy->framesReleased();
                 checked = true;
             }
         }
     }
-    if (!checked) { // no server info, assume drained.
-        mAudioTrackServerProxy->setDrained(true);
-    }
+
+    mAudioTrackServerProxy->setDrained(drained);
     // Set correction for flushed frames that are not accounted for in released.
     local.mFlushed = mAudioTrackServerProxy->framesFlushed();
     mServerProxy->setTimestamp(local);
+
+    // Compute latency info.
+    const bool useTrackTimestamp = !drained;
+    const double latencyMs = useTrackTimestamp
+            ? local.getOutputServerLatencyMs(sampleRate())
+            : timeStamp.getOutputServerLatencyMs(halSampleRate);
+
+    mServerLatencyFromTrack.store(useTrackTimestamp);
+    mServerLatencyMs.store(latencyMs);
+}
+
+binder::Status AudioFlinger::PlaybackThread::Track::AudioVibrationController::mute(
+        /*out*/ bool *ret) {
+    *ret = false;
+    sp<ThreadBase> thread = mTrack->mThread.promote();
+    if (thread != 0) {
+        // Lock for updating mHapticPlaybackEnabled.
+        Mutex::Autolock _l(thread->mLock);
+        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+        if ((mTrack->channelMask() & AUDIO_CHANNEL_HAPTIC_ALL) != AUDIO_CHANNEL_NONE
+                && playbackThread->mHapticChannelCount > 0) {
+            mTrack->setHapticPlaybackEnabled(false);
+            *ret = true;
+        }
+    }
+    return binder::Status::ok();
+}
+
+binder::Status AudioFlinger::PlaybackThread::Track::AudioVibrationController::unmute(
+        /*out*/ bool *ret) {
+    *ret = false;
+    sp<ThreadBase> thread = mTrack->mThread.promote();
+    if (thread != 0) {
+        // Lock for updating mHapticPlaybackEnabled.
+        Mutex::Autolock _l(thread->mLock);
+        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+        if ((mTrack->channelMask() & AUDIO_CHANNEL_HAPTIC_ALL) != AUDIO_CHANNEL_NONE
+                && playbackThread->mHapticChannelCount > 0) {
+            mTrack->setHapticPlaybackEnabled(true);
+            *ret = true;
+        }
+    }
+    return binder::Status::ok();
 }
 
 // ----------------------------------------------------------------------------
+#undef LOG_TAG
+#define LOG_TAG "AF::OutputTrack"
 
 AudioFlinger::PlaybackThread::OutputTrack::OutputTrack(
             PlaybackThread *playbackThread,
@@ -1291,7 +1566,7 @@
               audio_attributes_t{} /* currently unused for output track */,
               sampleRate, format, channelMask, frameCount,
               nullptr /* buffer */, (size_t)0 /* bufferSize */, nullptr /* sharedBuffer */,
-              AUDIO_SESSION_NONE, uid, AUDIO_OUTPUT_FLAG_NONE,
+              AUDIO_SESSION_NONE, getpid(), uid, AUDIO_OUTPUT_FLAG_NONE,
               TYPE_OUTPUT),
     mActive(false), mSourceThread(sourceThread)
 {
@@ -1299,9 +1574,9 @@
     if (mCblk != NULL) {
         mOutBuffer.frameCount = 0;
         playbackThread->mTracks.add(this);
-        ALOGV("OutputTrack constructor mCblk %p, mBuffer %p, "
+        ALOGV("%s(): mCblk %p, mBuffer %p, "
                 "frameCount %zu, mChannelMask 0x%08x",
-                mCblk, mBuffer,
+                __func__, mCblk, mBuffer,
                 frameCount, mChannelMask);
         // since client and server are in the same process,
         // the buffer has the same virtual address on both sides
@@ -1311,7 +1586,8 @@
         mClientProxy->setSendLevel(0.0);
         mClientProxy->setSampleRate(sampleRate);
     } else {
-        ALOGW("Error creating output track on thread %p", playbackThread);
+        ALOGW("%s(%d): Error creating output track on thread %d",
+                __func__, mId, (int)mThreadIoHandle);
     }
 }
 
@@ -1342,7 +1618,7 @@
     mActive = false;
 }
 
-bool AudioFlinger::PlaybackThread::OutputTrack::write(void* data, uint32_t frames)
+ssize_t AudioFlinger::PlaybackThread::OutputTrack::write(void* data, uint32_t frames)
 {
     Buffer *pInBuffer;
     Buffer inBuffer;
@@ -1373,8 +1649,9 @@
             nsecs_t startTime = systemTime();
             status_t status = obtainBuffer(&mOutBuffer, waitTimeLeftMs);
             if (status != NO_ERROR && status != NOT_ENOUGH_DATA) {
-                ALOGV("OutputTrack::write() %p thread %p no more output buffers; status %d", this,
-                        mThread.unsafe_get(), status);
+                ALOGV("%s(%d): thread %d no more output buffers; status %d",
+                        __func__, mId,
+                        (int)mThreadIoHandle, status);
                 outputBufferFull = true;
                 break;
             }
@@ -1410,8 +1687,9 @@
                 if (pInBuffer != &inBuffer) {
                     delete pInBuffer;
                 }
-                ALOGV("OutputTrack::write() %p thread %p released overflow buffer %zu", this,
-                        mThread.unsafe_get(), mBufferQueue.size());
+                ALOGV("%s(%d): thread %d released overflow buffer %zu",
+                        __func__, mId,
+                        (int)mThreadIoHandle, mBufferQueue.size());
             } else {
                 break;
             }
@@ -1429,11 +1707,14 @@
                 pInBuffer->raw = pInBuffer->mBuffer;
                 memcpy(pInBuffer->raw, inBuffer.raw, inBuffer.frameCount * mFrameSize);
                 mBufferQueue.add(pInBuffer);
-                ALOGV("OutputTrack::write() %p thread %p adding overflow buffer %zu", this,
-                        mThread.unsafe_get(), mBufferQueue.size());
+                ALOGV("%s(%d): thread %d adding overflow buffer %zu", __func__, mId,
+                        (int)mThreadIoHandle, mBufferQueue.size());
+                // audio data is consumed (stored locally); set frameCount to 0.
+                inBuffer.frameCount = 0;
             } else {
-                ALOGW("OutputTrack::write() %p thread %p no more overflow buffers",
-                        mThread.unsafe_get(), this);
+                ALOGW("%s(%d): thread %d no more overflow buffers",
+                        __func__, mId, (int)mThreadIoHandle);
+                // TODO: return error for this.
             }
         }
     }
@@ -1444,7 +1725,7 @@
         stop();
     }
 
-    return outputBufferFull;
+    return frames - inBuffer.frameCount;  // number of frames consumed.
 }
 
 void AudioFlinger::PlaybackThread::OutputTrack::copyMetadataTo(MetadataInserter& backInserter) const
@@ -1496,6 +1777,10 @@
     }
 }
 
+// ----------------------------------------------------------------------------
+#undef LOG_TAG
+#define LOG_TAG "AF::PatchTrack"
+
 AudioFlinger::PlaybackThread::PatchTrack::PatchTrack(PlaybackThread *playbackThread,
                                                      audio_stream_type_t streamType,
                                                      uint32_t sampleRate,
@@ -1504,31 +1789,29 @@
                                                      size_t frameCount,
                                                      void *buffer,
                                                      size_t bufferSize,
-                                                     audio_output_flags_t flags)
+                                                     audio_output_flags_t flags,
+                                                     const Timeout& timeout)
     :   Track(playbackThread, NULL, streamType,
               audio_attributes_t{} /* currently unused for patch track */,
               sampleRate, format, channelMask, frameCount,
               buffer, bufferSize, nullptr /* sharedBuffer */,
-              AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH),
-              mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, true, true))
+              AUDIO_SESSION_NONE, getpid(), AID_AUDIOSERVER, flags, TYPE_PATCH),
+        PatchTrackBase(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, true, true),
+                       *playbackThread, timeout)
 {
-    uint64_t mixBufferNs = ((uint64_t)2 * playbackThread->frameCount() * 1000000000) /
-                                                                    playbackThread->sampleRate();
-    mPeerTimeout.tv_sec = mixBufferNs / 1000000000;
-    mPeerTimeout.tv_nsec = (int) (mixBufferNs % 1000000000);
-
-    ALOGV("PatchTrack %p sampleRate %d mPeerTimeout %d.%03d sec",
-                                      this, sampleRate,
+    ALOGV("%s(%d): sampleRate %d mPeerTimeout %d.%03d sec",
+                                      __func__, mId, sampleRate,
                                       (int)mPeerTimeout.tv_sec,
                                       (int)(mPeerTimeout.tv_nsec / 1000000));
 }
 
 AudioFlinger::PlaybackThread::PatchTrack::~PatchTrack()
 {
+    ALOGV("%s(%d)", __func__, mId);
 }
 
 status_t AudioFlinger::PlaybackThread::PatchTrack::start(AudioSystem::sync_event_t event,
-                                                          audio_session_t triggerSession)
+                                                         audio_session_t triggerSession)
 {
     status_t status = Track::start(event, triggerSession);
     if (status != NO_ERROR) {
@@ -1542,11 +1825,11 @@
 status_t AudioFlinger::PlaybackThread::PatchTrack::getNextBuffer(
         AudioBufferProvider::Buffer* buffer)
 {
-    ALOG_ASSERT(mPeerProxy != 0, "PatchTrack::getNextBuffer() called without peer proxy");
+    ALOG_ASSERT(mPeerProxy != 0, "%s(%d): called without peer proxy", __func__, mId);
     Proxy::Buffer buf;
     buf.mFrameCount = buffer->frameCount;
     status_t status = mPeerProxy->obtainBuffer(&buf, &mPeerTimeout);
-    ALOGV_IF(status != NO_ERROR, "PatchTrack() %p getNextBuffer status %d", this, status);
+    ALOGV_IF(status != NO_ERROR, "%s(%d): getNextBuffer status %d", __func__, mId, status);
     buffer->frameCount = buf.mFrameCount;
     if (buf.mFrameCount == 0) {
         return WOULD_BLOCK;
@@ -1557,7 +1840,7 @@
 
 void AudioFlinger::PlaybackThread::PatchTrack::releaseBuffer(AudioBufferProvider::Buffer* buffer)
 {
-    ALOG_ASSERT(mPeerProxy != 0, "PatchTrack::releaseBuffer() called without peer proxy");
+    ALOG_ASSERT(mPeerProxy != 0, "%s(%d): called without peer proxy", __func__, mId);
     Proxy::Buffer buf;
     buf.mFrameCount = buffer->frameCount;
     buf.mRaw = buffer->raw;
@@ -1592,7 +1875,7 @@
 void AudioFlinger::PlaybackThread::PatchTrack::restartIfDisabled()
 {
     if (android_atomic_and(~CBLK_DISABLED, &mCblk->mFlags) & CBLK_DISABLED) {
-        ALOGW("PatchTrack::releaseBuffer() disabled due to previous underrun, restarting");
+        ALOGW("%s(%d): disabled due to previous underrun, restarting", __func__, mId);
         start();
     }
 }
@@ -1601,10 +1884,14 @@
 //      Record
 // ----------------------------------------------------------------------------
 
+
 // ----------------------------------------------------------------------------
 //      AppOp for audio recording
 // -------------------------------
 
+#undef LOG_TAG
+#define LOG_TAG "AF::OpRecordAudioMonitor"
+
 // static
 sp<AudioFlinger::RecordThread::OpRecordAudioMonitor>
 AudioFlinger::RecordThread::OpRecordAudioMonitor::createIfNeeded(
@@ -1661,7 +1948,7 @@
 
 // Called by RecordAudioOpCallback when OP_RECORD_AUDIO is updated in AppOp callback
 // and in onFirstRef()
-// Note this method is never called (and never to be) for audio server / patch record track
+// Note this method is never called (and never to be) for audio server / root track
 // due to the UID in createIfNeeded(). As a result for those record track, it's:
 // - not called from constructor,
 // - not called from RecordAudioOpCallback because the callback is not installed in this case
@@ -1693,7 +1980,11 @@
     }
 }
 
-//----------------------------------------
+
+
+#undef LOG_TAG
+#define LOG_TAG "AF::RecordHandle"
+
 AudioFlinger::RecordHandle::RecordHandle(
         const sp<AudioFlinger::RecordThread::RecordTrack>& recordTrack)
     : BnAudioRecord(),
@@ -1708,7 +1999,7 @@
 
 binder::Status AudioFlinger::RecordHandle::start(int /*AudioSystem::sync_event_t*/ event,
         int /*audio_session_t*/ triggerSession) {
-    ALOGV("RecordHandle::start()");
+    ALOGV("%s()", __func__);
     return binder::Status::fromStatusT(
         mRecordTrack->start((AudioSystem::sync_event_t)event, (audio_session_t) triggerSession));
 }
@@ -1719,18 +2010,32 @@
 }
 
 void AudioFlinger::RecordHandle::stop_nonvirtual() {
-    ALOGV("RecordHandle::stop()");
+    ALOGV("%s()", __func__);
     mRecordTrack->stop();
 }
 
 binder::Status AudioFlinger::RecordHandle::getActiveMicrophones(
         std::vector<media::MicrophoneInfo>* activeMicrophones) {
-    ALOGV("RecordHandle::getActiveMicrophones()");
+    ALOGV("%s()", __func__);
     return binder::Status::fromStatusT(
             mRecordTrack->getActiveMicrophones(activeMicrophones));
 }
 
+binder::Status AudioFlinger::RecordHandle::setPreferredMicrophoneDirection(
+        int /*audio_microphone_direction_t*/ direction) {
+    ALOGV("%s()", __func__);
+    return binder::Status::fromStatusT(mRecordTrack->setPreferredMicrophoneDirection(
+            static_cast<audio_microphone_direction_t>(direction)));
+}
+
+binder::Status AudioFlinger::RecordHandle::setPreferredMicrophoneFieldDimension(float zoom) {
+    ALOGV("%s()", __func__);
+    return binder::Status::fromStatusT(mRecordTrack->setPreferredMicrophoneFieldDimension(zoom));
+}
+
 // ----------------------------------------------------------------------------
+#undef LOG_TAG
+#define LOG_TAG "AF::RecordTrack"
 
 // RecordTrack constructor must be called with AudioFlinger::mLock and ThreadBase::mLock held
 AudioFlinger::RecordThread::RecordTrack::RecordTrack(
@@ -1744,13 +2049,15 @@
             void *buffer,
             size_t bufferSize,
             audio_session_t sessionId,
+            pid_t creatorPid,
             uid_t uid,
             audio_input_flags_t flags,
             track_type type,
             const String16& opPackageName,
             audio_port_handle_t portId)
     :   TrackBase(thread, client, attr, sampleRate, format,
-                  channelMask, frameCount, buffer, bufferSize, sessionId, uid, false /*isOut*/,
+                  channelMask, frameCount, buffer, bufferSize, sessionId,
+                  creatorPid, uid, false /*isOut*/,
                   (type == TYPE_DEFAULT) ?
                           ((flags & AUDIO_INPUT_FLAG_FAST) ? ALLOC_PIPE : ALLOC_CBLK) :
                           ((buffer == NULL) ? ALLOC_LOCAL : ALLOC_NONE),
@@ -1767,18 +2074,20 @@
         return;
     }
 
-    mRecordBufferConverter = new RecordBufferConverter(
-            thread->mChannelMask, thread->mFormat, thread->mSampleRate,
-            channelMask, format, sampleRate);
-    // Check if the RecordBufferConverter construction was successful.
-    // If not, don't continue with construction.
-    //
-    // NOTE: It would be extremely rare that the record track cannot be created
-    // for the current device, but a pending or future device change would make
-    // the record track configuration valid.
-    if (mRecordBufferConverter->initCheck() != NO_ERROR) {
-        ALOGE("RecordTrack unable to create record buffer converter");
-        return;
+    if (!isDirect()) {
+        mRecordBufferConverter = new RecordBufferConverter(
+                thread->mChannelMask, thread->mFormat, thread->mSampleRate,
+                channelMask, format, sampleRate);
+        // Check if the RecordBufferConverter construction was successful.
+        // If not, don't continue with construction.
+        //
+        // NOTE: It would be extremely rare that the record track cannot be created
+        // for the current device, but a pending or future device change would make
+        // the record track configuration valid.
+        if (mRecordBufferConverter->initCheck() != NO_ERROR) {
+            ALOGE("%s(%d): RecordTrack unable to create record buffer converter", __func__, mId);
+            return;
+        }
     }
 
     mServerProxy = new AudioRecordServerProxy(mCblk, mBuffer, frameCount,
@@ -1789,12 +2098,20 @@
     if (flags & AUDIO_INPUT_FLAG_FAST) {
         ALOG_ASSERT(thread->mFastTrackAvail);
         thread->mFastTrackAvail = false;
+    } else {
+        // TODO: only Normal Record has timestamps (Fast Record does not).
+        mServerLatencySupported = checkServerLatencySupported(mFormat, flags);
     }
+#ifdef TEE_SINK
+    mTee.setId(std::string("_") + std::to_string(mThreadIoHandle)
+            + "_" + std::to_string(mId)
+            + "_R");
+#endif
 }
 
 AudioFlinger::RecordThread::RecordTrack::~RecordTrack()
 {
-    ALOGV("%s", __func__);
+    ALOGV("%s()", __func__);
     delete mRecordBufferConverter;
     delete mResamplerBufferProvider;
 }
@@ -1851,17 +2168,34 @@
     // see comments at AudioFlinger::PlaybackThread::Track::destroy()
     sp<RecordTrack> keep(this);
     {
-        if (isExternalTrack()) {
-            if (mState == ACTIVE || mState == RESUMING) {
-                AudioSystem::stopInput(mPortId);
-            }
-            AudioSystem::releaseInput(mPortId);
-        }
+        track_state priorState = mState;
         sp<ThreadBase> thread = mThread.promote();
         if (thread != 0) {
             Mutex::Autolock _l(thread->mLock);
             RecordThread *recordThread = (RecordThread *) thread.get();
-            recordThread->destroyTrack_l(this);
+            priorState = mState;
+            recordThread->destroyTrack_l(this); // move mState to STOPPED, terminate
+        }
+        // APM portid/client management done outside of lock.
+        // NOTE: if thread doesn't exist, the input descriptor probably doesn't either.
+        if (isExternalTrack()) {
+            switch (priorState) {
+            case ACTIVE:     // invalidated while still active
+            case STARTING_2: // invalidated/start-aborted after startInput successfully called
+            case PAUSING:    // invalidated while in the middle of stop() pausing (still active)
+                AudioSystem::stopInput(mPortId);
+                break;
+
+            case STARTING_1: // invalidated/start-aborted and startInput not successful
+            case PAUSED:     // OK, not active
+            case IDLE:       // OK, not active
+                break;
+
+            case STOPPED:    // unexpected (destroyed)
+            default:
+                LOG_ALWAYS_FATAL("%s(%d): invalid prior state: %d", __func__, mId, priorState);
+            }
+            AudioSystem::releaseInput(mPortId);
         }
     }
 }
@@ -1878,31 +2212,50 @@
 }
 
 
-/*static*/ void AudioFlinger::RecordThread::RecordTrack::appendDumpHeader(String8& result)
+void AudioFlinger::RecordThread::RecordTrack::appendDumpHeader(String8& result)
 {
-    result.append("Active Client Session S  Flags   Format Chn mask  SRate   Server FrmCnt Sil\n");
+    result.appendFormat("Active     Id Client Session Port Id  S  Flags  "
+                        " Format Chn mask  SRate Source  "
+                        " Server FrmCnt FrmRdy Sil%s\n",
+                        isServerLatencySupported() ? "   Latency" : "");
 }
 
 void AudioFlinger::RecordThread::RecordTrack::appendDump(String8& result, bool active)
 {
-    result.appendFormat("%c%5s %6u %7u %2s 0x%03X "
-            "%08X %08X %6u "
-            "%08X %6zu %3c\n",
+    result.appendFormat("%c%5s %6d %6u %7u %7u  %2s 0x%03X "
+            "%08X %08X %6u %6X "
+            "%08X %6zu %6zu %3c",
             isFastTrack() ? 'F' : ' ',
             active ? "yes" : "no",
-            (mClient == 0) ? getpid_cached : mClient->pid(),
+            mId,
+            (mClient == 0) ? getpid() : mClient->pid(),
             mSessionId,
+            mPortId,
             getTrackStateString(),
             mCblk->mFlags,
 
             mFormat,
             mChannelMask,
             mSampleRate,
+            mAttr.source,
 
             mCblk->mServer,
             mFrameCount,
+            mServerProxy->framesReadySafe(),
             isSilenced() ? 's' : 'n'
             );
+    if (isServerLatencySupported()) {
+        double latencyMs;
+        bool fromTrack;
+        if (getTrackLatencyMs(&latencyMs, &fromTrack) == OK) {
+            // Show latency in msec, followed by 't' if from track timestamp (the most accurate)
+            // or 'k' if estimated from kernel (usually for debugging).
+            result.appendFormat(" %7.2lf %c", latencyMs, fromTrack ? 't' : 'k');
+        } else {
+            result.appendFormat("%10s", mCblk->mServer != 0 ? "unavail" : "new");
+        }
+    }
+    result.append("\n");
 }
 
 void AudioFlinger::RecordThread::RecordTrack::handleSyncStartEvent(const sp<SyncEvent>& event)
@@ -1932,6 +2285,16 @@
         int64_t trackFramesReleased, int64_t sourceFramesRead,
         uint32_t halSampleRate, const ExtendedTimestamp &timestamp)
 {
+   // Make the kernel frametime available.
+    const FrameTime ft{
+            timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL],
+            timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL]};
+    // ALOGD("FrameTime: %lld %lld", (long long)ft.frames, (long long)ft.timeNs);
+    mKernelFrameTime.store(ft);
+    if (!audio_is_linear_pcm(mFormat)) {
+        return;
+    }
+
     ExtendedTimestamp local = timestamp;
 
     // Convert HAL frames to server-side track frames at track sample rate.
@@ -1945,6 +2308,15 @@
         }
     }
     mServerProxy->setTimestamp(local);
+
+    // Compute latency info.
+    const bool useTrackTimestamp = true; // use track unless debugging.
+    const double latencyMs = - (useTrackTimestamp
+            ? local.getOutputServerLatencyMs(sampleRate())
+            : timestamp.getOutputServerLatencyMs(halSampleRate));
+
+    mServerLatencyFromTrack.store(useTrackTimestamp);
+    mServerLatencyMs.store(latencyMs);
 }
 
 bool AudioFlinger::RecordThread::RecordTrack::isSilenced() const {
@@ -1967,6 +2339,31 @@
     }
 }
 
+status_t AudioFlinger::RecordThread::RecordTrack::setPreferredMicrophoneDirection(
+        audio_microphone_direction_t direction) {
+    sp<ThreadBase> thread = mThread.promote();
+    if (thread != 0) {
+        RecordThread *recordThread = (RecordThread *)thread.get();
+        return recordThread->setPreferredMicrophoneDirection(direction);
+    } else {
+        return BAD_VALUE;
+    }
+}
+
+status_t AudioFlinger::RecordThread::RecordTrack::setPreferredMicrophoneFieldDimension(float zoom) {
+    sp<ThreadBase> thread = mThread.promote();
+    if (thread != 0) {
+        RecordThread *recordThread = (RecordThread *)thread.get();
+        return recordThread->setPreferredMicrophoneFieldDimension(zoom);
+    } else {
+        return BAD_VALUE;
+    }
+}
+
+// ----------------------------------------------------------------------------
+#undef LOG_TAG
+#define LOG_TAG "AF::PatchRecord"
+
 AudioFlinger::RecordThread::PatchRecord::PatchRecord(RecordThread *recordThread,
                                                      uint32_t sampleRate,
                                                      audio_channel_mask_t channelMask,
@@ -1974,38 +2371,37 @@
                                                      size_t frameCount,
                                                      void *buffer,
                                                      size_t bufferSize,
-                                                     audio_input_flags_t flags)
+                                                     audio_input_flags_t flags,
+                                                     const Timeout& timeout)
     :   RecordTrack(recordThread, NULL,
                 audio_attributes_t{} /* currently unused for patch track */,
                 sampleRate, format, channelMask, frameCount,
-                buffer, bufferSize, AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH, String16()),
-                mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, false, true))
+                buffer, bufferSize, AUDIO_SESSION_NONE, getpid(), AID_AUDIOSERVER,
+                flags, TYPE_PATCH, String16()),
+        PatchTrackBase(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, false, true),
+                       *recordThread, timeout)
 {
-    uint64_t mixBufferNs = ((uint64_t)2 * recordThread->frameCount() * 1000000000) /
-                                                                recordThread->sampleRate();
-    mPeerTimeout.tv_sec = mixBufferNs / 1000000000;
-    mPeerTimeout.tv_nsec = (int) (mixBufferNs % 1000000000);
-
-    ALOGV("PatchRecord %p sampleRate %d mPeerTimeout %d.%03d sec",
-                                      this, sampleRate,
+    ALOGV("%s(%d): sampleRate %d mPeerTimeout %d.%03d sec",
+                                      __func__, mId, sampleRate,
                                       (int)mPeerTimeout.tv_sec,
                                       (int)(mPeerTimeout.tv_nsec / 1000000));
 }
 
 AudioFlinger::RecordThread::PatchRecord::~PatchRecord()
 {
+    ALOGV("%s(%d)", __func__, mId);
 }
 
 // AudioBufferProvider interface
 status_t AudioFlinger::RecordThread::PatchRecord::getNextBuffer(
                                                   AudioBufferProvider::Buffer* buffer)
 {
-    ALOG_ASSERT(mPeerProxy != 0, "PatchRecord::getNextBuffer() called without peer proxy");
+    ALOG_ASSERT(mPeerProxy != 0, "%s(%d): called without peer proxy", __func__, mId);
     Proxy::Buffer buf;
     buf.mFrameCount = buffer->frameCount;
     status_t status = mPeerProxy->obtainBuffer(&buf, &mPeerTimeout);
     ALOGV_IF(status != NO_ERROR,
-             "PatchRecord() %p mPeerProxy->obtainBuffer status %d", this, status);
+             "%s(%d): mPeerProxy->obtainBuffer status %d", __func__, mId, status);
     buffer->frameCount = buf.mFrameCount;
     if (buf.mFrameCount == 0) {
         return WOULD_BLOCK;
@@ -2016,7 +2412,7 @@
 
 void AudioFlinger::RecordThread::PatchRecord::releaseBuffer(AudioBufferProvider::Buffer* buffer)
 {
-    ALOG_ASSERT(mPeerProxy != 0, "PatchRecord::releaseBuffer() called without peer proxy");
+    ALOG_ASSERT(mPeerProxy != 0, "%s(%d): called without peer proxy", __func__, mId);
     Proxy::Buffer buf;
     buf.mFrameCount = buffer->frameCount;
     buf.mRaw = buffer->raw;
@@ -2035,7 +2431,9 @@
     mProxy->releaseBuffer(buffer);
 }
 
-
+// ----------------------------------------------------------------------------
+#undef LOG_TAG
+#define LOG_TAG "AF::MmapTrack"
 
 AudioFlinger::MmapThread::MmapTrack::MmapTrack(ThreadBase *thread,
         const audio_attributes_t& attr,
@@ -2043,13 +2441,15 @@
         audio_format_t format,
         audio_channel_mask_t channelMask,
         audio_session_t sessionId,
+        bool isOut,
         uid_t uid,
         pid_t pid,
+        pid_t creatorPid,
         audio_port_handle_t portId)
     :   TrackBase(thread, NULL, attr, sampleRate, format,
                   channelMask, (size_t)0 /* frameCount */,
                   nullptr /* buffer */, (size_t)0 /* bufferSize */,
-                  sessionId, uid, false /* isOut */,
+                  sessionId, creatorPid, uid, isOut,
                   ALLOC_NONE,
                   TYPE_DEFAULT, portId),
         mPid(pid), mSilenced(false), mSilencedNotified(false)
@@ -2066,7 +2466,7 @@
 }
 
 status_t AudioFlinger::MmapThread::MmapTrack::start(AudioSystem::sync_event_t event __unused,
-                                                        audio_session_t triggerSession __unused)
+                                                    audio_session_t triggerSession __unused)
 {
     return NO_ERROR;
 }
@@ -2097,19 +2497,28 @@
 {
 }
 
-/*static*/ void AudioFlinger::MmapThread::MmapTrack::appendDumpHeader(String8& result)
+void AudioFlinger::MmapThread::MmapTrack::appendDumpHeader(String8& result)
 {
-    result.append("Client Session   Format Chn mask  SRate\n");
+    result.appendFormat("Client Session Port Id  Format Chn mask  SRate Flags %s\n",
+                        isOut() ? "Usg CT": "Source");
 }
 
 void AudioFlinger::MmapThread::MmapTrack::appendDump(String8& result, bool active __unused)
 {
-    result.appendFormat("%6u %7u %08X %08X %6u\n",
+    result.appendFormat("%6u %7u %7u %08X %08X %6u 0x%03X ",
             mPid,
             mSessionId,
+            mPortId,
             mFormat,
             mChannelMask,
-            mSampleRate);
+            mSampleRate,
+            mAttr.flags);
+    if (isOut()) {
+        result.appendFormat("%3x %2x", mAttr.usage, mAttr.content_type);
+    } else {
+        result.appendFormat("%6x", mAttr.source);
+    }
+    result.append("\n");
 }
 
 } // namespace android
diff --git a/services/audioflinger/TypedLogger.h b/services/audioflinger/TypedLogger.h
index 38c3c02..6ef19bf 100644
--- a/services/audioflinger/TypedLogger.h
+++ b/services/audioflinger/TypedLogger.h
@@ -97,8 +97,42 @@
 #define LOG_AUDIO_STATE() do { NBLog::Writer *x = tlNBLogWriter; if (x != nullptr) \
         x->logEventHistTs(NBLog::EVENT_AUDIO_STATE, hash(__FILE__, __LINE__)); } while(0)
 
+// Log the difference bewteen frames presented by HAL and frames written to HAL output sink,
+// divided by the sample rate. Parameter ms is of type double.
+#define LOG_LATENCY(ms) do { NBLog::Writer *x = tlNBLogWriter; if (x != nullptr) \
+        x->log<NBLog::EVENT_LATENCY>(ms); } while (0)
+
+// Record thread overrun event nanosecond timestamp. Parameter ns is an int64_t.
+#define LOG_OVERRUN(ns) do { NBLog::Writer *x = tlNBLogWriter; if (x != nullptr) \
+        x->log<NBLog::EVENT_OVERRUN>(ns); } while (0)
+
+// Record thread info. This currently includes type, frameCount, and sampleRate.
+// Parameter type is thread_info_t as defined in NBLog.h.
+#define LOG_THREAD_INFO(info) do { NBLog::Writer *x = tlNBLogWriter; \
+        if (x != nullptr) x->log<NBLog::EVENT_THREAD_INFO>(info); } while (0)
+
+#define LOG_THREAD_PARAMS(params) do {NBLog::Writer *x = tlNBLogWriter; \
+        if (x != nullptr) x->log<NBLog::EVENT_THREAD_PARAMS>(params); } while (0)
+
+// Record thread underrun event nanosecond timestamp. Parameter ns is an int64_t.
+#define LOG_UNDERRUN(ns) do { NBLog::Writer *x = tlNBLogWriter; if (x != nullptr) \
+        x->log<NBLog::EVENT_UNDERRUN>(ns); } while (0)
+
+// Record thread warmup time in milliseconds. Parameter ms is of type double.
+#define LOG_WARMUP_TIME(ms) do { NBLog::Writer *x = tlNBLogWriter; if (x != nullptr) \
+        x->log<NBLog::EVENT_WARMUP_TIME>(ms); } while (0)
+
+// Record a typed entry that represents a thread's work time in nanoseconds.
+// Parameter ns should be of type uint32_t.
+#define LOG_WORK_TIME(ns) do { NBLog::Writer *x = tlNBLogWriter; if (x != nullptr) \
+        x->log<NBLog::EVENT_WORK_TIME>(ns); } while (0)
+
 namespace android {
 extern "C" {
+// TODO consider adding a thread_local NBLog::Writer tlDummyNBLogWriter and then
+// initialize below tlNBLogWriter to &tlDummyNBLogWriter to remove the need to
+// check for nullptr every time. Also reduces the need to add a new logging macro above
+// each time we want to log a new type.
 extern thread_local NBLog::Writer *tlNBLogWriter;
 }
 } // namespace android
diff --git a/services/audiopolicy/Android.bp b/services/audiopolicy/Android.bp
new file mode 100644
index 0000000..a42b89f
--- /dev/null
+++ b/services/audiopolicy/Android.bp
@@ -0,0 +1,5 @@
+cc_library_headers {
+    name: "libaudiopolicymanager_interface_headers",
+    host_supported: true,
+    export_include_dirs: ["."],
+}
diff --git a/services/audiopolicy/Android.mk b/services/audiopolicy/Android.mk
deleted file mode 100644
index d29cae1..0000000
--- a/services/audiopolicy/Android.mk
+++ /dev/null
@@ -1,129 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-    service/AudioPolicyService.cpp \
-    service/AudioPolicyEffects.cpp \
-    service/AudioPolicyInterfaceImpl.cpp \
-    service/AudioPolicyClientImpl.cpp
-
-LOCAL_C_INCLUDES := \
-    frameworks/av/services/audioflinger \
-    $(call include-path-for, audio-utils) \
-    frameworks/av/services/audiopolicy/common/include \
-    frameworks/av/services/audiopolicy/engine/interface \
-    frameworks/av/services/audiopolicy/utilities
-
-LOCAL_SHARED_LIBRARIES := \
-    libcutils \
-    libutils \
-    liblog \
-    libbinder \
-    libaudioclient \
-    libhardware_legacy \
-    libserviceutility \
-    libaudiopolicymanager \
-    libmedia_helper \
-    libmediametrics \
-    libeffectsconfig
-
-LOCAL_STATIC_LIBRARIES := \
-    libaudiopolicycomponents
-
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
-LOCAL_MODULE:= libaudiopolicyservice
-
-LOCAL_CFLAGS += -fvisibility=hidden
-LOCAL_CFLAGS += -Wall -Werror
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= managerdefault/AudioPolicyManager.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-    libcutils \
-    libutils \
-    liblog \
-    libsoundtrigger
-
-ifeq ($(USE_CONFIGURABLE_AUDIO_POLICY), 1)
-
-ifneq ($(USE_XML_AUDIO_POLICY_CONF), 1)
-$(error Configurable policy does not support legacy conf file)
-endif #ifneq ($(USE_XML_AUDIO_POLICY_CONF), 1)
-
-LOCAL_REQUIRED_MODULES := \
-    parameter-framework.policy \
-    audio_policy_criteria.conf \
-
-LOCAL_C_INCLUDES += frameworks/av/services/audiopolicy/engineconfigurable/include
-LOCAL_C_INCLUDES += frameworks/av/include
-
-LOCAL_SHARED_LIBRARIES += libaudiopolicyengineconfigurable
-
-else
-
-LOCAL_SHARED_LIBRARIES += libaudiopolicyenginedefault
-
-endif # ifeq ($(USE_CONFIGURABLE_AUDIO_POLICY), 1)
-
-LOCAL_C_INCLUDES += \
-    frameworks/av/services/audiopolicy/common/include \
-    frameworks/av/services/audiopolicy/engine/interface \
-    frameworks/av/services/audiopolicy/utilities
-
-LOCAL_STATIC_LIBRARIES := \
-    libaudiopolicycomponents
-
-LOCAL_SHARED_LIBRARIES += libmedia_helper
-LOCAL_SHARED_LIBRARIES += libmediametrics
-
-ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
-LOCAL_SHARED_LIBRARIES += libicuuc libxml2
-
-LOCAL_CFLAGS += -DUSE_XML_AUDIO_POLICY_CONF
-endif #ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
-
-LOCAL_CFLAGS += -Wall -Werror
-
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
-LOCAL_MODULE:= libaudiopolicymanagerdefault
-
-include $(BUILD_SHARED_LIBRARY)
-
-ifneq ($(USE_CUSTOM_AUDIO_POLICY), 1)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-    manager/AudioPolicyFactory.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-    libaudiopolicymanagerdefault
-
-LOCAL_STATIC_LIBRARIES := \
-    libaudiopolicycomponents
-
-LOCAL_C_INCLUDES += \
-    frameworks/av/services/audiopolicy/common/include \
-    frameworks/av/services/audiopolicy/engine/interface
-
-LOCAL_CFLAGS := -Wall -Werror
-
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
-LOCAL_MODULE:= libaudiopolicymanager
-
-include $(BUILD_SHARED_LIBRARY)
-
-endif
-
-#######################################################################
-# Recursive call sub-folder Android.mk
-#
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 4812b1f..30f29d6 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -58,27 +58,15 @@
     typedef enum {
         API_INPUT_INVALID = -1,
         API_INPUT_LEGACY  = 0,// e.g. audio recording from a microphone
-        API_INPUT_MIX_CAPTURE,// used for "remote submix", capture of the media to play it remotely
+        API_INPUT_MIX_CAPTURE,// used for "remote submix" legacy mode (no DAP),
+                              // capture of the media to play it remotely
         API_INPUT_MIX_EXT_POLICY_REROUTE,// used for platform audio rerouting, where mixes are
                                          // handled by external and dynamically installed
                                          // policies which reroute audio mixes
+        API_INPUT_MIX_PUBLIC_CAPTURE_PLAYBACK,  // used for playback capture with a MediaProjection
         API_INPUT_TELEPHONY_RX, // used for capture from telephony RX path
     } input_type_t;
 
-    enum {
-        API_INPUT_CONCURRENCY_NONE = 0,
-        API_INPUT_CONCURRENCY_CALL = (1 << 0),      // Concurrency with a call
-        API_INPUT_CONCURRENCY_CAPTURE = (1 << 1),   // Concurrency with another capture
-        API_INPUT_CONCURRENCY_HOTWORD = (1 << 2),   // Concurrency with a hotword
-        API_INPUT_CONCURRENCY_PREEMPT = (1 << 3),   // pre-empted someone
-                // NB: preempt is marked on a successful return, others are on failing calls
-        API_INPUT_CONCURRENCY_LAST = (1 << 4),
-
-        API_INPUT_CONCURRENCY_ALL = (API_INPUT_CONCURRENCY_LAST - 1),
-    };
-
-    typedef uint32_t concurrency_type__mask_t;
-
 public:
     virtual ~AudioPolicyInterface() {}
     //
@@ -89,14 +77,16 @@
     virtual status_t setDeviceConnectionState(audio_devices_t device,
                                               audio_policy_dev_state_t state,
                                               const char *device_address,
-                                              const char *device_name) = 0;
+                                              const char *device_name,
+                                              audio_format_t encodedFormat) = 0;
     // retrieve a device connection status
     virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
                                                                           const char *device_address) = 0;
     // indicate a change in device configuration
     virtual status_t handleDeviceConfigChange(audio_devices_t device,
                                               const char *device_address,
-                                              const char *device_name) = 0;
+                                              const char *device_name,
+                                              audio_format_t encodedFormat) = 0;
     // indicate a change in phone state. Valid phones states are defined by audio_mode_t
     virtual void setPhoneState(audio_mode_t state) = 0;
     // force using a specific device category for the specified usage
@@ -122,23 +112,19 @@
                                         const audio_config_t *config,
                                         audio_output_flags_t *flags,
                                         audio_port_handle_t *selectedDeviceId,
-                                        audio_port_handle_t *portId) = 0;
+                                        audio_port_handle_t *portId,
+                                        std::vector<audio_io_handle_t> *secondaryOutputs) = 0;
     // indicates to the audio policy manager that the output starts being used by corresponding stream.
-    virtual status_t startOutput(audio_io_handle_t output,
-                                 audio_stream_type_t stream,
-                                 audio_session_t session) = 0;
+    virtual status_t startOutput(audio_port_handle_t portId) = 0;
     // indicates to the audio policy manager that the output stops being used by corresponding stream.
-    virtual status_t stopOutput(audio_io_handle_t output,
-                                audio_stream_type_t stream,
-                                audio_session_t session) = 0;
+    virtual status_t stopOutput(audio_port_handle_t portId) = 0;
     // releases the output.
-    virtual void releaseOutput(audio_io_handle_t output,
-                               audio_stream_type_t stream,
-                               audio_session_t session) = 0;
+    virtual void releaseOutput(audio_port_handle_t portId) = 0;
 
     // request an input appropriate for record from the supplied device with supplied parameters.
     virtual status_t getInputForAttr(const audio_attributes_t *attr,
                                      audio_io_handle_t *input,
+                                     audio_unique_id_t riid,
                                      audio_session_t session,
                                      uid_t uid,
                                      const audio_config_base_t *config,
@@ -147,16 +133,11 @@
                                      input_type_t *inputType,
                                      audio_port_handle_t *portId) = 0;
     // indicates to the audio policy manager that the input starts being used.
-    virtual status_t startInput(audio_io_handle_t input,
-                                audio_session_t session,
-                                bool silenced,
-                                concurrency_type__mask_t *concurrency) = 0;
+    virtual status_t startInput(audio_port_handle_t portId) = 0;
     // indicates to the audio policy manager that the input stops being used.
-    virtual status_t stopInput(audio_io_handle_t input,
-                               audio_session_t session) = 0;
+    virtual status_t stopInput(audio_port_handle_t portId) = 0;
     // releases the input.
-    virtual void releaseInput(audio_io_handle_t input,
-                              audio_session_t session) = 0;
+    virtual void releaseInput(audio_port_handle_t portId) = 0;
 
     //
     // volume control functions
@@ -181,6 +162,19 @@
                                           int *index,
                                           audio_devices_t device) = 0;
 
+    virtual status_t setVolumeIndexForAttributes(const audio_attributes_t &attr,
+                                                 int index,
+                                                 audio_devices_t device) = 0;
+    virtual status_t getVolumeIndexForAttributes(const audio_attributes_t &attr,
+                                                 int &index,
+                                                 audio_devices_t device) = 0;
+
+    virtual status_t getMaxVolumeIndexForAttributes(const audio_attributes_t &attr,
+                                                    int &index) = 0;
+
+    virtual status_t getMinVolumeIndexForAttributes(const audio_attributes_t &attr,
+                                                    int &index) = 0;
+
     // return the strategy corresponding to a given stream type
     virtual uint32_t getStrategyForStream(audio_stream_type_t stream) = 0;
 
@@ -196,6 +190,7 @@
                                     int id) = 0;
     virtual status_t unregisterEffect(int id) = 0;
     virtual status_t setEffectEnabled(int id, bool enabled) = 0;
+    virtual status_t moveEffectsToIo(const std::vector<int>& ids, audio_io_handle_t io) = 0;
 
     virtual bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const = 0;
     virtual bool isStreamActiveRemotely(audio_stream_type_t stream,
@@ -205,7 +200,10 @@
     //dump state
     virtual status_t    dump(int fd) = 0;
 
+    virtual status_t setAllowedCapturePolicy(uid_t uid, audio_flags_mask_t flags) = 0;
     virtual bool isOffloadSupported(const audio_offload_info_t& offloadInfo) = 0;
+    virtual bool isDirectOutputSupported(const audio_config_base_t& config,
+                                         const audio_attributes_t& attributes) = 0;
 
     virtual status_t listAudioPorts(audio_port_role_t role,
                                     audio_port_type_t type,
@@ -233,11 +231,15 @@
     virtual status_t registerPolicyMixes(const Vector<AudioMix>& mixes) = 0;
     virtual status_t unregisterPolicyMixes(Vector<AudioMix> mixes) = 0;
 
+    virtual status_t setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices)
+            = 0;
+    virtual status_t removeUidDeviceAffinities(uid_t uid) = 0;
+
     virtual status_t startAudioSource(const struct audio_port_config *source,
                                       const audio_attributes_t *attributes,
-                                      audio_patch_handle_t *handle,
+                                      audio_port_handle_t *portId,
                                       uid_t uid) = 0;
-    virtual status_t stopAudioSource(audio_patch_handle_t handle) = 0;
+    virtual status_t stopAudioSource(audio_port_handle_t portId) = 0;
 
     virtual status_t setMasterMono(bool mono) = 0;
     virtual status_t getMasterMono(bool *mono) = 0;
@@ -251,7 +253,22 @@
                                         bool reported) = 0;
     virtual status_t setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled) = 0;
 
-    virtual void     setRecordSilenced(uid_t uid, bool silenced);
+    virtual bool     isHapticPlaybackSupported() = 0;
+
+    virtual status_t getHwOffloadEncodingFormatsSupportedForA2DP(
+                std::vector<audio_format_t> *formats) = 0;
+
+    virtual void     setAppState(uid_t uid, app_state_t state) = 0;
+
+    virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies) = 0;
+
+    virtual status_t getProductStrategyFromAudioAttributes(const AudioAttributes &aa,
+                                                           product_strategy_t &productStrategy) = 0;
+
+    virtual status_t listAudioVolumeGroups(AudioVolumeGroupVector &groups) = 0;
+
+    virtual status_t getVolumeGroupFromAudioAttributes(const AudioAttributes &aa,
+                                                       volume_group_t &volumeGroup) = 0;
 };
 
 
@@ -324,11 +341,6 @@
     // function enabling to receive proprietary informations directly from audio hardware interface to audio policy manager.
     virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys) = 0;
 
-    // request the playback of a tone on the specified stream: used for instance to replace notification sounds when playing
-    // over a telephony device during a phone call.
-    virtual status_t startTone(audio_policy_tone_t tone, audio_stream_type_t stream) = 0;
-    virtual status_t stopTone() = 0;
-
     // set down link audio volume.
     virtual status_t setVoiceVolume(float volume, int delayMs = 0) = 0;
 
@@ -337,6 +349,10 @@
                                      audio_io_handle_t srcOutput,
                                      audio_io_handle_t dstOutput) = 0;
 
+    virtual void setEffectSuspended(int effectId,
+                                    audio_session_t sessionId,
+                                    bool suspended) = 0;
+
     /* Create a patch between several source and sink ports */
     virtual status_t createAudioPatch(const struct audio_patch *patch,
                                        audio_patch_handle_t *handle,
@@ -353,15 +369,20 @@
 
     virtual void onAudioPatchListUpdate() = 0;
 
+    virtual void onAudioVolumeGroupChanged(volume_group_t group, int flags) = 0;
+
     virtual audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use) = 0;
 
     virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state) = 0;
 
     virtual void onRecordingConfigurationUpdate(int event,
-                    const record_client_info_t *clientInfo,
-                    const struct audio_config_base *clientConfig,
-                    const struct audio_config_base *deviceConfig,
-                    audio_patch_handle_t patchHandle) = 0;
+                                                const record_client_info_t *clientInfo,
+                                                const audio_config_base_t *clientConfig,
+                                                std::vector<effect_descriptor_t> clientEffects,
+                                                const audio_config_base_t *deviceConfig,
+                                                std::vector<effect_descriptor_t> effects,
+                                                audio_patch_handle_t patchHandle,
+                                                audio_source_t source) = 0;
 };
 
 extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface);
diff --git a/services/audiopolicy/TEST_MAPPING b/services/audiopolicy/TEST_MAPPING
new file mode 100644
index 0000000..a94fd87
--- /dev/null
+++ b/services/audiopolicy/TEST_MAPPING
@@ -0,0 +1,10 @@
+{
+  "presubmit": [
+    {
+       "name": "audiopolicy_tests"
+    },
+    {
+       "name": "systemaudio_tests"
+    }
+  ]
+}
diff --git a/services/audiopolicy/common/Android.bp b/services/audiopolicy/common/Android.bp
new file mode 100644
index 0000000..a925b9a
--- /dev/null
+++ b/services/audiopolicy/common/Android.bp
@@ -0,0 +1,4 @@
+cc_library_headers {
+    name: "libaudiopolicycommon",
+    export_include_dirs: ["include"],
+}
diff --git a/services/audiopolicy/common/Android.mk b/services/audiopolicy/common/Android.mk
deleted file mode 100644
index dcce8e3..0000000
--- a/services/audiopolicy/common/Android.mk
+++ /dev/null
@@ -1,9 +0,0 @@
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-#######################################################################
-# Recursive call sub-folder Android.mk
-#
-include $(call all-makefiles-under,$(LOCAL_PATH))
-
diff --git a/services/audiopolicy/common/include/RoutingStrategy.h b/services/audiopolicy/common/include/RoutingStrategy.h
deleted file mode 100644
index d38967e..0000000
--- a/services/audiopolicy/common/include/RoutingStrategy.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-namespace android {
-
-// Time in milliseconds after media stopped playing during which we consider that the
-// sonification should be as unobtrusive as during the time media was playing.
-#define SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY 5000
-
-enum routing_strategy {
-    STRATEGY_MEDIA,
-    STRATEGY_PHONE,
-    STRATEGY_SONIFICATION,
-    STRATEGY_SONIFICATION_RESPECTFUL,
-    STRATEGY_DTMF,
-    STRATEGY_ENFORCED_AUDIBLE,
-    STRATEGY_TRANSMITTED_THROUGH_SPEAKER,
-    STRATEGY_ACCESSIBILITY,
-    STRATEGY_REROUTING,
-    NUM_STRATEGIES
-};
-
-}; //namespace android
diff --git a/services/audiopolicy/common/include/Volume.h b/services/audiopolicy/common/include/Volume.h
index fc012a2..1dbd1eb 100644
--- a/services/audiopolicy/common/include/Volume.h
+++ b/services/audiopolicy/common/include/Volume.h
@@ -16,10 +16,24 @@
 
 #pragma once
 
+#include <media/AudioCommonTypes.h>
 #include <system/audio.h>
 #include <utils/Log.h>
 #include <math.h>
 
+namespace android {
+
+/**
+ * VolumeSource is the discriminent for volume management on an output.
+ * It used to be the stream type by legacy, it may be host volume group or a volume curves if
+ * we allow to have more than one curve per volume group (mandatory to get rid of AudioServer
+ * stream aliases.
+ */
+enum VolumeSource : std::underlying_type<volume_group_t>::type;
+static const VolumeSource VOLUME_SOURCE_NONE = static_cast<VolumeSource>(VOLUME_GROUP_NONE);
+
+} // namespace android
+
 // Absolute min volume in dB (can be represented in single precision normal float value)
 #define VOLUME_MIN_DB (-758)
 
@@ -134,6 +148,7 @@
         case AUDIO_DEVICE_OUT_USB_DEVICE:
             return DEVICE_CATEGORY_EXT_MEDIA;
         case AUDIO_DEVICE_OUT_SPEAKER:
+        case AUDIO_DEVICE_OUT_SPEAKER_SAFE:
         case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
         case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
         case AUDIO_DEVICE_OUT_USB_ACCESSORY:
diff --git a/services/audiopolicy/common/include/policy.h b/services/audiopolicy/common/include/policy.h
index 9bd68e1..605fc1c 100644
--- a/services/audiopolicy/common/include/policy.h
+++ b/services/audiopolicy/common/include/policy.h
@@ -17,9 +17,20 @@
 #pragma once
 
 #include <system/audio.h>
+#include <vector>
+
+namespace android {
+
+using StreamTypeVector = std::vector<audio_stream_type_t>;
+
+static const audio_attributes_t defaultAttr = AUDIO_ATTRIBUTES_INITIALIZER;
+
+} // namespace android
 
 static const audio_format_t gDynamicFormat = AUDIO_FORMAT_DEFAULT;
 
+static const uint32_t SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY = 5000;
+
 // For mixed output and inputs, the policy will use max mixer sampling rates.
 // Do not limit sampling rate otherwise
 #define SAMPLE_RATE_HZ_MAX 192000
@@ -32,14 +43,6 @@
 #define MAX_MIXER_CHANNEL_COUNT FCC_8
 
 /**
- * A device mask for all audio input devices that are considered "virtual" when evaluating
- * active inputs in getActiveInputs()
- */
-#define APM_AUDIO_IN_DEVICE_VIRTUAL_ALL (AUDIO_DEVICE_IN_REMOTE_SUBMIX|\
-        AUDIO_DEVICE_IN_BUS|AUDIO_DEVICE_IN_FM_TUNER)
-
-
-/**
  * A device mask for all audio input and output devices where matching inputs/outputs on device
  * type alone is not enough: the address must match too
  */
@@ -68,23 +71,6 @@
 }
 
 /**
- * Check if the input device given is considered as a virtual device.
- *
- * @param[in] device to consider
- *
- * @return true if the device is a virtual one, false otherwise.
- */
-static inline bool is_virtual_input_device(audio_devices_t device)
-{
-    if ((device & AUDIO_DEVICE_BIT_IN) != 0) {
-        device &= ~AUDIO_DEVICE_BIT_IN;
-        if ((popcount(device) == 1) && ((device & ~APM_AUDIO_IN_DEVICE_VIRTUAL_ALL) == 0))
-            return true;
-    }
-    return false;
-}
-
-/**
  * Check whether the device type is one
  * where addresses are used to distinguish between one connected device and another
  *
@@ -101,6 +87,21 @@
 }
 
 /**
+ * Check whether audio device has encoding capability.
+ *
+ * @param[in] device to consider
+ *
+ * @return true if device has encoding capability, false otherwise..
+ */
+static inline bool device_has_encoding_capability(audio_devices_t device)
+{
+    if (device & AUDIO_DEVICE_OUT_ALL_A2DP) {
+        return true;
+    }
+    return false;
+}
+
+/**
  * Returns the priority of a given audio source for capture. The priority is used when more than one
  * capture session is active on a given input stream to determine which session drives routing and
  * effect configuration.
@@ -108,7 +109,10 @@
  * @param[in] inputSource to consider. Valid sources are:
  * - AUDIO_SOURCE_VOICE_COMMUNICATION
  * - AUDIO_SOURCE_CAMCORDER
+ * - AUDIO_SOURCE_VOICE_PERFORMANCE
+ * - AUDIO_SOURCE_UNPROCESSED
  * - AUDIO_SOURCE_MIC
+ * - AUDIO_SOURCE_ECHO_REFERENCE
  * - AUDIO_SOURCE_FM_TUNER
  * - AUDIO_SOURCE_VOICE_RECOGNITION
  * - AUDIO_SOURCE_HOTWORD
@@ -121,10 +125,16 @@
 {
     switch (inputSource) {
     case AUDIO_SOURCE_VOICE_COMMUNICATION:
-        return 6;
+        return 9;
     case AUDIO_SOURCE_CAMCORDER:
-        return 5;
+        return 8;
+    case AUDIO_SOURCE_VOICE_PERFORMANCE:
+        return 7;
+    case AUDIO_SOURCE_UNPROCESSED:
+        return 6;
     case AUDIO_SOURCE_MIC:
+        return 5;
+    case AUDIO_SOURCE_ECHO_REFERENCE:
         return 4;
     case AUDIO_SOURCE_FM_TUNER:
         return 3;
@@ -152,3 +162,25 @@
     }
     return format1 == format2;
 }
+
+/**
+ * @brief hasStream checks if a given stream type is found in the list of streams
+ * @param streams collection of stream types to consider.
+ * @param streamType to consider
+ * @return true if voice stream is found in the given streams, false otherwise
+ */
+static inline bool hasStream(const android::StreamTypeVector &streams,
+                             audio_stream_type_t streamType)
+{
+    return std::find(begin(streams), end(streams), streamType) != end(streams);
+}
+
+/**
+ * @brief hasVoiceStream checks if a voice stream is found in the list of streams
+ * @param streams collection to consider.
+ * @return true if voice stream is found in the given streams, false otherwise
+ */
+static inline bool hasVoiceStream(const android::StreamTypeVector &streams)
+{
+    return hasStream(streams, AUDIO_STREAM_VOICE_CALL);
+}
diff --git a/services/audiopolicy/common/managerdefinitions/Android.bp b/services/audiopolicy/common/managerdefinitions/Android.bp
new file mode 100644
index 0000000..f02f3cf
--- /dev/null
+++ b/services/audiopolicy/common/managerdefinitions/Android.bp
@@ -0,0 +1,52 @@
+cc_library_static {
+    name: "libaudiopolicycomponents",
+
+    srcs: [
+        "src/AudioCollections.cpp",
+        "src/AudioGain.cpp",
+        "src/AudioInputDescriptor.cpp",
+        "src/AudioOutputDescriptor.cpp",
+        "src/AudioPatch.cpp",
+        "src/AudioPolicyMix.cpp",
+        "src/AudioPort.cpp",
+        "src/AudioProfile.cpp",
+        "src/AudioRoute.cpp",
+        "src/ClientDescriptor.cpp",
+        "src/DeviceDescriptor.cpp",
+        "src/EffectDescriptor.cpp",
+        "src/HwModule.cpp",
+        "src/IOProfile.cpp",
+        "src/Serializer.cpp",
+        "src/SoundTriggerSession.cpp",
+        "src/TypeConverter.cpp",
+    ],
+    shared_libs: [
+        "libcutils",
+        "libhidlbase",
+        "liblog",
+        "libmedia",
+        "libutils",
+        "libxml2",
+    ],
+    export_shared_lib_headers: ["libmedia"],
+    static_libs: [
+        "libaudioutils",
+    ],
+    header_libs: [
+        "libaudiopolicycommon",
+        "libaudiopolicymanager_interface_headers",
+    ],
+    export_header_lib_headers: ["libaudiopolicycommon"],
+
+    include_dirs: [
+        "frameworks/av/services/audiopolicy",
+    ],
+
+    export_include_dirs: ["include"],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+
+}
diff --git a/services/audiopolicy/common/managerdefinitions/Android.mk b/services/audiopolicy/common/managerdefinitions/Android.mk
deleted file mode 100644
index e69e687..0000000
--- a/services/audiopolicy/common/managerdefinitions/Android.mk
+++ /dev/null
@@ -1,69 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-    src/DeviceDescriptor.cpp \
-    src/AudioGain.cpp \
-    src/HwModule.cpp \
-    src/IOProfile.cpp \
-    src/AudioPort.cpp \
-    src/AudioProfile.cpp \
-    src/AudioRoute.cpp \
-    src/AudioPolicyMix.cpp \
-    src/AudioPatch.cpp \
-    src/AudioInputDescriptor.cpp \
-    src/AudioOutputDescriptor.cpp \
-    src/AudioCollections.cpp \
-    src/EffectDescriptor.cpp \
-    src/SoundTriggerSession.cpp \
-    src/SessionRoute.cpp \
-    src/AudioSourceDescriptor.cpp \
-    src/VolumeCurve.cpp \
-    src/TypeConverter.cpp \
-    src/AudioSession.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-    libcutils \
-    libmedia \
-    libutils \
-    liblog \
-
-LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := libmedia
-
-LOCAL_C_INCLUDES := \
-    $(LOCAL_PATH)/include \
-    frameworks/av/services/audiopolicy/common/include \
-    frameworks/av/services/audiopolicy \
-    frameworks/av/services/audiopolicy/utilities \
-    system/media/audio_utils/include \
-
-ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
-
-LOCAL_SRC_FILES += src/Serializer.cpp
-
-LOCAL_SHARED_LIBRARIES += libicuuc libxml2
-
-LOCAL_C_INCLUDES += \
-    external/libxml2/include \
-    external/icu/icu4c/source/common
-
-else
-
-LOCAL_SRC_FILES += \
-    src/ConfigParsingUtils.cpp \
-    src/StreamDescriptor.cpp \
-    src/Gains.cpp
-
-endif #ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := \
-    $(LOCAL_PATH)/include
-
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
-LOCAL_CFLAGS := -Wall -Werror
-
-LOCAL_MODULE := libaudiopolicycomponents
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioCollections.h b/services/audiopolicy/common/managerdefinitions/include/AudioCollections.h
index f86e75a..a948ea9 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioCollections.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioCollections.h
@@ -38,7 +38,7 @@
 class AudioRouteVector : public Vector<sp<AudioRoute> >
 {
 public:
-    status_t dump(int fd, int spaces) const;
+    void dump(String8 *dst, int spaces) const;
 };
 
 } // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioGain.h b/services/audiopolicy/common/managerdefinitions/include/AudioGain.h
index 4ac508f..4af93e1 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioGain.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioGain.h
@@ -18,7 +18,9 @@
 
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
+#include <utils/String8.h>
 #include <system/audio.h>
+#include <vector>
 
 namespace android {
 
@@ -53,17 +55,41 @@
     int getMaxRampInMs() const { return mGain.max_ramp_ms; }
 
     // TODO: remove dump from here (split serialization)
-    void dump(int fd, int spaces, int index) const;
+    void dump(String8 *dst, int spaces, int index) const;
 
     void getDefaultConfig(struct audio_gain_config *config);
     status_t checkConfig(const struct audio_gain_config *config);
 
+    void setUseForVolume(bool canUseForVolume) { mUseForVolume = canUseForVolume; }
+    bool canUseForVolume() const { return mUseForVolume; }
+
     const struct audio_gain &getGain() const { return mGain; }
 
 private:
     int               mIndex;
     struct audio_gain mGain;
     bool              mUseInChannelMask;
+    bool              mUseForVolume = false;
+};
+
+class AudioGains : public std::vector<sp<AudioGain> >
+{
+public:
+    bool canUseForVolume() const
+    {
+        for (const auto &gain: *this) {
+            if (gain->canUseForVolume()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    int32_t add(const sp<AudioGain> gain)
+    {
+        push_back(gain);
+        return 0;
+    }
 };
 
 } // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h b/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
new file mode 100644
index 0000000..6e29632
--- /dev/null
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "DeviceDescriptor.h"
+
+namespace android {
+
+/**
+ * Interface for I/O descriptors to implement so information about their context
+ * can be queried and updated.
+ */
+class AudioIODescriptorInterface
+{
+public:
+    virtual ~AudioIODescriptorInterface() {};
+
+    virtual audio_config_base_t getConfig() const = 0;
+
+    virtual audio_patch_handle_t getPatchHandle() const = 0;
+
+    virtual void setPatchHandle(audio_patch_handle_t handle) = 0;
+};
+
+template <class IoDescriptor, class Filter>
+sp<DeviceDescriptor> findPreferredDevice(
+        IoDescriptor& desc, Filter filter, bool& active, const DeviceVector& devices)
+{
+    auto activeClients = desc->clientsList(true /*activeOnly*/);
+    auto activeClientsWithRoute =
+        desc->clientsList(true /*activeOnly*/, filter, true /*preferredDevice*/);
+    active = activeClients.size() > 0;
+    if (active && activeClients.size() == activeClientsWithRoute.size()) {
+        return devices.getDeviceFromId(activeClientsWithRoute[0]->preferredDeviceId());
+    }
+    return nullptr;
+}
+
+template <class IoCollection, class Filter>
+sp<DeviceDescriptor> findPreferredDevice(
+        IoCollection& ioCollection, Filter filter, const DeviceVector& devices)
+{
+    sp<DeviceDescriptor> device;
+    for (size_t i = 0; i < ioCollection.size(); i++) {
+        auto desc = ioCollection.valueAt(i);
+        bool active;
+        sp<DeviceDescriptor> curDevice = findPreferredDevice(desc, filter, active, devices);
+        if (active && curDevice == nullptr) {
+            return nullptr;
+        } else if (curDevice != nullptr) {
+            device = curDevice;
+        }
+    }
+    return device;
+}
+
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
index df1cf26..37f9d14 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
@@ -16,36 +16,45 @@
 
 #pragma once
 
-#include "AudioPort.h"
-#include "AudioSession.h"
-#include "AudioSessionInfoProvider.h"
-#include <utils/Errors.h>
 #include <system/audio.h>
+#include <utils/Errors.h>
 #include <utils/SortedVector.h>
 #include <utils/KeyedVector.h>
+#include "AudioIODescriptorInterface.h"
+#include "AudioPort.h"
+#include "ClientDescriptor.h"
+#include "DeviceDescriptor.h"
+#include "EffectDescriptor.h"
+#include "IOProfile.h"
 
 namespace android {
 
-class IOProfile;
 class AudioPolicyMix;
+class AudioPolicyClientInterface;
 
 // descriptor for audio inputs. Used to maintain current configuration of each opened audio input
 // and keep track of the usage of this input.
-class AudioInputDescriptor: public AudioPortConfig, public AudioSessionInfoProvider
+class AudioInputDescriptor: public AudioPortConfig, public AudioIODescriptorInterface
+    , public ClientMapHandler<RecordClientDescriptor>
 {
 public:
     explicit AudioInputDescriptor(const sp<IOProfile>& profile,
                                   AudioPolicyClientInterface *clientInterface);
     audio_port_handle_t getId() const;
     audio_module_handle_t getModuleHandle() const;
-    uint32_t getOpenRefCount() const;
 
-    status_t    dump(int fd);
+    audio_devices_t getDeviceType() const { return (mDevice != nullptr) ?
+                    mDevice->type() : AUDIO_DEVICE_NONE; }
+    sp<DeviceDescriptor> getDevice() const { return mDevice; }
+    void setDevice(const sp<DeviceDescriptor> &device) { mDevice = device; }
+    DeviceVector supportedDevices() const  {
+        return mProfile != nullptr ? mProfile->getSupportedDevices() :  DeviceVector(); }
 
-    audio_io_handle_t             mIoHandle;       // input handle
-    audio_devices_t               mDevice;         // current device this input is routed to
-    wp<AudioPolicyMix>            mPolicyMix;      // non NULL when used by a dynamic policy
-    const sp<IOProfile>           mProfile;        // I/O profile this output derives from
+    void dump(String8 *dst) const override;
+
+    audio_io_handle_t   mIoHandle = AUDIO_IO_HANDLE_NONE; // input handle
+    wp<AudioPolicyMix>  mPolicyMix;                   // non NULL when used by a dynamic policy
+    const sp<IOProfile> mProfile;                     // I/O profile this output derives from
 
     virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
             const struct audio_port_config *srcConfig = NULL) const;
@@ -55,43 +64,56 @@
     SortedVector<audio_session_t> getPreemptedSessions() const;
     bool hasPreemptedSession(audio_session_t session) const;
     void clearPreemptedSessions();
-    bool isActive() const;
+    bool isActive() const { return mGlobalActiveCount > 0; }
     bool isSourceActive(audio_source_t source) const;
-    audio_source_t inputSource(bool activeOnly = false) const;
+    audio_source_t source() const;
     bool isSoundTrigger() const;
-    status_t addAudioSession(audio_session_t session,
-                             const sp<AudioSession>& audioSession);
-    status_t removeAudioSession(audio_session_t session);
-    sp<AudioSession> getAudioSession(audio_session_t session) const;
-    AudioSessionCollection getAudioSessions(bool activeOnly) const;
-    size_t getAudioSessionCount(bool activeOnly) const;
-    audio_source_t getHighestPrioritySource(bool activeOnly) const;
-
-    // implementation of AudioSessionInfoProvider
-    virtual audio_config_base_t getConfig() const;
-    virtual audio_patch_handle_t getPatchHandle() const;
-
-    void setPatchHandle(audio_patch_handle_t handle);
+    sp<RecordClientDescriptor> getHighestPriorityClient() const;
+    audio_attributes_t getHighestPriorityAttributes() const;
+    void setClientActive(const sp<RecordClientDescriptor>& client, bool active);
+    int32_t activeCount() { return mGlobalActiveCount; }
+    void trackEffectEnabled(const sp<EffectDescriptor> &effect, bool enabled);
+    EffectDescriptorCollection getEnabledEffects() const;
+    EffectDescriptorCollection getActiveEffects() const; // enabled and not suspended
+    // implementation of AudioIODescriptorInterface
+    audio_config_base_t getConfig() const override;
+    audio_patch_handle_t getPatchHandle() const override;
+    void setPatchHandle(audio_patch_handle_t handle) override;
 
     status_t open(const audio_config_t *config,
-                  audio_devices_t device,
-                  const String8& address,
+                  const sp<DeviceDescriptor> &device,
                   audio_source_t source,
                   audio_input_flags_t flags,
                   audio_io_handle_t *input);
     // Called when a stream is about to be started.
-    // Note: called after AudioSession::changeActiveCount(1)
+    // Note: called after setClientActive(client, true)
     status_t start();
     // Called after a stream is stopped
-    // Note: called after AudioSession::changeActiveCount(-1)
+    // Note: called after setClientActive(client, false)
     void stop();
     void close();
 
-private:
-    audio_patch_handle_t          mPatchHandle;
-    audio_port_handle_t           mId;
-    // audio sessions attached to this input
-    AudioSessionCollection        mSessions;
+    RecordClientVector getClientsForSession(audio_session_t session);
+    RecordClientVector clientsList(bool activeOnly = false,
+        audio_source_t source = AUDIO_SOURCE_DEFAULT, bool preferredDeviceOnly = false) const;
+
+    void setAppState(uid_t uid, app_state_t state);
+
+    // implementation of ClientMapHandler<RecordClientDescriptor>
+    void addClient(const sp<RecordClientDescriptor> &client) override;
+
+    // Go over all active clients and suspend or restore effects according highest priority
+    // active use case
+    void checkSuspendEffects();
+
+ private:
+
+    void updateClientRecordingConfiguration(int event, const sp<RecordClientDescriptor>& client);
+
+    audio_patch_handle_t mPatchHandle = AUDIO_PATCH_HANDLE_NONE;
+    audio_port_handle_t  mId = AUDIO_PORT_HANDLE_NONE;
+    sp<DeviceDescriptor> mDevice = nullptr; /**< current device this input is routed to */
+
     // Because a preemptible capture session can preempt another one, we end up in an endless loop
     // situation were each session is allowed to restart after being preempted,
     // thus preempting the other one which restarts and so on.
@@ -99,7 +121,9 @@
     // a particular input started and prevent preemption of this active input by this session.
     // We also inherit sessions from the preempted input to avoid a 3 way preemption loop etc...
     SortedVector<audio_session_t> mPreemptedSessions;
-    AudioPolicyClientInterface *mClientInterface;
+    AudioPolicyClientInterface * const mClientInterface;
+    int32_t mGlobalActiveCount = 0;  // non-client-specific activity ref count
+    EffectDescriptorCollection mEnabledEffects;
 };
 
 class AudioInputCollection :
@@ -111,19 +135,31 @@
     sp<AudioInputDescriptor> getInputFromId(audio_port_handle_t id) const;
 
     // count active capture sessions using one of the specified devices.
-    // ignore devices if AUDIO_DEVICE_IN_DEFAULT is passed
-    uint32_t activeInputsCountOnDevices(audio_devices_t devices = AUDIO_DEVICE_IN_DEFAULT) const;
+    // ignore devices if empty vector is passed
+    uint32_t activeInputsCountOnDevices(const DeviceVector &devices) const;
 
     /**
      * return io handle of active input or 0 if no input is active
      * Only considers inputs from physical devices (e.g. main mic, headset mic) when
      * ignoreVirtualInputs is true.
      */
-    Vector<sp <AudioInputDescriptor> > getActiveInputs(bool ignoreVirtualInputs = true);
+    Vector<sp <AudioInputDescriptor> > getActiveInputs();
 
-    audio_devices_t getSupportedDevices(audio_io_handle_t handle) const;
+    sp<AudioInputDescriptor> getInputForClient(audio_port_handle_t portId);
 
-    status_t dump(int fd) const;
+    void trackEffectEnabled(const sp<EffectDescriptor> &effect, bool enabled);
+
+    /**
+    * @brief clearSessionRoutesForDevice: when a device is disconnected, and if this device has
+    * been chosen as the preferred device by any client, the policy manager shall
+    * prevent from using this device any more by clearing all the session routes involving this
+    * device.
+    * In other words, the preferred device port id of these clients will be resetted to NONE.
+    * @param disconnectedDevice device to be disconnected
+    */
+    void clearSessionRoutesForDevice(const sp<DeviceDescriptor> &disconnectedDevice);
+
+    void dump(String8 *dst) const;
 };
 
 
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index 247f20f..cd54085 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -16,55 +16,234 @@
 
 #pragma once
 
+#define __STDC_LIMIT_MACROS
+#include <inttypes.h>
+
 #include <sys/types.h>
 
-#include "AudioPort.h"
-#include <RoutingStrategy.h>
 #include <utils/Errors.h>
 #include <utils/Timers.h>
 #include <utils/KeyedVector.h>
 #include <system/audio.h>
-#include "AudioSourceDescriptor.h"
+#include "AudioIODescriptorInterface.h"
+#include "AudioPort.h"
+#include "ClientDescriptor.h"
+#include "DeviceDescriptor.h"
+#include <vector>
 
 namespace android {
 
 class IOProfile;
 class AudioPolicyMix;
 class AudioPolicyClientInterface;
-class DeviceDescriptor;
+
+class ActivityTracking
+{
+public:
+    virtual ~ActivityTracking() = default;
+    bool isActive(uint32_t inPastMs = 0, nsecs_t sysTime = 0) const
+    {
+        if (mActivityCount > 0) {
+            return true;
+        }
+        if (inPastMs == 0) {
+            return false;
+        }
+        if (sysTime == 0) {
+            sysTime = systemTime();
+        }
+        if (ns2ms(sysTime - mStopTime) < inPastMs) {
+            return true;
+        }
+        return false;
+    }
+    void changeActivityCount(int delta)
+    {
+        if ((delta + (int)mActivityCount) < 0) {
+            LOG_ALWAYS_FATAL("%s: invalid delta %d, refCount %d", __func__, delta, mActivityCount);
+        }
+        mActivityCount += delta;
+        if (!mActivityCount) {
+            setStopTime(systemTime());
+        }
+    }
+    uint32_t getActivityCount() const { return mActivityCount; }
+    nsecs_t getStopTime() const { return mStopTime; }
+    void setStopTime(nsecs_t stopTime) { mStopTime = stopTime; }
+
+    virtual void dump(String8 *dst, int spaces) const
+    {
+        dst->appendFormat("%*s- ActivityCount: %d, StopTime: %" PRId64 ", ", spaces, "",
+                          getActivityCount(), getStopTime());
+    }
+private:
+    uint32_t mActivityCount = 0;
+    nsecs_t mStopTime = 0;
+};
+
+/**
+ * @brief VolumeActivity: it tracks the activity for volume policy (volume index, mute,
+ * memorize previous stop, and store mute if incompatible device with another strategy.
+ */
+class VolumeActivity : public ActivityTracking
+{
+public:
+    bool isMuted() const { return mMuteCount > 0; }
+    int getMuteCount() const { return mMuteCount; }
+    int incMuteCount() { return ++mMuteCount; }
+    int decMuteCount() { return mMuteCount > 0 ? --mMuteCount : -1; }
+
+    void dump(String8 *dst, int spaces) const override
+    {
+        ActivityTracking::dump(dst, spaces);
+        dst->appendFormat(", Volume: %.03f, MuteCount: %02d\n", mCurVolumeDb, mMuteCount);
+    }
+    void setVolume(float volumeDb) { mCurVolumeDb = volumeDb; }
+    float getVolume() const { return mCurVolumeDb; }
+
+private:
+    int mMuteCount = 0; /**< mute request counter */
+    float mCurVolumeDb = NAN; /**< current volume in dB. */
+};
+/**
+ * Note: volume activities shall be indexed by CurvesId if we want to allow multiple
+ * curves per volume source, inferring a mute management or volume balancing between HW and SW is
+ * done
+ */
+using VolumeActivities = std::map<VolumeSource, VolumeActivity>;
+
+/**
+ * @brief The Activity class: it tracks the activity for volume policy (volume index, mute,
+ * memorize previous stop, and store mute if incompatible device with another strategy.
+ * Having this class prevents from looping on all attributes (legacy streams) of the strategy
+ */
+class RoutingActivity : public ActivityTracking
+{
+public:
+    void setMutedByDevice( bool isMuted) { mIsMutedByDevice = isMuted; }
+    bool isMutedByDevice() const { return mIsMutedByDevice; }
+
+    void dump(String8 *dst, int spaces) const override {
+        ActivityTracking::dump(dst, spaces);
+        dst->appendFormat("\n");
+    }
+private:
+    /**
+     * strategies muted because of incompatible device selection.
+     * See AudioPolicyManager::checkDeviceMuteStrategies()
+     */
+    bool mIsMutedByDevice = false;
+};
+using RoutingActivities = std::map<product_strategy_t, RoutingActivity>;
 
 // descriptor for audio outputs. Used to maintain current configuration of each opened audio output
 // and keep track of the usage of this output by each audio stream type.
-class AudioOutputDescriptor: public AudioPortConfig
+class AudioOutputDescriptor: public AudioPortConfig, public AudioIODescriptorInterface
+    , public ClientMapHandler<TrackClientDescriptor>
 {
 public:
     AudioOutputDescriptor(const sp<AudioPort>& port,
                           AudioPolicyClientInterface *clientInterface);
     virtual ~AudioOutputDescriptor() {}
 
-    status_t    dump(int fd);
+    void dump(String8 *dst) const override;
     void        log(const char* indent);
 
     audio_port_handle_t getId() const;
-    virtual audio_devices_t device() const;
-    virtual bool sharesHwModuleWith(const sp<AudioOutputDescriptor>& outputDesc);
-    virtual audio_devices_t supportedDevices();
+    virtual DeviceVector devices() const { return mDevices; }
+    bool sharesHwModuleWith(const sp<AudioOutputDescriptor>& outputDesc);
+    virtual DeviceVector supportedDevices() const  { return mDevices; }
     virtual bool isDuplicated() const { return false; }
     virtual uint32_t latency() { return 0; }
     virtual bool isFixedVolume(audio_devices_t device);
-    virtual sp<AudioOutputDescriptor> subOutput1() { return 0; }
-    virtual sp<AudioOutputDescriptor> subOutput2() { return 0; }
-    virtual bool setVolume(float volume,
-                           audio_stream_type_t stream,
+    virtual bool setVolume(float volumeDb,
+                           VolumeSource volumeSource, const StreamTypeVector &streams,
                            audio_devices_t device,
                            uint32_t delayMs,
                            bool force);
-    virtual void changeRefCount(audio_stream_type_t stream, int delta);
 
-    bool isActive(uint32_t inPastMs = 0) const;
-    bool isStreamActive(audio_stream_type_t stream,
-                        uint32_t inPastMs = 0,
-                        nsecs_t sysTime = 0) const;
+    /**
+     * @brief setStopTime set the stop time due to the client stoppage or a re routing of this
+     * client
+     * @param client to be considered
+     * @param sysTime when the client stopped/was rerouted
+     */
+    void setStopTime(const sp<TrackClientDescriptor>& client, nsecs_t sysTime);
+
+    /**
+     * Changes the client->active() state and the output descriptor's global active count,
+     * along with the stream active count and mActiveClients.
+     * The client must be previously added by the base class addClient().
+     * In case of duplicating thread, client shall be added on the duplicated thread, not on the
+     * involved outputs but setClientActive will be called on all output to track strategy and
+     * active client for a given output.
+     * Active ref count of the client will be incremented/decremented through setActive API
+     */
+    virtual void setClientActive(const sp<TrackClientDescriptor>& client, bool active);
+
+    bool isActive(uint32_t inPastMs) const;
+    bool isActive(VolumeSource volumeSource = VOLUME_SOURCE_NONE,
+                  uint32_t inPastMs = 0,
+                  nsecs_t sysTime = 0) const;
+    bool isAnyActive(VolumeSource volumeSourceToIgnore) const;
+
+    std::vector<VolumeSource> getActiveVolumeSources() const {
+        std::vector<VolumeSource> activeList;
+        for (const auto &iter : mVolumeActivities) {
+            if (iter.second.isActive()) {
+                activeList.push_back(iter.first);
+            }
+        }
+        return activeList;
+    }
+    uint32_t getActivityCount(VolumeSource vs) const
+    {
+        return mVolumeActivities.find(vs) != std::end(mVolumeActivities)?
+                    mVolumeActivities.at(vs).getActivityCount() : 0;
+    }
+    bool isMuted(VolumeSource vs) const
+    {
+        return mVolumeActivities.find(vs) != std::end(mVolumeActivities)?
+                    mVolumeActivities.at(vs).isMuted() : false;
+    }
+    int getMuteCount(VolumeSource vs) const
+    {
+        return mVolumeActivities.find(vs) != std::end(mVolumeActivities)?
+                    mVolumeActivities.at(vs).getMuteCount() : 0;
+    }
+    int incMuteCount(VolumeSource vs)
+    {
+        return mVolumeActivities[vs].incMuteCount();
+    }
+    int decMuteCount(VolumeSource vs)
+    {
+        return mVolumeActivities[vs].decMuteCount();
+    }
+    void setCurVolume(VolumeSource vs, float volumeDb)
+    {
+        // Even if not activity for this source registered, need to create anyway
+        mVolumeActivities[vs].setVolume(volumeDb);
+    }
+    float getCurVolume(VolumeSource vs) const
+    {
+        return mVolumeActivities.find(vs) != std::end(mVolumeActivities) ?
+                    mVolumeActivities.at(vs).getVolume() : NAN;
+    }
+
+    bool isStrategyActive(product_strategy_t ps, uint32_t inPastMs = 0, nsecs_t sysTime = 0) const
+    {
+        return mRoutingActivities.find(ps) != std::end(mRoutingActivities)?
+                    mRoutingActivities.at(ps).isActive(inPastMs, sysTime) : false;
+    }
+    bool isStrategyMutedByDevice(product_strategy_t ps) const
+    {
+        return mRoutingActivities.find(ps) != std::end(mRoutingActivities)?
+                    mRoutingActivities.at(ps).isMutedByDevice() : false;
+    }
+    void setStrategyMutedByDevice(product_strategy_t ps, bool isMuted)
+    {
+        mRoutingActivities[ps].setMutedByDevice(isMuted);
+    }
 
     virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
                            const struct audio_port_config *srcConfig = NULL) const;
@@ -73,22 +252,58 @@
 
     audio_module_handle_t getModuleHandle() const;
 
-    audio_patch_handle_t getPatchHandle() const { return mPatchHandle; };
-    void setPatchHandle(audio_patch_handle_t handle) { mPatchHandle = handle; };
+    // implementation of AudioIODescriptorInterface
+    audio_config_base_t getConfig() const override;
+    audio_patch_handle_t getPatchHandle() const override;
+    void setPatchHandle(audio_patch_handle_t handle) override;
 
-    sp<AudioPort>       mPort;
-    audio_devices_t mDevice;                   // current device this output is routed to
-    uint32_t mRefCount[AUDIO_STREAM_CNT]; // number of streams of each type using this output
-    nsecs_t mStopTime[AUDIO_STREAM_CNT];
-    float mCurVolume[AUDIO_STREAM_CNT];   // current stream volume in dB
-    int mMuteCount[AUDIO_STREAM_CNT];     // mute request counter
-    bool mStrategyMutedByDevice[NUM_STRATEGIES]; // strategies muted because of incompatible
-                                        // device selection. See checkDeviceMuteStrategies()
-    AudioPolicyClientInterface *mClientInterface;
+    TrackClientVector clientsList(bool activeOnly = false,
+                                  product_strategy_t strategy = PRODUCT_STRATEGY_NONE,
+                                  bool preferredDeviceOnly = false) const;
+
+    // override ClientMapHandler to abort when removing a client when active.
+    void removeClient(audio_port_handle_t portId) override {
+        auto client = getClient(portId);
+        LOG_ALWAYS_FATAL_IF(client.get() == nullptr,
+                "%s(%d): nonexistent client portId %d", __func__, mId, portId);
+        // it is possible that when a client is removed, we could remove its
+        // associated active count by calling changeStreamActiveCount(),
+        // but that would be hiding a problem, so we log fatal instead.
+        auto clientIter = std::find(begin(mActiveClients), end(mActiveClients), client);
+        LOG_ALWAYS_FATAL_IF(clientIter != mActiveClients.end(),
+                            "%s(%d) removing client portId %d which is active (count %d)",
+                            __func__, mId, portId, client->getActivityCount());
+        ClientMapHandler<TrackClientDescriptor>::removeClient(portId);
+    }
+
+    const TrackClientVector& getActiveClients() const {
+        return mActiveClients;
+    }
+
+    bool useHwGain() const
+    {
+        return !devices().isEmpty() ? devices().itemAt(0)->hasGainController() : false;
+    }
+
+    DeviceVector mDevices; /**< current devices this output is routed to */
+    wp<AudioPolicyMix> mPolicyMix;  // non NULL when used by a dynamic policy
 
 protected:
-    audio_patch_handle_t mPatchHandle;
-    audio_port_handle_t mId;
+    const sp<AudioPort> mPort;
+    AudioPolicyClientInterface * const mClientInterface;
+    uint32_t mGlobalActiveCount = 0;  // non-client-specific active count
+    audio_patch_handle_t mPatchHandle = AUDIO_PATCH_HANDLE_NONE;
+    audio_port_handle_t mId = AUDIO_PORT_HANDLE_NONE;
+
+    // The ActiveClients shows the clients that contribute to the @VolumeSource counts
+    // and may include upstream clients from a duplicating thread.
+    // Compare with the ClientMap (mClients) which are external AudioTrack clients of the
+    // output descriptor (and do not count internal PatchTracks).
+    TrackClientVector mActiveClients;
+
+    RoutingActivities mRoutingActivities; /**< track routing activity on this ouput.*/
+
+    VolumeActivities mVolumeActivities; /**< track volume activity on this ouput.*/
 };
 
 // Audio output driven by a software mixer in audio flinger.
@@ -99,19 +314,26 @@
                             AudioPolicyClientInterface *clientInterface);
     virtual ~SwAudioOutputDescriptor() {}
 
-    status_t    dump(int fd);
-
-    virtual audio_devices_t device() const;
-    virtual bool sharesHwModuleWith(const sp<AudioOutputDescriptor>& outputDesc);
-    virtual audio_devices_t supportedDevices();
+            void dump(String8 *dst) const override;
+    virtual DeviceVector devices() const;
+    void setDevices(const DeviceVector &devices) { mDevices = devices; }
+    bool sharesHwModuleWith(const sp<SwAudioOutputDescriptor>& outputDesc);
+    virtual DeviceVector supportedDevices() const;
+    virtual bool deviceSupportsEncodedFormats(audio_devices_t device);
     virtual uint32_t latency();
     virtual bool isDuplicated() const { return (mOutput1 != NULL && mOutput2 != NULL); }
     virtual bool isFixedVolume(audio_devices_t device);
-    virtual sp<AudioOutputDescriptor> subOutput1() { return mOutput1; }
-    virtual sp<AudioOutputDescriptor> subOutput2() { return mOutput2; }
-    virtual void changeRefCount(audio_stream_type_t stream, int delta);
-    virtual bool setVolume(float volume,
-                           audio_stream_type_t stream,
+    sp<SwAudioOutputDescriptor> subOutput1() { return mOutput1; }
+    sp<SwAudioOutputDescriptor> subOutput2() { return mOutput2; }
+    void setClientActive(const sp<TrackClientDescriptor>& client, bool active) override;
+    void setAllClientsInactive()
+    {
+        for (const auto &client : clientsList(true)) {
+            setClientActive(client, false);
+        }
+    }
+    virtual bool setVolume(float volumeDb,
+                           VolumeSource volumeSource, const StreamTypeVector &streams,
                            audio_devices_t device,
                            uint32_t delayMs,
                            bool force);
@@ -120,48 +342,72 @@
                            const struct audio_port_config *srcConfig = NULL) const;
     virtual void toAudioPort(struct audio_port *port) const;
 
-            status_t open(const audio_config_t *config,
-                          audio_devices_t device,
-                          const String8& address,
-                          audio_stream_type_t stream,
-                          audio_output_flags_t flags,
-                          audio_io_handle_t *output);
-            // Called when a stream is about to be started
-            // Note: called before changeRefCount(1);
-            status_t start();
-            // Called after a stream is stopped.
-            // Note: called after changeRefCount(-1);
-            void stop();
-            void close();
-            status_t openDuplicating(const sp<SwAudioOutputDescriptor>& output1,
-                                     const sp<SwAudioOutputDescriptor>& output2,
-                                     audio_io_handle_t *ioHandle);
+        status_t open(const audio_config_t *config,
+                      const DeviceVector &devices,
+                      audio_stream_type_t stream,
+                      audio_output_flags_t flags,
+                      audio_io_handle_t *output);
+
+        // Called when a stream is about to be started
+        // Note: called before setClientActive(true);
+        status_t start();
+        // Called after a stream is stopped.
+        // Note: called after setClientActive(false);
+        void stop();
+        void close();
+        status_t openDuplicating(const sp<SwAudioOutputDescriptor>& output1,
+                                 const sp<SwAudioOutputDescriptor>& output2,
+                                 audio_io_handle_t *ioHandle);
+
+    /**
+     * @brief supportsDevice
+     * @param device to be checked against
+     * @return true if the device is supported by type (for non bus / remote submix devices),
+     *         true if the device is supported (both type and address) for bus / remote submix
+     *         false otherwise
+     */
+    bool supportsDevice(const sp<DeviceDescriptor> &device) const;
+
+    /**
+     * @brief supportsAllDevices
+     * @param devices to be checked against
+     * @return true if the device is weakly supported by type (e.g. for non bus / rsubmix devices),
+     *         true if the device is supported (both type and address) for bus / remote submix
+     *         false otherwise
+     */
+    bool supportsAllDevices(const DeviceVector &devices) const;
+
+    /**
+     * @brief filterSupportedDevices takes a vector of devices and filters them according to the
+     * device supported by this output (the profile from which this output derives from)
+     * @param devices reference device vector to be filtered
+     * @return vector of devices filtered from the supported devices of this output (weakly or not
+     * depending on the device type)
+     */
+    DeviceVector filterSupportedDevices(const DeviceVector &devices) const;
 
     const sp<IOProfile> mProfile;          // I/O profile this output derives from
     audio_io_handle_t mIoHandle;           // output handle
     uint32_t mLatency;                  //
     audio_output_flags_t mFlags;   //
-    wp<AudioPolicyMix> mPolicyMix;           // non NULL when used by a dynamic policy
     sp<SwAudioOutputDescriptor> mOutput1;    // used by duplicated outputs: first output
     sp<SwAudioOutputDescriptor> mOutput2;    // used by duplicated outputs: second output
     uint32_t mDirectOpenCount; // number of clients using this output (direct outputs only)
     audio_session_t mDirectClientSession; // session id of the direct output client
-    uint32_t mGlobalRefCount;  // non-stream-specific ref count
 };
 
 // Audio output driven by an input device directly.
 class HwAudioOutputDescriptor: public AudioOutputDescriptor
 {
 public:
-    HwAudioOutputDescriptor(const sp<AudioSourceDescriptor>& source,
+    HwAudioOutputDescriptor(const sp<SourceClientDescriptor>& source,
                             AudioPolicyClientInterface *clientInterface);
     virtual ~HwAudioOutputDescriptor() {}
 
-    status_t    dump(int fd);
+            void dump(String8 *dst) const override;
 
-    virtual audio_devices_t supportedDevices();
-    virtual bool setVolume(float volume,
-                           audio_stream_type_t stream,
+    virtual bool setVolume(float volumeDb,
+                           VolumeSource volumeSource, const StreamTypeVector &streams,
                            audio_devices_t device,
                            uint32_t delayMs,
                            bool force);
@@ -170,7 +416,7 @@
                            const struct audio_port_config *srcConfig = NULL) const;
     virtual void toAudioPort(struct audio_port *port) const;
 
-    const sp<AudioSourceDescriptor> mSource;
+    const sp<SourceClientDescriptor> mSource;
 
 };
 
@@ -178,25 +424,52 @@
         public DefaultKeyedVector< audio_io_handle_t, sp<SwAudioOutputDescriptor> >
 {
 public:
-    bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const;
+    bool isActive(VolumeSource volumeSource, uint32_t inPastMs = 0) const;
 
     /**
-     * return whether a stream is playing remotely, override to change the definition of
+     * return whether any source contributing to VolumeSource is playing remotely, override
+     * to change the definition of
      * local/remote playback, used for instance by notification manager to not make
      * media players lose audio focus when not playing locally
      * For the base implementation, "remotely" means playing during screen mirroring which
      * uses an output for playback with a non-empty, non "0" address.
      */
-    bool isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs = 0) const;
+    bool isActiveRemotely(VolumeSource volumeSource, uint32_t inPastMs = 0) const;
 
     /**
-     * return whether a stream is playing, but not on a "remote" device.
+     * return whether any source contributing to VolumeSource is playing, but not on a "remote"
+     * device.
      * Override to change the definition of a local/remote playback.
      * Used for instance by policy manager to alter the speaker playback ("speaker safe" behavior)
      * when media plays or not locally.
      * For the base implementation, "remotely" means playing during screen mirroring.
      */
-    bool isStreamActiveLocally(audio_stream_type_t stream, uint32_t inPastMs = 0) const;
+    bool isActiveLocally(VolumeSource volumeSource, uint32_t inPastMs = 0) const;
+
+    /**
+     * @brief isStrategyActiveOnSameModule checks if the given strategy is active (or was active
+     * in the past) on the given output and all the outputs belonging to the same HW Module
+     * the same module than the given output
+     * @param outputDesc to be considered
+     * @param ps product strategy to be checked upon activity status
+     * @param inPastMs if 0, check currently, otherwise, check in the past
+     * @param sysTime shall be set if request is done for the past activity.
+     * @return true if an output following the strategy is active on the same module than desc,
+     * false otherwise
+     */
+    bool isStrategyActiveOnSameModule(product_strategy_t ps,
+                                      const sp<SwAudioOutputDescriptor>& desc,
+                                      uint32_t inPastMs = 0, nsecs_t sysTime = 0) const;
+
+    /**
+     * @brief clearSessionRoutesForDevice: when a device is disconnected, and if this device has
+     * been chosen as the preferred device by any client, the policy manager shall
+     * prevent from using this device any more by clearing all the session routes involving this
+     * device.
+     * In other words, the preferred device port id of these clients will be resetted to NONE.
+     * @param disconnectedDevice device to be disconnected
+     */
+    void clearSessionRoutesForDevice(const sp<DeviceDescriptor> &disconnectedDevice);
 
     /**
      * returns the A2DP output handle if it is open or 0 otherwise
@@ -218,27 +491,53 @@
     sp<SwAudioOutputDescriptor> getPrimaryOutput() const;
 
     /**
-     * return true if any output is playing anything besides the stream to ignore
+     * @brief isAnyOutputActive checks if any output is active (aka playing) except the one(s) that
+     * hold the volume source to be ignored
+     * @param volumeSourceToIgnore source not to be considered in the activity detection
+     * @return true if any output is active for any volume source except the one to be ignored
      */
-    bool isAnyOutputActive(audio_stream_type_t streamToIgnore) const;
+    bool isAnyOutputActive(VolumeSource volumeSourceToIgnore) const
+    {
+        for (size_t i = 0; i < size(); i++) {
+            const sp<AudioOutputDescriptor> &outputDesc = valueAt(i);
+            if (outputDesc->isAnyActive(volumeSourceToIgnore)) {
+                return true;
+            }
+        }
+        return false;
+    }
 
     audio_devices_t getSupportedDevices(audio_io_handle_t handle) const;
 
-    status_t dump(int fd) const;
+    sp<SwAudioOutputDescriptor> getOutputForClient(audio_port_handle_t portId);
+
+    void dump(String8 *dst) const;
 };
 
 class HwAudioOutputCollection :
         public DefaultKeyedVector< audio_io_handle_t, sp<HwAudioOutputDescriptor> >
 {
 public:
-    bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const;
+    bool isActive(VolumeSource volumeSource, uint32_t inPastMs = 0) const;
 
     /**
-     * return true if any output is playing anything besides the stream to ignore
+     * @brief isAnyOutputActive checks if any output is active (aka playing) except the one(s) that
+     * hold the volume source to be ignored
+     * @param volumeSourceToIgnore source not to be considered in the activity detection
+     * @return true if any output is active for any volume source except the one to be ignored
      */
-    bool isAnyOutputActive(audio_stream_type_t streamToIgnore) const;
+    bool isAnyOutputActive(VolumeSource volumeSourceToIgnore) const
+    {
+        for (size_t i = 0; i < size(); i++) {
+            const sp<AudioOutputDescriptor> &outputDesc = valueAt(i);
+            if (outputDesc->isAnyActive(volumeSourceToIgnore)) {
+                return true;
+            }
+        }
+        return false;
+    }
 
-    status_t dump(int fd) const;
+    void dump(String8 *dst) const;
 };
 
 
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPatch.h b/services/audiopolicy/common/managerdefinitions/include/AudioPatch.h
index c1c3f3c..0843fea 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPatch.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPatch.h
@@ -22,6 +22,7 @@
 #include <utils/RefBase.h>
 #include <utils/Errors.h>
 #include <utils/KeyedVector.h>
+#include <utils/String8.h>
 
 namespace android {
 
@@ -30,7 +31,7 @@
 public:
     AudioPatch(const struct audio_patch *patch, uid_t uid);
 
-    status_t dump(int fd, int spaces, int index) const;
+    void dump(String8 *dst, int spaces, int index) const;
 
     audio_patch_handle_t mHandle;
     struct audio_patch mPatch;
@@ -47,7 +48,7 @@
 
     status_t listAudioPatches(unsigned int *num_patches, struct audio_patch *patches) const;
 
-    status_t dump(int fd) const;
+    void dump(String8 *dst) const;
 };
 
 } // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
index 43f6ed6..2264d8f 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
@@ -16,8 +16,10 @@
 
 #pragma once
 
+#include <unordered_map>
+#include <unordered_set>
+
 #include <AudioGain.h>
-#include <VolumeCurve.h>
 #include <AudioPort.h>
 #include <AudioPatch.h>
 #include <DeviceDescriptor.h>
@@ -28,7 +30,6 @@
 #include <AudioPolicyMix.h>
 #include <EffectDescriptor.h>
 #include <SoundTriggerSession.h>
-#include <SessionRoute.h>
 
 namespace android {
 
@@ -38,21 +39,20 @@
     AudioPolicyConfig(HwModuleCollection &hwModules,
                       DeviceVector &availableOutputDevices,
                       DeviceVector &availableInputDevices,
-                      sp<DeviceDescriptor> &defaultOutputDevices,
-                      VolumeCurvesCollection *volumes = nullptr)
+                      sp<DeviceDescriptor> &defaultOutputDevice)
         : mHwModules(hwModules),
           mAvailableOutputDevices(availableOutputDevices),
           mAvailableInputDevices(availableInputDevices),
-          mDefaultOutputDevices(defaultOutputDevices),
-          mVolumeCurves(volumes),
+          mDefaultOutputDevice(defaultOutputDevice),
           mIsSpeakerDrcEnabled(false)
     {}
 
-    void setVolumes(const VolumeCurvesCollection &volumes)
-    {
-        if (mVolumeCurves != nullptr) {
-            *mVolumeCurves = volumes;
-        }
+    const std::string& getSource() const {
+        return mSource;
+    }
+
+    void setSource(const std::string& file) {
+        mSource = file;
     }
 
     void setHwModules(const HwModuleCollection &hwModules)
@@ -100,51 +100,83 @@
 
     void setDefaultOutputDevice(const sp<DeviceDescriptor> &defaultDevice)
     {
-        mDefaultOutputDevices = defaultDevice;
+        mDefaultOutputDevice = defaultDevice;
     }
 
-    const sp<DeviceDescriptor> &getDefaultOutputDevice() const { return mDefaultOutputDevices; }
+    const sp<DeviceDescriptor> &getDefaultOutputDevice() const { return mDefaultOutputDevice; }
 
     void setDefault(void)
     {
-        mDefaultOutputDevices = new DeviceDescriptor(AUDIO_DEVICE_OUT_SPEAKER);
-        sp<HwModule> module;
+        mSource = "AudioPolicyConfig::setDefault";
+        mDefaultOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_SPEAKER);
+        mDefaultOutputDevice->addAudioProfile(AudioProfile::createFullDynamic());
         sp<DeviceDescriptor> defaultInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_BUILTIN_MIC);
-        mAvailableOutputDevices.add(mDefaultOutputDevices);
+        defaultInputDevice->addAudioProfile(AudioProfile::createFullDynamic());
+        sp<AudioProfile> micProfile = new AudioProfile(
+                AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_MONO, 8000);
+        defaultInputDevice->addAudioProfile(micProfile);
+        mAvailableOutputDevices.add(mDefaultOutputDevice);
         mAvailableInputDevices.add(defaultInputDevice);
 
-        module = new HwModule(AUDIO_HARDWARE_MODULE_ID_PRIMARY);
+        sp<HwModule> module = new HwModule(AUDIO_HARDWARE_MODULE_ID_PRIMARY, 2 /*halVersionMajor*/);
+        mHwModules.add(module);
+        mDefaultOutputDevice->attach(module);
+        defaultInputDevice->attach(module);
 
-        sp<OutputProfile> outProfile;
-        outProfile = new OutputProfile(String8("primary"));
-        outProfile->attach(module);
+        sp<OutputProfile> outProfile = new OutputProfile(String8("primary"));
         outProfile->addAudioProfile(
                 new AudioProfile(AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 44100));
-        outProfile->addSupportedDevice(mDefaultOutputDevices);
+        outProfile->addSupportedDevice(mDefaultOutputDevice);
         outProfile->setFlags(AUDIO_OUTPUT_FLAG_PRIMARY);
         module->addOutputProfile(outProfile);
 
-        sp<InputProfile> inProfile;
-        inProfile = new InputProfile(String8("primary"));
-        inProfile->attach(module);
-        inProfile->addAudioProfile(
-                new AudioProfile(AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_MONO, 8000));
+        sp<InputProfile> inProfile = new InputProfile(String8("primary"));
+        inProfile->addAudioProfile(micProfile);
         inProfile->addSupportedDevice(defaultInputDevice);
         module->addInputProfile(inProfile);
 
-        mHwModules.add(module);
+        setDefaultSurroundFormats();
+    }
+
+    // Surround formats, with an optional list of subformats that are equivalent from users' POV.
+    using SurroundFormats = std::unordered_map<audio_format_t, std::unordered_set<audio_format_t>>;
+
+    const SurroundFormats &getSurroundFormats() const
+    {
+        return mSurroundFormats;
+    }
+
+    void setSurroundFormats(const SurroundFormats &surroundFormats)
+    {
+        mSurroundFormats = surroundFormats;
+    }
+
+    void setDefaultSurroundFormats()
+    {
+        mSurroundFormats = {
+            {AUDIO_FORMAT_AC3, {}},
+            {AUDIO_FORMAT_E_AC3, {}},
+            {AUDIO_FORMAT_DTS, {}},
+            {AUDIO_FORMAT_DTS_HD, {}},
+            {AUDIO_FORMAT_AAC_LC, {
+                    AUDIO_FORMAT_AAC_HE_V1, AUDIO_FORMAT_AAC_HE_V2, AUDIO_FORMAT_AAC_ELD,
+                    AUDIO_FORMAT_AAC_XHE}},
+            {AUDIO_FORMAT_DOLBY_TRUEHD, {}},
+            {AUDIO_FORMAT_E_AC3_JOC, {}},
+            {AUDIO_FORMAT_AC4, {}}};
     }
 
 private:
+    std::string mSource;
     HwModuleCollection &mHwModules; /**< Collection of Module, with Profiles, i.e. Mix Ports. */
     DeviceVector &mAvailableOutputDevices;
     DeviceVector &mAvailableInputDevices;
-    sp<DeviceDescriptor> &mDefaultOutputDevices;
-    VolumeCurvesCollection *mVolumeCurves;
+    sp<DeviceDescriptor> &mDefaultOutputDevice;
     // TODO: remove when legacy conf file is removed. true on devices that use DRC on the
     // DEVICE_CATEGORY_SPEAKER path to boost soft sounds, used to adjust volume curves accordingly.
     // Note: remove also speaker_drc_enabled from global configuration of XML config file.
     bool mIsSpeakerDrcEnabled;
+    SurroundFormats mSurroundFormats;
 };
 
 } // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
index 3345579..094f506 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
@@ -16,46 +16,47 @@
 
 #pragma once
 
+#include "DeviceDescriptor.h"
 #include <utils/RefBase.h>
 #include <media/AudioPolicy.h>
-#include <utils/KeyedVector.h>
+#include <utils/Vector.h>
 #include <system/audio.h>
 #include <utils/String8.h>
 
-namespace android {
+#include <DeviceDescriptor.h>
+#include <AudioOutputDescriptor.h>
 
-class SwAudioOutputDescriptor;
+namespace android {
 
 /**
  * custom mix entry in mPolicyMixes
  */
 class AudioPolicyMix : public AudioMix, public RefBase {
 public:
-    AudioPolicyMix(const AudioMix &mix);
+    AudioPolicyMix(const AudioMix &mix) : AudioMix(mix) {}
     AudioPolicyMix(const AudioPolicyMix&) = delete;
     AudioPolicyMix& operator=(const AudioPolicyMix&) = delete;
 
-    const sp<SwAudioOutputDescriptor> &getOutput() const;
+    const sp<SwAudioOutputDescriptor> &getOutput() const { return mOutput; }
+    void setOutput(const sp<SwAudioOutputDescriptor> &output) { mOutput = output; }
+    void clearOutput() { mOutput.clear(); }
 
-    void setOutput(sp<SwAudioOutputDescriptor> &output);
-
-    void clearOutput();
-
-    status_t dump(int fd, int spaces, int index) const;
+    void dump(String8 *dst, int spaces, int index) const;
 
 private:
     sp<SwAudioOutputDescriptor> mOutput;  // Corresponding output stream
 };
 
 
-class AudioPolicyMixCollection : public DefaultKeyedVector<String8, sp<AudioPolicyMix> >
+class AudioPolicyMixCollection : public Vector<sp<AudioPolicyMix>>
 {
 public:
-    status_t getAudioPolicyMix(const String8& address, sp<AudioPolicyMix> &policyMix) const;
+    status_t getAudioPolicyMix(audio_devices_t deviceType,
+            const String8& address, sp<AudioPolicyMix> &policyMix) const;
 
-    status_t registerMix(const String8& address, AudioMix mix, sp<SwAudioOutputDescriptor> desc);
+    status_t registerMix(AudioMix mix, sp<SwAudioOutputDescriptor> desc);
 
-    status_t unregisterMix(const String8& address);
+    status_t unregisterMix(const AudioMix& mix);
 
     void closeOutput(sp<SwAudioOutputDescriptor> &desc);
 
@@ -63,21 +64,52 @@
      * Try to find an output descriptor for the given attributes.
      *
      * @param[in] attributes to consider fowr the research of output descriptor.
-     * @param[out] desc to return if an output could be found.
-     *
-     * @return NO_ERROR if an output was found for the given attribute (in this case, the
-     *                  descriptor output param is initialized), error code otherwise.
+     * @param[out] desc to return if an primary output could be found.
+     * @param[out] secondaryDesc other desc that the audio should be routed to.
+     * @return OK if the request is valid
+     *         otherwise if the request is not supported
      */
-    status_t getOutputForAttr(audio_attributes_t attributes, uid_t uid,
-            sp<SwAudioOutputDescriptor> &desc);
+    status_t getOutputForAttr(const audio_attributes_t& attributes, uid_t uid,
+                              audio_output_flags_t flags,
+                              sp<SwAudioOutputDescriptor> &primaryDesc,
+                              std::vector<sp<SwAudioOutputDescriptor>> *secondaryDescs);
 
-    audio_devices_t getDeviceAndMixForInputSource(audio_source_t inputSource,
-                                                  audio_devices_t availableDeviceTypes,
-                                                  sp<AudioPolicyMix> *policyMix);
+    sp<DeviceDescriptor> getDeviceAndMixForInputSource(audio_source_t inputSource,
+                                                       const DeviceVector &availableDeviceTypes,
+                                                       sp<AudioPolicyMix> *policyMix) const;
+
+    /**
+     * @brief try to find a matching mix for a given output descriptor and returns the associated
+     * output device.
+     * @param output to be considered
+     * @param availableOutputDevices list of output devices currently reachable
+     * @return device selected from the mix attached to the output, null pointer otherwise
+     */
+    sp<DeviceDescriptor> getDeviceAndMixForOutput(const sp<SwAudioOutputDescriptor> &output,
+                                                  const DeviceVector &availableOutputDevices);
 
     status_t getInputMixForAttr(audio_attributes_t attr, sp<AudioPolicyMix> *policyMix);
 
-    status_t dump(int fd) const;
+    /**
+     * Updates the mix rules in order to make streams associated with the given uid
+     * be routed to the given audio devices.
+     * @param uid the uid for which the device affinity is set
+     * @param devices the vector of devices that this uid may be routed to. A typical
+     *    use is to pass the devices associated with a given zone in a multi-zone setup.
+     * @return NO_ERROR if the update was successful, INVALID_OPERATION otherwise.
+     *    An example of failure is when there are already rules in place to restrict
+     *    a mix to the given uid (i.e. when a MATCH_UID rule was set for it).
+     */
+    status_t setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices);
+    status_t removeUidDeviceAffinities(uid_t uid);
+    status_t getDevicesForUid(uid_t uid, Vector<AudioDeviceTypeAddr>& devices) const;
+
+    void dump(String8 *dst) const;
+
+private:
+    enum class MixMatchStatus { MATCH, NO_MATCH, INVALID_MIX };
+    MixMatchStatus mixMatch(const AudioMix* mix, size_t mixIndex,
+                            const audio_attributes_t& attributes, uid_t uid);
 };
 
 } // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
index 09a86dd..d906f11 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
@@ -18,6 +18,7 @@
 
 #include "AudioCollections.h"
 #include "AudioProfile.h"
+#include "AudioGain.h"
 #include "HandleGenerator.h"
 #include <utils/String8.h>
 #include <utils/Vector.h>
@@ -29,9 +30,7 @@
 namespace android {
 
 class HwModule;
-class AudioGain;
 class AudioRoute;
-typedef Vector<sp<AudioGain> > AudioGainCollection;
 
 class AudioPort : public virtual RefBase, private HandleGenerator<audio_port_handle_t>
 {
@@ -49,8 +48,8 @@
 
     virtual const String8 getTagName() const = 0;
 
-    void setGains(const AudioGainCollection &gains) { mGains = gains; }
-    const AudioGainCollection &getGains() const { return mGains; }
+    void setGains(const AudioGains &gains) { mGains = gains; }
+    const AudioGains &getGains() const { return mGains; }
 
     virtual void setFlags(uint32_t flags)
     {
@@ -65,6 +64,7 @@
     uint32_t getFlags() const { return mFlags; }
 
     virtual void attach(const sp<HwModule>& module);
+    virtual void detach();
     bool isAttached() { return mModule != 0; }
 
     // Audio port IDs are in a different namespace than AudioFlinger unique IDs
@@ -112,10 +112,14 @@
     static bool isBetterFormatMatch(audio_format_t newFormat,
                                         audio_format_t currentFormat,
                                         audio_format_t targetFormat);
+    static uint32_t formatDistance(audio_format_t format1,
+                                   audio_format_t format2);
+    static const uint32_t kFormatDistanceMax = 4;
 
     audio_module_handle_t getModuleHandle() const;
     uint32_t getModuleVersionMajor() const;
     const char *getModuleName() const;
+    sp<HwModule> getModule() const { return mModule; }
 
     bool useInputChannelMask() const
     {
@@ -132,16 +136,17 @@
     void addRoute(const sp<AudioRoute> &route) { mRoutes.add(route); }
     const AudioRouteVector &getRoutes() const { return mRoutes; }
 
-    void dump(int fd, int spaces, bool verbose = true) const;
+    void dump(String8 *dst, int spaces, bool verbose = true) const;
+
     void log(const char* indent) const;
 
-    AudioGainCollection mGains; // gain controllers
-    sp<HwModule> mModule;                 // audio HW module exposing this I/O stream
+    AudioGains mGains; // gain controllers
 
 private:
     void pickChannelMask(audio_channel_mask_t &channelMask, const ChannelsVector &channelMasks) const;
     void pickSamplingRate(uint32_t &rate,const SampleRateVector &samplingRates) const;
 
+    sp<HwModule> mModule;                 // audio HW module exposing this I/O stream
     String8  mName;
     audio_port_type_t mType;
     audio_port_role_t mRole;
@@ -153,22 +158,22 @@
 class AudioPortConfig : public virtual RefBase
 {
 public:
-    AudioPortConfig();
-    virtual ~AudioPortConfig() {}
-
     status_t applyAudioPortConfig(const struct audio_port_config *config,
                                   struct audio_port_config *backupConfig = NULL);
     virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
                                    const struct audio_port_config *srcConfig = NULL) const = 0;
     virtual sp<AudioPort> getAudioPort() const = 0;
     virtual bool hasSameHwModuleAs(const sp<AudioPortConfig>& other) const {
-        return (other != 0) &&
+        return (other != 0) && (other->getAudioPort() != 0) && (getAudioPort() != 0) &&
                 (other->getAudioPort()->getModuleHandle() == getAudioPort()->getModuleHandle());
     }
-    uint32_t mSamplingRate;
-    audio_format_t mFormat;
-    audio_channel_mask_t mChannelMask;
-    struct audio_gain_config mGain;
+    bool hasGainController(bool canUseForVolume = false) const;
+
+    unsigned int mSamplingRate = 0u;
+    audio_format_t mFormat = AUDIO_FORMAT_INVALID;
+    audio_channel_mask_t mChannelMask = AUDIO_CHANNEL_NONE;
+    struct audio_gain_config mGain = { .index = -1 };
+    union audio_io_flags mFlags = { AUDIO_INPUT_FLAG_NONE };
 };
 
 } // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioProfile.h b/services/audiopolicy/common/managerdefinitions/include/AudioProfile.h
index 8741c66..b588d57 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioProfile.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioProfile.h
@@ -16,91 +16,84 @@
 
 #pragma once
 
-#include "policy.h"
-#include <utils/String8.h>
-#include <utils/SortedVector.h>
-#include <utils/RefBase.h>
-#include <utils/Errors.h>
+#include <vector>
+
 #include <system/audio.h>
-#include <cutils/config_utils.h>
+#include <utils/RefBase.h>
+#include <utils/SortedVector.h>
+#include <utils/String8.h>
+
+#include "policy.h"
 
 namespace android {
 
 typedef SortedVector<uint32_t> SampleRateVector;
-typedef SortedVector<audio_channel_mask_t> ChannelsVector;
 typedef Vector<audio_format_t> FormatVector;
 
 template <typename T>
-bool operator == (const SortedVector<T> &left, const SortedVector<T> &right);
+bool operator== (const SortedVector<T> &left, const SortedVector<T> &right)
+{
+    if (left.size() != right.size()) {
+        return false;
+    }
+    for (size_t index = 0; index < right.size(); index++) {
+        if (left[index] != right[index]) {
+            return false;
+        }
+    }
+    return true;
+}
+
+template <typename T>
+bool operator!= (const SortedVector<T> &left, const SortedVector<T> &right)
+{
+    return !(left == right);
+}
+
+class ChannelsVector : public SortedVector<audio_channel_mask_t>
+{
+public:
+    ChannelsVector() = default;
+    ChannelsVector(const ChannelsVector&) = default;
+    ChannelsVector(const SortedVector<audio_channel_mask_t>& sv) :
+            SortedVector<audio_channel_mask_t>(sv) {}
+    ChannelsVector& operator=(const ChannelsVector&) = default;
+
+    // Applies audio_channel_mask_out_to_in to all elements and returns the result.
+    ChannelsVector asInMask() const;
+    // Applies audio_channel_mask_in_to_out to all elements and returns the result.
+    ChannelsVector asOutMask() const;
+};
 
 class AudioProfile : public virtual RefBase
 {
 public:
-    AudioProfile(audio_format_t format,
-                 audio_channel_mask_t channelMasks,
-                 uint32_t samplingRate) :
-        mName(String8("")),
-        mFormat(format)
-    {
-        mChannelMasks.add(channelMasks);
-        mSamplingRates.add(samplingRate);
-    }
+    static sp<AudioProfile> createFullDynamic();
 
+    AudioProfile(audio_format_t format, audio_channel_mask_t channelMasks, uint32_t samplingRate);
     AudioProfile(audio_format_t format,
                  const ChannelsVector &channelMasks,
-                 const SampleRateVector &samplingRateCollection) :
-        mName(String8("")),
-        mFormat(format),
-        mChannelMasks(channelMasks),
-        mSamplingRates(samplingRateCollection)
-    {}
+                 const SampleRateVector &samplingRateCollection);
 
     audio_format_t getFormat() const { return mFormat; }
-
-    void setChannels(const ChannelsVector &channelMasks)
-    {
-        if (mIsDynamicChannels) {
-            mChannelMasks = channelMasks;
-        }
-    }
     const ChannelsVector &getChannels() const { return mChannelMasks; }
-
-    void setSampleRates(const SampleRateVector &sampleRates)
-    {
-        if (mIsDynamicRate) {
-            mSamplingRates = sampleRates;
-        }
-    }
     const SampleRateVector &getSampleRates() const { return mSamplingRates; }
+    void setChannels(const ChannelsVector &channelMasks);
+    void setSampleRates(const SampleRateVector &sampleRates);
 
+    void clear();
     bool isValid() const { return hasValidFormat() && hasValidRates() && hasValidChannels(); }
-
-    void clear()
-    {
-        if (mIsDynamicChannels) {
-            mChannelMasks.clear();
-        }
-        if (mIsDynamicRate) {
-            mSamplingRates.clear();
-        }
-    }
-
-    inline bool supportsChannels(audio_channel_mask_t channels) const
+    bool supportsChannels(audio_channel_mask_t channels) const
     {
         return mChannelMasks.indexOf(channels) >= 0;
     }
-    inline bool supportsRate(uint32_t rate) const
-    {
-        return mSamplingRates.indexOf(rate) >= 0;
-    }
+    bool supportsRate(uint32_t rate) const { return mSamplingRates.indexOf(rate) >= 0; }
 
     status_t checkExact(uint32_t rate, audio_channel_mask_t channels, audio_format_t format) const;
-
     status_t checkCompatibleChannelMask(audio_channel_mask_t channelMask,
                                         audio_channel_mask_t &updatedChannelMask,
                                         audio_port_type_t portType,
                                         audio_port_role_t portRole) const;
-
     status_t checkCompatibleSamplingRate(uint32_t samplingRate,
                                          uint32_t &updatedSamplingRate) const;
 
@@ -119,7 +112,7 @@
 
     bool isDynamic() { return mIsDynamicFormat || mIsDynamicChannels || mIsDynamicRate; }
 
-    void dump(int fd, int spaces) const;
+    void dump(String8 *dst, int spaces) const;
 
 private:
     String8  mName;
@@ -136,213 +129,48 @@
 class AudioProfileVector : public Vector<sp<AudioProfile> >
 {
 public:
-    ssize_t add(const sp<AudioProfile> &profile)
-    {
-        ssize_t index = Vector::add(profile);
-        // we sort from worst to best, so that AUDIO_FORMAT_DEFAULT is always the first entry.
-        // TODO: compareFormats could be a lambda to convert between pointer-to-format to format:
-        // [](const audio_format_t *format1, const audio_format_t *format2) {
-        //     return compareFormats(*format1, *format2);
-        // }
-        sort(compareFormats);
-        return index;
-    }
-
+    ssize_t add(const sp<AudioProfile> &profile);
     // This API is intended to be used by the policy manager once retrieving capabilities
     // for a profile with dynamic format, rate and channels attributes
-    ssize_t addProfileFromHal(const sp<AudioProfile> &profileToAdd)
-    {
-        // Check valid profile to add:
-        if (!profileToAdd->hasValidFormat()) {
-            return -1;
-        }
-        if (!profileToAdd->hasValidChannels() && !profileToAdd->hasValidRates()) {
-            FormatVector formats;
-            formats.add(profileToAdd->getFormat());
-            setFormats(FormatVector(formats));
-            return 0;
-        }
-        if (!profileToAdd->hasValidChannels() && profileToAdd->hasValidRates()) {
-            setSampleRatesFor(profileToAdd->getSampleRates(), profileToAdd->getFormat());
-            return 0;
-        }
-        if (profileToAdd->hasValidChannels() && !profileToAdd->hasValidRates()) {
-            setChannelsFor(profileToAdd->getChannels(), profileToAdd->getFormat());
-            return 0;
-        }
-        // Go through the list of profile to avoid duplicates
-        for (size_t profileIndex = 0; profileIndex < size(); profileIndex++) {
-            const sp<AudioProfile> &profile = itemAt(profileIndex);
-            if (profile->isValid() && profile == profileToAdd) {
-                // Nothing to do
-                return profileIndex;
-            }
-        }
-        profileToAdd->setDynamicFormat(true); // set the format as dynamic to allow removal
-        return add(profileToAdd);
-    }
-
-    sp<AudioProfile> getFirstValidProfile() const
-    {
-        for (size_t i = 0; i < size(); i++) {
-            if (itemAt(i)->isValid()) {
-                return itemAt(i);
-            }
-        }
-        return 0;
-    }
-
-    bool hasValidProfile() const { return getFirstValidProfile() != 0; }
+    ssize_t addProfileFromHal(const sp<AudioProfile> &profileToAdd);
 
     status_t checkExactProfile(uint32_t samplingRate, audio_channel_mask_t channelMask,
                                audio_format_t format) const;
-
     status_t checkCompatibleProfile(uint32_t &samplingRate, audio_channel_mask_t &channelMask,
                                     audio_format_t &format,
                                     audio_port_type_t portType,
                                     audio_port_role_t portRole) const;
+    void clearProfiles();
+    // Assuming that this profile vector contains input profiles,
+    // find the best matching config from 'outputProfiles', according to
+    // the given preferences for audio formats and channel masks.
+    // Note: std::vectors are used because specialized containers for formats
+    //       and channels can be sorted and use their own ordering.
+    status_t findBestMatchingOutputConfig(const AudioProfileVector& outputProfiles,
+            const std::vector<audio_format_t>& preferredFormats, // order: most pref -> least pref
+            const std::vector<audio_channel_mask_t>& preferredOutputChannels,
+            bool preferHigherSamplingRates,
+            audio_config_base *bestOutputConfig) const;
 
-    FormatVector getSupportedFormats() const
-    {
-        FormatVector supportedFormats;
-        for (size_t i = 0; i < size(); i++) {
-            if (itemAt(i)->hasValidFormat()) {
-                supportedFormats.add(itemAt(i)->getFormat());
-            }
-        }
-        return supportedFormats;
-    }
+    sp<AudioProfile> getFirstValidProfile() const;
+    sp<AudioProfile> getFirstValidProfileFor(audio_format_t format) const;
+    bool hasValidProfile() const { return getFirstValidProfile() != 0; }
 
-    bool hasDynamicProfile() const
-    {
-        for (size_t i = 0; i < size(); i++) {
-            if (itemAt(i)->isDynamic()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    bool hasDynamicFormat() const
-    {
-        return getProfileFor(gDynamicFormat) != 0;
-    }
-
-    bool hasDynamicChannelsFor(audio_format_t format) const
-    {
-       for (size_t i = 0; i < size(); i++) {
-           sp<AudioProfile> profile = itemAt(i);
-           if (profile->getFormat() == format && profile->isDynamicChannels()) {
-               return true;
-           }
-       }
-       return false;
-    }
-
-    bool hasDynamicRateFor(audio_format_t format) const
-    {
-        for (size_t i = 0; i < size(); i++) {
-            sp<AudioProfile> profile = itemAt(i);
-            if (profile->getFormat() == format && profile->isDynamicRate()) {
-                return true;
-            }
-        }
-        return false;
-    }
+    FormatVector getSupportedFormats() const;
+    bool hasDynamicChannelsFor(audio_format_t format) const;
+    bool hasDynamicFormat() const { return getProfileFor(gDynamicFormat) != 0; }
+    bool hasDynamicProfile() const;
+    bool hasDynamicRateFor(audio_format_t format) const;
 
     // One audio profile will be added for each format supported by Audio HAL
-    void setFormats(const FormatVector &formats)
-    {
-        // Only allow to change the format of dynamic profile
-        sp<AudioProfile> dynamicFormatProfile = getProfileFor(gDynamicFormat);
-        if (dynamicFormatProfile == 0) {
-            return;
-        }
-        for (size_t i = 0; i < formats.size(); i++) {
-            sp<AudioProfile> profile = new AudioProfile(formats[i],
-                                                        dynamicFormatProfile->getChannels(),
-                                                        dynamicFormatProfile->getSampleRates());
-            profile->setDynamicFormat(true);
-            profile->setDynamicChannels(dynamicFormatProfile->isDynamicChannels());
-            profile->setDynamicRate(dynamicFormatProfile->isDynamicRate());
-            add(profile);
-        }
-    }
+    void setFormats(const FormatVector &formats);
 
-    void clearProfiles()
-    {
-        for (size_t i = size(); i != 0; ) {
-            sp<AudioProfile> profile = itemAt(--i);
-            if (profile->isDynamicFormat() && profile->hasValidFormat()) {
-                removeAt(i);
-                continue;
-            }
-            profile->clear();
-        }
-    }
-
-    void dump(int fd, int spaces) const
-    {
-        const size_t SIZE = 256;
-        char buffer[SIZE];
-
-        snprintf(buffer, SIZE, "%*s- Profiles:\n", spaces, "");
-        write(fd, buffer, strlen(buffer));
-        for (size_t i = 0; i < size(); i++) {
-            snprintf(buffer, SIZE, "%*sProfile %zu:", spaces + 4, "", i);
-            write(fd, buffer, strlen(buffer));
-            itemAt(i)->dump(fd, spaces + 8);
-        }
-    }
+    void dump(String8 *dst, int spaces) const;
 
 private:
-    void setSampleRatesFor(const SampleRateVector &sampleRates, audio_format_t format)
-    {
-        for (size_t i = 0; i < size(); i++) {
-            sp<AudioProfile> profile = itemAt(i);
-            if (profile->getFormat() == format && profile->isDynamicRate()) {
-                if (profile->hasValidRates()) {
-                    // Need to create a new profile with same format
-                    sp<AudioProfile> profileToAdd = new AudioProfile(format, profile->getChannels(),
-                                                                     sampleRates);
-                    profileToAdd->setDynamicFormat(true); // need to set to allow cleaning
-                    add(profileToAdd);
-                } else {
-                    profile->setSampleRates(sampleRates);
-                }
-                return;
-            }
-        }
-    }
-
-    void setChannelsFor(const ChannelsVector &channelMasks, audio_format_t format)
-    {
-        for (size_t i = 0; i < size(); i++) {
-            sp<AudioProfile> profile = itemAt(i);
-            if (profile->getFormat() == format && profile->isDynamicChannels()) {
-                if (profile->hasValidChannels()) {
-                    // Need to create a new profile with same format
-                    sp<AudioProfile> profileToAdd = new AudioProfile(format, channelMasks,
-                                                                     profile->getSampleRates());
-                    profileToAdd->setDynamicFormat(true); // need to set to allow cleaning
-                    add(profileToAdd);
-                } else {
-                    profile->setChannels(channelMasks);
-                }
-                return;
-            }
-        }
-    }
-
-    sp<AudioProfile> getProfileFor(audio_format_t format) const
-    {
-        for (size_t i = 0; i < size(); i++) {
-            if (itemAt(i)->getFormat() == format) {
-                return itemAt(i);
-            }
-        }
-        return 0;
-    }
+    sp<AudioProfile> getProfileFor(audio_format_t format) const;
+    void setSampleRatesFor(const SampleRateVector &sampleRates, audio_format_t format);
+    void setChannelsFor(const ChannelsVector &channelMasks, audio_format_t format);
 
     static int compareFormats(const sp<AudioProfile> *profile1, const sp<AudioProfile> *profile2);
 };
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h b/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h
index 6b24fde..0357ff4 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h
@@ -46,7 +46,20 @@
 
     audio_route_type_t getType() const { return mType; }
 
-    void dump(int fd, int spaces) const;
+    /**
+     * @brief supportsPatch checks if an audio patch is supported by a Route declared in
+     * the audio_policy_configuration.xml file.
+     * If the patch is supported natively by an AudioHAL (which supports of course Routing API 3.0),
+     * audiopolicy will not request AudioFlinger to use a software bridge to realize a patch
+     * between 2 ports.
+     * @param srcPort (aka the source) to be considered
+     * @param dstPort (aka the sink) to be considered
+     * @return true if the audio route supports the connection between the sink and the source,
+     * false otherwise
+     */
+    bool supportsPatch(const sp<AudioPort> &srcPort, const sp<AudioPort> &dstPort) const;
+
+    void dump(String8 *dst, int spaces) const;
 
 private:
     AudioPortVector mSources;
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h b/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
deleted file mode 100644
index f7d8bf3..0000000
--- a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <system/audio.h>
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-#include <utils/Errors.h>
-#include <utils/KeyedVector.h>
-#include <media/AudioPolicy.h>
-#include <media/IAudioPolicyServiceClient.h>
-#include "AudioSessionInfoProvider.h"
-
-namespace android {
-
-class AudioPolicyClientInterface;
-class AudioPolicyMix;
-
-class AudioSession : public RefBase, public AudioSessionInfoUpdateListener
-{
-public:
-    AudioSession(audio_session_t session,
-                 audio_source_t inputSource,
-                 audio_format_t format,
-                 uint32_t sampleRate,
-                 audio_channel_mask_t channelMask,
-                 audio_input_flags_t flags,
-                 uid_t uid,
-                 bool isSoundTrigger,
-                 const sp<AudioPolicyMix> &policyMix,
-                 AudioPolicyClientInterface *clientInterface);
-
-    status_t dump(int fd, int spaces, int index) const;
-
-    audio_session_t session() const { return mRecordClientInfo.session; }
-    audio_source_t inputSource()const { return mRecordClientInfo.source; }
-    audio_format_t format() const { return mConfig.format; }
-    uint32_t sampleRate() const { return mConfig.sample_rate; }
-    audio_channel_mask_t channelMask() const { return mConfig.channel_mask; }
-    audio_input_flags_t flags() const { return mFlags; }
-    uid_t uid() const { return mRecordClientInfo.uid; }
-    void setUid(uid_t uid) { mRecordClientInfo.uid = uid; }
-    bool matches(const sp<AudioSession> &other) const;
-    bool isSoundTrigger() const { return mIsSoundTrigger; }
-    void setSilenced(bool silenced) { mSilenced = silenced; }
-    bool isSilenced() const { return mSilenced; }
-    uint32_t openCount() const { return mOpenCount; } ;
-    uint32_t activeCount() const { return mActiveCount; } ;
-
-    uint32_t changeOpenCount(int delta);
-    uint32_t changeActiveCount(int delta);
-
-    void setInfoProvider(AudioSessionInfoProvider *provider);
-    // implementation of AudioSessionInfoUpdateListener
-    virtual void onSessionInfoUpdate() const;
-
-private:
-    record_client_info_t mRecordClientInfo;
-    const struct audio_config_base mConfig;
-    const audio_input_flags_t mFlags;
-    bool  mIsSoundTrigger;
-    bool mSilenced;
-    uint32_t  mOpenCount;
-    uint32_t  mActiveCount;
-    wp<AudioPolicyMix> mPolicyMix; // non NULL when used by a dynamic policy
-    AudioPolicyClientInterface* mClientInterface;
-    const AudioSessionInfoProvider* mInfoProvider;
-};
-
-class AudioSessionCollection :
-    public DefaultKeyedVector<audio_session_t, sp<AudioSession> >,
-    public AudioSessionInfoUpdateListener
-{
-public:
-    status_t addSession(audio_session_t session,
-                             const sp<AudioSession>& audioSession,
-                             AudioSessionInfoProvider *provider);
-
-    status_t removeSession(audio_session_t session);
-
-    uint32_t getOpenCount() const;
-
-    AudioSessionCollection getActiveSessions() const;
-    size_t getActiveSessionCount() const;
-    bool hasActiveSession() const;
-    bool isSourceActive(audio_source_t source) const;
-    audio_source_t getHighestPrioritySource(bool activeOnly) const;
-
-    // implementation of AudioSessionInfoUpdateListener
-    virtual void onSessionInfoUpdate() const;
-
-    status_t dump(int fd, int spaces) const;
-};
-
-} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioSessionInfoProvider.h b/services/audiopolicy/common/managerdefinitions/include/AudioSessionInfoProvider.h
deleted file mode 100644
index e0037fc..0000000
--- a/services/audiopolicy/common/managerdefinitions/include/AudioSessionInfoProvider.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-namespace android {
-
-/**
- * Interface for input descriptors to implement so dependent audio sessions can query information
- * about their context
- */
-class AudioSessionInfoProvider
-{
-public:
-    virtual ~AudioSessionInfoProvider() {};
-
-    virtual audio_config_base_t getConfig() const = 0;
-
-    virtual audio_patch_handle_t getPatchHandle() const = 0;
-
-};
-
-class AudioSessionInfoUpdateListener
-{
-public:
-    virtual ~AudioSessionInfoUpdateListener() {};
-
-    virtual void onSessionInfoUpdate() const = 0;;
-};
-
-} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioSourceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioSourceDescriptor.h
deleted file mode 100644
index 0d90f42..0000000
--- a/services/audiopolicy/common/managerdefinitions/include/AudioSourceDescriptor.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <system/audio.h>
-#include <utils/Errors.h>
-#include <utils/KeyedVector.h>
-#include <utils/RefBase.h>
-#include <RoutingStrategy.h>
-#include <AudioPatch.h>
-
-namespace android {
-
-class SwAudioOutputDescriptor;
-class HwAudioOutputDescriptor;
-class DeviceDescriptor;
-
-class AudioSourceDescriptor: public RefBase
-{
-public:
-    AudioSourceDescriptor(const sp<DeviceDescriptor> device, const audio_attributes_t *attributes,
-                          uid_t uid) :
-        mDevice(device), mAttributes(*attributes), mUid(uid) {}
-    virtual ~AudioSourceDescriptor() {}
-
-    audio_patch_handle_t getHandle() const { return mPatchDesc->mHandle; }
-
-    status_t    dump(int fd);
-
-    const sp<DeviceDescriptor> mDevice;
-    const audio_attributes_t mAttributes;
-    uid_t mUid;
-    sp<AudioPatch> mPatchDesc;
-    wp<SwAudioOutputDescriptor> mSwOutput;
-    wp<HwAudioOutputDescriptor> mHwOutput;
-};
-
-class AudioSourceCollection :
-        public DefaultKeyedVector< audio_patch_handle_t, sp<AudioSourceDescriptor> >
-{
-public:
-    status_t dump(int fd) const;
-};
-
-} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
new file mode 100644
index 0000000..0d05a63
--- /dev/null
+++ b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <vector>
+#include <map>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <system/audio.h>
+#include <audiomanager/AudioManager.h>
+#include <media/AudioProductStrategy.h>
+#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+#include <policy.h>
+#include <Volume.h>
+#include "AudioPatch.h"
+#include "EffectDescriptor.h"
+
+namespace android {
+
+class DeviceDescriptor;
+class HwAudioOutputDescriptor;
+class SwAudioOutputDescriptor;
+
+class ClientDescriptor: public RefBase
+{
+public:
+    ClientDescriptor(audio_port_handle_t portId, uid_t uid, audio_session_t sessionId,
+                     audio_attributes_t attributes, audio_config_base_t config,
+                     audio_port_handle_t preferredDeviceId,
+                     bool isPreferredDeviceForExclusiveUse = false) :
+        mPortId(portId), mUid(uid), mSessionId(sessionId), mAttributes(attributes),
+        mConfig(config), mPreferredDeviceId(preferredDeviceId), mActive(false),
+        mPreferredDeviceForExclusiveUse(isPreferredDeviceForExclusiveUse){}
+    ~ClientDescriptor() override = default;
+
+    virtual void dump(String8 *dst, int spaces, int index) const;
+    virtual std::string toShortString() const;
+
+    audio_port_handle_t portId() const { return mPortId; }
+    uid_t uid() const { return mUid; }
+    audio_session_t session() const { return mSessionId; };
+    audio_attributes_t attributes() const { return mAttributes; }
+    audio_config_base_t config() const { return mConfig; }
+    audio_port_handle_t preferredDeviceId() const { return mPreferredDeviceId; };
+    void setPreferredDeviceId(audio_port_handle_t preferredDeviceId) {
+        mPreferredDeviceId = preferredDeviceId;
+    }
+    bool isPreferredDeviceForExclusiveUse() const { return mPreferredDeviceForExclusiveUse; }
+    virtual void setActive(bool active) { mActive = active; }
+    bool active() const { return mActive; }
+    bool hasPreferredDevice(bool activeOnly = false) const {
+        return mPreferredDeviceId != AUDIO_PORT_HANDLE_NONE && (!activeOnly || mActive);
+    }
+
+private:
+    const audio_port_handle_t mPortId;  // unique Id for this client
+    const uid_t mUid;                     // client UID
+    const audio_session_t mSessionId;       // audio session ID
+    const audio_attributes_t mAttributes; // usage...
+    const audio_config_base_t mConfig;
+          audio_port_handle_t mPreferredDeviceId;  // selected input device port ID
+          bool mActive;
+          bool mPreferredDeviceForExclusiveUse = false;
+};
+
+class TrackClientDescriptor: public ClientDescriptor
+{
+public:
+    TrackClientDescriptor(audio_port_handle_t portId, uid_t uid, audio_session_t sessionId,
+                          audio_attributes_t attributes, audio_config_base_t config,
+                          audio_port_handle_t preferredDeviceId, audio_stream_type_t stream,
+                          product_strategy_t strategy, VolumeSource volumeSource,
+                          audio_output_flags_t flags,
+                          bool isPreferredDeviceForExclusiveUse,
+                          std::vector<wp<SwAudioOutputDescriptor>> secondaryOutputs) :
+        ClientDescriptor(portId, uid, sessionId, attributes, config, preferredDeviceId,
+                         isPreferredDeviceForExclusiveUse),
+        mStream(stream), mStrategy(strategy), mVolumeSource(volumeSource), mFlags(flags),
+        mSecondaryOutputs(std::move(secondaryOutputs)) {}
+    ~TrackClientDescriptor() override = default;
+
+    using ClientDescriptor::dump;
+    void dump(String8 *dst, int spaces, int index) const override;
+    std::string toShortString() const override;
+
+    audio_output_flags_t flags() const { return mFlags; }
+    audio_stream_type_t stream() const { return mStream; }
+    product_strategy_t strategy() const { return mStrategy; }
+    const std::vector<wp<SwAudioOutputDescriptor>>& getSecondaryOutputs() const {
+        return mSecondaryOutputs;
+    };
+    VolumeSource volumeSource() const { return mVolumeSource; }
+
+    void setActive(bool active) override
+    {
+        int delta = active ? 1 : -1;
+        changeActivityCount(delta);
+    }
+    void changeActivityCount(int delta)
+    {
+        if (delta > 0) {
+            mActivityCount += delta;
+        } else {
+            LOG_ALWAYS_FATAL_IF(!mActivityCount, "%s(%s) invalid delta %d, inactive client",
+                                 __func__, toShortString().c_str(), delta);
+            LOG_ALWAYS_FATAL_IF(static_cast<int>(mActivityCount) < -delta,
+                                "%s(%s) invalid delta %d, active client count %d",
+                                 __func__, toShortString().c_str(), delta, mActivityCount);
+            mActivityCount += delta;
+        }
+        ClientDescriptor::setActive(mActivityCount > 0);
+    }
+    uint32_t getActivityCount() const { return mActivityCount; }
+
+private:
+    const audio_stream_type_t mStream;
+    const product_strategy_t mStrategy;
+    const VolumeSource mVolumeSource;
+    const audio_output_flags_t mFlags;
+    const std::vector<wp<SwAudioOutputDescriptor>> mSecondaryOutputs;
+
+    /**
+     * required for duplicating thread, prevent from removing active client from an output
+     * involved in a duplication.
+     */
+    uint32_t mActivityCount = 0;
+};
+
+class RecordClientDescriptor: public ClientDescriptor
+{
+public:
+    RecordClientDescriptor(audio_port_handle_t portId, audio_unique_id_t riid, uid_t uid,
+                        audio_session_t sessionId, audio_attributes_t attributes,
+                        audio_config_base_t config, audio_port_handle_t preferredDeviceId,
+                        audio_source_t source, audio_input_flags_t flags, bool isSoundTrigger) :
+        ClientDescriptor(portId, uid, sessionId, attributes, config, preferredDeviceId),
+        mRIId(riid), mSource(source), mFlags(flags), mIsSoundTrigger(isSoundTrigger),
+        mAppState(APP_STATE_IDLE) {}
+    ~RecordClientDescriptor() override = default;
+
+    using ClientDescriptor::dump;
+    void dump(String8 *dst, int spaces, int index) const override;
+
+    audio_unique_id_t riid() const { return mRIId; }
+    audio_source_t source() const { return mSource; }
+    audio_input_flags_t flags() const { return mFlags; }
+    bool isSoundTrigger() const { return mIsSoundTrigger; }
+    bool isLowLevel() const { return mRIId == RECORD_RIID_INVALID; }
+    void setAppState(app_state_t appState) { mAppState = appState; }
+    app_state_t appState() { return mAppState; }
+    bool isSilenced() const { return mAppState == APP_STATE_IDLE; }
+    void trackEffectEnabled(const sp<EffectDescriptor> &effect, bool enabled);
+    EffectDescriptorCollection getEnabledEffects() const { return mEnabledEffects; }
+
+private:
+    const audio_unique_id_t mRIId;
+    const audio_source_t mSource;
+    const audio_input_flags_t mFlags;
+    const bool mIsSoundTrigger;
+          app_state_t mAppState;
+    EffectDescriptorCollection mEnabledEffects;
+};
+
+class SourceClientDescriptor: public TrackClientDescriptor
+{
+public:
+    SourceClientDescriptor(audio_port_handle_t portId, uid_t uid, audio_attributes_t attributes,
+                           const sp<AudioPatch>& patchDesc, const sp<DeviceDescriptor>& srcDevice,
+                           audio_stream_type_t stream, product_strategy_t strategy,
+                           VolumeSource volumeSource);
+    ~SourceClientDescriptor() override = default;
+
+    sp<AudioPatch> patchDesc() const { return mPatchDesc; }
+    sp<DeviceDescriptor> srcDevice() const { return mSrcDevice; };
+    wp<SwAudioOutputDescriptor> swOutput() const { return mSwOutput; }
+    void setSwOutput(const sp<SwAudioOutputDescriptor>& swOutput);
+    wp<HwAudioOutputDescriptor> hwOutput() const { return mHwOutput; }
+    void setHwOutput(const sp<HwAudioOutputDescriptor>& hwOutput);
+
+    using ClientDescriptor::dump;
+    void dump(String8 *dst, int spaces, int index) const override;
+
+ private:
+    const sp<AudioPatch> mPatchDesc;
+    const sp<DeviceDescriptor> mSrcDevice;
+    wp<SwAudioOutputDescriptor> mSwOutput;
+    wp<HwAudioOutputDescriptor> mHwOutput;
+};
+
+class SourceClientCollection :
+    public DefaultKeyedVector< audio_port_handle_t, sp<SourceClientDescriptor> >
+{
+public:
+    void dump(String8 *dst) const;
+};
+
+typedef std::vector< sp<TrackClientDescriptor> > TrackClientVector;
+typedef std::vector< sp<RecordClientDescriptor> > RecordClientVector;
+
+// A Map that associates a portId with a client (type T)
+// which is either TrackClientDescriptor or RecordClientDescriptor.
+
+template<typename T>
+class ClientMapHandler {
+public:
+    virtual ~ClientMapHandler() = default;
+
+    // Track client management
+    virtual void addClient(const sp<T> &client) {
+        const audio_port_handle_t portId = client->portId();
+        LOG_ALWAYS_FATAL_IF(!mClients.emplace(portId, client).second,
+                "%s(%d): attempting to add client that already exists", __func__, portId);
+    }
+    sp<T> getClient(audio_port_handle_t portId) const {
+        auto it = mClients.find(portId);
+        if (it == mClients.end()) return nullptr;
+        return it->second;
+    }
+    virtual void removeClient(audio_port_handle_t portId) {
+        auto it = mClients.find(portId);
+        LOG_ALWAYS_FATAL_IF(it == mClients.end(),
+                "%s(%d): client does not exist", __func__, portId);
+        LOG_ALWAYS_FATAL_IF(it->second->active(),
+                "%s(%d): removing client still active!", __func__, portId);
+        (void)mClients.erase(it);
+    }
+    size_t getClientCount() const {
+        return mClients.size();
+    }
+    virtual void dump(String8 *dst) const {
+        size_t index = 0;
+        for (const auto& client: getClientIterable()) {
+            client->dump(dst, 2, index++);
+        }
+    }
+
+    // helper types
+    using ClientMap = std::map<audio_port_handle_t, sp<T>>;
+    using ClientMapIterator = typename ClientMap::const_iterator;  // ClientMap is const qualified
+    class ClientIterable {
+    public:
+        explicit ClientIterable(const ClientMapHandler<T> &ref) : mClientMapHandler(ref) { }
+
+        class iterator {
+        public:
+            // traits
+            using iterator_category = std::forward_iterator_tag;
+            using value_type = sp<T>;
+            using difference_type = ptrdiff_t;
+            using pointer = const sp<T>*;    // Note: const
+            using reference = const sp<T>&;  // Note: const
+
+            // implementation
+            explicit iterator(const ClientMapIterator &it) : mIt(it) { }
+            iterator& operator++()    /* prefix */     { ++mIt; return *this; }
+            reference operator* () const               { return mIt->second; }
+            reference operator->() const               { return mIt->second; } // as if sp<>
+            difference_type operator-(const iterator& rhs) {return mIt - rhs.mIt; }
+            bool operator==(const iterator& rhs) const { return mIt == rhs.mIt; }
+            bool operator!=(const iterator& rhs) const { return mIt != rhs.mIt; }
+        private:
+            ClientMapIterator mIt;
+        };
+
+        iterator begin() const { return iterator{mClientMapHandler.mClients.begin()}; }
+        iterator end() const { return iterator{mClientMapHandler.mClients.end()}; }
+
+    private:
+        const ClientMapHandler<T>& mClientMapHandler; // iterating does not modify map.
+    };
+
+    // return an iterable object that can be used in a range-based-for to enumerate clients.
+    // this iterable does not allow modification, it should be used as a temporary.
+    ClientIterable getClientIterable() const {
+        return ClientIterable{*this};
+    }
+
+private:
+    // ClientMap maps a portId to a client descriptor (both uniquely identify each other).
+    ClientMap mClients;
+};
+
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h b/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h
deleted file mode 100644
index a007854..0000000
--- a/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "AudioPolicyConfig.h"
-#include "DeviceDescriptor.h"
-#include "HwModule.h"
-#include "audio_policy_conf.h"
-#include <system/audio.h>
-#include <utils/Log.h>
-#include <utils/Vector.h>
-#include <utils/SortedVector.h>
-#include <cutils/config_utils.h>
-#include <utils/RefBase.h>
-#include <system/audio_policy.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-// Definitions for audio_policy.conf file parsing
-// ----------------------------------------------------------------------------
-
-class ConfigParsingUtils
-{
-public:
-    static status_t loadConfig(const char *path, AudioPolicyConfig &config);
-
-private:
-    static void loadAudioPortGain(cnode *root, AudioPort &audioPort, int index);
-    static void loadAudioPortGains(cnode *root, AudioPort &audioPort);
-    static void loadDeviceDescriptorGains(cnode *root, sp<DeviceDescriptor> &deviceDesc);
-    static status_t loadHwModuleDevice(cnode *root, DeviceVector &devices);
-    static status_t loadHwModuleProfile(cnode *root, sp<HwModule> &module, audio_port_role_t role);
-    static void loadDevicesFromTag(const char *tag, DeviceVector &devices,
-                            const DeviceVector &declaredDevices);
-    static void loadHwModules(cnode *root, HwModuleCollection &hwModules,
-                              AudioPolicyConfig &config);
-    static void loadGlobalConfig(cnode *root, AudioPolicyConfig &config,
-                                 const sp<HwModule> &primaryModule);
-    static void loadModuleGlobalConfig(cnode *root, const sp<HwModule> &module,
-                                       AudioPolicyConfig &config);
-    static status_t loadHwModule(cnode *root, sp<HwModule> &module, AudioPolicyConfig &config);
-};
-
-} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
index 92a4c3e..33e506f 100644
--- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
@@ -31,15 +31,31 @@
 public:
      // Note that empty name refers by convention to a generic device.
     explicit DeviceDescriptor(audio_devices_t type, const String8 &tagName = String8(""));
+    DeviceDescriptor(audio_devices_t type, const FormatVector &encodedFormats,
+            const String8 &tagName = String8(""));
 
     virtual ~DeviceDescriptor() {}
 
     virtual const String8 getTagName() const { return mTagName; }
 
     audio_devices_t type() const { return mDeviceType; }
+    String8 address() const { return mAddress; }
+    void setAddress(const String8 &address) { mAddress = address; }
+
+    const FormatVector& encodedFormats() const { return mEncodedFormats; }
+
+    audio_format_t getEncodedFormat() { return mCurrentEncodedFormat; }
+
+    void setEncodedFormat(audio_format_t format) {
+        mCurrentEncodedFormat = format;
+    }
 
     bool equals(const sp<DeviceDescriptor>& other) const;
 
+    bool hasCurrentEncodedFormat() const;
+
+    bool supportsFormat(audio_format_t format);
+
     // AudioPortConfig
     virtual sp<AudioPort> getAudioPort() const { return (AudioPort*) this; }
     virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
@@ -47,44 +63,148 @@
 
     // AudioPort
     virtual void attach(const sp<HwModule>& module);
+    virtual void detach();
+
     virtual void toAudioPort(struct audio_port *port) const;
     virtual void importAudioPort(const sp<AudioPort>& port, bool force = false);
 
     audio_port_handle_t getId() const;
-    status_t dump(int fd, int spaces, int index, bool verbose = true) const;
+    void dump(String8 *dst, int spaces, int index, bool verbose = true) const;
     void log() const;
-
-    String8 mAddress;
+    std::string toString() const;
 
 private:
+    String8 mAddress{""};
     String8 mTagName; // Unique human readable identifier for a device port found in conf file.
     audio_devices_t     mDeviceType;
-    audio_port_handle_t mId;
-
-friend class DeviceVector;
+    FormatVector        mEncodedFormats;
+    audio_port_handle_t mId = AUDIO_PORT_HANDLE_NONE;
+    audio_format_t      mCurrentEncodedFormat;
 };
 
 class DeviceVector : public SortedVector<sp<DeviceDescriptor> >
 {
 public:
     DeviceVector() : SortedVector(), mDeviceTypes(AUDIO_DEVICE_NONE) {}
+    explicit DeviceVector(const sp<DeviceDescriptor>& item) : DeviceVector()
+    {
+        add(item);
+    }
 
     ssize_t add(const sp<DeviceDescriptor>& item);
     void add(const DeviceVector &devices);
     ssize_t remove(const sp<DeviceDescriptor>& item);
+    void remove(const DeviceVector &devices);
     ssize_t indexOf(const sp<DeviceDescriptor>& item) const;
 
     audio_devices_t types() const { return mDeviceTypes; }
 
-    sp<DeviceDescriptor> getDevice(audio_devices_t type, const String8& address) const;
-    DeviceVector getDevicesFromType(audio_devices_t types) const;
+    // If 'address' is empty and 'codec' is AUDIO_FORMAT_DEFAULT, a device with a non-empty
+    // address may be returned if there is no device with the specified 'type' and empty address.
+    sp<DeviceDescriptor> getDevice(audio_devices_t type, const String8 &address,
+                                   audio_format_t codec) const;
+    DeviceVector getDevicesFromTypeMask(audio_devices_t types) const;
+
+    /**
+     * @brief getDeviceFromId
+     * @param id of the DeviceDescriptor to seach (aka Port handle).
+     * @return DeviceDescriptor associated to port id if found, nullptr otherwise. If the id is
+     * equal to AUDIO_PORT_HANDLE_NONE, it also returns a nullptr.
+     */
     sp<DeviceDescriptor> getDeviceFromId(audio_port_handle_t id) const;
     sp<DeviceDescriptor> getDeviceFromTagName(const String8 &tagName) const;
-    DeviceVector getDevicesFromTypeAddr(audio_devices_t type, const String8& address) const;
+    DeviceVector getDevicesFromHwModule(audio_module_handle_t moduleHandle) const;
+    audio_devices_t getDeviceTypesFromHwModule(audio_module_handle_t moduleHandle) const;
 
-    audio_devices_t getDevicesFromHwModule(audio_module_handle_t moduleHandle) const;
+    bool contains(const sp<DeviceDescriptor>& item) const { return indexOf(item) >= 0; }
 
-    status_t dump(int fd, const String8 &tag, int spaces = 0, bool verbose = true) const;
+    /**
+     * @brief containsAtLeastOne
+     * @param devices vector of devices to check against.
+     * @return true if the DeviceVector contains at list one of the devices from the given vector.
+     */
+    bool containsAtLeastOne(const DeviceVector &devices) const;
+
+    /**
+     * @brief containsAllDevices
+     * @param devices vector of devices to check against.
+     * @return true if the DeviceVector contains all the devices from the given vector
+     */
+    bool containsAllDevices(const DeviceVector &devices) const;
+
+    /**
+     * @brief filter the devices supported by this collection against another collection
+     * @param devices to filter against
+     * @return a filtered DeviceVector
+     */
+    DeviceVector filter(const DeviceVector &devices) const;
+
+    /**
+     * @brief filter the devices supported by this collection before sending
+     * then to the Engine via AudioPolicyManagerObserver interface
+     * @return a filtered DeviceVector
+     */
+    DeviceVector filterForEngine() const;
+
+    /**
+     * @brief merge two vectors. As SortedVector Implementation is buggy (it does not check the size
+     * of the destination vector, only of the source, it provides a safe implementation
+     * @param devices source device vector to merge with
+     * @return size of the merged vector.
+     */
+    ssize_t merge(const DeviceVector &devices)
+    {
+        if (isEmpty()) {
+            add(devices);
+            return size();
+        }
+        return SortedVector::merge(devices);
+    }
+
+    /**
+     * @brief operator == DeviceVector are equals if all the DeviceDescriptor can be found (aka
+     * DeviceDescriptor with same type and address) and the vector has same size.
+     * @param right DeviceVector to compare to.
+     * @return true if right contains the same device and has the same size.
+     */
+    bool operator==(const DeviceVector &right) const
+    {
+        if (size() != right.size()) {
+            return false;
+        }
+        for (const auto &device : *this) {
+            if (right.indexOf(device) < 0) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    bool operator!=(const DeviceVector &right) const
+    {
+        return !operator==(right);
+    }
+
+    /**
+     * @brief getFirstValidAddress
+     * @return the first valid address of a list of device, "" if no device with valid address
+     * found.
+     * This helper function helps maintaining compatibility with legacy where we used to have a
+     * devices mask and an address.
+     */
+    String8 getFirstValidAddress() const
+    {
+        for (const auto &device : *this) {
+            if (device->address() != "") {
+                return device->address();
+            }
+        }
+        return String8("");
+    }
+
+    std::string toString() const;
+
+    void dump(String8 *dst, const String8 &tag, int spaces = 0, bool verbose = true) const;
 
 private:
     void refreshTypes();
diff --git a/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
index 04831c6..c4eab30 100644
--- a/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
@@ -16,25 +16,39 @@
 
 #pragma once
 
-#include <RoutingStrategy.h>
+#include <policy.h>
 #include <system/audio_effect.h>
 #include <utils/KeyedVector.h>
 #include <utils/RefBase.h>
 #include <utils/Errors.h>
+#include <utils/String8.h>
 
 namespace android {
 
-
 class EffectDescriptor : public RefBase
 {
 public:
-    status_t dump(int fd);
+    EffectDescriptor(const effect_descriptor_t *desc, bool isMusicEffect,
+                     int id, audio_io_handle_t io, audio_session_t session) :
+        mId(id), mIo(io), mSession(session), mEnabled(false), mSuspended(false),
+        mIsMusicEffect(isMusicEffect)
+    {
+        memcpy (&mDesc, desc, sizeof(effect_descriptor_t));
+    }
 
-    int mIo;                // io the effect is attached to
-    routing_strategy mStrategy; // routing strategy the effect is associated to
-    int mSession;               // audio session the effect is on
-    effect_descriptor_t mDesc;  // effect descriptor
-    bool mEnabled;              // enabled state: CPU load being used or not
+    void dump(String8 *dst, int spaces = 0) const;
+
+    int mId;                   // effect unique ID
+    audio_io_handle_t mIo;     // io the effect is attached to
+    audio_session_t mSession;  // audio session the effect is on
+    effect_descriptor_t mDesc; // effect descriptor
+    bool mEnabled;             // enabled state: CPU load being used or not
+    bool mSuspended;           // enabled but suspended by concurent capture policy
+
+    bool isMusicEffect() const { return mIsMusicEffect; }
+
+private:
+    bool mIsMusicEffect;
 };
 
 class EffectDescriptorCollection : public KeyedVector<int, sp<EffectDescriptor> >
@@ -43,14 +57,22 @@
     EffectDescriptorCollection();
 
     status_t registerEffect(const effect_descriptor_t *desc, audio_io_handle_t io,
-                            uint32_t strategy, int session, int id);
+                            int session, int id, bool isMusicEffect);
     status_t unregisterEffect(int id);
+    sp<EffectDescriptor> getEffect(int id) const;
+    EffectDescriptorCollection getEffectsForIo(audio_io_handle_t io) const;
     status_t setEffectEnabled(int id, bool enabled);
+    bool     isEffectEnabled(int id) const;
     uint32_t getMaxEffectsCpuLoad() const;
     uint32_t getMaxEffectsMemory() const;
-    bool isNonOffloadableEffectEnabled();
+    bool isNonOffloadableEffectEnabled() const;
 
-    status_t dump(int fd);
+    void moveEffects(audio_session_t session,
+                     audio_io_handle_t srcOutput,
+                     audio_io_handle_t dstOutput);
+    void moveEffects(const std::vector<int>& ids, audio_io_handle_t dstOutput);
+
+    void dump(String8 *dst, int spaces = 0, bool verbose = true) const;
 
 private:
     status_t setEffectEnabled(const sp<EffectDescriptor> &effectDesc, bool enabled);
diff --git a/services/audiopolicy/common/managerdefinitions/include/Gains.h b/services/audiopolicy/common/managerdefinitions/include/Gains.h
deleted file mode 100644
index cb229a4..0000000
--- a/services/audiopolicy/common/managerdefinitions/include/Gains.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <StreamDescriptor.h>
-#include <utils/KeyedVector.h>
-#include <system/audio.h>
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-
-namespace android {
-
-class StreamDescriptor;
-
-class Gains
-{
-public :
-    static float volIndexToDb(const VolumeCurvePoint *point, int indexMin, int indexMax,
-                              int indexInUi);
-
-    // default volume curve
-    static const VolumeCurvePoint sDefaultVolumeCurve[Volume::VOLCNT];
-    // default volume curve for media strategy
-    static const VolumeCurvePoint sDefaultMediaVolumeCurve[Volume::VOLCNT];
-    // volume curve for non-media audio on ext media outputs (HDMI, Line, etc)
-    static const VolumeCurvePoint sExtMediaSystemVolumeCurve[Volume::VOLCNT];
-    // volume curve for media strategy on speakers
-    static const VolumeCurvePoint sSpeakerMediaVolumeCurve[Volume::VOLCNT];
-    static const VolumeCurvePoint sSpeakerMediaVolumeCurveDrc[Volume::VOLCNT];
-    // volume curve for sonification strategy on speakers
-    static const VolumeCurvePoint sSpeakerSonificationVolumeCurve[Volume::VOLCNT];
-    static const VolumeCurvePoint sSpeakerSonificationVolumeCurveDrc[Volume::VOLCNT];
-    static const VolumeCurvePoint sDefaultSystemVolumeCurve[Volume::VOLCNT];
-    static const VolumeCurvePoint sDefaultSystemVolumeCurveDrc[Volume::VOLCNT];
-    static const VolumeCurvePoint sHeadsetSystemVolumeCurve[Volume::VOLCNT];
-    static const VolumeCurvePoint sDefaultVoiceVolumeCurve[Volume::VOLCNT];
-    static const VolumeCurvePoint sSpeakerVoiceVolumeCurve[Volume::VOLCNT];
-    static const VolumeCurvePoint sLinearVolumeCurve[Volume::VOLCNT];
-    static const VolumeCurvePoint sSilentVolumeCurve[Volume::VOLCNT];
-    static const VolumeCurvePoint sFullScaleVolumeCurve[Volume::VOLCNT];
-    static const VolumeCurvePoint sHearingAidVolumeCurve[Volume::VOLCNT];
-    // default volume curves per stream and device category. See initializeVolumeCurves()
-    static const VolumeCurvePoint *sVolumeProfiles[AUDIO_STREAM_CNT][DEVICE_CATEGORY_CNT];
-};
-
-} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/HwModule.h b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
index cb9f49e..eb34da4 100644
--- a/services/audiopolicy/common/managerdefinitions/include/HwModule.h
+++ b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
@@ -46,6 +46,22 @@
 
     const DeviceVector &getDeclaredDevices() const { return mDeclaredDevices; }
     void setDeclaredDevices(const DeviceVector &devices);
+    DeviceVector getAllDevices() const
+    {
+        DeviceVector devices = mDeclaredDevices;
+        devices.merge(mDynamicDevices);
+        return devices;
+    }
+    void addDynamicDevice(const sp<DeviceDescriptor> &device)
+    {
+        mDynamicDevices.add(device);
+    }
+
+    bool removeDynamicDevice(const sp<DeviceDescriptor> &device)
+    {
+        return mDynamicDevices.remove(device) >= 0;
+    }
+    DeviceVector getDynamicDevices() const { return mDynamicDevices; }
 
     const InputProfileCollection &getInputProfiles() const { return mInputProfiles; }
     const OutputProfileCollection &getOutputProfiles() const { return mOutputProfiles; }
@@ -81,8 +97,19 @@
         return mPorts.findByTagName(tagName);
     }
 
+    /**
+     * @brief supportsPatch checks if an audio patch between 2 ports beloging to this HwModule
+     * is supported by a HwModule. The ports and the route shall be declared in the
+     * audio_policy_configuration.xml file.
+     * @param srcPort (aka the source) to be considered
+     * @param dstPort (aka the sink) to be considered
+     * @return true if the HwModule supports the connection between the sink and the source,
+     * false otherwise
+     */
+    bool supportsPatch(const sp<AudioPort> &srcPort, const sp<AudioPort> &dstPort) const;
+
     // TODO remove from here (split serialization)
-    void dump(int fd);
+    void dump(String8 *dst) const;
 
 private:
     void refreshSupportedDevices();
@@ -93,6 +120,7 @@
     InputProfileCollection mInputProfiles;  // input profiles exposed by this module
     uint32_t mHalVersion; // audio HAL API version
     DeviceVector mDeclaredDevices; // devices declared in audio_policy configuration file.
+    DeviceVector mDynamicDevices; /**< devices that can be added/removed at runtime (e.g. rsbumix)*/
     AudioRouteVector mRoutes;
     AudioPortVector mPorts;
 };
@@ -102,14 +130,64 @@
 public:
     sp<HwModule> getModuleFromName(const char *name) const;
 
-    sp<HwModule> getModuleForDevice(audio_devices_t device) const;
+    sp<HwModule> getModuleForDeviceTypes(audio_devices_t device,
+                                         audio_format_t encodedFormat) const;
 
-    sp<DeviceDescriptor> getDeviceDescriptor(const audio_devices_t device,
-                                             const char *device_address,
-                                             const char *device_name,
-                                             bool matchAdress = true) const;
+    sp<HwModule> getModuleForDevice(const sp<DeviceDescriptor> &device,
+                                    audio_format_t encodedFormat) const;
 
-    status_t dump(int fd) const;
+    DeviceVector getAvailableDevicesFromModuleName(const char *name,
+                                                   const DeviceVector &availableDevices) const;
+
+    /**
+     * @brief getDeviceDescriptor returns a device descriptor associated to the device type and
+     * device address (if matchAddress is true).
+     * It may loop twice on all modules to check if allowToCreate is true
+     *      -first loop will check if the device is found on a module since declared in the list
+     * of device port in configuration file
+     *      -(allowToCreate is true)second loop will check if the device is weakly supported by one
+     * or more profiles on a given module and will add as a supported device for this module.
+     *       The device will also be added to the dynamic list of device of this module
+     * @param type of the device requested
+     * @param address of the device requested
+     * @param name of the device that requested
+     * @param encodedFormat if not AUDIO_FORMAT_DEFAULT, must match one supported format
+     * @param matchAddress true if a strong match is required
+     * @param allowToCreate true if allowed to create dynamic device (e.g. hdmi, usb...)
+     * @return device descriptor associated to the type (and address if matchAddress is true)
+     */
+    sp<DeviceDescriptor> getDeviceDescriptor(const audio_devices_t type,
+                                             const char *address,
+                                             const char *name,
+                                             audio_format_t encodedFormat,
+                                             bool allowToCreate = false,
+                                             bool matchAddress = true) const;
+
+    /**
+     * @brief createDevice creates a new device from the type and address given. It checks that
+     * according to the device type, a module is supporting this device (weak check).
+     * This concerns only dynamic device, aka device with a specific address and not
+     * already supported by module/underlying profiles.
+     * @param type of the device to be created
+     * @param address of the device to be created
+     * @param name of the device to be created
+     * @return device descriptor if a module is supporting this type, nullptr otherwise.
+     */
+    sp<DeviceDescriptor> createDevice(const audio_devices_t type,
+                                      const char *address,
+                                      const char *name,
+                                      const audio_format_t encodedFormat) const;
+
+    /**
+     * @brief cleanUpForDevice: loop on all profiles of all modules to remove device from
+     * the list of supported device. If this device is a dynamic device (aka a device not in the
+     * xml file with a runtime address), it is also removed from the module collection of dynamic
+     * devices.
+     * @param device that has been disconnected
+     */
+    void cleanUpForDevice(const sp<DeviceDescriptor> &device);
+
+    void dump(String8 *dst) const;
 };
 
 } // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
index 67ac9bc..e0b56d4 100644
--- a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
+++ b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
@@ -35,7 +35,7 @@
 public:
     IOProfile(const String8 &name, audio_port_role_t role)
         : AudioPort(name, AUDIO_PORT_TYPE_MIX, role),
-          maxOpenCount((role == AUDIO_PORT_ROLE_SOURCE) ? 1 : 0),
+          maxOpenCount(1),
           curOpenCount(0),
           maxActiveCount(1),
           curActiveCount(0) {}
@@ -57,12 +57,25 @@
         }
     }
 
-    // This method is used for input and direct output, and is not used for other output.
-    // If parameter updatedSamplingRate is non-NULL, it is assigned the actual sample rate.
-    // For input, flags is interpreted as audio_input_flags_t.
-    // TODO: merge audio_output_flags_t and audio_input_flags_t.
-    bool isCompatibleProfile(audio_devices_t device,
-                             const String8& address,
+    /**
+     * @brief isCompatibleProfile: This method is used for input and direct output,
+     * and is not used for other output.
+     * Checks if the IO profile is compatible with specified parameters.
+     * For input, flags is interpreted as audio_input_flags_t.
+     * TODO: merge audio_output_flags_t and audio_input_flags_t.
+     *
+     * @param devices vector of devices to be checked for compatibility
+     * @param samplingRate to be checked for compatibility. Must be specified
+     * @param updatedSamplingRate if non-NULL, it is assigned the actual sample rate.
+     * @param format to be checked for compatibility. Must be specified
+     * @param updatedFormat if non-NULL, it is assigned the actual format
+     * @param channelMask to be checked for compatibility. Must be specified
+     * @param updatedChannelMask if non-NULL, it is assigned the actual channel mask
+     * @param flags to be checked for compatibility
+     * @param exactMatchRequiredForInputFlags true if exact match is required on flags
+     * @return true if the profile is compatible, false otherwise.
+     */
+    bool isCompatibleProfile(const DeviceVector &devices,
                              uint32_t samplingRate,
                              uint32_t *updatedSamplingRate,
                              audio_format_t format,
@@ -73,54 +86,66 @@
                              uint32_t flags,
                              bool exactMatchRequiredForInputFlags = false) const;
 
-    void dump(int fd);
+    void dump(String8 *dst) const;
     void log();
 
     bool hasSupportedDevices() const { return !mSupportedDevices.isEmpty(); }
 
-    bool supportDevice(audio_devices_t device) const
+    bool supportsDeviceTypes(audio_devices_t device) const
     {
         if (audio_is_output_devices(device)) {
-            return mSupportedDevices.types() & device;
+            if (deviceSupportsEncodedFormats(device)) {
+                return mSupportedDevices.types() & device;
+            }
+            return false;
         }
         return mSupportedDevices.types() & (device & ~AUDIO_DEVICE_BIT_IN);
     }
 
-    bool supportDeviceAddress(const String8 &address) const
+    /**
+     * @brief supportsDevice
+     * @param device to be checked against
+     *        forceCheckOnAddress if true, check on type and address whatever the type, otherwise
+     *        the address enforcement is limited to "offical devices" that distinguishe on address
+     * @return true if the device is supported by type (for non bus / remote submix devices),
+     *         true if the device is supported (both type and address) for bus / remote submix
+     *         false otherwise
+     */
+    bool supportsDevice(const sp<DeviceDescriptor> &device, bool forceCheckOnAddress = false) const
     {
-        return mSupportedDevices[0]->mAddress == address;
-    }
-
-    // chose first device present in mSupportedDevices also part of deviceType
-    audio_devices_t getSupportedDeviceForType(audio_devices_t deviceType) const
-    {
-        for (size_t k = 0; k  < mSupportedDevices.size(); k++) {
-            audio_devices_t profileType = mSupportedDevices[k]->type();
-            if (profileType & deviceType) {
-                return profileType;
-            }
+        if (!device_distinguishes_on_address(device->type()) && !forceCheckOnAddress) {
+            return supportsDeviceTypes(device->type());
         }
-        return AUDIO_DEVICE_NONE;
+        return mSupportedDevices.contains(device);
     }
 
-    audio_devices_t getSupportedDevicesType() const { return mSupportedDevices.types(); }
+    bool deviceSupportsEncodedFormats(audio_devices_t device) const
+    {
+        if (device == AUDIO_DEVICE_NONE) {
+            return true; // required for isOffloadSupported() check
+        }
+        DeviceVector deviceList =
+            mSupportedDevices.getDevicesFromTypeMask(device);
+        if (!deviceList.empty()) {
+            return deviceList.itemAt(0)->hasCurrentEncodedFormat();
+        }
+        return false;
+    }
 
     void clearSupportedDevices() { mSupportedDevices.clear(); }
     void addSupportedDevice(const sp<DeviceDescriptor> &device)
     {
         mSupportedDevices.add(device);
     }
-
+    void removeSupportedDevice(const sp<DeviceDescriptor> &device)
+    {
+        mSupportedDevices.remove(device);
+    }
     void setSupportedDevices(const DeviceVector &devices)
     {
         mSupportedDevices = devices;
     }
 
-    sp<DeviceDescriptor> getSupportedDeviceByAddress(audio_devices_t type, String8 address) const
-    {
-        return mSupportedDevices.getDevice(type, address);
-    }
-
     const DeviceVector &getSupportedDevices() const { return mSupportedDevices; }
 
     bool canOpenNewIo() {
diff --git a/services/audiopolicy/common/managerdefinitions/include/IVolumeCurves.h b/services/audiopolicy/common/managerdefinitions/include/IVolumeCurves.h
new file mode 100644
index 0000000..d408446
--- /dev/null
+++ b/services/audiopolicy/common/managerdefinitions/include/IVolumeCurves.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <system/audio.h>
+#include <Volume.h>
+#include <utils/Errors.h>
+#include <utils/String8.h>
+#include <vector>
+
+namespace android {
+
+class IVolumeCurves
+{
+public:
+    virtual ~IVolumeCurves() = default;
+
+    virtual void clearCurrentVolumeIndex() = 0;
+    virtual void addCurrentVolumeIndex(audio_devices_t device, int index) = 0;
+    virtual bool canBeMuted() const = 0;
+    virtual int getVolumeIndexMin() const = 0;
+    virtual int getVolumeIndex(audio_devices_t device) const = 0;
+    virtual int getVolumeIndexMax() const = 0;
+    virtual float volIndexToDb(device_category device, int indexInUi) const = 0;
+    virtual bool hasVolumeIndexForDevice(audio_devices_t device) const = 0;
+    virtual status_t initVolume(int indexMin, int indexMax) = 0;
+    virtual std::vector<audio_attributes_t> getAttributes() const = 0;
+    virtual std::vector<audio_stream_type_t> getStreamTypes() const = 0;
+    virtual void dump(String8 *dst, int spaces = 0, bool curvePoints = false) const = 0;
+};
+
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/IVolumeCurvesCollection.h b/services/audiopolicy/common/managerdefinitions/include/IVolumeCurvesCollection.h
deleted file mode 100644
index e1f6b08..0000000
--- a/services/audiopolicy/common/managerdefinitions/include/IVolumeCurvesCollection.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <system/audio.h>
-#include <Volume.h>
-#include <utils/Errors.h>
-
-namespace android {
-
-class IVolumeCurvesCollection
-{
-public:
-    virtual ~IVolumeCurvesCollection() = default;
-
-    virtual void clearCurrentVolumeIndex(audio_stream_type_t stream) = 0;
-    virtual void addCurrentVolumeIndex(audio_stream_type_t stream, audio_devices_t device,
-                                       int index) = 0;
-    virtual bool canBeMuted(audio_stream_type_t stream) = 0;
-    virtual int getVolumeIndexMin(audio_stream_type_t stream) const = 0;
-    virtual int getVolumeIndex(audio_stream_type_t stream, audio_devices_t device) = 0;
-    virtual int getVolumeIndexMax(audio_stream_type_t stream) const = 0;
-    virtual float volIndexToDb(audio_stream_type_t stream, device_category device,
-                               int indexInUi) const = 0;
-    virtual status_t initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax) = 0;
-
-    virtual void initializeVolumeCurves(bool /*isSpeakerDrcEnabled*/) {}
-    virtual void switchVolumeCurve(audio_stream_type_t src, audio_stream_type_t dst) = 0;
-    virtual void restoreOriginVolumeCurve(audio_stream_type_t stream)
-    {
-        switchVolumeCurve(stream, stream);
-    }
-    virtual bool hasVolumeIndexForDevice(audio_stream_type_t stream,
-                                         audio_devices_t device) const = 0;
-
-    virtual status_t dump(int fd) const = 0;
-};
-
-} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/Serializer.h b/services/audiopolicy/common/managerdefinitions/include/Serializer.h
index 29de848..48c4147 100644
--- a/services/audiopolicy/common/managerdefinitions/include/Serializer.h
+++ b/services/audiopolicy/common/managerdefinitions/include/Serializer.h
@@ -17,223 +17,9 @@
 #pragma once
 
 #include "AudioPolicyConfig.h"
-#include <utils/StrongPointer.h>
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-#include <string>
-#include <sstream>
-#include <fstream>
-
-struct _xmlNode;
-struct _xmlDoc;
 
 namespace android {
 
-struct AudioGainTraits
-{
-    static const char *const tag;
-    static const char *const collectionTag;
-
-    struct Attributes
-    {
-        static const char mode[]; /**< gain modes supported, e.g. AUDIO_GAIN_MODE_CHANNELS. */
-        /** controlled channels, needed if mode AUDIO_GAIN_MODE_CHANNELS. */
-        static const char channelMask[];
-        static const char minValueMB[]; /**< min value in millibel. */
-        static const char maxValueMB[]; /**< max value in millibel. */
-        static const char defaultValueMB[]; /**< default value in millibel. */
-        static const char stepValueMB[]; /**< step value in millibel. */
-        static const char minRampMs[]; /**< needed if mode AUDIO_GAIN_MODE_RAMP. */
-        static const char maxRampMs[]; /**< .needed if mode AUDIO_GAIN_MODE_RAMP */
-    };
-
-    typedef AudioGain Element;
-    typedef sp<Element> PtrElement;
-    typedef AudioGainCollection Collection;
-    typedef void *PtrSerializingCtx;
-
-    static status_t deserialize(_xmlDoc *doc, const _xmlNode *root, PtrElement &element,
-                                PtrSerializingCtx serializingContext);
-
-    // Gain has no child
-};
-
-// A profile section contains a name,  one audio format and the list of supported sampling rates
-// and channel masks for this format
-struct AudioProfileTraits
-{
-    static const char *const tag;
-    static const char *const collectionTag;
-
-    struct Attributes
-    {
-        static const char name[];
-        static const char samplingRates[];
-        static const char format[];
-        static const char channelMasks[];
-    };
-
-    typedef AudioProfile Element;
-    typedef sp<AudioProfile> PtrElement;
-    typedef AudioProfileVector Collection;
-    typedef void *PtrSerializingCtx;
-
-    static status_t deserialize(_xmlDoc *doc, const _xmlNode *root, PtrElement &element,
-                                PtrSerializingCtx serializingContext);
-};
-
-struct MixPortTraits
-{
-    static const char *const tag;
-    static const char *const collectionTag;
-
-    struct Attributes
-    {
-        static const char name[];
-        static const char role[];
-        static const char flags[];
-        static const char maxOpenCount[];
-        static const char maxActiveCount[];
-    };
-
-    typedef IOProfile Element;
-    typedef sp<Element> PtrElement;
-    typedef IOProfileCollection Collection;
-    typedef void *PtrSerializingCtx;
-
-    static status_t deserialize(_xmlDoc *doc, const _xmlNode *root, PtrElement &element,
-                                PtrSerializingCtx serializingContext);
-
-    // Children are: GainTraits
-};
-
-struct DevicePortTraits
-{
-    static const char *const tag;
-    static const char *const collectionTag;
-
-    struct Attributes
-    {
-        static const char tagName[]; /**<  <device tag name>: any string without space. */
-        static const char type[]; /**< <device type>. */
-        static const char role[]; /**< <device role: sink or source>. */
-        static const char roleSource[]; /**< <attribute role source value>. */
-        static const char address[]; /**< optional: device address, char string less than 64. */
-    };
-    typedef DeviceDescriptor Element;
-    typedef sp<DeviceDescriptor> PtrElement;
-    typedef DeviceVector Collection;
-    typedef void *PtrSerializingCtx;
-
-    static status_t deserialize(_xmlDoc *doc, const _xmlNode *root, PtrElement &element,
-                                PtrSerializingCtx serializingContext);
-    // Children are: GainTraits (optionnal)
-};
-
-struct RouteTraits
-{
-    static const char *const tag;
-    static const char *const collectionTag;
-
-    struct Attributes
-    {
-        static const char type[]; /**< <route type>: mix or mux. */
-        static const char typeMix[]; /**< type attribute mix value. */
-        static const char sink[]; /**< <sink: involved in this route>. */
-        static const char sources[]; /**< sources: all source that can be involved in this route. */
-    };
-    typedef AudioRoute Element;
-    typedef sp<AudioRoute> PtrElement;
-    typedef AudioRouteVector Collection;
-    typedef HwModule *PtrSerializingCtx;
-
-    static status_t deserialize(_xmlDoc *doc, const _xmlNode *root, PtrElement &element,
-                                PtrSerializingCtx ctx);
-};
-
-struct ModuleTraits
-{
-    static const char *const tag;
-    static const char *const collectionTag;
-
-    static const char *const childAttachedDevicesTag;
-    static const char *const childAttachedDeviceTag;
-    static const char *const childDefaultOutputDeviceTag;
-
-    struct Attributes
-    {
-        static const char name[];
-        static const char version[];
-    };
-
-    typedef HwModule Element;
-    typedef sp<Element> PtrElement;
-    typedef HwModuleCollection Collection;
-    typedef AudioPolicyConfig *PtrSerializingCtx;
-
-    static status_t deserialize(_xmlDoc *doc, const _xmlNode *root, PtrElement &element,
-                                PtrSerializingCtx serializingContext);
-
-    // Children are: mixPortTraits, devicePortTraits and routeTraits
-    // Need to call deserialize on each child
-};
-
-struct GlobalConfigTraits
-{
-    static const char *const tag;
-
-    struct Attributes
-    {
-        static const char speakerDrcEnabled[];
-    };
-
-    static status_t deserialize(const _xmlNode *root, AudioPolicyConfig &config);
-};
-
-struct VolumeTraits
-{
-    static const char *const tag;
-    static const char *const collectionTag;
-    static const char *const volumePointTag;
-
-    struct Attributes
-    {
-        static const char stream[];
-        static const char deviceCategory[];
-        static const char reference[];
-    };
-
-    typedef VolumeCurve Element;
-    typedef sp<VolumeCurve> PtrElement;
-    typedef VolumeCurvesCollection Collection;
-    typedef void *PtrSerializingCtx;
-
-    static status_t deserialize(_xmlDoc *doc, const _xmlNode *root, PtrElement &element,
-                                PtrSerializingCtx serializingContext);
-
-    // No Child
-};
-
-class PolicySerializer
-{
-private:
-    static const char *const rootName;
-
-    static const char *const versionAttribute;
-    static const uint32_t gMajor; /**< the major number of the policy xml format version. */
-    static const uint32_t gMinor; /**< the minor number of the policy xml format version. */
-
-public:
-    PolicySerializer();
-    status_t deserialize(const char *str, AudioPolicyConfig &config);
-
-private:
-    typedef AudioPolicyConfig Element;
-
-    std::string mRootElementName;
-    std::string mVersion;
-
-    // Children are: ModulesTraits, VolumeTraits
-};
+status_t deserializeAudioPolicyFile(const char *fileName, AudioPolicyConfig *config);
 
 } // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/SessionRoute.h b/services/audiopolicy/common/managerdefinitions/include/SessionRoute.h
deleted file mode 100644
index 32b4440..0000000
--- a/services/audiopolicy/common/managerdefinitions/include/SessionRoute.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <system/audio.h>
-#include <utils/KeyedVector.h>
-#include <utils/RefBase.h>
-#include <utils/Errors.h>
-
-namespace android {
-
-class DeviceDescriptor;
-class DeviceVector;
-
-class SessionRoute : public RefBase
-{
-public:
-    // For Input (Source) routes, use STREAM_TYPE_NA ("NA" = "not applicable)for the
-    // streamType argument
-    static const audio_stream_type_t STREAM_TYPE_NA = AUDIO_STREAM_DEFAULT;
-
-    // For Output (Sink) routes, use SOURCE_TYPE_NA ("NA" = "not applicable") for the
-    // source argument
-
-    static const audio_source_t SOURCE_TYPE_NA = AUDIO_SOURCE_DEFAULT;
-
-    SessionRoute(audio_session_t session,
-                 audio_stream_type_t streamType,
-                 audio_source_t source,
-                 sp<DeviceDescriptor> deviceDescriptor,
-                 uid_t uid)
-        : mUid(uid),
-          mSession(session),
-          mDeviceDescriptor(deviceDescriptor),
-          mRefCount(0),
-          mActivityCount(0),
-          mChanged(false),
-          mStreamType(streamType),
-          mSource(source)
-    {}
-
-    void log(const char* prefix);
-
-    bool isActiveOrChanged() {
-        return (mDeviceDescriptor != 0) && (mChanged || (mActivityCount > 0));
-    }
-
-    uid_t                       mUid;
-    audio_session_t             mSession;
-    sp<DeviceDescriptor>        mDeviceDescriptor;
-
-    // "reference" counting
-    int                         mRefCount;      // +/- on references
-    int                         mActivityCount; // +/- on start/stop
-    bool                        mChanged;
-    // for outputs
-    const audio_stream_type_t   mStreamType;
-    // for inputs
-    const audio_source_t        mSource;
-};
-
-class SessionRouteMap: public KeyedVector<audio_session_t, sp<SessionRoute> >
-{
-public:
-    // These constants identify the SessionRoutMap as holding EITHER input routes,
-    // or output routes.  An error will occur if an attempt is made to add a SessionRoute
-    // object with mStreamType == STREAM_TYPE_NA (i.e. an input SessionRoute) to a
-    // SessionRoutMap that is marked for output (i.e. mMapType == SESSION_ROUTE_MAP_OUTPUT)
-    // and similarly  for output SessionRoutes and Input SessionRouteMaps.
-    typedef enum
-    {
-        MAPTYPE_INPUT = 0,
-        MAPTYPE_OUTPUT = 1
-    } session_route_map_type_t;
-
-    explicit SessionRouteMap(session_route_map_type_t mapType) :
-        mMapType(mapType)
-    {}
-
-    bool hasRoute(audio_session_t session);
-
-    void removeRoute(audio_session_t session);
-
-    int incRouteActivity(audio_session_t session);
-    int decRouteActivity(audio_session_t session);
-    bool getAndClearRouteChanged(audio_session_t session); // also clears the changed flag
-    void log(const char* caption);
-    audio_devices_t getActiveDeviceForStream(audio_stream_type_t streamType,
-                                             const DeviceVector& availableDevices);
-    // Specify an Output(Sink) route by passing SessionRoute::SOURCE_TYPE_NA in the
-    // source argument.
-    // Specify an Input(Source) rout by passing SessionRoute::AUDIO_STREAM_DEFAULT
-    // in the streamType argument.
-    void addRoute(audio_session_t session,
-                  audio_stream_type_t streamType,
-                  audio_source_t source,
-                  const sp<DeviceDescriptor>& deviceDescriptor,
-                  uid_t uid);
-
-private:
-    // Used to mark a SessionRoute as for either inputs (mMapType == kSessionRouteMap_Input)
-    // or outputs (mMapType == kSessionRouteMap_Output)
-    const session_route_map_type_t mMapType;
-};
-
-} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/StreamDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/StreamDescriptor.h
deleted file mode 100644
index 50b1037..0000000
--- a/services/audiopolicy/common/managerdefinitions/include/StreamDescriptor.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "IVolumeCurvesCollection.h"
-#include <utils/KeyedVector.h>
-#include <utils/StrongPointer.h>
-#include <utils/SortedVector.h>
-#include <system/audio.h>
-
-namespace android {
-
-// stream descriptor used for volume control
-class StreamDescriptor
-{
-public:
-    StreamDescriptor();
-
-    int getVolumeIndex(audio_devices_t device) const;
-    bool canBeMuted() const { return mCanBeMuted; }
-    void clearCurrentVolumeIndex();
-    void addCurrentVolumeIndex(audio_devices_t device, int index);
-    int getVolumeIndexMin() const { return mIndexMin; }
-    int getVolumeIndexMax() const { return mIndexMax; }
-    void setVolumeIndexMin(int volIndexMin);
-    void setVolumeIndexMax(int volIndexMax);
-    bool hasVolumeIndexForDevice(audio_devices_t device) const
-    {
-        device = Volume::getDeviceForVolume(device);
-        return mIndexCur.indexOfKey(device) >= 0;
-    }
-
-    void dump(int fd) const;
-
-    void setVolumeCurvePoint(device_category deviceCategory, const VolumeCurvePoint *point);
-    const VolumeCurvePoint *getVolumeCurvePoint(device_category deviceCategory) const
-    {
-        return mVolumeCurve[deviceCategory];
-    }
-
-private:
-    const VolumeCurvePoint *mVolumeCurve[DEVICE_CATEGORY_CNT];
-    KeyedVector<audio_devices_t, int> mIndexCur; /**< current volume index per device. */
-    int mIndexMin; /**< min volume index. */
-    int mIndexMax; /**< max volume index. */
-    bool mCanBeMuted; /**< true is the stream can be muted. */
-};
-
-/**
- * stream descriptors collection for volume control
- */
-class StreamDescriptorCollection : public DefaultKeyedVector<audio_stream_type_t, StreamDescriptor>,
-                                   public IVolumeCurvesCollection
-{
-public:
-    StreamDescriptorCollection();
-
-    virtual void clearCurrentVolumeIndex(audio_stream_type_t stream);
-    virtual void addCurrentVolumeIndex(audio_stream_type_t stream, audio_devices_t device,
-                                       int index);
-    virtual bool canBeMuted(audio_stream_type_t stream);
-    virtual int getVolumeIndexMin(audio_stream_type_t stream) const
-    {
-        return valueFor(stream).getVolumeIndexMin();
-    }
-    virtual int getVolumeIndex(audio_stream_type_t stream, audio_devices_t device)
-    {
-        return valueFor(stream).getVolumeIndex(device);
-    }
-    virtual int getVolumeIndexMax(audio_stream_type_t stream) const
-    {
-        return valueFor(stream).getVolumeIndexMax();
-    }
-    virtual float volIndexToDb(audio_stream_type_t stream, device_category device,
-                               int indexInUi) const;
-    virtual status_t initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax);
-    virtual void initializeVolumeCurves(bool isSpeakerDrcEnabled);
-    virtual void switchVolumeCurve(audio_stream_type_t streamSrc, audio_stream_type_t streamDst);
-    virtual bool hasVolumeIndexForDevice(audio_stream_type_t stream,
-                                         audio_devices_t device) const
-    {
-        return valueFor(stream).hasVolumeIndexForDevice(device);
-    }
-
-    virtual status_t dump(int fd) const;
-
-private:
-    void setVolumeCurvePoint(audio_stream_type_t stream, device_category deviceCategory,
-                             const VolumeCurvePoint *point);
-    const VolumeCurvePoint *getVolumeCurvePoint(audio_stream_type_t stream,
-                                                device_category deviceCategory) const;
-    void setVolumeIndexMin(audio_stream_type_t stream,int volIndexMin);
-    void setVolumeIndexMax(audio_stream_type_t stream,int volIndexMax);
-};
-
-} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/TypeConverter.h b/services/audiopolicy/common/managerdefinitions/include/TypeConverter.h
index 63c19d1..6b0476c 100644
--- a/services/audiopolicy/common/managerdefinitions/include/TypeConverter.h
+++ b/services/audiopolicy/common/managerdefinitions/include/TypeConverter.h
@@ -23,26 +23,10 @@
 
 namespace android {
 
-struct DeviceCategoryTraits
-{
-    typedef device_category Type;
-    typedef Vector<Type> Collection;
-};
-struct MixTypeTraits
-{
-    typedef int32_t Type;
-    typedef Vector<Type> Collection;
-};
-struct RouteFlagTraits
-{
-    typedef uint32_t Type;
-    typedef Vector<Type> Collection;
-};
-struct RuleTraits
-{
-    typedef uint32_t Type;
-    typedef Vector<Type> Collection;
-};
+struct RuleTraits : public DefaultTraits<uint32_t> {};
+using DeviceCategoryTraits = DefaultTraits<device_category>;
+struct MixTypeTraits : public DefaultTraits<int32_t> {};
+struct RouteFlagTraits : public DefaultTraits<uint32_t> {};
 
 typedef TypeConverter<DeviceCategoryTraits> DeviceCategoryConverter;
 typedef TypeConverter<MixTypeTraits> MixTypeConverter;
diff --git a/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h b/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h
deleted file mode 100644
index 3e6b2b4..0000000
--- a/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "IVolumeCurvesCollection.h"
-#include <policy.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-#include <utils/SortedVector.h>
-#include <utils/KeyedVector.h>
-#include <system/audio.h>
-#include <cutils/config_utils.h>
-#include <string>
-#include <utility>
-
-namespace android {
-
-struct CurvePoint
-{
-    CurvePoint() {}
-    CurvePoint(int index, int attenuationInMb) :
-        mIndex(index), mAttenuationInMb(attenuationInMb) {}
-    uint32_t mIndex;
-    int mAttenuationInMb;
-};
-
-inline bool operator< (const CurvePoint &lhs, const CurvePoint &rhs)
-{
-    return lhs.mIndex < rhs.mIndex;
-}
-
-// A volume curve for a given use case and device category
-// It contains of list of points of this curve expressing the attenuation in Millibels for
-// a given volume index from 0 to 100
-class VolumeCurve : public RefBase
-{
-public:
-    VolumeCurve(device_category device, audio_stream_type_t stream) :
-        mDeviceCategory(device), mStreamType(stream) {}
-
-    device_category getDeviceCategory() const { return mDeviceCategory; }
-    audio_stream_type_t getStreamType() const { return mStreamType; }
-
-    void add(const CurvePoint &point) { mCurvePoints.add(point); }
-
-    float volIndexToDb(int indexInUi, int volIndexMin, int volIndexMax) const;
-
-    void dump(int fd) const;
-
-private:
-    SortedVector<CurvePoint> mCurvePoints;
-    device_category mDeviceCategory;
-    audio_stream_type_t mStreamType;
-};
-
-// Volume Curves for a given use case indexed by device category
-class VolumeCurvesForStream : public KeyedVector<device_category, sp<VolumeCurve> >
-{
-public:
-    VolumeCurvesForStream() : mIndexMin(0), mIndexMax(1), mCanBeMuted(true)
-    {
-        mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, 0);
-    }
-
-    sp<VolumeCurve> getCurvesFor(device_category device) const
-    {
-        if (indexOfKey(device) < 0) {
-            return 0;
-        }
-        return valueFor(device);
-    }
-
-    int getVolumeIndex(audio_devices_t device) const
-    {
-        device = Volume::getDeviceForVolume(device);
-        // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME
-        if (mIndexCur.indexOfKey(device) < 0) {
-            device = AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME;
-        }
-        return mIndexCur.valueFor(device);
-    }
-
-    bool canBeMuted() const { return mCanBeMuted; }
-    void clearCurrentVolumeIndex() { mIndexCur.clear(); }
-    void addCurrentVolumeIndex(audio_devices_t device, int index) { mIndexCur.add(device, index); }
-
-    void setVolumeIndexMin(int volIndexMin) { mIndexMin = volIndexMin; }
-    int getVolumeIndexMin() const { return mIndexMin; }
-
-    void setVolumeIndexMax(int volIndexMax) { mIndexMax = volIndexMax; }
-    int getVolumeIndexMax() const { return mIndexMax; }
-
-    bool hasVolumeIndexForDevice(audio_devices_t device) const
-    {
-        device = Volume::getDeviceForVolume(device);
-        return mIndexCur.indexOfKey(device) >= 0;
-    }
-
-    const sp<VolumeCurve> getOriginVolumeCurve(device_category deviceCategory) const
-    {
-        ALOG_ASSERT(mOriginVolumeCurves.indexOfKey(deviceCategory) >= 0, "Invalid device category");
-        return mOriginVolumeCurves.valueFor(deviceCategory);
-    }
-    void setVolumeCurve(device_category deviceCategory, const sp<VolumeCurve> &volumeCurve)
-    {
-        ALOG_ASSERT(indexOfKey(deviceCategory) >= 0, "Invalid device category for Volume Curve");
-        replaceValueFor(deviceCategory, volumeCurve);
-    }
-
-    ssize_t add(const sp<VolumeCurve> &volumeCurve)
-    {
-        device_category deviceCategory = volumeCurve->getDeviceCategory();
-        ssize_t index = indexOfKey(deviceCategory);
-        if (index < 0) {
-            // Keep track of original Volume Curves per device category in order to switch curves.
-            mOriginVolumeCurves.add(deviceCategory, volumeCurve);
-            return KeyedVector::add(deviceCategory, volumeCurve);
-        }
-        return index;
-    }
-
-    float volIndexToDb(device_category deviceCat, int indexInUi) const
-    {
-        sp<VolumeCurve> vc = getCurvesFor(deviceCat);
-        if (vc != 0) {
-            return vc->volIndexToDb(indexInUi, mIndexMin, mIndexMax);
-        } else {
-            ALOGE("Invalid device category %d for Volume Curve", deviceCat);
-            return 0.0f;
-        }
-    }
-
-    void dump(int fd, int spaces, bool curvePoints = false) const;
-
-private:
-    KeyedVector<device_category, sp<VolumeCurve> > mOriginVolumeCurves;
-    KeyedVector<audio_devices_t, int> mIndexCur; /**< current volume index per device. */
-    int mIndexMin; /**< min volume index. */
-    int mIndexMax; /**< max volume index. */
-    bool mCanBeMuted; /**< true is the stream can be muted. */
-};
-
-// Collection of Volume Curves indexed by use case
-class VolumeCurvesCollection : public KeyedVector<audio_stream_type_t, VolumeCurvesForStream>,
-                               public IVolumeCurvesCollection
-{
-public:
-    VolumeCurvesCollection()
-    {
-        // Create an empty collection of curves
-        for (ssize_t i = 0 ; i < AUDIO_STREAM_CNT; i++) {
-            audio_stream_type_t stream = static_cast<audio_stream_type_t>(i);
-            KeyedVector::add(stream, VolumeCurvesForStream());
-        }
-    }
-
-    // Once XML has been parsed, must be call first to sanity check table and initialize indexes
-    virtual status_t initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax)
-    {
-        editValueAt(stream).setVolumeIndexMin(indexMin);
-        editValueAt(stream).setVolumeIndexMax(indexMax);
-        return NO_ERROR;
-    }
-    virtual void clearCurrentVolumeIndex(audio_stream_type_t stream)
-    {
-        editCurvesFor(stream).clearCurrentVolumeIndex();
-    }
-    virtual void addCurrentVolumeIndex(audio_stream_type_t stream, audio_devices_t device, int index)
-    {
-        editCurvesFor(stream).addCurrentVolumeIndex(device, index);
-    }
-    virtual bool canBeMuted(audio_stream_type_t stream) { return getCurvesFor(stream).canBeMuted(); }
-
-    virtual int getVolumeIndexMin(audio_stream_type_t stream) const
-    {
-        return getCurvesFor(stream).getVolumeIndexMin();
-    }
-    virtual int getVolumeIndexMax(audio_stream_type_t stream) const
-    {
-        return getCurvesFor(stream).getVolumeIndexMax();
-    }
-    virtual int getVolumeIndex(audio_stream_type_t stream, audio_devices_t device)
-    {
-        return getCurvesFor(stream).getVolumeIndex(device);
-    }
-    virtual void switchVolumeCurve(audio_stream_type_t streamSrc, audio_stream_type_t streamDst)
-    {
-        const VolumeCurvesForStream &sourceCurves = getCurvesFor(streamSrc);
-        VolumeCurvesForStream &dstCurves = editCurvesFor(streamDst);
-        ALOG_ASSERT(sourceCurves.size() == dstCurves.size(), "device category not aligned");
-        for (size_t index = 0; index < sourceCurves.size(); index++) {
-            device_category cat = sourceCurves.keyAt(index);
-            dstCurves.setVolumeCurve(cat, sourceCurves.getOriginVolumeCurve(cat));
-        }
-    }
-    virtual float volIndexToDb(audio_stream_type_t stream, device_category cat, int indexInUi) const
-    {
-        return getCurvesFor(stream).volIndexToDb(cat, indexInUi);
-    }
-    virtual bool hasVolumeIndexForDevice(audio_stream_type_t stream,
-                                         audio_devices_t device) const
-    {
-        return getCurvesFor(stream).hasVolumeIndexForDevice(device);
-    }
-
-    virtual status_t dump(int fd) const;
-
-    ssize_t add(const sp<VolumeCurve> &volumeCurve)
-    {
-        audio_stream_type_t streamType = volumeCurve->getStreamType();
-        return editCurvesFor(streamType).add(volumeCurve);
-    }
-    VolumeCurvesForStream &editCurvesFor(audio_stream_type_t stream)
-    {
-        ALOG_ASSERT(indexOfKey(stream) >= 0, "Invalid stream type for Volume Curve");
-        return editValueAt(stream);
-    }
-    const VolumeCurvesForStream &getCurvesFor(audio_stream_type_t stream) const
-    {
-        ALOG_ASSERT(indexOfKey(stream) >= 0, "Invalid stream type for Volume Curve");
-        return valueFor(stream);
-    }
-};
-
-} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioCollections.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioCollections.cpp
index ca67b87..c90a582 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioCollections.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioCollections.cpp
@@ -35,22 +35,16 @@
     return nullptr;
 }
 
-status_t AudioRouteVector::dump(int fd, int spaces) const
+void AudioRouteVector::dump(String8 *dst, int spaces) const
 {
     if (isEmpty()) {
-        return NO_ERROR;
+        return;
     }
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE, "\n%*sAudio Routes (%zu):\n", spaces, "", size());
-    write(fd, buffer, strlen(buffer));
+    dst->appendFormat("\n%*sAudio Routes (%zu):\n", spaces, "", size());
     for (size_t i = 0; i < size(); i++) {
-        snprintf(buffer, SIZE, "%*s- Route %zu:\n", spaces, "", i + 1);
-        write(fd, buffer, strlen(buffer));
-        itemAt(i)->dump(fd, 4);
+        dst->appendFormat("%*s- Route %zu:\n", spaces, "", i + 1);
+        itemAt(i)->dump(dst, 4);
     }
-    return NO_ERROR;
 }
 
 } // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioGain.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioGain.cpp
index 193d4a6..2725870 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioGain.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioGain.cpp
@@ -98,32 +98,17 @@
     return NO_ERROR;
 }
 
-void AudioGain::dump(int fd, int spaces, int index) const
+void AudioGain::dump(String8 *dst, int spaces, int index) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "%*sGain %d:\n", spaces, "", index+1);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- mode: %08x\n", spaces, "", mGain.mode);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- channel_mask: %08x\n", spaces, "", mGain.channel_mask);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- min_value: %d mB\n", spaces, "", mGain.min_value);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- max_value: %d mB\n", spaces, "", mGain.max_value);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- default_value: %d mB\n", spaces, "", mGain.default_value);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- step_value: %d mB\n", spaces, "", mGain.step_value);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- min_ramp_ms: %d ms\n", spaces, "", mGain.min_ramp_ms);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- max_ramp_ms: %d ms\n", spaces, "", mGain.max_ramp_ms);
-    result.append(buffer);
-
-    write(fd, result.string(), result.size());
+    dst->appendFormat("%*sGain %d:\n", spaces, "", index+1);
+    dst->appendFormat("%*s- mode: %08x\n", spaces, "", mGain.mode);
+    dst->appendFormat("%*s- channel_mask: %08x\n", spaces, "", mGain.channel_mask);
+    dst->appendFormat("%*s- min_value: %d mB\n", spaces, "", mGain.min_value);
+    dst->appendFormat("%*s- max_value: %d mB\n", spaces, "", mGain.max_value);
+    dst->appendFormat("%*s- default_value: %d mB\n", spaces, "", mGain.default_value);
+    dst->appendFormat("%*s- step_value: %d mB\n", spaces, "", mGain.step_value);
+    dst->appendFormat("%*s- min_ramp_ms: %d ms\n", spaces, "", mGain.min_ramp_ms);
+    dst->appendFormat("%*s- max_ramp_ms: %d ms\n", spaces, "", mGain.max_ramp_ms);
 }
 
 } // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
index 27bc4c6..a096e8f 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
@@ -17,23 +17,21 @@
 #define LOG_TAG "APM::AudioInputDescriptor"
 //#define LOG_NDEBUG 0
 
+#include <audiomanager/AudioManager.h>
+#include <media/AudioPolicy.h>
+#include <policy.h>
 #include <AudioPolicyInterface.h>
 #include "AudioInputDescriptor.h"
-#include "IOProfile.h"
 #include "AudioGain.h"
 #include "AudioPolicyMix.h"
 #include "HwModule.h"
-#include <media/AudioPolicy.h>
-#include <policy.h>
 
 namespace android {
 
 AudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile,
                                            AudioPolicyClientInterface *clientInterface)
-    : mIoHandle(0),
-      mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL),
-      mProfile(profile), mPatchHandle(AUDIO_PATCH_HANDLE_NONE), mId(0),
-      mClientInterface(clientInterface)
+    : mProfile(profile)
+    ,  mClientInterface(clientInterface)
 {
     if (profile != NULL) {
         profile->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
@@ -51,19 +49,14 @@
     return mProfile->getModuleHandle();
 }
 
-uint32_t AudioInputDescriptor::getOpenRefCount() const
-{
-    return mSessions.getOpenCount();
-}
-
 audio_port_handle_t AudioInputDescriptor::getId() const
 {
     return mId;
 }
 
-audio_source_t AudioInputDescriptor::inputSource(bool activeOnly) const
+audio_source_t AudioInputDescriptor::source() const
 {
-    return getHighestPrioritySource(activeOnly);
+    return getHighestPriorityAttributes().source;
 }
 
 void AudioInputDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
@@ -84,7 +77,7 @@
     dstConfig->type = AUDIO_PORT_TYPE_MIX;
     dstConfig->ext.mix.hw_module = getModuleHandle();
     dstConfig->ext.mix.handle = mIoHandle;
-    dstConfig->ext.mix.usecase.source = inputSource();
+    dstConfig->ext.mix.usecase.source = source();
 }
 
 void AudioInputDescriptor::toAudioPort(struct audio_port *port) const
@@ -119,57 +112,62 @@
     mPreemptedSessions.clear();
 }
 
-bool AudioInputDescriptor::isActive() const {
-    return mSessions.hasActiveSession();
-}
-
 bool AudioInputDescriptor::isSourceActive(audio_source_t source) const
 {
-    return mSessions.isSourceActive(source);
+    for (const auto &client : getClientIterable()) {
+        if (client->active() &&
+            ((client->source() == source) ||
+                ((source == AUDIO_SOURCE_VOICE_RECOGNITION) &&
+                    (client->source() == AUDIO_SOURCE_HOTWORD) &&
+                    client->isSoundTrigger()))) {
+            return true;
+        }
+    }
+    return false;
 }
 
-audio_source_t AudioInputDescriptor::getHighestPrioritySource(bool activeOnly) const
+audio_attributes_t AudioInputDescriptor::getHighestPriorityAttributes() const
 {
+    audio_attributes_t attributes = { .source = AUDIO_SOURCE_DEFAULT };
+    sp<RecordClientDescriptor> topClient = getHighestPriorityClient();
+    return topClient ? topClient->attributes() : attributes;
+}
 
-    return mSessions.getHighestPrioritySource(activeOnly);
+sp<RecordClientDescriptor> AudioInputDescriptor::getHighestPriorityClient() const
+{
+    sp<RecordClientDescriptor> topClient;
+
+    for (bool activeOnly : { true, false }) {
+        int32_t topPriority = -1;
+        app_state_t topState = APP_STATE_IDLE;
+        for (const auto &client : getClientIterable()) {
+            if (activeOnly && !client->active()) {
+              continue;
+            }
+            app_state_t curState = client->appState();
+            if (curState >= topState) {
+                int32_t curPriority = source_priority(client->source());
+                if (curPriority >= topPriority) {
+                    topClient = client;
+                    topPriority = curPriority;
+                }
+                topState = curState;
+            }
+        }
+        if (topClient != nullptr) {
+            break;
+        }
+    }
+    return topClient;
 }
 
 bool AudioInputDescriptor::isSoundTrigger() const {
-    // sound trigger and non sound trigger sessions are not mixed
-    // on a given input
-    return mSessions.valueAt(0)->isSoundTrigger();
-}
-
-sp<AudioSession> AudioInputDescriptor::getAudioSession(
-                                              audio_session_t session) const {
-    return mSessions.valueFor(session);
-}
-
-AudioSessionCollection AudioInputDescriptor::getAudioSessions(bool activeOnly) const
-{
-    if (activeOnly) {
-        return mSessions.getActiveSessions();
-    } else {
-        return mSessions;
+    // sound trigger and non sound trigger clients are not mixed on a given input
+    // so check only first client
+    if (getClientCount() == 0) {
+        return false;
     }
-}
-
-size_t AudioInputDescriptor::getAudioSessionCount(bool activeOnly) const
-{
-    if (activeOnly) {
-        return mSessions.getActiveSessionCount();
-    } else {
-        return mSessions.size();
-    }
-}
-
-status_t AudioInputDescriptor::addAudioSession(audio_session_t session,
-                         const sp<AudioSession>& audioSession) {
-    return mSessions.addSession(session, audioSession, /*AudioSessionInfoProvider*/this);
-}
-
-status_t AudioInputDescriptor::removeAudioSession(audio_session_t session) {
-    return mSessions.removeSession(session);
+    return getClientIterable().begin()->isSoundTrigger();
 }
 
 audio_patch_handle_t AudioInputDescriptor::getPatchHandle() const
@@ -180,7 +178,13 @@
 void AudioInputDescriptor::setPatchHandle(audio_patch_handle_t handle)
 {
     mPatchHandle = handle;
-    mSessions.onSessionInfoUpdate();
+    for (const auto &client : getClientIterable()) {
+        if (client->active()) {
+            updateClientRecordingConfiguration(
+                    client->isLowLevel() ? RECORD_CONFIG_EVENT_START : RECORD_CONFIG_EVENT_UPDATE,
+                    client);
+        }
+    }
 }
 
 audio_config_base_t AudioInputDescriptor::getConfig() const
@@ -191,8 +195,7 @@
 }
 
 status_t AudioInputDescriptor::open(const audio_config_t *config,
-                                       audio_devices_t device,
-                                       const String8& address,
+                                       const sp<DeviceDescriptor> &device,
                                        audio_source_t source,
                                        audio_input_flags_t flags,
                                        audio_io_handle_t *input)
@@ -209,24 +212,26 @@
 
     mDevice = device;
 
-    ALOGV("opening input for device %08x address %s profile %p name %s",
-          mDevice, address.string(), mProfile.get(), mProfile->getName().string());
+    ALOGV("opening input for device %s profile %p name %s",
+          mDevice->toString().c_str(), mProfile.get(), mProfile->getName().string());
+
+    audio_devices_t deviceType = mDevice->type();
 
     status_t status = mClientInterface->openInput(mProfile->getModuleHandle(),
                                                   input,
                                                   &lConfig,
-                                                  &mDevice,
-                                                  address,
+                                                  &deviceType,
+                                                  mDevice->address(),
                                                   source,
                                                   flags);
-    LOG_ALWAYS_FATAL_IF(mDevice != device,
+    LOG_ALWAYS_FATAL_IF(mDevice->type() != deviceType,
                         "%s openInput returned device %08x when given device %08x",
-                        __FUNCTION__, mDevice, device);
+                        __FUNCTION__, mDevice->type(), deviceType);
 
     if (status == NO_ERROR) {
         LOG_ALWAYS_FATAL_IF(*input == AUDIO_IO_HANDLE_NONE,
-                            "%s openInput returned input handle %d for device %08x",
-                            __FUNCTION__, *input, device);
+                            "%s openInput returned input handle %d for device %s",
+                            __FUNCTION__, *input, mDevice->toString().c_str());
         mSamplingRate = lConfig.sample_rate;
         mChannelMask = lConfig.channel_mask;
         mFormat = lConfig.format;
@@ -240,7 +245,7 @@
 
 status_t AudioInputDescriptor::start()
 {
-    if (getAudioSessionCount(true/*activeOnly*/) == 1) {
+    if (!isActive()) {
         if (!mProfile->canStartNewIo()) {
             ALOGI("%s mProfile->curActiveCount %d", __func__, mProfile->curActiveCount);
             return INVALID_OPERATION;
@@ -263,42 +268,247 @@
 void AudioInputDescriptor::close()
 {
     if (mIoHandle != AUDIO_IO_HANDLE_NONE) {
+        // clean up active clients if any (can happen if close() is called to force
+        // clients to reconnect
+        for (const auto &client : getClientIterable()) {
+            if (client->active()) {
+                ALOGW("%s client with port ID %d still active on input %d",
+                    __func__, client->portId(), mId);
+                setClientActive(client, false);
+                stop();
+            }
+        }
+
         mClientInterface->closeInput(mIoHandle);
         LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
                             __FUNCTION__, mProfile->curOpenCount);
-        // do not call stop() here as stop() is supposed to be called after
-        // AudioSession::changeActiveCount(-1) and we don't know how many sessions
-        // are still active at this time
-        if (isActive()) {
-            mProfile->curActiveCount--;
-        }
+
         mProfile->curOpenCount--;
+        LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount <  mProfile->curActiveCount,
+                "%s(%d): mProfile->curOpenCount %d < mProfile->curActiveCount %d.",
+                __func__, mId, mProfile->curOpenCount, mProfile->curActiveCount);
         mIoHandle = AUDIO_IO_HANDLE_NONE;
     }
 }
 
-status_t AudioInputDescriptor::dump(int fd)
+void AudioInputDescriptor::addClient(const sp<RecordClientDescriptor> &client) {
+    ClientMapHandler<RecordClientDescriptor>::addClient(client);
+
+    for (size_t i = 0; i < mEnabledEffects.size(); i++) {
+        if (mEnabledEffects.valueAt(i)->mSession == client->session()) {
+            client->trackEffectEnabled(mEnabledEffects.valueAt(i), true);
+        }
+    }
+}
+
+void AudioInputDescriptor::setClientActive(const sp<RecordClientDescriptor>& client, bool active)
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
+    LOG_ALWAYS_FATAL_IF(getClient(client->portId()) == nullptr,
+        "%s(%d) does not exist on input descriptor", __func__, client->portId());
+    if (active == client->active()) {
+        return;
+    }
 
-    snprintf(buffer, SIZE, " ID: %d\n", getId());
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Format: %d\n", mFormat);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
-    result.append(buffer);
+    // Handle non-client-specific activity ref count
+    int32_t oldGlobalActiveCount = mGlobalActiveCount;
+    if (!active && mGlobalActiveCount < 1) {
+        LOG_ALWAYS_FATAL("%s(%d) invalid deactivation with globalActiveCount %d",
+               __func__, client->portId(), mGlobalActiveCount);
+        // mGlobalActiveCount = 1;
+    }
+    const int delta = active ? 1 : -1;
+    mGlobalActiveCount += delta;
 
-    write(fd, result.string(), result.size());
+    sp<AudioPolicyMix> policyMix = mPolicyMix.promote();
+    if ((oldGlobalActiveCount == 0) && (mGlobalActiveCount > 0)) {
+        if ((policyMix != NULL) && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
+        {
+            mClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
+                                                            MIX_STATE_MIXING);
+        }
+    } else if ((oldGlobalActiveCount > 0) && (mGlobalActiveCount == 0)) {
+        if ((policyMix != NULL) && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
+        {
+            mClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
+                                                            MIX_STATE_IDLE);
+        }
+    }
 
-    mSessions.dump(fd, 1);
+    client->setActive(active);
 
-    return NO_ERROR;
+    checkSuspendEffects();
+
+    int event = active ? RECORD_CONFIG_EVENT_START : RECORD_CONFIG_EVENT_STOP;
+    updateClientRecordingConfiguration(event, client);
+}
+
+void AudioInputDescriptor::updateClientRecordingConfiguration(
+    int event, const sp<RecordClientDescriptor>& client)
+{
+    ALOGV("%s riid %d uid %d port %d session %d event %d",
+            __func__, client->riid(), client->uid(), client->portId(), client->session(), event);
+    // do not send callback if starting and no device is selected yet to avoid
+    // double callbacks from startInput() before and after the device is selected
+    // "start" and "stop" events for "high level" clients (AudioRecord) are sent by the client side
+    if ((event == RECORD_CONFIG_EVENT_START && mPatchHandle == AUDIO_PATCH_HANDLE_NONE)
+            || (!client->isLowLevel()
+                    && (event == RECORD_CONFIG_EVENT_START || event == RECORD_CONFIG_EVENT_STOP))) {
+        return;
+    }
+
+    const audio_config_base_t sessionConfig = client->config();
+    const record_client_info_t recordClientInfo{client->riid(), client->uid(), client->session(),
+                                                client->source(), client->portId(),
+                                                client->isSilenced()};
+    const audio_config_base_t config = getConfig();
+
+    std::vector<effect_descriptor_t> clientEffects;
+    EffectDescriptorCollection effectsList = client->getEnabledEffects();
+    for (size_t i = 0; i < effectsList.size(); i++) {
+        clientEffects.push_back(effectsList.valueAt(i)->mDesc);
+    }
+
+    std::vector<effect_descriptor_t> effects;
+    effectsList = getEnabledEffects();
+    for (size_t i = 0; i < effectsList.size(); i++) {
+        effects.push_back(effectsList.valueAt(i)->mDesc);
+    }
+
+    mClientInterface->onRecordingConfigurationUpdate(event, &recordClientInfo, &sessionConfig,
+                                                     clientEffects, &config, effects,
+                                                     mPatchHandle, source());
+}
+
+RecordClientVector AudioInputDescriptor::getClientsForSession(
+    audio_session_t session)
+{
+    RecordClientVector clients;
+    for (const auto &client : getClientIterable()) {
+        if (client->session() == session) {
+            clients.push_back(client);
+        }
+    }
+    return clients;
+}
+
+RecordClientVector AudioInputDescriptor::clientsList(bool activeOnly, audio_source_t source,
+                                                     bool preferredDeviceOnly) const
+{
+    RecordClientVector clients;
+    for (const auto &client : getClientIterable()) {
+        if ((!activeOnly || client->active())
+            && (source == AUDIO_SOURCE_DEFAULT || source == client->source())
+            && (!preferredDeviceOnly || client->hasPreferredDevice())) {
+            clients.push_back(client);
+        }
+    }
+    return clients;
+}
+
+void AudioInputDescriptor::trackEffectEnabled(const sp<EffectDescriptor> &effect,
+                                              bool enabled)
+{
+    if (enabled) {
+        mEnabledEffects.replaceValueFor(effect->mId, effect);
+    } else {
+        mEnabledEffects.removeItem(effect->mId);
+        // always exit from suspend when disabling an effect as only enabled effects
+        // are managed by checkSuspendEffects()
+        if (effect->mSuspended) {
+            effect->mSuspended = false;
+            mClientInterface->setEffectSuspended(effect->mId, effect->mSession, effect->mSuspended);
+        }
+    }
+
+    RecordClientVector clients = getClientsForSession((audio_session_t)effect->mSession);
+    RecordClientVector updatedClients;
+
+    for (const auto& client : clients) {
+        sp<EffectDescriptor> clientEffect = client->getEnabledEffects().getEffect(effect->mId);
+        bool changed = (enabled && clientEffect == nullptr)
+                || (!enabled && clientEffect != nullptr);
+        client->trackEffectEnabled(effect, enabled);
+        if (changed && client->active()) {
+            updatedClients.push_back(client);
+        }
+    }
+
+    checkSuspendEffects();
+
+    for (const auto& client : updatedClients) {
+        updateClientRecordingConfiguration(RECORD_CONFIG_EVENT_UPDATE, client);
+    }
+}
+
+EffectDescriptorCollection AudioInputDescriptor::getEnabledEffects() const
+{
+    // report effects for highest priority active source as applied to all clients
+    EffectDescriptorCollection enabledEffects;
+    sp<RecordClientDescriptor> topClient = getHighestPriorityClient();
+    if (topClient != nullptr) {
+        enabledEffects = topClient->getEnabledEffects();
+    }
+    return enabledEffects;
+}
+
+void AudioInputDescriptor::setAppState(uid_t uid, app_state_t state)
+{
+    RecordClientVector clients = clientsList(false /*activeOnly*/);
+    RecordClientVector updatedClients;
+
+    for (const auto& client : clients) {
+        if (uid == client->uid()) {
+            bool wasSilenced = client->isSilenced();
+            client->setAppState(state);
+            if (client->active() && wasSilenced != client->isSilenced()) {
+                updatedClients.push_back(client);
+            }
+        }
+    }
+
+    checkSuspendEffects();
+
+    for (const auto& client : updatedClients) {
+        updateClientRecordingConfiguration(RECORD_CONFIG_EVENT_UPDATE, client);
+    }
+}
+
+void AudioInputDescriptor::checkSuspendEffects()
+{
+    sp<RecordClientDescriptor> topClient = getHighestPriorityClient();
+    if (topClient == nullptr) {
+        return;
+    }
+
+    for (size_t i = 0; i < mEnabledEffects.size(); i++) {
+        sp<EffectDescriptor> effect = mEnabledEffects.valueAt(i);
+        if (effect->mSession == topClient->session()) {
+            if (effect->mSuspended) {
+                effect->mSuspended = false;
+                mClientInterface->setEffectSuspended(effect->mId,
+                                                     effect->mSession,
+                                                     effect->mSuspended);
+            }
+        } else if (!effect->mSuspended) {
+            effect->mSuspended = true;
+            mClientInterface->setEffectSuspended(effect->mId,
+                                                 effect->mSession,
+                                                 effect->mSuspended);
+        }
+    }
+}
+
+void AudioInputDescriptor::dump(String8 *dst) const
+{
+    dst->appendFormat(" ID: %d\n", getId());
+    dst->appendFormat(" Sampling rate: %d\n", mSamplingRate);
+    dst->appendFormat(" Format: %d\n", mFormat);
+    dst->appendFormat(" Channels: %08x\n", mChannelMask);
+    dst->appendFormat(" Devices %s\n", mDevice->toString().c_str());
+    mEnabledEffects.dump(dst, 1 /*spaces*/, false /*verbose*/);
+    dst->append(" AudioRecord Clients:\n");
+    ClientMapHandler<RecordClientDescriptor>::dump(dst);
+    dst->append("\n");
 }
 
 bool AudioInputCollection::isSourceActive(audio_source_t source) const
@@ -314,66 +524,83 @@
 
 sp<AudioInputDescriptor> AudioInputCollection::getInputFromId(audio_port_handle_t id) const
 {
-    sp<AudioInputDescriptor> inputDesc = NULL;
     for (size_t i = 0; i < size(); i++) {
-        inputDesc = valueAt(i);
-        if (inputDesc->getId() == id) {
-            break;
+        const sp<AudioInputDescriptor> inputDescriptor = valueAt(i);
+        if (inputDescriptor->getId() == id) {
+            return inputDescriptor;
         }
     }
-    return inputDesc;
+    return NULL;
 }
 
-uint32_t AudioInputCollection::activeInputsCountOnDevices(audio_devices_t devices) const
+uint32_t AudioInputCollection::activeInputsCountOnDevices(const DeviceVector &devices) const
 {
     uint32_t count = 0;
     for (size_t i = 0; i < size(); i++) {
         const sp<AudioInputDescriptor>  inputDescriptor = valueAt(i);
         if (inputDescriptor->isActive() &&
-                ((devices == AUDIO_DEVICE_IN_DEFAULT) ||
-                 ((inputDescriptor->mDevice & devices & ~AUDIO_DEVICE_BIT_IN) != 0))) {
+                (devices.isEmpty() || devices.contains(inputDescriptor->getDevice()))) {
             count++;
         }
     }
     return count;
 }
 
-Vector<sp <AudioInputDescriptor> > AudioInputCollection::getActiveInputs(bool ignoreVirtualInputs)
+Vector<sp <AudioInputDescriptor> > AudioInputCollection::getActiveInputs()
 {
     Vector<sp <AudioInputDescriptor> > activeInputs;
 
     for (size_t i = 0; i < size(); i++) {
         const sp<AudioInputDescriptor>  inputDescriptor = valueAt(i);
-        if ((inputDescriptor->isActive())
-                && (!ignoreVirtualInputs ||
-                    !is_virtual_input_device(inputDescriptor->mDevice))) {
+        if (inputDescriptor->isActive()) {
             activeInputs.add(inputDescriptor);
         }
     }
     return activeInputs;
 }
 
-audio_devices_t AudioInputCollection::getSupportedDevices(audio_io_handle_t handle) const
+sp<AudioInputDescriptor> AudioInputCollection::getInputForClient(audio_port_handle_t portId)
 {
-    sp<AudioInputDescriptor> inputDesc = valueFor(handle);
-    audio_devices_t devices = inputDesc->mProfile->getSupportedDevicesType();
-    return devices;
+    for (size_t i = 0; i < size(); i++) {
+        sp<AudioInputDescriptor> inputDesc = valueAt(i);
+        if (inputDesc->getClient(portId) != nullptr) {
+            return inputDesc;
+        }
+    }
+    return 0;
 }
 
-status_t AudioInputCollection::dump(int fd) const
+void AudioInputCollection::trackEffectEnabled(const sp<EffectDescriptor> &effect,
+                                            bool enabled)
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE, "\nInputs dump:\n");
-    write(fd, buffer, strlen(buffer));
     for (size_t i = 0; i < size(); i++) {
-        snprintf(buffer, SIZE, "- Input %d dump:\n", keyAt(i));
-        write(fd, buffer, strlen(buffer));
-        valueAt(i)->dump(fd);
+        sp<AudioInputDescriptor> inputDesc = valueAt(i);
+        if (inputDesc->mIoHandle == effect->mIo) {
+            return inputDesc->trackEffectEnabled(effect, enabled);
+        }
     }
+}
 
-    return NO_ERROR;
+void AudioInputCollection::clearSessionRoutesForDevice(
+    const sp<DeviceDescriptor> &disconnectedDevice)
+{
+    for (size_t i = 0; i < size(); i++) {
+        sp<AudioInputDescriptor> inputDesc = valueAt(i);
+        for (const auto& client : inputDesc->getClientIterable()) {
+            if (client->preferredDeviceId() == disconnectedDevice->getId()) {
+                client->setPreferredDeviceId(AUDIO_PORT_HANDLE_NONE);
+            }
+        }
+    }
+}
+
+void AudioInputCollection::dump(String8 *dst) const
+{
+    dst->append("\nInputs dump:\n");
+    for (size_t i = 0; i < size(); i++) {
+        dst->appendFormat("- Input %d dump:\n", keyAt(i));
+        valueAt(i)->dump(dst);
+    }
 }
 
 }; //namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index d15ba4b..8a60cf2 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -24,6 +24,7 @@
 #include "AudioGain.h"
 #include "Volume.h"
 #include "HwModule.h"
+#include "TypeConverter.h"
 #include <media/AudioParameter.h>
 #include <media/AudioPolicy.h>
 
@@ -35,19 +36,8 @@
 
 AudioOutputDescriptor::AudioOutputDescriptor(const sp<AudioPort>& port,
                                              AudioPolicyClientInterface *clientInterface)
-    : mPort(port), mDevice(AUDIO_DEVICE_NONE),
-      mClientInterface(clientInterface), mPatchHandle(AUDIO_PATCH_HANDLE_NONE), mId(0)
+    : mPort(port), mClientInterface(clientInterface)
 {
-    // clear usage count for all stream types
-    for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
-        mRefCount[i] = 0;
-        mCurVolume[i] = -1.0;
-        mMuteCount[i] = 0;
-        mStopTime[i] = 0;
-    }
-    for (int i = 0; i < NUM_STRATEGIES; i++) {
-        mStrategyMutedByDevice[i] = false;
-    }
     if (mPort.get() != nullptr) {
         mPort->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
         if (mPort->mGains.size() > 0) {
@@ -56,48 +46,88 @@
     }
 }
 
+audio_config_base_t AudioOutputDescriptor::getConfig() const
+{
+    const audio_config_base_t config = { .sample_rate = mSamplingRate, .channel_mask = mChannelMask,
+            .format = mFormat };
+    return config;
+}
+
 audio_module_handle_t AudioOutputDescriptor::getModuleHandle() const
 {
     return mPort.get() != nullptr ? mPort->getModuleHandle() : AUDIO_MODULE_HANDLE_NONE;
 }
 
+audio_patch_handle_t AudioOutputDescriptor::getPatchHandle() const
+{
+    return mPatchHandle;
+}
+
+void AudioOutputDescriptor::setPatchHandle(audio_patch_handle_t handle)
+{
+    mPatchHandle = handle;
+}
+
 audio_port_handle_t AudioOutputDescriptor::getId() const
 {
     return mId;
 }
 
-audio_devices_t AudioOutputDescriptor::device() const
-{
-    return mDevice;
-}
-
-audio_devices_t AudioOutputDescriptor::supportedDevices()
-{
-    return mDevice;
-}
-
 bool AudioOutputDescriptor::sharesHwModuleWith(
         const sp<AudioOutputDescriptor>& outputDesc)
 {
-    if (outputDesc->isDuplicated()) {
-        return sharesHwModuleWith(outputDesc->subOutput1()) ||
-                    sharesHwModuleWith(outputDesc->subOutput2());
-    } else {
-        return hasSameHwModuleAs(outputDesc);
-    }
+    return hasSameHwModuleAs(outputDesc);
 }
 
-void AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
-                                                                   int delta)
+void AudioOutputDescriptor::setStopTime(const sp<TrackClientDescriptor>& client, nsecs_t sysTime)
 {
-    if ((delta + (int)mRefCount[stream]) < 0) {
-        ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d",
-              delta, stream, mRefCount[stream]);
-        mRefCount[stream] = 0;
+    mVolumeActivities[client->volumeSource()].setStopTime(sysTime);
+    mRoutingActivities[client->strategy()].setStopTime(sysTime);
+}
+
+void AudioOutputDescriptor::setClientActive(const sp<TrackClientDescriptor>& client, bool active)
+{
+    auto clientIter = std::find(begin(mActiveClients), end(mActiveClients), client);
+    if (active == (clientIter != end(mActiveClients))) {
+        ALOGW("%s(%s): ignored active: %d, current stream count %d", __func__,
+              client->toShortString().c_str(), active,
+              mRoutingActivities.at(client->strategy()).getActivityCount());
         return;
     }
-    mRefCount[stream] += delta;
-    ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
+    if (active) {
+        mActiveClients.push_back(client);
+    } else {
+        mActiveClients.erase(clientIter);
+    }
+    const int delta = active ? 1 : -1;
+    // If ps is unknown, it is time to track it!
+    mRoutingActivities[client->strategy()].changeActivityCount(delta);
+    mVolumeActivities[client->volumeSource()].changeActivityCount(delta);
+
+    // Handle non-client-specific activity ref count
+    int32_t oldGlobalActiveCount = mGlobalActiveCount;
+    if (!active && mGlobalActiveCount < 1) {
+        ALOGW("%s(%s): invalid deactivation with globalRefCount %d",
+              __func__, client->toShortString().c_str(), mGlobalActiveCount);
+        mGlobalActiveCount = 1;
+    }
+    mGlobalActiveCount += delta;
+
+    sp<AudioPolicyMix> policyMix = mPolicyMix.promote();
+    if ((policyMix != NULL) && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
+        if ((oldGlobalActiveCount == 0) || (mGlobalActiveCount == 0)) {
+            mClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
+                mGlobalActiveCount > 0 ? MIX_STATE_MIXING : MIX_STATE_IDLE);
+        }
+    }
+    client->setActive(active);
+}
+
+bool AudioOutputDescriptor::isActive(VolumeSource vs, uint32_t inPastMs, nsecs_t sysTime) const
+{
+    return (vs == VOLUME_SOURCE_NONE) ?
+                isActive(inPastMs) : (mVolumeActivities.find(vs) != std::end(mVolumeActivities)?
+                mVolumeActivities.at(vs).isActive(inPastMs, sysTime) : false);
 }
 
 bool AudioOutputDescriptor::isActive(uint32_t inPastMs) const
@@ -106,54 +136,32 @@
     if (inPastMs != 0) {
         sysTime = systemTime();
     }
-    for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
-        if (i == AUDIO_STREAM_PATCH) {
-            continue;
-        }
-        if (isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) {
+    for (const auto &iter : mVolumeActivities) {
+        if (iter.second.isActive(inPastMs, sysTime)) {
             return true;
         }
     }
     return false;
 }
 
-bool AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream,
-                                           uint32_t inPastMs,
-                                           nsecs_t sysTime) const
-{
-    if (mRefCount[stream] != 0) {
-        return true;
-    }
-    if (inPastMs == 0) {
-        return false;
-    }
-    if (sysTime == 0) {
-        sysTime = systemTime();
-    }
-    if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) {
-        return true;
-    }
-    return false;
-}
-
-
 bool AudioOutputDescriptor::isFixedVolume(audio_devices_t device __unused)
 {
     return false;
 }
 
-bool AudioOutputDescriptor::setVolume(float volume,
-                                      audio_stream_type_t stream,
-                                      audio_devices_t device __unused,
+bool AudioOutputDescriptor::setVolume(float volumeDb,
+                                      VolumeSource volumeSource,
+                                      const StreamTypeVector &/*streams*/,
+                                      audio_devices_t /*device*/,
                                       uint32_t delayMs,
                                       bool force)
 {
     // We actually change the volume if:
     // - the float value returned by computeVolume() changed
     // - the force flag is set
-    if (volume != mCurVolume[stream] || force) {
-        ALOGV("setVolume() for stream %d, volume %f, delay %d", stream, volume, delayMs);
-        mCurVolume[stream] = volume;
+    if (volumeDb != getCurVolume(volumeSource) || force) {
+        ALOGV("%s for volumeSrc %d, volume %f, delay %d", __func__, volumeSource, volumeDb, delayMs);
+        setCurVolume(volumeSource, volumeDb);
         return true;
     }
     return false;
@@ -185,32 +193,55 @@
     port->ext.mix.hw_module = getModuleHandle();
 }
 
-status_t AudioOutputDescriptor::dump(int fd)
+TrackClientVector AudioOutputDescriptor::clientsList(bool activeOnly, product_strategy_t strategy,
+                                                     bool preferredDeviceOnly) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, " ID: %d\n", mId);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Format: %08x\n", mFormat);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Devices %08x\n", device());
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Stream volume refCount muteCount\n");
-    result.append(buffer);
-    for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
-        snprintf(buffer, SIZE, " %02d     %.03f     %02d       %02d\n",
-                 i, mCurVolume[i], mRefCount[i], mMuteCount[i]);
-        result.append(buffer);
+    TrackClientVector clients;
+    for (const auto &client : getClientIterable()) {
+        if ((!activeOnly || client->active())
+            && (strategy == PRODUCT_STRATEGY_NONE || strategy == client->strategy())
+            && (!preferredDeviceOnly ||
+                (client->hasPreferredDevice() && !client->isPreferredDeviceForExclusiveUse()))) {
+            clients.push_back(client);
+        }
     }
-    write(fd, result.string(), result.size());
+    return clients;
+}
 
-    return NO_ERROR;
+bool AudioOutputDescriptor::isAnyActive(VolumeSource volumeSourceToIgnore) const
+{
+    return std::find_if(begin(mActiveClients), end(mActiveClients),
+                        [&volumeSourceToIgnore](const auto &client) {
+        return client->volumeSource() != volumeSourceToIgnore; }) != end(mActiveClients);
+}
+
+void AudioOutputDescriptor::dump(String8 *dst) const
+{
+    dst->appendFormat(" ID: %d\n", mId);
+    dst->appendFormat(" Sampling rate: %d\n", mSamplingRate);
+    dst->appendFormat(" Format: %08x\n", mFormat);
+    dst->appendFormat(" Channels: %08x\n", mChannelMask);
+    dst->appendFormat(" Devices: %s\n", devices().toString().c_str());
+    dst->appendFormat(" Global active count: %u\n", mGlobalActiveCount);
+    for (const auto &iter : mRoutingActivities) {
+        dst->appendFormat(" Product Strategy id: %d", iter.first);
+        iter.second.dump(dst, 4);
+    }
+    for (const auto &iter : mVolumeActivities) {
+        dst->appendFormat(" Volume Activities id: %d", iter.first);
+        iter.second.dump(dst, 4);
+    }
+    dst->append(" AudioTrack Clients:\n");
+    ClientMapHandler<TrackClientDescriptor>::dump(dst);
+    dst->append("\n");
+    if (!mActiveClients.empty()) {
+        dst->append(" AudioTrack active (stream) clients:\n");
+        size_t index = 0;
+        for (const auto& client : mActiveClients) {
+            client->dump(dst, 2, index++);
+        }
+        dst->append(" \n");
+    }
 }
 
 void AudioOutputDescriptor::log(const char* indent)
@@ -224,43 +255,34 @@
                                                  AudioPolicyClientInterface *clientInterface)
     : AudioOutputDescriptor(profile, clientInterface),
     mProfile(profile), mIoHandle(AUDIO_IO_HANDLE_NONE), mLatency(0),
-    mFlags((audio_output_flags_t)0), mPolicyMix(NULL),
+    mFlags((audio_output_flags_t)0),
     mOutput1(0), mOutput2(0), mDirectOpenCount(0),
-    mDirectClientSession(AUDIO_SESSION_NONE), mGlobalRefCount(0)
+    mDirectClientSession(AUDIO_SESSION_NONE)
 {
     if (profile != NULL) {
         mFlags = (audio_output_flags_t)profile->getFlags();
     }
 }
 
-status_t SwAudioOutputDescriptor::dump(int fd)
+void SwAudioOutputDescriptor::dump(String8 *dst) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
-    result.append(buffer);
-    write(fd, result.string(), result.size());
-
-    AudioOutputDescriptor::dump(fd);
-
-    return NO_ERROR;
+    dst->appendFormat(" Latency: %d\n", mLatency);
+    dst->appendFormat(" Flags %08x\n", mFlags);
+    AudioOutputDescriptor::dump(dst);
 }
 
-audio_devices_t SwAudioOutputDescriptor::device() const
+DeviceVector SwAudioOutputDescriptor::devices() const
 {
     if (isDuplicated()) {
-        return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice);
-    } else {
-        return mDevice;
+        DeviceVector devices = mOutput1->devices();
+        devices.merge(mOutput2->devices());
+        return devices;
     }
+    return mDevices;
 }
 
 bool SwAudioOutputDescriptor::sharesHwModuleWith(
-        const sp<AudioOutputDescriptor>& outputDesc)
+        const sp<SwAudioOutputDescriptor>& outputDesc)
 {
     if (isDuplicated()) {
         return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
@@ -272,12 +294,39 @@
     }
 }
 
-audio_devices_t SwAudioOutputDescriptor::supportedDevices()
+DeviceVector SwAudioOutputDescriptor::supportedDevices() const
 {
     if (isDuplicated()) {
-        return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices());
+        DeviceVector supportedDevices = mOutput1->supportedDevices();
+        supportedDevices.merge(mOutput2->supportedDevices());
+        return supportedDevices;
+    }
+    return mProfile->getSupportedDevices();
+}
+
+bool SwAudioOutputDescriptor::supportsDevice(const sp<DeviceDescriptor> &device) const
+{
+    return supportedDevices().contains(device);
+}
+
+bool SwAudioOutputDescriptor::supportsAllDevices(const DeviceVector &devices) const
+{
+    return supportedDevices().containsAllDevices(devices);
+}
+
+DeviceVector SwAudioOutputDescriptor::filterSupportedDevices(const DeviceVector &devices) const
+{
+    DeviceVector filteredDevices = supportedDevices();
+    return filteredDevices.filter(devices);
+}
+
+bool SwAudioOutputDescriptor::deviceSupportsEncodedFormats(audio_devices_t device)
+{
+    if (isDuplicated()) {
+        return (mOutput1->deviceSupportsEncodedFormats(device)
+                    || mOutput2->deviceSupportsEncodedFormats(device));
     } else {
-        return mProfile->getSupportedDevicesType();
+       return mProfile->deviceSupportsEncodedFormats(device);
     }
 }
 
@@ -290,42 +339,16 @@
     }
 }
 
-void SwAudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
-                                                                   int delta)
+void SwAudioOutputDescriptor::setClientActive(const sp<TrackClientDescriptor>& client, bool active)
 {
     // forward usage count change to attached outputs
     if (isDuplicated()) {
-        mOutput1->changeRefCount(stream, delta);
-        mOutput2->changeRefCount(stream, delta);
+        mOutput1->setClientActive(client, active);
+        mOutput2->setClientActive(client, active);
     }
-    AudioOutputDescriptor::changeRefCount(stream, delta);
-
-    // handle stream-independent ref count
-    uint32_t oldGlobalRefCount = mGlobalRefCount;
-    if ((delta + (int)mGlobalRefCount) < 0) {
-        ALOGW("changeRefCount() invalid delta %d globalRefCount %d", delta, mGlobalRefCount);
-        mGlobalRefCount = 0;
-    } else {
-        mGlobalRefCount += delta;
-    }
-    sp<AudioPolicyMix> policyMix = mPolicyMix.promote();
-    if ((oldGlobalRefCount == 0) && (mGlobalRefCount > 0)) {
-        if ((policyMix != NULL) && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
-        {
-            mClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
-                    MIX_STATE_MIXING);
-        }
-
-    } else if ((oldGlobalRefCount > 0) && (mGlobalRefCount == 0)) {
-        if ((policyMix != NULL) && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
-        {
-            mClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
-                    MIX_STATE_IDLE);
-        }
-    }
+    AudioOutputDescriptor::setClientActive(client, active);
 }
 
-
 bool SwAudioOutputDescriptor::isFixedVolume(audio_devices_t device)
 {
     // unit gain if rerouting to external policy
@@ -366,34 +389,72 @@
             mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
 }
 
-bool SwAudioOutputDescriptor::setVolume(float volume,
-                                        audio_stream_type_t stream,
+bool SwAudioOutputDescriptor::setVolume(float volumeDb,
+                                        VolumeSource vs, const StreamTypeVector &streamTypes,
                                         audio_devices_t device,
                                         uint32_t delayMs,
                                         bool force)
 {
-    bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force);
-
-    if (changed) {
-        // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is
-        // enabled
-        float volume = Volume::DbToAmpl(mCurVolume[stream]);
-        if (stream == AUDIO_STREAM_BLUETOOTH_SCO) {
-            mClientInterface->setStreamVolume(
-                    AUDIO_STREAM_VOICE_CALL, volume, mIoHandle, delayMs);
-        }
-        mClientInterface->setStreamVolume(stream, volume, mIoHandle, delayMs);
+    StreamTypeVector streams = streamTypes;
+    if (!AudioOutputDescriptor::setVolume(volumeDb, vs, streamTypes, device, delayMs, force)) {
+        return false;
     }
-    return changed;
+    if (streams.empty()) {
+        streams.push_back(AUDIO_STREAM_MUSIC);
+    }
+    for (const auto& devicePort : devices()) {
+        // APM loops on all group, so filter on active group to set the port gain,
+        // let the other groups set the stream volume as per legacy
+        // TODO: Pass in the device address and check against it.
+        if (device == devicePort->type() &&
+                devicePort->hasGainController(true) && isActive(vs)) {
+            ALOGV("%s: device %s has gain controller", __func__, devicePort->toString().c_str());
+            // @todo: here we might be in trouble if the SwOutput has several active clients with
+            // different Volume Source (or if we allow several curves within same volume group)
+            //
+            // @todo: default stream volume to max (0) when using HW Port gain?
+            float volumeAmpl = Volume::DbToAmpl(0);
+            for (const auto &stream : streams) {
+                mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
+            }
+
+            AudioGains gains = devicePort->getGains();
+            int gainMinValueInMb = gains[0]->getMinValueInMb();
+            int gainMaxValueInMb = gains[0]->getMaxValueInMb();
+            int gainStepValueInMb = gains[0]->getStepValueInMb();
+            int gainValueMb = ((volumeDb * 100)/ gainStepValueInMb) * gainStepValueInMb;
+            gainValueMb = std::max(gainMinValueInMb, std::min(gainValueMb, gainMaxValueInMb));
+
+            audio_port_config config = {};
+            devicePort->toAudioPortConfig(&config);
+            config.config_mask = AUDIO_PORT_CONFIG_GAIN;
+            config.gain.values[0] = gainValueMb;
+            return mClientInterface->setAudioPortConfig(&config, 0) == NO_ERROR;
+        }
+    }
+    // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is enabled
+    float volumeAmpl = Volume::DbToAmpl(getCurVolume(vs));
+    if (hasStream(streams, AUDIO_STREAM_BLUETOOTH_SCO)) {
+        mClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volumeAmpl, mIoHandle, delayMs);
+    }
+    for (const auto &stream : streams) {
+        ALOGV("%s output %d for volumeSource %d, volume %f, delay %d stream=%s", __func__,
+              mIoHandle, vs, volumeDb, delayMs, toString(stream).c_str());
+        mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
+    }
+    return true;
 }
 
 status_t SwAudioOutputDescriptor::open(const audio_config_t *config,
-                                       audio_devices_t device,
-                                       const String8& address,
+                                       const DeviceVector &devices,
                                        audio_stream_type_t stream,
                                        audio_output_flags_t flags,
                                        audio_io_handle_t *output)
 {
+    mDevices = devices;
+    const String8& address = devices.getFirstValidAddress();
+    audio_devices_t device = devices.types();
+
     audio_config_t lConfig;
     if (config == nullptr) {
         lConfig = AUDIO_CONFIG_INITIALIZER;
@@ -404,7 +465,6 @@
         lConfig = *config;
     }
 
-    mDevice = device;
     // if the selected profile is offloaded and no offload info was specified,
     // create a default one
     if ((mProfile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
@@ -422,19 +482,19 @@
 
     mFlags = (audio_output_flags_t)(mFlags | flags);
 
-    ALOGV("opening output for device %08x address %s profile %p name %s",
-          mDevice, address.string(), mProfile.get(), mProfile->getName().string());
+    ALOGV("opening output for device %s profile %p name %s",
+          mDevices.toString().c_str(), mProfile.get(), mProfile->getName().string());
 
     status_t status = mClientInterface->openOutput(mProfile->getModuleHandle(),
                                                    output,
                                                    &lConfig,
-                                                   &mDevice,
+                                                   &device,
                                                    address,
                                                    &mLatency,
                                                    mFlags);
-    LOG_ALWAYS_FATAL_IF(mDevice != device,
+    LOG_ALWAYS_FATAL_IF(mDevices.types() != device,
                         "%s openOutput returned device %08x when given device %08x",
-                        __FUNCTION__, mDevice, device);
+                        __FUNCTION__, mDevices.types(), device);
 
     if (status == NO_ERROR) {
         LOG_ALWAYS_FATAL_IF(*output == AUDIO_IO_HANDLE_NONE,
@@ -493,6 +553,17 @@
 void SwAudioOutputDescriptor::close()
 {
     if (mIoHandle != AUDIO_IO_HANDLE_NONE) {
+        // clean up active clients if any (can happen if close() is called to force
+        // clients to reconnect
+        for (const auto &client : getClientIterable()) {
+            if (client->active()) {
+                ALOGW("%s client with port ID %d still active on output %d",
+                      __func__, client->portId(), mId);
+                setClientActive(client, false);
+                stop();
+            }
+        }
+
         AudioParameter param;
         param.add(String8("closing"), String8("true"));
         mClientInterface->setParameters(mIoHandle, param.toString());
@@ -501,11 +572,6 @@
 
         LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
                             __FUNCTION__, mProfile->curOpenCount);
-        // do not call stop() here as stop() is supposed to be called after changeRefCount(-1)
-        // and we don't know how many streams are still active at this time
-        if (isActive()) {
-            mProfile->curActiveCount--;
-        }
         mProfile->curOpenCount--;
         mIoHandle = AUDIO_IO_HANDLE_NONE;
     }
@@ -536,55 +602,42 @@
 }
 
 // HwAudioOutputDescriptor implementation
-HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<AudioSourceDescriptor>& source,
+HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<SourceClientDescriptor>& source,
                                                  AudioPolicyClientInterface *clientInterface)
-    : AudioOutputDescriptor(source->mDevice, clientInterface),
+    : AudioOutputDescriptor(source->srcDevice(), clientInterface),
       mSource(source)
 {
 }
 
-status_t HwAudioOutputDescriptor::dump(int fd)
+void HwAudioOutputDescriptor::dump(String8 *dst) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    AudioOutputDescriptor::dump(fd);
-
-    snprintf(buffer, SIZE, "Source:\n");
-    result.append(buffer);
-    write(fd, result.string(), result.size());
-    mSource->dump(fd);
-
-    return NO_ERROR;
-}
-
-audio_devices_t HwAudioOutputDescriptor::supportedDevices()
-{
-    return mDevice;
+    AudioOutputDescriptor::dump(dst);
+    dst->append("Source:\n");
+    mSource->dump(dst, 0, 0);
 }
 
 void HwAudioOutputDescriptor::toAudioPortConfig(
                                                  struct audio_port_config *dstConfig,
                                                  const struct audio_port_config *srcConfig) const
 {
-    mSource->mDevice->toAudioPortConfig(dstConfig, srcConfig);
+    mSource->srcDevice()->toAudioPortConfig(dstConfig, srcConfig);
 }
 
 void HwAudioOutputDescriptor::toAudioPort(
                                                     struct audio_port *port) const
 {
-    mSource->mDevice->toAudioPort(port);
+    mSource->srcDevice()->toAudioPort(port);
 }
 
 
-bool HwAudioOutputDescriptor::setVolume(float volume,
-                                        audio_stream_type_t stream,
+bool HwAudioOutputDescriptor::setVolume(float volumeDb,
+                                        VolumeSource volumeSource, const StreamTypeVector &streams,
                                         audio_devices_t device,
                                         uint32_t delayMs,
                                         bool force)
 {
-    bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force);
+    bool changed =
+        AudioOutputDescriptor::setVolume(volumeDb, volumeSource, streams, device, delayMs, force);
 
     if (changed) {
       // TODO: use gain controller on source device if any to adjust volume
@@ -593,39 +646,38 @@
 }
 
 // SwAudioOutputCollection implementation
-bool SwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
+bool SwAudioOutputCollection::isActive(VolumeSource volumeSource, uint32_t inPastMs) const
 {
     nsecs_t sysTime = systemTime();
     for (size_t i = 0; i < this->size(); i++) {
         const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
-        if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
+        if (outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
             return true;
         }
     }
     return false;
 }
 
-bool SwAudioOutputCollection::isStreamActiveLocally(audio_stream_type_t stream, uint32_t inPastMs) const
+bool SwAudioOutputCollection::isActiveLocally(VolumeSource volumeSource, uint32_t inPastMs) const
 {
     nsecs_t sysTime = systemTime();
     for (size_t i = 0; i < this->size(); i++) {
         const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
-        if (outputDesc->isStreamActive(stream, inPastMs, sysTime)
-                && ((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) == 0)) {
+        if (outputDesc->isActive(volumeSource, inPastMs, sysTime)
+                && ((outputDesc->devices().types() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) == 0)) {
             return true;
         }
     }
     return false;
 }
 
-bool SwAudioOutputCollection::isStreamActiveRemotely(audio_stream_type_t stream,
-                                                   uint32_t inPastMs) const
+bool SwAudioOutputCollection::isActiveRemotely(VolumeSource volumeSource, uint32_t inPastMs) const
 {
     nsecs_t sysTime = systemTime();
     for (size_t i = 0; i < size(); i++) {
         const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
-        if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) &&
-                outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
+        if (((outputDesc->devices().types() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) &&
+                outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
             // do not consider re routing (when the output is going to a dynamic policy)
             // as "remote playback"
             if (outputDesc->mPolicyMix == NULL) {
@@ -636,11 +688,28 @@
     return false;
 }
 
+bool SwAudioOutputCollection::isStrategyActiveOnSameModule(product_strategy_t ps,
+                                                           const sp<SwAudioOutputDescriptor>& desc,
+                                                           uint32_t inPastMs, nsecs_t sysTime) const
+{
+    for (size_t i = 0; i < size(); i++) {
+        const sp<SwAudioOutputDescriptor> otherDesc = valueAt(i);
+        if (desc->sharesHwModuleWith(otherDesc) &&
+                otherDesc->isStrategyActive(ps, inPastMs, sysTime)) {
+            return true;
+        }
+    }
+    return false;
+}
+
 audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const
 {
     for (size_t i = 0; i < size(); i++) {
         sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
-        if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) {
+        if (!outputDesc->isDuplicated() &&
+             outputDesc->devices().types()  & AUDIO_DEVICE_OUT_ALL_A2DP &&
+             outputDesc->deviceSupportsEncodedFormats(
+                     AUDIO_DEVICE_OUT_BLUETOOTH_A2DP)) {
             return this->keyAt(i);
         }
     }
@@ -652,12 +721,11 @@
     sp<SwAudioOutputDescriptor> primaryOutput = getPrimaryOutput();
 
     if ((primaryOutput != NULL) && (primaryOutput->mProfile != NULL)
-        && (primaryOutput->mProfile->mModule != NULL)) {
-        sp<HwModule> primaryHwModule = primaryOutput->mProfile->mModule;
-        Vector <sp<IOProfile>> primaryHwModuleOutputProfiles =
-                                   primaryHwModule->getOutputProfiles();
-        for (size_t i = 0; i < primaryHwModuleOutputProfiles.size(); i++) {
-            if (primaryHwModuleOutputProfiles[i]->supportDevice(AUDIO_DEVICE_OUT_ALL_A2DP)) {
+        && (primaryOutput->mProfile->getModule() != NULL)) {
+        sp<HwModule> primaryHwModule = primaryOutput->mProfile->getModule();
+
+        for (const auto &outputProfile : primaryHwModule->getOutputProfiles()) {
+            if (outputProfile->supportsDeviceTypes(AUDIO_DEVICE_OUT_ALL_A2DP)) {
                 return true;
             }
         }
@@ -683,99 +751,68 @@
 
 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const
 {
-    sp<SwAudioOutputDescriptor> outputDesc = NULL;
     for (size_t i = 0; i < size(); i++) {
-        outputDesc = valueAt(i);
+        const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
         if (outputDesc->getId() == id) {
-            break;
+            return outputDesc;
         }
     }
-    return outputDesc;
+    return NULL;
 }
 
-bool SwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const
+sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputForClient(audio_port_handle_t portId)
 {
-    for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) {
-        if (s == (size_t) streamToIgnore) {
-            continue;
+    for (size_t i = 0; i < size(); i++) {
+        sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
+        if (outputDesc->getClient(portId) != nullptr) {
+            return outputDesc;
         }
-        for (size_t i = 0; i < size(); i++) {
-            const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
-            if (outputDesc->mRefCount[s] != 0) {
-                return true;
+    }
+    return 0;
+}
+
+void SwAudioOutputCollection::clearSessionRoutesForDevice(
+        const sp<DeviceDescriptor> &disconnectedDevice)
+{
+    for (size_t i = 0; i < size(); i++) {
+        sp<AudioOutputDescriptor> outputDesc = valueAt(i);
+        for (const auto& client : outputDesc->getClientIterable()) {
+            if (client->preferredDeviceId() == disconnectedDevice->getId()) {
+                client->setPreferredDeviceId(AUDIO_PORT_HANDLE_NONE);
             }
         }
     }
-    return false;
 }
 
-audio_devices_t SwAudioOutputCollection::getSupportedDevices(audio_io_handle_t handle) const
+void SwAudioOutputCollection::dump(String8 *dst) const
 {
-    sp<SwAudioOutputDescriptor> outputDesc = valueFor(handle);
-    audio_devices_t devices = outputDesc->mProfile->getSupportedDevicesType();
-    return devices;
-}
-
-
-status_t SwAudioOutputCollection::dump(int fd) const
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE, "\nOutputs dump:\n");
-    write(fd, buffer, strlen(buffer));
+    dst->append("\nOutputs dump:\n");
     for (size_t i = 0; i < size(); i++) {
-        snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i));
-        write(fd, buffer, strlen(buffer));
-        valueAt(i)->dump(fd);
+        dst->appendFormat("- Output %d dump:\n", keyAt(i));
+        valueAt(i)->dump(dst);
     }
-
-    return NO_ERROR;
 }
 
 // HwAudioOutputCollection implementation
-bool HwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
+bool HwAudioOutputCollection::isActive(VolumeSource volumeSource, uint32_t inPastMs) const
 {
     nsecs_t sysTime = systemTime();
     for (size_t i = 0; i < this->size(); i++) {
         const sp<HwAudioOutputDescriptor> outputDesc = this->valueAt(i);
-        if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
+        if (outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
             return true;
         }
     }
     return false;
 }
 
-bool HwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const
+void HwAudioOutputCollection::dump(String8 *dst) const
 {
-    for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) {
-        if (s == (size_t) streamToIgnore) {
-            continue;
-        }
-        for (size_t i = 0; i < size(); i++) {
-            const sp<HwAudioOutputDescriptor> outputDesc = valueAt(i);
-            if (outputDesc->mRefCount[s] != 0) {
-                return true;
-            }
-        }
-    }
-    return false;
-}
-
-status_t HwAudioOutputCollection::dump(int fd) const
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE, "\nOutputs dump:\n");
-    write(fd, buffer, strlen(buffer));
+    dst->append("\nOutputs dump:\n");
     for (size_t i = 0; i < size(); i++) {
-        snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i));
-        write(fd, buffer, strlen(buffer));
-        valueAt(i)->dump(fd);
+        dst->appendFormat("- Output %d dump:\n", keyAt(i));
+        valueAt(i)->dump(dst);
     }
-
-    return NO_ERROR;
 }
 
 }; //namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp
index a9fe48d..3a4db90 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp
@@ -34,53 +34,27 @@
 {
 }
 
-status_t AudioPatch::dump(int fd, int spaces, int index) const
+static void dumpPatchEndpoints(
+        String8 *dst, int spaces, const char *prefix, int count, const audio_port_config *cfgs)
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "%*sAudio patch %d:\n", spaces, "", index+1);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- handle: %2d\n", spaces, "", mHandle);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- audio flinger handle: %2d\n", spaces, "", mAfPatchHandle);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- owner uid: %2d\n", spaces, "", mUid);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- %d sources:\n", spaces, "", mPatch.num_sources);
-    result.append(buffer);
-    for (size_t i = 0; i < mPatch.num_sources; i++) {
-        if (mPatch.sources[i].type == AUDIO_PORT_TYPE_DEVICE) {
-            std::string device;
-            deviceToString(mPatch.sources[i].ext.device.type, device);
-            snprintf(buffer, SIZE, "%*s- Device ID %d %s\n", spaces + 2, "",
-                     mPatch.sources[i].id,
-                     device.c_str());
+    for (int i = 0; i < count; ++i) {
+        const audio_port_config &cfg = cfgs[i];
+        dst->appendFormat("%*s  [%s %d] ", spaces, "", prefix, i + 1);
+        if (cfg.type == AUDIO_PORT_TYPE_DEVICE) {
+            dst->appendFormat("Device ID %d %s", cfg.id, toString(cfg.ext.device.type).c_str());
         } else {
-            snprintf(buffer, SIZE, "%*s- Mix ID %d I/O handle %d\n", spaces + 2, "",
-                     mPatch.sources[i].id, mPatch.sources[i].ext.mix.handle);
+            dst->appendFormat("Mix ID %d I/O handle %d", cfg.id, cfg.ext.mix.handle);
         }
-        result.append(buffer);
+        dst->append("\n");
     }
-    snprintf(buffer, SIZE, "%*s- %d sinks:\n", spaces, "", mPatch.num_sinks);
-    result.append(buffer);
-    for (size_t i = 0; i < mPatch.num_sinks; i++) {
-        if (mPatch.sinks[i].type == AUDIO_PORT_TYPE_DEVICE) {
-            std::string device;
-            deviceToString(mPatch.sinks[i].ext.device.type, device);
-            snprintf(buffer, SIZE, "%*s- Device ID %d %s\n", spaces + 2, "",
-                     mPatch.sinks[i].id,
-                     device.c_str());
-        } else {
-            snprintf(buffer, SIZE, "%*s- Mix ID %d I/O handle %d\n", spaces + 2, "",
-                     mPatch.sinks[i].id, mPatch.sinks[i].ext.mix.handle);
-        }
-        result.append(buffer);
-    }
+}
 
-    write(fd, result.string(), result.size());
-    return NO_ERROR;
+void AudioPatch::dump(String8 *dst, int spaces, int index) const
+{
+    dst->appendFormat("%*sPatch %d: owner uid %4d, handle %2d, af handle %2d\n",
+            spaces, "", index + 1, mUid, mHandle, mAfPatchHandle);
+    dumpPatchEndpoints(dst, spaces, "src ", mPatch.num_sources, mPatch.sources);
+    dumpPatchEndpoints(dst, spaces, "sink", mPatch.num_sinks, mPatch.sinks);
 }
 
 status_t AudioPatchCollection::addAudioPatch(audio_patch_handle_t handle,
@@ -161,16 +135,12 @@
     return NO_ERROR;
 }
 
-status_t AudioPatchCollection::dump(int fd) const
+void AudioPatchCollection::dump(String8 *dst) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    snprintf(buffer, SIZE, "\nAudio Patches:\n");
-    write(fd, buffer, strlen(buffer));
+    dst->append("\nAudio Patches:\n");
     for (size_t i = 0; i < size(); i++) {
-        valueAt(i)->dump(fd, 2, i);
+        valueAt(i)->dump(dst, 2, i);
     }
-    return NO_ERROR;
 }
 
 } // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index 327dc4d..c42923a 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -27,95 +27,67 @@
 
 namespace android {
 
-AudioPolicyMix::AudioPolicyMix(const AudioMix &mix) : AudioMix(mix)
+void AudioPolicyMix::dump(String8 *dst, int spaces, int index) const
 {
-}
-
-void AudioPolicyMix::setOutput(sp<SwAudioOutputDescriptor> &output)
-{
-    mOutput = output;
-}
-
-const sp<SwAudioOutputDescriptor> &AudioPolicyMix::getOutput() const
-{
-    return mOutput;
-}
-
-void AudioPolicyMix::clearOutput()
-{
-    mOutput.clear();
-}
-
-status_t AudioPolicyMix::dump(int fd, int spaces, int index) const
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "%*sAudio Policy Mix %d:\n", spaces, "", index+1);
-    result.append(buffer);
+    dst->appendFormat("%*sAudio Policy Mix %d:\n", spaces, "", index + 1);
     std::string mixTypeLiteral;
     if (!MixTypeConverter::toString(mMixType, mixTypeLiteral)) {
         ALOGE("%s: failed to convert mix type %d", __FUNCTION__, mMixType);
-        return BAD_VALUE;
+        return;
     }
-    snprintf(buffer, SIZE, "%*s- mix type: %s\n", spaces, "", mixTypeLiteral.c_str());
-    result.append(buffer);
+    dst->appendFormat("%*s- mix type: %s\n", spaces, "", mixTypeLiteral.c_str());
+
     std::string routeFlagLiteral;
     RouteFlagTypeConverter::maskToString(mRouteFlags, routeFlagLiteral);
-    snprintf(buffer, SIZE, "%*s- Route Flags: %s\n", spaces, "", routeFlagLiteral.c_str());
-    result.append(buffer);
-    std::string deviceLiteral;
-    deviceToString(mDeviceType, deviceLiteral);
-    snprintf(buffer, SIZE, "%*s- device type: %s\n", spaces, "", deviceLiteral.c_str());
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- device address: %s\n", spaces, "", mDeviceAddress.string());
-    result.append(buffer);
+    dst->appendFormat("%*s- Route Flags: %s\n", spaces, "", routeFlagLiteral.c_str());
+
+    dst->appendFormat("%*s- device type: %s\n", spaces, "", toString(mDeviceType).c_str());
+
+    dst->appendFormat("%*s- device address: %s\n", spaces, "", mDeviceAddress.string());
 
     int indexCriterion = 0;
     for (const auto &criterion : mCriteria) {
-        snprintf(buffer, SIZE, "%*s- Criterion %d:\n", spaces + 2, "", indexCriterion++);
-        result.append(buffer);
-        std::string usageLiteral;
-        if (!UsageTypeConverter::toString(criterion.mValue.mUsage, usageLiteral)) {
-            ALOGE("%s: failed to convert usage %d", __FUNCTION__, criterion.mValue.mUsage);
-            return BAD_VALUE;
+        dst->appendFormat("%*s- Criterion %d: ", spaces + 2, "", indexCriterion++);
+
+        std::string ruleType, ruleValue;
+        bool unknownRule = !RuleTypeConverter::toString(criterion.mRule, ruleType);
+        switch (criterion.mRule & ~RULE_EXCLUSION_MASK) { // no need to match RULE_EXCLUDE_...
+        case RULE_MATCH_ATTRIBUTE_USAGE:
+            UsageTypeConverter::toString(criterion.mValue.mUsage, ruleValue);
+            break;
+        case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET:
+            SourceTypeConverter::toString(criterion.mValue.mSource, ruleValue);
+            break;
+        case RULE_MATCH_UID:
+            ruleValue = std::to_string(criterion.mValue.mUid);
+            break;
+        default:
+            unknownRule = true;
         }
-        snprintf(buffer, SIZE, "%*s- Usage:%s\n", spaces + 4, "", usageLiteral.c_str());
-        result.append(buffer);
-        if (mMixType == MIX_TYPE_RECORDERS) {
-            std::string sourceLiteral;
-            if (!SourceTypeConverter::toString(criterion.mValue.mSource, sourceLiteral)) {
-                ALOGE("%s: failed to convert source %d", __FUNCTION__, criterion.mValue.mSource);
-                return BAD_VALUE;
-            }
-            snprintf(buffer, SIZE, "%*s- Source:%s\n", spaces + 4, "", sourceLiteral.c_str());
-            result.append(buffer);
+
+        if (!unknownRule) {
+            dst->appendFormat("%s %s\n", ruleType.c_str(), ruleValue.c_str());
+        } else {
+            dst->appendFormat("Unknown rule type value 0x%x\n", criterion.mRule);
         }
-        snprintf(buffer, SIZE, "%*s- Uid:%d\n", spaces + 4, "", criterion.mValue.mUid);
-        result.append(buffer);
-        std::string ruleLiteral;
-        if (!RuleTypeConverter::toString(criterion.mRule, ruleLiteral)) {
-            ALOGE("%s: failed to convert source %d", __FUNCTION__,criterion.mRule);
-            return BAD_VALUE;
-        }
-        snprintf(buffer, SIZE, "%*s- Rule:%s\n", spaces + 4, "", ruleLiteral.c_str());
-        result.append(buffer);
     }
-    write(fd, result.string(), result.size());
-    return NO_ERROR;
 }
 
-status_t AudioPolicyMixCollection::registerMix(const String8& address, AudioMix mix,
-                                               sp<SwAudioOutputDescriptor> desc)
+status_t AudioPolicyMixCollection::registerMix(AudioMix mix, sp<SwAudioOutputDescriptor> desc)
 {
-    ssize_t index = indexOfKey(address);
-    if (index >= 0) {
-        ALOGE("registerPolicyMixes(): mix for address %s already registered", address.string());
-        return BAD_VALUE;
+    for (size_t i = 0; i < size(); i++) {
+        const sp<AudioPolicyMix>& registeredMix = itemAt(i);
+        if (mix.mDeviceType == registeredMix->mDeviceType
+                && mix.mDeviceAddress.compare(registeredMix->mDeviceAddress) == 0) {
+            ALOGE("registerMix(): mix already registered for dev=0x%x addr=%s",
+                    mix.mDeviceType, mix.mDeviceAddress.string());
+            return BAD_VALUE;
+        }
     }
     sp<AudioPolicyMix> policyMix = new AudioPolicyMix(mix);
-    add(address, policyMix);
+    add(policyMix);
+    ALOGD("registerMix(): adding mix for dev=0x%x addr=%s",
+            policyMix->mDeviceType, policyMix->mDeviceAddress.string());
 
     if (desc != 0) {
         desc->mPolicyMix = policyMix;
@@ -124,171 +96,269 @@
     return NO_ERROR;
 }
 
-status_t AudioPolicyMixCollection::unregisterMix(const String8& address)
+status_t AudioPolicyMixCollection::unregisterMix(const AudioMix& mix)
 {
-    ssize_t index = indexOfKey(address);
-    if (index < 0) {
-        ALOGE("unregisterPolicyMixes(): mix for address %s not registered", address.string());
-        return BAD_VALUE;
+    for (size_t i = 0; i < size(); i++) {
+        const sp<AudioPolicyMix>& registeredMix = itemAt(i);
+        if (mix.mDeviceType == registeredMix->mDeviceType
+                && mix.mDeviceAddress.compare(registeredMix->mDeviceAddress) == 0) {
+            ALOGD("unregisterMix(): removing mix for dev=0x%x addr=%s",
+                    mix.mDeviceType, mix.mDeviceAddress.string());
+            removeAt(i);
+            return NO_ERROR;
+        }
     }
 
-    removeItemsAt(index);
-    return NO_ERROR;
+    ALOGE("unregisterMix(): mix not registered for dev=0x%x addr=%s",
+            mix.mDeviceType, mix.mDeviceAddress.string());
+    return BAD_VALUE;
 }
 
-status_t AudioPolicyMixCollection::getAudioPolicyMix(const String8& address,
-                                                     sp<AudioPolicyMix> &policyMix) const
+status_t AudioPolicyMixCollection::getAudioPolicyMix(audio_devices_t deviceType,
+        const String8& address, sp<AudioPolicyMix> &policyMix) const
 {
-    ssize_t index = indexOfKey(address);
-    if (index < 0) {
-        ALOGE("unregisterPolicyMixes(): mix for address %s not registered", address.string());
-        return BAD_VALUE;
+
+    ALOGV("getAudioPolicyMix() for dev=0x%x addr=%s", deviceType, address.string());
+    for (ssize_t i = 0; i < size(); i++) {
+        // Workaround: when an in audio policy is registered, it opens an output
+        // that tries to find the audio policy, thus the device must be ignored.
+        if (itemAt(i)->mDeviceAddress.compare(address) == 0) {
+            policyMix = itemAt(i);
+            ALOGV("getAudioPolicyMix: found mix %zu match (devType=0x%x addr=%s)",
+                    i, deviceType, address.string());
+            return NO_ERROR;
+        }
     }
-    policyMix = valueAt(index);
-    return NO_ERROR;
+
+    ALOGE("getAudioPolicyMix(): mix not registered for dev=0x%x addr=%s",
+            deviceType, address.string());
+    return BAD_VALUE;
 }
 
 void AudioPolicyMixCollection::closeOutput(sp<SwAudioOutputDescriptor> &desc)
 {
     for (size_t i = 0; i < size(); i++) {
-        sp<AudioPolicyMix> policyMix = valueAt(i);
+        sp<AudioPolicyMix> policyMix = itemAt(i);
         if (policyMix->getOutput() == desc) {
             policyMix->clearOutput();
         }
     }
 }
 
-status_t AudioPolicyMixCollection::getOutputForAttr(audio_attributes_t attributes, uid_t uid,
-                                                    sp<SwAudioOutputDescriptor> &desc)
+status_t AudioPolicyMixCollection::getOutputForAttr(
+        const audio_attributes_t& attributes, uid_t uid,
+        audio_output_flags_t flags,
+        sp<SwAudioOutputDescriptor> &primaryDesc,
+        std::vector<sp<SwAudioOutputDescriptor>> *secondaryDescs)
 {
     ALOGV("getOutputForAttr() querying %zu mixes:", size());
-    desc = 0;
+    primaryDesc = 0;
     for (size_t i = 0; i < size(); i++) {
-        sp<AudioPolicyMix> mix = valueAt(i);
+        sp<AudioPolicyMix> policyMix = itemAt(i);
+        const bool primaryOutputMix = !is_mix_loopback_render(policyMix->mRouteFlags);
+        if (!primaryOutputMix && (flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ)) {
+            // AAudio does not support MMAP_NO_IRQ loopback render, and there is no way with
+            // the current MmapStreamInterface::start to reject a specific client added to a shared
+            // mmap stream.
+            // As a result all MMAP_NOIRQ requests have to be rejected when an loopback render
+            // policy is present. That ensures no shared mmap stream is used when an loopback
+            // render policy is registered.
+            ALOGD("%s: Rejecting MMAP_NOIRQ request due to LOOPBACK|RENDER mix present.", __func__);
+            return INVALID_OPERATION;
+        }
 
-        if (mix->mMixType == MIX_TYPE_PLAYERS) {
-            // TODO if adding more player rules (currently only 2), make rule handling "generic"
-            //      as there is no difference in the treatment of usage- or uid-based rules
-            bool hasUsageMatchRules = false;
-            bool hasUsageExcludeRules = false;
-            bool usageMatchFound = false;
-            bool usageExclusionFound = false;
+        sp<SwAudioOutputDescriptor> policyDesc = policyMix->getOutput();
+        if (!policyDesc) {
+            ALOGV("%s: Skiping %zu: Mix has no output", __func__, i);
+            continue;
+        }
 
-            bool hasUidMatchRules = false;
-            bool hasUidExcludeRules = false;
-            bool uidMatchFound = false;
-            bool uidExclusionFound = false;
+        if (primaryOutputMix && primaryDesc != 0) {
+            ALOGV("%s: Skiping %zu: Primary output already found", __func__, i);
+            continue; // Primary output already found
+        }
 
-            bool hasAddrMatch = false;
+        switch (mixMatch(policyMix.get(), i, attributes, uid)) {
+            case MixMatchStatus::INVALID_MIX:
+                // The mix has contradictory rules, ignore it
+                // TODO: reject invalid mix at registration
+                continue;
+            case MixMatchStatus::NO_MATCH:
+                ALOGV("%s: Mix %zu: does not match", __func__, i);
+                continue; // skip the mix
+            case MixMatchStatus::MATCH:;
+        }
 
-            // iterate over all mix criteria to list what rules this mix contains
-            for (size_t j = 0; j < mix->mCriteria.size(); j++) {
-                ALOGV(" getOutputForAttr: mix %zu: inspecting mix criteria %zu of %zu",
-                        i, j, mix->mCriteria.size());
-
-                // if there is an address match, prioritize that match
-                if (strncmp(attributes.tags, "addr=", strlen("addr=")) == 0 &&
-                        strncmp(attributes.tags + strlen("addr="),
-                                mix->mDeviceAddress.string(),
-                                AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0) {
-                    hasAddrMatch = true;
-                    break;
-                }
-
-                switch (mix->mCriteria[j].mRule) {
-                case RULE_MATCH_ATTRIBUTE_USAGE:
-                    ALOGV("\tmix has RULE_MATCH_ATTRIBUTE_USAGE for usage %d",
-                                                mix->mCriteria[j].mValue.mUsage);
-                    hasUsageMatchRules = true;
-                    if (mix->mCriteria[j].mValue.mUsage == attributes.usage) {
-                        // found one match against all allowed usages
-                        usageMatchFound = true;
-                    }
-                    break;
-                case RULE_EXCLUDE_ATTRIBUTE_USAGE:
-                    ALOGV("\tmix has RULE_EXCLUDE_ATTRIBUTE_USAGE for usage %d",
-                            mix->mCriteria[j].mValue.mUsage);
-                    hasUsageExcludeRules = true;
-                    if (mix->mCriteria[j].mValue.mUsage == attributes.usage) {
-                        // found this usage is to be excluded
-                        usageExclusionFound = true;
-                    }
-                    break;
-                case RULE_MATCH_UID:
-                    ALOGV("\tmix has RULE_MATCH_UID for uid %d", mix->mCriteria[j].mValue.mUid);
-                    hasUidMatchRules = true;
-                    if (mix->mCriteria[j].mValue.mUid == uid) {
-                        // found one UID match against all allowed UIDs
-                        uidMatchFound = true;
-                    }
-                    break;
-                case RULE_EXCLUDE_UID:
-                    ALOGV("\tmix has RULE_EXCLUDE_UID for uid %d", mix->mCriteria[j].mValue.mUid);
-                    hasUidExcludeRules = true;
-                    if (mix->mCriteria[j].mValue.mUid == uid) {
-                        // found this UID is to be excluded
-                        uidExclusionFound = true;
-                    }
-                    break;
-                default:
-                    break;
-                }
-
-                // consistency checks: for each "dimension" of rules (usage, uid...), we can
-                // only have MATCH rules, or EXCLUDE rules in each dimension, not a combination
-                if (hasUsageMatchRules && hasUsageExcludeRules) {
-                    ALOGE("getOutputForAttr: invalid combination of RULE_MATCH_ATTRIBUTE_USAGE"
-                            " and RULE_EXCLUDE_ATTRIBUTE_USAGE in mix %zu", i);
-                    return BAD_VALUE;
-                }
-                if (hasUidMatchRules && hasUidExcludeRules) {
-                    ALOGE("getOutputForAttr: invalid combination of RULE_MATCH_UID"
-                            " and RULE_EXCLUDE_UID in mix %zu", i);
-                    return BAD_VALUE;
-                }
-
-                if ((hasUsageExcludeRules && usageExclusionFound)
-                        || (hasUidExcludeRules && uidExclusionFound)) {
-                    break; // stop iterating on criteria because an exclusion was found (will fail)
-                }
-
-            }//iterate on mix criteria
-
-            // determine if exiting on success (or implicit failure as desc is 0)
-            if (hasAddrMatch ||
-                    !((hasUsageExcludeRules && usageExclusionFound) ||
-                      (hasUsageMatchRules && !usageMatchFound)  ||
-                      (hasUidExcludeRules && uidExclusionFound) ||
-                      (hasUidMatchRules && !uidMatchFound))) {
-                ALOGV("\tgetOutputForAttr will use mix %zu", i);
-                desc = mix->getOutput();
+        policyDesc->mPolicyMix = policyMix;
+        if (primaryOutputMix) {
+            primaryDesc = policyDesc;
+            ALOGV("%s: Mix %zu: set primary desc", __func__, i);
+        } else {
+            if (policyDesc->mIoHandle == AUDIO_IO_HANDLE_NONE) {
+                ALOGV("%s: Mix %zu ignored as secondaryOutput because not opened yet", __func__, i);
+            } else {
+                ALOGV("%s: Add a secondary desc %zu", __func__, i);
+                secondaryDescs->push_back(policyDesc);
             }
+        }
+    }
+    return NO_ERROR;
+}
 
-        } else if (mix->mMixType == MIX_TYPE_RECORDERS) {
-            if (attributes.usage == AUDIO_USAGE_VIRTUAL_SOURCE &&
-                    strncmp(attributes.tags, "addr=", strlen("addr=")) == 0 &&
+AudioPolicyMixCollection::MixMatchStatus AudioPolicyMixCollection::mixMatch(
+        const AudioMix* mix, size_t mixIndex, const audio_attributes_t& attributes, uid_t uid) {
+
+    if (mix->mMixType == MIX_TYPE_PLAYERS) {
+        // Loopback render mixes are created from a public API and thus restricted
+        // to non sensible audio that have not opted out.
+        if (is_mix_loopback_render(mix->mRouteFlags)) {
+            auto hasFlag = [](auto flags, auto flag) { return (flags & flag) == flag; };
+            if (hasFlag(attributes.flags, AUDIO_FLAG_NO_SYSTEM_CAPTURE)) {
+                return MixMatchStatus::NO_MATCH;
+            }
+            if (!mix->mAllowPrivilegedPlaybackCapture &&
+                hasFlag(attributes.flags, AUDIO_FLAG_NO_MEDIA_PROJECTION)) {
+                return MixMatchStatus::NO_MATCH;
+            }
+            if (!(attributes.usage == AUDIO_USAGE_UNKNOWN ||
+                  attributes.usage == AUDIO_USAGE_MEDIA ||
+                  attributes.usage == AUDIO_USAGE_GAME)) {
+                return MixMatchStatus::NO_MATCH;
+            }
+        }
+        // TODO if adding more player rules (currently only 2), make rule handling "generic"
+        //      as there is no difference in the treatment of usage- or uid-based rules
+        bool hasUsageMatchRules = false;
+        bool hasUsageExcludeRules = false;
+        bool usageMatchFound = false;
+        bool usageExclusionFound = false;
+
+        bool hasUidMatchRules = false;
+        bool hasUidExcludeRules = false;
+        bool uidMatchFound = false;
+        bool uidExclusionFound = false;
+
+        bool hasAddrMatch = false;
+
+        // iterate over all mix criteria to list what rules this mix contains
+        for (size_t j = 0; j < mix->mCriteria.size(); j++) {
+            ALOGV(" getOutputForAttr: mix %zu: inspecting mix criteria %zu of %zu",
+                    mixIndex, j, mix->mCriteria.size());
+
+            // if there is an address match, prioritize that match
+            if (strncmp(attributes.tags, "addr=", strlen("addr=")) == 0 &&
                     strncmp(attributes.tags + strlen("addr="),
                             mix->mDeviceAddress.string(),
                             AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0) {
-                desc = mix->getOutput();
+                hasAddrMatch = true;
+                break;
             }
+
+            switch (mix->mCriteria[j].mRule) {
+            case RULE_MATCH_ATTRIBUTE_USAGE:
+                ALOGV("\tmix has RULE_MATCH_ATTRIBUTE_USAGE for usage %d",
+                                            mix->mCriteria[j].mValue.mUsage);
+                hasUsageMatchRules = true;
+                if (mix->mCriteria[j].mValue.mUsage == attributes.usage) {
+                    // found one match against all allowed usages
+                    usageMatchFound = true;
+                }
+                break;
+            case RULE_EXCLUDE_ATTRIBUTE_USAGE:
+                ALOGV("\tmix has RULE_EXCLUDE_ATTRIBUTE_USAGE for usage %d",
+                        mix->mCriteria[j].mValue.mUsage);
+                hasUsageExcludeRules = true;
+                if (mix->mCriteria[j].mValue.mUsage == attributes.usage) {
+                    // found this usage is to be excluded
+                    usageExclusionFound = true;
+                }
+                break;
+            case RULE_MATCH_UID:
+                ALOGV("\tmix has RULE_MATCH_UID for uid %d", mix->mCriteria[j].mValue.mUid);
+                hasUidMatchRules = true;
+                if (mix->mCriteria[j].mValue.mUid == uid) {
+                    // found one UID match against all allowed UIDs
+                    uidMatchFound = true;
+                }
+                break;
+            case RULE_EXCLUDE_UID:
+                ALOGV("\tmix has RULE_EXCLUDE_UID for uid %d", mix->mCriteria[j].mValue.mUid);
+                hasUidExcludeRules = true;
+                if (mix->mCriteria[j].mValue.mUid == uid) {
+                    // found this UID is to be excluded
+                    uidExclusionFound = true;
+                }
+                break;
+            default:
+                break;
+            }
+
+            // consistency checks: for each "dimension" of rules (usage, uid...), we can
+            // only have MATCH rules, or EXCLUDE rules in each dimension, not a combination
+            if (hasUsageMatchRules && hasUsageExcludeRules) {
+                ALOGE("getOutputForAttr: invalid combination of RULE_MATCH_ATTRIBUTE_USAGE"
+                        " and RULE_EXCLUDE_ATTRIBUTE_USAGE in mix %zu", mixIndex);
+                return MixMatchStatus::INVALID_MIX;
+            }
+            if (hasUidMatchRules && hasUidExcludeRules) {
+                ALOGE("getOutputForAttr: invalid combination of RULE_MATCH_UID"
+                        " and RULE_EXCLUDE_UID in mix %zu", mixIndex);
+                return MixMatchStatus::INVALID_MIX;
+            }
+
+            if ((hasUsageExcludeRules && usageExclusionFound)
+                    || (hasUidExcludeRules && uidExclusionFound)) {
+                break; // stop iterating on criteria because an exclusion was found (will fail)
+            }
+
+        }//iterate on mix criteria
+
+        // determine if exiting on success (or implicit failure as desc is 0)
+        if (hasAddrMatch ||
+                !((hasUsageExcludeRules && usageExclusionFound) ||
+                  (hasUsageMatchRules && !usageMatchFound)  ||
+                  (hasUidExcludeRules && uidExclusionFound) ||
+                  (hasUidMatchRules && !uidMatchFound))) {
+            ALOGV("\tgetOutputForAttr will use mix %zu", mixIndex);
+            return MixMatchStatus::MATCH;
         }
-        if (desc != 0) {
-            desc->mPolicyMix = mix;
-            return NO_ERROR;
+
+    } else if (mix->mMixType == MIX_TYPE_RECORDERS) {
+        if (attributes.usage == AUDIO_USAGE_VIRTUAL_SOURCE &&
+                strncmp(attributes.tags, "addr=", strlen("addr=")) == 0 &&
+                strncmp(attributes.tags + strlen("addr="),
+                        mix->mDeviceAddress.string(),
+                        AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0) {
+            return MixMatchStatus::MATCH;
         }
     }
-    return BAD_VALUE;
+    return MixMatchStatus::NO_MATCH;
 }
 
-audio_devices_t AudioPolicyMixCollection::getDeviceAndMixForInputSource(
-        audio_source_t inputSource,
-        audio_devices_t availDevices,
-        sp<AudioPolicyMix> *policyMix)
+sp<DeviceDescriptor> AudioPolicyMixCollection::getDeviceAndMixForOutput(
+        const sp<SwAudioOutputDescriptor> &output,
+        const DeviceVector &availableOutputDevices)
 {
     for (size_t i = 0; i < size(); i++) {
-        AudioPolicyMix *mix = valueAt(i).get();
+        if (itemAt(i)->getOutput() == output) {
+            // This Desc is involved in a Mix, which has the highest prio
+            audio_devices_t deviceType = itemAt(i)->mDeviceType;
+            String8 address = itemAt(i)->mDeviceAddress;
+            ALOGV("%s: device (0x%x, addr=%s) forced by mix",
+                  __FUNCTION__, deviceType, address.c_str());
+            return availableOutputDevices.getDevice(deviceType, address, AUDIO_FORMAT_DEFAULT);
+        }
+    }
+    return nullptr;
+}
 
+sp<DeviceDescriptor> AudioPolicyMixCollection::getDeviceAndMixForInputSource(
+        audio_source_t inputSource,
+        const DeviceVector &availDevices,
+        sp<AudioPolicyMix> *policyMix) const
+{
+    for (size_t i = 0; i < size(); i++) {
+        AudioPolicyMix *mix = itemAt(i).get();
         if (mix->mMixType != MIX_TYPE_RECORDERS) {
             continue;
         }
@@ -297,17 +367,22 @@
                     mix->mCriteria[j].mValue.mSource == inputSource) ||
                (RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET == mix->mCriteria[j].mRule &&
                     mix->mCriteria[j].mValue.mSource != inputSource)) {
-                if (availDevices & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
-                    if (policyMix != NULL) {
+                // assuming PolicyMix only for remote submix for input
+                // so mix->mDeviceType can only be AUDIO_DEVICE_OUT_REMOTE_SUBMIX
+                audio_devices_t device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
+                auto mixDevice =
+                        availDevices.getDevice(device, mix->mDeviceAddress, AUDIO_FORMAT_DEFAULT);
+                if (mixDevice != nullptr) {
+                    if (policyMix != nullptr) {
                         *policyMix = mix;
                     }
-                    return AUDIO_DEVICE_IN_REMOTE_SUBMIX;
+                    return mixDevice;
                 }
                 break;
             }
         }
     }
-    return AUDIO_DEVICE_NONE;
+    return nullptr;
 }
 
 status_t AudioPolicyMixCollection::getInputMixForAttr(
@@ -319,19 +394,28 @@
     String8 address(attr.tags + strlen("addr="));
 
 #ifdef LOG_NDEBUG
-    ALOGV("getInputMixForAttr looking for address %s\n  mixes available:", address.string());
+    ALOGV("getInputMixForAttr looking for address %s for source %d\n  mixes available:",
+            address.string(), attr.source);
     for (size_t i = 0; i < size(); i++) {
-            sp<AudioPolicyMix> mix = valueAt(i);
-            ALOGV("\tmix %zu address=%s", i, mix->mDeviceAddress.string());
+        const sp<AudioPolicyMix> audioPolicyMix = itemAt(i);
+        ALOGV("\tmix %zu address=%s", i, audioPolicyMix->mDeviceAddress.string());
     }
 #endif
 
-    ssize_t index = indexOfKey(address);
-    if (index < 0) {
+    size_t index;
+    for (index = 0; index < size(); index++) {
+        const sp<AudioPolicyMix>& registeredMix = itemAt(index);
+        if (registeredMix->mDeviceAddress.compare(address) == 0) {
+            ALOGD("getInputMixForAttr found addr=%s dev=0x%x",
+                    registeredMix->mDeviceAddress.string(), registeredMix->mDeviceType);
+            break;
+        }
+    }
+    if (index == size()) {
         ALOGW("getInputMixForAttr() no policy for address %s", address.string());
         return BAD_VALUE;
     }
-    sp<AudioPolicyMix> audioPolicyMix = valueAt(index);
+    const sp<AudioPolicyMix> audioPolicyMix = itemAt(index);
 
     if (audioPolicyMix->mMixType != MIX_TYPE_PLAYERS) {
         ALOGW("getInputMixForAttr() bad policy mix type for address %s", address.string());
@@ -343,14 +427,114 @@
     return NO_ERROR;
 }
 
-status_t AudioPolicyMixCollection::dump(int fd) const
-{
-    std::string log("\nAudio Policy Mix:\n");
-    write(fd, log.c_str(), log.size());
+status_t AudioPolicyMixCollection::setUidDeviceAffinities(uid_t uid,
+        const Vector<AudioDeviceTypeAddr>& devices) {
+    // verify feasibility: for each player mix: if it already contains a
+    //    "match uid" rule for this uid, return an error
+    //    (adding a uid-device affinity would result in contradictory rules)
     for (size_t i = 0; i < size(); i++) {
-        valueAt(i)->dump(fd, 2, i);
+        const AudioPolicyMix* mix = itemAt(i).get();
+        if (!mix->isDeviceAffinityCompatible()) {
+            continue;
+        }
+        if (mix->hasUidRule(true /*match*/, uid)) {
+            return INVALID_OPERATION;
+        }
+    }
+
+    // remove existing rules for this uid
+    removeUidDeviceAffinities(uid);
+
+    // for each player mix:
+    //   IF    device is not a target for the mix,
+    //     AND it doesn't have a "match uid" rule
+    //   THEN add a rule to exclude the uid
+    for (size_t i = 0; i < size(); i++) {
+        const AudioPolicyMix *mix = itemAt(i).get();
+        if (!mix->isDeviceAffinityCompatible()) {
+            continue;
+        }
+        // check if this mix goes to a device in the list of devices
+        bool deviceMatch = false;
+        for (size_t j = 0; j < devices.size(); j++) {
+            if (devices[j].mType == mix->mDeviceType
+                    && devices[j].mAddress == mix->mDeviceAddress) {
+                deviceMatch = true;
+                break;
+            }
+        }
+        if (!deviceMatch && !mix->hasMatchUidRule()) {
+            // this mix doesn't go to one of the listed devices for the given uid,
+            // and it's not already restricting the mix on a uid,
+            // modify its rules to exclude the uid
+            if (!mix->hasUidRule(false /*match*/, uid)) {
+                // no need to do it again if uid is already excluded
+                mix->setExcludeUid(uid);
+            }
+        }
+    }
+
+    return NO_ERROR;
+}
+
+status_t AudioPolicyMixCollection::removeUidDeviceAffinities(uid_t uid) {
+    // for each player mix: remove existing rules that match or exclude this uid
+    for (size_t i = 0; i < size(); i++) {
+        bool foundUidRule = false;
+        const AudioPolicyMix *mix = itemAt(i).get();
+        if (!mix->isDeviceAffinityCompatible()) {
+            continue;
+        }
+        std::vector<size_t> criteriaToRemove;
+        for (size_t j = 0; j < mix->mCriteria.size(); j++) {
+            const uint32_t rule = mix->mCriteria[j].mRule;
+            // is this rule excluding the uid? (not considering uid match rules
+            // as those are not used for uid-device affinity)
+            if (rule == RULE_EXCLUDE_UID
+                    && uid == mix->mCriteria[j].mValue.mUid) {
+                foundUidRule = true;
+                criteriaToRemove.insert(criteriaToRemove.begin(), j);
+            }
+        }
+        if (foundUidRule) {
+            for (size_t j = 0; j < criteriaToRemove.size(); j++) {
+                mix->mCriteria.removeAt(criteriaToRemove[j]);
+            }
+        }
     }
     return NO_ERROR;
 }
 
+status_t AudioPolicyMixCollection::getDevicesForUid(uid_t uid,
+        Vector<AudioDeviceTypeAddr>& devices) const {
+    // for each player mix: find rules that don't exclude this uid, and add the device to the list
+    for (size_t i = 0; i < size(); i++) {
+        bool ruleAllowsUid = true;
+        const AudioPolicyMix *mix = itemAt(i).get();
+        if (mix->mMixType != MIX_TYPE_PLAYERS) {
+            continue;
+        }
+        for (size_t j = 0; j < mix->mCriteria.size(); j++) {
+            const uint32_t rule = mix->mCriteria[j].mRule;
+            if (rule == RULE_EXCLUDE_UID
+                    && uid == mix->mCriteria[j].mValue.mUid) {
+                ruleAllowsUid = false;
+                break;
+            }
+        }
+        if (ruleAllowsUid) {
+            devices.add(AudioDeviceTypeAddr(mix->mDeviceType, mix->mDeviceAddress));
+        }
+    }
+    return NO_ERROR;
+}
+
+void AudioPolicyMixCollection::dump(String8 *dst) const
+{
+    dst->append("\nAudio Policy Mix:\n");
+    for (size_t i = 0; i < size(); i++) {
+        itemAt(i)->dump(dst, 2, i);
+    }
+}
+
 }; //namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
index d85562e..c11490a 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
@@ -31,9 +31,15 @@
 // --- AudioPort class implementation
 void AudioPort::attach(const sp<HwModule>& module)
 {
+    ALOGV("%s: attaching module %s to port %s", __FUNCTION__, getModuleName(), mName.string());
     mModule = module;
 }
 
+void AudioPort::detach()
+{
+    mModule = nullptr;
+}
+
 // Note that is a different namespace than AudioFlinger unique IDs
 audio_port_handle_t AudioPort::getNextUniqueId()
 {
@@ -276,30 +282,25 @@
     return index1 - index2;
 }
 
+uint32_t AudioPort::formatDistance(audio_format_t format1, audio_format_t format2)
+{
+    if (format1 == format2) {
+        return 0;
+    }
+    if (format1 == AUDIO_FORMAT_INVALID || format2 == AUDIO_FORMAT_INVALID) {
+        return kFormatDistanceMax;
+    }
+    int diffBytes = (int)audio_bytes_per_sample(format1) -
+            audio_bytes_per_sample(format2);
+
+    return abs(diffBytes);
+}
+
 bool AudioPort::isBetterFormatMatch(audio_format_t newFormat,
                                     audio_format_t currentFormat,
                                     audio_format_t targetFormat)
 {
-    if (newFormat == currentFormat) {
-        return false;
-    }
-    if (currentFormat == AUDIO_FORMAT_INVALID) {
-        return true;
-    }
-    if (newFormat == targetFormat) {
-        return true;
-    }
-    int currentDiffBytes = (int)audio_bytes_per_sample(targetFormat) -
-            audio_bytes_per_sample(currentFormat);
-    int newDiffBytes = (int)audio_bytes_per_sample(targetFormat) -
-            audio_bytes_per_sample(newFormat);
-
-    if (abs(newDiffBytes) < abs(currentDiffBytes)) {
-        return true;
-    } else if (abs(newDiffBytes) == abs(currentDiffBytes)) {
-        return (newDiffBytes >= 0);
-    }
-    return false;
+    return formatDistance(newFormat, targetFormat) < formatDistance(currentFormat, targetFormat);
 }
 
 void AudioPort::pickAudioProfile(uint32_t &samplingRate,
@@ -354,26 +355,18 @@
     return mGains[index]->checkConfig(gainConfig);
 }
 
-void AudioPort::dump(int fd, int spaces, bool verbose) const
+void AudioPort::dump(String8 *dst, int spaces, bool verbose) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
     if (!mName.isEmpty()) {
-        snprintf(buffer, SIZE, "%*s- name: %s\n", spaces, "", mName.string());
-        result.append(buffer);
-        write(fd, result.string(), result.size());
+        dst->appendFormat("%*s- name: %s\n", spaces, "", mName.string());
     }
     if (verbose) {
-        mProfiles.dump(fd, spaces);
+        mProfiles.dump(dst, spaces);
 
         if (mGains.size() != 0) {
-            snprintf(buffer, SIZE, "%*s- gains:\n", spaces, "");
-            result = buffer;
-            write(fd, result.string(), result.size());
+            dst->appendFormat("%*s- gains:\n", spaces, "");
             for (size_t i = 0; i < mGains.size(); i++) {
-                mGains[i]->dump(fd, spaces + 2, i);
+                mGains[i]->dump(dst, spaces + 2, i);
             }
         }
     }
@@ -386,22 +379,12 @@
 
 // --- AudioPortConfig class implementation
 
-AudioPortConfig::AudioPortConfig()
-{
-    mSamplingRate = 0;
-    mChannelMask = AUDIO_CHANNEL_NONE;
-    mFormat = AUDIO_FORMAT_INVALID;
-    memset(&mGain, 0, sizeof(struct audio_gain_config));
-    mGain.index = -1;
-}
-
 status_t AudioPortConfig::applyAudioPortConfig(const struct audio_port_config *config,
                                                struct audio_port_config *backupConfig)
 {
-    struct audio_port_config localBackupConfig;
+    struct audio_port_config localBackupConfig = { .config_mask = config->config_mask };
     status_t status = NO_ERROR;
 
-    localBackupConfig.config_mask = config->config_mask;
     toAudioPortConfig(&localBackupConfig);
 
     sp<AudioPort> audioport = getAudioPort();
@@ -425,6 +408,9 @@
     if (config->config_mask & AUDIO_PORT_CONFIG_GAIN) {
         mGain = config->gain;
     }
+    if (config->config_mask & AUDIO_PORT_CONFIG_FLAGS) {
+        mFlags = config->flags;
+    }
 
 exit:
     if (status != NO_ERROR) {
@@ -436,33 +422,38 @@
     return status;
 }
 
+namespace {
+
+template<typename T>
+void updateField(
+        const T& portConfigField, T audio_port_config::*port_config_field,
+        struct audio_port_config *dstConfig, const struct audio_port_config *srcConfig,
+        unsigned int configMask, T defaultValue)
+{
+    if (dstConfig->config_mask & configMask) {
+        if ((srcConfig != nullptr) && (srcConfig->config_mask & configMask)) {
+            dstConfig->*port_config_field = srcConfig->*port_config_field;
+        } else {
+            dstConfig->*port_config_field = portConfigField;
+        }
+    } else {
+        dstConfig->*port_config_field = defaultValue;
+    }
+}
+
+} // namespace
+
 void AudioPortConfig::toAudioPortConfig(struct audio_port_config *dstConfig,
                                         const struct audio_port_config *srcConfig) const
 {
-    if (dstConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
-        dstConfig->sample_rate = mSamplingRate;
-        if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE)) {
-            dstConfig->sample_rate = srcConfig->sample_rate;
-        }
-    } else {
-        dstConfig->sample_rate = 0;
-    }
-    if (dstConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
-        dstConfig->channel_mask = mChannelMask;
-        if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK)) {
-            dstConfig->channel_mask = srcConfig->channel_mask;
-        }
-    } else {
-        dstConfig->channel_mask = AUDIO_CHANNEL_NONE;
-    }
-    if (dstConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT) {
-        dstConfig->format = mFormat;
-        if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT)) {
-            dstConfig->format = srcConfig->format;
-        }
-    } else {
-        dstConfig->format = AUDIO_FORMAT_INVALID;
-    }
+    updateField(mSamplingRate, &audio_port_config::sample_rate,
+            dstConfig, srcConfig, AUDIO_PORT_CONFIG_SAMPLE_RATE, 0u);
+    updateField(mChannelMask, &audio_port_config::channel_mask,
+            dstConfig, srcConfig, AUDIO_PORT_CONFIG_CHANNEL_MASK,
+            (audio_channel_mask_t)AUDIO_CHANNEL_NONE);
+    updateField(mFormat, &audio_port_config::format,
+            dstConfig, srcConfig, AUDIO_PORT_CONFIG_FORMAT, AUDIO_FORMAT_INVALID);
+
     sp<AudioPort> audioport = getAudioPort();
     if ((dstConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) && audioport != NULL) {
         dstConfig->gain = mGain;
@@ -478,6 +469,19 @@
     } else {
         dstConfig->config_mask &= ~AUDIO_PORT_CONFIG_GAIN;
     }
+
+    updateField(mFlags, &audio_port_config::flags,
+            dstConfig, srcConfig, AUDIO_PORT_CONFIG_FLAGS, { AUDIO_INPUT_FLAG_NONE });
+}
+
+bool AudioPortConfig::hasGainController(bool canUseForVolume) const
+{
+    sp<AudioPort> audioport = getAudioPort();
+    if (audioport == nullptr) {
+        return false;
+    }
+    return canUseForVolume ? audioport->getGains().canUseForVolume()
+                           : audioport->getGains().size() > 0;
 }
 
 } // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp
index fd6fc1c..69d6b0c 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp
@@ -14,20 +14,112 @@
  * limitations under the License.
  */
 
+#include <algorithm>
+#include <set>
+#include <string>
+
 #define LOG_TAG "APM::AudioProfile"
 //#define LOG_NDEBUG 0
 
-#include "AudioProfile.h"
-#include "AudioPort.h"
-#include "HwModule.h"
-#include "AudioGain.h"
-#include <utils/SortedVector.h>
-#include "TypeConverter.h"
 #include <media/AudioResamplerPublic.h>
-#include <algorithm>
+#include <utils/Errors.h>
+
+#include "AudioGain.h"
+#include "AudioPort.h"
+#include "AudioProfile.h"
+#include "HwModule.h"
+#include "TypeConverter.h"
 
 namespace android {
 
+ChannelsVector ChannelsVector::asInMask() const
+{
+    ChannelsVector inMaskVector;
+    for (const auto& channel : *this) {
+        if (audio_channel_mask_out_to_in(channel) != AUDIO_CHANNEL_INVALID) {
+            inMaskVector.add(audio_channel_mask_out_to_in(channel));
+        }
+    }
+    return inMaskVector;
+}
+
+ChannelsVector ChannelsVector::asOutMask() const
+{
+    ChannelsVector outMaskVector;
+    for (const auto& channel : *this) {
+        if (audio_channel_mask_in_to_out(channel) != AUDIO_CHANNEL_INVALID) {
+            outMaskVector.add(audio_channel_mask_in_to_out(channel));
+        }
+    }
+    return outMaskVector;
+}
+
+bool operator == (const AudioProfile &left, const AudioProfile &compareTo)
+{
+    return (left.getFormat() == compareTo.getFormat()) &&
+            (left.getChannels() == compareTo.getChannels()) &&
+            (left.getSampleRates() == compareTo.getSampleRates());
+}
+
+static AudioProfile* createFullDynamicImpl()
+{
+    AudioProfile* dynamicProfile = new AudioProfile(gDynamicFormat,
+            ChannelsVector(), SampleRateVector());
+    dynamicProfile->setDynamicFormat(true);
+    dynamicProfile->setDynamicChannels(true);
+    dynamicProfile->setDynamicRate(true);
+    return dynamicProfile;
+}
+
+// static
+sp<AudioProfile> AudioProfile::createFullDynamic()
+{
+    static sp<AudioProfile> dynamicProfile = createFullDynamicImpl();
+    return dynamicProfile;
+}
+
+AudioProfile::AudioProfile(audio_format_t format,
+                           audio_channel_mask_t channelMasks,
+                           uint32_t samplingRate) :
+        mName(String8("")),
+        mFormat(format)
+{
+    mChannelMasks.add(channelMasks);
+    mSamplingRates.add(samplingRate);
+}
+
+AudioProfile::AudioProfile(audio_format_t format,
+                           const ChannelsVector &channelMasks,
+                           const SampleRateVector &samplingRateCollection) :
+        mName(String8("")),
+        mFormat(format),
+        mChannelMasks(channelMasks),
+        mSamplingRates(samplingRateCollection) {}
+
+void AudioProfile::setChannels(const ChannelsVector &channelMasks)
+{
+    if (mIsDynamicChannels) {
+        mChannelMasks = channelMasks;
+    }
+}
+
+void AudioProfile::setSampleRates(const SampleRateVector &sampleRates)
+{
+    if (mIsDynamicRate) {
+        mSamplingRates = sampleRates;
+    }
+}
+
+void AudioProfile::clear()
+{
+    if (mIsDynamicChannels) {
+        mChannelMasks.clear();
+    }
+    if (mIsDynamicRate) {
+        mSamplingRates.clear();
+    }
+}
+
 status_t AudioProfile::checkExact(uint32_t samplingRate, audio_channel_mask_t channelMask,
                                   audio_format_t format) const
 {
@@ -39,27 +131,6 @@
     return BAD_VALUE;
 }
 
-template <typename T>
-bool operator == (const SortedVector<T> &left, const SortedVector<T> &right)
-{
-    if (left.size() != right.size()) {
-        return false;
-    }
-    for(size_t index = 0; index < right.size(); index++) {
-        if (left[index] != right[index]) {
-            return false;
-        }
-    }
-    return true;
-}
-
-bool operator == (const AudioProfile &left, const AudioProfile &compareTo)
-{
-    return (left.getFormat() == compareTo.getFormat()) &&
-            (left.getChannels() == compareTo.getChannels()) &&
-            (left.getSampleRates() == compareTo.getSampleRates());
-}
-
 status_t AudioProfile::checkCompatibleSamplingRate(uint32_t samplingRate,
                                                    uint32_t &updatedSamplingRate) const
 {
@@ -107,6 +178,7 @@
     const bool isRecordThread = portType == AUDIO_PORT_TYPE_MIX && portRole == AUDIO_PORT_ROLE_SINK;
     const bool isIndex = audio_channel_mask_get_representation(channelMask)
             == AUDIO_CHANNEL_REPRESENTATION_INDEX;
+    const uint32_t channelCount = audio_channel_count_from_in_mask(channelMask);
     int bestMatch = 0;
     for (size_t i = 0; i < mChannelMasks.size(); i ++) {
         audio_channel_mask_t supported = mChannelMasks[i];
@@ -130,11 +202,15 @@
             // OR
             // match score += 100 if the channel mask representations match
             // match score += number of channels matched.
+            // match score += 100 if the channel mask representations DO NOT match
+            //   but the profile has positional channel mask and less than 2 channels.
+            //   This is for audio HAL convention to not list index masks for less than 2 channels
             //
             // If there are no matched channels, the mask may still be accepted
             // but the playback or record will be silent.
             const bool isSupportedIndex = (audio_channel_mask_get_representation(supported)
                     == AUDIO_CHANNEL_REPRESENTATION_INDEX);
+            const uint32_t supportedChannelCount = audio_channel_count_from_in_mask(supported);
             int match;
             if (isIndex && isSupportedIndex) {
                 // index equivalence
@@ -142,13 +218,14 @@
                         audio_channel_mask_get_bits(channelMask)
                             & audio_channel_mask_get_bits(supported));
             } else if (isIndex && !isSupportedIndex) {
-                const uint32_t equivalentBits =
-                        (1 << audio_channel_count_from_in_mask(supported)) - 1 ;
+                const uint32_t equivalentBits = (1 << supportedChannelCount) - 1 ;
                 match = __builtin_popcount(
                         audio_channel_mask_get_bits(channelMask) & equivalentBits);
+                if (supportedChannelCount <= FCC_2) {
+                    match += 100;
+                }
             } else if (!isIndex && isSupportedIndex) {
-                const uint32_t equivalentBits =
-                        (1 << audio_channel_count_from_in_mask(channelMask)) - 1;
+                const uint32_t equivalentBits = (1 << channelCount) - 1;
                 match = __builtin_popcount(
                         equivalentBits & audio_channel_mask_get_bits(supported));
             } else {
@@ -182,47 +259,79 @@
     return bestMatch > 0 ? NO_ERROR : BAD_VALUE;
 }
 
-void AudioProfile::dump(int fd, int spaces) const
+void AudioProfile::dump(String8 *dst, int spaces) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "%s%s%s\n", mIsDynamicFormat ? "[dynamic format]" : "",
+    dst->appendFormat("%s%s%s\n", mIsDynamicFormat ? "[dynamic format]" : "",
              mIsDynamicChannels ? "[dynamic channels]" : "",
              mIsDynamicRate ? "[dynamic rates]" : "");
-    result.append(buffer);
     if (mName.length() != 0) {
-        snprintf(buffer, SIZE, "%*s- name: %s\n", spaces, "", mName.string());
-        result.append(buffer);
+        dst->appendFormat("%*s- name: %s\n", spaces, "", mName.string());
     }
     std::string formatLiteral;
     if (FormatConverter::toString(mFormat, formatLiteral)) {
-        snprintf(buffer, SIZE, "%*s- format: %s\n", spaces, "", formatLiteral.c_str());
-        result.append(buffer);
+        dst->appendFormat("%*s- format: %s\n", spaces, "", formatLiteral.c_str());
     }
     if (!mSamplingRates.isEmpty()) {
-        snprintf(buffer, SIZE, "%*s- sampling rates:", spaces, "");
-        result.append(buffer);
+        dst->appendFormat("%*s- sampling rates:", spaces, "");
         for (size_t i = 0; i < mSamplingRates.size(); i++) {
-            snprintf(buffer, SIZE, "%d", mSamplingRates[i]);
-            result.append(buffer);
-            result.append(i == (mSamplingRates.size() - 1) ? "" : ", ");
+            dst->appendFormat("%d", mSamplingRates[i]);
+            dst->append(i == (mSamplingRates.size() - 1) ? "" : ", ");
         }
-        result.append("\n");
+        dst->append("\n");
     }
 
     if (!mChannelMasks.isEmpty()) {
-        snprintf(buffer, SIZE, "%*s- channel masks:", spaces, "");
-        result.append(buffer);
+        dst->appendFormat("%*s- channel masks:", spaces, "");
         for (size_t i = 0; i < mChannelMasks.size(); i++) {
-            snprintf(buffer, SIZE, "0x%04x", mChannelMasks[i]);
-            result.append(buffer);
-            result.append(i == (mChannelMasks.size() - 1) ? "" : ", ");
+            dst->appendFormat("0x%04x", mChannelMasks[i]);
+            dst->append(i == (mChannelMasks.size() - 1) ? "" : ", ");
         }
-        result.append("\n");
+        dst->append("\n");
     }
-    write(fd, result.string(), result.size());
+}
+
+ssize_t AudioProfileVector::add(const sp<AudioProfile> &profile)
+{
+    ssize_t index = Vector::add(profile);
+    // we sort from worst to best, so that AUDIO_FORMAT_DEFAULT is always the first entry.
+    // TODO: compareFormats could be a lambda to convert between pointer-to-format to format:
+    // [](const audio_format_t *format1, const audio_format_t *format2) {
+    //     return compareFormats(*format1, *format2);
+    // }
+    sort(compareFormats);
+    return index;
+}
+
+ssize_t AudioProfileVector::addProfileFromHal(const sp<AudioProfile> &profileToAdd)
+{
+    // Check valid profile to add:
+    if (!profileToAdd->hasValidFormat()) {
+        return -1;
+    }
+    if (!profileToAdd->hasValidChannels() && !profileToAdd->hasValidRates()) {
+        FormatVector formats;
+        formats.add(profileToAdd->getFormat());
+        setFormats(FormatVector(formats));
+        return 0;
+    }
+    if (!profileToAdd->hasValidChannels() && profileToAdd->hasValidRates()) {
+        setSampleRatesFor(profileToAdd->getSampleRates(), profileToAdd->getFormat());
+        return 0;
+    }
+    if (profileToAdd->hasValidChannels() && !profileToAdd->hasValidRates()) {
+        setChannelsFor(profileToAdd->getChannels(), profileToAdd->getFormat());
+        return 0;
+    }
+    // Go through the list of profile to avoid duplicates
+    for (size_t profileIndex = 0; profileIndex < size(); profileIndex++) {
+        const sp<AudioProfile> &profile = itemAt(profileIndex);
+        if (profile->isValid() && profile == profileToAdd) {
+            // Nothing to do
+            return profileIndex;
+        }
+    }
+    profileToAdd->setDynamicFormat(true); // set the format as dynamic to allow removal
+    return add(profileToAdd);
 }
 
 status_t AudioProfileVector::checkExactProfile(uint32_t samplingRate,
@@ -281,6 +390,228 @@
     return BAD_VALUE;
 }
 
+void AudioProfileVector::clearProfiles()
+{
+    for (size_t i = size(); i != 0; ) {
+        sp<AudioProfile> profile = itemAt(--i);
+        if (profile->isDynamicFormat() && profile->hasValidFormat()) {
+            removeAt(i);
+            continue;
+        }
+        profile->clear();
+    }
+}
+
+// Returns an intersection between two possibly unsorted vectors and the contents of 'order'.
+// The result is ordered according to 'order'.
+template<typename T, typename Order>
+std::vector<typename T::value_type> intersectFilterAndOrder(
+        const T& input1, const T& input2, const Order& order)
+{
+    std::set<typename T::value_type> set1{input1.begin(), input1.end()};
+    std::set<typename T::value_type> set2{input2.begin(), input2.end()};
+    std::set<typename T::value_type> common;
+    std::set_intersection(set1.begin(), set1.end(), set2.begin(), set2.end(),
+            std::inserter(common, common.begin()));
+    std::vector<typename T::value_type> result;
+    for (const auto& e : order) {
+        if (common.find(e) != common.end()) result.push_back(e);
+    }
+    return result;
+}
+
+// Intersect two possibly unsorted vectors, return common elements according to 'comp' ordering.
+// 'comp' is a comparator function.
+template<typename T, typename Compare>
+std::vector<typename T::value_type> intersectAndOrder(
+        const T& input1, const T& input2, Compare comp)
+{
+    std::set<typename T::value_type, Compare> set1{input1.begin(), input1.end(), comp};
+    std::set<typename T::value_type, Compare> set2{input2.begin(), input2.end(), comp};
+    std::vector<typename T::value_type> result;
+    std::set_intersection(set1.begin(), set1.end(), set2.begin(), set2.end(),
+            std::back_inserter(result), comp);
+    return result;
+}
+
+status_t AudioProfileVector::findBestMatchingOutputConfig(const AudioProfileVector& outputProfiles,
+            const std::vector<audio_format_t>& preferredFormats,
+            const std::vector<audio_channel_mask_t>& preferredOutputChannels,
+            bool preferHigherSamplingRates,
+            audio_config_base *bestOutputConfig) const
+{
+    auto formats = intersectFilterAndOrder(getSupportedFormats(),
+            outputProfiles.getSupportedFormats(), preferredFormats);
+    // Pick the best compatible profile.
+    for (const auto& f : formats) {
+        sp<AudioProfile> inputProfile = getFirstValidProfileFor(f);
+        sp<AudioProfile> outputProfile = outputProfiles.getFirstValidProfileFor(f);
+        if (inputProfile == nullptr || outputProfile == nullptr) {
+            continue;
+        }
+        auto channels = intersectFilterAndOrder(inputProfile->getChannels().asOutMask(),
+                outputProfile->getChannels(), preferredOutputChannels);
+        if (channels.empty()) {
+            continue;
+        }
+        auto sampleRates = preferHigherSamplingRates ?
+                intersectAndOrder(inputProfile->getSampleRates(), outputProfile->getSampleRates(),
+                        std::greater<typename SampleRateVector::value_type>()) :
+                intersectAndOrder(inputProfile->getSampleRates(), outputProfile->getSampleRates(),
+                        std::less<typename SampleRateVector::value_type>());
+        if (sampleRates.empty()) {
+            continue;
+        }
+        ALOGD("%s() found channel mask %#x and sample rate %d for format %#x.",
+                __func__, *channels.begin(), *sampleRates.begin(), f);
+        bestOutputConfig->format = f;
+        bestOutputConfig->sample_rate = *sampleRates.begin();
+        bestOutputConfig->channel_mask = *channels.begin();
+        return NO_ERROR;
+    }
+    return BAD_VALUE;
+}
+
+sp<AudioProfile> AudioProfileVector::getFirstValidProfile() const
+{
+    for (size_t i = 0; i < size(); i++) {
+        if (itemAt(i)->isValid()) {
+            return itemAt(i);
+        }
+    }
+    return 0;
+}
+
+sp<AudioProfile> AudioProfileVector::getFirstValidProfileFor(audio_format_t format) const
+{
+    for (size_t i = 0; i < size(); i++) {
+        if (itemAt(i)->isValid() && itemAt(i)->getFormat() == format) {
+            return itemAt(i);
+        }
+    }
+    return 0;
+}
+
+FormatVector AudioProfileVector::getSupportedFormats() const
+{
+    FormatVector supportedFormats;
+    for (size_t i = 0; i < size(); i++) {
+        if (itemAt(i)->hasValidFormat()) {
+            supportedFormats.add(itemAt(i)->getFormat());
+        }
+    }
+    return supportedFormats;
+}
+
+bool AudioProfileVector::hasDynamicChannelsFor(audio_format_t format) const
+{
+    for (size_t i = 0; i < size(); i++) {
+        sp<AudioProfile> profile = itemAt(i);
+        if (profile->getFormat() == format && profile->isDynamicChannels()) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool AudioProfileVector::hasDynamicProfile() const
+{
+    for (size_t i = 0; i < size(); i++) {
+        if (itemAt(i)->isDynamic()) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool AudioProfileVector::hasDynamicRateFor(audio_format_t format) const
+{
+    for (size_t i = 0; i < size(); i++) {
+        sp<AudioProfile> profile = itemAt(i);
+        if (profile->getFormat() == format && profile->isDynamicRate()) {
+            return true;
+        }
+    }
+    return false;
+}
+
+void AudioProfileVector::setFormats(const FormatVector &formats)
+{
+    // Only allow to change the format of dynamic profile
+    sp<AudioProfile> dynamicFormatProfile = getProfileFor(gDynamicFormat);
+    if (dynamicFormatProfile == 0) {
+        return;
+    }
+    for (size_t i = 0; i < formats.size(); i++) {
+        sp<AudioProfile> profile = new AudioProfile(formats[i],
+                dynamicFormatProfile->getChannels(),
+                dynamicFormatProfile->getSampleRates());
+        profile->setDynamicFormat(true);
+        profile->setDynamicChannels(dynamicFormatProfile->isDynamicChannels());
+        profile->setDynamicRate(dynamicFormatProfile->isDynamicRate());
+        add(profile);
+    }
+}
+
+void AudioProfileVector::dump(String8 *dst, int spaces) const
+{
+    dst->appendFormat("%*s- Profiles:\n", spaces, "");
+    for (size_t i = 0; i < size(); i++) {
+        dst->appendFormat("%*sProfile %zu:", spaces + 4, "", i);
+        itemAt(i)->dump(dst, spaces + 8);
+    }
+}
+
+sp<AudioProfile> AudioProfileVector::getProfileFor(audio_format_t format) const
+{
+    for (size_t i = 0; i < size(); i++) {
+        if (itemAt(i)->getFormat() == format) {
+            return itemAt(i);
+        }
+    }
+    return 0;
+}
+
+void AudioProfileVector::setSampleRatesFor(
+        const SampleRateVector &sampleRates, audio_format_t format)
+{
+    for (size_t i = 0; i < size(); i++) {
+        sp<AudioProfile> profile = itemAt(i);
+        if (profile->getFormat() == format && profile->isDynamicRate()) {
+            if (profile->hasValidRates()) {
+                // Need to create a new profile with same format
+                sp<AudioProfile> profileToAdd = new AudioProfile(format, profile->getChannels(),
+                        sampleRates);
+                profileToAdd->setDynamicFormat(true); // need to set to allow cleaning
+                add(profileToAdd);
+            } else {
+                profile->setSampleRates(sampleRates);
+            }
+            return;
+        }
+    }
+}
+
+void AudioProfileVector::setChannelsFor(const ChannelsVector &channelMasks, audio_format_t format)
+{
+    for (size_t i = 0; i < size(); i++) {
+        sp<AudioProfile> profile = itemAt(i);
+        if (profile->getFormat() == format && profile->isDynamicChannels()) {
+            if (profile->hasValidChannels()) {
+                // Need to create a new profile with same format
+                sp<AudioProfile> profileToAdd = new AudioProfile(format, channelMasks,
+                        profile->getSampleRates());
+                profileToAdd->setDynamicFormat(true); // need to set to allow cleaning
+                add(profileToAdd);
+            } else {
+                profile->setChannels(channelMasks);
+            }
+            return;
+        }
+    }
+}
+
+// static
 int AudioProfileVector::compareFormats(const sp<AudioProfile> *profile1,
                                        const sp<AudioProfile> *profile2)
 {
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp
index 79ad1f7..79f0919 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp
@@ -24,29 +24,32 @@
 namespace android
 {
 
-void AudioRoute::dump(int fd, int spaces) const
+void AudioRoute::dump(String8 *dst, int spaces) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "%*s- Type: %s\n", spaces, "", mType == AUDIO_ROUTE_MUX ? "Mux" : "Mix");
-    result.append(buffer);
-
-    snprintf(buffer, SIZE, "%*s- Sink: %s\n", spaces, "", mSink->getTagName().string());
-    result.append(buffer);
-
+    dst->appendFormat("%*s- Type: %s\n", spaces, "", mType == AUDIO_ROUTE_MUX ? "Mux" : "Mix");
+    dst->appendFormat("%*s- Sink: %s\n", spaces, "", mSink->getTagName().string());
     if (mSources.size() != 0) {
-        snprintf(buffer, SIZE, "%*s- Sources: \n", spaces, "");
-        result.append(buffer);
+        dst->appendFormat("%*s- Sources: \n", spaces, "");
         for (size_t i = 0; i < mSources.size(); i++) {
-            snprintf(buffer, SIZE, "%*s%s \n", spaces + 4, "", mSources[i]->getTagName().string());
-            result.append(buffer);
+            dst->appendFormat("%*s%s \n", spaces + 4, "", mSources[i]->getTagName().string());
         }
     }
-    result.append("\n");
+    dst->append("\n");
+}
 
-    write(fd, result.string(), result.size());
+bool AudioRoute::supportsPatch(const sp<AudioPort> &srcPort, const sp<AudioPort> &dstPort) const
+{
+    if (mSink == 0 || dstPort == 0 || dstPort != mSink) {
+        return false;
+    }
+    ALOGV("%s: sinks %s matching", __FUNCTION__, mSink->getTagName().string());
+    for (const auto &sourcePort : mSources) {
+        if (sourcePort == srcPort) {
+            ALOGV("%s: sources %s matching", __FUNCTION__, sourcePort->getTagName().string());
+            return true;
+        }
+    }
+    return false;
 }
 
 }
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
deleted file mode 100644
index 694c3f2..0000000
--- a/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "APM::AudioSession"
-//#define LOG_NDEBUG 0
-
-#include <AudioPolicyInterface.h>
-#include "policy.h"
-#include "AudioPolicyMix.h"
-#include "AudioSession.h"
-#include "AudioGain.h"
-#include "TypeConverter.h"
-
-#include <log/log.h>
-#include <utils/String8.h>
-
-namespace android {
-
-AudioSession::AudioSession(audio_session_t session,
-                           audio_source_t inputSource,
-                           audio_format_t format,
-                           uint32_t sampleRate,
-                           audio_channel_mask_t channelMask,
-                           audio_input_flags_t flags,
-                           uid_t uid,
-                           bool isSoundTrigger,
-                           const sp<AudioPolicyMix> &policyMix,
-                           AudioPolicyClientInterface *clientInterface) :
-    mRecordClientInfo({ .uid = uid, .session = session, .source = inputSource}),
-    mConfig({ .format = format, .sample_rate = sampleRate, .channel_mask = channelMask}),
-    mFlags(flags), mIsSoundTrigger(isSoundTrigger),
-    mOpenCount(1), mActiveCount(0), mPolicyMix(policyMix), mClientInterface(clientInterface),
-    mInfoProvider(NULL)
-{
-}
-
-uint32_t AudioSession::changeOpenCount(int delta)
-{
-    if ((delta + (int)mOpenCount) < 0) {
-        ALOGW("%s invalid delta %d, open count %d",
-              __FUNCTION__, delta, mOpenCount);
-        mOpenCount = (uint32_t)(-delta);
-    }
-    mOpenCount += delta;
-    ALOGV("%s open count %d", __FUNCTION__, mOpenCount);
-    return mOpenCount;
-}
-
-uint32_t AudioSession::changeActiveCount(int delta)
-{
-    const uint32_t oldActiveCount = mActiveCount;
-    if ((delta + (int)mActiveCount) < 0) {
-        ALOGW("%s invalid delta %d, active count %d",
-              __FUNCTION__, delta, mActiveCount);
-        mActiveCount = (uint32_t)(-delta);
-    }
-    mActiveCount += delta;
-    ALOGV("%s active count %d", __FUNCTION__, mActiveCount);
-    int event = RECORD_CONFIG_EVENT_NONE;
-
-    if ((oldActiveCount == 0) && (mActiveCount > 0)) {
-        event = RECORD_CONFIG_EVENT_START;
-    } else if ((oldActiveCount > 0) && (mActiveCount == 0)) {
-        event = RECORD_CONFIG_EVENT_STOP;
-    }
-
-    if (event != RECORD_CONFIG_EVENT_NONE) {
-        // Dynamic policy callback:
-        // if input maps to a dynamic policy with an activity listener, notify of state change
-        sp<AudioPolicyMix> policyMix = mPolicyMix.promote();
-        if ((policyMix != NULL) && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
-        {
-            mClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
-                    (event == RECORD_CONFIG_EVENT_START) ? MIX_STATE_MIXING : MIX_STATE_IDLE);
-        }
-
-        // Recording configuration callback:
-        const AudioSessionInfoProvider* provider = mInfoProvider;
-        const audio_config_base_t deviceConfig = (provider != NULL) ? provider->getConfig() :
-                AUDIO_CONFIG_BASE_INITIALIZER;
-        const audio_patch_handle_t patchHandle = (provider != NULL) ? provider->getPatchHandle() :
-                AUDIO_PATCH_HANDLE_NONE;
-        if (patchHandle != AUDIO_PATCH_HANDLE_NONE) {
-            mClientInterface->onRecordingConfigurationUpdate(event, &mRecordClientInfo,
-                    &mConfig, &deviceConfig, patchHandle);
-        }
-    }
-
-    return mActiveCount;
-}
-
-bool AudioSession::matches(const sp<AudioSession> &other) const
-{
-    if (other->session() == mRecordClientInfo.session &&
-        other->inputSource() == mRecordClientInfo.source &&
-        other->format() == mConfig.format &&
-        other->sampleRate() == mConfig.sample_rate &&
-        other->channelMask() == mConfig.channel_mask &&
-        other->flags() == mFlags &&
-        other->uid() == mRecordClientInfo.uid) {
-        return true;
-    }
-    return false;
-}
-
-void AudioSession::setInfoProvider(AudioSessionInfoProvider *provider)
-{
-    mInfoProvider = provider;
-}
-
-void AudioSession::onSessionInfoUpdate() const
-{
-    if (mActiveCount > 0) {
-        // resend the callback after requerying the informations from the info provider
-        const AudioSessionInfoProvider* provider = mInfoProvider;
-        const audio_config_base_t deviceConfig = (provider != NULL) ? provider->getConfig() :
-                AUDIO_CONFIG_BASE_INITIALIZER;
-        const audio_patch_handle_t patchHandle = (provider != NULL) ? provider->getPatchHandle() :
-                AUDIO_PATCH_HANDLE_NONE;
-        if (patchHandle != AUDIO_PATCH_HANDLE_NONE) {
-            mClientInterface->onRecordingConfigurationUpdate(RECORD_CONFIG_EVENT_START,
-                    &mRecordClientInfo, &mConfig, &deviceConfig, patchHandle);
-        }
-    }
-}
-
-status_t AudioSession::dump(int fd, int spaces, int index) const
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "%*sAudio session %d:\n", spaces, "", index+1);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- session: %2d\n", spaces, "", mRecordClientInfo.session);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- owner uid: %2d\n", spaces, "", mRecordClientInfo.uid);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- input source: %d\n", spaces, "", mRecordClientInfo.source);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- format: %08x\n", spaces, "", mConfig.format);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- sample: %d\n", spaces, "", mConfig.sample_rate);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- channel mask: %08x\n",
-             spaces, "", mConfig.channel_mask);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- is soundtrigger: %s\n",
-             spaces, "", mIsSoundTrigger ? "true" : "false");
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- open count: %d\n", spaces, "", mOpenCount);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- active count: %d\n", spaces, "", mActiveCount);
-    result.append(buffer);
-
-    write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
-
-status_t AudioSessionCollection::addSession(audio_session_t session,
-                                         const sp<AudioSession>& audioSession,
-                                         AudioSessionInfoProvider *provider)
-{
-    ssize_t index = indexOfKey(session);
-
-    if (index >= 0) {
-        ALOGW("addSession() session %d already in", session);
-        return ALREADY_EXISTS;
-    }
-    audioSession->setInfoProvider(provider);
-    add(session, audioSession);
-    ALOGV("addSession() session %d  client %d source %d",
-            session, audioSession->uid(), audioSession->inputSource());
-    return NO_ERROR;
-}
-
-status_t AudioSessionCollection::removeSession(audio_session_t session)
-{
-    ssize_t index = indexOfKey(session);
-
-    if (index < 0) {
-        ALOGW("removeSession() session %d not in", session);
-        return ALREADY_EXISTS;
-    }
-    ALOGV("removeSession() session %d", session);
-    valueAt(index)->setInfoProvider(NULL);
-    removeItemsAt(index);
-    return NO_ERROR;
-}
-
-uint32_t AudioSessionCollection::getOpenCount() const
-{
-    uint32_t openCount = 0;
-    for (size_t i = 0; i < size(); i++) {
-        openCount += valueAt(i)->openCount();
-    }
-    return openCount;
-}
-
-AudioSessionCollection AudioSessionCollection::getActiveSessions() const
-{
-    AudioSessionCollection activeSessions;
-    for (size_t i = 0; i < size(); i++) {
-        if (valueAt(i)->activeCount() != 0) {
-            activeSessions.add(valueAt(i)->session(), valueAt(i));
-        }
-    }
-    return activeSessions;
-}
-
-size_t AudioSessionCollection::getActiveSessionCount() const
-{
-    size_t activeCount = 0;
-    for (size_t i = 0; i < size(); i++) {
-        if (valueAt(i)->activeCount() != 0) {
-            activeCount++;
-        }
-    }
-    return activeCount;
-}
-
-bool AudioSessionCollection::hasActiveSession() const
-{
-    return getActiveSessionCount() != 0;
-}
-
-bool AudioSessionCollection::isSourceActive(audio_source_t source) const
-{
-    for (size_t i = 0; i < size(); i++) {
-        const sp<AudioSession>  audioSession = valueAt(i);
-        // AUDIO_SOURCE_HOTWORD is equivalent to AUDIO_SOURCE_VOICE_RECOGNITION only if it
-        // corresponds to an active capture triggered by a hardware hotword recognition
-        if (audioSession->activeCount() > 0 &&
-                ((audioSession->inputSource() == source) ||
-                ((source == AUDIO_SOURCE_VOICE_RECOGNITION) &&
-                 (audioSession->inputSource() == AUDIO_SOURCE_HOTWORD) &&
-                 audioSession->isSoundTrigger()))) {
-            return true;
-        }
-    }
-    return false;
-}
-
-audio_source_t AudioSessionCollection::getHighestPrioritySource(bool activeOnly) const
-{
-    audio_source_t source = AUDIO_SOURCE_DEFAULT;
-    int32_t priority = -1;
-
-    for (size_t i = 0; i < size(); i++) {
-        const sp<AudioSession>  audioSession = valueAt(i);
-        if (activeOnly && audioSession->activeCount() == 0) {
-            continue;
-        }
-        int32_t curPriority = source_priority(audioSession->inputSource());
-        if (curPriority > priority) {
-            priority = curPriority;
-            source = audioSession->inputSource();
-        }
-    }
-    return source;
-}
-
-void AudioSessionCollection::onSessionInfoUpdate() const
-{
-    for (size_t i = 0; i < size(); i++) {
-        valueAt(i)->onSessionInfoUpdate();
-    }
-}
-
-status_t AudioSessionCollection::dump(int fd, int spaces) const
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    snprintf(buffer, SIZE, "%*sAudio Sessions:\n", spaces, "");
-    write(fd, buffer, strlen(buffer));
-    for (size_t i = 0; i < size(); i++) {
-        valueAt(i)->dump(fd, spaces + 2, i);
-    }
-    return NO_ERROR;
-}
-
-} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioSourceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioSourceDescriptor.cpp
deleted file mode 100644
index ba33e57..0000000
--- a/services/audiopolicy/common/managerdefinitions/src/AudioSourceDescriptor.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "APM::AudioSourceDescriptor"
-//#define LOG_NDEBUG 0
-
-#include <utils/Log.h>
-#include <utils/String8.h>
-#include <media/AudioPolicyHelper.h>
-#include <HwModule.h>
-#include <AudioGain.h>
-#include <AudioSourceDescriptor.h>
-#include <DeviceDescriptor.h>
-#include <IOProfile.h>
-#include <AudioOutputDescriptor.h>
-
-namespace android {
-
-status_t AudioSourceDescriptor::dump(int fd)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "mStream: %d\n", audio_attributes_to_stream_type(&mAttributes));
-    result.append(buffer);
-    snprintf(buffer, SIZE, "mDevice:\n");
-    result.append(buffer);
-    write(fd, result.string(), result.size());
-    mDevice->dump(fd, 2 , 0);
-    return NO_ERROR;
-}
-
-
-status_t AudioSourceCollection::dump(int fd) const
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE, "\nAudio sources dump:\n");
-    write(fd, buffer, strlen(buffer));
-    for (size_t i = 0; i < size(); i++) {
-        snprintf(buffer, SIZE, "- Source %d dump:\n", keyAt(i));
-        write(fd, buffer, strlen(buffer));
-        valueAt(i)->dump(fd);
-    }
-
-    return NO_ERROR;
-}
-
-}; //namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
new file mode 100644
index 0000000..ad07ab1
--- /dev/null
+++ b/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "APM_ClientDescriptor"
+//#define LOG_NDEBUG 0
+
+#include <sstream>
+#include <utils/Log.h>
+#include <utils/String8.h>
+#include <TypeConverter.h>
+#include "AudioGain.h"
+#include "AudioOutputDescriptor.h"
+#include "AudioPatch.h"
+#include "ClientDescriptor.h"
+#include "DeviceDescriptor.h"
+#include "HwModule.h"
+#include "IOProfile.h"
+
+namespace android {
+
+std::string ClientDescriptor::toShortString() const
+{
+    std::stringstream ss;
+
+    ss << "PortId: " << mPortId << " SessionId: " << mSessionId << " Uid: " << mUid;
+    return ss.str();
+}
+
+void ClientDescriptor::dump(String8 *dst, int spaces, int index) const
+{
+    dst->appendFormat("%*sClient %d:\n", spaces, "", index+1);
+    dst->appendFormat("%*s- Port Id: %d Session Id: %d UID: %d\n", spaces, "",
+             mPortId, mSessionId, mUid);
+    dst->appendFormat("%*s- Format: %08x Sampling rate: %d Channels: %08x\n", spaces, "",
+             mConfig.format, mConfig.sample_rate, mConfig.channel_mask);
+    dst->appendFormat("%*s- Attributes: %s\n", spaces, "", toString(mAttributes).c_str());
+    dst->appendFormat("%*s- Preferred Device Id: %08x\n", spaces, "", mPreferredDeviceId);
+    dst->appendFormat("%*s- State: %s\n", spaces, "", mActive ? "Active" : "Inactive");
+}
+
+void TrackClientDescriptor::dump(String8 *dst, int spaces, int index) const
+{
+    ClientDescriptor::dump(dst, spaces, index);
+    dst->appendFormat("%*s- Stream: %d flags: %08x\n", spaces, "", mStream, mFlags);
+    dst->appendFormat("%*s- Refcount: %d\n", spaces, "", mActivityCount);
+}
+
+std::string TrackClientDescriptor::toShortString() const
+{
+    std::stringstream ss;
+
+    ss << ClientDescriptor::toShortString() << " Stream: " << mStream;
+    return ss.str();
+}
+
+void RecordClientDescriptor::trackEffectEnabled(const sp<EffectDescriptor> &effect, bool enabled)
+{
+    if (enabled) {
+        mEnabledEffects.replaceValueFor(effect->mId, effect);
+    } else {
+        mEnabledEffects.removeItem(effect->mId);
+    }
+}
+
+void RecordClientDescriptor::dump(String8 *dst, int spaces, int index) const
+{
+    ClientDescriptor::dump(dst, spaces, index);
+    dst->appendFormat("%*s- Source: %d flags: %08x\n", spaces, "", mSource, mFlags);
+    mEnabledEffects.dump(dst, spaces + 2 /*spaces*/, false /*verbose*/);
+}
+
+SourceClientDescriptor::SourceClientDescriptor(audio_port_handle_t portId, uid_t uid,
+         audio_attributes_t attributes, const sp<AudioPatch>& patchDesc,
+         const sp<DeviceDescriptor>& srcDevice, audio_stream_type_t stream,
+         product_strategy_t strategy, VolumeSource volumeSource) :
+    TrackClientDescriptor::TrackClientDescriptor(portId, uid, AUDIO_SESSION_NONE, attributes,
+        AUDIO_CONFIG_BASE_INITIALIZER, AUDIO_PORT_HANDLE_NONE,
+        stream, strategy, volumeSource, AUDIO_OUTPUT_FLAG_NONE, false,
+        {} /* Sources do not support secondary outputs*/),
+        mPatchDesc(patchDesc), mSrcDevice(srcDevice)
+{
+}
+
+void SourceClientDescriptor::setSwOutput(const sp<SwAudioOutputDescriptor>& swOutput)
+{
+    mSwOutput = swOutput;
+}
+
+void SourceClientDescriptor::setHwOutput(const sp<HwAudioOutputDescriptor>& hwOutput)
+{
+    mHwOutput = hwOutput;
+}
+
+void SourceClientDescriptor::dump(String8 *dst, int spaces, int index) const
+{
+    TrackClientDescriptor::dump(dst, spaces, index);
+    dst->appendFormat("%*s- Device:\n", spaces, "");
+    mSrcDevice->dump(dst, 2, 0);
+}
+
+void SourceClientCollection::dump(String8 *dst) const
+{
+    dst->append("\nAudio sources:\n");
+    for (size_t i = 0; i < size(); i++) {
+        valueAt(i)->dump(dst, 2, i);
+    }
+}
+
+}; //namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/ConfigParsingUtils.cpp b/services/audiopolicy/common/managerdefinitions/src/ConfigParsingUtils.cpp
deleted file mode 100644
index 1e105f5..0000000
--- a/services/audiopolicy/common/managerdefinitions/src/ConfigParsingUtils.cpp
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "APM::ConfigParsingUtils"
-//#define LOG_NDEBUG 0
-
-#include "ConfigParsingUtils.h"
-#include "AudioGain.h"
-#include "IOProfile.h"
-#include <system/audio.h>
-#include <media/AudioParameter.h>
-#include <media/TypeConverter.h>
-#include <utils/Log.h>
-#include <cutils/misc.h>
-
-namespace android {
-
-// --- audio_policy.conf file parsing
-
-//static
-void ConfigParsingUtils::loadAudioPortGain(cnode *root, AudioPort &audioPort, int index)
-{
-    cnode *node = root->first_child;
-
-    sp<AudioGain> gain = new AudioGain(index, audioPort.useInputChannelMask());
-
-    while (node) {
-        if (strcmp(node->name, GAIN_MODE) == 0) {
-            gain->setMode(GainModeConverter::maskFromString(node->value));
-        } else if (strcmp(node->name, GAIN_CHANNELS) == 0) {
-            audio_channel_mask_t mask;
-            if (audioPort.useInputChannelMask()) {
-                if (InputChannelConverter::fromString(node->value, mask)) {
-                    gain->setChannelMask(mask);
-                }
-            } else {
-                if (OutputChannelConverter::fromString(node->value, mask)) {
-                    gain->setChannelMask(mask);
-                }
-            }
-        } else if (strcmp(node->name, GAIN_MIN_VALUE) == 0) {
-            gain->setMinValueInMb(atoi(node->value));
-        } else if (strcmp(node->name, GAIN_MAX_VALUE) == 0) {
-            gain->setMaxValueInMb(atoi(node->value));
-        } else if (strcmp(node->name, GAIN_DEFAULT_VALUE) == 0) {
-            gain->setDefaultValueInMb(atoi(node->value));
-        } else if (strcmp(node->name, GAIN_STEP_VALUE) == 0) {
-            gain->setStepValueInMb(atoi(node->value));
-        } else if (strcmp(node->name, GAIN_MIN_RAMP_MS) == 0) {
-            gain->setMinRampInMs(atoi(node->value));
-        } else if (strcmp(node->name, GAIN_MAX_RAMP_MS) == 0) {
-            gain->setMaxRampInMs(atoi(node->value));
-        }
-        node = node->next;
-    }
-
-    ALOGV("loadGain() adding new gain mode %08x channel mask %08x min mB %d max mB %d",
-          gain->getMode(), gain->getChannelMask(), gain->getMinValueInMb(),
-          gain->getMaxValueInMb());
-
-    if (gain->getMode() == 0) {
-        return;
-    }
-    audioPort.mGains.add(gain);
-}
-
-void ConfigParsingUtils::loadAudioPortGains(cnode *root, AudioPort &audioPort)
-{
-    cnode *node = root->first_child;
-    int index = 0;
-    while (node) {
-        ALOGV("loadGains() loading gain %s", node->name);
-        loadAudioPortGain(node, audioPort, index++);
-        node = node->next;
-    }
-}
-
-//static
-void ConfigParsingUtils::loadDeviceDescriptorGains(cnode *root, sp<DeviceDescriptor> &deviceDesc)
-{
-    loadAudioPortGains(root, *deviceDesc);
-    if (deviceDesc->mGains.size() > 0) {
-        deviceDesc->mGains[0]->getDefaultConfig(&deviceDesc->mGain);
-    }
-}
-
-//static
-status_t ConfigParsingUtils::loadHwModuleDevice(cnode *root, DeviceVector &devices)
-{
-    cnode *node = root->first_child;
-
-    audio_devices_t type = AUDIO_DEVICE_NONE;
-    while (node) {
-        if (strcmp(node->name, APM_DEVICE_TYPE) == 0) {
-            deviceFromString(node->value, type);
-            break;
-        }
-        node = node->next;
-    }
-    if (type == AUDIO_DEVICE_NONE ||
-            (!audio_is_input_device(type) && !audio_is_output_device(type))) {
-        ALOGW("loadDevice() bad type %08x", type);
-        return BAD_VALUE;
-    }
-    sp<DeviceDescriptor> deviceDesc = new DeviceDescriptor(type, String8(root->name));
-
-    node = root->first_child;
-    while (node) {
-        if (strcmp(node->name, APM_DEVICE_ADDRESS) == 0) {
-            deviceDesc->mAddress = String8((char *)node->value);
-        } else if (strcmp(node->name, CHANNELS_TAG) == 0) {
-            if (audio_is_input_device(type)) {
-                deviceDesc->addAudioProfile(
-                        new AudioProfile(gDynamicFormat,
-                                         inputChannelMasksFromString(node->value),
-                                         SampleRateVector()));
-            } else {
-                deviceDesc->addAudioProfile(
-                        new AudioProfile(gDynamicFormat,
-                                         outputChannelMasksFromString(node->value),
-                                         SampleRateVector()));
-            }
-        } else if (strcmp(node->name, GAINS_TAG) == 0) {
-            loadDeviceDescriptorGains(node, deviceDesc);
-        }
-        node = node->next;
-    }
-
-    ALOGV("loadDevice() adding device tag (literal type) %s type %08x address %s",
-          deviceDesc->getTagName().string(), type, deviceDesc->mAddress.string());
-
-    devices.add(deviceDesc);
-    return NO_ERROR;
-}
-
-//static
-status_t ConfigParsingUtils::loadHwModuleProfile(cnode *root, sp<HwModule> &module,
-                                                 audio_port_role_t role)
-{
-    cnode *node = root->first_child;
-
-    sp<IOProfile> profile = new IOProfile(String8(root->name), role);
-
-    AudioProfileVector audioProfiles;
-    SampleRateVector sampleRates;
-    ChannelsVector channels;
-    FormatVector formats;
-
-    while (node) {
-        if (strcmp(node->name, FORMATS_TAG) == 0 &&
-                strcmp(node->value, DYNAMIC_VALUE_TAG) != 0) {
-            formats = formatsFromString(node->value);
-        } else if (strcmp(node->name, SAMPLING_RATES_TAG) == 0 &&
-                  strcmp(node->value, DYNAMIC_VALUE_TAG) != 0) {
-            collectionFromString<SampleRateTraits>(node->value, sampleRates);
-        } else if (strcmp(node->name, CHANNELS_TAG) == 0 &&
-                   strcmp(node->value, DYNAMIC_VALUE_TAG) != 0) {
-            if (role == AUDIO_PORT_ROLE_SINK) {
-                channels = inputChannelMasksFromString(node->value);
-            } else {
-                channels = outputChannelMasksFromString(node->value);
-            }
-        } else if (strcmp(node->name, DEVICES_TAG) == 0) {
-            DeviceVector devices;
-            loadDevicesFromTag(node->value, devices, module->getDeclaredDevices());
-            profile->setSupportedDevices(devices);
-        } else if (strcmp(node->name, FLAGS_TAG) == 0) {
-            if (role == AUDIO_PORT_ROLE_SINK) {
-                profile->setFlags(InputFlagConverter::maskFromString(node->value));
-            } else {
-                profile->setFlags(OutputFlagConverter::maskFromString(node->value));
-            }
-        } else if (strcmp(node->name, GAINS_TAG) == 0) {
-            loadAudioPortGains(node, *profile);
-        }
-        node = node->next;
-    }
-    if (formats.isEmpty()) {
-        sp<AudioProfile> profileToAdd = new AudioProfile(gDynamicFormat, channels, sampleRates);
-        profileToAdd->setDynamicFormat(true);
-        profileToAdd->setDynamicChannels(channels.isEmpty());
-        profileToAdd->setDynamicRate(sampleRates.isEmpty());
-        audioProfiles.add(profileToAdd);
-    } else {
-        for (size_t i = 0; i < formats.size(); i++) {
-            // For compatibility reason, for each format, creates a profile with the same
-            // collection of rate and channels.
-            sp<AudioProfile> profileToAdd = new AudioProfile(formats[i], channels, sampleRates);
-            profileToAdd->setDynamicFormat(formats[i] == gDynamicFormat);
-            profileToAdd->setDynamicChannels(channels.isEmpty());
-            profileToAdd->setDynamicRate(sampleRates.isEmpty());
-            audioProfiles.add(profileToAdd);
-        }
-    }
-    profile->setAudioProfiles(audioProfiles);
-    ALOGW_IF(!profile->hasSupportedDevices(), "load%s() invalid supported devices",
-             role == AUDIO_PORT_ROLE_SINK ? "Input" : "Output");
-    if (profile->hasSupportedDevices()) {
-        ALOGV("load%s() adding Supported Devices %04x, mFlags %04x",
-              role == AUDIO_PORT_ROLE_SINK ? "Input" : "Output",
-              profile->getSupportedDevicesType(), profile->getFlags());
-        return module->addProfile(profile);
-    }
-    return BAD_VALUE;
-}
-
-//static
-status_t ConfigParsingUtils::loadHwModule(cnode *root, sp<HwModule> &module,
-                                          AudioPolicyConfig &config)
-{
-    status_t status = NAME_NOT_FOUND;
-    cnode *node = config_find(root, DEVICES_TAG);
-    if (node != NULL) {
-        node = node->first_child;
-        DeviceVector devices;
-        while (node) {
-            ALOGV("loadHwModule() loading device %s", node->name);
-            status_t tmpStatus = loadHwModuleDevice(node, devices);
-            if (status == NAME_NOT_FOUND || status == NO_ERROR) {
-                status = tmpStatus;
-            }
-            node = node->next;
-        }
-        module->setDeclaredDevices(devices);
-    }
-    node = config_find(root, OUTPUTS_TAG);
-    if (node != NULL) {
-        node = node->first_child;
-        while (node) {
-            ALOGV("loadHwModule() loading output %s", node->name);
-            status_t tmpStatus = loadHwModuleProfile(node, module, AUDIO_PORT_ROLE_SOURCE);
-            if (status == NAME_NOT_FOUND || status == NO_ERROR) {
-                status = tmpStatus;
-            }
-            node = node->next;
-        }
-    }
-    node = config_find(root, INPUTS_TAG);
-    if (node != NULL) {
-        node = node->first_child;
-        while (node) {
-            ALOGV("loadHwModule() loading input %s", node->name);
-            status_t tmpStatus = loadHwModuleProfile(node, module, AUDIO_PORT_ROLE_SINK);
-            if (status == NAME_NOT_FOUND || status == NO_ERROR) {
-                status = tmpStatus;
-            }
-            node = node->next;
-        }
-    }
-    loadModuleGlobalConfig(root, module, config);
-    return status;
-}
-
-//static
-void ConfigParsingUtils::loadHwModules(cnode *root, HwModuleCollection &hwModules,
-                                       AudioPolicyConfig &config)
-{
-    cnode *node = config_find(root, AUDIO_HW_MODULE_TAG);
-    if (node == NULL) {
-        return;
-    }
-
-    node = node->first_child;
-    while (node) {
-        ALOGV("loadHwModules() loading module %s", node->name);
-        sp<HwModule> module = new HwModule(node->name);
-        if (loadHwModule(node, module, config) == NO_ERROR) {
-            hwModules.add(module);
-        }
-        node = node->next;
-    }
-}
-
-//static
-void ConfigParsingUtils::loadDevicesFromTag(const char *tag, DeviceVector &devices,
-                                            const DeviceVector &declaredDevices)
-{
-    char *tagLiteral = strndup(tag, strlen(tag));
-    char *devTag = strtok(tagLiteral, AudioParameter::valueListSeparator);
-    while (devTag != NULL) {
-        if (strlen(devTag) != 0) {
-            audio_devices_t type;
-            if (deviceFromString(devTag, type)) {
-                uint32_t inBit = type & AUDIO_DEVICE_BIT_IN;
-                type &= ~AUDIO_DEVICE_BIT_IN;
-                while (type) {
-                  audio_devices_t singleType =
-                        inBit | (1 << (31 - __builtin_clz(type)));
-                    type &= ~singleType;
-                    sp<DeviceDescriptor> dev = new DeviceDescriptor(singleType);
-                    devices.add(dev);
-                }
-            } else {
-                sp<DeviceDescriptor> deviceDesc =
-                        declaredDevices.getDeviceFromTagName(String8(devTag));
-                if (deviceDesc != 0) {
-                    devices.add(deviceDesc);
-                }
-            }
-        }
-        devTag = strtok(NULL, AudioParameter::valueListSeparator);
-    }
-    free(tagLiteral);
-}
-
-//static
-void ConfigParsingUtils::loadModuleGlobalConfig(cnode *root, const sp<HwModule> &module,
-                                                AudioPolicyConfig &config)
-{
-    cnode *node = config_find(root, GLOBAL_CONFIG_TAG);
-
-    if (node == NULL) {
-        return;
-    }
-    DeviceVector declaredDevices;
-    if (module != NULL) {
-        declaredDevices = module->getDeclaredDevices();
-    }
-
-    node = node->first_child;
-    while (node) {
-        if (strcmp(ATTACHED_OUTPUT_DEVICES_TAG, node->name) == 0) {
-            DeviceVector availableOutputDevices;
-            loadDevicesFromTag(node->value, availableOutputDevices, declaredDevices);
-            ALOGV("loadGlobalConfig() Attached Output Devices %08x",
-                  availableOutputDevices.types());
-            config.addAvailableOutputDevices(availableOutputDevices);
-        } else if (strcmp(DEFAULT_OUTPUT_DEVICE_TAG, node->name) == 0) {
-            audio_devices_t device = AUDIO_DEVICE_NONE;
-            deviceFromString(node->value, device);
-            if (device != AUDIO_DEVICE_NONE) {
-                sp<DeviceDescriptor> defaultOutputDevice = new DeviceDescriptor(device);
-                config.setDefaultOutputDevice(defaultOutputDevice);
-                ALOGV("loadGlobalConfig() mDefaultOutputDevice %08x", defaultOutputDevice->type());
-            } else {
-                ALOGW("loadGlobalConfig() default device not specified");
-            }
-        } else if (strcmp(ATTACHED_INPUT_DEVICES_TAG, node->name) == 0) {
-            DeviceVector availableInputDevices;
-            loadDevicesFromTag(node->value, availableInputDevices, declaredDevices);
-            ALOGV("loadGlobalConfig() Available InputDevices %08x", availableInputDevices.types());
-            config.addAvailableInputDevices(availableInputDevices);
-        } else if (strcmp(AUDIO_HAL_VERSION_TAG, node->name) == 0) {
-            uint32_t major, minor;
-            sscanf((char *)node->value, "%u.%u", &major, &minor);
-            module->setHalVersion(major, minor);
-            ALOGV("loadGlobalConfig() mHalVersion = major %u minor %u", major, minor);
-        }
-        node = node->next;
-    }
-}
-
-//static
-void ConfigParsingUtils::loadGlobalConfig(cnode *root, AudioPolicyConfig &config,
-                                          const sp<HwModule>& primaryModule)
-{
-    cnode *node = config_find(root, GLOBAL_CONFIG_TAG);
-
-    if (node == NULL) {
-        return;
-    }
-    node = node->first_child;
-    while (node) {
-        if (strcmp(SPEAKER_DRC_ENABLED_TAG, node->name) == 0) {
-            bool speakerDrcEnabled;
-            if (utilities::convertTo<std::string, bool>(node->value, speakerDrcEnabled)) {
-                ALOGV("loadGlobalConfig() mSpeakerDrcEnabled = %d", speakerDrcEnabled);
-                config.setSpeakerDrcEnabled(speakerDrcEnabled);
-            }
-        }
-        node = node->next;
-    }
-    loadModuleGlobalConfig(root, primaryModule, config);
-}
-
-//static
-status_t ConfigParsingUtils::loadConfig(const char *path, AudioPolicyConfig &config)
-{
-    cnode *root;
-    char *data;
-
-    data = (char *)load_file(path, NULL);
-    if (data == NULL) {
-        return -ENODEV;
-    }
-    root = config_node("", "");
-    config_load(root, data);
-
-    HwModuleCollection hwModules;
-    loadHwModules(root, hwModules, config);
-
-    // legacy audio_policy.conf files have one global_configuration section, attached to primary.
-    loadGlobalConfig(root, config, hwModules.getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY));
-
-    config.setHwModules(hwModules);
-
-    config_free(root);
-    free(root);
-    free(data);
-
-    ALOGI("loadAudioPolicyConfig() loaded %s\n", path);
-
-    return NO_ERROR;
-}
-
-} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index 19c2062..ecd5b34 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -18,6 +18,8 @@
 //#define LOG_NDEBUG 0
 
 #include <audio_utils/string.h>
+#include <media/TypeConverter.h>
+#include <set>
 #include "DeviceDescriptor.h"
 #include "TypeConverter.h"
 #include "AudioGain.h"
@@ -26,14 +28,30 @@
 namespace android {
 
 DeviceDescriptor::DeviceDescriptor(audio_devices_t type, const String8 &tagName) :
+        DeviceDescriptor(type, FormatVector{}, tagName)
+{
+}
+
+DeviceDescriptor::DeviceDescriptor(audio_devices_t type, const FormatVector &encodedFormats,
+        const String8 &tagName) :
     AudioPort(String8(""), AUDIO_PORT_TYPE_DEVICE,
               audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK :
                                              AUDIO_PORT_ROLE_SOURCE),
-    mAddress(""), mTagName(tagName), mDeviceType(type), mId(0)
+    mTagName(tagName), mDeviceType(type), mEncodedFormats(encodedFormats)
 {
-    if (type == AUDIO_DEVICE_IN_REMOTE_SUBMIX || type == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ) {
+    mCurrentEncodedFormat = AUDIO_FORMAT_DEFAULT;
+    if (audio_is_remote_submix_device(type)) {
         mAddress = String8("0");
     }
+    /* If framework runs against a pre 5.0 Audio HAL, encoded formats are absent from the config.
+     * FIXME: APM should know the version of the HAL and don't add the formats for V5.0.
+     * For now, the workaround to remove AC3 and IEC61937 support on HDMI is to declare
+     * something like 'encodedFormats="AUDIO_FORMAT_PCM_16_BIT"' on the HDMI devicePort.
+     */
+    if (type == AUDIO_DEVICE_OUT_HDMI && mEncodedFormats.isEmpty()) {
+        mEncodedFormats.add(AUDIO_FORMAT_AC3);
+        mEncodedFormats.add(AUDIO_FORMAT_IEC61937);
+    }
 }
 
 audio_port_handle_t DeviceDescriptor::getId() const
@@ -47,15 +65,57 @@
     mId = getNextUniqueId();
 }
 
+void DeviceDescriptor::detach() {
+    mId = AUDIO_PORT_HANDLE_NONE;
+    AudioPort::detach();
+}
+
+template<typename T>
+bool checkEqual(const T& f1, const T& f2)
+{
+    std::set<typename T::value_type> s1(f1.begin(), f1.end());
+    std::set<typename T::value_type> s2(f2.begin(), f2.end());
+    return s1 == s2;
+}
+
 bool DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const
 {
     // Devices are considered equal if they:
     // - are of the same type (a device type cannot be AUDIO_DEVICE_NONE)
     // - have the same address
+    // - have the same encodingFormats (if device supports encoding)
     if (other == 0) {
         return false;
     }
-    return (mDeviceType == other->mDeviceType) && (mAddress == other->mAddress);
+
+    return (mDeviceType == other->mDeviceType) && (mAddress == other->mAddress) &&
+           checkEqual(mEncodedFormats, other->mEncodedFormats);
+}
+
+bool DeviceDescriptor::hasCurrentEncodedFormat() const
+{
+    if (!device_has_encoding_capability(type())) {
+        return true;
+    }
+    if (mEncodedFormats.isEmpty()) {
+        return true;
+    }
+
+    return (mCurrentEncodedFormat != AUDIO_FORMAT_DEFAULT);
+}
+
+bool DeviceDescriptor::supportsFormat(audio_format_t format)
+{
+    if (mEncodedFormats.isEmpty()) {
+        return true;
+    }
+
+    for (const auto& devFormat : mEncodedFormats) {
+        if (devFormat == format) {
+            return true;
+        }
+    }
+    return false;
 }
 
 void DeviceVector::refreshTypes()
@@ -70,7 +130,7 @@
 ssize_t DeviceVector::indexOf(const sp<DeviceDescriptor>& item) const
 {
     for (size_t i = 0; i < size(); i++) {
-        if (item->equals(itemAt(i))) {
+        if (itemAt(i)->equals(item)) { // item may be null sp<>, i.e. AUDIO_DEVICE_NONE
             return i;
         }
     }
@@ -121,70 +181,84 @@
     return ret;
 }
 
-audio_devices_t DeviceVector::getDevicesFromHwModule(audio_module_handle_t moduleHandle) const
+void DeviceVector::remove(const DeviceVector &devices)
 {
-    audio_devices_t devices = AUDIO_DEVICE_NONE;
-    for (size_t i = 0; i < size(); i++) {
-        if (itemAt(i)->getModuleHandle() == moduleHandle) {
-            devices |= itemAt(i)->type();
+    for (const auto& device : devices) {
+        remove(device);
+    }
+}
+
+DeviceVector DeviceVector::getDevicesFromHwModule(audio_module_handle_t moduleHandle) const
+{
+    DeviceVector devices;
+    for (const auto& device : *this) {
+        if (device->getModuleHandle() == moduleHandle) {
+            devices.add(device);
         }
     }
     return devices;
 }
 
-sp<DeviceDescriptor> DeviceVector::getDevice(audio_devices_t type, const String8& address) const
+audio_devices_t DeviceVector::getDeviceTypesFromHwModule(audio_module_handle_t moduleHandle) const
+{
+    audio_devices_t deviceTypes = AUDIO_DEVICE_NONE;
+    for (const auto& device : *this) {
+        if (device->getModuleHandle() == moduleHandle) {
+            deviceTypes |= device->type();
+        }
+    }
+    return deviceTypes;
+}
+
+sp<DeviceDescriptor> DeviceVector::getDevice(audio_devices_t type, const String8& address,
+                                             audio_format_t format) const
 {
     sp<DeviceDescriptor> device;
     for (size_t i = 0; i < size(); i++) {
         if (itemAt(i)->type() == type) {
-            if (address == "" || itemAt(i)->mAddress == address) {
+            // If format is specified, match it and ignore address
+            // Otherwise if address is specified match it
+            // Otherwise always match
+            if (((address == "" || itemAt(i)->address() == address) &&
+                 format == AUDIO_FORMAT_DEFAULT) ||
+                (itemAt(i)->supportsFormat(format) && format != AUDIO_FORMAT_DEFAULT)) {
                 device = itemAt(i);
-                if (itemAt(i)->mAddress == address) {
+                if (itemAt(i)->address() == address) {
                     break;
                 }
             }
         }
     }
-    ALOGV("DeviceVector::getDevice() for type %08x address %s found %p",
-          type, address.string(), device.get());
+    ALOGV("DeviceVector::%s() for type %08x address \"%s\" found %p format %08x",
+            __func__, type, address.string(), device.get(), format);
     return device;
 }
 
 sp<DeviceDescriptor> DeviceVector::getDeviceFromId(audio_port_handle_t id) const
 {
-    for (const auto& device : *this) {
-        if (device->getId() == id) {
-            return device;
+    if (id != AUDIO_PORT_HANDLE_NONE) {
+        for (const auto& device : *this) {
+            if (device->getId() == id) {
+                return device;
+            }
         }
     }
     return nullptr;
 }
 
-DeviceVector DeviceVector::getDevicesFromType(audio_devices_t type) const
+DeviceVector DeviceVector::getDevicesFromTypeMask(audio_devices_t type) const
 {
     DeviceVector devices;
     bool isOutput = audio_is_output_devices(type);
     type &= ~AUDIO_DEVICE_BIT_IN;
     for (size_t i = 0; (i < size()) && (type != AUDIO_DEVICE_NONE); i++) {
-        bool curIsOutput = audio_is_output_devices(itemAt(i)->mDeviceType);
-        audio_devices_t curType = itemAt(i)->mDeviceType & ~AUDIO_DEVICE_BIT_IN;
+        bool curIsOutput = audio_is_output_devices(itemAt(i)->type());
+        audio_devices_t curType = itemAt(i)->type() & ~AUDIO_DEVICE_BIT_IN;
         if ((isOutput == curIsOutput) && ((type & curType) != 0)) {
             devices.add(itemAt(i));
             type &= ~curType;
-            ALOGV("DeviceVector::getDevicesFromType() for type %x found %p",
-                  itemAt(i)->type(), itemAt(i).get());
-        }
-    }
-    return devices;
-}
-
-DeviceVector DeviceVector::getDevicesFromTypeAddr(
-        audio_devices_t type, const String8& address) const
-{
-    DeviceVector devices;
-    for (const auto& device : *this) {
-        if (device->type() == type && device->mAddress == address) {
-            devices.add(device);
+            ALOGV("DeviceVector::%s() for type %08x found %p",
+                    __func__, itemAt(i)->type(), itemAt(i).get());
         }
     }
     return devices;
@@ -200,20 +274,15 @@
     return nullptr;
 }
 
-status_t DeviceVector::dump(int fd, const String8 &tag, int spaces, bool verbose) const
+void DeviceVector::dump(String8 *dst, const String8 &tag, int spaces, bool verbose) const
 {
     if (isEmpty()) {
-        return NO_ERROR;
+        return;
     }
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE, "%*s- %s devices:\n", spaces, "", tag.string());
-    write(fd, buffer, strlen(buffer));
+    dst->appendFormat("%*s- %s devices:\n", spaces, "", tag.string());
     for (size_t i = 0; i < size(); i++) {
-        itemAt(i)->dump(fd, spaces + 2, i, verbose);
+        itemAt(i)->dump(dst, spaces + 2, i, verbose);
     }
-    return NO_ERROR;
 }
 
 void DeviceDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
@@ -246,19 +315,18 @@
     // without the test?
     // This has been demonstrated to NOT be true (at start up)
     // ALOG_ASSERT(mModule != NULL);
-    dstConfig->ext.device.hw_module =
-            mModule != 0 ? mModule->getHandle() : AUDIO_MODULE_HANDLE_NONE;
+    dstConfig->ext.device.hw_module = getModuleHandle();
     (void)audio_utils_strlcpy_zerofill(dstConfig->ext.device.address, mAddress.string());
 }
 
 void DeviceDescriptor::toAudioPort(struct audio_port *port) const
 {
-    ALOGV("DeviceDescriptor::toAudioPort() handle %d type %x", mId, mDeviceType);
+    ALOGV("DeviceDescriptor::toAudioPort() handle %d type %08x", mId, mDeviceType);
     AudioPort::toAudioPort(port);
     port->id = mId;
     toAudioPortConfig(&port->active_config);
     port->ext.device.type = mDeviceType;
-    port->ext.device.hw_module = mModule->getHandle();
+    port->ext.device.hw_module = getModuleHandle();
     (void)audio_utils_strlcpy_zerofill(port->ext.device.address, mAddress.string());
 }
 
@@ -270,42 +338,83 @@
     port->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
 }
 
-status_t DeviceDescriptor::dump(int fd, int spaces, int index, bool verbose) const
+void DeviceDescriptor::dump(String8 *dst, int spaces, int index, bool verbose) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "%*sDevice %d:\n", spaces, "", index+1);
-    result.append(buffer);
+    dst->appendFormat("%*sDevice %d:\n", spaces, "", index + 1);
     if (mId != 0) {
-        snprintf(buffer, SIZE, "%*s- id: %2d\n", spaces, "", mId);
-        result.append(buffer);
+        dst->appendFormat("%*s- id: %2d\n", spaces, "", mId);
     }
     if (!mTagName.isEmpty()) {
-        snprintf(buffer, SIZE, "%*s- tag name: %s\n", spaces, "", mTagName.string());
-        result.append(buffer);
+        dst->appendFormat("%*s- tag name: %s\n", spaces, "", mTagName.string());
     }
-    std::string deviceLiteral;
-    if (deviceToString(mDeviceType, deviceLiteral)) {
-        snprintf(buffer, SIZE, "%*s- type: %-48s\n", spaces, "", deviceLiteral.c_str());
-        result.append(buffer);
-    }
-    if (mAddress.size() != 0) {
-        snprintf(buffer, SIZE, "%*s- address: %-32s\n", spaces, "", mAddress.string());
-        result.append(buffer);
-    }
-    write(fd, result.string(), result.size());
-    AudioPort::dump(fd, spaces, verbose);
 
-    return NO_ERROR;
+    dst->appendFormat("%*s- type: %-48s\n", spaces, "", ::android::toString(mDeviceType).c_str());
+
+    if (mAddress.size() != 0) {
+        dst->appendFormat("%*s- address: %-32s\n", spaces, "", mAddress.string());
+    }
+    AudioPort::dump(dst, spaces, verbose);
+}
+
+std::string DeviceDescriptor::toString() const
+{
+    std::stringstream sstream;
+    sstream << "type:0x" << std::hex << type() << ",@:" << mAddress;
+    return sstream.str();
+}
+
+std::string DeviceVector::toString() const
+{
+    if (isEmpty()) {
+        return {"AUDIO_DEVICE_NONE"};
+    }
+    std::string result = {"{"};
+    for (const auto &device : *this) {
+        if (device != *begin()) {
+           result += ";";
+        }
+        result += device->toString();
+    }
+    return result + "}";
+}
+
+DeviceVector DeviceVector::filter(const DeviceVector &devices) const
+{
+    DeviceVector filteredDevices;
+    for (const auto &device : *this) {
+        if (devices.contains(device)) {
+            filteredDevices.add(device);
+        }
+    }
+    return filteredDevices;
+}
+
+bool DeviceVector::containsAtLeastOne(const DeviceVector &devices) const
+{
+    return !filter(devices).isEmpty();
+}
+
+bool DeviceVector::containsAllDevices(const DeviceVector &devices) const
+{
+    return filter(devices).size() == devices.size();
+}
+
+DeviceVector DeviceVector::filterForEngine() const
+{
+    DeviceVector filteredDevices;
+    for (const auto &device : *this) {
+        if (audio_is_remote_submix_device(device->type()) && device->address() != "0") {
+            continue;
+        }
+        filteredDevices.add(device);
+    }
+    return filteredDevices;
 }
 
 void DeviceDescriptor::log() const
 {
-    std::string device;
-    deviceToString(mDeviceType, device);
-    ALOGI("Device id:%d type:0x%X:%s, addr:%s", mId,  mDeviceType, device.c_str(),
+    ALOGI("Device id:%d type:0x%08X:%s, addr:%s", mId,  mDeviceType,
+          ::android::toString(mDeviceType).c_str(),
           mAddress.string());
 
     AudioPort::log("  ");
diff --git a/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
index 7b2341e..415962a 100644
--- a/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
@@ -22,25 +22,15 @@
 
 namespace android {
 
-status_t EffectDescriptor::dump(int fd)
+void EffectDescriptor::dump(String8 *dst, int spaces) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, " I/O: %d\n", mIo);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Strategy: %d\n", mStrategy);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Session: %d\n", mSession);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Name: %s\n",  mDesc.name);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " %s\n",  mEnabled ? "Enabled" : "Disabled");
-    result.append(buffer);
-    write(fd, result.string(), result.size());
-
-    return NO_ERROR;
+    dst->appendFormat("%*sID: %d\n", spaces, "", mId);
+    dst->appendFormat("%*sI/O: %d\n", spaces, "", mIo);
+    dst->appendFormat("%*sMusic Effect: %s\n", spaces, "", isMusicEffect()? "yes" : "no");
+    dst->appendFormat("%*sSession: %d\n", spaces, "", mSession);
+    dst->appendFormat("%*sName: %s\n", spaces, "",  mDesc.name);
+    dst->appendFormat("%*s%s\n", spaces, "",  mEnabled ? "Enabled" : "Disabled");
+    dst->appendFormat("%*s%s\n", spaces, "",  mSuspended ? "Suspended" : "Active");
 }
 
 EffectDescriptorCollection::EffectDescriptorCollection() :
@@ -53,10 +43,14 @@
 
 status_t EffectDescriptorCollection::registerEffect(const effect_descriptor_t *desc,
                                                     audio_io_handle_t io,
-                                                    uint32_t strategy,
                                                     int session,
-                                                    int id)
+                                                    int id, bool isMusicEffect)
 {
+    if (getEffect(id) != nullptr) {
+        ALOGW("%s effect %s already registered", __FUNCTION__, desc->name);
+        return INVALID_OPERATION;
+    }
+
     if (mTotalEffectsMemory + desc->memoryUsage > getMaxEffectsMemory()) {
         ALOGW("registerEffect() memory limit exceeded for Fx %s, Memory %d KB",
                 desc->name, desc->memoryUsage);
@@ -66,34 +60,34 @@
     if (mTotalEffectsMemory > mTotalEffectsMemoryMaxUsed) {
         mTotalEffectsMemoryMaxUsed = mTotalEffectsMemory;
     }
-    ALOGV("registerEffect() effect %s, io %d, strategy %d session %d id %d",
-            desc->name, io, strategy, session, id);
+    ALOGV("registerEffect() effect %s, io %d, session %d id %d",
+            desc->name, io, session, id);
     ALOGV("registerEffect() memory %d, total memory %d", desc->memoryUsage, mTotalEffectsMemory);
 
-    sp<EffectDescriptor> effectDesc = new EffectDescriptor();
-    memcpy (&effectDesc->mDesc, desc, sizeof(effect_descriptor_t));
-    effectDesc->mIo = io;
-    effectDesc->mStrategy = static_cast<routing_strategy>(strategy);
-    effectDesc->mSession = session;
-    effectDesc->mEnabled = false;
-
+    sp<EffectDescriptor> effectDesc =
+        new EffectDescriptor(desc, isMusicEffect, id, io, (audio_session_t)session);
     add(id, effectDesc);
 
     return NO_ERROR;
 }
 
-status_t EffectDescriptorCollection::unregisterEffect(int id)
+sp<EffectDescriptor> EffectDescriptorCollection::getEffect(int id) const
 {
     ssize_t index = indexOfKey(id);
     if (index < 0) {
-        ALOGW("unregisterEffect() unknown effect ID %d", id);
+        return nullptr;
+    }
+    return valueAt(index);
+}
+
+status_t EffectDescriptorCollection::unregisterEffect(int id)
+{
+    sp<EffectDescriptor> effectDesc = getEffect(id);
+    if (effectDesc == nullptr) {
+        ALOGW("%s unknown effect ID %d", __FUNCTION__, id);
         return INVALID_OPERATION;
     }
 
-    sp<EffectDescriptor> effectDesc = valueAt(index);
-
-    setEffectEnabled(effectDesc, false);
-
     if (mTotalEffectsMemory < effectDesc->mDesc.memoryUsage) {
         ALOGW("unregisterEffect() memory %d too big for total %d",
                 effectDesc->mDesc.memoryUsage, mTotalEffectsMemory);
@@ -119,6 +113,14 @@
     return setEffectEnabled(valueAt(index), enabled);
 }
 
+bool EffectDescriptorCollection::isEffectEnabled(int id) const
+{
+    ssize_t index = indexOfKey(id);
+    if (index < 0) {
+        return false;
+    }
+    return valueAt(index)->mEnabled;
+}
 
 status_t EffectDescriptorCollection::setEffectEnabled(const sp<EffectDescriptor> &effectDesc,
                                                       bool enabled)
@@ -150,11 +152,11 @@
     return NO_ERROR;
 }
 
-bool EffectDescriptorCollection::isNonOffloadableEffectEnabled()
+bool EffectDescriptorCollection::isNonOffloadableEffectEnabled() const
 {
     for (size_t i = 0; i < size(); i++) {
         sp<EffectDescriptor> effectDesc = valueAt(i);
-        if (effectDesc->mEnabled && (effectDesc->mStrategy == STRATEGY_MEDIA) &&
+        if (effectDesc->mEnabled && (effectDesc->isMusicEffect()) &&
                 ((effectDesc->mDesc.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) == 0)) {
             ALOGV("isNonOffloadableEffectEnabled() non offloadable effect %s enabled on session %d",
                   effectDesc->mDesc.name, effectDesc->mSession);
@@ -174,24 +176,59 @@
     return MAX_EFFECTS_MEMORY;
 }
 
-status_t EffectDescriptorCollection::dump(int fd)
+void EffectDescriptorCollection::moveEffects(audio_session_t session,
+                                             audio_io_handle_t srcOutput,
+                                             audio_io_handle_t dstOutput)
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE,
-            "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB, Max memory used: %d KB\n",
-             (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory, mTotalEffectsMemoryMaxUsed);
-    write(fd, buffer, strlen(buffer));
-
-    snprintf(buffer, SIZE, "Registered effects:\n");
-    write(fd, buffer, strlen(buffer));
+    ALOGV("%s session %d srcOutput %d dstOutput %d", __func__, session, srcOutput, dstOutput);
     for (size_t i = 0; i < size(); i++) {
-        snprintf(buffer, SIZE, "- Effect %d dump:\n", keyAt(i));
-        write(fd, buffer, strlen(buffer));
-        valueAt(i)->dump(fd);
+        sp<EffectDescriptor> effect = valueAt(i);
+        if (effect->mSession == session && effect->mIo == srcOutput) {
+            effect->mIo = dstOutput;
+        }
     }
-    return NO_ERROR;
+}
+
+void EffectDescriptorCollection::moveEffects(const std::vector<int>& ids,
+                                             audio_io_handle_t dstOutput)
+{
+    ALOGV("%s num effects %zu, first ID %d, dstOutput %d",
+        __func__, ids.size(), ids.size() ? ids[0] : 0, dstOutput);
+    for (size_t i = 0; i < size(); i++) {
+        sp<EffectDescriptor> effect = valueAt(i);
+        if (std::find(begin(ids), end(ids), effect->mId) != end(ids)) {
+            effect->mIo = dstOutput;
+        }
+    }
+}
+
+EffectDescriptorCollection EffectDescriptorCollection::getEffectsForIo(audio_io_handle_t io) const
+{
+    EffectDescriptorCollection effects;
+    for (size_t i = 0; i < size(); i++) {
+        if (valueAt(i)->mIo == io) {
+            effects.add(keyAt(i), valueAt(i));
+        }
+    }
+    return effects;
+}
+
+void EffectDescriptorCollection::dump(String8 *dst, int spaces, bool verbose) const
+{
+    if (verbose) {
+        dst->appendFormat(
+            "\n%*sTotal Effects CPU: %f MIPS, "
+            "Total Effects memory: %d KB, Max memory used: %d KB\n",
+            spaces, "",
+            (float) mTotalEffectsCpuLoad / 10,
+            mTotalEffectsMemory,
+            mTotalEffectsMemoryMaxUsed);
+    }
+    dst->appendFormat("%*sEffects:\n", spaces, "");
+    for (size_t i = 0; i < size(); i++) {
+        dst->appendFormat("%*s- Effect %d:\n", spaces, "", keyAt(i));
+        valueAt(i)->dump(dst, spaces + 2);
+    }
 }
 
 }; //namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/Gains.cpp b/services/audiopolicy/common/managerdefinitions/src/Gains.cpp
deleted file mode 100644
index 6407a17..0000000
--- a/services/audiopolicy/common/managerdefinitions/src/Gains.cpp
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "APM::Gains"
-//#define LOG_NDEBUG 0
-
-//#define VERY_VERBOSE_LOGGING
-#ifdef VERY_VERBOSE_LOGGING
-#define ALOGVV ALOGV
-#else
-#define ALOGVV(a...) do { } while(0)
-#endif
-
-#include "Gains.h"
-#include <Volume.h>
-#include <math.h>
-#include <utils/String8.h>
-
-namespace android {
-
-// Enginedefault
-const VolumeCurvePoint
-Gains::sDefaultVolumeCurve[Volume::VOLCNT] = {
-    {1, -49.5f}, {33, -33.5f}, {66, -17.0f}, {100, 0.0f}
-};
-
-
-const VolumeCurvePoint
-Gains::sDefaultMediaVolumeCurve[Volume::VOLCNT] = {
-    {1, -58.0f}, {20, -40.0f}, {60, -17.0f}, {100, 0.0f}
-};
-
-const VolumeCurvePoint
-Gains::sExtMediaSystemVolumeCurve[Volume::VOLCNT] = {
-    {1, -58.0f}, {20, -40.0f}, {60, -21.0f}, {100, -10.0f}
-};
-
-const VolumeCurvePoint
-Gains::sSpeakerMediaVolumeCurve[Volume::VOLCNT] = {
-    {1, -56.0f}, {20, -34.0f}, {60, -11.0f}, {100, 0.0f}
-};
-
-const VolumeCurvePoint
-Gains::sSpeakerMediaVolumeCurveDrc[Volume::VOLCNT] = {
-    {1, -55.0f}, {20, -43.0f}, {86, -12.0f}, {100, 0.0f}
-};
-
-const VolumeCurvePoint
-Gains::sSpeakerSonificationVolumeCurve[Volume::VOLCNT] = {
-    {1, -29.7f}, {33, -20.1f}, {66, -10.2f}, {100, 0.0f}
-};
-
-const VolumeCurvePoint
-Gains::sSpeakerSonificationVolumeCurveDrc[Volume::VOLCNT] = {
-    {1, -35.7f}, {33, -26.1f}, {66, -13.2f}, {100, 0.0f}
-};
-
-// AUDIO_STREAM_SYSTEM, AUDIO_STREAM_ENFORCED_AUDIBLE and AUDIO_STREAM_DTMF volume tracks
-// AUDIO_STREAM_RING on phones and AUDIO_STREAM_MUSIC on tablets.
-// AUDIO_STREAM_DTMF tracks AUDIO_STREAM_VOICE_CALL while in call (See AudioService.java).
-// The range is constrained between -24dB and -6dB over speaker and -30dB and -18dB over headset.
-
-const VolumeCurvePoint
-Gains::sDefaultSystemVolumeCurve[Volume::VOLCNT] = {
-    {1, -24.0f}, {33, -18.0f}, {66, -12.0f}, {100, -6.0f}
-};
-
-const VolumeCurvePoint
-Gains::sDefaultSystemVolumeCurveDrc[Volume::VOLCNT] = {
-    {1, -34.0f}, {33, -24.0f}, {66, -15.0f}, {100, -6.0f}
-};
-
-const VolumeCurvePoint
-Gains::sHeadsetSystemVolumeCurve[Volume::VOLCNT] = {
-    {1, -30.0f}, {33, -26.0f}, {66, -22.0f}, {100, -18.0f}
-};
-
-const VolumeCurvePoint
-Gains::sDefaultVoiceVolumeCurve[Volume::VOLCNT] = {
-    {0, -42.0f}, {33, -28.0f}, {66, -14.0f}, {100, 0.0f}
-};
-
-const VolumeCurvePoint
-Gains::sSpeakerVoiceVolumeCurve[Volume::VOLCNT] = {
-    {0, -24.0f}, {33, -16.0f}, {66, -8.0f}, {100, 0.0f}
-};
-
-const VolumeCurvePoint
-Gains::sLinearVolumeCurve[Volume::VOLCNT] = {
-    {0, -96.0f}, {33, -68.0f}, {66, -34.0f}, {100, 0.0f}
-};
-
-const VolumeCurvePoint
-Gains::sSilentVolumeCurve[Volume::VOLCNT] = {
-    {0, -96.0f}, {1, -96.0f}, {2, -96.0f}, {100, -96.0f}
-};
-
-const VolumeCurvePoint
-Gains::sFullScaleVolumeCurve[Volume::VOLCNT] = {
-    {0, 0.0f}, {1, 0.0f}, {2, 0.0f}, {100, 0.0f}
-};
-
-const VolumeCurvePoint
-Gains::sHearingAidVolumeCurve[Volume::VOLCNT] = {
-    {1, -128.0f}, {20, -80.0f}, {60, -40.0f}, {100, 0.0f}
-};
-
-const VolumeCurvePoint *Gains::sVolumeProfiles[AUDIO_STREAM_CNT]
-                                                  [DEVICE_CATEGORY_CNT] = {
-    { // AUDIO_STREAM_VOICE_CALL
-        Gains::sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        Gains::sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        Gains::sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        Gains::sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
-        Gains::sHearingAidVolumeCurve     // DEVICE_CATEGORY_HEARING_AID
-    },
-    { // AUDIO_STREAM_SYSTEM
-        Gains::sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        Gains::sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        Gains::sDefaultSystemVolumeCurve,  // DEVICE_CATEGORY_EARPIECE
-        Gains::sExtMediaSystemVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
-        Gains::sHearingAidVolumeCurve       // DEVICE_CATEGORY_HEARING_AID
-    },
-    { // AUDIO_STREAM_RING
-        Gains::sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        Gains::sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        Gains::sDefaultVolumeCurve,  // DEVICE_CATEGORY_EARPIECE
-        Gains::sExtMediaSystemVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
-        Gains::sHearingAidVolumeCurve // DEVICE_CATEGORY_HEARING_AID
-    },
-    { // AUDIO_STREAM_MUSIC
-        Gains::sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        Gains::sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        Gains::sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        Gains::sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
-        Gains::sHearingAidVolumeCurve     // DEVICE_CATEGORY_HEARING_AID
-    },
-    { // AUDIO_STREAM_ALARM
-        Gains::sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        Gains::sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        Gains::sDefaultVolumeCurve,  // DEVICE_CATEGORY_EARPIECE
-        Gains::sExtMediaSystemVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
-        Gains::sHearingAidVolumeCurve // DEVICE_CATEGORY_HEARING_AID
-    },
-    { // AUDIO_STREAM_NOTIFICATION
-        Gains::sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        Gains::sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        Gains::sDefaultVolumeCurve,  // DEVICE_CATEGORY_EARPIECE
-        Gains::sExtMediaSystemVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
-        Gains::sHearingAidVolumeCurve // DEVICE_CATEGORY_HEARING_AID
-    },
-    { // AUDIO_STREAM_BLUETOOTH_SCO
-        Gains::sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        Gains::sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        Gains::sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        Gains::sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
-        Gains::sHearingAidVolumeCurve      // DEVICE_CATEGORY_HEARING_AID
-    },
-    { // AUDIO_STREAM_ENFORCED_AUDIBLE
-        Gains::sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        Gains::sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        Gains::sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        Gains::sExtMediaSystemVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
-        Gains::sHearingAidVolumeCurve       // DEVICE_CATEGORY_HEARING_AID
-    },
-    {  // AUDIO_STREAM_DTMF
-        Gains::sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        Gains::sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        Gains::sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        Gains::sExtMediaSystemVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
-        Gains::sHearingAidVolumeCurve       // DEVICE_CATEGORY_HEARING_AID
-    },
-    { // AUDIO_STREAM_TTS
-      // "Transmitted Through Speaker": always silent except on DEVICE_CATEGORY_SPEAKER
-        Gains::sSilentVolumeCurve,    // DEVICE_CATEGORY_HEADSET
-        Gains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        Gains::sSilentVolumeCurve,    // DEVICE_CATEGORY_EARPIECE
-        Gains::sSilentVolumeCurve,    // DEVICE_CATEGORY_EXT_MEDIA
-        Gains::sHearingAidVolumeCurve  // DEVICE_CATEGORY_HEARING_AID
-    },
-    { // AUDIO_STREAM_ACCESSIBILITY
-        Gains::sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        Gains::sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        Gains::sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        Gains::sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
-        Gains::sHearingAidVolumeCurve     // DEVICE_CATEGORY_HEARING_AID
-    },
-    { // AUDIO_STREAM_REROUTING
-        Gains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        Gains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        Gains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        Gains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
-        Gains::sFullScaleVolumeCurve  // DEVICE_CATEGORY_HEARING_AID
-    },
-    { // AUDIO_STREAM_PATCH
-        Gains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        Gains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        Gains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        Gains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
-        Gains::sFullScaleVolumeCurve  // DEVICE_CATEGORY_HEARING_AID
-    },
-};
-
-//static
-float Gains::volIndexToDb(const VolumeCurvePoint *curve, int indexMin, int indexMax, int indexInUi)
-{
-    // the volume index in the UI is relative to the min and max volume indices for this stream type
-    int nbSteps = 1 + curve[Volume::VOLMAX].mIndex - curve[Volume::VOLMIN].mIndex;
-    int volIdx = (nbSteps * (indexInUi - indexMin)) / (indexMax - indexMin);
-
-    // find what part of the curve this index volume belongs to, or if it's out of bounds
-    int segment = 0;
-    if (volIdx < curve[Volume::VOLMIN].mIndex) {         // out of bounds
-        return VOLUME_MIN_DB;
-    } else if (volIdx < curve[Volume::VOLKNEE1].mIndex) {
-        segment = 0;
-    } else if (volIdx < curve[Volume::VOLKNEE2].mIndex) {
-        segment = 1;
-    } else if (volIdx <= curve[Volume::VOLMAX].mIndex) {
-        segment = 2;
-    } else {                                                               // out of bounds
-        return 0.0f;
-    }
-
-    // linear interpolation in the attenuation table in dB
-    float decibels = curve[segment].mDBAttenuation +
-            ((float)(volIdx - curve[segment].mIndex)) *
-                ( (curve[segment+1].mDBAttenuation -
-                        curve[segment].mDBAttenuation) /
-                    ((float)(curve[segment+1].mIndex -
-                            curve[segment].mIndex)) );
-
-    ALOGVV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f]",
-            curve[segment].mIndex, volIdx,
-            curve[segment+1].mIndex,
-            curve[segment].mDBAttenuation,
-            decibels,
-            curve[segment+1].mDBAttenuation);
-
-    return decibels;
-}
-
-} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index aef7dbe..96a8337 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -51,7 +51,10 @@
                                               config->sample_rate));
 
     sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device);
-    devDesc->mAddress = address;
+    devDesc->setAddress(address);
+    addDynamicDevice(devDesc);
+    // Reciprocally attach the device to the module
+    devDesc->attach(this);
     profile->addSupportedDevice(devDesc);
 
     return addOutputProfile(profile);
@@ -97,6 +100,9 @@
 {
     for (size_t i = 0; i < mOutputProfiles.size(); i++) {
         if (mOutputProfiles[i]->getName() == name) {
+            for (const auto &device : mOutputProfiles[i]->getSupportedDevices()) {
+                removeDynamicDevice(device);
+            }
             mOutputProfiles.removeAt(i);
             break;
         }
@@ -113,7 +119,10 @@
                                               config->sample_rate));
 
     sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device);
-    devDesc->mAddress = address;
+    devDesc->setAddress(address);
+    addDynamicDevice(devDesc);
+    // Reciprocally attach the device to the module
+    devDesc->attach(this);
     profile->addSupportedDevice(devDesc);
 
     ALOGV("addInputProfile() name %s rate %d mask 0x%08x",
@@ -126,6 +135,9 @@
 {
     for (size_t i = 0; i < mInputProfiles.size(); i++) {
         if (mInputProfiles[i]->getName() == name) {
+            for (const auto &device : mInputProfiles[i]->getSupportedDevices()) {
+                removeDynamicDevice(device);
+            }
             mInputProfiles.removeAt(i);
             break;
         }
@@ -218,37 +230,37 @@
     mHandle = handle;
 }
 
-void HwModule::dump(int fd)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
+bool HwModule::supportsPatch(const sp<AudioPort> &srcPort, const sp<AudioPort> &dstPort) const {
+    for (const auto &route : mRoutes) {
+        if (route->supportsPatch(srcPort, dstPort)) {
+            return true;
+        }
+    }
+    return false;
+}
 
-    snprintf(buffer, SIZE, "  - name: %s\n", getName());
-    result.append(buffer);
-    snprintf(buffer, SIZE, "  - handle: %d\n", mHandle);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "  - version: %u.%u\n", getHalVersionMajor(), getHalVersionMinor());
-    result.append(buffer);
-    write(fd, result.string(), result.size());
+void HwModule::dump(String8 *dst) const
+{
+    dst->appendFormat("  - name: %s\n", getName());
+    dst->appendFormat("  - handle: %d\n", mHandle);
+    dst->appendFormat("  - version: %u.%u\n", getHalVersionMajor(), getHalVersionMinor());
     if (mOutputProfiles.size()) {
-        write(fd, "  - outputs:\n", strlen("  - outputs:\n"));
+        dst->append("  - outputs:\n");
         for (size_t i = 0; i < mOutputProfiles.size(); i++) {
-            snprintf(buffer, SIZE, "    output %zu:\n", i);
-            write(fd, buffer, strlen(buffer));
-            mOutputProfiles[i]->dump(fd);
+            dst->appendFormat("    output %zu:\n", i);
+            mOutputProfiles[i]->dump(dst);
         }
     }
     if (mInputProfiles.size()) {
-        write(fd, "  - inputs:\n", strlen("  - inputs:\n"));
+        dst->append("  - inputs:\n");
         for (size_t i = 0; i < mInputProfiles.size(); i++) {
-            snprintf(buffer, SIZE, "    input %zu:\n", i);
-            write(fd, buffer, strlen(buffer));
-            mInputProfiles[i]->dump(fd);
+            dst->appendFormat("    input %zu:\n", i);
+            mInputProfiles[i]->dump(dst);
         }
     }
-    mDeclaredDevices.dump(fd, String8("Declared"),  2, true);
-    mRoutes.dump(fd, 2);
+    mDeclaredDevices.dump(dst, String8("Declared"), 2, true);
+    mDynamicDevices.dump(dst, String8("Dynamic"),  2, true);
+    mRoutes.dump(dst, 2);
 }
 
 sp <HwModule> HwModuleCollection::getModuleFromName(const char *name) const
@@ -261,64 +273,167 @@
     return nullptr;
 }
 
-sp <HwModule> HwModuleCollection::getModuleForDevice(audio_devices_t device) const
+sp <HwModule> HwModuleCollection::getModuleForDeviceTypes(audio_devices_t type,
+                                                          audio_format_t encodedFormat) const
 {
     for (const auto& module : *this) {
-        const auto& profiles = audio_is_output_device(device) ?
+        const auto& profiles = audio_is_output_device(type) ?
                 module->getOutputProfiles() : module->getInputProfiles();
         for (const auto& profile : profiles) {
-            if (profile->supportDevice(device)) {
-                return module;
+            if (profile->supportsDeviceTypes(type)) {
+                if (encodedFormat != AUDIO_FORMAT_DEFAULT) {
+                    DeviceVector declaredDevices = module->getDeclaredDevices();
+                    sp <DeviceDescriptor> deviceDesc =
+                            declaredDevices.getDevice(type, String8(), encodedFormat);
+                    if (deviceDesc) {
+                        return module;
+                    }
+                } else {
+                    return module;
+                }
             }
         }
     }
     return nullptr;
 }
 
-sp<DeviceDescriptor> HwModuleCollection::getDeviceDescriptor(const audio_devices_t device,
-                                                             const char *device_address,
-                                                             const char *device_name,
-                                                             bool matchAdress) const
+sp<HwModule> HwModuleCollection::getModuleForDevice(const sp<DeviceDescriptor> &device,
+                                                     audio_format_t encodedFormat) const
 {
-    String8 address = (device_address == nullptr) ? String8("") : String8(device_address);
+    return getModuleForDeviceTypes(device->type(), encodedFormat);
+}
+
+DeviceVector HwModuleCollection::getAvailableDevicesFromModuleName(
+        const char *name, const DeviceVector &availableDevices) const
+{
+    sp<HwModule> module = getModuleFromName(name);
+    if (module == nullptr) {
+        return DeviceVector();
+    }
+    return availableDevices.getDevicesFromHwModule(module->getHandle());
+}
+
+sp<DeviceDescriptor> HwModuleCollection::getDeviceDescriptor(const audio_devices_t deviceType,
+                                                             const char *address,
+                                                             const char *name,
+                                                             const audio_format_t encodedFormat,
+                                                             bool allowToCreate,
+                                                             bool matchAddress) const
+{
+    String8 devAddress = (address == nullptr || !matchAddress) ? String8("") : String8(address);
     // handle legacy remote submix case where the address was not always specified
-    if (device_distinguishes_on_address(device) && (address.length() == 0)) {
-        address = String8("0");
+    if (device_distinguishes_on_address(deviceType) && (devAddress.length() == 0)) {
+        devAddress = String8("0");
     }
 
     for (const auto& hwModule : *this) {
-        DeviceVector declaredDevices = hwModule->getDeclaredDevices();
-        DeviceVector deviceList = declaredDevices.getDevicesFromTypeAddr(device, address);
-        if (!deviceList.isEmpty()) {
-            return deviceList.itemAt(0);
+        DeviceVector moduleDevices = hwModule->getAllDevices();
+        auto moduleDevice = moduleDevices.getDevice(deviceType, devAddress, encodedFormat);
+        if (moduleDevice) {
+            if (encodedFormat != AUDIO_FORMAT_DEFAULT) {
+                moduleDevice->setEncodedFormat(encodedFormat);
+            }
+            moduleDevice->setAddress(devAddress);
+            if (allowToCreate) {
+                moduleDevice->attach(hwModule);
+            }
+            return moduleDevice;
         }
-        if (!matchAdress) {
-            deviceList = declaredDevices.getDevicesFromType(device);
-            if (!deviceList.isEmpty()) {
-                return deviceList.itemAt(0);
+    }
+    if (!allowToCreate) {
+        ALOGV("%s: could not find HW module for device %s %04x address %s", __FUNCTION__,
+              name, deviceType, address);
+        return nullptr;
+    }
+    return createDevice(deviceType, address, name, encodedFormat);
+}
+
+sp<DeviceDescriptor> HwModuleCollection::createDevice(const audio_devices_t type,
+                                                      const char *address,
+                                                      const char *name,
+                                                      const audio_format_t encodedFormat) const
+{
+    sp<HwModule> hwModule = getModuleForDeviceTypes(type, encodedFormat);
+    if (hwModule == 0) {
+        ALOGE("%s: could not find HW module for device %04x address %s", __FUNCTION__, type,
+              address);
+        return nullptr;
+    }
+    sp<DeviceDescriptor> device = new DeviceDescriptor(type, String8(name));
+    device->setName(String8(name));
+    device->setAddress(String8(address));
+    device->setEncodedFormat(encodedFormat);
+
+  // Add the device to the list of dynamic devices
+    hwModule->addDynamicDevice(device);
+    // Reciprocally attach the device to the module
+    device->attach(hwModule);
+    ALOGD("%s: adding dynamic device %s to module %s", __FUNCTION__,
+          device->toString().c_str(), hwModule->getName());
+
+    const auto &profiles = (audio_is_output_device(type) ? hwModule->getOutputProfiles() :
+                                                             hwModule->getInputProfiles());
+    for (const auto &profile : profiles) {
+        // Add the device as supported to all profile supporting "weakly" or not the device
+        // according to its type
+        if (profile->supportsDevice(device, false /*matchAdress*/)) {
+
+            // @todo quid of audio profile? import the profile from device of the same type?
+            const auto &isoTypeDeviceForProfile =
+                profile->getSupportedDevices().getDevice(type, String8(), AUDIO_FORMAT_DEFAULT);
+            device->importAudioPort(isoTypeDeviceForProfile, true /* force */);
+
+            ALOGV("%s: adding device %s to profile %s", __FUNCTION__,
+                  device->toString().c_str(), profile->getTagName().c_str());
+            profile->addSupportedDevice(device);
+        }
+    }
+    return device;
+}
+
+void HwModuleCollection::cleanUpForDevice(const sp<DeviceDescriptor> &device)
+{
+    for (const auto& hwModule : *this) {
+        DeviceVector moduleDevices = hwModule->getAllDevices();
+        if (!moduleDevices.contains(device)) {
+            continue;
+        }
+
+        // removal of remote submix devices associated with a dynamic policy is
+        // handled by removeOutputProfile() and removeInputProfile()
+        if (audio_is_remote_submix_device(device->type()) && device->address() != "0") {
+            continue;
+        }
+
+        device->detach();
+        // Only remove from dynamic list, not from declared list!!!
+        if (!hwModule->getDynamicDevices().contains(device)) {
+            return;
+        }
+        hwModule->removeDynamicDevice(device);
+        ALOGV("%s: removed dynamic device %s from module %s", __FUNCTION__,
+              device->toString().c_str(), hwModule->getName());
+
+        const IOProfileCollection &profiles = audio_is_output_device(device->type()) ?
+                    hwModule->getOutputProfiles() : hwModule->getInputProfiles();
+        for (const auto &profile : profiles) {
+            // For cleanup, strong match is required
+            if (profile->supportsDevice(device, true /*matchAdress*/)) {
+                ALOGV("%s: removing device %s from profile %s", __FUNCTION__,
+                      device->toString().c_str(), profile->getTagName().c_str());
+                profile->removeSupportedDevice(device);
             }
         }
     }
-
-    sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device);
-    devDesc->setName(String8(device_name));
-    devDesc->mAddress = address;
-    return devDesc;
 }
 
-status_t HwModuleCollection::dump(int fd) const
+void HwModuleCollection::dump(String8 *dst) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE, "\nHW Modules dump:\n");
-    write(fd, buffer, strlen(buffer));
+    dst->append("\nHW Modules dump:\n");
     for (size_t i = 0; i < size(); i++) {
-        snprintf(buffer, SIZE, "- HW Module %zu:\n", i + 1);
-        write(fd, buffer, strlen(buffer));
-        itemAt(i)->dump(fd);
+        dst->appendFormat("- HW Module %zu:\n", i + 1);
+        itemAt(i)->dump(dst);
     }
-    return NO_ERROR;
 }
 
 
diff --git a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
index fbc2384..fe2eaee 100644
--- a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "APM::IOProfile"
 //#define LOG_NDEBUG 0
 
+#include <system/audio-base.h>
 #include "IOProfile.h"
 #include "HwModule.h"
 #include "AudioGain.h"
@@ -24,11 +25,7 @@
 
 namespace android {
 
-// checks if the IO profile is compatible with specified parameters.
-// Sampling rate, format and channel mask must be specified in order to
-// get a valid a match
-bool IOProfile::isCompatibleProfile(audio_devices_t device,
-                                    const String8& address,
+bool IOProfile::isCompatibleProfile(const DeviceVector &devices,
                                     uint32_t samplingRate,
                                     uint32_t *updatedSamplingRate,
                                     audio_format_t format,
@@ -45,14 +42,8 @@
             getType() == AUDIO_PORT_TYPE_MIX && getRole() == AUDIO_PORT_ROLE_SINK;
     ALOG_ASSERT(isPlaybackThread != isRecordThread);
 
-
-    if (device != AUDIO_DEVICE_NONE) {
-        // just check types if multiple devices are selected
-        if (popcount(device & ~AUDIO_DEVICE_BIT_IN) > 1) {
-            if ((mSupportedDevices.types() & device) != device) {
-                return false;
-            }
-        } else if (mSupportedDevices.getDevice(device, address) == 0) {
+    if (!devices.isEmpty()) {
+        if (!mSupportedDevices.containsAllDevices(devices)) {
             return false;
         }
     }
@@ -66,19 +57,23 @@
     audio_format_t myUpdatedFormat = format;
     audio_channel_mask_t myUpdatedChannelMask = channelMask;
     uint32_t myUpdatedSamplingRate = samplingRate;
+    const struct audio_port_config config = {
+        .config_mask = AUDIO_PORT_CONFIG_ALL & ~AUDIO_PORT_CONFIG_GAIN,
+        .sample_rate = samplingRate,
+        .channel_mask = channelMask,
+        .format = format,
+    };
     if (isRecordThread)
     {
-        if (checkCompatibleAudioProfile(
+        if ((flags & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0) {
+            if (checkExactAudioProfile(&config) != NO_ERROR) {
+                return false;
+            }
+        } else if (checkCompatibleAudioProfile(
                 myUpdatedSamplingRate, myUpdatedChannelMask, myUpdatedFormat) != NO_ERROR) {
             return false;
         }
     } else {
-        const struct audio_port_config config = {
-            .config_mask = AUDIO_PORT_CONFIG_ALL & ~AUDIO_PORT_CONFIG_GAIN,
-            .sample_rate = samplingRate,
-            .channel_mask = channelMask,
-            .format = format,
-        };
         if (checkExactAudioProfile(&config) != NO_ERROR) {
             return false;
         }
@@ -108,16 +103,11 @@
     return true;
 }
 
-void IOProfile::dump(int fd)
+void IOProfile::dump(String8 *dst) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
+    AudioPort::dump(dst, 4);
 
-    AudioPort::dump(fd, 4);
-
-    snprintf(buffer, SIZE, "    - flags: 0x%04x", getFlags());
-    result.append(buffer);
+    dst->appendFormat("    - flags: 0x%04x", getFlags());
     std::string flagsLiteral;
     if (getRole() == AUDIO_PORT_ROLE_SINK) {
         InputFlagConverter::maskToString(getFlags(), flagsLiteral);
@@ -125,21 +115,14 @@
         OutputFlagConverter::maskToString(getFlags(), flagsLiteral);
     }
     if (!flagsLiteral.empty()) {
-        result.appendFormat(" (%s)", flagsLiteral.c_str());
+        dst->appendFormat(" (%s)", flagsLiteral.c_str());
     }
-    result.append("\n");
-    write(fd, result.string(), result.size());
-    mSupportedDevices.dump(fd, String8("Supported"), 4, false);
-
-    result.clear();
-    snprintf(buffer, SIZE, "\n    - maxOpenCount: %u - curOpenCount: %u\n",
+    dst->append("\n");
+    mSupportedDevices.dump(dst, String8("Supported"), 4, false);
+    dst->appendFormat("\n    - maxOpenCount: %u - curOpenCount: %u\n",
              maxOpenCount, curOpenCount);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "    - maxActiveCount: %u - curActiveCount: %u\n",
+    dst->appendFormat("    - maxActiveCount: %u - curActiveCount: %u\n",
              maxActiveCount, curActiveCount);
-    result.append(buffer);
-
-    write(fd, result.string(), result.size());
 }
 
 void IOProfile::log()
diff --git a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
index a253113..5f820c2 100644
--- a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
@@ -17,241 +17,432 @@
 #define LOG_TAG "APM::Serializer"
 //#define LOG_NDEBUG 0
 
-#include "Serializer.h"
-#include <media/convert.h>
-#include "TypeConverter.h"
+#include <memory>
+#include <string>
+#include <utility>
+
+#include <hidl/Status.h>
 #include <libxml/parser.h>
 #include <libxml/xinclude.h>
-#include <string>
-#include <sstream>
-#include <istream>
-
-using std::string;
+#include <media/convert.h>
+#include <utils/Log.h>
+#include <utils/StrongPointer.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include "Serializer.h"
+#include "TypeConverter.h"
 
 namespace android {
 
-string getXmlAttribute(const xmlNode *cur, const char *attribute)
+namespace {
+
+// TODO(mnaganov): Consider finding an alternative for using HIDL code.
+using hardware::Return;
+using hardware::Status;
+using utilities::convertTo;
+
+template<typename E, typename C>
+struct AndroidCollectionTraits {
+    typedef sp<E> Element;
+    typedef C Collection;
+    typedef void* PtrSerializingCtx;
+
+    static status_t addElementToCollection(const Element &element, Collection *collection) {
+        return collection->add(element) >= 0 ? NO_ERROR : BAD_VALUE;
+    }
+};
+
+template<typename C>
+struct StdCollectionTraits {
+    typedef C Collection;
+    typedef typename C::value_type Element;
+    typedef void* PtrSerializingCtx;
+
+    static status_t addElementToCollection(const Element &element, Collection *collection) {
+        auto pair = collection->insert(element);
+        return pair.second ? NO_ERROR : BAD_VALUE;
+    }
+};
+
+struct AudioGainTraits : public AndroidCollectionTraits<AudioGain, AudioGains>
 {
-    xmlChar *xmlValue = xmlGetProp(cur, (const xmlChar*)attribute);
-    if (xmlValue == NULL) {
+    static constexpr const char *tag = "gain";
+    static constexpr const char *collectionTag = "gains";
+
+    struct Attributes
+    {
+        /** gain modes supported, e.g. AUDIO_GAIN_MODE_CHANNELS. */
+        static constexpr const char *mode = "mode";
+        /** controlled channels, needed if mode AUDIO_GAIN_MODE_CHANNELS. */
+        static constexpr const char *channelMask = "channel_mask";
+        static constexpr const char *minValueMB = "minValueMB"; /**< min value in millibel. */
+        static constexpr const char *maxValueMB = "maxValueMB"; /**< max value in millibel. */
+        /** default value in millibel. */
+        static constexpr const char *defaultValueMB = "defaultValueMB";
+        static constexpr const char *stepValueMB = "stepValueMB"; /**< step value in millibel. */
+        /** needed if mode AUDIO_GAIN_MODE_RAMP. */
+        static constexpr const char *minRampMs = "minRampMs";
+        /** needed if mode AUDIO_GAIN_MODE_RAMP. */
+        static constexpr const char *maxRampMs = "maxRampMs";
+        /** needed to allow use setPortGain instead of setStreamVolume. */
+        static constexpr const char *useForVolume = "useForVolume";
+
+    };
+
+    static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
+    // No children
+};
+
+// A profile section contains a name,  one audio format and the list of supported sampling rates
+// and channel masks for this format
+struct AudioProfileTraits : public AndroidCollectionTraits<AudioProfile, AudioProfileVector>
+{
+    static constexpr const char *tag = "profile";
+    static constexpr const char *collectionTag = "profiles";
+
+    struct Attributes
+    {
+        static constexpr const char *samplingRates = "samplingRates";
+        static constexpr const char *format = "format";
+        static constexpr const char *channelMasks = "channelMasks";
+    };
+
+    static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
+};
+
+struct MixPortTraits : public AndroidCollectionTraits<IOProfile, IOProfileCollection>
+{
+    static constexpr const char *tag = "mixPort";
+    static constexpr const char *collectionTag = "mixPorts";
+
+    struct Attributes
+    {
+        static constexpr const char *name = "name";
+        static constexpr const char *role = "role";
+        static constexpr const char *roleSource = "source"; /**< <attribute role source value>. */
+        static constexpr const char *flags = "flags";
+        static constexpr const char *maxOpenCount = "maxOpenCount";
+        static constexpr const char *maxActiveCount = "maxActiveCount";
+    };
+
+    static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
+    // Children: GainTraits
+};
+
+struct DevicePortTraits : public AndroidCollectionTraits<DeviceDescriptor, DeviceVector>
+{
+    static constexpr const char *tag = "devicePort";
+    static constexpr const char *collectionTag = "devicePorts";
+
+    struct Attributes
+    {
+        /**  <device tag name>: any string without space. */
+        static constexpr const char *tagName = "tagName";
+        static constexpr const char *type = "type"; /**< <device type>. */
+        static constexpr const char *role = "role"; /**< <device role: sink or source>. */
+        static constexpr const char *roleSource = "source"; /**< <attribute role source value>. */
+        /** optional: device address, char string less than 64. */
+        static constexpr const char *address = "address";
+        /** optional: the list of encoded audio formats that are known to be supported. */
+        static constexpr const char *encodedFormats = "encodedFormats";
+    };
+
+    static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
+    // Children: GainTraits (optional)
+};
+
+struct RouteTraits : public AndroidCollectionTraits<AudioRoute, AudioRouteVector>
+{
+    static constexpr const char *tag = "route";
+    static constexpr const char *collectionTag = "routes";
+
+    struct Attributes
+    {
+        static constexpr const char *type = "type"; /**< <route type>: mix or mux. */
+        static constexpr const char *typeMix = "mix"; /**< type attribute mix value. */
+        static constexpr const char *sink = "sink"; /**< <sink: involved in this route>. */
+        /** sources: all source that can be involved in this route. */
+        static constexpr const char *sources = "sources";
+    };
+
+    typedef HwModule *PtrSerializingCtx;
+
+    static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
+};
+
+struct ModuleTraits : public AndroidCollectionTraits<HwModule, HwModuleCollection>
+{
+    static constexpr const char *tag = "module";
+    static constexpr const char *collectionTag = "modules";
+
+    static constexpr const char *childAttachedDevicesTag = "attachedDevices";
+    static constexpr const char *childAttachedDeviceTag = "item";
+    static constexpr const char *childDefaultOutputDeviceTag = "defaultOutputDevice";
+
+    struct Attributes
+    {
+        static constexpr const char *name = "name";
+        static constexpr const char *version = "halVersion";
+    };
+
+    typedef AudioPolicyConfig *PtrSerializingCtx;
+
+    static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
+    // Children: mixPortTraits, devicePortTraits, and routeTraits
+    // Need to call deserialize on each child
+};
+
+struct GlobalConfigTraits
+{
+    static constexpr const char *tag = "globalConfiguration";
+
+    struct Attributes
+    {
+        static constexpr const char *speakerDrcEnabled = "speaker_drc_enabled";
+    };
+
+    static status_t deserialize(const xmlNode *root, AudioPolicyConfig *config);
+};
+
+struct SurroundSoundTraits
+{
+    static constexpr const char *tag = "surroundSound";
+
+    static status_t deserialize(const xmlNode *root, AudioPolicyConfig *config);
+    // Children: SurroundSoundFormatTraits
+};
+
+struct SurroundSoundFormatTraits : public StdCollectionTraits<AudioPolicyConfig::SurroundFormats>
+{
+    static constexpr const char *tag = "format";
+    static constexpr const char *collectionTag = "formats";
+
+    struct Attributes
+    {
+        static constexpr const char *name = "name";
+        static constexpr const char *subformats = "subformats";
+    };
+
+    static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
+};
+
+class PolicySerializer
+{
+public:
+    PolicySerializer() : mVersion{std::to_string(gMajor) + "." + std::to_string(gMinor)}
+    {
+        ALOGV("%s: Version=%s Root=%s", __func__, mVersion.c_str(), rootName);
+    }
+    status_t deserialize(const char *configFile, AudioPolicyConfig *config);
+
+private:
+    static constexpr const char *rootName = "audioPolicyConfiguration";
+    static constexpr const char *versionAttribute = "version";
+    static constexpr uint32_t gMajor = 1; /**< the major number of the policy xml format version. */
+    static constexpr uint32_t gMinor = 0; /**< the minor number of the policy xml format version. */
+
+    typedef AudioPolicyConfig Element;
+
+    const std::string mVersion;
+
+    // Children: ModulesTraits, VolumeTraits, SurroundSoundTraits (optional)
+};
+
+template <class T>
+constexpr void (*xmlDeleter)(T* t);
+template <>
+constexpr auto xmlDeleter<xmlDoc> = xmlFreeDoc;
+// http://b/111067277 - Add back constexpr when we switch to C++17.
+template <>
+auto xmlDeleter<xmlChar> = [](xmlChar *s) { xmlFree(s); };
+
+/** @return a unique_ptr with the correct deleter for the libxml2 object. */
+template <class T>
+constexpr auto make_xmlUnique(T *t) {
+    // Wrap deleter in lambda to enable empty base optimization
+    auto deleter = [](T *t) { xmlDeleter<T>(t); };
+    return std::unique_ptr<T, decltype(deleter)>{t, deleter};
+}
+
+std::string getXmlAttribute(const xmlNode *cur, const char *attribute)
+{
+    auto xmlValue = make_xmlUnique(xmlGetProp(cur, reinterpret_cast<const xmlChar*>(attribute)));
+    if (xmlValue == nullptr) {
         return "";
     }
-    string value((const char*)xmlValue);
-    xmlFree(xmlValue);
+    std::string value(reinterpret_cast<const char*>(xmlValue.get()));
     return value;
 }
 
-using utilities::convertTo;
-
-const char *const PolicySerializer::rootName = "audioPolicyConfiguration";
-const char *const PolicySerializer::versionAttribute = "version";
-const uint32_t PolicySerializer::gMajor = 1;
-const uint32_t PolicySerializer::gMinor = 0;
-static const char *const gReferenceElementName = "reference";
-static const char *const gReferenceAttributeName = "name";
-
 template <class Trait>
-static void getReference(const _xmlNode *root, const _xmlNode *&refNode, const string &refName)
+const xmlNode* getReference(const xmlNode *cur, const std::string &refName)
 {
-    const _xmlNode *col = root;
-    while (col != NULL) {
-        if (!xmlStrcmp(col->name, (const xmlChar *)Trait::collectionTag)) {
-            const xmlNode *cur = col->children;
-            while (cur != NULL) {
-                if ((!xmlStrcmp(cur->name, (const xmlChar *)gReferenceElementName))) {
-                    string name = getXmlAttribute(cur, gReferenceAttributeName);
+    for (; cur != NULL; cur = cur->next) {
+        if (!xmlStrcmp(cur->name, reinterpret_cast<const xmlChar*>(Trait::collectionTag))) {
+            for (const xmlNode *child = cur->children; child != NULL; child = child->next) {
+                if ((!xmlStrcmp(child->name,
+                                        reinterpret_cast<const xmlChar*>(Trait::referenceTag)))) {
+                    std::string name = getXmlAttribute(child, Trait::Attributes::referenceName);
                     if (refName == name) {
-                        refNode = cur;
-                        return;
+                        return child;
                     }
                 }
-                cur = cur->next;
             }
         }
-        col = col->next;
     }
-    return;
+    return NULL;
 }
 
 template <class Trait>
-static status_t deserializeCollection(_xmlDoc *doc, const _xmlNode *cur,
-                                      typename Trait::Collection &collection,
-                                      typename Trait::PtrSerializingCtx serializingContext)
+status_t deserializeCollection(const xmlNode *cur,
+        typename Trait::Collection *collection,
+        typename Trait::PtrSerializingCtx serializingContext)
 {
-    const xmlNode *root = cur->xmlChildrenNode;
-    while (root != NULL) {
-        if (xmlStrcmp(root->name, (const xmlChar *)Trait::collectionTag) &&
-                xmlStrcmp(root->name, (const xmlChar *)Trait::tag)) {
-            root = root->next;
-            continue;
+    for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) {
+        const xmlNode *child = NULL;
+        if (!xmlStrcmp(cur->name, reinterpret_cast<const xmlChar*>(Trait::collectionTag))) {
+            child = cur->xmlChildrenNode;
+        } else if (!xmlStrcmp(cur->name, reinterpret_cast<const xmlChar*>(Trait::tag))) {
+            child = cur;
         }
-        const xmlNode *child = root;
-        if (!xmlStrcmp(child->name, (const xmlChar *)Trait::collectionTag)) {
-            child = child->xmlChildrenNode;
-        }
-        while (child != NULL) {
-            if (!xmlStrcmp(child->name, (const xmlChar *)Trait::tag)) {
-                typename Trait::PtrElement element;
-                status_t status = Trait::deserialize(doc, child, element, serializingContext);
-                if (status != NO_ERROR) {
-                    return status;
-                }
-                if (collection.add(element) < 0) {
-                    ALOGE("%s: could not add element to %s collection", __FUNCTION__,
-                          Trait::collectionTag);
+        for (; child != NULL; child = child->next) {
+            if (!xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>(Trait::tag))) {
+                auto element = Trait::deserialize(child, serializingContext);
+                if (element.isOk()) {
+                    status_t status = Trait::addElementToCollection(element, collection);
+                    if (status != NO_ERROR) {
+                        ALOGE("%s: could not add element to %s collection", __func__,
+                            Trait::collectionTag);
+                        return status;
+                    }
+                } else {
+                    return BAD_VALUE;
                 }
             }
-            child = child->next;
         }
-        if (!xmlStrcmp(root->name, (const xmlChar *)Trait::tag)) {
+        if (!xmlStrcmp(cur->name, reinterpret_cast<const xmlChar*>(Trait::tag))) {
             return NO_ERROR;
         }
-        root = root->next;
     }
     return NO_ERROR;
 }
 
-const char *const AudioGainTraits::tag = "gain";
-const char *const AudioGainTraits::collectionTag = "gains";
-
-const char AudioGainTraits::Attributes::mode[] = "mode";
-const char AudioGainTraits::Attributes::channelMask[] = "channel_mask";
-const char AudioGainTraits::Attributes::minValueMB[] = "minValueMB";
-const char AudioGainTraits::Attributes::maxValueMB[] = "maxValueMB";
-const char AudioGainTraits::Attributes::defaultValueMB[] = "defaultValueMB";
-const char AudioGainTraits::Attributes::stepValueMB[] = "stepValueMB";
-const char AudioGainTraits::Attributes::minRampMs[] = "minRampMs";
-const char AudioGainTraits::Attributes::maxRampMs[] = "maxRampMs";
-
-status_t AudioGainTraits::deserialize(_xmlDoc */*doc*/, const _xmlNode *root, PtrElement &gain,
-                                      PtrSerializingCtx /*serializingContext*/)
+Return<AudioGainTraits::Element> AudioGainTraits::deserialize(const xmlNode *cur,
+        PtrSerializingCtx /*serializingContext*/)
 {
     static uint32_t index = 0;
-    gain = new Element(index++, true);
+    Element gain = new AudioGain(index++, true);
 
-    string mode = getXmlAttribute(root, Attributes::mode);
+    std::string mode = getXmlAttribute(cur, Attributes::mode);
     if (!mode.empty()) {
         gain->setMode(GainModeConverter::maskFromString(mode));
     }
 
-    string channelsLiteral = getXmlAttribute(root, Attributes::channelMask);
+    std::string channelsLiteral = getXmlAttribute(cur, Attributes::channelMask);
     if (!channelsLiteral.empty()) {
         gain->setChannelMask(channelMaskFromString(channelsLiteral));
     }
 
-    string minValueMBLiteral = getXmlAttribute(root, Attributes::minValueMB);
+    std::string minValueMBLiteral = getXmlAttribute(cur, Attributes::minValueMB);
     int32_t minValueMB;
     if (!minValueMBLiteral.empty() && convertTo(minValueMBLiteral, minValueMB)) {
         gain->setMinValueInMb(minValueMB);
     }
 
-    string maxValueMBLiteral = getXmlAttribute(root, Attributes::maxValueMB);
+    std::string maxValueMBLiteral = getXmlAttribute(cur, Attributes::maxValueMB);
     int32_t maxValueMB;
     if (!maxValueMBLiteral.empty() && convertTo(maxValueMBLiteral, maxValueMB)) {
         gain->setMaxValueInMb(maxValueMB);
     }
 
-    string defaultValueMBLiteral = getXmlAttribute(root, Attributes::defaultValueMB);
+    std::string defaultValueMBLiteral = getXmlAttribute(cur, Attributes::defaultValueMB);
     int32_t defaultValueMB;
     if (!defaultValueMBLiteral.empty() && convertTo(defaultValueMBLiteral, defaultValueMB)) {
         gain->setDefaultValueInMb(defaultValueMB);
     }
 
-    string stepValueMBLiteral = getXmlAttribute(root, Attributes::stepValueMB);
+    std::string stepValueMBLiteral = getXmlAttribute(cur, Attributes::stepValueMB);
     uint32_t stepValueMB;
     if (!stepValueMBLiteral.empty() && convertTo(stepValueMBLiteral, stepValueMB)) {
         gain->setStepValueInMb(stepValueMB);
     }
 
-    string minRampMsLiteral = getXmlAttribute(root, Attributes::minRampMs);
+    std::string minRampMsLiteral = getXmlAttribute(cur, Attributes::minRampMs);
     uint32_t minRampMs;
     if (!minRampMsLiteral.empty() && convertTo(minRampMsLiteral, minRampMs)) {
         gain->setMinRampInMs(minRampMs);
     }
 
-    string maxRampMsLiteral = getXmlAttribute(root, Attributes::maxRampMs);
+    std::string maxRampMsLiteral = getXmlAttribute(cur, Attributes::maxRampMs);
     uint32_t maxRampMs;
     if (!maxRampMsLiteral.empty() && convertTo(maxRampMsLiteral, maxRampMs)) {
         gain->setMaxRampInMs(maxRampMs);
     }
-    ALOGV("%s: adding new gain mode %08x channel mask %08x min mB %d max mB %d", __FUNCTION__,
-          gain->getMode(), gain->getChannelMask(), gain->getMinValueInMb(),
-          gain->getMaxValueInMb());
-
-    if (gain->getMode() == 0) {
-        return BAD_VALUE;
+    std::string useForVolumeLiteral = getXmlAttribute(cur, Attributes::useForVolume);
+    bool useForVolume = false;
+    if (!useForVolumeLiteral.empty() && convertTo(useForVolumeLiteral, useForVolume)) {
+        gain->setUseForVolume(useForVolume);
     }
-    return NO_ERROR;
+    ALOGV("%s: adding new gain mode %08x channel mask %08x min mB %d max mB %d UseForVolume: %d",
+          __func__, gain->getMode(), gain->getChannelMask(), gain->getMinValueInMb(),
+          gain->getMaxValueInMb(), useForVolume);
+
+    if (gain->getMode() != 0) {
+        return gain;
+    } else {
+        return Status::fromStatusT(BAD_VALUE);
+    }
 }
 
-const char *const AudioProfileTraits::collectionTag = "profiles";
-const char *const AudioProfileTraits::tag = "profile";
-
-const char AudioProfileTraits::Attributes::name[] = "name";
-const char AudioProfileTraits::Attributes::samplingRates[] = "samplingRates";
-const char AudioProfileTraits::Attributes::format[] = "format";
-const char AudioProfileTraits::Attributes::channelMasks[] = "channelMasks";
-
-status_t AudioProfileTraits::deserialize(_xmlDoc */*doc*/, const _xmlNode *root, PtrElement &profile,
-                                         PtrSerializingCtx /*serializingContext*/)
+Return<AudioProfileTraits::Element> AudioProfileTraits::deserialize(const xmlNode *cur,
+        PtrSerializingCtx /*serializingContext*/)
 {
-    string samplingRates = getXmlAttribute(root, Attributes::samplingRates);
-    string format = getXmlAttribute(root, Attributes::format);
-    string channels = getXmlAttribute(root, Attributes::channelMasks);
+    std::string samplingRates = getXmlAttribute(cur, Attributes::samplingRates);
+    std::string format = getXmlAttribute(cur, Attributes::format);
+    std::string channels = getXmlAttribute(cur, Attributes::channelMasks);
 
-    profile = new Element(formatFromString(format, gDynamicFormat),
-                          channelMasksFromString(channels, ","),
-                          samplingRatesFromString(samplingRates, ","));
+    Element profile = new AudioProfile(formatFromString(format, gDynamicFormat),
+            channelMasksFromString(channels, ","),
+            samplingRatesFromString(samplingRates, ","));
 
     profile->setDynamicFormat(profile->getFormat() == gDynamicFormat);
     profile->setDynamicChannels(profile->getChannels().isEmpty());
     profile->setDynamicRate(profile->getSampleRates().isEmpty());
 
-    return NO_ERROR;
+    return profile;
 }
 
-
-const char *const MixPortTraits::collectionTag = "mixPorts";
-const char *const MixPortTraits::tag = "mixPort";
-
-const char MixPortTraits::Attributes::name[] = "name";
-const char MixPortTraits::Attributes::role[] = "role";
-const char MixPortTraits::Attributes::flags[] = "flags";
-const char MixPortTraits::Attributes::maxOpenCount[] = "maxOpenCount";
-const char MixPortTraits::Attributes::maxActiveCount[] = "maxActiveCount";
-
-status_t MixPortTraits::deserialize(_xmlDoc *doc, const _xmlNode *child, PtrElement &mixPort,
-                                    PtrSerializingCtx /*serializingContext*/)
+Return<MixPortTraits::Element> MixPortTraits::deserialize(const xmlNode *child,
+        PtrSerializingCtx /*serializingContext*/)
 {
-    string name = getXmlAttribute(child, Attributes::name);
+    std::string name = getXmlAttribute(child, Attributes::name);
     if (name.empty()) {
-        ALOGE("%s: No %s found", __FUNCTION__, Attributes::name);
-        return BAD_VALUE;
+        ALOGE("%s: No %s found", __func__, Attributes::name);
+        return Status::fromStatusT(BAD_VALUE);
     }
-    ALOGV("%s: %s %s=%s", __FUNCTION__, tag, Attributes::name, name.c_str());
-    string role = getXmlAttribute(child, Attributes::role);
+    ALOGV("%s: %s %s=%s", __func__, tag, Attributes::name, name.c_str());
+    std::string role = getXmlAttribute(child, Attributes::role);
     if (role.empty()) {
-        ALOGE("%s: No %s found", __FUNCTION__, Attributes::role);
-        return BAD_VALUE;
+        ALOGE("%s: No %s found", __func__, Attributes::role);
+        return Status::fromStatusT(BAD_VALUE);
     }
-    ALOGV("%s: Role=%s", __FUNCTION__, role.c_str());
-    audio_port_role_t portRole = role == "source" ? AUDIO_PORT_ROLE_SOURCE : AUDIO_PORT_ROLE_SINK;
+    ALOGV("%s: Role=%s", __func__, role.c_str());
+    audio_port_role_t portRole = (role == Attributes::roleSource) ?
+            AUDIO_PORT_ROLE_SOURCE : AUDIO_PORT_ROLE_SINK;
 
-    mixPort = new Element(String8(name.c_str()), portRole);
+    Element mixPort = new IOProfile(String8(name.c_str()), portRole);
 
     AudioProfileTraits::Collection profiles;
-    deserializeCollection<AudioProfileTraits>(doc, child, profiles, NULL);
+    status_t status = deserializeCollection<AudioProfileTraits>(child, &profiles, NULL);
+    if (status != NO_ERROR) {
+        return Status::fromStatusT(status);
+    }
     if (profiles.isEmpty()) {
-        sp <AudioProfile> dynamicProfile = new AudioProfile(gDynamicFormat,
-                                                            ChannelsVector(), SampleRateVector());
-        dynamicProfile->setDynamicFormat(true);
-        dynamicProfile->setDynamicChannels(true);
-        dynamicProfile->setDynamicRate(true);
-        profiles.add(dynamicProfile);
+        profiles.add(AudioProfile::createFullDynamic());
     }
     mixPort->setAudioProfiles(profiles);
 
-    string flags = getXmlAttribute(child, Attributes::flags);
+    std::string flags = getXmlAttribute(child, Attributes::flags);
     if (!flags.empty()) {
         // Source role
         if (portRole == AUDIO_PORT_ROLE_SOURCE) {
@@ -261,52 +452,46 @@
             mixPort->setFlags(InputFlagConverter::maskFromString(flags));
         }
     }
-    string maxOpenCount = getXmlAttribute(child, Attributes::maxOpenCount);
+    std::string maxOpenCount = getXmlAttribute(child, Attributes::maxOpenCount);
     if (!maxOpenCount.empty()) {
         convertTo(maxOpenCount, mixPort->maxOpenCount);
     }
-    string maxActiveCount = getXmlAttribute(child, Attributes::maxActiveCount);
+    std::string maxActiveCount = getXmlAttribute(child, Attributes::maxActiveCount);
     if (!maxActiveCount.empty()) {
         convertTo(maxActiveCount, mixPort->maxActiveCount);
     }
     // Deserialize children
     AudioGainTraits::Collection gains;
-    deserializeCollection<AudioGainTraits>(doc, child, gains, NULL);
+    status = deserializeCollection<AudioGainTraits>(child, &gains, NULL);
+    if (status != NO_ERROR) {
+        return Status::fromStatusT(status);
+    }
     mixPort->setGains(gains);
 
-    return NO_ERROR;
+    return mixPort;
 }
 
-const char *const DevicePortTraits::tag = "devicePort";
-const char *const DevicePortTraits::collectionTag = "devicePorts";
-
-const char DevicePortTraits::Attributes::tagName[] = "tagName";
-const char DevicePortTraits::Attributes::type[] = "type";
-const char DevicePortTraits::Attributes::role[] = "role";
-const char DevicePortTraits::Attributes::address[] = "address";
-const char DevicePortTraits::Attributes::roleSource[] = "source";
-
-status_t DevicePortTraits::deserialize(_xmlDoc *doc, const _xmlNode *root, PtrElement &deviceDesc,
-                                       PtrSerializingCtx /*serializingContext*/)
+Return<DevicePortTraits::Element> DevicePortTraits::deserialize(const xmlNode *cur,
+        PtrSerializingCtx /*serializingContext*/)
 {
-    string name = getXmlAttribute(root, Attributes::tagName);
+    std::string name = getXmlAttribute(cur, Attributes::tagName);
     if (name.empty()) {
-        ALOGE("%s: No %s found", __FUNCTION__, Attributes::tagName);
-        return BAD_VALUE;
+        ALOGE("%s: No %s found", __func__, Attributes::tagName);
+        return Status::fromStatusT(BAD_VALUE);
     }
-    ALOGV("%s: %s %s=%s", __FUNCTION__, tag, Attributes::tagName, name.c_str());
-    string typeName = getXmlAttribute(root, Attributes::type);
+    ALOGV("%s: %s %s=%s", __func__, tag, Attributes::tagName, name.c_str());
+    std::string typeName = getXmlAttribute(cur, Attributes::type);
     if (typeName.empty()) {
-        ALOGE("%s: no type for %s", __FUNCTION__, name.c_str());
-        return BAD_VALUE;
+        ALOGE("%s: no type for %s", __func__, name.c_str());
+        return Status::fromStatusT(BAD_VALUE);
     }
-    ALOGV("%s: %s %s=%s", __FUNCTION__, tag, Attributes::type, typeName.c_str());
-    string role = getXmlAttribute(root, Attributes::role);
+    ALOGV("%s: %s %s=%s", __func__, tag, Attributes::type, typeName.c_str());
+    std::string role = getXmlAttribute(cur, Attributes::role);
     if (role.empty()) {
-        ALOGE("%s: No %s found", __FUNCTION__, Attributes::role);
-        return BAD_VALUE;
+        ALOGE("%s: No %s found", __func__, Attributes::role);
+        return Status::fromStatusT(BAD_VALUE);
     }
-    ALOGV("%s: %s %s=%s", __FUNCTION__, tag, Attributes::role, role.c_str());
+    ALOGV("%s: %s %s=%s", __func__, tag, Attributes::role, role.c_str());
     audio_port_role_t portRole = (role == Attributes::roleSource) ?
                 AUDIO_PORT_ROLE_SOURCE : AUDIO_PORT_ROLE_SINK;
 
@@ -314,338 +499,301 @@
     if (!deviceFromString(typeName, type) ||
             (!audio_is_input_device(type) && portRole == AUDIO_PORT_ROLE_SOURCE) ||
             (!audio_is_output_devices(type) && portRole == AUDIO_PORT_ROLE_SINK)) {
-        ALOGW("%s: bad type %08x", __FUNCTION__, type);
-        return BAD_VALUE;
+        ALOGW("%s: bad type %08x", __func__, type);
+        return Status::fromStatusT(BAD_VALUE);
     }
-    deviceDesc = new Element(type, String8(name.c_str()));
+    std::string encodedFormatsLiteral = getXmlAttribute(cur, Attributes::encodedFormats);
+    ALOGV("%s: %s %s=%s", __func__, tag, Attributes::encodedFormats, encodedFormatsLiteral.c_str());
+    FormatVector encodedFormats;
+    if (!encodedFormatsLiteral.empty()) {
+        encodedFormats = formatsFromString(encodedFormatsLiteral, " ");
+    }
+    Element deviceDesc = new DeviceDescriptor(type, encodedFormats, String8(name.c_str()));
 
-    string address = getXmlAttribute(root, Attributes::address);
+    std::string address = getXmlAttribute(cur, Attributes::address);
     if (!address.empty()) {
-        ALOGV("%s: address=%s for %s", __FUNCTION__, address.c_str(), name.c_str());
-        deviceDesc->mAddress = String8(address.c_str());
+        ALOGV("%s: address=%s for %s", __func__, address.c_str(), name.c_str());
+        deviceDesc->setAddress(String8(address.c_str()));
     }
 
     AudioProfileTraits::Collection profiles;
-    deserializeCollection<AudioProfileTraits>(doc, root, profiles, NULL);
+    status_t status = deserializeCollection<AudioProfileTraits>(cur, &profiles, NULL);
+    if (status != NO_ERROR) {
+        return Status::fromStatusT(status);
+    }
     if (profiles.isEmpty()) {
-        sp <AudioProfile> dynamicProfile = new AudioProfile(gDynamicFormat,
-                                                            ChannelsVector(), SampleRateVector());
-        dynamicProfile->setDynamicFormat(true);
-        dynamicProfile->setDynamicChannels(true);
-        dynamicProfile->setDynamicRate(true);
-        profiles.add(dynamicProfile);
+        profiles.add(AudioProfile::createFullDynamic());
     }
     deviceDesc->setAudioProfiles(profiles);
 
     // Deserialize AudioGain children
-    deserializeCollection<AudioGainTraits>(doc, root, deviceDesc->mGains, NULL);
-    ALOGV("%s: adding device tag %s type %08x address %s", __FUNCTION__,
-          deviceDesc->getName().string(), type, deviceDesc->mAddress.string());
-    return NO_ERROR;
+    status = deserializeCollection<AudioGainTraits>(cur, &deviceDesc->mGains, NULL);
+    if (status != NO_ERROR) {
+        return Status::fromStatusT(status);
+    }
+    ALOGV("%s: adding device tag %s type %08x address %s", __func__,
+          deviceDesc->getName().string(), type, deviceDesc->address().string());
+    return deviceDesc;
 }
 
-const char *const RouteTraits::tag = "route";
-const char *const RouteTraits::collectionTag = "routes";
-
-const char RouteTraits::Attributes::type[] = "type";
-const char RouteTraits::Attributes::typeMix[] = "mix";
-const char RouteTraits::Attributes::sink[] = "sink";
-const char RouteTraits::Attributes::sources[] = "sources";
-
-
-status_t RouteTraits::deserialize(_xmlDoc */*doc*/, const _xmlNode *root, PtrElement &element,
-                                  PtrSerializingCtx ctx)
+Return<RouteTraits::Element> RouteTraits::deserialize(const xmlNode *cur, PtrSerializingCtx ctx)
 {
-    string type = getXmlAttribute(root, Attributes::type);
+    std::string type = getXmlAttribute(cur, Attributes::type);
     if (type.empty()) {
-        ALOGE("%s: No %s found", __FUNCTION__, Attributes::type);
-        return BAD_VALUE;
+        ALOGE("%s: No %s found", __func__, Attributes::type);
+        return Status::fromStatusT(BAD_VALUE);
     }
     audio_route_type_t routeType = (type == Attributes::typeMix) ?
                 AUDIO_ROUTE_MIX : AUDIO_ROUTE_MUX;
 
-    ALOGV("%s: %s %s=%s", __FUNCTION__, tag, Attributes::type, type.c_str());
-    element = new Element(routeType);
+    ALOGV("%s: %s %s=%s", __func__, tag, Attributes::type, type.c_str());
+    Element route = new AudioRoute(routeType);
 
-    string sinkAttr = getXmlAttribute(root, Attributes::sink);
+    std::string sinkAttr = getXmlAttribute(cur, Attributes::sink);
     if (sinkAttr.empty()) {
-        ALOGE("%s: No %s found", __FUNCTION__, Attributes::sink);
-        return BAD_VALUE;
+        ALOGE("%s: No %s found", __func__, Attributes::sink);
+        return Status::fromStatusT(BAD_VALUE);
     }
     // Convert Sink name to port pointer
     sp<AudioPort> sink = ctx->findPortByTagName(String8(sinkAttr.c_str()));
     if (sink == NULL) {
-        ALOGE("%s: no sink found with name=%s", __FUNCTION__, sinkAttr.c_str());
-        return BAD_VALUE;
+        ALOGE("%s: no sink found with name=%s", __func__, sinkAttr.c_str());
+        return Status::fromStatusT(BAD_VALUE);
     }
-    element->setSink(sink);
+    route->setSink(sink);
 
-    string sourcesAttr = getXmlAttribute(root, Attributes::sources);
+    std::string sourcesAttr = getXmlAttribute(cur, Attributes::sources);
     if (sourcesAttr.empty()) {
-        ALOGE("%s: No %s found", __FUNCTION__, Attributes::sources);
-        return BAD_VALUE;
+        ALOGE("%s: No %s found", __func__, Attributes::sources);
+        return Status::fromStatusT(BAD_VALUE);
     }
     // Tokenize and Convert Sources name to port pointer
     AudioPortVector sources;
-    char *sourcesLiteral = strndup(sourcesAttr.c_str(), strlen(sourcesAttr.c_str()));
-    char *devTag = strtok(sourcesLiteral, ",");
+    std::unique_ptr<char[]> sourcesLiteral{strndup(
+                sourcesAttr.c_str(), strlen(sourcesAttr.c_str()))};
+    char *devTag = strtok(sourcesLiteral.get(), ",");
     while (devTag != NULL) {
         if (strlen(devTag) != 0) {
             sp<AudioPort> source = ctx->findPortByTagName(String8(devTag));
             if (source == NULL) {
-                ALOGE("%s: no source found with name=%s", __FUNCTION__, devTag);
-                free(sourcesLiteral);
-                return BAD_VALUE;
+                ALOGE("%s: no source found with name=%s", __func__, devTag);
+                return Status::fromStatusT(BAD_VALUE);
             }
             sources.add(source);
         }
         devTag = strtok(NULL, ",");
     }
-    free(sourcesLiteral);
 
-    sink->addRoute(element);
+    sink->addRoute(route);
     for (size_t i = 0; i < sources.size(); i++) {
         sp<AudioPort> source = sources.itemAt(i);
-        source->addRoute(element);
+        source->addRoute(route);
     }
-    element->setSources(sources);
-    return NO_ERROR;
+    route->setSources(sources);
+    return route;
 }
 
-const char *const ModuleTraits::childAttachedDevicesTag = "attachedDevices";
-const char *const ModuleTraits::childAttachedDeviceTag = "item";
-const char *const ModuleTraits::childDefaultOutputDeviceTag = "defaultOutputDevice";
-
-const char *const ModuleTraits::tag = "module";
-const char *const ModuleTraits::collectionTag = "modules";
-
-const char ModuleTraits::Attributes::name[] = "name";
-const char ModuleTraits::Attributes::version[] = "halVersion";
-
-status_t ModuleTraits::deserialize(xmlDocPtr doc, const xmlNode *root, PtrElement &module,
-                                   PtrSerializingCtx ctx)
+Return<ModuleTraits::Element> ModuleTraits::deserialize(const xmlNode *cur, PtrSerializingCtx ctx)
 {
-    string name = getXmlAttribute(root, Attributes::name);
+    std::string name = getXmlAttribute(cur, Attributes::name);
     if (name.empty()) {
-        ALOGE("%s: No %s found", __FUNCTION__, Attributes::name);
-        return BAD_VALUE;
+        ALOGE("%s: No %s found", __func__, Attributes::name);
+        return Status::fromStatusT(BAD_VALUE);
     }
     uint32_t versionMajor = 0, versionMinor = 0;
-    string versionLiteral = getXmlAttribute(root, Attributes::version);
+    std::string versionLiteral = getXmlAttribute(cur, Attributes::version);
     if (!versionLiteral.empty()) {
         sscanf(versionLiteral.c_str(), "%u.%u", &versionMajor, &versionMinor);
-        ALOGV("%s: mHalVersion = major %u minor %u",  __FUNCTION__,
+        ALOGV("%s: mHalVersion = major %u minor %u",  __func__,
               versionMajor, versionMajor);
     }
 
-    ALOGV("%s: %s %s=%s", __FUNCTION__, tag, Attributes::name, name.c_str());
+    ALOGV("%s: %s %s=%s", __func__, tag, Attributes::name, name.c_str());
 
-    module = new Element(name.c_str(), versionMajor, versionMinor);
+    Element module = new HwModule(name.c_str(), versionMajor, versionMinor);
 
     // Deserialize childrens: Audio Mix Port, Audio Device Ports (Source/Sink), Audio Routes
     MixPortTraits::Collection mixPorts;
-    deserializeCollection<MixPortTraits>(doc, root, mixPorts, NULL);
+    status_t status = deserializeCollection<MixPortTraits>(cur, &mixPorts, NULL);
+    if (status != NO_ERROR) {
+        return Status::fromStatusT(status);
+    }
     module->setProfiles(mixPorts);
 
     DevicePortTraits::Collection devicePorts;
-    deserializeCollection<DevicePortTraits>(doc, root, devicePorts, NULL);
+    status = deserializeCollection<DevicePortTraits>(cur, &devicePorts, NULL);
+    if (status != NO_ERROR) {
+        return Status::fromStatusT(status);
+    }
     module->setDeclaredDevices(devicePorts);
 
     RouteTraits::Collection routes;
-    deserializeCollection<RouteTraits>(doc, root, routes, module.get());
+    status = deserializeCollection<RouteTraits>(cur, &routes, module.get());
+    if (status != NO_ERROR) {
+        return Status::fromStatusT(status);
+    }
     module->setRoutes(routes);
 
-    const xmlNode *children = root->xmlChildrenNode;
-    while (children != NULL) {
-        if (!xmlStrcmp(children->name, (const xmlChar *)childAttachedDevicesTag)) {
-            ALOGV("%s: %s %s found", __FUNCTION__, tag, childAttachedDevicesTag);
-            const xmlNode *child = children->xmlChildrenNode;
-            while (child != NULL) {
-                if (!xmlStrcmp(child->name, (const xmlChar *)childAttachedDeviceTag)) {
-                    xmlChar *attachedDevice = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);
-                    if (attachedDevice != NULL) {
-                        ALOGV("%s: %s %s=%s", __FUNCTION__, tag, childAttachedDeviceTag,
-                              (const char*)attachedDevice);
-                        sp<DeviceDescriptor> device =
-                                module->getDeclaredDevices().getDeviceFromTagName(String8((const char*)attachedDevice));
+    for (const xmlNode *children = cur->xmlChildrenNode; children != NULL;
+         children = children->next) {
+        if (!xmlStrcmp(children->name, reinterpret_cast<const xmlChar*>(childAttachedDevicesTag))) {
+            ALOGV("%s: %s %s found", __func__, tag, childAttachedDevicesTag);
+            for (const xmlNode *child = children->xmlChildrenNode; child != NULL;
+                 child = child->next) {
+                if (!xmlStrcmp(child->name,
+                                reinterpret_cast<const xmlChar*>(childAttachedDeviceTag))) {
+                    auto attachedDevice = make_xmlUnique(xmlNodeListGetString(
+                                    child->doc, child->xmlChildrenNode, 1));
+                    if (attachedDevice != nullptr) {
+                        ALOGV("%s: %s %s=%s", __func__, tag, childAttachedDeviceTag,
+                                reinterpret_cast<const char*>(attachedDevice.get()));
+                        sp<DeviceDescriptor> device = module->getDeclaredDevices().
+                                getDeviceFromTagName(String8(reinterpret_cast<const char*>(
+                                                        attachedDevice.get())));
                         ctx->addAvailableDevice(device);
-                        xmlFree(attachedDevice);
                     }
                 }
-                child = child->next;
             }
         }
-        if (!xmlStrcmp(children->name, (const xmlChar *)childDefaultOutputDeviceTag)) {
-            xmlChar *defaultOutputDevice = xmlNodeListGetString(doc, children->xmlChildrenNode, 1);;
-            if (defaultOutputDevice != NULL) {
-                ALOGV("%s: %s %s=%s", __FUNCTION__, tag, childDefaultOutputDeviceTag,
-                      (const char*)defaultOutputDevice);
-                sp<DeviceDescriptor> device =
-                        module->getDeclaredDevices().getDeviceFromTagName(String8((const char*)defaultOutputDevice));
+        if (!xmlStrcmp(children->name,
+                        reinterpret_cast<const xmlChar*>(childDefaultOutputDeviceTag))) {
+            auto defaultOutputDevice = make_xmlUnique(xmlNodeListGetString(
+                            children->doc, children->xmlChildrenNode, 1));
+            if (defaultOutputDevice != nullptr) {
+                ALOGV("%s: %s %s=%s", __func__, tag, childDefaultOutputDeviceTag,
+                        reinterpret_cast<const char*>(defaultOutputDevice.get()));
+                sp<DeviceDescriptor> device = module->getDeclaredDevices().getDeviceFromTagName(
+                        String8(reinterpret_cast<const char*>(defaultOutputDevice.get())));
                 if (device != 0 && ctx->getDefaultOutputDevice() == 0) {
                     ctx->setDefaultOutputDevice(device);
-                    ALOGV("%s: default is %08x", __FUNCTION__, ctx->getDefaultOutputDevice()->type());
+                    ALOGV("%s: default is %08x",
+                            __func__, ctx->getDefaultOutputDevice()->type());
                 }
-                xmlFree(defaultOutputDevice);
             }
         }
-        children = children->next;
     }
-    return NO_ERROR;
+    return module;
 }
 
-const char *const GlobalConfigTraits::tag = "globalConfiguration";
-
-const char GlobalConfigTraits::Attributes::speakerDrcEnabled[] = "speaker_drc_enabled";
-
-
-status_t GlobalConfigTraits::deserialize(const xmlNode *cur, AudioPolicyConfig &config)
+status_t GlobalConfigTraits::deserialize(const xmlNode *root, AudioPolicyConfig *config)
 {
-    const xmlNode *root = cur->xmlChildrenNode;
-    while (root != NULL) {
-        if (!xmlStrcmp(root->name, (const xmlChar *)tag)) {
-            string speakerDrcEnabled =
-                    getXmlAttribute(root, Attributes::speakerDrcEnabled);
+    for (const xmlNode *cur = root->xmlChildrenNode; cur != NULL; cur = cur->next) {
+        if (!xmlStrcmp(cur->name, reinterpret_cast<const xmlChar*>(tag))) {
+            std::string speakerDrcEnabled =
+                    getXmlAttribute(cur, Attributes::speakerDrcEnabled);
             bool isSpeakerDrcEnabled;
             if (!speakerDrcEnabled.empty() &&
-                    convertTo<string, bool>(speakerDrcEnabled, isSpeakerDrcEnabled)) {
-                config.setSpeakerDrcEnabled(isSpeakerDrcEnabled);
+                    convertTo<std::string, bool>(speakerDrcEnabled, isSpeakerDrcEnabled)) {
+                config->setSpeakerDrcEnabled(isSpeakerDrcEnabled);
             }
             return NO_ERROR;
         }
-        root = root->next;
     }
     return NO_ERROR;
 }
 
-
-const char *const VolumeTraits::tag = "volume";
-const char *const VolumeTraits::collectionTag = "volumes";
-const char *const VolumeTraits::volumePointTag = "point";
-
-const char VolumeTraits::Attributes::stream[] = "stream";
-const char VolumeTraits::Attributes::deviceCategory[] = "deviceCategory";
-const char VolumeTraits::Attributes::reference[] = "ref";
-
-status_t VolumeTraits::deserialize(_xmlDoc *doc, const _xmlNode *root, PtrElement &element,
-                                   PtrSerializingCtx /*serializingContext*/)
+status_t SurroundSoundTraits::deserialize(const xmlNode *root, AudioPolicyConfig *config)
 {
-    string streamTypeLiteral = getXmlAttribute(root, Attributes::stream);
-    if (streamTypeLiteral.empty()) {
-        ALOGE("%s: No %s found", __FUNCTION__, Attributes::stream);
-        return BAD_VALUE;
-    }
-    audio_stream_type_t streamType;
-    if (!StreamTypeConverter::fromString(streamTypeLiteral, streamType)) {
-        ALOGE("%s: Invalid %s", __FUNCTION__, Attributes::stream);
-        return BAD_VALUE;
-    }
-    string deviceCategoryLiteral = getXmlAttribute(root, Attributes::deviceCategory);
-    if (deviceCategoryLiteral.empty()) {
-        ALOGE("%s: No %s found", __FUNCTION__, Attributes::deviceCategory);
-        return BAD_VALUE;
-    }
-    device_category deviceCategory;
-    if (!DeviceCategoryConverter::fromString(deviceCategoryLiteral, deviceCategory)) {
-        ALOGE("%s: Invalid %s=%s", __FUNCTION__, Attributes::deviceCategory,
-              deviceCategoryLiteral.c_str());
-        return BAD_VALUE;
-    }
+    config->setDefaultSurroundFormats();
 
-    string referenceName = getXmlAttribute(root, Attributes::reference);
-    const _xmlNode *ref = NULL;
-    if (!referenceName.empty()) {
-        getReference<VolumeTraits>(root->parent, ref, referenceName);
-        if (ref == NULL) {
-            ALOGE("%s: No reference Ptr found for %s", __FUNCTION__, referenceName.c_str());
-            return BAD_VALUE;
-        }
-    }
-
-    element = new Element(deviceCategory, streamType);
-
-    const xmlNode *child = referenceName.empty() ? root->xmlChildrenNode : ref->xmlChildrenNode;
-    while (child != NULL) {
-        if (!xmlStrcmp(child->name, (const xmlChar *)volumePointTag)) {
-            xmlChar *pointDefinition = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);;
-            if (pointDefinition == NULL) {
-                return BAD_VALUE;
+    for (const xmlNode *cur = root->xmlChildrenNode; cur != NULL; cur = cur->next) {
+        if (!xmlStrcmp(cur->name, reinterpret_cast<const xmlChar*>(tag))) {
+            AudioPolicyConfig::SurroundFormats formats;
+            status_t status = deserializeCollection<SurroundSoundFormatTraits>(
+                    cur, &formats, nullptr);
+            if (status == NO_ERROR) {
+                config->setSurroundFormats(formats);
             }
-            ALOGV("%s: %s=%s", __FUNCTION__, tag, (const char*)pointDefinition);
-            Vector<int32_t> point;
-            collectionFromString<DefaultTraits<int32_t> >((const char*)pointDefinition, point, ",");
-            if (point.size() != 2) {
-                ALOGE("%s: Invalid %s: %s", __FUNCTION__, volumePointTag,
-                      (const char*)pointDefinition);
-                return BAD_VALUE;
-            }
-            element->add(CurvePoint(point[0], point[1]));
-            xmlFree(pointDefinition);
+            return NO_ERROR;
         }
-        child = child->next;
     }
     return NO_ERROR;
 }
 
-PolicySerializer::PolicySerializer() : mRootElementName(rootName)
+Return<SurroundSoundFormatTraits::Element> SurroundSoundFormatTraits::deserialize(
+        const xmlNode *cur, PtrSerializingCtx /*serializingContext*/)
 {
-    std::ostringstream oss;
-    oss << gMajor << "." << gMinor;
-    mVersion = oss.str();
-    ALOGV("%s: Version=%s Root=%s", __FUNCTION__, mVersion.c_str(), mRootElementName.c_str());
+    std::string formatLiteral = getXmlAttribute(cur, Attributes::name);
+    if (formatLiteral.empty()) {
+        ALOGE("%s: No %s found for a surround format", __func__, Attributes::name);
+        return Status::fromStatusT(BAD_VALUE);
+    }
+    audio_format_t format = formatFromString(formatLiteral);
+    if (format == AUDIO_FORMAT_DEFAULT) {
+        ALOGE("%s: Unrecognized format %s", __func__, formatLiteral.c_str());
+        return Status::fromStatusT(BAD_VALUE);
+    }
+    Element pair = std::make_pair(format, Collection::mapped_type{});
+
+    std::string subformatsLiteral = getXmlAttribute(cur, Attributes::subformats);
+    if (subformatsLiteral.empty()) return pair;
+    FormatVector subformats = formatsFromString(subformatsLiteral, " ");
+    for (const auto& subformat : subformats) {
+        auto result = pair.second.insert(subformat);
+        if (!result.second) {
+            ALOGE("%s: could not add subformat %x to collection", __func__, subformat);
+            return Status::fromStatusT(BAD_VALUE);
+        }
+    }
+    return pair;
 }
 
-status_t PolicySerializer::deserialize(const char *configFile, AudioPolicyConfig &config)
+status_t PolicySerializer::deserialize(const char *configFile, AudioPolicyConfig *config)
 {
-    xmlDocPtr doc;
-    doc = xmlParseFile(configFile);
-    if (doc == NULL) {
-        ALOGE("%s: Could not parse %s document.", __FUNCTION__, configFile);
+    auto doc = make_xmlUnique(xmlParseFile(configFile));
+    if (doc == nullptr) {
+        ALOGE("%s: Could not parse %s document.", __func__, configFile);
         return BAD_VALUE;
     }
-    xmlNodePtr cur = xmlDocGetRootElement(doc);
-    if (cur == NULL) {
-        ALOGE("%s: Could not parse %s document: empty.", __FUNCTION__, configFile);
-        xmlFreeDoc(doc);
+    xmlNodePtr root = xmlDocGetRootElement(doc.get());
+    if (root == NULL) {
+        ALOGE("%s: Could not parse %s document: empty.", __func__, configFile);
         return BAD_VALUE;
     }
-    if (xmlXIncludeProcess(doc) < 0) {
-         ALOGE("%s: libxml failed to resolve XIncludes on %s document.", __FUNCTION__, configFile);
+    if (xmlXIncludeProcess(doc.get()) < 0) {
+        ALOGE("%s: libxml failed to resolve XIncludes on %s document.", __func__, configFile);
     }
 
-    if (xmlStrcmp(cur->name, (const xmlChar *) mRootElementName.c_str()))  {
-        ALOGE("%s: No %s root element found in xml data %s.", __FUNCTION__, mRootElementName.c_str(),
-              (const char *)cur->name);
-        xmlFreeDoc(doc);
+    if (xmlStrcmp(root->name, reinterpret_cast<const xmlChar*>(rootName)))  {
+        ALOGE("%s: No %s root element found in xml data %s.", __func__, rootName,
+                reinterpret_cast<const char*>(root->name));
         return BAD_VALUE;
     }
 
-    string version = getXmlAttribute(cur, versionAttribute);
+    std::string version = getXmlAttribute(root, versionAttribute);
     if (version.empty()) {
-        ALOGE("%s: No version found in root node %s", __FUNCTION__, mRootElementName.c_str());
+        ALOGE("%s: No version found in root node %s", __func__, rootName);
         return BAD_VALUE;
     }
     if (version != mVersion) {
-        ALOGE("%s: Version does not match; expect %s got %s", __FUNCTION__, mVersion.c_str(),
+        ALOGE("%s: Version does not match; expect %s got %s", __func__, mVersion.c_str(),
               version.c_str());
         return BAD_VALUE;
     }
     // Lets deserialize children
     // Modules
     ModuleTraits::Collection modules;
-    deserializeCollection<ModuleTraits>(doc, cur, modules, &config);
-    config.setHwModules(modules);
-
-    // deserialize volume section
-    VolumeTraits::Collection volumes;
-    deserializeCollection<VolumeTraits>(doc, cur, volumes, &config);
-    config.setVolumes(volumes);
+    status_t status = deserializeCollection<ModuleTraits>(root, &modules, config);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    config->setHwModules(modules);
 
     // Global Configuration
-    GlobalConfigTraits::deserialize(cur, config);
+    GlobalConfigTraits::deserialize(root, config);
 
-    xmlFreeDoc(doc);
+    // Surround configuration
+    SurroundSoundTraits::deserialize(root, config);
+
     return android::OK;
 }
 
+}  // namespace
+
+status_t deserializeAudioPolicyFile(const char *fileName, AudioPolicyConfig *config)
+{
+    PolicySerializer serializer;
+    return serializer.deserialize(fileName, config);
+}
+
 } // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/SessionRoute.cpp b/services/audiopolicy/common/managerdefinitions/src/SessionRoute.cpp
deleted file mode 100644
index 2206526..0000000
--- a/services/audiopolicy/common/managerdefinitions/src/SessionRoute.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "APM_SessionRoute"
-//#define LOG_NDEBUG 0
-
-#include "SessionRoute.h"
-#include "HwModule.h"
-#include "AudioGain.h"
-#include "DeviceDescriptor.h"
-#include <utils/Log.h>
-
-namespace android {
-
-// --- SessionRoute class implementation
-void SessionRoute::log(const char* prefix)
-{
-    ALOGI("%s[SessionRoute strm:0x%X, src:%d, sess:0x%X, dev:0x%X refs:%d act:%d",
-          prefix, mStreamType, mSource, mSession,
-          mDeviceDescriptor != 0 ? mDeviceDescriptor->type() : AUDIO_DEVICE_NONE,
-          mRefCount, mActivityCount);
-}
-
-// --- SessionRouteMap class implementation
-bool SessionRouteMap::hasRoute(audio_session_t session)
-{
-    return indexOfKey(session) >= 0 && valueFor(session)->mDeviceDescriptor != 0;
-}
-
-bool SessionRouteMap::getAndClearRouteChanged(audio_session_t session)
-{
-    if (indexOfKey(session) >= 0) {
-        if (valueFor(session)->mChanged) {
-            valueFor(session)->mChanged = false;
-            return true;
-        }
-    }
-    return false;
-}
-
-void SessionRouteMap::removeRoute(audio_session_t session)
-{
-    sp<SessionRoute> route = indexOfKey(session) >= 0 ? valueFor(session) : 0;
-    if (route != 0) {
-        ALOG_ASSERT(route->mRefCount > 0);
-        --route->mRefCount;
-        if (route->mRefCount <= 0) {
-            removeItem(session);
-        }
-    }
-}
-
-int SessionRouteMap::incRouteActivity(audio_session_t session)
-{
-    sp<SessionRoute> route = indexOfKey(session) >= 0 ? valueFor(session) : 0;
-    return route != 0 ? ++(route->mActivityCount) : -1;
-}
-
-int SessionRouteMap::decRouteActivity(audio_session_t session)
-{
-    sp<SessionRoute> route = indexOfKey(session) >= 0 ? valueFor(session) : 0;
-    if (route != 0 && route->mActivityCount > 0) {
-        return --(route->mActivityCount);
-    } else {
-        return -1;
-    }
-}
-
-void SessionRouteMap::log(const char* caption)
-{
-    ALOGI("%s ----", caption);
-    for (size_t index = 0; index < size(); index++) {
-        valueAt(index)->log("  ");
-    }
-}
-
-void SessionRouteMap::addRoute(audio_session_t session,
-                               audio_stream_type_t streamType,
-                               audio_source_t source,
-                               const sp<DeviceDescriptor>& descriptor,
-                               uid_t uid)
-{
-    if (mMapType == MAPTYPE_INPUT && streamType != SessionRoute::STREAM_TYPE_NA) {
-        ALOGE("Adding Output Route to InputRouteMap");
-        return;
-    } else if (mMapType == MAPTYPE_OUTPUT && source != SessionRoute::SOURCE_TYPE_NA) {
-        ALOGE("Adding Input Route to OutputRouteMap");
-        return;
-    }
-
-    sp<SessionRoute> route = indexOfKey(session) >= 0 ? valueFor(session) : 0;
-
-    if (route != 0) {
-        if (descriptor != 0 || route->mDeviceDescriptor != 0) {
-            route->mChanged = true;
-        }
-        route->mRefCount++;
-        route->mDeviceDescriptor = descriptor;
-    } else {
-        route = new SessionRoute(session, streamType, source, descriptor, uid);
-        route->mRefCount++;
-        if (descriptor != 0) {
-            route->mChanged = true;
-        }
-        add(session, route);
-    }
-}
-
-audio_devices_t SessionRouteMap::getActiveDeviceForStream(audio_stream_type_t streamType,
-                                                          const DeviceVector& availableDevices)
-{
-    for (size_t index = 0; index < size(); index++) {
-        sp<SessionRoute> route = valueAt(index);
-        if (streamType == route->mStreamType && route->isActiveOrChanged()
-                && route->mDeviceDescriptor != 0) {
-            audio_devices_t device = route->mDeviceDescriptor->type();
-            if (!availableDevices.getDevicesFromType(device).isEmpty()) {
-                return device;
-            }
-        }
-    }
-    return AUDIO_DEVICE_NONE;
-}
-
-} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/StreamDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/StreamDescriptor.cpp
deleted file mode 100644
index 65649fb..0000000
--- a/services/audiopolicy/common/managerdefinitions/src/StreamDescriptor.cpp
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "APM::Volumes"
-//#define LOG_NDEBUG 0
-
-//#define VERY_VERBOSE_LOGGING
-#ifdef VERY_VERBOSE_LOGGING
-#define ALOGVV ALOGV
-#else
-#define ALOGVV(a...) do { } while(0)
-#endif
-
-#include "StreamDescriptor.h"
-#include "Gains.h"
-#include "policy.h"
-#include <utils/Log.h>
-#include <utils/String8.h>
-
-namespace android {
-
-// --- StreamDescriptor class implementation
-
-StreamDescriptor::StreamDescriptor()
-    :   mIndexMin(0), mIndexMax(1), mCanBeMuted(true)
-{
-    // Initialize the current stream's index to mIndexMax so volume isn't 0 in
-    // cases where the Java layer doesn't call into the audio policy service to
-    // set the default volume.
-    mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, mIndexMax);
-}
-
-int StreamDescriptor::getVolumeIndex(audio_devices_t device) const
-{
-    device = Volume::getDeviceForVolume(device);
-    // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME
-    if (mIndexCur.indexOfKey(device) < 0) {
-        device = AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME;
-    }
-    return mIndexCur.valueFor(device);
-}
-
-void StreamDescriptor::clearCurrentVolumeIndex()
-{
-    mIndexCur.clear();
-}
-
-void StreamDescriptor::addCurrentVolumeIndex(audio_devices_t device, int index)
-{
-    mIndexCur.add(device, index);
-}
-
-void StreamDescriptor::setVolumeIndexMin(int volIndexMin)
-{
-    mIndexMin = volIndexMin;
-}
-
-void StreamDescriptor::setVolumeIndexMax(int volIndexMax)
-{
-    mIndexMax = volIndexMax;
-}
-
-void StreamDescriptor::setVolumeCurvePoint(device_category deviceCategory,
-                                           const VolumeCurvePoint *point)
-{
-    mVolumeCurve[deviceCategory] = point;
-}
-
-void StreamDescriptor::dump(int fd) const
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "%s         %02d         %02d         ",
-             mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax);
-    result.append(buffer);
-    for (size_t i = 0; i < mIndexCur.size(); i++) {
-        snprintf(buffer, SIZE, "%04x : %02d, ",
-                 mIndexCur.keyAt(i),
-                 mIndexCur.valueAt(i));
-        result.append(buffer);
-    }
-    result.append("\n");
-
-    write(fd, result.string(), result.size());
-}
-
-StreamDescriptorCollection::StreamDescriptorCollection()
-{
-    for (size_t stream = 0 ; stream < AUDIO_STREAM_CNT; stream++) {
-        add(static_cast<audio_stream_type_t>(stream), StreamDescriptor());
-    }
-}
-
-bool StreamDescriptorCollection::canBeMuted(audio_stream_type_t stream)
-{
-    return valueAt(stream).canBeMuted();
-}
-
-void StreamDescriptorCollection::clearCurrentVolumeIndex(audio_stream_type_t stream)
-{
-    editValueAt(stream).clearCurrentVolumeIndex();
-}
-
-void StreamDescriptorCollection::addCurrentVolumeIndex(audio_stream_type_t stream,
-                                                       audio_devices_t device, int index)
-{
-    editValueAt(stream).addCurrentVolumeIndex(device, index);
-}
-
-void StreamDescriptorCollection::setVolumeCurvePoint(audio_stream_type_t stream,
-                                                     device_category deviceCategory,
-                                                     const VolumeCurvePoint *point)
-{
-    editValueAt(stream).setVolumeCurvePoint(deviceCategory, point);
-}
-
-const VolumeCurvePoint *StreamDescriptorCollection::getVolumeCurvePoint(audio_stream_type_t stream,
-                                                                        device_category deviceCategory) const
-{
-    return valueAt(stream).getVolumeCurvePoint(deviceCategory);
-}
-
-void StreamDescriptorCollection::setVolumeIndexMin(audio_stream_type_t stream,int volIndexMin)
-{
-    return editValueAt(stream).setVolumeIndexMin(volIndexMin);
-}
-
-void StreamDescriptorCollection::setVolumeIndexMax(audio_stream_type_t stream,int volIndexMax)
-{
-    return editValueAt(stream).setVolumeIndexMax(volIndexMax);
-}
-
-float StreamDescriptorCollection::volIndexToDb(audio_stream_type_t stream, device_category category,
-                                               int indexInUi) const
-{
-    const StreamDescriptor &streamDesc = valueAt(stream);
-    return Gains::volIndexToDb(streamDesc.getVolumeCurvePoint(category),
-                               streamDesc.getVolumeIndexMin(), streamDesc.getVolumeIndexMax(),
-                               indexInUi);
-}
-
-status_t StreamDescriptorCollection::initStreamVolume(audio_stream_type_t stream,
-                                                      int indexMin, int indexMax)
-{
-    ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
-    if (indexMin < 0 || indexMin >= indexMax) {
-        ALOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d",
-              stream , indexMin, indexMax);
-        return BAD_VALUE;
-    }
-    setVolumeIndexMin(stream, indexMin);
-    setVolumeIndexMax(stream, indexMax);
-    return NO_ERROR;
-}
-
-void StreamDescriptorCollection::initializeVolumeCurves(bool isSpeakerDrcEnabled)
-{
-    for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
-        for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
-            setVolumeCurvePoint(static_cast<audio_stream_type_t>(i),
-                                static_cast<device_category>(j),
-                                Gains::sVolumeProfiles[i][j]);
-        }
-    }
-
-    // Check availability of DRC on speaker path: if available, override some of the speaker curves
-    if (isSpeakerDrcEnabled) {
-        setVolumeCurvePoint(AUDIO_STREAM_SYSTEM, DEVICE_CATEGORY_SPEAKER,
-                            Gains::sDefaultSystemVolumeCurveDrc);
-        setVolumeCurvePoint(AUDIO_STREAM_RING, DEVICE_CATEGORY_SPEAKER,
-                            Gains::sSpeakerSonificationVolumeCurveDrc);
-        setVolumeCurvePoint(AUDIO_STREAM_ALARM, DEVICE_CATEGORY_SPEAKER,
-                            Gains::sSpeakerSonificationVolumeCurveDrc);
-        setVolumeCurvePoint(AUDIO_STREAM_NOTIFICATION, DEVICE_CATEGORY_SPEAKER,
-                            Gains::sSpeakerSonificationVolumeCurveDrc);
-        setVolumeCurvePoint(AUDIO_STREAM_MUSIC, DEVICE_CATEGORY_SPEAKER,
-                            Gains::sSpeakerMediaVolumeCurveDrc);
-        setVolumeCurvePoint(AUDIO_STREAM_ACCESSIBILITY, DEVICE_CATEGORY_SPEAKER,
-                            Gains::sSpeakerMediaVolumeCurveDrc);
-    }
-}
-
-void StreamDescriptorCollection::switchVolumeCurve(audio_stream_type_t streamSrc,
-                                                   audio_stream_type_t streamDst)
-{
-    for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
-        setVolumeCurvePoint(streamDst, static_cast<device_category>(j),
-                            Gains::sVolumeProfiles[streamSrc][j]);
-    }
-}
-
-status_t StreamDescriptorCollection::dump(int fd) const
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE, "\nStreams dump:\n");
-    write(fd, buffer, strlen(buffer));
-    snprintf(buffer, SIZE,
-             " Stream  Can be muted  Index Min  Index Max  Index Cur [device : index]...\n");
-    write(fd, buffer, strlen(buffer));
-    for (size_t i = 0; i < size(); i++) {
-        snprintf(buffer, SIZE, " %02zu      ", i);
-        write(fd, buffer, strlen(buffer));
-        valueAt(i).dump(fd);
-    }
-
-    return NO_ERROR;
-}
-
-} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp b/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp
index 6f48eae..2b5455e 100644
--- a/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp
@@ -45,13 +45,13 @@
 const RouteFlagTypeConverter::Table RouteFlagTypeConverter::mTable[] = {
     MAKE_STRING_FROM_ENUM(MIX_ROUTE_FLAG_RENDER),
     MAKE_STRING_FROM_ENUM(MIX_ROUTE_FLAG_LOOP_BACK),
+    MAKE_STRING_FROM_ENUM(MIX_ROUTE_FLAG_LOOP_BACK_AND_RENDER),
     MAKE_STRING_FROM_ENUM(MIX_ROUTE_FLAG_ALL),
     TERMINATOR
 };
 
 template <>
 const RuleTypeConverter::Table RuleTypeConverter::mTable[] = {
-    MAKE_STRING_FROM_ENUM(RULE_EXCLUSION_MASK),
     MAKE_STRING_FROM_ENUM(RULE_MATCH_ATTRIBUTE_USAGE),
     MAKE_STRING_FROM_ENUM(RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET),
     MAKE_STRING_FROM_ENUM(RULE_MATCH_UID),
diff --git a/services/audiopolicy/common/managerdefinitions/src/VolumeCurve.cpp b/services/audiopolicy/common/managerdefinitions/src/VolumeCurve.cpp
deleted file mode 100644
index ac3f1bc..0000000
--- a/services/audiopolicy/common/managerdefinitions/src/VolumeCurve.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "APM::VolumeCurve"
-//#define LOG_NDEBUG 0
-
-#include "VolumeCurve.h"
-#include "TypeConverter.h"
-
-namespace android {
-
-float VolumeCurve::volIndexToDb(int indexInUi, int volIndexMin, int volIndexMax) const
-{
-    ALOG_ASSERT(!mCurvePoints.isEmpty(), "Invalid volume curve");
-
-    size_t nbCurvePoints = mCurvePoints.size();
-    // the volume index in the UI is relative to the min and max volume indices for this stream
-    int nbSteps = 1 + mCurvePoints[nbCurvePoints - 1].mIndex - mCurvePoints[0].mIndex;
-    if (indexInUi < volIndexMin) {
-        ALOGV("VOLUME remapping index from %d to min index %d", indexInUi, volIndexMin);
-        indexInUi = volIndexMin;
-    } else if (indexInUi > volIndexMax) {
-        ALOGV("VOLUME remapping index from %d to max index %d", indexInUi, volIndexMax);
-        indexInUi = volIndexMax;
-    }
-    int volIdx = (nbSteps * (indexInUi - volIndexMin)) / (volIndexMax - volIndexMin);
-
-    // Where would this volume index been inserted in the curve point
-    size_t indexInUiPosition = mCurvePoints.orderOf(CurvePoint(volIdx, 0));
-    if (indexInUiPosition >= nbCurvePoints) {
-        //use last point of table
-        return mCurvePoints[nbCurvePoints - 1].mAttenuationInMb / 100.0f;
-    }
-    if (indexInUiPosition == 0) {
-        if (indexInUiPosition != mCurvePoints[0].mIndex) {
-            return VOLUME_MIN_DB; // out of bounds
-        }
-        return mCurvePoints[0].mAttenuationInMb / 100.0f;
-    }
-    // linear interpolation in the attenuation table in dB
-    float decibels = (mCurvePoints[indexInUiPosition - 1].mAttenuationInMb / 100.0f) +
-            ((float)(volIdx - mCurvePoints[indexInUiPosition - 1].mIndex)) *
-                ( ((mCurvePoints[indexInUiPosition].mAttenuationInMb / 100.0f) -
-                        (mCurvePoints[indexInUiPosition - 1].mAttenuationInMb / 100.0f)) /
-                    ((float)(mCurvePoints[indexInUiPosition].mIndex -
-                            mCurvePoints[indexInUiPosition - 1].mIndex)) );
-
-    ALOGV("VOLUME mDeviceCategory %d, mStreamType %d vol index=[%d %d %d], dB=[%.1f %.1f %.1f]",
-            mDeviceCategory, mStreamType,
-            mCurvePoints[indexInUiPosition - 1].mIndex, volIdx,
-            mCurvePoints[indexInUiPosition].mIndex,
-            ((float)mCurvePoints[indexInUiPosition - 1].mAttenuationInMb / 100.0f), decibels,
-            ((float)mCurvePoints[indexInUiPosition].mAttenuationInMb / 100.0f));
-
-    return decibels;
-}
-
-void VolumeCurve::dump(int fd) const
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-    snprintf(buffer, SIZE, " {");
-    result.append(buffer);
-    for (size_t i = 0; i < mCurvePoints.size(); i++) {
-        snprintf(buffer, SIZE, "(%3d, %5d)",
-                 mCurvePoints[i].mIndex, mCurvePoints[i].mAttenuationInMb);
-        result.append(buffer);
-        result.append(i == (mCurvePoints.size() - 1) ? " }\n" : ", ");
-    }
-    write(fd, result.string(), result.size());
-}
-
-void VolumeCurvesForStream::dump(int fd, int spaces = 0, bool curvePoints) const
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    if (!curvePoints) {
-        snprintf(buffer, SIZE, "%s         %02d         %02d         ",
-                 mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax);
-        result.append(buffer);
-        for (size_t i = 0; i < mIndexCur.size(); i++) {
-            snprintf(buffer, SIZE, "%04x : %02d, ", mIndexCur.keyAt(i), mIndexCur.valueAt(i));
-            result.append(buffer);
-        }
-        result.append("\n");
-        write(fd, result.string(), result.size());
-        return;
-    }
-
-    for (size_t i = 0; i < size(); i++) {
-        std::string deviceCatLiteral;
-        DeviceCategoryConverter::toString(keyAt(i), deviceCatLiteral);
-        snprintf(buffer, SIZE, "%*s %s :",
-                 spaces, "", deviceCatLiteral.c_str());
-        write(fd, buffer, strlen(buffer));
-        valueAt(i)->dump(fd);
-    }
-    result.append("\n");
-    write(fd, result.string(), result.size());
-}
-
-status_t VolumeCurvesCollection::dump(int fd) const
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE, "\nStreams dump:\n");
-    write(fd, buffer, strlen(buffer));
-    snprintf(buffer, SIZE,
-             " Stream  Can be muted  Index Min  Index Max  Index Cur [device : index]...\n");
-    write(fd, buffer, strlen(buffer));
-    for (size_t i = 0; i < size(); i++) {
-        snprintf(buffer, SIZE, " %02zu      ", i);
-        write(fd, buffer, strlen(buffer));
-        valueAt(i).dump(fd);
-    }
-    snprintf(buffer, SIZE, "\nVolume Curves for Use Cases (aka Stream types) dump:\n");
-    write(fd, buffer, strlen(buffer));
-    for (size_t i = 0; i < size(); i++) {
-        std::string streamTypeLiteral;
-        StreamTypeConverter::toString(keyAt(i), streamTypeLiteral);
-        snprintf(buffer, SIZE,
-                 " %s (%02zu): Curve points for device category (index, attenuation in millibel)\n",
-                 streamTypeLiteral.c_str(), i);
-        write(fd, buffer, strlen(buffer));
-        valueAt(i).dump(fd, 2, true);
-    }
-
-    return NO_ERROR;
-}
-
-} // namespace android
diff --git a/services/audiopolicy/config/a2dp_in_audio_policy_configuration.xml b/services/audiopolicy/config/a2dp_in_audio_policy_configuration.xml
new file mode 100644
index 0000000..57bd4f8
--- /dev/null
+++ b/services/audiopolicy/config/a2dp_in_audio_policy_configuration.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Bluetooth Input Audio HAL Audio Policy Configuration file -->
+<module name="a2dp" halVersion="2.0">
+    <mixPorts>
+        <mixPort name="a2dp input" role="sink">
+            <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                     samplingRates="44100,48000"
+                     channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+        </mixPort>
+    </mixPorts>
+    <devicePorts>
+        <devicePort tagName="BT A2DP In" type="AUDIO_DEVICE_IN_BLUETOOTH_A2DP" role="source">
+            <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                     samplingRates="44100,48000"
+                     channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+        </devicePort>
+    </devicePorts>
+    <routes>
+        <route type="mix" sink="a2dp input"
+               sources="BT A2DP In"/>
+    </routes>
+</module>
diff --git a/services/audiopolicy/config/audio_policy_configuration.xml b/services/audiopolicy/config/audio_policy_configuration.xml
index a75f1cb..b28381b 100644
--- a/services/audiopolicy/config/audio_policy_configuration.xml
+++ b/services/audiopolicy/config/audio_policy_configuration.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
+<!-- Copyright (C) 2019 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -173,8 +173,8 @@
 
         </module>
 
-        <!-- A2dp Audio HAL -->
-        <xi:include href="a2dp_audio_policy_configuration.xml"/>
+        <!-- A2dp Input Audio HAL -->
+        <xi:include href="a2dp_in_audio_policy_configuration.xml"/>
 
         <!-- Usb Audio HAL -->
         <xi:include href="usb_audio_policy_configuration.xml"/>
@@ -182,17 +182,30 @@
         <!-- Remote Submix Audio HAL -->
         <xi:include href="r_submix_audio_policy_configuration.xml"/>
 
-        <!-- Hearing aid Audio HAL -->
-        <xi:include href="hearing_aid_audio_policy_configuration.xml"/>
+        <!-- Bluetooth Audio HAL -->
+        <xi:include href="bluetooth_audio_policy_configuration.xml"/>
+
+        <!-- MSD Audio HAL (optional) -->
+        <xi:include href="msd_audio_policy_configuration.xml"/>
 
     </modules>
     <!-- End of Modules section -->
 
-    <!-- Volume section -->
+    <!-- Volume section:
+        IMPORTANT NOTE: Volume tables have been moved to engine configuration.
+                        Keep it here for legacy.
+                        Engine will fallback on these files if none are provided by engine.
+     -->
 
     <xi:include href="audio_policy_volumes.xml"/>
     <xi:include href="default_volume_tables.xml"/>
 
     <!-- End of Volume section -->
 
+    <!-- Surround Sound configuration -->
+
+    <xi:include href="surround_sound_configuration_5_0.xml"/>
+
+    <!-- End of Surround Sound configuration -->
+
 </audioPolicyConfiguration>
diff --git a/services/audiopolicy/config/audio_policy_configuration_bluetooth_legacy_hal.xml b/services/audiopolicy/config/audio_policy_configuration_bluetooth_legacy_hal.xml
new file mode 100644
index 0000000..b4cc1d3
--- /dev/null
+++ b/services/audiopolicy/config/audio_policy_configuration_bluetooth_legacy_hal.xml
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <!-- version section contains a “version” tag in the form “major.minor” e.g version=”1.0” -->
+
+    <!-- Global configuration Decalaration -->
+    <globalConfiguration speaker_drc_enabled="true"/>
+
+
+    <!-- Modules section:
+        There is one section per audio HW module present on the platform.
+        Each module section will contains two mandatory tags for audio HAL “halVersion” and “name”.
+        The module names are the same as in current .conf file:
+                “primary”, “A2DP”, “remote_submix”, “USB”
+        Each module will contain the following sections:
+        “devicePorts”: a list of device descriptors for all input and output devices accessible via this
+        module.
+        This contains both permanently attached devices and removable devices.
+        “mixPorts”: listing all output and input streams exposed by the audio HAL
+        “routes”: list of possible connections between input and output devices or between stream and
+        devices.
+            "route": is defined by an attribute:
+                -"type": <mux|mix> means all sources are mutual exclusive (mux) or can be mixed (mix)
+                -"sink": the sink involved in this route
+                -"sources": all the sources than can be connected to the sink via vis route
+        “attachedDevices”: permanently attached devices.
+        The attachedDevices section is a list of devices names. The names correspond to device names
+        defined in <devicePorts> section.
+        “defaultOutputDevice”: device to be used by default when no policy rule applies
+    -->
+    <modules>
+        <!-- Primary Audio HAL -->
+        <module name="primary" halVersion="3.0">
+            <attachedDevices>
+                <item>Speaker</item>
+                <item>Built-In Mic</item>
+                <item>Built-In Back Mic</item>
+            </attachedDevices>
+            <defaultOutputDevice>Speaker</defaultOutputDevice>
+            <mixPorts>
+                <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+                <mixPort name="deep_buffer" role="source"
+                        flags="AUDIO_OUTPUT_FLAG_DEEP_BUFFER">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+                <mixPort name="compressed_offload" role="source"
+                         flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING">
+                    <profile name="" format="AUDIO_FORMAT_MP3"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
+                    <profile name="" format="AUDIO_FORMAT_AAC"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
+                    <profile name="" format="AUDIO_FORMAT_AAC_LC"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
+                </mixPort>
+                <mixPort name="voice_tx" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
+                </mixPort>
+                <mixPort name="primary input" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </mixPort>
+                <mixPort name="voice_rx" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
+                </mixPort>
+            </mixPorts>
+            <devicePorts>
+                <!-- Output devices declaration, i.e. Sink DEVICE PORT -->
+                <devicePort tagName="Earpiece" type="AUDIO_DEVICE_OUT_EARPIECE" role="sink">
+                   <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                            samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
+                </devicePort>
+                <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                    <gains>
+                        <gain name="gain_1" mode="AUDIO_GAIN_MODE_JOINT"
+                              minValueMB="-8400"
+                              maxValueMB="4000"
+                              defaultValueMB="0"
+                              stepValueMB="100"/>
+                    </gains>
+                </devicePort>
+                <devicePort tagName="Wired Headset" type="AUDIO_DEVICE_OUT_WIRED_HEADSET" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="Wired Headphones" type="AUDIO_DEVICE_OUT_WIRED_HEADPHONE" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="BT SCO" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
+                </devicePort>
+                <devicePort tagName="BT SCO Headset" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
+                </devicePort>
+                <devicePort tagName="BT SCO Car Kit" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
+                </devicePort>
+                <devicePort tagName="Telephony Tx" type="AUDIO_DEVICE_OUT_TELEPHONY_TX" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
+                </devicePort>
+
+                <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </devicePort>
+                <devicePort tagName="Built-In Back Mic" type="AUDIO_DEVICE_IN_BACK_MIC" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </devicePort>
+                <devicePort tagName="Wired Headset Mic" type="AUDIO_DEVICE_IN_WIRED_HEADSET" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </devicePort>
+                <devicePort tagName="BT SCO Headset Mic" type="AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
+                </devicePort>
+                <devicePort tagName="Telephony Rx" type="AUDIO_DEVICE_IN_TELEPHONY_RX" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
+                </devicePort>
+            </devicePorts>
+            <!-- route declaration, i.e. list all available sources for a given sink -->
+            <routes>
+                <route type="mix" sink="Earpiece"
+                       sources="primary output,deep_buffer,BT SCO Headset Mic"/>
+                <route type="mix" sink="Speaker"
+                       sources="primary output,deep_buffer,compressed_offload,BT SCO Headset Mic,Telephony Rx"/>
+                <route type="mix" sink="Wired Headset"
+                       sources="primary output,deep_buffer,compressed_offload,BT SCO Headset Mic,Telephony Rx"/>
+                <route type="mix" sink="Wired Headphones"
+                       sources="primary output,deep_buffer,compressed_offload,BT SCO Headset Mic,Telephony Rx"/>
+                <route type="mix" sink="primary input"
+                       sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,BT SCO Headset Mic"/>
+                <route type="mix" sink="Telephony Tx"
+                       sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,BT SCO Headset Mic, voice_tx"/>
+                <route type="mix" sink="voice_rx"
+                       sources="Telephony Rx"/>
+            </routes>
+
+        </module>
+
+        <!-- A2dp Audio HAL -->
+        <xi:include href="a2dp_audio_policy_configuration.xml"/>
+
+        <!-- Usb Audio HAL -->
+        <xi:include href="usb_audio_policy_configuration.xml"/>
+
+        <!-- Remote Submix Audio HAL -->
+        <xi:include href="r_submix_audio_policy_configuration.xml"/>
+
+        <!-- Hearing aid Audio HAL -->
+        <xi:include href="hearing_aid_audio_policy_configuration.xml"/>
+
+        <!-- MSD Audio HAL (optional) -->
+        <xi:include href="msd_audio_policy_configuration.xml"/>
+
+    </modules>
+    <!-- End of Modules section -->
+
+    <!-- Volume section:
+        IMPORTANT NOTE: Volume tables have been moved to engine configuration.
+                        Keep it here for legacy.
+                        Engine will fallback on these files if none are provided by engine.
+     -->
+
+    <xi:include href="audio_policy_volumes.xml"/>
+    <xi:include href="default_volume_tables.xml"/>
+
+    <!-- End of Volume section -->
+
+    <!-- Surround Sound configuration -->
+
+    <xi:include href="surround_sound_configuration_5_0.xml"/>
+
+    <!-- End of Surround Sound configuration -->
+
+</audioPolicyConfiguration>
diff --git a/services/audiopolicy/config/audio_policy_configuration_generic.xml b/services/audiopolicy/config/audio_policy_configuration_generic.xml
index 58768c3..9ad609d 100644
--- a/services/audiopolicy/config/audio_policy_configuration_generic.xml
+++ b/services/audiopolicy/config/audio_policy_configuration_generic.xml
@@ -30,11 +30,21 @@
     </modules>
     <!-- End of Modules section -->
 
-    <!-- Volume section -->
+    <!-- Volume section:
+        IMPORTANT NOTE: Volume tables have been moved to engine configuration.
+                        Keep it here for legacy.
+                        Engine will fallback on these files if none are provided by engine.
+     -->
 
     <xi:include href="audio_policy_volumes.xml"/>
     <xi:include href="default_volume_tables.xml"/>
 
     <!-- End of Volume section -->
 
+    <!-- Surround Sound configuration -->
+
+    <xi:include href="surround_sound_configuration_5_0.xml"/>
+
+    <!-- End of Surround Sound configuration -->
+
 </audioPolicyConfiguration>
diff --git a/services/audiopolicy/config/audio_policy_configuration_generic_tv.xml b/services/audiopolicy/config/audio_policy_configuration_generic_tv.xml
new file mode 100644
index 0000000..5f1ca31
--- /dev/null
+++ b/services/audiopolicy/config/audio_policy_configuration_generic_tv.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <!-- version section contains a “version” tag in the form “major.minor” e.g version=”1.0” -->
+
+    <!-- Global configuration Decalaration -->
+    <globalConfiguration speaker_drc_enabled="false"/>
+
+    <modules>
+        <!-- Primary Audio HAL -->
+        <xi:include href="primary_audio_policy_configuration_tv.xml"/>
+
+        <!-- Usb Audio HAL -->
+        <xi:include href="usb_audio_policy_configuration.xml"/>
+
+        <!-- Remote Submix Audio HAL -->
+        <xi:include href="r_submix_audio_policy_configuration.xml"/>
+
+    </modules>
+    <!-- End of Modules section -->
+
+    <!-- Volume section -->
+
+    <xi:include href="audio_policy_volumes.xml"/>
+    <xi:include href="default_volume_tables.xml"/>
+
+    <!-- End of Volume section -->
+
+    <!-- Surround Sound configuration -->
+
+    <xi:include href="surround_sound_configuration_5_0.xml"/>
+
+    <!-- End of Surround Sound configuration -->
+
+</audioPolicyConfiguration>
diff --git a/services/audiopolicy/config/audio_policy_configuration_stub.xml b/services/audiopolicy/config/audio_policy_configuration_stub.xml
index 26c381f..8350eb8 100644
--- a/services/audiopolicy/config/audio_policy_configuration_stub.xml
+++ b/services/audiopolicy/config/audio_policy_configuration_stub.xml
@@ -15,6 +15,9 @@
 -->
 
 <audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <!-- Global configuration Decalaration -->
+    <globalConfiguration speaker_drc_enabled="false"/>
+
     <modules>
         <!-- Stub Audio HAL -->
         <xi:include href="stub_audio_policy_configuration.xml"/>
@@ -26,5 +29,6 @@
 
     <xi:include href="audio_policy_volumes.xml"/>
     <xi:include href="default_volume_tables.xml"/>
+    <xi:include href="surround_sound_configuration_5_0.xml"/>
 
 </audioPolicyConfiguration>
diff --git a/services/audiopolicy/config/bluetooth_audio_policy_configuration.xml b/services/audiopolicy/config/bluetooth_audio_policy_configuration.xml
new file mode 100644
index 0000000..ce78eb0
--- /dev/null
+++ b/services/audiopolicy/config/bluetooth_audio_policy_configuration.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Bluetooth Audio HAL Audio Policy Configuration file -->
+<module name="bluetooth" halVersion="2.0">
+    <mixPorts>
+        <!-- A2DP Audio Ports -->
+        <mixPort name="a2dp output" role="source"/>
+        <!-- Hearing AIDs Audio Ports -->
+        <mixPort name="hearing aid output" role="source">
+            <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                     samplingRates="24000,16000"
+                     channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+        </mixPort>
+    </mixPorts>
+    <devicePorts>
+        <!-- A2DP Audio Ports -->
+        <devicePort tagName="BT A2DP Out" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP" role="sink">
+            <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                     samplingRates="44100,48000,88200,96000"
+                     channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+        </devicePort>
+        <devicePort tagName="BT A2DP Headphones" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES" role="sink">
+            <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                     samplingRates="44100,48000,88200,96000"
+                     channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+        </devicePort>
+        <devicePort tagName="BT A2DP Speaker" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER" role="sink">
+            <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                     samplingRates="44100,48000,88200,96000"
+                     channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+        </devicePort>
+        <!-- Hearing AIDs Audio Ports -->
+        <devicePort tagName="BT Hearing Aid Out" type="AUDIO_DEVICE_OUT_HEARING_AID" role="sink"/>
+    </devicePorts>
+    <routes>
+        <route type="mix" sink="BT A2DP Out"
+               sources="a2dp output"/>
+        <route type="mix" sink="BT A2DP Headphones"
+               sources="a2dp output"/>
+        <route type="mix" sink="BT A2DP Speaker"
+               sources="a2dp output"/>
+        <route type="mix" sink="BT Hearing Aid Out"
+               sources="hearing aid output"/>
+    </routes>
+</module>
diff --git a/services/audiopolicy/config/hearing_aid_audio_policy_configuration.xml b/services/audiopolicy/config/hearing_aid_audio_policy_configuration.xml
index 3c48e88..e6e6bdb 100644
--- a/services/audiopolicy/config/hearing_aid_audio_policy_configuration.xml
+++ b/services/audiopolicy/config/hearing_aid_audio_policy_configuration.xml
@@ -2,7 +2,7 @@
 <!-- Hearing aid Audio HAL Audio Policy Configuration file -->
 <module name="hearing_aid" halVersion="2.0">
     <mixPorts>
-        <mixPort name="hearing aid output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+        <mixPort name="hearing aid output" role="source">
             <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                      samplingRates="24000,16000"
                      channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
diff --git a/services/audiopolicy/config/msd_audio_policy_configuration.xml b/services/audiopolicy/config/msd_audio_policy_configuration.xml
new file mode 100644
index 0000000..db17bc6
--- /dev/null
+++ b/services/audiopolicy/config/msd_audio_policy_configuration.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017-2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<!-- Multi Stream Decoder Audio Policy Configuration file -->
+<module name="msd" halVersion="2.0">
+    <attachedDevices>
+        <item>MS12 Input</item>
+        <item>MS12 Output</item>
+    </attachedDevices>
+    <mixPorts>
+        <mixPort name="ms12 input" role="source">
+            <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                     samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+        </mixPort>
+        <mixPort name="ms12 compressed input" role="source"
+                flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING">
+            <profile name="" format="AUDIO_FORMAT_AC3"
+                     samplingRates="32000,44100,48000"
+                     channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_5POINT1"/>
+            <profile name="" format="AUDIO_FORMAT_E_AC3"
+                     samplingRates="32000,44100,48000"
+                     channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+            <profile name="" format="AUDIO_FORMAT_E_AC3_JOC"
+                     samplingRates="32000,44100,48000"
+                     channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+            <profile name="" format="AUDIO_FORMAT_AC4"
+                     samplingRates="32000,44100,48000"
+                     channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+        </mixPort>
+        <!-- The HW AV Sync flag is not required, but is recommended -->
+        <mixPort name="ms12 output" role="sink" flags="AUDIO_INPUT_FLAG_HW_AV_SYNC">
+            <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                     samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
+            <profile name="" format="AUDIO_FORMAT_AC3"
+                     samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_5POINT1"/>
+            <profile name="" format="AUDIO_FORMAT_E_AC3"
+                     samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_5POINT1"/>
+        </mixPort>
+   </mixPorts>
+   <devicePorts>
+       <devicePort tagName="MS12 Input" type="AUDIO_DEVICE_OUT_BUS"  role="sink">
+           <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                    samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+           <profile name="" format="AUDIO_FORMAT_AC3"
+                    samplingRates="32000,44100,48000"
+                    channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_5POINT1"/>
+           <profile name="" format="AUDIO_FORMAT_E_AC3"
+                    samplingRates="32000,44100,48000"
+                    channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+            <profile name="" format="AUDIO_FORMAT_E_AC3_JOC"
+                     samplingRates="32000,44100,48000"
+                     channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+           <profile name="" format="AUDIO_FORMAT_AC4"
+                    samplingRates="32000,44100,48000"
+                    channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+       </devicePort>
+       <devicePort tagName="MS12 Output" type="AUDIO_DEVICE_IN_BUS"  role="source">
+           <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                    samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
+        </devicePort>
+    </devicePorts>
+    <routes>
+        <route type="mix" sink="MS12 Input" sources="ms12 input,ms12 compressed input"/>
+        <route type="mix" sink="ms12 output" sources="MS12 Output"/>
+    </routes>
+</module>
diff --git a/services/audiopolicy/config/primary_audio_policy_configuration.xml b/services/audiopolicy/config/primary_audio_policy_configuration.xml
index 5b7ae7f..eedc96b 100644
--- a/services/audiopolicy/config/primary_audio_policy_configuration.xml
+++ b/services/audiopolicy/config/primary_audio_policy_configuration.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Default Primary Audio HAL Module Audio Policy Configuration include flie -->
+<!-- Default Primary Audio HAL Module Audio Policy Configuration include file -->
 <module name="primary" halVersion="2.0">
     <attachedDevices>
         <item>Speaker</item>
diff --git a/services/audiopolicy/config/primary_audio_policy_configuration_tv.xml b/services/audiopolicy/config/primary_audio_policy_configuration_tv.xml
new file mode 100644
index 0000000..826015a
--- /dev/null
+++ b/services/audiopolicy/config/primary_audio_policy_configuration_tv.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Default Primary Audio HAL Module Audio Policy Configuration include file for TV -->
+<module name="primary" halVersion="2.0">
+    <attachedDevices>
+        <item>Speaker</item>
+    </attachedDevices>
+    <defaultOutputDevice>Speaker</defaultOutputDevice>
+    <mixPorts>
+        <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+            <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                     samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+        </mixPort>
+        <mixPort name="direct" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT" />
+        <mixPort name="tunnel" role="source"
+                 flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_HW_AV_SYNC" />
+   </mixPorts>
+   <devicePorts>
+        <devicePort tagName="Speaker" type="AUDIO_DEVICE_OUT_SPEAKER" role="sink" />
+        <devicePort tagName="Out Aux Digital" type="AUDIO_DEVICE_OUT_AUX_DIGITAL" role="sink"
+                    encodedFormats="AUDIO_FORMAT_AC3 AUDIO_FORMAT_IEC61937" />
+    </devicePorts>
+    <routes>
+        <route type="mix" sink="Speaker" sources="primary output"/>
+        <route type="mix" sink="Out Aux Digital" sources="primary output,direct,tunnel"/>
+    </routes>
+</module>
diff --git a/services/audiopolicy/config/surround_sound_configuration_5_0.xml b/services/audiopolicy/config/surround_sound_configuration_5_0.xml
new file mode 100644
index 0000000..590a181
--- /dev/null
+++ b/services/audiopolicy/config/surround_sound_configuration_5_0.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<surroundSound>
+  <!-- Each of the listed formats gets an entry in Surround Settings dialog on TV devices.
+       There must be a corresponding Java ENCODING_... contant defined in AudioFormat.java,
+       and a display name defined in AudioFormat.toDisplayName. For the formats that don't
+       need a dedicated Surrond Settings dialog entry, a subformats list has to be used. -->
+  <formats>
+    <format name="AUDIO_FORMAT_AC3" />
+    <format name="AUDIO_FORMAT_E_AC3" />
+    <format name="AUDIO_FORMAT_E_AC3_JOC" />
+    <format name="AUDIO_FORMAT_DOLBY_TRUEHD" />
+    <format name="AUDIO_FORMAT_DTS" />
+    <format name="AUDIO_FORMAT_DTS_HD" />
+    <format name="AUDIO_FORMAT_AAC_LC" subformats="AUDIO_FORMAT_AAC_HE_V1 AUDIO_FORMAT_AAC_HE_V2 AUDIO_FORMAT_AAC_ELD AUDIO_FORMAT_AAC_XHE" />
+    <format name="AUDIO_FORMAT_AC4" />
+  </formats>
+</surroundSound>
diff --git a/services/audiopolicy/engine/common/Android.bp b/services/audiopolicy/engine/common/Android.bp
new file mode 100644
index 0000000..d0775ad
--- /dev/null
+++ b/services/audiopolicy/engine/common/Android.bp
@@ -0,0 +1,47 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library_headers {
+    name: "libaudiopolicyengine_common_headers",
+    host_supported: true,
+    export_include_dirs: ["include"],
+}
+
+cc_library_static {
+    name: "libaudiopolicyengine_common",
+    srcs: [
+        "src/EngineBase.cpp",
+        "src/ProductStrategy.cpp",
+        "src/VolumeCurve.cpp",
+        "src/VolumeGroup.cpp",
+    ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+    ],
+    header_libs: [
+        "libbase_headers",
+        "libaudiopolicycommon",
+        "libaudiopolicyengine_common_headers",
+        "libaudiopolicyengine_interface_headers",
+    ],
+    export_header_lib_headers: [
+        "libaudiopolicyengine_common_headers",
+    ],
+    static_libs: [
+        "libaudiopolicycomponents",
+        "libaudiopolicyengine_config",
+    ],
+}
diff --git a/services/audiopolicy/engine/common/include/EngineBase.h b/services/audiopolicy/engine/common/include/EngineBase.h
new file mode 100644
index 0000000..cedc78f
--- /dev/null
+++ b/services/audiopolicy/engine/common/include/EngineBase.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <EngineConfig.h>
+#include <AudioPolicyManagerInterface.h>
+#include <ProductStrategy.h>
+#include <VolumeGroup.h>
+
+namespace android {
+namespace audio_policy {
+
+class EngineBase : public AudioPolicyManagerInterface
+{
+public:
+    ///
+    /// from AudioPolicyManagerInterface
+    ///
+    android::status_t initCheck() override;
+
+    void setObserver(AudioPolicyManagerObserver *observer) override;
+
+    status_t setPhoneState(audio_mode_t mode) override;
+
+    audio_mode_t getPhoneState() const override { return mPhoneState; }
+
+    status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config) override
+    {
+        mForceUse[usage] = config;
+        return NO_ERROR;
+    }
+
+    audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const override
+    {
+        return mForceUse[usage];
+    }
+    android::status_t setDeviceConnectionState(const sp<DeviceDescriptor> /*devDesc*/,
+                                               audio_policy_dev_state_t /*state*/) override
+    {
+        return NO_ERROR;
+    }
+    product_strategy_t getProductStrategyForAttributes(
+            const audio_attributes_t &attr) const override;
+
+    audio_stream_type_t getStreamTypeForAttributes(const audio_attributes_t &attr) const override;
+
+    audio_attributes_t getAttributesForStreamType(audio_stream_type_t stream) const override;
+
+    StreamTypeVector getStreamTypesForProductStrategy(product_strategy_t ps) const override;
+
+    AttributesVector getAllAttributesForProductStrategy(product_strategy_t ps) const override;
+
+    StrategyVector getOrderedProductStrategies() const override;
+
+    status_t listAudioProductStrategies(AudioProductStrategyVector &strategies) const override;
+
+    VolumeCurves *getVolumeCurvesForAttributes(const audio_attributes_t &attr) const override;
+
+    VolumeCurves *getVolumeCurvesForStreamType(audio_stream_type_t stream) const override;
+
+    IVolumeCurves *getVolumeCurvesForVolumeGroup(volume_group_t group) const override
+    {
+       return mVolumeGroups.find(group) != end(mVolumeGroups) ?
+                   mVolumeGroups.at(group)->getVolumeCurves() : nullptr;
+    }
+
+    VolumeGroupVector getVolumeGroups() const override;
+
+    volume_group_t getVolumeGroupForAttributes(const audio_attributes_t &attr) const override;
+
+    volume_group_t getVolumeGroupForStreamType(audio_stream_type_t stream) const override;
+
+    status_t listAudioVolumeGroups(AudioVolumeGroupVector &groups) const override;
+
+    void dump(String8 *dst) const override;
+
+
+    engineConfig::ParsingResult loadAudioPolicyEngineConfig();
+
+    const ProductStrategyMap &getProductStrategies() const { return mProductStrategies; }
+
+    ProductStrategyMap &getProductStrategies() { return mProductStrategies; }
+
+    product_strategy_t getProductStrategyForStream(audio_stream_type_t stream) const;
+
+    product_strategy_t getProductStrategyByName(const std::string &name) const;
+
+    AudioPolicyManagerObserver *getApmObserver() const { return mApmObserver; }
+
+    inline bool isInCall() const
+    {
+        return is_state_in_call(getPhoneState());
+    }
+
+    VolumeSource toVolumeSource(audio_stream_type_t stream) const
+    {
+        return static_cast<VolumeSource>(getVolumeGroupForStreamType(stream));
+    }
+
+    status_t switchVolumeCurve(audio_stream_type_t streamSrc, audio_stream_type_t streamDst);
+
+    status_t restoreOriginVolumeCurve(audio_stream_type_t stream);
+
+ private:
+    AudioPolicyManagerObserver *mApmObserver = nullptr;
+
+    ProductStrategyMap mProductStrategies;
+    VolumeGroupMap mVolumeGroups;
+    audio_mode_t mPhoneState = AUDIO_MODE_NORMAL;  /**< current phone state. */
+
+    /** current forced use configuration. */
+    audio_policy_forced_cfg_t mForceUse[AUDIO_POLICY_FORCE_USE_CNT] = {};
+};
+
+} // namespace audio_policy
+} // namespace android
diff --git a/services/audiopolicy/engine/common/include/ProductStrategy.h b/services/audiopolicy/engine/common/include/ProductStrategy.h
new file mode 100644
index 0000000..1a2a198
--- /dev/null
+++ b/services/audiopolicy/engine/common/include/ProductStrategy.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "VolumeGroup.h"
+
+#include <system/audio.h>
+#include <AudioPolicyManagerInterface.h>
+#include <utils/RefBase.h>
+#include <HandleGenerator.h>
+#include <string>
+#include <vector>
+#include <map>
+#include <utils/Errors.h>
+#include <utils/String8.h>
+
+namespace android {
+
+/**
+ * @brief The ProductStrategy class describes for each product_strategy_t identifier the
+ * associated audio attributes, the device types to use, the device address to use.
+ * The identifier is voluntarily not strongly typed in order to be extensible by OEM.
+ */
+class ProductStrategy : public virtual RefBase, private HandleGenerator<uint32_t>
+{
+private:
+    struct AudioAttributes {
+        audio_stream_type_t mStream = AUDIO_STREAM_DEFAULT;
+        volume_group_t mVolumeGroup = VOLUME_GROUP_NONE;
+        audio_attributes_t mAttributes = AUDIO_ATTRIBUTES_INITIALIZER;
+    };
+
+    using AudioAttributesVector = std::vector<AudioAttributes>;
+
+public:
+    ProductStrategy(const std::string &name);
+
+    void addAttributes(const AudioAttributes &audioAttributes);
+
+    std::vector<android::AudioAttributes> listAudioAttributes() const;
+
+    std::string getName() const { return mName; }
+    AttributesVector getAudioAttributes() const;
+    product_strategy_t getId() const { return mId; }
+    StreamTypeVector getSupportedStreams() const;
+
+    /**
+     * @brief matches checks if the given audio attributes shall follow the strategy.
+     *        Order of the attributes within a strategy matters.
+     *        If only the usage is available, the check is performed on the usages of the given
+     *        attributes, otherwise all fields must match.
+     * @param attributes to consider
+     * @return true if attributes matches with the strategy, false otherwise.
+     */
+    bool matches(const audio_attributes_t attributes) const;
+
+    bool supportStreamType(const audio_stream_type_t &streamType) const;
+
+    void setDeviceAddress(const std::string &address)
+    {
+        mDeviceAddress = address;
+    }
+
+    std::string getDeviceAddress() const { return mDeviceAddress; }
+
+    void setDeviceTypes(audio_devices_t devices)
+    {
+        mApplicableDevices = devices;
+    }
+
+    audio_devices_t getDeviceTypes() const { return mApplicableDevices; }
+
+    audio_attributes_t getAttributesForStreamType(audio_stream_type_t stream) const;
+    audio_stream_type_t getStreamTypeForAttributes(const audio_attributes_t &attr) const;
+
+    volume_group_t getVolumeGroupForAttributes(const audio_attributes_t &attr) const;
+
+    volume_group_t getVolumeGroupForStreamType(audio_stream_type_t stream) const;
+
+    volume_group_t getDefaultVolumeGroup() const;
+
+    bool isDefault() const;
+
+    void dump(String8 *dst, int spaces = 0) const;
+
+private:
+    std::string mName;
+
+    AudioAttributesVector mAttributesVector;
+
+    product_strategy_t mId;
+
+    std::string mDeviceAddress; /**< Device address applicable for this strategy, maybe empty */
+
+    /**
+     * Applicable device(s) type mask for this strategy.
+     */
+    audio_devices_t mApplicableDevices = AUDIO_DEVICE_NONE;
+};
+
+class ProductStrategyMap : public std::map<product_strategy_t, sp<ProductStrategy> >
+{
+public:
+    /**
+     * @brief initialize: set default product strategy in cache.
+     */
+    void initialize();
+    /**
+     * @brief getProductStrategyForAttribute. The order of the vector is dimensionning.
+     * @param attr
+     * @return applicable product strategy for the given attribute, default if none applicable.
+     */
+    product_strategy_t getProductStrategyForAttributes(const audio_attributes_t &attr) const;
+
+    product_strategy_t getProductStrategyForStream(audio_stream_type_t stream) const;
+
+    audio_attributes_t getAttributesForStreamType(audio_stream_type_t stream) const;
+
+    audio_stream_type_t getStreamTypeForAttributes(const audio_attributes_t &attr) const;
+
+    /**
+     * @brief getAttributesForProductStrategy can be called from
+     *        AudioManager: in this case, the product strategy IS the former routing strategy
+     *        CarAudioManager: in this case, the product strategy IS the car usage
+     *                      [getAudioAttributesForCarUsage]
+     *        OemExtension: in this case, the product strategy IS the Oem usage
+     *
+     * @param strategy
+     * @return audio attributes (or at least one of the attributes) following the given strategy.
+     */
+    audio_attributes_t getAttributesForProductStrategy(product_strategy_t strategy) const;
+
+    audio_devices_t getDeviceTypesForProductStrategy(product_strategy_t strategy) const;
+
+    std::string getDeviceAddressForProductStrategy(product_strategy_t strategy) const;
+
+    volume_group_t getVolumeGroupForAttributes(const audio_attributes_t &attr) const;
+
+    volume_group_t getVolumeGroupForStreamType(audio_stream_type_t stream) const;
+
+    volume_group_t getDefaultVolumeGroup() const;
+
+    product_strategy_t getDefault() const;
+
+    void dump(String8 *dst, int spaces = 0) const;
+
+private:
+    product_strategy_t mDefaultStrategy = PRODUCT_STRATEGY_NONE;
+};
+
+} // namespace android
diff --git a/services/audiopolicy/engine/common/include/VolumeCurve.h b/services/audiopolicy/engine/common/include/VolumeCurve.h
new file mode 100644
index 0000000..54314e3
--- /dev/null
+++ b/services/audiopolicy/engine/common/include/VolumeCurve.h
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "IVolumeCurves.h"
+#include <policy.h>
+#include <AudioPolicyManagerInterface.h>
+#include <utils/RefBase.h>
+#include <HandleGenerator.h>
+#include <utils/String8.h>
+#include <utils/SortedVector.h>
+#include <utils/KeyedVector.h>
+#include <system/audio.h>
+#include <cutils/config_utils.h>
+#include <string>
+#include <map>
+#include <utility>
+
+namespace android {
+
+struct CurvePoint
+{
+    CurvePoint() {}
+    CurvePoint(int index, int attenuationInMb) :
+        mIndex(index), mAttenuationInMb(attenuationInMb) {}
+    uint32_t mIndex;
+    int mAttenuationInMb;
+};
+
+inline bool operator< (const CurvePoint &lhs, const CurvePoint &rhs)
+{
+    return lhs.mIndex < rhs.mIndex;
+}
+
+// A volume curve for a given use case and device category
+// It contains of list of points of this curve expressing the attenuation in Millibels for
+// a given volume index from 0 to 100
+class VolumeCurve : public RefBase
+{
+public:
+    VolumeCurve(device_category device) : mDeviceCategory(device) {}
+
+    void add(const CurvePoint &point) { mCurvePoints.add(point); }
+
+    float volIndexToDb(int indexInUi, int volIndexMin, int volIndexMax) const;
+
+    void dump(String8 *dst, int spaces = 0, bool curvePoints = false) const;
+
+    device_category getDeviceCategory() const { return mDeviceCategory; }
+
+private:
+    const device_category mDeviceCategory;
+    SortedVector<CurvePoint> mCurvePoints;
+};
+
+// Volume Curves for a given use case indexed by device category
+class VolumeCurves : public KeyedVector<device_category, sp<VolumeCurve> >,
+                     public IVolumeCurves
+{
+public:
+    VolumeCurves(int indexMin = 0, int indexMax = 100) :
+        mIndexMin(indexMin), mIndexMax(indexMax)
+    {
+        addCurrentVolumeIndex(AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, 0);
+    }
+    status_t initVolume(int indexMin, int indexMax) override
+    {
+        mIndexMin = indexMin;
+        mIndexMax = indexMax;
+        return NO_ERROR;
+    }
+
+    sp<VolumeCurve> getCurvesFor(device_category device) const
+    {
+        if (indexOfKey(device) < 0) {
+            return 0;
+        }
+        return valueFor(device);
+    }
+
+    virtual int getVolumeIndex(audio_devices_t device) const
+    {
+        device = Volume::getDeviceForVolume(device);
+        // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME
+        if (mIndexCur.find(device) == end(mIndexCur)) {
+            device = AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME;
+        }
+        return mIndexCur.at(device);
+    }
+
+    virtual bool canBeMuted() const { return mCanBeMuted; }
+    virtual void clearCurrentVolumeIndex() { mIndexCur.clear(); }
+    void addCurrentVolumeIndex(audio_devices_t device, int index) override
+    {
+        mIndexCur[device] = index;
+    }
+
+    int getVolumeIndexMin() const { return mIndexMin; }
+
+    int getVolumeIndexMax() const { return mIndexMax; }
+
+    bool hasVolumeIndexForDevice(audio_devices_t device) const
+    {
+        device = Volume::getDeviceForVolume(device);
+        return mIndexCur.find(device) != end(mIndexCur);
+    }
+
+    status_t switchCurvesFrom(const VolumeCurves &referenceCurves)
+    {
+        if (size() != referenceCurves.size()) {
+            ALOGE("%s! device category not aligned, cannot switch", __FUNCTION__);
+            return BAD_TYPE;
+        }
+        for (size_t index = 0; index < size(); index++) {
+            device_category cat = keyAt(index);
+            setVolumeCurve(cat, referenceCurves.getOriginVolumeCurve(cat));
+        }
+        return NO_ERROR;
+    }
+    status_t restoreOriginVolumeCurve()
+    {
+        return switchCurvesFrom(*this);
+    }
+
+    const sp<VolumeCurve> getOriginVolumeCurve(device_category deviceCategory) const
+    {
+        ALOG_ASSERT(mOriginVolumeCurves.indexOfKey(deviceCategory) >= 0, "Invalid device category");
+        return mOriginVolumeCurves.valueFor(deviceCategory);
+    }
+    void setVolumeCurve(device_category deviceCategory, const sp<VolumeCurve> &volumeCurve)
+    {
+        ALOG_ASSERT(indexOfKey(deviceCategory) >= 0, "Invalid device category for Volume Curve");
+        replaceValueFor(deviceCategory, volumeCurve);
+    }
+
+    ssize_t add(const sp<VolumeCurve> &volumeCurve)
+    {
+        device_category deviceCategory = volumeCurve->getDeviceCategory();
+        ssize_t index = indexOfKey(deviceCategory);
+        if (index < 0) {
+            // Keep track of original Volume Curves per device category in order to switch curves.
+            mOriginVolumeCurves.add(deviceCategory, volumeCurve);
+            return KeyedVector::add(deviceCategory, volumeCurve);
+        }
+        return index;
+    }
+
+    virtual float volIndexToDb(device_category deviceCat, int indexInUi) const
+    {
+        sp<VolumeCurve> vc = getCurvesFor(deviceCat);
+        if (vc != 0) {
+            return vc->volIndexToDb(indexInUi, mIndexMin, mIndexMax);
+        } else {
+            ALOGE("Invalid device category %d for Volume Curve", deviceCat);
+            return 0.0f;
+        }
+    }
+    void addAttributes(const audio_attributes_t &attr)
+    {
+        mAttributes.push_back(attr);
+    }
+    AttributesVector getAttributes() const override { return mAttributes; }
+    void addStreamType(audio_stream_type_t stream)
+    {
+        mStreams.push_back(stream);
+    }
+    StreamTypeVector getStreamTypes() const override { return mStreams; }
+
+    void dump(String8 *dst, int spaces = 0, bool curvePoints = false) const override;
+
+private:
+    KeyedVector<device_category, sp<VolumeCurve> > mOriginVolumeCurves;
+    std::map<audio_devices_t, int> mIndexCur; /**< current volume index per device. */
+    int mIndexMin; /**< min volume index. */
+    int mIndexMax; /**< max volume index. */
+    const bool mCanBeMuted = true; /**< true is the stream can be muted. */
+
+    AttributesVector mAttributes;
+    StreamTypeVector mStreams; /**< Keep it for legacy. */
+};
+
+} // namespace android
diff --git a/services/audiopolicy/engine/common/include/VolumeGroup.h b/services/audiopolicy/engine/common/include/VolumeGroup.h
new file mode 100644
index 0000000..c34b406
--- /dev/null
+++ b/services/audiopolicy/engine/common/include/VolumeGroup.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <AudioPolicyManagerInterface.h>
+#include <VolumeCurve.h>
+#include <system/audio.h>
+#include <utils/RefBase.h>
+#include <HandleGenerator.h>
+#include <string>
+#include <vector>
+#include <map>
+#include <utils/Errors.h>
+
+namespace android {
+
+class VolumeGroup : public virtual RefBase, private HandleGenerator<uint32_t>
+{
+public:
+    VolumeGroup(const std::string &name, int indexMin, int indexMax);
+    std::string getName() const { return mName; }
+    volume_group_t getId() const { return mId; }
+
+    void add(const sp<VolumeCurve> &curve);
+
+    VolumeCurves *getVolumeCurves() { return &mGroupVolumeCurves; }
+
+    void addSupportedAttributes(const audio_attributes_t &attr);
+    AttributesVector getSupportedAttributes() const { return mGroupVolumeCurves.getAttributes(); }
+
+    void addSupportedStream(audio_stream_type_t stream);
+    StreamTypeVector getStreamTypes() const { return mGroupVolumeCurves.getStreamTypes(); }
+
+    void dump(String8 *dst, int spaces = 0) const;
+
+private:
+    const std::string mName;
+    const volume_group_t mId;
+    VolumeCurves mGroupVolumeCurves;
+};
+
+class VolumeGroupMap : public std::map<volume_group_t, sp<VolumeGroup> >
+{
+public:
+    void dump(String8 *dst, int spaces = 0) const;
+};
+
+} // namespace android
diff --git a/services/audiopolicy/engine/common/src/EngineBase.cpp b/services/audiopolicy/engine/common/src/EngineBase.cpp
new file mode 100644
index 0000000..07a7e65
--- /dev/null
+++ b/services/audiopolicy/engine/common/src/EngineBase.cpp
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "APM::AudioPolicyEngine/Base"
+//#define LOG_NDEBUG 0
+
+#include "EngineBase.h"
+#include "EngineDefaultConfig.h"
+#include <TypeConverter.h>
+
+namespace android {
+namespace audio_policy {
+
+void EngineBase::setObserver(AudioPolicyManagerObserver *observer)
+{
+    ALOG_ASSERT(observer != NULL, "Invalid Audio Policy Manager observer");
+    mApmObserver = observer;
+}
+
+status_t EngineBase::initCheck()
+{
+    return (mApmObserver != nullptr)? NO_ERROR : NO_INIT;
+}
+
+status_t EngineBase::setPhoneState(audio_mode_t state)
+{
+    ALOGV("setPhoneState() state %d", state);
+
+    if (state < 0 || state >= AUDIO_MODE_CNT) {
+        ALOGW("setPhoneState() invalid state %d", state);
+        return BAD_VALUE;
+    }
+
+    if (state == mPhoneState ) {
+        ALOGW("setPhoneState() setting same state %d", state);
+        return BAD_VALUE;
+    }
+
+    // store previous phone state for management of sonification strategy below
+    int oldState = mPhoneState;
+    mPhoneState = state;
+
+    if (!is_state_in_call(oldState) && is_state_in_call(state)) {
+        ALOGV("  Entering call in setPhoneState()");
+        switchVolumeCurve(AUDIO_STREAM_VOICE_CALL, AUDIO_STREAM_DTMF);
+    } else if (is_state_in_call(oldState) && !is_state_in_call(state)) {
+        ALOGV("  Exiting call in setPhoneState()");
+        restoreOriginVolumeCurve(AUDIO_STREAM_DTMF);
+    }
+    return NO_ERROR;
+}
+
+product_strategy_t EngineBase::getProductStrategyForAttributes(const audio_attributes_t &attr) const
+{
+    return mProductStrategies.getProductStrategyForAttributes(attr);
+}
+
+audio_stream_type_t EngineBase::getStreamTypeForAttributes(const audio_attributes_t &attr) const
+{
+    return mProductStrategies.getStreamTypeForAttributes(attr);
+}
+
+audio_attributes_t EngineBase::getAttributesForStreamType(audio_stream_type_t stream) const
+{
+    return mProductStrategies.getAttributesForStreamType(stream);
+}
+
+product_strategy_t EngineBase::getProductStrategyForStream(audio_stream_type_t stream) const
+{
+    return mProductStrategies.getProductStrategyForStream(stream);
+}
+
+product_strategy_t EngineBase::getProductStrategyByName(const std::string &name) const
+{
+    for (const auto &iter : mProductStrategies) {
+        if (iter.second->getName() == name) {
+            return iter.second->getId();
+        }
+    }
+    return PRODUCT_STRATEGY_NONE;
+}
+
+engineConfig::ParsingResult EngineBase::loadAudioPolicyEngineConfig()
+{
+    auto loadProductStrategies =
+            [](auto& strategyConfigs, auto& productStrategies, auto& volumeGroups) {
+        for (auto& strategyConfig : strategyConfigs) {
+            sp<ProductStrategy> strategy = new ProductStrategy(strategyConfig.name);
+            for (const auto &group : strategyConfig.attributesGroups) {
+                const auto &iter = std::find_if(begin(volumeGroups), end(volumeGroups),
+                                         [&group](const auto &volumeGroup) {
+                        return group.volumeGroup == volumeGroup.second->getName(); });
+                ALOG_ASSERT(iter != end(volumeGroups), "Invalid Volume Group Name %s",
+                            group.volumeGroup.c_str());
+                if (group.stream != AUDIO_STREAM_DEFAULT) {
+                    iter->second->addSupportedStream(group.stream);
+                }
+                for (const auto &attr : group.attributesVect) {
+                    strategy->addAttributes({group.stream, iter->second->getId(), attr});
+                    iter->second->addSupportedAttributes(attr);
+                }
+            }
+            product_strategy_t strategyId = strategy->getId();
+            productStrategies[strategyId] = strategy;
+        }
+    };
+    auto loadVolumeGroups = [](auto &volumeConfigs, auto &volumeGroups) {
+        for (auto &volumeConfig : volumeConfigs) {
+            sp<VolumeGroup> volumeGroup = new VolumeGroup(volumeConfig.name, volumeConfig.indexMin,
+                                                          volumeConfig.indexMax);
+            volumeGroups[volumeGroup->getId()] = volumeGroup;
+
+            for (auto &configCurve : volumeConfig.volumeCurves) {
+                device_category deviceCat = DEVICE_CATEGORY_SPEAKER;
+                if (!DeviceCategoryConverter::fromString(configCurve.deviceCategory, deviceCat)) {
+                    ALOGE("%s: Invalid %s", __FUNCTION__, configCurve.deviceCategory.c_str());
+                    continue;
+                }
+                sp<VolumeCurve> curve = new VolumeCurve(deviceCat);
+                for (auto &point : configCurve.curvePoints) {
+                    curve->add({point.index, point.attenuationInMb});
+                }
+                volumeGroup->add(curve);
+            }
+        }
+    };
+    auto result = engineConfig::parse();
+    if (result.parsedConfig == nullptr) {
+        ALOGW("%s: No configuration found, using default matching phone experience.", __FUNCTION__);
+        engineConfig::Config config = gDefaultEngineConfig;
+        android::status_t ret = engineConfig::parseLegacyVolumes(config.volumeGroups);
+        result = {std::make_unique<engineConfig::Config>(config),
+                  static_cast<size_t>(ret == NO_ERROR ? 0 : 1)};
+    }
+    ALOGE_IF(result.nbSkippedElement != 0, "skipped %zu elements", result.nbSkippedElement);
+    loadVolumeGroups(result.parsedConfig->volumeGroups, mVolumeGroups);
+    loadProductStrategies(result.parsedConfig->productStrategies, mProductStrategies,
+                          mVolumeGroups);
+    mProductStrategies.initialize();
+    return result;
+}
+
+StrategyVector EngineBase::getOrderedProductStrategies() const
+{
+    auto findByFlag = [](const auto &productStrategies, auto flag) {
+        return std::find_if(begin(productStrategies), end(productStrategies),
+                            [&](const auto &strategy) {
+            for (const auto &attributes : strategy.second->getAudioAttributes()) {
+                if ((attributes.flags & flag) == flag) {
+                    return true;
+                }
+            }
+            return false;
+        });
+    };
+    auto strategies = mProductStrategies;
+    auto enforcedAudibleStrategyIter = findByFlag(strategies, AUDIO_FLAG_AUDIBILITY_ENFORCED);
+
+    if (getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED &&
+            enforcedAudibleStrategyIter != strategies.end()) {
+        auto enforcedAudibleStrategy = *enforcedAudibleStrategyIter;
+        strategies.erase(enforcedAudibleStrategyIter);
+        strategies.insert(begin(strategies), enforcedAudibleStrategy);
+    }
+    StrategyVector orderedStrategies;
+    for (const auto &iter : strategies) {
+        orderedStrategies.push_back(iter.second->getId());
+    }
+    return orderedStrategies;
+}
+
+StreamTypeVector EngineBase::getStreamTypesForProductStrategy(product_strategy_t ps) const
+{
+    // @TODO default music stream to control volume if no group?
+    return (mProductStrategies.find(ps) != end(mProductStrategies)) ?
+                mProductStrategies.at(ps)->getSupportedStreams() :
+                StreamTypeVector(AUDIO_STREAM_MUSIC);
+}
+
+AttributesVector EngineBase::getAllAttributesForProductStrategy(product_strategy_t ps) const
+{
+    return (mProductStrategies.find(ps) != end(mProductStrategies)) ?
+                mProductStrategies.at(ps)->getAudioAttributes() : AttributesVector();
+}
+
+status_t EngineBase::listAudioProductStrategies(AudioProductStrategyVector &strategies) const
+{
+    for (const auto &iter : mProductStrategies) {
+        const auto &productStrategy = iter.second;
+        strategies.push_back(
+        {productStrategy->getName(), productStrategy->listAudioAttributes(),
+         productStrategy->getId()});
+    }
+    return NO_ERROR;
+}
+
+VolumeCurves *EngineBase::getVolumeCurvesForAttributes(const audio_attributes_t &attr) const
+{
+    volume_group_t volGr = mProductStrategies.getVolumeGroupForAttributes(attr);
+    const auto &iter = mVolumeGroups.find(volGr);
+    LOG_ALWAYS_FATAL_IF(iter == std::end(mVolumeGroups), "No volume groups for %s", toString(attr).c_str());
+    return mVolumeGroups.at(volGr)->getVolumeCurves();
+}
+
+VolumeCurves *EngineBase::getVolumeCurvesForStreamType(audio_stream_type_t stream) const
+{
+    volume_group_t volGr = mProductStrategies.getVolumeGroupForStreamType(stream);
+    if (volGr == VOLUME_GROUP_NONE) {
+        volGr = mProductStrategies.getDefaultVolumeGroup();
+    }
+    const auto &iter = mVolumeGroups.find(volGr);
+    LOG_ALWAYS_FATAL_IF(iter == std::end(mVolumeGroups), "No volume groups for %s",
+                toString(stream).c_str());
+    return mVolumeGroups.at(volGr)->getVolumeCurves();
+}
+
+status_t EngineBase::switchVolumeCurve(audio_stream_type_t streamSrc, audio_stream_type_t streamDst)
+{
+    auto srcCurves = getVolumeCurvesForStreamType(streamSrc);
+    auto dstCurves = getVolumeCurvesForStreamType(streamDst);
+
+    if (srcCurves == nullptr || dstCurves == nullptr) {
+        return BAD_VALUE;
+    }
+    return dstCurves->switchCurvesFrom(*srcCurves);
+}
+
+status_t EngineBase::restoreOriginVolumeCurve(audio_stream_type_t stream)
+{
+    VolumeCurves *curves = getVolumeCurvesForStreamType(stream);
+    return curves != nullptr ? curves->switchCurvesFrom(*curves) : BAD_VALUE;
+}
+
+VolumeGroupVector EngineBase::getVolumeGroups() const
+{
+    VolumeGroupVector group;
+    for (const auto &iter : mVolumeGroups) {
+        group.push_back(iter.first);
+    }
+    return group;
+}
+
+volume_group_t EngineBase::getVolumeGroupForAttributes(const audio_attributes_t &attr) const
+{
+    return mProductStrategies.getVolumeGroupForAttributes(attr);
+}
+
+volume_group_t EngineBase::getVolumeGroupForStreamType(audio_stream_type_t stream) const
+{
+    return mProductStrategies.getVolumeGroupForStreamType(stream);
+}
+
+status_t EngineBase::listAudioVolumeGroups(AudioVolumeGroupVector &groups) const
+{
+    for (const auto &iter : mVolumeGroups) {
+        groups.push_back({iter.second->getName(), iter.second->getId(),
+                          iter.second->getSupportedAttributes(), iter.second->getStreamTypes()});
+    }
+    return NO_ERROR;
+}
+
+void EngineBase::dump(String8 *dst) const
+{
+    mProductStrategies.dump(dst, 2);
+    mVolumeGroups.dump(dst, 2);
+}
+
+} // namespace audio_policy
+} // namespace android
diff --git a/services/audiopolicy/engine/common/src/EngineDefaultConfig.h b/services/audiopolicy/engine/common/src/EngineDefaultConfig.h
new file mode 100644
index 0000000..fede0d9
--- /dev/null
+++ b/services/audiopolicy/engine/common/src/EngineDefaultConfig.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <system/audio.h>
+
+namespace android {
+/**
+ * @brief AudioProductStrategies hard coded array of strategies to fill new engine API contract.
+ */
+const engineConfig::ProductStrategies gOrderedStrategies = {
+    {"STRATEGY_PHONE",
+     {
+         {"phone", AUDIO_STREAM_VOICE_CALL, "AUDIO_STREAM_VOICE_CALL",
+          {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_SOURCE_DEFAULT, 0,
+            ""}},
+         },
+         {"sco", AUDIO_STREAM_BLUETOOTH_SCO, "AUDIO_STREAM_BLUETOOTH_SCO",
+          {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_SCO,
+            ""}},
+         }
+     },
+    },
+    {"STRATEGY_SONIFICATION",
+     {
+         {"ring", AUDIO_STREAM_RING, "AUDIO_STREAM_RING",
+          {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE,
+            AUDIO_SOURCE_DEFAULT, 0, ""}}
+         },
+         {"alarm", AUDIO_STREAM_ALARM, "AUDIO_STREAM_ALARM",
+          {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ALARM, AUDIO_SOURCE_DEFAULT, 0, ""}},
+         }
+     },
+    },
+    {"STRATEGY_ENFORCED_AUDIBLE",
+     {
+         {"", AUDIO_STREAM_ENFORCED_AUDIBLE, "AUDIO_STREAM_ENFORCED_AUDIBLE",
+          {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT,
+            AUDIO_FLAG_AUDIBILITY_ENFORCED, ""}}
+         }
+     },
+    },
+    {"STRATEGY_ACCESSIBILITY",
+     {
+         {"", AUDIO_STREAM_ACCESSIBILITY, "AUDIO_STREAM_ACCESSIBILITY",
+          {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY,
+            AUDIO_SOURCE_DEFAULT, 0, ""}}
+         }
+     },
+    },
+    {"STRATEGY_SONIFICATION_RESPECTFUL",
+     {
+         {"", AUDIO_STREAM_NOTIFICATION, "AUDIO_STREAM_NOTIFICATION",
+          {
+              {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION, AUDIO_SOURCE_DEFAULT, 0, ""},
+              {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST,
+               AUDIO_SOURCE_DEFAULT, 0, ""},
+              {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT,
+               AUDIO_SOURCE_DEFAULT, 0, ""},
+              {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED,
+               AUDIO_SOURCE_DEFAULT, 0, ""},
+              {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION_EVENT,
+               AUDIO_SOURCE_DEFAULT, 0, ""}
+          }
+         }
+     },
+    },
+    {"STRATEGY_MEDIA",
+     {
+         {"music", AUDIO_STREAM_MUSIC, "AUDIO_STREAM_MUSIC",
+          {
+              {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA, AUDIO_SOURCE_DEFAULT, 0, ""},
+              {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_GAME, AUDIO_SOURCE_DEFAULT, 0, ""},
+              {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ASSISTANT, AUDIO_SOURCE_DEFAULT, 0, ""},
+              {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
+               AUDIO_SOURCE_DEFAULT, 0, ""},
+              {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT, 0, ""}
+          },
+         },
+         {"system", AUDIO_STREAM_SYSTEM, "AUDIO_STREAM_SYSTEM",
+          {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ASSISTANCE_SONIFICATION,
+            AUDIO_SOURCE_DEFAULT, 0, ""}}
+         }
+     },
+    },
+    {"STRATEGY_DTMF",
+     {
+         {"", AUDIO_STREAM_DTMF, "AUDIO_STREAM_DTMF",
+          {
+              {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING,
+               AUDIO_SOURCE_DEFAULT, 0, ""}
+          }
+         }
+     },
+    },
+    {"STRATEGY_TRANSMITTED_THROUGH_SPEAKER",
+     {
+         {"", AUDIO_STREAM_TTS, "AUDIO_STREAM_TTS",
+          {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT,
+            AUDIO_FLAG_BEACON, ""}}
+         }
+     },
+    },
+    {"STRATEGY_REROUTING",
+     {
+         {"", AUDIO_STREAM_REROUTING, "AUDIO_STREAM_REROUTING",
+          {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT, 0, ""}}
+         }
+     },
+    },
+    {"STRATEGY_PATCH",
+     {
+         {"", AUDIO_STREAM_PATCH, "AUDIO_STREAM_PATCH",
+          {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT, 0, ""}}
+         }
+     },
+    }
+};
+
+const engineConfig::Config gDefaultEngineConfig = {
+    1.0,
+    gOrderedStrategies,
+    {},
+    {},
+    {}
+};
+} // namespace android
diff --git a/services/audiopolicy/engine/common/src/ProductStrategy.cpp b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
new file mode 100644
index 0000000..f74f190
--- /dev/null
+++ b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "APM::AudioPolicyEngine/ProductStrategy"
+//#define LOG_NDEBUG 0
+
+#include "ProductStrategy.h"
+
+#include <media/TypeConverter.h>
+#include <utils/String8.h>
+#include <cstdint>
+#include <string>
+
+#include <log/log.h>
+
+
+namespace android {
+
+ProductStrategy::ProductStrategy(const std::string &name) :
+    mName(name),
+    mId(static_cast<product_strategy_t>(HandleGenerator<uint32_t>::getNextHandle()))
+{
+}
+
+void ProductStrategy::addAttributes(const AudioAttributes &audioAttributes)
+{
+    mAttributesVector.push_back(audioAttributes);
+}
+
+std::vector<android::AudioAttributes> ProductStrategy::listAudioAttributes() const
+{
+    std::vector<android::AudioAttributes> androidAa;
+    for (const auto &attr : mAttributesVector) {
+        androidAa.push_back({attr.mVolumeGroup, attr.mStream, attr.mAttributes});
+    }
+    return androidAa;
+}
+
+AttributesVector ProductStrategy::getAudioAttributes() const
+{
+    AttributesVector attrVector;
+    for (const auto &attrGroup : mAttributesVector) {
+        attrVector.push_back(attrGroup.mAttributes);
+    }
+    if (not attrVector.empty()) {
+        return attrVector;
+    }
+    return { AUDIO_ATTRIBUTES_INITIALIZER };
+}
+
+bool ProductStrategy::matches(const audio_attributes_t attr) const
+{
+    return std::find_if(begin(mAttributesVector), end(mAttributesVector),
+                        [&attr](const auto &supportedAttr) {
+        return AudioProductStrategy::attributesMatches(supportedAttr.mAttributes, attr);
+    }) != end(mAttributesVector);
+}
+
+audio_stream_type_t ProductStrategy::getStreamTypeForAttributes(
+        const audio_attributes_t &attr) const
+{
+    const auto iter = std::find_if(begin(mAttributesVector), end(mAttributesVector),
+                                   [&attr](const auto &supportedAttr) {
+        return AudioProductStrategy::attributesMatches(supportedAttr.mAttributes, attr); });
+    return iter != end(mAttributesVector) ? iter->mStream : AUDIO_STREAM_DEFAULT;
+}
+
+audio_attributes_t ProductStrategy::getAttributesForStreamType(audio_stream_type_t streamType) const
+{
+    const auto iter = std::find_if(begin(mAttributesVector), end(mAttributesVector),
+                                   [&streamType](const auto &supportedAttr) {
+        return supportedAttr.mStream == streamType; });
+    return iter != end(mAttributesVector) ? iter->mAttributes : AUDIO_ATTRIBUTES_INITIALIZER;
+}
+
+bool ProductStrategy::isDefault() const
+{
+    return std::find_if(begin(mAttributesVector), end(mAttributesVector), [](const auto &attr) {
+        return attr.mAttributes == defaultAttr; }) != end(mAttributesVector);
+}
+
+StreamTypeVector ProductStrategy::getSupportedStreams() const
+{
+    StreamTypeVector streams;
+    for (const auto &supportedAttr : mAttributesVector) {
+        if (std::find(begin(streams), end(streams), supportedAttr.mStream) == end(streams) &&
+                supportedAttr.mStream != AUDIO_STREAM_DEFAULT) {
+            streams.push_back(supportedAttr.mStream);
+        }
+    }
+    return streams;
+}
+
+bool ProductStrategy::supportStreamType(const audio_stream_type_t &streamType) const
+{
+    return std::find_if(begin(mAttributesVector), end(mAttributesVector),
+                        [&streamType](const auto &supportedAttr) {
+        return supportedAttr.mStream == streamType; }) != end(mAttributesVector);
+}
+
+volume_group_t ProductStrategy::getVolumeGroupForAttributes(const audio_attributes_t &attr) const
+{
+    for (const auto &supportedAttr : mAttributesVector) {
+        if (AudioProductStrategy::attributesMatches(supportedAttr.mAttributes, attr)) {
+            return supportedAttr.mVolumeGroup;
+        }
+    }
+    return VOLUME_GROUP_NONE;
+}
+
+volume_group_t ProductStrategy::getVolumeGroupForStreamType(audio_stream_type_t stream) const
+{
+    for (const auto &supportedAttr : mAttributesVector) {
+        if (supportedAttr.mStream == stream) {
+            return supportedAttr.mVolumeGroup;
+        }
+    }
+    return VOLUME_GROUP_NONE;
+}
+
+volume_group_t ProductStrategy::getDefaultVolumeGroup() const
+{
+    const auto &iter = std::find_if(begin(mAttributesVector), end(mAttributesVector),
+                                    [](const auto &attr) {return attr.mAttributes == defaultAttr;});
+    return iter != end(mAttributesVector) ? iter->mVolumeGroup : VOLUME_GROUP_NONE;
+}
+
+void ProductStrategy::dump(String8 *dst, int spaces) const
+{
+    dst->appendFormat("\n%*s-%s (id: %d)\n", spaces, "", mName.c_str(), mId);
+    std::string deviceLiteral;
+    if (!OutputDeviceConverter::toString(mApplicableDevices, deviceLiteral)) {
+        ALOGE("%s: failed to convert device %d", __FUNCTION__, mApplicableDevices);
+    }
+    dst->appendFormat("%*sSelected Device: {type:%s, @:%s}\n", spaces + 2, "",
+                       deviceLiteral.c_str(), mDeviceAddress.c_str());
+
+    for (const auto &attr : mAttributesVector) {
+        dst->appendFormat("%*sGroup: %d stream: %s\n", spaces + 3, "", attr.mVolumeGroup,
+                          android::toString(attr.mStream).c_str());
+        dst->appendFormat("%*s Attributes: ", spaces + 3, "");
+        std::string attStr =
+                attr.mAttributes == defaultAttr ? "{ Any }" : android::toString(attr.mAttributes);
+        dst->appendFormat("%s\n", attStr.c_str());
+    }
+}
+
+product_strategy_t ProductStrategyMap::getProductStrategyForAttributes(
+        const audio_attributes_t &attr) const
+{
+    for (const auto &iter : *this) {
+        if (iter.second->matches(attr)) {
+            return iter.second->getId();
+        }
+    }
+    ALOGV("%s: No matching product strategy for attributes %s, return default", __FUNCTION__,
+          toString(attr).c_str());
+    return getDefault();
+}
+
+audio_attributes_t ProductStrategyMap::getAttributesForStreamType(audio_stream_type_t stream) const
+{
+    for (const auto &iter : *this) {
+        const auto strategy = iter.second;
+        if (strategy->supportStreamType(stream)) {
+            return strategy->getAttributesForStreamType(stream);
+        }
+    }
+    ALOGV("%s: No product strategy for stream %s, using default", __FUNCTION__,
+          toString(stream).c_str());
+    return {};
+}
+
+audio_stream_type_t ProductStrategyMap::getStreamTypeForAttributes(
+        const audio_attributes_t &attr) const
+{
+    for (const auto &iter : *this) {
+        audio_stream_type_t stream = iter.second->getStreamTypeForAttributes(attr);
+        if (stream != AUDIO_STREAM_DEFAULT) {
+            return stream;
+        }
+    }
+    ALOGV("%s: No product strategy for attributes %s, using default (aka MUSIC)", __FUNCTION__,
+          toString(attr).c_str());
+    return  AUDIO_STREAM_MUSIC;
+}
+
+product_strategy_t ProductStrategyMap::getDefault() const
+{
+    if (mDefaultStrategy != PRODUCT_STRATEGY_NONE) {
+        return mDefaultStrategy;
+    }
+    for (const auto &iter : *this) {
+        if (iter.second->isDefault()) {
+            ALOGV("%s: using default %s", __FUNCTION__, iter.second->getName().c_str());
+            return iter.second->getId();
+        }
+    }
+    ALOGE("%s: No default product strategy defined", __FUNCTION__);
+    return PRODUCT_STRATEGY_NONE;
+}
+
+audio_attributes_t ProductStrategyMap::getAttributesForProductStrategy(
+        product_strategy_t strategy) const
+{
+    if (find(strategy) == end()) {
+        ALOGE("Invalid %d strategy requested", strategy);
+        return AUDIO_ATTRIBUTES_INITIALIZER;
+    }
+    return at(strategy)->getAudioAttributes()[0];
+}
+
+product_strategy_t ProductStrategyMap::getProductStrategyForStream(audio_stream_type_t stream) const
+{
+    for (const auto &iter : *this) {
+        if (iter.second->supportStreamType(stream)) {
+            return iter.second->getId();
+        }
+    }
+    ALOGV("%s: No product strategy for stream %d, using default", __FUNCTION__, stream);
+    return getDefault();
+}
+
+
+audio_devices_t ProductStrategyMap::getDeviceTypesForProductStrategy(
+        product_strategy_t strategy) const
+{
+    if (find(strategy) == end()) {
+        ALOGE("Invalid %d strategy requested, returning device for default strategy", strategy);
+        product_strategy_t defaultStrategy = getDefault();
+        if (defaultStrategy == PRODUCT_STRATEGY_NONE) {
+            return AUDIO_DEVICE_NONE;
+        }
+        return at(getDefault())->getDeviceTypes();
+    }
+    return at(strategy)->getDeviceTypes();
+}
+
+std::string ProductStrategyMap::getDeviceAddressForProductStrategy(product_strategy_t psId) const
+{
+    if (find(psId) == end()) {
+        ALOGE("Invalid %d strategy requested, returning device for default strategy", psId);
+        product_strategy_t defaultStrategy = getDefault();
+        if (defaultStrategy == PRODUCT_STRATEGY_NONE) {
+            return {};
+        }
+        return at(getDefault())->getDeviceAddress();
+    }
+    return at(psId)->getDeviceAddress();
+}
+
+volume_group_t ProductStrategyMap::getVolumeGroupForAttributes(const audio_attributes_t &attr) const
+{
+    for (const auto &iter : *this) {
+        volume_group_t group = iter.second->getVolumeGroupForAttributes(attr);
+        if (group != VOLUME_GROUP_NONE) {
+            return group;
+        }
+    }
+    return getDefaultVolumeGroup();
+}
+
+volume_group_t ProductStrategyMap::getVolumeGroupForStreamType(audio_stream_type_t stream) const
+{
+    for (const auto &iter : *this) {
+        volume_group_t group = iter.second->getVolumeGroupForStreamType(stream);
+        if (group != VOLUME_GROUP_NONE) {
+            return group;
+        }
+    }
+    ALOGW("%s: no volume group for %s, using default", __func__, toString(stream).c_str());
+    return getDefaultVolumeGroup();
+}
+
+volume_group_t ProductStrategyMap::getDefaultVolumeGroup() const
+{
+    product_strategy_t defaultStrategy = getDefault();
+    if (defaultStrategy == PRODUCT_STRATEGY_NONE) {
+        return VOLUME_GROUP_NONE;
+    }
+    return at(defaultStrategy)->getDefaultVolumeGroup();
+}
+
+void ProductStrategyMap::initialize()
+{
+    mDefaultStrategy = getDefault();
+    ALOG_ASSERT(mDefaultStrategy != PRODUCT_STRATEGY_NONE, "No default product strategy found");
+}
+
+void ProductStrategyMap::dump(String8 *dst, int spaces) const
+{
+    dst->appendFormat("%*sProduct Strategies dump:", spaces, "");
+    for (const auto &iter : *this) {
+        iter.second->dump(dst, spaces + 2);
+    }
+}
+
+}
+
diff --git a/services/audiopolicy/engine/common/src/VolumeCurve.cpp b/services/audiopolicy/engine/common/src/VolumeCurve.cpp
new file mode 100644
index 0000000..c352578
--- /dev/null
+++ b/services/audiopolicy/engine/common/src/VolumeCurve.cpp
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "APM::VolumeCurve"
+//#define LOG_NDEBUG 0
+
+#include "VolumeCurve.h"
+#include "TypeConverter.h"
+#include <media/TypeConverter.h>
+
+namespace android {
+
+float VolumeCurve::volIndexToDb(int indexInUi, int volIndexMin, int volIndexMax) const
+{
+    ALOG_ASSERT(!mCurvePoints.isEmpty(), "Invalid volume curve");
+    if (volIndexMin < 0 || volIndexMax < 0) {
+        // In order to let AudioService initialize the min and max, convention is to use -1
+        return NAN;
+    }
+    if (indexInUi < volIndexMin) {
+        // an index of 0 means mute request when volIndexMin > 0
+        if (indexInUi == 0) {
+            ALOGV("VOLUME forcing mute for index 0 with min index %d", volIndexMin);
+            return VOLUME_MIN_DB;
+        }
+        ALOGV("VOLUME remapping index from %d to min index %d", indexInUi, volIndexMin);
+        indexInUi = volIndexMin;
+    } else if (indexInUi > volIndexMax) {
+        ALOGV("VOLUME remapping index from %d to max index %d", indexInUi, volIndexMax);
+        indexInUi = volIndexMax;
+    }
+
+    size_t nbCurvePoints = mCurvePoints.size();
+    // the volume index in the UI is relative to the min and max volume indices for this stream
+    int nbSteps = 1 + mCurvePoints[nbCurvePoints - 1].mIndex - mCurvePoints[0].mIndex;
+    int volIdx = (nbSteps * (indexInUi - volIndexMin)) / (volIndexMax - volIndexMin);
+
+    // Where would this volume index been inserted in the curve point
+    size_t indexInUiPosition = mCurvePoints.orderOf(CurvePoint(volIdx, 0));
+    if (indexInUiPosition >= nbCurvePoints) {
+        //use last point of table
+        return mCurvePoints[nbCurvePoints - 1].mAttenuationInMb / 100.0f;
+    }
+    if (indexInUiPosition == 0) {
+        if (indexInUiPosition != mCurvePoints[0].mIndex) {
+            return VOLUME_MIN_DB; // out of bounds
+        }
+        return mCurvePoints[0].mAttenuationInMb / 100.0f;
+    }
+    // linear interpolation in the attenuation table in dB
+    float decibels = (mCurvePoints[indexInUiPosition - 1].mAttenuationInMb / 100.0f) +
+            ((float)(volIdx - mCurvePoints[indexInUiPosition - 1].mIndex)) *
+                ( ((mCurvePoints[indexInUiPosition].mAttenuationInMb / 100.0f) -
+                        (mCurvePoints[indexInUiPosition - 1].mAttenuationInMb / 100.0f)) /
+                    ((float)(mCurvePoints[indexInUiPosition].mIndex -
+                            mCurvePoints[indexInUiPosition - 1].mIndex)) );
+
+    ALOGV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f]",
+            mCurvePoints[indexInUiPosition - 1].mIndex, volIdx,
+            mCurvePoints[indexInUiPosition].mIndex,
+            ((float)mCurvePoints[indexInUiPosition - 1].mAttenuationInMb / 100.0f), decibels,
+            ((float)mCurvePoints[indexInUiPosition].mAttenuationInMb / 100.0f));
+
+    return decibels;
+}
+
+void VolumeCurve::dump(String8 *dst, int spaces, bool curvePoints) const
+{
+    if (!curvePoints) {
+        return;
+    }
+    dst->append(" {");
+    for (size_t i = 0; i < mCurvePoints.size(); i++) {
+        dst->appendFormat("%*s(%3d, %5d)", spaces, "", mCurvePoints[i].mIndex,
+                          mCurvePoints[i].mAttenuationInMb);
+        dst->appendFormat(i == (mCurvePoints.size() - 1) ? " }\n" : ", ");
+    }
+}
+
+void VolumeCurves::dump(String8 *dst, int spaces, bool curvePoints) const
+{
+    if (!curvePoints) {
+//        dst->appendFormat("%*s%02d      %s         %03d        %03d        ", spaces, "",
+//                          mStream, mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax);
+        dst->appendFormat("%*s Can be muted  Index Min  Index Max  Index Cur [device : index]...\n",
+                          spaces + 1, "");
+        dst->appendFormat("%*s %s         %02d         %02d         ", spaces + 1, "",
+                          mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax);
+        for (const auto &pair : mIndexCur) {
+            dst->appendFormat("%04x : %02d, ", pair.first, pair.second);
+        }
+        dst->appendFormat("\n");
+        return;
+    }
+    std::string streamNames;
+    for (const auto &stream : mStreams) {
+        streamNames += android::toString(stream) + "("+std::to_string(stream)+") ";
+    }
+    dst->appendFormat("%*sVolume Curves Streams/Attributes, Curve points Streams for device"
+                      " category (index, attenuation in millibel)\n", spaces, "");
+    dst->appendFormat("%*s Streams: %s \n", spaces, "", streamNames.c_str());
+    if (!mAttributes.empty()) dst->appendFormat("%*s Attributes:", spaces, "");
+    for (const auto &attributes : mAttributes) {
+        std::string attStr = attributes == defaultAttr ? "{ Any }" : android::toString(attributes);
+        dst->appendFormat("%*s %s\n", attributes == mAttributes.front() ? 0 : spaces + 13, "",
+                          attStr.c_str());
+    }
+    for (size_t i = 0; i < size(); i++) {
+        std::string deviceCatLiteral;
+        DeviceCategoryConverter::toString(keyAt(i), deviceCatLiteral);
+        dst->appendFormat("%*s %s :", spaces, "", deviceCatLiteral.c_str());
+        valueAt(i)->dump(dst, 1, true);
+    }
+}
+
+} // namespace android
diff --git a/services/audiopolicy/engine/common/src/VolumeGroup.cpp b/services/audiopolicy/engine/common/src/VolumeGroup.cpp
new file mode 100644
index 0000000..e189807
--- /dev/null
+++ b/services/audiopolicy/engine/common/src/VolumeGroup.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "APM::AudioPolicyEngine/VolumeGroup"
+//#define LOG_NDEBUG 0
+
+#include "VolumeGroup.h"
+#include <media/TypeConverter.h>
+#include <utils/String8.h>
+#include <cstdint>
+#include <string>
+
+#include <log/log.h>
+
+
+namespace android {
+
+//
+// VolumeGroup implementation
+//
+VolumeGroup::VolumeGroup(const std::string &name, int indexMin, int indexMax) :
+    mName(name), mId(static_cast<volume_group_t>(HandleGenerator<uint32_t>::getNextHandle())),
+    mGroupVolumeCurves(VolumeCurves(indexMin, indexMax))
+{
+}
+
+void VolumeGroup::dump(String8 *dst, int spaces) const
+{
+    dst->appendFormat("\n%*s-%s (id: %d)\n", spaces, "", mName.c_str(), mId);
+    mGroupVolumeCurves.dump(dst, spaces + 2, true);
+    mGroupVolumeCurves.dump(dst, spaces + 2, false);
+    dst->appendFormat("\n");
+}
+
+void VolumeGroup::add(const sp<VolumeCurve> &curve)
+{
+    mGroupVolumeCurves.add(curve);
+}
+
+void VolumeGroup::addSupportedAttributes(const audio_attributes_t &attr)
+{
+    mGroupVolumeCurves.addAttributes(attr);
+}
+
+void VolumeGroup::addSupportedStream(audio_stream_type_t stream)
+{
+    mGroupVolumeCurves.addStreamType(stream);
+}
+
+//
+// VolumeGroupMap implementation
+//
+void VolumeGroupMap::dump(String8 *dst, int spaces) const
+{
+    dst->appendFormat("\n%*sVolume Groups dump:", spaces, "");
+    for (const auto &iter : *this) {
+        iter.second->dump(dst, spaces + 2);
+    }
+}
+
+} // namespace android
+
diff --git a/services/audiopolicy/engine/config/Android.bp b/services/audiopolicy/engine/config/Android.bp
new file mode 100644
index 0000000..6e72f2a
--- /dev/null
+++ b/services/audiopolicy/engine/config/Android.bp
@@ -0,0 +1,31 @@
+cc_library_static {
+    name: "libaudiopolicyengine_config",
+    export_include_dirs: ["include"],
+    include_dirs: [
+        "external/libxml2/include",
+        "external/icu/icu4c/source/common",
+    ],
+    srcs: [
+        "src/EngineConfig.cpp",
+    ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+    ],
+    shared_libs: [
+        "libmedia_helper",
+        "libandroidicu",
+        "libxml2",
+        "libutils",
+        "liblog",
+        "libcutils",
+    ],
+    static_libs: [
+        "libaudiopolicycomponents",
+    ],
+    header_libs: [
+        "libaudio_system_headers",
+        "libaudiopolicycommon",
+    ],
+}
diff --git a/services/audiopolicy/engine/config/include/EngineConfig.h b/services/audiopolicy/engine/config/include/EngineConfig.h
new file mode 100644
index 0000000..7f5ed5e
--- /dev/null
+++ b/services/audiopolicy/engine/config/include/EngineConfig.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <system/audio.h>
+
+#include <string>
+#include <vector>
+#include <utils/Errors.h>
+
+struct _xmlNode;
+struct _xmlDoc;
+
+namespace android {
+namespace engineConfig {
+
+/** Default path of audio policy usages configuration file. */
+constexpr char DEFAULT_PATH[] = "/vendor/etc/audio_policy_engine_configuration.xml";
+
+/** Directories where the effect libraries will be search for. */
+constexpr const char* POLICY_USAGE_LIBRARY_PATH[] = {"/odm/etc/", "/vendor/etc/", "/system/etc/"};
+
+using AttributesVector = std::vector<audio_attributes_t>;
+using StreamVector = std::vector<audio_stream_type_t>;
+
+struct AttributesGroup {
+    std::string name;
+    audio_stream_type_t stream;
+    std::string volumeGroup;
+    AttributesVector attributesVect;
+};
+
+using AttributesGroups = std::vector<AttributesGroup>;
+
+struct CurvePoint {
+    int index;
+    int attenuationInMb;
+};
+using CurvePoints = std::vector<CurvePoint>;
+
+struct VolumeCurve {
+    std::string deviceCategory;
+    CurvePoints curvePoints;
+};
+using VolumeCurves = std::vector<VolumeCurve>;
+
+struct VolumeGroup {
+    std::string name;
+    int indexMin;
+    int indexMax;
+    VolumeCurves volumeCurves;
+};
+using VolumeGroups = std::vector<VolumeGroup>;
+
+struct ProductStrategy {
+    std::string name;
+    AttributesGroups attributesGroups;
+};
+
+using ProductStrategies = std::vector<ProductStrategy>;
+
+using ValuePair = std::pair<uint32_t, std::string>;
+using ValuePairs = std::vector<ValuePair>;
+
+struct CriterionType
+{
+    std::string name;
+    bool isInclusive;
+    ValuePairs valuePairs;
+};
+
+using CriterionTypes = std::vector<CriterionType>;
+
+struct Criterion
+{
+    std::string name;
+    std::string typeName;
+    std::string defaultLiteralValue;
+};
+
+using Criteria = std::vector<Criterion>;
+
+struct Config {
+    float version;
+    ProductStrategies productStrategies;
+    Criteria criteria;
+    CriterionTypes criterionTypes;
+    VolumeGroups volumeGroups;
+};
+
+/** Result of `parse(const char*)` */
+struct ParsingResult {
+    /** Parsed config, nullptr if the xml lib could not load the file */
+    std::unique_ptr<Config> parsedConfig;
+    size_t nbSkippedElement; //< Number of skipped invalid product strategies
+};
+
+/** Parses the provided audio policy usage configuration.
+ * @return audio policy usage @see Config
+ */
+ParsingResult parse(const char* path = DEFAULT_PATH);
+android::status_t parseLegacyVolumes(VolumeGroups &volumeGroups);
+
+} // namespace engineConfig
+} // namespace android
diff --git a/services/audiopolicy/engine/config/src/EngineConfig.cpp b/services/audiopolicy/engine/config/src/EngineConfig.cpp
new file mode 100644
index 0000000..1ad7739
--- /dev/null
+++ b/services/audiopolicy/engine/config/src/EngineConfig.cpp
@@ -0,0 +1,699 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "APM::AudioPolicyEngine/Config"
+//#define LOG_NDEBUG 0
+
+#include "EngineConfig.h"
+#include <policy.h>
+#include <cutils/properties.h>
+#include <media/TypeConverter.h>
+#include <media/convert.h>
+#include <utils/Log.h>
+#include <libxml/parser.h>
+#include <libxml/xinclude.h>
+#include <string>
+#include <vector>
+#include <map>
+#include <sstream>
+#include <istream>
+
+#include <cstdint>
+#include <string>
+
+
+namespace android {
+
+using utilities::convertTo;
+
+namespace engineConfig {
+
+static constexpr const char *gVersionAttribute = "version";
+static const char *const gReferenceElementName = "reference";
+static const char *const gReferenceAttributeName = "name";
+
+template<typename E, typename C>
+struct BaseSerializerTraits {
+    typedef E Element;
+    typedef C Collection;
+    typedef void* PtrSerializingCtx;
+};
+
+struct AttributesGroupTraits : public BaseSerializerTraits<AttributesGroup, AttributesGroups> {
+    static constexpr const char *tag = "AttributesGroup";
+    static constexpr const char *collectionTag = "AttributesGroups";
+
+    struct Attributes {
+        static constexpr const char *name = "name";
+        static constexpr const char *streamType = "streamType";
+        static constexpr const char *volumeGroup = "volumeGroup";
+    };
+    static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root, Collection &ps);
+};
+
+struct ProductStrategyTraits : public BaseSerializerTraits<ProductStrategy, ProductStrategies> {
+    static constexpr const char *tag = "ProductStrategy";
+    static constexpr const char *collectionTag = "ProductStrategies";
+
+    struct Attributes {
+        static constexpr const char *name = "name";
+    };
+    static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root, Collection &ps);
+};
+struct ValueTraits : public BaseSerializerTraits<ValuePair, ValuePairs> {
+    static constexpr const char *tag = "value";
+    static constexpr const char *collectionTag = "values";
+
+    struct Attributes {
+        static constexpr const char *literal = "literal";
+        static constexpr const char *numerical = "numerical";
+    };
+
+    static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root,
+                                         Collection &collection);
+};
+struct CriterionTypeTraits : public BaseSerializerTraits<CriterionType, CriterionTypes> {
+    static constexpr const char *tag = "criterion_type";
+    static constexpr const char *collectionTag = "criterion_types";
+
+    struct Attributes {
+        static constexpr const char *name = "name";
+        static constexpr const char *type = "type";
+    };
+
+    static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root,
+                                         Collection &collection);
+};
+struct CriterionTraits : public BaseSerializerTraits<Criterion, Criteria> {
+    static constexpr const char *tag = "criterion";
+    static constexpr const char *collectionTag = "criteria";
+
+    struct Attributes {
+        static constexpr const char *name = "name";
+        static constexpr const char *type = "type";
+        static constexpr const char *defaultVal = "default";
+    };
+
+    static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root,
+                                         Collection &collection);
+};
+struct VolumeTraits : public BaseSerializerTraits<VolumeCurve, VolumeCurves> {
+    static constexpr const char *tag = "volume";
+    static constexpr const char *collectionTag = "volumes";
+    static constexpr const char *volumePointTag = "point";
+
+    struct Attributes {
+        static constexpr const char *deviceCategory = "deviceCategory";
+        static constexpr const char *stream = "stream"; // For legacy volume curves
+        static constexpr const char *reference = "ref"; /**< For volume curves factorization. */
+    };
+
+    static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root,
+                                         Collection &collection);
+};
+struct VolumeGroupTraits : public BaseSerializerTraits<VolumeGroup, VolumeGroups> {
+    static constexpr const char *tag = "volumeGroup";
+    static constexpr const char *collectionTag = "volumeGroups";
+
+    struct Attributes {
+        static constexpr const char *name = "name";
+        static constexpr const char *stream = "stream"; // For legacy volume curves
+        static constexpr const char *indexMin = "indexMin";
+        static constexpr const char *indexMax = "indexMax";
+    };
+
+    static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root,
+                                         Collection &collection);
+};
+
+using xmlCharUnique = std::unique_ptr<xmlChar, decltype(xmlFree)>;
+
+std::string getXmlAttribute(const xmlNode *cur, const char *attribute)
+{
+    xmlCharUnique charPtr(xmlGetProp(cur, reinterpret_cast<const xmlChar *>(attribute)), xmlFree);
+    if (charPtr == NULL) {
+        return "";
+    }
+    std::string value(reinterpret_cast<const char*>(charPtr.get()));
+    return value;
+}
+
+static void getReference(const _xmlNode *root, const _xmlNode *&refNode, const std::string &refName,
+                         const char *collectionTag)
+{
+    for (root = root->xmlChildrenNode; root != NULL; root = root->next) {
+        if (!xmlStrcmp(root->name, (const xmlChar *)collectionTag)) {
+            for (xmlNode *cur = root->xmlChildrenNode; cur != NULL; cur = cur->next) {
+                if ((!xmlStrcmp(cur->name, (const xmlChar *)gReferenceElementName))) {
+                    std::string name = getXmlAttribute(cur, gReferenceAttributeName);
+                    if (refName == name) {
+                        refNode = cur;
+                        return;
+                    }
+                }
+            }
+        }
+    }
+    return;
+}
+
+template <class Trait>
+static status_t deserializeCollection(_xmlDoc *doc, const _xmlNode *cur,
+                                      typename Trait::Collection &collection,
+                                      size_t &nbSkippedElement)
+{
+    for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) {
+        if (xmlStrcmp(cur->name, (const xmlChar *)Trait::collectionTag) &&
+            xmlStrcmp(cur->name, (const xmlChar *)Trait::tag)) {
+            continue;
+        }
+        const xmlNode *child = cur;
+        if (!xmlStrcmp(child->name, (const xmlChar *)Trait::collectionTag)) {
+            child = child->xmlChildrenNode;
+        }
+        for (; child != NULL; child = child->next) {
+            if (!xmlStrcmp(child->name, (const xmlChar *)Trait::tag)) {
+                status_t status = Trait::deserialize(doc, child, collection);
+                if (status != NO_ERROR) {
+                    nbSkippedElement += 1;
+                }
+            }
+        }
+        if (!xmlStrcmp(cur->name, (const xmlChar *)Trait::tag)) {
+            return NO_ERROR;
+        }
+    }
+    return NO_ERROR;
+}
+
+static constexpr const char *attributesAttributeRef = "attributesRef"; /**< for factorization. */
+
+static status_t parseAttributes(const _xmlNode *cur, audio_attributes_t &attributes)
+{
+    for (; cur != NULL; cur = cur->next) {
+        if (!xmlStrcmp(cur->name, (const xmlChar *)("ContentType"))) {
+            std::string contentTypeXml = getXmlAttribute(cur, "value");
+            audio_content_type_t contentType;
+            if (not AudioContentTypeConverter::fromString(contentTypeXml.c_str(), contentType)) {
+                ALOGE("Invalid content type %s", contentTypeXml.c_str());
+                return BAD_VALUE;
+            }
+            attributes.content_type = contentType;
+            ALOGV("%s content type %s",  __FUNCTION__, contentTypeXml.c_str());
+        }
+        if (!xmlStrcmp(cur->name, (const xmlChar *)("Usage"))) {
+            std::string usageXml = getXmlAttribute(cur, "value");
+            audio_usage_t usage;
+            if (not UsageTypeConverter::fromString(usageXml.c_str(), usage)) {
+                ALOGE("Invalid usage %s", usageXml.c_str());
+                return BAD_VALUE;
+            }
+            attributes.usage = usage;
+            ALOGV("%s usage %s",  __FUNCTION__, usageXml.c_str());
+        }
+        if (!xmlStrcmp(cur->name, (const xmlChar *)("Flags"))) {
+            std::string flags = getXmlAttribute(cur, "value");
+
+            ALOGV("%s flags %s",  __FUNCTION__, flags.c_str());
+            attributes.flags = AudioFlagConverter::maskFromString(flags, " ");
+        }
+        if (!xmlStrcmp(cur->name, (const xmlChar *)("Bundle"))) {
+            std::string bundleKey = getXmlAttribute(cur, "key");
+            std::string bundleValue = getXmlAttribute(cur, "value");
+
+            ALOGV("%s Bundle %s %s",  __FUNCTION__, bundleKey.c_str(), bundleValue.c_str());
+
+            std::string tags(bundleKey + "=" + bundleValue);
+            std::strncpy(attributes.tags, tags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1);
+        }
+    }
+    return NO_ERROR;
+}
+
+static status_t deserializeAttributes(_xmlDoc *doc, const _xmlNode *cur,
+                                      audio_attributes_t &attributes) {
+    // Retrieve content type, usage, flags, and bundle from xml
+    for (; cur != NULL; cur = cur->next) {
+        if (not xmlStrcmp(cur->name, (const xmlChar *)("Attributes"))) {
+            const xmlNode *attrNode = cur;
+            std::string attrRef = getXmlAttribute(cur, attributesAttributeRef);
+            if (!attrRef.empty()) {
+                getReference(xmlDocGetRootElement(doc), attrNode, attrRef, attributesAttributeRef);
+                if (attrNode == NULL) {
+                    ALOGE("%s: No reference found for %s", __FUNCTION__, attrRef.c_str());
+                    return BAD_VALUE;
+                }
+                return deserializeAttributes(doc, attrNode->xmlChildrenNode, attributes);
+            }
+            return parseAttributes(attrNode->xmlChildrenNode, attributes);
+        }
+        if (not xmlStrcmp(cur->name, (const xmlChar *)("ContentType")) ||
+                not xmlStrcmp(cur->name, (const xmlChar *)("Usage")) ||
+                not xmlStrcmp(cur->name, (const xmlChar *)("Flags")) ||
+                not xmlStrcmp(cur->name, (const xmlChar *)("Bundle"))) {
+            return parseAttributes(cur, attributes);
+        }
+    }
+    return BAD_VALUE;
+}
+
+static status_t deserializeAttributesCollection(_xmlDoc *doc, const _xmlNode *cur,
+                                                AttributesVector &collection)
+{
+    status_t ret = BAD_VALUE;
+    // Either we do provide only one attributes or a collection of supported attributes
+    for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) {
+        if (not xmlStrcmp(cur->name, (const xmlChar *)("Attributes")) ||
+                not xmlStrcmp(cur->name, (const xmlChar *)("ContentType")) ||
+                not xmlStrcmp(cur->name, (const xmlChar *)("Usage")) ||
+                not xmlStrcmp(cur->name, (const xmlChar *)("Flags")) ||
+                not xmlStrcmp(cur->name, (const xmlChar *)("Bundle"))) {
+            audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
+            ret = deserializeAttributes(doc, cur, attributes);
+            if (ret == NO_ERROR) {
+                collection.push_back(attributes);
+                // We are done if the "Attributes" balise is omitted, only one Attributes is allowed
+                if (xmlStrcmp(cur->name, (const xmlChar *)("Attributes"))) {
+                    return ret;
+                }
+            }
+        }
+    }
+    return ret;
+}
+
+status_t AttributesGroupTraits::deserialize(_xmlDoc *doc, const _xmlNode *child,
+                                            Collection &attributesGroup)
+{
+    std::string name = getXmlAttribute(child, Attributes::name);
+    if (name.empty()) {
+        ALOGV("AttributesGroupTraits No attribute %s found", Attributes::name);
+    }
+    ALOGV("%s: %s = %s", __FUNCTION__, Attributes::name, name.c_str());
+
+    std::string volumeGroup = getXmlAttribute(child, Attributes::volumeGroup);
+    if (volumeGroup.empty()) {
+        ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::volumeGroup);
+    }
+    ALOGV("%s: %s = %s", __FUNCTION__, Attributes::volumeGroup, volumeGroup.c_str());
+
+    audio_stream_type_t streamType = AUDIO_STREAM_DEFAULT;
+    std::string streamTypeXml = getXmlAttribute(child, Attributes::streamType);
+    if (streamTypeXml.empty()) {
+        ALOGV("%s: No attribute %s found", __FUNCTION__, Attributes::streamType);
+    } else {
+        ALOGV("%s: %s = %s", __FUNCTION__, Attributes::streamType, streamTypeXml.c_str());
+        if (not StreamTypeConverter::fromString(streamTypeXml.c_str(), streamType)) {
+            ALOGE("Invalid stream type %s", streamTypeXml.c_str());
+            return BAD_VALUE;
+        }
+    }
+    AttributesVector attributesVect;
+    deserializeAttributesCollection(doc, child, attributesVect);
+
+    attributesGroup.push_back({name, streamType, volumeGroup, attributesVect});
+    return NO_ERROR;
+}
+
+status_t ValueTraits::deserialize(_xmlDoc */*doc*/, const _xmlNode *child, Collection &values)
+{
+    std::string literal = getXmlAttribute(child, Attributes::literal);
+    if (literal.empty()) {
+        ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::literal);
+        return BAD_VALUE;
+    }
+    uint32_t numerical = 0;
+    std::string numericalTag = getXmlAttribute(child, Attributes::numerical);
+    if (numericalTag.empty()) {
+        ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::literal);
+        return BAD_VALUE;
+    }
+    if (!convertTo(numericalTag, numerical)) {
+        ALOGE("%s: : Invalid value(%s)", __FUNCTION__, numericalTag.c_str());
+        return BAD_VALUE;
+    }
+    values.push_back({numerical, literal});
+    return NO_ERROR;
+}
+
+status_t CriterionTypeTraits::deserialize(_xmlDoc *doc, const _xmlNode *child,
+                                          Collection &criterionTypes)
+{
+    std::string name = getXmlAttribute(child, Attributes::name);
+    if (name.empty()) {
+        ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::name);
+        return BAD_VALUE;
+    }
+    ALOGV("%s: %s %s = %s", __FUNCTION__, tag, Attributes::name, name.c_str());
+
+    std::string type = getXmlAttribute(child, Attributes::type);
+    if (type.empty()) {
+        ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::type);
+        return BAD_VALUE;
+    }
+    ALOGV("%s: %s %s = %s", __FUNCTION__, tag, Attributes::type, type.c_str());
+    bool isInclusive(type == "inclusive");
+
+    ValuePairs pairs;
+    size_t nbSkippedElements = 0;
+    deserializeCollection<ValueTraits>(doc, child, pairs, nbSkippedElements);
+    criterionTypes.push_back({name, isInclusive, pairs});
+    return NO_ERROR;
+}
+
+status_t CriterionTraits::deserialize(_xmlDoc */*doc*/, const _xmlNode *child,
+                                      Collection &criteria)
+{
+    std::string name = getXmlAttribute(child, Attributes::name);
+    if (name.empty()) {
+        ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::name);
+        return BAD_VALUE;
+    }
+    ALOGV("%s: %s = %s", __FUNCTION__, Attributes::name, name.c_str());
+
+    std::string defaultValue = getXmlAttribute(child, Attributes::defaultVal);
+    if (defaultValue.empty()) {
+        // Not mandatory to provide a default value for a criterion, even it is recommanded...
+        ALOGV("%s: No attribute %s found (but recommanded)", __FUNCTION__, Attributes::defaultVal);
+    }
+    ALOGV("%s: %s = %s", __FUNCTION__, Attributes::defaultVal, defaultValue.c_str());
+
+    std::string typeName = getXmlAttribute(child, Attributes::type);
+    if (typeName.empty()) {
+        ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::name);
+        return BAD_VALUE;
+    }
+    ALOGV("%s: %s = %s", __FUNCTION__, Attributes::type, typeName.c_str());
+
+    criteria.push_back({name, typeName, defaultValue});
+    return NO_ERROR;
+}
+
+status_t ProductStrategyTraits::deserialize(_xmlDoc *doc, const _xmlNode *child,
+                                            Collection &strategies)
+{
+    std::string name = getXmlAttribute(child, Attributes::name);
+    if (name.empty()) {
+        ALOGE("ProductStrategyTraits No attribute %s found", Attributes::name);
+        return BAD_VALUE;
+    }
+    ALOGV("%s: %s = %s", __FUNCTION__, Attributes::name, name.c_str());
+
+    size_t skipped = 0;
+    AttributesGroups attrGroups;
+    deserializeCollection<AttributesGroupTraits>(doc, child, attrGroups, skipped);
+
+    strategies.push_back({name, attrGroups});
+    return NO_ERROR;
+}
+
+status_t VolumeTraits::deserialize(_xmlDoc *doc, const _xmlNode *root, Collection &volumes)
+{
+    std::string deviceCategory = getXmlAttribute(root, Attributes::deviceCategory);
+    if (deviceCategory.empty()) {
+        ALOGW("%s: No %s found", __FUNCTION__, Attributes::deviceCategory);
+    }
+    std::string referenceName = getXmlAttribute(root, Attributes::reference);
+    const _xmlNode *ref = NULL;
+    if (!referenceName.empty()) {
+        getReference(xmlDocGetRootElement(doc), ref, referenceName, collectionTag);
+        if (ref == NULL) {
+            ALOGE("%s: No reference Ptr found for %s", __FUNCTION__, referenceName.c_str());
+            return BAD_VALUE;
+        }
+    }
+    // Retrieve curve point from reference element if found or directly from current curve
+    CurvePoints curvePoints;
+    for (const xmlNode *child = referenceName.empty() ?
+         root->xmlChildrenNode : ref->xmlChildrenNode; child != NULL; child = child->next) {
+        if (!xmlStrcmp(child->name, (const xmlChar *)volumePointTag)) {
+            xmlCharUnique pointXml(xmlNodeListGetString(doc, child->xmlChildrenNode, 1), xmlFree);
+            if (pointXml == NULL) {
+                return BAD_VALUE;
+            }
+            ALOGV("%s: %s=%s", __func__, tag, reinterpret_cast<const char*>(pointXml.get()));
+            std::vector<int> point;
+            collectionFromString<DefaultTraits<int>>(
+                        reinterpret_cast<const char*>(pointXml.get()), point, ",");
+            if (point.size() != 2) {
+                ALOGE("%s: Invalid %s: %s", __func__, volumePointTag,
+                      reinterpret_cast<const char*>(pointXml.get()));
+                return BAD_VALUE;
+            }
+            curvePoints.push_back({point[0], point[1]});
+        }
+    }
+    volumes.push_back({ deviceCategory, curvePoints });
+    return NO_ERROR;
+}
+
+status_t VolumeGroupTraits::deserialize(_xmlDoc *doc, const _xmlNode *root, Collection &volumes)
+{
+    std::string name;
+    int indexMin = 0;
+    int indexMax = 0;
+    StreamVector streams = {};
+    AttributesVector attributesVect = {};
+
+    for (const xmlNode *child = root->xmlChildrenNode; child != NULL; child = child->next) {
+        if (not xmlStrcmp(child->name, (const xmlChar *)Attributes::name)) {
+            xmlCharUnique nameXml(xmlNodeListGetString(doc, child->xmlChildrenNode, 1), xmlFree);
+            if (nameXml == nullptr) {
+                return BAD_VALUE;
+            }
+            name = reinterpret_cast<const char*>(nameXml.get());
+        }
+        if (not xmlStrcmp(child->name, (const xmlChar *)Attributes::indexMin)) {
+            xmlCharUnique indexMinXml(xmlNodeListGetString(doc, child->xmlChildrenNode, 1), xmlFree);
+            if (indexMinXml == nullptr) {
+                return BAD_VALUE;
+            }
+            std::string indexMinLiteral(reinterpret_cast<const char*>(indexMinXml.get()));
+            if (!convertTo(indexMinLiteral, indexMin)) {
+                return BAD_VALUE;
+            }
+        }
+        if (not xmlStrcmp(child->name, (const xmlChar *)Attributes::indexMax)) {
+            xmlCharUnique indexMaxXml(xmlNodeListGetString(doc, child->xmlChildrenNode, 1), xmlFree);
+            if (indexMaxXml == nullptr) {
+                return BAD_VALUE;
+            }
+            std::string indexMaxLiteral(reinterpret_cast<const char*>(indexMaxXml.get()));
+            if (!convertTo(indexMaxLiteral, indexMax)) {
+                return BAD_VALUE;
+            }
+        }
+    }
+    deserializeAttributesCollection(doc, root, attributesVect);
+
+    std::string streamNames;
+    for (const auto &stream : streams) {
+        streamNames += android::toString(stream) + " ";
+    }
+    std::string attrmNames;
+    for (const auto &attr : attributesVect) {
+        attrmNames += android::toString(attr) + "\n";
+    }
+    ALOGV("%s: group=%s indexMin=%d, indexMax=%d streams=%s attributes=%s",
+          __func__, name.c_str(), indexMin, indexMax, streamNames.c_str(), attrmNames.c_str( ));
+
+    VolumeCurves groupVolumeCurves;
+    size_t skipped = 0;
+    deserializeCollection<VolumeTraits>(doc, root, groupVolumeCurves, skipped);
+    volumes.push_back({ name, indexMin, indexMax, groupVolumeCurves });
+    return NO_ERROR;
+}
+
+static constexpr const char *legacyVolumecollectionTag = "volumes";
+static constexpr const char *legacyVolumeTag = "volume";
+
+status_t deserializeLegacyVolume(_xmlDoc *doc, const _xmlNode *cur,
+                                 std::map<std::string, VolumeCurves> &legacyVolumes)
+{
+    std::string streamTypeLiteral = getXmlAttribute(cur, "stream");
+    if (streamTypeLiteral.empty()) {
+        ALOGE("%s: No attribute stream found", __func__);
+        return BAD_VALUE;
+    }
+    std::string deviceCategoryLiteral = getXmlAttribute(cur, "deviceCategory");
+    if (deviceCategoryLiteral.empty()) {
+        ALOGE("%s: No attribute deviceCategory found", __func__);
+        return BAD_VALUE;
+    }
+    std::string referenceName = getXmlAttribute(cur, "ref");
+    const xmlNode *ref = NULL;
+    if (!referenceName.empty()) {
+        getReference(xmlDocGetRootElement(doc), ref, referenceName, legacyVolumecollectionTag);
+        if (ref == NULL) {
+            ALOGE("%s: No reference Ptr found for %s", __func__, referenceName.c_str());
+            return BAD_VALUE;
+        }
+        ALOGV("%s: reference found for %s", __func__, referenceName.c_str());
+    }
+    CurvePoints curvePoints;
+    for (const xmlNode *child = referenceName.empty() ?
+         cur->xmlChildrenNode : ref->xmlChildrenNode; child != NULL; child = child->next) {
+        if (!xmlStrcmp(child->name, (const xmlChar *)VolumeTraits::volumePointTag)) {
+            xmlCharUnique pointXml(xmlNodeListGetString(doc, child->xmlChildrenNode, 1), xmlFree);
+            if (pointXml == NULL) {
+                return BAD_VALUE;
+            }
+            ALOGV("%s: %s=%s", __func__, legacyVolumeTag,
+                  reinterpret_cast<const char*>(pointXml.get()));
+            std::vector<int> point;
+            collectionFromString<DefaultTraits<int>>(
+                        reinterpret_cast<const char*>(pointXml.get()), point, ",");
+            if (point.size() != 2) {
+                ALOGE("%s: Invalid %s: %s", __func__, VolumeTraits::volumePointTag,
+                      reinterpret_cast<const char*>(pointXml.get()));
+                return BAD_VALUE;
+            }
+            curvePoints.push_back({point[0], point[1]});
+        }
+    }
+    legacyVolumes[streamTypeLiteral].push_back({ deviceCategoryLiteral, curvePoints });
+    return NO_ERROR;
+}
+
+static status_t deserializeLegacyVolumeCollection(_xmlDoc *doc, const _xmlNode *cur,
+                                                  VolumeGroups &volumeGroups,
+                                                  size_t &nbSkippedElement)
+{
+    std::map<std::string, VolumeCurves> legacyVolumeMap;
+    for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) {
+        if (xmlStrcmp(cur->name, (const xmlChar *)legacyVolumecollectionTag)) {
+            continue;
+        }
+        const xmlNode *child = cur->xmlChildrenNode;
+        for (; child != NULL; child = child->next) {
+            if (!xmlStrcmp(child->name, (const xmlChar *)legacyVolumeTag)) {
+
+                status_t status = deserializeLegacyVolume(doc, child, legacyVolumeMap);
+                if (status != NO_ERROR) {
+                    nbSkippedElement += 1;
+                }
+            }
+        }
+    }
+    for (const auto &volumeMapIter : legacyVolumeMap) {
+        // In order to let AudioService setting the min and max (compatibility), set Min and Max
+        // to -1 except for private streams
+        audio_stream_type_t streamType;
+        if (!StreamTypeConverter::fromString(volumeMapIter.first, streamType)) {
+            ALOGE("%s: Invalid stream %s", __func__, volumeMapIter.first.c_str());
+            return BAD_VALUE;
+        }
+        int indexMin = streamType >= AUDIO_STREAM_PUBLIC_CNT ? 0 : -1;
+        int indexMax = streamType >= AUDIO_STREAM_PUBLIC_CNT ? 100 : -1;
+        volumeGroups.push_back({ volumeMapIter.first, indexMin, indexMax, volumeMapIter.second });
+    }
+    return NO_ERROR;
+}
+
+ParsingResult parse(const char* path) {
+    xmlDocPtr doc;
+    doc = xmlParseFile(path);
+    if (doc == NULL) {
+        ALOGE("%s: Could not parse document %s", __FUNCTION__, path);
+        return {nullptr, 0};
+    }
+    xmlNodePtr cur = xmlDocGetRootElement(doc);
+    if (cur == NULL) {
+        ALOGE("%s: Could not parse: empty document %s", __FUNCTION__, path);
+        xmlFreeDoc(doc);
+        return {nullptr, 0};
+    }
+    if (xmlXIncludeProcess(doc) < 0) {
+        ALOGE("%s: libxml failed to resolve XIncludes on document %s", __FUNCTION__, path);
+        return {nullptr, 0};
+    }
+    std::string version = getXmlAttribute(cur, gVersionAttribute);
+    if (version.empty()) {
+        ALOGE("%s: No version found", __func__);
+        return {nullptr, 0};
+    }
+    size_t nbSkippedElements = 0;
+    auto config = std::make_unique<Config>();
+    config->version = std::stof(version);
+    deserializeCollection<ProductStrategyTraits>(
+                doc, cur, config->productStrategies, nbSkippedElements);
+    deserializeCollection<CriterionTraits>(
+                doc, cur, config->criteria, nbSkippedElements);
+    deserializeCollection<CriterionTypeTraits>(
+                doc, cur, config->criterionTypes, nbSkippedElements);
+    deserializeCollection<VolumeGroupTraits>(
+                doc, cur, config->volumeGroups, nbSkippedElements);
+
+    return {std::move(config), nbSkippedElements};
+}
+
+android::status_t parseLegacyVolumeFile(const char* path, VolumeGroups &volumeGroups) {
+    xmlDocPtr doc;
+    doc = xmlParseFile(path);
+    if (doc == NULL) {
+        ALOGE("%s: Could not parse document %s", __FUNCTION__, path);
+        return BAD_VALUE;
+    }
+    xmlNodePtr cur = xmlDocGetRootElement(doc);
+    if (cur == NULL) {
+        ALOGE("%s: Could not parse: empty document %s", __FUNCTION__, path);
+        xmlFreeDoc(doc);
+        return BAD_VALUE;
+    }
+    if (xmlXIncludeProcess(doc) < 0) {
+        ALOGE("%s: libxml failed to resolve XIncludes on document %s", __FUNCTION__, path);
+        return BAD_VALUE;
+    }
+    size_t nbSkippedElements = 0;
+    return deserializeLegacyVolumeCollection(doc, cur, volumeGroups, nbSkippedElements);
+}
+
+static const char *kConfigLocationList[] = {"/odm/etc", "/vendor/etc", "/system/etc"};
+static const int kConfigLocationListSize =
+        (sizeof(kConfigLocationList) / sizeof(kConfigLocationList[0]));
+static const int gApmXmlConfigFilePathMaxLength = 128;
+
+static constexpr const char *apmXmlConfigFileName = "audio_policy_configuration.xml";
+static constexpr const char *apmA2dpOffloadDisabledXmlConfigFileName =
+        "audio_policy_configuration_a2dp_offload_disabled.xml";
+
+android::status_t parseLegacyVolumes(VolumeGroups &volumeGroups) {
+    char audioPolicyXmlConfigFile[gApmXmlConfigFilePathMaxLength];
+    std::vector<const char *> fileNames;
+    status_t ret;
+
+    if (property_get_bool("ro.bluetooth.a2dp_offload.supported", false) &&
+            property_get_bool("persist.bluetooth.a2dp_offload.disabled", false)) {
+        // A2DP offload supported but disabled: try to use special XML file
+        fileNames.push_back(apmA2dpOffloadDisabledXmlConfigFileName);
+    }
+    fileNames.push_back(apmXmlConfigFileName);
+
+    for (const char* fileName : fileNames) {
+        for (int i = 0; i < kConfigLocationListSize; i++) {
+            snprintf(audioPolicyXmlConfigFile, sizeof(audioPolicyXmlConfigFile),
+                     "%s/%s", kConfigLocationList[i], fileName);
+            ret = parseLegacyVolumeFile(audioPolicyXmlConfigFile, volumeGroups);
+            if (ret == NO_ERROR) {
+                return ret;
+            }
+        }
+    }
+    return BAD_VALUE;
+}
+
+} // namespace engineConfig
+} // namespace android
diff --git a/services/audiopolicy/engine/interface/Android.bp b/services/audiopolicy/engine/interface/Android.bp
new file mode 100644
index 0000000..2ea42b6
--- /dev/null
+++ b/services/audiopolicy/engine/interface/Android.bp
@@ -0,0 +1,19 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library_headers {
+    name: "libaudiopolicyengine_interface_headers",
+    host_supported: true,
+    export_include_dirs: ["."],
+}
diff --git a/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h b/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
index 04594f5..b7fd031 100644
--- a/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
+++ b/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
@@ -17,7 +17,10 @@
 #pragma once
 
 #include <AudioPolicyManagerObserver.h>
-#include <RoutingStrategy.h>
+#include <media/AudioProductStrategy.h>
+#include <media/AudioVolumeGroup.h>
+#include <IVolumeCurves.h>
+#include <policy.h>
 #include <Volume.h>
 #include <HwModule.h>
 #include <DeviceDescriptor.h>
@@ -28,6 +31,10 @@
 
 namespace android {
 
+using DeviceStrategyMap = std::map<product_strategy_t, DeviceVector>;
+using StrategyVector = std::vector<product_strategy_t>;
+using VolumeGroupVector = std::vector<volume_group_t>;
+
 /**
  * This interface is dedicated to the policy manager that a Policy Engine shall implement.
  */
@@ -50,42 +57,6 @@
     virtual void setObserver(AudioPolicyManagerObserver *observer) = 0;
 
     /**
-     * Get the input device selected for a given input source.
-     *
-     * @param[in] inputSource to get the selected input device associated to
-     *
-     * @return selected input device for the given input source, may be none if error.
-     */
-    virtual audio_devices_t getDeviceForInputSource(audio_source_t inputSource) const = 0;
-
-    /**
-     * Get the output device associated to a given strategy.
-     *
-     * @param[in] stream type for which the selected ouput device is requested.
-     *
-     * @return selected ouput device for the given strategy, may be none if error.
-     */
-    virtual audio_devices_t getDeviceForStrategy(routing_strategy stategy) const = 0;
-
-    /**
-     * Get the strategy selected for a given stream type.
-     *
-     * @param[in] stream: for which the selected strategy followed by is requested.
-     *
-     * @return strategy to be followed.
-     */
-    virtual routing_strategy getStrategyForStream(audio_stream_type_t stream) = 0;
-
-    /**
-     * Get the strategy selected for a given usage.
-     *
-     * @param[in] usage to get the selected strategy followed by.
-     *
-     * @return strategy to be followed.
-     */
-    virtual routing_strategy getStrategyForUsage(audio_usage_t usage) = 0;
-
-    /**
      * Set the Telephony Mode.
      *
      * @param[in] mode: Android Phone state (normal, ringtone, csv, in communication)
@@ -133,6 +104,196 @@
     virtual status_t setDeviceConnectionState(const android::sp<android::DeviceDescriptor> devDesc,
                                               audio_policy_dev_state_t state) = 0;
 
+    /**
+     * Get the strategy selected for a given audio attributes.
+     *
+     * @param[in] audio attributes to get the selected @product_strategy_t followed by.
+     *
+     * @return @product_strategy_t to be followed.
+     */
+    virtual product_strategy_t getProductStrategyForAttributes(
+            const audio_attributes_t &attr) const = 0;
+
+    /**
+     * @brief getOutputDevicesForAttributes retrieves the devices to be used for given
+     * audio attributes.
+     * @param attributes of the output requesting Device(s) selection
+     * @param preferedDevice valid reference if a prefered device is requested, nullptr otherwise.
+     * @param fromCache if true, the device is returned from internal cache,
+     *                  otherwise it is determined by current state (device connected,phone state,
+     *                  force use, a2dp output...)
+     * @return vector of selected device descriptors.
+     *         Appropriate device for streams handled by the specified audio attributes according
+     *         to current phone state, forced states, connected devices...
+     *         if fromCache is true, the device is returned from internal cache,
+     *         otherwise it is determined by current state (device connected,phone state, force use,
+     *         a2dp output...)
+     * This allows to:
+     *      1 speed up process when the state is stable (when starting or stopping an output)
+     *      2 access to either current device selection (fromCache == true) or
+     *      "future" device selection (fromCache == false) when called from a context
+     *      where conditions are changing (setDeviceConnectionState(), setPhoneState()...) AND
+     *      before manager updates its outputs.
+     */
+    virtual DeviceVector getOutputDevicesForAttributes(
+            const audio_attributes_t &attributes,
+            const sp<DeviceDescriptor> &preferedDevice = nullptr,
+            bool fromCache = false) const = 0;
+
+    /**
+     * @brief getOutputDevicesForStream Legacy function retrieving devices from a stream type.
+     * @param stream type of the output requesting Device(s) selection
+     * @param fromCache if true, the device is returned from internal cache,
+     *                  otherwise it is determined by current state (device connected,phone state,
+     *                  force use, a2dp output...)
+     * @return appropriate device for streams handled by the specified audio attributes according
+     *         to current phone state, forced states, connected devices...
+     *         if fromCache is true, the device is returned from internal cache,
+     *         otherwise it is determined by current state (device connected,phone state, force use,
+     *         a2dp output...)
+     * This allows to:
+     *      1 speed up process when the state is stable (when starting or stopping an output)
+     *      2 access to either current device selection (fromCache == true) or
+     *      "future" device selection (fromCache == false) when called from a context
+     *      where conditions are changing (setDeviceConnectionState(), setPhoneState()...) AND
+     *      before manager updates its outputs.
+     */
+    virtual DeviceVector getOutputDevicesForStream(audio_stream_type_t stream,
+                                                   bool fromCache = false) const = 0;
+
+    /**
+     * Get the input device selected for given audio attributes.
+     *
+     * @param[in] attr audio attributes to consider
+     * @param[out] mix to be used if a mix has been installed for the given audio attributes.
+     * @return selected input device for the audio attributes, may be null if error.
+     */
+    virtual sp<DeviceDescriptor> getInputDeviceForAttributes(
+            const audio_attributes_t &attr, sp<AudioPolicyMix> *mix = nullptr) const = 0;
+
+    /**
+     * Get the legacy stream type for a given audio attributes.
+     *
+     * @param[in] audio attributes to get the associated audio_stream_type_t.
+     *
+     * @return audio_stream_type_t associated to the attributes.
+     */
+    virtual audio_stream_type_t getStreamTypeForAttributes(
+            const audio_attributes_t &attr) const = 0;
+
+    /**
+     * @brief getAttributesForStream get the audio attributes from legacy stream type
+     * Attributes returned might only be used to check upon routing decision, not volume decisions.
+     * @param stream to consider
+     * @return audio attributes matching the legacy stream type
+     */
+    virtual audio_attributes_t getAttributesForStreamType(audio_stream_type_t stream) const = 0;
+
+    /**
+     * @brief getStreamTypesForProductStrategy retrieves the list of legacy stream type following
+     * the given product strategy
+     * @param ps product strategy to consider
+     * @return associated legacy Stream Types vector of the given product strategy
+     */
+    virtual StreamTypeVector getStreamTypesForProductStrategy(product_strategy_t ps) const = 0;
+
+    /**
+     * @brief getAllAttributesForProductStrategy retrieves all the attributes following the given
+     * product strategy. Any attributes that "matches" with this one will follow the product
+     * strategy.
+     * "matching" means the usage shall match if reference attributes has a defined usage, AND
+     * content type shall match if reference attributes has a defined content type AND
+     * flags shall match if reference attributes has defined flags AND
+     * tags shall match if reference attributes has defined tags.
+     * @param ps product strategy to consider
+     * @return vector of product strategy ids, empty if unknown strategy.
+     */
+    virtual AttributesVector getAllAttributesForProductStrategy(product_strategy_t ps) const = 0;
+
+    /**
+     * @brief getOrderedAudioProductStrategies
+     * @return priority ordered product strategies to help the AudioPolicyManager evaluating the
+     * device selection per output according to the prioritized strategies.
+     */
+    virtual StrategyVector getOrderedProductStrategies() const = 0;
+
+    /**
+     * @brief updateDeviceSelectionCache. Device selection for AudioAttribute / Streams is cached
+     * in the engine in order to speed up process when the audio system is stable.
+     * When a device is connected, the android mode is changed, engine is notified and can update
+     * the cache.
+     * When starting / stopping an output with a stream that can affect notification, the engine
+     * needs to update the cache upon this function call.
+     */
+    virtual void updateDeviceSelectionCache() = 0;
+
+    /**
+     * @brief listAudioProductStrategies. Introspection API to retrieve a collection of
+     * AudioProductStrategyVector that allows to build AudioAttributes according to a
+     * product_strategy which is just an index. It has also a human readable name to help the
+     * Car/Oem/AudioManager identiying the use case.
+     * @param strategies collection.
+     * @return OK if the list has been retrieved, error code otherwise
+     */
+    virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies) const = 0;
+
+    /**
+     * @brief getVolumeCurvesForAttributes retrieves the Volume Curves interface for the
+     *        requested Audio Attributes.
+     * @param attr to be considered
+     * @return IVolumeCurves interface pointer if found, nullptr otherwise
+     */
+    virtual IVolumeCurves *getVolumeCurvesForAttributes(const audio_attributes_t &attr) const = 0;
+
+    /**
+     * @brief getVolumeCurvesForStreamType retrieves the Volume Curves interface for the stream
+     * @param stream to be considered
+     * @return IVolumeCurves interface pointer if found, nullptr otherwise
+     */
+    virtual IVolumeCurves *getVolumeCurvesForStreamType(audio_stream_type_t stream) const = 0;
+
+    /**
+     * @brief getVolumeCurvesForVolumeGroup retrieves the Volume Curves interface for volume group
+     * @param group to be considered
+     * @return IVolumeCurves interface pointer if found, nullptr otherwise
+     */
+    virtual IVolumeCurves *getVolumeCurvesForVolumeGroup(volume_group_t group) const = 0;
+
+    /**
+     * @brief getVolumeGroups retrieves the collection of volume groups.
+     * @return vector of volume groups
+     */
+    virtual VolumeGroupVector getVolumeGroups() const = 0;
+
+    /**
+     * @brief getVolumeGroupForAttributes gets the appropriate volume group to be used for a given
+     * Audio Attributes.
+     * @param attr to be considered
+     * @return volume group associated to the given audio attributes, default group if none
+     * applicable, VOLUME_GROUP_NONE if no default group defined.
+     */
+    virtual volume_group_t getVolumeGroupForAttributes(const audio_attributes_t &attr) const = 0;
+
+    /**
+     * @brief getVolumeGroupForStreamType gets the appropriate volume group to be used for a given
+     * legacy stream type
+     * @param stream type to be considered
+     * @return volume group associated to the given stream type, default group if none applicable,
+     * VOLUME_GROUP_NONE if no default group defined.
+     */
+    virtual volume_group_t getVolumeGroupForStreamType(audio_stream_type_t stream) const = 0;
+
+    /**
+     * @brief listAudioVolumeGroups introspection API to get the Audio Volume Groups, aka
+     * former stream aliases in Audio Service, defining volume curves attached to one or more
+     * Audio Attributes.
+     * @param groups
+     * @return NO_ERROR if the volume groups were retrieved successfully, error code otherwise
+     */
+    virtual status_t listAudioVolumeGroups(AudioVolumeGroupVector &groups) const = 0;
+
+    virtual void dump(String8 *dst) const = 0;
+
 protected:
     virtual ~AudioPolicyManagerInterface() {}
 };
diff --git a/services/audiopolicy/engine/interface/AudioPolicyManagerObserver.h b/services/audiopolicy/engine/interface/AudioPolicyManagerObserver.h
index b7902cf..ebd82a7 100644
--- a/services/audiopolicy/engine/interface/AudioPolicyManagerObserver.h
+++ b/services/audiopolicy/engine/interface/AudioPolicyManagerObserver.h
@@ -16,7 +16,6 @@
 
 #pragma once
 
-#include <IVolumeCurvesCollection.h>
 #include <AudioGain.h>
 #include <AudioPort.h>
 #include <AudioPatch.h>
@@ -47,11 +46,9 @@
 
     virtual const AudioInputCollection &getInputs() const = 0;
 
-    virtual const DeviceVector &getAvailableOutputDevices() const = 0;
+    virtual const DeviceVector getAvailableOutputDevices() const = 0;
 
-    virtual const DeviceVector &getAvailableInputDevices() const = 0;
-
-    virtual IVolumeCurvesCollection &getVolumeCurves() = 0;
+    virtual const DeviceVector getAvailableInputDevices() const = 0;
 
     virtual const sp<DeviceDescriptor> &getDefaultOutputDevice() const = 0;
 
diff --git a/services/audiopolicy/engineconfigurable/Android.bp b/services/audiopolicy/engineconfigurable/Android.bp
new file mode 100644
index 0000000..c27dc88
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/Android.bp
@@ -0,0 +1,44 @@
+cc_library_headers {
+    name: "libaudiopolicyengineconfigurable_interface_headers",
+    host_supported: true,
+    export_include_dirs: ["interface"],
+}
+
+cc_library_shared {
+    name: "libaudiopolicyengineconfigurable",
+    export_include_dirs: ["include"],
+    srcs: [
+        "src/Engine.cpp",
+        "src/EngineInstance.cpp",
+        "src/Stream.cpp",
+        "src/InputSource.cpp",
+    ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+    ],
+    local_include_dirs: ["include"],
+    header_libs: [
+        "libbase_headers",
+        "libaudiopolicycommon",
+        "libaudiopolicyengine_interface_headers",
+        "libaudiopolicyengineconfigurable_interface_headers",
+    ],
+    static_libs: [
+        "libaudiopolicycomponents",
+        "libaudiopolicyengine_common",
+        "libaudiopolicyengine_config",
+        "libaudiopolicyengineconfigurable_pfwwrapper",
+
+    ],
+    shared_libs: [
+        "liblog",
+        "libcutils",
+        "libutils",
+        "libmedia_helper",
+        "libaudiopolicy",
+        "libparameter",
+        "libxml2",
+    ],
+}
diff --git a/services/audiopolicy/engineconfigurable/Android.mk b/services/audiopolicy/engineconfigurable/Android.mk
deleted file mode 100644
index c2105e9..0000000
--- a/services/audiopolicy/engineconfigurable/Android.mk
+++ /dev/null
@@ -1,64 +0,0 @@
-ifeq ($(USE_CONFIGURABLE_AUDIO_POLICY), 1)
-
-LOCAL_PATH := $(call my-dir)
-
-# Component build
-#######################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-    src/Engine.cpp \
-    src/EngineInstance.cpp \
-    src/Stream.cpp \
-    src/Strategy.cpp \
-    src/Usage.cpp \
-    src/InputSource.cpp \
-
-audio_policy_engine_includes_common := \
-    frameworks/av/services/audiopolicy/engineconfigurable/include \
-    frameworks/av/services/audiopolicy/engineconfigurable/interface \
-    frameworks/av/services/audiopolicy/engine/interface
-
-LOCAL_CFLAGS += \
-    -Wall \
-    -Werror \
-    -Wextra \
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := \
-    $(audio_policy_engine_includes_common)
-
-LOCAL_C_INCLUDES := \
-    $(audio_policy_engine_includes_common) \
-    $(TARGET_OUT_HEADERS)/hw \
-    $(call include-path-for, frameworks-av) \
-    $(call include-path-for, audio-utils) \
-    frameworks/av/services/audiopolicy/common/include
-
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
-LOCAL_MODULE := libaudiopolicyengineconfigurable
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_STATIC_LIBRARIES := \
-    libaudiopolicypfwwrapper \
-    libaudiopolicycomponents
-
-LOCAL_SHARED_LIBRARIES := \
-    liblog \
-    libcutils \
-    libutils \
-    liblog \
-    libaudioutils \
-    libparameter \
-    libmedia_helper \
-    libxml2
-
-include $(BUILD_SHARED_LIBRARY)
-
-#######################################################################
-# Recursive call sub-folder Android.mk
-#
-include $(call all-makefiles-under,$(LOCAL_PATH))
-
-endif
diff --git a/services/audiopolicy/engineconfigurable/config/example/Android.mk b/services/audiopolicy/engineconfigurable/config/example/Android.mk
new file mode 100644
index 0000000..a0f1a90
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/Android.mk
@@ -0,0 +1,151 @@
+LOCAL_PATH := $(call my-dir)
+
+ifdef BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION
+
+TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
+PROVISION_CRITERION_TYPES := $(TOOLS)/provision_criterion_types_from_android_headers.mk
+
+##################################################################
+# CONFIGURATION TOP FILE
+##################################################################
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_configurable)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_configuration.xml
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := phone/$(LOCAL_MODULE)
+
+LOCAL_REQUIRED_MODULES := \
+    audio_policy_engine_product_strategies.xml  \
+    audio_policy_engine_stream_volumes.xml \
+    audio_policy_engine_default_stream_volumes.xml \
+    audio_policy_engine_criteria.xml \
+    audio_policy_engine_criterion_types.xml
+
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_product_strategies.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := phone/$(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_stream_volumes.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := phone/$(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_default_stream_volumes.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := phone/$(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_configurable)
+
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),automotive_configurable caremu_configurable))
+
+##################################################################
+# AUTOMOTIVE CONFIGURATION TOP FILE
+##################################################################
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_configuration.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := automotive/$(LOCAL_MODULE)
+
+LOCAL_REQUIRED_MODULES := \
+    audio_policy_engine_product_strategies.xml \
+    audio_policy_engine_criteria.xml \
+    audio_policy_engine_criterion_types.xml \
+    audio_policy_engine_volumes.xml
+
+include $(BUILD_PREBUILT)
+
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),automotive_configurable caremu_configurable))
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), automotive_configurable)
+
+##################################################################
+# CONFIGURATION FILES
+##################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_product_strategies.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := automotive/$(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_volumes.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := automotive/$(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), automotive_configurable)
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), caremu_configurable)
+
+##################################################################
+# CONFIGURATION FILES
+##################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_product_strategies.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := caremu/$(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_volumes.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := caremu/$(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), caremu_configurable)
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable caremu_configurable))
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_criteria.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := common/$(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_criterion_types.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_VENDOR_ETC)/primary_audio_policy_configuration.xml
+ANDROID_AUDIO_BASE_HEADER_FILE := system/media/audio/include/system/audio-base.h
+AUDIO_POLICY_CONFIGURATION_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_configuration.xml
+CRITERION_TYPES_FILE := $(LOCAL_PATH)/common/$(LOCAL_MODULE).in
+
+include $(PROVISION_CRITERION_TYPES)
+
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable caremu_configurable))
+
+endif #ifdef BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION
diff --git a/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_configuration.xml b/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_configuration.xml
new file mode 100644
index 0000000..28a140a
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_configuration.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+     -->
+
+<configuration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+
+    <xi:include href="audio_policy_engine_product_strategies.xml"/>
+    <xi:include href="audio_policy_engine_criterion_types.xml"/>
+    <xi:include href="audio_policy_engine_criteria.xml"/>
+    <xi:include href="audio_policy_engine_volumes.xml"/>
+
+</configuration>
+
diff --git a/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_product_strategies.xml b/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_product_strategies.xml
new file mode 100644
index 0000000..0ee83a2
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_product_strategies.xml
@@ -0,0 +1,185 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<ProductStrategies>
+    <!-- OEM Usages -->
+    <!-- product_strategy will be defined according this order
+    product_strategy is oem_traffic_anouncement if all the conditions are satisfied for
+    AudioAttributes aa
+
+    int type = 0;
+    if (bundle != null) {
+    type = bundle.getInt(KEY_OEM_TYPE, 0);
+    }
+    if(
+    ( aa.mContentType == AudioAttributes.AUDIO_CONTENT_TYPE_SPEECH ) &&
+    ( aa.mUsage == AudioAttributes.AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE ) &&
+    ( type == 1 ) )
+    -->
+
+    <ProductStrategy name="oem_traffic_anouncement">
+        <AttributesGroup volumeGroup="oem_traffic_anouncement">
+            <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
+            <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+            <!--  traffic_annoucement = 1 -->
+            <Bundle key="oem" value="1"/>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="oem_strategy_1">
+        <AttributesGroup volumeGroup="oem_adas_2">
+            <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
+            <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+            <Bundle key="oem" value="2"/>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="oem_strategy_2">
+        <AttributesGroup volumeGroup="oem_adas_3">
+            <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
+            <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+            <Bundle key="oem" value="3"/>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <!-- Car Usages -->
+    <!-- Keep those lines only for car -->
+    <!-- Check car conditions if any OEM conditions matched -->
+    <!-- As defined by CarAudioAttributesUtil.java -->
+    <!-- product_strategy will be defined according this order
+    product_strategy is radio if all the conditions are satisfied for AudioAttributes aa
+
+        int type = CAR_AUDIO_TYPE_DEFAULT;
+        if (bundle != null) {
+        type = bundle.getInt(KEY_CAR_AUDIO_TYPE, CAR_AUDIO_TYPE_DEFAULT);
+        }
+        if(
+        ( aa.mContentType == AudioAttributes.AUDIO_CONTENT_TYPE_SPEECH ) &&
+        ( aa.mUsage == AudioAttributes.AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE ) &&
+        ( type == CAR_AUDIO_TYPE_RADIO ) )
+        -->
+    <ProductStrategy name="radio">
+        <AttributesGroup volumeGroup="media_car_audio_type_3">
+            <ContentType value="AUDIO_CONTENT_TYPE_MUSIC"/>
+            <Usage value="AUDIO_USAGE_MEDIA"/>
+            <Bundle key="car_audio_type" value="3"/>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="ext_audio_source">
+        <AttributesGroup volumeGroup="media_car_audio_type_7">
+            <ContentType value="AUDIO_CONTENT_TYPE_MUSIC"/>
+            <Usage value="AUDIO_USAGE_MEDIA"/>
+            <Bundle key="car_audio_type" value="7"/>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="voice_command">
+        <AttributesGroup volumeGroup="speech">
+            <Attributes>
+                <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
+                <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+                <!--  CAR_AUDIO_TYPE_VOICE_COMMAND = 1 -->
+                <Bundle key="car_audio_type" value="1"/>
+            </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_ASSISTANT"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="safety_alert">
+        <AttributesGroup volumeGroup="system">
+            <ContentType value="AUDIO_CONTENT_TYPE_SONIFICATION"/>
+            <Usage value="AUDIO_USAGE_NOTIFICATION"/>
+            <!--  CAR_AUDIO_TYPE_SAFETY_ALERT = 2 -->
+            <Bundle key="car_audio_type" value="2"/>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <!-- To be checked
+    CAR_AUDIO_TYPE_CARSERVICE_BOTTOM
+    CAR_AUDIO_TYPE_CARSERVICE_CAR_PROXY
+    CAR_AUDIO_TYPE_CARSERVICE_MEDIA_MUTE
+    -->
+
+    <!-- Generic Usages -->
+    <ProductStrategy name="music">
+        <AttributesGroup streamType="AUDIO_STREAM_MUSIC" volumeGroup="media">
+            <Attributes> <Usage value="AUDIO_USAGE_MEDIA"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_GAME"/> </Attributes>
+            <!-- Default product strategy has empty attributes -->
+            <Attributes></Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="nav_guidance">
+        <AttributesGroup volumeGroup="speech">
+            <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="voice_call">
+        <AttributesGroup streamType="AUDIO_STREAM_VOICE_CALL" volumeGroup="phone">
+            <Attributes> <Usage value="AUDIO_USAGE_VOICE_COMMUNICATION"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING"/> </Attributes>
+        </AttributesGroup>
+        <AttributesGroup streamType="AUDIO_STREAM_BLUETOOTH_SCO" volumeGroup="phone">
+            <Attributes> <Flags value="AUDIO_FLAG_SCO"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="alarm">
+        <AttributesGroup streamType="AUDIO_STREAM_ALARM" volumeGroup="ring">
+            <Usage value="AUDIO_USAGE_ALARM"/>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="ring">
+        <AttributesGroup streamType="AUDIO_STREAM_RING" volumeGroup="ring">
+            <Usage value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE"/>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="notification">
+        <AttributesGroup streamType="AUDIO_STREAM_NOTIFICATION" volumeGroup="ring">
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_EVENT"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="system">
+        <AttributesGroup streamType="AUDIO_STREAM_SYSTEM" volumeGroup="system">
+            <Usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION"/>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="tts">
+        <!-- TTS stream MUST BE MANAGED OUTSIDE default product strategy if NO DEDICATED OUTPUT
+             for TTS, otherwise when beacon happens, default strategy is ... muted.
+             If it is media, it is annoying... -->
+        <AttributesGroup streamType="AUDIO_STREAM_TTS" volumeGroup="tts">
+            <Attributes> <Flags value="AUDIO_FLAG_BEACON"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <!-- Routing Strategy rerouting may be removed as following media??? -->
+    <ProductStrategy name="rerouting">
+        <AttributesGroup streamType="AUDIO_STREAM_REROUTING" volumeGroup="rerouting">
+            <Attributes></Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <!-- Patch stream needs full scale volume, define it otherwise switch to default... -->
+    <ProductStrategy name="patch">
+        <AttributesGroup streamType="AUDIO_STREAM_PATCH" volumeGroup="patch">
+            <Attributes></Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+</ProductStrategies>
+
diff --git a/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_volumes.xml b/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_volumes.xml
new file mode 100644
index 0000000..6e72dc5
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_volumes.xml
@@ -0,0 +1,213 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+     -->
+
+<!-- Volume Groups Tables included by Audio Policy Configuration file -->
+<!-- Note:
+        It is VALID to have a group without attributes if a product strategy is following
+        this group for all attributes.
+        Otherwise, attributes must be specified
+-->
+
+<volumeGroups>
+    <volumeGroup>
+        <name>oem_traffic_anouncement</name>
+        <indexMin>0</indexMin>
+        <indexMax>40</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+
+<!-- OEM ADAS is a volume group that has a single port gain (this is the reason why it is a group
+     but may host different streams.
+     A priority must be given among them (either they are multualy excluisve, so the volume
+     will be the one of the currently acitve stream, otherwise a priority must be given by
+     any mean. -->
+    <volumeGroup>
+        <name>oem_adas_2</name>
+        <indexMin>0</indexMin>
+        <indexMax>40</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+    <volumeGroup>
+        <name>oem_adas_3</name>
+        <indexMin>0</indexMin>
+        <indexMax>40</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-2400</point>
+            <point>33,-1600</point>
+            <point>66,-800</point>
+            <point>100,0</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE">
+            <point>0,-2400</point>
+            <point>33,-1600</point>
+            <point>66,-800</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+
+<!-- MEDIA is a volume group that has a single port gain (this is the reason why it is a group
+     but may host different streams.
+     A priority must be given among them (either they are multualy exclusive, so the volume
+     will be the one of the active stream with highest priority (ORDER MATTERS) unless the curves
+     followed will the the curves for the requested attributes.-->
+    <volumeGroup>
+        <name>media_car_audio_type_3</name>
+        <indexMin>0</indexMin>
+        <indexMax>40</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+    <volumeGroup>
+        <name>media_car_audio_type_7</name>
+        <indexMin>0</indexMin>
+        <indexMax>40</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-2400</point>
+            <point>33,-1600</point>
+            <point>66,-800</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+    <volumeGroup>
+        <name>media</name>
+        <indexMin>0</indexMin>
+        <indexMax>40</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-2400</point>
+            <point>33,-1600</point>
+            <point>66,-800</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>speech</name>
+        <indexMin>1</indexMin>
+        <indexMax>40</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>system</name>
+        <indexMin>0</indexMin>
+        <indexMax>40</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>phone</name>
+        <indexMin>1</indexMin>
+        <indexMax>40</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>ring</name>
+        <indexMin>0</indexMin>
+        <indexMax>40</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>tts</name>
+        <indexMin>0</indexMin>
+        <indexMax>15</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-0</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>rerouting</name>
+        <indexMin>0</indexMin>
+        <indexMax>1</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+            <point>0,0</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>patch</name>
+        <indexMin>0</indexMin>
+        <indexMax>1</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+            <point>0,0</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+
+</volumeGroups>
+
diff --git a/services/audiopolicy/engineconfigurable/config/example/caremu/audio_policy_engine_product_strategies.xml b/services/audiopolicy/engineconfigurable/config/example/caremu/audio_policy_engine_product_strategies.xml
new file mode 100644
index 0000000..adcbd83
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/caremu/audio_policy_engine_product_strategies.xml
@@ -0,0 +1,184 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<ProductStrategies>
+    <!-- OEM Usages -->
+    <!-- product_strategy will be defined according this order
+    product_strategy is oem_traffic_anouncement if all the conditions are satisfied for
+    AudioAttributes aa
+
+    int type = 0;
+    if (bundle != null) {
+    type = bundle.getInt(KEY_OEM_TYPE, 0);
+    }
+    if(
+    ( aa.mContentType == AudioAttributes.AUDIO_CONTENT_TYPE_SPEECH ) &&
+    ( aa.mUsage == AudioAttributes.AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE ) &&
+    ( type == 1 ) )
+    -->
+
+    <ProductStrategy name="oem_traffic_anouncement">
+        <AttributesGroup volumeGroup="oem_traffic_anouncement">
+            <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
+            <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+            <!--  traffic_annoucement = 1 -->
+            <Bundle key="oem" value="1"/>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="oem_strategy_1">
+        <AttributesGroup volumeGroup="oem_adas_2">
+            <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
+            <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+            <Bundle key="oem" value="2"/>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="oem_strategy_2">
+        <AttributesGroup volumeGroup="oem_adas_3">
+            <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
+            <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+            <Bundle key="oem" value="3"/>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <!-- Car Usages -->
+    <!-- Keep those lines only for car -->
+    <!-- Check car conditions if any OEM conditions matched -->
+    <!-- As defined by CarAudioAttributesUtil.java -->
+    <!-- product_strategy will be defined according this order
+    product_strategy is radio if all the conditions are satisfied for AudioAttributes aa
+
+        int type = CAR_AUDIO_TYPE_DEFAULT;
+        if (bundle != null) {
+        type = bundle.getInt(KEY_CAR_AUDIO_TYPE, CAR_AUDIO_TYPE_DEFAULT);
+        }
+        if(
+        ( aa.mContentType == AudioAttributes.AUDIO_CONTENT_TYPE_SPEECH ) &&
+        ( aa.mUsage == AudioAttributes.AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE ) &&
+        ( type == CAR_AUDIO_TYPE_RADIO ) )
+        -->
+    <ProductStrategy name="radio">
+        <AttributesGroup volumeGroup="media_car_audio_type_3">
+            <ContentType value="AUDIO_CONTENT_TYPE_MUSIC"/>
+            <Usage value="AUDIO_USAGE_MEDIA"/>
+            <Bundle key="car_audio_type" value="3"/>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="ext_audio_source">
+        <AttributesGroup volumeGroup="media_car_audio_type_7">
+            <ContentType value="AUDIO_CONTENT_TYPE_MUSIC"/>
+            <Usage value="AUDIO_USAGE_MEDIA"/>
+            <Bundle key="car_audio_type" value="7"/>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="voice_command">
+        <AttributesGroup volumeGroup="speech">
+            <Attributes>
+                <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
+                <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+                <!--  CAR_AUDIO_TYPE_VOICE_COMMAND = 1 -->
+                <Bundle key="car_audio_type" value="1"/>
+            </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_ASSISTANT"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="safety_alert">
+        <AttributesGroup volumeGroup="system">
+            <ContentType value="AUDIO_CONTENT_TYPE_SONIFICATION"/>
+            <Usage value="AUDIO_USAGE_NOTIFICATION"/>
+            <!--  CAR_AUDIO_TYPE_SAFETY_ALERT = 2 -->
+            <Bundle key="car_audio_type" value="2"/>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <!-- To be checked
+    CAR_AUDIO_TYPE_CARSERVICE_BOTTOM
+    CAR_AUDIO_TYPE_CARSERVICE_CAR_PROXY
+    CAR_AUDIO_TYPE_CARSERVICE_MEDIA_MUTE
+    -->
+
+    <!-- Generic Usages -->
+    <ProductStrategy name="music">
+        <AttributesGroup streamType="AUDIO_STREAM_MUSIC" volumeGroup="media">
+            <Attributes> <Usage value="AUDIO_USAGE_MEDIA"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_GAME"/> </Attributes>
+            <!-- Default product strategy has empty attributes -->
+            <Attributes></Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="nav_guidance">
+        <AttributesGroup volumeGroup="speech">
+            <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="voice_call">
+        <AttributesGroup streamType="AUDIO_STREAM_VOICE_CALL" volumeGroup="phone">
+            <Attributes> <Usage value="AUDIO_USAGE_VOICE_COMMUNICATION"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING"/> </Attributes>
+        </AttributesGroup>
+        <AttributesGroup streamType="AUDIO_STREAM_BLUETOOTH_SCO" volumeGroup="phone">
+            <Attributes> <Flags value="AUDIO_FLAG_SCO"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="alarm">
+        <AttributesGroup streamType="AUDIO_STREAM_ALARM" volumeGroup="ring">
+            <Usage value="AUDIO_USAGE_ALARM"/>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="ring">
+        <AttributesGroup streamType="AUDIO_STREAM_RING" volumeGroup="ring">
+            <Usage value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE"/>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="notification">
+        <AttributesGroup streamType="AUDIO_STREAM_NOTIFICATION" volumeGroup="ring">
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_EVENT"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="system">
+        <AttributesGroup streamType="AUDIO_STREAM_SYSTEM" volumeGroup="system">
+            <Usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION"/>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="tts">
+        <!-- TTS stream MUST BE MANAGED OUTSIDE default product strategy if NO DEDICATED OUTPUT
+             for TTS, otherwise when beacon happens, default strategy is ... muted.
+             If it is media, it is annoying... -->
+        <AttributesGroup streamType="AUDIO_STREAM_TTS" volumeGroup="tts">
+            <Attributes> <Flags value="AUDIO_FLAG_BEACON"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <!-- Routing Strategy rerouting may be removed as following media??? -->
+    <ProductStrategy name="rerouting">
+        <AttributesGroup streamType="AUDIO_STREAM_REROUTING" volumeGroup="rerouting">
+            <Attributes></Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <!-- Patch stream needs full scale volume, define it otherwise switch to default... -->
+    <ProductStrategy name="patch">
+        <AttributesGroup streamType="AUDIO_STREAM_PATCH" volumeGroup="patch">
+            <Attributes></Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+</ProductStrategies>
+
diff --git a/services/audiopolicy/engineconfigurable/config/example/caremu/audio_policy_engine_volumes.xml b/services/audiopolicy/engineconfigurable/config/example/caremu/audio_policy_engine_volumes.xml
new file mode 100644
index 0000000..6e72dc5
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/caremu/audio_policy_engine_volumes.xml
@@ -0,0 +1,213 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+     -->
+
+<!-- Volume Groups Tables included by Audio Policy Configuration file -->
+<!-- Note:
+        It is VALID to have a group without attributes if a product strategy is following
+        this group for all attributes.
+        Otherwise, attributes must be specified
+-->
+
+<volumeGroups>
+    <volumeGroup>
+        <name>oem_traffic_anouncement</name>
+        <indexMin>0</indexMin>
+        <indexMax>40</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+
+<!-- OEM ADAS is a volume group that has a single port gain (this is the reason why it is a group
+     but may host different streams.
+     A priority must be given among them (either they are multualy excluisve, so the volume
+     will be the one of the currently acitve stream, otherwise a priority must be given by
+     any mean. -->
+    <volumeGroup>
+        <name>oem_adas_2</name>
+        <indexMin>0</indexMin>
+        <indexMax>40</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+    <volumeGroup>
+        <name>oem_adas_3</name>
+        <indexMin>0</indexMin>
+        <indexMax>40</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-2400</point>
+            <point>33,-1600</point>
+            <point>66,-800</point>
+            <point>100,0</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE">
+            <point>0,-2400</point>
+            <point>33,-1600</point>
+            <point>66,-800</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+
+<!-- MEDIA is a volume group that has a single port gain (this is the reason why it is a group
+     but may host different streams.
+     A priority must be given among them (either they are multualy exclusive, so the volume
+     will be the one of the active stream with highest priority (ORDER MATTERS) unless the curves
+     followed will the the curves for the requested attributes.-->
+    <volumeGroup>
+        <name>media_car_audio_type_3</name>
+        <indexMin>0</indexMin>
+        <indexMax>40</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+    <volumeGroup>
+        <name>media_car_audio_type_7</name>
+        <indexMin>0</indexMin>
+        <indexMax>40</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-2400</point>
+            <point>33,-1600</point>
+            <point>66,-800</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+    <volumeGroup>
+        <name>media</name>
+        <indexMin>0</indexMin>
+        <indexMax>40</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-2400</point>
+            <point>33,-1600</point>
+            <point>66,-800</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>speech</name>
+        <indexMin>1</indexMin>
+        <indexMax>40</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>system</name>
+        <indexMin>0</indexMin>
+        <indexMax>40</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>phone</name>
+        <indexMin>1</indexMin>
+        <indexMax>40</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>ring</name>
+        <indexMin>0</indexMin>
+        <indexMax>40</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>tts</name>
+        <indexMin>0</indexMin>
+        <indexMax>15</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-0</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>rerouting</name>
+        <indexMin>0</indexMin>
+        <indexMax>1</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+            <point>0,0</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>patch</name>
+        <indexMin>0</indexMin>
+        <indexMax>1</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+            <point>0,0</point>
+            <point>100,0</point>
+        </volume>
+    </volumeGroup>
+
+</volumeGroups>
+
diff --git a/services/audiopolicy/engineconfigurable/config/example/common/audio_policy_engine_criteria.xml b/services/audiopolicy/engineconfigurable/config/example/common/audio_policy_engine_criteria.xml
new file mode 100644
index 0000000..ec82b2e
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/common/audio_policy_engine_criteria.xml
@@ -0,0 +1,30 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<criteria>
+    <criterion name="AvailableInputDevices" type="InputDevicesMaskType" default="none"/>
+    <criterion name="AvailableOutputDevices" type="OutputDevicesMaskType" default="none"/>
+    <criterion name="AvailableOutputDevicesAddresses" type="OutputDevicesAddressesType" default="none"/>
+    <criterion name="AvailableInputDevicesAddresses" type="InputDevicesAddressesType" default="none"/>
+    <criterion name="TelephonyMode" type="AndroidModeType" default="Normal"/>
+    <criterion name="ForceUseForCommunication" type="ForceUseForCommunicationType" default="ForceNone"/>
+    <criterion name="ForceUseForMedia" type="ForceUseForMediaType" default="ForceNone"/>
+    <criterion name="ForceUseForRecord" type="ForceUseForRecordType" default="ForceNone"/>
+    <criterion name="ForceUseForDock" type="ForceUseForDockType" default="ForceNone"/>
+    <criterion name="ForceUseForSystem" type="ForceUseForSystemType" default="ForceNone"/>
+    <criterion name="ForceUseForHdmiSystemAudio" type="ForceUseForHdmiSystemAudioType" default="ForceNone"/>
+    <criterion name="ForceUseForEncodedSurround" type="ForceUseForEncodedSurroundType" default="ForceNone"/>
+    <criterion name="ForceUseForVibrateRinging" type="ForceUseForVibrateRingingType" default="ForceNone"/>
+</criteria>
diff --git a/services/audiopolicy/engineconfigurable/config/example/common/audio_policy_engine_criterion_types.xml.in b/services/audiopolicy/engineconfigurable/config/example/common/audio_policy_engine_criterion_types.xml.in
new file mode 100644
index 0000000..fe17369
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/common/audio_policy_engine_criterion_types.xml.in
@@ -0,0 +1,96 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<criterion_types>
+    <criterion_type name="OutputDevicesMaskType" type="inclusive"/>
+    <criterion_type name="InputDevicesMaskType" type="inclusive"/>
+    <criterion_type name="OutputDevicesAddressesType" type="inclusive">
+        <values>
+            <!-- legacy remote submix -->
+            <value literal="0" numerical="1"/>
+        </values>
+    </criterion_type>
+    <criterion_type name="InputDevicesAddressesType" type="inclusive"/>
+    <criterion_type name="AndroidModeType" type="exclusive"/>
+    <criterion_type name="BooleanType" type="exclusive">
+        <values>
+            <value literal="False" numerical="0"/>
+            <value literal="True" numerical="1"/>
+        </values>
+    </criterion_type>
+    <criterion_type name="ForceUseForCommunicationType" type="exclusive">
+        <values>
+            <value literal="ForceNone" numerical="0"/>
+            <value literal="ForceSpeaker" numerical="1"/>
+            <value literal="ForceBtSco" numerical="3"/>
+        </values>
+    </criterion_type>
+    <criterion_type name="ForceUseForMediaType" type="exclusive">
+        <values>
+            <value literal="ForceNone" numerical="0"/>
+            <value literal="ForceSpeaker" numerical="1"/>
+            <value literal="ForceHeadphones" numerical="2"/>
+            <value literal="ForceBtA2dp" numerical="4"/>
+            <value literal="ForceWiredAccessory" numerical="5"/>
+            <value literal="ForceAnalogDock" numerical="8"/>
+            <value literal="ForceDigitalDock" numerical="9"/>
+            <value literal="ForceNoBtA2dp" numerical="10"/>
+        </values>
+    </criterion_type>
+    <criterion_type name="ForceUseForRecordType" type="exclusive">
+        <values>
+            <value literal="ForceNone" numerical="0"/>
+            <value literal="ForceBtSco" numerical="3"/>
+            <value literal="ForceWiredAccessory" numerical="5"/>
+        </values>
+    </criterion_type>
+    <criterion_type name="ForceUseForDockType" type="exclusive">
+        <values>
+            <value literal="ForceNone" numerical="0"/>
+            <value literal="ForceWiredAccessory" numerical="5"/>
+            <value literal="ForceBtCarDock" numerical="6"/>
+            <value literal="ForceBtDeskDock" numerical="7"/>
+            <value literal="ForceAnalogDock" numerical="8"/>
+            <value literal="ForceDigitalDock" numerical="9"/>
+        </values>
+    </criterion_type>
+    <criterion_type name="ForceUseForSystemType" type="exclusive" >
+        <values>
+            <value literal="ForceNone" numerical="0"/>
+            <value literal="ForceSystemEnforced" numerical="11"/>
+        </values>
+    </criterion_type>
+    <criterion_type name="ForceUseForHdmiSystemAudioType" type="exclusive">
+        <values>
+            <value literal="ForceNone" numerical="0"/>
+            <value literal="ForceHdmiSystemEnforced" numerical="12"/>
+        </values>
+    </criterion_type>
+    <criterion_type name="ForceUseForEncodedSurroundType" type="exclusive">
+        <values>
+            <value literal="ForceNone" numerical="0"/>
+            <value literal="ForceEncodedSurroundNever" numerical="13"/>
+            <value literal="ForceEncodedSurroundAlways" numerical="14"/>
+        </values>
+    </criterion_type>
+    <criterion_type name="ForceUseForVibrateRingingType" type="exclusive">
+        <values>
+            <value literal="ForceNone" numerical="0"/>
+            <value literal="ForceBtSco" numerical="3"/>
+        </values>
+    </criterion_type>
+</criterion_types>
+
+
diff --git a/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_configuration.xml b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_configuration.xml
new file mode 100644
index 0000000..3faf9b9
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_configuration.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+     -->
+
+<configuration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+
+    <xi:include href="audio_policy_engine_product_strategies.xml"/>
+    <xi:include href="audio_policy_engine_criterion_types.xml"/>
+    <xi:include href="audio_policy_engine_criteria.xml"/>
+    <xi:include href="audio_policy_engine_stream_volumes.xml"/>
+    <xi:include href="audio_policy_engine_default_stream_volumes.xml"/>
+
+</configuration>
+
diff --git a/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_default_stream_volumes.xml b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_default_stream_volumes.xml
new file mode 100644
index 0000000..21e6dd5
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_default_stream_volumes.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<!-- Default Volume Tables included by Audio Policy Configuration file -->
+<!-- Full Default Volume table for all device category -->
+<volumes>
+    <reference name="FULL_SCALE_VOLUME_CURVE">
+    <!-- Full Scale reference Volume Curve -->
+        <point>0,0</point>
+        <point>100,0</point>
+    </reference>
+    <reference name="SILENT_VOLUME_CURVE">
+        <point>0,-9600</point>
+        <point>100,-9600</point>
+    </reference>
+    <reference name="DEFAULT_SYSTEM_VOLUME_CURVE">
+    <!-- Default System reference Volume Curve -->
+        <point>1,-2400</point>
+        <point>33,-1800</point>
+        <point>66,-1200</point>
+        <point>100,-600</point>
+    </reference>
+    <reference name="DEFAULT_MEDIA_VOLUME_CURVE">
+    <!-- Default Media reference Volume Curve -->
+        <point>1,-5800</point>
+        <point>20,-4000</point>
+        <point>60,-1700</point>
+        <point>100,0</point>
+    </reference>
+    <reference name="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE">
+    <!--Default Volume Curve -->
+        <point>1,-4950</point>
+        <point>33,-3350</point>
+        <point>66,-1700</point>
+        <point>100,0</point>
+    </reference>
+    <reference name="DEFAULT_DEVICE_CATEGORY_SPEAKER_VOLUME_CURVE">
+    <!-- Default is Speaker Media Volume Curve -->
+        <point>1,-5800</point>
+        <point>20,-4000</point>
+        <point>60,-1700</point>
+        <point>100,0</point>
+    </reference>
+    <reference name="DEFAULT_DEVICE_CATEGORY_SPEAKER_SYSTEM_VOLUME_CURVE">
+    <!-- Default is Speaker System Volume Curve -->
+        <point>1,-4680</point>
+        <point>42,-2070</point>
+        <point>85,-540</point>
+        <point>100,0</point>
+    </reference>
+    <reference name="DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE">
+    <!--Default Volume Curve -->
+        <point>1,-4950</point>
+        <point>33,-3350</point>
+        <point>66,-1700</point>
+        <point>100,0</point>
+    </reference>
+    <reference name="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE">
+    <!-- Default is Ext Media System Volume Curve -->
+        <point>1,-5800</point>
+        <point>20,-4000</point>
+        <point>60,-2100</point>
+        <point>100,-1000</point>
+    </reference>
+    <reference name="DEFAULT_HEARING_AID_VOLUME_CURVE">
+    <!-- Default Hearing Aid Volume Curve -->
+        <point>1,-12700</point>
+        <point>20,-8000</point>
+        <point>60,-4000</point>
+        <point>100,0</point>
+    </reference>
+    <!-- **************************************************************** -->
+    <!-- Non-mutable default volume curves:                               -->
+    <!--     * first point is always for index 0                          -->
+    <!--     * attenuation is small enough that stream can still be heard -->
+    <reference name="DEFAULT_NON_MUTABLE_VOLUME_CURVE">
+    <!-- Default non-mutable reference Volume Curve -->
+    <!--        based on DEFAULT_MEDIA_VOLUME_CURVE -->
+        <point>0,-5800</point>
+        <point>20,-4000</point>
+        <point>60,-1700</point>
+        <point>100,0</point>
+    </reference>
+    <reference name="DEFAULT_NON_MUTABLE_HEADSET_VOLUME_CURVE">
+    <!--Default non-mutable Volume Curve for headset -->
+    <!--    based on DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE -->
+        <point>0,-4950</point>
+        <point>33,-3350</point>
+        <point>66,-1700</point>
+        <point>100,0</point>
+    </reference>
+    <reference name="DEFAULT_NON_MUTABLE_SPEAKER_VOLUME_CURVE">
+    <!-- Default non-mutable Speaker Volume Curve -->
+    <!--    based on DEFAULT_DEVICE_CATEGORY_SPEAKER_VOLUME_CURVE -->
+        <point>0,-5800</point>
+        <point>20,-4000</point>
+        <point>60,-1700</point>
+        <point>100,0</point>
+    </reference>
+    <reference name="DEFAULT_NON_MUTABLE_EARPIECE_VOLUME_CURVE">
+    <!--Default non-mutable Volume Curve -->
+    <!--    based on DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE -->
+        <point>0,-4950</point>
+        <point>33,-3350</point>
+        <point>66,-1700</point>
+        <point>100,0</point>
+    </reference>
+    <reference name="DEFAULT_NON_MUTABLE_EXT_VOLUME_CURVE">
+    <!-- Default non-mutable Ext Media System Volume Curve -->
+    <!--     based on DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE -->
+        <point>0,-5800</point>
+        <point>20,-4000</point>
+        <point>60,-2100</point>
+        <point>100,-1000</point>
+    </reference>
+    <reference name="DEFAULT_NON_MUTABLE_HEARING_AID_VOLUME_CURVE">
+    <!-- Default non-mutable Hearing Aid Volume Curve -->
+    <!--     based on DEFAULT_HEARING_AID_VOLUME_CURVE -->
+        <point>0,-12700</point>
+        <point>20,-8000</point>
+        <point>60,-4000</point>
+        <point>100,0</point>
+    </reference>
+</volumes>
diff --git a/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml
new file mode 100644
index 0000000..9398743
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+     -->
+
+<ProductStrategies>
+
+    <!-- "hidden strategies" like TTS, enforced audible:
+            Shall we expose them here or keep it hard coded -->
+
+    <!-- Used to identify the volume of audio streams for enforced system sounds in certain
+         countries (e.g. camera in Japan)
+         This strategy will only have higher priority than phone if force for system is set to
+         enforced. -->
+
+    <ProductStrategy name="STRATEGY_PHONE">
+        <AttributesGroup streamType="AUDIO_STREAM_VOICE_CALL" volumeGroup="voice_call">
+            <Attributes> <Usage value="AUDIO_USAGE_VOICE_COMMUNICATION"/> </Attributes>
+        </AttributesGroup>
+        <AttributesGroup streamType="AUDIO_STREAM_BLUETOOTH_SCO" volumeGroup="bluetooth_sco">
+            <Attributes> <Flags value="AUDIO_FLAG_SCO"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="STRATEGY_SONIFICATION">
+        <AttributesGroup streamType="AUDIO_STREAM_RING" volumeGroup="ring">
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE"/> </Attributes>
+        </AttributesGroup>
+        <AttributesGroup streamType="AUDIO_STREAM_ALARM" volumeGroup="alarm">
+            <Attributes> <Usage value="AUDIO_USAGE_ALARM"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="STRATEGY_ENFORCED_AUDIBLE">
+        <AttributesGroup streamType="AUDIO_STREAM_ENFORCED_AUDIBLE" volumeGroup="enforced_audible">
+            <Attributes> <Flags value="AUDIO_FLAG_AUDIBILITY_ENFORCED"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="STRATEGY_ACCESSIBILITY">
+        <AttributesGroup streamType="AUDIO_STREAM_ACCESSIBILITY" volumeGroup="accessibility">
+            <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="STRATEGY_SONIFICATION_RESPECTFUL">
+        <AttributesGroup streamType="AUDIO_STREAM_NOTIFICATION" volumeGroup="notification">
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_EVENT"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="STRATEGY_MEDIA">
+         <AttributesGroup streamType="AUDIO_STREAM_MUSIC" volumeGroup="music">
+            <Attributes> <Usage value="AUDIO_USAGE_MEDIA"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_GAME"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_ASSISTANT"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/> </Attributes>
+            <Attributes></Attributes>
+        </AttributesGroup>
+        <AttributesGroup streamType="AUDIO_STREAM_SYSTEM" volumeGroup="system">
+            <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="STRATEGY_DTMF">
+        <AttributesGroup streamType="AUDIO_STREAM_DTMF" volumeGroup="dtmf">
+            <Attributes> <Usage value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <!-- Used to identify the volume of audio streams exclusively transmitted through the  speaker
+         (TTS) of the device -->
+    <ProductStrategy name="STRATEGY_TRANSMITTED_THROUGH_SPEAKER">
+        <AttributesGroup streamType="AUDIO_STREAM_TTS" volumeGroup="tts">
+            <Attributes> <Flags value="AUDIO_FLAG_BEACON"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <!-- Routing Strategy rerouting may be removed as following media??? -->
+    <ProductStrategy name="STRATEGY_REROUTING">
+        <AttributesGroup streamType="AUDIO_STREAM_REROUTING" volumeGroup="rerouting">
+            <Attributes></Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <!-- Default product strategy has empty attributes -->
+    <ProductStrategy name="STRATEGY_PATCH">
+        <AttributesGroup streamType="AUDIO_STREAM_PATCH" volumeGroup="patch">
+            <Attributes></Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+
+</ProductStrategies>
+
diff --git a/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_stream_volumes.xml b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_stream_volumes.xml
new file mode 100644
index 0000000..707a184
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_stream_volumes.xml
@@ -0,0 +1,231 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<!-- Volume section defines a volume curve for a given use case and device category.
+It contains a list of points of this curve expressing the attenuation in Millibels for a given
+volume index from 0 to 100.
+<volume deviceCategory=””>
+<point>0,-9600</point>
+<point>100,0</point>
+</volume>
+-->
+
+<volumeGroups>
+    <volumeGroup>
+        <name>voice_call</name>
+        <indexMin>1</indexMin>
+        <indexMax>7</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-2400</point>
+            <point>33,-1600</point>
+            <point>66,-800</point>
+            <point>100,0</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE">
+            <point>0,-2700</point>
+            <point>33,-1800</point>
+            <point>66,-900</point>
+            <point>100,0</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>system</name>
+        <indexMin>0</indexMin>
+        <indexMax>7</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+            <point>1,-3000</point>
+            <point>33,-2600</point>
+            <point>66,-2200</point>
+            <point>100,-1800</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>1,-5100</point>
+            <point>57,-2800</point>
+            <point>71,-2500</point>
+            <point>85,-2300</point>
+            <point>100,-2100</point>
+        </volume>
+        <!--volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_SYSTEM_VOLUME_CURVE"/-->
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_SYSTEM_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>ring</name>
+        <indexMin>0</indexMin>
+        <indexMax>7</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_DEVICE_CATEGORY_SPEAKER_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>music</name>
+        <indexMin>0</indexMin>
+        <indexMax>25</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_DEVICE_CATEGORY_SPEAKER_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID"  ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>alarm</name>
+        <indexMin>1</indexMin>
+        <indexMax>7</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_NON_MUTABLE_HEADSET_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_NON_MUTABLE_SPEAKER_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_NON_MUTABLE_EARPIECE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_NON_MUTABLE_EXT_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_NON_MUTABLE_HEARING_AID_VOLUME_CURVE"/>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>notification</name>
+        <indexMin>0</indexMin>
+        <indexMax>7</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_DEVICE_CATEGORY_SPEAKER_SYSTEM_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE"/>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>bluetooth_sco</name>
+        <indexMin>0</indexMin>
+        <indexMax>15</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-2400</point>
+            <point>33,-1600</point>
+            <point>66,-800</point>
+            <point>100,0</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>enforced_audible</name>
+        <indexMin>0</indexMin>
+        <indexMax>7</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+            <point>1,-3000</point>
+            <point>33,-2600</point>
+            <point>66,-2200</point>
+            <point>100,-1800</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>1,-3400</point>
+            <point>71,-2400</point>
+            <point>100,-2000</point>
+        </volume>
+        <!--volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_SYSTEM_VOLUME_CURVE"/-->
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_SYSTEM_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>dtmf</name>
+        <indexMin>0</indexMin>
+        <indexMax>15</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+            <point>1,-3000</point>
+            <point>33,-2600</point>
+            <point>66,-2200</point>
+            <point>100,-1800</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>1,-4000</point>
+            <point>71,-2400</point>
+            <point>100,-1400</point>
+        </volume>
+        <!--volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_SYSTEM_VOLUME_CURVE"/-->
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_SYSTEM_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>tts</name>
+        <indexMin>0</indexMin>
+        <indexMax>15</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="SILENT_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="SILENT_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="SILENT_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="SILENT_VOLUME_CURVE"/>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>accessibility</name>
+        <indexMin>1</indexMin>
+        <indexMax>15</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_NON_MUTABLE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_NON_MUTABLE_SPEAKER_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_NON_MUTABLE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_NON_MUTABLE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_NON_MUTABLE_HEARING_AID_VOLUME_CURVE"/>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>rerouting</name>
+        <indexMin>0</indexMin>
+        <indexMax>1</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="FULL_SCALE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="FULL_SCALE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="FULL_SCALE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="FULL_SCALE_VOLUME_CURVE"/>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>patch</name>
+        <indexMin>0</indexMin>
+        <indexMax>1</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="FULL_SCALE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="FULL_SCALE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="FULL_SCALE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="FULL_SCALE_VOLUME_CURVE"/>
+    </volumeGroup>
+</volumeGroups>
+
diff --git a/services/audiopolicy/engineconfigurable/include/AudioPolicyEngineInstance.h b/services/audiopolicy/engineconfigurable/include/AudioPolicyEngineInstance.h
index a597e87..efc69da 100644
--- a/services/audiopolicy/engineconfigurable/include/AudioPolicyEngineInstance.h
+++ b/services/audiopolicy/engineconfigurable/include/AudioPolicyEngineInstance.h
@@ -19,10 +19,8 @@
 class AudioPolicyManagerInterface;
 class AudioPolicyPluginInterface;
 
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
 
 class Engine;
 
diff --git a/services/audiopolicy/engineconfigurable/interface/AudioPolicyPluginInterface.h b/services/audiopolicy/engineconfigurable/interface/AudioPolicyPluginInterface.h
index 2e29a9b..1fc2264 100644
--- a/services/audiopolicy/engineconfigurable/interface/AudioPolicyPluginInterface.h
+++ b/services/audiopolicy/engineconfigurable/interface/AudioPolicyPluginInterface.h
@@ -16,10 +16,11 @@
 
 #pragma once
 
-#include <RoutingStrategy.h>
+#include <policy.h>
 #include <EngineDefinition.h>
 #include <Volume.h>
 #include <system/audio.h>
+#include <media/AudioCommonTypes.h>
 #include <utils/Errors.h>
 #include <string>
 #include <vector>
@@ -36,19 +37,6 @@
 {
 public:
     /**
-     * Add a strategy to the engine
-     *
-     * @param[in] name of the strategy to add
-     * @param[in] identifier: the numerical value associated to this member. It MUST match either
-     *            system/audio.h or system/audio_policy.h enumration value in order to link the
-     *            parameter controled by the PFW and the policy manager component.
-     *
-     * @return NO_ERROR if the strategy has been added successfully, error code otherwise.
-     *
-     */
-    virtual android::status_t addStrategy(const std::string &name, routing_strategy id) = 0;
-
-    /**
      * Add a streams to the engine.
      *
      * @param[in] name of the stream to add
@@ -62,19 +50,6 @@
     virtual android::status_t addStream(const std::string &name, audio_stream_type_t id) = 0;
 
     /**
-     * Add a usage to the engine
-     *
-     * @param[in] name of the usage to add
-     * @param[in] identifier: the numerical value associated to this member. It MUST match either
-     *            system/audio.h or system/audio_policy.h enumration value in order to link the
-     *            parameter controled by the PFW and the policy manager component.
-     *
-     * @return NO_ERROR if the usage has been added successfully, error code otherwise.
-     *
-     */
-    virtual android::status_t addUsage(const std::string &name, audio_usage_t id) = 0;
-
-    /**
      * Add an input source to the engine
      *
      * @param[in] name of the input source to add
@@ -88,26 +63,6 @@
     virtual android::status_t addInputSource(const std::string &name, audio_source_t id) = 0;
 
     /**
-     * Set the device to be used by a strategy.
-     *
-     * @param[in] strategy: name of the strategy for which the device to use has to be set
-     * @param[in] devices; mask of devices to be used for the given strategy.
-     *
-     * @return true if the devices were set correclty for this strategy, false otherwise.
-     */
-    virtual bool setDeviceForStrategy(const routing_strategy &strategy, audio_devices_t devices) = 0;
-
-    /**
-     * Set the strategy to be followed by a stream.
-     *
-     * @param[in] stream: name of the stream for which the strategy to use has to be set
-     * @param[in] strategy to follow for the given stream.
-     *
-     * @return true if the strategy were set correclty for this stream, false otherwise.
-     */
-    virtual bool setStrategyForStream(const audio_stream_type_t &stream, routing_strategy strategy) = 0;
-
-    /**
      * Set the strategy to be followed by a stream.
      *
      * @param[in] stream: name of the stream for which the strategy to use has to be set
@@ -119,16 +74,6 @@
                                            const audio_stream_type_t &volumeProfile) = 0;
 
     /**
-     * Set the strategy to be followed by a usage.
-     *
-     * @param[in] usage: name of the usage for which the strategy to use has to be set
-     * @param[in] strategy to follow for the given usage.
-     *
-     * @return true if the strategy were set correclty for this usage, false otherwise.
-     */
-    virtual bool setStrategyForUsage(const audio_usage_t &usage, routing_strategy strategy) = 0;
-
-    /**
      * Set the input device to be used by an input source.
      *
      * @param[in] inputSource: name of the input source for which the device to use has to be set
@@ -139,6 +84,22 @@
     virtual bool setDeviceForInputSource(const audio_source_t &inputSource,
                                          audio_devices_t device) = 0;
 
+    virtual void setDeviceAddressForProductStrategy(product_strategy_t strategy,
+                                                    const std::string &address) = 0;
+
+    /**
+     * Set the device to be used by a product strategy.
+     *
+     * @param[in] strategy: name of the product strategy for which the device to use has to be set
+     * @param[in] devices; mask of devices to be used for the given strategy.
+     *
+     * @return true if the devices were set correclty for this strategy, false otherwise.
+     */
+    virtual bool setDeviceTypesForProductStrategy(product_strategy_t strategy,
+                                                  audio_devices_t devices) = 0;
+
+    virtual product_strategy_t getProductStrategyByName(const std::string &address) = 0;
+
 protected:
     virtual ~AudioPolicyPluginInterface() {}
 };
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/Android.mk
deleted file mode 100644
index c402fd5..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/Android.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-#######################################################################
-# Recursive call sub-folder Android.mk
-#######################################################################
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
index baaefd2..19f93b3 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
@@ -7,27 +7,44 @@
 #
 ################################################################################################
 
-ifeq (1, 0)
-
 LOCAL_PATH := $(call my-dir)
 
+ifdef BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable caremu_configurable no-output_configurable no-input_configurable))
+
 PFW_CORE := external/parameter-framework
-BUILD_PFW_SETTINGS := $(PFW_CORE)/support/android/build_pfw_settings.mk
+#@TODO: upstream new domain generator
+#BUILD_PFW_SETTINGS := $(PFW_CORE)/support/android/build_pfw_settings.mk
 PFW_DEFAULT_SCHEMAS_DIR := $(PFW_CORE)/upstream/schemas
 PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
 
+TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
+BUILD_PFW_SETTINGS := $(TOOLS)/build_audio_pfw_settings.mk
+
+PROVISION_STRATEGIES_STRUCTURE := $(TOOLS)/provision_strategies_structure.mk
+
+endif
+
 ##################################################################
 # CONFIGURATION FILES
 ##################################################################
 ######### Policy PFW top level file #########
 
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable caremu_configurable))
+
 include $(CLEAR_VARS)
 LOCAL_MODULE := ParameterFrameworkConfigurationPolicy.xml
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/parameter-framework
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework
 LOCAL_SRC_FILES := $(LOCAL_MODULE).in
+LOCAL_REQUIRED_MODULES := \
+    PolicySubsystem.xml \
+    PolicyClass.xml
 
+# external/parameter-framework prevents from using debug interface
 AUDIO_PATTERN = @TUNING_ALLOWED@
 ifeq ($(TARGET_BUILD_VARIANT),user)
 AUDIO_VALUE = false
@@ -35,128 +52,136 @@
 AUDIO_VALUE = true
 endif
 
-LOCAL_POST_INSTALL_CMD := $(hide) sed -i -e 's|$(AUDIO_PATTERN)|$(AUDIO_VALUE)|g' $(LOCAL_MODULE_PATH)/$(LOCAL_MODULE)
+LOCAL_POST_INSTALL_CMD := $(hide) sed -i -e 's|$(AUDIO_PATTERN)|$(AUDIO_VALUE)|g' $(TARGET_OUT_VENDOR_ETC)/$(LOCAL_MODULE_RELATIVE_PATH)/$(LOCAL_MODULE)
 
 include $(BUILD_PREBUILT)
 
-
-########## Policy PFW Structures #########
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := PolicyClass.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/parameter-framework/Structure/Policy
-LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
+########## Policy PFW Common Structures #########
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := PolicySubsystem.xml
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
 LOCAL_REQUIRED_MODULES := \
     PolicySubsystem-CommonTypes.xml \
-    PolicySubsystem-Volume.xml \
-    libpolicy-subsystem \
+    ProductStrategies.xml
 
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/parameter-framework/Structure/Policy
-LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE)
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
+LOCAL_SRC_FILES := common/Structure/$(LOCAL_MODULE)
 include $(BUILD_PREBUILT)
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := PolicySubsystem-CommonTypes.xml
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/parameter-framework/Structure/Policy
-LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE)
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
+LOCAL_SRC_FILES := common/Structure/$(LOCAL_MODULE)
 include $(BUILD_PREBUILT)
 
-######### Policy PFW Settings #########
 include $(CLEAR_VARS)
-LOCAL_MODULE := parameter-framework.policy
-LOCAL_MODULE_STEM := PolicyConfigurableDomains.xml
+LOCAL_MODULE := PolicyClass.xml
+LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
-LOCAL_ADDITIONAL_DEPENDENCIES := \
-        PolicyClass.xml \
-        PolicySubsystem.xml \
-        ParameterFrameworkConfigurationPolicy.xml
-
-ifeq ($(pfw_rebuild_settings),true)
-PFW_TOPLEVEL_FILE := $(TARGET_OUT_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
-PFW_CRITERIA_FILE := $(LOCAL_PATH)/policy_criteria.txt
-PFW_EDD_FILES := \
-        $(LOCAL_PATH)/Settings/device_for_strategy_media.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_phone.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_sonification.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_sonification_respectful.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_dtmf.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_enforced_audible.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_transmitted_through_speaker.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_accessibility.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_rerouting.pfw \
-        $(LOCAL_PATH)/Settings/strategy_for_stream.pfw \
-        $(LOCAL_PATH)/Settings/strategy_for_usage.pfw \
-        $(LOCAL_PATH)/Settings/device_for_input_source.pfw \
-        $(LOCAL_PATH)/Settings/volumes.pfw
-
-include $(BUILD_PFW_SETTINGS)
-else
-# Use the existing file
-LOCAL_SRC_FILES := Settings/$(LOCAL_MODULE_STEM)
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
+LOCAL_SRC_FILES := common/Structure/$(LOCAL_MODULE)
 include $(BUILD_PREBUILT)
-endif # pfw_rebuild_settings
+
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := ProductStrategies.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
+
+AUDIO_POLICY_ENGINE_CONFIGURATION_FILE := \
+    $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_configuration.xml
+STRATEGIES_STRUCTURE_FILE := $(LOCAL_PATH)/common/Structure/$(LOCAL_MODULE).in
+
+include $(PROVISION_STRATEGIES_STRUCTURE)
+
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable caremu_configurable))
+
+########## Policy PFW Example Structures #########
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-output_configurable no-input_configurable))
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := PolicySubsystem.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_REQUIRED_MODULES := PolicySubsystem-CommonTypes.xml
+
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
+LOCAL_SRC_FILES := common/Structure/$(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := ParameterFrameworkConfigurationPolicy-no-strategy.xml
+LOCAL_MODULE_STEM := ParameterFrameworkConfigurationPolicy.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework
+LOCAL_SRC_FILES := $(LOCAL_MODULE).in
+LOCAL_REQUIRED_MODULES := \
+    PolicySubsystem.xml \
+    PolicyClass.xml
+AUDIO_VALUE = false
+LOCAL_POST_INSTALL_CMD := $(hide) sed -i -e 's|$(AUDIO_PATTERN)|$(AUDIO_VALUE)|g' $(TARGET_OUT_VENDOR_ETC)/$(LOCAL_MODULE_RELATIVE_PATH)/$(LOCAL_MODULE)
+
+include $(BUILD_PREBUILT)
+
+endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-output_configurable no-input_configurable))
 
 ######### Policy PFW Settings - No Output #########
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-output_configurable)
+
 include $(CLEAR_VARS)
-LOCAL_MODULE := parameter-framework.policy.no-output
+LOCAL_MODULE := parameter-framework.policy
 LOCAL_MODULE_STEM := PolicyConfigurableDomains-NoOutputDevice.xml
 LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
-LOCAL_ADDITIONAL_DEPENDENCIES := \
-        PolicyClass.xml \
-        PolicySubsystem.xml \
-        ParameterFrameworkConfigurationPolicy.xml
 
-PFW_TOPLEVEL_FILE := $(TARGET_OUT_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
-PFW_CRITERIA_FILE := $(LOCAL_PATH)/policy_criteria.txt
+PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
+PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criterion_types.xml
+PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criteria.xml
 PFW_EDD_FILES := \
         $(LOCAL_PATH)/SettingsNoOutput/device_for_strategies.pfw \
-        $(LOCAL_PATH)/Settings/strategy_for_stream.pfw \
-        $(LOCAL_PATH)/Settings/strategy_for_usage.pfw \
         $(LOCAL_PATH)/Settings/device_for_input_source.pfw \
-        $(LOCAL_PATH)/Settings/volumes.pfw
-
+        $(LOCAL_PATH)/Settings/volumes.pfw        
+LOCAL_REQUIRED_MODULES := libpolicy-subsystem
 include $(BUILD_PFW_SETTINGS)
 
+endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-output_configurable)
 ######### Policy PFW Settings - No Input #########
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-input_configurable)
+
 include $(CLEAR_VARS)
-LOCAL_MODULE := parameter-framework.policy.no-input
+LOCAL_MODULE := parameter-framework.policy
 LOCAL_MODULE_STEM := PolicyConfigurableDomains-NoInputDevice.xml
 LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
-LOCAL_ADDITIONAL_DEPENDENCIES := \
-        PolicyClass.xml \
-        PolicySubsystem.xml \
-        ParameterFrameworkConfigurationPolicy.xml
 
-PFW_TOPLEVEL_FILE := $(TARGET_OUT_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
-PFW_CRITERIA_FILE := $(LOCAL_PATH)/policy_criteria.txt
+PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
+PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criterion_types.xml
+PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criteria.xml
 PFW_EDD_FILES := \
-        $(LOCAL_PATH)/Settings/device_for_strategy_media.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_phone.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_sonification.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_sonification_respectful.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_dtmf.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_enforced_audible.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_transmitted_through_speaker.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_accessibility.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_rerouting.pfw \
-        $(LOCAL_PATH)/Settings/strategy_for_stream.pfw \
-        $(LOCAL_PATH)/Settings/strategy_for_usage.pfw \
         $(LOCAL_PATH)/SettingsNoInput/device_for_input_source.pfw \
         $(LOCAL_PATH)/Settings/volumes.pfw
-
+LOCAL_REQUIRED_MODULES := libpolicy-subsystem
 include $(BUILD_PFW_SETTINGS)
 
-endif # ifeq (1, 0)
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-input_configurable)
+#######################################################################
+# Recursive call sub-folder Android.mk
+#######################################################################
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
+
+endif #ifdef BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION
+
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Android.mk
new file mode 100644
index 0000000..7304ec2
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Android.mk
@@ -0,0 +1,47 @@
+################################################################################################
+#
+# @NOTE:
+# Audio Policy Engine configurable example for generic device build
+#
+# Any vendor shall have its own configuration within the corresponding device folder
+#
+################################################################################################
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), automotive_configurable)
+LOCAL_PATH := $(call my-dir)
+
+PFW_CORE := external/parameter-framework
+PFW_DEFAULT_SCHEMAS_DIR := $(PFW_CORE)/upstream/schemas
+PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
+
+TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
+BUILD_PFW_SETTINGS := $(TOOLS)/build_audio_pfw_settings.mk
+
+
+##################################################################
+# CONFIGURATION FILES
+##################################################################
+
+########## Policy PFW Structures #########
+######### Policy PFW Settings #########
+include $(CLEAR_VARS)
+LOCAL_MODULE := parameter-framework.policy
+LOCAL_MODULE_STEM := PolicyConfigurableDomains.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
+LOCAL_REQUIRED_MODULES := libpolicy-subsystem
+
+PFW_EDD_FILES := \
+    $(LOCAL_PATH)/Settings/device_for_product_strategies.pfw \
+    $(LOCAL_PATH)/../Settings/device_for_input_source.pfw \
+    $(LOCAL_PATH)/../Settings/volumes.pfw
+
+PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criterion_types.xml
+PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criteria.xml
+PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
+PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
+
+include $(BUILD_PFW_SETTINGS)
+
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), automotive_configurable)
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Settings/device_for_product_strategies.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Settings/device_for_product_strategies.pfw
new file mode 100644
index 0000000..57ad592
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Settings/device_for_product_strategies.pfw
@@ -0,0 +1,760 @@
+supDomain: DeviceForProductStrategies
+	supDomain: OemTrafficAnouncement
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/oem_traffic_anouncement/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/oem_traffic_anouncement/device_address = BUS08_OEM1
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS08_OEM1
+
+				component: /Policy/policy/product_strategies/oem_traffic_anouncement/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/oem_traffic_anouncement/selected_output_devices/mask
+					bus = 0
+
+	supDomain: OemStrategy1
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/oem_strategy_1/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/oem_strategy_1/device_address = BUS08_OEM1
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS08_OEM1
+
+				component: /Policy/policy/product_strategies/oem_strategy_1/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/oem_strategy_1/selected_output_devices/mask
+					bus = 0
+
+
+
+	supDomain: OemStrategy2
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/oem_strategy_2/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/oem_strategy_2/device_address = BUS08_OEM1
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS08_OEM1
+
+				component: /Policy/policy/product_strategies/oem_strategy_2/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/oem_strategy_2/selected_output_devices/mask
+					bus = 0
+
+
+
+	supDomain: Radio
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/radio/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/radio/device_address = BUS09_OEM2
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS09_OEM2
+
+				component: /Policy/policy/product_strategies/radio/selected_output_devices/mask
+					speaker = 0
+					bus = 1
+
+			conf: Speaker
+				AvailableOutputDevices Includes Speaker
+				component: /Policy/policy/product_strategies/radio/selected_output_devices/mask
+					speaker = 1
+					bus = 0
+
+			conf: Default
+				component: /Policy/policy/product_strategies/radio/selected_output_devices/mask
+					speaker = 0
+					bus = 0
+
+	supDomain: ExtAudioSource
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/ext_audio_source/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/ext_audio_source/device_address = BUS09_OEM2
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS09_OEM2
+
+				component: /Policy/policy/product_strategies/ext_audio_source/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/ext_audio_source/selected_output_devices/mask
+					bus = 0
+
+
+
+	supDomain: VoiceCommand
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/voice_command/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/voice_command/device_address = BUS02_VOICE_COMMAND
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS02_VOICE_COMMAND
+
+				component: /Policy/policy/product_strategies/voice_command/selected_output_devices/mask
+					speaker = 0
+					bus = 1
+
+			conf: Speaker
+				AvailableOutputDevices Includes Speaker
+				component: /Policy/policy/product_strategies/voice_command/selected_output_devices/mask
+					speaker = 1
+					bus = 0
+
+			conf: Default
+				component: /Policy/policy/product_strategies/voice_command/selected_output_devices/mask
+					speaker = 0
+					bus = 0
+
+
+	supDomain: SafetyAlert
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/safety_alert/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/safety_alert/device_address = BUS00_MEDIA
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS00_MEDIA
+
+				component: /Policy/policy/product_strategies/safety_alert/selected_output_devices/mask
+					speaker = 0
+					bus = 1
+
+			conf: Speaker
+				AvailableOutputDevices Includes Speaker
+				component: /Policy/policy/product_strategies/safety_alert/selected_output_devices/mask
+					speaker = 1
+					bus = 0
+
+			conf: Default
+				component: /Policy/policy/product_strategies/safety_alert/selected_output_devices/mask
+					speaker = 0
+					bus = 0
+
+
+	supDomain: Music
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/music/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/music/device_address = BUS00_MEDIA
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS00_MEDIA
+
+				component: /Policy/policy/product_strategies/music/selected_output_devices/mask
+					speaker = 0
+					bus = 1
+
+			conf: Speaker
+				AvailableOutputDevices Includes Speaker
+				component: /Policy/policy/product_strategies/music/selected_output_devices/mask
+					speaker = 1
+					bus = 0
+
+			conf: Default
+				component: /Policy/policy/product_strategies/music/selected_output_devices/mask
+					speaker = 0
+					bus = 0
+
+
+
+	supDomain: NavGuidance
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/nav_guidance/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/nav_guidance/device_address = BUS01_NAV_GUIDANCE
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS01_NAV_GUIDANCE
+
+				component: /Policy/policy/product_strategies/nav_guidance/selected_output_devices/mask
+					speaker = 0
+					bus = 1
+
+			conf: Speaker
+				AvailableOutputDevices Includes Speaker
+				component: /Policy/policy/product_strategies/nav_guidance/selected_output_devices/mask
+					speaker = 1
+					bus = 0
+
+			conf: Default
+				component: /Policy/policy/product_strategies/nav_guidance/selected_output_devices/mask
+					speaker = 0
+					bus = 0
+
+
+	supDomain: VoiceCall
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/voice_call/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/voice_call/device_address = BUS04_CALL
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS04_CALL
+
+				component: /Policy/policy/product_strategies/voice_call/selected_output_devices/mask
+					speaker = 0
+					bus = 1
+
+			conf: Speaker
+				AvailableOutputDevices Includes Speaker
+				component: /Policy/policy/product_strategies/voice_call/selected_output_devices/mask
+					speaker = 1
+					bus = 0
+
+			conf: Default
+				component: /Policy/policy/product_strategies/voice_call/selected_output_devices/mask
+					speaker = 0
+					bus = 0
+
+
+	supDomain: Alarm
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/alarm/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/alarm/device_address = BUS05_ALARM
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS05_ALARM
+
+				component: /Policy/policy/product_strategies/alarm/selected_output_devices/mask
+					speaker = 0
+					bus = 1
+
+			conf: Speaker
+				AvailableOutputDevices Includes Speaker
+				component: /Policy/policy/product_strategies/alarm/selected_output_devices/mask
+					speaker = 1
+					bus = 0
+
+			conf: Default
+				component: /Policy/policy/product_strategies/alarm/selected_output_devices/mask
+					speaker = 0
+					bus = 0
+
+
+	supDomain: Ring
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/ring/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/ring/device_address = BUS03_CALL_RING
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS03_CALL_RING
+
+				component: /Policy/policy/product_strategies/ring/selected_output_devices/mask
+					speaker = 0
+					bus = 1
+
+			conf: Speaker
+				AvailableOutputDevices Includes Speaker
+				component: /Policy/policy/product_strategies/ring/selected_output_devices/mask
+					speaker = 1
+					bus = 0
+
+			conf: Default
+				component: /Policy/policy/product_strategies/ring/selected_output_devices/mask
+					speaker = 0
+					bus = 0
+
+
+	supDomain: Notification
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/notification/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/notification/device_address = BUS06_NOTIFICATION
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS06_NOTIFICATION
+
+				component: /Policy/policy/product_strategies/notification/selected_output_devices/mask
+					speaker = 0
+					bus = 1
+
+			conf: Speaker
+				AvailableOutputDevices Includes Speaker
+				component: /Policy/policy/product_strategies/notification/selected_output_devices/mask
+					speaker = 1
+					bus = 0
+
+			conf: Default
+				component: /Policy/policy/product_strategies/notification/selected_output_devices/mask
+					speaker = 0
+					bus = 0
+
+
+	supDomain: System
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/system/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/system/device_address = BUS07_SYSTEM_SOUND
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS07_SYSTEM_SOUND
+
+				component: /Policy/policy/product_strategies/system/selected_output_devices/mask
+					speaker = 0
+					bus = 1
+
+			conf: Speaker
+				AvailableOutputDevices Includes Speaker
+				component: /Policy/policy/product_strategies/system/selected_output_devices/mask
+					speaker = 1
+					bus = 0
+
+			conf: Default
+				component: /Policy/policy/product_strategies/system/selected_output_devices/mask
+					speaker = 0
+					bus = 0
+
+	supDomain: Tts
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/tts/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/tts/device_address = BUS00_MEDIA
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS00_MEDIA
+
+				component: /Policy/policy/product_strategies/tts/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/tts/selected_output_devices/mask
+					bus = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/CarEmu/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/examples/CarEmu/Android.mk
new file mode 100644
index 0000000..f5eb7d1
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/CarEmu/Android.mk
@@ -0,0 +1,46 @@
+################################################################################################
+#
+# @NOTE:
+# Audio Policy Engine configurable example for generic device build
+#
+# Any vendor shall have its own configuration within the corresponding device folder
+#
+################################################################################################
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), caremu_configurable)
+LOCAL_PATH := $(call my-dir)
+
+PFW_CORE := external/parameter-framework
+PFW_DEFAULT_SCHEMAS_DIR := $(PFW_CORE)/upstream/schemas
+PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
+
+TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
+BUILD_PFW_SETTINGS := $(TOOLS)/build_audio_pfw_settings.mk
+
+
+##################################################################
+# CONFIGURATION FILES
+##################################################################
+
+########## Policy PFW Structures #########
+######### Policy PFW Settings #########
+include $(CLEAR_VARS)
+LOCAL_MODULE := parameter-framework.policy
+LOCAL_MODULE_STEM := PolicyConfigurableDomains.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
+LOCAL_REQUIRED_MODULES := libpolicy-subsystem
+
+PFW_EDD_FILES := \
+    $(LOCAL_PATH)/Settings/device_for_product_strategies.pfw \
+    $(LOCAL_PATH)/../Settings/device_for_input_source.pfw \
+    $(LOCAL_PATH)/../Settings/volumes.pfw
+PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criterion_types.xml
+PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criteria.xml
+PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
+PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
+
+include $(BUILD_PFW_SETTINGS)
+
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), caremu_configurable)
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/CarEmu/Settings/device_for_product_strategies.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/CarEmu/Settings/device_for_product_strategies.pfw
new file mode 100644
index 0000000..ca3464f
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/CarEmu/Settings/device_for_product_strategies.pfw
@@ -0,0 +1,690 @@
+supDomain: DeviceForProductStrategies
+	supDomain: OemTrafficAnouncement
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/oem_traffic_anouncement/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/oem_traffic_anouncement/device_address = BUS00_MEDIA
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS00_MEDIA
+
+				component: /Policy/policy/product_strategies/oem_traffic_anouncement/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/oem_traffic_anouncement/selected_output_devices/mask
+					bus = 0
+
+	supDomain: OemStrategy1
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/oem_strategy_1/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/oem_strategy_1/device_address = BUS02_OEM1
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS02_OEM1
+
+				component: /Policy/policy/product_strategies/oem_strategy_1/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/oem_strategy_1/selected_output_devices/mask
+					bus = 0
+
+
+
+	supDomain: OemStrategy2
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/oem_strategy_2/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/oem_strategy_2/device_address = BUS01_NAV_GUIDANCE
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS01_NAV_GUIDANCE
+
+				component: /Policy/policy/product_strategies/oem_strategy_2/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/oem_strategy_2/selected_output_devices/mask
+					bus = 0
+
+
+
+	supDomain: Radio
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/radio/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/radio/device_address = BUS00_MEDIA
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS00_MEDIA
+
+				component: /Policy/policy/product_strategies/radio/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/radio/selected_output_devices/mask
+					bus = 0
+
+	supDomain: ExtAudioSource
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/ext_audio_source/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/ext_audio_source/device_address = BUS00_MEDIA
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS00_MEDIA
+
+				component: /Policy/policy/product_strategies/ext_audio_source/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/ext_audio_source/selected_output_devices/mask
+					bus = 0
+
+
+
+	supDomain: VoiceCommand
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/voice_command/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/voice_command/device_address = BUS04_VOICE
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS04_VOICE
+
+				component: /Policy/policy/product_strategies/voice_command/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/voice_command/selected_output_devices/mask
+					bus = 0
+
+
+	supDomain: SafetyAlert
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/safety_alert/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/safety_alert/device_address = BUS00_MEDIA
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS00_MEDIA
+
+				component: /Policy/policy/product_strategies/safety_alert/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/safety_alert/selected_output_devices/mask
+					bus = 0
+
+
+	supDomain: Music
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/music/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/music/device_address = BUS00_MEDIA
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS00_MEDIA
+
+				component: /Policy/policy/product_strategies/music/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/music/selected_output_devices/mask
+					bus = 0
+
+
+
+	supDomain: NavGuidance
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/nav_guidance/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/nav_guidance/device_address = BUS01_NAV_GUIDANCE
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS01_NAV_GUIDANCE
+
+				component: /Policy/policy/product_strategies/nav_guidance/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/nav_guidance/selected_output_devices/mask
+					bus = 0
+
+
+	supDomain: VoiceCall
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/voice_call/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/voice_call/device_address = BUS04_VOICE
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS04_VOICE
+
+				component: /Policy/policy/product_strategies/voice_call/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/voice_call/selected_output_devices/mask
+					bus = 0
+
+
+	supDomain: Alarm
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/alarm/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/alarm/device_address = BUS00_MEDIA
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS00_MEDIA
+
+				component: /Policy/policy/product_strategies/alarm/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/alarm/selected_output_devices/mask
+					bus = 0
+
+
+	supDomain: Ring
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/ring/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/ring/device_address = BUS04_VOICE
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS04_VOICE
+
+				component: /Policy/policy/product_strategies/ring/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/ring/selected_output_devices/mask
+					bus = 0
+
+
+	supDomain: Notification
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/notification/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/notification/device_address = BUS00_MEDIA
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS00_MEDIA
+
+				component: /Policy/policy/product_strategies/notification/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/notification/selected_output_devices/mask
+					bus = 0
+
+
+	supDomain: System
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/system/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/system/device_address = BUS03_SYSTEM_SOUND
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS03_SYSTEM_SOUND
+
+				component: /Policy/policy/product_strategies/system/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/system/selected_output_devices/mask
+					bus = 0
+
+	supDomain: Tts
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/tts/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/tts/device_address = BUS00_MEDIA
+ 
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS00_MEDIA
+
+				component: /Policy/policy/product_strategies/tts/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/tts/selected_output_devices/mask
+					bus = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.xml.in b/services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.xml.in
index f5615cd..1be67dd 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.xml.in
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.xml.in
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ParameterFrameworkConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    SystemClassName="Policy" ServerPort="5019" TuningAllowed="@TUNING_ALLOWED@">
+    SystemClassName="Policy" ServerPort="unix:///dev/socket/audioserver/policy_debug"
+    TuningAllowed="@TUNING_ALLOWED@">
 
     <SubsystemPlugins>
         <Location Folder="">
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Android.mk
new file mode 100644
index 0000000..0b20781
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Android.mk
@@ -0,0 +1,54 @@
+################################################################################################
+#
+# @NOTE:
+# Audio Policy Engine configurable example for generic device build
+#
+# Any vendor shall have its own configuration within the corresponding device folder
+#
+################################################################################################
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_configurable)
+
+LOCAL_PATH := $(call my-dir)
+
+PFW_CORE := external/parameter-framework
+PFW_DEFAULT_SCHEMAS_DIR := $(PFW_CORE)/upstream/schemas
+PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
+
+TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
+BUILD_PFW_SETTINGS := $(TOOLS)/build_audio_pfw_settings.mk
+
+##################################################################
+# CONFIGURATION FILES
+##################################################################
+########## Policy PFW Structures #########
+######### Policy PFW Settings #########
+include $(CLEAR_VARS)
+LOCAL_MODULE := parameter-framework.policy
+LOCAL_MODULE_STEM := PolicyConfigurableDomains.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
+LOCAL_REQUIRED_MODULES := libpolicy-subsystem
+
+PFW_EDD_FILES := \
+        $(LOCAL_PATH)/../Settings/device_for_input_source.pfw \
+        $(LOCAL_PATH)/../Settings/volumes.pfw \
+        $(LOCAL_PATH)/Settings/device_for_product_strategy_media.pfw \
+        $(LOCAL_PATH)/Settings/device_for_product_strategy_accessibility.pfw \
+        $(LOCAL_PATH)/Settings/device_for_product_strategy_dtmf.pfw \
+        $(LOCAL_PATH)/Settings/device_for_product_strategy_enforced_audible.pfw \
+        $(LOCAL_PATH)/Settings/device_for_product_strategy_phone.pfw \
+        $(LOCAL_PATH)/Settings/device_for_product_strategy_sonification.pfw \
+        $(LOCAL_PATH)/Settings/device_for_product_strategy_sonification_respectful.pfw \
+        $(LOCAL_PATH)/Settings/device_for_product_strategy_transmitted_through_speaker.pfw \
+        $(LOCAL_PATH)/Settings/device_for_product_strategy_rerouting.pfw \
+        $(LOCAL_PATH)/Settings/device_for_product_strategy_patch.pfw
+PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criterion_types.xml
+PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criteria.xml
+PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
+PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
+
+include $(BUILD_PFW_SETTINGS)
+
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_configurable)
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_accessibility.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_accessibility.pfw
new file mode 100644
index 0000000..53e93de
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_accessibility.pfw
@@ -0,0 +1,596 @@
+supDomain: DeviceForProductStrategy
+
+	supDomain: Accessibility
+		#
+		# STRATEGY_ACCESSIBILITY follows STRATEGY_PHONE if in call widely speaking
+		# STRATEGY_ACCESSIBILITY follows STRATEGY_MEDIA otherwise
+		#
+		# Other case are handled programmatically has involving activity of streams.
+		#
+		domain: UnreachableDevices
+			conf: Calibration
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
+					hdmi_arc = 0
+					spdif = 0
+					aux_line = 0
+					fm = 0
+					speaker_safe = 0
+					telephony_tx = 0
+					ip = 0
+					bus = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+
+		domain: Device
+			conf: RemoteSubmix
+				#
+				# Accessibility follows Media strategy if not in call
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				AvailableOutputDevices Includes RemoteSubmix
+				AvailableOutputDevicesAddresses Includes 0
+
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
+					remote_submix = 1
+					earpiece = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: BluetoothA2dp
+				#
+				# Accessibility falls through media strategy if not in call (widely speaking)
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				ForceUseForMedia IsNot ForceNoBtA2dp
+				AvailableOutputDevices Includes BluetoothA2dp
+
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					bluetooth_a2dp = 1
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: BluetoothA2dpHeadphone
+				#
+				# Accessibility falls through media strategy if not in call (widely speaking)
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				ForceUseForMedia IsNot ForceNoBtA2dp
+				AvailableOutputDevices Includes BluetoothA2dpHeadphones
+
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 1
+					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: BluetoothA2dpSpeaker
+				#
+				# Accessibility falls through media strategy if not in call (widely speaking)
+				#
+				ForceUseForMedia IsNot ForceNoBtA2dp
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				AvailableOutputDevices Includes BluetoothA2dpSpeaker
+
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 1
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: ForceSpeakerWhenNotInCall
+				#
+				# Accessibility follows Media strategy if not in call
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				ForceUseForMedia Is ForceSpeaker
+				AvailableOutputDevices Includes Speaker
+
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
+					speaker = 1
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: BluetoothScoCarkit
+				#
+				# accessibility falls through Phone strategy if in call
+				#
+				ANY
+					TelephonyMode Is InCall
+					TelephonyMode Is InCommunication
+				AvailableOutputDevices Includes BluetoothScoCarkit
+				ForceUseForCommunication Is ForceBtSco
+
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 1
+					bluetooth_sco = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: BluetoothScoHeadset
+				#
+				# accessibility falls through Phone strategy if in call
+				#
+				ANY
+					TelephonyMode Is InCall
+					TelephonyMode Is InCommunication
+				AvailableOutputDevices Includes BluetoothScoHeadset
+				ForceUseForCommunication Is ForceBtSco
+
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 1
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: BluetoothSco
+				#
+				# accessibility falls through Phone strategy if in call
+				#
+				ANY
+					TelephonyMode Is InCall
+					TelephonyMode Is InCommunication
+				AvailableOutputDevices Includes BluetoothSco
+				ForceUseForCommunication Is ForceBtSco
+
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 1
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: WiredHeadphone
+				ANY
+					#
+					# accessibility falls through Phone strategy if in call
+					#
+					ALL
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						ForceUseForCommunication IsNot ForceSpeaker
+					#
+					# accessibility follows Media strategy if not in call
+					#
+					ALL
+						TelephonyMode IsNot InCall
+						TelephonyMode IsNot InCommunication
+				AvailableOutputDevices Includes WiredHeadphone
+
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 1
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: Line
+				ANY
+					#
+					# accessibility falls through Phone strategy if in call
+					# but Line has a lower priority than WiredHeadset in this case.
+					#
+					ALL
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						ForceUseForCommunication IsNot ForceSpeaker
+						AvailableOutputDevices Excludes WiredHeadset
+					#
+					# accessibility follows Media strategy if not in call
+					#
+				AvailableOutputDevices Includes Line
+
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 1
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: WiredHeadset
+				ANY
+					#
+					# accessibility falls through Phone strategy if in call
+					#
+					ALL
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						ForceUseForCommunication IsNot ForceSpeaker
+					#
+					# accessibility follows Media strategy if not in call
+					#
+					ALL
+						TelephonyMode IsNot InCall
+						TelephonyMode IsNot InCommunication
+				AvailableOutputDevices Includes WiredHeadset
+
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
+					speaker = 0
+					wired_headset = 1
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: UsbDevice
+				ANY
+					#
+					# accessibility falls through Phone strategy if in call (widely speaking)
+					#
+					ALL
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						ForceUseForCommunication IsNot ForceSpeaker
+					#
+					# accessibility follows Media strategy if not in call
+					# Media strategy inverts the priority of USB device vs accessory
+					#
+					ALL
+						TelephonyMode IsNot InCall
+						TelephonyMode IsNot InCommunication
+						AvailableOutputDevices Excludes UsbAccessory
+						ForceUseForMedia IsNot ForceSpeaker
+				AvailableOutputDevices Includes UsbDevice
+
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 1
+					hdmi = 0
+
+			conf: UsbAccessory
+				#
+				# accessibility falls through Phone strategy if in call (widely speaking)
+				# but USB accessory not reachable in call
+				#
+				# accessibility follows Media strategy if not in call
+				# Media strategy inverts the priority of USB device vs accessory
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				AvailableOutputDevices Includes UsbAccessory
+
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 1
+					usb_device = 0
+					hdmi = 0
+
+			conf: DgtlDockHeadset
+				#
+				# accessibility falls through Phone strategy if in call (widely speaking)
+				# but DgtlDockHeadset not reachable in call
+				#
+				# accessibility follows Media strategy if not in call
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				AvailableOutputDevices Includes DgtlDockHeadset
+
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 1
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: AuxDigital
+				#
+				# accessibility falls through Phone strategy if in call (widely speaking)
+				# but Hdmi not reachable in call
+				#
+				# accessibility follows Media strategy if not in call
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				AvailableOutputDevices Includes Hdmi
+
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 1
+
+			conf: AnlgDockHeadset
+				#
+				# accessibility falls through Phone strategy if in call (widely speaking)
+				# but AnlgDockHeadset not reachable in call
+				#
+				# accessibility follows Media strategy if not in call
+				# Media strategy inverts the priority of USB device vs accessory
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				AvailableOutputDevices Includes AnlgDockHeadset
+				ForceUseForDock Is ForceAnalogDock
+
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 1
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: Earpiece
+				#
+				# accessibility falls through Phone strategy if in call
+				#
+				ANY
+					TelephonyMode Is InCall
+					TelephonyMode Is InCommunication
+				AvailableOutputDevices Includes Earpiece
+				ForceUseForCommunication IsNot ForceSpeaker
+
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 1
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: Speaker
+				AvailableOutputDevices Includes Speaker
+
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
+					speaker = 1
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: Default
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_dtmf.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_dtmf.pfw
new file mode 100644
index 0000000..b8426c6
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_dtmf.pfw
@@ -0,0 +1,625 @@
+supDomain: DeviceForProductStrategies
+	supDomain: Dtmf
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
+					fm = 0
+					speaker_safe = 0
+					bluetooth_sco_carkit = 0
+					ip = 0
+					bus = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/dtmf/device_address =
+
+		domain: Device2
+			conf: RemoteSubmix
+				#
+				# DTMF follows Media strategy if not in call
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				AvailableOutputDevices Includes RemoteSubmix
+				AvailableOutputDevicesAddresses Includes 0
+
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
+					remote_submix = 1
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: BluetoothA2dp
+				#
+				# DTMF follows Media strategy if not in call
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				ForceUseForMedia IsNot ForceNoBtA2dp
+				AvailableOutputDevices Includes BluetoothA2dp
+
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_a2dp = 1
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: BluetoothA2dpHeadphones
+				#
+				# DTMF follows Media strategy if not in call
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				ForceUseForMedia IsNot ForceNoBtA2dp
+				AvailableOutputDevices Includes BluetoothA2dpHeadphones
+
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 1
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: BluetoothA2dpSpeaker
+				#
+				# DTMF follows Media strategy if not in call
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				ForceUseForMedia IsNot ForceNoBtA2dp
+				AvailableOutputDevices Includes BluetoothA2dpSpeaker
+
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 1
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: ForceSpeakerWhenNotInCall
+				#
+				# DTMF follows Media strategy if not in call
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				ForceUseForMedia Is ForceSpeaker
+				ForceUseForHdmiSystemAudio IsNot ForceHdmiSystemEnforced
+				AvailableOutputDevices Includes Speaker
+
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 1
+
+			conf: BluetoothScoHeadset
+				#
+				# DTMF falls through Phone strategy if in call
+				#
+				ANY
+					TelephonyMode Is InCall
+					TelephonyMode Is InCommunication
+				AvailableOutputDevices Includes BluetoothScoHeadset
+				ForceUseForCommunication Is ForceBtSco
+
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 1
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: BluetoothSco
+				#
+				# DTMF falls through Phone strategy if in call
+				#
+				ANY
+					TelephonyMode Is InCall
+					TelephonyMode Is InCommunication
+				AvailableOutputDevices Includes BluetoothSco
+				ForceUseForCommunication Is ForceBtSco
+
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 1
+					bluetooth_sco_headset = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: WiredHeadphone
+				ANY
+					#
+					# DTMF falls through Phone strategy if in call
+					#
+					ALL
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						ForceUseForCommunication IsNot ForceSpeaker
+					#
+					# DTMF follows Media strategy if not in call
+					#
+					ALL
+						TelephonyMode IsNot InCall
+						TelephonyMode IsNot InCommunication
+				AvailableOutputDevices Includes WiredHeadphone
+
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 1
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: Line
+				ANY
+					#
+					# DTMF falls through Phone strategy if in call
+					# but Line has a lower priority than WiredHeadset in this case.
+					#
+					ALL
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						ForceUseForCommunication IsNot ForceSpeaker
+						AvailableOutputDevices Excludes WiredHeadset
+					#
+					# DTMF follows Media strategy if not in call
+					#
+					ALL
+						TelephonyMode IsNot InCall
+						TelephonyMode IsNot InCommunication
+				AvailableOutputDevices Includes Line
+
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 1
+					speaker = 0
+
+			conf: WiredHeadset
+				ANY
+					#
+					# DTMF falls through Phone strategy if in call
+					#
+					ALL
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						ForceUseForCommunication IsNot ForceSpeaker
+					#
+					# DTMF follows Media strategy if not in call
+					#
+					ALL
+						TelephonyMode IsNot InCall
+						TelephonyMode IsNot InCommunication
+				AvailableOutputDevices Includes WiredHeadset
+
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 1
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: UsbDevice
+				ANY
+					#
+					# DTMF falls through Phone strategy if in call (widely speaking)
+					#
+					ALL
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						ForceUseForCommunication IsNot ForceSpeaker
+					#
+					# DTMF follows Media strategy if not in call
+					# Media strategy inverts the priority of USB device vs accessory
+					#
+					ALL
+						TelephonyMode IsNot InCall
+						TelephonyMode IsNot InCommunication
+						AvailableOutputDevices Excludes UsbAccessory
+						ForceUseForCommunication Is ForceSpeaker
+				AvailableOutputDevices Includes UsbDevice
+
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 1
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: UsbAccessory
+				#
+				# DTMF falls through Phone strategy if in call (widely speaking)
+				# but USB accessory not reachable in call
+				#
+				# DTMF follows Media strategy if not in call
+				# Media strategy inverts the priority of USB device vs accessory
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				AvailableOutputDevices Includes UsbAccessory
+
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 1
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: DgtlDockHeadset
+				#
+				# DTMF falls through Phone strategy if in call (widely speaking)
+				# but DgtlDockHeadset not reachable in call
+				#
+				# DTMF follows Media strategy if not in call
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				AvailableOutputDevices Includes DgtlDockHeadset
+
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 1
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: Hdmi
+				#
+				# DTMF falls through Phone strategy if in call (widely speaking)
+				# but Hdmi not reachable in call
+				#
+				# DTMF follows Media strategy if not in call
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				AvailableOutputDevices Includes Hdmi
+
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 1
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: AnlgDockHeadset
+				#
+				# DTMF falls through Phone strategy if in call (widely speaking)
+				# but AnlgDockHeadset not reachable in call
+				#
+				# DTMF follows Media strategy if not in call
+				# Media strategy inverts the priority of USB device vs accessory
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				ForceUseForDock Is ForceAnalogDock
+				AvailableOutputDevices Includes AnlgDockHeadset
+
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 1
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: Earpiece
+				#
+				# DTMF falls through Phone strategy if in call
+				#
+				ANY
+					TelephonyMode Is InCall
+					TelephonyMode Is InCommunication
+				AvailableOutputDevices Includes Earpiece
+				ForceUseForCommunication IsNot ForceSpeaker
+
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 1
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: Speaker
+				ANY
+					#
+					# DTMF falls through Phone strategy if in call
+					#
+					ALL
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						ForceUseForCommunication Is ForceSpeaker
+					#
+					# DTMF follows Media strategy if not in call
+					#
+					ALL
+						TelephonyMode IsNot InCall
+						TelephonyMode IsNot InCommunication
+						ForceUseForHdmiSystemAudio IsNot ForceHdmiSystemEnforced
+				AvailableOutputDevices Includes Speaker
+
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+		domain: Arc
+			#
+			# DTMF strategy follows media strategy if not in call
+			# these following domains consists in device(s) that can co-exist with others
+			# e.g. ARC, SPDIF, AUX_LINE
+			#
+			conf: Selected
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				AvailableOutputDevices Includes HdmiArc
+
+				/Policy/policy/product_strategies/dtmf/selected_output_devices/mask/hdmi_arc = 1
+
+			conf: NotSelected
+				/Policy/policy/product_strategies/dtmf/selected_output_devices/mask/hdmi_arc = 0
+
+		domain: Spdif
+			#
+			# DTMF strategy follows media strategy if not in call
+			# these following domains consists in device(s) that can co-exist with others
+			# e.g. ARC, SPDIF, AUX_LINE
+			#
+			conf: Selected
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				AvailableOutputDevices Includes Spdif
+
+				/Policy/policy/product_strategies/dtmf/selected_output_devices/mask/spdif = 1
+
+			conf: NotSelected
+				/Policy/policy/product_strategies/dtmf/selected_output_devices/mask/spdif = 0
+
+		domain: AuxLine
+			#
+			# DTMF strategy follows media strategy if not in call
+			# these following domains consists in device(s) that can co-exist with others
+			# e.g. ARC, SPDIF, AUX_LINE
+			#
+			conf: Selected
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				AvailableOutputDevices Includes AuxLine
+
+				/Policy/policy/product_strategies/dtmf/selected_output_devices/mask/aux_line = 1
+
+			conf: NotSelected
+				/Policy/policy/product_strategies/dtmf/selected_output_devices/mask/aux_line = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_enforced_audible.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_enforced_audible.pfw
new file mode 100644
index 0000000..2daa9ac
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_enforced_audible.pfw
@@ -0,0 +1,361 @@
+supDomain: DeviceForProductStrategy
+
+	supDomain: EnforcedAudible
+
+		domain: UnreachableDevices
+			conf: Calibration
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
+					# no enforced_audible on remote submix (e.g. WFD)
+					hdmi_arc = 0
+					spdif = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					bus = 0
+					fm = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+
+		domain: Speaker
+			conf: Selected
+				#
+				# strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
+				# except:
+				#    - when in call where it doesn't default to STRATEGY_PHONE behavior
+				#    - in countries where not enforced in which case it follows STRATEGY_MEDIA
+				#
+				AvailableOutputDevices Includes Speaker
+				ANY
+					ForceUseForSystem Is ForceSystemEnforced
+					ALL
+						ForceUseForMedia Is ForceSpeaker
+						AvailableOutputDevices Excludes RemoteSubmix
+						ANY
+							ForceUseForMedia IsNot ForceNoBtA2dp
+							AvailableOutputDevices Excludes BluetoothA2dp
+							AvailableOutputDevices Excludes BluetoothA2dpHeadphones
+							AvailableOutputDevices Excludes BluetoothA2dpSpeaker
+					#
+					# Speaker is also the fallback device if any of the device from Device2 domain
+					# is selected.
+					#
+					ALL
+						AvailableOutputDevices Excludes RemoteSubmix
+						AvailableOutputDevices Excludes WiredHeadphone
+						AvailableOutputDevices Excludes Line
+						AvailableOutputDevices Excludes WiredHeadset
+						AvailableOutputDevices Excludes UsbAccessory
+						AvailableOutputDevices Excludes UsbDevice
+						AvailableOutputDevices Excludes DgtlDockHeadset
+						AvailableOutputDevices Excludes Hdmi
+						ANY
+							AvailableOutputDevices Excludes AnlgDockHeadset
+							ForceUseForDock IsNot ForceAnalogDock
+
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
+					speaker = 1
+
+			conf: NotSelected
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
+					speaker = 0
+
+		domain: Device2
+			conf: RemoteSubmix
+				AvailableOutputDevices Includes RemoteSubmix
+				AvailableOutputDevicesAddresses Includes 0
+
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
+					remote_submix = 1
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+
+			conf: BluetoothA2dp
+				AvailableOutputDevices Includes BluetoothA2dp
+				ForceUseForMedia IsNot ForceNoBtA2dp
+
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 1
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+
+			conf: BluetoothA2dpHeadphones
+				AvailableOutputDevices Includes BluetoothA2dpHeadphones
+				ForceUseForMedia IsNot ForceNoBtA2dp
+
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 1
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+
+			conf: BluetoothA2dpSpeaker
+				AvailableOutputDevices Includes BluetoothA2dpSpeaker
+				ForceUseForMedia IsNot ForceNoBtA2dp
+
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 1
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+
+			conf: WiredHeadphone
+				ForceUseForMedia IsNot ForceSpeaker
+				AvailableOutputDevices Includes WiredHeadphone
+
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 1
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+
+			conf: Line
+				ForceUseForMedia IsNot ForceSpeaker
+				AvailableOutputDevices Includes Line
+
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 1
+
+			conf: WiredHeadset
+				ForceUseForMedia IsNot ForceSpeaker
+				AvailableOutputDevices Includes WiredHeadset
+
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 1
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+
+			conf: UsbAccessory
+				ForceUseForMedia IsNot ForceSpeaker
+				AvailableOutputDevices Includes UsbAccessory
+
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 1
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+
+			conf: UsbDevice
+				ForceUseForMedia IsNot ForceSpeaker
+				AvailableOutputDevices Includes UsbDevice
+
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 1
+					telephony_tx = 0
+					line = 0
+
+			conf: DgtlDockHeadset
+				ForceUseForMedia IsNot ForceSpeaker
+				AvailableOutputDevices Includes DgtlDockHeadset
+
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 1
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+
+			conf: Hdmi
+				ForceUseForMedia IsNot ForceSpeaker
+				AvailableOutputDevices Includes Hdmi
+
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 1
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+
+			conf: AnlgDockHeadset
+				ForceUseForMedia IsNot ForceSpeaker
+				ForceUseForDock Is ForceAnalogDock
+				AvailableOutputDevices Includes AnlgDockHeadset
+
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 1
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+
+			conf: NoDevice
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+
+
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_media.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_media.pfw
new file mode 100644
index 0000000..d6d355c
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_media.pfw
@@ -0,0 +1,340 @@
+supDomain: DeviceForProductStrategy
+	supDomain: Media
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
+					fm = 0
+					speaker_safe = 0
+					earpiece = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					telephony_tx = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					bus = 0
+					stub = 0
+				/Policy/policy/product_strategies/media/device_address =
+
+		domain: Device2
+			conf: RemoteSubmix
+				AvailableOutputDevices Includes RemoteSubmix
+				AvailableOutputDevicesAddresses Includes 0
+
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
+					speaker = 0
+					hdmi = 0
+					dgtl_dock_headset = 0
+					angl_dock_headset = 0
+					usb_device = 0
+					usb_accessory = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp = 0
+					remote_submix = 1
+					line = 0
+
+			conf: BluetoothA2dp
+				ForceUseForMedia IsNot ForceNoBtA2dp
+				ForceUseForCommunication IsNot ForceBtSco
+				AvailableOutputDevices Includes BluetoothA2dp
+
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
+					speaker = 0
+					hdmi = 0
+					dgtl_dock_headset = 0
+					angl_dock_headset = 0
+					usb_device = 0
+					usb_accessory = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp = 1
+					remote_submix = 0
+					line = 0
+
+			conf: BluetoothA2dpHeadphone
+				ForceUseForMedia IsNot ForceNoBtA2dp
+				ForceUseForCommunication IsNot ForceBtSco
+				AvailableOutputDevices Includes BluetoothA2dpHeadphones
+
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
+					speaker = 0
+					hdmi = 0
+					dgtl_dock_headset = 0
+					angl_dock_headset = 0
+					usb_device = 0
+					usb_accessory = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp_headphones = 1
+					bluetooth_a2dp = 0
+					remote_submix = 0
+					line = 0
+
+			conf: BluetoothA2dpSpeaker
+				ForceUseForMedia IsNot ForceNoBtA2dp
+				ForceUseForCommunication IsNot ForceBtSco
+				AvailableOutputDevices Includes BluetoothA2dpSpeaker
+
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
+					speaker = 0
+					hdmi = 0
+					dgtl_dock_headset = 0
+					angl_dock_headset = 0
+					usb_device = 0
+					usb_accessory = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_a2dp_speaker = 1
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp = 0
+					remote_submix = 0
+					line = 0
+
+			conf: ForceSpeaker
+				ForceUseForMedia Is ForceSpeaker
+				AvailableOutputDevices Includes Speaker
+				#
+				# If hdmi system audio mode is on, remove speaker out of output list.
+				#
+				ForceUseForHdmiSystemAudio IsNot ForceHdmiSystemEnforced
+
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
+					speaker = 1
+					hdmi = 0
+					dgtl_dock_headset = 0
+					angl_dock_headset = 0
+					usb_device = 0
+					usb_accessory = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp = 0
+					remote_submix = 0
+					line = 0
+
+			conf: WiredHeadphone
+				AvailableOutputDevices Includes WiredHeadphone
+
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
+					speaker = 0
+					hdmi = 0
+					dgtl_dock_headset = 0
+					angl_dock_headset = 0
+					usb_device = 0
+					usb_accessory = 0
+					wired_headset = 0
+					wired_headphone = 1
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp = 0
+					remote_submix = 0
+					line = 0
+
+			conf: Line
+				AvailableOutputDevices Includes Line
+
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
+					speaker = 0
+					hdmi = 0
+					dgtl_dock_headset = 0
+					angl_dock_headset = 0
+					usb_device = 0
+					usb_accessory = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp = 0
+					remote_submix = 0
+					line = 1
+
+			conf: WiredHeadset
+				AvailableOutputDevices Includes WiredHeadset
+
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
+					speaker = 0
+					hdmi = 0
+					dgtl_dock_headset = 0
+					angl_dock_headset = 0
+					usb_device = 0
+					usb_accessory = 0
+					wired_headset = 1
+					wired_headphone = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp = 0
+					remote_submix = 0
+					line = 0
+
+			conf: UsbAccessory
+				AvailableOutputDevices Includes UsbAccessory
+
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
+					speaker = 0
+					hdmi = 0
+					dgtl_dock_headset = 0
+					angl_dock_headset = 0
+					usb_device = 0
+					usb_accessory = 1
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp = 0
+					remote_submix = 0
+					line = 0
+
+			conf: UsbDevice
+				AvailableOutputDevices Includes UsbDevice
+
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
+					speaker = 0
+					hdmi = 0
+					dgtl_dock_headset = 0
+					angl_dock_headset = 0
+					usb_device = 1
+					usb_accessory = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp = 0
+					remote_submix = 0
+					line = 0
+
+			conf: DgtlDockHeadset
+				AvailableOutputDevices Includes DgtlDockHeadset
+
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
+					speaker = 0
+					hdmi = 0
+					dgtl_dock_headset = 1
+					angl_dock_headset = 0
+					usb_device = 0
+					usb_accessory = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp = 0
+					remote_submix = 0
+					line = 0
+
+			conf: AuxDigital
+				AvailableOutputDevices Includes Hdmi
+
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
+					speaker = 0
+					hdmi = 1
+					dgtl_dock_headset = 0
+					angl_dock_headset = 0
+					usb_device = 0
+					usb_accessory = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp = 0
+					remote_submix = 0
+					line = 0
+
+			conf: AnlgDockHeadset
+				AvailableOutputDevices Includes AnlgDockHeadset
+				ForceUseForDock Is ForceAnalogDock
+
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
+					speaker = 0
+					hdmi = 0
+					dgtl_dock_headset = 0
+					angl_dock_headset = 1
+					usb_device = 0
+					usb_accessory = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp = 0
+					remote_submix = 0
+					line = 0
+
+			conf: Speaker
+				AvailableOutputDevices Includes Speaker
+				#
+				# If hdmi system audio mode is on, remove speaker out of output list.
+				#
+				ForceUseForHdmiSystemAudio IsNot ForceHdmiSystemEnforced
+				ForceUseForCommunication IsNot ForceBtSco
+
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
+					speaker = 1
+					hdmi = 0
+					dgtl_dock_headset = 0
+					angl_dock_headset = 0
+					usb_device = 0
+					usb_accessory = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp = 0
+					remote_submix = 0
+					line = 0
+
+			conf: Default
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
+					speaker = 0
+					hdmi = 0
+					dgtl_dock_headset = 0
+					angl_dock_headset = 0
+					usb_device = 0
+					usb_accessory = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp = 0
+					remote_submix = 0
+					line = 0
+
+		domain: Arc
+			#
+			# these following domains consists in device(s) that can co-exist with others
+			# e.g. ARC, SPDIF, AUX_LINE
+			#
+			conf: Selected
+				AvailableOutputDevices Includes HdmiArc
+
+				/Policy/policy/product_strategies/media/selected_output_devices/mask/hdmi_arc = 1
+
+			conf: NotSelected
+				/Policy/policy/product_strategies/media/selected_output_devices/mask/hdmi_arc = 0
+
+		domain: Spdif
+			#
+			# these following domains consists in device(s) that can co-exist with others
+			# e.g. ARC, SPDIF, AUX_LINE
+			#
+			conf: Selected
+				AvailableOutputDevices Includes Spdif
+
+				/Policy/policy/product_strategies/media/selected_output_devices/mask/spdif = 1
+
+			conf: NotSelected
+				/Policy/policy/product_strategies/media/selected_output_devices/mask/spdif = 0
+
+		domain: AuxLine
+			conf: Selected
+				AvailableOutputDevices Includes AuxLine
+
+				/Policy/policy/product_strategies/media/selected_output_devices/mask/aux_line = 1
+
+			conf: NotSelected
+				/Policy/policy/product_strategies/media/selected_output_devices/mask/aux_line = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_patch.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_patch.pfw
new file mode 100644
index 0000000..d2cc090
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_patch.pfw
@@ -0,0 +1,36 @@
+supDomain: DeviceForProductStrategy
+	supDomain: Patch
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/patch/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					bus = 0
+					stub = 0
+				/Policy/policy/product_strategies/patch/device_address =
+
+
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_phone.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_phone.pfw
new file mode 100644
index 0000000..5693d4e
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_phone.pfw
@@ -0,0 +1,483 @@
+supDomain: DeviceForProductStrategy
+	supDomain: Phone
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
+					# no sonification on remote submix (e.g. WFD)
+					remote_submix = 0
+					hdmi_arc = 0
+					aux_line = 0
+					spdif = 0
+					fm = 0
+					speaker_safe = 0
+					bus = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/phone/device_address =
+
+		domain: Device
+			conf: ScoCarkit
+				AvailableOutputDevices Includes BluetoothScoCarkit
+				ForceUseForCommunication Is ForceBtSco
+
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 1
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: BluetoothScoHeadset
+				AvailableOutputDevices Includes BluetoothScoHeadset
+				ForceUseForCommunication Is ForceBtSco
+
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 1
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: BluetoothSco
+				AvailableOutputDevices Includes BluetoothSco
+				ForceUseForCommunication Is ForceBtSco
+
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 1
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: BluetoothA2dp
+				#
+				# Fallback BT Sco devices in case of FORCE_BT_SCO
+				# or FORCE_NONE
+				#
+				AvailableOutputDevices Includes BluetoothA2dp
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				ForceUseForMedia IsNot ForceNoBtA2dp
+				ForceUseForCommunication Is ForceNone
+
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 1
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: BluetoothA2dpHeadphones
+				#
+				# Fallback BT Sco devices in case of FORCE_BT_SCO
+				# or FORCE_NONE
+				#
+				AvailableOutputDevices Includes BluetoothA2dpHeadphones
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				ForceUseForMedia IsNot ForceNoBtA2dp
+				ForceUseForCommunication Is ForceNone
+
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 1
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: BluetoothA2dpSpeaker
+				#
+				# Fallback BT Sco devices in case of FORCE_BT_SCO
+				# or FORCE_NONE
+				#
+				AvailableOutputDevices Includes BluetoothA2dpSpeaker
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				ForceUseForMedia IsNot ForceNoBtA2dp
+				ForceUseForCommunication Is ForceSpeaker
+
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 1
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: WiredHeadphone
+				#
+				# Fallback BT Sco devices in case of FORCE_BT_SCO
+				# or FORCE_NONE
+				#
+				AvailableOutputDevices Includes WiredHeadphone
+				ForceUseForCommunication IsNot ForceSpeaker
+
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 1
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: WiredHeadset
+				#
+				# Fallback BT Sco devices in case of FORCE_BT_SCO
+				# or FORCE_NONE
+				#
+				AvailableOutputDevices Includes WiredHeadset
+				ForceUseForCommunication IsNot ForceSpeaker
+
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 1
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: Line
+				AvailableOutputDevices Includes Line
+				ForceUseForCommunication IsNot ForceSpeaker
+
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 1
+					speaker = 0
+
+			conf: UsbDevice
+				#
+				# Fallback BT Sco devices in case of FORCE_BT_SCO
+				# or FORCE_NONE
+				#
+				AvailableOutputDevices Includes UsbDevice
+				ANY
+					ForceUseForCommunication Is ForceBtSco
+					ForceUseForCommunication Is ForceNone
+					ALL
+						ForceUseForCommunication Is ForceSpeaker
+						#
+						# In case of Force Speaker, priority between device and accessory are
+						# inverted compared to Force None or Bt Sco
+						#
+						AvailableOutputDevices Excludes UsbAccessory
+						TelephonyMode IsNot InCall
+						TelephonyMode IsNot InCommunication
+
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 1
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: UsbAccessory
+				#
+				# Fallback BT Sco devices in case of FORCE_BT_SCO
+				# or FORCE_NONE
+				#
+				AvailableOutputDevices Includes UsbAccessory
+				TelephonyMode IsNot InCommunication
+				TelephonyMode IsNot InCall
+
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 1
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: DgtlDockHeadset
+				#
+				# Fallback BT Sco devices in case of FORCE_BT_SCO
+				# or FORCE_NONE
+				#
+				AvailableOutputDevices Includes DgtlDockHeadset
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 1
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: Hdmi
+				#
+				# Fallback BT Sco devices in case of FORCE_BT_SCO
+				# or FORCE_NONE
+				#
+				AvailableOutputDevices Includes Hdmi
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 1
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: AnlgDockHeadset
+				#
+				# Fallback BT Sco devices in case of FORCE_BT_SCO
+				# or FORCE_NONE
+				#
+				AvailableOutputDevices Includes AnlgDockHeadset
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 1
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: Earpiece
+				#
+				# Fallback BT Sco devices in case of FORCE_BT_SCO
+				# or FORCE_NONE
+				#
+				AvailableOutputDevices Includes Earpiece
+				ForceUseForCommunication IsNot ForceSpeaker
+
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
+					earpiece = 1
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 0
+
+			conf: Speaker
+				#
+				# Fallback BT Sco devices in case of FORCE_BT_SCO
+				# or FORCE_NONE
+				#
+				AvailableOutputDevices Includes Speaker
+				ForceUseForCommunication Is ForceSpeaker
+
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 1
+
+			conf: Default
+				#
+				# Fallback on default output device which can be speaker for example
+				#
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					speaker = 1
+
+
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_rerouting.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_rerouting.pfw
new file mode 100644
index 0000000..10f8814
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_rerouting.pfw
@@ -0,0 +1,36 @@
+supDomain: DeviceForProductStrategy
+	supDomain: Rerouting
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/rerouting/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					bus = 0
+					stub = 0
+				/Policy/policy/product_strategies/rerouting/device_address =
+
+
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_sonification.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_sonification.pfw
new file mode 100644
index 0000000..c4edeeb
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_sonification.pfw
@@ -0,0 +1,490 @@
+supDomain: DeviceForProductStrategy
+	supDomain: Sonification
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
+					remote_submix = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					speaker_safe = 0
+					aux_line = 0
+					#
+					# Sonification follows phone strategy if in call but HDMI is not reachable
+					#
+					hdmi = 0
+					bus = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/sonification/device_address =
+
+		domain: Speaker
+
+			conf: Selected
+				AvailableOutputDevices Includes Speaker
+				ANY
+					#
+					# Sonification falls through ENFORCED_AUDIBLE if not in call (widely speaking)
+					#
+					ALL
+						TelephonyMode IsNot InCall
+						TelephonyMode IsNot InCommunication
+					ALL
+						#
+						# Sonification follows phone strategy if in call (widely speaking)
+						#
+						ForceUseForCommunication Is ForceSpeaker
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						AvailableOutputDevices Excludes Line
+
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
+					speaker = 1
+
+			conf: NotSelected
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
+					speaker = 0
+
+		domain: Device2
+
+			conf: BluetoothA2dp
+				#
+				# Sonification falls through media strategy if not in call (widely speaking)
+				#
+				AvailableOutputDevices Includes BluetoothA2dp
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				ForceUseForMedia IsNot ForceNoBtA2dp
+
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 1
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+
+			conf: BluetoothA2dpHeadphones
+				#
+				# Sonification falls through media strategy if not in call (widely speaking)
+				#
+				AvailableOutputDevices Includes BluetoothA2dpHeadphones
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				ForceUseForMedia IsNot ForceNoBtA2dp
+
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 1
+					bluetooth_a2dp_speaker = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+
+			conf: BluetoothA2dpSpeaker
+				#
+				# Sonification falls through media strategy if not in call (widely speaking)
+				#
+				AvailableOutputDevices Includes BluetoothA2dpSpeaker
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				ForceUseForMedia IsNot ForceNoBtA2dp
+
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 1
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+
+			conf: ScoCarkit
+				#
+				# Sonification follows phone strategy if in call (widely speaking)
+				#
+				ANY
+					TelephonyMode Is InCall
+					TelephonyMode Is InCommunication
+				ForceUseForCommunication Is ForceBtSco
+				AvailableOutputDevices Includes BluetoothScoCarkit
+
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 1
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+
+			conf: ScoHeadset
+				#
+				# Sonification follows phone strategy if in call (widely speaking)
+				#
+				ANY
+					TelephonyMode Is InCall
+					TelephonyMode Is InCommunication
+				ForceUseForCommunication Is ForceBtSco
+				AvailableOutputDevices Includes BluetoothScoHeadset
+
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 1
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+
+			conf: Sco
+				#
+				# Sonification follows phone strategy if in call (widely speaking)
+				#
+				ANY
+					TelephonyMode Is InCall
+					TelephonyMode Is InCommunication
+				ForceUseForCommunication Is ForceBtSco
+				AvailableOutputDevices Includes BluetoothSco
+
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 1
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+
+			conf: WiredHeadphone
+				AvailableOutputDevices Includes WiredHeadphone
+				ANY
+					#
+					# Sonification falls through media strategy if not in call (widely speaking)
+					#
+					ALL
+						TelephonyMode IsNot InCall
+						TelephonyMode IsNot InCommunication
+						ForceUseForMedia IsNot ForceSpeaker
+					#
+					# Sonification follows Phone strategy if in call (widely speaking)
+					#
+					ALL
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						ForceUseForCommunication IsNot ForceSpeaker
+
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 1
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+
+			conf: Line
+				AvailableOutputDevices Includes Line
+				ANY
+					#
+					# Sonification follows Phone strategy if in call (widely speaking)
+					# but Line has a lower priority than WiredHeadset in this case.
+					#
+					ALL
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						ForceUseForCommunication IsNot ForceSpeaker
+						AvailableOutputDevices Excludes WiredHeadset
+					#
+					# Sonification falls through media strategy if not in call (widely speaking)
+					#
+					ALL
+						TelephonyMode IsNot InCall
+						TelephonyMode IsNot InCommunication
+						ForceUseForMedia IsNot ForceSpeaker
+
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 1
+
+			conf: WiredHeadset
+				AvailableOutputDevices Includes WiredHeadset
+				ANY
+					#
+					# Sonification falls through media strategy if not in call (widely speaking)
+					#
+					ALL
+						TelephonyMode IsNot InCall
+						TelephonyMode IsNot InCommunication
+						ForceUseForMedia IsNot ForceSpeaker
+					ALL
+						#
+						# Sonification Follows Phone Strategy if in call (widely speaking)
+						#
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						ForceUseForCommunication IsNot ForceSpeaker
+
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 1
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+
+			conf: UsbDevice
+				AvailableOutputDevices Includes UsbDevice
+				ANY
+					#
+					# Sonification falls through media strategy if not in call (widely speaking)
+					#
+					ALL
+						AvailableOutputDevices Excludes UsbAccessory
+						TelephonyMode IsNot InCall
+						TelephonyMode IsNot InCommunication
+						ForceUseForMedia IsNot ForceSpeaker
+					ALL
+						#
+						# Sonification Follows Phone Strategy if in call (widely speaking)
+						#
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						ForceUseForCommunication IsNot ForceSpeaker
+
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 1
+					telephony_tx = 0
+					line = 0
+
+			conf: UsbAccessory
+				AvailableOutputDevices Includes UsbAccessory
+				#
+				# Sonification falls through media strategy if not in call (widely speaking)
+				#
+				# Sonification Follows Phone Strategy if in call (widely speaking)
+				# but USB Accessory not reachable in call.
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				ForceUseForMedia IsNot ForceSpeaker
+
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 1
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+
+			conf: DgtlDockHeadset
+				AvailableOutputDevices Includes DgtlDockHeadset
+				#
+				# Sonification falls through media strategy if not in call
+				#
+				# Sonification Follows Phone Strategy if in call (widely speaking)
+				# but DgtlDockHeadset not reachable in call.
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				ForceUseForMedia IsNot ForceSpeaker
+
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 1
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+
+			conf: AnlgDockHeadset
+				AvailableOutputDevices Includes AnlgDockHeadset
+				#
+				# Sonification falls through media strategy if not in call
+				#
+				# Sonification Follows Phone Strategy if in call (widely speaking)
+				# but AnlgDockHeadset not reachable in call.
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				ForceUseForMedia IsNot ForceSpeaker
+				ForceUseForDock Is ForceAnalogDock
+
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					angl_dock_headset = 1
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+
+			conf: Earpiece
+				#
+				# Sonification Follows Phone Strategy if in call
+				#
+				ANY
+					TelephonyMode Is InCall
+					TelephonyMode Is InCommunication
+				ForceUseForCommunication IsNot ForceSpeaker
+				AvailableOutputDevices Includes Earpiece
+
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
+					earpiece = 1
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+
+			conf: None
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_sonification_respectful.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_sonification_respectful.pfw
new file mode 100644
index 0000000..0a3dd5f
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_sonification_respectful.pfw
@@ -0,0 +1,536 @@
+supDomain: DeviceForProductStrategy
+	supDomain: SonificationRespectful
+		#
+		# Sonificiation Respectful follows:
+		#	- If in call: Strategy sonification (that follows phone strategy in call also...)
+		#	- If not in call AND a music stream is active remotely: Strategy sonification (that
+		#     follows enforced audible, which follows media)
+		#	- if not in call and no music stream active remotely and music stream active): strategy
+		#     media
+		#   - Otherwise follows sonification by replacing speaker with speaker safe if speaker is
+		#	  selected.
+		#
+		# Case of stream active handled programmatically
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
+					remote_submix = 0
+					hdmi_arc = 0
+					aux_line = 0
+					spdif = 0
+					fm = 0
+					telephony_tx = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/sonification_respectful/device_address =
+
+		domain: Speakers
+
+			conf: SpeakerSafe
+				AvailableOutputDevices Includes Speaker
+				AvailableOutputDevices Includes SpeakerSafe
+				#
+				# Follows sonification strategy if not in call and replace speaker by speaker safe
+				# if and only if speaker only selected
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
+					speaker_safe = 1
+					speaker = 0
+
+			conf: Speaker
+				AvailableOutputDevices Includes Speaker
+				ANY
+					#
+					# Follows sonification strategy if not in call
+					#
+					ALL
+						TelephonyMode IsNot InCall
+						TelephonyMode IsNot InCommunication
+					ALL
+						#
+						# Follows Phone Strategy if call
+						#
+						ForceUseForCommunication Is ForceSpeaker
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						AvailableOutputDevices Excludes Line
+
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
+					speaker_safe = 0
+					speaker = 1
+
+			conf: None
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
+					speaker_safe = 0
+					speaker = 0
+
+		domain: Device2
+			conf: BluetoothA2dp
+				#
+				# SonificationRespectful Follows Sonification that falls through Media strategy if not in call
+				# SonificationRespectful follows media if music stream is active
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				ForceUseForMedia IsNot ForceNoBtA2dp
+				AvailableOutputDevices Includes BluetoothA2dp
+
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
+					earpiece = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp = 1
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: BluetoothA2dpHeadphones
+				#
+				# SonificationRespectful Follows Sonification that falls through Media strategy if not in call
+				# SonificationRespectful follows media if music stream is active
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				ForceUseForMedia IsNot ForceNoBtA2dp
+				AvailableOutputDevices Includes BluetoothA2dpHeadphones
+
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
+					earpiece = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp_headphones = 1
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: BluetoothA2dpSpeaker
+				#
+				# SonificationRespectful Follows Sonification that falls through Media strategy if not in call
+				# SonificationRespectful follows media if music stream is active
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				ForceUseForMedia IsNot ForceNoBtA2dp
+				AvailableOutputDevices Includes BluetoothA2dpSpeaker
+
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
+					earpiece = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 1
+					bluetooth_a2dp = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: BluetoothScoCarkit
+				#
+				# SonificationRespectful Follows Phone strategy if in call
+				#
+				ANY
+					TelephonyMode Is InCall
+					TelephonyMode Is InCommunication
+				ForceUseForCommunication Is ForceBtSco
+				AvailableOutputDevices Includes BluetoothScoCarkit
+
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
+					earpiece = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 1
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: BluetoothScoHeadset
+				#
+				# SonificationRespectful Follows Phone strategy if in call
+				#
+				ANY
+					TelephonyMode Is InCall
+					TelephonyMode Is InCommunication
+				ForceUseForCommunication Is ForceBtSco
+				AvailableOutputDevices Includes BluetoothScoHeadset
+
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
+					earpiece = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 1
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: BluetoothSco
+				#
+				# SonificationRespectful Follows Phone strategy if in call
+				#
+				ANY
+					TelephonyMode Is InCall
+					TelephonyMode Is InCommunication
+				ForceUseForCommunication Is ForceBtSco
+				AvailableOutputDevices Includes BluetoothSco
+
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
+					earpiece = 0
+					bluetooth_sco = 1
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: WiredHeadphone
+				ANY
+					ALL
+						#
+						# SonificationRespectful Follows Phone strategy if in call
+						#
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						ForceUseForCommunication IsNot ForceSpeaker
+					ALL
+						#
+						# SonificationRespectful Follows Sonification that falls through Media strategy if not in call
+						# SonificationRespectful follows media if music stream is active
+						#
+						TelephonyMode IsNot InCall
+						TelephonyMode IsNot InCommunication
+						ForceUseForMedia IsNot ForceSpeaker
+				AvailableOutputDevices Includes WiredHeadphone
+
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
+					earpiece = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp = 0
+					wired_headset = 0
+					wired_headphone = 1
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: Line
+				ANY
+					#
+					# SonificationRespectful Follows Phone strategy if in call
+					# but Line has a lower priority than WiredHeadset in this case.
+					#
+					#
+					ALL
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						ForceUseForCommunication IsNot ForceSpeaker
+						AvailableOutputDevices Excludes WiredHeadset
+					#
+					# SonificationRespectful Follows Sonification that falls through Media strategy if not in call
+					# SonificationRespectful follows media if music stream is active
+					#
+					ALL
+						TelephonyMode IsNot InCall
+						TelephonyMode IsNot InCommunication
+						AvailableOutputDevices Includes WiredHeadphone
+						ForceUseForMedia IsNot ForceSpeaker
+				AvailableOutputDevices Includes Line
+
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
+					earpiece = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 1
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: WiredHeadset
+				ANY
+					ALL
+						#
+						# SonificationRespectful Follows Phone strategy if in call
+						#
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						ForceUseForCommunication IsNot ForceSpeaker
+					ALL
+						#
+						# SonificationRespectful Follows Sonification that falls through Media strategy if not in call
+						# SonificationRespectful follows media if music stream is active
+						#
+						TelephonyMode IsNot InCall
+						TelephonyMode IsNot InCommunication
+						ForceUseForMedia IsNot ForceSpeaker
+				AvailableOutputDevices Includes WiredHeadset
+
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
+					earpiece = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp = 0
+					wired_headset = 1
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: UsbDevice
+				ANY
+					ALL
+						#
+						# SonificationRespectful Follows Phone strategy if in call
+						#
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						ForceUseForCommunication IsNot ForceSpeaker
+					ALL
+						#
+						# SonificationRespectful Follows Sonification that falls through Media strategy if not in call
+						# SonificationRespectful follows media if music stream is active
+						#
+						TelephonyMode IsNot InCall
+						TelephonyMode IsNot InCommunication
+						ForceUseForMedia IsNot ForceSpeaker
+						AvailableOutputDevices Excludes UsbAccessory
+				AvailableOutputDevices Includes UsbDevice
+
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
+					earpiece = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 1
+					hdmi = 0
+
+			conf: UsbAccessory
+				#
+				# SonificationRespectful Follows Phone strategy if in call (widely speaking)
+				# but UsbAccessory not reachable in call.
+				#
+				# SonificationRespectful Follows Sonification that falls through Media strategy if not in call
+				# SonificationRespectful follows media if music stream is active
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				ForceUseForMedia IsNot ForceSpeaker
+				AvailableOutputDevices Includes UsbAccessory
+
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
+					earpiece = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 1
+					usb_device = 0
+					hdmi = 0
+
+			conf: DgtlDockHeadset
+				#
+				# SonificationRespectful Follows Phone strategy if in call (widely speaking)
+				# but DgtlDockHeadset not reachable in call.
+				#
+				# SonificationRespectful Follows Sonification that falls through Media strategy if not in call
+				# SonificationRespectful follows media if music stream is active
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				ForceUseForMedia IsNot ForceSpeaker
+				AvailableOutputDevices Includes DgtlDockHeadset
+
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
+					earpiece = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 1
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: AuxDigital
+				#
+				# SonificationRespectful Follows Phone strategy if in call (widely speaking)
+				# but HDMI not reachable in call.
+				#
+				# SonificationRespectful Follows Sonification that falls through Media strategy if not in call
+				# SonificationRespectful follows media if music stream is active
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				ForceUseForMedia IsNot ForceSpeaker
+				AvailableOutputDevices Includes Hdmi
+
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
+					earpiece = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 1
+
+			conf: AnlgDockHeadset
+				#
+				# SonificationRespectful Follows Phone strategy if in call (widely speaking)
+				# but AnlgDockHeadset not reachable in call.
+				#
+				# SonificationRespectful Follows Sonification that falls through Media strategy if not in call
+				# SonificationRespectful follows media if music stream is active
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				ForceUseForMedia IsNot ForceSpeaker
+				ForceUseForDock Is ForceAnalogDock
+				AvailableOutputDevices Includes AnlgDockHeadset
+
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
+					earpiece = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 1
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: Earpiece
+				#
+				# SonificationRespectful Follows Phone strategy if in call
+				#
+				ANY
+					TelephonyMode Is InCall
+					TelephonyMode Is InCommunication
+				ForceUseForCommunication IsNot ForceSpeaker
+				AvailableOutputDevices Includes Earpiece
+
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
+					earpiece = 1
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_a2dp = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_transmitted_through_speaker.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_transmitted_through_speaker.pfw
new file mode 100644
index 0000000..3fc7670
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_transmitted_through_speaker.pfw
@@ -0,0 +1,43 @@
+supDomain: DeviceForProductStrategy
+	supDomain: TransmittedThroughSpeaker
+		domain: UnreacheableDevices
+			conf: Calibration
+				component: /Policy/policy/product_strategies/transmitted_through_speaker/selected_output_devices/mask
+					remote_submix = 0
+					hdmi_arc = 0
+					spdif = 0
+					aux_line = 0
+					fm = 0
+					speaker_safe = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+					ip = 0
+					bus = 0
+					stub = 0
+				/Policy/policy/product_strategies/transmitted_through_speaker/device_address =
+
+		domain: Speaker
+			conf: Selected
+				AvailableOutputDevices Includes Speaker
+
+				component: /Policy/policy/product_strategies/transmitted_through_speaker/selected_output_devices/mask
+					speaker = 1
+
+			conf: NotSelected
+				component: /Policy/policy/product_strategies/transmitted_through_speaker/selected_output_devices/mask
+					speaker = 0
+
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/PolicyConfigurableDomains.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/PolicyConfigurableDomains.xml
index b43f83b..0710441 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/PolicyConfigurableDomains.xml
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/PolicyConfigurableDomains.xml
@@ -8472,7 +8472,7 @@
     <Configurations>
       <Configuration Name="Sonification">
         <CompoundRule Type="All">
-          <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="RingTone"/>
+          <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="Ringtone"/>
         </CompoundRule>
       </Configuration>
       <Configuration Name="Phone">
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_accessibility.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_accessibility.pfw
deleted file mode 100644
index eb11980..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_accessibility.pfw
+++ /dev/null
@@ -1,593 +0,0 @@
-supDomain: DeviceForStrategy
-
-	supDomain: Accessibility
-		#
-		# STRATEGY_ACCESSIBILITY follows STRATEGY_PHONE if in call widely speaking
-		# STRATEGY_ACCESSIBILITY follows STRATEGY_MEDIA otherwise
-		#
-		# Other case are handled programmatically has involving activity of streams.
-		#
-		domain: UnreachableDevices
-			conf: Calibration
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
-					hdmi_arc = 0
-					spdif = 0
-					aux_line = 0
-					fm = 0
-					speaker_safe = 0
-					telephony_tx = 0
-					ip = 0
-					bus = 0
-					stub = 0
-
-		domain: Device
-			conf: RemoteSubmix
-				#
-				# Accessibility follows Media strategy if not in call
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				AvailableOutputDevices Includes RemoteSubmix
-
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
-					remote_submix = 1
-					earpiece = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_sco = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: BluetoothA2dp
-				#
-				# Accessibility falls through media strategy if not in call (widely speaking)
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				ForceUseForMedia IsNot ForceNoBtA2dp
-				AvailableOutputDevices Includes BluetoothA2dp
-
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					bluetooth_a2dp = 1
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_sco = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: BluetoothA2dpHeadphone
-				#
-				# Accessibility falls through media strategy if not in call (widely speaking)
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				ForceUseForMedia IsNot ForceNoBtA2dp
-				AvailableOutputDevices Includes BluetoothA2dpHeadphones
-
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 1
-					bluetooth_a2dp_speaker = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_sco = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: BluetoothA2dpSpeaker
-				#
-				# Accessibility falls through media strategy if not in call (widely speaking)
-				#
-				ForceUseForMedia IsNot ForceNoBtA2dp
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				AvailableOutputDevices Includes BluetoothA2dpSpeaker
-
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 1
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_sco = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: ForceSpeakerWhenNotInCall
-				#
-				# Accessibility follows Media strategy if not in call
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				ForceUseForMedia Is ForceSpeaker
-				AvailableOutputDevices Includes Speaker
-
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_sco = 0
-					speaker = 1
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: BluetoothScoCarkit
-				#
-				# accessibility falls through Phone strategy if in call
-				#
-				ANY
-					TelephonyMode Is InCall
-					TelephonyMode Is InCommunication
-				AvailableOutputDevices Includes BluetoothScoCarkit
-				ForceUseForCommunication Is ForceBtSco
-
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 1
-					bluetooth_sco = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: BluetoothScoHeadset
-				#
-				# accessibility falls through Phone strategy if in call
-				#
-				ANY
-					TelephonyMode Is InCall
-					TelephonyMode Is InCommunication
-				AvailableOutputDevices Includes BluetoothScoHeadset
-				ForceUseForCommunication Is ForceBtSco
-
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_sco_headset = 1
-					bluetooth_sco_carkit = 0
-					bluetooth_sco = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: BluetoothSco
-				#
-				# accessibility falls through Phone strategy if in call
-				#
-				ANY
-					TelephonyMode Is InCall
-					TelephonyMode Is InCommunication
-				AvailableOutputDevices Includes BluetoothSco
-				ForceUseForCommunication Is ForceBtSco
-
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_sco = 1
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: WiredHeadphone
-				ANY
-					#
-					# accessibility falls through Phone strategy if in call
-					#
-					ALL
-						ANY
-							TelephonyMode Is InCall
-							TelephonyMode Is InCommunication
-						ForceUseForCommunication IsNot ForceSpeaker
-					#
-					# accessibility follows Media strategy if not in call
-					#
-					ALL
-						TelephonyMode IsNot InCall
-						TelephonyMode IsNot InCommunication
-				AvailableOutputDevices Includes WiredHeadphone
-
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_sco = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 1
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: Line
-				ANY
-					#
-					# accessibility falls through Phone strategy if in call
-					# but Line has a lower priority than WiredHeadset in this case.
-					#
-					ALL
-						ANY
-							TelephonyMode Is InCall
-							TelephonyMode Is InCommunication
-						ForceUseForCommunication IsNot ForceSpeaker
-						AvailableOutputDevices Excludes WiredHeadset
-					#
-					# accessibility follows Media strategy if not in call
-					#
-				AvailableOutputDevices Includes Line
-
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_sco = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 1
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: WiredHeadset
-				ANY
-					#
-					# accessibility falls through Phone strategy if in call
-					#
-					ALL
-						ANY
-							TelephonyMode Is InCall
-							TelephonyMode Is InCommunication
-						ForceUseForCommunication IsNot ForceSpeaker
-					#
-					# accessibility follows Media strategy if not in call
-					#
-					ALL
-						TelephonyMode IsNot InCall
-						TelephonyMode IsNot InCommunication
-				AvailableOutputDevices Includes WiredHeadset
-
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_sco = 0
-					speaker = 0
-					wired_headset = 1
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: UsbDevice
-				ANY
-					#
-					# accessibility falls through Phone strategy if in call (widely speaking)
-					#
-					ALL
-						ANY
-							TelephonyMode Is InCall
-							TelephonyMode Is InCommunication
-						ForceUseForCommunication IsNot ForceSpeaker
-					#
-					# accessibility follows Media strategy if not in call
-					# Media strategy inverts the priority of USB device vs accessory
-					#
-					ALL
-						TelephonyMode IsNot InCall
-						TelephonyMode IsNot InCommunication
-						AvailableOutputDevices Excludes UsbAccessory
-						ForceUseForMedia IsNot ForceSpeaker
-				AvailableOutputDevices Includes UsbDevice
-
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_sco = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 1
-					hdmi = 0
-
-			conf: UsbAccessory
-				#
-				# accessibility falls through Phone strategy if in call (widely speaking)
-				# but USB accessory not reachable in call
-				#
-				# accessibility follows Media strategy if not in call
-				# Media strategy inverts the priority of USB device vs accessory
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				AvailableOutputDevices Includes UsbAccessory
-
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_sco = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 1
-					usb_device = 0
-					hdmi = 0
-
-			conf: DgtlDockHeadset
-				#
-				# accessibility falls through Phone strategy if in call (widely speaking)
-				# but DgtlDockHeadset not reachable in call
-				#
-				# accessibility follows Media strategy if not in call
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				AvailableOutputDevices Includes DgtlDockHeadset
-
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_sco = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 1
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: AuxDigital
-				#
-				# accessibility falls through Phone strategy if in call (widely speaking)
-				# but Hdmi not reachable in call
-				#
-				# accessibility follows Media strategy if not in call
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				AvailableOutputDevices Includes Hdmi
-
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_sco = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 1
-
-			conf: AnlgDockHeadset
-				#
-				# accessibility falls through Phone strategy if in call (widely speaking)
-				# but AnlgDockHeadset not reachable in call
-				#
-				# accessibility follows Media strategy if not in call
-				# Media strategy inverts the priority of USB device vs accessory
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				AvailableOutputDevices Includes AnlgDockHeadset
-				ForceUseForDock Is ForceAnalogDock
-
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_sco = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 1
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: Earpiece
-				#
-				# accessibility falls through Phone strategy if in call
-				#
-				ANY
-					TelephonyMode Is InCall
-					TelephonyMode Is InCommunication
-				AvailableOutputDevices Includes Earpiece
-				ForceUseForCommunication IsNot ForceSpeaker
-
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 1
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_sco = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: Speaker
-				AvailableOutputDevices Includes Speaker
-
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_sco = 0
-					speaker = 1
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: Default
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_sco = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_dtmf.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_dtmf.pfw
deleted file mode 100644
index 883c741..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_dtmf.pfw
+++ /dev/null
@@ -1,623 +0,0 @@
-supDomain: DeviceForStrategy
-
-	supDomain: Dtmf
-
-		domain: UnreachableDevices
-			conf: Calibration
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
-					fm = 0
-					speaker_safe = 0
-					bluetooth_sco_carkit = 0
-					ip = 0
-					bus = 0
-					stub = 0
-
-		domain: Device2
-			conf: RemoteSubmix
-				#
-				# DTMF follows Media strategy if not in call
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				AvailableOutputDevices Includes RemoteSubmix
-
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
-					remote_submix = 1
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: BluetoothA2dp
-				#
-				# DTMF follows Media strategy if not in call
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				ForceUseForMedia IsNot ForceNoBtA2dp
-				AvailableOutputDevices Includes BluetoothA2dp
-
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_a2dp = 1
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: BluetoothA2dpHeadphones
-				#
-				# DTMF follows Media strategy if not in call
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				ForceUseForMedia IsNot ForceNoBtA2dp
-				AvailableOutputDevices Includes BluetoothA2dpHeadphones
-
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 1
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: BluetoothA2dpSpeaker
-				#
-				# DTMF follows Media strategy if not in call
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				ForceUseForMedia IsNot ForceNoBtA2dp
-				AvailableOutputDevices Includes BluetoothA2dpSpeaker
-
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 1
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: ForceSpeakerWhenNotInCall
-				#
-				# DTMF follows Media strategy if not in call
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				ForceUseForMedia Is ForceSpeaker
-				ForceUseForHdmiSystemAudio IsNot ForceHdmiSystemEnforced
-				AvailableOutputDevices Includes Speaker
-
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 1
-
-			conf: BluetoothScoHeadset
-				#
-				# DTMF falls through Phone strategy if in call
-				#
-				ANY
-					TelephonyMode Is InCall
-					TelephonyMode Is InCommunication
-				AvailableOutputDevices Includes BluetoothScoHeadset
-				ForceUseForCommunication Is ForceBtSco
-
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 1
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: BluetoothSco
-				#
-				# DTMF falls through Phone strategy if in call
-				#
-				ANY
-					TelephonyMode Is InCall
-					TelephonyMode Is InCommunication
-				AvailableOutputDevices Includes BluetoothSco
-				ForceUseForCommunication Is ForceBtSco
-
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 1
-					bluetooth_sco_headset = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: WiredHeadphone
-				ANY
-					#
-					# DTMF falls through Phone strategy if in call
-					#
-					ALL
-						ANY
-							TelephonyMode Is InCall
-							TelephonyMode Is InCommunication
-						ForceUseForCommunication IsNot ForceSpeaker
-					#
-					# DTMF follows Media strategy if not in call
-					#
-					ALL
-						TelephonyMode IsNot InCall
-						TelephonyMode IsNot InCommunication
-				AvailableOutputDevices Includes WiredHeadphone
-
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 1
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: Line
-				ANY
-					#
-					# DTMF falls through Phone strategy if in call
-					# but Line has a lower priority than WiredHeadset in this case.
-					#
-					ALL
-						ANY
-							TelephonyMode Is InCall
-							TelephonyMode Is InCommunication
-						ForceUseForCommunication IsNot ForceSpeaker
-						AvailableOutputDevices Excludes WiredHeadset
-					#
-					# DTMF follows Media strategy if not in call
-					#
-					ALL
-						TelephonyMode IsNot InCall
-						TelephonyMode IsNot InCommunication
-				AvailableOutputDevices Includes Line
-
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 1
-					speaker = 0
-
-			conf: WiredHeadset
-				ANY
-					#
-					# DTMF falls through Phone strategy if in call
-					#
-					ALL
-						ANY
-							TelephonyMode Is InCall
-							TelephonyMode Is InCommunication
-						ForceUseForCommunication IsNot ForceSpeaker
-					#
-					# DTMF follows Media strategy if not in call
-					#
-					ALL
-						TelephonyMode IsNot InCall
-						TelephonyMode IsNot InCommunication
-				AvailableOutputDevices Includes WiredHeadset
-
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 1
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: UsbDevice
-				ANY
-					#
-					# DTMF falls through Phone strategy if in call (widely speaking)
-					#
-					ALL
-						ANY
-							TelephonyMode Is InCall
-							TelephonyMode Is InCommunication
-						ForceUseForCommunication IsNot ForceSpeaker
-					#
-					# DTMF follows Media strategy if not in call
-					# Media strategy inverts the priority of USB device vs accessory
-					#
-					ALL
-						TelephonyMode IsNot InCall
-						TelephonyMode IsNot InCommunication
-						AvailableOutputDevices Excludes UsbAccessory
-						ForceUseForCommunication Is ForceSpeaker
-				AvailableOutputDevices Includes UsbDevice
-
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 1
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: UsbAccessory
-				#
-				# DTMF falls through Phone strategy if in call (widely speaking)
-				# but USB accessory not reachable in call
-				#
-				# DTMF follows Media strategy if not in call
-				# Media strategy inverts the priority of USB device vs accessory
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				AvailableOutputDevices Includes UsbAccessory
-
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 1
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: DgtlDockHeadset
-				#
-				# DTMF falls through Phone strategy if in call (widely speaking)
-				# but DgtlDockHeadset not reachable in call
-				#
-				# DTMF follows Media strategy if not in call
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				AvailableOutputDevices Includes DgtlDockHeadset
-
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 1
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: Hdmi
-				#
-				# DTMF falls through Phone strategy if in call (widely speaking)
-				# but Hdmi not reachable in call
-				#
-				# DTMF follows Media strategy if not in call
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				AvailableOutputDevices Includes Hdmi
-
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 1
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: AnlgDockHeadset
-				#
-				# DTMF falls through Phone strategy if in call (widely speaking)
-				# but AnlgDockHeadset not reachable in call
-				#
-				# DTMF follows Media strategy if not in call
-				# Media strategy inverts the priority of USB device vs accessory
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				ForceUseForDock Is ForceAnalogDock
-				AvailableOutputDevices Includes AnlgDockHeadset
-
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 1
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: Earpiece
-				#
-				# DTMF falls through Phone strategy if in call
-				#
-				ANY
-					TelephonyMode Is InCall
-					TelephonyMode Is InCommunication
-				AvailableOutputDevices Includes Earpiece
-				ForceUseForCommunication IsNot ForceSpeaker
-
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 1
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: Speaker
-				ANY
-					#
-					# DTMF falls through Phone strategy if in call
-					#
-					ALL
-						ANY
-							TelephonyMode Is InCall
-							TelephonyMode Is InCommunication
-						ForceUseForCommunication Is ForceSpeaker
-					#
-					# DTMF follows Media strategy if not in call
-					#
-					ALL
-						TelephonyMode IsNot InCall
-						TelephonyMode IsNot InCommunication
-						ForceUseForHdmiSystemAudio IsNot ForceHdmiSystemEnforced
-				AvailableOutputDevices Includes Speaker
-
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 1
-
-			conf: Default
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-		domain: Arc
-			#
-			# DTMF strategy follows media strategy if not in call
-			# these following domains consists in device(s) that can co-exist with others
-			# e.g. ARC, SPDIF, AUX_LINE
-			#
-			conf: Selected
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				AvailableOutputDevices Includes HdmiArc
-
-				/Policy/policy/strategies/dtmf/selected_output_devices/mask/hdmi_arc = 1
-
-			conf: NotSelected
-				/Policy/policy/strategies/dtmf/selected_output_devices/mask/hdmi_arc = 0
-
-		domain: Spdif
-			#
-			# DTMF strategy follows media strategy if not in call
-			# these following domains consists in device(s) that can co-exist with others
-			# e.g. ARC, SPDIF, AUX_LINE
-			#
-			conf: Selected
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				AvailableOutputDevices Includes Spdif
-
-				/Policy/policy/strategies/dtmf/selected_output_devices/mask/spdif = 1
-
-			conf: NotSelected
-				/Policy/policy/strategies/dtmf/selected_output_devices/mask/spdif = 0
-
-		domain: AuxLine
-			#
-			# DTMF strategy follows media strategy if not in call
-			# these following domains consists in device(s) that can co-exist with others
-			# e.g. ARC, SPDIF, AUX_LINE
-			#
-			conf: Selected
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				AvailableOutputDevices Includes AuxLine
-
-				/Policy/policy/strategies/dtmf/selected_output_devices/mask/aux_line = 1
-
-			conf: NotSelected
-				/Policy/policy/strategies/dtmf/selected_output_devices/mask/aux_line = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_enforced_audible.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_enforced_audible.pfw
deleted file mode 100644
index f504631..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_enforced_audible.pfw
+++ /dev/null
@@ -1,358 +0,0 @@
-supDomain: DeviceForStrategy
-
-	supDomain: EnforcedAudible
-
-		domain: UnreachableDevices
-			conf: Calibration
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
-					# no enforced_audible on remote submix (e.g. WFD)
-					hdmi_arc = 0
-					spdif = 0
-					aux_line = 0
-					speaker_safe = 0
-					ip = 0
-					bus = 0
-					fm = 0
-					stub = 0
-
-		domain: Speaker
-			conf: Selected
-				#
-				# strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
-				# except:
-				#    - when in call where it doesn't default to STRATEGY_PHONE behavior
-				#    - in countries where not enforced in which case it follows STRATEGY_MEDIA
-				#
-				AvailableOutputDevices Includes Speaker
-				ANY
-					ForceUseForSystem Is ForceSystemEnforced
-					ALL
-						ForceUseForMedia Is ForceSpeaker
-						AvailableOutputDevices Excludes RemoteSubmix
-						ANY
-							ForceUseForMedia IsNot ForceNoBtA2dp
-							AvailableOutputDevices Excludes BluetoothA2dp
-							AvailableOutputDevices Excludes BluetoothA2dpHeadphones
-							AvailableOutputDevices Excludes BluetoothA2dpSpeaker
-					#
-					# Speaker is also the fallback device if any of the device from Device2 domain
-					# is selected.
-					#
-					ALL
-						AvailableOutputDevices Excludes RemoteSubmix
-						AvailableOutputDevices Excludes WiredHeadphone
-						AvailableOutputDevices Excludes Line
-						AvailableOutputDevices Excludes WiredHeadset
-						AvailableOutputDevices Excludes UsbAccessory
-						AvailableOutputDevices Excludes UsbDevice
-						AvailableOutputDevices Excludes DgtlDockHeadset
-						AvailableOutputDevices Excludes Hdmi
-						ANY
-							AvailableOutputDevices Excludes AnlgDockHeadset
-							ForceUseForDock IsNot ForceAnalogDock
-
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
-					speaker = 1
-
-			conf: NotSelected
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
-					speaker = 0
-
-		domain: Device2
-			conf: RemoteSubmix
-				AvailableOutputDevices Includes RemoteSubmix
-
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
-					remote_submix = 1
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-
-			conf: BluetoothA2dp
-				AvailableOutputDevices Includes BluetoothA2dp
-				ForceUseForMedia IsNot ForceNoBtA2dp
-
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 1
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-
-			conf: BluetoothA2dpHeadphones
-				AvailableOutputDevices Includes BluetoothA2dpHeadphones
-				ForceUseForMedia IsNot ForceNoBtA2dp
-
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 1
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-
-			conf: BluetoothA2dpSpeaker
-				AvailableOutputDevices Includes BluetoothA2dpSpeaker
-				ForceUseForMedia IsNot ForceNoBtA2dp
-
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 1
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-
-			conf: WiredHeadphone
-				ForceUseForMedia IsNot ForceSpeaker
-				AvailableOutputDevices Includes WiredHeadphone
-
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 1
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-
-			conf: Line
-				ForceUseForMedia IsNot ForceSpeaker
-				AvailableOutputDevices Includes Line
-
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 1
-
-			conf: WiredHeadset
-				ForceUseForMedia IsNot ForceSpeaker
-				AvailableOutputDevices Includes WiredHeadset
-
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 1
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-
-			conf: UsbAccessory
-				ForceUseForMedia IsNot ForceSpeaker
-				AvailableOutputDevices Includes UsbAccessory
-
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 1
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-
-			conf: UsbDevice
-				ForceUseForMedia IsNot ForceSpeaker
-				AvailableOutputDevices Includes UsbDevice
-
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 1
-					telephony_tx = 0
-					line = 0
-
-			conf: DgtlDockHeadset
-				ForceUseForMedia IsNot ForceSpeaker
-				AvailableOutputDevices Includes DgtlDockHeadset
-
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 1
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-
-			conf: Hdmi
-				ForceUseForMedia IsNot ForceSpeaker
-				AvailableOutputDevices Includes Hdmi
-
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 1
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-
-			conf: AnlgDockHeadset
-				ForceUseForMedia IsNot ForceSpeaker
-				ForceUseForDock Is ForceAnalogDock
-				AvailableOutputDevices Includes AnlgDockHeadset
-
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 1
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-
-			conf: NoDevice
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-
-
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_media.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_media.pfw
deleted file mode 100644
index bdb6ae0..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_media.pfw
+++ /dev/null
@@ -1,338 +0,0 @@
-domainGroup: DeviceForStrategy
-
-	domainGroup: Media
-
-		domain: UnreachableDevices
-			conf: Calibration
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
-					fm = 0
-					speaker_safe = 0
-					earpiece = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					telephony_tx = 0
-					ip = 0
-					bus = 0
-					stub = 0
-
-		domain: Device2
-			conf: RemoteSubmix
-				AvailableOutputDevices Includes RemoteSubmix
-
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
-					speaker = 0
-					hdmi = 0
-					dgtl_dock_headset = 0
-					angl_dock_headset = 0
-					usb_device = 0
-					usb_accessory = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp = 0
-					remote_submix = 1
-					line = 0
-
-			conf: BluetoothA2dp
-				ForceUseForMedia IsNot ForceNoBtA2dp
-				ForceUseForCommunication IsNot ForceBtSco
-				AvailableOutputDevices Includes BluetoothA2dp
-
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
-					speaker = 0
-					hdmi = 0
-					dgtl_dock_headset = 0
-					angl_dock_headset = 0
-					usb_device = 0
-					usb_accessory = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp = 1
-					remote_submix = 0
-					line = 0
-
-			conf: BluetoothA2dpHeadphone
-				ForceUseForMedia IsNot ForceNoBtA2dp
-				ForceUseForCommunication IsNot ForceBtSco
-				AvailableOutputDevices Includes BluetoothA2dpHeadphones
-
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
-					speaker = 0
-					hdmi = 0
-					dgtl_dock_headset = 0
-					angl_dock_headset = 0
-					usb_device = 0
-					usb_accessory = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp_headphones = 1
-					bluetooth_a2dp = 0
-					remote_submix = 0
-					line = 0
-
-			conf: BluetoothA2dpSpeaker
-				ForceUseForMedia IsNot ForceNoBtA2dp
-				ForceUseForCommunication IsNot ForceBtSco
-				AvailableOutputDevices Includes BluetoothA2dpSpeaker
-
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
-					speaker = 0
-					hdmi = 0
-					dgtl_dock_headset = 0
-					angl_dock_headset = 0
-					usb_device = 0
-					usb_accessory = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_a2dp_speaker = 1
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp = 0
-					remote_submix = 0
-					line = 0
-
-			conf: ForceSpeaker
-				ForceUseForMedia Is ForceSpeaker
-				AvailableOutputDevices Includes Speaker
-				#
-				# If hdmi system audio mode is on, remove speaker out of output list.
-				#
-				ForceUseForHdmiSystemAudio IsNot ForceHdmiSystemEnforced
-
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
-					speaker = 1
-					hdmi = 0
-					dgtl_dock_headset = 0
-					angl_dock_headset = 0
-					usb_device = 0
-					usb_accessory = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp = 0
-					remote_submix = 0
-					line = 0
-
-			conf: WiredHeadphone
-				AvailableOutputDevices Includes WiredHeadphone
-
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
-					speaker = 0
-					hdmi = 0
-					dgtl_dock_headset = 0
-					angl_dock_headset = 0
-					usb_device = 0
-					usb_accessory = 0
-					wired_headset = 0
-					wired_headphone = 1
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp = 0
-					remote_submix = 0
-					line = 0
-
-			conf: Line
-				AvailableOutputDevices Includes Line
-
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
-					speaker = 0
-					hdmi = 0
-					dgtl_dock_headset = 0
-					angl_dock_headset = 0
-					usb_device = 0
-					usb_accessory = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp = 0
-					remote_submix = 0
-					line = 1
-
-			conf: WiredHeadset
-				AvailableOutputDevices Includes WiredHeadset
-
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
-					speaker = 0
-					hdmi = 0
-					dgtl_dock_headset = 0
-					angl_dock_headset = 0
-					usb_device = 0
-					usb_accessory = 0
-					wired_headset = 1
-					wired_headphone = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp = 0
-					remote_submix = 0
-					line = 0
-
-			conf: UsbAccessory
-				AvailableOutputDevices Includes UsbAccessory
-
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
-					speaker = 0
-					hdmi = 0
-					dgtl_dock_headset = 0
-					angl_dock_headset = 0
-					usb_device = 0
-					usb_accessory = 1
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp = 0
-					remote_submix = 0
-					line = 0
-
-			conf: UsbDevice
-				AvailableOutputDevices Includes UsbDevice
-
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
-					speaker = 0
-					hdmi = 0
-					dgtl_dock_headset = 0
-					angl_dock_headset = 0
-					usb_device = 1
-					usb_accessory = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp = 0
-					remote_submix = 0
-					line = 0
-
-			conf: DgtlDockHeadset
-				AvailableOutputDevices Includes DgtlDockHeadset
-
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
-					speaker = 0
-					hdmi = 0
-					dgtl_dock_headset = 1
-					angl_dock_headset = 0
-					usb_device = 0
-					usb_accessory = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp = 0
-					remote_submix = 0
-					line = 0
-
-			conf: AuxDigital
-				AvailableOutputDevices Includes Hdmi
-
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
-					speaker = 0
-					hdmi = 1
-					dgtl_dock_headset = 0
-					angl_dock_headset = 0
-					usb_device = 0
-					usb_accessory = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp = 0
-					remote_submix = 0
-					line = 0
-
-			conf: AnlgDockHeadset
-				AvailableOutputDevices Includes AnlgDockHeadset
-				ForceUseForDock Is ForceAnalogDock
-
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
-					speaker = 0
-					hdmi = 0
-					dgtl_dock_headset = 0
-					angl_dock_headset = 1
-					usb_device = 0
-					usb_accessory = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp = 0
-					remote_submix = 0
-					line = 0
-
-			conf: Speaker
-				AvailableOutputDevices Includes Speaker
-				#
-				# If hdmi system audio mode is on, remove speaker out of output list.
-				#
-				ForceUseForHdmiSystemAudio IsNot ForceHdmiSystemEnforced
-				ForceUseForCommunication IsNot ForceBtSco
-
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
-					speaker = 1
-					hdmi = 0
-					dgtl_dock_headset = 0
-					angl_dock_headset = 0
-					usb_device = 0
-					usb_accessory = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp = 0
-					remote_submix = 0
-					line = 0
-
-			conf: Default
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
-					speaker = 0
-					hdmi = 0
-					dgtl_dock_headset = 0
-					angl_dock_headset = 0
-					usb_device = 0
-					usb_accessory = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp = 0
-					remote_submix = 0
-					line = 0
-
-		domain: Arc
-			#
-			# these following domains consists in device(s) that can co-exist with others
-			# e.g. ARC, SPDIF, AUX_LINE
-			#
-			conf: Selected
-				AvailableOutputDevices Includes HdmiArc
-
-				/Policy/policy/strategies/media/selected_output_devices/mask/hdmi_arc = 1
-
-			conf: NotSelected
-				/Policy/policy/strategies/media/selected_output_devices/mask/hdmi_arc = 0
-
-		domain: Spdif
-			#
-			# these following domains consists in device(s) that can co-exist with others
-			# e.g. ARC, SPDIF, AUX_LINE
-			#
-			conf: Selected
-				AvailableOutputDevices Includes Spdif
-
-				/Policy/policy/strategies/media/selected_output_devices/mask/spdif = 1
-
-			conf: NotSelected
-				/Policy/policy/strategies/media/selected_output_devices/mask/spdif = 0
-
-		domain: AuxLine
-			conf: Selected
-				AvailableOutputDevices Includes AuxLine
-
-				/Policy/policy/strategies/media/selected_output_devices/mask/aux_line = 1
-
-			conf: NotSelected
-				/Policy/policy/strategies/media/selected_output_devices/mask/aux_line = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_phone.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_phone.pfw
deleted file mode 100644
index d371ad9..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_phone.pfw
+++ /dev/null
@@ -1,483 +0,0 @@
-supDomain: DeviceForStrategy
-
-	supDomain: Phone
-
-		domain: UnreachableDevices
-			conf: Calibration
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
-					# no sonification on remote submix (e.g. WFD)
-					remote_submix = 0
-					hdmi_arc = 0
-					aux_line = 0
-					spdif = 0
-					fm = 0
-					speaker_safe = 0
-					ip = 0
-					bus = 0
-					stub = 0
-
-		domain: Device
-			conf: ScoCarkit
-				AvailableOutputDevices Includes BluetoothScoCarkit
-				ForceUseForCommunication Is ForceBtSco
-
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 1
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: BluetoothScoHeadset
-				AvailableOutputDevices Includes BluetoothScoHeadset
-				ForceUseForCommunication Is ForceBtSco
-
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 1
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: BluetoothSco
-				AvailableOutputDevices Includes BluetoothSco
-				ForceUseForCommunication Is ForceBtSco
-
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 1
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: BluetoothA2dp
-				#
-				# Fallback BT Sco devices in case of FORCE_BT_SCO
-				# or FORCE_NONE
-				#
-				AvailableOutputDevices Includes BluetoothA2dp
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				ForceUseForMedia IsNot ForceNoBtA2dp
-				ForceUseForCommunication Is ForceNone
-
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 1
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: BluetoothA2dpHeadphones
-				#
-				# Fallback BT Sco devices in case of FORCE_BT_SCO
-				# or FORCE_NONE
-				#
-				AvailableOutputDevices Includes BluetoothA2dpHeadphones
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				ForceUseForMedia IsNot ForceNoBtA2dp
-				ForceUseForCommunication Is ForceNone
-
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 1
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: BluetoothA2dpSpeaker
-				#
-				# Fallback BT Sco devices in case of FORCE_BT_SCO
-				# or FORCE_NONE
-				#
-				AvailableOutputDevices Includes BluetoothA2dpSpeaker
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				ForceUseForMedia IsNot ForceNoBtA2dp
-				ForceUseForCommunication Is ForceSpeaker
-
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 1
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: WiredHeadphone
-				#
-				# Fallback BT Sco devices in case of FORCE_BT_SCO
-				# or FORCE_NONE
-				#
-				AvailableOutputDevices Includes WiredHeadphone
-				ForceUseForCommunication IsNot ForceSpeaker
-
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 1
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: WiredHeadset
-				#
-				# Fallback BT Sco devices in case of FORCE_BT_SCO
-				# or FORCE_NONE
-				#
-				AvailableOutputDevices Includes WiredHeadset
-				ForceUseForCommunication IsNot ForceSpeaker
-
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 1
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: Line
-				AvailableOutputDevices Includes Line
-				ForceUseForCommunication IsNot ForceSpeaker
-
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 1
-					speaker = 0
-
-			conf: UsbDevice
-				#
-				# Fallback BT Sco devices in case of FORCE_BT_SCO
-				# or FORCE_NONE
-				#
-				AvailableOutputDevices Includes UsbDevice
-				ANY
-					ForceUseForCommunication Is ForceBtSco
-					ForceUseForCommunication Is ForceNone
-					ALL
-						ForceUseForCommunication Is ForceSpeaker
-						#
-						# In case of Force Speaker, priority between device and accessory are
-						# inverted compared to Force None or Bt Sco
-						#
-						AvailableOutputDevices Excludes UsbAccessory
-						TelephonyMode IsNot InCall
-						TelephonyMode IsNot InCommunication
-
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 1
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: UsbAccessory
-				#
-				# Fallback BT Sco devices in case of FORCE_BT_SCO
-				# or FORCE_NONE
-				#
-				AvailableOutputDevices Includes UsbAccessory
-				TelephonyMode IsNot InCommunication
-				TelephonyMode IsNot InCall
-
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 1
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: DgtlDockHeadset
-				#
-				# Fallback BT Sco devices in case of FORCE_BT_SCO
-				# or FORCE_NONE
-				#
-				AvailableOutputDevices Includes DgtlDockHeadset
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 1
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: Hdmi
-				#
-				# Fallback BT Sco devices in case of FORCE_BT_SCO
-				# or FORCE_NONE
-				#
-				AvailableOutputDevices Includes Hdmi
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 1
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: AnlgDockHeadset
-				#
-				# Fallback BT Sco devices in case of FORCE_BT_SCO
-				# or FORCE_NONE
-				#
-				AvailableOutputDevices Includes AnlgDockHeadset
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 1
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: Earpiece
-				#
-				# Fallback BT Sco devices in case of FORCE_BT_SCO
-				# or FORCE_NONE
-				#
-				AvailableOutputDevices Includes Earpiece
-				ForceUseForCommunication IsNot ForceSpeaker
-
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
-					earpiece = 1
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 0
-
-			conf: Speaker
-				#
-				# Fallback BT Sco devices in case of FORCE_BT_SCO
-				# or FORCE_NONE
-				#
-				AvailableOutputDevices Includes Speaker
-				ForceUseForCommunication Is ForceSpeaker
-
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 1
-
-			conf: Default
-				#
-				# Fallback on default output device which can be speaker for example
-				#
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					speaker = 1
-
-
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_rerouting.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_rerouting.pfw
deleted file mode 100644
index 04e62f7..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_rerouting.pfw
+++ /dev/null
@@ -1,300 +0,0 @@
-domainGroup: DeviceForStrategy
-
-	domainGroup: Rerouting
-		#
-		# Falls through media strategy
-		#
-		domain: UnreachableDevices
-			conf: Calibration
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					hdmi_arc = 0
-					spdif = 0
-					aux_line = 0
-					fm = 0
-					speaker_safe = 0
-					earpiece = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					telephony_tx = 0
-					ip = 0
-					bus = 0
-					stub = 0
-
-		domain: Device2
-			conf: RemoteSubmix
-				AvailableOutputDevices Includes RemoteSubmix
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 1
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: BluetoothA2dp
-				ForceUseForMedia IsNot ForceNoBtA2dp
-				AvailableOutputDevices Includes BluetoothA2dp
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 1
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: BluetoothA2dpHeadphone
-				ForceUseForMedia IsNot ForceNoBtA2dp
-				AvailableOutputDevices Includes BluetoothA2dpHeadphones
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 1
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: BluetoothA2dpSpeaker
-				ForceUseForMedia IsNot ForceNoBtA2dp
-				AvailableOutputDevices Includes BluetoothA2dpSpeaker
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 1
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: ForceSpeaker
-				ForceUseForMedia Is ForceSpeaker
-				AvailableOutputDevices Includes Speaker
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 1
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: WiredHeadphone
-				AvailableOutputDevices Includes WiredHeadphone
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 1
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: Line
-				AvailableOutputDevices Includes Line
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 1
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: WiredHeadset
-				AvailableOutputDevices Includes WiredHeadset
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 1
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: UsbAccessory
-				AvailableOutputDevices Includes UsbAccessory
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 1
-					usb_device = 0
-					hdmi = 0
-
-			conf: UsbDevice
-				AvailableOutputDevices Includes UsbDevice
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 1
-					hdmi = 0
-
-			conf: DgtlDockHeadset
-				AvailableOutputDevices Includes DgtlDockHeadset
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 1
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: AuxDigital
-				#
-				# Rerouting is similar to media and sonification (exept here: sonification is not allowed on HDMI)
-				#
-				AvailableOutputDevices Includes Hdmi
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 1
-
-			conf: AnlgDockHeadset
-				AvailableOutputDevices Includes AnlgDockHeadset
-				ForceUseForDock Is ForceAnalogDock
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 1
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: Speaker
-				AvailableOutputDevices Includes Speaker
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 1
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: Default
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_sonification.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_sonification.pfw
deleted file mode 100644
index 70740d1..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_sonification.pfw
+++ /dev/null
@@ -1,490 +0,0 @@
-supDomain: DeviceForStrategy
-
-	supDomain: Sonification
-
-		domain: UnreachableDevices
-			conf: Calibration
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
-					# no sonification on remote submix (e.g. WFD)
-					remote_submix = 0
-					hdmi_arc = 0
-					spdif = 0
-					fm = 0
-					speaker_safe = 0
-					aux_line = 0
-					#
-					# Sonification follows phone strategy if in call but HDMI is not reachable
-					#
-					hdmi = 0
-					ip = 0
-					bus = 0
-					stub = 0
-
-		domain: Speaker
-
-			conf: Selected
-				AvailableOutputDevices Includes Speaker
-				ANY
-					#
-					# Sonification falls through ENFORCED_AUDIBLE if not in call (widely speaking)
-					#
-					ALL
-						TelephonyMode IsNot InCall
-						TelephonyMode IsNot InCommunication
-					ALL
-						#
-						# Sonification follows phone strategy if in call (widely speaking)
-						#
-						ForceUseForCommunication Is ForceSpeaker
-						ANY
-							TelephonyMode Is InCall
-							TelephonyMode Is InCommunication
-						AvailableOutputDevices Excludes Line
-
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
-					speaker = 1
-
-			conf: NotSelected
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
-					speaker = 0
-
-		domain: Device2
-
-			conf: BluetoothA2dp
-				#
-				# Sonification falls through media strategy if not in call (widely speaking)
-				#
-				AvailableOutputDevices Includes BluetoothA2dp
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				ForceUseForMedia IsNot ForceNoBtA2dp
-
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 1
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-
-			conf: BluetoothA2dpHeadphones
-				#
-				# Sonification falls through media strategy if not in call (widely speaking)
-				#
-				AvailableOutputDevices Includes BluetoothA2dpHeadphones
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				ForceUseForMedia IsNot ForceNoBtA2dp
-
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 1
-					bluetooth_a2dp_speaker = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-
-			conf: BluetoothA2dpSpeaker
-				#
-				# Sonification falls through media strategy if not in call (widely speaking)
-				#
-				AvailableOutputDevices Includes BluetoothA2dpSpeaker
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				ForceUseForMedia IsNot ForceNoBtA2dp
-
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 1
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-
-			conf: ScoCarkit
-				#
-				# Sonification follows phone strategy if in call (widely speaking)
-				#
-				ANY
-					TelephonyMode Is InCall
-					TelephonyMode Is InCommunication
-				ForceUseForCommunication Is ForceBtSco
-				AvailableOutputDevices Includes BluetoothScoCarkit
-
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 1
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-
-			conf: ScoHeadset
-				#
-				# Sonification follows phone strategy if in call (widely speaking)
-				#
-				ANY
-					TelephonyMode Is InCall
-					TelephonyMode Is InCommunication
-				ForceUseForCommunication Is ForceBtSco
-				AvailableOutputDevices Includes BluetoothScoHeadset
-
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 1
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-
-			conf: Sco
-				#
-				# Sonification follows phone strategy if in call (widely speaking)
-				#
-				ANY
-					TelephonyMode Is InCall
-					TelephonyMode Is InCommunication
-				ForceUseForCommunication Is ForceBtSco
-				AvailableOutputDevices Includes BluetoothSco
-
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 1
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-
-			conf: WiredHeadphone
-				AvailableOutputDevices Includes WiredHeadphone
-				ANY
-					#
-					# Sonification falls through media strategy if not in call (widely speaking)
-					#
-					ALL
-						TelephonyMode IsNot InCall
-						TelephonyMode IsNot InCommunication
-						ForceUseForMedia IsNot ForceSpeaker
-					#
-					# Sonification follows Phone strategy if in call (widely speaking)
-					#
-					ALL
-						ANY
-							TelephonyMode Is InCall
-							TelephonyMode Is InCommunication
-						ForceUseForCommunication IsNot ForceSpeaker
-
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 1
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-
-			conf: Line
-				AvailableOutputDevices Includes Line
-				ANY
-					#
-					# Sonification follows Phone strategy if in call (widely speaking)
-					# but Line has a lower priority than WiredHeadset in this case.
-					#
-					ALL
-						ANY
-							TelephonyMode Is InCall
-							TelephonyMode Is InCommunication
-						ForceUseForCommunication IsNot ForceSpeaker
-						AvailableOutputDevices Excludes WiredHeadset
-					#
-					# Sonification falls through media strategy if not in call (widely speaking)
-					#
-					ALL
-						TelephonyMode IsNot InCall
-						TelephonyMode IsNot InCommunication
-						ForceUseForMedia IsNot ForceSpeaker
-
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 1
-
-			conf: WiredHeadset
-				AvailableOutputDevices Includes WiredHeadset
-				ANY
-					#
-					# Sonification falls through media strategy if not in call (widely speaking)
-					#
-					ALL
-						TelephonyMode IsNot InCall
-						TelephonyMode IsNot InCommunication
-						ForceUseForMedia IsNot ForceSpeaker
-					ALL
-						#
-						# Sonification Follows Phone Strategy if in call (widely speaking)
-						#
-						ANY
-							TelephonyMode Is InCall
-							TelephonyMode Is InCommunication
-						ForceUseForCommunication IsNot ForceSpeaker
-
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 1
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-
-			conf: UsbDevice
-				AvailableOutputDevices Includes UsbDevice
-				ANY
-					#
-					# Sonification falls through media strategy if not in call (widely speaking)
-					#
-					ALL
-						AvailableOutputDevices Excludes UsbAccessory
-						TelephonyMode IsNot InCall
-						TelephonyMode IsNot InCommunication
-						ForceUseForMedia IsNot ForceSpeaker
-					ALL
-						#
-						# Sonification Follows Phone Strategy if in call (widely speaking)
-						#
-						ANY
-							TelephonyMode Is InCall
-							TelephonyMode Is InCommunication
-						ForceUseForCommunication IsNot ForceSpeaker
-
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 1
-					telephony_tx = 0
-					line = 0
-
-			conf: UsbAccessory
-				AvailableOutputDevices Includes UsbAccessory
-				#
-				# Sonification falls through media strategy if not in call (widely speaking)
-				#
-				# Sonification Follows Phone Strategy if in call (widely speaking)
-				# but USB Accessory not reachable in call.
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				ForceUseForMedia IsNot ForceSpeaker
-
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 1
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-
-			conf: DgtlDockHeadset
-				AvailableOutputDevices Includes DgtlDockHeadset
-				#
-				# Sonification falls through media strategy if not in call
-				#
-				# Sonification Follows Phone Strategy if in call (widely speaking)
-				# but DgtlDockHeadset not reachable in call.
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				ForceUseForMedia IsNot ForceSpeaker
-
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 1
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-
-			conf: AnlgDockHeadset
-				AvailableOutputDevices Includes AnlgDockHeadset
-				#
-				# Sonification falls through media strategy if not in call
-				#
-				# Sonification Follows Phone Strategy if in call (widely speaking)
-				# but AnlgDockHeadset not reachable in call.
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				ForceUseForMedia IsNot ForceSpeaker
-				ForceUseForDock Is ForceAnalogDock
-
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					angl_dock_headset = 1
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-
-			conf: Earpiece
-				#
-				# Sonification Follows Phone Strategy if in call
-				#
-				ANY
-					TelephonyMode Is InCall
-					TelephonyMode Is InCommunication
-				ForceUseForCommunication IsNot ForceSpeaker
-				AvailableOutputDevices Includes Earpiece
-
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
-					earpiece = 1
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-
-			conf: None
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_sonification_respectful.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_sonification_respectful.pfw
deleted file mode 100644
index cee7cd1..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_sonification_respectful.pfw
+++ /dev/null
@@ -1,536 +0,0 @@
-domainGroup: DeviceForStrategy
-
-	domainGroup: SonificationRespectful
-		#
-		# Sonificiation Respectful follows:
-		#	- If in call: Strategy sonification (that follows phone strategy in call also...)
-		#	- If not in call AND a music stream is active remotely: Strategy sonification (that
-		#     follows enforced audible, which follows media)
-		#	- if not in call and no music stream active remotely and music stream active): strategy
-		#     media
-		#   - Otherwise follows sonification by replacing speaker with speaker safe if speaker is
-		#	  selected.
-		#
-		# Case of stream active handled programmatically
-
-		domain: UnreachableDevices
-			conf: Calibration
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
-					remote_submix = 0
-					hdmi_arc = 0
-					aux_line = 0
-					spdif = 0
-					fm = 0
-					telephony_tx = 0
-					ip = 0
-					bus = 0
-					stub = 0
-
-		domain: Speakers
-
-			conf: SpeakerSafe
-				AvailableOutputDevices Includes Speaker
-				AvailableOutputDevices Includes SpeakerSafe
-				#
-				# Follows sonification strategy if not in call and replace speaker by speaker safe
-				# if and only if speaker only selected
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
-					speaker_safe = 1
-					speaker = 0
-
-			conf: Speaker
-				AvailableOutputDevices Includes Speaker
-				ANY
-					#
-					# Follows sonification strategy if not in call
-					#
-					ALL
-						TelephonyMode IsNot InCall
-						TelephonyMode IsNot InCommunication
-					ALL
-						#
-						# Follows Phone Strategy if call
-						#
-						ForceUseForCommunication Is ForceSpeaker
-						ANY
-							TelephonyMode Is InCall
-							TelephonyMode Is InCommunication
-						AvailableOutputDevices Excludes Line
-
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
-					speaker_safe = 0
-					speaker = 1
-
-			conf: None
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
-					speaker_safe = 0
-					speaker = 0
-
-		domain: Device2
-			conf: BluetoothA2dp
-				#
-				# SonificationRespectful Follows Sonification that falls through Media strategy if not in call
-				# SonificationRespectful follows media if music stream is active
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				ForceUseForMedia IsNot ForceNoBtA2dp
-				AvailableOutputDevices Includes BluetoothA2dp
-
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
-					earpiece = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp = 1
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: BluetoothA2dpHeadphones
-				#
-				# SonificationRespectful Follows Sonification that falls through Media strategy if not in call
-				# SonificationRespectful follows media if music stream is active
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				ForceUseForMedia IsNot ForceNoBtA2dp
-				AvailableOutputDevices Includes BluetoothA2dpHeadphones
-
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
-					earpiece = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp_headphones = 1
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: BluetoothA2dpSpeaker
-				#
-				# SonificationRespectful Follows Sonification that falls through Media strategy if not in call
-				# SonificationRespectful follows media if music stream is active
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				ForceUseForMedia IsNot ForceNoBtA2dp
-				AvailableOutputDevices Includes BluetoothA2dpSpeaker
-
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
-					earpiece = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 1
-					bluetooth_a2dp = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: BluetoothScoCarkit
-				#
-				# SonificationRespectful Follows Phone strategy if in call
-				#
-				ANY
-					TelephonyMode Is InCall
-					TelephonyMode Is InCommunication
-				ForceUseForCommunication Is ForceBtSco
-				AvailableOutputDevices Includes BluetoothScoCarkit
-
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
-					earpiece = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 1
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: BluetoothScoHeadset
-				#
-				# SonificationRespectful Follows Phone strategy if in call
-				#
-				ANY
-					TelephonyMode Is InCall
-					TelephonyMode Is InCommunication
-				ForceUseForCommunication Is ForceBtSco
-				AvailableOutputDevices Includes BluetoothScoHeadset
-
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
-					earpiece = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 1
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: BluetoothSco
-				#
-				# SonificationRespectful Follows Phone strategy if in call
-				#
-				ANY
-					TelephonyMode Is InCall
-					TelephonyMode Is InCommunication
-				ForceUseForCommunication Is ForceBtSco
-				AvailableOutputDevices Includes BluetoothSco
-
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
-					earpiece = 0
-					bluetooth_sco = 1
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: WiredHeadphone
-				ANY
-					ALL
-						#
-						# SonificationRespectful Follows Phone strategy if in call
-						#
-						ANY
-							TelephonyMode Is InCall
-							TelephonyMode Is InCommunication
-						ForceUseForCommunication IsNot ForceSpeaker
-					ALL
-						#
-						# SonificationRespectful Follows Sonification that falls through Media strategy if not in call
-						# SonificationRespectful follows media if music stream is active
-						#
-						TelephonyMode IsNot InCall
-						TelephonyMode IsNot InCommunication
-						ForceUseForMedia IsNot ForceSpeaker
-				AvailableOutputDevices Includes WiredHeadphone
-
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
-					earpiece = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp = 0
-					wired_headset = 0
-					wired_headphone = 1
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: Line
-				ANY
-					#
-					# SonificationRespectful Follows Phone strategy if in call
-					# but Line has a lower priority than WiredHeadset in this case.
-					#
-					#
-					ALL
-						ANY
-							TelephonyMode Is InCall
-							TelephonyMode Is InCommunication
-						ForceUseForCommunication IsNot ForceSpeaker
-						AvailableOutputDevices Excludes WiredHeadset
-					#
-					# SonificationRespectful Follows Sonification that falls through Media strategy if not in call
-					# SonificationRespectful follows media if music stream is active
-					#
-					ALL
-						TelephonyMode IsNot InCall
-						TelephonyMode IsNot InCommunication
-						AvailableOutputDevices Includes WiredHeadphone
-						ForceUseForMedia IsNot ForceSpeaker
-				AvailableOutputDevices Includes Line
-
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
-					earpiece = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 1
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: WiredHeadset
-				ANY
-					ALL
-						#
-						# SonificationRespectful Follows Phone strategy if in call
-						#
-						ANY
-							TelephonyMode Is InCall
-							TelephonyMode Is InCommunication
-						ForceUseForCommunication IsNot ForceSpeaker
-					ALL
-						#
-						# SonificationRespectful Follows Sonification that falls through Media strategy if not in call
-						# SonificationRespectful follows media if music stream is active
-						#
-						TelephonyMode IsNot InCall
-						TelephonyMode IsNot InCommunication
-						ForceUseForMedia IsNot ForceSpeaker
-				AvailableOutputDevices Includes WiredHeadset
-
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
-					earpiece = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp = 0
-					wired_headset = 1
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: UsbDevice
-				ANY
-					ALL
-						#
-						# SonificationRespectful Follows Phone strategy if in call
-						#
-						ANY
-							TelephonyMode Is InCall
-							TelephonyMode Is InCommunication
-						ForceUseForCommunication IsNot ForceSpeaker
-					ALL
-						#
-						# SonificationRespectful Follows Sonification that falls through Media strategy if not in call
-						# SonificationRespectful follows media if music stream is active
-						#
-						TelephonyMode IsNot InCall
-						TelephonyMode IsNot InCommunication
-						ForceUseForMedia IsNot ForceSpeaker
-						AvailableOutputDevices Excludes UsbAccessory
-				AvailableOutputDevices Includes UsbDevice
-
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
-					earpiece = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 1
-					hdmi = 0
-
-			conf: UsbAccessory
-				#
-				# SonificationRespectful Follows Phone strategy if in call (widely speaking)
-				# but UsbAccessory not reachable in call.
-				#
-				# SonificationRespectful Follows Sonification that falls through Media strategy if not in call
-				# SonificationRespectful follows media if music stream is active
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				ForceUseForMedia IsNot ForceSpeaker
-				AvailableOutputDevices Includes UsbAccessory
-
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
-					earpiece = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 1
-					usb_device = 0
-					hdmi = 0
-
-			conf: DgtlDockHeadset
-				#
-				# SonificationRespectful Follows Phone strategy if in call (widely speaking)
-				# but DgtlDockHeadset not reachable in call.
-				#
-				# SonificationRespectful Follows Sonification that falls through Media strategy if not in call
-				# SonificationRespectful follows media if music stream is active
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				ForceUseForMedia IsNot ForceSpeaker
-				AvailableOutputDevices Includes DgtlDockHeadset
-
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
-					earpiece = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 1
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: AuxDigital
-				#
-				# SonificationRespectful Follows Phone strategy if in call (widely speaking)
-				# but HDMI not reachable in call.
-				#
-				# SonificationRespectful Follows Sonification that falls through Media strategy if not in call
-				# SonificationRespectful follows media if music stream is active
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				ForceUseForMedia IsNot ForceSpeaker
-				AvailableOutputDevices Includes Hdmi
-
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
-					earpiece = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 1
-
-			conf: AnlgDockHeadset
-				#
-				# SonificationRespectful Follows Phone strategy if in call (widely speaking)
-				# but AnlgDockHeadset not reachable in call.
-				#
-				# SonificationRespectful Follows Sonification that falls through Media strategy if not in call
-				# SonificationRespectful follows media if music stream is active
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				ForceUseForMedia IsNot ForceSpeaker
-				ForceUseForDock Is ForceAnalogDock
-				AvailableOutputDevices Includes AnlgDockHeadset
-
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
-					earpiece = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 1
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: Earpiece
-				#
-				# SonificationRespectful Follows Phone strategy if in call
-				#
-				ANY
-					TelephonyMode Is InCall
-					TelephonyMode Is InCommunication
-				ForceUseForCommunication IsNot ForceSpeaker
-				AvailableOutputDevices Includes Earpiece
-
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
-					earpiece = 1
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_transmitted_through_speaker.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_transmitted_through_speaker.pfw
deleted file mode 100644
index 9f9c211..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_transmitted_through_speaker.pfw
+++ /dev/null
@@ -1,43 +0,0 @@
-supDomain: DeviceForStrategy
-
-	supDomain: TransmittedThroughSpeaker
-		domain: UnreacheableDevices
-			conf: Calibration
-				component: /Policy/policy/strategies/transmitted_through_speaker/selected_output_devices/mask
-					remote_submix = 0
-					hdmi_arc = 0
-					spdif = 0
-					aux_line = 0
-					fm = 0
-					speaker_safe = 0
-					earpiece = 0
-					wired_headset = 1
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 0
-					ip = 0
-					bus = 0
-					stub = 0
-
-		domain: Speaker
-			conf: Selected
-				AvailableOutputDevices Includes Speaker
-
-				component: /Policy/policy/strategies/transmitted_through_speaker/selected_output_devices/mask
-					speaker = 1
-
-			conf: NotSelected
-				component: /Policy/policy/strategies/transmitted_through_speaker/selected_output_devices/mask
-					speaker = 0
-
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/strategy_for_stream.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/strategy_for_stream.pfw
deleted file mode 100644
index 3940b9d..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/strategy_for_stream.pfw
+++ /dev/null
@@ -1,20 +0,0 @@
-domain: StrategyForStream
-
-	conf: Calibration
-		/Policy/policy/streams/voice_call/applicable_strategy/strategy = phone
-		#
-		# NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
-		# while key clicks are played produces a poor result
-		#
-		/Policy/policy/streams/system/applicable_strategy/strategy = media
-		/Policy/policy/streams/ring/applicable_strategy/strategy = sonification
-		/Policy/policy/streams/music/applicable_strategy/strategy = media
-		/Policy/policy/streams/alarm/applicable_strategy/strategy = sonification
-		/Policy/policy/streams/notification/applicable_strategy/strategy = sonification_respectful
-		/Policy/policy/streams/bluetooth_sco/applicable_strategy/strategy = phone
-		/Policy/policy/streams/enforced_audible/applicable_strategy/strategy = enforced_audible
-		/Policy/policy/streams/dtmf/applicable_strategy/strategy = dtmf
-		/Policy/policy/streams/tts/applicable_strategy/strategy = transmitted_through_speaker
-		/Policy/policy/streams/accessibility/applicable_strategy/strategy = accessibility
-		/Policy/policy/streams/rerouting/applicable_strategy/strategy = rerouting
-
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/strategy_for_usage.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/strategy_for_usage.pfw
index b3115e7..fbea9e2 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/strategy_for_usage.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/strategy_for_usage.pfw
@@ -24,7 +24,7 @@
 			# In case of Ring or Alarm stream type active, switching to sonification
 			# @todo: handle this dynamic case. As a WA, using Ringtone mode...
 			#
-			TelephonyMode Is RingTone
+			TelephonyMode Is Ringtone
 
 			/Policy/policy/usages/assistance_accessibility/applicable_strategy/strategy = sonification
 
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoOutput/device_for_strategies.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoOutput/device_for_strategies.pfw
index 917d4a7..f923610 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoOutput/device_for_strategies.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoOutput/device_for_strategies.pfw
@@ -9,7 +9,7 @@
 				bluetooth_sco = 0
 				bluetooth_sco_headset = 0
 				bluetooth_sco_carkit = 0
-				bluetooth_a2dp = 0>
+				bluetooth_a2dp = 0
 				bluetooth_a2dp_headphones = 0
 				bluetooth_a2dp_speaker = 0
 				hdmi = 0
@@ -37,7 +37,7 @@
 				bluetooth_sco = 0
 				bluetooth_sco_headset = 0
 				bluetooth_sco_carkit = 0
-				bluetooth_a2dp = 0>
+				bluetooth_a2dp = 0
 				bluetooth_a2dp_headphones = 0
 				bluetooth_a2dp_speaker = 0
 				hdmi = 0
@@ -65,7 +65,7 @@
 				bluetooth_sco = 0
 				bluetooth_sco_headset = 0
 				bluetooth_sco_carkit = 0
-				bluetooth_a2dp = 0>
+				bluetooth_a2dp = 0
 				bluetooth_a2dp_headphones = 0
 				bluetooth_a2dp_speaker = 0
 				hdmi = 0
@@ -93,7 +93,7 @@
 				bluetooth_sco = 0
 				bluetooth_sco_headset = 0
 				bluetooth_sco_carkit = 0
-				bluetooth_a2dp = 0>
+				bluetooth_a2dp = 0
 				bluetooth_a2dp_headphones = 0
 				bluetooth_a2dp_speaker = 0
 				hdmi = 0
@@ -121,7 +121,7 @@
 				bluetooth_sco = 0
 				bluetooth_sco_headset = 0
 				bluetooth_sco_carkit = 0
-				bluetooth_a2dp = 0>
+				bluetooth_a2dp = 0
 				bluetooth_a2dp_headphones = 0
 				bluetooth_a2dp_speaker = 0
 				hdmi = 0
@@ -149,7 +149,7 @@
 				bluetooth_sco = 0
 				bluetooth_sco_headset = 0
 				bluetooth_sco_carkit = 0
-				bluetooth_a2dp = 0>
+				bluetooth_a2dp = 0
 				bluetooth_a2dp_headphones = 0
 				bluetooth_a2dp_speaker = 0
 				hdmi = 0
@@ -177,7 +177,7 @@
 				bluetooth_sco = 0
 				bluetooth_sco_headset = 0
 				bluetooth_sco_carkit = 0
-				bluetooth_a2dp = 0>
+				bluetooth_a2dp = 0
 				bluetooth_a2dp_headphones = 0
 				bluetooth_a2dp_speaker = 0
 				hdmi = 0
@@ -205,7 +205,7 @@
 				bluetooth_sco = 0
 				bluetooth_sco_headset = 0
 				bluetooth_sco_carkit = 0
-				bluetooth_a2dp = 0>
+				bluetooth_a2dp = 0
 				bluetooth_a2dp_headphones = 0
 				bluetooth_a2dp_speaker = 0
 				hdmi = 0
@@ -233,7 +233,7 @@
 				bluetooth_sco = 0
 				bluetooth_sco_headset = 0
 				bluetooth_sco_carkit = 0
-				bluetooth_a2dp = 0>
+				bluetooth_a2dp = 0
 				bluetooth_a2dp_headphones = 0
 				bluetooth_a2dp_speaker = 0
 				hdmi = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem-CommonTypes.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem-CommonTypes.xml
deleted file mode 100644
index 461e44a..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem-CommonTypes.xml
+++ /dev/null
@@ -1,198 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ComponentTypeSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-              xmlns:xi="http://www.w3.org/2001/XInclude"
-              xsi:noNamespaceSchemaLocation="Schemas/ComponentTypeSet.xsd">
-    <!-- Output devices definition as a bitfield for the supported devices per output
-    profile. It must match with the output device enum parameter.
-    -->
-     <!--#################### GLOBAL COMPONENTS BEGIN ####################-->
-
-     <!--#################### GLOBAL COMPONENTS END ####################-->
-
-    <ComponentType Name="OutputDevicesMask" Description="32th bit is not allowed as dedicated
-                                                     for input devices detection">
-        <BitParameterBlock Name="mask" Size="32">
-            <BitParameter Name="earpiece" Size="1" Pos="0"/>
-            <BitParameter Name="speaker" Size="1" Pos="1"/>
-            <BitParameter Name="wired_headset" Size="1" Pos="2"/>
-            <BitParameter Name="wired_headphone" Size="1" Pos="3"/>
-            <BitParameter Name="bluetooth_sco" Size="1" Pos="4"/>
-            <BitParameter Name="bluetooth_sco_headset" Size="1" Pos="5"/>
-            <BitParameter Name="bluetooth_sco_carkit" Size="1" Pos="6"/>
-            <BitParameter Name="bluetooth_a2dp" Size="1" Pos="7"/>
-            <BitParameter Name="bluetooth_a2dp_headphones" Size="1" Pos="8"/>
-            <BitParameter Name="bluetooth_a2dp_speaker" Size="1" Pos="9"/>
-            <BitParameter Name="hdmi" Size="1" Pos="10"/>
-            <BitParameter Name="angl_dock_headset" Size="1" Pos="11"/>
-            <BitParameter Name="dgtl_dock_headset" Size="1" Pos="12"/>
-            <BitParameter Name="usb_accessory" Size="1" Pos="13"/>
-            <BitParameter Name="usb_device" Size="1" Pos="14"/>
-            <BitParameter Name="remote_submix" Size="1" Pos="15"/>
-            <BitParameter Name="telephony_tx" Size="1" Pos="16"/>
-            <BitParameter Name="line" Size="1" Pos="17"/>
-            <BitParameter Name="hdmi_arc" Size="1" Pos="18"/>
-            <BitParameter Name="spdif" Size="1" Pos="19"/>
-            <BitParameter Name="fm" Size="1" Pos="20"/>
-            <BitParameter Name="aux_line" Size="1" Pos="21"/>
-            <BitParameter Name="speaker_safe" Size="1" Pos="22"/>
-            <BitParameter Name="ip" Size="1" Pos="23"/>
-            <BitParameter Name="bus" Size="1" Pos="24"/>
-            <BitParameter Name="stub" Size="1" Pos="30"/>
-        </BitParameterBlock>
-    </ComponentType>
-
-    <!-- Input devices definition as a bitfield for the supported devices per Input
-    profile. It must match with the Input device enum parameter.
-    -->
-    <ComponentType Name="InputDevicesMask">
-        <BitParameterBlock Name="mask" Size="32">
-            <BitParameter Name="communication" Size="1" Pos="0"/>
-            <BitParameter Name="ambient" Size="1" Pos="1"/>
-            <BitParameter Name="builtin_mic" Size="1" Pos="2"/>
-            <BitParameter Name="bluetooth_sco_headset" Size="1" Pos="3"/>
-            <BitParameter Name="wired_headset" Size="1" Pos="4"/>
-            <BitParameter Name="hdmi" Size="1" Pos="5"/>
-            <BitParameter Name="telephony_rx" Size="1" Pos="6"/>
-            <BitParameter Name="back_mic" Size="1" Pos="7"/>
-            <BitParameter Name="remote_submix" Size="1" Pos="8"/>
-            <BitParameter Name="anlg_dock_headset" Size="1" Pos="9"/>
-            <BitParameter Name="dgtl_dock_headset" Size="1" Pos="10"/>
-            <BitParameter Name="usb_accessory" Size="1" Pos="11"/>
-            <BitParameter Name="usb_device" Size="1" Pos="12"/>
-            <BitParameter Name="fm_tuner" Size="1" Pos="13"/>
-            <BitParameter Name="tv_tuner" Size="1" Pos="14"/>
-            <BitParameter Name="line" Size="1" Pos="15"/>
-            <BitParameter Name="spdif" Size="1" Pos="16"/>
-            <BitParameter Name="bluetooth_a2dp" Size="1" Pos="17"/>
-            <BitParameter Name="loopback" Size="1" Pos="18"/>
-            <BitParameter Name="ip" Size="1" Pos="19"/>
-            <BitParameter Name="bus" Size="1" Pos="20"/>
-            <BitParameter Name="stub" Size="1" Pos="30"/>
-        </BitParameterBlock>
-    </ComponentType>
-
-    <ComponentType Name="OutputFlags"
-                   Description="the audio output flags serve two purposes:
-                    - when an AudioTrack is created they indicate a wish to be connected to an
-                      output stream with attributes corresponding to the specified flags.
-                    - when present in an output profile descriptor listed for a particular audio
-                      hardware module, they indicate that an output stream can be opened that
-                      supports the attributes indicated by the flags.
-                    The audio policy manager will try to match the flags in the request
-                    (when getOuput() is called) to an available output stream.">
-        <BitParameterBlock Name="mask" Size="32">
-            <BitParameter Name="direct" Size="1" Pos="0"/>
-            <BitParameter Name="primary" Size="1" Pos="1"/>
-            <BitParameter Name="fast" Size="1" Pos="2"/>
-            <BitParameter Name="deep_buffer" Size="1" Pos="3"/>
-            <BitParameter Name="compress_offload" Size="1" Pos="4"/>
-            <BitParameter Name="non_blocking" Size="1" Pos="5"/>
-            <BitParameter Name="hw_av_sync" Size="1" Pos="6"/>
-            <BitParameter Name="tts" Size="1" Pos="7"/>
-            <BitParameter Name="raw" Size="1" Pos="8"/>
-            <BitParameter Name="sync" Size="1" Pos="9"/>
-            <BitParameter Name="iec958_nonaudio" Size="1" Pos="10"/>
-        </BitParameterBlock>
-    </ComponentType>
-
-    <ComponentType Name="InputFlags"
-                   Description="The audio input flags are analogous to audio output flags.
-                                Currently they are used only when an AudioRecord is created,
-                                to indicate a preference to be connected to an input stream with
-                                attributes corresponding to the specified flags.">
-        <BitParameterBlock Name="mask" Size="32">
-            <BitParameter Name="fast" Size="1" Pos="0"/>
-            <BitParameter Name="hw_hotword" Size="1" Pos="2"/>
-            <BitParameter Name="raw" Size="1" Pos="3"/>
-            <BitParameter Name="sync" Size="1" Pos="4"/>
-        </BitParameterBlock>
-    </ComponentType>
-
-    <ComponentType Name="InputSourcesMask" Description="The audio input source is also known
-                                                        as the use case.">
-        <BitParameterBlock Name="mask" Size="32">
-            <BitParameter Name="default" Size="1" Pos="0"/>
-            <BitParameter Name="mic" Size="1" Pos="1"/>
-            <BitParameter Name="voice_uplink" Size="1" Pos="2"/>
-            <BitParameter Name="voice_downlink" Size="1" Pos="3"/>
-            <BitParameter Name="voice_call" Size="1" Pos="4"/>
-            <BitParameter Name="camcorder" Size="1" Pos="5"/>
-            <BitParameter Name="voice_recognition" Size="1" Pos="6"/>
-            <BitParameter Name="voice_communication" Size="1" Pos="7"/>
-            <BitParameter Name="remote_submix" Size="1" Pos="8"/>
-            <BitParameter Name="unprocessed" Size="1" Pos="9"/>
-            <BitParameter Name="fm_tuner" Size="1" Pos="10"/>
-            <BitParameter Name="hotword" Size="1" Pos="11"/>
-        </BitParameterBlock>
-    </ComponentType>
-
-    <!-- Routing Strategy definition as an enumeration. Numerical value must match the value
-         of the routing strategy in policy header file. -->
-    <ComponentType Name="Strategy">
-        <EnumParameter Name="strategy" Size="32">
-            <ValuePair Literal="media" Numerical="0"/>
-            <ValuePair Literal="phone" Numerical="1"/>
-            <ValuePair Literal="sonification" Numerical="2"/>
-            <ValuePair Literal="sonification_respectful" Numerical="3"/>
-            <ValuePair Literal="dtmf" Numerical="4"/>
-            <ValuePair Literal="enforced_audible" Numerical="5"/>
-            <ValuePair Literal="transmitted_through_speaker" Numerical="6"/>
-            <ValuePair Literal="accessibility" Numerical="7"/>
-            <ValuePair Literal="rerouting" Numerical="8"/>
-        </EnumParameter>
-    </ComponentType>
-
-    <!--#################### STRATEGY COMMON TYPES BEGIN ####################-->
-
-    <ComponentType Name="StrategyConfig" Mapping="Strategy:'%1'">
-        <Component Name="selected_output_devices" Type="OutputDevicesMask"/>
-    </ComponentType>
-
-    <!--#################### STRATEGY COMMON TYPES END ####################-->
-
-    <!--#################### STREAM COMMON TYPES BEGIN ####################-->
-
-    <ComponentType Name="VolumeProfileType">
-        <EnumParameter Name="volume_profile" Size="32">
-            <ValuePair Literal="voice_call" Numerical="0"/>
-            <ValuePair Literal="system" Numerical="1"/>
-            <ValuePair Literal="ring" Numerical="2"/>
-            <ValuePair Literal="music" Numerical="3"/>
-            <ValuePair Literal="alarm" Numerical="4"/>
-            <ValuePair Literal="notification" Numerical="5"/>
-            <ValuePair Literal="bluetooth_sco" Numerical="6"/>
-            <ValuePair Literal="enforced_audible" Numerical="7"/>
-            <ValuePair Literal="dtmf" Numerical="8"/>
-            <ValuePair Literal="tts" Numerical="9"/>
-            <ValuePair Literal="accessibility" Numerical="10"/>
-            <ValuePair Literal="rerouting" Numerical="11"/>
-            <ValuePair Literal="patch" Numerical="12"/>
-        </EnumParameter>
-    </ComponentType>
-
-    <ComponentType Name="Stream">
-        <Component Name="applicable_strategy" Type="Strategy"/>
-        <Component Name="applicable_volume_profile" Type="VolumeProfileType"
-                   Description="Volume profile followed by a given stream type."/>
-    </ComponentType>
-
-    <!--#################### STREAM COMMON TYPES END ####################-->
-
-    <!--#################### USAGE COMMON TYPES BEGIN ####################-->
-
-    <ComponentType Name="Usage">
-        <Component Name="applicable_strategy" Type="Strategy" Mapping="Usage:'%1'"/>
-    </ComponentType>
-
-    <!--#################### USAGE COMMON TYPES END ####################-->
-
-    <!--#################### INPUT SOURCE COMMON TYPES BEGIN ####################-->
-
-    <ComponentType Name="InputSource">
-        <Component Name="applicable_input_device" Type="InputDevicesMask"
-                   Mapping="InputSource:'%1'" Description="Selected Input device"/>
-    </ComponentType>
-
-    <!--#################### INPUT SOURCE COMMON TYPES END ####################-->
-
-</ComponentTypeSet>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem.xml
deleted file mode 100644
index ad9c356..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem.xml
+++ /dev/null
@@ -1,140 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Subsystem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-           xmlns:xi="http://www.w3.org/2001/XInclude"
-           xsi:noNamespaceSchemaLocation="Schemas/Subsystem.xsd"
-           Name="policy" Type="Policy">
-
-    <ComponentLibrary>
-        <!--#################### GLOBAL COMPONENTS BEGIN ####################-->
-        <!-- Common Types defintion -->
-        <xi:include href="PolicySubsystem-CommonTypes.xml"/>
-
-        <!--#################### GLOBAL COMPONENTS END ####################-->
-
-        <!--#################### STRATEGY BEGIN ####################-->
-
-        <ComponentType Name="Strategies" Description="Identifier must match the enum value to make
-                             the link between the PolicyManager and PFW">
-            <Component Name="media" Type="StrategyConfig" Mapping="Amend1:Media,Identifier:0"/>
-            <Component Name="phone" Type="StrategyConfig" Mapping="Amend1:Phone,Identifier:1"/>
-            <Component Name="sonification" Type="StrategyConfig"
-                                           Mapping="Amend1:Sonification,Identifier:2"/>
-            <Component Name="sonification_respectful" Type="StrategyConfig"
-                       Mapping="Amend1:SonificationRespectful,Identifier:3"/>
-            <Component Name="dtmf" Type="StrategyConfig" Mapping="Amend1:Dtmf,Identifier:4"/>
-            <Component Name="enforced_audible" Type="StrategyConfig"
-                                               Mapping="Amend1:EnforcedAudible,Identifier:5"/>
-            <Component Name="transmitted_through_speaker" Type="StrategyConfig"
-                       Mapping="Amend1:TransmittedThroughSpeaker,Identifier:6"/>
-            <Component Name="accessibility" Type="StrategyConfig"
-                                            Mapping="Amend1:Accessibility,Identifier:7"/>
-            <Component Name="rerouting" Type="StrategyConfig"
-                                        Mapping="Amend1:Rerouting,Identifier:8"/>
-        </ComponentType>
-
-        <!--#################### STRATEGY END ####################-->
-
-        <!--#################### STREAM BEGIN ####################-->
-
-        <ComponentType Name="Streams" Description="associated to audio_stream_type_t definition,
-                             identifier mapping must match the value of the enum">
-            <Component Name="voice_call" Type="Stream" Mapping="Stream:VoiceCall,Identifier:0"/>
-            <Component Name="system" Type="Stream" Mapping="Stream:System,Identifier:1"/>
-            <Component Name="ring" Type="Stream" Mapping="Stream:Ring,Identifier:2"/>
-            <Component Name="music" Type="Stream" Mapping="Stream:Music,Identifier:3"/>
-            <Component Name="alarm" Type="Stream" Mapping="Stream:Alarm,Identifier:4"/>
-            <Component Name="notification" Type="Stream"
-                                           Mapping="Stream:Notification,Identifier:5"/>
-            <Component Name="bluetooth_sco" Type="Stream"
-                                            Mapping="Stream:BluetoothSco,Identifier:6"/>
-            <Component Name="enforced_audible" Type="Stream"
-                                               Mapping="Stream:EnforceAudible,Identifier:7"
-                       Description="Sounds that cannot be muted by user and must
-                                    be routed to speaker"/>
-            <Component Name="dtmf" Type="Stream" Mapping="Stream:Dtmf,Identifier:8"/>
-            <Component Name="tts" Type="Stream" Mapping="Stream:Tts,Identifier:9"
-                             Description="Transmitted Through Speaker.
-                                          Plays over speaker only, silent on other devices"/>
-            <Component Name="accessibility" Type="Stream"
-                                            Mapping="Stream:Accessibility,Identifier:10"
-                             Description="For accessibility talk back prompts"/>
-            <Component Name="rerouting" Type="Stream" Mapping="Stream:Rerouting,Identifier:11"
-                             Description="For dynamic policy output mixes"/>
-            <Component Name="patch" Type="Stream" Mapping="Stream:Patch,Identifier:12"
-                             Description="For internal audio flinger tracks. Fixed volume"/>
-        </ComponentType>
-
-        <!--#################### STREAM END ####################-->
-
-        <!--#################### USAGE BEGIN ####################-->
-
-        <ComponentType Name="Usages" Description="associated to audio_usage_t definition,
-                             identifier mapping must match the value of the enum">
-            <Component Name="unknown" Type="Usage" Mapping="Amend1:Unknown,Identifier:0"/>
-            <Component Name="media" Type="Usage" Mapping="Amend1:Media,Identifier:1"/>
-            <Component Name="voice_communication" Type="Usage"
-                                                  Mapping="Amend1:VoiceCommunication,Identifier:2"/>
-            <Component Name="voice_communication_signalling" Type="Usage"
-                       Mapping="Amend1:VoiceCommunicationSignalling,Identifier:3"/>
-            <Component Name="alarm" Type="Usage" Mapping="Amend1:Alarm,Identifier:4"/>
-            <Component Name="notification" Type="Usage" Mapping="Amend1:Notification,Identifier:5"/>
-            <Component Name="notification_telephony_ringtone" Type="Usage"
-                       Mapping="Amend1:NotificationTelephonyRingtone,Identifier:6"/>
-            <Component Name="notification_communication_request" Type="Usage"
-                       Mapping="Amend1:NotificationCommunicationRequest,Identifier:7"/>
-            <Component Name="notification_communication_instant" Type="Usage"
-                       Mapping="Amend1:NotificationCommunicationInstant,Identifier:8"/>
-            <Component Name="notification_communication_delayed" Type="Usage"
-                       Mapping="Amend1:NotificationCommunicationDelated,Identifier:9"/>
-            <Component Name="notification_event" Type="Usage"
-                                                 Mapping="Amend1:NotificationEvent,Identifier:10"/>
-            <Component Name="assistance_accessibility" Type="Usage"
-                       Mapping="Amend1:AssistanceAccessibility,Identifier:11"/>
-            <Component Name="assistance_navigation_guidance" Type="Usage"
-                       Mapping="Amend1:AssistanceNavigationGuidance,Identifier:12"/>
-            <Component Name="assistance_sonification" Type="Usage"
-                       Mapping="Amend1:AssistanceSonification,Identifier:13"/>
-            <Component Name="game" Type="Usage" Mapping="Amend1:BluetoothSco,Identifier:14"/>
-            <Component Name="virtual_source" Type="Usage"
-                                             Mapping="Amend1:VirtualSource,Identifier:15"/>
-            <Component Name="assistant" Type="Usage" Mapping="Amend1:Assistant,Identifier:16"/>
-        </ComponentType>
-
-        <!--#################### USAGE END ####################-->
-
-        <!--#################### INPUT SOURCE BEGIN ####################-->
-
-        <ComponentType Name="InputSources" Description="associated to audio_source_t definition,
-                             identifier mapping must match the value of the enum">
-            <Component Name="default" Type="InputSource" Mapping="Amend1:Default,Identifier:0"/>
-            <Component Name="mic" Type="InputSource" Mapping="Amend1:Mic,Identifier:1"/>
-            <Component Name="voice_uplink" Type="InputSource"
-                                           Mapping="Amend1:VoiceUplink,Identifier:2"/>
-            <Component Name="voice_downlink" Type="InputSource"
-                                             Mapping="Amend1:VoiceDownlink,Identifier:3"/>
-            <Component Name="voice_call" Type="InputSource"
-                                         Mapping="Amend1:VoiceCall,Identifier:4"/>
-            <Component Name="camcorder" Type="InputSource" Mapping="Amend1:Camcorder,Identifier:5"/>
-            <Component Name="voice_recognition" Type="InputSource"
-                                                Mapping="Amend1:VoiceRecognition,Identifier:6"/>
-            <Component Name="voice_communication" Type="InputSource"
-                                                  Mapping="Amend1:VoiceCommunication,Identifier:7"/>
-            <Component Name="remote_submix" Type="InputSource"
-                                            Mapping="Amend1:RemoteSubmix,Identifier:8"/>
-            <Component Name="unprocessed" Type="InputSource"
-                                            Mapping="Amend1:Unprocessed,Identifier:9"/>
-            <Component Name="fm_tuner" Type="InputSource" Mapping="Amend1:FmTuner,Identifier:1998"/>
-            <Component Name="hotword" Type="InputSource" Mapping="Amend1:Hotword,Identifier:1999"/>
-        </ComponentType>
-
-        <!--#################### INPUT SOURCE END ####################-->
-
-    </ComponentLibrary>
-
-    <InstanceDefinition>
-        <Component Name="streams" Type="Streams"/>
-        <Component Name="strategies" Type="Strategies"/>
-        <Component Name="input_sources" Type="InputSources"/>
-        <Component Name="usages" Type="Usages"/>
-    </InstanceDefinition>
-</Subsystem>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicyClass.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/PolicyClass.xml
similarity index 100%
rename from services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicyClass.xml
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/PolicyClass.xml
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/PolicySubsystem-CommonTypes.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/PolicySubsystem-CommonTypes.xml
new file mode 100644
index 0000000..d17c021
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/PolicySubsystem-CommonTypes.xml
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ComponentTypeSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+              xmlns:xi="http://www.w3.org/2001/XInclude"
+              xsi:noNamespaceSchemaLocation="Schemas/ComponentTypeSet.xsd">
+    <!-- Output devices definition as a bitfield for the supported devices per output
+    profile. It must match with the output device enum parameter.
+    -->
+     <!--#################### GLOBAL COMPONENTS BEGIN ####################-->
+
+     <!--#################### GLOBAL COMPONENTS END ####################-->
+
+    <ComponentType Name="OutputDevicesMask" Description="32th bit is not allowed as dedicated
+                                                     for input devices detection">
+        <BitParameterBlock Name="mask" Size="32">
+            <BitParameter Name="earpiece" Size="1" Pos="0"/>
+            <BitParameter Name="speaker" Size="1" Pos="1"/>
+            <BitParameter Name="wired_headset" Size="1" Pos="2"/>
+            <BitParameter Name="wired_headphone" Size="1" Pos="3"/>
+            <BitParameter Name="bluetooth_sco" Size="1" Pos="4"/>
+            <BitParameter Name="bluetooth_sco_headset" Size="1" Pos="5"/>
+            <BitParameter Name="bluetooth_sco_carkit" Size="1" Pos="6"/>
+            <BitParameter Name="bluetooth_a2dp" Size="1" Pos="7"/>
+            <BitParameter Name="bluetooth_a2dp_headphones" Size="1" Pos="8"/>
+            <BitParameter Name="bluetooth_a2dp_speaker" Size="1" Pos="9"/>
+            <BitParameter Name="hdmi" Size="1" Pos="10"/>
+            <BitParameter Name="angl_dock_headset" Size="1" Pos="11"/>
+            <BitParameter Name="dgtl_dock_headset" Size="1" Pos="12"/>
+            <BitParameter Name="usb_accessory" Size="1" Pos="13"/>
+            <BitParameter Name="usb_device" Size="1" Pos="14"/>
+            <BitParameter Name="remote_submix" Size="1" Pos="15"/>
+            <BitParameter Name="telephony_tx" Size="1" Pos="16"/>
+            <BitParameter Name="line" Size="1" Pos="17"/>
+            <BitParameter Name="hdmi_arc" Size="1" Pos="18"/>
+            <BitParameter Name="spdif" Size="1" Pos="19"/>
+            <BitParameter Name="fm" Size="1" Pos="20"/>
+            <BitParameter Name="aux_line" Size="1" Pos="21"/>
+            <BitParameter Name="speaker_safe" Size="1" Pos="22"/>
+            <BitParameter Name="ip" Size="1" Pos="23"/>
+            <BitParameter Name="bus" Size="1" Pos="24"/>
+            <BitParameter Name="proxy" Size="1" Pos="25"/>
+            <BitParameter Name="usb_headset" Size="1" Pos="26"/>
+            <BitParameter Name="hearing_aid" Size="1" Pos="27"/>
+            <BitParameter Name="echo_canceller" Size="1" Pos="28"/>
+            <BitParameter Name="stub" Size="1" Pos="30"/>
+        </BitParameterBlock>
+    </ComponentType>
+
+    <!-- Input devices definition as a bitfield for the supported devices per Input
+    profile. It must match with the Input device enum parameter.
+    -->
+    <ComponentType Name="InputDevicesMask">
+        <BitParameterBlock Name="mask" Size="32">
+            <BitParameter Name="communication" Size="1" Pos="0"/>
+            <BitParameter Name="ambient" Size="1" Pos="1"/>
+            <BitParameter Name="builtin_mic" Size="1" Pos="2"/>
+            <BitParameter Name="bluetooth_sco_headset" Size="1" Pos="3"/>
+            <BitParameter Name="wired_headset" Size="1" Pos="4"/>
+            <BitParameter Name="hdmi" Size="1" Pos="5"/>
+            <BitParameter Name="telephony_rx" Size="1" Pos="6"/>
+            <BitParameter Name="back_mic" Size="1" Pos="7"/>
+            <BitParameter Name="remote_submix" Size="1" Pos="8"/>
+            <BitParameter Name="anlg_dock_headset" Size="1" Pos="9"/>
+            <BitParameter Name="dgtl_dock_headset" Size="1" Pos="10"/>
+            <BitParameter Name="usb_accessory" Size="1" Pos="11"/>
+            <BitParameter Name="usb_device" Size="1" Pos="12"/>
+            <BitParameter Name="fm_tuner" Size="1" Pos="13"/>
+            <BitParameter Name="tv_tuner" Size="1" Pos="14"/>
+            <BitParameter Name="line" Size="1" Pos="15"/>
+            <BitParameter Name="spdif" Size="1" Pos="16"/>
+            <BitParameter Name="bluetooth_a2dp" Size="1" Pos="17"/>
+            <BitParameter Name="loopback" Size="1" Pos="18"/>
+            <BitParameter Name="ip" Size="1" Pos="19"/>
+            <BitParameter Name="bus" Size="1" Pos="20"/>
+            <BitParameter Name="proxy" Size="1" Pos="21"/>
+            <BitParameter Name="usb_headset" Size="1" Pos="22"/>
+            <BitParameter Name="bluetooth_ble" Size="1" Pos="23"/>
+            <BitParameter Name="hdmi_arc" Size="1" Pos="24"/>
+            <BitParameter Name="echo_reference" Size="1" Pos="25"/>
+            <BitParameter Name="stub" Size="1" Pos="30"/>
+        </BitParameterBlock>
+    </ComponentType>
+
+    <ComponentType Name="OutputFlags"
+                   Description="the audio output flags serve two purposes:
+                    - when an AudioTrack is created they indicate a wish to be connected to an
+                      output stream with attributes corresponding to the specified flags.
+                    - when present in an output profile descriptor listed for a particular audio
+                      hardware module, they indicate that an output stream can be opened that
+                      supports the attributes indicated by the flags.
+                    The audio policy manager will try to match the flags in the request
+                    (when getOuput() is called) to an available output stream.">
+        <BitParameterBlock Name="mask" Size="32">
+            <BitParameter Name="direct" Size="1" Pos="0"/>
+            <BitParameter Name="primary" Size="1" Pos="1"/>
+            <BitParameter Name="fast" Size="1" Pos="2"/>
+            <BitParameter Name="deep_buffer" Size="1" Pos="3"/>
+            <BitParameter Name="compress_offload" Size="1" Pos="4"/>
+            <BitParameter Name="non_blocking" Size="1" Pos="5"/>
+            <BitParameter Name="hw_av_sync" Size="1" Pos="6"/>
+            <BitParameter Name="tts" Size="1" Pos="7"/>
+            <BitParameter Name="raw" Size="1" Pos="8"/>
+            <BitParameter Name="sync" Size="1" Pos="9"/>
+            <BitParameter Name="iec958_nonaudio" Size="1" Pos="10"/>
+        </BitParameterBlock>
+    </ComponentType>
+
+    <ComponentType Name="InputFlags"
+                   Description="The audio input flags are analogous to audio output flags.
+                                Currently they are used only when an AudioRecord is created,
+                                to indicate a preference to be connected to an input stream with
+                                attributes corresponding to the specified flags.">
+        <BitParameterBlock Name="mask" Size="32">
+            <BitParameter Name="fast" Size="1" Pos="0"/>
+            <BitParameter Name="hw_hotword" Size="1" Pos="2"/>
+            <BitParameter Name="raw" Size="1" Pos="3"/>
+            <BitParameter Name="sync" Size="1" Pos="4"/>
+        </BitParameterBlock>
+    </ComponentType>
+
+    <ComponentType Name="InputSourcesMask" Description="The audio input source is also known
+                                                        as the use case.">
+        <BitParameterBlock Name="mask" Size="32">
+            <BitParameter Name="default" Size="1" Pos="0"/>
+            <BitParameter Name="mic" Size="1" Pos="1"/>
+            <BitParameter Name="voice_uplink" Size="1" Pos="2"/>
+            <BitParameter Name="voice_downlink" Size="1" Pos="3"/>
+            <BitParameter Name="voice_call" Size="1" Pos="4"/>
+            <BitParameter Name="camcorder" Size="1" Pos="5"/>
+            <BitParameter Name="voice_recognition" Size="1" Pos="6"/>
+            <BitParameter Name="voice_communication" Size="1" Pos="7"/>
+            <BitParameter Name="remote_submix" Size="1" Pos="8"/>
+            <BitParameter Name="unprocessed" Size="1" Pos="9"/>
+            <BitParameter Name="voice_performance" Size="1" Pos="10"/>
+            <BitParameter Name="echo_reference" Size="1" Pos="11"/>
+            <BitParameter Name="fm_tuner" Size="1" Pos="12"/>
+            <BitParameter Name="hotword" Size="1" Pos="13"/>
+        </BitParameterBlock>
+    </ComponentType>
+
+    <!--#################### STREAM COMMON TYPES BEGIN ####################-->
+
+    <ComponentType Name="VolumeProfileType">
+        <EnumParameter Name="volume_profile" Size="32">
+            <ValuePair Literal="voice_call" Numerical="0"/>
+            <ValuePair Literal="system" Numerical="1"/>
+            <ValuePair Literal="ring" Numerical="2"/>
+            <ValuePair Literal="music" Numerical="3"/>
+            <ValuePair Literal="alarm" Numerical="4"/>
+            <ValuePair Literal="notification" Numerical="5"/>
+            <ValuePair Literal="bluetooth_sco" Numerical="6"/>
+            <ValuePair Literal="enforced_audible" Numerical="7"/>
+            <ValuePair Literal="dtmf" Numerical="8"/>
+            <ValuePair Literal="tts" Numerical="9"/>
+            <ValuePair Literal="accessibility" Numerical="10"/>
+            <ValuePair Literal="rerouting" Numerical="11"/>
+            <ValuePair Literal="patch" Numerical="12"/>
+        </EnumParameter>
+    </ComponentType>
+
+    <ComponentType Name="Stream"  Mapping="Stream">
+        <Component Name="applicable_volume_profile" Type="VolumeProfileType"
+                   Description="Volume profile followed by a given stream type."/>
+    </ComponentType>
+
+    <!--#################### STREAM COMMON TYPES END ####################-->
+
+    <!--#################### INPUT SOURCE COMMON TYPES BEGIN ####################-->
+
+    <ComponentType Name="InputSource">
+        <Component Name="applicable_input_device" Type="InputDevicesMask"
+                   Mapping="InputSource" Description="Selected Input device"/>
+    </ComponentType>
+
+    <!--#################### INPUT SOURCE COMMON TYPES END ####################-->
+
+    <!--#################### PRODUCT STRATEGY COMMON TYPES BEGIN ####################-->
+
+    <ComponentType Name="ProductStrategy" Mapping="ProductStrategy">
+        <Component Name="selected_output_devices" Type="OutputDevicesMask"/>
+        <StringParameter Name="device_address" MaxLength="256"
+                         Description="if any, device address associated"/>
+    </ComponentType>
+
+    <!--#################### PRODUCT STRATEGY COMMON TYPES END ####################-->
+
+</ComponentTypeSet>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/PolicySubsystem-no-strategy.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/PolicySubsystem-no-strategy.xml
new file mode 100644
index 0000000..a4e7537
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/PolicySubsystem-no-strategy.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Subsystem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+           xmlns:xi="http://www.w3.org/2001/XInclude"
+           xsi:noNamespaceSchemaLocation="Schemas/Subsystem.xsd"
+           Name="policy" Type="Policy">
+
+    <ComponentLibrary>
+        <!--#################### GLOBAL COMPONENTS BEGIN ####################-->
+        <!-- Common Types defintion -->
+        <xi:include href="PolicySubsystem-CommonTypes.xml"/>
+
+        <!--#################### GLOBAL COMPONENTS END ####################-->
+
+        <!--#################### STREAM BEGIN ####################-->
+
+        <ComponentType Name="Streams" Description="associated to audio_stream_type_t definition">
+            <Component Name="voice_call" Type="Stream" Mapping="Name:AUDIO_STREAM_VOICE_CALL"/>
+            <Component Name="system" Type="Stream" Mapping="Name:AUDIO_STREAM_SYSTEM"/>
+            <Component Name="ring" Type="Stream" Mapping="Name:AUDIO_STREAM_RING"/>
+            <Component Name="music" Type="Stream" Mapping="Name:AUDIO_STREAM_MUSIC"/>
+            <Component Name="alarm" Type="Stream" Mapping="Name:AUDIO_STREAM_ALARM"/>
+            <Component Name="notification" Type="Stream" Mapping="Name:AUDIO_STREAM_NOTIFICATION"/>
+            <Component Name="bluetooth_sco" Type="Stream" Mapping="Name:AUDIO_STREAM_BLUETOOTH_SCO"/>
+            <Component Name="enforced_audible" Type="Stream" Mapping="Name:AUDIO_STREAM_ENFORCED_AUDIBLE"
+                       Description="Sounds that cannot be muted by user and must be routed to speaker"/>
+            <Component Name="dtmf" Type="Stream" Mapping="Name:AUDIO_STREAM_DTMF"/>
+            <Component Name="tts" Type="Stream" Mapping="Name:AUDIO_STREAM_TTS"
+                             Description="Transmitted Through Speaker. Plays over speaker only, silent on other devices"/>
+            <Component Name="accessibility" Type="Stream" Mapping="Name:AUDIO_STREAM_ACCESSIBILITY"
+                             Description="For accessibility talk back prompts"/>
+            <Component Name="rerouting" Type="Stream" Mapping="Name:AUDIO_STREAM_REROUTING"
+                             Description="For dynamic policy output mixes"/>
+            <Component Name="patch" Type="Stream" Mapping="Name:AUDIO_STREAM_PATCH"
+                             Description="For internal audio flinger tracks. Fixed volume"/>
+        </ComponentType>
+
+        <!--#################### STREAM END ####################-->
+
+        <!--#################### INPUT SOURCE BEGIN ####################-->
+
+        <ComponentType Name="InputSources" Description="associated to audio_source_t definition,
+                             identifier mapping must match the value of the enum">
+            <Component Name="default" Type="InputSource" Mapping="Name:AUDIO_SOURCE_DEFAULT"/>
+            <Component Name="mic" Type="InputSource" Mapping="Name:AUDIO_SOURCE_MIC"/>
+            <Component Name="voice_uplink" Type="InputSource"
+                                           Mapping="Name:AUDIO_SOURCE_VOICE_UPLINK"/>
+            <Component Name="voice_downlink" Type="InputSource"
+                                             Mapping="Name:AUDIO_SOURCE_VOICE_DOWNLINK"/>
+            <Component Name="voice_call" Type="InputSource"
+                                         Mapping="Name:AUDIO_SOURCE_VOICE_CALL"/>
+            <Component Name="camcorder" Type="InputSource" Mapping="Name:AUDIO_SOURCE_CAMCORDER"/>
+            <Component Name="voice_recognition" Type="InputSource"
+                                                Mapping="Name:AUDIO_SOURCE_VOICE_RECOGNITION"/>
+            <Component Name="voice_communication" Type="InputSource"
+                                                  Mapping="Name:AUDIO_SOURCE_VOICE_COMMUNICATION"/>
+            <Component Name="remote_submix" Type="InputSource"
+                                            Mapping="Name:AUDIO_SOURCE_REMOTE_SUBMIX"/>
+            <Component Name="unprocessed" Type="InputSource"
+                                            Mapping="Name:AUDIO_SOURCE_UNPROCESSED"/>
+            <Component Name="fm_tuner" Type="InputSource" Mapping="Name:AUDIO_SOURCE_FM_TUNER"/>
+            <Component Name="hotword" Type="InputSource" Mapping="Name:AUDIO_SOURCE_HOTWORD"/>
+        </ComponentType>
+
+        <!--#################### INPUT SOURCE END ####################-->
+
+    </ComponentLibrary>
+
+    <InstanceDefinition>
+        <Component Name="streams" Type="Streams"/>
+        <Component Name="input_sources" Type="InputSources"/>
+    </InstanceDefinition>
+</Subsystem>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/PolicySubsystem.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/PolicySubsystem.xml
new file mode 100644
index 0000000..b55ce2c
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/PolicySubsystem.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<Subsystem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+           xmlns:xi="http://www.w3.org/2001/XInclude"
+           xsi:noNamespaceSchemaLocation="Schemas/Subsystem.xsd"
+           Name="policy" Type="Policy">
+
+    <ComponentLibrary>
+        <!--#################### GLOBAL COMPONENTS BEGIN ####################-->
+        <!-- Common Types defintion -->
+        <xi:include href="PolicySubsystem-CommonTypes.xml"/>
+        <xi:include href="ProductStrategies.xml"/>
+
+
+        <!--#################### GLOBAL COMPONENTS END ####################-->
+
+        <!--#################### STREAM BEGIN ####################-->
+
+        <ComponentType Name="Streams" Description="associated to audio_stream_type_t definition">
+            <Component Name="voice_call" Type="Stream" Mapping="Name:AUDIO_STREAM_VOICE_CALL"/>
+            <Component Name="system" Type="Stream" Mapping="Name:AUDIO_STREAM_SYSTEM"/>
+            <Component Name="ring" Type="Stream" Mapping="Name:AUDIO_STREAM_RING"/>
+            <Component Name="music" Type="Stream" Mapping="Name:AUDIO_STREAM_MUSIC"/>
+            <Component Name="alarm" Type="Stream" Mapping="Name:AUDIO_STREAM_ALARM"/>
+            <Component Name="notification" Type="Stream" Mapping="Name:AUDIO_STREAM_NOTIFICATION"/>
+            <Component Name="bluetooth_sco" Type="Stream" Mapping="Name:AUDIO_STREAM_BLUETOOTH_SCO"/>
+            <Component Name="enforced_audible" Type="Stream" Mapping="Name:AUDIO_STREAM_ENFORCED_AUDIBLE"
+                       Description="Sounds that cannot be muted by user and must be routed to speaker"/>
+            <Component Name="dtmf" Type="Stream" Mapping="Name:AUDIO_STREAM_DTMF"/>
+            <Component Name="tts" Type="Stream" Mapping="Name:AUDIO_STREAM_TTS"
+                             Description="Transmitted Through Speaker. Plays over speaker only, silent on other devices"/>
+            <Component Name="accessibility" Type="Stream" Mapping="Name:AUDIO_STREAM_ACCESSIBILITY"
+                             Description="For accessibility talk back prompts"/>
+            <Component Name="rerouting" Type="Stream" Mapping="Name:AUDIO_STREAM_REROUTING"
+                             Description="For dynamic policy output mixes"/>
+            <Component Name="patch" Type="Stream" Mapping="Name:AUDIO_STREAM_PATCH"
+                             Description="For internal audio flinger tracks. Fixed volume"/>
+        </ComponentType>
+
+        <!--#################### STREAM END ####################-->
+
+        <!--#################### INPUT SOURCE BEGIN ####################-->
+
+        <ComponentType Name="InputSources" Description="associated to audio_source_t definition,
+                             identifier mapping must match the value of the enum">
+            <Component Name="default" Type="InputSource" Mapping="Name:AUDIO_SOURCE_DEFAULT"/>
+            <Component Name="mic" Type="InputSource" Mapping="Name:AUDIO_SOURCE_MIC"/>
+            <Component Name="voice_uplink" Type="InputSource"
+                                           Mapping="Name:AUDIO_SOURCE_VOICE_UPLINK"/>
+            <Component Name="voice_downlink" Type="InputSource"
+                                             Mapping="Name:AUDIO_SOURCE_VOICE_DOWNLINK"/>
+            <Component Name="voice_call" Type="InputSource"
+                                         Mapping="Name:AUDIO_SOURCE_VOICE_CALL"/>
+            <Component Name="camcorder" Type="InputSource" Mapping="Name:AUDIO_SOURCE_CAMCORDER"/>
+            <Component Name="voice_recognition" Type="InputSource"
+                                                Mapping="Name:AUDIO_SOURCE_VOICE_RECOGNITION"/>
+            <Component Name="voice_communication" Type="InputSource"
+                                                  Mapping="Name:AUDIO_SOURCE_VOICE_COMMUNICATION"/>
+            <Component Name="remote_submix" Type="InputSource"
+                                            Mapping="Name:AUDIO_SOURCE_REMOTE_SUBMIX"/>
+            <Component Name="unprocessed" Type="InputSource"
+                                            Mapping="Name:AUDIO_SOURCE_UNPROCESSED"/>
+            <Component Name="fm_tuner" Type="InputSource" Mapping="Name:AUDIO_SOURCE_FM_TUNER"/>
+            <Component Name="hotword" Type="InputSource" Mapping="Name:AUDIO_SOURCE_HOTWORD"/>
+        </ComponentType>
+
+        <!--#################### INPUT SOURCE END ####################-->
+    </ComponentLibrary>
+
+    <InstanceDefinition>
+        <Component Name="streams" Type="Streams"/>
+        <Component Name="input_sources" Type="InputSources"/>
+        <Component Name="product_strategies" Type="ProductStrategies"/>
+    </InstanceDefinition>
+</Subsystem>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/ProductStrategies.xml.in b/services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/ProductStrategies.xml.in
new file mode 100644
index 0000000..2760b25
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/ProductStrategies.xml.in
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<ComponentTypeSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+              xmlns:xi="http://www.w3.org/2001/XInclude"
+              xsi:noNamespaceSchemaLocation="Schemas/ComponentTypeSet.xsd">
+
+  <!-- automatically populate the strategy structure plugin file from Engine Configuration XML file
+        Component Name="xxx" Type="ProductStrategy"/-->
+  <ComponentType Name="ProductStrategies" Description="">
+  </ComponentType>
+
+</ComponentTypeSet>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/policy_criteria.txt b/services/audiopolicy/engineconfigurable/parameter-framework/examples/policy_criteria.txt
deleted file mode 100644
index 480cbe1..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/policy_criteria.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-ExclusiveCriterion TelephonyMode                :   Normal          RingTone                InCall              InCommunication
-InclusiveCriterion AvailableInputDevices        :   Communication Ambient BuiltinMic BluetoothScoHeadset WiredHeadset Hdmi TelephonyRx BackMic RemoteSubmix AnlgDockHeadset DgtlDockHeadset UsbAccessory UsbDevice FmTuner TvTuner Line Spdif BluetoothA2dp Loopback Ip Bus Stub
-InclusiveCriterion AvailableOutputDevices       :   Earpiece Speaker WiredSpeaker WiredHeadset WiredHeadphone BluetoothSco BluetoothScoHeadset BluetoothScoCarkit BluetoothA2dp BluetoothA2dpHeadphones BluetoothA2dpSpeaker Hdmi AnlgDockHeadset DgtlDockHeadset UsbAccessory UsbDevice RemoteSubmix TelephonyTx Line HdmiArc Spdif Fm AuxLine SpeakerSafe Ip Bus Stub
-ExclusiveCriterion ForceUseForCommunication     :   ForceNone       ForceSpeaker            ForceBtSco
-ExclusiveCriterion ForceUseForMedia             :   ForceNone       ForceSpeaker			ForceHeadphones         ForceBtA2dp         ForceWiredAccessory ForceAnalogDock ForceDigitalDock    ForceNoBtA2dp       ForceSystemEnforced
-ExclusiveCriterion ForceUseForRecord            :   ForceNone       ForceBtSco              ForceWiredAccessory
-ExclusiveCriterion ForceUseForDock              :   ForceNone       ForceWiredAccessory     ForceBtCarDock      ForceBtDeskDock     ForceAnalogDock ForceDigitalDock
-ExclusiveCriterion ForceUseForSystem            :   ForceNone       ForceSystemEnforced
-ExclusiveCriterion ForceUseForHdmiSystemAudio   :   ForceNone       ForceHdmiSystemEnforced
-ExclusiveCriterion ForceUseForEncodedSurround   :   ForceNone       ForceEncodedSurroundNever   ForceEncodedSurroundAlways
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.bp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.bp
new file mode 100644
index 0000000..2685c6d
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.bp
@@ -0,0 +1,36 @@
+cc_library_shared {
+    name: "libpolicy-subsystem",
+    srcs: [
+        "PolicySubsystemBuilder.cpp",
+        "PolicySubsystem.cpp",
+        "InputSource.cpp",
+        "Stream.cpp",
+        "ProductStrategy.cpp",
+    ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+        "-fvisibility-inlines-hidden",
+        "-fvisibility=hidden",
+    ],
+    header_libs: [
+        "libbase_headers",
+        "libaudiopolicycommon",
+        "libaudioclient_headers",
+        "libaudiopolicyengine_interface_headers",
+        "libaudiopolicyengineconfigurable_interface_headers",
+    ],
+    static_libs: [
+        "libaudiopolicycomponents",
+        "libaudiopolicyengine_common",
+        "libpfw_utility",
+    ],
+    shared_libs: [
+        "libaudiopolicyengineconfigurable",
+        "liblog",
+        "libutils",
+        "libmedia_helper",
+        "libparameter"
+    ],
+}
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk
deleted file mode 100644
index 3559cf1..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk
+++ /dev/null
@@ -1,42 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-ifneq ($(USE_CUSTOM_PARAMETER_FRAMEWORK), true)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := \
-    PolicySubsystemBuilder.cpp \
-    PolicySubsystem.cpp \
-    Strategy.cpp \
-    InputSource.cpp \
-    Stream.cpp \
-    Usage.cpp
-
-LOCAL_CFLAGS += \
-    -Wall \
-    -Werror \
-    -Wextra \
-    -fvisibility-inlines-hidden \
-    -fvisibility=hidden
-
-LOCAL_C_INCLUDES := \
-    frameworks/av/services/audiopolicy/common/include \
-    frameworks/av/services/audiopolicy/engineconfigurable/include \
-    frameworks/av/services/audiopolicy/engineconfigurable/interface \
-
-LOCAL_SHARED_LIBRARIES := \
-    libaudiopolicyengineconfigurable  \
-    libparameter \
-    liblog \
-
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
-LOCAL_STATIC_LIBRARIES := libpfw_utility
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := libpolicy-subsystem
-
-include $(BUILD_SHARED_LIBRARY)
-
-endif # ifneq ($(USE_CUSTOM_PARAMETER_FRAMEWORK), true)
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/InputSource.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/InputSource.cpp
index eac4efe..f91f8d7 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/InputSource.cpp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/InputSource.cpp
@@ -17,6 +17,7 @@
 #include "InputSource.h"
 #include "PolicyMappingKeys.h"
 #include "PolicySubsystem.h"
+#include <media/TypeConverter.h>
 
 using std::string;
 
@@ -33,9 +34,13 @@
                            instanceConfigurableElement->getBelongingSubsystem())),
       mPolicyPluginInterface(mPolicySubsystem->getPolicyPluginInterface())
 {
-    mId = static_cast<audio_source_t>(context.getItemAsInteger(MappingKeyIdentifier));
+    std::string name(context.getItem(MappingKeyName));
+
+    if(not android::SourceTypeConverter::fromString(name, mId)) {
+        LOG_ALWAYS_FATAL("Invalid Input Source name: %s, invalid XML structure file", name.c_str());
+    }
     // Declares the strategy to audio policy engine
-    mPolicyPluginInterface->addInputSource(getFormattedMappingValue(), mId);
+    mPolicyPluginInterface->addInputSource(name, mId);
 }
 
 bool InputSource::sendToHW(string & /*error*/)
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.cpp
index 98d10a9..8bd7f66 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.cpp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.cpp
@@ -17,10 +17,9 @@
 #include "PolicySubsystem.h"
 #include "SubsystemObjectFactory.h"
 #include "PolicyMappingKeys.h"
-#include "Strategy.h"
 #include "Stream.h"
 #include "InputSource.h"
-#include "Usage.h"
+#include "ProductStrategy.h"
 #include <AudioPolicyPluginInterface.h>
 #include <AudioPolicyEngineInstance.h>
 #include <utils/Log.h>
@@ -36,9 +35,8 @@
 
 
 const char *const PolicySubsystem::mStreamComponentName = "Stream";
-const char *const PolicySubsystem::mStrategyComponentName = "Strategy";
 const char *const PolicySubsystem::mInputSourceComponentName = "InputSource";
-const char *const PolicySubsystem::mUsageComponentName = "Usage";
+const char *const PolicySubsystem::mProductStrategyComponentName = "ProductStrategy";
 
 PolicySubsystem::PolicySubsystem(const std::string &name, core::log::Logger &logger)
     : CSubsystem(name, logger),
@@ -65,22 +63,16 @@
     addSubsystemObjectFactory(
         new TSubsystemObjectFactory<Stream>(
             mStreamComponentName,
-            (1 << MappingKeyIdentifier))
-        );
-    addSubsystemObjectFactory(
-        new TSubsystemObjectFactory<Strategy>(
-            mStrategyComponentName,
-            (1 << MappingKeyAmend1) | (1 << MappingKeyIdentifier))
-        );
-    addSubsystemObjectFactory(
-        new TSubsystemObjectFactory<Usage>(
-            mUsageComponentName,
-            (1 << MappingKeyAmend1) | (1 << MappingKeyIdentifier))
+            (1 << MappingKeyName))
         );
     addSubsystemObjectFactory(
         new TSubsystemObjectFactory<InputSource>(
             mInputSourceComponentName,
-            (1 << MappingKeyAmend1) | (1 << MappingKeyIdentifier))
+            (1 << MappingKeyName))
+        );
+    addSubsystemObjectFactory(
+        new TSubsystemObjectFactory<ProductStrategy>(
+            mProductStrategyComponentName, (1 << MappingKeyName))
         );
 }
 
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.h b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.h
index 822eeb9..9bf1c23 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.h
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.h
@@ -53,7 +53,6 @@
     static const char *const mKeyAmend3; /**< amend3 key mapping string. */
 
     static const char *const mStreamComponentName;
-    static const char *const mStrategyComponentName;
     static const char *const mInputSourceComponentName;
-    static const char *const mUsageComponentName;
+    static const char *const mProductStrategyComponentName;
 };
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/ProductStrategy.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/ProductStrategy.cpp
new file mode 100644
index 0000000..ebd9456
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/ProductStrategy.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ProductStrategy.h"
+#include "PolicyMappingKeys.h"
+#include "PolicySubsystem.h"
+
+using std::string;
+using android::product_strategy_t;
+
+ProductStrategy::ProductStrategy(const string &mappingValue,
+                   CInstanceConfigurableElement *instanceConfigurableElement,
+                   const CMappingContext &context,
+                   core::log::Logger& logger)
+    : CFormattedSubsystemObject(instanceConfigurableElement,
+                                logger,
+                                mappingValue,
+                                MappingKeyAmend1,
+                                (MappingKeyAmendEnd - MappingKeyAmend1 + 1),
+                                context)
+{
+    std::string name(context.getItem(MappingKeyName));
+
+    ALOG_ASSERT(instanceConfigurableElement != nullptr, "Invalid Configurable Element");
+    mPolicySubsystem = static_cast<const PolicySubsystem *>(
+                instanceConfigurableElement->getBelongingSubsystem());
+    ALOG_ASSERT(mPolicySubsystem != nullptr, "Invalid Policy Subsystem");
+
+    mPolicyPluginInterface = mPolicySubsystem->getPolicyPluginInterface();
+    ALOG_ASSERT(mPolicyPluginInterface != nullptr, "Invalid Policy Plugin Interface");
+
+    mId = mPolicyPluginInterface->getProductStrategyByName(name);
+
+    ALOG_ASSERT(mId != PRODUCT_STRATEGY_INVALID, "Product Strategy %s not found", name.c_str());
+
+    ALOGE("Product Strategy %s added", name.c_str());
+}
+
+bool ProductStrategy::sendToHW(string & /*error*/)
+{
+    Device deviceParams;
+    blackboardRead(&deviceParams, sizeof(deviceParams));
+
+    mPolicyPluginInterface->setDeviceTypesForProductStrategy(mId, deviceParams.applicableDevice);
+    mPolicyPluginInterface->setDeviceAddressForProductStrategy(mId, deviceParams.deviceAddress);
+    return true;
+}
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/ProductStrategy.h b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/ProductStrategy.h
new file mode 100644
index 0000000..244f082
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/ProductStrategy.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "FormattedSubsystemObject.h"
+#include "InstanceConfigurableElement.h"
+#include "MappingContext.h"
+#include <AudioPolicyPluginInterface.h>
+#include <policy.h>
+#include <string>
+
+class PolicySubsystem;
+
+class ProductStrategy : public CFormattedSubsystemObject
+{
+private:
+    static const uint32_t mMaxStringSize = 257; /**< max string size (plus zero terminal). */
+
+    struct Device
+    {
+        uint32_t applicableDevice; /**< applicable device for this strategy. */
+        char deviceAddress[mMaxStringSize]; /**< device address associated with this strategy. */
+    } __attribute__((packed));
+
+public:
+    ProductStrategy(const std::string &mappingValue,
+             CInstanceConfigurableElement *instanceConfigurableElement,
+             const CMappingContext &context,
+             core::log::Logger& logger);
+
+protected:
+    virtual bool sendToHW(std::string &error);
+
+private:
+    const PolicySubsystem *mPolicySubsystem; /**< Route subsytem plugin. */
+
+    android::product_strategy_t mId;
+
+    /**
+     * Interface to communicate with Audio Policy Engine.
+     */
+    android::AudioPolicyPluginInterface *mPolicyPluginInterface;
+};
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.cpp
deleted file mode 100644
index 746c3a8..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "Strategy.h"
-#include "PolicyMappingKeys.h"
-#include "PolicySubsystem.h"
-
-using std::string;
-using android::routing_strategy;
-
-Strategy::Strategy(const string &mappingValue,
-                   CInstanceConfigurableElement *instanceConfigurableElement,
-                   const CMappingContext &context,
-                   core::log::Logger& logger)
-    : CFormattedSubsystemObject(instanceConfigurableElement,
-                                logger,
-                                mappingValue,
-                                MappingKeyAmend1,
-                                (MappingKeyAmendEnd - MappingKeyAmend1 + 1),
-                                context),
-      mPolicySubsystem(static_cast<const PolicySubsystem *>(
-                           instanceConfigurableElement->getBelongingSubsystem())),
-      mPolicyPluginInterface(mPolicySubsystem->getPolicyPluginInterface())
-{
-    mId = static_cast<routing_strategy>(context.getItemAsInteger(MappingKeyIdentifier));
-
-    // Declares the strategy to audio policy engine
-    mPolicyPluginInterface->addStrategy(getFormattedMappingValue(), mId);
-}
-
-bool Strategy::sendToHW(string & /*error*/)
-{
-    uint32_t applicableOutputDevice;
-    blackboardRead(&applicableOutputDevice, sizeof(applicableOutputDevice));
-    return mPolicyPluginInterface->setDeviceForStrategy(mId, applicableOutputDevice);
-}
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.h b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.h
deleted file mode 100644
index c02b82c..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "FormattedSubsystemObject.h"
-#include "InstanceConfigurableElement.h"
-#include "MappingContext.h"
-#include <AudioPolicyPluginInterface.h>
-#include <string>
-
-class PolicySubsystem;
-
-class Strategy : public CFormattedSubsystemObject
-{
-public:
-    Strategy(const std::string &mappingValue,
-             CInstanceConfigurableElement *instanceConfigurableElement,
-             const CMappingContext &context,
-             core::log::Logger& logger);
-
-protected:
-    virtual bool sendToHW(std::string &error);
-
-private:
-    const PolicySubsystem *mPolicySubsystem; /**< Route subsytem plugin. */
-
-    /**
-     * Interface to communicate with Audio Policy Engine.
-     */
-    android::AudioPolicyPluginInterface *mPolicyPluginInterface;
-
-    android::routing_strategy mId; /**< strategy identifier to link with audio.h.*/
-};
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.cpp
index c642a23..5230e0e 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.cpp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.cpp
@@ -17,9 +17,9 @@
 #include "Stream.h"
 #include "PolicyMappingKeys.h"
 #include "PolicySubsystem.h"
+#include <media/TypeConverter.h>
 
 using std::string;
-using android::routing_strategy;
 
 Stream::Stream(const string &/*mappingValue*/,
                CInstanceConfigurableElement *instanceConfigurableElement,
@@ -29,10 +29,14 @@
                            instanceConfigurableElement->getBelongingSubsystem())),
       mPolicyPluginInterface(mPolicySubsystem->getPolicyPluginInterface())
 {
-    mId = static_cast<audio_stream_type_t>(context.getItemAsInteger(MappingKeyIdentifier));
+    std::string name(context.getItem(MappingKeyName));
+
+    if (not android::StreamTypeConverter::fromString(name, mId)) {
+        LOG_ALWAYS_FATAL("Invalid Stream type name: %s, invalid XML structure file", name.c_str());
+    }
 
     // Declares the strategy to audio policy engine
-    mPolicyPluginInterface->addStream(getFormattedMappingValue(), mId);
+    mPolicyPluginInterface->addStream(name, mId);
 }
 
 bool Stream::sendToHW(string & /*error*/)
@@ -40,11 +44,8 @@
     Applicable params;
     blackboardRead(&params, sizeof(params));
 
-    mPolicyPluginInterface->setStrategyForStream(mId,
-                                                 static_cast<routing_strategy>(params.strategy));
-
-    mPolicyPluginInterface->setVolumeProfileForStream(mId,
-                                                      static_cast<audio_stream_type_t>(params.volumeProfile));
+    mPolicyPluginInterface->setVolumeProfileForStream(
+                mId, static_cast<audio_stream_type_t>(params.volumeProfile));
 
     return true;
 
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.h b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.h
index 4a875db..e0ce2fa 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.h
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.h
@@ -29,7 +29,6 @@
 private:
     struct Applicable
     {
-        uint32_t strategy; /**< applicable strategy for this stream. */
         uint32_t volumeProfile; /**< applicable strategy for this stream. */
     } __attribute__((packed));
 
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.cpp
deleted file mode 100644
index 78199f8..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "Usage.h"
-#include "PolicyMappingKeys.h"
-#include "PolicySubsystem.h"
-
-using std::string;
-using android::routing_strategy;
-
-Usage::Usage(const string &mappingValue,
-                   CInstanceConfigurableElement *instanceConfigurableElement,
-                   const CMappingContext &context, core::log::Logger &logger)
-    : CFormattedSubsystemObject(instanceConfigurableElement,
-                                logger,
-                                mappingValue,
-                                MappingKeyAmend1,
-                                (MappingKeyAmendEnd - MappingKeyAmend1 + 1),
-                                context),
-      mPolicySubsystem(static_cast<const PolicySubsystem *>(
-                           instanceConfigurableElement->getBelongingSubsystem())),
-      mPolicyPluginInterface(mPolicySubsystem->getPolicyPluginInterface())
-{
-    mId = static_cast<audio_usage_t>(context.getItemAsInteger(MappingKeyIdentifier));
-
-    // Declares the strategy to audio policy engine
-    mPolicyPluginInterface->addUsage(getFormattedMappingValue(), mId);
-}
-
-bool Usage::sendToHW(string & /*error*/)
-{
-    uint32_t applicableStrategy;
-    blackboardRead(&applicableStrategy, sizeof(applicableStrategy));
-    return mPolicyPluginInterface->setStrategyForUsage(mId,
-                                              static_cast<routing_strategy>(applicableStrategy));
-}
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.h b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.h
deleted file mode 100644
index 860204f..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "FormattedSubsystemObject.h"
-#include "InstanceConfigurableElement.h"
-#include "MappingContext.h"
-#include <AudioPolicyPluginInterface.h>
-#include <string>
-
-class PolicySubsystem;
-
-class Usage : public CFormattedSubsystemObject
-{
-public:
-    Usage(const std::string &mappingValue,
-          CInstanceConfigurableElement *instanceConfigurableElement,
-          const CMappingContext &context,
-          core::log::Logger& logger);
-
-protected:
-    virtual bool sendToHW(std::string &error);
-
-private:
-    const PolicySubsystem *mPolicySubsystem; /**< Route subsytem plugin. */
-
-    /**
-     * Interface to communicate with Audio Policy Engine.
-     */
-    android::AudioPolicyPluginInterface *mPolicyPluginInterface;
-
-    audio_usage_t mId; /**< usage identifier to link with audio.h. */
-};
diff --git a/services/audiopolicy/engineconfigurable/sepolicy/audioserver.te b/services/audiopolicy/engineconfigurable/sepolicy/audioserver.te
new file mode 100644
index 0000000..4d41d42
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/sepolicy/audioserver.te
@@ -0,0 +1,4 @@
+userdebug_or_eng(`
+  allow audioserver audioserver_socket:dir rw_dir_perms;
+  allow audioserver audioserver_socket:sock_file create_file_perms;
+')
diff --git a/services/audiopolicy/engineconfigurable/sepolicy/file.te b/services/audiopolicy/engineconfigurable/sepolicy/file.te
new file mode 100644
index 0000000..7db1937
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/sepolicy/file.te
@@ -0,0 +1,2 @@
+# Policy Engine remote connection for runtime debug of parameter framework
+type audioserver_socket, file_type, coredomain_socket;
diff --git a/services/audiopolicy/engineconfigurable/sepolicy/file_contexts b/services/audiopolicy/engineconfigurable/sepolicy/file_contexts
new file mode 100644
index 0000000..950fcce
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/sepolicy/file_contexts
@@ -0,0 +1 @@
+/dev/socket/audioserver(/.*)?    u:object_r:audioserver_socket:s0
diff --git a/services/audiopolicy/engineconfigurable/src/Collection.h b/services/audiopolicy/engineconfigurable/src/Collection.h
index b72ded8..02b41cb 100644
--- a/services/audiopolicy/engineconfigurable/src/Collection.h
+++ b/services/audiopolicy/engineconfigurable/src/Collection.h
@@ -18,8 +18,6 @@
 
 #include "Element.h"
 #include "Stream.h"
-#include "Strategy.h"
-#include "Usage.h"
 #include "InputSource.h"
 #include <utils/Errors.h>
 #include <system/audio.h>
@@ -28,10 +26,8 @@
 #include <stdint.h>
 #include <string>
 
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
 
 /**
  * Collection of policy element as a map indexed with a their UID type.
@@ -149,15 +145,9 @@
 template <>
 struct Collection<std::string>::collectionSupported {};
 template <>
-struct Collection<audio_usage_t>::collectionSupported {};
-template <>
 struct Collection<audio_source_t>::collectionSupported {};
-template <>
-struct Collection<routing_strategy>::collectionSupported {};
 
-typedef Collection<routing_strategy> StrategyCollection;
 typedef Collection<audio_stream_type_t> StreamCollection;
-typedef Collection<audio_usage_t> UsageCollection;
 typedef Collection<audio_source_t> InputSourceCollection;
 
 } // namespace audio_policy
diff --git a/services/audiopolicy/engineconfigurable/src/Element.h b/services/audiopolicy/engineconfigurable/src/Element.h
index 52e77e5..97950d8 100644
--- a/services/audiopolicy/engineconfigurable/src/Element.h
+++ b/services/audiopolicy/engineconfigurable/src/Element.h
@@ -22,10 +22,8 @@
 #include <system/audio.h>
 #include <utils/Log.h>
 
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
 
 template <typename Key>
 class Element
@@ -64,7 +62,7 @@
 
     /**
      * A Policy element may implement getter/setter function for a given property.
-     * Property may be routing_strategy, audio_stream_type_t, audio_usage_t, audio_source_t
+     * Property may be audio_stream_type_t, audio_usage_t, audio_source_t
      * or a string.
      *
      * @tparam Property for which this policy element has setter / getter.
@@ -75,7 +73,7 @@
 
     /**
      * A Policy element may implement getter/setter function for a given property.
-     * Property may be routing_strategy, audio_stream_type_t, audio_usage_t, audio_source_t
+     * Property may be audio_stream_type_t, audio_usage_t, audio_source_t
      * or a string.
      *
      * @tparam Property for which this policy element has setter / getter.
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.cpp b/services/audiopolicy/engineconfigurable/src/Engine.cpp
index 0d18ffa..cb45fcf 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Engine.cpp
@@ -25,92 +25,63 @@
 #endif
 
 #include "Engine.h"
-#include "Strategy.h"
 #include "Stream.h"
 #include "InputSource.h"
-#include "Usage.h"
+
+#include <EngineConfig.h>
 #include <policy.h>
+#include <AudioIODescriptorInterface.h>
 #include <ParameterManagerWrapper.h>
 
 using std::string;
 using std::map;
 
-namespace android
-{
-namespace audio_policy
-{
-template <>
-StrategyCollection &Engine::getCollection<routing_strategy>()
-{
-    return mStrategyCollection;
-}
+namespace android {
+namespace audio_policy {
+
 template <>
 StreamCollection &Engine::getCollection<audio_stream_type_t>()
 {
     return mStreamCollection;
 }
 template <>
-UsageCollection &Engine::getCollection<audio_usage_t>()
-{
-    return mUsageCollection;
-}
-template <>
 InputSourceCollection &Engine::getCollection<audio_source_t>()
 {
     return mInputSourceCollection;
 }
 
 template <>
-const StrategyCollection &Engine::getCollection<routing_strategy>() const
-{
-    return mStrategyCollection;
-}
-template <>
 const StreamCollection &Engine::getCollection<audio_stream_type_t>() const
 {
     return mStreamCollection;
 }
 template <>
-const UsageCollection &Engine::getCollection<audio_usage_t>() const
-{
-    return mUsageCollection;
-}
-template <>
 const InputSourceCollection &Engine::getCollection<audio_source_t>() const
 {
     return mInputSourceCollection;
 }
 
-Engine::Engine()
-    : mManagerInterface(this),
-      mPluginInterface(this),
-      mPolicyParameterMgr(new ParameterManagerWrapper()),
-      mApmObserver(NULL)
+Engine::Engine() : mPolicyParameterMgr(new ParameterManagerWrapper())
 {
+    status_t loadResult = loadAudioPolicyEngineConfig();
+    if (loadResult < 0) {
+        ALOGE("Policy Engine configuration is invalid.");
+    }
 }
 
 Engine::~Engine()
 {
-    mStrategyCollection.clear();
     mStreamCollection.clear();
     mInputSourceCollection.clear();
-    mUsageCollection.clear();
-}
-
-
-void Engine::setObserver(AudioPolicyManagerObserver *observer)
-{
-    ALOG_ASSERT(observer != NULL, "Invalid Audio Policy Manager observer");
-    mApmObserver = observer;
 }
 
 status_t Engine::initCheck()
 {
-    if (mPolicyParameterMgr == NULL || mPolicyParameterMgr->start() != NO_ERROR) {
+    if (mPolicyParameterMgr == nullptr || mPolicyParameterMgr->start() != NO_ERROR) {
         ALOGE("%s: could not start Policy PFW", __FUNCTION__);
         return NO_INIT;
     }
-    return (mApmObserver != NULL)? NO_ERROR : NO_INIT;
+    return EngineBase::initCheck();
 }
 
 template <typename Key>
@@ -138,55 +109,16 @@
     return element->template get<Property>();
 }
 
-routing_strategy Engine::ManagerInterfaceImpl::getStrategyForUsage(audio_usage_t usage)
+bool Engine::setVolumeProfileForStream(const audio_stream_type_t &stream,
+                                       const audio_stream_type_t &profile)
 {
-    return mPolicyEngine->getPropertyForKey<routing_strategy, audio_usage_t>(usage);
-}
-
-audio_devices_t Engine::ManagerInterfaceImpl::getDeviceForStrategy(routing_strategy strategy) const
-{
-    const SwAudioOutputCollection &outputs = mPolicyEngine->mApmObserver->getOutputs();
-
-    /** This is the only case handled programmatically because the PFW is unable to know the
-     * activity of streams.
-     *
-     * -While media is playing on a remote device, use the the sonification behavior.
-     * Note that we test this usecase before testing if media is playing because
-     * the isStreamActive() method only informs about the activity of a stream, not
-     * if it's for local playback. Note also that we use the same delay between both tests
-     *
-     * -When media is not playing anymore, fall back on the sonification behavior
-     */
-    if (strategy == STRATEGY_SONIFICATION_RESPECTFUL &&
-            !is_state_in_call(getPhoneState()) &&
-            !outputs.isStreamActiveRemotely(AUDIO_STREAM_MUSIC,
-                                    SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY) &&
-            outputs.isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
-        return mPolicyEngine->getPropertyForKey<audio_devices_t, routing_strategy>(STRATEGY_MEDIA);
-    }
-    if (strategy == STRATEGY_ACCESSIBILITY &&
-        (outputs.isStreamActive(AUDIO_STREAM_RING) || outputs.isStreamActive(AUDIO_STREAM_ALARM))) {
-            // do not route accessibility prompts to a digital output currently configured with a
-            // compressed format as they would likely not be mixed and dropped.
-            // Device For Sonification conf file has HDMI, SPDIF and HDMI ARC unreacheable.
-        return mPolicyEngine->getPropertyForKey<audio_devices_t, routing_strategy>(
-                    STRATEGY_SONIFICATION);
-    }
-    return mPolicyEngine->getPropertyForKey<audio_devices_t, routing_strategy>(strategy);
-}
-
-bool Engine::PluginInterfaceImpl::setVolumeProfileForStream(const audio_stream_type_t &stream,
-                                                            const audio_stream_type_t &profile)
-{
-    if (mPolicyEngine->setPropertyForKey<audio_stream_type_t, audio_stream_type_t>(stream,
-                                                                                   profile)) {
-        mPolicyEngine->mApmObserver->getVolumeCurves().switchVolumeCurve(profile, stream);
+    if (setPropertyForKey<audio_stream_type_t, audio_stream_type_t>(stream, profile)) {
+        switchVolumeCurve(profile, stream);
         return true;
     }
     return false;
 }
 
-
 template <typename Property, typename Key>
 bool Engine::setPropertyForKey(const Property &property, const Key &key)
 {
@@ -200,7 +132,11 @@
 
 status_t Engine::setPhoneState(audio_mode_t mode)
 {
-    return mPolicyParameterMgr->setPhoneState(mode);
+    status_t status = mPolicyParameterMgr->setPhoneState(mode);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    return EngineBase::setPhoneState(mode);
 }
 
 audio_mode_t Engine::getPhoneState() const
@@ -211,7 +147,11 @@
 status_t Engine::setForceUse(audio_policy_force_use_t usage,
                                       audio_policy_forced_cfg_t config)
 {
-    return mPolicyParameterMgr->setForceUse(usage, config);
+    status_t status = mPolicyParameterMgr->setForceUse(usage, config);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    return EngineBase::setForceUse(usage, config);
 }
 
 audio_policy_forced_cfg_t Engine::getForceUse(audio_policy_force_use_t usage) const
@@ -220,28 +160,216 @@
 }
 
 status_t Engine::setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
-                                          audio_policy_dev_state_t /*state*/)
+                                          audio_policy_dev_state_t state)
 {
+    mPolicyParameterMgr->setDeviceConnectionState(devDesc, state);
+
     if (audio_is_output_device(devDesc->type())) {
         return mPolicyParameterMgr->setAvailableOutputDevices(
-                    mApmObserver->getAvailableOutputDevices().types());
+                    getApmObserver()->getAvailableOutputDevices().types());
     } else if (audio_is_input_device(devDesc->type())) {
         return mPolicyParameterMgr->setAvailableInputDevices(
-                    mApmObserver->getAvailableInputDevices().types());
+                    getApmObserver()->getAvailableInputDevices().types());
     }
     return BAD_TYPE;
 }
 
+status_t Engine::loadAudioPolicyEngineConfig()
+{
+    auto result = EngineBase::loadAudioPolicyEngineConfig();
+
+    // Custom XML Parsing
+    auto loadCriteria= [this](const auto& configCriteria, const auto& configCriterionTypes) {
+        for (auto& criterion : configCriteria) {
+            engineConfig::CriterionType criterionType;
+            for (auto &configCriterionType : configCriterionTypes) {
+                if (configCriterionType.name == criterion.typeName) {
+                    criterionType = configCriterionType;
+                    break;
+                }
+            }
+            ALOG_ASSERT(not criterionType.name.empty(), "Invalid criterion type for %s",
+                        criterion.name.c_str());
+            mPolicyParameterMgr->addCriterion(criterion.name, criterionType.isInclusive,
+                                              criterionType.valuePairs,
+                                              criterion.defaultLiteralValue);
+        }
+    };
+
+    loadCriteria(result.parsedConfig->criteria, result.parsedConfig->criterionTypes);
+    return result.nbSkippedElement == 0? NO_ERROR : BAD_VALUE;
+}
+
+DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t ps) const
+{
+    const auto productStrategies = getProductStrategies();
+    if (productStrategies.find(ps) == productStrategies.end()) {
+        ALOGE("%s: Trying to get device on invalid strategy %d", __FUNCTION__, ps);
+        return {};
+    }
+    const DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
+    const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
+    uint32_t availableOutputDevicesType = availableOutputDevices.types();
+
+    /** This is the only case handled programmatically because the PFW is unable to know the
+     * activity of streams.
+     *
+     * -While media is playing on a remote device, use the the sonification behavior.
+     * Note that we test this usecase before testing if media is playing because
+     * the isStreamActive() method only informs about the activity of a stream, not
+     * if it's for local playback. Note also that we use the same delay between both tests
+     *
+     * -When media is not playing anymore, fall back on the sonification behavior
+     */
+    audio_devices_t devices = AUDIO_DEVICE_NONE;
+    if (ps == getProductStrategyForStream(AUDIO_STREAM_NOTIFICATION) &&
+            !is_state_in_call(getPhoneState()) &&
+            !outputs.isActiveRemotely(toVolumeSource(AUDIO_STREAM_MUSIC),
+                                      SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY) &&
+            outputs.isActive(toVolumeSource(AUDIO_STREAM_MUSIC),
+                             SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
+        product_strategy_t strategyForMedia =
+                getProductStrategyForStream(AUDIO_STREAM_MUSIC);
+        devices = productStrategies.getDeviceTypesForProductStrategy(strategyForMedia);
+    } else if (ps == getProductStrategyForStream(AUDIO_STREAM_ACCESSIBILITY) &&
+        (outputs.isActive(toVolumeSource(AUDIO_STREAM_RING)) ||
+         outputs.isActive(toVolumeSource(AUDIO_STREAM_ALARM)))) {
+            // do not route accessibility prompts to a digital output currently configured with a
+            // compressed format as they would likely not be mixed and dropped.
+            // Device For Sonification conf file has HDMI, SPDIF and HDMI ARC unreacheable.
+        product_strategy_t strategyNotification = getProductStrategyForStream(AUDIO_STREAM_RING);
+        devices = productStrategies.getDeviceTypesForProductStrategy(strategyNotification);
+    } else {
+        devices = productStrategies.getDeviceTypesForProductStrategy(ps);
+    }
+    if (devices == AUDIO_DEVICE_NONE ||
+            (devices & availableOutputDevicesType) == AUDIO_DEVICE_NONE) {
+        devices = getApmObserver()->getDefaultOutputDevice()->type();
+        ALOGE_IF(devices == AUDIO_DEVICE_NONE, "%s: no valid default device defined", __FUNCTION__);
+        return DeviceVector(getApmObserver()->getDefaultOutputDevice());
+    }
+    if (/*device_distinguishes_on_address(devices)*/ devices == AUDIO_DEVICE_OUT_BUS) {
+        // We do expect only one device for these types of devices
+        // Criterion device address garantee this one is available
+        // If this criterion is not wished, need to ensure this device is available
+        const String8 address(productStrategies.getDeviceAddressForProductStrategy(ps).c_str());
+        ALOGV("%s:device 0x%x %s %d", __FUNCTION__, devices, address.c_str(), ps);
+        return DeviceVector(availableOutputDevices.getDevice(devices,
+                                                             address,
+                                                             AUDIO_FORMAT_DEFAULT));
+    }
+    ALOGV("%s:device 0x%x %d", __FUNCTION__, devices, ps);
+    return availableOutputDevices.getDevicesFromTypeMask(devices);
+}
+
+DeviceVector Engine::getOutputDevicesForAttributes(const audio_attributes_t &attributes,
+                                                   const sp<DeviceDescriptor> &preferredDevice,
+                                                   bool fromCache) const
+{
+    // First check for explict routing device
+    if (preferredDevice != nullptr) {
+        ALOGV("%s explicit Routing on device %s", __func__, preferredDevice->toString().c_str());
+        return DeviceVector(preferredDevice);
+    }
+    product_strategy_t strategy = getProductStrategyForAttributes(attributes);
+    const DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
+    const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
+    //
+    // @TODO: what is the priority of explicit routing? Shall it be considered first as it used to
+    // be by APM?
+    //
+    // Honor explicit routing requests only if all active clients have a preferred route in which
+    // case the last active client route is used
+    sp<DeviceDescriptor> device = findPreferredDevice(outputs, strategy, availableOutputDevices);
+    if (device != nullptr) {
+        return DeviceVector(device);
+    }
+
+    return fromCache? mDevicesForStrategies.at(strategy) : getDevicesForProductStrategy(strategy);
+}
+
+DeviceVector Engine::getOutputDevicesForStream(audio_stream_type_t stream, bool fromCache) const
+{
+    auto attributes = EngineBase::getAttributesForStreamType(stream);
+    return getOutputDevicesForAttributes(attributes, nullptr, fromCache);
+}
+
+sp<DeviceDescriptor> Engine::getInputDeviceForAttributes(const audio_attributes_t &attr,
+                                                         sp<AudioPolicyMix> *mix) const
+{
+    const auto &policyMixes = getApmObserver()->getAudioPolicyMixCollection();
+    const auto availableInputDevices = getApmObserver()->getAvailableInputDevices();
+    const auto &inputs = getApmObserver()->getInputs();
+    std::string address;
+    //
+    // Explicit Routing ??? what is the priority of explicit routing? Shall it be considered
+    // first as it used to be by APM?
+    //
+    // Honor explicit routing requests only if all active clients have a preferred route in which
+    // case the last active client route is used
+    sp<DeviceDescriptor> device =
+            findPreferredDevice(inputs, attr.source, availableInputDevices);
+    if (device != nullptr) {
+        return device;
+    }
+
+    device = policyMixes.getDeviceAndMixForInputSource(attr.source, availableInputDevices, mix);
+    if (device != nullptr) {
+        return device;
+    }
+
+    audio_devices_t deviceType = getPropertyForKey<audio_devices_t, audio_source_t>(attr.source);
+
+    if (audio_is_remote_submix_device(deviceType)) {
+        address = "0";
+        std::size_t pos;
+        std::string tags { attr.tags };
+        if ((pos = tags.find("addr=")) != std::string::npos) {
+            address = tags.substr(pos + std::strlen("addr="));
+        }
+    }
+    return availableInputDevices.getDevice(deviceType, String8(address.c_str()), AUDIO_FORMAT_DEFAULT);
+}
+
+void Engine::updateDeviceSelectionCache()
+{
+    for (const auto &iter : getProductStrategies()) {
+        const auto &strategy = iter.second;
+        mDevicesForStrategies[strategy->getId()] = getDevicesForProductStrategy(strategy->getId());
+    }
+}
+
+void Engine::setDeviceAddressForProductStrategy(product_strategy_t strategy,
+                                                const std::string &address)
+{
+    if (getProductStrategies().find(strategy) == getProductStrategies().end()) {
+        ALOGE("%s: Trying to set address %s on invalid strategy %d", __FUNCTION__, address.c_str(),
+              strategy);
+        return;
+    }
+    getProductStrategies().at(strategy)->setDeviceAddress(address);
+}
+
+bool Engine::setDeviceTypesForProductStrategy(product_strategy_t strategy, audio_devices_t devices)
+{
+    if (getProductStrategies().find(strategy) == getProductStrategies().end()) {
+        ALOGE("%s: set device %d on invalid strategy %d", __FUNCTION__, devices, strategy);
+        return false;
+    }
+    getProductStrategies().at(strategy)->setDeviceTypes(devices);
+    return true;
+}
+
 template <>
 AudioPolicyManagerInterface *Engine::queryInterface()
 {
-    return &mManagerInterface;
+    return this;
 }
 
 template <>
 AudioPolicyPluginInterface *Engine::queryInterface()
 {
-    return &mPluginInterface;
+    return this;
 }
 
 } // namespace audio_policy
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.h b/services/audiopolicy/engineconfigurable/src/Engine.h
index 328d23d..4662e7e 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.h
+++ b/services/audiopolicy/engineconfigurable/src/Engine.h
@@ -16,22 +16,20 @@
 
 #pragma once
 
-
+#include "EngineBase.h"
 #include <AudioPolicyManagerInterface.h>
 #include <AudioPolicyPluginInterface.h>
 #include "Collection.h"
 
-namespace android
-{
+namespace android {
 class AudioPolicyManagerObserver;
 
-namespace audio_policy
-{
+namespace audio_policy {
 
 class ParameterManagerWrapper;
 class VolumeProfile;
 
-class Engine
+class Engine : public EngineBase, AudioPolicyPluginInterface
 {
 public:
     Engine();
@@ -40,132 +38,69 @@
     template <class RequestedInterface>
     RequestedInterface *queryInterface();
 
-private:
-    /// Interface members
-    class ManagerInterfaceImpl : public AudioPolicyManagerInterface
+    ///
+    /// from EngineBase
+    ///
+    android::status_t initCheck() override;
+
+    status_t setPhoneState(audio_mode_t mode) override;
+
+    audio_mode_t getPhoneState() const override;
+
+    status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config) override;
+
+    audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const override;
+
+    android::status_t setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
+                                               audio_policy_dev_state_t state) override;
+
+    DeviceVector getOutputDevicesForAttributes(const audio_attributes_t &attr,
+                                               const sp<DeviceDescriptor> &preferedDevice = nullptr,
+                                               bool fromCache = false) const override;
+
+    DeviceVector getOutputDevicesForStream(audio_stream_type_t stream,
+                                           bool fromCache = false) const override;
+
+    sp<DeviceDescriptor> getInputDeviceForAttributes(
+            const audio_attributes_t &attr, sp<AudioPolicyMix> *mix = nullptr) const override;
+
+    void updateDeviceSelectionCache() override;
+
+    ///
+    /// from AudioPolicyPluginInterface
+    ///
+    status_t addStream(const std::string &name, audio_stream_type_t stream) override
     {
-    public:
-        ManagerInterfaceImpl(Engine *policyEngine)
-            : mPolicyEngine(policyEngine) {}
-
-        virtual android::status_t initCheck()
-        {
-            return mPolicyEngine->initCheck();
-        }
-        virtual void setObserver(AudioPolicyManagerObserver *observer)
-        {
-            mPolicyEngine->setObserver(observer);
-        }
-        virtual audio_devices_t getDeviceForInputSource(audio_source_t inputSource) const
-        {
-            return mPolicyEngine->getPropertyForKey<audio_devices_t, audio_source_t>(inputSource);
-        }
-        virtual audio_devices_t getDeviceForStrategy(routing_strategy stategy) const;
-        virtual routing_strategy getStrategyForStream(audio_stream_type_t stream)
-        {
-            return mPolicyEngine->getPropertyForKey<routing_strategy, audio_stream_type_t>(stream);
-        }
-        virtual routing_strategy getStrategyForUsage(audio_usage_t usage);
-        virtual status_t setPhoneState(audio_mode_t mode)
-        {
-            return mPolicyEngine->setPhoneState(mode);
-        }
-        virtual audio_mode_t getPhoneState() const
-        {
-            return mPolicyEngine->getPhoneState();
-        }
-        virtual status_t setForceUse(audio_policy_force_use_t usage,
-                                              audio_policy_forced_cfg_t config)
-        {
-            return mPolicyEngine->setForceUse(usage, config);
-        }
-        virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const
-        {
-            return mPolicyEngine->getForceUse(usage);
-        }
-        virtual android::status_t setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
-                                                           audio_policy_dev_state_t state)
-        {
-            return mPolicyEngine->setDeviceConnectionState(devDesc, state);
-        }
-
-    private:
-        Engine *mPolicyEngine;
-    } mManagerInterface;
-
-    class PluginInterfaceImpl : public AudioPolicyPluginInterface
+        return add<audio_stream_type_t>(name, stream);
+    }
+    status_t addInputSource(const std::string &name, audio_source_t source) override
     {
-    public:
-        PluginInterfaceImpl(Engine *policyEngine)
-            : mPolicyEngine(policyEngine) {}
+        return add<audio_source_t>(name, source);
+    }
+    bool setVolumeProfileForStream(const audio_stream_type_t &stream,
+                                   const audio_stream_type_t &volumeProfile) override;
 
-        virtual status_t addStrategy(const std::string &name, routing_strategy strategy)
-        {
-            return mPolicyEngine->add<routing_strategy>(name, strategy);
-        }
-        virtual status_t addStream(const std::string &name, audio_stream_type_t stream)
-        {
-            return mPolicyEngine->add<audio_stream_type_t>(name, stream);
-        }
-        virtual status_t addUsage(const std::string &name, audio_usage_t usage)
-        {
-            return mPolicyEngine->add<audio_usage_t>(name, usage);
-        }
-        virtual status_t addInputSource(const std::string &name, audio_source_t source)
-        {
-            return mPolicyEngine->add<audio_source_t>(name, source);
-        }
-        virtual bool setDeviceForStrategy(const routing_strategy &strategy, audio_devices_t devices)
-        {
-            return mPolicyEngine->setPropertyForKey<audio_devices_t, routing_strategy>(devices,
-                                                                                       strategy);
-        }
-        virtual bool setStrategyForStream(const audio_stream_type_t &stream,
-                                          routing_strategy strategy)
-        {
-            return mPolicyEngine->setPropertyForKey<routing_strategy, audio_stream_type_t>(strategy,
-                                                                                           stream);
-        }
-        virtual bool setVolumeProfileForStream(const audio_stream_type_t &stream,
-                                               const audio_stream_type_t &volumeProfile);
+    bool setDeviceForInputSource(const audio_source_t &inputSource, audio_devices_t device) override
+    {
+        return setPropertyForKey<audio_devices_t, audio_source_t>(device, inputSource);
+    }
+    void setDeviceAddressForProductStrategy(product_strategy_t strategy,
+                                                    const std::string &address) override;
 
-        virtual bool setStrategyForUsage(const audio_usage_t &usage, routing_strategy strategy)
-        {
-            return mPolicyEngine->setPropertyForKey<routing_strategy, audio_usage_t>(strategy,
-                                                                                     usage);
-        }
-        virtual bool setDeviceForInputSource(const audio_source_t &inputSource,
-                                             audio_devices_t device)
-        {
-            return mPolicyEngine->setPropertyForKey<audio_devices_t, audio_source_t>(device,
-                                                                                     inputSource);
-        }
+    bool setDeviceTypesForProductStrategy(product_strategy_t strategy,
+                                                  audio_devices_t devices) override;
 
-    private:
-        Engine *mPolicyEngine;
-    } mPluginInterface;
+    product_strategy_t getProductStrategyByName(const std::string &name) override
+    {
+        return EngineBase::getProductStrategyByName(name);
+    }
 
 private:
     /* Copy facilities are put private to disable copy. */
     Engine(const Engine &object);
     Engine &operator=(const Engine &object);
 
-    void setObserver(AudioPolicyManagerObserver *observer);
-
-    bool setVolumeProfileForStream(const audio_stream_type_t &stream,
-                                   device_category deviceCategory,
-                                   const VolumeCurvePoints &points);
-
-    status_t initCheck();
-    status_t setPhoneState(audio_mode_t mode);
-    audio_mode_t getPhoneState() const;
-    status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
-    audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const;
-    status_t setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
-                                      audio_policy_dev_state_t state);
-    StrategyCollection mStrategyCollection; /**< Strategies indexed by their enum id. */
     StreamCollection mStreamCollection; /**< Streams indexed by their enum id.  */
-    UsageCollection mUsageCollection; /**< Usages indexed by their enum id. */
     InputSourceCollection mInputSourceCollection; /**< Input sources indexed by their enum id. */
 
     template <typename Key>
@@ -186,12 +121,16 @@
     template <typename Property, typename Key>
     bool setPropertyForKey(const Property &property, const Key &key);
 
+    status_t loadAudioPolicyEngineConfig();
+
+    DeviceVector getDevicesForProductStrategy(product_strategy_t strategy) const;
+
     /**
      * Policy Parameter Manager hidden through a wrapper.
      */
     ParameterManagerWrapper *mPolicyParameterMgr;
 
-    AudioPolicyManagerObserver *mApmObserver;
+    DeviceStrategyMap mDevicesForStrategies;
 };
 
 } // namespace audio_policy
diff --git a/services/audiopolicy/engineconfigurable/src/EngineInstance.cpp b/services/audiopolicy/engineconfigurable/src/EngineInstance.cpp
index 9aa89b2..2442590 100644
--- a/services/audiopolicy/engineconfigurable/src/EngineInstance.cpp
+++ b/services/audiopolicy/engineconfigurable/src/EngineInstance.cpp
@@ -21,10 +21,8 @@
 
 using std::string;
 
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
 
 EngineInstance::EngineInstance()
 {
diff --git a/services/audiopolicy/engineconfigurable/src/InputSource.cpp b/services/audiopolicy/engineconfigurable/src/InputSource.cpp
index ae39fef..d252d3f 100644
--- a/services/audiopolicy/engineconfigurable/src/InputSource.cpp
+++ b/services/audiopolicy/engineconfigurable/src/InputSource.cpp
@@ -20,13 +20,13 @@
 
 using std::string;
 
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
+
 status_t Element<audio_source_t>::setIdentifier(audio_source_t identifier)
 {
-    if (identifier > AUDIO_SOURCE_MAX && identifier != AUDIO_SOURCE_HOTWORD) {
+    if (identifier > AUDIO_SOURCE_MAX && identifier != AUDIO_SOURCE_HOTWORD
+        && identifier != AUDIO_SOURCE_FM_TUNER && identifier != AUDIO_SOURCE_ECHO_REFERENCE) {
         return BAD_VALUE;
     }
     mIdentifier = identifier;
diff --git a/services/audiopolicy/engineconfigurable/src/InputSource.h b/services/audiopolicy/engineconfigurable/src/InputSource.h
index 6c498dc..e1865cc 100644
--- a/services/audiopolicy/engineconfigurable/src/InputSource.h
+++ b/services/audiopolicy/engineconfigurable/src/InputSource.h
@@ -18,10 +18,8 @@
 
 #include "Element.h"
 
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
 
 /**
  * Specialization of policy base class element for audio_source_t
@@ -61,7 +59,7 @@
 
     /**
      * A Policy element may implement getter/setter function for a given property.
-     * Property may be routing_strategy, audio_stream_type_t, audio_usage_t, audio_source_t
+     * Property may be audio_stream_type_t, audio_usage_t, audio_source_t
      * or a string.
      */
     template <typename Property>
diff --git a/services/audiopolicy/engineconfigurable/src/Strategy.cpp b/services/audiopolicy/engineconfigurable/src/Strategy.cpp
deleted file mode 100644
index a539914..0000000
--- a/services/audiopolicy/engineconfigurable/src/Strategy.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "APM::AudioPolicyEngine/Strategy"
-
-#include "Strategy.h"
-
-using std::string;
-
-namespace android
-{
-namespace audio_policy
-{
-
-status_t Element<routing_strategy>::setIdentifier(routing_strategy identifier)
-{
-    if (identifier >= NUM_STRATEGIES) {
-        return BAD_VALUE;
-    }
-    mIdentifier = identifier;
-    ALOGD("%s: Strategy %s identifier 0x%X", __FUNCTION__, getName().c_str(), identifier);
-    return NO_ERROR;
-}
-
-/**
- * Set the device associated to this strategy.
- * It checks if the output device is valid.
- *
- * @param[in] devices selected for the given strategy.
- *
- * @return NO_ERROR if the device is either valid or none, error code otherwise.
- */
-template <>
-status_t Element<routing_strategy>::set<audio_devices_t>(audio_devices_t devices)
-{
-    if (!audio_is_output_devices(devices) || devices == AUDIO_DEVICE_NONE) {
-        ALOGE("%s: trying to set an invalid device 0x%X for strategy %s",
-              __FUNCTION__, devices, getName().c_str());
-        return BAD_VALUE;
-    }
-    ALOGD("%s: 0x%X for strategy %s", __FUNCTION__, devices, getName().c_str());
-    mApplicableDevices = devices;
-    return NO_ERROR;
-}
-
-template <>
-audio_devices_t Element<routing_strategy>::get<audio_devices_t>() const
-{
-    ALOGV("%s: 0x%X for strategy %s", __FUNCTION__, mApplicableDevices, getName().c_str());
-    return mApplicableDevices;
-}
-
-} // namespace audio_policy
-} // namespace android
-
diff --git a/services/audiopolicy/engineconfigurable/src/Strategy.h b/services/audiopolicy/engineconfigurable/src/Strategy.h
deleted file mode 100644
index 1157d55..0000000
--- a/services/audiopolicy/engineconfigurable/src/Strategy.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "Element.h"
-#include <RoutingStrategy.h>
-
-namespace android
-{
-namespace audio_policy
-{
-
-/**
- * @tparam audio_devices_t: Applicable output device(s) for this strategy.
- */
-template <>
-class Element<routing_strategy>
-{
-public:
-    Element(const std::string &name)
-        : mName(name),
-          mApplicableDevices(AUDIO_DEVICE_NONE)
-    {}
-    ~Element() {}
-
-    /**
-     * Returns identifier of this policy element
-     *
-     * @returns string representing the name of this policy element
-     */
-    const std::string &getName() const { return mName; }
-
-    /**
-    * Set the unique identifier for this policy element.
-    *
-    * @tparam Key type of the unique identifier.
-    * @param[in] identifier to be set.
-    *
-    * @return NO_ERROR if the identifier is valid and set correctly, error code otherwise.
-    */
-    status_t setIdentifier(routing_strategy identifier);
-
-    /**
-     * @return the unique identifier of this policy element.
-     */
-    routing_strategy getIdentifier() const { return mIdentifier; }
-
-    /**
-     * A Policy element may implement getter/setter function for a given property.
-     * Property may be routing_strategy, audio_stream_type_t, audio_usage_t, audio_source_t
-     * or a string.
-     */
-    template <typename Property>
-    Property get() const;
-
-    template <typename Property>
-    status_t set(Property property);
-
-private:
-    /* Copy facilities are put private to disable copy. */
-    Element(const Element &object);
-    Element &operator=(const Element &object);
-
-    std::string mName; /**< Unique literal Identifier of a policy base element*/
-    routing_strategy mIdentifier; /**< Unique numerical Identifier of a policy base element*/
-
-    audio_devices_t mApplicableDevices; /**< Applicable output device(s) for this strategy. */
-};
-
-typedef Element<routing_strategy> Strategy;
-
-} // namespace audio_policy
-} // namespace android
-
-
diff --git a/services/audiopolicy/engineconfigurable/src/Stream.cpp b/services/audiopolicy/engineconfigurable/src/Stream.cpp
index 0ed364f..297eb02 100644
--- a/services/audiopolicy/engineconfigurable/src/Stream.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Stream.cpp
@@ -21,10 +21,8 @@
 
 using std::string;
 
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
 
 status_t Element<audio_stream_type_t>::setIdentifier(audio_stream_type_t identifier)
 {
@@ -36,32 +34,6 @@
     return NO_ERROR;
 }
 
-/**
-* Set the strategy to follow for this stream.
-* It checks if the strategy is valid.
-*
-* @param[in] strategy to be followed.
-*
-* @return NO_ERROR if the strategy is set correctly, error code otherwise.
-*/
-template <>
-status_t Element<audio_stream_type_t>::set<routing_strategy>(routing_strategy strategy)
-{
-    if (strategy >= NUM_STRATEGIES) {
-        return BAD_VALUE;
-    }
-    mApplicableStrategy = strategy;
-    ALOGD("%s: 0x%X for Stream %s", __FUNCTION__, strategy, getName().c_str());
-    return NO_ERROR;
-}
-
-template <>
-routing_strategy Element<audio_stream_type_t>::get<routing_strategy>() const
-{
-    ALOGV("%s: 0x%X for Stream %s", __FUNCTION__, mApplicableStrategy, getName().c_str());
-    return mApplicableStrategy;
-}
-
 template <>
 status_t Element<audio_stream_type_t>::set<audio_stream_type_t>(audio_stream_type_t volumeProfile)
 {
diff --git a/services/audiopolicy/engineconfigurable/src/Stream.h b/services/audiopolicy/engineconfigurable/src/Stream.h
index 6902003..a4fdd39 100644
--- a/services/audiopolicy/engineconfigurable/src/Stream.h
+++ b/services/audiopolicy/engineconfigurable/src/Stream.h
@@ -18,23 +18,20 @@
 
 #include "Element.h"
 #include "EngineDefinition.h"
-#include <RoutingStrategy.h>
 #include <map>
 
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
+
 /**
- * @tparam routing_strategy: Applicable strategy for this stream.
+ * @tparam product_strategy_t: Applicable strategy for this stream.
  */
 template <>
 class Element<audio_stream_type_t>
 {
 public:
     Element(const std::string &name)
-        : mName(name),
-          mApplicableStrategy(STRATEGY_MEDIA)
+        : mName(name)
     {}
     ~Element() {}
 
@@ -62,7 +59,7 @@
 
     /**
      * A Policy element may implement getter/setter function for a given property.
-     * Property may be routing_strategy, audio_stream_type_t, audio_usage_t, audio_source_t
+     * Property may be  audio_stream_type_t, audio_usage_t, audio_source_t
      * or a string.
      */
     template <typename Property>
@@ -79,8 +76,6 @@
     std::string mName; /**< Unique literal Identifier of a policy base element*/
     audio_stream_type_t mIdentifier; /**< Unique numerical Identifier of a policy base element*/
 
-    routing_strategy mApplicableStrategy; /**< Applicable strategy for this stream. */
-
     audio_stream_type_t mVolumeProfile; /**< Volume Profile followed by this stream. */
 };
 
diff --git a/services/audiopolicy/engineconfigurable/src/Usage.cpp b/services/audiopolicy/engineconfigurable/src/Usage.cpp
deleted file mode 100644
index 5d20828..0000000
--- a/services/audiopolicy/engineconfigurable/src/Usage.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "APM::AudioPolicyEngine/Usage"
-
-#include "Usage.h"
-
-namespace android
-{
-namespace audio_policy
-{
-
-status_t Element<audio_usage_t>::setIdentifier(audio_usage_t identifier)
-{
-    if (identifier > AUDIO_USAGE_MAX) {
-        return BAD_VALUE;
-    }
-    mIdentifier = identifier;
-    ALOGD("%s: Usage %s has identifier 0x%X", __FUNCTION__, getName().c_str(), identifier);
-    return NO_ERROR;
-}
-
-template <>
-status_t Element<audio_usage_t>::set<routing_strategy>(routing_strategy strategy)
-{
-    if (strategy >= NUM_STRATEGIES) {
-        return BAD_VALUE;
-    }
-    ALOGD("%s: %d for Usage %s", __FUNCTION__, strategy, getName().c_str());
-    mApplicableStrategy = strategy;
-    return NO_ERROR;
-}
-
-template <>
-routing_strategy Element<audio_usage_t>::get<routing_strategy>() const
-{
-    ALOGD("%s: %d for Usage %s", __FUNCTION__, mApplicableStrategy, getName().c_str());
-    return mApplicableStrategy;
-}
-
-} // namespace audio_policy
-} // namespace android
-
-
diff --git a/services/audiopolicy/engineconfigurable/src/Usage.h b/services/audiopolicy/engineconfigurable/src/Usage.h
deleted file mode 100644
index d69e0e0..0000000
--- a/services/audiopolicy/engineconfigurable/src/Usage.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "Element.h"
-#include <RoutingStrategy.h>
-
-namespace android
-{
-namespace audio_policy
-{
-
-/**
- * @tparam routing_strategy: Applicable strategy for this usage.
- */
-template <>
-class Element<audio_usage_t>
-{
-public:
-    Element(const std::string &name)
-        : mName(name),
-          mApplicableStrategy(STRATEGY_MEDIA)
-    {}
-    ~Element() {}
-
-    /**
-     * Returns identifier of this policy element
-     *
-     * @returns string representing the name of this policy element
-     */
-    const std::string &getName() const { return mName; }
-
-    /**
-    * Set the unique identifier for this policy element.
-    *
-    * @tparam Key type of the unique identifier.
-    * @param[in] identifier to be set.
-    *
-    * @return NO_ERROR if the identifier is valid and set correctly, error code otherwise.
-    */
-    status_t setIdentifier(audio_usage_t identifier);
-
-    /**
-     * @return the unique identifier of this policy element.
-     */
-    audio_usage_t getIdentifier() const { return mIdentifier; }
-
-    /**
-     * A Policy element may implement getter/setter function for a given property.
-     * Property may be routing_strategy, audio_stream_type_t, audio_usage_t, audio_source_t
-     * or a string.
-     */
-    template <typename Property>
-    Property get() const;
-
-    template <typename Property>
-    status_t set(Property property);
-
-private:
-    /* Copy facilities are put private to disable copy. */
-    Element(const Element &object);
-    Element &operator=(const Element &object);
-
-    std::string mName; /**< Unique literal Identifier of a policy base element*/
-    audio_usage_t mIdentifier; /**< Unique numerical Identifier of a policy base element*/
-    routing_strategy mApplicableStrategy; /**< Applicable strategy for this usage. */
-};
-
-typedef Element<audio_usage_t> Usage;
-
-} // namespace audio_policy
-} // namespace android
-
-
diff --git a/services/audiopolicy/engineconfigurable/tools/Android.bp b/services/audiopolicy/engineconfigurable/tools/Android.bp
new file mode 100644
index 0000000..8c16972
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/tools/Android.bp
@@ -0,0 +1,60 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+python_defaults {
+    name: "tools_default",
+    version: {
+        py2: {
+            enabled: true,
+        },
+        py3: {
+            enabled: false,
+        },
+    },
+}
+
+python_binary_host {
+    name: "buildPolicyCriterionTypes.py",
+    main: "buildPolicyCriterionTypes.py",
+    srcs: [
+        "buildPolicyCriterionTypes.py",
+    ],
+    defaults: ["tools_default"],
+}
+
+python_binary_host {
+    name: "domainGeneratorPolicy.py",
+    main: "domainGeneratorPolicy.py",
+    srcs: [
+        "domainGeneratorPolicy.py",
+    ],
+    defaults: ["tools_default"],
+    libs: [
+        "EddParser.py",
+        "hostConfig.py",
+        "PFWScriptGenerator.py",
+    ],
+    required: [
+        "domainGeneratorConnector",
+    ],
+}
+
+python_binary_host {
+    name: "buildStrategiesStructureFile.py",
+    main: "buildStrategiesStructureFile.py",
+    srcs: [
+        "buildStrategiesStructureFile.py",
+    ],
+    defaults: ["tools_default"],
+}
diff --git a/services/audiopolicy/engineconfigurable/tools/buildPolicyCriterionTypes.py b/services/audiopolicy/engineconfigurable/tools/buildPolicyCriterionTypes.py
new file mode 100755
index 0000000..a63c858
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/tools/buildPolicyCriterionTypes.py
@@ -0,0 +1,251 @@
+#!/usr/bin/python
+
+#
+# Copyright 2018, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import argparse
+import re
+import sys
+import tempfile
+import os
+import logging
+import subprocess
+import xml.etree.ElementTree as ET
+import xml.etree.ElementInclude as EI
+import xml.dom.minidom as MINIDOM
+from collections import OrderedDict
+
+#
+# Helper script that helps to feed at build time the XML criterion types file used by
+# the engineconfigurable to start the parameter-framework.
+# It prevents to fill them manually and avoid divergences with android.
+#
+# The Device Types criterion types are fed from audio-base.h file with the option
+#           --androidaudiobaseheader <path/to/android/audio/base/file/audio-base.h>
+#
+# The Device Addresses criterion types are fed from the audio policy configuration file
+# in order to discover all the devices for which the address matter.
+#           --audiopolicyconfigurationfile <path/to/audio_policy_configuration.xml>
+#
+# The reference file of criterion types must also be set as an input of the script:
+#           --criteriontypes <path/to/criterion/file/audio_criterion_types.xml.in>
+#
+# At last, the output of the script shall be set also:
+#           --outputfile <path/to/out/vendor/etc/audio_criterion_types.xml>
+#
+
+def parseArgs():
+    argparser = argparse.ArgumentParser(description="Parameter-Framework XML \
+        audio criterion type file generator.\n\
+        Exit with the number of (recoverable or not) error that occured.")
+    argparser.add_argument('--androidaudiobaseheader',
+            help="Android Audio Base C header file, Mandatory.",
+            metavar="ANDROID_AUDIO_BASE_HEADER",
+            type=argparse.FileType('r'),
+            required=True)
+    argparser.add_argument('--audiopolicyconfigurationfile',
+            help="Android Audio Policy Configuration file, Mandatory.",
+            metavar="(AUDIO_POLICY_CONFIGURATION_FILE)",
+            type=argparse.FileType('r'),
+            required=True)
+    argparser.add_argument('--criteriontypes',
+            help="Criterion types XML base file, in \
+            '<criterion_types> \
+                <criterion_type name="" type=<inclusive|exclusive> values=<value1,value2,...>/>' \
+        format. Mandatory.",
+            metavar="CRITERION_TYPE_FILE",
+            type=argparse.FileType('r'),
+            required=True)
+    argparser.add_argument('--outputfile',
+            help="Criterion types outputfile file. Mandatory.",
+            metavar="CRITERION_TYPE_OUTPUT_FILE",
+            type=argparse.FileType('w'),
+            required=True)
+    argparser.add_argument('--verbose',
+            action='store_true')
+
+    return argparser.parse_args()
+
+
+def generateXmlCriterionTypesFile(criterionTypes, addressCriteria, criterionTypesFile, outputFile):
+
+    logging.info("Importing criterionTypesFile {}".format(criterionTypesFile))
+    criterion_types_in_tree = ET.parse(criterionTypesFile)
+
+    criterion_types_root = criterion_types_in_tree.getroot()
+
+    for criterion_name, values_dict in criterionTypes.items():
+        for criterion_type in criterion_types_root.findall('criterion_type'):
+            if criterion_type.get('name') == criterion_name:
+                values_node = ET.SubElement(criterion_type, "values")
+                ordered_values = OrderedDict(sorted(values_dict.items(), key=lambda x: x[1]))
+                for key, value in ordered_values.items():
+                    value_node = ET.SubElement(values_node, "value")
+                    value_node.set('numerical', str(value))
+                    value_node.set('literal', key)
+
+    if addressCriteria:
+        for criterion_name, values_list in addressCriteria.items():
+            for criterion_type in criterion_types_root.findall('criterion_type'):
+                if criterion_type.get('name') == criterion_name:
+                    index = 0
+                    existing_values_node = criterion_type.find("values")
+                    if existing_values_node is not None:
+                        for existing_value in existing_values_node.findall('value'):
+                            if existing_value.get('numerical') == str(1 << index):
+                                index += 1
+                        values_node = existing_values_node
+                    else:
+                        values_node = ET.SubElement(criterion_type, "values")
+
+                    for value in values_list:
+                        value_node = ET.SubElement(values_node, "value", literal=value)
+                        value_node.set('numerical', str(1 << index))
+                        index += 1
+
+    xmlstr = ET.tostring(criterion_types_root, encoding='utf8', method='xml')
+    reparsed = MINIDOM.parseString(xmlstr)
+    prettyXmlStr = reparsed.toprettyxml(newl='\r\n')
+    prettyXmlStr = os.linesep.join([s for s in prettyXmlStr.splitlines() if s.strip()])
+    outputFile.write(prettyXmlStr.encode('utf-8'))
+
+def capitalizeLine(line):
+    return ' '.join((w.capitalize() for w in line.split(' ')))
+
+
+#
+# Parse the audio policy configuration file and output a dictionary of device criteria addresses
+#
+def parseAndroidAudioPolicyConfigurationFile(audiopolicyconfigurationfile):
+
+    logging.info("Checking Audio Policy Configuration file {}".format(audiopolicyconfigurationfile))
+    #
+    # extract all devices addresses from audio policy configuration file
+    #
+    address_criteria_mapping_table = {
+        'sink' : "OutputDevicesAddressesType",
+        'source' : "InputDevicesAddressesType" }
+
+    address_criteria = {
+        'OutputDevicesAddressesType' : [],
+        'InputDevicesAddressesType' : [] }
+
+    oldWorkingDir = os.getcwd()
+    print "Current working directory %s" % oldWorkingDir
+
+    newDir = os.path.join(oldWorkingDir , audiopolicyconfigurationfile.name)
+
+    policy_in_tree = ET.parse(audiopolicyconfigurationfile)
+    os.chdir(os.path.dirname(os.path.normpath(newDir)))
+
+    print "new working directory %s" % os.getcwd()
+
+    policy_root = policy_in_tree.getroot()
+    EI.include(policy_root)
+
+    os.chdir(oldWorkingDir)
+
+    for device in policy_root.iter('devicePort'):
+        for key in address_criteria_mapping_table.keys():
+            if device.get('role') == key and device.get('address') :
+                logging.info("{}: <{}>".format(key, device.get('address')))
+                address_criteria[address_criteria_mapping_table[key]].append(device.get('address'))
+
+    for criteria in address_criteria:
+        values = ','.join(address_criteria[criteria])
+        logging.info("{}: <{}>".format(criteria, values))
+
+    return address_criteria
+
+#
+# Parse the audio-base.h file and output a dictionary of android dependent criterion types:
+#   -Android Mode
+#   -Output devices type
+#   -Input devices type
+#
+def parseAndroidAudioFile(androidaudiobaseheaderFile):
+    #
+    # Adaptation table between Android Enumeration prefix and Audio PFW Criterion type names
+    #
+    criterion_mapping_table = {
+        'AUDIO_MODE' : "AndroidModeType",
+        'AUDIO_DEVICE_OUT' : "OutputDevicesMaskType",
+        'AUDIO_DEVICE_IN' : "InputDevicesMaskType"}
+
+    all_criteria = {
+        'AndroidModeType' : {},
+        'OutputDevicesMaskType' : {},
+        'InputDevicesMaskType' : {} }
+
+    #
+    # _CNT, _MAX, _ALL and _NONE are prohibited values as ther are just helpers for enum users.
+    #
+    ignored_values = [ 'CNT', 'MAX', 'ALL', 'NONE' ]
+
+    criteria_pattern = re.compile(
+        r"\s*(?P<type>(?:"+'|'.join(criterion_mapping_table.keys()) + "))\_" \
+        r"(?P<literal>(?!" + '|'.join(ignored_values) + ")\w*)\s*=\s*" \
+        r"(?P<values>(?:0[xX])?[0-9a-fA-F]+)")
+
+    logging.info("Checking Android Header file {}".format(androidaudiobaseheaderFile))
+
+    for line_number, line in enumerate(androidaudiobaseheaderFile):
+        match = criteria_pattern.match(line)
+        if match:
+            logging.debug("The following line is VALID: {}:{}\n{}".format(
+                androidaudiobaseheaderFile.name, line_number, line))
+
+            criterion_name = criterion_mapping_table[match.groupdict()['type']]
+            literal = ''.join((w.capitalize() for w in match.groupdict()['literal'].split('_')))
+            numerical_value = match.groupdict()['values']
+
+            # for AUDIO_DEVICE_IN: need to remove sign bit
+            if criterion_name == "InputDevicesMaskType":
+                numerical_value = str(int(numerical_value, 0) & ~2147483648)
+
+            # Remove duplicated numerical values
+            if int(numerical_value, 0) in all_criteria[criterion_name].values():
+                logging.info("criterion {} duplicated values:".format(criterion_name))
+                logging.info("{}:{}".format(numerical_value, literal))
+                logging.info("KEEPING LATEST")
+                for key in all_criteria[criterion_name].keys():
+                    if all_criteria[criterion_name][key] == int(numerical_value, 0):
+                        del all_criteria[criterion_name][key]
+
+            all_criteria[criterion_name][literal] = int(numerical_value, 0)
+
+            logging.debug("type:{},".format(criterion_name))
+            logging.debug("iteral:{},".format(literal))
+            logging.debug("values:{}.".format(numerical_value))
+
+    return all_criteria
+
+
+def main():
+    logging.root.setLevel(logging.INFO)
+    args = parseArgs()
+
+    all_criteria = parseAndroidAudioFile(args.androidaudiobaseheader)
+
+    address_criteria = parseAndroidAudioPolicyConfigurationFile(args.audiopolicyconfigurationfile)
+
+    criterion_types = args.criteriontypes
+
+    generateXmlCriterionTypesFile(all_criteria, address_criteria, criterion_types, args.outputfile)
+
+# If this file is directly executed
+if __name__ == "__main__":
+    sys.exit(main())
diff --git a/services/audiopolicy/engineconfigurable/tools/buildStrategiesStructureFile.py b/services/audiopolicy/engineconfigurable/tools/buildStrategiesStructureFile.py
new file mode 100755
index 0000000..af40602
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/tools/buildStrategiesStructureFile.py
@@ -0,0 +1,139 @@
+#!/usr/bin/python
+
+#
+# Copyright 2019, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import argparse
+import re
+import sys
+import tempfile
+import os
+import logging
+import subprocess
+import xml.etree.ElementTree as ET
+import xml.etree.ElementInclude as EI
+import xml.dom.minidom as MINIDOM
+from collections import OrderedDict
+
+#
+# Helper script that helps to feed at build time the XML Product Strategies Structure file file used
+# by the engineconfigurable to start the parameter-framework.
+# It prevents to fill them manually and avoid divergences with android.
+#
+# The Product Strategies Structure file is fed from the audio policy engine configuration file
+# in order to discover all the strategies available for the current platform.
+#           --audiopolicyengineconfigurationfile <path/to/audio_policy_engine_configuration.xml>
+#
+# The reference file of ProductStrategies structure must also be set as an input of the script:
+#           --productstrategiesstructurefile <path/to/structure/file/ProductStrategies.xml.in>
+#
+# At last, the output of the script shall be set also:
+#           --outputfile <path/to/out/<system|vendor|odm>/etc/ProductStrategies.xml>
+#
+
+def parseArgs():
+    argparser = argparse.ArgumentParser(description="Parameter-Framework XML \
+        product strategies structure file generator.\n\
+        Exit with the number of (recoverable or not) error that occured.")
+    argparser.add_argument('--audiopolicyengineconfigurationfile',
+            help="Android Audio Policy Engine Configuration file, Mandatory.",
+            metavar="(AUDIO_POLICY_ENGINE_CONFIGURATION_FILE)",
+            type=argparse.FileType('r'),
+            required=True)
+    argparser.add_argument('--productstrategiesstructurefile',
+            help="Product Strategies Structure XML base file, Mandatory.",
+            metavar="STRATEGIES_STRUCTURE_FILE",
+            type=argparse.FileType('r'),
+            required=True)
+    argparser.add_argument('--outputfile',
+            help="Product Strategies Structure output file, Mandatory.",
+            metavar="STRATEGIES_STRUCTURE_OUTPUT_FILE",
+            type=argparse.FileType('w'),
+            required=True)
+    argparser.add_argument('--verbose',
+            action='store_true')
+
+    return argparser.parse_args()
+
+
+def generateXmlStructureFile(strategies, strategyStructureInFile, outputFile):
+
+    logging.info("Importing strategyStructureInFile {}".format(strategyStructureInFile))
+    strategies_in_tree = ET.parse(strategyStructureInFile)
+
+    strategies_root = strategies_in_tree.getroot()
+    strategy_components = strategies_root.find('ComponentType')
+
+    for strategy_name in strategies:
+        context_mapping = "".join(map(str, ["Name:", strategy_name]))
+        strategy_pfw_name = strategy_name.replace('STRATEGY_', '').lower()
+        strategy_component_node = ET.SubElement(strategy_components, "Component", Name=strategy_pfw_name, Type="ProductStrategy", Mapping=context_mapping)
+
+    xmlstr = ET.tostring(strategies_root, encoding='utf8', method='xml')
+    reparsed = MINIDOM.parseString(xmlstr)
+    prettyXmlStr = reparsed.toprettyxml(newl='\r\n')
+    prettyXmlStr = os.linesep.join([s for s in prettyXmlStr.splitlines() if s.strip()])
+    outputFile.write(prettyXmlStr.encode('utf-8'))
+
+def capitalizeLine(line):
+    return ' '.join((w.capitalize() for w in line.split(' ')))
+
+
+#
+# Parse the audio policy configuration file and output a dictionary of device criteria addresses
+#
+def parseAndroidAudioPolicyEngineConfigurationFile(audiopolicyengineconfigurationfile):
+
+    logging.info("Checking Audio Policy Engine Configuration file {}".format(audiopolicyengineconfigurationfile))
+    #
+    # extract all product strategies name from audio policy engine configuration file
+    #
+    strategy_names = []
+
+    oldWorkingDir = os.getcwd()
+    print "Current working directory %s" % oldWorkingDir
+
+    newDir = os.path.join(oldWorkingDir , audiopolicyengineconfigurationfile.name)
+
+    policy_engine_in_tree = ET.parse(audiopolicyengineconfigurationfile)
+    os.chdir(os.path.dirname(os.path.normpath(newDir)))
+
+    print "new working directory %s" % os.getcwd()
+
+    policy_engine_root = policy_engine_in_tree.getroot()
+    EI.include(policy_engine_root)
+
+    os.chdir(oldWorkingDir)
+
+    for strategy in policy_engine_root.iter('ProductStrategy'):
+        strategy_names.append(strategy.get('name'))
+
+    return strategy_names
+
+
+def main():
+    logging.root.setLevel(logging.INFO)
+    args = parseArgs()
+
+    strategies = parseAndroidAudioPolicyEngineConfigurationFile(args.audiopolicyengineconfigurationfile)
+
+    product_strategies_structure = args.productstrategiesstructurefile
+
+    generateXmlStructureFile(strategies, product_strategies_structure, args.outputfile)
+
+# If this file is directly executed
+if __name__ == "__main__":
+    sys.exit(main())
diff --git a/services/audiopolicy/engineconfigurable/tools/build_audio_pfw_settings.mk b/services/audiopolicy/engineconfigurable/tools/build_audio_pfw_settings.mk
new file mode 100644
index 0000000..ac60ef7
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/tools/build_audio_pfw_settings.mk
@@ -0,0 +1,38 @@
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := optional
+LOCAL_ADDITIONAL_DEPENDENCIES += \
+    $(HOST_OUT_EXECUTABLES)/domainGeneratorPolicy.py \
+    $(PFW_TOPLEVEL_FILE) $(PFW_CRITERIA_FILE) $(PFW_CRITERION_TYPES_FILE)
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): MY_CRITERION_TYPES_FILE := $(PFW_CRITERION_TYPES_FILE)
+$(LOCAL_BUILT_MODULE): MY_TOOL := $(HOST_OUT_EXECUTABLES)/domainGeneratorPolicy.py
+$(LOCAL_BUILT_MODULE): MY_TOPLEVEL_FILE := $(PFW_TOPLEVEL_FILE)
+$(LOCAL_BUILT_MODULE): MY_CRITERIA_FILE := $(PFW_CRITERIA_FILE)
+$(LOCAL_BUILT_MODULE): MY_TUNING_FILE := $(PFW_TUNING_FILE)
+$(LOCAL_BUILT_MODULE): MY_EDD_FILES := $(PFW_EDD_FILES)
+$(LOCAL_BUILT_MODULE): MY_DOMAIN_FILES := $(PFW_DOMAIN_FILES)
+$(LOCAL_BUILT_MODULE): MY_SCHEMAS_DIR := $(PFW_SCHEMAS_DIR)
+$(LOCAL_BUILT_MODULE): MY_CRITERION_TYPES_FILE := $(PFW_CRITERION_TYPES_FILE)
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+
+	"$(MY_TOOL)" --validate \
+		--toplevel-config "$(MY_TOPLEVEL_FILE)" \
+		--criteria "$(MY_CRITERIA_FILE)" \
+		--criteriontypes "$(MY_CRITERION_TYPES_FILE)" \
+		--initial-settings $(MY_TUNING_FILE) \
+		--add-edds $(MY_EDD_FILES) \
+		--add-domains $(MY_DOMAIN_FILES) \
+		--schemas-dir $(MY_SCHEMAS_DIR) > "$@"
+
+
+# Clear variables for further use
+PFW_TOPLEVEL_FILE :=
+PFW_STRUCTURE_FILES :=
+PFW_CRITERIA_FILE :=
+PFW_CRITERION_TYPES_FILE :=
+PFW_TUNING_FILE :=
+PFW_EDD_FILES :=
+PFW_DOMAIN_FILES :=
+PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
diff --git a/services/audiopolicy/engineconfigurable/tools/domainGeneratorPolicy.py b/services/audiopolicy/engineconfigurable/tools/domainGeneratorPolicy.py
new file mode 100755
index 0000000..4dec9a2
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/tools/domainGeneratorPolicy.py
@@ -0,0 +1,268 @@
+#!/usr/bin/python
+
+#
+# Copyright 2018, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import EddParser
+from PFWScriptGenerator import PfwScriptTranslator
+import hostConfig
+
+import argparse
+import re
+import sys
+import tempfile
+import os
+import logging
+import subprocess
+import xml.etree.ElementTree as ET
+
+#
+# In order to build the XML Settings file at build time, an instance of the parameter-framework
+# shall be started and fed with all the criterion types/criteria that will be used by
+# the engineconfigurable.
+# This scripts allows generates the settings from the same audio_criterion_types.xml /
+# audio_criteria.xml files used at run time by the engineconfigurable
+#
+
+def parseArgs():
+    argparser = argparse.ArgumentParser(description="Parameter-Framework XML \
+        Settings file generator.\n\
+        Exit with the number of (recoverable or not) error that occured.")
+    argparser.add_argument('--toplevel-config',
+            help="Top-level parameter-framework configuration file. Mandatory.",
+            metavar="TOPLEVEL_CONFIG_FILE",
+            required=True)
+    argparser.add_argument('--criteria',
+            help="Criteria file, in XML format: \
+                  in '<criteria> \
+                          <criterion name="" type=""/> \
+                      </criteria>' \
+        format. Mandatory.",
+            metavar="CRITERIA_FILE",
+            type=argparse.FileType('r'),
+            required=True)
+    argparser.add_argument('--criteriontypes',
+            help="Criterion types XML file, in \
+            '<criterion_types> \
+                <criterion_type name="" type=<inclusive|exclusive> values=<value1,value2,...>/> \
+             </criterion_types>' \
+        format. Mandatory.",
+            metavar="CRITERION_TYPE_FILE",
+            type=argparse.FileType('r'),
+            required=False)
+    argparser.add_argument('--initial-settings',
+            help="Initial XML settings file (containing a \
+        <ConfigurableDomains>  tag",
+            nargs='?',
+            default=None,
+            metavar="XML_SETTINGS_FILE")
+    argparser.add_argument('--add-domains',
+            help="List of single domain files (each containing a single \
+        <ConfigurableDomain> tag",
+            metavar="XML_DOMAIN_FILE",
+            nargs='*',
+            dest='xml_domain_files',
+            default=[])
+    argparser.add_argument('--add-edds',
+            help="List of files in EDD syntax (aka \".pfw\" files)",
+            metavar="EDD_FILE",
+            type=argparse.FileType('r'),
+            nargs='*',
+            default=[],
+            dest='edd_files')
+    argparser.add_argument('--schemas-dir',
+            help="Directory of parameter-framework XML Schemas for generation \
+        validation",
+            default=None)
+    argparser.add_argument('--target-schemas-dir',
+            help="Ignored. Kept for retro-compatibility")
+    argparser.add_argument('--validate',
+            help="Validate the settings against XML schemas",
+            action='store_true')
+    argparser.add_argument('--verbose',
+            action='store_true')
+
+    return argparser.parse_args()
+
+#
+# Parses audio_criterion_types.xml / audio_criteria.xml files used at run time by the
+# engineconfigurable and outputs a dictionnary of criteria.
+# For each criteria, the name, type (aka inclusive (bitfield) or exclusive (enum), the values
+# are provided.
+#
+def parseCriteriaAndCriterionTypes(criteriaFile, criterionTypesFile):
+    # Parse criteria and criterion types XML files
+    #
+    criteria_tree = ET.parse(criteriaFile)
+    logging.info("Importing criteriaFile {}".format(criteriaFile))
+    criterion_types_tree = ET.parse(criterionTypesFile)
+    logging.info("Importing criterionTypesFile {}".format(criterionTypesFile))
+
+    criteria_root = criteria_tree.getroot()
+    criterion_types_root = criterion_types_tree.getroot()
+
+    all_criteria = []
+    for criterion in criteria_root.findall('criterion'):
+        criterion_name = criterion.get('name')
+        type_name = criterion.get('type')
+        logging.info("Importing criterion_name {}".format(criterion_name))
+        logging.info("Importing type_name {}".format(type_name))
+
+        for criterion_types in criterion_types_tree.findall('criterion_type'):
+            criterion_type_name = criterion_types.get('name')
+            if criterion_type_name == type_name:
+                criterion_inclusiveness = criterion_types.get('type')
+
+                criterion_values = []
+
+                values_node = criterion_types.find('values')
+                if values_node is not None:
+                    for value in values_node.findall('value'):
+                        criterion_values.append(value.get('literal'))
+
+                if len(criterion_values) == 0:
+                    criterion_values.append('')
+
+                logging.info("Importing criterion_type_name {}".format(criterion_type_name))
+                logging.info("Importing criterion_inclusiveness {}".format(criterion_inclusiveness))
+                logging.info("Importing criterion_values {}".format(criterion_values))
+
+                all_criteria.append({
+                    "name" : criterion_name,
+                    "inclusive" : criterion_inclusiveness,
+                    "values" : criterion_values})
+                break
+
+    return all_criteria
+
+#
+# Parses the Edd files (aka .pfw extension file), which is a simplified language to write the
+# parameter framework settings.
+#
+def parseEdd(EDDFiles):
+    parsed_edds = []
+
+    for edd_file in EDDFiles:
+        try:
+            root = EddParser.Parser().parse(edd_file)
+        except EddParser.MySyntaxError as ex:
+            logging.critical(str(ex))
+            logging.info("EXIT ON FAILURE")
+            exit(2)
+
+        try:
+            root.propagate()
+        except EddParser.MyPropagationError, ex :
+            logging.critical(str(ex))
+            logging.info("EXIT ON FAILURE")
+            exit(1)
+
+        parsed_edds.append((edd_file.name, root))
+    return parsed_edds
+
+#
+# Generates all the required commands to be sent to the instance of parameter-framework launched
+# at runtime to generate the XML Settings file.
+# It takes as input the collection of criteria, the domains and the simplified settings read from
+# pfw.
+#
+def generateDomainCommands(logging, all_criteria, initial_settings, xml_domain_files, parsed_edds):
+        # create and inject all the criteria
+        logging.info("Creating all criteria")
+        for criterion in all_criteria:
+            yield ["createSelectionCriterion", criterion['inclusive'],
+                   criterion['name']] + criterion['values']
+
+        yield ["start"]
+
+        # Import initial settings file
+        if initial_settings:
+            logging.info("Importing initial settings file {}".format(initial_settings))
+            yield ["importDomainsWithSettingsXML", initial_settings]
+
+        # Import each standalone domain files
+        for domain_file in xml_domain_files:
+            logging.info("Importing single domain file {}".format(domain_file))
+            yield ["importDomainWithSettingsXML", domain_file]
+
+        # Generate the script for each EDD file
+        for filename, parsed_edd in parsed_edds:
+            logging.info("Translating and injecting EDD file {}".format(filename))
+            translator = PfwScriptTranslator()
+            parsed_edd.translate(translator)
+            for command in translator.getScript():
+                yield command
+
+#
+# Entry point of the domain generator.
+#       -Parses Criterion types and criteria files
+#       -Parses settings written in simplified pfw language.
+#       -Launches a parameter-framework
+#       -Translates the settings into command that can be interpreted by parameter-framework.
+#       -Use the exports command and output them in XML Settings file.
+#
+def main():
+    logging.root.setLevel(logging.INFO)
+    args = parseArgs()
+
+    all_criteria = parseCriteriaAndCriterionTypes(args.criteria, args.criteriontypes)
+
+    #
+    # EDD files (aka ".pfw" files)
+    #
+    parsed_edds = parseEdd(args.edd_files)
+
+    # We need to modify the toplevel configuration file to account for differences
+    # between development setup and target (installation) setup, in particular, the
+    # TuningMwith ode must be enforced, regardless of what will be allowed on the target
+    fake_toplevel_config = tempfile.NamedTemporaryFile(mode='w', delete=False, suffix=".xml",
+                                                       prefix="TMPdomainGeneratorPFConfig_")
+
+    install_path = os.path.dirname(os.path.realpath(args.toplevel_config))
+    hostConfig.configure(
+            infile=args.toplevel_config,
+            outfile=fake_toplevel_config,
+            structPath=install_path)
+    fake_toplevel_config.close()
+
+    # Create the connector. Pipe its input to us in order to write commands;
+    # connect its output to stdout in order to have it dump the domains
+    # there; connect its error output to stderr.
+    connector = subprocess.Popen(["domainGeneratorConnector",
+                            fake_toplevel_config.name,
+                            'verbose' if args.verbose else 'no-verbose',
+                            'validate' if args.validate else 'no-validate',
+                            args.schemas_dir],
+                           stdout=sys.stdout, stdin=subprocess.PIPE, stderr=sys.stderr)
+
+    initial_settings = None
+    if args.initial_settings:
+        initial_settings = os.path.realpath(args.initial_settings)
+
+    for command in generateDomainCommands(logging, all_criteria, initial_settings,
+                                       args.xml_domain_files, parsed_edds):
+        connector.stdin.write('\0'.join(command))
+        connector.stdin.write("\n")
+
+    # Closing the connector's input triggers the domain generation
+    connector.stdin.close()
+    connector.wait()
+    os.remove(fake_toplevel_config.name)
+    return connector.returncode
+
+# If this file is directly executed
+if __name__ == "__main__":
+    sys.exit(main())
diff --git a/services/audiopolicy/engineconfigurable/tools/provision_criterion_types_from_android_headers.mk b/services/audiopolicy/engineconfigurable/tools/provision_criterion_types_from_android_headers.mk
new file mode 100644
index 0000000..dab5a0f
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/tools/provision_criterion_types_from_android_headers.mk
@@ -0,0 +1,25 @@
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := optional
+LOCAL_ADDITIONAL_DEPENDENCIES += \
+    $(HOST_OUT_EXECUTABLES)/buildPolicyCriterionTypes.py \
+    $(CRITERION_TYPES_FILE) $(AUDIO_POLICY_CONFIGURATION_FILE) \
+    $(ANDROID_AUDIO_BASE_HEADER_FILE)
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): MY_CRITERION_TYPES_FILE := $(CRITERION_TYPES_FILE)
+$(LOCAL_BUILT_MODULE): MY_ANDROID_AUDIO_BASE_HEADER_FILE := $(ANDROID_AUDIO_BASE_HEADER_FILE)
+$(LOCAL_BUILT_MODULE): MY_AUDIO_POLICY_CONFIGURATION_FILE := $(AUDIO_POLICY_CONFIGURATION_FILE)
+$(LOCAL_BUILT_MODULE): MY_CRITERION_TOOL := $(HOST_OUT_EXECUTABLES)/buildPolicyCriterionTypes.py
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+
+	"$(MY_CRITERION_TOOL)" \
+		--androidaudiobaseheader "$(MY_ANDROID_AUDIO_BASE_HEADER_FILE)" \
+		--audiopolicyconfigurationfile "$(MY_AUDIO_POLICY_CONFIGURATION_FILE)" \
+		--criteriontypes "$(MY_CRITERION_TYPES_FILE)" \
+		--outputfile "$(@)"
+
+# Clear variables for further use
+CRITERION_TYPES_FILE :=
+ANDROID_AUDIO_BASE_HEADER_FILE :=
+AUDIO_POLICY_CONFIGURATION_FILE :=
diff --git a/services/audiopolicy/engineconfigurable/tools/provision_strategies_structure.mk b/services/audiopolicy/engineconfigurable/tools/provision_strategies_structure.mk
new file mode 100644
index 0000000..f2b1a19
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/tools/provision_strategies_structure.mk
@@ -0,0 +1,21 @@
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := optional
+LOCAL_ADDITIONAL_DEPENDENCIES += \
+    $(HOST_OUT_EXECUTABLES)/buildStrategiesStructureFile.py \
+    $(STRATEGIES_STRUCTURE_FILE) $(AUDIO_POLICY_ENGINE_CONFIGURATION_FILE)
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): MY_STRATEGIES_STRUCTURE_FILE := $(STRATEGIES_STRUCTURE_FILE)
+$(LOCAL_BUILT_MODULE): MY_AUDIO_POLICY_ENGINE_CONFIGURATION_FILE := $(AUDIO_POLICY_ENGINE_CONFIGURATION_FILE)
+$(LOCAL_BUILT_MODULE): MY_PROVISION_TOOL := $(HOST_OUT_EXECUTABLES)/buildStrategiesStructureFile.py
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+
+	"$(MY_PROVISION_TOOL)" \
+		--audiopolicyengineconfigurationfile "$(MY_AUDIO_POLICY_ENGINE_CONFIGURATION_FILE)" \
+		--productstrategiesstructurefile "$(MY_STRATEGIES_STRUCTURE_FILE)" \
+		--outputfile "$(@)"
+
+# Clear variables for further use
+STRATEGIES_STRUCTURE_FILE :=
+AUDIO_POLICY_ENGINE_CONFIGURATION_FILE :=
diff --git a/services/audiopolicy/engineconfigurable/wrapper/Android.bp b/services/audiopolicy/engineconfigurable/wrapper/Android.bp
new file mode 100644
index 0000000..6f59487
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/wrapper/Android.bp
@@ -0,0 +1,21 @@
+cc_library {
+    name: "libaudiopolicyengineconfigurable_pfwwrapper",
+    export_include_dirs: ["include"],
+    srcs: ["ParameterManagerWrapper.cpp"],
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+    ],
+    header_libs: [
+        "libbase_headers",
+        "libaudiopolicycommon",
+    ],
+    static_libs: ["libaudiopolicycomponents"],
+    shared_libs: [
+        "liblog",
+        "libutils",
+        "libmedia_helper",
+        "libparameter",
+    ],
+}
diff --git a/services/audiopolicy/engineconfigurable/wrapper/Android.mk b/services/audiopolicy/engineconfigurable/wrapper/Android.mk
deleted file mode 100644
index 36e0f42..0000000
--- a/services/audiopolicy/engineconfigurable/wrapper/Android.mk
+++ /dev/null
@@ -1,42 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-##################################################################
-# WRAPPER LIBRARY
-##################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_C_INCLUDES := \
-    $(LOCAL_PATH)/include \
-    frameworks/av/services/audiopolicy/engineconfigurable/include \
-    frameworks/av/services/audiopolicy/engineconfigurable/interface \
-    frameworks/av/services/audiopolicy/utilities/convert \
-
-LOCAL_SRC_FILES:= ParameterManagerWrapper.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-    libparameter \
-    libmedia_helper
-
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
-LOCAL_MODULE:= libaudiopolicypfwwrapper
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS := -Wall -Werror -Wextra
-
-include $(BUILD_STATIC_LIBRARY)
-
-##################################################################
-# CONFIGURATION FILE
-##################################################################
-
-# specific management of audio_policy_criteria.conf
-include $(CLEAR_VARS)
-LOCAL_MODULE := audio_policy_criteria.conf
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
-LOCAL_SRC_FILES := config/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
diff --git a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
index 9b0442e..4b57444 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
+++ b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
@@ -18,7 +18,6 @@
 //#define LOG_NDEBUG 0
 
 #include "ParameterManagerWrapper.h"
-#include "audio_policy_criteria_conf.h"
 #include <ParameterMgrPlatformConnector.h>
 #include <SelectionCriterionTypeInterface.h>
 #include <SelectionCriterionInterface.h>
@@ -56,15 +55,37 @@
     }
 };
 
-namespace android
-{
+namespace android {
 
 using utilities::convertTo;
 
-namespace audio_policy
-{
+namespace audio_policy {
+
 const char *const ParameterManagerWrapper::mPolicyPfwDefaultConfFileName =
     "/etc/parameter-framework/ParameterFrameworkConfigurationPolicy.xml";
+const char *const ParameterManagerWrapper::mPolicyPfwVendorConfFileName =
+    "/vendor/etc/parameter-framework/ParameterFrameworkConfigurationPolicy.xml";
+
+static const char *const gInputDeviceCriterionName = "AvailableInputDevices";
+static const char *const gOutputDeviceCriterionName = "AvailableOutputDevices";
+static const char *const gPhoneStateCriterionName = "TelephonyMode";
+static const char *const gOutputDeviceAddressCriterionName = "AvailableOutputDevicesAddresses";
+static const char *const gInputDeviceAddressCriterionName = "AvailableInputDevicesAddresses";
+
+/**
+ * Order MUST be align with defintiion of audio_policy_force_use_t within audio_policy.h
+ */
+static const char *const gForceUseCriterionTag[AUDIO_POLICY_FORCE_USE_CNT] =
+{
+    [AUDIO_POLICY_FORCE_FOR_COMMUNICATION] =        "ForceUseForCommunication",
+    [AUDIO_POLICY_FORCE_FOR_MEDIA] =                "ForceUseForMedia",
+    [AUDIO_POLICY_FORCE_FOR_RECORD] =               "ForceUseForRecord",
+    [AUDIO_POLICY_FORCE_FOR_DOCK] =                 "ForceUseForDock",
+    [AUDIO_POLICY_FORCE_FOR_SYSTEM] =               "ForceUseForSystem",
+    [AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] =    "ForceUseForHdmiSystemAudio",
+    [AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND] =     "ForceUseForEncodedSurround",
+    [AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING] =      "ForceUseForVibrateRinging"
+};
 
 template <>
 struct ParameterManagerWrapper::parameterManagerElementSupported<ISelectionCriterionInterface> {};
@@ -75,18 +96,43 @@
     : mPfwConnectorLogger(new ParameterMgrPlatformConnectorLogger)
 {
     // Connector
-    mPfwConnector = new CParameterMgrPlatformConnector(mPolicyPfwDefaultConfFileName);
+    if (access(mPolicyPfwVendorConfFileName, R_OK) == 0) {
+        mPfwConnector = new CParameterMgrPlatformConnector(mPolicyPfwVendorConfFileName);
+    } else {
+        mPfwConnector = new CParameterMgrPlatformConnector(mPolicyPfwDefaultConfFileName);
+    }
 
     // Logger
     mPfwConnector->setLogger(mPfwConnectorLogger);
+}
 
-    // Load criteria file
-    if ((loadAudioPolicyCriteriaConfig(gAudioPolicyCriteriaVendorConfFilePath) != NO_ERROR) &&
-        (loadAudioPolicyCriteriaConfig(gAudioPolicyCriteriaConfFilePath) != NO_ERROR)) {
-        ALOGE("%s: Neither vendor conf file (%s) nor system conf file (%s) could be found",
-              __FUNCTION__, gAudioPolicyCriteriaVendorConfFilePath,
-              gAudioPolicyCriteriaConfFilePath);
+status_t ParameterManagerWrapper::addCriterion(const std::string &name, bool isInclusive,
+                                               ValuePairs pairs, const std::string &defaultValue)
+{
+    ALOG_ASSERT(not isStarted(), "Cannot add a criterion if PFW is already started");
+    auto criterionType = mPfwConnector->createSelectionCriterionType(isInclusive);
+
+    for (auto pair : pairs) {
+        std::string error;
+        ALOGV("%s: Adding pair %d,%s for criterionType %s", __FUNCTION__, pair.first,
+              pair.second.c_str(), name.c_str());
+        criterionType->addValuePair(pair.first, pair.second, error);
     }
+    ALOG_ASSERT(mPolicyCriteria.find(name) == mPolicyCriteria.end(),
+                "%s: Criterion %s already added", __FUNCTION__, name.c_str());
+
+    auto criterion = mPfwConnector->createSelectionCriterion(name, criterionType);
+    mPolicyCriteria[name] = criterion;
+
+    if (not defaultValue.empty()) {
+        int numericalValue = 0;
+        if (not criterionType->getNumericalValue(defaultValue.c_str(), numericalValue)) {
+            ALOGE("%s; trying to apply invalid default literal value (%s)", __FUNCTION__,
+                  defaultValue.c_str());
+        }
+        criterion->setCriterionState(numericalValue);
+    }
+    return NO_ERROR;
 }
 
 ParameterManagerWrapper::~ParameterManagerWrapper()
@@ -112,112 +158,6 @@
     return NO_ERROR;
 }
 
-
-void ParameterManagerWrapper::addCriterionType(const string &typeName, bool isInclusive)
-{
-    ALOG_ASSERT(mPolicyCriterionTypes.find(typeName) == mPolicyCriterionTypes.end(),
-                      "CriterionType %s already added", typeName.c_str());
-    ALOGD("%s: Adding new criterionType %s", __FUNCTION__, typeName.c_str());
-
-    mPolicyCriterionTypes[typeName] = mPfwConnector->createSelectionCriterionType(isInclusive);
-}
-
-void ParameterManagerWrapper::addCriterionTypeValuePair(
-    const string &typeName,
-    uint32_t numericValue,
-    const string &literalValue)
-{
-    ALOG_ASSERT(mPolicyCriterionTypes.find(typeName) != mPolicyCriterionTypes.end(),
-                      "CriterionType %s not found", typeName.c_str());
-    ALOGV("%s: Adding new value pair (%d,%s) for criterionType %s", __FUNCTION__,
-          numericValue, literalValue.c_str(), typeName.c_str());
-    ISelectionCriterionTypeInterface *criterionType = mPolicyCriterionTypes[typeName];
-    std::string error;
-    criterionType->addValuePair(numericValue, literalValue, error);
-}
-
-void ParameterManagerWrapper::loadCriterionType(cnode *root, bool isInclusive)
-{
-    ALOG_ASSERT(root != NULL, "error in parsing file");
-    cnode *node;
-    for (node = root->first_child; node != NULL; node = node->next) {
-
-        ALOG_ASSERT(node != NULL, "error in parsing file");
-        const char *typeName = node->name;
-        char *valueNames = strndup(node->value, strlen(node->value));
-
-        addCriterionType(typeName, isInclusive);
-
-        uint32_t index = 0;
-        char *ctx;
-        char *valueName = strtok_r(valueNames, ",", &ctx);
-        while (valueName != NULL) {
-            if (strlen(valueName) != 0) {
-
-                // Conf file may use or not pair, if no pair, use incremental index, else
-                // use provided index.
-                if (strchr(valueName, ':') != NULL) {
-
-                    char *first = strtok(valueName, ":");
-                    char *second = strtok(NULL, ":");
-                    ALOG_ASSERT((first != NULL) && (strlen(first) != 0) &&
-                                      (second != NULL) && (strlen(second) != 0),
-                                      "invalid value pair");
-
-                    if (!convertTo<string, uint32_t>(first, index)) {
-                        ALOGE("%s: Invalid index(%s) found", __FUNCTION__, first);
-                    }
-                    addCriterionTypeValuePair(typeName, index, second);
-                } else {
-
-                    uint32_t pfwIndex = isInclusive ? 1 << index : index;
-                    addCriterionTypeValuePair(typeName, pfwIndex, valueName);
-                    index += 1;
-                }
-            }
-            valueName = strtok_r(NULL, ",", &ctx);
-        }
-        free(valueNames);
-    }
-}
-
-void ParameterManagerWrapper::loadInclusiveCriterionType(cnode *root)
-{
-    ALOG_ASSERT(root != NULL, "error in parsing file");
-    cnode *node = config_find(root, gInclusiveCriterionTypeTag.c_str());
-    if (node == NULL) {
-        return;
-    }
-    loadCriterionType(node, true);
-}
-
-void ParameterManagerWrapper::loadExclusiveCriterionType(cnode *root)
-{
-    ALOG_ASSERT(root != NULL, "error in parsing file");
-    cnode *node = config_find(root, gExclusiveCriterionTypeTag.c_str());
-    if (node == NULL) {
-        return;
-    }
-    loadCriterionType(node, false);
-}
-
-void ParameterManagerWrapper::parseChildren(cnode *root, string &defaultValue, string &type)
-{
-    ALOG_ASSERT(root != NULL, "error in parsing file");
-    cnode *node;
-    for (node = root->first_child; node != NULL; node = node->next) {
-        ALOG_ASSERT(node != NULL, "error in parsing file");
-
-        if (string(node->name) == gDefaultTag) {
-            defaultValue = node->value;
-        } else if (string(node->name) == gTypeTag) {
-            type = node->value;
-        } else {
-             ALOGE("%s: Unrecognized %s %s node", __FUNCTION__, node->name, node->value);
-        }
-    }
-}
-
 template <typename T>
 T *ParameterManagerWrapper::getElement(const string &name, std::map<string, T *> &elementsMap)
 {
@@ -236,97 +176,6 @@
     return it != elementsMap.end() ? it->second : NULL;
 }
 
-void ParameterManagerWrapper::loadCriteria(cnode *root)
-{
-    ALOG_ASSERT(root != NULL, "error in parsing file");
-    cnode *node = config_find(root, gCriterionTag.c_str());
-
-    if (node == NULL) {
-        ALOGW("%s: no inclusive criteria found", __FUNCTION__);
-        return;
-    }
-    for (node = node->first_child; node != NULL; node = node->next) {
-        loadCriterion(node);
-    }
-}
-
-void ParameterManagerWrapper::addCriterion(const string &name, const string &typeName,
-                              const string &defaultLiteralValue)
-{
-    ALOG_ASSERT(mPolicyCriteria.find(name) == mPolicyCriteria.end(),
-                "Route Criterion %s already added", name.c_str());
-
-    ISelectionCriterionTypeInterface *criterionType =
-            getElement<ISelectionCriterionTypeInterface>(typeName, mPolicyCriterionTypes);
-
-    ISelectionCriterionInterface *criterion =
-            mPfwConnector->createSelectionCriterion(name, criterionType);
-
-    mPolicyCriteria[name] = criterion;
-    int numericalValue = 0;
-    if (!criterionType->getNumericalValue(defaultLiteralValue.c_str(),  numericalValue)) {
-        ALOGE("%s; trying to apply invalid default literal value (%s)", __FUNCTION__,
-              defaultLiteralValue.c_str());
-    }
-    criterion->setCriterionState(numericalValue);
-}
-
-void ParameterManagerWrapper::loadCriterion(cnode *root)
-{
-    ALOG_ASSERT(root != NULL, "error in parsing file");
-    const char *criterionName = root->name;
-
-    ALOG_ASSERT(mPolicyCriteria.find(criterionName) == mPolicyCriteria.end(),
-                      "Criterion %s already added", criterionName);
-
-    string paramKeyName = "";
-    string path = "";
-    string typeName = "";
-    string defaultValue = "";
-
-    parseChildren(root, defaultValue, typeName);
-
-    addCriterion(criterionName, typeName, defaultValue);
-}
-
-void ParameterManagerWrapper::loadConfig(cnode *root)
-{
-    ALOG_ASSERT(root != NULL, "error in parsing file");
-    cnode *node = config_find(root, gPolicyConfTag.c_str());
-    if (node == NULL) {
-        ALOGW("%s: Could not find node for pfw", __FUNCTION__);
-        return;
-    }
-    ALOGD("%s: Loading conf for pfw", __FUNCTION__);
-    loadInclusiveCriterionType(node);
-    loadExclusiveCriterionType(node);
-    loadCriteria(node);
-}
-
-
-status_t ParameterManagerWrapper::loadAudioPolicyCriteriaConfig(const char *path)
-{
-    ALOG_ASSERT(path != NULL, "error in parsing file: empty path");
-    cnode *root;
-    char *data;
-    ALOGD("%s", __FUNCTION__);
-    data = (char *)load_file(path, NULL);
-    if (data == NULL) {
-        return -ENODEV;
-    }
-    root = config_node("", "");
-    ALOG_ASSERT(root != NULL, "Unable to allocate a configuration node");
-    config_load(root, data);
-
-    loadConfig(root);
-
-    config_free(root);
-    free(root);
-    free(data);
-    ALOGD("%s: loaded", __FUNCTION__);
-    return NO_ERROR;
-}
-
 bool ParameterManagerWrapper::isStarted()
 {
     return mPfwConnector && mPfwConnector->isStarted();
@@ -335,9 +184,9 @@
 status_t ParameterManagerWrapper::setPhoneState(audio_mode_t mode)
 {
     ISelectionCriterionInterface *criterion =
-            getElement<ISelectionCriterionInterface>(gPhoneStateCriterionTag, mPolicyCriteria);
+            getElement<ISelectionCriterionInterface>(gPhoneStateCriterionName, mPolicyCriteria);
     if (criterion == NULL) {
-        ALOGE("%s: no criterion found for %s", __FUNCTION__, gPhoneStateCriterionTag.c_str());
+        ALOGE("%s: no criterion found for %s", __FUNCTION__, gPhoneStateCriterionName);
         return BAD_VALUE;
     }
     if (!isValueValidForCriterion(criterion, static_cast<int>(mode))) {
@@ -351,9 +200,9 @@
 audio_mode_t ParameterManagerWrapper::getPhoneState() const
 {
     const ISelectionCriterionInterface *criterion =
-            getElement<ISelectionCriterionInterface>(gPhoneStateCriterionTag, mPolicyCriteria);
+            getElement<ISelectionCriterionInterface>(gPhoneStateCriterionName, mPolicyCriteria);
     if (criterion == NULL) {
-        ALOGE("%s: no criterion found for %s", __FUNCTION__, gPhoneStateCriterionTag.c_str());
+        ALOGE("%s: no criterion found for %s", __FUNCTION__, gPhoneStateCriterionName);
         return AUDIO_MODE_NORMAL;
     }
     return static_cast<audio_mode_t>(criterion->getCriterionState());
@@ -370,7 +219,7 @@
     ISelectionCriterionInterface *criterion =
             getElement<ISelectionCriterionInterface>(gForceUseCriterionTag[usage], mPolicyCriteria);
     if (criterion == NULL) {
-        ALOGE("%s: no criterion found for %s", __FUNCTION__, gForceUseCriterionTag[usage].c_str());
+        ALOGE("%s: no criterion found for %s", __FUNCTION__, gForceUseCriterionTag[usage]);
         return BAD_VALUE;
     }
     if (!isValueValidForCriterion(criterion, static_cast<int>(config))) {
@@ -390,7 +239,7 @@
     const ISelectionCriterionInterface *criterion =
             getElement<ISelectionCriterionInterface>(gForceUseCriterionTag[usage], mPolicyCriteria);
     if (criterion == NULL) {
-        ALOGE("%s: no criterion found for %s", __FUNCTION__, gForceUseCriterionTag[usage].c_str());
+        ALOGE("%s: no criterion found for %s", __FUNCTION__, gForceUseCriterionTag[usage]);
         return AUDIO_POLICY_FORCE_NONE;
     }
     return static_cast<audio_policy_forced_cfg_t>(criterion->getCriterionState());
@@ -404,12 +253,45 @@
     return interface->getLiteralValue(valueToCheck, literalValue);
 }
 
+status_t ParameterManagerWrapper::setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
+                                                           audio_policy_dev_state_t state)
+{
+    std::string criterionName = audio_is_output_device(devDesc->type()) ?
+                gOutputDeviceAddressCriterionName : gInputDeviceAddressCriterionName;
+
+    ALOGV("%s: device with address %s %s", __FUNCTION__, devDesc->address().string(),
+          state != AUDIO_POLICY_DEVICE_STATE_AVAILABLE? "disconnected" : "connected");
+    ISelectionCriterionInterface *criterion =
+            getElement<ISelectionCriterionInterface>(criterionName, mPolicyCriteria);
+
+    if (criterion == NULL) {
+        ALOGE("%s: no criterion found for %s", __FUNCTION__, criterionName.c_str());
+        return DEAD_OBJECT;
+    }
+
+    auto criterionType = criterion->getCriterionType();
+    int deviceAddressId;
+    if (not criterionType->getNumericalValue(devDesc->address().string(), deviceAddressId)) {
+        ALOGW("%s: unknown device address reported (%s)", __FUNCTION__, devDesc->address().c_str());
+        return BAD_TYPE;
+    }
+    int currentValueMask = criterion->getCriterionState();
+    if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
+        currentValueMask |= deviceAddressId;
+    }
+    else {
+        currentValueMask &= ~deviceAddressId;
+    }
+    criterion->setCriterionState(currentValueMask);
+    return NO_ERROR;
+}
+
 status_t ParameterManagerWrapper::setAvailableInputDevices(audio_devices_t inputDevices)
 {
     ISelectionCriterionInterface *criterion =
-            getElement<ISelectionCriterionInterface>(gInputDeviceCriterionTag, mPolicyCriteria);
+            getElement<ISelectionCriterionInterface>(gInputDeviceCriterionName, mPolicyCriteria);
     if (criterion == NULL) {
-        ALOGE("%s: no criterion found for %s", __FUNCTION__, gInputDeviceCriterionTag.c_str());
+        ALOGE("%s: no criterion found for %s", __FUNCTION__, gInputDeviceCriterionName);
         return DEAD_OBJECT;
     }
     criterion->setCriterionState(inputDevices & ~AUDIO_DEVICE_BIT_IN);
@@ -420,9 +302,9 @@
 status_t ParameterManagerWrapper::setAvailableOutputDevices(audio_devices_t outputDevices)
 {
     ISelectionCriterionInterface *criterion =
-            getElement<ISelectionCriterionInterface>(gOutputDeviceCriterionTag, mPolicyCriteria);
+            getElement<ISelectionCriterionInterface>(gOutputDeviceCriterionName, mPolicyCriteria);
     if (criterion == NULL) {
-        ALOGE("%s: no criterion found for %s", __FUNCTION__, gOutputDeviceCriterionTag.c_str());
+        ALOGE("%s: no criterion found for %s", __FUNCTION__, gOutputDeviceCriterionName);
         return DEAD_OBJECT;
     }
     criterion->setCriterionState(outputDevices);
diff --git a/services/audiopolicy/engineconfigurable/wrapper/audio_policy_criteria_conf.h b/services/audiopolicy/engineconfigurable/wrapper/audio_policy_criteria_conf.h
deleted file mode 100644
index e4fd176..0000000
--- a/services/audiopolicy/engineconfigurable/wrapper/audio_policy_criteria_conf.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <string>
-#include <system/audio_policy.h>
-
-//////////////////////////////////////////////////////////////////////////////////////////////////
-//      Definitions for audio policy criteria configuration file (audio_policy_criteria.conf)   //
-//                                                                                              //
-//      @TODO: scripted from audio.h & audio_policy,h                                           //
-//////////////////////////////////////////////////////////////////////////////////////////////////
-
-static const char *const gAudioPolicyCriteriaConfFilePath =
-    "/system/etc/audio_policy_criteria.conf";
-static const char *const gAudioPolicyCriteriaVendorConfFilePath =
-    "/vendor/etc/audio_policy_criteria.conf";
-
-/**
- * PFW instances tags
- */
-static const std::string &gPolicyConfTag = "Policy";
-static const std::string &gDefaultTag = "Default";
-static const std::string &gTypeTag = "Type";
-
-/**
- * PFW elements tags
- */
-static const std::string &gInclusiveCriterionTypeTag = "InclusiveCriterionType";
-static const std::string &gExclusiveCriterionTypeTag = "ExclusiveCriterionType";
-static const std::string &gCriterionTag = "Criterion";
-
-/**
- * PFW known criterion tags
- */
-static const std::string &gInputDeviceCriterionTag = "AvailableInputDevices";
-static const std::string &gOutputDeviceCriterionTag = "AvailableOutputDevices";
-static const std::string &gPhoneStateCriterionTag = "TelephonyMode";
-
-/**
- * Order MUST be align with defintiion of audio_policy_force_use_t within audio_policy.h
- */
-static const std::string gForceUseCriterionTag[AUDIO_POLICY_FORCE_USE_CNT] =
-{
-    [AUDIO_POLICY_FORCE_FOR_COMMUNICATION] =        "ForceUseForCommunication",
-    [AUDIO_POLICY_FORCE_FOR_MEDIA] =                "ForceUseForMedia",
-    [AUDIO_POLICY_FORCE_FOR_RECORD] =               "ForceUseForRecord",
-    [AUDIO_POLICY_FORCE_FOR_DOCK] =                 "ForceUseForDock",
-    [AUDIO_POLICY_FORCE_FOR_SYSTEM] =               "ForceUseForSystem",
-    [AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] =    "ForceUseForHdmiSystemAudio",
-    [AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND] =     "ForceUseForEncodedSurround",
-    [AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING] =      "ForceUseForVibrateRinging"
-};
-
-
-
-
-
-
diff --git a/services/audiopolicy/engineconfigurable/wrapper/config/audio_policy_criteria.conf b/services/audiopolicy/engineconfigurable/wrapper/config/audio_policy_criteria.conf
deleted file mode 100644
index 043d5a6..0000000
--- a/services/audiopolicy/engineconfigurable/wrapper/config/audio_policy_criteria.conf
+++ /dev/null
@@ -1,146 +0,0 @@
-################################################################################################
-#
-# @NOTE:
-# Audio Policy Criteria file example for generic device build
-#
-# Any vendor shall have its own configuration within the corresponding device folder
-#
-################################################################################################
-
-#########################################################
-# Criterion type Example:
-# For each criterion, a couple of numerical, literal values must be provided to the PFW.
-# The numerical part is not mandatory. If not filled by the user, a default numerical value will be
-# automatically provided by audio HAL using the following logic:
-#   - Exclusive criterion:
-#          * 0 -> first literal value,
-#          * 1 -> second literal value,
-#               ...
-#          * N -> (N+1)th literal value.
-#   - Inclusive criterion:
-#          * 1 << 0 -> first literal value,
-#          * 1 << 1 -> second literal value,
-#               ...
-#          * 1 << N -> (N+1)th literal value,
-#
-#########################################################
-# Policy {
-#    InclusiveCriterionType|ExclusiveCriterionType {
-#        <Criterion Name>  [numerical value 1:]<literal value 1>,[numerical value 2:]<literal value 2>,<literal value 3>,...
-#    }
-# }
-
-#########################################################
-# Criterion:
-#########################################################
-# Policy {
-#    Criterion {
-#        <Criterion Name> {
-#            Type            <Criterion type name>
-#            Default         <default value of the criterion>
-#        }
-#    }
-# }
-
-Policy {
-    InclusiveCriterionType {
-        #
-        # DO NOT CHANGE ORDER. This definition must be aligned with the definition of
-        # AUDIO_DEVICE_OUT_* within <system/audio.h> file of android.
-        #
-        OutputDevicesMaskType   Earpiece,Speaker,WiredHeadset,WiredHeadphone,BluetoothSco,BluetoothScoHeadset,BluetoothScoCarkit,BluetoothA2dp,BluetoothA2dpHeadphones,BluetoothA2dpSpeaker,Hdmi,AnlgDockHeadset,DgtlDockHeadset,UsbAccessory,UsbDevice,RemoteSubmix,TelephonyTx,Line,HdmiArc,Spdif,Fm,AuxLine,SpeakerSafe
-        #
-        # DO NOT CHANGE ORDER. This definition must be aligned with the definition of
-        # AUDIO_DEVICE_IN_* within <system/audio.h> file of android.
-        # Note also that direction bit will be decimated by AudioHAL in order to allow using a mask
-        # with the cardinality of 1 between a bit and an input device.
-        #
-        InputDevicesMaskType    Communication,Ambient,BuiltinMic,BluetoothScoHeadset,WiredHeadset,Hdmi,TelephonyRx,BackMic,RemoteSubmix,AnlgDockHeadset,DgtlDockHeadset,UsbAccessory,UsbDevice,FmTuner,TvTune,Line,Spdif,BluetoothA2dp,Loopback
-    }
-    ExclusiveCriterionType {
-        #
-        # The values of the mode MUST be aligned with the definition of the audio_mode_t
-        # from system/audio.h
-        #
-        AndroidModeType     0:Normal,1:RingTone,2:InCall,3:InCommunication
-        #
-        # The values of the mode MUST be aligned with the definition of the
-        # audio_policy_forced_config_t from system/audio.h
-        #
-        ForceUseForCommunicationType    0:ForceNone,1:ForceSpeaker,3:ForceBtSco
-        #
-        # The values of the mode MUST be aligned with the definition of the
-        # audio_policy_forced_config_t from system/audio.h
-        #
-        ForceUseForMediaType            0:ForceNone,1:ForceSpeaker,2:ForceHeadphones,4:ForceBtA2dp,5:ForceWiredAccessory,8:ForceAnalogDock,9:ForceDigitalDock,10:ForceNoBtA2dp
-        #
-        # The values of the mode MUST be aligned with the definition of the
-        # audio_policy_forced_config_t from system/audio.h
-        #
-        ForceUseForRecordType           0:ForceNone,3:ForceBtSco,5:ForceWiredAccessory
-        #
-        # The values of the mode MUST be aligned with the definition of the
-        # audio_policy_forced_config_t from system/audio.h
-        #
-        ForceUseForDockType             0:ForceNone,5:ForceWiredAccessory,6:ForceBtCarDock,7:ForceBtDeskDock,8:ForceAnalogDock,9:ForceDigitalDock
-        #
-        # The values of the mode MUST be aligned with the definition of the
-        # audio_policy_forced_config_t from system/audio.h
-        #
-        ForceUseForSystemType           0:ForceNone,11:ForceSystemEnforced
-        #
-        # The values of the mode MUST be aligned with the definition of the
-        # audio_policy_forced_config_t from system/audio.h
-        #
-        ForceUseForHdmiSystemAudioType  0:ForceNone,12:ForceHdmiSystemEnforced
-        #
-        # The values of the mode MUST be aligned with the definition of the
-        # audio_policy_forced_config_t from system/audio_policy.h
-        #
-        ForceUseForEncodedSurroundType  0:ForceNone,13:ForceEncodedSurroundNever,14:ForceEncodedSurroundAlways
-    }
-
-    Criterion {
-        AvailableInputDevices {
-            Type            InputDevicesMaskType
-            Default         none
-        }
-        AvailableOutputDevices {
-            Type            OutputDevicesMaskType
-            Default         none
-        }
-        TelephonyMode {
-            Type            AndroidModeType
-            Default         Normal
-        }
-        ForceUseForCommunication {
-            Type            ForceUseForCommunicationType
-            Default         ForceNone
-        }
-        ForceUseForMedia {
-            Type            ForceUseForMediaType
-            Default         ForceNone
-        }
-        ForceUseForRecord {
-            Type            ForceUseForRecordType
-            Default         ForceNone
-        }
-        ForceUseForDock {
-            Type            ForceUseForDockType
-            Default         ForceNone
-        }
-        ForceUseForSystem {
-            Type            ForceUseForSystemType
-            Default         ForceNone
-        }
-        ForceUseForHdmiSystemAudio {
-            Type            ForceUseForHdmiSystemAudioType
-            Default         ForceNone
-        }
-        ForceUseForEncodedSurround {
-            Type            ForceUseForEncodedSurroundType
-            Default         ForceNone
-        }
-    }
-}
-
diff --git a/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h b/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
index 4c1acfe..5bfad29 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
+++ b/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
@@ -16,10 +16,15 @@
 
 #pragma once
 
+#include <AudioGain.h>
+#include <AudioPort.h>
+#include <HwModule.h>
+#include <DeviceDescriptor.h>
 #include <system/audio.h>
 #include <system/audio_policy.h>
 #include <utils/Errors.h>
 #include <utils/RWLock.h>
+#include <utils/RefBase.h>
 #include <list>
 #include <map>
 #include <string>
@@ -27,27 +32,20 @@
 
 class CParameterMgrPlatformConnector;
 class ISelectionCriterionInterface;
-class ISelectionCriterionTypeInterface;
 struct cnode;
 
 class ParameterMgrPlatformConnectorLogger;
 
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
+
+using ValuePair = std::pair<uint32_t, std::string>;
+using ValuePairs = std::vector<ValuePair>;
 
 class ParameterManagerWrapper
 {
 private:
-    typedef std::pair<int, const char *> CriterionTypeValuePair;
-
-    typedef std::map<std::string, ISelectionCriterionInterface *> CriterionCollection;
-    typedef std::map<std::string, ISelectionCriterionTypeInterface *> CriterionTypeCollection;
-    typedef CriterionCollection::iterator CriterionMapIterator;
-    typedef CriterionCollection::const_iterator CriterionMapConstIterator;
-    typedef CriterionTypeCollection::iterator CriterionTypeMapIterator;
-    typedef CriterionTypeCollection::const_iterator CriteriaTypeMapConstIterator;
+    using Criteria = std::map<std::string, ISelectionCriterionInterface *>;
 
 public:
     ParameterManagerWrapper();
@@ -120,6 +118,20 @@
      */
     status_t setAvailableOutputDevices(audio_devices_t outputDevices);
 
+    status_t setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
+                                      audio_policy_dev_state_t state);
+
+    /**
+     * @brief addCriterion to the policy pfw
+     * @param name of the criterion
+     * @param isInclusive if true, inclusive, if false exclusive criterion type
+     * @param pairs of numerical/literal values of the criterion
+     * @param defaultValue provided as literal.
+     * @return
+     */
+    status_t addCriterion(const std::string &name, bool isInclusive, ValuePairs pairs,
+                          const std::string &defaultValue);
+
 private:
     /**
      * Apply the configuration of the platform on the policy parameter manager.
@@ -133,96 +145,7 @@
      */
     void applyPlatformConfiguration();
 
-    /**
-     * Load the criterion configuration file.
-     *
-     * @param[in] path Criterion conf file path.
-     *
-     * @return NO_ERROR is parsing successful, error code otherwise.
-     */
-    status_t loadAudioPolicyCriteriaConfig(const char *path);
-
-    /**
-     * Add a criterion type to AudioPolicyPfw.
-     *
-     * @param[in] typeName of the PFW criterion type.
-     * @param[in] isInclusive attribute of the criterion type.
-     */
-    void addCriterionType(const std::string &typeName, bool isInclusive);
-
-    /**
-     * Add a criterion type value pair to AudioPolicyPfw.
-     *
-     * @param[in] typeName criterion type name to which this value pair is added to.
-     * @param[in] numeric part of the value pair.
-     * @param[in] literal part of the value pair.
-     */
-    void addCriterionTypeValuePair(const std::string &typeName, uint32_t numeric,
-                                   const std::string &literal);
-
-    /**
-     * Add a criterion to AudioPolicyPfw.
-     *
-     * @param[in] name of the PFW criterion.
-     * @param[in] typeName criterion type name to which this criterion is associated to.
-     * @param[in] defaultLiteralValue of the PFW criterion.
-     */
-    void addCriterion(const std::string &name,
-                      const std::string &typeName,
-                      const std::string &defaultLiteralValue);
-    /**
-     * Parse and load the inclusive criterion type from configuration file.
-     *
-     * @param[in] root node of the configuration file.
-     */
-    void loadInclusiveCriterionType(cnode *root);
-
-    /**
-     * Parse and load the exclusive criterion type from configuration file.
-     *
-     * @param[in] root node of the configuration file.
-     */
-    void loadExclusiveCriterionType(cnode *root);
-
-    /**
-     * Parse and load the criteria from configuration file.
-     *
-     * @param[in] root node of the configuration file.
-     */
-    void loadCriteria(cnode *root);
-
-    /**
-     * Parse and load a criterion from configuration file.
-     *
-     * @param[in] root node of the configuration file.
-     */
-    void loadCriterion(cnode *root);
-
-    /**
-     * Parse and load the criterion types from configuration file.
-     *
-     * @param[in] root node of the configuration file
-     * @param[in] isInclusive true if inclusive, false is exclusive.
-     */
-    void loadCriterionType(cnode *root, bool isInclusive);
-
-    /**
-     * Load the configuration file.
-     *
-     * @param[in] root node of the configuration file.
-     */
-    void loadConfig(cnode *root);
-
-    /**
-     * Parse and load the chidren node from a given root node.
-     *
-     * @param[in] root node of the configuration file
-     * @param[out] defaultValue of the parameter manager element to retrieve.
-     * @param[out] type of the parameter manager element to retrieve.
-    */
-    void parseChildren(cnode *root, std::string &defaultValue, std::string &type);
-
-    /**
+     /**
      * Retrieve an element from a map by its name.
      *
      * @tparam T type of element to search.
@@ -266,8 +189,7 @@
 
     bool isValueValidForCriterion(ISelectionCriterionInterface *criterion, int valueToCheck);
 
-    CriterionTypeCollection mPolicyCriterionTypes; /**< Policy Criterion Type map. */
-    CriterionCollection mPolicyCriteria; /**< Policy Criterion Map. */
+    Criteria mPolicyCriteria; /**< Policy Criterion Map. */
 
     CParameterMgrPlatformConnector *mPfwConnector; /**< Policy Parameter Manager connector. */
     ParameterMgrPlatformConnectorLogger *mPfwConnectorLogger; /**< Policy PFW logger. */
@@ -284,6 +206,7 @@
     struct parameterManagerElementSupported;
 
     static const char *const mPolicyPfwDefaultConfFileName; /**< Default Policy PFW top file name.*/
+    static const char *const mPolicyPfwVendorConfFileName; /**< Vendor Policy PFW top file name.*/
 };
 
 } // namespace audio_policy
diff --git a/services/audiopolicy/enginedefault/Android.bp b/services/audiopolicy/enginedefault/Android.bp
new file mode 100644
index 0000000..7b42c6a
--- /dev/null
+++ b/services/audiopolicy/enginedefault/Android.bp
@@ -0,0 +1,32 @@
+cc_library_shared {
+    name: "libaudiopolicyenginedefault",
+    export_include_dirs: ["include"],
+    srcs: [
+        "src/Engine.cpp",
+        "src/EngineInstance.cpp",
+    ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+    ],
+    local_include_dirs: ["include"],
+    header_libs: [
+        "libbase_headers",
+        "libaudiopolicycommon",
+        "libaudiopolicyengine_interface_headers",
+    ],
+    static_libs: [
+        "libaudiopolicycomponents",
+        "libaudiopolicyengine_common",
+        "libaudiopolicyengine_config",
+    ],
+    shared_libs: [
+        "liblog",
+        "libcutils",
+        "libutils",
+        "libmedia_helper",
+        "libaudiopolicy",
+        "libxml2",
+    ],
+}
diff --git a/services/audiopolicy/enginedefault/Android.mk b/services/audiopolicy/enginedefault/Android.mk
deleted file mode 100644
index cbbe306..0000000
--- a/services/audiopolicy/enginedefault/Android.mk
+++ /dev/null
@@ -1,46 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-# Component build
-#######################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-    src/Engine.cpp \
-    src/EngineInstance.cpp \
-
-audio_policy_engine_includes_common := \
-    $(LOCAL_PATH)/include \
-    frameworks/av/services/audiopolicy/engine/interface
-
-LOCAL_CFLAGS += \
-    -Wall \
-    -Werror \
-    -Wextra \
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := \
-    $(audio_policy_engine_includes_common)
-
-LOCAL_C_INCLUDES := \
-    $(audio_policy_engine_includes_common) \
-    $(TARGET_OUT_HEADERS)/hw \
-    $(call include-path-for, frameworks-av) \
-    $(call include-path-for, audio-utils) \
-    $(call include-path-for, bionic) \
-    frameworks/av/services/audiopolicy/common/include
-
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
-LOCAL_MODULE := libaudiopolicyenginedefault
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_STATIC_LIBRARIES := \
-    libaudiopolicycomponents \
-
-LOCAL_SHARED_LIBRARIES += \
-    liblog \
-    libcutils \
-    libutils \
-    libmedia_helper
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/services/audiopolicy/enginedefault/config/example/Android.mk b/services/audiopolicy/enginedefault/config/example/Android.mk
new file mode 100644
index 0000000..0badac8
--- /dev/null
+++ b/services/audiopolicy/enginedefault/config/example/Android.mk
@@ -0,0 +1,48 @@
+LOCAL_PATH := $(call my-dir)
+
+##################################################################
+# CONFIGURATION TOP FILE
+##################################################################
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_default)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_configuration.xml
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := phone/$(LOCAL_MODULE)
+
+LOCAL_REQUIRED_MODULES := \
+    audio_policy_engine_product_strategies.xml \
+    audio_policy_engine_stream_volumes.xml \
+    audio_policy_engine_default_stream_volumes.xml
+
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_product_strategies.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := phone/$(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_stream_volumes.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := phone/$(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_default_stream_volumes.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := phone/$(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_default)
diff --git a/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_configuration.xml b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_configuration.xml
new file mode 100644
index 0000000..4ca33b4
--- /dev/null
+++ b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_configuration.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+     -->
+
+<configuration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+
+    <xi:include href="audio_policy_engine_product_strategies.xml"/>
+    <xi:include href="audio_policy_engine_stream_volumes.xml"/>
+    <xi:include href="audio_policy_engine_default_stream_volumes.xml"/>
+
+</configuration>
+
diff --git a/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_default_stream_volumes.xml b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_default_stream_volumes.xml
new file mode 100644
index 0000000..21e6dd5
--- /dev/null
+++ b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_default_stream_volumes.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<!-- Default Volume Tables included by Audio Policy Configuration file -->
+<!-- Full Default Volume table for all device category -->
+<volumes>
+    <reference name="FULL_SCALE_VOLUME_CURVE">
+    <!-- Full Scale reference Volume Curve -->
+        <point>0,0</point>
+        <point>100,0</point>
+    </reference>
+    <reference name="SILENT_VOLUME_CURVE">
+        <point>0,-9600</point>
+        <point>100,-9600</point>
+    </reference>
+    <reference name="DEFAULT_SYSTEM_VOLUME_CURVE">
+    <!-- Default System reference Volume Curve -->
+        <point>1,-2400</point>
+        <point>33,-1800</point>
+        <point>66,-1200</point>
+        <point>100,-600</point>
+    </reference>
+    <reference name="DEFAULT_MEDIA_VOLUME_CURVE">
+    <!-- Default Media reference Volume Curve -->
+        <point>1,-5800</point>
+        <point>20,-4000</point>
+        <point>60,-1700</point>
+        <point>100,0</point>
+    </reference>
+    <reference name="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE">
+    <!--Default Volume Curve -->
+        <point>1,-4950</point>
+        <point>33,-3350</point>
+        <point>66,-1700</point>
+        <point>100,0</point>
+    </reference>
+    <reference name="DEFAULT_DEVICE_CATEGORY_SPEAKER_VOLUME_CURVE">
+    <!-- Default is Speaker Media Volume Curve -->
+        <point>1,-5800</point>
+        <point>20,-4000</point>
+        <point>60,-1700</point>
+        <point>100,0</point>
+    </reference>
+    <reference name="DEFAULT_DEVICE_CATEGORY_SPEAKER_SYSTEM_VOLUME_CURVE">
+    <!-- Default is Speaker System Volume Curve -->
+        <point>1,-4680</point>
+        <point>42,-2070</point>
+        <point>85,-540</point>
+        <point>100,0</point>
+    </reference>
+    <reference name="DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE">
+    <!--Default Volume Curve -->
+        <point>1,-4950</point>
+        <point>33,-3350</point>
+        <point>66,-1700</point>
+        <point>100,0</point>
+    </reference>
+    <reference name="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE">
+    <!-- Default is Ext Media System Volume Curve -->
+        <point>1,-5800</point>
+        <point>20,-4000</point>
+        <point>60,-2100</point>
+        <point>100,-1000</point>
+    </reference>
+    <reference name="DEFAULT_HEARING_AID_VOLUME_CURVE">
+    <!-- Default Hearing Aid Volume Curve -->
+        <point>1,-12700</point>
+        <point>20,-8000</point>
+        <point>60,-4000</point>
+        <point>100,0</point>
+    </reference>
+    <!-- **************************************************************** -->
+    <!-- Non-mutable default volume curves:                               -->
+    <!--     * first point is always for index 0                          -->
+    <!--     * attenuation is small enough that stream can still be heard -->
+    <reference name="DEFAULT_NON_MUTABLE_VOLUME_CURVE">
+    <!-- Default non-mutable reference Volume Curve -->
+    <!--        based on DEFAULT_MEDIA_VOLUME_CURVE -->
+        <point>0,-5800</point>
+        <point>20,-4000</point>
+        <point>60,-1700</point>
+        <point>100,0</point>
+    </reference>
+    <reference name="DEFAULT_NON_MUTABLE_HEADSET_VOLUME_CURVE">
+    <!--Default non-mutable Volume Curve for headset -->
+    <!--    based on DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE -->
+        <point>0,-4950</point>
+        <point>33,-3350</point>
+        <point>66,-1700</point>
+        <point>100,0</point>
+    </reference>
+    <reference name="DEFAULT_NON_MUTABLE_SPEAKER_VOLUME_CURVE">
+    <!-- Default non-mutable Speaker Volume Curve -->
+    <!--    based on DEFAULT_DEVICE_CATEGORY_SPEAKER_VOLUME_CURVE -->
+        <point>0,-5800</point>
+        <point>20,-4000</point>
+        <point>60,-1700</point>
+        <point>100,0</point>
+    </reference>
+    <reference name="DEFAULT_NON_MUTABLE_EARPIECE_VOLUME_CURVE">
+    <!--Default non-mutable Volume Curve -->
+    <!--    based on DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE -->
+        <point>0,-4950</point>
+        <point>33,-3350</point>
+        <point>66,-1700</point>
+        <point>100,0</point>
+    </reference>
+    <reference name="DEFAULT_NON_MUTABLE_EXT_VOLUME_CURVE">
+    <!-- Default non-mutable Ext Media System Volume Curve -->
+    <!--     based on DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE -->
+        <point>0,-5800</point>
+        <point>20,-4000</point>
+        <point>60,-2100</point>
+        <point>100,-1000</point>
+    </reference>
+    <reference name="DEFAULT_NON_MUTABLE_HEARING_AID_VOLUME_CURVE">
+    <!-- Default non-mutable Hearing Aid Volume Curve -->
+    <!--     based on DEFAULT_HEARING_AID_VOLUME_CURVE -->
+        <point>0,-12700</point>
+        <point>20,-8000</point>
+        <point>60,-4000</point>
+        <point>100,0</point>
+    </reference>
+</volumes>
diff --git a/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml
new file mode 100644
index 0000000..9398743
--- /dev/null
+++ b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+     -->
+
+<ProductStrategies>
+
+    <!-- "hidden strategies" like TTS, enforced audible:
+            Shall we expose them here or keep it hard coded -->
+
+    <!-- Used to identify the volume of audio streams for enforced system sounds in certain
+         countries (e.g. camera in Japan)
+         This strategy will only have higher priority than phone if force for system is set to
+         enforced. -->
+
+    <ProductStrategy name="STRATEGY_PHONE">
+        <AttributesGroup streamType="AUDIO_STREAM_VOICE_CALL" volumeGroup="voice_call">
+            <Attributes> <Usage value="AUDIO_USAGE_VOICE_COMMUNICATION"/> </Attributes>
+        </AttributesGroup>
+        <AttributesGroup streamType="AUDIO_STREAM_BLUETOOTH_SCO" volumeGroup="bluetooth_sco">
+            <Attributes> <Flags value="AUDIO_FLAG_SCO"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="STRATEGY_SONIFICATION">
+        <AttributesGroup streamType="AUDIO_STREAM_RING" volumeGroup="ring">
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE"/> </Attributes>
+        </AttributesGroup>
+        <AttributesGroup streamType="AUDIO_STREAM_ALARM" volumeGroup="alarm">
+            <Attributes> <Usage value="AUDIO_USAGE_ALARM"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="STRATEGY_ENFORCED_AUDIBLE">
+        <AttributesGroup streamType="AUDIO_STREAM_ENFORCED_AUDIBLE" volumeGroup="enforced_audible">
+            <Attributes> <Flags value="AUDIO_FLAG_AUDIBILITY_ENFORCED"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="STRATEGY_ACCESSIBILITY">
+        <AttributesGroup streamType="AUDIO_STREAM_ACCESSIBILITY" volumeGroup="accessibility">
+            <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="STRATEGY_SONIFICATION_RESPECTFUL">
+        <AttributesGroup streamType="AUDIO_STREAM_NOTIFICATION" volumeGroup="notification">
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_EVENT"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="STRATEGY_MEDIA">
+         <AttributesGroup streamType="AUDIO_STREAM_MUSIC" volumeGroup="music">
+            <Attributes> <Usage value="AUDIO_USAGE_MEDIA"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_GAME"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_ASSISTANT"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/> </Attributes>
+            <Attributes></Attributes>
+        </AttributesGroup>
+        <AttributesGroup streamType="AUDIO_STREAM_SYSTEM" volumeGroup="system">
+            <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="STRATEGY_DTMF">
+        <AttributesGroup streamType="AUDIO_STREAM_DTMF" volumeGroup="dtmf">
+            <Attributes> <Usage value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <!-- Used to identify the volume of audio streams exclusively transmitted through the  speaker
+         (TTS) of the device -->
+    <ProductStrategy name="STRATEGY_TRANSMITTED_THROUGH_SPEAKER">
+        <AttributesGroup streamType="AUDIO_STREAM_TTS" volumeGroup="tts">
+            <Attributes> <Flags value="AUDIO_FLAG_BEACON"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <!-- Routing Strategy rerouting may be removed as following media??? -->
+    <ProductStrategy name="STRATEGY_REROUTING">
+        <AttributesGroup streamType="AUDIO_STREAM_REROUTING" volumeGroup="rerouting">
+            <Attributes></Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <!-- Default product strategy has empty attributes -->
+    <ProductStrategy name="STRATEGY_PATCH">
+        <AttributesGroup streamType="AUDIO_STREAM_PATCH" volumeGroup="patch">
+            <Attributes></Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+
+</ProductStrategies>
+
diff --git a/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_stream_volumes.xml b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_stream_volumes.xml
new file mode 100644
index 0000000..707a184
--- /dev/null
+++ b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_stream_volumes.xml
@@ -0,0 +1,231 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<!-- Volume section defines a volume curve for a given use case and device category.
+It contains a list of points of this curve expressing the attenuation in Millibels for a given
+volume index from 0 to 100.
+<volume deviceCategory=””>
+<point>0,-9600</point>
+<point>100,0</point>
+</volume>
+-->
+
+<volumeGroups>
+    <volumeGroup>
+        <name>voice_call</name>
+        <indexMin>1</indexMin>
+        <indexMax>7</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-2400</point>
+            <point>33,-1600</point>
+            <point>66,-800</point>
+            <point>100,0</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE">
+            <point>0,-2700</point>
+            <point>33,-1800</point>
+            <point>66,-900</point>
+            <point>100,0</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>system</name>
+        <indexMin>0</indexMin>
+        <indexMax>7</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+            <point>1,-3000</point>
+            <point>33,-2600</point>
+            <point>66,-2200</point>
+            <point>100,-1800</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>1,-5100</point>
+            <point>57,-2800</point>
+            <point>71,-2500</point>
+            <point>85,-2300</point>
+            <point>100,-2100</point>
+        </volume>
+        <!--volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_SYSTEM_VOLUME_CURVE"/-->
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_SYSTEM_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>ring</name>
+        <indexMin>0</indexMin>
+        <indexMax>7</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_DEVICE_CATEGORY_SPEAKER_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>music</name>
+        <indexMin>0</indexMin>
+        <indexMax>25</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_DEVICE_CATEGORY_SPEAKER_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID"  ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>alarm</name>
+        <indexMin>1</indexMin>
+        <indexMax>7</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_NON_MUTABLE_HEADSET_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_NON_MUTABLE_SPEAKER_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_NON_MUTABLE_EARPIECE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_NON_MUTABLE_EXT_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_NON_MUTABLE_HEARING_AID_VOLUME_CURVE"/>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>notification</name>
+        <indexMin>0</indexMin>
+        <indexMax>7</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_DEVICE_CATEGORY_SPEAKER_SYSTEM_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE"/>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>bluetooth_sco</name>
+        <indexMin>0</indexMin>
+        <indexMax>15</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>0,-2400</point>
+            <point>33,-1600</point>
+            <point>66,-800</point>
+            <point>100,0</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE">
+            <point>0,-4200</point>
+            <point>33,-2800</point>
+            <point>66,-1400</point>
+            <point>100,0</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>enforced_audible</name>
+        <indexMin>0</indexMin>
+        <indexMax>7</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+            <point>1,-3000</point>
+            <point>33,-2600</point>
+            <point>66,-2200</point>
+            <point>100,-1800</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>1,-3400</point>
+            <point>71,-2400</point>
+            <point>100,-2000</point>
+        </volume>
+        <!--volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_SYSTEM_VOLUME_CURVE"/-->
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_SYSTEM_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>dtmf</name>
+        <indexMin>0</indexMin>
+        <indexMax>15</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+            <point>1,-3000</point>
+            <point>33,-2600</point>
+            <point>66,-2200</point>
+            <point>100,-1800</point>
+        </volume>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+            <point>1,-4000</point>
+            <point>71,-2400</point>
+            <point>100,-1400</point>
+        </volume>
+        <!--volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_SYSTEM_VOLUME_CURVE"/-->
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_SYSTEM_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>tts</name>
+        <indexMin>0</indexMin>
+        <indexMax>15</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="SILENT_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="SILENT_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="SILENT_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="SILENT_VOLUME_CURVE"/>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>accessibility</name>
+        <indexMin>1</indexMin>
+        <indexMax>15</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_NON_MUTABLE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_NON_MUTABLE_SPEAKER_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_NON_MUTABLE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_NON_MUTABLE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_NON_MUTABLE_HEARING_AID_VOLUME_CURVE"/>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>rerouting</name>
+        <indexMin>0</indexMin>
+        <indexMax>1</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="FULL_SCALE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="FULL_SCALE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="FULL_SCALE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="FULL_SCALE_VOLUME_CURVE"/>
+    </volumeGroup>
+
+    <volumeGroup>
+        <name>patch</name>
+        <indexMin>0</indexMin>
+        <indexMax>1</indexMax>
+        <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="FULL_SCALE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="FULL_SCALE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="FULL_SCALE_VOLUME_CURVE"/>
+        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="FULL_SCALE_VOLUME_CURVE"/>
+    </volumeGroup>
+</volumeGroups>
+
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 3e13e50..04170ac 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -25,9 +25,11 @@
 #endif
 
 #include "Engine.h"
+#include <android-base/macros.h>
 #include <AudioPolicyManagerObserver.h>
 #include <AudioPort.h>
 #include <IOProfile.h>
+#include <AudioIODescriptorInterface.h>
 #include <policy.h>
 #include <utils/String8.h>
 #include <utils/Log.h>
@@ -37,60 +39,33 @@
 namespace audio_policy
 {
 
+struct legacy_strategy_map { const char *name; legacy_strategy id; };
+static const std::vector<legacy_strategy_map> gLegacyStrategy = {
+    { "STRATEGY_NONE", STRATEGY_NONE },
+    { "STRATEGY_MEDIA", STRATEGY_MEDIA },
+    { "STRATEGY_PHONE", STRATEGY_PHONE },
+    { "STRATEGY_SONIFICATION", STRATEGY_SONIFICATION },
+    { "STRATEGY_SONIFICATION_RESPECTFUL", STRATEGY_SONIFICATION_RESPECTFUL },
+    { "STRATEGY_DTMF", STRATEGY_DTMF },
+    { "STRATEGY_ENFORCED_AUDIBLE", STRATEGY_ENFORCED_AUDIBLE },
+    { "STRATEGY_TRANSMITTED_THROUGH_SPEAKER", STRATEGY_TRANSMITTED_THROUGH_SPEAKER },
+    { "STRATEGY_ACCESSIBILITY", STRATEGY_ACCESSIBILITY },
+    { "STRATEGY_REROUTING", STRATEGY_REROUTING },
+    { "STRATEGY_PATCH", STRATEGY_REROUTING }, // boiler to manage stream patch volume
+};
+
 Engine::Engine()
-    : mManagerInterface(this),
-      mPhoneState(AUDIO_MODE_NORMAL),
-      mApmObserver(NULL)
 {
-    for (int i = 0; i < AUDIO_POLICY_FORCE_USE_CNT; i++) {
-        mForceUse[i] = AUDIO_POLICY_FORCE_NONE;
+    auto result = EngineBase::loadAudioPolicyEngineConfig();
+    ALOGE_IF(result.nbSkippedElement != 0,
+             "Policy Engine configuration is partially invalid, skipped %zu elements",
+             result.nbSkippedElement);
+
+    for (const auto &strategy : gLegacyStrategy) {
+        mLegacyStrategyMap[getProductStrategyByName(strategy.name)] = strategy.id;
     }
 }
 
-Engine::~Engine()
-{
-}
-
-void Engine::setObserver(AudioPolicyManagerObserver *observer)
-{
-    ALOG_ASSERT(observer != NULL, "Invalid Audio Policy Manager observer");
-    mApmObserver = observer;
-}
-
-status_t Engine::initCheck()
-{
-    return (mApmObserver != NULL) ?  NO_ERROR : NO_INIT;
-}
-
-status_t Engine::setPhoneState(audio_mode_t state)
-{
-    ALOGV("setPhoneState() state %d", state);
-
-    if (state < 0 || state >= AUDIO_MODE_CNT) {
-        ALOGW("setPhoneState() invalid state %d", state);
-        return BAD_VALUE;
-    }
-
-    if (state == mPhoneState ) {
-        ALOGW("setPhoneState() setting same state %d", state);
-        return BAD_VALUE;
-    }
-
-    // store previous phone state for management of sonification strategy below
-    int oldState = mPhoneState;
-    mPhoneState = state;
-
-    if (!is_state_in_call(oldState) && is_state_in_call(state)) {
-        ALOGV("  Entering call in setPhoneState()");
-        mApmObserver->getVolumeCurves().switchVolumeCurve(AUDIO_STREAM_VOICE_CALL,
-                                                          AUDIO_STREAM_DTMF);
-    } else if (is_state_in_call(oldState) && !is_state_in_call(state)) {
-        ALOGV("  Exiting call in setPhoneState()");
-        mApmObserver->getVolumeCurves().restoreOriginVolumeCurve(AUDIO_STREAM_DTMF);
-    }
-    return NO_ERROR;
-}
-
 status_t Engine::setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config)
 {
     switch(usage) {
@@ -100,7 +75,6 @@
             ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config);
             return BAD_VALUE;
         }
-        mForceUse[usage] = config;
         break;
     case AUDIO_POLICY_FORCE_FOR_MEDIA:
         if (config != AUDIO_POLICY_FORCE_HEADPHONES && config != AUDIO_POLICY_FORCE_BT_A2DP &&
@@ -111,7 +85,6 @@
             ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config);
             return BAD_VALUE;
         }
-        mForceUse[usage] = config;
         break;
     case AUDIO_POLICY_FORCE_FOR_RECORD:
         if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
@@ -119,7 +92,6 @@
             ALOGW("setForceUse() invalid config %d for FOR_RECORD", config);
             return BAD_VALUE;
         }
-        mForceUse[usage] = config;
         break;
     case AUDIO_POLICY_FORCE_FOR_DOCK:
         if (config != AUDIO_POLICY_FORCE_NONE && config != AUDIO_POLICY_FORCE_BT_CAR_DOCK &&
@@ -129,21 +101,18 @@
             config != AUDIO_POLICY_FORCE_DIGITAL_DOCK) {
             ALOGW("setForceUse() invalid config %d for FOR_DOCK", config);
         }
-        mForceUse[usage] = config;
         break;
     case AUDIO_POLICY_FORCE_FOR_SYSTEM:
         if (config != AUDIO_POLICY_FORCE_NONE &&
             config != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
             ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config);
         }
-        mForceUse[usage] = config;
         break;
     case AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO:
         if (config != AUDIO_POLICY_FORCE_NONE &&
             config != AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED) {
             ALOGW("setForceUse() invalid config %d for HDMI_SYSTEM_AUDIO", config);
         }
-        mForceUse[usage] = config;
         break;
     case AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND:
         if (config != AUDIO_POLICY_FORCE_NONE &&
@@ -153,108 +122,25 @@
             ALOGW("setForceUse() invalid config %d for ENCODED_SURROUND", config);
             return BAD_VALUE;
         }
-        mForceUse[usage] = config;
         break;
     case AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING:
         if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_NONE) {
             ALOGW("setForceUse() invalid config %d for FOR_VIBRATE_RINGING", config);
             return BAD_VALUE;
         }
-        mForceUse[usage] = config;
         break;
     default:
         ALOGW("setForceUse() invalid usage %d", usage);
         break; // TODO return BAD_VALUE?
     }
-    return NO_ERROR;
+    return EngineBase::setForceUse(usage, config);
 }
 
-routing_strategy Engine::getStrategyForStream(audio_stream_type_t stream)
-{
-    // stream to strategy mapping
-    switch (stream) {
-    case AUDIO_STREAM_VOICE_CALL:
-    case AUDIO_STREAM_BLUETOOTH_SCO:
-        return STRATEGY_PHONE;
-    case AUDIO_STREAM_RING:
-    case AUDIO_STREAM_ALARM:
-        return STRATEGY_SONIFICATION;
-    case AUDIO_STREAM_NOTIFICATION:
-        return STRATEGY_SONIFICATION_RESPECTFUL;
-    case AUDIO_STREAM_DTMF:
-        return STRATEGY_DTMF;
-    default:
-        ALOGE("unknown stream type %d", stream);
-    case AUDIO_STREAM_SYSTEM:
-        // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
-        // while key clicks are played produces a poor result
-    case AUDIO_STREAM_MUSIC:
-        return STRATEGY_MEDIA;
-    case AUDIO_STREAM_ENFORCED_AUDIBLE:
-        return STRATEGY_ENFORCED_AUDIBLE;
-    case AUDIO_STREAM_TTS:
-        return STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
-    case AUDIO_STREAM_ACCESSIBILITY:
-        return STRATEGY_ACCESSIBILITY;
-    case AUDIO_STREAM_REROUTING:
-        return STRATEGY_REROUTING;
-    }
-}
-
-routing_strategy Engine::getStrategyForUsage(audio_usage_t usage)
-{
-    // usage to strategy mapping
-    switch (usage) {
-    case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
-        return STRATEGY_ACCESSIBILITY;
-
-    case AUDIO_USAGE_MEDIA:
-    case AUDIO_USAGE_GAME:
-    case AUDIO_USAGE_ASSISTANT:
-    case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
-    case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
-        return STRATEGY_MEDIA;
-
-    case AUDIO_USAGE_VOICE_COMMUNICATION:
-        return STRATEGY_PHONE;
-
-    case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
-        return STRATEGY_DTMF;
-
-    case AUDIO_USAGE_ALARM:
-    case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
-        return STRATEGY_SONIFICATION;
-
-    case AUDIO_USAGE_NOTIFICATION:
-    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
-    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
-    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
-    case AUDIO_USAGE_NOTIFICATION_EVENT:
-        return STRATEGY_SONIFICATION_RESPECTFUL;
-
-    case AUDIO_USAGE_UNKNOWN:
-    default:
-        return STRATEGY_MEDIA;
-    }
-}
-
-audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const
-{
-    DeviceVector availableOutputDevices = mApmObserver->getAvailableOutputDevices();
-    DeviceVector availableInputDevices = mApmObserver->getAvailableInputDevices();
-
-    const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
-
-    return getDeviceForStrategyInt(strategy, availableOutputDevices,
-                                   availableInputDevices, outputs, (uint32_t)AUDIO_DEVICE_NONE);
-}
-
-
-audio_devices_t Engine::getDeviceForStrategyInt(routing_strategy strategy,
-        DeviceVector availableOutputDevices,
-        DeviceVector availableInputDevices,
-        const SwAudioOutputCollection &outputs,
-        uint32_t outputDeviceTypesToIgnore) const
+audio_devices_t Engine::getDeviceForStrategyInt(legacy_strategy strategy,
+                                                DeviceVector availableOutputDevices,
+                                                DeviceVector availableInputDevices,
+                                                const SwAudioOutputCollection &outputs,
+                                                uint32_t outputDeviceTypesToIgnore) const
 {
     uint32_t device = AUDIO_DEVICE_NONE;
     uint32_t availableOutputDevicesType =
@@ -267,16 +153,17 @@
         break;
 
     case STRATEGY_SONIFICATION_RESPECTFUL:
-        if (isInCall() || outputs.isStreamActiveLocally(AUDIO_STREAM_VOICE_CALL)) {
+        if (isInCall() || outputs.isActiveLocally(toVolumeSource(AUDIO_STREAM_VOICE_CALL))) {
             device = getDeviceForStrategyInt(
                     STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs,
                     outputDeviceTypesToIgnore);
         } else {
             bool media_active_locally =
-                    outputs.isStreamActiveLocally(
-                            AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)
-                    || outputs.isStreamActiveLocally(
-                            AUDIO_STREAM_ACCESSIBILITY, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY);
+                    outputs.isActiveLocally(toVolumeSource(AUDIO_STREAM_MUSIC),
+                                            SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)
+                    || outputs.isActiveLocally(
+                        toVolumeSource(AUDIO_STREAM_ACCESSIBILITY),
+                        SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY);
             // routing is same as media without the "remote" device
             device = getDeviceForStrategyInt(STRATEGY_MEDIA,
                     availableOutputDevices,
@@ -302,7 +189,7 @@
             break;
         }
         // when in call, DTMF and PHONE strategies follow the same rules
-        // FALL THROUGH
+        FALLTHROUGH_INTENDED;
 
     case STRATEGY_PHONE:
         // Force use of only devices on primary output if:
@@ -313,14 +200,14 @@
             audio_devices_t txDevice = getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
             sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
             audio_devices_t availPrimaryInputDevices =
-                 availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle());
+                 availableInputDevices.getDeviceTypesFromHwModule(primaryOutput->getModuleHandle());
 
             // TODO: getPrimaryOutput return only devices from first module in
             // audio_policy_configuration.xml, hearing aid is not there, but it's
             // a primary device
             // FIXME: this is not the right way of solving this problem
             audio_devices_t availPrimaryOutputDevices =
-                (primaryOutput->supportedDevices() | AUDIO_DEVICE_OUT_HEARING_AID) &
+                (primaryOutput->supportedDevices().types() | AUDIO_DEVICE_OUT_HEARING_AID) &
                 availableOutputDevices.types();
 
             if (((availableInputDevices.types() &
@@ -332,7 +219,7 @@
         }
         // for phone strategy, we first consider the forced use and then the available devices by
         // order of priority
-        switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
+        switch (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION)) {
         case AUDIO_POLICY_FORCE_BT_SCO:
             if (!isInCall() || strategy != STRATEGY_DTMF) {
                 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
@@ -343,14 +230,14 @@
             device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
             if (device) break;
             // if SCO device is requested but no SCO device is available, fall back to default case
-            // FALL THROUGH
+            FALLTHROUGH_INTENDED;
 
         default:    // FORCE_NONE
             device = availableOutputDevicesType & AUDIO_DEVICE_OUT_HEARING_AID;
             if (device) break;
             // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
             if (!isInCall() &&
-                    (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
+                    (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
                      outputs.isA2dpSupported()) {
                 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
                 if (device) break;
@@ -384,7 +271,7 @@
             // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
             // A2DP speaker when forcing to speaker output
             if (!isInCall() &&
-                    (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
+                    (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
                      outputs.isA2dpSupported()) {
                 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
                 if (device) break;
@@ -408,15 +295,15 @@
 
     case STRATEGY_SONIFICATION:
 
-        // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
-        // handleIncallSonification().
-        if (isInCall() || outputs.isStreamActiveLocally(AUDIO_STREAM_VOICE_CALL)) {
+        // If incall, just select the STRATEGY_PHONE device
+        if (isInCall() ||
+                outputs.isActiveLocally(toVolumeSource(AUDIO_STREAM_VOICE_CALL))) {
             device = getDeviceForStrategyInt(
                     STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
                     outputDeviceTypesToIgnore);
             break;
         }
-        // FALL THROUGH
+        FALLTHROUGH_INTENDED;
 
     case STRATEGY_ENFORCED_AUDIBLE:
         // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
@@ -425,7 +312,7 @@
         //   - in countries where not enforced in which case it follows STRATEGY_MEDIA
 
         if ((strategy == STRATEGY_SONIFICATION) ||
-                (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
+                (getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
             device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
         }
 
@@ -441,9 +328,9 @@
                 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
             }
             // Use ONLY Bluetooth SCO output when ringing in vibration mode
-            if (!((mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
+            if (!((getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
                     && (strategy == STRATEGY_ENFORCED_AUDIBLE))) {
-                if (mForceUse[AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING]
+                if (getForceUse(AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING)
                         == AUDIO_POLICY_FORCE_BT_SCO) {
                     if (device2 != AUDIO_DEVICE_NONE) {
                         device = device2;
@@ -452,7 +339,7 @@
                 }
             }
             // Use both Bluetooth SCO and phone default output when ringing in normal mode
-            if (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) {
+            if (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION) == AUDIO_POLICY_FORCE_BT_SCO) {
                 if ((strategy == STRATEGY_SONIFICATION) &&
                         (device & AUDIO_DEVICE_OUT_SPEAKER) &&
                         (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
@@ -466,7 +353,7 @@
             }
         }
         // The second device used for sonification is the same as the device used by media strategy
-        // FALL THROUGH
+        FALLTHROUGH_INTENDED;
 
     case STRATEGY_ACCESSIBILITY:
         if (strategy == STRATEGY_ACCESSIBILITY) {
@@ -474,7 +361,7 @@
             // compressed format as they would likely not be mixed and dropped.
             for (size_t i = 0; i < outputs.size(); i++) {
                 sp<AudioOutputDescriptor> desc = outputs.valueAt(i);
-                audio_devices_t devices = desc->device() &
+                audio_devices_t devices = desc->devices().types() &
                     (AUDIO_DEVICE_OUT_HDMI | AUDIO_DEVICE_OUT_SPDIF | AUDIO_DEVICE_OUT_HDMI_ARC);
                 if (desc->isActive() && !audio_is_linear_pcm(desc->mFormat) &&
                         devices != AUDIO_DEVICE_NONE) {
@@ -482,9 +369,9 @@
                 }
             }
             availableOutputDevices =
-                    availableOutputDevices.getDevicesFromType(availableOutputDevicesType);
-            if (outputs.isStreamActive(AUDIO_STREAM_RING) ||
-                    outputs.isStreamActive(AUDIO_STREAM_ALARM)) {
+                    availableOutputDevices.getDevicesFromTypeMask(availableOutputDevicesType);
+            if (outputs.isActive(toVolumeSource(AUDIO_STREAM_RING)) ||
+                    outputs.isActive(toVolumeSource(AUDIO_STREAM_ALARM))) {
                 return getDeviceForStrategyInt(
                     STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs,
                     outputDeviceTypesToIgnore);
@@ -496,7 +383,7 @@
             }
         }
         // For other cases, STRATEGY_ACCESSIBILITY behaves like STRATEGY_MEDIA
-        // FALL THROUGH
+        FALLTHROUGH_INTENDED;
 
     // FIXME: STRATEGY_REROUTING follow STRATEGY_MEDIA for now
     case STRATEGY_REROUTING:
@@ -505,7 +392,7 @@
         if (strategy != STRATEGY_SONIFICATION) {
             // no sonification on remote submix (e.g. WFD)
             if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
-                                                 String8("0")) != 0) {
+                                                 String8("0"), AUDIO_FORMAT_DEFAULT) != 0) {
                 device2 = availableOutputDevices.types() & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
             }
         }
@@ -515,11 +402,13 @@
                     outputDeviceTypesToIgnore);
             break;
         }
-        if (device2 == AUDIO_DEVICE_NONE) {
+        // FIXME: Find a better solution to prevent routing to BT hearing aid(b/122931261).
+        if ((device2 == AUDIO_DEVICE_NONE) &&
+                (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP)) {
             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HEARING_AID;
         }
         if ((device2 == AUDIO_DEVICE_NONE) &&
-                (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
+                (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
                  outputs.isA2dpSupported()) {
             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
             if (device2 == AUDIO_DEVICE_NONE) {
@@ -530,7 +419,7 @@
             }
         }
         if ((device2 == AUDIO_DEVICE_NONE) &&
-            (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] == AUDIO_POLICY_FORCE_SPEAKER)) {
+            (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) == AUDIO_POLICY_FORCE_SPEAKER)) {
             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
         }
         if (device2 == AUDIO_DEVICE_NONE) {
@@ -559,7 +448,7 @@
             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
         }
         if ((device2 == AUDIO_DEVICE_NONE) &&
-                (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
+                (getForceUse(AUDIO_POLICY_FORCE_FOR_DOCK) == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
         }
         if (device2 == AUDIO_DEVICE_NONE) {
@@ -580,7 +469,7 @@
 
         // If hdmi system audio mode is on, remove speaker out of output list.
         if ((strategy == STRATEGY_MEDIA) &&
-            (mForceUse[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] ==
+            (getForceUse(AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO) ==
                 AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {
             device &= ~AUDIO_DEVICE_OUT_SPEAKER;
         }
@@ -602,7 +491,7 @@
 
     if (device == AUDIO_DEVICE_NONE) {
         ALOGV("getDeviceForStrategy() no device found for strategy %d", strategy);
-        device = mApmObserver->getDefaultOutputDevice()->type();
+        device = getApmObserver()->getDefaultOutputDevice()->type();
         ALOGE_IF(device == AUDIO_DEVICE_NONE,
                  "getDeviceForStrategy() no default device defined");
     }
@@ -613,11 +502,13 @@
 
 audio_devices_t Engine::getDeviceForInputSource(audio_source_t inputSource) const
 {
-    const DeviceVector &availableOutputDevices = mApmObserver->getAvailableOutputDevices();
-    const DeviceVector &availableInputDevices = mApmObserver->getAvailableInputDevices();
-    const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
+    const DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
+    const DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices();
+    const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
     audio_devices_t availableDeviceTypes = availableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
-
+    sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
+    audio_devices_t availablePrimaryDeviceTypes = availableInputDevices.getDeviceTypesFromHwModule(
+        primaryOutput->getModuleHandle()) & ~AUDIO_DEVICE_BIT_IN;
     uint32_t device = AUDIO_DEVICE_NONE;
 
     // when a call is active, force device selection to match source VOICE_COMMUNICATION
@@ -630,6 +521,7 @@
         case AUDIO_SOURCE_UNPROCESSED:
         case AUDIO_SOURCE_HOTWORD:
         case AUDIO_SOURCE_CAMCORDER:
+        case AUDIO_SOURCE_VOICE_PERFORMANCE:
             inputSource = AUDIO_SOURCE_VOICE_COMMUNICATION;
             break;
         default:
@@ -638,18 +530,11 @@
     }
 
     switch (inputSource) {
-    case AUDIO_SOURCE_VOICE_UPLINK:
-      if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
-          device = AUDIO_DEVICE_IN_VOICE_CALL;
-          break;
-      }
-      break;
-
     case AUDIO_SOURCE_DEFAULT:
     case AUDIO_SOURCE_MIC:
     if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
         device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
-    } else if ((mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO) &&
+    } else if ((getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO) &&
         (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
         device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
     } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
@@ -668,20 +553,17 @@
         // to voice call path.
         if ((getPhoneState() == AUDIO_MODE_IN_CALL) &&
                 (availableOutputDevices.types() & AUDIO_DEVICE_OUT_TELEPHONY_TX) == 0) {
-            sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
-            availableDeviceTypes =
-                    availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle())
-                    & ~AUDIO_DEVICE_BIT_IN;
+            availableDeviceTypes = availablePrimaryDeviceTypes;
         }
 
-        switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
+        switch (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION)) {
         case AUDIO_POLICY_FORCE_BT_SCO:
             // if SCO device is requested but no SCO device is available, fall back to default case
             if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
                 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
                 break;
             }
-            // FALL THROUGH
+            FALLTHROUGH_INTENDED;
 
         default:    // FORCE_NONE
             if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
@@ -708,7 +590,10 @@
     case AUDIO_SOURCE_VOICE_RECOGNITION:
     case AUDIO_SOURCE_UNPROCESSED:
     case AUDIO_SOURCE_HOTWORD:
-        if (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO &&
+        if (inputSource == AUDIO_SOURCE_HOTWORD) {
+            availableDeviceTypes = availablePrimaryDeviceTypes;
+        }
+        if (getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO &&
                 availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
             device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
         } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
@@ -726,24 +611,44 @@
             device = AUDIO_DEVICE_IN_BACK_MIC;
         } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
             device = AUDIO_DEVICE_IN_BUILTIN_MIC;
+        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
+            // This is specifically for a device without built-in mic
+            device = AUDIO_DEVICE_IN_USB_DEVICE;
         }
         break;
     case AUDIO_SOURCE_VOICE_DOWNLINK:
     case AUDIO_SOURCE_VOICE_CALL:
+    case AUDIO_SOURCE_VOICE_UPLINK:
         if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
             device = AUDIO_DEVICE_IN_VOICE_CALL;
         }
         break;
+    case AUDIO_SOURCE_VOICE_PERFORMANCE:
+        if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+            device = AUDIO_DEVICE_IN_WIRED_HEADSET;
+        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
+            device = AUDIO_DEVICE_IN_USB_HEADSET;
+        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
+            device = AUDIO_DEVICE_IN_USB_DEVICE;
+        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+            device = AUDIO_DEVICE_IN_BUILTIN_MIC;
+        }
+        break;
     case AUDIO_SOURCE_REMOTE_SUBMIX:
         if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
             device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
         }
         break;
-     case AUDIO_SOURCE_FM_TUNER:
+    case AUDIO_SOURCE_FM_TUNER:
         if (availableDeviceTypes & AUDIO_DEVICE_IN_FM_TUNER) {
             device = AUDIO_DEVICE_IN_FM_TUNER;
         }
         break;
+    case AUDIO_SOURCE_ECHO_REFERENCE:
+        if (availableDeviceTypes & AUDIO_DEVICE_IN_ECHO_REFERENCE) {
+            device = AUDIO_DEVICE_IN_ECHO_REFERENCE;
+        }
+        break;
     default:
         ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
         break;
@@ -760,10 +665,107 @@
     return device;
 }
 
+void Engine::updateDeviceSelectionCache()
+{
+    for (const auto &iter : getProductStrategies()) {
+        const auto &strategy = iter.second;
+        auto devices = getDevicesForProductStrategy(strategy->getId());
+        mDevicesForStrategies[strategy->getId()] = devices;
+        strategy->setDeviceTypes(devices.types());
+        strategy->setDeviceAddress(devices.getFirstValidAddress().c_str());
+    }
+}
+
+DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t strategy) const
+{
+    DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
+    DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices();
+    const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
+
+    auto legacyStrategy = mLegacyStrategyMap.find(strategy) != end(mLegacyStrategyMap) ?
+                mLegacyStrategyMap.at(strategy) : STRATEGY_NONE;
+    audio_devices_t devices = getDeviceForStrategyInt(legacyStrategy,
+                                                      availableOutputDevices,
+                                                      availableInputDevices, outputs,
+                                                      (uint32_t)AUDIO_DEVICE_NONE);
+    return availableOutputDevices.getDevicesFromTypeMask(devices);
+}
+
+DeviceVector Engine::getOutputDevicesForAttributes(const audio_attributes_t &attributes,
+                                                   const sp<DeviceDescriptor> &preferredDevice,
+                                                   bool fromCache) const
+{
+    // First check for explict routing device
+    if (preferredDevice != nullptr) {
+        ALOGV("%s explicit Routing on device %s", __func__, preferredDevice->toString().c_str());
+        return DeviceVector(preferredDevice);
+    }
+    product_strategy_t strategy = getProductStrategyForAttributes(attributes);
+    const DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
+    const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
+    //
+    // @TODO: what is the priority of explicit routing? Shall it be considered first as it used to
+    // be by APM?
+    //
+    // Honor explicit routing requests only if all active clients have a preferred route in which
+    // case the last active client route is used
+    sp<DeviceDescriptor> device = findPreferredDevice(outputs, strategy, availableOutputDevices);
+    if (device != nullptr) {
+        return DeviceVector(device);
+    }
+
+    return fromCache? mDevicesForStrategies.at(strategy) : getDevicesForProductStrategy(strategy);
+}
+
+DeviceVector Engine::getOutputDevicesForStream(audio_stream_type_t stream, bool fromCache) const
+{
+    auto attributes = getAttributesForStreamType(stream);
+    return getOutputDevicesForAttributes(attributes, nullptr, fromCache);
+}
+
+sp<DeviceDescriptor> Engine::getInputDeviceForAttributes(const audio_attributes_t &attr,
+                                                         sp<AudioPolicyMix> *mix) const
+{
+    const auto &policyMixes = getApmObserver()->getAudioPolicyMixCollection();
+    const auto availableInputDevices = getApmObserver()->getAvailableInputDevices();
+    const auto &inputs = getApmObserver()->getInputs();
+    std::string address;
+
+    //
+    // Explicit Routing ??? what is the priority of explicit routing? Shall it be considered
+    // first as it used to be by APM?
+    //
+    // Honor explicit routing requests only if all active clients have a preferred route in which
+    // case the last active client route is used
+    sp<DeviceDescriptor> device =
+            findPreferredDevice(inputs, attr.source, availableInputDevices);
+    if (device != nullptr) {
+        return device;
+    }
+
+    device = policyMixes.getDeviceAndMixForInputSource(attr.source, availableInputDevices, mix);
+    if (device != nullptr) {
+        return device;
+    }
+    audio_devices_t deviceType = getDeviceForInputSource(attr.source);
+
+    if (audio_is_remote_submix_device(deviceType)) {
+        address = "0";
+        std::size_t pos;
+        std::string tags { attr.tags };
+        if ((pos = tags.find("addr=")) != std::string::npos) {
+            address = tags.substr(pos + std::strlen("addr="));
+        }
+    }
+    return availableInputDevices.getDevice(deviceType,
+                                           String8(address.c_str()),
+                                           AUDIO_FORMAT_DEFAULT);
+}
+
 template <>
 AudioPolicyManagerInterface *Engine::queryInterface()
 {
-    return &mManagerInterface;
+    return this;
 }
 
 } // namespace audio_policy
diff --git a/services/audiopolicy/enginedefault/src/Engine.h b/services/audiopolicy/enginedefault/src/Engine.h
index 06186c1..d5dfacc 100644
--- a/services/audiopolicy/enginedefault/src/Engine.h
+++ b/services/audiopolicy/enginedefault/src/Engine.h
@@ -16,7 +16,7 @@
 
 #pragma once
 
-
+#include "EngineBase.h"
 #include "AudioPolicyManagerInterface.h"
 #include <AudioGain.h>
 #include <policy.h>
@@ -29,114 +29,67 @@
 namespace audio_policy
 {
 
-class Engine
+enum legacy_strategy {
+    STRATEGY_NONE = -1,
+    STRATEGY_MEDIA,
+    STRATEGY_PHONE,
+    STRATEGY_SONIFICATION,
+    STRATEGY_SONIFICATION_RESPECTFUL,
+    STRATEGY_DTMF,
+    STRATEGY_ENFORCED_AUDIBLE,
+    STRATEGY_TRANSMITTED_THROUGH_SPEAKER,
+    STRATEGY_ACCESSIBILITY,
+    STRATEGY_REROUTING,
+};
+
+class Engine : public EngineBase
 {
 public:
     Engine();
-    virtual ~Engine();
+    virtual ~Engine() = default;
 
     template <class RequestedInterface>
     RequestedInterface *queryInterface();
 
 private:
-    /// Interface members
-    class ManagerInterfaceImpl : public AudioPolicyManagerInterface
-    {
-    public:
-        explicit ManagerInterfaceImpl(Engine *policyEngine)
-            : mPolicyEngine(policyEngine) {}
+    ///
+    /// from EngineBase, so from AudioPolicyManagerInterface
+    ///
+    status_t setForceUse(audio_policy_force_use_t usage,
+                         audio_policy_forced_cfg_t config) override;
 
-        virtual void setObserver(AudioPolicyManagerObserver *observer)
-        {
-            mPolicyEngine->setObserver(observer);
-        }
-        virtual status_t initCheck()
-        {
-            return mPolicyEngine->initCheck();
-        }
-        virtual audio_devices_t getDeviceForInputSource(audio_source_t inputSource) const
-        {
-            return mPolicyEngine->getDeviceForInputSource(inputSource);
-        }
-        virtual audio_devices_t getDeviceForStrategy(routing_strategy strategy) const
-        {
-            return mPolicyEngine->getDeviceForStrategy(strategy);
-        }
-        virtual routing_strategy getStrategyForStream(audio_stream_type_t stream)
-        {
-            return mPolicyEngine->getStrategyForStream(stream);
-        }
-        virtual routing_strategy getStrategyForUsage(audio_usage_t usage)
-        {
-            return mPolicyEngine->getStrategyForUsage(usage);
-        }
-        virtual status_t setPhoneState(audio_mode_t mode)
-        {
-            return mPolicyEngine->setPhoneState(mode);
-        }
-        virtual audio_mode_t getPhoneState() const
-        {
-            return mPolicyEngine->getPhoneState();
-        }
-        virtual status_t setForceUse(audio_policy_force_use_t usage,
-                                     audio_policy_forced_cfg_t config)
-        {
-            return mPolicyEngine->setForceUse(usage, config);
-        }
-        virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const
-        {
-            return mPolicyEngine->getForceUse(usage);
-        }
-        virtual status_t setDeviceConnectionState(const sp<DeviceDescriptor> /*devDesc*/,
-                                                  audio_policy_dev_state_t /*state*/)
-        {
-            return NO_ERROR;
-        }
-    private:
-        Engine *mPolicyEngine;
-    } mManagerInterface;
+    DeviceVector getOutputDevicesForAttributes(const audio_attributes_t &attr,
+                                               const sp<DeviceDescriptor> &preferedDevice = nullptr,
+                                               bool fromCache = false) const override;
+
+    DeviceVector getOutputDevicesForStream(audio_stream_type_t stream,
+                                           bool fromCache = false) const override;
+
+    sp<DeviceDescriptor> getInputDeviceForAttributes(
+            const audio_attributes_t &attr, sp<AudioPolicyMix> *mix = nullptr) const override;
+
+    void updateDeviceSelectionCache() override;
 
 private:
     /* Copy facilities are put private to disable copy. */
     Engine(const Engine &object);
     Engine &operator=(const Engine &object);
 
-    void setObserver(AudioPolicyManagerObserver *observer);
-
-    status_t initCheck();
-
-    inline bool isInCall() const
-    {
-        return is_state_in_call(mPhoneState);
-    }
-
-    status_t setPhoneState(audio_mode_t mode);
-    audio_mode_t getPhoneState() const
-    {
-        return mPhoneState;
-    }
-    status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
-    audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const
-    {
-        return mForceUse[usage];
-    }
     status_t setDefaultDevice(audio_devices_t device);
 
-    routing_strategy getStrategyForStream(audio_stream_type_t stream);
-    routing_strategy getStrategyForUsage(audio_usage_t usage);
-    audio_devices_t getDeviceForStrategy(routing_strategy strategy) const;
-    audio_devices_t getDeviceForStrategyInt(routing_strategy strategy,
-            DeviceVector availableOutputDevices,
-            DeviceVector availableInputDevices,
-            const SwAudioOutputCollection &outputs,
-            uint32_t outputDeviceTypesToIgnore) const;
+    audio_devices_t getDeviceForStrategyInt(legacy_strategy strategy,
+                                            DeviceVector availableOutputDevices,
+                                            DeviceVector availableInputDevices,
+                                            const SwAudioOutputCollection &outputs,
+                                            uint32_t outputDeviceTypesToIgnore) const;
+
+    DeviceVector getDevicesForProductStrategy(product_strategy_t strategy) const;
+
     audio_devices_t getDeviceForInputSource(audio_source_t inputSource) const;
-    audio_mode_t mPhoneState;  /**< current phone state. */
 
-    /** current forced use configuration. */
-    audio_policy_forced_cfg_t mForceUse[AUDIO_POLICY_FORCE_USE_CNT];
+    DeviceStrategyMap mDevicesForStrategies;
 
-    AudioPolicyManagerObserver *mApmObserver;
+    std::map<product_strategy_t, legacy_strategy> mLegacyStrategyMap;
 };
 } // namespace audio_policy
 } // namespace android
diff --git a/services/audiopolicy/manager/Android.mk b/services/audiopolicy/manager/Android.mk
new file mode 100644
index 0000000..d6ca2f2
--- /dev/null
+++ b/services/audiopolicy/manager/Android.mk
@@ -0,0 +1,32 @@
+LOCAL_PATH:= $(call my-dir)
+
+ifneq ($(USE_CUSTOM_AUDIO_POLICY), 1)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+    AudioPolicyFactory.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+    libaudiopolicymanagerdefault
+
+LOCAL_STATIC_LIBRARIES := \
+    libaudiopolicycomponents
+
+LOCAL_C_INCLUDES += \
+    $(call include-path-for, audio-utils)
+
+LOCAL_HEADER_LIBRARIES := \
+    libaudiopolicycommon \
+    libaudiopolicyengine_interface_headers \
+    libaudiopolicymanager_interface_headers
+
+LOCAL_CFLAGS := -Wall -Werror
+
+LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
+
+LOCAL_MODULE:= libaudiopolicymanager
+
+include $(BUILD_SHARED_LIBRARY)
+
+endif #ifneq ($(USE_CUSTOM_AUDIO_POLICY), 1)
diff --git a/services/audiopolicy/manager/AudioPolicyFactory.cpp b/services/audiopolicy/manager/AudioPolicyFactory.cpp
index 3efa1b0..7aff6a9 100644
--- a/services/audiopolicy/manager/AudioPolicyFactory.cpp
+++ b/services/audiopolicy/manager/AudioPolicyFactory.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "managerdefault/AudioPolicyManager.h"
+#include <AudioPolicyManager.h>
 
 namespace android {
 
diff --git a/services/audiopolicy/managerdefault/Android.mk b/services/audiopolicy/managerdefault/Android.mk
new file mode 100644
index 0000000..684fc9f
--- /dev/null
+++ b/services/audiopolicy/managerdefault/Android.mk
@@ -0,0 +1,56 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= AudioPolicyManager.cpp
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    libutils \
+    liblog \
+    libaudiopolicy \
+    libsoundtrigger
+
+ifeq ($(USE_CONFIGURABLE_AUDIO_POLICY), 1)
+
+ifneq ($(USE_XML_AUDIO_POLICY_CONF), 1)
+$(error Configurable policy does not support legacy conf file)
+endif #ifneq ($(USE_XML_AUDIO_POLICY_CONF), 1)
+
+LOCAL_SHARED_LIBRARIES += libaudiopolicyengineconfigurable
+
+else
+
+LOCAL_SHARED_LIBRARIES += libaudiopolicyenginedefault
+
+endif # ifeq ($(USE_CONFIGURABLE_AUDIO_POLICY), 1)
+
+LOCAL_C_INCLUDES += \
+    $(call include-path-for, audio-utils)
+
+LOCAL_HEADER_LIBRARIES := \
+    libaudiopolicycommon \
+    libaudiopolicyengine_interface_headers \
+    libaudiopolicymanager_interface_headers
+
+LOCAL_STATIC_LIBRARIES := \
+    libaudiopolicycomponents
+
+LOCAL_SHARED_LIBRARIES += libmedia_helper
+LOCAL_SHARED_LIBRARIES += libmediametrics
+
+LOCAL_SHARED_LIBRARIES += libbinder libhidlbase libxml2
+
+ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
+LOCAL_CFLAGS += -DUSE_XML_AUDIO_POLICY_CONF
+endif #ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
+
+LOCAL_CFLAGS += -Wall -Werror
+
+LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
+
+LOCAL_MODULE:= libaudiopolicymanagerdefault
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 2736fd4..1d4dacd 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -15,7 +15,12 @@
  */
 
 #define LOG_TAG "APM_AudioPolicyManager"
-//#define LOG_NDEBUG 0
+
+// Need to keep the log statements even in production builds
+// to enable VERBOSE logging dynamically.
+// You can enable VERBOSE logging as follows:
+// adb shell setprop log.tag.APM_AudioPolicyManager V
+#define LOG_NDEBUG 0
 
 //#define VERY_VERBOSE_LOGGING
 #ifdef VERY_VERBOSE_LOGGING
@@ -28,24 +33,25 @@
 #define AUDIO_POLICY_XML_CONFIG_FILE_NAME "audio_policy_configuration.xml"
 #define AUDIO_POLICY_A2DP_OFFLOAD_DISABLED_XML_CONFIG_FILE_NAME \
         "audio_policy_configuration_a2dp_offload_disabled.xml"
+#define AUDIO_POLICY_BLUETOOTH_LEGACY_HAL_XML_CONFIG_FILE_NAME \
+        "audio_policy_configuration_bluetooth_legacy_hal.xml"
 
+#include <algorithm>
 #include <inttypes.h>
 #include <math.h>
-
+#include <set>
+#include <unordered_set>
+#include <vector>
 #include <AudioPolicyManagerInterface.h>
 #include <AudioPolicyEngineInstance.h>
 #include <cutils/properties.h>
 #include <utils/Log.h>
 #include <media/AudioParameter.h>
-#include <media/AudioPolicyHelper.h>
+#include <private/android_filesystem_config.h>
 #include <soundtrigger/SoundTrigger.h>
 #include <system/audio.h>
 #include <audio_policy_conf.h>
 #include "AudioPolicyManager.h"
-#ifndef USE_XML_AUDIO_POLICY_CONF
-#include <ConfigParsingUtils.h>
-#include <StreamDescriptor.h>
-#endif
 #include <Serializer.h>
 #include "TypeConverter.h"
 #include <policy.h>
@@ -60,25 +66,15 @@
 // media / notification / system volume.
 constexpr float IN_CALL_EARPIECE_HEADROOM_DB = 3.f;
 
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-// Array of all surround formats.
-static const audio_format_t SURROUND_FORMATS[] = {
-    AUDIO_FORMAT_AC3,
-    AUDIO_FORMAT_E_AC3,
-    AUDIO_FORMAT_DTS,
-    AUDIO_FORMAT_DTS_HD,
-    AUDIO_FORMAT_AAC_LC,
-    AUDIO_FORMAT_DOLBY_TRUEHD,
-    AUDIO_FORMAT_E_AC3_JOC,
-};
-// Array of all AAC formats. When AAC is enabled by users, all AAC formats should be enabled.
-static const audio_format_t AAC_FORMATS[] = {
-    AUDIO_FORMAT_AAC_LC,
-    AUDIO_FORMAT_AAC_HE_V1,
-    AUDIO_FORMAT_AAC_HE_V2,
-    AUDIO_FORMAT_AAC_ELD,
-    AUDIO_FORMAT_AAC_XHE,
-};
+// Compressed formats for MSD module, ordered from most preferred to least preferred.
+static const std::vector<audio_format_t> compressedFormatsOrder = {{
+        AUDIO_FORMAT_MAT_2_1, AUDIO_FORMAT_MAT_2_0, AUDIO_FORMAT_E_AC3,
+        AUDIO_FORMAT_AC3, AUDIO_FORMAT_PCM_16_BIT }};
+// Channel masks for MSD module, 3D > 2D > 1D ordering (most preferred to least preferred).
+static const std::vector<audio_channel_mask_t> surroundChannelMasksOrder = {{
+        AUDIO_CHANNEL_OUT_3POINT1POINT2, AUDIO_CHANNEL_OUT_3POINT0POINT2,
+        AUDIO_CHANNEL_OUT_2POINT1POINT2, AUDIO_CHANNEL_OUT_2POINT0POINT2,
+        AUDIO_CHANNEL_OUT_5POINT1, AUDIO_CHANNEL_OUT_STEREO }};
 
 // ----------------------------------------------------------------------------
 // AudioPolicyInterface implementation
@@ -87,43 +83,49 @@
 status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,
                                                       audio_policy_dev_state_t state,
                                                       const char *device_address,
-                                                      const char *device_name)
+                                                      const char *device_name,
+                                                      audio_format_t encodedFormat)
 {
-    status_t status = setDeviceConnectionStateInt(device, state, device_address, device_name);
+    status_t status = setDeviceConnectionStateInt(device, state, device_address,
+                                                  device_name, encodedFormat);
     nextAudioPortGeneration();
     return status;
 }
 
-void AudioPolicyManager::broadcastDeviceConnectionState(audio_devices_t device,
-                                                        audio_policy_dev_state_t state,
-                                                        const String8 &device_address)
+void AudioPolicyManager::broadcastDeviceConnectionState(const sp<DeviceDescriptor> &device,
+                                                        audio_policy_dev_state_t state)
 {
-    AudioParameter param(device_address);
+    AudioParameter param(device->address());
     const String8 key(state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE ?
                 AudioParameter::keyStreamConnect : AudioParameter::keyStreamDisconnect);
-    param.addInt(key, device);
+    param.addInt(key, device->type());
     mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
 }
 
-status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t device,
+status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t deviceType,
                                                          audio_policy_dev_state_t state,
                                                          const char *device_address,
-                                                         const char *device_name)
+                                                         const char *device_name,
+                                                         audio_format_t encodedFormat)
 {
-    ALOGV("setDeviceConnectionStateInt() device: 0x%X, state %d, address %s name %s",
-            device, state, device_address, device_name);
+    ALOGV("setDeviceConnectionStateInt() device: 0x%X, state %d, address %s name %s format 0x%X",
+            deviceType, state, device_address, device_name, encodedFormat);
 
     // connect/disconnect only 1 device at a time
-    if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
+    if (!audio_is_output_device(deviceType) && !audio_is_input_device(deviceType)) return BAD_VALUE;
 
-    sp<DeviceDescriptor> devDesc =
-            mHwModules.getDeviceDescriptor(device, device_address, device_name);
+    sp<DeviceDescriptor> device =
+            mHwModules.getDeviceDescriptor(deviceType, device_address, device_name, encodedFormat,
+                                           state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
+    if (device == 0) {
+        return INVALID_OPERATION;
+    }
 
     // handle output devices
-    if (audio_is_output_device(device)) {
+    if (audio_is_output_device(deviceType)) {
         SortedVector <audio_io_handle_t> outputs;
 
-        ssize_t index = mAvailableOutputDevices.indexOf(devDesc);
+        ssize_t index = mAvailableOutputDevices.indexOf(device);
 
         // save a copy of the opened output descriptors before any output is opened or closed
         // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies()
@@ -133,115 +135,136 @@
         // handle output device connection
         case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
             if (index >= 0) {
-                ALOGW("setDeviceConnectionState() device already connected: %x", device);
+                ALOGW("%s() device already connected: %s", __func__, device->toString().c_str());
                 return INVALID_OPERATION;
             }
-            ALOGV("setDeviceConnectionState() connecting device %x", device);
+            ALOGV("%s() connecting device %s format %x",
+                    __func__, device->toString().c_str(), encodedFormat);
 
             // register new device as available
-            index = mAvailableOutputDevices.add(devDesc);
-            if (index >= 0) {
-                sp<HwModule> module = mHwModules.getModuleForDevice(device);
-                if (module == 0) {
-                    ALOGD("setDeviceConnectionState() could not find HW module for device %08x",
-                          device);
-                    mAvailableOutputDevices.remove(devDesc);
-                    return INVALID_OPERATION;
-                }
-                mAvailableOutputDevices[index]->attach(module);
-            } else {
+            if (mAvailableOutputDevices.add(device) < 0) {
                 return NO_MEMORY;
             }
 
             // Before checking outputs, broadcast connect event to allow HAL to retrieve dynamic
             // parameters on newly connected devices (instead of opening the outputs...)
-            broadcastDeviceConnectionState(device, state, devDesc->mAddress);
+            broadcastDeviceConnectionState(device, state);
 
-            if (checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress) != NO_ERROR) {
-                mAvailableOutputDevices.remove(devDesc);
+            if (checkOutputsForDevice(device, state, outputs) != NO_ERROR) {
+                mAvailableOutputDevices.remove(device);
 
-                broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
-                                               devDesc->mAddress);
+                mHwModules.cleanUpForDevice(device);
+
+                broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE);
                 return INVALID_OPERATION;
             }
-            // Propagate device availability to Engine
-            mEngine->setDeviceConnectionState(devDesc, state);
 
             // outputs should never be empty here
             ALOG_ASSERT(outputs.size() != 0, "setDeviceConnectionState():"
                     "checkOutputsForDevice() returned no outputs but status OK");
-            ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %zu outputs",
-                  outputs.size());
+            ALOGV("%s() checkOutputsForDevice() returned %zu outputs", __func__, outputs.size());
 
             } break;
         // handle output device disconnection
         case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
             if (index < 0) {
-                ALOGW("setDeviceConnectionState() device not connected: %x", device);
+                ALOGW("%s() device not connected: %s", __func__, device->toString().c_str());
                 return INVALID_OPERATION;
             }
 
-            ALOGV("setDeviceConnectionState() disconnecting output device %x", device);
+            ALOGV("%s() disconnecting output device %s", __func__, device->toString().c_str());
 
             // Send Disconnect to HALs
-            broadcastDeviceConnectionState(device, state, devDesc->mAddress);
+            broadcastDeviceConnectionState(device, state);
 
             // remove device from available output devices
-            mAvailableOutputDevices.remove(devDesc);
+            mAvailableOutputDevices.remove(device);
 
-            checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress);
+            mOutputs.clearSessionRoutesForDevice(device);
 
-            // Propagate device availability to Engine
-            mEngine->setDeviceConnectionState(devDesc, state);
+            checkOutputsForDevice(device, state, outputs);
+
+            // Reset active device codec
+            device->setEncodedFormat(AUDIO_FORMAT_DEFAULT);
+
             } break;
 
         default:
-            ALOGE("setDeviceConnectionState() invalid state: %x", state);
+            ALOGE("%s() invalid state: %x", __func__, state);
             return BAD_VALUE;
         }
 
-        // checkA2dpSuspend must run before checkOutputForAllStrategies so that A2DP
-        // output is suspended before any tracks are moved to it
-        checkA2dpSuspend();
-        checkOutputForAllStrategies();
-        // outputs must be closed after checkOutputForAllStrategies() is executed
-        if (!outputs.isEmpty()) {
+        // Propagate device availability to Engine
+        setEngineDeviceConnectionState(device, state);
+
+        // No need to evaluate playback routing when connecting a remote submix
+        // output device used by a dynamic policy of type recorder as no
+        // playback use case is affected.
+        bool doCheckForDeviceAndOutputChanges = true;
+        if (device->type() == AUDIO_DEVICE_OUT_REMOTE_SUBMIX
+                && strncmp(device_address, "0", AUDIO_DEVICE_MAX_ADDRESS_LEN) != 0) {
             for (audio_io_handle_t output : outputs) {
                 sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(output);
-                // close unused outputs after device disconnection or direct outputs that have been
-                // opened by checkOutputsForDevice() to query dynamic parameters
-                if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) ||
-                        (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) &&
-                         (desc->mDirectOpenCount == 0))) {
-                    closeOutput(output);
+                sp<AudioPolicyMix> policyMix = desc->mPolicyMix.promote();
+                if (policyMix != nullptr
+                        && policyMix->mMixType == MIX_TYPE_RECORDERS
+                        && strncmp(device_address,
+                                   policyMix->mDeviceAddress.string(),
+                                   AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
+                    doCheckForDeviceAndOutputChanges = false;
+                    break;
                 }
             }
-            // check again after closing A2DP output to reset mA2dpSuspended if needed
-            checkA2dpSuspend();
         }
 
-        updateDevicesAndOutputs();
-        if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
-            audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
-            updateCallRouting(newDevice);
+        auto checkCloseOutputs = [&]() {
+            // outputs must be closed after checkOutputForAllStrategies() is executed
+            if (!outputs.isEmpty()) {
+                for (audio_io_handle_t output : outputs) {
+                    sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(output);
+                    // close unused outputs after device disconnection or direct outputs that have
+                    // been opened by checkOutputsForDevice() to query dynamic parameters
+                    if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) ||
+                            (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) &&
+                                (desc->mDirectOpenCount == 0))) {
+                        closeOutput(output);
+                    }
+                }
+                // check A2DP again after closing A2DP output to reset mA2dpSuspended if needed
+                return true;
+            }
+            return false;
+        };
+
+        if (doCheckForDeviceAndOutputChanges) {
+            checkForDeviceAndOutputChanges(checkCloseOutputs);
+        } else {
+            checkCloseOutputs();
         }
+
+        if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
+            DeviceVector newDevices = getNewOutputDevices(mPrimaryOutput, false /*fromCache*/);
+            updateCallRouting(newDevices);
+        }
+        const DeviceVector msdOutDevices = getMsdAudioOutDevices();
         for (size_t i = 0; i < mOutputs.size(); i++) {
             sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
             if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (desc != mPrimaryOutput)) {
-                audio_devices_t newDevice = getNewOutputDevice(desc, true /*fromCache*/);
+                DeviceVector newDevices = getNewOutputDevices(desc, true /*fromCache*/);
                 // do not force device change on duplicated output because if device is 0, it will
                 // also force a device 0 for the two outputs it is duplicated to which may override
                 // a valid device selection on those outputs.
-                bool force = !desc->isDuplicated()
-                        && (!device_distinguishes_on_address(device)
+                bool force = (msdOutDevices.isEmpty() || msdOutDevices != desc->devices())
+                        && !desc->isDuplicated()
+                        && (!device_distinguishes_on_address(deviceType)
                                 // always force when disconnecting (a non-duplicated device)
                                 || (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
-                setOutputDevice(desc, newDevice, force, 0);
+                setOutputDevices(desc, newDevices, force, 0);
             }
         }
 
         if (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
-            cleanUpForDevice(devDesc);
+            cleanUpForDevice(device);
         }
 
         mpClientInterface->onAudioPortListUpdate();
@@ -249,101 +272,105 @@
     }  // end if is output device
 
     // handle input devices
-    if (audio_is_input_device(device)) {
-        SortedVector <audio_io_handle_t> inputs;
-
-        ssize_t index = mAvailableInputDevices.indexOf(devDesc);
+    if (audio_is_input_device(deviceType)) {
+        ssize_t index = mAvailableInputDevices.indexOf(device);
         switch (state)
         {
         // handle input device connection
         case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
             if (index >= 0) {
-                ALOGW("setDeviceConnectionState() device already connected: %d", device);
+                ALOGW("%s() device already connected: %s", __func__, device->toString().c_str());
                 return INVALID_OPERATION;
             }
-            sp<HwModule> module = mHwModules.getModuleForDevice(device);
-            if (module == NULL) {
-                ALOGW("setDeviceConnectionState(): could not find HW module for device %08x",
-                      device);
-                return INVALID_OPERATION;
+
+            if (mAvailableInputDevices.add(device) < 0) {
+                return NO_MEMORY;
             }
 
             // Before checking intputs, broadcast connect event to allow HAL to retrieve dynamic
             // parameters on newly connected devices (instead of opening the inputs...)
-            broadcastDeviceConnectionState(device, state, devDesc->mAddress);
+            broadcastDeviceConnectionState(device, state);
 
-            if (checkInputsForDevice(devDesc, state, inputs, devDesc->mAddress) != NO_ERROR) {
-                broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
-                                               devDesc->mAddress);
+            if (checkInputsForDevice(device, state) != NO_ERROR) {
+                mAvailableInputDevices.remove(device);
+
+                broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE);
+
+                mHwModules.cleanUpForDevice(device);
+
                 return INVALID_OPERATION;
             }
 
-            index = mAvailableInputDevices.add(devDesc);
-            if (index >= 0) {
-                mAvailableInputDevices[index]->attach(module);
-            } else {
-                return NO_MEMORY;
-            }
-
-            // Propagate device availability to Engine
-            mEngine->setDeviceConnectionState(devDesc, state);
         } break;
 
         // handle input device disconnection
         case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
             if (index < 0) {
-                ALOGW("setDeviceConnectionState() device not connected: %d", device);
+                ALOGW("%s() device not connected: %s", __func__, device->toString().c_str());
                 return INVALID_OPERATION;
             }
 
-            ALOGV("setDeviceConnectionState() disconnecting input device %x", device);
+            ALOGV("%s() disconnecting input device %s", __func__, device->toString().c_str());
 
             // Set Disconnect to HALs
-            broadcastDeviceConnectionState(device, state, devDesc->mAddress);
+            broadcastDeviceConnectionState(device, state);
 
-            checkInputsForDevice(devDesc, state, inputs, devDesc->mAddress);
-            mAvailableInputDevices.remove(devDesc);
+            mAvailableInputDevices.remove(device);
 
-            // Propagate device availability to Engine
-            mEngine->setDeviceConnectionState(devDesc, state);
+            checkInputsForDevice(device, state);
         } break;
 
         default:
-            ALOGE("setDeviceConnectionState() invalid state: %x", state);
+            ALOGE("%s() invalid state: %x", __func__, state);
             return BAD_VALUE;
         }
 
-        closeAllInputs();
+        // Propagate device availability to Engine
+        setEngineDeviceConnectionState(device, state);
+
+        checkCloseInputs();
         // As the input device list can impact the output device selection, update
         // getDeviceForStrategy() cache
         updateDevicesAndOutputs();
 
         if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
-            audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
-            updateCallRouting(newDevice);
+            DeviceVector newDevices = getNewOutputDevices(mPrimaryOutput, false /*fromCache*/);
+            updateCallRouting(newDevices);
         }
 
         if (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
-            cleanUpForDevice(devDesc);
+            cleanUpForDevice(device);
         }
 
         mpClientInterface->onAudioPortListUpdate();
         return NO_ERROR;
     } // end if is input device
 
-    ALOGW("setDeviceConnectionState() invalid device: %x", device);
+    ALOGW("%s() invalid device: %s", __func__, device->toString().c_str());
     return BAD_VALUE;
 }
 
+void AudioPolicyManager::setEngineDeviceConnectionState(const sp<DeviceDescriptor> device,
+                                      audio_policy_dev_state_t state) {
+
+    // the Engine does not have to know about remote submix devices used by dynamic audio policies
+    if (audio_is_remote_submix_device(device->type()) && device->address() != "0") {
+        return;
+    }
+    mEngine->setDeviceConnectionState(device, state);
+}
+
+
 audio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devices_t device,
                                                                       const char *device_address)
 {
     sp<DeviceDescriptor> devDesc =
-            mHwModules.getDeviceDescriptor(device, device_address, "",
+            mHwModules.getDeviceDescriptor(device, device_address, "", AUDIO_FORMAT_DEFAULT,
+                                           false /* allowToCreate */,
                                            (strlen(device_address) != 0)/*matchAddress*/);
 
     if (devDesc == 0) {
-        ALOGW("getDeviceConnectionState() undeclared device, type %08x, address: %s",
+        ALOGV("getDeviceConnectionState() undeclared device, type %08x, address: %s",
               device, device_address);
         return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
     }
@@ -355,55 +382,64 @@
     } else if (audio_is_input_device(device)) {
         deviceVector = &mAvailableInputDevices;
     } else {
-        ALOGW("getDeviceConnectionState() invalid device type %08x", device);
+        ALOGW("%s() invalid device type %08x", __func__, device);
         return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
     }
 
-    return (deviceVector->getDevice(device, String8(device_address)) != 0) ?
+    return (deviceVector->getDevice(
+                device, String8(device_address), AUDIO_FORMAT_DEFAULT) != 0) ?
             AUDIO_POLICY_DEVICE_STATE_AVAILABLE : AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
 }
 
 status_t AudioPolicyManager::handleDeviceConfigChange(audio_devices_t device,
                                                       const char *device_address,
-                                                      const char *device_name)
+                                                      const char *device_name,
+                                                      audio_format_t encodedFormat)
 {
     status_t status;
     String8 reply;
     AudioParameter param;
     int isReconfigA2dpSupported = 0;
 
-    ALOGV("handleDeviceConfigChange(() device: 0x%X, address %s name %s",
-          device, device_address, device_name);
+    ALOGV("handleDeviceConfigChange(() device: 0x%X, address %s name %s encodedFormat: 0x%X",
+          device, device_address, device_name, encodedFormat);
 
     // connect/disconnect only 1 device at a time
     if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
 
     // Check if the device is currently connected
-    sp<DeviceDescriptor> devDesc =
-            mHwModules.getDeviceDescriptor(device, device_address, device_name);
-    ssize_t index = mAvailableOutputDevices.indexOf(devDesc);
-    if (index < 0) {
+    DeviceVector deviceList = mAvailableOutputDevices.getDevicesFromTypeMask(device);
+    if (deviceList.empty()) {
         // Nothing to do: device is not connected
         return NO_ERROR;
     }
+    sp<DeviceDescriptor> devDesc = deviceList.itemAt(0);
 
     // For offloaded A2DP, Hw modules may have the capability to
-    // configure codecs. Check if any of the loaded hw modules
-    // supports this.
-    // If supported, send a set parameter to configure A2DP codecs
-    // and return. No need to toggle device state.
+    // configure codecs.
+    // Handle two specific cases by sending a set parameter to
+    // configure A2DP codecs. No need to toggle device state.
+    // Case 1: A2DP active device switches from primary to primary
+    // module
+    // Case 2: A2DP device config changes on primary module.
     if (device & AUDIO_DEVICE_OUT_ALL_A2DP) {
-        reply = mpClientInterface->getParameters(
-                    AUDIO_IO_HANDLE_NONE,
-                    String8(AudioParameter::keyReconfigA2dpSupported));
-        AudioParameter repliedParameters(reply);
-        repliedParameters.getInt(
-                String8(AudioParameter::keyReconfigA2dpSupported), isReconfigA2dpSupported);
-        if (isReconfigA2dpSupported) {
-            const String8 key(AudioParameter::keyReconfigA2dp);
-            param.add(key, String8("true"));
-            mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
-            return NO_ERROR;
+        sp<HwModule> module = mHwModules.getModuleForDeviceTypes(device, encodedFormat);
+        audio_module_handle_t primaryHandle = mPrimaryOutput->getModuleHandle();
+        if (availablePrimaryOutputDevices().contains(devDesc) &&
+           (module != 0 && module->getHandle() == primaryHandle)) {
+            reply = mpClientInterface->getParameters(
+                        AUDIO_IO_HANDLE_NONE,
+                        String8(AudioParameter::keyReconfigA2dpSupported));
+            AudioParameter repliedParameters(reply);
+            repliedParameters.getInt(
+                    String8(AudioParameter::keyReconfigA2dpSupported), isReconfigA2dpSupported);
+            if (isReconfigA2dpSupported) {
+                const String8 key(AudioParameter::keyReconfigA2dp);
+                param.add(key, String8("true"));
+                mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
+                devDesc->setEncodedFormat(encodedFormat);
+                return NO_ERROR;
+            }
         }
     }
 
@@ -411,7 +447,8 @@
     // This will force reading again the device configuration
     status = setDeviceConnectionState(device,
                                       AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
-                                      device_address, device_name);
+                                      device_address, device_name,
+                                      devDesc->getEncodedFormat());
     if (status != NO_ERROR) {
         ALOGW("handleDeviceConfigChange() error disabling connection state: %d",
               status);
@@ -420,7 +457,7 @@
 
     status = setDeviceConnectionState(device,
                                       AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
-                                      device_address, device_name);
+                                      device_address, device_name, encodedFormat);
     if (status != NO_ERROR) {
         ALOGW("handleDeviceConfigChange() error enabling connection state: %d",
               status);
@@ -430,16 +467,40 @@
     return NO_ERROR;
 }
 
-uint32_t AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, uint32_t delayMs)
+status_t AudioPolicyManager::getHwOffloadEncodingFormatsSupportedForA2DP(
+                                    std::vector<audio_format_t> *formats)
+{
+    ALOGV("getHwOffloadEncodingFormatsSupportedForA2DP()");
+    status_t status = NO_ERROR;
+    std::unordered_set<audio_format_t> formatSet;
+    sp<HwModule> primaryModule =
+            mHwModules.getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY);
+    DeviceVector declaredDevices = primaryModule->getDeclaredDevices().getDevicesFromTypeMask(
+            AUDIO_DEVICE_OUT_ALL_A2DP);
+    for (const auto& device : declaredDevices) {
+        formatSet.insert(device->encodedFormats().begin(), device->encodedFormats().end());
+    }
+    formats->assign(formatSet.begin(), formatSet.end());
+    return status;
+}
+
+uint32_t AudioPolicyManager::updateCallRouting(const DeviceVector &rxDevices, uint32_t delayMs)
 {
     bool createTxPatch = false;
+    bool createRxPatch = false;
     uint32_t muteWaitMs = 0;
 
-    if(!hasPrimaryOutput() || mPrimaryOutput->device() == AUDIO_DEVICE_OUT_STUB) {
+    if(!hasPrimaryOutput() || mPrimaryOutput->devices().types() == AUDIO_DEVICE_OUT_STUB) {
         return muteWaitMs;
     }
-    audio_devices_t txDevice = getDeviceAndMixForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
-    ALOGV("updateCallRouting device rxDevice %08x txDevice %08x", rxDevice, txDevice);
+    ALOG_ASSERT(!rxDevices.isEmpty(), "updateCallRouting() no selected output device");
+
+    audio_attributes_t attr = { .source = AUDIO_SOURCE_VOICE_COMMUNICATION };
+    auto txSourceDevice = mEngine->getInputDeviceForAttributes(attr);
+    ALOG_ASSERT(txSourceDevice != 0, "updateCallRouting() input selected device not available");
+
+    ALOGV("updateCallRouting device rxDevice %s txDevice %s",
+          rxDevices.itemAt(0)->toString().c_str(), txSourceDevice->toString().c_str());
 
     // release existing RX patch if any
     if (mCallRxPatch != 0) {
@@ -452,57 +513,92 @@
         mCallTxPatch.clear();
     }
 
-    // If the RX device is on the primary HW module, then use legacy routing method for voice calls
-    // via setOutputDevice() on primary output.
-    // Otherwise, create two audio patches for TX and RX path.
-    if (availablePrimaryOutputDevices() & rxDevice) {
-        muteWaitMs = setOutputDevice(mPrimaryOutput, rxDevice, true, delayMs);
+    auto telephonyRxModule =
+        mHwModules.getModuleForDeviceTypes(AUDIO_DEVICE_IN_TELEPHONY_RX, AUDIO_FORMAT_DEFAULT);
+    auto telephonyTxModule =
+        mHwModules.getModuleForDeviceTypes(AUDIO_DEVICE_OUT_TELEPHONY_TX, AUDIO_FORMAT_DEFAULT);
+    // retrieve Rx Source and Tx Sink device descriptors
+    sp<DeviceDescriptor> rxSourceDevice =
+        mAvailableInputDevices.getDevice(AUDIO_DEVICE_IN_TELEPHONY_RX,
+                                         String8(),
+                                         AUDIO_FORMAT_DEFAULT);
+    sp<DeviceDescriptor> txSinkDevice =
+        mAvailableOutputDevices.getDevice(AUDIO_DEVICE_OUT_TELEPHONY_TX,
+                                          String8(),
+                                          AUDIO_FORMAT_DEFAULT);
+
+    // RX and TX Telephony device are declared by Primary Audio HAL
+    if (isPrimaryModule(telephonyRxModule) && isPrimaryModule(telephonyTxModule) &&
+            (telephonyRxModule->getHalVersionMajor() >= 3)) {
+        if (rxSourceDevice == 0 || txSinkDevice == 0) {
+            // RX / TX Telephony device(s) is(are) not currently available
+            ALOGE("updateCallRouting() no telephony Tx and/or RX device");
+            return muteWaitMs;
+        }
+        // do not create a patch (aka Sw Bridging) if Primary HW module has declared supporting a
+        // route between telephony RX to Sink device and Source device to telephony TX
+        const auto &primaryModule = telephonyRxModule;
+        createRxPatch = !primaryModule->supportsPatch(rxSourceDevice, rxDevices.itemAt(0));
+        createTxPatch = !primaryModule->supportsPatch(txSourceDevice, txSinkDevice);
+    } else {
+        // If the RX device is on the primary HW module, then use legacy routing method for
+        // voice calls via setOutputDevice() on primary output.
+        // Otherwise, create two audio patches for TX and RX path.
+        createRxPatch = !(availablePrimaryOutputDevices().contains(rxDevices.itemAt(0))) &&
+                (rxSourceDevice != 0);
         // If the TX device is also on the primary HW module, setOutputDevice() will take care
         // of it due to legacy implementation. If not, create a patch.
-        if ((availablePrimaryInputDevices() & txDevice & ~AUDIO_DEVICE_BIT_IN)
-                == AUDIO_DEVICE_NONE) {
-            createTxPatch = true;
-        }
+        createTxPatch = !(availablePrimaryModuleInputDevices().contains(txSourceDevice)) &&
+                (txSinkDevice != 0);
+    }
+    // Use legacy routing method for voice calls via setOutputDevice() on primary output.
+    // Otherwise, create two audio patches for TX and RX path.
+    if (!createRxPatch) {
+        muteWaitMs = setOutputDevices(mPrimaryOutput, rxDevices, true, delayMs);
     } else { // create RX path audio patch
-        mCallRxPatch = createTelephonyPatch(true /*isRx*/, rxDevice, delayMs);
-        createTxPatch = true;
+        mCallRxPatch = createTelephonyPatch(true /*isRx*/, rxDevices.itemAt(0), delayMs);
+
+        // If the TX device is on the primary HW module but RX device is
+        // on other HW module, SinkMetaData of telephony input should handle it
+        // assuming the device uses audio HAL V5.0 and above
     }
     if (createTxPatch) { // create TX path audio patch
-        mCallTxPatch = createTelephonyPatch(false /*isRx*/, txDevice, delayMs);
+        mCallTxPatch = createTelephonyPatch(false /*isRx*/, txSourceDevice, delayMs);
     }
 
     return muteWaitMs;
 }
 
 sp<AudioPatch> AudioPolicyManager::createTelephonyPatch(
-        bool isRx, audio_devices_t device, uint32_t delayMs) {
-    struct audio_patch patch;
-    patch.num_sources = 1;
-    patch.num_sinks = 1;
+        bool isRx, const sp<DeviceDescriptor> &device, uint32_t delayMs) {
+    PatchBuilder patchBuilder;
 
-    sp<DeviceDescriptor> txSourceDeviceDesc;
+    if (device == nullptr) {
+        return nullptr;
+    }
     if (isRx) {
-        fillAudioPortConfigForDevice(mAvailableOutputDevices, device, &patch.sinks[0]);
-        fillAudioPortConfigForDevice(
-                mAvailableInputDevices, AUDIO_DEVICE_IN_TELEPHONY_RX, &patch.sources[0]);
+        patchBuilder.addSink(device).
+                addSource(mAvailableInputDevices.getDevice(
+                    AUDIO_DEVICE_IN_TELEPHONY_RX, String8(), AUDIO_FORMAT_DEFAULT));
     } else {
-        txSourceDeviceDesc = fillAudioPortConfigForDevice(
-                mAvailableInputDevices, device, &patch.sources[0]);
-        fillAudioPortConfigForDevice(
-                mAvailableOutputDevices, AUDIO_DEVICE_OUT_TELEPHONY_TX, &patch.sinks[0]);
+        patchBuilder.addSource(device).
+                addSink(mAvailableOutputDevices.getDevice(
+                    AUDIO_DEVICE_OUT_TELEPHONY_TX, String8(), AUDIO_FORMAT_DEFAULT));
     }
 
-    audio_devices_t outputDevice = isRx ? device : AUDIO_DEVICE_OUT_TELEPHONY_TX;
-    SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(outputDevice, mOutputs);
-    audio_io_handle_t output = selectOutput(outputs, AUDIO_OUTPUT_FLAG_NONE, AUDIO_FORMAT_INVALID);
+    // @TODO: still ignoring the address, or not dealing platform with mutliple telephonydevices
+    const sp<DeviceDescriptor> outputDevice = isRx ?
+                device : mAvailableOutputDevices.getDevice(
+                    AUDIO_DEVICE_OUT_TELEPHONY_TX, String8(), AUDIO_FORMAT_DEFAULT);
+    SortedVector<audio_io_handle_t> outputs =
+            getOutputsForDevices(DeviceVector(outputDevice), mOutputs);
+    const audio_io_handle_t output = selectOutput(outputs);
     // request to reuse existing output stream if one is already opened to reach the target device
     if (output != AUDIO_IO_HANDLE_NONE) {
         sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
-        ALOG_ASSERT(!outputDesc->isDuplicated(),
-                "%s() %#x device output %d is duplicated", __func__, outputDevice, output);
-        outputDesc->toAudioPortConfig(&patch.sources[1]);
-        patch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH;
-        patch.num_sources = 2;
+        ALOG_ASSERT(!outputDesc->isDuplicated(), "%s() %s device output %d is duplicated", __func__,
+                    outputDevice->toString().c_str(), output);
+        patchBuilder.addSource(outputDesc, { .stream = AUDIO_STREAM_PATCH });
     }
 
     if (!isRx) {
@@ -511,39 +607,50 @@
         // call TX device but this information is not in the audio patch and logic here must be
         // symmetric to the one in startInput()
         for (const auto& activeDesc : mInputs.getActiveInputs()) {
-            if (activeDesc->hasSameHwModuleAs(txSourceDeviceDesc)) {
-                AudioSessionCollection activeSessions =
-                        activeDesc->getAudioSessions(true /*activeOnly*/);
-                for (size_t j = 0; j < activeSessions.size(); j++) {
-                    audio_session_t activeSession = activeSessions.keyAt(j);
-                    stopInput(activeDesc->mIoHandle, activeSession);
-                    releaseInput(activeDesc->mIoHandle, activeSession);
-                }
+            if (activeDesc->hasSameHwModuleAs(device)) {
+                closeActiveClients(activeDesc);
             }
         }
     }
 
     audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
-    status_t status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, delayMs);
+    status_t status = mpClientInterface->createAudioPatch(
+            patchBuilder.patch(), &afPatchHandle, delayMs);
     ALOGW_IF(status != NO_ERROR,
             "%s() error %d creating %s audio patch", __func__, status, isRx ? "RX" : "TX");
     sp<AudioPatch> audioPatch;
     if (status == NO_ERROR) {
-        audioPatch = new AudioPatch(&patch, mUidCached);
+        audioPatch = new AudioPatch(patchBuilder.patch(), mUidCached);
         audioPatch->mAfPatchHandle = afPatchHandle;
         audioPatch->mUid = mUidCached;
     }
     return audioPatch;
 }
 
-sp<DeviceDescriptor> AudioPolicyManager::fillAudioPortConfigForDevice(
-        const DeviceVector& devices, audio_devices_t device, audio_port_config *config) {
-    DeviceVector deviceList = devices.getDevicesFromType(device);
+sp<DeviceDescriptor> AudioPolicyManager::findDevice(
+        const DeviceVector& devices, audio_devices_t device) const {
+    DeviceVector deviceList = devices.getDevicesFromTypeMask(device);
     ALOG_ASSERT(!deviceList.isEmpty(),
             "%s() selected device type %#x is not in devices list", __func__, device);
-    sp<DeviceDescriptor> deviceDesc = deviceList.itemAt(0);
-    deviceDesc->toAudioPortConfig(config);
-    return deviceDesc;
+    return deviceList.itemAt(0);
+}
+
+audio_devices_t AudioPolicyManager::getModuleDeviceTypes(
+        const DeviceVector& devices, const char *moduleId) const {
+    sp<HwModule> mod = mHwModules.getModuleFromName(moduleId);
+    return mod != 0 ? devices.getDeviceTypesFromHwModule(mod->getHandle()) : AUDIO_DEVICE_NONE;
+}
+
+bool AudioPolicyManager::isDeviceOfModule(
+        const sp<DeviceDescriptor>& devDesc, const char *moduleId) const {
+    sp<HwModule> module = mHwModules.getModuleFromName(moduleId);
+    if (module != 0) {
+        return mAvailableOutputDevices.getDevicesFromHwModule(module->getHandle())
+                .indexOf(devDesc) != NAME_NOT_FOUND
+                || mAvailableInputDevices.getDevicesFromHwModule(module->getHandle())
+                .indexOf(devDesc) != NAME_NOT_FOUND;
+    }
+    return false;
 }
 
 void AudioPolicyManager::setPhoneState(audio_mode_t state)
@@ -557,14 +664,8 @@
         return;
     }
     /// Opens: can these line be executed after the switch of volume curves???
-    // if leaving call state, handle special case of active streams
-    // pertaining to sonification strategy see handleIncallSonification()
     if (isStateInCall(oldState)) {
         ALOGV("setPhoneState() in call state management: new state is %d", state);
-        for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
-            handleIncallSonification((audio_stream_type_t)stream, false, true);
-        }
-
         // force reevaluating accessibility routing when call stops
         mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
     }
@@ -577,48 +678,47 @@
                   || (is_state_in_call(state) && (state != oldState)));
 
     // check for device and output changes triggered by new phone state
-    checkA2dpSuspend();
-    checkOutputForAllStrategies();
-    updateDevicesAndOutputs();
+    checkForDeviceAndOutputChanges();
 
     int delayMs = 0;
     if (isStateInCall(state)) {
         nsecs_t sysTime = systemTime();
+        auto musicStrategy = streamToStrategy(AUDIO_STREAM_MUSIC);
+        auto sonificationStrategy = streamToStrategy(AUDIO_STREAM_ALARM);
         for (size_t i = 0; i < mOutputs.size(); i++) {
             sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
             // mute media and sonification strategies and delay device switch by the largest
             // latency of any output where either strategy is active.
             // This avoid sending the ring tone or music tail into the earpiece or headset.
-            if ((isStrategyActive(desc, STRATEGY_MEDIA,
-                                  SONIFICATION_HEADSET_MUSIC_DELAY,
-                                  sysTime) ||
-                 isStrategyActive(desc, STRATEGY_SONIFICATION,
-                                  SONIFICATION_HEADSET_MUSIC_DELAY,
-                                  sysTime)) &&
+            if ((desc->isStrategyActive(musicStrategy, SONIFICATION_HEADSET_MUSIC_DELAY, sysTime) ||
+                 desc->isStrategyActive(sonificationStrategy, SONIFICATION_HEADSET_MUSIC_DELAY,
+                                        sysTime)) &&
                     (delayMs < (int)desc->latency()*2)) {
                 delayMs = desc->latency()*2;
             }
-            setStrategyMute(STRATEGY_MEDIA, true, desc);
-            setStrategyMute(STRATEGY_MEDIA, false, desc, MUTE_TIME_MS,
-                getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
-            setStrategyMute(STRATEGY_SONIFICATION, true, desc);
-            setStrategyMute(STRATEGY_SONIFICATION, false, desc, MUTE_TIME_MS,
-                getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/));
+            setStrategyMute(musicStrategy, true, desc);
+            setStrategyMute(musicStrategy, false, desc, MUTE_TIME_MS,
+                mEngine->getOutputDevicesForAttributes(attributes_initializer(AUDIO_USAGE_MEDIA),
+                                                       nullptr, true /*fromCache*/).types());
+            setStrategyMute(sonificationStrategy, true, desc);
+            setStrategyMute(sonificationStrategy, false, desc, MUTE_TIME_MS,
+                mEngine->getOutputDevicesForAttributes(attributes_initializer(AUDIO_USAGE_ALARM),
+                                                       nullptr, true /*fromCache*/).types());
         }
     }
 
     if (hasPrimaryOutput()) {
-        // Note that despite the fact that getNewOutputDevice() is called on the primary output,
+        // Note that despite the fact that getNewOutputDevices() is called on the primary output,
         // the device returned is not necessarily reachable via this output
-        audio_devices_t rxDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
+        DeviceVector rxDevices = getNewOutputDevices(mPrimaryOutput, false /*fromCache*/);
         // force routing command to audio hardware when ending call
         // even if no device change is needed
-        if (isStateInCall(oldState) && rxDevice == AUDIO_DEVICE_NONE) {
-            rxDevice = mPrimaryOutput->device();
+        if (isStateInCall(oldState) && rxDevices.isEmpty()) {
+            rxDevices = mPrimaryOutput->devices();
         }
 
         if (state == AUDIO_MODE_IN_CALL) {
-            updateCallRouting(rxDevice, delayMs);
+            updateCallRouting(rxDevices, delayMs);
         } else if (oldState == AUDIO_MODE_IN_CALL) {
             if (mCallRxPatch != 0) {
                 mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0);
@@ -628,40 +728,30 @@
                 mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0);
                 mCallTxPatch.clear();
             }
-            setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
+            setOutputDevices(mPrimaryOutput, rxDevices, force, 0);
         } else {
-            setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
+            setOutputDevices(mPrimaryOutput, rxDevices, force, 0);
         }
     }
 
     // reevaluate routing on all outputs in case tracks have been started during the call
     for (size_t i = 0; i < mOutputs.size(); i++) {
         sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
-        audio_devices_t newDevice = getNewOutputDevice(desc, true /*fromCache*/);
+        DeviceVector newDevices = getNewOutputDevices(desc, true /*fromCache*/);
         if (state != AUDIO_MODE_IN_CALL || desc != mPrimaryOutput) {
-            setOutputDevice(desc, newDevice, (newDevice != AUDIO_DEVICE_NONE), 0 /*delayMs*/);
+            setOutputDevices(desc, newDevices, !newDevices.isEmpty(), 0 /*delayMs*/);
         }
     }
 
-    // if entering in call state, handle special case of active streams
-    // pertaining to sonification strategy see handleIncallSonification()
     if (isStateInCall(state)) {
         ALOGV("setPhoneState() in call state management: new state is %d", state);
-        for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
-            handleIncallSonification((audio_stream_type_t)stream, true, true);
-        }
-
         // force reevaluating accessibility routing when call starts
         mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
     }
 
     // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
-    if (state == AUDIO_MODE_RINGTONE &&
-        isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
-        mLimitRingtoneVolume = true;
-    } else {
-        mLimitRingtoneVolume = false;
-    }
+    mLimitRingtoneVolume = (state == AUDIO_MODE_RINGTONE &&
+                            isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY));
 }
 
 audio_mode_t AudioPolicyManager::getPhoneState() {
@@ -669,7 +759,7 @@
 }
 
 void AudioPolicyManager::setForceUse(audio_policy_force_use_t usage,
-                                         audio_policy_forced_cfg_t config)
+                                     audio_policy_forced_cfg_t config)
 {
     ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mEngine->getPhoneState());
     if (config == mEngine->getForceUse(usage)) {
@@ -685,9 +775,13 @@
             (usage == AUDIO_POLICY_FORCE_FOR_SYSTEM);
 
     // check for device and output changes triggered by new force usage
-    checkA2dpSuspend();
-    checkOutputForAllStrategies();
-    updateDevicesAndOutputs();
+    checkForDeviceAndOutputChanges();
+
+    // force client reconnection to reevaluate flag AUDIO_FLAG_AUDIBILITY_ENFORCED
+    if (usage == AUDIO_POLICY_FORCE_FOR_SYSTEM) {
+        mpClientInterface->invalidateStream(AUDIO_STREAM_SYSTEM);
+        mpClientInterface->invalidateStream(AUDIO_STREAM_ENFORCED_AUDIBLE);
+    }
 
     //FIXME: workaround for truncated touch sounds
     // to be removed when the problem is handled by system UI
@@ -697,26 +791,27 @@
         delayMs = TOUCH_SOUND_FIXED_DELAY_MS;
     }
     if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
-        audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, true /*fromCache*/);
-        waitMs = updateCallRouting(newDevice, delayMs);
+        DeviceVector newDevices = getNewOutputDevices(mPrimaryOutput, true /*fromCache*/);
+        waitMs = updateCallRouting(newDevices, delayMs);
     }
     for (size_t i = 0; i < mOutputs.size(); i++) {
         sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
-        audio_devices_t newDevice = getNewOutputDevice(outputDesc, true /*fromCache*/);
+        DeviceVector newDevices = getNewOutputDevices(outputDesc, true /*fromCache*/);
         if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (outputDesc != mPrimaryOutput)) {
-            waitMs = setOutputDevice(outputDesc, newDevice, (newDevice != AUDIO_DEVICE_NONE),
-                                     delayMs);
+            // As done in setDeviceConnectionState, we could also fix default device issue by
+            // preventing the force re-routing in case of default dev that distinguishes on address.
+            // Let's give back to engine full device choice decision however.
+            waitMs = setOutputDevices(outputDesc, newDevices, !newDevices.isEmpty(), delayMs);
         }
-        if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) {
-            applyStreamVolumes(outputDesc, newDevice, waitMs, true);
+        if (forceVolumeReeval && !newDevices.isEmpty()) {
+            applyStreamVolumes(outputDesc, newDevices.types(), waitMs, true);
         }
     }
 
     for (const auto& activeDesc : mInputs.getActiveInputs()) {
-        audio_devices_t newDevice = getNewInputDevice(activeDesc);
+        auto newDevice = getNewInputDevice(activeDesc);
         // Force new input selection if the new device can not be reached via current input
-        if (activeDesc->mProfile->getSupportedDevices().types() &
-                (newDevice & ~AUDIO_DEVICE_BIT_IN)) {
+        if (activeDesc->mProfile->getSupportedDevices().contains(newDevice)) {
             setInputDevice(activeDesc->mIoHandle, newDevice);
         } else {
             closeInput(activeDesc->mIoHandle);
@@ -729,28 +824,31 @@
     ALOGV("setSystemProperty() property %s, value %s", property, value);
 }
 
-// Find a direct output profile compatible with the parameters passed, even if the input flags do
-// not explicitly request a direct output
-sp<IOProfile> AudioPolicyManager::getProfileForDirectOutput(
-                                                               audio_devices_t device,
-                                                               uint32_t samplingRate,
-                                                               audio_format_t format,
-                                                               audio_channel_mask_t channelMask,
-                                                               audio_output_flags_t flags)
+// Find an output profile compatible with the parameters passed. When "directOnly" is set, restrict
+// search to profiles for direct outputs.
+sp<IOProfile> AudioPolicyManager::getProfileForOutput(
+                                                   const DeviceVector& devices,
+                                                   uint32_t samplingRate,
+                                                   audio_format_t format,
+                                                   audio_channel_mask_t channelMask,
+                                                   audio_output_flags_t flags,
+                                                   bool directOnly)
 {
-    // only retain flags that will drive the direct output profile selection
-    // if explicitly requested
-    static const uint32_t kRelevantFlags =
-            (AUDIO_OUTPUT_FLAG_HW_AV_SYNC | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
-             AUDIO_OUTPUT_FLAG_VOIP_RX);
-    flags =
-        (audio_output_flags_t)((flags & kRelevantFlags) | AUDIO_OUTPUT_FLAG_DIRECT);
+    if (directOnly) {
+        // only retain flags that will drive the direct output profile selection
+        // if explicitly requested
+        static const uint32_t kRelevantFlags =
+                (AUDIO_OUTPUT_FLAG_HW_AV_SYNC | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
+                 AUDIO_OUTPUT_FLAG_VOIP_RX);
+        flags =
+            (audio_output_flags_t)((flags & kRelevantFlags) | AUDIO_OUTPUT_FLAG_DIRECT);
+    }
 
     sp<IOProfile> profile;
 
     for (const auto& hwModule : mHwModules) {
         for (const auto& curProfile : hwModule->getOutputProfiles()) {
-            if (!curProfile->isCompatibleProfile(device, String8(""),
+            if (!curProfile->isCompatibleProfile(devices,
                     samplingRate, NULL /*updatedSamplingRate*/,
                     format, NULL /*updatedFormat*/,
                     channelMask, NULL /*updatedChannelMask*/,
@@ -758,10 +856,16 @@
                 continue;
             }
             // reject profiles not corresponding to a device currently available
-            if ((mAvailableOutputDevices.types() & curProfile->getSupportedDevicesType()) == 0) {
+            if (!mAvailableOutputDevices.containsAtLeastOne(curProfile->getSupportedDevices())) {
                 continue;
             }
-            // if several profiles are compatible, give priority to one with offload capability
+            // reject profiles if connected device does not support codec
+            if (!curProfile->deviceSupportsEncodedFormats(devices.types())) {
+                continue;
+            }
+            if (!directOnly) return curProfile;
+            // when searching for direct outputs, if several profiles are compatible, give priority
+            // to one with offload capability
             if (profile != 0 && ((curProfile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0)) {
                 continue;
             }
@@ -776,8 +880,7 @@
 
 audio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream)
 {
-    routing_strategy strategy = getStrategy(stream);
-    audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
+    DeviceVector devices = mEngine->getOutputDevicesForStream(stream, false /*fromCache*/);
 
     // Note that related method getOutputForAttr() uses getOutputForDevice() not selectOutput().
     // We use selectOutput() here since we don't have the desired AudioTrack sample rate,
@@ -785,13 +888,163 @@
     // getOutput() solely on audio_stream_type such as AudioSystem::getOutputFrameCount()
     // and AudioSystem::getOutputSamplingRate().
 
-    SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
-    audio_io_handle_t output = selectOutput(outputs, AUDIO_OUTPUT_FLAG_NONE, AUDIO_FORMAT_INVALID);
+    SortedVector<audio_io_handle_t> outputs = getOutputsForDevices(devices, mOutputs);
+    const audio_io_handle_t output = selectOutput(outputs);
 
-    ALOGV("getOutput() stream %d selected device %08x, output %d", stream, device, output);
+    ALOGV("getOutput() stream %d selected devices %s, output %d", stream,
+          devices.toString().c_str(), output);
     return output;
 }
 
+status_t AudioPolicyManager::getAudioAttributes(audio_attributes_t *dstAttr,
+                                                const audio_attributes_t *srcAttr,
+                                                audio_stream_type_t srcStream)
+{
+    if (srcAttr != NULL) {
+        if (!isValidAttributes(srcAttr)) {
+            ALOGE("%s invalid attributes: usage=%d content=%d flags=0x%x tags=[%s]",
+                    __func__,
+                    srcAttr->usage, srcAttr->content_type, srcAttr->flags,
+                    srcAttr->tags);
+            return BAD_VALUE;
+        }
+        *dstAttr = *srcAttr;
+    } else {
+        if (srcStream < AUDIO_STREAM_MIN || srcStream >= AUDIO_STREAM_PUBLIC_CNT) {
+            ALOGE("%s:  invalid stream type", __func__);
+            return BAD_VALUE;
+        }
+        *dstAttr = mEngine->getAttributesForStreamType(srcStream);
+    }
+
+    // Only honor audibility enforced when required. The client will be
+    // forced to reconnect if the forced usage changes.
+    if (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
+        dstAttr->flags &= ~AUDIO_FLAG_AUDIBILITY_ENFORCED;
+    }
+
+    return NO_ERROR;
+}
+
+status_t AudioPolicyManager::getOutputForAttrInt(
+        audio_attributes_t *resultAttr,
+        audio_io_handle_t *output,
+        audio_session_t session,
+        const audio_attributes_t *attr,
+        audio_stream_type_t *stream,
+        uid_t uid,
+        const audio_config_t *config,
+        audio_output_flags_t *flags,
+        audio_port_handle_t *selectedDeviceId,
+        bool *isRequestedDeviceForExclusiveUse,
+        std::vector<sp<SwAudioOutputDescriptor>> *secondaryDescs)
+{
+    DeviceVector outputDevices;
+    const audio_port_handle_t requestedPortId = *selectedDeviceId;
+    DeviceVector msdDevices = getMsdAudioOutDevices();
+    const sp<DeviceDescriptor> requestedDevice =
+        mAvailableOutputDevices.getDeviceFromId(requestedPortId);
+
+    status_t status = getAudioAttributes(resultAttr, attr, *stream);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    if (auto it = mAllowedCapturePolicies.find(uid); it != end(mAllowedCapturePolicies)) {
+        resultAttr->flags |= it->second;
+    }
+    *stream = mEngine->getStreamTypeForAttributes(*resultAttr);
+
+    ALOGV("%s() attributes=%s stream=%s session %d selectedDeviceId %d", __func__,
+          toString(*resultAttr).c_str(), toString(*stream).c_str(), session, requestedPortId);
+
+    // The primary output is the explicit routing (eg. setPreferredDevice) if specified,
+    //       otherwise, fallback to the dynamic policies, if none match, query the engine.
+    // Secondary outputs are always found by dynamic policies as the engine do not support them
+    sp<SwAudioOutputDescriptor> policyDesc;
+    status = mPolicyMixes.getOutputForAttr(*resultAttr, uid, *flags, policyDesc, secondaryDescs);
+    if (status != OK) {
+        return status;
+    }
+
+    // Explicit routing is higher priority then any dynamic policy primary output
+    bool usePrimaryOutputFromPolicyMixes = requestedDevice == nullptr && policyDesc != nullptr;
+
+    // FIXME: in case of RENDER policy, the output capabilities should be checked
+    if ((usePrimaryOutputFromPolicyMixes || !secondaryDescs->empty())
+        && !audio_is_linear_pcm(config->format)) {
+        ALOGD("%s: rejecting request as dynamic audio policy only support pcm", __func__);
+        return BAD_VALUE;
+    }
+    if (usePrimaryOutputFromPolicyMixes) {
+        *output = policyDesc->mIoHandle;
+        sp<AudioPolicyMix> mix = policyDesc->mPolicyMix.promote();
+        sp<DeviceDescriptor> deviceDesc =
+                mAvailableOutputDevices.getDevice(mix->mDeviceType,
+                                                  mix->mDeviceAddress,
+                                                  AUDIO_FORMAT_DEFAULT);
+        *selectedDeviceId = deviceDesc != 0 ? deviceDesc->getId() : AUDIO_PORT_HANDLE_NONE;
+        ALOGV("getOutputForAttr() returns output %d", *output);
+        return NO_ERROR;
+    }
+    // Virtual sources must always be dynamicaly or explicitly routed
+    if (resultAttr->usage == AUDIO_USAGE_VIRTUAL_SOURCE) {
+        ALOGW("getOutputForAttr() no policy mix found for usage AUDIO_USAGE_VIRTUAL_SOURCE");
+        return BAD_VALUE;
+    }
+    // explicit routing managed by getDeviceForStrategy in APM is now handled by engine
+    // in order to let the choice of the order to future vendor engine
+    outputDevices = mEngine->getOutputDevicesForAttributes(*resultAttr, requestedDevice, false);
+
+    if ((resultAttr->flags & AUDIO_FLAG_HW_AV_SYNC) != 0) {
+        *flags = (audio_output_flags_t)(*flags | AUDIO_OUTPUT_FLAG_HW_AV_SYNC);
+    }
+
+    // Set incall music only if device was explicitly set, and fallback to the device which is
+    // chosen by the engine if not.
+    // FIXME: provide a more generic approach which is not device specific and move this back
+    // to getOutputForDevice.
+    // TODO: Remove check of AUDIO_STREAM_MUSIC once migration is completed on the app side.
+    if (outputDevices.types() == AUDIO_DEVICE_OUT_TELEPHONY_TX &&
+        (*stream == AUDIO_STREAM_MUSIC  || resultAttr->usage == AUDIO_USAGE_VOICE_COMMUNICATION) &&
+        audio_is_linear_pcm(config->format) &&
+        isInCall()) {
+        if (requestedPortId != AUDIO_PORT_HANDLE_NONE) {
+            *flags = (audio_output_flags_t)AUDIO_OUTPUT_FLAG_INCALL_MUSIC;
+            *isRequestedDeviceForExclusiveUse = true;
+        }
+    }
+
+    ALOGV("%s() device %s, sampling rate %d, format %#x, channel mask %#x, flags %#x stream %s",
+          __func__, outputDevices.toString().c_str(), config->sample_rate, config->format,
+          config->channel_mask, *flags, toString(*stream).c_str());
+
+    *output = AUDIO_IO_HANDLE_NONE;
+    if (!msdDevices.isEmpty()) {
+        *output = getOutputForDevices(msdDevices, session, *stream, config, flags);
+        sp<DeviceDescriptor> device = outputDevices.isEmpty() ? nullptr : outputDevices.itemAt(0);
+        if (*output != AUDIO_IO_HANDLE_NONE && setMsdPatch(device) == NO_ERROR) {
+            ALOGV("%s() Using MSD devices %s instead of devices %s",
+                  __func__, msdDevices.toString().c_str(), outputDevices.toString().c_str());
+            outputDevices = msdDevices;
+        } else {
+            *output = AUDIO_IO_HANDLE_NONE;
+        }
+    }
+    if (*output == AUDIO_IO_HANDLE_NONE) {
+        *output = getOutputForDevices(outputDevices, session, *stream, config,
+                flags, resultAttr->flags & AUDIO_FLAG_MUTE_HAPTIC);
+    }
+    if (*output == AUDIO_IO_HANDLE_NONE) {
+        return INVALID_OPERATION;
+    }
+
+    *selectedDeviceId = getFirstDeviceId(outputDevices);
+
+    ALOGV("%s returns output %d selectedDeviceId %d", __func__, *output, *selectedDeviceId);
+
+    return NO_ERROR;
+}
+
 status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
                                               audio_io_handle_t *output,
                                               audio_session_t session,
@@ -800,111 +1053,73 @@
                                               const audio_config_t *config,
                                               audio_output_flags_t *flags,
                                               audio_port_handle_t *selectedDeviceId,
-                                              audio_port_handle_t *portId)
+                                              audio_port_handle_t *portId,
+                                              std::vector<audio_io_handle_t> *secondaryOutputs)
 {
-    audio_attributes_t attributes;
-    if (attr != NULL) {
-        if (!isValidAttributes(attr)) {
-            ALOGE("getOutputForAttr() invalid attributes: usage=%d content=%d flags=0x%x tags=[%s]",
-                  attr->usage, attr->content_type, attr->flags,
-                  attr->tags);
-            return BAD_VALUE;
-        }
-        attributes = *attr;
-    } else {
-        if (*stream < AUDIO_STREAM_MIN || *stream >= AUDIO_STREAM_PUBLIC_CNT) {
-            ALOGE("getOutputForAttr():  invalid stream type");
-            return BAD_VALUE;
-        }
-        stream_type_to_audio_attributes(*stream, &attributes);
-    }
-
-    // TODO: check for existing client for this port ID
-    if (*portId == AUDIO_PORT_HANDLE_NONE) {
-        *portId = AudioPort::getNextUniqueId();
-    }
-
-    sp<SwAudioOutputDescriptor> desc;
-    if (mPolicyMixes.getOutputForAttr(attributes, uid, desc) == NO_ERROR) {
-        ALOG_ASSERT(desc != 0, "Invalid desc returned by getOutputForAttr");
-        if (!audio_has_proportional_frames(config->format)) {
-            return BAD_VALUE;
-        }
-        *stream = streamTypefromAttributesInt(&attributes);
-        *output = desc->mIoHandle;
-        ALOGV("getOutputForAttr() returns output %d", *output);
-        return NO_ERROR;
-    }
-    if (attributes.usage == AUDIO_USAGE_VIRTUAL_SOURCE) {
-        ALOGW("getOutputForAttr() no policy mix found for usage AUDIO_USAGE_VIRTUAL_SOURCE");
-        return BAD_VALUE;
-    }
-
-    ALOGV("getOutputForAttr() usage=%d, content=%d, tag=%s flags=%08x"
-            " session %d selectedDeviceId %d",
-            attributes.usage, attributes.content_type, attributes.tags, attributes.flags,
-            session, *selectedDeviceId);
-
-    *stream = streamTypefromAttributesInt(&attributes);
-
-    // Explicit routing?
-    sp<DeviceDescriptor> deviceDesc;
-    if (*selectedDeviceId != AUDIO_PORT_HANDLE_NONE) {
-        deviceDesc = mAvailableOutputDevices.getDeviceFromId(*selectedDeviceId);
-    }
-    mOutputRoutes.addRoute(session, *stream, SessionRoute::SOURCE_TYPE_NA, deviceDesc, uid);
-
-    routing_strategy strategy = (routing_strategy) getStrategyForAttr(&attributes);
-    audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
-
-    if ((attributes.flags & AUDIO_FLAG_HW_AV_SYNC) != 0) {
-        *flags = (audio_output_flags_t)(*flags | AUDIO_OUTPUT_FLAG_HW_AV_SYNC);
-    }
-
-    // Set incall music only if device was explicitly set, and fallback to the device which is
-    // chosen by the engine if not.
-    // FIXME: provide a more generic approach which is not device specific and move this back
-    // to getOutputForDevice.
-    if (device == AUDIO_DEVICE_OUT_TELEPHONY_TX &&
-        *stream == AUDIO_STREAM_MUSIC &&
-        audio_is_linear_pcm(config->format) &&
-        isInCall()) {
-        if (*selectedDeviceId != AUDIO_PORT_HANDLE_NONE) {
-            *flags = (audio_output_flags_t)AUDIO_OUTPUT_FLAG_INCALL_MUSIC;
-        } else {
-            device = mEngine->getDeviceForStrategy(strategy);
-        }
-    }
-
-    ALOGV("getOutputForAttr() device 0x%x, sampling rate %d, format %#x, channel mask %#x, "
-          "flags %#x",
-          device, config->sample_rate, config->format, config->channel_mask, *flags);
-
-    *output = getOutputForDevice(device, session, *stream, config, flags);
-    if (*output == AUDIO_IO_HANDLE_NONE) {
-        mOutputRoutes.removeRoute(session);
+    // The supplied portId must be AUDIO_PORT_HANDLE_NONE
+    if (*portId != AUDIO_PORT_HANDLE_NONE) {
         return INVALID_OPERATION;
     }
+    const audio_port_handle_t requestedPortId = *selectedDeviceId;
+    audio_attributes_t resultAttr;
+    bool isRequestedDeviceForExclusiveUse = false;
+    std::vector<sp<SwAudioOutputDescriptor>> secondaryOutputDescs;
+    const sp<DeviceDescriptor> requestedDevice =
+      mAvailableOutputDevices.getDeviceFromId(requestedPortId);
 
-    DeviceVector outputDevices = mAvailableOutputDevices.getDevicesFromType(device);
-    *selectedDeviceId = outputDevices.size() > 0 ? outputDevices.itemAt(0)->getId()
-            : AUDIO_PORT_HANDLE_NONE;
+    // Prevent from storing invalid requested device id in clients
+    const audio_port_handle_t sanitizedRequestedPortId =
+      requestedDevice != nullptr ? requestedPortId : AUDIO_PORT_HANDLE_NONE;
+    *selectedDeviceId = sanitizedRequestedPortId;
 
-    ALOGV("  getOutputForAttr() returns output %d selectedDeviceId %d", *output, *selectedDeviceId);
+    status_t status = getOutputForAttrInt(&resultAttr, output, session, attr, stream, uid,
+            config, flags, selectedDeviceId, &isRequestedDeviceForExclusiveUse,
+            &secondaryOutputDescs);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    std::vector<wp<SwAudioOutputDescriptor>> weakSecondaryOutputDescs;
+    for (auto& secondaryDesc : secondaryOutputDescs) {
+        secondaryOutputs->push_back(secondaryDesc->mIoHandle);
+        weakSecondaryOutputDescs.push_back(secondaryDesc);
+    }
+
+    audio_config_base_t clientConfig = {.sample_rate = config->sample_rate,
+        .format = config->format,
+        .channel_mask = config->channel_mask };
+    *portId = AudioPort::getNextUniqueId();
+
+    sp<TrackClientDescriptor> clientDesc =
+        new TrackClientDescriptor(*portId, uid, session, resultAttr, clientConfig,
+                                  sanitizedRequestedPortId, *stream,
+                                  mEngine->getProductStrategyForAttributes(resultAttr),
+                                  toVolumeSource(resultAttr),
+                                  *flags, isRequestedDeviceForExclusiveUse,
+                                  std::move(weakSecondaryOutputDescs));
+    sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(*output);
+    outputDesc->addClient(clientDesc);
+
+    ALOGV("%s() returns output %d requestedPortId %d selectedDeviceId %d for port ID %d", __func__,
+          *output, requestedPortId, *selectedDeviceId, *portId);
 
     return NO_ERROR;
 }
 
-audio_io_handle_t AudioPolicyManager::getOutputForDevice(
-        audio_devices_t device,
+audio_io_handle_t AudioPolicyManager::getOutputForDevices(
+        const DeviceVector &devices,
         audio_session_t session,
         audio_stream_type_t stream,
         const audio_config_t *config,
-        audio_output_flags_t *flags)
+        audio_output_flags_t *flags,
+        bool forceMutingHaptic)
 {
     audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
     status_t status;
 
+    // Discard haptic channel mask when forcing muting haptic channels.
+    audio_channel_mask_t channelMask = forceMutingHaptic
+            ? (config->channel_mask & ~AUDIO_CHANNEL_HAPTIC_ALL) : config->channel_mask;
+
     // open a direct output if required by specified parameters
     //force direct flag if offload flag is set: offloading implies a direct output stream
     // and all common behaviors are driven by checking only the direct flag
@@ -927,7 +1142,8 @@
     if (stream == AUDIO_STREAM_TTS) {
         *flags = AUDIO_OUTPUT_FLAG_TTS;
     } else if (stream == AUDIO_STREAM_VOICE_CALL &&
-               audio_is_linear_pcm(config->format)) {
+               audio_is_linear_pcm(config->format) &&
+               (*flags & AUDIO_OUTPUT_FLAG_INCALL_MUSIC) == 0) {
         *flags = (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_VOIP_RX |
                                        AUDIO_OUTPUT_FLAG_DIRECT);
         ALOGV("Set VoIP and Direct output flags for PCM format");
@@ -940,7 +1156,7 @@
     // and not explicitly requested
     if (((*flags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) &&
             audio_is_linear_pcm(config->format) && config->sample_rate <= SAMPLE_RATE_HZ_MAX &&
-            audio_channel_count_from_out_mask(config->channel_mask) <= 2) {
+            audio_channel_count_from_out_mask(channelMask) <= 2) {
         goto non_direct_output;
     }
 
@@ -953,11 +1169,12 @@
 
     if (((*flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) ||
             !(mEffects.isNonOffloadableEffectEnabled() || mMasterMono)) {
-        profile = getProfileForDirectOutput(device,
-                                           config->sample_rate,
-                                           config->format,
-                                           config->channel_mask,
-                                           (audio_output_flags_t)*flags);
+        profile = getProfileForOutput(devices,
+                                   config->sample_rate,
+                                   config->format,
+                                   channelMask,
+                                   (audio_output_flags_t)*flags,
+                                   true /* directOnly */);
     }
 
     if (profile != 0) {
@@ -969,10 +1186,10 @@
                 // and configured with same parameters
                 if ((config->sample_rate == desc->mSamplingRate) &&
                     (config->format == desc->mFormat) &&
-                    (config->channel_mask == desc->mChannelMask) &&
+                    (channelMask == desc->mChannelMask) &&
                     (session == desc->mDirectClientSession)) {
                     desc->mDirectOpenCount++;
-                    ALOGI("getOutputForDevice() reusing direct output %d for session %d",
+                    ALOGI("%s reusing direct output %d for session %d", __func__, 
                         mOutputs.keyAt(i), session);
                     return mOutputs.keyAt(i);
                 }
@@ -986,21 +1203,36 @@
         sp<SwAudioOutputDescriptor> outputDesc =
                 new SwAudioOutputDescriptor(profile, mpClientInterface);
 
-        DeviceVector outputDevices = mAvailableOutputDevices.getDevicesFromType(device);
-        String8 address = outputDevices.size() > 0 ? outputDevices.itemAt(0)->mAddress
-                : String8("");
+        String8 address = getFirstDeviceAddress(devices);
 
-        status = outputDesc->open(config, device, address, stream, *flags, &output);
+        // MSD patch may be using the only output stream that can service this request. Release
+        // MSD patch to prioritize this request over any active output on MSD.
+        AudioPatchCollection msdPatches = getMsdPatches();
+        for (size_t i = 0; i < msdPatches.size(); i++) {
+            const auto& patch = msdPatches[i];
+            for (size_t j = 0; j < patch->mPatch.num_sinks; ++j) {
+                const struct audio_port_config *sink = &patch->mPatch.sinks[j];
+                if (sink->type == AUDIO_PORT_TYPE_DEVICE &&
+                        (sink->ext.device.type & devices.types()) != AUDIO_DEVICE_NONE &&
+                        (address.isEmpty() || strncmp(sink->ext.device.address, address.string(),
+                                AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0)) {
+                    releaseAudioPatch(patch->mHandle, mUidCached);
+                    break;
+                }
+            }
+        }
+
+        status = outputDesc->open(config, devices, stream, *flags, &output);
 
         // only accept an output with the requested parameters
         if (status != NO_ERROR ||
             (config->sample_rate != 0 && config->sample_rate != outputDesc->mSamplingRate) ||
             (config->format != AUDIO_FORMAT_DEFAULT && config->format != outputDesc->mFormat) ||
-            (config->channel_mask != 0 && config->channel_mask != outputDesc->mChannelMask)) {
-            ALOGV("getOutputForDevice() failed opening direct output: output %d sample rate %d %d,"
-                    "format %d %d, channel mask %04x %04x", output, config->sample_rate,
+            (channelMask != 0 && channelMask != outputDesc->mChannelMask)) {
+            ALOGV("%s failed opening direct output: output %d sample rate %d %d," 
+                    "format %d %d, channel mask %04x %04x", __func__, output, config->sample_rate,
                     outputDesc->mSamplingRate, config->format, outputDesc->mFormat,
-                    config->channel_mask, outputDesc->mChannelMask);
+                    channelMask, outputDesc->mChannelMask);
             if (output != AUDIO_IO_HANDLE_NONE) {
                 outputDesc->close();
             }
@@ -1011,14 +1243,12 @@
             }
             return AUDIO_IO_HANDLE_NONE;
         }
-        outputDesc->mRefCount[stream] = 0;
-        outputDesc->mStopTime[stream] = 0;
         outputDesc->mDirectOpenCount = 1;
         outputDesc->mDirectClientSession = session;
 
         addOutput(output, outputDesc);
         mPreviousOutputs = mOutputs;
-        ALOGV("getOutputForDevice() returns new direct output %d", output);
+        ALOGV("%s returns new direct output %d", __func__, output);
         mpClientInterface->onAudioPortListUpdate();
         return output;
     }
@@ -1039,159 +1269,327 @@
     if (audio_is_linear_pcm(config->format)) {
         // get which output is suitable for the specified stream. The actual
         // routing change will happen when startOutput() will be called
-        SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
+        SortedVector<audio_io_handle_t> outputs = getOutputsForDevices(devices, mOutputs);
 
         // at this stage we should ignore the DIRECT flag as no direct output could be found earlier
         *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_DIRECT);
-        output = selectOutput(outputs, *flags, config->format);
+        output = selectOutput(outputs, *flags, config->format, channelMask, config->sample_rate);
     }
-    ALOGW_IF((output == 0), "getOutputForDevice() could not find output for stream %d, "
+    ALOGW_IF((output == 0), "getOutputForDevices() could not find output for stream %d, "
             "sampling rate %d, format %#x, channels %#x, flags %#x",
-            stream, config->sample_rate, config->format, config->channel_mask, *flags);
+            stream, config->sample_rate, config->format, channelMask, *flags);
 
     return output;
 }
 
-audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_handle_t>& outputs,
-                                                       audio_output_flags_t flags,
-                                                       audio_format_t format)
-{
-    // select one output among several that provide a path to a particular device or set of
-    // devices (the list was previously build by getOutputsForDevice()).
-    // The priority is as follows:
-    // 1: the output with the highest number of requested policy flags
-    // 2: the output with the bit depth the closest to the requested one
-    // 3: the primary output
-    // 4: the first output in the list
+sp<DeviceDescriptor> AudioPolicyManager::getMsdAudioInDevice() const {
+    auto msdInDevices = mHwModules.getAvailableDevicesFromModuleName(AUDIO_HARDWARE_MODULE_ID_MSD,
+                                                                     mAvailableInputDevices);
+    return msdInDevices.isEmpty()? nullptr : msdInDevices.itemAt(0);
+}
 
-    if (outputs.size() == 0) {
-        return AUDIO_IO_HANDLE_NONE;
-    }
-    if (outputs.size() == 1) {
-        return outputs[0];
-    }
+DeviceVector AudioPolicyManager::getMsdAudioOutDevices() const {
+    return mHwModules.getAvailableDevicesFromModuleName(AUDIO_HARDWARE_MODULE_ID_MSD,
+                                                        mAvailableOutputDevices);
+}
 
-    int maxCommonFlags = 0;
-    audio_io_handle_t outputForFlags = AUDIO_IO_HANDLE_NONE;
-    audio_io_handle_t outputForPrimary = AUDIO_IO_HANDLE_NONE;
-    audio_io_handle_t outputForFormat = AUDIO_IO_HANDLE_NONE;
-    audio_format_t bestFormat = AUDIO_FORMAT_INVALID;
-    audio_format_t bestFormatForFlags = AUDIO_FORMAT_INVALID;
-
-    for (audio_io_handle_t output : outputs) {
-        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
-        if (!outputDesc->isDuplicated()) {
-            // if a valid format is specified, skip output if not compatible
-            if (format != AUDIO_FORMAT_INVALID) {
-                if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
-                    if (format != outputDesc->mFormat) {
-                        continue;
-                    }
-                } else if (!audio_is_linear_pcm(format)) {
-                    continue;
+const AudioPatchCollection AudioPolicyManager::getMsdPatches() const {
+    AudioPatchCollection msdPatches;
+    sp<HwModule> msdModule = mHwModules.getModuleFromName(AUDIO_HARDWARE_MODULE_ID_MSD);
+    if (msdModule != 0) {
+        for (size_t i = 0; i < mAudioPatches.size(); ++i) {
+            sp<AudioPatch> patch = mAudioPatches.valueAt(i);
+            for (size_t j = 0; j < patch->mPatch.num_sources; ++j) {
+                const struct audio_port_config *source = &patch->mPatch.sources[j];
+                if (source->type == AUDIO_PORT_TYPE_DEVICE &&
+                        source->ext.device.hw_module == msdModule->getHandle()) {
+                    msdPatches.addAudioPatch(patch->mHandle, patch);
                 }
-                if (AudioPort::isBetterFormatMatch(
-                        outputDesc->mFormat, bestFormat, format)) {
-                    outputForFormat = output;
-                    bestFormat = outputDesc->mFormat;
-                }
-            }
-
-            int commonFlags = popcount(outputDesc->mProfile->getFlags() & flags);
-            if (commonFlags >= maxCommonFlags) {
-                if (commonFlags == maxCommonFlags) {
-                    if (format != AUDIO_FORMAT_INVALID
-                            && AudioPort::isBetterFormatMatch(
-                                    outputDesc->mFormat, bestFormatForFlags, format)) {
-                        outputForFlags = output;
-                        bestFormatForFlags = outputDesc->mFormat;
-                    }
-                } else {
-                    outputForFlags = output;
-                    maxCommonFlags = commonFlags;
-                    bestFormatForFlags = outputDesc->mFormat;
-                }
-                ALOGV("selectOutput() commonFlags for output %d, %04x", output, commonFlags);
-            }
-            if (outputDesc->mProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
-                outputForPrimary = output;
             }
         }
     }
-
-    if (outputForFlags != AUDIO_IO_HANDLE_NONE) {
-        return outputForFlags;
-    }
-    if (outputForFormat != AUDIO_IO_HANDLE_NONE) {
-        return outputForFormat;
-    }
-    if (outputForPrimary != AUDIO_IO_HANDLE_NONE) {
-        return outputForPrimary;
-    }
-
-    return outputs[0];
+    return msdPatches;
 }
 
-status_t AudioPolicyManager::startOutput(audio_io_handle_t output,
-                                             audio_stream_type_t stream,
-                                             audio_session_t session)
+status_t AudioPolicyManager::getBestMsdAudioProfileFor(const sp<DeviceDescriptor> &outputDevice,
+        bool hwAvSync, audio_port_config *sourceConfig, audio_port_config *sinkConfig) const
 {
-    ALOGV("startOutput() output %d, stream %d, session %d",
-          output, stream, session);
-    ssize_t index = mOutputs.indexOfKey(output);
-    if (index < 0) {
-        ALOGW("startOutput() unknown output %d", output);
-        return BAD_VALUE;
+    sp<HwModule> msdModule = mHwModules.getModuleFromName(AUDIO_HARDWARE_MODULE_ID_MSD);
+    if (msdModule == nullptr) {
+        ALOGE("%s() unable to get MSD module", __func__);
+        return NO_INIT;
+    }
+    sp<HwModule> deviceModule = mHwModules.getModuleForDevice(outputDevice, AUDIO_FORMAT_DEFAULT);
+    if (deviceModule == nullptr) {
+        ALOGE("%s() unable to get module for %s", __func__, outputDevice->toString().c_str());
+        return NO_INIT;
+    }
+    const InputProfileCollection &inputProfiles = msdModule->getInputProfiles();
+    if (inputProfiles.isEmpty()) {
+        ALOGE("%s() no input profiles for MSD module", __func__);
+        return NO_INIT;
+    }
+    const OutputProfileCollection &outputProfiles = deviceModule->getOutputProfiles();
+    if (outputProfiles.isEmpty()) {
+        ALOGE("%s() no output profiles for device %s", __func__, outputDevice->toString().c_str());
+        return NO_INIT;
+    }
+    AudioProfileVector msdProfiles;
+    // Each IOProfile represents a MixPort from audio_policy_configuration.xml
+    for (const auto &inProfile : inputProfiles) {
+        if (hwAvSync == ((inProfile->getFlags() & AUDIO_INPUT_FLAG_HW_AV_SYNC) != 0)) {
+            msdProfiles.appendVector(inProfile->getAudioProfiles());
+        }
+    }
+    AudioProfileVector deviceProfiles;
+    for (const auto &outProfile : outputProfiles) {
+        if (hwAvSync == ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0)) {
+            deviceProfiles.appendVector(outProfile->getAudioProfiles());
+        }
+    }
+    struct audio_config_base bestSinkConfig;
+    status_t result = msdProfiles.findBestMatchingOutputConfig(deviceProfiles,
+            compressedFormatsOrder, surroundChannelMasksOrder, true /*preferHigherSamplingRates*/,
+            &bestSinkConfig);
+    if (result != NO_ERROR) {
+        ALOGD("%s() no matching profiles found for device: %s, hwAvSync: %d",
+                __func__, outputDevice->toString().c_str(), hwAvSync);
+        return result;
+    }
+    sinkConfig->sample_rate = bestSinkConfig.sample_rate;
+    sinkConfig->channel_mask = bestSinkConfig.channel_mask;
+    sinkConfig->format = bestSinkConfig.format;
+    // For encoded streams force direct flag to prevent downstream mixing.
+    sinkConfig->flags.output = static_cast<audio_output_flags_t>(
+            sinkConfig->flags.output | AUDIO_OUTPUT_FLAG_DIRECT);
+    sourceConfig->sample_rate = bestSinkConfig.sample_rate;
+    // Specify exact channel mask to prevent guessing by bit count in PatchPanel.
+    sourceConfig->channel_mask = audio_channel_mask_out_to_in(bestSinkConfig.channel_mask);
+    sourceConfig->format = bestSinkConfig.format;
+    // Copy input stream directly without any processing (e.g. resampling).
+    sourceConfig->flags.input = static_cast<audio_input_flags_t>(
+            sourceConfig->flags.input | AUDIO_INPUT_FLAG_DIRECT);
+    if (hwAvSync) {
+        sinkConfig->flags.output = static_cast<audio_output_flags_t>(
+                sinkConfig->flags.output | AUDIO_OUTPUT_FLAG_HW_AV_SYNC);
+        sourceConfig->flags.input = static_cast<audio_input_flags_t>(
+                sourceConfig->flags.input | AUDIO_INPUT_FLAG_HW_AV_SYNC);
+    }
+    const unsigned int config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE |
+            AUDIO_PORT_CONFIG_CHANNEL_MASK | AUDIO_PORT_CONFIG_FORMAT | AUDIO_PORT_CONFIG_FLAGS;
+    sinkConfig->config_mask |= config_mask;
+    sourceConfig->config_mask |= config_mask;
+    return NO_ERROR;
+}
+
+PatchBuilder AudioPolicyManager::buildMsdPatch(const sp<DeviceDescriptor> &outputDevice) const
+{
+    PatchBuilder patchBuilder;
+    patchBuilder.addSource(getMsdAudioInDevice()).addSink(outputDevice);
+    audio_port_config sourceConfig = patchBuilder.patch()->sources[0];
+    audio_port_config sinkConfig = patchBuilder.patch()->sinks[0];
+    // TODO: Figure out whether MSD module has HW_AV_SYNC flag set in the AP config file.
+    // For now, we just forcefully try with HwAvSync first.
+    status_t res = getBestMsdAudioProfileFor(outputDevice, true /*hwAvSync*/,
+            &sourceConfig, &sinkConfig) == NO_ERROR ? NO_ERROR :
+            getBestMsdAudioProfileFor(
+                    outputDevice, false /*hwAvSync*/, &sourceConfig, &sinkConfig);
+    if (res == NO_ERROR) {
+        // Found a matching profile for encoded audio. Re-create PatchBuilder with this config.
+        return (PatchBuilder()).addSource(sourceConfig).addSink(sinkConfig);
+    }
+    ALOGV("%s() no matching profile found. Fall through to default PCM patch"
+            " supporting PCM format conversion.", __func__);
+    return patchBuilder;
+}
+
+status_t AudioPolicyManager::setMsdPatch(const sp<DeviceDescriptor> &outputDevice) {
+    sp<DeviceDescriptor> device = outputDevice;
+    if (device == nullptr) {
+        // Use media strategy for unspecified output device. This should only
+        // occur on checkForDeviceAndOutputChanges(). Device connection events may
+        // therefore invalidate explicit routing requests.
+        DeviceVector devices = mEngine->getOutputDevicesForAttributes(
+                    attributes_initializer(AUDIO_USAGE_MEDIA), nullptr, false /*fromCache*/);
+        LOG_ALWAYS_FATAL_IF(devices.isEmpty(), "no outpudevice to set Msd Patch");
+        device = devices.itemAt(0);
+    }
+    ALOGV("%s() for device %s", __func__, device->toString().c_str());
+    PatchBuilder patchBuilder = buildMsdPatch(device);
+    const struct audio_patch* patch = patchBuilder.patch();
+    const AudioPatchCollection msdPatches = getMsdPatches();
+    if (!msdPatches.isEmpty()) {
+        LOG_ALWAYS_FATAL_IF(msdPatches.size() > 1,
+                "The current MSD prototype only supports one output patch");
+        sp<AudioPatch> currentPatch = msdPatches.valueAt(0);
+        if (audio_patches_are_equal(&currentPatch->mPatch, patch)) {
+            return NO_ERROR;
+        }
+        releaseAudioPatch(currentPatch->mHandle, mUidCached);
+    }
+    status_t status = installPatch(__func__, -1 /*index*/, nullptr /*patchHandle*/,
+            patch, 0 /*delayMs*/, mUidCached, nullptr /*patchDescPtr*/);
+    ALOGE_IF(status != NO_ERROR, "%s() error %d creating MSD audio patch", __func__, status);
+    ALOGI_IF(status == NO_ERROR, "%s() Patch created from MSD_IN to "
+           "device:%s (format:%#x channels:%#x samplerate:%d)", __func__,
+             device->toString().c_str(), patch->sources[0].format,
+             patch->sources[0].channel_mask, patch->sources[0].sample_rate);
+    return status;
+}
+
+audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_handle_t>& outputs,
+                                                       audio_output_flags_t flags,
+                                                       audio_format_t format,
+                                                       audio_channel_mask_t channelMask,
+                                                       uint32_t samplingRate)
+{
+    LOG_ALWAYS_FATAL_IF(!(format == AUDIO_FORMAT_INVALID || audio_is_linear_pcm(format)),
+        "%s called with format %#x", __func__, format);
+
+    // Flags disqualifying an output: the match must happen before calling selectOutput()
+    static const audio_output_flags_t kExcludedFlags = (audio_output_flags_t)
+        (AUDIO_OUTPUT_FLAG_HW_AV_SYNC | AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT);
+
+    // Flags expressing a functional request: must be honored in priority over
+    // other criteria
+    static const audio_output_flags_t kFunctionalFlags = (audio_output_flags_t)
+        (AUDIO_OUTPUT_FLAG_VOIP_RX | AUDIO_OUTPUT_FLAG_INCALL_MUSIC |
+            AUDIO_OUTPUT_FLAG_TTS | AUDIO_OUTPUT_FLAG_DIRECT_PCM);
+    // Flags expressing a performance request: have lower priority than serving
+    // requested sampling rate or channel mask
+    static const audio_output_flags_t kPerformanceFlags = (audio_output_flags_t)
+        (AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_DEEP_BUFFER |
+            AUDIO_OUTPUT_FLAG_RAW | AUDIO_OUTPUT_FLAG_SYNC);
+
+    const audio_output_flags_t functionalFlags =
+        (audio_output_flags_t)(flags & kFunctionalFlags);
+    const audio_output_flags_t performanceFlags =
+        (audio_output_flags_t)(flags & kPerformanceFlags);
+
+    audio_io_handle_t bestOutput = (outputs.size() == 0) ? AUDIO_IO_HANDLE_NONE : outputs[0];
+
+    // select one output among several that provide a path to a particular device or set of
+    // devices (the list was previously build by getOutputsForDevices()).
+    // The priority is as follows:
+    // 1: the output supporting haptic playback when requesting haptic playback
+    // 2: the output with the highest number of requested functional flags
+    // 3: the output supporting the exact channel mask
+    // 4: the output with a higher channel count than requested
+    // 5: the output with a higher sampling rate than requested
+    // 6: the output with the highest number of requested performance flags
+    // 7: the output with the bit depth the closest to the requested one
+    // 8: the primary output
+    // 9: the first output in the list
+
+    // matching criteria values in priority order for best matching output so far
+    std::vector<uint32_t> bestMatchCriteria(8, 0);
+
+    const uint32_t channelCount = audio_channel_count_from_out_mask(channelMask);
+    const uint32_t hapticChannelCount = audio_channel_count_from_out_mask(
+        channelMask & AUDIO_CHANNEL_HAPTIC_ALL);
+
+    for (audio_io_handle_t output : outputs) {
+        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
+        // matching criteria values in priority order for current output
+        std::vector<uint32_t> currentMatchCriteria(8, 0);
+
+        if (outputDesc->isDuplicated()) {
+            continue;
+        }
+        if ((kExcludedFlags & outputDesc->mFlags) != 0) {
+            continue;
+        }
+
+        // If haptic channel is specified, use the haptic output if present.
+        // When using haptic output, same audio format and sample rate are required.
+        const uint32_t outputHapticChannelCount = audio_channel_count_from_out_mask(
+            outputDesc->mChannelMask & AUDIO_CHANNEL_HAPTIC_ALL);
+        if ((hapticChannelCount == 0) != (outputHapticChannelCount == 0)) {
+            continue;
+        }
+        if (outputHapticChannelCount >= hapticChannelCount
+            && format == outputDesc->mFormat
+            && samplingRate == outputDesc->mSamplingRate) {
+                currentMatchCriteria[0] = outputHapticChannelCount;
+        }
+
+        // functional flags match
+        currentMatchCriteria[1] = popcount(outputDesc->mFlags & functionalFlags);
+
+        // channel mask and channel count match
+        uint32_t outputChannelCount = audio_channel_count_from_out_mask(outputDesc->mChannelMask);
+        if (channelMask != AUDIO_CHANNEL_NONE && channelCount > 2 &&
+            channelCount <= outputChannelCount) {
+            if ((audio_channel_mask_get_representation(channelMask) ==
+                    audio_channel_mask_get_representation(outputDesc->mChannelMask)) &&
+                    ((channelMask & outputDesc->mChannelMask) == channelMask)) {
+                currentMatchCriteria[2] = outputChannelCount;
+            }
+            currentMatchCriteria[3] = outputChannelCount;
+        }
+
+        // sampling rate match
+        if (samplingRate > SAMPLE_RATE_HZ_DEFAULT &&
+                samplingRate <= outputDesc->mSamplingRate) {
+            currentMatchCriteria[4] = outputDesc->mSamplingRate;
+        }
+
+        // performance flags match
+        currentMatchCriteria[5] = popcount(outputDesc->mFlags & performanceFlags);
+
+        // format match
+        if (format != AUDIO_FORMAT_INVALID) {
+            currentMatchCriteria[6] =
+                AudioPort::kFormatDistanceMax -
+                AudioPort::formatDistance(format, outputDesc->mFormat);
+        }
+
+        // primary output match
+        currentMatchCriteria[7] = outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY;
+
+        // compare match criteria by priority then value
+        if (std::lexicographical_compare(bestMatchCriteria.begin(), bestMatchCriteria.end(),
+                currentMatchCriteria.begin(), currentMatchCriteria.end())) {
+            bestMatchCriteria = currentMatchCriteria;
+            bestOutput = output;
+
+            std::stringstream result;
+            std::copy(bestMatchCriteria.begin(), bestMatchCriteria.end(),
+                std::ostream_iterator<int>(result, " "));
+            ALOGV("%s new bestOutput %d criteria %s",
+                __func__, bestOutput, result.str().c_str());
+        }
     }
 
-    sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
+    return bestOutput;
+}
+
+status_t AudioPolicyManager::startOutput(audio_port_handle_t portId)
+{
+    ALOGV("%s portId %d", __FUNCTION__, portId);
+
+    sp<SwAudioOutputDescriptor> outputDesc = mOutputs.getOutputForClient(portId);
+    if (outputDesc == 0) {
+        ALOGW("startOutput() no output for client %d", portId);
+        return BAD_VALUE;
+    }
+    sp<TrackClientDescriptor> client = outputDesc->getClient(portId);
+
+    ALOGV("startOutput() output %d, stream %d, session %d",
+          outputDesc->mIoHandle, client->stream(), client->session());
 
     status_t status = outputDesc->start();
     if (status != NO_ERROR) {
         return status;
     }
 
-    // Routing?
-    mOutputRoutes.incRouteActivity(session);
-
-    audio_devices_t newDevice;
-    sp<AudioPolicyMix> policyMix = outputDesc->mPolicyMix.promote();
-    const char *address = NULL;
-    if (policyMix != NULL) {
-        address = policyMix->mDeviceAddress.string();
-        if ((policyMix->mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
-            newDevice = policyMix->mDeviceType;
-        } else {
-            newDevice = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
-        }
-    } else if (mOutputRoutes.getAndClearRouteChanged(session)) {
-        newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
-        if (newDevice != outputDesc->device()) {
-            checkStrategyRoute(getStrategy(stream), output);
-        }
-    } else {
-        newDevice = AUDIO_DEVICE_NONE;
-    }
-
-    uint32_t delayMs = 0;
-
-    status = startSource(outputDesc, stream, newDevice, address, &delayMs);
+    uint32_t delayMs;
+    status = startSource(outputDesc, client, &delayMs);
 
     if (status != NO_ERROR) {
-        mOutputRoutes.decRouteActivity(session);
         outputDesc->stop();
         return status;
     }
-    // Automatically enable the remote submix input when output is started on a re routing mix
-    // of type MIX_TYPE_RECORDERS
-    if (audio_is_remote_submix_device(newDevice) && policyMix != NULL &&
-            policyMix->mMixType == MIX_TYPE_RECORDERS) {
-            setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
-                    AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
-                    address,
-                    "remote-submix");
-    }
-
     if (delayMs != 0) {
         usleep(delayMs * 1000);
     }
@@ -1199,19 +1597,22 @@
     return status;
 }
 
-status_t AudioPolicyManager::startSource(const sp<AudioOutputDescriptor>& outputDesc,
-                                             audio_stream_type_t stream,
-                                             audio_devices_t device,
-                                             const char *address,
-                                             uint32_t *delayMs)
+status_t AudioPolicyManager::startSource(const sp<SwAudioOutputDescriptor>& outputDesc,
+                                         const sp<TrackClientDescriptor>& client,
+                                         uint32_t *delayMs)
 {
     // cannot start playback of STREAM_TTS if any other output is being used
     uint32_t beaconMuteLatency = 0;
 
     *delayMs = 0;
+    audio_stream_type_t stream = client->stream();
+    auto clientVolSrc = client->volumeSource();
+    auto clientStrategy = client->strategy();
+    auto clientAttr = client->attributes();
     if (stream == AUDIO_STREAM_TTS) {
         ALOGV("\t found BEACON stream");
-        if (!mTtsOutputAvailable && mOutputs.isAnyOutputActive(AUDIO_STREAM_TTS /*streamToIgnore*/)) {
+        if (!mTtsOutputAvailable && mOutputs.isAnyOutputActive(
+                                    toVolumeSource(AUDIO_STREAM_TTS) /*sourceToIgnore*/)) {
             return INVALID_OPERATION;
         } else {
             beaconMuteLatency = handleEventForBeacon(STARTING_BEACON);
@@ -1226,6 +1627,23 @@
     bool force = !outputDesc->isActive() &&
             (outputDesc->getPatchHandle() == AUDIO_PATCH_HANDLE_NONE);
 
+    DeviceVector devices;
+    sp<AudioPolicyMix> policyMix = outputDesc->mPolicyMix.promote();
+    const char *address = NULL;
+    if (policyMix != NULL) {
+        audio_devices_t newDeviceType;
+        address = policyMix->mDeviceAddress.string();
+        if ((policyMix->mRouteFlags & MIX_ROUTE_FLAG_LOOP_BACK) == MIX_ROUTE_FLAG_LOOP_BACK) {
+            newDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
+        } else {
+            newDeviceType = policyMix->mDeviceType;
+        }
+        sp device = mAvailableOutputDevices.getDevice(newDeviceType, String8(address),
+                                                        AUDIO_FORMAT_DEFAULT);
+        ALOG_ASSERT(device, "%s: no device found t=%u, a=%s", __func__, newDeviceType, address);
+        devices.add(device);
+    }
+
     // requiresMuteCheck is false when we can bypass mute strategy.
     // It covers a common case when there is no materially active audio
     // and muting would result in unnecessary delay and dropped audio.
@@ -1235,31 +1653,44 @@
     // increment usage count for this stream on the requested output:
     // NOTE that the usage count is the same for duplicated output and hardware output which is
     // necessary for a correct control of hardware output routing by startOutput() and stopOutput()
-    outputDesc->changeRefCount(stream, 1);
+    outputDesc->setClientActive(client, true);
 
-    if (stream == AUDIO_STREAM_MUSIC) {
+    if (client->hasPreferredDevice(true)) {
+        if (outputDesc->clientsList(true /*activeOnly*/).size() == 1 &&
+                client->isPreferredDeviceForExclusiveUse()) {
+            // Preferred device may be exclusive, use only if no other active clients on this output
+            devices = DeviceVector(
+                        mAvailableOutputDevices.getDeviceFromId(client->preferredDeviceId()));
+        } else {
+            devices = getNewOutputDevices(outputDesc, false /*fromCache*/);
+        }
+        if (devices != outputDesc->devices()) {
+            checkStrategyRoute(clientStrategy, outputDesc->mIoHandle);
+        }
+    }
+
+    if (followsSameRouting(clientAttr, attributes_initializer(AUDIO_USAGE_MEDIA))) {
         selectOutputForMusicEffects();
     }
 
-    if (outputDesc->mRefCount[stream] == 1 || device != AUDIO_DEVICE_NONE) {
+    if (outputDesc->getActivityCount(clientVolSrc) == 1 || !devices.isEmpty()) {
         // starting an output being rerouted?
-        if (device == AUDIO_DEVICE_NONE) {
-            device = getNewOutputDevice(outputDesc, false /*fromCache*/);
+        if (devices.isEmpty()) {
+            devices = getNewOutputDevices(outputDesc, false /*fromCache*/);
         }
-
-        routing_strategy strategy = getStrategy(stream);
-        bool shouldWait = (strategy == STRATEGY_SONIFICATION) ||
-                            (strategy == STRATEGY_SONIFICATION_RESPECTFUL) ||
-                            (beaconMuteLatency > 0);
+        bool shouldWait =
+            (followsSameRouting(clientAttr, attributes_initializer(AUDIO_USAGE_ALARM)) ||
+             followsSameRouting(clientAttr, attributes_initializer(AUDIO_USAGE_NOTIFICATION)) ||
+             (beaconMuteLatency > 0));
         uint32_t waitMs = beaconMuteLatency;
         for (size_t i = 0; i < mOutputs.size(); i++) {
-            sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
+            sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
             if (desc != outputDesc) {
                 // An output has a shared device if
                 // - managed by the same hw module
                 // - supports the currently selected device
                 const bool sharedDevice = outputDesc->sharesHwModuleWith(desc)
-                        && (desc->supportedDevices() & device) != AUDIO_DEVICE_NONE;
+                        && (!desc->filterSupportedDevices(devices).isEmpty());
 
                 // force a device change if any other output is:
                 // - managed by the same hw module
@@ -1269,7 +1700,7 @@
                 // In this case, the audio HAL must receive the new device selection so that it can
                 // change the device currently selected by the other output.
                 if (sharedDevice &&
-                        desc->device() != device &&
+                        desc->devices() != devices &&
                         desc->getPatchHandle() != AUDIO_PATCH_HANDLE_NONE) {
                     force = true;
                 }
@@ -1292,25 +1723,21 @@
         }
 
         const uint32_t muteWaitMs =
-                setOutputDevice(outputDesc, device, force, 0, NULL, address, requiresMuteCheck);
-
-        // handle special case for sonification while in call
-        if (isInCall()) {
-            handleIncallSonification(stream, true, false);
-        }
+                setOutputDevices(outputDesc, devices, force, 0, NULL, requiresMuteCheck);
 
         // apply volume rules for current stream and device if necessary
-        checkAndSetVolume(stream,
-                          mVolumeCurves->getVolumeIndex(stream, outputDesc->device()),
+        auto &curves = getVolumeCurves(client->attributes());
+        checkAndSetVolume(curves, client->volumeSource(),
+                          curves.getVolumeIndex(outputDesc->devices().types()),
                           outputDesc,
-                          outputDesc->device());
+                          outputDesc->devices().types());
 
         // update the outputs if starting an output with a stream that can affect notification
         // routing
         handleNotificationRoutingForStream(stream);
 
         // force reevaluating accessibility routing when ringtone or alarm starts
-        if (strategy == STRATEGY_SONIFICATION) {
+        if (followsSameRouting(clientAttr, attributes_initializer(AUDIO_USAGE_ALARM))) {
             mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
         }
 
@@ -1329,52 +1756,38 @@
 
     if (stream == AUDIO_STREAM_ENFORCED_AUDIBLE &&
             mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
-        setStrategyMute(STRATEGY_SONIFICATION, true, outputDesc);
+        setStrategyMute(streamToStrategy(AUDIO_STREAM_ALARM), true, outputDesc);
+    }
+
+    // Automatically enable the remote submix input when output is started on a re routing mix
+    // of type MIX_TYPE_RECORDERS
+    if (audio_is_remote_submix_device(devices.types()) && policyMix != NULL &&
+        policyMix->mMixType == MIX_TYPE_RECORDERS) {
+        setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
+                                    AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
+                                    address,
+                                    "remote-submix",
+                                    AUDIO_FORMAT_DEFAULT);
     }
 
     return NO_ERROR;
 }
 
-
-status_t AudioPolicyManager::stopOutput(audio_io_handle_t output,
-                                            audio_stream_type_t stream,
-                                            audio_session_t session)
+status_t AudioPolicyManager::stopOutput(audio_port_handle_t portId)
 {
-    ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session);
-    ssize_t index = mOutputs.indexOfKey(output);
-    if (index < 0) {
-        ALOGW("stopOutput() unknown output %d", output);
+    ALOGV("%s portId %d", __FUNCTION__, portId);
+
+    sp<SwAudioOutputDescriptor> outputDesc = mOutputs.getOutputForClient(portId);
+    if (outputDesc == 0) {
+        ALOGW("stopOutput() no output for client %d", portId);
         return BAD_VALUE;
     }
+    sp<TrackClientDescriptor> client = outputDesc->getClient(portId);
 
-    sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
+    ALOGV("stopOutput() output %d, stream %d, session %d",
+          outputDesc->mIoHandle, client->stream(), client->session());
 
-    if (outputDesc->mRefCount[stream] == 1) {
-        // Automatically disable the remote submix input when output is stopped on a
-        // re routing mix of type MIX_TYPE_RECORDERS
-        sp<AudioPolicyMix> policyMix = outputDesc->mPolicyMix.promote();
-        if (audio_is_remote_submix_device(outputDesc->mDevice) &&
-                policyMix != NULL &&
-                policyMix->mMixType == MIX_TYPE_RECORDERS) {
-            setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
-                    AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
-                    policyMix->mDeviceAddress,
-                    "remote-submix");
-        }
-    }
-
-    // Routing?
-    bool forceDeviceUpdate = false;
-    if (outputDesc->mRefCount[stream] > 0) {
-        int activityCount = mOutputRoutes.decRouteActivity(session);
-        forceDeviceUpdate = (mOutputRoutes.hasRoute(session) && (activityCount == 0));
-
-        if (forceDeviceUpdate) {
-            checkStrategyRoute(getStrategy(stream), AUDIO_IO_HANDLE_NONE);
-        }
-    }
-
-    status_t status = stopSource(outputDesc, stream, forceDeviceUpdate);
+    status_t status = stopSource(outputDesc, client);
 
     if (status == NO_ERROR ) {
         outputDesc->stop();
@@ -1382,52 +1795,66 @@
     return status;
 }
 
-status_t AudioPolicyManager::stopSource(const sp<AudioOutputDescriptor>& outputDesc,
-                                            audio_stream_type_t stream,
-                                            bool forceDeviceUpdate)
+status_t AudioPolicyManager::stopSource(const sp<SwAudioOutputDescriptor>& outputDesc,
+                                        const sp<TrackClientDescriptor>& client)
 {
     // always handle stream stop, check which stream type is stopping
+    audio_stream_type_t stream = client->stream();
+    auto clientVolSrc = client->volumeSource();
+
     handleEventForBeacon(stream == AUDIO_STREAM_TTS ? STOPPING_BEACON : STOPPING_OUTPUT);
 
-    // handle special case for sonification while in call
-    if (isInCall()) {
-        handleIncallSonification(stream, false, false);
-    }
+    if (outputDesc->getActivityCount(clientVolSrc) > 0) {
+        if (outputDesc->getActivityCount(clientVolSrc) == 1) {
+            // Automatically disable the remote submix input when output is stopped on a
+            // re routing mix of type MIX_TYPE_RECORDERS
+            sp<AudioPolicyMix> policyMix = outputDesc->mPolicyMix.promote();
+            if (audio_is_remote_submix_device(outputDesc->devices().types()) &&
+                policyMix != NULL &&
+                policyMix->mMixType == MIX_TYPE_RECORDERS) {
+                setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
+                                            AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
+                                            policyMix->mDeviceAddress,
+                                            "remote-submix", AUDIO_FORMAT_DEFAULT);
+            }
+        }
+        bool forceDeviceUpdate = false;
+        if (client->hasPreferredDevice(true)) {
+            checkStrategyRoute(client->strategy(), AUDIO_IO_HANDLE_NONE);
+            forceDeviceUpdate = true;
+        }
 
-    if (outputDesc->mRefCount[stream] > 0) {
         // decrement usage count of this stream on the output
-        outputDesc->changeRefCount(stream, -1);
+        outputDesc->setClientActive(client, false);
 
         // store time at which the stream was stopped - see isStreamActive()
-        if (outputDesc->mRefCount[stream] == 0 || forceDeviceUpdate) {
-            outputDesc->mStopTime[stream] = systemTime();
-            audio_devices_t newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
+        if (outputDesc->getActivityCount(clientVolSrc) == 0 || forceDeviceUpdate) {
+            outputDesc->setStopTime(client, systemTime());
+            DeviceVector newDevices = getNewOutputDevices(outputDesc, false /*fromCache*/);
             // delay the device switch by twice the latency because stopOutput() is executed when
             // the track stop() command is received and at that time the audio track buffer can
             // still contain data that needs to be drained. The latency only covers the audio HAL
             // and kernel buffers. Also the latency does not always include additional delay in the
             // audio path (audio DSP, CODEC ...)
-            setOutputDevice(outputDesc, newDevice, false, outputDesc->latency()*2);
+            setOutputDevices(outputDesc, newDevices, false, outputDesc->latency()*2);
 
             // force restoring the device selection on other active outputs if it differs from the
             // one being selected for this output
             uint32_t delayMs = outputDesc->latency()*2;
             for (size_t i = 0; i < mOutputs.size(); i++) {
-                sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
+                sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
                 if (desc != outputDesc &&
                         desc->isActive() &&
                         outputDesc->sharesHwModuleWith(desc) &&
-                        (newDevice != desc->device())) {
-                    audio_devices_t newDevice2 = getNewOutputDevice(desc, false /*fromCache*/);
-                    bool force = desc->device() != newDevice2;
+                        (newDevices != desc->devices())) {
+                    DeviceVector newDevices2 = getNewOutputDevices(desc, false /*fromCache*/);
+                    bool force = desc->devices() != newDevices2;
 
-                    setOutputDevice(desc,
-                                    newDevice2,
-                                    force,
-                                    delayMs);
+                    setOutputDevices(desc, newDevices2, force, delayMs);
+
                     // re-apply device specific volume if not done by setOutputDevice()
                     if (!force) {
-                        applyStreamVolumes(desc, newDevice2, delayMs);
+                        applyStreamVolumes(desc, newDevices2.types(), delayMs);
                     }
                 }
             }
@@ -1437,10 +1864,10 @@
 
         if (stream == AUDIO_STREAM_ENFORCED_AUDIBLE &&
                 mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
-            setStrategyMute(STRATEGY_SONIFICATION, false, outputDesc);
+            setStrategyMute(streamToStrategy(AUDIO_STREAM_ALARM), false, outputDesc);
         }
 
-        if (stream == AUDIO_STREAM_MUSIC) {
+        if (followsSameRouting(client->attributes(), attributes_initializer(AUDIO_USAGE_MEDIA))) {
             selectOutputForMusicEffects();
         }
         return NO_ERROR;
@@ -1450,37 +1877,44 @@
     }
 }
 
-void AudioPolicyManager::releaseOutput(audio_io_handle_t output,
-                                       audio_stream_type_t stream __unused,
-                                       audio_session_t session __unused)
+void AudioPolicyManager::releaseOutput(audio_port_handle_t portId)
 {
-    ALOGV("releaseOutput() %d", output);
-    ssize_t index = mOutputs.indexOfKey(output);
-    if (index < 0) {
-        ALOGW("releaseOutput() releasing unknown output %d", output);
+    ALOGV("%s portId %d", __FUNCTION__, portId);
+
+    sp<SwAudioOutputDescriptor> outputDesc = mOutputs.getOutputForClient(portId);
+    if (outputDesc == 0) {
+        // If an output descriptor is closed due to a device routing change,
+        // then there are race conditions with releaseOutput from tracks
+        // that may be destroyed (with no PlaybackThread) or a PlaybackThread
+        // destroyed shortly thereafter.
+        //
+        // Here we just log a warning, instead of a fatal error.
+        ALOGW("releaseOutput() no output for client %d", portId);
         return;
     }
 
-    // Routing
-    mOutputRoutes.removeRoute(session);
+    ALOGV("releaseOutput() %d", outputDesc->mIoHandle);
 
-    sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(index);
-    if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
-        if (desc->mDirectOpenCount <= 0) {
+    if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
+        if (outputDesc->mDirectOpenCount <= 0) {
             ALOGW("releaseOutput() invalid open count %d for output %d",
-                                                              desc->mDirectOpenCount, output);
+                  outputDesc->mDirectOpenCount, outputDesc->mIoHandle);
             return;
         }
-        if (--desc->mDirectOpenCount == 0) {
-            closeOutput(output);
+        if (--outputDesc->mDirectOpenCount == 0) {
+            closeOutput(outputDesc->mIoHandle);
             mpClientInterface->onAudioPortListUpdate();
         }
     }
+    // stopOutput() needs to be successfully called before releaseOutput()
+    // otherwise there may be inaccurate stream reference counts.
+    // This is checked in outputDesc->removeClient below.
+    outputDesc->removeClient(portId);
 }
 
-
 status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
                                              audio_io_handle_t *input,
+                                             audio_unique_id_t riid,
                                              audio_session_t session,
                                              uid_t uid,
                                              const audio_config_base_t *config,
@@ -1489,28 +1923,32 @@
                                              input_type_t *inputType,
                                              audio_port_handle_t *portId)
 {
-    ALOGV("getInputForAttr() source %d, sampling rate %d, format %#x, channel mask %#x,"
-            "session %d, flags %#x",
-          attr->source, config->sample_rate, config->format, config->channel_mask, session, flags);
+    ALOGV("%s() source %d, sampling rate %d, format %#x, channel mask %#x, session %d, "
+          "flags %#x attributes=%s", __func__, attr->source, config->sample_rate,
+          config->format, config->channel_mask, session, flags, toString(*attr).c_str());
 
     status_t status = NO_ERROR;
-    // handle legacy remote submix case where the address was not always specified
-    String8 address = String8("");
     audio_source_t halInputSource;
-    audio_source_t inputSource = attr->source;
+    audio_attributes_t attributes = *attr;
     sp<AudioPolicyMix> policyMix;
-    DeviceVector inputDevices;
+    sp<DeviceDescriptor> device;
+    sp<AudioInputDescriptor> inputDesc;
+    sp<RecordClientDescriptor> clientDesc;
+    audio_port_handle_t requestedDeviceId = *selectedDeviceId;
+    bool isSoundTrigger;
 
-    if (inputSource == AUDIO_SOURCE_DEFAULT) {
-        inputSource = AUDIO_SOURCE_MIC;
+    // The supplied portId must be AUDIO_PORT_HANDLE_NONE
+    if (*portId != AUDIO_PORT_HANDLE_NONE) {
+        return INVALID_OPERATION;
+    }
+
+    if (attr->source == AUDIO_SOURCE_DEFAULT) {
+        attributes.source = AUDIO_SOURCE_MIC;
     }
 
     // Explicit routing?
-    sp<DeviceDescriptor> deviceDesc;
-    if (*selectedDeviceId != AUDIO_PORT_HANDLE_NONE) {
-        deviceDesc = mAvailableInputDevices.getDeviceFromId(*selectedDeviceId);
-    }
-    mInputRoutes.addRoute(session, SessionRoute::STREAM_TYPE_NA, inputSource, deviceDesc, uid);
+    sp<DeviceDescriptor> explicitRoutingDevice = 
+            mAvailableInputDevices.getDeviceFromId(*selectedDeviceId);
 
     // special case for mmap capture: if an input IO handle is specified, we reuse this input if
     // possible
@@ -1523,8 +1961,8 @@
             goto error;
         }
         sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
-        sp<AudioSession> audioSession = inputDesc->getAudioSession(session);
-        if (audioSession == 0) {
+        RecordClientVector clients = inputDesc->getClientsForSession(session);
+        if (clients.size() == 0) {
             ALOGW("getInputForAttr() unknown session %d on input %d", session, *input);
             status = BAD_VALUE;
             goto error;
@@ -1533,75 +1971,80 @@
         // The second call is for the first active client and sets the UID. Any further call
         // corresponds to a new client and is only permitted from the same UID.
         // If the first UID is silenced, allow a new UID connection and replace with new UID
-        if (audioSession->openCount() == 1) {
-            audioSession->setUid(uid);
-        } else if (audioSession->uid() != uid) {
-            if (!audioSession->isSilenced()) {
-                ALOGW("getInputForAttr() bad uid %d for session %d uid %d",
-                      uid, session, audioSession->uid());
-                status = INVALID_OPERATION;
-                goto error;
+        if (clients.size() > 1) {
+            for (const auto& client : clients) {
+                // The client map is ordered by key values (portId) and portIds are allocated
+                // incrementaly. So the first client in this list is the one opened by audio flinger
+                // when the mmap stream is created and should be ignored as it does not correspond
+                // to an actual client
+                if (client == *clients.cbegin()) {
+                    continue;
+                }
+                if (uid != client->uid() && !client->isSilenced()) {
+                    ALOGW("getInputForAttr() bad uid %d for client %d uid %d",
+                          uid, client->portId(), client->uid());
+                    status = INVALID_OPERATION;
+                    goto error;
+                }
             }
-            audioSession->setUid(uid);
-            audioSession->setSilenced(false);
         }
-        audioSession->changeOpenCount(1);
         *inputType = API_INPUT_LEGACY;
-        if (*portId == AUDIO_PORT_HANDLE_NONE) {
-            *portId = AudioPort::getNextUniqueId();
-        }
-        inputDevices = mAvailableInputDevices.getDevicesFromType(inputDesc->mDevice);
-        *selectedDeviceId = inputDevices.size() > 0 ? inputDevices.itemAt(0)->getId()
-                : AUDIO_PORT_HANDLE_NONE;
-        ALOGI("%s reusing MMAP input %d for session %d", __FUNCTION__, *input, session);
+        device = inputDesc->getDevice();
 
-        return NO_ERROR;
+        ALOGI("%s reusing MMAP input %d for session %d", __FUNCTION__, *input, session);
+        goto exit;
     }
 
     *input = AUDIO_IO_HANDLE_NONE;
     *inputType = API_INPUT_INVALID;
 
-    halInputSource = inputSource;
+    halInputSource = attributes.source;
 
-    // TODO: check for existing client for this port ID
-    if (*portId == AUDIO_PORT_HANDLE_NONE) {
-        *portId = AudioPort::getNextUniqueId();
-    }
-
-    audio_devices_t device;
-
-    if (inputSource == AUDIO_SOURCE_REMOTE_SUBMIX &&
-            strncmp(attr->tags, "addr=", strlen("addr=")) == 0) {
-        status = mPolicyMixes.getInputMixForAttr(*attr, &policyMix);
+    if (attributes.source == AUDIO_SOURCE_REMOTE_SUBMIX &&
+            strncmp(attributes.tags, "addr=", strlen("addr=")) == 0) {
+        status = mPolicyMixes.getInputMixForAttr(attributes, &policyMix);
         if (status != NO_ERROR) {
+            ALOGW("%s could not find input mix for attr %s",
+                    __func__, toString(attributes).c_str());
             goto error;
         }
-        *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE;
-        device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
-        address = String8(attr->tags + strlen("addr="));
-    } else {
-        device = getDeviceAndMixForInputSource(inputSource, &policyMix);
-        if (device == AUDIO_DEVICE_NONE) {
-            ALOGW("getInputForAttr() could not find device for source %d", inputSource);
+        device = mAvailableInputDevices.getDevice(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
+                                                  String8(attr->tags + strlen("addr=")),
+                                                  AUDIO_FORMAT_DEFAULT);
+        if (device == nullptr) {
+            ALOGW("%s could not find in Remote Submix device for source %d, tags %s",
+                    __func__, attributes.source, attributes.tags);
             status = BAD_VALUE;
             goto error;
         }
-        if (policyMix != NULL) {
-            address = policyMix->mDeviceAddress;
-            if (policyMix->mMixType == MIX_TYPE_RECORDERS) {
-                // there is an external policy, but this input is attached to a mix of recorders,
-                // meaning it receives audio injected into the framework, so the recorder doesn't
-                // know about it and is therefore considered "legacy"
-                *inputType = API_INPUT_LEGACY;
-            } else {
-                // recording a mix of players defined by an external policy, we're rerouting for
-                // an external policy
-                *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE;
-            }
-        } else if (audio_is_remote_submix_device(device)) {
-            address = String8("0");
+
+        if (is_mix_loopback_render(policyMix->mRouteFlags)) {
+            *inputType = API_INPUT_MIX_PUBLIC_CAPTURE_PLAYBACK;
+        } else {
+            *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE;
+        }
+    } else {
+        if (explicitRoutingDevice != nullptr) {
+            device = explicitRoutingDevice;
+        } else {
+            // Prevent from storing invalid requested device id in clients
+            requestedDeviceId = AUDIO_PORT_HANDLE_NONE;
+            device = mEngine->getInputDeviceForAttributes(attributes, &policyMix);
+        }
+        if (device == nullptr) {
+            ALOGW("getInputForAttr() could not find device for source %d", attributes.source);
+            status = BAD_VALUE;
+            goto error;
+        }
+        if (policyMix) {
+            ALOG_ASSERT(policyMix->mMixType == MIX_TYPE_RECORDERS, "Invalid Mix Type");
+            // there is an external policy, but this input is attached to a mix of recorders,
+            // meaning it receives audio injected into the framework, so the recorder doesn't
+            // know about it and is therefore considered "legacy"
+            *inputType = API_INPUT_LEGACY;
+        } else if (audio_is_remote_submix_device(device->type())) {
             *inputType = API_INPUT_MIX_CAPTURE;
-        } else if (device == AUDIO_DEVICE_IN_TELEPHONY_RX) {
+        } else if (device->type() == AUDIO_DEVICE_IN_TELEPHONY_RX) {
             *inputType = API_INPUT_TELEPHONY_RX;
         } else {
             *inputType = API_INPUT_LEGACY;
@@ -1609,43 +2052,49 @@
 
     }
 
-    *input = getInputForDevice(device, address, session, uid, inputSource,
-                               config, flags,
-                               policyMix);
+    *input = getInputForDevice(device, session, attributes, config, flags, policyMix);
     if (*input == AUDIO_IO_HANDLE_NONE) {
         status = INVALID_OPERATION;
         goto error;
     }
 
-    inputDevices = mAvailableInputDevices.getDevicesFromType(device);
-    *selectedDeviceId = inputDevices.size() > 0 ? inputDevices.itemAt(0)->getId()
-            : AUDIO_PORT_HANDLE_NONE;
+exit:
 
-    ALOGV("getInputForAttr() returns input %d type %d selectedDeviceId %d",
-            *input, *inputType, *selectedDeviceId);
+    *selectedDeviceId = mAvailableInputDevices.contains(device) ?
+                device->getId() : AUDIO_PORT_HANDLE_NONE;
+
+    isSoundTrigger = attributes.source == AUDIO_SOURCE_HOTWORD &&
+        mSoundTriggerSessions.indexOfKey(session) >= 0;
+    *portId = AudioPort::getNextUniqueId();
+
+    clientDesc = new RecordClientDescriptor(*portId, riid, uid, session, attributes, *config,
+                                            requestedDeviceId, attributes.source, flags,
+                                            isSoundTrigger);
+    inputDesc = mInputs.valueFor(*input);
+    inputDesc->addClient(clientDesc);
+
+    ALOGV("getInputForAttr() returns input %d type %d selectedDeviceId %d for port ID %d",
+            *input, *inputType, *selectedDeviceId, *portId);
 
     return NO_ERROR;
 
 error:
-    mInputRoutes.removeRoute(session);
     return status;
 }
 
 
-audio_io_handle_t AudioPolicyManager::getInputForDevice(audio_devices_t device,
-                                                        String8 address,
+audio_io_handle_t AudioPolicyManager::getInputForDevice(const sp<DeviceDescriptor> &device,
                                                         audio_session_t session,
-                                                        uid_t uid,
-                                                        audio_source_t inputSource,
+                                                        const audio_attributes_t &attributes,
                                                         const audio_config_base_t *config,
                                                         audio_input_flags_t flags,
                                                         const sp<AudioPolicyMix> &policyMix)
 {
     audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
-    audio_source_t halInputSource = inputSource;
+    audio_source_t halInputSource = attributes.source;
     bool isSoundTrigger = false;
 
-    if (inputSource == AUDIO_SOURCE_HOTWORD) {
+    if (attributes.source == AUDIO_SOURCE_HOTWORD) {
         ssize_t index = mSoundTriggerSessions.indexOfKey(session);
         if (index >= 0) {
             input = mSoundTriggerSessions.valueFor(session);
@@ -1655,7 +2104,7 @@
         } else {
             halInputSource = AUDIO_SOURCE_VOICE_RECOGNITION;
         }
-    } else if (inputSource == AUDIO_SOURCE_VOICE_COMMUNICATION &&
+    } else if (attributes.source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
                audio_is_linear_pcm(config->format)) {
         flags = (audio_input_flags_t)(flags | AUDIO_INPUT_FLAG_VOIP_TX);
     }
@@ -1670,8 +2119,7 @@
     audio_input_flags_t profileFlags = flags;
     for (;;) {
         profileFormat = config->format; // reset each time through loop, in case it is updated
-        profile = getInputProfile(device, address,
-                                  profileSamplingRate, profileFormat, profileChannelMask,
+        profile = getInputProfile(device, profileSamplingRate, profileFormat, profileChannelMask,
                                   profileFlags);
         if (profile != 0) {
             break; // success
@@ -1680,9 +2128,9 @@
         } else if (profileFlags != AUDIO_INPUT_FLAG_NONE) {
             profileFlags = AUDIO_INPUT_FLAG_NONE; // retry
         } else { // fail
-            ALOGW("getInputForDevice() could not find profile for device 0x%X, "
-                  "sampling rate %u, format %#x, channel mask 0x%X, flags %#x",
-                    device, config->sample_rate, config->format, config->channel_mask, flags);
+            ALOGW("%s could not find profile for device %s, sampling rate %u, format %#x, "
+                  "channel mask 0x%X, flags %#x", __func__, device->toString().c_str(), 
+                  config->sample_rate, config->format, config->channel_mask, flags);
             return input;
         }
     }
@@ -1697,86 +2145,42 @@
         return input;
     }
 
-    sp<AudioSession> audioSession = new AudioSession(session,
-                                                     inputSource,
-                                                     config->format,
-                                                     samplingRate,
-                                                     config->channel_mask,
-                                                     flags,
-                                                     uid,
-                                                     isSoundTrigger,
-                                                     policyMix, mpClientInterface);
-
-// FIXME: disable concurrent capture until UI is ready
-#if 0
-    // reuse an open input if possible
-    sp<AudioInputDescriptor> reusedInputDesc;
-    for (size_t i = 0; i < mInputs.size(); i++) {
-        sp<AudioInputDescriptor> desc = mInputs.valueAt(i);
-        // reuse input if:
-        // - it shares the same profile
-        //      AND
-        // - it is not a reroute submix input
-        //      AND
-        // - it is: not used for sound trigger
-        //                OR
-        //          used for sound trigger and all clients use the same session ID
-        //
-        if ((profile == desc->mProfile) &&
-            (isSoundTrigger == desc->isSoundTrigger()) &&
-            !is_virtual_input_device(device)) {
-
-            sp<AudioSession> as = desc->getAudioSession(session);
-            if (as != 0) {
-                // do not allow unmatching properties on same session
-                if (as->matches(audioSession)) {
-                    as->changeOpenCount(1);
-                } else {
-                    ALOGW("getInputForDevice() record with different attributes"
-                          " exists for session %d", session);
+    if (!profile->canOpenNewIo()) {
+        for (size_t i = 0; i < mInputs.size(); ) {
+            sp <AudioInputDescriptor> desc = mInputs.valueAt(i);
+            if (desc->mProfile != profile) {
+                i++;
+                continue;
+            }
+            // if sound trigger, reuse input if used by other sound trigger on same session
+            // else
+            //    reuse input if active client app is not in IDLE state
+            //
+            RecordClientVector clients = desc->clientsList();
+            bool doClose = false;
+            for (const auto& client : clients) {
+                if (isSoundTrigger != client->isSoundTrigger()) {
                     continue;
                 }
-            } else if (isSoundTrigger) {
-                continue;
+                if (client->isSoundTrigger()) {
+                    if (session == client->session()) {
+                        return desc->mIoHandle;
+                    }
+                    continue;
+                }
+                if (client->active() && client->appState() != APP_STATE_IDLE) {
+                    return desc->mIoHandle;
+                }
+                doClose = true;
             }
-
-            // Reuse the already opened input stream on this profile if:
-            // - the new capture source is background OR
-            // - the path requested configurations match OR
-            // - the new source priority is less than the highest source priority on this input
-            // If the input stream cannot be reused, close it before opening a new stream
-            // on the same profile for the new client so that the requested path configuration
-            // can be selected.
-            if (!isConcurrentSource(inputSource) &&
-                    ((desc->mSamplingRate != samplingRate ||
-                    desc->mChannelMask != config->channel_mask ||
-                    !audio_formats_match(desc->mFormat, config->format)) &&
-                    (source_priority(desc->getHighestPrioritySource(false /*activeOnly*/)) <
-                     source_priority(inputSource)))) {
-                reusedInputDesc = desc;
-                continue;
+            if (doClose) {
+                closeInput(desc->mIoHandle);
             } else {
-                desc->addAudioSession(session, audioSession);
-                ALOGV("%s: reusing input %d", __FUNCTION__, mInputs.keyAt(i));
-                return mInputs.keyAt(i);
+                i++;
             }
         }
     }
 
-    if (reusedInputDesc != 0) {
-        AudioSessionCollection sessions = reusedInputDesc->getAudioSessions(false /*activeOnly*/);
-        for (size_t j = 0; j < sessions.size(); j++) {
-            audio_session_t currentSession = sessions.keyAt(j);
-            stopInput(reusedInputDesc->mIoHandle, currentSession);
-            releaseInput(reusedInputDesc->mIoHandle, currentSession);
-        }
-    }
-#endif
-
-    if (!profile->canOpenNewIo()) {
-        return AUDIO_IO_HANDLE_NONE;
-    }
-
     sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile, mpClientInterface);
 
     audio_config_t lConfig = AUDIO_CONFIG_INITIALIZER;
@@ -1784,14 +2188,7 @@
     lConfig.channel_mask = profileChannelMask;
     lConfig.format = profileFormat;
 
-    if (address == "") {
-        DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(device);
-        // the inputs vector must be of size >= 1, but we don't want to crash here
-        address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress : String8("");
-    }
-
-    status_t status = inputDesc->open(&lConfig, device, address,
-            halInputSource, profileFlags, &input);
+    status_t status = inputDesc->open(&lConfig, device, halInputSource, profileFlags, &input);
 
     // only accept input with the exact requested set of parameters
     if (status != NO_ERROR || input == AUDIO_IO_HANDLE_NONE ||
@@ -1808,7 +2205,6 @@
     }
 
     inputDesc->mPolicyMix = policyMix;
-    inputDesc->addAudioSession(session, audioSession);
 
     addInput(input, inputDesc);
     mpClientInterface->onAudioPortListUpdate();
@@ -1816,430 +2212,232 @@
     return input;
 }
 
-//static
-bool AudioPolicyManager::isConcurrentSource(audio_source_t source)
+status_t AudioPolicyManager::startInput(audio_port_handle_t portId)
 {
-    return (source == AUDIO_SOURCE_HOTWORD) ||
-            (source == AUDIO_SOURCE_VOICE_RECOGNITION) ||
-            (source == AUDIO_SOURCE_FM_TUNER);
-}
+    ALOGV("%s portId %d", __FUNCTION__, portId);
 
-bool AudioPolicyManager::isConcurentCaptureAllowed(const sp<AudioInputDescriptor>& inputDesc,
-        const sp<AudioSession>& audioSession)
-{
-    // Do not allow capture if an active voice call is using a software patch and
-    // the call TX source device is on the same HW module.
-    // FIXME: would be better to refine to only inputs whose profile connects to the
-    // call TX device but this information is not in the audio patch
-    if (mCallTxPatch != 0 &&
-        inputDesc->getModuleHandle() == mCallTxPatch->mPatch.sources[0].ext.device.hw_module) {
-        return false;
-    }
-
-    // starting concurrent capture is enabled if:
-    // 1) capturing for re-routing
-    // 2) capturing for HOTWORD source
-    // 3) capturing for FM TUNER source
-    // 3) All other active captures are either for re-routing or HOTWORD
-
-    if (is_virtual_input_device(inputDesc->mDevice) ||
-            isConcurrentSource(audioSession->inputSource())) {
-        return true;
-    }
-
-    for (const auto& activeInput : mInputs.getActiveInputs()) {
-        if (!isConcurrentSource(activeInput->inputSource(true)) &&
-                !is_virtual_input_device(activeInput->mDevice)) {
-            return false;
-        }
-    }
-
-    return true;
-}
-
-// FIXME: remove when concurrent capture is ready. This is a hack to work around bug b/63083537.
-bool AudioPolicyManager::soundTriggerSupportsConcurrentCapture() {
-    if (!mHasComputedSoundTriggerSupportsConcurrentCapture) {
-        bool soundTriggerSupportsConcurrentCapture = false;
-        unsigned int numModules = 0;
-        struct sound_trigger_module_descriptor* nModules = NULL;
-
-        status_t status = SoundTrigger::listModules(nModules, &numModules);
-        if (status == NO_ERROR && numModules != 0) {
-            nModules = (struct sound_trigger_module_descriptor*) calloc(
-                    numModules, sizeof(struct sound_trigger_module_descriptor));
-            if (nModules == NULL) {
-              // We failed to malloc the buffer, so just say no for now, and hope that we have more
-              // ram the next time this function is called.
-              ALOGE("Failed to allocate buffer for module descriptors");
-              return false;
-            }
-
-            status = SoundTrigger::listModules(nModules, &numModules);
-            if (status == NO_ERROR) {
-                soundTriggerSupportsConcurrentCapture = true;
-                for (size_t i = 0; i < numModules; ++i) {
-                    soundTriggerSupportsConcurrentCapture &=
-                            nModules[i].properties.concurrent_capture;
-                }
-            }
-            free(nModules);
-        }
-        mSoundTriggerSupportsConcurrentCapture = soundTriggerSupportsConcurrentCapture;
-        mHasComputedSoundTriggerSupportsConcurrentCapture = true;
-    }
-    return mSoundTriggerSupportsConcurrentCapture;
-}
-
-
-status_t AudioPolicyManager::startInput(audio_io_handle_t input,
-                                        audio_session_t session,
-                                        bool silenced,
-                                        concurrency_type__mask_t *concurrency)
-{
-
-    ALOGV("AudioPolicyManager::startInput(input:%d, session:%d, silenced:%d, concurrency:%d)",
-            input, session, silenced, *concurrency);
-
-    *concurrency = API_INPUT_CONCURRENCY_NONE;
-
-    ssize_t index = mInputs.indexOfKey(input);
-    if (index < 0) {
-        ALOGW("startInput() unknown input %d", input);
+    sp<AudioInputDescriptor> inputDesc = mInputs.getInputForClient(portId);
+    if (inputDesc == 0) {
+        ALOGW("%s no input for client %d", __FUNCTION__, portId);
         return BAD_VALUE;
     }
-    sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
-
-    sp<AudioSession> audioSession = inputDesc->getAudioSession(session);
-    if (audioSession == 0) {
-        ALOGW("startInput() unknown session %d on input %d", session, input);
-        return BAD_VALUE;
-    }
-
-// FIXME: disable concurrent capture until UI is ready
-#if 0
-    if (!isConcurentCaptureAllowed(inputDesc, audioSession)) {
-        ALOGW("startInput(%d) failed: other input already started", input);
+    audio_io_handle_t input = inputDesc->mIoHandle;
+    sp<RecordClientDescriptor> client = inputDesc->getClient(portId);
+    if (client->active()) {
+        ALOGW("%s input %d client %d already started", __FUNCTION__, input, client->portId());
         return INVALID_OPERATION;
     }
 
-    if (isInCall()) {
-        *concurrency |= API_INPUT_CONCURRENCY_CALL;
+    audio_session_t session = client->session();
+
+    ALOGV("%s input:%d, session:%d)", __FUNCTION__, input, session);
+
+    Vector<sp<AudioInputDescriptor>> activeInputs = mInputs.getActiveInputs();
+
+    status_t status = inputDesc->start();
+    if (status != NO_ERROR) {
+        return status;
     }
-    if (mInputs.activeInputsCountOnDevices() != 0) {
-        *concurrency |= API_INPUT_CONCURRENCY_CAPTURE;
-    }
-#else
-    if (!is_virtual_input_device(inputDesc->mDevice)) {
-        if (mCallTxPatch != 0 &&
-            inputDesc->getModuleHandle() == mCallTxPatch->mPatch.sources[0].ext.device.hw_module) {
-            ALOGW("startInput(%d) failed: call in progress", input);
-            *concurrency |= API_INPUT_CONCURRENCY_CALL;
-            return INVALID_OPERATION;
-        }
 
-        Vector<sp<AudioInputDescriptor>> activeInputs = mInputs.getActiveInputs();
-
-        // If a UID is idle and records silence and another not silenced recording starts
-        // from another UID (idle or active) we stop the current idle UID recording in
-        // favor of the new one - "There can be only one" TM
-        if (!silenced) {
-            for (const auto& activeDesc : activeInputs) {
-                if ((audioSession->flags() & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0 &&
-                        activeDesc->getId() == inputDesc->getId()) {
-                     continue;
-                }
-
-                AudioSessionCollection activeSessions = activeDesc->getAudioSessions(
-                        true /*activeOnly*/);
-                sp<AudioSession> activeSession = activeSessions.valueAt(0);
-                if (activeSession->isSilenced()) {
-                    audio_io_handle_t activeInput = activeDesc->mIoHandle;
-                    audio_session_t activeSessionId = activeSession->session();
-                    stopInput(activeInput, activeSessionId);
-                    releaseInput(activeInput, activeSessionId);
-                    ALOGV("startInput(%d) stopping silenced input %d", input, activeInput);
-                    activeInputs = mInputs.getActiveInputs();
-                }
-            }
-        }
-
-        for (const auto& activeDesc : activeInputs) {
-            if ((audioSession->flags() & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0 &&
-                    activeDesc->getId() == inputDesc->getId()) {
-                continue;
-            }
-
-            audio_source_t activeSource = activeDesc->inputSource(true);
-            if (audioSession->inputSource() == AUDIO_SOURCE_HOTWORD) {
-                if (activeSource == AUDIO_SOURCE_HOTWORD) {
-                    if (activeDesc->hasPreemptedSession(session)) {
-                        ALOGW("startInput(%d) failed for HOTWORD: "
-                                "other input %d already started for HOTWORD",
-                              input, activeDesc->mIoHandle);
-                        *concurrency |= API_INPUT_CONCURRENCY_HOTWORD;
-                        return INVALID_OPERATION;
-                    }
-                } else {
-                    ALOGV("startInput(%d) failed for HOTWORD: other input %d already started",
-                          input, activeDesc->mIoHandle);
-                    *concurrency |= API_INPUT_CONCURRENCY_CAPTURE;
-                    return INVALID_OPERATION;
-                }
-            } else {
-                if (activeSource != AUDIO_SOURCE_HOTWORD) {
-                    ALOGW("startInput(%d) failed: other input %d already started",
-                          input, activeDesc->mIoHandle);
-                    *concurrency |= API_INPUT_CONCURRENCY_CAPTURE;
-                    return INVALID_OPERATION;
-                }
-            }
-        }
-
-        // We only need to check if the sound trigger session supports concurrent capture if the
-        // input is also a sound trigger input. Otherwise, we should preempt any hotword stream
-        // that's running.
-        const bool allowConcurrentWithSoundTrigger =
-            inputDesc->isSoundTrigger() ? soundTriggerSupportsConcurrentCapture() : false;
-
-        // if capture is allowed, preempt currently active HOTWORD captures
-        for (const auto& activeDesc : activeInputs) {
-            if (allowConcurrentWithSoundTrigger && activeDesc->isSoundTrigger()) {
-                continue;
-            }
-
-            audio_source_t activeSource = activeDesc->inputSource(true);
-            if (activeSource == AUDIO_SOURCE_HOTWORD) {
-                AudioSessionCollection activeSessions =
-                        activeDesc->getAudioSessions(true /*activeOnly*/);
-                audio_session_t activeSession = activeSessions.keyAt(0);
-                audio_io_handle_t activeHandle = activeDesc->mIoHandle;
-                SortedVector<audio_session_t> sessions = activeDesc->getPreemptedSessions();
-                *concurrency |= API_INPUT_CONCURRENCY_PREEMPT;
-                sessions.add(activeSession);
-                inputDesc->setPreemptedSessions(sessions);
-                stopInput(activeHandle, activeSession);
-                releaseInput(activeHandle, activeSession);
-                ALOGV("startInput(%d) for HOTWORD preempting HOTWORD input %d",
-                      input, activeDesc->mIoHandle);
-            }
-        }
-    }
-#endif
-
-    // Make sure we start with the correct silence state
-    audioSession->setSilenced(silenced);
-
-    // increment activity count before calling getNewInputDevice() below as only active sessions
+  // increment activity count before calling getNewInputDevice() below as only active sessions
     // are considered for device selection
-    audioSession->changeActiveCount(1);
+    inputDesc->setClientActive(client, true);
 
-    // Routing?
-    mInputRoutes.incRouteActivity(session);
+    // indicate active capture to sound trigger service if starting capture from a mic on
+    // primary HW module
+    sp<DeviceDescriptor> device = getNewInputDevice(inputDesc);
+    setInputDevice(input, device, true /* force */);
 
-    if (audioSession->activeCount() == 1 || mInputRoutes.getAndClearRouteChanged(session)) {
-        // indicate active capture to sound trigger service if starting capture from a mic on
-        // primary HW module
-        audio_devices_t device = getNewInputDevice(inputDesc);
-        setInputDevice(input, device, true /* force */);
-
-        status_t status = inputDesc->start();
-        if (status != NO_ERROR) {
-            mInputRoutes.decRouteActivity(session);
-            audioSession->changeActiveCount(-1);
-            return status;
+    if (inputDesc->activeCount()  == 1) {
+        sp<AudioPolicyMix> policyMix = inputDesc->mPolicyMix.promote();
+        // if input maps to a dynamic policy with an activity listener, notify of state change
+        if ((policyMix != NULL)
+                && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
+            mpClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
+                    MIX_STATE_MIXING);
         }
 
-        if (inputDesc->getAudioSessionCount(true/*activeOnly*/) == 1) {
-            sp<AudioPolicyMix> policyMix = inputDesc->mPolicyMix.promote();
-            // if input maps to a dynamic policy with an activity listener, notify of state change
-            if ((policyMix != NULL)
-                    && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
-                mpClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
-                        MIX_STATE_MIXING);
-            }
+        DeviceVector primaryInputDevices = availablePrimaryModuleInputDevices();
+        if (primaryInputDevices.contains(device) &&
+                mInputs.activeInputsCountOnDevices(primaryInputDevices) == 1) {
+            SoundTrigger::setCaptureState(true);
+        }
 
-            audio_devices_t primaryInputDevices = availablePrimaryInputDevices();
-            if (((device & primaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) &&
-                    mInputs.activeInputsCountOnDevices(primaryInputDevices) == 1) {
-                SoundTrigger::setCaptureState(true);
+        // automatically enable the remote submix output when input is started if not
+        // used by a policy mix of type MIX_TYPE_RECORDERS
+        // For remote submix (a virtual device), we open only one input per capture request.
+        if (audio_is_remote_submix_device(inputDesc->getDeviceType())) {
+            String8 address = String8("");
+            if (policyMix == NULL) {
+                address = String8("0");
+            } else if (policyMix->mMixType == MIX_TYPE_PLAYERS) {
+                address = policyMix->mDeviceAddress;
             }
-
-            // automatically enable the remote submix output when input is started if not
-            // used by a policy mix of type MIX_TYPE_RECORDERS
-            // For remote submix (a virtual device), we open only one input per capture request.
-            if (audio_is_remote_submix_device(inputDesc->mDevice)) {
-                String8 address = String8("");
-                if (policyMix == NULL) {
-                    address = String8("0");
-                } else if (policyMix->mMixType == MIX_TYPE_PLAYERS) {
-                    address = policyMix->mDeviceAddress;
-                }
-                if (address != "") {
-                    setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
-                            AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
-                            address, "remote-submix");
-                }
+            if (address != "") {
+                setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
+                        AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
+                        address, "remote-submix", AUDIO_FORMAT_DEFAULT);
             }
         }
     }
 
-    ALOGV("AudioPolicyManager::startInput() input source = %d", audioSession->inputSource());
+    ALOGV("%s input %d source = %d exit", __FUNCTION__, input, client->source());
 
     return NO_ERROR;
 }
 
-status_t AudioPolicyManager::stopInput(audio_io_handle_t input,
-                                       audio_session_t session)
+status_t AudioPolicyManager::stopInput(audio_port_handle_t portId)
 {
-    ALOGV("stopInput() input %d", input);
-    ssize_t index = mInputs.indexOfKey(input);
-    if (index < 0) {
-        ALOGW("stopInput() unknown input %d", input);
+    ALOGV("%s portId %d", __FUNCTION__, portId);
+
+    sp<AudioInputDescriptor> inputDesc = mInputs.getInputForClient(portId);
+    if (inputDesc == 0) {
+        ALOGW("%s no input for client %d", __FUNCTION__, portId);
         return BAD_VALUE;
     }
-    sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
-
-    sp<AudioSession> audioSession = inputDesc->getAudioSession(session);
-    if (index < 0) {
-        ALOGW("stopInput() unknown session %d on input %d", session, input);
-        return BAD_VALUE;
-    }
-
-    if (audioSession->activeCount() == 0) {
-        ALOGW("stopInput() input %d already stopped", input);
+    audio_io_handle_t input = inputDesc->mIoHandle;
+    sp<RecordClientDescriptor> client = inputDesc->getClient(portId);
+    if (!client->active()) {
+        ALOGW("%s input %d client %d already stopped", __FUNCTION__, input, client->portId());
         return INVALID_OPERATION;
     }
 
-    audioSession->changeActiveCount(-1);
+    inputDesc->setClientActive(client, false);
 
-    // Routing?
-    mInputRoutes.decRouteActivity(session);
-
-    if (audioSession->activeCount() == 0) {
-        inputDesc->stop();
-        if (inputDesc->isActive()) {
-            setInputDevice(input, getNewInputDevice(inputDesc), false /* force */);
-        } else {
-            sp<AudioPolicyMix> policyMix = inputDesc->mPolicyMix.promote();
-            // if input maps to a dynamic policy with an activity listener, notify of state change
-            if ((policyMix != NULL)
-                    && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
-                mpClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
-                        MIX_STATE_IDLE);
-            }
-
-            // automatically disable the remote submix output when input is stopped if not
-            // used by a policy mix of type MIX_TYPE_RECORDERS
-            if (audio_is_remote_submix_device(inputDesc->mDevice)) {
-                String8 address = String8("");
-                if (policyMix == NULL) {
-                    address = String8("0");
-                } else if (policyMix->mMixType == MIX_TYPE_PLAYERS) {
-                    address = policyMix->mDeviceAddress;
-                }
-                if (address != "") {
-                    setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
-                                             AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
-                                             address, "remote-submix");
-                }
-            }
-
-            audio_devices_t device = inputDesc->mDevice;
-            resetInputDevice(input);
-
-            // indicate inactive capture to sound trigger service if stopping capture from a mic on
-            // primary HW module
-            audio_devices_t primaryInputDevices = availablePrimaryInputDevices();
-            if (((device & primaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) &&
-                    mInputs.activeInputsCountOnDevices(primaryInputDevices) == 0) {
-                SoundTrigger::setCaptureState(false);
-            }
-            inputDesc->clearPreemptedSessions();
+    inputDesc->stop();
+    if (inputDesc->isActive()) {
+        setInputDevice(input, getNewInputDevice(inputDesc), false /* force */);
+    } else {
+        sp<AudioPolicyMix> policyMix = inputDesc->mPolicyMix.promote();
+        // if input maps to a dynamic policy with an activity listener, notify of state change
+        if ((policyMix != NULL)
+                && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
+            mpClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
+                    MIX_STATE_IDLE);
         }
+
+        // automatically disable the remote submix output when input is stopped if not
+        // used by a policy mix of type MIX_TYPE_RECORDERS
+        if (audio_is_remote_submix_device(inputDesc->getDeviceType())) {
+            String8 address = String8("");
+            if (policyMix == NULL) {
+                address = String8("0");
+            } else if (policyMix->mMixType == MIX_TYPE_PLAYERS) {
+                address = policyMix->mDeviceAddress;
+            }
+            if (address != "") {
+                setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
+                                         AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
+                                         address, "remote-submix", AUDIO_FORMAT_DEFAULT);
+            }
+        }
+        resetInputDevice(input);
+
+        // indicate inactive capture to sound trigger service if stopping capture from a mic on
+        // primary HW module
+        DeviceVector primaryInputDevices = availablePrimaryModuleInputDevices();
+        if (primaryInputDevices.contains(inputDesc->getDevice()) &&
+                mInputs.activeInputsCountOnDevices(primaryInputDevices) == 0) {
+            SoundTrigger::setCaptureState(false);
+        }
+        inputDesc->clearPreemptedSessions();
     }
     return NO_ERROR;
 }
 
-void AudioPolicyManager::releaseInput(audio_io_handle_t input,
-                                      audio_session_t session)
+void AudioPolicyManager::releaseInput(audio_port_handle_t portId)
 {
-    ALOGV("releaseInput() %d", input);
-    ssize_t index = mInputs.indexOfKey(input);
-    if (index < 0) {
-        ALOGW("releaseInput() releasing unknown input %d", input);
+    ALOGV("%s portId %d", __FUNCTION__, portId);
+
+    sp<AudioInputDescriptor> inputDesc = mInputs.getInputForClient(portId);
+    if (inputDesc == 0) {
+        ALOGW("%s no input for client %d", __FUNCTION__, portId);
         return;
     }
+    sp<RecordClientDescriptor> client = inputDesc->getClient(portId);
+    audio_io_handle_t input = inputDesc->mIoHandle;
 
-    // Routing
-    mInputRoutes.removeRoute(session);
+    ALOGV("%s %d", __FUNCTION__, input);
 
-    sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
-    ALOG_ASSERT(inputDesc != 0);
+    inputDesc->removeClient(portId);
 
-    sp<AudioSession> audioSession = inputDesc->getAudioSession(session);
-    if (audioSession == 0) {
-        ALOGW("releaseInput() unknown session %d on input %d", session, input);
-        return;
-    }
-
-    if (audioSession->openCount() == 0) {
-        ALOGW("releaseInput() invalid open count %d on session %d",
-              audioSession->openCount(), session);
-        return;
-    }
-
-    if (audioSession->changeOpenCount(-1) == 0) {
-        inputDesc->removeAudioSession(session);
-    }
-
-    if (inputDesc->getOpenRefCount() > 0) {
-        ALOGV("releaseInput() exit > 0");
+    if (inputDesc->getClientCount() > 0) {
+        ALOGV("%s(%d) %zu clients remaining", __func__, portId, inputDesc->getClientCount());
         return;
     }
 
     closeInput(input);
     mpClientInterface->onAudioPortListUpdate();
-    ALOGV("releaseInput() exit");
+    ALOGV("%s exit", __FUNCTION__);
 }
 
-void AudioPolicyManager::closeAllInputs() {
-    bool patchRemoved = false;
+void AudioPolicyManager::closeActiveClients(const sp<AudioInputDescriptor>& input)
+{
+    RecordClientVector clients = input->clientsList(true);
 
-    for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
-        sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(input_index);
-        ssize_t patch_index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
-        if (patch_index >= 0) {
-            sp<AudioPatch> patchDesc = mAudioPatches.valueAt(patch_index);
-            (void) /*status_t status*/ mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
-            mAudioPatches.removeItemsAt(patch_index);
-            patchRemoved = true;
+    for (const auto& client : clients) {
+        closeClient(client->portId());
+    }
+}
+
+void AudioPolicyManager::closeClient(audio_port_handle_t portId)
+{
+    stopInput(portId);
+    releaseInput(portId);
+}
+
+void AudioPolicyManager::checkCloseInputs() {
+    // After connecting or disconnecting an input device, close input if:
+    // - it has no client (was just opened to check profile)  OR
+    // - none of its supported devices are connected anymore OR
+    // - one of its clients cannot be routed to one of its supported
+    // devices anymore. Otherwise update device selection
+    std::vector<audio_io_handle_t> inputsToClose;
+    for (size_t i = 0; i < mInputs.size(); i++) {
+        const sp<AudioInputDescriptor> input = mInputs.valueAt(i);
+        if (input->clientsList().size() == 0
+                || !mAvailableInputDevices.containsAtLeastOne(input->supportedDevices())
+                || (input->getAudioPort()->getFlags() & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0) {
+            inputsToClose.push_back(mInputs.keyAt(i));
+        } else {
+            bool close = false;
+            for (const auto& client : input->clientsList()) {
+                sp<DeviceDescriptor> device =
+                    mEngine->getInputDeviceForAttributes(client->attributes());
+                if (!input->supportedDevices().contains(device)) {
+                    close = true;
+                    break;
+                }
+            }
+            if (close) {
+                inputsToClose.push_back(mInputs.keyAt(i));
+            } else {
+                setInputDevice(input->mIoHandle, getNewInputDevice(input));
+            }
         }
-        inputDesc->close();
     }
-    mInputRoutes.clear();
-    mInputs.clear();
-    SoundTrigger::setCaptureState(false);
-    nextAudioPortGeneration();
 
-    if (patchRemoved) {
-        mpClientInterface->onAudioPatchListUpdate();
+    for (const audio_io_handle_t handle : inputsToClose) {
+        ALOGV("%s closing input %d", __func__, handle);
+        closeInput(handle);
     }
 }
 
-void AudioPolicyManager::initStreamVolume(audio_stream_type_t stream,
-                                            int indexMin,
-                                            int indexMax)
+void AudioPolicyManager::initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax)
 {
     ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
-    mVolumeCurves->initStreamVolume(stream, indexMin, indexMax);
+    if (indexMin < 0 || indexMax < 0) {
+        ALOGE("%s for stream %d: invalid min %d or max %d", __func__, stream , indexMin, indexMax);
+        return;
+    }
+    getVolumeCurves(stream).initVolume(indexMin, indexMax);
 
     // initialize other private stream volumes which follow this one
     for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
         if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
             continue;
         }
-        mVolumeCurves->initStreamVolume((audio_stream_type_t)curStream, indexMin, indexMax);
+        getVolumeCurves((audio_stream_type_t)curStream).initVolume(indexMin, indexMax);
     }
 }
 
@@ -2247,12 +2445,166 @@
                                                   int index,
                                                   audio_devices_t device)
 {
+    auto attributes = mEngine->getAttributesForStreamType(stream);
+    ALOGV("%s: stream %s attributes=%s", __func__,
+          toString(stream).c_str(), toString(attributes).c_str());
+    return setVolumeIndexForAttributes(attributes, index, device);
+}
 
+status_t AudioPolicyManager::getStreamVolumeIndex(audio_stream_type_t stream,
+                                                  int *index,
+                                                  audio_devices_t device)
+{
+    // if device is AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, return volume for device selected for this
+    // stream by the engine.
+    if (device == AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
+        device = mEngine->getOutputDevicesForStream(stream, true /*fromCache*/).types();
+    }
+    return getVolumeIndex(getVolumeCurves(stream), *index, device);
+}
+
+status_t AudioPolicyManager::setVolumeIndexForAttributes(const audio_attributes_t &attributes,
+                                                         int index,
+                                                         audio_devices_t device)
+{
+    // Get Volume group matching the Audio Attributes
+    auto group = mEngine->getVolumeGroupForAttributes(attributes);
+    if (group == VOLUME_GROUP_NONE) {
+        ALOGD("%s: no group matching with %s", __FUNCTION__, toString(attributes).c_str());
+        return BAD_VALUE;
+    }
+    ALOGV("%s: group %d matching with %s", __FUNCTION__, group, toString(attributes).c_str());
+    status_t status = NO_ERROR;
+    IVolumeCurves &curves = getVolumeCurves(attributes);
+    VolumeSource vs = toVolumeSource(group);
+    product_strategy_t strategy = mEngine->getProductStrategyForAttributes(attributes);
+
+    status = setVolumeCurveIndex(index, device, curves);
+    if (status != NO_ERROR) {
+        ALOGE("%s failed to set curve index for group %d device 0x%X", __func__, group, device);
+        return status;
+    }
+
+    audio_devices_t curSrcDevice;
+    auto curCurvAttrs = curves.getAttributes();
+    if (!curCurvAttrs.empty() && curCurvAttrs.front() != defaultAttr) {
+        auto attr = curCurvAttrs.front();
+        curSrcDevice = mEngine->getOutputDevicesForAttributes(attr, nullptr, false).types();
+    } else if (!curves.getStreamTypes().empty()) {
+        auto stream = curves.getStreamTypes().front();
+        curSrcDevice = mEngine->getOutputDevicesForStream(stream, false).types();
+    } else {
+        ALOGE("%s: Invalid src %d: no valid attributes nor stream",__func__, vs);
+        return BAD_VALUE;
+    }
+    curSrcDevice = Volume::getDeviceForVolume(curSrcDevice);
+
+    // update volume on all outputs and streams matching the following:
+    // - The requested stream (or a stream matching for volume control) is active on the output
+    // - The device (or devices) selected by the engine for this stream includes
+    // the requested device
+    // - For non default requested device, currently selected device on the output is either the
+    // requested device or one of the devices selected by the engine for this stream
+    // - For default requested device (AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME), apply volume only if
+    // no specific device volume value exists for currently selected device.
+    for (size_t i = 0; i < mOutputs.size(); i++) {
+        sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
+        audio_devices_t curDevice = desc->devices().types();
+
+        if (curDevice & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
+            curDevice |= AUDIO_DEVICE_OUT_SPEAKER;
+            curDevice &= ~AUDIO_DEVICE_OUT_SPEAKER_SAFE;
+        }
+
+        // Inter / intra volume group priority management: Loop on strategies arranged by priority
+        // If a higher priority strategy is active, and the output is routed to a device with a
+        // HW Gain management, do not change the volume
+        bool applyVolume = false;
+        if (desc->useHwGain()) {
+            if (!(desc->isActive(toVolumeSource(group)) || isInCall())) {
+                continue;
+            }
+            for (const auto &productStrategy : mEngine->getOrderedProductStrategies()) {
+                auto activeClients = desc->clientsList(true /*activeOnly*/, productStrategy,
+                                                       false /*preferredDevice*/);
+                if (activeClients.empty()) {
+                    continue;
+                }
+                bool isPreempted = false;
+                bool isHigherPriority = productStrategy < strategy;
+                for (const auto &client : activeClients) {
+                    if (isHigherPriority && (client->volumeSource() != vs)) {
+                        ALOGV("%s: Strategy=%d (\nrequester:\n"
+                              " group %d, volumeGroup=%d attributes=%s)\n"
+                              " higher priority source active:\n"
+                              " volumeGroup=%d attributes=%s) \n"
+                              " on output %zu, bailing out", __func__, productStrategy,
+                              group, group, toString(attributes).c_str(),
+                              client->volumeSource(), toString(client->attributes()).c_str(), i);
+                        applyVolume = false;
+                        isPreempted = true;
+                        break;
+                    }
+                    // However, continue for loop to ensure no higher prio clients running on output
+                    if (client->volumeSource() == vs) {
+                        applyVolume = true;
+                    }
+                }
+                if (isPreempted || applyVolume) {
+                    break;
+                }
+            }
+            if (!applyVolume) {
+                continue; // next output
+            }
+            status_t volStatus = checkAndSetVolume(curves, vs, index, desc, curDevice,
+                                                   (vs == toVolumeSource(AUDIO_STREAM_SYSTEM)?
+                                                        TOUCH_SOUND_FIXED_DELAY_MS : 0));
+            if (volStatus != NO_ERROR) {
+                status = volStatus;
+            }
+            continue;
+        }
+        if (!(desc->isActive(vs) || isInCall())) {
+            continue;
+        }
+        if ((device != AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) && ((curDevice & device) == 0)) {
+            continue;
+        }
+        if (device != AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
+            curSrcDevice |= device;
+            applyVolume = (Volume::getDeviceForVolume(curDevice) & curSrcDevice) != 0;
+        } else {
+            applyVolume = !curves.hasVolumeIndexForDevice(curSrcDevice);
+        }
+        if (applyVolume) {
+            //FIXME: workaround for truncated touch sounds
+            // delayed volume change for system stream to be removed when the problem is
+            // handled by system UI
+            status_t volStatus = checkAndSetVolume(
+                        curves, vs, index, desc, curDevice,
+                        ((vs == toVolumeSource(AUDIO_STREAM_SYSTEM))?
+                             TOUCH_SOUND_FIXED_DELAY_MS : 0));
+            if (volStatus != NO_ERROR) {
+                status = volStatus;
+            }
+        }
+    }
+    mpClientInterface->onAudioVolumeGroupChanged(group, 0 /*flags*/);
+    return status;
+}
+
+status_t AudioPolicyManager::setVolumeCurveIndex(int index,
+                                                 audio_devices_t device,
+                                                 IVolumeCurves &volumeCurves)
+{
     // VOICE_CALL stream has minVolumeIndex > 0  but can be muted directly by an
     // app that has MODIFY_PHONE_STATE permission.
-    if (((index < mVolumeCurves->getVolumeIndexMin(stream)) &&
-            !(stream == AUDIO_STREAM_VOICE_CALL && index == 0)) ||
-            (index > mVolumeCurves->getVolumeIndexMax(stream))) {
+    bool hasVoice = hasVoiceStream(volumeCurves.getStreamTypes());
+    if (((index < volumeCurves.getVolumeIndexMin()) && !(hasVoice && index == 0)) ||
+            (index > volumeCurves.getVolumeIndexMax())) {
+        ALOGD("%s: wrong index %d min=%d max=%d", __FUNCTION__, index,
+              volumeCurves.getVolumeIndexMin(), volumeCurves.getVolumeIndexMax());
         return BAD_VALUE;
     }
     if (!audio_is_output_device(device)) {
@@ -2260,90 +2612,49 @@
     }
 
     // Force max volume if stream cannot be muted
-    if (!mVolumeCurves->canBeMuted(stream)) index = mVolumeCurves->getVolumeIndexMax(stream);
+    if (!volumeCurves.canBeMuted()) index = volumeCurves.getVolumeIndexMax();
 
-    ALOGV("setStreamVolumeIndex() stream %d, device %08x, index %d",
-          stream, device, index);
-
-    // update other private stream volumes which follow this one
-    for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
-        if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
-            continue;
-        }
-        mVolumeCurves->addCurrentVolumeIndex((audio_stream_type_t)curStream, device, index);
-    }
-
-    // update volume on all outputs and streams matching the following:
-    // - The requested stream (or a stream matching for volume control) is active on the output
-    // - The device (or devices) selected by the strategy corresponding to this stream includes
-    // the requested device
-    // - For non default requested device, currently selected device on the output is either the
-    // requested device or one of the devices selected by the strategy
-    // - For default requested device (AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME), apply volume only if
-    // no specific device volume value exists for currently selected device.
-    status_t status = NO_ERROR;
-    for (size_t i = 0; i < mOutputs.size(); i++) {
-        sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
-        audio_devices_t curDevice = Volume::getDeviceForVolume(desc->device());
-        for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
-            if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
-                continue;
-            }
-            if (!(desc->isStreamActive((audio_stream_type_t)curStream) ||
-                    (isInCall() && (curStream == AUDIO_STREAM_VOICE_CALL)))) {
-                continue;
-            }
-            routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream);
-            audio_devices_t curStreamDevice = Volume::getDeviceForVolume(getDeviceForStrategy(
-                    curStrategy, false /*fromCache*/));
-            if ((device != AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) &&
-                    ((curStreamDevice & device) == 0)) {
-                continue;
-            }
-            bool applyVolume;
-            if (device != AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
-                curStreamDevice |= device;
-                applyVolume = (curDevice & curStreamDevice) != 0;
-            } else {
-                applyVolume = !mVolumeCurves->hasVolumeIndexForDevice(
-                        stream, curStreamDevice);
-            }
-
-            if (applyVolume) {
-                //FIXME: workaround for truncated touch sounds
-                // delayed volume change for system stream to be removed when the problem is
-                // handled by system UI
-                status_t volStatus =
-                        checkAndSetVolume((audio_stream_type_t)curStream, index, desc, curDevice,
-                            (stream == AUDIO_STREAM_SYSTEM) ? TOUCH_SOUND_FIXED_DELAY_MS : 0);
-                if (volStatus != NO_ERROR) {
-                    status = volStatus;
-                }
-            }
-        }
-    }
-    return status;
+    ALOGV("%s device %08x, index %d", __FUNCTION__ , device, index);
+    volumeCurves.addCurrentVolumeIndex(device, index);
+    return NO_ERROR;
 }
 
-status_t AudioPolicyManager::getStreamVolumeIndex(audio_stream_type_t stream,
-                                                      int *index,
-                                                      audio_devices_t device)
+status_t AudioPolicyManager::getVolumeIndexForAttributes(const audio_attributes_t &attr,
+                                                         int &index,
+                                                         audio_devices_t device)
 {
-    if (index == NULL) {
-        return BAD_VALUE;
+    // if device is AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, return volume for device selected for this
+    // stream by the engine.
+    if (device == AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
+        device = mEngine->getOutputDevicesForAttributes(attr, nullptr, true /*fromCache*/).types();
     }
+    return getVolumeIndex(getVolumeCurves(attr), index, device);
+}
+
+status_t AudioPolicyManager::getVolumeIndex(const IVolumeCurves &curves,
+                                            int &index,
+                                            audio_devices_t device) const
+{
     if (!audio_is_output_device(device)) {
         return BAD_VALUE;
     }
-    // if device is AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, return volume for device corresponding to
-    // the strategy the stream belongs to.
-    if (device == AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
-        device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/);
-    }
     device = Volume::getDeviceForVolume(device);
+    index = curves.getVolumeIndex(device);
+    ALOGV("%s: device %08x index %d", __FUNCTION__, device, index);
+    return NO_ERROR;
+}
 
-    *index =  mVolumeCurves->getVolumeIndex(stream, device);
-    ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index);
+status_t AudioPolicyManager::getMinVolumeIndexForAttributes(const audio_attributes_t &attr,
+                                                            int &index)
+{
+    index = getVolumeCurves(attr).getVolumeIndexMin();
+    return NO_ERROR;
+}
+
+status_t AudioPolicyManager::getMaxVolumeIndexForAttributes(const audio_attributes_t &attr,
+                                                            int &index)
+{
+    index = getVolumeCurves(attr).getVolumeIndexMax();
     return NO_ERROR;
 }
 
@@ -2358,9 +2669,9 @@
     // 3: The primary output
     // 4: the first output in the list
 
-    routing_strategy strategy = getStrategy(AUDIO_STREAM_MUSIC);
-    audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
-    SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
+    DeviceVector devices = mEngine->getOutputDevicesForAttributes(
+                attributes_initializer(AUDIO_USAGE_MEDIA), nullptr, false /*fromCache*/);
+    SortedVector<audio_io_handle_t> outputs = getOutputsForDevices(devices, mOutputs);
 
     if (outputs.size() == 0) {
         return AUDIO_IO_HANDLE_NONE;
@@ -2376,7 +2687,7 @@
 
         for (audio_io_handle_t output : outputs) {
             sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(output);
-            if (activeOnly && !desc->isStreamActive(AUDIO_STREAM_MUSIC)) {
+            if (activeOnly && !desc->isActive(toVolumeSource(AUDIO_STREAM_MUSIC))) {
                 continue;
             }
             ALOGV("selectOutputForMusicEffects activeOnly %d output %d flags 0x%08x",
@@ -2404,6 +2715,7 @@
     }
 
     if (output != mMusicEffectOutput) {
+        mEffects.moveEffects(AUDIO_SESSION_OUTPUT_MIX, mMusicEffectOutput, output);
         mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, mMusicEffectOutput, output);
         mMusicEffectOutput = output;
     }
@@ -2431,24 +2743,62 @@
             return INVALID_OPERATION;
         }
     }
-    return mEffects.registerEffect(desc, io, strategy, session, id);
+    return mEffects.registerEffect(desc, io, session, id,
+                                   (strategy == streamToStrategy(AUDIO_STREAM_MUSIC) ||
+                                   strategy == PRODUCT_STRATEGY_NONE));
+}
+
+status_t AudioPolicyManager::unregisterEffect(int id)
+{
+    if (mEffects.getEffect(id) == nullptr) {
+        return INVALID_OPERATION;
+    }
+    if (mEffects.isEffectEnabled(id)) {
+        ALOGW("%s effect %d enabled", __FUNCTION__, id);
+        setEffectEnabled(id, false);
+    }
+    return mEffects.unregisterEffect(id);
+}
+
+void AudioPolicyManager::cleanUpEffectsForIo(audio_io_handle_t io)
+{
+    EffectDescriptorCollection effects = mEffects.getEffectsForIo(io);
+    for (size_t i = 0; i < effects.size(); i++) {
+        ALOGW("%s removing stale effect %s, id %d on closed IO %d",
+              __func__, effects.valueAt(i)->mDesc.name, effects.keyAt(i), io);
+        unregisterEffect(effects.keyAt(i));
+    }
+}
+
+status_t AudioPolicyManager::setEffectEnabled(int id, bool enabled)
+{
+    sp<EffectDescriptor> effect = mEffects.getEffect(id);
+    if (effect == nullptr) {
+        return INVALID_OPERATION;
+    }
+
+    status_t status = mEffects.setEffectEnabled(id, enabled);
+    if (status == NO_ERROR) {
+        mInputs.trackEffectEnabled(effect, enabled);
+    }
+    return status;
+}
+
+
+status_t AudioPolicyManager::moveEffectsToIo(const std::vector<int>& ids, audio_io_handle_t io)
+{
+   mEffects.moveEffects(ids, io);
+   return NO_ERROR;
 }
 
 bool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
 {
-    bool active = false;
-    for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT && !active; curStream++) {
-        if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
-            continue;
-        }
-        active = mOutputs.isStreamActive((audio_stream_type_t)curStream, inPastMs);
-    }
-    return active;
+    return mOutputs.isActive(toVolumeSource(stream), inPastMs);
 }
 
 bool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const
 {
-    return mOutputs.isStreamActiveRemotely(stream, inPastMs);
+    return mOutputs.isActiveRemotely(toVolumeSource(stream), inPastMs);
 }
 
 bool AudioPolicyManager::isSourceActive(audio_source_t source) const
@@ -2493,33 +2843,48 @@
     sp<HwModule> rSubmixModule;
     // examine each mix's route type
     for (size_t i = 0; i < mixes.size(); i++) {
-        // we only support MIX_ROUTE_FLAG_LOOP_BACK or MIX_ROUTE_FLAG_RENDER, not the combination
-        if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_ALL) == MIX_ROUTE_FLAG_ALL) {
+        AudioMix mix = mixes[i];
+        // Only capture of playback is allowed in LOOP_BACK & RENDER mode
+        if (is_mix_loopback_render(mix.mRouteFlags) && mix.mMixType != MIX_TYPE_PLAYERS) {
+            ALOGE("Unsupported Policy Mix %zu of %zu: "
+                  "Only capture of playback is allowed in LOOP_BACK & RENDER mode",
+                   i, mixes.size());
             res = INVALID_OPERATION;
             break;
         }
-        if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_LOOP_BACK) == MIX_ROUTE_FLAG_LOOP_BACK) {
-            ALOGV("registerPolicyMixes() mix %zu of %zu is LOOP_BACK", i, mixes.size());
+        // LOOP_BACK and LOOP_BACK | RENDER have the same remote submix backend and are handled
+        // in the same way.
+        if ((mix.mRouteFlags & MIX_ROUTE_FLAG_LOOP_BACK) == MIX_ROUTE_FLAG_LOOP_BACK) {
+            ALOGV("registerPolicyMixes() mix %zu of %zu is LOOP_BACK %d", i, mixes.size(),
+                  mix.mRouteFlags);
             if (rSubmixModule == 0) {
                 rSubmixModule = mHwModules.getModuleFromName(
                         AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX);
                 if (rSubmixModule == 0) {
-                    ALOGE(" Unable to find audio module for submix, aborting mix %zu registration",
+                    ALOGE("Unable to find audio module for submix, aborting mix %zu registration",
                             i);
                     res = INVALID_OPERATION;
                     break;
                 }
             }
 
-            String8 address = mixes[i].mDeviceAddress;
+            String8 address = mix.mDeviceAddress;
+            audio_devices_t deviceTypeToMakeAvailable;
+            if (mix.mMixType == MIX_TYPE_PLAYERS) {
+                mix.mDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
+                deviceTypeToMakeAvailable = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
+            } else {
+                mix.mDeviceType = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
+                deviceTypeToMakeAvailable = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
+            }
 
-            if (mPolicyMixes.registerMix(address, mixes[i], 0 /*output desc*/) != NO_ERROR) {
-                ALOGE(" Error registering mix %zu for address %s", i, address.string());
+            if (mPolicyMixes.registerMix(mix, 0 /*output desc*/) != NO_ERROR) {
+                ALOGE("Error registering mix %zu for address %s", i, address.string());
                 res = INVALID_OPERATION;
                 break;
             }
-            audio_config_t outputConfig = mixes[i].mFormat;
-            audio_config_t inputConfig = mixes[i].mFormat;
+            audio_config_t outputConfig = mix.mFormat;
+            audio_config_t inputConfig = mix.mFormat;
             // NOTE: audio flinger mixer does not support mono output: configure remote submix HAL in
             // stereo and let audio flinger do the channel conversion if needed.
             outputConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
@@ -2529,31 +2894,35 @@
             rSubmixModule->addInputProfile(address, &inputConfig,
                     AUDIO_DEVICE_IN_REMOTE_SUBMIX, address);
 
-            if (mixes[i].mMixType == MIX_TYPE_PLAYERS) {
-                setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
-                        AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
-                        address.string(), "remote-submix");
-            } else {
-                setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
-                        AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
-                        address.string(), "remote-submix");
+            if ((res = setDeviceConnectionStateInt(deviceTypeToMakeAvailable,
+                    AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
+                    address.string(), "remote-submix", AUDIO_FORMAT_DEFAULT)) != NO_ERROR) {
+                ALOGE("Failed to set remote submix device available, type %u, address %s",
+                        mix.mDeviceType, address.string());
+                break;
             }
-        } else if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
-            String8 address = mixes[i].mDeviceAddress;
-            audio_devices_t device = mixes[i].mDeviceType;
+        } else if ((mix.mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
+            String8 address = mix.mDeviceAddress;
+            audio_devices_t type = mix.mDeviceType;
             ALOGV(" registerPolicyMixes() mix %zu of %zu is RENDER, dev=0x%X addr=%s",
-                    i, mixes.size(), device, address.string());
+                    i, mixes.size(), type, address.string());
+
+            sp<DeviceDescriptor> device = mHwModules.getDeviceDescriptor(
+                    mix.mDeviceType, mix.mDeviceAddress,
+                    String8(), AUDIO_FORMAT_DEFAULT);
+            if (device == nullptr) {
+                res = INVALID_OPERATION;
+                break;
+            }
 
             bool foundOutput = false;
             for (size_t j = 0 ; j < mOutputs.size() ; j++) {
                 sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(j);
-                sp<AudioPatch> patch = mAudioPatches.valueFor(desc->getPatchHandle());
-                if ((patch != 0) && (patch->mPatch.num_sinks != 0)
-                        && (patch->mPatch.sinks[0].type == AUDIO_PORT_TYPE_DEVICE)
-                        && (patch->mPatch.sinks[0].ext.device.type == device)
-                        && (strncmp(patch->mPatch.sinks[0].ext.device.address, address.string(),
-                                AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0)) {
-                    if (mPolicyMixes.registerMix(address, mixes[i], desc) != NO_ERROR) {
+
+                if (desc->supportedDevices().contains(device)) {
+                    if (mPolicyMixes.registerMix(mix, desc) != NO_ERROR) {
+                        ALOGE("Could not register mix RENDER,  dev=0x%X addr=%s", type,
+                              address.string());
                         res = INVALID_OPERATION;
                     } else {
                         foundOutput = true;
@@ -2564,12 +2933,12 @@
 
             if (res != NO_ERROR) {
                 ALOGE(" Error registering mix %zu for device 0x%X addr %s",
-                        i, device, address.string());
+                        i, type, address.string());
                 res = INVALID_OPERATION;
                 break;
             } else if (!foundOutput) {
                 ALOGE(" Output not found for mix %zu for device 0x%X addr %s",
-                        i, device, address.string());
+                        i, type, address.string());
                 res = INVALID_OPERATION;
                 break;
             }
@@ -2601,28 +2970,28 @@
 
             String8 address = mix.mDeviceAddress;
 
-            if (mPolicyMixes.unregisterMix(address) != NO_ERROR) {
+            if (mPolicyMixes.unregisterMix(mix) != NO_ERROR) {
                 res = INVALID_OPERATION;
                 continue;
             }
 
-            if (getDeviceConnectionState(AUDIO_DEVICE_IN_REMOTE_SUBMIX, address.string()) ==
-                    AUDIO_POLICY_DEVICE_STATE_AVAILABLE)  {
-                setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
-                        AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
-                        address.string(), "remote-submix");
-            }
-            if (getDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, address.string()) ==
-                    AUDIO_POLICY_DEVICE_STATE_AVAILABLE)  {
-                setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
-                        AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
-                        address.string(), "remote-submix");
+            for (auto device : {AUDIO_DEVICE_IN_REMOTE_SUBMIX, AUDIO_DEVICE_OUT_REMOTE_SUBMIX}) {
+                if (getDeviceConnectionState(device, address.string()) ==
+                        AUDIO_POLICY_DEVICE_STATE_AVAILABLE)  {
+                    res = setDeviceConnectionStateInt(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
+                                                      address.string(), "remote-submix",
+                                                      AUDIO_FORMAT_DEFAULT);
+                    if (res != OK) {
+                        ALOGE("Error making RemoteSubmix device unavailable for mix "
+                              "with type %d, address %s", device, address.string());
+                    }
+                }
             }
             rSubmixModule->removeOutputProfile(address);
             rSubmixModule->removeInputProfile(address);
 
-        } if ((mix.mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
-            if (mPolicyMixes.unregisterMix(mix.mDeviceAddress) != NO_ERROR) {
+        } else if ((mix.mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
+            if (mPolicyMixes.unregisterMix(mix) != NO_ERROR) {
                 res = INVALID_OPERATION;
                 continue;
             }
@@ -2631,57 +3000,117 @@
     return res;
 }
 
+void AudioPolicyManager::dumpManualSurroundFormats(String8 *dst) const
+{
+    size_t i = 0;
+    constexpr size_t audioFormatPrefixLen = sizeof("AUDIO_FORMAT_");
+    for (const auto& fmt : mManualSurroundFormats) {
+        if (i++ != 0) dst->append(", ");
+        std::string sfmt;
+        FormatConverter::toString(fmt, sfmt);
+        dst->append(sfmt.size() >= audioFormatPrefixLen ?
+                sfmt.c_str() + audioFormatPrefixLen - 1 : sfmt.c_str());
+    }
+}
+
+status_t AudioPolicyManager::setUidDeviceAffinities(uid_t uid,
+        const Vector<AudioDeviceTypeAddr>& devices) {
+    ALOGV("%s() uid=%d num devices %zu", __FUNCTION__, uid, devices.size());
+    // uid/device affinity is only for output devices
+    for (size_t i = 0; i < devices.size(); i++) {
+        if (!audio_is_output_device(devices[i].mType)) {
+            ALOGE("setUidDeviceAffinities() device=%08x is NOT an output device",
+                    devices[i].mType);
+            return BAD_VALUE;
+        }
+    }
+    status_t res =  mPolicyMixes.setUidDeviceAffinities(uid, devices);
+    if (res == NO_ERROR) {
+        // reevaluate outputs for all given devices
+        for (size_t i = 0; i < devices.size(); i++) {
+            sp<DeviceDescriptor> devDesc = mHwModules.getDeviceDescriptor(
+                            devices[i].mType, devices[i].mAddress, String8(),
+                            AUDIO_FORMAT_DEFAULT);
+            SortedVector<audio_io_handle_t> outputs;
+            if (checkOutputsForDevice(devDesc, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
+                    outputs) != NO_ERROR) {
+                ALOGE("setUidDeviceAffinities() error in checkOutputsForDevice for device=%08x"
+                        " addr=%s", devices[i].mType, devices[i].mAddress.string());
+                return INVALID_OPERATION;
+            }
+        }
+    }
+    return res;
+}
+
+status_t AudioPolicyManager::removeUidDeviceAffinities(uid_t uid) {
+    ALOGV("%s() uid=%d", __FUNCTION__, uid);
+    status_t res = mPolicyMixes.removeUidDeviceAffinities(uid);
+    if (res != NO_ERROR) {
+        ALOGE("%s() Could not remove all device affinities fo uid = %d",
+            __FUNCTION__, uid);
+        return INVALID_OPERATION;
+    }
+
+    return res;
+}
+
+void AudioPolicyManager::dump(String8 *dst) const
+{
+    dst->appendFormat("\nAudioPolicyManager Dump: %p\n", this);
+    dst->appendFormat(" Primary Output: %d\n",
+             hasPrimaryOutput() ? mPrimaryOutput->mIoHandle : AUDIO_IO_HANDLE_NONE);
+    std::string stateLiteral;
+    AudioModeConverter::toString(mEngine->getPhoneState(), stateLiteral);
+    dst->appendFormat(" Phone state: %s\n", stateLiteral.c_str());
+    const char* forceUses[AUDIO_POLICY_FORCE_USE_CNT] = {
+        "communications", "media", "record", "dock", "system",
+        "HDMI system audio", "encoded surround output", "vibrate ringing" };
+    for (audio_policy_force_use_t i = AUDIO_POLICY_FORCE_FOR_COMMUNICATION;
+         i < AUDIO_POLICY_FORCE_USE_CNT; i = (audio_policy_force_use_t)((int)i + 1)) {
+        audio_policy_forced_cfg_t forceUseValue = mEngine->getForceUse(i);
+        dst->appendFormat(" Force use for %s: %d", forceUses[i], forceUseValue);
+        if (i == AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND &&
+                forceUseValue == AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL) {
+            dst->append(" (MANUAL: ");
+            dumpManualSurroundFormats(dst);
+            dst->append(")");
+        }
+        dst->append("\n");
+    }
+    dst->appendFormat(" TTS output %savailable\n", mTtsOutputAvailable ? "" : "not ");
+    dst->appendFormat(" Master mono: %s\n", mMasterMono ? "on" : "off");
+    dst->appendFormat(" Config source: %s\n", mConfig.getSource().c_str()); // getConfig not const
+    mAvailableOutputDevices.dump(dst, String8("Available output"));
+    mAvailableInputDevices.dump(dst, String8("Available input"));
+    mHwModulesAll.dump(dst);
+    mOutputs.dump(dst);
+    mInputs.dump(dst);
+    mEffects.dump(dst);
+    mAudioPatches.dump(dst);
+    mPolicyMixes.dump(dst);
+    mAudioSources.dump(dst);
+
+    dst->appendFormat(" AllowedCapturePolicies:\n");
+    for (auto& policy : mAllowedCapturePolicies) {
+        dst->appendFormat("   - uid=%d flag_mask=%#x\n", policy.first, policy.second);
+    }
+
+    dst->appendFormat("\nPolicy Engine dump:\n");
+    mEngine->dump(dst);
+}
 
 status_t AudioPolicyManager::dump(int fd)
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
     String8 result;
-
-    snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this);
-    result.append(buffer);
-
-    snprintf(buffer, SIZE, " Primary Output: %d\n",
-             hasPrimaryOutput() ? mPrimaryOutput->mIoHandle : AUDIO_IO_HANDLE_NONE);
-    result.append(buffer);
-    std::string stateLiteral;
-    AudioModeConverter::toString(mEngine->getPhoneState(), stateLiteral);
-    snprintf(buffer, SIZE, " Phone state: %s\n", stateLiteral.c_str());
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Force use for communications %d\n",
-             mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION));
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Force use for media %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA));
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Force use for record %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD));
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Force use for dock %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_DOCK));
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Force use for system %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM));
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Force use for hdmi system audio %d\n",
-            mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO));
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Force use for encoded surround output %d\n",
-            mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND));
-    result.append(buffer);
-    snprintf(buffer, SIZE, " TTS output %s\n", mTtsOutputAvailable ? "available" : "not available");
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Master mono: %s\n", mMasterMono ? "on" : "off");
-    result.append(buffer);
-
+    dump(&result);
     write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
 
-    mAvailableOutputDevices.dump(fd, String8("Available output"));
-    mAvailableInputDevices.dump(fd, String8("Available input"));
-    mHwModulesAll.dump(fd);
-    mOutputs.dump(fd);
-    mInputs.dump(fd);
-    mVolumeCurves->dump(fd);
-    mEffects.dump(fd);
-    mAudioPatches.dump(fd);
-    mPolicyMixes.dump(fd);
-
+status_t AudioPolicyManager::setAllowedCapturePolicy(uid_t uid, audio_flags_mask_t capturePolicy)
+{
+    mAllowedCapturePolicies[uid] = capturePolicy;
     return NO_ERROR;
 }
 
@@ -2702,12 +3131,9 @@
     }
 
     // Check if offload has been disabled
-    char propValue[PROPERTY_VALUE_MAX];
-    if (property_get("audio.offload.disable", propValue, "0")) {
-        if (atoi(propValue) != 0) {
-            ALOGV("offload disabled by audio.offload.disable=%s", propValue );
-            return false;
-        }
+    if (property_get_bool("audio.offload.disable", false /* default_value */)) {
+        ALOGV("offload disabled by audio.offload.disable");
+        return false;
     }
 
     // Check if stream type is music, then only allow offload as of now.
@@ -2726,9 +3152,12 @@
     }
 
     //If duration is less than minimum value defined in property, return false
-    if (property_get("audio.offload.min.duration.secs", propValue, NULL)) {
-        if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) {
-            ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue);
+    const int min_duration_secs = property_get_int32(
+            "audio.offload.min.duration.secs", -1 /* default_value */);
+    if (min_duration_secs >= 0) {
+        if (offloadInfo.duration_us < min_duration_secs * 1000000LL) {
+            ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%d)",
+                    min_duration_secs);
             return false;
         }
     } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) {
@@ -2748,15 +3177,34 @@
 
     // See if there is a profile to support this.
     // AUDIO_DEVICE_NONE
-    sp<IOProfile> profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */,
+    sp<IOProfile> profile = getProfileForOutput(DeviceVector() /*ignore device */,
                                             offloadInfo.sample_rate,
                                             offloadInfo.format,
                                             offloadInfo.channel_mask,
-                                            AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
+                                            AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD,
+                                            true /* directOnly */);
     ALOGV("isOffloadSupported() profile %sfound", profile != 0 ? "" : "NOT ");
     return (profile != 0);
 }
 
+bool AudioPolicyManager::isDirectOutputSupported(const audio_config_base_t& config,
+                                                 const audio_attributes_t& attributes) {
+    audio_output_flags_t output_flags = AUDIO_OUTPUT_FLAG_NONE;
+    audio_flags_to_audio_output_flags(attributes.flags, &output_flags);
+    sp<IOProfile> profile = getProfileForOutput(DeviceVector() /*ignore device */,
+                                            config.sample_rate,
+                                            config.format,
+                                            config.channel_mask,
+                                            output_flags,
+                                            true /* directOnly */);
+    ALOGV("%s() profile %sfound with name: %s, "
+        "sample rate: %u, format: 0x%x, channel_mask: 0x%x, output flags: 0x%x",
+        __FUNCTION__, profile != 0 ? "" : "NOT ",
+        (profile != 0 ? profile->getTagName().string() : "null"),
+        config.sample_rate, config.format, config.channel_mask, output_flags);
+    return (profile != 0);
+}
+
 status_t AudioPolicyManager::listAudioPorts(audio_port_role_t role,
                                             audio_port_type_t type,
                                             unsigned int *num_ports,
@@ -2865,8 +3313,7 @@
     }
     ALOGV("createAudioPatch() num sources %d num sinks %d", patch->num_sources, patch->num_sinks);
 
-    if (patch->num_sources == 0 || patch->num_sources > AUDIO_PATCH_PORTS_MAX ||
-            patch->num_sinks == 0 || patch->num_sinks > AUDIO_PATCH_PORTS_MAX) {
+    if (!audio_patch_is_valid(patch)) {
         return BAD_VALUE;
     }
     // only one source per audio patch supported for now
@@ -2938,8 +3385,7 @@
                 return BAD_VALUE;
             }
 
-            if (!outputDesc->mProfile->isCompatibleProfile(devDesc->type(),
-                                                           devDesc->mAddress,
+            if (!outputDesc->mProfile->isCompatibleProfile(DeviceVector(devDesc),
                                                            patch->sources[0].sample_rate,
                                                            NULL,  // updatedSamplingRate
                                                            patch->sources[0].format,
@@ -2960,7 +3406,7 @@
         // TODO: reconfigure output format and channels here
         ALOGV("createAudioPatch() setting device %08x on output %d",
               devices.types(), outputDesc->mIoHandle);
-        setOutputDevice(outputDesc, devices.types(), true, 0, handle);
+        setOutputDevices(outputDesc, devices, true, 0, handle);
         index = mAudioPatches.indexOfKey(*handle);
         if (index >= 0) {
             if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) {
@@ -2989,14 +3435,13 @@
                     return BAD_VALUE;
                 }
             }
-            sp<DeviceDescriptor> devDesc =
+            sp<DeviceDescriptor> device =
                     mAvailableInputDevices.getDeviceFromId(patch->sources[0].id);
-            if (devDesc == 0) {
+            if (device == 0) {
                 return BAD_VALUE;
             }
 
-            if (!inputDesc->mProfile->isCompatibleProfile(devDesc->type(),
-                                                          devDesc->mAddress,
+            if (!inputDesc->mProfile->isCompatibleProfile(DeviceVector(device),
                                                           patch->sinks[0].sample_rate,
                                                           NULL, /*updatedSampleRate*/
                                                           patch->sinks[0].format,
@@ -3010,9 +3455,9 @@
                 return INVALID_OPERATION;
             }
             // TODO: reconfigure output format and channels here
-            ALOGV("createAudioPatch() setting device %08x on output %d",
-                                                  devDesc->type(), inputDesc->mIoHandle);
-            setInputDevice(inputDesc->mIoHandle, devDesc->type(), true, handle);
+            ALOGV("%s() setting device %s on output %d", __func__,
+                  device->toString().c_str(), inputDesc->mIoHandle);
+            setInputDevice(inputDesc->mIoHandle, device, true, handle);
             index = mAudioPatches.indexOfKey(*handle);
             if (index >= 0) {
                 if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) {
@@ -3032,16 +3477,16 @@
                     return BAD_VALUE;
                 }
             }
-            sp<DeviceDescriptor> srcDeviceDesc =
+            sp<DeviceDescriptor> srcDevice =
                     mAvailableInputDevices.getDeviceFromId(patch->sources[0].id);
-            if (srcDeviceDesc == 0) {
+            if (srcDevice == 0) {
                 return BAD_VALUE;
             }
 
             //update source and sink with our own data as the data passed in the patch may
             // be incomplete.
             struct audio_patch newPatch = *patch;
-            srcDeviceDesc->toAudioPortConfig(&newPatch.sources[0], &patch->sources[0]);
+            srcDevice->toAudioPortConfig(&newPatch.sources[0], &patch->sources[0]);
 
             for (size_t i = 0; i < patch->num_sinks; i++) {
                 if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
@@ -3049,29 +3494,29 @@
                     return INVALID_OPERATION;
                 }
 
-                sp<DeviceDescriptor> sinkDeviceDesc =
+                sp<DeviceDescriptor> sinkDevice =
                         mAvailableOutputDevices.getDeviceFromId(patch->sinks[i].id);
-                if (sinkDeviceDesc == 0) {
+                if (sinkDevice == 0) {
                     return BAD_VALUE;
                 }
-                sinkDeviceDesc->toAudioPortConfig(&newPatch.sinks[i], &patch->sinks[i]);
+                sinkDevice->toAudioPortConfig(&newPatch.sinks[i], &patch->sinks[i]);
 
                 // create a software bridge in PatchPanel if:
                 // - source and sink devices are on different HW modules OR
                 // - audio HAL version is < 3.0
-                if (!srcDeviceDesc->hasSameHwModuleAs(sinkDeviceDesc) ||
-                        (srcDeviceDesc->mModule->getHalVersionMajor() < 3)) {
+                // - audio HAL version is >= 3.0 but no route has been declared between devices
+                if (!srcDevice->hasSameHwModuleAs(sinkDevice) ||
+                        (srcDevice->getModuleVersionMajor() < 3) ||
+                        !srcDevice->getModule()->supportsPatch(srcDevice, sinkDevice)) {
                     // support only one sink device for now to simplify output selection logic
                     if (patch->num_sinks > 1) {
                         return INVALID_OPERATION;
                     }
                     SortedVector<audio_io_handle_t> outputs =
-                                            getOutputsForDevice(sinkDeviceDesc->type(), mOutputs);
+                            getOutputsForDevices(DeviceVector(sinkDevice), mOutputs);
                     // if the sink device is reachable via an opened output stream, request to go via
                     // this output stream by adding a second source to the patch description
-                    audio_io_handle_t output = selectOutput(outputs,
-                                                            AUDIO_OUTPUT_FLAG_NONE,
-                                                            AUDIO_FORMAT_INVALID);
+                    const audio_io_handle_t output = selectOutput(outputs);
                     if (output != AUDIO_IO_HANDLE_NONE) {
                         sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
                         if (outputDesc->isDuplicated()) {
@@ -3085,28 +3530,8 @@
             }
             // TODO: check from routing capabilities in config file and other conflicting patches
 
-            audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
-            if (index >= 0) {
-                afPatchHandle = patchDesc->mAfPatchHandle;
-            }
-
-            status_t status = mpClientInterface->createAudioPatch(&newPatch,
-                                                                  &afPatchHandle,
-                                                                  0);
-            ALOGV("createAudioPatch() patch panel returned %d patchHandle %d",
-                                                                  status, afPatchHandle);
-            if (status == NO_ERROR) {
-                if (index < 0) {
-                    patchDesc = new AudioPatch(&newPatch, uid);
-                    addAudioPatch(patchDesc->mHandle, patchDesc);
-                } else {
-                    patchDesc->mPatch = newPatch;
-                }
-                patchDesc->mAfPatchHandle = afPatchHandle;
-                *handle = patchDesc->mHandle;
-                nextAudioPortGeneration();
-                mpClientInterface->onAudioPatchListUpdate();
-            } else {
+            status_t status = installPatch(__func__, index, handle, &newPatch, 0, uid, &patchDesc);
+            if (status != NO_ERROR) {
                 ALOGW("createAudioPatch() patch panel could not connect device patch, error %d",
                 status);
                 return INVALID_OPERATION;
@@ -3146,11 +3571,11 @@
             return BAD_VALUE;
         }
 
-        setOutputDevice(outputDesc,
-                        getNewOutputDevice(outputDesc, true /*fromCache*/),
-                       true,
-                       0,
-                       NULL);
+        setOutputDevices(outputDesc,
+                         getNewOutputDevices(outputDesc, true /*fromCache*/),
+                         true,
+                         0,
+                         NULL);
     } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) {
         if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
             sp<AudioInputDescriptor> inputDesc = mInputs.getInputFromId(patch->sinks[0].id);
@@ -3239,10 +3664,10 @@
         return BAD_VALUE;
     }
 
-    struct audio_port_config backupConfig;
+    struct audio_port_config backupConfig = {};
     status_t status = audioPortConfig->applyAudioPortConfig(config, &backupConfig);
     if (status == NO_ERROR) {
-        struct audio_port_config newConfig;
+        struct audio_port_config newConfig = {};
         audioPortConfig->toAudioPortConfig(&newConfig, config);
         status = mpClientInterface->setAudioPortConfig(&newConfig, 0);
     }
@@ -3270,31 +3695,31 @@
     }
 }
 
-void AudioPolicyManager::checkStrategyRoute(routing_strategy strategy,
-                                            audio_io_handle_t ouptutToSkip)
+void AudioPolicyManager::checkStrategyRoute(product_strategy_t ps, audio_io_handle_t ouptutToSkip)
 {
-    audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
-    SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
+    // Take the first attributes following the product strategy as it is used to retrieve the routed
+    // device. All attributes wihin a strategy follows the same "routing strategy"
+    auto attributes = mEngine->getAllAttributesForProductStrategy(ps).front();
+    DeviceVector devices = mEngine->getOutputDevicesForAttributes(attributes, nullptr, false);
+    SortedVector<audio_io_handle_t> outputs = getOutputsForDevices(devices, mOutputs);
     for (size_t j = 0; j < mOutputs.size(); j++) {
         if (mOutputs.keyAt(j) == ouptutToSkip) {
             continue;
         }
         sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(j);
-        if (!isStrategyActive(outputDesc, (routing_strategy)strategy)) {
+        if (!outputDesc->isStrategyActive(ps)) {
             continue;
         }
         // If the default device for this strategy is on another output mix,
         // invalidate all tracks in this strategy to force re connection.
         // Otherwise select new device on the output mix.
         if (outputs.indexOf(mOutputs.keyAt(j)) < 0) {
-            for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
-                if (getStrategy((audio_stream_type_t)stream) == strategy) {
-                    mpClientInterface->invalidateStream((audio_stream_type_t)stream);
-                }
+            for (auto stream : mEngine->getStreamTypesForProductStrategy(ps)) {
+                mpClientInterface->invalidateStream(stream);
             }
         } else {
-            audio_devices_t newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
-            setOutputDevice(outputDesc, newDevice, false);
+            setOutputDevices(
+                        outputDesc, getNewOutputDevices(outputDesc, false /*fromCache*/), false);
         }
     }
 }
@@ -3302,13 +3727,18 @@
 void AudioPolicyManager::clearSessionRoutes(uid_t uid)
 {
     // remove output routes associated with this uid
-    SortedVector<routing_strategy> affectedStrategies;
-    for (ssize_t i = (ssize_t)mOutputRoutes.size() - 1; i >= 0; i--)  {
-        sp<SessionRoute> route = mOutputRoutes.valueAt(i);
-        if (route->mUid == uid) {
-            mOutputRoutes.removeItemsAt(i);
-            if (route->mDeviceDescriptor != 0) {
-                affectedStrategies.add(getStrategy(route->mStreamType));
+    std::vector<product_strategy_t> affectedStrategies;
+    for (size_t i = 0; i < mOutputs.size(); i++) {
+        sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
+        for (const auto& client : outputDesc->getClientIterable()) {
+            if (client->hasPreferredDevice() && client->uid() == uid) {
+                client->setPreferredDeviceId(AUDIO_PORT_HANDLE_NONE);
+                auto clientStrategy = client->strategy();
+                if (std::find(begin(affectedStrategies), end(affectedStrategies), clientStrategy) !=
+                        end(affectedStrategies)) {
+                    continue;
+                }
+                affectedStrategies.push_back(client->strategy());
             }
         }
     }
@@ -3319,12 +3749,12 @@
 
     // remove input routes associated with this uid
     SortedVector<audio_source_t> affectedSources;
-    for (ssize_t i = (ssize_t)mInputRoutes.size() - 1; i >= 0; i--)  {
-        sp<SessionRoute> route = mInputRoutes.valueAt(i);
-        if (route->mUid == uid) {
-            mInputRoutes.removeItemsAt(i);
-            if (route->mDeviceDescriptor != 0) {
-                affectedSources.add(route->mSource);
+    for (size_t i = 0; i < mInputs.size(); i++) {
+        sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(i);
+        for (const auto& client : inputDesc->getClientIterable()) {
+            if (client->hasPreferredDevice() && client->uid() == uid) {
+                client->setPreferredDeviceId(AUDIO_PORT_HANDLE_NONE);
+                affectedSources.add(client->source());
             }
         }
     }
@@ -3332,7 +3762,7 @@
     SortedVector<audio_io_handle_t> inputsToClose;
     for (size_t i = 0; i < mInputs.size(); i++) {
         sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(i);
-        if (affectedSources.indexOf(inputDesc->inputSource()) >= 0) {
+        if (affectedSources.indexOf(inputDesc->source()) >= 0) {
             inputsToClose.add(inputDesc->mIoHandle);
         }
     }
@@ -3344,8 +3774,8 @@
 void AudioPolicyManager::clearAudioSources(uid_t uid)
 {
     for (ssize_t i = (ssize_t)mAudioSources.size() - 1; i >= 0; i--)  {
-        sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueAt(i);
-        if (sourceDesc->mUid == uid) {
+        sp<SourceClientDescriptor> sourceDesc = mAudioSources.valueAt(i);
+        if (sourceDesc->uid() == uid) {
             stopAudioSource(mAudioSources.keyAt(i));
         }
     }
@@ -3357,87 +3787,110 @@
 {
     *session = (audio_session_t)mpClientInterface->newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
     *ioHandle = (audio_io_handle_t)mpClientInterface->newAudioUniqueId(AUDIO_UNIQUE_ID_USE_INPUT);
-    *device = getDeviceAndMixForInputSource(AUDIO_SOURCE_HOTWORD);
+    audio_attributes_t attr = { .source = AUDIO_SOURCE_HOTWORD };
+    *device = mEngine->getInputDeviceForAttributes(attr)->type();
 
     return mSoundTriggerSessions.acquireSession(*session, *ioHandle);
 }
 
 status_t AudioPolicyManager::startAudioSource(const struct audio_port_config *source,
-                                  const audio_attributes_t *attributes,
-                                  audio_patch_handle_t *handle,
-                                  uid_t uid)
+                                              const audio_attributes_t *attributes,
+                                              audio_port_handle_t *portId,
+                                              uid_t uid)
 {
-    ALOGV("%s source %p attributes %p handle %p", __FUNCTION__, source, attributes, handle);
-    if (source == NULL || attributes == NULL || handle == NULL) {
+    ALOGV("%s", __FUNCTION__);
+    *portId = AUDIO_PORT_HANDLE_NONE;
+
+    if (source == NULL || attributes == NULL || portId == NULL) {
+        ALOGW("%s invalid argument: source %p attributes %p handle %p",
+              __FUNCTION__, source, attributes, portId);
         return BAD_VALUE;
     }
 
-    *handle = AUDIO_PATCH_HANDLE_NONE;
-
     if (source->role != AUDIO_PORT_ROLE_SOURCE ||
             source->type != AUDIO_PORT_TYPE_DEVICE) {
-        ALOGV("%s INVALID_OPERATION source->role %d source->type %d", __FUNCTION__, source->role, source->type);
+        ALOGW("%s INVALID_OPERATION source->role %d source->type %d",
+              __FUNCTION__, source->role, source->type);
         return INVALID_OPERATION;
     }
 
-    sp<DeviceDescriptor> srcDeviceDesc =
+    sp<DeviceDescriptor> srcDevice =
             mAvailableInputDevices.getDevice(source->ext.device.type,
-                                              String8(source->ext.device.address));
-    if (srcDeviceDesc == 0) {
-        ALOGV("%s source->ext.device.type %08x not found", __FUNCTION__, source->ext.device.type);
+                                             String8(source->ext.device.address),
+                                             AUDIO_FORMAT_DEFAULT);
+    if (srcDevice == 0) {
+        ALOGW("%s source->ext.device.type %08x not found", __FUNCTION__, source->ext.device.type);
         return BAD_VALUE;
     }
-    sp<AudioSourceDescriptor> sourceDesc =
-            new AudioSourceDescriptor(srcDeviceDesc, attributes, uid);
 
-    struct audio_patch dummyPatch;
+    *portId = AudioPort::getNextUniqueId();
+
+    struct audio_patch dummyPatch = {};
     sp<AudioPatch> patchDesc = new AudioPatch(&dummyPatch, uid);
-    sourceDesc->mPatchDesc = patchDesc;
+
+    sp<SourceClientDescriptor> sourceDesc =
+        new SourceClientDescriptor(*portId, uid, *attributes, patchDesc, srcDevice,
+                                   mEngine->getStreamTypeForAttributes(*attributes),
+                                   mEngine->getProductStrategyForAttributes(*attributes),
+                                   toVolumeSource(*attributes));
 
     status_t status = connectAudioSource(sourceDesc);
     if (status == NO_ERROR) {
-        mAudioSources.add(sourceDesc->getHandle(), sourceDesc);
-        *handle = sourceDesc->getHandle();
+        mAudioSources.add(*portId, sourceDesc);
     }
     return status;
 }
 
-status_t AudioPolicyManager::connectAudioSource(const sp<AudioSourceDescriptor>& sourceDesc)
+status_t AudioPolicyManager::connectAudioSource(const sp<SourceClientDescriptor>& sourceDesc)
 {
-    ALOGV("%s handle %d", __FUNCTION__, sourceDesc->getHandle());
+    ALOGV("%s handle %d", __FUNCTION__, sourceDesc->portId());
 
     // make sure we only have one patch per source.
     disconnectAudioSource(sourceDesc);
 
-    routing_strategy strategy = (routing_strategy) getStrategyForAttr(&sourceDesc->mAttributes);
-    audio_stream_type_t stream = streamTypefromAttributesInt(&sourceDesc->mAttributes);
-    sp<DeviceDescriptor> srcDeviceDesc = sourceDesc->mDevice;
+    audio_attributes_t attributes = sourceDesc->attributes();
+    audio_stream_type_t stream = sourceDesc->stream();
+    sp<DeviceDescriptor> srcDevice = sourceDesc->srcDevice();
 
-    audio_devices_t sinkDevice = getDeviceForStrategy(strategy, true);
-    sp<DeviceDescriptor> sinkDeviceDesc =
-            mAvailableOutputDevices.getDevice(sinkDevice, String8(""));
+    DeviceVector sinkDevices =
+            mEngine->getOutputDevicesForAttributes(attributes, nullptr, true);
+    ALOG_ASSERT(!sinkDevices.isEmpty(), "connectAudioSource(): no device found for attributes");
+    sp<DeviceDescriptor> sinkDevice = sinkDevices.itemAt(0);
+    ALOG_ASSERT(mAvailableOutputDevices.contains(sinkDevice), "%s: Device %s not available",
+                __FUNCTION__, sinkDevice->toString().c_str());
 
     audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
-    struct audio_patch *patch = &sourceDesc->mPatchDesc->mPatch;
 
-    if (srcDeviceDesc->getAudioPort()->mModule->getHandle() ==
-            sinkDeviceDesc->getAudioPort()->mModule->getHandle() &&
-            srcDeviceDesc->getAudioPort()->mModule->getHalVersionMajor() >= 3 &&
-            srcDeviceDesc->getAudioPort()->mGains.size() > 0) {
-        ALOGV("%s AUDIO_DEVICE_API_VERSION_3_0", __FUNCTION__);
+    if (srcDevice->hasSameHwModuleAs(sinkDevice) &&
+            srcDevice->getModuleVersionMajor() >= 3 &&
+            sinkDevice->getModule()->supportsPatch(srcDevice, sinkDevice) &&
+            srcDevice->getAudioPort()->mGains.size() > 0) {
+        ALOGV("%s Device to Device route supported by >=3.0 HAL", __FUNCTION__);
+        // TODO: may explicitly specify whether we should use HW or SW patch
         //   create patch between src device and output device
         //   create Hwoutput and add to mHwOutputs
     } else {
-        SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(sinkDevice, mOutputs);
-        audio_io_handle_t output =
-                selectOutput(outputs, AUDIO_OUTPUT_FLAG_NONE, AUDIO_FORMAT_INVALID);
+        audio_attributes_t resultAttr;
+        audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
+        audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+        config.sample_rate = sourceDesc->config().sample_rate;
+        config.channel_mask = sourceDesc->config().channel_mask;
+        config.format = sourceDesc->config().format;
+        audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE;
+        audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+        bool isRequestedDeviceForExclusiveUse = false;
+        std::vector<sp<SwAudioOutputDescriptor>> secondaryOutputs;
+        getOutputForAttrInt(&resultAttr, &output, AUDIO_SESSION_NONE,
+                &attributes, &stream, sourceDesc->uid(), &config, &flags,
+                &selectedDeviceId, &isRequestedDeviceForExclusiveUse,
+                &secondaryOutputs);
         if (output == AUDIO_IO_HANDLE_NONE) {
-            ALOGV("%s no output for device %08x", __FUNCTION__, sinkDevice);
+            ALOGV("%s no output for device %08x", __FUNCTION__, sinkDevices.types());
             return INVALID_OPERATION;
         }
         sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
         if (outputDesc->isDuplicated()) {
-            ALOGV("%s output for device %08x is duplicated", __FUNCTION__, sinkDevice);
+            ALOGV("%s output for device %08x is duplicated", __FUNCTION__, sinkDevices.types());
             return INVALID_OPERATION;
         }
         status_t status = outputDesc->start();
@@ -3450,51 +3903,58 @@
         // be connected as well as the stream type for volume control
         // - the sink is defined by whatever output device is currently selected for the output
         // though which this patch is routed.
-        patch->num_sinks = 0;
-        patch->num_sources = 2;
-        srcDeviceDesc->toAudioPortConfig(&patch->sources[0], NULL);
-        outputDesc->toAudioPortConfig(&patch->sources[1], NULL);
-        patch->sources[1].ext.mix.usecase.stream = stream;
-        status = mpClientInterface->createAudioPatch(patch,
+        PatchBuilder patchBuilder;
+        patchBuilder.addSource(srcDevice).addSource(outputDesc, { .stream = stream });
+        status = mpClientInterface->createAudioPatch(patchBuilder.patch(),
                                                               &afPatchHandle,
                                                               0);
         ALOGV("%s patch panel returned %d patchHandle %d", __FUNCTION__,
                                                               status, afPatchHandle);
+        sourceDesc->patchDesc()->mPatch = *patchBuilder.patch();
         if (status != NO_ERROR) {
             ALOGW("%s patch panel could not connect device patch, error %d",
                   __FUNCTION__, status);
             return INVALID_OPERATION;
         }
+
+        if (outputDesc->getClient(sourceDesc->portId()) != nullptr) {
+            ALOGW("%s source portId has already been attached to outputDesc", __func__);
+            return INVALID_OPERATION;
+        }
+        outputDesc->addClient(sourceDesc);
+
         uint32_t delayMs = 0;
-        status = startSource(outputDesc, stream, sinkDevice, NULL, &delayMs);
+        status = startSource(outputDesc, sourceDesc, &delayMs);
 
         if (status != NO_ERROR) {
-            mpClientInterface->releaseAudioPatch(sourceDesc->mPatchDesc->mAfPatchHandle, 0);
+            mpClientInterface->releaseAudioPatch(sourceDesc->patchDesc()->mAfPatchHandle, 0);
+            outputDesc->removeClient(sourceDesc->portId());
+            outputDesc->stop();
             return status;
         }
-        sourceDesc->mSwOutput = outputDesc;
+        sourceDesc->setSwOutput(outputDesc);
         if (delayMs != 0) {
             usleep(delayMs * 1000);
         }
     }
 
-    sourceDesc->mPatchDesc->mAfPatchHandle = afPatchHandle;
-    addAudioPatch(sourceDesc->mPatchDesc->mHandle, sourceDesc->mPatchDesc);
+    sourceDesc->patchDesc()->mAfPatchHandle = afPatchHandle;
+    addAudioPatch(sourceDesc->patchDesc()->mHandle, sourceDesc->patchDesc());
 
     return NO_ERROR;
 }
 
-status_t AudioPolicyManager::stopAudioSource(audio_patch_handle_t handle __unused)
+status_t AudioPolicyManager::stopAudioSource(audio_port_handle_t portId)
 {
-    sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueFor(handle);
-    ALOGV("%s handle %d", __FUNCTION__, handle);
+    sp<SourceClientDescriptor> sourceDesc = mAudioSources.valueFor(portId);
+    ALOGV("%s port ID %d", __FUNCTION__, portId);
     if (sourceDesc == 0) {
-        ALOGW("%s unknown source for handle %d", __FUNCTION__, handle);
+        ALOGW("%s unknown source for port ID %d", __FUNCTION__, portId);
         return BAD_VALUE;
     }
     status_t status = disconnectAudioSource(sourceDesc);
 
-    mAudioSources.removeItem(handle);
+    mAudioSources.removeItem(portId);
     return status;
 }
 
@@ -3539,51 +3999,7 @@
 float AudioPolicyManager::getStreamVolumeDB(
         audio_stream_type_t stream, int index, audio_devices_t device)
 {
-    return computeVolume(stream, index, device);
-}
-
-status_t AudioPolicyManager::getSupportedFormats(audio_io_handle_t ioHandle,
-                                                 FormatVector& formats) {
-    if (ioHandle == AUDIO_IO_HANDLE_NONE) {
-        return BAD_VALUE;
-    }
-    String8 reply;
-    reply = mpClientInterface->getParameters(
-            ioHandle, String8(AudioParameter::keyStreamSupportedFormats));
-    ALOGV("%s: supported formats %s", __FUNCTION__, reply.string());
-    AudioParameter repliedParameters(reply);
-    if (repliedParameters.get(
-            String8(AudioParameter::keyStreamSupportedFormats), reply) != NO_ERROR) {
-        ALOGE("%s: failed to retrieve format, bailing out", __FUNCTION__);
-        return BAD_VALUE;
-    }
-    for (auto format : formatsFromString(reply.string())) {
-        // Only AUDIO_FORMAT_AAC_LC will be used in Settings UI for all AAC formats.
-        for (size_t i = 0; i < ARRAY_SIZE(AAC_FORMATS); i++) {
-            if (format == AAC_FORMATS[i]) {
-                format = AUDIO_FORMAT_AAC_LC;
-                break;
-            }
-        }
-        bool exist = false;
-        for (size_t i = 0; i < formats.size(); i++) {
-            if (format == formats[i]) {
-                exist = true;
-                break;
-            }
-        }
-        bool isSurroundFormat = false;
-        for (size_t i = 0; i < ARRAY_SIZE(SURROUND_FORMATS); i++) {
-            if (SURROUND_FORMATS[i] == format) {
-                isSurroundFormat = true;
-                break;
-            }
-        }
-        if (!exist && isSurroundFormat) {
-            formats.add(format);
-        }
-    }
-    return NO_ERROR;
+    return computeVolume(getVolumeCurves(stream), toVolumeSource(stream), index, device);
 }
 
 status_t AudioPolicyManager::getSurroundFormats(unsigned int *numSurroundFormats,
@@ -3595,261 +4011,193 @@
             (surroundFormats == NULL || surroundFormatsEnabled == NULL))) {
         return BAD_VALUE;
     }
-    ALOGV("getSurroundFormats() numSurroundFormats %d surroundFormats %p surroundFormatsEnabled %p",
-            *numSurroundFormats, surroundFormats, surroundFormatsEnabled);
-
-    // Only return value if there is HDMI output.
-    if ((mAvailableOutputDevices.types() & AUDIO_DEVICE_OUT_HDMI) == 0) {
-        return INVALID_OPERATION;
-    }
+    ALOGV("%s() numSurroundFormats %d surroundFormats %p surroundFormatsEnabled %p reported %d",
+            __func__, *numSurroundFormats, surroundFormats, surroundFormatsEnabled, reported);
 
     size_t formatsWritten = 0;
     size_t formatsMax = *numSurroundFormats;
-    *numSurroundFormats = 0;
-    FormatVector formats;
+    std::unordered_set<audio_format_t> formats; // Uses primary surround formats only
     if (reported) {
-        // Only get surround formats which are reported by device.
-        // First list already open outputs that can be routed to this device
-        audio_devices_t device = AUDIO_DEVICE_OUT_HDMI;
-        SortedVector<audio_io_handle_t> outputs;
-        bool reportedFormatFound = false;
-        status_t status;
-        sp<SwAudioOutputDescriptor> desc;
-        for (size_t i = 0; i < mOutputs.size(); i++) {
-            desc = mOutputs.valueAt(i);
-            if (!desc->isDuplicated() && (desc->supportedDevices() & device)) {
-                outputs.add(mOutputs.keyAt(i));
-            }
-        }
-        // Open an output to query dynamic parameters.
-        DeviceVector hdmiOutputDevices = mAvailableOutputDevices.getDevicesFromType(
-                AUDIO_DEVICE_OUT_HDMI);
-        for (size_t i = 0; i < hdmiOutputDevices.size(); i++) {
-            String8 address = hdmiOutputDevices[i]->mAddress;
-            for (const auto& hwModule : mHwModules) {
-                for (size_t i = 0; i < hwModule->getOutputProfiles().size(); i++) {
-                    sp<IOProfile> profile = hwModule->getOutputProfiles()[i];
-                    if (profile->supportDevice(AUDIO_DEVICE_OUT_HDMI) &&
-                            profile->supportDeviceAddress(address)) {
-                        size_t j;
-                        for (j = 0; j < outputs.size(); j++) {
-                            desc = mOutputs.valueFor(outputs.itemAt(j));
-                            if (!desc->isDuplicated() && desc->mProfile == profile) {
-                                break;
-                            }
-                        }
-                        if (j != outputs.size()) {
-                            status = getSupportedFormats(outputs.itemAt(j), formats);
-                            reportedFormatFound |= (status == NO_ERROR);
-                            continue;
-                        }
-
-                        if (!profile->canOpenNewIo()) {
-                            ALOGW("Max Output number %u already opened for this profile %s",
-                                  profile->maxOpenCount, profile->getTagName().c_str());
-                            continue;
-                        }
-
-                        ALOGV("opening output for device %08x with params %s profile %p name %s",
-                              device, address.string(), profile.get(), profile->getName().string());
-                        desc = new SwAudioOutputDescriptor(profile, mpClientInterface);
-                        audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
-                        status_t status = desc->open(nullptr, device, address,
-                                                     AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE,
-                                                     &output);
-
-                        if (status == NO_ERROR) {
-                            status = getSupportedFormats(output, formats);
-                            reportedFormatFound |= (status == NO_ERROR);
-                            desc->close();
-                            output = AUDIO_IO_HANDLE_NONE;
+        // Return formats from all device profiles that have already been resolved by
+        // checkOutputsForDevice().
+        for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) {
+            sp<DeviceDescriptor> device = mAvailableOutputDevices[i];
+            FormatVector supportedFormats =
+                    device->getAudioPort()->getAudioProfiles().getSupportedFormats();
+            for (size_t j = 0; j < supportedFormats.size(); j++) {
+                if (mConfig.getSurroundFormats().count(supportedFormats[j]) != 0) {
+                    formats.insert(supportedFormats[j]);
+                } else {
+                    for (const auto& pair : mConfig.getSurroundFormats()) {
+                        if (pair.second.count(supportedFormats[j]) != 0) {
+                            formats.insert(pair.first);
+                            break;
                         }
                     }
                 }
             }
         }
-
-        if (!reportedFormatFound) {
-            return UNKNOWN_ERROR;
-        }
     } else {
-        for (size_t i = 0; i < ARRAY_SIZE(SURROUND_FORMATS); i++) {
-            formats.add(SURROUND_FORMATS[i]);
+        for (const auto& pair : mConfig.getSurroundFormats()) {
+            formats.insert(pair.first);
         }
     }
-    for (size_t i = 0; i < formats.size(); i++) {
+    *numSurroundFormats = formats.size();
+    audio_policy_forced_cfg_t forceUse = mEngine->getForceUse(
+            AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND);
+    for (const auto& format: formats) {
         if (formatsWritten < formatsMax) {
-            surroundFormats[formatsWritten] = formats[i];
-            bool formatEnabled = false;
-            if (formats[i] == AUDIO_FORMAT_AAC_LC) {
-                for (size_t j = 0; j < ARRAY_SIZE(AAC_FORMATS); j++) {
-                    formatEnabled =
-                            mSurroundFormats.find(AAC_FORMATS[i]) != mSurroundFormats.end();
+            surroundFormats[formatsWritten] = format;
+            bool formatEnabled = true;
+            switch (forceUse) {
+                case AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL:
+                    formatEnabled = mManualSurroundFormats.count(format) != 0;
                     break;
-                }
-            } else {
-                formatEnabled = mSurroundFormats.find(formats[i]) != mSurroundFormats.end();
+                case AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER:
+                    formatEnabled = false;
+                    break;
+                default: // AUTO or ALWAYS => true
+                    break;
             }
             surroundFormatsEnabled[formatsWritten++] = formatEnabled;
         }
-        (*numSurroundFormats)++;
     }
     return NO_ERROR;
 }
 
 status_t AudioPolicyManager::setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled)
 {
-    // Check if audio format is a surround formats.
-    bool isSurroundFormat = false;
-    for (size_t i = 0; i < ARRAY_SIZE(SURROUND_FORMATS); i++) {
-        if (audioFormat == SURROUND_FORMATS[i]) {
-            isSurroundFormat = true;
-            break;
-        }
-    }
-    if (!isSurroundFormat) {
+    ALOGV("%s() format 0x%X enabled %d", __func__, audioFormat, enabled);
+    const auto& formatIter = mConfig.getSurroundFormats().find(audioFormat);
+    if (formatIter == mConfig.getSurroundFormats().end()) {
+        ALOGW("%s() format 0x%X is not a known surround format", __func__, audioFormat);
         return BAD_VALUE;
     }
 
-    // Should only be called when MANUAL.
-    audio_policy_forced_cfg_t forceUse = mEngine->getForceUse(
-                AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND);
-    if (forceUse != AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL) {
+    if (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND) !=
+            AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL) {
+        ALOGW("%s() not in manual mode for surround sound format selection", __func__);
         return INVALID_OPERATION;
     }
 
-    if ((mSurroundFormats.find(audioFormat) != mSurroundFormats.end() && enabled)
-            || (mSurroundFormats.find(audioFormat) == mSurroundFormats.end() && !enabled)) {
+    if ((mManualSurroundFormats.count(audioFormat) != 0) == enabled) {
         return NO_ERROR;
     }
 
-    // The operation is valid only when there is HDMI output available.
-    if ((mAvailableOutputDevices.types() & AUDIO_DEVICE_OUT_HDMI) == 0) {
-        return INVALID_OPERATION;
-    }
-
+    std::unordered_set<audio_format_t> surroundFormatsBackup(mManualSurroundFormats);
     if (enabled) {
-        if (audioFormat == AUDIO_FORMAT_AAC_LC) {
-            for (size_t i = 0; i < ARRAY_SIZE(AAC_FORMATS); i++) {
-                mSurroundFormats.insert(AAC_FORMATS[i]);
-            }
-        } else {
-            mSurroundFormats.insert(audioFormat);
+        mManualSurroundFormats.insert(audioFormat);
+        for (const auto& subFormat : formatIter->second) {
+            mManualSurroundFormats.insert(subFormat);
         }
     } else {
-        if (audioFormat == AUDIO_FORMAT_AAC_LC) {
-            for (size_t i = 0; i < ARRAY_SIZE(AAC_FORMATS); i++) {
-                mSurroundFormats.erase(AAC_FORMATS[i]);
-            }
-        } else {
-            mSurroundFormats.erase(audioFormat);
+        mManualSurroundFormats.erase(audioFormat);
+        for (const auto& subFormat : formatIter->second) {
+            mManualSurroundFormats.erase(subFormat);
         }
     }
 
     sp<SwAudioOutputDescriptor> outputDesc;
     bool profileUpdated = false;
-    DeviceVector hdmiOutputDevices = mAvailableOutputDevices.getDevicesFromType(
+    DeviceVector hdmiOutputDevices = mAvailableOutputDevices.getDevicesFromTypeMask(
             AUDIO_DEVICE_OUT_HDMI);
     for (size_t i = 0; i < hdmiOutputDevices.size(); i++) {
         // Simulate reconnection to update enabled surround sound formats.
-        String8 address = hdmiOutputDevices[i]->mAddress;
+        String8 address = hdmiOutputDevices[i]->address();
         String8 name = hdmiOutputDevices[i]->getName();
         status_t status = setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_HDMI,
                                                       AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
                                                       address.c_str(),
-                                                      name.c_str());
+                                                      name.c_str(),
+                                                      AUDIO_FORMAT_DEFAULT);
         if (status != NO_ERROR) {
             continue;
         }
         status = setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_HDMI,
                                              AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
                                              address.c_str(),
-                                             name.c_str());
+                                             name.c_str(),
+                                             AUDIO_FORMAT_DEFAULT);
         profileUpdated |= (status == NO_ERROR);
     }
-    DeviceVector hdmiInputDevices = mAvailableInputDevices.getDevicesFromType(
+    // FIXME: Why doing this for input HDMI devices if we don't augment their reported formats?
+    DeviceVector hdmiInputDevices = mAvailableInputDevices.getDevicesFromTypeMask(
                 AUDIO_DEVICE_IN_HDMI);
     for (size_t i = 0; i < hdmiInputDevices.size(); i++) {
         // Simulate reconnection to update enabled surround sound formats.
-        String8 address = hdmiInputDevices[i]->mAddress;
+        String8 address = hdmiInputDevices[i]->address();
         String8 name = hdmiInputDevices[i]->getName();
         status_t status = setDeviceConnectionStateInt(AUDIO_DEVICE_IN_HDMI,
                                                       AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
                                                       address.c_str(),
-                                                      name.c_str());
+                                                      name.c_str(),
+                                                      AUDIO_FORMAT_DEFAULT);
         if (status != NO_ERROR) {
             continue;
         }
         status = setDeviceConnectionStateInt(AUDIO_DEVICE_IN_HDMI,
                                              AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
                                              address.c_str(),
-                                             name.c_str());
+                                             name.c_str(),
+                                             AUDIO_FORMAT_DEFAULT);
         profileUpdated |= (status == NO_ERROR);
     }
 
-    // Undo the surround formats change due to no audio profiles updated.
     if (!profileUpdated) {
-        if (enabled) {
-            if (audioFormat == AUDIO_FORMAT_AAC_LC) {
-                for (size_t i = 0; i < ARRAY_SIZE(AAC_FORMATS); i++) {
-                    mSurroundFormats.erase(AAC_FORMATS[i]);
-                }
-            } else {
-                mSurroundFormats.erase(audioFormat);
-            }
-        } else {
-            if (audioFormat == AUDIO_FORMAT_AAC_LC) {
-                for (size_t i = 0; i < ARRAY_SIZE(AAC_FORMATS); i++) {
-                    mSurroundFormats.insert(AAC_FORMATS[i]);
-                }
-            } else {
-                mSurroundFormats.insert(audioFormat);
-            }
-        }
+        ALOGW("%s() no audio profiles updated, undoing surround formats change", __func__);
+        mManualSurroundFormats = std::move(surroundFormatsBackup);
     }
 
     return profileUpdated ? NO_ERROR : INVALID_OPERATION;
 }
 
-void AudioPolicyManager::setRecordSilenced(uid_t uid, bool silenced)
+void AudioPolicyManager::setAppState(uid_t uid, app_state_t state)
 {
-    ALOGV("AudioPolicyManager:setRecordSilenced(uid:%d, silenced:%d)", uid, silenced);
-
-    Vector<sp<AudioInputDescriptor> > activeInputs = mInputs.getActiveInputs();
-    for (size_t i = 0; i < activeInputs.size(); i++) {
-        sp<AudioInputDescriptor> activeDesc = activeInputs[i];
-        AudioSessionCollection activeSessions = activeDesc->getAudioSessions(true);
-        for (size_t j = 0; j < activeSessions.size(); j++) {
-            sp<AudioSession> activeSession = activeSessions.valueAt(j);
-            if (activeSession->uid() == uid) {
-                activeSession->setSilenced(silenced);
-            }
-        }
+    ALOGV("%s(uid:%d, state:%d)", __func__, uid, state);
+    for (size_t i = 0; i < mInputs.size(); i++) {
+        mInputs.valueAt(i)->setAppState(uid, state);
     }
 }
 
-status_t AudioPolicyManager::disconnectAudioSource(const sp<AudioSourceDescriptor>& sourceDesc)
+bool AudioPolicyManager::isHapticPlaybackSupported()
 {
-    ALOGV("%s handle %d", __FUNCTION__, sourceDesc->getHandle());
+    for (const auto& hwModule : mHwModules) {
+        const OutputProfileCollection &outputProfiles = hwModule->getOutputProfiles();
+        for (const auto &outProfile : outputProfiles) {
+            struct audio_port audioPort;
+            outProfile->toAudioPort(&audioPort);
+            for (size_t i = 0; i < audioPort.num_channel_masks; i++) {
+                if (audioPort.channel_masks[i] & AUDIO_CHANNEL_HAPTIC_ALL) {
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+}
 
-    sp<AudioPatch> patchDesc = mAudioPatches.valueFor(sourceDesc->mPatchDesc->mHandle);
+status_t AudioPolicyManager::disconnectAudioSource(const sp<SourceClientDescriptor>& sourceDesc)
+{
+    ALOGV("%s port Id %d", __FUNCTION__, sourceDesc->portId());
+
+    sp<AudioPatch> patchDesc = mAudioPatches.valueFor(sourceDesc->patchDesc()->mHandle);
     if (patchDesc == 0) {
         ALOGW("%s source has no patch with handle %d", __FUNCTION__,
-              sourceDesc->mPatchDesc->mHandle);
+              sourceDesc->patchDesc()->mHandle);
         return BAD_VALUE;
     }
-    removeAudioPatch(sourceDesc->mPatchDesc->mHandle);
+    removeAudioPatch(sourceDesc->patchDesc()->mHandle);
 
-    audio_stream_type_t stream = streamTypefromAttributesInt(&sourceDesc->mAttributes);
-    sp<SwAudioOutputDescriptor> swOutputDesc = sourceDesc->mSwOutput.promote();
+    sp<SwAudioOutputDescriptor> swOutputDesc = sourceDesc->swOutput().promote();
     if (swOutputDesc != 0) {
-        status_t status = stopSource(swOutputDesc, stream, false);
+        status_t status = stopSource(swOutputDesc, sourceDesc);
         if (status == NO_ERROR) {
             swOutputDesc->stop();
         }
+        swOutputDesc->removeClient(sourceDesc->portId());
         mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
     } else {
-        sp<HwAudioOutputDescriptor> hwOutputDesc = sourceDesc->mHwOutput.promote();
+        sp<HwAudioOutputDescriptor> hwOutputDesc = sourceDesc->hwOutput().promote();
         if (hwOutputDesc != 0) {
           //   release patch between src device and output device
           //   close Hwoutput and remove from mHwOutputs
@@ -3860,16 +4208,15 @@
     return NO_ERROR;
 }
 
-sp<AudioSourceDescriptor> AudioPolicyManager::getSourceForStrategyOnOutput(
-        audio_io_handle_t output, routing_strategy strategy)
+sp<SourceClientDescriptor> AudioPolicyManager::getSourceForAttributesOnOutput(
+        audio_io_handle_t output, const audio_attributes_t &attr)
 {
-    sp<AudioSourceDescriptor> source;
+    sp<SourceClientDescriptor> source;
     for (size_t i = 0; i < mAudioSources.size(); i++)  {
-        sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueAt(i);
-        routing_strategy sourceStrategy =
-                (routing_strategy) getStrategyForAttr(&sourceDesc->mAttributes);
-        sp<SwAudioOutputDescriptor> outputDesc = sourceDesc->mSwOutput.promote();
-        if (sourceStrategy == strategy && outputDesc != 0 && outputDesc->mIoHandle == output) {
+        sp<SourceClientDescriptor> sourceDesc = mAudioSources.valueAt(i);
+        sp<SwAudioOutputDescriptor> outputDesc = sourceDesc->swOutput().promote();
+        if (followsSameRouting(attr, sourceDesc->attributes()) &&
+                               outputDesc != 0 && outputDesc->mIoHandle == output) {
             source = sourceDesc;
             break;
         }
@@ -3885,7 +4232,6 @@
     return mAudioPortGeneration++;
 }
 
-#ifdef USE_XML_AUDIO_POLICY_CONF
 // Treblized audio policy xml config will be located in /odm/etc or /vendor/etc.
 static const char *kConfigLocationList[] =
         {"/odm/etc", "/vendor/etc", "/system/etc"};
@@ -3897,52 +4243,50 @@
     std::vector<const char*> fileNames;
     status_t ret;
 
-    if (property_get_bool("ro.bluetooth.a2dp_offload.supported", false) &&
-        property_get_bool("persist.bluetooth.a2dp_offload.disabled", false)) {
-        // A2DP offload supported but disabled: try to use special XML file
-        fileNames.push_back(AUDIO_POLICY_A2DP_OFFLOAD_DISABLED_XML_CONFIG_FILE_NAME);
+    if (property_get_bool("ro.bluetooth.a2dp_offload.supported", false)) {
+        if (property_get_bool("persist.bluetooth.bluetooth_audio_hal.disabled", false) &&
+            property_get_bool("persist.bluetooth.a2dp_offload.disabled", false)) {
+            // Both BluetoothAudio@2.0 and BluetoothA2dp@1.0 (Offlaod) are disabled, and uses
+            // the legacy hardware module for A2DP and hearing aid.
+            fileNames.push_back(AUDIO_POLICY_BLUETOOTH_LEGACY_HAL_XML_CONFIG_FILE_NAME);
+        } else if (property_get_bool("persist.bluetooth.a2dp_offload.disabled", false)) {
+            // A2DP offload supported but disabled: try to use special XML file
+            fileNames.push_back(AUDIO_POLICY_A2DP_OFFLOAD_DISABLED_XML_CONFIG_FILE_NAME);
+        }
+    } else if (property_get_bool("persist.bluetooth.bluetooth_audio_hal.disabled", false)) {
+        fileNames.push_back(AUDIO_POLICY_BLUETOOTH_LEGACY_HAL_XML_CONFIG_FILE_NAME);
     }
     fileNames.push_back(AUDIO_POLICY_XML_CONFIG_FILE_NAME);
 
     for (const char* fileName : fileNames) {
         for (int i = 0; i < kConfigLocationListSize; i++) {
-            PolicySerializer serializer;
             snprintf(audioPolicyXmlConfigFile, sizeof(audioPolicyXmlConfigFile),
                      "%s/%s", kConfigLocationList[i], fileName);
-            ret = serializer.deserialize(audioPolicyXmlConfigFile, config);
+            ret = deserializeAudioPolicyFile(audioPolicyXmlConfigFile, &config);
             if (ret == NO_ERROR) {
+                config.setSource(audioPolicyXmlConfigFile);
                 return ret;
             }
         }
     }
     return ret;
 }
-#endif
 
 AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface,
                                        bool /*forTesting*/)
     :
-    mUidCached(getuid()),
+    mUidCached(AID_AUDIOSERVER), // no need to call getuid(), there's only one of us running.
     mpClientInterface(clientInterface),
     mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
     mA2dpSuspended(false),
-#ifdef USE_XML_AUDIO_POLICY_CONF
-    mVolumeCurves(new VolumeCurvesCollection()),
-    mConfig(mHwModulesAll, mAvailableOutputDevices, mAvailableInputDevices,
-            mDefaultOutputDevice, static_cast<VolumeCurvesCollection*>(mVolumeCurves.get())),
-#else
-    mVolumeCurves(new StreamDescriptorCollection()),
-    mConfig(mHwModulesAll, mAvailableOutputDevices, mAvailableInputDevices,
-            mDefaultOutputDevice),
-#endif
+    mConfig(mHwModulesAll, mAvailableOutputDevices, mAvailableInputDevices, mDefaultOutputDevice),
     mAudioPortGeneration(1),
     mBeaconMuteRefCount(0),
     mBeaconPlayingRefCount(0),
     mBeaconMuted(false),
     mTtsOutputAvailable(false),
     mMasterMono(false),
-    mMusicEffectOutput(AUDIO_IO_HANDLE_NONE),
-    mHasComputedSoundTriggerSupportsConcurrentCapture(false)
+    mMusicEffectOutput(AUDIO_IO_HANDLE_NONE)
 {
 }
 
@@ -3953,21 +4297,22 @@
     initialize();
 }
 
-void AudioPolicyManager::loadConfig() {
-#ifdef USE_XML_AUDIO_POLICY_CONF
-    if (deserializeAudioPolicyXmlConfig(getConfig()) != NO_ERROR) {
-#else
-    if ((ConfigParsingUtils::loadConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, getConfig()) != NO_ERROR)
-           && (ConfigParsingUtils::loadConfig(AUDIO_POLICY_CONFIG_FILE, getConfig()) != NO_ERROR)) {
+//  This check is to catch any legacy platform updating to Q without having
+//  switched to XML since its deprecation on O.
+// TODO: after Q release, remove this check and flag as XML is now the only
+//        option and all legacy platform should have transitioned to XML.
+#ifndef USE_XML_AUDIO_POLICY_CONF
+#error Audio policy no longer supports legacy .conf configuration format
 #endif
+
+void AudioPolicyManager::loadConfig() {
+    if (deserializeAudioPolicyXmlConfig(getConfig()) != NO_ERROR) {
         ALOGE("could not load audio policy configuration file, setting defaults");
         getConfig().setDefault();
     }
 }
 
 status_t AudioPolicyManager::initialize() {
-    mVolumeCurves->initializeVolumeCurves(getConfig().isSpeakerDrcEnabled());
-
     // Once policy config has been parsed, retrieve an instance of the engine and initialize it.
     audio_policy::EngineInstance *engineInstance = audio_policy::EngineInstance::getInstance();
     if (!engineInstance) {
@@ -3989,8 +4334,6 @@
 
     // mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices
     // open all output streams needed to access attached devices
-    audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types();
-    audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
     for (const auto& hwModule : mHwModulesAll) {
         hwModule->setHandle(mpClientInterface->loadHwModule(hwModule->getName()));
         if (hwModule->getHandle() == AUDIO_MODULE_HANDLE_NONE) {
@@ -4019,51 +4362,49 @@
             if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_DIRECT) != 0) {
                 continue;
             }
-            audio_devices_t profileType = outProfile->getSupportedDevicesType();
-            if ((profileType & mDefaultOutputDevice->type()) != AUDIO_DEVICE_NONE) {
-                profileType = mDefaultOutputDevice->type();
+            const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
+            DeviceVector availProfileDevices = supportedDevices.filter(mAvailableOutputDevices);
+            sp<DeviceDescriptor> supportedDevice = 0;
+            if (supportedDevices.contains(mDefaultOutputDevice)) {
+                supportedDevice = mDefaultOutputDevice;
             } else {
-                // chose first device present in profile's SupportedDevices also part of
-                // outputDeviceTypes
-                profileType = outProfile->getSupportedDeviceForType(outputDeviceTypes);
+                // choose first device present in profile's SupportedDevices also part of
+                // mAvailableOutputDevices.
+                if (availProfileDevices.isEmpty()) {
+                    continue;
+                }
+                supportedDevice = availProfileDevices.itemAt(0);
             }
-            if ((profileType & outputDeviceTypes) == 0) {
+            if (!mAvailableOutputDevices.contains(supportedDevice)) {
                 continue;
             }
             sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
                                                                                  mpClientInterface);
-            const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
-            const DeviceVector &devicesForType = supportedDevices.getDevicesFromType(profileType);
-            String8 address = devicesForType.size() > 0 ? devicesForType.itemAt(0)->mAddress
-                    : String8("");
             audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
-            status_t status = outputDesc->open(nullptr, profileType, address,
-                                           AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
-
+            status_t status = outputDesc->open(nullptr, DeviceVector(supportedDevice),
+                                               AUDIO_STREAM_DEFAULT,
+                                               AUDIO_OUTPUT_FLAG_NONE, &output);
             if (status != NO_ERROR) {
-                ALOGW("Cannot open output stream for device %08x on hw module %s",
-                      outputDesc->mDevice,
-                      hwModule->getName());
-            } else {
-                for (const auto& dev : supportedDevices) {
-                    ssize_t index = mAvailableOutputDevices.indexOf(dev);
-                    // give a valid ID to an attached device once confirmed it is reachable
-                    if (index >= 0 && !mAvailableOutputDevices[index]->isAttached()) {
-                        mAvailableOutputDevices[index]->attach(hwModule);
-                    }
-                }
-                if (mPrimaryOutput == 0 &&
-                        outProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
-                    mPrimaryOutput = outputDesc;
-                }
-                addOutput(output, outputDesc);
-                setOutputDevice(outputDesc,
-                                profileType,
-                                true,
-                                0,
-                                NULL,
-                                address);
+                ALOGW("Cannot open output stream for devices %s on hw module %s",
+                      supportedDevice->toString().c_str(), hwModule->getName());
+                continue;
             }
+            for (const auto &device : availProfileDevices) {
+                // give a valid ID to an attached device once confirmed it is reachable
+                if (!device->isAttached()) {
+                    device->attach(hwModule);
+                }
+            }
+            if (mPrimaryOutput == 0 &&
+                    outProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
+                mPrimaryOutput = outputDesc;
+            }
+            addOutput(output, outputDesc);
+            setOutputDevices(outputDesc,
+                             DeviceVector(supportedDevice),
+                             true,
+                             0,
+                             NULL);
         }
         // open input streams needed to access attached devices to validate
         // mAvailableInputDevices list
@@ -4078,85 +4419,68 @@
                 continue;
             }
             // chose first device present in profile's SupportedDevices also part of
-            // inputDeviceTypes
-            audio_devices_t profileType = inProfile->getSupportedDeviceForType(inputDeviceTypes);
-
-            if ((profileType & inputDeviceTypes) == 0) {
+            // available input devices
+            const DeviceVector &supportedDevices = inProfile->getSupportedDevices();
+            DeviceVector availProfileDevices = supportedDevices.filter(mAvailableInputDevices);
+            if (availProfileDevices.isEmpty()) {
+                ALOGE("%s: Input device list is empty!", __FUNCTION__);
                 continue;
             }
             sp<AudioInputDescriptor> inputDesc =
                     new AudioInputDescriptor(inProfile, mpClientInterface);
 
-            DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(profileType);
-            //   the inputs vector must be of size >= 1, but we don't want to crash here
-            String8 address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress
-                    : String8("");
-            ALOGV("  for input device 0x%x using address %s", profileType, address.string());
-            ALOGE_IF(inputDevices.size() == 0, "Input device list is empty!");
-
             audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
             status_t status = inputDesc->open(nullptr,
-                                              profileType,
-                                              address,
+                                              availProfileDevices.itemAt(0),
                                               AUDIO_SOURCE_MIC,
                                               AUDIO_INPUT_FLAG_NONE,
                                               &input);
-
-            if (status == NO_ERROR) {
-                for (const auto& dev : inProfile->getSupportedDevices()) {
-                    ssize_t index = mAvailableInputDevices.indexOf(dev);
-                    // give a valid ID to an attached device once confirmed it is reachable
-                    if (index >= 0) {
-                        sp<DeviceDescriptor> devDesc = mAvailableInputDevices[index];
-                        if (!devDesc->isAttached()) {
-                            devDesc->attach(hwModule);
-                            devDesc->importAudioPort(inProfile, true);
-                        }
-                    }
-                }
-                inputDesc->close();
-            } else {
-                ALOGW("Cannot open input stream for device %08x on hw module %s",
-                      profileType,
+            if (status != NO_ERROR) {
+                ALOGW("Cannot open input stream for device %s on hw module %s",
+                      availProfileDevices.toString().c_str(),
                       hwModule->getName());
+                continue;
             }
+            for (const auto &device : availProfileDevices) {
+                // give a valid ID to an attached device once confirmed it is reachable
+                if (!device->isAttached()) {
+                    device->attach(hwModule);
+                    device->importAudioPort(inProfile, true);
+                }
+            }
+            inputDesc->close();
         }
     }
     // make sure all attached devices have been allocated a unique ID
-    for (size_t i = 0; i  < mAvailableOutputDevices.size();) {
-        if (!mAvailableOutputDevices[i]->isAttached()) {
-            ALOGW("Output device %08x unreachable", mAvailableOutputDevices[i]->type());
-            mAvailableOutputDevices.remove(mAvailableOutputDevices[i]);
-            continue;
+    auto checkAndSetAvailable = [this](auto& devices) {
+        for (size_t i = 0; i < devices.size();) {
+            const auto &device = devices[i];
+            if (!device->isAttached()) {
+                ALOGW("device %s is unreachable", device->toString().c_str());
+                devices.remove(device);
+                continue;
+            }
+            // Device is now validated and can be appended to the available devices of the engine
+            setEngineDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
+            i++;
         }
-        // The device is now validated and can be appended to the available devices of the engine
-        mEngine->setDeviceConnectionState(mAvailableOutputDevices[i],
-                                          AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
-        i++;
-    }
-    for (size_t i = 0; i  < mAvailableInputDevices.size();) {
-        if (!mAvailableInputDevices[i]->isAttached()) {
-            ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->type());
-            mAvailableInputDevices.remove(mAvailableInputDevices[i]);
-            continue;
-        }
-        // The device is now validated and can be appended to the available devices of the engine
-        mEngine->setDeviceConnectionState(mAvailableInputDevices[i],
-                                          AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
-        i++;
-    }
+    };
+    checkAndSetAvailable(mAvailableOutputDevices);
+    checkAndSetAvailable(mAvailableInputDevices);
+
     // make sure default device is reachable
-    if (mDefaultOutputDevice == 0 || mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) {
-        ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->type());
+    if (mDefaultOutputDevice == 0 || !mAvailableOutputDevices.contains(mDefaultOutputDevice)) {
+        ALOGE_IF(mDefaultOutputDevice != 0, "Default device %s is unreachable",
+                 mDefaultOutputDevice->toString().c_str());
         status = NO_INIT;
     }
     // If microphones address is empty, set it according to device type
-    for (size_t i = 0; i  < mAvailableInputDevices.size(); i++) {
-        if (mAvailableInputDevices[i]->mAddress.isEmpty()) {
+    for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
+        if (mAvailableInputDevices[i]->address().isEmpty()) {
             if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BUILTIN_MIC) {
-                mAvailableInputDevices[i]->mAddress = String8(AUDIO_BOTTOM_MICROPHONE_ADDRESS);
+                mAvailableInputDevices[i]->setAddress(String8(AUDIO_BOTTOM_MICROPHONE_ADDRESS));
             } else if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BACK_MIC) {
-                mAvailableInputDevices[i]->mAddress = String8(AUDIO_BACK_MICROPHONE_ADDRESS);
+                mAvailableInputDevices[i]->setAddress(String8(AUDIO_BACK_MICROPHONE_ADDRESS));
             }
         }
     }
@@ -4166,6 +4490,9 @@
         status = NO_INIT;
     }
 
+    // Silence ALOGV statements
+    property_set("log.tag." LOG_TAG, "D");
+
     updateDevicesAndOutputs();
     return status;
 }
@@ -4184,7 +4511,7 @@
    mInputs.clear();
    mHwModules.clear();
    mHwModulesAll.clear();
-   mSurroundFormats.clear();
+   mManualSurroundFormats.clear();
 }
 
 status_t AudioPolicyManager::initCheck()
@@ -4217,44 +4544,28 @@
     nextAudioPortGeneration();
 }
 
-void AudioPolicyManager::findIoHandlesByAddress(const sp<SwAudioOutputDescriptor>& desc /*in*/,
-        const audio_devices_t device /*in*/,
-        const String8& address /*in*/,
-        SortedVector<audio_io_handle_t>& outputs /*out*/) {
-    sp<DeviceDescriptor> devDesc =
-        desc->mProfile->getSupportedDeviceByAddress(device, address);
-    if (devDesc != 0) {
-        ALOGV("findIoHandlesByAddress(): adding opened output %d on same address %s",
-              desc->mIoHandle, address.string());
-        outputs.add(desc->mIoHandle);
-    }
-}
-
-status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor>& devDesc,
+status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor>& device,
                                                    audio_policy_dev_state_t state,
-                                                   SortedVector<audio_io_handle_t>& outputs,
-                                                   const String8& address)
+                                                   SortedVector<audio_io_handle_t>& outputs)
 {
-    audio_devices_t device = devDesc->type();
+    audio_devices_t deviceType = device->type();
+    const String8 &address = device->address();
     sp<SwAudioOutputDescriptor> desc;
 
-    if (audio_device_is_digital(device)) {
+    if (audio_device_is_digital(deviceType)) {
         // erase all current sample rates, formats and channel masks
-        devDesc->clearAudioProfiles();
+        device->clearAudioProfiles();
     }
 
     if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
         // first list already open outputs that can be routed to this device
         for (size_t i = 0; i < mOutputs.size(); i++) {
             desc = mOutputs.valueAt(i);
-            if (!desc->isDuplicated() && (desc->supportedDevices() & device)) {
-                if (!device_distinguishes_on_address(device)) {
-                    ALOGV("checkOutputsForDevice(): adding opened output %d", mOutputs.keyAt(i));
-                    outputs.add(mOutputs.keyAt(i));
-                } else {
-                    ALOGV("  checking address match due to device 0x%x", device);
-                    findIoHandlesByAddress(desc, device, address, outputs);
-                }
+            if (!desc->isDuplicated() && desc->supportsDevice(device)
+                    && desc->deviceSupportsEncodedFormats(deviceType)) {
+                ALOGV("checkOutputsForDevice(): adding opened output %d on device %s",
+                      mOutputs.keyAt(i), device->toString().c_str());
+                outputs.add(mOutputs.keyAt(i));
             }
         }
         // then look for output profiles that can be routed to this device
@@ -4262,13 +4573,10 @@
         for (const auto& hwModule : mHwModules) {
             for (size_t j = 0; j < hwModule->getOutputProfiles().size(); j++) {
                 sp<IOProfile> profile = hwModule->getOutputProfiles()[j];
-                if (profile->supportDevice(device)) {
-                    if (!device_distinguishes_on_address(device) ||
-                            profile->supportDeviceAddress(address)) {
-                        profiles.add(profile);
-                        ALOGV("checkOutputsForDevice(): adding profile %zu from module %s",
-                                j, hwModule->getName());
-                    }
+                if (profile->supportsDevice(device)) {
+                    profiles.add(profile);
+                    ALOGV("checkOutputsForDevice(): adding profile %zu from module %s",
+                          j, hwModule->getName());
                 }
             }
         }
@@ -4276,7 +4584,7 @@
         ALOGV("  found %zu profiles, %zu outputs", profiles.size(), outputs.size());
 
         if (profiles.isEmpty() && outputs.isEmpty()) {
-            ALOGW("checkOutputsForDevice(): No output available for device %04x", device);
+            ALOGW("checkOutputsForDevice(): No output available for device %04x", deviceType);
             return BAD_VALUE;
         }
 
@@ -4292,8 +4600,8 @@
                 if (!desc->isDuplicated() && desc->mProfile == profile) {
                     // matching profile: save the sample rates, format and channel masks supported
                     // by the profile in our device descriptor
-                    if (audio_device_is_digital(device)) {
-                        devDesc->importAudioPort(profile);
+                    if (audio_device_is_digital(deviceType)) {
+                        device->importAudioPort(profile);
                     }
                     break;
                 }
@@ -4309,16 +4617,16 @@
             }
 
             ALOGV("opening output for device %08x with params %s profile %p name %s",
-                  device, address.string(), profile.get(), profile->getName().string());
+                  deviceType, address.string(), profile.get(), profile->getName().string());
             desc = new SwAudioOutputDescriptor(profile, mpClientInterface);
             audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
-            status_t status = desc->open(nullptr, device, address,
+            status_t status = desc->open(nullptr, DeviceVector(device),
                                          AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
 
             if (status == NO_ERROR) {
                 // Here is where the out_set_parameters() for card & device gets called
                 if (!address.isEmpty()) {
-                    char *param = audio_device_address_to_parameter(device, address);
+                    char *param = audio_device_address_to_parameter(deviceType, address);
                     mpClientInterface->setParameters(output, String8(param));
                     free(param);
                 }
@@ -4337,7 +4645,8 @@
                     config.offload_info.channel_mask = config.channel_mask;
                     config.offload_info.format = config.format;
 
-                    status_t status = desc->open(&config, device, address, AUDIO_STREAM_DEFAULT,
+                    status_t status = desc->open(&config, DeviceVector(device),
+                                                 AUDIO_STREAM_DEFAULT,
                                                  AUDIO_OUTPUT_FLAG_NONE, &output);
                     if (status != NO_ERROR) {
                         output = AUDIO_IO_HANDLE_NONE;
@@ -4346,14 +4655,16 @@
 
                 if (output != AUDIO_IO_HANDLE_NONE) {
                     addOutput(output, desc);
-                    if (device_distinguishes_on_address(device) && address != "0") {
+                    if (device_distinguishes_on_address(deviceType) && address != "0") {
                         sp<AudioPolicyMix> policyMix;
-                        if (mPolicyMixes.getAudioPolicyMix(address, policyMix) != NO_ERROR) {
-                            ALOGE("checkOutputsForDevice() cannot find policy for address %s",
+                        if (mPolicyMixes.getAudioPolicyMix(deviceType, address, policyMix)
+                                == NO_ERROR) {
+                            policyMix->setOutput(desc);
+                            desc->mPolicyMix = policyMix;
+                        } else {
+                            ALOGW("checkOutputsForDevice() cannot find policy for address %s",
                                   address.string());
                         }
-                        policyMix->setOutput(desc);
-                        desc->mPolicyMix = policyMix;
 
                     } else if (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) &&
                                     hasPrimaryOutput()) {
@@ -4385,28 +4696,28 @@
                 output = AUDIO_IO_HANDLE_NONE;
             }
             if (output == AUDIO_IO_HANDLE_NONE) {
-                ALOGW("checkOutputsForDevice() could not open output for device %x", device);
+                ALOGW("checkOutputsForDevice() could not open output for device %x", deviceType);
                 profiles.removeAt(profile_index);
                 profile_index--;
             } else {
                 outputs.add(output);
                 // Load digital format info only for digital devices
-                if (audio_device_is_digital(device)) {
-                    devDesc->importAudioPort(profile);
+                if (audio_device_is_digital(deviceType)) {
+                    device->importAudioPort(profile);
                 }
 
-                if (device_distinguishes_on_address(device)) {
-                    ALOGV("checkOutputsForDevice(): setOutputDevice(dev=0x%x, addr=%s)",
-                            device, address.string());
-                    setOutputDevice(desc, device, true/*force*/, 0/*delay*/,
-                            NULL/*patch handle*/, address.string());
+                if (device_distinguishes_on_address(deviceType)) {
+                    ALOGV("checkOutputsForDevice(): setOutputDevices %s",
+                            device->toString().c_str());
+                    setOutputDevices(desc, DeviceVector(device), true/*force*/, 0/*delay*/,
+                                     NULL/*patch handle*/);
                 }
                 ALOGV("checkOutputsForDevice(): adding output %d", output);
             }
         }
 
         if (profiles.isEmpty()) {
-            ALOGW("checkOutputsForDevice(): No output available for device %04x", device);
+            ALOGW("checkOutputsForDevice(): No output available for device %04x", deviceType);
             return BAD_VALUE;
         }
     } else { // Disconnect
@@ -4415,10 +4726,10 @@
             desc = mOutputs.valueAt(i);
             if (!desc->isDuplicated()) {
                 // exact match on device
-                if (device_distinguishes_on_address(device) &&
-                        (desc->supportedDevices() == device)) {
-                    findIoHandlesByAddress(desc, device, address, outputs);
-                } else if (!(desc->supportedDevices() & mAvailableOutputDevices.types())) {
+                if (device_distinguishes_on_address(deviceType) && desc->supportsDevice(device)
+                        && desc->deviceSupportsEncodedFormats(deviceType)) {
+                    outputs.add(mOutputs.keyAt(i));
+                } else if (!mAvailableOutputDevices.containsAtLeastOne(desc->supportedDevices())) {
                     ALOGV("checkOutputsForDevice(): disconnecting adding output %d",
                             mOutputs.keyAt(i));
                     outputs.add(mOutputs.keyAt(i));
@@ -4429,7 +4740,7 @@
         for (const auto& hwModule : mHwModules) {
             for (size_t j = 0; j < hwModule->getOutputProfiles().size(); j++) {
                 sp<IOProfile> profile = hwModule->getOutputProfiles()[j];
-                if (profile->supportDevice(device)) {
+                if (profile->supportsDevice(device)) {
                     ALOGV("checkOutputsForDevice(): "
                             "clearing direct output profile %zu on module %s",
                             j, hwModule->getName());
@@ -4441,30 +4752,18 @@
     return NO_ERROR;
 }
 
-status_t AudioPolicyManager::checkInputsForDevice(const sp<DeviceDescriptor>& devDesc,
-                                                  audio_policy_dev_state_t state,
-                                                  SortedVector<audio_io_handle_t>& inputs,
-                                                  const String8& address)
+status_t AudioPolicyManager::checkInputsForDevice(const sp<DeviceDescriptor>& device,
+                                                  audio_policy_dev_state_t state)
 {
-    audio_devices_t device = devDesc->type();
     sp<AudioInputDescriptor> desc;
 
-    if (audio_device_is_digital(device)) {
+    if (audio_device_is_digital(device->type())) {
         // erase all current sample rates, formats and channel masks
-        devDesc->clearAudioProfiles();
+        device->clearAudioProfiles();
     }
 
     if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
-        // first list already open inputs that can be routed to this device
-        for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
-            desc = mInputs.valueAt(input_index);
-            if (desc->mProfile->supportDevice(device)) {
-                ALOGV("checkInputsForDevice(): adding opened input %d", mInputs.keyAt(input_index));
-               inputs.add(mInputs.keyAt(input_index));
-            }
-        }
-
-        // then look for input profiles that can be routed to this device
+        // look for input profiles that can be routed to this device
         SortedVector< sp<IOProfile> > profiles;
         for (const auto& hwModule : mHwModules) {
             for (size_t profile_index = 0;
@@ -4472,19 +4771,17 @@
                  profile_index++) {
                 sp<IOProfile> profile = hwModule->getInputProfiles()[profile_index];
 
-                if (profile->supportDevice(device)) {
-                    if (!device_distinguishes_on_address(device) ||
-                            profile->supportDeviceAddress(address)) {
-                        profiles.add(profile);
-                        ALOGV("checkInputsForDevice(): adding profile %zu from module %s",
-                                profile_index, hwModule->getName());
-                    }
+                if (profile->supportsDevice(device)) {
+                    profiles.add(profile);
+                    ALOGV("checkInputsForDevice(): adding profile %zu from module %s",
+                          profile_index, hwModule->getName());
                 }
             }
         }
 
-        if (profiles.isEmpty() && inputs.isEmpty()) {
-            ALOGW("checkInputsForDevice(): No input available for device 0x%X", device);
+        if (profiles.isEmpty()) {
+            ALOGW("%s: No input profile available for device %s",
+                __func__, device->toString().c_str());
             return BAD_VALUE;
         }
 
@@ -4499,8 +4796,8 @@
             for (input_index = 0; input_index < mInputs.size(); input_index++) {
                 desc = mInputs.valueAt(input_index);
                 if (desc->mProfile == profile) {
-                    if (audio_device_is_digital(device)) {
-                        devDesc->importAudioPort(profile);
+                    if (audio_device_is_digital(device->type())) {
+                        device->importAudioPort(profile);
                     }
                     break;
                 }
@@ -4519,14 +4816,14 @@
             audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
             status_t status = desc->open(nullptr,
                                          device,
-                                         address,
                                          AUDIO_SOURCE_MIC,
                                          AUDIO_INPUT_FLAG_NONE,
                                          &input);
 
             if (status == NO_ERROR) {
+                const String8& address = device->address();
                 if (!address.isEmpty()) {
-                    char *param = audio_device_address_to_parameter(device, address);
+                    char *param = audio_device_address_to_parameter(device->type(), address);
                     mpClientInterface->setParameters(input, String8(param));
                     free(param);
                 }
@@ -4537,46 +4834,37 @@
                     input = AUDIO_IO_HANDLE_NONE;
                 }
 
-                if (input != 0) {
+                if (input != AUDIO_IO_HANDLE_NONE) {
                     addInput(input, desc);
                 }
             } // endif input != 0
 
             if (input == AUDIO_IO_HANDLE_NONE) {
-                ALOGW("checkInputsForDevice() could not open input for device 0x%X", device);
+                ALOGW("%s could not open input for device %s", __func__,  
+                       device->toString().c_str());
                 profiles.removeAt(profile_index);
                 profile_index--;
             } else {
-                inputs.add(input);
-                if (audio_device_is_digital(device)) {
-                    devDesc->importAudioPort(profile);
+                if (audio_device_is_digital(device->type())) {
+                    device->importAudioPort(profile);
                 }
                 ALOGV("checkInputsForDevice(): adding input %d", input);
             }
         } // end scan profiles
 
         if (profiles.isEmpty()) {
-            ALOGW("checkInputsForDevice(): No input available for device 0x%X", device);
+            ALOGW("%s: No input available for device %s", __func__,  device->toString().c_str());
             return BAD_VALUE;
         }
     } else {
         // Disconnect
-        // check if one opened input is not needed any more after disconnecting one device
-        for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
-            desc = mInputs.valueAt(input_index);
-            if (!(desc->mProfile->supportDevice(mAvailableInputDevices.types()))) {
-                ALOGV("checkInputsForDevice(): disconnecting adding input %d",
-                      mInputs.keyAt(input_index));
-                inputs.add(mInputs.keyAt(input_index));
-            }
-        }
         // Clear any profiles associated with the disconnected device.
         for (const auto& hwModule : mHwModules) {
             for (size_t profile_index = 0;
                  profile_index < hwModule->getInputProfiles().size();
                  profile_index++) {
                 sp<IOProfile> profile = hwModule->getInputProfiles()[profile_index];
-                if (profile->supportDevice(device)) {
+                if (profile->supportsDevice(device)) {
                     ALOGV("checkInputsForDevice(): clearing direct input profile %zu on module %s",
                             profile_index, hwModule->getName());
                     profile->clearAudioProfiles();
@@ -4593,38 +4881,32 @@
 {
     ALOGV("closeOutput(%d)", output);
 
-    sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
-    if (outputDesc == NULL) {
+    sp<SwAudioOutputDescriptor> closingOutput = mOutputs.valueFor(output);
+    if (closingOutput == NULL) {
         ALOGW("closeOutput() unknown output %d", output);
         return;
     }
-    mPolicyMixes.closeOutput(outputDesc);
+    const bool closingOutputWasActive = closingOutput->isActive();
+    mPolicyMixes.closeOutput(closingOutput);
 
     // look for duplicated outputs connected to the output being removed.
     for (size_t i = 0; i < mOutputs.size(); i++) {
-        sp<SwAudioOutputDescriptor> dupOutputDesc = mOutputs.valueAt(i);
-        if (dupOutputDesc->isDuplicated() &&
-                (dupOutputDesc->mOutput1 == outputDesc ||
-                dupOutputDesc->mOutput2 == outputDesc)) {
-            sp<SwAudioOutputDescriptor> outputDesc2;
-            if (dupOutputDesc->mOutput1 == outputDesc) {
-                outputDesc2 = dupOutputDesc->mOutput2;
-            } else {
-                outputDesc2 = dupOutputDesc->mOutput1;
-            }
+        sp<SwAudioOutputDescriptor> dupOutput = mOutputs.valueAt(i);
+        if (dupOutput->isDuplicated() &&
+                (dupOutput->mOutput1 == closingOutput || dupOutput->mOutput2 == closingOutput)) {
+            sp<SwAudioOutputDescriptor> remainingOutput =
+                dupOutput->mOutput1 == closingOutput ? dupOutput->mOutput2 : dupOutput->mOutput1;
             // As all active tracks on duplicated output will be deleted,
             // and as they were also referenced on the other output, the reference
             // count for their stream type must be adjusted accordingly on
             // the other output.
-            bool wasActive = outputDesc2->isActive();
-            for (int j = 0; j < AUDIO_STREAM_CNT; j++) {
-                int refCount = dupOutputDesc->mRefCount[j];
-                outputDesc2->changeRefCount((audio_stream_type_t)j,-refCount);
-            }
+            const bool wasActive = remainingOutput->isActive();
+            // Note: no-op on the closing output where all clients has already been set inactive
+            dupOutput->setAllClientsInactive();
             // stop() will be a no op if the output is still active but is needed in case all
             // active streams refcounts where cleared above
             if (wasActive) {
-                outputDesc2->stop();
+                remainingOutput->stop();
             }
             audio_io_handle_t duplicatedOutput = mOutputs.keyAt(i);
             ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput);
@@ -4636,7 +4918,7 @@
 
     nextAudioPortGeneration();
 
-    ssize_t index = mAudioPatches.indexOfKey(outputDesc->getPatchHandle());
+    ssize_t index = mAudioPatches.indexOfKey(closingOutput->getPatchHandle());
     if (index >= 0) {
         sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
         (void) /*status_t status*/ mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
@@ -4644,10 +4926,31 @@
         mpClientInterface->onAudioPatchListUpdate();
     }
 
-    outputDesc->close();
+    if (closingOutputWasActive) {
+        closingOutput->stop();
+    }
+    closingOutput->close();
 
     removeOutput(output);
     mPreviousOutputs = mOutputs;
+
+    // MSD patches may have been released to support a non-MSD direct output. Reset MSD patch if
+    // no direct outputs are open.
+    if (!getMsdAudioOutDevices().isEmpty()) {
+        bool directOutputOpen = false;
+        for (size_t i = 0; i < mOutputs.size(); i++) {
+            if (mOutputs[i]->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
+                directOutputOpen = true;
+                break;
+            }
+        }
+        if (!directOutputOpen) {
+            ALOGV("no direct outputs open, reset MSD patch");
+            setMsdPatch();
+        }
+    }
+
+    cleanUpEffectsForIo(output);
 }
 
 void AudioPolicyManager::closeInput(audio_io_handle_t input)
@@ -4662,6 +4965,7 @@
 
     nextAudioPortGeneration();
 
+    sp<DeviceDescriptor> device = inputDesc->getDevice();
     ssize_t index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
     if (index >= 0) {
         sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
@@ -4672,51 +4976,69 @@
 
     inputDesc->close();
     mInputs.removeItem(input);
+
+    DeviceVector primaryInputDevices = availablePrimaryModuleInputDevices();
+    if (primaryInputDevices.contains(device) &&
+            mInputs.activeInputsCountOnDevices(primaryInputDevices) == 0) {
+        SoundTrigger::setCaptureState(false);
+    }
+
+    cleanUpEffectsForIo(input);
 }
 
-SortedVector<audio_io_handle_t> AudioPolicyManager::getOutputsForDevice(
-                                                                audio_devices_t device,
-                                                                const SwAudioOutputCollection& openOutputs)
+SortedVector<audio_io_handle_t> AudioPolicyManager::getOutputsForDevices(
+            const DeviceVector &devices,
+            const SwAudioOutputCollection& openOutputs)
 {
     SortedVector<audio_io_handle_t> outputs;
 
-    ALOGVV("getOutputsForDevice() device %04x", device);
+    ALOGVV("%s() devices %s", __func__, devices.toString().c_str());
     for (size_t i = 0; i < openOutputs.size(); i++) {
-        ALOGVV("output %zu isDuplicated=%d device=%04x",
+        ALOGVV("output %zu isDuplicated=%d device=%s",
                 i, openOutputs.valueAt(i)->isDuplicated(),
-                openOutputs.valueAt(i)->supportedDevices());
-        if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) {
-            ALOGVV("getOutputsForDevice() found output %d", openOutputs.keyAt(i));
+                openOutputs.valueAt(i)->supportedDevices().toString().c_str());
+        if (openOutputs.valueAt(i)->supportsAllDevices(devices)
+                && openOutputs.valueAt(i)->deviceSupportsEncodedFormats(devices.types())) {
+            ALOGVV("%s() found output %d", __func__, openOutputs.keyAt(i));
             outputs.add(openOutputs.keyAt(i));
         }
     }
     return outputs;
 }
 
-bool AudioPolicyManager::vectorsEqual(SortedVector<audio_io_handle_t>& outputs1,
-                                      SortedVector<audio_io_handle_t>& outputs2)
+void AudioPolicyManager::checkForDeviceAndOutputChanges(std::function<bool()> onOutputsChecked)
 {
-    if (outputs1.size() != outputs2.size()) {
-        return false;
+    // checkA2dpSuspend must run before checkOutputForAllStrategies so that A2DP
+    // output is suspended before any tracks are moved to it
+    checkA2dpSuspend();
+    checkOutputForAllStrategies();
+    checkSecondaryOutputs();
+    if (onOutputsChecked != nullptr && onOutputsChecked()) checkA2dpSuspend();
+    updateDevicesAndOutputs();
+    if (mHwModules.getModuleFromName(AUDIO_HARDWARE_MODULE_ID_MSD) != 0) {
+        setMsdPatch();
     }
-    for (size_t i = 0; i < outputs1.size(); i++) {
-        if (outputs1[i] != outputs2[i]) {
-            return false;
-        }
-    }
-    return true;
 }
 
-void AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy)
+bool AudioPolicyManager::followsSameRouting(const audio_attributes_t &lAttr,
+                                            const audio_attributes_t &rAttr) const
 {
-    audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/);
-    audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/);
-    SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs);
-    SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs);
+    return mEngine->getProductStrategyForAttributes(lAttr) ==
+            mEngine->getProductStrategyForAttributes(rAttr);
+}
+
+void AudioPolicyManager::checkOutputForAttributes(const audio_attributes_t &attr)
+{
+    auto psId = mEngine->getProductStrategyForAttributes(attr);
+
+    DeviceVector oldDevices = mEngine->getOutputDevicesForAttributes(attr, 0, true /*fromCache*/);
+    DeviceVector newDevices = mEngine->getOutputDevicesForAttributes(attr, 0, false /*fromCache*/);
+    SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevices(oldDevices, mPreviousOutputs);
+    SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevices(newDevices, mOutputs);
 
     // also take into account external policy-related changes: add all outputs which are
     // associated with policies in the "before" and "after" output vectors
-    ALOGVV("checkOutputForStrategy(): policy related outputs");
+    ALOGVV("%s(): policy related outputs", __func__);
     for (size_t i = 0 ; i < mPreviousOutputs.size() ; i++) {
         const sp<SwAudioOutputDescriptor> desc = mPreviousOutputs.valueAt(i);
         if (desc != 0 && desc->mPolicyMix != NULL) {
@@ -4732,7 +5054,7 @@
         }
     }
 
-    if (!vectorsEqual(srcOutputs,dstOutputs)) {
+    if (srcOutputs != dstOutputs) {
         // get maximum latency of all source outputs to determine the minimum mute time guaranteeing
         // audio from invalidated tracks will be rendered when unmuting
         uint32_t maxLatency = 0;
@@ -4742,48 +5064,64 @@
                 maxLatency = desc->latency();
             }
         }
-        ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d",
-              strategy, srcOutputs[0], dstOutputs[0]);
+        ALOGV_IF(!(srcOutputs.isEmpty() || dstOutputs.isEmpty()),
+              "%s: strategy %d, moving from output %s to output %s", __func__, psId,
+              std::to_string(srcOutputs[0]).c_str(),
+              std::to_string(dstOutputs[0]).c_str());
         // mute strategy while moving tracks from one output to another
         for (audio_io_handle_t srcOut : srcOutputs) {
             sp<SwAudioOutputDescriptor> desc = mPreviousOutputs.valueFor(srcOut);
-            if (desc != 0 && isStrategyActive(desc, strategy)) {
-                setStrategyMute(strategy, true, desc);
-                setStrategyMute(strategy, false, desc, maxLatency * LATENCY_MUTE_FACTOR, newDevice);
+            if (desc != 0 && desc->isStrategyActive(psId)) {
+                setStrategyMute(psId, true, desc);
+                setStrategyMute(psId, false, desc, maxLatency * LATENCY_MUTE_FACTOR,
+                                newDevices.types());
             }
-            sp<AudioSourceDescriptor> source =
-                    getSourceForStrategyOnOutput(srcOut, strategy);
+            sp<SourceClientDescriptor> source = getSourceForAttributesOnOutput(srcOut, attr);
             if (source != 0){
                 connectAudioSource(source);
             }
         }
 
-        // Move effects associated to this strategy from previous output to new output
-        if (strategy == STRATEGY_MEDIA) {
+        // Move effects associated to this stream from previous output to new output
+        if (followsSameRouting(attr, attributes_initializer(AUDIO_USAGE_MEDIA))) {
             selectOutputForMusicEffects();
         }
-        // Move tracks associated to this strategy from previous output to new output
-        for (int i = 0; i < AUDIO_STREAM_FOR_POLICY_CNT; i++) {
-            if (getStrategy((audio_stream_type_t)i) == strategy) {
-                mpClientInterface->invalidateStream((audio_stream_type_t)i);
-            }
+        // Move tracks associated to this stream (and linked) from previous output to new output
+        for (auto stream :  mEngine->getStreamTypesForProductStrategy(psId)) {
+            mpClientInterface->invalidateStream(stream);
         }
     }
 }
 
 void AudioPolicyManager::checkOutputForAllStrategies()
 {
-    if (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
-        checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE);
-    checkOutputForStrategy(STRATEGY_PHONE);
-    if (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
-        checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE);
-    checkOutputForStrategy(STRATEGY_SONIFICATION);
-    checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
-    checkOutputForStrategy(STRATEGY_ACCESSIBILITY);
-    checkOutputForStrategy(STRATEGY_MEDIA);
-    checkOutputForStrategy(STRATEGY_DTMF);
-    checkOutputForStrategy(STRATEGY_REROUTING);
+    for (const auto &strategy : mEngine->getOrderedProductStrategies()) {
+        auto attributes = mEngine->getAllAttributesForProductStrategy(strategy).front();
+        checkOutputForAttributes(attributes);
+    }
+}
+
+void AudioPolicyManager::checkSecondaryOutputs() {
+    std::set<audio_stream_type_t> streamsToInvalidate;
+    for (size_t i = 0; i < mOutputs.size(); i++) {
+        const sp<SwAudioOutputDescriptor>& outputDescriptor = mOutputs[i];
+        for (const sp<TrackClientDescriptor>& client : outputDescriptor->getClientIterable()) {
+            sp<SwAudioOutputDescriptor> desc;
+            std::vector<sp<SwAudioOutputDescriptor>> secondaryDescs;
+            status_t status = mPolicyMixes.getOutputForAttr(client->attributes(), client->uid(),
+                                                            client->flags(), desc, &secondaryDescs);
+            if (status != OK ||
+                !std::equal(client->getSecondaryOutputs().begin(),
+                            client->getSecondaryOutputs().end(),
+                            secondaryDescs.begin(), secondaryDescs.end())) {
+                streamsToInvalidate.insert(client->stream());
+            }
+        }
+    }
+    for (audio_stream_type_t stream : streamsToInvalidate) {
+        ALOGD("%s Invalidate stream %d due to secondary output change", __func__, stream);
+        mpClientInterface->invalidateStream(stream);
+    }
 }
 
 void AudioPolicyManager::checkA2dpSuspend()
@@ -4836,108 +5174,87 @@
     }
 }
 
-audio_devices_t AudioPolicyManager::getNewOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
-                                                       bool fromCache)
+DeviceVector AudioPolicyManager::getNewOutputDevices(const sp<SwAudioOutputDescriptor>& outputDesc,
+                                                     bool fromCache)
 {
-    audio_devices_t device = AUDIO_DEVICE_NONE;
+    DeviceVector devices;
 
     ssize_t index = mAudioPatches.indexOfKey(outputDesc->getPatchHandle());
     if (index >= 0) {
         sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
         if (patchDesc->mUid != mUidCached) {
-            ALOGV("getNewOutputDevice() device %08x forced by patch %d",
-                  outputDesc->device(), outputDesc->getPatchHandle());
-            return outputDesc->device();
+            ALOGV("%s device %s forced by patch %d", __func__,
+                  outputDesc->devices().toString().c_str(), outputDesc->getPatchHandle());
+            return  outputDesc->devices();
         }
     }
 
-    // Check if an explicit routing request exists for an active stream on this output and
-    // use it in priority before any other rule
-    for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
-        if (outputDesc->isStreamActive((audio_stream_type_t)stream)) {
-            audio_devices_t forcedDevice =
-                    mOutputRoutes.getActiveDeviceForStream(
-                            (audio_stream_type_t)stream, mAvailableOutputDevices);
+    // Honor explicit routing requests only if no client using default routing is active on this
+    // input: a specific app can not force routing for other apps by setting a preferred device.
+    bool active; // unused
+    sp<DeviceDescriptor> device =
+        findPreferredDevice(outputDesc, PRODUCT_STRATEGY_NONE, active, mAvailableOutputDevices);
+    if (device != nullptr) {
+        return DeviceVector(device);
+    }
 
-            if (forcedDevice != AUDIO_DEVICE_NONE) {
-                return forcedDevice;
-            }
+    // Legacy Engine cannot take care of bus devices and mix, so we need to handle the conflict
+    // of setForceUse / Default Bus device here
+    device = mPolicyMixes.getDeviceAndMixForOutput(outputDesc, mAvailableOutputDevices);
+    if (device != nullptr) {
+        return DeviceVector(device);
+    }
+
+    for (const auto &productStrategy : mEngine->getOrderedProductStrategies()) {
+        StreamTypeVector streams = mEngine->getStreamTypesForProductStrategy(productStrategy);
+        auto attr = mEngine->getAllAttributesForProductStrategy(productStrategy).front();
+
+        if ((hasVoiceStream(streams) &&
+             (isInCall() || mOutputs.isStrategyActiveOnSameModule(productStrategy, outputDesc))) ||
+             ((hasStream(streams, AUDIO_STREAM_ALARM) || hasStream(streams, AUDIO_STREAM_ENFORCED_AUDIBLE)) &&
+                mOutputs.isStrategyActiveOnSameModule(productStrategy, outputDesc)) ||
+                outputDesc->isStrategyActive(productStrategy)) {
+            // Retrieval of devices for voice DL is done on primary output profile, cannot
+            // check the route (would force modifying configuration file for this profile)
+            devices = mEngine->getOutputDevicesForAttributes(attr, nullptr, fromCache);
+            break;
         }
     }
-
-    // check the following by order of priority to request a routing change if necessary:
-    // 1: the strategy enforced audible is active and enforced on the output:
-    //      use device for strategy enforced audible
-    // 2: we are in call or the strategy phone is active on the output:
-    //      use device for strategy phone
-    // 3: the strategy sonification is active on the output:
-    //      use device for strategy sonification
-    // 4: the strategy for enforced audible is active but not enforced on the output:
-    //      use the device for strategy enforced audible
-    // 5: the strategy accessibility is active on the output:
-    //      use device for strategy accessibility
-    // 6: the strategy "respectful" sonification is active on the output:
-    //      use device for strategy "respectful" sonification
-    // 7: the strategy media is active on the output:
-    //      use device for strategy media
-    // 8: the strategy DTMF is active on the output:
-    //      use device for strategy DTMF
-    // 9: the strategy for beacon, a.k.a. "transmitted through speaker" is active on the output:
-    //      use device for strategy t-t-s
-
-    // FIXME: extend use of isStrategyActiveOnSameModule() to all strategies
-    // with a refined rule considering mutually exclusive devices (using same backend)
-    // as opposed to all streams on the same audio HAL module.
-    if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE) &&
-        mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
-        device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
-    } else if (isInCall() ||
-               isStrategyActiveOnSameModule(outputDesc, STRATEGY_PHONE)) {
-        device = getDeviceForStrategy(STRATEGY_PHONE, fromCache);
-    } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION)) {
-        device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);
-    } else if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE)) {
-        device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
-    } else if (isStrategyActive(outputDesc, STRATEGY_ACCESSIBILITY)) {
-        device = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, fromCache);
-    } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION_RESPECTFUL)) {
-        device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache);
-    } else if (isStrategyActive(outputDesc, STRATEGY_MEDIA)) {
-        device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache);
-    } else if (isStrategyActive(outputDesc, STRATEGY_DTMF)) {
-        device = getDeviceForStrategy(STRATEGY_DTMF, fromCache);
-    } else if (isStrategyActive(outputDesc, STRATEGY_TRANSMITTED_THROUGH_SPEAKER)) {
-        device = getDeviceForStrategy(STRATEGY_TRANSMITTED_THROUGH_SPEAKER, fromCache);
-    } else if (isStrategyActive(outputDesc, STRATEGY_REROUTING)) {
-        device = getDeviceForStrategy(STRATEGY_REROUTING, fromCache);
-    }
-
-    ALOGV("getNewOutputDevice() selected device %x", device);
-    return device;
+    ALOGV("%s selected devices %s", __func__, devices.toString().c_str());
+    return devices;
 }
 
-audio_devices_t AudioPolicyManager::getNewInputDevice(const sp<AudioInputDescriptor>& inputDesc)
+sp<DeviceDescriptor> AudioPolicyManager::getNewInputDevice(
+        const sp<AudioInputDescriptor>& inputDesc)
 {
-    audio_devices_t device = AUDIO_DEVICE_NONE;
+    sp<DeviceDescriptor> device;
 
     ssize_t index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
     if (index >= 0) {
         sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
         if (patchDesc->mUid != mUidCached) {
-            ALOGV("getNewInputDevice() device %08x forced by patch %d",
-                  inputDesc->mDevice, inputDesc->getPatchHandle());
-            return inputDesc->mDevice;
+            ALOGV("getNewInputDevice() device %s forced by patch %d",
+                  inputDesc->getDevice()->toString().c_str(), inputDesc->getPatchHandle());
+            return inputDesc->getDevice();
         }
     }
 
-    // If we are not in call and no client is active on this input, this methods returns
-    // AUDIO_DEVICE_NONE, causing the patch on the input stream to be released.
-    audio_source_t source = inputDesc->getHighestPrioritySource(true /*activeOnly*/);
-    if (source == AUDIO_SOURCE_DEFAULT && isInCall()) {
-        source = AUDIO_SOURCE_VOICE_COMMUNICATION;
+    // Honor explicit routing requests only if no client using default routing is active on this
+    // input: a specific app can not force routing for other apps by setting a preferred device.
+    bool active;
+    device = findPreferredDevice(inputDesc, AUDIO_SOURCE_DEFAULT, active, mAvailableInputDevices);
+    if (device != nullptr) {
+        return device;
     }
-    if (source != AUDIO_SOURCE_DEFAULT) {
-        device = getDeviceAndMixForInputSource(source);
+
+    // If we are not in call and no client is active on this input, this methods returns
+    // a null sp<>, causing the patch on the input stream to be released.
+    audio_attributes_t attributes = inputDesc->getHighestPriorityAttributes();
+    if (attributes.source == AUDIO_SOURCE_DEFAULT && isInCall()) {
+        attributes.source = AUDIO_SOURCE_VOICE_COMMUNICATION;
+    }
+    if (attributes.source != AUDIO_SOURCE_DEFAULT) {
+        device = mEngine->getInputDeviceForAttributes(attributes);
     }
 
     return device;
@@ -4948,65 +5265,50 @@
     return (stream1 == stream2);
 }
 
-uint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) {
-    return (uint32_t)getStrategy(stream);
-}
-
 audio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stream) {
     // By checking the range of stream before calling getStrategy, we avoid
-    // getStrategy's behavior for invalid streams.  getStrategy would do a ALOGE
-    // and then return STRATEGY_MEDIA, but we want to return the empty set.
-    if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_PUBLIC_CNT) {
+    // getOutputDevicesForStream's behavior for invalid streams.
+    // engine's getOutputDevicesForStream would fallback on its default behavior (most probably
+    // device for music stream), but we want to return the empty set.
+    if (stream < AUDIO_STREAM_MIN || stream >= AUDIO_STREAM_PUBLIC_CNT) {
         return AUDIO_DEVICE_NONE;
     }
-    audio_devices_t devices = AUDIO_DEVICE_NONE;
-    for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
-        if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
+    DeviceVector activeDevices;
+    DeviceVector devices;
+    for (audio_stream_type_t curStream = AUDIO_STREAM_MIN; curStream < AUDIO_STREAM_PUBLIC_CNT;
+         curStream = (audio_stream_type_t) (curStream + 1)) {
+        if (!streamsMatchForvolume(stream, curStream)) {
             continue;
         }
-        routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream);
-        audio_devices_t curDevices =
-                getDeviceForStrategy((routing_strategy)curStrategy, false /*fromCache*/);
-        for (audio_io_handle_t output : getOutputsForDevice(curDevices, mOutputs)) {
+        DeviceVector curDevices = mEngine->getOutputDevicesForStream(curStream, false/*fromCache*/);
+        devices.merge(curDevices);
+        for (audio_io_handle_t output : getOutputsForDevices(curDevices, mOutputs)) {
             sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
-            if (outputDesc->isStreamActive((audio_stream_type_t)curStream)) {
-                curDevices |= outputDesc->device();
+            if (outputDesc->isActive(toVolumeSource(curStream))) {
+                activeDevices.merge(outputDesc->devices());
             }
         }
-        devices |= curDevices;
     }
 
+    // Favor devices selected on active streams if any to report correct device in case of
+    // explicit device selection
+    if (!activeDevices.isEmpty()) {
+        devices = activeDevices;
+    }
     /*Filter SPEAKER_SAFE out of results, as AudioService doesn't know about it
       and doesn't really need to.*/
-    if (devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
-        devices |= AUDIO_DEVICE_OUT_SPEAKER;
-        devices &= ~AUDIO_DEVICE_OUT_SPEAKER_SAFE;
+    DeviceVector speakerSafeDevices = devices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_SPEAKER_SAFE);
+    if (!speakerSafeDevices.isEmpty()) {
+        devices.merge(mAvailableOutputDevices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_SPEAKER));
+        devices.remove(speakerSafeDevices);
     }
-    return devices;
-}
-
-routing_strategy AudioPolicyManager::getStrategy(audio_stream_type_t stream) const
-{
-    ALOG_ASSERT(stream != AUDIO_STREAM_PATCH,"getStrategy() called for AUDIO_STREAM_PATCH");
-    return mEngine->getStrategyForStream(stream);
-}
-
-uint32_t AudioPolicyManager::getStrategyForAttr(const audio_attributes_t *attr) {
-    // flags to strategy mapping
-    if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) {
-        return (uint32_t) STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
-    }
-    if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
-        return (uint32_t) STRATEGY_ENFORCED_AUDIBLE;
-    }
-    // usage to strategy mapping
-    return static_cast<uint32_t>(mEngine->getStrategyForUsage(attr->usage));
+    return devices.types();
 }
 
 void AudioPolicyManager::handleNotificationRoutingForStream(audio_stream_type_t stream) {
     switch(stream) {
     case AUDIO_STREAM_MUSIC:
-        checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
+        checkOutputForAttributes(attributes_initializer(AUDIO_USAGE_NOTIFICATION));
         updateDevicesAndOutputs();
         break;
     default:
@@ -5057,11 +5359,10 @@
         // mute/unmute AUDIO_STREAM_TTS on all outputs
         ALOGV("\t muting %d", mute);
         uint32_t maxLatency = 0;
+        auto ttsVolumeSource = toVolumeSource(AUDIO_STREAM_TTS);
         for (size_t i = 0; i < mOutputs.size(); i++) {
             sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
-            setStreamMute(AUDIO_STREAM_TTS, mute/*on*/,
-                    desc,
-                    0 /*delay*/, AUDIO_DEVICE_NONE);
+            setVolumeSourceMute(ttsVolumeSource, mute/*on*/, desc, 0 /*delay*/, AUDIO_DEVICE_NONE);
             const uint32_t latency = desc->latency() * 2;
             if (latency > maxLatency) {
                 maxLatency = latency;
@@ -5073,40 +5374,14 @@
     return 0;
 }
 
-audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy,
-                                                         bool fromCache)
-{
-    // Check if an explicit routing request exists for a stream type corresponding to the
-    // specified strategy and use it in priority over default routing rules.
-    for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
-        if (getStrategy((audio_stream_type_t)stream) == strategy) {
-            audio_devices_t forcedDevice =
-                    mOutputRoutes.getActiveDeviceForStream(
-                            (audio_stream_type_t)stream, mAvailableOutputDevices);
-            if (forcedDevice != AUDIO_DEVICE_NONE) {
-                return forcedDevice;
-            }
-        }
-    }
-
-    if (fromCache) {
-        ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x",
-              strategy, mDeviceForStrategy[strategy]);
-        return mDeviceForStrategy[strategy];
-    }
-    return mEngine->getDeviceForStrategy(strategy);
-}
-
 void AudioPolicyManager::updateDevicesAndOutputs()
 {
-    for (int i = 0; i < NUM_STRATEGIES; i++) {
-        mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
-    }
+    mEngine->updateDeviceSelectionCache();
     mPreviousOutputs = mOutputs;
 }
 
 uint32_t AudioPolicyManager::checkDeviceMuteStrategies(const sp<AudioOutputDescriptor>& outputDesc,
-                                                       audio_devices_t prevDevice,
+                                                       const DeviceVector &prevDevices,
                                                        uint32_t delayMs)
 {
     // mute/unmute strategies using an incompatible device combination
@@ -5117,34 +5392,36 @@
     }
 
     uint32_t muteWaitMs = 0;
-    audio_devices_t device = outputDesc->device();
-    bool shouldMute = outputDesc->isActive() && (popcount(device) >= 2);
+    DeviceVector devices = outputDesc->devices();
+    bool shouldMute = outputDesc->isActive() && (devices.size() >= 2);
 
-    for (size_t i = 0; i < NUM_STRATEGIES; i++) {
-        audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
-        curDevice = curDevice & outputDesc->supportedDevices();
-        bool mute = shouldMute && (curDevice & device) && (curDevice != device);
+    auto productStrategies = mEngine->getOrderedProductStrategies();
+    for (const auto &productStrategy : productStrategies) {
+        auto attributes = mEngine->getAllAttributesForProductStrategy(productStrategy).front();
+        DeviceVector curDevices =
+                mEngine->getOutputDevicesForAttributes(attributes, nullptr, false/*fromCache*/);
+        curDevices = curDevices.filter(outputDesc->supportedDevices());
+        bool mute = shouldMute && curDevices.containsAtLeastOne(devices) && curDevices != devices;
         bool doMute = false;
 
-        if (mute && !outputDesc->mStrategyMutedByDevice[i]) {
+        if (mute && !outputDesc->isStrategyMutedByDevice(productStrategy)) {
             doMute = true;
-            outputDesc->mStrategyMutedByDevice[i] = true;
-        } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){
+            outputDesc->setStrategyMutedByDevice(productStrategy, true);
+        } else if (!mute && outputDesc->isStrategyMutedByDevice(productStrategy)) {
             doMute = true;
-            outputDesc->mStrategyMutedByDevice[i] = false;
+            outputDesc->setStrategyMutedByDevice(productStrategy, false);
         }
         if (doMute) {
             for (size_t j = 0; j < mOutputs.size(); j++) {
                 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(j);
                 // skip output if it does not share any device with current output
-                if ((desc->supportedDevices() & outputDesc->supportedDevices())
-                        == AUDIO_DEVICE_NONE) {
+                if (!desc->supportedDevices().containsAtLeastOne(outputDesc->supportedDevices())) {
                     continue;
                 }
-                ALOGVV("checkDeviceMuteStrategies() %s strategy %zu (curDevice %04x)",
-                      mute ? "muting" : "unmuting", i, curDevice);
-                setStrategyMute((routing_strategy)i, mute, desc, mute ? 0 : delayMs);
-                if (isStrategyActive(desc, (routing_strategy)i)) {
+                ALOGVV("%s() %s (curDevice %s)", __func__,
+                      mute ? "muting" : "unmuting", curDevices.toString().c_str());
+                setStrategyMute(productStrategy, mute, desc, mute ? 0 : delayMs);
+                if (desc->isStrategyActive(productStrategy)) {
                     if (mute) {
                         // FIXME: should not need to double latency if volume could be applied
                         // immediately by the audioflinger mixer. We must account for the delay
@@ -5162,22 +5439,19 @@
 
     // temporary mute output if device selection changes to avoid volume bursts due to
     // different per device volumes
-    if (outputDesc->isActive() && (device != prevDevice)) {
+    if (outputDesc->isActive() && (devices != prevDevices)) {
         uint32_t tempMuteWaitMs = outputDesc->latency() * 2;
         // temporary mute duration is conservatively set to 4 times the reported latency
         uint32_t tempMuteDurationMs = outputDesc->latency() * 4;
         if (muteWaitMs < tempMuteWaitMs) {
             muteWaitMs = tempMuteWaitMs;
         }
-
-        for (size_t i = 0; i < NUM_STRATEGIES; i++) {
-            if (isStrategyActive(outputDesc, (routing_strategy)i)) {
-                // make sure that we do not start the temporary mute period too early in case of
-                // delayed device change
-                setStrategyMute((routing_strategy)i, true, outputDesc, delayMs);
-                setStrategyMute((routing_strategy)i, false, outputDesc,
-                                delayMs + tempMuteDurationMs, device);
-            }
+        for (const auto &activeVs : outputDesc->getActiveVolumeSources()) {
+            // make sure that we do not start the temporary mute period too early in case of
+            // delayed device change
+            setVolumeSourceMute(activeVs, true, outputDesc, delayMs);
+            setVolumeSourceMute(activeVs, false, outputDesc, delayMs + tempMuteDurationMs,
+                                devices.types());
         }
     }
 
@@ -5190,46 +5464,46 @@
     return 0;
 }
 
-uint32_t AudioPolicyManager::setOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
-                                             audio_devices_t device,
-                                             bool force,
-                                             int delayMs,
-                                             audio_patch_handle_t *patchHandle,
-                                             const char *address,
-                                             bool requiresMuteCheck)
+uint32_t AudioPolicyManager::setOutputDevices(const sp<SwAudioOutputDescriptor>& outputDesc,
+                                              const DeviceVector &devices,
+                                              bool force,
+                                              int delayMs,
+                                              audio_patch_handle_t *patchHandle,
+                                              bool requiresMuteCheck)
 {
-    ALOGV("setOutputDevice() device %04x delayMs %d", device, delayMs);
-    AudioParameter param;
+    ALOGV("%s device %s delayMs %d", __func__, devices.toString().c_str(), delayMs);
     uint32_t muteWaitMs;
 
     if (outputDesc->isDuplicated()) {
-        muteWaitMs = setOutputDevice(outputDesc->subOutput1(), device, force, delayMs,
-                nullptr /* patchHandle */, nullptr /* address */, requiresMuteCheck);
-        muteWaitMs += setOutputDevice(outputDesc->subOutput2(), device, force, delayMs,
-                nullptr /* patchHandle */, nullptr /* address */, requiresMuteCheck);
+        muteWaitMs = setOutputDevices(outputDesc->subOutput1(), devices, force, delayMs,
+                nullptr /* patchHandle */, requiresMuteCheck);
+        muteWaitMs += setOutputDevices(outputDesc->subOutput2(), devices, force, delayMs,
+                nullptr /* patchHandle */, requiresMuteCheck);
         return muteWaitMs;
     }
-    // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current
-    // output profile
-    if ((device != AUDIO_DEVICE_NONE) &&
-            ((device & outputDesc->supportedDevices()) == AUDIO_DEVICE_NONE)) {
-        return 0;
-    }
 
     // filter devices according to output selected
-    device = (audio_devices_t)(device & outputDesc->supportedDevices());
+    DeviceVector filteredDevices = outputDesc->filterSupportedDevices(devices);
+    DeviceVector prevDevices = outputDesc->devices();
 
-    audio_devices_t prevDevice = outputDesc->mDevice;
+    // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current
+    // output profile or if new device is not supported AND previous device(s) is(are) still
+    // available (otherwise reset device must be done on the output)
+    if (!devices.isEmpty() && filteredDevices.isEmpty() &&
+            !mAvailableOutputDevices.filter(prevDevices).empty()) {
+        ALOGV("%s: unsupported device %s for output", __func__, devices.toString().c_str());
+        return 0;
+    }
 
-    ALOGV("setOutputDevice() prevDevice 0x%04x", prevDevice);
+    ALOGV("setOutputDevices() prevDevice %s", prevDevices.toString().c_str());
 
-    if (device != AUDIO_DEVICE_NONE) {
-        outputDesc->mDevice = device;
+    if (!filteredDevices.isEmpty()) {
+        outputDesc->setDevices(filteredDevices);
     }
 
     // if the outputs are not materially active, there is no need to mute.
     if (requiresMuteCheck) {
-        muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs);
+        muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevices, delayMs);
     } else {
         ALOGV("%s: suppressing checkDeviceMuteStrategies", __func__);
         muteWaitMs = 0;
@@ -5240,89 +5514,32 @@
     //      OR the requested device is the same as current device
     //  AND force is not specified
     //  AND the output is connected by a valid audio patch.
-    // Doing this check here allows the caller to call setOutputDevice() without conditions
-    if ((device == AUDIO_DEVICE_NONE || device == prevDevice) &&
-        !force &&
-        outputDesc->getPatchHandle() != 0) {
-        ALOGV("setOutputDevice() setting same device 0x%04x or null device", device);
+    // Doing this check here allows the caller to call setOutputDevices() without conditions
+    if ((filteredDevices.isEmpty() || filteredDevices == prevDevices) &&
+            !force && outputDesc->getPatchHandle() != 0) {
+        ALOGV("%s setting same device %s or null device, force=%d, patch handle=%d", __func__,
+              filteredDevices.toString().c_str(), force, outputDesc->getPatchHandle());
         return muteWaitMs;
     }
 
-    ALOGV("setOutputDevice() changing device");
+    ALOGV("%s changing device to %s", __func__, filteredDevices.toString().c_str());
 
     // do the routing
-    if (device == AUDIO_DEVICE_NONE) {
+    if (filteredDevices.isEmpty()) {
         resetOutputDevice(outputDesc, delayMs, NULL);
     } else {
-        DeviceVector deviceList;
-        if ((address == NULL) || (strlen(address) == 0)) {
-            deviceList = mAvailableOutputDevices.getDevicesFromType(device);
-        } else {
-            deviceList = mAvailableOutputDevices.getDevicesFromTypeAddr(device, String8(address));
+        PatchBuilder patchBuilder;
+        patchBuilder.addSource(outputDesc);
+        ALOG_ASSERT(filteredDevices.size() <= AUDIO_PATCH_PORTS_MAX, "Too many sink ports");
+        for (const auto &filteredDevice : filteredDevices) {
+            patchBuilder.addSink(filteredDevice);
         }
 
-        if (!deviceList.isEmpty()) {
-            struct audio_patch patch;
-            outputDesc->toAudioPortConfig(&patch.sources[0]);
-            patch.num_sources = 1;
-            patch.num_sinks = 0;
-            for (size_t i = 0; i < deviceList.size() && i < AUDIO_PATCH_PORTS_MAX; i++) {
-                deviceList.itemAt(i)->toAudioPortConfig(&patch.sinks[i]);
-                patch.num_sinks++;
-            }
-            ssize_t index;
-            if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) {
-                index = mAudioPatches.indexOfKey(*patchHandle);
-            } else {
-                index = mAudioPatches.indexOfKey(outputDesc->getPatchHandle());
-            }
-            sp< AudioPatch> patchDesc;
-            audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
-            if (index >= 0) {
-                patchDesc = mAudioPatches.valueAt(index);
-                afPatchHandle = patchDesc->mAfPatchHandle;
-            }
-
-            status_t status = mpClientInterface->createAudioPatch(&patch,
-                                                                   &afPatchHandle,
-                                                                   delayMs);
-            ALOGV("setOutputDevice() createAudioPatch returned %d patchHandle %d"
-                    "num_sources %d num_sinks %d",
-                                       status, afPatchHandle, patch.num_sources, patch.num_sinks);
-            if (status == NO_ERROR) {
-                if (index < 0) {
-                    patchDesc = new AudioPatch(&patch, mUidCached);
-                    addAudioPatch(patchDesc->mHandle, patchDesc);
-                } else {
-                    patchDesc->mPatch = patch;
-                }
-                patchDesc->mAfPatchHandle = afPatchHandle;
-                if (patchHandle) {
-                    *patchHandle = patchDesc->mHandle;
-                }
-                outputDesc->setPatchHandle(patchDesc->mHandle);
-                nextAudioPortGeneration();
-                mpClientInterface->onAudioPatchListUpdate();
-            }
-        }
-
-        // inform all input as well
-        for (size_t i = 0; i < mInputs.size(); i++) {
-            const sp<AudioInputDescriptor>  inputDescriptor = mInputs.valueAt(i);
-            if (!is_virtual_input_device(inputDescriptor->mDevice)) {
-                AudioParameter inputCmd = AudioParameter();
-                ALOGV("%s: inform input %d of device:%d", __func__,
-                      inputDescriptor->mIoHandle, device);
-                inputCmd.addInt(String8(AudioParameter::keyRouting),device);
-                mpClientInterface->setParameters(inputDescriptor->mIoHandle,
-                                                 inputCmd.toString(),
-                                                 delayMs);
-            }
-        }
+        installPatch(__func__, patchHandle, outputDesc.get(), patchBuilder.patch(), delayMs);
     }
 
     // update stream volumes according to new device
-    applyStreamVolumes(outputDesc, device, delayMs);
+    applyStreamVolumes(outputDesc, filteredDevices.types(), delayMs);
 
     return muteWaitMs;
 }
@@ -5351,63 +5568,30 @@
 }
 
 status_t AudioPolicyManager::setInputDevice(audio_io_handle_t input,
-                                            audio_devices_t device,
+                                            const sp<DeviceDescriptor> &device,
                                             bool force,
                                             audio_patch_handle_t *patchHandle)
 {
     status_t status = NO_ERROR;
 
     sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
-    if ((device != AUDIO_DEVICE_NONE) && ((device != inputDesc->mDevice) || force)) {
-        inputDesc->mDevice = device;
+    if ((device != nullptr) && ((device != inputDesc->getDevice()) || force)) {
+        inputDesc->setDevice(device);
 
-        DeviceVector deviceList = mAvailableInputDevices.getDevicesFromType(device);
-        if (!deviceList.isEmpty()) {
-            struct audio_patch patch;
-            inputDesc->toAudioPortConfig(&patch.sinks[0]);
+        if (mAvailableInputDevices.contains(device)) {
+            PatchBuilder patchBuilder;
+            patchBuilder.addSink(inputDesc,
             // AUDIO_SOURCE_HOTWORD is for internal use only:
             // handled as AUDIO_SOURCE_VOICE_RECOGNITION by the audio HAL
-            if (patch.sinks[0].ext.mix.usecase.source == AUDIO_SOURCE_HOTWORD &&
-                    !inputDesc->isSoundTrigger()) {
-                patch.sinks[0].ext.mix.usecase.source = AUDIO_SOURCE_VOICE_RECOGNITION;
-            }
-            patch.num_sinks = 1;
+                    [inputDesc](const PatchBuilder::mix_usecase_t& usecase) {
+                        auto result = usecase;
+                        if (result.source == AUDIO_SOURCE_HOTWORD && !inputDesc->isSoundTrigger()) {
+                            result.source = AUDIO_SOURCE_VOICE_RECOGNITION;
+                        }
+                        return result; }).
             //only one input device for now
-            deviceList.itemAt(0)->toAudioPortConfig(&patch.sources[0]);
-            patch.num_sources = 1;
-            ssize_t index;
-            if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) {
-                index = mAudioPatches.indexOfKey(*patchHandle);
-            } else {
-                index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
-            }
-            sp< AudioPatch> patchDesc;
-            audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
-            if (index >= 0) {
-                patchDesc = mAudioPatches.valueAt(index);
-                afPatchHandle = patchDesc->mAfPatchHandle;
-            }
-
-            status_t status = mpClientInterface->createAudioPatch(&patch,
-                                                                  &afPatchHandle,
-                                                                  0);
-            ALOGV("setInputDevice() createAudioPatch returned %d patchHandle %d",
-                                                                          status, afPatchHandle);
-            if (status == NO_ERROR) {
-                if (index < 0) {
-                    patchDesc = new AudioPatch(&patch, mUidCached);
-                    addAudioPatch(patchDesc->mHandle, patchDesc);
-                } else {
-                    patchDesc->mPatch = patch;
-                }
-                patchDesc->mAfPatchHandle = afPatchHandle;
-                if (patchHandle) {
-                    *patchHandle = patchDesc->mHandle;
-                }
-                inputDesc->setPatchHandle(patchDesc->mHandle);
-                nextAudioPortGeneration();
-                mpClientInterface->onAudioPatchListUpdate();
-            }
+                    addSource(device);
+            status = installPatch(__func__, patchHandle, inputDesc.get(), patchBuilder.patch(), 0);
         }
     }
     return status;
@@ -5436,8 +5620,7 @@
     return status;
 }
 
-sp<IOProfile> AudioPolicyManager::getInputProfile(audio_devices_t device,
-                                                  const String8& address,
+sp<IOProfile> AudioPolicyManager::getInputProfile(const sp<DeviceDescriptor> &device,
                                                   uint32_t& samplingRate,
                                                   audio_format_t& format,
                                                   audio_channel_mask_t& channelMask,
@@ -5457,7 +5640,7 @@
         for (const auto& profile : hwModule->getInputProfiles()) {
             // profile->log();
             //updatedFormat = format;
-            if (profile->isCompatibleProfile(device, address, samplingRate,
+            if (profile->isCompatibleProfile(DeviceVector(device), samplingRate,
                                              &samplingRate  /*updatedSamplingRate*/,
                                              format,
                                              &format,       /*updatedFormat*/
@@ -5468,7 +5651,7 @@
                                              true /*exactMatchRequiredForInputFlags*/)) {
                 return profile;
             }
-            if (firstInexact == nullptr && profile->isCompatibleProfile(device, address,
+            if (firstInexact == nullptr && profile->isCompatibleProfile(DeviceVector(device),
                                              samplingRate,
                                              &updatedSamplingRate,
                                              format,
@@ -5492,83 +5675,60 @@
     return NULL;
 }
 
-
-audio_devices_t AudioPolicyManager::getDeviceAndMixForInputSource(audio_source_t inputSource,
-                                                                  sp<AudioPolicyMix> *policyMix)
-{
-    audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
-    audio_devices_t selectedDeviceFromMix =
-           mPolicyMixes.getDeviceAndMixForInputSource(inputSource, availableDeviceTypes, policyMix);
-
-    if (selectedDeviceFromMix != AUDIO_DEVICE_NONE) {
-        return selectedDeviceFromMix;
-    }
-    return getDeviceForInputSource(inputSource);
-}
-
-audio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource)
-{
-    // Routing
-    // Scan the whole RouteMap to see if we have an explicit route:
-    // if the input source in the RouteMap is the same as the argument above,
-    // and activity count is non-zero and the device in the route descriptor is available
-    // then select this device.
-    for (size_t routeIndex = 0; routeIndex < mInputRoutes.size(); routeIndex++) {
-         sp<SessionRoute> route = mInputRoutes.valueAt(routeIndex);
-         if ((inputSource == route->mSource) && route->isActiveOrChanged() &&
-                 (mAvailableInputDevices.indexOf(route->mDeviceDescriptor) >= 0)) {
-             return route->mDeviceDescriptor->type();
-         }
-     }
-
-     return mEngine->getDeviceForInputSource(inputSource);
-}
-
-float AudioPolicyManager::computeVolume(audio_stream_type_t stream,
+float AudioPolicyManager::computeVolume(IVolumeCurves &curves,
+                                        VolumeSource volumeSource,
                                         int index,
                                         audio_devices_t device)
 {
-    float volumeDB = mVolumeCurves->volIndexToDb(stream, Volume::getDeviceCategory(device), index);
+    float volumeDb = curves.volIndexToDb(Volume::getDeviceCategory(device), index);
 
     // handle the case of accessibility active while a ringtone is playing: if the ringtone is much
     // louder than the accessibility prompt, the prompt cannot be heard, thus masking the touch
     // exploration of the dialer UI. In this situation, bring the accessibility volume closer to
     // the ringtone volume
-    if ((stream == AUDIO_STREAM_ACCESSIBILITY)
-            && (AUDIO_MODE_RINGTONE == mEngine->getPhoneState())
-            && isStreamActive(AUDIO_STREAM_RING, 0)) {
-        const float ringVolumeDB = computeVolume(AUDIO_STREAM_RING, index, device);
-        return ringVolumeDB - 4 > volumeDB ? ringVolumeDB - 4 : volumeDB;
+    const auto callVolumeSrc = toVolumeSource(AUDIO_STREAM_VOICE_CALL);
+    const auto ringVolumeSrc = toVolumeSource(AUDIO_STREAM_RING);
+    const auto musicVolumeSrc = toVolumeSource(AUDIO_STREAM_MUSIC);
+    const auto alarmVolumeSrc = toVolumeSource(AUDIO_STREAM_ALARM);
+
+    if (volumeSource == toVolumeSource(AUDIO_STREAM_ACCESSIBILITY)
+            && (AUDIO_MODE_RINGTONE == mEngine->getPhoneState()) &&
+            mOutputs.isActive(ringVolumeSrc, 0)) {
+        auto &ringCurves = getVolumeCurves(AUDIO_STREAM_RING);
+        const float ringVolumeDb = computeVolume(ringCurves, ringVolumeSrc, index, device);
+        return ringVolumeDb - 4 > volumeDb ? ringVolumeDb - 4 : volumeDb;
     }
 
-    // in-call: always cap earpiece volume by voice volume + some low headroom
-    if ((stream != AUDIO_STREAM_VOICE_CALL) && (device & AUDIO_DEVICE_OUT_EARPIECE) &&
-            (isInCall() || mOutputs.isStreamActiveLocally(AUDIO_STREAM_VOICE_CALL))) {
-        switch (stream) {
-        case AUDIO_STREAM_SYSTEM:
-        case AUDIO_STREAM_RING:
-        case AUDIO_STREAM_MUSIC:
-        case AUDIO_STREAM_ALARM:
-        case AUDIO_STREAM_NOTIFICATION:
-        case AUDIO_STREAM_ENFORCED_AUDIBLE:
-        case AUDIO_STREAM_DTMF:
-        case AUDIO_STREAM_ACCESSIBILITY: {
-            int voiceVolumeIndex =
-                mVolumeCurves->getVolumeIndex(AUDIO_STREAM_VOICE_CALL, AUDIO_DEVICE_OUT_EARPIECE);
-            const float maxVoiceVolDb =
-                computeVolume(AUDIO_STREAM_VOICE_CALL, voiceVolumeIndex, AUDIO_DEVICE_OUT_EARPIECE)
+    // in-call: always cap volume by voice volume + some low headroom
+    if ((volumeSource != callVolumeSrc && (isInCall() ||
+                                           mOutputs.isActiveLocally(callVolumeSrc))) &&
+            (volumeSource == toVolumeSource(AUDIO_STREAM_SYSTEM) ||
+             volumeSource == ringVolumeSrc || volumeSource == musicVolumeSrc ||
+             volumeSource == alarmVolumeSrc ||
+             volumeSource == toVolumeSource(AUDIO_STREAM_NOTIFICATION) ||
+             volumeSource == toVolumeSource(AUDIO_STREAM_ENFORCED_AUDIBLE) ||
+             volumeSource == toVolumeSource(AUDIO_STREAM_DTMF) ||
+             volumeSource == toVolumeSource(AUDIO_STREAM_ACCESSIBILITY))) {
+        auto &voiceCurves = getVolumeCurves(callVolumeSrc);
+        int voiceVolumeIndex = voiceCurves.getVolumeIndex(device);
+        const float maxVoiceVolDb =
+                computeVolume(voiceCurves, callVolumeSrc, voiceVolumeIndex, device)
                 + IN_CALL_EARPIECE_HEADROOM_DB;
-            if (volumeDB > maxVoiceVolDb) {
-                ALOGV("computeVolume() stream %d at vol=%f overriden by stream %d at vol=%f",
-                        stream, volumeDB, AUDIO_STREAM_VOICE_CALL, maxVoiceVolDb);
-                volumeDB = maxVoiceVolDb;
-            }
-            } break;
-        default:
-            break;
+        // FIXME: Workaround for call screening applications until a proper audio mode is defined
+        // to support this scenario : Exempt the RING stream from the audio cap if the audio was
+        // programmatically muted.
+        // VOICE_CALL stream has minVolumeIndex > 0 : Users cannot set the volume of voice calls to
+        // 0. We don't want to cap volume when the system has programmatically muted the voice call
+        // stream. See setVolumeCurveIndex() for more information.
+        bool exemptFromCapping = (volumeSource == ringVolumeSrc) && (voiceVolumeIndex == 0);
+        ALOGV_IF(exemptFromCapping, "%s volume source %d at vol=%f not capped", __func__,
+                 volumeSource, volumeDb);
+        if ((volumeDb > maxVoiceVolDb) && !exemptFromCapping) {
+            ALOGV("%s volume source %d at vol=%f overriden by volume group %d at vol=%f", __func__,
+                  volumeSource, volumeDb, callVolumeSrc, maxVoiceVolDb);
+            volumeDb = maxVoiceVolDb;
         }
     }
-
     // if a headset is connected, apply the following rules to ring tones and notifications
     // to avoid sound level bursts in user's ears:
     // - always attenuate notifications volume by 6dB
@@ -5576,110 +5736,137 @@
     // speaker is part of the select devices
     // - if music is playing, always limit the volume to current music volume,
     // with a minimum threshold at -36dB so that notification is always perceived.
-    const routing_strategy stream_strategy = getStrategy(stream);
-    if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
-            AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
-            AUDIO_DEVICE_OUT_WIRED_HEADSET |
-            AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
-            AUDIO_DEVICE_OUT_USB_HEADSET |
-            AUDIO_DEVICE_OUT_HEARING_AID)) &&
-        ((stream_strategy == STRATEGY_SONIFICATION)
-                || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL)
-                || (stream == AUDIO_STREAM_SYSTEM)
-                || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) &&
-                    (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) &&
-            mVolumeCurves->canBeMuted(stream)) {
+    if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP | AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
+                   AUDIO_DEVICE_OUT_WIRED_HEADSET | AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
+                   AUDIO_DEVICE_OUT_USB_HEADSET | AUDIO_DEVICE_OUT_HEARING_AID)) &&
+            ((volumeSource == alarmVolumeSrc ||
+              volumeSource == ringVolumeSrc) ||
+             (volumeSource == toVolumeSource(AUDIO_STREAM_NOTIFICATION)) ||
+             (volumeSource == toVolumeSource(AUDIO_STREAM_SYSTEM)) ||
+             ((volumeSource == toVolumeSource(AUDIO_STREAM_ENFORCED_AUDIBLE)) &&
+              (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) &&
+            curves.canBeMuted()) {
+
         // when the phone is ringing we must consider that music could have been paused just before
         // by the music application and behave as if music was active if the last music track was
         // just stopped
         if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) ||
                 mLimitRingtoneVolume) {
-            volumeDB += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
-            audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/);
-            float musicVolDB = computeVolume(AUDIO_STREAM_MUSIC,
-                                             mVolumeCurves->getVolumeIndex(AUDIO_STREAM_MUSIC,
-                                                                              musicDevice),
-                                             musicDevice);
-            float minVolDB = (musicVolDB > SONIFICATION_HEADSET_VOLUME_MIN_DB) ?
-                    musicVolDB : SONIFICATION_HEADSET_VOLUME_MIN_DB;
-            if (volumeDB > minVolDB) {
-                volumeDB = minVolDB;
-                ALOGV("computeVolume limiting volume to %f musicVol %f", minVolDB, musicVolDB);
+            volumeDb += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
+            audio_devices_t musicDevice =
+                    mEngine->getOutputDevicesForAttributes(attributes_initializer(AUDIO_USAGE_MEDIA),
+                                                           nullptr, true /*fromCache*/).types();
+            auto &musicCurves = getVolumeCurves(AUDIO_STREAM_MUSIC);
+            float musicVolDb = computeVolume(musicCurves, musicVolumeSrc,
+                                             musicCurves.getVolumeIndex(musicDevice), musicDevice);
+            float minVolDb = (musicVolDb > SONIFICATION_HEADSET_VOLUME_MIN_DB) ?
+                        musicVolDb : SONIFICATION_HEADSET_VOLUME_MIN_DB;
+            if (volumeDb > minVolDb) {
+                volumeDb = minVolDb;
+                ALOGV("computeVolume limiting volume to %f musicVol %f", minVolDb, musicVolDb);
             }
             if (device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
-                    AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES)) {
+                          AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES)) {
                 // on A2DP, also ensure notification volume is not too low compared to media when
                 // intended to be played
-                if ((volumeDB > -96.0f) &&
-                        (musicVolDB - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB > volumeDB)) {
-                    ALOGV("computeVolume increasing volume for stream=%d device=0x%X from %f to %f",
-                            stream, device,
-                            volumeDB, musicVolDB - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB);
-                    volumeDB = musicVolDB - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB;
+                if ((volumeDb > -96.0f) &&
+                        (musicVolDb - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB > volumeDb)) {
+                    ALOGV("%s increasing volume for volume source=%d device=0x%X from %f to %f",
+                          __func__, volumeSource, device, volumeDb,
+                          musicVolDb - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB);
+                    volumeDb = musicVolDb - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB;
                 }
             }
         } else if ((Volume::getDeviceForVolume(device) != AUDIO_DEVICE_OUT_SPEAKER) ||
-                stream_strategy != STRATEGY_SONIFICATION) {
-            volumeDB += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
+                   (!(volumeSource == alarmVolumeSrc || volumeSource == ringVolumeSrc))) {
+            volumeDb += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
         }
     }
 
-    return volumeDB;
+    return volumeDb;
 }
 
-status_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream,
-                                                   int index,
-                                                   const sp<AudioOutputDescriptor>& outputDesc,
-                                                   audio_devices_t device,
-                                                   int delayMs,
-                                                   bool force)
+int AudioPolicyManager::rescaleVolumeIndex(int srcIndex,
+                                           VolumeSource fromVolumeSource,
+                                           VolumeSource toVolumeSource)
 {
-    // do not change actual stream volume if the stream is muted
-    if (outputDesc->mMuteCount[stream] != 0) {
-        ALOGVV("checkAndSetVolume() stream %d muted count %d",
-              stream, outputDesc->mMuteCount[stream]);
+    if (fromVolumeSource == toVolumeSource) {
+        return srcIndex;
+    }
+    auto &srcCurves = getVolumeCurves(fromVolumeSource);
+    auto &dstCurves = getVolumeCurves(toVolumeSource);
+    float minSrc = (float)srcCurves.getVolumeIndexMin();
+    float maxSrc = (float)srcCurves.getVolumeIndexMax();
+    float minDst = (float)dstCurves.getVolumeIndexMin();
+    float maxDst = (float)dstCurves.getVolumeIndexMax();
+
+    // preserve mute request or correct range
+    if (srcIndex < minSrc) {
+        if (srcIndex == 0) {
+            return 0;
+        }
+        srcIndex = minSrc;
+    } else if (srcIndex > maxSrc) {
+        srcIndex = maxSrc;
+    }
+    return (int)(minDst + ((srcIndex - minSrc) * (maxDst - minDst)) / (maxSrc - minSrc));
+}
+
+status_t AudioPolicyManager::checkAndSetVolume(IVolumeCurves &curves,
+                                               VolumeSource volumeSource,
+                                               int index,
+                                               const sp<AudioOutputDescriptor>& outputDesc,
+                                               audio_devices_t device,
+                                               int delayMs,
+                                               bool force)
+{
+    // do not change actual attributes volume if the attributes is muted
+    if (outputDesc->isMuted(volumeSource)) {
+        ALOGVV("%s: volume source %d muted count %d active=%d", __func__, volumeSource,
+               outputDesc->getMuteCount(volumeSource), outputDesc->isActive(volumeSource));
         return NO_ERROR;
     }
+    VolumeSource callVolSrc = toVolumeSource(AUDIO_STREAM_VOICE_CALL);
+    VolumeSource btScoVolSrc = toVolumeSource(AUDIO_STREAM_BLUETOOTH_SCO);
+    bool isVoiceVolSrc = callVolSrc == volumeSource;
+    bool isBtScoVolSrc = btScoVolSrc == volumeSource;
+
     audio_policy_forced_cfg_t forceUseForComm =
             mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION);
     // do not change in call volume if bluetooth is connected and vice versa
-    if ((stream == AUDIO_STREAM_VOICE_CALL && forceUseForComm == AUDIO_POLICY_FORCE_BT_SCO) ||
-        (stream == AUDIO_STREAM_BLUETOOTH_SCO && forceUseForComm != AUDIO_POLICY_FORCE_BT_SCO)) {
-        ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
-             stream, forceUseForComm);
+    // if sco and call follow same curves, bypass forceUseForComm
+    if ((callVolSrc != btScoVolSrc) &&
+            ((isVoiceVolSrc && forceUseForComm == AUDIO_POLICY_FORCE_BT_SCO) ||
+             (isBtScoVolSrc && forceUseForComm != AUDIO_POLICY_FORCE_BT_SCO))) {
+        ALOGV("%s cannot set volume group %d volume with force use = %d for comm", __func__,
+             volumeSource, forceUseForComm);
         return INVALID_OPERATION;
     }
-
     if (device == AUDIO_DEVICE_NONE) {
-        device = outputDesc->device();
+        device = outputDesc->devices().types();
     }
 
-    float volumeDb = computeVolume(stream, index, device);
+    float volumeDb = computeVolume(curves, volumeSource, index, device);
     if (outputDesc->isFixedVolume(device) ||
             // Force VoIP volume to max for bluetooth SCO
-            ((stream == AUDIO_STREAM_VOICE_CALL || stream == AUDIO_STREAM_BLUETOOTH_SCO) &&
-             (device & AUDIO_DEVICE_OUT_ALL_SCO) != 0)) {
+            ((isVoiceVolSrc || isBtScoVolSrc) && (device & AUDIO_DEVICE_OUT_ALL_SCO) != 0)) {
         volumeDb = 0.0f;
     }
+    outputDesc->setVolume(volumeDb, volumeSource, curves.getStreamTypes(), device, delayMs, force);
 
-    outputDesc->setVolume(volumeDb, stream, device, delayMs, force);
-
-    if (stream == AUDIO_STREAM_VOICE_CALL ||
-        stream == AUDIO_STREAM_BLUETOOTH_SCO) {
+    if (isVoiceVolSrc || isBtScoVolSrc) {
         float voiceVolume;
-        // Force voice volume to max for bluetooth SCO as volume is managed by the headset
-        if (stream == AUDIO_STREAM_VOICE_CALL) {
-            voiceVolume = (float)index/(float)mVolumeCurves->getVolumeIndexMax(stream);
+        // Force voice volume to max or mute for Bluetooth SCO as other attenuations are managed by the headset
+        if (isVoiceVolSrc) {
+            voiceVolume = (float)index/(float)curves.getVolumeIndexMax();
         } else {
-            voiceVolume = 1.0;
+            voiceVolume = index == 0 ? 0.0 : 1.0;
         }
-
         if (voiceVolume != mLastVoiceVolume) {
             mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
             mLastVoiceVolume = voiceVolume;
         }
     }
-
     return NO_ERROR;
 }
 
@@ -5689,63 +5876,64 @@
                                                 bool force)
 {
     ALOGVV("applyStreamVolumes() for device %08x", device);
-
-    for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
-        checkAndSetVolume((audio_stream_type_t)stream,
-                          mVolumeCurves->getVolumeIndex((audio_stream_type_t)stream, device),
-                          outputDesc,
-                          device,
-                          delayMs,
-                          force);
+    for (const auto &volumeGroup : mEngine->getVolumeGroups()) {
+        auto &curves = getVolumeCurves(toVolumeSource(volumeGroup));
+        checkAndSetVolume(curves, toVolumeSource(volumeGroup),
+                          curves.getVolumeIndex(device), outputDesc, device, delayMs, force);
     }
 }
 
-void AudioPolicyManager::setStrategyMute(routing_strategy strategy,
+void AudioPolicyManager::setStrategyMute(product_strategy_t strategy,
+                                         bool on,
+                                         const sp<AudioOutputDescriptor>& outputDesc,
+                                         int delayMs,
+                                         audio_devices_t device)
+{
+    std::vector<VolumeSource> sourcesToMute;
+    for (auto attributes: mEngine->getAllAttributesForProductStrategy(strategy)) {
+        ALOGVV("%s() attributes %s, mute %d, output ID %d", __func__,
+               toString(attributes).c_str(), on, outputDesc->getId());
+        VolumeSource source = toVolumeSource(attributes);
+        if (std::find(begin(sourcesToMute), end(sourcesToMute), source) == end(sourcesToMute)) {
+            sourcesToMute.push_back(source);
+        }
+    }
+    for (auto source : sourcesToMute) {
+        setVolumeSourceMute(source, on, outputDesc, delayMs, device);
+    }
+
+}
+
+void AudioPolicyManager::setVolumeSourceMute(VolumeSource volumeSource,
                                              bool on,
                                              const sp<AudioOutputDescriptor>& outputDesc,
                                              int delayMs,
                                              audio_devices_t device)
 {
-    ALOGVV("setStrategyMute() strategy %d, mute %d, output ID %d",
-           strategy, on, outputDesc->getId());
-    for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
-        if (getStrategy((audio_stream_type_t)stream) == strategy) {
-            setStreamMute((audio_stream_type_t)stream, on, outputDesc, delayMs, device);
-        }
-    }
-}
-
-void AudioPolicyManager::setStreamMute(audio_stream_type_t stream,
-                                           bool on,
-                                           const sp<AudioOutputDescriptor>& outputDesc,
-                                           int delayMs,
-                                           audio_devices_t device)
-{
     if (device == AUDIO_DEVICE_NONE) {
-        device = outputDesc->device();
+        device = outputDesc->devices().types();
     }
-
-    ALOGVV("setStreamMute() stream %d, mute %d, mMuteCount %d device %04x",
-          stream, on, outputDesc->mMuteCount[stream], device);
-
+    auto &curves = getVolumeCurves(volumeSource);
     if (on) {
-        if (outputDesc->mMuteCount[stream] == 0) {
-            if (mVolumeCurves->canBeMuted(stream) &&
-                    ((stream != AUDIO_STREAM_ENFORCED_AUDIBLE) ||
-                     (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) {
-                checkAndSetVolume(stream, 0, outputDesc, device, delayMs);
+        if (!outputDesc->isMuted(volumeSource)) {
+            if (curves.canBeMuted() &&
+                    (volumeSource != toVolumeSource(AUDIO_STREAM_ENFORCED_AUDIBLE) ||
+                     (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) ==
+                      AUDIO_POLICY_FORCE_NONE))) {
+                checkAndSetVolume(curves, volumeSource, 0, outputDesc, device, delayMs);
             }
         }
-        // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored
-        outputDesc->mMuteCount[stream]++;
+        // increment mMuteCount after calling checkAndSetVolume() so that volume change is not
+        // ignored
+        outputDesc->incMuteCount(volumeSource);
     } else {
-        if (outputDesc->mMuteCount[stream] == 0) {
-            ALOGV("setStreamMute() unmuting non muted stream!");
+        if (!outputDesc->isMuted(volumeSource)) {
+            ALOGV("%s unmuting non muted attributes!", __func__);
             return;
         }
-        if (--outputDesc->mMuteCount[stream] == 0) {
-            checkAndSetVolume(stream,
-                              mVolumeCurves->getVolumeIndex(stream, device),
+        if (outputDesc->decMuteCount(volumeSource) == 0) {
+            checkAndSetVolume(curves, volumeSource,
+                              curves.getVolumeIndex(device),
                               outputDesc,
                               device,
                               delayMs);
@@ -5753,106 +5941,9 @@
     }
 }
 
-void AudioPolicyManager::handleIncallSonification(audio_stream_type_t stream,
-                                                      bool starting, bool stateChange)
-{
-    if(!hasPrimaryOutput()) {
-        return;
-    }
-
-    // if the stream pertains to sonification strategy and we are in call we must
-    // mute the stream if it is low visibility. If it is high visibility, we must play a tone
-    // in the device used for phone strategy and play the tone if the selected device does not
-    // interfere with the device used for phone strategy
-    // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as
-    // many times as there are active tracks on the output
-    const routing_strategy stream_strategy = getStrategy(stream);
-    if ((stream_strategy == STRATEGY_SONIFICATION) ||
-            ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) {
-        sp<SwAudioOutputDescriptor> outputDesc = mPrimaryOutput;
-        ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d",
-                stream, starting, outputDesc->mDevice, stateChange);
-        if (outputDesc->mRefCount[stream]) {
-            int muteCount = 1;
-            if (stateChange) {
-                muteCount = outputDesc->mRefCount[stream];
-            }
-            if (audio_is_low_visibility(stream)) {
-                ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount);
-                for (int i = 0; i < muteCount; i++) {
-                    setStreamMute(stream, starting, mPrimaryOutput);
-                }
-            } else {
-                ALOGV("handleIncallSonification() high visibility");
-                if (outputDesc->device() &
-                        getDeviceForStrategy(STRATEGY_PHONE, true /*fromCache*/)) {
-                    ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount);
-                    for (int i = 0; i < muteCount; i++) {
-                        setStreamMute(stream, starting, mPrimaryOutput);
-                    }
-                }
-                if (starting) {
-                    mpClientInterface->startTone(AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION,
-                                                 AUDIO_STREAM_VOICE_CALL);
-                } else {
-                    mpClientInterface->stopTone();
-                }
-            }
-        }
-    }
-}
-
-audio_stream_type_t AudioPolicyManager::streamTypefromAttributesInt(const audio_attributes_t *attr)
-{
-    // flags to stream type mapping
-    if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
-        return AUDIO_STREAM_ENFORCED_AUDIBLE;
-    }
-    if ((attr->flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) {
-        return AUDIO_STREAM_BLUETOOTH_SCO;
-    }
-    if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) {
-        return AUDIO_STREAM_TTS;
-    }
-
-    // usage to stream type mapping
-    switch (attr->usage) {
-    case AUDIO_USAGE_MEDIA:
-    case AUDIO_USAGE_GAME:
-    case AUDIO_USAGE_ASSISTANT:
-    case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
-        return AUDIO_STREAM_MUSIC;
-    case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
-        return AUDIO_STREAM_ACCESSIBILITY;
-    case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
-        return AUDIO_STREAM_SYSTEM;
-    case AUDIO_USAGE_VOICE_COMMUNICATION:
-        return AUDIO_STREAM_VOICE_CALL;
-
-    case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
-        return AUDIO_STREAM_DTMF;
-
-    case AUDIO_USAGE_ALARM:
-        return AUDIO_STREAM_ALARM;
-    case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
-        return AUDIO_STREAM_RING;
-
-    case AUDIO_USAGE_NOTIFICATION:
-    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
-    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
-    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
-    case AUDIO_USAGE_NOTIFICATION_EVENT:
-        return AUDIO_STREAM_NOTIFICATION;
-
-    case AUDIO_USAGE_UNKNOWN:
-    default:
-        return AUDIO_STREAM_MUSIC;
-    }
-}
-
 bool AudioPolicyManager::isValidAttributes(const audio_attributes_t *paa)
 {
-    // has flags that map to a strategy?
+    // has flags that map to a stream type?
     if ((paa->flags & (AUDIO_FLAG_AUDIBILITY_ENFORCED | AUDIO_FLAG_SCO | AUDIO_FLAG_BEACON)) != 0) {
         return true;
     }
@@ -5883,37 +5974,6 @@
     return true;
 }
 
-bool AudioPolicyManager::isStrategyActive(const sp<AudioOutputDescriptor>& outputDesc,
-                                          routing_strategy strategy, uint32_t inPastMs,
-                                          nsecs_t sysTime) const
-{
-    if ((sysTime == 0) && (inPastMs != 0)) {
-        sysTime = systemTime();
-    }
-    for (int i = 0; i < (int)AUDIO_STREAM_FOR_POLICY_CNT; i++) {
-        if (((getStrategy((audio_stream_type_t)i) == strategy) ||
-                (NUM_STRATEGIES == strategy)) &&
-                outputDesc->isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-bool AudioPolicyManager::isStrategyActiveOnSameModule(const sp<AudioOutputDescriptor>& outputDesc,
-                                          routing_strategy strategy, uint32_t inPastMs,
-                                          nsecs_t sysTime) const
-{
-    for (size_t i = 0; i < mOutputs.size(); i++) {
-        sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
-        if (outputDesc->sharesHwModuleWith(desc)
-            && isStrategyActive(desc, strategy, inPastMs, sysTime)) {
-            return true;
-        }
-    }
-    return false;
-}
-
 audio_policy_forced_cfg_t AudioPolicyManager::getForceUse(audio_policy_force_use_t usage)
 {
     return mEngine->getForceUse(usage);
@@ -5932,10 +5992,10 @@
 void AudioPolicyManager::cleanUpForDevice(const sp<DeviceDescriptor>& deviceDesc)
 {
     for (ssize_t i = (ssize_t)mAudioSources.size() - 1; i >= 0; i--)  {
-        sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueAt(i);
-        if (sourceDesc->mDevice->equals(deviceDesc)) {
-            ALOGV("%s releasing audio source %d", __FUNCTION__, sourceDesc->getHandle());
-            stopAudioSource(sourceDesc->getHandle());
+        sp<SourceClientDescriptor> sourceDesc = mAudioSources.valueAt(i);
+        if (sourceDesc->srcDevice()->equals(deviceDesc)) {
+            ALOGV("%s releasing audio source %d", __FUNCTION__, sourceDesc->portId());
+            stopAudioSource(sourceDesc->portId());
         }
     }
 
@@ -5961,128 +6021,67 @@
             releaseAudioPatch(patchDesc->mHandle, patchDesc->mUid);
         }
     }
+
+    mInputs.clearSessionRoutesForDevice(deviceDesc);
+
+    mHwModules.cleanUpForDevice(deviceDesc);
 }
 
-// Modify the list of surround sound formats supported.
-void AudioPolicyManager::filterSurroundFormats(FormatVector *formatsPtr) {
-    FormatVector &formats = *formatsPtr;
-    // TODO Set this based on Config properties.
-    const bool alwaysForceAC3 = true;
+void AudioPolicyManager::modifySurroundFormats(
+        const sp<DeviceDescriptor>& devDesc, FormatVector *formatsPtr) {
+    std::unordered_set<audio_format_t> enforcedSurround(
+            devDesc->encodedFormats().begin(), devDesc->encodedFormats().end());
+    std::unordered_set<audio_format_t> allSurround;  // A flat set of all known surround formats
+    for (const auto& pair : mConfig.getSurroundFormats()) {
+        allSurround.insert(pair.first);
+        for (const auto& subformat : pair.second) allSurround.insert(subformat);
+    }
 
     audio_policy_forced_cfg_t forceUse = mEngine->getForceUse(
             AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND);
     ALOGD("%s: forced use = %d", __FUNCTION__, forceUse);
+    // This is the resulting set of formats depending on the surround mode:
+    //   'all surround' = allSurround
+    //   'enforced surround' = enforcedSurround [may include IEC69137 which isn't raw surround fmt]
+    //   'non-surround' = not in 'all surround' and not in 'enforced surround'
+    //   'manual surround' = mManualSurroundFormats
+    // AUTO:   formats v 'enforced surround'
+    // ALWAYS: formats v 'all surround' v 'enforced surround'
+    // NEVER:  formats ^ 'non-surround'
+    // MANUAL: formats ^ ('non-surround' v 'manual surround' v (IEC69137 ^ 'enforced surround'))
 
-    // If MANUAL, keep the supported surround sound formats as current enabled ones.
+    std::unordered_set<audio_format_t> formatSet;
+    if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL
+            || forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER) {
+        // formatSet is (formats ^ 'non-surround')
+        for (auto formatIter = formatsPtr->begin(); formatIter != formatsPtr->end(); ++formatIter) {
+            if (allSurround.count(*formatIter) == 0 && enforcedSurround.count(*formatIter) == 0) {
+                formatSet.insert(*formatIter);
+            }
+        }
+    } else {
+        formatSet.insert(formatsPtr->begin(), formatsPtr->end());
+    }
+    formatsPtr->clear();  // Re-filled from the formatSet at the end.
+
     if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL) {
-        formats.clear();
-        for (auto it = mSurroundFormats.begin(); it != mSurroundFormats.end(); it++) {
-            formats.add(*it);
+        formatSet.insert(mManualSurroundFormats.begin(), mManualSurroundFormats.end());
+        // Enable IEC61937 when in MANUAL mode if it's enforced for this device.
+        if (enforcedSurround.count(AUDIO_FORMAT_IEC61937) != 0) {
+            formatSet.insert(AUDIO_FORMAT_IEC61937);
         }
-        // Always enable IEC61937 when in MANUAL mode.
-        formats.add(AUDIO_FORMAT_IEC61937);
-    } else { // NEVER, AUTO or ALWAYS
-        // Analyze original support for various formats.
-        bool supportsAC3 = false;
-        bool supportsOtherSurround = false;
-        bool supportsIEC61937 = false;
-        mSurroundFormats.clear();
-        for (ssize_t formatIndex = 0; formatIndex < (ssize_t)formats.size(); formatIndex++) {
-            audio_format_t format = formats[formatIndex];
-            switch (format) {
-                case AUDIO_FORMAT_AC3:
-                    supportsAC3 = true;
-                    break;
-                case AUDIO_FORMAT_E_AC3:
-                case AUDIO_FORMAT_DTS:
-                case AUDIO_FORMAT_DTS_HD:
-                    // If ALWAYS, remove all other surround formats here
-                    // since we will add them later.
-                    if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS) {
-                        formats.removeAt(formatIndex);
-                        formatIndex--;
-                    }
-                    supportsOtherSurround = true;
-                    break;
-                case AUDIO_FORMAT_IEC61937:
-                    supportsIEC61937 = true;
-                    break;
-                default:
-                    break;
-            }
+    } else if (forceUse != AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER) { // AUTO or ALWAYS
+        if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS) {
+            formatSet.insert(allSurround.begin(), allSurround.end());
         }
-
-        // Modify formats based on surround preferences.
-        // If NEVER, remove support for surround formats.
-        if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER) {
-            if (supportsAC3 || supportsOtherSurround || supportsIEC61937) {
-                // Remove surround sound related formats.
-                for (size_t formatIndex = 0; formatIndex < formats.size(); ) {
-                    audio_format_t format = formats[formatIndex];
-                    switch(format) {
-                        case AUDIO_FORMAT_AC3:
-                        case AUDIO_FORMAT_E_AC3:
-                        case AUDIO_FORMAT_DTS:
-                        case AUDIO_FORMAT_DTS_HD:
-                        case AUDIO_FORMAT_IEC61937:
-                            formats.removeAt(formatIndex);
-                            break;
-                        default:
-                            formatIndex++; // keep it
-                            break;
-                    }
-                }
-                supportsAC3 = false;
-                supportsOtherSurround = false;
-                supportsIEC61937 = false;
-            }
-        } else { // AUTO or ALWAYS
-            // Most TVs support AC3 even if they do not report it in the EDID.
-            if ((alwaysForceAC3 || (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS))
-                    && !supportsAC3) {
-                formats.add(AUDIO_FORMAT_AC3);
-                supportsAC3 = true;
-            }
-
-            // If ALWAYS, add support for raw surround formats if all are missing.
-            // This assumes that if any of these formats are reported by the HAL
-            // then the report is valid and should not be modified.
-            if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS) {
-                formats.add(AUDIO_FORMAT_E_AC3);
-                formats.add(AUDIO_FORMAT_DTS);
-                formats.add(AUDIO_FORMAT_DTS_HD);
-                supportsOtherSurround = true;
-            }
-
-            // Add support for IEC61937 if any raw surround supported.
-            // The HAL could do this but add it here, just in case.
-            if ((supportsAC3 || supportsOtherSurround) && !supportsIEC61937) {
-                formats.add(AUDIO_FORMAT_IEC61937);
-                supportsIEC61937 = true;
-            }
-
-            // Add reported surround sound formats to enabled surround formats.
-            for (size_t formatIndex = 0; formatIndex < formats.size(); formatIndex++) {
-                audio_format_t format = formats[formatIndex];
-                switch(format) {
-                    case AUDIO_FORMAT_AC3:
-                    case AUDIO_FORMAT_E_AC3:
-                    case AUDIO_FORMAT_DTS:
-                    case AUDIO_FORMAT_DTS_HD:
-                    case AUDIO_FORMAT_AAC_LC:
-                    case AUDIO_FORMAT_DOLBY_TRUEHD:
-                    case AUDIO_FORMAT_E_AC3_JOC:
-                        mSurroundFormats.insert(format);
-                    default:
-                        break;
-                }
-            }
-        }
+        formatSet.insert(enforcedSurround.begin(), enforcedSurround.end());
+    }
+    for (const auto& format : formatSet) {
+        formatsPtr->push(format);
     }
 }
 
-// Modify the list of channel masks supported.
-void AudioPolicyManager::filterSurroundChannelMasks(ChannelsVector *channelMasksPtr) {
+void AudioPolicyManager::modifySurroundChannelMasks(ChannelsVector *channelMasksPtr) {
     ChannelsVector &channelMasks = *channelMasksPtr;
     audio_policy_forced_cfg_t forceUse = mEngine->getForceUse(
             AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND);
@@ -6112,16 +6111,17 @@
         // If not then add 5.1 support.
         if (!supports5dot1) {
             channelMasks.add(AUDIO_CHANNEL_OUT_5POINT1);
-            ALOGI("%s: force ALWAYS, so adding channelMask for 5.1 surround", __FUNCTION__);
+            ALOGI("%s: force MANUAL or ALWAYS, so adding channelMask for 5.1 surround", __func__);
         }
     }
 }
 
-void AudioPolicyManager::updateAudioProfiles(audio_devices_t device,
+void AudioPolicyManager::updateAudioProfiles(const sp<DeviceDescriptor>& devDesc,
                                              audio_io_handle_t ioHandle,
                                              AudioProfileVector &profiles)
 {
     String8 reply;
+    audio_devices_t device = devDesc->type();
 
     // Format MUST be checked first to update the list of AudioProfile
     if (profiles.hasDynamicFormat()) {
@@ -6135,8 +6135,9 @@
             return;
         }
         FormatVector formats = formatsFromString(reply.string());
-        if (device == AUDIO_DEVICE_OUT_HDMI) {
-            filterSurroundFormats(&formats);
+        if (device == AUDIO_DEVICE_OUT_HDMI
+                || isDeviceOfModule(devDesc, AUDIO_HARDWARE_MODULE_ID_MSD)) {
+            modifySurroundFormats(devDesc, &formats);
         }
         profiles.setFormats(formats);
     }
@@ -6168,8 +6169,9 @@
             if (repliedParameters.get(
                     String8(AudioParameter::keyStreamSupportedChannels), reply) == NO_ERROR) {
                 channelMasks = channelMasksFromString(reply.string());
-                if (device == AUDIO_DEVICE_OUT_HDMI) {
-                    filterSurroundChannelMasks(&channelMasks);
+                if (device == AUDIO_DEVICE_OUT_HDMI
+                        || isDeviceOfModule(devDesc, AUDIO_HARDWARE_MODULE_ID_MSD)) {
+                    modifySurroundChannelMasks(&channelMasks);
                 }
             }
         }
@@ -6177,4 +6179,58 @@
     }
 }
 
+status_t AudioPolicyManager::installPatch(const char *caller,
+                                          audio_patch_handle_t *patchHandle,
+                                          AudioIODescriptorInterface *ioDescriptor,
+                                          const struct audio_patch *patch,
+                                          int delayMs)
+{
+    ssize_t index = mAudioPatches.indexOfKey(
+            patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE ?
+            *patchHandle : ioDescriptor->getPatchHandle());
+    sp<AudioPatch> patchDesc;
+    status_t status = installPatch(
+            caller, index, patchHandle, patch, delayMs, mUidCached, &patchDesc);
+    if (status == NO_ERROR) {
+        ioDescriptor->setPatchHandle(patchDesc->mHandle);
+    }
+    return status;
+}
+
+status_t AudioPolicyManager::installPatch(const char *caller,
+                                          ssize_t index,
+                                          audio_patch_handle_t *patchHandle,
+                                          const struct audio_patch *patch,
+                                          int delayMs,
+                                          uid_t uid,
+                                          sp<AudioPatch> *patchDescPtr)
+{
+    sp<AudioPatch> patchDesc;
+    audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
+    if (index >= 0) {
+        patchDesc = mAudioPatches.valueAt(index);
+        afPatchHandle = patchDesc->mAfPatchHandle;
+    }
+
+    status_t status = mpClientInterface->createAudioPatch(patch, &afPatchHandle, delayMs);
+    ALOGV("%s() AF::createAudioPatch returned %d patchHandle %d num_sources %d num_sinks %d",
+            caller, status, afPatchHandle, patch->num_sources, patch->num_sinks);
+    if (status == NO_ERROR) {
+        if (index < 0) {
+            patchDesc = new AudioPatch(patch, uid);
+            addAudioPatch(patchDesc->mHandle, patchDesc);
+        } else {
+            patchDesc->mPatch = *patch;
+        }
+        patchDesc->mAfPatchHandle = afPatchHandle;
+        if (patchHandle) {
+            *patchHandle = patchDesc->mHandle;
+        }
+        nextAudioPortGeneration();
+        mpClientInterface->onAudioPatchListUpdate();
+    }
+    if (patchDescPtr) *patchDescPtr = patchDesc;
+    return status;
+}
+
 } // namespace android
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 45dca2e..612bd8f 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -17,6 +17,7 @@
 #pragma once
 
 #include <atomic>
+#include <functional>
 #include <memory>
 #include <unordered_set>
 
@@ -30,6 +31,7 @@
 #include <utils/SortedVector.h>
 #include <media/AudioParameter.h>
 #include <media/AudioPolicy.h>
+#include <media/PatchBuilder.h>
 #include "AudioPolicyInterface.h"
 
 #include <AudioPolicyManagerInterface.h>
@@ -38,6 +40,7 @@
 #include <AudioPolicyConfig.h>
 #include <AudioPort.h>
 #include <AudioPatch.h>
+#include <AudioProfile.h>
 #include <DeviceDescriptor.h>
 #include <IOProfile.h>
 #include <HwModule.h>
@@ -46,8 +49,7 @@
 #include <AudioPolicyMix.h>
 #include <EffectDescriptor.h>
 #include <SoundTriggerSession.h>
-#include <SessionRoute.h>
-#include <VolumeCurve.h>
+#include "TypeConverter.h"
 
 namespace android {
 
@@ -95,12 +97,14 @@
         virtual status_t setDeviceConnectionState(audio_devices_t device,
                                                           audio_policy_dev_state_t state,
                                                           const char *device_address,
-                                                          const char *device_name);
+                                                          const char *device_name,
+                                                          audio_format_t encodedFormat);
         virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
                                                                               const char *device_address);
         virtual status_t handleDeviceConfigChange(audio_devices_t device,
                                                   const char *device_address,
-                                                  const char *device_name);
+                                                  const char *device_name,
+                                                  audio_format_t encodedFormat);
         virtual void setPhoneState(audio_mode_t state);
         virtual void setForceUse(audio_policy_force_use_t usage,
                                  audio_policy_forced_cfg_t config);
@@ -109,26 +113,22 @@
         virtual void setSystemProperty(const char* property, const char* value);
         virtual status_t initCheck();
         virtual audio_io_handle_t getOutput(audio_stream_type_t stream);
-        virtual status_t getOutputForAttr(const audio_attributes_t *attr,
-                                          audio_io_handle_t *output,
-                                          audio_session_t session,
-                                          audio_stream_type_t *stream,
-                                          uid_t uid,
-                                          const audio_config_t *config,
-                                          audio_output_flags_t *flags,
-                                          audio_port_handle_t *selectedDeviceId,
-                                          audio_port_handle_t *portId);
-        virtual status_t startOutput(audio_io_handle_t output,
-                                     audio_stream_type_t stream,
-                                     audio_session_t session);
-        virtual status_t stopOutput(audio_io_handle_t output,
-                                    audio_stream_type_t stream,
-                                    audio_session_t session);
-        virtual void releaseOutput(audio_io_handle_t output,
-                                   audio_stream_type_t stream,
-                                   audio_session_t session);
+        status_t getOutputForAttr(const audio_attributes_t *attr,
+                                  audio_io_handle_t *output,
+                                  audio_session_t session,
+                                  audio_stream_type_t *stream,
+                                  uid_t uid,
+                                  const audio_config_t *config,
+                                  audio_output_flags_t *flags,
+                                  audio_port_handle_t *selectedDeviceId,
+                                  audio_port_handle_t *portId,
+                                  std::vector<audio_io_handle_t> *secondaryOutputs) override;
+        virtual status_t startOutput(audio_port_handle_t portId);
+        virtual status_t stopOutput(audio_port_handle_t portId);
+        virtual void releaseOutput(audio_port_handle_t portId);
         virtual status_t getInputForAttr(const audio_attributes_t *attr,
                                          audio_io_handle_t *input,
+                                         audio_unique_id_t riid,
                                          audio_session_t session,
                                          uid_t uid,
                                          const audio_config_base_t *config,
@@ -138,20 +138,23 @@
                                          audio_port_handle_t *portId);
 
         // indicates to the audio policy manager that the input starts being used.
-        virtual status_t startInput(audio_io_handle_t input,
-                                    audio_session_t session,
-                                    bool silenced,
-                                    concurrency_type__mask_t *concurrency);
+        virtual status_t startInput(audio_port_handle_t portId);
 
         // indicates to the audio policy manager that the input stops being used.
-        virtual status_t stopInput(audio_io_handle_t input,
-                                   audio_session_t session);
-        virtual void releaseInput(audio_io_handle_t input,
-                                  audio_session_t session);
-        virtual void closeAllInputs();
-        virtual void initStreamVolume(audio_stream_type_t stream,
-                                                    int indexMin,
-                                                    int indexMax);
+        virtual status_t stopInput(audio_port_handle_t portId);
+        virtual void releaseInput(audio_port_handle_t portId);
+        virtual void checkCloseInputs();
+        /**
+         * @brief initStreamVolume: even if the engine volume files provides min and max, keep this
+         * api for compatibility reason.
+         * AudioServer will get the min and max and may overwrite them if:
+         *      -using property (highest priority)
+         *      -not defined (-1 by convention), case when still using apm volume tables XML files
+         * @param stream to be considered
+         * @param indexMin to set
+         * @param indexMax to set
+         */
+        virtual void initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax);
         virtual status_t setStreamVolumeIndex(audio_stream_type_t stream,
                                               int index,
                                               audio_devices_t device);
@@ -159,10 +162,33 @@
                                               int *index,
                                               audio_devices_t device);
 
+        virtual status_t setVolumeIndexForAttributes(const audio_attributes_t &attr,
+                                                     int index,
+                                                     audio_devices_t device);
+        virtual status_t getVolumeIndexForAttributes(const audio_attributes_t &attr,
+                                                     int &index,
+                                                     audio_devices_t device);
+        virtual status_t getMaxVolumeIndexForAttributes(const audio_attributes_t &attr, int &index);
+
+        virtual status_t getMinVolumeIndexForAttributes(const audio_attributes_t &attr, int &index);
+
+        status_t setVolumeCurveIndex(int index,
+                                     audio_devices_t device,
+                                     IVolumeCurves &volumeCurves);
+
+        status_t getVolumeIndex(const IVolumeCurves &curves, int &index,
+                                audio_devices_t device) const;
+
         // return the strategy corresponding to a given stream type
-        virtual uint32_t getStrategyForStream(audio_stream_type_t stream);
-        // return the strategy corresponding to the given audio attributes
-        virtual uint32_t getStrategyForAttr(const audio_attributes_t *attr);
+        virtual uint32_t getStrategyForStream(audio_stream_type_t stream)
+        {
+            return streamToStrategy(stream);
+        }
+        product_strategy_t streamToStrategy(audio_stream_type_t stream) const
+        {
+            auto attributes = mEngine->getAttributesForStreamType(stream);
+            return mEngine->getProductStrategyForAttributes(attributes);
+        }
 
         // return the enabled output devices for the given stream type
         virtual audio_devices_t getDevicesForStream(audio_stream_type_t stream);
@@ -173,14 +199,9 @@
                                         uint32_t strategy,
                                         int session,
                                         int id);
-        virtual status_t unregisterEffect(int id)
-        {
-            return mEffects.unregisterEffect(id);
-        }
-        virtual status_t setEffectEnabled(int id, bool enabled)
-        {
-            return mEffects.setEffectEnabled(id, enabled);
-        }
+        virtual status_t unregisterEffect(int id);
+        virtual status_t setEffectEnabled(int id, bool enabled);
+        status_t moveEffectsToIo(const std::vector<int>& ids, audio_io_handle_t io) override;
 
         virtual bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const;
         // return whether a stream is playing remotely, override to change the definition of
@@ -193,10 +214,18 @@
 
         virtual bool isSourceActive(audio_source_t source) const;
 
-        virtual status_t dump(int fd);
+        // helpers for dump(int fd)
+        void dumpManualSurroundFormats(String8 *dst) const;
+        void dump(String8 *dst) const;
 
+        status_t dump(int fd) override;
+
+        status_t setAllowedCapturePolicy(uid_t uid, audio_flags_mask_t capturePolicy) override;
         virtual bool isOffloadSupported(const audio_offload_info_t& offloadInfo);
 
+        virtual bool isDirectOutputSupported(const audio_config_base_t& config,
+                                             const audio_attributes_t& attributes);
+
         virtual status_t listAudioPorts(audio_port_role_t role,
                                         audio_port_type_t type,
                                         unsigned int *num_ports,
@@ -226,12 +255,15 @@
 
         virtual status_t registerPolicyMixes(const Vector<AudioMix>& mixes);
         virtual status_t unregisterPolicyMixes(Vector<AudioMix> mixes);
+        virtual status_t setUidDeviceAffinities(uid_t uid,
+                const Vector<AudioDeviceTypeAddr>& devices);
+        virtual status_t removeUidDeviceAffinities(uid_t uid);
 
         virtual status_t startAudioSource(const struct audio_port_config *source,
                                           const audio_attributes_t *attributes,
-                                          audio_patch_handle_t *handle,
+                                          audio_port_handle_t *portId,
                                           uid_t uid);
-        virtual status_t stopAudioSource(audio_patch_handle_t handle);
+        virtual status_t stopAudioSource(audio_port_handle_t portId);
 
         virtual status_t setMasterMono(bool mono);
         virtual status_t getMasterMono(bool *mono);
@@ -244,10 +276,36 @@
                                             bool reported);
         virtual status_t setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled);
 
-        // return the strategy corresponding to a given stream type
-        routing_strategy getStrategy(audio_stream_type_t stream) const;
+        virtual status_t getHwOffloadEncodingFormatsSupportedForA2DP(
+                    std::vector<audio_format_t> *formats);
 
-        virtual void setRecordSilenced(uid_t uid, bool silenced);
+        virtual void setAppState(uid_t uid, app_state_t state);
+
+        virtual bool isHapticPlaybackSupported();
+
+        virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies)
+        {
+            return mEngine->listAudioProductStrategies(strategies);
+        }
+
+        virtual status_t getProductStrategyFromAudioAttributes(const AudioAttributes &aa,
+                                                               product_strategy_t &productStrategy)
+        {
+            productStrategy = mEngine->getProductStrategyForAttributes(aa.getAttributes());
+            return productStrategy != PRODUCT_STRATEGY_NONE ? NO_ERROR : BAD_VALUE;
+        }
+
+        virtual status_t listAudioVolumeGroups(AudioVolumeGroupVector &groups)
+        {
+            return mEngine->listAudioVolumeGroups(groups);
+        }
+
+        virtual status_t getVolumeGroupFromAudioAttributes(const AudioAttributes &aa,
+                                                           volume_group_t &volumeGroup)
+        {
+            volumeGroup = mEngine->getVolumeGroupForAttributes(aa.getAttributes());
+            return volumeGroup != VOLUME_GROUP_NONE ? NO_ERROR : BAD_VALUE;
+        }
 
 protected:
         // A constructor that allows more fine-grained control over initialization process,
@@ -286,75 +344,93 @@
         {
             return mInputs;
         }
-        virtual const DeviceVector &getAvailableOutputDevices() const
+        virtual const DeviceVector getAvailableOutputDevices() const
         {
             return mAvailableOutputDevices;
         }
-        virtual const DeviceVector &getAvailableInputDevices() const
+        virtual const DeviceVector getAvailableInputDevices() const
         {
+            // legacy and non-legacy remote-submix are managed by the engine, do not filter
             return mAvailableInputDevices;
         }
-        virtual IVolumeCurvesCollection &getVolumeCurves() { return *mVolumeCurves; }
         virtual const sp<DeviceDescriptor> &getDefaultOutputDevice() const
         {
             return mDefaultOutputDevice;
         }
 
+        std::vector<volume_group_t> getVolumeGroups() const
+        {
+            return mEngine->getVolumeGroups();
+        }
+
+        VolumeSource toVolumeSource(volume_group_t volumeGroup) const
+        {
+            return static_cast<VolumeSource>(volumeGroup);
+        }
+        VolumeSource toVolumeSource(const audio_attributes_t &attributes) const
+        {
+            return toVolumeSource(mEngine->getVolumeGroupForAttributes(attributes));
+        }
+        VolumeSource toVolumeSource(audio_stream_type_t stream) const
+        {
+            return toVolumeSource(mEngine->getVolumeGroupForStreamType(stream));
+        }
+        IVolumeCurves &getVolumeCurves(VolumeSource volumeSource)
+        {
+          auto *curves = mEngine->getVolumeCurvesForVolumeGroup(
+              static_cast<volume_group_t>(volumeSource));
+          ALOG_ASSERT(curves != nullptr, "No curves for volume source %d", volumeSource);
+          return *curves;
+        }
+        IVolumeCurves &getVolumeCurves(const audio_attributes_t &attr)
+        {
+            auto *curves = mEngine->getVolumeCurvesForAttributes(attr);
+            ALOG_ASSERT(curves != nullptr, "No curves for attributes %s", toString(attr).c_str());
+            return *curves;
+        }
+        IVolumeCurves &getVolumeCurves(audio_stream_type_t stream)
+        {
+            auto *curves = mEngine->getVolumeCurvesForStreamType(stream);
+            ALOG_ASSERT(curves != nullptr, "No curves for stream %s", toString(stream).c_str());
+            return *curves;
+        }
+
         void addOutput(audio_io_handle_t output, const sp<SwAudioOutputDescriptor>& outputDesc);
         void removeOutput(audio_io_handle_t output);
         void addInput(audio_io_handle_t input, const sp<AudioInputDescriptor>& inputDesc);
 
-        // return appropriate device for streams handled by the specified strategy according to current
-        // phone state, connected devices...
-        // if fromCache is true, the device is returned from mDeviceForStrategy[],
-        // otherwise it is determine by current state
-        // (device connected,phone state, force use, a2dp output...)
-        // This allows to:
-        //  1 speed up process when the state is stable (when starting or stopping an output)
-        //  2 access to either current device selection (fromCache == true) or
-        // "future" device selection (fromCache == false) when called from a context
-        //  where conditions are changing (setDeviceConnectionState(), setPhoneState()...) AND
-        //  before updateDevicesAndOutputs() is called.
-        virtual audio_devices_t getDeviceForStrategy(routing_strategy strategy,
-                                                     bool fromCache);
-
-        bool isStrategyActive(const sp<AudioOutputDescriptor>& outputDesc, routing_strategy strategy,
-                              uint32_t inPastMs = 0, nsecs_t sysTime = 0) const;
-
-        bool isStrategyActiveOnSameModule(const sp<AudioOutputDescriptor>& outputDesc,
-                                                  routing_strategy strategy, uint32_t inPastMs = 0,
-                                                  nsecs_t sysTime = 0) const;
-
         // change the route of the specified output. Returns the number of ms we have slept to
         // allow new routing to take effect in certain cases.
-        virtual uint32_t setOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
-                             audio_devices_t device,
-                             bool force = false,
-                             int delayMs = 0,
-                             audio_patch_handle_t *patchHandle = NULL,
-                             const char *address = nullptr,
-                             bool requiresMuteCheck = true);
+        uint32_t setOutputDevices(const sp<SwAudioOutputDescriptor>& outputDesc,
+                                  const DeviceVector &device,
+                                  bool force = false,
+                                  int delayMs = 0,
+                                  audio_patch_handle_t *patchHandle = NULL,
+                                  bool requiresMuteCheck = true);
         status_t resetOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
                                    int delayMs = 0,
                                    audio_patch_handle_t *patchHandle = NULL);
         status_t setInputDevice(audio_io_handle_t input,
-                                audio_devices_t device,
+                                const sp<DeviceDescriptor> &device,
                                 bool force = false,
                                 audio_patch_handle_t *patchHandle = NULL);
         status_t resetInputDevice(audio_io_handle_t input,
                                   audio_patch_handle_t *patchHandle = NULL);
 
-        // select input device corresponding to requested audio source
-        virtual audio_devices_t getDeviceForInputSource(audio_source_t inputSource);
-
         // compute the actual volume for a given stream according to the requested index and a particular
         // device
-        virtual float computeVolume(audio_stream_type_t stream,
+        virtual float computeVolume(IVolumeCurves &curves,
+                                    VolumeSource volumeSource,
                                     int index,
                                     audio_devices_t device);
 
+        // rescale volume index from srcStream within range of dstStream
+        int rescaleVolumeIndex(int srcIndex,
+                               VolumeSource fromVolumeSource,
+                               VolumeSource toVolumeSource);
         // check that volume change is permitted, compute and send new volume to audio hardware
-        virtual status_t checkAndSetVolume(audio_stream_type_t stream, int index,
+        virtual status_t checkAndSetVolume(IVolumeCurves &curves,
+                                           VolumeSource volumeSource, int index,
                                            const sp<AudioOutputDescriptor>& outputDesc,
                                            audio_devices_t device,
                                            int delayMs = 0, bool force = false);
@@ -363,23 +439,35 @@
         void applyStreamVolumes(const sp<AudioOutputDescriptor>& outputDesc,
                                 audio_devices_t device, int delayMs = 0, bool force = false);
 
-        // Mute or unmute all streams handled by the specified strategy on the specified output
-        void setStrategyMute(routing_strategy strategy,
+        /**
+         * @brief setStrategyMute Mute or unmute all active clients on the considered output
+         * following the given strategy.
+         * @param strategy to be considered
+         * @param on true for mute, false for unmute
+         * @param outputDesc to be considered
+         * @param delayMs
+         * @param device
+         */
+        void setStrategyMute(product_strategy_t strategy,
                              bool on,
                              const sp<AudioOutputDescriptor>& outputDesc,
                              int delayMs = 0,
-                             audio_devices_t device = (audio_devices_t)0);
+                             audio_devices_t device = AUDIO_DEVICE_NONE);
 
-        // Mute or unmute the stream on the specified output
-        void setStreamMute(audio_stream_type_t stream,
-                           bool on,
-                           const sp<AudioOutputDescriptor>& outputDesc,
-                           int delayMs = 0,
-                           audio_devices_t device = (audio_devices_t)0);
-
-        // handle special cases for sonification strategy while in call: mute streams or replace by
-        // a special tone in the device used for communication
-        void handleIncallSonification(audio_stream_type_t stream, bool starting, bool stateChange);
+        /**
+         * @brief setVolumeSourceMute Mute or unmute the volume source on the specified output
+         * @param volumeSource to be muted/unmute (may host legacy streams or by extension set of
+         * audio attributes)
+         * @param on true to mute, false to umute
+         * @param outputDesc on which the client following the volume group shall be muted/umuted
+         * @param delayMs
+         * @param device
+         */
+        void setVolumeSourceMute(VolumeSource volumeSource,
+                                 bool on,
+                                 const sp<AudioOutputDescriptor>& outputDesc,
+                                 int delayMs = 0,
+                                 audio_devices_t device = AUDIO_DEVICE_NONE);
 
         audio_mode_t getPhoneState();
 
@@ -394,15 +482,12 @@
         // when a device is disconnected, checks if an output is not used any more and
         // returns its handle if any.
         // transfers the audio tracks and effects from one output thread to another accordingly.
-        status_t checkOutputsForDevice(const sp<DeviceDescriptor>& devDesc,
+        status_t checkOutputsForDevice(const sp<DeviceDescriptor>& device,
                                        audio_policy_dev_state_t state,
-                                       SortedVector<audio_io_handle_t>& outputs,
-                                       const String8& address);
+                                       SortedVector<audio_io_handle_t>& outputs);
 
-        status_t checkInputsForDevice(const sp<DeviceDescriptor>& devDesc,
-                                      audio_policy_dev_state_t state,
-                                      SortedVector<audio_io_handle_t>& inputs,
-                                      const String8& address);
+        status_t checkInputsForDevice(const sp<DeviceDescriptor>& device,
+                                      audio_policy_dev_state_t state);
 
         // close an output and its companion duplicating output.
         void closeOutput(audio_io_handle_t output);
@@ -410,15 +495,35 @@
         // close an input.
         void closeInput(audio_io_handle_t input);
 
-        // checks and if necessary changes outputs used for all strategies.
-        // must be called every time a condition that affects the output choice for a given strategy
-        // changes: connected device, phone state, force use...
-        // Must be called before updateDevicesAndOutputs()
-        void checkOutputForStrategy(routing_strategy strategy);
+        // runs all the checks required for accomodating changes in devices and outputs
+        // if 'onOutputsChecked' callback is provided, it is executed after the outputs
+        // check via 'checkOutputForAllStrategies'. If the callback returns 'true',
+        // A2DP suspend status is rechecked.
+        void checkForDeviceAndOutputChanges(std::function<bool()> onOutputsChecked = nullptr);
 
-        // Same as checkOutputForStrategy() but for a all strategies in order of priority
+        /**
+         * @brief checkOutputForAttributes checks and if necessary changes outputs used for the
+         * given audio attributes.
+         * must be called every time a condition that affects the output choice for a given
+         * attributes changes: connected device, phone state, force use...
+         * Must be called before updateDevicesAndOutputs()
+         * @param attr to be considered
+         */
+        void checkOutputForAttributes(const audio_attributes_t &attr);
+
+        bool followsSameRouting(const audio_attributes_t &lAttr,
+                                const audio_attributes_t &rAttr) const;
+
+        /**
+         * @brief checkOutputForAllStrategies Same as @see checkOutputForAttributes()
+         *      but for a all product strategies in order of priority
+         */
         void checkOutputForAllStrategies();
 
+        // Same as checkOutputForStrategy but for secondary outputs. Make sure if a secondary
+        // output condition changes, the track is properly rerouted
+        void checkSecondaryOutputs();
+
         // manages A2DP output suspend/restore according to phone state and BT SCO usage
         void checkA2dpSuspend();
 
@@ -426,18 +531,21 @@
         // must be called every time a condition that affects the device choice for a given output is
         // changed: connected device, phone state, force use, output start, output stop..
         // see getDeviceForStrategy() for the use of fromCache parameter
-        audio_devices_t getNewOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
-                                           bool fromCache);
+        DeviceVector getNewOutputDevices(const sp<SwAudioOutputDescriptor>& outputDesc,
+                                         bool fromCache);
 
-        // updates cache of device used by all strategies (mDeviceForStrategy[])
-        // must be called every time a condition that affects the device choice for a given strategy is
-        // changed: connected device, phone state, force use...
-        // cached values are used by getDeviceForStrategy() if parameter fromCache is true.
-         // Must be called after checkOutputForAllStrategies()
+        /**
+         * @brief updateDevicesAndOutputs: updates cache of devices of the engine
+         * must be called every time a condition that affects the device choice is changed:
+         * connected device, phone state, force use...
+         * cached values are used by getOutputDevicesForStream()/getDevicesForAttributes if
+         * parameter fromCache is true.
+         * Must be called after checkOutputForAllStrategies()
+         */
         void updateDevicesAndOutputs();
 
         // selects the most appropriate device on input for current state
-        audio_devices_t getNewInputDevice(const sp<AudioInputDescriptor>& inputDesc);
+        sp<DeviceDescriptor> getNewInputDevice(const sp<AudioInputDescriptor>& inputDesc);
 
         virtual uint32_t getMaxEffectsCpuLoad()
         {
@@ -449,34 +557,50 @@
             return mEffects.getMaxEffectsMemory();
         }
 
-        SortedVector<audio_io_handle_t> getOutputsForDevice(audio_devices_t device,
-                                                            const SwAudioOutputCollection& openOutputs);
-        bool vectorsEqual(SortedVector<audio_io_handle_t>& outputs1,
-                                           SortedVector<audio_io_handle_t>& outputs2);
+        SortedVector<audio_io_handle_t> getOutputsForDevices(
+                const DeviceVector &devices, const SwAudioOutputCollection& openOutputs);
 
-        // mute/unmute strategies using an incompatible device combination
-        // if muting, wait for the audio in pcm buffer to be drained before proceeding
-        // if unmuting, unmute only after the specified delay
-        // Returns the number of ms waited
-        virtual uint32_t  checkDeviceMuteStrategies(const sp<AudioOutputDescriptor>& outputDesc,
-                                            audio_devices_t prevDevice,
-                                            uint32_t delayMs);
+        /**
+         * @brief checkDeviceMuteStrategies mute/unmute strategies
+         *      using an incompatible device combination.
+         *      if muting, wait for the audio in pcm buffer to be drained before proceeding
+         *      if unmuting, unmute only after the specified delay
+         * @param outputDesc
+         * @param prevDevice
+         * @param delayMs
+         * @return the number of ms waited
+         */
+        virtual uint32_t checkDeviceMuteStrategies(const sp<AudioOutputDescriptor>& outputDesc,
+                                                   const DeviceVector &prevDevices,
+                                                   uint32_t delayMs);
 
         audio_io_handle_t selectOutput(const SortedVector<audio_io_handle_t>& outputs,
-                                       audio_output_flags_t flags,
-                                       audio_format_t format);
+                                       audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
+                                       audio_format_t format = AUDIO_FORMAT_INVALID,
+                                       audio_channel_mask_t channelMask = AUDIO_CHANNEL_NONE,
+                                       uint32_t samplingRate = 0);
         // samplingRate, format, channelMask are in/out and so may be modified
-        sp<IOProfile> getInputProfile(audio_devices_t device,
-                                      const String8& address,
+        sp<IOProfile> getInputProfile(const sp<DeviceDescriptor> & device,
                                       uint32_t& samplingRate,
                                       audio_format_t& format,
                                       audio_channel_mask_t& channelMask,
                                       audio_input_flags_t flags);
-        sp<IOProfile> getProfileForDirectOutput(audio_devices_t device,
-                                                       uint32_t samplingRate,
-                                                       audio_format_t format,
-                                                       audio_channel_mask_t channelMask,
-                                                       audio_output_flags_t flags);
+        /**
+         * @brief getProfileForOutput
+         * @param devices vector of descriptors, may be empty if ignoring the device is required
+         * @param samplingRate
+         * @param format
+         * @param channelMask
+         * @param flags
+         * @param directOnly
+         * @return IOProfile to be used if found, nullptr otherwise
+         */
+        sp<IOProfile> getProfileForOutput(const DeviceVector &devices,
+                                          uint32_t samplingRate,
+                                          audio_format_t format,
+                                          audio_channel_mask_t channelMask,
+                                          audio_output_flags_t flags,
+                                          bool directOnly);
 
         audio_io_handle_t selectOutputForMusicEffects();
 
@@ -489,62 +613,87 @@
             return mAudioPatches.removeAudioPatch(handle);
         }
 
-        audio_devices_t availablePrimaryOutputDevices() const
+        bool isPrimaryModule(const sp<HwModule> &module) const
+        {
+            if (module == 0 || !hasPrimaryOutput()) {
+                return false;
+            }
+            return module->getHandle() == mPrimaryOutput->getModuleHandle();
+        }
+        DeviceVector availablePrimaryOutputDevices() const
         {
             if (!hasPrimaryOutput()) {
-                return AUDIO_DEVICE_NONE;
+                return DeviceVector();
             }
-            return mPrimaryOutput->supportedDevices() & mAvailableOutputDevices.types();
+            return mAvailableOutputDevices.filter(mPrimaryOutput->supportedDevices());
         }
-        audio_devices_t availablePrimaryInputDevices() const
+        DeviceVector availablePrimaryModuleInputDevices() const
         {
             if (!hasPrimaryOutput()) {
-                return AUDIO_DEVICE_NONE;
+                return DeviceVector();
             }
-            return mAvailableInputDevices.getDevicesFromHwModule(mPrimaryOutput->getModuleHandle());
+            return mAvailableInputDevices.getDevicesFromHwModule(
+                    mPrimaryOutput->getModuleHandle());
+        }
+        /**
+         * @brief getFirstDeviceId of the Device Vector
+         * @return if the collection is not empty, it returns the first device Id,
+         *         otherwise AUDIO_PORT_HANDLE_NONE
+         */
+        audio_port_handle_t getFirstDeviceId(const DeviceVector &devices) const
+        {
+            return (devices.size() > 0) ? devices.itemAt(0)->getId() : AUDIO_PORT_HANDLE_NONE;
+        }
+        String8 getFirstDeviceAddress(const DeviceVector &devices) const
+        {
+            return (devices.size() > 0) ? devices.itemAt(0)->address() : String8("");
         }
 
-        uint32_t updateCallRouting(audio_devices_t rxDevice, uint32_t delayMs = 0);
-        sp<AudioPatch> createTelephonyPatch(bool isRx, audio_devices_t device, uint32_t delayMs);
-        sp<DeviceDescriptor> fillAudioPortConfigForDevice(
-                const DeviceVector& devices, audio_devices_t device, audio_port_config *config);
+        uint32_t updateCallRouting(const DeviceVector &rxDevices, uint32_t delayMs = 0);
+        sp<AudioPatch> createTelephonyPatch(bool isRx, const sp<DeviceDescriptor> &device,
+                                            uint32_t delayMs);
+        sp<DeviceDescriptor> findDevice(
+                const DeviceVector& devices, audio_devices_t device) const;
+        audio_devices_t getModuleDeviceTypes(
+                const DeviceVector& devices, const char *moduleId) const;
+        bool isDeviceOfModule(const sp<DeviceDescriptor>& devDesc, const char *moduleId) const;
 
-        // if argument "device" is different from AUDIO_DEVICE_NONE,  startSource() will force
-        // the re-evaluation of the output device.
-        status_t startSource(const sp<AudioOutputDescriptor>& outputDesc,
-                             audio_stream_type_t stream,
-                             audio_devices_t device,
-                             const char *address,
+        status_t startSource(const sp<SwAudioOutputDescriptor>& outputDesc,
+                             const sp<TrackClientDescriptor>& client,
                              uint32_t *delayMs);
-        status_t stopSource(const sp<AudioOutputDescriptor>& outputDesc,
-                            audio_stream_type_t stream,
-                            bool forceDeviceUpdate);
+        status_t stopSource(const sp<SwAudioOutputDescriptor>& outputDesc,
+                            const sp<TrackClientDescriptor>& client);
 
         void clearAudioPatches(uid_t uid);
         void clearSessionRoutes(uid_t uid);
-        void checkStrategyRoute(routing_strategy strategy, audio_io_handle_t ouptutToSkip);
+
+        /**
+         * @brief checkStrategyRoute: when an output is beeing rerouted, reconsider each output
+         * that may host a strategy playing on the considered output.
+         * @param ps product strategy that initiated the rerouting
+         * @param ouptutToSkip output that initiated the rerouting
+         */
+        void checkStrategyRoute(product_strategy_t ps, audio_io_handle_t ouptutToSkip);
 
         status_t hasPrimaryOutput() const { return mPrimaryOutput != 0; }
 
-        status_t connectAudioSource(const sp<AudioSourceDescriptor>& sourceDesc);
-        status_t disconnectAudioSource(const sp<AudioSourceDescriptor>& sourceDesc);
+        status_t connectAudioSource(const sp<SourceClientDescriptor>& sourceDesc);
+        status_t disconnectAudioSource(const sp<SourceClientDescriptor>& sourceDesc);
 
-        sp<AudioSourceDescriptor> getSourceForStrategyOnOutput(audio_io_handle_t output,
-                                                               routing_strategy strategy);
+        sp<SourceClientDescriptor> getSourceForAttributesOnOutput(audio_io_handle_t output,
+                                                                  const audio_attributes_t &attr);
 
         void cleanUpForDevice(const sp<DeviceDescriptor>& deviceDesc);
 
         void clearAudioSources(uid_t uid);
 
-        static bool isConcurrentSource(audio_source_t source);
-
-        bool isConcurentCaptureAllowed(const sp<AudioInputDescriptor>& inputDesc,
-                const sp<AudioSession>& audioSession);
-
         static bool streamsMatchForvolume(audio_stream_type_t stream1,
                                           audio_stream_type_t stream2);
 
-        uid_t mUidCached;
+        void closeActiveClients(const sp<AudioInputDescriptor>& input);
+        void closeClient(audio_port_handle_t portId);
+
+        const uid_t mUidCached;                         // AID_AUDIOSERVER
         AudioPolicyClientInterface *mpClientInterface;  // audio policy client interface
         sp<SwAudioOutputDescriptor> mPrimaryOutput;     // primary output descriptor
         // list of descriptors for outputs currently opened
@@ -558,20 +707,17 @@
         DeviceVector  mAvailableOutputDevices; // all available output devices
         DeviceVector  mAvailableInputDevices;  // all available input devices
 
-        SessionRouteMap mOutputRoutes = SessionRouteMap(SessionRouteMap::MAPTYPE_OUTPUT);
-        SessionRouteMap mInputRoutes = SessionRouteMap(SessionRouteMap::MAPTYPE_INPUT);
-
         bool    mLimitRingtoneVolume;        // limit ringtone volume to music volume if headset connected
-        audio_devices_t mDeviceForStrategy[NUM_STRATEGIES];
+
         float   mLastVoiceVolume;            // last voice volume value sent to audio HAL
         bool    mA2dpSuspended;  // true if A2DP output is suspended
 
-        std::unique_ptr<IVolumeCurvesCollection> mVolumeCurves; // Volume Curves per use case and device category
         EffectDescriptorCollection mEffects;  // list of registered audio effects
         sp<DeviceDescriptor> mDefaultOutputDevice; // output device selected by default at boot time
         HwModuleCollection mHwModules; // contains only modules that have been loaded successfully
         HwModuleCollection mHwModulesAll; // normally not needed, used during construction and for
                                           // dumps
+
         AudioPolicyConfig mConfig;
 
         std::atomic<uint32_t> mAudioPortGeneration;
@@ -584,7 +730,7 @@
         sp<AudioPatch> mCallRxPatch;
 
         HwAudioOutputCollection mHwOutputs;
-        AudioSourceCollection mAudioSources;
+        SourceClientCollection mAudioSources;
 
         // for supporting "beacon" streams, i.e. streams that only play on speaker, and never
         // when something other than STREAM_TTS (a.k.a. "Transmitted Through Speaker") is playing
@@ -608,17 +754,29 @@
         // Audio Policy Engine Interface.
         AudioPolicyManagerInterface *mEngine;
 
-        // Surround formats that are enabled.
-        std::unordered_set<audio_format_t> mSurroundFormats;
+        // Surround formats that are enabled manually. Taken into account when
+        // "encoded surround" is forced into "manual" mode.
+        std::unordered_set<audio_format_t> mManualSurroundFormats;
+
+        std::unordered_map<uid_t, audio_flags_mask_t> mAllowedCapturePolicies;
 private:
         // Add or remove AC3 DTS encodings based on user preferences.
-        void filterSurroundFormats(FormatVector *formatsPtr);
-        void filterSurroundChannelMasks(ChannelsVector *channelMasksPtr);
+        void modifySurroundFormats(const sp<DeviceDescriptor>& devDesc, FormatVector *formatsPtr);
+        void modifySurroundChannelMasks(ChannelsVector *channelMasksPtr);
 
-        status_t getSupportedFormats(audio_io_handle_t ioHandle, FormatVector& formats);
+        // Support for Multi-Stream Decoder (MSD) module
+        sp<DeviceDescriptor> getMsdAudioInDevice() const;
+        DeviceVector getMsdAudioOutDevices() const;
+        const AudioPatchCollection getMsdPatches() const;
+        status_t getBestMsdAudioProfileFor(const sp<DeviceDescriptor> &outputDevice,
+                                           bool hwAvSync,
+                                           audio_port_config *sourceConfig,
+                                           audio_port_config *sinkConfig) const;
+        PatchBuilder buildMsdPatch(const sp<DeviceDescriptor> &outputDevice) const;
+        status_t setMsdPatch(const sp<DeviceDescriptor> &outputDevice = nullptr);
 
         // If any, resolve any "dynamic" fields of an Audio Profiles collection
-        void updateAudioProfiles(audio_devices_t device, audio_io_handle_t ioHandle,
+        void updateAudioProfiles(const sp<DeviceDescriptor>& devDesc, audio_io_handle_t ioHandle,
                 AudioProfileVector &profiles);
 
         // Notify the policy client of any change of device state with AUDIO_IO_HANDLE_NONE,
@@ -626,42 +784,58 @@
         // It can give a chance to HAL implementer to retrieve dynamic capabilities associated
         // to this device for example.
         // TODO avoid opening stream to retrieve capabilities of a profile.
-        void broadcastDeviceConnectionState(audio_devices_t device,
-                                            audio_policy_dev_state_t state,
-                                            const String8 &device_address);
+        void broadcastDeviceConnectionState(const sp<DeviceDescriptor> &device,
+                                            audio_policy_dev_state_t state);
 
         // updates device caching and output for streams that can influence the
         //    routing of notifications
         void handleNotificationRoutingForStream(audio_stream_type_t stream);
-        // find the outputs on a given output descriptor that have the given address.
-        // to be called on an AudioOutputDescriptor whose supported devices (as defined
-        //   in mProfile->mSupportedDevices) matches the device whose address is to be matched.
-        // see deviceDistinguishesOnAddress(audio_devices_t) for whether the device type is one
-        //   where addresses are used to distinguish between one connected device and another.
-        void findIoHandlesByAddress(const sp<SwAudioOutputDescriptor>& desc /*in*/,
-                const audio_devices_t device /*in*/,
-                const String8& address /*in*/,
-                SortedVector<audio_io_handle_t>& outputs /*out*/);
         uint32_t curAudioPortGeneration() const { return mAudioPortGeneration; }
+        // internal method, get audio_attributes_t from either a source audio_attributes_t
+        // or audio_stream_type_t, respectively.
+        status_t getAudioAttributes(audio_attributes_t *dstAttr,
+                const audio_attributes_t *srcAttr,
+                audio_stream_type_t srcStream);
+        // internal method, called by getOutputForAttr() and connectAudioSource.
+        status_t getOutputForAttrInt(audio_attributes_t *resultAttr,
+                audio_io_handle_t *output,
+                audio_session_t session,
+                const audio_attributes_t *attr,
+                audio_stream_type_t *stream,
+                uid_t uid,
+                const audio_config_t *config,
+                audio_output_flags_t *flags,
+                audio_port_handle_t *selectedDeviceId,
+                bool *isRequestedDeviceForExclusiveUse,
+                std::vector<sp<SwAudioOutputDescriptor>> *secondaryDescs);
         // internal method to return the output handle for the given device and format
-        audio_io_handle_t getOutputForDevice(
-                audio_devices_t device,
+        audio_io_handle_t getOutputForDevices(
+                const DeviceVector &devices,
                 audio_session_t session,
                 audio_stream_type_t stream,
                 const audio_config_t *config,
-                audio_output_flags_t *flags);
-        // internal method to return the input handle for the given device and format
-        audio_io_handle_t getInputForDevice(audio_devices_t device,
-                String8 address,
+                audio_output_flags_t *flags,
+                bool forceMutingHaptic = false);
+
+        /**
+         * @brief getInputForDevice selects an input handle for a given input device and
+         * requester context
+         * @param device to be used by requester, selected by policy mix rules or engine
+         * @param session requester session id
+         * @param uid requester uid
+         * @param attributes requester audio attributes (e.g. input source and tags matter)
+         * @param config requester audio configuration (e.g. sample rate, format, channel mask).
+         * @param flags requester input flags
+         * @param policyMix may be null, policy rules to be followed by the requester
+         * @return input io handle aka unique input identifier selected for this device.
+         */
+        audio_io_handle_t getInputForDevice(const sp<DeviceDescriptor> &device,
                 audio_session_t session,
-                uid_t uid,
-                audio_source_t inputSource,
+                const audio_attributes_t &attributes,
                 const audio_config_base_t *config,
                 audio_input_flags_t flags,
                 const sp<AudioPolicyMix> &policyMix);
 
-        // internal function to derive a stream type value from audio attributes
-        audio_stream_type_t streamTypefromAttributesInt(const audio_attributes_t *attr);
         // event is one of STARTING_OUTPUT, STARTING_BEACON, STOPPING_OUTPUT, STOPPING_BEACON
         // returns 0 if no mute/unmute event happened, the largest latency of the device where
         //   the mute/unmute happened
@@ -669,25 +843,35 @@
         uint32_t setBeaconMute(bool mute);
         bool     isValidAttributes(const audio_attributes_t *paa);
 
-        // select input device corresponding to requested audio source and return associated policy
-        // mix if any. Calls getDeviceForInputSource().
-        audio_devices_t getDeviceAndMixForInputSource(audio_source_t inputSource,
-                                                      sp<AudioPolicyMix> *policyMix = NULL);
-
         // Called by setDeviceConnectionState().
-        status_t setDeviceConnectionStateInt(audio_devices_t device,
-                                                          audio_policy_dev_state_t state,
-                                                          const char *device_address,
-                                                          const char *device_name);
+        status_t setDeviceConnectionStateInt(audio_devices_t deviceType,
+                                             audio_policy_dev_state_t state,
+                                             const char *device_address,
+                                             const char *device_name,
+                                             audio_format_t encodedFormat);
+
+        void setEngineDeviceConnectionState(const sp<DeviceDescriptor> device,
+                                      audio_policy_dev_state_t state);
+
         void updateMono(audio_io_handle_t output) {
             AudioParameter param;
             param.addInt(String8(AudioParameter::keyMonoOutput), (int)mMasterMono);
             mpClientInterface->setParameters(output, param.toString());
         }
+        status_t installPatch(const char *caller,
+                audio_patch_handle_t *patchHandle,
+                AudioIODescriptorInterface *ioDescriptor,
+                const struct audio_patch *patch,
+                int delayMs);
+        status_t installPatch(const char *caller,
+                ssize_t index,
+                audio_patch_handle_t *patchHandle,
+                const struct audio_patch *patch,
+                int delayMs,
+                uid_t uid,
+                sp<AudioPatch> *patchDescPtr);
 
-        bool soundTriggerSupportsConcurrentCapture();
-        bool mSoundTriggerSupportsConcurrentCapture;
-        bool mHasComputedSoundTriggerSupportsConcurrentCapture;
+        void cleanUpEffectsForIo(audio_io_handle_t io);
 };
 
 };
diff --git a/services/audiopolicy/service/Android.mk b/services/audiopolicy/service/Android.mk
new file mode 100644
index 0000000..c4f4c56
--- /dev/null
+++ b/services/audiopolicy/service/Android.mk
@@ -0,0 +1,49 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+    AudioPolicyService.cpp \
+    AudioPolicyEffects.cpp \
+    AudioPolicyInterfaceImpl.cpp \
+    AudioPolicyClientImpl.cpp
+
+LOCAL_C_INCLUDES := \
+    frameworks/av/services/audioflinger \
+    $(call include-path-for, audio-utils)
+
+LOCAL_HEADER_LIBRARIES := \
+    libaudiopolicycommon \
+    libaudiopolicyengine_interface_headers \
+    libaudiopolicymanager_interface_headers
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    libutils \
+    liblog \
+    libbinder \
+    libaudioclient \
+    libaudioutils \
+    libhardware_legacy \
+    libaudiopolicymanager \
+    libmedia_helper \
+    libmediametrics \
+    libmediautils \
+    libeffectsconfig \
+    libsensorprivacy
+
+LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
+    libsensorprivacy
+
+LOCAL_STATIC_LIBRARIES := \
+    libaudiopolicycomponents
+
+LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
+
+LOCAL_MODULE:= libaudiopolicyservice
+
+LOCAL_CFLAGS += -fvisibility=hidden
+LOCAL_CFLAGS += -Wall -Werror
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index b064f8c..d51cc6e 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -155,17 +155,6 @@
     return result;
 }
 
-status_t AudioPolicyService::AudioPolicyClient::startTone(audio_policy_tone_t tone,
-              audio_stream_type_t stream)
-{
-    return mAudioPolicyService->startTone(tone, stream);
-}
-
-status_t AudioPolicyService::AudioPolicyClient::stopTone()
-{
-    return mAudioPolicyService->stopTone();
-}
-
 status_t AudioPolicyService::AudioPolicyClient::setVoiceVolume(float volume, int delay_ms)
 {
     return mAudioPolicyService->setVoiceVolume(volume, delay_ms);
@@ -183,6 +172,13 @@
     return af->moveEffects(session, src_output, dst_output);
 }
 
+void AudioPolicyService::AudioPolicyClient::setEffectSuspended(int effectId,
+                                audio_session_t sessionId,
+                                bool suspended)
+{
+    mAudioPolicyService->setEffectSuspended(effectId, sessionId, suspended);
+}
+
 status_t AudioPolicyService::AudioPolicyClient::createAudioPatch(const struct audio_patch *patch,
                                                                   audio_patch_handle_t *handle,
                                                                   int delayMs)
@@ -220,12 +216,23 @@
 }
 
 void AudioPolicyService::AudioPolicyClient::onRecordingConfigurationUpdate(
-        int event, const record_client_info_t *clientInfo,
-        const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
-        audio_patch_handle_t patchHandle)
+                                                    int event,
+                                                    const record_client_info_t *clientInfo,
+                                                    const audio_config_base_t *clientConfig,
+                                                    std::vector<effect_descriptor_t> clientEffects,
+                                                    const audio_config_base_t *deviceConfig,
+                                                    std::vector<effect_descriptor_t> effects,
+                                                    audio_patch_handle_t patchHandle,
+                                                    audio_source_t source)
 {
     mAudioPolicyService->onRecordingConfigurationUpdate(event, clientInfo,
-            clientConfig, deviceConfig, patchHandle);
+            clientConfig, clientEffects, deviceConfig, effects, patchHandle, source);
+}
+
+void AudioPolicyService::AudioPolicyClient::onAudioVolumeGroupChanged(volume_group_t group,
+                                                                      int flags)
+{
+    mAudioPolicyService->onAudioVolumeGroupChanged(group, flags);
 }
 
 audio_unique_id_t AudioPolicyService::AudioPolicyClient::newAudioUniqueId(audio_unique_id_use_t use)
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
index c7dfe0f..4947714 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/service/AudioPolicyEffects.cpp
@@ -24,6 +24,7 @@
 #include <cutils/misc.h>
 #include <media/AudioEffect.h>
 #include <media/EffectsConfig.h>
+#include <mediautils/ServiceUtilities.h>
 #include <system/audio.h>
 #include <system/audio_effects/audio_effects_conf.h>
 #include <utils/Vector.h>
@@ -31,7 +32,6 @@
 #include <cutils/config_utils.h>
 #include <binder/IPCThreadState.h>
 #include "AudioPolicyEffects.h"
-#include "ServiceUtilities.h"
 
 namespace android {
 
@@ -317,6 +317,201 @@
     return status;
 }
 
+status_t AudioPolicyEffects::addSourceDefaultEffect(const effect_uuid_t *type,
+                                                    const String16& opPackageName,
+                                                    const effect_uuid_t *uuid,
+                                                    int32_t priority,
+                                                    audio_source_t source,
+                                                    audio_unique_id_t* id)
+{
+    if (uuid == NULL || type == NULL) {
+        ALOGE("addSourceDefaultEffect(): Null uuid or type uuid pointer");
+        return BAD_VALUE;
+    }
+
+    // HOTWORD, FM_TUNER and ECHO_REFERENCE are special case sources > MAX.
+    if (source < AUDIO_SOURCE_DEFAULT ||
+            (source > AUDIO_SOURCE_MAX &&
+             source != AUDIO_SOURCE_HOTWORD &&
+             source != AUDIO_SOURCE_FM_TUNER &&
+             source != AUDIO_SOURCE_ECHO_REFERENCE)) {
+        ALOGE("addSourceDefaultEffect(): Unsupported source type %d", source);
+        return BAD_VALUE;
+    }
+
+    // Check that |uuid| or |type| corresponds to an effect on the system.
+    effect_descriptor_t descriptor = {};
+    status_t res = AudioEffect::getEffectDescriptor(
+            uuid, type, EFFECT_FLAG_TYPE_PRE_PROC, &descriptor);
+    if (res != OK) {
+        ALOGE("addSourceDefaultEffect(): Failed to find effect descriptor matching uuid/type.");
+        return res;
+    }
+
+    // Only pre-processing effects can be added dynamically as source defaults.
+    if ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_PRE_PROC) {
+        ALOGE("addSourceDefaultEffect(): Desired effect cannot be attached "
+              "as a source default effect.");
+        return BAD_VALUE;
+    }
+
+    Mutex::Autolock _l(mLock);
+
+    // Find the EffectDescVector for the given source type, or create a new one if necessary.
+    ssize_t index = mInputSources.indexOfKey(source);
+    EffectDescVector *desc = NULL;
+    if (index < 0) {
+        // No effects for this source type yet.
+        desc = new EffectDescVector();
+        mInputSources.add(source, desc);
+    } else {
+        desc = mInputSources.valueAt(index);
+    }
+
+    // Create a new effect and add it to the vector.
+    res = AudioEffect::newEffectUniqueId(id);
+    if (res != OK) {
+        ALOGE("addSourceDefaultEffect(): failed to get new unique id.");
+        return res;
+    }
+    EffectDesc *effect = new EffectDesc(
+            descriptor.name, *type, opPackageName, *uuid, priority, *id);
+    desc->mEffects.add(effect);
+    // TODO(b/71813697): Support setting params as well.
+
+    // TODO(b/71814300): Retroactively attach to any existing sources of the given type.
+    // This requires tracking the source type of each session id in addition to what is
+    // already being tracked.
+
+    return NO_ERROR;
+}
+
+status_t AudioPolicyEffects::addStreamDefaultEffect(const effect_uuid_t *type,
+                                                    const String16& opPackageName,
+                                                    const effect_uuid_t *uuid,
+                                                    int32_t priority,
+                                                    audio_usage_t usage,
+                                                    audio_unique_id_t* id)
+{
+    if (uuid == NULL || type == NULL) {
+        ALOGE("addStreamDefaultEffect(): Null uuid or type uuid pointer");
+        return BAD_VALUE;
+    }
+    audio_stream_type_t stream = AudioSystem::attributesToStreamType(attributes_initializer(usage));
+
+    if (stream < AUDIO_STREAM_MIN || stream >= AUDIO_STREAM_PUBLIC_CNT) {
+        ALOGE("addStreamDefaultEffect(): Unsupported stream type %d", stream);
+        return BAD_VALUE;
+    }
+
+    // Check that |uuid| or |type| corresponds to an effect on the system.
+    effect_descriptor_t descriptor = {};
+    status_t res = AudioEffect::getEffectDescriptor(
+            uuid, type, EFFECT_FLAG_TYPE_INSERT, &descriptor);
+    if (res != OK) {
+        ALOGE("addStreamDefaultEffect(): Failed to find effect descriptor matching uuid/type.");
+        return res;
+    }
+
+    // Only insert effects can be added dynamically as stream defaults.
+    if ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_INSERT) {
+        ALOGE("addStreamDefaultEffect(): Desired effect cannot be attached "
+              "as a stream default effect.");
+        return BAD_VALUE;
+    }
+
+    Mutex::Autolock _l(mLock);
+
+    // Find the EffectDescVector for the given stream type, or create a new one if necessary.
+    ssize_t index = mOutputStreams.indexOfKey(stream);
+    EffectDescVector *desc = NULL;
+    if (index < 0) {
+        // No effects for this stream type yet.
+        desc = new EffectDescVector();
+        mOutputStreams.add(stream, desc);
+    } else {
+        desc = mOutputStreams.valueAt(index);
+    }
+
+    // Create a new effect and add it to the vector.
+    res = AudioEffect::newEffectUniqueId(id);
+    if (res != OK) {
+        ALOGE("addStreamDefaultEffect(): failed to get new unique id.");
+        return res;
+    }
+    EffectDesc *effect = new EffectDesc(
+            descriptor.name, *type, opPackageName, *uuid, priority, *id);
+    desc->mEffects.add(effect);
+    // TODO(b/71813697): Support setting params as well.
+
+    // TODO(b/71814300): Retroactively attach to any existing streams of the given type.
+    // This requires tracking the stream type of each session id in addition to what is
+    // already being tracked.
+
+    return NO_ERROR;
+}
+
+status_t AudioPolicyEffects::removeSourceDefaultEffect(audio_unique_id_t id)
+{
+    if (id == AUDIO_UNIQUE_ID_ALLOCATE) {
+        // ALLOCATE is not a unique identifier, but rather a reserved value indicating
+        // a real id has not been assigned. For default effects, this value is only used
+        // by system-owned defaults from the loaded config, which cannot be removed.
+        return BAD_VALUE;
+    }
+
+    Mutex::Autolock _l(mLock);
+
+    // Check each source type.
+    size_t numSources = mInputSources.size();
+    for (size_t i = 0; i < numSources; ++i) {
+        // Check each effect for each source.
+        EffectDescVector* descVector = mInputSources[i];
+        for (auto desc = descVector->mEffects.begin(); desc != descVector->mEffects.end(); ++desc) {
+            if ((*desc)->mId == id) {
+                // Found it!
+                // TODO(b/71814300): Remove from any sources the effect was attached to.
+                descVector->mEffects.erase(desc);
+                // Handles are unique; there can only be one match, so return early.
+                return NO_ERROR;
+            }
+        }
+    }
+
+    // Effect wasn't found, so it's been trivially removed successfully.
+    return NO_ERROR;
+}
+
+status_t AudioPolicyEffects::removeStreamDefaultEffect(audio_unique_id_t id)
+{
+    if (id == AUDIO_UNIQUE_ID_ALLOCATE) {
+        // ALLOCATE is not a unique identifier, but rather a reserved value indicating
+        // a real id has not been assigned. For default effects, this value is only used
+        // by system-owned defaults from the loaded config, which cannot be removed.
+        return BAD_VALUE;
+    }
+
+    Mutex::Autolock _l(mLock);
+
+    // Check each stream type.
+    size_t numStreams = mOutputStreams.size();
+    for (size_t i = 0; i < numStreams; ++i) {
+        // Check each effect for each stream.
+        EffectDescVector* descVector = mOutputStreams[i];
+        for (auto desc = descVector->mEffects.begin(); desc != descVector->mEffects.end(); ++desc) {
+            if ((*desc)->mId == id) {
+                // Found it!
+                // TODO(b/71814300): Remove from any streams the effect was attached to.
+                descVector->mEffects.erase(desc);
+                // Handles are unique; there can only be one match, so return early.
+                return NO_ERROR;
+            }
+        }
+    }
+
+    // Effect wasn't found, so it's been trivially removed successfully.
+    return NO_ERROR;
+}
 
 void AudioPolicyEffects::EffectVector::setProcessorEnabled(bool enabled)
 {
@@ -338,7 +533,8 @@
     CAMCORDER_SRC_TAG,
     VOICE_REC_SRC_TAG,
     VOICE_COMM_SRC_TAG,
-    UNPROCESSED_SRC_TAG
+    UNPROCESSED_SRC_TAG,
+    VOICE_PERFORMANCE_SRC_TAG
 };
 
 // returns the audio_source_t enum corresponding to the input source name or
@@ -460,12 +656,13 @@
         len = strnlen(node->value, EFFECT_STRING_LEN_MAX);
         if (*curSize + len + 1 > *totSize) {
             *totSize = *curSize + len + 1;
-            *param = (char *)realloc(*param, *totSize);
-            if (*param == NULL) {
+            char *newParam = (char *)realloc(*param, *totSize);
+            if (newParam == NULL) {
                 len = 0;
                 ALOGE("%s realloc error for string len %zu", __func__, *totSize);
                 goto exit;
             }
+            *param = newParam;
         }
         strncpy(*param + *curSize, node->value, len);
         *curSize += len;
diff --git a/services/audiopolicy/service/AudioPolicyEffects.h b/services/audiopolicy/service/AudioPolicyEffects.h
index 623180e..dcf093b 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.h
+++ b/services/audiopolicy/service/AudioPolicyEffects.h
@@ -64,7 +64,6 @@
     status_t releaseInputEffects(audio_io_handle_t input,
                                  audio_session_t audioSession);
 
-
     // Return a list of effect descriptors for default output effects
     // associated with audioSession
     status_t queryDefaultOutputSessionEffects(audio_session_t audioSession,
@@ -82,18 +81,60 @@
                              audio_stream_type_t stream,
                              audio_session_t audioSession);
 
+    // Add the effect to the list of default effects for sources of type |source|.
+    status_t addSourceDefaultEffect(const effect_uuid_t *type,
+                                    const String16& opPackageName,
+                                    const effect_uuid_t *uuid,
+                                    int32_t priority,
+                                    audio_source_t source,
+                                    audio_unique_id_t* id);
+
+    // Add the effect to the list of default effects for streams of a given usage.
+    status_t addStreamDefaultEffect(const effect_uuid_t *type,
+                                    const String16& opPackageName,
+                                    const effect_uuid_t *uuid,
+                                    int32_t priority,
+                                    audio_usage_t usage,
+                                    audio_unique_id_t* id);
+
+    // Remove the default source effect from wherever it's attached.
+    status_t removeSourceDefaultEffect(audio_unique_id_t id);
+
+    // Remove the default stream effect from wherever it's attached.
+    status_t removeStreamDefaultEffect(audio_unique_id_t id);
+
 private:
 
     // class to store the description of an effects and its parameters
     // as defined in audio_effects.conf
     class EffectDesc {
     public:
-        EffectDesc(const char *name, const effect_uuid_t& uuid) :
+        EffectDesc(const char *name,
+                   const effect_uuid_t& typeUuid,
+                   const String16& opPackageName,
+                   const effect_uuid_t& uuid,
+                   uint32_t priority,
+                   audio_unique_id_t id) :
                         mName(strdup(name)),
-                        mUuid(uuid) { }
+                        mTypeUuid(typeUuid),
+                        mOpPackageName(opPackageName),
+                        mUuid(uuid),
+                        mPriority(priority),
+                        mId(id) { }
+        EffectDesc(const char *name, const effect_uuid_t& uuid) :
+                        EffectDesc(name,
+                                   *EFFECT_UUID_NULL,
+                                   String16(""),
+                                   uuid,
+                                   0,
+                                   AUDIO_UNIQUE_ID_ALLOCATE) { }
         EffectDesc(const EffectDesc& orig) :
                         mName(strdup(orig.mName)),
-                        mUuid(orig.mUuid) {
+                        mTypeUuid(orig.mTypeUuid),
+                        mOpPackageName(orig.mOpPackageName),
+                        mUuid(orig.mUuid),
+                        mPriority(orig.mPriority),
+                        mId(orig.mId) {
                             // deep copy mParams
                             for (size_t k = 0; k < orig.mParams.size(); k++) {
                                 effect_param_t *origParam = orig.mParams[k];
@@ -116,7 +157,11 @@
             }
         }
         char *mName;
+        effect_uuid_t mTypeUuid;
+        String16 mOpPackageName;
         effect_uuid_t mUuid;
+        int32_t mPriority;
+        audio_unique_id_t mId;
         Vector <effect_param_t *> mParams;
     };
 
@@ -180,6 +225,8 @@
                          size_t *totSize);
 
     // protects access to mInputSources, mInputSessions, mOutputStreams, mOutputSessions
+    // never hold AudioPolicyService::mLock when calling AudioPolicyEffects methods as
+    // those can call back into AudioPolicyService methods and try to acquire the mutex
     Mutex mLock;
     // Automatic input effects are configured per audio_source_t
     KeyedVector< audio_source_t, EffectDescVector* > mInputSources;
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 7337f04..fa8da89 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -17,12 +17,11 @@
 #define LOG_TAG "AudioPolicyIntefaceImpl"
 //#define LOG_NDEBUG 0
 
-#include <utils/Log.h>
-#include <media/MediaAnalyticsItem.h>
-
 #include "AudioPolicyService.h"
-#include "ServiceUtilities.h"
 #include "TypeConverter.h"
+#include <media/MediaAnalyticsItem.h>
+#include <media/AudioPolicy.h>
+#include <utils/Log.h>
 
 namespace android {
 
@@ -32,7 +31,8 @@
 status_t AudioPolicyService::setDeviceConnectionState(audio_devices_t device,
                                                   audio_policy_dev_state_t state,
                                                   const char *device_address,
-                                                  const char *device_name)
+                                                  const char *device_name,
+                                                  audio_format_t encodedFormat)
 {
     if (mAudioPolicyManager == NULL) {
         return NO_INIT;
@@ -49,7 +49,7 @@
     Mutex::Autolock _l(mLock);
     AutoCallerClear acc;
     return mAudioPolicyManager->setDeviceConnectionState(device, state,
-                                                         device_address, device_name);
+                                                         device_address, device_name, encodedFormat);
 }
 
 audio_policy_dev_state_t AudioPolicyService::getDeviceConnectionState(
@@ -66,7 +66,8 @@
 
 status_t AudioPolicyService::handleDeviceConfigChange(audio_devices_t device,
                                                   const char *device_address,
-                                                  const char *device_name)
+                                                  const char *device_name,
+                                                  audio_format_t encodedFormat)
 {
     if (mAudioPolicyManager == NULL) {
         return NO_INIT;
@@ -79,7 +80,7 @@
     Mutex::Autolock _l(mLock);
     AutoCallerClear acc;
     return mAudioPolicyManager->handleDeviceConfigChange(device, device_address,
-                                                         device_name);
+                                                         device_name, encodedFormat);
 }
 
 status_t AudioPolicyService::setPhoneState(audio_mode_t state)
@@ -165,7 +166,7 @@
     return mAudioPolicyManager->getOutput(stream);
 }
 
-status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr,
+status_t AudioPolicyService::getOutputForAttr(audio_attributes_t *attr,
                                               audio_io_handle_t *output,
                                               audio_session_t session,
                                               audio_stream_type_t *stream,
@@ -174,7 +175,8 @@
                                               const audio_config_t *config,
                                               audio_output_flags_t flags,
                                               audio_port_handle_t *selectedDeviceId,
-                                              audio_port_handle_t *portId)
+                                              audio_port_handle_t *portId,
+                                              std::vector<audio_io_handle_t> *secondaryOutputs)
 {
     if (mAudioPolicyManager == NULL) {
         return NO_INIT;
@@ -183,16 +185,24 @@
     Mutex::Autolock _l(mLock);
 
     const uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    if (!isTrustedCallingUid(callingUid) || uid == (uid_t)-1) {
+    if (!isAudioServerOrMediaServerUid(callingUid) || uid == (uid_t)-1) {
         ALOGW_IF(uid != (uid_t)-1 && uid != callingUid,
                 "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, uid);
         uid = callingUid;
     }
+    if (!mPackageManager.allowPlaybackCapture(uid)) {
+        attr->flags |= AUDIO_FLAG_NO_MEDIA_PROJECTION;
+    }
+    if (((attr->flags & (AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY|AUDIO_FLAG_BYPASS_MUTE)) != 0)
+            && !bypassInterruptionPolicyAllowed(pid, uid)) {
+        attr->flags &= ~(AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY|AUDIO_FLAG_BYPASS_MUTE);
+    }
     audio_output_flags_t originalFlags = flags;
     AutoCallerClear acc;
     status_t result = mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid,
                                                  config,
-                                                 &flags, selectedDeviceId, portId);
+                                                 &flags, selectedDeviceId, portId,
+                                                 secondaryOutputs);
 
     // FIXME: Introduce a way to check for the the telephony device before opening the output
     if ((result == NO_ERROR) &&
@@ -200,105 +210,134 @@
         !modifyPhoneStateAllowed(pid, uid)) {
         // If the app tries to play music through the telephony device and doesn't have permission
         // the fallback to the default output device.
-        mAudioPolicyManager->releaseOutput(*output, *stream, session);
+        mAudioPolicyManager->releaseOutput(*portId);
         flags = originalFlags;
         *selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
         *portId = AUDIO_PORT_HANDLE_NONE;
-        result = mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid,
-                                                 config,
-                                                 &flags, selectedDeviceId, portId);
+        secondaryOutputs->clear();
+        result = mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid, config,
+                                                       &flags, selectedDeviceId, portId,
+                                                       secondaryOutputs);
+    }
+
+    if (result == NO_ERROR) {
+        sp <AudioPlaybackClient> client =
+            new AudioPlaybackClient(*attr, *output, uid, pid, session, *selectedDeviceId, *stream);
+        mAudioPlaybackClients.add(*portId, client);
     }
     return result;
 }
 
-status_t AudioPolicyService::startOutput(audio_io_handle_t output,
-                                         audio_stream_type_t stream,
-                                         audio_session_t session)
+void AudioPolicyService::getPlaybackClientAndEffects(audio_port_handle_t portId,
+                                                     sp<AudioPlaybackClient>& client,
+                                                     sp<AudioPolicyEffects>& effects,
+                                                     const char *context)
 {
-    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
-        return BAD_VALUE;
+    Mutex::Autolock _l(mLock);
+    const ssize_t index = mAudioPlaybackClients.indexOfKey(portId);
+    if (index < 0) {
+        ALOGE("%s AudioTrack client not found for portId %d", context, portId);
+        return;
     }
+    client = mAudioPlaybackClients.valueAt(index);
+    effects = mAudioPolicyEffects;
+}
+
+status_t AudioPolicyService::startOutput(audio_port_handle_t portId)
+{
     if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
     ALOGV("startOutput()");
+    sp<AudioPlaybackClient> client;
     sp<AudioPolicyEffects>audioPolicyEffects;
-    {
-        Mutex::Autolock _l(mLock);
-        audioPolicyEffects = mAudioPolicyEffects;
-    }
+
+    getPlaybackClientAndEffects(portId, client, audioPolicyEffects, __func__);
+
     if (audioPolicyEffects != 0) {
         // create audio processors according to stream
-        status_t status = audioPolicyEffects->addOutputSessionEffects(output, stream, session);
+        status_t status = audioPolicyEffects->addOutputSessionEffects(
+            client->io, client->stream, client->session);
         if (status != NO_ERROR && status != ALREADY_EXISTS) {
-            ALOGW("Failed to add effects on session %d", session);
+            ALOGW("Failed to add effects on session %d", client->session);
         }
     }
     Mutex::Autolock _l(mLock);
     AutoCallerClear acc;
-    return mAudioPolicyManager->startOutput(output, stream, session);
+    status_t status = mAudioPolicyManager->startOutput(portId);
+    if (status == NO_ERROR) {
+        client->active = true;
+    }
+    return status;
 }
 
-status_t AudioPolicyService::stopOutput(audio_io_handle_t output,
-                                        audio_stream_type_t stream,
-                                        audio_session_t session)
+status_t AudioPolicyService::stopOutput(audio_port_handle_t portId)
 {
-    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
-        return BAD_VALUE;
-    }
     if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
     ALOGV("stopOutput()");
-    mOutputCommandThread->stopOutputCommand(output, stream, session);
+    mOutputCommandThread->stopOutputCommand(portId);
     return NO_ERROR;
 }
 
-status_t  AudioPolicyService::doStopOutput(audio_io_handle_t output,
-                                      audio_stream_type_t stream,
-                                      audio_session_t session)
+status_t  AudioPolicyService::doStopOutput(audio_port_handle_t portId)
 {
-    ALOGV("doStopOutput from tid %d", gettid());
+    ALOGV("doStopOutput");
+    sp<AudioPlaybackClient> client;
     sp<AudioPolicyEffects>audioPolicyEffects;
-    {
-        Mutex::Autolock _l(mLock);
-        audioPolicyEffects = mAudioPolicyEffects;
-    }
+
+    getPlaybackClientAndEffects(portId, client, audioPolicyEffects, __func__);
+
     if (audioPolicyEffects != 0) {
         // release audio processors from the stream
-        status_t status = audioPolicyEffects->releaseOutputSessionEffects(output, stream, session);
+        status_t status = audioPolicyEffects->releaseOutputSessionEffects(
+            client->io, client->stream, client->session);
         if (status != NO_ERROR && status != ALREADY_EXISTS) {
-            ALOGW("Failed to release effects on session %d", session);
+            ALOGW("Failed to release effects on session %d", client->session);
         }
     }
     Mutex::Autolock _l(mLock);
     AutoCallerClear acc;
-    return mAudioPolicyManager->stopOutput(output, stream, session);
+    status_t status = mAudioPolicyManager->stopOutput(portId);
+    if (status == NO_ERROR) {
+        client->active = false;
+    }
+    return status;
 }
 
-void AudioPolicyService::releaseOutput(audio_io_handle_t output,
-                                       audio_stream_type_t stream,
-                                       audio_session_t session)
+void AudioPolicyService::releaseOutput(audio_port_handle_t portId)
 {
     if (mAudioPolicyManager == NULL) {
         return;
     }
     ALOGV("releaseOutput()");
-    mOutputCommandThread->releaseOutputCommand(output, stream, session);
+    mOutputCommandThread->releaseOutputCommand(portId);
 }
 
-void AudioPolicyService::doReleaseOutput(audio_io_handle_t output,
-                                         audio_stream_type_t stream,
-                                         audio_session_t session)
+void AudioPolicyService::doReleaseOutput(audio_port_handle_t portId)
 {
     ALOGV("doReleaseOutput from tid %d", gettid());
+    sp<AudioPlaybackClient> client;
+    sp<AudioPolicyEffects> audioPolicyEffects;
+
+    getPlaybackClientAndEffects(portId, client, audioPolicyEffects, __func__);
+
+    if (audioPolicyEffects != 0 && client->active) {
+        // clean up effects if output was not stopped before being released
+        audioPolicyEffects->releaseOutputSessionEffects(
+            client->io, client->stream, client->session);
+    }
     Mutex::Autolock _l(mLock);
+    mAudioPlaybackClients.removeItem(portId);
+
     // called from internal thread: no need to clear caller identity
-    mAudioPolicyManager->releaseOutput(output, stream, session);
+    mAudioPolicyManager->releaseOutput(portId);
 }
 
 status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
                                              audio_io_handle_t *input,
+                                             audio_unique_id_t riid,
                                              audio_session_t session,
                                              pid_t pid,
                                              uid_t uid,
@@ -313,14 +352,17 @@
     }
 
     // already checked by client, but double-check in case the client wrapper is bypassed
-    if (attr->source < AUDIO_SOURCE_DEFAULT && attr->source >= AUDIO_SOURCE_CNT &&
-            attr->source != AUDIO_SOURCE_HOTWORD && attr->source != AUDIO_SOURCE_FM_TUNER) {
+    if ((attr->source < AUDIO_SOURCE_DEFAULT)
+            || (attr->source >= AUDIO_SOURCE_CNT
+                && attr->source != AUDIO_SOURCE_HOTWORD
+                && attr->source != AUDIO_SOURCE_FM_TUNER
+                && attr->source != AUDIO_SOURCE_ECHO_REFERENCE)) {
         return BAD_VALUE;
     }
 
     bool updatePid = (pid == -1);
     const uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    if (!isTrustedCallingUid(callingUid)) {
+    if (!isAudioServerOrMediaServerUid(callingUid)) {
         ALOGW_IF(uid != (uid_t)-1 && uid != callingUid,
                 "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, uid);
         uid = callingUid;
@@ -342,14 +384,17 @@
         return PERMISSION_DENIED;
     }
 
+    bool canCaptureOutput = captureAudioOutputAllowed(pid, uid);
     if ((attr->source == AUDIO_SOURCE_VOICE_UPLINK ||
         attr->source == AUDIO_SOURCE_VOICE_DOWNLINK ||
-        attr->source == AUDIO_SOURCE_VOICE_CALL) &&
-        !captureAudioOutputAllowed(pid, uid)) {
+        attr->source == AUDIO_SOURCE_VOICE_CALL ||
+        attr->source == AUDIO_SOURCE_ECHO_REFERENCE) &&
+        !canCaptureOutput) {
         return PERMISSION_DENIED;
     }
 
-    if ((attr->source == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed(pid, uid)) {
+    bool canCaptureHotword = captureHotwordAllowed(opPackageName, pid, uid);
+    if ((attr->source == AUDIO_SOURCE_HOTWORD) && !canCaptureHotword) {
         return BAD_VALUE;
     }
 
@@ -362,7 +407,7 @@
         {
             AutoCallerClear acc;
             // the audio_in_acoustics_t parameter is ignored by get_input()
-            status = mAudioPolicyManager->getInputForAttr(attr, input, session, uid,
+            status = mAudioPolicyManager->getInputForAttr(attr, input, riid, session, uid,
                                                          config,
                                                          flags, selectedDeviceId,
                                                          &inputType, portId);
@@ -372,12 +417,15 @@
         if (status == NO_ERROR) {
             // enforce permission (if any) required for each type of input
             switch (inputType) {
+            case AudioPolicyInterface::API_INPUT_MIX_PUBLIC_CAPTURE_PLAYBACK:
+                // this use case has been validated in audio service with a MediaProjection token,
+                // and doesn't rely on regular permissions
             case AudioPolicyInterface::API_INPUT_LEGACY:
                 break;
             case AudioPolicyInterface::API_INPUT_TELEPHONY_RX:
                 // FIXME: use the same permission as for remote submix for now.
             case AudioPolicyInterface::API_INPUT_MIX_CAPTURE:
-                if (!captureAudioOutputAllowed(pid, uid)) {
+                if (!canCaptureOutput) {
                     ALOGE("getInputForAttr() permission denied: capture not allowed");
                     status = PERMISSION_DENIED;
                 }
@@ -398,17 +446,14 @@
         if (status != NO_ERROR) {
             if (status == PERMISSION_DENIED) {
                 AutoCallerClear acc;
-                mAudioPolicyManager->releaseInput(*input, session);
+                mAudioPolicyManager->releaseInput(*portId);
             }
             return status;
         }
 
-        sp<AudioRecordClient> client =
-                new AudioRecordClient(*attr, *input, uid, pid, opPackageName, session);
-        client->active = false;
-        client->isConcurrent = false;
-        client->isVirtualDevice = false; //TODO : update from APM->getInputForAttr()
-        client->deviceId = *selectedDeviceId;
+        sp<AudioRecordClient> client = new AudioRecordClient(*attr, *input, uid, pid, session,
+                                                             *selectedDeviceId, opPackageName,
+                                                             canCaptureOutput, canCaptureHotword);
         mAudioRecordClients.add(*portId, client);
     }
 
@@ -422,48 +467,17 @@
     return NO_ERROR;
 }
 
-// this is replicated from frameworks/av/media/libaudioclient/AudioRecord.cpp
-// XXX -- figure out how to put it into a common, shared location
-
-static std::string audioSourceString(audio_source_t value) {
-    std::string source;
-    if (SourceTypeConverter::toString(value, source)) {
-        return source;
-    }
-    char rawbuffer[16];  // room for "%d"
-    snprintf(rawbuffer, sizeof(rawbuffer), "%d", value);
-    return rawbuffer;
-}
-
-static std::string audioConcurrencyString(
-        AudioPolicyInterface::concurrency_type__mask_t concurrency)
-{
-    char buffer[64]; // oversized
-    if (concurrency & AudioPolicyInterface::API_INPUT_CONCURRENCY_ALL) {
-        snprintf(buffer, sizeof(buffer), "%s%s%s%s",
-            (concurrency & AudioPolicyInterface::API_INPUT_CONCURRENCY_CALL)? ",call":"",
-            (concurrency & AudioPolicyInterface::API_INPUT_CONCURRENCY_CAPTURE)? ",capture":"",
-            (concurrency & AudioPolicyInterface::API_INPUT_CONCURRENCY_HOTWORD)? ",hotword":"",
-            (concurrency & AudioPolicyInterface::API_INPUT_CONCURRENCY_PREEMPT)? ",preempt":"");
-    } else {
-        snprintf(buffer, sizeof(buffer), ",none");
-    }
-
-    return &buffer[1];
-}
-
 std::string AudioPolicyService::getDeviceTypeStrForPortId(audio_port_handle_t portId) {
-    std::string typeStr;
     struct audio_port port = {};
     port.id = portId;
     status_t status = mAudioPolicyManager->getAudioPort(&port);
     if (status == NO_ERROR && port.type == AUDIO_PORT_TYPE_DEVICE) {
-        deviceToString(port.ext.device.type, typeStr);
+        return toString(port.ext.device.type);
     }
-    return typeStr;
+    return {};
 }
 
-status_t AudioPolicyService::startInput(audio_port_handle_t portId, bool *silenced)
+status_t AudioPolicyService::startInput(audio_port_handle_t portId)
 {
     if (mAudioPolicyManager == NULL) {
         return NO_INIT;
@@ -486,27 +500,25 @@
         return PERMISSION_DENIED;
     }
 
-    // If UID inactive it records silence until becoming active
-    *silenced = !mUidPolicy->isUidActive(client->uid) && !client->isVirtualDevice;
-
     Mutex::Autolock _l(mLock);
-    AudioPolicyInterface::concurrency_type__mask_t concurrency =
-            AudioPolicyInterface::API_INPUT_CONCURRENCY_NONE;
+
+    client->active = true;
+    client->startTimeNs = systemTime();
+    updateUidStates_l();
 
     status_t status;
     {
         AutoCallerClear acc;
-        status = mAudioPolicyManager->startInput(
-                    client->input, client->session, *silenced, &concurrency);
+        status = mAudioPolicyManager->startInput(portId);
 
     }
 
     // including successes gets very verbose
+    // but once we cut over to westworld, log them all.
     if (status != NO_ERROR) {
 
         static constexpr char kAudioPolicy[] = "audiopolicy";
 
-        static constexpr char kAudioPolicyReason[] = "android.media.audiopolicy.reason";
         static constexpr char kAudioPolicyStatus[] = "android.media.audiopolicy.status";
         static constexpr char kAudioPolicyRqstSrc[] = "android.media.audiopolicy.rqst.src";
         static constexpr char kAudioPolicyRqstPkg[] = "android.media.audiopolicy.rqst.pkg";
@@ -520,42 +532,43 @@
         static constexpr char kAudioPolicyActiveDevice[] =
                 "android.media.audiopolicy.active.device";
 
-        MediaAnalyticsItem *item = new MediaAnalyticsItem(kAudioPolicy);
+        MediaAnalyticsItem *item = MediaAnalyticsItem::create(kAudioPolicy);
         if (item != NULL) {
 
-            item->setCString(kAudioPolicyReason, audioConcurrencyString(concurrency).c_str());
             item->setInt32(kAudioPolicyStatus, status);
 
             item->setCString(kAudioPolicyRqstSrc,
-                             audioSourceString(client->attributes.source).c_str());
-            item->setCString(kAudioPolicyRqstPkg,
-                             std::string(String8(client->opPackageName).string()).c_str());
+                             toString(client->attributes.source).c_str());
             item->setInt32(kAudioPolicyRqstSession, client->session);
-
+            if (client->opPackageName.size() != 0) {
+                item->setCString(kAudioPolicyRqstPkg,
+                                 std::string(String8(client->opPackageName).string()).c_str());
+            } else {
+                item->setCString(kAudioPolicyRqstPkg, std::to_string(client->uid).c_str());
+            }
             item->setCString(
                     kAudioPolicyRqstDevice, getDeviceTypeStrForPortId(client->deviceId).c_str());
 
-            // figure out who is active
-            // NB: might the other party have given up the microphone since then? how sure.
-            // perhaps could have given up on it.
-            // we hold mLock, so perhaps we're safe for this looping
-            if (concurrency != AudioPolicyInterface::API_INPUT_CONCURRENCY_NONE) {
-                int count = mAudioRecordClients.size();
-                for (int i = 0; i<count ; i++) {
-                    if (portId == mAudioRecordClients.keyAt(i)) {
-                        continue;
-                    }
-                    sp<AudioRecordClient> other = mAudioRecordClients.valueAt(i);
-                    if (other->active) {
-                        // keeps the last of the clients marked active
-                        item->setCString(kAudioPolicyActiveSrc,
-                                         audioSourceString(other->attributes.source).c_str());
+            int count = mAudioRecordClients.size();
+            for (int i = 0; i < count ; i++) {
+                if (portId == mAudioRecordClients.keyAt(i)) {
+                    continue;
+                }
+                sp<AudioRecordClient> other = mAudioRecordClients.valueAt(i);
+                if (other->active) {
+                    // keeps the last of the clients marked active
+                    item->setCString(kAudioPolicyActiveSrc,
+                                     toString(other->attributes.source).c_str());
+                    item->setInt32(kAudioPolicyActiveSession, other->session);
+                    if (other->opPackageName.size() != 0) {
                         item->setCString(kAudioPolicyActivePkg,
-                                     std::string(String8(other->opPackageName).string()).c_str());
-                        item->setInt32(kAudioPolicyActiveSession, other->session);
-                        item->setCString(kAudioPolicyActiveDevice,
-                                         getDeviceTypeStrForPortId(other->deviceId).c_str());
+                             std::string(String8(other->opPackageName).string()).c_str());
+                    } else {
+                        item->setCString(kAudioPolicyRqstPkg,
+                                         std::to_string(other->uid).c_str());
                     }
+                    item->setCString(kAudioPolicyActiveDevice,
+                                     getDeviceTypeStrForPortId(other->deviceId).c_str());
                 }
             }
             item->selfrecord();
@@ -564,20 +577,10 @@
         }
     }
 
-    if (status == NO_ERROR) {
-        LOG_ALWAYS_FATAL_IF(concurrency & ~AudioPolicyInterface::API_INPUT_CONCURRENCY_ALL,
-                            "startInput(): invalid concurrency type %d", (int)concurrency);
-
-        // enforce permission (if any) required for each type of concurrency
-        if (concurrency & AudioPolicyInterface::API_INPUT_CONCURRENCY_CALL) {
-            //TODO: check incall capture permission
-        }
-        if (concurrency & AudioPolicyInterface::API_INPUT_CONCURRENCY_CAPTURE) {
-            //TODO: check concurrent capture permission
-        }
-
-        client->active = true;
-    } else {
+    if (status != NO_ERROR) {
+        client->active = false;
+        client->startTimeNs = 0;
+        updateUidStates_l();
         finishRecording(client->opPackageName, client->uid);
     }
 
@@ -589,6 +592,7 @@
     if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
+
     Mutex::Autolock _l(mLock);
 
     ssize_t index = mAudioRecordClients.indexOfKey(portId);
@@ -598,11 +602,14 @@
     sp<AudioRecordClient> client = mAudioRecordClients.valueAt(index);
 
     client->active = false;
+    client->startTimeNs = 0;
+
+    updateUidStates_l();
 
     // finish the recording app op
     finishRecording(client->opPackageName, client->uid);
     AutoCallerClear acc;
-    return mAudioPolicyManager->stopInput(client->input, client->session);
+    return mAudioPolicyManager->stopInput(portId);
 }
 
 void AudioPolicyService::releaseInput(audio_port_handle_t portId)
@@ -620,6 +627,14 @@
             return;
         }
         client = mAudioRecordClients.valueAt(index);
+
+        if (client->active) {
+            ALOGW("%s releasing active client portId %d", __FUNCTION__, portId);
+            client->active = false;
+            client->startTimeNs = 0;
+            updateUidStates_l();
+        }
+
         mAudioRecordClients.removeItem(portId);
     }
     if (client == 0) {
@@ -627,15 +642,15 @@
     }
     if (audioPolicyEffects != 0) {
         // release audio processors from the input
-        status_t status = audioPolicyEffects->releaseInputEffects(client->input, client->session);
+        status_t status = audioPolicyEffects->releaseInputEffects(client->io, client->session);
         if(status != NO_ERROR) {
-            ALOGW("Failed to release effects on input %d", client->input);
+            ALOGW("Failed to release effects on input %d", client->io);
         }
     }
     {
         Mutex::Autolock _l(mLock);
         AutoCallerClear acc;
-        mAudioPolicyManager->releaseInput(client->input, client->session);
+        mAudioPolicyManager->releaseInput(portId);
     }
 }
 
@@ -695,14 +710,62 @@
                                                     device);
 }
 
+status_t AudioPolicyService::setVolumeIndexForAttributes(const audio_attributes_t &attributes,
+                                                         int index, audio_devices_t device)
+{
+    if (mAudioPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+    Mutex::Autolock _l(mLock);
+    AutoCallerClear acc;
+    return mAudioPolicyManager->setVolumeIndexForAttributes(attributes, index, device);
+}
+
+status_t AudioPolicyService::getVolumeIndexForAttributes(const audio_attributes_t &attributes,
+                                                         int &index, audio_devices_t device)
+{
+    if (mAudioPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    Mutex::Autolock _l(mLock);
+    AutoCallerClear acc;
+    return mAudioPolicyManager->getVolumeIndexForAttributes(attributes, index, device);
+}
+
+status_t AudioPolicyService::getMinVolumeIndexForAttributes(const audio_attributes_t &attributes,
+                                                            int &index)
+{
+    if (mAudioPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    Mutex::Autolock _l(mLock);
+    AutoCallerClear acc;
+    return mAudioPolicyManager->getMinVolumeIndexForAttributes(attributes, index);
+}
+
+status_t AudioPolicyService::getMaxVolumeIndexForAttributes(const audio_attributes_t &attributes,
+                                                            int &index)
+{
+    if (mAudioPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    Mutex::Autolock _l(mLock);
+    AutoCallerClear acc;
+    return mAudioPolicyManager->getMaxVolumeIndexForAttributes(attributes, index);
+}
+
 uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
 {
     if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
-        return 0;
+        return PRODUCT_STRATEGY_NONE;
     }
     if (mAudioPolicyManager == NULL) {
-        return 0;
+        return PRODUCT_STRATEGY_NONE;
     }
+    // DO NOT LOCK, may be called from AudioFlinger with lock held, reaching deadlock
     AutoCallerClear acc;
     return mAudioPolicyManager->getStrategyForStream(stream);
 }
@@ -742,7 +805,7 @@
     if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
-    Mutex::Autolock _l(mEffectsLock);
+    Mutex::Autolock _l(mLock);
     AutoCallerClear acc;
     return mAudioPolicyManager->registerEffect(desc, io, strategy, session, id);
 }
@@ -752,7 +815,7 @@
     if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
-    Mutex::Autolock _l(mEffectsLock);
+    Mutex::Autolock _l(mLock);
     AutoCallerClear acc;
     return mAudioPolicyManager->unregisterEffect(id);
 }
@@ -762,11 +825,21 @@
     if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
-    Mutex::Autolock _l(mEffectsLock);
+    Mutex::Autolock _l(mLock);
     AutoCallerClear acc;
     return mAudioPolicyManager->setEffectEnabled(id, enabled);
 }
 
+status_t AudioPolicyService::moveEffectsToIo(const std::vector<int>& ids, audio_io_handle_t io)
+{
+    if (mAudioPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    Mutex::Autolock _l(mLock);
+    AutoCallerClear acc;
+    return mAudioPolicyManager->moveEffectsToIo(ids, io);
+}
+
 bool AudioPolicyService::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
 {
     if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
@@ -803,27 +876,114 @@
     return mAudioPolicyManager->isSourceActive(source);
 }
 
-status_t AudioPolicyService::queryDefaultPreProcessing(audio_session_t audioSession,
-                                                       effect_descriptor_t *descriptors,
-                                                       uint32_t *count)
+status_t AudioPolicyService::getAudioPolicyEffects(sp<AudioPolicyEffects>& audioPolicyEffects)
 {
     if (mAudioPolicyManager == NULL) {
-        *count = 0;
         return NO_INIT;
     }
-    sp<AudioPolicyEffects>audioPolicyEffects;
     {
         Mutex::Autolock _l(mLock);
         audioPolicyEffects = mAudioPolicyEffects;
     }
     if (audioPolicyEffects == 0) {
-        *count = 0;
         return NO_INIT;
     }
+
+    return OK;
+}
+
+status_t AudioPolicyService::queryDefaultPreProcessing(audio_session_t audioSession,
+                                                       effect_descriptor_t *descriptors,
+                                                       uint32_t *count)
+{
+    sp<AudioPolicyEffects>audioPolicyEffects;
+    status_t status = getAudioPolicyEffects(audioPolicyEffects);
+    if (status != OK) {
+        *count = 0;
+        return status;
+    }
     return audioPolicyEffects->queryDefaultInputEffects(
             (audio_session_t)audioSession, descriptors, count);
 }
 
+status_t AudioPolicyService::addSourceDefaultEffect(const effect_uuid_t *type,
+                                                    const String16& opPackageName,
+                                                    const effect_uuid_t *uuid,
+                                                    int32_t priority,
+                                                    audio_source_t source,
+                                                    audio_unique_id_t* id)
+{
+    sp<AudioPolicyEffects>audioPolicyEffects;
+    status_t status = getAudioPolicyEffects(audioPolicyEffects);
+    if (status != OK) {
+        return status;
+    }
+    if (!modifyDefaultAudioEffectsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+    return audioPolicyEffects->addSourceDefaultEffect(
+            type, opPackageName, uuid, priority, source, id);
+}
+
+status_t AudioPolicyService::addStreamDefaultEffect(const effect_uuid_t *type,
+                                                    const String16& opPackageName,
+                                                    const effect_uuid_t *uuid,
+                                                    int32_t priority,
+                                                    audio_usage_t usage,
+                                                    audio_unique_id_t* id)
+{
+    sp<AudioPolicyEffects>audioPolicyEffects;
+    status_t status = getAudioPolicyEffects(audioPolicyEffects);
+    if (status != OK) {
+        return status;
+    }
+    if (!modifyDefaultAudioEffectsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+    return audioPolicyEffects->addStreamDefaultEffect(
+            type, opPackageName, uuid, priority, usage, id);
+}
+
+status_t AudioPolicyService::removeSourceDefaultEffect(audio_unique_id_t id)
+{
+    sp<AudioPolicyEffects>audioPolicyEffects;
+    status_t status = getAudioPolicyEffects(audioPolicyEffects);
+    if (status != OK) {
+        return status;
+    }
+    if (!modifyDefaultAudioEffectsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+    return audioPolicyEffects->removeSourceDefaultEffect(id);
+}
+
+status_t AudioPolicyService::removeStreamDefaultEffect(audio_unique_id_t id)
+{
+    sp<AudioPolicyEffects>audioPolicyEffects;
+    status_t status = getAudioPolicyEffects(audioPolicyEffects);
+    if (status != OK) {
+        return status;
+    }
+    if (!modifyDefaultAudioEffectsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+    return audioPolicyEffects->removeStreamDefaultEffect(id);
+}
+
+status_t AudioPolicyService::setAllowedCapturePolicy(uid_t uid, audio_flags_mask_t capturePolicy) {
+    Mutex::Autolock _l(mLock);
+    if (mAudioPolicyManager == NULL) {
+        ALOGV("%s() mAudioPolicyManager == NULL", __func__);
+        return NO_INIT;
+    }
+    uint_t callingUid = IPCThreadState::self()->getCallingUid();
+    if (uid != callingUid) {
+        ALOGD("%s() uid invalid %d != %d", __func__, uid, callingUid);
+        return PERMISSION_DENIED;
+    }
+    return mAudioPolicyManager->setAllowedCapturePolicy(uid, capturePolicy);
+}
+
 bool AudioPolicyService::isOffloadSupported(const audio_offload_info_t& info)
 {
     if (mAudioPolicyManager == NULL) {
@@ -831,12 +991,21 @@
         return false;
     }
     Mutex::Autolock _l(mLock);
-    Mutex::Autolock _le(mEffectsLock); // isOffloadSupported queries for
-                                      // non-offloadable effects
     AutoCallerClear acc;
     return mAudioPolicyManager->isOffloadSupported(info);
 }
 
+bool AudioPolicyService::isDirectOutputSupported(const audio_config_base_t& config,
+                                                 const audio_attributes_t& attributes) {
+    if (mAudioPolicyManager == NULL) {
+        ALOGV("mAudioPolicyManager == NULL");
+        return false;
+    }
+    Mutex::Autolock _l(mLock);
+    return mAudioPolicyManager->isDirectOutputSupported(config, attributes);
+}
+
+
 status_t AudioPolicyService::listAudioPorts(audio_port_role_t role,
                                             audio_port_type_t type,
                                             unsigned int *num_ports,
@@ -940,9 +1109,22 @@
 status_t AudioPolicyService::registerPolicyMixes(const Vector<AudioMix>& mixes, bool registration)
 {
     Mutex::Autolock _l(mLock);
-    if(!modifyAudioRoutingAllowed()) {
+
+    // loopback|render only need a MediaProjection (checked in caller AudioService.java)
+    bool needModifyAudioRouting = std::any_of(mixes.begin(), mixes.end(), [](auto& mix) {
+            return !is_mix_loopback_render(mix.mRouteFlags); });
+    if (needModifyAudioRouting && !modifyAudioRoutingAllowed()) {
         return PERMISSION_DENIED;
     }
+
+    bool needCaptureMediaOutput = std::any_of(mixes.begin(), mixes.end(), [](auto& mix) {
+            return mix.mAllowPrivilegedPlaybackCapture; });
+    const uid_t callingUid = IPCThreadState::self()->getCallingUid();
+    const pid_t callingPid = IPCThreadState::self()->getCallingPid();
+    if (needCaptureMediaOutput && !captureMediaOutputAllowed(callingPid, callingUid)) {
+        return PERMISSION_DENIED;
+    }
+
     if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
@@ -954,27 +1136,53 @@
     }
 }
 
-status_t AudioPolicyService::startAudioSource(const struct audio_port_config *source,
-                                  const audio_attributes_t *attributes,
-                                  audio_patch_handle_t *handle)
-{
+status_t AudioPolicyService::setUidDeviceAffinities(uid_t uid,
+        const Vector<AudioDeviceTypeAddr>& devices) {
     Mutex::Autolock _l(mLock);
+    if(!modifyAudioRoutingAllowed()) {
+        return PERMISSION_DENIED;
+    }
     if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
     AutoCallerClear acc;
-    return mAudioPolicyManager->startAudioSource(source, attributes, handle,
-                                                 IPCThreadState::self()->getCallingUid());
+    return mAudioPolicyManager->setUidDeviceAffinities(uid, devices);
 }
 
-status_t AudioPolicyService::stopAudioSource(audio_patch_handle_t handle)
+status_t AudioPolicyService::removeUidDeviceAffinities(uid_t uid) {
+    Mutex::Autolock _l(mLock);
+    if(!modifyAudioRoutingAllowed()) {
+        return PERMISSION_DENIED;
+    }
+    if (mAudioPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    AutoCallerClear acc;
+    return mAudioPolicyManager->removeUidDeviceAffinities(uid);
+}
+
+status_t AudioPolicyService::startAudioSource(const struct audio_port_config *source,
+                                              const audio_attributes_t *attributes,
+                                              audio_port_handle_t *portId)
+{
+    Mutex::Autolock _l(mLock);
+    if (mAudioPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    // startAudioSource should be created as the calling uid
+    const uid_t callingUid = IPCThreadState::self()->getCallingUid();
+    AutoCallerClear acc;
+    return mAudioPolicyManager->startAudioSource(source, attributes, portId, callingUid);
+}
+
+status_t AudioPolicyService::stopAudioSource(audio_port_handle_t portId)
 {
     Mutex::Autolock _l(mLock);
     if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
     AutoCallerClear acc;
-    return mAudioPolicyManager->stopAudioSource(handle);
+    return mAudioPolicyManager->stopAudioSource(portId);
 }
 
 status_t AudioPolicyService::setMasterMono(bool mono)
@@ -1026,6 +1234,17 @@
                                                    surroundFormatsEnabled, reported);
 }
 
+status_t AudioPolicyService::getHwOffloadEncodingFormatsSupportedForA2DP(
+                                        std::vector<audio_format_t> *formats)
+{
+    if (mAudioPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    Mutex::Autolock _l(mLock);
+    AutoCallerClear acc;
+    return mAudioPolicyManager->getHwOffloadEncodingFormatsSupportedForA2DP(formats);
+}
+
 status_t AudioPolicyService::setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled)
 {
     if (mAudioPolicyManager == NULL) {
@@ -1036,4 +1255,74 @@
     return mAudioPolicyManager->setSurroundFormatEnabled(audioFormat, enabled);
 }
 
+status_t AudioPolicyService::setAssistantUid(uid_t uid)
+{
+    Mutex::Autolock _l(mLock);
+    mUidPolicy->setAssistantUid(uid);
+    return NO_ERROR;
+}
+
+status_t AudioPolicyService::setA11yServicesUids(const std::vector<uid_t>& uids)
+{
+    Mutex::Autolock _l(mLock);
+    mUidPolicy->setA11yUids(uids);
+    return NO_ERROR;
+}
+
+bool AudioPolicyService::isHapticPlaybackSupported()
+{
+    if (mAudioPolicyManager == NULL) {
+        ALOGW("%s, mAudioPolicyManager == NULL", __func__);
+        return false;
+    }
+    Mutex::Autolock _l(mLock);
+    AutoCallerClear acc;
+    return mAudioPolicyManager->isHapticPlaybackSupported();
+}
+
+status_t AudioPolicyService::listAudioProductStrategies(AudioProductStrategyVector &strategies)
+{
+    if (mAudioPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    Mutex::Autolock _l(mLock);
+    return mAudioPolicyManager->listAudioProductStrategies(strategies);
+}
+
+status_t AudioPolicyService::getProductStrategyFromAudioAttributes(
+        const AudioAttributes &aa, product_strategy_t &productStrategy)
+{
+    if (mAudioPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    Mutex::Autolock _l(mLock);
+    return mAudioPolicyManager->getProductStrategyFromAudioAttributes(aa, productStrategy);
+}
+
+status_t AudioPolicyService::listAudioVolumeGroups(AudioVolumeGroupVector &groups)
+{
+    if (mAudioPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    Mutex::Autolock _l(mLock);
+    return mAudioPolicyManager->listAudioVolumeGroups(groups);
+}
+
+status_t AudioPolicyService::getVolumeGroupFromAudioAttributes(const AudioAttributes &aa,
+                                                               volume_group_t &volumeGroup)
+{
+    if (mAudioPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    Mutex::Autolock _l(mLock);
+    return mAudioPolicyManager->getVolumeGroupFromAudioAttributes(aa, volumeGroup);
+}
+
+status_t AudioPolicyService::setRttEnabled(bool enabled)
+{
+    Mutex::Autolock _l(mLock);
+    mUidPolicy->setRttEnabled(enabled);
+    return NO_ERROR;
+}
+
 } // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index f3cddc3..77f7997 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -22,11 +22,11 @@
 #define __STDINT_LIMITS
 #define __STDC_LIMIT_MACROS
 #include <stdint.h>
-
 #include <sys/time.h>
+
+#include <audio_utils/clock.h>
 #include <binder/IServiceManager.h>
 #include <utils/Log.h>
-#include <cutils/multiuser.h>
 #include <cutils/properties.h>
 #include <binder/IPCThreadState.h>
 #include <binder/ActivityManager.h>
@@ -35,23 +35,21 @@
 #include <utils/String16.h>
 #include <utils/threads.h>
 #include "AudioPolicyService.h"
-#include "ServiceUtilities.h"
 #include <hardware_legacy/power.h>
 #include <media/AudioEffect.h>
 #include <media/AudioParameter.h>
+#include <mediautils/ServiceUtilities.h>
+#include <sensorprivacy/SensorPrivacyManager.h>
 
 #include <system/audio.h>
 #include <system/audio_policy.h>
 
-#include <private/android_filesystem_config.h>
-
 namespace android {
 
 static const char kDeadlockedString[] = "AudioPolicyService may be deadlocked\n";
 static const char kCmdDeadlockedString[] = "AudioPolicyService command thread may be deadlocked\n";
 
-static const int kDumpLockRetries = 50;
-static const int kDumpLockSleepUs = 20000;
+static const int kDumpLockTimeoutNs = 1 * NANOS_PER_SECOND;
 
 static const nsecs_t kAudioCommandTimeoutNs = seconds(3); // 3 seconds
 
@@ -70,8 +68,6 @@
     {
         Mutex::Autolock _l(mLock);
 
-        // start tone playback thread
-        mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this);
         // start audio commands thread
         mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
         // start output activity command thread
@@ -89,11 +85,13 @@
 
     mUidPolicy = new UidPolicy(this);
     mUidPolicy->registerSelf();
+
+    mSensorPrivacyPolicy = new SensorPrivacyPolicy(this);
+    mSensorPrivacyPolicy->registerSelf();
 }
 
 AudioPolicyService::~AudioPolicyService()
 {
-    mTonePlaybackThread->exit();
     mAudioCommandThread->exit();
     mOutputCommandThread->exit();
 
@@ -105,6 +103,9 @@
 
     mUidPolicy->unregisterSelf();
     mUidPolicy.clear();
+
+    mSensorPrivacyPolicy->unregisterSelf();
+    mSensorPrivacyPolicy.clear();
 }
 
 // A notification client is always registered by AudioSystem when the client process
@@ -118,13 +119,17 @@
     Mutex::Autolock _l(mNotificationClientsLock);
 
     uid_t uid = IPCThreadState::self()->getCallingUid();
-    if (mNotificationClients.indexOfKey(uid) < 0) {
+    pid_t pid = IPCThreadState::self()->getCallingPid();
+    int64_t token = ((int64_t)uid<<32) | pid;
+
+    if (mNotificationClients.indexOfKey(token) < 0) {
         sp<NotificationClient> notificationClient = new NotificationClient(this,
                                                                            client,
-                                                                           uid);
-        ALOGV("registerClient() client %p, uid %d", client.get(), uid);
+                                                                           uid,
+                                                                           pid);
+        ALOGV("registerClient() client %p, uid %d pid %d", client.get(), uid, pid);
 
-        mNotificationClients.add(uid, notificationClient);
+        mNotificationClients.add(token, notificationClient);
 
         sp<IBinder> binder = IInterface::asBinder(client);
         binder->linkToDeath(notificationClient);
@@ -136,22 +141,47 @@
     Mutex::Autolock _l(mNotificationClientsLock);
 
     uid_t uid = IPCThreadState::self()->getCallingUid();
-    if (mNotificationClients.indexOfKey(uid) < 0) {
+    pid_t pid = IPCThreadState::self()->getCallingPid();
+    int64_t token = ((int64_t)uid<<32) | pid;
+
+    if (mNotificationClients.indexOfKey(token) < 0) {
         return;
     }
-    mNotificationClients.valueFor(uid)->setAudioPortCallbacksEnabled(enabled);
+    mNotificationClients.valueFor(token)->setAudioPortCallbacksEnabled(enabled);
+}
+
+void AudioPolicyService::setAudioVolumeGroupCallbacksEnabled(bool enabled)
+{
+    Mutex::Autolock _l(mNotificationClientsLock);
+
+    uid_t uid = IPCThreadState::self()->getCallingUid();
+    pid_t pid = IPCThreadState::self()->getCallingPid();
+    int64_t token = ((int64_t)uid<<32) | pid;
+
+    if (mNotificationClients.indexOfKey(token) < 0) {
+        return;
+    }
+    mNotificationClients.valueFor(token)->setAudioVolumeGroupCallbacksEnabled(enabled);
 }
 
 // removeNotificationClient() is called when the client process dies.
-void AudioPolicyService::removeNotificationClient(uid_t uid)
+void AudioPolicyService::removeNotificationClient(uid_t uid, pid_t pid)
 {
     {
         Mutex::Autolock _l(mNotificationClientsLock);
-        mNotificationClients.removeItem(uid);
+        int64_t token = ((int64_t)uid<<32) | pid;
+        mNotificationClients.removeItem(token);
     }
     {
         Mutex::Autolock _l(mLock);
-        if (mAudioPolicyManager) {
+        bool hasSameUid = false;
+        for (size_t i = 0; i < mNotificationClients.size(); i++) {
+            if (mNotificationClients.valueAt(i)->uid() == uid) {
+                hasSameUid = true;
+                break;
+            }
+        }
+        if (mAudioPolicyManager && !hasSameUid) {
             // called from binder death notification: no need to clear caller identity
             mAudioPolicyManager->releaseResourcesForUid(uid);
         }
@@ -184,6 +214,19 @@
     }
 }
 
+void AudioPolicyService::onAudioVolumeGroupChanged(volume_group_t group, int flags)
+{
+    mOutputCommandThread->changeAudioVolumeGroupCommand(group, flags);
+}
+
+void AudioPolicyService::doOnAudioVolumeGroupChanged(volume_group_t group, int flags)
+{
+    Mutex::Autolock _l(mNotificationClientsLock);
+    for (size_t i = 0; i < mNotificationClients.size(); i++) {
+        mNotificationClients.valueAt(i)->onAudioVolumeGroupChanged(group, flags);
+    }
+}
+
 void AudioPolicyService::onDynamicPolicyMixStateUpdate(const String8& regId, int32_t state)
 {
     ALOGV("AudioPolicyService::onDynamicPolicyMixStateUpdate(%s, %d)",
@@ -199,22 +242,34 @@
     }
 }
 
-void AudioPolicyService::onRecordingConfigurationUpdate(int event,
-        const record_client_info_t *clientInfo, const audio_config_base_t *clientConfig,
-        const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle)
+void AudioPolicyService::onRecordingConfigurationUpdate(
+                                                    int event,
+                                                    const record_client_info_t *clientInfo,
+                                                    const audio_config_base_t *clientConfig,
+                                                    std::vector<effect_descriptor_t> clientEffects,
+                                                    const audio_config_base_t *deviceConfig,
+                                                    std::vector<effect_descriptor_t> effects,
+                                                    audio_patch_handle_t patchHandle,
+                                                    audio_source_t source)
 {
     mOutputCommandThread->recordingConfigurationUpdateCommand(event, clientInfo,
-            clientConfig, deviceConfig, patchHandle);
+            clientConfig, clientEffects, deviceConfig, effects, patchHandle, source);
 }
 
-void AudioPolicyService::doOnRecordingConfigurationUpdate(int event,
-        const record_client_info_t *clientInfo, const audio_config_base_t *clientConfig,
-        const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle)
+void AudioPolicyService::doOnRecordingConfigurationUpdate(
+                                                  int event,
+                                                  const record_client_info_t *clientInfo,
+                                                  const audio_config_base_t *clientConfig,
+                                                  std::vector<effect_descriptor_t> clientEffects,
+                                                  const audio_config_base_t *deviceConfig,
+                                                  std::vector<effect_descriptor_t> effects,
+                                                  audio_patch_handle_t patchHandle,
+                                                  audio_source_t source)
 {
     Mutex::Autolock _l(mNotificationClientsLock);
     for (size_t i = 0; i < mNotificationClients.size(); i++) {
         mNotificationClients.valueAt(i)->onRecordingConfigurationUpdate(event, clientInfo,
-                clientConfig, deviceConfig, patchHandle);
+                clientConfig, clientEffects, deviceConfig, effects, patchHandle, source);
     }
 }
 
@@ -239,9 +294,10 @@
 
 AudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyService>& service,
                                                      const sp<IAudioPolicyServiceClient>& client,
-                                                     uid_t uid)
-    : mService(service), mUid(uid), mAudioPolicyServiceClient(client),
-      mAudioPortCallbacksEnabled(false)
+                                                     uid_t uid,
+                                                     pid_t pid)
+    : mService(service), mUid(uid), mPid(pid), mAudioPolicyServiceClient(client),
+      mAudioPortCallbacksEnabled(false), mAudioVolumeGroupCallbacksEnabled(false)
 {
 }
 
@@ -254,7 +310,7 @@
     sp<NotificationClient> keep(this);
     sp<AudioPolicyService> service = mService.promote();
     if (service != 0) {
-        service->removeNotificationClient(mUid);
+        service->removeNotificationClient(mUid, mPid);
     }
 }
 
@@ -272,22 +328,36 @@
     }
 }
 
+void AudioPolicyService::NotificationClient::onAudioVolumeGroupChanged(volume_group_t group, 
+                                                                      int flags)
+{
+    if (mAudioPolicyServiceClient != 0 && mAudioVolumeGroupCallbacksEnabled) {
+        mAudioPolicyServiceClient->onAudioVolumeGroupChanged(group, flags);
+    }
+}
+
+
 void AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate(
         const String8& regId, int32_t state)
 {
-    if (mAudioPolicyServiceClient != 0 && multiuser_get_app_id(mUid) < AID_APP_START) {
+    if (mAudioPolicyServiceClient != 0 && isServiceUid(mUid)) {
         mAudioPolicyServiceClient->onDynamicPolicyMixStateUpdate(regId, state);
     }
 }
 
 void AudioPolicyService::NotificationClient::onRecordingConfigurationUpdate(
-        int event, const record_client_info_t *clientInfo,
-        const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
-        audio_patch_handle_t patchHandle)
+                                            int event,
+                                            const record_client_info_t *clientInfo,
+                                            const audio_config_base_t *clientConfig,
+                                            std::vector<effect_descriptor_t> clientEffects,
+                                            const audio_config_base_t *deviceConfig,
+                                            std::vector<effect_descriptor_t> effects,
+                                            audio_patch_handle_t patchHandle,
+                                            audio_source_t source)
 {
-    if (mAudioPolicyServiceClient != 0 && multiuser_get_app_id(mUid) < AID_APP_START) {
+    if (mAudioPolicyServiceClient != 0 && isServiceUid(mUid)) {
         mAudioPolicyServiceClient->onRecordingConfigurationUpdate(event, clientInfo,
-                clientConfig, deviceConfig, patchHandle);
+                clientConfig, clientEffects, deviceConfig, effects, patchHandle, source);
     }
 }
 
@@ -296,23 +366,20 @@
     mAudioPortCallbacksEnabled = enabled;
 }
 
+void AudioPolicyService::NotificationClient::setAudioVolumeGroupCallbacksEnabled(bool enabled)
+{
+    mAudioVolumeGroupCallbacksEnabled = enabled;
+}
 
 void AudioPolicyService::binderDied(const wp<IBinder>& who) {
     ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(),
             IPCThreadState::self()->getCallingPid());
 }
 
-static bool tryLock(Mutex& mutex)
+static bool dumpTryLock(Mutex& mutex)
 {
-    bool locked = false;
-    for (int i = 0; i < kDumpLockRetries; ++i) {
-        if (mutex.tryLock() == NO_ERROR) {
-            locked = true;
-            break;
-        }
-        usleep(kDumpLockSleepUs);
-    }
-    return locked;
+    status_t err = mutex.timedLock(kDumpLockTimeoutNs);
+    return err == NO_ERROR;
 }
 
 status_t AudioPolicyService::dumpInternals(int fd)
@@ -325,24 +392,230 @@
     result.append(buffer);
     snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get());
     result.append(buffer);
-    snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get());
-    result.append(buffer);
 
     write(fd, result.string(), result.size());
     return NO_ERROR;
 }
 
-void AudioPolicyService::setRecordSilenced(uid_t uid, bool silenced)
+void AudioPolicyService::updateUidStates()
 {
-    {
-        Mutex::Autolock _l(mLock);
-        if (mAudioPolicyManager) {
-            AutoCallerClear acc;
-            mAudioPolicyManager->setRecordSilenced(uid, silenced);
+    Mutex::Autolock _l(mLock);
+    updateUidStates_l();
+}
+
+void AudioPolicyService::updateUidStates_l()
+{
+//    Go over all active clients and allow capture (does not force silence) in the
+//    following cases:
+//    Another client in the same UID has already been allowed to capture
+//    OR The client is the assistant
+//        AND an accessibility service is on TOP or a RTT call is active
+//               AND the source is VOICE_RECOGNITION or HOTWORD
+//        OR uses VOICE_RECOGNITION AND is on TOP
+//               OR uses HOTWORD
+//            AND there is no active privacy sensitive capture or call
+//                OR client has CAPTURE_AUDIO_OUTPUT privileged permission
+//    OR The client is an accessibility service
+//        AND is on TOP
+//        AND the source is VOICE_RECOGNITION or HOTWORD
+//    OR the client source is virtual (remote submix, call audio TX or RX...)
+//    OR Any client
+//        AND The assistant is not on TOP
+//        AND is on TOP or latest started
+//        AND there is no active privacy sensitive capture or call
+//                OR client has CAPTURE_AUDIO_OUTPUT privileged permission
+
+    sp<AudioRecordClient> topActive;
+    sp<AudioRecordClient> latestActive;
+    sp<AudioRecordClient> latestSensitiveActive;
+
+    nsecs_t topStartNs = 0;
+    nsecs_t latestStartNs = 0;
+    nsecs_t latestSensitiveStartNs = 0;
+    bool isA11yOnTop = mUidPolicy->isA11yOnTop();
+    bool isAssistantOnTop = false;
+    bool isSensitiveActive = false;
+    bool isInCall = mPhoneState == AUDIO_MODE_IN_CALL;
+    bool rttCallActive =
+            (mPhoneState == AUDIO_MODE_IN_CALL || mPhoneState == AUDIO_MODE_IN_COMMUNICATION)
+            && mUidPolicy->isRttEnabled();
+
+    // if Sensor Privacy is enabled then all recordings should be silenced.
+    if (mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
+        silenceAllRecordings_l();
+        return;
+    }
+
+    for (size_t i =0; i < mAudioRecordClients.size(); i++) {
+        sp<AudioRecordClient> current = mAudioRecordClients[i];
+        if (!current->active) {
+            continue;
         }
+
+        app_state_t appState = apmStatFromAmState(mUidPolicy->getUidState(current->uid));
+        // clients which app is in IDLE state are not eligible for top active or
+        // latest active
+        if (appState == APP_STATE_IDLE) {
+            continue;
+        }
+
+        if (appState == APP_STATE_TOP) {
+            if (current->startTimeNs > topStartNs) {
+                topActive = current;
+                topStartNs = current->startTimeNs;
+            }
+            if (mUidPolicy->isAssistantUid(current->uid)) {
+                isAssistantOnTop = true;
+            }
+        }
+        if (current->startTimeNs > latestStartNs) {
+            latestActive = current;
+            latestStartNs = current->startTimeNs;
+        }
+        if (isPrivacySensitiveSource(current->attributes.source)) {
+            if (current->startTimeNs > latestSensitiveStartNs) {
+                latestSensitiveActive = current;
+                latestSensitiveStartNs = current->startTimeNs;
+            }
+            isSensitiveActive = true;
+        }
+    }
+
+    // if no active client with UI on Top, consider latest active as top
+    if (topActive == nullptr) {
+        topActive = latestActive;
+    }
+
+    std::vector<uid_t> enabledUids;
+
+    for (size_t i =0; i < mAudioRecordClients.size(); i++) {
+        sp<AudioRecordClient> current = mAudioRecordClients[i];
+        if (!current->active) {
+            continue;
+        }
+
+        // keep capture allowed if another client with the same UID has already
+        // been allowed to capture
+        if (std::find(enabledUids.begin(), enabledUids.end(), current->uid)
+                != enabledUids.end()) {
+            continue;
+        }
+
+        audio_source_t source = current->attributes.source;
+        bool isTopOrLatestActive = topActive == nullptr ? false : current->uid == topActive->uid;
+        bool isLatestSensitive = latestSensitiveActive == nullptr ?
+                                 false : current->uid == latestSensitiveActive->uid;
+
+        // By default allow capture if:
+        //     The assistant is not on TOP
+        //     AND is on TOP or latest started
+        //     AND there is no active privacy sensitive capture or call
+        //             OR client has CAPTURE_AUDIO_OUTPUT privileged permission
+        bool allowCapture = !isAssistantOnTop
+                && ((isTopOrLatestActive && !isLatestSensitive) || isLatestSensitive)
+                && !(isSensitiveActive && !(isLatestSensitive || current->canCaptureOutput))
+                && !(isInCall && !current->canCaptureOutput);
+
+        if (isVirtualSource(source)) {
+            // Allow capture for virtual (remote submix, call audio TX or RX...) sources
+            allowCapture = true;
+        } else if (mUidPolicy->isAssistantUid(current->uid)) {
+            // For assistant allow capture if:
+            //     An accessibility service is on TOP or a RTT call is active
+            //            AND the source is VOICE_RECOGNITION or HOTWORD
+            //     OR is on TOP AND uses VOICE_RECOGNITION
+            //            OR uses HOTWORD
+            //         AND there is no active privacy sensitive capture or call
+            //             OR client has CAPTURE_AUDIO_OUTPUT privileged permission
+            if (isA11yOnTop || rttCallActive) {
+                if (source == AUDIO_SOURCE_HOTWORD || source == AUDIO_SOURCE_VOICE_RECOGNITION) {
+                    allowCapture = true;
+                }
+            } else {
+                if (((isAssistantOnTop && source == AUDIO_SOURCE_VOICE_RECOGNITION) ||
+                        source == AUDIO_SOURCE_HOTWORD) &&
+                        (!(isSensitiveActive || isInCall) || current->canCaptureOutput)) {
+                    allowCapture = true;
+                }
+            }
+        } else if (mUidPolicy->isA11yUid(current->uid)) {
+            // For accessibility service allow capture if:
+            //     Is on TOP
+            //     AND the source is VOICE_RECOGNITION or HOTWORD
+            if (isA11yOnTop &&
+                    (source == AUDIO_SOURCE_VOICE_RECOGNITION || source == AUDIO_SOURCE_HOTWORD)) {
+                allowCapture = true;
+            }
+        }
+        setAppState_l(current->uid,
+                      allowCapture ? apmStatFromAmState(mUidPolicy->getUidState(current->uid)) :
+                                APP_STATE_IDLE);
+        if (allowCapture) {
+            enabledUids.push_back(current->uid);
+        }
+    }
+}
+
+void AudioPolicyService::silenceAllRecordings_l() {
+    for (size_t i = 0; i < mAudioRecordClients.size(); i++) {
+        sp<AudioRecordClient> current = mAudioRecordClients[i];
+        if (!isVirtualSource(current->attributes.source)) {
+            setAppState_l(current->uid, APP_STATE_IDLE);
+        }
+    }
+}
+
+/* static */
+app_state_t AudioPolicyService::apmStatFromAmState(int amState) {
+
+    if (amState == ActivityManager::PROCESS_STATE_UNKNOWN) {
+        return APP_STATE_IDLE;
+    } else if (amState <= ActivityManager::PROCESS_STATE_TOP) {
+      // include persistent services
+      return APP_STATE_TOP;
+    }
+    return APP_STATE_FOREGROUND;
+}
+
+/* static */
+bool AudioPolicyService::isPrivacySensitiveSource(audio_source_t source)
+{
+    switch (source) {
+        case AUDIO_SOURCE_CAMCORDER:
+        case AUDIO_SOURCE_VOICE_COMMUNICATION:
+            return true;
+        default:
+            break;
+    }
+    return false;
+}
+
+/* static */
+bool AudioPolicyService::isVirtualSource(audio_source_t source)
+{
+    switch (source) {
+        case AUDIO_SOURCE_VOICE_UPLINK:
+        case AUDIO_SOURCE_VOICE_DOWNLINK:
+        case AUDIO_SOURCE_VOICE_CALL:
+        case AUDIO_SOURCE_REMOTE_SUBMIX:
+        case AUDIO_SOURCE_FM_TUNER:
+            return true;
+        default:
+            break;
+    }
+    return false;
+}
+
+void AudioPolicyService::setAppState_l(uid_t uid, app_state_t state)
+{
+    AutoCallerClear acc;
+
+    if (mAudioPolicyManager) {
+        mAudioPolicyManager->setAppState(uid, state);
     }
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
     if (af) {
+        bool silenced = state == APP_STATE_IDLE;
         af->setRecordSilenced(uid, silenced);
     }
 }
@@ -352,7 +625,7 @@
     if (!dumpAllowed()) {
         dumpPermissionDenial(fd);
     } else {
-        bool locked = tryLock(mLock);
+        bool locked = dumpTryLock(mLock);
         if (!locked) {
             String8 result(kDeadlockedString);
             write(fd, result.string(), result.size());
@@ -362,14 +635,13 @@
         if (mAudioCommandThread != 0) {
             mAudioCommandThread->dump(fd);
         }
-        if (mTonePlaybackThread != 0) {
-            mTonePlaybackThread->dump(fd);
-        }
 
         if (mAudioPolicyManager) {
             mAudioPolicyManager->dump(fd);
         }
 
+        mPackageManager.dump(fd);
+
         if (locked) mLock.unlock();
     }
     return NO_ERROR;
@@ -505,7 +777,8 @@
     ActivityManager am;
     am.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE
             | ActivityManager::UID_OBSERVER_IDLE
-            | ActivityManager::UID_OBSERVER_ACTIVE,
+            | ActivityManager::UID_OBSERVER_ACTIVE
+            | ActivityManager::UID_OBSERVER_PROCSTATE,
             ActivityManager::PROCESS_STATE_UNKNOWN,
             String16("audioserver"));
     status_t res = am.linkToDeath(this);
@@ -514,6 +787,7 @@
         mObserverRegistered = true;
     } else {
         ALOGE("UidPolicy::registerSelf linkToDeath failed: %d", res);
+
         am.unregisterUidObserver(this);
     }
 }
@@ -532,8 +806,7 @@
     mObserverRegistered = false;
 }
 
-bool AudioPolicyService::UidPolicy::isUidActive(uid_t uid) {
-    if (isServiceUid(uid)) return true;
+void AudioPolicyService::UidPolicy::checkRegistered() {
     bool needToReregister = false;
     {
         Mutex::Autolock _l(mLock);
@@ -543,103 +816,212 @@
         // Looks like ActivityManager has died previously, attempt to re-register.
         registerSelf();
     }
+}
+
+bool AudioPolicyService::UidPolicy::isUidActive(uid_t uid) {
+    if (isServiceUid(uid)) return true;
+    checkRegistered();
     {
         Mutex::Autolock _l(mLock);
         auto overrideIter = mOverrideUids.find(uid);
         if (overrideIter != mOverrideUids.end()) {
-            return overrideIter->second;
+            return overrideIter->second.first;
         }
         // In an absense of the ActivityManager, assume everything to be active.
         if (!mObserverRegistered) return true;
         auto cacheIter = mCachedUids.find(uid);
         if (cacheIter != mCachedUids.end()) {
-            return cacheIter->second;
+            return cacheIter->second.first;
         }
     }
     ActivityManager am;
     bool active = am.isUidActive(uid, String16("audioserver"));
     {
         Mutex::Autolock _l(mLock);
-        mCachedUids.insert(std::pair<uid_t, bool>(uid, active));
+        mCachedUids.insert(std::pair<uid_t,
+                           std::pair<bool, int>>(uid, std::pair<bool, int>(active,
+                                                      ActivityManager::PROCESS_STATE_UNKNOWN)));
     }
     return active;
 }
 
+int AudioPolicyService::UidPolicy::getUidState(uid_t uid) {
+    if (isServiceUid(uid)) {
+        return ActivityManager::PROCESS_STATE_TOP;
+    }
+    checkRegistered();
+    {
+        Mutex::Autolock _l(mLock);
+        auto overrideIter = mOverrideUids.find(uid);
+        if (overrideIter != mOverrideUids.end()) {
+            if (overrideIter->second.first) {
+                if (overrideIter->second.second != ActivityManager::PROCESS_STATE_UNKNOWN) {
+                    return overrideIter->second.second;
+                } else {
+                    auto cacheIter = mCachedUids.find(uid);
+                    if (cacheIter != mCachedUids.end()) {
+                        return cacheIter->second.second;
+                    }
+                }
+            }
+            return ActivityManager::PROCESS_STATE_UNKNOWN;
+        }
+        // In an absense of the ActivityManager, assume everything to be active.
+        if (!mObserverRegistered) {
+            return ActivityManager::PROCESS_STATE_TOP;
+        }
+        auto cacheIter = mCachedUids.find(uid);
+        if (cacheIter != mCachedUids.end()) {
+            if (cacheIter->second.first) {
+                return cacheIter->second.second;
+            } else {
+                return ActivityManager::PROCESS_STATE_UNKNOWN;
+            }
+        }
+    }
+    ActivityManager am;
+    bool active = am.isUidActive(uid, String16("audioserver"));
+    int state = ActivityManager::PROCESS_STATE_UNKNOWN;
+    if (active) {
+        state = am.getUidProcessState(uid, String16("audioserver"));
+    }
+    {
+        Mutex::Autolock _l(mLock);
+        mCachedUids.insert(std::pair<uid_t,
+                           std::pair<bool, int>>(uid, std::pair<bool, int>(active, state)));
+    }
+
+    return state;
+}
+
 void AudioPolicyService::UidPolicy::onUidActive(uid_t uid) {
-    updateUidCache(uid, true, true);
+    updateUid(&mCachedUids, uid, true, ActivityManager::PROCESS_STATE_UNKNOWN, true);
 }
 
 void AudioPolicyService::UidPolicy::onUidGone(uid_t uid, __unused bool disabled) {
-    updateUidCache(uid, false, false);
+    updateUid(&mCachedUids, uid, false, ActivityManager::PROCESS_STATE_UNKNOWN, false);
 }
 
 void AudioPolicyService::UidPolicy::onUidIdle(uid_t uid, __unused bool disabled) {
-    updateUidCache(uid, false, true);
+    updateUid(&mCachedUids, uid, false, ActivityManager::PROCESS_STATE_UNKNOWN, true);
 }
 
-bool AudioPolicyService::UidPolicy::isServiceUid(uid_t uid) const {
-    return multiuser_get_app_id(uid) < AID_APP_START;
-}
-
-void AudioPolicyService::UidPolicy::notifyService(uid_t uid, bool active) {
-    sp<AudioPolicyService> service = mService.promote();
-    if (service != nullptr) {
-        service->setRecordSilenced(uid, !active);
+void AudioPolicyService::UidPolicy::onUidStateChanged(uid_t uid,
+                                                      int32_t procState,
+                                                      int64_t procStateSeq __unused) {
+    if (procState != ActivityManager::PROCESS_STATE_UNKNOWN) {
+        updateUid(&mCachedUids, uid, true, procState, true);
     }
 }
 
 void AudioPolicyService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) {
-    if (isServiceUid(uid)) return;
-    bool wasOverridden = false, wasActive = false;
-    {
-        Mutex::Autolock _l(mLock);
-        updateUidLocked(&mOverrideUids, uid, active, insert, &wasOverridden, &wasActive);
-    }
-    if (!wasOverridden && insert) {
-        notifyService(uid, active);  // Started to override.
-    } else if (wasOverridden && !insert) {
-        notifyService(uid, isUidActive(uid));  // Override ceased, notify with ground truth.
-    } else if (wasActive != active) {
-        notifyService(uid, active);  // Override updated.
+    updateUid(&mOverrideUids, uid, active, ActivityManager::PROCESS_STATE_UNKNOWN, insert);
+}
+
+void AudioPolicyService::UidPolicy::notifyService() {
+    sp<AudioPolicyService> service = mService.promote();
+    if (service != nullptr) {
+        service->updateUidStates();
     }
 }
 
-void AudioPolicyService::UidPolicy::updateUidCache(uid_t uid, bool active, bool insert) {
-    if (isServiceUid(uid)) return;
-    bool wasActive = false;
+void AudioPolicyService::UidPolicy::updateUid(std::unordered_map<uid_t,
+                                              std::pair<bool, int>> *uids,
+                                              uid_t uid,
+                                              bool active,
+                                              int state,
+                                              bool insert) {
+    if (isServiceUid(uid)) {
+        return;
+    }
+    bool wasActive = isUidActive(uid);
+    int previousState = getUidState(uid);
     {
         Mutex::Autolock _l(mLock);
-        updateUidLocked(&mCachedUids, uid, active, insert, nullptr, &wasActive);
-        // Do not notify service if currently overridden.
-        if (mOverrideUids.find(uid) != mOverrideUids.end()) return;
+        updateUidLocked(uids, uid, active, state, insert);
     }
-    bool nowActive = active && insert;
-    if (wasActive != nowActive) notifyService(uid, nowActive);
+    if (wasActive != isUidActive(uid) || state != previousState) {
+        notifyService();
+    }
 }
 
-void AudioPolicyService::UidPolicy::updateUidLocked(std::unordered_map<uid_t, bool> *uids,
-        uid_t uid, bool active, bool insert, bool *wasThere, bool *wasActive) {
+void AudioPolicyService::UidPolicy::updateUidLocked(std::unordered_map<uid_t,
+                                                    std::pair<bool, int>> *uids,
+                                                    uid_t uid,
+                                                    bool active,
+                                                    int state,
+                                                    bool insert) {
     auto it = uids->find(uid);
     if (it != uids->end()) {
-        if (wasThere != nullptr) *wasThere = true;
-        if (wasActive != nullptr) *wasActive = it->second;
         if (insert) {
-            it->second = active;
+            if (state == ActivityManager::PROCESS_STATE_UNKNOWN) {
+                it->second.first = active;
+            }
+            if (it->second.first) {
+                it->second.second = state;
+            } else {
+                it->second.second = ActivityManager::PROCESS_STATE_UNKNOWN;
+            }
         } else {
             uids->erase(it);
         }
-    } else if (insert) {
-        uids->insert(std::pair<uid_t, bool>(uid, active));
+    } else if (insert && (state == ActivityManager::PROCESS_STATE_UNKNOWN)) {
+        uids->insert(std::pair<uid_t, std::pair<bool, int>>(uid,
+                                      std::pair<bool, int>(active, state)));
     }
 }
 
+bool AudioPolicyService::UidPolicy::isA11yOnTop() {
+    for (const auto &uid : mCachedUids) {
+        std::vector<uid_t>::iterator it = find(mA11yUids.begin(), mA11yUids.end(), uid.first);
+        if (it == mA11yUids.end()) {
+            continue;
+        }
+        if (uid.second.second >= ActivityManager::PROCESS_STATE_TOP
+                && uid.second.second <= ActivityManager::PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool AudioPolicyService::UidPolicy::isA11yUid(uid_t uid)
+{
+    std::vector<uid_t>::iterator it = find(mA11yUids.begin(), mA11yUids.end(), uid);
+    return it != mA11yUids.end();
+}
+
+// -----------  AudioPolicyService::SensorPrivacyService implementation ----------
+void AudioPolicyService::SensorPrivacyPolicy::registerSelf() {
+    SensorPrivacyManager spm;
+    mSensorPrivacyEnabled = spm.isSensorPrivacyEnabled();
+    spm.addSensorPrivacyListener(this);
+}
+
+void AudioPolicyService::SensorPrivacyPolicy::unregisterSelf() {
+    SensorPrivacyManager spm;
+    spm.removeSensorPrivacyListener(this);
+}
+
+bool AudioPolicyService::SensorPrivacyPolicy::isSensorPrivacyEnabled() {
+    return mSensorPrivacyEnabled;
+}
+
+binder::Status AudioPolicyService::SensorPrivacyPolicy::onSensorPrivacyChanged(bool enabled) {
+    mSensorPrivacyEnabled = enabled;
+    sp<AudioPolicyService> service = mService.promote();
+    if (service != nullptr) {
+        service->updateUidStates();
+    }
+    return binder::Status::ok();
+}
+
 // -----------  AudioPolicyService::AudioCommandThread implementation ----------
 
 AudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name,
                                                            const wp<AudioPolicyService>& service)
     : Thread(false), mName(name), mService(service)
 {
-    mpToneGenerator = NULL;
 }
 
 
@@ -649,7 +1031,6 @@
         release_wake_lock(mName.string());
     }
     mAudioCommands.clear();
-    delete mpToneGenerator;
 }
 
 void AudioPolicyService::AudioCommandThread::onFirstRef()
@@ -674,68 +1055,54 @@
                 mLastCommand = command;
 
                 switch (command->mCommand) {
-                case START_TONE: {
-                    mLock.unlock();
-                    ToneData *data = (ToneData *)command->mParam.get();
-                    ALOGV("AudioCommandThread() processing start tone %d on stream %d",
-                            data->mType, data->mStream);
-                    delete mpToneGenerator;
-                    mpToneGenerator = new ToneGenerator(data->mStream, 1.0);
-                    mpToneGenerator->startTone(data->mType);
-                    mLock.lock();
-                    }break;
-                case STOP_TONE: {
-                    mLock.unlock();
-                    ALOGV("AudioCommandThread() processing stop tone");
-                    if (mpToneGenerator != NULL) {
-                        mpToneGenerator->stopTone();
-                        delete mpToneGenerator;
-                        mpToneGenerator = NULL;
-                    }
-                    mLock.lock();
-                    }break;
                 case SET_VOLUME: {
                     VolumeData *data = (VolumeData *)command->mParam.get();
                     ALOGV("AudioCommandThread() processing set volume stream %d, \
                             volume %f, output %d", data->mStream, data->mVolume, data->mIO);
+                    mLock.unlock();
                     command->mStatus = AudioSystem::setStreamVolume(data->mStream,
                                                                     data->mVolume,
                                                                     data->mIO);
+                    mLock.lock();
                     }break;
                 case SET_PARAMETERS: {
                     ParametersData *data = (ParametersData *)command->mParam.get();
                     ALOGV("AudioCommandThread() processing set parameters string %s, io %d",
                             data->mKeyValuePairs.string(), data->mIO);
+                    mLock.unlock();
                     command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs);
+                    mLock.lock();
                     }break;
                 case SET_VOICE_VOLUME: {
                     VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get();
                     ALOGV("AudioCommandThread() processing set voice volume volume %f",
                             data->mVolume);
+                    mLock.unlock();
                     command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
+                    mLock.lock();
                     }break;
                 case STOP_OUTPUT: {
                     StopOutputData *data = (StopOutputData *)command->mParam.get();
-                    ALOGV("AudioCommandThread() processing stop output %d",
-                            data->mIO);
+                    ALOGV("AudioCommandThread() processing stop output portId %d",
+                            data->mPortId);
                     svc = mService.promote();
                     if (svc == 0) {
                         break;
                     }
                     mLock.unlock();
-                    svc->doStopOutput(data->mIO, data->mStream, data->mSession);
+                    svc->doStopOutput(data->mPortId);
                     mLock.lock();
                     }break;
                 case RELEASE_OUTPUT: {
                     ReleaseOutputData *data = (ReleaseOutputData *)command->mParam.get();
-                    ALOGV("AudioCommandThread() processing release output %d",
-                            data->mIO);
+                    ALOGV("AudioCommandThread() processing release output portId %d",
+                            data->mPortId);
                     svc = mService.promote();
                     if (svc == 0) {
                         break;
                     }
                     mLock.unlock();
-                    svc->doReleaseOutput(data->mIO, data->mStream, data->mSession);
+                    svc->doReleaseOutput(data->mPortId);
                     mLock.lock();
                     }break;
                 case CREATE_AUDIO_PATCH: {
@@ -745,7 +1112,9 @@
                     if (af == 0) {
                         command->mStatus = PERMISSION_DENIED;
                     } else {
+                        mLock.unlock();
                         command->mStatus = af->createAudioPatch(&data->mPatch, &data->mHandle);
+                        mLock.lock();
                     }
                     } break;
                 case RELEASE_AUDIO_PATCH: {
@@ -755,7 +1124,9 @@
                     if (af == 0) {
                         command->mStatus = PERMISSION_DENIED;
                     } else {
+                        mLock.unlock();
                         command->mStatus = af->releaseAudioPatch(data->mHandle);
+                        mLock.lock();
                     }
                     } break;
                 case UPDATE_AUDIOPORT_LIST: {
@@ -778,6 +1149,18 @@
                     svc->doOnAudioPatchListUpdate();
                     mLock.lock();
                     }break;
+                case CHANGED_AUDIOVOLUMEGROUP: {
+                    AudioVolumeGroupData *data =
+                            static_cast<AudioVolumeGroupData *>(command->mParam.get());
+                    ALOGV("AudioCommandThread() processing update audio volume group");
+                    svc = mService.promote();
+                    if (svc == 0) {
+                        break;
+                    }
+                    mLock.unlock();
+                    svc->doOnAudioVolumeGroupChanged(data->mGroup, data->mFlags);
+                    mLock.lock();
+                    }break;
                 case SET_AUDIOPORT_CONFIG: {
                     SetAudioPortConfigData *data = (SetAudioPortConfigData *)command->mParam.get();
                     ALOGV("AudioCommandThread() processing set port config");
@@ -785,7 +1168,9 @@
                     if (af == 0) {
                         command->mStatus = PERMISSION_DENIED;
                     } else {
+                        mLock.unlock();
                         command->mStatus = af->setAudioPortConfig(&data->mConfig);
+                        mLock.lock();
                     }
                     } break;
                 case DYN_POLICY_MIX_STATE_UPDATE: {
@@ -811,10 +1196,22 @@
                     }
                     mLock.unlock();
                     svc->doOnRecordingConfigurationUpdate(data->mEvent, &data->mClientInfo,
-                            &data->mClientConfig, &data->mDeviceConfig,
-                            data->mPatchHandle);
+                            &data->mClientConfig, data->mClientEffects,
+                            &data->mDeviceConfig, data->mEffects,
+                            data->mPatchHandle, data->mSource);
                     mLock.lock();
                     } break;
+                case SET_EFFECT_SUSPENDED: {
+                    SetEffectSuspendedData *data = (SetEffectSuspendedData *)command->mParam.get();
+                    ALOGV("AudioCommandThread() processing set effect suspended");
+                    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+                    if (af != 0) {
+                        mLock.unlock();
+                        af->setEffectSuspended(data->mEffectId, data->mSessionId, data->mSuspended);
+                        mLock.lock();
+                    }
+                    } break;
+
                 default:
                     ALOGW("AudioCommandThread() unknown command %d", command->mCommand);
                 }
@@ -872,7 +1269,7 @@
     result.append(buffer);
     write(fd, result.string(), result.size());
 
-    bool locked = tryLock(mLock);
+    bool locked = dumpTryLock(mLock);
     if (!locked) {
         String8 result2(kCmdDeadlockedString);
         write(fd, result2.string(), result2.size());
@@ -900,27 +1297,6 @@
     return NO_ERROR;
 }
 
-void AudioPolicyService::AudioCommandThread::startToneCommand(ToneGenerator::tone_type type,
-        audio_stream_type_t stream)
-{
-    sp<AudioCommand> command = new AudioCommand();
-    command->mCommand = START_TONE;
-    sp<ToneData> data = new ToneData();
-    data->mType = type;
-    data->mStream = stream;
-    command->mParam = data;
-    ALOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream);
-    sendCommand(command);
-}
-
-void AudioPolicyService::AudioCommandThread::stopToneCommand()
-{
-    sp<AudioCommand> command = new AudioCommand();
-    command->mCommand = STOP_TONE;
-    ALOGV("AudioCommandThread() adding tone stop");
-    sendCommand(command);
-}
-
 status_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream,
                                                                float volume,
                                                                audio_io_handle_t output,
@@ -967,33 +1343,42 @@
     return sendCommand(command, delayMs);
 }
 
-void AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t output,
-                                                               audio_stream_type_t stream,
-                                                               audio_session_t session)
+void AudioPolicyService::AudioCommandThread::setEffectSuspendedCommand(int effectId,
+                                                                       audio_session_t sessionId,
+                                                                       bool suspended)
+{
+    sp<AudioCommand> command = new AudioCommand();
+    command->mCommand = SET_EFFECT_SUSPENDED;
+    sp<SetEffectSuspendedData> data = new SetEffectSuspendedData();
+    data->mEffectId = effectId;
+    data->mSessionId = sessionId;
+    data->mSuspended = suspended;
+    command->mParam = data;
+    ALOGV("AudioCommandThread() adding set suspended effectId %d sessionId %d suspended %d",
+        effectId, sessionId, suspended);
+    sendCommand(command);
+}
+
+
+void AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_port_handle_t portId)
 {
     sp<AudioCommand> command = new AudioCommand();
     command->mCommand = STOP_OUTPUT;
     sp<StopOutputData> data = new StopOutputData();
-    data->mIO = output;
-    data->mStream = stream;
-    data->mSession = session;
+    data->mPortId = portId;
     command->mParam = data;
-    ALOGV("AudioCommandThread() adding stop output %d", output);
+    ALOGV("AudioCommandThread() adding stop output portId %d", portId);
     sendCommand(command);
 }
 
-void AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_io_handle_t output,
-                                                                  audio_stream_type_t stream,
-                                                                  audio_session_t session)
+void AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_port_handle_t portId)
 {
     sp<AudioCommand> command = new AudioCommand();
     command->mCommand = RELEASE_OUTPUT;
     sp<ReleaseOutputData> data = new ReleaseOutputData();
-    data->mIO = output;
-    data->mStream = stream;
-    data->mSession = session;
+    data->mPortId = portId;
     command->mParam = data;
-    ALOGV("AudioCommandThread() adding release output %d", output);
+    ALOGV("AudioCommandThread() adding release output portId %d", portId);
     sendCommand(command);
 }
 
@@ -1048,6 +1433,19 @@
     sendCommand(command);
 }
 
+void AudioPolicyService::AudioCommandThread::changeAudioVolumeGroupCommand(volume_group_t group,
+                                                                           int flags)
+{
+    sp<AudioCommand>command = new AudioCommand();
+    command->mCommand = CHANGED_AUDIOVOLUMEGROUP;
+    AudioVolumeGroupData *data= new AudioVolumeGroupData();
+    data->mGroup = group;
+    data->mFlags = flags;
+    command->mParam = data;
+    ALOGV("AudioCommandThread() adding audio volume group changed");
+    sendCommand(command);
+}
+
 status_t AudioPolicyService::AudioCommandThread::setAudioPortConfigCommand(
                                             const struct audio_port_config *config, int delayMs)
 {
@@ -1076,9 +1474,14 @@
 }
 
 void AudioPolicyService::AudioCommandThread::recordingConfigurationUpdateCommand(
-        int event, const record_client_info_t *clientInfo,
-        const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
-        audio_patch_handle_t patchHandle)
+                                                int event,
+                                                const record_client_info_t *clientInfo,
+                                                const audio_config_base_t *clientConfig,
+                                                std::vector<effect_descriptor_t> clientEffects,
+                                                const audio_config_base_t *deviceConfig,
+                                                std::vector<effect_descriptor_t> effects,
+                                                audio_patch_handle_t patchHandle,
+                                                audio_source_t source)
 {
     sp<AudioCommand>command = new AudioCommand();
     command->mCommand = RECORDING_CONFIGURATION_UPDATE;
@@ -1086,8 +1489,11 @@
     data->mEvent = event;
     data->mClientInfo = *clientInfo;
     data->mClientConfig = *clientConfig;
+    data->mClientEffects = clientEffects;
     data->mDeviceConfig = *deviceConfig;
+    data->mEffects = effects;
     data->mPatchHandle = patchHandle;
+    data->mSource = source;
     command->mParam = data;
     ALOGV("AudioCommandThread() adding recording configuration update event %d, source %d uid %u",
             event, clientInfo->source, clientInfo->uid);
@@ -1212,6 +1618,7 @@
                 patch = ((CreateAudioPatchData *)command->mParam.get())->mPatch;
             } else {
                 handle = ((ReleaseAudioPatchData *)command->mParam.get())->mHandle;
+                memset(&patch, 0, sizeof(patch));
             }
             audio_patch_handle_t handle2;
             struct audio_patch patch2;
@@ -1256,8 +1663,6 @@
 
         } break;
 
-        case START_TONE:
-        case STOP_TONE:
         default:
             break;
         }
@@ -1330,32 +1735,19 @@
                                                    output, delayMs);
 }
 
-int AudioPolicyService::startTone(audio_policy_tone_t tone,
-                                  audio_stream_type_t stream)
-{
-    if (tone != AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION) {
-        ALOGE("startTone: illegal tone requested (%d)", tone);
-    }
-    if (stream != AUDIO_STREAM_VOICE_CALL) {
-        ALOGE("startTone: illegal stream (%d) requested for tone %d", stream,
-            tone);
-    }
-    mTonePlaybackThread->startToneCommand(ToneGenerator::TONE_SUP_CALL_WAITING,
-                                          AUDIO_STREAM_VOICE_CALL);
-    return 0;
-}
-
-int AudioPolicyService::stopTone()
-{
-    mTonePlaybackThread->stopToneCommand();
-    return 0;
-}
-
 int AudioPolicyService::setVoiceVolume(float volume, int delayMs)
 {
     return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
 }
 
+void AudioPolicyService::setEffectSuspended(int effectId,
+                                            audio_session_t sessionId,
+                                            bool suspended)
+{
+    mAudioCommandThread->setEffectSuspendedCommand(effectId, sessionId, suspended);
+}
+
+
 extern "C" {
 audio_module_handle_t aps_load_hw_module(void *service __unused,
                                              const char *name);
@@ -1406,9 +1798,6 @@
 int aps_set_stream_volume(void *service, audio_stream_type_t stream,
                                      float volume, audio_io_handle_t output,
                                      int delay_ms);
-int aps_start_tone(void *service, audio_policy_tone_t tone,
-                              audio_stream_type_t stream);
-int aps_stop_tone(void *service);
 int aps_set_voice_volume(void *service, float volume, int delay_ms);
 };
 
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 407d7a5..e467f70 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -31,15 +31,15 @@
 #include <media/ToneGenerator.h>
 #include <media/AudioEffect.h>
 #include <media/AudioPolicy.h>
+#include <mediautils/ServiceUtilities.h>
 #include "AudioPolicyEffects.h"
-#include "managerdefault/AudioPolicyManager.h"
+#include <AudioPolicyInterface.h>
+#include <android/hardware/BnSensorPrivacyListener.h>
 
 #include <unordered_map>
 
 namespace android {
 
-using namespace std;
-
 // ----------------------------------------------------------------------------
 
 class AudioPolicyService :
@@ -62,38 +62,36 @@
     virtual status_t setDeviceConnectionState(audio_devices_t device,
                                               audio_policy_dev_state_t state,
                                               const char *device_address,
-                                              const char *device_name);
+                                              const char *device_name,
+                                              audio_format_t encodedFormat);
     virtual audio_policy_dev_state_t getDeviceConnectionState(
                                                                 audio_devices_t device,
                                                                 const char *device_address);
     virtual status_t handleDeviceConfigChange(audio_devices_t device,
                                               const char *device_address,
-                                              const char *device_name);
+                                              const char *device_name,
+                                              audio_format_t encodedFormat);
     virtual status_t setPhoneState(audio_mode_t state);
     virtual status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
     virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage);
     virtual audio_io_handle_t getOutput(audio_stream_type_t stream);
-    virtual status_t getOutputForAttr(const audio_attributes_t *attr,
-                                      audio_io_handle_t *output,
-                                      audio_session_t session,
-                                      audio_stream_type_t *stream,
-                                      pid_t pid,
-                                      uid_t uid,
-                                      const audio_config_t *config,
-                                      audio_output_flags_t flags,
-                                      audio_port_handle_t *selectedDeviceId,
-                                      audio_port_handle_t *portId);
-    virtual status_t startOutput(audio_io_handle_t output,
-                                 audio_stream_type_t stream,
-                                 audio_session_t session);
-    virtual status_t stopOutput(audio_io_handle_t output,
-                                audio_stream_type_t stream,
-                                audio_session_t session);
-    virtual void releaseOutput(audio_io_handle_t output,
-                               audio_stream_type_t stream,
-                               audio_session_t session);
+    status_t getOutputForAttr(audio_attributes_t *attr,
+                              audio_io_handle_t *output,
+                              audio_session_t session,
+                              audio_stream_type_t *stream,
+                              pid_t pid,
+                              uid_t uid,
+                              const audio_config_t *config,
+                              audio_output_flags_t flags,
+                              audio_port_handle_t *selectedDeviceId,
+                              audio_port_handle_t *portId,
+                              std::vector<audio_io_handle_t> *secondaryOutputs) override;
+    virtual status_t startOutput(audio_port_handle_t portId);
+    virtual status_t stopOutput(audio_port_handle_t portId);
+    virtual void releaseOutput(audio_port_handle_t portId);
     virtual status_t getInputForAttr(const audio_attributes_t *attr,
                                      audio_io_handle_t *input,
+                                     audio_unique_id_t riid,
                                      audio_session_t session,
                                      pid_t pid,
                                      uid_t uid,
@@ -102,8 +100,7 @@
                                      audio_input_flags_t flags,
                                      audio_port_handle_t *selectedDeviceId = NULL,
                                      audio_port_handle_t *portId = NULL);
-    virtual status_t startInput(audio_port_handle_t portId,
-                                bool *silenced);
+    virtual status_t startInput(audio_port_handle_t portId);
     virtual status_t stopInput(audio_port_handle_t portId);
     virtual void releaseInput(audio_port_handle_t portId);
     virtual status_t initStreamVolume(audio_stream_type_t stream,
@@ -116,6 +113,17 @@
                                           int *index,
                                           audio_devices_t device);
 
+    virtual status_t setVolumeIndexForAttributes(const audio_attributes_t &attr,
+                                                 int index,
+                                                 audio_devices_t device);
+    virtual status_t getVolumeIndexForAttributes(const audio_attributes_t &attr,
+                                                 int &index,
+                                                 audio_devices_t device);
+    virtual status_t getMinVolumeIndexForAttributes(const audio_attributes_t &attr,
+                                                    int &index);
+    virtual status_t getMaxVolumeIndexForAttributes(const audio_attributes_t &attr,
+                                                    int &index);
+
     virtual uint32_t getStrategyForStream(audio_stream_type_t stream);
     virtual audio_devices_t getDevicesForStream(audio_stream_type_t stream);
 
@@ -127,6 +135,7 @@
                                     int id);
     virtual status_t unregisterEffect(int id);
     virtual status_t setEffectEnabled(int id, bool enabled);
+    status_t moveEffectsToIo(const std::vector<int>& ids, audio_io_handle_t io) override;
     virtual bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const;
     virtual bool isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs = 0) const;
     virtual bool isSourceActive(audio_source_t source) const;
@@ -134,6 +143,21 @@
     virtual status_t queryDefaultPreProcessing(audio_session_t audioSession,
                                               effect_descriptor_t *descriptors,
                                               uint32_t *count);
+    virtual status_t addSourceDefaultEffect(const effect_uuid_t *type,
+                                            const String16& opPackageName,
+                                            const effect_uuid_t *uuid,
+                                            int32_t priority,
+                                            audio_source_t source,
+                                            audio_unique_id_t* id);
+    virtual status_t addStreamDefaultEffect(const effect_uuid_t *type,
+                                            const String16& opPackageName,
+                                            const effect_uuid_t *uuid,
+                                            int32_t priority,
+                                            audio_usage_t usage,
+                                            audio_unique_id_t* id);
+    virtual status_t removeSourceDefaultEffect(audio_unique_id_t id);
+    virtual status_t removeStreamDefaultEffect(audio_unique_id_t id);
+
     virtual     status_t    onTransact(
                                 uint32_t code,
                                 const Parcel& data,
@@ -159,10 +183,11 @@
                                      float volume,
                                      audio_io_handle_t output,
                                      int delayMs = 0);
-    virtual status_t startTone(audio_policy_tone_t tone, audio_stream_type_t stream);
-    virtual status_t stopTone();
     virtual status_t setVoiceVolume(float volume, int delayMs = 0);
+    status_t setAllowedCapturePolicy(uint_t uid, audio_flags_mask_t capturePolicy) override;
     virtual bool isOffloadSupported(const audio_offload_info_t &config);
+    virtual bool isDirectOutputSupported(const audio_config_base_t& config,
+                                         const audio_attributes_t& attributes);
 
     virtual status_t listAudioPorts(audio_port_role_t role,
                                     audio_port_type_t type,
@@ -182,6 +207,8 @@
 
     virtual void setAudioPortCallbacksEnabled(bool enabled);
 
+    virtual void setAudioVolumeGroupCallbacksEnabled(bool enabled);
+
     virtual status_t acquireSoundTriggerSession(audio_session_t *session,
                                            audio_io_handle_t *ioHandle,
                                            audio_devices_t *device);
@@ -192,10 +219,14 @@
 
     virtual status_t registerPolicyMixes(const Vector<AudioMix>& mixes, bool registration);
 
+    virtual status_t setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices);
+
+    virtual status_t removeUidDeviceAffinities(uid_t uid);
+
     virtual status_t startAudioSource(const struct audio_port_config *source,
                                       const audio_attributes_t *attributes,
-                                      audio_patch_handle_t *handle);
-    virtual status_t stopAudioSource(audio_patch_handle_t handle);
+                                      audio_port_handle_t *portId);
+    virtual status_t stopAudioSource(audio_port_handle_t portId);
 
     virtual status_t setMasterMono(bool mono);
     virtual status_t getMasterMono(bool *mono);
@@ -207,14 +238,28 @@
                                         audio_format_t *surroundFormats,
                                         bool *surroundFormatsEnabled,
                                         bool reported);
+    virtual status_t getHwOffloadEncodingFormatsSupportedForA2DP(
+                                        std::vector<audio_format_t> *formats);
     virtual status_t setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled);
 
-            status_t doStopOutput(audio_io_handle_t output,
-                                  audio_stream_type_t stream,
-                                  audio_session_t session);
-            void doReleaseOutput(audio_io_handle_t output,
-                                 audio_stream_type_t stream,
-                                 audio_session_t session);
+    virtual status_t setAssistantUid(uid_t uid);
+    virtual status_t setA11yServicesUids(const std::vector<uid_t>& uids);
+
+    virtual bool     isHapticPlaybackSupported();
+
+    virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies);
+    virtual status_t getProductStrategyFromAudioAttributes(const AudioAttributes &aa,
+                                                           product_strategy_t &productStrategy);
+
+    virtual status_t listAudioVolumeGroups(AudioVolumeGroupVector &groups);
+
+    virtual status_t getVolumeGroupFromAudioAttributes(const AudioAttributes &aa,
+                                                       volume_group_t &volumeGroup);
+
+    virtual status_t setRttEnabled(bool enabled);
+
+            status_t doStopOutput(audio_port_handle_t portId);
+            void doReleaseOutput(audio_port_handle_t portId);
 
             status_t clientCreateAudioPatch(const struct audio_patch *patch,
                                       audio_patch_handle_t *handle,
@@ -224,7 +269,7 @@
             virtual status_t clientSetAudioPortConfig(const struct audio_port_config *config,
                                                       int delayMs);
 
-            void removeNotificationClient(uid_t uid);
+            void removeNotificationClient(uid_t uid, pid_t pid);
             void onAudioPortListUpdate();
             void doOnAudioPortListUpdate();
             void onAudioPatchListUpdate();
@@ -232,12 +277,28 @@
 
             void onDynamicPolicyMixStateUpdate(const String8& regId, int32_t state);
             void doOnDynamicPolicyMixStateUpdate(const String8& regId, int32_t state);
-            void onRecordingConfigurationUpdate(int event, const record_client_info_t *clientInfo,
-                    const audio_config_base_t *clientConfig,
-                    const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle);
-            void doOnRecordingConfigurationUpdate(int event, const record_client_info_t *clientInfo,
-                    const audio_config_base_t *clientConfig,
-                    const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle);
+            void onRecordingConfigurationUpdate(int event,
+                                                const record_client_info_t *clientInfo,
+                                                const audio_config_base_t *clientConfig,
+                                                std::vector<effect_descriptor_t> clientEffects,
+                                                const audio_config_base_t *deviceConfig,
+                                                std::vector<effect_descriptor_t> effects,
+                                                audio_patch_handle_t patchHandle,
+                                                audio_source_t source);
+            void doOnRecordingConfigurationUpdate(int event,
+                                                  const record_client_info_t *clientInfo,
+                                                  const audio_config_base_t *clientConfig,
+                                                  std::vector<effect_descriptor_t> clientEffects,
+                                                  const audio_config_base_t *deviceConfig,
+                                                  std::vector<effect_descriptor_t> effects,
+                                                  audio_patch_handle_t patchHandle,
+                                                  audio_source_t source);
+
+            void onAudioVolumeGroupChanged(volume_group_t group, int flags);
+            void doOnAudioVolumeGroupChanged(volume_group_t group, int flags);
+            void setEffectSuspended(int effectId,
+                                    audio_session_t sessionId,
+                                    bool suspended);
 
 private:
                         AudioPolicyService() ANDROID_API;
@@ -249,7 +310,7 @@
     virtual status_t shellCommand(int in, int out, int err, Vector<String16>& args);
 
     // Sets whether the given UID records only silence
-    virtual void setRecordSilenced(uid_t uid, bool silenced);
+    virtual void setAppState_l(uid_t uid, app_state_t state);
 
     // Overrides the UID state as if it is idle
     status_t handleSetUidState(Vector<String16>& args, int err);
@@ -265,6 +326,18 @@
 
     std::string getDeviceTypeStrForPortId(audio_port_handle_t portId);
 
+    status_t getAudioPolicyEffects(sp<AudioPolicyEffects>& audioPolicyEffects);
+
+    app_state_t apmStatFromAmState(int amState);
+
+    void updateUidStates();
+    void updateUidStates_l();
+
+    void silenceAllRecordings_l();
+
+    static bool isPrivacySensitiveSource(audio_source_t source);
+    static bool isVirtualSource(audio_source_t source);
+
     // If recording we need to make sure the UID is allowed to do that. If the UID is idle
     // then it cannot record and gets buffers with zeros - silence. As soon as the UID
     // transitions to an active state we will start reporting buffers with data. This approach
@@ -274,7 +347,8 @@
     class UidPolicy : public BnUidObserver, public virtual IBinder::DeathRecipient {
     public:
         explicit UidPolicy(wp<AudioPolicyService> service)
-                : mService(service), mObserverRegistered(false) {}
+                : mService(service), mObserverRegistered(false),
+                  mAssistantUid(0), mRttEnabled(false) {}
 
         void registerSelf();
         void unregisterSelf();
@@ -283,34 +357,66 @@
         void binderDied(const wp<IBinder> &who) override;
 
         bool isUidActive(uid_t uid);
+        int getUidState(uid_t uid);
+        void setAssistantUid(uid_t uid) { mAssistantUid = uid; }
+        bool isAssistantUid(uid_t uid) { return uid == mAssistantUid; }
+        void setA11yUids(const std::vector<uid_t>& uids) { mA11yUids.clear(); mA11yUids = uids; }
+        bool isA11yUid(uid_t uid);
+        bool isA11yOnTop();
+        void setRttEnabled(bool enabled) { mRttEnabled = enabled; }
+        bool isRttEnabled() { return mRttEnabled; }
 
         // BnUidObserver implementation
         void onUidActive(uid_t uid) override;
         void onUidGone(uid_t uid, bool disabled) override;
         void onUidIdle(uid_t uid, bool disabled) override;
+        void onUidStateChanged(uid_t uid, int32_t procState, int64_t procStateSeq);
 
         void addOverrideUid(uid_t uid, bool active) { updateOverrideUid(uid, active, true); }
         void removeOverrideUid(uid_t uid) { updateOverrideUid(uid, false, false); }
 
-    private:
-        bool isServiceUid(uid_t uid) const;
-        void notifyService(uid_t uid, bool active);
+        void updateUid(std::unordered_map<uid_t, std::pair<bool, int>> *uids,
+                       uid_t uid, bool active, int state, bool insert);
+
+     private:
+        void notifyService();
         void updateOverrideUid(uid_t uid, bool active, bool insert);
-        void updateUidCache(uid_t uid, bool active, bool insert);
-        void updateUidLocked(std::unordered_map<uid_t, bool> *uids,
-                uid_t uid, bool active, bool insert, bool *wasThere, bool *wasActive);
+        void updateUidLocked(std::unordered_map<uid_t, std::pair<bool, int>> *uids,
+                             uid_t uid, bool active, int state, bool insert);
+        void checkRegistered();
 
         wp<AudioPolicyService> mService;
         Mutex mLock;
         bool mObserverRegistered;
-        std::unordered_map<uid_t, bool> mOverrideUids;
-        std::unordered_map<uid_t, bool> mCachedUids;
+        std::unordered_map<uid_t, std::pair<bool, int>> mOverrideUids;
+        std::unordered_map<uid_t, std::pair<bool, int>> mCachedUids;
+        uid_t mAssistantUid;
+        std::vector<uid_t> mA11yUids;
+        bool mRttEnabled;
     };
 
-    // Thread used for tone playback and to send audio config commands to audio flinger
-    // For tone playback, using a separate thread is necessary to avoid deadlock with mLock because
-    // startTone() and stopTone() are normally called with mLock locked and requesting a tone start
-    // or stop will cause calls to AudioPolicyService and an attempt to lock mLock.
+    // If sensor privacy is enabled then all apps, including those that are active, should be
+    // prevented from recording. This is handled similar to idle UIDs, any app that attempts
+    // to record while sensor privacy is enabled will receive buffers with zeros. As soon as
+    // sensor privacy is disabled active apps will receive the expected data when recording.
+    class SensorPrivacyPolicy : public hardware::BnSensorPrivacyListener {
+        public:
+            explicit SensorPrivacyPolicy(wp<AudioPolicyService> service)
+                    : mService(service) {}
+
+            void registerSelf();
+            void unregisterSelf();
+
+            bool isSensorPrivacyEnabled();
+
+            binder::Status onSensorPrivacyChanged(bool enabled);
+
+        private:
+            wp<AudioPolicyService> mService;
+            std::atomic_bool mSensorPrivacyEnabled;
+    };
+
+    // Thread used to send audio config commands to audio flinger
     // For audio config commands, it is necessary because audio flinger requires that the calling
     // process (user) has permission to modify audio settings.
     class AudioCommandThread : public Thread {
@@ -319,8 +425,6 @@
 
         // commands for tone AudioCommand
         enum {
-            START_TONE,
-            STOP_TONE,
             SET_VOLUME,
             SET_PARAMETERS,
             SET_VOICE_VOLUME,
@@ -330,9 +434,11 @@
             RELEASE_AUDIO_PATCH,
             UPDATE_AUDIOPORT_LIST,
             UPDATE_AUDIOPATCH_LIST,
+            CHANGED_AUDIOVOLUMEGROUP,
             SET_AUDIOPORT_CONFIG,
             DYN_POLICY_MIX_STATE_UPDATE,
-            RECORDING_CONFIGURATION_UPDATE
+            RECORDING_CONFIGURATION_UPDATE,
+            SET_EFFECT_SUSPENDED,
         };
 
         AudioCommandThread (String8 name, const wp<AudioPolicyService>& service);
@@ -345,20 +451,13 @@
         virtual     bool        threadLoop();
 
                     void        exit();
-                    void        startToneCommand(ToneGenerator::tone_type type,
-                                                 audio_stream_type_t stream);
-                    void        stopToneCommand();
                     status_t    volumeCommand(audio_stream_type_t stream, float volume,
                                             audio_io_handle_t output, int delayMs = 0);
                     status_t    parametersCommand(audio_io_handle_t ioHandle,
                                             const char *keyValuePairs, int delayMs = 0);
                     status_t    voiceVolumeCommand(float volume, int delayMs = 0);
-                    void        stopOutputCommand(audio_io_handle_t output,
-                                                  audio_stream_type_t stream,
-                                                  audio_session_t session);
-                    void        releaseOutputCommand(audio_io_handle_t output,
-                                                     audio_stream_type_t stream,
-                                                     audio_session_t session);
+                    void        stopOutputCommand(audio_port_handle_t portId);
+                    void        releaseOutputCommand(audio_port_handle_t portId);
                     status_t    sendCommand(sp<AudioCommand>& command, int delayMs = 0);
                     void        insertCommand_l(sp<AudioCommand>& command, int delayMs = 0);
                     status_t    createAudioPatchCommand(const struct audio_patch *patch,
@@ -368,15 +467,23 @@
                                                          int delayMs);
                     void        updateAudioPortListCommand();
                     void        updateAudioPatchListCommand();
+                    void        changeAudioVolumeGroupCommand(volume_group_t group, int flags);
                     status_t    setAudioPortConfigCommand(const struct audio_port_config *config,
                                                           int delayMs);
-                    void        dynamicPolicyMixStateUpdateCommand(const String8& regId, int32_t state);
+                    void        dynamicPolicyMixStateUpdateCommand(const String8& regId,
+                                                                   int32_t state);
                     void        recordingConfigurationUpdateCommand(
-                                                        int event,
-                                                        const record_client_info_t *clientInfo,
-                                                        const audio_config_base_t *clientConfig,
-                                                        const audio_config_base_t *deviceConfig,
-                                                        audio_patch_handle_t patchHandle);
+                                                    int event,
+                                                    const record_client_info_t *clientInfo,
+                                                    const audio_config_base_t *clientConfig,
+                                                    std::vector<effect_descriptor_t> clientEffects,
+                                                    const audio_config_base_t *deviceConfig,
+                                                    std::vector<effect_descriptor_t> effects,
+                                                    audio_patch_handle_t patchHandle,
+                                                    audio_source_t source);
+                    void        setEffectSuspendedCommand(int effectId,
+                                                          audio_session_t sessionId,
+                                                          bool suspended);
                     void        insertCommand_l(AudioCommand *command, int delayMs = 0);
     private:
         class AudioCommandData;
@@ -390,7 +497,7 @@
 
             void dump(char* buffer, size_t size);
 
-            int mCommand;   // START_TONE, STOP_TONE ...
+            int mCommand;   // SET_VOLUME, SET_PARAMETERS...
             nsecs_t mTime;  // time stamp
             Mutex mLock;    // mutex associated to mCond
             Condition mCond; // condition for status return
@@ -406,12 +513,6 @@
             AudioCommandData() {}
         };
 
-        class ToneData : public AudioCommandData {
-        public:
-            ToneGenerator::tone_type mType; // tone type (START_TONE only)
-            audio_stream_type_t mStream;    // stream type (START_TONE only)
-        };
-
         class VolumeData : public AudioCommandData {
         public:
             audio_stream_type_t mStream;
@@ -432,16 +533,12 @@
 
         class StopOutputData : public AudioCommandData {
         public:
-            audio_io_handle_t mIO;
-            audio_stream_type_t mStream;
-            audio_session_t mSession;
+            audio_port_handle_t mPortId;
         };
 
         class ReleaseOutputData : public AudioCommandData {
         public:
-            audio_io_handle_t mIO;
-            audio_stream_type_t mStream;
-            audio_session_t mSession;
+            audio_port_handle_t mPortId;
         };
 
         class CreateAudioPatchData : public AudioCommandData {
@@ -455,6 +552,12 @@
             audio_patch_handle_t mHandle;
         };
 
+        class AudioVolumeGroupData : public AudioCommandData {
+        public:
+            volume_group_t mGroup;
+            int mFlags;
+        };
+
         class SetAudioPortConfigData : public AudioCommandData {
         public:
             struct audio_port_config mConfig;
@@ -471,14 +574,23 @@
             int mEvent;
             record_client_info_t mClientInfo;
             struct audio_config_base mClientConfig;
+            std::vector<effect_descriptor_t> mClientEffects;
             struct audio_config_base mDeviceConfig;
+            std::vector<effect_descriptor_t> mEffects;
             audio_patch_handle_t mPatchHandle;
+            audio_source_t mSource;
+        };
+
+        class SetEffectSuspendedData : public AudioCommandData {
+        public:
+            int mEffectId;
+            audio_session_t mSessionId;
+            bool mSuspended;
         };
 
         Mutex   mLock;
         Condition mWaitWorkCV;
         Vector < sp<AudioCommand> > mAudioCommands; // list of pending commands
-        ToneGenerator *mpToneGenerator;     // the tone generator
         sp<AudioCommand> mLastCommand;      // last processed command (used by dump)
         String8 mName;                      // string used by wake lock fo delayed commands
         wp<AudioPolicyService> mService;
@@ -553,11 +665,6 @@
         // function enabling to receive proprietary informations directly from audio hardware interface to audio policy manager.
         virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys);
 
-        // request the playback of a tone on the specified stream: used for instance to replace notification sounds when playing
-        // over a telephony device during a phone call.
-        virtual status_t startTone(audio_policy_tone_t tone, audio_stream_type_t stream);
-        virtual status_t stopTone();
-
         // set down link audio volume.
         virtual status_t setVoiceVolume(float volume, int delayMs = 0);
 
@@ -566,6 +673,10 @@
                                          audio_io_handle_t srcOutput,
                                          audio_io_handle_t dstOutput);
 
+                void setEffectSuspended(int effectId,
+                                        audio_session_t sessionId,
+                                        bool suspended) override;
+
         /* Create a patch between several source and sink ports */
         virtual status_t createAudioPatch(const struct audio_patch *patch,
                                            audio_patch_handle_t *handle,
@@ -582,9 +693,15 @@
         virtual void onAudioPatchListUpdate();
         virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state);
         virtual void onRecordingConfigurationUpdate(int event,
-                        const record_client_info_t *clientInfo,
-                        const audio_config_base_t *clientConfig,
-                        const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle);
+                                                    const record_client_info_t *clientInfo,
+                                                    const audio_config_base_t *clientConfig,
+                                                    std::vector<effect_descriptor_t> clientEffects,
+                                                    const audio_config_base_t *deviceConfig,
+                                                    std::vector<effect_descriptor_t> effects,
+                                                    audio_patch_handle_t patchHandle,
+                                                    audio_source_t source);
+
+        virtual void onAudioVolumeGroupChanged(volume_group_t group, int flags);
 
         virtual audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use);
 
@@ -597,18 +714,29 @@
     public:
                             NotificationClient(const sp<AudioPolicyService>& service,
                                                 const sp<IAudioPolicyServiceClient>& client,
-                                                uid_t uid);
+                                                uid_t uid, pid_t pid);
         virtual             ~NotificationClient();
 
                             void      onAudioPortListUpdate();
                             void      onAudioPatchListUpdate();
-                            void      onDynamicPolicyMixStateUpdate(const String8& regId, int32_t state);
+                            void      onDynamicPolicyMixStateUpdate(const String8& regId,
+                                                                    int32_t state);
+                            void      onAudioVolumeGroupChanged(volume_group_t group, int flags);
                             void      onRecordingConfigurationUpdate(
-                                        int event, const record_client_info_t *clientInfo,
-                                        const audio_config_base_t *clientConfig,
-                                        const audio_config_base_t *deviceConfig,
-                                        audio_patch_handle_t patchHandle);
+                                                    int event,
+                                                    const record_client_info_t *clientInfo,
+                                                    const audio_config_base_t *clientConfig,
+                                                    std::vector<effect_descriptor_t> clientEffects,
+                                                    const audio_config_base_t *deviceConfig,
+                                                    std::vector<effect_descriptor_t> effects,
+                                                    audio_patch_handle_t patchHandle,
+                                                    audio_source_t source);
                             void      setAudioPortCallbacksEnabled(bool enabled);
+                            void setAudioVolumeGroupCallbacksEnabled(bool enabled);
+
+                            uid_t uid() {
+                                return mUid;
+                            }
 
                 // IBinder::DeathRecipient
                 virtual     void        binderDied(const wp<IBinder>& who);
@@ -619,36 +747,73 @@
 
         const wp<AudioPolicyService>        mService;
         const uid_t                         mUid;
+        const pid_t                         mPid;
         const sp<IAudioPolicyServiceClient> mAudioPolicyServiceClient;
               bool                          mAudioPortCallbacksEnabled;
+              bool                          mAudioVolumeGroupCallbacksEnabled;
+    };
+
+    class AudioClient : public virtual RefBase {
+    public:
+                AudioClient(const audio_attributes_t attributes,
+                            const audio_io_handle_t io, uid_t uid, pid_t pid,
+                            const audio_session_t session, const audio_port_handle_t deviceId) :
+                                attributes(attributes), io(io), uid(uid), pid(pid),
+                                session(session), deviceId(deviceId), active(false) {}
+                ~AudioClient() override = default;
+
+
+        const audio_attributes_t attributes; // source, flags ...
+        const audio_io_handle_t io;          // audio HAL stream IO handle
+        const uid_t uid;                     // client UID
+        const pid_t pid;                     // client PID
+        const audio_session_t session;       // audio session ID
+        const audio_port_handle_t deviceId;  // selected input device port ID
+              bool active;                   // Playback/Capture is active or inactive
     };
 
     // --- AudioRecordClient ---
     // Information about each registered AudioRecord client
     // (between calls to getInputForAttr() and releaseInput())
-    class AudioRecordClient : public RefBase {
+    class AudioRecordClient : public AudioClient {
     public:
                 AudioRecordClient(const audio_attributes_t attributes,
-                                  const audio_io_handle_t input, uid_t uid, pid_t pid,
-                                  const String16& opPackageName, const audio_session_t session) :
-                                      attributes(attributes),
-                                      input(input), uid(uid), pid(pid),
-                                      opPackageName(opPackageName), session(session),
-                                      active(false), isConcurrent(false), isVirtualDevice(false) {}
-        virtual ~AudioRecordClient() {}
+                          const audio_io_handle_t io, uid_t uid, pid_t pid,
+                          const audio_session_t session, const audio_port_handle_t deviceId,
+                          const String16& opPackageName,
+                          bool canCaptureOutput, bool canCaptureHotword) :
+                    AudioClient(attributes, io, uid, pid, session, deviceId),
+                    opPackageName(opPackageName), startTimeNs(0),
+                    canCaptureOutput(canCaptureOutput), canCaptureHotword(canCaptureHotword) {}
+                ~AudioRecordClient() override = default;
 
-        const audio_attributes_t attributes; // source, flags ...
-        const audio_io_handle_t input;       // audio HAL input IO handle
-        const uid_t uid;                     // client UID
-        const pid_t pid;                     // client PID
         const String16 opPackageName;        // client package name
-        const audio_session_t session;       // audio session ID
-        bool active;                   // Capture is active or inactive
-        bool isConcurrent;             // is allowed to concurrent capture
-        bool isVirtualDevice;          // uses virtual device: updated by APM::getInputForAttr()
-        audio_port_handle_t deviceId;  // selected input device port ID
+        nsecs_t startTimeNs;
+        const bool canCaptureOutput;
+        const bool canCaptureHotword;
     };
 
+    // --- AudioPlaybackClient ---
+    // Information about each registered AudioTrack client
+    // (between calls to getOutputForAttr() and releaseOutput())
+    class AudioPlaybackClient : public AudioClient {
+    public:
+                AudioPlaybackClient(const audio_attributes_t attributes,
+                      const audio_io_handle_t io, uid_t uid, pid_t pid,
+                            const audio_session_t session, audio_port_handle_t deviceId,
+                            audio_stream_type_t stream) :
+                    AudioClient(attributes, io, uid, pid, session, deviceId), stream(stream) {}
+                ~AudioPlaybackClient() override = default;
+
+        const audio_stream_type_t stream;
+    };
+
+    void getPlaybackClientAndEffects(audio_port_handle_t portId,
+                                     sp<AudioPlaybackClient>& client,
+                                     sp<AudioPolicyEffects>& effects,
+                                     const char *context);
+
+
     // A class automatically clearing and restoring binder caller identity inside
     // a code block (scoped variable)
     // Declare one systematically before calling AudioPolicyManager methods so that they are
@@ -671,26 +836,31 @@
 
     mutable Mutex mLock;    // prevents concurrent access to AudioPolicy manager functions changing
                             // device connection state  or routing
-    mutable Mutex mEffectsLock; // serialize access to Effect state within APM.
     // Note: lock acquisition order is always mLock > mEffectsLock:
     // mLock protects AudioPolicyManager methods that can call into audio flinger
     // and possibly back in to audio policy service and acquire mEffectsLock.
     sp<AudioCommandThread> mAudioCommandThread;     // audio commands thread
-    sp<AudioCommandThread> mTonePlaybackThread;     // tone playback thread
     sp<AudioCommandThread> mOutputCommandThread;    // process stop and release output
     struct audio_policy_device *mpAudioPolicyDev;
     struct audio_policy *mpAudioPolicy;
     AudioPolicyInterface *mAudioPolicyManager;
     AudioPolicyClient *mAudioPolicyClient;
 
-    DefaultKeyedVector< uid_t, sp<NotificationClient> >    mNotificationClients;
+    DefaultKeyedVector< int64_t, sp<NotificationClient> >    mNotificationClients;
     Mutex mNotificationClientsLock;  // protects mNotificationClients
     // Manage all effects configured in audio_effects.conf
+    // never hold AudioPolicyService::mLock when calling AudioPolicyEffects methods as
+    // those can call back into AudioPolicyService methods and try to acquire the mutex
     sp<AudioPolicyEffects> mAudioPolicyEffects;
     audio_mode_t mPhoneState;
 
     sp<UidPolicy> mUidPolicy;
+    sp<SensorPrivacyPolicy> mSensorPrivacyPolicy;
+
     DefaultKeyedVector< audio_port_handle_t, sp<AudioRecordClient> >   mAudioRecordClients;
+    DefaultKeyedVector< audio_port_handle_t, sp<AudioPlaybackClient> >   mAudioPlaybackClients;
+
+    MediaPackageManager mPackageManager; // To check allowPlaybackCapture
 };
 
 } // namespace android
diff --git a/services/audiopolicy/tests/Android.mk b/services/audiopolicy/tests/Android.mk
index a43daea..ab9f78b 100644
--- a/services/audiopolicy/tests/Android.mk
+++ b/services/audiopolicy/tests/Android.mk
@@ -4,9 +4,7 @@
 
 LOCAL_C_INCLUDES := \
   frameworks/av/services/audiopolicy \
-  frameworks/av/services/audiopolicy/common/include \
-  frameworks/av/services/audiopolicy/engine/interface \
-  frameworks/av/services/audiopolicy/utilities
+  $(call include-path-for, audio-utils) \
 
 LOCAL_SHARED_LIBRARIES := \
   libaudiopolicymanagerdefault \
@@ -18,6 +16,11 @@
 LOCAL_STATIC_LIBRARIES := \
   libaudiopolicycomponents \
 
+LOCAL_HEADER_LIBRARIES := \
+    libaudiopolicycommon \
+    libaudiopolicyengine_interface_headers \
+    libaudiopolicymanager_interface_headers
+
 LOCAL_SRC_FILES := \
   audiopolicymanager_tests.cpp \
 
@@ -29,4 +32,34 @@
 
 LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
 
+LOCAL_COMPATIBILITY_SUITE := device-tests
+
+include $(BUILD_NATIVE_TEST)
+
+# system/audio.h utilities test
+
+include $(CLEAR_VARS)
+
+LOCAL_SHARED_LIBRARIES := \
+  libbase \
+  liblog \
+  libmedia_helper \
+  libutils
+
+LOCAL_HEADER_LIBRARIES := \
+  libmedia_headers
+
+LOCAL_SRC_FILES := \
+  systemaudio_tests.cpp \
+
+LOCAL_MODULE := systemaudio_tests
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_CFLAGS := -Werror -Wall
+
+LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
+
+LOCAL_COMPATIBILITY_SUITE := device-tests
+
 include $(BUILD_NATIVE_TEST)
diff --git a/services/audiopolicy/tests/AudioPolicyTestClient.h b/services/audiopolicy/tests/AudioPolicyTestClient.h
index eb8222c..e4c64e5 100644
--- a/services/audiopolicy/tests/AudioPolicyTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyTestClient.h
@@ -60,9 +60,6 @@
                        int /*delayMs*/) override { }
     String8 getParameters(audio_io_handle_t /*ioHandle*/,
                           const String8& /*keys*/) override { return String8(); }
-    status_t startTone(audio_policy_tone_t /*tone*/,
-                       audio_stream_type_t /*stream*/) override { return NO_INIT; }
-    status_t stopTone() override { return NO_INIT; }
     status_t setVoiceVolume(float /*volume*/, int /*delayMs*/) override { return NO_INIT; }
     status_t moveEffects(audio_session_t /*session*/,
                          audio_io_handle_t /*srcOutput*/,
@@ -76,13 +73,20 @@
                                 int /*delayMs*/) override { return NO_INIT; }
     void onAudioPortListUpdate() override { }
     void onAudioPatchListUpdate() override { }
+    void onAudioVolumeGroupChanged(volume_group_t /*group*/, int /*flags*/) override { }
     audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t /*use*/) override { return 0; }
     void onDynamicPolicyMixStateUpdate(String8 /*regId*/, int32_t /*state*/) override { }
-    void onRecordingConfigurationUpdate(int /*event*/,
-                                        const record_client_info_t* /*clientInfo*/,
-                                        const struct audio_config_base* /*clientConfig*/,
-                                        const struct audio_config_base* /*deviceConfig*/,
-                                        audio_patch_handle_t /*patchHandle*/) override { }
+    void onRecordingConfigurationUpdate(int event __unused,
+                                        const record_client_info_t *clientInfo __unused,
+                                        const audio_config_base_t *clientConfig __unused,
+                                        std::vector<effect_descriptor_t> clientEffects __unused,
+                                        const audio_config_base_t *deviceConfig __unused,
+                                        std::vector<effect_descriptor_t> effects __unused,
+                                        audio_patch_handle_t patchHandle __unused,
+                                        audio_source_t source __unused) override { }
+    void setEffectSuspended(int effectId __unused,
+                            audio_session_t sessionId __unused,
+                            bool suspended __unused) {}
 };
 
 } // namespace android
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index a9593b8..de5670c 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -16,9 +16,15 @@
 
 #include <memory>
 #include <set>
+#include <sys/wait.h>
+#include <unistd.h>
 
 #include <gtest/gtest.h>
 
+#define LOG_TAG "APM_Test"
+#include <log/log.h>
+#include <media/PatchBuilder.h>
+
 #include "AudioPolicyTestClient.h"
 #include "AudioPolicyTestManager.h"
 
@@ -106,10 +112,39 @@
     std::set<audio_patch_handle_t> mActivePatches;
 };
 
+class PatchCountCheck {
+  public:
+    explicit PatchCountCheck(AudioPolicyManagerTestClient *client)
+            : mClient{client},
+              mInitialCount{mClient->getActivePatchesCount()} {}
+    int deltaFromSnapshot() const {
+        size_t currentCount = mClient->getActivePatchesCount();
+        if (mInitialCount <= currentCount) {
+            return currentCount - mInitialCount;
+        } else {
+            return -(static_cast<int>(mInitialCount - currentCount));
+        }
+    }
+  private:
+    const AudioPolicyManagerTestClient *mClient;
+    const size_t mInitialCount;
+};
+
 class AudioPolicyManagerTest : public testing::Test {
   protected:
-    virtual void SetUp();
-    virtual void TearDown();
+    void SetUp() override;
+    void TearDown() override;
+    virtual void SetUpConfig(AudioPolicyConfig *config) { (void)config; }
+
+    void dumpToLog();
+    void getOutputForAttr(
+            audio_port_handle_t *selectedDeviceId,
+            audio_format_t format,
+            int channelMask,
+            int sampleRate,
+            audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
+            audio_port_handle_t *portId = nullptr);
+    PatchCountCheck snapshotPatchCount() { return PatchCountCheck(mClient.get()); }
 
     std::unique_ptr<AudioPolicyManagerTestClient> mClient;
     std::unique_ptr<AudioPolicyTestManager> mManager;
@@ -119,6 +154,7 @@
     mClient.reset(new AudioPolicyManagerTestClient);
     mManager.reset(new AudioPolicyTestManager(mClient.get()));
     mManager->getConfig().setDefault();
+    SetUpConfig(&mManager->getConfig());  // Subclasses may want to customize the config.
     ASSERT_EQ(NO_ERROR, mManager->initialize());
     ASSERT_EQ(NO_ERROR, mManager->initCheck());
 }
@@ -128,14 +164,73 @@
     mClient.reset();
 }
 
+void AudioPolicyManagerTest::dumpToLog() {
+    int pipefd[2];
+    ASSERT_NE(-1, pipe(pipefd));
+    pid_t cpid = fork();
+    ASSERT_NE(-1, cpid);
+    if (cpid == 0) {
+        // Child process reads from the pipe and logs.
+        close(pipefd[1]);
+        std::string line;
+        char buf;
+        while (read(pipefd[0], &buf, sizeof(buf)) > 0) {
+            if (buf != '\n') {
+                line += buf;
+            } else {
+                ALOGI("%s", line.c_str());
+                line = "";
+            }
+        }
+        if (!line.empty()) ALOGI("%s", line.c_str());
+        close(pipefd[0]);
+        _exit(EXIT_SUCCESS);
+    } else {
+        // Parent does the dump and checks the status code.
+        close(pipefd[0]);
+        ASSERT_EQ(NO_ERROR, mManager->dump(pipefd[1]));
+        close(pipefd[1]);
+        wait(NULL);  // Wait for the child to exit.
+    }
+}
+
+void AudioPolicyManagerTest::getOutputForAttr(
+        audio_port_handle_t *selectedDeviceId,
+        audio_format_t format,
+        int channelMask,
+        int sampleRate,
+        audio_output_flags_t flags,
+        audio_port_handle_t *portId) {
+    audio_attributes_t attr = {};
+    audio_io_handle_t output = AUDIO_PORT_HANDLE_NONE;
+    audio_stream_type_t stream = AUDIO_STREAM_DEFAULT;
+    audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+    config.sample_rate = sampleRate;
+    config.channel_mask = channelMask;
+    config.format = format;
+    *selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+    audio_port_handle_t localPortId;
+    if (!portId) portId = &localPortId;
+    *portId = AUDIO_PORT_HANDLE_NONE;
+    ASSERT_EQ(OK, mManager->getOutputForAttr(
+                    &attr, &output, AUDIO_SESSION_NONE, &stream, 0 /*uid*/, &config, &flags,
+                    selectedDeviceId, portId, {}));
+    ASSERT_NE(AUDIO_PORT_HANDLE_NONE, *portId);
+}
+
+
 TEST_F(AudioPolicyManagerTest, InitSuccess) {
     // SetUp must finish with no assertions.
 }
 
+TEST_F(AudioPolicyManagerTest, Dump) {
+    dumpToLog();
+}
+
 TEST_F(AudioPolicyManagerTest, CreateAudioPatchFailure) {
     audio_patch patch{};
     audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
-    const size_t patchCountBefore = mClient->getActivePatchesCount();
+    const PatchCountCheck patchCount = snapshotPatchCount();
     ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(nullptr, &handle, 0));
     ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, nullptr, 0));
     ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, &handle, 0));
@@ -162,35 +257,180 @@
     ASSERT_EQ(INVALID_OPERATION, mManager->createAudioPatch(&patch, &handle, 0));
     // Verify that the handle is left unchanged.
     ASSERT_EQ(AUDIO_PATCH_HANDLE_NONE, handle);
-    ASSERT_EQ(patchCountBefore, mClient->getActivePatchesCount());
+    ASSERT_EQ(0, patchCount.deltaFromSnapshot());
 }
 
 TEST_F(AudioPolicyManagerTest, CreateAudioPatchFromMix) {
-    audio_patch patch{};
     audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
     uid_t uid = 42;
-    const size_t patchCountBefore = mClient->getActivePatchesCount();
-    patch.num_sources = 1;
-    {
-        auto& src = patch.sources[0];
-        src.role = AUDIO_PORT_ROLE_SOURCE;
-        src.type = AUDIO_PORT_TYPE_MIX;
-        src.id = mManager->getConfig().getAvailableInputDevices()[0]->getId();
-        // Note: these are the parameters of the output device.
-        src.sample_rate = 44100;
-        src.format = AUDIO_FORMAT_PCM_16_BIT;
-        src.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
-    }
-    patch.num_sinks = 1;
-    {
-        auto& sink = patch.sinks[0];
-        sink.role = AUDIO_PORT_ROLE_SINK;
-        sink.type = AUDIO_PORT_TYPE_DEVICE;
-        sink.id = mManager->getConfig().getDefaultOutputDevice()->getId();
-    }
-    ASSERT_EQ(NO_ERROR, mManager->createAudioPatch(&patch, &handle, uid));
+    const PatchCountCheck patchCount = snapshotPatchCount();
+    ASSERT_FALSE(mManager->getConfig().getAvailableInputDevices().isEmpty());
+    PatchBuilder patchBuilder;
+    patchBuilder.addSource(mManager->getConfig().getAvailableInputDevices()[0]).
+            addSink(mManager->getConfig().getDefaultOutputDevice());
+    ASSERT_EQ(NO_ERROR, mManager->createAudioPatch(patchBuilder.patch(), &handle, uid));
     ASSERT_NE(AUDIO_PATCH_HANDLE_NONE, handle);
-    ASSERT_EQ(patchCountBefore + 1, mClient->getActivePatchesCount());
+    ASSERT_EQ(1, patchCount.deltaFromSnapshot());
 }
 
 // TODO: Add patch creation tests that involve already existing patch
+
+class AudioPolicyManagerTestMsd : public AudioPolicyManagerTest {
+  protected:
+    void SetUpConfig(AudioPolicyConfig *config) override;
+    void TearDown() override;
+
+    sp<DeviceDescriptor> mMsdOutputDevice;
+    sp<DeviceDescriptor> mMsdInputDevice;
+};
+
+void AudioPolicyManagerTestMsd::SetUpConfig(AudioPolicyConfig *config) {
+    // TODO: Consider using Serializer to load part of the config from a string.
+    mMsdOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_BUS);
+    sp<AudioProfile> pcmOutputProfile = new AudioProfile(
+            AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 48000);
+    sp<AudioProfile> ac3OutputProfile = new AudioProfile(
+            AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, 48000);
+    mMsdOutputDevice->addAudioProfile(pcmOutputProfile);
+    mMsdOutputDevice->addAudioProfile(ac3OutputProfile);
+    mMsdInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_BUS);
+    // Match output profile from AudioPolicyConfig::setDefault.
+    sp<AudioProfile> pcmInputProfile = new AudioProfile(
+            AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, 44100);
+    mMsdInputDevice->addAudioProfile(pcmInputProfile);
+    config->addAvailableDevice(mMsdOutputDevice);
+    config->addAvailableDevice(mMsdInputDevice);
+
+    sp<HwModule> msdModule = new HwModule(AUDIO_HARDWARE_MODULE_ID_MSD, 2 /*halVersionMajor*/);
+    HwModuleCollection modules = config->getHwModules();
+    modules.add(msdModule);
+    config->setHwModules(modules);
+    mMsdOutputDevice->attach(msdModule);
+    mMsdInputDevice->attach(msdModule);
+
+    sp<OutputProfile> msdOutputProfile = new OutputProfile(String8("msd input"));
+    msdOutputProfile->addAudioProfile(pcmOutputProfile);
+    msdOutputProfile->addSupportedDevice(mMsdOutputDevice);
+    msdModule->addOutputProfile(msdOutputProfile);
+    sp<OutputProfile> msdCompressedOutputProfile =
+            new OutputProfile(String8("msd compressed input"));
+    msdCompressedOutputProfile->addAudioProfile(ac3OutputProfile);
+    msdCompressedOutputProfile->setFlags(
+            AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
+            AUDIO_OUTPUT_FLAG_NON_BLOCKING);
+    msdCompressedOutputProfile->addSupportedDevice(mMsdOutputDevice);
+    msdModule->addOutputProfile(msdCompressedOutputProfile);
+
+    sp<InputProfile> msdInputProfile = new InputProfile(String8("msd output"));
+    msdInputProfile->addAudioProfile(pcmInputProfile);
+    msdInputProfile->addSupportedDevice(mMsdInputDevice);
+    msdModule->addInputProfile(msdInputProfile);
+
+    // Add a profile with another encoding to the default device to test routing
+    // of streams that are not supported by MSD.
+    sp<AudioProfile> dtsOutputProfile = new AudioProfile(
+            AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1, 48000);
+    config->getDefaultOutputDevice()->addAudioProfile(dtsOutputProfile);
+    sp<OutputProfile> primaryEncodedOutputProfile = new OutputProfile(String8("encoded"));
+    primaryEncodedOutputProfile->addAudioProfile(dtsOutputProfile);
+    primaryEncodedOutputProfile->setFlags(AUDIO_OUTPUT_FLAG_DIRECT);
+    primaryEncodedOutputProfile->addSupportedDevice(config->getDefaultOutputDevice());
+    config->getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
+            addOutputProfile(primaryEncodedOutputProfile);
+}
+
+void AudioPolicyManagerTestMsd::TearDown() {
+    mMsdOutputDevice.clear();
+    mMsdInputDevice.clear();
+    AudioPolicyManagerTest::TearDown();
+}
+
+TEST_F(AudioPolicyManagerTestMsd, InitSuccess) {
+    ASSERT_TRUE(mMsdOutputDevice);
+    ASSERT_TRUE(mMsdInputDevice);
+}
+
+TEST_F(AudioPolicyManagerTestMsd, Dump) {
+    dumpToLog();
+}
+
+TEST_F(AudioPolicyManagerTestMsd, PatchCreationOnSetForceUse) {
+    const PatchCountCheck patchCount = snapshotPatchCount();
+    mManager->setForceUse(AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND,
+            AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS);
+    ASSERT_EQ(1, patchCount.deltaFromSnapshot());
+}
+
+TEST_F(AudioPolicyManagerTestMsd, GetOutputForAttrEncodedRoutesToMsd) {
+    const PatchCountCheck patchCount = snapshotPatchCount();
+    audio_port_handle_t selectedDeviceId;
+    getOutputForAttr(&selectedDeviceId,
+            AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT);
+    ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
+    ASSERT_EQ(1, patchCount.deltaFromSnapshot());
+}
+
+TEST_F(AudioPolicyManagerTestMsd, GetOutputForAttrPcmRoutesToMsd) {
+    const PatchCountCheck patchCount = snapshotPatchCount();
+    audio_port_handle_t selectedDeviceId;
+    getOutputForAttr(&selectedDeviceId,
+            AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 48000);
+    ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
+    ASSERT_EQ(1, patchCount.deltaFromSnapshot());
+}
+
+TEST_F(AudioPolicyManagerTestMsd, GetOutputForAttrEncodedPlusPcmRoutesToMsd) {
+    const PatchCountCheck patchCount = snapshotPatchCount();
+    audio_port_handle_t selectedDeviceId;
+    getOutputForAttr(&selectedDeviceId,
+            AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT);
+    ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
+    ASSERT_EQ(1, patchCount.deltaFromSnapshot());
+    getOutputForAttr(&selectedDeviceId,
+            AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 48000);
+    ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
+    ASSERT_EQ(1, patchCount.deltaFromSnapshot());
+}
+
+TEST_F(AudioPolicyManagerTestMsd, GetOutputForAttrUnsupportedFormatBypassesMsd) {
+    const PatchCountCheck patchCount = snapshotPatchCount();
+    audio_port_handle_t selectedDeviceId;
+    getOutputForAttr(&selectedDeviceId,
+            AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT);
+    ASSERT_NE(selectedDeviceId, mMsdOutputDevice->getId());
+    ASSERT_EQ(0, patchCount.deltaFromSnapshot());
+}
+
+TEST_F(AudioPolicyManagerTestMsd, GetOutputForAttrFormatSwitching) {
+    // Switch between formats that are supported and not supported by MSD.
+    {
+        const PatchCountCheck patchCount = snapshotPatchCount();
+        audio_port_handle_t selectedDeviceId, portId;
+        getOutputForAttr(&selectedDeviceId,
+                AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT,
+                &portId);
+        ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
+        ASSERT_EQ(1, patchCount.deltaFromSnapshot());
+        mManager->releaseOutput(portId);
+        ASSERT_EQ(1, patchCount.deltaFromSnapshot());
+    }
+    {
+        const PatchCountCheck patchCount = snapshotPatchCount();
+        audio_port_handle_t selectedDeviceId, portId;
+        getOutputForAttr(&selectedDeviceId,
+                AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT,
+                &portId);
+        ASSERT_NE(selectedDeviceId, mMsdOutputDevice->getId());
+        ASSERT_EQ(-1, patchCount.deltaFromSnapshot());
+        mManager->releaseOutput(portId);
+        ASSERT_EQ(0, patchCount.deltaFromSnapshot());
+    }
+    {
+        const PatchCountCheck patchCount = snapshotPatchCount();
+        audio_port_handle_t selectedDeviceId;
+        getOutputForAttr(&selectedDeviceId,
+                AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT);
+        ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
+        ASSERT_EQ(0, patchCount.deltaFromSnapshot());
+    }
+}
diff --git a/services/audiopolicy/tests/systemaudio_tests.cpp b/services/audiopolicy/tests/systemaudio_tests.cpp
new file mode 100644
index 0000000..abaae52
--- /dev/null
+++ b/services/audiopolicy/tests/systemaudio_tests.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#define LOG_TAG "SysAudio_Test"
+#include <log/log.h>
+#include <media/PatchBuilder.h>
+#include <system/audio.h>
+
+using namespace android;
+
+TEST(SystemAudioTest, PatchInvalid) {
+    audio_patch patch{};
+    ASSERT_FALSE(audio_patch_is_valid(&patch));
+    patch.num_sources = AUDIO_PATCH_PORTS_MAX + 1;
+    patch.num_sinks = 1;
+    ASSERT_FALSE(audio_patch_is_valid(&patch));
+    patch.num_sources = 1;
+    patch.num_sinks = AUDIO_PATCH_PORTS_MAX + 1;
+    ASSERT_FALSE(audio_patch_is_valid(&patch));
+    patch.num_sources = 0;
+    patch.num_sinks = 1;
+    ASSERT_FALSE(audio_patch_is_valid(&patch));
+}
+
+TEST(SystemAudioTest, PatchValid) {
+    const audio_port_config src = {
+        .id = 1, .role = AUDIO_PORT_ROLE_SOURCE, .type = AUDIO_PORT_TYPE_DEVICE };
+    // It's OK not to have sinks.
+    ASSERT_TRUE(audio_patch_is_valid((PatchBuilder{}).addSource(src).patch()));
+    const audio_port_config sink = {
+        .id = 2, .role = AUDIO_PORT_ROLE_SINK, .type = AUDIO_PORT_TYPE_DEVICE };
+    ASSERT_TRUE(audio_patch_is_valid((PatchBuilder{}).addSource(src).addSink(sink).patch()));
+    ASSERT_TRUE(audio_patch_is_valid(
+                    (PatchBuilder{}).addSource(src).addSource(src).addSink(sink).patch()));
+    ASSERT_TRUE(audio_patch_is_valid(
+                    (PatchBuilder{}).addSource(src).addSink(sink).addSink(sink).patch()));
+    ASSERT_TRUE(audio_patch_is_valid(
+                    (PatchBuilder{}).addSource(src).addSource(src).
+                    addSink(sink).addSink(sink).patch()));
+}
+
+TEST(SystemAudioTest, PatchHwAvSync) {
+    audio_port_config device_src_cfg = {
+        .id = 1, .role = AUDIO_PORT_ROLE_SOURCE, .type = AUDIO_PORT_TYPE_DEVICE };
+    ASSERT_FALSE(audio_port_config_has_hw_av_sync(&device_src_cfg));
+    device_src_cfg.config_mask |= AUDIO_PORT_CONFIG_FLAGS;
+    ASSERT_FALSE(audio_port_config_has_hw_av_sync(&device_src_cfg));
+    device_src_cfg.flags.input = AUDIO_INPUT_FLAG_HW_AV_SYNC;
+    ASSERT_TRUE(audio_port_config_has_hw_av_sync(&device_src_cfg));
+
+    audio_port_config device_sink_cfg = {
+        .id = 1, .role = AUDIO_PORT_ROLE_SINK, .type = AUDIO_PORT_TYPE_DEVICE };
+    ASSERT_FALSE(audio_port_config_has_hw_av_sync(&device_sink_cfg));
+    device_sink_cfg.config_mask |= AUDIO_PORT_CONFIG_FLAGS;
+    ASSERT_FALSE(audio_port_config_has_hw_av_sync(&device_sink_cfg));
+    device_sink_cfg.flags.output = AUDIO_OUTPUT_FLAG_HW_AV_SYNC;
+    ASSERT_TRUE(audio_port_config_has_hw_av_sync(&device_sink_cfg));
+
+    audio_port_config mix_sink_cfg = {
+        .id = 1, .role = AUDIO_PORT_ROLE_SINK, .type = AUDIO_PORT_TYPE_MIX };
+    ASSERT_FALSE(audio_port_config_has_hw_av_sync(&mix_sink_cfg));
+    mix_sink_cfg.config_mask |= AUDIO_PORT_CONFIG_FLAGS;
+    ASSERT_FALSE(audio_port_config_has_hw_av_sync(&mix_sink_cfg));
+    mix_sink_cfg.flags.input = AUDIO_INPUT_FLAG_HW_AV_SYNC;
+    ASSERT_TRUE(audio_port_config_has_hw_av_sync(&mix_sink_cfg));
+
+    audio_port_config mix_src_cfg = {
+        .id = 1, .role = AUDIO_PORT_ROLE_SOURCE, .type = AUDIO_PORT_TYPE_MIX };
+    ASSERT_FALSE(audio_port_config_has_hw_av_sync(&mix_src_cfg));
+    mix_src_cfg.config_mask |= AUDIO_PORT_CONFIG_FLAGS;
+    ASSERT_FALSE(audio_port_config_has_hw_av_sync(&mix_src_cfg));
+    mix_src_cfg.flags.output = AUDIO_OUTPUT_FLAG_HW_AV_SYNC;
+    ASSERT_TRUE(audio_port_config_has_hw_av_sync(&mix_src_cfg));
+}
+
+TEST(SystemAudioTest, PatchEqual) {
+    const audio_patch patch1{}, patch2{};
+    // Invalid patches are not equal.
+    ASSERT_FALSE(audio_patches_are_equal(&patch1, &patch2));
+    const audio_port_config src = {
+        .id = 1, .role = AUDIO_PORT_ROLE_SOURCE, .type = AUDIO_PORT_TYPE_DEVICE };
+    const audio_port_config sink = {
+        .id = 2, .role = AUDIO_PORT_ROLE_SINK, .type = AUDIO_PORT_TYPE_DEVICE };
+    ASSERT_FALSE(audio_patches_are_equal(
+                    (PatchBuilder{}).addSource(src).patch(),
+                    (PatchBuilder{}).addSource(src).addSink(sink).patch()));
+    ASSERT_TRUE(audio_patches_are_equal(
+                    (PatchBuilder{}).addSource(src).addSink(sink).patch(),
+                    (PatchBuilder{}).addSource(src).addSink(sink).patch()));
+    ASSERT_FALSE(audio_patches_are_equal(
+                    (PatchBuilder{}).addSource(src).addSink(sink).patch(),
+                    (PatchBuilder{}).addSource(src).addSource(src).addSink(sink).patch()));
+    audio_port_config sink_hw_av_sync = sink;
+    sink_hw_av_sync.config_mask |= AUDIO_PORT_CONFIG_FLAGS;
+    sink_hw_av_sync.flags.output = AUDIO_OUTPUT_FLAG_HW_AV_SYNC;
+    ASSERT_FALSE(audio_patches_are_equal(
+                    (PatchBuilder{}).addSource(src).addSink(sink).patch(),
+                    (PatchBuilder{}).addSource(src).addSink(sink_hw_av_sync).patch()));
+    ASSERT_TRUE(audio_patches_are_equal(
+                    (PatchBuilder{}).addSource(src).addSink(sink_hw_av_sync).patch(),
+                    (PatchBuilder{}).addSource(src).addSink(sink_hw_av_sync).patch()));
+}
diff --git a/services/camera/OWNERS b/services/camera/OWNERS
index 18acfee..f48a95c 100644
--- a/services/camera/OWNERS
+++ b/services/camera/OWNERS
@@ -1,6 +1 @@
-cychen@google.com
-epeev@google.com
-etalvala@google.com
-shuzhenwang@google.com
-yinchiayeh@google.com
-zhijunhe@google.com
+include platform/frameworks/av:/camera/OWNERS
diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp
new file mode 100644
index 0000000..1c1f5e6
--- /dev/null
+++ b/services/camera/libcameraservice/Android.bp
@@ -0,0 +1,174 @@
+// Copyright 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//
+// libcameraservice
+//
+
+cc_library_shared {
+    name: "libcameraservice",
+
+    // Camera service source
+
+    srcs: [
+        "CameraService.cpp",
+        "CameraFlashlight.cpp",
+        "common/Camera2ClientBase.cpp",
+        "common/CameraDeviceBase.cpp",
+        "common/CameraProviderManager.cpp",
+        "common/FrameProcessorBase.cpp",
+        "api1/CameraClient.cpp",
+        "api1/Camera2Client.cpp",
+        "api1/client2/Parameters.cpp",
+        "api1/client2/FrameProcessor.cpp",
+        "api1/client2/StreamingProcessor.cpp",
+        "api1/client2/JpegProcessor.cpp",
+        "api1/client2/CallbackProcessor.cpp",
+        "api1/client2/JpegCompressor.cpp",
+        "api1/client2/CaptureSequencer.cpp",
+        "api1/client2/ZslProcessor.cpp",
+        "api2/CameraDeviceClient.cpp",
+        "api2/CompositeStream.cpp",
+        "api2/DepthCompositeStream.cpp",
+        "api2/HeicEncoderInfoManager.cpp",
+        "api2/HeicCompositeStream.cpp",
+        "device1/CameraHardwareInterface.cpp",
+        "device3/Camera3Device.cpp",
+        "device3/Camera3Stream.cpp",
+        "device3/Camera3IOStreamBase.cpp",
+        "device3/Camera3InputStream.cpp",
+        "device3/Camera3OutputStream.cpp",
+        "device3/Camera3DummyStream.cpp",
+        "device3/Camera3SharedOutputStream.cpp",
+        "device3/StatusTracker.cpp",
+        "device3/Camera3BufferManager.cpp",
+        "device3/Camera3StreamSplitter.cpp",
+        "device3/DistortionMapper.cpp",
+        "gui/RingBufferConsumer.cpp",
+        "utils/CameraThreadState.cpp",
+        "hidl/AidlCameraDeviceCallbacks.cpp",
+        "hidl/AidlCameraServiceListener.cpp",
+        "hidl/Convert.cpp",
+        "hidl/HidlCameraDeviceUser.cpp",
+        "hidl/HidlCameraService.cpp",
+        "utils/CameraTraces.cpp",
+        "utils/AutoConditionLock.cpp",
+        "utils/ExifUtils.cpp",
+        "utils/TagMonitor.cpp",
+        "utils/LatencyHistogram.cpp",
+    ],
+
+    shared_libs: [
+        "libbase",
+        "libdl",
+        "libexif",
+        "libui",
+        "liblog",
+        "libutilscallstack",
+        "libutils",
+        "libbinder",
+        "libcutils",
+        "libmedia",
+        "libmediautils",
+        "libcamera_client",
+        "libcamera_metadata",
+        "libfmq",
+        "libgui",
+        "libhardware",
+        "libhwbinder",
+        "libhidlbase",
+        "libhidltransport",
+        "libjpeg",
+        "libmedia_omx",
+        "libmemunreachable",
+        "libsensorprivacy",
+        "libstagefright",
+        "libstagefright_foundation",
+        "libyuv",
+        "android.frameworks.cameraservice.common@2.0",
+        "android.frameworks.cameraservice.service@2.0",
+        "android.frameworks.cameraservice.device@2.0",
+        "android.hardware.camera.common@1.0",
+        "android.hardware.camera.provider@2.4",
+        "android.hardware.camera.provider@2.5",
+        "android.hardware.camera.device@1.0",
+        "android.hardware.camera.device@3.2",
+        "android.hardware.camera.device@3.3",
+        "android.hardware.camera.device@3.4",
+        "android.hardware.camera.device@3.5",
+    ],
+
+    export_shared_lib_headers: [
+        "libbinder",
+        "libcamera_client",
+        "libfmq",
+        "libsensorprivacy",
+    ],
+
+    include_dirs: [
+        "system/media/private/camera/include",
+        "frameworks/native/include/media/openmax",
+        "frameworks/av/media/ndk",
+        "external/dynamic_depth/includes",
+        "external/dynamic_depth/internal",
+    ],
+
+    export_include_dirs: ["."],
+
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-Wno-ignored-qualifiers",
+    ],
+
+}
+
+cc_library_shared {
+    name: "libdepthphoto",
+
+    srcs: [
+        "utils/ExifUtils.cpp",
+        "common/DepthPhotoProcessor.cpp",
+    ],
+
+    shared_libs: [
+        "libimage_io",
+        "libdynamic_depth",
+        "libxml2",
+        "liblog",
+        "libutilscallstack",
+        "libutils",
+        "libcutils",
+        "libjpeg",
+        "libmemunreachable",
+        "libexif",
+        "libcamera_client",
+    ],
+
+    include_dirs: [
+        "external/dynamic_depth/includes",
+        "external/dynamic_depth/internal",
+    ],
+
+    export_include_dirs: ["."],
+
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-Wno-ignored-qualifiers",
+    ],
+
+}
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk
index 96261ab..4cfecfd 100644
--- a/services/camera/libcameraservice/Android.mk
+++ b/services/camera/libcameraservice/Android.mk
@@ -14,91 +14,9 @@
 
 LOCAL_PATH:= $(call my-dir)
 
-#
-# libcameraservice
-#
-
 include $(CLEAR_VARS)
 
-# Camera service source
-
-LOCAL_SRC_FILES :=  \
-    CameraService.cpp \
-    CameraFlashlight.cpp \
-    common/Camera2ClientBase.cpp \
-    common/CameraDeviceBase.cpp \
-    common/CameraProviderManager.cpp \
-    common/FrameProcessorBase.cpp \
-    api1/CameraClient.cpp \
-    api1/Camera2Client.cpp \
-    api1/client2/Parameters.cpp \
-    api1/client2/FrameProcessor.cpp \
-    api1/client2/StreamingProcessor.cpp \
-    api1/client2/JpegProcessor.cpp \
-    api1/client2/CallbackProcessor.cpp \
-    api1/client2/JpegCompressor.cpp \
-    api1/client2/CaptureSequencer.cpp \
-    api1/client2/ZslProcessor.cpp \
-    api2/CameraDeviceClient.cpp \
-    device1/CameraHardwareInterface.cpp \
-    device3/Camera3Device.cpp \
-    device3/Camera3Stream.cpp \
-    device3/Camera3IOStreamBase.cpp \
-    device3/Camera3InputStream.cpp \
-    device3/Camera3OutputStream.cpp \
-    device3/Camera3DummyStream.cpp \
-    device3/Camera3SharedOutputStream.cpp \
-    device3/StatusTracker.cpp \
-    device3/Camera3BufferManager.cpp \
-    device3/Camera3StreamSplitter.cpp \
-    device3/DistortionMapper.cpp \
-    gui/RingBufferConsumer.cpp \
-    utils/CameraTraces.cpp \
-    utils/AutoConditionLock.cpp \
-    utils/TagMonitor.cpp \
-    utils/LatencyHistogram.cpp
-
-LOCAL_SHARED_LIBRARIES:= \
-    libui \
-    liblog \
-    libutilscallstack \
-    libutils \
-    libbinder \
-    libcutils \
-    libmedia \
-    libmediautils \
-    libcamera_client \
-    libcamera_metadata \
-    libfmq \
-    libgui \
-    libhardware \
-    libhidlbase \
-    libhidltransport \
-    libjpeg \
-    libmemunreachable \
-    android.hardware.camera.common@1.0 \
-    android.hardware.camera.provider@2.4 \
-    android.hardware.camera.device@1.0 \
-    android.hardware.camera.device@3.2 \
-    android.hardware.camera.device@3.3 \
-    android.hardware.camera.device@3.4
-
-LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := libbinder libcamera_client libfmq
-
-LOCAL_C_INCLUDES += \
-    system/media/private/camera/include \
-    frameworks/native/include/media/openmax
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := \
-    frameworks/av/services/camera/libcameraservice
-
-LOCAL_CFLAGS += -Wall -Wextra -Werror
-
-LOCAL_MODULE:= libcameraservice
-
-include $(BUILD_SHARED_LIBRARY)
-
-# Build tests too
+# Build tests
 
 include $(LOCAL_PATH)/tests/Android.mk
 
diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp
index 471c77d..e629cdd 100644
--- a/services/camera/libcameraservice/CameraFlashlight.cpp
+++ b/services/camera/libcameraservice/CameraFlashlight.cpp
@@ -125,7 +125,7 @@
     status_t res;
 
     std::vector<String8> cameraIds;
-    std::vector<std::string> ids = mProviderManager->getAPI1CompatibleCameraDeviceIds();
+    std::vector<std::string> ids = mProviderManager->getCameraDeviceIds();
     int numberOfCameras = static_cast<int>(ids.size());
     cameraIds.resize(numberOfCameras);
     // No module, must be provider
@@ -217,7 +217,7 @@
 
         if (mOpenedCameraIds.size() == 0) {
             // notify torch unavailable for all cameras with a flash
-            std::vector<std::string> ids = mProviderManager->getAPI1CompatibleCameraDeviceIds();
+            std::vector<std::string> ids = mProviderManager->getCameraDeviceIds();
             int numCameras = static_cast<int>(ids.size());
             for (int i = 0; i < numCameras; i++) {
                 String8 id8(ids[i].c_str());
@@ -263,7 +263,7 @@
 
     if (isBackwardCompatibleMode(cameraId)) {
         // notify torch available for all cameras with a flash
-        std::vector<std::string> ids = mProviderManager->getAPI1CompatibleCameraDeviceIds();
+        std::vector<std::string> ids = mProviderManager->getCameraDeviceIds();
         int numCameras = static_cast<int>(ids.size());
         for (int i = 0; i < numCameras; i++) {
             String8 id8(ids[i].c_str());
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 2bf42b6..3e62102 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -33,6 +33,7 @@
 
 #include <android-base/macros.h>
 #include <android-base/parseint.h>
+#include <android-base/stringprintf.h>
 #include <binder/ActivityManager.h>
 #include <binder/AppOpsManager.h>
 #include <binder/IPCThreadState.h>
@@ -47,11 +48,15 @@
 #include <cutils/misc.h>
 #include <gui/Surface.h>
 #include <hardware/hardware.h>
+#include "hidl/HidlCameraService.h"
+#include <hidl/HidlTransportSupport.h>
+#include <hwbinder/IPCThreadState.h>
 #include <memunreachable/memunreachable.h>
 #include <media/AudioSystem.h>
 #include <media/IMediaHTTPService.h>
 #include <media/mediaplayer.h>
 #include <mediautils/BatteryNotifier.h>
+#include <sensorprivacy/SensorPrivacyManager.h>
 #include <utils/Errors.h>
 #include <utils/Log.h>
 #include <utils/String16.h>
@@ -69,6 +74,7 @@
 #include "api2/CameraDeviceClient.h"
 #include "utils/CameraTraces.h"
 #include "utils/TagMonitor.h"
+#include "utils/CameraThreadState.h"
 
 namespace {
     const char* kPermissionServiceName = "permission";
@@ -76,7 +82,9 @@
 
 namespace android {
 
+using base::StringPrintf;
 using binder::Status;
+using frameworks::cameraservice::service::V2_0::implementation::HidlCameraService;
 using hardware::ICamera;
 using hardware::ICameraClient;
 using hardware::ICameraServiceProxy;
@@ -111,6 +119,14 @@
 
 static const String16 sManageCameraPermission("android.permission.MANAGE_CAMERA");
 
+// Matches with PERCEPTIBLE_APP_ADJ in ProcessList.java
+static constexpr int32_t kVendorClientScore = 200;
+// Matches with PROCESS_STATE_PERSISTENT_UI in ActivityManager.java
+static constexpr int32_t kVendorClientState = 1;
+
+Mutex CameraService::sProxyMutex;
+sp<hardware::ICameraServiceProxy> CameraService::sCameraServiceProxy;
+
 CameraService::CameraService() :
         mEventLog(DEFAULT_EVENT_LOG_LENGTH),
         mNumberOfCameras(0),
@@ -141,6 +157,13 @@
 
     mUidPolicy = new UidPolicy(this);
     mUidPolicy->registerSelf();
+    mSensorPrivacyPolicy = new SensorPrivacyPolicy(this);
+    mSensorPrivacyPolicy->registerSelf();
+    sp<HidlCameraService> hcs = HidlCameraService::getInstance(this);
+    if (hcs->registerAsService() != android::OK) {
+        ALOGE("%s: Failed to register default android.frameworks.cameraservice.service@1.0",
+              __FUNCTION__);
+    }
 }
 
 status_t CameraService::enumerateProviders() {
@@ -181,25 +204,29 @@
 
     for (auto& cameraId : deviceIds) {
         String8 id8 = String8(cameraId.c_str());
-        onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);
+        if (getCameraState(id8) == nullptr) {
+            onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);
+        }
     }
 
     return OK;
 }
 
 sp<ICameraServiceProxy> CameraService::getCameraServiceProxy() {
-    sp<ICameraServiceProxy> proxyBinder = nullptr;
 #ifndef __BRILLO__
-    sp<IServiceManager> sm = defaultServiceManager();
-    // Use checkService because cameraserver normally starts before the
-    // system server and the proxy service. So the long timeout that getService
-    // has before giving up is inappropriate.
-    sp<IBinder> binder = sm->checkService(String16("media.camera.proxy"));
-    if (binder != nullptr) {
-        proxyBinder = interface_cast<ICameraServiceProxy>(binder);
+    Mutex::Autolock al(sProxyMutex);
+    if (sCameraServiceProxy == nullptr) {
+        sp<IServiceManager> sm = defaultServiceManager();
+        // Use checkService because cameraserver normally starts before the
+        // system server and the proxy service. So the long timeout that getService
+        // has before giving up is inappropriate.
+        sp<IBinder> binder = sm->checkService(String16("media.camera.proxy"));
+        if (binder != nullptr) {
+            sCameraServiceProxy = interface_cast<ICameraServiceProxy>(binder);
+        }
     }
 #endif
-    return proxyBinder;
+    return sCameraServiceProxy;
 }
 
 void CameraService::pingCameraServiceProxy() {
@@ -208,9 +235,18 @@
     proxyBinder->pingForUserUpdate();
 }
 
+void CameraService::broadcastTorchModeStatus(const String8& cameraId, TorchModeStatus status) {
+    Mutex::Autolock lock(mStatusListenerLock);
+
+    for (auto& i : mListenerList) {
+        i.second->getListener()->onTorchStatusChanged(mapToInterface(status), String16{cameraId});
+    }
+}
+
 CameraService::~CameraService() {
     VendorTagDescriptor::clearGlobalVendorTagDescriptor();
     mUidPolicy->unregisterSelf();
+    mSensorPrivacyPolicy->unregisterSelf();
 }
 
 void CameraService::onNewProviderRegistered() {
@@ -246,6 +282,8 @@
     if (mFlashlight->hasFlashUnit(id)) {
         Mutex::Autolock al(mTorchStatusMutex);
         mTorchStatusMap.add(id, TorchModeStatus::AVAILABLE_OFF);
+
+        broadcastTorchModeStatus(id, TorchModeStatus::AVAILABLE_OFF);
     }
 
     updateCameraNumAndIds();
@@ -325,7 +363,7 @@
                     hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
                     CaptureResultExtras{});
             // Ensure not in binder RPC so client disconnect PID checks work correctly
-            LOG_ALWAYS_FATAL_IF(getCallingPid() != getpid(),
+            LOG_ALWAYS_FATAL_IF(CameraThreadState::getCallingPid() != getpid(),
                     "onDeviceStatusChanged must be called from the camera service process!");
             clientToDisconnect->disconnect();
         }
@@ -398,12 +436,7 @@
         }
     }
 
-    {
-        Mutex::Autolock lock(mStatusListenerLock);
-        for (auto& i : mListenerList) {
-            i->onTorchStatusChanged(mapToInterface(newStatus), String16{cameraId});
-        }
-    }
+    broadcastTorchModeStatus(cameraId, newStatus);
 }
 
 Status CameraService::getNumberOfCameras(int32_t type, int32_t* numCameras) {
@@ -491,17 +524,37 @@
                 strerror(-res), res);
     }
 
+    int callingPid = CameraThreadState::getCallingPid();
+    int callingUid = CameraThreadState::getCallingUid();
+    std::vector<int32_t> tagsRemoved;
+    // If it's not calling from cameraserver, check the permission.
+    if ((callingPid != getpid()) &&
+            !checkPermission(String16("android.permission.CAMERA"), callingPid, callingUid)) {
+        res = cameraInfo->removePermissionEntries(
+                mCameraProviderManager->getProviderTagIdLocked(String8(cameraId).string()),
+                &tagsRemoved);
+        if (res != OK) {
+            cameraInfo->clear();
+            return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Failed to remove camera"
+                    " characteristics needing camera permission for device %s: %s (%d)",
+                    String8(cameraId).string(), strerror(-res), res);
+        }
+    }
+
+    if (!tagsRemoved.empty()) {
+        res = cameraInfo->update(ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION,
+                tagsRemoved.data(), tagsRemoved.size());
+        if (res != OK) {
+            cameraInfo->clear();
+            return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Failed to insert camera "
+                    "keys needing permission for device %s: %s (%d)", String8(cameraId).string(),
+                    strerror(-res), res);
+        }
+    }
+
     return ret;
 }
 
-int CameraService::getCallingPid() {
-    return IPCThreadState::self()->getCallingPid();
-}
-
-int CameraService::getCallingUid() {
-    return IPCThreadState::self()->getCallingUid();
-}
-
 String8 CameraService::getFormattedCurrentTime() {
     time_t now = time(nullptr);
     char formattedTime[64];
@@ -582,7 +635,7 @@
 Status CameraService::makeClient(const sp<CameraService>& cameraService,
         const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
         int api1CameraId, int facing, int clientPid, uid_t clientUid, int servicePid,
-        bool legacyMode, int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
+        int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
         /*out*/sp<BasicClient>* client) {
 
     if (halVersion < 0 || halVersion == deviceVersion) {
@@ -594,7 +647,7 @@
                 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
                 *client = new CameraClient(cameraService, tmp, packageName,
                         api1CameraId, facing, clientPid, clientUid,
-                        getpid(), legacyMode);
+                        getpid());
             } else { // Camera2 API route
                 ALOGW("Camera using old HAL version: %d", deviceVersion);
                 return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
@@ -607,12 +660,13 @@
           case CAMERA_DEVICE_API_VERSION_3_2:
           case CAMERA_DEVICE_API_VERSION_3_3:
           case CAMERA_DEVICE_API_VERSION_3_4:
+          case CAMERA_DEVICE_API_VERSION_3_5:
             if (effectiveApiLevel == API_1) { // Camera1 API route
                 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
                 *client = new Camera2Client(cameraService, tmp, packageName,
                         cameraId, api1CameraId,
                         facing, clientPid, clientUid,
-                        servicePid, legacyMode);
+                        servicePid);
             } else { // Camera2 API route
                 sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
                         static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
@@ -636,7 +690,7 @@
             sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
             *client = new CameraClient(cameraService, tmp, packageName,
                     api1CameraId, facing, clientPid, clientUid,
-                    servicePid, legacyMode);
+                    servicePid);
         } else {
             // Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
             ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
@@ -725,7 +779,7 @@
 }
 
 Status CameraService::initializeShimMetadata(int cameraId) {
-    int uid = getCallingUid();
+    int uid = CameraThreadState::getCallingUid();
 
     String16 internalPackageName("cameraserver");
     String8 id = String8::format("%d", cameraId);
@@ -735,8 +789,7 @@
             sp<ICameraClient>{nullptr}, id, cameraId,
             static_cast<int>(CAMERA_HAL_API_VERSION_UNSPECIFIED),
             internalPackageName, uid, USE_CALLING_PID,
-            API_1, /*legacyMode*/ false, /*shimUpdateOnly*/ true,
-            /*out*/ tmp)
+            API_1, /*shimUpdateOnly*/ true, /*out*/ tmp)
             ).isOk()) {
         ALOGE("%s: Error initializing shim metadata: %s", __FUNCTION__, ret.toString8().string());
     }
@@ -775,9 +828,9 @@
         }
     }
 
-    int64_t token = IPCThreadState::self()->clearCallingIdentity();
+    int64_t token = CameraThreadState::clearCallingIdentity();
     ret = initializeShimMetadata(cameraId);
-    IPCThreadState::self()->restoreCallingIdentity(token);
+    CameraThreadState::restoreCallingIdentity(token);
     if (!ret.isOk()) {
         // Error already logged by callee
         return ret;
@@ -817,6 +870,25 @@
     }
 }
 
+static status_t getUidForPackage(String16 packageName, int userId, /*inout*/uid_t& uid, int err) {
+    PermissionController pc;
+    uid = pc.getPackageUid(packageName, 0);
+    if (uid <= 0) {
+        ALOGE("Unknown package: '%s'", String8(packageName).string());
+        dprintf(err, "Unknown package: '%s'\n", String8(packageName).string());
+        return BAD_VALUE;
+    }
+
+    if (userId < 0) {
+        ALOGE("Invalid user: %d", userId);
+        dprintf(err, "Invalid user: %d\n", userId);
+        return BAD_VALUE;
+    }
+
+    uid = multiuser_get_uid(userId, uid);
+    return NO_ERROR;
+}
+
 Status CameraService::validateConnectLocked(const String8& cameraId,
         const String8& clientName8, /*inout*/int& clientUid, /*inout*/int& clientPid,
         /*out*/int& originalClientPid) const {
@@ -834,7 +906,7 @@
     }
 #endif  // __BRILLO__
 
-    int callingPid = getCallingPid();
+    int callingPid = CameraThreadState::getCallingPid();
 
     if (!mInitialized) {
         ALOGE("CameraService::connect X (PID %d) rejected (camera HAL module not loaded)",
@@ -868,8 +940,8 @@
 Status CameraService::validateClientPermissionsLocked(const String8& cameraId,
         const String8& clientName8, int& clientUid, int& clientPid,
         /*out*/int& originalClientPid) const {
-    int callingPid = getCallingPid();
-    int callingUid = getCallingUid();
+    int callingPid = CameraThreadState::getCallingPid();
+    int callingUid = CameraThreadState::getCallingUid();
 
     // Check if we can trust clientUid
     if (clientUid == USE_CALLING_UID) {
@@ -908,11 +980,22 @@
 
     // Make sure the UID is in an active state to use the camera
     if (!mUidPolicy->isUidActive(callingUid, String16(clientName8))) {
+        int32_t procState = mUidPolicy->getProcState(callingUid);
         ALOGE("Access Denial: can't use the camera from an idle UID pid=%d, uid=%d",
             clientPid, clientUid);
         return STATUS_ERROR_FMT(ERROR_DISABLED,
-                "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" from background",
-                clientName8.string(), clientUid, clientPid, cameraId.string());
+                "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" from background ("
+                "calling UID %d proc state %" PRId32 ")",
+                clientName8.string(), clientUid, clientPid, cameraId.string(),
+                callingUid, procState);
+    }
+
+    // If sensor privacy is enabled then prevent access to the camera
+    if (mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
+        ALOGE("Access Denial: cannot use the camera when sensor privacy is enabled");
+        return STATUS_ERROR_FMT(ERROR_DISABLED,
+                "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" when sensor privacy "
+                "is enabled", clientName8.string(), clientUid, clientPid, cameraId.string());
     }
 
     // Only use passed in clientPid to check permission. Use calling PID as the client PID that's
@@ -923,8 +1006,9 @@
     userid_t clientUserId = multiuser_get_user_id(clientUid);
 
     // Only allow clients who are being used by the current foreground device user, unless calling
-    // from our own process.
-    if (callingPid != getpid() && (mAllowedUsers.find(clientUserId) == mAllowedUsers.end())) {
+    // from our own process OR the caller is using the cameraserver's HIDL interface.
+    if (!hardware::IPCThreadState::self()->isServingCall() && callingPid != getpid() &&
+            (mAllowedUsers.find(clientUserId) == mAllowedUsers.end())) {
         ALOGE("CameraService::connect X (PID %d) rejected (cannot connect from "
                 "device user %d, currently allowed device users: %s)", callingPid, clientUserId,
                 toString(mAllowedUsers).string());
@@ -938,7 +1022,7 @@
 
 status_t CameraService::checkIfDeviceIsUsable(const String8& cameraId) const {
     auto cameraState = getCameraState(cameraId);
-    int callingPid = getCallingPid();
+    int callingPid = CameraThreadState::getCallingPid();
     if (cameraState == nullptr) {
         ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
                 cameraId.string());
@@ -1043,7 +1127,8 @@
         std::map<int,resource_policy::ClientPriority> pidToPriorityMap;
         for (size_t i = 0; i < ownerPids.size() - 1; i++) {
             pidToPriorityMap.emplace(ownerPids[i],
-                    resource_policy::ClientPriority(priorityScores[i], states[i]));
+                    resource_policy::ClientPriority(priorityScores[i], states[i],
+                            /* isVendorClient won't get copied over*/ false));
         }
         mActiveClientManager.updatePriorities(pidToPriorityMap);
 
@@ -1142,7 +1227,7 @@
     mServiceLock.unlock();
 
     // Clear caller identity temporarily so client disconnect PID checks work correctly
-    int64_t token = IPCThreadState::self()->clearCallingIdentity();
+    int64_t token = CameraThreadState::clearCallingIdentity();
 
     // Destroy evicted clients
     for (auto& i : evictedClients) {
@@ -1150,7 +1235,7 @@
         i->getValue()->disconnect(); // Clients will remove themselves from the active client list
     }
 
-    IPCThreadState::self()->restoreCallingIdentity(token);
+    CameraThreadState::restoreCallingIdentity(token);
 
     for (const auto& i : evictedClients) {
         ALOGV("%s: Waiting for disconnect to complete for client for device %s (PID %" PRId32 ")",
@@ -1200,11 +1285,10 @@
     sp<Client> client = nullptr;
     ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId,
             CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid, clientPid, API_1,
-            /*legacyMode*/ false, /*shimUpdateOnly*/ false,
-            /*out*/client);
+            /*shimUpdateOnly*/ false, /*out*/client);
 
     if(!ret.isOk()) {
-        logRejected(id, getCallingPid(), String8(clientPackageName),
+        logRejected(id, CameraThreadState::getCallingPid(), String8(clientPackageName),
                 ret.toString8());
         return ret;
     }
@@ -1227,12 +1311,11 @@
     Status ret = Status::ok();
     sp<Client> client = nullptr;
     ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId, halVersion,
-            clientPackageName, clientUid, USE_CALLING_PID, API_1,
-            /*legacyMode*/ true, /*shimUpdateOnly*/ false,
+            clientPackageName, clientUid, USE_CALLING_PID, API_1, /*shimUpdateOnly*/ false,
             /*out*/client);
 
     if(!ret.isOk()) {
-        logRejected(id, getCallingPid(), String8(clientPackageName),
+        logRejected(id, CameraThreadState::getCallingPid(), String8(clientPackageName),
                 ret.toString8());
         return ret;
     }
@@ -1241,6 +1324,18 @@
     return ret;
 }
 
+bool CameraService::shouldRejectHiddenCameraConnection(const String8 & cameraId) {
+    // If the thread serving this call is not a hwbinder thread and the caller
+    // isn't the cameraserver itself, and the camera id being requested is to be
+    // publically hidden, we should reject the connection.
+    if (!hardware::IPCThreadState::self()->isServingCall() &&
+            CameraThreadState::getCallingPid() != getpid() &&
+            mCameraProviderManager->isPublicallyHiddenSecureCamera(cameraId.c_str())) {
+        return true;
+    }
+    return false;
+}
+
 Status CameraService::connectDevice(
         const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
         const String16& cameraId,
@@ -1253,15 +1348,14 @@
     Status ret = Status::ok();
     String8 id = String8(cameraId);
     sp<CameraDeviceClient> client = nullptr;
+
     ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
             /*api1CameraId*/-1,
             CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName,
-            clientUid, USE_CALLING_PID, API_2,
-            /*legacyMode*/ false, /*shimUpdateOnly*/ false,
-            /*out*/client);
+            clientUid, USE_CALLING_PID, API_2, /*shimUpdateOnly*/ false, /*out*/client);
 
     if(!ret.isOk()) {
-        logRejected(id, getCallingPid(), String8(clientPackageName),
+        logRejected(id, CameraThreadState::getCallingPid(), String8(clientPackageName),
                 ret.toString8());
         return ret;
     }
@@ -1273,7 +1367,7 @@
 template<class CALLBACK, class CLIENT>
 Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
         int api1CameraId, int halVersion, const String16& clientPackageName, int clientUid,
-        int clientPid, apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly,
+        int clientPid, apiLevel effectiveApiLevel, bool shimUpdateOnly,
         /*out*/sp<CLIENT>& device) {
     binder::Status ret = binder::Status::ok();
 
@@ -1286,6 +1380,14 @@
             (halVersion == -1) ? "default" : std::to_string(halVersion).c_str(),
             static_cast<int>(effectiveApiLevel));
 
+    if (shouldRejectHiddenCameraConnection(cameraId)) {
+        ALOGW("Attempting to connect to system-only camera id %s, connection rejected",
+              cameraId.c_str());
+        return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
+                                "No camera device with ID \"%s\" currently available",
+                                cameraId.string());
+
+    }
     sp<CLIENT> client = nullptr;
     {
         // Acquire mServiceLock and prevent other clients from connecting
@@ -1358,7 +1460,7 @@
         sp<BasicClient> tmp = nullptr;
         if(!(ret = makeClient(this, cameraCb, clientPackageName,
                 cameraId, api1CameraId, facing,
-                clientPid, clientUid, getpid(), legacyMode,
+                clientPid, clientUid, getpid(),
                 halVersion, deviceVersion, effectiveApiLevel,
                 /*out*/&tmp)).isOk()) {
             return ret;
@@ -1442,7 +1544,7 @@
     }
 
     String8 id = String8(cameraId.string());
-    int uid = getCallingUid();
+    int uid = CameraThreadState::getCallingUid();
 
     // verify id is valid.
     auto state = getCameraState(id);
@@ -1544,18 +1646,42 @@
         }
     }
 
+    int clientPid = CameraThreadState::getCallingPid();
+    const char *id_cstr = id.c_str();
+    const char *torchState = enabled ? "on" : "off";
+    ALOGI("Torch for camera id %s turned %s for client PID %d", id_cstr, torchState, clientPid);
+    logTorchEvent(id_cstr, torchState , clientPid);
     return Status::ok();
 }
 
 Status CameraService::notifySystemEvent(int32_t eventId,
         const std::vector<int32_t>& args) {
+    const int pid = CameraThreadState::getCallingPid();
+    const int selfPid = getpid();
+
+    // Permission checks
+    if (pid != selfPid) {
+        // Ensure we're being called by system_server, or similar process with
+        // permissions to notify the camera service about system events
+        if (!checkCallingPermission(
+                String16("android.permission.CAMERA_SEND_SYSTEM_EVENTS"))) {
+            const int uid = CameraThreadState::getCallingUid();
+            ALOGE("Permission Denial: cannot send updates to camera service about system"
+                    " events from pid=%d, uid=%d", pid, uid);
+            return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
+                    "No permission to send updates to camera service about system events"
+                    " from pid=%d, uid=%d", pid, uid);
+        }
+    }
+
     ATRACE_CALL();
 
     switch(eventId) {
         case ICameraService::EVENT_USER_SWITCHED: {
-            // Try to register for UID policy updates, in case we're recovering
+            // Try to register for UID and sensor privacy policy updates, in case we're recovering
             // from a system server crash
             mUidPolicy->registerSelf();
+            mSensorPrivacyPolicy->registerSelf();
             doUserSwitch(/*newUserIds*/ args);
             break;
         }
@@ -1569,9 +1695,72 @@
     return Status::ok();
 }
 
+void CameraService::notifyMonitoredUids() {
+    Mutex::Autolock lock(mStatusListenerLock);
+
+    for (const auto& it : mListenerList) {
+        auto ret = it.second->getListener()->onCameraAccessPrioritiesChanged();
+        if (!ret.isOk()) {
+            ALOGE("%s: Failed to trigger permission callback: %d", __FUNCTION__,
+                    ret.exceptionCode());
+        }
+    }
+}
+
+Status CameraService::notifyDeviceStateChange(int64_t newState) {
+    const int pid = CameraThreadState::getCallingPid();
+    const int selfPid = getpid();
+
+    // Permission checks
+    if (pid != selfPid) {
+        // Ensure we're being called by system_server, or similar process with
+        // permissions to notify the camera service about system events
+        if (!checkCallingPermission(
+                String16("android.permission.CAMERA_SEND_SYSTEM_EVENTS"))) {
+            const int uid = CameraThreadState::getCallingUid();
+            ALOGE("Permission Denial: cannot send updates to camera service about device"
+                    " state changes from pid=%d, uid=%d", pid, uid);
+            return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
+                    "No permission to send updates to camera service about device state"
+                    " changes from pid=%d, uid=%d", pid, uid);
+        }
+    }
+
+    ATRACE_CALL();
+
+    using hardware::camera::provider::V2_5::DeviceState;
+    hardware::hidl_bitfield<DeviceState> newDeviceState{};
+    if (newState & ICameraService::DEVICE_STATE_BACK_COVERED) {
+        newDeviceState |= DeviceState::BACK_COVERED;
+    }
+    if (newState & ICameraService::DEVICE_STATE_FRONT_COVERED) {
+        newDeviceState |= DeviceState::FRONT_COVERED;
+    }
+    if (newState & ICameraService::DEVICE_STATE_FOLDED) {
+        newDeviceState |= DeviceState::FOLDED;
+    }
+    // Only map vendor bits directly
+    uint64_t vendorBits = static_cast<uint64_t>(newState) & 0xFFFFFFFF00000000l;
+    newDeviceState |= vendorBits;
+
+    ALOGV("%s: New device state 0x%" PRIx64, __FUNCTION__, newDeviceState);
+    Mutex::Autolock l(mServiceLock);
+    mCameraProviderManager->notifyDeviceStateChange(newDeviceState);
+
+    return Status::ok();
+}
+
 Status CameraService::addListener(const sp<ICameraServiceListener>& listener,
         /*out*/
         std::vector<hardware::CameraStatus> *cameraStatuses) {
+    return addListenerHelper(listener, cameraStatuses);
+}
+
+Status CameraService::addListenerHelper(const sp<ICameraServiceListener>& listener,
+        /*out*/
+        std::vector<hardware::CameraStatus> *cameraStatuses,
+        bool isVendorListener) {
+
     ATRACE_CALL();
 
     ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
@@ -1585,21 +1774,37 @@
 
     {
         Mutex::Autolock lock(mStatusListenerLock);
-        for (auto& it : mListenerList) {
-            if (IInterface::asBinder(it) == IInterface::asBinder(listener)) {
+        for (const auto &it : mListenerList) {
+            if (IInterface::asBinder(it.second->getListener()) == IInterface::asBinder(listener)) {
                 ALOGW("%s: Tried to add listener %p which was already subscribed",
                       __FUNCTION__, listener.get());
                 return STATUS_ERROR(ERROR_ALREADY_EXISTS, "Listener already registered");
             }
         }
 
-        mListenerList.push_back(listener);
+        auto clientUid = CameraThreadState::getCallingUid();
+        sp<ServiceListener> serviceListener = new ServiceListener(this, listener, clientUid);
+        auto ret = serviceListener->initialize();
+        if (ret != NO_ERROR) {
+            String8 msg = String8::format("Failed to initialize service listener: %s (%d)",
+                    strerror(-ret), ret);
+            ALOGE("%s: %s", __FUNCTION__, msg.string());
+            return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
+        }
+        mListenerList.emplace_back(isVendorListener, serviceListener);
+        mUidPolicy->registerMonitorUid(clientUid);
     }
 
     /* Collect current devices and status */
     {
         Mutex::Autolock lock(mCameraStatesLock);
         for (auto& i : mCameraStates) {
+            if (!isVendorListener &&
+                mCameraProviderManager->isPublicallyHiddenSecureCamera(i.first.c_str())) {
+                ALOGV("Cannot add public listener for hidden system-only %s for pid %d",
+                      i.first.c_str(), CameraThreadState::getCallingPid());
+                continue;
+            }
             cameraStatuses->emplace_back(i.first, mapToInterface(i.second->getStatus()));
         }
     }
@@ -1634,7 +1839,9 @@
     {
         Mutex::Autolock lock(mStatusListenerLock);
         for (auto it = mListenerList.begin(); it != mListenerList.end(); it++) {
-            if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) {
+            if (IInterface::asBinder(it->second->getListener()) == IInterface::asBinder(listener)) {
+                mUidPolicy->unregisterMonitorUid(it->second->getListenerUid());
+                IInterface::asBinder(listener)->unlinkToDeath(it->second);
                 mListenerList.erase(it);
                 return Status::ok();
             }
@@ -1692,7 +1899,7 @@
     }
 
     int deviceVersion = getDeviceVersion(id);
-    switch(deviceVersion) {
+    switch (deviceVersion) {
         case CAMERA_DEVICE_API_VERSION_1_0:
         case CAMERA_DEVICE_API_VERSION_3_0:
         case CAMERA_DEVICE_API_VERSION_3_1:
@@ -1709,6 +1916,7 @@
         case CAMERA_DEVICE_API_VERSION_3_2:
         case CAMERA_DEVICE_API_VERSION_3_3:
         case CAMERA_DEVICE_API_VERSION_3_4:
+        case CAMERA_DEVICE_API_VERSION_3_5:
             ALOGV("%s: Camera id %s uses HAL3.2 or newer, supports api1/api2 directly",
                     __FUNCTION__, id.string());
             *isSupported = true;
@@ -1729,6 +1937,18 @@
     return Status::ok();
 }
 
+Status CameraService::isHiddenPhysicalCamera(const String16& cameraId,
+        /*out*/ bool *isSupported) {
+    ATRACE_CALL();
+
+    const String8 id = String8(cameraId);
+
+    ALOGV("%s: for camera ID = %s", __FUNCTION__, id.string());
+    *isSupported = mCameraProviderManager->isHiddenPhysicalCamera(id.string());
+
+    return Status::ok();
+}
+
 void CameraService::removeByClient(const BasicClient* client) {
     Mutex::Autolock lock(mServiceLock);
     for (auto& i : mActiveClientManager.getAll()) {
@@ -1876,13 +2096,13 @@
     mServiceLock.unlock();
 
     // Clear caller identity temporarily so client disconnect PID checks work correctly
-    int64_t token = IPCThreadState::self()->clearCallingIdentity();
+    int64_t token = CameraThreadState::clearCallingIdentity();
 
     for (auto& i : evicted) {
         i->disconnect();
     }
 
-    IPCThreadState::self()->restoreCallingIdentity(token);
+    CameraThreadState::restoreCallingIdentity(token);
 
     // Reacquire mServiceLock
     mServiceLock.lock();
@@ -1915,6 +2135,12 @@
             cameraId, clientPackage, clientPid, reason));
 }
 
+void CameraService::logTorchEvent(const char* cameraId, const char *torchState, int clientPid) {
+    // Log torch event
+    logEvent(String8::format("Torch for camera id %s turned %s for client PID %d", cameraId,
+            torchState, clientPid));
+}
+
 void CameraService::logUserSwitch(const std::set<userid_t>& oldUserIds,
         const std::set<userid_t>& newUserIds) {
     String8 newUsers = toString(newUserIds);
@@ -1950,9 +2176,6 @@
 status_t CameraService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
         uint32_t flags) {
 
-    const int pid = getCallingPid();
-    const int selfPid = getpid();
-
     // Permission checks
     switch (code) {
         case SHELL_COMMAND_TRANSACTION: {
@@ -1979,20 +2202,6 @@
             }
             return NO_ERROR;
         }
-        case BnCameraService::NOTIFYSYSTEMEVENT: {
-            if (pid != selfPid) {
-                // Ensure we're being called by system_server, or similar process with
-                // permissions to notify the camera service about system events
-                if (!checkCallingPermission(
-                        String16("android.permission.CAMERA_SEND_SYSTEM_EVENTS"))) {
-                    const int uid = getCallingUid();
-                    ALOGE("Permission Denial: cannot send updates to camera service about system"
-                            " events from pid=%d, uid=%d", pid, uid);
-                    return PERMISSION_DENIED;
-                }
-            }
-            break;
-        }
     }
 
     return BnCameraService::onTransact(code, data, reply, flags);
@@ -2018,31 +2227,37 @@
     return mp;
 }
 
-void CameraService::loadSound() {
+void CameraService::increaseSoundRef() {
+    Mutex::Autolock lock(mSoundLock);
+    mSoundRef++;
+}
+
+void CameraService::loadSoundLocked(sound_kind kind) {
     ATRACE_CALL();
 
-    Mutex::Autolock lock(mSoundLock);
-    LOG1("CameraService::loadSound ref=%d", mSoundRef);
-    if (mSoundRef++) return;
-
-    mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/product/media/audio/ui/camera_click.ogg");
-    if (mSoundPlayer[SOUND_SHUTTER] == nullptr) {
-        mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
-    }
-    mSoundPlayer[SOUND_RECORDING_START] = newMediaPlayer("/product/media/audio/ui/VideoRecord.ogg");
-    if (mSoundPlayer[SOUND_RECORDING_START] == nullptr) {
-        mSoundPlayer[SOUND_RECORDING_START] =
+    LOG1("CameraService::loadSoundLocked ref=%d", mSoundRef);
+    if (SOUND_SHUTTER == kind && mSoundPlayer[SOUND_SHUTTER] == NULL) {
+        mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/product/media/audio/ui/camera_click.ogg");
+        if (mSoundPlayer[SOUND_SHUTTER] == nullptr) {
+            mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
+        }
+    } else if (SOUND_RECORDING_START == kind && mSoundPlayer[SOUND_RECORDING_START] ==  NULL) {
+        mSoundPlayer[SOUND_RECORDING_START] = newMediaPlayer("/product/media/audio/ui/VideoRecord.ogg");
+        if (mSoundPlayer[SOUND_RECORDING_START] == nullptr) {
+            mSoundPlayer[SOUND_RECORDING_START] =
                 newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
-    }
-    mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/product/media/audio/ui/VideoStop.ogg");
-    if (mSoundPlayer[SOUND_RECORDING_STOP] == nullptr) {
-        mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/system/media/audio/ui/VideoStop.ogg");
+        }
+    } else if (SOUND_RECORDING_STOP == kind && mSoundPlayer[SOUND_RECORDING_STOP] == NULL) {
+        mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/product/media/audio/ui/VideoStop.ogg");
+        if (mSoundPlayer[SOUND_RECORDING_STOP] == nullptr) {
+            mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/system/media/audio/ui/VideoStop.ogg");
+        }
     }
 }
 
-void CameraService::releaseSound() {
+void CameraService::decreaseSoundRef() {
     Mutex::Autolock lock(mSoundLock);
-    LOG1("CameraService::releaseSound ref=%d", mSoundRef);
+    LOG1("CameraService::decreaseSoundRef ref=%d", mSoundRef);
     if (--mSoundRef) return;
 
     for (int i = 0; i < NUM_SOUNDS; i++) {
@@ -2058,6 +2273,7 @@
 
     LOG1("playSound(%d)", kind);
     Mutex::Autolock lock(mSoundLock);
+    loadSoundLocked(kind);
     sp<MediaPlayer> player = mSoundPlayer[kind];
     if (player != 0) {
         player->seekTo(0);
@@ -2082,12 +2298,12 @@
                 servicePid),
         mCameraId(api1CameraId)
 {
-    int callingPid = getCallingPid();
+    int callingPid = CameraThreadState::getCallingPid();
     LOG1("Client::Client E (pid %d, id %d)", callingPid, mCameraId);
 
     mRemoteCallback = cameraClient;
 
-    cameraService->loadSound();
+    cameraService->increaseSoundRef();
 
     LOG1("Client::Client X (pid %d, id %d)", callingPid, mCameraId);
 }
@@ -2097,7 +2313,7 @@
     ALOGV("~Client");
     mDestructionStarted = true;
 
-    sCameraService->releaseSound();
+    sCameraService->decreaseSoundRef();
     // unconditionally disconnect. function is idempotent
     Client::disconnect();
 }
@@ -2152,6 +2368,13 @@
         }
         mClientPackageName = packages[0];
     }
+    if (hardware::IPCThreadState::self()->isServingCall()) {
+        std::string vendorClient =
+                StringPrintf("vendor.client.pid<%d>", CameraThreadState::getCallingPid());
+        mClientPackageName = String16(vendorClient.c_str());
+    } else {
+        mAppOpsManager = std::make_unique<AppOpsManager>();
+    }
 }
 
 CameraService::BasicClient::~BasicClient() {
@@ -2167,8 +2390,9 @@
     mDisconnected = true;
 
     sCameraService->removeByClient(this);
-    sCameraService->logDisconnected(mCameraIdStr, mClientPid,
-            String8(mClientPackageName));
+    sCameraService->logDisconnected(mCameraIdStr, mClientPid, String8(mClientPackageName));
+    sCameraService->mCameraProviderManager->removeRef(CameraProviderManager::DeviceMode::CAMERA,
+            mCameraIdStr.c_str());
 
     sp<IBinder> remote = getRemote();
     if (remote != nullptr) {
@@ -2191,7 +2415,7 @@
     // No dumping of clients directly over Binder,
     // must go through CameraService::dump
     android_errorWriteWithInfoLog(SN_EVENT_LOG_ID, "26265403",
-            IPCThreadState::self()->getCallingUid(), NULL, 0);
+            CameraThreadState::getCallingUid(), NULL, 0);
     return OK;
 }
 
@@ -2216,31 +2440,31 @@
 status_t CameraService::BasicClient::startCameraOps() {
     ATRACE_CALL();
 
-    int32_t res;
-    // Notify app ops that the camera is not available
-    mOpsCallback = new OpsCallback(this);
-
     {
         ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
               __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
     }
+    if (mAppOpsManager != nullptr) {
+        // Notify app ops that the camera is not available
+        mOpsCallback = new OpsCallback(this);
+        int32_t res;
+        mAppOpsManager->startWatchingMode(AppOpsManager::OP_CAMERA,
+                mClientPackageName, mOpsCallback);
+        res = mAppOpsManager->startOpNoThrow(AppOpsManager::OP_CAMERA,
+                mClientUid, mClientPackageName, /*startIfModeDefault*/ false);
 
-    mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
-            mClientPackageName, mOpsCallback);
-    res = mAppOpsManager.startOpNoThrow(AppOpsManager::OP_CAMERA,
-            mClientUid, mClientPackageName, /*startIfModeDefault*/ false);
+        if (res == AppOpsManager::MODE_ERRORED) {
+            ALOGI("Camera %s: Access for \"%s\" has been revoked",
+                    mCameraIdStr.string(), String8(mClientPackageName).string());
+            return PERMISSION_DENIED;
+        }
 
-    if (res == AppOpsManager::MODE_ERRORED) {
-        ALOGI("Camera %s: Access for \"%s\" has been revoked",
-                mCameraIdStr.string(), String8(mClientPackageName).string());
-        return PERMISSION_DENIED;
-    }
-
-    if (res == AppOpsManager::MODE_IGNORED) {
-        ALOGI("Camera %s: Access for \"%s\" has been restricted",
-                mCameraIdStr.string(), String8(mClientPackageName).string());
-        // Return the same error as for device policy manager rejection
-        return -EACCES;
+        if (res == AppOpsManager::MODE_IGNORED) {
+            ALOGI("Camera %s: Access for \"%s\" has been restricted",
+                    mCameraIdStr.string(), String8(mClientPackageName).string());
+            // Return the same error as for device policy manager rejection
+            return -EACCES;
+        }
     }
 
     mOpsActive = true;
@@ -2256,6 +2480,8 @@
     sCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_OPEN,
             mCameraIdStr, mCameraFacing, mClientPackageName, apiLevel);
 
+    sCameraService->mUidPolicy->registerMonitorUid(mClientUid);
+
     return OK;
 }
 
@@ -2265,10 +2491,11 @@
     // Check if startCameraOps succeeded, and if so, finish the camera op
     if (mOpsActive) {
         // Notify app ops that the camera is available again
-        mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
-                mClientPackageName);
-        mOpsActive = false;
-
+        if (mAppOpsManager != nullptr) {
+            mAppOpsManager->finishOp(AppOpsManager::OP_CAMERA, mClientUid,
+                    mClientPackageName);
+            mOpsActive = false;
+        }
         // This function is called when a client disconnects. This should
         // release the camera, but actually only if it was in a proper
         // functional state, i.e. with status NOT_AVAILABLE
@@ -2288,27 +2515,28 @@
                 mCameraIdStr, mCameraFacing, mClientPackageName, apiLevel);
     }
     // Always stop watching, even if no camera op is active
-    if (mOpsCallback != NULL) {
-        mAppOpsManager.stopWatchingMode(mOpsCallback);
+    if (mOpsCallback != nullptr && mAppOpsManager != nullptr) {
+        mAppOpsManager->stopWatchingMode(mOpsCallback);
     }
     mOpsCallback.clear();
 
+    sCameraService->mUidPolicy->unregisterMonitorUid(mClientUid);
+
     return OK;
 }
 
-void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
+void CameraService::BasicClient::opChanged(int32_t op, const String16&) {
     ATRACE_CALL();
-
-    String8 name(packageName);
-    String8 myName(mClientPackageName);
-
+    if (mAppOpsManager == nullptr) {
+        return;
+    }
     if (op != AppOpsManager::OP_CAMERA) {
         ALOGW("Unexpected app ops notification received: %d", op);
         return;
     }
 
     int32_t res;
-    res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
+    res = mAppOpsManager->checkOp(AppOpsManager::OP_CAMERA,
             mClientUid, mClientPackageName);
     ALOGV("checkOp returns: %d, %s ", res,
             res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
@@ -2318,7 +2546,7 @@
 
     if (res != AppOpsManager::MODE_ALLOWED) {
         ALOGI("Camera %s: Access for \"%s\" revoked", mCameraIdStr.string(),
-                myName.string());
+              String8(mClientPackageName).string());
         block();
     }
 }
@@ -2328,7 +2556,7 @@
 
     // Reset the client PID to allow server-initiated disconnect,
     // and to prevent further calls by client.
-    mClientPid = getCallingPid();
+    mClientPid = CameraThreadState::getCallingPid();
     CaptureResultExtras resultExtras; // a dummy result (invalid)
     notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISABLED, resultExtras);
     disconnect();
@@ -2383,7 +2611,7 @@
     if (mRegistered) return;
     am.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE
             | ActivityManager::UID_OBSERVER_IDLE
-            | ActivityManager::UID_OBSERVER_ACTIVE,
+            | ActivityManager::UID_OBSERVER_ACTIVE | ActivityManager::UID_OBSERVER_PROCSTATE,
             ActivityManager::PROCESS_STATE_UNKNOWN,
             String16("cameraserver"));
     status_t res = am.linkToDeath(this);
@@ -2429,6 +2657,51 @@
     }
 }
 
+void CameraService::UidPolicy::onUidStateChanged(uid_t uid, int32_t procState,
+        int64_t /*procStateSeq*/) {
+    bool procStateChange = false;
+    {
+        Mutex::Autolock _l(mUidLock);
+        if ((mMonitoredUids.find(uid) != mMonitoredUids.end()) &&
+                (mMonitoredUids[uid].first != procState)) {
+            mMonitoredUids[uid].first = procState;
+            procStateChange = true;
+        }
+    }
+
+    if (procStateChange) {
+        sp<CameraService> service = mService.promote();
+        if (service != nullptr) {
+            service->notifyMonitoredUids();
+        }
+    }
+}
+
+void CameraService::UidPolicy::registerMonitorUid(uid_t uid) {
+    Mutex::Autolock _l(mUidLock);
+    auto it = mMonitoredUids.find(uid);
+    if (it != mMonitoredUids.end()) {
+        it->second.second++;
+    } else {
+        mMonitoredUids.emplace(
+                std::pair<uid_t, std::pair<int32_t, size_t>> (uid,
+                    std::pair<int32_t, size_t> (ActivityManager::PROCESS_STATE_NONEXISTENT, 1)));
+    }
+}
+
+void CameraService::UidPolicy::unregisterMonitorUid(uid_t uid) {
+    Mutex::Autolock _l(mUidLock);
+    auto it = mMonitoredUids.find(uid);
+    if (it != mMonitoredUids.end()) {
+        it->second.second--;
+        if (it->second.second == 0) {
+            mMonitoredUids.erase(it);
+        }
+    } else {
+        ALOGE("%s: Trying to unregister uid: %d which is not monitored!", __FUNCTION__, uid);
+    }
+}
+
 bool CameraService::UidPolicy::isUidActive(uid_t uid, String16 callingPackage) {
     Mutex::Autolock _l(mUidLock);
     return isUidActiveLocked(uid, callingPackage);
@@ -2491,6 +2764,19 @@
     return active;
 }
 
+int32_t CameraService::UidPolicy::getProcState(uid_t uid) {
+    Mutex::Autolock _l(mUidLock);
+    return getProcStateLocked(uid);
+}
+
+int32_t CameraService::UidPolicy::getProcStateLocked(uid_t uid) {
+    int32_t procState = ActivityManager::PROCESS_STATE_UNKNOWN;
+    if (mMonitoredUids.find(uid) != mMonitoredUids.end()) {
+        procState = mMonitoredUids[uid].first;
+    }
+    return procState;
+}
+
 void CameraService::UidPolicy::UidPolicy::addOverrideUid(uid_t uid,
         String16 callingPackage, bool active) {
     updateOverrideUid(uid, callingPackage, active, true);
@@ -2529,6 +2815,59 @@
 }
 
 // ----------------------------------------------------------------------------
+//                  SensorPrivacyPolicy
+// ----------------------------------------------------------------------------
+void CameraService::SensorPrivacyPolicy::registerSelf() {
+    Mutex::Autolock _l(mSensorPrivacyLock);
+    if (mRegistered) {
+        return;
+    }
+    SensorPrivacyManager spm;
+    spm.addSensorPrivacyListener(this);
+    mSensorPrivacyEnabled = spm.isSensorPrivacyEnabled();
+    status_t res = spm.linkToDeath(this);
+    if (res == OK) {
+        mRegistered = true;
+        ALOGV("SensorPrivacyPolicy: Registered with SensorPrivacyManager");
+    }
+}
+
+void CameraService::SensorPrivacyPolicy::unregisterSelf() {
+    Mutex::Autolock _l(mSensorPrivacyLock);
+    SensorPrivacyManager spm;
+    spm.removeSensorPrivacyListener(this);
+    spm.unlinkToDeath(this);
+    mRegistered = false;
+    ALOGV("SensorPrivacyPolicy: Unregistered with SensorPrivacyManager");
+}
+
+bool CameraService::SensorPrivacyPolicy::isSensorPrivacyEnabled() {
+    Mutex::Autolock _l(mSensorPrivacyLock);
+    return mSensorPrivacyEnabled;
+}
+
+binder::Status CameraService::SensorPrivacyPolicy::onSensorPrivacyChanged(bool enabled) {
+    {
+        Mutex::Autolock _l(mSensorPrivacyLock);
+        mSensorPrivacyEnabled = enabled;
+    }
+    // if sensor privacy is enabled then block all clients from accessing the camera
+    if (enabled) {
+        sp<CameraService> service = mService.promote();
+        if (service != nullptr) {
+            service->blockAllClients();
+        }
+    }
+    return binder::Status::ok();
+}
+
+void CameraService::SensorPrivacyPolicy::binderDied(const wp<IBinder>& /*who*/) {
+    Mutex::Autolock _l(mSensorPrivacyLock);
+    ALOGV("SensorPrivacyPolicy: SensorPrivacyManager has died");
+    mRegistered = false;
+}
+
+// ----------------------------------------------------------------------------
 //                  CameraState
 // ----------------------------------------------------------------------------
 
@@ -2655,8 +2994,12 @@
         const std::set<String8>& conflictingKeys, int32_t score, int32_t ownerId,
         int32_t state) {
 
+    bool isVendorClient = hardware::IPCThreadState::self()->isServingCall();
+    int32_t score_adj = isVendorClient ? kVendorClientScore : score;
+    int32_t state_adj = isVendorClient ? kVendorClientState: state;
+
     return std::make_shared<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>(
-            key, value, cost, conflictingKeys, score, ownerId, state);
+            key, value, cost, conflictingKeys, score_adj, ownerId, state_adj, isVendorClient);
 }
 
 CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
@@ -2689,8 +3032,8 @@
 
     if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
         dprintf(fd, "Permission Denial: can't dump CameraService from pid=%d, uid=%d\n",
-                getCallingPid(),
-                getCallingUid());
+                CameraThreadState::getCallingPid(),
+                CameraThreadState::getCallingUid());
         return NO_ERROR;
     }
     bool locked = tryLock(mServiceLock);
@@ -2863,7 +3206,7 @@
       * binder driver
       */
     // PID here is approximate and can be wrong.
-    logClientDied(getCallingPid(), String8("Binder died unexpectedly"));
+    logClientDied(CameraThreadState::getCallingPid(), String8("Binder died unexpectedly"));
 
     // check torch client
     handleTorchClientBinderDied(who);
@@ -2919,7 +3262,14 @@
             Mutex::Autolock lock(mStatusListenerLock);
 
             for (auto& listener : mListenerList) {
-                listener->onStatusChanged(mapToInterface(status), String16(cameraId));
+                if (!listener.first &&
+                    mCameraProviderManager->isPublicallyHiddenSecureCamera(cameraId.c_str())) {
+                    ALOGV("Skipping camera discovery callback for system-only camera %s",
+                          cameraId.c_str());
+                    continue;
+                }
+                listener.second->getListener()->onStatusChanged(mapToInterface(status),
+                        String16(cameraId));
             }
         });
 }
@@ -3014,6 +3364,18 @@
     }
 }
 
+void CameraService::blockAllClients() {
+    const auto clients = mActiveClientManager.getAll();
+    for (auto& current : clients) {
+        if (current != nullptr) {
+            const auto basicClient = current->getValue();
+            if (basicClient.get() != nullptr) {
+                basicClient->block();
+            }
+        }
+    }
+}
+
 // NOTE: This is a remote API - make sure all args are validated
 status_t CameraService::shellCommand(int in, int out, int err, const Vector<String16>& args) {
     if (!checkCallingPermission(sManageCameraPermission, nullptr, nullptr)) {
@@ -3022,11 +3384,11 @@
     if (in == BAD_TYPE || out == BAD_TYPE || err == BAD_TYPE) {
         return BAD_VALUE;
     }
-    if (args.size() == 3 && args[0] == String16("set-uid-state")) {
+    if (args.size() >= 3 && args[0] == String16("set-uid-state")) {
         return handleSetUidState(args, err);
-    } else if (args.size() == 2 && args[0] == String16("reset-uid-state")) {
+    } else if (args.size() >= 2 && args[0] == String16("reset-uid-state")) {
         return handleResetUidState(args, err);
-    } else if (args.size() == 2 && args[0] == String16("get-uid-state")) {
+    } else if (args.size() >= 2 && args[0] == String16("get-uid-state")) {
         return handleGetUidState(args, out, err);
     } else if (args.size() == 1 && args[0] == String16("help")) {
         printHelp(out);
@@ -3037,13 +3399,8 @@
 }
 
 status_t CameraService::handleSetUidState(const Vector<String16>& args, int err) {
-    PermissionController pc;
-    int uid = pc.getPackageUid(args[1], 0);
-    if (uid <= 0) {
-        ALOGE("Unknown package: '%s'", String8(args[1]).string());
-        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
-        return BAD_VALUE;
-    }
+    String16 packageName = args[1];
+
     bool active = false;
     if (args[2] == String16("active")) {
         active = true;
@@ -3051,31 +3408,52 @@
         ALOGE("Expected active or idle but got: '%s'", String8(args[2]).string());
         return BAD_VALUE;
     }
-    mUidPolicy->addOverrideUid(uid, args[1], active);
+
+    int userId = 0;
+    if (args.size() >= 5 && args[3] == String16("--user")) {
+        userId = atoi(String8(args[4]));
+    }
+
+    uid_t uid;
+    if (getUidForPackage(packageName, userId, uid, err) == BAD_VALUE) {
+        return BAD_VALUE;
+    }
+
+    mUidPolicy->addOverrideUid(uid, packageName, active);
     return NO_ERROR;
 }
 
 status_t CameraService::handleResetUidState(const Vector<String16>& args, int err) {
-    PermissionController pc;
-    int uid = pc.getPackageUid(args[1], 0);
-    if (uid < 0) {
-        ALOGE("Unknown package: '%s'", String8(args[1]).string());
-        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
+    String16 packageName = args[1];
+
+    int userId = 0;
+    if (args.size() >= 4 && args[2] == String16("--user")) {
+        userId = atoi(String8(args[3]));
+    }
+
+    uid_t uid;
+    if (getUidForPackage(packageName, userId, uid, err) == BAD_VALUE) {
         return BAD_VALUE;
     }
-    mUidPolicy->removeOverrideUid(uid, args[1]);
+
+    mUidPolicy->removeOverrideUid(uid, packageName);
     return NO_ERROR;
 }
 
 status_t CameraService::handleGetUidState(const Vector<String16>& args, int out, int err) {
-    PermissionController pc;
-    int uid = pc.getPackageUid(args[1], 0);
-    if (uid <= 0) {
-        ALOGE("Unknown package: '%s'", String8(args[1]).string());
-        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
+    String16 packageName = args[1];
+
+    int userId = 0;
+    if (args.size() >= 4 && args[2] == String16("--user")) {
+        userId = atoi(String8(args[3]));
+    }
+
+    uid_t uid;
+    if (getUidForPackage(packageName, userId, uid, err) == BAD_VALUE) {
         return BAD_VALUE;
     }
-    if (mUidPolicy->isUidActive(uid, args[1])) {
+
+    if (mUidPolicy->isUidActive(uid, packageName)) {
         return dprintf(out, "active\n");
     } else {
         return dprintf(out, "idle\n");
@@ -3084,9 +3462,9 @@
 
 status_t CameraService::printHelp(int out) {
     return dprintf(out, "Camera service commands:\n"
-        "  get-uid-state <PACKAGE> gets the uid state\n"
-        "  set-uid-state <PACKAGE> <active|idle> overrides the uid state\n"
-        "  reset-uid-state <PACKAGE> clears the uid state override\n"
+        "  get-uid-state <PACKAGE> [--user USER_ID] gets the uid state\n"
+        "  set-uid-state <PACKAGE> <active|idle> [--user USER_ID] overrides the uid state\n"
+        "  reset-uid-state <PACKAGE> [--user USER_ID] clears the uid state override\n"
         "  help print this message\n");
 }
 
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 8d4bcdb..065157d 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -18,6 +18,7 @@
 #define ANDROID_SERVERS_CAMERA_CAMERASERVICE_H
 
 #include <android/hardware/BnCameraService.h>
+#include <android/hardware/BnSensorPrivacyListener.h>
 #include <android/hardware/ICameraServiceListener.h>
 #include <android/hardware/ICameraServiceProxy.h>
 
@@ -153,12 +154,19 @@
     virtual binder::Status    notifySystemEvent(int32_t eventId,
             const std::vector<int32_t>& args);
 
+    virtual binder::Status    notifyDeviceStateChange(int64_t newState);
+
     // OK = supports api of that version, -EOPNOTSUPP = does not support
     virtual binder::Status    supportsCameraApi(
             const String16& cameraId, int32_t apiVersion,
             /*out*/
             bool *isSupported);
 
+    virtual binder::Status    isHiddenPhysicalCamera(
+            const String16& cameraId,
+            /*out*/
+            bool *isSupported);
+
     // Extra permissions checks
     virtual status_t    onTransact(uint32_t code, const Parcel& data,
                                    Parcel* reply, uint32_t flags);
@@ -167,6 +175,13 @@
 
     virtual status_t    shellCommand(int in, int out, int err, const Vector<String16>& args);
 
+    binder::Status      addListenerHelper(const sp<hardware::ICameraServiceListener>& listener,
+            /*out*/
+            std::vector<hardware::CameraStatus>* cameraStatuses, bool isVendor = false);
+
+    // Monitored UIDs availability notification
+    void                notifyMonitoredUids();
+
     /////////////////////////////////////////////////////////////////////
     // Client functionality
 
@@ -177,10 +192,10 @@
         NUM_SOUNDS
     };
 
-    void                loadSound();
     void                playSound(sound_kind kind);
-    void                releaseSound();
-
+    void                loadSoundLocked(sound_kind kind);
+    void                decreaseSoundRef();
+    void                increaseSoundRef();
     /**
      * Update the state of a given camera device (open/close/active/idle) with
      * the camera proxy service in the system service
@@ -278,7 +293,7 @@
         status_t                        finishCameraOps();
 
     private:
-        AppOpsManager                   mAppOpsManager;
+        std::unique_ptr<AppOpsManager>  mAppOpsManager = nullptr;
 
         class OpsCallback : public BnAppOpsCallback {
         public:
@@ -527,29 +542,64 @@
         void unregisterSelf();
 
         bool isUidActive(uid_t uid, String16 callingPackage);
+        int32_t getProcState(uid_t uid);
 
         void onUidGone(uid_t uid, bool disabled);
         void onUidActive(uid_t uid);
         void onUidIdle(uid_t uid, bool disabled);
+        void onUidStateChanged(uid_t uid, int32_t procState, int64_t procStateSeq);
 
         void addOverrideUid(uid_t uid, String16 callingPackage, bool active);
         void removeOverrideUid(uid_t uid, String16 callingPackage);
 
+        void registerMonitorUid(uid_t uid);
+        void unregisterMonitorUid(uid_t uid);
+
         // IBinder::DeathRecipient implementation
         virtual void binderDied(const wp<IBinder> &who);
     private:
         bool isUidActiveLocked(uid_t uid, String16 callingPackage);
+        int32_t getProcStateLocked(uid_t uid);
         void updateOverrideUid(uid_t uid, String16 callingPackage, bool active, bool insert);
 
         Mutex mUidLock;
         bool mRegistered;
         wp<CameraService> mService;
         std::unordered_set<uid_t> mActiveUids;
+        // Monitored uid map to cached procState and refCount pair
+        std::unordered_map<uid_t, std::pair<int32_t, size_t>> mMonitoredUids;
         std::unordered_map<uid_t, bool> mOverrideUids;
     }; // class UidPolicy
 
+    // If sensor privacy is enabled then all apps, including those that are active, should be
+    // prevented from accessing the camera.
+    class SensorPrivacyPolicy : public hardware::BnSensorPrivacyListener,
+            public virtual IBinder::DeathRecipient {
+        public:
+            explicit SensorPrivacyPolicy(wp<CameraService> service)
+                    : mService(service), mSensorPrivacyEnabled(false), mRegistered(false) {}
+
+            void registerSelf();
+            void unregisterSelf();
+
+            bool isSensorPrivacyEnabled();
+
+            binder::Status onSensorPrivacyChanged(bool enabled);
+
+            // IBinder::DeathRecipient implementation
+            virtual void binderDied(const wp<IBinder> &who);
+
+        private:
+            wp<CameraService> mService;
+            Mutex mSensorPrivacyLock;
+            bool mSensorPrivacyEnabled;
+            bool mRegistered;
+    };
+
     sp<UidPolicy> mUidPolicy;
 
+    sp<SensorPrivacyPolicy> mSensorPrivacyPolicy;
+
     // Delay-load the Camera HAL module
     virtual void onFirstRef();
 
@@ -581,12 +631,15 @@
         sp<BasicClient>* client,
         std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial);
 
+    // Should an operation attempt on a cameraId be rejected, if the camera id is
+    // advertised as a publically hidden secure camera, by the camera HAL ?
+    bool shouldRejectHiddenCameraConnection(const String8 & cameraId);
+
     // Single implementation shared between the various connect calls
     template<class CALLBACK, class CLIENT>
     binder::Status connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
             int api1CameraId, int halVersion, const String16& clientPackageName,
-            int clientUid, int clientPid,
-            apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly,
+            int clientUid, int clientPid, apiLevel effectiveApiLevel, bool shimUpdateOnly,
             /*out*/sp<CLIENT>& device);
 
     // Lock guarding camera service state
@@ -695,6 +748,11 @@
             const char* reason);
 
     /**
+     * Add an event log message when a client calls setTorchMode succesfully.
+     */
+    void logTorchEvent(const char* cameraId, const char *torchState, int clientPid);
+
+    /**
      * Add an event log message that the current device user has been switched.
      */
     void logUserSwitch(const std::set<userid_t>& oldUserIds,
@@ -747,8 +805,34 @@
 
     sp<CameraProviderManager> mCameraProviderManager;
 
+    class ServiceListener : public virtual IBinder::DeathRecipient {
+        public:
+            ServiceListener(sp<CameraService> parent, sp<hardware::ICameraServiceListener> listener,
+                    int uid) : mParent(parent), mListener(listener), mListenerUid(uid) {}
+
+            status_t initialize() {
+                return IInterface::asBinder(mListener)->linkToDeath(this);
+            }
+
+            virtual void binderDied(const wp<IBinder> &/*who*/) {
+                auto parent = mParent.promote();
+                if (parent.get() != nullptr) {
+                    parent->removeListener(mListener);
+                }
+            }
+
+            int getListenerUid() { return mListenerUid; }
+            sp<hardware::ICameraServiceListener> getListener() { return mListener; }
+
+        private:
+            wp<CameraService> mParent;
+            sp<hardware::ICameraServiceListener> mListener;
+            int mListenerUid;
+    };
+
     // Guarded by mStatusListenerMutex
-    std::vector<sp<hardware::ICameraServiceListener>> mListenerList;
+    std::vector<std::pair<bool, sp<ServiceListener>>> mListenerList;
+
     Mutex       mStatusListenerLock;
 
     /**
@@ -820,6 +904,9 @@
     // Blocks all clients from the UID
     void blockClientsForUid(uid_t uid);
 
+    // Blocks all active clients.
+    void blockAllClients();
+
     // Overrides the UID state as if it is idle
     status_t handleSetUidState(const Vector<String16>& args, int err);
 
@@ -832,10 +919,6 @@
     // Prints the shell command help
     status_t printHelp(int out);
 
-    static int getCallingPid();
-
-    static int getCallingUid();
-
     /**
      * Get the current system time as a formatted string.
      */
@@ -844,7 +927,7 @@
     static binder::Status makeClient(const sp<CameraService>& cameraService,
             const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
             int api1CameraId, int facing, int clientPid, uid_t clientUid, int servicePid,
-            bool legacyMode, int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
+            int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
             /*out*/sp<BasicClient>* client);
 
     status_t checkCameraAccess(const String16& opPackageName);
@@ -854,9 +937,16 @@
     static StatusInternal mapToInternal(hardware::camera::common::V1_0::CameraDeviceStatus status);
     static int32_t mapToInterface(StatusInternal status);
 
+    // Guard mCameraServiceProxy
+    static Mutex sProxyMutex;
+    // Cached interface to the camera service proxy in system service
+    static sp<hardware::ICameraServiceProxy> sCameraServiceProxy;
+
     static sp<hardware::ICameraServiceProxy> getCameraServiceProxy();
     static void pingCameraServiceProxy();
 
+    void broadcastTorchModeStatus(const String8& cameraId,
+            hardware::camera::common::V1_0::TorchModeStatus status);
 };
 
 } // namespace android
diff --git a/services/camera/libcameraservice/TEST_MAPPING b/services/camera/libcameraservice/TEST_MAPPING
new file mode 100644
index 0000000..6fdac68
--- /dev/null
+++ b/services/camera/libcameraservice/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+       "name": "cameraservice_test"
+    }
+  ]
+}
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index d59b313..162b50f 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -33,17 +33,18 @@
 #include "api1/client2/CaptureSequencer.h"
 #include "api1/client2/CallbackProcessor.h"
 #include "api1/client2/ZslProcessor.h"
+#include "utils/CameraThreadState.h"
 
 #define ALOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
 #define ALOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
 
+#ifndef FALLTHROUGH_INTENDED
+#define FALLTHROUGH_INTENDED [[fallthrough]]
+#endif
+
 namespace android {
 using namespace camera2;
 
-static int getCallingPid() {
-    return IPCThreadState::self()->getCallingPid();
-}
-
 // Interface used by CameraService
 
 Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
@@ -54,8 +55,7 @@
         int cameraFacing,
         int clientPid,
         uid_t clientUid,
-        int servicePid,
-        bool legacyMode):
+        int servicePid):
         Camera2ClientBase(cameraService, cameraClient, clientPackageName,
                 cameraDeviceId, api1CameraId, cameraFacing,
                 clientPid, clientUid, servicePid),
@@ -65,8 +65,6 @@
 
     SharedParameters::Lock l(mParameters);
     l.mParameters.state = Parameters::DISCONNECTED;
-
-    mLegacyMode = legacyMode;
 }
 
 status_t Camera2Client::initialize(sp<CameraProviderManager> manager, const String8& monitorTags) {
@@ -401,7 +399,7 @@
 
     binder::Status res = binder::Status::ok();
     // Allow both client and the cameraserver to disconnect at all times
-    int callingPid = getCallingPid();
+    int callingPid = CameraThreadState::getCallingPid();
     if (callingPid != mClientPid && callingPid != mServicePid) return res;
 
     if (mDevice == 0) return res;
@@ -456,8 +454,6 @@
 
     mDevice->disconnect();
 
-    mDevice.clear();
-
     CameraService::Client::disconnect();
 
     return res;
@@ -468,14 +464,14 @@
     ALOGV("%s: E", __FUNCTION__);
     Mutex::Autolock icl(mBinderSerializationLock);
 
-    if (mClientPid != 0 && getCallingPid() != mClientPid) {
+    if (mClientPid != 0 && CameraThreadState::getCallingPid() != mClientPid) {
         ALOGE("%s: Camera %d: Connection attempt from pid %d; "
                 "current locked to pid %d", __FUNCTION__,
-                mCameraId, getCallingPid(), mClientPid);
+                mCameraId, CameraThreadState::getCallingPid(), mClientPid);
         return BAD_VALUE;
     }
 
-    mClientPid = getCallingPid();
+    mClientPid = CameraThreadState::getCallingPid();
 
     mRemoteCallback = client;
     mSharedCameraCallbacks = client;
@@ -488,16 +484,16 @@
     ALOGV("%s: E", __FUNCTION__);
     Mutex::Autolock icl(mBinderSerializationLock);
     ALOGV("%s: Camera %d: Lock call from pid %d; current client pid %d",
-            __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
+            __FUNCTION__, mCameraId, CameraThreadState::getCallingPid(), mClientPid);
 
     if (mClientPid == 0) {
-        mClientPid = getCallingPid();
+        mClientPid = CameraThreadState::getCallingPid();
         return OK;
     }
 
-    if (mClientPid != getCallingPid()) {
+    if (mClientPid != CameraThreadState::getCallingPid()) {
         ALOGE("%s: Camera %d: Lock call from pid %d; currently locked to pid %d",
-                __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
+                __FUNCTION__, mCameraId, CameraThreadState::getCallingPid(), mClientPid);
         return EBUSY;
     }
 
@@ -509,9 +505,9 @@
     ALOGV("%s: E", __FUNCTION__);
     Mutex::Autolock icl(mBinderSerializationLock);
     ALOGV("%s: Camera %d: Unlock call from pid %d; current client pid %d",
-            __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
+            __FUNCTION__, mCameraId, CameraThreadState::getCallingPid(), mClientPid);
 
-    if (mClientPid == getCallingPid()) {
+    if (mClientPid == CameraThreadState::getCallingPid()) {
         SharedParameters::Lock l(mParameters);
         if (l.mParameters.state == Parameters::RECORD ||
                 l.mParameters.state == Parameters::VIDEO_SNAPSHOT) {
@@ -525,7 +521,7 @@
     }
 
     ALOGE("%s: Camera %d: Unlock call from pid %d; currently locked to pid %d",
-            __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
+            __FUNCTION__, mCameraId, CameraThreadState::getCallingPid(), mClientPid);
     return EBUSY;
 }
 
@@ -780,33 +776,35 @@
     int lastJpegStreamId = mJpegProcessor->getStreamId();
     // If jpeg stream will slow down preview, make sure we remove it before starting preview
     if (params.slowJpegMode) {
-        // Pause preview if we are streaming
-        int32_t activeRequestId = mStreamingProcessor->getActiveRequestId();
-        if (activeRequestId != 0) {
-            res = mStreamingProcessor->togglePauseStream(/*pause*/true);
-            if (res != OK) {
-                ALOGE("%s: Camera %d: Can't pause streaming: %s (%d)",
-                        __FUNCTION__, mCameraId, strerror(-res), res);
+        if (lastJpegStreamId != NO_STREAM) {
+            // Pause preview if we are streaming
+            int32_t activeRequestId = mStreamingProcessor->getActiveRequestId();
+            if (activeRequestId != 0) {
+                res = mStreamingProcessor->togglePauseStream(/*pause*/true);
+                if (res != OK) {
+                    ALOGE("%s: Camera %d: Can't pause streaming: %s (%d)",
+                            __FUNCTION__, mCameraId, strerror(-res), res);
+                }
+                res = mDevice->waitUntilDrained();
+                if (res != OK) {
+                    ALOGE("%s: Camera %d: Waiting to stop streaming failed: %s (%d)",
+                            __FUNCTION__, mCameraId, strerror(-res), res);
+                }
             }
-            res = mDevice->waitUntilDrained();
+
+            res = mJpegProcessor->deleteStream();
+
             if (res != OK) {
-                ALOGE("%s: Camera %d: Waiting to stop streaming failed: %s (%d)",
-                        __FUNCTION__, mCameraId, strerror(-res), res);
+                ALOGE("%s: Camera %d: delete Jpeg stream failed: %s (%d)",
+                        __FUNCTION__, mCameraId,  strerror(-res), res);
             }
-        }
 
-        res = mJpegProcessor->deleteStream();
-
-        if (res != OK) {
-            ALOGE("%s: Camera %d: delete Jpeg stream failed: %s (%d)",
-                    __FUNCTION__, mCameraId,  strerror(-res), res);
-        }
-
-        if (activeRequestId != 0) {
-            res = mStreamingProcessor->togglePauseStream(/*pause*/false);
-            if (res != OK) {
-                ALOGE("%s: Camera %d: Can't unpause streaming: %s (%d)",
-                        __FUNCTION__, mCameraId, strerror(-res), res);
+            if (activeRequestId != 0) {
+                res = mStreamingProcessor->togglePauseStream(/*pause*/false);
+                if (res != OK) {
+                    ALOGE("%s: Camera %d: Can't unpause streaming: %s (%d)",
+                            __FUNCTION__, mCameraId, strerror(-res), res);
+                }
             }
         }
     } else {
@@ -957,7 +955,7 @@
         case Parameters::VIDEO_SNAPSHOT:
         case Parameters::STILL_CAPTURE:
             mCaptureSequencer->waitUntilIdle(kStopCaptureTimeout);
-            // no break
+            FALLTHROUGH_INTENDED;
         case Parameters::RECORD:
         case Parameters::PREVIEW:
             syncWithDevice();
@@ -987,7 +985,7 @@
                         "stop preview: %s (%d)",
                         __FUNCTION__, mCameraId, strerror(-res), res);
             }
-            // no break
+            FALLTHROUGH_INTENDED;
         case Parameters::WAITING_FOR_PREVIEW_WINDOW: {
             SharedParameters::Lock l(mParameters);
             l.mParameters.state = Parameters::STOPPED;
@@ -1441,13 +1439,14 @@
     return OK;
 }
 
-status_t Camera2Client::takePicture(int msgType) {
+status_t Camera2Client::takePicture(int /*msgType*/) {
     ATRACE_CALL();
     Mutex::Autolock icl(mBinderSerializationLock);
     status_t res;
     if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
 
     int takePictureCounter;
+    bool shouldSyncWithDevice = true;
     {
         SharedParameters::Lock l(mParameters);
         switch (l.mParameters.state) {
@@ -1533,14 +1532,25 @@
                     __FUNCTION__, mCameraId);
             mZslProcessor->clearZslQueue();
         }
+
+        // We should always sync with the device in case flash is turned on,
+        // the camera device suggests that flash is needed (AE state FLASH_REQUIRED)
+        // or we are in some other AE state different from CONVERGED that may need
+        // precapture trigger.
+        if (l.mParameters.flashMode != Parameters::FLASH_MODE_ON &&
+                (l.mParameters.aeState == ANDROID_CONTROL_AE_STATE_CONVERGED)) {
+            shouldSyncWithDevice  = false;
+        }
     }
 
     ATRACE_ASYNC_BEGIN(kTakepictureLabel, takePictureCounter);
 
-    // Need HAL to have correct settings before (possibly) triggering precapture
-    syncWithDevice();
+    // Make sure HAL has correct settings in case precapture trigger is needed.
+    if (shouldSyncWithDevice) {
+        syncWithDevice();
+    }
 
-    res = mCaptureSequencer->startCapture(msgType);
+    res = mCaptureSequencer->startCapture();
     if (res != OK) {
         ALOGE("%s: Camera %d: Unable to start capture: %s (%d)",
                 __FUNCTION__, mCameraId, strerror(-res), res);
@@ -1577,7 +1587,7 @@
     ALOGV("%s: Camera %d", __FUNCTION__, mCameraId);
     Mutex::Autolock icl(mBinderSerializationLock);
     // The camera service can unconditionally get the parameters at all times
-    if (getCallingPid() != mServicePid && checkPid(__FUNCTION__) != OK) return String8();
+    if (CameraThreadState::getCallingPid() != mServicePid && checkPid(__FUNCTION__) != OK) return String8();
 
     SharedParameters::ReadLock l(mParameters);
 
@@ -1660,27 +1670,6 @@
         return OK;
     }
 
-    // the camera2 api legacy mode can unconditionally disable the shutter sound
-    if (mLegacyMode) {
-        ALOGV("%s: Disable shutter sound in legacy mode", __FUNCTION__);
-        l.mParameters.playShutterSound = false;
-        return OK;
-    }
-
-    // Disabling shutter sound may not be allowed. In that case only
-    // allow the mediaserver process to disable the sound.
-    char value[PROPERTY_VALUE_MAX];
-    property_get("ro.camera.sound.forced", value, "0");
-    if (strncmp(value, "0", 2) != 0) {
-        // Disabling shutter sound is not allowed. Deny if the current
-        // process is not mediaserver.
-        if (getCallingPid() != getpid()) {
-            ALOGE("Failed to disable shutter sound. Permission denied (pid %d)",
-                    getCallingPid());
-            return PERMISSION_DENIED;
-        }
-    }
-
     l.mParameters.playShutterSound = false;
     return OK;
 }
@@ -1778,6 +1767,7 @@
         case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER:
             ALOGW("%s: Received recoverable error %d from HAL - ignoring, requestId %" PRId32,
                     __FUNCTION__, errorCode, resultExtras.requestId);
+            mCaptureSequencer->notifyError(errorCode, resultExtras);
             return;
         default:
             err = CAMERA_ERROR_UNKNOWN;
@@ -1833,7 +1823,7 @@
                 switch (newState) {
                     case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
                         success = true;
-                        // no break
+                        FALLTHROUGH_INTENDED;
                     case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
                         sendCompletedMessage = true;
                         l.mParameters.currentAfTriggerId = -1;
@@ -1857,7 +1847,7 @@
                 switch (newState) {
                     case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
                         success = true;
-                        // no break
+                        FALLTHROUGH_INTENDED;
                     case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
                         // Don't send notifications upstream if they're not for
                         // the current AF trigger. For example, if cancel was
@@ -1885,7 +1875,7 @@
                     case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
                         // Start passive scan, inform upstream
                         afInMotion = true;
-                        // no break
+                        FALLTHROUGH_INTENDED;
                     case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
                     case ANDROID_CONTROL_AF_STATE_PASSIVE_UNFOCUSED:
                         // Stop passive scan, inform upstream
@@ -1928,14 +1918,16 @@
 void Camera2Client::notifyAutoExposure(uint8_t newState, int triggerId) {
     ALOGV("%s: Autoexposure state now %d, last trigger %d",
             __FUNCTION__, newState, triggerId);
+    {
+        SharedParameters::Lock l(mParameters);
+        // Update state
+        l.mParameters.aeState = newState;
+    }
     mCaptureSequencer->notifyAutoExposure(newState, triggerId);
 }
 
 void Camera2Client::notifyShutter(const CaptureResultExtras& resultExtras,
                                   nsecs_t timestamp) {
-    (void)resultExtras;
-    (void)timestamp;
-
     ALOGV("%s: Shutter notification for request id %" PRId32 " at time %" PRId64,
             __FUNCTION__, resultExtras.requestId, timestamp);
     mCaptureSequencer->notifyShutter(resultExtras, timestamp);
diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h
index 44929c3..a9ea271 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.h
+++ b/services/camera/libcameraservice/api1/Camera2Client.h
@@ -96,8 +96,7 @@
             int cameraFacing,
             int clientPid,
             uid_t clientUid,
-            int servicePid,
-            bool legacyMode);
+            int servicePid);
 
     virtual ~Camera2Client();
 
diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp
index f1203f9..d65ac7b 100644
--- a/services/camera/libcameraservice/api1/CameraClient.cpp
+++ b/services/camera/libcameraservice/api1/CameraClient.cpp
@@ -25,27 +25,24 @@
 #include "api1/CameraClient.h"
 #include "device1/CameraHardwareInterface.h"
 #include "CameraService.h"
+#include "utils/CameraThreadState.h"
 
 namespace android {
 
 #define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
 #define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
 
-static int getCallingPid() {
-    return IPCThreadState::self()->getCallingPid();
-}
-
 CameraClient::CameraClient(const sp<CameraService>& cameraService,
         const sp<hardware::ICameraClient>& cameraClient,
         const String16& clientPackageName,
         int cameraId, int cameraFacing,
         int clientPid, int clientUid,
-        int servicePid, bool legacyMode):
+        int servicePid):
         Client(cameraService, cameraClient, clientPackageName,
                 String8::format("%d", cameraId), cameraId, cameraFacing, clientPid,
                 clientUid, servicePid)
 {
-    int callingPid = getCallingPid();
+    int callingPid = CameraThreadState::getCallingPid();
     LOG1("CameraClient::CameraClient E (pid %d, id %d)", callingPid, cameraId);
 
     mHardware = NULL;
@@ -57,14 +54,13 @@
     // Callback is disabled by default
     mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
     mOrientation = getOrientation(0, mCameraFacing == CAMERA_FACING_FRONT);
-    mLegacyMode = legacyMode;
     mPlayShutterSound = true;
     LOG1("CameraClient::CameraClient X (pid %d, id %d)", callingPid, cameraId);
 }
 
 status_t CameraClient::initialize(sp<CameraProviderManager> manager,
         const String8& /*monitorTags*/) {
-    int callingPid = getCallingPid();
+    int callingPid = CameraThreadState::getCallingPid();
     status_t res;
 
     LOG1("CameraClient::initialize E (pid %d, id %d)", callingPid, mCameraId);
@@ -105,7 +101,7 @@
 // tear down the client
 CameraClient::~CameraClient() {
     mDestructionStarted = true;
-    int callingPid = getCallingPid();
+    int callingPid = CameraThreadState::getCallingPid();
     LOG1("CameraClient::~CameraClient E (pid %d, this %p)", callingPid, this);
 
     disconnect();
@@ -148,7 +144,7 @@
 // ----------------------------------------------------------------------------
 
 status_t CameraClient::checkPid() const {
-    int callingPid = getCallingPid();
+    int callingPid = CameraThreadState::getCallingPid();
     if (callingPid == mClientPid) return NO_ERROR;
 
     ALOGW("attempt to use a locked camera from a different process"
@@ -158,7 +154,8 @@
 
 status_t CameraClient::checkPidAndHardware() const {
     if (mHardware == 0) {
-        ALOGE("attempt to use a camera after disconnect() (pid %d)", getCallingPid());
+        ALOGE("attempt to use a camera after disconnect() (pid %d)",
+              CameraThreadState::getCallingPid());
         return INVALID_OPERATION;
     }
     status_t result = checkPid();
@@ -167,7 +164,7 @@
 }
 
 status_t CameraClient::lock() {
-    int callingPid = getCallingPid();
+    int callingPid = CameraThreadState::getCallingPid();
     LOG1("lock (pid %d)", callingPid);
     Mutex::Autolock lock(mLock);
 
@@ -182,7 +179,7 @@
 }
 
 status_t CameraClient::unlock() {
-    int callingPid = getCallingPid();
+    int callingPid = CameraThreadState::getCallingPid();
     LOG1("unlock (pid %d)", callingPid);
     Mutex::Autolock lock(mLock);
 
@@ -204,7 +201,7 @@
 
 // connect a new client to the camera
 status_t CameraClient::connect(const sp<hardware::ICameraClient>& client) {
-    int callingPid = getCallingPid();
+    int callingPid = CameraThreadState::getCallingPid();
     LOG1("connect E (pid %d)", callingPid);
     Mutex::Autolock lock(mLock);
 
@@ -240,7 +237,7 @@
 }
 
 binder::Status CameraClient::disconnect() {
-    int callingPid = getCallingPid();
+    int callingPid = CameraThreadState::getCallingPid();
     LOG1("disconnect E (pid %d)", callingPid);
     Mutex::Autolock lock(mLock);
 
@@ -334,7 +331,7 @@
 status_t CameraClient::setPreviewTarget(
         const sp<IGraphicBufferProducer>& bufferProducer) {
     LOG1("setPreviewTarget(%p) (pid %d)", bufferProducer.get(),
-            getCallingPid());
+            CameraThreadState::getCallingPid());
 
     sp<IBinder> binder;
     sp<ANativeWindow> window;
@@ -351,7 +348,7 @@
 // set the preview callback flag to affect how the received frames from
 // preview are handled.
 void CameraClient::setPreviewCallbackFlag(int callback_flag) {
-    LOG1("setPreviewCallbackFlag(%d) (pid %d)", callback_flag, getCallingPid());
+    LOG1("setPreviewCallbackFlag(%d) (pid %d)", callback_flag, CameraThreadState::getCallingPid());
     Mutex::Autolock lock(mLock);
     if (checkPidAndHardware() != NO_ERROR) return;
 
@@ -372,13 +369,13 @@
 
 // start preview mode
 status_t CameraClient::startPreview() {
-    LOG1("startPreview (pid %d)", getCallingPid());
+    LOG1("startPreview (pid %d)", CameraThreadState::getCallingPid());
     return startCameraMode(CAMERA_PREVIEW_MODE);
 }
 
 // start recording mode
 status_t CameraClient::startRecording() {
-    LOG1("startRecording (pid %d)", getCallingPid());
+    LOG1("startRecording (pid %d)", CameraThreadState::getCallingPid());
     return startCameraMode(CAMERA_RECORDING_MODE);
 }
 
@@ -461,7 +458,7 @@
 
 // stop preview mode
 void CameraClient::stopPreview() {
-    LOG1("stopPreview (pid %d)", getCallingPid());
+    LOG1("stopPreview (pid %d)", CameraThreadState::getCallingPid());
     Mutex::Autolock lock(mLock);
     if (checkPidAndHardware() != NO_ERROR) return;
 
@@ -477,7 +474,7 @@
 
 // stop recording mode
 void CameraClient::stopRecording() {
-    LOG1("stopRecording (pid %d)", getCallingPid());
+    LOG1("stopRecording (pid %d)", CameraThreadState::getCallingPid());
     {
         Mutex::Autolock lock(mLock);
         if (checkPidAndHardware() != NO_ERROR) return;
@@ -503,7 +500,7 @@
     if (checkPidAndHardware() != NO_ERROR) return;
     if (mem == nullptr) {
         android_errorWriteWithInfoLog(CameraService::SN_EVENT_LOG_ID, "26164272",
-                IPCThreadState::self()->getCallingUid(), nullptr, 0);
+                CameraThreadState::getCallingUid(), nullptr, 0);
         return;
     }
 
@@ -615,7 +612,7 @@
 }
 
 bool CameraClient::previewEnabled() {
-    LOG1("previewEnabled (pid %d)", getCallingPid());
+    LOG1("previewEnabled (pid %d)", CameraThreadState::getCallingPid());
 
     Mutex::Autolock lock(mLock);
     if (checkPidAndHardware() != NO_ERROR) return false;
@@ -623,7 +620,7 @@
 }
 
 bool CameraClient::recordingEnabled() {
-    LOG1("recordingEnabled (pid %d)", getCallingPid());
+    LOG1("recordingEnabled (pid %d)", CameraThreadState::getCallingPid());
 
     Mutex::Autolock lock(mLock);
     if (checkPidAndHardware() != NO_ERROR) return false;
@@ -631,7 +628,7 @@
 }
 
 status_t CameraClient::autoFocus() {
-    LOG1("autoFocus (pid %d)", getCallingPid());
+    LOG1("autoFocus (pid %d)", CameraThreadState::getCallingPid());
 
     Mutex::Autolock lock(mLock);
     status_t result = checkPidAndHardware();
@@ -641,7 +638,7 @@
 }
 
 status_t CameraClient::cancelAutoFocus() {
-    LOG1("cancelAutoFocus (pid %d)", getCallingPid());
+    LOG1("cancelAutoFocus (pid %d)", CameraThreadState::getCallingPid());
 
     Mutex::Autolock lock(mLock);
     status_t result = checkPidAndHardware();
@@ -652,7 +649,7 @@
 
 // take a picture - image is returned in callback
 status_t CameraClient::takePicture(int msgType) {
-    LOG1("takePicture (pid %d): 0x%x", getCallingPid(), msgType);
+    LOG1("takePicture (pid %d): 0x%x", CameraThreadState::getCallingPid(), msgType);
 
     Mutex::Autolock lock(mLock);
     status_t result = checkPidAndHardware();
@@ -681,7 +678,7 @@
 
 // set preview/capture parameters - key/value pairs
 status_t CameraClient::setParameters(const String8& params) {
-    LOG1("setParameters (pid %d) (%s)", getCallingPid(), params.string());
+    LOG1("setParameters (pid %d) (%s)", CameraThreadState::getCallingPid(), params.string());
 
     Mutex::Autolock lock(mLock);
     status_t result = checkPidAndHardware();
@@ -696,16 +693,18 @@
 String8 CameraClient::getParameters() const {
     Mutex::Autolock lock(mLock);
     // The camera service can unconditionally get the parameters at all times
-    if (getCallingPid() != mServicePid && checkPidAndHardware() != NO_ERROR) return String8();
+    if (CameraThreadState::getCallingPid() != mServicePid && checkPidAndHardware() != NO_ERROR) {
+        return String8();
+    }
 
     String8 params(mHardware->getParameters().flatten());
-    LOG1("getParameters (pid %d) (%s)", getCallingPid(), params.string());
+    LOG1("getParameters (pid %d) (%s)", CameraThreadState::getCallingPid(), params.string());
     return params;
 }
 
 // enable shutter sound
 status_t CameraClient::enableShutterSound(bool enable) {
-    LOG1("enableShutterSound (pid %d)", getCallingPid());
+    LOG1("enableShutterSound (pid %d)", CameraThreadState::getCallingPid());
 
     status_t result = checkPidAndHardware();
     if (result != NO_ERROR) return result;
@@ -715,32 +714,12 @@
         return OK;
     }
 
-    // the camera2 api legacy mode can unconditionally disable the shutter sound
-    if (mLegacyMode) {
-        ALOGV("%s: Disable shutter sound in legacy mode", __FUNCTION__);
-        mPlayShutterSound = false;
-        return OK;
-    }
-
-    // Disabling shutter sound may not be allowed. In that case only
-    // allow the mediaserver process to disable the sound.
-    char value[PROPERTY_VALUE_MAX];
-    property_get("ro.camera.sound.forced", value, "0");
-    if (strcmp(value, "0") != 0) {
-        // Disabling shutter sound is not allowed. Deny if the current
-        // process is not mediaserver.
-        if (getCallingPid() != getpid()) {
-            ALOGE("Failed to disable shutter sound. Permission denied (pid %d)", getCallingPid());
-            return PERMISSION_DENIED;
-        }
-    }
-
     mPlayShutterSound = false;
     return OK;
 }
 
 status_t CameraClient::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
-    LOG1("sendCommand (pid %d)", getCallingPid());
+    LOG1("sendCommand (pid %d)", CameraThreadState::getCallingPid());
     int orientation;
     Mutex::Autolock lock(mLock);
     status_t result = checkPidAndHardware();
diff --git a/services/camera/libcameraservice/api1/CameraClient.h b/services/camera/libcameraservice/api1/CameraClient.h
index 1910536..9530b6c 100644
--- a/services/camera/libcameraservice/api1/CameraClient.h
+++ b/services/camera/libcameraservice/api1/CameraClient.h
@@ -68,8 +68,7 @@
             int cameraFacing,
             int clientPid,
             int clientUid,
-            int servicePid,
-            bool legacyMode = false);
+            int servicePid);
     ~CameraClient();
 
     virtual status_t initialize(sp<CameraProviderManager> manager,
diff --git a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
index a9b2e75..88799f9 100644
--- a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
+++ b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
@@ -50,8 +50,7 @@
         mStateTransitionCount(0),
         mTriggerId(0),
         mTimeoutCount(0),
-        mCaptureId(Camera2Client::kCaptureRequestIdStart),
-        mMsgType(0) {
+        mCaptureId(Camera2Client::kCaptureRequestIdStart) {
     ALOGV("%s", __FUNCTION__);
 }
 
@@ -64,7 +63,7 @@
     mZslProcessor = processor;
 }
 
-status_t CaptureSequencer::startCapture(int msgType) {
+status_t CaptureSequencer::startCapture() {
     ALOGV("%s", __FUNCTION__);
     ATRACE_CALL();
     Mutex::Autolock l(mInputMutex);
@@ -73,7 +72,6 @@
         return INVALID_OPERATION;
     }
     if (!mStartCapture) {
-        mMsgType = msgType;
         mStartCapture = true;
         mStartCaptureSignal.signal();
     }
@@ -119,6 +117,31 @@
     }
 }
 
+void CaptureSequencer::notifyError(int32_t errorCode, const CaptureResultExtras& resultExtras) {
+    ATRACE_CALL();
+    bool jpegBufferLost = false;
+    if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
+        sp<Camera2Client> client = mClient.promote();
+        if (client == nullptr) {
+            return;
+        }
+        int captureStreamId = client->getCaptureStreamId();
+        if (captureStreamId == resultExtras.errorStreamId) {
+            jpegBufferLost = true;
+        }
+    } else if (errorCode ==
+            hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST) {
+        if (resultExtras.requestId == mShutterCaptureId) {
+            jpegBufferLost = true;
+        }
+    }
+
+    if (jpegBufferLost) {
+        sp<MemoryBase> emptyBuffer;
+        onCaptureAvailable(/*timestamp*/0, emptyBuffer, /*captureError*/true);
+    }
+}
+
 void CaptureSequencer::onResultAvailable(const CaptureResult &result) {
     ATRACE_CALL();
     ALOGV("%s: New result available.", __FUNCTION__);
@@ -386,7 +409,7 @@
 
     SharedParameters::Lock l(client->getParameters());
     /* warning: this also locks a SharedCameraCallbacks */
-    shutterNotifyLocked(l.mParameters, client, mMsgType);
+    shutterNotifyLocked(l.mParameters, client);
     mShutterNotified = true;
     mTimeoutCount = kMaxTimeoutsForCaptureEnd;
     return STANDARD_CAPTURE_WAIT;
@@ -492,7 +515,6 @@
     ATRACE_CALL();
     SharedParameters::Lock l(client->getParameters());
     Vector<int32_t> outputStreams;
-    uint8_t captureIntent = static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
 
     /**
      * Set up output streams in the request
@@ -522,7 +544,6 @@
 
     if (l.mParameters.state == Parameters::VIDEO_SNAPSHOT) {
         outputStreams.push(client->getRecordingStreamId());
-        captureIntent = static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT);
     }
 
     res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
@@ -532,10 +553,6 @@
                 &mCaptureId, 1);
     }
     if (res == OK) {
-        res = mCaptureRequest.update(ANDROID_CONTROL_CAPTURE_INTENT,
-                &captureIntent, 1);
-    }
-    if (res == OK) {
         res = mCaptureRequest.sort();
     }
 
@@ -612,7 +629,7 @@
         if (!mShutterNotified) {
             SharedParameters::Lock l(client->getParameters());
             /* warning: this also locks a SharedCameraCallbacks */
-            shutterNotifyLocked(l.mParameters, client, mMsgType);
+            shutterNotifyLocked(l.mParameters, client);
             mShutterNotified = true;
         }
     } else if (mTimeoutCount <= 0) {
@@ -685,6 +702,8 @@
         sp<Camera2Client> &client) {
     ATRACE_CALL();
     status_t res;
+    uint8_t captureIntent = static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
+
     if (mCaptureRequest.entryCount() == 0) {
         res = client->getCameraDevice()->createDefaultRequest(
                 CAMERA2_TEMPLATE_STILL_CAPTURE,
@@ -697,6 +716,16 @@
         }
     }
 
+    if (params.state == Parameters::VIDEO_SNAPSHOT) {
+        captureIntent = static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT);
+    }
+    res = mCaptureRequest.update(ANDROID_CONTROL_CAPTURE_INTENT, &captureIntent, 1);
+    if (res != OK) {
+        ALOGE("%s: Camera %d: Unable to update capture intent: %s (%d)",
+                __FUNCTION__, client->getCameraId(), strerror(-res), res);
+        return res;
+    }
+
     res = params.updateRequest(&mCaptureRequest);
     if (res != OK) {
         ALOGE("%s: Camera %d: Unable to update common entries of capture "
@@ -717,12 +746,11 @@
 }
 
 /*static*/ void CaptureSequencer::shutterNotifyLocked(const Parameters &params,
-            const sp<Camera2Client>& client, int msgType) {
+            const sp<Camera2Client>& client) {
     ATRACE_CALL();
 
     if (params.state == Parameters::STILL_CAPTURE
-        && params.playShutterSound
-        && (msgType & CAMERA_MSG_SHUTTER)) {
+        && params.playShutterSound) {
         client->getCameraService()->playSound(CameraService::SOUND_SHUTTER);
     }
 
diff --git a/services/camera/libcameraservice/api1/client2/CaptureSequencer.h b/services/camera/libcameraservice/api1/client2/CaptureSequencer.h
index f2e3750..727dd53 100644
--- a/services/camera/libcameraservice/api1/client2/CaptureSequencer.h
+++ b/services/camera/libcameraservice/api1/client2/CaptureSequencer.h
@@ -51,7 +51,7 @@
     void setZslProcessor(const wp<ZslProcessor>& processor);
 
     // Begin still image capture
-    status_t startCapture(int msgType);
+    status_t startCapture();
 
     // Wait until current image capture completes; returns immediately if no
     // capture is active. Returns TIMED_OUT if capture does not complete during
@@ -65,6 +65,9 @@
     void notifyShutter(const CaptureResultExtras& resultExtras,
                        nsecs_t timestamp);
 
+    // Notifications about shutter (capture start)
+    void notifyError(int32_t errorCode, const CaptureResultExtras& resultExtras);
+
     // Notification from the frame processor
     virtual void onResultAvailable(const CaptureResult &result);
 
@@ -145,7 +148,6 @@
     bool mAeInPrecapture;
 
     int32_t mCaptureId;
-    int mMsgType;
 
     // Main internal methods
 
@@ -172,7 +174,7 @@
 
     // Emit Shutter/Raw callback to java, and maybe play a shutter sound
     static void shutterNotifyLocked(const Parameters &params,
-            const sp<Camera2Client>& client, int msgType);
+            const sp<Camera2Client>& client);
 };
 
 }; // namespace camera2
diff --git a/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp b/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp
index 0c738e7..683e84d 100644
--- a/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp
@@ -33,7 +33,10 @@
     FrameProcessorBase(device),
     mClient(client),
     mLastFrameNumberOfFaces(0),
-    mLast3AFrameNumber(-1) {
+    mLast3AFrameNumber(-1),
+    mLastAEFrameNumber(-1),
+    mLastAFrameNumber(-1),
+    mLastAWBFrameNumber(-1) {
 
     sp<CameraDeviceBase> d = device.promote();
     mSynthesize3ANotify = !(d->willNotify3A());
@@ -262,24 +265,73 @@
     bool gotAllStates = true;
 
     // TODO: Also use AE mode, AE trigger ID
-    gotAllStates &= updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AF_MODE,
+    bool gotAFState = updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AF_MODE,
             &pendingState.afMode, frameNumber, cameraId);
 
-    gotAllStates &= updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AWB_MODE,
+    bool gotAWBState = updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AWB_MODE,
             &pendingState.awbMode, frameNumber, cameraId);
 
-    gotAllStates &= updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AE_STATE,
+    bool gotAEState = updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AE_STATE,
             &pendingState.aeState, frameNumber, cameraId);
 
-    gotAllStates &= updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AF_STATE,
+    gotAFState &= updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AF_STATE,
             &pendingState.afState, frameNumber, cameraId);
 
-    gotAllStates &= updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AWB_STATE,
+    gotAWBState &= updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AWB_STATE,
             &pendingState.awbState, frameNumber, cameraId);
 
     pendingState.afTriggerId = frame.mResultExtras.afTriggerId;
     pendingState.aeTriggerId = frame.mResultExtras.precaptureTriggerId;
 
+    if (gotAEState && (frameNumber > mLastAEFrameNumber)) {
+        if (pendingState.aeState != m3aState.aeState ||
+                pendingState.aeTriggerId > m3aState.aeTriggerId) {
+            ALOGV("%s: Camera %d: AE state %d->%d",
+                    __FUNCTION__, cameraId,
+                    m3aState.aeState, pendingState.aeState);
+            client->notifyAutoExposure(pendingState.aeState, pendingState.aeTriggerId);
+
+            m3aState.aeState = pendingState.aeState;
+            m3aState.aeTriggerId = pendingState.aeTriggerId;
+            mLastAEFrameNumber = frameNumber;
+        }
+    }
+
+    if (gotAFState && (frameNumber > mLastAFrameNumber)) {
+        if (pendingState.afState != m3aState.afState ||
+                pendingState.afMode != m3aState.afMode ||
+                pendingState.afTriggerId != m3aState.afTriggerId) {
+            ALOGV("%s: Camera %d: AF state %d->%d. AF mode %d->%d. Trigger %d->%d",
+                    __FUNCTION__, cameraId,
+                    m3aState.afState, pendingState.afState,
+                    m3aState.afMode, pendingState.afMode,
+                    m3aState.afTriggerId, pendingState.afTriggerId);
+            client->notifyAutoFocus(pendingState.afState, pendingState.afTriggerId);
+
+            m3aState.afState = pendingState.afState;
+            m3aState.afMode = pendingState.afMode;
+            m3aState.afTriggerId = pendingState.afTriggerId;
+            mLastAFrameNumber = frameNumber;
+        }
+    }
+
+    if (gotAWBState && (frameNumber > mLastAWBFrameNumber)) {
+        if (pendingState.awbState != m3aState.awbState ||
+                pendingState.awbMode != m3aState.awbMode) {
+            ALOGV("%s: Camera %d: AWB state %d->%d. AWB mode %d->%d",
+                    __FUNCTION__, cameraId,
+                    m3aState.awbState, pendingState.awbState,
+                    m3aState.awbMode, pendingState.awbMode);
+            client->notifyAutoWhitebalance(pendingState.awbState,
+                    pendingState.aeTriggerId);
+
+            m3aState.awbMode = pendingState.awbMode;
+            m3aState.awbState = pendingState.awbState;
+            mLastAWBFrameNumber = frameNumber;
+        }
+    }
+
+    gotAllStates &= gotAEState & gotAFState & gotAWBState;
     if (!gotAllStates) {
         // If not all states are received, put the pending state to mPending3AStates.
         if (index == NAME_NOT_FOUND) {
@@ -290,40 +342,10 @@
         return NOT_ENOUGH_DATA;
     }
 
-    // Once all 3A states are received, notify the client about 3A changes.
-    if (pendingState.aeState != m3aState.aeState ||
-            pendingState.aeTriggerId > m3aState.aeTriggerId) {
-        ALOGV("%s: Camera %d: AE state %d->%d",
-                __FUNCTION__, cameraId,
-                m3aState.aeState, pendingState.aeState);
-        client->notifyAutoExposure(pendingState.aeState, pendingState.aeTriggerId);
-    }
-
-    if (pendingState.afState != m3aState.afState ||
-        pendingState.afMode != m3aState.afMode ||
-        pendingState.afTriggerId != m3aState.afTriggerId) {
-        ALOGV("%s: Camera %d: AF state %d->%d. AF mode %d->%d. Trigger %d->%d",
-                __FUNCTION__, cameraId,
-                m3aState.afState, pendingState.afState,
-                m3aState.afMode, pendingState.afMode,
-                m3aState.afTriggerId, pendingState.afTriggerId);
-        client->notifyAutoFocus(pendingState.afState, pendingState.afTriggerId);
-    }
-    if (pendingState.awbState != m3aState.awbState ||
-        pendingState.awbMode != m3aState.awbMode) {
-        ALOGV("%s: Camera %d: AWB state %d->%d. AWB mode %d->%d",
-                __FUNCTION__, cameraId,
-                m3aState.awbState, pendingState.awbState,
-                m3aState.awbMode, pendingState.awbMode);
-        client->notifyAutoWhitebalance(pendingState.awbState,
-                pendingState.aeTriggerId);
-    }
-
     if (index != NAME_NOT_FOUND) {
         mPending3AStates.removeItemsAt(index);
     }
 
-    m3aState = pendingState;
     mLast3AFrameNumber = frameNumber;
 
     return OK;
diff --git a/services/camera/libcameraservice/api1/client2/FrameProcessor.h b/services/camera/libcameraservice/api1/client2/FrameProcessor.h
index 62a4e91..8183c12 100644
--- a/services/camera/libcameraservice/api1/client2/FrameProcessor.h
+++ b/services/camera/libcameraservice/api1/client2/FrameProcessor.h
@@ -104,8 +104,7 @@
     // Track most recent frame number for which 3A notifications were sent for.
     // Used to filter against sending 3A notifications for the same frame
     // several times.
-    int32_t mLast3AFrameNumber;
-
+    int32_t mLast3AFrameNumber, mLastAEFrameNumber, mLastAFrameNumber, mLastAWBFrameNumber;
     // Emit FaceDetection event to java if faces changed
     void callbackFaceDetection(const sp<Camera2Client>& client,
                                const camera_frame_metadata &metadata);
diff --git a/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp b/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp
index b7020fe..ddfe5e3 100755
--- a/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp
@@ -62,26 +62,6 @@
     }
 }
 
-void JpegProcessor::onBufferAcquired(const BufferInfo& /*bufferInfo*/) {
-    // Intentionally left empty
-}
-
-void JpegProcessor::onBufferReleased(const BufferInfo& bufferInfo) {
-    ALOGV("%s", __FUNCTION__);
-    if (bufferInfo.mError) {
-        // Only lock in case of error, since we get one of these for each
-        // onFrameAvailable as well, and scheduling may delay this call late
-        // enough to run into later preview restart operations, for non-error
-        // cases.
-        // b/29524651
-        ALOGV("%s: JPEG buffer lost", __FUNCTION__);
-        Mutex::Autolock l(mInputMutex);
-        mCaptureDone = true;
-        mCaptureSuccess = false;
-        mCaptureDoneSignal.signal();
-    }
-}
-
 status_t JpegProcessor::updateStream(const Parameters &params) {
     ATRACE_CALL();
     ALOGV("%s", __FUNCTION__);
@@ -176,13 +156,6 @@
                     strerror(-res), res);
             return res;
         }
-
-        res = device->addBufferListenerForStream(mCaptureStreamId, this);
-        if (res != OK) {
-              ALOGE("%s: Camera %d: Can't add buffer listeneri: %s (%d)",
-                    __FUNCTION__, mId, strerror(-res), res);
-              return res;
-        }
     }
     return OK;
 }
diff --git a/services/camera/libcameraservice/api1/client2/JpegProcessor.h b/services/camera/libcameraservice/api1/client2/JpegProcessor.h
index 7187ad9..977f11d 100644
--- a/services/camera/libcameraservice/api1/client2/JpegProcessor.h
+++ b/services/camera/libcameraservice/api1/client2/JpegProcessor.h
@@ -25,6 +25,7 @@
 #include <gui/CpuConsumer.h>
 
 #include "camera/CameraMetadata.h"
+#include "device3/Camera3StreamBufferListener.h"
 
 namespace android {
 
@@ -41,8 +42,7 @@
  * Still image capture output image processing
  */
 class JpegProcessor:
-            public Thread, public CpuConsumer::FrameAvailableListener,
-            public camera3::Camera3StreamBufferListener {
+            public Thread, public CpuConsumer::FrameAvailableListener {
   public:
     JpegProcessor(sp<Camera2Client> client, wp<CaptureSequencer> sequencer);
     ~JpegProcessor();
@@ -50,15 +50,14 @@
     // CpuConsumer listener implementation
     void onFrameAvailable(const BufferItem& item);
 
-    // Camera3StreamBufferListener implementation
-    void onBufferAcquired(const BufferInfo& bufferInfo) override;
-    void onBufferReleased(const BufferInfo& bufferInfo) override;
-
     status_t updateStream(const Parameters &params);
     status_t deleteStream();
     int getStreamId() const;
 
     void dump(int fd, const Vector<String16>& args) const;
+
+    static size_t findJpegSize(uint8_t* jpegBuffer, size_t maxSize);
+
   private:
     static const nsecs_t kWaitDuration = 10000000; // 10 ms
     wp<CameraDeviceBase> mDevice;
@@ -82,7 +81,6 @@
     virtual bool threadLoop();
 
     status_t processNewCapture(bool captureSuccess);
-    size_t findJpegSize(uint8_t* jpegBuffer, size_t maxSize);
 
 };
 
diff --git a/services/camera/libcameraservice/api1/client2/Parameters.cpp b/services/camera/libcameraservice/api1/client2/Parameters.cpp
index 28d186a..18addb5 100644
--- a/services/camera/libcameraservice/api1/client2/Parameters.cpp
+++ b/services/camera/libcameraservice/api1/client2/Parameters.cpp
@@ -69,7 +69,7 @@
     res = buildQuirks();
     if (res != OK) return res;
 
-    const Size MAX_PREVIEW_SIZE = { MAX_PREVIEW_WIDTH, MAX_PREVIEW_HEIGHT };
+    Size maxPreviewSize = { MAX_PREVIEW_WIDTH, MAX_PREVIEW_HEIGHT };
     // Treat the H.264 max size as the max supported video size.
     MediaProfiles *videoEncoderProfiles = MediaProfiles::getInstance();
     Vector<video_encoder> encoders = videoEncoderProfiles->getVideoEncoders();
@@ -90,11 +90,16 @@
         }
     }
     // This is just an upper bound and may not be an actually valid video size
-    const Size VIDEO_SIZE_UPPER_BOUND = {maxVideoWidth, maxVideoHeight};
+    Size videoSizeUpperBound = {maxVideoWidth, maxVideoHeight};
 
-    res = getFilteredSizes(MAX_PREVIEW_SIZE, &availablePreviewSizes);
+    if (fastInfo.supportsPreferredConfigs) {
+        maxPreviewSize = getMaxSize(getPreferredPreviewSizes());
+        videoSizeUpperBound = getMaxSize(getPreferredVideoSizes());
+    }
+
+    res = getFilteredSizes(maxPreviewSize, &availablePreviewSizes);
     if (res != OK) return res;
-    res = getFilteredSizes(VIDEO_SIZE_UPPER_BOUND, &availableVideoSizes);
+    res = getFilteredSizes(videoSizeUpperBound, &availableVideoSizes);
     if (res != OK) return res;
 
     // Select initial preview and video size that's under the initial bound and
@@ -296,9 +301,13 @@
     Vector<Size> availableJpegSizes = getAvailableJpegSizes();
     if (!availableJpegSizes.size()) return NO_INIT;
 
-    // TODO: Pick maximum
     pictureWidth = availableJpegSizes[0].width;
     pictureHeight = availableJpegSizes[0].height;
+    if (fastInfo.supportsPreferredConfigs) {
+        Size suggestedJpegSize = getMaxSize(getPreferredJpegSizes());
+        pictureWidth = suggestedJpegSize.width;
+        pictureHeight = suggestedJpegSize.height;
+    }
     pictureWidthLastSet = pictureWidth;
     pictureHeightLastSet = pictureHeight;
     pictureSizeOverriden = false;
@@ -757,6 +766,7 @@
     focusState = ANDROID_CONTROL_AF_STATE_INACTIVE;
     shadowFocusMode = FOCUS_MODE_INVALID;
 
+    aeState = ANDROID_CONTROL_AE_STATE_INACTIVE;
     camera_metadata_ro_entry_t max3aRegions = staticInfo(ANDROID_CONTROL_MAX_REGIONS,
             Parameters::NUM_REGION, Parameters::NUM_REGION);
     if (max3aRegions.count != Parameters::NUM_REGION) return NO_INIT;
@@ -1010,6 +1020,9 @@
         arrayHeight = activeArraySize.data.i32[3];
     } else return NO_INIT;
 
+    fastInfo.supportsPreferredConfigs =
+        info->exists(ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS);
+
     // We'll set the target FPS range for still captures to be as wide
     // as possible to give the HAL maximum latitude for exposure selection
     camera_metadata_ro_entry_t availableFpsRanges =
@@ -1021,8 +1034,11 @@
     // Get supported preview fps ranges, up to default maximum.
     Vector<Size> supportedPreviewSizes;
     Vector<FpsRange> supportedPreviewFpsRanges;
-    const Size PREVIEW_SIZE_BOUND = { MAX_PREVIEW_WIDTH, MAX_PREVIEW_HEIGHT };
-    status_t res = getFilteredSizes(PREVIEW_SIZE_BOUND, &supportedPreviewSizes);
+    Size previewSizeBound = { MAX_PREVIEW_WIDTH, MAX_PREVIEW_HEIGHT };
+    if (fastInfo.supportsPreferredConfigs) {
+        previewSizeBound = getMaxSize(getPreferredPreviewSizes());
+    }
+    status_t res = getFilteredSizes(previewSizeBound, &supportedPreviewSizes);
     if (res != OK) return res;
     for (size_t i=0; i < availableFpsRanges.count; i += 2) {
         if (!isFpsSupported(supportedPreviewSizes,
@@ -3106,6 +3122,67 @@
     return jpegSizes;
 }
 
+Vector<Parameters::StreamConfiguration> Parameters::getPreferredStreamConfigurations(
+        int32_t usecaseId) const {
+    const size_t STREAM_CONFIGURATION_SIZE = 5;
+    const size_t STREAM_WIDTH_OFFSET = 0;
+    const size_t STREAM_HEIGHT_OFFSET = 1;
+    const size_t STREAM_FORMAT_OFFSET = 2;
+    const size_t STREAM_IS_INPUT_OFFSET = 3;
+    const size_t STREAM_USECASE_BITMAP_OFFSET = 4;
+    Vector<StreamConfiguration> scs;
+
+    if (fastInfo.supportsPreferredConfigs) {
+        camera_metadata_ro_entry_t availableStreamConfigs = staticInfo(
+                ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS);
+        for (size_t i = 0; i < availableStreamConfigs.count; i+= STREAM_CONFIGURATION_SIZE) {
+            int32_t width = availableStreamConfigs.data.i32[i + STREAM_WIDTH_OFFSET];
+            int32_t height = availableStreamConfigs.data.i32[i + STREAM_HEIGHT_OFFSET];
+            int32_t format = availableStreamConfigs.data.i32[i + STREAM_FORMAT_OFFSET];
+            int32_t isInput = availableStreamConfigs.data.i32[i + STREAM_IS_INPUT_OFFSET];
+            int32_t supportedUsecases =
+                    availableStreamConfigs.data.i32[i + STREAM_USECASE_BITMAP_OFFSET];
+            if (supportedUsecases & (1 << usecaseId)) {
+                StreamConfiguration sc = {format, width, height, isInput};
+                scs.add(sc);
+            }
+        }
+    }
+
+    return scs;
+}
+
+Vector<Parameters::Size> Parameters::getPreferredFilteredSizes(int32_t usecaseId,
+        int32_t format) const {
+    Vector<Parameters::Size> sizes;
+    Vector<StreamConfiguration> scs = getPreferredStreamConfigurations(usecaseId);
+    for (const auto &it : scs) {
+        if (it.format == format) {
+            sizes.add({it.width, it.height});
+        }
+    }
+
+    return sizes;
+}
+
+Vector<Parameters::Size> Parameters::getPreferredJpegSizes() const {
+    return getPreferredFilteredSizes(
+            ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_SNAPSHOT,
+            HAL_PIXEL_FORMAT_BLOB);
+}
+
+Vector<Parameters::Size> Parameters::getPreferredPreviewSizes() const {
+    return getPreferredFilteredSizes(
+            ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PREVIEW,
+            HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
+}
+
+Vector<Parameters::Size> Parameters::getPreferredVideoSizes() const {
+    return getPreferredFilteredSizes(
+            ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_RECORD,
+            HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
+}
+
 Parameters::CropRegion Parameters::calculateCropRegion(bool previewOnly) const {
 
     float zoomLeft, zoomTop, zoomWidth, zoomHeight;
diff --git a/services/camera/libcameraservice/api1/client2/Parameters.h b/services/camera/libcameraservice/api1/client2/Parameters.h
index 42e7a47..3a709c9 100644
--- a/services/camera/libcameraservice/api1/client2/Parameters.h
+++ b/services/camera/libcameraservice/api1/client2/Parameters.h
@@ -122,6 +122,7 @@
         int32_t high;
     };
 
+    uint8_t aeState; //latest AE state from Hal
     int32_t exposureCompensation;
     bool autoExposureLock;
     bool autoExposureLockAvailable;
@@ -247,6 +248,7 @@
         bool useFlexibleYuv;
         Size maxJpegSize;
         Size maxZslSize;
+        bool supportsPreferredConfigs;
     } fastInfo;
 
     // Quirks information; these are short-lived flags to enable workarounds for
@@ -417,6 +419,9 @@
     // returns an empty Vector if device HAL version does support it
     Vector<StreamConfiguration> getStreamConfigurations();
 
+    // Helper function to extract the suggested stream configurations
+    Vector<StreamConfiguration> getPreferredStreamConfigurations(int32_t usecaseId) const;
+
     // Helper function to get minimum frame duration for a jpeg size
     // return -1 if input jpeg size cannot be found in supported size list
     int64_t getJpegStreamMinFrameDurationNs(Parameters::Size size);
@@ -438,6 +443,15 @@
     // The maximum size is defined by comparing width first, when width ties comparing height.
     Size getMaxSize(const Vector<Size>& sizes);
 
+    // Helper function to filter and sort suggested sizes
+    Vector<Parameters::Size> getPreferredFilteredSizes(int32_t usecaseId, int32_t format) const;
+    // Helper function to get the suggested jpeg sizes
+    Vector<Size> getPreferredJpegSizes() const;
+    // Helper function to get the suggested preview sizes
+    Vector<Size> getPreferredPreviewSizes() const;
+    // Helper function to get the suggested video sizes
+    Vector<Size> getPreferredVideoSizes() const;
+
     int mDeviceVersion;
     uint8_t mDefaultSceneMode;
 };
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 98d0534..c7a4f2b 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -19,6 +19,7 @@
 //#define LOG_NDEBUG 0
 
 #include <cutils/properties.h>
+#include <utils/CameraThreadState.h>
 #include <utils/Log.h>
 #include <utils/Trace.h>
 #include <gui/Surface.h>
@@ -26,10 +27,15 @@
 #include <camera/CameraUtils.h>
 
 #include "common/CameraDeviceBase.h"
+#include "device3/Camera3Device.h"
+#include "device3/Camera3OutputStream.h"
 #include "api2/CameraDeviceClient.h"
 
 #include <camera_metadata_hidden.h>
 
+#include "DepthCompositeStream.h"
+#include "HeicCompositeStream.h"
+
 // Convenience methods for constructing binder::Status objects for error returns
 
 #define STATUS_ERROR(errorCode, errorString) \
@@ -122,6 +128,7 @@
                 physicalKeysEntry.data.i32 + physicalKeysEntry.count);
     }
 
+    mProviderManager = providerPtr;
     return OK;
 }
 
@@ -139,6 +146,7 @@
 
 binder::Status CameraDeviceClient::insertGbpLocked(const sp<IGraphicBufferProducer>& gbp,
         SurfaceMap* outSurfaceMap, Vector<int32_t>* outputStreamIds, int32_t *currentStreamId) {
+    int compositeIdx;
     int idx = mStreamMap.indexOfKey(IInterface::asBinder(gbp));
 
     // Trying to submit request with surface that wasn't created
@@ -148,6 +156,11 @@
                 __FUNCTION__, mCameraIdStr.string());
         return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
                 "Request targets Surface that is not part of current capture session");
+    } else if ((compositeIdx = mCompositeStreamMap.indexOfKey(IInterface::asBinder(gbp)))
+            != NAME_NOT_FOUND) {
+        mCompositeStreamMap.valueAt(compositeIdx)->insertGbp(outSurfaceMap, outputStreamIds,
+                currentStreamId);
+        return binder::Status::ok();
     }
 
     const StreamSurfaceId& streamSurfaceId = mStreamMap.valueAt(idx);
@@ -252,7 +265,7 @@
         Vector<int32_t> outputStreamIds;
         std::vector<std::string> requestedPhysicalIds;
         if (request.mSurfaceList.size() > 0) {
-            for (sp<Surface> surface : request.mSurfaceList) {
+            for (const sp<Surface>& surface : request.mSurfaceList) {
                 if (surface == 0) continue;
 
                 int32_t streamId;
@@ -469,6 +482,79 @@
         return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
     }
 
+    res = checkOperatingModeLocked(operatingMode);
+    if (!res.isOk()) {
+        return res;
+    }
+
+    status_t err = mDevice->configureStreams(sessionParams, operatingMode);
+    if (err == BAD_VALUE) {
+        String8 msg = String8::format("Camera %s: Unsupported set of inputs/outputs provided",
+                mCameraIdStr.string());
+        ALOGE("%s: %s", __FUNCTION__, msg.string());
+        res = STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+    } else if (err != OK) {
+        String8 msg = String8::format("Camera %s: Error configuring streams: %s (%d)",
+                mCameraIdStr.string(), strerror(-err), err);
+        ALOGE("%s: %s", __FUNCTION__, msg.string());
+        res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+    } else {
+        for (size_t i = 0; i < mCompositeStreamMap.size(); ++i) {
+            err = mCompositeStreamMap.valueAt(i)->configureStream();
+            if (err != OK ) {
+                String8 msg = String8::format("Camera %s: Error configuring composite "
+                        "streams: %s (%d)", mCameraIdStr.string(), strerror(-err), err);
+                ALOGE("%s: %s", __FUNCTION__, msg.string());
+                res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+                break;
+            }
+        }
+    }
+
+    return res;
+}
+
+binder::Status CameraDeviceClient::checkSurfaceTypeLocked(size_t numBufferProducers,
+        bool deferredConsumer, int surfaceType) const {
+    if (numBufferProducers > MAX_SURFACES_PER_STREAM) {
+        ALOGE("%s: GraphicBufferProducer count %zu for stream exceeds limit of %d",
+                __FUNCTION__, numBufferProducers, MAX_SURFACES_PER_STREAM);
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Surface count is too high");
+    } else if ((numBufferProducers == 0) && (!deferredConsumer)) {
+        ALOGE("%s: Number of consumers cannot be smaller than 1", __FUNCTION__);
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "No valid consumers.");
+    }
+
+    bool validSurfaceType = ((surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) ||
+            (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_TEXTURE));
+
+    if (deferredConsumer && !validSurfaceType) {
+        ALOGE("%s: Target surface has invalid surfaceType = %d.", __FUNCTION__, surfaceType);
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Target Surface is invalid");
+    }
+
+    return binder::Status::ok();
+}
+
+binder::Status CameraDeviceClient::checkPhysicalCameraIdLocked(String8 physicalCameraId) {
+    if (physicalCameraId.size() > 0) {
+        std::vector<std::string> physicalCameraIds;
+        bool logicalCamera =
+            mProviderManager->isLogicalCamera(mCameraIdStr.string(), &physicalCameraIds);
+        if (!logicalCamera ||
+                std::find(physicalCameraIds.begin(), physicalCameraIds.end(),
+                    physicalCameraId.string()) == physicalCameraIds.end()) {
+            String8 msg = String8::format("Camera %s: Camera doesn't support physicalCameraId %s.",
+                    mCameraIdStr.string(), physicalCameraId.string());
+            ALOGE("%s: %s", __FUNCTION__, msg.string());
+            return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        }
+    }
+
+    return binder::Status::ok();
+}
+
+binder::Status CameraDeviceClient::checkOperatingModeLocked(int operatingMode) const {
     if (operatingMode < 0) {
         String8 msg = String8::format(
             "Camera %s: Invalid operating mode %d requested", mCameraIdStr.string(), operatingMode);
@@ -477,7 +563,6 @@
                 msg.string());
     }
 
-    // Sanitize the high speed session against necessary capability bit.
     bool isConstrainedHighSpeed = (operatingMode == ICameraDeviceUser::CONSTRAINED_HIGH_SPEED_MODE);
     if (isConstrainedHighSpeed) {
         CameraMetadata staticInfo = mDevice->info();
@@ -500,17 +585,205 @@
         }
     }
 
-    status_t err = mDevice->configureStreams(sessionParams, operatingMode);
-    if (err == BAD_VALUE) {
-        String8 msg = String8::format("Camera %s: Unsupported set of inputs/outputs provided",
-                mCameraIdStr.string());
+    return binder::Status::ok();
+}
+
+void CameraDeviceClient::mapStreamInfo(const OutputStreamInfo &streamInfo,
+            camera3_stream_rotation_t rotation, String8 physicalId,
+            hardware::camera::device::V3_4::Stream *stream /*out*/) {
+    if (stream == nullptr) {
+        return;
+    }
+
+    stream->v3_2.streamType = hardware::camera::device::V3_2::StreamType::OUTPUT;
+    stream->v3_2.width = streamInfo.width;
+    stream->v3_2.height = streamInfo.height;
+    stream->v3_2.format = Camera3Device::mapToPixelFormat(streamInfo.format);
+    auto u = streamInfo.consumerUsage;
+    camera3::Camera3OutputStream::applyZSLUsageQuirk(streamInfo.format, &u);
+    stream->v3_2.usage = Camera3Device::mapToConsumerUsage(u);
+    stream->v3_2.dataSpace = Camera3Device::mapToHidlDataspace(streamInfo.dataSpace);
+    stream->v3_2.rotation = Camera3Device::mapToStreamRotation(rotation);
+    stream->v3_2.id = -1; // Invalid stream id
+    stream->physicalCameraId = std::string(physicalId.string());
+    stream->bufferSize = 0;
+}
+
+binder::Status CameraDeviceClient::isSessionConfigurationSupported(
+        const SessionConfiguration& sessionConfiguration, bool *status /*out*/) {
+    ATRACE_CALL();
+
+    binder::Status res;
+    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
+
+    Mutex::Autolock icl(mBinderSerializationLock);
+
+    if (!mDevice.get()) {
+        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
+    }
+
+    auto operatingMode = sessionConfiguration.getOperatingMode();
+    res = checkOperatingModeLocked(operatingMode);
+    if (!res.isOk()) {
+        return res;
+    }
+
+    if (status == nullptr) {
+        String8 msg = String8::format( "Camera %s: Invalid status!", mCameraIdStr.string());
         ALOGE("%s: %s", __FUNCTION__, msg.string());
-        res = STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
-    } else if (err != OK) {
-        String8 msg = String8::format("Camera %s: Error configuring streams: %s (%d)",
-                mCameraIdStr.string(), strerror(-err), err);
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+    }
+
+    hardware::camera::device::V3_4::StreamConfiguration streamConfiguration;
+    auto ret = Camera3Device::mapToStreamConfigurationMode(
+            static_cast<camera3_stream_configuration_mode_t> (operatingMode),
+            /*out*/ &streamConfiguration.operationMode);
+    if (ret != OK) {
+        String8 msg = String8::format(
+            "Camera %s: Failed mapping operating mode %d requested: %s (%d)", mCameraIdStr.string(),
+            operatingMode, strerror(-ret), ret);
         ALOGE("%s: %s", __FUNCTION__, msg.string());
-        res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
+                msg.string());
+    }
+
+    bool isInputValid = (sessionConfiguration.getInputWidth() > 0) &&
+            (sessionConfiguration.getInputHeight() > 0) &&
+            (sessionConfiguration.getInputFormat() > 0);
+    auto outputConfigs = sessionConfiguration.getOutputConfigurations();
+    size_t streamCount = outputConfigs.size();
+    streamCount = isInputValid ? streamCount + 1 : streamCount;
+    streamConfiguration.streams.resize(streamCount);
+    size_t streamIdx = 0;
+    if (isInputValid) {
+        streamConfiguration.streams[streamIdx++] = {{/*streamId*/0,
+                hardware::camera::device::V3_2::StreamType::INPUT,
+                static_cast<uint32_t> (sessionConfiguration.getInputWidth()),
+                static_cast<uint32_t> (sessionConfiguration.getInputHeight()),
+                Camera3Device::mapToPixelFormat(sessionConfiguration.getInputFormat()),
+                /*usage*/ 0, HAL_DATASPACE_UNKNOWN,
+                hardware::camera::device::V3_2::StreamRotation::ROTATION_0},
+                /*physicalId*/ nullptr, /*bufferSize*/0};
+    }
+
+    for (const auto &it : outputConfigs) {
+        const std::vector<sp<IGraphicBufferProducer>>& bufferProducers =
+            it.getGraphicBufferProducers();
+        bool deferredConsumer = it.isDeferred();
+        String8 physicalCameraId = String8(it.getPhysicalCameraId());
+        size_t numBufferProducers = bufferProducers.size();
+        bool isStreamInfoValid = false;
+        OutputStreamInfo streamInfo;
+
+        res = checkSurfaceTypeLocked(numBufferProducers, deferredConsumer, it.getSurfaceType());
+        if (!res.isOk()) {
+            return res;
+        }
+
+        res = checkPhysicalCameraIdLocked(physicalCameraId);
+        if (!res.isOk()) {
+            return res;
+        }
+
+        if (deferredConsumer) {
+            streamInfo.width = it.getWidth();
+            streamInfo.height = it.getHeight();
+            streamInfo.format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
+            streamInfo.dataSpace = android_dataspace_t::HAL_DATASPACE_UNKNOWN;
+            auto surfaceType = it.getSurfaceType();
+            streamInfo.consumerUsage = GraphicBuffer::USAGE_HW_TEXTURE;
+            if (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) {
+                streamInfo.consumerUsage |= GraphicBuffer::USAGE_HW_COMPOSER;
+            }
+            mapStreamInfo(streamInfo, CAMERA3_STREAM_ROTATION_0, physicalCameraId,
+                    &streamConfiguration.streams[streamIdx++]);
+            isStreamInfoValid = true;
+
+            if (numBufferProducers == 0) {
+                continue;
+            }
+        }
+
+        for (auto& bufferProducer : bufferProducers) {
+            sp<Surface> surface;
+            res = createSurfaceFromGbp(streamInfo, isStreamInfoValid, surface, bufferProducer,
+                    physicalCameraId);
+
+            if (!res.isOk())
+                return res;
+
+            if (!isStreamInfoValid) {
+                bool isDepthCompositeStream =
+                        camera3::DepthCompositeStream::isDepthCompositeStream(surface);
+                bool isHeicCompositeStream =
+                        camera3::HeicCompositeStream::isHeicCompositeStream(surface);
+                if (isDepthCompositeStream || isHeicCompositeStream) {
+                    // We need to take in to account that composite streams can have
+                    // additional internal camera streams.
+                    std::vector<OutputStreamInfo> compositeStreams;
+                    if (isDepthCompositeStream) {
+                        ret = camera3::DepthCompositeStream::getCompositeStreamInfo(streamInfo,
+                                mDevice->info(), &compositeStreams);
+                    } else {
+                        ret = camera3::HeicCompositeStream::getCompositeStreamInfo(streamInfo,
+                            mDevice->info(), &compositeStreams);
+                    }
+                    if (ret != OK) {
+                        String8 msg = String8::format(
+                                "Camera %s: Failed adding composite streams: %s (%d)",
+                                mCameraIdStr.string(), strerror(-ret), ret);
+                        ALOGE("%s: %s", __FUNCTION__, msg.string());
+                        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+                    }
+
+                    if (compositeStreams.size() == 0) {
+                        // No internal streams means composite stream not
+                        // supported.
+                        *status = false;
+                        return binder::Status::ok();
+                    } else if (compositeStreams.size() > 1) {
+                        streamCount += compositeStreams.size() - 1;
+                        streamConfiguration.streams.resize(streamCount);
+                    }
+
+                    for (const auto& compositeStream : compositeStreams) {
+                        mapStreamInfo(compositeStream,
+                                static_cast<camera3_stream_rotation_t> (it.getRotation()),
+                                physicalCameraId, &streamConfiguration.streams[streamIdx++]);
+                    }
+                } else {
+                    mapStreamInfo(streamInfo,
+                            static_cast<camera3_stream_rotation_t> (it.getRotation()),
+                            physicalCameraId, &streamConfiguration.streams[streamIdx++]);
+                }
+                isStreamInfoValid = true;
+            }
+        }
+    }
+
+    *status = false;
+    ret = mProviderManager->isSessionConfigurationSupported(mCameraIdStr.string(),
+            streamConfiguration, status);
+    switch (ret) {
+        case OK:
+            // Expected, do nothing.
+            break;
+        case INVALID_OPERATION: {
+                String8 msg = String8::format(
+                        "Camera %s: Session configuration query not supported!",
+                        mCameraIdStr.string());
+                ALOGD("%s: %s", __FUNCTION__, msg.string());
+                res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+            }
+
+            break;
+        default: {
+                String8 msg = String8::format( "Camera %s: Error: %s (%d)", mCameraIdStr.string(),
+                        strerror(-ret), ret);
+                ALOGE("%s: %s", __FUNCTION__, msg.string());
+                res = STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
+                        msg.string());
+            }
     }
 
     return res;
@@ -532,6 +805,7 @@
     bool isInput = false;
     std::vector<sp<IBinder>> surfaces;
     ssize_t dIndex = NAME_NOT_FOUND;
+    ssize_t compositeIndex  = NAME_NOT_FOUND;
 
     if (mInputStream.configured && mInputStream.id == streamId) {
         isInput = true;
@@ -551,6 +825,13 @@
             }
         }
 
+        for (size_t i = 0; i < mCompositeStreamMap.size(); ++i) {
+            if (streamId == mCompositeStreamMap.valueAt(i)->getStreamId()) {
+                compositeIndex = i;
+                break;
+            }
+        }
+
         if (surfaces.empty() && dIndex == NAME_NOT_FOUND) {
             String8 msg = String8::format("Camera %s: Invalid stream ID (%d) specified, no such"
                     " stream created yet", mCameraIdStr.string(), streamId);
@@ -580,6 +861,19 @@
             if (dIndex != NAME_NOT_FOUND) {
                 mDeferredStreams.removeItemsAt(dIndex);
             }
+
+            if (compositeIndex != NAME_NOT_FOUND) {
+                status_t ret;
+                if ((ret = mCompositeStreamMap.valueAt(compositeIndex)->deleteStream())
+                        != OK) {
+                    String8 msg = String8::format("Camera %s: Unexpected error %s (%d) when "
+                            "deleting composite stream %d", mCameraIdStr.string(), strerror(-err), err,
+                            streamId);
+                    ALOGE("%s: %s", __FUNCTION__, msg.string());
+                    res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+                }
+                mCompositeStreamMap.removeItemsAt(compositeIndex);
+            }
         }
     }
 
@@ -603,41 +897,23 @@
     bool deferredConsumer = outputConfiguration.isDeferred();
     bool isShared = outputConfiguration.isShared();
     String8 physicalCameraId = String8(outputConfiguration.getPhysicalCameraId());
-
-    if (numBufferProducers > MAX_SURFACES_PER_STREAM) {
-        ALOGE("%s: GraphicBufferProducer count %zu for stream exceeds limit of %d",
-              __FUNCTION__, bufferProducers.size(), MAX_SURFACES_PER_STREAM);
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Surface count is too high");
-    }
     bool deferredConsumerOnly = deferredConsumer && numBufferProducers == 0;
-    int surfaceType = outputConfiguration.getSurfaceType();
-    bool validSurfaceType = ((surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) ||
-            (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_TEXTURE));
 
-    if (deferredConsumer && !validSurfaceType) {
-        ALOGE("%s: Target surface is invalid: bufferProducer = %p, surfaceType = %d.",
-                __FUNCTION__, bufferProducers[0].get(), surfaceType);
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Target Surface is invalid");
+    res = checkSurfaceTypeLocked(numBufferProducers, deferredConsumer,
+            outputConfiguration.getSurfaceType());
+    if (!res.isOk()) {
+        return res;
     }
 
     if (!mDevice.get()) {
         return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
     }
 
-    if (physicalCameraId.size() > 0) {
-        std::vector<std::string> physicalCameraIds;
-        std::string physicalId(physicalCameraId.string());
-        bool logicalCamera =
-                CameraProviderManager::isLogicalCamera(mDevice->info(), &physicalCameraIds);
-        if (!logicalCamera ||
-                std::find(physicalCameraIds.begin(), physicalCameraIds.end(), physicalId) ==
-                physicalCameraIds.end()) {
-            String8 msg = String8::format("Camera %s: Camera doesn't support physicalCameraId %s.",
-                    mCameraIdStr.string(), physicalCameraId.string());
-            ALOGE("%s: %s", __FUNCTION__, msg.string());
-            return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
-        }
+    res = checkPhysicalCameraIdLocked(physicalCameraId);
+    if (!res.isOk()) {
+        return res;
     }
+
     std::vector<sp<Surface>> surfaces;
     std::vector<sp<IBinder>> binders;
     status_t err;
@@ -661,7 +937,8 @@
         }
 
         sp<Surface> surface;
-        res = createSurfaceFromGbp(streamInfo, isStreamInfoValid, surface, bufferProducer);
+        res = createSurfaceFromGbp(streamInfo, isStreamInfoValid, surface, bufferProducer,
+                physicalCameraId);
 
         if (!res.isOk())
             return res;
@@ -676,11 +953,32 @@
 
     int streamId = camera3::CAMERA3_STREAM_ID_INVALID;
     std::vector<int> surfaceIds;
-    err = mDevice->createStream(surfaces, deferredConsumer, streamInfo.width,
-            streamInfo.height, streamInfo.format, streamInfo.dataSpace,
-            static_cast<camera3_stream_rotation_t>(outputConfiguration.getRotation()),
-            &streamId, physicalCameraId, &surfaceIds, outputConfiguration.getSurfaceSetID(),
-            isShared);
+    bool isDepthCompositeStream = camera3::DepthCompositeStream::isDepthCompositeStream(surfaces[0]);
+    bool isHeicCompisiteStream = camera3::HeicCompositeStream::isHeicCompositeStream(surfaces[0]);
+    if (isDepthCompositeStream || isHeicCompisiteStream) {
+        sp<CompositeStream> compositeStream;
+        if (isDepthCompositeStream) {
+            compositeStream = new camera3::DepthCompositeStream(mDevice, getRemoteCallback());
+        } else {
+            compositeStream = new camera3::HeicCompositeStream(mDevice, getRemoteCallback());
+        }
+
+        err = compositeStream->createStream(surfaces, deferredConsumer, streamInfo.width,
+                streamInfo.height, streamInfo.format,
+                static_cast<camera3_stream_rotation_t>(outputConfiguration.getRotation()),
+                &streamId, physicalCameraId, &surfaceIds, outputConfiguration.getSurfaceSetID(),
+                isShared);
+        if (err == OK) {
+            mCompositeStreamMap.add(IInterface::asBinder(surfaces[0]->getIGraphicBufferProducer()),
+                    compositeStream);
+        }
+    } else {
+        err = mDevice->createStream(surfaces, deferredConsumer, streamInfo.width,
+                streamInfo.height, streamInfo.format, streamInfo.dataSpace,
+                static_cast<camera3_stream_rotation_t>(outputConfiguration.getRotation()),
+                &streamId, physicalCameraId, &surfaceIds, outputConfiguration.getSurfaceSetID(),
+                isShared);
+    }
 
     if (err != OK) {
         res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
@@ -889,6 +1187,8 @@
 
     const std::vector<sp<IGraphicBufferProducer> >& bufferProducers =
             outputConfiguration.getGraphicBufferProducers();
+    String8 physicalCameraId(outputConfiguration.getPhysicalCameraId());
+
     auto producerCount = bufferProducers.size();
     if (producerCount == 0) {
         ALOGE("%s: bufferProducers must not be empty", __FUNCTION__);
@@ -942,7 +1242,7 @@
         OutputStreamInfo outInfo;
         sp<Surface> surface;
         res = createSurfaceFromGbp(outInfo, /*isStreamInfoValid*/ false, surface,
-                newOutputsMap.valueAt(i));
+                newOutputsMap.valueAt(i), physicalCameraId);
         if (!res.isOk())
             return res;
 
@@ -1021,7 +1321,8 @@
 
 binder::Status CameraDeviceClient::createSurfaceFromGbp(
         OutputStreamInfo& streamInfo, bool isStreamInfoValid,
-        sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp) {
+        sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp,
+        const String8& physicalId) {
 
     // bufferProducer must be non-null
     if (gbp == nullptr) {
@@ -1098,7 +1399,7 @@
     // Round dimensions to the nearest dimensions available for this format
     if (flexibleConsumer && isPublicFormat(format) &&
             !CameraDeviceClient::roundBufferDimensionNearest(width, height,
-            format, dataSpace, mDevice->info(), /*out*/&width, /*out*/&height)) {
+            format, dataSpace, mDevice->info(physicalId), /*out*/&width, /*out*/&height)) {
         String8 msg = String8::format("Camera %s: No supported stream configurations with "
                 "format %#x defined, failed to create output stream",
                 mCameraIdStr.string(), format);
@@ -1159,6 +1460,8 @@
     camera_metadata_ro_entry streamConfigs =
             (dataSpace == HAL_DATASPACE_DEPTH) ?
             info.find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS) :
+            (dataSpace == static_cast<android_dataspace>(HAL_DATASPACE_HEIF)) ?
+            info.find(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS) :
             info.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
 
     int32_t bestWidth = -1;
@@ -1468,6 +1771,7 @@
 
     const std::vector<sp<IGraphicBufferProducer> >& bufferProducers =
             outputConfiguration.getGraphicBufferProducers();
+    String8 physicalId(outputConfiguration.getPhysicalCameraId());
 
     if (bufferProducers.size() == 0) {
         ALOGE("%s: bufferProducers must not be empty", __FUNCTION__);
@@ -1521,7 +1825,7 @@
 
         sp<Surface> surface;
         res = createSurfaceFromGbp(mStreamInfoMap[streamId], true /*isStreamInfoValid*/,
-                surface, bufferProducer);
+                surface, bufferProducer, physicalId);
 
         if (!res.isOk())
             return res;
@@ -1610,7 +1914,14 @@
     // Thread safe. Don't bother locking.
     sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
 
-    if (remoteCb != 0) {
+    // Composites can have multiple internal streams. Error notifications coming from such internal
+    // streams may need to remain within camera service.
+    bool skipClientNotification = false;
+    for (size_t i = 0; i < mCompositeStreamMap.size(); i++) {
+        skipClientNotification |= mCompositeStreamMap.valueAt(i)->onError(errorCode, resultExtras);
+    }
+
+    if ((remoteCb != 0) && (!skipClientNotification)) {
         remoteCb->onDeviceError(errorCode, resultExtras);
     }
 }
@@ -1644,6 +1955,10 @@
         remoteCb->onCaptureStarted(resultExtras, timestamp);
     }
     Camera2ClientBase::notifyShutter(resultExtras, timestamp);
+
+    for (size_t i = 0; i < mCompositeStreamMap.size(); i++) {
+        mCompositeStreamMap.valueAt(i)->onShutter(resultExtras, timestamp);
+    }
 }
 
 void CameraDeviceClient::notifyPrepared(int streamId) {
@@ -1677,9 +1992,12 @@
 
     // WORKAROUND: HAL refuses to disconnect while there's streams in flight
     {
-        mDevice->clearStreamingRequest();
-
+        int64_t lastFrameNumber;
         status_t code;
+        if ((code = mDevice->flush(&lastFrameNumber)) != OK) {
+            ALOGE("%s: flush failed with code 0x%x", __FUNCTION__, code);
+        }
+
         if ((code = mDevice->waitUntilDrained()) != OK) {
             ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__,
                   code);
@@ -1700,6 +2018,10 @@
         remoteCb->onResultReceived(result.mMetadata, result.mResultExtras,
                 result.mPhysicalMetadatas);
     }
+
+    for (size_t i = 0; i < mCompositeStreamMap.size(); i++) {
+        mCompositeStreamMap.valueAt(i)->onResultAvailable(result);
+    }
 }
 
 binder::Status CameraDeviceClient::checkPidStatus(const char* checkLocation) {
@@ -1716,7 +2038,7 @@
 // TODO: move to Camera2ClientBase
 bool CameraDeviceClient::enforceRequestPermissions(CameraMetadata& metadata) {
 
-    const int pid = IPCThreadState::self()->getCallingPid();
+    const int pid = CameraThreadState::getCallingPid();
     const int selfPid = getpid();
     camera_metadata_entry_t entry;
 
@@ -1755,7 +2077,7 @@
         String16 permissionString =
             String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
         if (!checkCallingPermission(permissionString)) {
-            const int uid = IPCThreadState::self()->getCallingUid();
+            const int uid = CameraThreadState::getCallingUid();
             ALOGE("Permission Denial: "
                   "can't disable transmit LED pid=%d, uid=%d", pid, uid);
             return false;
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 5aaf5aa..1c5abb0 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -20,13 +20,16 @@
 #include <android/hardware/camera2/BnCameraDeviceUser.h>
 #include <android/hardware/camera2/ICameraDeviceCallbacks.h>
 #include <camera/camera2/OutputConfiguration.h>
+#include <camera/camera2/SessionConfiguration.h>
 #include <camera/camera2/SubmitInfo.h>
 
 #include "CameraService.h"
 #include "common/FrameProcessorBase.h"
 #include "common/Camera2ClientBase.h"
+#include "CompositeStream.h"
 
 using android::camera3::OutputStreamInfo;
+using android::camera3::CompositeStream;
 
 namespace android {
 
@@ -89,6 +92,12 @@
     virtual binder::Status endConfigure(int operatingMode,
             const hardware::camera2::impl::CameraMetadataNative& sessionParams) override;
 
+    // Verify specific session configuration.
+    virtual binder::Status isSessionConfigurationSupported(
+            const SessionConfiguration& sessionConfiguration,
+            /*out*/
+            bool* streamStatus) override;
+
     // Returns -EBUSY if device is not idle or in error state
     virtual binder::Status deleteStream(int streamId) override;
 
@@ -230,6 +239,13 @@
 
     /** Utility members */
     binder::Status checkPidStatus(const char* checkLocation);
+    binder::Status checkOperatingModeLocked(int operatingMode) const;
+    binder::Status checkPhysicalCameraIdLocked(String8 physicalCameraId);
+    binder::Status checkSurfaceTypeLocked(size_t numBufferProducers, bool deferredConsumer,
+            int surfaceType) const;
+    static void mapStreamInfo(const OutputStreamInfo &streamInfo,
+            camera3_stream_rotation_t rotation, String8 physicalId,
+            hardware::camera::device::V3_4::Stream *stream /*out*/);
     bool enforceRequestPermissions(CameraMetadata& metadata);
 
     // Find the square of the euclidean distance between two points
@@ -258,7 +274,8 @@
     // Create a Surface from an IGraphicBufferProducer. Returns error if
     // IGraphicBufferProducer's property doesn't match with streamInfo
     binder::Status createSurfaceFromGbp(OutputStreamInfo& streamInfo, bool isStreamInfoValid,
-            sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp);
+            sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp,
+            const String8& physicalCameraId);
 
 
     // Utility method to insert the surface into SurfaceMap
@@ -299,7 +316,10 @@
     // stream ID -> outputStreamInfo mapping
     std::unordered_map<int32_t, OutputStreamInfo> mStreamInfoMap;
 
-    static const int32_t MAX_SURFACES_PER_STREAM = 2;
+    KeyedVector<sp<IBinder>, sp<CompositeStream>> mCompositeStreamMap;
+
+    static const int32_t MAX_SURFACES_PER_STREAM = 4;
+    sp<CameraProviderManager> mProviderManager;
 };
 
 }; // namespace android
diff --git a/services/camera/libcameraservice/api2/CompositeStream.cpp b/services/camera/libcameraservice/api2/CompositeStream.cpp
new file mode 100644
index 0000000..354eaf9
--- /dev/null
+++ b/services/camera/libcameraservice/api2/CompositeStream.cpp
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Camera3-CompositeStream"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+//#define LOG_NDEBUG 0
+
+#include <utils/Log.h>
+#include <utils/Trace.h>
+
+#include "common/CameraDeviceBase.h"
+#include "CameraDeviceClient.h"
+#include "CompositeStream.h"
+
+namespace android {
+namespace camera3 {
+
+CompositeStream::CompositeStream(wp<CameraDeviceBase> device,
+        wp<hardware::camera2::ICameraDeviceCallbacks> cb) :
+        mDevice(device),
+        mRemoteCallback(cb),
+        mNumPartialResults(1),
+        mErrorState(false) {
+    sp<CameraDeviceBase> cameraDevice = device.promote();
+    if (cameraDevice.get() != nullptr) {
+        CameraMetadata staticInfo = cameraDevice->info();
+        camera_metadata_entry_t entry = staticInfo.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
+        if (entry.count > 0) {
+            mNumPartialResults = entry.data.i32[0];
+        }
+    }
+}
+
+status_t CompositeStream::createStream(const std::vector<sp<Surface>>& consumers,
+        bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
+        camera3_stream_rotation_t rotation, int * id, const String8& physicalCameraId,
+        std::vector<int> * surfaceIds, int streamSetId, bool isShared) {
+    if (hasDeferredConsumer) {
+        ALOGE("%s: Deferred consumers not supported in case of composite streams!",
+                __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    if (streamSetId != camera3::CAMERA3_STREAM_ID_INVALID) {
+        ALOGE("%s: Surface groups not supported in case of composite streams!",
+                __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    if (isShared) {
+        ALOGE("%s: Shared surfaces not supported in case of composite streams!",
+                __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    return createInternalStreams(consumers, hasDeferredConsumer, width, height, format, rotation, id,
+            physicalCameraId, surfaceIds, streamSetId, isShared);
+}
+
+status_t CompositeStream::deleteStream() {
+    {
+        Mutex::Autolock l(mMutex);
+        mPendingCaptureResults.clear();
+        mCaptureResults.clear();
+        mFrameNumberMap.clear();
+        mErrorFrameNumbers.clear();
+    }
+
+    return deleteInternalStreams();
+}
+
+void CompositeStream::onBufferRequestForFrameNumber(uint64_t frameNumber, int streamId,
+        const CameraMetadata& /*settings*/) {
+    Mutex::Autolock l(mMutex);
+    if (!mErrorState && (streamId == getStreamId())) {
+        mPendingCaptureResults.emplace(frameNumber, CameraMetadata());
+    }
+}
+
+void CompositeStream::onBufferReleased(const BufferInfo& bufferInfo) {
+    Mutex::Autolock l(mMutex);
+    if (!mErrorState && !bufferInfo.mError) {
+        mFrameNumberMap.emplace(bufferInfo.mFrameNumber, bufferInfo.mTimestamp);
+        mInputReadyCondition.signal();
+    }
+}
+
+void CompositeStream::eraseResult(int64_t frameNumber) {
+    Mutex::Autolock l(mMutex);
+
+    auto it = mPendingCaptureResults.find(frameNumber);
+    if (it == mPendingCaptureResults.end()) {
+        return;
+    }
+
+    it = mPendingCaptureResults.erase(it);
+}
+
+void CompositeStream::onResultAvailable(const CaptureResult& result) {
+    bool resultError = false;
+    {
+        Mutex::Autolock l(mMutex);
+
+        uint64_t frameNumber = result.mResultExtras.frameNumber;
+        bool resultReady = false;
+        auto it = mPendingCaptureResults.find(frameNumber);
+        if (it != mPendingCaptureResults.end()) {
+            it->second.append(result.mMetadata);
+            if (result.mResultExtras.partialResultCount >= mNumPartialResults) {
+                auto entry = it->second.find(ANDROID_SENSOR_TIMESTAMP);
+                if (entry.count == 1) {
+                    auto ts = entry.data.i64[0];
+                    mCaptureResults.emplace(ts, std::make_tuple(frameNumber, it->second));
+                    resultReady = true;
+                } else {
+                    ALOGE("%s: Timestamp metadata entry missing for frameNumber: %" PRIu64,
+                            __FUNCTION__, frameNumber);
+                    resultError = true;
+                }
+                mPendingCaptureResults.erase(it);
+            }
+        }
+
+        if (resultReady) {
+            mInputReadyCondition.signal();
+        }
+    }
+
+    if (resultError) {
+        onResultError(result.mResultExtras);
+    }
+}
+
+void CompositeStream::flagAnErrorFrameNumber(int64_t frameNumber) {
+    Mutex::Autolock l(mMutex);
+    mErrorFrameNumbers.emplace(frameNumber);
+    mInputReadyCondition.signal();
+}
+
+status_t CompositeStream::registerCompositeStreamListener(int32_t streamId) {
+    sp<CameraDeviceBase> device = mDevice.promote();
+    if (device.get() == nullptr) {
+        return NO_INIT;
+    }
+
+    auto ret = device->addBufferListenerForStream(streamId, this);
+    if (ret != OK) {
+        ALOGE("%s: Failed to register composite stream listener!", __FUNCTION__);
+    }
+
+    return ret;
+}
+
+bool CompositeStream::onError(int32_t errorCode, const CaptureResultExtras& resultExtras) {
+    auto ret = false;
+    switch (errorCode) {
+        case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT:
+            onResultError(resultExtras);
+            break;
+        case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER:
+            ret = onStreamBufferError(resultExtras);
+            break;
+        case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST:
+            // Invalid request, this shouldn't affect composite streams.
+            break;
+        default:
+            ALOGE("%s: Unrecoverable error: %d detected!", __FUNCTION__, errorCode);
+            Mutex::Autolock l(mMutex);
+            mErrorState = true;
+            break;
+    }
+
+    return ret;
+}
+
+void CompositeStream::notifyError(int64_t frameNumber) {
+    sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb =
+        mRemoteCallback.promote();
+
+    if ((frameNumber >= 0) && (remoteCb.get() != nullptr)) {
+        CaptureResultExtras extras;
+        extras.errorStreamId = getStreamId();
+        extras.frameNumber = frameNumber;
+        remoteCb->onDeviceError(
+                hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER,
+                extras);
+    }
+}
+
+}; // namespace camera3
+}; // namespace android
diff --git a/services/camera/libcameraservice/api2/CompositeStream.h b/services/camera/libcameraservice/api2/CompositeStream.h
new file mode 100644
index 0000000..a401a82
--- /dev/null
+++ b/services/camera/libcameraservice/api2/CompositeStream.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SERVERS_CAMERA_CAMERA3_COMPOSITE_STREAM_H
+#define ANDROID_SERVERS_CAMERA_CAMERA3_COMPOSITE_STREAM_H
+
+#include <set>
+#include <unordered_map>
+
+#include <android/hardware/camera2/ICameraDeviceCallbacks.h>
+#include <camera/CameraMetadata.h>
+#include <camera/camera2/OutputConfiguration.h>
+#include <gui/IProducerListener.h>
+#include "common/CameraDeviceBase.h"
+#include "device3/Camera3StreamInterface.h"
+
+namespace android {
+
+class CameraDeviceClient;
+class CameraMetadata;
+class Surface;
+
+namespace camera3 {
+
+class CompositeStream : public camera3::Camera3StreamBufferListener {
+
+public:
+    CompositeStream(wp<CameraDeviceBase> device, wp<hardware::camera2::ICameraDeviceCallbacks> cb);
+    virtual ~CompositeStream() {}
+
+    status_t createStream(const std::vector<sp<Surface>>& consumers,
+            bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
+            camera3_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+            std::vector<int> *surfaceIds, int streamSetId, bool isShared);
+
+    status_t deleteStream();
+
+    // Create and register all internal camera streams.
+    virtual status_t createInternalStreams(const std::vector<sp<Surface>>& consumers,
+            bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
+            camera3_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+            std::vector<int> *surfaceIds, int streamSetId, bool isShared) = 0;
+
+    // Release all internal streams and corresponding resources.
+    virtual status_t deleteInternalStreams() = 0;
+
+    // Stream configuration completed.
+    virtual status_t configureStream() = 0;
+
+    // Insert the internal composite stream id in the user capture request.
+    virtual status_t insertGbp(SurfaceMap* /*out*/outSurfaceMap,
+            Vector<int32_t>* /*out*/outputStreamIds, int32_t* /*out*/currentStreamId) = 0;
+
+    // Return composite stream id.
+    virtual int getStreamId() = 0;
+
+    // Notify when shutter notify is triggered
+    virtual void onShutter(const CaptureResultExtras& /*resultExtras*/, nsecs_t /*timestamp*/) {}
+
+    void onResultAvailable(const CaptureResult& result);
+    bool onError(int32_t errorCode, const CaptureResultExtras& resultExtras);
+
+    // Camera3StreamBufferListener implementation
+    void onBufferAcquired(const BufferInfo& /*bufferInfo*/) override { /*Empty for now */ }
+    void onBufferReleased(const BufferInfo& bufferInfo) override;
+    void onBufferRequestForFrameNumber(uint64_t frameNumber, int streamId,
+            const CameraMetadata& settings) override;
+
+protected:
+    struct ProducerListener : public BnProducerListener {
+        // ProducerListener impementation
+        void onBufferReleased() override { /*No impl. for now*/ };
+    };
+
+    status_t registerCompositeStreamListener(int32_t streamId);
+    void eraseResult(int64_t frameNumber);
+    void flagAnErrorFrameNumber(int64_t frameNumber);
+    void notifyError(int64_t frameNumber);
+
+    // Subclasses should check for buffer errors from internal streams and return 'true' in
+    // case the error notification should remain within camera service.
+    virtual bool onStreamBufferError(const CaptureResultExtras& resultExtras) = 0;
+
+    // Subclasses can decide how to handle result errors depending on whether or not the
+    // internal processing needs result data.
+    virtual void onResultError(const CaptureResultExtras& resultExtras) = 0;
+
+    // Device and/or service is in unrecoverable error state.
+    // Composite streams should behave accordingly.
+    void enableErrorState();
+
+    wp<CameraDeviceBase>   mDevice;
+    wp<hardware::camera2::ICameraDeviceCallbacks> mRemoteCallback;
+
+    mutable Mutex          mMutex;
+    Condition              mInputReadyCondition;
+    int32_t                mNumPartialResults;
+    bool                   mErrorState;
+
+    // Frame number to capture result map of partial pending request results.
+    std::unordered_map<uint64_t, CameraMetadata> mPendingCaptureResults;
+
+    // Timestamp to capture (frame number, result) map of completed pending request results.
+    std::unordered_map<int64_t, std::tuple<int64_t, CameraMetadata>> mCaptureResults;
+
+    // Frame number to timestamp map
+    std::unordered_map<int64_t, int64_t> mFrameNumberMap;
+
+    // Keeps a set buffer/result frame numbers for any errors detected during processing.
+    std::set<int64_t> mErrorFrameNumbers;
+
+};
+
+}; //namespace camera3
+}; //namespace android
+
+#endif
diff --git a/services/camera/libcameraservice/api2/DepthCompositeStream.cpp b/services/camera/libcameraservice/api2/DepthCompositeStream.cpp
new file mode 100644
index 0000000..8ebaa2b
--- /dev/null
+++ b/services/camera/libcameraservice/api2/DepthCompositeStream.cpp
@@ -0,0 +1,822 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Camera3-DepthCompositeStream"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+//#define LOG_NDEBUG 0
+
+#include "api1/client2/JpegProcessor.h"
+#include "common/CameraProviderManager.h"
+#include "dlfcn.h"
+#include <gui/Surface.h>
+#include <utils/Log.h>
+#include <utils/Trace.h>
+
+#include "DepthCompositeStream.h"
+
+namespace android {
+namespace camera3 {
+
+DepthCompositeStream::DepthCompositeStream(wp<CameraDeviceBase> device,
+        wp<hardware::camera2::ICameraDeviceCallbacks> cb) :
+        CompositeStream(device, cb),
+        mBlobStreamId(-1),
+        mBlobSurfaceId(-1),
+        mDepthStreamId(-1),
+        mDepthSurfaceId(-1),
+        mBlobWidth(0),
+        mBlobHeight(0),
+        mDepthBufferAcquired(false),
+        mBlobBufferAcquired(false),
+        mProducerListener(new ProducerListener()),
+        mMaxJpegSize(-1),
+        mIsLogicalCamera(false),
+        mDepthPhotoLibHandle(nullptr),
+        mDepthPhotoProcess(nullptr) {
+    sp<CameraDeviceBase> cameraDevice = device.promote();
+    if (cameraDevice.get() != nullptr) {
+        CameraMetadata staticInfo = cameraDevice->info();
+        auto entry = staticInfo.find(ANDROID_JPEG_MAX_SIZE);
+        if (entry.count > 0) {
+            mMaxJpegSize = entry.data.i32[0];
+        } else {
+            ALOGW("%s: Maximum jpeg size absent from camera characteristics", __FUNCTION__);
+        }
+
+        entry = staticInfo.find(ANDROID_LENS_INTRINSIC_CALIBRATION);
+        if (entry.count == 5) {
+            mIntrinsicCalibration.reserve(5);
+            mIntrinsicCalibration.insert(mIntrinsicCalibration.end(), entry.data.f,
+                    entry.data.f + 5);
+        } else {
+            ALOGW("%s: Intrinsic calibration absent from camera characteristics!", __FUNCTION__);
+        }
+
+        entry = staticInfo.find(ANDROID_LENS_DISTORTION);
+        if (entry.count == 5) {
+            mLensDistortion.reserve(5);
+            mLensDistortion.insert(mLensDistortion.end(), entry.data.f, entry.data.f + 5);
+        } else {
+            ALOGW("%s: Lens distortion absent from camera characteristics!", __FUNCTION__);
+        }
+
+        entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
+        for (size_t i = 0; i < entry.count; ++i) {
+            uint8_t capability = entry.data.u8[i];
+            if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
+                mIsLogicalCamera = true;
+                break;
+            }
+        }
+
+        getSupportedDepthSizes(staticInfo, &mSupportedDepthSizes);
+
+        mDepthPhotoLibHandle = dlopen(camera3::kDepthPhotoLibrary, RTLD_NOW | RTLD_LOCAL);
+        if (mDepthPhotoLibHandle != nullptr) {
+            mDepthPhotoProcess = reinterpret_cast<camera3::process_depth_photo_frame> (
+                    dlsym(mDepthPhotoLibHandle, camera3::kDepthPhotoProcessFunction));
+            if (mDepthPhotoProcess == nullptr) {
+                ALOGE("%s: Failed to link to depth photo process function: %s", __FUNCTION__,
+                        dlerror());
+            }
+        } else {
+            ALOGE("%s: Failed to link to depth photo library: %s", __FUNCTION__, dlerror());
+        }
+
+    }
+}
+
+DepthCompositeStream::~DepthCompositeStream() {
+    mBlobConsumer.clear(),
+    mBlobSurface.clear(),
+    mBlobStreamId = -1;
+    mBlobSurfaceId = -1;
+    mDepthConsumer.clear();
+    mDepthSurface.clear();
+    mDepthConsumer = nullptr;
+    mDepthSurface = nullptr;
+    if (mDepthPhotoLibHandle != nullptr) {
+        dlclose(mDepthPhotoLibHandle);
+        mDepthPhotoLibHandle = nullptr;
+    }
+    mDepthPhotoProcess = nullptr;
+}
+
+void DepthCompositeStream::compilePendingInputLocked() {
+    CpuConsumer::LockedBuffer imgBuffer;
+
+    while (!mInputJpegBuffers.empty() && !mBlobBufferAcquired) {
+        auto it = mInputJpegBuffers.begin();
+        auto res = mBlobConsumer->lockNextBuffer(&imgBuffer);
+        if (res == NOT_ENOUGH_DATA) {
+            // Can not lock any more buffers.
+            break;
+        } else if (res != OK) {
+            ALOGE("%s: Error locking blob image buffer: %s (%d)", __FUNCTION__,
+                    strerror(-res), res);
+            mPendingInputFrames[*it].error = true;
+            mInputJpegBuffers.erase(it);
+            continue;
+        }
+
+        if (*it != imgBuffer.timestamp) {
+            ALOGW("%s: Expecting jpeg buffer with time stamp: %" PRId64 " received buffer with "
+                    "time stamp: %" PRId64, __FUNCTION__, *it, imgBuffer.timestamp);
+        }
+
+        if ((mPendingInputFrames.find(imgBuffer.timestamp) != mPendingInputFrames.end()) &&
+                (mPendingInputFrames[imgBuffer.timestamp].error)) {
+            mBlobConsumer->unlockBuffer(imgBuffer);
+        } else {
+            mPendingInputFrames[imgBuffer.timestamp].jpegBuffer = imgBuffer;
+            mBlobBufferAcquired = true;
+        }
+        mInputJpegBuffers.erase(it);
+    }
+
+    while (!mInputDepthBuffers.empty() && !mDepthBufferAcquired) {
+        auto it = mInputDepthBuffers.begin();
+        auto res = mDepthConsumer->lockNextBuffer(&imgBuffer);
+        if (res == NOT_ENOUGH_DATA) {
+            // Can not lock any more buffers.
+            break;
+        } else if (res != OK) {
+            ALOGE("%s: Error receiving depth image buffer: %s (%d)", __FUNCTION__,
+                    strerror(-res), res);
+            mPendingInputFrames[*it].error = true;
+            mInputDepthBuffers.erase(it);
+            continue;
+        }
+
+        if (*it != imgBuffer.timestamp) {
+            ALOGW("%s: Expecting depth buffer with time stamp: %" PRId64 " received buffer with "
+                    "time stamp: %" PRId64, __FUNCTION__, *it, imgBuffer.timestamp);
+        }
+
+        if ((mPendingInputFrames.find(imgBuffer.timestamp) != mPendingInputFrames.end()) &&
+                (mPendingInputFrames[imgBuffer.timestamp].error)) {
+            mDepthConsumer->unlockBuffer(imgBuffer);
+        } else {
+            mPendingInputFrames[imgBuffer.timestamp].depthBuffer = imgBuffer;
+            mDepthBufferAcquired = true;
+        }
+        mInputDepthBuffers.erase(it);
+    }
+
+    while (!mCaptureResults.empty()) {
+        auto it = mCaptureResults.begin();
+        // Negative timestamp indicates that something went wrong during the capture result
+        // collection process.
+        if (it->first >= 0) {
+            mPendingInputFrames[it->first].frameNumber = std::get<0>(it->second);
+            mPendingInputFrames[it->first].result = std::get<1>(it->second);
+        }
+        mCaptureResults.erase(it);
+    }
+
+    while (!mFrameNumberMap.empty()) {
+        auto it = mFrameNumberMap.begin();
+        mPendingInputFrames[it->second].frameNumber = it->first;
+        mFrameNumberMap.erase(it);
+    }
+
+    auto it = mErrorFrameNumbers.begin();
+    while (it != mErrorFrameNumbers.end()) {
+        bool frameFound = false;
+        for (auto &inputFrame : mPendingInputFrames) {
+            if (inputFrame.second.frameNumber == *it) {
+                inputFrame.second.error = true;
+                frameFound = true;
+                break;
+            }
+        }
+
+        if (frameFound) {
+            it = mErrorFrameNumbers.erase(it);
+        } else {
+            ALOGW("%s: Not able to find failing input with frame number: %" PRId64, __FUNCTION__,
+                    *it);
+            it++;
+        }
+    }
+}
+
+bool DepthCompositeStream::getNextReadyInputLocked(int64_t *currentTs /*inout*/) {
+    if (currentTs == nullptr) {
+        return false;
+    }
+
+    bool newInputAvailable = false;
+    for (const auto& it : mPendingInputFrames) {
+        if ((!it.second.error) && (it.second.depthBuffer.data != nullptr) &&
+                (it.second.jpegBuffer.data != nullptr) && (it.first < *currentTs)) {
+            *currentTs = it.first;
+            newInputAvailable = true;
+        }
+    }
+
+    return newInputAvailable;
+}
+
+int64_t DepthCompositeStream::getNextFailingInputLocked(int64_t *currentTs /*inout*/) {
+    int64_t ret = -1;
+    if (currentTs == nullptr) {
+        return ret;
+    }
+
+    for (const auto& it : mPendingInputFrames) {
+        if (it.second.error && !it.second.errorNotified && (it.first < *currentTs)) {
+            *currentTs = it.first;
+            ret = it.second.frameNumber;
+        }
+    }
+
+    return ret;
+}
+
+status_t DepthCompositeStream::processInputFrame(const InputFrame &inputFrame) {
+    status_t res;
+    sp<ANativeWindow> outputANW = mOutputSurface;
+    ANativeWindowBuffer *anb;
+    int fenceFd;
+    void *dstBuffer;
+
+    auto jpegSize = android::camera2::JpegProcessor::findJpegSize(inputFrame.jpegBuffer.data,
+            inputFrame.jpegBuffer.width);
+    if (jpegSize == 0) {
+        ALOGW("%s: Failed to find input jpeg size, default to using entire buffer!", __FUNCTION__);
+        jpegSize = inputFrame.jpegBuffer.width;
+    }
+
+    size_t maxDepthJpegSize;
+    if (mMaxJpegSize > 0) {
+        maxDepthJpegSize = mMaxJpegSize;
+    } else {
+        maxDepthJpegSize = std::max<size_t> (jpegSize,
+                inputFrame.depthBuffer.width * inputFrame.depthBuffer.height * 3 / 2);
+    }
+    uint8_t jpegQuality = 100;
+    auto entry = inputFrame.result.find(ANDROID_JPEG_QUALITY);
+    if (entry.count > 0) {
+        jpegQuality = entry.data.u8[0];
+    }
+
+    // The final depth photo will consist of the main jpeg buffer, the depth map buffer (also in
+    // jpeg format) and confidence map (jpeg as well). Assume worst case that all 3 jpeg need
+    // max jpeg size.
+    size_t finalJpegBufferSize = maxDepthJpegSize * 3;
+
+    if ((res = native_window_set_buffers_dimensions(mOutputSurface.get(), finalJpegBufferSize, 1))
+            != OK) {
+        ALOGE("%s: Unable to configure stream buffer dimensions"
+                " %zux%u for stream %d", __FUNCTION__, finalJpegBufferSize, 1U, mBlobStreamId);
+        return res;
+    }
+
+    res = outputANW->dequeueBuffer(mOutputSurface.get(), &anb, &fenceFd);
+    if (res != OK) {
+        ALOGE("%s: Error retrieving output buffer: %s (%d)", __FUNCTION__, strerror(-res),
+                res);
+        return res;
+    }
+
+    sp<GraphicBuffer> gb = GraphicBuffer::from(anb);
+    res = gb->lockAsync(GRALLOC_USAGE_SW_WRITE_OFTEN, &dstBuffer, fenceFd);
+    if (res != OK) {
+        ALOGE("%s: Error trying to lock output buffer fence: %s (%d)", __FUNCTION__,
+                strerror(-res), res);
+        outputANW->cancelBuffer(mOutputSurface.get(), anb, /*fence*/ -1);
+        return res;
+    }
+
+    if ((gb->getWidth() < finalJpegBufferSize) || (gb->getHeight() != 1)) {
+        ALOGE("%s: Blob buffer size mismatch, expected %dx%d received %zux%u", __FUNCTION__,
+                gb->getWidth(), gb->getHeight(), finalJpegBufferSize, 1U);
+        outputANW->cancelBuffer(mOutputSurface.get(), anb, /*fence*/ -1);
+        return BAD_VALUE;
+    }
+
+    DepthPhotoInputFrame depthPhoto;
+    depthPhoto.mMainJpegBuffer = reinterpret_cast<const char*> (inputFrame.jpegBuffer.data);
+    depthPhoto.mMainJpegWidth = mBlobWidth;
+    depthPhoto.mMainJpegHeight = mBlobHeight;
+    depthPhoto.mMainJpegSize = jpegSize;
+    depthPhoto.mDepthMapBuffer = reinterpret_cast<uint16_t*> (inputFrame.depthBuffer.data);
+    depthPhoto.mDepthMapWidth = inputFrame.depthBuffer.width;
+    depthPhoto.mDepthMapHeight = inputFrame.depthBuffer.height;
+    depthPhoto.mDepthMapStride = inputFrame.depthBuffer.stride;
+    depthPhoto.mJpegQuality = jpegQuality;
+    depthPhoto.mIsLogical = mIsLogicalCamera;
+    depthPhoto.mMaxJpegSize = maxDepthJpegSize;
+    // The camera intrinsic calibration layout is as follows:
+    // [focalLengthX, focalLengthY, opticalCenterX, opticalCenterY, skew]
+    if (mIntrinsicCalibration.size() == 5) {
+        memcpy(depthPhoto.mIntrinsicCalibration, mIntrinsicCalibration.data(),
+                sizeof(depthPhoto.mIntrinsicCalibration));
+        depthPhoto.mIsIntrinsicCalibrationValid = 1;
+    } else {
+        depthPhoto.mIsIntrinsicCalibrationValid = 0;
+    }
+    // The camera lens distortion contains the following lens correction coefficients.
+    // [kappa_1, kappa_2, kappa_3 kappa_4, kappa_5]
+    if (mLensDistortion.size() == 5) {
+        memcpy(depthPhoto.mLensDistortion, mLensDistortion.data(),
+                sizeof(depthPhoto.mLensDistortion));
+        depthPhoto.mIsLensDistortionValid = 1;
+    } else {
+        depthPhoto.mIsLensDistortionValid = 0;
+    }
+    entry = inputFrame.result.find(ANDROID_JPEG_ORIENTATION);
+    if (entry.count > 0) {
+        // The camera jpeg orientation values must be within [0, 90, 180, 270].
+        switch (entry.data.i32[0]) {
+            case 0:
+            case 90:
+            case 180:
+            case 270:
+                depthPhoto.mOrientation = static_cast<DepthPhotoOrientation> (entry.data.i32[0]);
+                break;
+            default:
+                ALOGE("%s: Unexpected jpeg orientation value: %d, default to 0 degrees",
+                        __FUNCTION__, entry.data.i32[0]);
+        }
+    }
+
+    size_t actualJpegSize = 0;
+    res = mDepthPhotoProcess(depthPhoto, finalJpegBufferSize, dstBuffer, &actualJpegSize);
+    if (res != 0) {
+        ALOGE("%s: Depth photo processing failed: %s (%d)", __FUNCTION__, strerror(-res), res);
+        outputANW->cancelBuffer(mOutputSurface.get(), anb, /*fence*/ -1);
+        return res;
+    }
+
+    size_t finalJpegSize = actualJpegSize + sizeof(struct camera3_jpeg_blob);
+    if (finalJpegSize > finalJpegBufferSize) {
+        ALOGE("%s: Final jpeg buffer not large enough for the jpeg blob header", __FUNCTION__);
+        outputANW->cancelBuffer(mOutputSurface.get(), anb, /*fence*/ -1);
+        return NO_MEMORY;
+    }
+
+    ALOGV("%s: Final jpeg size: %zu", __func__, finalJpegSize);
+    uint8_t* header = static_cast<uint8_t *> (dstBuffer) +
+        (gb->getWidth() - sizeof(struct camera3_jpeg_blob));
+    struct camera3_jpeg_blob *blob = reinterpret_cast<struct camera3_jpeg_blob*> (header);
+    blob->jpeg_blob_id = CAMERA3_JPEG_BLOB_ID;
+    blob->jpeg_size = actualJpegSize;
+    outputANW->queueBuffer(mOutputSurface.get(), anb, /*fence*/ -1);
+
+    return res;
+}
+
+void DepthCompositeStream::releaseInputFrameLocked(InputFrame *inputFrame /*out*/) {
+    if (inputFrame == nullptr) {
+        return;
+    }
+
+    if (inputFrame->depthBuffer.data != nullptr) {
+        mDepthConsumer->unlockBuffer(inputFrame->depthBuffer);
+        inputFrame->depthBuffer.data = nullptr;
+        mDepthBufferAcquired = false;
+    }
+
+    if (inputFrame->jpegBuffer.data != nullptr) {
+        mBlobConsumer->unlockBuffer(inputFrame->jpegBuffer);
+        inputFrame->jpegBuffer.data = nullptr;
+        mBlobBufferAcquired = false;
+    }
+
+    if ((inputFrame->error || mErrorState) && !inputFrame->errorNotified) {
+        notifyError(inputFrame->frameNumber);
+        inputFrame->errorNotified = true;
+    }
+}
+
+void DepthCompositeStream::releaseInputFramesLocked(int64_t currentTs) {
+    auto it = mPendingInputFrames.begin();
+    while (it != mPendingInputFrames.end()) {
+        if (it->first <= currentTs) {
+            releaseInputFrameLocked(&it->second);
+            it = mPendingInputFrames.erase(it);
+        } else {
+            it++;
+        }
+    }
+}
+
+bool DepthCompositeStream::threadLoop() {
+    int64_t currentTs = INT64_MAX;
+    bool newInputAvailable = false;
+
+    {
+        Mutex::Autolock l(mMutex);
+
+        if (mErrorState) {
+            // In case we landed in error state, return any pending buffers and
+            // halt all further processing.
+            compilePendingInputLocked();
+            releaseInputFramesLocked(currentTs);
+            return false;
+        }
+
+        while (!newInputAvailable) {
+            compilePendingInputLocked();
+            newInputAvailable = getNextReadyInputLocked(&currentTs);
+            if (!newInputAvailable) {
+                auto failingFrameNumber = getNextFailingInputLocked(&currentTs);
+                if (failingFrameNumber >= 0) {
+                    // We cannot erase 'mPendingInputFrames[currentTs]' at this point because it is
+                    // possible for two internal stream buffers to fail. In such scenario the
+                    // composite stream should notify the client about a stream buffer error only
+                    // once and this information is kept within 'errorNotified'.
+                    // Any present failed input frames will be removed on a subsequent call to
+                    // 'releaseInputFramesLocked()'.
+                    releaseInputFrameLocked(&mPendingInputFrames[currentTs]);
+                    currentTs = INT64_MAX;
+                }
+
+                auto ret = mInputReadyCondition.waitRelative(mMutex, kWaitDuration);
+                if (ret == TIMED_OUT) {
+                    return true;
+                } else if (ret != OK) {
+                    ALOGE("%s: Timed wait on condition failed: %s (%d)", __FUNCTION__,
+                            strerror(-ret), ret);
+                    return false;
+                }
+            }
+        }
+    }
+
+    auto res = processInputFrame(mPendingInputFrames[currentTs]);
+    Mutex::Autolock l(mMutex);
+    if (res != OK) {
+        ALOGE("%s: Failed processing frame with timestamp: %" PRIu64 ": %s (%d)", __FUNCTION__,
+                currentTs, strerror(-res), res);
+        mPendingInputFrames[currentTs].error = true;
+    }
+
+    releaseInputFramesLocked(currentTs);
+
+    return true;
+}
+
+bool DepthCompositeStream::isDepthCompositeStream(const sp<Surface> &surface) {
+    ANativeWindow *anw = surface.get();
+    status_t err;
+    int format;
+    if ((err = anw->query(anw, NATIVE_WINDOW_FORMAT, &format)) != OK) {
+        String8 msg = String8::format("Failed to query Surface format: %s (%d)", strerror(-err),
+                err);
+        ALOGE("%s: %s", __FUNCTION__, msg.string());
+        return false;
+    }
+
+    int dataspace;
+    if ((err = anw->query(anw, NATIVE_WINDOW_DEFAULT_DATASPACE, &dataspace)) != OK) {
+        String8 msg = String8::format("Failed to query Surface dataspace: %s (%d)", strerror(-err),
+                err);
+        ALOGE("%s: %s", __FUNCTION__, msg.string());
+        return false;
+    }
+
+    if ((format == HAL_PIXEL_FORMAT_BLOB) && (dataspace == HAL_DATASPACE_DYNAMIC_DEPTH)) {
+        return true;
+    }
+
+    return false;
+}
+
+status_t DepthCompositeStream::createInternalStreams(const std::vector<sp<Surface>>& consumers,
+        bool /*hasDeferredConsumer*/, uint32_t width, uint32_t height, int format,
+        camera3_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+        std::vector<int> *surfaceIds, int /*streamSetId*/, bool /*isShared*/) {
+    if (mSupportedDepthSizes.empty()) {
+        ALOGE("%s: This camera device doesn't support any depth map streams!", __FUNCTION__);
+        return INVALID_OPERATION;
+    }
+
+    size_t depthWidth, depthHeight;
+    auto ret = getMatchingDepthSize(width, height, mSupportedDepthSizes, &depthWidth, &depthHeight);
+    if (ret != OK) {
+        ALOGE("%s: Failed to find an appropriate depth stream size!", __FUNCTION__);
+        return ret;
+    }
+
+    sp<CameraDeviceBase> device = mDevice.promote();
+    if (!device.get()) {
+        ALOGE("%s: Invalid camera device!", __FUNCTION__);
+        return NO_INIT;
+    }
+
+    sp<IGraphicBufferProducer> producer;
+    sp<IGraphicBufferConsumer> consumer;
+    BufferQueue::createBufferQueue(&producer, &consumer);
+    mBlobConsumer = new CpuConsumer(consumer, /*maxLockedBuffers*/1, /*controlledByApp*/ true);
+    mBlobConsumer->setFrameAvailableListener(this);
+    mBlobConsumer->setName(String8("Camera3-JpegCompositeStream"));
+    mBlobSurface = new Surface(producer);
+
+    ret = device->createStream(mBlobSurface, width, height, format, kJpegDataSpace, rotation,
+            id, physicalCameraId, surfaceIds);
+    if (ret == OK) {
+        mBlobStreamId = *id;
+        mBlobSurfaceId = (*surfaceIds)[0];
+        mOutputSurface = consumers[0];
+    } else {
+        return ret;
+    }
+
+    BufferQueue::createBufferQueue(&producer, &consumer);
+    mDepthConsumer = new CpuConsumer(consumer, /*maxLockedBuffers*/ 1, /*controlledByApp*/ true);
+    mDepthConsumer->setFrameAvailableListener(this);
+    mDepthConsumer->setName(String8("Camera3-DepthCompositeStream"));
+    mDepthSurface = new Surface(producer);
+    std::vector<int> depthSurfaceId;
+    ret = device->createStream(mDepthSurface, depthWidth, depthHeight, kDepthMapPixelFormat,
+            kDepthMapDataSpace, rotation, &mDepthStreamId, physicalCameraId, &depthSurfaceId);
+    if (ret == OK) {
+        mDepthSurfaceId = depthSurfaceId[0];
+    } else {
+        return ret;
+    }
+
+    ret = registerCompositeStreamListener(getStreamId());
+    if (ret != OK) {
+        ALOGE("%s: Failed to register blob stream listener!", __FUNCTION__);
+        return ret;
+    }
+
+    ret = registerCompositeStreamListener(mDepthStreamId);
+    if (ret != OK) {
+        ALOGE("%s: Failed to register depth stream listener!", __FUNCTION__);
+        return ret;
+    }
+
+    mBlobWidth = width;
+    mBlobHeight = height;
+
+    return ret;
+}
+
+status_t DepthCompositeStream::configureStream() {
+    if (isRunning()) {
+        // Processing thread is already running, nothing more to do.
+        return NO_ERROR;
+    }
+
+    if ((mDepthPhotoLibHandle == nullptr) || (mDepthPhotoProcess == nullptr)) {
+        ALOGE("%s: Depth photo library is not present!", __FUNCTION__);
+        return NO_INIT;
+    }
+
+    if (mOutputSurface.get() == nullptr) {
+        ALOGE("%s: No valid output surface set!", __FUNCTION__);
+        return NO_INIT;
+    }
+
+    auto res = mOutputSurface->connect(NATIVE_WINDOW_API_CAMERA, mProducerListener);
+    if (res != OK) {
+        ALOGE("%s: Unable to connect to native window for stream %d",
+                __FUNCTION__, mBlobStreamId);
+        return res;
+    }
+
+    if ((res = native_window_set_buffers_format(mOutputSurface.get(), HAL_PIXEL_FORMAT_BLOB))
+            != OK) {
+        ALOGE("%s: Unable to configure stream buffer format for stream %d", __FUNCTION__,
+                mBlobStreamId);
+        return res;
+    }
+
+    int maxProducerBuffers;
+    ANativeWindow *anw = mBlobSurface.get();
+    if ((res = anw->query(anw, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxProducerBuffers)) != OK) {
+        ALOGE("%s: Unable to query consumer undequeued"
+                " buffer count for stream %d", __FUNCTION__, mBlobStreamId);
+        return res;
+    }
+
+    ANativeWindow *anwConsumer = mOutputSurface.get();
+    int maxConsumerBuffers;
+    if ((res = anwConsumer->query(anwConsumer, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
+                    &maxConsumerBuffers)) != OK) {
+        ALOGE("%s: Unable to query consumer undequeued"
+                " buffer count for stream %d", __FUNCTION__, mBlobStreamId);
+        return res;
+    }
+
+    if ((res = native_window_set_buffer_count(
+                    anwConsumer, maxProducerBuffers + maxConsumerBuffers)) != OK) {
+        ALOGE("%s: Unable to set buffer count for stream %d", __FUNCTION__, mBlobStreamId);
+        return res;
+    }
+
+    run("DepthCompositeStreamProc");
+
+    return NO_ERROR;
+}
+
+status_t DepthCompositeStream::deleteInternalStreams() {
+    // The 'CameraDeviceClient' parent will delete the blob stream
+    requestExit();
+
+    auto ret = join();
+    if (ret != OK) {
+        ALOGE("%s: Failed to join with the main processing thread: %s (%d)", __FUNCTION__,
+                strerror(-ret), ret);
+    }
+
+    sp<CameraDeviceBase> device = mDevice.promote();
+    if (!device.get()) {
+        ALOGE("%s: Invalid camera device!", __FUNCTION__);
+        return NO_INIT;
+    }
+
+    if (mDepthStreamId >= 0) {
+        ret = device->deleteStream(mDepthStreamId);
+        mDepthStreamId = -1;
+    }
+
+    if (mOutputSurface != nullptr) {
+        mOutputSurface->disconnect(NATIVE_WINDOW_API_CAMERA);
+        mOutputSurface.clear();
+    }
+
+    return ret;
+}
+
+void DepthCompositeStream::onFrameAvailable(const BufferItem& item) {
+    if (item.mDataSpace == kJpegDataSpace) {
+        ALOGV("%s: Jpeg buffer with ts: %" PRIu64 " ms. arrived!",
+                __func__, ns2ms(item.mTimestamp));
+
+        Mutex::Autolock l(mMutex);
+        if (!mErrorState) {
+            mInputJpegBuffers.push_back(item.mTimestamp);
+            mInputReadyCondition.signal();
+        }
+    } else if (item.mDataSpace == kDepthMapDataSpace) {
+        ALOGV("%s: Depth buffer with ts: %" PRIu64 " ms. arrived!", __func__,
+                ns2ms(item.mTimestamp));
+
+        Mutex::Autolock l(mMutex);
+        if (!mErrorState) {
+            mInputDepthBuffers.push_back(item.mTimestamp);
+            mInputReadyCondition.signal();
+        }
+    } else {
+        ALOGE("%s: Unexpected data space: 0x%x", __FUNCTION__, item.mDataSpace);
+    }
+}
+
+status_t DepthCompositeStream::insertGbp(SurfaceMap* /*out*/outSurfaceMap,
+        Vector<int32_t> * /*out*/outputStreamIds, int32_t* /*out*/currentStreamId) {
+    if (outSurfaceMap->find(mDepthStreamId) == outSurfaceMap->end()) {
+        (*outSurfaceMap)[mDepthStreamId] = std::vector<size_t>();
+        outputStreamIds->push_back(mDepthStreamId);
+    }
+    (*outSurfaceMap)[mDepthStreamId].push_back(mDepthSurfaceId);
+
+    if (outSurfaceMap->find(mBlobStreamId) == outSurfaceMap->end()) {
+        (*outSurfaceMap)[mBlobStreamId] = std::vector<size_t>();
+        outputStreamIds->push_back(mBlobStreamId);
+    }
+    (*outSurfaceMap)[mBlobStreamId].push_back(mBlobSurfaceId);
+
+    if (currentStreamId != nullptr) {
+        *currentStreamId = mBlobStreamId;
+    }
+
+    return NO_ERROR;
+}
+
+void DepthCompositeStream::onResultError(const CaptureResultExtras& resultExtras) {
+    // Processing can continue even in case of result errors.
+    // At the moment depth composite stream processing relies mainly on static camera
+    // characteristics data. The actual result data can be used for the jpeg quality but
+    // in case it is absent we can default to maximum.
+    eraseResult(resultExtras.frameNumber);
+}
+
+bool DepthCompositeStream::onStreamBufferError(const CaptureResultExtras& resultExtras) {
+    bool ret = false;
+    // Buffer errors concerning internal composite streams should not be directly visible to
+    // camera clients. They must only receive a single buffer error with the public composite
+    // stream id.
+    if ((resultExtras.errorStreamId == mDepthStreamId) ||
+            (resultExtras.errorStreamId == mBlobStreamId)) {
+        flagAnErrorFrameNumber(resultExtras.frameNumber);
+        ret = true;
+    }
+
+    return ret;
+}
+
+status_t DepthCompositeStream::getMatchingDepthSize(size_t width, size_t height,
+        const std::vector<std::tuple<size_t, size_t>>& supporedDepthSizes,
+        size_t *depthWidth /*out*/, size_t *depthHeight /*out*/) {
+    if ((depthWidth == nullptr) || (depthHeight == nullptr)) {
+        return BAD_VALUE;
+    }
+
+    float arTol = CameraProviderManager::kDepthARTolerance;
+    *depthWidth = *depthHeight = 0;
+
+    float aspectRatio = static_cast<float> (width) / static_cast<float> (height);
+    for (const auto& it : supporedDepthSizes) {
+        auto currentWidth = std::get<0>(it);
+        auto currentHeight = std::get<1>(it);
+        if ((currentWidth == width) && (currentHeight == height)) {
+            *depthWidth = width;
+            *depthHeight = height;
+            break;
+        } else {
+            float currentRatio = static_cast<float> (currentWidth) /
+                    static_cast<float> (currentHeight);
+            auto currentSize = currentWidth * currentHeight;
+            auto oldSize = (*depthWidth) * (*depthHeight);
+            if ((fabs(aspectRatio - currentRatio) <= arTol) && (currentSize > oldSize)) {
+                *depthWidth = currentWidth;
+                *depthHeight = currentHeight;
+            }
+        }
+    }
+
+    return ((*depthWidth > 0) && (*depthHeight > 0)) ? OK : BAD_VALUE;
+}
+
+void DepthCompositeStream::getSupportedDepthSizes(const CameraMetadata& ch,
+        std::vector<std::tuple<size_t, size_t>>* depthSizes /*out*/) {
+    if (depthSizes == nullptr) {
+        return;
+    }
+
+    auto entry = ch.find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS);
+    if (entry.count > 0) {
+        // Depth stream dimensions have four int32_t components
+        // (pixelformat, width, height, type)
+        size_t entryCount = entry.count / 4;
+        depthSizes->reserve(entryCount);
+        for (size_t i = 0; i < entry.count; i += 4) {
+            if ((entry.data.i32[i] == kDepthMapPixelFormat) &&
+                    (entry.data.i32[i+3] ==
+                     ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT)) {
+                depthSizes->push_back(std::make_tuple(entry.data.i32[i+1],
+                            entry.data.i32[i+2]));
+            }
+        }
+    }
+}
+
+status_t DepthCompositeStream::getCompositeStreamInfo(const OutputStreamInfo &streamInfo,
+            const CameraMetadata& ch, std::vector<OutputStreamInfo>* compositeOutput /*out*/) {
+    if (compositeOutput == nullptr) {
+        return BAD_VALUE;
+    }
+
+    std::vector<std::tuple<size_t, size_t>> depthSizes;
+    getSupportedDepthSizes(ch, &depthSizes);
+    if (depthSizes.empty()) {
+        ALOGE("%s: No depth stream configurations present", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    size_t depthWidth, depthHeight;
+    auto ret = getMatchingDepthSize(streamInfo.width, streamInfo.height, depthSizes, &depthWidth,
+            &depthHeight);
+    if (ret != OK) {
+        ALOGE("%s: No matching depth stream size found", __FUNCTION__);
+        return ret;
+    }
+
+    compositeOutput->clear();
+    compositeOutput->insert(compositeOutput->end(), 2, streamInfo);
+
+    // Jpeg/Blob stream info
+    (*compositeOutput)[0].dataSpace = kJpegDataSpace;
+    (*compositeOutput)[0].consumerUsage = GRALLOC_USAGE_SW_READ_OFTEN;
+
+    // Depth stream info
+    (*compositeOutput)[1].width = depthWidth;
+    (*compositeOutput)[1].height = depthHeight;
+    (*compositeOutput)[1].format = kDepthMapPixelFormat;
+    (*compositeOutput)[1].dataSpace = kDepthMapDataSpace;
+    (*compositeOutput)[1].consumerUsage = GRALLOC_USAGE_SW_READ_OFTEN;
+
+    return NO_ERROR;
+}
+
+}; // namespace camera3
+}; // namespace android
diff --git a/services/camera/libcameraservice/api2/DepthCompositeStream.h b/services/camera/libcameraservice/api2/DepthCompositeStream.h
new file mode 100644
index 0000000..975c59b
--- /dev/null
+++ b/services/camera/libcameraservice/api2/DepthCompositeStream.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SERVERS_CAMERA_CAMERA3_DEPTH_COMPOSITE_STREAM_H
+#define ANDROID_SERVERS_CAMERA_CAMERA3_DEPTH_COMPOSITE_STREAM_H
+
+#include "common/DepthPhotoProcessor.h"
+#include <dynamic_depth/imaging_model.h>
+#include <dynamic_depth/depth_map.h>
+
+#include <gui/CpuConsumer.h>
+
+#include "CompositeStream.h"
+
+using dynamic_depth::DepthMap;
+using dynamic_depth::Item;
+using dynamic_depth::ImagingModel;
+
+namespace android {
+
+class CameraDeviceClient;
+class CameraMetadata;
+class Surface;
+
+namespace camera3 {
+
+class DepthCompositeStream : public CompositeStream, public Thread,
+        public CpuConsumer::FrameAvailableListener {
+
+public:
+    DepthCompositeStream(wp<CameraDeviceBase> device,
+            wp<hardware::camera2::ICameraDeviceCallbacks> cb);
+    ~DepthCompositeStream() override;
+
+    static bool isDepthCompositeStream(const sp<Surface> &surface);
+
+    // CompositeStream overrides
+    status_t createInternalStreams(const std::vector<sp<Surface>>& consumers,
+            bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
+            camera3_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+            std::vector<int> *surfaceIds, int streamSetId, bool isShared) override;
+    status_t deleteInternalStreams() override;
+    status_t configureStream() override;
+    status_t insertGbp(SurfaceMap* /*out*/outSurfaceMap, Vector<int32_t>* /*out*/outputStreamIds,
+            int32_t* /*out*/currentStreamId) override;
+    int getStreamId() override { return mBlobStreamId; }
+
+    // CpuConsumer listener implementation
+    void onFrameAvailable(const BufferItem& item) override;
+
+    // Return stream information about the internal camera streams
+    static status_t getCompositeStreamInfo(const OutputStreamInfo &streamInfo,
+            const CameraMetadata& ch, std::vector<OutputStreamInfo>* compositeOutput /*out*/);
+
+protected:
+
+    bool threadLoop() override;
+    bool onStreamBufferError(const CaptureResultExtras& resultExtras) override;
+    void onResultError(const CaptureResultExtras& resultExtras) override;
+
+private:
+    struct InputFrame {
+        CpuConsumer::LockedBuffer depthBuffer;
+        CpuConsumer::LockedBuffer jpegBuffer;
+        CameraMetadata            result;
+        bool                      error;
+        bool                      errorNotified;
+        int64_t                   frameNumber;
+
+        InputFrame() : error(false), errorNotified(false), frameNumber(-1) { }
+    };
+
+    // Helper methods
+    static void getSupportedDepthSizes(const CameraMetadata& ch,
+            std::vector<std::tuple<size_t, size_t>>* depthSizes /*out*/);
+    static status_t getMatchingDepthSize(size_t width, size_t height,
+            const std::vector<std::tuple<size_t, size_t>>& supporedDepthSizes,
+            size_t *depthWidth /*out*/, size_t *depthHeight /*out*/);
+
+    // Dynamic depth processing
+    status_t encodeGrayscaleJpeg(size_t width, size_t height, uint8_t *in, void *out,
+            const size_t maxOutSize, uint8_t jpegQuality, size_t &actualSize);
+    std::unique_ptr<DepthMap> processDepthMapFrame(const CpuConsumer::LockedBuffer &depthMapBuffer,
+            size_t maxJpegSize, uint8_t jpegQuality,
+            std::vector<std::unique_ptr<Item>>* items /*out*/);
+    std::unique_ptr<ImagingModel> getImagingModel();
+    status_t processInputFrame(const InputFrame &inputFrame);
+
+    // Buffer/Results handling
+    void compilePendingInputLocked();
+    void releaseInputFrameLocked(InputFrame *inputFrame /*out*/);
+    void releaseInputFramesLocked(int64_t currentTs);
+
+    // Find first complete and valid frame with smallest timestamp
+    bool getNextReadyInputLocked(int64_t *currentTs /*inout*/);
+
+    // Find next failing frame number with smallest timestamp and return respective frame number
+    int64_t getNextFailingInputLocked(int64_t *currentTs /*inout*/);
+
+    static const nsecs_t kWaitDuration = 10000000; // 10 ms
+    static const auto kDepthMapPixelFormat = HAL_PIXEL_FORMAT_Y16;
+    static const auto kDepthMapDataSpace = HAL_DATASPACE_DEPTH;
+    static const auto kJpegDataSpace = HAL_DATASPACE_V0_JFIF;
+
+    int                  mBlobStreamId, mBlobSurfaceId, mDepthStreamId, mDepthSurfaceId;
+    size_t               mBlobWidth, mBlobHeight;
+    sp<CpuConsumer>      mBlobConsumer, mDepthConsumer;
+    bool                 mDepthBufferAcquired, mBlobBufferAcquired;
+    sp<Surface>          mDepthSurface, mBlobSurface, mOutputSurface;
+    sp<ProducerListener> mProducerListener;
+
+    ssize_t              mMaxJpegSize;
+    std::vector<std::tuple<size_t, size_t>> mSupportedDepthSizes;
+    std::vector<float>   mIntrinsicCalibration, mLensDistortion;
+    bool                 mIsLogicalCamera;
+    void*                mDepthPhotoLibHandle;
+    process_depth_photo_frame mDepthPhotoProcess;
+
+    // Keep all incoming Depth buffer timestamps pending further processing.
+    std::vector<int64_t> mInputDepthBuffers;
+
+    // Keep all incoming Jpeg/Blob buffer timestamps pending further processing.
+    std::vector<int64_t> mInputJpegBuffers;
+
+    // Map of all input frames pending further processing.
+    std::unordered_map<int64_t, InputFrame> mPendingInputFrames;
+};
+
+}; //namespace camera3
+}; //namespace android
+
+#endif
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
new file mode 100644
index 0000000..5a87134
--- /dev/null
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
@@ -0,0 +1,1714 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Camera3-HeicCompositeStream"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+//#define LOG_NDEBUG 0
+
+#include <linux/memfd.h>
+#include <pthread.h>
+#include <sys/syscall.h>
+
+#include <android/hardware/camera/device/3.5/types.h>
+#include <libyuv.h>
+#include <gui/Surface.h>
+#include <utils/Log.h>
+#include <utils/Trace.h>
+
+#include <media/ICrypto.h>
+#include <media/MediaCodecBuffer.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/MediaDefs.h>
+#include <media/stagefright/MediaCodecConstants.h>
+
+#include "common/CameraDeviceBase.h"
+#include "utils/ExifUtils.h"
+#include "HeicEncoderInfoManager.h"
+#include "HeicCompositeStream.h"
+
+using android::hardware::camera::device::V3_5::CameraBlob;
+using android::hardware::camera::device::V3_5::CameraBlobId;
+
+namespace android {
+namespace camera3 {
+
+HeicCompositeStream::HeicCompositeStream(wp<CameraDeviceBase> device,
+        wp<hardware::camera2::ICameraDeviceCallbacks> cb) :
+        CompositeStream(device, cb),
+        mUseHeic(false),
+        mNumOutputTiles(1),
+        mOutputWidth(0),
+        mOutputHeight(0),
+        mMaxHeicBufferSize(0),
+        mGridWidth(HeicEncoderInfoManager::kGridWidth),
+        mGridHeight(HeicEncoderInfoManager::kGridHeight),
+        mGridRows(1),
+        mGridCols(1),
+        mUseGrid(false),
+        mAppSegmentStreamId(-1),
+        mAppSegmentSurfaceId(-1),
+        mAppSegmentBufferAcquired(false),
+        mMainImageStreamId(-1),
+        mMainImageSurfaceId(-1),
+        mYuvBufferAcquired(false),
+        mProducerListener(new ProducerListener()),
+        mOutputBufferCounter(0),
+        mGridTimestampUs(0) {
+}
+
+HeicCompositeStream::~HeicCompositeStream() {
+    // Call deinitCodec in case stream hasn't been deleted yet to avoid any
+    // memory/resource leak.
+    deinitCodec();
+
+    mInputAppSegmentBuffers.clear();
+    mCodecOutputBuffers.clear();
+
+    mAppSegmentStreamId = -1;
+    mAppSegmentSurfaceId = -1;
+    mAppSegmentConsumer.clear();
+    mAppSegmentSurface.clear();
+
+    mMainImageStreamId = -1;
+    mMainImageSurfaceId = -1;
+    mMainImageConsumer.clear();
+    mMainImageSurface.clear();
+}
+
+bool HeicCompositeStream::isHeicCompositeStream(const sp<Surface> &surface) {
+    ANativeWindow *anw = surface.get();
+    status_t err;
+    int format;
+    if ((err = anw->query(anw, NATIVE_WINDOW_FORMAT, &format)) != OK) {
+        String8 msg = String8::format("Failed to query Surface format: %s (%d)", strerror(-err),
+                err);
+        ALOGE("%s: %s", __FUNCTION__, msg.string());
+        return false;
+    }
+
+    int dataspace;
+    if ((err = anw->query(anw, NATIVE_WINDOW_DEFAULT_DATASPACE, &dataspace)) != OK) {
+        String8 msg = String8::format("Failed to query Surface dataspace: %s (%d)", strerror(-err),
+                err);
+        ALOGE("%s: %s", __FUNCTION__, msg.string());
+        return false;
+    }
+
+    return ((format == HAL_PIXEL_FORMAT_BLOB) && (dataspace == HAL_DATASPACE_HEIF));
+}
+
+status_t HeicCompositeStream::createInternalStreams(const std::vector<sp<Surface>>& consumers,
+        bool /*hasDeferredConsumer*/, uint32_t width, uint32_t height, int format,
+        camera3_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+        std::vector<int> *surfaceIds, int /*streamSetId*/, bool /*isShared*/) {
+
+    sp<CameraDeviceBase> device = mDevice.promote();
+    if (!device.get()) {
+        ALOGE("%s: Invalid camera device!", __FUNCTION__);
+        return NO_INIT;
+    }
+
+    status_t res = initializeCodec(width, height, device);
+    if (res != OK) {
+        ALOGE("%s: Failed to initialize HEIC/HEVC codec: %s (%d)",
+                __FUNCTION__, strerror(-res), res);
+        return NO_INIT;
+    }
+
+    sp<IGraphicBufferProducer> producer;
+    sp<IGraphicBufferConsumer> consumer;
+    BufferQueue::createBufferQueue(&producer, &consumer);
+    mAppSegmentConsumer = new CpuConsumer(consumer, 1);
+    mAppSegmentConsumer->setFrameAvailableListener(this);
+    mAppSegmentConsumer->setName(String8("Camera3-HeicComposite-AppSegmentStream"));
+    mAppSegmentSurface = new Surface(producer);
+
+    mStaticInfo = device->info();
+
+    res = device->createStream(mAppSegmentSurface, mAppSegmentMaxSize, 1, format,
+            kAppSegmentDataSpace, rotation, &mAppSegmentStreamId, physicalCameraId, surfaceIds);
+    if (res == OK) {
+        mAppSegmentSurfaceId = (*surfaceIds)[0];
+    } else {
+        ALOGE("%s: Failed to create JPEG App segment stream: %s (%d)", __FUNCTION__,
+                strerror(-res), res);
+        return res;
+    }
+
+    if (!mUseGrid) {
+        res = mCodec->createInputSurface(&producer);
+        if (res != OK) {
+            ALOGE("%s: Failed to create input surface for Heic codec: %s (%d)",
+                    __FUNCTION__, strerror(-res), res);
+            return res;
+        }
+    } else {
+        BufferQueue::createBufferQueue(&producer, &consumer);
+        mMainImageConsumer = new CpuConsumer(consumer, 1);
+        mMainImageConsumer->setFrameAvailableListener(this);
+        mMainImageConsumer->setName(String8("Camera3-HeicComposite-HevcInputYUVStream"));
+    }
+    mMainImageSurface = new Surface(producer);
+
+    res = mCodec->start();
+    if (res != OK) {
+        ALOGE("%s: Failed to start codec: %s (%d)", __FUNCTION__,
+                strerror(-res), res);
+        return res;
+    }
+
+    std::vector<int> sourceSurfaceId;
+    //Use YUV_888 format if framework tiling is needed.
+    int srcStreamFmt = mUseGrid ? HAL_PIXEL_FORMAT_YCbCr_420_888 :
+            HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
+    res = device->createStream(mMainImageSurface, width, height, srcStreamFmt, kHeifDataSpace,
+            rotation, id, physicalCameraId, &sourceSurfaceId);
+    if (res == OK) {
+        mMainImageSurfaceId = sourceSurfaceId[0];
+        mMainImageStreamId = *id;
+    } else {
+        ALOGE("%s: Failed to create main image stream: %s (%d)", __FUNCTION__,
+                strerror(-res), res);
+        return res;
+    }
+
+    mOutputSurface = consumers[0];
+    res = registerCompositeStreamListener(getStreamId());
+    if (res != OK) {
+        ALOGE("%s: Failed to register HAL main image stream", __FUNCTION__);
+        return res;
+    }
+
+    initCopyRowFunction(width);
+    return res;
+}
+
+status_t HeicCompositeStream::deleteInternalStreams() {
+    requestExit();
+    auto res = join();
+    if (res != OK) {
+        ALOGE("%s: Failed to join with the main processing thread: %s (%d)", __FUNCTION__,
+                strerror(-res), res);
+    }
+
+    deinitCodec();
+
+    if (mAppSegmentStreamId >= 0) {
+        sp<CameraDeviceBase> device = mDevice.promote();
+        if (!device.get()) {
+            ALOGE("%s: Invalid camera device!", __FUNCTION__);
+            return NO_INIT;
+        }
+
+        res = device->deleteStream(mAppSegmentStreamId);
+        mAppSegmentStreamId = -1;
+    }
+
+    if (mOutputSurface != nullptr) {
+        mOutputSurface->disconnect(NATIVE_WINDOW_API_CAMERA);
+        mOutputSurface.clear();
+    }
+    return res;
+}
+
+void HeicCompositeStream::onBufferReleased(const BufferInfo& bufferInfo) {
+    Mutex::Autolock l(mMutex);
+
+    if (bufferInfo.mError) return;
+
+    mCodecOutputBufferTimestamps.push(bufferInfo.mTimestamp);
+}
+
+// We need to get the settings early to handle the case where the codec output
+// arrives earlier than result metadata.
+void HeicCompositeStream::onBufferRequestForFrameNumber(uint64_t frameNumber, int streamId,
+        const CameraMetadata& settings) {
+    ATRACE_ASYNC_BEGIN("HEIC capture", frameNumber);
+
+    Mutex::Autolock l(mMutex);
+    if (mErrorState || (streamId != getStreamId())) {
+        return;
+    }
+
+    mPendingCaptureResults.emplace(frameNumber, CameraMetadata());
+
+    camera_metadata_ro_entry entry;
+
+    int32_t orientation = 0;
+    entry = settings.find(ANDROID_JPEG_ORIENTATION);
+    if (entry.count == 1) {
+        orientation = entry.data.i32[0];
+    }
+
+    int32_t quality = kDefaultJpegQuality;
+    entry = settings.find(ANDROID_JPEG_QUALITY);
+    if (entry.count == 1) {
+        quality = entry.data.i32[0];
+    }
+
+    mSettingsByFrameNumber[frameNumber] = std::make_pair(orientation, quality);
+}
+
+void HeicCompositeStream::onFrameAvailable(const BufferItem& item) {
+    if (item.mDataSpace == static_cast<android_dataspace>(kAppSegmentDataSpace)) {
+        ALOGV("%s: JPEG APP segments buffer with ts: %" PRIu64 " ms. arrived!",
+                __func__, ns2ms(item.mTimestamp));
+
+        Mutex::Autolock l(mMutex);
+        if (!mErrorState) {
+            mInputAppSegmentBuffers.push_back(item.mTimestamp);
+            mInputReadyCondition.signal();
+        }
+    } else if (item.mDataSpace == kHeifDataSpace) {
+        ALOGV("%s: YUV_888 buffer with ts: %" PRIu64 " ms. arrived!",
+                __func__, ns2ms(item.mTimestamp));
+
+        Mutex::Autolock l(mMutex);
+        if (!mUseGrid) {
+            ALOGE("%s: YUV_888 internal stream is only supported for HEVC tiling",
+                    __FUNCTION__);
+            return;
+        }
+        if (!mErrorState) {
+            mInputYuvBuffers.push_back(item.mTimestamp);
+            mInputReadyCondition.signal();
+        }
+    } else {
+        ALOGE("%s: Unexpected data space: 0x%x", __FUNCTION__, item.mDataSpace);
+    }
+}
+
+status_t HeicCompositeStream::getCompositeStreamInfo(const OutputStreamInfo &streamInfo,
+            const CameraMetadata& ch, std::vector<OutputStreamInfo>* compositeOutput /*out*/) {
+    if (compositeOutput == nullptr) {
+        return BAD_VALUE;
+    }
+
+    compositeOutput->clear();
+
+    bool useGrid, useHeic;
+    bool isSizeSupported = isSizeSupportedByHeifEncoder(
+            streamInfo.width, streamInfo.height, &useHeic, &useGrid, nullptr);
+    if (!isSizeSupported) {
+        // Size is not supported by either encoder.
+        return OK;
+    }
+
+    compositeOutput->insert(compositeOutput->end(), 2, streamInfo);
+
+    // JPEG APPS segments Blob stream info
+    (*compositeOutput)[0].width = calcAppSegmentMaxSize(ch);
+    (*compositeOutput)[0].height = 1;
+    (*compositeOutput)[0].format = HAL_PIXEL_FORMAT_BLOB;
+    (*compositeOutput)[0].dataSpace = kAppSegmentDataSpace;
+    (*compositeOutput)[0].consumerUsage = GRALLOC_USAGE_SW_READ_OFTEN;
+
+    // YUV/IMPLEMENTATION_DEFINED stream info
+    (*compositeOutput)[1].width = streamInfo.width;
+    (*compositeOutput)[1].height = streamInfo.height;
+    (*compositeOutput)[1].format = useGrid ? HAL_PIXEL_FORMAT_YCbCr_420_888 :
+            HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
+    (*compositeOutput)[1].dataSpace = kHeifDataSpace;
+    (*compositeOutput)[1].consumerUsage = useHeic ? GRALLOC_USAGE_HW_IMAGE_ENCODER :
+            useGrid ? GRALLOC_USAGE_SW_READ_OFTEN : GRALLOC_USAGE_HW_VIDEO_ENCODER;
+
+    return NO_ERROR;
+}
+
+bool HeicCompositeStream::isSizeSupportedByHeifEncoder(int32_t width, int32_t height,
+        bool* useHeic, bool* useGrid, int64_t* stall, AString* hevcName) {
+    static HeicEncoderInfoManager& heicManager = HeicEncoderInfoManager::getInstance();
+    return heicManager.isSizeSupported(width, height, useHeic, useGrid, stall, hevcName);
+}
+
+bool HeicCompositeStream::isInMemoryTempFileSupported() {
+    int memfd = syscall(__NR_memfd_create, "HEIF-try-memfd", MFD_CLOEXEC);
+    if (memfd == -1) {
+        if (errno != ENOSYS) {
+            ALOGE("%s: Failed to create tmpfs file. errno %d", __FUNCTION__, errno);
+        }
+        return false;
+    }
+    close(memfd);
+    return true;
+}
+
+void HeicCompositeStream::onHeicOutputFrameAvailable(
+        const CodecOutputBufferInfo& outputBufferInfo) {
+    Mutex::Autolock l(mMutex);
+
+    ALOGV("%s: index %d, offset %d, size %d, time %" PRId64 ", flags 0x%x",
+            __FUNCTION__, outputBufferInfo.index, outputBufferInfo.offset,
+            outputBufferInfo.size, outputBufferInfo.timeUs, outputBufferInfo.flags);
+
+    if (!mErrorState) {
+        if ((outputBufferInfo.size > 0) &&
+                ((outputBufferInfo.flags & MediaCodec::BUFFER_FLAG_CODECCONFIG) == 0)) {
+            mCodecOutputBuffers.push_back(outputBufferInfo);
+            mInputReadyCondition.signal();
+        } else {
+            mCodec->releaseOutputBuffer(outputBufferInfo.index);
+        }
+    } else {
+        mCodec->releaseOutputBuffer(outputBufferInfo.index);
+    }
+}
+
+void HeicCompositeStream::onHeicInputFrameAvailable(int32_t index) {
+    Mutex::Autolock l(mMutex);
+
+    if (!mUseGrid) {
+        ALOGE("%s: Codec YUV input mode must only be used for Hevc tiling mode", __FUNCTION__);
+        return;
+    }
+
+    mCodecInputBuffers.push_back(index);
+    mInputReadyCondition.signal();
+}
+
+void HeicCompositeStream::onHeicFormatChanged(sp<AMessage>& newFormat) {
+    if (newFormat == nullptr) {
+        ALOGE("%s: newFormat must not be null!", __FUNCTION__);
+        return;
+    }
+
+    Mutex::Autolock l(mMutex);
+
+    AString mime;
+    AString mimeHeic(MIMETYPE_IMAGE_ANDROID_HEIC);
+    newFormat->findString(KEY_MIME, &mime);
+    if (mime != mimeHeic) {
+        // For HEVC codec, below keys need to be filled out or overwritten so that the
+        // muxer can handle them as HEIC output image.
+        newFormat->setString(KEY_MIME, mimeHeic);
+        newFormat->setInt32(KEY_WIDTH, mOutputWidth);
+        newFormat->setInt32(KEY_HEIGHT, mOutputHeight);
+        if (mUseGrid) {
+            newFormat->setInt32(KEY_TILE_WIDTH, mGridWidth);
+            newFormat->setInt32(KEY_TILE_HEIGHT, mGridHeight);
+            newFormat->setInt32(KEY_GRID_ROWS, mGridRows);
+            newFormat->setInt32(KEY_GRID_COLUMNS, mGridCols);
+        }
+    }
+    newFormat->setInt32(KEY_IS_DEFAULT, 1 /*isPrimary*/);
+
+    int32_t gridRows, gridCols;
+    if (newFormat->findInt32(KEY_GRID_ROWS, &gridRows) &&
+            newFormat->findInt32(KEY_GRID_COLUMNS, &gridCols)) {
+        mNumOutputTiles = gridRows * gridCols;
+    } else {
+        mNumOutputTiles = 1;
+    }
+
+    ALOGV("%s: mNumOutputTiles is %zu", __FUNCTION__, mNumOutputTiles);
+    mFormat = newFormat;
+}
+
+void HeicCompositeStream::onHeicCodecError() {
+    Mutex::Autolock l(mMutex);
+    mErrorState = true;
+}
+
+status_t HeicCompositeStream::configureStream() {
+    if (isRunning()) {
+        // Processing thread is already running, nothing more to do.
+        return NO_ERROR;
+    }
+
+    if (mOutputSurface.get() == nullptr) {
+        ALOGE("%s: No valid output surface set!", __FUNCTION__);
+        return NO_INIT;
+    }
+
+    auto res = mOutputSurface->connect(NATIVE_WINDOW_API_CAMERA, mProducerListener);
+    if (res != OK) {
+        ALOGE("%s: Unable to connect to native window for stream %d",
+                __FUNCTION__, mMainImageStreamId);
+        return res;
+    }
+
+    if ((res = native_window_set_buffers_format(mOutputSurface.get(), HAL_PIXEL_FORMAT_BLOB))
+            != OK) {
+        ALOGE("%s: Unable to configure stream buffer format for stream %d", __FUNCTION__,
+                mMainImageStreamId);
+        return res;
+    }
+
+    ANativeWindow *anwConsumer = mOutputSurface.get();
+    int maxConsumerBuffers;
+    if ((res = anwConsumer->query(anwConsumer, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
+                    &maxConsumerBuffers)) != OK) {
+        ALOGE("%s: Unable to query consumer undequeued"
+                " buffer count for stream %d", __FUNCTION__, mMainImageStreamId);
+        return res;
+    }
+
+    // Cannot use SourceSurface buffer count since it could be codec's 512*512 tile
+    // buffer count.
+    int maxProducerBuffers = 1;
+    if ((res = native_window_set_buffer_count(
+                    anwConsumer, maxProducerBuffers + maxConsumerBuffers)) != OK) {
+        ALOGE("%s: Unable to set buffer count for stream %d", __FUNCTION__, mMainImageStreamId);
+        return res;
+    }
+
+    if ((res = native_window_set_buffers_dimensions(anwConsumer, mMaxHeicBufferSize, 1)) != OK) {
+        ALOGE("%s: Unable to set buffer dimension %zu x 1 for stream %d: %s (%d)",
+                __FUNCTION__, mMaxHeicBufferSize, mMainImageStreamId, strerror(-res), res);
+        return res;
+    }
+
+    run("HeicCompositeStreamProc");
+
+    return NO_ERROR;
+}
+
+status_t HeicCompositeStream::insertGbp(SurfaceMap* /*out*/outSurfaceMap,
+        Vector<int32_t>* /*out*/outputStreamIds, int32_t* /*out*/currentStreamId) {
+    if (outSurfaceMap->find(mAppSegmentStreamId) == outSurfaceMap->end()) {
+        (*outSurfaceMap)[mAppSegmentStreamId] = std::vector<size_t>();
+        outputStreamIds->push_back(mAppSegmentStreamId);
+    }
+    (*outSurfaceMap)[mAppSegmentStreamId].push_back(mAppSegmentSurfaceId);
+
+    if (outSurfaceMap->find(mMainImageStreamId) == outSurfaceMap->end()) {
+        (*outSurfaceMap)[mMainImageStreamId] = std::vector<size_t>();
+        outputStreamIds->push_back(mMainImageStreamId);
+    }
+    (*outSurfaceMap)[mMainImageStreamId].push_back(mMainImageSurfaceId);
+
+    if (currentStreamId != nullptr) {
+        *currentStreamId = mMainImageStreamId;
+    }
+
+    return NO_ERROR;
+}
+
+void HeicCompositeStream::onShutter(const CaptureResultExtras& resultExtras, nsecs_t timestamp) {
+    Mutex::Autolock l(mMutex);
+    if (mErrorState) {
+        return;
+    }
+
+    if (mSettingsByFrameNumber.find(resultExtras.frameNumber) != mSettingsByFrameNumber.end()) {
+        mFrameNumberMap.emplace(resultExtras.frameNumber, timestamp);
+        mSettingsByTimestamp[timestamp] = mSettingsByFrameNumber[resultExtras.frameNumber];
+        mSettingsByFrameNumber.erase(resultExtras.frameNumber);
+        mInputReadyCondition.signal();
+    }
+}
+
+void HeicCompositeStream::compilePendingInputLocked() {
+    while (!mSettingsByTimestamp.empty()) {
+        auto it = mSettingsByTimestamp.begin();
+        mPendingInputFrames[it->first].orientation = it->second.first;
+        mPendingInputFrames[it->first].quality = it->second.second;
+        mSettingsByTimestamp.erase(it);
+    }
+
+    while (!mInputAppSegmentBuffers.empty() && !mAppSegmentBufferAcquired) {
+        CpuConsumer::LockedBuffer imgBuffer;
+        auto it = mInputAppSegmentBuffers.begin();
+        auto res = mAppSegmentConsumer->lockNextBuffer(&imgBuffer);
+        if (res == NOT_ENOUGH_DATA) {
+            // Canot not lock any more buffers.
+            break;
+        } else if ((res != OK) || (*it != imgBuffer.timestamp)) {
+            if (res != OK) {
+                ALOGE("%s: Error locking JPEG_APP_SEGMENTS image buffer: %s (%d)", __FUNCTION__,
+                        strerror(-res), res);
+            } else {
+                ALOGE("%s: Expecting JPEG_APP_SEGMENTS buffer with time stamp: %" PRId64
+                        " received buffer with time stamp: %" PRId64, __FUNCTION__,
+                        *it, imgBuffer.timestamp);
+            }
+            mPendingInputFrames[*it].error = true;
+            mInputAppSegmentBuffers.erase(it);
+            continue;
+        }
+
+        if ((mPendingInputFrames.find(imgBuffer.timestamp) != mPendingInputFrames.end()) &&
+                (mPendingInputFrames[imgBuffer.timestamp].error)) {
+            mAppSegmentConsumer->unlockBuffer(imgBuffer);
+        } else {
+            mPendingInputFrames[imgBuffer.timestamp].appSegmentBuffer = imgBuffer;
+            mAppSegmentBufferAcquired = true;
+        }
+        mInputAppSegmentBuffers.erase(it);
+    }
+
+    while (!mInputYuvBuffers.empty() && !mYuvBufferAcquired) {
+        CpuConsumer::LockedBuffer imgBuffer;
+        auto it = mInputYuvBuffers.begin();
+        auto res = mMainImageConsumer->lockNextBuffer(&imgBuffer);
+        if (res == NOT_ENOUGH_DATA) {
+            // Canot not lock any more buffers.
+            break;
+        } else if (res != OK) {
+            ALOGE("%s: Error locking YUV_888 image buffer: %s (%d)", __FUNCTION__,
+                    strerror(-res), res);
+            mPendingInputFrames[*it].error = true;
+            mInputYuvBuffers.erase(it);
+            continue;
+        } else if (*it != imgBuffer.timestamp) {
+            ALOGW("%s: Expecting YUV_888 buffer with time stamp: %" PRId64 " received buffer with "
+                    "time stamp: %" PRId64, __FUNCTION__, *it, imgBuffer.timestamp);
+            mPendingInputFrames[*it].error = true;
+            mInputYuvBuffers.erase(it);
+            continue;
+        }
+
+        if ((mPendingInputFrames.find(imgBuffer.timestamp) != mPendingInputFrames.end()) &&
+                (mPendingInputFrames[imgBuffer.timestamp].error)) {
+            mMainImageConsumer->unlockBuffer(imgBuffer);
+        } else {
+            mPendingInputFrames[imgBuffer.timestamp].yuvBuffer = imgBuffer;
+            mYuvBufferAcquired = true;
+        }
+        mInputYuvBuffers.erase(it);
+    }
+
+    while (!mCodecOutputBuffers.empty()) {
+        auto it = mCodecOutputBuffers.begin();
+        // Bitstream buffer timestamp doesn't necessarily directly correlate with input
+        // buffer timestamp. Assume encoder input to output is FIFO, use a queue
+        // to look up timestamp.
+        int64_t bufferTime = -1;
+        if (mCodecOutputBufferTimestamps.empty()) {
+            ALOGE("%s: Failed to find buffer timestamp for codec output buffer!", __FUNCTION__);
+        } else {
+            // Direct mapping between camera timestamp (in ns) and codec timestamp (in us).
+            bufferTime = mCodecOutputBufferTimestamps.front();
+            mOutputBufferCounter++;
+            if (mOutputBufferCounter == mNumOutputTiles) {
+                mCodecOutputBufferTimestamps.pop();
+                mOutputBufferCounter = 0;
+            }
+
+            mPendingInputFrames[bufferTime].codecOutputBuffers.push_back(*it);
+        }
+        mCodecOutputBuffers.erase(it);
+    }
+
+    while (!mFrameNumberMap.empty()) {
+        auto it = mFrameNumberMap.begin();
+        mPendingInputFrames[it->second].frameNumber = it->first;
+        mFrameNumberMap.erase(it);
+    }
+
+    while (!mCaptureResults.empty()) {
+        auto it = mCaptureResults.begin();
+        // Negative timestamp indicates that something went wrong during the capture result
+        // collection process.
+        if (it->first >= 0) {
+            if (mPendingInputFrames[it->first].frameNumber == std::get<0>(it->second)) {
+                mPendingInputFrames[it->first].result =
+                        std::make_unique<CameraMetadata>(std::get<1>(it->second));
+            } else {
+                ALOGE("%s: Capture result frameNumber/timestamp mapping changed between "
+                        "shutter and capture result!", __FUNCTION__);
+            }
+        }
+        mCaptureResults.erase(it);
+    }
+
+    // mErrorFrameNumbers stores frame number of dropped buffers.
+    auto it = mErrorFrameNumbers.begin();
+    while (it != mErrorFrameNumbers.end()) {
+        bool frameFound = false;
+        for (auto &inputFrame : mPendingInputFrames) {
+            if (inputFrame.second.frameNumber == *it) {
+                inputFrame.second.error = true;
+                frameFound = true;
+                break;
+            }
+        }
+
+        if (frameFound) {
+            it = mErrorFrameNumbers.erase(it);
+        } else {
+            ALOGW("%s: Not able to find failing input with frame number: %" PRId64, __FUNCTION__,
+                    *it);
+            it++;
+        }
+    }
+
+    // Distribute codec input buffers to be filled out from YUV output
+    for (auto it = mPendingInputFrames.begin();
+            it != mPendingInputFrames.end() && mCodecInputBuffers.size() > 0; it++) {
+        InputFrame& inputFrame(it->second);
+        if (inputFrame.codecInputCounter < mGridRows * mGridCols) {
+            // Available input tiles that are required for the current input
+            // image.
+            size_t newInputTiles = std::min(mCodecInputBuffers.size(),
+                    mGridRows * mGridCols - inputFrame.codecInputCounter);
+            for (size_t i = 0; i < newInputTiles; i++) {
+                CodecInputBufferInfo inputInfo =
+                        { mCodecInputBuffers[0], mGridTimestampUs++, inputFrame.codecInputCounter };
+                inputFrame.codecInputBuffers.push_back(inputInfo);
+
+                mCodecInputBuffers.erase(mCodecInputBuffers.begin());
+                inputFrame.codecInputCounter++;
+            }
+            break;
+        }
+    }
+}
+
+bool HeicCompositeStream::getNextReadyInputLocked(int64_t *currentTs /*out*/) {
+    if (currentTs == nullptr) {
+        return false;
+    }
+
+    bool newInputAvailable = false;
+    for (const auto& it : mPendingInputFrames) {
+        bool appSegmentReady = (it.second.appSegmentBuffer.data != nullptr) &&
+                !it.second.appSegmentWritten && it.second.result != nullptr;
+        bool codecOutputReady = !it.second.codecOutputBuffers.empty();
+        bool codecInputReady = (it.second.yuvBuffer.data != nullptr) &&
+                (!it.second.codecInputBuffers.empty());
+        if ((!it.second.error) &&
+                (it.first < *currentTs) &&
+                (appSegmentReady || codecOutputReady || codecInputReady)) {
+            *currentTs = it.first;
+            newInputAvailable = true;
+            break;
+        }
+    }
+
+    return newInputAvailable;
+}
+
+int64_t HeicCompositeStream::getNextFailingInputLocked(int64_t *currentTs /*out*/) {
+    int64_t res = -1;
+    if (currentTs == nullptr) {
+        return res;
+    }
+
+    for (const auto& it : mPendingInputFrames) {
+        if (it.second.error && !it.second.errorNotified && (it.first < *currentTs)) {
+            *currentTs = it.first;
+            res = it.second.frameNumber;
+            break;
+        }
+    }
+
+    return res;
+}
+
+status_t HeicCompositeStream::processInputFrame(nsecs_t timestamp,
+        InputFrame &inputFrame) {
+    ATRACE_CALL();
+    status_t res = OK;
+
+    bool appSegmentReady = inputFrame.appSegmentBuffer.data != nullptr &&
+            !inputFrame.appSegmentWritten && inputFrame.result != nullptr;
+    bool codecOutputReady = inputFrame.codecOutputBuffers.size() > 0;
+    bool codecInputReady = inputFrame.yuvBuffer.data != nullptr &&
+           !inputFrame.codecInputBuffers.empty();
+
+    if (!appSegmentReady && !codecOutputReady && !codecInputReady) {
+        ALOGW("%s: No valid appSegmentBuffer/codec input/outputBuffer available!", __FUNCTION__);
+        return OK;
+    }
+
+    // Handle inputs for Hevc tiling
+    if (codecInputReady) {
+        res = processCodecInputFrame(inputFrame);
+        if (res != OK) {
+            ALOGE("%s: Failed to process codec input frame: %s (%d)", __FUNCTION__,
+                    strerror(-res), res);
+            return res;
+        }
+    }
+
+    // Initialize and start muxer if not yet done so
+    if (inputFrame.muxer == nullptr) {
+        res = startMuxerForInputFrame(timestamp, inputFrame);
+        if (res != OK) {
+            ALOGE("%s: Failed to create and start muxer: %s (%d)", __FUNCTION__,
+                    strerror(-res), res);
+            return res;
+        }
+    }
+
+    // Write JPEG APP segments data to the muxer.
+    if (appSegmentReady && inputFrame.muxer != nullptr) {
+        res = processAppSegment(timestamp, inputFrame);
+        if (res != OK) {
+            ALOGE("%s: Failed to process JPEG APP segments: %s (%d)", __FUNCTION__,
+                    strerror(-res), res);
+            return res;
+        }
+    }
+
+    // Write media codec bitstream buffers to muxer.
+    while (!inputFrame.codecOutputBuffers.empty()) {
+        res = processOneCodecOutputFrame(timestamp, inputFrame);
+        if (res != OK) {
+            ALOGE("%s: Failed to process codec output frame: %s (%d)", __FUNCTION__,
+                    strerror(-res), res);
+            return res;
+        }
+    }
+
+    if (inputFrame.appSegmentWritten && inputFrame.pendingOutputTiles == 0) {
+        res = processCompletedInputFrame(timestamp, inputFrame);
+        if (res != OK) {
+            ALOGE("%s: Failed to process completed input frame: %s (%d)", __FUNCTION__,
+                    strerror(-res), res);
+            return res;
+        }
+    }
+
+    return res;
+}
+
+status_t HeicCompositeStream::startMuxerForInputFrame(nsecs_t timestamp, InputFrame &inputFrame) {
+    sp<ANativeWindow> outputANW = mOutputSurface;
+    if (inputFrame.codecOutputBuffers.size() == 0) {
+        // No single codec output buffer has been generated. Continue to
+        // wait.
+        return OK;
+    }
+
+    auto res = outputANW->dequeueBuffer(mOutputSurface.get(), &inputFrame.anb, &inputFrame.fenceFd);
+    if (res != OK) {
+        ALOGE("%s: Error retrieving output buffer: %s (%d)", __FUNCTION__, strerror(-res),
+                res);
+        return res;
+    }
+
+    // Combine current thread id, stream id and timestamp to uniquely identify image.
+    std::ostringstream tempOutputFile;
+    tempOutputFile << "HEIF-" << pthread_self() << "-"
+            << getStreamId() << "-" << timestamp;
+    inputFrame.fileFd = syscall(__NR_memfd_create, tempOutputFile.str().c_str(), MFD_CLOEXEC);
+    if (inputFrame.fileFd < 0) {
+        ALOGE("%s: Failed to create file %s. Error no is %d", __FUNCTION__,
+                tempOutputFile.str().c_str(), errno);
+        return NO_INIT;
+    }
+    inputFrame.muxer = new MediaMuxer(inputFrame.fileFd, MediaMuxer::OUTPUT_FORMAT_HEIF);
+    if (inputFrame.muxer == nullptr) {
+        ALOGE("%s: Failed to create MediaMuxer for file fd %d",
+                __FUNCTION__, inputFrame.fileFd);
+        return NO_INIT;
+    }
+
+    res = inputFrame.muxer->setOrientationHint(inputFrame.orientation);
+    if (res != OK) {
+        ALOGE("%s: Failed to setOrientationHint: %s (%d)", __FUNCTION__,
+                strerror(-res), res);
+        return res;
+    }
+    // Set encoder quality
+    {
+        sp<AMessage> qualityParams = new AMessage;
+        qualityParams->setInt32(PARAMETER_KEY_VIDEO_BITRATE, inputFrame.quality);
+        res = mCodec->setParameters(qualityParams);
+        if (res != OK) {
+            ALOGE("%s: Failed to set codec quality: %s (%d)",
+                    __FUNCTION__, strerror(-res), res);
+            return res;
+        }
+    }
+
+    ssize_t trackId = inputFrame.muxer->addTrack(mFormat);
+    if (trackId < 0) {
+        ALOGE("%s: Failed to addTrack to the muxer: %zd", __FUNCTION__, trackId);
+        return NO_INIT;
+    }
+
+    inputFrame.trackIndex = trackId;
+    inputFrame.pendingOutputTiles = mNumOutputTiles;
+
+    res = inputFrame.muxer->start();
+    if (res != OK) {
+        ALOGE("%s: Failed to start MediaMuxer: %s (%d)",
+                __FUNCTION__, strerror(-res), res);
+        return res;
+    }
+
+    return OK;
+}
+
+status_t HeicCompositeStream::processAppSegment(nsecs_t timestamp, InputFrame &inputFrame) {
+    size_t app1Size = 0;
+    auto appSegmentSize = findAppSegmentsSize(inputFrame.appSegmentBuffer.data,
+            inputFrame.appSegmentBuffer.width * inputFrame.appSegmentBuffer.height,
+            &app1Size);
+    ALOGV("%s: appSegmentSize is %zu, width %d, height %d, app1Size %zu", __FUNCTION__,
+          appSegmentSize, inputFrame.appSegmentBuffer.width,
+          inputFrame.appSegmentBuffer.height, app1Size);
+    if (appSegmentSize == 0) {
+        ALOGE("%s: Failed to find JPEG APP segment size", __FUNCTION__);
+        return NO_INIT;
+    }
+
+    std::unique_ptr<ExifUtils> exifUtils(ExifUtils::create());
+    auto exifRes = exifUtils->initialize(inputFrame.appSegmentBuffer.data, app1Size);
+    if (!exifRes) {
+        ALOGE("%s: Failed to initialize ExifUtils object!", __FUNCTION__);
+        return BAD_VALUE;
+    }
+    exifRes = exifUtils->setFromMetadata(*inputFrame.result, mStaticInfo,
+            mOutputWidth, mOutputHeight);
+    if (!exifRes) {
+        ALOGE("%s: Failed to set Exif tags using metadata and main image sizes", __FUNCTION__);
+        return BAD_VALUE;
+    }
+    exifRes = exifUtils->setOrientation(inputFrame.orientation);
+    if (!exifRes) {
+        ALOGE("%s: ExifUtils failed to set orientation", __FUNCTION__);
+        return BAD_VALUE;
+    }
+    exifRes = exifUtils->generateApp1();
+    if (!exifRes) {
+        ALOGE("%s: ExifUtils failed to generate APP1 segment", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    unsigned int newApp1Length = exifUtils->getApp1Length();
+    const uint8_t *newApp1Segment = exifUtils->getApp1Buffer();
+
+    //Assemble the APP1 marker buffer required by MediaCodec
+    uint8_t kExifApp1Marker[] = {'E', 'x', 'i', 'f', 0xFF, 0xE1, 0x00, 0x00};
+    kExifApp1Marker[6] = static_cast<uint8_t>(newApp1Length >> 8);
+    kExifApp1Marker[7] = static_cast<uint8_t>(newApp1Length & 0xFF);
+    size_t appSegmentBufferSize = sizeof(kExifApp1Marker) +
+            appSegmentSize - app1Size + newApp1Length;
+    uint8_t* appSegmentBuffer = new uint8_t[appSegmentBufferSize];
+    memcpy(appSegmentBuffer, kExifApp1Marker, sizeof(kExifApp1Marker));
+    memcpy(appSegmentBuffer + sizeof(kExifApp1Marker), newApp1Segment, newApp1Length);
+    if (appSegmentSize - app1Size > 0) {
+        memcpy(appSegmentBuffer + sizeof(kExifApp1Marker) + newApp1Length,
+                inputFrame.appSegmentBuffer.data + app1Size, appSegmentSize - app1Size);
+    }
+
+    sp<ABuffer> aBuffer = new ABuffer(appSegmentBuffer, appSegmentBufferSize);
+    auto res = inputFrame.muxer->writeSampleData(aBuffer, inputFrame.trackIndex,
+            timestamp, MediaCodec::BUFFER_FLAG_MUXER_DATA);
+    delete[] appSegmentBuffer;
+
+    if (res != OK) {
+        ALOGE("%s: Failed to write JPEG APP segments to muxer: %s (%d)",
+                __FUNCTION__, strerror(-res), res);
+        return res;
+    }
+    inputFrame.appSegmentWritten = true;
+
+    return OK;
+}
+
+status_t HeicCompositeStream::processCodecInputFrame(InputFrame &inputFrame) {
+    for (auto& inputBuffer : inputFrame.codecInputBuffers) {
+        sp<MediaCodecBuffer> buffer;
+        auto res = mCodec->getInputBuffer(inputBuffer.index, &buffer);
+        if (res != OK) {
+            ALOGE("%s: Error getting codec input buffer: %s (%d)", __FUNCTION__,
+                    strerror(-res), res);
+            return res;
+        }
+
+        // Copy one tile from source to destination.
+        size_t tileX = inputBuffer.tileIndex % mGridCols;
+        size_t tileY = inputBuffer.tileIndex / mGridCols;
+        size_t top = mGridHeight * tileY;
+        size_t left = mGridWidth * tileX;
+        size_t width = (tileX == static_cast<size_t>(mGridCols) - 1) ?
+                mOutputWidth - tileX * mGridWidth : mGridWidth;
+        size_t height = (tileY == static_cast<size_t>(mGridRows) - 1) ?
+                mOutputHeight - tileY * mGridHeight : mGridHeight;
+        ALOGV("%s: inputBuffer tileIndex [%zu, %zu], top %zu, left %zu, width %zu, height %zu",
+                __FUNCTION__, tileX, tileY, top, left, width, height);
+
+        res = copyOneYuvTile(buffer, inputFrame.yuvBuffer, top, left, width, height);
+        if (res != OK) {
+            ALOGE("%s: Failed to copy YUV tile %s (%d)", __FUNCTION__,
+                    strerror(-res), res);
+            return res;
+        }
+
+        res = mCodec->queueInputBuffer(inputBuffer.index, 0, buffer->capacity(),
+                inputBuffer.timeUs, 0, nullptr /*errorDetailMsg*/);
+        if (res != OK) {
+            ALOGE("%s: Failed to queueInputBuffer to Codec: %s (%d)",
+                    __FUNCTION__, strerror(-res), res);
+            return res;
+        }
+    }
+
+    inputFrame.codecInputBuffers.clear();
+    return OK;
+}
+
+status_t HeicCompositeStream::processOneCodecOutputFrame(nsecs_t timestamp,
+        InputFrame &inputFrame) {
+    auto it = inputFrame.codecOutputBuffers.begin();
+    sp<MediaCodecBuffer> buffer;
+    status_t res = mCodec->getOutputBuffer(it->index, &buffer);
+    if (res != OK) {
+        ALOGE("%s: Error getting Heic codec output buffer at index %d: %s (%d)",
+                __FUNCTION__, it->index, strerror(-res), res);
+        return res;
+    }
+    if (buffer == nullptr) {
+        ALOGE("%s: Invalid Heic codec output buffer at index %d",
+                __FUNCTION__, it->index);
+        return BAD_VALUE;
+    }
+
+    sp<ABuffer> aBuffer = new ABuffer(buffer->data(), buffer->size());
+    res = inputFrame.muxer->writeSampleData(
+            aBuffer, inputFrame.trackIndex, timestamp, 0 /*flags*/);
+    if (res != OK) {
+        ALOGE("%s: Failed to write buffer index %d to muxer: %s (%d)",
+                __FUNCTION__, it->index, strerror(-res), res);
+        return res;
+    }
+
+    mCodec->releaseOutputBuffer(it->index);
+    if (inputFrame.pendingOutputTiles == 0) {
+        ALOGW("%s: Codec generated more tiles than expected!", __FUNCTION__);
+    } else {
+        inputFrame.pendingOutputTiles--;
+    }
+
+    inputFrame.codecOutputBuffers.erase(inputFrame.codecOutputBuffers.begin());
+    return OK;
+}
+
+status_t HeicCompositeStream::processCompletedInputFrame(nsecs_t timestamp,
+        InputFrame &inputFrame) {
+    sp<ANativeWindow> outputANW = mOutputSurface;
+    inputFrame.muxer->stop();
+
+    // Copy the content of the file to memory.
+    sp<GraphicBuffer> gb = GraphicBuffer::from(inputFrame.anb);
+    void* dstBuffer;
+    auto res = gb->lockAsync(GRALLOC_USAGE_SW_WRITE_OFTEN, &dstBuffer, inputFrame.fenceFd);
+    if (res != OK) {
+        ALOGE("%s: Error trying to lock output buffer fence: %s (%d)", __FUNCTION__,
+                strerror(-res), res);
+        return res;
+    }
+
+    off_t fSize = lseek(inputFrame.fileFd, 0, SEEK_END);
+    if (static_cast<size_t>(fSize) > mMaxHeicBufferSize - sizeof(CameraBlob)) {
+        ALOGE("%s: Error: MediaMuxer output size %ld is larger than buffer sizer %zu",
+                __FUNCTION__, fSize, mMaxHeicBufferSize - sizeof(CameraBlob));
+        return BAD_VALUE;
+    }
+
+    lseek(inputFrame.fileFd, 0, SEEK_SET);
+    ssize_t bytesRead = read(inputFrame.fileFd, dstBuffer, fSize);
+    if (bytesRead < fSize) {
+        ALOGE("%s: Only %zd of %ld bytes read", __FUNCTION__, bytesRead, fSize);
+        return BAD_VALUE;
+    }
+
+    close(inputFrame.fileFd);
+    inputFrame.fileFd = -1;
+
+    // Fill in HEIC header
+    uint8_t *header = static_cast<uint8_t*>(dstBuffer) + mMaxHeicBufferSize - sizeof(CameraBlob);
+    struct CameraBlob *blobHeader = (struct CameraBlob *)header;
+    // Must be in sync with CAMERA3_HEIC_BLOB_ID in android_media_Utils.cpp
+    blobHeader->blobId = static_cast<CameraBlobId>(0x00FE);
+    blobHeader->blobSize = fSize;
+
+    res = native_window_set_buffers_timestamp(mOutputSurface.get(), timestamp);
+    if (res != OK) {
+        ALOGE("%s: Stream %d: Error setting timestamp: %s (%d)",
+               __FUNCTION__, getStreamId(), strerror(-res), res);
+        return res;
+    }
+
+    res = outputANW->queueBuffer(mOutputSurface.get(), inputFrame.anb, /*fence*/ -1);
+    if (res != OK) {
+        ALOGE("%s: Failed to queueBuffer to Heic stream: %s (%d)", __FUNCTION__,
+                strerror(-res), res);
+        return res;
+    }
+    inputFrame.anb = nullptr;
+
+    ATRACE_ASYNC_END("HEIC capture", inputFrame.frameNumber);
+    return OK;
+}
+
+
+void HeicCompositeStream::releaseInputFrameLocked(InputFrame *inputFrame /*out*/) {
+    if (inputFrame == nullptr) {
+        return;
+    }
+
+    if (inputFrame->appSegmentBuffer.data != nullptr) {
+        mAppSegmentConsumer->unlockBuffer(inputFrame->appSegmentBuffer);
+        inputFrame->appSegmentBuffer.data = nullptr;
+        mAppSegmentBufferAcquired = false;
+    }
+
+    while (!inputFrame->codecOutputBuffers.empty()) {
+        auto it = inputFrame->codecOutputBuffers.begin();
+        ALOGV("%s: releaseOutputBuffer index %d", __FUNCTION__, it->index);
+        mCodec->releaseOutputBuffer(it->index);
+        inputFrame->codecOutputBuffers.erase(it);
+    }
+
+    if (inputFrame->yuvBuffer.data != nullptr) {
+        mMainImageConsumer->unlockBuffer(inputFrame->yuvBuffer);
+        inputFrame->yuvBuffer.data = nullptr;
+        mYuvBufferAcquired = false;
+    }
+
+    while (!inputFrame->codecInputBuffers.empty()) {
+        auto it = inputFrame->codecInputBuffers.begin();
+        inputFrame->codecInputBuffers.erase(it);
+    }
+
+    if ((inputFrame->error || mErrorState) && !inputFrame->errorNotified) {
+        notifyError(inputFrame->frameNumber);
+        inputFrame->errorNotified = true;
+    }
+
+    if (inputFrame->fileFd >= 0) {
+        close(inputFrame->fileFd);
+        inputFrame->fileFd = -1;
+    }
+
+    if (inputFrame->anb != nullptr) {
+        sp<ANativeWindow> outputANW = mOutputSurface;
+        outputANW->cancelBuffer(mOutputSurface.get(), inputFrame->anb, /*fence*/ -1);
+        inputFrame->anb = nullptr;
+    }
+}
+
+void HeicCompositeStream::releaseInputFramesLocked(int64_t currentTs) {
+    auto it = mPendingInputFrames.begin();
+    while (it != mPendingInputFrames.end()) {
+        if (it->first <= currentTs) {
+            releaseInputFrameLocked(&it->second);
+            it = mPendingInputFrames.erase(it);
+        } else {
+            it++;
+        }
+    }
+}
+
+status_t HeicCompositeStream::initializeCodec(uint32_t width, uint32_t height,
+        const sp<CameraDeviceBase>& cameraDevice) {
+    ALOGV("%s", __FUNCTION__);
+
+    bool useGrid = false;
+    AString hevcName;
+    bool isSizeSupported = isSizeSupportedByHeifEncoder(width, height,
+            &mUseHeic, &useGrid, nullptr, &hevcName);
+    if (!isSizeSupported) {
+        ALOGE("%s: Encoder doesnt' support size %u x %u!",
+                __FUNCTION__, width, height);
+        return BAD_VALUE;
+    }
+
+    // Create Looper for MediaCodec.
+    auto desiredMime = mUseHeic ? MIMETYPE_IMAGE_ANDROID_HEIC : MIMETYPE_VIDEO_HEVC;
+    mCodecLooper = new ALooper;
+    mCodecLooper->setName("Camera3-HeicComposite-MediaCodecLooper");
+    status_t res = mCodecLooper->start(
+            false,   // runOnCallingThread
+            false,    // canCallJava
+            PRIORITY_AUDIO);
+    if (res != OK) {
+        ALOGE("%s: Failed to start codec looper: %s (%d)",
+                __FUNCTION__, strerror(-res), res);
+        return NO_INIT;
+    }
+
+    // Create HEIC/HEVC codec.
+    if (mUseHeic) {
+        mCodec = MediaCodec::CreateByType(mCodecLooper, desiredMime, true /*encoder*/);
+    } else {
+        mCodec = MediaCodec::CreateByComponentName(mCodecLooper, hevcName);
+    }
+    if (mCodec == nullptr) {
+        ALOGE("%s: Failed to create codec for %s", __FUNCTION__, desiredMime);
+        return NO_INIT;
+    }
+
+    // Create Looper and handler for Codec callback.
+    mCodecCallbackHandler = new CodecCallbackHandler(this);
+    if (mCodecCallbackHandler == nullptr) {
+        ALOGE("%s: Failed to create codec callback handler", __FUNCTION__);
+        return NO_MEMORY;
+    }
+    mCallbackLooper = new ALooper;
+    mCallbackLooper->setName("Camera3-HeicComposite-MediaCodecCallbackLooper");
+    res = mCallbackLooper->start(
+            false,   // runOnCallingThread
+            false,    // canCallJava
+            PRIORITY_AUDIO);
+    if (res != OK) {
+        ALOGE("%s: Failed to start media callback looper: %s (%d)",
+                __FUNCTION__, strerror(-res), res);
+        return NO_INIT;
+    }
+    mCallbackLooper->registerHandler(mCodecCallbackHandler);
+
+    mAsyncNotify = new AMessage(kWhatCallbackNotify, mCodecCallbackHandler);
+    res = mCodec->setCallback(mAsyncNotify);
+    if (res != OK) {
+        ALOGE("%s: Failed to set MediaCodec callback: %s (%d)", __FUNCTION__,
+                strerror(-res), res);
+        return res;
+    }
+
+    // Create output format and configure the Codec.
+    sp<AMessage> outputFormat = new AMessage();
+    outputFormat->setString(KEY_MIME, desiredMime);
+    outputFormat->setInt32(KEY_BITRATE_MODE, BITRATE_MODE_CQ);
+    outputFormat->setInt32(KEY_QUALITY, kDefaultJpegQuality);
+    // Ask codec to skip timestamp check and encode all frames.
+    outputFormat->setInt64(KEY_MAX_PTS_GAP_TO_ENCODER, kNoFrameDropMaxPtsGap);
+
+    int32_t gridWidth, gridHeight, gridRows, gridCols;
+    if (useGrid || mUseHeic) {
+        gridWidth = HeicEncoderInfoManager::kGridWidth;
+        gridHeight = HeicEncoderInfoManager::kGridHeight;
+        gridRows = (height + gridHeight - 1)/gridHeight;
+        gridCols = (width + gridWidth - 1)/gridWidth;
+
+        if (mUseHeic) {
+            outputFormat->setInt32(KEY_TILE_WIDTH, gridWidth);
+            outputFormat->setInt32(KEY_TILE_HEIGHT, gridHeight);
+            outputFormat->setInt32(KEY_GRID_COLUMNS, gridCols);
+            outputFormat->setInt32(KEY_GRID_ROWS, gridRows);
+        }
+
+    } else {
+        gridWidth = width;
+        gridHeight = height;
+        gridRows = 1;
+        gridCols = 1;
+    }
+
+    outputFormat->setInt32(KEY_WIDTH, !useGrid ? width : gridWidth);
+    outputFormat->setInt32(KEY_HEIGHT, !useGrid ? height : gridHeight);
+    outputFormat->setInt32(KEY_I_FRAME_INTERVAL, 0);
+    outputFormat->setInt32(KEY_COLOR_FORMAT,
+            useGrid ? COLOR_FormatYUV420Flexible : COLOR_FormatSurface);
+    outputFormat->setInt32(KEY_FRAME_RATE, gridRows * gridCols);
+    // This only serves as a hint to encoder when encoding is not real-time.
+    outputFormat->setInt32(KEY_OPERATING_RATE, useGrid ? kGridOpRate : kNoGridOpRate);
+
+    res = mCodec->configure(outputFormat, nullptr /*nativeWindow*/,
+            nullptr /*crypto*/, CONFIGURE_FLAG_ENCODE);
+    if (res != OK) {
+        ALOGE("%s: Failed to configure codec: %s (%d)", __FUNCTION__,
+                strerror(-res), res);
+        return res;
+    }
+
+    mGridWidth = gridWidth;
+    mGridHeight = gridHeight;
+    mGridRows = gridRows;
+    mGridCols = gridCols;
+    mUseGrid = useGrid;
+    mOutputWidth = width;
+    mOutputHeight = height;
+    mAppSegmentMaxSize = calcAppSegmentMaxSize(cameraDevice->info());
+    mMaxHeicBufferSize = mOutputWidth * mOutputHeight * 3 / 2 + mAppSegmentMaxSize;
+
+    return OK;
+}
+
+void HeicCompositeStream::deinitCodec() {
+    ALOGV("%s", __FUNCTION__);
+    if (mCodec != nullptr) {
+        mCodec->stop();
+        mCodec->release();
+        mCodec.clear();
+    }
+
+    if (mCodecLooper != nullptr) {
+        mCodecLooper->stop();
+        mCodecLooper.clear();
+    }
+
+    if (mCallbackLooper != nullptr) {
+        mCallbackLooper->stop();
+        mCallbackLooper.clear();
+    }
+
+    mAsyncNotify.clear();
+    mFormat.clear();
+}
+
+// Return the size of the complete list of app segment, 0 indicates failure
+size_t HeicCompositeStream::findAppSegmentsSize(const uint8_t* appSegmentBuffer,
+        size_t maxSize, size_t *app1SegmentSize) {
+    if (appSegmentBuffer == nullptr || app1SegmentSize == nullptr) {
+        ALOGE("%s: Invalid input appSegmentBuffer %p, app1SegmentSize %p",
+                __FUNCTION__, appSegmentBuffer, app1SegmentSize);
+        return 0;
+    }
+
+    size_t expectedSize = 0;
+    // First check for EXIF transport header at the end of the buffer
+    const uint8_t *header = appSegmentBuffer + (maxSize - sizeof(struct CameraBlob));
+    const struct CameraBlob *blob = (const struct CameraBlob*)(header);
+    if (blob->blobId != CameraBlobId::JPEG_APP_SEGMENTS) {
+        ALOGE("%s: Invalid EXIF blobId %hu", __FUNCTION__, blob->blobId);
+        return 0;
+    }
+
+    expectedSize = blob->blobSize;
+    if (expectedSize == 0 || expectedSize > maxSize - sizeof(struct CameraBlob)) {
+        ALOGE("%s: Invalid blobSize %zu.", __FUNCTION__, expectedSize);
+        return 0;
+    }
+
+    uint32_t totalSize = 0;
+
+    // Verify APP1 marker (mandatory)
+    uint8_t app1Marker[] = {0xFF, 0xE1};
+    if (memcmp(appSegmentBuffer, app1Marker, sizeof(app1Marker))) {
+        ALOGE("%s: Invalid APP1 marker: %x, %x", __FUNCTION__,
+                appSegmentBuffer[0], appSegmentBuffer[1]);
+        return 0;
+    }
+    totalSize += sizeof(app1Marker);
+
+    uint16_t app1Size = (static_cast<uint16_t>(appSegmentBuffer[totalSize]) << 8) +
+            appSegmentBuffer[totalSize+1];
+    totalSize += app1Size;
+
+    ALOGV("%s: Expected APP segments size %zu, APP1 segment size %u",
+            __FUNCTION__, expectedSize, app1Size);
+    while (totalSize < expectedSize) {
+        if (appSegmentBuffer[totalSize] != 0xFF ||
+                appSegmentBuffer[totalSize+1] <= 0xE1 ||
+                appSegmentBuffer[totalSize+1] > 0xEF) {
+            // Invalid APPn marker
+            ALOGE("%s: Invalid APPn marker: %x, %x", __FUNCTION__,
+                    appSegmentBuffer[totalSize], appSegmentBuffer[totalSize+1]);
+            return 0;
+        }
+        totalSize += 2;
+
+        uint16_t appnSize = (static_cast<uint16_t>(appSegmentBuffer[totalSize]) << 8) +
+                appSegmentBuffer[totalSize+1];
+        totalSize += appnSize;
+    }
+
+    if (totalSize != expectedSize) {
+        ALOGE("%s: Invalid JPEG APP segments: totalSize %u vs expected size %zu",
+                __FUNCTION__, totalSize, expectedSize);
+        return 0;
+    }
+
+    *app1SegmentSize = app1Size + sizeof(app1Marker);
+    return expectedSize;
+}
+
+int64_t HeicCompositeStream::findTimestampInNsLocked(int64_t timeInUs) {
+    for (const auto& fn : mFrameNumberMap) {
+        if (timeInUs == ns2us(fn.second)) {
+            return fn.second;
+        }
+    }
+    for (const auto& inputFrame : mPendingInputFrames) {
+        if (timeInUs == ns2us(inputFrame.first)) {
+            return inputFrame.first;
+        }
+    }
+    return -1;
+}
+
+status_t HeicCompositeStream::copyOneYuvTile(sp<MediaCodecBuffer>& codecBuffer,
+        const CpuConsumer::LockedBuffer& yuvBuffer,
+        size_t top, size_t left, size_t width, size_t height) {
+    ATRACE_CALL();
+
+    // Get stride information for codecBuffer
+    sp<ABuffer> imageData;
+    if (!codecBuffer->meta()->findBuffer("image-data", &imageData)) {
+        ALOGE("%s: Codec input buffer is not for image data!", __FUNCTION__);
+        return BAD_VALUE;
+    }
+    if (imageData->size() != sizeof(MediaImage2)) {
+        ALOGE("%s: Invalid codec input image size %zu, expected %zu",
+                __FUNCTION__, imageData->size(), sizeof(MediaImage2));
+        return BAD_VALUE;
+    }
+    MediaImage2* imageInfo = reinterpret_cast<MediaImage2*>(imageData->data());
+    if (imageInfo->mType != MediaImage2::MEDIA_IMAGE_TYPE_YUV ||
+            imageInfo->mBitDepth != 8 ||
+            imageInfo->mBitDepthAllocated != 8 ||
+            imageInfo->mNumPlanes != 3) {
+        ALOGE("%s: Invalid codec input image info: mType %d, mBitDepth %d, "
+                "mBitDepthAllocated %d, mNumPlanes %d!", __FUNCTION__,
+                imageInfo->mType, imageInfo->mBitDepth,
+                imageInfo->mBitDepthAllocated, imageInfo->mNumPlanes);
+        return BAD_VALUE;
+    }
+
+    ALOGV("%s: yuvBuffer chromaStep %d, chromaStride %d",
+            __FUNCTION__, yuvBuffer.chromaStep, yuvBuffer.chromaStride);
+    ALOGV("%s: U offset %u, V offset %u, U rowInc %d, V rowInc %d, U colInc %d, V colInc %d",
+            __FUNCTION__, imageInfo->mPlane[MediaImage2::U].mOffset,
+            imageInfo->mPlane[MediaImage2::V].mOffset,
+            imageInfo->mPlane[MediaImage2::U].mRowInc,
+            imageInfo->mPlane[MediaImage2::V].mRowInc,
+            imageInfo->mPlane[MediaImage2::U].mColInc,
+            imageInfo->mPlane[MediaImage2::V].mColInc);
+
+    // Y
+    for (auto row = top; row < top+height; row++) {
+        uint8_t *dst = codecBuffer->data() + imageInfo->mPlane[MediaImage2::Y].mOffset +
+                imageInfo->mPlane[MediaImage2::Y].mRowInc * (row - top);
+        mFnCopyRow(yuvBuffer.data+row*yuvBuffer.stride+left, dst, width);
+    }
+
+    // U is Cb, V is Cr
+    bool codecUPlaneFirst = imageInfo->mPlane[MediaImage2::V].mOffset >
+            imageInfo->mPlane[MediaImage2::U].mOffset;
+    uint32_t codecUvOffsetDiff = codecUPlaneFirst ?
+            imageInfo->mPlane[MediaImage2::V].mOffset - imageInfo->mPlane[MediaImage2::U].mOffset :
+            imageInfo->mPlane[MediaImage2::U].mOffset - imageInfo->mPlane[MediaImage2::V].mOffset;
+    bool isCodecUvSemiplannar = (codecUvOffsetDiff == 1) &&
+            (imageInfo->mPlane[MediaImage2::U].mRowInc ==
+            imageInfo->mPlane[MediaImage2::V].mRowInc) &&
+            (imageInfo->mPlane[MediaImage2::U].mColInc == 2) &&
+            (imageInfo->mPlane[MediaImage2::V].mColInc == 2);
+    bool isCodecUvPlannar =
+            ((codecUPlaneFirst && codecUvOffsetDiff >=
+                    imageInfo->mPlane[MediaImage2::U].mRowInc * imageInfo->mHeight/2) ||
+            ((!codecUPlaneFirst && codecUvOffsetDiff >=
+                    imageInfo->mPlane[MediaImage2::V].mRowInc * imageInfo->mHeight/2))) &&
+            imageInfo->mPlane[MediaImage2::U].mColInc == 1 &&
+            imageInfo->mPlane[MediaImage2::V].mColInc == 1;
+    bool cameraUPlaneFirst = yuvBuffer.dataCr > yuvBuffer.dataCb;
+
+    if (isCodecUvSemiplannar && yuvBuffer.chromaStep == 2 &&
+            (codecUPlaneFirst == cameraUPlaneFirst)) {
+        // UV semiplannar
+        // The chrome plane could be either Cb first, or Cr first. Take the
+        // smaller address.
+        uint8_t *src = std::min(yuvBuffer.dataCb, yuvBuffer.dataCr);
+        MediaImage2::PlaneIndex dstPlane = codecUvOffsetDiff > 0 ? MediaImage2::U : MediaImage2::V;
+        for (auto row = top/2; row < (top+height)/2; row++) {
+            uint8_t *dst = codecBuffer->data() + imageInfo->mPlane[dstPlane].mOffset +
+                    imageInfo->mPlane[dstPlane].mRowInc * (row - top/2);
+            mFnCopyRow(src+row*yuvBuffer.chromaStride+left, dst, width);
+        }
+    } else if (isCodecUvPlannar && yuvBuffer.chromaStep == 1) {
+        // U plane
+        for (auto row = top/2; row < (top+height)/2; row++) {
+            uint8_t *dst = codecBuffer->data() + imageInfo->mPlane[MediaImage2::U].mOffset +
+                    imageInfo->mPlane[MediaImage2::U].mRowInc * (row - top/2);
+            mFnCopyRow(yuvBuffer.dataCb+row*yuvBuffer.chromaStride+left/2, dst, width/2);
+        }
+
+        // V plane
+        for (auto row = top/2; row < (top+height)/2; row++) {
+            uint8_t *dst = codecBuffer->data() + imageInfo->mPlane[MediaImage2::V].mOffset +
+                    imageInfo->mPlane[MediaImage2::V].mRowInc * (row - top/2);
+            mFnCopyRow(yuvBuffer.dataCr+row*yuvBuffer.chromaStride+left/2, dst, width/2);
+        }
+    } else {
+        // Convert between semiplannar and plannar, or when UV orders are
+        // different.
+        uint8_t *dst = codecBuffer->data();
+        for (auto row = top/2; row < (top+height)/2; row++) {
+            for (auto col = left/2; col < (left+width)/2; col++) {
+                // U/Cb
+                int32_t dstIndex = imageInfo->mPlane[MediaImage2::U].mOffset +
+                        imageInfo->mPlane[MediaImage2::U].mRowInc * (row - top/2) +
+                        imageInfo->mPlane[MediaImage2::U].mColInc * (col - left/2);
+                int32_t srcIndex = row * yuvBuffer.chromaStride + yuvBuffer.chromaStep * col;
+                dst[dstIndex] = yuvBuffer.dataCb[srcIndex];
+
+                // V/Cr
+                dstIndex = imageInfo->mPlane[MediaImage2::V].mOffset +
+                        imageInfo->mPlane[MediaImage2::V].mRowInc * (row - top/2) +
+                        imageInfo->mPlane[MediaImage2::V].mColInc * (col - left/2);
+                srcIndex = row * yuvBuffer.chromaStride + yuvBuffer.chromaStep * col;
+                dst[dstIndex] = yuvBuffer.dataCr[srcIndex];
+            }
+        }
+    }
+    return OK;
+}
+
+void HeicCompositeStream::initCopyRowFunction(int32_t width)
+{
+    using namespace libyuv;
+
+    mFnCopyRow = CopyRow_C;
+#if defined(HAS_COPYROW_SSE2)
+    if (TestCpuFlag(kCpuHasSSE2)) {
+        mFnCopyRow = IS_ALIGNED(width, 32) ? CopyRow_SSE2 : CopyRow_Any_SSE2;
+    }
+#endif
+#if defined(HAS_COPYROW_AVX)
+    if (TestCpuFlag(kCpuHasAVX)) {
+        mFnCopyRow = IS_ALIGNED(width, 64) ? CopyRow_AVX : CopyRow_Any_AVX;
+    }
+#endif
+#if defined(HAS_COPYROW_ERMS)
+    if (TestCpuFlag(kCpuHasERMS)) {
+        mFnCopyRow = CopyRow_ERMS;
+    }
+#endif
+#if defined(HAS_COPYROW_NEON)
+    if (TestCpuFlag(kCpuHasNEON)) {
+        mFnCopyRow = IS_ALIGNED(width, 32) ? CopyRow_NEON : CopyRow_Any_NEON;
+    }
+#endif
+#if defined(HAS_COPYROW_MIPS)
+    if (TestCpuFlag(kCpuHasMIPS)) {
+        mFnCopyRow = CopyRow_MIPS;
+    }
+#endif
+}
+
+size_t HeicCompositeStream::calcAppSegmentMaxSize(const CameraMetadata& info) {
+    camera_metadata_ro_entry_t entry = info.find(ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT);
+    size_t maxAppsSegment = 1;
+    if (entry.count > 0) {
+        maxAppsSegment = entry.data.u8[0] < 1 ? 1 :
+                entry.data.u8[0] > 16 ? 16 : entry.data.u8[0];
+    }
+    return maxAppsSegment * (2 + 0xFFFF) + sizeof(struct CameraBlob);
+}
+
+bool HeicCompositeStream::threadLoop() {
+    int64_t currentTs = INT64_MAX;
+    bool newInputAvailable = false;
+
+    {
+        Mutex::Autolock l(mMutex);
+        if (mErrorState) {
+            // In case we landed in error state, return any pending buffers and
+            // halt all further processing.
+            compilePendingInputLocked();
+            releaseInputFramesLocked(currentTs);
+            return false;
+        }
+
+
+        while (!newInputAvailable) {
+            compilePendingInputLocked();
+            newInputAvailable = getNextReadyInputLocked(&currentTs);
+
+            if (!newInputAvailable) {
+                auto failingFrameNumber = getNextFailingInputLocked(&currentTs);
+                if (failingFrameNumber >= 0) {
+                    // We cannot erase 'mPendingInputFrames[currentTs]' at this point because it is
+                    // possible for two internal stream buffers to fail. In such scenario the
+                    // composite stream should notify the client about a stream buffer error only
+                    // once and this information is kept within 'errorNotified'.
+                    // Any present failed input frames will be removed on a subsequent call to
+                    // 'releaseInputFramesLocked()'.
+                    releaseInputFrameLocked(&mPendingInputFrames[currentTs]);
+                    currentTs = INT64_MAX;
+                }
+
+                auto ret = mInputReadyCondition.waitRelative(mMutex, kWaitDuration);
+                if (ret == TIMED_OUT) {
+                    return true;
+                } else if (ret != OK) {
+                    ALOGE("%s: Timed wait on condition failed: %s (%d)", __FUNCTION__,
+                            strerror(-ret), ret);
+                    return false;
+                }
+            }
+        }
+    }
+
+    auto res = processInputFrame(currentTs, mPendingInputFrames[currentTs]);
+    Mutex::Autolock l(mMutex);
+    if (res != OK) {
+        ALOGE("%s: Failed processing frame with timestamp: %" PRIu64 ": %s (%d)",
+                __FUNCTION__, currentTs, strerror(-res), res);
+        mPendingInputFrames[currentTs].error = true;
+    }
+
+    if (mPendingInputFrames[currentTs].error ||
+            (mPendingInputFrames[currentTs].appSegmentWritten &&
+            mPendingInputFrames[currentTs].pendingOutputTiles == 0)) {
+        releaseInputFramesLocked(currentTs);
+    }
+
+    return true;
+}
+
+bool HeicCompositeStream::onStreamBufferError(const CaptureResultExtras& resultExtras) {
+    bool res = false;
+    // Buffer errors concerning internal composite streams should not be directly visible to
+    // camera clients. They must only receive a single buffer error with the public composite
+    // stream id.
+    if ((resultExtras.errorStreamId == mAppSegmentStreamId) ||
+            (resultExtras.errorStreamId == mMainImageStreamId)) {
+        flagAnErrorFrameNumber(resultExtras.frameNumber);
+        res = true;
+    }
+
+    return res;
+}
+
+void HeicCompositeStream::onResultError(const CaptureResultExtras& resultExtras) {
+    // For result error, since the APPS_SEGMENT buffer already contains EXIF,
+    // simply skip using the capture result metadata to override EXIF.
+    Mutex::Autolock l(mMutex);
+
+    int64_t timestamp = -1;
+    for (const auto& fn : mFrameNumberMap) {
+        if (fn.first == resultExtras.frameNumber) {
+            timestamp = fn.second;
+            break;
+        }
+    }
+    if (timestamp == -1) {
+        for (const auto& inputFrame : mPendingInputFrames) {
+            if (inputFrame.second.frameNumber == resultExtras.frameNumber) {
+                timestamp = inputFrame.first;
+                break;
+            }
+        }
+    }
+
+    if (timestamp == -1) {
+        ALOGE("%s: Failed to find shutter timestamp for result error!", __FUNCTION__);
+        return;
+    }
+
+    mCaptureResults.emplace(timestamp, std::make_tuple(resultExtras.frameNumber, CameraMetadata()));
+    mInputReadyCondition.signal();
+}
+
+void HeicCompositeStream::CodecCallbackHandler::onMessageReceived(const sp<AMessage> &msg) {
+    sp<HeicCompositeStream> parent = mParent.promote();
+    if (parent == nullptr) return;
+
+    switch (msg->what()) {
+        case kWhatCallbackNotify: {
+             int32_t cbID;
+             if (!msg->findInt32("callbackID", &cbID)) {
+                 ALOGE("kWhatCallbackNotify: callbackID is expected.");
+                 break;
+             }
+
+             ALOGV("kWhatCallbackNotify: cbID = %d", cbID);
+
+             switch (cbID) {
+                 case MediaCodec::CB_INPUT_AVAILABLE: {
+                     int32_t index;
+                     if (!msg->findInt32("index", &index)) {
+                         ALOGE("CB_INPUT_AVAILABLE: index is expected.");
+                         break;
+                     }
+                     parent->onHeicInputFrameAvailable(index);
+                     break;
+                 }
+
+                 case MediaCodec::CB_OUTPUT_AVAILABLE: {
+                     int32_t index;
+                     size_t offset;
+                     size_t size;
+                     int64_t timeUs;
+                     int32_t flags;
+
+                     if (!msg->findInt32("index", &index)) {
+                         ALOGE("CB_OUTPUT_AVAILABLE: index is expected.");
+                         break;
+                     }
+                     if (!msg->findSize("offset", &offset)) {
+                         ALOGE("CB_OUTPUT_AVAILABLE: offset is expected.");
+                         break;
+                     }
+                     if (!msg->findSize("size", &size)) {
+                         ALOGE("CB_OUTPUT_AVAILABLE: size is expected.");
+                         break;
+                     }
+                     if (!msg->findInt64("timeUs", &timeUs)) {
+                         ALOGE("CB_OUTPUT_AVAILABLE: timeUs is expected.");
+                         break;
+                     }
+                     if (!msg->findInt32("flags", &flags)) {
+                         ALOGE("CB_OUTPUT_AVAILABLE: flags is expected.");
+                         break;
+                     }
+
+                     CodecOutputBufferInfo bufferInfo = {
+                         index,
+                         (int32_t)offset,
+                         (int32_t)size,
+                         timeUs,
+                         (uint32_t)flags};
+
+                     parent->onHeicOutputFrameAvailable(bufferInfo);
+                     break;
+                 }
+
+                 case MediaCodec::CB_OUTPUT_FORMAT_CHANGED: {
+                     sp<AMessage> format;
+                     if (!msg->findMessage("format", &format)) {
+                         ALOGE("CB_OUTPUT_FORMAT_CHANGED: format is expected.");
+                         break;
+                     }
+
+                     parent->onHeicFormatChanged(format);
+                     break;
+                 }
+
+                 case MediaCodec::CB_ERROR: {
+                     status_t err;
+                     int32_t actionCode;
+                     AString detail;
+                     if (!msg->findInt32("err", &err)) {
+                         ALOGE("CB_ERROR: err is expected.");
+                         break;
+                     }
+                     if (!msg->findInt32("action", &actionCode)) {
+                         ALOGE("CB_ERROR: action is expected.");
+                         break;
+                     }
+                     msg->findString("detail", &detail);
+                     ALOGE("Codec reported error(0x%x), actionCode(%d), detail(%s)",
+                             err, actionCode, detail.c_str());
+
+                     parent->onHeicCodecError();
+                     break;
+                 }
+
+                 default: {
+                     ALOGE("kWhatCallbackNotify: callbackID(%d) is unexpected.", cbID);
+                     break;
+                 }
+             }
+             break;
+        }
+
+        default:
+            ALOGE("shouldn't be here");
+            break;
+    }
+}
+
+}; // namespace camera3
+}; // namespace android
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.h b/services/camera/libcameraservice/api2/HeicCompositeStream.h
new file mode 100644
index 0000000..260c68e
--- /dev/null
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.h
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SERVERS_CAMERA_CAMERA3_HEIC_COMPOSITE_STREAM_H
+#define ANDROID_SERVERS_CAMERA_CAMERA3_HEIC_COMPOSITE_STREAM_H
+
+#include <queue>
+
+#include <gui/IProducerListener.h>
+#include <gui/CpuConsumer.h>
+
+#include <media/hardware/VideoAPI.h>
+#include <media/MediaCodecBuffer.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/MediaCodec.h>
+#include <media/stagefright/MediaMuxer.h>
+
+#include "CompositeStream.h"
+
+namespace android {
+namespace camera3 {
+
+class HeicCompositeStream : public CompositeStream, public Thread,
+        public CpuConsumer::FrameAvailableListener {
+public:
+    HeicCompositeStream(wp<CameraDeviceBase> device,
+            wp<hardware::camera2::ICameraDeviceCallbacks> cb);
+    ~HeicCompositeStream() override;
+
+    static bool isHeicCompositeStream(const sp<Surface> &surface);
+
+    status_t createInternalStreams(const std::vector<sp<Surface>>& consumers,
+            bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
+            camera3_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+            std::vector<int> *surfaceIds, int streamSetId, bool isShared) override;
+
+    status_t deleteInternalStreams() override;
+
+    status_t configureStream() override;
+
+    status_t insertGbp(SurfaceMap* /*out*/outSurfaceMap, Vector<int32_t>* /*out*/outputStreamIds,
+            int32_t* /*out*/currentStreamId) override;
+
+    void onShutter(const CaptureResultExtras& resultExtras, nsecs_t timestamp) override;
+
+    int getStreamId() override { return mMainImageStreamId; }
+
+    // Use onShutter to keep track of frame number <-> timestamp mapping.
+    void onBufferReleased(const BufferInfo& bufferInfo) override;
+    void onBufferRequestForFrameNumber(uint64_t frameNumber, int streamId,
+            const CameraMetadata& settings) override;
+
+    // CpuConsumer listener implementation
+    void onFrameAvailable(const BufferItem& item) override;
+
+    // Return stream information about the internal camera streams
+    static status_t getCompositeStreamInfo(const OutputStreamInfo &streamInfo,
+            const CameraMetadata& ch, std::vector<OutputStreamInfo>* compositeOutput /*out*/);
+
+    static bool isSizeSupportedByHeifEncoder(int32_t width, int32_t height,
+            bool* useHeic, bool* useGrid, int64_t* stall, AString* hevcName = nullptr);
+    static bool isInMemoryTempFileSupported();
+protected:
+
+    bool threadLoop() override;
+    bool onStreamBufferError(const CaptureResultExtras& resultExtras) override;
+    void onResultError(const CaptureResultExtras& resultExtras) override;
+
+private:
+    //
+    // HEIC/HEVC Codec related structures, utility functions, and callbacks
+    //
+    struct CodecOutputBufferInfo {
+        int32_t index;
+        int32_t offset;
+        int32_t size;
+        int64_t timeUs;
+        uint32_t flags;
+    };
+
+    struct CodecInputBufferInfo {
+        int32_t index;
+        int64_t timeUs;
+        size_t tileIndex;
+    };
+
+    class CodecCallbackHandler : public AHandler {
+    public:
+        explicit CodecCallbackHandler(wp<HeicCompositeStream> parent) {
+            mParent = parent;
+        }
+        virtual void onMessageReceived(const sp<AMessage> &msg);
+    private:
+        wp<HeicCompositeStream> mParent;
+    };
+
+    enum {
+        kWhatCallbackNotify,
+    };
+
+    bool              mUseHeic;
+    sp<MediaCodec>    mCodec;
+    sp<ALooper>       mCodecLooper, mCallbackLooper;
+    sp<CodecCallbackHandler> mCodecCallbackHandler;
+    sp<AMessage>      mAsyncNotify;
+    sp<AMessage>      mFormat;
+    size_t            mNumOutputTiles;
+
+    int32_t           mOutputWidth, mOutputHeight;
+    size_t            mMaxHeicBufferSize;
+    int32_t           mGridWidth, mGridHeight;
+    size_t            mGridRows, mGridCols;
+    bool              mUseGrid; // Whether to use framework YUV frame tiling.
+
+    static const int64_t kNoFrameDropMaxPtsGap = -1000000;
+    static const int32_t kNoGridOpRate = 30;
+    static const int32_t kGridOpRate = 120;
+
+    void onHeicOutputFrameAvailable(const CodecOutputBufferInfo& bufferInfo);
+    void onHeicInputFrameAvailable(int32_t index);  // Only called for YUV input mode.
+    void onHeicFormatChanged(sp<AMessage>& newFormat);
+    void onHeicCodecError();
+
+    status_t initializeCodec(uint32_t width, uint32_t height,
+            const sp<CameraDeviceBase>& cameraDevice);
+    void deinitCodec();
+
+    //
+    // Composite stream related structures, utility functions and callbacks.
+    //
+    struct InputFrame {
+        int32_t                   orientation;
+        int32_t                   quality;
+
+        CpuConsumer::LockedBuffer          appSegmentBuffer;
+        std::vector<CodecOutputBufferInfo> codecOutputBuffers;
+        std::unique_ptr<CameraMetadata>    result;
+
+        // Fields that are only applicable to HEVC tiling.
+        CpuConsumer::LockedBuffer          yuvBuffer;
+        std::vector<CodecInputBufferInfo>  codecInputBuffers;
+
+        bool                      error;
+        bool                      errorNotified;
+        int64_t                   frameNumber;
+
+        sp<MediaMuxer>            muxer;
+        int                       fenceFd;
+        int                       fileFd;
+        ssize_t                   trackIndex;
+        ANativeWindowBuffer       *anb;
+
+        bool                      appSegmentWritten;
+        size_t                    pendingOutputTiles;
+        size_t                    codecInputCounter;
+
+        InputFrame() : orientation(0), quality(kDefaultJpegQuality), error(false),
+                       errorNotified(false), frameNumber(-1), fenceFd(-1), fileFd(-1),
+                       trackIndex(-1), anb(nullptr), appSegmentWritten(false),
+                       pendingOutputTiles(0), codecInputCounter(0) { }
+    };
+
+    void compilePendingInputLocked();
+    // Find first complete and valid frame with smallest timestamp
+    bool getNextReadyInputLocked(int64_t *currentTs /*out*/);
+    // Find next failing frame number with smallest timestamp and return respective frame number
+    int64_t getNextFailingInputLocked(int64_t *currentTs /*out*/);
+
+    status_t processInputFrame(nsecs_t timestamp, InputFrame &inputFrame);
+    status_t processCodecInputFrame(InputFrame &inputFrame);
+    status_t startMuxerForInputFrame(nsecs_t timestamp, InputFrame &inputFrame);
+    status_t processAppSegment(nsecs_t timestamp, InputFrame &inputFrame);
+    status_t processOneCodecOutputFrame(nsecs_t timestamp, InputFrame &inputFrame);
+    status_t processCompletedInputFrame(nsecs_t timestamp, InputFrame &inputFrame);
+
+    void releaseInputFrameLocked(InputFrame *inputFrame /*out*/);
+    void releaseInputFramesLocked(int64_t currentTs);
+
+    size_t findAppSegmentsSize(const uint8_t* appSegmentBuffer, size_t maxSize,
+            size_t* app1SegmentSize);
+    int64_t findTimestampInNsLocked(int64_t timeInUs);
+    status_t copyOneYuvTile(sp<MediaCodecBuffer>& codecBuffer,
+            const CpuConsumer::LockedBuffer& yuvBuffer,
+            size_t top, size_t left, size_t width, size_t height);
+    void initCopyRowFunction(int32_t width);
+    static size_t calcAppSegmentMaxSize(const CameraMetadata& info);
+
+    static const nsecs_t kWaitDuration = 10000000; // 10 ms
+    static const int32_t kDefaultJpegQuality = 99;
+    static const auto kJpegDataSpace = HAL_DATASPACE_V0_JFIF;
+    static const android_dataspace kAppSegmentDataSpace =
+            static_cast<android_dataspace>(HAL_DATASPACE_JPEG_APP_SEGMENTS);
+    static const android_dataspace kHeifDataSpace =
+            static_cast<android_dataspace>(HAL_DATASPACE_HEIF);
+
+    int               mAppSegmentStreamId, mAppSegmentSurfaceId;
+    sp<CpuConsumer>   mAppSegmentConsumer;
+    sp<Surface>       mAppSegmentSurface;
+    bool              mAppSegmentBufferAcquired;
+    size_t            mAppSegmentMaxSize;
+    CameraMetadata    mStaticInfo;
+
+    int               mMainImageStreamId, mMainImageSurfaceId;
+    sp<Surface>       mMainImageSurface;
+    sp<CpuConsumer>   mMainImageConsumer; // Only applicable for HEVC codec.
+    bool              mYuvBufferAcquired; // Only applicable to HEVC codec
+
+    sp<Surface>       mOutputSurface;
+    sp<ProducerListener> mProducerListener;
+
+
+    // Map from frame number to JPEG setting of orientation+quality
+    std::map<int64_t, std::pair<int32_t, int32_t>> mSettingsByFrameNumber;
+    // Map from timestamp to JPEG setting of orientation+quality
+    std::map<int64_t, std::pair<int32_t, int32_t>> mSettingsByTimestamp;
+
+    // Keep all incoming APP segment Blob buffer pending further processing.
+    std::vector<int64_t> mInputAppSegmentBuffers;
+
+    // Keep all incoming HEIC blob buffer pending further processing.
+    std::vector<CodecOutputBufferInfo> mCodecOutputBuffers;
+    std::queue<int64_t> mCodecOutputBufferTimestamps;
+    size_t mOutputBufferCounter;
+
+    // Keep all incoming Yuv buffer pending tiling and encoding (for HEVC YUV tiling only)
+    std::vector<int64_t> mInputYuvBuffers;
+    // Keep all codec input buffers ready to be filled out (for HEVC YUV tiling only)
+    std::vector<int32_t> mCodecInputBuffers;
+
+    // Artificial strictly incremental YUV grid timestamp to make encoder happy.
+    int64_t mGridTimestampUs;
+
+    // In most common use case, entries are accessed in order.
+    std::map<int64_t, InputFrame> mPendingInputFrames;
+
+    // Function pointer of libyuv row copy.
+    void (*mFnCopyRow)(const uint8_t* src, uint8_t* dst, int width);
+};
+
+}; // namespace camera3
+}; // namespace android
+
+#endif //ANDROID_SERVERS_CAMERA_CAMERA3_HEIC_COMPOSITE_STREAM_H
diff --git a/services/camera/libcameraservice/api2/HeicEncoderInfoManager.cpp b/services/camera/libcameraservice/api2/HeicEncoderInfoManager.cpp
new file mode 100644
index 0000000..d7cc2bf
--- /dev/null
+++ b/services/camera/libcameraservice/api2/HeicEncoderInfoManager.cpp
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "HeicEncoderInfoManager"
+//#define LOG_NDEBUG 0
+
+#include <cstdint>
+#include <regex>
+
+#include <cutils/properties.h>
+#include <log/log_main.h>
+#include <system/graphics.h>
+
+#include <media/stagefright/MediaCodecList.h>
+#include <media/stagefright/foundation/MediaDefs.h>
+#include <media/stagefright/foundation/ABuffer.h>
+
+#include "HeicEncoderInfoManager.h"
+
+namespace android {
+namespace camera3 {
+
+HeicEncoderInfoManager::HeicEncoderInfoManager() :
+        mIsInited(false),
+        mMinSizeHeic(0, 0),
+        mMaxSizeHeic(INT32_MAX, INT32_MAX),
+        mHasHEVC(false),
+        mHasHEIC(false),
+        mDisableGrid(false) {
+    if (initialize() == OK) {
+        mIsInited = true;
+    }
+}
+
+HeicEncoderInfoManager::~HeicEncoderInfoManager() {
+}
+
+bool HeicEncoderInfoManager::isSizeSupported(int32_t width, int32_t height, bool* useHeic,
+        bool* useGrid, int64_t* stall, AString* hevcName) const {
+    if (useHeic == nullptr || useGrid == nullptr) {
+        ALOGE("%s: invalid parameters: useHeic %p, useGrid %p",
+                __FUNCTION__, useHeic, useGrid);
+        return false;
+    }
+    if (!mIsInited) return false;
+
+    bool chooseHeic = false, enableGrid = true;
+    if (mHasHEIC && width >= mMinSizeHeic.first &&
+            height >= mMinSizeHeic.second && width <= mMaxSizeHeic.first &&
+            height <= mMaxSizeHeic.second) {
+        chooseHeic = true;
+        enableGrid = false;
+    } else if (mHasHEVC) {
+        bool fullSizeSupportedByHevc = (width >= mMinSizeHevc.first &&
+                height >= mMinSizeHevc.second &&
+                width <= mMaxSizeHevc.first &&
+                height <= mMaxSizeHevc.second);
+        if (fullSizeSupportedByHevc && (mDisableGrid ||
+                (width <= 1920 && height <= 1080))) {
+            enableGrid = false;
+        }
+        if (hevcName != nullptr) {
+            *hevcName = mHevcName;
+        }
+    } else {
+        // No encoder available for the requested size.
+        return false;
+    }
+
+    if (stall != nullptr) {
+        // Find preferred encoder which advertise
+        // "measured-frame-rate-WIDTHxHEIGHT-range" key.
+        const FrameRateMaps& maps =
+                (chooseHeic && mHeicFrameRateMaps.size() > 0) ?
+                mHeicFrameRateMaps : mHevcFrameRateMaps;
+        const auto& closestSize = findClosestSize(maps, width, height);
+        if (closestSize == maps.end()) {
+            // The "measured-frame-rate-WIDTHxHEIGHT-range" key is optional.
+            // Hardcode to some default value (3.33ms * tile count) based on resolution.
+            *stall = 3333333LL * width * height / (kGridWidth * kGridHeight);
+            return true;
+        }
+
+        // Derive stall durations based on average fps of the closest size.
+        constexpr int64_t NSEC_PER_SEC = 1000000000LL;
+        int32_t avgFps = (closestSize->second.first + closestSize->second.second)/2;
+        float ratio = 1.0f * width * height /
+                (closestSize->first.first * closestSize->first.second);
+        *stall = ratio * NSEC_PER_SEC / avgFps;
+    }
+
+    *useHeic = chooseHeic;
+    *useGrid = enableGrid;
+    return true;
+}
+
+status_t HeicEncoderInfoManager::initialize() {
+    mDisableGrid = property_get_bool("camera.heic.disable_grid", false);
+    sp<IMediaCodecList> codecsList = MediaCodecList::getInstance();
+    if (codecsList == nullptr) {
+        // No media codec available.
+        return OK;
+    }
+
+    sp<AMessage> heicDetails = getCodecDetails(codecsList, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC);
+
+    if (!getHevcCodecDetails(codecsList, MEDIA_MIMETYPE_VIDEO_HEVC)) {
+        if (heicDetails != nullptr) {
+            ALOGE("%s: Device must support HEVC codec if HEIC codec is available!",
+                    __FUNCTION__);
+            return BAD_VALUE;
+        }
+        return OK;
+    }
+    mHasHEVC = true;
+
+    // HEIC size range
+    if (heicDetails != nullptr) {
+        auto res = getCodecSizeRange(MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC,
+                heicDetails, &mMinSizeHeic, &mMaxSizeHeic, &mHeicFrameRateMaps);
+        if (res != OK) {
+            ALOGE("%s: Failed to get HEIC codec size range: %s (%d)", __FUNCTION__,
+                    strerror(-res), res);
+            return BAD_VALUE;
+        }
+        mHasHEIC = true;
+    }
+
+    return OK;
+}
+
+status_t HeicEncoderInfoManager::getFrameRateMaps(sp<AMessage> details, FrameRateMaps* maps) {
+    if (details == nullptr || maps == nullptr) {
+        ALOGE("%s: Invalid input: details: %p, maps: %p", __FUNCTION__, details.get(), maps);
+        return BAD_VALUE;
+    }
+
+    for (size_t i = 0; i < details->countEntries(); i++) {
+        AMessage::Type type;
+        const char* entryName = details->getEntryNameAt(i, &type);
+        if (type != AMessage::kTypeString) continue;
+        std::regex frameRateNamePattern("measured-frame-rate-([0-9]+)[*x]([0-9]+)-range",
+                std::regex_constants::icase);
+        std::cmatch sizeMatch;
+        if (std::regex_match(entryName, sizeMatch, frameRateNamePattern) &&
+                sizeMatch.size() == 3) {
+            AMessage::ItemData item = details->getEntryAt(i);
+            AString fpsRangeStr;
+            if (item.find(&fpsRangeStr)) {
+                ALOGV("%s: %s", entryName, fpsRangeStr.c_str());
+                std::regex frameRatePattern("([0-9]+)-([0-9]+)");
+                std::cmatch fpsMatch;
+                if (std::regex_match(fpsRangeStr.c_str(), fpsMatch, frameRatePattern) &&
+                        fpsMatch.size() == 3) {
+                    maps->emplace(
+                            std::make_pair(stoi(sizeMatch[1]), stoi(sizeMatch[2])),
+                            std::make_pair(stoi(fpsMatch[1]), stoi(fpsMatch[2])));
+                } else {
+                    return BAD_VALUE;
+                }
+            }
+        }
+    }
+    return OK;
+}
+
+status_t HeicEncoderInfoManager::getCodecSizeRange(
+        const char* codecName,
+        sp<AMessage> details,
+        std::pair<int32_t, int32_t>* minSize,
+        std::pair<int32_t, int32_t>* maxSize,
+        FrameRateMaps* frameRateMaps) {
+    if (codecName == nullptr || minSize == nullptr || maxSize == nullptr ||
+            details == nullptr || frameRateMaps == nullptr) {
+        return BAD_VALUE;
+    }
+
+    AString sizeRange;
+    auto hasItem = details->findString("size-range", &sizeRange);
+    if (!hasItem) {
+        ALOGE("%s: Failed to query size range for codec %s", __FUNCTION__, codecName);
+        return BAD_VALUE;
+    }
+    ALOGV("%s: %s codec's size range is %s", __FUNCTION__, codecName, sizeRange.c_str());
+    std::regex pattern("([0-9]+)[*x]([0-9]+)-([0-9]+)[*x]([0-9]+)");
+    std::cmatch match;
+    if (std::regex_match(sizeRange.c_str(), match, pattern)) {
+        if (match.size() == 5) {
+            minSize->first = stoi(match[1]);
+            minSize->second = stoi(match[2]);
+            maxSize->first = stoi(match[3]);
+            maxSize->second = stoi(match[4]);
+            if (minSize->first > maxSize->first ||
+                    minSize->second > maxSize->second) {
+                ALOGE("%s: Invalid %s code size range: %s",
+                        __FUNCTION__, codecName, sizeRange.c_str());
+                return BAD_VALUE;
+            }
+        } else {
+            return BAD_VALUE;
+        }
+    }
+
+    auto res = getFrameRateMaps(details, frameRateMaps);
+    if (res != OK) {
+        return res;
+    }
+
+    return OK;
+}
+
+HeicEncoderInfoManager::FrameRateMaps::const_iterator HeicEncoderInfoManager::findClosestSize(
+        const FrameRateMaps& maps, int32_t width, int32_t height) const {
+    int32_t minDiff = INT32_MAX;
+    FrameRateMaps::const_iterator closestIter = maps.begin();
+    for (auto iter = maps.begin(); iter != maps.end(); iter++) {
+        // Use area difference between the sizes to approximate size
+        // difference.
+        int32_t diff = abs(iter->first.first * iter->first.second - width * height);
+        if (diff < minDiff) {
+            closestIter = iter;
+            minDiff = diff;
+        }
+    }
+    return closestIter;
+}
+
+sp<AMessage> HeicEncoderInfoManager::getCodecDetails(
+        sp<IMediaCodecList> codecsList, const char* name) {
+    ssize_t idx = codecsList->findCodecByType(name, true /*encoder*/);
+    if (idx < 0) {
+        return nullptr;
+    }
+
+    const sp<MediaCodecInfo> info = codecsList->getCodecInfo(idx);
+    if (info == nullptr) {
+        ALOGE("%s: Failed to get codec info for %s", __FUNCTION__, name);
+        return nullptr;
+    }
+    const sp<MediaCodecInfo::Capabilities> caps =
+            info->getCapabilitiesFor(name);
+    if (caps == nullptr) {
+        ALOGE("%s: Failed to get capabilities for codec %s", __FUNCTION__, name);
+        return nullptr;
+    }
+    const sp<AMessage> details = caps->getDetails();
+    if (details == nullptr) {
+        ALOGE("%s: Failed to get details for codec %s", __FUNCTION__, name);
+        return nullptr;
+    }
+
+    return details;
+}
+
+bool HeicEncoderInfoManager::getHevcCodecDetails(
+        sp<IMediaCodecList> codecsList, const char* mime) {
+    bool found = false;
+    ssize_t idx = 0;
+    while ((idx = codecsList->findCodecByType(mime, true /*encoder*/, idx)) >= 0) {
+        const sp<MediaCodecInfo> info = codecsList->getCodecInfo(idx++);
+        if (info == nullptr) {
+            ALOGE("%s: Failed to get codec info for %s", __FUNCTION__, mime);
+            break;
+        }
+
+        // Filter out software ones as they may be too slow
+        if (!(info->getAttributes() & MediaCodecInfo::kFlagIsHardwareAccelerated)) {
+            continue;
+        }
+
+        const sp<MediaCodecInfo::Capabilities> caps =
+                info->getCapabilitiesFor(mime);
+        if (caps == nullptr) {
+            ALOGE("%s: [%s] Failed to get capabilities", __FUNCTION__,
+                    info->getCodecName());
+            break;
+        }
+        const sp<AMessage> details = caps->getDetails();
+        if (details == nullptr) {
+            ALOGE("%s: [%s] Failed to get details", __FUNCTION__,
+                    info->getCodecName());
+            break;
+        }
+
+        // Check CQ mode
+        AString bitrateModes;
+        auto hasItem = details->findString("feature-bitrate-modes", &bitrateModes);
+        if (!hasItem) {
+            ALOGE("%s: [%s] Failed to query bitrate modes", __FUNCTION__,
+                    info->getCodecName());
+            break;
+        }
+        ALOGV("%s: [%s] feature-bitrate-modes value is %d, %s",
+                __FUNCTION__, info->getCodecName(), hasItem, bitrateModes.c_str());
+        std::regex pattern("(^|,)CQ($|,)", std::regex_constants::icase);
+        if (!std::regex_search(bitrateModes.c_str(), pattern)) {
+            continue; // move on to next encoder
+        }
+
+        std::pair<int32_t, int32_t> minSizeHevc, maxSizeHevc;
+        FrameRateMaps hevcFrameRateMaps;
+        auto res = getCodecSizeRange(MEDIA_MIMETYPE_VIDEO_HEVC,
+                details, &minSizeHevc, &maxSizeHevc, &hevcFrameRateMaps);
+        if (res != OK) {
+            ALOGE("%s: [%s] Failed to get size range: %s (%d)", __FUNCTION__,
+                    info->getCodecName(), strerror(-res), res);
+            break;
+        }
+        if (kGridWidth < minSizeHevc.first
+                || kGridWidth > maxSizeHevc.first
+                || kGridHeight < minSizeHevc.second
+                || kGridHeight > maxSizeHevc.second) {
+            continue; // move on to next encoder
+        }
+
+        // Found: save name, size, frame rate
+        mHevcName = info->getCodecName();
+        mMinSizeHevc = minSizeHevc;
+        mMaxSizeHevc = maxSizeHevc;
+        mHevcFrameRateMaps = hevcFrameRateMaps;
+
+        found = true;
+        break;
+    }
+
+    return found;
+}
+
+} //namespace camera3
+} // namespace android
diff --git a/services/camera/libcameraservice/api2/HeicEncoderInfoManager.h b/services/camera/libcameraservice/api2/HeicEncoderInfoManager.h
new file mode 100644
index 0000000..58edba2
--- /dev/null
+++ b/services/camera/libcameraservice/api2/HeicEncoderInfoManager.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SERVERS_CAMERA_HEICENCODER_INFO_MANAGER_H
+#define ANDROID_SERVERS_CAMERA_HEICENCODER_INFO_MANAGER_H
+
+#include <unordered_map>
+#include <utility>
+#include <utils/Errors.h>
+#include <utils/StrongPointer.h>
+
+#include <media/IMediaCodecList.h>
+#include <media/stagefright/foundation/AMessage.h>
+
+namespace android {
+namespace camera3 {
+
+class HeicEncoderInfoManager {
+public:
+    static HeicEncoderInfoManager& getInstance() {
+        static HeicEncoderInfoManager instance;
+        return instance;
+    }
+
+    bool isSizeSupported(int32_t width, int32_t height,
+            bool* useHeic, bool* useGrid, int64_t* stall, AString* hevcName) const;
+
+    static const auto kGridWidth = 512;
+    static const auto kGridHeight = 512;
+private:
+    struct SizePairHash {
+        std::size_t operator () (const std::pair<int32_t,int32_t> &p) const {
+            return p.first * 31 + p.second;
+        }
+    };
+
+    typedef std::unordered_map<std::pair<int32_t, int32_t>,
+            std::pair<int32_t, int32_t>, SizePairHash> FrameRateMaps;
+
+    HeicEncoderInfoManager();
+    virtual ~HeicEncoderInfoManager();
+
+    status_t initialize();
+    status_t getFrameRateMaps(sp<AMessage> details, FrameRateMaps* maps);
+    status_t getCodecSizeRange(const char* codecName, sp<AMessage> details,
+            std::pair<int32_t, int32_t>* minSize, std::pair<int32_t, int32_t>* maxSize,
+            FrameRateMaps* frameRateMaps);
+    FrameRateMaps::const_iterator findClosestSize(const FrameRateMaps& maps,
+            int32_t width, int32_t height) const;
+    sp<AMessage> getCodecDetails(sp<IMediaCodecList> codecsList, const char* name);
+    bool getHevcCodecDetails(sp<IMediaCodecList> codecsList, const char* mime);
+
+    bool mIsInited;
+    std::pair<int32_t, int32_t> mMinSizeHeic, mMaxSizeHeic;
+    std::pair<int32_t, int32_t> mMinSizeHevc, mMaxSizeHevc;
+    bool mHasHEVC, mHasHEIC;
+    AString mHevcName;
+    FrameRateMaps mHeicFrameRateMaps, mHevcFrameRateMaps;
+    bool mDisableGrid;
+
+};
+
+} // namespace camera3
+} // namespace android
+
+#endif // ANDROID_SERVERS_CAMERA_HEICENCODER_INFO_MANAGER_H
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index ce006a7..78feb3e 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -32,14 +32,11 @@
 #include "api2/CameraDeviceClient.h"
 
 #include "device3/Camera3Device.h"
+#include "utils/CameraThreadState.h"
 
 namespace android {
 using namespace camera2;
 
-static int getCallingPid() {
-    return IPCThreadState::self()->getCallingPid();
-}
-
 // Interface used by CameraService
 
 template <typename TClientBase>
@@ -57,13 +54,13 @@
                 cameraId, api1CameraId, cameraFacing, clientPid, clientUid, servicePid),
         mSharedCameraCallbacks(remoteCallback),
         mDeviceVersion(cameraService->getDeviceVersion(TClientBase::mCameraIdStr)),
+        mDevice(new Camera3Device(cameraId)),
         mDeviceActive(false), mApi1CameraId(api1CameraId)
 {
     ALOGI("Camera %s: Opened. Client: %s (PID %d, UID %d)", cameraId.string(),
             String8(clientPackageName).string(), clientPid, clientUid);
 
     mInitialClientPid = clientPid;
-    mDevice = new Camera3Device(cameraId);
     LOG_ALWAYS_FATAL_IF(mDevice == 0, "Device should never be NULL here.");
 }
 
@@ -71,7 +68,7 @@
 status_t Camera2ClientBase<TClientBase>::checkPid(const char* checkLocation)
         const {
 
-    int callingPid = getCallingPid();
+    int callingPid = CameraThreadState::getCallingPid();
     if (callingPid == TClientBase::mClientPid) return NO_ERROR;
 
     ALOGE("%s: attempt to use a locked camera from a different process"
@@ -186,7 +183,7 @@
 
     binder::Status res = binder::Status::ok();
     // Allow both client and the media server to disconnect at all times
-    int callingPid = getCallingPid();
+    int callingPid = CameraThreadState::getCallingPid();
     if (callingPid != TClientBase::mClientPid &&
         callingPid != TClientBase::mServicePid) return res;
 
@@ -206,8 +203,6 @@
     if (mDevice == 0) return;
     mDevice->disconnect();
 
-    mDevice.clear();
-
     ALOGV("Camera %s: Detach complete", TClientBase::mCameraIdStr.string());
 }
 
@@ -219,18 +214,18 @@
     Mutex::Autolock icl(mBinderSerializationLock);
 
     if (TClientBase::mClientPid != 0 &&
-        getCallingPid() != TClientBase::mClientPid) {
+        CameraThreadState::getCallingPid() != TClientBase::mClientPid) {
 
         ALOGE("%s: Camera %s: Connection attempt from pid %d; "
                 "current locked to pid %d",
                 __FUNCTION__,
                 TClientBase::mCameraIdStr.string(),
-                getCallingPid(),
+                CameraThreadState::getCallingPid(),
                 TClientBase::mClientPid);
         return BAD_VALUE;
     }
 
-    TClientBase::mClientPid = getCallingPid();
+    TClientBase::mClientPid = CameraThreadState::getCallingPid();
 
     TClientBase::mRemoteCallback = client;
     mSharedCameraCallbacks = client;
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h
index e74fbdf..6693847 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.h
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.h
@@ -130,7 +130,10 @@
     /** CameraDeviceBase instance wrapping HAL3+ entry */
 
     const int mDeviceVersion;
-    sp<CameraDeviceBase>  mDevice;
+
+    // Set to const to avoid mDevice being updated (update of sp<> is racy) during
+    // dumpDevice (which is important to be lock free for debugging purpose)
+    const sp<CameraDeviceBase>  mDevice;
 
     /** Utility members */
 
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index 0ba7403..98c1b5e 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -69,6 +69,10 @@
      * The device's static characteristics metadata buffer
      */
     virtual const CameraMetadata& info() const = 0;
+    /**
+     * The physical camera device's static characteristics metadata buffer
+     */
+    virtual const CameraMetadata& info(const String8& physicalId) const = 0;
 
     struct PhysicalCameraSettings {
         std::string cameraId;
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 43f1a91..09638d0 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -20,27 +20,42 @@
 
 #include "CameraProviderManager.h"
 
+#include <android/hardware/camera/device/3.5/ICameraDevice.h>
+
 #include <algorithm>
 #include <chrono>
+#include "common/DepthPhotoProcessor.h"
+#include <dlfcn.h>
+#include <future>
 #include <inttypes.h>
+#include <hardware/camera_common.h>
 #include <hidl/ServiceManagement.h>
 #include <functional>
 #include <camera_metadata_hidden.h>
 #include <android-base/parseint.h>
+#include <android-base/logging.h>
+#include <cutils/properties.h>
+#include <hwbinder/IPCThreadState.h>
+#include <utils/Trace.h>
+
+#include "api2/HeicCompositeStream.h"
 
 namespace android {
 
 using namespace ::android::hardware::camera;
 using namespace ::android::hardware::camera::common::V1_0;
+using std::literals::chrono_literals::operator""s;
 
 namespace {
 // Hardcoded name for the passthrough HAL implementation, since it can't be discovered via the
 // service manager
 const std::string kLegacyProviderName("legacy/0");
 const std::string kExternalProviderName("external/0");
-
+const bool kEnableLazyHal(property_get_bool("ro.camera.enableLazyHal", false));
 } // anonymous namespace
 
+const float CameraProviderManager::kDepthARTolerance = .1f;
+
 CameraProviderManager::HardwareServiceInteractionProxy
 CameraProviderManager::sHardwareServiceInteractionProxy{};
 
@@ -56,6 +71,8 @@
     }
     mListener = listener;
     mServiceProxy = proxy;
+    mDeviceState = static_cast<hardware::hidl_bitfield<provider::V2_5::DeviceState>>(
+        provider::V2_5::DeviceState::NORMAL);
 
     // Registering will trigger notifications for all already-known providers
     bool success = mServiceProxy->registerForNotifications(
@@ -71,6 +88,8 @@
     addProviderLocked(kLegacyProviderName, /*expected*/ false);
     addProviderLocked(kExternalProviderName, /*expected*/ false);
 
+    IPCThreadState::self()->flushCommands();
+
     return OK;
 }
 
@@ -101,8 +120,8 @@
         std::vector<std::string> providerDeviceIds = provider->mUniqueAPI1CompatibleCameraIds;
 
         // API1 app doesn't handle logical and physical camera devices well. So
-        // for each [logical, physical1, physical2, ...] id combo, only take the
-        // first id advertised by HAL, and filter out the rest.
+        // for each camera facing, only take the first id advertised by HAL in
+        // all [logical, physical1, physical2, ...] id combos, and filter out the rest.
         filterLogicalCameraIdsLocked(providerDeviceIds);
 
         deviceIds.insert(deviceIds.end(), providerDeviceIds.begin(), providerDeviceIds.end());
@@ -174,6 +193,19 @@
     return deviceInfo->getCameraInfo(info);
 }
 
+status_t CameraProviderManager::isSessionConfigurationSupported(const std::string& id,
+        const hardware::camera::device::V3_4::StreamConfiguration &configuration,
+        bool *status /*out*/) const {
+    std::lock_guard<std::mutex> lock(mInterfaceMutex);
+
+    auto deviceInfo = findDeviceInfoLocked(id);
+    if (deviceInfo == nullptr) {
+        return NAME_NOT_FOUND;
+    }
+
+    return deviceInfo->isSessionConfigurationSupported(configuration, status);
+}
+
 status_t CameraProviderManager::getCameraCharacteristics(const std::string &id,
         CameraMetadata* characteristics) const {
     std::lock_guard<std::mutex> lock(mInterfaceMutex);
@@ -203,26 +235,15 @@
     return OK;
 }
 
-bool CameraProviderManager::supportSetTorchMode(const std::string &id) {
+bool CameraProviderManager::supportSetTorchMode(const std::string &id) const {
     std::lock_guard<std::mutex> lock(mInterfaceMutex);
-    bool support = false;
     for (auto& provider : mProviders) {
         auto deviceInfo = findDeviceInfoLocked(id);
         if (deviceInfo != nullptr) {
-            auto ret = provider->mInterface->isSetTorchModeSupported(
-                [&support](auto status, bool supported) {
-                    if (status == Status::OK) {
-                        support = supported;
-                    }
-                });
-            if (!ret.isOk()) {
-                ALOGE("%s: Transaction error checking torch mode support '%s': %s",
-                        __FUNCTION__, provider->mProviderName.c_str(), ret.description().c_str());
-            }
-            break;
+            return provider->mSetTorchModeSupported;
         }
     }
-    return support;
+    return false;
 }
 
 status_t CameraProviderManager::setTorchMode(const std::string &id, bool enabled) {
@@ -231,6 +252,15 @@
     auto deviceInfo = findDeviceInfoLocked(id);
     if (deviceInfo == nullptr) return NAME_NOT_FOUND;
 
+    // Pass the camera ID to start interface so that it will save it to the map of ICameraProviders
+    // that are currently in use.
+    const sp<provider::V2_4::ICameraProvider> interface =
+            deviceInfo->mParentProvider->startProviderInterface();
+    if (interface == nullptr) {
+        return DEAD_OBJECT;
+    }
+    saveRef(DeviceMode::TORCH, deviceInfo->mId, interface);
+
     return deviceInfo->setTorchMode(enabled);
 }
 
@@ -238,37 +268,7 @@
     sp<VendorTagDescriptorCache> tagCache = new VendorTagDescriptorCache();
 
     for (auto& provider : mProviders) {
-        hardware::hidl_vec<VendorTagSection> vts;
-        Status status;
-        hardware::Return<void> ret;
-        ret = provider->mInterface->getVendorTags(
-            [&](auto s, const auto& vendorTagSecs) {
-                status = s;
-                if (s == Status::OK) {
-                    vts = vendorTagSecs;
-                }
-        });
-        if (!ret.isOk()) {
-            ALOGE("%s: Transaction error getting vendor tags from provider '%s': %s",
-                    __FUNCTION__, provider->mProviderName.c_str(), ret.description().c_str());
-            return DEAD_OBJECT;
-        }
-        if (status != Status::OK) {
-            return mapToStatusT(status);
-        }
-
-        // Read all vendor tag definitions into a descriptor
-        sp<VendorTagDescriptor> desc;
-        status_t res;
-        if ((res = HidlVendorTagDescriptor::createDescriptorFromHidl(vts, /*out*/desc))
-                != OK) {
-            ALOGE("%s: Could not generate descriptor from vendor tag operations,"
-                  "received error %s (%d). Camera clients will not be able to use"
-                  "vendor tags", __FUNCTION__, strerror(res), res);
-            return res;
-        }
-
-        tagCache->addVendorDescriptor(provider->mProviderTagid, desc);
+        tagCache->addVendorDescriptor(provider->mProviderTagid, provider->mVendorTagDescriptor);
     }
 
     VendorTagDescriptorCache::setAsGlobalVendorTagCache(tagCache);
@@ -276,10 +276,30 @@
     return OK;
 }
 
+status_t CameraProviderManager::notifyDeviceStateChange(
+        hardware::hidl_bitfield<provider::V2_5::DeviceState> newState) {
+    std::lock_guard<std::mutex> lock(mInterfaceMutex);
+    mDeviceState = newState;
+    status_t res = OK;
+    for (auto& provider : mProviders) {
+        ALOGV("%s: Notifying %s for new state 0x%" PRIx64,
+                __FUNCTION__, provider->mProviderName.c_str(), newState);
+        status_t singleRes = provider->notifyDeviceStateChange(mDeviceState);
+        if (singleRes != OK) {
+            ALOGE("%s: Unable to notify provider %s about device state change",
+                    __FUNCTION__,
+                    provider->mProviderName.c_str());
+            res = singleRes;
+            // continue to do the rest of the providers instead of returning now
+        }
+    }
+    return res;
+}
+
 status_t CameraProviderManager::openSession(const std::string &id,
-        const sp<hardware::camera::device::V3_2::ICameraDeviceCallback>& callback,
+        const sp<device::V3_2::ICameraDeviceCallback>& callback,
         /*out*/
-        sp<hardware::camera::device::V3_2::ICameraDeviceSession> *session) {
+        sp<device::V3_2::ICameraDeviceSession> *session) {
 
     std::lock_guard<std::mutex> lock(mInterfaceMutex);
 
@@ -288,10 +308,22 @@
     if (deviceInfo == nullptr) return NAME_NOT_FOUND;
 
     auto *deviceInfo3 = static_cast<ProviderInfo::DeviceInfo3*>(deviceInfo);
+    const sp<provider::V2_4::ICameraProvider> provider =
+            deviceInfo->mParentProvider->startProviderInterface();
+    if (provider == nullptr) {
+        return DEAD_OBJECT;
+    }
+    saveRef(DeviceMode::CAMERA, id, provider);
 
     Status status;
     hardware::Return<void> ret;
-    ret = deviceInfo3->mInterface->open(callback, [&status, &session]
+    auto interface = deviceInfo3->startDeviceInterface<
+            CameraProviderManager::ProviderInfo::DeviceInfo3::InterfaceT>();
+    if (interface == nullptr) {
+        return DEAD_OBJECT;
+    }
+
+    ret = interface->open(callback, [&status, &session]
             (Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {
                 status = s;
                 if (status == Status::OK) {
@@ -299,6 +331,7 @@
                 }
             });
     if (!ret.isOk()) {
+        removeRef(DeviceMode::CAMERA, id);
         ALOGE("%s: Transaction error opening a session for camera device %s: %s",
                 __FUNCTION__, id.c_str(), ret.description().c_str());
         return DEAD_OBJECT;
@@ -307,9 +340,9 @@
 }
 
 status_t CameraProviderManager::openSession(const std::string &id,
-        const sp<hardware::camera::device::V1_0::ICameraDeviceCallback>& callback,
+        const sp<device::V1_0::ICameraDeviceCallback>& callback,
         /*out*/
-        sp<hardware::camera::device::V1_0::ICameraDevice> *session) {
+        sp<device::V1_0::ICameraDevice> *session) {
 
     std::lock_guard<std::mutex> lock(mInterfaceMutex);
 
@@ -318,24 +351,91 @@
     if (deviceInfo == nullptr) return NAME_NOT_FOUND;
 
     auto *deviceInfo1 = static_cast<ProviderInfo::DeviceInfo1*>(deviceInfo);
+    const sp<provider::V2_4::ICameraProvider> provider =
+            deviceInfo->mParentProvider->startProviderInterface();
+    if (provider == nullptr) {
+        return DEAD_OBJECT;
+    }
+    saveRef(DeviceMode::CAMERA, id, provider);
 
-    hardware::Return<Status> status = deviceInfo1->mInterface->open(callback);
+    auto interface = deviceInfo1->startDeviceInterface<
+            CameraProviderManager::ProviderInfo::DeviceInfo1::InterfaceT>();
+    if (interface == nullptr) {
+        return DEAD_OBJECT;
+    }
+    hardware::Return<Status> status = interface->open(callback);
     if (!status.isOk()) {
+        removeRef(DeviceMode::CAMERA, id);
         ALOGE("%s: Transaction error opening a session for camera device %s: %s",
                 __FUNCTION__, id.c_str(), status.description().c_str());
         return DEAD_OBJECT;
     }
     if (status == Status::OK) {
-        *session = deviceInfo1->mInterface;
+        *session = interface;
     }
     return mapToStatusT(status);
 }
 
+void CameraProviderManager::saveRef(DeviceMode usageType, const std::string &cameraId,
+        sp<provider::V2_4::ICameraProvider> provider) {
+    if (!kEnableLazyHal) {
+        return;
+    }
+    ALOGV("Saving camera provider %s for camera device %s", provider->descriptor, cameraId.c_str());
+    std::lock_guard<std::mutex> lock(mProviderInterfaceMapLock);
+    std::unordered_map<std::string, sp<provider::V2_4::ICameraProvider>> *primaryMap, *alternateMap;
+    if (usageType == DeviceMode::TORCH) {
+        primaryMap = &mTorchProviderByCameraId;
+        alternateMap = &mCameraProviderByCameraId;
+    } else {
+        primaryMap = &mCameraProviderByCameraId;
+        alternateMap = &mTorchProviderByCameraId;
+    }
+    auto id = cameraId.c_str();
+    (*primaryMap)[id] = provider;
+    auto search = alternateMap->find(id);
+    if (search != alternateMap->end()) {
+        ALOGW("%s: Camera device %s is using both torch mode and camera mode simultaneously. "
+                "That should not be possible", __FUNCTION__, id);
+    }
+    ALOGV("%s: Camera device %s connected", __FUNCTION__, id);
+}
+
+void CameraProviderManager::removeRef(DeviceMode usageType, const std::string &cameraId) {
+    if (!kEnableLazyHal) {
+        return;
+    }
+    ALOGV("Removing camera device %s", cameraId.c_str());
+    std::unordered_map<std::string, sp<provider::V2_4::ICameraProvider>> *providerMap;
+    if (usageType == DeviceMode::TORCH) {
+        providerMap = &mTorchProviderByCameraId;
+    } else {
+        providerMap = &mCameraProviderByCameraId;
+    }
+    std::lock_guard<std::mutex> lock(mProviderInterfaceMapLock);
+    auto search = providerMap->find(cameraId.c_str());
+    if (search != providerMap->end()) {
+        // Drop the reference to this ICameraProvider. This is safe to do immediately (without an
+        // added delay) because hwservicemanager guarantees to hold the reference for at least five
+        // more seconds.  We depend on this behavior so that if the provider is unreferenced and
+        // then referenced again quickly, we do not let the HAL exit and then need to immediately
+        // restart it. An example when this could happen is switching from a front-facing to a
+        // rear-facing camera. If the HAL were to exit during the camera switch, the camera could
+        // appear janky to the user.
+        providerMap->erase(cameraId.c_str());
+        IPCThreadState::self()->flushCommands();
+    } else {
+        ALOGE("%s: Asked to remove reference for camera %s, but no reference to it was found. This "
+                "could mean removeRef was called twice for the same camera ID.", __FUNCTION__,
+                cameraId.c_str());
+    }
+}
 
 hardware::Return<void> CameraProviderManager::onRegistration(
         const hardware::hidl_string& /*fqName*/,
         const hardware::hidl_string& name,
         bool /*preexisting*/) {
+    std::lock_guard<std::mutex> providerLock(mProviderLifecycleLock);
     {
         std::lock_guard<std::mutex> lock(mInterfaceMutex);
 
@@ -347,6 +447,8 @@
         listener->onNewProviderRegistered();
     }
 
+    IPCThreadState::self()->flushCommands();
+
     return hardware::Return<void>();
 }
 
@@ -392,35 +494,597 @@
     return ret;
 }
 
-bool CameraProviderManager::isLogicalCamera(const CameraMetadata& staticInfo,
-        std::vector<std::string>* physicalCameraIds) {
-    bool isLogicalCam = false;
-    camera_metadata_ro_entry_t entryCap;
+void CameraProviderManager::ProviderInfo::DeviceInfo3::queryPhysicalCameraIds() {
+    camera_metadata_entry_t entryCap;
 
-    entryCap = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
+    entryCap = mCameraCharacteristics.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
     for (size_t i = 0; i < entryCap.count; ++i) {
         uint8_t capability = entryCap.data.u8[i];
         if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
-            isLogicalCam = true;
+            mIsLogicalCamera = true;
             break;
         }
     }
-    if (!isLogicalCam) {
-        return false;
+    if (!mIsLogicalCamera) {
+        return;
     }
 
-    camera_metadata_ro_entry_t entryIds = staticInfo.find(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);
+    camera_metadata_entry_t entryIds = mCameraCharacteristics.find(
+            ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);
     const uint8_t* ids = entryIds.data.u8;
     size_t start = 0;
     for (size_t i = 0; i < entryIds.count; ++i) {
         if (ids[i] == '\0') {
             if (start != i) {
-                physicalCameraIds->push_back((const char*)ids+start);
+                mPhysicalIds.push_back((const char*)ids+start);
             }
             start = i+1;
         }
     }
-    return true;
+}
+
+bool CameraProviderManager::ProviderInfo::DeviceInfo3::isPublicallyHiddenSecureCamera() {
+    camera_metadata_entry_t entryCap;
+    entryCap = mCameraCharacteristics.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
+    if (entryCap.count != 1) {
+        // Do NOT hide this camera device if the capabilities specify anything more
+        // than ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA.
+        return false;
+    }
+    return entryCap.data.u8[0] == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA;
+}
+
+void CameraProviderManager::ProviderInfo::DeviceInfo3::getSupportedSizes(
+        const CameraMetadata& ch, uint32_t tag, android_pixel_format_t format,
+        std::vector<std::tuple<size_t, size_t>> *sizes/*out*/) {
+    if (sizes == nullptr) {
+        return;
+    }
+
+    auto scalerDims = ch.find(tag);
+    if (scalerDims.count > 0) {
+        // Scaler entry contains 4 elements (format, width, height, type)
+        for (size_t i = 0; i < scalerDims.count; i += 4) {
+            if ((scalerDims.data.i32[i] == format) &&
+                    (scalerDims.data.i32[i+3] ==
+                     ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT)) {
+                sizes->push_back(std::make_tuple(scalerDims.data.i32[i+1],
+                            scalerDims.data.i32[i+2]));
+            }
+        }
+    }
+}
+
+void CameraProviderManager::ProviderInfo::DeviceInfo3::getSupportedDurations(
+        const CameraMetadata& ch, uint32_t tag, android_pixel_format_t format,
+        const std::vector<std::tuple<size_t, size_t>>& sizes,
+        std::vector<int64_t> *durations/*out*/) {
+    if (durations == nullptr) {
+        return;
+    }
+
+    auto availableDurations = ch.find(tag);
+    if (availableDurations.count > 0) {
+        // Duration entry contains 4 elements (format, width, height, duration)
+        for (size_t i = 0; i < availableDurations.count; i += 4) {
+            for (const auto& size : sizes) {
+                int64_t width = std::get<0>(size);
+                int64_t height = std::get<1>(size);
+                if ((availableDurations.data.i64[i] == format) &&
+                        (availableDurations.data.i64[i+1] == width) &&
+                        (availableDurations.data.i64[i+2] == height)) {
+                    durations->push_back(availableDurations.data.i64[i+3]);
+                }
+            }
+        }
+    }
+}
+void CameraProviderManager::ProviderInfo::DeviceInfo3::getSupportedDynamicDepthDurations(
+        const std::vector<int64_t>& depthDurations, const std::vector<int64_t>& blobDurations,
+        std::vector<int64_t> *dynamicDepthDurations /*out*/) {
+    if ((dynamicDepthDurations == nullptr) || (depthDurations.size() != blobDurations.size())) {
+        return;
+    }
+
+    // Unfortunately there is no direct way to calculate the dynamic depth stream duration.
+    // Processing time on camera service side can vary greatly depending on multiple
+    // variables which are not under our control. Make a guesstimate by taking the maximum
+    // corresponding duration value from depth and blob.
+    auto depthDuration = depthDurations.begin();
+    auto blobDuration = blobDurations.begin();
+    dynamicDepthDurations->reserve(depthDurations.size());
+    while ((depthDuration != depthDurations.end()) && (blobDuration != blobDurations.end())) {
+        dynamicDepthDurations->push_back(std::max(*depthDuration, *blobDuration));
+        depthDuration++; blobDuration++;
+    }
+}
+
+void CameraProviderManager::ProviderInfo::DeviceInfo3::getSupportedDynamicDepthSizes(
+        const std::vector<std::tuple<size_t, size_t>>& blobSizes,
+        const std::vector<std::tuple<size_t, size_t>>& depthSizes,
+        std::vector<std::tuple<size_t, size_t>> *dynamicDepthSizes /*out*/,
+        std::vector<std::tuple<size_t, size_t>> *internalDepthSizes /*out*/) {
+    if (dynamicDepthSizes == nullptr || internalDepthSizes == nullptr) {
+        return;
+    }
+
+    // The dynamic depth spec. does not mention how close the AR ratio should be.
+    // Try using something appropriate.
+    float ARTolerance = kDepthARTolerance;
+
+    for (const auto& blobSize : blobSizes) {
+        float jpegAR = static_cast<float> (std::get<0>(blobSize)) /
+                static_cast<float>(std::get<1>(blobSize));
+        bool found = false;
+        for (const auto& depthSize : depthSizes) {
+            if (depthSize == blobSize) {
+                internalDepthSizes->push_back(depthSize);
+                found = true;
+                break;
+            } else {
+                float depthAR = static_cast<float> (std::get<0>(depthSize)) /
+                    static_cast<float>(std::get<1>(depthSize));
+                if (std::fabs(jpegAR - depthAR) <= ARTolerance) {
+                    internalDepthSizes->push_back(depthSize);
+                    found = true;
+                    break;
+                }
+            }
+        }
+
+        if (found) {
+            dynamicDepthSizes->push_back(blobSize);
+        }
+    }
+}
+
+bool CameraProviderManager::ProviderInfo::DeviceInfo3::isDepthPhotoLibraryPresent() {
+    static bool libraryPresent = false;
+    static bool initialized = false;
+    if (initialized) {
+        return libraryPresent;
+    } else {
+        initialized = true;
+    }
+
+    void* depthLibHandle = dlopen(camera3::kDepthPhotoLibrary, RTLD_NOW | RTLD_LOCAL);
+    if (depthLibHandle == nullptr) {
+        return false;
+    }
+
+    auto processFunc = dlsym(depthLibHandle, camera3::kDepthPhotoProcessFunction);
+    if (processFunc != nullptr) {
+        libraryPresent = true;
+    } else {
+        libraryPresent = false;
+    }
+    dlclose(depthLibHandle);
+
+    return libraryPresent;
+}
+
+status_t CameraProviderManager::ProviderInfo::DeviceInfo3::addDynamicDepthTags() {
+    uint32_t depthExclTag = ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE;
+    uint32_t depthSizesTag = ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS;
+    auto& c = mCameraCharacteristics;
+    std::vector<std::tuple<size_t, size_t>> supportedBlobSizes, supportedDepthSizes,
+            supportedDynamicDepthSizes, internalDepthSizes;
+    auto chTags = c.find(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
+    if (chTags.count == 0) {
+        ALOGE("%s: Supported camera characteristics is empty!", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    bool isDepthExclusivePresent = std::find(chTags.data.i32, chTags.data.i32 + chTags.count,
+            depthExclTag) != (chTags.data.i32 + chTags.count);
+    bool isDepthSizePresent = std::find(chTags.data.i32, chTags.data.i32 + chTags.count,
+            depthSizesTag) != (chTags.data.i32 + chTags.count);
+    if (!(isDepthExclusivePresent && isDepthSizePresent)) {
+        // No depth support, nothing more to do.
+        return OK;
+    }
+
+    auto depthExclusiveEntry = c.find(depthExclTag);
+    if (depthExclusiveEntry.count > 0) {
+        if (depthExclusiveEntry.data.u8[0] != ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE_FALSE) {
+            // Depth support is exclusive, nothing more to do.
+            return OK;
+        }
+    } else {
+        ALOGE("%s: Advertised depth exclusive tag but value is not present!", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    getSupportedSizes(c, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, HAL_PIXEL_FORMAT_BLOB,
+            &supportedBlobSizes);
+    getSupportedSizes(c, depthSizesTag, HAL_PIXEL_FORMAT_Y16, &supportedDepthSizes);
+    if (supportedBlobSizes.empty() || supportedDepthSizes.empty()) {
+        // Nothing to do in this case.
+        return OK;
+    }
+
+    getSupportedDynamicDepthSizes(supportedBlobSizes, supportedDepthSizes,
+            &supportedDynamicDepthSizes, &internalDepthSizes);
+    if (supportedDynamicDepthSizes.empty()) {
+        // Nothing more to do.
+        return OK;
+    }
+
+    if(!isDepthPhotoLibraryPresent()) {
+        // Depth photo processing library is not present, nothing more to do.
+        return OK;
+    }
+
+    std::vector<int32_t> dynamicDepthEntries;
+    for (const auto& it : supportedDynamicDepthSizes) {
+        int32_t entry[4] = {HAL_PIXEL_FORMAT_BLOB, static_cast<int32_t> (std::get<0>(it)),
+                static_cast<int32_t> (std::get<1>(it)),
+                ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT };
+        dynamicDepthEntries.insert(dynamicDepthEntries.end(), entry, entry + 4);
+    }
+
+    std::vector<int64_t> depthMinDurations, depthStallDurations;
+    std::vector<int64_t> blobMinDurations, blobStallDurations;
+    std::vector<int64_t> dynamicDepthMinDurations, dynamicDepthStallDurations;
+
+    getSupportedDurations(c, ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS,
+            HAL_PIXEL_FORMAT_Y16, internalDepthSizes, &depthMinDurations);
+    getSupportedDurations(c, ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
+            HAL_PIXEL_FORMAT_BLOB, supportedDynamicDepthSizes, &blobMinDurations);
+    if (blobMinDurations.empty() || depthMinDurations.empty() ||
+            (depthMinDurations.size() != blobMinDurations.size())) {
+        ALOGE("%s: Unexpected number of available depth min durations! %zu vs. %zu",
+                __FUNCTION__, depthMinDurations.size(), blobMinDurations.size());
+        return BAD_VALUE;
+    }
+
+    getSupportedDurations(c, ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS,
+            HAL_PIXEL_FORMAT_Y16, internalDepthSizes, &depthStallDurations);
+    getSupportedDurations(c, ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
+            HAL_PIXEL_FORMAT_BLOB, supportedDynamicDepthSizes, &blobStallDurations);
+    if (blobStallDurations.empty() || depthStallDurations.empty() ||
+            (depthStallDurations.size() != blobStallDurations.size())) {
+        ALOGE("%s: Unexpected number of available depth stall durations! %zu vs. %zu",
+                __FUNCTION__, depthStallDurations.size(), blobStallDurations.size());
+        return BAD_VALUE;
+    }
+
+    getSupportedDynamicDepthDurations(depthMinDurations, blobMinDurations,
+            &dynamicDepthMinDurations);
+    getSupportedDynamicDepthDurations(depthStallDurations, blobStallDurations,
+            &dynamicDepthStallDurations);
+    if (dynamicDepthMinDurations.empty() || dynamicDepthStallDurations.empty() ||
+            (dynamicDepthMinDurations.size() != dynamicDepthStallDurations.size())) {
+        ALOGE("%s: Unexpected number of dynamic depth stall/min durations! %zu vs. %zu",
+                __FUNCTION__, dynamicDepthMinDurations.size(), dynamicDepthStallDurations.size());
+        return BAD_VALUE;
+    }
+
+    std::vector<int64_t> dynamicDepthMinDurationEntries;
+    auto itDuration = dynamicDepthMinDurations.begin();
+    auto itSize = supportedDynamicDepthSizes.begin();
+    while (itDuration != dynamicDepthMinDurations.end()) {
+        int64_t entry[4] = {HAL_PIXEL_FORMAT_BLOB, static_cast<int32_t> (std::get<0>(*itSize)),
+                static_cast<int32_t> (std::get<1>(*itSize)), *itDuration};
+        dynamicDepthMinDurationEntries.insert(dynamicDepthMinDurationEntries.end(), entry,
+                entry + 4);
+        itDuration++; itSize++;
+    }
+
+    std::vector<int64_t> dynamicDepthStallDurationEntries;
+    itDuration = dynamicDepthStallDurations.begin();
+    itSize = supportedDynamicDepthSizes.begin();
+    while (itDuration != dynamicDepthStallDurations.end()) {
+        int64_t entry[4] = {HAL_PIXEL_FORMAT_BLOB, static_cast<int32_t> (std::get<0>(*itSize)),
+                static_cast<int32_t> (std::get<1>(*itSize)), *itDuration};
+        dynamicDepthStallDurationEntries.insert(dynamicDepthStallDurationEntries.end(), entry,
+                entry + 4);
+        itDuration++; itSize++;
+    }
+
+    c.update(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS,
+            dynamicDepthEntries.data(), dynamicDepthEntries.size());
+    c.update(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS,
+            dynamicDepthMinDurationEntries.data(), dynamicDepthMinDurationEntries.size());
+    c.update(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS,
+            dynamicDepthStallDurationEntries.data(), dynamicDepthStallDurationEntries.size());
+
+    std::vector<int32_t> supportedChTags;
+    supportedChTags.reserve(chTags.count + 3);
+    supportedChTags.insert(supportedChTags.end(), chTags.data.i32,
+            chTags.data.i32 + chTags.count);
+    supportedChTags.push_back(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS);
+    supportedChTags.push_back(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS);
+    supportedChTags.push_back(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS);
+    c.update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, supportedChTags.data(),
+            supportedChTags.size());
+
+    return OK;
+}
+
+status_t CameraProviderManager::ProviderInfo::DeviceInfo3::fixupMonochromeTags() {
+    status_t res = OK;
+    auto& c = mCameraCharacteristics;
+
+    // Override static metadata for MONOCHROME camera with older device version
+    if (mVersion.get_major() == 3 && mVersion.get_minor() < 5) {
+        camera_metadata_entry cap = c.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
+        for (size_t i = 0; i < cap.count; i++) {
+            if (cap.data.u8[i] == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME) {
+                // ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
+                uint8_t cfa = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO;
+                res = c.update(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT, &cfa, 1);
+                if (res != OK) {
+                    ALOGE("%s: Failed to update COLOR_FILTER_ARRANGEMENT: %s (%d)",
+                          __FUNCTION__, strerror(-res), res);
+                    return res;
+                }
+
+                // ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS
+                const std::vector<uint32_t> sKeys = {
+                        ANDROID_SENSOR_REFERENCE_ILLUMINANT1,
+                        ANDROID_SENSOR_REFERENCE_ILLUMINANT2,
+                        ANDROID_SENSOR_CALIBRATION_TRANSFORM1,
+                        ANDROID_SENSOR_CALIBRATION_TRANSFORM2,
+                        ANDROID_SENSOR_COLOR_TRANSFORM1,
+                        ANDROID_SENSOR_COLOR_TRANSFORM2,
+                        ANDROID_SENSOR_FORWARD_MATRIX1,
+                        ANDROID_SENSOR_FORWARD_MATRIX2,
+                };
+                res = removeAvailableKeys(c, sKeys,
+                        ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
+                if (res != OK) {
+                    ALOGE("%s: Failed to update REQUEST_AVAILABLE_CHARACTERISTICS_KEYS: %s (%d)",
+                            __FUNCTION__, strerror(-res), res);
+                    return res;
+                }
+
+                // ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS
+                const std::vector<uint32_t> reqKeys = {
+                        ANDROID_COLOR_CORRECTION_MODE,
+                        ANDROID_COLOR_CORRECTION_TRANSFORM,
+                        ANDROID_COLOR_CORRECTION_GAINS,
+                };
+                res = removeAvailableKeys(c, reqKeys, ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS);
+                if (res != OK) {
+                    ALOGE("%s: Failed to update REQUEST_AVAILABLE_REQUEST_KEYS: %s (%d)",
+                            __FUNCTION__, strerror(-res), res);
+                    return res;
+                }
+
+                // ANDROID_REQUEST_AVAILABLE_RESULT_KEYS
+                const std::vector<uint32_t> resKeys = {
+                        ANDROID_SENSOR_GREEN_SPLIT,
+                        ANDROID_SENSOR_NEUTRAL_COLOR_POINT,
+                        ANDROID_COLOR_CORRECTION_MODE,
+                        ANDROID_COLOR_CORRECTION_TRANSFORM,
+                        ANDROID_COLOR_CORRECTION_GAINS,
+                };
+                res = removeAvailableKeys(c, resKeys, ANDROID_REQUEST_AVAILABLE_RESULT_KEYS);
+                if (res != OK) {
+                    ALOGE("%s: Failed to update REQUEST_AVAILABLE_RESULT_KEYS: %s (%d)",
+                            __FUNCTION__, strerror(-res), res);
+                    return res;
+                }
+
+                // ANDROID_SENSOR_BLACK_LEVEL_PATTERN
+                camera_metadata_entry blEntry = c.find(ANDROID_SENSOR_BLACK_LEVEL_PATTERN);
+                for (size_t j = 1; j < blEntry.count; j++) {
+                    blEntry.data.i32[j] = blEntry.data.i32[0];
+                }
+            }
+        }
+    }
+    return res;
+}
+
+status_t CameraProviderManager::ProviderInfo::DeviceInfo3::removeAvailableKeys(
+        CameraMetadata& c, const std::vector<uint32_t>& keys, uint32_t keyTag) {
+    status_t res = OK;
+
+    camera_metadata_entry keysEntry = c.find(keyTag);
+    if (keysEntry.count == 0) {
+        ALOGE("%s: Failed to find tag %u: %s (%d)", __FUNCTION__, keyTag, strerror(-res), res);
+        return res;
+    }
+    std::vector<int32_t> vKeys;
+    vKeys.reserve(keysEntry.count);
+    for (size_t i = 0; i < keysEntry.count; i++) {
+        if (std::find(keys.begin(), keys.end(), keysEntry.data.i32[i]) == keys.end()) {
+            vKeys.push_back(keysEntry.data.i32[i]);
+        }
+    }
+    res = c.update(keyTag, vKeys.data(), vKeys.size());
+    return res;
+}
+
+status_t CameraProviderManager::ProviderInfo::DeviceInfo3::fillHeicStreamCombinations(
+        std::vector<int32_t>* outputs,
+        std::vector<int64_t>* durations,
+        std::vector<int64_t>* stallDurations,
+        const camera_metadata_entry& halStreamConfigs,
+        const camera_metadata_entry& halStreamDurations) {
+    if (outputs == nullptr || durations == nullptr || stallDurations == nullptr) {
+        return BAD_VALUE;
+    }
+
+    static bool supportInMemoryTempFile =
+            camera3::HeicCompositeStream::isInMemoryTempFileSupported();
+    if (!supportInMemoryTempFile) {
+        ALOGI("%s: No HEIC support due to absence of in memory temp file support",
+                __FUNCTION__);
+        return OK;
+    }
+
+    for (size_t i = 0; i < halStreamConfigs.count; i += 4) {
+        int32_t format = halStreamConfigs.data.i32[i];
+        // Only IMPLEMENTATION_DEFINED and YUV_888 can be used to generate HEIC
+        // image.
+        if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
+                format != HAL_PIXEL_FORMAT_YCBCR_420_888) {
+            continue;
+        }
+
+        bool sizeAvail = false;
+        for (size_t j = 0; j < outputs->size(); j+= 4) {
+            if ((*outputs)[j+1] == halStreamConfigs.data.i32[i+1] &&
+                    (*outputs)[j+2] == halStreamConfigs.data.i32[i+2]) {
+                sizeAvail = true;
+                break;
+            }
+        }
+        if (sizeAvail) continue;
+
+        int64_t stall = 0;
+        bool useHeic, useGrid;
+        if (camera3::HeicCompositeStream::isSizeSupportedByHeifEncoder(
+                halStreamConfigs.data.i32[i+1], halStreamConfigs.data.i32[i+2],
+                &useHeic, &useGrid, &stall)) {
+            if (useGrid != (format == HAL_PIXEL_FORMAT_YCBCR_420_888)) {
+                continue;
+            }
+
+            // HEIC configuration
+            int32_t config[] = {HAL_PIXEL_FORMAT_BLOB, halStreamConfigs.data.i32[i+1],
+                    halStreamConfigs.data.i32[i+2], 0 /*isInput*/};
+            outputs->insert(outputs->end(), config, config + 4);
+
+            // HEIC minFrameDuration
+            for (size_t j = 0; j < halStreamDurations.count; j += 4) {
+                if (halStreamDurations.data.i64[j] == format &&
+                        halStreamDurations.data.i64[j+1] == halStreamConfigs.data.i32[i+1] &&
+                        halStreamDurations.data.i64[j+2] == halStreamConfigs.data.i32[i+2]) {
+                    int64_t duration[] = {HAL_PIXEL_FORMAT_BLOB, halStreamConfigs.data.i32[i+1],
+                            halStreamConfigs.data.i32[i+2], halStreamDurations.data.i64[j+3]};
+                    durations->insert(durations->end(), duration, duration+4);
+                    break;
+                }
+            }
+
+            // HEIC stallDuration
+            int64_t stallDuration[] = {HAL_PIXEL_FORMAT_BLOB, halStreamConfigs.data.i32[i+1],
+                    halStreamConfigs.data.i32[i+2], stall};
+            stallDurations->insert(stallDurations->end(), stallDuration, stallDuration+4);
+        }
+    }
+    return OK;
+}
+
+status_t CameraProviderManager::ProviderInfo::DeviceInfo3::deriveHeicTags() {
+    auto& c = mCameraCharacteristics;
+
+    camera_metadata_entry halHeicSupport = c.find(ANDROID_HEIC_INFO_SUPPORTED);
+    if (halHeicSupport.count > 1) {
+        ALOGE("%s: Invalid entry count %zu for ANDROID_HEIC_INFO_SUPPORTED",
+                __FUNCTION__, halHeicSupport.count);
+        return BAD_VALUE;
+    } else if (halHeicSupport.count == 0 ||
+            halHeicSupport.data.u8[0] == ANDROID_HEIC_INFO_SUPPORTED_FALSE) {
+        // Camera HAL doesn't support mandatory stream combinations for HEIC.
+        return OK;
+    }
+
+    camera_metadata_entry maxJpegAppsSegments =
+            c.find(ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT);
+    if (maxJpegAppsSegments.count != 1 || maxJpegAppsSegments.data.u8[0] == 0 ||
+            maxJpegAppsSegments.data.u8[0] > 16) {
+        ALOGE("%s: ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT must be within [1, 16]",
+                __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    // Populate HEIC output configurations and its related min frame duration
+    // and stall duration.
+    std::vector<int32_t> heicOutputs;
+    std::vector<int64_t> heicDurations;
+    std::vector<int64_t> heicStallDurations;
+
+    camera_metadata_entry halStreamConfigs =
+            c.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
+    camera_metadata_entry minFrameDurations =
+            c.find(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS);
+
+    status_t res = fillHeicStreamCombinations(&heicOutputs, &heicDurations, &heicStallDurations,
+            halStreamConfigs, minFrameDurations);
+    if (res != OK) {
+        ALOGE("%s: Failed to fill HEIC stream combinations: %s (%d)", __FUNCTION__,
+                strerror(-res), res);
+        return res;
+    }
+
+    c.update(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS,
+           heicOutputs.data(), heicOutputs.size());
+    c.update(ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS,
+            heicDurations.data(), heicDurations.size());
+    c.update(ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS,
+            heicStallDurations.data(), heicStallDurations.size());
+
+    return OK;
+}
+
+bool CameraProviderManager::isLogicalCamera(const std::string& id,
+        std::vector<std::string>* physicalCameraIds) {
+    std::lock_guard<std::mutex> lock(mInterfaceMutex);
+
+    auto deviceInfo = findDeviceInfoLocked(id);
+    if (deviceInfo == nullptr) return false;
+
+    if (deviceInfo->mIsLogicalCamera && physicalCameraIds != nullptr) {
+        *physicalCameraIds = deviceInfo->mPhysicalIds;
+    }
+    return deviceInfo->mIsLogicalCamera;
+}
+
+bool CameraProviderManager::isPublicallyHiddenSecureCamera(const std::string& id) {
+    std::lock_guard<std::mutex> lock(mInterfaceMutex);
+
+    auto deviceInfo = findDeviceInfoLocked(id);
+    if (deviceInfo == nullptr) {
+        return false;
+    }
+    return deviceInfo->mIsPublicallyHiddenSecureCamera;
+}
+
+bool CameraProviderManager::isHiddenPhysicalCamera(const std::string& cameraId) {
+    for (auto& provider : mProviders) {
+        for (auto& deviceInfo : provider->mDevices) {
+            if (deviceInfo->mId == cameraId) {
+                // cameraId is found in public camera IDs advertised by the
+                // provider.
+                return false;
+            }
+        }
+    }
+
+    for (auto& provider : mProviders) {
+        for (auto& deviceInfo : provider->mDevices) {
+            CameraMetadata info;
+            status_t res = deviceInfo->getCameraCharacteristics(&info);
+            if (res != OK) {
+                ALOGE("%s: Failed to getCameraCharacteristics for id %s", __FUNCTION__,
+                        deviceInfo->mId.c_str());
+                return false;
+            }
+
+            std::vector<std::string> physicalIds;
+            if (deviceInfo->mIsLogicalCamera) {
+                if (std::find(deviceInfo->mPhysicalIds.begin(), deviceInfo->mPhysicalIds.end(),
+                        cameraId) != deviceInfo->mPhysicalIds.end()) {
+                    int deviceVersion = HARDWARE_DEVICE_API_VERSION(
+                            deviceInfo->mVersion.get_major(), deviceInfo->mVersion.get_minor());
+                    if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_5) {
+                        ALOGE("%s: Wrong deviceVersion %x for hiddenPhysicalCameraId %s",
+                                __FUNCTION__, deviceVersion, cameraId.c_str());
+                        return false;
+                    } else {
+                        return true;
+                    }
+                }
+            }
+        }
+    }
+
+    return false;
 }
 
 status_t CameraProviderManager::addProviderLocked(const std::string& newProvider, bool expected) {
@@ -445,9 +1109,8 @@
         }
     }
 
-    sp<ProviderInfo> providerInfo =
-            new ProviderInfo(newProvider, interface, this);
-    status_t res = providerInfo->initialize();
+    sp<ProviderInfo> providerInfo = new ProviderInfo(newProvider, this);
+    status_t res = providerInfo->initialize(interface, mDeviceState);
     if (res != OK) {
         return res;
     }
@@ -458,6 +1121,7 @@
 }
 
 status_t CameraProviderManager::removeProvider(const std::string& provider) {
+    std::lock_guard<std::mutex> providerLock(mProviderLifecycleLock);
     std::unique_lock<std::mutex> lock(mInterfaceMutex);
     std::vector<String8> removedDeviceIds;
     status_t res = NAME_NOT_FOUND;
@@ -498,27 +1162,36 @@
 
 CameraProviderManager::ProviderInfo::ProviderInfo(
         const std::string &providerName,
-        sp<provider::V2_4::ICameraProvider>& interface,
         CameraProviderManager *manager) :
         mProviderName(providerName),
-        mInterface(interface),
         mProviderTagid(generateVendorTagId(providerName)),
         mUniqueDeviceCount(0),
         mManager(manager) {
     (void) mManager;
 }
 
-status_t CameraProviderManager::ProviderInfo::initialize() {
+status_t CameraProviderManager::ProviderInfo::initialize(
+        sp<provider::V2_4::ICameraProvider>& interface,
+        hardware::hidl_bitfield<provider::V2_5::DeviceState> currentDeviceState) {
     status_t res = parseProviderName(mProviderName, &mType, &mId);
     if (res != OK) {
         ALOGE("%s: Invalid provider name, ignoring", __FUNCTION__);
         return BAD_VALUE;
     }
     ALOGI("Connecting to new camera provider: %s, isRemote? %d",
-            mProviderName.c_str(), mInterface->isRemote());
+            mProviderName.c_str(), interface->isRemote());
+
+    // Determine minor version
+    auto castResult = provider::V2_5::ICameraProvider::castFrom(interface);
+    if (castResult.isOk()) {
+        mMinorVersion = 5;
+    } else {
+        mMinorVersion = 4;
+    }
+
     // cameraDeviceStatusChange callbacks may be called (and causing new devices added)
     // before setCallback returns
-    hardware::Return<Status> status = mInterface->setCallback(this);
+    hardware::Return<Status> status = interface->setCallback(this);
     if (!status.isOk()) {
         ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",
                 __FUNCTION__, mProviderName.c_str(), status.description().c_str());
@@ -530,7 +1203,7 @@
         return mapToStatusT(status);
     }
 
-    hardware::Return<bool> linked = mInterface->linkToDeath(this, /*cookie*/ mId);
+    hardware::Return<bool> linked = interface->linkToDeath(this, /*cookie*/ mId);
     if (!linked.isOk()) {
         ALOGE("%s: Transaction error in linking to camera provider '%s' death: %s",
                 __FUNCTION__, mProviderName.c_str(), linked.description().c_str());
@@ -540,15 +1213,42 @@
                 __FUNCTION__, mProviderName.c_str());
     }
 
+    if (!kEnableLazyHal) {
+        // Save HAL reference indefinitely
+        mSavedInterface = interface;
+    } else {
+        mActiveInterface = interface;
+    }
+
+    ALOGV("%s: Setting device state for %s: 0x%" PRIx64,
+            __FUNCTION__, mProviderName.c_str(), mDeviceState);
+    notifyDeviceStateChange(currentDeviceState);
+
+    res = setUpVendorTags();
+    if (res != OK) {
+        ALOGE("%s: Unable to set up vendor tags from provider '%s'",
+                __FUNCTION__, mProviderName.c_str());
+        return res;
+    }
+
     // Get initial list of camera devices, if any
     std::vector<std::string> devices;
-    hardware::Return<void> ret = mInterface->getCameraIdList([&status, &devices](
+    hardware::Return<void> ret = interface->getCameraIdList([&status, this, &devices](
             Status idStatus,
             const hardware::hidl_vec<hardware::hidl_string>& cameraDeviceNames) {
         status = idStatus;
         if (status == Status::OK) {
-            for (size_t i = 0; i < cameraDeviceNames.size(); i++) {
-                devices.push_back(cameraDeviceNames[i]);
+            for (auto& name : cameraDeviceNames) {
+                uint16_t major, minor;
+                std::string type, id;
+                status_t res = parseDeviceName(name, &major, &minor, &type, &id);
+                if (res != OK) {
+                    ALOGE("%s: Error parsing deviceName: %s: %d", __FUNCTION__, name.c_str(), res);
+                    status = Status::INTERNAL_ERROR;
+                } else {
+                    devices.push_back(name);
+                    mProviderPublicCameraIds.push_back(id);
+                }
             }
         } });
     if (!ret.isOk()) {
@@ -562,11 +1262,24 @@
         return mapToStatusT(status);
     }
 
+    ret = interface->isSetTorchModeSupported(
+        [this](auto status, bool supported) {
+            if (status == Status::OK) {
+                mSetTorchModeSupported = supported;
+            }
+        });
+    if (!ret.isOk()) {
+        ALOGE("%s: Transaction error checking torch mode support '%s': %s",
+                __FUNCTION__, mProviderName.c_str(), ret.description().c_str());
+        return DEAD_OBJECT;
+    }
+
+    mIsRemote = interface->isRemote();
+
     sp<StatusListener> listener = mManager->getStatusListener();
     for (auto& device : devices) {
         std::string id;
-        status_t res = addDevice(device,
-                hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT, &id);
+        status_t res = addDevice(device, common::V1_0::CameraDeviceStatus::PRESENT, &id);
         if (res != OK) {
             ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",
                     __FUNCTION__, device.c_str(), strerror(-res), res);
@@ -581,6 +1294,53 @@
     return OK;
 }
 
+const sp<provider::V2_4::ICameraProvider>
+CameraProviderManager::ProviderInfo::startProviderInterface() {
+    ATRACE_CALL();
+    ALOGV("Request to start camera provider: %s", mProviderName.c_str());
+    if (mSavedInterface != nullptr) {
+        return mSavedInterface;
+    }
+    if (!kEnableLazyHal) {
+        ALOGE("Bad provider state! Should not be here on a non-lazy HAL!");
+        return nullptr;
+    }
+
+    auto interface = mActiveInterface.promote();
+    if (interface == nullptr) {
+        ALOGI("Camera HAL provider needs restart, calling getService(%s)", mProviderName.c_str());
+        interface = mManager->mServiceProxy->getService(mProviderName);
+        interface->setCallback(this);
+        hardware::Return<bool> linked = interface->linkToDeath(this, /*cookie*/ mId);
+        if (!linked.isOk()) {
+            ALOGE("%s: Transaction error in linking to camera provider '%s' death: %s",
+                    __FUNCTION__, mProviderName.c_str(), linked.description().c_str());
+            mManager->removeProvider(mProviderName);
+            return nullptr;
+        } else if (!linked) {
+            ALOGW("%s: Unable to link to provider '%s' death notifications",
+                    __FUNCTION__, mProviderName.c_str());
+        }
+        // Send current device state
+        if (mMinorVersion >= 5) {
+            auto castResult = provider::V2_5::ICameraProvider::castFrom(interface);
+            if (castResult.isOk()) {
+                sp<provider::V2_5::ICameraProvider> interface_2_5 = castResult;
+                if (interface_2_5 != nullptr) {
+                    ALOGV("%s: Initial device state for %s: 0x %" PRIx64,
+                            __FUNCTION__, mProviderName.c_str(), mDeviceState);
+                    interface_2_5->notifyDeviceStateChange(mDeviceState);
+                }
+            }
+        }
+
+        mActiveInterface = interface;
+    } else {
+        ALOGV("Camera provider (%s) already in use. Re-using instance.", mProviderName.c_str());
+    }
+    return interface;
+}
+
 const std::string& CameraProviderManager::ProviderInfo::getType() const {
     return mType;
 }
@@ -631,7 +1391,12 @@
 
     mUniqueCameraIds.insert(id);
     if (isAPI1Compatible) {
-        mUniqueAPI1CompatibleCameraIds.push_back(id);
+        // addDevice can be called more than once for the same camera id if HAL
+        // supports openLegacy.
+        if (std::find(mUniqueAPI1CompatibleCameraIds.begin(), mUniqueAPI1CompatibleCameraIds.end(),
+                id) == mUniqueAPI1CompatibleCameraIds.end()) {
+            mUniqueAPI1CompatibleCameraIds.push_back(id);
+        }
     }
 
     if (parsedId != nullptr) {
@@ -656,8 +1421,10 @@
 }
 
 status_t CameraProviderManager::ProviderInfo::dump(int fd, const Vector<String16>&) const {
-    dprintf(fd, "== Camera Provider HAL %s (v2.4, %s) static info: %zu devices: ==\n",
-            mProviderName.c_str(), mInterface->isRemote() ? "remote" : "passthrough",
+    dprintf(fd, "== Camera Provider HAL %s (v2.%d, %s) static info: %zu devices: ==\n",
+            mProviderName.c_str(),
+            mMinorVersion,
+            mIsRemote ? "remote" : "passthrough",
             mDevices.size());
 
     for (auto& device : mDevices) {
@@ -698,6 +1465,24 @@
             info2.dump(fd, /*verbosity*/ 2, /*indentation*/ 4);
         }
 
+        // Dump characteristics of non-standalone physical camera
+        if (device->mIsLogicalCamera) {
+            for (auto& id : device->mPhysicalIds) {
+                // Skip if physical id is an independent camera
+                if (std::find(mProviderPublicCameraIds.begin(), mProviderPublicCameraIds.end(), id)
+                        != mProviderPublicCameraIds.end()) {
+                    continue;
+                }
+
+                CameraMetadata physicalInfo;
+                status_t status = device->getPhysicalCameraCharacteristics(id, &physicalInfo);
+                if (status == OK) {
+                    dprintf(fd, "  Physical camera %s characteristics:\n", id.c_str());
+                    physicalInfo.dump(fd, /*verbosity*/ 2, /*indentation*/ 4);
+                }
+            }
+        }
+
         dprintf(fd, "== Camera HAL device %s (v%d.%d) dumpState: ==\n", device->mName.c_str(),
                 device->mVersion.get_major(), device->mVersion.get_minor());
         res = device->dumpState(fd);
@@ -767,6 +1552,9 @@
                         torchStatusToString(newStatus));
                 id = deviceInfo->mId;
                 known = true;
+                if (TorchModeStatus::AVAILABLE_ON != newStatus) {
+                    mManager->removeRef(DeviceMode::TORCH, id);
+                }
                 break;
             }
         }
@@ -795,15 +1583,75 @@
     mManager->removeProvider(mProviderName);
 }
 
+status_t CameraProviderManager::ProviderInfo::setUpVendorTags() {
+    if (mVendorTagDescriptor != nullptr)
+        return OK;
+
+    hardware::hidl_vec<VendorTagSection> vts;
+    Status status;
+    hardware::Return<void> ret;
+    const sp<provider::V2_4::ICameraProvider> interface = startProviderInterface();
+    if (interface == nullptr) {
+        return DEAD_OBJECT;
+    }
+    ret = interface->getVendorTags(
+        [&](auto s, const auto& vendorTagSecs) {
+            status = s;
+            if (s == Status::OK) {
+                vts = vendorTagSecs;
+            }
+    });
+    if (!ret.isOk()) {
+        ALOGE("%s: Transaction error getting vendor tags from provider '%s': %s",
+                __FUNCTION__, mProviderName.c_str(), ret.description().c_str());
+        return DEAD_OBJECT;
+    }
+    if (status != Status::OK) {
+        return mapToStatusT(status);
+    }
+
+    // Read all vendor tag definitions into a descriptor
+    status_t res;
+    if ((res = HidlVendorTagDescriptor::createDescriptorFromHidl(vts, /*out*/mVendorTagDescriptor))
+            != OK) {
+        ALOGE("%s: Could not generate descriptor from vendor tag operations,"
+                "received error %s (%d). Camera clients will not be able to use"
+                "vendor tags", __FUNCTION__, strerror(res), res);
+        return res;
+    }
+
+    return OK;
+}
+
+status_t CameraProviderManager::ProviderInfo::notifyDeviceStateChange(
+        hardware::hidl_bitfield<provider::V2_5::DeviceState> newDeviceState) {
+    mDeviceState = newDeviceState;
+    if (mMinorVersion >= 5) {
+        // Check if the provider is currently active - not going to start it up for this notification
+        auto interface = mSavedInterface != nullptr ? mSavedInterface : mActiveInterface.promote();
+        if (interface != nullptr) {
+            // Send current device state
+            auto castResult = provider::V2_5::ICameraProvider::castFrom(interface);
+            if (castResult.isOk()) {
+                sp<provider::V2_5::ICameraProvider> interface_2_5 = castResult;
+                if (interface_2_5 != nullptr) {
+                    interface_2_5->notifyDeviceStateChange(mDeviceState);
+                }
+            }
+        }
+    }
+    return OK;
+}
+
 template<class DeviceInfoT>
 std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo>
     CameraProviderManager::ProviderInfo::initializeDeviceInfo(
         const std::string &name, const metadata_vendor_id_t tagId,
-        const std::string &id, uint16_t minorVersion) const {
+        const std::string &id, uint16_t minorVersion) {
     Status status;
 
     auto cameraInterface =
-            getDeviceInterface<typename DeviceInfoT::InterfaceT>(name);
+            startDeviceInterface<typename DeviceInfoT::InterfaceT>(name);
     if (cameraInterface == nullptr) return nullptr;
 
     CameraResourceCost resourceCost;
@@ -830,13 +1678,13 @@
     }
 
     return std::unique_ptr<DeviceInfo>(
-        new DeviceInfoT(name, tagId, id, minorVersion, resourceCost,
-                cameraInterface));
+        new DeviceInfoT(name, tagId, id, minorVersion, resourceCost, this,
+                mProviderPublicCameraIds, cameraInterface));
 }
 
 template<class InterfaceT>
 sp<InterfaceT>
-CameraProviderManager::ProviderInfo::getDeviceInterface(const std::string &name) const {
+CameraProviderManager::ProviderInfo::startDeviceInterface(const std::string &name) {
     ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__,
             name.c_str(), InterfaceT::version.get_major());
     return nullptr;
@@ -844,12 +1692,16 @@
 
 template<>
 sp<device::V1_0::ICameraDevice>
-CameraProviderManager::ProviderInfo::getDeviceInterface
-        <device::V1_0::ICameraDevice>(const std::string &name) const {
+CameraProviderManager::ProviderInfo::startDeviceInterface
+        <device::V1_0::ICameraDevice>(const std::string &name) {
     Status status;
     sp<device::V1_0::ICameraDevice> cameraInterface;
     hardware::Return<void> ret;
-    ret = mInterface->getCameraDeviceInterface_V1_x(name, [&status, &cameraInterface](
+    const sp<provider::V2_4::ICameraProvider> interface = startProviderInterface();
+    if (interface == nullptr) {
+        return nullptr;
+    }
+    ret = interface->getCameraDeviceInterface_V1_x(name, [&status, &cameraInterface](
         Status s, sp<device::V1_0::ICameraDevice> interface) {
                 status = s;
                 cameraInterface = interface;
@@ -869,12 +1721,16 @@
 
 template<>
 sp<device::V3_2::ICameraDevice>
-CameraProviderManager::ProviderInfo::getDeviceInterface
-        <device::V3_2::ICameraDevice>(const std::string &name) const {
+CameraProviderManager::ProviderInfo::startDeviceInterface
+        <device::V3_2::ICameraDevice>(const std::string &name) {
     Status status;
     sp<device::V3_2::ICameraDevice> cameraInterface;
     hardware::Return<void> ret;
-    ret = mInterface->getCameraDeviceInterface_V3_x(name, [&status, &cameraInterface](
+    const sp<provider::V2_4::ICameraProvider> interface = startProviderInterface();
+    if (interface == nullptr) {
+        return nullptr;
+    }
+    ret = interface->getCameraDeviceInterface_V3_x(name, [&status, &cameraInterface](
         Status s, sp<device::V3_2::ICameraDevice> interface) {
                 status = s;
                 cameraInterface = interface;
@@ -895,6 +1751,18 @@
 CameraProviderManager::ProviderInfo::DeviceInfo::~DeviceInfo() {}
 
 template<class InterfaceT>
+sp<InterfaceT> CameraProviderManager::ProviderInfo::DeviceInfo::startDeviceInterface() {
+    sp<InterfaceT> device;
+    ATRACE_CALL();
+    if (mSavedInterface == nullptr) {
+        device = mParentProvider->startDeviceInterface<InterfaceT>(mName);
+    } else {
+        device = (InterfaceT *) mSavedInterface.get();
+    }
+    return device;
+}
+
+template<class InterfaceT>
 status_t CameraProviderManager::ProviderInfo::DeviceInfo::setTorchMode(InterfaceT& interface,
         bool enabled) {
     Status s = interface->setTorchMode(enabled ? TorchMode::ON : TorchMode::OFF);
@@ -905,30 +1773,31 @@
         const metadata_vendor_id_t tagId, const std::string &id,
         uint16_t minorVersion,
         const CameraResourceCost& resourceCost,
+        sp<ProviderInfo> parentProvider,
+        const std::vector<std::string>& publicCameraIds,
         sp<InterfaceT> interface) :
         DeviceInfo(name, tagId, id, hardware::hidl_version{1, minorVersion},
-                   resourceCost),
-        mInterface(interface) {
+                   publicCameraIds, resourceCost, parentProvider) {
     // Get default parameters and initialize flash unit availability
     // Requires powering on the camera device
-    hardware::Return<Status> status = mInterface->open(nullptr);
+    hardware::Return<Status> status = interface->open(nullptr);
     if (!status.isOk()) {
         ALOGE("%s: Transaction error opening camera device %s to check for a flash unit: %s",
-                __FUNCTION__, mId.c_str(), status.description().c_str());
+                __FUNCTION__, id.c_str(), status.description().c_str());
         return;
     }
     if (status != Status::OK) {
         ALOGE("%s: Unable to open camera device %s to check for a flash unit: %s", __FUNCTION__,
-                mId.c_str(), CameraProviderManager::statusToString(status));
+                id.c_str(), CameraProviderManager::statusToString(status));
         return;
     }
     hardware::Return<void> ret;
-    ret = mInterface->getParameters([this](const hardware::hidl_string& parms) {
+    ret = interface->getParameters([this](const hardware::hidl_string& parms) {
                 mDefaultParameters.unflatten(String8(parms.c_str()));
             });
     if (!ret.isOk()) {
         ALOGE("%s: Transaction error reading camera device %s params to check for a flash unit: %s",
-                __FUNCTION__, mId.c_str(), status.description().c_str());
+                __FUNCTION__, id.c_str(), status.description().c_str());
         return;
     }
     const char *flashMode =
@@ -937,27 +1806,43 @@
         mHasFlashUnit = true;
     }
 
-    ret = mInterface->close();
+    status_t res = cacheCameraInfo(interface);
+    if (res != OK) {
+        ALOGE("%s: Could not cache CameraInfo", __FUNCTION__);
+        return;
+    }
+
+    ret = interface->close();
     if (!ret.isOk()) {
         ALOGE("%s: Transaction error closing camera device %s after check for a flash unit: %s",
-                __FUNCTION__, mId.c_str(), status.description().c_str());
+                __FUNCTION__, id.c_str(), status.description().c_str());
+    }
+
+    if (!kEnableLazyHal) {
+        // Save HAL reference indefinitely
+        mSavedInterface = interface;
     }
 }
 
 CameraProviderManager::ProviderInfo::DeviceInfo1::~DeviceInfo1() {}
 
 status_t CameraProviderManager::ProviderInfo::DeviceInfo1::setTorchMode(bool enabled) {
-    return DeviceInfo::setTorchMode(mInterface, enabled);
+    return setTorchModeForDevice<InterfaceT>(enabled);
 }
 
 status_t CameraProviderManager::ProviderInfo::DeviceInfo1::getCameraInfo(
         hardware::CameraInfo *info) const {
     if (info == nullptr) return BAD_VALUE;
+    *info = mInfo;
+    return OK;
+}
 
+status_t CameraProviderManager::ProviderInfo::DeviceInfo1::cacheCameraInfo(
+        sp<CameraProviderManager::ProviderInfo::DeviceInfo1::InterfaceT> interface) {
     Status status;
     device::V1_0::CameraInfo cInfo;
     hardware::Return<void> ret;
-    ret = mInterface->getCameraInfo([&status, &cInfo](Status s, device::V1_0::CameraInfo camInfo) {
+    ret = interface->getCameraInfo([&status, &cInfo](Status s, device::V1_0::CameraInfo camInfo) {
                 status = s;
                 cInfo = camInfo;
             });
@@ -972,27 +1857,31 @@
 
     switch(cInfo.facing) {
         case device::V1_0::CameraFacing::BACK:
-            info->facing = hardware::CAMERA_FACING_BACK;
+            mInfo.facing = hardware::CAMERA_FACING_BACK;
             break;
         case device::V1_0::CameraFacing::EXTERNAL:
             // Map external to front for legacy API
         case device::V1_0::CameraFacing::FRONT:
-            info->facing = hardware::CAMERA_FACING_FRONT;
+            mInfo.facing = hardware::CAMERA_FACING_FRONT;
             break;
         default:
             ALOGW("%s: Device %s: Unknown camera facing: %d",
                     __FUNCTION__, mId.c_str(), cInfo.facing);
-            info->facing = hardware::CAMERA_FACING_BACK;
+            mInfo.facing = hardware::CAMERA_FACING_BACK;
     }
-    info->orientation = cInfo.orientation;
+    mInfo.orientation = cInfo.orientation;
 
     return OK;
 }
 
-status_t CameraProviderManager::ProviderInfo::DeviceInfo1::dumpState(int fd) const {
+status_t CameraProviderManager::ProviderInfo::DeviceInfo1::dumpState(int fd) {
     native_handle_t* handle = native_handle_create(1,0);
     handle->data[0] = fd;
-    hardware::Return<Status> s = mInterface->dumpState(handle);
+    const sp<InterfaceT> interface = startDeviceInterface<InterfaceT>();
+    if (interface == nullptr) {
+        return DEAD_OBJECT;
+    }
+    hardware::Return<Status> s = interface->dumpState(handle);
     native_handle_delete(handle);
     if (!s.isOk()) {
         return INVALID_OPERATION;
@@ -1004,14 +1893,15 @@
         const metadata_vendor_id_t tagId, const std::string &id,
         uint16_t minorVersion,
         const CameraResourceCost& resourceCost,
+        sp<ProviderInfo> parentProvider,
+        const std::vector<std::string>& publicCameraIds,
         sp<InterfaceT> interface) :
         DeviceInfo(name, tagId, id, hardware::hidl_version{3, minorVersion},
-                   resourceCost),
-        mInterface(interface) {
+                   publicCameraIds, resourceCost, parentProvider) {
     // Get camera characteristics and initialize flash unit availability
     Status status;
     hardware::Return<void> ret;
-    ret = mInterface->getCameraCharacteristics([&status, this](Status s,
+    ret = interface->getCameraCharacteristics([&status, this](Status s,
                     device::V3_2::CameraMetadata metadata) {
                 status = s;
                 if (s == Status::OK) {
@@ -1030,15 +1920,35 @@
             });
     if (!ret.isOk()) {
         ALOGE("%s: Transaction error getting camera characteristics for device %s"
-                " to check for a flash unit: %s", __FUNCTION__, mId.c_str(),
+                " to check for a flash unit: %s", __FUNCTION__, id.c_str(),
                 ret.description().c_str());
         return;
     }
     if (status != Status::OK) {
         ALOGE("%s: Unable to get camera characteristics for device %s: %s (%d)",
-                __FUNCTION__, mId.c_str(), CameraProviderManager::statusToString(status), status);
+                __FUNCTION__, id.c_str(), CameraProviderManager::statusToString(status), status);
         return;
     }
+
+    mIsPublicallyHiddenSecureCamera = isPublicallyHiddenSecureCamera();
+
+    status_t res = fixupMonochromeTags();
+    if (OK != res) {
+        ALOGE("%s: Unable to fix up monochrome tags based for older HAL version: %s (%d)",
+                __FUNCTION__, strerror(-res), res);
+        return;
+    }
+    auto stat = addDynamicDepthTags();
+    if (OK != stat) {
+        ALOGE("%s: Failed appending dynamic depth tags: %s (%d)", __FUNCTION__, strerror(-stat),
+                stat);
+    }
+    res = deriveHeicTags();
+    if (OK != res) {
+        ALOGE("%s: Unable to derive HEIC tags based on camera and media capabilities: %s (%d)",
+                __FUNCTION__, strerror(-res), res);
+    }
+
     camera_metadata_entry flashAvailable =
             mCameraCharacteristics.find(ANDROID_FLASH_INFO_AVAILABLE);
     if (flashAvailable.count == 1 &&
@@ -1047,12 +1957,71 @@
     } else {
         mHasFlashUnit = false;
     }
+
+    queryPhysicalCameraIds();
+
+    // Get physical camera characteristics if applicable
+    auto castResult = device::V3_5::ICameraDevice::castFrom(interface);
+    if (!castResult.isOk()) {
+        ALOGV("%s: Unable to convert ICameraDevice instance to version 3.5", __FUNCTION__);
+        return;
+    }
+    sp<device::V3_5::ICameraDevice> interface_3_5 = castResult;
+    if (interface_3_5 == nullptr) {
+        ALOGE("%s: Converted ICameraDevice instance to nullptr", __FUNCTION__);
+        return;
+    }
+
+    if (mIsLogicalCamera) {
+        for (auto& id : mPhysicalIds) {
+            if (std::find(mPublicCameraIds.begin(), mPublicCameraIds.end(), id) !=
+                    mPublicCameraIds.end()) {
+                continue;
+            }
+
+            hardware::hidl_string hidlId(id);
+            ret = interface_3_5->getPhysicalCameraCharacteristics(hidlId,
+                    [&status, &id, this](Status s, device::V3_2::CameraMetadata metadata) {
+                status = s;
+                if (s == Status::OK) {
+                    camera_metadata_t *buffer =
+                            reinterpret_cast<camera_metadata_t*>(metadata.data());
+                    size_t expectedSize = metadata.size();
+                    int res = validate_camera_metadata_structure(buffer, &expectedSize);
+                    if (res == OK || res == CAMERA_METADATA_VALIDATION_SHIFTED) {
+                        set_camera_metadata_vendor_id(buffer, mProviderTagid);
+                        mPhysicalCameraCharacteristics[id] = buffer;
+                    } else {
+                        ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
+                        status = Status::INTERNAL_ERROR;
+                    }
+                }
+            });
+
+            if (!ret.isOk()) {
+                ALOGE("%s: Transaction error getting physical camera %s characteristics for %s: %s",
+                        __FUNCTION__, id.c_str(), id.c_str(), ret.description().c_str());
+                return;
+            }
+            if (status != Status::OK) {
+                ALOGE("%s: Unable to get physical camera %s characteristics for device %s: %s (%d)",
+                        __FUNCTION__, id.c_str(), mId.c_str(),
+                        CameraProviderManager::statusToString(status), status);
+                return;
+            }
+        }
+    }
+
+    if (!kEnableLazyHal) {
+        // Save HAL reference indefinitely
+        mSavedInterface = interface;
+    }
 }
 
 CameraProviderManager::ProviderInfo::DeviceInfo3::~DeviceInfo3() {}
 
 status_t CameraProviderManager::ProviderInfo::DeviceInfo3::setTorchMode(bool enabled) {
-    return DeviceInfo::setTorchMode(mInterface, enabled);
+    return setTorchModeForDevice<InterfaceT>(enabled);
 }
 
 status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getCameraInfo(
@@ -1103,10 +2072,14 @@
     return isBackwardCompatible;
 }
 
-status_t CameraProviderManager::ProviderInfo::DeviceInfo3::dumpState(int fd) const {
+status_t CameraProviderManager::ProviderInfo::DeviceInfo3::dumpState(int fd) {
     native_handle_t* handle = native_handle_create(1,0);
     handle->data[0] = fd;
-    auto ret = mInterface->dumpState(handle);
+    const sp<InterfaceT> interface = startDeviceInterface<InterfaceT>();
+    if (interface == nullptr) {
+        return DEAD_OBJECT;
+    }
+    auto ret = interface->dumpState(handle);
     native_handle_delete(handle);
     if (!ret.isOk()) {
         return INVALID_OPERATION;
@@ -1122,6 +2095,61 @@
     return OK;
 }
 
+status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getPhysicalCameraCharacteristics(
+        const std::string& physicalCameraId, CameraMetadata *characteristics) const {
+    if (characteristics == nullptr) return BAD_VALUE;
+    if (mPhysicalCameraCharacteristics.find(physicalCameraId) ==
+            mPhysicalCameraCharacteristics.end()) {
+        return NAME_NOT_FOUND;
+    }
+
+    *characteristics = mPhysicalCameraCharacteristics.at(physicalCameraId);
+    return OK;
+}
+
+status_t CameraProviderManager::ProviderInfo::DeviceInfo3::isSessionConfigurationSupported(
+        const hardware::camera::device::V3_4::StreamConfiguration &configuration,
+        bool *status /*out*/) {
+
+    const sp<CameraProviderManager::ProviderInfo::DeviceInfo3::InterfaceT> interface =
+            this->startDeviceInterface<CameraProviderManager::ProviderInfo::DeviceInfo3::InterfaceT>();
+    if (interface == nullptr) {
+        return DEAD_OBJECT;
+    }
+    auto castResult = device::V3_5::ICameraDevice::castFrom(interface);
+    sp<hardware::camera::device::V3_5::ICameraDevice> interface_3_5 = castResult;
+    if (interface_3_5 == nullptr) {
+        return INVALID_OPERATION;
+    }
+
+    status_t res;
+    Status callStatus;
+    auto ret =  interface_3_5->isStreamCombinationSupported(configuration,
+            [&callStatus, &status] (Status s, bool combStatus) {
+                callStatus = s;
+                *status = combStatus;
+            });
+    if (ret.isOk()) {
+        switch (callStatus) {
+            case Status::OK:
+                // Expected case, do nothing.
+                res = OK;
+                break;
+            case Status::METHOD_NOT_SUPPORTED:
+                res = INVALID_OPERATION;
+                break;
+            default:
+                ALOGE("%s: Session configuration query failed: %d", __FUNCTION__, callStatus);
+                res = UNKNOWN_ERROR;
+        }
+    } else {
+        ALOGE("%s: Unexpected binder error: %s", __FUNCTION__, ret.description().c_str());
+        res = UNKNOWN_ERROR;
+    }
+
+    return res;
+}
+
 status_t CameraProviderManager::ProviderInfo::parseProviderName(const std::string& name,
         std::string *type, uint32_t *id) {
     // Format must be "<type>/<id>"
@@ -1364,7 +2392,7 @@
 
 
 status_t HidlVendorTagDescriptor::createDescriptorFromHidl(
-        const hardware::hidl_vec<hardware::camera::common::V1_0::VendorTagSection>& vts,
+        const hardware::hidl_vec<common::V1_0::VendorTagSection>& vts,
         /*out*/
         sp<VendorTagDescriptor>& descriptor) {
 
@@ -1392,7 +2420,7 @@
 
     int idx = 0;
     for (size_t s = 0; s < vts.size(); s++) {
-        const hardware::camera::common::V1_0::VendorTagSection& section = vts[s];
+        const common::V1_0::VendorTagSection& section = vts[s];
         const char *sectionName = section.sectionName.c_str();
         if (sectionName == NULL) {
             ALOGE("%s: no section name defined for vendor tag section %zu.", __FUNCTION__, s);
@@ -1453,49 +2481,69 @@
 
 status_t CameraProviderManager::getCameraCharacteristicsLocked(const std::string &id,
         CameraMetadata* characteristics) const {
-    auto deviceInfo = findDeviceInfoLocked(id, /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
-    if (deviceInfo == nullptr) return NAME_NOT_FOUND;
+    auto deviceInfo = findDeviceInfoLocked(id, /*minVersion*/ {3,0}, /*maxVersion*/ {5,0});
+    if (deviceInfo != nullptr) {
+        return deviceInfo->getCameraCharacteristics(characteristics);
+    }
 
-    return deviceInfo->getCameraCharacteristics(characteristics);
+    // Find hidden physical camera characteristics
+    for (auto& provider : mProviders) {
+        for (auto& deviceInfo : provider->mDevices) {
+            status_t res = deviceInfo->getPhysicalCameraCharacteristics(id, characteristics);
+            if (res != NAME_NOT_FOUND) return res;
+        }
+    }
+
+    return NAME_NOT_FOUND;
 }
 
 void CameraProviderManager::filterLogicalCameraIdsLocked(
         std::vector<std::string>& deviceIds) const
 {
-    std::unordered_set<std::string> removedIds;
+    // Map between camera facing and camera IDs related to logical camera.
+    std::map<int, std::unordered_set<std::string>> idCombos;
 
+    // Collect all logical and its underlying physical camera IDs for each
+    // facing.
     for (auto& deviceId : deviceIds) {
-        CameraMetadata info;
-        status_t res = getCameraCharacteristicsLocked(deviceId, &info);
-        if (res != OK) {
-            ALOGE("%s: Failed to getCameraCharacteristics for id %s", __FUNCTION__,
-                    deviceId.c_str());
-            return;
-        }
+        auto deviceInfo = findDeviceInfoLocked(deviceId);
+        if (deviceInfo == nullptr) continue;
 
-        // idCombo contains the ids of a logical camera and its physical cameras
-        std::vector<std::string> idCombo;
-        bool logicalCamera = CameraProviderManager::isLogicalCamera(info, &idCombo);
-        if (!logicalCamera) {
+        if (!deviceInfo->mIsLogicalCamera) {
             continue;
         }
-        idCombo.push_back(deviceId);
 
+        // combo contains the ids of a logical camera and its physical cameras
+        std::vector<std::string> combo = deviceInfo->mPhysicalIds;
+        combo.push_back(deviceId);
+
+        hardware::CameraInfo info;
+        status_t res = deviceInfo->getCameraInfo(&info);
+        if (res != OK) {
+            ALOGE("%s: Error reading camera info: %s (%d)", __FUNCTION__, strerror(-res), res);
+            continue;
+        }
+        idCombos[info.facing].insert(combo.begin(), combo.end());
+    }
+
+    // Only expose one camera ID per facing for all logical and underlying
+    // physical camera IDs.
+    for (auto& r : idCombos) {
+        auto& removedIds = r.second;
         for (auto& id : deviceIds) {
-            auto foundId = std::find(idCombo.begin(), idCombo.end(), id);
-            if (foundId == idCombo.end()) {
+            auto foundId = std::find(removedIds.begin(), removedIds.end(), id);
+            if (foundId == removedIds.end()) {
                 continue;
             }
 
-            idCombo.erase(foundId);
-            removedIds.insert(idCombo.begin(), idCombo.end());
+            removedIds.erase(foundId);
             break;
         }
+        deviceIds.erase(std::remove_if(deviceIds.begin(), deviceIds.end(),
+                [&removedIds](const std::string& s) {
+                return removedIds.find(s) != removedIds.end();}),
+                deviceIds.end());
     }
-
-    deviceIds.erase(std::remove_if(deviceIds.begin(), deviceIds.end(),
-            [&removedIds](const std::string& s) {return removedIds.find(s) != removedIds.end();}),
-            deviceIds.end());
 }
 
 } // namespace android
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index b8b8b8c..a42fb4d 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -18,6 +18,7 @@
 #define ANDROID_SERVERS_CAMERA_CAMERAPROVIDER_H
 
 #include <vector>
+#include <unordered_map>
 #include <unordered_set>
 #include <string>
 #include <mutex>
@@ -27,8 +28,8 @@
 #include <camera/CameraBase.h>
 #include <utils/Errors.h>
 #include <android/hardware/camera/common/1.0/types.h>
-#include <android/hardware/camera/provider/2.4/ICameraProvider.h>
-//#include <android/hardware/camera/provider/2.4/ICameraProviderCallbacks.h>
+#include <android/hardware/camera/provider/2.5/ICameraProvider.h>
+#include <android/hardware/camera/device/3.4/ICameraDeviceSession.h>
 #include <android/hidl/manager/1.0/IServiceNotification.h>
 #include <camera/VendorTagDescriptor.h>
 
@@ -110,6 +111,14 @@
     };
 
     /**
+     * Represents the mode a camera device is currently in
+     */
+    enum class DeviceMode {
+        TORCH,
+        CAMERA
+    };
+
+    /**
      * Initialize the manager and give it a status listener; optionally accepts a service
      * interaction proxy.
      *
@@ -166,6 +175,13 @@
             CameraMetadata* characteristics) const;
 
     /**
+     * Check for device support of specific stream combination.
+     */
+    status_t isSessionConfigurationSupported(const std::string& id,
+            const hardware::camera::device::V3_4::StreamConfiguration &configuration,
+            bool *status /*out*/) const;
+
+    /**
      * Return the highest supported device interface version for this ID
      */
     status_t getHighestSupportedVersion(const std::string &id,
@@ -174,7 +190,7 @@
     /**
      * Check if a given camera device support setTorchMode API.
      */
-    bool supportSetTorchMode(const std::string &id);
+    bool supportSetTorchMode(const std::string &id) const;
 
     /**
      * Turn on or off the flashlight on a given camera device.
@@ -189,6 +205,12 @@
     status_t setUpVendorTags();
 
     /**
+     * Inform registered providers about a device state change, such as folding or unfolding
+     */
+    status_t notifyDeviceStateChange(
+        android::hardware::hidl_bitfield<hardware::camera::provider::V2_5::DeviceState> newState);
+
+    /**
      * Open an active session to a camera device.
      *
      * This fully powers on the camera device hardware, and returns a handle to a
@@ -205,6 +227,17 @@
             sp<hardware::camera::device::V1_0::ICameraDevice> *session);
 
     /**
+     * Save the ICameraProvider while it is being used by a camera or torch client
+     */
+    void saveRef(DeviceMode usageType, const std::string &cameraId,
+            sp<hardware::camera::provider::V2_4::ICameraProvider> provider);
+
+    /**
+     * Notify that the camera or torch is no longer being used by a camera client
+     */
+    void removeRef(DeviceMode usageType, const std::string &cameraId);
+
+    /**
      * IServiceNotification::onRegistration
      * Invoked by the hardware service manager when a new camera provider is registered
      */
@@ -231,12 +264,15 @@
             hardware::hidl_version maxVersion = hardware::hidl_version{1000,0}) const;
 
     /*
-     * Check if a camera with staticInfo is a logical camera. And if yes, return
+     * Check if a camera is a logical camera. And if yes, return
      * the physical camera ids.
      */
-    static bool isLogicalCamera(const CameraMetadata& staticInfo,
-            std::vector<std::string>* physicalCameraIds);
+    bool isLogicalCamera(const std::string& id, std::vector<std::string>* physicalCameraIds);
 
+    bool isPublicallyHiddenSecureCamera(const std::string& id);
+    bool isHiddenPhysicalCamera(const std::string& cameraId);
+
+    static const float kDepthARTolerance;
 private:
     // All private members, unless otherwise noted, expect mInterfaceMutex to be locked before use
     mutable std::mutex mInterfaceMutex;
@@ -246,22 +282,57 @@
     wp<StatusListener> mListener;
     ServiceInteractionProxy* mServiceProxy;
 
+    // Current overall Android device physical status
+    android::hardware::hidl_bitfield<hardware::camera::provider::V2_5::DeviceState> mDeviceState;
+
+    // mProviderLifecycleLock is locked during onRegistration and removeProvider
+    mutable std::mutex mProviderLifecycleLock;
+
     static HardwareServiceInteractionProxy sHardwareServiceInteractionProxy;
 
+    // Mapping from CameraDevice IDs to CameraProviders. This map is used to keep the
+    // ICameraProvider alive while it is in use by the camera with the given ID for camera
+    // capabilities
+    std::unordered_map<std::string, sp<hardware::camera::provider::V2_4::ICameraProvider>>
+            mCameraProviderByCameraId;
+
+    // Mapping from CameraDevice IDs to CameraProviders. This map is used to keep the
+    // ICameraProvider alive while it is in use by the camera with the given ID for torch
+    // capabilities
+    std::unordered_map<std::string, sp<hardware::camera::provider::V2_4::ICameraProvider>>
+            mTorchProviderByCameraId;
+
+    // Lock for accessing mCameraProviderByCameraId and mTorchProviderByCameraId
+    std::mutex mProviderInterfaceMapLock;
+
     struct ProviderInfo :
             virtual public hardware::camera::provider::V2_4::ICameraProviderCallback,
             virtual public hardware::hidl_death_recipient
     {
         const std::string mProviderName;
-        const sp<hardware::camera::provider::V2_4::ICameraProvider> mInterface;
         const metadata_vendor_id_t mProviderTagid;
+        int mMinorVersion;
+        sp<VendorTagDescriptor> mVendorTagDescriptor;
+        bool mSetTorchModeSupported;
+        bool mIsRemote;
+
+        // Current overall Android device physical status
+        hardware::hidl_bitfield<hardware::camera::provider::V2_5::DeviceState> mDeviceState;
+
+        // This pointer is used to keep a reference to the ICameraProvider that was last accessed.
+        wp<hardware::camera::provider::V2_4::ICameraProvider> mActiveInterface;
+
+        sp<hardware::camera::provider::V2_4::ICameraProvider> mSavedInterface;
 
         ProviderInfo(const std::string &providerName,
-                sp<hardware::camera::provider::V2_4::ICameraProvider>& interface,
                 CameraProviderManager *manager);
         ~ProviderInfo();
 
-        status_t initialize();
+        status_t initialize(sp<hardware::camera::provider::V2_4::ICameraProvider>& interface,
+                hardware::hidl_bitfield<hardware::camera::provider::V2_5::DeviceState>
+                    currentDeviceState);
+
+        const sp<hardware::camera::provider::V2_4::ICameraProvider> startProviderInterface();
 
         const std::string& getType() const;
 
@@ -283,84 +354,173 @@
         // hidl_death_recipient interface - this locks the parent mInterfaceMutex
         virtual void serviceDied(uint64_t cookie, const wp<hidl::base::V1_0::IBase>& who) override;
 
+        /**
+         * Setup vendor tags for this provider
+         */
+        status_t setUpVendorTags();
+
+        /**
+         * Notify provider about top-level device physical state changes
+         */
+        status_t notifyDeviceStateChange(
+                hardware::hidl_bitfield<hardware::camera::provider::V2_5::DeviceState>
+                    newDeviceState);
+
         // Basic device information, common to all camera devices
         struct DeviceInfo {
             const std::string mName;  // Full instance name
             const std::string mId;    // ID section of full name
             const hardware::hidl_version mVersion;
             const metadata_vendor_id_t mProviderTagid;
+            bool mIsLogicalCamera;
+            std::vector<std::string> mPhysicalIds;
+            hardware::CameraInfo mInfo;
+            sp<IBase> mSavedInterface;
+            bool mIsPublicallyHiddenSecureCamera = false;
 
             const hardware::camera::common::V1_0::CameraResourceCost mResourceCost;
 
             hardware::camera::common::V1_0::CameraDeviceStatus mStatus;
 
+            sp<ProviderInfo> mParentProvider;
+
             bool hasFlashUnit() const { return mHasFlashUnit; }
             virtual status_t setTorchMode(bool enabled) = 0;
             virtual status_t getCameraInfo(hardware::CameraInfo *info) const = 0;
             virtual bool isAPI1Compatible() const = 0;
-            virtual status_t dumpState(int fd) const = 0;
+            virtual status_t dumpState(int fd) = 0;
             virtual status_t getCameraCharacteristics(CameraMetadata *characteristics) const {
                 (void) characteristics;
                 return INVALID_OPERATION;
             }
+            virtual status_t getPhysicalCameraCharacteristics(const std::string& physicalCameraId,
+                    CameraMetadata *characteristics) const {
+                (void) physicalCameraId;
+                (void) characteristics;
+                return INVALID_OPERATION;
+            }
+
+            virtual status_t isSessionConfigurationSupported(
+                    const hardware::camera::device::V3_4::StreamConfiguration &/*configuration*/,
+                    bool * /*status*/) {
+                return INVALID_OPERATION;
+            }
+
+            template<class InterfaceT>
+            sp<InterfaceT> startDeviceInterface();
 
             DeviceInfo(const std::string& name, const metadata_vendor_id_t tagId,
                     const std::string &id, const hardware::hidl_version& version,
-                    const hardware::camera::common::V1_0::CameraResourceCost& resourceCost) :
+                    const std::vector<std::string>& publicCameraIds,
+                    const hardware::camera::common::V1_0::CameraResourceCost& resourceCost,
+                    sp<ProviderInfo> parentProvider) :
                     mName(name), mId(id), mVersion(version), mProviderTagid(tagId),
-                    mResourceCost(resourceCost),
+                    mIsLogicalCamera(false), mResourceCost(resourceCost),
                     mStatus(hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT),
-                    mHasFlashUnit(false) {}
+                    mParentProvider(parentProvider), mHasFlashUnit(false),
+                    mPublicCameraIds(publicCameraIds) {}
             virtual ~DeviceInfo();
         protected:
             bool mHasFlashUnit;
+            const std::vector<std::string>& mPublicCameraIds;
 
             template<class InterfaceT>
             static status_t setTorchMode(InterfaceT& interface, bool enabled);
+
+            template<class InterfaceT>
+            status_t setTorchModeForDevice(bool enabled) {
+                // Don't save the ICameraProvider interface here because we assume that this was
+                // called from CameraProviderManager::setTorchMode(), which does save it.
+                const sp<InterfaceT> interface = startDeviceInterface<InterfaceT>();
+                return DeviceInfo::setTorchMode(interface, enabled);
+            }
         };
         std::vector<std::unique_ptr<DeviceInfo>> mDevices;
         std::unordered_set<std::string> mUniqueCameraIds;
         int mUniqueDeviceCount;
         std::vector<std::string> mUniqueAPI1CompatibleCameraIds;
+        // The initial public camera IDs published by the camera provider.
+        // Currently logical multi-camera is not supported for hot-plug camera.
+        // And we use this list to keep track of initial public camera IDs
+        // advertised by the provider, and to distinguish against "hidden"
+        // physical camera IDs.
+        std::vector<std::string> mProviderPublicCameraIds;
 
         // HALv1-specific camera fields, including the actual device interface
         struct DeviceInfo1 : public DeviceInfo {
             typedef hardware::camera::device::V1_0::ICameraDevice InterfaceT;
-            const sp<InterfaceT> mInterface;
 
             virtual status_t setTorchMode(bool enabled) override;
             virtual status_t getCameraInfo(hardware::CameraInfo *info) const override;
             //In case of Device1Info assume that we are always API1 compatible
             virtual bool isAPI1Compatible() const override { return true; }
-            virtual status_t dumpState(int fd) const override;
+            virtual status_t dumpState(int fd) override;
             DeviceInfo1(const std::string& name, const metadata_vendor_id_t tagId,
                     const std::string &id, uint16_t minorVersion,
                     const hardware::camera::common::V1_0::CameraResourceCost& resourceCost,
+                    sp<ProviderInfo> parentProvider,
+                    const std::vector<std::string>& publicCameraIds,
                     sp<InterfaceT> interface);
             virtual ~DeviceInfo1();
         private:
             CameraParameters2 mDefaultParameters;
+            status_t cacheCameraInfo(sp<InterfaceT> interface);
         };
 
         // HALv3-specific camera fields, including the actual device interface
         struct DeviceInfo3 : public DeviceInfo {
             typedef hardware::camera::device::V3_2::ICameraDevice InterfaceT;
-            const sp<InterfaceT> mInterface;
 
             virtual status_t setTorchMode(bool enabled) override;
             virtual status_t getCameraInfo(hardware::CameraInfo *info) const override;
             virtual bool isAPI1Compatible() const override;
-            virtual status_t dumpState(int fd) const override;
+            virtual status_t dumpState(int fd) override;
             virtual status_t getCameraCharacteristics(
                     CameraMetadata *characteristics) const override;
+            virtual status_t getPhysicalCameraCharacteristics(const std::string& physicalCameraId,
+                    CameraMetadata *characteristics) const override;
+            virtual status_t isSessionConfigurationSupported(
+                    const hardware::camera::device::V3_4::StreamConfiguration &configuration,
+                    bool *status /*out*/)
+                    override;
 
             DeviceInfo3(const std::string& name, const metadata_vendor_id_t tagId,
                     const std::string &id, uint16_t minorVersion,
                     const hardware::camera::common::V1_0::CameraResourceCost& resourceCost,
-                    sp<InterfaceT> interface);
+                    sp<ProviderInfo> parentProvider,
+                    const std::vector<std::string>& publicCameraIds, sp<InterfaceT> interface);
             virtual ~DeviceInfo3();
         private:
             CameraMetadata mCameraCharacteristics;
+            std::unordered_map<std::string, CameraMetadata> mPhysicalCameraCharacteristics;
+            void queryPhysicalCameraIds();
+            bool isPublicallyHiddenSecureCamera();
+            status_t fixupMonochromeTags();
+            status_t addDynamicDepthTags();
+            static void getSupportedSizes(const CameraMetadata& ch, uint32_t tag,
+                    android_pixel_format_t format,
+                    std::vector<std::tuple<size_t, size_t>> *sizes /*out*/);
+            void getSupportedDurations( const CameraMetadata& ch, uint32_t tag,
+                    android_pixel_format_t format,
+                    const std::vector<std::tuple<size_t, size_t>>& sizes,
+                    std::vector<int64_t> *durations/*out*/);
+            void getSupportedDynamicDepthDurations(const std::vector<int64_t>& depthDurations,
+                    const std::vector<int64_t>& blobDurations,
+                    std::vector<int64_t> *dynamicDepthDurations /*out*/);
+            static bool isDepthPhotoLibraryPresent();
+            static void getSupportedDynamicDepthSizes(
+                    const std::vector<std::tuple<size_t, size_t>>& blobSizes,
+                    const std::vector<std::tuple<size_t, size_t>>& depthSizes,
+                    std::vector<std::tuple<size_t, size_t>> *dynamicDepthSizes /*out*/,
+                    std::vector<std::tuple<size_t, size_t>> *internalDepthSizes /*out*/);
+            status_t removeAvailableKeys(CameraMetadata& c, const std::vector<uint32_t>& keys,
+                    uint32_t keyTag);
+            status_t fillHeicStreamCombinations(std::vector<int32_t>* outputs,
+                    std::vector<int64_t>* durations,
+                    std::vector<int64_t>* stallDurations,
+                    const camera_metadata_entry& halStreamConfigs,
+                    const camera_metadata_entry& halStreamDurations);
+            status_t deriveHeicTags();
         };
 
     private:
@@ -378,11 +538,11 @@
         template<class DeviceInfoT>
         std::unique_ptr<DeviceInfo> initializeDeviceInfo(const std::string &name,
                 const metadata_vendor_id_t tagId, const std::string &id,
-                uint16_t minorVersion) const;
+                uint16_t minorVersion);
 
         // Helper for initializeDeviceInfo to use the right CameraProvider get method.
         template<class InterfaceT>
-        sp<InterfaceT> getDeviceInterface(const std::string &name) const;
+        sp<InterfaceT> startDeviceInterface(const std::string &name);
 
         // Parse provider instance name for type and id
         static status_t parseProviderName(const std::string& name,
@@ -416,6 +576,14 @@
 
     std::vector<sp<ProviderInfo>> mProviders;
 
+    void addProviderToMap(
+            const std::string &cameraId,
+            sp<hardware::camera::provider::V2_4::ICameraProvider> provider,
+            bool isTorchUsage);
+    void removeCameraIdFromMap(
+        std::unordered_map<std::string, sp<hardware::camera::provider::V2_4::ICameraProvider>> &map,
+        const std::string &cameraId);
+
     static const char* deviceStatusToString(
         const hardware::camera::common::V1_0::CameraDeviceStatus&);
     static const char* torchStatusToString(
diff --git a/services/camera/libcameraservice/common/DepthPhotoProcessor.cpp b/services/camera/libcameraservice/common/DepthPhotoProcessor.cpp
new file mode 100644
index 0000000..3c90de0
--- /dev/null
+++ b/services/camera/libcameraservice/common/DepthPhotoProcessor.cpp
@@ -0,0 +1,515 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Camera3-DepthPhotoProcessor"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+//#define LOG_NDEBUG 0
+//
+
+#include "DepthPhotoProcessor.h"
+
+#include <dynamic_depth/camera.h>
+#include <dynamic_depth/cameras.h>
+#include <dynamic_depth/container.h>
+#include <dynamic_depth/device.h>
+#include <dynamic_depth/dimension.h>
+#include <dynamic_depth/dynamic_depth.h>
+#include <dynamic_depth/point.h>
+#include <dynamic_depth/pose.h>
+#include <dynamic_depth/profile.h>
+#include <dynamic_depth/profiles.h>
+#include <jpeglib.h>
+#include <libexif/exif-data.h>
+#include <libexif/exif-system.h>
+#include <math.h>
+#include <sstream>
+#include <utils/Errors.h>
+#include <utils/ExifUtils.h>
+#include <utils/Log.h>
+#include <xmpmeta/xmp_data.h>
+#include <xmpmeta/xmp_writer.h>
+
+using dynamic_depth::Camera;
+using dynamic_depth::Cameras;
+using dynamic_depth::CameraParams;
+using dynamic_depth::Container;
+using dynamic_depth::DepthFormat;
+using dynamic_depth::DepthMap;
+using dynamic_depth::DepthMapParams;
+using dynamic_depth::DepthUnits;
+using dynamic_depth::Device;
+using dynamic_depth::DeviceParams;
+using dynamic_depth::Dimension;
+using dynamic_depth::Image;
+using dynamic_depth::ImagingModel;
+using dynamic_depth::ImagingModelParams;
+using dynamic_depth::Item;
+using dynamic_depth::Pose;
+using dynamic_depth::Profile;
+using dynamic_depth::Profiles;
+
+template<>
+struct std::default_delete<jpeg_compress_struct> {
+    inline void operator()(jpeg_compress_struct* cinfo) const {
+        jpeg_destroy_compress(cinfo);
+    }
+};
+
+namespace android {
+namespace camera3 {
+
+// Depth samples with low confidence can skew the
+// near/far values and impact the range inverse coding.
+static const float CONFIDENCE_THRESHOLD = .15f;
+
+ExifOrientation getExifOrientation(const unsigned char *jpegBuffer, size_t jpegBufferSize) {
+    if ((jpegBuffer == nullptr) || (jpegBufferSize == 0)) {
+        return ExifOrientation::ORIENTATION_UNDEFINED;
+    }
+
+    auto exifData = exif_data_new();
+    exif_data_load_data(exifData, jpegBuffer, jpegBufferSize);
+    ExifEntry *orientation = exif_content_get_entry(exifData->ifd[EXIF_IFD_0],
+            EXIF_TAG_ORIENTATION);
+    if ((orientation == nullptr) || (orientation->size != sizeof(ExifShort))) {
+        ALOGV("%s: Orientation EXIF entry invalid!", __FUNCTION__);
+        exif_data_unref(exifData);
+        return ExifOrientation::ORIENTATION_0_DEGREES;
+    }
+
+    auto orientationValue = exif_get_short(orientation->data, exif_data_get_byte_order(exifData));
+    ExifOrientation ret;
+    switch (orientationValue) {
+        case ExifOrientation::ORIENTATION_0_DEGREES:
+        case ExifOrientation::ORIENTATION_90_DEGREES:
+        case ExifOrientation::ORIENTATION_180_DEGREES:
+        case ExifOrientation::ORIENTATION_270_DEGREES:
+            ret = static_cast<ExifOrientation> (orientationValue);
+            break;
+        default:
+            ALOGE("%s: Unexpected EXIF orientation value: %d, defaulting to 0 degrees",
+                    __FUNCTION__, orientationValue);
+            ret = ExifOrientation::ORIENTATION_0_DEGREES;
+    }
+
+    exif_data_unref(exifData);
+
+    return ret;
+}
+
+status_t encodeGrayscaleJpeg(size_t width, size_t height, uint8_t *in, void *out,
+        const size_t maxOutSize, uint8_t jpegQuality, ExifOrientation exifOrientation,
+        size_t &actualSize) {
+    status_t ret;
+    // libjpeg is a C library so we use C-style "inheritance" by
+    // putting libjpeg's jpeg_destination_mgr first in our custom
+    // struct. This allows us to cast jpeg_destination_mgr* to
+    // CustomJpegDestMgr* when we get it passed to us in a callback.
+    struct CustomJpegDestMgr : public jpeg_destination_mgr {
+        JOCTET *mBuffer;
+        size_t mBufferSize;
+        size_t mEncodedSize;
+        bool mSuccess;
+    } dmgr;
+
+    std::unique_ptr<jpeg_compress_struct> cinfo = std::make_unique<jpeg_compress_struct>();
+    jpeg_error_mgr jerr;
+
+    // Initialize error handling with standard callbacks, but
+    // then override output_message (to print to ALOG) and
+    // error_exit to set a flag and print a message instead
+    // of killing the whole process.
+    cinfo->err = jpeg_std_error(&jerr);
+
+    cinfo->err->output_message = [](j_common_ptr cinfo) {
+        char buffer[JMSG_LENGTH_MAX];
+
+        /* Create the message */
+        (*cinfo->err->format_message)(cinfo, buffer);
+        ALOGE("libjpeg error: %s", buffer);
+    };
+
+    cinfo->err->error_exit = [](j_common_ptr cinfo) {
+        (*cinfo->err->output_message)(cinfo);
+        if(cinfo->client_data) {
+            auto & dmgr = *static_cast<CustomJpegDestMgr*>(cinfo->client_data);
+            dmgr.mSuccess = false;
+        }
+    };
+
+    // Now that we initialized some callbacks, let's create our compressor
+    jpeg_create_compress(cinfo.get());
+    dmgr.mBuffer = static_cast<JOCTET*>(out);
+    dmgr.mBufferSize = maxOutSize;
+    dmgr.mEncodedSize = 0;
+    dmgr.mSuccess = true;
+    cinfo->client_data = static_cast<void*>(&dmgr);
+
+    // These lambdas become C-style function pointers and as per C++11 spec
+    // may not capture anything.
+    dmgr.init_destination = [](j_compress_ptr cinfo) {
+        auto & dmgr = static_cast<CustomJpegDestMgr&>(*cinfo->dest);
+        dmgr.next_output_byte = dmgr.mBuffer;
+        dmgr.free_in_buffer = dmgr.mBufferSize;
+        ALOGV("%s:%d jpeg start: %p [%zu]",
+              __FUNCTION__, __LINE__, dmgr.mBuffer, dmgr.mBufferSize);
+    };
+
+    dmgr.empty_output_buffer = [](j_compress_ptr cinfo __unused) {
+        ALOGV("%s:%d Out of buffer", __FUNCTION__, __LINE__);
+        return 0;
+    };
+
+    dmgr.term_destination = [](j_compress_ptr cinfo) {
+        auto & dmgr = static_cast<CustomJpegDestMgr&>(*cinfo->dest);
+        dmgr.mEncodedSize = dmgr.mBufferSize - dmgr.free_in_buffer;
+        ALOGV("%s:%d Done with jpeg: %zu", __FUNCTION__, __LINE__, dmgr.mEncodedSize);
+    };
+    cinfo->dest = static_cast<struct jpeg_destination_mgr*>(&dmgr);
+    cinfo->image_width = width;
+    cinfo->image_height = height;
+    cinfo->input_components = 1;
+    cinfo->in_color_space = JCS_GRAYSCALE;
+
+    // Initialize defaults and then override what we want
+    jpeg_set_defaults(cinfo.get());
+
+    jpeg_set_quality(cinfo.get(), jpegQuality, 1);
+    jpeg_set_colorspace(cinfo.get(), JCS_GRAYSCALE);
+    cinfo->raw_data_in = 0;
+    cinfo->dct_method = JDCT_IFAST;
+
+    cinfo->comp_info[0].h_samp_factor = 1;
+    cinfo->comp_info[1].h_samp_factor = 1;
+    cinfo->comp_info[2].h_samp_factor = 1;
+    cinfo->comp_info[0].v_samp_factor = 1;
+    cinfo->comp_info[1].v_samp_factor = 1;
+    cinfo->comp_info[2].v_samp_factor = 1;
+
+    jpeg_start_compress(cinfo.get(), TRUE);
+
+    if (exifOrientation != ExifOrientation::ORIENTATION_UNDEFINED) {
+        std::unique_ptr<ExifUtils> utils(ExifUtils::create());
+        utils->initializeEmpty();
+        utils->setImageWidth(width);
+        utils->setImageHeight(height);
+        utils->setOrientationValue(exifOrientation);
+
+        if (utils->generateApp1()) {
+            const uint8_t* exifBuffer = utils->getApp1Buffer();
+            size_t exifBufferSize = utils->getApp1Length();
+            jpeg_write_marker(cinfo.get(), JPEG_APP0 + 1, static_cast<const JOCTET*>(exifBuffer),
+                    exifBufferSize);
+        } else {
+            ALOGE("%s: Unable to generate App1 buffer", __FUNCTION__);
+        }
+    }
+
+    for (size_t i = 0; i < cinfo->image_height; i++) {
+        auto currentRow  = static_cast<JSAMPROW>(in + i*width);
+        jpeg_write_scanlines(cinfo.get(), &currentRow, /*num_lines*/1);
+    }
+
+    jpeg_finish_compress(cinfo.get());
+
+    actualSize = dmgr.mEncodedSize;
+    if (dmgr.mSuccess) {
+        ret = NO_ERROR;
+    } else {
+        ret = UNKNOWN_ERROR;
+    }
+
+    return ret;
+}
+
+inline void unpackDepth16(uint16_t value, std::vector<float> *points /*out*/,
+        std::vector<float> *confidence /*out*/, float *near /*out*/, float *far /*out*/) {
+    // Android densely packed depth map. The units for the range are in
+    // millimeters and need to be scaled to meters.
+    // The confidence value is encoded in the 3 most significant bits.
+    // The confidence data needs to be additionally normalized with
+    // values 1.0f, 0.0f representing maximum and minimum confidence
+    // respectively.
+    auto point = static_cast<float>(value & 0x1FFF) / 1000.f;
+    points->push_back(point);
+
+    auto conf = (value >> 13) & 0x7;
+    float normConfidence = (conf == 0) ? 1.f : (static_cast<float>(conf) - 1) / 7.f;
+    confidence->push_back(normConfidence);
+    if (normConfidence < CONFIDENCE_THRESHOLD) {
+        return;
+    }
+
+    if (*near > point) {
+        *near = point;
+    }
+    if (*far < point) {
+        *far = point;
+    }
+}
+
+// Trivial case, read forward from top,left corner.
+void rotate0AndUnpack(DepthPhotoInputFrame inputFrame, std::vector<float> *points /*out*/,
+        std::vector<float> *confidence /*out*/, float *near /*out*/, float *far /*out*/) {
+    for (size_t i = 0; i < inputFrame.mDepthMapHeight; i++) {
+        for (size_t j = 0; j < inputFrame.mDepthMapWidth; j++) {
+            unpackDepth16(inputFrame.mDepthMapBuffer[i*inputFrame.mDepthMapStride + j], points,
+                    confidence, near, far);
+        }
+    }
+}
+
+// 90 degrees CW rotation can be applied by starting to read from bottom, left corner
+// transposing rows and columns.
+void rotate90AndUnpack(DepthPhotoInputFrame inputFrame, std::vector<float> *points /*out*/,
+        std::vector<float> *confidence /*out*/, float *near /*out*/, float *far /*out*/) {
+    for (size_t i = 0; i < inputFrame.mDepthMapWidth; i++) {
+        for (ssize_t j = inputFrame.mDepthMapHeight-1; j >= 0; j--) {
+            unpackDepth16(inputFrame.mDepthMapBuffer[j*inputFrame.mDepthMapStride + i], points,
+                    confidence, near, far);
+        }
+    }
+}
+
+// 180 CW degrees rotation can be applied by starting to read backwards from bottom, right corner.
+void rotate180AndUnpack(DepthPhotoInputFrame inputFrame, std::vector<float> *points /*out*/,
+        std::vector<float> *confidence /*out*/, float *near /*out*/, float *far /*out*/) {
+    for (ssize_t i = inputFrame.mDepthMapHeight-1; i >= 0; i--) {
+        for (ssize_t j = inputFrame.mDepthMapWidth-1; j >= 0; j--) {
+            unpackDepth16(inputFrame.mDepthMapBuffer[i*inputFrame.mDepthMapStride + j], points,
+                    confidence, near, far);
+        }
+    }
+}
+
+// 270 degrees CW rotation can be applied by starting to read from top, right corner
+// transposing rows and columns.
+void rotate270AndUnpack(DepthPhotoInputFrame inputFrame, std::vector<float> *points /*out*/,
+        std::vector<float> *confidence /*out*/, float *near /*out*/, float *far /*out*/) {
+    for (ssize_t i = inputFrame.mDepthMapWidth-1; i >= 0; i--) {
+        for (size_t j = 0; j < inputFrame.mDepthMapHeight; j++) {
+            unpackDepth16(inputFrame.mDepthMapBuffer[j*inputFrame.mDepthMapStride + i], points,
+                    confidence, near, far);
+        }
+    }
+}
+
+bool rotateAndUnpack(DepthPhotoInputFrame inputFrame, std::vector<float> *points /*out*/,
+        std::vector<float> *confidence /*out*/, float *near /*out*/, float *far /*out*/) {
+    switch (inputFrame.mOrientation) {
+        case DepthPhotoOrientation::DEPTH_ORIENTATION_0_DEGREES:
+            rotate0AndUnpack(inputFrame, points, confidence, near, far);
+            return false;
+        case DepthPhotoOrientation::DEPTH_ORIENTATION_90_DEGREES:
+            rotate90AndUnpack(inputFrame, points, confidence, near, far);
+            return true;
+        case DepthPhotoOrientation::DEPTH_ORIENTATION_180_DEGREES:
+            rotate180AndUnpack(inputFrame, points, confidence, near, far);
+            return false;
+        case DepthPhotoOrientation::DEPTH_ORIENTATION_270_DEGREES:
+            rotate270AndUnpack(inputFrame, points, confidence, near, far);
+            return true;
+        default:
+            ALOGE("%s: Unsupported depth photo rotation: %d, default to 0", __FUNCTION__,
+                    inputFrame.mOrientation);
+            rotate0AndUnpack(inputFrame, points, confidence, near, far);
+    }
+
+    return false;
+}
+
+std::unique_ptr<dynamic_depth::DepthMap> processDepthMapFrame(DepthPhotoInputFrame inputFrame,
+        ExifOrientation exifOrientation, std::vector<std::unique_ptr<Item>> *items /*out*/,
+        bool *switchDimensions /*out*/) {
+    if ((items == nullptr) || (switchDimensions == nullptr)) {
+        return nullptr;
+    }
+
+    std::vector<float> points, confidence;
+
+    size_t pointCount = inputFrame.mDepthMapWidth * inputFrame.mDepthMapHeight;
+    points.reserve(pointCount);
+    confidence.reserve(pointCount);
+    float near = UINT16_MAX;
+    float far = .0f;
+    *switchDimensions = false;
+    // Physical rotation of depth and confidence maps may be needed in case
+    // the EXIF orientation is set to 0 degrees and the depth photo orientation
+    // (source color image) has some different value.
+    if (exifOrientation == ExifOrientation::ORIENTATION_0_DEGREES) {
+        *switchDimensions = rotateAndUnpack(inputFrame, &points, &confidence, &near, &far);
+    } else {
+        rotate0AndUnpack(inputFrame, &points, &confidence, &near, &far);
+    }
+
+    size_t width = inputFrame.mDepthMapWidth;
+    size_t height = inputFrame.mDepthMapHeight;
+    if (*switchDimensions) {
+        width = inputFrame.mDepthMapHeight;
+        height = inputFrame.mDepthMapWidth;
+    }
+
+    if (near == far) {
+        ALOGE("%s: Near and far range values must not match!", __FUNCTION__);
+        return nullptr;
+    }
+
+    std::vector<uint8_t> pointsQuantized, confidenceQuantized;
+    pointsQuantized.reserve(pointCount); confidenceQuantized.reserve(pointCount);
+    auto pointIt = points.begin();
+    auto confidenceIt = confidence.begin();
+    while ((pointIt != points.end()) && (confidenceIt != confidence.end())) {
+        auto point = *pointIt;
+        if ((*confidenceIt) < CONFIDENCE_THRESHOLD) {
+            point = std::clamp(point, near, far);
+        }
+        pointsQuantized.push_back(floorf(((far * (point - near)) /
+                (point * (far - near))) * 255.0f));
+        confidenceQuantized.push_back(floorf(*confidenceIt * 255.0f));
+        confidenceIt++; pointIt++;
+    }
+
+    DepthMapParams depthParams(DepthFormat::kRangeInverse, near, far, DepthUnits::kMeters,
+            "android/depthmap");
+    depthParams.confidence_uri = "android/confidencemap";
+    depthParams.mime = "image/jpeg";
+    depthParams.depth_image_data.resize(inputFrame.mMaxJpegSize);
+    depthParams.confidence_data.resize(inputFrame.mMaxJpegSize);
+    size_t actualJpegSize;
+    auto ret = encodeGrayscaleJpeg(width, height, pointsQuantized.data(),
+            depthParams.depth_image_data.data(), inputFrame.mMaxJpegSize,
+            inputFrame.mJpegQuality, exifOrientation, actualJpegSize);
+    if (ret != NO_ERROR) {
+        ALOGE("%s: Depth map compression failed!", __FUNCTION__);
+        return nullptr;
+    }
+    depthParams.depth_image_data.resize(actualJpegSize);
+
+    ret = encodeGrayscaleJpeg(width, height, confidenceQuantized.data(),
+            depthParams.confidence_data.data(), inputFrame.mMaxJpegSize,
+            inputFrame.mJpegQuality, exifOrientation, actualJpegSize);
+    if (ret != NO_ERROR) {
+        ALOGE("%s: Confidence map compression failed!", __FUNCTION__);
+        return nullptr;
+    }
+    depthParams.confidence_data.resize(actualJpegSize);
+
+    return DepthMap::FromData(depthParams, items);
+}
+
+extern "C" int processDepthPhotoFrame(DepthPhotoInputFrame inputFrame, size_t depthPhotoBufferSize,
+        void* depthPhotoBuffer /*out*/, size_t* depthPhotoActualSize /*out*/) {
+    if ((inputFrame.mMainJpegBuffer == nullptr) || (inputFrame.mDepthMapBuffer == nullptr) ||
+            (depthPhotoBuffer == nullptr) || (depthPhotoActualSize == nullptr)) {
+        return BAD_VALUE;
+    }
+
+    std::vector<std::unique_ptr<Item>> items;
+    std::vector<std::unique_ptr<Camera>> cameraList;
+    auto image = Image::FromDataForPrimaryImage("android/mainimage", &items);
+    std::unique_ptr<CameraParams> cameraParams(new CameraParams(std::move(image)));
+    if (cameraParams == nullptr) {
+        ALOGE("%s: Failed to initialize camera parameters", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    ExifOrientation exifOrientation = getExifOrientation(
+            reinterpret_cast<const unsigned char*> (inputFrame.mMainJpegBuffer),
+            inputFrame.mMainJpegSize);
+    bool switchDimensions;
+    cameraParams->depth_map = processDepthMapFrame(inputFrame, exifOrientation, &items,
+            &switchDimensions);
+    if (cameraParams->depth_map == nullptr) {
+        ALOGE("%s: Depth map processing failed!", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    // It is not possible to generate an imaging model without intrinsic calibration.
+    if (inputFrame.mIsIntrinsicCalibrationValid) {
+        // The camera intrinsic calibration layout is as follows:
+        // [focalLengthX, focalLengthY, opticalCenterX, opticalCenterY, skew]
+        const dynamic_depth::Point<double> focalLength(inputFrame.mIntrinsicCalibration[0],
+                inputFrame.mIntrinsicCalibration[1]);
+        size_t width = inputFrame.mMainJpegWidth;
+        size_t height = inputFrame.mMainJpegHeight;
+        if (switchDimensions) {
+            width = inputFrame.mMainJpegHeight;
+            height = inputFrame.mMainJpegWidth;
+        }
+        const Dimension imageSize(width, height);
+        ImagingModelParams imagingParams(focalLength, imageSize);
+        imagingParams.principal_point.x = inputFrame.mIntrinsicCalibration[2];
+        imagingParams.principal_point.y = inputFrame.mIntrinsicCalibration[3];
+        imagingParams.skew = inputFrame.mIntrinsicCalibration[4];
+
+        // The camera lens distortion contains the following lens correction coefficients.
+        // [kappa_1, kappa_2, kappa_3 kappa_4, kappa_5]
+        if (inputFrame.mIsLensDistortionValid) {
+            // According to specification the lens distortion coefficients should be ordered
+            // as [1, kappa_4, kappa_1, kappa_5, kappa_2, 0, kappa_3, 0]
+            float distortionData[] = {1.f, inputFrame.mLensDistortion[3],
+                    inputFrame.mLensDistortion[0], inputFrame.mLensDistortion[4],
+                    inputFrame.mLensDistortion[1], 0.f, inputFrame.mLensDistortion[2], 0.f};
+            auto distortionDataLength = sizeof(distortionData) / sizeof(distortionData[0]);
+            imagingParams.distortion.reserve(distortionDataLength);
+            imagingParams.distortion.insert(imagingParams.distortion.end(), distortionData,
+                    distortionData + distortionDataLength);
+        }
+
+        cameraParams->imaging_model = ImagingModel::FromData(imagingParams);
+    }
+
+    if (inputFrame.mIsLogical) {
+        cameraParams->trait = dynamic_depth::CameraTrait::LOGICAL;
+    } else {
+        cameraParams->trait = dynamic_depth::CameraTrait::PHYSICAL;
+    }
+
+    cameraList.emplace_back(Camera::FromData(std::move(cameraParams)));
+
+    auto deviceParams = std::make_unique<DeviceParams> (Cameras::FromCameraArray(&cameraList));
+    deviceParams->container = Container::FromItems(&items);
+    std::vector<std::unique_ptr<Profile>> profileList;
+    profileList.emplace_back(Profile::FromData("DepthPhoto", {0}));
+    deviceParams->profiles = Profiles::FromProfileArray(&profileList);
+    std::unique_ptr<Device> device = Device::FromData(std::move(deviceParams));
+    if (device == nullptr) {
+        ALOGE("%s: Failed to initialize camera device", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    std::istringstream inputJpegStream(
+            std::string(inputFrame.mMainJpegBuffer, inputFrame.mMainJpegSize));
+    std::ostringstream outputJpegStream;
+    if (!WriteImageAndMetadataAndContainer(&inputJpegStream, device.get(), &outputJpegStream)) {
+        ALOGE("%s: Failed writing depth output", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    *depthPhotoActualSize = static_cast<size_t> (outputJpegStream.tellp());
+    if (*depthPhotoActualSize > depthPhotoBufferSize) {
+        ALOGE("%s: Depth photo output buffer not sufficient, needed %zu actual %zu", __FUNCTION__,
+                *depthPhotoActualSize, depthPhotoBufferSize);
+        return NO_MEMORY;
+    }
+
+    memcpy(depthPhotoBuffer, outputJpegStream.str().c_str(), *depthPhotoActualSize);
+
+    return 0;
+}
+
+}; // namespace camera3
+}; // namespace android
diff --git a/services/camera/libcameraservice/common/DepthPhotoProcessor.h b/services/camera/libcameraservice/common/DepthPhotoProcessor.h
new file mode 100644
index 0000000..ba5ca9e
--- /dev/null
+++ b/services/camera/libcameraservice/common/DepthPhotoProcessor.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SERVERS_CAMERA_CAMERA3_DEPTH_PROCESSOR_H
+#define ANDROID_SERVERS_CAMERA_CAMERA3_DEPTH_PROCESSOR_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace android {
+namespace camera3 {
+
+enum DepthPhotoOrientation {
+    DEPTH_ORIENTATION_0_DEGREES   = 0,
+    DEPTH_ORIENTATION_90_DEGREES  = 90,
+    DEPTH_ORIENTATION_180_DEGREES = 180,
+    DEPTH_ORIENTATION_270_DEGREES = 270,
+};
+
+struct DepthPhotoInputFrame {
+    const char*           mMainJpegBuffer;
+    size_t                mMainJpegSize;
+    size_t                mMainJpegWidth, mMainJpegHeight;
+    uint16_t*             mDepthMapBuffer;
+    size_t                mDepthMapWidth, mDepthMapHeight, mDepthMapStride;
+    size_t                mMaxJpegSize;
+    uint8_t               mJpegQuality;
+    uint8_t               mIsLogical;
+    float                 mIntrinsicCalibration[5];
+    uint8_t               mIsIntrinsicCalibrationValid;
+    float                 mLensDistortion[5];
+    uint8_t               mIsLensDistortionValid;
+    DepthPhotoOrientation mOrientation;
+
+    DepthPhotoInputFrame() :
+            mMainJpegBuffer(nullptr),
+            mMainJpegSize(0),
+            mMainJpegWidth(0),
+            mMainJpegHeight(0),
+            mDepthMapBuffer(nullptr),
+            mDepthMapWidth(0),
+            mDepthMapHeight(0),
+            mDepthMapStride(0),
+            mMaxJpegSize(0),
+            mJpegQuality(100),
+            mIsLogical(0),
+            mIntrinsicCalibration{0.f},
+            mIsIntrinsicCalibrationValid(0),
+            mLensDistortion{0.f},
+            mIsLensDistortionValid(0),
+            mOrientation(DepthPhotoOrientation::DEPTH_ORIENTATION_0_DEGREES) {}
+};
+
+static const char *kDepthPhotoLibrary = "libdepthphoto.so";
+static const char *kDepthPhotoProcessFunction = "processDepthPhotoFrame";
+typedef int (*process_depth_photo_frame) (DepthPhotoInputFrame /*inputFrame*/,
+        size_t /*depthPhotoBufferSize*/, void* /*depthPhotoBuffer out*/,
+        size_t* /*depthPhotoActualSize out*/);
+
+}; // namespace camera3
+}; // namespace android
+
+#endif
diff --git a/services/camera/libcameraservice/common/FrameProcessorBase.cpp b/services/camera/libcameraservice/common/FrameProcessorBase.cpp
index 41c953b..3d56cd2 100644
--- a/services/camera/libcameraservice/common/FrameProcessorBase.cpp
+++ b/services/camera/libcameraservice/common/FrameProcessorBase.cpp
@@ -89,12 +89,27 @@
     write(fd, result.string(), result.size());
 
     CameraMetadata lastFrame;
+    std::map<std::string, CameraMetadata> lastPhysicalFrames;
     {
         // Don't race while dumping metadata
         Mutex::Autolock al(mLastFrameMutex);
         lastFrame = CameraMetadata(mLastFrame);
+
+        for (const auto& physicalFrame : mLastPhysicalFrames) {
+            lastPhysicalFrames.emplace(String8(physicalFrame.mPhysicalCameraId),
+                    physicalFrame.mPhysicalCameraMetadata);
+        }
     }
-    lastFrame.dump(fd, 2, 6);
+    lastFrame.dump(fd, /*verbosity*/2, /*indentation*/6);
+
+    for (const auto& physicalFrame : lastPhysicalFrames) {
+        result = String8::format("   Latest received frame for physical camera %s:\n",
+                physicalFrame.first.c_str());
+        write(fd, result.string(), result.size());
+        CameraMetadata lastPhysicalMetadata = CameraMetadata(physicalFrame.second);
+        lastPhysicalMetadata.sort();
+        lastPhysicalMetadata.dump(fd, /*verbosity*/2, /*indentation*/6);
+    }
 }
 
 bool FrameProcessorBase::threadLoop() {
@@ -145,6 +160,8 @@
         if (!result.mMetadata.isEmpty()) {
             Mutex::Autolock al(mLastFrameMutex);
             mLastFrame.acquire(result.mMetadata);
+
+            mLastPhysicalFrames = std::move(result.mPhysicalMetadatas);
         }
     }
     if (res != NOT_ENOUGH_DATA) {
diff --git a/services/camera/libcameraservice/common/FrameProcessorBase.h b/services/camera/libcameraservice/common/FrameProcessorBase.h
index 00763a4..ae6d15d 100644
--- a/services/camera/libcameraservice/common/FrameProcessorBase.h
+++ b/services/camera/libcameraservice/common/FrameProcessorBase.h
@@ -83,6 +83,8 @@
                               const sp<CameraDeviceBase> &device);
 
     CameraMetadata mLastFrame;
+    std::vector<PhysicalCaptureResultInfo> mLastPhysicalFrames;
+
 };
 
 
diff --git a/services/camera/libcameraservice/device3/Camera3BufferManager.cpp b/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
index 8c8b97a..d6bf83e 100644
--- a/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
+++ b/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
@@ -237,7 +237,7 @@
 }
 
 status_t Camera3BufferManager::getBufferForStream(int streamId, int streamSetId,
-        sp<GraphicBuffer>* gb, int* fenceFd) {
+        sp<GraphicBuffer>* gb, int* fenceFd, bool noFreeBufferAtConsumer) {
     ATRACE_CALL();
 
     Mutex::Autolock l(mLock);
@@ -253,14 +253,19 @@
     StreamSet &streamSet = mStreamSetMap.editValueFor(streamSetId);
     BufferCountMap& handOutBufferCounts = streamSet.handoutBufferCountMap;
     size_t& bufferCount = handOutBufferCounts.editValueFor(streamId);
+    BufferCountMap& attachedBufferCounts = streamSet.attachedBufferCountMap;
+    size_t& attachedBufferCount = attachedBufferCounts.editValueFor(streamId);
+
+    if (noFreeBufferAtConsumer) {
+        attachedBufferCount = bufferCount;
+    }
+
     if (bufferCount >= streamSet.maxAllowedBufferCount) {
         ALOGE("%s: bufferCount (%zu) exceeds the max allowed buffer count (%zu) of this stream set",
                 __FUNCTION__, bufferCount, streamSet.maxAllowedBufferCount);
         return INVALID_OPERATION;
     }
 
-    BufferCountMap& attachedBufferCounts = streamSet.attachedBufferCountMap;
-    size_t& attachedBufferCount = attachedBufferCounts.editValueFor(streamId);
     if (attachedBufferCount > bufferCount) {
         // We've already attached more buffers to this stream than we currently have
         // outstanding, so have the stream just use an already-attached buffer
diff --git a/services/camera/libcameraservice/device3/Camera3BufferManager.h b/services/camera/libcameraservice/device3/Camera3BufferManager.h
index 025062e..f0de1c1 100644
--- a/services/camera/libcameraservice/device3/Camera3BufferManager.h
+++ b/services/camera/libcameraservice/device3/Camera3BufferManager.h
@@ -112,6 +112,10 @@
      *
      * After this call, the client takes over the ownership of this buffer if it is not freed.
      *
+     * Sometimes free buffers are discarded from consumer side and the dequeueBuffer call returns
+     * TIMED_OUT, in this case calling getBufferForStream again with noFreeBufferAtConsumer set to
+     * true will notify buffer manager to update its states and also tries to allocate a new buffer.
+     *
      * Return values:
      *
      *  OK:        Getting buffer for this stream was successful.
@@ -122,7 +126,9 @@
      *             to this buffer manager before.
      *  NO_MEMORY: Unable to allocate a buffer for this stream at this time.
      */
-    status_t getBufferForStream(int streamId, int streamSetId, sp<GraphicBuffer>* gb, int* fenceFd);
+    status_t getBufferForStream(
+            int streamId, int streamSetId, sp<GraphicBuffer>* gb, int* fenceFd,
+            bool noFreeBufferAtConsumer = false);
 
     /**
      * This method notifies the manager that a buffer has been released by the consumer.
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index fb81b88..e347127 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -56,6 +56,9 @@
 #include "device3/Camera3DummyStream.h"
 #include "device3/Camera3SharedOutputStream.h"
 #include "CameraService.h"
+#include "utils/CameraThreadState.h"
+
+#include <tuple>
 
 using namespace android::camera3;
 using namespace android::hardware::camera;
@@ -74,15 +77,16 @@
         mTimestampOffset(0),
         mNextResultFrameNumber(0),
         mNextReprocessResultFrameNumber(0),
+        mNextZslStillResultFrameNumber(0),
         mNextShutterFrameNumber(0),
         mNextReprocessShutterFrameNumber(0),
+        mNextZslStillShutterFrameNumber(0),
         mListener(NULL),
         mVendorTagId(CAMERA_METADATA_INVALID_VENDOR_ID),
-        mLastTemplateId(-1)
+        mLastTemplateId(-1),
+        mNeedFixupMonochromeTags(false)
 {
     ATRACE_CALL();
-    camera3_callback_ops::notify = &sNotify;
-    camera3_callback_ops::process_capture_result = &sProcessCaptureResult;
     ALOGV("%s: Created device for camera %s", __FUNCTION__, mId.string());
 }
 
@@ -90,7 +94,7 @@
 {
     ATRACE_CALL();
     ALOGV("%s: Tearing down for camera id %s", __FUNCTION__, mId.string());
-    disconnect();
+    disconnectImpl();
 }
 
 const String8& Camera3Device::getId() const {
@@ -121,11 +125,36 @@
 
     res = manager->getCameraCharacteristics(mId.string(), &mDeviceInfo);
     if (res != OK) {
-        SET_ERR_L("Could not retrive camera characteristics: %s (%d)", strerror(-res), res);
+        SET_ERR_L("Could not retrieve camera characteristics: %s (%d)", strerror(-res), res);
         session->close();
         return res;
     }
 
+    std::vector<std::string> physicalCameraIds;
+    bool isLogical = manager->isLogicalCamera(mId.string(), &physicalCameraIds);
+    if (isLogical) {
+        for (auto& physicalId : physicalCameraIds) {
+            res = manager->getCameraCharacteristics(
+                    physicalId, &mPhysicalDeviceInfoMap[physicalId]);
+            if (res != OK) {
+                SET_ERR_L("Could not retrieve camera %s characteristics: %s (%d)",
+                        physicalId.c_str(), strerror(-res), res);
+                session->close();
+                return res;
+            }
+
+            if (DistortionMapper::isDistortionSupported(mPhysicalDeviceInfoMap[physicalId])) {
+                mDistortionMappers[physicalId].setupStaticInfo(mPhysicalDeviceInfoMap[physicalId]);
+                if (res != OK) {
+                    SET_ERR_L("Unable to read camera %s's calibration fields for distortion "
+                            "correction", physicalId.c_str());
+                    session->close();
+                    return res;
+                }
+            }
+        }
+    }
+
     std::shared_ptr<RequestMetadataQueue> queue;
     auto requestQueueRet = session->getCaptureRequestMetadataQueue(
         [&queue](const auto& descriptor) {
@@ -161,13 +190,20 @@
         session->interfaceChain([](
             ::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) {
                 ALOGV("Session interface chain:");
-                for (auto iface : interfaceChain) {
+                for (const auto& iface : interfaceChain) {
                     ALOGV("  %s", iface.c_str());
                 }
             });
     }
 
-    mInterface = new HalInterface(session, queue);
+    camera_metadata_entry bufMgrMode =
+            mDeviceInfo.find(ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION);
+    if (bufMgrMode.count > 0) {
+         mUseHalBufManager = (bufMgrMode.data.u8[0] ==
+            ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
+    }
+
+    mInterface = new HalInterface(session, queue, mUseHalBufManager);
     std::string providerType;
     mVendorTagId = manager->getProviderTagIdLocked(mId.string());
     mTagMonitor.initialize(mVendorTagId);
@@ -175,6 +211,28 @@
         mTagMonitor.parseTagsToMonitor(String8(monitorTags));
     }
 
+    // Metadata tags needs fixup for monochrome camera device version less
+    // than 3.5.
+    hardware::hidl_version maxVersion{0,0};
+    res = manager->getHighestSupportedVersion(mId.string(), &maxVersion);
+    if (res != OK) {
+        ALOGE("%s: Error in getting camera device version id: %s (%d)",
+                __FUNCTION__, strerror(-res), res);
+        return res;
+    }
+    int deviceVersion = HARDWARE_DEVICE_API_VERSION(
+            maxVersion.get_major(), maxVersion.get_minor());
+
+    bool isMonochrome = false;
+    camera_metadata_entry_t entry = mDeviceInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
+    for (size_t i = 0; i < entry.count; i++) {
+        uint8_t capability = entry.data.u8[i];
+        if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME) {
+            isMonochrome = true;
+        }
+    }
+    mNeedFixupMonochromeTags = (isMonochrome && deviceVersion < CAMERA_DEVICE_API_VERSION_3_5);
+
     return initializeCommonLocked();
 }
 
@@ -194,6 +252,17 @@
     /** Register in-flight map to the status tracker */
     mInFlightStatusId = mStatusTracker->addComponent();
 
+    if (mUseHalBufManager) {
+        res = mRequestBufferSM.initialize(mStatusTracker);
+        if (res != OK) {
+            SET_ERR_L("Unable to start request buffer state machine: %s (%d)",
+                    strerror(-res), res);
+            mInterface->close();
+            mStatusTracker.clear();
+            return res;
+        }
+    }
+
     /** Create buffer manager */
     mBufferManager = new Camera3BufferManager();
 
@@ -203,8 +272,10 @@
     if (sessionKeysEntry.count > 0) {
         sessionParamKeys.insertArrayAt(sessionKeysEntry.data.i32, 0, sessionKeysEntry.count);
     }
+
     /** Start up request queue thread */
-    mRequestThread = new RequestThread(this, mStatusTracker, mInterface, sessionParamKeys);
+    mRequestThread = new RequestThread(
+            this, mStatusTracker, mInterface, sessionParamKeys, mUseHalBufManager);
     res = mRequestThread->run(String8::format("C3Dev-%s-ReqQueue", mId.string()).string());
     if (res != OK) {
         SET_ERR_L("Unable to start request queue thread: %s (%d)",
@@ -250,17 +321,20 @@
     }
 
     if (DistortionMapper::isDistortionSupported(mDeviceInfo)) {
-        res = mDistortionMapper.setupStaticInfo(mDeviceInfo);
+        res = mDistortionMappers[mId.c_str()].setupStaticInfo(mDeviceInfo);
         if (res != OK) {
             SET_ERR_L("Unable to read necessary calibration fields for distortion correction");
             return res;
         }
     }
-
     return OK;
 }
 
 status_t Camera3Device::disconnect() {
+    return disconnectImpl();
+}
+
+status_t Camera3Device::disconnectImpl() {
     ATRACE_CALL();
     Mutex::Autolock il(mInterfaceLock);
 
@@ -327,6 +401,7 @@
     {
         Mutex::Autolock l(mLock);
         mRequestThread.clear();
+        Mutex::Autolock stLock(mTrackerLock);
         mStatusTracker.clear();
         interface = mInterface.get();
     }
@@ -719,7 +794,7 @@
     return OK;
 }
 
-const CameraMetadata& Camera3Device::info() const {
+const CameraMetadata& Camera3Device::info(const String8& physicalId) const {
     ALOGVV("%s: E", __FUNCTION__);
     if (CC_UNLIKELY(mStatus == STATUS_UNINITIALIZED ||
                     mStatus == STATUS_ERROR)) {
@@ -727,7 +802,22 @@
                 mStatus == STATUS_ERROR ?
                 "when in error state" : "before init");
     }
-    return mDeviceInfo;
+    if (physicalId.isEmpty()) {
+        return mDeviceInfo;
+    } else {
+        std::string id(physicalId.c_str());
+        if (mPhysicalDeviceInfoMap.find(id) != mPhysicalDeviceInfoMap.end()) {
+            return mPhysicalDeviceInfoMap.at(id);
+        } else {
+            ALOGE("%s: Invalid physical camera id %s", __FUNCTION__, physicalId.c_str());
+            return mDeviceInfo;
+        }
+    }
+}
+
+const CameraMetadata& Camera3Device::info() const {
+    String8 emptyId;
+    return info(emptyId);
 }
 
 status_t Camera3Device::checkStatusOkToCaptureLocked() {
@@ -810,14 +900,14 @@
     return OK;
 }
 
-status_t Camera3Device::capture(CameraMetadata &request, int64_t* /*lastFrameNumber*/) {
+status_t Camera3Device::capture(CameraMetadata &request, int64_t* lastFrameNumber) {
     ATRACE_CALL();
 
     List<const PhysicalCameraSettingsList> requestsList;
     std::list<const SurfaceMap> surfaceMaps;
     convertToRequestList(requestsList, surfaceMaps, request);
 
-    return captureList(requestsList, surfaceMaps, /*lastFrameNumber*/NULL);
+    return captureList(requestsList, surfaceMaps, lastFrameNumber);
 }
 
 void Camera3Device::convertToRequestList(List<const PhysicalCameraSettingsList>& requestsList,
@@ -884,6 +974,236 @@
     return res;
 }
 
+hardware::Return<void> Camera3Device::requestStreamBuffers(
+        const hardware::hidl_vec<hardware::camera::device::V3_5::BufferRequest>& bufReqs,
+        requestStreamBuffers_cb _hidl_cb) {
+    using hardware::camera::device::V3_5::BufferRequestStatus;
+    using hardware::camera::device::V3_5::StreamBufferRet;
+    using hardware::camera::device::V3_5::StreamBufferRequestError;
+
+    std::lock_guard<std::mutex> lock(mRequestBufferInterfaceLock);
+
+    hardware::hidl_vec<StreamBufferRet> bufRets;
+    if (!mUseHalBufManager) {
+        ALOGE("%s: Camera %s does not support HAL buffer management",
+                __FUNCTION__, mId.string());
+        _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, bufRets);
+        return hardware::Void();
+    }
+
+    SortedVector<int32_t> streamIds;
+    ssize_t sz = streamIds.setCapacity(bufReqs.size());
+    if (sz < 0 || static_cast<size_t>(sz) != bufReqs.size()) {
+        ALOGE("%s: failed to allocate memory for %zu buffer requests",
+                __FUNCTION__, bufReqs.size());
+        _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, bufRets);
+        return hardware::Void();
+    }
+
+    if (bufReqs.size() > mOutputStreams.size()) {
+        ALOGE("%s: too many buffer requests (%zu > # of output streams %zu)",
+                __FUNCTION__, bufReqs.size(), mOutputStreams.size());
+        _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, bufRets);
+        return hardware::Void();
+    }
+
+    // Check for repeated streamId
+    for (const auto& bufReq : bufReqs) {
+        if (streamIds.indexOf(bufReq.streamId) != NAME_NOT_FOUND) {
+            ALOGE("%s: Stream %d appear multiple times in buffer requests",
+                    __FUNCTION__, bufReq.streamId);
+            _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, bufRets);
+            return hardware::Void();
+        }
+        streamIds.add(bufReq.streamId);
+    }
+
+    if (!mRequestBufferSM.startRequestBuffer()) {
+        ALOGE("%s: request buffer disallowed while camera service is configuring",
+                __FUNCTION__);
+        _hidl_cb(BufferRequestStatus::FAILED_CONFIGURING, bufRets);
+        return hardware::Void();
+    }
+
+    bufRets.resize(bufReqs.size());
+
+    bool allReqsSucceeds = true;
+    bool oneReqSucceeds = false;
+    for (size_t i = 0; i < bufReqs.size(); i++) {
+        const auto& bufReq = bufReqs[i];
+        auto& bufRet = bufRets[i];
+        int32_t streamId = bufReq.streamId;
+        sp<Camera3OutputStreamInterface> outputStream = mOutputStreams.get(streamId);
+        if (outputStream == nullptr) {
+            ALOGE("%s: Output stream id %d not found!", __FUNCTION__, streamId);
+            hardware::hidl_vec<StreamBufferRet> emptyBufRets;
+            _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, emptyBufRets);
+            mRequestBufferSM.endRequestBuffer();
+            return hardware::Void();
+        }
+
+        if (outputStream->isAbandoned()) {
+            bufRet.val.error(StreamBufferRequestError::STREAM_DISCONNECTED);
+            allReqsSucceeds = false;
+            continue;
+        }
+
+        bufRet.streamId = streamId;
+        size_t handOutBufferCount = outputStream->getOutstandingBuffersCount();
+        uint32_t numBuffersRequested = bufReq.numBuffersRequested;
+        size_t totalHandout = handOutBufferCount + numBuffersRequested;
+        uint32_t maxBuffers = outputStream->asHalStream()->max_buffers;
+        if (totalHandout > maxBuffers) {
+            // Not able to allocate enough buffer. Exit early for this stream
+            ALOGE("%s: request too much buffers for stream %d: at HAL: %zu + requesting: %d"
+                    " > max: %d", __FUNCTION__, streamId, handOutBufferCount,
+                    numBuffersRequested, maxBuffers);
+            bufRet.val.error(StreamBufferRequestError::MAX_BUFFER_EXCEEDED);
+            allReqsSucceeds = false;
+            continue;
+        }
+
+        hardware::hidl_vec<StreamBuffer> tmpRetBuffers(numBuffersRequested);
+        bool currentReqSucceeds = true;
+        std::vector<camera3_stream_buffer_t> streamBuffers(numBuffersRequested);
+        size_t numAllocatedBuffers = 0;
+        size_t numPushedInflightBuffers = 0;
+        for (size_t b = 0; b < numBuffersRequested; b++) {
+            camera3_stream_buffer_t& sb = streamBuffers[b];
+            // Since this method can run concurrently with request thread
+            // We need to update the wait duration everytime we call getbuffer
+            nsecs_t waitDuration = kBaseGetBufferWait + getExpectedInFlightDuration();
+            status_t res = outputStream->getBuffer(&sb, waitDuration);
+            if (res != OK) {
+                if (res == NO_INIT || res == DEAD_OBJECT) {
+                    ALOGV("%s: Can't get output buffer for stream %d: %s (%d)",
+                            __FUNCTION__, streamId, strerror(-res), res);
+                    bufRet.val.error(StreamBufferRequestError::STREAM_DISCONNECTED);
+                } else {
+                    ALOGE("%s: Can't get output buffer for stream %d: %s (%d)",
+                            __FUNCTION__, streamId, strerror(-res), res);
+                    if (res == TIMED_OUT || res == NO_MEMORY) {
+                        bufRet.val.error(StreamBufferRequestError::NO_BUFFER_AVAILABLE);
+                    } else {
+                        bufRet.val.error(StreamBufferRequestError::UNKNOWN_ERROR);
+                    }
+                }
+                currentReqSucceeds = false;
+                break;
+            }
+            numAllocatedBuffers++;
+
+            buffer_handle_t *buffer = sb.buffer;
+            auto pair = mInterface->getBufferId(*buffer, streamId);
+            bool isNewBuffer = pair.first;
+            uint64_t bufferId = pair.second;
+            StreamBuffer& hBuf = tmpRetBuffers[b];
+
+            hBuf.streamId = streamId;
+            hBuf.bufferId = bufferId;
+            hBuf.buffer = (isNewBuffer) ? *buffer : nullptr;
+            hBuf.status = BufferStatus::OK;
+            hBuf.releaseFence = nullptr;
+
+            native_handle_t *acquireFence = nullptr;
+            if (sb.acquire_fence != -1) {
+                acquireFence = native_handle_create(1,0);
+                acquireFence->data[0] = sb.acquire_fence;
+            }
+            hBuf.acquireFence.setTo(acquireFence, /*shouldOwn*/true);
+            hBuf.releaseFence = nullptr;
+
+            res = mInterface->pushInflightRequestBuffer(bufferId, buffer, streamId);
+            if (res != OK) {
+                ALOGE("%s: Can't get register request buffers for stream %d: %s (%d)",
+                        __FUNCTION__, streamId, strerror(-res), res);
+                bufRet.val.error(StreamBufferRequestError::UNKNOWN_ERROR);
+                currentReqSucceeds = false;
+                break;
+            }
+            numPushedInflightBuffers++;
+        }
+        if (currentReqSucceeds) {
+            bufRet.val.buffers(std::move(tmpRetBuffers));
+            oneReqSucceeds = true;
+        } else {
+            allReqsSucceeds = false;
+            for (size_t b = 0; b < numPushedInflightBuffers; b++) {
+                StreamBuffer& hBuf = tmpRetBuffers[b];
+                buffer_handle_t* buffer;
+                status_t res = mInterface->popInflightRequestBuffer(hBuf.bufferId, &buffer);
+                if (res != OK) {
+                    SET_ERR("%s: popInflightRequestBuffer failed for stream %d: %s (%d)",
+                            __FUNCTION__, streamId, strerror(-res), res);
+                }
+            }
+            for (size_t b = 0; b < numAllocatedBuffers; b++) {
+                camera3_stream_buffer_t& sb = streamBuffers[b];
+                sb.acquire_fence = -1;
+                sb.status = CAMERA3_BUFFER_STATUS_ERROR;
+            }
+            returnOutputBuffers(streamBuffers.data(), numAllocatedBuffers, 0);
+        }
+    }
+
+    _hidl_cb(allReqsSucceeds ? BufferRequestStatus::OK :
+            oneReqSucceeds ? BufferRequestStatus::FAILED_PARTIAL :
+                             BufferRequestStatus::FAILED_UNKNOWN,
+            bufRets);
+    mRequestBufferSM.endRequestBuffer();
+    return hardware::Void();
+}
+
+hardware::Return<void> Camera3Device::returnStreamBuffers(
+        const hardware::hidl_vec<hardware::camera::device::V3_2::StreamBuffer>& buffers) {
+    if (!mUseHalBufManager) {
+        ALOGE("%s: Camera %s does not support HAL buffer managerment",
+                __FUNCTION__, mId.string());
+        return hardware::Void();
+    }
+
+    for (const auto& buf : buffers) {
+        if (buf.bufferId == HalInterface::BUFFER_ID_NO_BUFFER) {
+            ALOGE("%s: cannot return a buffer without bufferId", __FUNCTION__);
+            continue;
+        }
+
+        buffer_handle_t* buffer;
+        status_t res = mInterface->popInflightRequestBuffer(buf.bufferId, &buffer);
+
+        if (res != OK) {
+            ALOGE("%s: cannot find in-flight buffer %" PRIu64 " for stream %d",
+                    __FUNCTION__, buf.bufferId, buf.streamId);
+            continue;
+        }
+
+        camera3_stream_buffer_t streamBuffer;
+        streamBuffer.buffer = buffer;
+        streamBuffer.status = CAMERA3_BUFFER_STATUS_ERROR;
+        streamBuffer.acquire_fence = -1;
+        streamBuffer.release_fence = -1;
+
+        if (buf.releaseFence == nullptr) {
+            streamBuffer.release_fence = -1;
+        } else if (buf.releaseFence->numFds == 1) {
+            streamBuffer.release_fence = dup(buf.releaseFence->data[0]);
+        } else {
+            ALOGE("%s: Invalid release fence, fd count is %d, not 1",
+                    __FUNCTION__, buf.releaseFence->numFds);
+            continue;
+        }
+
+        sp<Camera3StreamInterface> stream = mOutputStreams.get(buf.streamId);
+        if (stream == nullptr) {
+            ALOGE("%s: Output stream id %d not found!", __FUNCTION__, buf.streamId);
+            continue;
+        }
+        streamBuffer.stream = stream->asHalStream();
+        returnOutputBuffers(&streamBuffer, /*size*/1, /*timestamp*/ 0);
+    }
+    return hardware::Void();
+}
+
 hardware::Return<void> Camera3Device::processCaptureResult_3_4(
         const hardware::hidl_vec<
                 hardware::camera::device::V3_4::CaptureResult>& results) {
@@ -988,7 +1308,7 @@
 void Camera3Device::processOneCaptureResultLocked(
         const hardware::camera::device::V3_2::CaptureResult& result,
         const hardware::hidl_vec<
-                hardware::camera::device::V3_4::PhysicalCameraMetadata> physicalCameraMetadatas) {
+                hardware::camera::device::V3_4::PhysicalCameraMetadata> physicalCameraMetadata) {
     camera3_capture_result r;
     status_t res;
     r.frame_number = result.frameNumber;
@@ -1004,21 +1324,21 @@
     r.result = reinterpret_cast<const camera_metadata_t*>(resultMetadata.data());
 
     // Read and validate physical camera metadata
-    size_t physResultCount = physicalCameraMetadatas.size();
+    size_t physResultCount = physicalCameraMetadata.size();
     std::vector<const char*> physCamIds(physResultCount);
     std::vector<const camera_metadata_t *> phyCamMetadatas(physResultCount);
     std::vector<hardware::camera::device::V3_2::CameraMetadata> physResultMetadata;
     physResultMetadata.resize(physResultCount);
-    for (size_t i = 0; i < physicalCameraMetadatas.size(); i++) {
-        res = readOneCameraMetadataLocked(physicalCameraMetadatas[i].fmqMetadataSize,
-                physResultMetadata[i], physicalCameraMetadatas[i].metadata);
+    for (size_t i = 0; i < physicalCameraMetadata.size(); i++) {
+        res = readOneCameraMetadataLocked(physicalCameraMetadata[i].fmqMetadataSize,
+                physResultMetadata[i], physicalCameraMetadata[i].metadata);
         if (res != OK) {
             ALOGE("%s: Frame %d: Failed to read capture result metadata for camera %s",
                     __FUNCTION__, result.frameNumber,
-                    physicalCameraMetadatas[i].physicalCameraId.c_str());
+                    physicalCameraMetadata[i].physicalCameraId.c_str());
             return;
         }
-        physCamIds[i] = physicalCameraMetadatas[i].physicalCameraId.c_str();
+        physCamIds[i] = physicalCameraMetadata[i].physicalCameraId.c_str();
         phyCamMetadatas[i] = reinterpret_cast<const camera_metadata_t*>(
                 physResultMetadata[i].data());
     }
@@ -1032,27 +1352,51 @@
         auto& bDst = outputBuffers[i];
         const StreamBuffer &bSrc = result.outputBuffers[i];
 
-        ssize_t idx = mOutputStreams.indexOfKey(bSrc.streamId);
-        if (idx == NAME_NOT_FOUND) {
+        sp<Camera3StreamInterface> stream = mOutputStreams.get(bSrc.streamId);
+        if (stream == nullptr) {
             ALOGE("%s: Frame %d: Buffer %zu: Invalid output stream id %d",
                     __FUNCTION__, result.frameNumber, i, bSrc.streamId);
             return;
         }
-        bDst.stream = mOutputStreams.valueAt(idx)->asHalStream();
+        bDst.stream = stream->asHalStream();
 
-        buffer_handle_t *buffer;
-        res = mInterface->popInflightBuffer(result.frameNumber, bSrc.streamId, &buffer);
+        bool noBufferReturned = false;
+        buffer_handle_t *buffer = nullptr;
+        if (mUseHalBufManager) {
+            // This is suspicious most of the time but can be correct during flush where HAL
+            // has to return capture result before a buffer is requested
+            if (bSrc.bufferId == HalInterface::BUFFER_ID_NO_BUFFER) {
+                if (bSrc.status == BufferStatus::OK) {
+                    ALOGE("%s: Frame %d: Buffer %zu: No bufferId for stream %d",
+                            __FUNCTION__, result.frameNumber, i, bSrc.streamId);
+                    // Still proceeds so other buffers can be returned
+                }
+                noBufferReturned = true;
+            }
+            if (noBufferReturned) {
+                res = OK;
+            } else {
+                res = mInterface->popInflightRequestBuffer(bSrc.bufferId, &buffer);
+            }
+        } else {
+            res = mInterface->popInflightBuffer(result.frameNumber, bSrc.streamId, &buffer);
+        }
+
         if (res != OK) {
             ALOGE("%s: Frame %d: Buffer %zu: No in-flight buffer for stream %d",
                     __FUNCTION__, result.frameNumber, i, bSrc.streamId);
             return;
         }
+
         bDst.buffer = buffer;
         bDst.status = mapHidlBufferStatus(bSrc.status);
         bDst.acquire_fence = -1;
         if (bSrc.releaseFence == nullptr) {
             bDst.release_fence = -1;
         } else if (bSrc.releaseFence->numFds == 1) {
+            if (noBufferReturned) {
+                ALOGE("%s: got releaseFence without output buffer!", __FUNCTION__);
+            }
             bDst.release_fence = dup(bSrc.releaseFence->data[0]);
         } else {
             ALOGE("%s: Frame %d: Invalid release fence for buffer %zu, fd count is %d, not 1",
@@ -1128,13 +1472,13 @@
             m.type = CAMERA3_MSG_ERROR;
             m.message.error.frame_number = msg.msg.error.frameNumber;
             if (msg.msg.error.errorStreamId >= 0) {
-                ssize_t idx = mOutputStreams.indexOfKey(msg.msg.error.errorStreamId);
-                if (idx == NAME_NOT_FOUND) {
-                    ALOGE("%s: Frame %d: Invalid error stream id %d",
-                            __FUNCTION__, m.message.error.frame_number, msg.msg.error.errorStreamId);
+                sp<Camera3StreamInterface> stream = mOutputStreams.get(msg.msg.error.errorStreamId);
+                if (stream == nullptr) {
+                    ALOGE("%s: Frame %d: Invalid error stream id %d", __FUNCTION__,
+                            m.message.error.frame_number, msg.msg.error.errorStreamId);
                     return;
                 }
-                m.message.error.error_stream = mOutputStreams.valueAt(idx)->asHalStream();
+                m.message.error.error_stream = stream->asHalStream();
             } else {
                 m.message.error.error_stream = nullptr;
             }
@@ -1315,6 +1659,56 @@
     return OK;
 }
 
+status_t Camera3Device::StreamSet::add(
+        int streamId, sp<camera3::Camera3OutputStreamInterface> stream) {
+    if (stream == nullptr) {
+        ALOGE("%s: cannot add null stream", __FUNCTION__);
+        return BAD_VALUE;
+    }
+    std::lock_guard<std::mutex> lock(mLock);
+    return mData.add(streamId, stream);
+}
+
+ssize_t Camera3Device::StreamSet::remove(int streamId) {
+    std::lock_guard<std::mutex> lock(mLock);
+    return mData.removeItem(streamId);
+}
+
+sp<camera3::Camera3OutputStreamInterface>
+Camera3Device::StreamSet::get(int streamId) {
+    std::lock_guard<std::mutex> lock(mLock);
+    ssize_t idx = mData.indexOfKey(streamId);
+    if (idx == NAME_NOT_FOUND) {
+        return nullptr;
+    }
+    return mData.editValueAt(idx);
+}
+
+sp<camera3::Camera3OutputStreamInterface>
+Camera3Device::StreamSet::operator[] (size_t index) {
+    std::lock_guard<std::mutex> lock(mLock);
+    return mData.editValueAt(index);
+}
+
+size_t Camera3Device::StreamSet::size() const {
+    std::lock_guard<std::mutex> lock(mLock);
+    return mData.size();
+}
+
+void Camera3Device::StreamSet::clear() {
+    std::lock_guard<std::mutex> lock(mLock);
+    return mData.clear();
+}
+
+std::vector<int> Camera3Device::StreamSet::getStreamIds() {
+    std::lock_guard<std::mutex> lock(mLock);
+    std::vector<int> streamIds(mData.size());
+    for (size_t i = 0; i < mData.size(); i++) {
+        streamIds[i] = mData.keyAt(i);
+    }
+    return streamIds;
+}
+
 status_t Camera3Device::createStream(sp<Surface> consumer,
             uint32_t width, uint32_t height, int format,
             android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
@@ -1393,18 +1787,20 @@
 
     if (format == HAL_PIXEL_FORMAT_BLOB) {
         ssize_t blobBufferSize;
-        if (dataSpace != HAL_DATASPACE_DEPTH) {
-            blobBufferSize = getJpegBufferSize(width, height);
-            if (blobBufferSize <= 0) {
-                SET_ERR_L("Invalid jpeg buffer size %zd", blobBufferSize);
-                return BAD_VALUE;
-            }
-        } else {
+        if (dataSpace == HAL_DATASPACE_DEPTH) {
             blobBufferSize = getPointCloudBufferSize();
             if (blobBufferSize <= 0) {
                 SET_ERR_L("Invalid point cloud buffer size %zd", blobBufferSize);
                 return BAD_VALUE;
             }
+        } else if (dataSpace == static_cast<android_dataspace>(HAL_DATASPACE_JPEG_APP_SEGMENTS)) {
+            blobBufferSize = width * height;
+        } else {
+            blobBufferSize = getJpegBufferSize(width, height);
+            if (blobBufferSize <= 0) {
+                SET_ERR_L("Invalid jpeg buffer size %zd", blobBufferSize);
+                return BAD_VALUE;
+            }
         }
         newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
                 width, height, blobBufferSize, format, dataSpace, rotation,
@@ -1421,7 +1817,8 @@
     } else if (isShared) {
         newStream = new Camera3SharedOutputStream(mNextStreamId, consumers,
                 width, height, format, consumerUsage, dataSpace, rotation,
-                mTimestampOffset, physicalCameraId, streamSetId);
+                mTimestampOffset, physicalCameraId, streamSetId,
+                mUseHalBufManager);
     } else if (consumers.size() == 0 && hasDeferredConsumer) {
         newStream = new Camera3OutputStream(mNextStreamId,
                 width, height, format, consumerUsage, dataSpace, rotation,
@@ -1498,20 +1895,20 @@
             return INVALID_OPERATION;
     }
 
-    ssize_t idx = mOutputStreams.indexOfKey(id);
-    if (idx == NAME_NOT_FOUND) {
+    sp<Camera3StreamInterface> stream = mOutputStreams.get(id);
+    if (stream == nullptr) {
         CLOGE("Stream %d is unknown", id);
-        return idx;
+        return BAD_VALUE;
     }
 
-    streamInfo->width  = mOutputStreams[idx]->getWidth();
-    streamInfo->height = mOutputStreams[idx]->getHeight();
-    streamInfo->format = mOutputStreams[idx]->getFormat();
-    streamInfo->dataSpace = mOutputStreams[idx]->getDataSpace();
-    streamInfo->formatOverridden = mOutputStreams[idx]->isFormatOverridden();
-    streamInfo->originalFormat = mOutputStreams[idx]->getOriginalFormat();
-    streamInfo->dataSpaceOverridden = mOutputStreams[idx]->isDataSpaceOverridden();
-    streamInfo->originalDataSpace = mOutputStreams[idx]->getOriginalDataSpace();
+    streamInfo->width  = stream->getWidth();
+    streamInfo->height = stream->getHeight();
+    streamInfo->format = stream->getFormat();
+    streamInfo->dataSpace = stream->getDataSpace();
+    streamInfo->formatOverridden = stream->isFormatOverridden();
+    streamInfo->originalFormat = stream->getOriginalFormat();
+    streamInfo->dataSpaceOverridden = stream->isDataSpaceOverridden();
+    streamInfo->originalDataSpace = stream->getOriginalDataSpace();
     return OK;
 }
 
@@ -1538,14 +1935,12 @@
             return INVALID_OPERATION;
     }
 
-    ssize_t idx = mOutputStreams.indexOfKey(id);
-    if (idx == NAME_NOT_FOUND) {
-        CLOGE("Stream %d does not exist",
-                id);
+    sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(id);
+    if (stream == nullptr) {
+        CLOGE("Stream %d does not exist", id);
         return BAD_VALUE;
     }
-
-    return mOutputStreams.editValueAt(idx)->setTransform(transform);
+    return stream->setTransform(transform);
 }
 
 status_t Camera3Device::deleteStream(int id) {
@@ -1570,21 +1965,21 @@
     }
 
     sp<Camera3StreamInterface> deletedStream;
-    ssize_t outputStreamIdx = mOutputStreams.indexOfKey(id);
+    sp<Camera3StreamInterface> stream = mOutputStreams.get(id);
     if (mInputStream != NULL && id == mInputStream->getId()) {
         deletedStream = mInputStream;
         mInputStream.clear();
     } else {
-        if (outputStreamIdx == NAME_NOT_FOUND) {
+        if (stream == nullptr) {
             CLOGE("Stream %d does not exist", id);
             return BAD_VALUE;
         }
     }
 
     // Delete output stream or the output part of a bi-directional stream.
-    if (outputStreamIdx != NAME_NOT_FOUND) {
-        deletedStream = mOutputStreams.editValueAt(outputStreamIdx);
-        mOutputStreams.removeItem(id);
+    if (stream != nullptr) {
+        deletedStream = stream;
+        mOutputStreams.remove(id);
     }
 
     // Free up the stream endpoint so that it can be used by some other stream
@@ -1667,7 +2062,7 @@
 
     if (templateId <= 0 || templateId >= CAMERA3_TEMPLATE_COUNT) {
         android_errorWriteWithInfoLog(CameraService::SN_EVENT_LOG_ID, "26866110",
-                IPCThreadState::self()->getCallingUid(), nullptr, 0);
+                CameraThreadState::getCallingUid(), nullptr, 0);
         return BAD_VALUE;
     }
 
@@ -1775,7 +2170,11 @@
 
 // Pause to reconfigure
 status_t Camera3Device::internalPauseAndWaitLocked(nsecs_t maxExpectedDuration) {
-    mRequestThread->setPaused(true);
+    if (mRequestThread.get() != nullptr) {
+        mRequestThread->setPaused(true);
+    } else {
+        return NO_INIT;
+    }
 
     ALOGV("%s: Camera %s: Internal wait until idle (% " PRIi64 " ns)", __FUNCTION__, mId.string(),
           maxExpectedDuration);
@@ -1821,6 +2220,14 @@
 
     mStatusWaiters++;
 
+    if (!active && mUseHalBufManager) {
+        auto streamIds = mOutputStreams.getStreamIds();
+        if (mStatus == STATUS_ACTIVE) {
+            mRequestThread->signalPipelineDrain(streamIds);
+        }
+        mRequestBufferSM.onWaitUntilIdle();
+    }
+
     bool stateSeen = false;
     do {
         if (active == (mStatus == STATUS_ACTIVE)) {
@@ -1980,6 +2387,13 @@
 
     {
         Mutex::Autolock l(mLock);
+
+        // b/116514106 "disconnect()" can get called twice for the same device. The
+        // camera device will not be initialized during the second run.
+        if (mStatus == STATUS_UNINITIALIZED) {
+            return OK;
+        }
+
         mRequestThread->clear(/*out*/frameNumber);
     }
 
@@ -1996,15 +2410,12 @@
     Mutex::Autolock il(mInterfaceLock);
     Mutex::Autolock l(mLock);
 
-    sp<Camera3StreamInterface> stream;
-    ssize_t outputStreamIdx = mOutputStreams.indexOfKey(streamId);
-    if (outputStreamIdx == NAME_NOT_FOUND) {
+    sp<Camera3StreamInterface> stream = mOutputStreams.get(streamId);
+    if (stream == nullptr) {
         CLOGE("Stream %d does not exist", streamId);
         return BAD_VALUE;
     }
 
-    stream = mOutputStreams.editValueAt(outputStreamIdx);
-
     if (stream->isUnpreparable() || stream->hasOutstandingBuffers() ) {
         CLOGE("Stream %d has already been a request target", streamId);
         return BAD_VALUE;
@@ -2024,15 +2435,12 @@
     Mutex::Autolock il(mInterfaceLock);
     Mutex::Autolock l(mLock);
 
-    sp<Camera3StreamInterface> stream;
-    ssize_t outputStreamIdx = mOutputStreams.indexOfKey(streamId);
-    if (outputStreamIdx == NAME_NOT_FOUND) {
+    sp<Camera3StreamInterface> stream = mOutputStreams.get(streamId);
+    if (stream == nullptr) {
         CLOGE("Stream %d does not exist", streamId);
         return BAD_VALUE;
     }
 
-    stream = mOutputStreams.editValueAt(outputStreamIdx);
-
     if (stream->hasOutstandingBuffers() || mRequestThread->isStreamPending(stream)) {
         CLOGE("Stream %d is a target of a in-progress request", streamId);
         return BAD_VALUE;
@@ -2048,14 +2456,11 @@
     Mutex::Autolock il(mInterfaceLock);
     Mutex::Autolock l(mLock);
 
-    sp<Camera3StreamInterface> stream;
-    ssize_t outputStreamIdx = mOutputStreams.indexOfKey(streamId);
-    if (outputStreamIdx == NAME_NOT_FOUND) {
+    sp<Camera3StreamInterface> stream = mOutputStreams.get(streamId);
+    if (stream == nullptr) {
         CLOGE("Stream %d does not exist", streamId);
         return BAD_VALUE;
     }
-
-    stream = mOutputStreams.editValueAt(outputStreamIdx);
     stream->addBufferListener(listener);
 
     return OK;
@@ -2114,12 +2519,14 @@
         return BAD_VALUE;
     }
 
-    ssize_t idx = mOutputStreams.indexOfKey(streamId);
-    if (idx == NAME_NOT_FOUND) {
+    sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(streamId);
+    if (stream == nullptr) {
         CLOGE("Stream %d is unknown", streamId);
-        return idx;
+        return BAD_VALUE;
     }
-    sp<Camera3OutputStreamInterface> stream = mOutputStreams[idx];
+
+    // isConsumerConfigurationDeferred will be off after setConsumers
+    bool isDeferred = stream->isConsumerConfigurationDeferred();
     status_t res = stream->setConsumers(consumers);
     if (res != OK) {
         CLOGE("Stream %d set consumer failed (error %d %s) ", streamId, res, strerror(-res));
@@ -2135,7 +2542,7 @@
         surfaceIds->push_back(id);
     }
 
-    if (stream->isConsumerConfigurationDeferred()) {
+    if (isDeferred) {
         if (!stream->isConfiguring()) {
             CLOGE("Stream %d was already fully configured.", streamId);
             return INVALID_OPERATION;
@@ -2164,10 +2571,10 @@
     Mutex::Autolock il(mInterfaceLock);
     Mutex::Autolock l(mLock);
 
-    ssize_t idx = mOutputStreams.indexOfKey(streamId);
-    if (idx == NAME_NOT_FOUND) {
+    sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(streamId);
+    if (stream == nullptr) {
         CLOGE("Stream %d is unknown", streamId);
-        return idx;
+        return BAD_VALUE;
     }
 
     for (const auto &it : removedSurfaceIds) {
@@ -2177,7 +2584,6 @@
         }
     }
 
-    sp<Camera3OutputStreamInterface> stream = mOutputStreams[idx];
     status_t res = stream->updateStream(newSurfaces, outputInfo, removedSurfaceIds, outputMap);
     if (res != OK) {
         CLOGE("Stream %d failed to update stream (error %d %s) ",
@@ -2196,13 +2602,11 @@
     Mutex::Autolock il(mInterfaceLock);
     Mutex::Autolock l(mLock);
 
-    int idx = mOutputStreams.indexOfKey(streamId);
-    if (idx == NAME_NOT_FOUND) {
+    sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(streamId);
+    if (stream == nullptr) {
         ALOGE("%s: Stream %d is not found.", __FUNCTION__, streamId);
         return BAD_VALUE;
     }
-
-    sp<Camera3OutputStreamInterface> stream = mOutputStreams.editValueAt(idx);
     return stream->dropBuffers(dropping);
 }
 
@@ -2213,7 +2617,6 @@
 sp<Camera3Device::CaptureRequest> Camera3Device::createCaptureRequest(
         const PhysicalCameraSettingsList &request, const SurfaceMap &surfaceMap) {
     ATRACE_CALL();
-    status_t res;
 
     sp<CaptureRequest> newRequest = new CaptureRequest;
     newRequest->mSettingsList = request;
@@ -2227,19 +2630,14 @@
                     inputStreams.data.u8[0]);
             return NULL;
         }
-        // Lazy completion of stream configuration (allocation/registration)
-        // on first use
+
         if (mInputStream->isConfiguring()) {
-            res = mInputStream->finishConfiguration();
-            if (res != OK) {
-                SET_ERR_L("Unable to finish configuring input stream %d:"
-                        " %s (%d)",
-                        mInputStream->getId(), strerror(-res), res);
-                return NULL;
-            }
+            SET_ERR_L("%s: input stream %d is not configured!",
+                    __FUNCTION__, mInputStream->getId());
+            return NULL;
         }
-        // Check if stream is being prepared
-        if (mInputStream->isPreparing()) {
+        // Check if stream prepare is blocking requests.
+        if (mInputStream->isBlockedByPrepare()) {
             CLOGE("Request references an input stream that's being prepared!");
             return NULL;
         }
@@ -2256,15 +2654,12 @@
     }
 
     for (size_t i = 0; i < streams.count; i++) {
-        int idx = mOutputStreams.indexOfKey(streams.data.i32[i]);
-        if (idx == NAME_NOT_FOUND) {
+        sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(streams.data.i32[i]);
+        if (stream == nullptr) {
             CLOGE("Request references unknown stream %d",
-                    streams.data.u8[i]);
+                    streams.data.i32[i]);
             return NULL;
         }
-        sp<Camera3OutputStreamInterface> stream =
-                mOutputStreams.editValueAt(idx);
-
         // It is illegal to include a deferred consumer output stream into a request
         auto iter = surfaceMap.find(streams.data.i32[i]);
         if (iter != surfaceMap.end()) {
@@ -2276,21 +2671,15 @@
                     return NULL;
                 }
             }
-            newRequest->mOutputSurfaces[i] = surfaces;
+            newRequest->mOutputSurfaces[streams.data.i32[i]] = surfaces;
         }
 
-        // Lazy completion of stream configuration (allocation/registration)
-        // on first use
         if (stream->isConfiguring()) {
-            res = stream->finishConfiguration();
-            if (res != OK) {
-                SET_ERR_L("Unable to finish configuring stream %d: %s (%d)",
-                        stream->getId(), strerror(-res), res);
-                return NULL;
-            }
+            SET_ERR_L("%s: stream %d is not configured!", __FUNCTION__, stream->getId());
+            return NULL;
         }
-        // Check if stream is being prepared
-        if (stream->isPreparing()) {
+        // Check if stream prepare is blocking requests.
+        if (stream->isBlockedByPrepare()) {
             CLOGE("Request references an output stream that's being prepared!");
             return NULL;
         }
@@ -2325,7 +2714,7 @@
     }
 
     for (size_t i = 0; i < mOutputStreams.size(); i++) {
-        sp<Camera3OutputStreamInterface> outputStream = mOutputStreams.editValueAt(i);
+        sp<Camera3OutputStreamInterface> outputStream = mOutputStreams[i];
         if (outputStream->isConfiguring()) {
             res = outputStream->cancelConfiguration();
             if (res != OK) {
@@ -2460,7 +2849,7 @@
         }
 
         camera3_stream_t *outputStream;
-        outputStream = mOutputStreams.editValueAt(i)->startConfiguration();
+        outputStream = mOutputStreams[i]->startConfiguration();
         if (outputStream == NULL) {
             CLOGE("Can't start output stream configuration");
             cancelStreamsConfigurationLocked();
@@ -2468,19 +2857,27 @@
         }
         streams.add(outputStream);
 
-        if (outputStream->format == HAL_PIXEL_FORMAT_BLOB &&
-                outputStream->data_space == HAL_DATASPACE_V0_JFIF) {
+        if (outputStream->format == HAL_PIXEL_FORMAT_BLOB) {
             size_t k = i + ((mInputStream != nullptr) ? 1 : 0); // Input stream if present should
                                                                 // always occupy the initial entry.
-            bufferSizes[k] = static_cast<uint32_t>(
-                    getJpegBufferSize(outputStream->width, outputStream->height));
+            if (outputStream->data_space == HAL_DATASPACE_V0_JFIF) {
+                bufferSizes[k] = static_cast<uint32_t>(
+                        getJpegBufferSize(outputStream->width, outputStream->height));
+            } else if (outputStream->data_space ==
+                    static_cast<android_dataspace>(HAL_DATASPACE_JPEG_APP_SEGMENTS)) {
+                bufferSizes[k] = outputStream->width * outputStream->height;
+            } else {
+                ALOGW("%s: Blob dataSpace %d not supported",
+                        __FUNCTION__, outputStream->data_space);
+            }
         }
     }
 
     config.streams = streams.editArray();
 
     // Do the HAL configuration; will potentially touch stream
-    // max_buffers, usage, priv fields.
+    // max_buffers, usage, and priv fields, as well as data_space and format
+    // fields for IMPLEMENTATION_DEFINED formats.
 
     const camera_metadata_t *sessionBuffer = sessionParams.getAndLock();
     res = mInterface->configureStreams(sessionBuffer, &config, bufferSizes);
@@ -2505,7 +2902,8 @@
     // faster
 
     if (mInputStream != NULL && mInputStream->isConfiguring()) {
-        res = mInputStream->finishConfiguration();
+        bool streamReConfigured = false;
+        res = mInputStream->finishConfiguration(&streamReConfigured);
         if (res != OK) {
             CLOGE("Can't finish configuring input stream %d: %s (%d)",
                     mInputStream->getId(), strerror(-res), res);
@@ -2515,13 +2913,16 @@
             }
             return BAD_VALUE;
         }
+        if (streamReConfigured) {
+            mInterface->onStreamReConfigured(mInputStream->getId());
+        }
     }
 
     for (size_t i = 0; i < mOutputStreams.size(); i++) {
-        sp<Camera3OutputStreamInterface> outputStream =
-            mOutputStreams.editValueAt(i);
+        sp<Camera3OutputStreamInterface> outputStream = mOutputStreams[i];
         if (outputStream->isConfiguring() && !outputStream->isConsumerConfigurationDeferred()) {
-            res = outputStream->finishConfiguration();
+            bool streamReConfigured = false;
+            res = outputStream->finishConfiguration(&streamReConfigured);
             if (res != OK) {
                 CLOGE("Can't finish configuring output stream %d: %s (%d)",
                         outputStream->getId(), strerror(-res), res);
@@ -2531,6 +2932,9 @@
                 }
                 return BAD_VALUE;
             }
+            if (streamReConfigured) {
+                mInterface->onStreamReConfigured(outputStream->getId());
+            }
         }
     }
 
@@ -2582,6 +2986,10 @@
         return rc;
     }
 
+    if (mDummyStreamId == NO_STREAM) {
+        mRequestBufferSM.onStreamsConfigured();
+    }
+
     return OK;
 }
 
@@ -2626,15 +3034,12 @@
     // Ok, have a dummy stream and there's at least one other output stream,
     // so remove the dummy
 
-    sp<Camera3StreamInterface> deletedStream;
-    ssize_t outputStreamIdx = mOutputStreams.indexOfKey(mDummyStreamId);
-    if (outputStreamIdx == NAME_NOT_FOUND) {
+    sp<Camera3StreamInterface> deletedStream = mOutputStreams.get(mDummyStreamId);
+    if (deletedStream == nullptr) {
         SET_ERR_L("Dummy stream %d does not appear to exist", mDummyStreamId);
         return INVALID_OPERATION;
     }
-
-    deletedStream = mOutputStreams.editValueAt(outputStreamIdx);
-    mOutputStreams.removeItemsAt(outputStreamIdx);
+    mOutputStreams.remove(mDummyStreamId);
 
     // Free up the stream endpoint so that it can be used by some other stream
     res = deletedStream->disconnect();
@@ -2708,18 +3113,21 @@
 status_t Camera3Device::registerInFlight(uint32_t frameNumber,
         int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput,
         bool hasAppCallback, nsecs_t maxExpectedDuration,
-        std::set<String8>& physicalCameraIds) {
+        std::set<String8>& physicalCameraIds, bool isStillCapture,
+        bool isZslCapture, const SurfaceMap& outputSurfaces) {
     ATRACE_CALL();
     Mutex::Autolock l(mInFlightLock);
 
     ssize_t res;
     res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras, hasInput,
-            hasAppCallback, maxExpectedDuration, physicalCameraIds));
+            hasAppCallback, maxExpectedDuration, physicalCameraIds, isStillCapture, isZslCapture,
+            outputSurfaces));
     if (res < 0) return res;
 
     if (mInFlightMap.size() == 1) {
-        // hold mLock to prevent race with disconnect
-        Mutex::Autolock l(mLock);
+        // Hold a separate dedicated tracker lock to prevent race with disconnect and also
+        // avoid a deadlock during reprocess requests.
+        Mutex::Autolock l(mTrackerLock);
         if (mStatusTracker != nullptr) {
             mStatusTracker->markComponentActive(mInFlightStatusId);
         }
@@ -2731,16 +3139,68 @@
 
 void Camera3Device::returnOutputBuffers(
         const camera3_stream_buffer_t *outputBuffers, size_t numBuffers,
-        nsecs_t timestamp) {
+        nsecs_t timestamp, bool timestampIncreasing,
+        const SurfaceMap& outputSurfaces,
+        const CaptureResultExtras &inResultExtras) {
+
     for (size_t i = 0; i < numBuffers; i++)
     {
-        Camera3Stream *stream = Camera3Stream::cast(outputBuffers[i].stream);
-        status_t res = stream->returnBuffer(outputBuffers[i], timestamp);
+        if (outputBuffers[i].buffer == nullptr) {
+            if (!mUseHalBufManager) {
+                // With HAL buffer management API, HAL sometimes will have to return buffers that
+                // has not got a output buffer handle filled yet. This is though illegal if HAL
+                // buffer management API is not being used.
+                ALOGE("%s: cannot return a null buffer!", __FUNCTION__);
+            }
+            continue;
+        }
+
+        Camera3StreamInterface *stream = Camera3Stream::cast(outputBuffers[i].stream);
+        int streamId = stream->getId();
+        const auto& it = outputSurfaces.find(streamId);
+        status_t res = OK;
+        if (it != outputSurfaces.end()) {
+            res = stream->returnBuffer(
+                    outputBuffers[i], timestamp, timestampIncreasing, it->second,
+                    inResultExtras.frameNumber);
+        } else {
+            res = stream->returnBuffer(
+                    outputBuffers[i], timestamp, timestampIncreasing, std::vector<size_t> (),
+                    inResultExtras.frameNumber);
+        }
+
         // Note: stream may be deallocated at this point, if this buffer was
         // the last reference to it.
-        if (res != OK) {
-            ALOGE("Can't return buffer to its stream: %s (%d)",
-                strerror(-res), res);
+        if (res == NO_INIT || res == DEAD_OBJECT) {
+            ALOGV("Can't return buffer to its stream: %s (%d)", strerror(-res), res);
+        } else if (res != OK) {
+            ALOGE("Can't return buffer to its stream: %s (%d)", strerror(-res), res);
+        }
+
+        // Long processing consumers can cause returnBuffer timeout for shared stream
+        // If that happens, cancel the buffer and send a buffer error to client
+        if (it != outputSurfaces.end() && res == TIMED_OUT &&
+                outputBuffers[i].status == CAMERA3_BUFFER_STATUS_OK) {
+            // cancel the buffer
+            camera3_stream_buffer_t sb = outputBuffers[i];
+            sb.status = CAMERA3_BUFFER_STATUS_ERROR;
+            stream->returnBuffer(sb, /*timestamp*/0, timestampIncreasing, std::vector<size_t> (),
+                    inResultExtras.frameNumber);
+
+            // notify client buffer error
+            sp<NotificationListener> listener;
+            {
+                Mutex::Autolock l(mOutputLock);
+                listener = mListener.promote();
+            }
+
+            if (listener != nullptr) {
+                CaptureResultExtras extras = inResultExtras;
+                extras.errorStreamId = streamId;
+                listener->notifyError(
+                        hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER,
+                        extras);
+            }
         }
     }
 }
@@ -2752,8 +3212,10 @@
 
     // Indicate idle inFlightMap to the status tracker
     if (mInFlightMap.size() == 0) {
-        // hold mLock to prevent race with disconnect
-        Mutex::Autolock l(mLock);
+        mRequestBufferSM.onInflightMapEmpty();
+        // Hold a separate dedicated tracker lock to prevent race with disconnect and also
+        // avoid a deadlock during reprocess requests.
+        Mutex::Autolock l(mTrackerLock);
         if (mStatusTracker != nullptr) {
             mStatusTracker->markComponentIdle(mInFlightStatusId, Fence::NO_FENCE);
         }
@@ -2778,6 +3240,10 @@
     if (request.numBuffersLeft == 0 &&
             (request.skipResultMetadata ||
             (request.haveResultMetadata && shutterTimestamp != 0))) {
+        if (request.stillCapture) {
+            ATRACE_ASYNC_END("still capture", frameNumber);
+        }
+
         ATRACE_ASYNC_END("frame capture", frameNumber);
 
         // Sanity check - if sensor timestamp matches shutter timestamp in the
@@ -2794,7 +3260,8 @@
         assert(request.requestStatus != OK ||
                request.pendingOutputBuffers.size() == 0);
         returnOutputBuffers(request.pendingOutputBuffers.array(),
-            request.pendingOutputBuffers.size(), 0);
+            request.pendingOutputBuffers.size(), 0, /*timestampIncreasing*/true,
+            request.outputSurfaces, request.resultExtras);
 
         removeInFlightMapEntryLocked(idx);
         ALOGVV("%s: removed frame %d from InFlightMap", __FUNCTION__, frameNumber);
@@ -2818,7 +3285,9 @@
         for (size_t idx = 0; idx < mInFlightMap.size(); idx++) {
             const InFlightRequest &request = mInFlightMap.valueAt(idx);
             returnOutputBuffers(request.pendingOutputBuffers.array(),
-                request.pendingOutputBuffers.size(), 0);
+                request.pendingOutputBuffers.size(), 0,
+                /*timestampIncreasing*/true, request.outputSurfaces,
+                request.resultExtras);
         }
         mInFlightMap.clear();
         mExpectedInflightDuration = 0;
@@ -2828,7 +3297,15 @@
     std::vector<std::pair<int32_t, int32_t>> inflightKeys;
     mInterface->getInflightBufferKeys(&inflightKeys);
 
-    int32_t inputStreamId = (mInputStream != nullptr) ? mInputStream->getId() : -1;
+    // Inflight buffers for HAL buffer manager
+    std::vector<uint64_t> inflightRequestBufferKeys;
+    mInterface->getInflightRequestBufferKeys(&inflightRequestBufferKeys);
+
+    // (streamId, frameNumber, buffer_handle_t*) tuple for all inflight buffers.
+    // frameNumber will be -1 for buffers from HAL buffer manager
+    std::vector<std::tuple<int32_t, int32_t, buffer_handle_t*>> inflightBuffers;
+    inflightBuffers.reserve(inflightKeys.size() + inflightRequestBufferKeys.size());
+
     for (auto& pair : inflightKeys) {
         int32_t frameNumber = pair.first;
         int32_t streamId = pair.second;
@@ -2839,6 +3316,26 @@
                     __FUNCTION__, frameNumber, streamId);
             continue;
         }
+        inflightBuffers.push_back(std::make_tuple(streamId, frameNumber, buffer));
+    }
+
+    for (auto& bufferId : inflightRequestBufferKeys) {
+        int32_t streamId = -1;
+        buffer_handle_t* buffer = nullptr;
+        status_t res = mInterface->popInflightRequestBuffer(bufferId, &buffer, &streamId);
+        if (res != OK) {
+            ALOGE("%s: cannot find in-flight buffer %" PRIu64, __FUNCTION__, bufferId);
+            continue;
+        }
+        inflightBuffers.push_back(std::make_tuple(streamId, /*frameNumber*/-1, buffer));
+    }
+
+    int32_t inputStreamId = (mInputStream != nullptr) ? mInputStream->getId() : -1;
+    for (auto& tuple : inflightBuffers) {
+        status_t res = OK;
+        int32_t streamId = std::get<0>(tuple);
+        int32_t frameNumber = std::get<1>(tuple);
+        buffer_handle_t* buffer = std::get<2>(tuple);
 
         camera3_stream_buffer_t streamBuffer;
         streamBuffer.buffer = buffer;
@@ -2856,7 +3353,8 @@
                 streamBuffer.stream = halStream;
                 switch (halStream->stream_type) {
                     case CAMERA3_STREAM_OUTPUT:
-                        res = stream->returnBuffer(streamBuffer, /*timestamp*/ 0);
+                        res = stream->returnBuffer(streamBuffer, /*timestamp*/ 0,
+                                /*timestampIncreasing*/true, std::vector<size_t> (), frameNumber);
                         if (res != OK) {
                             ALOGE("%s: Can't return output buffer for frame %d to"
                                   " stream %d: %s (%d)",  __FUNCTION__,
@@ -2893,12 +3391,12 @@
                       frameNumber, streamId, strerror(-res), res);
             }
         } else {
-            ssize_t idx = mOutputStreams.indexOfKey(streamId);
-            if (idx == NAME_NOT_FOUND) {
+            sp<Camera3StreamInterface> stream = mOutputStreams.get(streamId);
+            if (stream == nullptr) {
                 ALOGE("%s: Output stream id %d not found!", __FUNCTION__, streamId);
                 continue;
             }
-            streamBuffer.stream = mOutputStreams.valueAt(idx)->asHalStream();
+            streamBuffer.stream = stream->asHalStream();
             returnOutputBuffers(&streamBuffer, /*size*/1, /*timestamp*/ 0);
         }
     }
@@ -2924,6 +3422,14 @@
         return;
     }
 
+    // Update vendor tag id for physical metadata
+    for (auto& physicalMetadata : result->mPhysicalMetadatas) {
+        camera_metadata_t *pmeta = const_cast<camera_metadata_t *>(
+                physicalMetadata.mPhysicalCameraMetadata.getAndLock());
+        set_camera_metadata_vendor_id(pmeta, mVendorTagId);
+        physicalMetadata.mPhysicalCameraMetadata.unlock(pmeta);
+    }
+
     // Valid result, insert into queue
     List<CaptureResult>::iterator queuedResult =
             mResultQueue.insert(mResultQueue.end(), CaptureResult(*result));
@@ -2946,6 +3452,13 @@
     captureResult.mResultExtras = resultExtras;
     captureResult.mMetadata = partialResult;
 
+    // Fix up result metadata for monochrome camera.
+    status_t res = fixupMonochromeTags(mDeviceInfo, captureResult.mMetadata);
+    if (res != OK) {
+        SET_ERR("Failed to override result metadata: %s (%d)", strerror(-res), res);
+        return;
+    }
+
     insertResultLocked(&captureResult, frameNumber);
 }
 
@@ -2954,7 +3467,7 @@
         CaptureResultExtras &resultExtras,
         CameraMetadata &collectedPartialResult,
         uint32_t frameNumber,
-        bool reprocess,
+        bool reprocess, bool zslStillCapture,
         const std::vector<PhysicalCaptureResultInfo>& physicalMetadatas) {
     ATRACE_CALL();
     if (pendingMetadata.isEmpty())
@@ -2971,6 +3484,14 @@
             return;
         }
         mNextReprocessResultFrameNumber = frameNumber + 1;
+    } else if (zslStillCapture) {
+        if (frameNumber < mNextZslStillResultFrameNumber) {
+            SET_ERR("Out-of-order ZSL still capture result metadata submitted! "
+                "(got frame number %d, expecting %d)",
+                frameNumber, mNextZslStillResultFrameNumber);
+            return;
+        }
+        mNextZslStillResultFrameNumber = frameNumber + 1;
     } else {
         if (frameNumber < mNextResultFrameNumber) {
             SET_ERR("Out-of-order capture result metadata submitted! "
@@ -3000,7 +3521,6 @@
                 frameNumber);
         return;
     }
-
     nsecs_t sensorTimestamp = timestamp.data.i64[0];
 
     for (auto& physicalMetadata : captureResult.mPhysicalMetadatas) {
@@ -3014,15 +3534,51 @@
     }
 
     // Fix up some result metadata to account for HAL-level distortion correction
-    status_t res = mDistortionMapper.correctCaptureResult(&captureResult.mMetadata);
+    status_t res =
+            mDistortionMappers[mId.c_str()].correctCaptureResult(&captureResult.mMetadata);
     if (res != OK) {
         SET_ERR("Unable to correct capture result metadata for frame %d: %s (%d)",
                 frameNumber, strerror(res), res);
         return;
     }
+    for (auto& physicalMetadata : captureResult.mPhysicalMetadatas) {
+        String8 cameraId8(physicalMetadata.mPhysicalCameraId);
+        if (mDistortionMappers.find(cameraId8.c_str()) == mDistortionMappers.end()) {
+            continue;
+        }
+        res = mDistortionMappers[cameraId8.c_str()].correctCaptureResult(
+                &physicalMetadata.mPhysicalCameraMetadata);
+        if (res != OK) {
+            SET_ERR("Unable to correct physical capture result metadata for frame %d: %s (%d)",
+                    frameNumber, strerror(res), res);
+            return;
+        }
+    }
 
+    // Fix up result metadata for monochrome camera.
+    res = fixupMonochromeTags(mDeviceInfo, captureResult.mMetadata);
+    if (res != OK) {
+        SET_ERR("Failed to override result metadata: %s (%d)", strerror(-res), res);
+        return;
+    }
+    for (auto& physicalMetadata : captureResult.mPhysicalMetadatas) {
+        String8 cameraId8(physicalMetadata.mPhysicalCameraId);
+        res = fixupMonochromeTags(mPhysicalDeviceInfoMap.at(cameraId8.c_str()),
+                physicalMetadata.mPhysicalCameraMetadata);
+        if (res != OK) {
+            SET_ERR("Failed to override result metadata: %s (%d)", strerror(-res), res);
+            return;
+        }
+    }
+
+    std::unordered_map<std::string, CameraMetadata> monitoredPhysicalMetadata;
+    for (auto& m : physicalMetadatas) {
+        monitoredPhysicalMetadata.emplace(String8(m.mPhysicalCameraId).string(),
+                CameraMetadata(m.mPhysicalCameraMetadata));
+    }
     mTagMonitor.monitorMetadata(TagMonitor::RESULT,
-            frameNumber, sensorTimestamp, captureResult.mMetadata);
+            frameNumber, sensorTimestamp, captureResult.mMetadata,
+            monitoredPhysicalMetadata);
 
     insertResultLocked(&captureResult, frameNumber);
 }
@@ -3177,8 +3733,10 @@
             request.pendingOutputBuffers.appendArray(result->output_buffers,
                 result->num_output_buffers);
         } else {
+            bool timestampIncreasing = !(request.zslCapture || request.hasInputBuffer);
             returnOutputBuffers(result->output_buffers,
-                result->num_output_buffers, shutterTimestamp);
+                result->num_output_buffers, shutterTimestamp, timestampIncreasing,
+                request.outputSurfaces, request.resultExtras);
         }
 
         if (result->result != NULL && !isPartialResult) {
@@ -3191,12 +3749,13 @@
             if (shutterTimestamp == 0) {
                 request.pendingMetadata = result->result;
                 request.collectedPartialResult = collectedPartialResult;
-           } else if (request.hasCallback) {
+            } else if (request.hasCallback) {
                 CameraMetadata metadata;
                 metadata = result->result;
                 sendCaptureResult(metadata, request.resultExtras,
                     collectedPartialResult, frameNumber,
-                    hasInputBufferInRequest, request.physicalMetadatas);
+                    hasInputBufferInRequest, request.zslCapture && request.stillCapture,
+                    request.physicalMetadatas);
             }
         }
 
@@ -3276,10 +3835,12 @@
             hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_INVALID_ERROR;
 
     int streamId = 0;
+    String16 physicalCameraId;
     if (msg.error_stream != NULL) {
         Camera3Stream *stream =
                 Camera3Stream::cast(msg.error_stream);
         streamId = stream->getId();
+        physicalCameraId = String16(stream->physicalCameraId());
     }
     ALOGV("Camera %s: %s: HAL error, frame %d, stream %d: %d",
             mId.string(), __FUNCTION__, msg.frame_number,
@@ -3301,16 +3862,35 @@
                     InFlightRequest &r = mInFlightMap.editValueAt(idx);
                     r.requestStatus = msg.error_code;
                     resultExtras = r.resultExtras;
-                    if (hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT == errorCode
+                    bool logicalDeviceResultError = false;
+                    if (hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT ==
+                            errorCode) {
+                        if (physicalCameraId.size() > 0) {
+                            String8 cameraId(physicalCameraId);
+                            if (r.physicalCameraIds.find(cameraId) == r.physicalCameraIds.end()) {
+                                ALOGE("%s: Reported result failure for physical camera device: %s "
+                                        " which is not part of the respective request!",
+                                        __FUNCTION__, cameraId.string());
+                                break;
+                            }
+                            resultExtras.errorPhysicalCameraId = physicalCameraId;
+                        } else {
+                            logicalDeviceResultError = true;
+                        }
+                    }
+
+                    if (logicalDeviceResultError
                             ||  hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST ==
                             errorCode) {
                         r.skipResultMetadata = true;
                     }
-                    if (hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT ==
-                            errorCode) {
+                    if (logicalDeviceResultError) {
                         // In case of missing result check whether the buffers
                         // returned. If they returned, then remove inflight
                         // request.
+                        // TODO: should we call this for ERROR_CAMERA_REQUEST as well?
+                        //       otherwise we are depending on HAL to send the buffers back after
+                        //       calling notifyError. Not sure if that's in the spec.
                         removeInFlightRequestIfReadyLocked(idx);
                     }
                 } else {
@@ -3353,12 +3933,20 @@
                 // TODO: need to track errors for tighter bounds on expected frame number.
                 if (r.hasInputBuffer) {
                     if (msg.frame_number < mNextReprocessShutterFrameNumber) {
-                        SET_ERR("Shutter notification out-of-order. Expected "
+                        SET_ERR("Reprocess shutter notification out-of-order. Expected "
                                 "notification for frame %d, got frame %d",
                                 mNextReprocessShutterFrameNumber, msg.frame_number);
                         return;
                     }
                     mNextReprocessShutterFrameNumber = msg.frame_number + 1;
+                } else if (r.zslCapture && r.stillCapture) {
+                    if (msg.frame_number < mNextZslStillShutterFrameNumber) {
+                        SET_ERR("ZSL still capture shutter notification out-of-order. Expected "
+                                "notification for frame %d, got frame %d",
+                                mNextZslStillShutterFrameNumber, msg.frame_number);
+                        return;
+                    }
+                    mNextZslStillShutterFrameNumber = msg.frame_number + 1;
                 } else {
                     if (msg.frame_number < mNextShutterFrameNumber) {
                         SET_ERR("Shutter notification out-of-order. Expected "
@@ -3382,10 +3970,13 @@
                 // send pending result and buffers
                 sendCaptureResult(r.pendingMetadata, r.resultExtras,
                     r.collectedPartialResult, msg.frame_number,
-                    r.hasInputBuffer, r.physicalMetadatas);
+                    r.hasInputBuffer, r.zslCapture && r.stillCapture,
+                    r.physicalMetadatas);
             }
+            bool timestampIncreasing = !(r.zslCapture || r.hasInputBuffer);
             returnOutputBuffers(r.pendingOutputBuffers.array(),
-                r.pendingOutputBuffers.size(), r.shutterTimestamp);
+                    r.pendingOutputBuffers.size(), r.shutterTimestamp, timestampIncreasing,
+                    r.outputSurfaces, r.resultExtras);
             r.pendingOutputBuffers.clear();
 
             removeInFlightRequestIfReadyLocked(idx);
@@ -3411,8 +4002,11 @@
 
 
 void Camera3Device::monitorMetadata(TagMonitor::eventSource source,
-        int64_t frameNumber, nsecs_t timestamp, const CameraMetadata& metadata) {
-    mTagMonitor.monitorMetadata(source, frameNumber, timestamp, metadata);
+        int64_t frameNumber, nsecs_t timestamp, const CameraMetadata& metadata,
+        const std::unordered_map<std::string, CameraMetadata>& physicalMetadata) {
+
+    mTagMonitor.monitorMetadata(source, frameNumber, timestamp, metadata,
+            physicalMetadata);
 }
 
 /**
@@ -3421,11 +4015,18 @@
 
 Camera3Device::HalInterface::HalInterface(
             sp<ICameraDeviceSession> &session,
-            std::shared_ptr<RequestMetadataQueue> queue) :
+            std::shared_ptr<RequestMetadataQueue> queue,
+            bool useHalBufManager) :
         mHidlSession(session),
-        mRequestMetadataQueue(queue) {
+        mRequestMetadataQueue(queue),
+        mUseHalBufManager(useHalBufManager),
+        mIsReconfigurationQuerySupported(true) {
     // Check with hardware service manager if we can downcast these interfaces
     // Somewhat expensive, so cache the results at startup
+    auto castResult_3_5 = device::V3_5::ICameraDeviceSession::castFrom(mHidlSession);
+    if (castResult_3_5.isOk()) {
+        mHidlSession_3_5 = castResult_3_5;
+    }
     auto castResult_3_4 = device::V3_4::ICameraDeviceSession::castFrom(mHidlSession);
     if (castResult_3_4.isOk()) {
         mHidlSession_3_4 = castResult_3_4;
@@ -3436,26 +4037,24 @@
     }
 }
 
-Camera3Device::HalInterface::HalInterface() {}
+Camera3Device::HalInterface::HalInterface() : mUseHalBufManager(false) {}
 
 Camera3Device::HalInterface::HalInterface(const HalInterface& other) :
         mHidlSession(other.mHidlSession),
-        mRequestMetadataQueue(other.mRequestMetadataQueue) {}
+        mRequestMetadataQueue(other.mRequestMetadataQueue),
+        mUseHalBufManager(other.mUseHalBufManager) {}
 
 bool Camera3Device::HalInterface::valid() {
     return (mHidlSession != nullptr);
 }
 
 void Camera3Device::HalInterface::clear() {
+    mHidlSession_3_5.clear();
     mHidlSession_3_4.clear();
     mHidlSession_3_3.clear();
     mHidlSession.clear();
 }
 
-bool Camera3Device::HalInterface::supportBatchRequest() {
-    return mHidlSession != nullptr;
-}
-
 status_t Camera3Device::HalInterface::constructDefaultRequestSettings(
         camera3_request_template_t templateId,
         /*out*/ camera_metadata_t **requestTemplate) {
@@ -3523,6 +4122,52 @@
     return res;
 }
 
+bool Camera3Device::HalInterface::isReconfigurationRequired(CameraMetadata& oldSessionParams,
+        CameraMetadata& newSessionParams) {
+    // We do reconfiguration by default;
+    bool ret = true;
+    if ((mHidlSession_3_5 != nullptr) && mIsReconfigurationQuerySupported) {
+        android::hardware::hidl_vec<uint8_t> oldParams, newParams;
+        camera_metadata_t* oldSessioMeta = const_cast<camera_metadata_t*>(
+                oldSessionParams.getAndLock());
+        camera_metadata_t* newSessioMeta = const_cast<camera_metadata_t*>(
+                newSessionParams.getAndLock());
+        oldParams.setToExternal(reinterpret_cast<uint8_t*>(oldSessioMeta),
+                get_camera_metadata_size(oldSessioMeta));
+        newParams.setToExternal(reinterpret_cast<uint8_t*>(newSessioMeta),
+                get_camera_metadata_size(newSessioMeta));
+        hardware::camera::common::V1_0::Status callStatus;
+        bool required;
+        auto hidlCb = [&callStatus, &required] (hardware::camera::common::V1_0::Status s,
+                bool requiredFlag) {
+            callStatus = s;
+            required = requiredFlag;
+        };
+        auto err = mHidlSession_3_5->isReconfigurationRequired(oldParams, newParams, hidlCb);
+        oldSessionParams.unlock(oldSessioMeta);
+        newSessionParams.unlock(newSessioMeta);
+        if (err.isOk()) {
+            switch (callStatus) {
+                case hardware::camera::common::V1_0::Status::OK:
+                    ret = required;
+                    break;
+                case hardware::camera::common::V1_0::Status::METHOD_NOT_SUPPORTED:
+                    mIsReconfigurationQuerySupported = false;
+                    ret = true;
+                    break;
+                default:
+                    ALOGV("%s: Reconfiguration query failed: %d", __FUNCTION__, callStatus);
+                    ret = true;
+            }
+        } else {
+            ALOGE("%s: Unexpected binder error: %s", __FUNCTION__, err.description().c_str());
+            ret = true;
+        }
+    }
+
+    return ret;
+}
+
 status_t Camera3Device::HalInterface::configureStreams(const camera_metadata_t *sessionParams,
         camera3_stream_configuration *config, const std::vector<uint32_t>& bufferSizes) {
     ATRACE_NAME("CameraHal::configureStreams");
@@ -3560,10 +4205,19 @@
         dst3_2.streamType = streamType;
         dst3_2.width = src->width;
         dst3_2.height = src->height;
-        dst3_2.format = mapToPixelFormat(src->format);
         dst3_2.usage = mapToConsumerUsage(cam3stream->getUsage());
-        dst3_2.dataSpace = mapToHidlDataspace(src->data_space);
         dst3_2.rotation = mapToStreamRotation((camera3_stream_rotation_t) src->rotation);
+        // For HidlSession version 3.5 or newer, the format and dataSpace sent
+        // to HAL are original, not the overriden ones.
+        if (mHidlSession_3_5 != nullptr) {
+            dst3_2.format = mapToPixelFormat(cam3stream->isFormatOverridden() ?
+                    cam3stream->getOriginalFormat() : src->format);
+            dst3_2.dataSpace = mapToHidlDataspace(cam3stream->isDataSpaceOverridden() ?
+                    cam3stream->getOriginalDataSpace() : src->data_space);
+        } else {
+            dst3_2.format = mapToPixelFormat(src->format);
+            dst3_2.dataSpace = mapToHidlDataspace(src->data_space);
+        }
         dst3_4.v3_2 = dst3_2;
         dst3_4.bufferSize = bufferSizes[i];
         if (src->physical_camera_id != nullptr) {
@@ -3602,26 +4256,48 @@
 
     // Invoke configureStreams
     device::V3_3::HalStreamConfiguration finalConfiguration;
+    device::V3_4::HalStreamConfiguration finalConfiguration3_4;
     common::V1_0::Status status;
 
-    // See if we have v3.4 or v3.3 HAL
-    if (mHidlSession_3_4 != nullptr) {
-        // We do; use v3.4 for the call
-        ALOGV("%s: v3.4 device found", __FUNCTION__);
-        device::V3_4::HalStreamConfiguration finalConfiguration3_4;
-        auto err = mHidlSession_3_4->configureStreams_3_4(requestedConfiguration3_4,
-            [&status, &finalConfiguration3_4]
+    auto configStream34Cb = [&status, &finalConfiguration3_4]
             (common::V1_0::Status s, const device::V3_4::HalStreamConfiguration& halConfiguration) {
                 finalConfiguration3_4 = halConfiguration;
                 status = s;
-            });
-        if (!err.isOk()) {
-            ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
-            return DEAD_OBJECT;
+            };
+
+    auto postprocConfigStream34 = [&finalConfiguration, &finalConfiguration3_4]
+            (hardware::Return<void>& err) -> status_t {
+                if (!err.isOk()) {
+                    ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
+                    return DEAD_OBJECT;
+                }
+                finalConfiguration.streams.resize(finalConfiguration3_4.streams.size());
+                for (size_t i = 0; i < finalConfiguration3_4.streams.size(); i++) {
+                    finalConfiguration.streams[i] = finalConfiguration3_4.streams[i].v3_3;
+                }
+                return OK;
+            };
+
+    // See which version of HAL we have
+    if (mHidlSession_3_5 != nullptr) {
+        ALOGV("%s: v3.5 device found", __FUNCTION__);
+        device::V3_5::StreamConfiguration requestedConfiguration3_5;
+        requestedConfiguration3_5.v3_4 = requestedConfiguration3_4;
+        requestedConfiguration3_5.streamConfigCounter = mNextStreamConfigCounter++;
+        auto err = mHidlSession_3_5->configureStreams_3_5(
+                requestedConfiguration3_5, configStream34Cb);
+        res = postprocConfigStream34(err);
+        if (res != OK) {
+            return res;
         }
-        finalConfiguration.streams.resize(finalConfiguration3_4.streams.size());
-        for (size_t i = 0; i < finalConfiguration3_4.streams.size(); i++) {
-            finalConfiguration.streams[i] = finalConfiguration3_4.streams[i].v3_3;
+    } else if (mHidlSession_3_4 != nullptr) {
+        // We do; use v3.4 for the call
+        ALOGV("%s: v3.4 device found", __FUNCTION__);
+        auto err = mHidlSession_3_4->configureStreams_3_4(
+                requestedConfiguration3_4, configStream34Cb);
+        res = postprocConfigStream34(err);
+        if (res != OK) {
+            return res;
         }
     } else if (mHidlSession_3_3 != nullptr) {
         // We do; use v3.3 for the call
@@ -3671,12 +4347,13 @@
         // Start scan at i, with the assumption that the stream order matches
         size_t realIdx = i;
         bool found = false;
-        for (size_t idx = 0; idx < finalConfiguration.streams.size(); idx++) {
+        size_t halStreamCount = finalConfiguration.streams.size();
+        for (size_t idx = 0; idx < halStreamCount; idx++) {
             if (finalConfiguration.streams[realIdx].v3_2.id == streamId) {
                 found = true;
                 break;
             }
-            realIdx = (realIdx >= finalConfiguration.streams.size()) ? 0 : realIdx + 1;
+            realIdx = (realIdx >= halStreamCount - 1) ? 0 : realIdx + 1;
         }
         if (!found) {
             ALOGE("%s: Stream %d not found in stream configuration response from HAL",
@@ -3686,12 +4363,12 @@
         device::V3_3::HalStream &src = finalConfiguration.streams[realIdx];
 
         Camera3Stream* dstStream = Camera3Stream::cast(dst);
-        dstStream->setFormatOverride(false);
-        dstStream->setDataSpaceOverride(false);
         int overrideFormat = mapToFrameworkFormat(src.v3_2.overrideFormat);
         android_dataspace overrideDataSpace = mapToFrameworkDataspace(src.overrideDataSpace);
 
-        if (dst->format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
+        if (dstStream->getOriginalFormat() != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
+            dstStream->setFormatOverride(false);
+            dstStream->setDataSpaceOverride(false);
             if (dst->format != overrideFormat) {
                 ALOGE("%s: Stream %d: Format override not allowed for format 0x%x", __FUNCTION__,
                         streamId, dst->format);
@@ -3701,10 +4378,13 @@
                         streamId, dst->format);
             }
         } else {
-            dstStream->setFormatOverride((dst->format != overrideFormat) ? true : false);
-            dstStream->setDataSpaceOverride((dst->data_space != overrideDataSpace) ? true : false);
-
+            bool needFormatOverride =
+                    requestedConfiguration3_2.streams[i].format != src.v3_2.overrideFormat;
+            bool needDataspaceOverride =
+                    requestedConfiguration3_2.streams[i].dataSpace != src.overrideDataSpace;
             // Override allowed with IMPLEMENTATION_DEFINED
+            dstStream->setFormatOverride(needFormatOverride);
+            dstStream->setDataSpaceOverride(needDataspaceOverride);
             dst->format = overrideFormat;
             dst->data_space = overrideDataSpace;
         }
@@ -3733,14 +4413,15 @@
     return res;
 }
 
-void Camera3Device::HalInterface::wrapAsHidlRequest(camera3_capture_request_t* request,
+status_t Camera3Device::HalInterface::wrapAsHidlRequest(camera3_capture_request_t* request,
         /*out*/device::V3_2::CaptureRequest* captureRequest,
-        /*out*/std::vector<native_handle_t*>* handlesCreated) {
+        /*out*/std::vector<native_handle_t*>* handlesCreated,
+        /*out*/std::vector<std::pair<int32_t, int32_t>>* inflightBuffers) {
     ATRACE_CALL();
-    if (captureRequest == nullptr || handlesCreated == nullptr) {
-        ALOGE("%s: captureRequest (%p) and handlesCreated (%p) must not be null",
-                __FUNCTION__, captureRequest, handlesCreated);
-        return;
+    if (captureRequest == nullptr || handlesCreated == nullptr || inflightBuffers == nullptr) {
+        ALOGE("%s: captureRequest (%p), handlesCreated (%p), and inflightBuffers(%p) "
+                "must not be null", __FUNCTION__, captureRequest, handlesCreated, inflightBuffers);
+        return BAD_VALUE;
     }
 
     captureRequest->frameNumber = request->frame_number;
@@ -3769,8 +4450,8 @@
             captureRequest->inputBuffer.releaseFence = nullptr;
 
             pushInflightBufferLocked(captureRequest->frameNumber, streamId,
-                    request->input_buffer->buffer,
-                    request->input_buffer->acquire_fence);
+                    request->input_buffer->buffer);
+            inflightBuffers->push_back(std::make_pair(captureRequest->frameNumber, streamId));
         } else {
             captureRequest->inputBuffer.streamId = -1;
             captureRequest->inputBuffer.bufferId = BUFFER_ID_NO_BUFFER;
@@ -3781,26 +4462,57 @@
             const camera3_stream_buffer_t *src = request->output_buffers + i;
             StreamBuffer &dst = captureRequest->outputBuffers[i];
             int32_t streamId = Camera3Stream::cast(src->stream)->getId();
-            buffer_handle_t buf = *(src->buffer);
-            auto pair = getBufferId(buf, streamId);
-            bool isNewBuffer = pair.first;
-            dst.streamId = streamId;
-            dst.bufferId = pair.second;
-            dst.buffer = isNewBuffer ? buf : nullptr;
-            dst.status = BufferStatus::OK;
-            native_handle_t *acquireFence = nullptr;
-            if (src->acquire_fence != -1) {
-                acquireFence = native_handle_create(1,0);
-                acquireFence->data[0] = src->acquire_fence;
-                handlesCreated->push_back(acquireFence);
+            if (src->buffer != nullptr) {
+                buffer_handle_t buf = *(src->buffer);
+                auto pair = getBufferId(buf, streamId);
+                bool isNewBuffer = pair.first;
+                dst.bufferId = pair.second;
+                dst.buffer = isNewBuffer ? buf : nullptr;
+                native_handle_t *acquireFence = nullptr;
+                if (src->acquire_fence != -1) {
+                    acquireFence = native_handle_create(1,0);
+                    acquireFence->data[0] = src->acquire_fence;
+                    handlesCreated->push_back(acquireFence);
+                }
+                dst.acquireFence = acquireFence;
+            } else if (mUseHalBufManager) {
+                // HAL buffer management path
+                dst.bufferId = BUFFER_ID_NO_BUFFER;
+                dst.buffer = nullptr;
+                dst.acquireFence = nullptr;
+            } else {
+                ALOGE("%s: cannot send a null buffer in capture request!", __FUNCTION__);
+                return BAD_VALUE;
             }
-            dst.acquireFence = acquireFence;
+            dst.streamId = streamId;
+            dst.status = BufferStatus::OK;
             dst.releaseFence = nullptr;
 
-            pushInflightBufferLocked(captureRequest->frameNumber, streamId,
-                    src->buffer, src->acquire_fence);
+            // Output buffers are empty when using HAL buffer manager
+            if (!mUseHalBufManager) {
+                pushInflightBufferLocked(captureRequest->frameNumber, streamId, src->buffer);
+                inflightBuffers->push_back(std::make_pair(captureRequest->frameNumber, streamId));
+            }
         }
     }
+    return OK;
+}
+
+void Camera3Device::HalInterface::cleanupNativeHandles(
+        std::vector<native_handle_t*> *handles, bool closeFd) {
+    if (handles == nullptr) {
+        return;
+    }
+    if (closeFd) {
+        for (auto& handle : *handles) {
+            native_handle_close(handle);
+        }
+    }
+    for (auto& handle : *handles) {
+        native_handle_delete(handle);
+    }
+    handles->clear();
+    return;
 }
 
 status_t Camera3Device::HalInterface::processBatchCaptureRequests(
@@ -3823,13 +4535,21 @@
         captureRequests.resize(batchSize);
     }
     std::vector<native_handle_t*> handlesCreated;
+    std::vector<std::pair<int32_t, int32_t>> inflightBuffers;
 
+    status_t res = OK;
     for (size_t i = 0; i < batchSize; i++) {
         if (hidlSession_3_4 != nullptr) {
-            wrapAsHidlRequest(requests[i], /*out*/&captureRequests_3_4[i].v3_2,
-                    /*out*/&handlesCreated);
+            res = wrapAsHidlRequest(requests[i], /*out*/&captureRequests_3_4[i].v3_2,
+                    /*out*/&handlesCreated, /*out*/&inflightBuffers);
         } else {
-            wrapAsHidlRequest(requests[i], /*out*/&captureRequests[i], /*out*/&handlesCreated);
+            res = wrapAsHidlRequest(requests[i], /*out*/&captureRequests[i],
+                    /*out*/&handlesCreated, /*out*/&inflightBuffers);
+        }
+        if (res != OK) {
+            popInflightBuffers(inflightBuffers);
+            cleanupNativeHandles(&handlesCreated);
+            return res;
         }
     }
 
@@ -3911,46 +4631,43 @@
     }
 
     hardware::details::return_status err;
+    auto resultCallback =
+        [&status, &numRequestProcessed] (auto s, uint32_t n) {
+                status = s;
+                *numRequestProcessed = n;
+        };
     if (hidlSession_3_4 != nullptr) {
         err = hidlSession_3_4->processCaptureRequest_3_4(captureRequests_3_4, cachesToRemove,
-            [&status, &numRequestProcessed] (auto s, uint32_t n) {
-                status = s;
-                *numRequestProcessed = n;
-            });
+                                                         resultCallback);
     } else {
         err = mHidlSession->processCaptureRequest(captureRequests, cachesToRemove,
-            [&status, &numRequestProcessed] (auto s, uint32_t n) {
-                status = s;
-                *numRequestProcessed = n;
-            });
+                                                  resultCallback);
     }
     if (!err.isOk()) {
         ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
-        return DEAD_OBJECT;
+        status = common::V1_0::Status::CAMERA_DISCONNECTED;
     }
+
     if (status == common::V1_0::Status::OK && *numRequestProcessed != batchSize) {
         ALOGE("%s: processCaptureRequest returns OK but processed %d/%zu requests",
                 __FUNCTION__, *numRequestProcessed, batchSize);
         status = common::V1_0::Status::INTERNAL_ERROR;
     }
 
-    for (auto& handle : handlesCreated) {
-        native_handle_delete(handle);
+    res = CameraProviderManager::mapToStatusT(status);
+    if (res == OK) {
+        if (mHidlSession->isRemote()) {
+            // Only close acquire fence FDs when the HIDL transaction succeeds (so the FDs have been
+            // sent to camera HAL processes)
+            cleanupNativeHandles(&handlesCreated, /*closeFd*/true);
+        } else {
+            // In passthrough mode the FDs are now owned by HAL
+            cleanupNativeHandles(&handlesCreated);
+        }
+    } else {
+        popInflightBuffers(inflightBuffers);
+        cleanupNativeHandles(&handlesCreated);
     }
-    return CameraProviderManager::mapToStatusT(status);
-}
-
-status_t Camera3Device::HalInterface::processCaptureRequest(
-        camera3_capture_request_t *request) {
-    ATRACE_NAME("CameraHal::processCaptureRequest");
-    if (!valid()) return INVALID_OPERATION;
-    status_t res = OK;
-
-    uint32_t numRequestProcessed = 0;
-    std::vector<camera3_capture_request_t*> requests(1);
-    requests[0] = request;
-    res = processBatchCaptureRequests(requests, &numRequestProcessed);
-
     return res;
 }
 
@@ -3993,6 +4710,20 @@
     return res;
 }
 
+void Camera3Device::HalInterface::signalPipelineDrain(const std::vector<int>& streamIds) {
+    ATRACE_NAME("CameraHal::signalPipelineDrain");
+    if (!valid() || mHidlSession_3_5 == nullptr) {
+        ALOGE("%s called on invalid camera!", __FUNCTION__);
+        return;
+    }
+
+    auto err = mHidlSession_3_5->signalStreamFlush(streamIds, mNextStreamConfigCounter - 1);
+    if (!err.isOk()) {
+        ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
+        return;
+    }
+}
+
 void Camera3Device::HalInterface::getInflightBufferKeys(
         std::vector<std::pair<int32_t, int32_t>>* out) {
     std::lock_guard<std::mutex> lock(mInflightLock);
@@ -4007,11 +4738,21 @@
     return;
 }
 
+void Camera3Device::HalInterface::getInflightRequestBufferKeys(
+        std::vector<uint64_t>* out) {
+    std::lock_guard<std::mutex> lock(mRequestedBuffersLock);
+    out->clear();
+    out->reserve(mRequestedBuffers.size());
+    for (auto& pair : mRequestedBuffers) {
+        out->push_back(pair.first);
+    }
+    return;
+}
+
 status_t Camera3Device::HalInterface::pushInflightBufferLocked(
-        int32_t frameNumber, int32_t streamId, buffer_handle_t *buffer, int acquireFence) {
+        int32_t frameNumber, int32_t streamId, buffer_handle_t *buffer) {
     uint64_t key = static_cast<uint64_t>(frameNumber) << 32 | static_cast<uint64_t>(streamId);
-    auto pair = std::make_pair(buffer, acquireFence);
-    mInflightBufferMap[key] = pair;
+    mInflightBufferMap[key] = buffer;
     return OK;
 }
 
@@ -4023,16 +4764,58 @@
     uint64_t key = static_cast<uint64_t>(frameNumber) << 32 | static_cast<uint64_t>(streamId);
     auto it = mInflightBufferMap.find(key);
     if (it == mInflightBufferMap.end()) return NAME_NOT_FOUND;
-    auto pair = it->second;
-    *buffer = pair.first;
-    int acquireFence = pair.second;
-    if (acquireFence > 0) {
-        ::close(acquireFence);
+    if (buffer != nullptr) {
+        *buffer = it->second;
     }
     mInflightBufferMap.erase(it);
     return OK;
 }
 
+void Camera3Device::HalInterface::popInflightBuffers(
+        const std::vector<std::pair<int32_t, int32_t>>& buffers) {
+    for (const auto& pair : buffers) {
+        int32_t frameNumber = pair.first;
+        int32_t streamId = pair.second;
+        popInflightBuffer(frameNumber, streamId, nullptr);
+    }
+}
+
+status_t Camera3Device::HalInterface::pushInflightRequestBuffer(
+        uint64_t bufferId, buffer_handle_t* buf, int32_t streamId) {
+    std::lock_guard<std::mutex> lock(mRequestedBuffersLock);
+    auto pair = mRequestedBuffers.insert({bufferId, {streamId, buf}});
+    if (!pair.second) {
+        ALOGE("%s: bufId %" PRIu64 " is already inflight!",
+                __FUNCTION__, bufferId);
+        return BAD_VALUE;
+    }
+    return OK;
+}
+
+// Find and pop a buffer_handle_t based on bufferId
+status_t Camera3Device::HalInterface::popInflightRequestBuffer(
+        uint64_t bufferId,
+        /*out*/ buffer_handle_t** buffer,
+        /*optional out*/ int32_t* streamId) {
+    if (buffer == nullptr) {
+        ALOGE("%s: buffer (%p) must not be null", __FUNCTION__, buffer);
+        return BAD_VALUE;
+    }
+    std::lock_guard<std::mutex> lock(mRequestedBuffersLock);
+    auto it = mRequestedBuffers.find(bufferId);
+    if (it == mRequestedBuffers.end()) {
+        ALOGE("%s: bufId %" PRIu64 " is not inflight!",
+                __FUNCTION__, bufferId);
+        return BAD_VALUE;
+    }
+    *buffer = it->second.second;
+    if (streamId != nullptr) {
+        *streamId = it->second.first;
+    }
+    mRequestedBuffers.erase(it);
+    return OK;
+}
+
 std::pair<bool, uint64_t> Camera3Device::HalInterface::getBufferId(
         const buffer_handle_t& buf, int streamId) {
     std::lock_guard<std::mutex> lock(mBufferIdMapLock);
@@ -4067,7 +4850,7 @@
                 __FUNCTION__, handle, streamId);
         return;
     } else {
-        bufferId =  it->second;
+        bufferId = it->second;
         bIdMap.erase(it);
         ALOGV("%s: stream %d now have %zu buffer caches after removing buf %p",
                 __FUNCTION__, streamId, bIdMap.size(), handle);
@@ -4075,13 +4858,30 @@
     mFreedBuffers.push_back(std::make_pair(streamId, bufferId));
 }
 
+void Camera3Device::HalInterface::onStreamReConfigured(int streamId) {
+    std::lock_guard<std::mutex> lock(mBufferIdMapLock);
+    auto mapIt = mBufferIdMaps.find(streamId);
+    if (mapIt == mBufferIdMaps.end()) {
+        ALOGE("%s: streamId %d not found!", __FUNCTION__, streamId);
+        return;
+    }
+
+    BufferIdMap& bIdMap = mapIt->second;
+    for (const auto& it : bIdMap) {
+        uint64_t bufferId = it.second;
+        mFreedBuffers.push_back(std::make_pair(streamId, bufferId));
+    }
+    bIdMap.clear();
+}
+
 /**
  * RequestThread inner class methods
  */
 
 Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
         sp<StatusTracker> statusTracker,
-        sp<HalInterface> interface, const Vector<int32_t>& sessionParamKeys) :
+        sp<HalInterface> interface, const Vector<int32_t>& sessionParamKeys,
+        bool useHalBufManager) :
         Thread(/*canCallJava*/false),
         mParent(parent),
         mStatusTracker(statusTracker),
@@ -4091,6 +4891,7 @@
         mReconfigured(false),
         mDoPause(false),
         mPaused(true),
+        mNotifyPipelineDrain(false),
         mFrameNumber(0),
         mLatestRequestId(NAME_NOT_FOUND),
         mCurrentAfTriggerId(0),
@@ -4101,7 +4902,8 @@
         mConstrainedMode(false),
         mRequestLatency(kRequestLatencyBinSize),
         mSessionParamKeys(sessionParamKeys),
-        mLatestSessionParams(sessionParamKeys.size()) {
+        mLatestSessionParams(sessionParamKeys.size()),
+        mUseHalBufManager(useHalBufManager) {
     mStatusId = statusTracker->addComponent();
 }
 
@@ -4391,28 +5193,7 @@
         NextRequest& nextRequest = mNextRequests.editItemAt(i);
         nextRequest.submitted = true;
 
-
-        // Update the latest request sent to HAL
-        if (nextRequest.halRequest.settings != NULL) { // Don't update if they were unchanged
-            Mutex::Autolock al(mLatestRequestMutex);
-
-            camera_metadata_t* cloned = clone_camera_metadata(nextRequest.halRequest.settings);
-            mLatestRequest.acquire(cloned);
-
-            sp<Camera3Device> parent = mParent.promote();
-            if (parent != NULL) {
-                parent->monitorMetadata(TagMonitor::REQUEST,
-                        nextRequest.halRequest.frame_number,
-                        0, mLatestRequest);
-            }
-        }
-
-        if (nextRequest.halRequest.settings != NULL) {
-            nextRequest.captureRequest->mSettingsList.begin()->metadata.unlock(
-                    nextRequest.halRequest.settings);
-        }
-
-        cleanupPhysicalSettings(nextRequest.captureRequest, &nextRequest.halRequest);
+        updateNextRequest(nextRequest);
 
         if (!triggerRemoveFailed) {
             // Remove any previously queued triggers (after unlock)
@@ -4445,62 +5226,6 @@
     return true;
 }
 
-bool Camera3Device::RequestThread::sendRequestsOneByOne() {
-    status_t res;
-
-    for (auto& nextRequest : mNextRequests) {
-        // Submit request and block until ready for next one
-        ATRACE_ASYNC_BEGIN("frame capture", nextRequest.halRequest.frame_number);
-        res = mInterface->processCaptureRequest(&nextRequest.halRequest);
-
-        if (res != OK) {
-            // Should only get a failure here for malformed requests or device-level
-            // errors, so consider all errors fatal.  Bad metadata failures should
-            // come through notify.
-            SET_ERR("RequestThread: Unable to submit capture request %d to HAL"
-                    " device: %s (%d)", nextRequest.halRequest.frame_number, strerror(-res),
-                    res);
-            cleanUpFailedRequests(/*sendRequestError*/ false);
-            return false;
-        }
-
-        // Mark that the request has be submitted successfully.
-        nextRequest.submitted = true;
-
-        // Update the latest request sent to HAL
-        if (nextRequest.halRequest.settings != NULL) { // Don't update if they were unchanged
-            Mutex::Autolock al(mLatestRequestMutex);
-
-            camera_metadata_t* cloned = clone_camera_metadata(nextRequest.halRequest.settings);
-            mLatestRequest.acquire(cloned);
-
-            sp<Camera3Device> parent = mParent.promote();
-            if (parent != NULL) {
-                parent->monitorMetadata(TagMonitor::REQUEST, nextRequest.halRequest.frame_number,
-                        0, mLatestRequest);
-            }
-        }
-
-        if (nextRequest.halRequest.settings != NULL) {
-            nextRequest.captureRequest->mSettingsList.begin()->metadata.unlock(
-                    nextRequest.halRequest.settings);
-        }
-
-        cleanupPhysicalSettings(nextRequest.captureRequest, &nextRequest.halRequest);
-
-        // Remove any previously queued triggers (after unlock)
-        res = removeTriggers(mPrevRequest);
-        if (res != OK) {
-            SET_ERR("RequestThread: Unable to remove triggers "
-                  "(capture request %d, HAL device: %s (%d)",
-                  nextRequest.halRequest.frame_number, strerror(-res), res);
-            cleanUpFailedRequests(/*sendRequestError*/ false);
-            return false;
-        }
-    }
-    return true;
-}
-
 nsecs_t Camera3Device::RequestThread::calculateMaxExpectedDuration(const camera_metadata_t *request) {
     nsecs_t maxExpectedDuration = kDefaultExpectedDuration;
     camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
@@ -4548,13 +5273,45 @@
     return false;
 }
 
+void Camera3Device::RequestThread::updateNextRequest(NextRequest& nextRequest) {
+    // Update the latest request sent to HAL
+    if (nextRequest.halRequest.settings != NULL) { // Don't update if they were unchanged
+        Mutex::Autolock al(mLatestRequestMutex);
+
+        camera_metadata_t* cloned = clone_camera_metadata(nextRequest.halRequest.settings);
+        mLatestRequest.acquire(cloned);
+
+        mLatestPhysicalRequest.clear();
+        for (uint32_t i = 0; i < nextRequest.halRequest.num_physcam_settings; i++) {
+            cloned = clone_camera_metadata(nextRequest.halRequest.physcam_settings[i]);
+            mLatestPhysicalRequest.emplace(nextRequest.halRequest.physcam_id[i],
+                    CameraMetadata(cloned));
+        }
+
+        sp<Camera3Device> parent = mParent.promote();
+        if (parent != NULL) {
+            parent->monitorMetadata(TagMonitor::REQUEST,
+                    nextRequest.halRequest.frame_number,
+                    0, mLatestRequest, mLatestPhysicalRequest);
+        }
+    }
+
+    if (nextRequest.halRequest.settings != NULL) {
+        nextRequest.captureRequest->mSettingsList.begin()->metadata.unlock(
+                nextRequest.halRequest.settings);
+    }
+
+    cleanupPhysicalSettings(nextRequest.captureRequest, &nextRequest.halRequest);
+}
+
 bool Camera3Device::RequestThread::updateSessionParameters(const CameraMetadata& settings) {
     ATRACE_CALL();
     bool updatesDetected = false;
 
+    CameraMetadata updatedParams(mLatestSessionParams);
     for (auto tag : mSessionParamKeys) {
         camera_metadata_ro_entry entry = settings.find(tag);
-        camera_metadata_entry lastEntry = mLatestSessionParams.find(tag);
+        camera_metadata_entry lastEntry = updatedParams.find(tag);
 
         if (entry.count > 0) {
             bool isDifferent = false;
@@ -4583,17 +5340,26 @@
                 if (!skipHFRTargetFPSUpdate(tag, entry, lastEntry)) {
                     updatesDetected = true;
                 }
-                mLatestSessionParams.update(entry);
+                updatedParams.update(entry);
             }
         } else if (lastEntry.count > 0) {
             // Value has been removed
             ALOGV("%s: Session parameter tag id %d removed", __FUNCTION__, tag);
-            mLatestSessionParams.erase(tag);
+            updatedParams.erase(tag);
             updatesDetected = true;
         }
     }
 
-    return updatesDetected;
+    bool reconfigureRequired;
+    if (updatesDetected) {
+        reconfigureRequired = mInterface->isReconfigurationRequired(mLatestSessionParams,
+                updatedParams);
+        mLatestSessionParams = updatedParams;
+    } else {
+        reconfigureRequired = false;
+    }
+
+    return reconfigureRequired;
 }
 
 bool Camera3Device::RequestThread::threadLoop() {
@@ -4706,13 +5472,15 @@
     ALOGVV("%s: %d: submitting %zu requests in a batch.", __FUNCTION__, __LINE__,
             mNextRequests.size());
 
+    sp<Camera3Device> parent = mParent.promote();
+    if (parent != nullptr) {
+        parent->mRequestBufferSM.onSubmittingRequest();
+    }
+
     bool submitRequestSuccess = false;
     nsecs_t tRequestStart = systemTime(SYSTEM_TIME_MONOTONIC);
-    if (mInterface->supportBatchRequest()) {
-        submitRequestSuccess = sendRequestsBatch();
-    } else {
-        submitRequestSuccess = sendRequestsOneByOne();
-    }
+    submitRequestSuccess = sendRequestsBatch();
+
     nsecs_t tRequestEnd = systemTime(SYSTEM_TIME_MONOTONIC);
     mRequestLatency.add(tRequestStart, tRequestEnd);
 
@@ -4732,6 +5500,7 @@
 status_t Camera3Device::RequestThread::prepareHalRequests() {
     ATRACE_CALL();
 
+    bool batchedRequest = mNextRequests[0].captureRequest->mBatchSize > 1;
     for (size_t i = 0; i < mNextRequests.size(); i++) {
         auto& nextRequest = mNextRequests.editItemAt(i);
         sp<CaptureRequest> captureRequest = nextRequest.captureRequest;
@@ -4755,7 +5524,10 @@
         mPrevTriggers = triggerCount;
 
         // If the request is the same as last, or we had triggers last time
-        bool newRequest = mPrevRequest != captureRequest || triggersMixedIn;
+        bool newRequest = (mPrevRequest != captureRequest || triggersMixedIn) &&
+                // Request settings are all the same within one batch, so only treat the first
+                // request in a batch as new
+                !(batchedRequest && i > 0);
         if (newRequest) {
             /**
              * HAL workaround:
@@ -4773,13 +5545,21 @@
                 // Correct metadata regions for distortion correction if enabled
                 sp<Camera3Device> parent = mParent.promote();
                 if (parent != nullptr) {
-                    res = parent->mDistortionMapper.correctCaptureRequest(
-                        &(captureRequest->mSettingsList.begin()->metadata));
-                    if (res != OK) {
-                        SET_ERR("RequestThread: Unable to correct capture requests "
-                                "for lens distortion for request %d: %s (%d)",
-                                halRequest->frame_number, strerror(-res), res);
-                        return INVALID_OPERATION;
+                    List<PhysicalCameraSettings>::iterator it;
+                    for (it = captureRequest->mSettingsList.begin();
+                            it != captureRequest->mSettingsList.end(); it++) {
+                        if (parent->mDistortionMappers.find(it->cameraId) ==
+                                parent->mDistortionMappers.end()) {
+                            continue;
+                        }
+                        res = parent->mDistortionMappers[it->cameraId].correctCaptureRequest(
+                            &(it->metadata));
+                        if (res != OK) {
+                            SET_ERR("RequestThread: Unable to correct capture requests "
+                                    "for lens distortion for request %d: %s (%d)",
+                                    halRequest->frame_number, strerror(-res), res);
+                            return INVALID_OPERATION;
+                        }
                     }
                 }
             }
@@ -4847,15 +5627,28 @@
                 captureRequest->mOutputStreams.size());
         halRequest->output_buffers = outputBuffers->array();
         std::set<String8> requestedPhysicalCameras;
+
+        sp<Camera3Device> parent = mParent.promote();
+        if (parent == NULL) {
+            // Should not happen, and nowhere to send errors to, so just log it
+            CLOGE("RequestThread: Parent is gone");
+            return INVALID_OPERATION;
+        }
+        nsecs_t waitDuration = kBaseGetBufferWait + parent->getExpectedInFlightDuration();
+
+        SurfaceMap uniqueSurfaceIdMap;
         for (size_t j = 0; j < captureRequest->mOutputStreams.size(); j++) {
-            sp<Camera3OutputStreamInterface> outputStream = captureRequest->mOutputStreams.editItemAt(j);
+            sp<Camera3OutputStreamInterface> outputStream =
+                    captureRequest->mOutputStreams.editItemAt(j);
+            int streamId = outputStream->getId();
 
             // Prepare video buffers for high speed recording on the first video request.
             if (mPrepareVideoStream && outputStream->isVideoStream()) {
                 // Only try to prepare video stream on the first video request.
                 mPrepareVideoStream = false;
 
-                res = outputStream->startPrepare(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX);
+                res = outputStream->startPrepare(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX,
+                        false /*blockRequest*/);
                 while (res == NOT_ENOUGH_DATA) {
                     res = outputStream->prepareNextBuffer();
                 }
@@ -4866,16 +5659,61 @@
                 }
             }
 
-            res = outputStream->getBuffer(&outputBuffers->editItemAt(j),
-                    captureRequest->mOutputSurfaces[j]);
-            if (res != OK) {
-                // Can't get output buffer from gralloc queue - this could be due to
-                // abandoned queue or other consumer misbehavior, so not a fatal
-                // error
-                ALOGE("RequestThread: Can't get output buffer, skipping request:"
-                        " %s (%d)", strerror(-res), res);
+            std::vector<size_t> uniqueSurfaceIds;
+            res = outputStream->getUniqueSurfaceIds(
+                    captureRequest->mOutputSurfaces[streamId],
+                    &uniqueSurfaceIds);
+            // INVALID_OPERATION is normal output for streams not supporting surfaceIds
+            if (res != OK && res != INVALID_OPERATION) {
+                ALOGE("%s: failed to query stream %d unique surface IDs",
+                        __FUNCTION__, streamId);
+                return res;
+            }
+            if (res == OK) {
+                uniqueSurfaceIdMap.insert({streamId, std::move(uniqueSurfaceIds)});
+            }
 
-                return TIMED_OUT;
+            if (mUseHalBufManager) {
+                if (outputStream->isAbandoned()) {
+                    ALOGV("%s: stream %d is abandoned, skipping request", __FUNCTION__, streamId);
+                    return TIMED_OUT;
+                }
+                // HAL will request buffer through requestStreamBuffer API
+                camera3_stream_buffer_t& buffer = outputBuffers->editItemAt(j);
+                buffer.stream = outputStream->asHalStream();
+                buffer.buffer = nullptr;
+                buffer.status = CAMERA3_BUFFER_STATUS_OK;
+                buffer.acquire_fence = -1;
+                buffer.release_fence = -1;
+            } else {
+                res = outputStream->getBuffer(&outputBuffers->editItemAt(j),
+                        waitDuration,
+                        captureRequest->mOutputSurfaces[streamId]);
+                if (res != OK) {
+                    // Can't get output buffer from gralloc queue - this could be due to
+                    // abandoned queue or other consumer misbehavior, so not a fatal
+                    // error
+                    ALOGV("RequestThread: Can't get output buffer, skipping request:"
+                            " %s (%d)", strerror(-res), res);
+
+                    return TIMED_OUT;
+                }
+            }
+
+            {
+                sp<Camera3Device> parent = mParent.promote();
+                if (parent != nullptr) {
+                    const String8& streamCameraId = outputStream->getPhysicalCameraId();
+                    for (const auto& settings : captureRequest->mSettingsList) {
+                        if ((streamCameraId.isEmpty() &&
+                                parent->getId() == settings.cameraId.c_str()) ||
+                                streamCameraId == settings.cameraId.c_str()) {
+                            outputStream->fireBufferRequestForFrameNumber(
+                                    captureRequest->mResultExtras.frameNumber,
+                                    settings.metadata);
+                        }
+                    }
+                }
             }
 
             String8 physicalCameraId = outputStream->getPhysicalCameraId();
@@ -4893,26 +5731,36 @@
         totalNumBuffers += halRequest->num_output_buffers;
 
         // Log request in the in-flight queue
-        sp<Camera3Device> parent = mParent.promote();
-        if (parent == NULL) {
-            // Should not happen, and nowhere to send errors to, so just log it
-            CLOGE("RequestThread: Parent is gone");
-            return INVALID_OPERATION;
-        }
-
         // If this request list is for constrained high speed recording (not
         // preview), and the current request is not the last one in the batch,
         // do not send callback to the app.
         bool hasCallback = true;
-        if (mNextRequests[0].captureRequest->mBatchSize > 1 && i != mNextRequests.size()-1) {
+        if (batchedRequest && i != mNextRequests.size()-1) {
             hasCallback = false;
         }
+        bool isStillCapture = false;
+        bool isZslCapture = false;
+        if (!mNextRequests[0].captureRequest->mSettingsList.begin()->metadata.isEmpty()) {
+            camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
+            find_camera_metadata_ro_entry(halRequest->settings, ANDROID_CONTROL_CAPTURE_INTENT, &e);
+            if ((e.count > 0) && (e.data.u8[0] == ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE)) {
+                isStillCapture = true;
+                ATRACE_ASYNC_BEGIN("still capture", mNextRequests[i].halRequest.frame_number);
+            }
+
+            find_camera_metadata_ro_entry(halRequest->settings, ANDROID_CONTROL_ENABLE_ZSL, &e);
+            if ((e.count > 0) && (e.data.u8[0] == ANDROID_CONTROL_ENABLE_ZSL_TRUE)) {
+                isZslCapture = true;
+            }
+        }
         res = parent->registerInFlight(halRequest->frame_number,
                 totalNumBuffers, captureRequest->mResultExtras,
                 /*hasInput*/halRequest->input_buffer != NULL,
                 hasCallback,
                 calculateMaxExpectedDuration(halRequest->settings),
-                requestedPhysicalCameras);
+                requestedPhysicalCameras, isStillCapture, isZslCapture,
+                (mUseHalBufManager) ? uniqueSurfaceIdMap :
+                                      SurfaceMap{});
         ALOGVV("%s: registered in flight requestId = %" PRId32 ", frameNumber = %" PRId64
                ", burstId = %" PRId32 ".",
                 __FUNCTION__,
@@ -4988,7 +5836,7 @@
             if (s.first == streamId) {
                 const auto &it = std::find(s.second.begin(), s.second.end(), surfaceId);
                 if (it != s.second.end()) {
-                  return true;
+                    return true;
                 }
             }
         }
@@ -4999,7 +5847,7 @@
             if (s.first == streamId) {
                 const auto &it = std::find(s.second.begin(), s.second.end(), surfaceId);
                 if (it != s.second.end()) {
-                  return true;
+                    return true;
                 }
             }
         }
@@ -5008,6 +5856,22 @@
     return false;
 }
 
+void Camera3Device::RequestThread::signalPipelineDrain(const std::vector<int>& streamIds) {
+    if (!mUseHalBufManager) {
+        ALOGE("%s called for camera device not supporting HAL buffer management", __FUNCTION__);
+        return;
+    }
+
+    Mutex::Autolock pl(mPauseLock);
+    if (mPaused) {
+        mInterface->signalPipelineDrain(streamIds);
+        return;
+    }
+    // If request thread is still busy, wait until paused then notify HAL
+    mNotifyPipelineDrain = true;
+    mStreamIdsToBeDrained = streamIds;
+}
+
 nsecs_t Camera3Device::getExpectedInFlightDuration() {
     ATRACE_CALL();
     Mutex::Autolock al(mInFlightLock);
@@ -5065,16 +5929,21 @@
             captureRequest->mInputStream->returnInputBuffer(captureRequest->mInputBuffer);
         }
 
-        for (size_t i = 0; i < halRequest->num_output_buffers; i++) {
-            //Buffers that failed processing could still have
-            //valid acquire fence.
-            int acquireFence = (*outputBuffers)[i].acquire_fence;
-            if (0 <= acquireFence) {
-                close(acquireFence);
-                outputBuffers->editItemAt(i).acquire_fence = -1;
+        // No output buffer can be returned when using HAL buffer manager
+        if (!mUseHalBufManager) {
+            for (size_t i = 0; i < halRequest->num_output_buffers; i++) {
+                //Buffers that failed processing could still have
+                //valid acquire fence.
+                int acquireFence = (*outputBuffers)[i].acquire_fence;
+                if (0 <= acquireFence) {
+                    close(acquireFence);
+                    outputBuffers->editItemAt(i).acquire_fence = -1;
+                }
+                outputBuffers->editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
+                captureRequest->mOutputStreams.editItemAt(i)->returnBuffer((*outputBuffers)[i], 0,
+                        /*timestampIncreasing*/true, std::vector<size_t> (),
+                        captureRequest->mResultExtras.frameNumber);
             }
-            outputBuffers->editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
-            captureRequest->mOutputStreams.editItemAt(i)->returnBuffer((*outputBuffers)[i], 0);
         }
 
         if (sendRequestError) {
@@ -5180,11 +6049,20 @@
             if (mPaused == false) {
                 ALOGV("%s: RequestThread: Going idle", __FUNCTION__);
                 mPaused = true;
+                if (mNotifyPipelineDrain) {
+                    mInterface->signalPipelineDrain(mStreamIdsToBeDrained);
+                    mNotifyPipelineDrain = false;
+                    mStreamIdsToBeDrained.clear();
+                }
                 // Let the tracker know
                 sp<StatusTracker> statusTracker = mStatusTracker.promote();
                 if (statusTracker != 0) {
                     statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
                 }
+                sp<Camera3Device> parent = mParent.promote();
+                if (parent != nullptr) {
+                    parent->mRequestBufferSM.onRequestThreadPaused();
+                }
             }
             // Stop waiting for now and let thread management happen
             return NULL;
@@ -5264,11 +6142,20 @@
         if (mPaused == false) {
             mPaused = true;
             ALOGV("%s: RequestThread: Paused", __FUNCTION__);
+            if (mNotifyPipelineDrain) {
+                mInterface->signalPipelineDrain(mStreamIdsToBeDrained);
+                mNotifyPipelineDrain = false;
+                mStreamIdsToBeDrained.clear();
+            }
             // Let the tracker know
             sp<StatusTracker> statusTracker = mStatusTracker.promote();
             if (statusTracker != 0) {
                 statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
             }
+            sp<Camera3Device> parent = mParent.promote();
+            if (parent != nullptr) {
+                parent->mRequestBufferSM.onRequestThreadPaused();
+            }
         }
 
         res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout);
@@ -5526,7 +6413,7 @@
     Mutex::Autolock l(mLock);
     sp<NotificationListener> listener = mListener.promote();
 
-    res = stream->startPrepare(maxCount);
+    res = stream->startPrepare(maxCount, true /*blockRequest*/);
     if (res == OK) {
         // No preparation needed, fire listener right off
         ALOGV("%s: Stream %d already prepared", __FUNCTION__, stream->getId());
@@ -5614,7 +6501,7 @@
 
     auto it = mPendingStreams.begin();
     for (; it != mPendingStreams.end();) {
-        res = it->second->startPrepare(it->first);
+        res = it->second->startPrepare(it->first, true /*blockRequest*/);
         if (res == OK) {
             if (listener != NULL) {
                 listener->notifyPrepared(it->second->getId());
@@ -5724,23 +6611,174 @@
     return true;
 }
 
-/**
- * Static callback forwarding methods from HAL to instance
- */
+status_t Camera3Device::RequestBufferStateMachine::initialize(
+        sp<camera3::StatusTracker> statusTracker) {
+    if (statusTracker == nullptr) {
+        ALOGE("%s: statusTracker is null", __FUNCTION__);
+        return BAD_VALUE;
+    }
 
-void Camera3Device::sProcessCaptureResult(const camera3_callback_ops *cb,
-        const camera3_capture_result *result) {
-    Camera3Device *d =
-            const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
-
-    d->processCaptureResult(result);
+    std::lock_guard<std::mutex> lock(mLock);
+    mStatusTracker = statusTracker;
+    mRequestBufferStatusId = statusTracker->addComponent();
+    return OK;
 }
 
-void Camera3Device::sNotify(const camera3_callback_ops *cb,
-        const camera3_notify_msg *msg) {
-    Camera3Device *d =
-            const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
-    d->notify(msg);
+bool Camera3Device::RequestBufferStateMachine::startRequestBuffer() {
+    std::lock_guard<std::mutex> lock(mLock);
+    if (mStatus == RB_STATUS_READY || mStatus == RB_STATUS_PENDING_STOP) {
+        mRequestBufferOngoing = true;
+        notifyTrackerLocked(/*active*/true);
+        return true;
+    }
+    return false;
+}
+
+void Camera3Device::RequestBufferStateMachine::endRequestBuffer() {
+    std::lock_guard<std::mutex> lock(mLock);
+    if (!mRequestBufferOngoing) {
+        ALOGE("%s called without a successful startRequestBuffer call first!", __FUNCTION__);
+        return;
+    }
+    mRequestBufferOngoing = false;
+    if (mStatus == RB_STATUS_PENDING_STOP) {
+        checkSwitchToStopLocked();
+    }
+    notifyTrackerLocked(/*active*/false);
+}
+
+void Camera3Device::RequestBufferStateMachine::onStreamsConfigured() {
+    std::lock_guard<std::mutex> lock(mLock);
+    mStatus = RB_STATUS_READY;
+    return;
+}
+
+void Camera3Device::RequestBufferStateMachine::onSubmittingRequest() {
+    std::lock_guard<std::mutex> lock(mLock);
+    mRequestThreadPaused = false;
+    // inflight map register actually happens in prepareHalRequest now, but it is close enough
+    // approximation.
+    mInflightMapEmpty = false;
+    if (mStatus == RB_STATUS_STOPPED) {
+        mStatus = RB_STATUS_READY;
+    }
+    return;
+}
+
+void Camera3Device::RequestBufferStateMachine::onRequestThreadPaused() {
+    std::lock_guard<std::mutex> lock(mLock);
+    mRequestThreadPaused = true;
+    if (mStatus == RB_STATUS_PENDING_STOP) {
+        checkSwitchToStopLocked();
+    }
+    return;
+}
+
+void Camera3Device::RequestBufferStateMachine::onInflightMapEmpty() {
+    std::lock_guard<std::mutex> lock(mLock);
+    mInflightMapEmpty = true;
+    if (mStatus == RB_STATUS_PENDING_STOP) {
+        checkSwitchToStopLocked();
+    }
+    return;
+}
+
+void Camera3Device::RequestBufferStateMachine::onWaitUntilIdle() {
+    std::lock_guard<std::mutex> lock(mLock);
+    if (!checkSwitchToStopLocked()) {
+        mStatus = RB_STATUS_PENDING_STOP;
+    }
+    return;
+}
+
+void Camera3Device::RequestBufferStateMachine::notifyTrackerLocked(bool active) {
+    sp<StatusTracker> statusTracker = mStatusTracker.promote();
+    if (statusTracker != nullptr) {
+        if (active) {
+            statusTracker->markComponentActive(mRequestBufferStatusId);
+        } else {
+            statusTracker->markComponentIdle(mRequestBufferStatusId, Fence::NO_FENCE);
+        }
+    }
+}
+
+bool Camera3Device::RequestBufferStateMachine::checkSwitchToStopLocked() {
+    if (mInflightMapEmpty && mRequestThreadPaused && !mRequestBufferOngoing) {
+        mStatus = RB_STATUS_STOPPED;
+        return true;
+    }
+    return false;
+}
+
+status_t Camera3Device::fixupMonochromeTags(const CameraMetadata& deviceInfo,
+        CameraMetadata& resultMetadata) {
+    status_t res = OK;
+    if (!mNeedFixupMonochromeTags) {
+        return res;
+    }
+
+    // Remove tags that are not applicable to monochrome camera.
+    int32_t tagsToRemove[] = {
+           ANDROID_SENSOR_GREEN_SPLIT,
+           ANDROID_SENSOR_NEUTRAL_COLOR_POINT,
+           ANDROID_COLOR_CORRECTION_MODE,
+           ANDROID_COLOR_CORRECTION_TRANSFORM,
+           ANDROID_COLOR_CORRECTION_GAINS,
+    };
+    for (auto tag : tagsToRemove) {
+        res = resultMetadata.erase(tag);
+        if (res != OK) {
+            ALOGE("%s: Failed to remove tag %d for monochrome camera", __FUNCTION__, tag);
+            return res;
+        }
+    }
+
+    // ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL
+    camera_metadata_entry blEntry = resultMetadata.find(ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL);
+    for (size_t i = 1; i < blEntry.count; i++) {
+        blEntry.data.f[i] = blEntry.data.f[0];
+    }
+
+    // ANDROID_SENSOR_NOISE_PROFILE
+    camera_metadata_entry npEntry = resultMetadata.find(ANDROID_SENSOR_NOISE_PROFILE);
+    if (npEntry.count > 0 && npEntry.count % 2 == 0) {
+        double np[] = {npEntry.data.d[0], npEntry.data.d[1]};
+        res = resultMetadata.update(ANDROID_SENSOR_NOISE_PROFILE, np, 2);
+        if (res != OK) {
+             ALOGE("%s: Failed to update SENSOR_NOISE_PROFILE: %s (%d)",
+                    __FUNCTION__, strerror(-res), res);
+            return res;
+        }
+    }
+
+    // ANDROID_STATISTICS_LENS_SHADING_MAP
+    camera_metadata_ro_entry lsSizeEntry = deviceInfo.find(ANDROID_LENS_INFO_SHADING_MAP_SIZE);
+    camera_metadata_entry lsEntry = resultMetadata.find(ANDROID_STATISTICS_LENS_SHADING_MAP);
+    if (lsSizeEntry.count == 2 && lsEntry.count > 0
+            && (int32_t)lsEntry.count == 4 * lsSizeEntry.data.i32[0] * lsSizeEntry.data.i32[1]) {
+        for (int32_t i = 0; i < lsSizeEntry.data.i32[0] * lsSizeEntry.data.i32[1]; i++) {
+            lsEntry.data.f[4*i+1] = lsEntry.data.f[4*i];
+            lsEntry.data.f[4*i+2] = lsEntry.data.f[4*i];
+            lsEntry.data.f[4*i+3] = lsEntry.data.f[4*i];
+        }
+    }
+
+    // ANDROID_TONEMAP_CURVE_BLUE
+    // ANDROID_TONEMAP_CURVE_GREEN
+    // ANDROID_TONEMAP_CURVE_RED
+    camera_metadata_entry tcbEntry = resultMetadata.find(ANDROID_TONEMAP_CURVE_BLUE);
+    camera_metadata_entry tcgEntry = resultMetadata.find(ANDROID_TONEMAP_CURVE_GREEN);
+    camera_metadata_entry tcrEntry = resultMetadata.find(ANDROID_TONEMAP_CURVE_RED);
+    if (tcbEntry.count > 0
+            && tcbEntry.count == tcgEntry.count
+            && tcbEntry.count == tcrEntry.count) {
+        for (size_t i = 0; i < tcbEntry.count; i++) {
+            tcbEntry.data.f[i] = tcrEntry.data.f[i];
+            tcgEntry.data.f[i] = tcrEntry.data.f[i];
+        }
+    }
+
+    return res;
 }
 
 }; // namespace android
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index d8fe19f..6e8ac84 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -33,10 +33,11 @@
 #include <android/hardware/camera/device/3.2/ICameraDeviceSession.h>
 #include <android/hardware/camera/device/3.3/ICameraDeviceSession.h>
 #include <android/hardware/camera/device/3.4/ICameraDeviceSession.h>
+#include <android/hardware/camera/device/3.5/ICameraDeviceSession.h>
 #include <android/hardware/camera/device/3.2/ICameraDeviceCallback.h>
 #include <android/hardware/camera/device/3.4/ICameraDeviceCallback.h>
+#include <android/hardware/camera/device/3.5/ICameraDeviceCallback.h>
 #include <fmq/MessageQueue.h>
-#include <hardware/camera3.h>
 
 #include <camera/CaptureResult.h>
 
@@ -50,20 +51,6 @@
 
 using android::camera3::OutputStreamInfo;
 
-/**
- * Function pointer types with C calling convention to
- * use for HAL callback functions.
- */
-extern "C" {
-    typedef void (callbacks_process_capture_result_t)(
-        const struct camera3_callback_ops *,
-        const camera3_capture_result_t *);
-
-    typedef void (callbacks_notify_t)(
-        const struct camera3_callback_ops *,
-        const camera3_notify_msg_t *);
-}
-
 namespace android {
 
 namespace camera3 {
@@ -80,8 +67,7 @@
  */
 class Camera3Device :
             public CameraDeviceBase,
-            virtual public hardware::camera::device::V3_4::ICameraDeviceCallback,
-            private camera3_callback_ops {
+            virtual public hardware::camera::device::V3_5::ICameraDeviceCallback {
   public:
 
     explicit Camera3Device(const String8& id);
@@ -101,6 +87,7 @@
     status_t disconnect() override;
     status_t dump(int fd, const Vector<String16> &args) override;
     const CameraMetadata& info() const override;
+    const CameraMetadata& info(const String8& physicalId) const override;
 
     // Capture and setStreamingRequest will configure streams if currently in
     // idle state
@@ -207,8 +194,32 @@
      */
     status_t dropStreamBuffers(bool dropping, int streamId) override;
 
+    /**
+     * Helper functions to map between framework and HIDL values
+     */
+    static hardware::graphics::common::V1_0::PixelFormat mapToPixelFormat(int frameworkFormat);
+    static hardware::camera::device::V3_2::DataspaceFlags mapToHidlDataspace(
+            android_dataspace dataSpace);
+    static hardware::camera::device::V3_2::BufferUsageFlags mapToConsumerUsage(uint64_t usage);
+    static hardware::camera::device::V3_2::StreamRotation mapToStreamRotation(
+            camera3_stream_rotation_t rotation);
+    // Returns a negative error code if the passed-in operation mode is not valid.
+    static status_t mapToStreamConfigurationMode(camera3_stream_configuration_mode_t operationMode,
+            /*out*/ hardware::camera::device::V3_2::StreamConfigurationMode *mode);
+    static camera3_buffer_status_t mapHidlBufferStatus(
+            hardware::camera::device::V3_2::BufferStatus status);
+    static int mapToFrameworkFormat(hardware::graphics::common::V1_0::PixelFormat pixelFormat);
+    static android_dataspace mapToFrameworkDataspace(
+            hardware::camera::device::V3_2::DataspaceFlags);
+    static uint64_t mapConsumerToFrameworkUsage(
+            hardware::camera::device::V3_2::BufferUsageFlags usage);
+    static uint64_t mapProducerToFrameworkUsage(
+            hardware::camera::device::V3_2::BufferUsageFlags usage);
+
   private:
 
+    status_t disconnectImpl();
+
     // internal typedefs
     using RequestMetadataQueue = hardware::MessageQueue<uint8_t, hardware::kSynchronizedReadWrite>;
     using ResultMetadataQueue  = hardware::MessageQueue<uint8_t, hardware::kSynchronizedReadWrite>;
@@ -220,6 +231,7 @@
     static const size_t        kInFlightWarnLimitHighSpeed = 256; // batch size 32 * pipe depth 8
     static const nsecs_t       kDefaultExpectedDuration = 100000000; // 100 ms
     static const nsecs_t       kMinInflightDuration = 5000000000; // 5 s
+    static const nsecs_t       kBaseGetBufferWait = 3000000000; // 3 sec.
     // SCHED_FIFO priority for request submission thread in HFR mode
     static const int           kRequestThreadPriority = 1;
 
@@ -266,7 +278,8 @@
     class HalInterface : public camera3::Camera3StreamBufferFreedListener {
       public:
         HalInterface(sp<hardware::camera::device::V3_2::ICameraDeviceSession> &session,
-                     std::shared_ptr<RequestMetadataQueue> queue);
+                     std::shared_ptr<RequestMetadataQueue> queue,
+                     bool useHalBufManager);
         HalInterface(const HalInterface &other);
         HalInterface();
 
@@ -276,9 +289,6 @@
         // Reset this HalInterface object (does not call close())
         void clear();
 
-        // Check if HalInterface support sending requests in batch
-        bool supportBatchRequest();
-
         // Calls into the HAL interface
 
         // Caller takes ownership of requestTemplate
@@ -287,7 +297,11 @@
         status_t configureStreams(const camera_metadata_t *sessionParams,
                 /*inout*/ camera3_stream_configuration *config,
                 const std::vector<uint32_t>& bufferSizes);
-        status_t processCaptureRequest(camera3_capture_request_t *request);
+
+        // When the call succeeds, the ownership of acquire fences in requests is transferred to
+        // HalInterface. More specifically, the current implementation will send the fence to
+        // HAL process and close the FD in cameraserver process. When the call fails, the ownership
+        // of the acquire fence still belongs to the caller.
         status_t processBatchCaptureRequests(
                 std::vector<camera3_capture_request_t*>& requests,
                 /*out*/uint32_t* numRequestProcessed);
@@ -295,14 +309,37 @@
         status_t dump(int fd);
         status_t close();
 
+        void signalPipelineDrain(const std::vector<int>& streamIds);
+        bool isReconfigurationRequired(CameraMetadata& oldSessionParams,
+                CameraMetadata& newSessionParams);
+
+        // method to extract buffer's unique ID
+        // return pair of (newlySeenBuffer?, bufferId)
+        std::pair<bool, uint64_t> getBufferId(const buffer_handle_t& buf, int streamId);
+
         // Find a buffer_handle_t based on frame number and stream ID
         status_t popInflightBuffer(int32_t frameNumber, int32_t streamId,
                 /*out*/ buffer_handle_t **buffer);
 
+        // Register a bufId (streamId, buffer_handle_t) to inflight request buffer
+        status_t pushInflightRequestBuffer(
+                uint64_t bufferId, buffer_handle_t* buf, int32_t streamId);
+
+        // Find a buffer_handle_t based on bufferId
+        status_t popInflightRequestBuffer(uint64_t bufferId,
+                /*out*/ buffer_handle_t** buffer,
+                /*optional out*/ int32_t* streamId = nullptr);
+
         // Get a vector of (frameNumber, streamId) pair of currently inflight
         // buffers
         void getInflightBufferKeys(std::vector<std::pair<int32_t, int32_t>>* out);
 
+        // Get a vector of bufferId of currently inflight buffers
+        void getInflightRequestBufferKeys(std::vector<uint64_t>* out);
+
+        void onStreamReConfigured(int streamId);
+
+        static const uint64_t BUFFER_ID_NO_BUFFER = 0;
       private:
         // Always valid
         sp<hardware::camera::device::V3_2::ICameraDeviceSession> mHidlSession;
@@ -310,6 +347,8 @@
         sp<hardware::camera::device::V3_3::ICameraDeviceSession> mHidlSession_3_3;
         // Valid if ICameraDeviceSession is @3.4 or newer
         sp<hardware::camera::device::V3_4::ICameraDeviceSession> mHidlSession_3_4;
+        // Valid if ICameraDeviceSession is @3.5 or newer
+        sp<hardware::camera::device::V3_5::ICameraDeviceSession> mHidlSession_3_5;
 
         std::shared_ptr<RequestMetadataQueue> mRequestMetadataQueue;
 
@@ -317,15 +356,23 @@
 
         // The output HIDL request still depends on input camera3_capture_request_t
         // Do not free input camera3_capture_request_t before output HIDL request
-        void wrapAsHidlRequest(camera3_capture_request_t* in,
+        status_t wrapAsHidlRequest(camera3_capture_request_t* in,
                 /*out*/hardware::camera::device::V3_2::CaptureRequest* out,
-                /*out*/std::vector<native_handle_t*>* handlesCreated);
+                /*out*/std::vector<native_handle_t*>* handlesCreated,
+                /*out*/std::vector<std::pair<int32_t, int32_t>>* inflightBuffers);
 
         status_t pushInflightBufferLocked(int32_t frameNumber, int32_t streamId,
-                buffer_handle_t *buffer, int acquireFence);
+                buffer_handle_t *buffer);
+
+        // Pop inflight buffers based on pairs of (frameNumber,streamId)
+        void popInflightBuffers(const std::vector<std::pair<int32_t, int32_t>>& buffers);
+
         // Cache of buffer handles keyed off (frameNumber << 32 | streamId)
-        // value is a pair of (buffer_handle_t*, acquire_fence FD)
-        std::unordered_map<uint64_t, std::pair<buffer_handle_t*, int>> mInflightBufferMap;
+        std::unordered_map<uint64_t, buffer_handle_t*> mInflightBufferMap;
+
+        // Delete and optionally close native handles and clear the input vector afterward
+        static void cleanupNativeHandles(
+                std::vector<native_handle_t*> *handles, bool closeFd = false);
 
         struct BufferHasher {
             size_t operator()(const buffer_handle_t& buf) const {
@@ -361,24 +408,25 @@
         // stream ID -> per stream buffer ID map
         std::unordered_map<int, BufferIdMap> mBufferIdMaps;
         uint64_t mNextBufferId = 1; // 0 means no buffer
-        static const uint64_t BUFFER_ID_NO_BUFFER = 0;
-
-        // method to extract buffer's unique ID
-        // TODO: we should switch to use gralloc mapper's getBackingStore API
-        //       once we ran in binderized gralloc mode, but before that is ready,
-        //       we need to rely on the conventional buffer queue behavior where
-        //       buffer_handle_t's FD won't change.
-        // return pair of (newlySeenBuffer?, bufferId)
-        std::pair<bool, uint64_t> getBufferId(const buffer_handle_t& buf, int streamId);
 
         virtual void onBufferFreed(int streamId, const native_handle_t* handle) override;
 
         std::vector<std::pair<int, uint64_t>> mFreedBuffers;
+
+        // Buffers given to HAL through requestStreamBuffer API
+        std::mutex mRequestedBuffersLock;
+        std::unordered_map<uint64_t, std::pair<int32_t, buffer_handle_t*>> mRequestedBuffers;
+
+        uint32_t mNextStreamConfigCounter = 1;
+
+        const bool mUseHalBufManager;
+        bool mIsReconfigurationQuerySupported;
     };
 
     sp<HalInterface> mInterface;
 
     CameraMetadata             mDeviceInfo;
+    std::unordered_map<std::string, CameraMetadata> mPhysicalDeviceInfoMap;
 
     CameraMetadata             mRequestTemplateCache[CAMERA3_TEMPLATE_COUNT];
 
@@ -407,9 +455,22 @@
     // Tracking cause of fatal errors when in STATUS_ERROR
     String8                    mErrorCause;
 
-    // Mapping of stream IDs to stream instances
-    typedef KeyedVector<int, sp<camera3::Camera3OutputStreamInterface> >
-            StreamSet;
+    // Synchronized mapping of stream IDs to stream instances
+    class StreamSet {
+      public:
+        status_t add(int streamId, sp<camera3::Camera3OutputStreamInterface>);
+        ssize_t remove(int streamId);
+        sp<camera3::Camera3OutputStreamInterface> get(int streamId);
+        // get by (underlying) vector index
+        sp<camera3::Camera3OutputStreamInterface> operator[] (size_t index);
+        size_t size() const;
+        std::vector<int> getStreamIds();
+        void clear();
+
+      private:
+        mutable std::mutex mLock;
+        KeyedVector<int, sp<camera3::Camera3OutputStreamInterface>> mData;
+    };
 
     StreamSet                  mOutputStreams;
     sp<camera3::Camera3Stream> mInputStream;
@@ -478,8 +539,9 @@
 
 
     /**
-     * Implementation of android::hardware::camera::device::V3_4::ICameraDeviceCallback
+     * Implementation of android::hardware::camera::device::V3_5::ICameraDeviceCallback
      */
+
     hardware::Return<void> processCaptureResult_3_4(
             const hardware::hidl_vec<
                     hardware::camera::device::V3_4::CaptureResult>& results) override;
@@ -490,11 +552,20 @@
             const hardware::hidl_vec<
                     hardware::camera::device::V3_2::NotifyMsg>& msgs) override;
 
+    hardware::Return<void> requestStreamBuffers(
+            const hardware::hidl_vec<
+                    hardware::camera::device::V3_5::BufferRequest>& bufReqs,
+            requestStreamBuffers_cb _hidl_cb) override;
+
+    hardware::Return<void> returnStreamBuffers(
+            const hardware::hidl_vec<
+                    hardware::camera::device::V3_2::StreamBuffer>& buffers) override;
+
     // Handle one capture result. Assume that mProcessCaptureResultLock is held.
     void processOneCaptureResultLocked(
             const hardware::camera::device::V3_2::CaptureResult& result,
             const hardware::hidl_vec<
-            hardware::camera::device::V3_4::PhysicalCameraMetadata> physicalCameraMetadatas);
+            hardware::camera::device::V3_4::PhysicalCameraMetadata> physicalCameraMetadata);
     status_t readOneCameraMetadataLocked(uint64_t fmqResultSize,
             hardware::camera::device::V3_2::CameraMetadata& resultMetadata,
             const hardware::camera::device::V3_2::CameraMetadata& result);
@@ -650,27 +721,6 @@
      */
     static nsecs_t getMonoToBoottimeOffset();
 
-    /**
-     * Helper functions to map between framework and HIDL values
-     */
-    static hardware::graphics::common::V1_0::PixelFormat mapToPixelFormat(int frameworkFormat);
-    static hardware::camera::device::V3_2::DataspaceFlags mapToHidlDataspace(
-            android_dataspace dataSpace);
-    static hardware::camera::device::V3_2::BufferUsageFlags mapToConsumerUsage(uint64_t usage);
-    static hardware::camera::device::V3_2::StreamRotation mapToStreamRotation(
-            camera3_stream_rotation_t rotation);
-    // Returns a negative error code if the passed-in operation mode is not valid.
-    static status_t mapToStreamConfigurationMode(camera3_stream_configuration_mode_t operationMode,
-            /*out*/ hardware::camera::device::V3_2::StreamConfigurationMode *mode);
-    static camera3_buffer_status_t mapHidlBufferStatus(hardware::camera::device::V3_2::BufferStatus status);
-    static int mapToFrameworkFormat(hardware::graphics::common::V1_0::PixelFormat pixelFormat);
-    static android_dataspace mapToFrameworkDataspace(
-            hardware::camera::device::V3_2::DataspaceFlags);
-    static uint64_t mapConsumerToFrameworkUsage(
-            hardware::camera::device::V3_2::BufferUsageFlags usage);
-    static uint64_t mapProducerToFrameworkUsage(
-            hardware::camera::device::V3_2::BufferUsageFlags usage);
-
     struct RequestTrigger {
         // Metadata tag number, e.g. android.control.aePrecaptureTrigger
         uint32_t metadataTag;
@@ -697,7 +747,9 @@
 
         RequestThread(wp<Camera3Device> parent,
                 sp<camera3::StatusTracker> statusTracker,
-                sp<HalInterface> interface, const Vector<int32_t>& sessionParamKeys);
+                sp<HalInterface> interface,
+                const Vector<int32_t>& sessionParamKeys,
+                bool useHalBufManager);
         ~RequestThread();
 
         void     setNotificationListener(wp<NotificationListener> listener);
@@ -785,6 +837,8 @@
             mRequestLatency.dump(fd, name);
         }
 
+        void signalPipelineDrain(const std::vector<int>& streamIds);
+
       protected:
 
         virtual bool threadLoop();
@@ -850,9 +904,6 @@
         // Clear repeating requests. Must be called with mRequestLock held.
         status_t clearRepeatingRequestsLocked(/*out*/ int64_t *lastFrameNumber = NULL);
 
-        // send request in mNextRequests to HAL one by one. Return true = sucssess
-        bool sendRequestsOneByOne();
-
         // send request in mNextRequests to HAL in a batch. Return true = sucssess
         bool sendRequestsBatch();
 
@@ -867,8 +918,8 @@
         bool skipHFRTargetFPSUpdate(int32_t tag, const camera_metadata_ro_entry_t& newEntry,
                 const camera_metadata_entry_t& currentEntry);
 
-        // Re-configure camera using the latest session parameters.
-        bool reconfigureCamera();
+        // Update next request sent to HAL
+        void updateNextRequest(NextRequest& nextRequest);
 
         wp<Camera3Device>  mParent;
         wp<camera3::StatusTracker>  mStatusTracker;
@@ -894,12 +945,13 @@
 
         bool               mReconfigured;
 
-        // Used by waitIfPaused, waitForNextRequest, and waitUntilPaused
+        // Used by waitIfPaused, waitForNextRequest, waitUntilPaused, and signalPipelineDrain
         Mutex              mPauseLock;
         bool               mDoPause;
         Condition          mDoPauseSignal;
         bool               mPaused;
-        Condition          mPausedSignal;
+        bool               mNotifyPipelineDrain;
+        std::vector<int>   mStreamIdsToBeDrained;
 
         sp<CaptureRequest> mPrevRequest;
         int32_t            mPrevTriggers;
@@ -911,6 +963,7 @@
         // android.request.id for latest process_capture_request
         int32_t            mLatestRequestId;
         CameraMetadata     mLatestRequest;
+        std::unordered_map<std::string, CameraMetadata> mLatestPhysicalRequest;
 
         typedef KeyedVector<uint32_t/*tag*/, RequestTrigger> TriggerMap;
         Mutex              mTriggerMutex;
@@ -932,6 +985,8 @@
 
         Vector<int32_t>    mSessionParamKeys;
         CameraMetadata     mLatestSessionParams;
+
+        const bool         mUseHalBufManager;
     };
     sp<RequestThread> mRequestThread;
 
@@ -992,6 +1047,15 @@
         // Map of physicalCameraId <-> Metadata
         std::vector<PhysicalCaptureResultInfo> physicalMetadatas;
 
+        // Indicates a still capture request.
+        bool stillCapture;
+
+        // Indicates a ZSL capture request
+        bool zslCapture;
+
+        // What shared surfaces an output should go to
+        SurfaceMap outputSurfaces;
+
         // Default constructor needed by KeyedVector
         InFlightRequest() :
                 shutterTimestamp(0),
@@ -1002,12 +1066,16 @@
                 hasInputBuffer(false),
                 hasCallback(true),
                 maxExpectedDuration(kDefaultExpectedDuration),
-                skipResultMetadata(false) {
+                skipResultMetadata(false),
+                stillCapture(false),
+                zslCapture(false) {
         }
 
         InFlightRequest(int numBuffers, CaptureResultExtras extras, bool hasInput,
                 bool hasAppCallback, nsecs_t maxDuration,
-                const std::set<String8>& physicalCameraIdSet) :
+                const std::set<String8>& physicalCameraIdSet, bool isStillCapture,
+                bool isZslCapture,
+                const SurfaceMap& outSurfaces = SurfaceMap{}) :
                 shutterTimestamp(0),
                 sensorTimestamp(0),
                 requestStatus(OK),
@@ -1018,7 +1086,10 @@
                 hasCallback(hasAppCallback),
                 maxExpectedDuration(maxDuration),
                 skipResultMetadata(false),
-                physicalCameraIds(physicalCameraIdSet) {
+                physicalCameraIds(physicalCameraIdSet),
+                stillCapture(isStillCapture),
+                zslCapture(isZslCapture),
+                outputSurfaces(outSurfaces) {
         }
     };
 
@@ -1032,10 +1103,11 @@
     nsecs_t                mExpectedInflightDuration = 0;
     int                    mInFlightStatusId;
 
-
     status_t registerInFlight(uint32_t frameNumber,
             int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput,
-            bool callback, nsecs_t maxExpectedDuration, std::set<String8>& physicalCameraIds);
+            bool callback, nsecs_t maxExpectedDuration, std::set<String8>& physicalCameraIds,
+            bool isStillCapture, bool isZslCapture,
+            const SurfaceMap& outputSurfaces);
 
     /**
      * Returns the maximum expected time it'll take for all currently in-flight
@@ -1120,10 +1192,14 @@
     uint32_t               mNextResultFrameNumber;
     // the minimal frame number of the next reprocess result
     uint32_t               mNextReprocessResultFrameNumber;
+    // the minimal frame number of the next ZSL still capture result
+    uint32_t               mNextZslStillResultFrameNumber;
     // the minimal frame number of the next non-reprocess shutter
     uint32_t               mNextShutterFrameNumber;
     // the minimal frame number of the next reprocess shutter
     uint32_t               mNextReprocessShutterFrameNumber;
+    // the minimal frame number of the next ZSL still capture shutter
+    uint32_t               mNextZslStillShutterFrameNumber;
     List<CaptureResult>   mResultQueue;
     Condition              mResultSignal;
     wp<NotificationListener>  mListener;
@@ -1145,7 +1221,11 @@
 
     // helper function to return the output buffers to the streams.
     void returnOutputBuffers(const camera3_stream_buffer_t *outputBuffers,
-            size_t numBuffers, nsecs_t timestamp);
+            size_t numBuffers, nsecs_t timestamp, bool timestampIncreasing = true,
+            // The following arguments are only meant for surface sharing use case
+            const SurfaceMap& outputSurfaces = SurfaceMap{},
+            // Used to send buffer error callback when failing to return buffer
+            const CaptureResultExtras &resultExtras = CaptureResultExtras{});
 
     // Send a partial capture result.
     void sendPartialCaptureResult(const camera_metadata_t * partialResult,
@@ -1156,7 +1236,8 @@
     void sendCaptureResult(CameraMetadata &pendingMetadata,
             CaptureResultExtras &resultExtras,
             CameraMetadata &collectedPartialResult, uint32_t frameNumber,
-            bool reprocess, const std::vector<PhysicalCaptureResultInfo>& physicalMetadatas);
+            bool reprocess, bool zslStillCapture,
+            const std::vector<PhysicalCaptureResultInfo>& physicalMetadatas);
 
     bool isLastFullResult(const InFlightRequest& inFlightRequest);
 
@@ -1183,8 +1264,10 @@
     /**
      * Distortion correction support
      */
-
-    camera3::DistortionMapper mDistortionMapper;
+    // Map from camera IDs to its corresponding distortion mapper. Only contains
+    // 1 ID if the device isn't a logical multi-camera. Otherwise contains both
+    // logical camera and its physical subcameras.
+    std::unordered_map<std::string, camera3::DistortionMapper> mDistortionMappers;
 
     // Debug tracker for metadata tag value changes
     // - Enabled with the -m <taglist> option to dumpsys, such as
@@ -1194,20 +1277,96 @@
     TagMonitor mTagMonitor;
 
     void monitorMetadata(TagMonitor::eventSource source, int64_t frameNumber,
-            nsecs_t timestamp, const CameraMetadata& metadata);
+            nsecs_t timestamp, const CameraMetadata& metadata,
+            const std::unordered_map<std::string, CameraMetadata>& physicalMetadata);
 
     metadata_vendor_id_t mVendorTagId;
 
     // Cached last requested template id
     int mLastTemplateId;
 
-    /**
-     * Static callback forwarding methods from HAL to instance
-     */
-    static callbacks_process_capture_result_t sProcessCaptureResult;
+    // Synchronizes access to status tracker between inflight updates and disconnect.
+    // b/79972865
+    Mutex mTrackerLock;
 
-    static callbacks_notify_t sNotify;
+    // Whether HAL request buffers through requestStreamBuffers API
+    bool mUseHalBufManager = false;
 
+    // Lock to ensure requestStreamBuffers() callbacks are serialized
+    std::mutex mRequestBufferInterfaceLock;
+
+    // The state machine to control when requestStreamBuffers should allow
+    // HAL to request buffers.
+    enum RequestBufferState {
+        /**
+         * This is the initial state.
+         * requestStreamBuffers call will return FAILED_CONFIGURING in this state.
+         * Will switch to RB_STATUS_READY after a successful configureStreams or
+         * processCaptureRequest call.
+         */
+        RB_STATUS_STOPPED,
+
+        /**
+         * requestStreamBuffers call will proceed in this state.
+         * When device is asked to stay idle via waitUntilStateThenRelock() call:
+         *     - Switch to RB_STATUS_STOPPED if there is no inflight requests and
+         *       request thread is paused.
+         *     - Switch to RB_STATUS_PENDING_STOP otherwise
+         */
+        RB_STATUS_READY,
+
+        /**
+         * requestStreamBuffers call will proceed in this state.
+         * Switch to RB_STATUS_STOPPED when all inflight requests are fulfilled
+         * and request thread is paused
+         */
+        RB_STATUS_PENDING_STOP,
+    };
+
+    class RequestBufferStateMachine {
+      public:
+        status_t initialize(sp<camera3::StatusTracker> statusTracker);
+
+        // Return if the state machine currently allows for requestBuffers
+        // If the state allows for it, mRequestBufferOngoing will be set to true
+        // and caller must call endRequestBuffer() later to unset the flag
+        bool startRequestBuffer();
+        void endRequestBuffer();
+
+        // Events triggered by application API call
+        void onStreamsConfigured();
+        void onWaitUntilIdle();
+
+        // Events usually triggered by hwBinder processCaptureResult callback thread
+        // But can also be triggered on request thread for failed request, or on
+        // hwbinder notify callback thread for shutter/error callbacks
+        void onInflightMapEmpty();
+
+        // Events triggered by RequestThread
+        void onSubmittingRequest();
+        void onRequestThreadPaused();
+
+      private:
+        void notifyTrackerLocked(bool active);
+
+        // Switch to STOPPED state and return true if all conditions allows for it.
+        // Otherwise do nothing and return false.
+        bool checkSwitchToStopLocked();
+
+        std::mutex mLock;
+        RequestBufferState mStatus = RB_STATUS_STOPPED;
+
+        bool mRequestThreadPaused = true;
+        bool mInflightMapEmpty = true;
+        bool mRequestBufferOngoing = false;
+
+        wp<camera3::StatusTracker> mStatusTracker;
+        int  mRequestBufferStatusId;
+    } mRequestBufferSM;
+
+    // Fix up result metadata for monochrome camera.
+    bool mNeedFixupMonochromeTags;
+    status_t fixupMonochromeTags(const CameraMetadata& deviceInfo, CameraMetadata& resultMetadata);
 }; // class Camera3Device
 
 }; // namespace android
diff --git a/services/camera/libcameraservice/device3/Camera3DummyStream.cpp b/services/camera/libcameraservice/device3/Camera3DummyStream.cpp
index fb1ff77..b637160 100644
--- a/services/camera/libcameraservice/device3/Camera3DummyStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3DummyStream.cpp
@@ -48,7 +48,7 @@
 
 status_t Camera3DummyStream::returnBufferLocked(
         const camera3_stream_buffer &,
-        nsecs_t) {
+        nsecs_t, const std::vector<size_t>&) {
     ATRACE_CALL();
     ALOGE("%s: Stream %d: Dummy stream cannot return buffers!", __FUNCTION__, mId);
     return INVALID_OPERATION;
@@ -58,6 +58,7 @@
             const camera3_stream_buffer &,
             nsecs_t,
             bool,
+            const std::vector<size_t>&,
             /*out*/
             sp<Fence>*) {
     ATRACE_CALL();
diff --git a/services/camera/libcameraservice/device3/Camera3DummyStream.h b/services/camera/libcameraservice/device3/Camera3DummyStream.h
index 4627548..4b67ea5 100644
--- a/services/camera/libcameraservice/device3/Camera3DummyStream.h
+++ b/services/camera/libcameraservice/device3/Camera3DummyStream.h
@@ -87,6 +87,9 @@
      */
     virtual ssize_t getSurfaceId(const sp<Surface> &/*surface*/) { return 0; }
 
+    virtual status_t getUniqueSurfaceIds(const std::vector<size_t>&,
+            /*out*/std::vector<size_t>*) { return INVALID_OPERATION; };
+
     /**
      * Update the stream output surfaces.
      */
@@ -104,6 +107,7 @@
             const camera3_stream_buffer &buffer,
             nsecs_t timestamp,
             bool output,
+            const std::vector<size_t>& surface_ids,
             /*out*/
             sp<Fence> *releaseFenceOut);
 
@@ -128,7 +132,7 @@
             const std::vector<size_t>& surface_ids = std::vector<size_t>());
     virtual status_t returnBufferLocked(
             const camera3_stream_buffer &buffer,
-            nsecs_t timestamp);
+            nsecs_t timestamp, const std::vector<size_t>& surface_ids);
 
     virtual status_t configureQueueLocked();
 
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
index 3c1e43d..ef0d919 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
@@ -82,6 +82,9 @@
     lines.appendFormat("      Max size: %zu\n", mMaxSize);
     lines.appendFormat("      Combined usage: %" PRIu64 ", max HAL buffers: %d\n",
             mUsage | consumerUsage, camera3_stream::max_buffers);
+    if (strlen(camera3_stream::physical_camera_id) > 0) {
+        lines.appendFormat("      Physical camera id: %s\n", camera3_stream::physical_camera_id);
+    }
     lines.appendFormat("      Frames produced: %d, last timestamp: %" PRId64 " ns\n",
             mFrameCount, mLastTimestamp);
     lines.appendFormat("      Total buffers: %zu, currently dequeued: %zu\n",
@@ -116,7 +119,7 @@
     return mTotalBufferCount;
 }
 
-size_t Camera3IOStreamBase::getHandoutOutputBufferCountLocked() {
+size_t Camera3IOStreamBase::getHandoutOutputBufferCountLocked() const {
     return mHandoutOutputBufferCount;
 }
 
@@ -219,7 +222,8 @@
 status_t Camera3IOStreamBase::returnAnyBufferLocked(
         const camera3_stream_buffer &buffer,
         nsecs_t timestamp,
-        bool output) {
+        bool output,
+        const std::vector<size_t>& surface_ids) {
     status_t res;
 
     // returnBuffer may be called from a raw pointer, not a sp<>, and we'll be
@@ -235,7 +239,7 @@
     }
 
     sp<Fence> releaseFence;
-    res = returnBufferCheckedLocked(buffer, timestamp, output,
+    res = returnBufferCheckedLocked(buffer, timestamp, output, surface_ids,
                                     &releaseFence);
     // Res may be an error, but we still want to decrement our owned count
     // to enable clean shutdown. So we'll just return the error but otherwise
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
index 0a31d44..750f64d 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
@@ -66,12 +66,14 @@
     status_t         returnAnyBufferLocked(
             const camera3_stream_buffer &buffer,
             nsecs_t timestamp,
-            bool output);
+            bool output,
+            const std::vector<size_t>& surface_ids = std::vector<size_t>());
 
     virtual status_t returnBufferCheckedLocked(
             const camera3_stream_buffer &buffer,
             nsecs_t timestamp,
             bool output,
+            const std::vector<size_t>& surface_ids,
             /*out*/
             sp<Fence> *releaseFenceOut) = 0;
 
@@ -82,7 +84,7 @@
 
     virtual size_t   getBufferCountLocked();
 
-    virtual size_t   getHandoutOutputBufferCountLocked();
+    virtual size_t   getHandoutOutputBufferCountLocked() const;
 
     virtual size_t   getHandoutInputBufferCountLocked();
 
diff --git a/services/camera/libcameraservice/device3/Camera3InputStream.cpp b/services/camera/libcameraservice/device3/Camera3InputStream.cpp
index 017d7be..fc83684 100644
--- a/services/camera/libcameraservice/device3/Camera3InputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3InputStream.cpp
@@ -98,6 +98,7 @@
             const camera3_stream_buffer &buffer,
             nsecs_t timestamp,
             bool output,
+            const std::vector<size_t>&,
             /*out*/
             sp<Fence> *releaseFenceOut) {
 
diff --git a/services/camera/libcameraservice/device3/Camera3InputStream.h b/services/camera/libcameraservice/device3/Camera3InputStream.h
index 0732464..97a627a 100644
--- a/services/camera/libcameraservice/device3/Camera3InputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3InputStream.h
@@ -62,6 +62,7 @@
             const camera3_stream_buffer &buffer,
             nsecs_t timestamp,
             bool output,
+            const std::vector<size_t>& surface_ids,
             /*out*/
             sp<Fence> *releaseFenceOut);
 
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 2c020a2..acb8b3c 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -187,16 +187,17 @@
 }
 
 status_t Camera3OutputStream::queueBufferToConsumer(sp<ANativeWindow>& consumer,
-            ANativeWindowBuffer* buffer, int anwReleaseFence) {
+            ANativeWindowBuffer* buffer, int anwReleaseFence,
+            const std::vector<size_t>&) {
     return consumer->queueBuffer(consumer.get(), buffer, anwReleaseFence);
 }
 
 status_t Camera3OutputStream::returnBufferLocked(
         const camera3_stream_buffer &buffer,
-        nsecs_t timestamp) {
+        nsecs_t timestamp, const std::vector<size_t>& surface_ids) {
     ATRACE_CALL();
 
-    status_t res = returnAnyBufferLocked(buffer, timestamp, /*output*/true);
+    status_t res = returnAnyBufferLocked(buffer, timestamp, /*output*/true, surface_ids);
 
     if (res != OK) {
         return res;
@@ -212,6 +213,7 @@
             const camera3_stream_buffer &buffer,
             nsecs_t timestamp,
             bool output,
+            const std::vector<size_t>& surface_ids,
             /*out*/
             sp<Fence> *releaseFenceOut) {
 
@@ -231,24 +233,27 @@
      * queueBuffer
      */
     sp<ANativeWindow> currentConsumer = mConsumer;
+    StreamState state = mState;
     mLock.unlock();
 
     ANativeWindowBuffer *anwBuffer = container_of(buffer.buffer, ANativeWindowBuffer, handle);
     /**
      * Return buffer back to ANativeWindow
      */
-    if (buffer.status == CAMERA3_BUFFER_STATUS_ERROR || mDropBuffers) {
+    if (buffer.status == CAMERA3_BUFFER_STATUS_ERROR || mDropBuffers || timestamp == 0) {
         // Cancel buffer
         if (mDropBuffers) {
             ALOGV("%s: Dropping a frame for stream %d.", __FUNCTION__, mId);
+        } else if (buffer.status == CAMERA3_BUFFER_STATUS_ERROR) {
+            ALOGV("%s: A frame is dropped for stream %d due to buffer error.", __FUNCTION__, mId);
         } else {
-            ALOGW("%s: A frame is dropped for stream %d due to buffer error.", __FUNCTION__, mId);
+            ALOGE("%s: Stream %d: timestamp shouldn't be 0", __FUNCTION__, mId);
         }
 
         res = currentConsumer->cancelBuffer(currentConsumer.get(),
                 anwBuffer,
                 anwReleaseFence);
-        if (res != OK) {
+        if (shouldLogError(res, state)) {
             ALOGE("%s: Stream %d: Error cancelling buffer to native window:"
                   " %s (%d)", __FUNCTION__, mId, strerror(-res), res);
         }
@@ -279,10 +284,10 @@
             return res;
         }
 
-        res = queueBufferToConsumer(currentConsumer, anwBuffer, anwReleaseFence);
-        if (res != OK) {
-            ALOGE("%s: Stream %d: Error queueing buffer to native window: "
-                  "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
+        res = queueBufferToConsumer(currentConsumer, anwBuffer, anwReleaseFence, surface_ids);
+        if (shouldLogError(res, state)) {
+            ALOGE("%s: Stream %d: Error queueing buffer to native window:"
+                  " %s (%d)", __FUNCTION__, mId, strerror(-res), res);
         }
     }
     mLock.lock();
@@ -355,7 +360,18 @@
     // Set dequeueBuffer/attachBuffer timeout if the consumer is not hw composer or hw texture.
     // We need skip these cases as timeout will disable the non-blocking (async) mode.
     if (!(isConsumedByHWComposer() || isConsumedByHWTexture())) {
-        mConsumer->setDequeueTimeout(kDequeueBufferTimeout);
+        if (mUseBufferManager) {
+            // When buffer manager is handling the buffer, we should have available buffers in
+            // buffer queue before we calls into dequeueBuffer because buffer manager is tracking
+            // free buffers.
+            // There are however some consumer side feature (ImageReader::discardFreeBuffers) that
+            // can discard free buffers without notifying buffer manager. We want the timeout to
+            // happen immediately here so buffer manager can try to update its internal state and
+            // try to allocate a buffer instead of waiting.
+            mConsumer->setDequeueTimeout(0);
+        } else {
+            mConsumer->setDequeueTimeout(kDequeueBufferTimeout);
+        }
     }
 
     return OK;
@@ -475,8 +491,11 @@
      * sets the mBufferManager if device version is > HAL3.2, which guarantees that the buffer
      * manager setup is skipped in below code. Note that HAL3.2 is also excluded here, as some
      * HAL3.2 devices may not support the dynamic buffer registeration.
+     * Also Camera3BufferManager does not support display/texture streams as they have its own
+     * buffer management logic.
      */
-    if (mBufferManager != 0 && mSetId > CAMERA3_STREAM_SET_ID_INVALID) {
+    if (mBufferManager != 0 && mSetId > CAMERA3_STREAM_SET_ID_INVALID &&
+            !(isConsumedByHWComposer() || isConsumedByHWTexture())) {
         uint64_t consumerUsage = 0;
         getEndpointUsage(&consumerUsage);
         StreamInfo streamInfo(
@@ -519,9 +538,12 @@
             // successful return.
             *anb = gb.get();
             res = mConsumer->attachBuffer(*anb);
-            if (res != OK) {
+            if (shouldLogError(res, mState)) {
                 ALOGE("%s: Stream %d: Can't attach the output buffer to this surface: %s (%d)",
                         __FUNCTION__, mId, strerror(-res), res);
+            }
+            if (res != OK) {
+                checkRetAndSetAbandonedLocked(res);
                 return res;
             }
             gotBufferFromManager = true;
@@ -558,35 +580,82 @@
         mDequeueBufferLatency.add(dequeueStart, dequeueEnd);
 
         mLock.lock();
-        if (res != OK) {
-            ALOGE("%s: Stream %d: Can't dequeue next output buffer: %s (%d)",
-                    __FUNCTION__, mId, strerror(-res), res);
 
-            // Only transition to STATE_ABANDONED from STATE_CONFIGURED. (If it is STATE_PREPARING,
-            // let prepareNextBuffer handle the error.)
-            if ((res == NO_INIT || res == DEAD_OBJECT) && mState == STATE_CONFIGURED) {
-                mState = STATE_ABANDONED;
+        if (mUseBufferManager && res == TIMED_OUT) {
+            checkRemovedBuffersLocked();
+
+            sp<GraphicBuffer> gb;
+            res = mBufferManager->getBufferForStream(
+                    getId(), getStreamSetId(), &gb, fenceFd, /*noFreeBuffer*/true);
+
+            if (res == OK) {
+                // Attach this buffer to the bufferQueue: the buffer will be in dequeue state after
+                // a successful return.
+                *anb = gb.get();
+                res = mConsumer->attachBuffer(*anb);
+                gotBufferFromManager = true;
+                ALOGV("Stream %d: Attached new buffer", getId());
+
+                if (res != OK) {
+                    if (shouldLogError(res, mState)) {
+                        ALOGE("%s: Stream %d: Can't attach the output buffer to this surface:"
+                                " %s (%d)", __FUNCTION__, mId, strerror(-res), res);
+                    }
+                    checkRetAndSetAbandonedLocked(res);
+                    return res;
+                }
+            } else {
+                ALOGE("%s: Stream %d: Can't get next output buffer from buffer manager:"
+                        " %s (%d)", __FUNCTION__, mId, strerror(-res), res);
+                return res;
             }
-
+        } else if (res != OK) {
+            if (shouldLogError(res, mState)) {
+                ALOGE("%s: Stream %d: Can't dequeue next output buffer: %s (%d)",
+                        __FUNCTION__, mId, strerror(-res), res);
+            }
+            checkRetAndSetAbandonedLocked(res);
             return res;
         }
     }
 
     if (res == OK) {
-        std::vector<sp<GraphicBuffer>> removedBuffers;
-        res = mConsumer->getAndFlushRemovedBuffers(&removedBuffers);
-        if (res == OK) {
-            onBuffersRemovedLocked(removedBuffers);
-
-            if (mUseBufferManager && removedBuffers.size() > 0) {
-                mBufferManager->onBuffersRemoved(getId(), getStreamSetId(), removedBuffers.size());
-            }
-        }
+        checkRemovedBuffersLocked();
     }
 
     return res;
 }
 
+void Camera3OutputStream::checkRemovedBuffersLocked(bool notifyBufferManager) {
+    std::vector<sp<GraphicBuffer>> removedBuffers;
+    status_t res = mConsumer->getAndFlushRemovedBuffers(&removedBuffers);
+    if (res == OK) {
+        onBuffersRemovedLocked(removedBuffers);
+
+        if (notifyBufferManager && mUseBufferManager && removedBuffers.size() > 0) {
+            mBufferManager->onBuffersRemoved(getId(), getStreamSetId(), removedBuffers.size());
+        }
+    }
+}
+
+void Camera3OutputStream::checkRetAndSetAbandonedLocked(status_t res) {
+    // Only transition to STATE_ABANDONED from STATE_CONFIGURED. (If it is
+    // STATE_PREPARING, let prepareNextBuffer handle the error.)
+    if ((res == NO_INIT || res == DEAD_OBJECT) && mState == STATE_CONFIGURED) {
+        mState = STATE_ABANDONED;
+    }
+}
+
+bool Camera3OutputStream::shouldLogError(status_t res, StreamState state) {
+    if (res == OK) {
+        return false;
+    }
+    if ((res == DEAD_OBJECT || res == NO_INIT) && state == STATE_ABANDONED) {
+        return false;
+    }
+    return true;
+}
+
 status_t Camera3OutputStream::disconnectLocked() {
     status_t res;
 
@@ -659,12 +728,11 @@
     return res;
 }
 
-status_t Camera3OutputStream::getEndpointUsageForSurface(uint64_t *usage,
-        const sp<Surface>& surface) const {
-    status_t res;
-    uint64_t u = 0;
+void Camera3OutputStream::applyZSLUsageQuirk(int format, uint64_t *consumerUsage /*inout*/) {
+    if (consumerUsage == nullptr) {
+        return;
+    }
 
-    res = native_window_get_consumer_usage(static_cast<ANativeWindow*>(surface.get()), &u);
     // If an opaque output stream's endpoint is ImageReader, add
     // GRALLOC_USAGE_HW_CAMERA_ZSL to the usage so HAL knows it will be used
     // for the ZSL use case.
@@ -673,12 +741,20 @@
     //     2. GRALLOC_USAGE_HW_RENDER
     //     3. GRALLOC_USAGE_HW_COMPOSER
     //     4. GRALLOC_USAGE_HW_VIDEO_ENCODER
-    if (camera3_stream::format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
-            (u & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER |
+    if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
+            (*consumerUsage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER |
             GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_VIDEO_ENCODER)) == 0) {
-        u |= GRALLOC_USAGE_HW_CAMERA_ZSL;
+        *consumerUsage |= GRALLOC_USAGE_HW_CAMERA_ZSL;
     }
+}
 
+status_t Camera3OutputStream::getEndpointUsageForSurface(uint64_t *usage,
+        const sp<Surface>& surface) const {
+    status_t res;
+    uint64_t u = 0;
+
+    res = native_window_get_consumer_usage(static_cast<ANativeWindow*>(surface.get()), &u);
+    applyZSLUsageQuirk(camera3_stream::format, &u);
     *usage = u;
     return res;
 }
@@ -779,7 +855,9 @@
         ALOGW("%s: the released buffer has already been freed by the buffer queue!", __FUNCTION__);
     } else if (res != OK) {
         // Treat other errors as abandonment
-        ALOGE("%s: detach next buffer failed: %s (%d).", __FUNCTION__, strerror(-res), res);
+        if (shouldLogError(res, mState)) {
+            ALOGE("%s: detach next buffer failed: %s (%d).", __FUNCTION__, strerror(-res), res);
+        }
         mState = STATE_ABANDONED;
         return res;
     }
@@ -792,11 +870,8 @@
         }
     }
 
-    std::vector<sp<GraphicBuffer>> removedBuffers;
-    res = mConsumer->getAndFlushRemovedBuffers(&removedBuffers);
-    if (res == OK) {
-        onBuffersRemovedLocked(removedBuffers);
-    }
+    // Here we assume detachBuffer is called by buffer manager so it doesn't need to be notified
+    checkRemovedBuffersLocked(/*notifyBufferManager*/false);
     return res;
 }
 
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index 6f36f92..729c655 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -190,6 +190,9 @@
      */
     virtual ssize_t getSurfaceId(const sp<Surface> &/*surface*/) { return 0; }
 
+    virtual status_t getUniqueSurfaceIds(const std::vector<size_t>&,
+            /*out*/std::vector<size_t>*) { return INVALID_OPERATION; };
+
     /**
      * Update the stream output surfaces.
      */
@@ -198,6 +201,11 @@
             const std::vector<size_t> &removedSurfaceIds,
             KeyedVector<sp<Surface>, size_t> *outputMap/*out*/);
 
+    /**
+     * Apply ZSL related consumer usage quirk.
+     */
+    static void applyZSLUsageQuirk(int format, uint64_t *consumerUsage /*inout*/);
+
   protected:
     Camera3OutputStream(int id, camera3_stream_type_t type,
             uint32_t width, uint32_t height, int format,
@@ -213,6 +221,7 @@
             const camera3_stream_buffer &buffer,
             nsecs_t timestamp,
             bool output,
+            const std::vector<size_t>& surface_ids,
             /*out*/
             sp<Fence> *releaseFenceOut);
 
@@ -285,10 +294,11 @@
 
     virtual status_t returnBufferLocked(
             const camera3_stream_buffer &buffer,
-            nsecs_t timestamp);
+            nsecs_t timestamp, const std::vector<size_t>& surface_ids);
 
     virtual status_t queueBufferToConsumer(sp<ANativeWindow>& consumer,
-            ANativeWindowBuffer* buffer, int anwReleaseFence);
+            ANativeWindowBuffer* buffer, int anwReleaseFence,
+            const std::vector<size_t>& surface_ids);
 
     virtual status_t configureQueueLocked();
 
@@ -299,6 +309,17 @@
      */
     void onBuffersRemovedLocked(const std::vector<sp<GraphicBuffer>>&);
     status_t detachBufferLocked(sp<GraphicBuffer>* buffer, int* fenceFd);
+    // Call this after each dequeueBuffer/attachBuffer/detachNextBuffer call to get update on
+    // removed buffers. Set notifyBufferManager to false when the call is initiated by buffer
+    // manager so buffer manager doesn't need to be notified.
+    void checkRemovedBuffersLocked(bool notifyBufferManager = true);
+
+    // Check return status of IGBP calls and set abandoned state accordingly
+    void checkRetAndSetAbandonedLocked(status_t res);
+
+    // If the status indicates abandonded stream, only log when state hasn't been updated to
+    // STATE_ABANDONED
+    static bool shouldLogError(status_t res, StreamState state);
 
     static const int32_t kDequeueLatencyBinSize = 5; // in ms
     CameraLatencyHistogram mDequeueBufferLatency;
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h b/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
index a711a6d..2bde949 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
@@ -67,6 +67,18 @@
     virtual ssize_t getSurfaceId(const sp<Surface> &surface) = 0;
 
     /**
+     * Query the unique surface IDs of current surfaceIds.
+     * When passing unique surface IDs in returnBuffer(), if the
+     * surfaceId has been removed from the stream, the output corresponding to
+     * the unique surface ID will be ignored and not delivered to client.
+     *
+     * Return INVALID_OPERATION if and only if the stream does not support
+     * surface sharing.
+     */
+    virtual status_t getUniqueSurfaceIds(const std::vector<size_t>& surfaceIds,
+            /*out*/std::vector<size_t>* outUniqueIds) = 0;
+
+    /**
      * Update the stream output surfaces.
      */
     virtual status_t updateStream(const std::vector<sp<Surface>> &outputSurfaces,
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
index 2bb9ff7..86b45cb 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
@@ -14,6 +14,10 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "Camera3-SharedOuStrm"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+//#define LOG_NDEBUG 0
+
 #include "Camera3SharedOutputStream.h"
 
 namespace android {
@@ -28,16 +32,17 @@
         uint64_t consumerUsage, android_dataspace dataSpace,
         camera3_stream_rotation_t rotation,
         nsecs_t timestampOffset, const String8& physicalCameraId,
-        int setId) :
+        int setId, bool useHalBufManager) :
         Camera3OutputStream(id, CAMERA3_STREAM_OUTPUT, width, height,
                             format, dataSpace, rotation, physicalCameraId,
-                            consumerUsage, timestampOffset, setId) {
+                            consumerUsage, timestampOffset, setId),
+        mUseHalBufManager(useHalBufManager) {
     size_t consumerCount = std::min(surfaces.size(), kMaxOutputs);
     if (surfaces.size() > consumerCount) {
         ALOGE("%s: Trying to add more consumers than the maximum ", __func__);
     }
     for (size_t i = 0; i < consumerCount; i++) {
-        mSurfaces[i] = surfaces[i];
+        mSurfaceUniqueIds[i] = std::make_pair(surfaces[i], mNextUniqueSurfaceId++);
     }
 }
 
@@ -48,21 +53,20 @@
 status_t Camera3SharedOutputStream::connectStreamSplitterLocked() {
     status_t res = OK;
 
-    mStreamSplitter = new Camera3StreamSplitter();
+    mStreamSplitter = new Camera3StreamSplitter(mUseHalBufManager);
 
-    uint64_t usage;
+    uint64_t usage = 0;
     getEndpointUsage(&usage);
 
     std::unordered_map<size_t, sp<Surface>> initialSurfaces;
     for (size_t i = 0; i < kMaxOutputs; i++) {
-        if (mSurfaces[i] != nullptr) {
-            initialSurfaces.emplace(i, mSurfaces[i]);
+        if (mSurfaceUniqueIds[i].first != nullptr) {
+            initialSurfaces.emplace(i, mSurfaceUniqueIds[i].first);
         }
     }
 
-    android::PixelFormat format = isFormatOverridden() ? getOriginalFormat() : getFormat();
     res = mStreamSplitter->connect(initialSurfaces, usage, mUsage, camera3_stream::max_buffers,
-            getWidth(), getHeight(), format, &mConsumer);
+            getWidth(), getHeight(), getFormat(), &mConsumer);
     if (res != OK) {
         ALOGE("%s: Failed to connect to stream splitter: %s(%d)",
                 __FUNCTION__, strerror(-res), res);
@@ -72,6 +76,31 @@
     return res;
 }
 
+status_t Camera3SharedOutputStream::attachBufferToSplitterLocked(
+        ANativeWindowBuffer* anb,
+        const std::vector<size_t>& surface_ids) {
+    status_t res = OK;
+
+    // Attach the buffer to the splitter output queues. This could block if
+    // the output queue doesn't have any empty slot. So unlock during the course
+    // of attachBufferToOutputs.
+    sp<Camera3StreamSplitter> splitter = mStreamSplitter;
+    mLock.unlock();
+    res = splitter->attachBufferToOutputs(anb, surface_ids);
+    mLock.lock();
+    if (res != OK) {
+        ALOGE("%s: Stream %d: Cannot attach stream splitter buffer to outputs: %s (%d)",
+                __FUNCTION__, mId, strerror(-res), res);
+        // Only transition to STATE_ABANDONED from STATE_CONFIGURED. (If it is STATE_PREPARING,
+        // let prepareNextBuffer handle the error.)
+        if (res == NO_INIT && mState == STATE_CONFIGURED) {
+            mState = STATE_ABANDONED;
+        }
+    }
+    return res;
+}
+
+
 status_t Camera3SharedOutputStream::notifyBufferReleased(ANativeWindowBuffer *anwBuffer) {
     Mutex::Autolock l(mLock);
     status_t res = OK;
@@ -90,7 +119,7 @@
         return true;
     }
 
-    return (mSurfaces[surface_id] == nullptr);
+    return (mSurfaceUniqueIds[surface_id].first == nullptr);
 }
 
 status_t Camera3SharedOutputStream::setConsumers(const std::vector<sp<Surface>>& surfaces) {
@@ -113,7 +142,7 @@
             return NO_MEMORY;
         }
 
-        mSurfaces[id] = surface;
+        mSurfaceUniqueIds[id] = std::make_pair(surface, mNextUniqueSurfaceId++);
 
         // Only call addOutput if the splitter has been connected.
         if (mStreamSplitter != nullptr) {
@@ -129,7 +158,7 @@
 }
 
 status_t Camera3SharedOutputStream::getBufferLocked(camera3_stream_buffer *buffer,
-        const std::vector<size_t>& surface_ids) {
+        const std::vector<size_t>& surfaceIds) {
     ANativeWindowBuffer* anb;
     int fenceFd = -1;
 
@@ -139,23 +168,11 @@
         return res;
     }
 
-    // Attach the buffer to the splitter output queues. This could block if
-    // the output queue doesn't have any empty slot. So unlock during the course
-    // of attachBufferToOutputs.
-    sp<Camera3StreamSplitter> splitter = mStreamSplitter;
-    mLock.unlock();
-    res = splitter->attachBufferToOutputs(anb, surface_ids);
-    mLock.lock();
-    if (res != OK) {
-        ALOGE("%s: Stream %d: Cannot attach stream splitter buffer to outputs: %s (%d)",
-                __FUNCTION__, mId, strerror(-res), res);
-        // Only transition to STATE_ABANDONED from STATE_CONFIGURED. (If it is STATE_PREPARING,
-        // let prepareNextBuffer handle the error.)
-        if (res == NO_INIT && mState == STATE_CONFIGURED) {
-            mState = STATE_ABANDONED;
+    if (!mUseHalBufManager) {
+        res = attachBufferToSplitterLocked(anb, surfaceIds);
+        if (res != OK) {
+            return res;
         }
-
-        return res;
     }
 
     /**
@@ -169,8 +186,38 @@
 }
 
 status_t Camera3SharedOutputStream::queueBufferToConsumer(sp<ANativeWindow>& consumer,
-            ANativeWindowBuffer* buffer, int anwReleaseFence) {
-    status_t res = consumer->queueBuffer(consumer.get(), buffer, anwReleaseFence);
+            ANativeWindowBuffer* buffer, int anwReleaseFence,
+            const std::vector<size_t>& uniqueSurfaceIds) {
+    status_t res = OK;
+    if (mUseHalBufManager) {
+        if (uniqueSurfaceIds.size() == 0) {
+            ALOGE("%s: uniqueSurfaceIds must not be empty!", __FUNCTION__);
+            return BAD_VALUE;
+        }
+        Mutex::Autolock l(mLock);
+        std::vector<size_t> surfaceIds;
+        for (const auto& uniqueId : uniqueSurfaceIds) {
+            bool uniqueIdFound = false;
+            for (size_t i = 0; i < kMaxOutputs; i++) {
+                if (mSurfaceUniqueIds[i].second == uniqueId) {
+                    surfaceIds.push_back(i);
+                    uniqueIdFound = true;
+                    break;
+                }
+            }
+            if (!uniqueIdFound) {
+                ALOGV("%s: unknown unique surface ID %zu for stream %d: "
+                        "output might have been removed.",
+                        __FUNCTION__, uniqueId, mId);
+            }
+        }
+        res = attachBufferToSplitterLocked(buffer, surfaceIds);
+        if (res != OK) {
+            return res;
+        }
+    }
+
+    res = consumer->queueBuffer(consumer.get(), buffer, anwReleaseFence);
 
     // After queuing buffer to the internal consumer queue, check whether the buffer is
     // successfully queued to the output queues.
@@ -229,8 +276,8 @@
         *usage = getPresetConsumerUsage();
 
         for (size_t id = 0; id < kMaxOutputs; id++) {
-            if (mSurfaces[id] != nullptr) {
-                res = getEndpointUsageForSurface(&u, mSurfaces[id]);
+            if (mSurfaceUniqueIds[id].first != nullptr) {
+                res = getEndpointUsageForSurface(&u, mSurfaceUniqueIds[id].first);
                 *usage |= u;
             }
         }
@@ -246,7 +293,7 @@
 ssize_t Camera3SharedOutputStream::getNextSurfaceIdLocked() {
     ssize_t id = -1;
     for (size_t i = 0; i < kMaxOutputs; i++) {
-        if (mSurfaces[i] == nullptr) {
+        if (mSurfaceUniqueIds[i].first == nullptr) {
             id = i;
             break;
         }
@@ -259,7 +306,7 @@
     Mutex::Autolock l(mLock);
     ssize_t id = -1;
     for (size_t i = 0; i < kMaxOutputs; i++) {
-        if (mSurfaces[i] == surface) {
+        if (mSurfaceUniqueIds[i].first == surface) {
             id = i;
             break;
         }
@@ -268,6 +315,26 @@
     return id;
 }
 
+status_t Camera3SharedOutputStream::getUniqueSurfaceIds(
+        const std::vector<size_t>& surfaceIds,
+        /*out*/std::vector<size_t>* outUniqueIds) {
+    Mutex::Autolock l(mLock);
+    if (outUniqueIds == nullptr || surfaceIds.size() > kMaxOutputs) {
+        return BAD_VALUE;
+    }
+
+    outUniqueIds->clear();
+    outUniqueIds->reserve(surfaceIds.size());
+
+    for (const auto& surfaceId : surfaceIds) {
+        if (surfaceId >= kMaxOutputs) {
+            return BAD_VALUE;
+        }
+        outUniqueIds->push_back(mSurfaceUniqueIds[surfaceId].second);
+    }
+    return OK;
+}
+
 status_t Camera3SharedOutputStream::revertPartialUpdateLocked(
         const KeyedVector<sp<Surface>, size_t> &removedSurfaces,
         const KeyedVector<sp<Surface>, size_t> &attachedSurfaces) {
@@ -281,7 +348,7 @@
                 return UNKNOWN_ERROR;
             }
         }
-        mSurfaces[index] = nullptr;
+        mSurfaceUniqueIds[index] = std::make_pair(nullptr, mNextUniqueSurfaceId++);
     }
 
     for (size_t i = 0; i < removedSurfaces.size(); i++) {
@@ -292,7 +359,8 @@
                 return UNKNOWN_ERROR;
             }
         }
-        mSurfaces[index] = removedSurfaces.keyAt(i);
+        mSurfaceUniqueIds[index] = std::make_pair(
+                removedSurfaces.keyAt(i), mNextUniqueSurfaceId++);
     }
 
     return ret;
@@ -344,8 +412,8 @@
 
             }
         }
-        mSurfaces[it] = nullptr;
-        removedSurfaces.add(mSurfaces[it], it);
+        removedSurfaces.add(mSurfaceUniqueIds[it].first, it);
+        mSurfaceUniqueIds[it] = std::make_pair(nullptr, mNextUniqueSurfaceId++);
     }
 
     //Next add the new outputs
@@ -370,7 +438,7 @@
                 return ret;
             }
         }
-        mSurfaces[surfaceId] = it;
+        mSurfaceUniqueIds[surfaceId] = std::make_pair(it, mNextUniqueSurfaceId++);
         outputMap->add(it, surfaceId);
     }
 
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
index 02b1c09..b5e37c2 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_SERVERS_CAMERA3_SHARED_OUTPUT_STREAM_H
 #define ANDROID_SERVERS_CAMERA3_SHARED_OUTPUT_STREAM_H
 
+#include <array>
 #include "Camera3StreamSplitter.h"
 #include "Camera3OutputStream.h"
 
@@ -37,7 +38,8 @@
             uint64_t consumerUsage, android_dataspace dataSpace,
             camera3_stream_rotation_t rotation, nsecs_t timestampOffset,
             const String8& physicalCameraId,
-            int setId = CAMERA3_STREAM_SET_ID_INVALID);
+            int setId = CAMERA3_STREAM_SET_ID_INVALID,
+            bool useHalBufManager = false);
 
     virtual ~Camera3SharedOutputStream();
 
@@ -49,6 +51,15 @@
 
     virtual ssize_t getSurfaceId(const sp<Surface> &surface);
 
+    /**
+     * Query the unique surface IDs of current surfaceIds.
+     * When passing unique surface IDs in returnBuffer(), if the
+     * surfaceId has been removed from the stream, the output corresponding to
+     * the unique surface ID will be ignored and not delivered to client.
+     */
+    virtual status_t getUniqueSurfaceIds(const std::vector<size_t>& surfaceIds,
+            /*out*/std::vector<size_t>* outUniqueIds) override;
+
     virtual status_t updateStream(const std::vector<sp<Surface>> &outputSurfaces,
             const std::vector<OutputStreamInfo> &outputInfo,
             const std::vector<size_t> &removedSurfaceIds,
@@ -58,8 +69,17 @@
 
     static const size_t kMaxOutputs = 4;
 
-    // Map surfaceId -> output surfaces
-    sp<Surface> mSurfaces[kMaxOutputs];
+    // Whether HAL is in control for buffer management. Surface sharing behavior
+    // depends on this flag.
+    const bool mUseHalBufManager;
+
+    // Pair of an output Surface and its unique ID
+    typedef std::pair<sp<Surface>, size_t> SurfaceUniqueId;
+
+    // Map surfaceId -> (output surface, unique surface ID)
+    std::array<SurfaceUniqueId, kMaxOutputs> mSurfaceUniqueIds;
+
+    size_t mNextUniqueSurfaceId = 0;
 
     ssize_t getNextSurfaceIdLocked();
 
@@ -78,13 +98,24 @@
     status_t connectStreamSplitterLocked();
 
     /**
+     * Attach the output buffer to stream splitter.
+     * When camera service is doing buffer management, this method will be called
+     * before the buffer is handed out to HAL in request thread.
+     * When HAL is doing buffer management, this method will be called when
+     * the buffer is returned from HAL in hwbinder callback thread.
+     */
+    status_t attachBufferToSplitterLocked(ANativeWindowBuffer* anb,
+            const std::vector<size_t>& surface_ids);
+
+    /**
      * Internal Camera3Stream interface
      */
     virtual status_t getBufferLocked(camera3_stream_buffer *buffer,
             const std::vector<size_t>& surface_ids);
 
     virtual status_t queueBufferToConsumer(sp<ANativeWindow>& consumer,
-            ANativeWindowBuffer* buffer, int anwReleaseFence);
+            ANativeWindowBuffer* buffer, int anwReleaseFence,
+            const std::vector<size_t>& uniqueSurfaceIds);
 
     virtual status_t configureQueueLocked();
 
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 6030d15..fd9b4b0 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -60,13 +60,19 @@
     mUsage(0),
     mOldUsage(0),
     mOldMaxBuffers(0),
+    mOldFormat(-1),
+    mOldDataSpace(HAL_DATASPACE_UNKNOWN),
     mPrepared(false),
+    mPrepareBlockRequest(true),
     mPreparedBufferIdx(0),
     mLastMaxCount(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX),
     mBufferLimitLatency(kBufferLimitLatencyBinSize),
     mFormatOverridden(false),
-    mOriginalFormat(-1),
-    mPhysicalCameraId(physicalCameraId) {
+    mOriginalFormat(format),
+    mDataSpaceOverridden(false),
+    mOriginalDataSpace(HAL_DATASPACE_UNKNOWN),
+    mPhysicalCameraId(physicalCameraId),
+    mLastTimestamp(0) {
 
     camera3_stream::stream_type = type;
     camera3_stream::width = width;
@@ -119,7 +125,6 @@
 
 void Camera3Stream::setFormatOverride(bool formatOverridden) {
     mFormatOverridden = formatOverridden;
-    if (formatOverridden) mOriginalFormat = camera3_stream::format;
 }
 
 bool Camera3Stream::isFormatOverridden() const {
@@ -132,7 +137,9 @@
 
 void Camera3Stream::setDataSpaceOverride(bool dataSpaceOverridden) {
     mDataSpaceOverridden = dataSpaceOverridden;
-    if (dataSpaceOverridden) mOriginalDataSpace = camera3_stream::data_space;
+    if (dataSpaceOverridden && mOriginalDataSpace == HAL_DATASPACE_UNKNOWN) {
+        mOriginalDataSpace = camera3_stream::data_space;
+    }
 }
 
 bool Camera3Stream::isDataSpaceOverridden() const {
@@ -248,6 +255,8 @@
 
     mOldUsage = mUsage;
     mOldMaxBuffers = camera3_stream::max_buffers;
+    mOldFormat = camera3_stream::format;
+    mOldDataSpace = camera3_stream::data_space;
 
     res = getEndpointUsage(&mUsage);
     if (res != OK) {
@@ -285,8 +294,11 @@
     return (mState == STATE_IN_CONFIG) || (mState == STATE_IN_RECONFIG);
 }
 
-status_t Camera3Stream::finishConfiguration() {
+status_t Camera3Stream::finishConfiguration(/*out*/bool* streamReconfigured) {
     ATRACE_CALL();
+    if (streamReconfigured != nullptr) {
+        *streamReconfigured = false;
+    }
     Mutex::Autolock l(mLock);
     switch (mState) {
         case STATE_ERROR:
@@ -311,7 +323,7 @@
 
     // Register for idle tracking
     sp<StatusTracker> statusTracker = mStatusTracker.promote();
-    if (statusTracker != 0) {
+    if (statusTracker != 0 && mStatusId == StatusTracker::NO_STATUS_ID) {
         mStatusId = statusTracker->addComponent();
     }
 
@@ -319,7 +331,9 @@
     // so. As documented in hardware/camera3.h:configure_streams().
     if (mState == STATE_IN_RECONFIG &&
             mOldUsage == mUsage &&
-            mOldMaxBuffers == camera3_stream::max_buffers) {
+            mOldMaxBuffers == camera3_stream::max_buffers &&
+            mOldDataSpace == camera3_stream::data_space &&
+            mOldFormat == camera3_stream::format) {
         mState = STATE_CONFIGURED;
         return OK;
     }
@@ -327,8 +341,10 @@
     // Reset prepared state, since buffer config has changed, and existing
     // allocations are no longer valid
     mPrepared = false;
+    mPrepareBlockRequest = true;
     mStreamUnpreparable = false;
 
+    bool reconfiguring = (mState == STATE_IN_RECONFIG);
     status_t res;
     res = configureQueueLocked();
     // configureQueueLocked could return error in case of abandoned surface.
@@ -345,6 +361,9 @@
         return res;
     }
 
+    if (reconfiguring && streamReconfigured != nullptr) {
+        *streamReconfigured = true;
+    }
     mState = STATE_CONFIGURED;
 
     return res;
@@ -388,7 +407,7 @@
     return mStreamUnpreparable;
 }
 
-status_t Camera3Stream::startPrepare(int maxCount) {
+status_t Camera3Stream::startPrepare(int maxCount, bool blockRequest) {
     ATRACE_CALL();
 
     Mutex::Autolock l(mLock);
@@ -420,8 +439,6 @@
         return INVALID_OPERATION;
     }
 
-
-
     size_t pipelineMax = getBufferCountLocked();
     size_t clampedCount = (pipelineMax < static_cast<size_t>(maxCount)) ?
             pipelineMax : static_cast<size_t>(maxCount);
@@ -429,6 +446,7 @@
             pipelineMax : clampedCount;
 
     mPrepared = bufferCount <= mLastMaxCount;
+    mPrepareBlockRequest = blockRequest;
 
     if (mPrepared) return OK;
 
@@ -442,9 +460,9 @@
     return NOT_ENOUGH_DATA;
 }
 
-bool Camera3Stream::isPreparing() const {
+bool Camera3Stream::isBlockedByPrepare() const {
     Mutex::Autolock l(mLock);
-    return mState == STATE_PREPARING;
+    return mState == STATE_PREPARING && mPrepareBlockRequest;
 }
 
 bool Camera3Stream::isAbandoned() const {
@@ -576,6 +594,7 @@
 }
 
 status_t Camera3Stream::getBuffer(camera3_stream_buffer *buffer,
+        nsecs_t waitBufferTimeout,
         const std::vector<size_t>& surface_ids) {
     ATRACE_CALL();
     Mutex::Autolock l(mLock);
@@ -585,7 +604,11 @@
     if (mState != STATE_CONFIGURED) {
         ALOGE("%s: Stream %d: Can't get buffers if stream is not in CONFIGURED state %d",
                 __FUNCTION__, mId, mState);
-        return INVALID_OPERATION;
+        if (mState == STATE_ABANDONED) {
+            return DEAD_OBJECT;
+        } else {
+            return INVALID_OPERATION;
+        }
     }
 
     // Wait for new buffer returned back if we are running into the limit.
@@ -593,13 +616,16 @@
         ALOGV("%s: Already dequeued max output buffers (%d), wait for next returned one.",
                         __FUNCTION__, camera3_stream::max_buffers);
         nsecs_t waitStart = systemTime(SYSTEM_TIME_MONOTONIC);
-        res = mOutputBufferReturnedSignal.waitRelative(mLock, kWaitForBufferDuration);
+        if (waitBufferTimeout < kWaitForBufferDuration) {
+            waitBufferTimeout = kWaitForBufferDuration;
+        }
+        res = mOutputBufferReturnedSignal.waitRelative(mLock, waitBufferTimeout);
         nsecs_t waitEnd = systemTime(SYSTEM_TIME_MONOTONIC);
         mBufferLimitLatency.add(waitStart, waitEnd);
         if (res != OK) {
             if (res == TIMED_OUT) {
                 ALOGE("%s: wait for output buffer return timed out after %lldms (max_buffers %d)",
-                        __FUNCTION__, kWaitForBufferDuration / 1000000LL,
+                        __FUNCTION__, waitBufferTimeout / 1000000LL,
                         camera3_stream::max_buffers);
             }
             return res;
@@ -649,7 +675,8 @@
 }
 
 status_t Camera3Stream::returnBuffer(const camera3_stream_buffer &buffer,
-        nsecs_t timestamp) {
+        nsecs_t timestamp, bool timestampIncreasing,
+         const std::vector<size_t>& surface_ids, uint64_t frameNumber) {
     ATRACE_CALL();
     Mutex::Autolock l(mLock);
 
@@ -661,6 +688,15 @@
 
     removeOutstandingBuffer(buffer);
 
+    // Buffer status may be changed, so make a copy of the stream_buffer struct.
+    camera3_stream_buffer b = buffer;
+    if (timestampIncreasing && timestamp != 0 && timestamp <= mLastTimestamp) {
+        ALOGE("%s: Stream %d: timestamp %" PRId64 " is not increasing. Prev timestamp %" PRId64,
+                __FUNCTION__, mId, timestamp, mLastTimestamp);
+        b.status = CAMERA3_BUFFER_STATUS_ERROR;
+    }
+    mLastTimestamp = timestamp;
+
     /**
      * TODO: Check that the state is valid first.
      *
@@ -669,9 +705,9 @@
      *
      * Do this for getBuffer as well.
      */
-    status_t res = returnBufferLocked(buffer, timestamp);
+    status_t res = returnBufferLocked(b, timestamp, surface_ids);
     if (res == OK) {
-        fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/true);
+        fireBufferListenersLocked(b, /*acquired*/false, /*output*/true, timestamp, frameNumber);
     }
 
     // Even if returning the buffer failed, we still want to signal whoever is waiting for the
@@ -747,8 +783,22 @@
     return getInputBufferProducerLocked(producer);
 }
 
+void Camera3Stream::fireBufferRequestForFrameNumber(uint64_t frameNumber,
+        const CameraMetadata& settings) {
+    ATRACE_CALL();
+    Mutex::Autolock l(mLock);
+
+    for (auto &it : mBufferListenerList) {
+        sp<Camera3StreamBufferListener> listener = it.promote();
+        if (listener.get() != nullptr) {
+            listener->onBufferRequestForFrameNumber(frameNumber, getId(), settings);
+        }
+    }
+}
+
 void Camera3Stream::fireBufferListenersLocked(
-        const camera3_stream_buffer& buffer, bool acquired, bool output) {
+        const camera3_stream_buffer& buffer, bool acquired, bool output, nsecs_t timestamp,
+        uint64_t frameNumber) {
     List<wp<Camera3StreamBufferListener> >::iterator it, end;
 
     // TODO: finish implementing
@@ -757,6 +807,8 @@
         Camera3StreamBufferListener::BufferInfo();
     info.mOutput = output;
     info.mError = (buffer.status == CAMERA3_BUFFER_STATUS_ERROR);
+    info.mFrameNumber = frameNumber;
+    info.mTimestamp = timestamp;
     // TODO: rest of fields
 
     for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
@@ -780,6 +832,12 @@
     return hasOutstandingBuffersLocked();
 }
 
+size_t Camera3Stream::getOutstandingBuffersCount() const {
+    ATRACE_CALL();
+    Mutex::Autolock l(mLock);
+    return getHandoutOutputBufferCountLocked();
+}
+
 status_t Camera3Stream::setStatusTracker(sp<StatusTracker> statusTracker) {
     Mutex::Autolock l(mLock);
     sp<StatusTracker> oldTracker = mStatusTracker.promote();
@@ -822,7 +880,7 @@
     return INVALID_OPERATION;
 }
 status_t Camera3Stream::returnBufferLocked(const camera3_stream_buffer &,
-                                           nsecs_t) {
+                                           nsecs_t, const std::vector<size_t>&) {
     ALOGE("%s: This type of stream does not support output", __FUNCTION__);
     return INVALID_OPERATION;
 }
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index 4ddcf1a..67afd0f 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -197,6 +197,8 @@
      * after this call, but can still be read until the destruction of the
      * stream.
      *
+     * streamReconfigured: set to true when a stream is being reconfigured.
+     *
      * Returns:
      *   OK on a successful configuration
      *   NO_INIT in case of a serious error from the HAL device
@@ -204,7 +206,7 @@
      *   INVALID_OPERATION in case connecting to the consumer failed or consumer
      *       doesn't exist yet.
      */
-    status_t         finishConfiguration();
+    status_t         finishConfiguration(/*out*/bool* streamReconfigured = nullptr);
 
     /**
      * Cancels the stream configuration process. This returns the stream to the
@@ -232,6 +234,11 @@
      *
      * This call performs no allocation, so is quick to call.
      *
+     * blockRequest specifies whether prepare will block upcoming capture
+     * request. This flag should only be set to false if the caller guarantees
+     * the whole buffer preparation process is done before capture request
+     * comes in.
+     *
      * Returns:
      *    OK if no more buffers need to be preallocated
      *    NOT_ENOUGH_DATA if calls to prepareNextBuffer are needed to finish
@@ -240,12 +247,12 @@
      *    INVALID_OPERATION if called when not in CONFIGURED state, or a
      *        valid buffer has already been returned to this stream.
      */
-    status_t         startPrepare(int maxCount);
+    status_t         startPrepare(int maxCount, bool blockRequest);
 
     /**
-     * Check if the stream is mid-preparing.
+     * Check if the request on a stream is blocked by prepare.
      */
-    bool             isPreparing() const;
+    bool             isBlockedByPrepare() const;
 
     /**
      * Continue stream buffer preparation by allocating the next
@@ -311,16 +318,24 @@
      *
      */
     status_t         getBuffer(camera3_stream_buffer *buffer,
+            nsecs_t waitBufferTimeout,
             const std::vector<size_t>& surface_ids = std::vector<size_t>());
 
     /**
      * Return a buffer to the stream after use by the HAL.
      *
+     * Multiple surfaces could share the same HAL stream, but a request may
+     * be only for a subset of surfaces. In this case, the
+     * Camera3StreamInterface object needs the surface ID information to attach
+     * buffers for those surfaces.
+     *
      * This method may only be called for buffers provided by getBuffer().
      * For bidirectional streams, this method applies to the output-side buffers
      */
     status_t         returnBuffer(const camera3_stream_buffer &buffer,
-            nsecs_t timestamp);
+            nsecs_t timestamp, bool timestampIncreasing,
+            const std::vector<size_t>& surface_ids = std::vector<size_t>(),
+            uint64_t frameNumber = 0);
 
     /**
      * Fill in the camera3_stream_buffer with the next valid buffer for this
@@ -354,6 +369,11 @@
      */
     bool             hasOutstandingBuffers() const;
 
+    /**
+     * Get number of buffers currently handed out to HAL
+     */
+    size_t           getOutstandingBuffersCount() const;
+
     enum {
         TIMEOUT_NEVER = -1
     };
@@ -413,6 +433,12 @@
      */
     status_t         restoreConfiguredState();
 
+    /**
+     * Notify buffer stream listeners about incoming request with particular frame number.
+     */
+    void fireBufferRequestForFrameNumber(uint64_t frameNumber,
+            const CameraMetadata& settings) override;
+
   protected:
     const int mId;
     /**
@@ -434,7 +460,7 @@
     // Zero for formats with fixed buffer size for given dimensions.
     const size_t mMaxSize;
 
-    enum {
+    enum StreamState {
         STATE_ERROR,
         STATE_CONSTRUCTED,
         STATE_IN_CONFIG,
@@ -467,7 +493,8 @@
     virtual status_t getBufferLocked(camera3_stream_buffer *buffer,
             const std::vector<size_t>& surface_ids = std::vector<size_t>());
     virtual status_t returnBufferLocked(const camera3_stream_buffer &buffer,
-            nsecs_t timestamp);
+            nsecs_t timestamp,
+            const std::vector<size_t>& surface_ids = std::vector<size_t>());
     virtual status_t getInputBufferLocked(camera3_stream_buffer *buffer);
     virtual status_t returnInputBufferLocked(
             const camera3_stream_buffer &buffer);
@@ -489,7 +516,7 @@
     virtual size_t   getBufferCountLocked() = 0;
 
     // Get handout output buffer count.
-    virtual size_t   getHandoutOutputBufferCountLocked() = 0;
+    virtual size_t   getHandoutOutputBufferCountLocked() const = 0;
 
     // Get handout input buffer count.
     virtual size_t   getHandoutInputBufferCountLocked() = 0;
@@ -513,14 +540,18 @@
     uint64_t mUsage;
 
   private:
+    // Previously configured stream properties (post HAL override)
     uint64_t mOldUsage;
     uint32_t mOldMaxBuffers;
+    int mOldFormat;
+    android_dataspace mOldDataSpace;
+
     Condition mOutputBufferReturnedSignal;
     Condition mInputBufferReturnedSignal;
     static const nsecs_t kWaitForBufferDuration = 3000000000LL; // 3000 ms
 
     void fireBufferListenersLocked(const camera3_stream_buffer& buffer,
-                                  bool acquired, bool output);
+            bool acquired, bool output, nsecs_t timestamp = 0, uint64_t frameNumber = 0);
     List<wp<Camera3StreamBufferListener> > mBufferListenerList;
 
     status_t        cancelPrepareLocked();
@@ -534,6 +565,7 @@
     // has been called sufficient number of times, or stream configuration
     // had to register buffers with the HAL
     bool mPrepared;
+    bool mPrepareBlockRequest;
 
     Vector<camera3_stream_buffer_t> mPreparedBuffers;
     size_t mPreparedBufferIdx;
@@ -550,15 +582,16 @@
     static const int32_t kBufferLimitLatencyBinSize = 33; //in ms
     CameraLatencyHistogram mBufferLimitLatency;
 
-    //Keep track of original format in case it gets overridden
+    //Keep track of original format when the stream is created in case it gets overridden
     bool mFormatOverridden;
-    int mOriginalFormat;
+    const int mOriginalFormat;
 
     //Keep track of original dataSpace in case it gets overridden
     bool mDataSpaceOverridden;
     android_dataspace mOriginalDataSpace;
 
     String8 mPhysicalCameraId;
+    nsecs_t mLastTimestamp;
 }; // class Camera3Stream
 
 }; // namespace camera3
diff --git a/services/camera/libcameraservice/device3/Camera3StreamBufferListener.h b/services/camera/libcameraservice/device3/Camera3StreamBufferListener.h
index 2db333d..d0aee27 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamBufferListener.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamBufferListener.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_SERVERS_CAMERA3_STREAMBUFFERLISTENER_H
 #define ANDROID_SERVERS_CAMERA3_STREAMBUFFERLISTENER_H
 
+#include <camera/CameraMetadata.h>
 #include <gui/Surface.h>
 #include <utils/RefBase.h>
 
@@ -41,6 +42,9 @@
     virtual void onBufferAcquired(const BufferInfo& bufferInfo) = 0;
     // Buffer was released by the HAL
     virtual void onBufferReleased(const BufferInfo& bufferInfo) = 0;
+    // Notify about incoming buffer request frame number
+    virtual void onBufferRequestForFrameNumber(uint64_t frameNumber, int streamId,
+            const CameraMetadata& settings) = 0;
 };
 
 }; //namespace camera3
diff --git a/services/camera/libcameraservice/device3/Camera3StreamInterface.h b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
index 9ed7184..73f501a 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
@@ -18,6 +18,8 @@
 #define ANDROID_SERVERS_CAMERA3_STREAM_INTERFACE_H
 
 #include <utils/RefBase.h>
+
+#include <camera/CameraMetadata.h>
 #include "Camera3StreamBufferListener.h"
 #include "Camera3StreamBufferFreedListener.h"
 
@@ -128,13 +130,15 @@
      * modified after this call, but can still be read until the destruction of
      * the stream.
      *
+     * streamReconfigured: set to true when a stream is being reconfigured.
+     *
      * Returns:
      *   OK on a successful configuration
      *   NO_INIT in case of a serious error from the HAL device
      *   NO_MEMORY in case of an error registering buffers
      *   INVALID_OPERATION in case connecting to the consumer failed
      */
-    virtual status_t finishConfiguration() = 0;
+    virtual status_t finishConfiguration(/*out*/bool* streamReconfigured = nullptr) = 0;
 
     /**
      * Cancels the stream configuration process. This returns the stream to the
@@ -160,6 +164,11 @@
      * PREPARING state. Otherwise, returns NOT_ENOUGH_DATA and transitions
      * to PREPARING.
      *
+     * blockRequest specifies whether prepare will block upcoming capture
+     * request. This flag should only be set to false if the caller guarantees
+     * the whole buffer preparation process is done before capture request
+     * comes in.
+     *
      * Returns:
      *    OK if no more buffers need to be preallocated
      *    NOT_ENOUGH_DATA if calls to prepareNextBuffer are needed to finish
@@ -168,12 +177,12 @@
      *    INVALID_OPERATION if called when not in CONFIGURED state, or a
      *        valid buffer has already been returned to this stream.
      */
-    virtual status_t startPrepare(int maxCount) = 0;
+    virtual status_t startPrepare(int maxCount, bool blockRequest) = 0;
 
     /**
-     * Check if the stream is mid-preparing.
+     * Check if the request on a stream is blocked by prepare.
      */
-    virtual bool     isPreparing() const = 0;
+    virtual bool     isBlockedByPrepare() const = 0;
 
     /**
      * Continue stream buffer preparation by allocating the next
@@ -237,16 +246,25 @@
      *
      */
     virtual status_t getBuffer(camera3_stream_buffer *buffer,
+            nsecs_t waitBufferTimeout,
             const std::vector<size_t>& surface_ids = std::vector<size_t>()) = 0;
 
     /**
      * Return a buffer to the stream after use by the HAL.
      *
+     * Multiple surfaces could share the same HAL stream, but a request may
+     * be only for a subset of surfaces. In this case, the
+     * Camera3StreamInterface object needs the surface ID information to attach
+     * buffers for those surfaces. For the case of single surface for a HAL
+     * stream, surface_ids parameter has no effect.
+     *
      * This method may only be called for buffers provided by getBuffer().
      * For bidirectional streams, this method applies to the output-side buffers
      */
     virtual status_t returnBuffer(const camera3_stream_buffer &buffer,
-            nsecs_t timestamp) = 0;
+            nsecs_t timestamp, bool timestampIncreasing = true,
+            const std::vector<size_t>& surface_ids = std::vector<size_t>(),
+            uint64_t frameNumber = 0) = 0;
 
     /**
      * Fill in the camera3_stream_buffer with the next valid buffer for this
@@ -283,6 +301,11 @@
      */
     virtual bool     hasOutstandingBuffers() const = 0;
 
+    /**
+     * Get number of buffers currently handed out to HAL
+     */
+    virtual size_t   getOutstandingBuffersCount() const = 0;
+
     enum {
         TIMEOUT_NEVER = -1
     };
@@ -323,6 +346,12 @@
      * Camera3Stream.
      */
     virtual void setBufferFreedListener(wp<Camera3StreamBufferFreedListener> listener) = 0;
+
+    /**
+     * Notify buffer stream listeners about incoming request with particular frame number.
+     */
+    virtual void fireBufferRequestForFrameNumber(uint64_t frameNumber,
+            const CameraMetadata& settings) = 0;
 };
 
 } // namespace camera3
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
index 8a9402e..84c2ec7 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
@@ -83,8 +83,8 @@
     // from input, and attached to the outputs. In this case, the input queue's
     // dequeueBuffer can still allocate 1 extra buffer before being blocked by
     // the output's attachBuffer().
-    mBufferItemConsumer = new BufferItemConsumer(mConsumer, consumerUsage,
-                                                 mMaxConsumerBuffers+1);
+    mMaxConsumerBuffers++;
+    mBufferItemConsumer = new BufferItemConsumer(mConsumer, consumerUsage, mMaxConsumerBuffers);
     if (mBufferItemConsumer == nullptr) {
         return NO_MEMORY;
     }
@@ -108,6 +108,7 @@
     mHeight = height;
     mFormat = format;
     mProducerUsage = producerUsage;
+    mAcquiredInputBuffers = 0;
 
     SP_LOGV("%s: connected", __FUNCTION__);
     return res;
@@ -147,9 +148,12 @@
 
     mMaxHalBuffers = 0;
     mMaxConsumerBuffers = 0;
+    mAcquiredInputBuffers = 0;
     SP_LOGV("%s: Disconnected", __FUNCTION__);
 }
 
+Camera3StreamSplitter::Camera3StreamSplitter(bool useHalBufManager) :
+        mUseHalBufManager(useHalBufManager) {}
 
 Camera3StreamSplitter::~Camera3StreamSplitter() {
     disconnect();
@@ -165,7 +169,9 @@
         return res;
     }
 
-    res = mConsumer->setMaxAcquiredBufferCount(mMaxConsumerBuffers+1);
+    if (mMaxConsumerBuffers > mAcquiredInputBuffers) {
+        res = mConsumer->setMaxAcquiredBufferCount(mMaxConsumerBuffers);
+    }
 
     return res;
 }
@@ -182,12 +188,19 @@
         return BAD_VALUE;
     }
 
-  status_t res = native_window_set_buffers_dimensions(outputQueue.get(),
+    status_t res = native_window_set_buffers_dimensions(outputQueue.get(),
             mWidth, mHeight);
     if (res != NO_ERROR) {
         SP_LOGE("addOutput: failed to set buffer dimensions (%d)", res);
         return res;
     }
+    res = native_window_set_buffers_format(outputQueue.get(),
+            mFormat);
+    if (res != OK) {
+        ALOGE("%s: Unable to configure stream buffer format %#x for surfaceId %zu",
+                __FUNCTION__, mFormat, surfaceId);
+        return res;
+    }
 
     sp<IGraphicBufferProducer> gbp = outputQueue->getIGraphicBufferProducer();
     // Connect to the buffer producer
@@ -230,7 +243,9 @@
     uint64_t usage = 0;
     res = native_window_get_consumer_usage(static_cast<ANativeWindow*>(outputQueue.get()), &usage);
     if (!(usage & (GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_TEXTURE))) {
-        outputQueue->setDequeueTimeout(kDequeueBufferTimeout);
+        nsecs_t timeout = mUseHalBufManager ?
+                kHalBufMgrDequeueBufferTimeout : kNormalDequeueBufferTimeout;
+        outputQueue->setDequeueTimeout(timeout);
     }
 
     res = gbp->allowAllocation(false);
@@ -242,6 +257,10 @@
     // Add new entry into mOutputs
     mOutputs[surfaceId] = gbp;
     mConsumerBufferCount[surfaceId] = maxConsumerBuffers;
+    if (mConsumerBufferCount[surfaceId] > mMaxHalBuffers) {
+        SP_LOGW("%s: Consumer buffer count %zu larger than max. Hal buffers: %zu", __FUNCTION__,
+                mConsumerBufferCount[surfaceId], mMaxHalBuffers);
+    }
     mNotifiers[gbp] = listener;
     mOutputSlots[gbp] = std::make_unique<OutputSlots>(totalBufferCount);
 
@@ -259,10 +278,12 @@
         return res;
     }
 
-    res = mConsumer->setMaxAcquiredBufferCount(mMaxConsumerBuffers+1);
-    if (res != OK) {
-        SP_LOGE("%s: setMaxAcquiredBufferCount failed %d", __FUNCTION__, res);
-        return res;
+    if (mAcquiredInputBuffers < mMaxConsumerBuffers) {
+        res = mConsumer->setMaxAcquiredBufferCount(mMaxConsumerBuffers);
+        if (res != OK) {
+            SP_LOGE("%s: setMaxAcquiredBufferCount failed %d", __FUNCTION__, res);
+            return res;
+        }
     }
 
     return res;
@@ -311,11 +332,7 @@
     }
 
     mNotifiers[gbp] = nullptr;
-    if (mConsumerBufferCount[surfaceId] < mMaxHalBuffers) {
-        mMaxConsumerBuffers -= mConsumerBufferCount[surfaceId];
-    } else {
-        SP_LOGE("%s: Cached consumer buffer count mismatch!", __FUNCTION__);
-    }
+    mMaxConsumerBuffers -= mConsumerBufferCount[surfaceId];
     mConsumerBufferCount[surfaceId] = 0;
 
     return res;
@@ -423,8 +440,9 @@
         res = gbp->attachBuffer(&slot, gb);
         mMutex.lock();
         if (res != OK) {
-            SP_LOGE("%s: Cannot acquireBuffer from GraphicBufferProducer %p: %s (%d)",
+            SP_LOGE("%s: Cannot attachBuffer from GraphicBufferProducer %p: %s (%d)",
                     __FUNCTION__, gbp.get(), strerror(-res), res);
+            // TODO: might need to detach/cleanup the already attached buffers before return?
             return res;
         }
         if ((slot < 0) || (slot > BufferQueue::NUM_BUFFER_SLOTS)) {
@@ -490,6 +508,7 @@
         return;
     }
 
+    mAcquiredInputBuffers++;
     SP_LOGV("acquired buffer %" PRId64 " from input at slot %d",
             bufferItem.mGraphicBuffer->getId(), bufferItem.mSlot);
 
@@ -592,6 +611,12 @@
         } else {
             SP_LOGE("%s: releaseBuffer returns %d", __FUNCTION__, res);
         }
+    } else {
+        if (mAcquiredInputBuffers == 0) {
+            ALOGW("%s: Acquired input buffer count already at zero!", __FUNCTION__);
+        } else {
+            mAcquiredInputBuffers--;
+        }
     }
 }
 
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
index fea1bdb..960f7aa 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
@@ -49,7 +49,7 @@
 public:
 
     // Constructor
-    Camera3StreamSplitter() = default;
+    Camera3StreamSplitter(bool useHalBufManager = false);
 
     // Connect to the stream splitter by creating buffer queue and connecting it
     // with output surfaces.
@@ -226,7 +226,10 @@
     android::PixelFormat mFormat = android::PIXEL_FORMAT_NONE;
     uint64_t mProducerUsage = 0;
 
-    static const nsecs_t kDequeueBufferTimeout   = s2ns(1); // 1 sec
+    // The attachBuffer call will happen on different thread according to mUseHalBufManager and have
+    // different timing constraint.
+    static const nsecs_t kNormalDequeueBufferTimeout    = s2ns(1);  // 1 sec
+    static const nsecs_t kHalBufMgrDequeueBufferTimeout = ms2ns(1); // 1 msec
 
     Mutex mMutex;
 
@@ -269,7 +272,12 @@
     // Latest onFrameAvailable return value
     std::atomic<status_t> mOnFrameAvailableRes{0};
 
+    // Currently acquired input buffers
+    size_t mAcquiredInputBuffers;
+
     String8 mConsumerName;
+
+    const bool mUseHalBufManager;
 };
 
 } // namespace android
diff --git a/services/camera/libcameraservice/device3/DistortionMapper.cpp b/services/camera/libcameraservice/device3/DistortionMapper.cpp
index 4dafefd..ae7af8e 100644
--- a/services/camera/libcameraservice/device3/DistortionMapper.cpp
+++ b/services/camera/libcameraservice/device3/DistortionMapper.cpp
@@ -312,8 +312,8 @@
         int32_t coords[4] = {
             rects[i],
             rects[i + 1],
-            rects[i] + rects[i + 2],
-            rects[i + 1] + rects[i + 3]
+            rects[i] + rects[i + 2] - 1,
+            rects[i + 1] + rects[i + 3] - 1
         };
 
         mapRawToCorrected(coords, 2, clamp, simple);
@@ -321,8 +321,8 @@
         // Map back to (l, t, width, height)
         rects[i] = coords[0];
         rects[i + 1] = coords[1];
-        rects[i + 2] = coords[2] - coords[0];
-        rects[i + 3] = coords[3] - coords[1];
+        rects[i + 2] = coords[2] - coords[0] + 1;
+        rects[i + 3] = coords[3] - coords[1] + 1;
     }
 
     return OK;
@@ -400,8 +400,8 @@
         int32_t coords[4] = {
             rects[i],
             rects[i + 1],
-            rects[i] + rects[i + 2],
-            rects[i + 1] + rects[i + 3]
+            rects[i] + rects[i + 2] - 1,
+            rects[i + 1] + rects[i + 3] - 1
         };
 
         mapCorrectedToRaw(coords, 2, clamp, simple);
@@ -409,8 +409,8 @@
         // Map back to (l, t, width, height)
         rects[i] = coords[0];
         rects[i + 1] = coords[1];
-        rects[i + 2] = coords[2] - coords[0];
-        rects[i + 3] = coords[3] - coords[1];
+        rects[i + 2] = coords[2] - coords[0] + 1;
+        rects[i + 3] = coords[3] - coords[1] + 1;
     }
 
     return OK;
diff --git a/services/camera/libcameraservice/hidl/AidlCameraDeviceCallbacks.cpp b/services/camera/libcameraservice/hidl/AidlCameraDeviceCallbacks.cpp
new file mode 100644
index 0000000..f063506
--- /dev/null
+++ b/services/camera/libcameraservice/hidl/AidlCameraDeviceCallbacks.cpp
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <hardware/camera.h>
+
+#include <hidl/AidlCameraDeviceCallbacks.h>
+#include <hidl/Convert.h>
+
+namespace android {
+namespace frameworks {
+namespace cameraservice {
+namespace device {
+namespace V2_0 {
+namespace implementation {
+
+using hardware::hidl_vec;
+using HCaptureResultExtras = android::frameworks::cameraservice::device::V2_0::CaptureResultExtras;
+using HPhysicalCaptureResultInfo = android::frameworks::cameraservice::device::V2_0::PhysicalCaptureResultInfo;
+using HCameraMetadata = android::frameworks::cameraservice::device::V2_0::CameraMetadata;
+
+const char *H2BCameraDeviceCallbacks::kResultKey = "CaptureResult";
+
+H2BCameraDeviceCallbacks::H2BCameraDeviceCallbacks(const sp<HalInterface>& base) : CBase(base) { }
+
+bool H2BCameraDeviceCallbacks::initializeLooper() {
+    mCbLooper = new ALooper;
+    mCbLooper->setName("cs-looper");
+    status_t err = mCbLooper->start(/*runOnCallingThread*/ false, /*canCallJava*/ false,
+                                    PRIORITY_DEFAULT);
+    if (err !=OK) {
+        ALOGE("Unable to start camera device callback looper");
+        return false;
+    }
+    mHandler = new CallbackHandler(this);
+    mCbLooper->registerHandler(mHandler);
+    return true;
+}
+
+H2BCameraDeviceCallbacks::~H2BCameraDeviceCallbacks() {
+    if (mCbLooper != nullptr) {
+        if (mHandler != nullptr) {
+            mCbLooper->unregisterHandler(mHandler->id());
+        }
+        mCbLooper->stop();
+    }
+    mCbLooper.clear();
+    mHandler.clear();
+}
+
+binder::Status H2BCameraDeviceCallbacks::onDeviceError(
+    int32_t errorCode, const CaptureResultExtras& resultExtras) {
+    using hardware::cameraservice::utils::conversion::convertToHidl;
+    HCaptureResultExtras hCaptureResultExtras = convertToHidl(resultExtras);
+    auto ret = mBase->onDeviceError(convertToHidl(errorCode), hCaptureResultExtras);
+    if (!ret.isOk()) {
+        ALOGE("%s OnDeviceError callback failed due to %s",__FUNCTION__,
+              ret.description().c_str());
+    }
+    return binder::Status::ok();
+}
+
+binder::Status H2BCameraDeviceCallbacks::onDeviceIdle() {
+    auto ret = mBase->onDeviceIdle();
+    if (!ret.isOk()) {
+          ALOGE("%s OnDeviceIdle callback failed due to %s",__FUNCTION__,
+                ret.description().c_str());
+    }
+    return binder::Status::ok();
+}
+
+binder::Status H2BCameraDeviceCallbacks::onCaptureStarted(
+    const CaptureResultExtras& resultExtras, int64_t timestamp) {
+    using hardware::cameraservice::utils::conversion::convertToHidl;
+    HCaptureResultExtras hCaptureResultExtras = convertToHidl(resultExtras);
+    auto ret = mBase->onCaptureStarted(hCaptureResultExtras, timestamp);
+    if (!ret.isOk()) {
+        ALOGE("%s OnCaptureCallback failed due to %s",__FUNCTION__,
+              ret.description().c_str());
+    }
+    return binder::Status::ok();
+}
+
+void H2BCameraDeviceCallbacks::convertResultMetadataToHidl(const camera_metadata_t *rawMetadata,
+                                                           FmqSizeOrMetadata *hResultMetadata) {
+    // First try writing to fmq.
+    size_t metadata_size = get_camera_metadata_size(rawMetadata);
+    if ((metadata_size > 0) &&
+        (mCaptureResultMetadataQueue->availableToWrite() > 0)) {
+        if (mCaptureResultMetadataQueue->write((uint8_t *)rawMetadata, metadata_size)) {
+            hResultMetadata->fmqMetadataSize(metadata_size);
+        } else {
+            ALOGW("%s Couldn't use fmq, falling back to hwbinder", __FUNCTION__);
+            HCameraMetadata metadata;
+            hardware::cameraservice::utils::conversion::convertToHidl(rawMetadata, &metadata);
+            hResultMetadata->metadata(std::move(metadata));
+        }
+    }
+}
+
+void H2BCameraDeviceCallbacks::CallbackHandler::onMessageReceived(const sp<AMessage> &msg) {
+    sp<RefBase> obj = nullptr;
+    sp<ResultWrapper> resultWrapper = nullptr;
+    bool found = false;
+    switch (msg->what()) {
+        case kWhatResultReceived:
+            found = msg->findObject(kResultKey, &obj);
+            if (!found || obj == nullptr) {
+                ALOGE("Cannot find result object in callback message");
+                return;
+            }
+            resultWrapper = static_cast<ResultWrapper *>(obj.get());
+            processResultMessage(resultWrapper);
+            break;
+        default:
+            ALOGE("Unknown callback sent");
+            break;
+    }
+    return;
+}
+
+void H2BCameraDeviceCallbacks::CallbackHandler::processResultMessage(
+    sp<ResultWrapper> &resultWrapper) {
+    sp<H2BCameraDeviceCallbacks> converter = mConverter.promote();
+    if (converter == nullptr) {
+        ALOGE("Callback wrapper has died, result callback cannot be made");
+        return;
+    }
+    CameraMetadataNative &result = resultWrapper->mResult;
+    auto resultExtras = resultWrapper->mResultExtras;
+    HCaptureResultExtras hResultExtras =
+            hardware::cameraservice::utils::conversion::convertToHidl(resultExtras);
+
+    // Convert Metadata into HCameraMetadata;
+    FmqSizeOrMetadata hResult;
+    const camera_metadata_t *rawMetadata = result.getAndLock();
+    converter->convertResultMetadataToHidl(rawMetadata, &hResult);
+    result.unlock(rawMetadata);
+    auto &physicalCaptureResultInfos = resultWrapper->mPhysicalCaptureResultInfos;
+    hidl_vec<HPhysicalCaptureResultInfo> hPhysicalCaptureResultInfos =
+            hardware::cameraservice::utils::conversion::convertToHidl(
+                    physicalCaptureResultInfos, converter->mCaptureResultMetadataQueue);
+    auto ret = converter->mBase->onResultReceived(hResult, hResultExtras,
+                                                  hPhysicalCaptureResultInfos);
+    if (!ret.isOk()) {
+          ALOGE("%s OnResultReceived callback failed due to %s",__FUNCTION__,
+                ret.description().c_str());
+    }
+}
+
+binder::Status H2BCameraDeviceCallbacks::onResultReceived(
+    const CameraMetadataNative& result,
+    const CaptureResultExtras& resultExtras,
+    const ::std::vector<PhysicalCaptureResultInfo>& physicalCaptureResultInfos) {
+    // Wrap CameraMetadata, resultExtras and physicalCaptureResultInfos in on
+    // sp<RefBase>-able structure and post it.
+    sp<ResultWrapper> resultWrapper = new ResultWrapper(const_cast<CameraMetadataNative &>(result),
+                                                        resultExtras, physicalCaptureResultInfos);
+    sp<AMessage> msg = new AMessage(kWhatResultReceived, mHandler);
+    msg->setObject(kResultKey, resultWrapper);
+    msg->post();
+    return binder::Status::ok();
+}
+
+binder::Status H2BCameraDeviceCallbacks::onPrepared(int32_t streamId) {
+    // not implemented
+    // To silence Wunused-parameter.
+    (void) streamId;
+    return binder::Status::ok();
+}
+
+binder::Status H2BCameraDeviceCallbacks::onRepeatingRequestError(
+    int64_t lastFrameNumber,
+    int32_t repeatingRequestId) {
+    auto ret =
+        mBase->onRepeatingRequestError(lastFrameNumber, repeatingRequestId);
+    if (!ret.isOk()) {
+        ALOGE("%s OnRepeatingRequestEror callback failed due to %s",__FUNCTION__,
+              ret.description().c_str());
+    }
+    return binder::Status::ok();
+}
+
+binder::Status H2BCameraDeviceCallbacks::onRequestQueueEmpty() {
+    // not implemented
+    return binder::Status::ok();
+}
+
+} // implementation
+} // V2_0
+} // device
+} // cameraservice
+} // frameworks
+} // android
diff --git a/services/camera/libcameraservice/hidl/AidlCameraDeviceCallbacks.h b/services/camera/libcameraservice/hidl/AidlCameraDeviceCallbacks.h
new file mode 100644
index 0000000..dbf520a
--- /dev/null
+++ b/services/camera/libcameraservice/hidl/AidlCameraDeviceCallbacks.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_FRAMEWORKS_AIDL_CAMERADEVICECALLBACKS_H
+#define ANDROID_FRAMEWORKS_AIDL_CAMERADEVICECALLBACKS_H
+
+#include <mutex>
+#include <thread>
+
+#include <android/frameworks/cameraservice/common/2.0/types.h>
+#include <android/frameworks/cameraservice/service/2.0/types.h>
+#include <android/frameworks/cameraservice/device/2.0/ICameraDeviceCallback.h>
+#include <android/frameworks/cameraservice/device/2.0/types.h>
+#include <android/hardware/camera2/BnCameraDeviceCallbacks.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/foundation/AHandler.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <fmq/MessageQueue.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <CameraService.h>
+#include <hidl/CameraHybridInterface.h>
+
+namespace android {
+namespace frameworks {
+namespace cameraservice {
+namespace device {
+namespace V2_0 {
+namespace implementation {
+
+using camerahybrid::H2BConverter;
+using HCameraDeviceCallback = cameraservice::device::V2_0::ICameraDeviceCallback;
+using HPhysicalCaptureResultInfo = cameraservice::device::V2_0::PhysicalCaptureResultInfo;
+using android::frameworks::cameraservice::device::V2_0::FmqSizeOrMetadata;
+
+using hardware::camera2::BnCameraDeviceCallbacks;
+using hardware::camera2::ICameraDeviceCallbacks;
+using hardware::camera2::impl::CaptureResultExtras;
+using hardware::camera2::impl::CameraMetadataNative;
+using hardware::camera2::impl::PhysicalCaptureResultInfo;
+using hardware::kSynchronizedReadWrite;
+using hardware::MessageQueue;
+using CaptureResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+
+struct H2BCameraDeviceCallbacks :
+    public H2BConverter<HCameraDeviceCallback, ICameraDeviceCallbacks, BnCameraDeviceCallbacks> {
+    H2BCameraDeviceCallbacks(const sp<HalInterface>& base);
+
+    ~H2BCameraDeviceCallbacks();
+
+    bool initializeLooper();
+
+    virtual binder::Status onDeviceError(int32_t errorCode,
+                                         const CaptureResultExtras& resultExtras) override;
+
+    virtual binder::Status onDeviceIdle() override;
+
+    virtual binder::Status onCaptureStarted(const CaptureResultExtras& resultExtras,
+                                            int64_t timestamp) override;
+
+    virtual binder::Status onResultReceived(
+        const CameraMetadataNative& result, const CaptureResultExtras& resultExtras,
+        const std::vector<PhysicalCaptureResultInfo>& physicalCaptureResultInfos) override;
+
+    virtual binder::Status onPrepared(int32_t streamId) override;
+
+    virtual binder::Status onRepeatingRequestError(int64_t lastFrameNumber,
+                                                   int32_t repeatingRequestId) override;
+
+    virtual binder::Status onRequestQueueEmpty() override;
+
+    void setCaptureResultMetadataQueue(std::shared_ptr<CaptureResultMetadataQueue> metadataQueue) {
+        mCaptureResultMetadataQueue = metadataQueue;
+    }
+
+ private:
+    // Wrapper struct so that parameters to onResultReceived callback may be
+    // sent through an AMessage.
+    struct ResultWrapper : public RefBase {
+        CameraMetadataNative mResult;
+        CaptureResultExtras mResultExtras;
+        std::vector<PhysicalCaptureResultInfo> mPhysicalCaptureResultInfos;
+        ResultWrapper(CameraMetadataNative &result,
+                      const CaptureResultExtras resultExtras,
+                      const std::vector<PhysicalCaptureResultInfo> &physicalCaptureResultInfos) :
+      // TODO: make this std::movable
+      mResult(result), mResultExtras(resultExtras), mPhysicalCaptureResultInfos(physicalCaptureResultInfos) { }
+    };
+
+    struct CallbackHandler : public AHandler {
+        public:
+            void onMessageReceived(const sp<AMessage> &msg) override;
+            CallbackHandler(H2BCameraDeviceCallbacks *converter) : mConverter(converter) { }
+        private:
+            void processResultMessage(sp<ResultWrapper> &resultWrapper);
+            wp<H2BCameraDeviceCallbacks> mConverter = nullptr;
+            Mutex mMetadataQueueLock;
+    };
+
+    void convertResultMetadataToHidl(const camera_metadata *rawMetadata,
+                                     FmqSizeOrMetadata *resultMetadata);
+    enum {
+        kWhatResultReceived,
+    };
+
+    static const char *kResultKey;
+
+    std::shared_ptr<CaptureResultMetadataQueue> mCaptureResultMetadataQueue = nullptr;
+    sp<CallbackHandler> mHandler = nullptr;
+    sp<ALooper> mCbLooper = nullptr;
+};
+
+} // implementation
+} // V2_0
+} // device
+} // cameraservice
+} // frameworks
+} // android
+#endif // ANDROID_FRAMEWORKS_AIDL_CAMERADEVICECALLBACKS_H
diff --git a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.cpp b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.cpp
new file mode 100644
index 0000000..110ef8e
--- /dev/null
+++ b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <hidl/AidlCameraServiceListener.h>
+#include <hidl/Convert.h>
+
+namespace android {
+namespace frameworks {
+namespace cameraservice {
+namespace service {
+namespace V2_0 {
+namespace implementation {
+
+using hardware::cameraservice::utils::conversion::convertToHidlCameraDeviceStatus;
+
+binder::Status H2BCameraServiceListener::onStatusChanged(
+    int32_t status, const ::android::String16& cameraId) {
+  HCameraDeviceStatus hCameraDeviceStatus = convertToHidlCameraDeviceStatus(status);
+  CameraStatusAndId cameraStatusAndId;
+  cameraStatusAndId.deviceStatus = hCameraDeviceStatus;
+  cameraStatusAndId.cameraId = String8(cameraId).string();
+  auto ret = mBase->onStatusChanged(cameraStatusAndId);
+  if (!ret.isOk()) {
+      ALOGE("%s OnStatusChanged callback failed due to %s",__FUNCTION__,
+            ret.description().c_str());
+  }
+  return binder::Status::ok();
+}
+
+::android::binder::Status H2BCameraServiceListener::onTorchStatusChanged(
+    int32_t, const ::android::String16&) {
+  // We don't implement onTorchStatusChanged
+  return binder::Status::ok();
+}
+
+} // implementation
+} // V2_0
+} // common
+} // cameraservice
+} // frameworks
+} // android
diff --git a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
new file mode 100644
index 0000000..0f6be79
--- /dev/null
+++ b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <mutex>
+#include <thread>
+
+#include <android/frameworks/cameraservice/common/2.0/types.h>
+#include <android/frameworks/cameraservice/service/2.0/ICameraServiceListener.h>
+#include <android/frameworks/cameraservice/device/2.0/types.h>
+#include <android/hardware/BnCameraServiceListener.h>
+#include <android/hardware/BpCameraServiceListener.h>
+
+#include <hidl/Status.h>
+#include <hidl/CameraHybridInterface.h>
+
+namespace android {
+namespace frameworks {
+namespace cameraservice {
+namespace service {
+namespace V2_0 {
+namespace implementation {
+
+using hardware::BnCameraServiceListener;
+using hardware::BpCameraServiceListener;
+using camerahybrid::H2BConverter;
+using HCameraDeviceStatus = frameworks::cameraservice::service::V2_0::CameraDeviceStatus;
+typedef frameworks::cameraservice::service::V2_0::ICameraServiceListener HCameraServiceListener;
+
+struct H2BCameraServiceListener :
+    public H2BConverter<HCameraServiceListener, ICameraServiceListener, BnCameraServiceListener> {
+    H2BCameraServiceListener(const sp<HalInterface>& base) : CBase(base) { }
+
+    ~H2BCameraServiceListener() { }
+
+    virtual ::android::binder::Status onStatusChanged(int32_t status,
+                                                      const ::android::String16& cameraId) override;
+
+    virtual ::android::binder::Status onTorchStatusChanged(
+        int32_t status, const ::android::String16& cameraId) override;
+    virtual binder::Status onCameraAccessPrioritiesChanged() {
+        // TODO: no implementation yet.
+        return binder::Status::ok();
+    }
+};
+
+} // implementation
+} // V2_0
+} // service
+} // cameraservice
+} // frameworks
+} // android
diff --git a/services/camera/libcameraservice/hidl/CameraHybridInterface.h b/services/camera/libcameraservice/hidl/CameraHybridInterface.h
new file mode 100644
index 0000000..baf0112
--- /dev/null
+++ b/services/camera/libcameraservice/hidl/CameraHybridInterface.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_CAMERA_HYBRIDINTERFACE_H
+#define ANDROID_CAMERA_HYBRIDINTERFACE_H
+
+#include <vector>
+#include <mutex>
+
+#include <binder/Parcel.h>
+#include <hidl/HidlSupport.h>
+
+namespace android {
+namespace camerahybrid {
+typedef ::android::hidl::base::V1_0::IBase HInterface;
+
+template <
+        typename HINTERFACE,
+        typename INTERFACE,
+        typename BNINTERFACE >
+class H2BConverter : public BNINTERFACE {
+public:
+    typedef H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE> CBase; // Converter Base
+    typedef INTERFACE BaseInterface;
+    typedef HINTERFACE HalInterface;
+
+    H2BConverter(const sp<HalInterface>& base) : mBase(base) {}
+    virtual sp<HalInterface> getHalInterface() { return mBase; }
+    virtual status_t linkToDeath(
+            const sp<IBinder::DeathRecipient>& recipient,
+            void* cookie = nullptr,
+            uint32_t flags = 0);
+    virtual status_t unlinkToDeath(
+            const wp<IBinder::DeathRecipient>& recipient,
+            void* cookie = nullptr,
+            uint32_t flags = 0,
+            wp<IBinder::DeathRecipient>* outRecipient = nullptr);
+
+protected:
+    sp<HalInterface> mBase;
+    struct Obituary : public hardware::hidl_death_recipient {
+        wp<IBinder::DeathRecipient> recipient;
+        void* cookie;
+        uint32_t flags;
+        wp<IBinder> who;
+        Obituary(
+                const wp<IBinder::DeathRecipient>& r,
+                void* c, uint32_t f,
+                const wp<IBinder>& w) :
+            recipient(r), cookie(c), flags(f), who(w) {
+        }
+        Obituary(const Obituary& o) :
+            recipient(o.recipient),
+            cookie(o.cookie),
+            flags(o.flags),
+            who(o.who) {
+        }
+        Obituary& operator=(const Obituary& o) {
+            recipient = o.recipient;
+            cookie = o.cookie;
+            flags = o.flags;
+            who = o.who;
+            return *this;
+        }
+        void serviceDied(uint64_t, const wp<HInterface>&) override {
+            sp<IBinder::DeathRecipient> dr = recipient.promote();
+            if (dr != nullptr) {
+                dr->binderDied(who);
+            }
+        }
+    };
+    std::mutex mObituariesLock;
+    std::vector<sp<Obituary> > mObituaries;
+};
+
+template <
+        typename HINTERFACE,
+        typename INTERFACE,
+        typename BNINTERFACE>
+status_t H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE>::
+        linkToDeath(
+        const sp<IBinder::DeathRecipient>& recipient,
+        void* cookie, uint32_t flags) {
+    LOG_ALWAYS_FATAL_IF(recipient == nullptr,
+            "linkToDeath(): recipient must be non-nullptr");
+    {
+        std::lock_guard<std::mutex> lock(mObituariesLock);
+        mObituaries.push_back(new Obituary(recipient, cookie, flags, this));
+        if (!mBase->linkToDeath(mObituaries.back(), 0)) {
+           return DEAD_OBJECT;
+        }
+    }
+    return NO_ERROR;
+}
+
+template <
+        typename HINTERFACE,
+        typename INTERFACE,
+        typename BNINTERFACE>
+status_t H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE>::
+        unlinkToDeath(
+        const wp<IBinder::DeathRecipient>& recipient,
+        void* cookie, uint32_t flags,
+        wp<IBinder::DeathRecipient>* outRecipient) {
+    std::lock_guard<std::mutex> lock(mObituariesLock);
+    for (auto i = mObituaries.begin(); i != mObituaries.end(); ++i) {
+        if ((flags = (*i)->flags) && (
+                (recipient == (*i)->recipient) ||
+                ((recipient == nullptr) && (cookie == (*i)->cookie)))) {
+            if (outRecipient != nullptr) {
+                *outRecipient = (*i)->recipient;
+            }
+            bool success = mBase->unlinkToDeath(*i);
+            mObituaries.erase(i);
+            return success ? NO_ERROR : DEAD_OBJECT;
+        }
+    }
+    return NAME_NOT_FOUND;
+}
+
+} // namespace camerahybrid
+} // namespace android
+
+#endif // ANDROID_CAMERA_HYBRIDINTERFACE_H
+
diff --git a/services/camera/libcameraservice/hidl/Convert.cpp b/services/camera/libcameraservice/hidl/Convert.cpp
new file mode 100644
index 0000000..866c3b5
--- /dev/null
+++ b/services/camera/libcameraservice/hidl/Convert.cpp
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <hidl/Convert.h>
+#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
+#include <cutils/native_handle.h>
+#include <mediautils/AImageReaderUtils.h>
+
+namespace android {
+namespace hardware {
+namespace cameraservice {
+namespace utils {
+namespace conversion {
+
+using hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer;
+using aimg::AImageReader_getHGBPFromHandle;
+
+// Note: existing data in dst will be gone. Caller still owns the memory of src
+void convertToHidl(const camera_metadata_t *src, HCameraMetadata* dst) {
+    if (src == nullptr) {
+        ALOGW("%s:attempt to convert empty metadata to Hidl", __FUNCTION__);
+        return;
+    }
+    size_t size = get_camera_metadata_size(src);
+    dst->setToExternal((uint8_t *) src, size);
+    return;
+}
+
+int32_t convertFromHidl(HStreamConfigurationMode streamConfigurationMode) {
+    switch (streamConfigurationMode) {
+        case HStreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE:
+            return camera2::ICameraDeviceUser::CONSTRAINED_HIGH_SPEED_MODE;
+        case HStreamConfigurationMode::NORMAL_MODE:
+            return camera2::ICameraDeviceUser::NORMAL_MODE;
+        default:
+            // TODO: Fix this
+            return camera2::ICameraDeviceUser::VENDOR_MODE_START;
+    }
+}
+
+int32_t convertFromHidl(HTemplateId templateId) {
+    switch(templateId) {
+        case HTemplateId::PREVIEW:
+            return camera2::ICameraDeviceUser::TEMPLATE_PREVIEW;
+        case HTemplateId::STILL_CAPTURE:
+            return camera2::ICameraDeviceUser::TEMPLATE_STILL_CAPTURE;
+        case HTemplateId::RECORD:
+            return camera2::ICameraDeviceUser::TEMPLATE_RECORD;
+        case HTemplateId::VIDEO_SNAPSHOT:
+            return camera2::ICameraDeviceUser::TEMPLATE_VIDEO_SNAPSHOT;
+        case HTemplateId::ZERO_SHUTTER_LAG:
+            return camera2::ICameraDeviceUser::TEMPLATE_ZERO_SHUTTER_LAG;
+        case HTemplateId::MANUAL:
+            return camera2::ICameraDeviceUser::TEMPLATE_MANUAL;
+    }
+}
+
+int convertFromHidl(HOutputConfiguration::Rotation rotation) {
+    switch(rotation) {
+        case HOutputConfiguration::Rotation::R0:
+            return 0;
+        case HOutputConfiguration::Rotation::R90:
+            return 1;
+        case HOutputConfiguration::Rotation::R180:
+            return 2;
+        case HOutputConfiguration::Rotation::R270:
+            return 3;
+    }
+}
+
+hardware::camera2::params::OutputConfiguration convertFromHidl(
+    const HOutputConfiguration &hOutputConfiguration) {
+    std::vector<sp<IGraphicBufferProducer>> iGBPs;
+    auto &windowHandles = hOutputConfiguration.windowHandles;
+    iGBPs.reserve(windowHandles.size());
+    for (auto &handle : windowHandles) {
+        iGBPs.push_back(new H2BGraphicBufferProducer(AImageReader_getHGBPFromHandle(handle)));
+    }
+    String16 physicalCameraId16(hOutputConfiguration.physicalCameraId.c_str());
+    hardware::camera2::params::OutputConfiguration outputConfiguration(
+        iGBPs, convertFromHidl(hOutputConfiguration.rotation), physicalCameraId16,
+        hOutputConfiguration.windowGroupId, OutputConfiguration::SURFACE_TYPE_UNKNOWN, 0, 0,
+        (windowHandles.size() > 1));
+    return outputConfiguration;
+}
+
+hardware::camera2::params::SessionConfiguration convertFromHidl(
+    const HSessionConfiguration &hSessionConfiguration) {
+    hardware::camera2::params::SessionConfiguration sessionConfig(
+            hSessionConfiguration.inputWidth, hSessionConfiguration.inputHeight,
+            hSessionConfiguration.inputFormat,
+            static_cast<int>(hSessionConfiguration.operationMode));
+
+    for (const auto& hConfig : hSessionConfiguration.outputStreams) {
+        hardware::camera2::params::OutputConfiguration config = convertFromHidl(hConfig);
+        sessionConfig.addOutputConfiguration(config);
+    }
+
+    return sessionConfig;
+}
+
+// The camera metadata here is cloned. Since we're reading metadata over
+// hwbinder we would need to clone it in order to avoid aligment issues.
+bool convertFromHidl(const HCameraMetadata &src, CameraMetadata *dst) {
+    const camera_metadata_t *buffer = reinterpret_cast<const camera_metadata_t*>(src.data());
+    size_t expectedSize = src.size();
+    if (buffer != nullptr) {
+        int res = validate_camera_metadata_structure(buffer, &expectedSize);
+        if (res == OK || res == CAMERA_METADATA_VALIDATION_SHIFTED) {
+            *dst = buffer;
+        } else {
+            ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
+            return false;
+        }
+    }
+    return true;
+}
+
+HCameraDeviceStatus convertToHidlCameraDeviceStatus(int32_t status) {
+    HCameraDeviceStatus deviceStatus = HCameraDeviceStatus::STATUS_UNKNOWN;
+    switch(status) {
+        case hardware::ICameraServiceListener::STATUS_NOT_PRESENT:
+            deviceStatus = HCameraDeviceStatus::STATUS_NOT_PRESENT;
+            break;
+        case hardware::ICameraServiceListener::STATUS_PRESENT:
+            deviceStatus = HCameraDeviceStatus::STATUS_PRESENT;
+            break;
+        case hardware::ICameraServiceListener::STATUS_ENUMERATING:
+            deviceStatus = HCameraDeviceStatus::STATUS_ENUMERATING;
+            break;
+        case hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE:
+            deviceStatus = HCameraDeviceStatus::STATUS_NOT_AVAILABLE;
+            break;
+        default:
+            break;
+    }
+    return deviceStatus;
+}
+
+HCaptureResultExtras convertToHidl(const CaptureResultExtras &captureResultExtras) {
+    HCaptureResultExtras hCaptureResultExtras;
+    hCaptureResultExtras.requestId = captureResultExtras.requestId;
+    hCaptureResultExtras.burstId = captureResultExtras.burstId;
+    hCaptureResultExtras.frameNumber = captureResultExtras.frameNumber;
+    hCaptureResultExtras.partialResultCount = captureResultExtras.partialResultCount;
+    hCaptureResultExtras.errorStreamId = captureResultExtras.errorStreamId;
+    hCaptureResultExtras.errorPhysicalCameraId = hidl_string(String8(
+            captureResultExtras.errorPhysicalCameraId).string());
+    return hCaptureResultExtras;
+}
+
+HErrorCode convertToHidl(int32_t errorCode) {
+    switch(errorCode) {
+        case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED:
+            return HErrorCode::CAMERA_DISCONNECTED;
+        case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE :
+            return HErrorCode::CAMERA_DEVICE;
+        case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE:
+            return HErrorCode::CAMERA_SERVICE;
+        case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST:
+            return HErrorCode::CAMERA_REQUEST;
+        case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT:
+            return HErrorCode::CAMERA_RESULT;
+        case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER:
+            return HErrorCode::CAMERA_BUFFER;
+        case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISABLED:
+            return HErrorCode::CAMERA_DISABLED;
+        case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_INVALID_ERROR:
+            return HErrorCode::CAMERA_INVALID_ERROR;
+        default:
+            return HErrorCode::CAMERA_UNKNOWN_ERROR;
+    }
+}
+
+void convertToHidl(const std::vector<hardware::CameraStatus> &src,
+                   hidl_vec<HCameraStatusAndId>* dst) {
+    dst->resize(src.size());
+    size_t i = 0;
+    for (auto &statusAndId : src) {
+        auto &a = (*dst)[i++];
+        a.cameraId = statusAndId.cameraId.c_str();
+        a.deviceStatus = convertToHidlCameraDeviceStatus(statusAndId.status);
+    }
+    return;
+}
+
+void convertToHidl(
+    const hardware::camera2::utils::SubmitInfo &submitInfo,
+    frameworks::cameraservice::device::V2_0::SubmitInfo *hSubmitInfo) {
+    hSubmitInfo->requestId = submitInfo.mRequestId;
+    hSubmitInfo->lastFrameNumber = submitInfo.mLastFrameNumber;
+}
+
+HStatus B2HStatus(const binder::Status &bStatus) {
+    HStatus status = HStatus::NO_ERROR;
+    if (bStatus.isOk()) {
+        // NO Error here
+        return status;
+    }
+    switch(bStatus.serviceSpecificErrorCode()) {
+        case hardware::ICameraService::ERROR_DISCONNECTED:
+            status = HStatus::DISCONNECTED;
+            break;
+        case hardware::ICameraService::ERROR_CAMERA_IN_USE:
+            status = HStatus::CAMERA_IN_USE;
+            break;
+        case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE:
+            status = HStatus::MAX_CAMERAS_IN_USE;
+            break;
+        case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
+            status = HStatus::ILLEGAL_ARGUMENT;
+            break;
+        case hardware::ICameraService::ERROR_DEPRECATED_HAL:
+            // Should not reach here since we filtered legacy HALs earlier
+            status = HStatus::DEPRECATED_HAL;
+            break;
+        case hardware::ICameraService::ERROR_DISABLED:
+            status = HStatus::DISABLED;
+            break;
+        case hardware::ICameraService::ERROR_PERMISSION_DENIED:
+            status = HStatus::PERMISSION_DENIED;
+            break;
+        case hardware::ICameraService::ERROR_INVALID_OPERATION:
+            status = HStatus::INVALID_OPERATION;
+            break;
+        default:
+            status = HStatus::UNKNOWN_ERROR;
+            break;
+    }
+  return status;
+}
+
+HPhysicalCaptureResultInfo convertToHidl(
+    const PhysicalCaptureResultInfo &physicalCaptureResultInfo,
+    std::shared_ptr<CaptureResultMetadataQueue> &captureResultMetadataQueue) {
+    HPhysicalCaptureResultInfo hPhysicalCaptureResultInfo;
+    hPhysicalCaptureResultInfo.physicalCameraId =
+        String8(physicalCaptureResultInfo.mPhysicalCameraId).string();
+    const camera_metadata_t *rawMetadata =
+        physicalCaptureResultInfo.mPhysicalCameraMetadata.getAndLock();
+    // Try using fmq at first.
+    size_t metadata_size = get_camera_metadata_size(rawMetadata);
+    if ((metadata_size > 0) && (captureResultMetadataQueue->availableToWrite() > 0)) {
+        if (captureResultMetadataQueue->write((uint8_t *)rawMetadata, metadata_size)) {
+            hPhysicalCaptureResultInfo.physicalCameraMetadata.fmqMetadataSize(metadata_size);
+        } else {
+            ALOGW("%s Couldn't use fmq, falling back to hwbinder", __FUNCTION__);
+            HCameraMetadata metadata;
+            convertToHidl(rawMetadata, &metadata);
+            hPhysicalCaptureResultInfo.physicalCameraMetadata.metadata(std::move(metadata));
+        }
+    }
+    physicalCaptureResultInfo.mPhysicalCameraMetadata.unlock(rawMetadata);
+    return hPhysicalCaptureResultInfo;
+}
+
+hidl_vec<HPhysicalCaptureResultInfo> convertToHidl(
+    const std::vector<PhysicalCaptureResultInfo> &physicalCaptureResultInfos,
+    std::shared_ptr<CaptureResultMetadataQueue> &captureResultMetadataQueue) {
+    hidl_vec<HPhysicalCaptureResultInfo> hPhysicalCaptureResultInfos;
+    hPhysicalCaptureResultInfos.resize(physicalCaptureResultInfos.size());
+    size_t i = 0;
+    for (auto &physicalCaptureResultInfo : physicalCaptureResultInfos) {
+        hPhysicalCaptureResultInfos[i++] = convertToHidl(physicalCaptureResultInfo,
+                                                         captureResultMetadataQueue);
+    }
+    return hPhysicalCaptureResultInfos;
+}
+
+} //conversion
+} // utils
+} //cameraservice
+} // hardware
+} // android
diff --git a/services/camera/libcameraservice/hidl/Convert.h b/services/camera/libcameraservice/hidl/Convert.h
new file mode 100644
index 0000000..79683f6
--- /dev/null
+++ b/services/camera/libcameraservice/hidl/Convert.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CAMERASERVER_CONVERT_HIDL
+#define CAMERASERVER_CONVERT_HIDL
+
+#include <vector>
+
+#include <android/frameworks/cameraservice/service/2.0/ICameraService.h>
+#include <android/frameworks/cameraservice/device/2.0/ICameraDeviceUser.h>
+#include <android/frameworks/cameraservice/common/2.0/types.h>
+#include <android/frameworks/cameraservice/service/2.0/types.h>
+#include <android/frameworks/cameraservice/device/2.0/types.h>
+#include <android/hardware/camera/common/1.0/types.h>
+#include <android/hardware/camera2/ICameraDeviceUser.h>
+#include <android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer.h>
+#include <android/hardware/ICameraService.h>
+#include <fmq/MessageQueue.h>
+#include <hardware/camera.h>
+#include <hidl/MQDescriptor.h>
+
+namespace android {
+namespace hardware {
+namespace cameraservice {
+namespace utils {
+namespace conversion {
+
+using hardware::camera2::impl::CaptureResultExtras;
+using hardware::camera2::impl::PhysicalCaptureResultInfo;
+
+using CaptureResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+using HCameraMetadata = frameworks::cameraservice::service::V2_0::CameraMetadata;
+using HCameraDeviceStatus = frameworks::cameraservice::service::V2_0::CameraDeviceStatus;
+using HCameraStatusAndId = frameworks::cameraservice::service::V2_0::CameraStatusAndId;
+using HCameraDeviceUser = frameworks::cameraservice::device::V2_0::ICameraDeviceUser;
+using HCaptureResultExtras = frameworks::cameraservice::device::V2_0::CaptureResultExtras;
+using HCaptureRequest = frameworks::cameraservice::device::V2_0::CaptureRequest;
+using HErrorCode = frameworks::cameraservice::device::V2_0::ErrorCode;
+using HGraphicBufferProducer = hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer;
+using HOutputConfiguration = frameworks::cameraservice::device::V2_0::OutputConfiguration;
+using HPhysicalCameraSettings = frameworks::cameraservice::device::V2_0::PhysicalCameraSettings;
+using HPhysicalCaptureResultInfo = frameworks::cameraservice::device::V2_0::PhysicalCaptureResultInfo;
+using HSessionConfiguration = frameworks::cameraservice::device::V2_0::SessionConfiguration;
+using HSubmitInfo = frameworks::cameraservice::device::V2_0::SubmitInfo;
+using HStatus = frameworks::cameraservice::common::V2_0::Status;
+using HStreamConfigurationMode = frameworks::cameraservice::device::V2_0::StreamConfigurationMode;
+using HTemplateId = frameworks::cameraservice::device::V2_0::TemplateId;
+
+// Note: existing data in dst will be gone. Caller still owns the memory of src
+void convertToHidl(const camera_metadata_t *src, HCameraMetadata* dst);
+
+int32_t convertFromHidl(HStreamConfigurationMode streamConfigurationMode);
+
+int32_t convertFromHidl(HTemplateId templateId);
+
+bool convertFromHidl(const HCameraMetadata &src, CameraMetadata *dst);
+
+hardware::camera2::params::OutputConfiguration convertFromHidl(
+    const HOutputConfiguration &hOutputConfiguration);
+
+hardware::camera2::params::SessionConfiguration convertFromHidl(
+    const HSessionConfiguration &hSessionConfiguration);
+
+HCameraDeviceStatus convertToHidlCameraDeviceStatus(int32_t status);
+
+void convertToHidl(const std::vector<hardware::CameraStatus> &src,
+                   hidl_vec<HCameraStatusAndId>* dst);
+
+void convertToHidl(const hardware::camera2::utils::SubmitInfo &submitInfo,
+                   HSubmitInfo *hSubmitInfo);
+
+HErrorCode convertToHidl(int32_t errorCode);
+
+HCaptureResultExtras convertToHidl(const CaptureResultExtras &captureResultExtras);
+
+hidl_vec<HPhysicalCaptureResultInfo> convertToHidl(
+    const std::vector<PhysicalCaptureResultInfo> &physicalCaptureResultInfos,
+    std::shared_ptr<CaptureResultMetadataQueue> &captureResultMetadataQueue);
+
+HStatus B2HStatus(const binder::Status &bStatus);
+
+} // conversion
+} // utils
+} // cameraservice
+} // hardware
+} //android
+
+#endif //CAMERASERVER_CONVERT_TO_HIDL
diff --git a/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.cpp b/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.cpp
new file mode 100644
index 0000000..675ad24
--- /dev/null
+++ b/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.cpp
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/hardware/camera/device/3.2/types.h>
+#include <cutils/properties.h>
+#include <gui/Surface.h>
+#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
+
+#include <hidl/AidlCameraDeviceCallbacks.h>
+#include <hidl/Convert.h>
+#include <hidl/HidlCameraDeviceUser.h>
+#include <android/hardware/camera/device/3.2/types.h>
+
+namespace android {
+namespace frameworks {
+namespace cameraservice {
+namespace device {
+namespace V2_0 {
+namespace implementation {
+
+using hardware::cameraservice::utils::conversion::convertToHidl;
+using hardware::cameraservice::utils::conversion::convertFromHidl;
+using hardware::cameraservice::utils::conversion::B2HStatus;
+
+using hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer;
+using hardware::hidl_vec;
+using hardware::Return;
+using hardware::Void;
+using HSubmitInfo = device::V2_0::SubmitInfo;
+using hardware::camera2::params::OutputConfiguration;
+using hardware::camera2::params::SessionConfiguration;
+
+static constexpr int32_t CAMERA_REQUEST_METADATA_QUEUE_SIZE = 1 << 20 /* 1 MB */;
+static constexpr int32_t CAMERA_RESULT_METADATA_QUEUE_SIZE = 1 << 20 /* 1 MB */;
+
+Return<void> HidlCameraDeviceUser::disconnect() {
+    mDeviceRemote->disconnect();
+    return Void();
+}
+
+HidlCameraDeviceUser::HidlCameraDeviceUser(
+    const sp<hardware::camera2::ICameraDeviceUser> &deviceRemote)
+  : mDeviceRemote(deviceRemote) {
+    mInitSuccess = initDevice();
+}
+
+bool HidlCameraDeviceUser::initDevice() {
+    // TODO: Get request and result metadata queue size from a system property.
+    int32_t reqFMQSize = CAMERA_REQUEST_METADATA_QUEUE_SIZE;
+
+    mCaptureRequestMetadataQueue =
+        std::make_unique<CaptureRequestMetadataQueue>(static_cast<size_t>(reqFMQSize),
+                                                      false /* non blocking */);
+    if (!mCaptureRequestMetadataQueue->isValid()) {
+        ALOGE("%s: invalid request fmq", __FUNCTION__);
+        return false;
+    }
+
+    int32_t resFMQSize = CAMERA_RESULT_METADATA_QUEUE_SIZE;
+    mCaptureResultMetadataQueue =
+        std::make_shared<CaptureResultMetadataQueue>(static_cast<size_t>(resFMQSize),
+                                                     false /* non blocking */);
+    if (!mCaptureResultMetadataQueue->isValid()) {
+        ALOGE("%s: invalid result fmq", __FUNCTION__);
+        return false;
+    }
+    return true;
+}
+
+Return<void> HidlCameraDeviceUser::getCaptureRequestMetadataQueue(
+    getCaptureRequestMetadataQueue_cb _hidl_cb) {
+    if (mInitSuccess) {
+        _hidl_cb(*mCaptureRequestMetadataQueue->getDesc());
+    }
+    return Void();
+}
+
+Return<void> HidlCameraDeviceUser::getCaptureResultMetadataQueue(
+    getCaptureResultMetadataQueue_cb _hidl_cb) {
+    if (mInitSuccess) {
+        _hidl_cb(*mCaptureResultMetadataQueue->getDesc());
+    }
+    return Void();
+}
+
+/**
+ * To be used only by submitRequestList implementation, since it requires
+ * clients to call this method serially, incase fmq is used to send metadata.
+ */
+bool HidlCameraDeviceUser::copyPhysicalCameraSettings(
+    const hidl_vec<HPhysicalCameraSettings> &hPhysicalCameraSettings,
+    std::vector<CaptureRequest::PhysicalCameraSettings> *physicalCameraSettings) {
+    bool converted = false;
+    for (auto &e : hPhysicalCameraSettings) {
+        physicalCameraSettings->emplace_back();
+        CaptureRequest::PhysicalCameraSettings &physicalCameraSetting =
+            physicalCameraSettings->back();
+        physicalCameraSetting.id = e.id.c_str();
+
+        // Read the settings either from the fmq or straightaway from the
+        // request. We don't need any synchronization, since submitRequestList
+        // is guaranteed to be called serially by the client if it decides to
+        // use fmq.
+        if (e.settings.getDiscriminator() ==
+            FmqSizeOrMetadata::hidl_discriminator::fmqMetadataSize) {
+            /**
+             * Get settings from the fmq.
+             */
+            HCameraMetadata settingsFmq;
+            settingsFmq.resize(e.settings.fmqMetadataSize());
+            bool read = mCaptureRequestMetadataQueue->read(settingsFmq.data(),
+                                                           e.settings.fmqMetadataSize());
+            if (!read) {
+                ALOGE("%s capture request settings could't be read from fmq size",
+                      __FUNCTION__);
+                converted = false;
+            } else {
+                converted = convertFromHidl(settingsFmq, &physicalCameraSetting.settings);
+            }
+        } else {
+            /**
+             * The settings metadata is contained in request settings field.
+             */
+            converted =
+                convertFromHidl(e.settings.metadata(),
+                                &physicalCameraSetting.settings);
+        }
+        if (!converted) {
+          ALOGE("%s: Unable to convert physicalCameraSettings from HIDL to AIDL.", __FUNCTION__);
+          return false;
+        }
+    }
+    return true;
+}
+
+bool HidlCameraDeviceUser::convertRequestFromHidl(const HCaptureRequest &hRequest,
+                                                  CaptureRequest *request) {
+    // No reprocessing support.
+    request->mIsReprocess = false;
+    for (const auto &streamAndWindowId : hRequest.streamAndWindowIds) {
+        request->mStreamIdxList.push_back(streamAndWindowId.streamId);
+        request->mSurfaceIdxList.push_back(streamAndWindowId.windowId);
+    }
+    return copyPhysicalCameraSettings(hRequest.physicalCameraSettings,
+                                      &(request->mPhysicalCameraSettings));
+}
+
+Return<void> HidlCameraDeviceUser::submitRequestList(const hidl_vec<HCaptureRequest>& hRequestList,
+                                                     bool streaming,
+                                                     submitRequestList_cb _hidl_cb) {
+    hardware::camera2::utils::SubmitInfo submitInfo;
+    HSubmitInfo hSubmitInfo;
+    /**
+     * Create AIDL CaptureRequest from requestList and graphicBufferProducers.
+     */
+    std::vector<hardware::camera2::CaptureRequest> requests;
+    for (auto &hRequest : hRequestList) {
+        requests.emplace_back();
+        auto &request = requests.back();
+        if (!convertRequestFromHidl(hRequest, &request)) {
+            _hidl_cb(HStatus::ILLEGAL_ARGUMENT, hSubmitInfo);
+            return Void();
+        }
+    }
+    mDeviceRemote->submitRequestList(requests, streaming, &submitInfo);
+    mRequestId = submitInfo.mRequestId;
+    convertToHidl(submitInfo, &hSubmitInfo);
+    _hidl_cb(HStatus::NO_ERROR, hSubmitInfo);
+    return Void();
+}
+
+Return<void> HidlCameraDeviceUser::cancelRepeatingRequest(cancelRepeatingRequest_cb _hidl_cb) {
+    int64_t lastFrameNumber = 0;
+    binder::Status ret = mDeviceRemote->cancelRequest(mRequestId, &lastFrameNumber);
+    _hidl_cb(B2HStatus(ret), lastFrameNumber);
+    return Void();
+}
+
+Return<HStatus> HidlCameraDeviceUser::beginConfigure() {
+    binder::Status ret = mDeviceRemote->beginConfigure();
+    return B2HStatus(ret);
+}
+
+Return<HStatus> HidlCameraDeviceUser::endConfigure(StreamConfigurationMode operatingMode,
+                                                   const hidl_vec<uint8_t>& sessionParams) {
+    android::CameraMetadata cameraMetadata;
+    if (!convertFromHidl(sessionParams, &cameraMetadata)) {
+        return HStatus::ILLEGAL_ARGUMENT;
+    }
+
+    binder::Status ret = mDeviceRemote->endConfigure(convertFromHidl(operatingMode),
+                                                     cameraMetadata);
+    return B2HStatus(ret);
+}
+
+Return<HStatus> HidlCameraDeviceUser::deleteStream(int32_t streamId) {
+    binder::Status ret = mDeviceRemote->deleteStream(streamId);
+    return B2HStatus(ret);
+}
+
+Return<void> HidlCameraDeviceUser::createStream(const HOutputConfiguration& hOutputConfiguration,
+                                                createStream_cb hidl_cb_) {
+    OutputConfiguration outputConfiguration =
+        convertFromHidl(hOutputConfiguration);
+    int32_t newStreamId = 0;
+    binder::Status ret = mDeviceRemote->createStream(outputConfiguration, &newStreamId);
+    HStatus status = B2HStatus(ret);
+    hidl_cb_(status, newStreamId);
+    return Void();
+}
+
+Return<void> HidlCameraDeviceUser::createDefaultRequest(TemplateId templateId,
+                                                        createDefaultRequest_cb _hidl_cb) {
+    android::CameraMetadata cameraMetadata;
+    binder::Status ret = mDeviceRemote->createDefaultRequest(convertFromHidl(templateId),
+                                                             &cameraMetadata);
+    HStatus hStatus = B2HStatus(ret);
+    HCameraMetadata hidlMetadata;
+    const camera_metadata_t *rawMetadata = cameraMetadata.getAndLock();
+    convertToHidl(rawMetadata, &hidlMetadata);
+    _hidl_cb(hStatus, hidlMetadata);
+    cameraMetadata.unlock(rawMetadata);
+    return Void();
+}
+
+Return<HStatus> HidlCameraDeviceUser::waitUntilIdle() {
+    binder::Status ret = mDeviceRemote->waitUntilIdle();
+    return B2HStatus(ret);
+}
+
+Return<void> HidlCameraDeviceUser::flush(flush_cb _hidl_cb) {
+    int64_t lastFrameNumber = 0;
+    binder::Status ret = mDeviceRemote->flush(&lastFrameNumber);
+    _hidl_cb(B2HStatus(ret),lastFrameNumber);
+    return Void();
+}
+
+Return<HStatus> HidlCameraDeviceUser::updateOutputConfiguration(
+    int32_t streamId,
+    const HOutputConfiguration& hOutputConfiguration) {
+    OutputConfiguration outputConfiguration = convertFromHidl(hOutputConfiguration);
+    binder::Status ret = mDeviceRemote->updateOutputConfiguration(streamId, outputConfiguration);
+    return B2HStatus(ret);
+}
+
+Return<void> HidlCameraDeviceUser::isSessionConfigurationSupported(
+    const HSessionConfiguration& hSessionConfiguration,
+    isSessionConfigurationSupported_cb _hidl_cb) {
+    bool supported = false;
+    SessionConfiguration sessionConfiguration = convertFromHidl(hSessionConfiguration);
+    binder::Status ret = mDeviceRemote->isSessionConfigurationSupported(
+            sessionConfiguration, &supported);
+    HStatus status = B2HStatus(ret);
+    _hidl_cb(status, supported);
+    return Void();
+}
+
+} // implementation
+} // V2_0
+} // device
+} // cameraservice
+} // frameworks
+} // android
diff --git a/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.h b/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.h
new file mode 100644
index 0000000..c3a80fe
--- /dev/null
+++ b/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_FRAMEWORKS_CAMERADEVICEUSER_V2_0_CAMERADEVICEUSER_H
+#define ANDROID_FRAMEWORKS_CAMERADEVICEUSER_V2_0_CAMERADEVICEUSER_H
+
+#include <mutex>
+#include <memory>
+#include <thread>
+
+#include <android/frameworks/cameraservice/common/2.0/types.h>
+#include <android/frameworks/cameraservice/service/2.0/types.h>
+#include <android/frameworks/cameraservice/device/2.0/ICameraDeviceUser.h>
+#include <android/frameworks/cameraservice/device/2.0/types.h>
+#include <android/hardware/camera2/ICameraDeviceCallbacks.h>
+#include <fmq/MessageQueue.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+#include <CameraService.h>
+
+namespace android {
+namespace frameworks {
+namespace cameraservice {
+namespace device {
+namespace V2_0 {
+namespace implementation {
+
+using frameworks::cameraservice::device::V2_0::StreamConfigurationMode;
+using hardware::camera2::CaptureRequest;
+using hardware::hidl_vec;
+using hardware::kSynchronizedReadWrite;
+using hardware::MessageQueue;
+using hardware::MQDescriptorSync;
+using hardware::Return;
+using CaptureResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+using CaptureRequestMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+using TemplateId = frameworks::cameraservice::device::V2_0::TemplateId;
+
+using HCameraDeviceUser = device::V2_0::ICameraDeviceUser;
+using HCameraMetadata = cameraservice::service::V2_0::CameraMetadata;
+using HCaptureRequest = device::V2_0::CaptureRequest;
+using HSessionConfiguration = frameworks::cameraservice::device::V2_0::SessionConfiguration;
+using HOutputConfiguration = frameworks::cameraservice::device::V2_0::OutputConfiguration;
+using HPhysicalCameraSettings = frameworks::cameraservice::device::V2_0::PhysicalCameraSettings;
+using HStatus = frameworks::cameraservice::common::V2_0::Status;
+
+static constexpr int32_t REQUEST_ID_NONE = -1;
+
+struct HidlCameraDeviceUser final : public HCameraDeviceUser {
+    HidlCameraDeviceUser(const sp<hardware::camera2::ICameraDeviceUser> &deviceRemote);
+
+    ~HidlCameraDeviceUser() { }
+
+    virtual Return<void> disconnect() override;
+
+    virtual Return<void> getCaptureRequestMetadataQueue(
+        getCaptureRequestMetadataQueue_cb _hidl_cb) override;
+
+    virtual Return<void> getCaptureResultMetadataQueue(
+        getCaptureResultMetadataQueue_cb _hidl_cb) override;
+
+    virtual Return<void> submitRequestList(const hidl_vec<HCaptureRequest>& requestList,
+                                           bool streaming, submitRequestList_cb _hidl_cb) override;
+
+    virtual Return<void> cancelRepeatingRequest(cancelRepeatingRequest_cb _hidl_cb) override;
+
+    virtual Return<HStatus> beginConfigure() override;
+
+    virtual Return<HStatus> endConfigure(StreamConfigurationMode operatingMode,
+                                         const hidl_vec<uint8_t>& sessionParams);
+
+    virtual Return<HStatus> deleteStream(int32_t streamId) override;
+
+    virtual Return<void> createStream(const HOutputConfiguration& outputConfiguration,
+                                      createStream_cb _hidl_cb) override;
+
+    Return<void> createDefaultRequest(TemplateId templateId,
+                                      createDefaultRequest_cb _hidl_cb) override;
+
+    virtual Return<HStatus> waitUntilIdle() override;
+
+    virtual Return<void> flush(flush_cb _hidl_cb) override;
+
+    virtual Return<HStatus> updateOutputConfiguration(
+        int32_t streamId, const HOutputConfiguration& outputConfiguration) override;
+
+    virtual Return<void> isSessionConfigurationSupported(
+        const HSessionConfiguration& sessionConfiguration,
+        isSessionConfigurationSupported_cb _hidl_cb) override;
+
+    bool initStatus() { return mInitSuccess; }
+
+    std::shared_ptr<CaptureResultMetadataQueue> getCaptureResultMetadataQueue() {
+        return mCaptureResultMetadataQueue;
+    }
+
+ private:
+    bool initDevice();
+
+    bool convertRequestFromHidl(const HCaptureRequest &hRequest, CaptureRequest *request);
+
+    bool copyPhysicalCameraSettings(
+        const hidl_vec<HPhysicalCameraSettings> &hPhysicalCameraSettings,
+        std::vector<CaptureRequest::PhysicalCameraSettings> *physicalCameraSettings);
+
+    const sp<hardware::camera2::ICameraDeviceUser> mDeviceRemote;
+    std::unique_ptr<CaptureRequestMetadataQueue> mCaptureRequestMetadataQueue = nullptr;
+    std::shared_ptr<CaptureResultMetadataQueue> mCaptureResultMetadataQueue = nullptr;
+    bool mInitSuccess = false;
+    int32_t mRequestId = REQUEST_ID_NONE;
+};
+
+} // implementation
+} // V2_0
+} // device
+} // cameraservice
+} // frameworks
+} // android
+#endif // ANDROID_FRAMEOWORKS_CAMERADEVICEUSER_V2_0_CAMERADEVICEUSER_H
diff --git a/services/camera/libcameraservice/hidl/HidlCameraService.cpp b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
new file mode 100644
index 0000000..74cfe42
--- /dev/null
+++ b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <hidl/Convert.h>
+
+#include <hidl/HidlCameraService.h>
+
+#include <hidl/HidlCameraDeviceUser.h>
+#include <hidl/AidlCameraDeviceCallbacks.h>
+#include <hidl/AidlCameraServiceListener.h>
+
+#include <hidl/HidlTransportSupport.h>
+
+namespace android {
+namespace frameworks {
+namespace cameraservice {
+namespace service {
+namespace V2_0 {
+namespace implementation {
+
+using frameworks::cameraservice::service::V2_0::implementation::HidlCameraService;
+using hardware::hidl_vec;
+using hardware::cameraservice::utils::conversion::convertToHidl;
+using hardware::cameraservice::utils::conversion::B2HStatus;
+using hardware::Void;
+
+using device::V2_0::implementation::H2BCameraDeviceCallbacks;
+using device::V2_0::implementation::HidlCameraDeviceUser;
+using service::V2_0::implementation::H2BCameraServiceListener;
+using HCameraMetadataType = frameworks::cameraservice::common::V2_0::CameraMetadataType;
+using HVendorTag = frameworks::cameraservice::common::V2_0::VendorTag;
+using HVendorTagSection = frameworks::cameraservice::common::V2_0::VendorTagSection;
+using HProviderIdAndVendorTagSections =
+        frameworks::cameraservice::common::V2_0::ProviderIdAndVendorTagSections;
+
+sp<HidlCameraService> gHidlCameraService;
+
+sp<HidlCameraService> HidlCameraService::getInstance(android::CameraService *cs) {
+    gHidlCameraService = new HidlCameraService(cs);
+    return gHidlCameraService;
+}
+
+Return<void>
+HidlCameraService::getCameraCharacteristics(const hidl_string& cameraId,
+                                            getCameraCharacteristics_cb _hidl_cb) {
+    android::CameraMetadata cameraMetadata;
+    HStatus status = HStatus::NO_ERROR;
+    binder::Status serviceRet =
+        mAidlICameraService->getCameraCharacteristics(String16(cameraId.c_str()), &cameraMetadata);
+    HCameraMetadata hidlMetadata;
+    if (!serviceRet.isOk()) {
+        switch(serviceRet.serviceSpecificErrorCode()) {
+            // No ERROR_CAMERA_DISCONNECTED since we're in the same process.
+            case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
+                ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraId.c_str());
+                status = HStatus::ILLEGAL_ARGUMENT;
+                break;
+            default:
+                ALOGE("Get camera characteristics from camera service failed: %s",
+                      serviceRet.toString8().string());
+                status = B2HStatus(serviceRet);
+          }
+        _hidl_cb(status, hidlMetadata);
+        return Void();
+    }
+    const camera_metadata_t *rawMetadata = cameraMetadata.getAndLock();
+    convertToHidl(rawMetadata, &hidlMetadata);
+    _hidl_cb(status, hidlMetadata);
+    cameraMetadata.unlock(rawMetadata);
+    return Void();
+}
+
+Return<void> HidlCameraService::connectDevice(const sp<HCameraDeviceCallback>& hCallback,
+                                              const hidl_string& cameraId,
+                                              connectDevice_cb _hidl_cb) {
+    // Here, we first get ICameraDeviceUser from mAidlICameraService, then save
+    // that interface in the newly created HidlCameraDeviceUser impl class.
+    if (mAidlICameraService == nullptr) {
+        _hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
+        return Void();
+    }
+    sp<hardware::camera2::ICameraDeviceUser> deviceRemote = nullptr;
+    // Create a hardware::camera2::ICameraDeviceCallback object which internally
+    // calls callback functions passed through hCallback.
+    sp<H2BCameraDeviceCallbacks> hybridCallbacks = new H2BCameraDeviceCallbacks(hCallback);
+    if (!hybridCallbacks->initializeLooper()) {
+        ALOGE("Unable to handle callbacks on device, cannot connect");
+        _hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
+        return Void();
+    }
+    sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = hybridCallbacks;
+    binder::Status serviceRet = mAidlICameraService->connectDevice(
+            callbacks, String16(cameraId.c_str()), String16(""),
+            hardware::ICameraService::USE_CALLING_UID, /*out*/&deviceRemote);
+    HStatus status = HStatus::NO_ERROR;
+    if (!serviceRet.isOk()) {
+        ALOGE("%s: Unable to connect to camera device", __FUNCTION__);
+        status = B2HStatus(serviceRet);
+        _hidl_cb(status, nullptr);
+        return Void();
+    }
+    // Now we create a HidlCameraDeviceUser class, store the deviceRemote in it,
+    // and return that back. All calls on that interface will be forwarded to
+    // the AIDL interface.
+    sp<HidlCameraDeviceUser> hDeviceRemote = new HidlCameraDeviceUser(deviceRemote);
+    if (!hDeviceRemote->initStatus()) {
+        ALOGE("%s: Unable to initialize camera device HIDL wrapper", __FUNCTION__);
+        _hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
+        return Void();
+    }
+    hybridCallbacks->setCaptureResultMetadataQueue(hDeviceRemote->getCaptureResultMetadataQueue());
+    _hidl_cb(status, hDeviceRemote);
+    return Void();
+}
+
+void HidlCameraService::addToListenerCacheLocked(sp<HCameraServiceListener> hListener,
+                                                 sp<hardware::ICameraServiceListener> csListener) {
+        mListeners.emplace_back(std::make_pair(hListener, csListener));
+}
+
+sp<hardware::ICameraServiceListener>
+HidlCameraService::searchListenerCacheLocked(sp<HCameraServiceListener> hListener,
+                                             bool shouldRemove) {
+    // Go through the mListeners list and compare the listener with the HIDL
+    // listener registered.
+    auto it = mListeners.begin();
+    sp<ICameraServiceListener> csListener = nullptr;
+    for (;it != mListeners.end(); it++) {
+        if (hardware::interfacesEqual(it->first, hListener)) {
+            break;
+        }
+    }
+    if (it != mListeners.end()) {
+        csListener = it->second;
+        if (shouldRemove) {
+          mListeners.erase(it);
+        }
+    }
+    return csListener;
+}
+
+Return<void> HidlCameraService::addListener(const sp<HCameraServiceListener>& hCsListener,
+                                            addListener_cb _hidl_cb) {
+    if (mAidlICameraService == nullptr) {
+        _hidl_cb(HStatus::UNKNOWN_ERROR, {});
+        return Void();
+    }
+    if (hCsListener == nullptr) {
+        ALOGE("%s listener must not be NULL", __FUNCTION__);
+        _hidl_cb(HStatus::ILLEGAL_ARGUMENT, {});
+        return Void();
+    }
+    sp<hardware::ICameraServiceListener> csListener = nullptr;
+    // Check the cache for previously registered callbacks
+    {
+        Mutex::Autolock l(mListenerListLock);
+        csListener = searchListenerCacheLocked(hCsListener);
+        if (csListener == nullptr) {
+            // Wrap an hCsListener with AidlCameraServiceListener and pass it to
+            // CameraService.
+            csListener = new H2BCameraServiceListener(hCsListener);
+            // Add to cache
+            addToListenerCacheLocked(hCsListener, csListener);
+        } else {
+            ALOGE("%s: Trying to add a listener %p already registered",
+                  __FUNCTION__, hCsListener.get());
+            _hidl_cb(HStatus::ILLEGAL_ARGUMENT, {});
+            return Void();
+        }
+    }
+    std::vector<hardware::CameraStatus> cameraStatusAndIds{};
+    binder::Status serviceRet =
+        mAidlICameraService->addListenerHelper(csListener, &cameraStatusAndIds, true);
+    HStatus status = HStatus::NO_ERROR;
+    if (!serviceRet.isOk()) {
+      ALOGE("%s: Unable to add camera device status listener", __FUNCTION__);
+      status = B2HStatus(serviceRet);
+      _hidl_cb(status, {});
+      return Void();
+    }
+    hidl_vec<HCameraStatusAndId> hCameraStatusAndIds;
+    //Convert cameraStatusAndIds to HIDL and call callback
+    convertToHidl(cameraStatusAndIds, &hCameraStatusAndIds);
+    _hidl_cb(status, hCameraStatusAndIds);
+    return Void();
+}
+
+Return<HStatus> HidlCameraService::removeListener(const sp<HCameraServiceListener>& hCsListener) {
+    if (hCsListener == nullptr) {
+        ALOGE("%s listener must not be NULL", __FUNCTION__);
+        return HStatus::ILLEGAL_ARGUMENT;
+    }
+    sp<ICameraServiceListener> csListener = nullptr;
+    {
+        Mutex::Autolock l(mListenerListLock);
+        csListener = searchListenerCacheLocked(hCsListener, /*removeIfFound*/true);
+    }
+    if (csListener != nullptr) {
+          mAidlICameraService->removeListener(csListener);
+    } else {
+        ALOGE("%s Removing unregistered listener %p", __FUNCTION__, hCsListener.get());
+        return HStatus::ILLEGAL_ARGUMENT;
+    }
+    return HStatus::NO_ERROR;
+}
+
+Return<void> HidlCameraService::getCameraVendorTagSections(getCameraVendorTagSections_cb _hidl_cb) {
+    sp<VendorTagDescriptorCache> gCache = VendorTagDescriptorCache::getGlobalVendorTagCache();
+    if (gCache == nullptr) {
+        _hidl_cb(HStatus::UNKNOWN_ERROR, {});
+        return Void();
+    }
+    const std::unordered_map<metadata_vendor_id_t, sp<android::VendorTagDescriptor>>
+            &vendorIdsAndTagDescs = gCache->getVendorIdsAndTagDescriptors();
+    if (vendorIdsAndTagDescs.size() == 0) {
+        _hidl_cb(HStatus::UNKNOWN_ERROR, {});
+        return Void();
+    }
+
+    hidl_vec<HProviderIdAndVendorTagSections> hTagIdsAndVendorTagSections;
+    hTagIdsAndVendorTagSections.resize(vendorIdsAndTagDescs.size());
+    size_t j = 0;
+    for (auto &vendorIdAndTagDescs : vendorIdsAndTagDescs) {
+        hidl_vec<HVendorTagSection> hVendorTagSections;
+        sp<VendorTagDescriptor> desc = vendorIdAndTagDescs.second;
+        const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
+        size_t numSections = sectionNames->size();
+        std::vector<std::vector<HVendorTag>> tagsBySection(numSections);
+        int tagCount = desc->getTagCount();
+        std::vector<uint32_t> tags(tagCount);
+        desc->getTagArray(tags.data());
+        for (int i = 0; i < tagCount; i++) {
+            HVendorTag vt;
+            vt.tagId = tags[i];
+            vt.tagName = desc->getTagName(tags[i]);
+            vt.tagType = (HCameraMetadataType) desc->getTagType(tags[i]);
+            ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
+            tagsBySection[sectionIdx].push_back(vt);
+        }
+        hVendorTagSections.resize(numSections);
+        for (size_t s = 0; s < numSections; s++) {
+            hVendorTagSections[s].sectionName = (*sectionNames)[s].string();
+            hVendorTagSections[s].tags = tagsBySection[s];
+        }
+        HProviderIdAndVendorTagSections &hProviderIdAndVendorTagSections =
+                hTagIdsAndVendorTagSections[j];
+        hProviderIdAndVendorTagSections.providerId = vendorIdAndTagDescs.first;
+        hProviderIdAndVendorTagSections.vendorTagSections = std::move(hVendorTagSections);
+        j++;
+    }
+    _hidl_cb(HStatus::NO_ERROR, hTagIdsAndVendorTagSections);
+    return Void();
+}
+
+} // implementation
+} // V2_0
+} // service
+} // cameraservice
+} // frameworks
+} // android
+
diff --git a/services/camera/libcameraservice/hidl/HidlCameraService.h b/services/camera/libcameraservice/hidl/HidlCameraService.h
new file mode 100644
index 0000000..eead0bc
--- /dev/null
+++ b/services/camera/libcameraservice/hidl/HidlCameraService.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_FRAMEWORKS_CAMERASERVICE_V2_0_CAMERASERVICE_H
+#define ANDROID_FRAMEWORKS_CAMERASERVICE_V2_0_CAMERASERVICE_H
+
+#include <mutex>
+#include <thread>
+
+#include <android/frameworks/cameraservice/common/2.0/types.h>
+#include <android/frameworks/cameraservice/service/2.0/ICameraService.h>
+#include <android/frameworks/cameraservice/service/2.0/types.h>
+#include <android/frameworks/cameraservice/device/2.0/types.h>
+
+#include <hidl/Status.h>
+
+#include <CameraService.h>
+
+namespace android {
+namespace frameworks {
+namespace cameraservice {
+namespace service {
+namespace V2_0 {
+namespace implementation {
+
+using hardware::hidl_string;
+using hardware::ICameraServiceListener;
+using hardware::Return;
+
+using HCameraDeviceCallback = frameworks::cameraservice::device::V2_0::ICameraDeviceCallback;
+using HCameraMetadata = frameworks::cameraservice::service::V2_0::CameraMetadata;
+using HCameraService = frameworks::cameraservice::service::V2_0::ICameraService;
+using HCameraServiceListener = frameworks::cameraservice::service::V2_0::ICameraServiceListener;
+using HStatus = frameworks::cameraservice::common::V2_0::Status;
+using HCameraStatusAndId = frameworks::cameraservice::service::V2_0::CameraStatusAndId;
+
+struct HidlCameraService final : public HCameraService {
+
+    ~HidlCameraService() { };
+
+    // Methods from ::android::frameworks::cameraservice::service::V2.0::ICameraService follow.
+
+    Return<void> connectDevice(const sp<HCameraDeviceCallback>& callback,
+                               const hidl_string& cameraId, connectDevice_cb _hidl_cb) override;
+
+    Return<void> addListener(const sp<HCameraServiceListener>& listener,
+                             addListener_cb _hidl_cb) override;
+
+    Return<HStatus> removeListener(const sp<HCameraServiceListener>& listener) override;
+
+    Return<void> getCameraCharacteristics(const hidl_string& cameraId,
+                                          getCameraCharacteristics_cb _hidl_cb) override;
+
+    Return<void> getCameraVendorTagSections(getCameraVendorTagSections_cb _hidl_cb) override;
+
+    // This method should only be called by the cameraservers main thread to
+    // instantiate the hidl cameraserver.
+    static sp<HidlCameraService> getInstance(android::CameraService *cs);
+
+private:
+    HidlCameraService(android::CameraService *cs) : mAidlICameraService(cs) { };
+
+    sp<hardware::ICameraServiceListener> searchListenerCacheLocked(
+        sp<HCameraServiceListener> listener, /*removeIfFound*/ bool shouldRemove = false);
+
+    void addToListenerCacheLocked(sp<HCameraServiceListener> hListener,
+                                  sp<hardware::ICameraServiceListener> csListener);
+
+    android::CameraService *const mAidlICameraService = nullptr;
+
+    Mutex mListenerListLock;
+
+    using HIListeners =
+        std::pair<sp<HCameraServiceListener>, sp<ICameraServiceListener>>;
+    std::list<HIListeners> mListeners;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace service
+}  // namespace cameraservice
+}  // namespace frameworks
+}  // namespace android
+
+#endif  // ANDROID_FRAMEWORKS_CAMERASERVICE_V2_0_CAMERASERVICE_H
diff --git a/services/camera/libcameraservice/tests/Android.mk b/services/camera/libcameraservice/tests/Android.mk
index f77069c..b4e7c32 100644
--- a/services/camera/libcameraservice/tests/Android.mk
+++ b/services/camera/libcameraservice/tests/Android.mk
@@ -27,17 +27,24 @@
     libcamera_client \
     libcamera_metadata \
     libutils \
+    libjpeg \
+    libexif \
     android.hardware.camera.common@1.0 \
     android.hardware.camera.provider@2.4 \
+    android.hardware.camera.provider@2.5 \
     android.hardware.camera.device@1.0 \
-    android.hardware.camera.device@3.2
+    android.hardware.camera.device@3.2 \
+    android.hardware.camera.device@3.4
 
 LOCAL_C_INCLUDES += \
     system/media/private/camera/include \
+    external/dynamic_depth/includes \
+    external/dynamic_depth/internal \
 
 LOCAL_CFLAGS += -Wall -Wextra -Werror
 
 LOCAL_MODULE:= cameraservice_test
+LOCAL_COMPATIBILITY_SUITE := device-tests
 LOCAL_MODULE_TAGS := tests
 
 include $(BUILD_NATIVE_TEST)
diff --git a/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp b/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
index ef93d9a..f47e5a5 100644
--- a/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
+++ b/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
@@ -33,6 +33,7 @@
 using android::hardware::camera::common::V1_0::CameraMetadataType;
 using android::hardware::camera::device::V3_2::ICameraDeviceCallback;
 using android::hardware::camera::device::V3_2::ICameraDeviceSession;
+using android::hardware::camera::provider::V2_5::DeviceState;
 
 /**
  * Basic test implementation of a camera ver. 3.2 device interface
@@ -87,7 +88,7 @@
 /**
  * Basic test implementation of a camera provider
  */
-struct TestICameraProvider : virtual public provider::V2_4::ICameraProvider {
+struct TestICameraProvider : virtual public provider::V2_5::ICameraProvider {
     sp<provider::V2_4::ICameraProviderCallback> mCallbacks;
     std::vector<hardware::hidl_string> mDeviceNames;
     sp<device::V3_2::ICameraDevice> mDeviceInterface;
@@ -101,6 +102,7 @@
 
     virtual hardware::Return<Status> setCallback(
             const sp<provider::V2_4::ICameraProviderCallback>& callbacks) override {
+        mCalledCounter[SET_CALLBACK]++;
         mCallbacks = callbacks;
         return hardware::Return<Status>(Status::OK);
     }
@@ -108,6 +110,7 @@
     using getVendorTags_cb = std::function<void(Status status,
             const hardware::hidl_vec<common::V1_0::VendorTagSection>& sections)>;
     hardware::Return<void> getVendorTags(getVendorTags_cb _hidl_cb) override {
+        mCalledCounter[GET_VENDOR_TAGS]++;
         _hidl_cb(Status::OK, mVendorTagSections);
         return hardware::Void();
     }
@@ -117,6 +120,7 @@
              bool support)>;
     virtual ::hardware::Return<void> isSetTorchModeSupported(
             isSetTorchModeSupported_cb _hidl_cb) override {
+        mCalledCounter[IS_SET_TORCH_MODE_SUPPORTED]++;
         _hidl_cb(Status::OK, false);
         return hardware::Void();
     }
@@ -124,6 +128,7 @@
     using getCameraIdList_cb = std::function<void(Status status,
             const hardware::hidl_vec<hardware::hidl_string>& cameraDeviceNames)>;
     virtual hardware::Return<void> getCameraIdList(getCameraIdList_cb _hidl_cb) override {
+        mCalledCounter[GET_CAMERA_ID_LIST]++;
         _hidl_cb(Status::OK, mDeviceNames);
         return hardware::Void();
     }
@@ -148,6 +153,25 @@
         return hardware::Void();
     }
 
+    virtual hardware::Return<void> notifyDeviceStateChange(
+            hardware::hidl_bitfield<DeviceState> newState) override {
+        mCalledCounter[NOTIFY_DEVICE_STATE]++;
+        mCurrentState = newState;
+        return hardware::Void();
+    }
+
+    enum MethodNames {
+        SET_CALLBACK,
+        GET_VENDOR_TAGS,
+        IS_SET_TORCH_MODE_SUPPORTED,
+        NOTIFY_DEVICE_STATE,
+        GET_CAMERA_ID_LIST,
+
+        METHOD_NAME_COUNT
+    };
+    int mCalledCounter[METHOD_NAME_COUNT] {0};
+
+    hardware::hidl_bitfield<DeviceState> mCurrentState = 0xFFFFFFFF; // Unlikely to be a real state
 };
 
 /**
@@ -163,7 +187,7 @@
         mTestCameraProvider = provider;
     }
 
-    std::string mLastRequestedServiceName;
+    std::vector<std::string> mLastRequestedServiceNames;
 
     virtual ~TestInteractionProxy() {}
 
@@ -177,7 +201,7 @@
 
     virtual sp<hardware::camera::provider::V2_4::ICameraProvider> getService(
             const std::string &serviceName) override {
-        mLastRequestedServiceName = serviceName;
+        mLastRequestedServiceNames.push_back(serviceName);
         return mTestCameraProvider;
     }
 
@@ -209,10 +233,34 @@
 
     res = providerManager->initialize(statusListener, &serviceProxy);
     ASSERT_EQ(res, OK) << "Unable to initialize provider manager";
+    // Check that both "legacy" and "external" providers (really the same object) are called
+    // once for all the init methods
+    EXPECT_EQ(provider->mCalledCounter[TestICameraProvider::SET_CALLBACK], 2) <<
+            "Only one call to setCallback per provider expected during init";
+    EXPECT_EQ(provider->mCalledCounter[TestICameraProvider::GET_VENDOR_TAGS], 2) <<
+            "Only one call to getVendorTags per provider expected during init";
+    EXPECT_EQ(provider->mCalledCounter[TestICameraProvider::IS_SET_TORCH_MODE_SUPPORTED], 2) <<
+            "Only one call to isSetTorchModeSupported per provider expected during init";
+    EXPECT_EQ(provider->mCalledCounter[TestICameraProvider::GET_CAMERA_ID_LIST], 2) <<
+            "Only one call to getCameraIdList per provider expected during init";
+    EXPECT_EQ(provider->mCalledCounter[TestICameraProvider::NOTIFY_DEVICE_STATE], 2) <<
+            "Only one call to notifyDeviceState per provider expected during init";
 
-    hardware::hidl_string legacyInstanceName = "legacy/0";
-    ASSERT_EQ(serviceProxy.mLastRequestedServiceName, legacyInstanceName) <<
+    std::string legacyInstanceName = "legacy/0";
+    std::string externalInstanceName = "external/0";
+    bool gotLegacy = false;
+    bool gotExternal = false;
+    EXPECT_EQ(2u, serviceProxy.mLastRequestedServiceNames.size()) <<
+            "Only two service queries expected to be seen by hardware service manager";
+
+    for (auto& serviceName : serviceProxy.mLastRequestedServiceNames) {
+        if (serviceName == legacyInstanceName) gotLegacy = true;
+        if (serviceName == externalInstanceName) gotExternal = true;
+    }
+    ASSERT_TRUE(gotLegacy) <<
             "Legacy instance not requested from service manager";
+    ASSERT_TRUE(gotExternal) <<
+            "External instance not requested from service manager";
 
     hardware::hidl_string testProviderFqInterfaceName =
             "android.hardware.camera.provider@2.4::ICameraProvider";
@@ -221,7 +269,7 @@
             testProviderFqInterfaceName,
             testProviderInstanceName, false);
 
-    ASSERT_EQ(serviceProxy.mLastRequestedServiceName, testProviderInstanceName) <<
+    ASSERT_EQ(serviceProxy.mLastRequestedServiceNames.back(), testProviderInstanceName) <<
             "Incorrect instance requested from service manager";
 }
 
@@ -255,7 +303,7 @@
             "android.hardware.camera.provider@2.4::ICameraProvider";
     serviceProxy.mManagerNotificationInterface->onRegistration(
             testProviderFqInterfaceName, testProviderInstanceName, false);
-    ASSERT_EQ(serviceProxy.mLastRequestedServiceName, testProviderInstanceName) <<
+    ASSERT_EQ(serviceProxy.mLastRequestedServiceNames.back(), testProviderInstanceName) <<
             "Incorrect instance requested from service manager";
 
     hardware::hidl_string sectionNameSecond = "SecondVendorTestSection";
@@ -273,7 +321,7 @@
     hardware::hidl_string testProviderSecondInstanceName = "test2/0";
     serviceProxy.mManagerNotificationInterface->onRegistration(
             testProviderFqInterfaceName, testProviderSecondInstanceName, false);
-    ASSERT_EQ(serviceProxy.mLastRequestedServiceName,
+    ASSERT_EQ(serviceProxy.mLastRequestedServiceNames.back(),
               testProviderSecondInstanceName) <<
             "Incorrect instance requested from service manager";
 
@@ -366,3 +414,35 @@
     metadataCopy.dump(1, 2);
     secondMetadata.dump(1, 2);
 }
+
+TEST(CameraProviderManagerTest, NotifyStateChangeTest) {
+    std::vector<hardware::hidl_string> deviceNames {
+        "device@3.2/test/0",
+        "device@1.0/test/0",
+        "device@3.2/test/1"};
+
+    hardware::hidl_vec<common::V1_0::VendorTagSection> vendorSection;
+    status_t res;
+    sp<CameraProviderManager> providerManager = new CameraProviderManager();
+    sp<TestStatusListener> statusListener = new TestStatusListener();
+    TestInteractionProxy serviceProxy;
+    sp<TestICameraProvider> provider =  new TestICameraProvider(deviceNames,
+            vendorSection);
+    serviceProxy.setProvider(provider);
+
+    res = providerManager->initialize(statusListener, &serviceProxy);
+    ASSERT_EQ(res, OK) << "Unable to initialize provider manager";
+
+    ASSERT_EQ(provider->mCurrentState,
+            static_cast<hardware::hidl_bitfield<DeviceState>>(DeviceState::NORMAL))
+            << "Initial device state not set";
+
+    res = providerManager->notifyDeviceStateChange(
+        static_cast<hardware::hidl_bitfield<DeviceState>>(DeviceState::FOLDED));
+
+    ASSERT_EQ(res, OK) << "Unable to call notifyDeviceStateChange";
+    ASSERT_EQ(provider->mCurrentState,
+            static_cast<hardware::hidl_bitfield<DeviceState>>(DeviceState::FOLDED))
+            << "Unable to change device state";
+
+}
diff --git a/services/camera/libcameraservice/tests/DepthProcessorTest.cpp b/services/camera/libcameraservice/tests/DepthProcessorTest.cpp
new file mode 100644
index 0000000..2162514
--- /dev/null
+++ b/services/camera/libcameraservice/tests/DepthProcessorTest.cpp
@@ -0,0 +1,382 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "DepthProcessorTest"
+
+#include <array>
+#include <random>
+
+#include <dlfcn.h>
+#include <gtest/gtest.h>
+
+#include "../common/DepthPhotoProcessor.h"
+#include "../utils/ExifUtils.h"
+#include "NV12Compressor.h"
+
+using namespace android;
+using namespace android::camera3;
+
+static const size_t kTestBufferWidth = 640;
+static const size_t kTestBufferHeight = 480;
+static const size_t kTestBufferNV12Size ((((kTestBufferWidth) * (kTestBufferHeight)) * 3) / 2);
+static const size_t kTestBufferDepthSize (kTestBufferWidth * kTestBufferHeight);
+static const size_t kSeed = 1234;
+
+void linkToDepthPhotoLibrary(void **libHandle /*out*/,
+        process_depth_photo_frame *processFrameFunc /*out*/) {
+    ASSERT_NE(libHandle, nullptr);
+    ASSERT_NE(processFrameFunc, nullptr);
+
+    *libHandle = dlopen(kDepthPhotoLibrary, RTLD_NOW | RTLD_LOCAL);
+    if (*libHandle != nullptr) {
+        *processFrameFunc = reinterpret_cast<camera3::process_depth_photo_frame> (
+                dlsym(*libHandle, kDepthPhotoProcessFunction));
+        ASSERT_NE(*processFrameFunc, nullptr);
+    }
+}
+
+void generateColorJpegBuffer(int jpegQuality, ExifOrientation orientationValue, bool includeExif,
+        bool switchDimensions, std::vector<uint8_t> *colorJpegBuffer /*out*/) {
+    ASSERT_NE(colorJpegBuffer, nullptr);
+
+    std::array<uint8_t, kTestBufferNV12Size> colorSourceBuffer;
+    std::default_random_engine gen(kSeed);
+    std::uniform_int_distribution<int> uniDist(0, UINT8_MAX - 1);
+    for (size_t i = 0; i < colorSourceBuffer.size(); i++) {
+        colorSourceBuffer[i] = uniDist(gen);
+    }
+
+    size_t width = kTestBufferWidth;
+    size_t height = kTestBufferHeight;
+    if (switchDimensions) {
+        width = kTestBufferHeight;
+        height = kTestBufferWidth;
+    }
+
+    NV12Compressor jpegCompressor;
+    if (includeExif) {
+        ASSERT_TRUE(jpegCompressor.compressWithExifOrientation(
+                reinterpret_cast<const unsigned char*> (colorSourceBuffer.data()), width, height,
+                jpegQuality, orientationValue));
+    } else {
+        ASSERT_TRUE(jpegCompressor.compress(
+                reinterpret_cast<const unsigned char*> (colorSourceBuffer.data()), width, height,
+                jpegQuality));
+    }
+
+    *colorJpegBuffer = std::move(jpegCompressor.getCompressedData());
+    ASSERT_FALSE(colorJpegBuffer->empty());
+}
+
+void generateDepth16Buffer(std::array<uint16_t, kTestBufferDepthSize> *depth16Buffer /*out*/) {
+    ASSERT_NE(depth16Buffer, nullptr);
+    std::default_random_engine gen(kSeed+1);
+    std::uniform_int_distribution<int> uniDist(0, UINT16_MAX - 1);
+    for (size_t i = 0; i < depth16Buffer->size(); i++) {
+        (*depth16Buffer)[i] = uniDist(gen);
+    }
+}
+
+TEST(DepthProcessorTest, LinkToLibray) {
+    void *libHandle;
+    process_depth_photo_frame processFunc;
+    linkToDepthPhotoLibrary(&libHandle, &processFunc);
+    if (libHandle != nullptr) {
+        dlclose(libHandle);
+    }
+}
+
+TEST(DepthProcessorTest, BadInput) {
+    void *libHandle;
+    int jpegQuality = 95;
+
+    process_depth_photo_frame processFunc;
+    linkToDepthPhotoLibrary(&libHandle, &processFunc);
+    if (libHandle == nullptr) {
+        // Depth library no present, nothing more to test.
+        return;
+    }
+
+    DepthPhotoInputFrame inputFrame;
+    // Worst case both depth and confidence maps have the same size as the main color image.
+    inputFrame.mMaxJpegSize = inputFrame.mMainJpegSize * 3;
+
+    std::vector<uint8_t> colorJpegBuffer;
+    generateColorJpegBuffer(jpegQuality, ExifOrientation::ORIENTATION_UNDEFINED,
+            /*includeExif*/ false, /*switchDimensions*/ false, &colorJpegBuffer);
+
+    std::array<uint16_t, kTestBufferDepthSize> depth16Buffer;
+    generateDepth16Buffer(&depth16Buffer);
+
+    std::vector<uint8_t> depthPhotoBuffer(inputFrame.mMaxJpegSize);
+    size_t actualDepthPhotoSize = 0;
+
+    inputFrame.mMainJpegWidth = kTestBufferWidth;
+    inputFrame.mMainJpegHeight = kTestBufferHeight;
+    inputFrame.mJpegQuality = jpegQuality;
+    ASSERT_NE(processFunc(inputFrame, depthPhotoBuffer.size(), depthPhotoBuffer.data(),
+                &actualDepthPhotoSize), 0);
+
+    inputFrame.mMainJpegBuffer = reinterpret_cast<const char*> (colorJpegBuffer.data());
+    inputFrame.mMainJpegSize = colorJpegBuffer.size();
+    ASSERT_NE(processFunc(inputFrame, depthPhotoBuffer.size(), depthPhotoBuffer.data(),
+                &actualDepthPhotoSize), 0);
+
+    inputFrame.mDepthMapBuffer = depth16Buffer.data();
+    inputFrame.mDepthMapWidth = inputFrame.mDepthMapStride = kTestBufferWidth;
+    inputFrame.mDepthMapHeight = kTestBufferHeight;
+    ASSERT_NE(processFunc(inputFrame, depthPhotoBuffer.size(), nullptr,
+                &actualDepthPhotoSize), 0);
+
+    ASSERT_NE(processFunc(inputFrame, depthPhotoBuffer.size(), depthPhotoBuffer.data(), nullptr),
+            0);
+
+    dlclose(libHandle);
+}
+
+TEST(DepthProcessorTest, BasicDepthPhotoValidation) {
+    void *libHandle;
+    int jpegQuality = 95;
+
+    process_depth_photo_frame processFunc;
+    linkToDepthPhotoLibrary(&libHandle, &processFunc);
+    if (libHandle == nullptr) {
+        // Depth library no present, nothing more to test.
+        return;
+    }
+
+    std::vector<uint8_t> colorJpegBuffer;
+    generateColorJpegBuffer(jpegQuality, ExifOrientation::ORIENTATION_UNDEFINED,
+            /*includeExif*/ false, /*switchDimensions*/ false, &colorJpegBuffer);
+
+    std::array<uint16_t, kTestBufferDepthSize> depth16Buffer;
+    generateDepth16Buffer(&depth16Buffer);
+
+    DepthPhotoInputFrame inputFrame;
+    inputFrame.mMainJpegBuffer = reinterpret_cast<const char*> (colorJpegBuffer.data());
+    inputFrame.mMainJpegSize = colorJpegBuffer.size();
+    // Worst case both depth and confidence maps have the same size as the main color image.
+    inputFrame.mMaxJpegSize = inputFrame.mMainJpegSize * 3;
+    inputFrame.mMainJpegWidth = kTestBufferWidth;
+    inputFrame.mMainJpegHeight = kTestBufferHeight;
+    inputFrame.mJpegQuality = jpegQuality;
+    inputFrame.mDepthMapBuffer = depth16Buffer.data();
+    inputFrame.mDepthMapWidth = inputFrame.mDepthMapStride = kTestBufferWidth;
+    inputFrame.mDepthMapHeight = kTestBufferHeight;
+
+    std::vector<uint8_t> depthPhotoBuffer(inputFrame.mMaxJpegSize);
+    size_t actualDepthPhotoSize = 0;
+    ASSERT_EQ(processFunc(inputFrame, depthPhotoBuffer.size(), depthPhotoBuffer.data(),
+                &actualDepthPhotoSize), 0);
+    ASSERT_TRUE((actualDepthPhotoSize > 0) && (depthPhotoBuffer.size() >= actualDepthPhotoSize));
+
+    // The final depth photo must consist of three jpeg images:
+    //  - the main color image
+    //  - the depth map image
+    //  - the confidence map image
+    size_t mainJpegSize = 0;
+    ASSERT_EQ(NV12Compressor::findJpegSize(depthPhotoBuffer.data(), actualDepthPhotoSize,
+                &mainJpegSize), OK);
+    ASSERT_TRUE((mainJpegSize > 0) && (mainJpegSize < actualDepthPhotoSize));
+    size_t depthMapSize = 0;
+    ASSERT_EQ(NV12Compressor::findJpegSize(depthPhotoBuffer.data() + mainJpegSize,
+                actualDepthPhotoSize - mainJpegSize, &depthMapSize), OK);
+    ASSERT_TRUE((depthMapSize > 0) && (depthMapSize < (actualDepthPhotoSize - mainJpegSize)));
+
+    dlclose(libHandle);
+}
+
+TEST(DepthProcessorTest, TestDepthPhotoExifOrientation) {
+    void *libHandle;
+    int jpegQuality = 95;
+
+    process_depth_photo_frame processFunc;
+    linkToDepthPhotoLibrary(&libHandle, &processFunc);
+    if (libHandle == nullptr) {
+        // Depth library no present, nothing more to test.
+        return;
+    }
+
+    ExifOrientation exifOrientations[] = { ExifOrientation::ORIENTATION_UNDEFINED,
+            ExifOrientation::ORIENTATION_0_DEGREES, ExifOrientation::ORIENTATION_90_DEGREES,
+            ExifOrientation::ORIENTATION_180_DEGREES, ExifOrientation::ORIENTATION_270_DEGREES };
+    for (auto exifOrientation : exifOrientations) {
+        std::vector<uint8_t> colorJpegBuffer;
+        generateColorJpegBuffer(jpegQuality, exifOrientation, /*includeExif*/ true,
+                /*switchDimensions*/ false, &colorJpegBuffer);
+        if (exifOrientation != ExifOrientation::ORIENTATION_UNDEFINED) {
+            auto jpegExifOrientation = ExifOrientation::ORIENTATION_UNDEFINED;
+            ASSERT_EQ(NV12Compressor::getExifOrientation(colorJpegBuffer.data(),
+                    colorJpegBuffer.size(), &jpegExifOrientation), OK);
+            ASSERT_EQ(exifOrientation, jpegExifOrientation);
+        }
+
+        std::array<uint16_t, kTestBufferDepthSize> depth16Buffer;
+        generateDepth16Buffer(&depth16Buffer);
+
+        DepthPhotoInputFrame inputFrame;
+        inputFrame.mMainJpegBuffer = reinterpret_cast<const char*> (colorJpegBuffer.data());
+        inputFrame.mMainJpegSize = colorJpegBuffer.size();
+        // Worst case both depth and confidence maps have the same size as the main color image.
+        inputFrame.mMaxJpegSize = inputFrame.mMainJpegSize * 3;
+        inputFrame.mMainJpegWidth = kTestBufferWidth;
+        inputFrame.mMainJpegHeight = kTestBufferHeight;
+        inputFrame.mJpegQuality = jpegQuality;
+        inputFrame.mDepthMapBuffer = depth16Buffer.data();
+        inputFrame.mDepthMapWidth = inputFrame.mDepthMapStride = kTestBufferWidth;
+        inputFrame.mDepthMapHeight = kTestBufferHeight;
+
+        std::vector<uint8_t> depthPhotoBuffer(inputFrame.mMaxJpegSize);
+        size_t actualDepthPhotoSize = 0;
+        ASSERT_EQ(processFunc(inputFrame, depthPhotoBuffer.size(), depthPhotoBuffer.data(),
+                &actualDepthPhotoSize), 0);
+        ASSERT_TRUE((actualDepthPhotoSize > 0) &&
+                (depthPhotoBuffer.size() >= actualDepthPhotoSize));
+
+        size_t mainJpegSize = 0;
+        ASSERT_EQ(NV12Compressor::findJpegSize(depthPhotoBuffer.data(), actualDepthPhotoSize,
+                &mainJpegSize), OK);
+        ASSERT_TRUE((mainJpegSize > 0) && (mainJpegSize < actualDepthPhotoSize));
+        size_t depthMapSize = 0;
+        ASSERT_EQ(NV12Compressor::findJpegSize(depthPhotoBuffer.data() + mainJpegSize,
+                actualDepthPhotoSize - mainJpegSize, &depthMapSize), OK);
+        ASSERT_TRUE((depthMapSize > 0) && (depthMapSize < (actualDepthPhotoSize - mainJpegSize)));
+        size_t confidenceMapSize = actualDepthPhotoSize - (mainJpegSize + depthMapSize);
+
+        //Depth and confidence images must have the same EXIF orientation as the source
+        auto depthJpegExifOrientation = ExifOrientation::ORIENTATION_UNDEFINED;
+        ASSERT_EQ(NV12Compressor::getExifOrientation(depthPhotoBuffer.data() + mainJpegSize,
+                depthMapSize, &depthJpegExifOrientation), OK);
+        if (exifOrientation == ORIENTATION_UNDEFINED) {
+            // In case of undefined or missing EXIF orientation, always expect 0 degrees in the
+            // depth map.
+            ASSERT_EQ(depthJpegExifOrientation, ExifOrientation::ORIENTATION_0_DEGREES);
+        } else {
+            ASSERT_EQ(depthJpegExifOrientation, exifOrientation);
+        }
+
+        auto confidenceJpegExifOrientation = ExifOrientation::ORIENTATION_UNDEFINED;
+        ASSERT_EQ(NV12Compressor::getExifOrientation(
+                depthPhotoBuffer.data() + mainJpegSize + depthMapSize,
+                confidenceMapSize, &confidenceJpegExifOrientation), OK);
+        if (exifOrientation == ORIENTATION_UNDEFINED) {
+            // In case of undefined or missing EXIF orientation, always expect 0 degrees in the
+            // confidence map.
+            ASSERT_EQ(confidenceJpegExifOrientation, ExifOrientation::ORIENTATION_0_DEGREES);
+        } else {
+            ASSERT_EQ(confidenceJpegExifOrientation, exifOrientation);
+        }
+    }
+
+    dlclose(libHandle);
+}
+
+TEST(DepthProcessorTest, TestDephtPhotoPhysicalRotation) {
+    void *libHandle;
+    int jpegQuality = 95;
+
+    process_depth_photo_frame processFunc;
+    linkToDepthPhotoLibrary(&libHandle, &processFunc);
+    if (libHandle == nullptr) {
+        // Depth library no present, nothing more to test.
+        return;
+    }
+
+    // In case of physical rotation, the EXIF orientation must always be 0.
+    auto exifOrientation = ExifOrientation::ORIENTATION_0_DEGREES;
+    DepthPhotoOrientation depthOrientations[] = {
+            DepthPhotoOrientation::DEPTH_ORIENTATION_0_DEGREES,
+            DepthPhotoOrientation::DEPTH_ORIENTATION_90_DEGREES,
+            DepthPhotoOrientation::DEPTH_ORIENTATION_180_DEGREES,
+            DepthPhotoOrientation::DEPTH_ORIENTATION_270_DEGREES };
+    for (auto depthOrientation : depthOrientations) {
+        std::vector<uint8_t> colorJpegBuffer;
+        bool switchDimensions = false;
+        size_t expectedWidth = kTestBufferWidth;
+        size_t expectedHeight = kTestBufferHeight;
+        if ((depthOrientation == DepthPhotoOrientation::DEPTH_ORIENTATION_90_DEGREES) ||
+                (depthOrientation == DepthPhotoOrientation::DEPTH_ORIENTATION_270_DEGREES)) {
+            switchDimensions = true;
+            expectedWidth = kTestBufferHeight;
+            expectedHeight = kTestBufferWidth;
+        }
+        generateColorJpegBuffer(jpegQuality, exifOrientation, /*includeExif*/ true,
+                switchDimensions, &colorJpegBuffer);
+        auto jpegExifOrientation = ExifOrientation::ORIENTATION_UNDEFINED;
+        ASSERT_EQ(NV12Compressor::getExifOrientation(colorJpegBuffer.data(), colorJpegBuffer.size(),
+                &jpegExifOrientation), OK);
+        ASSERT_EQ(exifOrientation, jpegExifOrientation);
+
+        std::array<uint16_t, kTestBufferDepthSize> depth16Buffer;
+        generateDepth16Buffer(&depth16Buffer);
+
+        DepthPhotoInputFrame inputFrame;
+        inputFrame.mMainJpegBuffer = reinterpret_cast<const char*> (colorJpegBuffer.data());
+        inputFrame.mMainJpegSize = colorJpegBuffer.size();
+        // Worst case both depth and confidence maps have the same size as the main color image.
+        inputFrame.mMaxJpegSize = inputFrame.mMainJpegSize * 3;
+        inputFrame.mMainJpegWidth = kTestBufferWidth;
+        inputFrame.mMainJpegHeight = kTestBufferHeight;
+        inputFrame.mJpegQuality = jpegQuality;
+        inputFrame.mDepthMapBuffer = depth16Buffer.data();
+        inputFrame.mDepthMapWidth = inputFrame.mDepthMapStride = kTestBufferWidth;
+        inputFrame.mDepthMapHeight = kTestBufferHeight;
+        inputFrame.mOrientation = depthOrientation;
+
+        std::vector<uint8_t> depthPhotoBuffer(inputFrame.mMaxJpegSize);
+        size_t actualDepthPhotoSize = 0;
+        ASSERT_EQ(processFunc(inputFrame, depthPhotoBuffer.size(), depthPhotoBuffer.data(),
+                &actualDepthPhotoSize), 0);
+        ASSERT_TRUE((actualDepthPhotoSize > 0) &&
+                (depthPhotoBuffer.size() >= actualDepthPhotoSize));
+
+        size_t mainJpegSize = 0;
+        ASSERT_EQ(NV12Compressor::findJpegSize(depthPhotoBuffer.data(), actualDepthPhotoSize,
+                &mainJpegSize), OK);
+        ASSERT_TRUE((mainJpegSize > 0) && (mainJpegSize < actualDepthPhotoSize));
+        size_t depthMapSize = 0;
+        ASSERT_EQ(NV12Compressor::findJpegSize(depthPhotoBuffer.data() + mainJpegSize,
+                actualDepthPhotoSize - mainJpegSize, &depthMapSize), OK);
+        ASSERT_TRUE((depthMapSize > 0) && (depthMapSize < (actualDepthPhotoSize - mainJpegSize)));
+        size_t confidenceMapSize = actualDepthPhotoSize - (mainJpegSize + depthMapSize);
+
+        //Depth and confidence images must have the same EXIF orientation as the source
+        auto depthJpegExifOrientation = ExifOrientation::ORIENTATION_UNDEFINED;
+        ASSERT_EQ(NV12Compressor::getExifOrientation(depthPhotoBuffer.data() + mainJpegSize,
+                depthMapSize, &depthJpegExifOrientation), OK);
+        ASSERT_EQ(depthJpegExifOrientation, exifOrientation);
+        size_t depthMapWidth, depthMapHeight;
+        ASSERT_EQ(NV12Compressor::getJpegImageDimensions(depthPhotoBuffer.data() + mainJpegSize,
+                depthMapSize, &depthMapWidth, &depthMapHeight), OK);
+        ASSERT_EQ(depthMapWidth, expectedWidth);
+        ASSERT_EQ(depthMapHeight, expectedHeight);
+
+        auto confidenceJpegExifOrientation = ExifOrientation::ORIENTATION_UNDEFINED;
+        ASSERT_EQ(NV12Compressor::getExifOrientation(
+                depthPhotoBuffer.data() + mainJpegSize + depthMapSize, confidenceMapSize,
+                &confidenceJpegExifOrientation), OK);
+        ASSERT_EQ(confidenceJpegExifOrientation, exifOrientation);
+        size_t confidenceMapWidth, confidenceMapHeight;
+        ASSERT_EQ(NV12Compressor::getJpegImageDimensions(
+                depthPhotoBuffer.data() + mainJpegSize + depthMapSize, confidenceMapSize,
+                &confidenceMapWidth, &confidenceMapHeight), OK);
+        ASSERT_EQ(confidenceMapWidth, expectedWidth);
+        ASSERT_EQ(confidenceMapHeight, expectedHeight);
+    }
+
+    dlclose(libHandle);
+}
diff --git a/services/camera/libcameraservice/tests/DistortionMapperTest.cpp b/services/camera/libcameraservice/tests/DistortionMapperTest.cpp
index 2a689c6..54935c9 100644
--- a/services/camera/libcameraservice/tests/DistortionMapperTest.cpp
+++ b/services/camera/libcameraservice/tests/DistortionMapperTest.cpp
@@ -167,6 +167,30 @@
     }
 }
 
+TEST(DistortionMapperTest, ClampConsistency) {
+    status_t res;
+
+    std::array<int32_t, 4> activeArray = {0, 0, 4032, 3024};
+    DistortionMapper m;
+    setupTestMapper(&m, identityDistortion, testICal, /*activeArray*/ activeArray.data(),
+            /*preCorrectionActiveArray*/ activeArray.data());
+
+    auto rectsOrig = activeArray;
+    res = m.mapCorrectedRectToRaw(activeArray.data(), 1, /*clamp*/true, /*simple*/ true);
+    ASSERT_EQ(res, OK);
+
+    for (size_t i = 0; i < activeArray.size(); i++) {
+        EXPECT_EQ(activeArray[i], rectsOrig[i]);
+    }
+
+    res = m.mapRawRectToCorrected(activeArray.data(), 1, /*clamp*/true, /*simple*/ true);
+    ASSERT_EQ(res, OK);
+
+    for (size_t i = 0; i < activeArray.size(); i++) {
+        EXPECT_EQ(activeArray[i], rectsOrig[i]);
+    }
+}
+
 TEST(DistortionMapperTest, SimpleTransform) {
     status_t res;
 
diff --git a/services/camera/libcameraservice/tests/NV12Compressor.cpp b/services/camera/libcameraservice/tests/NV12Compressor.cpp
new file mode 100644
index 0000000..0a41a1f
--- /dev/null
+++ b/services/camera/libcameraservice/tests/NV12Compressor.cpp
@@ -0,0 +1,379 @@
+/*
+* Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "Test_NV12Compressor"
+
+#include "NV12Compressor.h"
+
+#include <libexif/exif-data.h>
+#include <netinet/in.h>
+
+using namespace android;
+using namespace android::camera3;
+
+namespace std {
+template <>
+struct default_delete<ExifEntry> {
+    inline void operator()(ExifEntry* entry) const { exif_entry_unref(entry); }
+};
+
+template <>
+struct default_delete<ExifData> {
+    inline void operator()(ExifData* data) const { exif_data_unref(data); }
+};
+
+}  // namespace std
+
+bool NV12Compressor::compress(const unsigned char* data, int width, int height, int quality) {
+    if (!configureCompressor(width, height, quality)) {
+        // the method will have logged a more detailed error message than we can
+        // provide here so just return.
+        return false;
+    }
+
+    return compressData(data, /*exifData*/ nullptr);
+}
+
+bool NV12Compressor::compressWithExifOrientation(const unsigned char* data, int width, int height,
+        int quality, android::camera3::ExifOrientation exifValue) {
+    std::unique_ptr<ExifData> exifData(exif_data_new());
+    if (exifData.get() == nullptr) {
+        return false;
+    }
+
+    exif_data_set_option(exifData.get(), EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
+    exif_data_set_data_type(exifData.get(), EXIF_DATA_TYPE_COMPRESSED);
+    exif_data_set_byte_order(exifData.get(), EXIF_BYTE_ORDER_INTEL);
+    std::unique_ptr<ExifEntry> exifEntry(exif_entry_new());
+    if (exifEntry.get() ==  nullptr) {
+        return false;
+    }
+
+    exifEntry->tag = EXIF_TAG_ORIENTATION;
+    exif_content_add_entry(exifData->ifd[EXIF_IFD_0], exifEntry.get());
+    exif_entry_initialize(exifEntry.get(), exifEntry->tag);
+    exif_set_short(exifEntry->data, EXIF_BYTE_ORDER_INTEL, exifValue);
+
+    if (!configureCompressor(width, height, quality)) {
+        return false;
+    }
+
+    return compressData(data, exifData.get());
+}
+
+const std::vector<uint8_t>& NV12Compressor::getCompressedData() const {
+    return mDestManager.mBuffer;
+}
+
+bool NV12Compressor::configureCompressor(int width, int height, int quality) {
+    mCompressInfo.err = jpeg_std_error(&mErrorManager);
+    // NOTE! DANGER! Do not construct any non-trivial objects below setjmp!
+    // The compiler will not generate code to destroy them during the return
+    // below so they will leak. Additionally, do not place any calls to libjpeg
+    // that can fail above this line or any error will cause undefined behavior.
+    if (setjmp(mErrorManager.mJumpBuffer)) {
+        // This is where the error handler will jump in case setup fails
+        // The error manager will ALOG an appropriate error message
+        return false;
+    }
+
+    jpeg_create_compress(&mCompressInfo);
+
+    mCompressInfo.image_width = width;
+    mCompressInfo.image_height = height;
+    mCompressInfo.input_components = 3;
+    mCompressInfo.in_color_space = JCS_YCbCr;
+    jpeg_set_defaults(&mCompressInfo);
+
+    jpeg_set_quality(&mCompressInfo, quality, TRUE);
+    // It may seem weird to set color space here again but this will also set
+    // other fields. These fields might be overwritten by jpeg_set_defaults
+    jpeg_set_colorspace(&mCompressInfo, JCS_YCbCr);
+    mCompressInfo.raw_data_in = TRUE;
+    mCompressInfo.dct_method = JDCT_IFAST;
+    // Set sampling factors
+    mCompressInfo.comp_info[0].h_samp_factor = 2;
+    mCompressInfo.comp_info[0].v_samp_factor = 2;
+    mCompressInfo.comp_info[1].h_samp_factor = 1;
+    mCompressInfo.comp_info[1].v_samp_factor = 1;
+    mCompressInfo.comp_info[2].h_samp_factor = 1;
+    mCompressInfo.comp_info[2].v_samp_factor = 1;
+
+    mCompressInfo.dest = &mDestManager;
+
+    return true;
+}
+
+static void deinterleave(const uint8_t* vuPlanar, std::vector<uint8_t>& uRows,
+        std::vector<uint8_t>& vRows, int rowIndex, int width, int height, int stride) {
+    int numRows = (height - rowIndex) / 2;
+    if (numRows > 8) numRows = 8;
+    for (int row = 0; row < numRows; ++row) {
+        int offset = ((rowIndex >> 1) + row) * stride;
+        const uint8_t* vu = vuPlanar + offset;
+        for (int i = 0; i < (width >> 1); ++i) {
+            int index = row * (width >> 1) + i;
+            uRows[index] = vu[1];
+            vRows[index] = vu[0];
+            vu += 2;
+        }
+    }
+}
+
+bool NV12Compressor::compressData(const unsigned char* data, ExifData* exifData) {
+    const uint8_t* y[16];
+    const uint8_t* cb[8];
+    const uint8_t* cr[8];
+    const uint8_t** planes[3] = { y, cb, cr };
+
+    int i, offset;
+    int width = mCompressInfo.image_width;
+    int height = mCompressInfo.image_height;
+    const uint8_t* yPlanar = data;
+    const uint8_t* vuPlanar = data + (width * height);
+    std::vector<uint8_t> uRows(8 * (width >> 1));
+    std::vector<uint8_t> vRows(8 * (width >> 1));
+
+    // NOTE! DANGER! Do not construct any non-trivial objects below setjmp!
+    // The compiler will not generate code to destroy them during the return
+    // below so they will leak. Additionally, do not place any calls to libjpeg
+    // that can fail above this line or any error will cause undefined behavior.
+    if (setjmp(mErrorManager.mJumpBuffer)) {
+        // This is where the error handler will jump in case compression fails
+        // The error manager will ALOG an appropriate error message
+        return false;
+    }
+
+    jpeg_start_compress(&mCompressInfo, TRUE);
+
+    attachExifData(exifData);
+
+    // process 16 lines of Y and 8 lines of U/V each time.
+    while (mCompressInfo.next_scanline < mCompressInfo.image_height) {
+        //deinterleave u and v
+        deinterleave(vuPlanar, uRows, vRows, mCompressInfo.next_scanline,
+                     width, height, width);
+
+        // Jpeg library ignores the rows whose indices are greater than height.
+        for (i = 0; i < 16; i++) {
+            // y row
+            y[i] = yPlanar + (mCompressInfo.next_scanline + i) * width;
+
+            // construct u row and v row
+            if ((i & 1) == 0) {
+                // height and width are both halved because of downsampling
+                offset = (i >> 1) * (width >> 1);
+                cb[i/2] = &uRows[offset];
+                cr[i/2] = &vRows[offset];
+            }
+          }
+        jpeg_write_raw_data(&mCompressInfo, const_cast<JSAMPIMAGE>(planes), 16);
+    }
+
+    jpeg_finish_compress(&mCompressInfo);
+    jpeg_destroy_compress(&mCompressInfo);
+
+    return true;
+}
+
+bool NV12Compressor::attachExifData(ExifData* exifData) {
+    if (exifData == nullptr) {
+        // This is not an error, we don't require EXIF data
+        return true;
+    }
+
+    // Save the EXIF data to memory
+    unsigned char* rawData = nullptr;
+    unsigned int size = 0;
+    exif_data_save_data(exifData, &rawData, &size);
+    if (rawData == nullptr) {
+        ALOGE("Failed to create EXIF data block");
+        return false;
+    }
+
+    jpeg_write_marker(&mCompressInfo, JPEG_APP0 + 1, rawData, size);
+    free(rawData);
+    return true;
+}
+
+NV12Compressor::ErrorManager::ErrorManager() {
+    error_exit = &onJpegError;
+}
+
+void NV12Compressor::ErrorManager::onJpegError(j_common_ptr cinfo) {
+    // NOTE! Do not construct any non-trivial objects in this method at the top
+    // scope. Their destructors will not be called. If you do need such an
+    // object create a local scope that does not include the longjmp call,
+    // that ensures the object is destroyed before longjmp is called.
+    ErrorManager* errorManager = reinterpret_cast<ErrorManager*>(cinfo->err);
+
+    // Format and log error message
+    char errorMessage[JMSG_LENGTH_MAX];
+    (*errorManager->format_message)(cinfo, errorMessage);
+    errorMessage[sizeof(errorMessage) - 1] = '\0';
+    ALOGE("JPEG compression error: %s", errorMessage);
+    jpeg_destroy(cinfo);
+
+    // And through the looking glass we go
+    longjmp(errorManager->mJumpBuffer, 1);
+}
+
+NV12Compressor::DestinationManager::DestinationManager() {
+    init_destination = &initDestination;
+    empty_output_buffer = &emptyOutputBuffer;
+    term_destination = &termDestination;
+}
+
+void NV12Compressor::DestinationManager::initDestination(j_compress_ptr cinfo) {
+    auto manager = reinterpret_cast<DestinationManager*>(cinfo->dest);
+
+    // Start out with some arbitrary but not too large buffer size
+    manager->mBuffer.resize(16 * 1024);
+    manager->next_output_byte = &manager->mBuffer[0];
+    manager->free_in_buffer = manager->mBuffer.size();
+}
+
+boolean NV12Compressor::DestinationManager::emptyOutputBuffer(
+        j_compress_ptr cinfo) {
+    auto manager = reinterpret_cast<DestinationManager*>(cinfo->dest);
+
+    // Keep doubling the size of the buffer for a very low, amortized
+    // performance cost of the allocations
+    size_t oldSize = manager->mBuffer.size();
+    manager->mBuffer.resize(oldSize * 2);
+    manager->next_output_byte = &manager->mBuffer[oldSize];
+    manager->free_in_buffer = manager->mBuffer.size() - oldSize;
+    return manager->free_in_buffer != 0;
+}
+
+void NV12Compressor::DestinationManager::termDestination(j_compress_ptr cinfo) {
+    auto manager = reinterpret_cast<DestinationManager*>(cinfo->dest);
+
+    // Resize down to the exact size of the output, that is remove as many
+    // bytes as there are left in the buffer
+    manager->mBuffer.resize(manager->mBuffer.size() - manager->free_in_buffer);
+}
+
+status_t NV12Compressor::findJpegSize(uint8_t *jpegBuffer, size_t maxSize, size_t *size /*out*/) {
+    if ((size == nullptr) || (jpegBuffer == nullptr)) {
+        return BAD_VALUE;
+    }
+
+    if (checkJpegStart(jpegBuffer) == 0) {
+        return BAD_VALUE;
+    }
+
+    // Read JFIF segment markers, skip over segment data
+    *size = kMarkerLength; //jump to Start Of Image
+    while (*size <= maxSize - kMarkerLength) {
+        segment_t *segment = (segment_t*)(jpegBuffer + *size);
+        uint8_t type = checkJpegMarker(segment->marker);
+        if (type == 0) { // invalid marker, no more segments, begin JPEG data
+            break;
+        }
+        if (type == kEndOfImage || *size > maxSize - sizeof(segment_t)) {
+            return BAD_VALUE;
+        }
+
+        size_t length = ntohs(segment->length);
+        *size += length + kMarkerLength;
+    }
+
+    // Find End of Image
+    // Scan JPEG buffer until End of Image
+    bool foundEnd = false;
+    for ( ; *size <= maxSize - kMarkerLength; (*size)++) {
+        if (checkJpegEnd(jpegBuffer + *size)) {
+            foundEnd = true;
+            *size += kMarkerLength;
+            break;
+        }
+    }
+
+    if (!foundEnd) {
+        return BAD_VALUE;
+    }
+
+    if (*size > maxSize) {
+        *size = maxSize;
+    }
+
+    return OK;
+}
+
+status_t NV12Compressor::getJpegImageDimensions(uint8_t *jpegBuffer,
+        size_t jpegBufferSize, size_t *width /*out*/, size_t *height /*out*/) {
+    if ((jpegBuffer == nullptr) || (width == nullptr) || (height == nullptr) ||
+            (jpegBufferSize == 0u)) {
+        return BAD_VALUE;
+    }
+
+    // Scan JPEG buffer until Start of Frame
+    bool foundSOF = false;
+    size_t currentPos;
+    for (currentPos = 0; currentPos <= jpegBufferSize - kMarkerLength; currentPos++) {
+        if (checkStartOfFrame(jpegBuffer + currentPos)) {
+            foundSOF = true;
+            currentPos += kMarkerLength;
+            break;
+        }
+    }
+
+    if (!foundSOF) {
+        ALOGE("%s: Start of Frame not found", __func__);
+        return BAD_VALUE;
+    }
+
+    sof_t *startOfFrame = reinterpret_cast<sof_t *> (jpegBuffer + currentPos);
+    *width = ntohs(startOfFrame->width);
+    *height = ntohs(startOfFrame->height);
+
+    return OK;
+}
+
+status_t NV12Compressor::getExifOrientation(uint8_t *jpegBuffer, size_t jpegBufferSize,
+        ExifOrientation *exifValue /*out*/) {
+    if ((jpegBuffer == nullptr) || (exifValue == nullptr) || (jpegBufferSize == 0u)) {
+        return BAD_VALUE;
+    }
+
+    std::unique_ptr<ExifData> exifData(exif_data_new());
+    exif_data_load_data(exifData.get(), jpegBuffer, jpegBufferSize);
+    ExifEntry *orientation = exif_content_get_entry(exifData->ifd[EXIF_IFD_0],
+            EXIF_TAG_ORIENTATION);
+    if ((orientation == nullptr) || (orientation->size != sizeof(ExifShort))) {
+        return BAD_VALUE;
+    }
+
+    auto orientationValue = exif_get_short(orientation->data,
+            exif_data_get_byte_order(exifData.get()));
+    status_t ret;
+    switch (orientationValue) {
+        case ExifOrientation::ORIENTATION_0_DEGREES:
+        case ExifOrientation::ORIENTATION_90_DEGREES:
+        case ExifOrientation::ORIENTATION_180_DEGREES:
+        case ExifOrientation::ORIENTATION_270_DEGREES:
+            *exifValue = static_cast<ExifOrientation> (orientationValue);
+            ret = OK;
+            break;
+        default:
+            ALOGE("%s: Unexpected EXIF orientation value: %u", __FUNCTION__, orientationValue);
+            ret = BAD_VALUE;
+    }
+
+    return ret;
+}
diff --git a/services/camera/libcameraservice/tests/NV12Compressor.h b/services/camera/libcameraservice/tests/NV12Compressor.h
new file mode 100644
index 0000000..ee22d5e
--- /dev/null
+++ b/services/camera/libcameraservice/tests/NV12Compressor.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TEST_CAMERA_JPEG_STUB_NV12_COMPRESSOR_H
+#define TEST_CAMERA_JPEG_STUB_NV12_COMPRESSOR_H
+
+#include <setjmp.h>
+#include <stdlib.h>
+extern "C" {
+#include <jpeglib.h>
+#include <jerror.h>
+}
+
+#include <utils/Errors.h>
+#include <vector>
+
+#include "../utils/ExifUtils.h"
+
+struct _ExifData;
+typedef _ExifData ExifData;
+
+class NV12Compressor {
+public:
+    NV12Compressor() {}
+
+    /* Compress |data| which represents raw NV21 encoded data of dimensions
+     * |width| * |height|.
+     */
+    bool compress(const unsigned char* data, int width, int height, int quality);
+    bool compressWithExifOrientation(const unsigned char* data, int width, int height, int quality,
+            android::camera3::ExifOrientation exifValue);
+
+    /* Get a reference to the compressed data, this will return an empty vector
+     * if compress has not been called yet
+     */
+    const std::vector<unsigned char>& getCompressedData() const;
+
+    // Utility methods
+    static android::status_t findJpegSize(uint8_t *jpegBuffer, size_t maxSize,
+            size_t *size /*out*/);
+
+    static android::status_t getExifOrientation(uint8_t *jpegBuffer,
+            size_t jpegBufferSize, android::camera3::ExifOrientation *exifValue /*out*/);
+
+    /* Get Jpeg image dimensions from the first Start Of Frame. Please note that due to the
+     * way the jpeg buffer is scanned if the image contains a thumbnail, then the size returned
+     * will be of the thumbnail and not the main image.
+     */
+    static android::status_t getJpegImageDimensions(uint8_t *jpegBuffer, size_t jpegBufferSize,
+            size_t *width /*out*/, size_t *height /*out*/);
+
+private:
+
+    struct DestinationManager : jpeg_destination_mgr {
+        DestinationManager();
+
+        static void initDestination(j_compress_ptr cinfo);
+        static boolean emptyOutputBuffer(j_compress_ptr cinfo);
+        static void termDestination(j_compress_ptr cinfo);
+
+        std::vector<unsigned char> mBuffer;
+    };
+
+    struct ErrorManager : jpeg_error_mgr {
+        ErrorManager();
+
+        static void onJpegError(j_common_ptr cinfo);
+
+        jmp_buf mJumpBuffer;
+    };
+
+    static const size_t kMarkerLength = 2; // length of a marker
+    static const uint8_t kMarker = 0xFF; // First byte of marker
+    static const uint8_t kStartOfImage = 0xD8; // Start of Image
+    static const uint8_t kEndOfImage = 0xD9; // End of Image
+    static const uint8_t kStartOfFrame = 0xC0; // Start of Frame
+
+    struct __attribute__((packed)) segment_t {
+        uint8_t marker[kMarkerLength];
+        uint16_t length;
+    };
+
+    struct __attribute__((packed)) sof_t {
+        uint16_t length;
+        uint8_t precision;
+        uint16_t height;
+        uint16_t width;
+    };
+
+    // check for start of image marker
+    static bool checkStartOfFrame(uint8_t* buf) {
+        return buf[0] == kMarker && buf[1] == kStartOfFrame;
+    }
+
+    // check for start of image marker
+    static bool checkJpegStart(uint8_t* buf) {
+        return buf[0] == kMarker && buf[1] == kStartOfImage;
+    }
+
+    // check for End of Image marker
+    static bool checkJpegEnd(uint8_t *buf) {
+        return buf[0] == kMarker && buf[1] == kEndOfImage;
+    }
+
+    // check for arbitrary marker, returns marker type (second byte)
+    // returns 0 if no marker found. Note: 0x00 is not a valid marker type
+    static uint8_t checkJpegMarker(uint8_t *buf) {
+        return (buf[0] == kMarker) ? buf[1] : 0;
+    }
+
+    jpeg_compress_struct mCompressInfo;
+    DestinationManager mDestManager;
+    ErrorManager mErrorManager;
+
+    bool configureCompressor(int width, int height, int quality);
+    bool compressData(const unsigned char* data, ExifData* exifData);
+    bool attachExifData(ExifData* exifData);
+};
+
+#endif  // TEST_CAMERA_JPEG_STUB_NV12_COMPRESSOR_H
+
diff --git a/services/camera/libcameraservice/utils/CameraThreadState.cpp b/services/camera/libcameraservice/utils/CameraThreadState.cpp
new file mode 100644
index 0000000..b9e344b
--- /dev/null
+++ b/services/camera/libcameraservice/utils/CameraThreadState.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "CameraThreadState.h"
+#include <binder/IPCThreadState.h>
+#include <hwbinder/IPCThreadState.h>
+#include <unistd.h>
+
+namespace android {
+
+int CameraThreadState::getCallingUid() {
+    if (hardware::IPCThreadState::self()->isServingCall()) {
+        return hardware::IPCThreadState::self()->getCallingUid();
+    }
+    return IPCThreadState::self()->getCallingUid();
+}
+
+int CameraThreadState::getCallingPid() {
+    if (hardware::IPCThreadState::self()->isServingCall()) {
+        return hardware::IPCThreadState::self()->getCallingPid();
+    }
+    return IPCThreadState::self()->getCallingPid();
+}
+
+int64_t CameraThreadState::clearCallingIdentity() {
+    if (hardware::IPCThreadState::self()->isServingCall()) {
+        return hardware::IPCThreadState::self()->clearCallingIdentity();
+    }
+    return IPCThreadState::self()->clearCallingIdentity();
+}
+
+void CameraThreadState::restoreCallingIdentity(int64_t token) {
+    if (hardware::IPCThreadState::self()->isServingCall()) {
+        hardware::IPCThreadState::self()->restoreCallingIdentity(token);
+    } else {
+        IPCThreadState::self()->restoreCallingIdentity(token);
+    }
+    return;
+}
+
+} // android
diff --git a/services/camera/libcameraservice/utils/CameraThreadState.h b/services/camera/libcameraservice/utils/CameraThreadState.h
new file mode 100644
index 0000000..e1a70de
--- /dev/null
+++ b/services/camera/libcameraservice/utils/CameraThreadState.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+
+namespace android {
+class CameraThreadState {
+public:
+  static int64_t clearCallingIdentity();
+
+  static void restoreCallingIdentity(int64_t token);
+
+  static int getCallingUid();
+
+  static int getCallingPid();
+};
+
+} // android
diff --git a/services/camera/libcameraservice/utils/ClientManager.h b/services/camera/libcameraservice/utils/ClientManager.h
index d7135f1..ec6f01c 100644
--- a/services/camera/libcameraservice/utils/ClientManager.h
+++ b/services/camera/libcameraservice/utils/ClientManager.h
@@ -33,12 +33,38 @@
 
 class ClientPriority {
 public:
-    ClientPriority(int32_t score, int32_t state) :
-        mScore(score), mState(state) {}
+    /**
+     * Choosing to set mIsVendorClient through a parameter instead of calling
+     * hardware::IPCThreadState::self()->isServingCall() to protect against the
+     * case where the construction is offloaded to another thread which isn't a
+     * hwbinder thread.
+     */
+    ClientPriority(int32_t score, int32_t state, bool isVendorClient) :
+            mScore(score), mState(state), mIsVendorClient(isVendorClient) { }
 
     int32_t getScore() const { return mScore; }
     int32_t getState() const { return mState; }
 
+    void setScore(int32_t score) {
+        // For vendor clients, the score is set once and for all during
+        // construction. Otherwise, it can get reset each time cameraserver
+        // queries ActivityManagerService for oom_adj scores / states .
+        if (!mIsVendorClient) {
+            mScore = score;
+        }
+    }
+
+    void setState(int32_t state) {
+      // For vendor clients, the score is set once and for all during
+      // construction. Otherwise, it can get reset each time cameraserver
+      // queries ActivityManagerService for oom_adj scores / states
+      // (ActivityManagerService returns a vendor process' state as
+      // PROCESS_STATE_NONEXISTENT.
+      if (!mIsVendorClient) {
+          mState = state;
+      }
+    }
+
     bool operator==(const ClientPriority& rhs) const {
         return (this->mScore == rhs.mScore) && (this->mState == rhs.mState);
     }
@@ -66,6 +92,7 @@
 private:
         int32_t mScore;
         int32_t mState;
+        bool mIsVendorClient = false;
 };
 
 // --------------------------------------------------------------------------------
@@ -82,9 +109,10 @@
 class ClientDescriptor final {
 public:
     ClientDescriptor(const KEY& key, const VALUE& value, int32_t cost,
-            const std::set<KEY>& conflictingKeys, int32_t score, int32_t ownerId, int32_t state);
+            const std::set<KEY>& conflictingKeys, int32_t score, int32_t ownerId, int32_t state,
+            bool isVendorClient);
     ClientDescriptor(KEY&& key, VALUE&& value, int32_t cost, std::set<KEY>&& conflictingKeys,
-            int32_t score, int32_t ownerId, int32_t state);
+            int32_t score, int32_t ownerId, int32_t state, bool isVendorClient);
 
     ~ClientDescriptor();
 
@@ -148,17 +176,19 @@
 
 template<class KEY, class VALUE>
 ClientDescriptor<KEY, VALUE>::ClientDescriptor(const KEY& key, const VALUE& value, int32_t cost,
-        const std::set<KEY>& conflictingKeys, int32_t score, int32_t ownerId, int32_t state) :
+        const std::set<KEY>& conflictingKeys, int32_t score, int32_t ownerId, int32_t state,
+        bool isVendorClient) :
         mKey{key}, mValue{value}, mCost{cost}, mConflicting{conflictingKeys},
-        mPriority(score, state),
+        mPriority(score, state, isVendorClient),
         mOwnerId{ownerId} {}
 
 template<class KEY, class VALUE>
 ClientDescriptor<KEY, VALUE>::ClientDescriptor(KEY&& key, VALUE&& value, int32_t cost,
-        std::set<KEY>&& conflictingKeys, int32_t score, int32_t ownerId, int32_t state) :
+        std::set<KEY>&& conflictingKeys, int32_t score, int32_t ownerId, int32_t state,
+        bool isVendorClient) :
         mKey{std::forward<KEY>(key)}, mValue{std::forward<VALUE>(value)}, mCost{cost},
         mConflicting{std::forward<std::set<KEY>>(conflictingKeys)},
-        mPriority(score, state), mOwnerId{ownerId} {}
+        mPriority(score, state, isVendorClient), mOwnerId{ownerId} {}
 
 template<class KEY, class VALUE>
 ClientDescriptor<KEY, VALUE>::~ClientDescriptor() {}
@@ -204,7 +234,13 @@
 
 template<class KEY, class VALUE>
 void ClientDescriptor<KEY, VALUE>::setPriority(const ClientPriority& priority) {
-    mPriority = priority;
+    // We don't use the usual copy constructor here since we want to remember
+    // whether a client is a vendor client or not. This could have been wiped
+    // off in the incoming priority argument since an AIDL thread might have
+    // called hardware::IPCThreadState::self()->isServingCall() after refreshing
+    // priorities for old clients through ProcessInfoService::getProcessStatesScoresFromPids().
+    mPriority.setScore(priority.getScore());
+    mPriority.setState(priority.getState());
 }
 
 // --------------------------------------------------------------------------------
diff --git a/services/camera/libcameraservice/utils/ExifUtils.cpp b/services/camera/libcameraservice/utils/ExifUtils.cpp
new file mode 100644
index 0000000..8a0303a
--- /dev/null
+++ b/services/camera/libcameraservice/utils/ExifUtils.cpp
@@ -0,0 +1,1104 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "CameraServerExifUtils"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+//#define LOG_NDEBUG 0
+
+#include <cutils/log.h>
+
+#include <inttypes.h>
+#include <math.h>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+#include "ExifUtils.h"
+
+extern "C" {
+#include <libexif/exif-data.h>
+}
+
+namespace std {
+
+template <>
+struct default_delete<ExifEntry> {
+    inline void operator()(ExifEntry* entry) const { exif_entry_unref(entry); }
+};
+
+}  // namespace std
+
+
+namespace android {
+namespace camera3 {
+
+
+class ExifUtilsImpl : public ExifUtils {
+public:
+    ExifUtilsImpl();
+
+    virtual ~ExifUtilsImpl();
+
+    // Initialize() can be called multiple times. The setting of Exif tags will be
+    // cleared.
+    virtual bool initialize(const unsigned char *app1Segment, size_t app1SegmentSize);
+    virtual bool initializeEmpty();
+
+    // set all known fields from a metadata structure
+    virtual bool setFromMetadata(const CameraMetadata& metadata,
+            const CameraMetadata& staticInfo,
+            const size_t imageWidth,
+            const size_t imageHeight);
+
+    // sets the len aperture.
+    // Returns false if memory allocation fails.
+    virtual bool setAperture(float aperture);
+
+    // sets the color space.
+    // Returns false if memory allocation fails.
+    virtual bool setColorSpace(uint16_t color_space);
+
+    // sets the date and time of image last modified. It takes local time. The
+    // name of the tag is DateTime in IFD0.
+    // Returns false if memory allocation fails.
+    virtual bool setDateTime(const struct tm& t);
+
+    // sets the digital zoom ratio. If the numerator is 0, it means digital zoom
+    // was not used.
+    // Returns false if memory allocation fails.
+    virtual bool setDigitalZoomRatio(
+            uint32_t crop_width, uint32_t crop_height,
+            uint32_t sensor_width, uint32_t sensor_height);
+
+    // Sets the exposure bias.
+    // Returns false if memory allocation fails.
+    virtual bool setExposureBias(int32_t ev,
+            uint32_t ev_step_numerator, uint32_t ev_step_denominator);
+
+    // sets the exposure mode set when the image was shot.
+    // Returns false if memory allocation fails.
+    virtual bool setExposureMode(uint8_t exposure_mode);
+
+    // sets the exposure time, given in seconds.
+    // Returns false if memory allocation fails.
+    virtual bool setExposureTime(float exposure_time);
+
+    // sets the status of flash.
+    // Returns false if memory allocation fails.
+    virtual bool setFlash(uint8_t flash_available, uint8_t flash_state, uint8_t ae_mode);
+
+    // sets the F number.
+    // Returns false if memory allocation fails.
+    virtual bool setFNumber(float f_number);
+
+    // sets the focal length of lens used to take the image in millimeters.
+    // Returns false if memory allocation fails.
+    virtual bool setFocalLength(float focal_length);
+
+    // sets the focal length of lens for 35mm film used to take the image in millimeters.
+    // Returns false if memory allocation fails.
+    virtual bool setFocalLengthIn35mmFilm(float focal_length,
+            float sensor_size_x, float sensor_size_y);
+
+    // sets the altitude in meters.
+    // Returns false if memory allocation fails.
+    virtual bool setGpsAltitude(double altitude);
+
+    // sets the latitude with degrees minutes seconds format.
+    // Returns false if memory allocation fails.
+    virtual bool setGpsLatitude(double latitude);
+
+    // sets the longitude with degrees minutes seconds format.
+    // Returns false if memory allocation fails.
+    virtual bool setGpsLongitude(double longitude);
+
+    // sets GPS processing method.
+    // Returns false if memory allocation fails.
+    virtual bool setGpsProcessingMethod(const std::string& method);
+
+    // sets GPS date stamp and time stamp (atomic clock). It takes UTC time.
+    // Returns false if memory allocation fails.
+    virtual bool setGpsTimestamp(const struct tm& t);
+
+    // sets the length (number of rows) of main image.
+    // Returns false if memory allocation fails.
+    virtual bool setImageHeight(uint32_t length);
+
+    // sets the width (number of columes) of main image.
+    // Returns false if memory allocation fails.
+    virtual bool setImageWidth(uint32_t width);
+
+    // sets the ISO speed.
+    // Returns false if memory allocation fails.
+    virtual bool setIsoSpeedRating(uint16_t iso_speed_ratings);
+
+    // sets the smallest F number of the lens.
+    // Returns false if memory allocation fails.
+    virtual bool setMaxAperture(float aperture);
+
+    // sets image orientation.
+    // Returns false if memory allocation fails.
+    virtual bool setOrientation(uint16_t degrees);
+
+    // sets image orientation.
+    // Returns false if memory allocation fails.
+    virtual bool setOrientationValue(ExifOrientation orientationValue);
+
+    // sets the shutter speed.
+    // Returns false if memory allocation fails.
+    virtual bool setShutterSpeed(float exposure_time);
+
+    // sets the distance to the subject, given in meters.
+    // Returns false if memory allocation fails.
+    virtual bool setSubjectDistance(float diopters);
+
+    // sets the fractions of seconds for the <DateTime> tag.
+    // Returns false if memory allocation fails.
+    virtual bool setSubsecTime(const std::string& subsec_time);
+
+    // sets the white balance mode set when the image was shot.
+    // Returns false if memory allocation fails.
+    virtual bool setWhiteBalance(uint8_t white_balance);
+
+    // Generates APP1 segment.
+    // Returns false if generating APP1 segment fails.
+    virtual bool generateApp1();
+
+    // Gets buffer of APP1 segment. This method must be called only after calling
+    // GenerateAPP1().
+    virtual const uint8_t* getApp1Buffer();
+
+    // Gets length of APP1 segment. This method must be called only after calling
+    // GenerateAPP1().
+    virtual unsigned int getApp1Length();
+
+  protected:
+    // sets the version of this standard supported.
+    // Returns false if memory allocation fails.
+    virtual bool setExifVersion(const std::string& exif_version);
+
+    // Resets the pointers and memories.
+    virtual void reset();
+
+    // Adds a variable length tag to |exif_data_|. It will remove the original one
+    // if the tag exists.
+    // Returns the entry of the tag. The reference count of returned ExifEntry is
+    // two.
+    virtual std::unique_ptr<ExifEntry> addVariableLengthEntry(ExifIfd ifd,
+            ExifTag tag, ExifFormat format, uint64_t components, unsigned int size);
+
+    // Adds a entry of |tag| in |exif_data_|. It won't remove the original one if
+    // the tag exists.
+    // Returns the entry of the tag. It adds one reference count to returned
+    // ExifEntry.
+    virtual std::unique_ptr<ExifEntry> addEntry(ExifIfd ifd, ExifTag tag);
+
+    // Helpe functions to add exif data with different types.
+    virtual bool setShort(ExifIfd ifd, ExifTag tag, uint16_t value, const std::string& msg);
+
+    virtual bool setLong(ExifIfd ifd, ExifTag tag, uint32_t value, const std::string& msg);
+
+    virtual bool setRational(ExifIfd ifd, ExifTag tag, uint32_t numerator,
+            uint32_t denominator, const std::string& msg);
+
+    virtual bool setSRational(ExifIfd ifd, ExifTag tag, int32_t numerator,
+            int32_t denominator, const std::string& msg);
+
+    virtual bool setString(ExifIfd ifd, ExifTag tag, ExifFormat format,
+            const std::string& buffer, const std::string& msg);
+
+    float convertToApex(float val) {
+        return 2.0f * log2f(val);
+    }
+
+    // Destroys the buffer of APP1 segment if exists.
+    virtual void destroyApp1();
+
+    // The Exif data (APP1). Owned by this class.
+    ExifData* exif_data_;
+    // The raw data of APP1 segment. It's allocated by ExifMem in |exif_data_| but
+    // owned by this class.
+    uint8_t* app1_buffer_;
+    // The length of |app1_buffer_|.
+    unsigned int app1_length_;
+
+    // How precise the float-to-rational conversion for EXIF tags would be.
+    const static int kRationalPrecision = 10000;
+};
+
+#define SET_SHORT(ifd, tag, value)                      \
+    do {                                                \
+        if (setShort(ifd, tag, value, #tag) == false)   \
+            return false;                               \
+    } while (0);
+
+#define SET_LONG(ifd, tag, value)                       \
+    do {                                                \
+        if (setLong(ifd, tag, value, #tag) == false)    \
+            return false;                               \
+    } while (0);
+
+#define SET_RATIONAL(ifd, tag, numerator, denominator)                      \
+    do {                                                                    \
+        if (setRational(ifd, tag, numerator, denominator, #tag) == false)   \
+            return false;                                                   \
+    } while (0);
+
+#define SET_SRATIONAL(ifd, tag, numerator, denominator)                       \
+    do {                                                                      \
+        if (setSRational(ifd, tag, numerator, denominator, #tag) == false)    \
+            return false;                                                     \
+    } while (0);
+
+#define SET_STRING(ifd, tag, format, buffer)                                  \
+    do {                                                                      \
+        if (setString(ifd, tag, format, buffer, #tag) == false)               \
+            return false;                                                     \
+    } while (0);
+
+// This comes from the Exif Version 2.2 standard table 6.
+const char gExifAsciiPrefix[] = {0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0};
+
+static void setLatitudeOrLongitudeData(unsigned char* data, double num) {
+    // Take the integer part of |num|.
+    ExifLong degrees = static_cast<ExifLong>(num);
+    ExifLong minutes = static_cast<ExifLong>(60 * (num - degrees));
+    ExifLong microseconds =
+            static_cast<ExifLong>(3600000000u * (num - degrees - minutes / 60.0));
+    exif_set_rational(data, EXIF_BYTE_ORDER_INTEL, {degrees, 1});
+    exif_set_rational(data + sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL, {minutes, 1});
+    exif_set_rational(data + 2 * sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL,
+            {microseconds, 1000000});
+}
+
+ExifUtils *ExifUtils::create() {
+    return new ExifUtilsImpl();
+}
+
+ExifUtils::~ExifUtils() {
+}
+
+ExifUtilsImpl::ExifUtilsImpl()
+        : exif_data_(nullptr), app1_buffer_(nullptr), app1_length_(0) {}
+
+ExifUtilsImpl::~ExifUtilsImpl() {
+    reset();
+}
+
+
+bool ExifUtilsImpl::initialize(const unsigned char *app1Segment, size_t app1SegmentSize) {
+    reset();
+    exif_data_ = exif_data_new_from_data(app1Segment, app1SegmentSize);
+    if (exif_data_ == nullptr) {
+        ALOGE("%s: allocate memory for exif_data_ failed", __FUNCTION__);
+        return false;
+    }
+    // set the image options.
+    exif_data_set_option(exif_data_, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
+    exif_data_set_data_type(exif_data_, EXIF_DATA_TYPE_COMPRESSED);
+    exif_data_set_byte_order(exif_data_, EXIF_BYTE_ORDER_INTEL);
+
+    // set exif version to 2.2.
+    if (!setExifVersion("0220")) {
+        return false;
+    }
+
+    return true;
+}
+
+bool ExifUtilsImpl::initializeEmpty() {
+    reset();
+    exif_data_ = exif_data_new();
+    if (exif_data_ == nullptr) {
+        ALOGE("%s: allocate memory for exif_data_ failed", __FUNCTION__);
+        return false;
+    }
+    // set the image options.
+    exif_data_set_option(exif_data_, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
+    exif_data_set_data_type(exif_data_, EXIF_DATA_TYPE_COMPRESSED);
+    exif_data_set_byte_order(exif_data_, EXIF_BYTE_ORDER_INTEL);
+
+    // set exif version to 2.2.
+    if (!setExifVersion("0220")) {
+        return false;
+    }
+
+    return true;
+}
+
+bool ExifUtilsImpl::setAperture(float aperture) {
+    float apexValue = convertToApex(aperture);
+    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_APERTURE_VALUE,
+            static_cast<uint32_t>(std::round(apexValue * kRationalPrecision)),
+            kRationalPrecision);
+    return true;
+}
+
+bool ExifUtilsImpl::setColorSpace(uint16_t color_space) {
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_COLOR_SPACE, color_space);
+    return true;
+}
+
+bool ExifUtilsImpl::setDateTime(const struct tm& t) {
+    // The length is 20 bytes including NULL for termination in Exif standard.
+    char str[20];
+    int result = snprintf(str, sizeof(str), "%04i:%02i:%02i %02i:%02i:%02i",
+            t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
+    if (result != sizeof(str) - 1) {
+        ALOGW("%s: Input time is invalid", __FUNCTION__);
+        return false;
+    }
+    std::string buffer(str);
+    SET_STRING(EXIF_IFD_0, EXIF_TAG_DATE_TIME, EXIF_FORMAT_ASCII, buffer);
+    SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_ORIGINAL, EXIF_FORMAT_ASCII, buffer);
+    SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_DIGITIZED, EXIF_FORMAT_ASCII, buffer);
+    return true;
+}
+
+bool ExifUtilsImpl::setDigitalZoomRatio(
+        uint32_t crop_width, uint32_t crop_height,
+        uint32_t sensor_width, uint32_t sensor_height) {
+    float zoomRatioX = (crop_width == 0) ? 1.0 : 1.0 * sensor_width / crop_width;
+    float zoomRatioY = (crop_height == 0) ? 1.0 : 1.0 * sensor_height / crop_height;
+    float zoomRatio = std::max(zoomRatioX, zoomRatioY);
+    const static float noZoomThreshold = 1.02f;
+
+    if (zoomRatio <= noZoomThreshold) {
+        SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_DIGITAL_ZOOM_RATIO, 0, 1);
+    } else {
+        SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_DIGITAL_ZOOM_RATIO,
+                static_cast<uint32_t>(std::round(zoomRatio * kRationalPrecision)),
+                kRationalPrecision);
+    }
+    return true;
+}
+
+bool ExifUtilsImpl::setExposureMode(uint8_t exposure_mode) {
+    uint16_t exposureMode = (exposure_mode == ANDROID_CONTROL_AE_MODE_OFF) ? 1 : 0;
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_MODE, exposureMode);
+    return true;
+}
+
+bool ExifUtilsImpl::setExposureTime(float exposure_time) {
+    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_TIME,
+            static_cast<uint32_t>(std::round(exposure_time * kRationalPrecision)),
+            kRationalPrecision);
+    return true;
+}
+
+bool ExifUtilsImpl::setFlash(uint8_t flash_available, uint8_t flash_state, uint8_t ae_mode) {
+    // EXIF_TAG_FLASH bits layout per EXIF standard:
+    // Bit 0:    0 - did not fire
+    //           1 - fired
+    // Bit 1-2:  status of return light
+    // Bit 3-4:  0 - unknown
+    //           1 - compulsory flash firing
+    //           2 - compulsory flash suppression
+    //           3 - auto mode
+    // Bit 5:    0 - flash function present
+    //           1 - no flash function
+    // Bit 6:    0 - no red-eye reduction mode or unknown
+    //           1 - red-eye reduction supported
+    uint16_t flash = 0x20;
+
+    if (flash_available == ANDROID_FLASH_INFO_AVAILABLE_TRUE) {
+        flash = 0x00;
+
+        if (flash_state == ANDROID_FLASH_STATE_FIRED) {
+            flash |= 0x1;
+        }
+        if (ae_mode == ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE) {
+            flash |= 0x40;
+        }
+
+        uint16_t flashMode = 0;
+        switch (ae_mode) {
+            case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH:
+            case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE:
+               flashMode = 3; // AUTO
+               break;
+            case ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH:
+            case ANDROID_CONTROL_AE_MODE_ON_EXTERNAL_FLASH:
+               flashMode = 1; // ON
+               break;
+            case ANDROID_CONTROL_AE_MODE_OFF:
+            case ANDROID_CONTROL_AE_MODE_ON:
+               flashMode = 2; // OFF
+               break;
+            default:
+               flashMode = 0; // UNKNOWN
+               break;
+        }
+        flash |= (flashMode << 3);
+    }
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_FLASH, flash);
+    return true;
+}
+
+bool ExifUtilsImpl::setFNumber(float f_number) {
+    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FNUMBER,
+            static_cast<uint32_t>(std::round(f_number * kRationalPrecision)),
+            kRationalPrecision);
+    return true;
+}
+
+bool ExifUtilsImpl::setFocalLength(float focal_length) {
+    uint32_t numerator = static_cast<uint32_t>(std::round(focal_length * kRationalPrecision));
+    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH, numerator, kRationalPrecision);
+    return true;
+}
+
+bool ExifUtilsImpl::setFocalLengthIn35mmFilm(
+        float focal_length, float sensor_size_x, float sensor_size_y) {
+    static const float filmDiagonal = 43.27; // diagonal of 35mm film
+    static const float minSensorDiagonal = 0.01;
+    float sensorDiagonal = std::sqrt(
+            sensor_size_x * sensor_size_x + sensor_size_y * sensor_size_y);
+    sensorDiagonal = std::max(sensorDiagonal, minSensorDiagonal);
+    float focalLength35mmFilm = std::round(focal_length * filmDiagonal / sensorDiagonal);
+    focalLength35mmFilm = std::min(1.0f * 65535, focalLength35mmFilm);
+
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM,
+            static_cast<uint16_t>(focalLength35mmFilm));
+    return true;
+}
+
+bool ExifUtilsImpl::setGpsAltitude(double altitude) {
+    ExifTag refTag = static_cast<ExifTag>(EXIF_TAG_GPS_ALTITUDE_REF);
+    std::unique_ptr<ExifEntry> refEntry =
+            addVariableLengthEntry(EXIF_IFD_GPS, refTag, EXIF_FORMAT_BYTE, 1, 1);
+    if (!refEntry) {
+        ALOGE("%s: Adding GPSAltitudeRef exif entry failed", __FUNCTION__);
+        return false;
+    }
+    if (altitude >= 0) {
+        *refEntry->data = 0;
+    } else {
+        *refEntry->data = 1;
+        altitude *= -1;
+    }
+
+    ExifTag tag = static_cast<ExifTag>(EXIF_TAG_GPS_ALTITUDE);
+    std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(
+            EXIF_IFD_GPS, tag, EXIF_FORMAT_RATIONAL, 1, sizeof(ExifRational));
+    if (!entry) {
+        exif_content_remove_entry(exif_data_->ifd[EXIF_IFD_GPS], refEntry.get());
+        ALOGE("%s: Adding GPSAltitude exif entry failed", __FUNCTION__);
+        return false;
+    }
+    exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL,
+            {static_cast<ExifLong>(altitude * 1000), 1000});
+
+    return true;
+}
+
+bool ExifUtilsImpl::setGpsLatitude(double latitude) {
+    const ExifTag refTag = static_cast<ExifTag>(EXIF_TAG_GPS_LATITUDE_REF);
+    std::unique_ptr<ExifEntry> refEntry =
+            addVariableLengthEntry(EXIF_IFD_GPS, refTag, EXIF_FORMAT_ASCII, 2, 2);
+    if (!refEntry) {
+        ALOGE("%s: Adding GPSLatitudeRef exif entry failed", __FUNCTION__);
+        return false;
+    }
+    if (latitude >= 0) {
+        memcpy(refEntry->data, "N", sizeof("N"));
+    } else {
+        memcpy(refEntry->data, "S", sizeof("S"));
+        latitude *= -1;
+    }
+
+    const ExifTag tag = static_cast<ExifTag>(EXIF_TAG_GPS_LATITUDE);
+    std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(
+            EXIF_IFD_GPS, tag, EXIF_FORMAT_RATIONAL, 3, 3 * sizeof(ExifRational));
+    if (!entry) {
+        exif_content_remove_entry(exif_data_->ifd[EXIF_IFD_GPS], refEntry.get());
+        ALOGE("%s: Adding GPSLatitude exif entry failed", __FUNCTION__);
+        return false;
+    }
+    setLatitudeOrLongitudeData(entry->data, latitude);
+
+    return true;
+}
+
+bool ExifUtilsImpl::setGpsLongitude(double longitude) {
+    ExifTag refTag = static_cast<ExifTag>(EXIF_TAG_GPS_LONGITUDE_REF);
+    std::unique_ptr<ExifEntry> refEntry =
+            addVariableLengthEntry(EXIF_IFD_GPS, refTag, EXIF_FORMAT_ASCII, 2, 2);
+    if (!refEntry) {
+        ALOGE("%s: Adding GPSLongitudeRef exif entry failed", __FUNCTION__);
+        return false;
+    }
+    if (longitude >= 0) {
+        memcpy(refEntry->data, "E", sizeof("E"));
+    } else {
+        memcpy(refEntry->data, "W", sizeof("W"));
+        longitude *= -1;
+    }
+
+    ExifTag tag = static_cast<ExifTag>(EXIF_TAG_GPS_LONGITUDE);
+    std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(
+            EXIF_IFD_GPS, tag, EXIF_FORMAT_RATIONAL, 3, 3 * sizeof(ExifRational));
+    if (!entry) {
+        exif_content_remove_entry(exif_data_->ifd[EXIF_IFD_GPS], refEntry.get());
+        ALOGE("%s: Adding GPSLongitude exif entry failed", __FUNCTION__);
+        return false;
+    }
+    setLatitudeOrLongitudeData(entry->data, longitude);
+
+    return true;
+}
+
+bool ExifUtilsImpl::setGpsProcessingMethod(const std::string& method) {
+    std::string buffer =
+            std::string(gExifAsciiPrefix, sizeof(gExifAsciiPrefix)) + method;
+    SET_STRING(EXIF_IFD_GPS, static_cast<ExifTag>(EXIF_TAG_GPS_PROCESSING_METHOD),
+            EXIF_FORMAT_UNDEFINED, buffer);
+    return true;
+}
+
+bool ExifUtilsImpl::setGpsTimestamp(const struct tm& t) {
+    const ExifTag dateTag = static_cast<ExifTag>(EXIF_TAG_GPS_DATE_STAMP);
+    const size_t kGpsDateStampSize = 11;
+    std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(EXIF_IFD_GPS,
+            dateTag, EXIF_FORMAT_ASCII, kGpsDateStampSize, kGpsDateStampSize);
+    if (!entry) {
+        ALOGE("%s: Adding GPSDateStamp exif entry failed", __FUNCTION__);
+        return false;
+    }
+    int result = snprintf(reinterpret_cast<char*>(entry->data), kGpsDateStampSize,
+            "%04i:%02i:%02i", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday);
+    if (result != kGpsDateStampSize - 1) {
+        ALOGW("%s: Input time is invalid", __FUNCTION__);
+        return false;
+    }
+
+    const ExifTag timeTag = static_cast<ExifTag>(EXIF_TAG_GPS_TIME_STAMP);
+    entry = addVariableLengthEntry(EXIF_IFD_GPS, timeTag, EXIF_FORMAT_RATIONAL, 3,
+            3 * sizeof(ExifRational));
+    if (!entry) {
+        ALOGE("%s: Adding GPSTimeStamp exif entry failed", __FUNCTION__);
+        return false;
+    }
+    exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL,
+            {static_cast<ExifLong>(t.tm_hour), 1});
+    exif_set_rational(entry->data + sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL,
+            {static_cast<ExifLong>(t.tm_min), 1});
+    exif_set_rational(entry->data + 2 * sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL,
+            {static_cast<ExifLong>(t.tm_sec), 1});
+
+    return true;
+}
+
+bool ExifUtilsImpl::setImageHeight(uint32_t length) {
+    SET_SHORT(EXIF_IFD_0, EXIF_TAG_IMAGE_LENGTH, length);
+    SET_LONG(EXIF_IFD_EXIF, EXIF_TAG_PIXEL_Y_DIMENSION, length);
+    return true;
+}
+
+bool ExifUtilsImpl::setImageWidth(uint32_t width) {
+    SET_SHORT(EXIF_IFD_0, EXIF_TAG_IMAGE_WIDTH, width);
+    SET_LONG(EXIF_IFD_EXIF, EXIF_TAG_PIXEL_X_DIMENSION, width);
+    return true;
+}
+
+bool ExifUtilsImpl::setIsoSpeedRating(uint16_t iso_speed_ratings) {
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_ISO_SPEED_RATINGS, iso_speed_ratings);
+    return true;
+}
+
+bool ExifUtilsImpl::setMaxAperture(float aperture) {
+    float maxAperture = convertToApex(aperture);
+    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_MAX_APERTURE_VALUE,
+            static_cast<uint32_t>(std::round(maxAperture * kRationalPrecision)),
+            kRationalPrecision);
+    return true;
+}
+
+bool ExifUtilsImpl::setExposureBias(int32_t ev,
+        uint32_t ev_step_numerator, uint32_t ev_step_denominator) {
+    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_BIAS_VALUE,
+            ev * ev_step_numerator, ev_step_denominator);
+    return true;
+}
+
+bool ExifUtilsImpl::setOrientation(uint16_t degrees) {
+    ExifOrientation value = ExifOrientation::ORIENTATION_0_DEGREES;
+    switch (degrees) {
+        case 90:
+            value = ExifOrientation::ORIENTATION_90_DEGREES;
+            break;
+        case 180:
+            value = ExifOrientation::ORIENTATION_180_DEGREES;
+            break;
+        case 270:
+            value = ExifOrientation::ORIENTATION_270_DEGREES;
+            break;
+        default:
+            break;
+    }
+    return setOrientationValue(value);
+}
+
+bool ExifUtilsImpl::setOrientationValue(ExifOrientation orientationValue) {
+    SET_SHORT(EXIF_IFD_0, EXIF_TAG_ORIENTATION, orientationValue);
+    return true;
+}
+
+bool ExifUtilsImpl::setShutterSpeed(float exposure_time) {
+    float shutterSpeed = -log2f(exposure_time);
+    SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_SHUTTER_SPEED_VALUE,
+            static_cast<uint32_t>(shutterSpeed * kRationalPrecision), kRationalPrecision);
+    return true;
+}
+
+bool ExifUtilsImpl::setSubjectDistance(float diopters) {
+    const static float kInfinityDiopters = 1.0e-6;
+    uint32_t numerator, denominator;
+    uint16_t distanceRange;
+    if (diopters > kInfinityDiopters) {
+        float focusDistance = 1.0f / diopters;
+        numerator = static_cast<uint32_t>(std::round(focusDistance * kRationalPrecision));
+        denominator = kRationalPrecision;
+
+        if (focusDistance < 1.0f) {
+            distanceRange = 1; // Macro
+        } else if (focusDistance < 3.0f) {
+            distanceRange = 2; // Close
+        } else {
+            distanceRange = 3; // Distant
+        }
+    } else {
+        numerator = 0xFFFFFFFF;
+        denominator = 1;
+        distanceRange = 3; // Distant
+    }
+    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_SUBJECT_DISTANCE, numerator, denominator);
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SUBJECT_DISTANCE_RANGE, distanceRange);
+    return true;
+}
+
+bool ExifUtilsImpl::setSubsecTime(const std::string& subsec_time) {
+    SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_SUB_SEC_TIME, EXIF_FORMAT_ASCII, subsec_time);
+    SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_SUB_SEC_TIME_ORIGINAL, EXIF_FORMAT_ASCII, subsec_time);
+    SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_SUB_SEC_TIME_DIGITIZED, EXIF_FORMAT_ASCII, subsec_time);
+    return true;
+}
+
+bool ExifUtilsImpl::setWhiteBalance(uint8_t white_balance) {
+    uint16_t whiteBalance = (white_balance == ANDROID_CONTROL_AWB_MODE_AUTO) ? 0 : 1;
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_WHITE_BALANCE, whiteBalance);
+    return true;
+}
+
+bool ExifUtilsImpl::generateApp1() {
+    destroyApp1();
+    // Save the result into |app1_buffer_|.
+    exif_data_save_data(exif_data_, &app1_buffer_, &app1_length_);
+    if (!app1_length_) {
+        ALOGE("%s: Allocate memory for app1_buffer_ failed", __FUNCTION__);
+        return false;
+    }
+    /*
+     * The JPEG segment size is 16 bits in spec. The size of APP1 segment should
+     * be smaller than 65533 because there are two bytes for segment size field.
+     */
+    if (app1_length_ > 65533) {
+        destroyApp1();
+        ALOGE("%s: The size of APP1 segment is too large", __FUNCTION__);
+        return false;
+    }
+    return true;
+}
+
+const uint8_t* ExifUtilsImpl::getApp1Buffer() {
+    return app1_buffer_;
+}
+
+unsigned int ExifUtilsImpl::getApp1Length() {
+    return app1_length_;
+}
+
+bool ExifUtilsImpl::setExifVersion(const std::string& exif_version) {
+    SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_EXIF_VERSION, EXIF_FORMAT_UNDEFINED, exif_version);
+    return true;
+}
+
+void ExifUtilsImpl::reset() {
+    destroyApp1();
+    if (exif_data_) {
+        /*
+         * Since we decided to ignore the original APP1, we are sure that there is
+         * no thumbnail allocated by libexif. |exif_data_->data| is actually
+         * allocated by JpegCompressor. sets |exif_data_->data| to nullptr to
+         * prevent exif_data_unref() destroy it incorrectly.
+         */
+        exif_data_->data = nullptr;
+        exif_data_->size = 0;
+        exif_data_unref(exif_data_);
+        exif_data_ = nullptr;
+    }
+}
+
+std::unique_ptr<ExifEntry> ExifUtilsImpl::addVariableLengthEntry(ExifIfd ifd,
+        ExifTag tag, ExifFormat format, uint64_t components, unsigned int size) {
+    // Remove old entry if exists.
+    exif_content_remove_entry(exif_data_->ifd[ifd],
+            exif_content_get_entry(exif_data_->ifd[ifd], tag));
+    ExifMem* mem = exif_mem_new_default();
+    if (!mem) {
+        ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
+        return nullptr;
+    }
+    std::unique_ptr<ExifEntry> entry(exif_entry_new_mem(mem));
+    if (!entry) {
+        ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
+        exif_mem_unref(mem);
+        return nullptr;
+    }
+    void* tmpBuffer = exif_mem_alloc(mem, size);
+    if (!tmpBuffer) {
+        ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
+        exif_mem_unref(mem);
+        return nullptr;
+    }
+
+    entry->data = static_cast<unsigned char*>(tmpBuffer);
+    entry->tag = tag;
+    entry->format = format;
+    entry->components = components;
+    entry->size = size;
+
+    exif_content_add_entry(exif_data_->ifd[ifd], entry.get());
+    exif_mem_unref(mem);
+
+    return entry;
+}
+
+std::unique_ptr<ExifEntry> ExifUtilsImpl::addEntry(ExifIfd ifd, ExifTag tag) {
+    std::unique_ptr<ExifEntry> entry(exif_content_get_entry(exif_data_->ifd[ifd], tag));
+    if (entry) {
+        // exif_content_get_entry() won't ref the entry, so we ref here.
+        exif_entry_ref(entry.get());
+        return entry;
+    }
+    entry.reset(exif_entry_new());
+    if (!entry) {
+        ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
+        return nullptr;
+    }
+    entry->tag = tag;
+    exif_content_add_entry(exif_data_->ifd[ifd], entry.get());
+    exif_entry_initialize(entry.get(), tag);
+    return entry;
+}
+
+bool ExifUtilsImpl::setShort(ExifIfd ifd, ExifTag tag, uint16_t value, const std::string& msg) {
+    std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
+    if (!entry) {
+        ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
+        return false;
+    }
+    exif_set_short(entry->data, EXIF_BYTE_ORDER_INTEL, value);
+    return true;
+}
+
+bool ExifUtilsImpl::setLong(ExifIfd ifd, ExifTag tag, uint32_t value, const std::string& msg) {
+    std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
+    if (!entry) {
+        ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
+        return false;
+    }
+    exif_set_long(entry->data, EXIF_BYTE_ORDER_INTEL, value);
+    return true;
+}
+
+bool ExifUtilsImpl::setRational(ExifIfd ifd, ExifTag tag, uint32_t numerator,
+        uint32_t denominator, const std::string& msg) {
+    std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
+    if (!entry) {
+        ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
+        return false;
+    }
+    exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL, {numerator, denominator});
+    return true;
+}
+
+bool ExifUtilsImpl::setSRational(ExifIfd ifd, ExifTag tag, int32_t numerator,
+        int32_t denominator, const std::string& msg) {
+    std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
+    if (!entry) {
+        ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
+        return false;
+    }
+    exif_set_srational(entry->data, EXIF_BYTE_ORDER_INTEL, {numerator, denominator});
+    return true;
+}
+
+bool ExifUtilsImpl::setString(ExifIfd ifd, ExifTag tag, ExifFormat format,
+        const std::string& buffer, const std::string& msg) {
+    size_t entry_size = buffer.length();
+    // Since the exif format is undefined, NULL termination is not necessary.
+    if (format == EXIF_FORMAT_ASCII) {
+        entry_size++;
+    }
+    std::unique_ptr<ExifEntry> entry =
+            addVariableLengthEntry(ifd, tag, format, entry_size, entry_size);
+    if (!entry) {
+        ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
+        return false;
+    }
+    memcpy(entry->data, buffer.c_str(), entry_size);
+    return true;
+}
+
+void ExifUtilsImpl::destroyApp1() {
+    /*
+     * Since there is no API to access ExifMem in ExifData->priv, we use free
+     * here, which is the default free function in libexif. See
+     * exif_data_save_data() for detail.
+     */
+    free(app1_buffer_);
+    app1_buffer_ = nullptr;
+    app1_length_ = 0;
+}
+
+bool ExifUtilsImpl::setFromMetadata(const CameraMetadata& metadata,
+        const CameraMetadata& staticInfo,
+        const size_t imageWidth, const size_t imageHeight) {
+    if (!setImageWidth(imageWidth) ||
+            !setImageHeight(imageHeight)) {
+        ALOGE("%s: setting image resolution failed.", __FUNCTION__);
+        return false;
+    }
+
+    struct timespec tp;
+    struct tm time_info;
+    bool time_available = clock_gettime(CLOCK_REALTIME, &tp) != -1;
+    localtime_r(&tp.tv_sec, &time_info);
+    if (!setDateTime(time_info)) {
+        ALOGE("%s: setting data time failed.", __FUNCTION__);
+        return false;
+    }
+
+    float focal_length;
+    camera_metadata_ro_entry entry = metadata.find(ANDROID_LENS_FOCAL_LENGTH);
+    if (entry.count) {
+        focal_length = entry.data.f[0];
+
+        if (!setFocalLength(focal_length)) {
+            ALOGE("%s: setting focal length failed.", __FUNCTION__);
+            return false;
+        }
+
+        camera_metadata_ro_entry sensorSizeEntry =
+                staticInfo.find(ANDROID_SENSOR_INFO_PHYSICAL_SIZE);
+        if (sensorSizeEntry.count == 2) {
+            if (!setFocalLengthIn35mmFilm(
+                    focal_length, sensorSizeEntry.data.f[0], sensorSizeEntry.data.f[1])) {
+                ALOGE("%s: setting focal length in 35mm failed.", __FUNCTION__);
+                return false;
+            }
+        }
+    } else {
+        ALOGV("%s: Cannot find focal length in metadata.", __FUNCTION__);
+    }
+
+    if (metadata.exists(ANDROID_SCALER_CROP_REGION) &&
+            staticInfo.exists(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE)) {
+        entry = metadata.find(ANDROID_SCALER_CROP_REGION);
+        camera_metadata_ro_entry activeArrayEntry =
+                staticInfo.find(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE);
+
+        if (!setDigitalZoomRatio(entry.data.i32[2], entry.data.i32[3],
+                activeArrayEntry.data.i32[2], activeArrayEntry.data.i32[3])) {
+            ALOGE("%s: setting digital zoom ratio failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
+    if (metadata.exists(ANDROID_JPEG_GPS_COORDINATES)) {
+        entry = metadata.find(ANDROID_JPEG_GPS_COORDINATES);
+        if (entry.count < 3) {
+            ALOGE("%s: Gps coordinates in metadata is not complete.", __FUNCTION__);
+            return false;
+        }
+        if (!setGpsLatitude(entry.data.d[0])) {
+            ALOGE("%s: setting gps latitude failed.", __FUNCTION__);
+            return false;
+        }
+        if (!setGpsLongitude(entry.data.d[1])) {
+            ALOGE("%s: setting gps longitude failed.", __FUNCTION__);
+            return false;
+        }
+        if (!setGpsAltitude(entry.data.d[2])) {
+            ALOGE("%s: setting gps altitude failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
+    if (metadata.exists(ANDROID_JPEG_GPS_PROCESSING_METHOD)) {
+        entry = metadata.find(ANDROID_JPEG_GPS_PROCESSING_METHOD);
+        std::string method_str(reinterpret_cast<const char*>(entry.data.u8));
+        if (!setGpsProcessingMethod(method_str)) {
+            ALOGE("%s: setting gps processing method failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
+    if (time_available && metadata.exists(ANDROID_JPEG_GPS_TIMESTAMP)) {
+        entry = metadata.find(ANDROID_JPEG_GPS_TIMESTAMP);
+        time_t timestamp = static_cast<time_t>(entry.data.i64[0]);
+        if (gmtime_r(&timestamp, &time_info)) {
+            if (!setGpsTimestamp(time_info)) {
+                ALOGE("%s: setting gps timestamp failed.", __FUNCTION__);
+                return false;
+            }
+        } else {
+            ALOGE("%s: Time tranformation failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
+    if (staticInfo.exists(ANDROID_CONTROL_AE_COMPENSATION_STEP) &&
+            metadata.exists(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION)) {
+        entry = metadata.find(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION);
+        camera_metadata_ro_entry stepEntry =
+                staticInfo.find(ANDROID_CONTROL_AE_COMPENSATION_STEP);
+        if (!setExposureBias(entry.data.i32[0], stepEntry.data.r[0].numerator,
+                stepEntry.data.r[0].denominator)) {
+            ALOGE("%s: setting exposure bias failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
+    if (metadata.exists(ANDROID_JPEG_ORIENTATION)) {
+        entry = metadata.find(ANDROID_JPEG_ORIENTATION);
+        if (!setOrientation(entry.data.i32[0])) {
+            ALOGE("%s: setting orientation failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
+    if (metadata.exists(ANDROID_SENSOR_EXPOSURE_TIME)) {
+        entry = metadata.find(ANDROID_SENSOR_EXPOSURE_TIME);
+        float exposure_time = 1.0f * entry.data.i64[0] / 1e9;
+        if (!setExposureTime(exposure_time)) {
+            ALOGE("%s: setting exposure time failed.", __FUNCTION__);
+            return false;
+        }
+
+        if (!setShutterSpeed(exposure_time)) {
+            ALOGE("%s: setting shutter speed failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
+    if (metadata.exists(ANDROID_LENS_FOCUS_DISTANCE)) {
+        entry = metadata.find(ANDROID_LENS_FOCUS_DISTANCE);
+        if (!setSubjectDistance(entry.data.f[0])) {
+            ALOGE("%s: setting subject distance failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
+    if (metadata.exists(ANDROID_SENSOR_SENSITIVITY)) {
+        entry = metadata.find(ANDROID_SENSOR_SENSITIVITY);
+        int32_t iso = entry.data.i32[0];
+        camera_metadata_ro_entry postRawSensEntry =
+                metadata.find(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST);
+        if (postRawSensEntry.count > 0) {
+            iso = iso * postRawSensEntry.data.i32[0] / 100;
+        }
+
+        if (!setIsoSpeedRating(static_cast<uint16_t>(iso))) {
+            ALOGE("%s: setting iso rating failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
+    if (metadata.exists(ANDROID_LENS_APERTURE)) {
+        entry = metadata.find(ANDROID_LENS_APERTURE);
+        if (!setFNumber(entry.data.f[0])) {
+            ALOGE("%s: setting F number failed.", __FUNCTION__);
+            return false;
+        }
+        if (!setAperture(entry.data.f[0])) {
+            ALOGE("%s: setting aperture failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
+    static const uint16_t kSRGBColorSpace = 1;
+    if (!setColorSpace(kSRGBColorSpace)) {
+        ALOGE("%s: setting color space failed.", __FUNCTION__);
+        return false;
+    }
+
+    if (staticInfo.exists(ANDROID_LENS_INFO_AVAILABLE_APERTURES)) {
+        entry = staticInfo.find(ANDROID_LENS_INFO_AVAILABLE_APERTURES);
+        if (!setMaxAperture(entry.data.f[0])) {
+            ALOGE("%s: setting max aperture failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
+    if (staticInfo.exists(ANDROID_FLASH_INFO_AVAILABLE)) {
+        entry = staticInfo.find(ANDROID_FLASH_INFO_AVAILABLE);
+        camera_metadata_ro_entry flashStateEntry = metadata.find(ANDROID_FLASH_STATE);
+        camera_metadata_ro_entry aeModeEntry = metadata.find(ANDROID_CONTROL_AE_MODE);
+        uint8_t flashState = flashStateEntry.count > 0 ?
+                flashStateEntry.data.u8[0] : ANDROID_FLASH_STATE_UNAVAILABLE;
+        uint8_t aeMode = aeModeEntry.count > 0 ?
+                aeModeEntry.data.u8[0] : ANDROID_CONTROL_AE_MODE_OFF;
+
+        if (!setFlash(entry.data.u8[0], flashState, aeMode)) {
+            ALOGE("%s: setting flash failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
+    if (metadata.exists(ANDROID_CONTROL_AWB_MODE)) {
+        entry = metadata.find(ANDROID_CONTROL_AWB_MODE);
+        if (!setWhiteBalance(entry.data.u8[0])) {
+            ALOGE("%s: setting white balance failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
+    if (metadata.exists(ANDROID_CONTROL_AE_MODE)) {
+        entry = metadata.find(ANDROID_CONTROL_AE_MODE);
+        if (!setExposureMode(entry.data.u8[0])) {
+            ALOGE("%s: setting exposure mode failed.", __FUNCTION__);
+            return false;
+        }
+    }
+    if (time_available) {
+        char str[4];
+        if (snprintf(str, sizeof(str), "%03ld", tp.tv_nsec / 1000000) < 0) {
+            ALOGE("%s: Subsec is invalid: %ld", __FUNCTION__, tp.tv_nsec);
+            return false;
+        }
+        if (!setSubsecTime(std::string(str))) {
+            ALOGE("%s: setting subsec time failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
+    return true;
+}
+
+} // namespace camera3
+} // namespace android
diff --git a/services/camera/libcameraservice/utils/ExifUtils.h b/services/camera/libcameraservice/utils/ExifUtils.h
new file mode 100644
index 0000000..f1d0205
--- /dev/null
+++ b/services/camera/libcameraservice/utils/ExifUtils.h
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SERVERS_CAMERA_EXIF_UTILS_H
+#define ANDROID_SERVERS_CAMERA_EXIF_UTILS_H
+
+#include "CameraMetadata.h"
+
+namespace android {
+namespace camera3 {
+
+/*
+ * Orientation value:
+ *  1      2      3      4      5          6          7          8
+ *
+ *  888888 888888     88 88     8888888888 88                 88 8888888888
+ *  88         88     88 88     88  88     88  88         88  88     88  88
+ *  8888     8888   8888 8888   88         8888888888 8888888888         88
+ *  88         88     88 88
+ *  88         88 888888 888888
+ */
+enum ExifOrientation : uint16_t {
+    ORIENTATION_UNDEFINED   = 0x0,
+    ORIENTATION_0_DEGREES   = 0x1,
+    ORIENTATION_90_DEGREES  = 0x6,
+    ORIENTATION_180_DEGREES = 0x3,
+    ORIENTATION_270_DEGREES = 0x8,
+};
+
+// This is based on the camera HIDL shim implementation, which was in turned
+// based on original ChromeOS ARC implementation of a V4L2 HAL
+
+// ExifUtils can override APP1 segment with tags which caller set. ExifUtils can
+// also add a thumbnail in the APP1 segment if thumbnail size is specified.
+// ExifUtils can be reused with different images by calling initialize().
+//
+// Example of using this class :
+//  std::unique_ptr<ExifUtils> utils(ExifUtils::Create());
+//  utils->initialize(const unsigned char* app1Segment, size_t app1SegmentSize);
+//  ...
+//  // Call ExifUtils functions to set Exif tags.
+//  ...
+//  utils->GenerateApp1();
+//  unsigned int app1Length = utils->GetApp1Length();
+//  uint8_t* app1Buffer = new uint8_t[app1Length];
+//  memcpy(app1Buffer, utils->GetApp1Buffer(), app1Length);
+class ExifUtils {
+
+public:
+    virtual ~ExifUtils();
+
+    static ExifUtils* create();
+
+    // Initialize() can be called multiple times. The setting of Exif tags will be
+    // cleared.
+    virtual bool initialize(const unsigned char *app1Segment, size_t app1SegmentSize) = 0;
+    virtual bool initializeEmpty() = 0;
+
+    // Set all known fields from a metadata structure
+    virtual bool setFromMetadata(const CameraMetadata& metadata,
+            const CameraMetadata& staticInfo,
+            const size_t imageWidth, const size_t imageHeight) = 0;
+
+    // Sets the len aperture.
+    // Returns false if memory allocation fails.
+    virtual bool setAperture(float aperture) = 0;
+
+    // sets the color space.
+    // Returns false if memory allocation fails.
+    virtual bool setColorSpace(uint16_t color_space) = 0;
+
+    // Sets the date and time of image last modified. It takes local time. The
+    // name of the tag is DateTime in IFD0.
+    // Returns false if memory allocation fails.
+    virtual bool setDateTime(const struct tm& t) = 0;
+
+    // Sets the digital zoom ratio. If the numerator is 0, it means digital zoom
+    // was not used.
+    // Returns false if memory allocation fails.
+    virtual bool setDigitalZoomRatio(uint32_t crop_width, uint32_t crop_height,
+            uint32_t sensor_width, uint32_t sensor_height) = 0;
+
+    // Sets the exposure bias.
+    // Returns false if memory allocation fails.
+    virtual bool setExposureBias(int32_t ev,
+            uint32_t ev_step_numerator, uint32_t ev_step_denominator) = 0;
+
+    // Sets the exposure mode set when the image was shot.
+    // Returns false if memory allocation fails.
+    virtual bool setExposureMode(uint8_t exposure_mode) = 0;
+
+    // Sets the exposure time, given in seconds.
+    // Returns false if memory allocation fails.
+    virtual bool setExposureTime(float exposure_time) = 0;
+
+    // Sets the status of flash.
+    // Returns false if memory allocation fails.
+    virtual bool setFlash(uint8_t flash_available, uint8_t flash_state, uint8_t ae_mode) = 0;
+
+    // Sets the F number.
+    // Returns false if memory allocation fails.
+    virtual bool setFNumber(float f_number) = 0;
+
+    // Sets the focal length of lens used to take the image in millimeters.
+    // Returns false if memory allocation fails.
+    virtual bool setFocalLength(float focal_length) = 0;
+
+    // Sets the focal length of lens for 35mm film used to take the image in millimeters.
+    // Returns false if memory allocation fails.
+    virtual bool setFocalLengthIn35mmFilm(float focal_length,
+            float sensor_size_x, float sensor_size_y) = 0;
+
+    // Sets the altitude in meters.
+    // Returns false if memory allocation fails.
+    virtual bool setGpsAltitude(double altitude) = 0;
+
+    // Sets the latitude with degrees minutes seconds format.
+    // Returns false if memory allocation fails.
+    virtual bool setGpsLatitude(double latitude) = 0;
+
+    // Sets the longitude with degrees minutes seconds format.
+    // Returns false if memory allocation fails.
+    virtual bool setGpsLongitude(double longitude) = 0;
+
+    // Sets GPS processing method.
+    // Returns false if memory allocation fails.
+    virtual bool setGpsProcessingMethod(const std::string& method) = 0;
+
+    // Sets GPS date stamp and time stamp (atomic clock). It takes UTC time.
+    // Returns false if memory allocation fails.
+    virtual bool setGpsTimestamp(const struct tm& t) = 0;
+
+    // Sets the height (number of rows) of main image.
+    // Returns false if memory allocation fails.
+    virtual bool setImageHeight(uint32_t length) = 0;
+
+    // Sets the width (number of columns) of main image.
+    // Returns false if memory allocation fails.
+    virtual bool setImageWidth(uint32_t width) = 0;
+
+    // Sets the ISO speed.
+    // Returns false if memory allocation fails.
+    virtual bool setIsoSpeedRating(uint16_t iso_speed_ratings) = 0;
+
+    // Sets the smallest F number of the lens.
+    // Returns false if memory allocation fails.
+    virtual bool setMaxAperture(float aperture) = 0;
+
+    // Sets image orientation.
+    // Returns false if memory allocation fails.
+    virtual bool setOrientation(uint16_t degrees) = 0;
+
+    // Sets image orientation.
+    // Returns false if memory allocation fails.
+    virtual bool setOrientationValue(ExifOrientation orientationValue) = 0;
+
+    // Sets the shutter speed.
+    // Returns false if memory allocation fails.
+    virtual bool setShutterSpeed(float exposure_time) = 0;
+
+    // Sets the distance to the subject, given in meters.
+    // Returns false if memory allocation fails.
+    virtual bool setSubjectDistance(float diopters) = 0;
+
+    // Sets the fractions of seconds for the <DateTime> tag.
+    // Returns false if memory allocation fails.
+    virtual bool setSubsecTime(const std::string& subsec_time) = 0;
+
+    // Sets the white balance mode set when the image was shot.
+    // Returns false if memory allocation fails.
+    virtual bool setWhiteBalance(uint8_t white_blanace) = 0;
+
+    // Generates APP1 segment.
+    // Returns false if generating APP1 segment fails.
+    virtual bool generateApp1() = 0;
+
+    // Gets buffer of APP1 segment. This method must be called only after calling
+    // GenerateAPP1().
+    virtual const uint8_t* getApp1Buffer() = 0;
+
+    // Gets length of APP1 segment. This method must be called only after calling
+    // GenerateAPP1().
+    virtual unsigned int getApp1Length() = 0;
+};
+
+} // namespace camera3
+} // namespace android
+
+#endif  // ANDROID_SERVERS_CAMERA_EXIF_UTILS_H
diff --git a/services/camera/libcameraservice/utils/LatencyHistogram.cpp b/services/camera/libcameraservice/utils/LatencyHistogram.cpp
index 538bb6e..e2bdc43 100644
--- a/services/camera/libcameraservice/utils/LatencyHistogram.cpp
+++ b/services/camera/libcameraservice/utils/LatencyHistogram.cpp
@@ -46,7 +46,7 @@
 }
 
 void CameraLatencyHistogram::reset() {
-    mBins.clear();
+    memset(mBins.data(), 0, mBins.size() * sizeof(int64_t));
     mTotalCount = 0;
 }
 
diff --git a/services/camera/libcameraservice/utils/TagMonitor.cpp b/services/camera/libcameraservice/utils/TagMonitor.cpp
index c0a353f..4037a66 100644
--- a/services/camera/libcameraservice/utils/TagMonitor.cpp
+++ b/services/camera/libcameraservice/utils/TagMonitor.cpp
@@ -49,7 +49,8 @@
     std::lock_guard<std::mutex> lock(mMonitorMutex);
 
     // Expand shorthands
-    if (ssize_t idx = tagNames.find("3a") != -1) {
+    ssize_t idx = tagNames.find("3a");
+    if (idx != -1) {
         ssize_t end = tagNames.find(",", idx);
         char* start = tagNames.lockBuffer(tagNames.size());
         start[idx] = '\0';
@@ -99,10 +100,13 @@
     mMonitoringEnabled = false;
     mLastMonitoredRequestValues.clear();
     mLastMonitoredResultValues.clear();
+    mLastMonitoredPhysicalRequestKeys.clear();
+    mLastMonitoredPhysicalResultKeys.clear();
 }
 
 void TagMonitor::monitorMetadata(eventSource source, int64_t frameNumber, nsecs_t timestamp,
-        const CameraMetadata& metadata) {
+        const CameraMetadata& metadata,
+        const std::unordered_map<std::string, CameraMetadata>& physicalMetadata) {
     if (!mMonitoringEnabled) return;
 
     std::lock_guard<std::mutex> lock(mMonitorMutex);
@@ -111,62 +115,77 @@
         timestamp = systemTime(SYSTEM_TIME_BOOTTIME);
     }
 
+    std::string emptyId;
     for (auto tag : mMonitoredTagList) {
-        camera_metadata_ro_entry entry = metadata.find(tag);
-        CameraMetadata &lastValues = (source == REQUEST) ?
-                mLastMonitoredRequestValues : mLastMonitoredResultValues;
-        if (lastValues.isEmpty()) {
-            lastValues = CameraMetadata(mMonitoredTagList.size());
-            const camera_metadata_t *metaBuffer =
-                    lastValues.getAndLock();
-            set_camera_metadata_vendor_id(
-                    const_cast<camera_metadata_t *> (metaBuffer), mVendorTagId);
-            lastValues.unlock(metaBuffer);
+        monitorSingleMetadata(source, frameNumber, timestamp, emptyId, tag, metadata);
+
+        for (auto& m : physicalMetadata) {
+            monitorSingleMetadata(source, frameNumber, timestamp, m.first, tag, m.second);
         }
+    }
+}
 
-        camera_metadata_entry lastEntry = lastValues.find(tag);
+void TagMonitor::monitorSingleMetadata(eventSource source, int64_t frameNumber, nsecs_t timestamp,
+        const std::string& cameraId, uint32_t tag, const CameraMetadata& metadata) {
 
-        if (entry.count > 0) {
-            bool isDifferent = false;
-            if (lastEntry.count > 0) {
-                // Have a last value, compare to see if changed
-                if (lastEntry.type == entry.type &&
-                        lastEntry.count == entry.count) {
-                    // Same type and count, compare values
-                    size_t bytesPerValue = camera_metadata_type_size[lastEntry.type];
-                    size_t entryBytes = bytesPerValue * lastEntry.count;
-                    int cmp = memcmp(entry.data.u8, lastEntry.data.u8, entryBytes);
-                    if (cmp != 0) {
-                        isDifferent = true;
-                    }
-                } else {
-                    // Count or type has changed
+    CameraMetadata &lastValues = (source == REQUEST) ?
+            (cameraId.empty() ? mLastMonitoredRequestValues :
+                    mLastMonitoredPhysicalRequestKeys[cameraId]) :
+            (cameraId.empty() ? mLastMonitoredResultValues :
+                    mLastMonitoredPhysicalResultKeys[cameraId]);
+
+    camera_metadata_ro_entry entry = metadata.find(tag);
+    if (lastValues.isEmpty()) {
+        lastValues = CameraMetadata(mMonitoredTagList.size());
+        const camera_metadata_t *metaBuffer =
+                lastValues.getAndLock();
+        set_camera_metadata_vendor_id(
+                const_cast<camera_metadata_t *> (metaBuffer), mVendorTagId);
+        lastValues.unlock(metaBuffer);
+    }
+
+    camera_metadata_entry lastEntry = lastValues.find(tag);
+
+    if (entry.count > 0) {
+        bool isDifferent = false;
+        if (lastEntry.count > 0) {
+            // Have a last value, compare to see if changed
+            if (lastEntry.type == entry.type &&
+                    lastEntry.count == entry.count) {
+                // Same type and count, compare values
+                size_t bytesPerValue = camera_metadata_type_size[lastEntry.type];
+                size_t entryBytes = bytesPerValue * lastEntry.count;
+                int cmp = memcmp(entry.data.u8, lastEntry.data.u8, entryBytes);
+                if (cmp != 0) {
                     isDifferent = true;
                 }
             } else {
-                // No last entry, so always consider to be different
+                // Count or type has changed
                 isDifferent = true;
             }
+        } else {
+            // No last entry, so always consider to be different
+            isDifferent = true;
+        }
 
-            if (isDifferent) {
-                ALOGV("%s: Tag %s changed", __FUNCTION__,
-                      get_local_camera_metadata_tag_name_vendor_id(
-                              tag, mVendorTagId));
-                lastValues.update(entry);
-                mMonitoringEvents.emplace(source, frameNumber, timestamp, entry);
-            }
-        } else if (lastEntry.count > 0) {
-            // Value has been removed
-            ALOGV("%s: Tag %s removed", __FUNCTION__,
+        if (isDifferent) {
+            ALOGV("%s: Tag %s changed", __FUNCTION__,
                   get_local_camera_metadata_tag_name_vendor_id(
                           tag, mVendorTagId));
-            lastValues.erase(tag);
-            entry.tag = tag;
-            entry.type = get_local_camera_metadata_tag_type_vendor_id(tag,
-                    mVendorTagId);
-            entry.count = 0;
-            mMonitoringEvents.emplace(source, frameNumber, timestamp, entry);
+            lastValues.update(entry);
+            mMonitoringEvents.emplace(source, frameNumber, timestamp, entry, cameraId);
         }
+    } else if (lastEntry.count > 0) {
+        // Value has been removed
+        ALOGV("%s: Tag %s removed", __FUNCTION__,
+              get_local_camera_metadata_tag_name_vendor_id(
+                      tag, mVendorTagId));
+        lastValues.erase(tag);
+        entry.tag = tag;
+        entry.type = get_local_camera_metadata_tag_type_vendor_id(tag,
+                mVendorTagId);
+        entry.count = 0;
+        mMonitoringEvents.emplace(source, frameNumber, timestamp, entry, cameraId);
     }
 }
 
@@ -189,8 +208,9 @@
         dprintf(fd, "     Monitored tag event log:\n");
         for (const auto& event : mMonitoringEvents) {
             int indentation = (event.source == REQUEST) ? 15 : 30;
-            dprintf(fd, "        f%d:%" PRId64 "ns: %*s%s.%s: ",
+            dprintf(fd, "        f%d:%" PRId64 "ns:%*s%*s%s.%s: ",
                     event.frameNumber, event.timestamp,
+                    2, event.cameraId.c_str(),
                     indentation,
                     event.source == REQUEST ? "REQ:" : "RES:",
                     get_local_camera_metadata_section_name_vendor_id(event.tag,
@@ -295,13 +315,14 @@
 
 template<typename T>
 TagMonitor::MonitorEvent::MonitorEvent(eventSource src, uint32_t frameNumber, nsecs_t timestamp,
-        const T &value) :
+        const T &value, const std::string& cameraId) :
         source(src),
         frameNumber(frameNumber),
         timestamp(timestamp),
         tag(value.tag),
         type(value.type),
-        newData(value.data.u8, value.data.u8 + camera_metadata_type_size[value.type] * value.count) {
+        newData(value.data.u8, value.data.u8 + camera_metadata_type_size[value.type] * value.count),
+        cameraId(cameraId) {
 }
 
 TagMonitor::MonitorEvent::~MonitorEvent() {
diff --git a/services/camera/libcameraservice/utils/TagMonitor.h b/services/camera/libcameraservice/utils/TagMonitor.h
index 2dece62..1b7b033 100644
--- a/services/camera/libcameraservice/utils/TagMonitor.h
+++ b/services/camera/libcameraservice/utils/TagMonitor.h
@@ -20,6 +20,7 @@
 #include <vector>
 #include <atomic>
 #include <mutex>
+#include <unordered_map>
 
 #include <utils/RefBase.h>
 #include <utils/String8.h>
@@ -62,7 +63,8 @@
 
     // Scan through the metadata and update the monitoring information
     void monitorMetadata(eventSource source, int64_t frameNumber,
-            nsecs_t timestamp, const CameraMetadata& metadata);
+            nsecs_t timestamp, const CameraMetadata& metadata,
+            const std::unordered_map<std::string, CameraMetadata>& physicalMetadata);
 
     // Dump current event log to the provided fd
     void dumpMonitoredMetadata(int fd);
@@ -72,6 +74,10 @@
     static void printData(int fd, const uint8_t *data_ptr, uint32_t tag,
             int type, int count, int indentation);
 
+    void monitorSingleMetadata(TagMonitor::eventSource source, int64_t frameNumber,
+            nsecs_t timestamp, const std::string& cameraId, uint32_t tag,
+            const CameraMetadata& metadata);
+
     std::atomic<bool> mMonitoringEnabled;
     std::mutex mMonitorMutex;
 
@@ -82,6 +88,9 @@
     CameraMetadata mLastMonitoredRequestValues;
     CameraMetadata mLastMonitoredResultValues;
 
+    std::unordered_map<std::string, CameraMetadata> mLastMonitoredPhysicalRequestKeys;
+    std::unordered_map<std::string, CameraMetadata> mLastMonitoredPhysicalResultKeys;
+
     /**
      * A monitoring event
      * Stores a new metadata field value and the timestamp at which it changed.
@@ -90,7 +99,7 @@
     struct MonitorEvent {
         template<typename T>
         MonitorEvent(eventSource src, uint32_t frameNumber, nsecs_t timestamp,
-                const T &newValue);
+                const T &newValue, const std::string& cameraId);
         ~MonitorEvent();
 
         eventSource source;
@@ -99,6 +108,7 @@
         uint32_t tag;
         uint8_t type;
         std::vector<uint8_t> newData;
+        std::string cameraId;
     };
 
     // A ring buffer for tracking the last kMaxMonitorEvents metadata changes
diff --git a/services/mediaanalytics/Android.bp b/services/mediaanalytics/Android.bp
new file mode 100644
index 0000000..72f4b52
--- /dev/null
+++ b/services/mediaanalytics/Android.bp
@@ -0,0 +1,68 @@
+// Media Statistics service
+//
+
+cc_binary {
+    name: "mediametrics",
+
+    srcs: [
+        "main_mediametrics.cpp",
+        "MediaAnalyticsService.cpp",
+        "iface_statsd.cpp",
+        "statsd_audiopolicy.cpp",
+        "statsd_audiorecord.cpp",
+        "statsd_audiothread.cpp",
+        "statsd_audiotrack.cpp",
+        "statsd_codec.cpp",
+        "statsd_drm.cpp",
+        "statsd_extractor.cpp",
+        "statsd_nuplayer.cpp",
+        "statsd_recorder.cpp",
+    ],
+
+    proto: {
+        type: "lite",
+    },
+
+    shared_libs: [
+        "libcutils",
+        "liblog",
+        "libmedia",
+        "libutils",
+        "libbinder",
+        "libdl",
+        "libgui",
+        "libmedia",
+        "libmediautils",
+        "libmediametrics",
+        "libstagefright_foundation",
+        "libstatslog",
+        "libutils",
+        "libprotobuf-cpp-lite",
+    ],
+
+    static_libs: [
+        "libplatformprotos",
+        "libregistermsext",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/libstagefright/include",
+        "frameworks/av/media/libstagefright/rtsp",
+        "frameworks/av/media/libstagefright/webm",
+        "frameworks/av/include/media",
+        "frameworks/av/include/camera",
+        "frameworks/native/include/media/openmax",
+        "frameworks/native/include/media/hardware",
+        "external/tremolo/Tremolo",
+    ],
+
+    init_rc: ["mediametrics.rc"],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+        "-Wno-error=deprecated-declarations",
+    ],
+    clang: true,
+
+}
diff --git a/services/mediaanalytics/Android.mk b/services/mediaanalytics/Android.mk
deleted file mode 100644
index 2eeb7fa..0000000
--- a/services/mediaanalytics/Android.mk
+++ /dev/null
@@ -1,48 +0,0 @@
-# Media Statistics service
-#
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-    main_mediametrics.cpp              \
-    MediaAnalyticsService.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-    libcutils                   \
-    liblog                      \
-    libmedia                    \
-    libutils                    \
-    libbinder                   \
-    libdl                       \
-    libgui                      \
-    libmedia                    \
-    libmediautils               \
-    libmediametrics             \
-    libstagefright_foundation   \
-    libutils
-
-LOCAL_STATIC_LIBRARIES := \
-        libregistermsext
-
-LOCAL_C_INCLUDES :=                                                 \
-    $(TOP)/frameworks/av/media/libstagefright/include               \
-    $(TOP)/frameworks/av/media/libstagefright/rtsp                  \
-    $(TOP)/frameworks/av/media/libstagefright/wifi-display          \
-    $(TOP)/frameworks/av/media/libstagefright/webm                  \
-    $(TOP)/frameworks/av/include/media                              \
-    $(TOP)/frameworks/av/include/camera                             \
-    $(TOP)/frameworks/native/include/media/openmax                  \
-    $(TOP)/frameworks/native/include/media/hardware                 \
-    $(TOP)/external/tremolo/Tremolo                                 \
-    libcore/include
-
-
-LOCAL_MODULE:= mediametrics
-
-LOCAL_INIT_RC := mediametrics.rc
-
-LOCAL_CFLAGS := -Werror -Wall -Wno-error=deprecated-declarations
-LOCAL_CLANG := true
-
-include $(BUILD_EXECUTABLE)
diff --git a/services/mediaanalytics/MediaAnalyticsService.cpp b/services/mediaanalytics/MediaAnalyticsService.cpp
index 4b05395..0e7edfd 100644
--- a/services/mediaanalytics/MediaAnalyticsService.cpp
+++ b/services/mediaanalytics/MediaAnalyticsService.cpp
@@ -26,6 +26,7 @@
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <dirent.h>
+#include <pthread.h>
 #include <unistd.h>
 
 #include <string.h>
@@ -50,7 +51,6 @@
 #include <utils/Timers.h>
 #include <utils/Vector.h>
 
-#include <media/AudioPolicyHelper.h>
 #include <media/IMediaHTTPService.h>
 #include <media/IRemoteDisplay.h>
 #include <media/IRemoteDisplayClient.h>
@@ -76,15 +76,24 @@
 
 namespace android {
 
-    using namespace android::base;
-    using namespace android::content::pm;
-
 // individual records kept in memory: age or count
-// age: <= 36 hours (1.5 days)
+// age: <= 28 hours (1 1/6 days)
 // count: hard limit of # records
 // (0 for either of these disables that threshold)
-static const nsecs_t kMaxRecordAgeNs =  36 * 3600 * (1000*1000*1000ll);
-static const int kMaxRecords    = 0;
+//
+static constexpr nsecs_t kMaxRecordAgeNs =  28 * 3600 * (1000*1000*1000ll);
+// 2019/6: average daily per device is currently 375-ish;
+// setting this to 2000 is large enough to catch most devices
+// we'll lose some data on very very media-active devices, but only for
+// the gms collection; statsd will have already covered those for us.
+// This also retains enough information to help with bugreports
+static constexpr int kMaxRecords    = 2000;
+
+// max we expire in a single call, to constrain how long we hold the
+// mutex, which also constrains how long a client might wait.
+static constexpr int kMaxExpiredAtOnce = 50;
+
+// TODO: need to look at tuning kMaxRecords and friends for low-memory devices
 
 static const char *kServiceName = "media.metrics";
 
@@ -96,6 +105,7 @@
 MediaAnalyticsService::MediaAnalyticsService()
         : mMaxRecords(kMaxRecords),
           mMaxRecordAgeNs(kMaxRecordAgeNs),
+          mMaxRecordsExpiredAtOnce(kMaxExpiredAtOnce),
           mDumpProto(MediaAnalyticsItem::PROTO_V1),
           mDumpProtoDefault(MediaAnalyticsItem::PROTO_V1) {
 
@@ -205,21 +215,24 @@
 
     // XXX: if we have a sessionid in the new record, look to make
     // sure it doesn't appear in the finalized list.
-    // XXX: this is for security / DOS prevention.
-    // may also require that we persist the unique sessionIDs
-    // across boots [instead of within a single boot]
 
     if (item->count() == 0) {
-        // drop empty records
+        ALOGV("dropping empty record...");
         delete item;
         item = NULL;
         return MediaAnalyticsItem::SessionIDInvalid;
     }
 
     // save the new record
+    //
+    // send a copy to statsd
+    dump2Statsd(item);
+
+    // and keep our copy for dumpsys
     MediaAnalyticsItem::SessionID_t id = item->getSessionID();
     saveItem(item);
     mItemsFinalized++;
+
     return id;
 }
 
@@ -432,23 +445,29 @@
 //
 // Our Cheap in-core, non-persistent records management.
 
-// insert appropriately into queue
-void MediaAnalyticsService::saveItem(MediaAnalyticsItem * item)
+
+// we hold mLock when we get here
+// if item != NULL, it's the item we just inserted
+// true == more items eligible to be recovered
+bool MediaAnalyticsService::expirations_l(MediaAnalyticsItem *item)
 {
-
-    Mutex::Autolock _l(mLock);
-    // mutex between insertion and dumping the contents
-
-    // we want to dump 'in FIFO order', so insert at the end
-    mItems.push_back(item);
+    bool more = false;
+    int handled = 0;
 
     // keep removing old records the front until we're in-bounds (count)
+    // since we invoke this with each insertion, it should be 0/1 iterations.
     if (mMaxRecords > 0) {
         while (mItems.size() > (size_t) mMaxRecords) {
             MediaAnalyticsItem * oitem = *(mItems.begin());
             if (oitem == item) {
                 break;
             }
+            if (handled >= mMaxRecordsExpiredAtOnce) {
+                // unlikely in this loop
+                more = true;
+                break;
+            }
+            handled++;
             mItems.erase(mItems.begin());
             delete oitem;
             mItemsDiscarded++;
@@ -456,8 +475,8 @@
         }
     }
 
-    // keep removing old records the front until we're in-bounds (count)
-    // NB: expired entries aren't removed until the next insertion, which could be a while
+    // keep removing old records the front until we're in-bounds (age)
+    // limited to mMaxRecordsExpiredAtOnce items per invocation.
     if (mMaxRecordAgeNs > 0) {
         nsecs_t now = systemTime(SYSTEM_TIME_REALTIME);
         while (mItems.size() > 0) {
@@ -471,18 +490,72 @@
                 // this (and the rest) are recent enough to keep
                 break;
             }
+            if (handled >= mMaxRecordsExpiredAtOnce) {
+                // this represents "one too many"; tell caller there are
+                // more to be reclaimed.
+                more = true;
+                break;
+            }
+            handled++;
             mItems.erase(mItems.begin());
             delete oitem;
             mItemsDiscarded++;
             mItemsDiscardedExpire++;
         }
     }
+
+    // we only indicate whether there's more to clean;
+    // caller chooses whether to schedule further cleanup.
+    return more;
+}
+
+// process expirations in bite sized chunks, allowing new insertions through
+// runs in a pthread specifically started for this (which then exits)
+bool MediaAnalyticsService::processExpirations()
+{
+    bool more;
+    do {
+        sleep(1);
+        {
+            Mutex::Autolock _l(mLock);
+            more = expirations_l(NULL);
+            if (!more) {
+                break;
+            }
+        }
+    } while (more);
+    return true;        // value is for std::future thread synchronization
+}
+
+// insert appropriately into queue
+void MediaAnalyticsService::saveItem(MediaAnalyticsItem * item)
+{
+
+    Mutex::Autolock _l(mLock);
+    // mutex between insertion and dumping the contents
+
+    // we want to dump 'in FIFO order', so insert at the end
+    mItems.push_back(item);
+
+    // clean old stuff from the queue
+    bool more = expirations_l(item);
+
+    // consider scheduling some asynchronous cleaning, if not running
+    if (more) {
+        if (!mExpireFuture.valid()
+            || mExpireFuture.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
+
+            mExpireFuture = std::async(std::launch::async, [this]()
+                                       {return this->processExpirations();});
+        }
+    }
 }
 
 static std::string allowedKeys[] =
 {
     "audiopolicy",
     "audiorecord",
+    "audiothread",
     "audiotrack",
     "codec",
     "extractor",
@@ -581,7 +654,8 @@
         }
 
         if (binder != NULL) {
-            sp<IPackageManagerNative> package_mgr = interface_cast<IPackageManagerNative>(binder);
+            sp<content::pm::IPackageManagerNative> package_mgr =
+                            interface_cast<content::pm::IPackageManagerNative>(binder);
             binder::Status status;
 
             std::vector<int> uids;
diff --git a/services/mediaanalytics/MediaAnalyticsService.h b/services/mediaanalytics/MediaAnalyticsService.h
index b3c902a..6c9cbaa 100644
--- a/services/mediaanalytics/MediaAnalyticsService.h
+++ b/services/mediaanalytics/MediaAnalyticsService.h
@@ -26,6 +26,8 @@
 #include <utils/String8.h>
 #include <utils/List.h>
 
+#include <future>
+
 #include <media/IMediaAnalyticsService.h>
 
 namespace android {
@@ -44,6 +46,8 @@
                             MediaAnalyticsService();
     virtual                 ~MediaAnalyticsService();
 
+    bool processExpirations();
+
  private:
     MediaAnalyticsItem::SessionID_t generateUniqueSessionID();
 
@@ -65,6 +69,8 @@
     int32_t mMaxRecords;
     // by time (none older than this long agan
     nsecs_t mMaxRecordAgeNs;
+    // max to expire per expirations_l() invocation
+    int32_t mMaxRecordsExpiredAtOnce;
     //
     // # of sets of summaries
     int32_t mMaxRecordSets;
@@ -79,6 +85,9 @@
     List<MediaAnalyticsItem *> mItems;
     void saveItem(MediaAnalyticsItem *);
 
+    bool expirations_l(MediaAnalyticsItem *);
+    std::future<bool> mExpireFuture;
+
     // support for generating output
     int mDumpProto;
     int mDumpProtoDefault;
@@ -103,6 +112,9 @@
 
 };
 
+// hook to send things off to the statsd subsystem
+extern bool dump2Statsd(MediaAnalyticsItem *item);
+
 // ----------------------------------------------------------------------------
 
 }; // namespace android
diff --git a/services/mediaanalytics/iface_statsd.cpp b/services/mediaanalytics/iface_statsd.cpp
new file mode 100644
index 0000000..6845f06
--- /dev/null
+++ b/services/mediaanalytics/iface_statsd.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "iface_statsd"
+#include <utils/Log.h>
+
+#include <stdint.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <dirent.h>
+#include <pthread.h>
+#include <unistd.h>
+
+#include <string.h>
+#include <pwd.h>
+
+#include "MediaAnalyticsService.h"
+#include "iface_statsd.h"
+
+#include <statslog.h>
+
+namespace android {
+
+// set of routines that crack a MediaAnalyticsItem
+// and send it off to statsd with the appropriate hooks
+//
+// each MediaAnalyticsItem type (extractor, codec, nuplayer, etc)
+// has its own routine to handle this.
+//
+
+bool enabled_statsd = true;
+
+struct statsd_hooks {
+    const char *key;
+    bool (*handler)(MediaAnalyticsItem *);
+};
+
+// keep this sorted, so we can do binary searches
+struct statsd_hooks  statsd_handlers[] =
+{
+    { "audiopolicy", statsd_audiopolicy },
+    { "audiorecord", statsd_audiorecord },
+    { "audiothread", statsd_audiothread },
+    { "audiotrack", statsd_audiotrack },
+    { "codec", statsd_codec},
+    { "drm.vendor.Google.WidevineCDM", statsd_widevineCDM },
+    { "extractor", statsd_extractor },
+    { "mediadrm", statsd_mediadrm },
+    { "nuplayer", statsd_nuplayer },
+    { "nuplayer2", statsd_nuplayer },
+    { "recorder", statsd_recorder },
+};
+
+
+// give me a record, i'll look at the type and upload appropriately
+bool dump2Statsd(MediaAnalyticsItem *item) {
+    if (item == NULL) return false;
+
+    // get the key
+    std::string key = item->getKey();
+
+    if (!enabled_statsd) {
+        ALOGV("statsd logging disabled for record key=%s", key.c_str());
+        return false;
+    }
+
+    int i;
+    for(i = 0;i < sizeof(statsd_handlers) / sizeof(statsd_handlers[0]) ; i++) {
+        if (key == statsd_handlers[i].key) {
+            return (*statsd_handlers[i].handler)(item);
+        }
+    }
+    return false;
+}
+
+} // namespace android
diff --git a/services/mediaanalytics/iface_statsd.h b/services/mediaanalytics/iface_statsd.h
new file mode 100644
index 0000000..f85d303
--- /dev/null
+++ b/services/mediaanalytics/iface_statsd.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace android {
+
+extern bool enabled_statsd;
+
+// component specific dumpers
+extern bool statsd_audiopolicy(MediaAnalyticsItem *);
+extern bool statsd_audiorecord(MediaAnalyticsItem *);
+extern bool statsd_audiothread(MediaAnalyticsItem *);
+extern bool statsd_audiotrack(MediaAnalyticsItem *);
+extern bool statsd_codec(MediaAnalyticsItem *);
+extern bool statsd_extractor(MediaAnalyticsItem *);
+extern bool statsd_nuplayer(MediaAnalyticsItem *);
+extern bool statsd_recorder(MediaAnalyticsItem *);
+
+extern bool statsd_mediadrm(MediaAnalyticsItem *);
+extern bool statsd_widevineCDM(MediaAnalyticsItem *);
+
+} // namespace android
diff --git a/services/mediaanalytics/statsd_audiopolicy.cpp b/services/mediaanalytics/statsd_audiopolicy.cpp
new file mode 100644
index 0000000..06c4dde
--- /dev/null
+++ b/services/mediaanalytics/statsd_audiopolicy.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "statsd_audiopolicy"
+#include <utils/Log.h>
+
+#include <dirent.h>
+#include <inttypes.h>
+#include <pthread.h>
+#include <pwd.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <statslog.h>
+
+#include "MediaAnalyticsService.h"
+#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "iface_statsd.h"
+
+namespace android {
+
+bool statsd_audiopolicy(MediaAnalyticsItem *item)
+{
+    if (item == NULL) return false;
+
+    // these go into the statsd wrapper
+    nsecs_t timestamp = item->getTimestamp();
+    std::string pkgName = item->getPkgName();
+    int64_t pkgVersionCode = item->getPkgVersionCode();
+    int64_t mediaApexVersion = 0;
+
+
+    // the rest into our own proto
+    //
+    ::android::stats::mediametrics::AudioPolicyData metrics_proto;
+
+    // flesh out the protobuf we'll hand off with our data
+    //
+    //int32 char kAudioPolicyStatus[] = "android.media.audiopolicy.status";
+    int32_t status = -1;
+    if (item->getInt32("android.media.audiopolicy.status", &status)) {
+        metrics_proto.set_status(status);
+    }
+    //string char kAudioPolicyRqstSrc[] = "android.media.audiopolicy.rqst.src";
+    char *rqst_src = NULL;
+    if (item->getCString("android.media.audiopolicy.rqst.src", &rqst_src)) {
+        metrics_proto.set_request_source(rqst_src);
+    }
+    //string char kAudioPolicyRqstPkg[] = "android.media.audiopolicy.rqst.pkg";
+    char *rqst_pkg = NULL;
+    if (item->getCString("android.media.audiopolicy.rqst.pkg", &rqst_pkg)) {
+        metrics_proto.set_request_package(rqst_pkg);
+    }
+    //int32 char kAudioPolicyRqstSession[] = "android.media.audiopolicy.rqst.session";
+    int32_t rqst_session = -1;
+    if (item->getInt32("android.media.audiopolicy.rqst.session", &rqst_session)) {
+        metrics_proto.set_request_session(rqst_session);
+    }
+    //string char kAudioPolicyRqstDevice[] = "android.media.audiopolicy.rqst.device";
+    char *rqst_device = NULL;
+    if (item->getCString("android.media.audiopolicy.rqst.device", &rqst_device)) {
+        metrics_proto.set_request_device(rqst_device);
+    }
+
+    //string char kAudioPolicyActiveSrc[] = "android.media.audiopolicy.active.src";
+    char *active_src = NULL;
+    if (item->getCString("android.media.audiopolicy.active.src", &active_src)) {
+        metrics_proto.set_active_source(active_src);
+    }
+    //string char kAudioPolicyActivePkg[] = "android.media.audiopolicy.active.pkg";
+    char *active_pkg = NULL;
+    if (item->getCString("android.media.audiopolicy.active.pkg", &active_pkg)) {
+        metrics_proto.set_active_package(active_pkg);
+    }
+    //int32 char kAudioPolicyActiveSession[] = "android.media.audiopolicy.active.session";
+    int32_t active_session = -1;
+    if (item->getInt32("android.media.audiopolicy.active.session", &active_session)) {
+        metrics_proto.set_active_session(active_session);
+    }
+    //string char kAudioPolicyActiveDevice[] = "android.media.audiopolicy.active.device";
+    char *active_device = NULL;
+    if (item->getCString("android.media.audiopolicy.active.device", &active_device)) {
+        metrics_proto.set_active_device(active_device);
+    }
+
+
+    std::string serialized;
+    if (!metrics_proto.SerializeToString(&serialized)) {
+        ALOGE("Failed to serialize audipolicy metrics");
+        return false;
+    }
+
+    if (enabled_statsd) {
+        android::util::BytesField bf_serialized( serialized.c_str(), serialized.size());
+        (void)android::util::stats_write(android::util::MEDIAMETRICS_AUDIOPOLICY_REPORTED,
+                                   timestamp, pkgName.c_str(), pkgVersionCode,
+                                   mediaApexVersion,
+                                   bf_serialized);
+
+    } else {
+        ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
+    }
+
+    // must free the strings that we were given
+    free(rqst_src);
+    free(rqst_pkg);
+    free(rqst_device);
+    free(active_src);
+    free(active_pkg);
+    free(active_device);
+
+    return true;
+}
+
+};
diff --git a/services/mediaanalytics/statsd_audiorecord.cpp b/services/mediaanalytics/statsd_audiorecord.cpp
new file mode 100644
index 0000000..c9edb27
--- /dev/null
+++ b/services/mediaanalytics/statsd_audiorecord.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "statsd_audiorecord"
+#include <utils/Log.h>
+
+#include <dirent.h>
+#include <inttypes.h>
+#include <pthread.h>
+#include <pwd.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <statslog.h>
+
+#include "MediaAnalyticsService.h"
+#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "iface_statsd.h"
+
+namespace android {
+
+bool statsd_audiorecord(MediaAnalyticsItem *item)
+{
+    if (item == NULL) return false;
+
+    // these go into the statsd wrapper
+    nsecs_t timestamp = item->getTimestamp();
+    std::string pkgName = item->getPkgName();
+    int64_t pkgVersionCode = item->getPkgVersionCode();
+    int64_t mediaApexVersion = 0;
+
+
+    // the rest into our own proto
+    //
+    ::android::stats::mediametrics::AudioRecordData metrics_proto;
+
+    // flesh out the protobuf we'll hand off with our data
+    //
+    char *encoding = NULL;
+    if (item->getCString("android.media.audiorecord.encoding", &encoding)) {
+        metrics_proto.set_encoding(encoding);
+    }
+
+    char *source = NULL;
+    if (item->getCString("android.media.audiorecord.source", &source)) {
+        metrics_proto.set_source(source);
+    }
+
+    int32_t latency = -1;
+    if (item->getInt32("android.media.audiorecord.latency", &latency)) {
+        metrics_proto.set_latency(latency);
+    }
+
+    int32_t samplerate = -1;
+    if (item->getInt32("android.media.audiorecord.samplerate", &samplerate)) {
+        metrics_proto.set_samplerate(samplerate);
+    }
+
+    int32_t channels = -1;
+    if (item->getInt32("android.media.audiorecord.channels", &channels)) {
+        metrics_proto.set_channels(channels);
+    }
+
+    int64_t createdMs = -1;
+    if (item->getInt64("android.media.audiorecord.createdMs", &createdMs)) {
+        metrics_proto.set_created_millis(createdMs);
+    }
+
+    int64_t durationMs = -1;
+    if (item->getInt64("android.media.audiorecord.durationMs", &durationMs)) {
+        metrics_proto.set_duration_millis(durationMs);
+    }
+
+    int32_t count = -1;
+    if (item->getInt32("android.media.audiorecord.n", &count)) {
+        metrics_proto.set_count(count);
+    }
+
+    int32_t errcode = -1;
+    if (item->getInt32("android.media.audiorecord.errcode", &errcode)) {
+        metrics_proto.set_error_code(errcode);
+    } else if (item->getInt32("android.media.audiorecord.lastError.code", &errcode)) {
+        metrics_proto.set_error_code(errcode);
+    }
+
+    char *errfunc = NULL;
+    if (item->getCString("android.media.audiorecord.errfunc", &errfunc)) {
+        metrics_proto.set_error_function(errfunc);
+    } else if (item->getCString("android.media.audiorecord.lastError.at", &errfunc)) {
+        metrics_proto.set_error_function(errfunc);
+    }
+
+    // portId (int32)
+    int32_t port_id = -1;
+    if (item->getInt32("android.media.audiorecord.portId", &port_id)) {
+        metrics_proto.set_port_id(count);
+    }
+    // frameCount (int32)
+    int32_t frameCount = -1;
+    if (item->getInt32("android.media.audiorecord.frameCount", &frameCount)) {
+        metrics_proto.set_frame_count(frameCount);
+    }
+    // attributes (string)
+    char *attributes = NULL;
+    if (item->getCString("android.media.audiorecord.attributes", &attributes)) {
+        metrics_proto.set_attributes(attributes);
+    }
+    // channelMask (int64)
+    int64_t channelMask = -1;
+    if (item->getInt64("android.media.audiorecord.channelMask", &channelMask)) {
+        metrics_proto.set_channel_mask(channelMask);
+    }
+    // startcount (int64)
+    int64_t startcount = -1;
+    if (item->getInt64("android.media.audiorecord.startcount", &startcount)) {
+        metrics_proto.set_start_count(startcount);
+    }
+
+
+    std::string serialized;
+    if (!metrics_proto.SerializeToString(&serialized)) {
+        ALOGE("Failed to serialize audiorecord metrics");
+        return false;
+    }
+
+    if (enabled_statsd) {
+        android::util::BytesField bf_serialized( serialized.c_str(), serialized.size());
+        (void)android::util::stats_write(android::util::MEDIAMETRICS_AUDIORECORD_REPORTED,
+                                   timestamp, pkgName.c_str(), pkgVersionCode,
+                                   mediaApexVersion,
+                                   bf_serialized);
+
+    } else {
+        ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
+    }
+
+    // must free the strings that we were given
+    free(encoding);
+    free(source);
+    free(errfunc);
+    free(attributes);
+
+    return true;
+}
+
+};
diff --git a/services/mediaanalytics/statsd_audiothread.cpp b/services/mediaanalytics/statsd_audiothread.cpp
new file mode 100644
index 0000000..8232424
--- /dev/null
+++ b/services/mediaanalytics/statsd_audiothread.cpp
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "statsd_audiothread"
+#include <utils/Log.h>
+
+#include <dirent.h>
+#include <inttypes.h>
+#include <pthread.h>
+#include <pwd.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <statslog.h>
+
+#include "MediaAnalyticsService.h"
+#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "iface_statsd.h"
+
+namespace android {
+
+bool statsd_audiothread(MediaAnalyticsItem *item)
+{
+    if (item == NULL) return false;
+
+    // these go into the statsd wrapper
+    nsecs_t timestamp = item->getTimestamp();
+    std::string pkgName = item->getPkgName();
+    int64_t pkgVersionCode = item->getPkgVersionCode();
+    int64_t mediaApexVersion = 0;
+
+
+    // the rest into our own proto
+    //
+    ::android::stats::mediametrics::AudioThreadData metrics_proto;
+
+#define	MM_PREFIX "android.media.audiothread."
+
+    // flesh out the protobuf we'll hand off with our data
+    //
+    char *mytype = NULL;
+    if (item->getCString(MM_PREFIX "type", &mytype)) {
+        metrics_proto.set_type(mytype);
+    }
+    int32_t framecount = -1;
+    if (item->getInt32(MM_PREFIX "framecount", &framecount)) {
+        metrics_proto.set_framecount(framecount);
+    }
+    int32_t samplerate = -1;
+    if (item->getInt32(MM_PREFIX "samplerate", &samplerate)) {
+        metrics_proto.set_samplerate(samplerate);
+    }
+    char *workhist = NULL;
+    if (item->getCString(MM_PREFIX "workMs.hist", &workhist)) {
+        metrics_proto.set_work_millis_hist(workhist);
+    }
+    char *latencyhist = NULL;
+    if (item->getCString(MM_PREFIX "latencyMs.hist", &latencyhist)) {
+        metrics_proto.set_latency_millis_hist(latencyhist);
+    }
+    char *warmuphist = NULL;
+    if (item->getCString(MM_PREFIX "warmupMs.hist", &warmuphist)) {
+        metrics_proto.set_warmup_millis_hist(warmuphist);
+    }
+    int64_t underruns = -1;
+    if (item->getInt64(MM_PREFIX "underruns", &underruns)) {
+        metrics_proto.set_underruns(underruns);
+    }
+    int64_t overruns = -1;
+    if (item->getInt64(MM_PREFIX "overruns", &overruns)) {
+        metrics_proto.set_overruns(overruns);
+    }
+    int64_t activeMs = -1;
+    if (item->getInt64(MM_PREFIX "activeMs", &activeMs)) {
+        metrics_proto.set_active_millis(activeMs);
+    }
+    int64_t durationMs = -1;
+    if (item->getInt64(MM_PREFIX "durationMs", &durationMs)) {
+        metrics_proto.set_duration_millis(durationMs);
+    }
+
+    // item->setInt32(MM_PREFIX "id", (int32_t)mId); // IO handle
+    int32_t id = -1;
+    if (item->getInt32(MM_PREFIX "id", &id)) {
+        metrics_proto.set_id(id);
+    }
+    // item->setInt32(MM_PREFIX "portId", (int32_t)mPortId);
+    int32_t port_id = -1;
+    if (item->getInt32(MM_PREFIX "portId", &id)) {
+        metrics_proto.set_port_id(port_id);
+    }
+    // item->setCString(MM_PREFIX "type", threadTypeToString(mType));
+    char *type = NULL;
+    if (item->getCString(MM_PREFIX "type", &type)) {
+        metrics_proto.set_type(type);
+    }
+    // item->setInt32(MM_PREFIX "sampleRate", (int32_t)mSampleRate);
+    int32_t sample_rate = -1;
+    if (item->getInt32(MM_PREFIX "sampleRate", &sample_rate)) {
+        metrics_proto.set_sample_rate(sample_rate);
+    }
+    // item->setInt64(MM_PREFIX "channelMask", (int64_t)mChannelMask);
+    int32_t channel_mask = -1;
+    if (item->getInt32(MM_PREFIX "channelMask", &channel_mask)) {
+        metrics_proto.set_channel_mask(channel_mask);
+    }
+    // item->setCString(MM_PREFIX "encoding", toString(mFormat).c_str());
+    char *encoding = NULL;
+    if (item->getCString(MM_PREFIX "encoding", &encoding)) {
+        metrics_proto.set_encoding(encoding);
+    }
+    // item->setInt32(MM_PREFIX "frameCount", (int32_t)mFrameCount);
+    int32_t frame_count = -1;
+    if (item->getInt32(MM_PREFIX "frameCount", &frame_count)) {
+        metrics_proto.set_frame_count(frame_count);
+    }
+    // item->setCString(MM_PREFIX "outDevice", toString(mOutDevice).c_str());
+    char *outDevice = NULL;
+    if (item->getCString(MM_PREFIX "outDevice", &outDevice)) {
+        metrics_proto.set_output_device(outDevice);
+    }
+    // item->setCString(MM_PREFIX "inDevice", toString(mInDevice).c_str());
+    char *inDevice = NULL;
+    if (item->getCString(MM_PREFIX "inDevice", &inDevice)) {
+        metrics_proto.set_input_device(inDevice);
+    }
+    // item->setDouble(MM_PREFIX "ioJitterMs.mean", mIoJitterMs.getMean());
+    double iojitters_ms_mean = -1;
+    if (item->getDouble(MM_PREFIX "ioJitterMs.mean", &iojitters_ms_mean)) {
+        metrics_proto.set_io_jitter_mean_millis(iojitters_ms_mean);
+    }
+    // item->setDouble(MM_PREFIX "ioJitterMs.std", mIoJitterMs.getStdDev());
+    double iojitters_ms_std = -1;
+    if (item->getDouble(MM_PREFIX "ioJitterMs.std", &iojitters_ms_std)) {
+        metrics_proto.set_io_jitter_stddev_millis(iojitters_ms_std);
+    }
+    // item->setDouble(MM_PREFIX "processTimeMs.mean", mProcessTimeMs.getMean());
+    double process_time_ms_mean = -1;
+    if (item->getDouble(MM_PREFIX "processTimeMs.mean", &process_time_ms_mean)) {
+        metrics_proto.set_process_time_mean_millis(process_time_ms_mean);
+    }
+    // item->setDouble(MM_PREFIX "processTimeMs.std", mProcessTimeMs.getStdDev());
+    double process_time_ms_std = -1;
+    if (item->getDouble(MM_PREFIX "processTimeMs.std", &process_time_ms_std)) {
+        metrics_proto.set_process_time_stddev_millis(process_time_ms_std);
+    }
+    // item->setDouble(MM_PREFIX "timestampJitterMs.mean", tsjitter.getMean());
+    double timestamp_jitter_ms_mean = -1;
+    if (item->getDouble(MM_PREFIX "timestampJitterMs.mean", &timestamp_jitter_ms_mean)) {
+        metrics_proto.set_timestamp_jitter_mean_millis(timestamp_jitter_ms_mean);
+    }
+    // item->setDouble(MM_PREFIX "timestampJitterMs.std", tsjitter.getStdDev());
+    double timestamp_jitter_ms_stddev = -1;
+    if (item->getDouble(MM_PREFIX "timestampJitterMs.std", &timestamp_jitter_ms_stddev)) {
+        metrics_proto.set_timestamp_jitter_stddev_millis(timestamp_jitter_ms_stddev);
+    }
+    // item->setDouble(MM_PREFIX "latencyMs.mean", mLatencyMs.getMean());
+    double latency_ms_mean = -1;
+    if (item->getDouble(MM_PREFIX "latencyMs.mean", &latency_ms_mean)) {
+        metrics_proto.set_latency_mean_millis(latency_ms_mean);
+    }
+    // item->setDouble(MM_PREFIX "latencyMs.std", mLatencyMs.getStdDev());
+    double latency_ms_stddev = -1;
+    if (item->getDouble(MM_PREFIX "latencyMs.std", &latency_ms_stddev)) {
+        metrics_proto.set_latency_stddev_millis(latency_ms_stddev);
+    }
+
+
+    std::string serialized;
+    if (!metrics_proto.SerializeToString(&serialized)) {
+        ALOGE("Failed to serialize audiothread metrics");
+        return false;
+    }
+
+    if (enabled_statsd) {
+        android::util::BytesField bf_serialized( serialized.c_str(), serialized.size());
+        (void)android::util::stats_write(android::util::MEDIAMETRICS_AUDIOTHREAD_REPORTED,
+                                   timestamp, pkgName.c_str(), pkgVersionCode,
+                                   mediaApexVersion,
+                                   bf_serialized);
+
+    } else {
+        ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
+    }
+
+    // must free the strings that we were given
+    free(mytype);
+    free(workhist);
+    free(latencyhist);
+    free(warmuphist);
+    free(type);
+    free(encoding);
+    free(inDevice);
+    free(outDevice);
+
+    return true;
+}
+
+};
diff --git a/services/mediaanalytics/statsd_audiotrack.cpp b/services/mediaanalytics/statsd_audiotrack.cpp
new file mode 100644
index 0000000..f250ced
--- /dev/null
+++ b/services/mediaanalytics/statsd_audiotrack.cpp
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "statsd_audiotrack"
+#include <utils/Log.h>
+
+#include <dirent.h>
+#include <inttypes.h>
+#include <pthread.h>
+#include <pwd.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <statslog.h>
+
+#include "MediaAnalyticsService.h"
+#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "iface_statsd.h"
+
+namespace android {
+
+bool statsd_audiotrack(MediaAnalyticsItem *item)
+{
+    if (item == NULL) return false;
+
+    // these go into the statsd wrapper
+    nsecs_t timestamp = item->getTimestamp();
+    std::string pkgName = item->getPkgName();
+    int64_t pkgVersionCode = item->getPkgVersionCode();
+    int64_t mediaApexVersion = 0;
+
+
+    // the rest into our own proto
+    //
+    ::android::stats::mediametrics::AudioTrackData metrics_proto;
+
+    // flesh out the protobuf we'll hand off with our data
+    //
+
+    // static constexpr char kAudioTrackStreamType[] = "android.media.audiotrack.streamtype";
+    // optional string streamType;
+    char *streamtype = NULL;
+    if (item->getCString("android.media.audiotrack.streamtype", &streamtype)) {
+        metrics_proto.set_stream_type(streamtype);
+    }
+
+    // static constexpr char kAudioTrackContentType[] = "android.media.audiotrack.type";
+    // optional string contentType;
+    char *contenttype = NULL;
+    if (item->getCString("android.media.audiotrack.type", &contenttype)) {
+        metrics_proto.set_content_type(contenttype);
+    }
+
+    // static constexpr char kAudioTrackUsage[] = "android.media.audiotrack.usage";
+    // optional string trackUsage;
+    char *trackusage = NULL;
+    if (item->getCString("android.media.audiotrack.usage", &trackusage)) {
+        metrics_proto.set_track_usage(trackusage);
+    }
+
+    // static constexpr char kAudioTrackSampleRate[] = "android.media.audiotrack.samplerate";
+    // optional int32 samplerate;
+    int32_t samplerate = -1;
+    if (item->getInt32("android.media.audiotrack.samplerate", &samplerate)) {
+        metrics_proto.set_sample_rate(samplerate);
+    }
+
+    // static constexpr char kAudioTrackChannelMask[] = "android.media.audiotrack.channelmask";
+    // optional int64 channelMask;
+    int64_t channelMask = -1;
+    if (item->getInt64("android.media.audiotrack.channelmask", &channelMask)) {
+        metrics_proto.set_channel_mask(channelMask);
+    }
+
+    // NB: These are not yet exposed as public Java API constants.
+    // static constexpr char kAudioTrackUnderrunFrames[] = "android.media.audiotrack.underrunframes";
+    // optional int32 underrunframes;
+    int32_t underrunframes = -1;
+    if (item->getInt32("android.media.audiotrack.underrunframes", &underrunframes)) {
+        metrics_proto.set_underrun_frames(underrunframes);
+    }
+
+    // static constexpr char kAudioTrackStartupGlitch[] = "android.media.audiotrack.glitch.startup";
+    // optional int32 startupglitch;
+    int32_t startupglitch = -1;
+    if (item->getInt32("android.media.audiotrack.glitch.startup", &startupglitch)) {
+        metrics_proto.set_startup_glitch(startupglitch);
+    }
+
+    // portId (int32)
+    int32_t port_id = -1;
+    if (item->getInt32("android.media.audiotrack.portId", &port_id)) {
+        metrics_proto.set_port_id(port_id);
+    }
+    // encoding (string)
+    char *encoding = NULL;
+    if (item->getCString("android.media.audiotrack.encoding", &encoding)) {
+        metrics_proto.set_encoding(encoding);
+    }
+    // frameCount (int32)
+    int32_t frame_count = -1;
+    if (item->getInt32("android.media.audiotrack.frameCount", &frame_count)) {
+        metrics_proto.set_frame_count(frame_count);
+    }
+    // attributes (string)
+    char *attributes = NULL;
+    if (item->getCString("android.media.audiotrack.attributes", &attributes)) {
+        metrics_proto.set_attributes(attributes);
+    }
+
+    std::string serialized;
+    if (!metrics_proto.SerializeToString(&serialized)) {
+        ALOGE("Failed to serialize audiotrack metrics");
+        return false;
+    }
+
+    if (enabled_statsd) {
+        android::util::BytesField bf_serialized( serialized.c_str(), serialized.size());
+        (void)android::util::stats_write(android::util::MEDIAMETRICS_AUDIOTRACK_REPORTED,
+                                   timestamp, pkgName.c_str(), pkgVersionCode,
+                                   mediaApexVersion,
+                                   bf_serialized);
+
+    } else {
+        ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
+    }
+
+    // must free the strings that we were given
+    free(streamtype);
+    free(contenttype);
+    free(trackusage);
+    free(encoding);
+    free(attributes);
+
+    return true;
+}
+
+};
diff --git a/services/mediaanalytics/statsd_codec.cpp b/services/mediaanalytics/statsd_codec.cpp
new file mode 100644
index 0000000..dc8e4ef
--- /dev/null
+++ b/services/mediaanalytics/statsd_codec.cpp
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "statsd_codec"
+#include <utils/Log.h>
+
+#include <dirent.h>
+#include <inttypes.h>
+#include <pthread.h>
+#include <pwd.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <statslog.h>
+
+#include "MediaAnalyticsService.h"
+#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "iface_statsd.h"
+
+namespace android {
+
+bool statsd_codec(MediaAnalyticsItem *item)
+{
+    if (item == NULL) return false;
+
+    // these go into the statsd wrapper
+    nsecs_t timestamp = item->getTimestamp();
+    std::string pkgName = item->getPkgName();
+    int64_t pkgVersionCode = item->getPkgVersionCode();
+    int64_t mediaApexVersion = 0;
+
+
+    // the rest into our own proto
+    //
+    ::android::stats::mediametrics::CodecData metrics_proto;
+
+    // flesh out the protobuf we'll hand off with our data
+    //
+    // android.media.mediacodec.codec   string
+    char *codec = NULL;
+    if (item->getCString("android.media.mediacodec.codec", &codec)) {
+        metrics_proto.set_codec(codec);
+    }
+    // android.media.mediacodec.mime    string
+    char *mime = NULL;
+    if (item->getCString("android.media.mediacodec.mime", &mime)) {
+        metrics_proto.set_mime(mime);
+    }
+    // android.media.mediacodec.mode    string
+    char *mode = NULL;
+    if ( item->getCString("android.media.mediacodec.mode", &mode)) {
+        metrics_proto.set_mode(mode);
+    }
+    // android.media.mediacodec.encoder int32
+    int32_t encoder = -1;
+    if ( item->getInt32("android.media.mediacodec.encoder", &encoder)) {
+        metrics_proto.set_encoder(encoder);
+    }
+    // android.media.mediacodec.secure  int32
+    int32_t secure = -1;
+    if ( item->getInt32("android.media.mediacodec.secure", &secure)) {
+        metrics_proto.set_secure(secure);
+    }
+    // android.media.mediacodec.width   int32
+    int32_t width = -1;
+    if ( item->getInt32("android.media.mediacodec.width", &width)) {
+        metrics_proto.set_width(width);
+    }
+    // android.media.mediacodec.height  int32
+    int32_t height = -1;
+    if ( item->getInt32("android.media.mediacodec.height", &height)) {
+        metrics_proto.set_height(height);
+    }
+    // android.media.mediacodec.rotation-degrees        int32
+    int32_t rotation = -1;
+    if ( item->getInt32("android.media.mediacodec.rotation-degrees", &rotation)) {
+        metrics_proto.set_rotation(rotation);
+    }
+    // android.media.mediacodec.crypto  int32 (although missing if not needed
+    int32_t crypto = -1;
+    if ( item->getInt32("android.media.mediacodec.crypto", &crypto)) {
+        metrics_proto.set_crypto(crypto);
+    }
+    // android.media.mediacodec.profile int32
+    int32_t profile = -1;
+    if ( item->getInt32("android.media.mediacodec.profile", &profile)) {
+        metrics_proto.set_profile(profile);
+    }
+    // android.media.mediacodec.level   int32
+    int32_t level = -1;
+    if ( item->getInt32("android.media.mediacodec.level", &level)) {
+        metrics_proto.set_level(level);
+    }
+    // android.media.mediacodec.maxwidth        int32
+    int32_t maxwidth = -1;
+    if ( item->getInt32("android.media.mediacodec.maxwidth", &maxwidth)) {
+        metrics_proto.set_max_width(maxwidth);
+    }
+    // android.media.mediacodec.maxheight       int32
+    int32_t maxheight = -1;
+    if ( item->getInt32("android.media.mediacodec.maxheight", &maxheight)) {
+        metrics_proto.set_max_height(maxheight);
+    }
+    // android.media.mediacodec.errcode         int32
+    int32_t errcode = -1;
+    if ( item->getInt32("android.media.mediacodec.errcode", &errcode)) {
+        metrics_proto.set_error_code(errcode);
+    }
+    // android.media.mediacodec.errstate        string
+    char *errstate = NULL;
+    if ( item->getCString("android.media.mediacodec.errstate", &errstate)) {
+        metrics_proto.set_error_state(errstate);
+    }
+    // android.media.mediacodec.latency.max  int64
+    int64_t latency_max = -1;
+    if ( item->getInt64("android.media.mediacodec.latency.max", &latency_max)) {
+        metrics_proto.set_latency_max(latency_max);
+    }
+    // android.media.mediacodec.latency.min  int64
+    int64_t latency_min = -1;
+    if ( item->getInt64("android.media.mediacodec.latency.min", &latency_min)) {
+        metrics_proto.set_latency_min(latency_min);
+    }
+    // android.media.mediacodec.latency.avg  int64
+    int64_t latency_avg = -1;
+    if ( item->getInt64("android.media.mediacodec.latency.avg", &latency_avg)) {
+        metrics_proto.set_latency_avg(latency_avg);
+    }
+    // android.media.mediacodec.latency.n    int64
+    int64_t latency_count = -1;
+    if ( item->getInt64("android.media.mediacodec.latency.n", &latency_count)) {
+        metrics_proto.set_latency_count(latency_count);
+    }
+    // android.media.mediacodec.latency.unknown    int64
+    int64_t latency_unknown = -1;
+    if ( item->getInt64("android.media.mediacodec.latency.unknown", &latency_unknown)) {
+        metrics_proto.set_latency_unknown(latency_unknown);
+    }
+    // android.media.mediacodec.latency.hist    NOT EMITTED
+
+    std::string serialized;
+    if (!metrics_proto.SerializeToString(&serialized)) {
+        ALOGE("Failed to serialize codec metrics");
+        return false;
+    }
+
+    if (enabled_statsd) {
+        android::util::BytesField bf_serialized( serialized.c_str(), serialized.size());
+        (void)android::util::stats_write(android::util::MEDIAMETRICS_CODEC_REPORTED,
+                                   timestamp, pkgName.c_str(), pkgVersionCode,
+                                   mediaApexVersion,
+                                   bf_serialized);
+
+    } else {
+        ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
+    }
+
+    // must free the strings that we were given
+    free(codec);
+    free(mime);
+    free(mode);
+    free(errstate);
+
+    return true;
+}
+
+};
diff --git a/services/mediaanalytics/statsd_drm.cpp b/services/mediaanalytics/statsd_drm.cpp
new file mode 100644
index 0000000..902483a
--- /dev/null
+++ b/services/mediaanalytics/statsd_drm.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "statsd_drm"
+#include <utils/Log.h>
+
+#include <stdint.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <dirent.h>
+#include <pthread.h>
+#include <unistd.h>
+
+#include <string.h>
+#include <pwd.h>
+
+#include "MediaAnalyticsService.h"
+#include "iface_statsd.h"
+
+#include <statslog.h>
+
+namespace android {
+
+// mediadrm
+bool statsd_mediadrm(MediaAnalyticsItem *item)
+{
+    if (item == NULL) return false;
+
+    nsecs_t timestamp = item->getTimestamp();
+    std::string pkgName = item->getPkgName();
+    int64_t pkgVersionCode = item->getPkgVersionCode();
+    int64_t mediaApexVersion = 0;
+
+    char *vendor = NULL;
+    (void) item->getCString("vendor", &vendor);
+    char *description = NULL;
+    (void) item->getCString("description", &description);
+    char *serialized_metrics = NULL;
+    (void) item->getCString("serialized_metrics", &serialized_metrics);
+
+    if (enabled_statsd) {
+        android::util::BytesField bf_serialized(serialized_metrics ? serialized_metrics : NULL,
+                                                serialized_metrics ? strlen(serialized_metrics)
+                                                                   : 0);
+        android::util::stats_write(android::util::MEDIAMETRICS_MEDIADRM_REPORTED,
+                                   timestamp, pkgName.c_str(), pkgVersionCode,
+                                   mediaApexVersion,
+                                   vendor, description,
+                                   bf_serialized);
+    } else {
+        ALOGV("NOT sending: mediadrm private data (len=%zu)",
+              serialized_metrics ? strlen(serialized_metrics) : 0);
+    }
+
+    free(vendor);
+    free(description);
+    free(serialized_metrics);
+    return true;
+}
+
+// widevineCDM
+bool statsd_widevineCDM(MediaAnalyticsItem *item)
+{
+    if (item == NULL) return false;
+
+    nsecs_t timestamp = item->getTimestamp();
+    std::string pkgName = item->getPkgName();
+    int64_t pkgVersionCode = item->getPkgVersionCode();
+    int64_t mediaApexVersion = 0;
+
+    char *serialized_metrics = NULL;
+    (void) item->getCString("serialized_metrics", &serialized_metrics);
+
+    if (enabled_statsd) {
+        android::util::BytesField bf_serialized(serialized_metrics ? serialized_metrics : NULL,
+                                                serialized_metrics ? strlen(serialized_metrics)
+                                                                   : 0);
+        android::util::stats_write(android::util::MEDIAMETRICS_DRM_WIDEVINE_REPORTED,
+                                   timestamp, pkgName.c_str(), pkgVersionCode,
+                                   mediaApexVersion,
+                                   bf_serialized);
+    } else {
+        ALOGV("NOT sending: widevine private data (len=%zu)",
+              serialized_metrics ? strlen(serialized_metrics) : 0);
+    }
+
+    free(serialized_metrics);
+    return true;
+}
+
+} // namespace android
diff --git a/services/mediaanalytics/statsd_extractor.cpp b/services/mediaanalytics/statsd_extractor.cpp
new file mode 100644
index 0000000..395c912
--- /dev/null
+++ b/services/mediaanalytics/statsd_extractor.cpp
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "statsd_extractor"
+#include <utils/Log.h>
+
+#include <dirent.h>
+#include <inttypes.h>
+#include <pthread.h>
+#include <pwd.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <statslog.h>
+
+#include "MediaAnalyticsService.h"
+#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "iface_statsd.h"
+
+namespace android {
+
+bool statsd_extractor(MediaAnalyticsItem *item)
+{
+    if (item == NULL) return false;
+
+    // these go into the statsd wrapper
+    nsecs_t timestamp = item->getTimestamp();
+    std::string pkgName = item->getPkgName();
+    int64_t pkgVersionCode = item->getPkgVersionCode();
+    int64_t mediaApexVersion = 0;
+
+
+    // the rest into our own proto
+    //
+    ::android::stats::mediametrics::ExtractorData metrics_proto;
+
+    // flesh out the protobuf we'll hand off with our data
+    //
+
+    // android.media.mediaextractor.fmt         string
+    char *fmt = NULL;
+    if (item->getCString("android.media.mediaextractor.fmt", &fmt)) {
+        metrics_proto.set_format(fmt);
+    }
+    // android.media.mediaextractor.mime        string
+    char *mime = NULL;
+    if (item->getCString("android.media.mediaextractor.mime", &mime)) {
+        metrics_proto.set_mime(mime);
+    }
+    // android.media.mediaextractor.ntrk        int32
+    int32_t ntrk = -1;
+    if (item->getInt32("android.media.mediaextractor.ntrk", &ntrk)) {
+        metrics_proto.set_tracks(ntrk);
+    }
+
+    std::string serialized;
+    if (!metrics_proto.SerializeToString(&serialized)) {
+        ALOGE("Failed to serialize extractor metrics");
+        return false;
+    }
+
+    if (enabled_statsd) {
+        android::util::BytesField bf_serialized( serialized.c_str(), serialized.size());
+        (void)android::util::stats_write(android::util::MEDIAMETRICS_EXTRACTOR_REPORTED,
+                                   timestamp, pkgName.c_str(), pkgVersionCode,
+                                   mediaApexVersion,
+                                   bf_serialized);
+
+    } else {
+        ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
+    }
+
+    // must free the strings that we were given
+    free(fmt);
+    free(mime);
+
+    return true;
+}
+
+};
diff --git a/services/mediaanalytics/statsd_nuplayer.cpp b/services/mediaanalytics/statsd_nuplayer.cpp
new file mode 100644
index 0000000..5ec118a
--- /dev/null
+++ b/services/mediaanalytics/statsd_nuplayer.cpp
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "statsd_nuplayer"
+#include <utils/Log.h>
+
+#include <dirent.h>
+#include <inttypes.h>
+#include <pthread.h>
+#include <pwd.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <statslog.h>
+
+#include "MediaAnalyticsService.h"
+#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "iface_statsd.h"
+
+namespace android {
+
+/*
+ *  handles nuplayer AND nuplayer2
+ *  checks for the union of what the two players generate
+ */
+bool statsd_nuplayer(MediaAnalyticsItem *item)
+{
+    if (item == NULL) return false;
+
+    // these go into the statsd wrapper
+    nsecs_t timestamp = item->getTimestamp();
+    std::string pkgName = item->getPkgName();
+    int64_t pkgVersionCode = item->getPkgVersionCode();
+    int64_t mediaApexVersion = 0;
+
+
+    // the rest into our own proto
+    //
+    ::android::stats::mediametrics::NuPlayerData metrics_proto;
+
+    // flesh out the protobuf we'll hand off with our data
+    //
+
+    // differentiate between nuplayer and nuplayer2
+    metrics_proto.set_whichplayer(item->getKey().c_str());
+
+    char *video_mime = NULL;
+    if (item->getCString("android.media.mediaplayer.video.mime", &video_mime)) {
+        metrics_proto.set_video_mime(video_mime);
+    }
+    char *video_codec = NULL;
+    if (item->getCString("android.media.mediaplayer.video.codec", &video_codec)) {
+        metrics_proto.set_video_codec(video_codec);
+    }
+
+    int32_t width = -1;
+    if (item->getInt32("android.media.mediaplayer.width", &width)) {
+        metrics_proto.set_width(width);
+    }
+    int32_t height = -1;
+    if (item->getInt32("android.media.mediaplayer.height", &height)) {
+        metrics_proto.set_height(height);
+    }
+
+    int64_t frames = -1;
+    if (item->getInt64("android.media.mediaplayer.frames", &frames)) {
+        metrics_proto.set_frames(frames);
+    }
+    int64_t frames_dropped = -1;
+    if (item->getInt64("android.media.mediaplayer.dropped", &frames_dropped)) {
+        metrics_proto.set_frames_dropped(frames_dropped);
+    }
+    int64_t frames_dropped_startup = -1;
+    if (item->getInt64("android.media.mediaplayer.startupdropped", &frames_dropped_startup)) {
+        metrics_proto.set_frames_dropped_startup(frames_dropped_startup);
+    }
+    double fps = -1.0;
+    if (item->getDouble("android.media.mediaplayer.fps", &fps)) {
+        metrics_proto.set_framerate(fps);
+    }
+
+    char *audio_mime = NULL;
+    if (item->getCString("android.media.mediaplayer.audio.mime", &audio_mime)) {
+        metrics_proto.set_audio_mime(audio_mime);
+    }
+    char *audio_codec = NULL;
+    if (item->getCString("android.media.mediaplayer.audio.codec", &audio_codec)) {
+        metrics_proto.set_audio_codec(audio_codec);
+    }
+
+    int64_t duration_ms = -1;
+    if (item->getInt64("android.media.mediaplayer.durationMs", &duration_ms)) {
+        metrics_proto.set_duration_millis(duration_ms);
+    }
+    int64_t playing_ms = -1;
+    if (item->getInt64("android.media.mediaplayer.playingMs", &playing_ms)) {
+        metrics_proto.set_playing_millis(playing_ms);
+    }
+
+    int32_t err = -1;
+    if (item->getInt32("android.media.mediaplayer.err", &err)) {
+        metrics_proto.set_error(err);
+    }
+    int32_t error_code = -1;
+    if (item->getInt32("android.media.mediaplayer.errcode", &error_code)) {
+        metrics_proto.set_error_code(error_code);
+    }
+    char *error_state = NULL;
+    if (item->getCString("android.media.mediaplayer.errstate", &error_state)) {
+        metrics_proto.set_error_state(error_state);
+    }
+
+    char *data_source_type = NULL;
+    if (item->getCString("android.media.mediaplayer.dataSource", &data_source_type)) {
+        metrics_proto.set_data_source_type(data_source_type);
+    }
+
+    int64_t rebufferingMs = -1;
+    if (item->getInt64("android.media.mediaplayer.rebufferingMs", &rebufferingMs)) {
+        metrics_proto.set_rebuffering_millis(rebufferingMs);
+    }
+    int32_t rebuffers = -1;
+    if (item->getInt32("android.media.mediaplayer.rebuffers", &rebuffers)) {
+        metrics_proto.set_rebuffers(rebuffers);
+    }
+    int32_t rebufferExit = -1;
+    if (item->getInt32("android.media.mediaplayer.rebufferExit", &rebufferExit)) {
+        metrics_proto.set_rebuffer_at_exit(rebufferExit);
+    }
+
+
+    std::string serialized;
+    if (!metrics_proto.SerializeToString(&serialized)) {
+        ALOGE("Failed to serialize nuplayer metrics");
+        return false;
+    }
+
+    if (enabled_statsd) {
+        android::util::BytesField bf_serialized( serialized.c_str(), serialized.size());
+        (void)android::util::stats_write(android::util::MEDIAMETRICS_NUPLAYER_REPORTED,
+                                   timestamp, pkgName.c_str(), pkgVersionCode,
+                                   mediaApexVersion,
+                                   bf_serialized);
+
+    } else {
+        ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
+    }
+
+    // must free the strings that we were given
+    free(video_mime);
+    free(video_codec);
+    free(audio_mime);
+    free(audio_codec);
+    free(error_state);
+    free(data_source_type);
+
+    return true;
+}
+
+};
diff --git a/services/mediaanalytics/statsd_recorder.cpp b/services/mediaanalytics/statsd_recorder.cpp
new file mode 100644
index 0000000..4d981b4
--- /dev/null
+++ b/services/mediaanalytics/statsd_recorder.cpp
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "statsd_recorder"
+#include <utils/Log.h>
+
+#include <dirent.h>
+#include <inttypes.h>
+#include <pthread.h>
+#include <pwd.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <statslog.h>
+
+#include "MediaAnalyticsService.h"
+#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "iface_statsd.h"
+
+namespace android {
+
+bool statsd_recorder(MediaAnalyticsItem *item)
+{
+    if (item == NULL) return false;
+
+    // these go into the statsd wrapper
+    nsecs_t timestamp = item->getTimestamp();
+    std::string pkgName = item->getPkgName();
+    int64_t pkgVersionCode = item->getPkgVersionCode();
+    int64_t mediaApexVersion = 0;
+
+
+    // the rest into our own proto
+    //
+    ::android::stats::mediametrics::RecorderData metrics_proto;
+
+    // flesh out the protobuf we'll hand off with our data
+    //
+
+    // string kRecorderAudioMime = "android.media.mediarecorder.audio.mime";
+    char *audio_mime = NULL;
+    if (item->getCString("android.media.mediarecorder.audio.mime", &audio_mime)) {
+        metrics_proto.set_audio_mime(audio_mime);
+    }
+    // string kRecorderVideoMime = "android.media.mediarecorder.video.mime";
+    char *video_mime = NULL;
+    if (item->getCString("android.media.mediarecorder.video.mime", &video_mime)) {
+        metrics_proto.set_video_mime(video_mime);
+    }
+    // int32 kRecorderVideoProfile = "android.media.mediarecorder.video-encoder-profile";
+    int32_t videoProfile = -1;
+    if (item->getInt32("android.media.mediarecorder.video-encoder-profile", &videoProfile)) {
+        metrics_proto.set_video_profile(videoProfile);
+    }
+    // int32 kRecorderVideoLevel = "android.media.mediarecorder.video-encoder-level";
+    int32_t videoLevel = -1;
+    if (item->getInt32("android.media.mediarecorder.video-encoder-level", &videoLevel)) {
+        metrics_proto.set_video_level(videoLevel);
+    }
+    // int32 kRecorderWidth = "android.media.mediarecorder.width";
+    int32_t width = -1;
+    if (item->getInt32("android.media.mediarecorder.width", &width)) {
+        metrics_proto.set_width(width);
+    }
+    // int32 kRecorderHeight = "android.media.mediarecorder.height";
+    int32_t height = -1;
+    if (item->getInt32("android.media.mediarecorder.height", &height)) {
+        metrics_proto.set_height(height);
+    }
+    // int32 kRecorderRotation = "android.media.mediarecorder.rotation";
+    int32_t rotation = -1;                      // default to 0?
+    if (item->getInt32("android.media.mediarecorder.rotation", &rotation)) {
+        metrics_proto.set_rotation(rotation);
+    }
+    // int32 kRecorderFrameRate = "android.media.mediarecorder.frame-rate";
+    int32_t framerate = -1;
+    if (item->getInt32("android.media.mediarecorder.frame-rate", &framerate)) {
+        metrics_proto.set_framerate(framerate);
+    }
+
+    // int32 kRecorderCaptureFps = "android.media.mediarecorder.capture-fps";
+    int32_t captureFps = -1;
+    if (item->getInt32("android.media.mediarecorder.capture-fps", &captureFps)) {
+        metrics_proto.set_capture_fps(captureFps);
+    }
+    // double kRecorderCaptureFpsEnable = "android.media.mediarecorder.capture-fpsenable";
+    double captureFpsEnable = -1;
+    if (item->getDouble("android.media.mediarecorder.capture-fpsenable", &captureFpsEnable)) {
+        metrics_proto.set_capture_fps_enable(captureFpsEnable);
+    }
+
+    // int64 kRecorderDurationMs = "android.media.mediarecorder.durationMs";
+    int64_t durationMs = -1;
+    if (item->getInt64("android.media.mediarecorder.durationMs", &durationMs)) {
+        metrics_proto.set_duration_millis(durationMs);
+    }
+    // int64 kRecorderPaused = "android.media.mediarecorder.pausedMs";
+    int64_t pausedMs = -1;
+    if (item->getInt64("android.media.mediarecorder.pausedMs", &pausedMs)) {
+        metrics_proto.set_paused_millis(pausedMs);
+    }
+    // int32 kRecorderNumPauses = "android.media.mediarecorder.NPauses";
+    int32_t pausedCount = -1;
+    if (item->getInt32("android.media.mediarecorder.NPauses", &pausedCount)) {
+        metrics_proto.set_paused_count(pausedCount);
+    }
+
+    // int32 kRecorderAudioBitrate = "android.media.mediarecorder.audio-bitrate";
+    int32_t audioBitrate = -1;
+    if (item->getInt32("android.media.mediarecorder.audio-bitrate", &audioBitrate)) {
+        metrics_proto.set_audio_bitrate(audioBitrate);
+    }
+    // int32 kRecorderAudioChannels = "android.media.mediarecorder.audio-channels";
+    int32_t audioChannels = -1;
+    if (item->getInt32("android.media.mediarecorder.audio-channels", &audioChannels)) {
+        metrics_proto.set_audio_channels(audioChannels);
+    }
+    // int32 kRecorderAudioSampleRate = "android.media.mediarecorder.audio-samplerate";
+    int32_t audioSampleRate = -1;
+    if (item->getInt32("android.media.mediarecorder.audio-samplerate", &audioSampleRate)) {
+        metrics_proto.set_audio_samplerate(audioSampleRate);
+    }
+
+    // int32 kRecorderMovieTimescale = "android.media.mediarecorder.movie-timescale";
+    int32_t movieTimescale = -1;
+    if (item->getInt32("android.media.mediarecorder.movie-timescale", &movieTimescale)) {
+        metrics_proto.set_movie_timescale(movieTimescale);
+    }
+    // int32 kRecorderAudioTimescale = "android.media.mediarecorder.audio-timescale";
+    int32_t audioTimescale = -1;
+    if (item->getInt32("android.media.mediarecorder.audio-timescale", &audioTimescale)) {
+        metrics_proto.set_audio_timescale(audioTimescale);
+    }
+    // int32 kRecorderVideoTimescale = "android.media.mediarecorder.video-timescale";
+    int32_t videoTimescale = -1;
+    if (item->getInt32("android.media.mediarecorder.video-timescale", &videoTimescale)) {
+        metrics_proto.set_video_timescale(videoTimescale);
+    }
+
+    // int32 kRecorderVideoBitrate = "android.media.mediarecorder.video-bitrate";
+    int32_t videoBitRate = -1;
+    if (item->getInt32("android.media.mediarecorder.video-bitrate", &videoBitRate)) {
+        metrics_proto.set_video_bitrate(videoBitRate);
+    }
+    // int32 kRecorderVideoIframeInterval = "android.media.mediarecorder.video-iframe-interval";
+    int32_t iFrameInterval = -1;
+    if (item->getInt32("android.media.mediarecorder.video-iframe-interval", &iFrameInterval)) {
+        metrics_proto.set_iframe_interval(iFrameInterval);
+    }
+
+    std::string serialized;
+    if (!metrics_proto.SerializeToString(&serialized)) {
+        ALOGE("Failed to serialize recorder metrics");
+        return false;
+    }
+
+    if (enabled_statsd) {
+        android::util::BytesField bf_serialized( serialized.c_str(), serialized.size());
+        (void)android::util::stats_write(android::util::MEDIAMETRICS_RECORDER_REPORTED,
+                                   timestamp, pkgName.c_str(), pkgVersionCode,
+                                   mediaApexVersion,
+                                   bf_serialized);
+
+    } else {
+        ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
+    }
+
+    // must free the strings that we were given
+    free(audio_mime);
+    free(video_mime);
+
+    return true;
+}
+
+};
diff --git a/services/mediacodec/Android.bp b/services/mediacodec/Android.bp
new file mode 100644
index 0000000..2f3cad9
--- /dev/null
+++ b/services/mediacodec/Android.bp
@@ -0,0 +1,71 @@
+cc_binary {
+    name: "mediaswcodec",
+    vendor_available: true,
+
+    srcs: [
+        "main_swcodecservice.cpp",
+    ],
+
+    shared_libs: [
+        "libavservices_minijail",
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libmedia_codecserviceregistrant",
+    ],
+
+    target: {
+        vendor: {
+            exclude_shared_libs: ["libavservices_minijail"],
+            shared_libs: ["libavservices_minijail_vendor"],
+        },
+        android: {
+            product_variables: {
+                malloc_not_svelte: {
+                    // Scudo increases memory footprint, so only enable on
+                    // non-svelte devices.
+                    shared_libs: ["libc_scudo"],
+                },
+            },
+        },
+    },
+
+    header_libs: [
+        "libmedia_headers",
+    ],
+
+    init_rc: ["mediaswcodec.rc"],
+
+    required: ["mediaswcodec.policy"],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+        "-Wno-error=deprecated-declarations",
+    ],
+}
+
+prebuilt_etc {
+    name: "mediaswcodec.policy",
+    sub_dir: "seccomp_policy",
+    arch: {
+        arm: {
+            src: "seccomp_policy/mediaswcodec-arm.policy",
+        },
+        arm64: {
+            src: "seccomp_policy/mediaswcodec-arm64.policy",
+        },
+        x86: {
+            src: "seccomp_policy/mediacodec-x86.policy",
+        },
+        x86_64: {
+            src: "seccomp_policy/mediacodec-x86.policy",
+        },
+    },
+    required: [
+        "crash_dump.policy",
+        "code_coverage.policy",
+    ],
+}
diff --git a/services/mediacodec/Android.mk b/services/mediacodec/Android.mk
index 8631c39..15bc503 100644
--- a/services/mediacodec/Android.mk
+++ b/services/mediacodec/Android.mk
@@ -22,18 +22,17 @@
     libstagefright_soft_vorbisdec \
     libstagefright_soft_vpxdec \
     libstagefright_soft_vpxenc \
+    libstagefright_softomx_plugin \
 
 # service executable
 include $(CLEAR_VARS)
 # seccomp is not required for coverage build.
 ifneq ($(NATIVE_COVERAGE),true)
-LOCAL_REQUIRED_MODULES := crash_dump.policy
 LOCAL_REQUIRED_MODULES_arm := mediacodec.policy
 LOCAL_REQUIRED_MODULES_x86 := mediacodec.policy
 endif
 LOCAL_SRC_FILES := main_codecservice.cpp
 LOCAL_SHARED_LIBRARIES := \
-    libmedia_omx \
     libbinder \
     libutils \
     liblog \
@@ -41,6 +40,7 @@
     libavservices_minijail_vendor \
     libcutils \
     libhwbinder \
+    libhidlbase \
     libhidltransport \
     libstagefright_omx \
     libstagefright_xmlparser \
@@ -64,12 +64,15 @@
 
 include $(BUILD_EXECUTABLE)
 
+####################################################################
+
 # service seccomp policy
 ifeq ($(TARGET_ARCH), $(filter $(TARGET_ARCH), x86 x86_64 arm arm64))
 include $(CLEAR_VARS)
 LOCAL_MODULE := mediacodec.policy
 LOCAL_MODULE_CLASS := ETC
 LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/seccomp_policy
+LOCAL_REQUIRED_MODULES := crash_dump.policy code_coverage.policy
 # mediacodec runs in 32-bit combatibility mode. For 64 bit architectures,
 # use the 32 bit policy
 ifdef TARGET_2ND_ARCH
@@ -84,4 +87,7 @@
 include $(BUILD_PREBUILT)
 endif
 
+####################################################################
+
+
 include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/services/mediacodec/main_codecservice.cpp b/services/mediacodec/main_codecservice.cpp
index 51619f6..f668c33 100644
--- a/services/mediacodec/main_codecservice.cpp
+++ b/services/mediacodec/main_codecservice.cpp
@@ -25,7 +25,6 @@
 #include <media/stagefright/omx/1.0/Omx.h>
 #include <media/stagefright/omx/1.0/OmxStore.h>
 
-#include <media/CodecServiceRegistrant.h>
 #include <dlfcn.h>
 
 using namespace android;
@@ -48,37 +47,21 @@
 
     ::android::hardware::configureRpcThreadpool(64, false);
 
-    // Registration of customized codec services
-    void *registrantLib = dlopen(
-            "libmedia_codecserviceregistrant.so",
-            RTLD_NOW | RTLD_LOCAL);
-    if (registrantLib) {
-        RegisterCodecServicesFunc registerCodecServices =
-                reinterpret_cast<RegisterCodecServicesFunc>(
-                dlsym(registrantLib, "RegisterCodecServices"));
-        if (registerCodecServices) {
-            registerCodecServices();
-        } else {
-            LOG(WARNING) << "Cannot register additional services "
-                    "-- corrupted library.";
-        }
+    // Default codec services
+    using namespace ::android::hardware::media::omx::V1_0;
+    sp<IOmx> omx = new implementation::Omx();
+    if (omx == nullptr) {
+        LOG(ERROR) << "Cannot create IOmx HAL service.";
+    } else if (omx->registerAsService() != OK) {
+        LOG(ERROR) << "Cannot register IOmx HAL service.";
     } else {
-        // Default codec services
-        using namespace ::android::hardware::media::omx::V1_0;
-        sp<IOmxStore> omxStore = new implementation::OmxStore();
-        if (omxStore == nullptr) {
-            LOG(ERROR) << "Cannot create IOmxStore HAL service.";
-        } else if (omxStore->registerAsService() != OK) {
-            LOG(ERROR) << "Cannot register IOmxStore HAL service.";
-        }
-        sp<IOmx> omx = new implementation::Omx();
-        if (omx == nullptr) {
-            LOG(ERROR) << "Cannot create IOmx HAL service.";
-        } else if (omx->registerAsService() != OK) {
-            LOG(ERROR) << "Cannot register IOmx HAL service.";
-        } else {
-            LOG(INFO) << "IOmx HAL service created.";
-        }
+        LOG(INFO) << "IOmx HAL service created.";
+    }
+    sp<IOmxStore> omxStore = new implementation::OmxStore(omx);
+    if (omxStore == nullptr) {
+        LOG(ERROR) << "Cannot create IOmxStore HAL service.";
+    } else if (omxStore->registerAsService() != OK) {
+        LOG(ERROR) << "Cannot register IOmxStore HAL service.";
     }
 
     ::android::hardware::joinRpcThreadpool();
diff --git a/services/mediacodec/main_swcodecservice.cpp b/services/mediacodec/main_swcodecservice.cpp
new file mode 100644
index 0000000..d91b788
--- /dev/null
+++ b/services/mediacodec/main_swcodecservice.cpp
@@ -0,0 +1,48 @@
+/*
+**
+** Copyright 2018, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include <android-base/logging.h>
+
+// from LOCAL_C_INCLUDES
+#include "minijail.h"
+#include <hidl/HidlTransportSupport.h>
+
+using namespace android;
+
+// kSystemSeccompPolicyPath points to the policy for the swcodecs themselves and
+// is part of the updates. kVendorSeccompPolicyPath points to any additional
+// policies that the vendor may need for the device.
+static const char kSystemSeccompPolicyPath[] =
+        "/apex/com.android.media.swcodec/etc/seccomp_policy/mediaswcodec.policy";
+static const char kVendorSeccompPolicyPath[] =
+        "/vendor/etc/seccomp_policy/mediaswcodec.policy";
+
+extern "C" void RegisterCodecServices();
+
+int main(int argc __unused, char** argv)
+{
+    LOG(INFO) << "media swcodec service starting";
+    signal(SIGPIPE, SIG_IGN);
+    SetUpMinijail(kSystemSeccompPolicyPath, kVendorSeccompPolicyPath);
+    strcpy(argv[0], "media.swcodec");
+
+    ::android::hardware::configureRpcThreadpool(64, false);
+
+    RegisterCodecServices();
+
+    ::android::hardware::joinRpcThreadpool();
+}
diff --git a/services/mediacodec/mediaswcodec.rc b/services/mediacodec/mediaswcodec.rc
new file mode 100644
index 0000000..3549666
--- /dev/null
+++ b/services/mediacodec/mediaswcodec.rc
@@ -0,0 +1,7 @@
+service media.swcodec /system/bin/mediaswcodec
+    class main
+    user mediacodec
+    group camera drmrpc mediadrm
+    updatable
+    ioprio rt 4
+    writepid /dev/cpuset/foreground/tasks
diff --git a/services/mediacodec/registrant/Android.bp b/services/mediacodec/registrant/Android.bp
new file mode 100644
index 0000000..17c2e02
--- /dev/null
+++ b/services/mediacodec/registrant/Android.bp
@@ -0,0 +1,54 @@
+cc_library_shared {
+    name: "libmedia_codecserviceregistrant",
+    vendor_available: true,
+    srcs: [
+        "CodecServiceRegistrant.cpp",
+    ],
+
+    header_libs: [
+        "libmedia_headers",
+    ],
+
+    shared_libs: [
+        "android.hardware.media.c2@1.0",
+        "libbase",
+        "libcodec2_hidl@1.0",
+        "libcodec2_vndk",
+        "libutils",
+    ],
+
+    // Codecs
+    runtime_libs: [
+        "libcodec2_soft_avcdec",
+        "libcodec2_soft_avcenc",
+        "libcodec2_soft_aacdec",
+        "libcodec2_soft_aacenc",
+        "libcodec2_soft_amrnbdec",
+        "libcodec2_soft_amrnbenc",
+        "libcodec2_soft_amrwbdec",
+        "libcodec2_soft_amrwbenc",
+        "libcodec2_soft_hevcdec",
+        "libcodec2_soft_hevcenc",
+        "libcodec2_soft_g711alawdec",
+        "libcodec2_soft_g711mlawdec",
+        "libcodec2_soft_mpeg2dec",
+        "libcodec2_soft_h263dec",
+        "libcodec2_soft_h263enc",
+        "libcodec2_soft_mpeg4dec",
+        "libcodec2_soft_mpeg4enc",
+        "libcodec2_soft_mp3dec",
+        "libcodec2_soft_vorbisdec",
+        "libcodec2_soft_opusdec",
+        "libcodec2_soft_opusenc",
+        "libcodec2_soft_vp8dec",
+        "libcodec2_soft_vp9dec",
+        "libcodec2_soft_av1dec",
+        "libcodec2_soft_vp8enc",
+        "libcodec2_soft_vp9enc",
+        "libcodec2_soft_rawdec",
+        "libcodec2_soft_flacdec",
+        "libcodec2_soft_flacenc",
+        "libcodec2_soft_gsmdec",
+    ],
+}
+
diff --git a/services/mediacodec/registrant/CodecServiceRegistrant.cpp b/services/mediacodec/registrant/CodecServiceRegistrant.cpp
new file mode 100644
index 0000000..706ebee
--- /dev/null
+++ b/services/mediacodec/registrant/CodecServiceRegistrant.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "CodecServiceRegistrant"
+
+#include <android-base/logging.h>
+
+#include <C2PlatformSupport.h>
+#include <codec2/hidl/1.0/ComponentStore.h>
+#include <media/CodecServiceRegistrant.h>
+
+extern "C" void RegisterCodecServices() {
+    using namespace ::android::hardware::media::c2::V1_0;
+    LOG(INFO) << "Creating software Codec2 service...";
+    android::sp<IComponentStore> store =
+        new utils::ComponentStore(
+                android::GetCodec2PlatformComponentStore());
+    if (store == nullptr) {
+        LOG(ERROR) <<
+                "Cannot create software Codec2 service.";
+    } else {
+        if (store->registerAsService("software") != android::OK) {
+            LOG(ERROR) <<
+                    "Cannot register software Codec2 service.";
+        } else {
+            LOG(INFO) <<
+                    "Software Codec2 service created.";
+        }
+    }
+}
+
diff --git a/services/mediacodec/seccomp_policy/mediacodec-arm.policy b/services/mediacodec/seccomp_policy/mediacodec-arm.policy
index 6ec8895..835f8bb 100644
--- a/services/mediacodec/seccomp_policy/mediacodec-arm.policy
+++ b/services/mediacodec/seccomp_policy/mediacodec-arm.policy
@@ -13,6 +13,9 @@
 ppoll: 1
 mmap2: 1
 getrandom: 1
+memfd_create: 1
+ftruncate: 1
+ftruncate64: 1
 
 # mremap: Ensure |flags| are (MREMAP_MAYMOVE | MREMAP_FIXED) TODO: Once minijail
 # parser support for '<' is in this needs to be modified to also prevent
@@ -56,3 +59,5 @@
 getrandom: 1
 
 @include /system/etc/seccomp_policy/crash_dump.arm.policy
+
+@include /system/etc/seccomp_policy/code_coverage.arm.policy
diff --git a/services/mediacodec/seccomp_policy/mediacodec-x86.policy b/services/mediacodec/seccomp_policy/mediacodec-x86.policy
index bbbe552..a9d32d6 100644
--- a/services/mediacodec/seccomp_policy/mediacodec-x86.policy
+++ b/services/mediacodec/seccomp_policy/mediacodec-x86.policy
@@ -18,14 +18,20 @@
 openat: 1
 open: 1
 getuid32: 1
+getuid: 1
+getrlimit: 1
 writev: 1
 ioctl: 1
 close: 1
 mmap2: 1
+mmap: 1
 fstat64: 1
+fstat: 1
 stat64: 1
+statfs64: 1
 madvise: 1
 fstatat64: 1
+newfstatat: 1
 futex: 1
 munmap: 1
 faccessat: 1
@@ -39,15 +45,22 @@
 exit_group: 1
 rt_sigreturn: 1
 ugetrlimit: 1
+readlink: 1
 readlinkat: 1
 _llseek: 1
 fstatfs64: 1
+fstatfs: 1
 pread64: 1
 mremap: 1
 dup: 1
 set_tid_address: 1
 write: 1
 nanosleep: 1
+sched_setscheduler: 1
+uname: 1
+memfd_create: 1
+ftruncate: 1
+ftruncate64: 1
 
 # Required by AddressSanitizer
 gettid: 1
@@ -56,3 +69,4 @@
 gettid: 1
 
 @include /system/etc/seccomp_policy/crash_dump.x86.policy
+@include /system/etc/seccomp_policy/code_coverage.x86.policy
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy b/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
new file mode 100644
index 0000000..93b4852
--- /dev/null
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
@@ -0,0 +1,88 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+futex: 1
+# ioctl calls are filtered via the selinux policy.
+ioctl: 1
+sched_yield: 1
+close: 1
+dup: 1
+ppoll: 1
+mprotect: arg2 in ~PROT_EXEC || arg2 in ~PROT_WRITE
+mmap2: arg2 in ~PROT_EXEC || arg2 in ~PROT_WRITE
+memfd_create: 1
+ftruncate: 1
+ftruncate64: 1
+
+# mremap: Ensure |flags| are (MREMAP_MAYMOVE | MREMAP_FIXED) TODO: Once minijail
+# parser support for '<' is in this needs to be modified to also prevent
+# |old_address| and |new_address| from touching the exception vector page, which
+# on ARM is statically loaded at 0xffff 0000. See
+# http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0211h/Babfeega.html
+# for more details.
+mremap: arg3 == 3
+munmap: 1
+prctl: 1
+getuid32: 1
+writev: 1
+sigaltstack: 1
+clone: 1
+exit: 1
+lseek: 1
+rt_sigprocmask: 1
+openat: 1
+open: 1
+fstat64: 1
+write: 1
+nanosleep: 1
+setpriority: 1
+set_tid_address: 1
+getdents64: 1
+readlinkat: 1
+readlink: 1
+read: 1
+pread64: 1
+fstatfs64: 1
+gettimeofday: 1
+faccessat: 1
+_llseek: 1
+fstatat64: 1
+ugetrlimit: 1
+exit_group: 1
+restart_syscall: 1
+rt_sigreturn: 1
+getrandom: 1
+madvise: 1
+
+# crash dump policy additions
+sigreturn: 1
+clock_gettime: 1
+futex: 1
+getpid: 1
+gettid: 1
+pipe2: 1
+recvmsg: 1
+process_vm_readv: 1
+tgkill: 1
+rt_sigaction: 1
+rt_tgsigqueueinfo: 1
+#prctl: arg0 == PR_GET_NO_NEW_PRIVS || arg0 == 0x53564d41
+#mprotect: arg2 in 0x1|0x2
+#mmap2: arg2 in 0x1|0x2
+geteuid32: 1
+getgid32: 1
+getegid32: 1
+getgroups32: 1
+
+@include /system/etc/seccomp_policy/code_coverage.arm.policy
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy b/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy
new file mode 100644
index 0000000..bb05770
--- /dev/null
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy
@@ -0,0 +1,82 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+futex: 1
+# ioctl calls are filtered via the selinux policy.
+ioctl: 1
+sched_yield: 1
+close: 1
+dup: 1
+ppoll: 1
+mprotect: arg2 in ~PROT_EXEC || arg2 in ~PROT_WRITE
+mmap: arg2 in ~PROT_EXEC || arg2 in ~PROT_WRITE
+getuid: 1
+getrlimit: 1
+fstat: 1
+newfstatat: 1
+fstatfs: 1
+memfd_create: 1
+ftruncate: 1
+
+# mremap: Ensure |flags| are (MREMAP_MAYMOVE | MREMAP_FIXED) TODO: Once minijail
+# parser support for '<' is in this needs to be modified to also prevent
+# |old_address| and |new_address| from touching the exception vector page, which
+# on ARM is statically loaded at 0xffff 0000. See
+# http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0211h/Babfeega.html
+# for more details.
+mremap: arg3 == 3
+munmap: 1
+prctl: 1
+writev: 1
+sigaltstack: 1
+clone: 1
+exit: 1
+lseek: 1
+rt_sigprocmask: 1
+openat: 1
+write: 1
+nanosleep: 1
+setpriority: 1
+set_tid_address: 1
+getdents64: 1
+readlinkat: 1
+read: 1
+pread64: 1
+gettimeofday: 1
+faccessat: 1
+exit_group: 1
+restart_syscall: 1
+rt_sigreturn: 1
+getrandom: 1
+madvise: 1
+
+# crash dump policy additions
+clock_gettime: 1
+getpid: 1
+gettid: 1
+pipe2: 1
+recvmsg: 1
+process_vm_readv: 1
+tgkill: 1
+rt_sigaction: 1
+rt_tgsigqueueinfo: 1
+#mprotect: arg2 in 0x1|0x2
+munmap: 1
+#mmap: arg2 in 0x1|0x2
+geteuid: 1
+getgid: 1
+getegid: 1
+getgroups: 1
+
+@include /system/etc/seccomp_policy/code_coverage.arm64.policy
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-x86.policy b/services/mediacodec/seccomp_policy/mediaswcodec-x86.policy
new file mode 120000
index 0000000..ab2592a
--- /dev/null
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-x86.policy
@@ -0,0 +1 @@
+mediacodec-x86.policy
\ No newline at end of file
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-x86_64.policy b/services/mediacodec/seccomp_policy/mediaswcodec-x86_64.policy
new file mode 120000
index 0000000..ab2592a
--- /dev/null
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-x86_64.policy
@@ -0,0 +1 @@
+mediacodec-x86.policy
\ No newline at end of file
diff --git a/services/mediadrm/Android.mk b/services/mediadrm/Android.mk
index e870965..227a29d 100644
--- a/services/mediadrm/Android.mk
+++ b/services/mediadrm/Android.mk
@@ -29,7 +29,8 @@
     libhidlmemory \
     libhidltransport \
     android.hardware.drm@1.0 \
-    android.hardware.drm@1.1
+    android.hardware.drm@1.1 \
+    android.hardware.drm@1.2
 
 LOCAL_CFLAGS += -Wall -Wextra -Werror
 
diff --git a/services/mediadrm/tests/Android.mk b/services/mediadrm/tests/Android.mk
deleted file mode 100644
index e2f7399..0000000
--- a/services/mediadrm/tests/Android.mk
+++ /dev/null
@@ -1,26 +0,0 @@
-# Build the unit tests.
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := DrmSessionManager_test
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := \
-	DrmSessionManager_test.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
-	liblog \
-	libmediaplayerservice \
-	libutils \
-
-LOCAL_C_INCLUDES := \
-	frameworks/av/include \
-	frameworks/av/media/libmediaplayerservice \
-
-LOCAL_CFLAGS += -Werror -Wall
-
-LOCAL_32_BIT_ONLY := true
-
-include $(BUILD_NATIVE_TEST)
-
diff --git a/services/mediadrm/tests/DrmSessionManager_test.cpp b/services/mediadrm/tests/DrmSessionManager_test.cpp
deleted file mode 100644
index de350a1..0000000
--- a/services/mediadrm/tests/DrmSessionManager_test.cpp
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "DrmSessionManager_test"
-#include <utils/Log.h>
-
-#include <gtest/gtest.h>
-
-#include "Drm.h"
-#include "DrmSessionClientInterface.h"
-#include "DrmSessionManager.h"
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/ProcessInfoInterface.h>
-
-namespace android {
-
-struct FakeProcessInfo : public ProcessInfoInterface {
-    FakeProcessInfo() {}
-    virtual ~FakeProcessInfo() {}
-
-    virtual bool getPriority(int pid, int* priority) {
-        // For testing, use pid as priority.
-        // Lower the value higher the priority.
-        *priority = pid;
-        return true;
-    }
-
-private:
-    DISALLOW_EVIL_CONSTRUCTORS(FakeProcessInfo);
-};
-
-struct FakeDrm : public DrmSessionClientInterface {
-    FakeDrm() {}
-    virtual ~FakeDrm() {}
-
-    virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
-        mReclaimedSessions.push_back(sessionId);
-        return true;
-    }
-
-    const Vector<Vector<uint8_t> >& reclaimedSessions() const {
-        return mReclaimedSessions;
-    }
-
-private:
-    Vector<Vector<uint8_t> > mReclaimedSessions;
-
-    DISALLOW_EVIL_CONSTRUCTORS(FakeDrm);
-};
-
-static const int kTestPid1 = 30;
-static const int kTestPid2 = 20;
-static const uint8_t kTestSessionId1[] = {1, 2, 3};
-static const uint8_t kTestSessionId2[] = {4, 5, 6, 7, 8};
-static const uint8_t kTestSessionId3[] = {9, 0};
-
-class DrmSessionManagerTest : public ::testing::Test {
-public:
-    DrmSessionManagerTest()
-        : mDrmSessionManager(new DrmSessionManager(new FakeProcessInfo())),
-          mTestDrm1(new FakeDrm()),
-          mTestDrm2(new FakeDrm()) {
-        GetSessionId(kTestSessionId1, ARRAY_SIZE(kTestSessionId1), &mSessionId1);
-        GetSessionId(kTestSessionId2, ARRAY_SIZE(kTestSessionId2), &mSessionId2);
-        GetSessionId(kTestSessionId3, ARRAY_SIZE(kTestSessionId3), &mSessionId3);
-    }
-
-protected:
-    static void GetSessionId(const uint8_t* ids, size_t num, Vector<uint8_t>* sessionId) {
-        for (size_t i = 0; i < num; ++i) {
-            sessionId->push_back(ids[i]);
-        }
-    }
-
-    static void ExpectEqSessionInfo(const SessionInfo& info, sp<DrmSessionClientInterface> drm,
-            const Vector<uint8_t>& sessionId, int64_t timeStamp) {
-        EXPECT_EQ(drm, info.drm);
-        EXPECT_TRUE(isEqualSessionId(sessionId, info.sessionId));
-        EXPECT_EQ(timeStamp, info.timeStamp);
-    }
-
-    void addSession() {
-        mDrmSessionManager->addSession(kTestPid1, mTestDrm1, mSessionId1);
-        mDrmSessionManager->addSession(kTestPid2, mTestDrm2, mSessionId2);
-        mDrmSessionManager->addSession(kTestPid2, mTestDrm2, mSessionId3);
-        const PidSessionInfosMap& map = sessionMap();
-        EXPECT_EQ(2u, map.size());
-        ssize_t index1 = map.indexOfKey(kTestPid1);
-        ASSERT_GE(index1, 0);
-        const SessionInfos& infos1 = map[index1];
-        EXPECT_EQ(1u, infos1.size());
-        ExpectEqSessionInfo(infos1[0], mTestDrm1, mSessionId1, 0);
-
-        ssize_t index2 = map.indexOfKey(kTestPid2);
-        ASSERT_GE(index2, 0);
-        const SessionInfos& infos2 = map[index2];
-        EXPECT_EQ(2u, infos2.size());
-        ExpectEqSessionInfo(infos2[0], mTestDrm2, mSessionId2, 1);
-        ExpectEqSessionInfo(infos2[1], mTestDrm2, mSessionId3, 2);
-    }
-
-    const PidSessionInfosMap& sessionMap() {
-        return mDrmSessionManager->mSessionMap;
-    }
-
-    void testGetLowestPriority() {
-        int pid;
-        int priority;
-        EXPECT_FALSE(mDrmSessionManager->getLowestPriority_l(&pid, &priority));
-
-        addSession();
-        EXPECT_TRUE(mDrmSessionManager->getLowestPriority_l(&pid, &priority));
-
-        EXPECT_EQ(kTestPid1, pid);
-        FakeProcessInfo processInfo;
-        int priority1;
-        processInfo.getPriority(kTestPid1, &priority1);
-        EXPECT_EQ(priority1, priority);
-    }
-
-    void testGetLeastUsedSession() {
-        sp<DrmSessionClientInterface> drm;
-        Vector<uint8_t> sessionId;
-        EXPECT_FALSE(mDrmSessionManager->getLeastUsedSession_l(kTestPid1, &drm, &sessionId));
-
-        addSession();
-
-        EXPECT_TRUE(mDrmSessionManager->getLeastUsedSession_l(kTestPid1, &drm, &sessionId));
-        EXPECT_EQ(mTestDrm1, drm);
-        EXPECT_TRUE(isEqualSessionId(mSessionId1, sessionId));
-
-        EXPECT_TRUE(mDrmSessionManager->getLeastUsedSession_l(kTestPid2, &drm, &sessionId));
-        EXPECT_EQ(mTestDrm2, drm);
-        EXPECT_TRUE(isEqualSessionId(mSessionId2, sessionId));
-
-        // mSessionId2 is no longer the least used session.
-        mDrmSessionManager->useSession(mSessionId2);
-        EXPECT_TRUE(mDrmSessionManager->getLeastUsedSession_l(kTestPid2, &drm, &sessionId));
-        EXPECT_EQ(mTestDrm2, drm);
-        EXPECT_TRUE(isEqualSessionId(mSessionId3, sessionId));
-    }
-
-    sp<DrmSessionManager> mDrmSessionManager;
-    sp<FakeDrm> mTestDrm1;
-    sp<FakeDrm> mTestDrm2;
-    Vector<uint8_t> mSessionId1;
-    Vector<uint8_t> mSessionId2;
-    Vector<uint8_t> mSessionId3;
-};
-
-TEST_F(DrmSessionManagerTest, addSession) {
-    addSession();
-}
-
-TEST_F(DrmSessionManagerTest, useSession) {
-    addSession();
-
-    mDrmSessionManager->useSession(mSessionId1);
-    mDrmSessionManager->useSession(mSessionId3);
-
-    const PidSessionInfosMap& map = sessionMap();
-    const SessionInfos& infos1 = map.valueFor(kTestPid1);
-    const SessionInfos& infos2 = map.valueFor(kTestPid2);
-    ExpectEqSessionInfo(infos1[0], mTestDrm1, mSessionId1, 3);
-    ExpectEqSessionInfo(infos2[1], mTestDrm2, mSessionId3, 4);
-}
-
-TEST_F(DrmSessionManagerTest, removeSession) {
-    addSession();
-
-    mDrmSessionManager->removeSession(mSessionId2);
-
-    const PidSessionInfosMap& map = sessionMap();
-    EXPECT_EQ(2u, map.size());
-    const SessionInfos& infos1 = map.valueFor(kTestPid1);
-    const SessionInfos& infos2 = map.valueFor(kTestPid2);
-    EXPECT_EQ(1u, infos1.size());
-    EXPECT_EQ(1u, infos2.size());
-    // mSessionId2 has been removed.
-    ExpectEqSessionInfo(infos2[0], mTestDrm2, mSessionId3, 2);
-}
-
-TEST_F(DrmSessionManagerTest, removeDrm) {
-    addSession();
-
-    sp<FakeDrm> drm = new FakeDrm;
-    const uint8_t ids[] = {123};
-    Vector<uint8_t> sessionId;
-    GetSessionId(ids, ARRAY_SIZE(ids), &sessionId);
-    mDrmSessionManager->addSession(kTestPid2, drm, sessionId);
-
-    mDrmSessionManager->removeDrm(mTestDrm2);
-
-    const PidSessionInfosMap& map = sessionMap();
-    const SessionInfos& infos2 = map.valueFor(kTestPid2);
-    EXPECT_EQ(1u, infos2.size());
-    // mTestDrm2 has been removed.
-    ExpectEqSessionInfo(infos2[0], drm, sessionId, 3);
-}
-
-TEST_F(DrmSessionManagerTest, reclaimSession) {
-    EXPECT_FALSE(mDrmSessionManager->reclaimSession(kTestPid1));
-    addSession();
-
-    // calling pid priority is too low
-    EXPECT_FALSE(mDrmSessionManager->reclaimSession(50));
-
-    EXPECT_TRUE(mDrmSessionManager->reclaimSession(10));
-    EXPECT_EQ(1u, mTestDrm1->reclaimedSessions().size());
-    EXPECT_TRUE(isEqualSessionId(mSessionId1, mTestDrm1->reclaimedSessions()[0]));
-
-    mDrmSessionManager->removeSession(mSessionId1);
-
-    // add a session from a higher priority process.
-    sp<FakeDrm> drm = new FakeDrm;
-    const uint8_t ids[] = {1, 3, 5};
-    Vector<uint8_t> sessionId;
-    GetSessionId(ids, ARRAY_SIZE(ids), &sessionId);
-    mDrmSessionManager->addSession(15, drm, sessionId);
-
-    EXPECT_TRUE(mDrmSessionManager->reclaimSession(18));
-    EXPECT_EQ(1u, mTestDrm2->reclaimedSessions().size());
-    // mSessionId2 is reclaimed.
-    EXPECT_TRUE(isEqualSessionId(mSessionId2, mTestDrm2->reclaimedSessions()[0]));
-}
-
-TEST_F(DrmSessionManagerTest, getLowestPriority) {
-    testGetLowestPriority();
-}
-
-TEST_F(DrmSessionManagerTest, getLeastUsedSession_l) {
-    testGetLeastUsedSession();
-}
-
-} // namespace android
diff --git a/services/mediaextractor/Android.bp b/services/mediaextractor/Android.bp
new file mode 100644
index 0000000..0c701d7
--- /dev/null
+++ b/services/mediaextractor/Android.bp
@@ -0,0 +1,74 @@
+// service library
+cc_library_shared {
+    name: "libmediaextractorservice",
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+    srcs: ["MediaExtractorService.cpp"],
+
+    shared_libs: [
+        "libmedia",
+        "libstagefright",
+        "libbinder",
+        "libutils",
+    ],
+}
+
+// service executable
+cc_binary {
+    name: "mediaextractor",
+
+    srcs: ["main_extractorservice.cpp"],
+    shared_libs: [
+        "libmedia",
+        "libmediaextractorservice",
+        "libbinder",
+        "libutils",
+        "liblog",
+        "libavservices_minijail",
+    ],
+    target: {
+        android: {
+            product_variables: {
+                malloc_not_svelte: {
+                    // Scudo increases memory footprint, so only enable on
+                    // non-svelte devices.
+                    shared_libs: ["libc_scudo"],
+                },
+            },
+        },
+    },
+    init_rc: ["mediaextractor.rc"],
+
+    include_dirs: ["frameworks/av/media/libmedia"],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+}
+
+prebuilt_etc {
+    name: "mediaextractor.policy",
+    sub_dir: "seccomp_policy",
+    arch: {
+        arm: {
+            src: "seccomp_policy/mediaextractor-arm.policy",
+        },
+        arm64: {
+            src: "seccomp_policy/mediaextractor-arm64.policy",
+        },
+        x86: {
+            src: "seccomp_policy/mediaextractor-x86.policy",
+        },
+        x86_64: {
+            src: "seccomp_policy/mediaextractor-x86_64.policy",
+        },
+    },
+    required: [
+        "crash_dump.policy",
+        "code_coverage.policy",
+    ],
+}
+
diff --git a/services/mediaextractor/Android.mk b/services/mediaextractor/Android.mk
deleted file mode 100644
index 7c6527f..0000000
--- a/services/mediaextractor/Android.mk
+++ /dev/null
@@ -1,54 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-# service library
-include $(CLEAR_VARS)
-LOCAL_CFLAGS := -Wall -Werror
-LOCAL_SRC_FILES := \
-    MediaExtractorService.cpp \
-    MediaExtractorUpdateService.cpp \
-
-LOCAL_SHARED_LIBRARIES := libmedia libstagefright libbinder libutils liblog
-LOCAL_MODULE:= libmediaextractorservice
-include $(BUILD_SHARED_LIBRARY)
-
-
-# service executable
-include $(CLEAR_VARS)
-# seccomp filters are defined for the following architectures:
-LOCAL_REQUIRED_MODULES := crash_dump.policy
-LOCAL_REQUIRED_MODULES_arm := mediaextractor.policy
-LOCAL_REQUIRED_MODULES_arm64 := mediaextractor.policy
-LOCAL_REQUIRED_MODULES_x86 := mediaextractor.policy
-
-# extractor libraries
-LOCAL_REQUIRED_MODULES += \
-    libaacextractor \
-    libamrextractor \
-    libflacextractor \
-    libmidiextractor \
-    libmkvextractor \
-    libmp3extractor \
-    libmp4extractor \
-    libmpeg2extractor \
-    liboggextractor \
-    libwavextractor \
-
-LOCAL_SRC_FILES := main_extractorservice.cpp
-LOCAL_SHARED_LIBRARIES := libmedia libmediaextractorservice libbinder libutils \
-    liblog libbase libicuuc libavservices_minijail
-LOCAL_STATIC_LIBRARIES := libicuandroid_utils
-LOCAL_MODULE:= mediaextractor
-LOCAL_INIT_RC := mediaextractor.rc
-LOCAL_C_INCLUDES := frameworks/av/media/libmedia
-LOCAL_CFLAGS := -Wall -Werror
-include $(BUILD_EXECUTABLE)
-
-# service seccomp filter
-ifeq ($(TARGET_ARCH), $(filter $(TARGET_ARCH), arm arm64 x86 x86_64))
-include $(CLEAR_VARS)
-LOCAL_MODULE := mediaextractor.policy
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/seccomp_policy
-LOCAL_SRC_FILES := seccomp_policy/mediaextractor-$(TARGET_ARCH).policy
-include $(BUILD_PREBUILT)
-endif
diff --git a/services/mediaextractor/MediaExtractorService.cpp b/services/mediaextractor/MediaExtractorService.cpp
index f0f44f5..36e084b 100644
--- a/services/mediaextractor/MediaExtractorService.cpp
+++ b/services/mediaextractor/MediaExtractorService.cpp
@@ -21,7 +21,6 @@
 #include <utils/Vector.h>
 
 #include <media/DataSource.h>
-#include <media/MediaExtractor.h>
 #include <media/stagefright/DataSourceFactory.h>
 #include <media/stagefright/InterfaceUtils.h>
 #include <media/stagefright/MediaExtractorFactory.h>
@@ -30,6 +29,11 @@
 
 namespace android {
 
+MediaExtractorService::MediaExtractorService()
+        : BnMediaExtractorService() {
+    MediaExtractorFactory::LoadExtractors();
+}
+
 sp<IMediaExtractor> MediaExtractorService::makeExtractor(
         const sp<IDataSource> &remoteSource, const char *mime) {
     ALOGV("@@@ MediaExtractorService::makeExtractor for %s", mime);
@@ -55,6 +59,10 @@
     return CreateIDataSourceFromDataSource(source);
 }
 
+std::unordered_set<std::string> MediaExtractorService::getSupportedTypes() {
+    return MediaExtractorFactory::getSupportedTypes();
+}
+
 status_t MediaExtractorService::dump(int fd, const Vector<String16>& args) {
     return MediaExtractorFactory::dump(fd, args) || dumpExtractors(fd, args);
 }
diff --git a/services/mediaextractor/MediaExtractorService.h b/services/mediaextractor/MediaExtractorService.h
index 9df3ecd..c9cebcf 100644
--- a/services/mediaextractor/MediaExtractorService.h
+++ b/services/mediaextractor/MediaExtractorService.h
@@ -27,7 +27,7 @@
 {
     friend class BinderService<MediaExtractorService>;    // for MediaExtractorService()
 public:
-    MediaExtractorService() : BnMediaExtractorService() { }
+    MediaExtractorService();
     virtual ~MediaExtractorService() { }
     virtual void onFirstRef() { }
 
@@ -37,6 +37,8 @@
 
     virtual sp<IDataSource> makeIDataSource(int fd, int64_t offset, int64_t length);
 
+    virtual std::unordered_set<std::string> getSupportedTypes();
+
     virtual status_t    dump(int fd, const Vector<String16>& args);
 
     virtual status_t    onTransact(uint32_t code, const Parcel& data, Parcel* reply,
diff --git a/services/mediaextractor/MediaExtractorUpdateService.cpp b/services/mediaextractor/MediaExtractorUpdateService.cpp
deleted file mode 100644
index 473a698..0000000
--- a/services/mediaextractor/MediaExtractorUpdateService.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "MediaExtractorUpdateService"
-#define LOG_NDEBUG 0
-#include <utils/Log.h>
-
-#include <media/stagefright/MediaExtractorFactory.h>
-
-#include "MediaExtractorUpdateService.h"
-
-namespace android {
-namespace media {
-
-binder::Status MediaExtractorUpdateService::loadPlugins(const ::std::string& apkPath) {
-    ALOGV("loadPlugins %s", apkPath.c_str());
-    MediaExtractorFactory::LoadPlugins(apkPath);
-    return binder::Status::ok();
-}
-
-}   // namespace media
-}   // namespace android
diff --git a/services/mediaextractor/MediaExtractorUpdateService.h b/services/mediaextractor/MediaExtractorUpdateService.h
deleted file mode 100644
index 4115f6d..0000000
--- a/services/mediaextractor/MediaExtractorUpdateService.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_MEDIA_EXTRACTOR_UPDATE_SERVICE_H
-#define ANDROID_MEDIA_EXTRACTOR_UPDATE_SERVICE_H
-
-#include <binder/BinderService.h>
-#include <android/media/BnMediaExtractorUpdateService.h>
-
-namespace android {
-namespace media {
-
-class MediaExtractorUpdateService
-    : public BinderService<MediaExtractorUpdateService>, public BnMediaExtractorUpdateService
-{
-    friend class BinderService<MediaExtractorUpdateService>;
-public:
-    MediaExtractorUpdateService() : BnMediaExtractorUpdateService() { }
-    virtual ~MediaExtractorUpdateService() { }
-    static const char* getServiceName() { return "media.extractor.update"; }
-    binder::Status loadPlugins(const ::std::string& apkPath);
-};
-
-}   // namespace media
-}   // namespace android
-
-#endif  // ANDROID_MEDIA_EXTRACTOR_UPDATE_SERVICE_H
diff --git a/services/mediaextractor/main_extractorservice.cpp b/services/mediaextractor/main_extractorservice.cpp
index 8d3359a..3c4125b 100644
--- a/services/mediaextractor/main_extractorservice.cpp
+++ b/services/mediaextractor/main_extractorservice.cpp
@@ -29,16 +29,14 @@
 #include <utils/misc.h>
 
 // from LOCAL_C_INCLUDES
-#include "IcuUtils.h"
 #include "MediaExtractorService.h"
-#include "MediaExtractorUpdateService.h"
 #include "MediaUtils.h"
 #include "minijail.h"
 
 using namespace android;
 
 static const char kSystemSeccompPolicyPath[] =
-        "/system/etc/seccomp_policy/mediaextractor.policy";
+        "/apex/com.android.media/etc/seccomp_policy/mediaextractor.policy";
 static const char kVendorSeccompPolicyPath[] =
         "/vendor/etc/seccomp_policy/mediaextractor.policy";
 
@@ -59,18 +57,11 @@
 
     SetUpMinijail(kSystemSeccompPolicyPath, kVendorSeccompPolicyPath);
 
-    InitializeIcuOrDie();
-
     strcpy(argv[0], "media.extractor");
     sp<ProcessState> proc(ProcessState::self());
     sp<IServiceManager> sm = defaultServiceManager();
     MediaExtractorService::instantiate();
 
-    std::string value = base::GetProperty("ro.build.type", "unknown");
-    if (value == "userdebug" || value == "eng") {
-        media::MediaExtractorUpdateService::instantiate();
-    }
-
     ProcessState::self()->startThreadPool();
     IPCThreadState::self()->joinThreadPool();
 }
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy b/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
index 87018ed..38f9be6 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
@@ -14,6 +14,7 @@
 setpriority: 1
 sigaltstack: 1
 openat: 1
+open: 1
 clone: 1
 read: 1
 clock_gettime: 1
@@ -49,3 +50,4 @@
 _llseek: 1
 
 @include /system/etc/seccomp_policy/crash_dump.arm.policy
+@include /system/etc/seccomp_policy/code_coverage.arm.policy
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy b/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy
index d70e27b..8fd8787 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy
@@ -40,4 +40,8 @@
 pread64: 1
 mremap: 1
 
+# Required by Sanitizers
+sched_yield: 1
+
 @include /system/etc/seccomp_policy/crash_dump.arm64.policy
+@include /system/etc/seccomp_policy/code_coverage.arm64.policy
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy b/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy
index d739ba1..05915d1 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy
@@ -11,6 +11,7 @@
 mmap2: 1
 madvise: 1
 openat: 1
+open: 1
 clock_gettime: 1
 writev: 1
 brk: 1
@@ -56,3 +57,4 @@
 gettid: 1
 
 @include /system/etc/seccomp_policy/crash_dump.x86.policy
+@include /system/etc/seccomp_policy/code_coverage.x86.policy
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy b/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy
old mode 100755
new mode 100644
index 63c7780..e6a55d0
--- a/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy
@@ -11,6 +11,7 @@
 mmap: 1
 madvise: 1
 openat: 1
+open: 1
 clock_gettime: 1
 writev: 1
 brk: 1
@@ -21,6 +22,8 @@
 getuid: 1
 setpriority: 1
 sigaltstack: 1
+fstat: 1
+fstatfs: 1
 newfstatat: 1
 restart_syscall: 1
 exit: 1
@@ -30,28 +33,22 @@
 sched_setscheduler: 1
 getrlimit: 1
 nanosleep: 1
+getrandom: 1
+
+# for dynamically loading extractors
+getdents64: 1
+readlinkat: 1
+pread64: 1
+mremap: 1
 
 # for FileSource
 readlinkat: 1
 
-# for attaching to debuggerd on process crash
-tgkill: 1
-socket: arg0 == 1
-connect: 1
-fcntl: 1
-rt_sigprocmask: 1
-rt_sigaction: 1
-rt_tgsigqueueinfo: 1
-geteuid: 1
-getgid: 1
-getegid: 1
-getgroups: 1
-getdents64: 1
-pipe2: 1
-ppoll: 1
-
 # Required by AddressSanitizer
 gettid: 1
 sched_yield: 1
 getpid: 1
 gettid: 1
+
+@include /system/etc/seccomp_policy/crash_dump.x86_64.policy
+@include /system/etc/seccomp_policy/code_coverage.x86_64.policy
diff --git a/services/medialog/Android.bp b/services/medialog/Android.bp
index 29e6dfc..bee5d25 100644
--- a/services/medialog/Android.bp
+++ b/services/medialog/Android.bp
@@ -10,7 +10,7 @@
         "libaudioutils",
         "libbinder",
         "liblog",
-        "libnbaio",
+        "libmediautils",
         "libnblog",
         "libutils",
     ],
diff --git a/services/medialog/MediaLogService.cpp b/services/medialog/MediaLogService.cpp
index 1be5544..902af66 100644
--- a/services/medialog/MediaLogService.cpp
+++ b/services/medialog/MediaLogService.cpp
@@ -20,8 +20,9 @@
 #include <sys/mman.h>
 #include <utils/Log.h>
 #include <binder/PermissionCache.h>
+#include <media/nblog/Merger.h>
 #include <media/nblog/NBLog.h>
-#include <private/android_filesystem_config.h>
+#include <mediautils/ServiceUtilities.h>
 #include "MediaLogService.h"
 
 namespace android {
@@ -53,27 +54,28 @@
 
 void MediaLogService::registerWriter(const sp<IMemory>& shared, size_t size, const char *name)
 {
-    if (IPCThreadState::self()->getCallingUid() != AID_AUDIOSERVER || shared == 0 ||
+    if (!isAudioServerOrMediaServerUid(IPCThreadState::self()->getCallingUid()) || shared == 0 ||
             size < kMinSize || size > kMaxSize || name == NULL ||
             shared->size() < NBLog::Timeline::sharedSize(size)) {
         return;
     }
-    sp<NBLog::Reader> reader(new NBLog::Reader(shared, size));
-    NBLog::NamedReader namedReader(reader, name);
+    sp<NBLog::Reader> reader(new NBLog::Reader(shared, size, name)); // Reader handled by merger
+    sp<NBLog::DumpReader> dumpReader(new NBLog::DumpReader(shared, size, name)); // for dumpsys
     Mutex::Autolock _l(mLock);
-    mNamedReaders.add(namedReader);
-    mMerger.addReader(namedReader);
+    mDumpReaders.add(dumpReader);
+    mMerger.addReader(reader);
 }
 
 void MediaLogService::unregisterWriter(const sp<IMemory>& shared)
 {
-    if (IPCThreadState::self()->getCallingUid() != AID_AUDIOSERVER || shared == 0) {
+    if (!isAudioServerOrMediaServerUid(IPCThreadState::self()->getCallingUid()) || shared == 0) {
         return;
     }
     Mutex::Autolock _l(mLock);
-    for (size_t i = 0; i < mNamedReaders.size(); ) {
-        if (mNamedReaders[i].reader()->isIMemory(shared)) {
-            mNamedReaders.removeAt(i);
+    for (size_t i = 0; i < mDumpReaders.size(); ) {
+        if (mDumpReaders[i]->isIMemory(shared)) {
+            mDumpReaders.removeAt(i);
+            // TODO mMerger.removeReaders(shared)
         } else {
             i++;
         }
@@ -95,10 +97,8 @@
 
 status_t MediaLogService::dump(int fd, const Vector<String16>& args __unused)
 {
-    // FIXME merge with similar but not identical code at services/audioflinger/ServiceUtilities.cpp
-    static const String16 sDump("android.permission.DUMP");
-    if (!(IPCThreadState::self()->getCallingUid() == AID_AUDIOSERVER ||
-            PermissionCache::checkCallingPermission(sDump))) {
+    if (!(isAudioServerOrMediaServerUid(IPCThreadState::self()->getCallingUid())
+            || dumpAllowed())) {
         dprintf(fd, "Permission Denial: can't dump media.log from pid=%d, uid=%d\n",
                 IPCThreadState::self()->getCallingPid(),
                 IPCThreadState::self()->getCallingUid());
@@ -108,7 +108,7 @@
     if (args.size() > 0) {
         const String8 arg0(args[0]);
         if (!strcmp(arg0.string(), "-r")) {
-            // needed because mNamedReaders is protected by mLock
+            // needed because mReaders is protected by mLock
             bool locked = dumpTryLock(mLock);
 
             // failed to lock - MediaLogService is probably deadlocked
@@ -119,21 +119,22 @@
                 } else {
                     ALOGW("%s:", result.string());
                 }
-                // TODO should we instead proceed to mMergeReader.dump? does it need lock?
                 return NO_ERROR;
             }
 
-            for (const auto& namedReader : mNamedReaders) {
+            for (const auto &dumpReader : mDumpReaders) {
                 if (fd >= 0) {
-                    dprintf(fd, "\n%s:\n", namedReader.name());
+                    dprintf(fd, "\n%s:\n", dumpReader->name().c_str());
+                    dumpReader->dump(fd, 0 /*indent*/);
                 } else {
-                    ALOGI("%s:", namedReader.name());
+                    ALOGI("%s:", dumpReader->name().c_str());
                 }
             }
             mLock.unlock();
+        } else {
+            mMergeReader.dump(fd, args);
         }
     }
-    mMergeReader.dump(fd);
     return NO_ERROR;
 }
 
diff --git a/services/medialog/MediaLogService.h b/services/medialog/MediaLogService.h
index c945d1f..21df898 100644
--- a/services/medialog/MediaLogService.h
+++ b/services/medialog/MediaLogService.h
@@ -19,6 +19,7 @@
 
 #include <binder/BinderService.h>
 #include <media/IMediaLogService.h>
+#include <media/nblog/Merger.h>
 #include <media/nblog/NBLog.h>
 
 namespace android {
@@ -55,7 +56,7 @@
 
     Mutex               mLock;
 
-    Vector<NBLog::NamedReader> mNamedReaders;   // protected by mLock
+    Vector<sp<NBLog::DumpReader>> mDumpReaders;   // protected by mLock
 
     // FIXME Need comments on all of these, especially about locking
     NBLog::Shared *mMergerShared;
diff --git a/services/mediaresourcemanager/Android.bp b/services/mediaresourcemanager/Android.bp
new file mode 100644
index 0000000..f3339a0
--- /dev/null
+++ b/services/mediaresourcemanager/Android.bp
@@ -0,0 +1,26 @@
+
+
+cc_library_shared {
+    name: "libresourcemanagerservice",
+
+    srcs: [
+        "ResourceManagerService.cpp",
+        "ServiceLog.cpp",
+    ],
+
+    shared_libs: [
+        "libmedia",
+        "libmediautils",
+        "libbinder",
+        "libutils",
+        "liblog",
+    ],
+
+    include_dirs: ["frameworks/av/include"],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+
+}
diff --git a/services/mediaresourcemanager/Android.mk b/services/mediaresourcemanager/Android.mk
deleted file mode 100644
index 5823036..0000000
--- a/services/mediaresourcemanager/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := ResourceManagerService.cpp ServiceLog.cpp
-
-LOCAL_SHARED_LIBRARIES := libmedia libmediautils libbinder libutils liblog
-
-LOCAL_MODULE:= libresourcemanagerservice
-
-LOCAL_32_BIT_ONLY := true
-
-LOCAL_C_INCLUDES += \
-    frameworks/av/include
-
-LOCAL_CFLAGS += -Werror -Wall
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/services/mediaresourcemanager/test/Android.bp b/services/mediaresourcemanager/test/Android.bp
new file mode 100644
index 0000000..70e8833
--- /dev/null
+++ b/services/mediaresourcemanager/test/Android.bp
@@ -0,0 +1,41 @@
+// Build the unit tests.
+cc_test {
+    name: "ResourceManagerService_test",
+    srcs: ["ResourceManagerService_test.cpp"],
+    shared_libs: [
+        "libbinder",
+        "liblog",
+        "libmedia",
+        "libresourcemanagerservice",
+        "libutils",
+    ],
+    include_dirs: [
+        "frameworks/av/include",
+        "frameworks/av/services/mediaresourcemanager",
+    ],
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+    compile_multilib: "32",
+}
+
+cc_test {
+    name: "ServiceLog_test",
+    srcs: ["ServiceLog_test.cpp"],
+    shared_libs: [
+        "liblog",
+        "libmedia",
+        "libresourcemanagerservice",
+        "libutils",
+    ],
+    include_dirs: [
+        "frameworks/av/include",
+        "frameworks/av/services/mediaresourcemanager",
+    ],
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+    compile_multilib: "32",
+}
diff --git a/services/mediaresourcemanager/test/Android.mk b/services/mediaresourcemanager/test/Android.mk
deleted file mode 100644
index 6abcf92..0000000
--- a/services/mediaresourcemanager/test/Android.mk
+++ /dev/null
@@ -1,52 +0,0 @@
-# Build the unit tests.
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := ResourceManagerService_test
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := \
-  ResourceManagerService_test.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
-  libbinder \
-  liblog \
-  libmedia \
-  libresourcemanagerservice \
-  libutils \
-
-LOCAL_C_INCLUDES := \
-  frameworks/av/include \
-  frameworks/av/services/mediaresourcemanager \
-
-LOCAL_CFLAGS += -Werror -Wall
-
-LOCAL_32_BIT_ONLY := true
-
-include $(BUILD_NATIVE_TEST)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := ServiceLog_test
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := \
-  ServiceLog_test.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
-  liblog \
-  libmedia \
-  libresourcemanagerservice \
-  libutils \
-
-LOCAL_C_INCLUDES := \
-  frameworks/av/include \
-  frameworks/av/services/mediaresourcemanager \
-
-LOCAL_CFLAGS += -Werror -Wall
-
-LOCAL_32_BIT_ONLY := true
-
-include $(BUILD_NATIVE_TEST)
diff --git a/services/oboeservice/AAudioClientTracker.cpp b/services/oboeservice/AAudioClientTracker.cpp
index 7264a9b..8572561 100644
--- a/services/oboeservice/AAudioClientTracker.cpp
+++ b/services/oboeservice/AAudioClientTracker.cpp
@@ -67,6 +67,12 @@
                                          const sp<IAAudioClient>& client) {
     ALOGV("registerClient(), calling pid = %d, getpid() = %d\n", pid, getpid());
 
+    if (client.get() == nullptr) {
+        ALOGE("AAudioClientTracker::%s() client is NULL!", __func__);
+        android_errorWriteLog(0x534e4554, "116230453");
+        return AAUDIO_ERROR_NULL;
+    }
+
     std::lock_guard<std::mutex> lock(mLock);
     if (mNotificationClients.count(pid) == 0) {
         sp<NotificationClient> notificationClient = new NotificationClient(pid);
@@ -101,7 +107,7 @@
 aaudio_result_t
 AAudioClientTracker::registerClientStream(pid_t pid, sp<AAudioServiceStreamBase> serviceStream) {
     aaudio_result_t result = AAUDIO_OK;
-    ALOGV("registerClientStream(%d, %p)\n", pid, serviceStream.get());
+    ALOGV("registerClientStream(%d,)\n", pid);
     std::lock_guard<std::mutex> lock(mLock);
     sp<NotificationClient> notificationClient = mNotificationClients[pid];
     if (notificationClient == 0) {
@@ -118,27 +124,23 @@
 aaudio_result_t
 AAudioClientTracker::unregisterClientStream(pid_t pid,
                                             sp<AAudioServiceStreamBase> serviceStream) {
-    ALOGV("unregisterClientStream(%d, %p)\n", pid, serviceStream.get());
+    ALOGV("unregisterClientStream(%d,)\n", pid);
     std::lock_guard<std::mutex> lock(mLock);
     auto it = mNotificationClients.find(pid);
     if (it != mNotificationClients.end()) {
-        ALOGV("unregisterClientStream(%d, %p) found NotificationClient\n",
-              pid, serviceStream.get());
+        ALOGV("unregisterClientStream(%d,) found NotificationClient\n", pid);
         it->second->unregisterClientStream(serviceStream);
     } else {
-        ALOGE("unregisterClientStream(%d, %p) missing NotificationClient\n",
-              pid, serviceStream.get());
+        ALOGE("unregisterClientStream(%d,) missing NotificationClient\n", pid);
     }
     return AAUDIO_OK;
 }
 
 AAudioClientTracker::NotificationClient::NotificationClient(pid_t pid)
         : mProcessId(pid) {
-    //ALOGD("NotificationClient(%d) created %p\n", pid, this);
 }
 
 AAudioClientTracker::NotificationClient::~NotificationClient() {
-    //ALOGD("~NotificationClient() destroyed %p\n", this);
 }
 
 int32_t AAudioClientTracker::NotificationClient::getStreamCount() {
diff --git a/services/oboeservice/AAudioEndpointManager.cpp b/services/oboeservice/AAudioEndpointManager.cpp
index 04fee13..a1fc0ea 100644
--- a/services/oboeservice/AAudioEndpointManager.cpp
+++ b/services/oboeservice/AAudioEndpointManager.cpp
@@ -108,7 +108,7 @@
         const AAudioStreamConfiguration &configuration) {
     sp<AAudioServiceEndpoint> endpoint;
     mExclusiveSearchCount++;
-    for (const auto ep : mExclusiveStreams) {
+    for (const auto& ep : mExclusiveStreams) {
         if (ep->matches(configuration)) {
             mExclusiveFoundCount++;
             endpoint = ep;
@@ -126,7 +126,7 @@
         const AAudioStreamConfiguration &configuration) {
     sp<AAudioServiceEndpointShared> endpoint;
     mSharedSearchCount++;
-    for (const auto ep  : mSharedStreams) {
+    for (const auto& ep  : mSharedStreams) {
         if (ep->matches(configuration)) {
             mSharedFoundCount++;
             endpoint = ep;
@@ -140,9 +140,8 @@
 }
 
 sp<AAudioServiceEndpoint> AAudioEndpointManager::openEndpoint(AAudioService &audioService,
-                                        const aaudio::AAudioStreamRequest &request,
-                                        aaudio_sharing_mode_t sharingMode) {
-    if (sharingMode == AAUDIO_SHARING_MODE_EXCLUSIVE) {
+                                        const aaudio::AAudioStreamRequest &request) {
+    if (request.getConstantConfiguration().getSharingMode() == AAUDIO_SHARING_MODE_EXCLUSIVE) {
         return openExclusiveEndpoint(audioService, request);
     } else {
         return openSharedEndpoint(audioService, request);
@@ -173,7 +172,7 @@
 
         aaudio_result_t result = endpoint->open(request);
         if (result != AAUDIO_OK) {
-            ALOGE("openExclusiveEndpoint(), open failed");
+            ALOGV("openExclusiveEndpoint(), open failed");
             endpoint.clear();
         } else {
             mExclusiveStreams.push_back(endpointMMap);
diff --git a/services/oboeservice/AAudioEndpointManager.h b/services/oboeservice/AAudioEndpointManager.h
index 193bdee..ba17853 100644
--- a/services/oboeservice/AAudioEndpointManager.h
+++ b/services/oboeservice/AAudioEndpointManager.h
@@ -56,8 +56,7 @@
      * @return endpoint or null
      */
     android::sp<AAudioServiceEndpoint> openEndpoint(android::AAudioService &audioService,
-                                        const aaudio::AAudioStreamRequest &request,
-                                        aaudio_sharing_mode_t sharingMode);
+                                        const aaudio::AAudioStreamRequest &request);
 
     void closeEndpoint(android::sp<AAudioServiceEndpoint> serviceEndpoint);
 
diff --git a/services/oboeservice/AAudioMixer.cpp b/services/oboeservice/AAudioMixer.cpp
index b031888..1c03b7f 100644
--- a/services/oboeservice/AAudioMixer.cpp
+++ b/services/oboeservice/AAudioMixer.cpp
@@ -99,7 +99,7 @@
         }
         partIndex++;
     }
-    fifo->getFifoControllerBase()->advanceReadIndex(framesDesired);
+    fifo->advanceReadIndex(framesDesired);
 
 #if AAUDIO_MIXER_ATRACE_ENABLED
     ATRACE_END();
diff --git a/services/oboeservice/AAudioService.cpp b/services/oboeservice/AAudioService.cpp
index 6a72e5b..e6a8375 100644
--- a/services/oboeservice/AAudioService.cpp
+++ b/services/oboeservice/AAudioService.cpp
@@ -24,6 +24,7 @@
 
 #include <aaudio/AAudio.h>
 #include <mediautils/SchedulingPolicyService.h>
+#include <mediautils/ServiceUtilities.h>
 #include <utils/String16.h>
 
 #include "binding/AAudioServiceMessage.h"
@@ -33,7 +34,6 @@
 #include "AAudioServiceStreamMMAP.h"
 #include "AAudioServiceStreamShared.h"
 #include "binding/IAAudioService.h"
-#include "ServiceUtilities.h"
 
 using namespace android;
 using namespace aaudio;
@@ -58,7 +58,7 @@
 
     if (!dumpAllowed()) {
         std::stringstream ss;
-        ss << "Permission denial: can't dump AAudioService from pid="
+        ss << "Permission Denial: can't dump AAudioService from pid="
                 << IPCThreadState::self()->getCallingPid() << ", uid="
                 << IPCThreadState::self()->getCallingUid() << "\n";
         result = ss.str();
@@ -118,21 +118,24 @@
         }
     }
 
-    // if SHARED requested or if EXCLUSIVE failed
-    if (sharingMode == AAUDIO_SHARING_MODE_SHARED
-         || (serviceStream.get() == nullptr && !sharingModeMatchRequired)) {
+    // Try SHARED if SHARED requested or if EXCLUSIVE failed.
+    if (sharingMode == AAUDIO_SHARING_MODE_SHARED) {
         serviceStream =  new AAudioServiceStreamShared(*this);
         result = serviceStream->open(request);
+    } else if (serviceStream.get() == nullptr && !sharingModeMatchRequired) {
+        aaudio::AAudioStreamRequest modifiedRequest = request;
+        // Overwrite the original EXCLUSIVE mode with SHARED.
+        modifiedRequest.getConfiguration().setSharingMode(AAUDIO_SHARING_MODE_SHARED);
+        serviceStream =  new AAudioServiceStreamShared(*this);
+        result = serviceStream->open(modifiedRequest);
     }
 
     if (result != AAUDIO_OK) {
         serviceStream.clear();
-        ALOGE("openStream(): failed, return %d = %s",
-              result, AAudio_convertResultToText(result));
         return result;
     } else {
         aaudio_handle_t handle = mStreamTracker.addStreamForHandle(serviceStream.get());
-        ALOGD("openStream(): handle = 0x%08X", handle);
+        ALOGV("openStream(): handle = 0x%08X", handle);
         serviceStream->setHandle(handle);
         pid_t pid = request.getProcessId();
         AAudioClientTracker::getInstance().registerClientStream(pid, serviceStream);
diff --git a/services/oboeservice/AAudioServiceEndpoint.cpp b/services/oboeservice/AAudioServiceEndpoint.cpp
index 0349034..553754e 100644
--- a/services/oboeservice/AAudioServiceEndpoint.cpp
+++ b/services/oboeservice/AAudioServiceEndpoint.cpp
@@ -38,10 +38,6 @@
 using namespace android;  // TODO just import names needed
 using namespace aaudio;   // TODO just import names needed
 
-AAudioServiceEndpoint::~AAudioServiceEndpoint() {
-    ALOGD("%s(%p) destroyed", __func__, this);
-}
-
 std::string AAudioServiceEndpoint::dump() const {
     std::stringstream result;
 
@@ -59,6 +55,7 @@
     result << "    Device Id:            " << getDeviceId() << "\n";
     result << "    Sample Rate:          " << getSampleRate() << "\n";
     result << "    Channel Count:        " << getSamplesPerFrame() << "\n";
+    result << "    Format:               " << getFormat() << "\n";
     result << "    Frames Per Burst:     " << mFramesPerBurst << "\n";
     result << "    Usage:                " << getUsage() << "\n";
     result << "    ContentType:          " << getContentType() << "\n";
@@ -68,7 +65,7 @@
     result << "    Connected:            " << mConnected.load() << "\n";
     result << "    Registered Streams:" << "\n";
     result << AAudioServiceStreamShared::dumpHeader() << "\n";
-    for (const auto stream : mRegisteredStreams) {
+    for (const auto& stream : mRegisteredStreams) {
         result << stream->dump() << "\n";
     }
 
@@ -81,7 +78,7 @@
 // @return true if stream found
 bool AAudioServiceEndpoint::isStreamRegistered(audio_port_handle_t portHandle) {
     std::lock_guard<std::mutex> lock(mLockStreams);
-    for (const auto stream : mRegisteredStreams) {
+    for (const auto& stream : mRegisteredStreams) {
         if (stream->getPortHandle() == portHandle) {
             return true;
         }
@@ -92,8 +89,9 @@
 void AAudioServiceEndpoint::disconnectRegisteredStreams() {
     std::lock_guard<std::mutex> lock(mLockStreams);
     mConnected.store(false);
-    for (const auto stream : mRegisteredStreams) {
-        ALOGD("disconnectRegisteredStreams() stop and disconnect %p", stream.get());
+    for (const auto& stream : mRegisteredStreams) {
+        ALOGD("disconnectRegisteredStreams() stop and disconnect port %d",
+              stream->getPortHandle());
         stream->stop();
         stream->disconnect();
     }
diff --git a/services/oboeservice/AAudioServiceEndpoint.h b/services/oboeservice/AAudioServiceEndpoint.h
index 253f290..a2f66a5 100644
--- a/services/oboeservice/AAudioServiceEndpoint.h
+++ b/services/oboeservice/AAudioServiceEndpoint.h
@@ -41,7 +41,7 @@
         , public AAudioStreamParameters {
 public:
 
-    virtual ~AAudioServiceEndpoint();
+    virtual ~AAudioServiceEndpoint() = default;
 
     virtual std::string dump() const;
 
@@ -61,7 +61,7 @@
 
     virtual aaudio_result_t startClient(const android::AudioClient& client,
                                         audio_port_handle_t *clientHandle) {
-        ALOGD("AAudioServiceEndpoint::startClient(%p, ...) AAUDIO_ERROR_UNAVAILABLE", &client);
+        ALOGD("AAudioServiceEndpoint::startClient(...) AAUDIO_ERROR_UNAVAILABLE");
         return AAUDIO_ERROR_UNAVAILABLE;
     }
 
@@ -77,6 +77,13 @@
      */
     virtual aaudio_result_t getFreeRunningPosition(int64_t *positionFrames, int64_t *timeNanos) = 0;
 
+    /**
+     * Set time that the associated frame was presented to the hardware.
+     *
+     * @param positionFrames receive position, input value is ignored
+     * @param timeNanos receive time, input value is ignored
+     * @return AAUDIO_OK or AAUDIO_ERROR_UNAVAILABLE or other negative error
+     */
     virtual aaudio_result_t getTimestamp(int64_t *positionFrames, int64_t *timeNanos) = 0;
 
     int32_t getFramesPerBurst() const {
@@ -114,7 +121,7 @@
     mutable std::mutex       mLockStreams;
     std::vector<android::sp<AAudioServiceStreamBase>> mRegisteredStreams;
 
-    SimpleDoubleBuffer<Timestamp>  mAtomicTimestamp;
+    SimpleDoubleBuffer<Timestamp>  mAtomicEndpointTimestamp;
 
     android::AudioClient     mMmapClient;   // set in open, used in open and startStream
 
diff --git a/services/oboeservice/AAudioServiceEndpointCapture.cpp b/services/oboeservice/AAudioServiceEndpointCapture.cpp
index efac788..37d105b 100644
--- a/services/oboeservice/AAudioServiceEndpointCapture.cpp
+++ b/services/oboeservice/AAudioServiceEndpointCapture.cpp
@@ -81,9 +81,10 @@
         { // brackets are for lock_guard
 
             std::lock_guard <std::mutex> lock(mLockStreams);
-            for (const auto clientStream : mRegisteredStreams) {
-                if (clientStream->isRunning()) {
+            for (const auto& clientStream : mRegisteredStreams) {
+                if (clientStream->isRunning() && !clientStream->isSuspended()) {
                     int64_t clientFramesWritten = 0;
+
                     sp<AAudioServiceStreamShared> streamShared =
                             static_cast<AAudioServiceStreamShared *>(clientStream.get());
 
@@ -102,7 +103,7 @@
                             streamShared->setTimestampPositionOffset(positionOffset);
 
                             // Is the buffer too full to write a burst?
-                            if (fifo->getFifoControllerBase()->getEmptyFramesAvailable() <
+                            if (fifo->getEmptyFramesAvailable() <
                                     getFramesPerBurst()) {
                                 streamShared->incrementXRunCount();
                             } else {
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.cpp b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
index f9e21fb..b05baa4 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.cpp
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
@@ -77,9 +77,6 @@
     audio_config_base_t config;
     audio_port_handle_t deviceId;
 
-    int32_t burstMinMicros = AAudioProperty_getHardwareBurstMinMicros();
-    int32_t burstMicros = 0;
-
     copyFrom(request.getConstantConfiguration());
 
     aaudio_direction_t direction = getDirection();
@@ -93,16 +90,16 @@
     const audio_source_t source = (direction == AAUDIO_DIRECTION_INPUT)
             ? AAudioConvert_inputPresetToAudioSource(getInputPreset())
             : AUDIO_SOURCE_DEFAULT;
+    const audio_flags_mask_t flags = AUDIO_FLAG_LOW_LATENCY |
+            AAudioConvert_allowCapturePolicyToAudioFlagsMask(getAllowedCapturePolicy());
 
     const audio_attributes_t attributes = {
             .content_type = contentType,
             .usage = usage,
             .source = source,
-            .flags = AUDIO_FLAG_LOW_LATENCY,
+            .flags = flags,
             .tags = ""
     };
-    ALOGD("%s(%p) MMAP attributes.usage = %d, content_type = %d, source = %d",
-          __func__, this, attributes.usage, attributes.content_type, attributes.source);
 
     mMmapClient.clientUid = request.getUserId();
     mMmapClient.clientPid = request.getProcessId();
@@ -111,11 +108,11 @@
     mRequestedDeviceId = deviceId = getDeviceId();
 
     // Fill in config
-    aaudio_format_t aaudioFormat = getFormat();
-    if (aaudioFormat == AAUDIO_UNSPECIFIED || aaudioFormat == AAUDIO_FORMAT_PCM_FLOAT) {
-        aaudioFormat = AAUDIO_FORMAT_PCM_I16;
+    audio_format_t audioFormat = getFormat();
+    if (audioFormat == AUDIO_FORMAT_DEFAULT || audioFormat == AUDIO_FORMAT_PCM_FLOAT) {
+        audioFormat = AUDIO_FORMAT_PCM_16_BIT;
     }
-    config.format = AAudioConvert_aaudioToAndroidDataFormat(aaudioFormat);
+    config.format = audioFormat;
 
     int32_t aaudioSampleRate = getSampleRate();
     if (aaudioSampleRate == AAUDIO_UNSPECIFIED) {
@@ -163,12 +160,14 @@
     ALOGD("%s() mMapClient.uid = %d, pid = %d => portHandle = %d\n",
           __func__, mMmapClient.clientUid,  mMmapClient.clientPid, mPortHandle);
     if (status != OK) {
-        ALOGE("%s() openMmapStream() returned status %d",  __func__, status);
+        // This can happen if the resource is busy or the config does
+        // not match the hardware.
+        ALOGD("%s() - openMmapStream() returned status %d",  __func__, status);
         return AAUDIO_ERROR_UNAVAILABLE;
     }
 
     if (deviceId == AAUDIO_UNSPECIFIED) {
-        ALOGW("%s() openMmapStream() failed to set deviceId", __func__);
+        ALOGW("%s() - openMmapStream() failed to set deviceId", __func__);
     }
     setDeviceId(deviceId);
 
@@ -189,34 +188,27 @@
         minSizeFrames = AAUDIO_BUFFER_CAPACITY_MIN;
     }
     status = mMmapStream->createMmapBuffer(minSizeFrames, &mMmapBufferinfo);
+    bool isBufferShareable = mMmapBufferinfo.flags & AUDIO_MMAP_APPLICATION_SHAREABLE;
     if (status != OK) {
         ALOGE("%s() - createMmapBuffer() failed with status %d %s",
               __func__, status, strerror(-status));
         result = AAUDIO_ERROR_UNAVAILABLE;
         goto error;
     } else {
-        ALOGD("%s() createMmapBuffer() returned = %d, buffer_size = %d, burst_size %d"
+        ALOGD("%s() createMmapBuffer() buffer_size = %d fr, burst_size %d fr"
                       ", Sharable FD: %s",
-              __func__, status,
-              abs(mMmapBufferinfo.buffer_size_frames),
+              __func__,
+              mMmapBufferinfo.buffer_size_frames,
               mMmapBufferinfo.burst_size_frames,
-              mMmapBufferinfo.buffer_size_frames < 0 ? "Yes" : "No");
+              isBufferShareable ? "Yes" : "No");
     }
 
     setBufferCapacity(mMmapBufferinfo.buffer_size_frames);
-    // The audio HAL indicates if the shared memory fd can be shared outside of audioserver
-    // by returning a negative buffer size
-    if (getBufferCapacity() < 0) {
-        // Exclusive mode can be used by client or service.
-        setBufferCapacity(-getBufferCapacity());
-    } else {
+    if (!isBufferShareable) {
         // Exclusive mode can only be used by the service because the FD cannot be shared.
         uid_t audioServiceUid = getuid();
         if ((mMmapClient.clientUid != audioServiceUid) &&
             getSharingMode() == AAUDIO_SHARING_MODE_EXCLUSIVE) {
-            // Fallback is handled by caller but indicate what is possible in case
-            // this is used in the future
-            setSharingMode(AAUDIO_SHARING_MODE_SHARED);
             ALOGW("%s() - exclusive FD cannot be used by client", __func__);
             result = AAUDIO_ERROR_UNAVAILABLE;
             goto error;
@@ -237,26 +229,16 @@
         goto error;
     }
     mFramesPerBurst = mMmapBufferinfo.burst_size_frames;
-    setFormat(AAudioConvert_androidToAAudioDataFormat(config.format));
+    setFormat(config.format);
     setSampleRate(config.sample_rate);
 
-    // Scale up the burst size to meet the minimum equivalent in microseconds.
-    // This is to avoid waking the CPU too often when the HW burst is very small
-    // or at high sample rates.
-    do {
-        if (burstMicros > 0) {  // skip first loop
-            mFramesPerBurst *= 2;
-        }
-        burstMicros = mFramesPerBurst * static_cast<int64_t>(1000000) / getSampleRate();
-    } while (burstMicros < burstMinMicros);
-
-    ALOGD("%s() original burst = %d, minMicros = %d, to burst = %d\n",
-          __func__, mMmapBufferinfo.burst_size_frames, burstMinMicros, mFramesPerBurst);
-
     ALOGD("%s() actual rate = %d, channels = %d"
           ", deviceId = %d, capacity = %d\n",
           __func__, getSampleRate(), getSamplesPerFrame(), deviceId, getBufferCapacity());
 
+    ALOGD("%s() format = 0x%08x, frame size = %d, burst size = %d",
+          __func__, getFormat(), calculateBytesPerFrame(), mFramesPerBurst);
+
     return result;
 
 error:
@@ -266,7 +248,6 @@
 
 aaudio_result_t AAudioServiceEndpointMMAP::close() {
     if (mMmapStream != 0) {
-        ALOGD("%s() clear() endpoint", __func__);
         // Needs to be explicitly cleared or CTS will fail but it is not clear why.
         mMmapStream.clear();
         // Apparently the above close is asynchronous. An attempt to open a new device
@@ -288,7 +269,7 @@
     LOG_ALWAYS_FATAL_IF(tempHandle != mPortHandle,
                         "%s() port handle not expected to change from %d to %d",
                         __func__, mPortHandle, tempHandle);
-    ALOGV("%s(%p) mPortHandle = %d", __func__, stream.get(), mPortHandle);
+    ALOGV("%s() mPortHandle = %d", __func__, mPortHandle);
     return result;
 }
 
@@ -303,26 +284,20 @@
     mFramesTransferred.roundUp64(getBufferCapacity());
 
     // Use the port handle that was provided by openMmapStream().
-    ALOGV("%s(%p) mPortHandle = %d", __func__, stream.get(), mPortHandle);
+    ALOGV("%s() mPortHandle = %d", __func__, mPortHandle);
     return stopClient(mPortHandle);
 }
 
 aaudio_result_t AAudioServiceEndpointMMAP::startClient(const android::AudioClient& client,
                                                        audio_port_handle_t *clientHandle) {
     if (mMmapStream == nullptr) return AAUDIO_ERROR_NULL;
-    ALOGD("%s(%p(uid=%d, pid=%d))", __func__, &client, client.clientUid, client.clientPid);
-    audio_port_handle_t originalHandle =  *clientHandle;
     status_t status = mMmapStream->start(client, clientHandle);
-    aaudio_result_t result = AAudioConvert_androidToAAudioResult(status);
-    ALOGD("%s() , portHandle %d => %d, returns %d", __func__, originalHandle, *clientHandle, result);
-    return result;
+    return AAudioConvert_androidToAAudioResult(status);
 }
 
 aaudio_result_t AAudioServiceEndpointMMAP::stopClient(audio_port_handle_t clientHandle) {
-    ALOGD("%s(portHandle = %d), called", __func__, clientHandle);
     if (mMmapStream == nullptr) return AAUDIO_ERROR_NULL;
     aaudio_result_t result = AAudioConvert_androidToAAudioResult(mMmapStream->stop(clientHandle));
-    ALOGD("%s(portHandle = %d), returns %d", __func__, clientHandle, result);
     return result;
 }
 
@@ -375,15 +350,15 @@
     // TODO Do we really need a different volume for each channel?
     // We get called with an array filled with a single value!
     float volume = values[0];
-    ALOGD("%s(%p) volume[0] = %f", __func__, this, volume);
+    ALOGD("%s() volume[0] = %f", __func__, volume);
     std::lock_guard<std::mutex> lock(mLockStreams);
-    for(const auto stream : mRegisteredStreams) {
+    for(const auto& stream : mRegisteredStreams) {
         stream->onVolumeChanged(volume);
     }
 };
 
 void AAudioServiceEndpointMMAP::onRoutingChanged(audio_port_handle_t deviceId) {
-    ALOGD("%s(%p) called with dev %d, old = %d", __func__, this, deviceId, getDeviceId());
+    ALOGD("%s() called with dev %d, old = %d", __func__, deviceId, getDeviceId());
     if (getDeviceId() != AUDIO_PORT_HANDLE_NONE  && getDeviceId() != deviceId) {
         disconnectRegisteredStreams();
     }
diff --git a/services/oboeservice/AAudioServiceEndpointPlay.cpp b/services/oboeservice/AAudioServiceEndpointPlay.cpp
index a274466..bda4b90 100644
--- a/services/oboeservice/AAudioServiceEndpointPlay.cpp
+++ b/services/oboeservice/AAudioServiceEndpointPlay.cpp
@@ -43,14 +43,9 @@
 
 AAudioServiceEndpointPlay::AAudioServiceEndpointPlay(AAudioService &audioService)
         : mStreamInternalPlay(audioService, true) {
-    ALOGD("%s(%p) created", __func__, this);
     mStreamInternal = &mStreamInternalPlay;
 }
 
-AAudioServiceEndpointPlay::~AAudioServiceEndpointPlay() {
-    ALOGD("%s(%p) destroyed", __func__, this);
-}
-
 aaudio_result_t AAudioServiceEndpointPlay::open(const aaudio::AAudioStreamRequest &request) {
     aaudio_result_t result = AAudioServiceEndpointShared::open(request);
     if (result == AAUDIO_OK) {
@@ -84,10 +79,14 @@
             int64_t mmapFramesWritten = getStreamInternal()->getFramesWritten();
 
             std::lock_guard <std::mutex> lock(mLockStreams);
-            for (const auto clientStream : mRegisteredStreams) {
+            for (const auto& clientStream : mRegisteredStreams) {
                 int64_t clientFramesRead = 0;
                 bool allowUnderflow = true;
 
+                if (clientStream->isSuspended()) {
+                    continue; // dead stream
+                }
+
                 aaudio_stream_state_t state = clientStream->getState();
                 if (state == AAUDIO_STREAM_STATE_STOPPING) {
                     allowUnderflow = false; // just read what is already in the FIFO
diff --git a/services/oboeservice/AAudioServiceEndpointPlay.h b/services/oboeservice/AAudioServiceEndpointPlay.h
index a0a383c..981e430 100644
--- a/services/oboeservice/AAudioServiceEndpointPlay.h
+++ b/services/oboeservice/AAudioServiceEndpointPlay.h
@@ -39,7 +39,6 @@
 class AAudioServiceEndpointPlay : public AAudioServiceEndpointShared {
 public:
     explicit AAudioServiceEndpointPlay(android::AAudioService &audioService);
-    virtual ~AAudioServiceEndpointPlay();
 
     aaudio_result_t open(const aaudio::AAudioStreamRequest &request) override;
 
diff --git a/services/oboeservice/AAudioServiceEndpointShared.cpp b/services/oboeservice/AAudioServiceEndpointShared.cpp
index 63b9983..0a415fd 100644
--- a/services/oboeservice/AAudioServiceEndpointShared.cpp
+++ b/services/oboeservice/AAudioServiceEndpointShared.cpp
@@ -78,6 +78,7 @@
     setSamplesPerFrame(mStreamInternal->getSamplesPerFrame());
     setDeviceId(mStreamInternal->getDeviceId());
     setSessionId(mStreamInternal->getSessionId());
+    setFormat(AUDIO_FORMAT_PCM_FLOAT); // force for mixer
     mFramesPerBurst = mStreamInternal->getFramesPerBurst();
 
     return result;
@@ -180,8 +181,8 @@
 // Get timestamp that was written by the real-time service thread, eg. mixer.
 aaudio_result_t AAudioServiceEndpointShared::getFreeRunningPosition(int64_t *positionFrames,
                                                                   int64_t *timeNanos) {
-    if (mAtomicTimestamp.isValid()) {
-        Timestamp timestamp = mAtomicTimestamp.read();
+    if (mAtomicEndpointTimestamp.isValid()) {
+        Timestamp timestamp = mAtomicEndpointTimestamp.read();
         *positionFrames = timestamp.getPosition();
         *timeNanos = timestamp.getNanoseconds();
         return AAUDIO_OK;
@@ -192,5 +193,13 @@
 
 aaudio_result_t AAudioServiceEndpointShared::getTimestamp(int64_t *positionFrames,
                                                           int64_t *timeNanos) {
-    return mStreamInternal->getTimestamp(CLOCK_MONOTONIC, positionFrames, timeNanos);
+    aaudio_result_t result = mStreamInternal->getTimestamp(CLOCK_MONOTONIC, positionFrames, timeNanos);
+    if (result == AAUDIO_ERROR_INVALID_STATE) {
+        // getTimestamp() can return AAUDIO_ERROR_INVALID_STATE if the stream has
+        // not completely started. This can cause a race condition that kills the
+        // timestamp service thread.  So we reduce the error to a less serious one
+        // that allows the timestamp thread to continue.
+        result = AAUDIO_ERROR_UNAVAILABLE;
+    }
+    return result;
 }
diff --git a/services/oboeservice/AAudioServiceEndpointShared.h b/services/oboeservice/AAudioServiceEndpointShared.h
index d671710..bfc1744 100644
--- a/services/oboeservice/AAudioServiceEndpointShared.h
+++ b/services/oboeservice/AAudioServiceEndpointShared.h
@@ -52,8 +52,7 @@
 
     aaudio_result_t getTimestamp(int64_t *positionFrames, int64_t *timeNanos) override;
 
-    virtual void            *callbackLoop() = 0;
-
+    virtual void   *callbackLoop() = 0;
 
 protected:
 
diff --git a/services/oboeservice/AAudioServiceStreamBase.cpp b/services/oboeservice/AAudioServiceStreamBase.cpp
index 9af8af3..880a3d7 100644
--- a/services/oboeservice/AAudioServiceStreamBase.cpp
+++ b/services/oboeservice/AAudioServiceStreamBase.cpp
@@ -43,7 +43,7 @@
 AAudioServiceStreamBase::AAudioServiceStreamBase(AAudioService &audioService)
         : mUpMessageQueue(nullptr)
         , mTimestampThread("AATime")
-        , mAtomicTimestamp()
+        , mAtomicStreamTimestamp()
         , mAudioService(audioService) {
     mMmapClient.clientUid = -1;
     mMmapClient.clientPid = -1;
@@ -51,7 +51,6 @@
 }
 
 AAudioServiceStreamBase::~AAudioServiceStreamBase() {
-    ALOGD("~AAudioServiceStreamBase() destroying %p", this);
     // If the stream is deleted when OPEN or in use then audio resources will leak.
     // This would indicate an internal error. So we want to find this ASAP.
     LOG_ALWAYS_FATAL_IF(!(getState() == AAUDIO_STREAM_STATE_CLOSED
@@ -81,8 +80,7 @@
     return result.str();
 }
 
-aaudio_result_t AAudioServiceStreamBase::open(const aaudio::AAudioStreamRequest &request,
-                                              aaudio_sharing_mode_t sharingMode) {
+aaudio_result_t AAudioServiceStreamBase::open(const aaudio::AAudioStreamRequest &request) {
     AAudioEndpointManager &mEndpointManager = AAudioEndpointManager::getInstance();
     aaudio_result_t result = AAUDIO_OK;
 
@@ -109,10 +107,8 @@
         // referenced until the service returns a handle to the client.
         // So only one thread can open a stream.
         mServiceEndpoint = mEndpointManager.openEndpoint(mAudioService,
-                                                         request,
-                                                         sharingMode);
+                                                         request);
         if (mServiceEndpoint == nullptr) {
-            ALOGE("%s() openEndpoint() failed", __func__);
             result = AAUDIO_ERROR_UNAVAILABLE;
             goto error;
         }
@@ -183,9 +179,10 @@
     }
 
     setFlowing(false);
+    setSuspended(false);
 
     // Start with fresh presentation timestamps.
-    mAtomicTimestamp.clear();
+    mAtomicStreamTimestamp.clear();
 
     mClientHandle = AUDIO_PORT_HANDLE_NONE;
     result = startDevice();
@@ -294,16 +291,20 @@
 }
 
 // implement Runnable, periodically send timestamps to client
+__attribute__((no_sanitize("integer")))
 void AAudioServiceStreamBase::run() {
     ALOGD("%s() %s entering >>>>>>>>>>>>>> TIMESTAMPS", __func__, getTypeText());
     TimestampScheduler timestampScheduler;
     timestampScheduler.setBurstPeriod(mFramesPerBurst, getSampleRate());
     timestampScheduler.start(AudioClock::getNanoseconds());
     int64_t nextTime = timestampScheduler.nextAbsoluteTime();
+    int32_t loopCount = 0;
     while(mThreadEnabled.load()) {
+        loopCount++;
         if (AudioClock::getNanoseconds() >= nextTime) {
             aaudio_result_t result = sendCurrentTimestamp();
             if (result != AAUDIO_OK) {
+                ALOGE("%s() timestamp thread got result = %d", __func__, result);
                 break;
             }
             nextTime = timestampScheduler.nextAbsoluteTime();
@@ -313,7 +314,8 @@
             AudioClock::sleepUntilNanoTime(nextTime);
         }
     }
-    ALOGD("%s() %s exiting <<<<<<<<<<<<<< TIMESTAMPS", __func__, getTypeText());
+    ALOGD("%s() %s exiting after %d loops <<<<<<<<<<<<<< TIMESTAMPS",
+          __func__, getTypeText(), loopCount);
 }
 
 void AAudioServiceStreamBase::disconnect() {
@@ -341,6 +343,20 @@
     return writeUpMessageQueue(&command);
 }
 
+bool AAudioServiceStreamBase::isUpMessageQueueBusy() {
+    std::lock_guard<std::mutex> lock(mUpMessageQueueLock);
+    if (mUpMessageQueue == nullptr) {
+        ALOGE("%s(): mUpMessageQueue null! - stream not open", __func__);
+        return true;
+    }
+    int32_t framesAvailable = mUpMessageQueue->getFifoBuffer()
+        ->getFullFramesAvailable();
+    int32_t capacity = mUpMessageQueue->getFifoBuffer()
+        ->getBufferCapacityInFrames();
+    // Is it half full or more
+    return framesAvailable >= (capacity / 2);
+}
+
 aaudio_result_t AAudioServiceStreamBase::writeUpMessageQueue(AAudioServiceMessage *command) {
     std::lock_guard<std::mutex> lock(mUpMessageQueueLock);
     if (mUpMessageQueue == nullptr) {
@@ -349,7 +365,9 @@
     }
     int32_t count = mUpMessageQueue->getFifoBuffer()->write(command, 1);
     if (count != 1) {
-        ALOGE("%s(): Queue full. Did client die? %s", __func__, getTypeText());
+        ALOGW("%s(): Queue full. Did client stop? Suspending stream. what = %u, %s",
+              __func__, command->what, getTypeText());
+        setSuspended(true);
         return AAUDIO_ERROR_WOULD_BLOCK;
     } else {
         return AAUDIO_OK;
@@ -362,6 +380,13 @@
 
 aaudio_result_t AAudioServiceStreamBase::sendCurrentTimestamp() {
     AAudioServiceMessage command;
+    // It is not worth filling up the queue with timestamps.
+    // That can cause the stream to get suspended.
+    // So just drop the timestamp if the queue is getting full.
+    if (isUpMessageQueueBusy()) {
+        return AAUDIO_OK;
+    }
+
     // Send a timestamp for the clock model.
     aaudio_result_t result = getFreeRunningPosition(&command.timestamp.position,
                                                     &command.timestamp.timestamp);
diff --git a/services/oboeservice/AAudioServiceStreamBase.h b/services/oboeservice/AAudioServiceStreamBase.h
index a1815d0..097bc64 100644
--- a/services/oboeservice/AAudioServiceStreamBase.h
+++ b/services/oboeservice/AAudioServiceStreamBase.h
@@ -204,6 +204,20 @@
     }
 
     /**
+     * Set false when the stream should not longer be processed.
+     * This may be caused by a message queue overflow.
+     * Set true when stream is started.
+     * @param suspended
+     */
+    void setSuspended(bool suspended) {
+        mSuspended = suspended;
+    }
+
+    bool isSuspended() const {
+        return mSuspended;
+    }
+
+    /**
      * Atomically increment the number of active references to the stream by AAudioService.
      *
      * This is called under a global lock in AAudioStreamTracker.
@@ -287,7 +301,7 @@
     // TODO rename mClientHandle to mPortHandle to be more consistent with AudioFlinger.
     audio_port_handle_t     mClientHandle = AUDIO_PORT_HANDLE_NONE;
 
-    SimpleDoubleBuffer<Timestamp>  mAtomicTimestamp;
+    SimpleDoubleBuffer<Timestamp>  mAtomicStreamTimestamp;
 
     android::AAudioService &mAudioService;
 
@@ -298,13 +312,24 @@
     android::wp<AAudioServiceEndpoint> mServiceEndpointWeak;
 
 private:
+
+    /**
+     * @return true if the queue is getting full.
+     */
+    bool isUpMessageQueueBusy();
+
     aaudio_handle_t         mHandle = -1;
     bool                    mFlowing = false;
 
     // This is modified under a global lock in AAudioStreamTracker.
     int32_t                 mCallingCount = 0;
 
+    // This indicates that a stream that is being referenced by a binder call needs to closed.
     std::atomic<bool>       mCloseNeeded{false};
+
+    // This indicate that a running stream should not be processed because of an error,
+    // for example a full message queue. Note that this atomic is unrelated to mCloseNeeded.
+    std::atomic<bool>       mSuspended{false};
 };
 
 } /* namespace aaudio */
diff --git a/services/oboeservice/AAudioServiceStreamMMAP.cpp b/services/oboeservice/AAudioServiceStreamMMAP.cpp
index c845309..837b080 100644
--- a/services/oboeservice/AAudioServiceStreamMMAP.cpp
+++ b/services/oboeservice/AAudioServiceStreamMMAP.cpp
@@ -64,8 +64,13 @@
 
     sp<AAudioServiceStreamMMAP> keep(this);
 
-    aaudio_result_t result = AAudioServiceStreamBase::open(request,
-                                                           AAUDIO_SHARING_MODE_EXCLUSIVE);
+    if (request.getConstantConfiguration().getSharingMode() != AAUDIO_SHARING_MODE_EXCLUSIVE) {
+        ALOGE("%s() sharingMode mismatch %d", __func__,
+              request.getConstantConfiguration().getSharingMode());
+        return AAUDIO_ERROR_INTERNAL;
+    }
+
+    aaudio_result_t result = AAudioServiceStreamBase::open(request);
     if (result != AAUDIO_OK) {
         return result;
     }
@@ -157,7 +162,7 @@
     aaudio_result_t result = serviceEndpointMMAP->getFreeRunningPosition(positionFrames, timeNanos);
     if (result == AAUDIO_OK) {
         Timestamp timestamp(*positionFrames, *timeNanos);
-        mAtomicTimestamp.write(timestamp);
+        mAtomicStreamTimestamp.write(timestamp);
         *positionFrames = timestamp.getPosition();
         *timeNanos = timestamp.getNanoseconds();
     } else if (result != AAUDIO_ERROR_UNAVAILABLE) {
@@ -179,8 +184,8 @@
             static_cast<AAudioServiceEndpointMMAP *>(endpoint.get());
 
     // TODO Get presentation timestamp from the HAL
-    if (mAtomicTimestamp.isValid()) {
-        Timestamp timestamp = mAtomicTimestamp.read();
+    if (mAtomicStreamTimestamp.isValid()) {
+        Timestamp timestamp = mAtomicStreamTimestamp.read();
         *positionFrames = timestamp.getPosition();
         *timeNanos = timestamp.getNanoseconds() + serviceEndpointMMAP->getHardwareTimeOffsetNanos();
         return AAUDIO_OK;
diff --git a/services/oboeservice/AAudioServiceStreamShared.cpp b/services/oboeservice/AAudioServiceStreamShared.cpp
index 05c5735..2ca847a 100644
--- a/services/oboeservice/AAudioServiceStreamShared.cpp
+++ b/services/oboeservice/AAudioServiceStreamShared.cpp
@@ -111,7 +111,7 @@
               capacityInFrames, MAX_FRAMES_PER_BUFFER);
         return AAUDIO_ERROR_OUT_OF_RANGE;
     }
-    ALOGD("calculateBufferCapacity() requested %d frames, actual = %d",
+    ALOGV("calculateBufferCapacity() requested %d frames, actual = %d",
           requestedCapacityFrames, capacityInFrames);
     return capacityInFrames;
 }
@@ -120,9 +120,14 @@
 
     sp<AAudioServiceStreamShared> keep(this);
 
-    aaudio_result_t result = AAudioServiceStreamBase::open(request, AAUDIO_SHARING_MODE_SHARED);
+    if (request.getConstantConfiguration().getSharingMode() != AAUDIO_SHARING_MODE_SHARED) {
+        ALOGE("%s() sharingMode mismatch %d", __func__,
+              request.getConstantConfiguration().getSharingMode());
+        return AAUDIO_ERROR_INTERNAL;
+    }
+
+    aaudio_result_t result = AAudioServiceStreamBase::open(request);
     if (result != AAUDIO_OK) {
-        ALOGE("%s() returned %d", __func__, result);
         return result;
     }
 
@@ -136,10 +141,10 @@
 
     // Is the request compatible with the shared endpoint?
     setFormat(configurationInput.getFormat());
-    if (getFormat() == AAUDIO_FORMAT_UNSPECIFIED) {
-        setFormat(AAUDIO_FORMAT_PCM_FLOAT);
-    } else if (getFormat() != AAUDIO_FORMAT_PCM_FLOAT) {
-        ALOGD("%s() mAudioFormat = %d, need FLOAT", __func__, getFormat());
+    if (getFormat() == AUDIO_FORMAT_DEFAULT) {
+        setFormat(AUDIO_FORMAT_PCM_FLOAT);
+    } else if (getFormat() != AUDIO_FORMAT_PCM_FLOAT) {
+        ALOGD("%s() audio_format_t mAudioFormat = %d, need FLOAT", __func__, getFormat());
         result = AAUDIO_ERROR_INVALID_FORMAT;
         goto error;
     }
@@ -185,9 +190,6 @@
         }
     }
 
-    ALOGD("AAudioServiceStreamShared::open() actual rate = %d, channels = %d, deviceId = %d",
-          getSampleRate(), getSamplesPerFrame(), endpoint->getDeviceId());
-
     result = endpoint->registerStream(keep);
     if (result != AAUDIO_OK) {
         goto error;
@@ -222,7 +224,7 @@
 {
     std::lock_guard<std::mutex> lock(mAudioDataQueueLock);
     if (mAudioDataQueue == nullptr) {
-        ALOGE("%s(): mUpMessageQueue null! - stream not open", __func__);
+        ALOGW("%s(): mUpMessageQueue null! - stream not open", __func__);
         return AAUDIO_ERROR_NULL;
     }
     // Gather information on the data queue.
@@ -233,15 +235,15 @@
 }
 
 void AAudioServiceStreamShared::markTransferTime(Timestamp &timestamp) {
-    mAtomicTimestamp.write(timestamp);
+    mAtomicStreamTimestamp.write(timestamp);
 }
 
 // Get timestamp that was written by mixer or distributor.
 aaudio_result_t AAudioServiceStreamShared::getFreeRunningPosition(int64_t *positionFrames,
                                                                   int64_t *timeNanos) {
     // TODO Get presentation timestamp from the HAL
-    if (mAtomicTimestamp.isValid()) {
-        Timestamp timestamp = mAtomicTimestamp.read();
+    if (mAtomicStreamTimestamp.isValid()) {
+        Timestamp timestamp = mAtomicStreamTimestamp.read();
         *positionFrames = timestamp.getPosition();
         *timeNanos = timestamp.getNanoseconds();
         return AAUDIO_OK;
@@ -257,7 +259,7 @@
     int64_t position = 0;
     sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
     if (endpoint == nullptr) {
-        ALOGE("%s() has no endpoint", __func__);
+        ALOGW("%s() has no endpoint", __func__);
         return AAUDIO_ERROR_INVALID_STATE;
     }
 
diff --git a/services/oboeservice/Android.mk b/services/oboeservice/Android.mk
index 584b2ef..3d5f140 100644
--- a/services/oboeservice/Android.mk
+++ b/services/oboeservice/Android.mk
@@ -53,7 +53,6 @@
     libbinder \
     libcutils \
     libmediautils \
-    libserviceutility \
     libutils \
     liblog
 
diff --git a/services/soundtrigger/Android.bp b/services/soundtrigger/Android.bp
new file mode 100644
index 0000000..3f02f48
--- /dev/null
+++ b/services/soundtrigger/Android.bp
@@ -0,0 +1,55 @@
+// Copyright 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library_shared {
+    name: "libsoundtriggerservice",
+
+    srcs: [
+        "SoundTriggerHwService.cpp",
+        "SoundTriggerHalHidl.cpp",
+    ],
+
+    shared_libs: [
+        "liblog",
+        "libutils",
+        "libbinder",
+        "libcutils",
+        "libhardware",
+        "libsoundtrigger",
+        "libaudioclient",
+        "libaudioutils",
+        "libmediautils",
+
+        "libhwbinder",
+        "libhidlbase",
+        "libhidlmemory",
+        "libhidltransport",
+        "libbase",
+        "libaudiohal",
+        "libaudiohal_deathhandler",
+        "android.hardware.soundtrigger@2.0",
+        "android.hardware.soundtrigger@2.1",
+        "android.hardware.soundtrigger@2.2",
+        "android.hardware.audio.common@2.0",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
+    ],
+
+    include_dirs: ["frameworks/av/services/audioflinger"],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+}
diff --git a/services/soundtrigger/Android.mk b/services/soundtrigger/Android.mk
deleted file mode 100644
index ad3666e..0000000
--- a/services/soundtrigger/Android.mk
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright 2014 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-ifeq ($(SOUND_TRIGGER_USE_STUB_MODULE), 1)
-    ifneq ($(USE_LEGACY_LOCAL_AUDIO_HAL), true)
-        $(error Requires building with USE_LEGACY_LOCAL_AUDIO_HAL=true)
-    endif
-    LOCAL_CFLAGS += -DSOUND_TRIGGER_USE_STUB_MODULE
-endif
-
-LOCAL_SRC_FILES:=               \
-    SoundTriggerHwService.cpp
-
-LOCAL_SHARED_LIBRARIES:= \
-    liblog \
-    libutils \
-    libbinder \
-    libcutils \
-    libhardware \
-    libsoundtrigger \
-    libaudioclient \
-    libserviceutility
-
-
-ifeq ($(USE_LEGACY_LOCAL_AUDIO_HAL),true)
-# libhardware configuration
-LOCAL_SRC_FILES +=               \
-    SoundTriggerHalLegacy.cpp
-else
-# Treble configuration
-LOCAL_SRC_FILES +=               \
-    SoundTriggerHalHidl.cpp
-
-LOCAL_SHARED_LIBRARIES += \
-    libhwbinder \
-    libhidlbase \
-    libhidlmemory \
-    libhidltransport \
-    libbase \
-    libaudiohal \
-    libaudiohal_deathhandler \
-    android.hardware.soundtrigger@2.0 \
-    android.hardware.soundtrigger@2.1 \
-    android.hardware.audio.common@2.0 \
-    android.hidl.allocator@1.0 \
-    android.hidl.memory@1.0
-endif
-
-
-LOCAL_C_INCLUDES += \
-    frameworks/av/services/audioflinger
-
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
-LOCAL_CFLAGS += -Wall -Werror
-
-LOCAL_MODULE:= libsoundtriggerservice
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/services/soundtrigger/SoundTriggerHalHidl.cpp b/services/soundtrigger/SoundTriggerHalHidl.cpp
index adf252e..68d54c7 100644
--- a/services/soundtrigger/SoundTriggerHalHidl.cpp
+++ b/services/soundtrigger/SoundTriggerHalHidl.cpp
@@ -168,18 +168,23 @@
     int ret;
     SoundModelHandle halHandle;
     sp<V2_1_ISoundTriggerHw> soundtrigger_2_1 = toService2_1(soundtrigger);
+    sp<V2_2_ISoundTriggerHw> soundtrigger_2_2 = toService2_2(soundtrigger);
     if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
-        if (!soundtrigger_2_1) {
-            ISoundTriggerHw::PhraseSoundModel halSoundModel;
-            convertPhraseSoundModelToHal(&halSoundModel, sound_model);
-            AutoMutex lock(mHalLock);
-            hidlReturn = soundtrigger->loadPhraseSoundModel(
-                    halSoundModel,
-                    this, modelId, [&](int32_t retval, auto res) {
-                        ret = retval;
-                        halHandle = res;
-                    });
-        } else {
+        if (soundtrigger_2_2) {
+            V2_2_ISoundTriggerHw::PhraseSoundModel halSoundModel;
+            auto result = convertPhraseSoundModelToHal(&halSoundModel, sound_model);
+            if (result.first) {
+                AutoMutex lock(mHalLock);
+                hidlReturn = soundtrigger_2_2->loadPhraseSoundModel_2_1(
+                        halSoundModel,
+                        this, modelId, [&](int32_t retval, auto res) {
+                            ret = retval;
+                            halHandle = res;
+                        });
+            } else {
+                return NO_MEMORY;
+            }
+        } else if (soundtrigger_2_1) {
             V2_1_ISoundTriggerHw::PhraseSoundModel halSoundModel;
             auto result = convertPhraseSoundModelToHal(&halSoundModel, sound_model);
             if (result.first) {
@@ -193,18 +198,32 @@
             } else {
                 return NO_MEMORY;
             }
-        }
-    } else {
-        if (!soundtrigger_2_1) {
-            ISoundTriggerHw::SoundModel halSoundModel;
-            convertSoundModelToHal(&halSoundModel, sound_model);
+        } else {
+            ISoundTriggerHw::PhraseSoundModel halSoundModel;
+            convertPhraseSoundModelToHal(&halSoundModel, sound_model);
             AutoMutex lock(mHalLock);
-            hidlReturn = soundtrigger->loadSoundModel(halSoundModel,
+            hidlReturn = soundtrigger->loadPhraseSoundModel(
+                    halSoundModel,
                     this, modelId, [&](int32_t retval, auto res) {
                         ret = retval;
                         halHandle = res;
                     });
-        } else {
+        }
+    } else {
+        if (soundtrigger_2_2) {
+            V2_2_ISoundTriggerHw::SoundModel halSoundModel;
+            auto result = convertSoundModelToHal(&halSoundModel, sound_model);
+            if (result.first) {
+                AutoMutex lock(mHalLock);
+                hidlReturn = soundtrigger_2_2->loadSoundModel_2_1(halSoundModel,
+                        this, modelId, [&](int32_t retval, auto res) {
+                            ret = retval;
+                            halHandle = res;
+                        });
+            } else {
+                return NO_MEMORY;
+            }
+        } else if (soundtrigger_2_1) {
             V2_1_ISoundTriggerHw::SoundModel halSoundModel;
             auto result = convertSoundModelToHal(&halSoundModel, sound_model);
             if (result.first) {
@@ -217,6 +236,15 @@
             } else {
                 return NO_MEMORY;
             }
+        } else {
+            ISoundTriggerHw::SoundModel halSoundModel;
+            convertSoundModelToHal(&halSoundModel, sound_model);
+            AutoMutex lock(mHalLock);
+            hidlReturn = soundtrigger->loadSoundModel(halSoundModel,
+                    this, modelId, [&](int32_t retval, auto res) {
+                        ret = retval;
+                        halHandle = res;
+                    });
         }
     }
 
@@ -282,16 +310,20 @@
     model->mRecognitionCookie = cookie;
 
     sp<V2_1_ISoundTriggerHw> soundtrigger_2_1 = toService2_1(soundtrigger);
+    sp<V2_2_ISoundTriggerHw> soundtrigger_2_2 = toService2_2(soundtrigger);
     Return<int32_t> hidlReturn(0);
 
-    if (!soundtrigger_2_1) {
-        ISoundTriggerHw::RecognitionConfig halConfig;
-        convertRecognitionConfigToHal(&halConfig, config);
-        {
+    if (soundtrigger_2_2) {
+        V2_2_ISoundTriggerHw::RecognitionConfig halConfig;
+        auto result = convertRecognitionConfigToHal(&halConfig, config);
+        if (result.first) {
             AutoMutex lock(mHalLock);
-            hidlReturn = soundtrigger->startRecognition(model->mHalHandle, halConfig, this, handle);
+            hidlReturn = soundtrigger_2_2->startRecognition_2_1(
+                    model->mHalHandle, halConfig, this, handle);
+        } else {
+            return NO_MEMORY;
         }
-    } else {
+    } else if (soundtrigger_2_1) {
         V2_1_ISoundTriggerHw::RecognitionConfig halConfig;
         auto result = convertRecognitionConfigToHal(&halConfig, config);
         if (result.first) {
@@ -301,6 +333,13 @@
         } else {
             return NO_MEMORY;
         }
+    } else {
+        ISoundTriggerHw::RecognitionConfig halConfig;
+        convertRecognitionConfigToHal(&halConfig, config);
+        {
+            AutoMutex lock(mHalLock);
+            hidlReturn = soundtrigger->startRecognition(model->mHalHandle, halConfig, this, handle);
+        }
     }
 
     if (!hidlReturn.isOk()) {
@@ -356,6 +395,38 @@
     return hidlReturn;
 }
 
+int SoundTriggerHalHidl::getModelState(sound_model_handle_t handle)
+{
+    sp<ISoundTriggerHw> soundtrigger = getService();
+    if (soundtrigger == 0) {
+        return -ENODEV;
+    }
+
+    sp<V2_2_ISoundTriggerHw> soundtrigger_2_2 = toService2_2(soundtrigger);
+    if (soundtrigger_2_2 == 0) {
+        ALOGE("getModelState not supported");
+        return -ENODEV;
+    }
+
+    sp<SoundModel> model = getModel(handle);
+    if (model == 0) {
+        ALOGE("getModelState model not found for handle %u", handle);
+        return -EINVAL;
+    }
+
+    int ret = NO_ERROR;
+    Return<int32_t> hidlReturn(0);
+    {
+        AutoMutex lock(mHalLock);
+        hidlReturn = soundtrigger_2_2->getModelState(model->mHalHandle);
+    }
+    if (!hidlReturn.isOk()) {
+        ALOGE("getModelState error %s", hidlReturn.description().c_str());
+        ret = FAILED_TRANSACTION;
+    }
+    return ret;
+}
+
 SoundTriggerHalHidl::SoundTriggerHalHidl(const char *moduleName)
     : mModuleName(moduleName), mNextUniqueId(1)
 {
@@ -388,6 +459,12 @@
     return castResult_2_1.isOk() ? static_cast<sp<V2_1_ISoundTriggerHw>>(castResult_2_1) : nullptr;
 }
 
+sp<V2_2_ISoundTriggerHw> SoundTriggerHalHidl::toService2_2(const sp<ISoundTriggerHw>& s)
+{
+    auto castResult_2_2 = V2_2_ISoundTriggerHw::castFrom(s);
+    return castResult_2_2.isOk() ? static_cast<sp<V2_2_ISoundTriggerHw>>(castResult_2_2) : nullptr;
+}
+
 sp<SoundTriggerHalHidl::SoundModel> SoundTriggerHalHidl::getModel(sound_model_handle_t handle)
 {
     AutoMutex lock(mLock);
diff --git a/services/soundtrigger/SoundTriggerHalHidl.h b/services/soundtrigger/SoundTriggerHalHidl.h
index 0b44ae0..fb9e39e 100644
--- a/services/soundtrigger/SoundTriggerHalHidl.h
+++ b/services/soundtrigger/SoundTriggerHalHidl.h
@@ -27,6 +27,7 @@
 #include "SoundTriggerHalInterface.h"
 #include <android/hardware/soundtrigger/2.0/types.h>
 #include <android/hardware/soundtrigger/2.1/ISoundTriggerHw.h>
+#include <android/hardware/soundtrigger/2.2/ISoundTriggerHw.h>
 #include <android/hardware/soundtrigger/2.0/ISoundTriggerHwCallback.h>
 #include <android/hardware/soundtrigger/2.1/ISoundTriggerHwCallback.h>
 
@@ -46,6 +47,8 @@
 using V2_1_ISoundTriggerHwCallback =
         ::android::hardware::soundtrigger::V2_1::ISoundTriggerHwCallback;
 using ::android::hidl::memory::V1_0::IMemory;
+using V2_2_ISoundTriggerHw =
+        ::android::hardware::soundtrigger::V2_2::ISoundTriggerHw;
 
 class SoundTriggerHalHidl : public SoundTriggerHalInterface,
                             public virtual V2_1_ISoundTriggerHwCallback
@@ -92,6 +95,14 @@
          */
         virtual int stopAllRecognitions();
 
+        /* Get the current state of a given model.
+         * Returns 0 or an error code. If successful the state will be returned asynchronously
+         * via a recognition event in the callback method that was registered in the
+         * startRecognition() method.
+         * Only supported for device api versions SOUND_TRIGGER_DEVICE_API_VERSION_1_2 or above.
+         */
+        virtual int getModelState(sound_model_handle_t handle);
+
         // ISoundTriggerHwCallback
         virtual ::android::hardware::Return<void> recognitionCallback(
                 const V2_0_ISoundTriggerHwCallback::RecognitionEvent& event, CallbackCookie cookie);
@@ -182,6 +193,7 @@
         uint32_t nextUniqueId();
         sp<ISoundTriggerHw> getService();
         sp<V2_1_ISoundTriggerHw> toService2_1(const sp<ISoundTriggerHw>& s);
+        sp<V2_2_ISoundTriggerHw> toService2_2(const sp<ISoundTriggerHw>& s);
         sp<SoundModel> getModel(sound_model_handle_t handle);
         sp<SoundModel> removeModel(sound_model_handle_t handle);
 
diff --git a/services/soundtrigger/SoundTriggerHalInterface.h b/services/soundtrigger/SoundTriggerHalInterface.h
index c083195..0183ece 100644
--- a/services/soundtrigger/SoundTriggerHalInterface.h
+++ b/services/soundtrigger/SoundTriggerHalInterface.h
@@ -71,6 +71,14 @@
          */
         virtual int stopAllRecognitions() = 0;
 
+        /* Get the current state of a given model.
+         * Returns 0 or an error code. If successful the state will be returned asynchronously
+         * via a recognition event in the callback method that was registered in the
+         * startRecognition() method.
+         * Only supported for device api versions SOUND_TRIGGER_DEVICE_API_VERSION_1_2 or above.
+         */
+        virtual int getModelState(sound_model_handle_t handle) = 0;
+
 protected:
         SoundTriggerHalInterface() {}
 };
diff --git a/services/soundtrigger/SoundTriggerHalLegacy.cpp b/services/soundtrigger/SoundTriggerHalLegacy.cpp
deleted file mode 100644
index 2b78818..0000000
--- a/services/soundtrigger/SoundTriggerHalLegacy.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <utils/Log.h>
-#include "SoundTriggerHalLegacy.h"
-
-namespace android {
-
-/* static */
-sp<SoundTriggerHalInterface> SoundTriggerHalInterface::connectModule(const char *moduleName)
-{
-    return new SoundTriggerHalLegacy(moduleName);
-}
-
-SoundTriggerHalLegacy::SoundTriggerHalLegacy(const char *moduleName)
-    : mModuleName(moduleName), mHwDevice(NULL)
-{
-}
-
-void SoundTriggerHalLegacy::onFirstRef()
-{
-    const hw_module_t *mod;
-    int rc;
-
-    if (mModuleName == NULL) {
-        mModuleName = "primary";
-    }
-
-    rc = hw_get_module_by_class(SOUND_TRIGGER_HARDWARE_MODULE_ID, mModuleName, &mod);
-    if (rc != 0) {
-        ALOGE("couldn't load sound trigger module %s.%s (%s)",
-              SOUND_TRIGGER_HARDWARE_MODULE_ID, mModuleName, strerror(-rc));
-        return;
-    }
-    rc = sound_trigger_hw_device_open(mod, &mHwDevice);
-    if (rc != 0) {
-        ALOGE("couldn't open sound trigger hw device in %s.%s (%s)",
-              SOUND_TRIGGER_HARDWARE_MODULE_ID, mModuleName, strerror(-rc));
-        mHwDevice = NULL;
-        return;
-    }
-    if (mHwDevice->common.version < SOUND_TRIGGER_DEVICE_API_VERSION_1_0 ||
-            mHwDevice->common.version > SOUND_TRIGGER_DEVICE_API_VERSION_CURRENT) {
-        ALOGE("wrong sound trigger hw device version %04x", mHwDevice->common.version);
-        return;
-    }
-}
-
-SoundTriggerHalLegacy::~SoundTriggerHalLegacy()
-{
-    if (mHwDevice != NULL) {
-        sound_trigger_hw_device_close(mHwDevice);
-    }
-}
-
-int SoundTriggerHalLegacy::getProperties(struct sound_trigger_properties *properties)
-{
-    if (mHwDevice == NULL) {
-        return -ENODEV;
-    }
-    return mHwDevice->get_properties(mHwDevice, properties);
-}
-
-int SoundTriggerHalLegacy::loadSoundModel(struct sound_trigger_sound_model *sound_model,
-                        sound_model_callback_t callback,
-                        void *cookie,
-                        sound_model_handle_t *handle)
-{
-    if (mHwDevice == NULL) {
-        return -ENODEV;
-    }
-    return mHwDevice->load_sound_model(mHwDevice, sound_model, callback, cookie, handle);
-}
-
-int SoundTriggerHalLegacy::unloadSoundModel(sound_model_handle_t handle)
-{
-    if (mHwDevice == NULL) {
-        return -ENODEV;
-    }
-    return mHwDevice->unload_sound_model(mHwDevice, handle);
-}
-
-int SoundTriggerHalLegacy::startRecognition(sound_model_handle_t handle,
-                         const struct sound_trigger_recognition_config *config,
-                         recognition_callback_t callback,
-                         void *cookie)
-{
-    if (mHwDevice == NULL) {
-        return -ENODEV;
-    }
-    return mHwDevice->start_recognition(mHwDevice, handle, config, callback, cookie);
-}
-
-int SoundTriggerHalLegacy::stopRecognition(sound_model_handle_t handle)
-{
-    if (mHwDevice == NULL) {
-        return -ENODEV;
-    }
-    return mHwDevice->stop_recognition(mHwDevice, handle);
-}
-
-int SoundTriggerHalLegacy::stopAllRecognitions()
-{
-    if (mHwDevice == NULL) {
-        return -ENODEV;
-    }
-    if (mHwDevice->common.version >= SOUND_TRIGGER_DEVICE_API_VERSION_1_1 &&
-     mHwDevice->stop_all_recognitions) {
-        return mHwDevice->stop_all_recognitions(mHwDevice);
-    }
-    return -ENOSYS;
-}
-
-} // namespace android
diff --git a/services/soundtrigger/SoundTriggerHalLegacy.h b/services/soundtrigger/SoundTriggerHalLegacy.h
deleted file mode 100644
index 52488de..0000000
--- a/services/soundtrigger/SoundTriggerHalLegacy.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_SOUNDTRIGGER_HAL_LEGACY_H
-#define ANDROID_HARDWARE_SOUNDTRIGGER_HAL_LEGACY_H
-
-#include "SoundTriggerHalInterface.h"
-
-namespace android {
-
-class SoundTriggerHalLegacy : public SoundTriggerHalInterface
-
-{
-public:
-        virtual             ~SoundTriggerHalLegacy();
-
-        virtual int getProperties(struct sound_trigger_properties *properties);
-
-        /*
-         * Load a sound model. Once loaded, recognition of this model can be started and stopped.
-         * Only one active recognition per model at a time. The SoundTrigger service will handle
-         * concurrent recognition requests by different users/applications on the same model.
-         * The implementation returns a unique handle used by other functions (unload_sound_model(),
-         * start_recognition(), etc...
-         */
-        virtual int loadSoundModel(struct sound_trigger_sound_model *sound_model,
-                                sound_model_callback_t callback,
-                                void *cookie,
-                                sound_model_handle_t *handle);
-
-        /*
-         * Unload a sound model. A sound model can be unloaded to make room for a new one to overcome
-         * implementation limitations.
-         */
-        virtual int unloadSoundModel(sound_model_handle_t handle);
-
-        /* Start recognition on a given model. Only one recognition active at a time per model.
-         * Once recognition succeeds of fails, the callback is called.
-         * TODO: group recognition configuration parameters into one struct and add key phrase options.
-         */
-        virtual int startRecognition(sound_model_handle_t handle,
-                                 const struct sound_trigger_recognition_config *config,
-                                 recognition_callback_t callback,
-                                 void *cookie);
-
-        /* Stop recognition on a given model.
-         * The implementation does not have to call the callback when stopped via this method.
-         */
-        virtual int stopRecognition(sound_model_handle_t handle);
-
-        /* Stop recognition on all models.
-         * Only supported for device api versions SOUND_TRIGGER_DEVICE_API_VERSION_1_1 or above.
-         * If no implementation is provided, stop_recognition will be called for each running model.
-         */
-        int stopAllRecognitions();
-
-        // RefBase
-        virtual     void        onFirstRef();
-
-private:
-
-        friend class SoundTriggerHalInterface;
-
-        explicit SoundTriggerHalLegacy(const char *moduleName = NULL);
-
-        const char *mModuleName;
-        struct sound_trigger_hw_device*        mHwDevice;
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_SOUNDTRIGGER_HAL_LEGACY_H
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index a7d6e83..377d30b 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -22,25 +22,22 @@
 #include <sys/types.h>
 #include <pthread.h>
 
+#include <audio_utils/clock.h>
 #include <system/sound_trigger.h>
 #include <cutils/atomic.h>
 #include <cutils/properties.h>
 #include <hardware/hardware.h>
 #include <media/AudioSystem.h>
+#include <mediautils/ServiceUtilities.h>
 #include <utils/Errors.h>
 #include <utils/Log.h>
 #include <binder/IServiceManager.h>
 #include <binder/MemoryBase.h>
 #include <binder/MemoryHeapBase.h>
 #include <system/sound_trigger.h>
-#include <ServiceUtilities.h>
 #include "SoundTriggerHwService.h"
 
-#ifdef SOUND_TRIGGER_USE_STUB_MODULE
-#define HW_MODULE_PREFIX "stub"
-#else
 #define HW_MODULE_PREFIX "primary"
-#endif
 namespace android {
 
 SoundTriggerHwService::SoundTriggerHwService()
@@ -85,11 +82,13 @@
     }
 }
 
-status_t SoundTriggerHwService::listModules(struct sound_trigger_module_descriptor *modules,
+status_t SoundTriggerHwService::listModules(const String16& opPackageName,
+                             struct sound_trigger_module_descriptor *modules,
                              uint32_t *numModules)
 {
     ALOGV("listModules");
-    if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
+    if (!captureHotwordAllowed(opPackageName,
+                               IPCThreadState::self()->getCallingPid(),
                                IPCThreadState::self()->getCallingUid())) {
         return PERMISSION_DENIED;
     }
@@ -106,12 +105,14 @@
     return NO_ERROR;
 }
 
-status_t SoundTriggerHwService::attach(const sound_trigger_module_handle_t handle,
+status_t SoundTriggerHwService::attach(const String16& opPackageName,
+                        const sound_trigger_module_handle_t handle,
                         const sp<ISoundTriggerClient>& client,
                         sp<ISoundTrigger>& moduleInterface)
 {
     ALOGV("attach module %d", handle);
-    if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
+    if (!captureHotwordAllowed(opPackageName,
+                               IPCThreadState::self()->getCallingPid(),
                                IPCThreadState::self()->getCallingUid())) {
         return PERMISSION_DENIED;
     }
@@ -127,7 +128,7 @@
     }
     sp<Module> module = mModules.valueAt(index);
 
-    sp<ModuleClient> moduleClient = module->addClient(client);
+    sp<ModuleClient> moduleClient = module->addClient(client, opPackageName);
     if (moduleClient == 0) {
         return NO_INIT;
     }
@@ -150,20 +151,12 @@
 }
 
 
-static const int kDumpLockRetries = 50;
-static const int kDumpLockSleep = 60000;
+static const int kDumpLockTimeoutNs = 1 * NANOS_PER_SECOND;
 
-static bool tryLock(Mutex& mutex)
+static bool dumpTryLock(Mutex& mutex)
 {
-    bool locked = false;
-    for (int i = 0; i < kDumpLockRetries; ++i) {
-        if (mutex.tryLock() == NO_ERROR) {
-            locked = true;
-            break;
-        }
-        usleep(kDumpLockSleep);
-    }
-    return locked;
+    status_t err = mutex.timedLock(kDumpLockTimeoutNs);
+    return err == NO_ERROR;
 }
 
 status_t SoundTriggerHwService::dump(int fd, const Vector<String16>& args __unused) {
@@ -172,7 +165,7 @@
         result.appendFormat("Permission Denial: can't dump SoundTriggerHwService");
         write(fd, result.string(), result.size());
     } else {
-        bool locked = tryLock(mServiceLock);
+        bool locked = dumpTryLock(mServiceLock);
         // failed to lock - SoundTriggerHwService is probably deadlocked
         if (!locked) {
             result.append("SoundTriggerHwService may be deadlocked\n");
@@ -490,7 +483,8 @@
 }
 
 sp<SoundTriggerHwService::ModuleClient>
-SoundTriggerHwService::Module::addClient(const sp<ISoundTriggerClient>& client)
+SoundTriggerHwService::Module::addClient(const sp<ISoundTriggerClient>& client,
+                                         const String16& opPackageName)
 {
     AutoMutex lock(mLock);
     sp<ModuleClient> moduleClient;
@@ -501,7 +495,7 @@
             return moduleClient;
         }
     }
-    moduleClient = new ModuleClient(this, client);
+    moduleClient = new ModuleClient(this, client, opPackageName);
 
     ALOGV("addClient() client %p", moduleClient.get());
     mModuleClients.add(moduleClient);
@@ -562,10 +556,7 @@
     if (mHalInterface == 0) {
         return NO_INIT;
     }
-    if (modelMemory == 0 || modelMemory->pointer() == NULL) {
-        ALOGE("loadSoundModel() modelMemory is 0 or has NULL pointer()");
-        return BAD_VALUE;
-    }
+
     struct sound_trigger_sound_model *sound_model =
             (struct sound_trigger_sound_model *)modelMemory->pointer();
 
@@ -659,11 +650,6 @@
     if (mHalInterface == 0) {
         return NO_INIT;
     }
-    if (dataMemory == 0 || dataMemory->pointer() == NULL) {
-        ALOGE("startRecognition() dataMemory is 0 or has NULL pointer()");
-        return BAD_VALUE;
-
-    }
 
     struct sound_trigger_recognition_config *config =
             (struct sound_trigger_recognition_config *)dataMemory->pointer();
@@ -725,6 +711,25 @@
     return NO_ERROR;
 }
 
+status_t SoundTriggerHwService::Module::getModelState(sound_model_handle_t handle)
+{
+    ALOGV("getModelState() model handle %d", handle);
+    if (mHalInterface == 0) {
+        return NO_INIT;
+    }
+    AutoMutex lock(mLock);
+    sp<Model> model = getModel(handle);
+    if (model == 0) {
+        return BAD_VALUE;
+    }
+
+    if (model->mState != Model::STATE_ACTIVE) {
+        return INVALID_OPERATION;
+    }
+
+    return mHalInterface->getModelState(handle);
+}
+
 void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event)
 {
     ALOGV("onCallbackEvent type %d", event->mType);
@@ -913,8 +918,9 @@
 #define LOG_TAG "SoundTriggerHwService::ModuleClient"
 
 SoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module,
-                                                  const sp<ISoundTriggerClient>& client)
- : mModule(module), mClient(client)
+                                                  const sp<ISoundTriggerClient>& client,
+                                                  const String16& opPackageName)
+ : mModule(module), mClient(client), mOpPackageName(opPackageName)
 {
 }
 
@@ -938,7 +944,8 @@
 
 void SoundTriggerHwService::ModuleClient::detach() {
     ALOGV("detach()");
-    if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
+    if (!captureHotwordAllowed(mOpPackageName,
+                               IPCThreadState::self()->getCallingPid(),
                                IPCThreadState::self()->getCallingUid())) {
         return;
     }
@@ -962,10 +969,14 @@
                                 sound_model_handle_t *handle)
 {
     ALOGV("loadSoundModel() handle");
-    if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
+    if (!captureHotwordAllowed(mOpPackageName,
+                               IPCThreadState::self()->getCallingPid(),
                                IPCThreadState::self()->getCallingUid())) {
         return PERMISSION_DENIED;
     }
+    if (checkIMemory(modelMemory) != NO_ERROR) {
+        return BAD_VALUE;
+    }
 
     sp<Module> module = mModule.promote();
     if (module == 0) {
@@ -977,7 +988,8 @@
 status_t SoundTriggerHwService::ModuleClient::unloadSoundModel(sound_model_handle_t handle)
 {
     ALOGV("unloadSoundModel() model handle %d", handle);
-    if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
+    if (!captureHotwordAllowed(mOpPackageName,
+                               IPCThreadState::self()->getCallingPid(),
                                IPCThreadState::self()->getCallingUid())) {
         return PERMISSION_DENIED;
     }
@@ -993,10 +1005,14 @@
                                  const sp<IMemory>& dataMemory)
 {
     ALOGV("startRecognition() model handle %d", handle);
-    if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
+    if (!captureHotwordAllowed(mOpPackageName,
+                               IPCThreadState::self()->getCallingPid(),
                                IPCThreadState::self()->getCallingUid())) {
         return PERMISSION_DENIED;
     }
+    if (checkIMemory(dataMemory) != NO_ERROR) {
+        return BAD_VALUE;
+    }
 
     sp<Module> module = mModule.promote();
     if (module == 0) {
@@ -1008,7 +1024,8 @@
 status_t SoundTriggerHwService::ModuleClient::stopRecognition(sound_model_handle_t handle)
 {
     ALOGV("stopRecognition() model handle %d", handle);
-    if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
+    if (!captureHotwordAllowed(mOpPackageName,
+                               IPCThreadState::self()->getCallingPid(),
                                IPCThreadState::self()->getCallingUid())) {
         return PERMISSION_DENIED;
     }
@@ -1020,6 +1037,22 @@
     return module->stopRecognition(handle);
 }
 
+status_t SoundTriggerHwService::ModuleClient::getModelState(sound_model_handle_t handle)
+{
+    ALOGV("getModelState() model handle %d", handle);
+    if (!captureHotwordAllowed(mOpPackageName,
+                               IPCThreadState::self()->getCallingPid(),
+                               IPCThreadState::self()->getCallingUid())) {
+        return PERMISSION_DENIED;
+    }
+
+    sp<Module> module = mModule.promote();
+    if (module == 0) {
+        return NO_INIT;
+    }
+    return module->getModelState(handle);
+}
+
 void SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active)
 {
     ALOGV("ModuleClient::setCaptureState_l %d", active);
diff --git a/services/soundtrigger/SoundTriggerHwService.h b/services/soundtrigger/SoundTriggerHwService.h
index 708fc98..43ad611 100644
--- a/services/soundtrigger/SoundTriggerHwService.h
+++ b/services/soundtrigger/SoundTriggerHwService.h
@@ -47,10 +47,12 @@
     virtual             ~SoundTriggerHwService();
 
     // ISoundTriggerHwService
-    virtual status_t listModules(struct sound_trigger_module_descriptor *modules,
+    virtual status_t listModules(const String16& opPackageName,
+                                 struct sound_trigger_module_descriptor *modules,
                                  uint32_t *numModules);
 
-    virtual status_t attach(const sound_trigger_module_handle_t handle,
+    virtual status_t attach(const String16& opPackageName,
+                            const sound_trigger_module_handle_t handle,
                             const sp<ISoundTriggerClient>& client,
                             sp<ISoundTrigger>& module);
 
@@ -122,6 +124,7 @@
        virtual status_t startRecognition(sound_model_handle_t handle,
                                          const sp<IMemory>& dataMemory);
        virtual status_t stopRecognition(sound_model_handle_t handle);
+       virtual status_t getModelState(sound_model_handle_t handle);
 
        sp<SoundTriggerHalInterface> halInterface() const { return mHalInterface; }
        struct sound_trigger_module_descriptor descriptor() { return mDescriptor; }
@@ -132,7 +135,8 @@
 
        void setCaptureState_l(bool active);
 
-       sp<ModuleClient> addClient(const sp<ISoundTriggerClient>& client);
+       sp<ModuleClient> addClient(const sp<ISoundTriggerClient>& client,
+                                  const String16& opPackageName);
 
        void detach(const sp<ModuleClient>& moduleClient);
 
@@ -155,7 +159,8 @@
     public:
 
        ModuleClient(const sp<Module>& module,
-              const sp<ISoundTriggerClient>& client);
+              const sp<ISoundTriggerClient>& client,
+              const String16& opPackageName);
 
        virtual ~ModuleClient();
 
@@ -169,6 +174,7 @@
        virtual status_t startRecognition(sound_model_handle_t handle,
                                          const sp<IMemory>& dataMemory);
        virtual status_t stopRecognition(sound_model_handle_t handle);
+       virtual status_t getModelState(sound_model_handle_t handle);
 
        virtual status_t dump(int fd, const Vector<String16>& args);
 
@@ -188,6 +194,7 @@
         mutable Mutex               mLock;
         wp<Module>                  mModule;
         sp<ISoundTriggerClient>     mClient;
+        const String16              mOpPackageName;
     }; // class ModuleClient
 
     class CallbackThread : public Thread {
diff --git a/soundtrigger/ISoundTrigger.cpp b/soundtrigger/ISoundTrigger.cpp
index 25332a4..f5b4b59 100644
--- a/soundtrigger/ISoundTrigger.cpp
+++ b/soundtrigger/ISoundTrigger.cpp
@@ -32,6 +32,7 @@
     UNLOAD_SOUND_MODEL,
     START_RECOGNITION,
     STOP_RECOGNITION,
+    GET_MODEL_STATE,
 };
 
 class BpSoundTrigger: public BpInterface<ISoundTrigger>
@@ -113,6 +114,18 @@
         return status;
     }
 
+    virtual status_t getModelState(sound_model_handle_t handle)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor());
+        data.write(&handle, sizeof(sound_model_handle_t));
+        status_t status = remote()->transact(GET_MODEL_STATE, data, &reply);
+        if (status == NO_ERROR) {
+            status = (status_t)reply.readInt32();
+        }
+        return status;
+    }
+
 };
 
 IMPLEMENT_META_INTERFACE(SoundTrigger, "android.hardware.ISoundTrigger");
@@ -169,6 +182,17 @@
             reply->writeInt32(status);
             return NO_ERROR;
         }
+        case GET_MODEL_STATE: {
+            CHECK_INTERFACE(ISoundTrigger, data, reply);
+            sound_model_handle_t handle;
+            status_t status = UNKNOWN_ERROR;
+            status_t ret = data.read(&handle, sizeof(sound_model_handle_t));
+            if (ret == NO_ERROR) {
+                status = getModelState(handle);
+            }
+            reply->writeInt32(status);
+            return ret;
+        }
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/soundtrigger/ISoundTriggerHwService.cpp b/soundtrigger/ISoundTriggerHwService.cpp
index d44f5cb..bd107b4 100644
--- a/soundtrigger/ISoundTriggerHwService.cpp
+++ b/soundtrigger/ISoundTriggerHwService.cpp
@@ -50,7 +50,8 @@
     {
     }
 
-    virtual status_t listModules(struct sound_trigger_module_descriptor *modules,
+    virtual status_t listModules(const String16& opPackageName,
+                                 struct sound_trigger_module_descriptor *modules,
                                  uint32_t *numModules)
     {
         if (numModules == NULL || (*numModules != 0 && modules == NULL)) {
@@ -58,6 +59,7 @@
         }
         Parcel data, reply;
         data.writeInterfaceToken(ISoundTriggerHwService::getInterfaceDescriptor());
+        data.writeString16(opPackageName);
         unsigned int numModulesReq = (modules == NULL) ? 0 : *numModules;
         data.writeInt32(numModulesReq);
         status_t status = remote()->transact(LIST_MODULES, data, &reply);
@@ -77,12 +79,14 @@
         return status;
     }
 
-    virtual status_t attach(const sound_trigger_module_handle_t handle,
+    virtual status_t attach(const String16& opPackageName,
+                            const sound_trigger_module_handle_t handle,
                             const sp<ISoundTriggerClient>& client,
                             sp<ISoundTrigger>& module)
     {
         Parcel data, reply;
         data.writeInterfaceToken(ISoundTriggerHwService::getInterfaceDescriptor());
+        data.writeString16(opPackageName);
         data.write(&handle, sizeof(sound_trigger_module_handle_t));
         data.writeStrongBinder(IInterface::asBinder(client));
         status_t status = remote()->transact(ATTACH, data, &reply);
@@ -120,6 +124,11 @@
     switch(code) {
         case LIST_MODULES: {
             CHECK_INTERFACE(ISoundTriggerHwService, data, reply);
+            String16 opPackageName;
+            status_t status = data.readString16(&opPackageName);
+            if (status != NO_ERROR) {
+                return status;
+            }
             unsigned int numModulesReq = data.readInt32();
             if (numModulesReq > MAX_ITEMS_PER_LIST) {
                 numModulesReq = MAX_ITEMS_PER_LIST;
@@ -133,7 +142,7 @@
                 reply->writeInt32(0);
                 return NO_ERROR;
             }
-            status_t status = listModules(modules, &numModules);
+            status = listModules(opPackageName, modules, &numModules);
             reply->writeInt32(status);
             reply->writeInt32(numModules);
             ALOGV("LIST_MODULES status %d got numModules %d", status, numModules);
@@ -151,12 +160,17 @@
 
         case ATTACH: {
             CHECK_INTERFACE(ISoundTriggerHwService, data, reply);
+            String16 opPackageName;
+            status_t status = data.readString16(&opPackageName);
+            if (status != NO_ERROR) {
+                return status;
+            }
             sound_trigger_module_handle_t handle;
             data.read(&handle, sizeof(sound_trigger_module_handle_t));
             sp<ISoundTriggerClient> client =
                     interface_cast<ISoundTriggerClient>(data.readStrongBinder());
             sp<ISoundTrigger> module;
-            status_t status = attach(handle, client, module);
+            status = attach(opPackageName, handle, client, module);
             reply->writeInt32(status);
             if (module != 0) {
                 reply->writeInt32(1);
diff --git a/soundtrigger/SoundTrigger.cpp b/soundtrigger/SoundTrigger.cpp
index 289b7b1..9708ea7 100644
--- a/soundtrigger/SoundTrigger.cpp
+++ b/soundtrigger/SoundTrigger.cpp
@@ -80,19 +80,21 @@
 }
 
 // Static methods
-status_t SoundTrigger::listModules(struct sound_trigger_module_descriptor *modules,
-                                 uint32_t *numModules)
+status_t SoundTrigger::listModules(const String16& opPackageName,
+                                   struct sound_trigger_module_descriptor *modules,
+                                   uint32_t *numModules)
 {
     ALOGV("listModules()");
     const sp<ISoundTriggerHwService> service = getSoundTriggerHwService();
     if (service == 0) {
         return NO_INIT;
     }
-    return service->listModules(modules, numModules);
+    return service->listModules(opPackageName, modules, numModules);
 }
 
-sp<SoundTrigger> SoundTrigger::attach(const sound_trigger_module_handle_t module,
-                                            const sp<SoundTriggerCallback>& callback)
+sp<SoundTrigger> SoundTrigger::attach(const String16& opPackageName,
+                                      const sound_trigger_module_handle_t module,
+                                      const sp<SoundTriggerCallback>& callback)
 {
     ALOGV("attach()");
     sp<SoundTrigger> soundTrigger;
@@ -101,7 +103,8 @@
         return soundTrigger;
     }
     soundTrigger = new SoundTrigger(module, callback);
-    status_t status = service->attach(module, soundTrigger, soundTrigger->mISoundTrigger);
+    status_t status = service->attach(opPackageName, module, soundTrigger,
+                                      soundTrigger->mISoundTrigger);
 
     if (status == NO_ERROR && soundTrigger->mISoundTrigger != 0) {
         IInterface::asBinder(soundTrigger->mISoundTrigger)->linkToDeath(soundTrigger);
@@ -188,6 +191,15 @@
     return mISoundTrigger->stopRecognition(handle);
 }
 
+status_t SoundTrigger::getModelState(sound_model_handle_t handle)
+{
+    Mutex::Autolock _l(mLock);
+    if (mISoundTrigger == 0) {
+        return NO_INIT;
+    }
+    return mISoundTrigger->getModelState(handle);
+}
+
 // BpSoundTriggerClient
 void SoundTrigger::onRecognitionEvent(const sp<IMemory>& eventMemory)
 {